[OpenThread][lib] Update library

OpenThread library commit hash:
42ecab1a2495960c33fa9590ad9111c7034abc19

Change-Id: I8bc83bb1a984298c9c997f79365f55eb97808b6b
diff --git a/.clang-format b/.clang-format
index 9a0a6ea..b5b25e7 100644
--- a/.clang-format
+++ b/.clang-format
@@ -105,7 +105,7 @@
 SpacesInCStyleCastParentheses: false
 SpacesInParentheses: false
 SpacesInSquareBrackets: false
-Standard:        Cpp03
+Standard:        Cpp11
 TabWidth:        4
 UseTab:          Never
 ...
diff --git a/.codecov.yml b/.codecov.yml
index 93d42f7..c7310f3 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -9,3 +9,4 @@
 
 comment:
   layout: "diff, flags, files"
+  after_n_builds: 16
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index da25f14..fd78a91 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,24 +1,19 @@
 ---
 name: Bug report
 about: Create a report to help us improve
-
 ---
 
-**Describe the bug**
-A clear and concise description of what the bug is.
+**Describe the bug** A clear and concise description of what the bug is.
 
-**To Reproduce**
-Information to reproduce the behavior, including:
+**To Reproduce** Information to reproduce the behavior, including:
+
 1. Git commit id
 2. IEEE 802.15.4 hardware platform
 3. Build steps
 4. Network topology
 
-**Expected behavior**
-A clear and concise description of what you expected to happen.
+**Expected behavior** A clear and concise description of what you expected to happen.
 
-**Console/log output**
-If applicable, add console/log output to help explain your problem.
+**Console/log output** If applicable, add console/log output to help explain your problem.
 
-**Additional context**
-Add any other context about the problem here.
+**Additional context** Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index b904f1f..f4fd35d 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -1,17 +1,12 @@
 ---
 name: Feature request
 about: Suggest an idea for this project
-
 ---
 
-**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is.
+**Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is.
 
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
+**Describe the solution you'd like** A clear and concise description of what you want to happen.
 
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
+**Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered.
 
-**Additional context**
-Add any other context or screenshots about the feature request here.
+**Additional context** Add any other context or screenshots about the feature request here.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..167d5e7
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,267 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+name: Build
+
+on: [push, pull_request]
+
+jobs:
+
+  cancel-previous-runs:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: rokroskar/workflow-run-cleanup-action@master
+      env:
+        GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+      if: "github.ref != 'refs/heads/master'"
+
+  pretty:
+    runs-on: ubuntu-18.04
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get remove -y clang-6.0 libclang-common-6.0-dev libclang1-6.0 libllvm6.0
+        sudo apt-get autoremove
+        sudo apt-get --no-install-recommends install -y clang-tools clang-format-6.0 shellcheck
+        python3 -m pip install yapf==0.29.0
+        sudo snap install shfmt
+    - name: Check
+      run: |
+        script/make-pretty check
+
+  cmake-version:
+    runs-on: ubuntu-18.04
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo pip3 install --system -U cmake==3.10.3
+        cmake --version | grep 3.10.3
+        sudo apt-get --no-install-recommends install -y ninja-build libreadline-dev libncurses-dev
+    - name: Build
+      run: |
+        NODE_MODE=rcp ./script/test build
+
+  package:
+    name: package-${{ matrix.compiler }}
+    runs-on: ubuntu-18.04
+    strategy:
+      matrix:
+        include:
+          - compiler: gcc
+            compiler_c: gcc
+            compiler_cpp: g++
+          - compiler: clang
+            compiler_c: clang
+            compiler_cpp: clang++
+    env:
+      CC: ${{ matrix.compiler_c }}
+      CXX: ${{ matrix.compiler_cpp }}
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y ninja-build libreadline-dev libncurses-dev
+    - name: Package
+      run: |
+        script/test package
+
+  scan-build:
+    runs-on: ubuntu-18.04
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get remove -y clang-6.0 libclang-common-6.0-dev libclang1-6.0 libllvm6.0
+        sudo apt-get autoremove
+        sudo apt-get --no-install-recommends install -y clang-tools
+    - name: Run
+      run: |
+        script/check-scan-build
+
+  arm-gcc:
+    name: arm-gcc-${{ matrix.gcc_ver }}
+    runs-on: ubuntu-18.04
+    strategy:
+      matrix:
+        include:
+          - gcc_ver: 4
+            gcc_download_url: https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q3-update/+download/gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2
+            gcc_extract_dir: gcc-arm-none-eabi-4_9-2015q3
+          - gcc_ver: 5
+            gcc_download_url: https://developer.arm.com/-/media/Files/downloads/gnu-rm/5_4-2016q3/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2
+            gcc_extract_dir: gcc-arm-none-eabi-5_4-2016q3
+          - gcc_ver: 6
+            gcc_download_url: https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2
+            gcc_extract_dir: gcc-arm-none-eabi-6-2017-q2-update
+          - gcc_ver: 7
+            gcc_download_url: https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2
+            gcc_extract_dir: gcc-arm-none-eabi-7-2018-q2-update
+          - gcc_ver: 9
+            gcc_download_url: https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2
+            gcc_extract_dir: gcc-arm-none-eabi-9-2019-q4-major
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        cd /tmp
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y lib32z1 ninja-build
+        wget ${{ matrix.gcc_download_url }} -O gcc-arm.tar.bz2
+        tar xjf gcc-arm.tar.bz2
+
+        # required for jn5189 and k32w061
+        pip install pycryptodome
+    - name: Build
+      run: |
+        export PATH=/tmp/${{ matrix.gcc_extract_dir }}/bin:$PATH
+        script/check-arm-build
+
+  gcc:
+    name: gcc-${{ matrix.gcc_ver }}
+    runs-on: ubuntu-18.04
+    strategy:
+      matrix:
+        gcc_ver: [5, 6, 7, 8, 9]
+    env:
+      CC: gcc-${{ matrix.gcc_ver }}
+      CXX: g++-${{ matrix.gcc_ver }}
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y gcc-${{ matrix.gcc_ver }} g++-${{ matrix.gcc_ver }} ninja-build libreadline-dev libncurses-dev
+    - name: Build
+      run: |
+        script/check-simulation-build
+        script/check-posix-build
+
+  clang:
+    name: clang-${{ matrix.clang_ver }}
+    runs-on: ubuntu-18.04
+    strategy:
+      matrix:
+        clang_ver: ["6.0", "7", "8", "9"]
+    env:
+      CC: clang-${{ matrix.clang_ver }}
+      CXX: clang++-${{ matrix.clang_ver }}
+    steps:
+      - uses: actions/checkout@v2
+      - name: Bootstrap
+        run: |
+          sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+          sudo apt-get --no-install-recommends install -y clang-${{ matrix.clang_ver }} clang++-${{ matrix.clang_ver }} ninja-build libreadline-dev libncurses-dev
+      - name: Build
+        run: |
+          script/check-simulation-build
+          script/check-posix-build
+
+  clang-m32:
+    name: clang-m32-${{ matrix.clang_ver }}
+    runs-on: ubuntu-18.04
+    strategy:
+      matrix:
+        clang_ver: ["6.0", "7", "8", "9"]
+    env:
+      CC: clang-${{ matrix.clang_ver }}
+      CXX: clang++-${{ matrix.clang_ver }}
+      CFLAGS: -m32 -Wconversion
+      CXXFLAGS: -m32 -Wconversion
+      LDFLAGS: -m32
+    steps:
+      - uses: actions/checkout@v2
+      - name: Bootstrap
+        run: |
+          sudo dpkg --add-architecture i386
+          sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+          sudo apt-get --no-install-recommends install -y clang-${{ matrix.clang_ver }} clang++-${{ matrix.clang_ver }} g++-multilib ninja-build
+          sudo apt-get --no-install-recommends install -y libreadline-dev:i386 libncurses-dev:i386
+      - name: Build
+        run: |
+          script/check-simulation-build
+          script/check-posix-build
+
+  gn:
+    runs-on: ubuntu-18.04
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y ninja-build
+        cd /tmp
+        wget -O gn.zip https://chrome-infra-packages.appspot.com/dl/gn/gn/linux-amd64/+/latest
+        unzip -o gn.zip
+        chmod a+x gn && mkdir -p bin && mv -f gn bin/
+    - name: Build
+      run: |
+        export PATH=/tmp/bin:$PATH
+        script/check-gn-build
+
+  macos-clang:
+    runs-on: macos-10.15
+    env:
+      CC: clang
+      CXX: clang++
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        brew install automake ninja llvm
+    - name: Build
+      run: |
+        script/check-posix-build
+        script/check-simulation-build
+
+  macos-gcc:
+    runs-on: macos-10.15
+    env:
+      CC: gcc
+      CXX: g++
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        brew install automake ninja
+    - name: Build
+      run: |
+        script/check-posix-build
+        script/check-simulation-build
+
+  android:
+    runs-on: ubuntu-18.04
+    steps:
+    - uses: actions/checkout@v2
+    - name: Build
+      run: |
+        docker run --rm -v $PWD:/build/openthread openthread/android-trusty /build/openthread/script/check-android-build
diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml
new file mode 100644
index 0000000..818664a
--- /dev/null
+++ b/.github/workflows/fuzz.yml
@@ -0,0 +1,51 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+name: CIFuzz
+on: [pull_request]
+jobs:
+ Fuzzing:
+   runs-on: ubuntu-latest
+   steps:
+   - name: Build Fuzzers
+     uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
+     with:
+       oss-fuzz-project-name: 'openthread'
+       dry-run: false
+   - name: Run Fuzzers
+     uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
+     with:
+       oss-fuzz-project-name: 'openthread'
+       fuzz-seconds: 1800
+       dry-run: false
+   - name: Upload Crash
+     uses: actions/upload-artifact@v1
+     if: failure()
+     with:
+       name: artifacts
+       path: ./out/artifacts
diff --git a/.github/workflows/posix.yml b/.github/workflows/posix.yml
new file mode 100644
index 0000000..600ddf4
--- /dev/null
+++ b/.github/workflows/posix.yml
@@ -0,0 +1,175 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+name: POSIX
+
+on: [push, pull_request]
+
+jobs:
+
+  cancel-previous-runs:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: rokroskar/workflow-run-cleanup-action@master
+      env:
+        GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+      if: "github.ref != 'refs/heads/master'"
+
+
+  posix-cli:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+      PYTHONUNBUFFERED: 1
+      READLINE: readline
+      REFERENCE_DEVICE: 1
+      VIRTUAL_TIME: 1
+      VIRTUAL_TIME_UART: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y libreadline6-dev
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+    - name: Build
+      run: |
+        ./bootstrap
+        make -f examples/Makefile-simulation
+        make -f src/posix/Makefile-posix
+    - name: Run
+      run: |
+        VERBOSE=1 OT_CLI_PATH="$(pwd)/$(ls output/posix/*/bin/ot-cli) -v" RADIO_DEVICE="$(pwd)/$(ls output/*/bin/ot-rcp)" make -f src/posix/Makefile-posix check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  posix-ncp:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+      NODE_TYPE: ncp-sim
+      PYTHONUNBUFFERED: 1
+      READLINE: readline
+      REFERENCE_DEVICE: 1
+      VIRTUAL_TIME: 1
+      VIRTUAL_TIME_UART: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y libreadline6-dev python3-setuptools
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+        sudo python3 -m pip install git+https://github.com/openthread/pyspinel
+    - name: Build
+      run: |
+        ./bootstrap
+        make -f examples/Makefile-simulation
+        make -f src/posix/Makefile-posix
+    - name: Run
+      run: |
+        VERBOSE=1 OT_NCP_PATH="$(pwd)/$(ls output/posix/*/bin/ot-ncp)" RADIO_DEVICE="$(pwd)/$(ls output/*/bin/ot-rcp)" make -f src/posix/Makefile-posix check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  posix-ncp-rcp-migrate:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y expect
+    - name: Build
+      run: |
+        ./bootstrap
+        script/check-ncp-rcp-migrate build
+    - name: Run
+      run: |
+        script/check-ncp-rcp-migrate check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  posix-pty:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y socat expect
+        cd /tmp
+        wget https://github.com/obgm/libcoap/archive/bsd-licensed.tar.gz
+        tar xvf bsd-licensed.tar.gz
+        cd libcoap-bsd-licensed
+        ./autogen.sh
+        ./configure --prefix= --exec-prefix=/usr --with-boost=internal --disable-tests --disable-documentation
+        make -j2
+        sudo make install
+    - name: Build
+      run: |
+        ./bootstrap
+        script/check-posix-pty build
+    - name: Run
+      run: |
+        script/check-posix-pty check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  posix-pty-daemon:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+      DAEMON: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y socat expect
+        cd /tmp
+        wget https://github.com/obgm/libcoap/archive/bsd-licensed.tar.gz
+        tar xvf bsd-licensed.tar.gz
+        cd libcoap-bsd-licensed
+        ./autogen.sh
+        ./configure --prefix= --exec-prefix=/usr --with-boost=internal --disable-tests --disable-documentation
+        make -j2
+        sudo make install
+    - name: Build
+      run: |
+        ./bootstrap
+        script/check-posix-pty build
+    - name: Run
+      run: |
+        script/check-posix-pty check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
diff --git a/.github/workflows/simulation-1.2.yml b/.github/workflows/simulation-1.2.yml
new file mode 100644
index 0000000..fab1c86
--- /dev/null
+++ b/.github/workflows/simulation-1.2.yml
@@ -0,0 +1,75 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+name: Simulation 1.2
+
+on: [push, pull_request]
+
+jobs:
+
+  cancel-previous-runs:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: rokroskar/workflow-run-cleanup-action@master
+      env:
+        GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+      if: "github.ref != 'refs/heads/master'"
+
+  thread-1-2:
+    name: thread-1-2-${{ matrix.compiler.c }}-${{ matrix.arch }}
+    runs-on: ubuntu-18.04
+    env:
+      CFLAGS: -${{ matrix.arch }}
+      CXXFLAGS: -${{ matrix.arch }}
+      LDFLAGS: -${{ matrix.arch }}
+      COVERAGE: 1
+      THREAD_VERSION: 1.2
+      VIRTUAL_TIME: 1
+      CC: ${{ matrix.compiler.c }}
+      CXX: ${{ matrix.compiler.cxx }}
+    strategy:
+      matrix:
+        compiler: [{c: "gcc", cxx: "g++"}, { c: "clang", cxx: "clang++"}]
+        arch: ["m32", "m64"]
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y g++-multilib ninja-build
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+    - name: Build
+      run: |
+        ./bootstrap
+        ./script/test build
+    - name: Run
+      run: |
+        ./script/test unit
+        ./script/test cert_suite tests/scripts/thread-cert/v1_2_*
+    - name: Codecov
+      uses: codecov/codecov-action@v1
diff --git a/.github/workflows/simulation.yml b/.github/workflows/simulation.yml
new file mode 100644
index 0000000..f183160
--- /dev/null
+++ b/.github/workflows/simulation.yml
@@ -0,0 +1,316 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+name: Simulation
+
+on: [push, pull_request]
+
+jobs:
+
+  cancel-previous-runs:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: rokroskar/workflow-run-cleanup-action@master
+      env:
+        GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+      if: "github.ref != 'refs/heads/master'"
+
+  distcheck:
+    runs-on: ubuntu-18.04
+    env:
+      CC: clang
+      CXX: clang++
+      REFERENCE_DEVICE: 1
+      VIRTUAL_TIME: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y llvm-runtime
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+    - name: Run
+      run: |
+        export ASAN_SYMBOLIZER_PATH=`which llvm-symbolizer`
+        export ASAN_OPTIONS=symbolize=1
+        export DISTCHECK_CONFIGURE_FLAGS= CPPFLAGS=-DOPENTHREAD_SIMULATION_VIRTUAL_TIME=1
+        ./bootstrap
+        make -f examples/Makefile-simulation distcheck
+
+  cli-ftd-otns:
+    runs-on: ubuntu-18.04
+    env:
+      CFLAGS: -m32
+      CXXFLAGS: -m32
+      LDFLAGS: -m32
+      COVERAGE: 1
+      REFERENCE_DEVICE: 1
+      VIRTUAL_TIME: 1
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-go@v1
+      with:
+        go-version: '1.13'
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y g++-multilib
+        ./bootstrap
+    - name: Run OTNS Tests
+      run: |
+        git clone https://github.com/openthread/ot-ns.git --depth 1 --branch master ~/otns
+        export OT_DIR=$PWD
+        cd ~/otns
+        ./script/test py-unittests py-examples
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  cli-ftd:
+    runs-on: ubuntu-18.04
+    env:
+      CFLAGS: -m32
+      CXXFLAGS: -m32
+      LDFLAGS: -m32
+      COVERAGE: 1
+      REFERENCE_DEVICE: 1
+      VIRTUAL_TIME: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y g++-multilib
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+    - name: Build
+      run: |
+        ./bootstrap
+        make -f examples/Makefile-simulation
+    - name: Run
+      run: |
+        VERBOSE=1 make -f examples/Makefile-simulation check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  cli-mtd:
+    runs-on: ubuntu-18.04
+    env:
+      CFLAGS: -m32
+      CXXFLAGS: -m32
+      LDFLAGS: -m32
+      COVERAGE: 1
+      REFERENCE_DEVICE: 1
+      USE_MTD: 1
+      VIRTUAL_TIME: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y g++-multilib
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+    - name: Build
+      run: |
+        ./bootstrap
+        make -f examples/Makefile-simulation
+    - name: Run
+      run: |
+        VERBOSE=1 make -f examples/Makefile-simulation check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  cli-time-sync:
+    runs-on: ubuntu-18.04
+    env:
+      CFLAGS: -m32
+      CXXFLAGS: -m32
+      LDFLAGS: -m32
+      COVERAGE: 1
+      REFERENCE_DEVICE: 1
+      TIME_SYNC: 1
+      VIRTUAL_TIME: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y g++-multilib
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+    - name: Build
+      run: |
+        ./bootstrap
+        make -f examples/Makefile-simulation
+    - name: Run
+      run: |
+        VERBOSE=1 make -f examples/Makefile-simulation check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  expects:
+    runs-on: ubuntu-18.04
+    env:
+      CFLAGS: -DCLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER=1
+      CXXFLAGS: -DCLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER=1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        OT_OPTIONS=-DOT_READLINE=OFF sudo apt-get --no-install-recommends install -y expect ninja-build
+    - name: Run
+      run: |
+        OT_OPTIONS=-DOT_TIME_SYNC=ON VIRTUAL_TIME=0 ./script/test build expect
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+    - name: Run RCP Mode
+      run: |
+        OT_OPTIONS=-DOT_READLINE=OFF VIRTUAL_TIME=0 NODE_MODE=rcp ./script/test clean build expect
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+    - name: Run TUN Mode
+      run: |
+        sudo apt-get install --no-install-recommends -y dnsmasq bind9-host ntp
+        sudo systemctl start dnsmasq ntp
+        host ipv6.google.com 127.0.0.1
+        echo 'listen-address=::1' | sudo tee /etc/dnsmasq.conf
+        echo 0 | sudo tee /proc/sys/net/ipv6/conf/all/disable_ipv6
+        sudo systemctl restart dnsmasq
+        host ipv6.google.com ::1
+        OT_OPTIONS=-DOT_READLINE=OFF OT_NATIVE_IP=1 VIRTUAL_TIME=0 NODE_MODE=rcp ./script/test clean build expect
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  external-commissioner:
+    runs-on: ubuntu-18.04
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/*
+        sudo apt-get --no-install-recommends install -y ninja-build
+        git clone https://github.com/openthread/ot-commissioner.git /tmp/ot-commissioner --depth 1 --branch master
+    - name: Build
+      run: |
+        cd /tmp/ot-commissioner
+        script/bootstrap.sh
+        cmake -GNinja                           \
+              -DCMAKE_CXX_STANDARD=11           \
+              -DCMAKE_CXX_STANDARD_REQUIRED=ON  \
+              -DCMAKE_BUILD_TYPE=Release        \
+              -DCMAKE_INSTALL_PREFIX=/usr/local \
+              -S . -B build
+        cmake --build build
+        sudo cmake --install build
+    - name: Run
+      run: |
+        export OT_COMM_OPENTHREAD="$(pwd)"
+        cd /tmp/ot-commissioner/tests/integration
+        ./bootstrap.sh
+        ./run_tests.sh
+    - name: Copy Codecov Files
+      run: |
+        cp -vr /tmp/test-ot-commissioner/ot-br-posix/build/* build/
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  multiple-instance:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+      MULTIPLE_INSTANCE: 1
+      REFERENCE_DEVICE: 1
+      VIRTUAL_TIME: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+    - name: Build
+      run: |
+        ./bootstrap
+        make -f examples/Makefile-simulation
+    - name: Run
+      run: |
+        VERBOSE=1 make -f examples/Makefile-simulation check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  ncp-gcc-m32:
+    runs-on: ubuntu-18.04
+    env:
+      CFLAGS: -m32
+      CXXFLAGS: -m32
+      LDFLAGS: -m32
+      COVERAGE: 1
+      NODE_TYPE: ncp-sim
+      PYTHONUNBUFFERED: 1
+      REFERENCE_DEVICE: 1
+      VIRTUAL_TIME: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y g++-multilib python3-setuptools
+        python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+        sudo python3 -m pip install git+https://github.com/openthread/pyspinel
+    - name: Build
+      run: |
+        ./bootstrap
+        make -f examples/Makefile-simulation
+    - name: Run
+      run: |
+        VERBOSE=1 make -f examples/Makefile-simulation check
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  ncp-clang:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+      NODE_TYPE: ncp-sim
+      PYTHONUNBUFFERED: 1
+      REFERENCE_DEVICE: 1
+      VIRTUAL_TIME: 1
+      CC: clang
+      CXX: clang++
+    steps:
+      - uses: actions/checkout@v2
+      - name: Bootstrap
+        run: |
+          sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+          sudo apt-get --no-install-recommends install -y python3-setuptools
+          python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
+          sudo python3 -m pip install git+https://github.com/openthread/pyspinel
+      - name: Build
+        run: |
+          ./bootstrap
+          make -f examples/Makefile-simulation
+      - name: Run
+        run: |
+          VERBOSE=1 make -f examples/Makefile-simulation check
+      - name: Codecov
+        uses: codecov/codecov-action@v1
diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml
new file mode 100644
index 0000000..168923d
--- /dev/null
+++ b/.github/workflows/size.yml
@@ -0,0 +1,58 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+name: Size
+
+on: [push, pull_request]
+
+jobs:
+
+  cancel-previous-runs:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: rokroskar/workflow-run-cleanup-action@master
+      env:
+        GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+      if: "github.ref != 'refs/heads/master'"
+
+  size-report:
+    runs-on: ubuntu-18.04
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      if: "github.event_name == 'push'"
+      run: |
+        python3 -m pip install --upgrade setuptools wheel
+        python3 -m pip install mdv
+    - name: Run
+      env:
+        OT_BASE_BRANCH: "${{ github.base_ref }}"
+        SIZE_REPORT_URL: "https://openthread-size-report.glitch.me/size-report/1354027"
+      run: |
+        export PATH=$PATH:$HOME/.local/bin
+        ./script/check-size
diff --git a/.github/workflows/toranj.yml b/.github/workflows/toranj.yml
new file mode 100644
index 0000000..c79d180
--- /dev/null
+++ b/.github/workflows/toranj.yml
@@ -0,0 +1,98 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+name: Toranj
+
+on: [push, pull_request]
+
+jobs:
+
+  cancel-previous-runs:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: rokroskar/workflow-run-cleanup-action@master
+      env:
+        GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+      if: "github.ref != 'refs/heads/master'"
+
+  toranj-ncp:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y dbus libdbus-1-dev
+        sudo apt-get --no-install-recommends install -y autoconf-archive
+        sudo apt-get --no-install-recommends install -y bsdtar
+        sudo apt-get --no-install-recommends install -y libtool
+        sudo apt-get --no-install-recommends install -y libglib2.0-dev
+        sudo apt-get --no-install-recommends install -y libboost-dev libboost-signals-dev
+
+        git clone --depth=1 --branch=master https://github.com/openthread/wpantund.git
+        cd wpantund
+        ./bootstrap.sh
+        ./configure
+        sudo make -j2
+        sudo make install
+    - name: Build & Run
+      run: |
+        top_builddir=$(pwd)/build/toranj ./tests/toranj/start.sh
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+
+  toranj-rcp:
+    runs-on: ubuntu-18.04
+    env:
+      COVERAGE: 1
+      TORANJ_POSIX_RCP_MODEL: 1
+    steps:
+    - uses: actions/checkout@v2
+    - name: Bootstrap
+      run: |
+        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
+        sudo apt-get --no-install-recommends install -y dbus libdbus-1-dev
+        sudo apt-get --no-install-recommends install -y autoconf-archive
+        sudo apt-get --no-install-recommends install -y bsdtar
+        sudo apt-get --no-install-recommends install -y libtool
+        sudo apt-get --no-install-recommends install -y libglib2.0-dev
+        sudo apt-get --no-install-recommends install -y libboost-dev libboost-signals-dev
+
+        git clone --depth=1 --branch=master https://github.com/openthread/wpantund.git
+        cd wpantund
+        ./bootstrap.sh
+        ./configure
+        sudo make -j2
+        sudo make install
+    - name: Build & Run
+      run: |
+        top_builddir=$(pwd)/build/toranj ./tests/toranj/start.sh
+    - name: Codecov
+      uses: codecov/codecov-action@v1
diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml
new file mode 100644
index 0000000..0c71178
--- /dev/null
+++ b/.github/workflows/version.yml
@@ -0,0 +1,48 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+name: API Version
+
+on: [pull_request]
+
+jobs:
+  cancel-previous-runs:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: rokroskar/workflow-run-cleanup-action@master
+      env:
+        GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+      if: "github.ref != 'refs/heads/master'"
+
+  api-version:
+    runs-on: ubuntu-18.04
+    steps:
+    - uses: actions/checkout@v2
+    - name: Check
+      run: |
+        script/check-api-version
diff --git a/.gitignore b/.gitignore
index 5bbdeab..3f44e28 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,9 @@
 *.orig
 *.pyc
 *.suo
+*.swn
+*.swo
+*.swp
 *.trs
 *.user
 *.bak
@@ -54,3 +57,4 @@
 third_party/nlbuild-autotools/repo/third_party/autoconf/m4/ltversion.m4
 third_party/nlbuild-autotools/repo/third_party/autoconf/m4/lt~obsolete.m4
 third_party/nlbuild-autotools/repo/third_party/autoconf/missing
+/tmp/
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..89cc06e
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,7 @@
+{
+    "$schema": "http://json.schemastore.org/prettierrc",
+    "printWidth": 80,
+    "tabWidth": 2,
+    "useTabs": false,
+    "proseWrap": "never"
+}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 52b05ec..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,209 +0,0 @@
-#
-#  Copyright (c) 2016, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-language: python
-python: "3.6"
-
-sudo: required
-dist: bionic
-
-before_install:
-  - travis_retry .travis/before_install.sh
-
-before_script:
-  - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
-      sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6';
-    fi
-
-after_success:
-  - .travis/after_success.sh
-
-stages:
-  - lint
-  - test
-
-jobs:
-  include:
-    - env: BUILD_TARGET="posix-app-cli" VERBOSE=1 VIRTUAL_TIME=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-app-ncp" VERBOSE=1 VIRTUAL_TIME=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-app-pty" VERBOSE=1 COVERAGE=1
-      os: linux
-      compiler: clang
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-app-pty" DAEMON=1 VERBOSE=1 COVERAGE=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-app-migrate" VERBOSE=1 COVERAGE=1
-      os: linux
-      compiler: clang
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-app-spi" VERBOSE=1 COVERAGE=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="android-build" VERBOSE=1
-      os: linux
-      dist: trusty
-      python: "2.7" # The old Android build system only supports python2
-      script: .travis/script.sh
-    - env: BUILD_TARGET="gn-build" VERBOSE=1
-      os: linux
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-distcheck" VERBOSE=1 VIRTUAL_TIME=1
-      os: linux
-      compiler: clang
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-32-bit" VERBOSE=1 VIRTUAL_TIME=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-32-bit" VERBOSE=1 VIRTUAL_TIME=1 TIME_SYNC=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-ncp" VERBOSE=1 VIRTUAL_TIME=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-mtd" VERBOSE=1 VIRTUAL_TIME=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="scan-build"
-      os: linux
-      compiler: clang
-      script: .travis/script.sh
-    - env: BUILD_TARGET="arm-gcc-4"
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="arm-gcc-5"
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="arm-gcc-6"
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="arm-gcc-7"
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-# Disable Arm GCC 8 until slow compile bug is fixed:
-# https://github.com/openthread/openthread/issues/4053
-#    - env: BUILD_TARGET="arm-gcc-8"
-#      os: linux
-#      compiler: gcc
-#      script: .travis/script.sh
-    - env: BUILD_TARGET="arm-gcc-9"
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix" CC="gcc-5" CXX="g++-5"
-      os: linux
-      compiler: gcc
-      addons:
-        apt:
-          packages:
-            - gcc-5
-            - g++-5
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix" CC="gcc-6" CXX="g++-6"
-      os: linux
-      compiler: gcc
-      addons:
-        apt:
-          packages:
-            - gcc-6
-            - g++-6
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix" CC="gcc-7" CXX="g++-7"
-      os: linux
-      compiler: gcc
-      addons:
-        apt:
-          packages:
-            - gcc-7
-            - g++-7
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix" CC="gcc-8" CXX="g++-8"
-      os: linux
-      compiler: gcc
-      addons:
-        apt:
-          packages:
-            - gcc-8
-            - g++-8
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix" CC="gcc-9" CXX="g++-9"
-      os: linux
-      compiler: gcc
-      addons:
-        apt:
-          sources:
-            - sourceline: "ppa:ubuntu-toolchain-r/test"
-          packages:
-            - gcc-9
-            - g++-9
-      script: .travis/script.sh
-    - env: BUILD_TARGET="posix-ncp-spi" VERBOSE=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="toranj-test-framework" COVERAGE=1 VERBOSE=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="toranj-test-framework" COVERAGE=1 VERBOSE=1 TORANJ_POSIX_APP_RCP_MODEL=1
-      os: linux
-      compiler: gcc
-      script: .travis/script.sh
-    - env: BUILD_TARGET="osx" VERBOSE=1
-      os: osx
-      language: generic
-      script: .travis/script.sh
-    - stage: lint
-      name: "Pretty Check"
-      os: linux
-      addons:
-        apt:
-          packages:
-            - clang-format-6.0
-      script: .travis/check-pretty
-    - env:
-      name: "Size Report"
-      os: linux
-      script: .travis/check-size
-      if: type = pull_request
diff --git a/.travis/after_success.sh b/.travis/after_success.sh
deleted file mode 100755
index 07e98d8..0000000
--- a/.travis/after_success.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-#
-#  Copyright (c) 2019, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-[ -n "$BUILD_TARGET" ] || exit 0
-
-set -e
-
-codecov_upload() {
-    curl -s https://codecov.io/bash > codecov
-    chmod a+x codecov
-
-    # Assume gcov by default, and llvm-cov if CC is clang
-    if [[ -z $CC ]]; then
-        ./codecov
-    elif  "$CC" --version | grep -q gcc; then
-        ./codecov
-    elif "$CC" --version | grep -q clang; then
-        ./codecov -x "llvm-cov gcov"
-    fi
-}
-
-main() {
-    codecov_upload
-}
-
-main "$@"
diff --git a/.travis/before_install.sh b/.travis/before_install.sh
deleted file mode 100755
index 510964e..0000000
--- a/.travis/before_install.sh
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/bin/sh
-#
-#  Copyright (c) 2016, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-[ -n "$BUILD_TARGET" ] || exit 0
-
-die() {
-	echo " *** ERROR: " $*
-	exit 1
-}
-
-set -x
-
-cd /tmp || die
-
-[ $TRAVIS_OS_NAME != linux ] || {
-    (cd /etc/apt/sources.list.d && sudo rm -rf cassandra.list* couchdb.list* mongodb-3.4.list* rabbitmq_rabbitmq-server.list* chris-lea-redis-server.list* github_git-lfs.list* pgdg.list)
-    sudo apt-get update || die
-
-    sudo apt-get install ninja-build
-
-    pip3 install --upgrade pip
-    pip3 install cmake
-
-    [ $BUILD_TARGET != posix-distcheck -a $BUILD_TARGET != posix-32-bit -a $BUILD_TARGET != posix-app-cli -a $BUILD_TARGET != posix-mtd -a $BUILD_TARGET != posix-ncp -a $BUILD_TARGET != posix-app-ncp ] || {
-        pip install --upgrade pip || die
-        pip install -r $TRAVIS_BUILD_DIR/tests/scripts/thread-cert/requirements.txt || die
-        [ $BUILD_TARGET != posix-ncp -a $BUILD_TARGET != posix-app-ncp ] || {
-            # Packages used by ncp tools.
-            pip install git+https://github.com/openthread/pyspinel || die
-        }
-    }
-
-    [ $BUILD_TARGET != android-build ] || {
-        sudo apt-get install -y bison gcc-multilib g++-multilib
-        (
-        cd $HOME
-        wget https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
-        unzip android-ndk-r17c-linux-x86_64.zip > /dev/null
-        mv android-ndk-r17c ndk-bundle
-        ) || die
-    }
-
-    [ $BUILD_TARGET != gn-build ] || {
-        # Install ninja
-        (
-        cd $HOME
-        wget -O ninja.zip https://chrome-infra-packages.appspot.com/dl/infra/ninja/linux-amd64/+/latest
-        unzip -o ninja.zip
-        chmod a+x ninja && mkdir -p bin && mv -f ninja bin/ && export PATH=${HOME}/bin:$PATH
-        ninja --version
-        ) || die
-
-
-        # Get latest gn
-        (
-        cd $HOME
-        wget -O gn.zip https://chrome-infra-packages.appspot.com/dl/gn/gn/linux-amd64/+/latest
-        unzip -o gn.zip
-        chmod a+x gn && mv -f gn bin/
-        gn --version
-        ) || die
-    }
-
-    [ $BUILD_TARGET != posix-app-pty ] || {
-        sudo apt-get install socat expect || die
-        JOBS=$(getconf _NPROCESSORS_ONLN)
-        (
-        LIBCOAP_TMPDIR=/tmp/libcoap
-        mkdir $LIBCOAP_TMPDIR
-        cd $LIBCOAP_TMPDIR
-        wget https://github.com/obgm/libcoap/archive/bsd-licensed.tar.gz
-        tar xvf bsd-licensed.tar.gz
-        cd libcoap-bsd-licensed
-        ./autogen.sh
-        ./configure --prefix= --exec-prefix=/usr --with-boost=internal --disable-tests --disable-documentation
-        make -j $JOBS
-        sudo make install
-        ) || die
-    }
-
-    [ $BUILD_TARGET != posix-app-migrate ] || {
-        sudo apt-get install expect || die
-    }
-
-    [ $BUILD_TARGET != arm-gcc-4 ] || {
-        sudo apt-get install lib32z1 || die
-        wget https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q3-update/+download/gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2 || die
-        tar xjf gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2 || die
-        export PATH=/tmp/gcc-arm-none-eabi-4_9-2015q3/bin:$PATH || die
-        arm-none-eabi-gcc --version || die
-    }
-
-    [ $BUILD_TARGET != arm-gcc-5 ] || {
-        sudo apt-get install lib32z1 || die
-        wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/5_4-2016q3/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2 || die
-        tar xjf gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2 || die
-        export PATH=/tmp/gcc-arm-none-eabi-5_4-2016q3/bin:$PATH || die
-        arm-none-eabi-gcc --version || die
-    }
-
-    [ $BUILD_TARGET != arm-gcc-6 ] || {
-        wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 || die
-        tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 || die
-        export PATH=/tmp/gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH || die
-        arm-none-eabi-gcc --version || die
-    }
-
-    [ $BUILD_TARGET != arm-gcc-7 ] || {
-        wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2 || die
-        tar xjf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2 || die
-        export PATH=/tmp/gcc-arm-none-eabi-7-2018-q2-update/bin:$PATH || die
-        arm-none-eabi-gcc --version || die
-    }
-
-    [ $BUILD_TARGET != arm-gcc-8 ] || {
-        wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 || die
-        tar xjf gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 || die
-        export PATH=/tmp/gcc-arm-none-eabi-8-2018-q4-major/bin:$PATH || die
-        arm-none-eabi-gcc --version || die
-    }
-
-    [ $BUILD_TARGET != arm-gcc-9 ] || {
-        wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 || die
-        tar xjf gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 || die
-        export PATH=/tmp/gcc-arm-none-eabi-9-2019-q4-major/bin:$PATH || die
-        arm-none-eabi-gcc --version || die
-    }
-
-    [ $BUILD_TARGET != posix-32-bit -a $BUILD_TARGET != posix-mtd ] || {
-        sudo apt-get install g++-multilib || die
-    }
-
-    [ $BUILD_TARGET != posix-distcheck ] || {
-        sudo apt-get install llvm-runtime || die
-    }
-
-    [ $BUILD_TARGET != toranj-test-framework ] || {
-        # packages for wpantund
-        sudo apt-get install dbus || die
-        sudo apt-get install gcc g++ libdbus-1-dev || die
-        sudo apt-get install autoconf-archive || die
-        sudo apt-get install bsdtar || die
-        sudo apt-get install libtool || die
-        sudo apt-get install libglib2.0-dev || die
-        sudo apt-get install libboost-dev || die
-        sudo apt-get install libboost-signals-dev || die
-
-        # clone and build wpantund
-        git clone --depth=1 --branch=master https://github.com/openthread/wpantund.git
-        cd wpantund || die
-        ./bootstrap.sh || die
-        ./configure || die
-        sudo make -j 8 || die
-        sudo make install || die
-        cd .. || die
-    }
-
-}
diff --git a/.travis/check-android-build b/.travis/check-android-build
deleted file mode 100755
index 4e6706e..0000000
--- a/.travis/check-android-build
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/bin/sh
-#
-#  Copyright (c) 2018, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-#
-# Run this command on parent directory of openthread
-#
-
-set -e
-set -x
-
-#######################################
-# Prepare android build system
-# Globals:
-#   None
-# Arguments:
-#   None
-# Returns:
-#   None
-#######################################
-android_prepare_build_system()
-{
-    # Android build system
-    (mkdir build && cd build && git init && git pull --depth 1 https://android.googlesource.com/platform/build 2db32730e79cafcf13e1f898a7bee7f82b0449d6)
-    ln -s build/core/main.mk Makefile
-
-    # Workarounds for java checking
-    export ANDROID_JAVA_HOME=/usr/lib/jvm/java-8-oracle
-    mkdir bin
-    cat > bin/java <<EOF
-#!/bin/sh
-echo java version \"1.6\"
-EOF
-
-    cat > bin/javac <<EOF
-echo javac \"1.6\"
-EOF
-    chmod a+x bin/java bin/javac
-    export PATH=$(pwd)/bin:$PATH
-
-    # Files for building ndk
-    mkdir -p system/core/include/arch/linux-arm
-    touch system/core/include/arch/linux-arm/AndroidConfig.h
-
-    mkdir -p system/core/include/arch/linux-x86
-    touch system/core/include/arch/linux-x86/AndroidConfig.h
-
-    ANDROID_NDK_PATH=$HOME/ndk-bundle
-    mkdir -p bionic/libc/
-    cp -r $ANDROID_NDK_PATH/sysroot/usr/include bionic/libc/include
-    mv bionic/libc/include/arm-linux-androideabi/asm bionic/libc/include/asm
-
-    mkdir -p out/target/product/generic/obj/
-    cp -r $ANDROID_NDK_PATH/platforms/android-27/arch-arm/usr/lib out/target/product/generic/obj/
-
-    mkdir -p bionic/libstdc++
-    cp -r $ANDROID_NDK_PATH/sources/cxx-stl/gnu-libstdc++/4.9/include bionic/libstdc++
-    cp -r $ANDROID_NDK_PATH/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include/* bionic/libstdc++/include
-    # The default libstdc++.so does not contain full stl implementation, see https://developer.android.com/ndk/guides/cpp-support
-    cp -r $ANDROID_NDK_PATH/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_shared.so out/target/product/generic/obj/lib/libstdc++.so
-
-    # Build spec
-    cat > buildspec.mk <<EOF
-TARGET_PRODUCT := generic
-TARGET_BUILD_VARIANT := eng
-TARGET_BUILD_TYPE := release
-TARGET_TOOLS_PREFIX := $ANDROID_NDK_PATH/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
-EOF
-}
-
-main() {
-    android_prepare_build_system
-
-    make showcommands ot-core
-    make showcommands ot-cli
-    make showcommands ot-ncp
-    make showcommands spi-hdlc-adapter
-
-    test -x out/target/product/generic/system/bin/ot-cli
-    test -x out/target/product/generic/system/bin/ot-ncp
-    test -x out/target/product/generic/system/bin/spi-hdlc-adapter
-}
-
-main "$@"
diff --git a/.travis/check-gn-build b/.travis/check-gn-build
deleted file mode 100755
index 8e96783..0000000
--- a/.travis/check-gn-build
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-#
-#  Copyright (c) 2019, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-#
-# Run this command on parent directory of openthread
-#
-
-set -e
-set -x
-
-main() {
-    gn gen gn-out
-    ninja -C gn-out
-    test -f gn-out/obj/lib-ot-core.a
-}
-
-main "$@"
diff --git a/.travis/check-ncp-rcp-migrate b/.travis/check-ncp-rcp-migrate
deleted file mode 100755
index 968a35a..0000000
--- a/.travis/check-ncp-rcp-migrate
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/bash
-#
-#  Copyright (c) 2020, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-set -e
-set -x
-
-at_exit() {
-    EXIT_CODE=$?
-
-    killall expect || true
-    killall ot-cli-ftd || true
-    killall ot-cli || true
-    killall ot-rcp || true
-
-    exit $EXIT_CODE
-}
-
-build() {
-    make -f examples/Makefile-posix
-    make -f src/posix/Makefile-posix
-}
-
-check() {
-    trap at_exit INT TERM EXIT
-
-    rm -rf tmp/
-
-    PANID="0xc001"
-    EXT_PANID="0123456789abcdef"
-    NETWORK_NAME="OT_NCP_TO_RCP"
-    CHANNEL="20"
-    MASTER_KEY="0123456789abcdef0123456789abcdef"
-
-    echo "Step 1. Start NCP platform and form a PAN..."
-    RADIO_NCP_CMD="$(pwd)/$(ls output/*linux*/bin/ot-cli-ftd)"
-
-    expect <<EOF
-spawn ${RADIO_NCP_CMD} 1
-set timeout 2
-expect_after {
-    timeout { exit 1 }
-}
-send "panid ${PANID}\r\n"
-expect "Done"
-send "extpanid ${EXT_PANID}\r\n"
-expect "Done"
-send "networkname ${NETWORK_NAME}\r\n"
-expect "Done"
-send "channel ${CHANNEL}\r\n"
-expect "Done"
-send "masterkey ${MASTER_KEY}\r\n"
-expect "Done"
-send "ifconfig up\r\n"
-expect "Done"
-send "thread start\r\n"
-expect "Done"
-sleep 5
-send "state\r\n"
-expect "leader"
-expect "Done"
-send "exit\r\n"
-expect eof
-EOF
-
-    echo "Step 2. Start retrieving dataset from Radio..."
-    RADIO_NCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-ncp-ftd)"
-    "$(pwd)/$(ls output/posix/*linux*/bin/ot-ncp)" -n --radio-version --ncp-dataset -- ${RADIO_NCP_PATH} 1
-
-    echo "Step 3. Start posix app and check whether PAN dataset is the same..."
-    RADIO_RCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-rcp)"
-
-    OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) ${RADIO_RCP_PATH} 1"
-
-    expect <<EOF
-spawn ${OT_CLI_CMD}
-set timeout 2
-expect_after {
-    timeout { exit 1 }
-}
-send "panid\r\n"
-expect ${PANID}
-expect "Done"
-send "extpanid\r\n"
-expect ${EXT_PANID}
-expect "Done"
-send "networkname\r\n"
-expect ${NETWORK_NAME}
-expect "Done"
-send "channel\r\n"
-expect ${CHANNEL}
-expect "Done"
-send "masterkey\r\n"
-expect ${MASTER_KEY}
-expect "Done"
-send "exit\r\n"
-expect eof
-EOF
-
-    echo "Step 4. Start posix app and check whether it can get radio firmware version..."
-    RADIO_VERSION="$("$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)" -n --radio-version --ncp-dataset -- ${RADIO_RCP_PATH} 1)" || true
-    test -n "{RADIO_VERSION}"
-}
-
-main() {
-    case "$1" in
-        check)
-            check
-            ;;
-        *)
-            build
-            check
-            ;;
-    esac
-}
-
-main "$@"
diff --git a/.travis/check-posix-app-pty b/.travis/check-posix-app-pty
deleted file mode 100755
index 2289547..0000000
--- a/.travis/check-posix-app-pty
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/bin/bash
-#
-#  Copyright (c) 2018, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-set -e
-set -x
-
-die() {
-	echo " *** ERROR: " $*
-	exit 1
-}
-
-at_exit() {
-    EXIT_CODE=$?
-
-    sudo killall expect || true
-    killall ot-ctl || true
-    killall ot-daemon || true
-    killall socat || true
-
-    exit $EXIT_CODE
-}
-
-build() {
-    make -f examples/Makefile-posix
-    make -f src/posix/Makefile-posix PLATFORM_NETIF=1 PLATFORM_UDP=1 UDP_FORWARD=0
-}
-
-check() {
-    trap at_exit INT TERM EXIT
-
-    SOCAT_OUTPUT=/tmp/ot-socat
-    OT_OUTPUT=/tmp/ot-output
-    socat -d -d pty,raw,echo=0 pty,raw,echo=0 > /dev/null 2> $SOCAT_OUTPUT &
-    while true; do
-        if test $(head -n2 $SOCAT_OUTPUT | wc -l) = 2; then
-            RADIO_PTY=$(head -n1 $SOCAT_OUTPUT | grep -o '/dev/.\+')
-            CORE_PTY=$(head -n2 $SOCAT_OUTPUT | tail -n1 | grep -o '/dev/.\+')
-            break
-        fi
-        echo 'Waiting for socat ready...'
-        sleep 1
-    done
-    echo 'RADIO_PTY' $DEVICE_PTY
-    echo 'CORE_PTY' $CORE_PTY
-
-    RADIO_NCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-rcp)"
-    $RADIO_NCP_PATH 1 > $RADIO_PTY < $RADIO_PTY &
-
-    if [[ "${DAEMON}" = 1 ]]; then
-        sudo "$(pwd)/$(ls output/posix/*linux*/bin/ot-daemon)" ${OT_NCP_PATH} ${CORE_PTY} &
-        sleep 1
-        OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-ctl)"
-    else
-        OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) ${OT_NCP_PATH} ${CORE_PTY}"
-    fi
-
-    if [[ "${DAEMON}" = 1 ]]; then
-        sudo ${OT_CLI_CMD} panid 0xface | grep 'Done' || die 'failed to set panid with ot-ctl'
-    fi
-
-    sudo expect <<EOF > "${OT_OUTPUT}" &
-spawn ${OT_CLI_CMD}
-send "panid 0xface\r\n"
-expect "Done"
-send "ifconfig up\r\n"
-expect "Done"
-send "thread start\r\n"
-expect "Done"
-sleep 5
-send "state\r\n"
-expect "leader"
-expect "Done"
-send "extaddr\r\n"
-expect "Done"
-send "ipaddr\r\n"
-expect "Done"
-send "coex\r\n"
-expect "Done"
-wait
-EOF
-
-    # wait until the node becomes leader
-    while true; do
-        sleep 5
-        if grep -q leader $OT_OUTPUT; then
-            break
-        else
-            echo 'Still waiting for leader'
-        fi
-    done
-
-    netstat -an | grep -q 61631 || die 'TMF port is not available!'
-
-    extaddr=$(awk '/extaddr/{getline; print}' $OT_OUTPUT | tr -d '\r\n')
-    echo "Extended address is: ${extaddr}"
-
-    LEADER_ALOC=fdde:ad00:beef::ff:fe00:fc00
-    # Retrievie extended address through network diagnostic get
-    coap_response=$(echo -n '120100' | xxd -r -p | coap-client -m POST coap://[${LEADER_ALOC}]:61631/d/dg -f- | xxd -p | grep 0008)
-    echo "CoAP response is: ${coap_response}"
-
-    # Verify CoAP response contains the extended address
-    [[ "${coap_response}" = *${extaddr}* ]] && echo 'Success' || die 'failed to get extended address'
-}
-
-main() {
-    case $1 in
-        check)
-            check
-            ;;
-        *)
-            build
-            check
-            ;;
-    esac
-}
-
-main "$@"
diff --git a/.travis/check-pretty b/.travis/check-pretty
deleted file mode 100755
index 30a9a2b..0000000
--- a/.travis/check-pretty
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/bash
-#
-#  Copyright (c) 2019, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-set -e -x -o pipefail
-
-setup_python()
-{
-  python -m pip install flake8
-}
-
-check_python()
-{
-  flake8 --config=script/pystyle.cfg tests tools
-}
-
-check_clang()
-{
-  clang-format --version
-  ./bootstrap
-  ./configure
-  make pretty-check
-}
-
-main()
-{
-  case $1 in
-    setup)
-      setup_python
-      ;;
-    python)
-      check_python
-      ;;
-    clang)
-      check_cpp
-      ;;
-    '')
-      setup_python
-      check_python
-      check_clang
-      ;;
-    *)
-      echo "USAGE: $0 [setup|python|clang]"
-      exit 1
-      ;;
-  esac
-}
-
-main "$@"
diff --git a/.travis/check-size b/.travis/check-size
deleted file mode 100755
index 5ee7d88..0000000
--- a/.travis/check-size
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/bin/bash
-#
-#  Copyright (c) 2019, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-set -e -x -o pipefail
-
-setup_arm_gcc_7()
-{
-  if arm-none-eabi-gcc --version | grep -q 'Arm Embedded Processors 7'; then
-    return 0
-  fi
-
-  (cd /tmp/
-   wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2
-   tar xjf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2)
-  export PATH=/tmp/gcc-arm-none-eabi-7-2018-q2-update/bin:$PATH
-
-  arm-none-eabi-gcc --version
-}
-
-size_nrf52840()
-{
-    [ ${TRAVIS_PULL_REQUEST} != false ]
-
-    mkdir ../output
-
-    export MERGE_BASE_SHA=$(git merge-base HEAD ${TRAVIS_BRANCH})
-
-    # pull request
-    OPENTHREAD_FLAGS="BORDER_AGENT=1 BORDER_ROUTER=1 CHANNEL_MANAGER=1 CHANNEL_MONITOR=1 CHILD_SUPERVISION=1 COAP=1 COAPS=1 COMMISSIONER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DIAGNOSTIC=1 DISABLE_DOC=1 DNS_CLIENT=1 ECDSA=1 FULL_LOGS=1 JAM_DETECTION=1 JOINER=1 LINK_RAW=1 MAC_FILTER=1 MTD_NETDIAG=1 SERVICE=1 SLAAC=1 SNTP_CLIENT=1 TIME_SYNC=1 UDP_FORWARD=1"
-
-    git checkout -- .
-    git clean -xfd
-    ./bootstrap
-    make -f examples/Makefile-nrf52840 ${OPENTHREAD_FLAGS}
-    mv output/nrf52840 ../output/nrf52840-b
-
-    git checkout -f ${MERGE_BASE_SHA}
-    git submodule update --init
-
-    # base branch
-    git checkout -- .
-    git clean -xfd
-    ./bootstrap
-    make -f examples/Makefile-nrf52840 ${OPENTHREAD_FLAGS}
-    mv output/nrf52840 ../output/nrf52840-a
-
-    curl -s "${SIZE_REPORT_URL}/bash" > size-report
-    chmod a+x size-report
-
-    ./size-report init OpenThread
-
-    ./size-report size ../output/nrf52840-a/bin/ot-cli-ftd ../output/nrf52840-b/bin/ot-cli-ftd
-    ./size-report size ../output/nrf52840-a/bin/ot-cli-mtd ../output/nrf52840-b/bin/ot-cli-mtd
-    ./size-report size ../output/nrf52840-a/bin/ot-ncp-ftd ../output/nrf52840-b/bin/ot-ncp-ftd
-    ./size-report size ../output/nrf52840-a/bin/ot-ncp-mtd ../output/nrf52840-b/bin/ot-ncp-mtd
-    ./size-report size ../output/nrf52840-a/bin/ot-rcp     ../output/nrf52840-b/bin/ot-rcp
-
-    ./size-report size ../output/nrf52840-a/lib/libopenthread-cli-ftd.a ../output/nrf52840-b/lib/libopenthread-cli-ftd.a
-    ./size-report size ../output/nrf52840-a/lib/libopenthread-cli-mtd.a ../output/nrf52840-b/lib/libopenthread-cli-mtd.a
-    ./size-report size ../output/nrf52840-a/lib/libopenthread-ftd.a     ../output/nrf52840-b/lib/libopenthread-ftd.a
-    ./size-report size ../output/nrf52840-a/lib/libopenthread-mtd.a     ../output/nrf52840-b/lib/libopenthread-mtd.a
-    ./size-report size ../output/nrf52840-a/lib/libopenthread-ncp-ftd.a ../output/nrf52840-b/lib/libopenthread-ncp-ftd.a
-    ./size-report size ../output/nrf52840-a/lib/libopenthread-ncp-mtd.a ../output/nrf52840-b/lib/libopenthread-ncp-mtd.a
-    ./size-report size ../output/nrf52840-a/lib/libopenthread-rcp.a     ../output/nrf52840-b/lib/libopenthread-rcp.a
-    ./size-report size ../output/nrf52840-a/lib/libopenthread-radio.a   ../output/nrf52840-b/lib/libopenthread-radio.a
-
-    ./size-report post
-}
-
-main()
-{
-  case $1 in
-    setup)
-      setup_arm_gcc_7
-      ;;
-    nrf52840)
-      size_nrf52840
-      ;;
-    '')
-      setup_arm_gcc_7
-      size_nrf52840
-      ;;
-    *)
-      echo "USAGE: $0 [setup|nrf52840]"
-      exit 1
-      ;;
-  esac
-}
-
-main "$@"
diff --git a/.travis/script.sh b/.travis/script.sh
deleted file mode 100755
index bd39ba2..0000000
--- a/.travis/script.sh
+++ /dev/null
@@ -1,653 +0,0 @@
-#!/bin/sh
-#
-#  Copyright (c) 2016, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-die() {
-	echo " *** ERROR: " $*
-	exit 1
-}
-
-set -x
-
-python --version || die
-
-[ $BUILD_TARGET != scan-build ] || {
-    ./bootstrap || die
-
-    export CPPFLAGS="-DMBEDTLS_DEBUG_C"
-    export CPPFLAGS="${CPPFLAGS} -I${TRAVIS_BUILD_DIR}/third_party/mbedtls"
-    export CPPFLAGS="${CPPFLAGS} -I${TRAVIS_BUILD_DIR}/third_party/mbedtls/repo/include"
-    export CPPFLAGS="${CPPFLAGS} -DMBEDTLS_CONFIG_FILE=\\\"mbedtls-config.h\\\""
-
-    # UART transport
-    export CPPFLAGS="${CPPFLAGS}                          \
-        -DOPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1         \
-        -DOPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1        \
-        -DOPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE=1      \
-        -DOPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE=1      \
-        -DOPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1    \
-        -DOPENTHREAD_CONFIG_COAP_API_ENABLE=1             \
-        -DOPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE=1      \
-        -DOPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1         \
-        -DOPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE=1         \
-        -DOPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE=1         \
-        -DOPENTHREAD_CONFIG_DIAG_ENABLE=1                 \
-        -DOPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1           \
-        -DOPENTHREAD_CONFIG_ECDSA_ENABLE=1                \
-        -DOPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE=1    \
-        -DOPENTHREAD_CONFIG_LEGACY_ENABLE=1               \
-        -DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1        \
-        -DOPENTHREAD_CONFIG_JOINER_ENABLE=1               \
-        -DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1             \
-        -DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1           \
-        -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1             \
-        -DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1     \
-        -DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1          \
-        -DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1  \
-        -DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1 \
-        -DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
-
-    scan-build ./configure                \
-        --enable-builtin-mbedtls=no       \
-        --enable-cli                      \
-        --enable-executable=no            \
-        --enable-ftd                      \
-        --enable-mtd                      \
-        --enable-ncp                      \
-        --enable-radio-only               \
-        --with-examples=posix || die
-
-    scan-build --status-bugs -analyze-headers -v make -j2 || die
-
-    # SPI transport
-    scan-build ./configure                \
-        --enable-builtin-mbedtls=no       \
-        --enable-cli                      \
-        --enable-executable=no            \
-        --enable-ftd                      \
-        --enable-mtd                      \
-        --enable-ncp                      \
-        --enable-radio-only               \
-        --with-examples=posix || die
-
-    scan-build --status-bugs -analyze-headers -v make -j2 || die
-}
-
-[ $BUILD_TARGET != android-build ] || {
-    (cd .. && ${TRAVIS_BUILD_DIR}/.travis/check-android-build) || die
-}
-
-[ $BUILD_TARGET != gn-build ] || {
-    (cd ${TRAVIS_BUILD_DIR} && .travis/check-gn-build) || die
-}
-
-build_cc1352() {
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    COMMISSIONER=1 JOINER=1 SLAAC=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 make -f examples/Makefile-cc1352 || die
-    arm-none-eabi-size  output/cc1352/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/cc1352/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/cc1352/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/cc1352/bin/ot-ncp-mtd || die
-}
-
-build_cc2538() {
-    git checkout -- . || die
-    git clean -xfd || die
-    mkdir build && cd build || die
-    cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=examples/platforms/cc2538/arm-none-eabi.cmake -DOT_PLATFORM=cc2538 .. || die
-    ninja || die
-    cd .. || die
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    COMMISSIONER=1 JOINER=1 SLAAC=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 make -f examples/Makefile-cc2538 || die
-    arm-none-eabi-size  output/cc2538/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/cc2538/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/cc2538/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/cc2538/bin/ot-ncp-mtd || die
-}
-
-build_cc2650() {
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    make -f examples/Makefile-cc2650 || die
-    arm-none-eabi-size  output/cc2650/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/cc2650/bin/ot-ncp-mtd || die
-}
-
-build_cc2652() {
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    COMMISSIONER=1 JOINER=1 SLAAC=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 make -f examples/Makefile-cc2652 || die
-    arm-none-eabi-size  output/cc2652/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/cc2652/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/cc2652/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/cc2652/bin/ot-ncp-mtd || die
-}
-
-build_kw41z() {
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    COMMISSIONER=1 JOINER=1 SLAAC=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 make -f examples/Makefile-kw41z || die
-    arm-none-eabi-size  output/kw41z/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/kw41z/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/kw41z/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/kw41z/bin/ot-ncp-mtd || die
-}
-
-build_nrf52811() {
-    # Default OpenThread switches for nRF52811 platform
-    OPENTHREAD_FLAGS="BORDER_ROUTER=1 COAP=1 DNS_CLIENT=1 LINK_RAW=1 MAC_FILTER=1 MTD_NETDIAG=1"
-
-    # UART transport
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    make -f examples/Makefile-nrf52811 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52811/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/nrf52811/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52811/bin/ot-rcp || die
-
-    # SPI transport for NCP
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    NCP_SPI=1 make -f examples/Makefile-nrf52811 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52811/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52811/bin/ot-rcp || die
-
-    # Build without transport (no CLI or NCP applications)
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    DISABLE_TRANSPORTS=1 make -f examples/Makefile-nrf52811 || die
-}
-
-build_nrf52833() {
-    # Default OpenThread switches for nRF52833 platform
-    OPENTHREAD_FLAGS="BORDER_AGENT=1 BORDER_ROUTER=1 COAP=1 COAPS=1 COMMISSIONER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 ECDSA=1 FULL_LOGS=1 IP6_FRAGM=1 JOINER=1 LINK_RAW=1 MAC_FILTER=1 MTD_NETDIAG=1 SERVICE=1 SLAAC=1 SNTP_CLIENT=1 UDP_FORWARD=1"
-
-    # UART transport
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    make -f examples/Makefile-nrf52833 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-rcp || die
-
-    # USB transport
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    USB=1 make -f examples/Makefile-nrf52833 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-rcp || die
-
-    # SPI transport for NCP
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    NCP_SPI=1 make -f examples/Makefile-nrf52833 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52833/bin/ot-rcp || die
-
-    # Build without transport (no CLI or NCP applications)
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    DISABLE_TRANSPORTS=1 make -f examples/Makefile-nrf52833 $OPENTHREAD_FLAGS || die
-}
-
-build_nrf52840() {
-    # Default OpenThread switches for nRF52840 platform
-    OPENTHREAD_FLAGS="BORDER_AGENT=1 BORDER_ROUTER=1 COAP=1 COAPS=1 COMMISSIONER=1 DEBUG=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 ECDSA=1 FULL_LOGS=1 IP6_FRAGM=1 JOINER=1 LINK_RAW=1 MAC_FILTER=1 MTD_NETDIAG=1 SERVICE=1 SLAAC=1 SNTP_CLIENT=1 UDP_FORWARD=1"
-
-    # UART transport
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    make -f examples/Makefile-nrf52840 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-rcp || die
-
-    # USB transport with bootloader e.g. to support PCA10059 dongle
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    USB=1 BOOTLOADER=1 make -f examples/Makefile-nrf52840 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-rcp || die
-
-    # SPI transport for NCP
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    NCP_SPI=1 make -f examples/Makefile-nrf52840 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-rcp || die
-
-    # Build without transport (no CLI or NCP applications)
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    DISABLE_TRANSPORTS=1 make -f examples/Makefile-nrf52840 $OPENTHREAD_FLAGS || die
-
-    # Software cryptography
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    DISABLE_BUILTIN_MBEDTLS=0 make -f examples/Makefile-nrf52840 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-rcp || die
-
-    # Software cryptography with threading support
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    DISABLE_BUILTIN_MBEDTLS=0 MBEDTLS_THREADING=1 make -f examples/Makefile-nrf52840 $OPENTHREAD_FLAGS || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-ncp-mtd || die
-    arm-none-eabi-size  output/nrf52840/bin/ot-rcp || die
-}
-
-build_qpg6095() {
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    COMMISSIONER=1 JOINER=1 SLAAC=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 make -f examples/Makefile-qpg6095 || die
-    arm-none-eabi-size  output/qpg6095/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/qpg6095/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/qpg6095/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/qpg6095/bin/ot-ncp-mtd || die
-}
-
-build_samr21() {
-    git checkout -- . || die
-    git clean -xfd || die
-    wget http://ww1.microchip.com/downloads/en/DeviceDoc/asf-standalone-archive-3.45.0.85.zip || die
-    unzip -qq asf-standalone-archive-3.45.0.85.zip || die
-    mv xdk-asf-3.45.0 third_party/microchip/asf || die
-    ./bootstrap || die
-    COMMISSIONER=1 JOINER=1 SLAAC=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 make -f examples/Makefile-samr21 || die
-    arm-none-eabi-size  output/samr21/bin/ot-cli-ftd || die
-    arm-none-eabi-size  output/samr21/bin/ot-cli-mtd || die
-    arm-none-eabi-size  output/samr21/bin/ot-ncp-ftd || die
-    arm-none-eabi-size  output/samr21/bin/ot-ncp-mtd || die
-}
-
-[ $BUILD_TARGET != arm-gcc-4 ] || {
-    export PATH=/tmp/gcc-arm-none-eabi-4_9-2015q3/bin:$PATH || die
-
-    build_cc1352
-    build_cc2538
-    build_cc2650
-    build_cc2652
-    build_kw41z
-    build_nrf52811
-    build_nrf52833
-    build_nrf52840
-    build_qpg6095
-    build_samr21
-}
-
-[ $BUILD_TARGET != arm-gcc-5 ] || {
-    export PATH=/tmp/gcc-arm-none-eabi-5_4-2016q3/bin:$PATH || die
-
-    build_cc1352
-    build_cc2538
-    build_cc2650
-    build_cc2652
-    build_kw41z
-    build_nrf52811
-    build_nrf52833
-    build_nrf52840
-    build_qpg6095
-    build_samr21
-}
-
-[ $BUILD_TARGET != arm-gcc-6 ] || {
-    export PATH=/tmp/gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH || die
-
-    build_cc1352
-    build_cc2538
-    build_cc2650
-    build_cc2652
-    build_kw41z
-    build_nrf52811
-    build_nrf52833
-    build_nrf52840
-    build_qpg6095
-    build_samr21
-}
-
-[ $BUILD_TARGET != arm-gcc-7 ] || {
-    export PATH=/tmp/gcc-arm-none-eabi-7-2018-q2-update/bin:$PATH || die
-
-    build_cc1352
-    build_cc2538
-    build_cc2650
-    build_cc2652
-    build_kw41z
-    build_nrf52811
-    build_nrf52833
-    build_nrf52840
-    build_qpg6095
-    build_samr21
-}
-
-[ $BUILD_TARGET != arm-gcc-8 ] || {
-    export PATH=/tmp/gcc-arm-none-eabi-8-2018-q4-major/bin:$PATH || die
-
-    build_cc1352
-    build_cc2538
-    build_cc2650
-    build_cc2652
-    build_kw41z
-    build_nrf52811
-    build_nrf52833
-    build_nrf52840
-    build_qpg6095
-    build_samr21
-}
-
-[ $BUILD_TARGET != arm-gcc-9 ] || {
-    export PATH=/tmp/gcc-arm-none-eabi-9-2019-q4-major/bin:$PATH || die
-
-    build_cc1352
-    build_cc2538
-    build_cc2650
-    build_cc2652
-    build_kw41z
-    build_nrf52811
-    build_nrf52833
-    build_nrf52840
-    build_qpg6095
-    build_samr21
-}
-
-[ $BUILD_TARGET != posix ] || {
-    git checkout -- . || die
-    git clean -xfd || die
-    mkdir build && cd build || die
-    cmake -GNinja -DOT_PLATFORM=posix .. || die
-    ninja || die
-    cd .. || die
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    CPPFLAGS=-DOPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_NONE make -f examples/Makefile-posix || die
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    CPPFLAGS=-DOPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_DEBG make -f examples/Makefile-posix || die
-
-    export CPPFLAGS="                                             \
-        -DOPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE=1              \
-        -DOPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1                 \
-        -DOPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1                \
-        -DOPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE=1              \
-        -DOPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE=1              \
-        -DOPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1            \
-        -DOPENTHREAD_CONFIG_COAP_API_ENABLE=1                     \
-        -DOPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE=1              \
-        -DOPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1                 \
-        -DOPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE=1                 \
-        -DOPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE=1                 \
-        -DOPENTHREAD_CONFIG_DIAG_ENABLE=1                         \
-        -DOPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1                   \
-        -DOPENTHREAD_CONFIG_ECDSA_ENABLE=1                        \
-        -DOPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE=1            \
-        -DOPENTHREAD_CONFIG_IP6_SLAAC_ENABLE=1                    \
-        -DOPENTHREAD_CONFIG_LEGACY_ENABLE=1                       \
-        -DOPENTHREAD_CONFIG_MAC_BEACON_RSP_WHEN_JOINABLE_ENABLE=1 \
-        -DOPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE=1           \
-        -DOPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE=1    \
-        -DOPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE           \
-        -DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1                \
-        -DOPENTHREAD_CONFIG_JOINER_ENABLE=1                       \
-        -DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1                     \
-        -DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1            \
-        -DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1                   \
-        -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1                     \
-        -DOPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1               \
-        -DOPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE=1          \
-        -DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1          \
-        -DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1             \
-        -DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1                  \
-        -DOPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE=1         \
-        -DOPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE=1        \
-        -DOPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE=1         \
-        -DOPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE=1          \
-        -DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1          \
-        -DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1         \
-        -DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    make -f examples/Makefile-posix || die
-
-    export CPPFLAGS="                                    \
-        -DOPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1       \
-        -DOPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE=1     \
-        -DOPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE=1     \
-        -DOPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1   \
-        -DOPENTHREAD_CONFIG_DIAG_ENABLE=1                \
-        -DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1       \
-        -DOPENTHREAD_CONFIG_LEGACY_ENABLE=1              \
-        -DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1          \
-        -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1             \
-        -DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    CPPFLAGS=-DOPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE=1 make -f examples/Makefile-posix || die
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    CPPFLAGS=-DOPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE=1 make -f examples/Makefile-posix || die
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    ./configure                             \
-        --enable-ncp                        \
-        --enable-ftd                        \
-        --enable-mtd                        \
-        --with-examples=posix               \
-        --disable-docs                      \
-        --disable-tests                     \
-        --with-vendor-extension=./src/core/common/extension_example.cpp || die
-    make -j 8 || die
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    ./configure                             \
-        --enable-cli                        \
-        --enable-mtd                        \
-        --with-examples=posix               \
-        --disable-docs                      \
-        --disable-tests || die
-    make -j 8 || die
-
-    export CPPFLAGS="                               \
-        -DOPENTHREAD_CONFIG_ANOUNCE_SENDER_ENABLE=1 \
-        -DOPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1      \
-        -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    ./configure                             \
-        --enable-cli                        \
-        --enable-ncp                        \
-        --enable-ftd                        \
-        --enable-mtd                        \
-        --enable-radio-only                 \
-        --with-examples=posix || die
-    make -j 8 || die
-
-    export CPPFLAGS="                               \
-        -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    ./configure                             \
-        --enable-ncp                        \
-        --enable-ftd                        \
-        --enable-mtd                        \
-        --with-examples=posix               \
-        --disable-docs                      \
-        --disable-tests                     \
-        --with-ncp-vendor-hook-source=./src/ncp/example_vendor_hook.cpp || die
-    make -j 8 || die
-}
-
-[ $BUILD_TARGET != posix-distcheck ] || {
-    export ASAN_SYMBOLIZER_PATH=`which llvm-symbolizer` || die
-    export ASAN_OPTIONS=symbolize=1 || die
-    export DISTCHECK_CONFIGURE_FLAGS= CPPFLAGS=-DOPENTHREAD_POSIX_VIRTUAL_TIME=1 || die
-    ./bootstrap || die
-    REFERENCE_DEVICE=1 make -f examples/Makefile-posix distcheck || die
-}
-
-[ $BUILD_TARGET != posix-32-bit ] || {
-    ./bootstrap || die
-    REFERENCE_DEVICE=1 COVERAGE=1 CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 make -f examples/Makefile-posix check || die
-}
-
-[ $BUILD_TARGET != posix-app-cli ] || {
-    ./bootstrap || die
-    # enable code coverage for OpenThread transceiver only
-    COVERAGE=1 VIRTUAL_TIME_UART=1 make -f examples/Makefile-posix || die
-    # readline supports pipe, editline does not
-    REFERENCE_DEVICE=1 COVERAGE=1 READLINE=readline make -f src/posix/Makefile-posix || die
-    REFERENCE_DEVICE=1 COVERAGE=1 PYTHONUNBUFFERED=1 OT_CLI_PATH="$(pwd)/$(ls output/posix/*/bin/ot-cli) -v" RADIO_DEVICE="$(pwd)/$(ls output/*/bin/ot-rcp)" make -f src/posix/Makefile-posix check || die
-}
-
-[ $BUILD_TARGET != posix-app-pty ] || {
-    # check daemon mode
-    git checkout -- . || die
-    git clean -xfd || die
-    mkdir build && cd build || die
-    cmake -GNinja -DOT_PLATFORM=posix-host -DOT_DAEMON=ON .. || die
-    ninja || die
-    cd .. || die
-
-    git checkout -- . || die
-    git clean -xfd || die
-    mkdir build && cd build || die
-    cmake -GNinja -DOT_PLATFORM=posix-host .. || die
-    ninja || die
-    cd .. || die
-
-    ./bootstrap
-    .travis/check-posix-app-pty || die
-}
-
-[ $BUILD_TARGET != posix-app-migrate ] || {
-    ./bootstrap
-    .travis/check-ncp-rcp-migrate || die
-}
-
-[ $BUILD_TARGET != posix-mtd ] || {
-    ./bootstrap || die
-    REFERENCE_DEVICE=1 COVERAGE=1 CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 USE_MTD=1 make -f examples/Makefile-posix check || die
-}
-
-[ $BUILD_TARGET != posix-ncp-spi ] || {
-    CPPFLAGS="-DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1"
-
-    ./bootstrap || die
-    make -f examples/Makefile-posix check configure_OPTIONS="--enable-ncp --enable-ftd --with-examples=posix" || die
-}
-
-[ $BUILD_TARGET != posix-app-ncp ] || {
-    ./bootstrap || die
-    REFERENCE_DEVICE=1 COVERAGE=1 VIRTUAL_TIME_UART=1 make -f examples/Makefile-posix || die
-    # enable code coverage for OpenThread posix radio
-    REFERENCE_DEVICE=1 COVERAGE=1 READLINE=readline make -f src/posix/Makefile-posix || die
-    REFERENCE_DEVICE=1 COVERAGE=1 PYTHONUNBUFFERED=1 OT_NCP_PATH="$(pwd)/$(ls output/posix/*/bin/ot-ncp)" RADIO_DEVICE="$(pwd)/$(ls output/*/bin/ot-rcp)" NODE_TYPE=ncp-sim make -f src/posix/Makefile-posix check || die
-}
-
-[ $BUILD_TARGET != posix-app-spi ] || {
-    ./bootstrap || die
-    REFERENCE_DEVICE=1 READLINE=readline RCP_SPI=1 make -f src/posix/Makefile-posix || die
-}
-
-[ $BUILD_TARGET != posix-ncp ] || {
-    ./bootstrap || die
-    REFERENCE_DEVICE=1 COVERAGE=1 PYTHONUNBUFFERED=1 NODE_TYPE=ncp-sim make -f examples/Makefile-posix check || die
-}
-
-[ $BUILD_TARGET != toranj-test-framework ] || {
-    top_builddir=$(pwd)/build/toranj ./tests/toranj/start.sh || die
-}
-
-[ $BUILD_TARGET != osx ] || {
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    make -f examples/Makefile-posix || die
-
-    git checkout -- . || die
-    git clean -xfd || die
-    ./bootstrap || die
-    make -f src/posix/Makefile-posix || die
-}
diff --git a/Android.mk b/Android.mk
index 2fddabf..234dd5a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,32 +32,58 @@
 OPENTHREAD_SOURCE_VERSION := $(shell git -C $(LOCAL_PATH) describe --always --match "[0-9].*" 2> /dev/null)
 OPENTHREAD_PROJECT_CFLAGS ?= -DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"openthread-core-posix-config.h\"
 
-OPENTHREAD_COMMON_FLAGS                                          := \
+OPENTHREAD_PUBLIC_CFLAGS                                         := \
+    -DOPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1                       \
+    -DOPENTHREAD_CONFIG_FILE=\<openthread-config-android.h\>        \
     -DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1                  \
     -DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1                         \
+    -DOPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE=1                      \
+    -DOPENTHREAD_FTD=1                                              \
+    -DOPENTHREAD_POSIX=1                                            \
+    -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1          \
+    $(NULL)
+
+OPENTHREAD_PRIVATE_CFLAGS                                        := \
+    -DMBEDTLS_CONFIG_FILE=\"mbedtls-config.h\"                      \
     -DPACKAGE=\"openthread\"                                        \
     -DPACKAGE_BUGREPORT=\"openthread-devel@googlegroups.com\"       \
     -DPACKAGE_NAME=\"OPENTHREAD\"                                   \
     -DPACKAGE_STRING=\"OPENTHREAD\ $(OPENTHREAD_DEFAULT_VERSION)\"  \
-    -DPACKAGE_VERSION=\"$(OPENTHREAD_SOURCE_VERSION)\"              \
     -DPACKAGE_TARNAME=\"openthread\"                                \
-    -DVERSION=\"$(OPENTHREAD_DEFAULT_VERSION)\"                     \
     -DPACKAGE_URL=\"http://github.com/openthread/openthread\"       \
-    -DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1                         \
+    -DPACKAGE_VERSION=\"$(OPENTHREAD_SOURCE_VERSION)\"              \
+    -DSPINEL_PLATFORM_HEADER=\"spinel_platform.h\"                  \
+    -DVERSION=\"$(OPENTHREAD_DEFAULT_VERSION)\"                     \
     $(NULL)
 
 # Enable required features for on-device tests.
 ifeq ($(TARGET_BUILD_VARIANT),eng)
-OPENTHREAD_COMMON_FLAGS                                          += \
+OPENTHREAD_PUBLIC_CFLAGS                                         += \
     -DOPENTHREAD_CONFIG_DIAG_ENABLE=1                               \
     $(NULL)
 endif
 
+ifeq ($(USE_OTBR_DAEMON), 1)
+OPENTHREAD_PUBLIC_CFLAGS                                         += \
+    -DOPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1                     \
+    -DOPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1                       \
+    -DOPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE=1  \
+    -DOPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE=1                       \
+    $(NULL)
+else
+OPENTHREAD_PUBLIC_CFLAGS += -DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1
+endif
+
+ifeq ($(USE_OT_RCP_BUS), spi)
+OPENTHREAD_PUBLIC_CFLAGS += -DOPENTHREAD_POSIX_CONFIG_RCP_BUS=OT_POSIX_RCP_BUS_SPI
+else
+OPENTHREAD_PUBLIC_CFLAGS += -DOPENTHREAD_POSIX_CONFIG_RCP_BUS=OT_POSIX_RCP_BUS_UART
+endif
+
 # Enable all optional features for CI tests.
 ifeq ($(TARGET_PRODUCT),generic)
-OPENTHREAD_COMMON_FLAGS                                          += \
+OPENTHREAD_PUBLIC_CFLAGS                                         += \
     -DOPENTHREAD_CONFIG_COAP_API_ENABLE=1                           \
-    -DOPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1                       \
     -DOPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE=1                       \
     -DOPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE=1                       \
     -DOPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1                         \
@@ -87,28 +113,38 @@
     $(LOCAL_PATH)/src/core                                  \
     $(LOCAL_PATH)/src/ncp                                   \
     $(LOCAL_PATH)/src/posix/platform                        \
+    $(LOCAL_PATH)/src/posix/platform/include                \
     $(LOCAL_PATH)/third_party                               \
     $(LOCAL_PATH)/third_party/mbedtls                       \
     $(LOCAL_PATH)/third_party/mbedtls/repo/include          \
     $(NULL)
 
 LOCAL_CFLAGS                                                                := \
-    -DMBEDTLS_CONFIG_FILE=\"mbedtls-config.h\"                                 \
-    -DOPENTHREAD_CONFIG_FILE=\<openthread-config-android.h\>                   \
-    $(OPENTHREAD_COMMON_FLAGS)                                                 \
-    -DOPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE=1                          \
-    -DOPENTHREAD_FTD=1                                                         \
-    -DOPENTHREAD_POSIX=1                                                       \
-    -DOPENTHREAD_POSIX_RCP_UART_ENABLE=1                                       \
-    -DSPINEL_PLATFORM_HEADER=\"spinel_platform.h\"                             \
+    $(OPENTHREAD_PUBLIC_CFLAGS)                                                \
+    $(OPENTHREAD_PRIVATE_CFLAGS)                                               \
     $(OPENTHREAD_PROJECT_CFLAGS)                                               \
     $(NULL)
 
+LOCAL_EXPORT_CFLAGS                                        := \
+    $(OPENTHREAD_PUBLIC_CFLAGS)                               \
+    $(OPENTHREAD_PROJECT_CFLAGS)                              \
+    $(NULL)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS     := \
+    $(OPENTHREAD_PROJECT_INCLUDES) \
+    $(LOCAL_PATH)/include          \
+    $(LOCAL_PATH)/src              \
+    $(NULL)
+
 LOCAL_CPPFLAGS                                                              := \
+    -std=c++11                                                                 \
+    -pedantic-errors                                                           \
     -Wno-non-virtual-dtor                                                      \
     $(NULL)
 
 LOCAL_SRC_FILES                                          := \
+    src/core/api/backbone_router_api.cpp                    \
+    src/core/api/backbone_router_ftd_api.cpp                \
     src/core/api/border_router_api.cpp                      \
     src/core/api/channel_manager_api.cpp                    \
     src/core/api/channel_monitor_api.cpp                    \
@@ -130,6 +166,7 @@
     src/core/api/logging_api.cpp                            \
     src/core/api/message_api.cpp                            \
     src/core/api/netdata_api.cpp                            \
+    src/core/api/netdiag_api.cpp                            \
     src/core/api/random_crypto_api.cpp                      \
     src/core/api/random_noncrypto_api.cpp                   \
     src/core/api/server_api.cpp                             \
@@ -137,6 +174,8 @@
     src/core/api/thread_api.cpp                             \
     src/core/api/thread_ftd_api.cpp                         \
     src/core/api/udp_api.cpp                                \
+    src/core/backbone_router/bbr_leader.cpp                 \
+    src/core/backbone_router/bbr_local.cpp                  \
     src/core/coap/coap.cpp                                  \
     src/core/coap/coap_message.cpp                          \
     src/core/coap/coap_secure.cpp                           \
@@ -179,8 +218,8 @@
     src/core/meshcop/energy_scan_client.cpp                 \
     src/core/meshcop/joiner.cpp                             \
     src/core/meshcop/joiner_router.cpp                      \
-    src/core/meshcop/leader.cpp                             \
     src/core/meshcop/meshcop.cpp                            \
+    src/core/meshcop/meshcop_leader.cpp                     \
     src/core/meshcop/meshcop_tlvs.cpp                       \
     src/core/meshcop/panid_query_client.cpp                 \
     src/core/meshcop/timestamp.cpp                          \
@@ -195,13 +234,15 @@
     src/core/net/ip6_mpl.cpp                                \
     src/core/net/netif.cpp                                  \
     src/core/net/udp6.cpp                                   \
+    src/core/radio/radio.cpp                                \
     src/core/radio/radio_callbacks.cpp                      \
     src/core/radio/radio_platform.cpp                       \
     src/core/thread/address_resolver.cpp                    \
     src/core/thread/announce_begin_server.cpp               \
     src/core/thread/announce_sender.cpp                     \
     src/core/thread/child_table.cpp                         \
-    src/core/thread/device_mode.cpp                         \
+    src/core/thread/discover_scanner.cpp                    \
+    src/core/thread/dua_manager.cpp                         \
     src/core/thread/energy_scan_server.cpp                  \
     src/core/thread/indirect_sender.cpp                     \
     src/core/thread/key_manager.cpp                         \
@@ -212,10 +253,12 @@
     src/core/thread/mesh_forwarder_mtd.cpp                  \
     src/core/thread/mle.cpp                                 \
     src/core/thread/mle_router.cpp                          \
+    src/core/thread/mle_types.cpp                           \
     src/core/thread/network_data.cpp                        \
     src/core/thread/network_data_leader.cpp                 \
     src/core/thread/network_data_leader_ftd.cpp             \
     src/core/thread/network_data_local.cpp                  \
+    src/core/thread/network_data_notifier.cpp               \
     src/core/thread/network_diagnostic.cpp                  \
     src/core/thread/panid_query_server.cpp                  \
     src/core/thread/router_table.cpp                        \
@@ -229,20 +272,25 @@
     src/core/utils/jam_detector.cpp                         \
     src/core/utils/parse_cmdline.cpp                        \
     src/core/utils/slaac_address.cpp                        \
-    src/ncp/hdlc.cpp                                        \
-    src/ncp/spinel.c                                        \
-    src/ncp/spinel_decoder.cpp                              \
-    src/ncp/spinel_encoder.cpp                              \
-    src/posix/platform/alarm.c                              \
-    src/posix/platform/entropy.c                            \
+    src/lib/hdlc/hdlc.cpp                                   \
+    src/lib/platform/exit_code.c                            \
+    src/lib/spinel/spinel.c                                 \
+    src/lib/spinel/spinel_decoder.cpp                       \
+    src/lib/spinel/spinel_encoder.cpp                       \
+    src/lib/url/url.cpp                                     \
+    src/posix/platform/alarm.cpp                            \
+    src/posix/platform/entropy.cpp                          \
     src/posix/platform/hdlc_interface.cpp                   \
-    src/posix/platform/logging.c                            \
-    src/posix/platform/misc.c                               \
-    src/posix/platform/radio_spinel.cpp                     \
+    src/posix/platform/logging.cpp                          \
+    src/posix/platform/misc.cpp                             \
+    src/posix/platform/netif.cpp                            \
+    src/posix/platform/radio.cpp                            \
+    src/posix/platform/radio_url.cpp                        \
     src/posix/platform/settings.cpp                         \
     src/posix/platform/spi_interface.cpp                    \
-    src/posix/platform/system.c                             \
-    src/posix/platform/uart.c                               \
+    src/posix/platform/system.cpp                           \
+    src/posix/platform/uart.cpp                             \
+    src/posix/platform/udp.cpp                              \
     third_party/mbedtls/repo/library/md.c                   \
     third_party/mbedtls/repo/library/md_wrap.c              \
     third_party/mbedtls/repo/library/memory_buffer_alloc.c  \
@@ -275,6 +323,51 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_MODULE := libopenthread-cli
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_C_INCLUDES                                         := \
+    $(OPENTHREAD_PROJECT_INCLUDES)                          \
+    $(LOCAL_PATH)/include                                   \
+    $(LOCAL_PATH)/src                                       \
+    $(LOCAL_PATH)/src/cli                                   \
+    $(LOCAL_PATH)/src/core                                  \
+    $(LOCAL_PATH)/src/posix/platform                        \
+    $(LOCAL_PATH)/src/posix/platform/include                \
+    $(LOCAL_PATH)/third_party/mbedtls                       \
+    $(LOCAL_PATH)/third_party/mbedtls/repo/include          \
+    $(NULL)
+
+LOCAL_CFLAGS                                                                := \
+    $(OPENTHREAD_PUBLIC_CFLAGS)                                                \
+    $(OPENTHREAD_PRIVATE_CFLAGS)                                               \
+    -DOPENTHREAD_CONFIG_UART_CLI_RAW=1                                         \
+    $(OPENTHREAD_PROJECT_CFLAGS)                                               \
+    $(NULL)
+
+LOCAL_CPPFLAGS                                                              := \
+    -std=c++11                                                                 \
+    -pedantic-errors                                                           \
+    -Wno-non-virtual-dtor                                                      \
+    $(NULL)
+
+LOCAL_SRC_FILES                            := \
+    src/cli/cli.cpp                           \
+    src/cli/cli_coap.cpp                      \
+    src/cli/cli_coap_secure.cpp               \
+    src/cli/cli_commissioner.cpp              \
+    src/cli/cli_console.cpp                   \
+    src/cli/cli_dataset.cpp                   \
+    src/cli/cli_joiner.cpp                    \
+    src/cli/cli_server.cpp                    \
+    src/cli/cli_uart.cpp                      \
+    src/cli/cli_udp.cpp                       \
+    $(NULL)
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
 LOCAL_MODULE := ot-cli
 LOCAL_MODULE_TAGS := eng
 
@@ -285,49 +378,78 @@
     $(LOCAL_PATH)/src/cli                                   \
     $(LOCAL_PATH)/src/core                                  \
     $(LOCAL_PATH)/src/posix/platform                        \
+    $(LOCAL_PATH)/src/posix/platform/include                \
     $(LOCAL_PATH)/third_party/mbedtls                       \
     $(LOCAL_PATH)/third_party/mbedtls/repo/include          \
     $(NULL)
 
 LOCAL_CFLAGS                                                                := \
-    -DMBEDTLS_CONFIG_FILE=\"mbedtls-config.h\"                                 \
-    -DOPENTHREAD_CONFIG_FILE=\<openthread-config-android.h\>                   \
-    $(OPENTHREAD_COMMON_FLAGS)                                                 \
-    -DOPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE=1                          \
-    -DOPENTHREAD_CONFIG_UART_CLI_RAW=1                                         \
-    -DOPENTHREAD_FTD=1                                                         \
-    -DOPENTHREAD_POSIX=1                                                       \
-    -DOPENTHREAD_POSIX_APP_TYPE=2                                              \
-    -DOPENTHREAD_POSIX_RCP_UART_ENABLE=1                                       \
-    -DSPINEL_PLATFORM_HEADER=\"spinel_platform.h\"                             \
+    $(OPENTHREAD_PUBLIC_CFLAGS)                                                \
+    $(OPENTHREAD_PRIVATE_CFLAGS)                                               \
+    -DOPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_CLI                          \
     $(OPENTHREAD_PROJECT_CFLAGS)                                               \
     $(NULL)
 
 LOCAL_CPPFLAGS                                                              := \
+    -std=c++11                                                                 \
+    -pedantic-errors                                                           \
     -Wno-non-virtual-dtor                                                      \
     $(NULL)
 
 LOCAL_LDLIBS                               := \
+    -lrt                                      \
     -lutil
 
 LOCAL_SRC_FILES                            := \
-    src/cli/cli.cpp                           \
-    src/cli/cli_coap.cpp                      \
-    src/cli/cli_commissioner.cpp              \
-    src/cli/cli_console.cpp                   \
-    src/cli/cli_dataset.cpp                   \
-    src/cli/cli_joiner.cpp                    \
-    src/cli/cli_server.cpp                    \
-    src/cli/cli_uart.cpp                      \
-    src/cli/cli_udp.cpp                       \
     src/posix/main.c                          \
     $(NULL)
 
-LOCAL_STATIC_LIBRARIES = ot-core
+LOCAL_STATIC_LIBRARIES = libopenthread-cli ot-core
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
 
+LOCAL_MODULE := libopenthread-ncp
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_C_INCLUDES                                         := \
+    $(OPENTHREAD_PROJECT_INCLUDES)                          \
+    $(LOCAL_PATH)/include                                   \
+    $(LOCAL_PATH)/src                                       \
+    $(LOCAL_PATH)/src/core                                  \
+    $(LOCAL_PATH)/src/ncp                                   \
+    $(LOCAL_PATH)/src/posix/platform                        \
+    $(LOCAL_PATH)/src/posix/platform/include                \
+    $(LOCAL_PATH)/third_party/mbedtls                       \
+    $(LOCAL_PATH)/third_party/mbedtls/repo/include          \
+    $(NULL)
+
+LOCAL_CFLAGS                                                                := \
+    $(OPENTHREAD_PUBLIC_CFLAGS)                                                \
+    $(OPENTHREAD_PRIVATE_CFLAGS)                                               \
+    $(OPENTHREAD_PROJECT_CFLAGS)                                               \
+    $(NULL)
+
+LOCAL_CPPFLAGS                                                              := \
+    -std=c++11                                                                 \
+    -pedantic-errors                                                           \
+    -Wno-non-virtual-dtor                                                      \
+    $(NULL)
+
+LOCAL_SRC_FILES                            := \
+    src/lib/spinel/spinel_buffer.cpp          \
+    src/ncp/changed_props_set.cpp             \
+    src/ncp/ncp_base.cpp                      \
+    src/ncp/ncp_base_mtd.cpp                  \
+    src/ncp/ncp_base_ftd.cpp                  \
+    src/ncp/ncp_base_dispatcher.cpp           \
+    src/ncp/ncp_uart.cpp                      \
+    $(NULL)
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
 LOCAL_MODULE := ot-ncp
 LOCAL_MODULE_TAGS := eng
 
@@ -338,40 +460,62 @@
     $(LOCAL_PATH)/src/core                                  \
     $(LOCAL_PATH)/src/ncp                                   \
     $(LOCAL_PATH)/src/posix/platform                        \
+    $(LOCAL_PATH)/src/posix/platform/include                \
     $(LOCAL_PATH)/third_party/mbedtls                       \
     $(LOCAL_PATH)/third_party/mbedtls/repo/include          \
     $(NULL)
 
 LOCAL_CFLAGS                                                                := \
-    -DMBEDTLS_CONFIG_FILE=\"mbedtls-config.h\"                                 \
-    -DOPENTHREAD_CONFIG_FILE=\<openthread-config-android.h\>                   \
-    $(OPENTHREAD_COMMON_FLAGS)                                                 \
-    -DOPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE=1                          \
-    -DOPENTHREAD_FTD=1                                                         \
-    -DOPENTHREAD_POSIX=1                                                       \
-    -DOPENTHREAD_POSIX_APP_TYPE=1                                              \
-    -DOPENTHREAD_POSIX_RCP_UART_ENABLE=1                                       \
-    -DSPINEL_PLATFORM_HEADER=\"spinel_platform.h\"                             \
+    $(OPENTHREAD_PUBLIC_CFLAGS)                                                \
+    $(OPENTHREAD_PRIVATE_CFLAGS)                                               \
+    -DOPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_NCP                          \
     $(OPENTHREAD_PROJECT_CFLAGS)                                               \
     $(NULL)
 
 LOCAL_CPPFLAGS                                                              := \
+    -std=c++11                                                                 \
+    -pedantic-errors                                                           \
     -Wno-non-virtual-dtor                                                      \
     $(NULL)
 
-LOCAL_LDLIBS                               := \
-    -lutil
-
 LOCAL_SRC_FILES                            := \
-    src/ncp/changed_props_set.cpp             \
-    src/ncp/ncp_base.cpp                      \
-    src/ncp/ncp_base_mtd.cpp                  \
-    src/ncp/ncp_base_ftd.cpp                  \
-    src/ncp/ncp_base_dispatcher.cpp           \
-    src/ncp/ncp_buffer.cpp                    \
-    src/ncp/ncp_uart.cpp                      \
     src/posix/main.c                          \
     $(NULL)
 
-LOCAL_STATIC_LIBRARIES = ot-core
+LOCAL_LDLIBS                               := \
+    -lrt                                      \
+    -lutil
+
+LOCAL_STATIC_LIBRARIES = libopenthread-ncp ot-core
+
 include $(BUILD_EXECUTABLE)
+
+ifeq ($(USE_OTBR_DAEMON), 1)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := ot-ctl
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_CPPFLAGS                                                              := \
+    -std=c++11                                                                 \
+    -pedantic-errors                                                           \
+    -Wno-non-virtual-dtor                                                      \
+    $(NULL)
+
+LOCAL_CFLAGS                                               := \
+    -DOPENTHREAD_CONFIG_FILE=\<openthread-config-android.h\>  \
+    $(NULL)
+
+LOCAL_C_INCLUDES                                         := \
+    $(OPENTHREAD_PROJECT_INCLUDES)                          \
+    $(LOCAL_PATH)/include                                   \
+    $(LOCAL_PATH)/src/                                      \
+    $(LOCAL_PATH)/src/core                                  \
+    $(LOCAL_PATH)/src/posix/platform                        \
+    $(LOCAL_PATH)/src/posix/platform/include                \
+    $(NULL)
+
+LOCAL_SRC_FILES := src/posix/client.cpp
+
+include $(BUILD_EXECUTABLE)
+endif # ($(USE_OTBR_DAEMON), 1)
diff --git a/BUILD.gn b/BUILD.gn
index a9dff17..5648551 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -25,11 +25,13 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-static_library("lib-ot-core") {
+source_set("lib-ot-core") {
 
  cflags_cc = [ "-Wno-non-virtual-dtor" ]
 
  sources = [
+    "src/core/api/backbone_router_api.cpp",
+    "src/core/api/backbone_router_ftd_api.cpp",
     "src/core/api/border_agent_api.cpp",
     "src/core/api/border_router_api.cpp",
     "src/core/api/channel_manager_api.cpp",
@@ -64,6 +66,8 @@
     "src/core/api/thread_api.cpp",
     "src/core/api/thread_ftd_api.cpp",
     "src/core/api/udp_api.cpp",
+    "src/core/backbone_router/bbr_leader.cpp",
+    "src/core/backbone_router/bbr_local.cpp",
     "src/core/coap/coap.cpp",
     "src/core/coap/coap_message.cpp",
     "src/core/coap/coap_secure.cpp",
@@ -109,8 +113,8 @@
     "src/core/meshcop/energy_scan_client.cpp",
     "src/core/meshcop/joiner.cpp",
     "src/core/meshcop/joiner_router.cpp",
-    "src/core/meshcop/leader.cpp",
     "src/core/meshcop/meshcop.cpp",
+    "src/core/meshcop/meshcop_leader.cpp",
     "src/core/meshcop/meshcop_tlvs.cpp",
     "src/core/meshcop/panid_query_client.cpp",
     "src/core/meshcop/timestamp.cpp",
@@ -128,11 +132,14 @@
     "src/core/net/udp6.cpp",
     "src/core/radio/radio_callbacks.cpp",
     "src/core/radio/radio_platform.cpp",
+    "src/core/radio/radio.cpp",
+    "src/core/radio/radio.hpp",
     "src/core/thread/address_resolver.cpp",
     "src/core/thread/announce_begin_server.cpp",
     "src/core/thread/announce_sender.cpp",
     "src/core/thread/child_table.cpp",
-    "src/core/thread/device_mode.cpp",
+    "src/core/thread/discover_scanner.cpp",
+    "src/core/thread/dua_manager.cpp",
     "src/core/thread/energy_scan_server.cpp",
     "src/core/thread/indirect_sender.cpp",
     "src/core/thread/key_manager.cpp",
@@ -143,10 +150,12 @@
     "src/core/thread/mesh_forwarder_mtd.cpp",
     "src/core/thread/mle.cpp",
     "src/core/thread/mle_router.cpp",
+    "src/core/thread/mle_types.cpp",
     "src/core/thread/network_data.cpp",
     "src/core/thread/network_data_leader.cpp",
     "src/core/thread/network_data_leader_ftd.cpp",
     "src/core/thread/network_data_local.cpp",
+    "src/core/thread/network_data_notifier.cpp",
     "src/core/thread/network_diagnostic.cpp",
     "src/core/thread/panid_query_server.cpp",
     "src/core/thread/router_table.cpp",
@@ -161,10 +170,26 @@
     "src/core/utils/jam_detector.cpp",
     "src/core/utils/parse_cmdline.cpp",
     "src/core/utils/slaac_address.cpp",
-    "src/ncp/hdlc.cpp",
-    "src/ncp/spinel.c",
-    "src/ncp/spinel_decoder.cpp",
-    "src/ncp/spinel_encoder.cpp",
+    "src/ncp/ncp_base.cpp",
+    "src/ncp/ncp_base_dispatcher.cpp",
+    "src/ncp/ncp_base_radio.cpp",
+    "src/ncp/ncp_base.hpp",
+    "src/ncp/ncp_base_mtd.cpp",
+    "src/ncp/ncp_base_ftd.cpp",
+    "src/ncp/ncp_config.h",
+    "src/ncp/changed_props_set.cpp",
+    "src/ncp/changed_props_set.h",
+
+    "src/lib/hdlc/hdlc.cpp",
+    "src/lib/hdlc/hdlc.hpp",
+    "src/lib/spinel/spinel.c",
+    "src/lib/spinel/spinel_decoder.cpp",
+    "src/lib/spinel/spinel_decoder.hpp",
+    "src/lib/spinel/spinel_encoder.cpp",
+    "src/lib/spinel/spinel_encoder.hpp",
+    "src/lib/spinel/spinel_buffer.cpp",
+    "src/lib/spinel/spinel_buffer.hpp",
+    "src/lib/platform/exit_code.c",
     "third_party/mbedtls/repo/library/md.c",
     "third_party/mbedtls/repo/library/md_wrap.c",
     "third_party/mbedtls/repo/library/memory_buffer_alloc.c",
@@ -189,7 +214,7 @@
     "third_party/mbedtls/repo/library/ssl_ticket.c",
     "third_party/mbedtls/repo/library/ssl_tls.c",
     "third_party/mbedtls/repo/library/aes.c",
-    "third_party/mbedtls/repo/library/ecp.c"
+    "third_party/mbedtls/repo/library/ecp.c",
   ]
 
   # Remove the example as it is not meant for compilation
@@ -202,9 +227,10 @@
     "src",
     "src/core",
     "src/ncp",
+    "src/lib/spinel",
     "third_party",
     "third_party/mbedtls",
-    "third_party/mbedtls/repo/include"
+    "third_party/mbedtls/repo/include",
   ]
 
   defines = [
@@ -212,7 +238,10 @@
     "OPENTHREAD_FTD=1",
     "SPINEL_PLATFORM_HEADER=\"spinel_platform.h\"",
     "OPENTHREAD_CONFIG_FILE=<openthread-config-android.h>",
+    "OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1",
     "PACKAGE_NAME=\"OPENTHREAD-CORE\"",
-    "PACKAGE_VERSION=\"1.0.0\""
+    "PACKAGE_VERSION=\"1.0.0\"",
+    "OPENTHREAD_CONFIG_LOG_PLATFORM=1",
+    "OPENTHREAD_CONFIG_LOG_LEVEL=6",
   ]
 }
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e81b3fb..8e89e1f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,17 +26,54 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-cmake_minimum_required(VERSION 3.13.1)
-project(openthread)
+cmake_policy(SET CMP0048 NEW)
+cmake_minimum_required(VERSION 3.10.2)
+
+file(READ .default-version OT_DEFAULT_VERSION)
+string(STRIP ${OT_DEFAULT_VERSION} OT_DEFAULT_VERSION)
+
+project(openthread VERSION ${OT_DEFAULT_VERSION})
 
 option(OT_BUILD_EXECUTABLES "Build executables" ON)
-option(OT_BUILTIN_MBEDTLS "Enable builtin mbedTLS" ON)
+option(OT_COVERAGE "enable coverage" OFF)
+set(OT_EXTERNAL_MBEDTLS "" CACHE STRING "Specify external mbedtls library")
+
+add_library(ot-config INTERFACE)
+
+target_include_directories(ot-config INTERFACE
+    ${PROJECT_SOURCE_DIR}/include
+    ${PROJECT_SOURCE_DIR}/src
+    ${PROJECT_SOURCE_DIR}/src/core
+)
+
+include(TestBigEndian)
+TEST_BIG_ENDIAN(OT_BIG_ENDIAN)
+if(OT_BIG_ENDIAN)
+    target_compile_definitions(ot-config INTERFACE "BYTE_ORDER_BIG_ENDIAN=1")
+endif()
 
 include("${PROJECT_SOURCE_DIR}/etc/cmake/checks.cmake")
 include("${PROJECT_SOURCE_DIR}/etc/cmake/options.cmake")
 include("${PROJECT_SOURCE_DIR}/etc/cmake/functions.cmake")
 
-file(READ .default-version OT_DEFAULT_VERSION)
+if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
+    option(OT_COMPILE_WARNING_AS_ERROR "whether to include -Werror -pedantic-errors with gcc-compatible compilers")
+    if (OT_COMPILE_WARNING_AS_ERROR)
+        set(OT_CFLAGS -Werror -pedantic-errors)
+    endif()
+
+    if(OT_COVERAGE)
+        target_compile_definitions(ot-config INTERFACE "OPENTHREAD_ENABLE_COVERAGE=1")
+        target_compile_options(ot-config INTERFACE -g -O0 --coverage)
+        target_link_libraries(ot-config INTERFACE --coverage)
+    endif()
+
+    set(OT_CFLAGS
+        $<$<COMPILE_LANGUAGE:C>:${OT_CFLAGS} -Wall -Wextra -Wshadow>
+        $<$<COMPILE_LANGUAGE:CXX>:${OT_CFLAGS} -Wall -Wextra -Wshadow -Wno-c++14-compat -fno-exceptions>
+    )
+endif()
+
 execute_process(
     COMMAND bash "-c" "third_party/nlbuild-autotools/repo/scripts/mkversion -b ${OT_DEFAULT_VERSION}"
     WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
@@ -44,19 +81,46 @@
 )
 message(STATUS "Version: ${OT_VERSION}")
 
-list(APPEND OT_PRIVATE_DEFINES
+target_compile_definitions(ot-config INTERFACE
     "PACKAGE_NAME=\"OPENTHREAD\""
     "PACKAGE_VERSION=\"${OT_VERSION}\""
 )
 
-set(OT_PLATFORM "none" CACHE STRING "Target platform chosen by the user at configure time")
+set(OT_THREAD_VERSION "1.1" CACHE STRING "Thread version chosen by the user at configure time")
+set_property(CACHE OT_THREAD_VERSION PROPERTY STRINGS "1.1" "1.2")
+if(${OT_THREAD_VERSION} EQUAL "1.1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_1")
+elseif(${OT_THREAD_VERSION} EQUAL "1.2")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_2")
+else()
+    message(FATAL_ERROR "Thread version unknown: ${OT_THREAD_VERSION}")
+endif()
 
-ot_get_platforms(OT_EXAMPLE_PLATFORMS)
-set_property(CACHE OT_PLATFORM PROPERTY STRINGS ${OT_EXAMPLE_PLATFORMS})
-if(NOT OT_PLATFORM IN_LIST OT_EXAMPLE_PLATFORMS)
-    if(NOT OT_PLATFORM STREQUAL "posix-host")
-        message(FATAL_ERROR "Platform unknown: ${OT_PLATFORM}")
+set(OT_PLATFORM "NO" CACHE STRING "Target platform chosen by the user at configure time")
+ot_get_platforms(OT_PLATFORMS)
+set_property(CACHE OT_PLATFORM PROPERTY STRINGS ${OT_PLATFORMS})
+if(NOT OT_PLATFORM IN_LIST OT_PLATFORMS)
+    message(FATAL_ERROR "Platform unknown: ${OT_PLATFORM}")
+endif()
+
+set(OT_LOG_OUTPUT_VALUES
+    "APP"
+    "DEBUG_UART"
+    "NONE"
+    "PLATFORM_DEFINED"
+)
+if(OT_REFERENCE_DEVICE AND NOT OT_PLATFORM STREQUAL "posix")
+    set(OT_LOG_OUTPUT "APP" CACHE STRING "Set log output to application for reference device")
+else()
+    set(OT_LOG_OUTPUT "" CACHE STRING "Where log output goes to")
+endif()
+set_property(CACHE OT_LOG_OUTPUT PROPERTY STRINGS ${OT_LOG_OUTPUT_VALUES})
+if(OT_LOG_OUTPUT)
+    if(NOT OT_LOG_OUTPUT IN_LIST OT_LOG_OUTPUT_VALUES)
+        message(FATAL_ERROR "Log output unknown: ${OT_LOG_OUTPUT}")
     endif()
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_OUTPUT=OPENTHREAD_CONFIG_LOG_OUTPUT_${OT_LOG_OUTPUT}")
+    message(STATUS "Log output: ${OT_LOG_OUTPUT}")
 endif()
 
 # OT_CONFIG allows users to specify the path to OpenThread project core
@@ -71,35 +135,37 @@
 list(APPEND OT_PUBLIC_INCLUDES ${PROJECT_SOURCE_DIR}/etc/cmake)
 list(APPEND OT_PUBLIC_INCLUDES ${PROJECT_SOURCE_DIR}/include)
 
-if(OT_PLATFORM STREQUAL "posix-host")
-    list(APPEND OT_PRIVATE_INCLUDES ${PROJECT_SOURCE_DIR}/src/posix/platform)
+if(OT_PLATFORM STREQUAL "posix")
+    target_include_directories(ot-config INTERFACE ${PROJECT_SOURCE_DIR}/src/posix/platform)
     add_subdirectory("${PROJECT_SOURCE_DIR}/src/posix/platform")
-elseif(NOT OT_PLATFORM MATCHES "none")
-    list(APPEND OT_PRIVATE_INCLUDES ${PROJECT_SOURCE_DIR}/examples/platforms/${OT_PLATFORM})
+elseif(OT_PLATFORM)
+    target_include_directories(ot-config INTERFACE ${PROJECT_SOURCE_DIR}/examples/platforms/${OT_PLATFORM})
     add_subdirectory("${PROJECT_SOURCE_DIR}/examples/platforms/${OT_PLATFORM}")
 endif()
 
 if(OT_CONFIG)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
     message(STATUS "Project core config: \"${OT_CONFIG}\"")
 endif()
 
-list(APPEND OT_PRIVATE_DEFINES ${OT_PLATFORM_DEFINES})
+target_compile_definitions(ot-config INTERFACE ${OT_PLATFORM_DEFINES})
 
-if(OT_BUILTIN_MBEDTLS)
-    list(APPEND OT_PRIVATE_INCLUDES ${PROJECT_SOURCE_DIR}/third_party/mbedtls)
-    list(APPEND OT_PRIVATE_INCLUDES ${PROJECT_SOURCE_DIR}/third_party/mbedtls/repo/include)
-
-    list(APPEND OT_PRIVATE_DEFINES
-        "MBEDTLS_CONFIG_FILE=\"mbedtls-config.h\""
-    )
-endif()
-
-if(OT_PLATFORM STREQUAL "posix-host")
-    add_subdirectory(src/posix)
-elseif(NOT OT_PLATFORM MATCHES "none")
+if(OT_PLATFORM STREQUAL "posix")
+    if(OT_BUILD_EXECUTABLES)
+        add_subdirectory(src/posix)
+    else()
+        add_subdirectory(src/posix EXCLUDE_FROM_ALL)
+    endif()
+elseif(OT_PLATFORM)
     add_subdirectory(examples)
 endif()
 
 add_subdirectory(src)
-add_subdirectory(third_party)
+add_subdirectory(third_party EXCLUDE_FROM_ALL)
+
+if(OT_PLATFORM STREQUAL "simulation")
+    enable_testing()
+    add_subdirectory(tests)
+endif()
+
+add_custom_target(print-ot-config ALL COMMAND echo -e "$<JOIN:$<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>,\"\\n\">")
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index c721749..a8eaeda 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -2,73 +2,45 @@
 
 ## Our Pledge
 
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, gender identity and expression, level of experience,
-nationality, personal appearance, race, religion, or sexual identity and
-orientation.
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
 
 ## Our Standards
 
-Examples of behavior that contributes to creating a positive environment
-include:
+Examples of behavior that contributes to creating a positive environment include:
 
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+- Using welcoming and inclusive language
+- Being respectful of differing viewpoints and experiences
+- Gracefully accepting constructive criticism
+- Focusing on what is best for the community
+- Showing empathy towards other community members
 
 Examples of unacceptable behavior by participants include:
 
-* The use of sexualized language or imagery and unwelcome sexual attention or
-advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
-  address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
-  professional setting
+- The use of sexualized language or imagery and unwelcome sexual attention or advances
+- Trolling, insulting/derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or electronic address, without explicit permission
+- Other conduct which could reasonably be considered inappropriate in a professional setting
 
 ## Our Responsibilities
 
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
 
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
 
 ## Scope
 
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
 
 ## Enforcement
 
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at openthread-conduct@google.com. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at openthread-conduct@google.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
 
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
 
 ## Attribution
 
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at [http://contributor-covenant.org/version/1/4][version]
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
 
 [homepage]: http://contributor-covenant.org
 [version]: http://contributor-covenant.org/version/1/4/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 30cf327..5b3d39e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,21 +2,21 @@
 
 We would love for you to contribute to OpenThread and help make it even better than it is today! As a contributor, here are the guidelines we would like you to follow.
 
-* [1 Code of Conduct](#code-of-conduct)
-* [2 Bugs](#bugs)
-* [3 New Features](#new-features)
-* [4 Contributing Code](#contributing-code)
-  * [4.1 Initial Setup](#initial-setup)
-  * [4.2 Contributor License Agreement (CLA)](#contributor-license-agreement--cla-)
-  * [4.3 Submitting a Pull Request](#submitting-a-pull-request)
+- [1 Code of Conduct](#code-of-conduct)
+- [2 Bugs](#bugs)
+- [3 New Features](#new-features)
+- [4 Contributing Code](#contributing-code)
+  - [4.1 Initial Setup](#initial-setup)
+  - [4.2 Contributor License Agreement (CLA)](#contributor-license-agreement--cla-)
+  - [4.3 Submitting a Pull Request](#submitting-a-pull-request)
 
 ## Code of Conduct
 
-Help us keep OpenThread open and inclusive.  Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
+Help us keep OpenThread open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
 
 ## Bugs
 
-If you find a bug in the source code, you can help us by [submitting a GitHub Issue](https://github.com/openthread/openthread/issues/new).  The best bug reports provide a detailed description of the issue and step-by-step instructions for predictably reproducing the issue.  Even better, you can [submit a Pull Request](#submitting-a-pull-request) with a fix.
+If you find a bug in the source code, you can help us by [submitting a GitHub Issue](https://github.com/openthread/openthread/issues/new). The best bug reports provide a detailed description of the issue and step-by-step instructions for predictably reproducing the issue. Even better, you can [submit a Pull Request](#submitting-a-pull-request) with a fix.
 
 ## New Features
 
@@ -24,9 +24,9 @@
 
 If you would like to implement a new feature, please consider the scope of the new feature:
 
-* *Large feature*: first [submit a GitHub Issue](https://github.com/openthread/openthread/issues/new) and communicate your proposal so that the community can review and provide feedback.  Getting early feedback will help ensure your implementation work is accepted by the community.  This will also allow us to better coordinate our efforts and minimize duplicated effort.
+- _Large feature_: first [submit a GitHub Issue](https://github.com/openthread/openthread/issues/new) and communicate your proposal so that the community can review and provide feedback. Getting early feedback will help ensure your implementation work is accepted by the community. This will also allow us to better coordinate our efforts and minimize duplicated effort.
 
-* *Small feature*: can be implemented and directly [submitted as a Pull Request](#submitting-a-pull-request).
+- _Small feature_: can be implemented and directly [submitted as a Pull Request](#submitting-a-pull-request).
 
 ## Contributing Code
 
@@ -37,7 +37,6 @@
 Setup your GitHub fork and continuous-integration services:
 
 1. Fork the [OpenThread repository](https://github.com/openthread/openthread) by clicking "Fork" on the web UI.
-2. Enable [Travis CI](https://travis-ci.org/) by logging in the respective service with your GitHub account and enabling your newly created fork.  We use Travis CI for Linux-based continuous integration checks.  All contributions must pass these checks to be accepted.
 
 Setup your local development environment:
 
@@ -109,17 +108,9 @@
 
 #### Coding Conventions and Style
 
-OpenThread uses and enforces the [OpenThread Coding Conventions and Style](STYLE_GUIDE.md) on all code, except for code located in [third_party](third_party).  Use the `make pretty` and `make pretty-check` targets to automatically reformat code and check for code-style compliance, respectively.  OpenThread currently requires [clang-format v6.0.0](http://releases.llvm.org/download.html#6.0.0) for `make pretty` and `make pretty-check`.
+OpenThread uses and enforces the [OpenThread Coding Conventions and Style](STYLE_GUIDE.md) on all code, except for code located in [third_party](third_party). Use `script/make-pretty` and `script/make-pretty check` to automatically reformat code and check for code-style compliance, respectively. OpenThread currently requires [clang-format v6.0.0](http://releases.llvm.org/download.html#6.0.0) for C/C++ and [yapf v0.29.0](https://github.com/google/yapf) for Python.
 
-As part of the cleanup process, you should also run `make pretty-check` to ensure that your code passes the baseline code style checks.
-
-```bash
-./bootstrap
-./configure
-make pretty-check
-```
-
-Make sure to include any code format changes in your commits.
+As part of the cleanup process, you should also run `script/make-pretty check` to ensure that your code passes the baseline code style checks.
 
 #### Push and Test
 
@@ -131,8 +122,8 @@
 git push origin <branch-name>
 ```
 
-This will trigger the Travis CI continuous-integration checks.  You can view the results in the respective services.  Note that the integration checks will report failures on occasion.  If a failure occurs, you may try rerunning the test via the Travis web UI.
+This will trigger continuous-integration checks using GitHub Actions. You can view the status and logs via the "Actions" tab in your fork.
 
 #### Submit Pull Request
 
-Once you've validated the Travis CI results, go to the page for your fork on GitHub, select your development branch, and click the pull request button. If you need to make any adjustments to your pull request, just push the updates to GitHub. Your pull request will automatically track the changes on your development branch and update.
+Once you've validated that all continuous-integration checks have passed, go to the page for your fork on GitHub, select your development branch, and click the pull request button. If you need to make any adjustments to your pull request, just push the updates to GitHub. Your pull request will automatically track the changes on your development branch and update.
diff --git a/Makefile.am b/Makefile.am
index 2073c16..441d5c4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -37,7 +37,7 @@
     --enable-mtd                      \
     --enable-ncp                      \
     --enable-radio-only               \
-    --with-examples=posix             \
+    --with-examples=simulation        \
     $(NULL)
 
 SUBDIRS                             = \
@@ -71,14 +71,6 @@
     .local-version                    \
     $(NULL)
 
-PRETTY_SUBDIRS                      = \
-    examples                          \
-    include                           \
-    src                               \
-    tests                             \
-    tools                             \
-    $(NULL)
-
 # Ignore the pseudo flash files on Posix platform during diskcheck
 distcleancheck_listfiles            = \
     $(AM_V_at)find . -type f -name "*flash"
diff --git a/README.md b/README.md
index b4566d1..f22d57e 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,10 @@
-[![OpenThread][ot-logo]][ot-repo]
-[![Build Status][ot-travis-svg]][ot-travis]
-[![Coverage Status][ot-codecov-svg]][ot-codecov]
-[![Build Status][ot-docker-dev-svg]][ot-docker-dev]
+[![OpenThread][ot-logo]][ot-repo] [![Build][ot-gh-action-build-svg]][ot-gh-action-build] [![Simulation][ot-gh-action-simulation-svg]][ot-gh-action-simulation] [![Language grade: C/C++][ot-lgtm-svg]][ot-lgtm] [![Coverage Status][ot-codecov-svg]][ot-codecov] [![Build Status][ot-docker-dev-svg]][ot-docker-dev]
 
 ---
 
 # What is OpenThread?
 
-OpenThread released by Google is...
-<a href="http://threadgroup.org/technology/ourtechnology#certifiedproducts">
-<img src="https://cdn.rawgit.com/openthread/openthread/ab4c4e1e/doc/images/certified.svg" alt="Thread Certified Component" width="150px" align="right">
-</a>
+OpenThread released by Google is... <a href="http://threadgroup.org/technology/ourtechnology#certifiedproducts"> <img src="https://cdn.rawgit.com/openthread/openthread/ab4c4e1e/doc/images/certified.svg" alt="Thread Certified Component" width="150px" align="right"> </a>
 
 **...an open-source implementation of the [Thread](http://threadgroup.org/technology/ourtechnology) networking protocol.** Google Nest has released OpenThread to make the technology used in Nest products more broadly available to developers to accelerate the development of products for the connected home.
 
@@ -23,8 +17,12 @@
 [thread]: http://threadgroup.org/technology/ourtechnology
 [ot-repo]: https://github.com/openthread/openthread
 [ot-logo]: doc/images/openthread_logo.png
-[ot-travis]: https://travis-ci.org/openthread/openthread
-[ot-travis-svg]: https://travis-ci.org/openthread/openthread.svg?branch=master
+[ot-gh-action-build]: https://github.com/openthread/openthread/actions?query=workflow%3ABuild+branch%3Amaster+event%3Apush
+[ot-gh-action-build-svg]: https://github.com/openthread/openthread/workflows/Build/badge.svg?branch=master&event=push
+[ot-gh-action-simulation]: https://github.com/openthread/openthread/actions?query=workflow%3ASimulation+branch%3Amaster+event%3Apush
+[ot-gh-action-simulation-svg]: https://github.com/openthread/openthread/workflows/Simulation/badge.svg?branch=master&event=push
+[ot-lgtm]: https://lgtm.com/projects/g/openthread/openthread/context:cpp
+[ot-lgtm-svg]: https://img.shields.io/lgtm/grade/cpp/g/openthread/openthread.svg?logo=lgtm&logoWidth=18
 [ot-codecov]: https://codecov.io/gh/openthread/openthread
 [ot-codecov-svg]: https://codecov.io/gh/openthread/openthread/branch/master/graph/badge.svg
 [ot-docker-dev]: https://hub.docker.com/r/openthread/environment
@@ -32,18 +30,18 @@
 
 # Who supports OpenThread?
 
-<a href="https://www.arm.com/"><img src="doc/images/ot-contrib-arm.png" alt="ARM" width="200px"></a><a href="https://www.cascoda.com/"><img src="doc/images/ot-contrib-cascoda.png" alt="Cascoda" width="200px"></a><a href="https://www.google.com/"><img src="doc/images/ot-contrib-google.png" alt="Google" width="200px"></a><a href="http://www.nordicsemi.com/"><img src="doc/images/ot-contrib-nordic.png" alt="Nordic" width="200px"></a><a href="http://www.nxp.com/"><img src="doc/images/ot-contrib-nxp.png" alt="NXP" width="200px"></a><a href="https://www.particle.io/"><img src="doc/images/ot-contrib-particle.png" alt="Particle" width="200px"></a><a href="http://www.qorvo.com/"><img src="doc/images/ot-contrib-qorvo.png" alt="Qorvo" width="200px"></a><a href="https://www.qualcomm.com/"><img src="doc/images/ot-contrib-qc.png" alt="Qualcomm" width="200px"></a><a href="https://www.samsung.com/"><img src="doc/images/ot-contrib-samsung.png" alt="Samsung" width="200px"></a><a href="https://www.silabs.com/"><img src="doc/images/ot-contrib-silabs.png" alt="Silicon Labs" width="200px"></a><a href="https://www.st.com/"><img src="doc/images/ot-contrib-stm.png" alt="STMicroelectronics" width="200px"></a><a href="https://www.synopsys.com/"><img src="doc/images/ot-contrib-synopsys.png" alt="Synopsys" width="200px"></a><a href="https://www.ti.com/"><img src="doc/images/ot-contrib-ti.png" alt="Texas Instruments" width="200px"></a><a href="https://www.zephyrproject.org/"><img src="doc/images/ot-contrib-zephyr.png" alt="Zephyr Project" width="200px"></a>
+<a href="https://www.arm.com/"><img src="doc/images/ot-contrib-arm.png" alt="ARM" width="200px"></a><a href="https://www.cascoda.com/"><img src="doc/images/ot-contrib-cascoda.png" alt="Cascoda" width="200px"></a><a href="https://www.google.com/"><img src="doc/images/ot-contrib-google.png" alt="Google" width="200px"></a><a href="http://www.nordicsemi.com/"><img src="doc/images/ot-contrib-nordic.png" alt="Nordic" width="200px"></a><a href="http://www.nxp.com/"><img src="doc/images/ot-contrib-nxp.png" alt="NXP" width="200px"></a><a href="http://www.qorvo.com/"><img src="doc/images/ot-contrib-qorvo.png" alt="Qorvo" width="200px"></a><a href="https://www.qualcomm.com/"><img src="doc/images/ot-contrib-qc.png" alt="Qualcomm" width="200px"></a><a href="https://www.samsung.com/"><img src="doc/images/ot-contrib-samsung.png" alt="Samsung" width="200px"></a><a href="https://www.silabs.com/"><img src="doc/images/ot-contrib-silabs.png" alt="Silicon Labs" width="200px"></a><a href="https://www.st.com/"><img src="doc/images/ot-contrib-stm.png" alt="STMicroelectronics" width="200px"></a><a href="https://www.synopsys.com/"><img src="doc/images/ot-contrib-synopsys.png" alt="Synopsys" width="200px"></a><a href="https://www.ti.com/"><img src="doc/images/ot-contrib-ti.png" alt="Texas Instruments" width="200px"></a><a href="https://www.zephyrproject.org/"><img src="doc/images/ot-contrib-zephyr.png" alt="Zephyr Project" width="200px"></a>
 
 # Getting started
 
 All end-user documentation and guides are located at [openthread.io](https://openthread.io). If you're looking to do things like...
 
-* Learn more about OpenThread features and enhancements
-* Use OpenThread in your products
-* Learn how to build and configure a Thread network
-* Port OpenThread to a new platform
-* Build an application on top of OpenThread
-* Certify a product using OpenThread
+- Learn more about OpenThread features and enhancements
+- Use OpenThread in your products
+- Learn how to build and configure a Thread network
+- Port OpenThread to a new platform
+- Build an application on top of OpenThread
+- Certify a product using OpenThread
 
 ...then [openthread.io](https://openthread.io) is the place for you.
 
@@ -71,8 +69,8 @@
 
 There are numerous avenues for OpenThread support:
 
-* Bugs and feature requests — [submit to the Issue Tracker](https://github.com/openthread/openthread/issues)
-* Stack Overflow — [post questions using the `openthread` tag](http://stackoverflow.com/questions/tagged/openthread)
-* Google Groups — [discussion and announcements at openthread-users](https://groups.google.com/forum/#!forum/openthread-users)
+- Bugs and feature requests — [submit to the Issue Tracker](https://github.com/openthread/openthread/issues)
+- Stack Overflow — [post questions using the `openthread` tag](http://stackoverflow.com/questions/tagged/openthread)
+- Google Groups — [discussion and announcements at openthread-users](https://groups.google.com/forum/#!forum/openthread-users)
 
 The openthread-users Google Group is the recommended place for users to discuss OpenThread and interact directly with the OpenThread team.
diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md
index c988752..ae507cc 100644
--- a/STYLE_GUIDE.md
+++ b/STYLE_GUIDE.md
@@ -1,15 +1,15 @@
 # OpenThread Coding Conventions and Style
 
-* [1 C and C++](#c-and-c)
-  * [1.1 Standards](#standards)
-  * [1.2 Conventions and Best Practices](#conventions-and-best-practices)
-  * [1.3 Tightly-constrained Systems and Shared Infrastructure](#tightly-constrained-systems-and-shared-infrastructure)
-  * [1.4 Format and Style](#format-and-style)
-  * [1.5 Comments](#comments)
-* [2 Python](#python)
-  * [2.1 Standards](#standards)
-  * [2.2 Conventions and Best Practices](#conventions-and-best-practices)
-  * [2.3 Format and Style](#format-and-style)
+- [1 C and C++](#c-and-c)
+  - [1.1 Standards](#standards)
+  - [1.2 Conventions and Best Practices](#conventions-and-best-practices)
+  - [1.3 Tightly-constrained Systems and Shared Infrastructure](#tightly-constrained-systems-and-shared-infrastructure)
+  - [1.4 Format and Style](#format-and-style)
+  - [1.5 Comments](#comments)
+- [2 Python](#python)
+  - [2.1 Standards](#standards)
+  - [2.2 Conventions and Best Practices](#conventions-and-best-practices)
+  - [2.3 Format and Style](#format-and-style)
 
 # C and C++
 
@@ -18,7 +18,7 @@
 - C
   - OpenThread uses and enforces the ISO9899:1999 (aka ISO C99, C99) C language standard as the minimum.
 - C++
-  - OpenThread uses and enforces the ISO14882:2003 (aka ISO C++03, C++03) C++ language standard as the minimum.
+  - OpenThread uses and enforces the ISO14882:2011 (aka ISO C++11, C++11) C++ language standard as the minimum.
 - Extensions
   - Wherever possible, toolchain-specific (e.g GCC/GNU) extensions or the use of later standards shall be avoided or shall be leveraged through toolchain-compatibility preprocessor macros.
 
@@ -27,13 +27,13 @@
 ### Language Independent
 
 - Inline functions should be used judiciously.
-  - The use of code in headers and, more specifically, the use of the non-local scope inline functions should be avoided.  Exception: Simple setters and getters are fine since the compiler can efficiently optimize these and make their overhead as low as a direct data member access.
+  - The use of code in headers and, more specifically, the use of the non-local scope inline functions should be avoided. Exception: Simple setters and getters are fine since the compiler can efficiently optimize these and make their overhead as low as a direct data member access.
 - Return Statements
   - There should be one return statement per free function or method at the end of the free function or method.
 - Non-local Goto
   - There should be no calls to the functions `setjmp` or `longjmp`.
 - Local Goto
-  - There should be no calls to the C/C++ keyword goto.  Exception: The use of local gotos for the purposes of common error handling blocks and single points of function return at the bottom of a function.
+  - There should be no calls to the C/C++ keyword goto. Exception: The use of local gotos for the purposes of common error handling blocks and single points of function return at the bottom of a function.
 - C Preprocessor
   - Use of the C preprocessor should be limited to file inclusion and simple macros.
   - Macros shall not be defined within a function or a block and should be defined at the top of a file.
@@ -63,16 +63,16 @@
 - Unbounded Recursion
   - There shall be no direct or indirect use of unbounded recursive function calls.
 - Symmetric APIs
-  - Wherever possible and appropriate, particularly around the management of resources, APIs should be symmetric.  For example, if there is a free function or object method that allocates a resource, then there should be one that deallocates it. If there is a free function or object method that opens a file or network stream, then there should be one that closes it.
+  - Wherever possible and appropriate, particularly around the management of resources, APIs should be symmetric. For example, if there is a free function or object method that allocates a resource, then there should be one that deallocates it. If there is a free function or object method that opens a file or network stream, then there should be one that closes it.
 - Use C stdint.h or C++ cstdint for Plain Old Data Types
-  - Standard, scalar data types defined in stdint.h (C) or cstdint (C++) should be used for basic signed and unsigned integer types, especially when size and serialization to non-volatile storage or across a network is concerned.  Examples of these are: `uint8_t`, `int8_t`, etc.
+  - Standard, scalar data types defined in stdint.h (C) or cstdint (C++) should be used for basic signed and unsigned integer types, especially when size and serialization to non-volatile storage or across a network is concerned. Examples of these are: `uint8_t`, `int8_t`, etc.
 - Constant Qualifiers
   - Read-only methods, global variables, stack variables, or data members are read-only should be qualified using the C or C++ `const` qualifier.
   - Pointers or references to read-only objects or storage, including but not limited to function parameters, should be qualified using the C or C++ `const` qualifier.
 - Header Include Guard
   - All C and C++ headers shall use preprocessor header include guards.
   - The terminating endif preprocessor directive shall have a comment, C or C++ depending on the header type, containing the preprocessor symbol introduced by the ifndef directive starting the guard.
-  - The symbol used for the guard should be the file name, converted to all uppercase, with any spaces (“ “) or dots (“.”) converted to underscores (“_”).
+  - The symbol used for the guard should be the file name, converted to all uppercase, with any spaces (“ “) or dots (“.”) converted to underscores (“\_”).
 - Function and Method Prototypes
   - All void functions or methods shall explicitly declare and specify the void type keyword.
 - Unused parameters
@@ -86,16 +86,16 @@
 ### C++
 
 - Prefer Passing Parameters by Reference to Pointer
-  - Unlike C, C++ offers an alternate way to alias data over and above a pointer, the reference, indicated by the & symbol.  Where appropriate, the reference should be preferred to the pointer.
+  - Unlike C, C++ offers an alternate way to alias data over and above a pointer, the reference, indicated by the & symbol. Where appropriate, the reference should be preferred to the pointer.
 - Passing Base Scalars
   - Size- and call frequency-based considerations should be made when passing scalars as to whether they should be passed by value or by constant reference; however, pass-by-value should generally be preferred.
 - Eliminate Unnecessary Destructors
-  - The creation of empty or useless destructors should be avoided.  Empty or useless destructors should be removed.
+  - The creation of empty or useless destructors should be avoided. Empty or useless destructors should be removed.
 - Default Parameters
   - When you declare C++ free functions and object methods, you should avoid or minimize using default parameters.
   - When you declare C++ virtual object methods, you shall avoid using default parameters.
 - Global and Scoped Static Construction
-  - There shall be no use of global, static or otherwise, object construction.  The use of scoped static object construction should be avoided.
+  - There shall be no use of global, static or otherwise, object construction. The use of scoped static object construction should be avoided.
 - C++-style Casts
   - Wherever possible and practical, C++ style casts should be used and preferred to the C style cast equivalent.
 - Avoid `using namespace` Statements in Headers
@@ -114,23 +114,25 @@
 
 ## Format and Style
 
-- OpenThread uses the `make pretty` build target to reformat code and enforce code format and style.  The `make pretty-check` build target is included in OpenThread's continuous integration and must pass before a pull request is merged.
+- OpenThread uses `script/make-pretty` to reformat code and enforce code format and style. `script/make-pretty check` build target is included in OpenThread's continuous integration and must pass before a pull request is merged.
 
-- The `make pretty` and `make pretty-check` build targets require [clang-format v6.0.0](http://releases.llvm.org/download.html#6.0.0).
+- `script/make-pretty` requires [clang-format v6.0.0](http://releases.llvm.org/download.html#6.0.0) for C/C++ and [yapf v0.29.0](https://github.com/google/yapf) for Python.
 
 ### File Names
-- File names should match the names and types of what is described in the file.  If a file contains many declarations and definitions, the author should choose the one that predominantly describes or that makes the most sense.
+
+- File names should match the names and types of what is described in the file. If a file contains many declarations and definitions, the author should choose the one that predominantly describes or that makes the most sense.
 - File contents and names should be limited in the scope of what they contain. It may also be possible that there is too much stuff in one file and you need to break it up into multiple files.
 - File names should be all lower case.
 - File extensions shall be indicative and appropriate for the type and usage of the source or header file.
 
 ### Naming
-- Names should be descriptive but not overly so and they should give some idea of scope and should be selected such that *wrong code looks wrong*.
+
+- Names should be descriptive but not overly so and they should give some idea of scope and should be selected such that _wrong code looks wrong_.
 - Names shall not give any idea of type, such as is done with System Hungarian notation.
 - Case
   - C preprocessor symbols should be all uppercase.
-  - All OpenThread class, namespace, structure, method, function, enumeration, and type names in the C/C++ language shall be in *upper camel case*.  Exception: the top level OpenThread namespace 'ot'.
-  - All OpenThread instantiated names of instances of classes, namespaces, structures, methods, functions, enumerations, and types as well as method and function parameters in the C++ language shall be in *lower camel case*.
+  - All OpenThread class, namespace, structure, method, function, enumeration, and type names in the C/C++ language shall be in _upper camel case_. Exception: the top level OpenThread namespace 'ot'.
+  - All OpenThread instantiated names of instances of classes, namespaces, structures, methods, functions, enumerations, and types as well as method and function parameters in the C++ language shall be in _lower camel case_.
 - Symbol Qualification
   - All OpenThread C public data types and free functions should have `ot` prepended to their name.
   - All OpenThread C++ code should be in the ‘ot’ top-level namespace.
@@ -142,6 +144,7 @@
   - All variables that do not have such prefixes shall be assumed to be function local scope.
 
 ### White Space
+
 - Indentation shall be 4 space characters.
 - Conditionals shall always appear on a separate line from the code to execute as a result of the condition.
 - Scoped Variable declarations
@@ -181,8 +184,8 @@
 
 ## Conventions and Best Practices
 
-- Run `pylint` over your code.  `pylint` is a tool for finding bugs and style problems in Python source code. It finds problems that are typically caught by a compiler for less dynamic languages like C and C++. Because of the dynamic nature of Python, some warnings may be incorrect; however, spurious warnings should be fairly infrequent.
+- Run `pylint` over your code. `pylint` is a tool for finding bugs and style problems in Python source code. It finds problems that are typically caught by a compiler for less dynamic languages like C and C++. Because of the dynamic nature of Python, some warnings may be incorrect; however, spurious warnings should be fairly infrequent.
 
 ## Format and Style
 
-- All code should adhere to [PEP 8](https://www.python.org/dev/peps/pep-0008/).
+- All code should adhere to [Google Python Style Guide](http://google.github.io/styleguide/pyguide.html).
diff --git a/bootstrap b/bootstrap
index b6f8ee0..881f2c5 100755
--- a/bootstrap
+++ b/bootstrap
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 #  Copyright (c) 2016, The OpenThread Authors.
 #  All rights reserved.
@@ -36,10 +36,10 @@
 
 nlbuild_autotools_stem="third_party/nlbuild-autotools/repo"
 
-# Establish some key directories
+abs_srcdir=$(cd "$(dirname "${0}")" && pwd)
 
-srcdir=`dirname ${0}`
-abs_srcdir=`pwd`
-abs_top_srcdir="${abs_srcdir}"
-
-exec ${srcdir}/${nlbuild_autotools_stem}/scripts/bootstrap -I "${abs_top_srcdir}/${nlbuild_autotools_stem}" $*
+# filter out knowning information from stderr which is causing GitHub annotation check warnings.
+(cd "$abs_srcdir" && exec "$abs_srcdir/$nlbuild_autotools_stem/scripts/bootstrap" -I "$abs_srcdir/$nlbuild_autotools_stem" "${@}") 2> \
+    >(grep -v "installing 'third_party/nlbuild-autotools/repo/third_party/autoconf/missing'" \
+        | grep -v "installing 'third_party/nlbuild-autotools/repo/third_party/autoconf/compile'" \
+        | grep -v "installing 'third_party/nlbuild-autotools/repo/third_party/autoconf/depcomp'" 1>&2)
diff --git a/configure.ac b/configure.ac
index d9f51b8..31829bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -137,24 +137,17 @@
 
     *darwin*)
         OPENTHREAD_TARGET=darwin
-        OPENTHREAD_TARGET_DEFINES="-DOPENTHREAD_TARGET_DARWIN"
         ;;
 
     *linux*)
         OPENTHREAD_TARGET=linux
-        OPENTHREAD_TARGET_DEFINES="-DOPENTHREAD_TARGET_LINUX"
         ;;
 
 esac
 
-AC_SUBST(OPENTHREAD_TARGET_DARWIN)
 AM_CONDITIONAL([OPENTHREAD_TARGET_DARWIN], [test "${OPENTHREAD_TARGET}" = "darwin"])
-
-AC_SUBST(OPENTHREAD_TARGET_LINUX)
 AM_CONDITIONAL([OPENTHREAD_TARGET_LINUX], [test "${OPENTHREAD_TARGET}" = "linux"])
 
-AC_SUBST(OPENTHREAD_TARGET_DEFINES)
-
 #
 # Checks for build host programs
 #
@@ -202,6 +195,8 @@
 
 AM_PROG_AS
 
+AC_C_BIGENDIAN
+
 # Check for other compiler toolchain tools.
 
 AC_CHECK_TOOL(AR, ar)
@@ -231,8 +226,8 @@
 #   -Wall                        CC, CXX
 #
 
-PROSPECTIVE_CFLAGS="-Wall -Wextra -Wshadow -Wundef -Werror -Wno-error=undef -std=c99 -pedantic-errors"
-PROSPECTIVE_CXXFLAGS="-Wall -Wextra -Wshadow -Wundef -Werror -Wno-error=undef -std=gnu++98 -Wno-c++14-compat -fno-exceptions"
+PROSPECTIVE_CFLAGS="-Wall -Wextra -Wshadow -Wundef -Wcast-align -Werror -Wno-error=undef -std=c99 -pedantic-errors"
+PROSPECTIVE_CXXFLAGS="-Wall -Wextra -Wshadow -Wundef -Wcast-align -Werror -Wno-error=undef -std=c++11 -Wno-c++14-compat -fno-exceptions -pedantic-errors"
 
 AC_CACHE_CHECK([whether $CC is Clang],
     [nl_cv_clang],
@@ -401,21 +396,10 @@
 fi
 
 #
-# Code style
-#
-
-AC_SUBST(PRETTY, ["\${abs_top_srcdir}/script/clang-format.sh"])
-AC_SUBST(PRETTY_ARGS, ["-style=file -i"])
-AC_SUBST(PRETTY_CHECK, ["\${abs_top_srcdir}/script/clang-format-check.sh"])
-AC_SUBST(PRETTY_CHECK_ARGS, [""])
-
-#
 # Tests
 #
 AC_MSG_NOTICE([checking whether to build tests])
 
-# Tests
-
 NL_ENABLE_TESTS([yes])
 
 AM_CONDITIONAL([OPENTHREAD_BUILD_TESTS], [test "${nl_cv_build_tests}" = "yes"])
@@ -457,64 +441,34 @@
 AM_CONDITIONAL([OPENTHREAD_ENABLE_BUILTIN_MBEDTLS], [test "${enable_builtin_mbedtls}" = "yes"])
 
 #
-# POSIX Application
-#
-
-AC_MSG_CHECKING([whether to build POSIX applicaton])
-AC_ARG_ENABLE(posix-app,
-    [AS_HELP_STRING([--enable-posix-app], [Build POSIX application @<:@default=no@:>@.])],
-    [
-        case "${enableval}" in
-
-        no|yes)
-            enable_posix_app=${enableval}
-            ;;
-
-        *)
-            AC_MSG_ERROR([Invalid value ${enable_posix_app} for --enable-posix-app])
-            ;;
-        esac
-    ],
-    [enable_posix_app=no])
-
-if test "$enable_posix_app" = "yes"; then
-    CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_PLATFORM_POSIX_APP=1"
-else
-    CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_PLATFORM_POSIX_APP=0"
-fi
-
-AC_MSG_RESULT(${enable_posix_app})
-AM_CONDITIONAL([OPENTHREAD_PLATFORM_POSIX_APP], [test "${enable_posix_app}" = "yes"])
-
-#
 # POSIX Daemon
 #
 
 AC_MSG_CHECKING([whether to build POSIX applicaton in daemon mode])
-AC_ARG_ENABLE(posix-app-daemon,
-    [AS_HELP_STRING([--enable-posix-app-daemon], [Build POSIX application in daemon mode@<:@default=no@:>@.])],
+AC_ARG_ENABLE(posix-daemon,
+    [AS_HELP_STRING([--enable-posix-daemon], [Build POSIX application in daemon mode@<:@default=no@:>@.])],
     [
         case "${enableval}" in
 
         no|yes)
-            enable_posix_app_daemon=${enableval}
+            enable_posix_daemon=${enableval}
             ;;
 
         *)
-            AC_MSG_ERROR([Invalid value ${enable_posix_app} for --enable-posix-app-daemon])
+            AC_MSG_ERROR([Invalid value ${enable_posix} for --enable-posix-daemon])
             ;;
         esac
     ],
-    [enable_posix_app_daemon=no])
+    [enable_posix_daemon=no])
 
-if test "$enable_posix_app_daemon" = "yes"; then
-    CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_ENABLE_POSIX_APP_DAEMON=1"
+if test "$enable_posix_daemon" = "yes"; then
+    CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE=1"
 else
-    CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_ENABLE_POSIX_APP_DAEMON=0"
+    CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE=0"
 fi
 
-AC_MSG_RESULT(${enable_posix_app_daemon})
-AM_CONDITIONAL([OPENTHREAD_ENABLE_POSIX_APP_DAEMON], [test "${enable_posix_app_daemon}" = "yes"])
+AC_MSG_RESULT(${enable_posix_daemon})
+AM_CONDITIONAL([OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE], [test "${enable_posix_daemon}" = "yes"])
 
 #
 # FTD Library
@@ -822,20 +776,23 @@
 # Examples
 #
 
+AC_MSG_CHECKING([whether to build examples])
+
 AC_ARG_WITH(examples,
     [AS_HELP_STRING([--with-examples=TARGET],
-        [Specify the examples from one of: no, posix, cc1352, cc2538, cc2650, cc2652, efr32mg12, efr32mg13, efr32mg21, gp712, kw41z, nrf52811, nrf52833, nrf52840, qpg6095, samr21 @<:@default=no@:>@.])],
+        [Build example applications for one of: simulation, cc1352, cc2538, cc2650, cc2652, efr32mg1, efr32mg12, efr32mg13, efr32mg21,
+         gp712, jn5189, k32w061, kw41z, nrf52811, nrf52833, nrf52840, qpg6095, samr21 @<:@default=no@:>@.
+         Note that building example applications also builds the associated OpenThread platform libraries
+         and any third_party libraries needed to support the examples.])],
     [
         case "${with_examples}" in
         no)
             ;;
-        posix|cc1352|cc2538|cc2650|cc2652|efr32mg12|efr32mg13|efr32mg21|gp712|kw41z|nrf52811|nrf52833|nrf52840|qpg6095|samr21)
-            if test ${enable_posix_app} = "yes"; then
-                AC_MSG_ERROR([--with-examples must be no when POSIX apps are enabled by --enable-posix-app])
-            fi
+        simulation|cc1352|cc2538|cc2650|cc2652|efr32mg1|efr32mg12|efr32mg13|efr32mg21|gp712|jn5189|k32w061|kw41z|nrf52811|nrf52833|nrf52840|qpg6095|samr21)
             ;;
         *)
-            AC_MSG_ERROR([Invalid value ${with_examples} for --with-examples])
+            AC_MSG_RESULT(ERROR)
+            AC_MSG_ERROR([Invalid value given for --with-examples: ${with_examples}])
             ;;
         esac
     ],
@@ -843,15 +800,18 @@
 
 AM_CONDITIONAL([OPENTHREAD_ENABLE_EXAMPLES], [test ${with_examples} != "no"])
 
-AM_CONDITIONAL([OPENTHREAD_EXAMPLES_POSIX],     [test "${with_examples}" = "posix"])
+AM_CONDITIONAL([OPENTHREAD_EXAMPLES_SIMULATION],[test "${with_examples}" = "simulation"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_CC1352],    [test "${with_examples}" = "cc1352"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_CC2538],    [test "${with_examples}" = "cc2538"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_CC2650],    [test "${with_examples}" = "cc2650"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_CC2652],    [test "${with_examples}" = "cc2652"])
+AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32MG1],  [test "${with_examples}" = "efr32mg1"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32MG12], [test "${with_examples}" = "efr32mg12"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32MG13], [test "${with_examples}" = "efr32mg13"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32MG21], [test "${with_examples}" = "efr32mg21"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_GP712],     [test "${with_examples}" = "gp712"])
+AM_CONDITIONAL([OPENTHREAD_EXAMPLES_JN5189],    [test "${with_examples}" = "jn5189"])
+AM_CONDITIONAL([OPENTHREAD_EXAMPLES_K32W061],   [test "${with_examples}" = "k32w061"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_KW41Z],     [test "${with_examples}" = "kw41z"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_NRF52811],  [test "${with_examples}" = "nrf52811"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_NRF52833],  [test "${with_examples}" = "nrf52833"])
@@ -859,12 +819,96 @@
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_QPG6095],   [test "${with_examples}" = "qpg6095"])
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_SAMR21],    [test "${with_examples}" = "samr21"])
 
-AM_COND_IF([OPENTHREAD_EXAMPLES_POSIX], CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_EXAMPLES_POSIX=1", CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_EXAMPLES_POSIX=0")
-
-AC_MSG_CHECKING([whether to enable examples])
-AC_MSG_RESULT(${with_examples})
+AM_COND_IF([OPENTHREAD_EXAMPLES_SIMULATION], CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_EXAMPLES_SIMULATION=1", CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_EXAMPLES_SIMULATION=0")
 
 AM_CONDITIONAL([OPENTHREAD_EXAMPLES_NRF528XX], [test OPENTHREAD_EXAMPLES_NRF52811 || test OPENTHREAD_EXAMPLES_NRF52833 || test OPENTHREAD_EXAMPLES_NRF52840])
+
+case ${with_examples} in
+    no)
+        AC_MSG_RESULT([no])
+        ;;
+    *)
+        AC_MSG_RESULT([yes (${with_examples})])
+        ;;
+esac
+
+#
+# Platform
+#
+
+AC_MSG_CHECKING([whether to build platform libraries])
+
+AC_ARG_WITH(platform,
+    [AS_HELP_STRING([--with-platform=TARGET],
+        [Build OpenThread platform libraries for one of: cc1352, cc2538, cc2650, cc2652,
+         efr32mg1, efr32mg12, efr32mg13, efr32mg21, gp712, jn5189, kw41z, nrf52811, nrf52833, nrf52840, posix, qpg6095, samr21, simulation @<:@default=simulation@:>@.])],
+    [
+        # Make sure the given target is valid.
+        case "${with_platform}" in
+        no|cc1352|cc2538|cc2650|cc2652|efr32mg1|efr32mg12|efr32mg13|efr32mg21|gp712|jn5189|kw41z|nrf52811|nrf52833|nrf52840|posix|qpg6095|samr21|simulation)
+            ;;
+        *)
+            AC_MSG_RESULT(ERROR)
+            AC_MSG_ERROR([Invalid value given for --with-platform: ${with_platform}])
+            ;;
+        esac
+
+        # If both --with-platform and --with-examples are specified, make sure the targets match.
+        case "${with_examples}" in
+        no)
+            ;;
+        ${with_platform})
+            ;;
+        *)
+            AC_MSG_RESULT(ERROR)
+            AC_MSG_ERROR([Invalid value given for --with-platform: The targets for --with-examples and --with-platform must match.])
+            ;;
+        esac
+
+    ],
+    [
+        # If --with-platform is NOT specified, but --with-examples is, automatically build the
+        # corresponding platform libraries. (Essentially, --with-examples implies --with-platform).
+        with_platform=${with_examples}
+    ])
+
+AM_CONDITIONAL([OPENTHREAD_ENABLE_PLATFORM], [test ${with_platform} != "no"])
+
+OPENTHREAD_ENABLE_PLATFORM=${with_platform}
+
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_CC1352],    [test "${with_platform}" = "cc1352"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_CC2538],    [test "${with_platform}" = "cc2538"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_CC2650],    [test "${with_platform}" = "cc2650"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_CC2652],    [test "${with_platform}" = "cc2652"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_EFR32MG1],  [test "${with_platform}" = "efr32mg1"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_EFR32MG12], [test "${with_platform}" = "efr32mg12"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_EFR32MG13], [test "${with_platform}" = "efr32mg13"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_EFR32MG21], [test "${with_platform}" = "efr32mg21"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_GP712],     [test "${with_platform}" = "gp712"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_JN5189],    [test "${with_platform}" = "jn5189"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_KW41Z],     [test "${with_platform}" = "kw41z"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_NRF52811],  [test "${with_platform}" = "nrf52811"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_NRF52833],  [test "${with_platform}" = "nrf52833"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_NRF52840],  [test "${with_platform}" = "nrf52840"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_POSIX],     [test "${with_platform}" = "posix"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_QPG6095],   [test "${with_platform}" = "qpg6095"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_SAMR21],    [test "${with_platform}" = "samr21"])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_SIMULATION],[test "${with_platform}" = "simulation"])
+
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_NRF528XX], [test OPENTHREAD_PLATFORM_NRF52811 || test OPENTHREAD_PLATFORM_NRF52833 || test OPENTHREAD_PLATFORM_NRF52840])
+AM_CONDITIONAL([OPENTHREAD_PLATFORM_K32W], [test OPENTHREAD_PLATFORM_K32W061 || test OPENTHREAD_PLATFORM_JN5189])
+
+AM_COND_IF([OPENTHREAD_PLATFORM_POSIX], CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_PLATFORM_POSIX=1", CPPFLAGS="${CPPFLAGS} -DOPENTHREAD_PLATFORM_POSIX=0")
+
+case ${with_platform} in
+    no)
+        AC_MSG_RESULT([no])
+        ;;
+    *)
+        AC_MSG_RESULT([yes (${with_platform})])
+        ;;
+esac
+
 #
 # Tools
 #
@@ -901,7 +945,7 @@
 
 AM_CONDITIONAL(OPENTHREAD_BUILD_DOCS, [test "${nl_cv_build_docs}" = "yes"])
 
-AM_CONDITIONAL(OPENTHREAD_POSIX, [test "${enable_posix_app}" = "yes" -o "${with_examples}" = "posix"])
+AM_CONDITIONAL(OPENTHREAD_POSIX, [test "${with_platform}" = "posix" -o "${with_examples}" = "simulation"])
 
 #
 # Checks for libraries and packages.
@@ -978,6 +1022,11 @@
 src/core/Makefile
 src/posix/Makefile
 src/posix/platform/Makefile
+src/lib/Makefile
+src/lib/hdlc/Makefile
+src/lib/platform/Makefile
+src/lib/spinel/Makefile
+src/lib/url/Makefile
 third_party/Makefile
 third_party/jlink/Makefile
 third_party/mbedtls/Makefile
@@ -992,6 +1041,7 @@
 examples/platforms/cc2538/Makefile
 examples/platforms/cc2650/Makefile
 examples/platforms/cc2652/Makefile
+examples/platforms/efr32mg1/Makefile
 examples/platforms/efr32mg12/Makefile
 examples/platforms/efr32mg12/sleepy-demo/Makefile
 examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/Makefile
@@ -1005,11 +1055,12 @@
 examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-ftd/Makefile
 examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-mtd/Makefile
 examples/platforms/gp712/Makefile
+examples/platforms/k32w/Makefile
 examples/platforms/kw41z/Makefile
 examples/platforms/nrf528xx/Makefile
 examples/platforms/qpg6095/Makefile
 examples/platforms/samr21/Makefile
-examples/platforms/posix/Makefile
+examples/platforms/simulation/Makefile
 examples/platforms/utils/Makefile
 tools/Makefile
 tools/harness-automation/Makefile
@@ -1077,10 +1128,6 @@
   Link flags                                : ${LDFLAGS:--}
   Link libraries                            : ${LIBS}
   Link maps                                 : ${enable_linker_map}
-  Pretty                                    : ${PRETTY:--}
-  Pretty args                               : ${PRETTY_ARGS:--}
-  Pretty check                              : ${PRETTY_CHECK:--}
-  Pretty check args                         : ${PRETTY_CHECK_ARGS:--}
   OpenThread FTD support                    : ${enable_ftd}
   OpenThread MTD support                    : ${enable_mtd}
   OpenThread Radio Only support             : ${enable_radio_only}
@@ -1091,6 +1138,6 @@
   OpenThread Vendor Extension Source        : ${with_vendor_extension}
   OpenThread builtin mbedtls support        : ${enable_builtin_mbedtls}
   OpenThread Examples                       : ${with_examples}
-  OpenThread POSIX Application              : ${enable_posix_app}
+  OpenThread Platform Libraries             : ${with_platform}
 
 ])
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 66e8aa3..b08da75 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -38,7 +38,6 @@
     $(srcdir)/images/ot-contrib-google.png        \
     $(srcdir)/images/ot-contrib-nordic.png        \
     $(srcdir)/images/ot-contrib-nxp.png           \
-    $(srcdir)/images/ot-contrib-particle.png      \
     $(srcdir)/images/ot-contrib-qc.png            \
     $(srcdir)/images/ot-contrib-qorvo.png         \
     $(srcdir)/images/ot-contrib-samsung.png       \
diff --git a/doc/images/ot-contrib-particle.png b/doc/images/ot-contrib-particle.png
deleted file mode 100644
index bf5ffc5..0000000
--- a/doc/images/ot-contrib-particle.png
+++ /dev/null
Binary files differ
diff --git a/doc/ot_api_doc.h b/doc/ot_api_doc.h
index bfec2cd..335a6e6 100644
--- a/doc/ot_api_doc.h
+++ b/doc/ot_api_doc.h
@@ -33,102 +33,103 @@
  */
 
 /**
- * @defgroup api  API
+ * @defgroup api                      API
  * @brief
  *   This module includes the application programming interface to the OpenThread stack.
  *
  * @{
  *
- * @defgroup api-error Error
+ * @defgroup api-error                Error
  *
- * @defgroup api-execution Execution
+ * @defgroup api-execution            Execution
  *
  * @{
  *
- * @defgroup api-instance Instance
- * @defgroup api-tasklets Tasklets
+ * @defgroup api-instance             Instance
+ * @defgroup api-tasklets             Tasklets
  *
  * @}
  *
- * @defgroup api-net IPv6 Networking
+ * @defgroup api-net                  IPv6 Networking
  * @{
  *
- * @defgroup api-dns         DNSv6
- * @defgroup api-icmp6       ICMPv6
- * @defgroup api-ip6         IPv6
- * @defgroup api-udp-group   UDP
+ * @defgroup api-dns                  DNSv6
+ * @defgroup api-icmp6                ICMPv6
+ * @defgroup api-ip6                  IPv6
+ * @defgroup api-udp-group            UDP
  *
  * @{
  *
- * @defgroup api-udp         UDP
- * @defgroup api-udp-forward UDP Forward
+ * @defgroup api-udp                  UDP
+ * @defgroup api-udp-forward          UDP Forward
  *
  * @}
  *
  * @}
  *
- * @defgroup api-link Link
+ * @defgroup api-link                 Link
  *
  * @{
  *
- * @defgroup api-link-link Link
- * @defgroup api-link-raw  Raw Link
+ * @defgroup api-link-link            Link
+ * @defgroup api-link-raw             Raw Link
  *
  * @}
  *
- * @defgroup api-message Message
+ * @defgroup api-message              Message
  *
- * @defgroup api-thread Thread
+ * @defgroup api-thread               Thread
  *
  * @{
  *
- * @defgroup api-border-agent   Border Agent
- * @defgroup api-border-router  Border Router
- * @defgroup api-commissioner   Commissioner
- * @defgroup api-thread-general General
+ * @defgroup api-backbone-router      Backbone Router
+ * @defgroup api-border-agent         Border Agent
+ * @defgroup api-border-router        Border Router
+ * @defgroup api-commissioner         Commissioner
+ * @defgroup api-thread-general       General
  * @brief This module includes functions for all Thread roles.
- * @defgroup api-joiner         Joiner
- * @defgroup api-thread-router  Router/Leader
+ * @defgroup api-joiner               Joiner
+ * @defgroup api-thread-router        Router/Leader
  * @brief This module includes functions for Thread Routers and Leaders.
- * @defgroup api-server         Server
+ * @defgroup api-server               Server
  *
  * @}
  *
- * @defgroup api-addons Add-Ons
+ * @defgroup api-addons               Add-Ons
  *
  * @{
  *
- * @defgroup api-channel-manager     Channel Manager
- * @defgroup api-channel-monitor     Channel Monitoring
- * @defgroup api-child-supervision   Child Supervision
- * @defgroup api-coap-group          CoAP
+ * @defgroup api-channel-manager      Channel Manager
+ * @defgroup api-channel-monitor      Channel Monitoring
+ * @defgroup api-child-supervision    Child Supervision
+ * @defgroup api-coap-group           CoAP
  *
  * @{
  *
- * @defgroup api-coap                CoAP
- * @defgroup api-coap-secure         CoAP Secure
+ * @defgroup api-coap                 CoAP
+ * @defgroup api-coap-secure          CoAP Secure
  *
  * @}
  *
- * @defgroup api-cli                 Command Line Interface
- * @defgroup api-crypto              Crypto
- * @defgroup api-entropy             Entropy Source
- * @defgroup api-factory-diagnostics Factory Diagnostics
- * @defgroup api-heap                Heap
- * @defgroup api-jam-detection       Jam Detection
- * @defgroup api-logging             Logging
- * @defgroup api-ncp                 Network Co-Processor
- * @defgroup api-network-time        Network Time Synchronization
- * @defgroup api-random-group        Random Number Generator
+ * @defgroup api-cli                  Command Line Interface
+ * @defgroup api-crypto               Crypto
+ * @defgroup api-entropy              Entropy Source
+ * @defgroup api-factory-diagnostics  Factory Diagnostics
+ * @defgroup api-heap                 Heap
+ * @defgroup api-jam-detection        Jam Detection
+ * @defgroup api-logging              Logging
+ * @defgroup api-ncp                  Network Co-Processor
+ * @defgroup api-network-time         Network Time Synchronization
+ * @defgroup api-random-group         Random Number Generator
  *
  * @{
  *
- * @defgroup api-random-crypto       RNG Cryptographic
- * @defgroup api-random-non-crypto   RNG Non-cryptographic
+ * @defgroup api-random-crypto        RNG Cryptographic
+ * @defgroup api-random-non-crypto    RNG Non-cryptographic
  *
  * @}
  *
- * @defgroup api-sntp                SNTP
+ * @defgroup api-sntp                 SNTP
  *
  * @}
  *
@@ -137,7 +138,7 @@
  */
 
 /**
- * @defgroup platform  Platform Abstraction
+ * @defgroup platform                 Platform Abstraction
  * @brief
  *   This module includes the platform abstraction used by the OpenThread stack.
  *
@@ -151,6 +152,7 @@
  * @defgroup plat-memory              Memory
  * @defgroup plat-messagepool         Message Pool
  * @defgroup plat-misc                Miscellaneous
+ * @defgroup plat-otns                Network Simulator
  * @defgroup plat-radio               Radio
  * @defgroup plat-settings            Settings
  * @defgroup plat-spi-slave           SPI Slave
@@ -161,4 +163,3 @@
  * @}
  *
  */
-
diff --git a/doc/site/en/guides/thread-primer/index.md b/doc/site/en/guides/thread-primer/index.md
new file mode 100644
index 0000000..fe9e6f2
--- /dev/null
+++ b/doc/site/en/guides/thread-primer/index.md
@@ -0,0 +1,37 @@
+# What is Thread?
+
+<figure class="attempt-right">
+<img src="../images/ot-logo-thread.png" srcset="../images/ot-logo-thread.png 1x, ../images/ot-logo-thread_2x.png 2x" border="0" alt="Thread" />
+</figure>
+
+<a href="http://threadgroup.org/">Thread<sup>®</sup></a> is an IPv6-based
+networking protocol designed for low-power Internet of Things devices in an IEEE
+802.15.4-2006 wireless mesh network, commonly called a Wireless Personal Area
+Network (WPAN). Thread is independent of other 802.15 mesh networking
+protocols, such a ZigBee, Z-Wave, and Bluetooth LE.
+
+Thread's primary features include:
+
+*   Simplicity — Simple installation, start up, and operation
+*   Security — All devices in a Thread network are authenticated and all
+    communications are encrypted
+*   Reliability — Self-healing mesh networking, with no single point of failure,
+    and spread-spectrum techniques to provide immunity to interference
+*   Efficiency — Low-power Thread devices can sleep and operate on battery power
+    for years
+*   Scalability — Thread networks can scale up to hundreds of devices
+
+If you're new to Thread, understanding the basics are critical to using
+OpenThread in your own applications. The goal of this primer is to explain the
+concepts behind Thread and how it works, and provide a springboard to OpenThread
+development.
+
+It is assumed you have good working knowledge of the following:
+
+*   IEEE 802.15.4
+*   Networking and routing concepts
+*   IPv6
+
+This primer is based on version 1.1.1 of the Thread Specification. It does not
+cover the full specification, which is available at
+[threadgroup.org](http://threadgroup.org/ThreadSpec).
diff --git a/doc/site/en/guides/thread-primer/ipv6-addressing.md b/doc/site/en/guides/thread-primer/ipv6-addressing.md
new file mode 100644
index 0000000..4385695
--- /dev/null
+++ b/doc/site/en/guides/thread-primer/ipv6-addressing.md
@@ -0,0 +1,276 @@
+# IPv6 Addressing
+
+Let's take a look at how Thread identifies each device in the network, and what
+types of addresses they use to communicate with each other.
+
+Key Term: In this primer, the term "interface" is used to identify an endpoint
+of a Thread device within a network. Typically, a single Thread device has
+a single Thread interface.
+
+## Scopes
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-scopes_2x.png"><img src="../images/ot-primer-scopes.png" srcset="../images/ot-primer-scopes.png 1x, ../images/ot-primer-scopes_2x.png 2x" border="0" alt="OT Scopes" /></a>
+</figure>
+
+There are three scopes in a Thread network for unicast addressing:
+
+*   Link-Local — all interfaces reachable by a single radio transmission
+*   Mesh-Local — all interfaces reachable within the same Thread network
+*   Global — all interfaces reachable from outside a Thread network
+
+The first two scopes correspond to prefixes designated by a Thread network.
+Link-Local have prefixes of `fe80::/16`, while Mesh-Local have prefixes of
+`fd00::/8`.
+
+<h2 style="clear:right">Unicast</h2>
+
+There are multiple IPv6 unicast addresses that identify a single Thread device.
+Each has a different function based on the scope and use case.
+
+Before we detail each type, let's learn more about a common one, called the
+Routing Locator (RLOC). The RLOC identifies a Thread interface, based on its
+location in the network topology.
+
+### How a Routing Locator is generated
+
+All devices are assigned a Router ID and a Child ID. Each Router maintains a
+table of all their Children, the combination of which uniquely identifies a
+device within the topology.  For example, consider the highlighted nodes in the
+following topology, where the number in a Router (pentagon) is the Router ID,
+and the number in an End Device (circle) is the Child ID:
+
+<figure>
+<a href="../images/ot-primer-rloc-topology_2x.png"><img src="../images/ot-primer-rloc-topology.png" srcset="../images/ot-primer-rloc-topology.png 1x, ../images/ot-primer-rloc-topology_2x.png 2x" border="0" width="600" alt="OT RLOC Topology" /></a>
+</figure>
+
+Each Child's Router ID corresponds to their Parent (Router). Because a Router is
+not a Child, the Child ID for a Router is always 0. Together, these values are
+unique for each device in the Thread network, and are used to create the RLOC16,
+which represents the last 16 bits of the RLOC.
+
+For example, here's how the RLOC16 is calculated for the upper-left node (Router
+ID = 1 and Child ID = 1):
+
+<figure>
+<a href="../images/ot-primer-rloc16_2x.png"><img src="../images/ot-primer-rloc16.png" srcset="../images/ot-primer-rloc16.png 1x, ../images/ot-primer-rloc16_2x.png 2x" border="0" width="400" alt="OT RLOC16" /></a>
+</figure>
+
+The RLOC16 is part of the Interface Identifier (IID), which corresponds to the
+last 64 bits of the IPv6 address. Some IIDs can be used to identify some types
+of Thread interfaces. For example, the IID for RLOCs is always of the form
+<code>0000:00ff:fe00:<var>RLOC16</var></code>.
+
+The IID, combined with a Mesh-Local Prefix, results in the RLOC. For example,
+using a Mesh-Local Prefix of `fde5:8dba:82e1:1::/64`, the RLOC for a node where
+RLOC16 = `0x401` is:
+
+<figure>
+<a href="../images/ot-primer-rloc_2x.png"><img src="../images/ot-primer-rloc.png" srcset="../images/ot-primer-rloc.png 1x, ../images/ot-primer-rloc_2x.png 2x" border="0" width="600" alt="OT RLOC" /></a>
+</figure>
+
+This same logic can be used to determine the RLOC for all highlighted nodes in the sample topology above:
+
+<figure>
+<a href="../images/ot-primer-rloc-topology-address_2x.png"><img src="../images/ot-primer-rloc-topology-address.png" srcset="../images/ot-primer-rloc-topology-address.png 1x, ../images/ot-primer-rloc-topology-address_2x.png 2x" border="0" width="600" alt="OT Topology w/ Address" /></a>
+</figure>
+
+However, because the RLOC is based on the location of the node in the topology,
+the RLOC of a node can change as the topology changes.
+
+For example, perhaps node `0x400` is removed from the Thread network. Nodes
+`0x401` and `0x402` establish new links to different Routers, and as a result
+they are each assigned a new RLOC16 and RLOC:
+
+<figure>
+<a href="../images/ot-primer-rloc-topology-change_2x.png"><img src="../images/ot-primer-rloc-topology-change.png" srcset="../images/ot-primer-rloc-topology-change.png 1x, ../images/ot-primer-rloc-topology-change_2x.png 2x" border="0" width="600" alt="OT Topology after Change" /></a>
+</figure>
+
+## Unicast address types
+The RLOC is just one of many IPv6 unicast addresses a Thread device can have.
+Another category of addresses are called Endpoint Identifiers (EIDs), which
+identify a unique Thread interface within a Thread network partition. EIDs are
+independent of Thread network topology.
+
+Common unicast types are detailed below.
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Link-Local Address (LLA)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">An EID that identifies a Thread interface reachable by a single radio transmission.</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>fe80::54db:881c:3845:57f4</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td>Based on 802.15.4 Extended Address</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Link-Local</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li>Used to discover neighbors, configure links, and exchange routing information</li><li>Not a routable address</li><li>Always has a prefix of <code>fe80::/16</code></li></ul></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Mesh-Local EID (ML-EID)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">An EID that identifies a Thread interface, independent of network topology. Used to reach a Thread interface within the same Thread partition. Also called a Unique Local Address (ULA).</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>fde5:8dba:82e1:1:416:993c:8399:35ab</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td>Random, chosen after commissioning is complete</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Mesh-Local</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li>Does not change as the topology changes</li><li>Should be used by applications</li><li>Always has a prefix <code>fd00::/8</code></li></ul></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Routing Locator (RLOC)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">Identifies a Thread interface, based on its location in the network topology.</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>fde5:8dba:82e1:1::ff:fe00:1001</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><code>0000:00ff:fe00:<var>RLOC16</var></code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Mesh-Local</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li>Generated once a device attaches to a network</li><li>For delivering IPv6 datagrams within a Thread network</li><li>Changes as the topology changes</li><li>Generally not used by applications</li></ul></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Anycast Locator (ALOC)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">Identifies a Thread interface via RLOC lookup, when the RLOC of a destination is not known.</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>fde5:8dba:82e1:1::ff:fe00:fc01</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><code>0000:00ff:fe00:fc<var>XX</var></code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Mesh-Local</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li><code>fc<var>XX</var></code> = <a href="#anycast">ALOC destination</a>, which looks up the appropriate RLOC</li><li>Generally not used by applications</li></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Global Unicast Address (GUA)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">An EID that identifies a Thread interface on a global scope, beyond a Thread network.</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>2000::54db:881c:3845:57f4</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><ul><li>SLAAC — Randomly assigned by the device itself</li><li>DHCP — Assigned by a DHCPv6 server</li><li>Manual — Assigned by the application layer</li></ul></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Global</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li>A public IPv6 address</li><li>Always has a prefix of <code>2000::/3</code></li></td>
+    </tr>
+  </tbody>
+</table>
+
+## Multicast
+
+Multicast is used to communicate information to multiple devices at once. In a
+Thread network, specific addresses are reserved for multicast use with different
+groups of devices, depending on the scope.
+
+| IPv6 Address | Scope      | Delivered to      |
+| ------------ | ---------- | ----------------- |
+| `ff02::1`    | Link-Local | All FTDs and MEDs |
+| `ff02::2`    | Link-Local | All FTDs          |
+| `ff03::1`    | Mesh-Local | All FTDs and MEDs |
+| `ff03::2`    | Mesh-Local | All FTDs          |
+
+Key Point: A major difference between FTDs and MTDs are that FTDs subscribe to
+the `ff03::2` multicast address. MTDs do not.
+
+You might notice that Sleepy End Devices (SEDs) are not included as a
+recipient in the multicast table above. Instead, Thread defines
+link-local and realm-local scope unicast prefix-based IPv6 multicast
+address used for All Thread Nodes, including SEDs. These multicast
+addresses vary by Thread network, because it is built on the unicast
+Mesh-Local prefix (see [RFC 3306](https://tools.ietf.org/html/rfc3306)
+for more details on unicast-prefix-based IPv6 multicast addresses).
+
+Arbitrary scopes beyond those already listed are also supported for Thread
+devices.
+
+
+## Anycast
+
+Anycast is used to route traffic to a Thread interface when the RLOC of a
+destination is not known. An Anycast Locator (ALOC) identifies the location of
+multiple interfaces within a Thread partition. The last 16 bits of an ALOC,
+called the ALOC16, is in the format of <code>0xfc<var>XX</var></code>, which
+represents the type of ALOC.
+
+For example, an ALOC16 between `0xfc01` and `0xfc0f` is reserved for DHCPv6
+Agents. If the specific DHCPv6 Agent RLOC is unknown (perhaps because the
+network topology has changed), a message can be sent to a DHCPv6 Agent ALOC to
+obtain the RLOC.
+
+Thread defines the following ALOC16 values:
+
+| ALOC16                                     | Type                     |
+| ------------------------------------------ | ------------------------ |
+| `0xfc00`                                   | Leader                   |
+| `0xfc01` – `0xfc0f`                        | DHCPv6 Agent             |
+| `0xfc10` – `0xfc2f`                        | Service                  |
+| `0xfc30` – `0xfc37`                        | Commissioner             |
+| `0xfc40` – `0xfc4e`                        | Neighbor Discovery Agent |
+| `0xfc38` – `0xfc3f`<br>`0xfc4f` – `0xfcff` | Reserved                 |
+
+## Recap
+
+What you've learned:
+
+*   A Thread network consists of three scopes: Link-Local, Mesh-Local, and Global
+*   A Thread device has multiple unicast IPv6 addresses
+    *   An RLOC represents a device's location in the Thread network
+    *   An ML-EID is unique to a Thread device within a partition and should be used by applications
+*   Thread uses multicast to forward data to groups of nodes and routers
+*   Thread uses anycast when the RLOC of a destination is unknown
+
+To learn more about Thread's IPv6 addressing, see sections 5.2 and 5.3 of the
+[Thread Specification](http://threadgroup.org/ThreadSpec).
diff --git a/doc/site/en/guides/thread-primer/network-discovery.md b/doc/site/en/guides/thread-primer/network-discovery.md
new file mode 100644
index 0000000..c4ff1e8
--- /dev/null
+++ b/doc/site/en/guides/thread-primer/network-discovery.md
@@ -0,0 +1,292 @@
+# Network Discovery and Formation
+
+## Thread networks
+
+Thread networks are identified by three unique identifiers:
+
+*   2-byte Personal Area Network ID (PAN ID)
+*   8-byte Extended Personal Area Network ID (XPAN ID)
+*   A human-readable Network Name
+
+For example, a Thread network may have the following identifiers:
+
+Identifier | Value
+---- | ----
+PAN ID | `0xBEEF`
+XPAN ID | `0xBEEF1111CAFE2222`
+Network Name | `yourThreadCafe`
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-network-active-scan_2x.png"><img src="../images/ot-primer-network-active-scan.png" srcset="../images/ot-primer-network-active-scan.png 1x, ../images/ot-primer-network-active-scan_2x.png 2x" border="0" alt="OT Active Scan" /></a>
+</figure>
+
+When creating a new Thread network, or searching for an existing one to join, a
+Thread device performs an active scan for 802.15.4 networks within radio range:
+
+1.  The device broadcasts an 802.15.4 Beacon Request on a specific Channel.
+1.  In return, any Routers or Router Eligible End Devices (REEDs) in range
+    broadcast a Beacon that contains their Thread network PAN ID, XPAN ID, and
+    Network Name.
+1.  The device repeats the previous two steps for each Channel.
+
+Once a Thread device has discovered all networks in range, it can either attach
+to an existing network, or create a new one if no networks are discovered.
+
+<h2 style="clear:right">Mesh Link Establishment</h2>
+
+Thread uses the Mesh Link Establishment (MLE) protocol to configure links and
+disseminate information about the network to Thread devices.
+
+In link configuration, MLE is used to:
+
+*   Discover links to neighboring devices
+*   Determine the quality of links to neighboring devices
+*   Establish links to neighboring devices
+*   Negotiate link parameters (device type, frame counters, timeout) with peers
+
+MLE disseminates the following types of information to devices wishing to
+establish links:
+
+*   Leader data (Leader RLOC, Partition ID, Partition weight)
+*   Network data (on-mesh prefixes, address autoconfiguration, more-specific
+    routes)
+*   Route propagation
+
+Route propagation in Thread works similar to the Routing Information Protocol
+(RIP), a distance-vector routing protocol.
+
+Note: MLE only proceeds once a Thread device has obtained Thread network
+credentials through Thread Commissioning. Commissioning and Security will be
+covered in depth later in this Primer. For now, this page assumes that the
+device has already been commissioned.
+
+## Create a new network
+
+If the device elects to create a new network, it selects the least busy Channel
+and a PAN ID not in use by other networks, then becomes a Router and elects
+itself the Leader. This device sends MLE Advertisement messages to other
+802.15.4 devices to inform them of its link state, and responds to Beacon
+Requests by other Thread devices performing an active scan.
+
+## Join an existing network
+
+If the device elects to join an existing network, it configures its Channel, PAN
+ID, XPAN ID, and Network Name to match that of the target network via Thread
+Commissioning, then goes through the MLE Attach process to attach as a Child
+(End Device). This process is used for Child-Parent links.
+
+Key Point: Every device, router-capable or not, initially attaches to a Thread
+network as a Child (End Device).
+
+1.  The Child sends a multicast [Parent Request](#1_parent_request) to all
+    neighboring Routers and REEDs in the target network.
+1.  All neighboring Routers and REEDs (if the Parent Request Scan Mask includes
+    REEDs) send [Parent Responses](#2_parent_response) with information about
+    themselves.
+1.  The Child chooses a Parent device and sends a [Child ID
+    Request](#3_child_id_request) to it.
+1.  The Parent sends a [Child ID Response](#4_child_id_response) to confirm link
+    establishment.
+
+### 1. Parent Request
+
+A Parent Request is a multicast request from the attaching device that is used
+to discover neighboring Routers and Router Eligible End Devices (REEDs) in the
+target network.
+
+<figure>
+<a href="../images/ot-primer-network-mle-attach-01_2x.png"><img src="../images/ot-primer-network-mle-attach-01.png" srcset="../images/ot-primer-network-mle-attach-01.png 1x, ../images/ot-primer-network-mle-attach-01_2x.png 2x" width="350" border="0" alt="OT MLE Attach Parent Request" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Parent Request Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Mode</b></td>
+      <td>Describes the attaching device</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
+      <td>Tests the timeliness of the Parent Response to prevent replay
+        attacks</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scan Mask</b></td>
+      <td>Limits the request to only Routers or to both Routers and REEDs</td>
+    </tr>
+  </tbody>
+</table>
+
+### 2. Parent Response
+
+A Parent Response is a unicast response to a Parent Request that provides
+information about a Router or REED to the attaching device.
+
+<figure>
+<a href="../images/ot-primer-network-mle-attach-02_2x.png"><img src="../images/ot-primer-network-mle-attach-02.png" srcset="../images/ot-primer-network-mle-attach-02.png 1x, ../images/ot-primer-network-mle-attach-02_2x.png 2x" width="350" border="0" alt="OT MLE Attach Parent Response" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Parent Response Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
+      <td>Thread protocol version</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
+      <td>Copy of the Parent Request Challenge</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
+        Counter</b></td>
+      <td>802.15.4 Frame Counter on the Router/REED</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
+        Counter</b></td>
+      <td>MLE Frame Counter on the Router/REED</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
+        Address</b></td>
+      <td>RLOC16 of the Router/REED</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link
+        Margin</b></td>
+      <td>Receive signal quality of the Router/REED</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Connectivity</b></td>
+      <td>Describes the Router/REED’s level of connectivity</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
+        Data</b></td>
+      <td>Information about the Router/REED’s Leader</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
+      <td>Tests the timeliness of the Child ID Request to prevent replay
+        attacks</td>
+    </tr>
+  </tbody>
+</table>
+
+### 3. Child ID Request
+
+A Child ID Request is a unicast request from the attaching device (Child) that
+is sent to the Router or REED (Parent) for the purpose of establishing a
+Child-Parent link. If the request is sent to a REED, it [upgrades itself to a
+Router](/guides/thread-primer/router-selection#upgrade_to_a_router) before
+accepting the request.
+
+<figure>
+<a href="../images/ot-primer-network-mle-attach-03_2x.png"><img src="../images/ot-primer-network-mle-attach-03.png" srcset="../images/ot-primer-network-mle-attach-03.png 1x, ../images/ot-primer-network-mle-attach-03_2x.png 2x" width="350" border="0" alt="OT MLE Attach Child ID Request" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Child ID Request Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
+      <td>Thread protocol version</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
+      <td>Copy of the Parent Response Challenge</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
+        Counter</b></td>
+      <td>802.15.4 Frame Counter on the Child</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
+        Counter</b></td><td>MLE Frame Counter on the Child</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Mode</b></td>
+      <td>Describes the Child</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Timeout</b></td>
+      <td>Inactivity duration before the Parent removes the Child</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address
+        Registration (MEDs and SEDs only)</b></td>
+      <td>Register IPv6 addresses</td>
+    </tr>
+  </tbody>
+</table>
+
+### 4. Child ID Response
+
+A Child ID Response is a unicast response from the Parent that is sent to the
+Child to confirm that a Child-Parent link has been established.
+
+<figure>
+<a href="../images/ot-primer-network-mle-attach-04_2x.png"><img src="../images/ot-primer-network-mle-attach-04.png" srcset="../images/ot-primer-network-mle-attach-04.png 1x, ../images/ot-primer-network-mle-attach-04_2x.png 2x" width="350" border="0" alt="OT MLE Attach Child ID Response" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Child ID Response Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
+        Address</b></td>
+      <td>Parent's RLOC16</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address16</b></td>
+      <td>Child's RLOC16</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
+        Data</b></td>
+      <td>Information about the Parent’s Leader (RLOC, Partition ID, Partition
+        weight)</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Network
+        Data</b></td>
+      <td>Information about the Thread network (on-mesh prefixes, address
+        autoconfiguration, more-specific routes)</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Route
+        (REED only)</b></td>
+      <td>Route propagation</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Timeout</b></td>
+      <td>Inactivity duration before the Parent removes the Child</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address
+        Registration (MEDs and SEDs only)</b></td>
+      <td>Confirm registered addresses</td>
+    </tr>
+  </tbody>
+</table>
+
+## Recap
+
+What you've learned:
+
+*   A Thread device performs an active scan for existing networks
+*   Thread uses Mesh Link Establishment to configure links and disseminate
+    information about network devices
+*   MLE Advertisement messages inform other Thread devices about a device's
+    network and link state
+*   The MLE Attach process establishes Child-Parent links
diff --git a/doc/site/en/guides/thread-primer/node-roles-and-types.md b/doc/site/en/guides/thread-primer/node-roles-and-types.md
new file mode 100644
index 0000000..2db6213
--- /dev/null
+++ b/doc/site/en/guides/thread-primer/node-roles-and-types.md
@@ -0,0 +1,152 @@
+# Node Roles and Types
+
+## Forwarding roles
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-roles_2x.png"><img src="../images/ot-primer-roles.png" srcset="../images/ot-primer-roles.png 1x, ../images/ot-primer-roles_2x.png 2x" border="0" alt="OT Node Roles" /></a>
+</figure>
+
+In a Thread network, nodes are split into two forwarding roles:
+
+### Router
+
+A Router is a node that:
+
+*   forwards packets for network devices
+*   provides secure commissioning services for devices trying to join the network
+*   keeps its transceiver enabled at all times
+
+### End Device
+
+An End Device (ED) is a node that:
+
+*   communicates primarily with a single Router
+*   does not forward packets for other network devices
+*   can disable its transceiver to reduce power
+
+Key Point: The relationship between Router and End Device is a Parent-Child
+relationship. An End Device attaches to exactly one Router. The Router is always
+the Parent, the End Device the Child.
+
+## Device types
+
+Furthermore, nodes comprise a number of types.
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-taxonomy_2x.png"><img src="../images/ot-primer-taxonomy.png" srcset="../images/ot-primer-taxonomy.png 1x, ../images/ot-primer-taxonomy.png 2x" border="0" alt="OT Device Taxonomy" /></a>
+</figure>
+
+### Full Thread Device
+
+A Full Thread Device (FTD) always has its radio on, subscribes to the
+all-routers multicast address, and maintains IPv6 address mappings. There are
+three types of FTDs:
+
+*   Router
+*   Router Eligible End Device (REED) — can be promoted to a Router
+*   Full End Device (FED) — cannot be promoted to a Router
+
+An FTD can operate as a Router (Parent) or an End Device (Child).
+
+### Minimal Thread Device
+
+A Minimal Thread Device does not subscribe to the all-routers
+multicast address and forwards all messages to its Parent. There are
+two types of MTDs:
+
+*   Minimal End Device (MED) — transceiver always on, does not need to poll for
+    messages from its parent
+*   Sleepy End Device (SED) — normally disabled, wakes on occasion to poll for
+    messages from its parent
+
+An MTD can only operate as an End Device (Child).
+
+### Upgrading and downgrading
+
+When a REED is the only node in reach of a new End Device wishing to join the
+Thread network, it can upgrade itself and operate as a Router:
+
+<figure>
+<a href="../images/ot-primer-router-upgrade_2x.png"><img src="../images/ot-primer-router-upgrade.png" srcset="../images/ot-primer-router-upgrade.png 1x, ../images/ot-primer-router-upgrade_2x.png 2x" border="0" width="400" alt="OT End Device to Router" /></a>
+</figure>
+
+Conversely, when a Router has no children, it can downgrade itself and operate
+as an End Device:
+
+<figure>
+<a href="../images/ot-primer-router-downgrade_2x.png"><img src="../images/ot-primer-router-downgrade.png" srcset="../images/ot-primer-router-downgrade.png 1x, ../images/ot-primer-router-downgrade_2x.png 2x" border="0" width="400" alt="OT Router to End Device" /></a>
+</figure>
+
+## Other roles and types
+
+### Thread Leader
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-leader_2x.png"><img src="../images/ot-primer-leader.png" srcset="../images/ot-primer-leader.png 1x, ../images/ot-primer-leader_2x.png 2x" border="0" alt="OT Leader and Border Router" /></a>
+</figure>
+
+The Thread Leader is a Router that is responsible for managing the set of
+Routers in a Thread network. It is dynamically self-elected for fault tolerance,
+and aggregates and distributes network-wide configuration information.
+
+Note: There is always a single Leader in each Thread network
+[partition](#partitions).
+
+### Border Router
+
+A Border Router is a device that can forward information between a Thread
+network and a non-Thread network (for example, Wi-Fi). It also configures a
+Thread network for external connectivity.
+
+Any device may serve as a Border Router.
+
+Note: There can be multiple Border Routers in a Thread network.
+
+## Partitions
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-partitions_2x.png"><img src="../images/ot-primer-partitions.png" srcset="../images/ot-primer-partitions.png 1x, ../images/ot-primer-partitions_2x.png 2x" border="0" alt="OT Partitions" /></a>
+</figure>
+
+A Thread network might be composed of partitions. This occurs when a group of
+Thread devices can no longer communicate with another group of Thread devices.
+Each partition logically operates as a distinct Thread network with its own
+Leader, Router ID assignments, and network data, while retaining the same
+security credentials for all devices across all partitions.
+
+Partitions in a Thread network do not have wireless connectivity between each
+other, and if partitions regain connectivity, they automatically merge into a
+single partition.
+
+Key Point: Security credentials define the Thread network. Physical radio
+connectivity defines partitions within that Thread network.
+
+Note that the use of "Thread network" in this primer assumes a single partition.
+Where necessary, key concepts and examples are clarified with the term "partition."
+Partitions are covered in-depth later in this primer.
+
+## Device limits
+
+There are limits to the number of device types a single Thread network supports.
+
+Role | Limit
+----|----
+Leader | 1
+Router | 32
+End Device | 511 per Router
+
+Thread tries to keep the number of Routers between 16 and 23. If a REED attaches
+as an End Device and the number of Routers in the network is below 16, it
+automatically promotes itself to a Router.
+
+## Recap
+
+What you learned:
+
+*   A Thread device is either a Router (Parent) or an End Device (Child)
+*   A Thread device is either a Full Thread Device (maintains IPv6 address
+    mappings) or a Minimal Thread Device (forwards all messages to its Parent)
+*   A Router Eligible End Device can promote itself to a Router, and vice versa
+*   Every Thread network partition has a Leader to manage Routers
+*   A Border Router is used to connect Thread and non-Thread networks
+*   A Thread network might be composed of multiple partitions
diff --git a/doc/site/en/guides/thread-primer/router-selection.md b/doc/site/en/guides/thread-primer/router-selection.md
new file mode 100644
index 0000000..be96bb6
--- /dev/null
+++ b/doc/site/en/guides/thread-primer/router-selection.md
@@ -0,0 +1,176 @@
+# Router Selection
+
+## Connected Dominating Set
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-cds_2x.png"><img src="../images/ot-primer-cds.png" srcset="../images/ot-primer-cds.png 1x, ../images/ot-primer-cds_2x.png 2x" width="350" border="0" alt="OT Connected Dominating Set" /></a><figcaption style="text-align: center"><i>Example of a Connected Dominating Set</i></figcaption>
+</figure>
+
+Routers must form a Connected Dominating Set (CDS), which means:
+
+1.  There is a Router-only path between any two Routers.
+1.  Any one Router in a Thread network can reach any other Router by staying
+    entirely within the set of Routers.
+1.  Every End Device in a Thread network is directly connected to a Router.
+
+A distributed algorithm maintains the CDS, which ensures a minimum level of
+redundancy. Every device initially attaches to the network as an End Device
+(Child). As the state of the Thread network changes, the algorithm adds or
+removes Routers to maintain the CDS.
+
+Thread adds Routers to:
+
+*   Increase coverage if the network is below the Router threshold of 16
+*   Increase path diversity
+*   Maintain a minimum level of redundancy
+*   Extend connectivity and support more Children
+
+Thread removes Routers to:
+
+*   Reduce the Routing state below the maximum of 32 Routers
+*   Allow new Routers in other parts of the network when needed
+
+## Upgrade to a Router
+
+After attaching to a Thread network, the Child device may elect to become a
+Router. Before initiating the MLE Link Request process, the Child sends an
+Address Solicit message to the Leader, asking for a Router ID. If the Leader
+accepts, it responds with a Router ID and the Child upgrades itself to a Router.
+
+The MLE Link Request process is then used to establish bi-directional
+Router-Router links with neighboring Routers.
+
+1.  The new Router sends a multicast [Link Request](#1_link_request) to
+    neighboring Routers.
+1.  Routers respond with [Link Accept and Request](#2_link_accept_and_request)
+    messages.
+1.  The new Router responds to each Router with a unicast [Link
+    Accept](#3_link_accept) to establish the Router-Router link.
+
+### 1. Link Request
+
+A Link Request is a request from the Router to all other Routers in the Thread
+network. When first becoming a Router, the device sends a multicast Link Request
+to `ff02::2`. Later, after discovering the other Routers via MLE Advertisements,
+the devices send unicast Link Requests.
+
+<figure>
+<a href="../images/ot-primer-network-mle-link-request-01_2x.png"><img src="../images/ot-primer-network-mle-link-request-01.png" srcset="../images/ot-primer-network-mle-link-request-01.png 1x, ../images/ot-primer-network-mle-link-request-01_2x.png 2x" width="350" border="0" alt="OT MLE Link Request" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Link Request Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
+      <td>Thread protocol version</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
+      <td>Tests the timeliness of the Link Response to prevent replay
+        attacks</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
+        Address</b></td>
+      <td>RLOC16 of the sender</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
+        Data</b></td>
+      <td>Information about the Router's Leader, as stored on the sender (RLOC,
+        Partition ID, Partition weight)</td>
+    </tr>
+  </tbody>
+</table>
+
+### 2. Link Accept and Request
+
+A Link Accept and Request is a combination of the Link Accept and Link Request
+messages. Thread uses this optimization in the MLE Link Request process to
+reduce the number of messages from four to three.
+
+<figure>
+<a href="../images/ot-primer-network-mle-link-request-02_2x.png"><img src="../images/ot-primer-network-mle-link-request-02.png" srcset="../images/ot-primer-network-mle-link-request-02.png 1x, ../images/ot-primer-network-mle-link-request-02_2x.png 2x" width="350" border="0" alt="OT MLE Link Accept and Request" /></a>
+</figure>
+
+### 3. Link Accept
+
+A Link Accept is a unicast response to a Link Request from a neighboring Router
+that provides information about itself and accepts the link to the neighboring
+Router.
+
+<figure>
+<a href="../images/ot-primer-network-mle-link-request-03_2x.png"><img src="../images/ot-primer-network-mle-link-request-03.png" srcset="../images/ot-primer-network-mle-link-request-03.png 1x, ../images/ot-primer-network-mle-link-request-03_2x.png 2x" width="350" border="0" alt="OT MLE Link Accept" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Link Accept Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
+      <td>Thread protocol version</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
+      <td>Tests the timeliness of the Link Response to prevent replay
+        attacks</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
+        Counter</b></td>
+      <td>802.15.4 Frame Counter on the sender</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
+        Counter</b></td>
+      <td>MLE Frame Counter on the sender</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
+        Address</b></td>
+      <td>RLOC16 of the sender</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
+        Data</b></td>
+      <td>Information about the Router's Leader, as stored on the sender (RLOC,
+        Partition ID, Partition weight)</td>
+    </tr>
+  </tbody>
+</table>
+
+## Downgrade to a REED
+
+When a Router downgrades to a REED, its Router-Router links are disconnected,
+and the device initiates the MLE Attach process to establish a Child-Parent
+link.
+
+See [Join an existing
+network](/guides/thread-primer/network-discovery#join_an_existing_network)
+for more information on the MLE Attach process.
+
+## One-way receive links
+
+In some scenarios, it may be necessary to establish a one-way receive link.
+
+After a Router reset, neighboring Routers may still have a valid receive link
+with the reset Router. In this case, the reset Router sends a Link Request
+message to re-establish the Router-Router link.
+
+An End Device may also wish to establish a receive link with neighboring
+non-Parent Routers to improve multicast reliability. We'll learn more about this
+when we get to Multicast Routing.
+
+## Recap
+
+What you've learned:
+
+*   Routers in a Thread network must form a Connected Dominating Set (CDS)
+*   Thread devices are upgraded to Routers or downgraded to End Devices to
+    maintain the CDS
+*   The MLE Link Request process is used to establish Router-Router links
diff --git a/doc/site/zh-cn/guides/thread-primer/index.md b/doc/site/zh-cn/guides/thread-primer/index.md
new file mode 100644
index 0000000..6b861f9
--- /dev/null
+++ b/doc/site/zh-cn/guides/thread-primer/index.md
@@ -0,0 +1,25 @@
+# 什么是 Thread?
+
+<figure class="attempt-right">
+<img src="../images/ot-logo-thread.png" srcset="../images/ot-logo-thread.png 1x, ../images/ot-logo-thread_2x.png 2x" border="0" alt="Thread" />
+</figure>
+
+<a href="http://threadgroup.org/">Thread<sup>®</sup></a> 是一个为低功耗物联网(IEEE 802.15.4-2006 WPAN)设备设计的基于 IPv6 的网络协议。Thread 是一个新的网状网络协议,它并不依赖其它的 802.15 网状网络协议(如 ZigBee、Z-Wave 和 Bluetooth LE)。
+
+Thread 的主要特性包括:
+
+* 易于部署和维护 — 安装、启动和操作相对简单
+* 通信安全 — Thread 网络中的设备都必须通过身份验证,并且所有的通信都经过了加密
+* 稳定可靠 — 具有自愈能力的网状网络,无单点故障,并且采用扩频技术以提高抗干扰能力
+* 低功耗 — Thread 低功耗设备可以进入休眠并使用电池供电,通常使用一块电池便能工作数年
+* 规模可扩展 — Thread 网络的规模可以扩展达数百个设备
+
+如果你不熟悉 Thread,那么了解基本的 Thread 知识对于你在应用中使用 OpenThread 是至关重要的。本入门教程的目的是解释 Thread 的基本概念和工作原理,并为你提供了 OpenThread 开发的起点。
+
+本教程假定读者已具备如下的基本知识:
+
+* IEEE 802.15.4
+* 网络及路由概念
+* IPv6
+
+本入门教程基于 Thread Specification V1.1.1。Thread Specification 可以在 [threadgroup.org](http://threadgroup.org/ThreadSpec) 中获取。
diff --git a/doc/site/zh-cn/guides/thread-primer/ipv6-addressing.md b/doc/site/zh-cn/guides/thread-primer/ipv6-addressing.md
new file mode 100644
index 0000000..56321b4
--- /dev/null
+++ b/doc/site/zh-cn/guides/thread-primer/ipv6-addressing.md
@@ -0,0 +1,231 @@
+# IPv6 寻址
+
+让我们来看一下 Thread 如何识别网络中的每个设备,以及设备间用何种类型的地址进行相互通信。
+
+Key Term: 在本入门教程中,术语“接口(interface)”用于标识网络内 Thread 设备的端点。通常,单个 Thread 设备具有单个 Thread 接口。
+
+## 域
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-scopes_2x.png"><img src="../images/ot-primer-scopes.png" srcset="../images/ot-primer-scopes.png 1x, ../images/ot-primer-scopes_2x.png 2x" border="0" alt="OT Scopes" /></a>
+</figure>
+
+Thread 网络中有三种域用于单播寻址:
+
+* Link-Local — 所有通过单次射频传输可访问的接口
+* Mesh-Local — 所有在同一 Thread 网络中可访问的接口
+* Global — 所有从 Thread 网络外部可以访问的接口
+
+前两个域与 Thread 网络指定的 Prefix(前缀)相对应。Link-Local 的 Prefix 为 `fe80::/16`,Mesh-Local 的 Prefix 为 `fd00::/8`。
+
+<h2 style="clear:right">单播</h2>
+
+单个 Thread 设备可以通过多种 IPv6 单播地址来进行标识。每种地址都有不同的功能(基于域和用例)。
+
+在介绍每种类型之前,让我们先了解一个共同的概念,它叫作 RLOC(Routing Locator)。RLOC 根据 Thread 接口在网络拓扑中的位置来对其进行标识。
+
+### 如何生成 RLOC
+
+所有设备都获得一个 Router ID 和一个 Child ID。每个 Router 维护一个包含其所有子节点的表,两个 ID 的组合唯一地标识拓扑中的设备。例如,请参考以下拓扑中高亮的节点,其中 Router(五边形)中的数字是 Router ID,End Device(圆形)中的数字是 Child ID:
+
+<figure>
+<a href="../images/ot-primer-rloc-topology_2x.png"><img src="../images/ot-primer-rloc-topology.png" srcset="../images/ot-primer-rloc-topology.png 1x, ../images/ot-primer-rloc-topology_2x.png 2x" border="0" width="600" alt="OT RLOC Topology" /></a>
+</figure>
+
+每个子节点的 Router ID 对应于它的父节点(Router)。因为 Router 不会是子节点,所以 Router 的 Child ID 始终为 0。这些值对于 Thread 网络中的每个设备都是唯一的,并用于创建 RLOC16(代表 RLOC 的后 16 位)。
+
+例如,以下是左上节点(Router ID = 1,Child ID = 1)的 RLOC16 的计算方法:
+
+<figure>
+<a href="../images/ot-primer-rloc16_2x.png"><img src="../images/ot-primer-rloc16.png" srcset="../images/ot-primer-rloc16.png 1x, ../images/ot-primer-rloc16_2x.png 2x" border="0" width="400" alt="OT RLOC16" /></a>
+</figure>
+
+RLOC16 是 IID(Interface Identifier)的一部分,IID 对应的是 IPv6 地址的后 64 位。一些 IID 可用于标识某些类型的 Thread 接口。例如,RLOC 的 IID 始终为 <code>0000:00ff:fe00:<var>RLOC16</var></code> 的形式。
+
+RLOC 由 Mesh-Local Prefix 和 IID 组成。例如,如果 Mesh-Local Prefix 是 `fde5:8dba:82e1:1::/64`,RLOC16 = `0x401`,那么该节点的 RLOC 就是:
+
+<figure>
+<a href="../images/ot-primer-rloc_2x.png"><img src="../images/ot-primer-rloc.png" srcset="../images/ot-primer-rloc.png 1x, ../images/ot-primer-rloc_2x.png 2x" border="0" width="600" alt="OT RLOC" /></a>
+</figure>
+
+可以使用相同的逻辑来确定以上示例拓扑中所有高亮的节点的 RLOC:
+
+<figure>
+<a href="../images/ot-primer-rloc-topology-address_2x.png"><img src="../images/ot-primer-rloc-topology-address.png" srcset="../images/ot-primer-rloc-topology-address.png 1x, ../images/ot-primer-rloc-topology-address_2x.png 2x" border="0" width="600" alt="OT Topology w/ Address" /></a>
+</figure>
+
+但是,因为 RLOC 是基于节点在拓扑中的位置的,所以节点的 RLOC 会随着拓扑的变化而改变。
+
+例如,如果 Thread 网络中的 `0x400` 节点离开了网络,那么它的子节点 `0x401` 和 `0x402` 会与其它的 Router 建立新连接,从而获得新的 RLOC16 和 RLOC:
+
+<figure>
+<a href="../images/ot-primer-rloc-topology-change_2x.png"><img src="../images/ot-primer-rloc-topology-change.png" srcset="../images/ot-primer-rloc-topology-change.png 1x, ../images/ot-primer-rloc-topology-change_2x.png 2x" border="0" width="600" alt="OT Topology after Change" /></a>
+</figure>
+
+## 单播地址类型
+
+RLOC 只是 Thread 设备可以获得的多种 IPv6 单播地址之一。另一类用于在 Thread 网络分区内标识唯一的 Thread 接口的地址称为 EID(Endpoint Identifier)。EID 与 Thread 网络拓扑无关。
+
+常见的单播类型如下。
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Link-Local Address (LLA)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">一种用于标识单次射频传输可访问的 Thread 接口的 EID。</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>fe80::54db:881c:3845:57f4</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td>基于 802.15.4 Extended Address</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Link-Local</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li>用于发现邻居、配置链路和交换路由信息</li><li>非可路由地址</li><li>总是带 <code>fe80::/16</code> Prefix</li></ul></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Mesh-Local EID (ML-EID)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">一种用于标识 Thread 接口的 EID,其与网络拓扑无关。用于访问同一 Thread 分区内的 Thread 接口。也称为 ULA(Unique Local Address)。</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>fde5:8dba:82e1:1:416:993c:8399:35ab</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td>在 commissioning 完成后随机生成</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Mesh-Local</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li>不会随拓扑变化而变化</li><li>应由应用程序使用</li><li>总是带 <code>fd00::/8</code> Prefix</li></ul></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Routing Locator (RLOC)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">根据 Thread 接口在网络拓扑中的位置来对其进行标识。</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>fde5:8dba:82e1:1::ff:fe00:1001</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><code>0000:00ff:fe00:<var>RLOC16</var></code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Mesh-Local</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li>在设备连接到网络后生成</li><li>用于在 Thread 网络中传递 IPv6 数据报</li><li>随拓扑变化而变化</li><li>通常不会由应用程序使用</li></ul></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Anycast Locator (ALOC)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">用于标识 Thread 网络分区中一个或多个 Thread 接口的位置。如果始发者不知道目的地的 RLOC,则使用 ALOC 进行查找。</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>fde5:8dba:82e1:1::ff:fe00:fc01</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><code>0000:00ff:fe00:fc<var>XX</var></code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Mesh-Local</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li><code>fc<var>XX</var></code> = <a href="#anycast">ALOC 目的地址</a>,用于查询对应的 RLOC</li><li>通常不会由应用程序使用</li></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2><h3>Global Unicast Address (GUA)</h3></th>
+    </tr>
+    <tr>
+      <td colspan=2 style="background-color:rgb(238, 241, 242)">一个EID,用于标识除 Thread 网络外的全局范围内的 Thread 接口。</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>2000::54db:881c:3845:57f4</code></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><ul><li>SLAAC — 由设备自身随机分配</li><li>DHCP — 由 DHCPv6 服务器分配</li><li>Manual — 由应用层分配</li></ul></td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Global</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li>一个公开的 IPv6 地址</li><li>总是带 <code>2000::/3</code> Prefix</li></td>
+    </tr>
+  </tbody>
+</table>
+
+## 多播
+
+多播用于一次将信息传达给多个设备。Thread 网络中保留了特定的地址,以提供给不同分组的设备在多播时使用。
+
+| IPv6 地址 | 域         | 传递给          |
+| --------- | ---------- | --------------- |
+| `ff02::1` | Link-Local | 所有 FTD 和 MED |
+| `ff02::2` | Link-Local | 所有 FTD        |
+| `ff03::1` | Mesh-Local | 所有 FTD 和 MED |
+| `ff03::2` | Mesh-Local | 所有 FTD        |
+
+Key Point: FTD 和 MTD 之间的主要区别在于 FTD 订阅了 `ff03::2` 多播地址。而 MTD 没有订阅。
+
+你可能会注意到,上面的多播表中没有将 SED 作为接收者包括在内。Thread 为所有 Thread 节点(包括 SED)定义了(link-local 和 realm-local 域)基于单播 prefix 的 IPv6 多播地址。这些多播地址基于单播 Mesh-Local prefix 构成,因 Thread 网络而异。(有关基于单播 prefix 的 IPv6 多播地址的详情,请参阅 [RFC 3306](https://tools.ietf.org/html/rfc3306))。
+
+Thread 设备还支持除表中所列举域之外的任意域。
+
+## 任播
+
+当目的地的 RLOC 未知时,可以使用任播将流量路由到 Thread 接口。ALOC(Anycast Locator)标识 Thread 分区内多个接口的位置。ALOC 的后 16 位,称为 ALOC16,其格式为 <code>0xfc<var>XX</var></code>,表示 ALOC 的类型。
+
+例如,`0xfc01` 和 `0xfc0f` 之间的 ALOC16 保留给了 DHCPv6 Agent。如果特定的 DHCPv6 Agent RLOC 是未知的(可能是因为网络拓扑已更改),则可以将消息发送到 DHCPv6 Agent ALOC 以获取 RLOC。
+
+Thread 定义了以下 ALOC16 值:
+
+| ALOC16                                     | 类型                     |
+| ------------------------------------------ | ------------------------ |
+| `0xfc00`                                   | Leader                   |
+| `0xfc01` – `0xfc0f`                        | DHCPv6 Agent             |
+| `0xfc10` – `0xfc2f`                        | Service                  |
+| `0xfc30` – `0xfc37`                        | Commissioner             |
+| `0xfc40` – `0xfc4e`                        | Neighbor Discovery Agent |
+| `0xfc38` – `0xfc3f`<br>`0xfc4f` – `0xfcff` | Reserved                 |
+
+## 回顾
+
+你应该学到了:
+
+* Thread 网络包含三个域:Link-Local、Mesh-Local 和 Global
+* Thread 设备具有多种单播 IPv6 地址
+* RLOC 表示设备在 Thread 网络中的位置
+* ML-EID 对于分区内的 Thread 设备是唯一的,并且应由应用程序使用
+* Thread 使用多播将数据转发到节点组和 Router 组
+* 当目的地的 RLOC 未知时,Thread 可以使用任播
+
+要了解有关 Thread 的 IPv6 寻址的更多信息,请参阅 [Thread Specification](http://threadgroup.org/ThreadSpec) 的 5.2 和 5.3 节。
diff --git a/doc/site/zh-cn/guides/thread-primer/network-discovery.md b/doc/site/zh-cn/guides/thread-primer/network-discovery.md
new file mode 100644
index 0000000..479dc9d
--- /dev/null
+++ b/doc/site/zh-cn/guides/thread-primer/network-discovery.md
@@ -0,0 +1,254 @@
+# 网络发现与形成
+
+## Thread 网络
+
+Thread 网络由三个唯一的标识符标识:
+
+* 2 字节的 PAN ID(Personal Area Network ID,个域网标识符)
+* 8 字节的 XPAN ID(Extended Personal Area Network ID,扩展个域网标识符)
+* 方便人类阅读的 Network Name(网络名称)
+
+例如,一个 Thread 网络可能具有以下标识符:
+
+| 标识符       | 值                   |
+| ------------ | -------------------- |
+| PAN ID       | `0xBEEF`             |
+| XPAN ID      | `0xBEEF1111CAFE2222` |
+| Network Name | `yourThreadCafe`     |
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-network-active-scan_2x.png"><img src="../images/ot-primer-network-active-scan.png" srcset="../images/ot-primer-network-active-scan.png 1x, ../images/ot-primer-network-active-scan_2x.png 2x" border="0" alt="OT Active Scan" /></a>
+</figure>
+
+在创建新的 Thread 网络或搜索现有的网络时,Thread 设备会主动扫描射频范围内的 802.15.4 网络:
+
+1. 设备在特定 Channel 上广播 802.15.4 信标请求(Beacon Request)。
+2. 范围内的所有 Router 或 REED 都会广播包含其 Thread 网络 PAN ID、XPAN ID 和 Network Name 的信标(Beacon),以作为回应。
+3. 设备为每个 Channel 重复前两个步骤。
+
+Thread 设备发现范围内的所有网络后,可以选择连接到现有的网络,也可以在未发现任何网络的情况下创建新的网络。
+
+<h2 style="clear:right">Mesh Link Establishment</h2>
+
+Thread 使用 MLE(Mesh Link Establishment)协议来配置链路并将网络的相关信息传播到 Thread 设备。
+
+在链路配置中,MLE 用于:
+
+* 发现相邻设备的链路
+* 确认到相邻设备的链路质量
+* 建立到相邻设备的链路
+* 与对端协商链路参数(设备类型、帧计数器、超时)
+
+MLE 将以下类型的信息传播给希望建立链路的设备:
+
+* Leader data(Leader RLOC, Partition ID(分区标识符), Partition weight(分区权重))
+* Network data(on-mesh prefixes, address autoconfiguration(地址自动配置), more-specific routes(具体路由))
+* Route propagation(路由传播)
+
+Thread 中路由传播的工作原理类似于 RIP(Routing Information Protocol,路由信息协议),RIP 是一种距离矢量路由协议。
+
+Note: 仅当 Thread 设备通过 Thread Commissioning 获得 Thread 网络凭据后,才会继续进行 MLE 过程。Commissioning 和安全性将在本教程的后续部分中深入介绍。目前,假定设备已通过 Commissioning。
+
+## 创建新网络
+
+如果设备选择创建新网络,它将选择最不繁忙的 Channel 和其他网络未使用的 PAN ID,然后成为 Router 并选举自己为 Leader。该设备将 MLE Advertisement 消息发送到其他 802.15.4 设备,以通知其链路状态,并响应其他执行主动扫描的 Thread 设备所发出的信标请求。
+
+## 加入现有网络
+
+如果设备选择加入到现有的网络,则会通过 Thread Commissioning 将其 Channel、PAN ID、XPAN ID 和 Network Name 配置为与目标网络相同,然后进行 MLE Attach 过程以作为子节点(End Device)进行加入。此过程用于“父子链路(Child-Parent link)”。
+
+Key Point: 每个设备(无论是否具有充当 Router 的能力),最初都作为子设备(End Device)连接到 Thread 网络。
+
+1. 子节点向目标网络中的所有相邻的 Router 和 REED 发送多播 [Parent Request](#1-Parent-Request)。
+2. 所有相邻的 Router 和 REED(如果 Parent Request Scan Mask(父节点请求扫描掩码)包括了 REED)都应发送 [Parent Response](#2-Parent-Response) 以将其自身的信息告诉给子节点。
+3. 子节点选择一个父节点,并向其发送 [Child ID Request](#3-Child-ID-Request)。
+4. 父节点发送 [Child ID Response](#4-Child-ID-Response) 以确认链路建立。
+
+### 1. Parent Request
+
+Parent Request 是来自待连接设备的多播请求,用于发现目标网络中的相邻的 Router 和 REED。
+
+<figure>
+<a href="../images/ot-primer-network-mle-attach-01_2x.png"><img src="../images/ot-primer-network-mle-attach-01.png" srcset="../images/ot-primer-network-mle-attach-01.png 1x, ../images/ot-primer-network-mle-attach-01_2x.png 2x" width="350" border="0" alt="OT MLE Attach Parent Request" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Parent Request Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Mode</b></td>
+      <td>描述待连接设备</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
+      <td>测试 Parent Response 的时效性,以防止重放攻击</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scan Mask</b></td>
+      <td>将请求限制为仅 Router 或 Router 和 REED</td>
+    </tr>
+  </tbody>
+</table>
+
+### 2. Parent Response
+
+Parent Response 是对 Parent Request 的单播响应,它向待连接设备提供有关 Router 或 REED 的信息。
+
+<figure>
+<a href="../images/ot-primer-network-mle-attach-02_2x.png"><img src="../images/ot-primer-network-mle-attach-02.png" srcset="../images/ot-primer-network-mle-attach-02.png 1x, ../images/ot-primer-network-mle-attach-02_2x.png 2x" width="350" border="0" alt="OT MLE Attach Parent Response" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Parent Response Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
+      <td>Thread 协议版本</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
+      <td>Parent Request Challenge 的副本</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
+        Counter</b></td>
+      <td>Router/REED 上的 802.15.4 帧计数器</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
+        Counter</b></td>
+      <td>Router/REED 上的 MLE 帧计数器</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
+        Address</b></td>
+      <td>Router/REED 的 RLOC16</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link
+        Margin</b></td>
+      <td>Router/REED 的接收信号质量</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Connectivity</b></td>
+      <td>描述 Router/REED 的连通性</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
+        Data</b></td>
+      <td>有关 Router/REED 的 Leader 的信息</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
+      <td>测试 Child ID Request 的时效性,以防止重放攻击</td>
+    </tr>
+  </tbody>
+</table>
+
+### 3. Child ID Request
+
+Child ID Request 是来自待连接设备(子)的单播请求,该单播请求被发送到 Router(父)或 REED(父),目的是建立父子链路。如果将请求发送到 REED,则 REED 会在接受请求之前将自身升级为 Router。
+
+<figure>
+<a href="../images/ot-primer-network-mle-attach-03_2x.png"><img src="../images/ot-primer-network-mle-attach-03.png" srcset="../images/ot-primer-network-mle-attach-03.png 1x, ../images/ot-primer-network-mle-attach-03_2x.png 2x" width="350" border="0" alt="OT MLE Attach Child ID Request" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Child ID Request Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
+      <td>Thread 协议版本</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
+      <td>Parent Response Challenge 的副本</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
+        Counter</b></td>
+      <td>Child 上的 802.15.4 帧计数器</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
+        Counter</b></td><td>Child 上的 MLE 帧计数器</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Mode</b></td>
+      <td>描述子节点</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Timeout</b></td>
+      <td>父节点移除子节点之前的闲置时间</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address
+        Registration (MEDs and SEDs only)</b></td>
+      <td>注册 IPv6 地址</td>
+    </tr>
+  </tbody>
+</table>
+
+### 4. Child ID Response
+
+Child ID Response 是父节点对 Child ID Request 的单播响应,该响应发送给对应的子节点以确认父子链路的建立。
+
+<figure>
+<a href="../images/ot-primer-network-mle-attach-04_2x.png"><img src="../images/ot-primer-network-mle-attach-04.png" srcset="../images/ot-primer-network-mle-attach-04.png 1x, ../images/ot-primer-network-mle-attach-04_2x.png 2x" width="350" border="0" alt="OT MLE Attach Child ID Response" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Child ID Response Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
+        Address</b></td>
+      <td>父节点的 RLOC16</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address16</b></td>
+      <td>子节点的 RLOC16</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
+        Data</b></td>
+      <td>父节点的 Leader 的相关信息(RLOC, Partition ID, Partition weight)</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Network
+        Data</b></td>
+      <td>Thread 网络的相关信息(on-mesh prefixes, address autoconfiguration, more-specific routes)</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Route
+        (REED only)</b></td>
+      <td>路由传播</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Timeout</b></td>
+      <td>父节点移除子节点之前的闲置时间</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address
+        Registration (MEDs and SEDs only)</b></td>
+      <td>确认已注册地址</td>
+    </tr>
+  </tbody>
+</table>
+
+## 回顾
+
+你应该学到了:
+
+* Thread 设备通过主动扫描发现现有网络
+* Thread 使用 MLE 来配置链路并分发有关网络设备的信息
+* MLE Advertisement 消息通知其他 Thread 设备有关设备的网络和链路状态
+* MLE Attach 过程建立了父子链路
diff --git a/doc/site/zh-cn/guides/thread-primer/node-roles-and-types.md b/doc/site/zh-cn/guides/thread-primer/node-roles-and-types.md
new file mode 100644
index 0000000..e1f07ae
--- /dev/null
+++ b/doc/site/zh-cn/guides/thread-primer/node-roles-and-types.md
@@ -0,0 +1,125 @@
+# 节点角色和类型
+
+## 转发角色
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-roles_2x.png"><img src="../images/ot-primer-roles.png" srcset="../images/ot-primer-roles.png 1x, ../images/ot-primer-roles_2x.png 2x" border="0" alt="OT Node Roles" /></a>
+</figure>
+
+在 Thread 网络中,节点分成两种转发角色:Router 和 End Device。
+
+### Router
+
+Router 节点的行为如下:
+
+* 为网络设备转发数据包
+* 为尝试加入网络的设备提供安全的 commissioning 服务
+* 始终打开它的收发器
+
+### End Device
+
+End Device 节点的行为如下:
+
+* 主要与单个 Router 进行通信
+* 不会为其他网络设备转发数据包
+* 可以关闭它的收发器来降低功耗
+
+Key Point: Router 和 End Device 之间的关系称为父子关系。End Device 正确地依附到一个 Router 上,其中 Router 始终作为父节点,End Device 则始终是子节点。
+
+## 设备类型
+
+此外,节点有许多种类型。
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-taxonomy_2x.png"><img src="../images/ot-primer-taxonomy.png" srcset="../images/ot-primer-taxonomy.png 1x, ../images/ot-primer-taxonomy.png 2x" border="0" alt="OT Device Taxonomy" /></a>
+</figure>
+
+### Full Thread Device
+
+一个 FTD(Full Thread Device)总是打开它的射频收发器,它订阅所有 Router 的多播地址,并维护 IPv6 地址映射。FTD 有三种类型:
+
+* Router
+* REED(Router Eligible End Device)— 可以升级为 Router
+* FED(Full End Device)— 无法升级为 Router
+
+FTD 可以作为 Router(父)或 End Device(子)。
+
+### Minimal Thread Device
+
+MTD(Minimal Thread Device)不会订阅 all-routers 多播地址,并且它会将它的所有消息发送给它的父节点。MTD 有两种类型:
+
+* MED(Minimal End Device)— 始终打开自身的收发器,无需从父节点中轮询消息
+* SED(Sleepy End Device)— 通常会关闭自身的收发器(睡眠),偶然会打开收发器(唤醒)以从父节点中轮询消息
+
+MTD 只能作为 End Device(子)。
+
+### 升级和降级
+
+当待加入设备仅能与某个 REED 通信时, 则该 REED 可以升级成为 Router:
+
+<figure>
+<a href="../images/ot-primer-router-upgrade_2x.png"><img src="../images/ot-primer-router-upgrade.png" srcset="../images/ot-primer-router-upgrade.png 1x, ../images/ot-primer-router-upgrade_2x.png 2x" border="0" width="400" alt="OT End Device to Router" /></a>
+</figure>
+
+相反,当一个 Router 没有子节点时,它可以降级成 End Device:
+
+<figure>
+<a href="../images/ot-primer-router-downgrade_2x.png"><img src="../images/ot-primer-router-downgrade.png" srcset="../images/ot-primer-router-downgrade.png 1x, ../images/ot-primer-router-downgrade_2x.png 2x" border="0" width="400" alt="OT Router to End Device" /></a>
+</figure>
+
+## 其他角色和类型
+
+### Thread Leader
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-leader_2x.png"><img src="../images/ot-primer-leader.png" srcset="../images/ot-primer-leader.png 1x, ../images/ot-primer-leader_2x.png 2x" border="0" alt="OT Leader and Border Router" /></a>
+</figure>
+
+Thread Leader 是一个 Router,它负责管理 Thread 网络中的 Router。Thread Leader 是动态自选的(提高容错率),它负责汇总和分发全网络的配置信息。
+
+Note: 每个 Thread 网络[分区](#分区)中总是只有一个 Leader。
+
+### Border Router
+
+Border Router 是一种可以在 Thread 网络和其他网络(如 Wi-Fi)之间转发信息的设备。它还为外部连接配置 Thread 网络。
+
+任何设备都可以充当 Border Router。
+
+Note: 一个 Thread 网络中可以有多个 Border Router。
+
+## 分区
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-partitions_2x.png"><img src="../images/ot-primer-partitions.png" srcset="../images/ot-primer-partitions.png 1x, ../images/ot-primer-partitions_2x.png 2x" border="0" alt="OT Partitions" /></a>
+</figure>
+
+一个 Thread 网络可能由多个分区组成。当一组 Thread 设备不能再与另一组 Thread 设备通信时,会发生这种情况。每个分区在逻辑上均作为独立的 Thread 网络来运行,它们具有各自的 Leader、Router ID 分配和网络数据,同时分区前相同的安全凭证都将被保留下来。
+
+当分区之间可以连通时,它们会自动合并。
+
+Key Point: 安全凭证(security credentials)定义了 Thread 网络。物理无线电的连通性定义了该 Thread 网络中的分区。
+
+请注意,在本入门教程中一般将 Thread 网络假定成单个分区。在必要时,将使用“分区”一词来阐明关键概念和示例。本教程稍后将详细介绍分区。
+
+## 设备限制
+
+单个 Thread 网络所支持的设备类型数量是有限制的。
+
+| 角色       | 限制               |
+| ---------- | ------------------ |
+| Leader     | 1                  |
+| Router     | 32                 |
+| End Device | 511(每个 Router) |
+
+Thread 会尝试将 Router 的数量保持在 16 ~ 23 之间。如果一个 REED 作为 End Device 加入,并且网络中的 Router 数量低于 16,那么它将自动升级为 Router。
+
+## 回顾
+
+你应该学到了:
+
+* Thread 设备可以是 Router(父)或 End Device(子)
+* Thread 设备可以是 FTD(维护 IPv6 地址映射),也可以是 MTD(将所有消息发送给其父节点)
+* REED 可以升级为 Router,Router 也可以降级为 REED
+* 每个 Thread 网络分区都有一个 Leader 来管理 Router
+* Border Router 用于连接 Thread 和其他网络
+* 一个 Thread 网络可能由多个分区组成
diff --git a/doc/site/zh-cn/guides/thread-primer/router-selection.md b/doc/site/zh-cn/guides/thread-primer/router-selection.md
new file mode 100644
index 0000000..da60f0f
--- /dev/null
+++ b/doc/site/zh-cn/guides/thread-primer/router-selection.md
@@ -0,0 +1,145 @@
+# Router 选择
+
+## Connected Dominating Set
+
+<figure class="attempt-right">
+<a href="../images/ot-primer-cds_2x.png"><img src="../images/ot-primer-cds.png" srcset="../images/ot-primer-cds.png 1x, ../images/ot-primer-cds_2x.png 2x" width="350" border="0" alt="OT Connected Dominating Set" /></a><figcaption style="text-align: center"><i>Example of a Connected Dominating Set</i></figcaption>
+</figure>
+
+Router 必须形成一个 CDS(Connected Dominating Set,连接支配集),这意味着:
+
+1. 在任何两个 Router 之间都有一个 Router-only 的路径。
+2. Thread 网络中的任何一个 Router 都可以通过完全位于 Router 集中而到达其他任何 Router。
+3. Thread 网络中的每个 End Device 都直接连接到 Router。
+
+Thread 使用分布式算法维护 CDS,从而确保最低程度的冗余。每个设备最初都作为 End Device(子)连接到网络。随着 Thread 网络状态的更改,算法会增添或移除 Router 以维护 CDS。
+
+Thread 在下列情况下将会增添 Router:
+
+* 如果网络低于 Router 阈值(16) —— 为了增加覆盖范围
+* 增加路径多样性
+* 保持最低程度的冗余
+* 扩展连接并支持更多子节点
+
+Thread 在下列情况下将会移除 Router:
+
+* 将路由状态减少到最多 32 个 Router 以下
+* 必要时允许在网络的其他部分使用新 Router
+
+## 升级成 Router
+
+子设备连接到 Thread 网络后,可以选择成为 Router。在开始 MLE Link Request 过程之前,子设备会向 Leader 发送 Address Solicit 消息,以请求一个 Router ID。如果 Leader 同意该请求,则它将响应一个 Router ID 给子设备,并且子设备会将自身升级为 Router。
+
+然后,MLE Link Request 过程用于与相邻的 Router 建立双向 Router-Router 链路。
+
+1. 新 Router 将发送一个多播 [Link Request](#1-Link-Request) 到相邻的 Router。
+2. Router 使用 [Link Accept and Request](#2-Link-Accept-and-Request) 消息进行响应。
+3. 新 Router 使用单播的 [Link Accept](#3-Link-Accept) 响应每个 Router,以建立 Router-Router 链路。
+
+### 1. Link Request
+
+Link Request 是从 Router 到 Thread 网络中所有其他 Router 的请求。首次成为 Router 时,设备会发送一个多播 Link Request 到 `ff02::2`。稍后,在通过 MLE Advertisement 发现其他 Router 后,设备将发送单播的 Link Request。
+
+<figure>
+<a href="../images/ot-primer-network-mle-link-request-01_2x.png"><img src="../images/ot-primer-network-mle-link-request-01.png" srcset="../images/ot-primer-network-mle-link-request-01.png 1x, ../images/ot-primer-network-mle-link-request-01_2x.png 2x" width="350" border="0" alt="OT MLE Link Request" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Link Request Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
+      <td>Thread 协议版本</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
+      <td>测试 Link Response 的及时性,以防止重放攻击</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
+        Address</b></td>
+      <td>发送者的 RLOC16</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
+        Data</b></td>
+      <td>Router 的 Leader 的相关信息(RLOC, Partition ID, Partition weight)</td>
+    </tr>
+  </tbody>
+</table>
+
+### 2. Link Accept and Request
+
+Link Accept and Request 是 Link Accept 和 Link Request 消息的组合。Thread 在 MLE Link Request 过程中使用此优化将消息的数量从四减少到三。
+
+<figure>
+<a href="../images/ot-primer-network-mle-link-request-02_2x.png"><img src="../images/ot-primer-network-mle-link-request-02.png" srcset="../images/ot-primer-network-mle-link-request-02.png 1x, ../images/ot-primer-network-mle-link-request-02_2x.png 2x" width="350" border="0" alt="OT MLE Link Accept and Request" /></a>
+</figure>
+
+### 3. Link Accept
+
+Link Accept 是对来自相邻 Router 的 Link Request 的单播响应,该响应提供有关自身的信息并接受到相邻 Router 的链路。
+
+<figure>
+<a href="../images/ot-primer-network-mle-link-request-03_2x.png"><img src="../images/ot-primer-network-mle-link-request-03.png" srcset="../images/ot-primer-network-mle-link-request-03.png 1x, ../images/ot-primer-network-mle-link-request-03_2x.png 2x" width="350" border="0" alt="OT MLE Link Accept" /></a>
+</figure>
+
+<table>
+  <tbody>
+    <tr>
+      <th colspan=2>Link Accept Message Contents</th>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
+      <td>Thread 协议版本</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
+      <td>测试 Link Response 的及时性,以防止重放攻击</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
+        Counter</b></td>
+      <td>发送者上的 802.15.4 帧计数器</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
+        Counter</b></td>
+      <td>发送者上的 MLE 帧计数器</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
+        Address</b></td>
+      <td>发送者的 RLOC16</td>
+    </tr>
+    <tr>
+      <td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
+        Data</b></td>
+      <td>Router 的 Leader 的相关信息(RLOC, Partition ID, Partition weight)</td>
+    </tr>
+  </tbody>
+</table>
+
+## 降级成 REED
+
+当 Router 降级成 REED 时,其 Router-Router 链路断开,并且设备开始 MLE Attach 过程以建立父子链路。
+
+有关 MLE Attach 过程的更多信息,请参阅 [加入现有网络](/guides/thread-primer/network-discovery#加入现有网络)。
+
+## 单向接收链路
+
+在某些情况下,建立单向接收链路是有必要的。
+
+在 Router 重置后,相邻 Router 可能仍具有与重置的 Router 的有效接收链路。在这种情况下,重置的 Router 发送 Link Request 消息以重新建立 Router-Router 链路。
+
+End Device 也可能希望与相邻的 Router(非父节点)建立接收链路,以提高多播可靠性。当我们进入多播路由时,我们将学习更多与此相关的内容。
+
+## 回顾
+
+你应该学到了:
+
+* Thread 网络中的 Router 必须形成 CDS
+* Thread 设备将升级成 Router 或降级成 REED 以维护 CDS
+* MLE Link Request 过程用于建立 Router-Router 链路
diff --git a/etc/cmake/functions.cmake b/etc/cmake/functions.cmake
index 9caf9e8..ffafe48 100755
--- a/etc/cmake/functions.cmake
+++ b/etc/cmake/functions.cmake
@@ -28,7 +28,7 @@
 
 # Get a list of the available platforms and output as a list to the 'arg_platforms' argument
 function(ot_get_platforms arg_platforms)
-    set(result "none")
+    list(APPEND result "NO" "posix")
     set(platforms_dir "${PROJECT_SOURCE_DIR}/examples/platforms")
     file(GLOB platforms RELATIVE "${platforms_dir}" "${platforms_dir}/*")
     foreach(platform IN LISTS platforms)
@@ -37,5 +37,7 @@
         endif()
     endforeach()
 
+    list(REMOVE_ITEM result utils)
+    list(SORT result)
     set(${arg_platforms} "${result}" PARENT_SCOPE)
 endfunction()
diff --git a/etc/cmake/options.cmake b/etc/cmake/options.cmake
index 81b58a3..e9414a9 100644
--- a/etc/cmake/options.cmake
+++ b/etc/cmake/options.cmake
@@ -26,178 +26,239 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-option(OT_BIG_ENDIAN "host platform uses big-endian byte order")
-if(OT_BIG_ENDIAN)
-    list(APPEND OT_PRIVATE_DEFINES "BYTE_ORDER_BIG_ENDIAN=1")
+option(OT_APP_CLI "enable CLI app" ON)
+option(OT_APP_NCP "enable NCP app" ON)
+option(OT_APP_RCP "enable RCP app" ON)
+
+option(OT_BACKBONE_ROUTER "enable backbone router functionality")
+if(OT_BACKBONE_ROUTER)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1")
 endif()
 
 option(OT_BORDER_AGENT "enable border agent support")
 if(OT_BORDER_AGENT)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1")
 endif()
 
 option(OT_BORDER_ROUTER "enable border router support")
 if(OT_BORDER_ROUTER)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1")
 endif()
 
-option(OT_COAP "enable coap api support")
-if(OT_COAP)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_COAP_API_ENABLE=1")
+if(NOT OT_EXTERNAL_MBEDTLS)
+    set(OT_MBEDTLS mbedtls)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS=1")
+else()
+    set(OT_MBEDTLS ${OT_EXTERNAL_MBEDTLS})
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS=0")
 endif()
 
-option(OT_COAPS "enable secure coap api support")
-if(OT_COAPS)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE=1")
-endif()
-
-option(OT_COMMISSIONER "enable commissioner support")
-if(OT_COMMISSIONER)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1")
+option(OT_BUILTIN_MBEDTLS_MANAGEMENT "enable builtin mbedtls management" ON)
+if(OT_BUILTIN_MBEDTLS_MANAGEMENT)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT=1")
+else()
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT=0")
 endif()
 
 option(OT_CHANNEL_MANAGER "enable channel manager support")
 if(OT_CHANNEL_MANAGER)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE=1")
 endif()
 
 option(OT_CHANNEL_MONITOR "enable channel monitor support")
 if(OT_CHANNEL_MONITOR)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE=1")
 endif()
 
 option(OT_CHILD_SUPERVISION "enable child supervision support")
 if(OT_CHILD_SUPERVISION)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1")
+endif()
+
+option(OT_COAP "enable coap api support")
+if(OT_COAP)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_COAP_API_ENABLE=1")
+endif()
+
+option(OT_COAPS "enable secure coap api support")
+if(OT_COAPS)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE=1")
+endif()
+
+option(OT_COAP_OBSERVE "enable coap observe (RFC7641) api support")
+if(OT_COAP_OBSERVE)
+    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE=1")
+endif()
+
+option(OT_COMMISSIONER "enable commissioner support")
+if(OT_COMMISSIONER)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1")
+endif()
+
+option(OT_CSL_RECEIVER "enable csl receiver")
+if(OT_CSL_RECEIVER)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE=1")
 endif()
 
 option(OT_DHCP6_CLIENT "enable DHCP6 client support")
 if(OT_DHCP6_CLIENT)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE=1")
 endif()
 
 option(OT_DHCP6_SERVER "enable DHCP6 server support")
 if(OT_DHCP6_SERVER)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE=1")
 endif()
 
 option(OT_DIAGNOSTIC "enable diagnostic support")
 if(OT_DIAGNOSTIC)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_DIAG_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_DIAG_ENABLE=1")
 endif()
 
 option(OT_DNS_CLIENT "enable DNS client support")
 if(OT_DNS_CLIENT)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1")
 endif()
 
 option(OT_ECDSA "enable ECDSA support")
 if(OT_ECDSA)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_ECDSA_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_ECDSA_ENABLE=1")
+endif()
+
+option(OT_DUA "enable Domain Unicast Address feature for Thread 1.2")
+if(OT_DUA)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_DUA_ENABLE=1")
 endif()
 
 option(OT_EXTERNAL_HEAP "enable external heap support")
 if(OT_EXTERNAL_HEAP)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_EXTERNAL_HEAP_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE=1")
 endif()
 
 option(OT_IP6_FRAGM "enable ipv6 fragmentation support")
 if(OT_IP6_FRAGM)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE=1")
 endif()
 
 option(OT_JAM_DETECTION "enable jam detection support")
 if(OT_JAM_DETECTION)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1")
 endif()
 
 option(OT_JOINER "enable joiner support")
 if(OT_JOINER)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_JOINER_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_JOINER_ENABLE=1")
 endif()
 
 option(OT_LEGACY "enable legacy network support")
 if(OT_LEGACY)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LEGACY_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LEGACY_ENABLE=1")
 endif()
 
 option(OT_LINK_RAW "enable link raw service")
 if(OT_LINK_RAW)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LINK_RAW_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LINK_RAW_ENABLE=1")
+endif()
+
+option(OT_LOG_LEVEL_DYNAMIC "enable dynamic log level control")
+if(OT_LOG_LEVEL_DYNAMIC)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1")
 endif()
 
 option(OT_MAC_FILTER "enable mac filter support")
 if(OT_MAC_FILTER)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1")
+endif()
+
+option(OT_MLE_LONG_ROUTES "enable MLE long routes extension (experimental, breaks Thread conformance)")
+if(OT_MLE_LONG_ROUTES)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE=1")
 endif()
 
 option(OT_MTD_NETDIAG "enable TMF network diagnostics on MTDs")
 if(OT_MTD_NETDIAG)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1")
+endif()
+
+option(OT_MULTIPLE_INSTANCE "enable multiple instances")
+if(OT_MULTIPLE_INSTANCE)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE=1")
+endif()
+
+option(OT_PLATFORM_NETIF "enable platform netif support")
+if(OT_PLATFORM_NETIF)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1")
 endif()
 
 option(OT_PLATFORM_UDP "enable platform UDP support")
 if(OT_PLATFORM_UDP)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1")
 endif()
 
 option(OT_REFERENCE_DEVICE "enable Thread Test Harness reference device support")
 if(OT_REFERENCE_DEVICE)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1")
 endif()
 
 option(OT_SERVICE "enable support for injecting Service entries into the Thread Network Data")
 if(OT_SERVICE)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1")
 endif()
 
 option(OT_SETTINGS_RAM "enable volatile-only storage of settings")
 if(OT_SETTINGS_RAM)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_SETTINGS_RAM=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_SETTINGS_RAM=1")
 endif()
 
 option(OT_SLAAC "enable support for adding of auto-configured SLAAC addresses by OpenThread")
 if(OT_SLAAC)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE=1")
 endif()
 
 option(OT_SNTP_CLIENT "enable SNTP Client support")
 if(OT_SNTP_CLIENT)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1")
 endif()
 
 option(OT_TIME_SYNC "enable the time synchronization service feature")
 if(OT_TIME_SYNC)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1")
 endif()
 
 option(OT_UDP_FORWARD "enable UDP forward support")
 if(OT_UDP_FORWARD)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1")
 endif()
 
 option(OT_FULL_LOGS "enable full logs")
 if(OT_FULL_LOGS)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_DEBG")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_API=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_ARP=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_CLI=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_COAP=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_ICMP=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_IP6=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_MAC=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_MEM=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_MLE=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_NETDATA=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_NETDIAG=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_PKT_DUMP=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_PLATFORM=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL=1")
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_LOG_PREPEND_REGION=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_DEBG")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_API=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_ARP=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_BBR=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_CLI=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_COAP=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_ICMP=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_IP6=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_MAC=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_MEM=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_MESHCOP=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_MLE=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_MLR=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_NETDATA=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_NETDIAG=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_PKT_DUMP=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_PLATFORM=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL=1")
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_LOG_PREPEND_REGION=1")
 endif()
 
-if(OT_BUILTIN_MBEDTLS)
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS=1")
-else()
-    list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS=0")
+option(OT_OTNS "enable OTNS support")
+if(OT_OTNS)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_OTNS_ENABLE=1")
+endif()
+
+# Checks
+if(OT_PLATFORM_UDP AND OT_UDP_FORWARD)
+    message(FATAL_ERROR "OT_PLATFORM_UDP and OT_UDP_FORWARD are exclusive")
 endif()
diff --git a/etc/docker/Makefile b/etc/docker/Makefile
index 1d105a9..5e83df2 100644
--- a/etc/docker/Makefile
+++ b/etc/docker/Makefile
@@ -1,7 +1,7 @@
 
 VERSION=0.1
 
-all: arm32v7_linux x86_linux sim
+all: arm32v7_linux x86_linux simulation
 
 arm32v7_linux: arm32v7_ubuntu_wpantund
 	docker build -t openthread/wpantund_arm32v7_linux arm32v7_ubuntu_wpantund && \
@@ -15,11 +15,11 @@
 	docker tag openthread/wpantund_amd64_linux openthread/wpantund_amd64_linux:$(VERSION) && \
 	docker push openthread/wpantund_amd64_linux:$(VERSION)
 
-sim: ot_sim
-	docker build -t openthread/sim ot_sim && \
-	docker push openthread/sim && \
-	docker tag openthread/sim openthread/sim:$(VERSION) && \
-	docker push openthread/sim:$(VERSION)
+simulation: ot_simulation
+	docker build -t openthread/simulation ot_sim && \
+	docker push openthread/simulation && \
+	docker tag openthread/simulation openthread/simulation:$(VERSION) && \
+	docker push openthread/simulation:$(VERSION)
 
 publish_manifest:
 	docker manifest create openthread/wpantund openthread/wpantund_arm32v7_linux openthread/wpantund_amd64_linux
diff --git a/etc/docker/README.md b/etc/docker/README.md
deleted file mode 100644
index 4dda7d0..0000000
--- a/etc/docker/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-
-## Running wpantund from a Docker container:
-
-For a device that has a Thread radio attached to port `/dev/ttyUSB0`, start `wpantund` as follows:
-
-```
-docker run --rm --detach -e "OPENTHREAD_DEVICE_PORT=/dev/ttyUSB0" --cap-add=NET_ADMIN --device=/dev/ttyUSB0 --name=wpantund openthread/wpantund
-```
-
-Once `wpantund` is running, one can control the Thread interface with `wpanctl` as follows:
-
-```
-docker exec -it wpantund wpanctl
-```
-
-
-## Content
-
-arm32v7_ubuntu_wpantund
-- `wpantund` running on ARMv7 (e.g. Raspberry Pi)
-
-x86_ubuntu_wpantund
-- `wpantund` running on x86
-
-ot_sim
-- OpenThread POSIX simulator
-
-codelab_otsim
-- For use with the [Docker Simulation Codelab](https://codelabs.developers.google.com/codelabs/openthread-simulation/), contains the OpenThread POSIX example and `wpantund` pre-built and ready to use.
-
-environment
-- Development environment with the GNU toolchain and all required OpenThread dependencies installed. OpenThread is not built in this image.
-
-Images built from these Dockerfiles are available to pull from [Docker Hub](https://hub.docker.com/u/openthread/). See [Docker Support on openthread.io](https://openthread.io/guides#docker_support) for more information.
\ No newline at end of file
diff --git a/etc/docker/android-trusty/Dockerfile b/etc/docker/android-trusty/Dockerfile
new file mode 100644
index 0000000..659f97d
--- /dev/null
+++ b/etc/docker/android-trusty/Dockerfile
@@ -0,0 +1,105 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Ubuntu 14.04 with tools required to run OpenThread Android check
+#
+
+FROM ubuntu:14.04
+
+ENV DEBIAN_FRONTEND noninteractive
+ENV ANDROID_JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64
+ENV OPT_BIN=/opt/bin
+ENV PATH=$OPT_BIN:$PATH
+ENV ANDROID_NDK_PATH=/opt/ndk-bundle
+
+WORKDIR /build
+
+RUN apt-get -y update && apt-get --no-install-recommends install -y \
+        gcc-multilib \
+        g++-multilib \
+        git \
+        make \
+        python \
+        unzip \
+        wget
+
+RUN wget https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip \
+        && unzip android-ndk-r17c-linux-x86_64.zip > /dev/null \
+        && mv android-ndk-r17c $ANDROID_NDK_PATH \
+        && rm android-ndk-r17c-linux-x86_64.zip
+
+# Android build system
+RUN mkdir build && cd build && git init && git pull --depth 1 https://android.googlesource.com/platform/build 2db32730e79cafcf13e1f898a7bee7f82b0449d6
+RUN ln -s build/core/main.mk Makefile
+
+RUN mkdir /opt/bin
+
+# Workarounds for java checking
+RUN printf '#!/bin/sh\n\
+echo java version \\"1.6\\"'\
+> $OPT_BIN/java \
+    && printf '#!/bin/sh\n\
+echo javac \\"1.6\\"'\
+> $OPT_BIN/javac \
+    && chmod a+x $OPT_BIN/java $OPT_BIN/javac \
+    && mkdir -p /usr/lib/jvm/java-6-openjdk-amd64/lib/ \
+    && touch /usr/lib/jvm/java-6-openjdk-amd64/lib/tools.jar
+
+# Files for building ndk
+# The default libstdc++.so does not contain full stl implementation, see https://developer.android.com/ndk/guides/cpp-support
+RUN mkdir -p system/core/include/arch/linux-arm \
+    && touch system/core/include/arch/linux-arm/AndroidConfig.h \
+    && mkdir -p system/core/include/arch/linux-x86 \
+    && touch system/core/include/arch/linux-x86/AndroidConfig.h \
+    && mkdir -p bionic/libc/ \
+    && cp -r "$ANDROID_NDK_PATH"/sysroot/usr/include bionic/libc/include \
+    && mv bionic/libc/include/arm-linux-androideabi/asm bionic/libc/include/asm \
+    && mkdir -p out/target/product/generic/obj/ \
+    && cp -r "$ANDROID_NDK_PATH"/platforms/android-27/arch-arm/usr/lib out/target/product/generic/obj/ \
+    && mkdir -p bionic/libstdc++ \
+    && cp -r "$ANDROID_NDK_PATH"/sources/cxx-stl/gnu-libstdc++/4.9/include bionic/libstdc++ \
+    && cp -r "$ANDROID_NDK_PATH"/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include/* bionic/libstdc++/include \
+    && cp "$ANDROID_NDK_PATH"/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_shared.so out/target/product/generic/obj/lib/libstdc++.so \
+    && printf "TARGET_PRODUCT := generic\n\
+TARGET_BUILD_VARIANT := eng\n\
+TARGET_BUILD_TYPE := release\n\
+TARGET_TOOLS_PREFIX := $ANDROID_NDK_PATH/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-"\
+> buildspec.mk
+
+RUN rm -rf "$ANDROID_NDK_PATH"/platforms
+RUN rm -rf "$ANDROID_NDK_PATH"/prebuilt
+RUN rm -rf "$ANDROID_NDK_PATH"/shader-tools
+RUN rm -rf "$ANDROID_NDK_PATH"/sources
+RUN rm -rf "$ANDROID_NDK_PATH"/sysroot
+RUN rm -rf "$ANDROID_NDK_PATH"/simpleperf
+RUN cd "$ANDROID_NDK_PATH"/toolchains && rm -rf aarch64-linux-android-4.9 llvm mips64el-linux-android-4.9 mipsel-linux-android-4.9 x86-4.9 x86_64-4.9
+RUN apt-get purge -y unzip wget git && apt-get -y autoremove && apt-get -y clean && rm -rf /var/lib/apt/lists/*
+
+CMD ["bash"]
+
diff --git a/etc/docker/arm32v7_ubuntu_wpantund/Dockerfile b/etc/docker/arm32v7_ubuntu_wpantund/Dockerfile
deleted file mode 100644
index 75dbaf7..0000000
--- a/etc/docker/arm32v7_ubuntu_wpantund/Dockerfile
+++ /dev/null
@@ -1,50 +0,0 @@
-# Ubuntu image with tools required to build OpenThread
-FROM arm32v7/ubuntu:18.04 as wpantund-dev
-
-LABEL maintainer="Marcin K Szczodrak"
-
-ENV DEBIAN_FRONTEND noninteractive
-RUN apt-get update
-RUN apt-get install -y apt-utils
-RUN apt-get install -y build-essential git make autoconf autoconf-archive \
-    automake dbus libtool gcc g++ libreadline-dev libdbus-1-dev libboost-dev
-
-# wpantund
-RUN mkdir -p ~/src && \
-    cd ~/src && \
-    git clone --recursive https://github.com/openthread/wpantund.git && \
-    cd wpantund && \
-    git checkout full/master && \
-    ./configure --sysconfdir=/etc --enable-shared=no && \
-    make && \
-    make install
-
-#FROM debian:stretch-slim
-FROM arm32v7/ubuntu:18.04
-
-LABEL maintainer="Marcin K Szczodrak"
-
-ENV DEBIAN_FRONTEND noninteractive
-
-RUN apt-get update
-
-RUN apt-get install -y libdbus-1-3 libreadline-dev net-tools
-
-RUN mkdir -p /dev/net && \
-    mknod /dev/net/tun c 10 200 && \
-    chmod 600 /dev/net/tun
-
-COPY --from=wpantund-dev /usr/local/share/man/man1/wpanctl.1 /usr/local/share/man/man1/wpanctl.1
-COPY --from=wpantund-dev /usr/local/share/man/man1/wpantund.1 /usr/local/share/man/man1/wpantund.1
-COPY --from=wpantund-dev /usr/local/share/wpantund /usr/local/share/wpantund
-COPY --from=wpantund-dev /usr/local/include/wpantund /usr/local/include/wpantund
-COPY --from=wpantund-dev /usr/local/bin/wpanctl /usr/local/bin/wpanctl
-COPY --from=wpantund-dev /usr/local/sbin/wpantund /usr/local/sbin/wpantund
-COPY --from=wpantund-dev /etc/dbus-1/system.d/wpantund.conf /etc/dbus-1/system.d/wpantund.conf
-COPY --from=wpantund-dev /etc/wpantund.conf /etc/wpantund.conf
-
-ENTRYPOINT mkdir -p /dev/net && mknod /dev/net/tun c 10 200 && chmod 600 /dev/net/tun && \
-    service dbus start && \
-    start-stop-daemon --start --background --quiet --exe /usr/local/sbin/wpantund -- -s $OPENTHREAD_DEVICE_PORT && \
-    tail -F /dev/null
-
diff --git a/etc/docker/codelab_otsim/Dockerfile b/etc/docker/codelab_otsim/Dockerfile
index 14c01ce..2982314 100644
--- a/etc/docker/codelab_otsim/Dockerfile
+++ b/etc/docker/codelab_otsim/Dockerfile
@@ -6,34 +6,19 @@
 # Install dependencies:
 RUN apt-get update -qq
 
-# Install packages needed for wpantund build and runtime:
-RUN apt-get install -y build-essential git make autoconf \
-                       autoconf-archive automake dbus libtool gcc \
-                       g++ gperf flex bison texinfo ncurses-dev \
-                       libexpat-dev python sed python-pip gawk \
-                       libreadline6-dev libdbus-1-dev \
-                       libboost-dev inetutils-ping
-
-RUN apt-get install -y --force-yes gcc-arm-none-eabi
-RUN pip install pexpect
-
-# Install wpantund:
-RUN mkdir -p ~/src && \
-    cd ~/src && \
-    git clone --recursive https://github.com/openthread/wpantund.git && \
-    cd wpantund && \
-    git checkout full/master && \
-    ./configure --sysconfdir=/etc && \
-    make && make install
-
-RUN mkdir -p /dev/net && mknod /dev/net/tun c 10 200 && chmod 600 /dev/net/tun
-
-# Restart dbus
-RUN service dbus restart
+# Install packages needed for build and runtime:
+RUN apt-get --no-install-recommends install -y git sudo software-properties-common \
+    ca-certificates \
+    && update-ca-certificates
 
 # Install OpenThread
-RUN cd ~/src && \
+RUN mkdir -p ~/src && \
+    cd ~/src && \
     git clone --recursive https://github.com/openthread/openthread.git && \
     cd openthread && \
+    ./script/bootstrap && \
     ./bootstrap && \
-    make -f examples/Makefile-posix
+    make -f examples/Makefile-simulation
+
+# Install OpenThread Daemon and ot-ctl
+RUN cd ~/src/openthread && make -f src/posix/Makefile-posix DAEMON=1
diff --git a/etc/docker/environment/Dockerfile b/etc/docker/environment/Dockerfile
index 7bba2b3..cc6c274 100644
--- a/etc/docker/environment/Dockerfile
+++ b/etc/docker/environment/Dockerfile
@@ -2,26 +2,30 @@
 FROM ubuntu:18.04
 
 ENV DEBIAN_FRONTEND noninteractive
+ENV LANG en_US.UTF-8
 
-RUN apt-get -y update
-RUN apt-get install -y git software-properties-common sudo
-RUN apt-get install -y iproute2 psmisc rsyslog
+RUN set -x \
+    && apt-get update -y \
+    && apt-get install -y locales \
+    && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 \
+    && apt-get --no-install-recommends install -fy \
+        git \
+        ninja-build \
+        python3 \
+        python3-pip \
+        python3-setuptools \
+        software-properties-common \
+        sudo \
+    && python3 -m pip install -U cmake \
+    && python3 -m pip install wheel
 
 # setup openthread
 WORKDIR /
 COPY . openthread
-WORKDIR /openthread
-RUN git reset --hard && git clean -xfd
-RUN ./script/bootstrap
-
-# setup wpantund
-WORKDIR /
-RUN git clone https://github.com/openthread/wpantund.git
-WORKDIR /wpantund
-RUN ./script/bootstrap && ./bootstrap.sh && ./configure && sudo make -j8 && sudo make install
-
-# entrypoint
-WORKDIR /
-COPY etc/docker/environment/docker-entrypoint.sh /
-ENTRYPOINT ["/docker-entrypoint.sh"]
-CMD ["bash"]
+RUN set -x \
+    && cd openthread \
+    && ./script/bootstrap \
+    && mkdir build \
+    && cd build \
+    && cmake -GNinja -DOT_PLATFORM=simulation .. \
+    && ninja
diff --git a/etc/docker/environment/docker-entrypoint.sh b/etc/docker/environment/docker-entrypoint.sh
deleted file mode 100755
index f8b79e6..0000000
--- a/etc/docker/environment/docker-entrypoint.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-#
-#  Copyright (c) 2018, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-#
-#  Description:
-#    This file configures docker environemnt to support wpantund
-#
-
-set -e
-
-mkdir -p /dev/net && mknod /dev/net/tun c 10 200 && chmod 600 /dev/net/tun
-service dbus restart
-service rsyslog start
-
-exec "$@"
diff --git a/etc/docker/ot_sim/Dockerfile b/etc/docker/ot_sim/Dockerfile
deleted file mode 100644
index 4387603..0000000
--- a/etc/docker/ot_sim/Dockerfile
+++ /dev/null
@@ -1,19 +0,0 @@
-FROM alpine:3.6 as openthread-dev
-LABEL maintainer="Marcin K Szczodrak"
-
-RUN apk add -U autoconf automake ca-certificates flex git g++ libtool linux-headers make
-
-# openthread
-RUN git clone --recursive https://github.com/openthread/openthread.git && \
-    cd /openthread && \
-    ./bootstrap && \
-    make -f examples/Makefile-posix
-
-
-FROM alpine:3.6
-LABEL maintainer="Marcin K Szczodrak"
-
-RUN apk add --no-cache libstdc++
-COPY --from=openthread-dev /openthread/output/x86_64-unknown-linux-gnu/bin/ot-cli-ftd /bin/ot-cli-ftd
-COPY --from=openthread-dev /openthread/output/x86_64-unknown-linux-gnu/bin/ot-cli-mtd /bin/ot-cli-mtd
-RUN ln -s /bin/ot-cli-ftd /bin/node
diff --git a/etc/docker/ot_sim/README.md b/etc/docker/ot_sim/README.md
deleted file mode 100644
index 6fb4791..0000000
--- a/etc/docker/ot_sim/README.md
+++ /dev/null
@@ -1,36 +0,0 @@
-
-## Starting simulator
-
-To start the OpenThread simulator, run:
-```
-docker run --rm -d --name otsim openthread/sim tail -F /dev/null
-```
-or
-```
-./start_sim
-```
-This runs in background a docker container with environment setup to simulate OpenThread nodes.
-
-## Adding a Thread node
-
-To start simulating an OpenThread node #1, run:
-```
-docker exec -it otsim node 1
-```
-or
-```
-./add_node 1
-```
-This runs a program called node, which is an OpenThread FTD binary, inside the docker container's simulator environment.
-
-## Stopping simulator
-
-To stop the OpenThread simualtor, run:
-```
-docker stop otsim
-```
-or
-```
-./stop_sim
-```
-This stop the docker daemon process.
diff --git a/etc/docker/ot_sim/add_node b/etc/docker/ot_sim/add_node
deleted file mode 100755
index 2625279..0000000
--- a/etc/docker/ot_sim/add_node
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-docker exec -it otsim node $1
diff --git a/etc/docker/ot_sim/start_sim b/etc/docker/ot_sim/start_sim
deleted file mode 100755
index ad77491..0000000
--- a/etc/docker/ot_sim/start_sim
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-docker run --rm -d --name otsim openthread/sim tail -F /dev/null
diff --git a/etc/docker/ot_sim/stop_sim b/etc/docker/ot_sim/stop_sim
deleted file mode 100755
index 0446362..0000000
--- a/etc/docker/ot_sim/stop_sim
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-docker stop otsim
diff --git a/etc/docker/x86_ubuntu_wpantund/Dockerfile b/etc/docker/x86_ubuntu_wpantund/Dockerfile
deleted file mode 100644
index 8956733..0000000
--- a/etc/docker/x86_ubuntu_wpantund/Dockerfile
+++ /dev/null
@@ -1,50 +0,0 @@
-# Ubuntu image with tools required to build OpenThread
-FROM ubuntu:18.04 as wpantund-dev
-
-LABEL maintainer="Marcin K Szczodrak"
-
-ENV DEBIAN_FRONTEND noninteractive
-RUN apt-get update
-RUN apt-get install -y apt-utils
-RUN apt-get install -y build-essential git make autoconf autoconf-archive \
-    automake dbus libtool gcc g++ libreadline-dev libdbus-1-dev libboost-dev
-
-# wpantund
-RUN mkdir -p ~/src && \
-    cd ~/src && \
-    git clone --recursive https://github.com/openthread/wpantund.git && \
-    cd wpantund && \
-    git checkout full/master && \
-    ./configure --sysconfdir=/etc --enable-shared=no && \
-    make && \
-    make install
-
-#FROM debian:stretch-slim
-FROM ubuntu:18.04
-
-LABEL maintainer="Marcin K Szczodrak"
-
-ENV DEBIAN_FRONTEND noninteractive
-
-RUN apt-get update
-
-RUN apt-get install -y libdbus-1-3 libreadline7 net-tools
-
-RUN mkdir -p /dev/net && \
-    mknod /dev/net/tun c 10 200 && \
-    chmod 600 /dev/net/tun
-
-COPY --from=wpantund-dev /usr/local/share/man/man1/wpanctl.1 /usr/local/share/man/man1/wpanctl.1
-COPY --from=wpantund-dev /usr/local/share/man/man1/wpantund.1 /usr/local/share/man/man1/wpantund.1
-COPY --from=wpantund-dev /usr/local/share/wpantund /usr/local/share/wpantund
-COPY --from=wpantund-dev /usr/local/include/wpantund /usr/local/include/wpantund
-COPY --from=wpantund-dev /usr/local/bin/wpanctl /usr/local/bin/wpanctl
-COPY --from=wpantund-dev /usr/local/sbin/wpantund /usr/local/sbin/wpantund
-COPY --from=wpantund-dev /etc/dbus-1/system.d/wpantund.conf /etc/dbus-1/system.d/wpantund.conf
-COPY --from=wpantund-dev /etc/wpantund.conf /etc/wpantund.conf
-
-ENTRYPOINT mkdir -p /dev/net && mknod /dev/net/tun c 10 200 && chmod 600 /dev/net/tun && \
-    service dbus start && \
-    start-stop-daemon --start --background --quiet --exe /usr/local/sbin/wpantund -- -s $OPENTHREAD_DEVICE_PORT && \
-    tail -F /dev/null
-
diff --git a/examples/Makefile-efr32mg1 b/examples/Makefile-efr32mg1
new file mode 100644
index 0000000..b46ca84
--- /dev/null
+++ b/examples/Makefile-efr32mg1
@@ -0,0 +1,309 @@
+#
+#  Copyright (c) 2017, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+.NOTPARALLEL:
+
+AR                              = arm-none-eabi-ar
+CCAS                            = arm-none-eabi-as
+CPP                             = arm-none-eabi-cpp
+CC                              = arm-none-eabi-gcc
+CXX                             = arm-none-eabi-g++
+LD                              = arm-none-eabi-ld
+STRIP                           = arm-none-eabi-strip
+NM                              = arm-none-eabi-nm
+RANLIB                          = arm-none-eabi-ranlib
+OBJCOPY                         = arm-none-eabi-objcopy
+
+BuildJobs                      ?= 10
+
+configure_OPTIONS               = \
+    --enable-ncp                  \
+    --enable-radio-only           \
+    --enable-linker-map           \
+    --with-examples=efr32mg1      \
+    MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)" \
+    $(NULL)
+
+ifneq ($(DISABLE_BUILTIN_MBEDTLS), 1)
+configure_OPTIONS              += MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)"
+endif
+
+TopSourceDir                    := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
+AbsTopSourceDir                 := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
+
+
+#
+# Differentiate between boards
+#
+ifeq ($(BOARD),BRD4151A)
+MCU = EFR32MG1P232F256GM48
+else
+$(error Please provide a value for BOARD variable e.g BOARD= BRD4151A (currently supported BRD4151A))
+endif
+
+EFR32_MBEDTLS_CPPFLAGS  = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
+EFR32_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"efr32-mbedtls-config.h\"'
+EFR32_MBEDTLS_CPPFLAGS += -D$(MCU)
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32mg1/crypto
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.7/util/third_party/mbedtls/configs
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/CMSIS/Include
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/include
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/Device/SiliconLabs/EFR32MG1P/Include
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/emlib/inc
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/radio/rail_lib/chip/efr32/efr32xg1x
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include
+EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/mbedtls
+
+CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/efr32mg1/
+HAL_CONF_DIR     = $(CONFIG_FILE_PATH)/$(shell echo $(BOARD) | tr A-Z a-z)
+
+EFR32MG1_CONFIG_FILE_CPPFLAGS  = -DOPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-efr32-config.h\"'
+EFR32MG1_CONFIG_FILE_CPPFLAGS += -DOPENTHREAD_CORE_CONFIG_PLATFORM_CHECK_FILE='\"openthread-core-efr32-config-check.h\"'
+EFR32MG1_CONFIG_FILE_CPPFLAGS += -I$(CONFIG_FILE_PATH)
+
+COMMONCFLAGS                       := \
+    -fdata-sections                   \
+    -ffunction-sections               \
+    -Os                               \
+    -g                                \
+    -I$(HAL_CONF_DIR)                 \
+    -D__START=main                    \
+    -D$(MCU)                          \
+    $(EFR32MG1_CONFIG_FILE_CPPFLAGS)  \
+    $(NULL)
+
+include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
+
+#
+# Platform-Specific switches
+#
+
+DMP                            ?= 0
+RADIODEBUG                     ?= 0
+
+ifeq ($(DMP),1)
+COMMONCFLAGS                   += -DRADIO_CONFIG_DMP_SUPPORT=1
+endif
+
+ifeq ($(RADIODEBUG),1)
+COMMONCFLAGS                   += -DRADIO_CONFIG_DEBUG_COUNTERS_SUPPORT=1
+endif
+
+CPPFLAGS                       += \
+    $(COMMONCFLAGS)               \
+    $(target_CPPFLAGS)            \
+    $(NULL)
+
+CFLAGS                         += \
+    $(COMMONCFLAGS)               \
+    $(target_CFLAGS)              \
+    $(NULL)
+
+CXXFLAGS                       += \
+    $(COMMONCFLAGS)               \
+    $(target_CXXFLAGS)            \
+    -fno-exceptions               \
+    -fno-rtti                     \
+    $(NULL)
+
+LDFLAGS                        += \
+    $(COMMONCFLAGS)               \
+    $(target_LDFLAGS)             \
+    -nostartfiles                 \
+    -specs=nano.specs             \
+    -specs=nosys.specs            \
+    -Wl,--gc-sections             \
+    $(NULL)
+
+ECHO                            := @echo
+MAKE                            := make
+MKDIR_P                         := mkdir -p
+LN_S                            := ln -s
+RM_F                            := rm -f
+
+INSTALL                         := /usr/bin/install
+INSTALLFLAGS                    := -p
+
+BuildPath                       = build
+TopBuildDir                     = $(BuildPath)
+AbsTopBuildDir                  = $(PWD)/$(TopBuildDir)
+
+ResultPath                      = output
+TopResultDir                    = $(ResultPath)
+AbsTopResultDir                 = $(PWD)/$(TopResultDir)
+
+TargetTuple                     = efr32mg1
+
+ARCHS                           = cortex-m4
+
+TopTargetLibDir                 = $(TopResultDir)/$(TargetTuple)/lib
+
+ifndef BuildJobs
+BuildJobs := $(shell getconf _NPROCESSORS_ONLN)
+endif
+JOBSFLAG := -j$(BuildJobs)
+
+#
+# configure-arch <arch>
+#
+# Configure OpenThread for the specified architecture.
+#
+#   arch - The architecture to configure.
+#
+define configure-arch
+$(ECHO) "  CONFIG   $(TargetTuple)..."
+(cd $(BuildPath)/$(TargetTuple) && $(AbsTopSourceDir)/configure \
+INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
+CPP="$(CPP)" CC="$(CC)" CXX="$(CXX)" OBJC="$(OBJC)" OBJCXX="$(OBJCXX)" AR="$(AR)" RANLIB="$(RANLIB)" NM="$(NM)" STRIP="$(STRIP)" CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \
+--host=arm-none-eabi \
+--prefix=/ \
+--exec-prefix=/$(TargetTuple) \
+$(configure_OPTIONS))
+endef # configure-arch
+
+#
+# build-arch <arch>
+#
+# Build the OpenThread intermediate build products for the specified
+# architecture.
+#
+#   arch - The architecture to build.
+#
+define build-arch
+$(ECHO) "  BUILD    $(TargetTuple)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(TargetTuple) --no-print-directory \
+all
+endef # build-arch
+
+#
+# stage-arch <arch>
+#
+# Stage (install) the OpenThread final build products for the specified
+# architecture.
+#
+#   arch - The architecture to stage.
+#
+define stage-arch
+$(ECHO) "  STAGE    $(TargetTuple)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(TargetTuple) --no-print-directory \
+DESTDIR=$(AbsTopResultDir) \
+install
+endef # stage-arch
+
+#
+# ARCH_template <arch>
+#
+# Define macros, targets and rules to configure, build, and stage the
+# OpenThread for a single architecture.
+#
+#   arch - The architecture to instantiate the template for.
+#
+define ARCH_template
+CONFIGURE_TARGETS += configure-$(1)
+BUILD_TARGETS     += do-build-$(1)
+STAGE_TARGETS     += stage-$(1)
+BUILD_DIRS        += $(BuildPath)/$(TargetTuple)
+DIRECTORIES       += $(BuildPath)/$(TargetTuple)
+
+configure-$(1): target_CPPFLAGS=$($(1)_target_CPPFLAGS)
+configure-$(1): target_CFLAGS=$($(1)_target_CFLAGS)
+configure-$(1): target_CXXFLAGS=$($(1)_target_CXXFLAGS)
+configure-$(1): target_LDFLAGS=$($(1)_target_LDFLAGS)
+
+configure-$(1): $(BuildPath)/$(TargetTuple)/config.status
+
+$(BuildPath)/$(TargetTuple)/config.status: | $(BuildPath)/$(TargetTuple)
+	$$(call configure-arch,$(1))
+
+do-build-$(1): configure-$(1)
+
+do-build-$(1):
+	+$$(call build-arch,$(1))
+
+stage-$(1): do-build-$(1)
+
+stage-$(1): | $(TopResultDir)
+	$$(call stage-arch,$(1))
+
+$(1): stage-$(1)
+endef # ARCH_template
+
+.DEFAULT_GOAL := all
+
+all: stage
+
+#
+# cortex-m4
+#
+
+cortex-m4_target_ABI                  = cortex-m4
+cortex-m4_target_CPPFLAGS             = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_CFLAGS               = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_CXXFLAGS             = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_LDFLAGS              = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+
+# Instantiate an architecture-specific build template for each target
+# architecture.
+
+$(foreach arch,$(ARCHS),$(eval $(call ARCH_template,$(arch))))
+
+#
+# Common / Finalization
+#
+
+configure: $(CONFIGURE_TARGETS)
+
+build: $(BUILD_TARGETS)
+
+stage: $(STAGE_TARGETS)
+
+DIRECTORIES     = $(TopResultDir) $(TopResultDir)/$(TargetTuple)/lib $(BUILD_DIRS)
+
+CLEAN_DIRS      = $(TopResultDir) $(BUILD_DIRS)
+
+all: stage
+
+$(DIRECTORIES):
+	$(ECHO) "  MKDIR    $@"
+	@$(MKDIR_P) "$@"
+
+clean:
+	$(ECHO) "  CLEAN"
+	@$(RM_F) -r $(CLEAN_DIRS)
+
+help:
+	$(ECHO) "Simply type 'make -f $(firstword $(MAKEFILE_LIST))' to build OpenThread for the following "
+	$(ECHO) "architectures: "
+	$(ECHO) ""
+	$(ECHO) "    $(ARCHS)"
+	$(ECHO) ""
+	$(ECHO) "To build only a particular architecture, specify: "
+	$(ECHO) ""
+	$(ECHO) "    make -f $(firstword $(MAKEFILE_LIST)) <architecture>"
+	$(ECHO) ""
diff --git a/examples/Makefile-efr32mg13 b/examples/Makefile-efr32mg13
index bd2d951..e1ef707 100644
--- a/examples/Makefile-efr32mg13
+++ b/examples/Makefile-efr32mg13
@@ -70,7 +70,6 @@
 $(error Please provide a value for BOARD variable e.g BOARD=BRD4168A (currently supported BRD4168A))
 endif
 
-
 EFR32_MBEDTLS_CPPFLAGS  = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
 EFR32_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"efr32-mbedtls-config.h\"'
 EFR32_MBEDTLS_CPPFLAGS += -D$(MCU)
diff --git a/examples/Makefile-efr32mg21 b/examples/Makefile-efr32mg21
index 20d23ee..9143283 100644
--- a/examples/Makefile-efr32mg21
+++ b/examples/Makefile-efr32mg21
@@ -84,6 +84,8 @@
 EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls
 EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include
 EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/mbedtls
+EFR32_MBEDTLS_CPPFLAGS += -Wno-unused-function
+EFR32_MBEDTLS_CPPFLAGS += -Wno-unused-parameter
 
 CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/efr32mg21/
 HAL_CONF_DIR     = $(CONFIG_FILE_PATH)/$(shell echo $(BOARD) | tr A-Z a-z)
diff --git a/examples/Makefile-gp712 b/examples/Makefile-gp712
index f111e5a..ad08880 100644
--- a/examples/Makefile-gp712
+++ b/examples/Makefile-gp712
@@ -81,6 +81,8 @@
 
 CFLAGS                         += \
     $(COMMONCFLAGS)               \
+    -D_BSD_SOURCE=1               \
+    -D_DEFAULT_SOURCE=1           \
     $(target_CFLAGS)              \
     $(NULL)
 
diff --git a/examples/Makefile-jn5189 b/examples/Makefile-jn5189
new file mode 100755
index 0000000..6cc5b67
--- /dev/null
+++ b/examples/Makefile-jn5189
@@ -0,0 +1,295 @@
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+.NOTPARALLEL:
+
+AR                              = arm-none-eabi-ar
+CCAS                            = arm-none-eabi-as
+CPP                             = arm-none-eabi-cpp
+CC                              = arm-none-eabi-gcc
+CXX                             = arm-none-eabi-g++
+LD                              = arm-none-eabi-ld
+STRIP                           = arm-none-eabi-strip
+NM                              = arm-none-eabi-nm
+RANLIB                          = arm-none-eabi-ranlib
+OBJCOPY                         = arm-none-eabi-objcopy
+
+BuildJobs                      ?= 10
+
+configure_OPTIONS               = \
+    --enable-cli                  \
+    --enable-ftd                  \
+    --enable-mtd                  \
+    --enable-ncp                  \
+    --with-ncp-bus=uart           \
+    --enable-radio-only           \
+    --enable-linker-map           \
+    --with-examples=jn5189        \
+    $(NULL)
+
+ifneq ($(DISABLE_BUILTIN_MBEDTLS), 1)
+configure_OPTIONS              += MBEDTLS_CPPFLAGS="$(JN5189_MBEDTLS_CPPFLAGS)"
+endif
+
+JN5189_MBEDTLS_CPPFLAGS  = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
+JN5189_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"jn5189-mbedtls-config.h\"'
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/include/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/devices/JN5189
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/devices/JN5189/drivers/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/devices/JN5189/utilities/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug-console/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/drivers/components/serial_manager/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/drivers/components/uart/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/JN5189DK6/CMSIS/Include/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/
+JN5189_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/mbedtls/
+
+TopSourceDir                    := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
+AbsTopSourceDir                 := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
+
+CONFIG_FILE      = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-jn5189-config.h\"'
+CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/k32w/jn5189/
+SIGN_IMAGE_PATH = $(AbsTopSourceDir)/third_party/nxp/JN5189DK6/tools/imagetool/
+
+COMMONCFLAGS                          := \
+    -fdata-sections                      \
+    -ffunction-sections                  \
+    -Os                                  \
+    -g                                   \
+    -DCPU_JN518X                         \
+    -DCPU_JN518X_REV=2                   \
+    -DJENNIC_CHIP_FAMILY_JN518x          \
+    -DJENNIC_CHIP_FAMILY_NAME=_JN518x    \
+    -DSDK_DEBUGCONSOLE=0                 \
+    -D$(CONFIG_FILE)                     \
+    -DUSE_RTOS=0                         \
+    -I$(CONFIG_FILE_PATH)                \
+    $(NULL)
+
+include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
+
+CPPFLAGS                       += \
+    $(COMMONCFLAGS)               \
+    $(target_CPPFLAGS)            \
+    $(NULL)
+
+CFLAGS                         += \
+    $(COMMONCFLAGS)               \
+    $(target_CFLAGS)              \
+    $(NULL)
+
+CXXFLAGS                       += \
+    $(COMMONCFLAGS)               \
+    $(target_CXXFLAGS)            \
+    -fno-exceptions               \
+    -fno-rtti                     \
+    $(NULL)
+
+LDFLAGS                        += \
+    $(COMMONCFLAGS)               \
+    $(target_LDFLAGS)             \
+    -specs=nano.specs             \
+    -specs=nosys.specs            \
+    -Wl,--gc-sections             \
+    $(NULL)
+
+ECHO                            := @echo
+MAKE                            := make
+MKDIR_P                         := mkdir -p
+LN_S                            := ln -s
+RM_F                            := rm -f
+
+INSTALL                         := /usr/bin/install
+INSTALLFLAGS                    := -p
+
+BuildPath                       = build
+TopBuildDir                     = $(BuildPath)
+AbsTopBuildDir                  = $(PWD)/$(TopBuildDir)
+
+ResultPath                      = output
+TopResultDir                    = $(ResultPath)
+AbsTopResultDir                 = $(PWD)/$(TopResultDir)
+
+TargetTuple                     = jn5189
+
+ARCHS                           = cortex-m4
+
+TopTargetLibDir                 = $(TopResultDir)/$(TargetTuple)/lib
+TopTargetBinDir                 = $(TopResultDir)/$(TargetTuple)/bin
+
+ifndef BuildJobs
+BuildJobs := $(shell getconf _NPROCESSORS_ONLN)
+endif
+JOBSFLAG := -j$(BuildJobs)
+
+#
+# configure-arch <arch>
+#
+# Configure OpenThread for the specified architecture.
+#
+#   arch - The architecture to configure.
+#
+define configure-arch
+$(ECHO) "  CONFIG   $(TargetTuple)..."
+(cd $(BuildPath)/$(TargetTuple) && $(AbsTopSourceDir)/configure \
+INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
+CPP="$(CPP)" CC="$(CC)" CXX="$(CXX)" OBJC="$(OBJC)" OBJCXX="$(OBJCXX)" AR="$(AR)" RANLIB="$(RANLIB)" NM="$(NM)" STRIP="$(STRIP)" CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \
+--host=arm-none-eabi \
+--prefix=/ \
+--exec-prefix=/$(TargetTuple) \
+$(configure_OPTIONS))
+endef # configure-arch
+
+#
+# build-arch <arch>
+#
+# Build the OpenThread intermediate build products for the specified
+# architecture.
+#
+#   arch - The architecture to build.
+#
+define build-arch
+$(ECHO) "  BUILD    $(TargetTuple)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(TargetTuple) --no-print-directory \
+all
+endef # build-arch
+
+#
+# stage-arch <arch>
+#
+# Stage (install) the OpenThread final build products for the specified
+# architecture.
+#
+#   arch - The architecture to stage.
+#
+define stage-arch
+$(ECHO) "  STAGE    $(TargetTuple)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(TargetTuple) --no-print-directory \
+DESTDIR=$(AbsTopResultDir) \
+install
+endef # stage-arch
+
+#
+# ARCH_template <arch>
+#
+# Define macros, targets and rules to configure, build, and stage the
+# OpenThread for a single architecture.
+#
+#   arch - The architecture to instantiate the template for.
+#
+define ARCH_template
+CONFIGURE_TARGETS += configure-$(1)
+BUILD_TARGETS     += do-build-$(1)
+STAGE_TARGETS     += stage-$(1)
+BUILD_DIRS        += $(BuildPath)/$(TargetTuple)
+DIRECTORIES       += $(BuildPath)/$(TargetTuple)
+
+configure-$(1): target_CPPFLAGS=$($(1)_target_CPPFLAGS)
+configure-$(1): target_CFLAGS=$($(1)_target_CFLAGS)
+configure-$(1): target_CXXFLAGS=$($(1)_target_CXXFLAGS)
+configure-$(1): target_LDFLAGS=$($(1)_target_LDFLAGS)
+
+configure-$(1): $(BuildPath)/$(TargetTuple)/config.status
+
+$(BuildPath)/$(TargetTuple)/config.status: | $(BuildPath)/$(TargetTuple)
+	$$(call configure-arch,$(1))
+
+do-build-$(1): configure-$(1)
+
+do-build-$(1):
+	+$$(call build-arch,$(1))
+
+stage-$(1): do-build-$(1)
+
+stage-$(1): | $(TopResultDir)
+	$$(call stage-arch,$(1))
+
+$(1): stage-$(1)
+endef # ARCH_template
+
+.DEFAULT_GOAL := all
+
+all: stage
+
+#
+# cortex-m4
+#
+
+cortex-m4_target_ABI                  = cortex-m4
+cortex-m4_target_CPPFLAGS             = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_CFLAGS               = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_CXXFLAGS             = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_LDFLAGS              = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+
+# Instantiate an architecture-specific build template for each target
+# architecture.
+
+$(foreach arch,$(ARCHS),$(eval $(call ARCH_template,$(arch))))
+
+#
+# Common / Finalization
+#
+
+configure: $(CONFIGURE_TARGETS)
+
+build: $(BUILD_TARGETS)
+
+stage: $(STAGE_TARGETS)
+
+DIRECTORIES     = $(TopResultDir) $(TopResultDir)/$(TargetTuple)/lib $(BUILD_DIRS)
+
+CLEAN_DIRS      = $(TopResultDir) $(BUILD_DIRS)
+
+all: stage post-build-step
+
+$(DIRECTORIES):
+	$(ECHO) "  MKDIR    $@"
+	@$(MKDIR_P) "$@"
+
+post-build-step:
+	$(SIGN_IMAGE_PATH)/sign_images.sh $(TopTargetBinDir)
+
+clean:
+	$(ECHO) "  CLEAN"
+	@$(RM_F) -r $(CLEAN_DIRS)
+
+help:
+	$(ECHO) "Simply type 'make -f $(firstword $(MAKEFILE_LIST))' to build OpenThread for the following "
+	$(ECHO) "architectures: "
+	$(ECHO) ""
+	$(ECHO) "    $(ARCHS)"
+	$(ECHO) ""
+	$(ECHO) "To build only a particular architecture, specify: "
+	$(ECHO) ""
+	$(ECHO) "    make -f $(firstword $(MAKEFILE_LIST)) <architecture>"
+	$(ECHO) ""
diff --git a/examples/Makefile-k32w061 b/examples/Makefile-k32w061
new file mode 100755
index 0000000..3c39573
--- /dev/null
+++ b/examples/Makefile-k32w061
@@ -0,0 +1,298 @@
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+.NOTPARALLEL:
+
+AR                              = arm-none-eabi-ar
+CCAS                            = arm-none-eabi-as
+CPP                             = arm-none-eabi-cpp
+CC                              = arm-none-eabi-gcc
+CXX                             = arm-none-eabi-g++
+LD                              = arm-none-eabi-ld
+STRIP                           = arm-none-eabi-strip
+NM                              = arm-none-eabi-nm
+RANLIB                          = arm-none-eabi-ranlib
+OBJCOPY                         = arm-none-eabi-objcopy
+
+BuildJobs                      ?= 10
+
+configure_OPTIONS               = \
+    --enable-cli                  \
+    --enable-diag                 \
+    --enable-ftd                  \
+    --enable-mtd                  \
+    --enable-ncp                  \
+    --with-ncp-bus=uart           \
+    --enable-radio-only           \
+    --enable-linker-map           \
+    --with-examples=k32w061       \
+    $(NULL)
+
+ifneq ($(DISABLE_BUILTIN_MBEDTLS), 1)
+configure_OPTIONS              += MBEDTLS_CPPFLAGS="$(K32W061_MBEDTLS_CPPFLAGS)"
+endif
+
+K32W061_MBEDTLS_CPPFLAGS  = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
+K32W061_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"k32w061-mbedtls-config.h\"'
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/include/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/devices/K32W061
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/devices/K32W061/drivers/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/devices/K32W061/utilities/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug-console/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/drivers/components/serial_manager/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/drivers/components/uart/
+
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/nxp/K32W061DK6/CMSIS/Include/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/
+K32W061_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/mbedtls/
+
+TopSourceDir                    := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
+AbsTopSourceDir                 := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
+
+CONFIG_FILE      = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-k32w061-config.h\"'
+CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/k32w/k32w061/
+SIGN_IMAGE_PATH = $(AbsTopSourceDir)/third_party/nxp/K32W061DK6/tools/imagetool/
+
+COMMONCFLAGS                          := \
+    -fdata-sections                      \
+    -ffunction-sections                  \
+    -Os                                  \
+    -g                                   \
+    -DCPU_K32W061HN                      \
+    -DCPU_JN518X                         \
+    -DCPU_JN518X_REV=2                   \
+    -DJENNIC_CHIP_FAMILY_JN518x          \
+    -DJENNIC_CHIP_FAMILY_NAME=_JN518x    \
+    -DSDK_DEBUGCONSOLE=0                 \
+    -D$(CONFIG_FILE)                     \
+    -DUSE_RTOS=0                         \
+    -I$(CONFIG_FILE_PATH)                \
+    $(NULL)
+
+include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
+
+CPPFLAGS                       += \
+    $(COMMONCFLAGS)               \
+    $(target_CPPFLAGS)            \
+    $(NULL)
+
+CFLAGS                         += \
+    $(COMMONCFLAGS)               \
+    $(target_CFLAGS)              \
+    $(NULL)
+
+CXXFLAGS                       += \
+    $(COMMONCFLAGS)               \
+    $(target_CXXFLAGS)            \
+    -fno-exceptions               \
+    -fno-rtti                     \
+    $(NULL)
+
+LDFLAGS                        += \
+    $(COMMONCFLAGS)               \
+    $(target_LDFLAGS)             \
+    -specs=nano.specs             \
+    -specs=nosys.specs            \
+    -Wl,--gc-sections             \
+    $(NULL)
+
+ECHO                            := @echo
+MAKE                            := make
+MKDIR_P                         := mkdir -p
+LN_S                            := ln -s
+RM_F                            := rm -f
+
+INSTALL                         := /usr/bin/install
+INSTALLFLAGS                    := -p
+
+BuildPath                       = build
+TopBuildDir                     = $(BuildPath)
+AbsTopBuildDir                  = $(PWD)/$(TopBuildDir)
+
+ResultPath                      = output
+TopResultDir                    = $(ResultPath)
+AbsTopResultDir                 = $(PWD)/$(TopResultDir)
+
+TargetTuple                     = k32w061
+
+ARCHS                           = cortex-m4
+
+TopTargetLibDir                 = $(TopResultDir)/$(TargetTuple)/lib
+TopTargetBinDir                 = $(TopResultDir)/$(TargetTuple)/bin
+
+ifndef BuildJobs
+BuildJobs := $(shell getconf _NPROCESSORS_ONLN)
+endif
+JOBSFLAG := -j$(BuildJobs)
+
+#
+# configure-arch <arch>
+#
+# Configure OpenThread for the specified architecture.
+#
+#   arch - The architecture to configure.
+#
+define configure-arch
+$(ECHO) "  CONFIG   $(TargetTuple)..."
+(cd $(BuildPath)/$(TargetTuple) && $(AbsTopSourceDir)/configure \
+INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
+CPP="$(CPP)" CC="$(CC)" CXX="$(CXX)" OBJC="$(OBJC)" OBJCXX="$(OBJCXX)" AR="$(AR)" RANLIB="$(RANLIB)" NM="$(NM)" STRIP="$(STRIP)" CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \
+--host=arm-none-eabi \
+--prefix=/ \
+--exec-prefix=/$(TargetTuple) \
+$(configure_OPTIONS))
+endef # configure-arch
+
+#
+# build-arch <arch>
+#
+# Build the OpenThread intermediate build products for the specified
+# architecture.
+#
+#   arch - The architecture to build.
+#
+define build-arch
+$(ECHO) "  BUILD    $(TargetTuple)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(TargetTuple) --no-print-directory \
+all
+endef # build-arch
+
+#
+# stage-arch <arch>
+#
+# Stage (install) the OpenThread final build products for the specified
+# architecture.
+#
+#   arch - The architecture to stage.
+#
+define stage-arch
+$(ECHO) "  STAGE    $(TargetTuple)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(TargetTuple) --no-print-directory \
+DESTDIR=$(AbsTopResultDir) \
+install
+endef # stage-arch
+
+#
+# ARCH_template <arch>
+#
+# Define macros, targets and rules to configure, build, and stage the
+# OpenThread for a single architecture.
+#
+#   arch - The architecture to instantiate the template for.
+#
+define ARCH_template
+CONFIGURE_TARGETS += configure-$(1)
+BUILD_TARGETS     += do-build-$(1)
+STAGE_TARGETS     += stage-$(1)
+BUILD_DIRS        += $(BuildPath)/$(TargetTuple)
+DIRECTORIES       += $(BuildPath)/$(TargetTuple)
+
+configure-$(1): target_CPPFLAGS=$($(1)_target_CPPFLAGS)
+configure-$(1): target_CFLAGS=$($(1)_target_CFLAGS)
+configure-$(1): target_CXXFLAGS=$($(1)_target_CXXFLAGS)
+configure-$(1): target_LDFLAGS=$($(1)_target_LDFLAGS)
+
+configure-$(1): $(BuildPath)/$(TargetTuple)/config.status
+
+$(BuildPath)/$(TargetTuple)/config.status: | $(BuildPath)/$(TargetTuple)
+	$$(call configure-arch,$(1))
+
+do-build-$(1): configure-$(1)
+
+do-build-$(1):
+	+$$(call build-arch,$(1))
+
+stage-$(1): do-build-$(1)
+
+stage-$(1): | $(TopResultDir)
+	$$(call stage-arch,$(1))
+
+$(1): stage-$(1)
+endef # ARCH_template
+
+.DEFAULT_GOAL := all
+
+all: stage
+
+#
+# cortex-m4
+#
+
+cortex-m4_target_ABI                  = cortex-m4
+cortex-m4_target_CPPFLAGS             = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_CFLAGS               = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_CXXFLAGS             = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+cortex-m4_target_LDFLAGS              = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
+
+# Instantiate an architecture-specific build template for each target
+# architecture.
+
+$(foreach arch,$(ARCHS),$(eval $(call ARCH_template,$(arch))))
+
+#
+# Common / Finalization
+#
+
+configure: $(CONFIGURE_TARGETS)
+
+build: $(BUILD_TARGETS)
+
+stage: $(STAGE_TARGETS)
+
+DIRECTORIES     = $(TopResultDir) $(TopResultDir)/$(TargetTuple)/lib $(BUILD_DIRS)
+
+CLEAN_DIRS      = $(TopResultDir) $(BUILD_DIRS)
+
+all: stage post-build-step
+
+$(DIRECTORIES):
+	$(ECHO) "  MKDIR    $@"
+	@$(MKDIR_P) "$@"
+
+post-build-step:
+	$(SIGN_IMAGE_PATH)/sign_images.sh $(TopTargetBinDir)
+
+clean:
+	$(ECHO) "  CLEAN"
+	@$(RM_F) -r $(CLEAN_DIRS)
+
+help:
+	$(ECHO) "Simply type 'make -f $(firstword $(MAKEFILE_LIST))' to build OpenThread for the following "
+	$(ECHO) "architectures: "
+	$(ECHO) ""
+	$(ECHO) "    $(ARCHS)"
+	$(ECHO) ""
+	$(ECHO) "To build only a particular architecture, specify: "
+	$(ECHO) ""
+	$(ECHO) "    make -f $(firstword $(MAKEFILE_LIST)) <architecture>"
+	$(ECHO) ""
diff --git a/examples/Makefile-nrf52811 b/examples/Makefile-nrf52811
index 63e8920..317bd9c 100644
--- a/examples/Makefile-nrf52811
+++ b/examples/Makefile-nrf52811
@@ -60,7 +60,6 @@
 NRF52811_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls
 NRF52811_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include
 NRF52811_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/mbedtls
-NRF52811_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/NordicSemiconductor/libraries/crypto
 NRF52811_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config
 NRF52811_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/NordicSemiconductor/nrfx/mdk
 NRF52811_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/NordicSemiconductor/cmsis
diff --git a/examples/Makefile-nrf52833 b/examples/Makefile-nrf52833
index b13286c..5f6ad35 100644
--- a/examples/Makefile-nrf52833
+++ b/examples/Makefile-nrf52833
@@ -61,7 +61,6 @@
 NRF52833_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls
 NRF52833_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include
 NRF52833_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/mbedtls
-NRF52833_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/NordicSemiconductor/libraries/crypto
 NRF52833_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config
 NRF52833_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/NordicSemiconductor/nrfx/mdk
 NRF52833_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/NordicSemiconductor/cmsis
diff --git a/examples/Makefile-posix b/examples/Makefile-posix
deleted file mode 100644
index 85b32ca..0000000
--- a/examples/Makefile-posix
+++ /dev/null
@@ -1,332 +0,0 @@
-#
-#  Copyright (c) 2016, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-# Don't allow this top-level makefile's targets to be built in parallel.
-
-.NOTPARALLEL:
-
-COVERAGE                       ?= 0
-DEBUG                          ?= 0
-
-# Enable most features by default to cover most code
-
-BORDER_AGENT                   ?= 1
-BORDER_ROUTER                  ?= 1
-COAP                           ?= 1
-COAPS                          ?= 1
-COMMISSIONER                   ?= 1
-CHANNEL_MANAGER                ?= 1
-CHANNEL_MONITOR                ?= 1
-CHILD_SUPERVISION              ?= 1
-DHCP6_CLIENT                   ?= 1
-DHCP6_SERVER                   ?= 1
-DIAGNOSTIC                     ?= 1
-DNS_CLIENT                     ?= 1
-ECDSA                          ?= 1
-IP6_FRAGM                      ?= 1
-JAM_DETECTION                  ?= 1
-JOINER                         ?= 1
-LEGACY                         ?= 1
-LINK_RAW                       ?= 1
-MAC_FILTER                     ?= 1
-MTD_NETDIAG                    ?= 1
-REFERENCE_DEVICE               ?= 1
-SERVICE                        ?= 1
-SNTP_CLIENT                    ?= 1
-UDP_FORWARD                    ?= 1
-
-COMMONCFLAGS                   := \
-    -g                            \
-    $(NULL)
-
-# If the user has asserted COVERAGE, alter the configuration options
-# accordingly.
-
-configure_OPTIONS               = \
-    --enable-cli                  \
-    --enable-ftd                  \
-    --enable-mtd                  \
-    --enable-ncp                  \
-    --enable-radio-only           \
-    --with-examples=posix         \
-    $(NULL)
-
-# Platform specific switches
-
-ifneq ($(DEBUG),1)
-COMMONCFLAGS                   += \
-    -O2                           \
-    $(NULL)
-endif
-
-ifeq ($(NCP_SPI),1)
-COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1
-else
-COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1
-endif # NCP_SPI == 1
-
-ifeq ($(VIRTUAL_TIME),1)
-COMMONCFLAGS                   += -DOPENTHREAD_POSIX_VIRTUAL_TIME=1
-endif
-
-ifeq ($(VIRTUAL_TIME_UART),1)
-COMMONCFLAGS                   += -DOPENTHREAD_POSIX_VIRTUAL_TIME_UART=1
-endif
-
-include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
-
-TopSourceDir                   := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
-AbsTopSourceDir                := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
-
-CONFIG_FILE      = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-posix-config.h\"'
-CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/posix/
-COMMONCFLAGS                   += \
-    -D$(CONFIG_FILE)              \
-    -I$(CONFIG_FILE_PATH)         \
-
-CPPFLAGS                       += \
-    $(COMMONCFLAGS)               \
-    $(NULL)
-
-CFLAGS                         += \
-    $(COMMONCFLAGS)               \
-    $(NULL)
-
-CXXFLAGS                       += \
-    $(COMMONCFLAGS)               \
-    $(NULL)
-
-LDFLAGS                        += \
-    $(COMMONCFLAGS)               \
-    $(NULL)
-
-ECHO                           := @echo
-INSTALL                        := /usr/bin/install
-INSTALLFLAGS                   := -p
-LN_S                           := ln -s
-MAKE                           := make
-MKDIR_P                        := mkdir -p
-RM_F                           := rm -f
-
-BuildJobs                      ?= 10
-BuildPath                       = build
-TopBuildDir                     = $(BuildPath)
-AbsTopBuildDir                  = $(PWD)/$(TopBuildDir)
-
-ResultPath                      = output
-TopResultDir                    = $(ResultPath)
-AbsTopResultDir                 = $(PWD)/$(TopResultDir)
-
-TargetTuple                     = $(shell ${AbsTopSourceDir}/third_party/nlbuild-autotools/repo/third_party/autoconf/config.guess | sed -e 's/[[:digit:].]*$$//g')
-
-ifndef BuildJobs
-BuildJobs := $(shell getconf _NPROCESSORS_ONLN)
-endif
-JOBSFLAG := -j$(BuildJobs)
-
-#
-# configure-arch <target>
-#
-# Configure OpenThread for the specified target.
-#
-#   target - The target to configure.
-#
-define configure-target
-$(ECHO) "  CONFIG   $(1)..."
-(cd $(BuildPath)/$(1) && $(AbsTopSourceDir)/configure \
-INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
-CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \
---prefix=/ \
---exec-prefix=/$(1) \
-$(configure_OPTIONS))
-endef # configure-target
-
-#
-# build-target <target>
-#
-# Build the OpenThread intermediate build products for the specified
-# target.
-#
-#   target - The target to build.
-#
-define build-target
-$(ECHO) "  BUILD    $(1)"
-$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
-all
-endef # build-target
-
-#
-# check-target <target>
-#
-# Check (run unit tests) OpenThread for the specified target.
-#
-#   target - The target to check.
-#
-define check-target
-$(ECHO) "  CHECK    $(1)"
-$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
-check
-endef # check-target
-
-#
-# distcheck-target <target>
-#
-# Check (run unit tests) OpenThread for the specified target.
-#
-#   target - The target to distcheck.
-#
-define distcheck-target
-$(ECHO) "  DISTCHECK    $(1)"
-$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
-distcheck
-endef # distcheck-target
-
-#
-# coverage-target <target>
-#
-# Generate code coverage from unit tests for OpenThread for the
-# specified target.
-#
-#   target - The target to generate code coverage for.
-#
-define coverage-target
-$(ECHO) "  COVERAGE $(1)"
-$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
-coverage
-endef # coverage-target
-
-#
-# stage-target <target>
-#
-# Stage (install) the OpenThread final build products for the specified
-# target.
-#
-#   target - The target to stage.
-#
-define stage-target
-$(ECHO) "  STAGE    $(1)"
-$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
-DESTDIR=$(AbsTopResultDir) \
-install
-endef # stage-target
-
-#
-# TARGET_template <target>
-#
-# Define macros, targets and rules to configure, build, and stage
-# OpenThread for a single target.
-#
-#   target - The target to instantiate the template for.
-#
-define TARGET_template
-CONFIGURE_TARGETS += configure-$(1)
-BUILD_TARGETS     += do-build-$(1)
-CHECK_TARGETS     += check-$(1)
-DISTCHECK_TARGETS += distcheck-$(1)
-COVERAGE_TARGETS  += coverage-$(1)
-STAGE_TARGETS     += stage-$(1)
-BUILD_DIRS        += $(BuildPath)/$(1)
-DIRECTORIES       += $(BuildPath)/$(1)
-
-configure-$(1): $(BuildPath)/$(1)/config.status
-
-$(BuildPath)/$(1)/config.status: | $(BuildPath)/$(1)
-	$$(call configure-target,$(1))
-
-do-build-$(1): configure-$(1)
-
-do-build-$(1):
-	+$$(call build-target,$(1))
-
-check-$(1): do-build-$(1)
-
-check-$(1):
-	+$$(call check-target,$(1))
-
-distcheck-$(1): do-build-$(1)
-
-distcheck-$(1):
-	+$$(call distcheck-target,$(1))
-
-coverage-$(1): do-build-$(1)
-
-coverage-$(1):
-	+$$(call coverage-target,$(1))
-
-stage-$(1): do-build-$(1)
-
-stage-$(1): | $(TopResultDir)
-	$$(call stage-target,$(1))
-
-$(1): stage-$(1)
-endef # TARGET_template
-
-.DEFAULT_GOAL := all
-
-all: stage
-
-# Instantiate an target-specific build template for the target.
-
-$(eval $(call TARGET_template,$(TargetTuple)))
-
-#
-# Common / Finalization
-#
-
-configure: $(CONFIGURE_TARGETS)
-
-build: $(BUILD_TARGETS)
-
-check: $(CHECK_TARGETS)
-
-distcheck: $(DISTCHECK_TARGETS)
-
-coverage: $(COVERAGE_TARGETS)
-
-stage: $(STAGE_TARGETS)
-
-DIRECTORIES     = $(TopResultDir) $(TopResultDir)/$(TargetTuple)/lib $(BUILD_DIRS)
-
-CLEAN_DIRS      = $(TopResultDir) $(BUILD_DIRS)
-
-all: stage
-
-$(DIRECTORIES):
-	$(ECHO) "  MKDIR    $@"
-	@$(MKDIR_P) "$@"
-
-clean:
-	$(ECHO) "  CLEAN"
-	@$(RM_F) -r $(CLEAN_DIRS)
-
-help:
-	$(ECHO) "Simply type 'make -f $(firstword $(MAKEFILE_LIST))' to build OpenThread for the following "
-	$(ECHO) "target:"
-	$(ECHO) ""
-	$(ECHO) "    $(TargetTuple)"
-	$(ECHO) ""
diff --git a/examples/Makefile-simulation b/examples/Makefile-simulation
new file mode 100644
index 0000000..9634ff2
--- /dev/null
+++ b/examples/Makefile-simulation
@@ -0,0 +1,337 @@
+#
+#  Copyright (c) 2016, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Don't allow this top-level makefile's targets to be built in parallel.
+
+.NOTPARALLEL:
+
+COVERAGE                       ?= 0
+DEBUG                          ?= 0
+
+# Enable most features by default to cover most code
+
+BORDER_AGENT                   ?= 1
+BORDER_ROUTER                  ?= 1
+COAP                           ?= 1
+COAP_OBSERVE                   ?= 1
+COAPS                          ?= 1
+COMMISSIONER                   ?= 1
+CHANNEL_MANAGER                ?= 1
+CHANNEL_MONITOR                ?= 1
+CHILD_SUPERVISION              ?= 1
+DHCP6_CLIENT                   ?= 1
+DHCP6_SERVER                   ?= 1
+DIAGNOSTIC                     ?= 1
+DNS_CLIENT                     ?= 1
+ECDSA                          ?= 1
+IP6_FRAGM                      ?= 1
+JAM_DETECTION                  ?= 1
+JOINER                         ?= 1
+LEGACY                         ?= 1
+LINK_RAW                       ?= 1
+MAC_FILTER                     ?= 1
+MTD_NETDIAG                    ?= 1
+REFERENCE_DEVICE               ?= 1
+SERVICE                        ?= 1
+SNTP_CLIENT                    ?= 1
+UDP_FORWARD                    ?= 1
+
+COMMONCFLAGS                   := \
+    -g                            \
+    $(NULL)
+
+# If the user has asserted COVERAGE, alter the configuration options
+# accordingly.
+
+configure_OPTIONS               = \
+    --enable-cli                  \
+    --enable-ftd                  \
+    --enable-mtd                  \
+    --enable-ncp                  \
+    --enable-radio-only           \
+    --with-examples=simulation    \
+    $(NULL)
+
+# Platform specific switches
+
+ifneq ($(DEBUG),1)
+COMMONCFLAGS                   += \
+    -O2                           \
+    $(NULL)
+endif
+
+ifeq ($(NCP_SPI),1)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1
+else
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1
+endif # NCP_SPI == 1
+
+ifeq ($(OTNS),1)
+VIRTUAL_TIME ?= 1
+endif
+
+ifeq ($(VIRTUAL_TIME),1)
+COMMONCFLAGS                   += -DOPENTHREAD_SIMULATION_VIRTUAL_TIME=1
+endif
+
+ifeq ($(VIRTUAL_TIME_UART),1)
+COMMONCFLAGS                   += -DOPENTHREAD_SIMULATION_VIRTUAL_TIME_UART=1
+endif
+
+include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
+
+TopSourceDir                   := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
+AbsTopSourceDir                := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
+
+CONFIG_FILE      = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-simulation-config.h\"'
+CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/simulation/
+COMMONCFLAGS                   += \
+    -D$(CONFIG_FILE)              \
+    -I$(CONFIG_FILE_PATH)         \
+
+CPPFLAGS                       += \
+    $(COMMONCFLAGS)               \
+    $(NULL)
+
+CFLAGS                         += \
+    $(COMMONCFLAGS)               \
+    $(NULL)
+
+CXXFLAGS                       += \
+    $(COMMONCFLAGS)               \
+    $(NULL)
+
+LDFLAGS                        += \
+    $(COMMONCFLAGS)               \
+    $(NULL)
+
+ECHO                           := @echo
+INSTALL                        := /usr/bin/install
+INSTALLFLAGS                   := -p
+LN_S                           := ln -s
+MAKE                           := make
+MKDIR_P                        := mkdir -p
+RM_F                           := rm -f
+
+BuildJobs                      ?= 10
+BuildPath                       = build
+TopBuildDir                     = $(BuildPath)
+AbsTopBuildDir                  = $(PWD)/$(TopBuildDir)
+
+ResultPath                      = output
+TopResultDir                    = $(ResultPath)
+AbsTopResultDir                 = $(PWD)/$(TopResultDir)
+
+TargetTuple                     = $(shell ${AbsTopSourceDir}/third_party/nlbuild-autotools/repo/third_party/autoconf/config.guess | sed -e 's/[[:digit:].]*$$//g')
+
+ifndef BuildJobs
+BuildJobs := $(shell getconf _NPROCESSORS_ONLN)
+endif
+JOBSFLAG := -j$(BuildJobs)
+
+#
+# configure-arch <target>
+#
+# Configure OpenThread for the specified target.
+#
+#   target - The target to configure.
+#
+define configure-target
+$(ECHO) "  CONFIG   $(1)..."
+(cd $(BuildPath)/$(1) && $(AbsTopSourceDir)/configure \
+INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
+CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \
+--prefix=/ \
+--exec-prefix=/$(1) \
+$(configure_OPTIONS))
+endef # configure-target
+
+#
+# build-target <target>
+#
+# Build the OpenThread intermediate build products for the specified
+# target.
+#
+#   target - The target to build.
+#
+define build-target
+$(ECHO) "  BUILD    $(1)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
+all
+endef # build-target
+
+#
+# check-target <target>
+#
+# Check (run unit tests) OpenThread for the specified target.
+#
+#   target - The target to check.
+#
+define check-target
+$(ECHO) "  CHECK    $(1)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
+check
+endef # check-target
+
+#
+# distcheck-target <target>
+#
+# Check (run unit tests) OpenThread for the specified target.
+#
+#   target - The target to distcheck.
+#
+define distcheck-target
+$(ECHO) "  DISTCHECK    $(1)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
+distcheck
+endef # distcheck-target
+
+#
+# coverage-target <target>
+#
+# Generate code coverage from unit tests for OpenThread for the
+# specified target.
+#
+#   target - The target to generate code coverage for.
+#
+define coverage-target
+$(ECHO) "  COVERAGE $(1)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
+coverage
+endef # coverage-target
+
+#
+# stage-target <target>
+#
+# Stage (install) the OpenThread final build products for the specified
+# target.
+#
+#   target - The target to stage.
+#
+define stage-target
+$(ECHO) "  STAGE    $(1)"
+$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
+DESTDIR=$(AbsTopResultDir) \
+install
+endef # stage-target
+
+#
+# TARGET_template <target>
+#
+# Define macros, targets and rules to configure, build, and stage
+# OpenThread for a single target.
+#
+#   target - The target to instantiate the template for.
+#
+define TARGET_template
+CONFIGURE_TARGETS += configure-$(1)
+BUILD_TARGETS     += do-build-$(1)
+CHECK_TARGETS     += check-$(1)
+DISTCHECK_TARGETS += distcheck-$(1)
+COVERAGE_TARGETS  += coverage-$(1)
+STAGE_TARGETS     += stage-$(1)
+BUILD_DIRS        += $(BuildPath)/$(1)
+DIRECTORIES       += $(BuildPath)/$(1)
+
+configure-$(1): $(BuildPath)/$(1)/config.status
+
+$(BuildPath)/$(1)/config.status: | $(BuildPath)/$(1)
+	$$(call configure-target,$(1))
+
+do-build-$(1): configure-$(1)
+
+do-build-$(1):
+	+$$(call build-target,$(1))
+
+check-$(1): do-build-$(1)
+
+check-$(1):
+	+$$(call check-target,$(1))
+
+distcheck-$(1): do-build-$(1)
+
+distcheck-$(1):
+	+$$(call distcheck-target,$(1))
+
+coverage-$(1): do-build-$(1)
+
+coverage-$(1):
+	+$$(call coverage-target,$(1))
+
+stage-$(1): do-build-$(1)
+
+stage-$(1): | $(TopResultDir)
+	$$(call stage-target,$(1))
+
+$(1): stage-$(1)
+endef # TARGET_template
+
+.DEFAULT_GOAL := all
+
+all: stage
+
+# Instantiate an target-specific build template for the target.
+
+$(eval $(call TARGET_template,$(TargetTuple)))
+
+#
+# Common / Finalization
+#
+
+configure: $(CONFIGURE_TARGETS)
+
+build: $(BUILD_TARGETS)
+
+check: $(CHECK_TARGETS)
+
+distcheck: $(DISTCHECK_TARGETS)
+
+coverage: $(COVERAGE_TARGETS)
+
+stage: $(STAGE_TARGETS)
+
+DIRECTORIES     = $(TopResultDir) $(TopResultDir)/$(TargetTuple)/lib $(BUILD_DIRS)
+
+CLEAN_DIRS      = $(TopResultDir) $(BUILD_DIRS)
+
+all: stage
+
+$(DIRECTORIES):
+	$(ECHO) "  MKDIR    $@"
+	@$(MKDIR_P) "$@"
+
+clean:
+	$(ECHO) "  CLEAN"
+	@$(RM_F) -r $(CLEAN_DIRS)
+
+help:
+	$(ECHO) "Simply type 'make -f $(firstword $(MAKEFILE_LIST))' to build OpenThread for the following "
+	$(ECHO) "target:"
+	$(ECHO) ""
+	$(ECHO) "    $(TargetTuple)"
+	$(ECHO) ""
diff --git a/examples/Makefile.am b/examples/Makefile.am
index d25b86c..8d15e20 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -47,11 +47,4 @@
     $(NULL)
 endif
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    platforms                             \
-    apps                                  \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/apps/CMakeLists.txt b/examples/apps/CMakeLists.txt
index 8200d57..03da6f0 100644
--- a/examples/apps/CMakeLists.txt
+++ b/examples/apps/CMakeLists.txt
@@ -26,5 +26,8 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-add_subdirectory(cli)
+if(OT_APP_CLI)
+    add_subdirectory(cli)
+endif()
+
 add_subdirectory(ncp)
diff --git a/examples/apps/Makefile.am b/examples/apps/Makefile.am
index c5dab8f..8abfc8b 100644
--- a/examples/apps/Makefile.am
+++ b/examples/apps/Makefile.am
@@ -50,11 +50,4 @@
 endif
 endif
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    cli                                   \
-    ncp                                   \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/apps/cli/CMakeLists.txt b/examples/apps/cli/CMakeLists.txt
index dac2bc2..05e1acd 100644
--- a/examples/apps/cli/CMakeLists.txt
+++ b/examples/apps/cli/CMakeLists.txt
@@ -36,7 +36,6 @@
 
 set(COMMON_INCLUDES
     ${OT_PUBLIC_INCLUDES}
-    ${OT_PRIVATE_INCLUDES}
     ${PROJECT_SOURCE_DIR}/examples/platforms
     ${PROJECT_SOURCE_DIR}/src/core
 )
@@ -44,18 +43,23 @@
 target_include_directories(ot-cli-ftd PRIVATE ${COMMON_INCLUDES})
 target_include_directories(ot-cli-mtd PRIVATE ${COMMON_INCLUDES})
 
-target_link_libraries(ot-cli-ftd
+target_link_libraries(ot-cli-ftd PRIVATE
     openthread-cli-ftd
     ${OT_PLATFORM_LIB}
     openthread-ftd
     ${OT_PLATFORM_LIB}
     mbedcrypto
+    ot-config
 )
 
-target_link_libraries(ot-cli-mtd
+target_link_libraries(ot-cli-mtd PRIVATE
     openthread-cli-mtd
     ${OT_PLATFORM_LIB}
     openthread-mtd
     ${OT_PLATFORM_LIB}
     mbedcrypto
+    ot-config
 )
+
+install(TARGETS ot-cli-ftd ot-cli-mtd
+    DESTINATION bin)
diff --git a/examples/apps/cli/README.md b/examples/apps/cli/README.md
index 8ba05bc..4d95b08 100644
--- a/examples/apps/cli/README.md
+++ b/examples/apps/cli/README.md
@@ -7,7 +7,7 @@
 ```bash
 $ cd <path-to-openthread>
 $ ./bootstrap
-$ make -f examples/Makefile-posix
+$ make -f examples/Makefile-simulation
 ```
 
 ## 2. Start node 1
diff --git a/examples/apps/cli/main.c b/examples/apps/cli/main.c
index 934b4a5..5257df5 100644
--- a/examples/apps/cli/main.c
+++ b/examples/apps/cli/main.c
@@ -37,7 +37,7 @@
 
 #include "openthread-system.h"
 
-#if OPENTHREAD_EXAMPLES_POSIX
+#if OPENTHREAD_EXAMPLES_SIMULATION
 #include <setjmp.h>
 #include <unistd.h>
 
@@ -71,7 +71,7 @@
 {
     otInstance *instance;
 
-#if OPENTHREAD_EXAMPLES_POSIX
+#if OPENTHREAD_EXAMPLES_SIMULATION
     if (setjmp(gResetJump))
     {
         alarm(0);
diff --git a/examples/apps/ncp/CMakeLists.txt b/examples/apps/ncp/CMakeLists.txt
index 5027850..d6a2d02 100644
--- a/examples/apps/ncp/CMakeLists.txt
+++ b/examples/apps/ncp/CMakeLists.txt
@@ -26,48 +26,16 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-add_executable(ot-ncp-ftd
-    main.c
-)
-
-add_executable(ot-ncp-mtd
-    main.c
-)
-
-add_executable(ot-rcp
-    main.c
-)
-
 set(COMMON_INCLUDES
     ${OT_PUBLIC_INCLUDES}
-    ${OT_PRIVATE_INCLUDES}
     ${PROJECT_SOURCE_DIR}/examples/platforms
     ${PROJECT_SOURCE_DIR}/src/core
 )
 
-target_include_directories(ot-ncp-ftd PRIVATE ${COMMON_INCLUDES})
-target_include_directories(ot-ncp-mtd PRIVATE ${COMMON_INCLUDES})
-target_include_directories(ot-rcp PRIVATE ${COMMON_INCLUDES})
+if(OT_APP_NCP)
+    include(ncp.cmake)
+endif()
 
-target_link_libraries(ot-ncp-ftd
-    openthread-ncp-ftd
-    ${OT_PLATFORM_LIB}
-    openthread-ftd
-    ${OT_PLATFORM_LIB}
-    mbedcrypto
-)
-
-target_link_libraries(ot-ncp-mtd
-    openthread-ncp-mtd
-    ${OT_PLATFORM_LIB}
-    openthread-mtd
-    ${OT_PLATFORM_LIB}
-    mbedcrypto
-)
-
-target_link_libraries(ot-rcp
-    openthread-rcp
-    ${OT_PLATFORM_LIB}
-    openthread-radio
-    ${OT_PLATFORM_LIB}
-)
+if(OT_APP_RCP)
+    include(rcp.cmake)
+endif()
diff --git a/examples/apps/ncp/Makefile.am b/examples/apps/ncp/Makefile.am
index 4881d06..430585e 100644
--- a/examples/apps/ncp/Makefile.am
+++ b/examples/apps/ncp/Makefile.am
@@ -54,6 +54,9 @@
 LDADD_MBEDTLS                                                          = \
     $(NULL)
 
+LDADD_MBEDTLS_RADIO                                                    = \
+    $(NULL)
+
 LDADD_DIAG                                                             = \
     $(NULL)
 
@@ -61,6 +64,10 @@
 LDADD_MBEDTLS                                                         += \
     $(top_builddir)/third_party/mbedtls/libmbedcrypto.a                  \
     $(NULL)
+
+LDADD_MBEDTLS_RADIO                                                   += \
+    $(top_builddir)/third_party/mbedtls/libmbedcrypto-radio.a            \
+    $(NULL)
 endif # OPENTHREAD_ENABLE_BUILTIN_MBEDTLS
 
 if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
@@ -151,8 +158,10 @@
     $(top_builddir)/src/ncp/libopenthread-rcp.a                          \
     $(top_builddir)/src/core/libopenthread-radio.a                       \
     $(LDADD_COMMON)                                                      \
+    $(LDADD_MBEDTLS_RADIO)                                               \
     $(top_builddir)/src/core/libopenthread-radio.a                       \
     $(LDADD_COMMON)                                                      \
+    $(LDADD_MBEDTLS_RADIO)                                               \
     $(NULL)
 
 ot_rcp_LDFLAGS                                                         = \
diff --git a/examples/apps/ncp/main.c b/examples/apps/ncp/main.c
index 8fdd544..2d9c630 100644
--- a/examples/apps/ncp/main.c
+++ b/examples/apps/ncp/main.c
@@ -36,7 +36,7 @@
 
 #include "openthread-system.h"
 
-#if OPENTHREAD_EXAMPLES_POSIX
+#if OPENTHREAD_EXAMPLES_SIMULATION
 #include <setjmp.h>
 #include <unistd.h>
 
@@ -70,7 +70,7 @@
 {
     otInstance *instance;
 
-#if OPENTHREAD_EXAMPLES_POSIX
+#if OPENTHREAD_EXAMPLES_SIMULATION
     if (setjmp(gResetJump))
     {
         alarm(0);
@@ -122,16 +122,3 @@
 
     return 0;
 }
-
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP)
-void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
-{
-    OT_UNUSED_VARIABLE(aLogLevel);
-    OT_UNUSED_VARIABLE(aLogRegion);
-
-    va_list ap;
-    va_start(ap, aFormat);
-    otNcpPlatLogv(aLogLevel, aLogRegion, aFormat, ap);
-    va_end(ap);
-}
-#endif
diff --git a/examples/apps/ncp/ncp.cmake b/examples/apps/ncp/ncp.cmake
new file mode 100644
index 0000000..4f7ca1a
--- /dev/null
+++ b/examples/apps/ncp/ncp.cmake
@@ -0,0 +1,58 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_executable(ot-ncp-ftd
+    main.c
+)
+
+add_executable(ot-ncp-mtd
+    main.c
+)
+
+target_include_directories(ot-ncp-ftd PRIVATE ${COMMON_INCLUDES})
+target_include_directories(ot-ncp-mtd PRIVATE ${COMMON_INCLUDES})
+
+target_link_libraries(ot-ncp-ftd PRIVATE
+    openthread-ncp-ftd
+    ${OT_PLATFORM_LIB}
+    openthread-ftd
+    ${OT_PLATFORM_LIB}
+    mbedcrypto
+    ot-config
+)
+
+target_link_libraries(ot-ncp-mtd PRIVATE
+    openthread-ncp-mtd
+    ${OT_PLATFORM_LIB}
+    openthread-mtd
+    ${OT_PLATFORM_LIB}
+    mbedcrypto
+    ot-config
+)
+
+install(TARGETS ot-ncp-ftd ot-ncp-mtd DESTINATION bin)
diff --git a/examples/apps/ncp/rcp.cmake b/examples/apps/ncp/rcp.cmake
new file mode 100644
index 0000000..0298df7
--- /dev/null
+++ b/examples/apps/ncp/rcp.cmake
@@ -0,0 +1,43 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_executable(ot-rcp
+    main.c
+)
+
+target_include_directories(ot-rcp PRIVATE ${COMMON_INCLUDES})
+
+target_link_libraries(ot-rcp PRIVATE
+    openthread-rcp
+    ${OT_PLATFORM_LIB}
+    openthread-radio
+    ${OT_PLATFORM_LIB}
+    ot-config
+)
+
+install(TARGETS ot-rcp DESTINATION bin)
diff --git a/examples/common-switches.mk b/examples/common-switches.mk
index 589f7cc..59fc043 100644
--- a/examples/common-switches.mk
+++ b/examples/common-switches.mk
@@ -28,10 +28,12 @@
 
 # OpenThread Features (Makefile default configuration).
 
+BACKBONE_ROUTER     ?= 0
 BIG_ENDIAN          ?= 0
 BORDER_AGENT        ?= 0
 BORDER_ROUTER       ?= 0
 COAP                ?= 0
+COAP_OBSERVE        ?= 0
 COAPS               ?= 0
 COMMISSIONER        ?= 0
 COVERAGE            ?= 0
@@ -43,7 +45,9 @@
 DHCP6_SERVER        ?= 0
 DIAGNOSTIC          ?= 0
 DISABLE_DOC         ?= 0
+DISABLE_TOOLS       ?= 0
 DNS_CLIENT          ?= 0
+DUA                 ?= 0
 DYNAMIC_LOG_LEVEL   ?= 0
 ECDSA               ?= 0
 EXTERNAL_HEAP       ?= 0
@@ -56,7 +60,10 @@
 endif
 LINK_RAW            ?= 0
 MAC_FILTER          ?= 0
+MLE_LONG_ROUTES     ?= 0
 MTD_NETDIAG         ?= 0
+MULTIPLE_INSTANCE   ?= 0
+OTNS                ?= 0
 PLATFORM_UDP        ?= 0
 REFERENCE_DEVICE    ?= 0
 SERVICE             ?= 0
@@ -64,10 +71,15 @@
 # SLAAC is enabled by default
 SLAAC               ?= 1
 SNTP_CLIENT         ?= 0
+THREAD_VERSION      ?= 1.1
 TIME_SYNC           ?= 0
 UDP_FORWARD         ?= 0
 
 
+ifeq ($(BACKBONE_ROUTER),1)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1
+endif
+
 ifeq ($(BIG_ENDIAN),1)
 COMMONCFLAGS                   += -DBYTE_ORDER_BIG_ENDIAN=1
 endif
@@ -88,6 +100,10 @@
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE=1
 endif
 
+ifeq ($(COAP_OBSERVE),1)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE=1
+endif
+
 ifeq ($(COMMISSIONER),1)
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1
 endif
@@ -108,6 +124,10 @@
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1
 endif
 
+ifeq ($(CSL_RECEIVER),1)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE=1
+endif
+
 ifeq ($(DEBUG),1)
 configure_OPTIONS              += --enable-debug --disable-optimization
 endif
@@ -128,10 +148,18 @@
 configure_OPTIONS              += --disable-docs
 endif
 
+ifeq ($(DISABLE_TOOLS),1)
+configure_OPTIONS              += --disable-tools
+endif
+
 ifeq ($(DNS_CLIENT),1)
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1
 endif
 
+ifeq ($(DUA),1)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_DUA_ENABLE=1
+endif
+
 ifeq ($(DYNAMIC_LOG_LEVEL),1)
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1
 endif
@@ -172,10 +200,19 @@
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1
 endif
 
+# Enable MLE long routes extension (experimental, breaks Thread conformance)
+ifeq ($(MLE_LONG_ROUTES),1)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE=1
+endif
+
 ifeq ($(MTD_NETDIAG),1)
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1
 endif
 
+ifeq ($(MULTIPLE_INSTANCE),1)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE=1
+endif
+
 ifeq ($(PLATFORM_UDP),1)
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1
 endif
@@ -197,6 +234,12 @@
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1
 endif
 
+ifeq ($(THREAD_VERSION),1.1)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_THREAD_VERSION=2
+else ifeq ($(THREAD_VERSION),1.2)
+COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_THREAD_VERSION=3
+endif
+
 ifeq ($(TIME_SYNC),1)
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1 -DOPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT=1
 endif
@@ -229,8 +272,10 @@
 
 ifeq ($(SETTINGS_RAM),1)
 COMMONCFLAGS += -DOPENTHREAD_SETTINGS_RAM=1
-else
-COMMONCFLAGS += -DOPENTHREAD_SETTINGS_RAM=0
+endif
+
+ifeq ($(OTNS),1)
+COMMONCFLAGS += -DOPENTHREAD_CONFIG_OTNS_ENABLE=1
 endif
 
 ifeq ($(FULL_LOGS),1)
@@ -238,13 +283,16 @@
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_DEBG
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_API=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_ARP=1
+LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_BBR=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_CLI=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_COAP=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_ICMP=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_IP6=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_MAC=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_MEM=1
+LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_MESHCOP=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_MLE=1
+LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_MLR=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_NETDATA=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_NETDIAG=1
 LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_PKT_DUMP=1
diff --git a/examples/platforms/Makefile.am b/examples/platforms/Makefile.am
index 7bd3df3..a479ede 100644
--- a/examples/platforms/Makefile.am
+++ b/examples/platforms/Makefile.am
@@ -35,13 +35,15 @@
     cc2538                                \
     cc2650                                \
     cc2652                                \
+    efr32mg1    			  \
     efr32mg12                             \
     efr32mg13                             \
     efr32mg21                             \
     gp712                                 \
+    k32w                                  \
     kw41z                                 \
     nrf528xx                              \
-    posix                                 \
+    simulation                            \
     qpg6095                               \
     samr21                                \
     utils                                 \
@@ -53,55 +55,63 @@
     utils                                 \
     $(NULL)
 
-if OPENTHREAD_EXAMPLES_CC1352
+if OPENTHREAD_PLATFORM_CC1352
 SUBDIRS                                += cc1352
 endif
 
-if OPENTHREAD_EXAMPLES_CC2538
+if OPENTHREAD_PLATFORM_CC2538
 SUBDIRS                                += cc2538
 endif
 
-if OPENTHREAD_EXAMPLES_CC2650
+if OPENTHREAD_PLATFORM_CC2650
 SUBDIRS                                += cc2650
 endif
 
-if OPENTHREAD_EXAMPLES_CC2652
+if OPENTHREAD_PLATFORM_CC2652
 SUBDIRS                                += cc2652
 endif
 
-if OPENTHREAD_EXAMPLES_EFR32MG12
+if OPENTHREAD_PLATFORM_EFR32MG1
+SUBDIRS                                += efr32mg1
+endif
+
+if OPENTHREAD_PLATFORM_EFR32MG12
 SUBDIRS                                += efr32mg12
 endif
 
-if OPENTHREAD_EXAMPLES_EFR32MG13
+if OPENTHREAD_PLATFORM_EFR32MG13
 SUBDIRS                                += efr32mg13
 endif
 
-if OPENTHREAD_EXAMPLES_EFR32MG21
+if OPENTHREAD_PLATFORM_EFR32MG21
 SUBDIRS                                += efr32mg21
 endif
 
-if OPENTHREAD_EXAMPLES_GP712
+if OPENTHREAD_PLATFORM_GP712
 SUBDIRS                                += gp712
 endif
 
-if OPENTHREAD_EXAMPLES_KW41Z
+if OPENTHREAD_PLATFORM_K32W
+SUBDIRS                                += k32w
+endif
+
+if OPENTHREAD_PLATFORM_KW41Z
 SUBDIRS                                += kw41z
 endif
 
-if OPENTHREAD_EXAMPLES_NRF528XX
+if OPENTHREAD_PLATFORM_NRF528XX
 SUBDIRS                                += nrf528xx
 endif
 
-if OPENTHREAD_EXAMPLES_POSIX
-SUBDIRS                                += posix
+if OPENTHREAD_PLATFORM_SIMULATION
+SUBDIRS                                += simulation
 endif
 
-if OPENTHREAD_EXAMPLES_QPG6095
+if OPENTHREAD_PLATFORM_QPG6095
 SUBDIRS                                += qpg6095
 endif
 
-if OPENTHREAD_EXAMPLES_SAMR21
+if OPENTHREAD_PLATFORM_SAMR21
 SUBDIRS                                += samr21
 endif
 
@@ -109,23 +119,4 @@
     openthread-system.h                   \
     $(NULL)
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    cc1352                                \
-    cc2538                                \
-    cc2650                                \
-    cc2652                                \
-    efr32mg12                             \
-    efr32mg13                             \
-    efr32mg21                             \
-    gp712                                 \
-    kw41z                                 \
-    nrf528xx                              \
-    posix                                 \
-    qpg6095                               \
-    samr21                                \
-    utils                                 \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/Makefile.platform.am b/examples/platforms/Makefile.platform.am
index 2fd657e..4ced649 100644
--- a/examples/platforms/Makefile.platform.am
+++ b/examples/platforms/Makefile.platform.am
@@ -57,6 +57,10 @@
 include $(top_srcdir)/examples/platforms/cc2652/Makefile.platform.am
 endif
 
+if OPENTHREAD_EXAMPLES_EFR32MG1
+include $(top_srcdir)/examples/platforms/efr32mg1/Makefile.platform.am
+endif
+
 if OPENTHREAD_EXAMPLES_EFR32MG12
 include $(top_srcdir)/examples/platforms/efr32mg12/Makefile.platform.am
 endif
@@ -73,6 +77,14 @@
 include $(top_srcdir)/examples/platforms/gp712/Makefile.platform.am
 endif
 
+if OPENTHREAD_EXAMPLES_JN5189
+include $(top_srcdir)/examples/platforms/k32w/jn5189/Makefile.platform.am
+endif
+
+if OPENTHREAD_EXAMPLES_K32W061
+include $(top_srcdir)/examples/platforms/k32w/k32w061/Makefile.platform.am
+endif
+
 if OPENTHREAD_EXAMPLES_KW41Z
 include $(top_srcdir)/examples/platforms/kw41z/Makefile.platform.am
 endif
@@ -97,6 +109,6 @@
 include $(top_srcdir)/examples/platforms/samr21/Makefile.platform.am
 endif # OPENTHREAD_EXAMPLES_SAMR21
 
-if OPENTHREAD_EXAMPLES_POSIX
-include $(top_srcdir)/examples/platforms/posix/Makefile.platform.am
+if OPENTHREAD_EXAMPLES_SIMULATION
+include $(top_srcdir)/examples/platforms/simulation/Makefile.platform.am
 endif
diff --git a/examples/platforms/cc1352/CMakeLists.txt b/examples/platforms/cc1352/CMakeLists.txt
new file mode 100644
index 0000000..6ab6c13
--- /dev/null
+++ b/examples/platforms/cc1352/CMakeLists.txt
@@ -0,0 +1,100 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(OT_PLATFORM_LIB "openthread-cc1352" PARENT_SCOPE)
+
+if(NOT OT_CONFIG)
+    set(OT_CONFIG "openthread-core-cc1352-config.h")
+    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES
+    "OPENTHREAD_CORE_CONFIG_PLATFORM_CHECK_FILE=\"openthread-core-cc1352-config-check.h\""
+)
+set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
+
+target_compile_definitions(ot-config INTERFACE "MBEDTLS_USER_CONFIG_FILE=\"cc1352-mbedtls-config.h\"")
+
+list(APPEND OT_PUBLIC_INCLUDES
+    "${CMAKE_CURRENT_SOURCE_DIR}/crypto"
+    "${PROJECT_SOURCE_DIR}/third_party/ti/devices/cc13x2_cc26x2"
+)
+set(OT_PUBLIC_INCLUDES ${OT_PUBLIC_INCLUDES} PARENT_SCOPE)
+
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+
+add_library(openthread-cc1352
+    alarm.c
+    diag.c
+    entropy.c
+    flash.c
+    logging.c
+    misc.c
+    radio.c
+    system.c
+    uart.c
+    crypto/aes_alt.c
+    cc1352_ccfg.c
+    cc1352_startup.c
+    cxx_helpers.c
+)
+
+set_target_properties(
+    openthread-cc1352
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_link_libraries(openthread-cc1352
+    PUBLIC
+        cc13x2-cc26x2-driver
+    PRIVATE
+        ${OT_MBEDTLS}
+        ot-config
+)
+
+target_link_options(openthread-cc1352
+    PUBLIC
+        -Wl,--gc-sections
+        -Wl,-Map=$<TARGET_PROPERTY:NAME>.map
+)
+
+target_compile_definitions(openthread-cc1352
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-cc1352 PRIVATE ${OT_CFLAGS})
+
+target_include_directories(openthread-cc1352
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        ${PROJECT_SOURCE_DIR}/src/core
+        ${PROJECT_SOURCE_DIR}/examples/platforms
+)
diff --git a/examples/platforms/cc1352/Makefile.am b/examples/platforms/cc1352/Makefile.am
index e64c9fd..b490b23 100644
--- a/examples/platforms/cc1352/Makefile.am
+++ b/examples/platforms/cc1352/Makefile.am
@@ -28,11 +28,11 @@
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
 
-lib_LIBRARIES = libopenthread-cc1352.a
+# Do not enable -Wcast-align for this platform
+override CFLAGS    := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS  := $(filter-out -Wcast-align,$(CXXFLAGS))
 
-# Do not enable -pedantic-errors for cc13xx driverlib
-override CFLAGS   := $(filter-out -pedantic-errors,$(CFLAGS))
-override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
+lib_LIBRARIES = libopenthread-cc1352.a
 
 libopenthread_cc1352_a_CPPFLAGS                                                         = \
     -I$(top_srcdir)/include                                                               \
@@ -73,10 +73,6 @@
     $(top_srcdir)/third_party/ti/devices/cc13x2_cc26x2/driverlib/bin/gcc/driverlib.a      \
     $(NULL)
 
-PRETTY_FILES                                                                            = \
-    $(PLATFORM_SOURCES)                                                                   \
-    $(NULL)
-
 Dash = -
 libopenthread_cc1352_a_LIBADD                                                           = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
diff --git a/examples/platforms/cc1352/README.md b/examples/platforms/cc1352/README.md
index fbbea5f..9c4c87a 100644
--- a/examples/platforms/cc1352/README.md
+++ b/examples/platforms/cc1352/README.md
@@ -1,34 +1,24 @@
 # OpenThread on CC1352 Example
 
-This directory contains example platform drivers for the [Texas Instruments
-CC1352R1][cc1352r1].
+This directory contains example platform drivers for the [Texas Instruments CC1352R1][cc1352r1].
 
-The example platform drivers are intended to present the minimal code necessary
-to support OpenThread. As a result, the example platform drivers do not
-necessarily highlight the platform's full capabilities. Consult the [SimpleLink
-CC26X2R1 SDK][cc26x2r1-sdk] for more development option. The platform drivers
-were built for the [CC1352R1 LAUNCHXL][cc1352r1-launchxl], usage on other
-boards with a cc1352r1 may require changes to the peripheral drivers.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. As a result, the example platform drivers do not necessarily highlight the platform's full capabilities. Consult the [SimpleLink CC26X2R1 SDK][cc26x2r1-sdk] for more development option. The platform drivers were built for the [CC1352R1 LAUNCHXL][cc1352r1-launchxl], usage on other boards with a cc1352r1 may require changes to the peripheral drivers.
 
 [cc1352r1-launchxl]: http://www.ti.com/tool/launchxl-cc26x2r1
 [cc26x2r1-sdk]: http://www.ti.com/tool/simplelink-cc26x2-sdk
+
 <!---
 TODO: Update link when cc1352 product page is live
 [cc1352r1]: http://www.ti.com/product/cc1352r1
 -->
+
 [cc1352r1]: http://www.ti.com/tool/launchxl-cc26x2r1
 
 ## Toolchain
 
-Building the examples for the cc1352 requires [GNU AutoConf][gnu-autoconf],
-[GNU AutoMake][gnu-automake], [Python][python], and the [ARM gcc
-toolchain][arm-toolchain].
+Building the examples for the cc1352 requires [GNU AutoConf][gnu-autoconf], [GNU AutoMake][gnu-automake], [Python][python], and the [ARM gcc toolchain][arm-toolchain].
 
-With the exception of the arm toolchain, most of these tools are installed by
-default on modern Posix systems. It is recommended to setup a Linux virtual
-machine for building on a Windows host system. For help setting up VirtualBox
-with Ubuntu, consult this [community help wiki
-article][ubuntu-wiki-virtualbox].
+With the exception of the arm toolchain, most of these tools are installed by default on modern Posix systems. It is recommended to setup a Linux virtual machine for building on a Windows host system. For help setting up VirtualBox with Ubuntu, consult this [community help wiki article][ubuntu-wiki-virtualbox].
 
 [gnu-autoconf]: https://www.gnu.org/software/autoconf
 [gnu-automake]: https://www.gnu.org/software/automake
@@ -38,8 +28,7 @@
 [mingw]: http://www.mingw.org
 [ubuntu-wiki-virtualbox]: https://help.ubuntu.com/community/VirtualBox
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -58,11 +47,9 @@
 
 ## Flash Binaries
 
-If the build completed successfully, the `elf` files may be found in
-`<path-to-openthread>/output/cc1352/bin`.
+If the build completed successfully, the `elf` files may be found in `<path-to-openthread>/output/cc1352/bin`.
 
-Flash the images with [Uniflash][uniflash]. Make sure to deselect the binary
-check-box, Uniflash assumes a file without an extension is a binary file.
+Flash the images with [Uniflash][uniflash]. Make sure to deselect the binary check-box, Uniflash assumes a file without an extension is a binary file.
 
 [uniflash]: http://www.ti.com/tool/uniflash
 
@@ -70,15 +57,13 @@
 
 ### CLI example
 
-1. With a terminal client (PuTTY, minicom, etc.) open the com port associated
-   with the cc1352 UART. The serial port settings are:
-    * 115200 baud
-    * 8 data bits
-    * no parity bit
-    * 1 stop bit
+1. With a terminal client (PuTTY, minicom, etc.) open the com port associated with the cc1352 UART. The serial port settings are:
+   - 115200 baud
+   - 8 data bits
+   - no parity bit
+   - 1 stop bit
 2. Type `help` for a list of commands.
-3. Follow the instructions in the [CLI README][cli-readme] for instructions on
-   setting up a network.
+3. Follow the instructions in the [CLI README][cli-readme] for instructions on setting up a network.
 
 [cli-readme]: ../../../src/cli/README.md
 
@@ -114,7 +99,6 @@
 
 ### NCP example
 
-Refer to the documentation in the [wpantund][wpantund] project for build
-instructions and usage information.
+Refer to the documentation in the [wpantund][wpantund] project for build instructions and usage information.
 
 [wpantund]: https://github.com/openthread/wpantund
diff --git a/examples/platforms/cc1352/arm-none-eabi.cmake b/examples/platforms/cc1352/arm-none-eabi.cmake
new file mode 100644
index 0000000..c2789c3
--- /dev/null
+++ b/examples/platforms/cc1352/arm-none-eabi.cmake
@@ -0,0 +1,50 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(CMAKE_SYSTEM_NAME              Generic)
+set(CMAKE_SYSTEM_PROCESSOR         ARM)
+
+set(CMAKE_C_COMPILER               arm-none-eabi-gcc)
+set(CMAKE_CXX_COMPILER             arm-none-eabi-g++)
+set(CMAKE_ASM_COMPILER             arm-none-eabi-as)
+set(CMAKE_RANLIB                   arm-none-eabi-ranlib)
+
+set(COMMON_C_FLAGS                 "-mcpu=cortex-m4 -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -fdata-sections -ffunction-sections")
+
+set(CMAKE_C_FLAGS                  "${COMMON_C_FLAGS} -std=gnu99")
+set(CMAKE_CXX_FLAGS                "${COMMON_C_FLAGS} -fno-exceptions -fno-rtti")
+set(CMAKE_ASM_FLAGS                "${COMMON_C_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS_INIT    "${COMMON_C_FLAGS} -nostartfiles -specs=nano.specs -specs=nosys.specs")
+
+set(CMAKE_C_FLAGS_DEBUG            "-Og -g")
+set(CMAKE_CXX_FLAGS_DEBUG          "-Og -g")
+set(CMAKE_ASM_FLAGS_DEBUG          "-g")
+
+set(CMAKE_C_FLAGS_RELEASE          "-Os")
+set(CMAKE_CXX_FLAGS_RELEASE        "-Os")
+set(CMAKE_ASM_FLAGS_RELEASE        "")
diff --git a/examples/platforms/cc1352/crypto/aes_alt.h b/examples/platforms/cc1352/crypto/aes_alt.h
index 4a14859..64ec3c4 100644
--- a/examples/platforms/cc1352/crypto/aes_alt.h
+++ b/examples/platforms/cc1352/crypto/aes_alt.h
@@ -71,8 +71,7 @@
  * @retval 0                                   If successful
  * @retval MBEDTLS_ERR_AES_INVALID_KEY_LENGTH  If keybits was not 128
  */
-int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
-                           unsigned int keybits);
+int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits);
 
 /**
  * @brief          AES key schedule (decryption)
@@ -84,8 +83,7 @@
  * @retval 0                                   If successful
  * @retval MBEDTLS_ERR_AES_INVALID_KEY_LENGTH  If keybits was not 128
  */
-int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
-                           unsigned int keybits);
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits);
 
 /**
  * \brief          AES-ECB block encryption/decryption
@@ -99,8 +97,7 @@
  * @retval 0                        If successful
  * @retval AES_KEYSTORE_READ_ERROR  If the indicated keystore ram could not be read
  */
-int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16],
-                          unsigned char output[16]);
+int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16]);
 
 #ifdef __cplusplus
 }
diff --git a/examples/platforms/cc1352/diag.c b/examples/platforms/cc1352/diag.c
index 520b409..7ab65c3 100644
--- a/examples/platforms/cc1352/diag.c
+++ b/examples/platforms/cc1352/diag.c
@@ -46,17 +46,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    // Add more platform specific diagnostics features here.
-    if (argc > 1)
-    {
-        snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-    }
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/cc1352/flash.c b/examples/platforms/cc1352/flash.c
index 2a4a013..9605c58 100644
--- a/examples/platforms/cc1352/flash.c
+++ b/examples/platforms/cc1352/flash.c
@@ -28,43 +28,21 @@
 
 #include <string.h>
 
+#include <openthread/instance.h>
+
 #include <driverlib/aon_batmon.h>
 #include <driverlib/flash.h>
 #include <driverlib/interrupt.h>
 #include <driverlib/vims.h>
 
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-#include <openthread/platform/alarm-milli.h>
-
 #include <utils/code_utils.h>
 
 #include "platform-cc1352.h"
 
-/*
- * The settings configuration base address *MUST* be defined in the core config
- * file. The base address *MUST* be aligned on an 8K page boundary or the flash
- * program calls will fail.
- */
-#ifndef SETTINGS_CONFIG_BASE_ADDRESS
-#error "SETTINGS_CONFIG_BASE_ADDRESS not defined in the OpenThread Core Config"
-#endif /* SETTINGS_CONFIG_BASE_ADDRESS */
-
-/*
- * The settings configuration page size *MUST* be defined in the core config
- * file. The page size *MUST* be 8K or the flash program calls will fail.
- */
-#if (SETTINGS_CONFIG_PAGE_SIZE != 0x2000)
-#error "SETTINGS_CONFIG_PAGE_SIZE must be defined in OpenThread Core Config"
-#endif
-
-/*
- * The settings configuration page number _SHOULD_ be defined in the core
- * config file.
- */
-#ifndef SETTINGS_CONFIG_PAGE_NUM
-#warn "SETTINGS_CONFIG_PAGE_NUM not defined in the OpenThread Core Config"
-#endif /* SETTINGS_CONFIG_PAGE_NUM */
+#define FLASH_BASE_ADDRESS 0x52000
+#define FLASH_PAGE_SIZE 0x2000
+#define FLASH_PAGE_NUM 2 /* must be a multiple of 2 */
+#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * (FLASH_PAGE_NUM / 2))
 
 enum
 {
@@ -158,117 +136,87 @@
     VIMSLineBufEnable(VIMS_BASE);
 }
 
-/**
- * Translate the errors from the Flash programming FSM to OpenThread error
- * codes.
- *
- * @param [in] error Return from the Flash programming function.
- *
- * @return The corresponding OpenThread @ref otError value.
- */
-static otError fsmErrorToOtError(uint32_t error)
+static uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    otError ret = OT_ERROR_GENERIC;
+    uint32_t address = FLASH_BASE_ADDRESS + aOffset;
 
-    switch (error)
+    if (aSwapIndex)
     {
-    case FAPI_STATUS_SUCCESS:
-        ret = OT_ERROR_NONE;
-        break;
-
-    case FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH:
-        ret = OT_ERROR_INVALID_ARGS;
-        break;
-
-    case FAPI_STATUS_FSM_ERROR:
-        ret = OT_ERROR_FAILED;
-        break;
-
-    default:
-        break;
+        address += FLASH_SWAP_SIZE;
     }
 
-    return ret;
+    return address;
 }
 
 /**
  * Function documented in platforms/utils/flash.h
  */
-otError utilsFlashInit(void)
+void otPlatFlashInit(otInstance *aInstance)
 {
-    return OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
 }
 
 /**
  * Function documented in platforms/utils/flash.h
  */
-uint32_t utilsFlashGetSize(void)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
 {
-    return FlashSizeGet();
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return FLASH_SWAP_SIZE;
 }
 
 /**
  * Function documented in platforms/utils/flash.h
  */
-otError utilsFlashErasePage(uint32_t aAddress)
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
 {
+    OT_UNUSED_VARIABLE(aInstance);
+
     uint32_t mode;
-    uint32_t fsmRet;
-    otError  ret;
-
-    otEXPECT_ACTION(checkVoltage(), ret = OT_ERROR_FAILED);
-
-    mode = disableFlashCache();
-
-    fsmRet = FlashSectorErase(aAddress);
-
-    restoreFlashCache(mode);
-
-    ret = fsmErrorToOtError(fsmRet);
-
-exit:
-    return ret;
-}
-
-/**
- * Function documented in platforms/utils/flash.h
- */
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    uint32_t start = otPlatAlarmMilliGetNow();
-    otError  ret   = OT_ERROR_BUSY;
-
-    while ((otPlatAlarmMilliGetNow() - start) < aTimeout)
-    {
-        if (FlashCheckFsmForReady() == FAPI_STATUS_FSM_READY)
-        {
-            ret = OT_ERROR_NONE;
-            break;
-        }
-    }
-
-    return ret;
-}
-
-/**
- * Function documented in platforms/utils/flash.h
- */
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t mode;
-    uint32_t written = 0;
 
     otEXPECT(checkVoltage());
 
     mode = disableFlashCache();
 
+    for (uint8_t page = 0; page < FLASH_PAGE_NUM; page++)
+    {
+        FlashSectorErase(mapAddress(aSwapIndex, (page * FLASH_PAGE_SIZE)));
+    }
+
+    restoreFlashCache(mode);
+
+    while (FlashCheckFsmForReady() != FAPI_STATUS_FSM_READY)
+    {
+    }
+
+exit:
+    return;
+}
+
+/**
+ * Function documented in platforms/utils/flash.h
+ */
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t mode;
+    uint32_t written = 0;
+    uint32_t address;
+
+    otEXPECT(checkVoltage());
+
+    mode = disableFlashCache();
+
+    address = mapAddress(aSwapIndex, aOffset);
+
     while (written < aSize)
     {
-        uint32_t toWrite = aSize - written;
-        uint8_t *data    = aData + written;
-        uint32_t address = aAddress + written;
-        uint32_t fsmRet;
-        bool     interruptsWereDisabled;
+        uint32_t       toWrite = aSize - written;
+        const uint8_t *data    = (uint8_t *)aData + written;
+        uint32_t       fsmRet;
+        bool           interruptsWereDisabled;
 
         if (toWrite > MAX_WRITE_INCREMENT)
         {
@@ -281,7 +229,7 @@
          */
         interruptsWereDisabled = IntMasterDisable();
 
-        fsmRet = FlashProgram(data, address, toWrite);
+        fsmRet = FlashProgram((uint8_t *)data, address + written, toWrite);
 
         if (!interruptsWereDisabled)
         {
@@ -299,15 +247,15 @@
     restoreFlashCache(mode);
 
 exit:
-    return written;
+    return;
 }
 
 /**
  * Function documented in platforms/utils/flash.h
  */
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
 {
-    memcpy(aData, (void *)aAddress, (size_t)aSize);
+    OT_UNUSED_VARIABLE(aInstance);
 
-    return aSize;
+    memcpy(aData, (void *)mapAddress(aSwapIndex, aOffset), (size_t)aSize);
 }
diff --git a/examples/platforms/cc1352/logging.c b/examples/platforms/cc1352/logging.c
index de5a469..c9a9a3b 100644
--- a/examples/platforms/cc1352/logging.c
+++ b/examples/platforms/cc1352/logging.c
@@ -36,8 +36,7 @@
 #include <openthread/platform/logging.h>
 #include <openthread/platform/toolchain.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
 {
     OT_UNUSED_VARIABLE(aLogLevel);
diff --git a/examples/platforms/cc1352/openthread-core-cc1352-config.h b/examples/platforms/cc1352/openthread-core-cc1352-config.h
index 35b25d2..ad73700 100644
--- a/examples/platforms/cc1352/openthread-core-cc1352-config.h
+++ b/examples/platforms/cc1352/openthread-core-cc1352-config.h
@@ -38,27 +38,14 @@
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "CC1352"
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of the pages to be used for non-volatile-settings storage.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
+ *
  */
-#define SETTINGS_CONFIG_BASE_ADDRESS (0x52000)
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The size in bytes of a page for the cc26x2 platform.
- *
- * @note *MUST BE* 8K.
- */
-#define SETTINGS_CONFIG_PAGE_SIZE (0x2000)
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The number of flash pages to use for non-volatile settings storage.
- */
-#define SETTINGS_CONFIG_PAGE_NUM (2)
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
diff --git a/examples/platforms/cc1352/radio.c b/examples/platforms/cc1352/radio.c
index b401fa8..b8beabb 100644
--- a/examples/platforms/cc1352/radio.c
+++ b/examples/platforms/cc1352/radio.c
@@ -37,6 +37,7 @@
 
 #include <assert.h>
 #include <utils/code_utils.h>
+#include <utils/encoding.h>
 #include <openthread/random_noncrypto.h> /* to seed the CSMA-CA funciton */
 #include <openthread/platform/alarm-milli.h>
 #include <openthread/platform/diag.h>
@@ -457,7 +458,7 @@
  * @return The index where the address was found.
  * @retval CC1352_SRC_MATCH_NONE The address was not found.
  */
-static uint8_t rfCoreFindShortSrcMatchIdx(const uint16_t aAddress)
+static uint8_t rfCoreFindShortSrcMatchIdx(uint16_t aAddress)
 {
     uint8_t i;
     uint8_t ret = CC1352_SRC_MATCH_NONE;
@@ -1508,7 +1509,7 @@
 /**
  * Function documented in platform/radio.h
  */
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -1542,7 +1543,7 @@
 /**
  * Function documented in platform/radio.h
  */
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -1577,7 +1578,7 @@
     OT_UNUSED_VARIABLE(aInstance);
 
     otError  error      = OT_ERROR_NONE;
-    uint64_t extAddress = *(uint64_t *)aExtAddress;
+    uint64_t extAddress = otEncodingReadUint64Le(aExtAddress->m8);
     uint8_t  idx        = rfCoreFindExtSrcMatchIdx(&extAddress);
 
     if (idx == CC1352_SRC_MATCH_NONE)
@@ -1611,7 +1612,7 @@
     OT_UNUSED_VARIABLE(aInstance);
 
     otError  error      = OT_ERROR_NONE;
-    uint64_t extAddress = *(uint64_t *)aExtAddress;
+    uint64_t extAddress = otEncodingReadUint64Le(aExtAddress->m8);
     uint8_t  idx;
 
     otEXPECT_ACTION((idx = rfCoreFindExtSrcMatchIdx(&extAddress)) != CC1352_SRC_MATCH_NONE,
@@ -1812,7 +1813,7 @@
     if (sState == cc1352_stateReceive)
     {
         otEXPECT(rfCoreExecuteAbortCmd() == CMDSTA_Done);
-        sReceiveCmd.localExtAddr = *((uint64_t *)(aAddress));
+        sReceiveCmd.localExtAddr = otEncodingReadUint64Le(aAddress->m8);
         otEXPECT(rfCoreClearReceiveQueue(&sRxDataQueue) == CMDSTA_Done);
         otEXPECT(rfCoreSendReceiveCmd() == CMDSTA_Done);
         /* the interrupt from abort changed our state to sleep */
@@ -1820,7 +1821,7 @@
     }
     else if (sState != cc1352_stateTransmit)
     {
-        sReceiveCmd.localExtAddr = *((uint64_t *)(aAddress));
+        sReceiveCmd.localExtAddr = otEncodingReadUint64Le(aAddress->m8);
     }
 
 exit:
diff --git a/examples/platforms/cc2538/CMakeLists.txt b/examples/platforms/cc2538/CMakeLists.txt
index 13ecedb..f33848a 100644
--- a/examples/platforms/cc2538/CMakeLists.txt
+++ b/examples/platforms/cc2538/CMakeLists.txt
@@ -55,15 +55,28 @@
     $<TARGET_OBJECTS:openthread-platform-utils>
 )
 
-target_link_libraries(openthread-cc2538 PRIVATE openthread-platform-utils)
-target_link_options(openthread-cc2538 PUBLIC -T${PROJECT_SOURCE_DIR}/examples/platforms/cc2538/cc2538.ld)
-target_link_options(openthread-cc2538 PUBLIC -Wl,-Map=$<TARGET_PROPERTY:NAME>.map)
+set_target_properties(
+    openthread-cc2538
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
 
-target_compile_definitions(openthread-cc2538 PUBLIC ${OT_PLATFORM_DEFINES})
+target_link_libraries(openthread-cc2538 PRIVATE openthread-platform-utils ot-config)
+target_link_options(openthread-cc2538 PUBLIC -T${PROJECT_SOURCE_DIR}/examples/platforms/cc2538/cc2538.ld)
+target_link_options(openthread-cc2538 PUBLIC -Wl,--gc-sections -Wl,-Map=$<TARGET_PROPERTY:NAME>.map)
+
+target_compile_definitions(openthread-cc2538
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-cc2538 PRIVATE
+    ${OT_CFLAGS}
+)
 
 target_include_directories(openthread-cc2538 PRIVATE
     ${OT_PUBLIC_INCLUDES}
-    ${OT_PRIVATE_INCLUDES}
     ${PROJECT_SOURCE_DIR}/examples/platforms
     ${PROJECT_SOURCE_DIR}/src/core
 )
diff --git a/examples/platforms/cc2538/Makefile.am b/examples/platforms/cc2538/Makefile.am
index a7d2f00..fb802f2 100644
--- a/examples/platforms/cc2538/Makefile.am
+++ b/examples/platforms/cc2538/Makefile.am
@@ -28,6 +28,10 @@
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
 
+# Do not enable -Wcast-align for this platform
+override CFLAGS    := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS  := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 lib_LIBRARIES                             = libopenthread-cc2538.a
 
 libopenthread_cc2538_a_CPPFLAGS           = \
@@ -58,10 +62,6 @@
     $(PLATFORM_SOURCES)                     \
     $(NULL)
 
-PRETTY_FILES                             = \
-    $(PLATFORM_SOURCES)                    \
-    $(NULL)
-
 Dash                                      = -
 libopenthread_cc2538_a_LIBADD             = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
diff --git a/examples/platforms/cc2538/README.md b/examples/platforms/cc2538/README.md
index c4166e4..d0e9af7 100644
--- a/examples/platforms/cc2538/README.md
+++ b/examples/platforms/cc2538/README.md
@@ -1,23 +1,18 @@
 # OpenThread on CC2538 Example
 
-This directory contains example platform drivers for the [Texas
-Instruments CC2538][cc2538].
+This directory contains example platform drivers for the [Texas Instruments CC2538][cc2538].
 
 [cc2538]: http://www.ti.com/product/CC2538
 
-The example platform drivers are intended to present the minimal code
-necessary to support OpenThread.  As a result, the example platform
-drivers do not necessarily highlight the platform's full capabilities.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. As a result, the example platform drivers do not necessarily highlight the platform's full capabilities.
 
 ## Toolchain
 
-Download and install the [GNU toolchain for ARM
-Cortex-M][gnu-toolchain].
+Download and install the [GNU toolchain for ARM Cortex-M][gnu-toolchain].
 
 [gnu-toolchain]: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -36,9 +31,7 @@
 
 ### CC2592 support
 
-If your board has a CC2592 range extender front-end IC connected to the CC2538
-(e.g. the CC2538-CC2592 EM reference design), you need to initialise this part
-before reception of radio traffic will work.
+If your board has a CC2592 range extender front-end IC connected to the CC2538 (e.g. the CC2538-CC2592 EM reference design), you need to initialise this part before reception of radio traffic will work.
 
 Support is enabled in OpenThread by building with `CC2592=1`:
 
@@ -46,62 +39,39 @@
 $ make -f examples/Makefile-cc2538 CC2592=1
 ```
 
-The default settings should work for any design following the integration
-advice given in TI's application report ["AN130 - Using CC2592 Front End With
-CC2538"](http://www.ti.com/lit/pdf/swra447).
+The default settings should work for any design following the integration advice given in TI's application report ["AN130 - Using CC2592 Front End With CC2538"](http://www.ti.com/lit/pdf/swra447).
 
 Additional settings can be customised:
 
-* `CC2592_PA_EN`: This specifies which pin (on port C of the CC2538) connects to the
-  CC2592's `PA_EN` pin.  The default is `3` (PC3).
-* `CC2592_LNA_EN`: This specifies which pin (on port C of the CC2538) connects to the
-  CC2592's `LNA_EN` pin.  The default is `2` (PC2).
-* `CC2592_USE_HGM`: This defines whether the HGM pin of the CC2592 is under GPIO control
-  or not.  If not, it is assumed that the HGM pin is tied to a power rail.
-* `CC2592_HGM_PORT`: The HGM pin can be connected to any free GPIO.  TI recommend using
-  PD2, however if you've used a pin on another GPIO port, you may specify that port (`A`,
-  `B` or `C`) here.
-* `CC2592_HGM_PORT`: The HGM pin can be connected to any free GPIO.  TI recommend using
-  PD2, however if you've used a pin on another GPIO port, you may specify that port (`A`,
-  `B` or `C`) here.  Default is `D`.
-* `CC2592_HGM_PIN`: The HGM pin can be connected to any free GPIO.  TI recommend using
-  PD2, however if you've used a pin on another GPIO pin, you can specify the pin here.
-  Default is `2`.
-* `CC2592_HGM_DEFAULT_STATE`: By default, HGM is enabled at power-on, but you may want
-  to have it default to off, specify `CC2592_HGM_DEFAULT_STATE=0` to do so.
-* `CC2538_RECEIVE_SENSITIVITY`: If you have tied the HGM pin to a power rail, this allows
-  you to calibrate the RSSI values according to the new receive sensitivity.  This has no
-  effect if `CC2592_USE_HGM=1` (the default).
-* `CC2538_RSSI_OFFSET`: If you have tied the HGM pin to a power rail, this allows
-  you to calibrate the RSSI values according to the new RSSI offset.  This has no
-  effect if `CC2592_USE_HGM=1` (the default).
+- `CC2592_PA_EN`: This specifies which pin (on port C of the CC2538) connects to the CC2592's `PA_EN` pin. The default is `3` (PC3).
+- `CC2592_LNA_EN`: This specifies which pin (on port C of the CC2538) connects to the CC2592's `LNA_EN` pin. The default is `2` (PC2).
+- `CC2592_USE_HGM`: This defines whether the HGM pin of the CC2592 is under GPIO control or not. If not, it is assumed that the HGM pin is tied to a power rail.
+- `CC2592_HGM_PORT`: The HGM pin can be connected to any free GPIO. TI recommend using PD2, however if you've used a pin on another GPIO port, you may specify that port (`A`, `B` or `C`) here.
+- `CC2592_HGM_PORT`: The HGM pin can be connected to any free GPIO. TI recommend using PD2, however if you've used a pin on another GPIO port, you may specify that port (`A`, `B` or `C`) here. Default is `D`.
+- `CC2592_HGM_PIN`: The HGM pin can be connected to any free GPIO. TI recommend using PD2, however if you've used a pin on another GPIO pin, you can specify the pin here. Default is `2`.
+- `CC2592_HGM_DEFAULT_STATE`: By default, HGM is enabled at power-on, but you may want to have it default to off, specify `CC2592_HGM_DEFAULT_STATE=0` to do so.
+- `CC2538_RECEIVE_SENSITIVITY`: If you have tied the HGM pin to a power rail, this allows you to calibrate the RSSI values according to the new receive sensitivity. This has no effect if `CC2592_USE_HGM=1` (the default).
+- `CC2538_RSSI_OFFSET`: If you have tied the HGM pin to a power rail, this allows you to calibrate the RSSI values according to the new RSSI offset. This has no effect if `CC2592_USE_HGM=1` (the default).
 
 ## Flash Binaries
 
-If the build completed successfully, the `elf` files may be found in
-`<path-to-openthread>/output/cc2538/bin`.
+If the build completed successfully, the `elf` files may be found in `<path-to-openthread>/output/cc2538/bin`.
 
-To flash the images with [Flash Programmer 2][ti-flash-programmer-2],
-the files must have the `*.elf` extension.
+To flash the images with [Flash Programmer 2][ti-flash-programmer-2], the files must have the `*.elf` extension.
 
 ```bash
 $ cd <path-to-openthread>/output/cc2538/bin
 $ cp ot-cli ot-cli.elf
 ```
 
-To load the images with the [serial bootloader][ti-cc2538-bootloader],
-the images must be converted to `bin`. This is done using
-`arm-none-eabi-objcopy`
+To load the images with the [serial bootloader][ti-cc2538-bootloader], the images must be converted to `bin`. This is done using `arm-none-eabi-objcopy`
 
 ```bash
 $ cd <path-to-openthread>/output/cc2538/bin
 $ arm-none-eabi-objcopy -O binary ot-cli ot-cli.bin
 ```
 
-The [cc2538-bsl.py script][cc2538-bsl-tool] provides a convenient
-method for flashing a CC2538 via the UART. To enter the bootloader
-backdoor for flashing, hold down SELECT for CC2538DK (corresponds to
-logic '0') while you press the Reset button.
+The [cc2538-bsl.py script][cc2538-bsl-tool] provides a convenient method for flashing a CC2538 via the UART. To enter the bootloader backdoor for flashing, hold down SELECT for CC2538DK (corresponds to logic '0') while you press the Reset button.
 
 [ti-flash-programmer-2]: http://www.ti.com/tool/flash-programmer
 [ti-cc2538-bootloader]: http://www.ti.com/lit/an/swra466a/swra466a.pdf
diff --git a/examples/platforms/cc2538/arm-none-eabi.cmake b/examples/platforms/cc2538/arm-none-eabi.cmake
index 3dfbb5f..dc06cae 100644
--- a/examples/platforms/cc2538/arm-none-eabi.cmake
+++ b/examples/platforms/cc2538/arm-none-eabi.cmake
@@ -39,14 +39,12 @@
 set(CMAKE_C_FLAGS                  "${COMMON_C_FLAGS} -std=gnu99")
 set(CMAKE_CXX_FLAGS                "${COMMON_C_FLAGS} -fno-exceptions -fno-rtti")
 set(CMAKE_ASM_FLAGS                "${COMMON_C_FLAGS}")
-set(CMAKE_EXE_LINKER_FLAGS         "${COMMON_C_FLAGS} -Wl,--gc-sections -specs=nano.specs -specs=nosys.specs -nostartfiles")
+set(CMAKE_EXE_LINKER_FLAGS_INIT    "${COMMON_C_FLAGS} -specs=nano.specs -specs=nosys.specs -nostartfiles")
 
 set(CMAKE_C_FLAGS_DEBUG            "-Og -g")
 set(CMAKE_CXX_FLAGS_DEBUG          "-Og -g")
 set(CMAKE_ASM_FLAGS_DEBUG          "-g")
-set(CMAKE_EXE_LINKER_FLAGS_DEBUG   "")
 
 set(CMAKE_C_FLAGS_RELEASE          "-Os")
 set(CMAKE_CXX_FLAGS_RELEASE        "-Os")
 set(CMAKE_ASM_FLAGS_RELEASE        "")
-set(CMAKE_EXE_LINKER_FLAGS_RELEASE "")
diff --git a/examples/platforms/cc2538/diag.c b/examples/platforms/cc2538/diag.c
index d991588..579c1e7 100644
--- a/examples/platforms/cc2538/diag.c
+++ b/examples/platforms/cc2538/diag.c
@@ -45,15 +45,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(aInstance);
-
-    // Add more platform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/cc2538/flash.c b/examples/platforms/cc2538/flash.c
index 7454047..04c8a65 100644
--- a/examples/platforms/cc2538/flash.c
+++ b/examples/platforms/cc2538/flash.c
@@ -26,168 +26,76 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <openthread/platform/alarm-milli.h>
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
 
 #include "platform-cc2538.h"
 #include "rom-utility.h"
-#include "utils/code_utils.h"
-#include "utils/flash.h"
 
 #define FLASH_CTRL_FCTL_BUSY 0x00000080
 
-#if SETTINGS_CONFIG_PAGE_SIZE != 2048
-#error FLASH page size is 2048 on this chip
-#endif
-
-#if SETTINGS_CONFIG_PAGE_NUM != 2
-#error Linker script reserves 2 pages for settings.
-#endif
+#define FLASH_PAGE_SIZE 2048
+#define FLASH_PAGE_NUM 2
+#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * (FLASH_PAGE_NUM / 2))
 
 /* The linker script creates this external symbol */
 extern uint8_t _FLASH_settings_pageA[];
 
 /* Convert a settings offset to the physical address within the flash settings pages */
-static uint32_t flashPhysAddr(uint32_t settings_offset)
+static uint32_t flashPhysAddr(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    uint32_t base;
+    uint32_t address = (uint32_t)(&_FLASH_settings_pageA[0]) + aOffset;
 
-    base = (uint32_t)(&_FLASH_settings_pageA[0]);
-    base = base + settings_offset;
-    return base;
-}
-
-static otError romStatusToThread(int32_t aStatus)
-{
-    otError error = OT_ERROR_NONE;
-
-    switch (aStatus)
+    if (aSwapIndex)
     {
-    case 0:
-        error = OT_ERROR_NONE;
-        break;
-
-    case -1:
-        error = OT_ERROR_FAILED;
-        break;
-
-    case -2:
-        error = OT_ERROR_INVALID_ARGS;
-        break;
-
-    default:
-        error = OT_ERROR_ABORT;
+        address += FLASH_SWAP_SIZE;
     }
 
-    return error;
+    return address;
 }
 
-otError utilsFlashInit(void)
+void otPlatFlashInit(otInstance *aInstance)
 {
-    return OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
 }
 
-uint32_t utilsFlashGetSize(void)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
 {
-    return (SETTINGS_CONFIG_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM);
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return FLASH_SWAP_SIZE;
 }
 
-otError utilsFlashErasePage(uint32_t aAddress)
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
 {
-    otError  error = OT_ERROR_NONE;
-    int32_t  status;
-    uint32_t address;
+    OT_UNUSED_VARIABLE(aInstance);
 
-    otEXPECT_ACTION(aAddress < utilsFlashGetSize(), error = OT_ERROR_INVALID_ARGS);
-
-    address = aAddress - (aAddress & (SETTINGS_CONFIG_PAGE_SIZE - 1));
-    address = flashPhysAddr(address);
-    status  = ROM_PageErase(address, SETTINGS_CONFIG_PAGE_SIZE);
-    error   = romStatusToThread(status);
-
-exit:
-    return error;
-}
-
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    otError  error = OT_ERROR_NONE;
-    uint32_t start = otPlatAlarmMilliGetNow();
-    uint32_t busy  = 1;
-
-    while (busy && ((otPlatAlarmMilliGetNow() - start) < aTimeout))
+    ROM_PageErase(flashPhysAddr(aSwapIndex, 0), FLASH_PAGE_SIZE);
+    while (HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY)
     {
-        busy = HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY;
     }
-
-    otEXPECT_ACTION(!busy, error = OT_ERROR_BUSY);
-
-exit:
-    return error;
 }
 
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
 {
-    int32_t   status;
-    uint32_t  busy = 1;
-    uint32_t *data;
-    uint32_t  size = 0;
+    OT_UNUSED_VARIABLE(aInstance);
 
-    otEXPECT_ACTION(((aAddress + aSize) < utilsFlashGetSize()) && (!(aAddress & 3)) && (!(aSize & 3)), aSize = 0);
+    uint32_t *data = (uint32_t *)(aData);
 
-    data = (uint32_t *)(aData);
-
-    while (size < aSize)
+    for (uint32_t size = 0; size < aSize; size += sizeof(uint32_t), aOffset += sizeof(uint32_t), data++)
     {
-        status = ROM_ProgramFlash(data, flashPhysAddr(aAddress), 4);
+        ROM_ProgramFlash(data, flashPhysAddr(aSwapIndex, aOffset), sizeof(uint32_t));
 
-        while (busy)
+        while (HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY)
         {
-            busy = HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY;
         }
-
-        otEXPECT(romStatusToThread(status) == OT_ERROR_NONE);
-        size += 4;
-        data++;
-        aAddress += 4;
     }
-
-exit:
-    return size;
 }
 
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, uint8_t *aData, uint32_t aSize)
 {
-    uint32_t size = 0;
+    OT_UNUSED_VARIABLE(aInstance);
 
-    otEXPECT((aAddress + aSize) < utilsFlashGetSize());
-
-    while (size < aSize)
-    {
-        uint8_t *byte     = (uint8_t *)flashPhysAddr(aAddress);
-        uint8_t  maxIndex = 4;
-
-        if (size == (aSize - aSize % 4))
-        {
-            maxIndex = aSize % 4;
-        }
-
-        for (uint8_t index = 0; index < maxIndex; index++, byte++, aData++)
-        {
-            *aData = *byte;
-        }
-
-        size += maxIndex;
-        aAddress += maxIndex;
-    }
-
-exit:
-    return size;
+    memcpy(aData, (void *)flashPhysAddr(aSwapIndex, aOffset), aSize);
 }
diff --git a/examples/platforms/cc2538/logging.c b/examples/platforms/cc2538/logging.c
index 4d3023e..82158ae 100644
--- a/examples/platforms/cc2538/logging.c
+++ b/examples/platforms/cc2538/logging.c
@@ -37,8 +37,7 @@
 #include <openthread/platform/logging.h>
 #include <openthread/platform/toolchain.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
 {
     OT_UNUSED_VARIABLE(aLogLevel);
diff --git a/examples/platforms/cc2538/openthread-core-cc2538-config.h b/examples/platforms/cc2538/openthread-core-cc2538-config.h
index ec7ef88..fabb6fa 100644
--- a/examples/platforms/cc2538/openthread-core-cc2538-config.h
+++ b/examples/platforms/cc2538/openthread-core-cc2538-config.h
@@ -43,62 +43,44 @@
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "CC2538"
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
  *
  * Define to 1 if you want to enable software ACK timeout logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
  *
  * Define to 1 if you want to enable software energy scanning logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 1
-
-/**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
- *
- * The actual physical address used for the cc2538 is set by the
- * linker file, the value here is "relative to the base address" set
- * in the linker file.
- *
- */
-#define SETTINGS_CONFIG_BASE_ADDRESS 0
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The CC2538 linker script sets aside 2 pages.
- *
- */
-#define SETTINGS_CONFIG_PAGE_NUM 2
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings, 2K bytes
- *
- */
-#define SETTINGS_CONFIG_PAGE_SIZE 2048
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
@@ -260,4 +242,14 @@
 #define OPENTHREAD_CONFIG_CC2592_HGM_DEFAULT_STATE true
 #endif
 
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+ *
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
+
 #endif // OPENTHREAD_CORE_CC2538_CONFIG_H_
diff --git a/examples/platforms/cc2538/radio.c b/examples/platforms/cc2538/radio.c
index 9aff8f1..cd2b351 100644
--- a/examples/platforms/cc2538/radio.c
+++ b/examples/platforms/cc2538/radio.c
@@ -875,7 +875,7 @@
     return status;
 }
 
-int8_t findSrcMatchShortEntry(const uint16_t aShortAddress)
+int8_t findSrcMatchShortEntry(uint16_t aShortAddress)
 {
     int8_t    entry = -1;
     uint16_t  shortAddr;
@@ -1036,7 +1036,7 @@
     }
 }
 
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -1086,7 +1086,7 @@
     return error;
 }
 
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
diff --git a/examples/platforms/cc2650/CMakeLists.txt b/examples/platforms/cc2650/CMakeLists.txt
new file mode 100644
index 0000000..84d7cf0
--- /dev/null
+++ b/examples/platforms/cc2650/CMakeLists.txt
@@ -0,0 +1,101 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(OT_PLATFORM_LIB "openthread-cc2650" PARENT_SCOPE)
+
+if(NOT OT_CONFIG)
+    set(OT_CONFIG "openthread-core-cc2650-config.h")
+    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES
+    "OPENTHREAD_CORE_CONFIG_PLATFORM_CHECK_FILE=\"openthread-core-cc2650-config-check.h\""
+)
+set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
+
+target_compile_definitions(ot-config INTERFACE "MBEDTLS_USER_CONFIG_FILE=\"cc2650-mbedtls-config.h\"")
+list(APPEND OT_PUBLIC_INCLUDES
+    "${CMAKE_CURRENT_SOURCE_DIR}/crypto"
+    "${PROJECT_SOURCE_DIR}/third_party/ti/devices/cc26x0"
+)
+set(OT_PUBLIC_INCLUDES ${OT_PUBLIC_INCLUDES} PARENT_SCOPE)
+
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+
+add_library(openthread-cc2650
+    alarm.c
+    cc2650_ccfg.c
+    cc2650_startup.c
+    crypto/aes_alt.c
+    crypto/sha256_alt.c
+    cxx_helpers.c
+    diag.c
+    entropy.c
+    logging.c
+    misc.c
+    radio.c
+    system.c
+    uart.c
+    $<TARGET_OBJECTS:openthread-platform-utils>
+)
+
+set_target_properties(
+    openthread-cc2650
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_link_libraries(openthread-cc2650
+    PUBLIC
+        cc26x0-driver
+    PRIVATE
+        ${OT_MBEDTLS}
+        openthread-platform-utils
+        ot-config
+)
+
+target_link_options(openthread-cc2650
+    PUBLIC
+        -Wl,--gc-sections
+        -Wl,-Map=$<TARGET_PROPERTY:NAME>.map
+)
+
+target_compile_definitions(openthread-cc2650
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-cc2650 PRIVATE ${OT_CFLAGS})
+
+target_include_directories(openthread-cc2650
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        ${PROJECT_SOURCE_DIR}/src/core
+        ${PROJECT_SOURCE_DIR}/examples/platforms
+)
diff --git a/examples/platforms/cc2650/Makefile.am b/examples/platforms/cc2650/Makefile.am
index af8dd42..db1e8b6 100644
--- a/examples/platforms/cc2650/Makefile.am
+++ b/examples/platforms/cc2650/Makefile.am
@@ -28,11 +28,11 @@
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
 
-lib_LIBRARIES                                         = libopenthread-cc2650.a
+# Do not enable -Wcast-align for this platform
+override CFLAGS    := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS  := $(filter-out -Wcast-align,$(CXXFLAGS))
 
-# Do not enable -pedantic-errors for cc26xx driverlib
-override CFLAGS                                      := $(filter-out -pedantic-errors,$(CFLAGS))
-override CXXFLAGS                                    := $(filter-out -pedantic-errors,$(CXXFLAGS))
+lib_LIBRARIES                                         = libopenthread-cc2650.a
 
 libopenthread_cc2650_a_CPPFLAGS                       = \
     -I$(top_srcdir)/include                             \
@@ -50,7 +50,6 @@
     cc2650_radio.h                                      \
     diag.c                                              \
     entropy.c                                           \
-    flash.c                                             \
     misc.c                                              \
     logging.c                                           \
     openthread-core-cc2650-config.h                     \
@@ -74,10 +73,6 @@
     $(top_srcdir)/third_party/ti/devices/cc26x0/driverlib/bin/gcc/driverlib.a \
     $(NULL)
 
-PRETTY_FILES                                          = \
-    $(PLATFORM_SOURCES)                                 \
-    $(NULL)
-
 Dash                                                  = -
 libopenthread_cc2650_a_LIBADD                         = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
diff --git a/examples/platforms/cc2650/README.md b/examples/platforms/cc2650/README.md
index 30c3ed7..98e7095 100644
--- a/examples/platforms/cc2650/README.md
+++ b/examples/platforms/cc2650/README.md
@@ -1,25 +1,14 @@
 # OpenThread on CC2650 Example
 
-This directory contains example platform drivers for the [Texas
-Instruments CC2650][cc2650].
+This directory contains example platform drivers for the [Texas Instruments CC2650][cc2650].
 
-The example platform drivers are intended to present the minimal code necessary
-to support OpenThread. As a result, the example platform drivers do not
-necessarily highlight the platform's full capabilities. The platform
-abstraction layer was build for the [CC2650 LAUNCHXL][cc2650-launchxl], usage
-on other boards with a CC2650 will require changes to the peripheral drivers.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. As a result, the example platform drivers do not necessarily highlight the platform's full capabilities. The platform abstraction layer was build for the [CC2650 LAUNCHXL][cc2650-launchxl], usage on other boards with a CC2650 will require changes to the peripheral drivers.
 
-Due to flash size limitations, some features of OpenThread are not supported on
-the [Texas Instruments CC2650][cc2650]. This platform is intended for
-exprimentation and exploration of OpenThread, not a production ready
-environment. Texas Instruments recommends future TI SoCs for production.
+Due to flash size limitations, some features of OpenThread are not supported on the [Texas Instruments CC2650][cc2650]. This platform is intended for exprimentation and exploration of OpenThread, not a production ready environment. Texas Instruments recommends future TI SoCs for production.
 
 Building with gcc 5.4 is recommended due to generated code size concerns.
 
-All three configurations were tested with `arm-none-eabi-gcc 5.4.1 20160609
-(release)` on [this commit][tested-commit]. The automatic integration builds have since
-been limited to only the `cli-mtd` configuration to limit the impact on pull
-requests.
+All three configurations were tested with `arm-none-eabi-gcc 5.4.1 20160609 (release)` on [this commit][tested-commit]. The automatic integration builds have since been limited to only the `cli-mtd` configuration to limit the impact on pull requests.
 
 [cc2650]: http://www.ti.com/product/CC2650
 [cc2650-launchxl]: http://www.ti.com/tool/Launchxl-cc2650
@@ -27,17 +16,9 @@
 
 ## Build Environment
 
-Building the examples for the cc2650 requires [GNU AutoConf][gnu-autoconf],
-[GNU AutoMake][gnu-automake], [Python][python], and the
-[ARM gcc toolchain][arm-toolchain].
+Building the examples for the cc2650 requires [GNU AutoConf][gnu-autoconf], [GNU AutoMake][gnu-automake], [Python][python], and the [ARM gcc toolchain][arm-toolchain].
 
-With the exception of the arm toolchain, most of these tools are installed by
-default on modern Posix systems. Windows does not have these tools installed by
-default, and the bootstrap script requires a Posix or MSYS environment to run.
-It is possible to setup an MSYS environment inside of Windows using tools such
-as [Cygwin][cygwin] or [MinGW][mingw] but it is recommended to setup a Linux VM
-for building on a Windows system. For help setting up VirtualBox with Ubuntu,
-consult this [community help wiki article][ubuntu-wiki-virtualbox].
+With the exception of the arm toolchain, most of these tools are installed by default on modern Posix systems. Windows does not have these tools installed by default, and the bootstrap script requires a Posix or MSYS environment to run. It is possible to setup an MSYS environment inside of Windows using tools such as [Cygwin][cygwin] or [MinGW][mingw] but it is recommended to setup a Linux VM for building on a Windows system. For help setting up VirtualBox with Ubuntu, consult this [community help wiki article][ubuntu-wiki-virtualbox].
 
 [gnu-autoconf]: https://www.gnu.org/software/autoconf
 [gnu-automake]: https://www.gnu.org/software/automake
@@ -47,8 +28,7 @@
 [mingw]: http://www.mingw.org
 [ubuntu-wiki-virtualbox]: https://help.ubuntu.com/community/VirtualBox
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -67,26 +47,23 @@
 
 ## Flash Binaries
 
-If the build completed successfully, the `elf` files may be found in
-`<path-to-openthread>/output/cc2650/bin`.
+If the build completed successfully, the `elf` files may be found in `<path-to-openthread>/output/cc2650/bin`.
 
-To flash the images with [Flash Programmer 2][ti-flash-programmer-2], the files
-must have the `*.elf` extension.
+To flash the images with [Flash Programmer 2][ti-flash-programmer-2], the files must have the `*.elf` extension.
+
 ```bash
 $ cd <path-to-openthread>/output/cc2650/bin
 $ cp ot-cli ot-cli.elf
 ```
 
-To load the images with the [serial bootloader][ti-cc2650-bootloader], the
-images must be converted to `bin`. This is done using `arm-none-eabi-objcopy`
+To load the images with the [serial bootloader][ti-cc2650-bootloader], the images must be converted to `bin`. This is done using `arm-none-eabi-objcopy`
+
 ```bash
 $ cd <path-to-openthread>/output/cc2650/bin
 $ arm-none-eabi-objcopy -O binary ot-cli ot-cli.bin
 ```
-The [cc2538-bsl.py script][cc2538-bsl-tool] provides a convenient method
-for flashing a CC2650 via the UART. To enter the bootloader backdoor for flashing,
-hold down BTN-1 on CC2650 LauchPad or SELECT for CC2650DK (corresponds to logic '0')
-while you press the Reset button.
+
+The [cc2538-bsl.py script][cc2538-bsl-tool] provides a convenient method for flashing a CC2650 via the UART. To enter the bootloader backdoor for flashing, hold down BTN-1 on CC2650 LauchPad or SELECT for CC2650DK (corresponds to logic '0') while you press the Reset button.
 
 [ti-flash-programmer-2]: http://www.ti.com/tool/flash-programmer
 [ti-cc2650-bootloader]: http://www.ti.com/lit/an/swra466a/swra466a.pdf
@@ -96,15 +73,13 @@
 
 ### CLI example
 
-1. With a terminal client (putty, minicom, etc.) open the com port associated
-   with the cc2650 UART. The serial port settings are:
-    * 115200 baud
-    * 8 data bits
-    * no parity bit
-    * 1 stop bit
+1. With a terminal client (putty, minicom, etc.) open the com port associated with the cc2650 UART. The serial port settings are:
+   - 115200 baud
+   - 8 data bits
+   - no parity bit
+   - 1 stop bit
 2. Type `help` for a list of commands
-3. follow the instructions in the [CLI README][cli-readme] for instructions on
-   setting up a network
+3. follow the instructions in the [CLI README][cli-readme] for instructions on setting up a network
 
 [cli-readme]: ../../../src/cli/README.md
 
@@ -140,7 +115,6 @@
 
 ### NCP example
 
-Refer to the documentation in the [wpantund][wpantund] project for build
-instructions and usage information.
+Refer to the documentation in the [wpantund][wpantund] project for build instructions and usage information.
 
 [wpantund]: https://github.com/openthread/wpantund
diff --git a/examples/platforms/cc2650/arm-none-eabi.cmake b/examples/platforms/cc2650/arm-none-eabi.cmake
new file mode 100644
index 0000000..c889e39
--- /dev/null
+++ b/examples/platforms/cc2650/arm-none-eabi.cmake
@@ -0,0 +1,50 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(CMAKE_SYSTEM_NAME              Generic)
+set(CMAKE_SYSTEM_PROCESSOR         ARM)
+
+set(CMAKE_C_COMPILER               arm-none-eabi-gcc)
+set(CMAKE_CXX_COMPILER             arm-none-eabi-g++)
+set(CMAKE_ASM_COMPILER             arm-none-eabi-as)
+set(CMAKE_RANLIB                   arm-none-eabi-ranlib)
+
+set(COMMON_C_FLAGS                 "-mthumb -fdata-sections -ffunction-sections -mcpu=cortex-m3 -mfloat-abi=soft")
+
+set(CMAKE_C_FLAGS                  "${COMMON_C_FLAGS} -std=gnu99")
+set(CMAKE_CXX_FLAGS                "${COMMON_C_FLAGS} -fno-exceptions -fno-rtti")
+set(CMAKE_ASM_FLAGS                "${COMMON_C_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS_INIT    "${COMMON_C_FLAGS} -specs=nano.specs -specs=nosys.specs -nostartfiles")
+
+set(CMAKE_C_FLAGS_DEBUG            "-Og -g")
+set(CMAKE_CXX_FLAGS_DEBUG          "-Og -g")
+set(CMAKE_ASM_FLAGS_DEBUG          "-g")
+
+set(CMAKE_C_FLAGS_RELEASE          "-Os")
+set(CMAKE_CXX_FLAGS_RELEASE        "-Os")
+set(CMAKE_ASM_FLAGS_RELEASE        "")
diff --git a/examples/platforms/cc2650/crypto/aes_alt.h b/examples/platforms/cc2650/crypto/aes_alt.h
index e809cd9..299c85b 100644
--- a/examples/platforms/cc2650/crypto/aes_alt.h
+++ b/examples/platforms/cc2650/crypto/aes_alt.h
@@ -70,8 +70,7 @@
  *
  * \return         0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
  */
-int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
-                           unsigned int keybits);
+int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits);
 
 /**
  * \brief          AES key schedule (decryption)
@@ -82,8 +81,7 @@
  *
  * \return         0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
  */
-int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
-                           unsigned int keybits);
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits);
 
 /**
  * \brief          AES-ECB block encryption/decryption
@@ -95,8 +93,7 @@
  *
  * \return         0 if successful
  */
-int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16],
-                          unsigned char output[16]);
+int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16]);
 
 #ifdef __cplusplus
 }
diff --git a/examples/platforms/cc2650/diag.c b/examples/platforms/cc2650/diag.c
index 95973df..50d20d9 100644
--- a/examples/platforms/cc2650/diag.c
+++ b/examples/platforms/cc2650/diag.c
@@ -44,17 +44,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    // Add more platform specific diagnostics features here.
-    if (argc > 1)
-    {
-        snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-    }
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/cc2650/flash.c b/examples/platforms/cc2650/flash.c
deleted file mode 100644
index 2b40af7..0000000
--- a/examples/platforms/cc2650/flash.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Copyright (c) 2017, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-cc2650.h"
-
-#include <openthread/error.h>
-
-/**
- * @warning this file only implements stubs for the function calls. There is
- * not enough space on the cc2650 to support NV as an SoC.
- */
-
-otError utilsFlashInit(void)
-{
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-uint32_t utilsFlashGetSize(void)
-{
-    return 0;
-}
-
-otError utilsFlashErasePage(uint32_t aAddress)
-{
-    OT_UNUSED_VARIABLE(aAddress);
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    OT_UNUSED_VARIABLE(aTimeout);
-    return OT_ERROR_NONE;
-}
-
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    OT_UNUSED_VARIABLE(aAddress);
-    OT_UNUSED_VARIABLE(aData);
-    OT_UNUSED_VARIABLE(aSize);
-    return 0;
-}
-
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    OT_UNUSED_VARIABLE(aAddress);
-    OT_UNUSED_VARIABLE(aData);
-    OT_UNUSED_VARIABLE(aSize);
-    return 0;
-}
diff --git a/examples/platforms/cc2650/logging.c b/examples/platforms/cc2650/logging.c
index de5a469..c9a9a3b 100644
--- a/examples/platforms/cc2650/logging.c
+++ b/examples/platforms/cc2650/logging.c
@@ -36,8 +36,7 @@
 #include <openthread/platform/logging.h>
 #include <openthread/platform/toolchain.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
 {
     OT_UNUSED_VARIABLE(aLogLevel);
diff --git a/examples/platforms/cc2650/openthread-core-cc2650-config.h b/examples/platforms/cc2650/openthread-core-cc2650-config.h
index acaf516..31d2fb1 100644
--- a/examples/platforms/cc2650/openthread-core-cc2650-config.h
+++ b/examples/platforms/cc2650/openthread-core-cc2650-config.h
@@ -52,4 +52,12 @@
  */
 #define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1
 
+/**
+ * @def OPENTHREAD_SETTINGS_RAM
+ *
+ * Define as 1 to enable saving the settings in RAM instead of flash.
+ *
+ */
+#define OPENTHREAD_SETTINGS_RAM 1
+
 #endif /* OPENTHREAD_CORE_CC2650_CONFIG_H_ */
diff --git a/examples/platforms/cc2650/radio.c b/examples/platforms/cc2650/radio.c
index 6d3628d..09d45d6 100644
--- a/examples/platforms/cc2650/radio.c
+++ b/examples/platforms/cc2650/radio.c
@@ -32,6 +32,7 @@
 #include "cc2650_radio.h"
 #include <assert.h>
 #include <utils/code_utils.h>
+#include <utils/encoding.h>
 #include <openthread/random_noncrypto.h> /* to seed the CSMA-CA funciton */
 #include <openthread/platform/alarm-milli.h>
 #include <openthread/platform/diag.h>
@@ -431,7 +432,7 @@
  * @return The index where the address was found.
  * @retval CC2650_SRC_MATCH_NONE The address was not found.
  */
-static uint8_t rfCoreFindShortSrcMatchIdx(const uint16_t aAddress)
+static uint8_t rfCoreFindShortSrcMatchIdx(uint16_t aAddress)
 {
     uint8_t i;
     uint8_t ret = CC2650_SRC_MATCH_NONE;
@@ -1459,7 +1460,7 @@
 /**
  * Function documented in platform/radio.h
  */
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -1493,7 +1494,7 @@
 /**
  * Function documented in platform/radio.h
  */
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -1528,7 +1529,7 @@
     OT_UNUSED_VARIABLE(aInstance);
 
     otError  error      = OT_ERROR_NONE;
-    uint64_t extAddress = *(uint64_t *)aExtAddress;
+    uint64_t extAddress = otEncodingReadUint64Le(aExtAddress->m8);
     uint8_t  idx        = rfCoreFindExtSrcMatchIdx(&extAddress);
 
     if (idx == CC2650_SRC_MATCH_NONE)
@@ -1562,7 +1563,7 @@
     OT_UNUSED_VARIABLE(aInstance);
 
     otError  error      = OT_ERROR_NONE;
-    uint64_t extAddress = *(uint64_t *)aExtAddress;
+    uint64_t extAddress = otEncodingReadUint64Le(aExtAddress->m8);
     uint8_t  idx;
 
     otEXPECT_ACTION((idx = rfCoreFindExtSrcMatchIdx(&extAddress)) != CC2650_SRC_MATCH_NONE,
@@ -1761,7 +1762,7 @@
     if (sState == cc2650_stateReceive)
     {
         otEXPECT(rfCoreExecuteAbortCmd() == CMDSTA_Done);
-        sReceiveCmd.localExtAddr = *((uint64_t *)(aAddress));
+        sReceiveCmd.localExtAddr = otEncodingReadUint64Le(aAddress->m8);
         otEXPECT(rfCoreClearReceiveQueue(&sRxDataQueue) == CMDSTA_Done);
         otEXPECT(rfCoreSendReceiveCmd() == CMDSTA_Done);
         /* the interrupt from abort changed our state to sleep */
@@ -1769,7 +1770,7 @@
     }
     else if (sState != cc2650_stateTransmit)
     {
-        sReceiveCmd.localExtAddr = *((uint64_t *)(aAddress));
+        sReceiveCmd.localExtAddr = otEncodingReadUint64Le(aAddress->m8);
     }
 
 exit:
diff --git a/examples/platforms/cc2652/CMakeLists.txt b/examples/platforms/cc2652/CMakeLists.txt
new file mode 100644
index 0000000..ddd4e24
--- /dev/null
+++ b/examples/platforms/cc2652/CMakeLists.txt
@@ -0,0 +1,102 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(OT_PLATFORM_LIB "openthread-cc2652" PARENT_SCOPE)
+
+if(NOT OT_CONFIG)
+    set(OT_CONFIG "openthread-core-cc2652-config.h")
+    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES
+    "OPENTHREAD_CORE_CONFIG_PLATFORM_CHECK_FILE=\"openthread-core-cc2652-config-check.h\""
+)
+set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
+
+target_compile_definitions(ot-config INTERFACE "MBEDTLS_USER_CONFIG_FILE=\"cc2652-mbedtls-config.h\"")
+
+list(APPEND OT_PUBLIC_INCLUDES
+    "${CMAKE_CURRENT_SOURCE_DIR}/crypto"
+    "${PROJECT_SOURCE_DIR}/third_party/ti/devices/cc13x2_cc26x2"
+)
+set(OT_PUBLIC_INCLUDES ${OT_PUBLIC_INCLUDES} PARENT_SCOPE)
+
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+
+add_library(openthread-cc2652
+    alarm.c
+    cc2652_ccfg.c
+    cc2652_startup.c
+    crypto/aes_alt.c
+    cxx_helpers.c
+    diag.c
+    entropy.c
+    flash.c
+    logging.c
+    misc.c
+    radio.c
+    system.c
+    uart.c
+)
+
+set_target_properties(
+    openthread-cc2652
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_link_libraries(openthread-cc2652
+    PUBLIC
+        cc13x2-cc26x2-driver
+    PRIVATE
+        ${OT_MBEDTLS}
+        ot-config
+)
+
+target_link_options(openthread-cc2652
+    PUBLIC
+        -Wl,--gc-sections
+)
+
+target_compile_definitions(openthread-cc2652
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-cc2652
+    PRIVATE
+        ${OT_CFLAGS}
+)
+
+target_include_directories(openthread-cc2652
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        ${PROJECT_SOURCE_DIR}/src/core
+        ${PROJECT_SOURCE_DIR}/examples/platforms
+)
diff --git a/examples/platforms/cc2652/Makefile.am b/examples/platforms/cc2652/Makefile.am
index 7dfe572..03e2720 100644
--- a/examples/platforms/cc2652/Makefile.am
+++ b/examples/platforms/cc2652/Makefile.am
@@ -28,11 +28,11 @@
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
 
-lib_LIBRARIES = libopenthread-cc2652.a
+# Do not enable -Wcast-align for this platform
+override CFLAGS    := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS  := $(filter-out -Wcast-align,$(CXXFLAGS))
 
-# Do not enable -pedantic-errors for cc26xx driverlib
-override CFLAGS   := $(filter-out -pedantic-errors,$(CFLAGS))
-override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
+lib_LIBRARIES = libopenthread-cc2652.a
 
 libopenthread_cc2652_a_CPPFLAGS                                                         = \
     -I$(top_srcdir)/include                                                               \
@@ -73,10 +73,6 @@
     $(top_srcdir)/third_party/ti/devices/cc13x2_cc26x2/driverlib/bin/gcc/driverlib.a      \
     $(NULL)
 
-PRETTY_FILES                                                                            = \
-    $(PLATFORM_SOURCES)                                                                   \
-    $(NULL)
-
 Dash = -
 libopenthread_cc2652_a_LIBADD                                                           = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
diff --git a/examples/platforms/cc2652/README.md b/examples/platforms/cc2652/README.md
index 613ce51..edb2c79 100644
--- a/examples/platforms/cc2652/README.md
+++ b/examples/platforms/cc2652/README.md
@@ -1,34 +1,24 @@
 # OpenThread on CC2652 Example
 
-This directory contains example platform drivers for the [Texas Instruments
-CC2652R1][cc2652r1].
+This directory contains example platform drivers for the [Texas Instruments CC2652R1][cc2652r1].
 
-The example platform drivers are intended to present the minimal code necessary
-to support OpenThread. As a result, the example platform drivers do not
-necessarily highlight the platform's full capabilities. Consult the [SimpleLink
-CC26X2R1 SDK][cc26x2r1-sdk] for more development option. The platform drivers
-were built for the [CC2652R1 LAUNCHXL][cc2652r1-launchxl], usage on other
-boards with a cc2652r1 may require changes to the peripheral drivers.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. As a result, the example platform drivers do not necessarily highlight the platform's full capabilities. Consult the [SimpleLink CC26X2R1 SDK][cc26x2r1-sdk] for more development option. The platform drivers were built for the [CC2652R1 LAUNCHXL][cc2652r1-launchxl], usage on other boards with a cc2652r1 may require changes to the peripheral drivers.
 
 [cc2652r1-launchxl]: http://www.ti.com/tool/launchxl-cc26x2r1
 [cc26x2r1-sdk]: http://www.ti.com/tool/simplelink-cc26x2-sdk
+
 <!---
 TODO: Update link when cc2652 product page is live
 [cc2652r1]: http://www.ti.com/product/cc2652r1
 -->
+
 [cc2652r1]: http://www.ti.com/tool/launchxl-cc26x2r1
 
 ## Toolchain
 
-Building the examples for the cc2652 requires [GNU AutoConf][gnu-autoconf],
-[GNU AutoMake][gnu-automake], [Python][python], and the [ARM gcc
-toolchain][arm-toolchain].
+Building the examples for the cc2652 requires [GNU AutoConf][gnu-autoconf], [GNU AutoMake][gnu-automake], [Python][python], and the [ARM gcc toolchain][arm-toolchain].
 
-With the exception of the arm toolchain, most of these tools are installed by
-default on modern Posix systems. It is recommended to setup a Linux virtual
-machine for building on a Windows host system. For help setting up VirtualBox
-with Ubuntu, consult this [community help wiki
-article][ubuntu-wiki-virtualbox].
+With the exception of the arm toolchain, most of these tools are installed by default on modern Posix systems. It is recommended to setup a Linux virtual machine for building on a Windows host system. For help setting up VirtualBox with Ubuntu, consult this [community help wiki article][ubuntu-wiki-virtualbox].
 
 [gnu-autoconf]: https://www.gnu.org/software/autoconf
 [gnu-automake]: https://www.gnu.org/software/automake
@@ -38,8 +28,7 @@
 [mingw]: http://www.mingw.org
 [ubuntu-wiki-virtualbox]: https://help.ubuntu.com/community/VirtualBox
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -58,11 +47,9 @@
 
 ## Flash Binaries
 
-If the build completed successfully, the `elf` files may be found in
-`<path-to-openthread>/output/cc2652/bin`.
+If the build completed successfully, the `elf` files may be found in `<path-to-openthread>/output/cc2652/bin`.
 
-Flash the images with [Uniflash][uniflash]. Make sure to deselect the binary
-check-box, Uniflash assumes a file without an extension is a binary file.
+Flash the images with [Uniflash][uniflash]. Make sure to deselect the binary check-box, Uniflash assumes a file without an extension is a binary file.
 
 [uniflash]: http://www.ti.com/tool/uniflash
 
@@ -70,15 +57,13 @@
 
 ### CLI example
 
-1. With a terminal client (PuTTY, minicom, etc.) open the com port associated
-   with the cc2652 UART. The serial port settings are:
-    * 115200 baud
-    * 8 data bits
-    * no parity bit
-    * 1 stop bit
+1. With a terminal client (PuTTY, minicom, etc.) open the com port associated with the cc2652 UART. The serial port settings are:
+   - 115200 baud
+   - 8 data bits
+   - no parity bit
+   - 1 stop bit
 2. Type `help` for a list of commands.
-3. Follow the instructions in the [CLI README][cli-readme] for instructions on
-   setting up a network.
+3. Follow the instructions in the [CLI README][cli-readme] for instructions on setting up a network.
 
 [cli-readme]: ../../../src/cli/README.md
 
@@ -114,7 +99,6 @@
 
 ### NCP example
 
-Refer to the documentation in the [wpantund][wpantund] project for build
-instructions and usage information.
+Refer to the documentation in the [wpantund][wpantund] project for build instructions and usage information.
 
 [wpantund]: https://github.com/openthread/wpantund
diff --git a/examples/platforms/cc2652/arm-none-eabi.cmake b/examples/platforms/cc2652/arm-none-eabi.cmake
new file mode 100644
index 0000000..bd81b36
--- /dev/null
+++ b/examples/platforms/cc2652/arm-none-eabi.cmake
@@ -0,0 +1,50 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(CMAKE_SYSTEM_NAME              Generic)
+set(CMAKE_SYSTEM_PROCESSOR         ARM)
+
+set(CMAKE_C_COMPILER               arm-none-eabi-gcc)
+set(CMAKE_CXX_COMPILER             arm-none-eabi-g++)
+set(CMAKE_ASM_COMPILER             arm-none-eabi-as)
+set(CMAKE_RANLIB                   arm-none-eabi-ranlib)
+
+set(COMMON_C_FLAGS                 "-mcpu=cortex-m4 -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -fdata-sections -ffunction-sections")
+
+set(CMAKE_C_FLAGS                  "${COMMON_C_FLAGS} -std=gnu99")
+set(CMAKE_CXX_FLAGS                "${COMMON_C_FLAGS} -fno-exceptions -fno-rtti")
+set(CMAKE_ASM_FLAGS                "${COMMON_C_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS_INIT    "${COMMON_C_FLAGS} -nostartfiles -specs=nano.specs -specs=nosys.specs -Wl,-Map=map.map")
+
+set(CMAKE_C_FLAGS_DEBUG            "-Og -g")
+set(CMAKE_CXX_FLAGS_DEBUG          "-Og -g")
+set(CMAKE_ASM_FLAGS_DEBUG          "-g")
+
+set(CMAKE_C_FLAGS_RELEASE          "-Os")
+set(CMAKE_CXX_FLAGS_RELEASE        "-Os")
+set(CMAKE_ASM_FLAGS_RELEASE        "")
diff --git a/examples/platforms/cc2652/crypto/aes_alt.h b/examples/platforms/cc2652/crypto/aes_alt.h
index 1f330ea..7de12e2 100644
--- a/examples/platforms/cc2652/crypto/aes_alt.h
+++ b/examples/platforms/cc2652/crypto/aes_alt.h
@@ -71,8 +71,7 @@
  * @retval 0                                   If successful
  * @retval MBEDTLS_ERR_AES_INVALID_KEY_LENGTH  If keybits was not 128
  */
-int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
-                           unsigned int keybits);
+int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits);
 
 /**
  * @brief          AES key schedule (decryption)
@@ -84,8 +83,7 @@
  * @retval 0                                   If successful
  * @retval MBEDTLS_ERR_AES_INVALID_KEY_LENGTH  If keybits was not 128
  */
-int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
-                           unsigned int keybits);
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits);
 
 /**
  * \brief          AES-ECB block encryption/decryption
@@ -99,8 +97,7 @@
  * @retval 0                        If successful
  * @retval AES_KEYSTORE_READ_ERROR  If the indicated keystore ram could not be read
  */
-int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16],
-                          unsigned char output[16]);
+int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16]);
 
 #ifdef __cplusplus
 }
diff --git a/examples/platforms/cc2652/diag.c b/examples/platforms/cc2652/diag.c
index c530964..fe2a538 100644
--- a/examples/platforms/cc2652/diag.c
+++ b/examples/platforms/cc2652/diag.c
@@ -46,17 +46,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    // Add more platform specific diagnostics features here.
-    if (argc > 1)
-    {
-        snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-    }
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/cc2652/flash.c b/examples/platforms/cc2652/flash.c
index aa95501..26e6f9c 100644
--- a/examples/platforms/cc2652/flash.c
+++ b/examples/platforms/cc2652/flash.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2018, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -28,43 +28,21 @@
 
 #include <string.h>
 
+#include <openthread/instance.h>
+
 #include <driverlib/aon_batmon.h>
 #include <driverlib/flash.h>
 #include <driverlib/interrupt.h>
 #include <driverlib/vims.h>
 
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-#include <openthread/platform/alarm-milli.h>
-
 #include <utils/code_utils.h>
 
 #include "platform-cc2652.h"
 
-/*
- * The settings configuration base address *MUST* be defined in the core config
- * file. The base address *MUST* be aligned on an 8K page boundary or the flash
- * program calls will fail.
- */
-#ifndef SETTINGS_CONFIG_BASE_ADDRESS
-#error "SETTINGS_CONFIG_BASE_ADDRESS not defined in the OpenThread Core Config"
-#endif /* SETTINGS_CONFIG_BASE_ADDRESS */
-
-/*
- * The settings configuration page size *MUST* be defined in the core config
- * file. The page size *MUST* be 8K or the flash program calls will fail.
- */
-#if (SETTINGS_CONFIG_PAGE_SIZE != 0x2000)
-#error "SETTINGS_CONFIG_PAGE_SIZE must be defined in OpenThread Core Config"
-#endif
-
-/*
- * The settings configuration page number _SHOULD_ be defined in the core
- * config file.
- */
-#ifndef SETTINGS_CONFIG_PAGE_NUM
-#warn "SETTINGS_CONFIG_PAGE_NUM not defined in the OpenThread Core Config"
-#endif /* SETTINGS_CONFIG_PAGE_NUM */
+#define FLASH_BASE_ADDRESS 0x52000
+#define FLASH_PAGE_SIZE 0x2000
+#define FLASH_PAGE_NUM 2 /* must be a multiple of 2 */
+#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * (FLASH_PAGE_NUM / 2))
 
 enum
 {
@@ -158,117 +136,87 @@
     VIMSLineBufEnable(VIMS_BASE);
 }
 
-/**
- * Translate the errors from the Flash programming FSM to OpenThread error
- * codes.
- *
- * @param [in] error Return from the Flash programming function.
- *
- * @return The corresponding OpenThread @ref otError value.
- */
-static otError fsmErrorToOtError(uint32_t error)
+static uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    otError ret = OT_ERROR_GENERIC;
+    uint32_t address = FLASH_BASE_ADDRESS + aOffset;
 
-    switch (error)
+    if (aSwapIndex)
     {
-    case FAPI_STATUS_SUCCESS:
-        ret = OT_ERROR_NONE;
-        break;
-
-    case FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH:
-        ret = OT_ERROR_INVALID_ARGS;
-        break;
-
-    case FAPI_STATUS_FSM_ERROR:
-        ret = OT_ERROR_FAILED;
-        break;
-
-    default:
-        break;
+        address += FLASH_SWAP_SIZE;
     }
 
-    return ret;
+    return address;
 }
 
 /**
  * Function documented in platforms/utils/flash.h
  */
-otError utilsFlashInit(void)
+void otPlatFlashInit(otInstance *aInstance)
 {
-    return OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
 }
 
 /**
  * Function documented in platforms/utils/flash.h
  */
-uint32_t utilsFlashGetSize(void)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
 {
-    return FlashSizeGet();
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return FLASH_SWAP_SIZE;
 }
 
 /**
  * Function documented in platforms/utils/flash.h
  */
-otError utilsFlashErasePage(uint32_t aAddress)
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
 {
+    OT_UNUSED_VARIABLE(aInstance);
+
     uint32_t mode;
-    uint32_t fsmRet;
-    otError  ret;
-
-    otEXPECT_ACTION(checkVoltage(), ret = OT_ERROR_FAILED);
-
-    mode = disableFlashCache();
-
-    fsmRet = FlashSectorErase(aAddress);
-
-    restoreFlashCache(mode);
-
-    ret = fsmErrorToOtError(fsmRet);
-
-exit:
-    return ret;
-}
-
-/**
- * Function documented in platforms/utils/flash.h
- */
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    uint32_t start = otPlatAlarmMilliGetNow();
-    otError  ret   = OT_ERROR_BUSY;
-
-    while ((otPlatAlarmMilliGetNow() - start) < aTimeout)
-    {
-        if (FlashCheckFsmForReady() == FAPI_STATUS_FSM_READY)
-        {
-            ret = OT_ERROR_NONE;
-            break;
-        }
-    }
-
-    return ret;
-}
-
-/**
- * Function documented in platforms/utils/flash.h
- */
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t mode;
-    uint32_t written = 0;
 
     otEXPECT(checkVoltage());
 
     mode = disableFlashCache();
 
+    for (uint8_t page = 0; page < FLASH_PAGE_NUM; page++)
+    {
+        FlashSectorErase(mapAddress(aSwapIndex, (page * FLASH_PAGE_SIZE)));
+    }
+
+    restoreFlashCache(mode);
+
+    while (FlashCheckFsmForReady() != FAPI_STATUS_FSM_READY)
+    {
+    }
+
+exit:
+    return;
+}
+
+/**
+ * Function documented in platforms/utils/flash.h
+ */
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t mode;
+    uint32_t written = 0;
+    uint32_t address;
+
+    otEXPECT(checkVoltage());
+
+    mode = disableFlashCache();
+
+    address = mapAddress(aSwapIndex, aOffset);
+
     while (written < aSize)
     {
-        uint32_t toWrite = aSize - written;
-        uint8_t *data    = aData + written;
-        uint32_t address = aAddress + written;
-        uint32_t fsmRet;
-        bool     interruptsWereDisabled;
+        uint32_t       toWrite = aSize - written;
+        const uint8_t *data    = (uint8_t *)aData + written;
+        uint32_t       fsmRet;
+        bool           interruptsWereDisabled;
 
         if (toWrite > MAX_WRITE_INCREMENT)
         {
@@ -281,7 +229,7 @@
          */
         interruptsWereDisabled = IntMasterDisable();
 
-        fsmRet = FlashProgram(data, address, toWrite);
+        fsmRet = FlashProgram((uint8_t *)data, address + written, toWrite);
 
         if (!interruptsWereDisabled)
         {
@@ -299,15 +247,15 @@
     restoreFlashCache(mode);
 
 exit:
-    return written;
+    return;
 }
 
 /**
  * Function documented in platforms/utils/flash.h
  */
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
 {
-    memcpy(aData, (void *)aAddress, (size_t)aSize);
+    OT_UNUSED_VARIABLE(aInstance);
 
-    return aSize;
+    memcpy(aData, (void *)mapAddress(aSwapIndex, aOffset), (size_t)aSize);
 }
diff --git a/examples/platforms/cc2652/logging.c b/examples/platforms/cc2652/logging.c
index de5a469..c9a9a3b 100644
--- a/examples/platforms/cc2652/logging.c
+++ b/examples/platforms/cc2652/logging.c
@@ -36,8 +36,7 @@
 #include <openthread/platform/logging.h>
 #include <openthread/platform/toolchain.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
 {
     OT_UNUSED_VARIABLE(aLogLevel);
diff --git a/examples/platforms/cc2652/openthread-core-cc2652-config.h b/examples/platforms/cc2652/openthread-core-cc2652-config.h
index 2e2113b..352c322 100644
--- a/examples/platforms/cc2652/openthread-core-cc2652-config.h
+++ b/examples/platforms/cc2652/openthread-core-cc2652-config.h
@@ -38,27 +38,14 @@
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "CC2652"
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of the pages to be used for non-volatile-settings storage.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
+ *
  */
-#define SETTINGS_CONFIG_BASE_ADDRESS (0x52000)
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The size in bytes of a page for the cc26x2 platform.
- *
- * @note *MUST BE* 8K.
- */
-#define SETTINGS_CONFIG_PAGE_SIZE (0x2000)
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The number of flash pages to use for non-volatile settings storage.
- */
-#define SETTINGS_CONFIG_PAGE_NUM (2)
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
diff --git a/examples/platforms/cc2652/radio.c b/examples/platforms/cc2652/radio.c
index f6b4712..345c234 100644
--- a/examples/platforms/cc2652/radio.c
+++ b/examples/platforms/cc2652/radio.c
@@ -37,6 +37,7 @@
 
 #include <assert.h>
 #include <utils/code_utils.h>
+#include <utils/encoding.h>
 #include <openthread/random_noncrypto.h> /* to seed the CSMA-CA funciton */
 #include <openthread/platform/alarm-milli.h>
 #include <openthread/platform/diag.h>
@@ -456,7 +457,7 @@
  * @return The index where the address was found.
  * @retval CC2652_SRC_MATCH_NONE The address was not found.
  */
-static uint8_t rfCoreFindShortSrcMatchIdx(const uint16_t aAddress)
+static uint8_t rfCoreFindShortSrcMatchIdx(uint16_t aAddress)
 {
     uint8_t i;
     uint8_t ret = CC2652_SRC_MATCH_NONE;
@@ -1489,7 +1490,7 @@
 /**
  * Function documented in platform/radio.h
  */
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -1523,7 +1524,7 @@
 /**
  * Function documented in platform/radio.h
  */
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -1558,7 +1559,7 @@
     OT_UNUSED_VARIABLE(aInstance);
 
     otError  error      = OT_ERROR_NONE;
-    uint64_t extAddress = *(uint64_t *)aExtAddress;
+    uint64_t extAddress = otEncodingReadUint64Le(aExtAddress->m8);
     uint8_t  idx        = rfCoreFindExtSrcMatchIdx(&extAddress);
 
     if (idx == CC2652_SRC_MATCH_NONE)
@@ -1592,7 +1593,7 @@
     OT_UNUSED_VARIABLE(aInstance);
 
     otError  error      = OT_ERROR_NONE;
-    uint64_t extAddress = *(uint64_t *)aExtAddress;
+    uint64_t extAddress = otEncodingReadUint64Le(aExtAddress->m8);
     uint8_t  idx;
 
     otEXPECT_ACTION((idx = rfCoreFindExtSrcMatchIdx(&extAddress)) != CC2652_SRC_MATCH_NONE,
@@ -1793,7 +1794,7 @@
     if (sState == cc2652_stateReceive)
     {
         otEXPECT(rfCoreExecuteAbortCmd() == CMDSTA_Done);
-        sReceiveCmd.localExtAddr = *((uint64_t *)(aAddress));
+        sReceiveCmd.localExtAddr = otEncodingReadUint64Le(aAddress->m8);
         otEXPECT(rfCoreClearReceiveQueue(&sRxDataQueue) == CMDSTA_Done);
         otEXPECT(rfCoreSendReceiveCmd() == CMDSTA_Done);
         /* the interrupt from abort changed our state to sleep */
@@ -1801,7 +1802,7 @@
     }
     else if (sState != cc2652_stateTransmit)
     {
-        sReceiveCmd.localExtAddr = *((uint64_t *)(aAddress));
+        sReceiveCmd.localExtAddr = otEncodingReadUint64Le(aAddress->m8);
     }
 
 exit:
diff --git a/examples/platforms/efr32mg1/Makefile.am b/examples/platforms/efr32mg1/Makefile.am
new file mode 100644
index 0000000..c50b01a
--- /dev/null
+++ b/examples/platforms/efr32mg1/Makefile.am
@@ -0,0 +1,140 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+
+lib_LIBRARIES = libopenthread-efr32mg1.a
+
+# Do not enable -Wconversion for rail
+override CFLAGS   := $(filter-out -Wconversion,$(CFLAGS))
+override CXXFLAGS := $(filter-out -Wconversion,$(CXXFLAGS))
+
+# Do not enable -pedantic-errors for rail
+override CFLAGS   := $(filter-out -pedantic-errors,$(CFLAGS))
+override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
+
+# Do not enable -Wundef for rail
+override CFLAGS   := $(filter-out -Wundef,$(CFLAGS))
+override CXXFLAGS := $(filter-out -Wundef,$(CXXFLAGS))
+
+EFR32_BOARD_DIR = $(shell echo $(BOARD) | tr A-Z a-z)
+
+SDK_SRC_DIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7
+
+libopenthread_efr32mg1_a_CPPFLAGS                                             = \
+    -DPLATFORM_HEADER=\"platform/base/hal/micro/cortexm3/compiler/gcc.h\"       \
+    -DNVIC_CONFIG=\"platform/base/hal/micro/cortexm3/efm32/nvic-config.h\"      \
+    -Wno-sign-compare                                                           \
+    -DCORTEXM3                                                                  \
+    -DPHY=EMBER_PHY_RAIL                                                        \
+    -DMICRO=EMBER_MICRO_CORTEXM3_EFR32                                          \
+    -DCORTEXM3_EFM32_MICRO                                                      \
+    -DPLAT=EMBER_PLATFORM_CORTEXM3                                              \
+    -I$(top_srcdir)/examples/platforms                                          \
+    -I$(top_srcdir)/examples/platforms/efr32mg1/$(EFR32_BOARD_DIR)              \
+    -I$(top_srcdir)/include                                                     \
+    -I$(top_srcdir)/src/core                                                    \
+    -I$(top_srcdir)/third_party/silabs/rail_config                              \
+    -I$(SDK_SRC_DIR)                                                            \
+    -I$(SDK_SRC_DIR)/hardware/kit/common/bsp                                    \
+    -I$(SDK_SRC_DIR)/hardware/kit/common/drivers                                \
+    -I$(SDK_SRC_DIR)/hardware/kit/EFR32MG1_$(BOARD)/config                      \
+    -I$(SDK_SRC_DIR)/platform/base/hal/micro/cortexm3/efm32                     \
+    -I$(SDK_SRC_DIR)/platform/base/hal/micro/cortexm3/efm32/config              \
+    -I$(SDK_SRC_DIR)/platform/bootloader/api                                    \
+    -I$(SDK_SRC_DIR)/platform/common/inc                                        \
+    -I$(SDK_SRC_DIR)/platform/CMSIS/Include                                     \
+    -I$(SDK_SRC_DIR)/platform/Device/SiliconLabs/EFR32MG1P/Include              \
+    -I$(SDK_SRC_DIR)/platform/emdrv/common/inc                                  \
+    -I$(SDK_SRC_DIR)/platform/emdrv/gpiointerrupt/inc                           \
+    -I$(SDK_SRC_DIR)/platform/emdrv/uartdrv/inc                                 \
+    -I$(SDK_SRC_DIR)/platform/emdrv/uartdrv/config                              \
+    -I$(SDK_SRC_DIR)/platform/emdrv/ustimer/inc                                 \
+    -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/inc                                  \
+    -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/config                               \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/inc                                    \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/config                                 \
+    -I$(SDK_SRC_DIR)/platform/emlib/inc                                         \
+    -I$(SDK_SRC_DIR)/platform/halconfig/inc/hal-config                          \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32                         \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32/efr32xg1x               \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32/rf/common/cortex        \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/common                             \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/hal                                \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/hal/efr32                          \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/protocol/ieee802154                \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/plugin/pa-conversions              \
+    -I$(SDK_SRC_DIR)/platform/service/mpu/inc                                   \
+    -I$(SDK_SRC_DIR)/platform/service/sleeptimer/config                         \
+    -I$(SDK_SRC_DIR)/platform/service/sleeptimer/inc                            \
+    -I$(SDK_SRC_DIR)/util/plugin/plugin-common/fem-control                      \
+    -I$(SDK_SRC_DIR)/util/third_party/mbedtls/sl_crypto/include                 \
+    -Wno-unused-parameter                                                       \
+    -Wno-missing-field-initializers                                             \
+    $(NULL)
+
+PLATFORM_SOURCES                                                              = \
+    alarm.c                                                                     \
+    diag.c                                                                      \
+    entropy.c                                                                   \
+    fem-control.c                                                               \
+    flash.c                                                                     \
+    logging.c                                                                   \
+    misc.c                                                                      \
+    openthread-core-efr32-config.h                                              \
+    openthread-core-efr32-config-check.h                                        \
+    platform-efr32.h                                                            \
+    platform-band.h                                                             \
+    radio.c                                                                     \
+    rail_config.h                                                               \
+    startup-gcc.c                                                               \
+    system.c                                                                    \
+    uart.c                                                                      \
+    $(NULL)
+
+noinst_HEADERS                                                                = \
+    platform-efr32.h                                                            \
+    platform-band.h                                                             \
+    $(NULL)
+
+libopenthread_efr32mg1_a_SOURCES                                              = \
+    $(PLATFORM_SOURCES)                                                         \
+    $(NULL)
+
+Dash = -
+libopenthread_efr32mg1_a_LIBADD                                                                      = \
+    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")             \
+    $(shell find $(top_builddir)/third_party/jlink/SEGGER_RTT_V640/RTT $(Dash)type f $(Dash)name "*.o")
+
+DIST_SUBDIRS                                                                  = \
+    $(NULL)
+
+SUBDIRS                                                                       = \
+    $(NULL)
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/efr32mg1/Makefile.platform.am b/examples/platforms/efr32mg1/Makefile.platform.am
new file mode 100644
index 0000000..d7920a8
--- /dev/null
+++ b/examples/platforms/efr32mg1/Makefile.platform.am
@@ -0,0 +1,49 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# efr32mg1 platform-specific Makefile
+#
+
+LIBRAIL = $(shell                                                                \
+if [ "$(DMP)" = "1" ]; then                                                      \
+    echo "librail_multiprotocol_efr32xg1_gcc_release.a";                         \
+else                                                                             \
+    echo "librail_efr32xg1_gcc_release.a";                                       \
+fi )
+
+LDADD_COMMON                                                                  += \
+    $(top_builddir)/examples/platforms/efr32mg1/libopenthread-efr32mg1.a         \
+    $(top_builddir)/third_party/silabs/libsilabs-efr32mg1-sdk.a                  \
+    $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/radio/rail_lib/autogen/librail_release/$(LIBRAIL) \
+    $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \
+    $(NULL)
+
+LDFLAGS_COMMON                                                                += \
+    -T $(top_srcdir)/examples/platforms/efr32mg1/efr32mg1.ld                     \
+    $(NULL)
diff --git a/examples/platforms/efr32mg1/README.md b/examples/platforms/efr32mg1/README.md
new file mode 100644
index 0000000..2084a1a
--- /dev/null
+++ b/examples/platforms/efr32mg1/README.md
@@ -0,0 +1,242 @@
+# OpenThread on EFR32MG1P Example
+
+This directory contains example platform drivers for the [Silicon Labs EFR32MG1P][efr32mg1p] based on [EFR32™ Mighty Gecko Wireless Starter Kit][slwstk6000b].
+
+[efr32mg]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc
+[slwstk6000b]: http://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit
+
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. [EFR32MG1P SoC][efr32mg1p] has rich memory and peripheral resources which can support all OpenThread capabilities. See the "Run the example with EFR32MG1 boards" section below for an example using basic OpenThread capabilities.
+
+## Toolchain
+
+Download and install the [GNU toolchain for ARM Cortex-M][gnu-toolchain].
+
+[gnu-toolchain]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
+
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
+
+```bash
+$ cd <path-to-openthread>
+$ ./script/bootstrap
+```
+
+## Build Examples
+
+1. Download and install the [Simplicity Studio][simplicity_studio].
+
+[simplicity_studio]: http://www.silabs.com/products/development-tools/software/simplicity-studio
+
+2. Install Flex (Gecko) SDK including RAIL Library from Simplicity Studio.
+   - Connect EFR32MG1P Wireless Starter Kit to Simplicity Studio.
+   - Find Flex SDK v2.7 in the Software Update page and click Install.
+   - Flex SDK v2.7 will be installed in the path: `/SimplicityStudio_v4/developer/sdks/gecko_sdk_suite`.
+
+For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32) portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the Wireless Gecko (EFR32™) Portfolio][qsg138]. For more information on RAIL, see [Radio Abstraction Interface Layer][rail].
+
+[qsg138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
+[rail]: http://www.silabs.com/products/development-tools/software/radio-abstraction-interface-layer-sdk
+
+3. Configure the path to Flex SDK source code.
+
+```bash
+$ cd <path-to-openthread>/third_party
+$ mkdir silabs
+$ cd <path-to-Simplicity-Studio>/developer/sdks
+$ cp -rf gecko_sdk_suite <path-to-openthread>/third_party/silabs/
+```
+
+Alternatively create a symbolic link to the Flex SDK source code.
+
+```bash
+$ cd <path-to-openthread>/third_party
+$ mkdir silabs
+$ ln -s <path-to-Simplicity-Studio>/developer/sdks/gecko_sdk_suite silabs/gecko_sdk_suite
+```
+
+4. Build OpenThread Firmware (CLI example) on EFR32 platform.
+
+```bash
+$ cd <path-to-openthread>
+$ ./bootstrap
+```
+
+For EFR32MG1™ Mighty Gecko Wireless Starter Kit:
+
+```bash
+$ make -f examples/Makefile-efr32mg1 BOARD=BRD4151A
+```
+
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/efr32mg1/bin`.
+
+## Flash Binaries
+
+Compiled binaries may be flashed onto the EFR32 using [JLinkGDBServer][jlinkgdbserver]. EFR32 Starter kit mainboard integrates an on-board SEGGER J-Link debugger.
+
+[jlinkgdbserver]: https://www.segger.com/jlink-gdb-server.html
+
+```bash
+$ cd <path-to-JLinkGDBServer>
+$ sudo ./JLinkGDBServer -if swd -device EFR32MG1PxxxF256
+$ cd <path-to-openthread>/output/efr32mg1/bin
+$ arm-none-eabi-gdb ot-cli-ftd
+$ (gdb) target remote 127.0.0.1:2331
+$ (gdb) load
+$ (gdb) monitor reset
+$ (gdb) c
+```
+
+Or Compiled binaries also may be flashed onto the specified EFR32 dev board using [J-Link Commander][j-link-commander].
+
+[j-link-commander]: https://www.segger.com/products/debug-probes/j-link/tools/j-link-commander/
+
+```bash
+$ cd <path-to-openthread>/output/efr32mg1/bin
+$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex
+$ JLinkExe -device EFR32MG1PxxxF256 -speed 4000 -if SWD -autoconnect 1 -SelectEmuBySN <SerialNo>
+$ J-Link>loadfile ot-cli-ftd.hex
+$ J-Link>r
+$ J-Link>q
+```
+
+Note: SerialNo is J-Link serial number. Use the following command to get the serial number of the connected J-Link.
+
+```bash
+$ JLinkExe
+```
+
+Alternatively Simplicity Commander provides a graphical interface for J-Link Commander.
+
+```bash
+$ cd <path-to-openthread>/output/efr32mg1/bin
+$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.ihex
+$ <path-to-simplicity-studio>/developer/adapter_packs/commander/commander
+```
+
+In the J-Link Device drop-down list select the serial number of the device to flash. Click the Adapter Connect button. Ensure the Debug Interface drop-down list is set to SWD and click the Target Connect button. Click on the Flash icon on the left side of the window to switch to the flash page. In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button. Click the Flash button located under the Browse... button.
+
+## Run the example with EFR32MG1 boards
+
+1. Flash two EFR32 boards with the `CLI example` firmware (as shown above).
+2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1). Type `help` for a list of commands.
+
+   ```bash
+   > help
+   help
+   channel
+   childtimeout
+   contextreusedelay
+   extaddr
+   extpanid
+   ipaddr
+   keysequence
+   leaderweight
+   masterkey
+   mode
+   netdataregister
+   networkidtimeout
+   networkname
+   panid
+   ping
+   prefix
+   releaserouterid
+   rloc16
+   route
+   routerupgradethreshold
+   scan
+   start
+   state
+   stop
+   whitelist
+   ```
+
+3. Start a Thread network as Leader.
+
+   ```bash
+   > dataset init new
+   Done
+   > dataset
+   Active Timestamp: 1
+   Channel: 13
+   Channel Mask: 07fff800
+   Ext PAN ID: d63e8e3e495ebbc3
+   Mesh Local Prefix: fd3d:b50b:f96d:722d/64
+   Master Key: dfd34f0f05cad978ec4e32b0413038ff
+   Network Name: OpenThread-8f28
+   PAN ID: 0x8f28
+   PSKc: c23a76e98f1a6483639b1ac1271e2e27
+   Security Policy: 0, onrcb
+   Done
+   > dataset commit active
+   Done
+   > ifconfig up
+   Done
+   > thread start
+   Done
+
+   wait a couple of seconds...
+
+   > state
+   leader
+   Done
+   ```
+
+4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1) and attach it to the Thread network as a Router.
+
+   ```bash
+   > dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
+   Done
+   > dataset commit active
+   Done
+   > routerselectionjitter 1
+   Done
+   > ifconfig up
+   Done
+   > thread start
+   Done
+
+   wait a couple of seconds...
+
+   > state
+   router
+   Done
+   ```
+
+5. List all IPv6 addresses of Leader.
+
+   ```bash
+   > ipaddr
+   fd3d:b50b:f96d:722d:0:ff:fe00:fc00
+   fd3d:b50b:f96d:722d:0:ff:fe00:c00
+   fd3d:b50b:f96d:722d:7a73:bff6:9093:9117
+   fe80:0:0:0:6c41:9001:f3d6:4148
+   Done
+   ```
+
+6. Send an ICMPv6 ping to Leader's Mesh-EID IPv6 address.
+
+   ```bash
+   > ping fd3d:b50b:f96d:722d:7a73:bff6:9093:9117
+   16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
+   ```
+
+The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner, joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
+
+```bash
+$ cd <path-to-openthread>
+$ ./bootstrap
+$ make -f examples/Makefile-efr32mg1 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1
+```
+
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
+
+[cli]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
+
+## Verification
+
+The following toolchain has been used for testing and verification:
+
+- gcc version 7.3.1
+
+The EFR32 example has been verified with following Flex SDK/RAIL Library version:
+
+- Flex SDK version 2.7.0.0
diff --git a/examples/platforms/efr32mg1/alarm.c b/examples/platforms/efr32mg1/alarm.c
new file mode 100644
index 0000000..71a39c0
--- /dev/null
+++ b/examples/platforms/efr32mg1/alarm.c
@@ -0,0 +1,145 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for the alarm.
+ *
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "openthread-system.h"
+#include <openthread/config.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+#include "common/logging.hpp"
+
+#include "platform-efr32.h"
+#include "utils/code_utils.h"
+
+#include "em_core.h"
+#include "rail.h"
+#include "sl_sleeptimer.h"
+
+#define XTAL_ACCURACY 200
+
+static sl_sleeptimer_timer_handle_t sl_handle;
+static uint32_t                     sAlarm     = 0;
+static bool                         sIsRunning = false;
+
+static void AlarmCallback(sl_sleeptimer_timer_handle_t *aHandle, void *aData)
+{
+    otSysEventSignalPending();
+}
+
+void efr32AlarmInit(void)
+{
+    memset(&sl_handle, 0, sizeof sl_handle);
+}
+
+uint32_t otPlatAlarmMilliGetNow(void)
+{
+    uint64_t    ticks;
+    uint64_t    now;
+    sl_status_t status;
+
+    ticks  = sl_sleeptimer_get_tick_count64();
+    status = sl_sleeptimer_tick64_to_ms(ticks, &now);
+    assert(status == SL_STATUS_OK);
+    return (uint32_t)now;
+}
+
+uint32_t otPlatTimeGetXtalAccuracy(void)
+{
+    return XTAL_ACCURACY;
+}
+
+void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    sl_status_t status;
+    int32_t     remaining;
+    uint32_t    ticks;
+
+    sl_sleeptimer_stop_timer(&sl_handle);
+
+    sAlarm     = aT0 + aDt;
+    remaining  = (int32_t)(sAlarm - otPlatAlarmMilliGetNow());
+    sIsRunning = true;
+
+    if (remaining <= 0)
+    {
+        otSysEventSignalPending();
+    }
+    else
+    {
+        status = sl_sleeptimer_ms32_to_tick(remaining, &ticks);
+        assert(status == SL_STATUS_OK);
+
+        status = sl_sleeptimer_start_timer(&sl_handle, ticks, AlarmCallback, NULL, 0,
+                                           SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG);
+        assert(status == SL_STATUS_OK);
+    }
+}
+
+void otPlatAlarmMilliStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sl_sleeptimer_stop_timer(&sl_handle);
+    sIsRunning = false;
+}
+
+void efr32AlarmProcess(otInstance *aInstance)
+{
+    int32_t remaining;
+
+    if (sIsRunning)
+    {
+        remaining = (int32_t)(sAlarm - otPlatAlarmMilliGetNow());
+
+        if (remaining <= 0)
+        {
+            sIsRunning = false;
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+            if (otPlatDiagModeGet())
+            {
+                otPlatDiagAlarmFired(aInstance);
+            }
+            else
+#endif
+            {
+                otPlatAlarmMilliFired(aInstance);
+            }
+        }
+    }
+}
diff --git a/examples/platforms/efr32mg1/brd4151a/board_config.h b/examples/platforms/efr32mg1/brd4151a/board_config.h
new file mode 100644
index 0000000..d798d52
--- /dev/null
+++ b/examples/platforms/efr32mg1/brd4151a/board_config.h
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2018, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes dev borad compile-time configuration constants for efr32.
+ *
+ */
+
+#ifndef __BOARD_CONFIG_H__
+#define __BOARD_CONFIG_H__
+
+#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 0 /// Dev board doesn't support OQPSK modulation in 915MHz band.
+
+#ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+#define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
+#endif
+
+#ifndef RADIO_CONFIG_DMP_SUPPORT
+#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
+#endif
+
+#define RADIO_CONFIG_PA_USES_DCDC 0 /// The PA(s) is(are) fed from VBAT
+
+#endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg1/brd4151a/hal-config.h b/examples/platforms/efr32mg1/brd4151a/hal-config.h
new file mode 100644
index 0000000..24a9a5e
--- /dev/null
+++ b/examples/platforms/efr32mg1/brd4151a/hal-config.h
@@ -0,0 +1,407 @@
+#ifndef HAL_CONFIG_H
+#define HAL_CONFIG_H
+
+#include "em_device.h"
+#include "hal-config-types.h"
+
+// This file is auto-generated by Hardware Configurator in Simplicity Studio.
+// Any content between $[ and ]$ will be replaced whenever the file is regenerated.
+// Content outside these regions will be preserved.
+
+// $[ACMP0]
+// [ACMP0]$
+
+// $[ACMP1]
+// [ACMP1]$
+
+// $[ADC0]
+// [ADC0]$
+
+// $[ANTDIV]
+// [ANTDIV]$
+
+// $[BATTERYMON]
+// [BATTERYMON]$
+
+// $[BTL_BUTTON]
+// [BTL_BUTTON]$
+
+// $[BULBPWM]
+// [BULBPWM]$
+
+// $[BULBPWM_COLOR]
+// [BULBPWM_COLOR]$
+
+// $[BUTTON]
+#define BSP_BUTTON_PRESENT (1)
+
+#define BSP_BUTTON0_PIN (6U)
+#define BSP_BUTTON0_PORT (gpioPortF)
+
+#define BSP_BUTTON1_PIN (7U)
+#define BSP_BUTTON1_PORT (gpioPortF)
+
+#define BSP_BUTTON_COUNT (2U)
+#define BSP_BUTTON_INIT                                                            \
+    {                                                                              \
+        {BSP_BUTTON0_PORT, BSP_BUTTON0_PIN}, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } \
+    }
+#define BSP_BUTTON_GPIO_DOUT (HAL_GPIO_DOUT_LOW)
+#define BSP_BUTTON_GPIO_MODE (HAL_GPIO_MODE_INPUT)
+// [BUTTON]$
+
+// $[CMU]
+#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
+#define HAL_CLK_LFECLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define HAL_CLK_LFBCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_LFXO_PRESENT (1)
+#define BSP_CLK_HFXO_PRESENT (1)
+#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
+#define BSP_CLK_LFXO_CTUNE (0)
+#define BSP_CLK_LFXO_FREQ (32768U)
+#define HAL_CLK_LFACLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_HFXO_FREQ (38400000UL)
+#define BSP_CLK_HFXO_CTUNE (338)
+#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
+#define BSP_CLK_HFXO_CTUNE_TOKEN (0)
+#define HAL_CLK_HFXO_AUTOSTART (HAL_CLK_HFXO_AUTOSTART_NONE)
+// [CMU]$
+
+// $[COEX]
+// [COEX]$
+
+// $[CS5463]
+// [CS5463]$
+
+// $[CSEN0]
+// [CSEN0]$
+
+// $[DCDC]
+#define BSP_DCDC_PRESENT (1)
+
+#define HAL_DCDC_BYPASS (0)
+#define BSP_DCDC_INIT EMU_DCDCINIT_DEFAULT
+// [DCDC]$
+
+// $[EMU]
+// [EMU]$
+
+// $[EXTFLASH]
+// [EXTFLASH]$
+
+// $[EZRADIOPRO]
+// [EZRADIOPRO]$
+
+// $[GPIO]
+#define PORTIO_GPIO_SWCLKTCK_PIN (0)
+#define PORTIO_GPIO_SWCLKTCK_PORT (gpioPortF)
+#define PORTIO_GPIO_DBGROUTE_LOC (0)
+
+#define PORTIO_GPIO_SWDIOTMS_PIN (1)
+#define PORTIO_GPIO_SWDIOTMS_PORT (gpioPortF)
+
+#define PORTIO_GPIO_SWV_PIN (2)
+#define PORTIO_GPIO_SWV_PORT (gpioPortF)
+#define PORTIO_GPIO_SWV_LOC (0)
+
+#define PORTIO_GPIO_TCLK_PIN (8)
+#define PORTIO_GPIO_TCLK_PORT (gpioPortF)
+#define PORTIO_GPIO_TCLK_LOC (0)
+
+#define PORTIO_GPIO_TD0_PIN (9)
+#define PORTIO_GPIO_TD0_PORT (gpioPortF)
+#define PORTIO_GPIO_TD0_LOC (0)
+
+#define PORTIO_GPIO_TD1_PIN (10)
+#define PORTIO_GPIO_TD1_PORT (gpioPortF)
+#define PORTIO_GPIO_TD1_LOC (0)
+
+#define PORTIO_GPIO_TD2_PIN (11)
+#define PORTIO_GPIO_TD2_PORT (gpioPortF)
+#define PORTIO_GPIO_TD2_LOC (0)
+
+#define PORTIO_GPIO_TD3_PIN (12)
+#define PORTIO_GPIO_TD3_PORT (gpioPortF)
+#define PORTIO_GPIO_TD3_LOC (0)
+
+// [GPIO]$
+
+// $[I2C0]
+#define PORTIO_I2C0_SCL_PIN (10)
+#define PORTIO_I2C0_SCL_PORT (gpioPortC)
+#define PORTIO_I2C0_SCL_LOC (14)
+
+#define PORTIO_I2C0_SDA_PIN (11)
+#define PORTIO_I2C0_SDA_PORT (gpioPortC)
+#define PORTIO_I2C0_SDA_LOC (16)
+
+// [I2C0]$
+
+// $[I2C1]
+// [I2C1]$
+
+// $[I2CSENSOR]
+// [I2CSENSOR]$
+
+// $[IDAC0]
+// [IDAC0]$
+
+// $[IOEXP]
+// [IOEXP]$
+
+// $[LED]
+#define BSP_LED_PRESENT (1)
+
+#define BSP_LED0_PIN (4)
+#define BSP_LED0_PORT (gpioPortF)
+
+#define BSP_LED1_PIN (5)
+#define BSP_LED1_PORT (gpioPortF)
+
+#define HAL_LED_ENABLE \
+    {                  \
+        0, 1           \
+    }
+#define HAL_LED_COUNT (2)
+#define BSP_LED_COUNT (2)
+#define BSP_LED_INIT                                                   \
+    {                                                                  \
+        {BSP_LED0_PORT, BSP_LED0_PIN}, { BSP_LED1_PORT, BSP_LED1_PIN } \
+    }
+// [LED]$
+
+// $[LESENSE]
+// [LESENSE]$
+
+// $[LETIMER0]
+// [LETIMER0]$
+
+// $[LEUART0]
+// [LEUART0]$
+
+// $[LFXO]
+// [LFXO]$
+
+// $[LNA]
+// [LNA]$
+
+// $[PA]
+#define HAL_PA_ENABLE (1)
+
+#define HAL_PA_RAMP (10)
+#define HAL_PA_2P4_LOWPOWER (0)
+#define HAL_PA_POWER (252)
+#define HAL_PA_VOLTAGE (3300)
+#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
+// [PA]$
+
+// $[PCNT0]
+// [PCNT0]$
+
+// $[PCNT1]
+// [PCNT1]$
+
+// $[PCNT2]
+// [PCNT2]$
+
+// $[PORTIO]
+// [PORTIO]$
+
+// $[PRS]
+#define PORTIO_PRS_CH4_PIN (13)
+#define PORTIO_PRS_CH4_PORT (gpioPortD)
+#define PORTIO_PRS_CH4_LOC (4)
+
+// [PRS]$
+
+// $[PTI]
+#define PORTIO_PTI_DFRAME_PIN (13)
+#define PORTIO_PTI_DFRAME_PORT (gpioPortB)
+#define PORTIO_PTI_DFRAME_LOC (6)
+
+#define PORTIO_PTI_DOUT_PIN (12)
+#define PORTIO_PTI_DOUT_PORT (gpioPortB)
+#define PORTIO_PTI_DOUT_LOC (6)
+
+#define HAL_PTI_ENABLE (1)
+
+#define BSP_PTI_DFRAME_PIN (13)
+#define BSP_PTI_DFRAME_PORT (gpioPortB)
+#define BSP_PTI_DFRAME_LOC (6)
+
+#define BSP_PTI_DOUT_PIN (12)
+#define BSP_PTI_DOUT_PORT (gpioPortB)
+#define BSP_PTI_DOUT_LOC (6)
+
+#define HAL_PTI_MODE (HAL_PTI_MODE_UART)
+#define HAL_PTI_BAUD_RATE (1600000)
+// [PTI]$
+
+// $[PYD1698]
+// [PYD1698]$
+
+// $[SERIAL]
+#define HAL_SERIAL_USART0_ENABLE (0)
+#define HAL_SERIAL_LEUART0_ENABLE (0)
+#define HAL_SERIAL_USART1_ENABLE (0)
+#define HAL_SERIAL_USART2_ENABLE (0)
+#define HAL_SERIAL_USART3_ENABLE (0)
+#define HAL_SERIAL_RXWAKE_ENABLE (0)
+#define BSP_SERIAL_APP_CTS_PIN (2)
+#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_CTS_LOC (30)
+
+#define BSP_SERIAL_APP_RX_PIN (1)
+#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RX_LOC (0)
+
+#define BSP_SERIAL_APP_TX_PIN (0)
+#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_TX_LOC (0)
+
+#define BSP_SERIAL_APP_RTS_PIN (3)
+#define BSP_SERIAL_APP_RTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RTS_LOC (30)
+
+#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128)
+#define HAL_SERIAL_APP_BAUD_RATE (115200)
+#define HAL_SERIAL_APP_RXSTOP (16)
+#define HAL_SERIAL_APP_RXSTART (16)
+#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128)
+#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
+// [SERIAL]$
+
+// $[SPIDISPLAY]
+// [SPIDISPLAY]$
+
+// $[SPINCP]
+// [SPINCP]$
+
+// $[TIMER0]
+// [TIMER0]$
+
+// $[TIMER1]
+// [TIMER1]$
+
+// $[UARTNCP]
+// [UARTNCP]$
+
+// $[USART0]
+#define PORTIO_USART0_CTS_PIN (2)
+#define PORTIO_USART0_CTS_PORT (gpioPortA)
+#define PORTIO_USART0_CTS_LOC (30)
+
+#define PORTIO_USART0_RTS_PIN (3)
+#define PORTIO_USART0_RTS_PORT (gpioPortA)
+#define PORTIO_USART0_RTS_LOC (30)
+
+#define PORTIO_USART0_RX_PIN (1)
+#define PORTIO_USART0_RX_PORT (gpioPortA)
+#define PORTIO_USART0_RX_LOC (0)
+
+#define PORTIO_USART0_TX_PIN (0)
+#define PORTIO_USART0_TX_PORT (gpioPortA)
+#define PORTIO_USART0_TX_LOC (0)
+
+#define HAL_USART0_ENABLE (1)
+
+#define BSP_USART0_CTS_PIN (2)
+#define BSP_USART0_CTS_PORT (gpioPortA)
+#define BSP_USART0_CTS_LOC (30)
+
+#define BSP_USART0_RX_PIN (1)
+#define BSP_USART0_RX_PORT (gpioPortA)
+#define BSP_USART0_RX_LOC (0)
+
+#define BSP_USART0_TX_PIN (0)
+#define BSP_USART0_TX_PORT (gpioPortA)
+#define BSP_USART0_TX_LOC (0)
+
+#define BSP_USART0_RTS_PIN (3)
+#define BSP_USART0_RTS_PORT (gpioPortA)
+#define BSP_USART0_RTS_LOC (30)
+
+#define HAL_USART0_RX_QUEUE_SIZE (128)
+#define HAL_USART0_BAUD_RATE (115200)
+#define HAL_USART0_RXSTOP (16)
+#define HAL_USART0_RXSTART (16)
+#define HAL_USART0_TX_QUEUE_SIZE (128)
+#define HAL_USART0_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
+// [USART0]$
+
+// $[USART1]
+#define PORTIO_USART1_CLK_PIN (8)
+#define PORTIO_USART1_CLK_PORT (gpioPortC)
+#define PORTIO_USART1_CLK_LOC (11)
+
+#define PORTIO_USART1_CS_PIN (9)
+#define PORTIO_USART1_CS_PORT (gpioPortC)
+#define PORTIO_USART1_CS_LOC (11)
+
+#define PORTIO_USART1_RX_PIN (7)
+#define PORTIO_USART1_RX_PORT (gpioPortC)
+#define PORTIO_USART1_RX_LOC (11)
+
+#define PORTIO_USART1_TX_PIN (6)
+#define PORTIO_USART1_TX_PORT (gpioPortC)
+#define PORTIO_USART1_TX_LOC (11)
+
+// [USART1]$
+
+// $[USART2]
+#define PORTIO_USART2_CLK_PIN (8)
+#define PORTIO_USART2_CLK_PORT (gpioPortA)
+#define PORTIO_USART2_CLK_LOC (1)
+
+#define PORTIO_USART2_CS_PIN (9)
+#define PORTIO_USART2_CS_PORT (gpioPortA)
+#define PORTIO_USART2_CS_LOC (1)
+
+#define PORTIO_USART2_RX_PIN (7)
+#define PORTIO_USART2_RX_PORT (gpioPortA)
+#define PORTIO_USART2_RX_LOC (1)
+
+#define PORTIO_USART2_TX_PIN (6)
+#define PORTIO_USART2_TX_PORT (gpioPortA)
+#define PORTIO_USART2_TX_LOC (1)
+
+// [USART2]$
+
+// $[USART3]
+#define PORTIO_USART3_CTS_PIN (8)
+#define PORTIO_USART3_CTS_PORT (gpioPortD)
+#define PORTIO_USART3_CTS_LOC (28)
+
+#define PORTIO_USART3_RTS_PIN (9)
+#define PORTIO_USART3_RTS_PORT (gpioPortD)
+#define PORTIO_USART3_RTS_LOC (28)
+
+#define PORTIO_USART3_RX_PIN (7)
+#define PORTIO_USART3_RX_PORT (gpioPortB)
+#define PORTIO_USART3_RX_LOC (10)
+
+#define PORTIO_USART3_TX_PIN (6)
+#define PORTIO_USART3_TX_PORT (gpioPortB)
+#define PORTIO_USART3_TX_LOC (10)
+
+// [USART3]$
+
+// $[VCOM]
+// [VCOM]$
+
+// $[VDAC0]
+// [VDAC0]$
+
+// $[VUART]
+// [VUART]$
+
+// $[WDOG]
+// [WDOG]$
+
+// $[WTIMER0]
+// [WTIMER0]$
+
+// $[WTIMER1]
+// [WTIMER1]$
+
+#endif /* HAL_CONFIG_H */
diff --git a/examples/platforms/efr32mg1/crypto/efr32-mbedtls-config.h b/examples/platforms/efr32mg1/crypto/efr32-mbedtls-config.h
new file mode 100644
index 0000000..14f1d1c
--- /dev/null
+++ b/examples/platforms/efr32mg1/crypto/efr32-mbedtls-config.h
@@ -0,0 +1,92 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EFR32_MBEDTLS_CONFIG_H
+#define EFR32_MBEDTLS_CONFIG_H
+
+#include "em_device.h"
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * Enable hardware acceleration for the AES block cipher
+ *
+ * Module:  sl_crypto/src/crypto_aes.c for devices with CRYPTO
+ *          sl_crypto/src/aes_aes.c for devices with AES
+ *
+ * See MBEDTLS_AES_C for more information.
+ */
+#define MBEDTLS_AES_ALT
+
+/**
+ * \def MBEDTLS_ECP_INTERNAL_ALT
+ * \def ECP_SHORTWEIERSTRASS
+ * \def MBEDTLS_ECP_ADD_MIXED_ALT
+ * \def MBEDTLS_ECP_DOUBLE_JAC_ALT
+ * \def MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
+ * \def MBEDTLS_ECP_NORMALIZE_JAC_ALT
+ *
+ * Enable hardware acceleration for the elliptic curve over GF(p) library.
+ *
+ * Module:  sl_crypto/src/crypto_ecp.c
+ * Caller:  library/ecp.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_ECP_C and at least one
+ * MBEDTLS_ECP_DP_XXX_ENABLED and (CRYPTO_COUNT > 0)
+ */
+#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
+#define MBEDTLS_ECP_INTERNAL_ALT
+#define ECP_SHORTWEIERSTRASS
+#define MBEDTLS_ECP_ADD_MIXED_ALT
+#define MBEDTLS_ECP_DOUBLE_JAC_ALT
+#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
+#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
+#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
+#endif
+
+/**
+ * \def MBEDTLS_SHA256_ALT
+ *
+ * Enable hardware acceleration for the SHA-224 and SHA-256 cryptographic
+ * hash algorithms.
+ *
+ * Module:  sl_crypto/src/crypto_sha.c
+ * Caller:  library/entropy.c
+ *          library/mbedtls_md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_SHA256_C and (CRYPTO_COUNT > 0)
+ * See MBEDTLS_SHA256_C for more information.
+ */
+#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
+#define MBEDTLS_SHA256_ALT
+#endif
+
+#endif // EFR32_MBEDTLS_CONFIG_H
diff --git a/examples/platforms/efr32mg1/diag.c b/examples/platforms/efr32mg1/diag.c
new file mode 100644
index 0000000..a7c3357
--- /dev/null
+++ b/examples/platforms/efr32mg1/diag.c
@@ -0,0 +1,86 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for the diagnostics.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <openthread/config.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/radio.h>
+
+#include "platform-efr32.h"
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+/**
+ * Diagnostics mode variables.
+ *
+ */
+static bool sDiagMode = false;
+
+void otPlatDiagModeSet(bool aMode)
+{
+    sDiagMode = aMode;
+}
+
+bool otPlatDiagModeGet()
+{
+    return sDiagMode;
+}
+
+void otPlatDiagChannelSet(uint8_t aChannel)
+{
+    OT_UNUSED_VARIABLE(aChannel);
+}
+
+void otPlatDiagTxPowerSet(int8_t aTxPower)
+{
+    OT_UNUSED_VARIABLE(aTxPower);
+}
+
+void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aFrame);
+    OT_UNUSED_VARIABLE(aError);
+}
+
+void otPlatDiagAlarmCallback(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+#endif // #if OPENTHREAD_CONFIG_DIAG_ENABLE
diff --git a/examples/platforms/efr32mg1/efr32mg1.ld b/examples/platforms/efr32mg1/efr32mg1.ld
new file mode 100644
index 0000000..92ba35e
--- /dev/null
+++ b/examples/platforms/efr32mg1/efr32mg1.ld
@@ -0,0 +1,246 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**
+ * @file
+ *   This file implements the OpenThread linker script for the
+ *   Silicon Labs efr32mg1 platform.
+ *
+ */
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
+  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 32K
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __copy_table_start__
+ *   __copy_table_end__
+ *   __zero_table_start__
+ *   __zero_table_end__
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __Vectors_End
+ *   __Vectors_Size
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+  .text :
+  {
+    KEEP(*(.vectors))
+    __Vectors_End = .;
+    __Vectors_Size = __Vectors_End - __Vectors;
+    __end__ = .;
+
+    *(.text*)
+
+    KEEP(*(.init))
+    KEEP(*(.fini))
+
+    /* .ctors */
+    *crtbegin.o(.ctors)
+    *crtbegin?.o(.ctors)
+    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+    *(SORT(.ctors.*))
+    *(.ctors)
+
+    /* .dtors */
+    *crtbegin.o(.dtors)
+    *crtbegin?.o(.dtors)
+    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+    *(SORT(.dtors.*))
+    *(.dtors)
+
+    *(.rodata*)
+
+    KEEP(*(.eh_frame*))
+  } > FLASH
+
+  .ARM.extab :
+  {
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+  } > FLASH
+
+  __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } > FLASH
+  __exidx_end = .;
+
+  /* To copy multiple ROM to RAM sections,
+   * uncomment .copy.table section and,
+   * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
+  /*
+  .copy.table :
+  {
+    . = ALIGN(4);
+    __copy_table_start__ = .;
+    LONG (__etext)
+    LONG (__data_start__)
+    LONG (__data_end__ - __data_start__)
+    LONG (__etext2)
+    LONG (__data2_start__)
+    LONG (__data2_end__ - __data2_start__)
+    __copy_table_end__ = .;
+  } > FLASH
+  */
+
+  /* To clear multiple BSS sections,
+   * uncomment .zero.table section and,
+   * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
+  /*
+  .zero.table :
+  {
+    . = ALIGN(4);
+    __zero_table_start__ = .;
+    LONG (__bss_start__)
+    LONG (__bss_end__ - __bss_start__)
+    LONG (__bss2_start__)
+    LONG (__bss2_end__ - __bss2_start__)
+    __zero_table_end__ = .;
+  } > FLASH
+  */
+
+  __etext = .;
+
+  .data : AT (__etext)
+  {
+    __data_start__ = .;
+    *(vtable)
+    *(.data*)
+    . = ALIGN (4);
+    PROVIDE (__ram_func_section_start = .);
+    *(.ram)
+    PROVIDE (__ram_func_section_end = .);
+
+    . = ALIGN(4);
+    /* preinit data */
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP(*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+
+    . = ALIGN(4);
+    /* init data */
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP(*(SORT(.init_array.*)))
+    KEEP(*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+
+    . = ALIGN(4);
+    /* finit data */
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP(*(SORT(.fini_array.*)))
+    KEEP(*(.fini_array))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+
+    KEEP(*(.jcr*))
+    . = ALIGN(4);
+    /* All data end */
+    __data_end__ = .;
+
+  } > RAM
+
+  .bss :
+  {
+    . = ALIGN(4);
+    __bss_start__ = .;
+    *(.bss*)
+    *(COMMON)
+    . = ALIGN(4);
+    __bss_end__ = .;
+  } > RAM
+
+  .heap (COPY):
+  {
+    __HeapBase = .;
+    __end__ = .;
+    end = __end__;
+    _end = __end__;
+    KEEP(*(.heap*))
+    __HeapLimit = .;
+  } > RAM
+
+  /* .stack_dummy section doesn't contains any symbols. It is only
+   * used for linker to calculate size of stack sections, and assign
+   * values to stack symbols later */
+  .stack_dummy (COPY):
+  {
+    KEEP(*(.stack*))
+  } > RAM
+
+  /* Set stack top to end of RAM, and stack limit move down by
+   * size of stack_dummy section */
+  __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+  PROVIDE(__stack = __StackTop);
+
+  /*******************************************************************/
+  /* Define flash block for nvm3                                     */
+  .nvm (DSECT) : {
+    KEEP(*(.simee*))
+  } > FLASH
+
+  linker_nvm_end = ORIGIN(FLASH) + LENGTH(FLASH);
+  linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm);
+  linker_nvm_size = SIZEOF(.nvm);
+  __nvm3Base = linker_nvm_begin;
+  /*******************************************************************/
+
+  /* Check if data + heap + stack exceeds RAM limit */
+  ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+
+  /* Check if FLASH usage exceeds FLASH size */
+  ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
+}
diff --git a/examples/platforms/efr32mg1/entropy.c b/examples/platforms/efr32mg1/entropy.c
new file mode 100644
index 0000000..2b196bb
--- /dev/null
+++ b/examples/platforms/efr32mg1/entropy.c
@@ -0,0 +1,109 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements an entropy source based on ADC.
+ *
+ */
+
+#include <openthread/platform/entropy.h>
+
+#include "utils/code_utils.h"
+
+#include "em_adc.h"
+#include "em_cmu.h"
+
+enum
+{
+    EFR32_ADC_REF_CLOCK = 7000000,
+};
+
+void efr32RandomInit(void)
+{
+    /* Enable ADC Clock */
+    CMU_ClockEnable(cmuClock_ADC0, true);
+    ADC_Init_TypeDef       init       = ADC_INIT_DEFAULT;
+    ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
+
+    /* Initialize the ADC with the required values */
+    init.timebase = ADC_TimebaseCalc(0);
+    init.prescale = ADC_PrescaleCalc(EFR32_ADC_REF_CLOCK, 0);
+    ADC_Init(ADC0, &init);
+
+    /* Initialize for single conversion specific to RNG */
+    singleInit.reference = adcRefVEntropy;
+    singleInit.diff      = true;
+    singleInit.posSel    = adcPosSelVSS;
+    singleInit.negSel    = adcNegSelVSS;
+    ADC_InitSingle(ADC0, &singleInit);
+
+    /* Set VINATT to maximum value and clear FIFO */
+    ADC0->SINGLECTRLX |= _ADC_SINGLECTRLX_VINATT_MASK;
+    ADC0->SINGLEFIFOCLEAR = ADC_SINGLEFIFOCLEAR_SINGLEFIFOCLEAR;
+}
+
+static uint32_t randomUint32Get(void)
+{
+    uint8_t  tmp;
+    uint32_t random = 0;
+
+    for (int i = 0; i < 4; i++)
+    {
+        tmp = 0;
+
+        for (int j = 0; j < 3; j++)
+        {
+            ADC_Start(ADC0, adcStartSingle);
+
+            while ((ADC0->IF & ADC_IF_SINGLE) == 0)
+                ;
+
+            tmp |= ((ADC_DataSingleGet(ADC0) & 0x07) << (j * 3));
+        }
+
+        random |= (tmp & 0xff) << (i * 8);
+    }
+
+    return random;
+}
+
+otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(aOutput, error = OT_ERROR_INVALID_ARGS);
+
+    for (uint16_t length = 0; length < aOutputLength; length++)
+    {
+        aOutput[length] = (uint8_t)randomUint32Get();
+    }
+
+exit:
+    return error;
+}
diff --git a/examples/platforms/efr32mg1/fem-control.c b/examples/platforms/efr32mg1/fem-control.c
new file mode 100644
index 0000000..f66415c
--- /dev/null
+++ b/examples/platforms/efr32mg1/fem-control.c
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "hal-config.h"
+
+#if (HAL_FEM_ENABLE)
+#include "util/plugin/plugin-common/fem-control/fem-control.c"
+#endif
diff --git a/examples/platforms/efr32mg1/flash.c b/examples/platforms/efr32mg1/flash.c
new file mode 100644
index 0000000..15d46ea
--- /dev/null
+++ b/examples/platforms/efr32mg1/flash.c
@@ -0,0 +1,364 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for the non-volatile storage.
+ */
+
+#include "openthread-core-efr32-config.h"
+#include <openthread/config.h>
+
+#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE // Use OT NV system
+
+#include "em_msc.h"
+#include <string.h>
+#include <openthread/instance.h>
+
+#define FLASH_PAGE_NUM 2
+#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
+#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * FLASH_PAGE_NUM))
+#define FLASH_SWAP_PAGE_NUM (FLASH_PAGE_NUM / 2)
+#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * FLASH_SWAP_PAGE_NUM)
+
+static inline uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
+{
+    uint32_t address;
+
+    address = FLASH_DATA_START_ADDR + aOffset;
+
+    if (aSwapIndex)
+    {
+        address += FLASH_SWAP_SIZE;
+    }
+
+    return address;
+}
+
+void otPlatFlashInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return FLASH_SWAP_SIZE;
+}
+
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address = mapAddress(aSwapIndex, 0);
+
+    for (uint32_t n = 0; n < FLASH_SWAP_PAGE_NUM; n++, address += FLASH_PAGE_SIZE)
+    {
+        MSC_ErasePage((uint32_t *)address);
+    }
+}
+
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    MSC_WriteWord((uint32_t *)mapAddress(aSwapIndex, aOffset), aData, aSize);
+}
+
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    memcpy(aData, (const uint8_t *)mapAddress(aSwapIndex, aOffset), aSize);
+}
+
+#else // Defaults to Silabs nvm3 system
+
+#include "nvm3.h"
+#include "nvm3_default.h"
+#include <string.h>
+#include <openthread/platform/settings.h>
+#include "common/code_utils.hpp"
+#include "common/logging.hpp"
+
+#define NVM3KEY_DOMAIN_OPENTHREAD 0x20000U
+#define NUM_INDEXED_SETTINGS \
+    OPENTHREAD_CONFIG_MLE_MAX_CHILDREN // Indexed key types are only supported for kKeyChildInfo (=='child table').
+#define ENUM_NVM3_KEY_LIST_SIZE 4      // List size used when enumerating nvm3 keys.
+
+static otError          addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
+static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index);
+static otError          mapNvm3Error(Ecode_t nvm3Res);
+
+void otPlatSettingsInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    if (mapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)) != OT_ERROR_NONE)
+    {
+        otLogDebgPlat("Error initializing nvm3 instance");
+    }
+}
+
+void otPlatSettingsDeinit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    nvm3_close(nvm3_defaultHandle);
+}
+
+otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
+{
+    // Searches through all matching nvm3 keys to find the one with the required
+    // 'index', then reads the nvm3 data into the destination buffer.
+    // (Repeatedly enumerates a list of matching keys from the nvm3 until the
+    // required index is found).
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError  err;
+    uint16_t valueLength = 0;
+
+    nvm3_ObjectKey_t nvm3Key  = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
+    bool             idxFound = false;
+    int              idx      = 0;
+    err                       = OT_ERROR_NOT_FOUND;
+    while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
+    {
+        // Get the next nvm3 key list.
+        nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
+        size_t           objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, nvm3Key,
+                                         makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
+        for (size_t i = 0; i < objCnt; ++i)
+        {
+            nvm3Key = keys[i];
+            if (idx == aIndex)
+            {
+                uint32_t objType;
+                size_t   objLen;
+                err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+                if (err == OT_ERROR_NONE)
+                {
+                    valueLength = objLen;
+
+                    // Only perform read if an input buffer was passed in.
+                    if ((aValue != NULL) && (aValueLength != NULL))
+                    {
+                        // Read all nvm3 obj bytes into a tmp buffer, then copy the required
+                        // number of bytes to the read destination buffer.
+                        uint8_t *buf = malloc(valueLength);
+                        err          = mapNvm3Error(nvm3_readData(nvm3_defaultHandle, nvm3Key, buf, valueLength));
+                        if (err == OT_ERROR_NONE)
+                        {
+                            memcpy(aValue, buf, (valueLength < *aValueLength) ? valueLength : *aValueLength);
+                        }
+                        free(buf);
+                        SuccessOrExit(err);
+                    }
+                }
+                idxFound = true;
+                break;
+            }
+            ++idx;
+        }
+        if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
+        {
+            // Stop searching (there are no more matching nvm3 objects).
+            break;
+        }
+        ++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
+    }
+
+exit:
+    if (aValueLength != NULL)
+    {
+        *aValueLength = valueLength; // always return actual nvm3 object length.
+    }
+
+    return err;
+}
+
+otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError err;
+
+    // Delete all nvm3 objects matching the input key (i.e. the 'setting indexes' of the key).
+    err = otPlatSettingsDelete(aInstance, aKey, -1);
+    if ((err == OT_ERROR_NONE) || (err == OT_ERROR_NOT_FOUND))
+    {
+        // Add new setting object (i.e. 'index0' of the key).
+        err = addSetting(aKey, aValue, aValueLength);
+        SuccessOrExit(err);
+    }
+
+exit:
+    return err;
+}
+
+otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return addSetting(aKey, aValue, aValueLength);
+}
+
+otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
+{
+    // Searches through all matching nvm3 keys to find the one with the required
+    // 'index' (or index = -1 to delete all), then deletes the nvm3 object.
+    // (Repeatedly enumerates a list of matching keys from the nvm3 until the
+    // required index is found).
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError          err;
+    nvm3_ObjectKey_t nvm3Key  = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
+    bool             idxFound = false;
+    int              idx      = 0;
+    err                       = OT_ERROR_NOT_FOUND;
+    while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
+    {
+        // Get the next nvm3 key list.
+        nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
+        size_t           objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, nvm3Key,
+                                         makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
+        for (size_t i = 0; i < objCnt; ++i)
+        {
+            nvm3Key = keys[i];
+            if ((idx == aIndex) || (aIndex == -1))
+            {
+                uint32_t objType;
+                size_t   objLen;
+                err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+                if (err == OT_ERROR_NONE)
+                {
+                    // Delete the nvm3 object.
+                    err = mapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, nvm3Key));
+                    SuccessOrExit(err);
+                }
+                if (aIndex != -1)
+                {
+                    idxFound = true;
+                    break;
+                }
+            }
+            ++idx;
+        }
+        if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
+        {
+            // Stop searching (there are no more matching nvm3 objects).
+            break;
+        }
+        ++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
+    }
+
+exit:
+    return err;
+}
+
+void otPlatSettingsWipe(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    // Delete nvm3 objects for all OT Settings keys (and any of their associated 'indexes').
+    // Note- any OT User nvm3 objects in the OT nvm3 area are NOT be erased.
+    for (uint16_t aKey = 0; aKey < 8; ++aKey)
+    {
+        otPlatSettingsDelete(NULL, aKey, -1);
+    }
+}
+
+// Local functions..
+
+static otError addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    // Helper function- writes input buffer data to a NEW nvm3 object.
+    // nvm3 object is created at the first available Key + index.
+
+    otError err;
+
+    if ((aValueLength == 0) || (aValue == NULL))
+    {
+        err = OT_ERROR_INVALID_ARGS;
+    }
+    else
+    {
+        for (int idx = 0; idx <= NUM_INDEXED_SETTINGS; ++idx)
+        {
+            nvm3_ObjectKey_t nvm3Key;
+            nvm3Key = makeNvm3ObjKey(aKey, idx);
+
+            uint32_t objType;
+            size_t   objLen;
+            err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+            if (err == OT_ERROR_NOT_FOUND)
+            {
+                // Use this index for the new nvm3 object.
+                // Write the binary data to nvm3 (Creates nvm3 object if required).
+                err = mapNvm3Error(nvm3_writeData(nvm3_defaultHandle, nvm3Key, aValue, aValueLength));
+                break;
+            }
+            else if (err != OT_ERROR_NONE)
+            {
+                break;
+            }
+        }
+    }
+
+    return err;
+}
+
+static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index)
+{
+    return (NVM3KEY_DOMAIN_OPENTHREAD | (otSettingsKey << 8) | (index & 0xFF));
+}
+
+static otError mapNvm3Error(Ecode_t nvm3Res)
+{
+    otError err;
+
+    switch (nvm3Res)
+    {
+    case ECODE_NVM3_OK:
+        err = OT_ERROR_NONE;
+        break;
+
+    case ECODE_NVM3_ERR_KEY_NOT_FOUND:
+        err = OT_ERROR_NOT_FOUND;
+        break;
+
+    default:
+        err = OT_ERROR_FAILED;
+        break;
+    }
+
+    return err;
+}
+
+#endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
diff --git a/examples/platforms/efr32mg1/logging.c b/examples/platforms/efr32mg1/logging.c
new file mode 100644
index 0000000..ad873dd
--- /dev/null
+++ b/examples/platforms/efr32mg1/logging.c
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file logging.c
+ * Platform abstraction for the logging
+ *
+ */
+
+#include <openthread-core-config.h>
+#include <openthread/config.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/logging.h>
+
+#include <utils/logging_rtt.h>
+
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
+    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+void efr32LogInit(void)
+{
+    utilsLogRttInit();
+}
+
+void efr32LogDeinit(void)
+{
+    utilsLogRttDeinit();
+}
+
+OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
+{
+    va_list ap;
+
+    va_start(ap, aFormat);
+
+    utilsLogRttOutput(aLogLevel, aLogRegion, aFormat, ap);
+
+    va_end(ap);
+}
+#endif
diff --git a/examples/platforms/efr32mg1/misc.c b/examples/platforms/efr32mg1/misc.c
new file mode 100644
index 0000000..4b2076f
--- /dev/null
+++ b/examples/platforms/efr32mg1/misc.c
@@ -0,0 +1,98 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for miscellaneous behaviors.
+ */
+
+#include <openthread/platform/misc.h>
+
+#include "em_rmu.h"
+#include "platform-efr32.h"
+
+static uint32_t sResetCause;
+
+void efr32MiscInit(void)
+{
+    // Read the cause of last reset.
+    sResetCause = RMU_ResetCauseGet();
+
+    // Clear the register, as the causes cumulate over resets.
+    RMU_ResetCauseClear();
+}
+
+void otPlatReset(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    NVIC_SystemReset();
+}
+
+otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otPlatResetReason reason;
+
+    if (sResetCause & RMU_RSTCAUSE_PORST)
+    {
+        reason = OT_PLAT_RESET_REASON_POWER_ON;
+    }
+    else if (sResetCause & RMU_RSTCAUSE_SYSREQRST)
+    {
+        reason = OT_PLAT_RESET_REASON_SOFTWARE;
+    }
+    else if (sResetCause & RMU_RSTCAUSE_WDOGRST)
+    {
+        reason = OT_PLAT_RESET_REASON_WATCHDOG;
+    }
+    else if (sResetCause & RMU_RSTCAUSE_EXTRST)
+    {
+        reason = OT_PLAT_RESET_REASON_EXTERNAL;
+    }
+    else if (sResetCause & RMU_RSTCAUSE_LOCKUPRST)
+    {
+        reason = OT_PLAT_RESET_REASON_FAULT;
+    }
+    else if ((sResetCause & RMU_RSTCAUSE_AVDDBOD) || (sResetCause & RMU_RSTCAUSE_DECBOD) ||
+             (sResetCause & RMU_RSTCAUSE_DVDDBOD) || (sResetCause & RMU_RSTCAUSE_EM4RST))
+    {
+        reason = OT_PLAT_RESET_REASON_ASSERT;
+    }
+    else
+    {
+        reason = OT_PLAT_RESET_REASON_UNKNOWN;
+    }
+
+    return reason;
+}
+
+void otPlatWakeHost(void)
+{
+    // TODO: implement an operation to wake the host from sleep state.
+}
diff --git a/examples/platforms/efr32mg1/openthread-core-efr32-config-check.h b/examples/platforms/efr32mg1/openthread-core-efr32-config-check.h
new file mode 100644
index 0000000..cf112c9
--- /dev/null
+++ b/examples/platforms/efr32mg1/openthread-core-efr32-config-check.h
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OPENTHREAD_CORE_EFR32_CONFIG_CHECK_H_
+#define OPENTHREAD_CORE_EFR32_CONFIG_CHECK_H_
+
+#include "board_config.h"
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+#error "Platform efr32mg1 doesn't support configuration option: OPENTHREAD_CONFIG_TIME_SYNC_ENABLE"
+#endif
+
+#ifndef RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
+#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+#error "Platform efr32mg1 not configured to support configuration option: OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT"
+#endif
+#endif
+
+#endif /* OPENTHREAD_CORE_EFR32_CONFIG_CHECK_H_ */
diff --git a/examples/platforms/efr32mg1/openthread-core-efr32-config.h b/examples/platforms/efr32mg1/openthread-core-efr32-config.h
new file mode 100644
index 0000000..d1cbde6
--- /dev/null
+++ b/examples/platforms/efr32mg1/openthread-core-efr32-config.h
@@ -0,0 +1,132 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes efr32 compile-time configuration constants
+ *   for OpenThread.
+ */
+
+#include "board_config.h"
+#include "em_msc.h"
+
+#ifndef OPENTHREAD_CORE_EFR32_CONFIG_H_
+#define OPENTHREAD_CORE_EFR32_CONFIG_H_
+
+/**
+ * @def OPENTHREAD_CONFIG_LOG_OUTPUT
+ *
+ * The efr32 platform provides an otPlatLog() function.
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
+#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
+#endif
+
+/*
+ * @def OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+ *
+ * Define to 1 if you want to enable physical layer to support OQPSK modulation in 915MHz band.
+ *
+ */
+#if RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
+#define OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT 1
+#else
+#define OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT 0
+#endif
+
+/*
+ * @def OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+ *
+ * Define to 1 if you want to enable physical layer to support OQPSK modulation in 2.4GHz band.
+ *
+ */
+#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
+#define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 1
+#else
+#define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_INFO
+ *
+ * The platform-specific string to insert into the OpenThread version string.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32"
+
+/*
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
+ *
+ * Define to 1 if you want to enable software retransmission logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
+ *
+ * Define to 1 if you want to enable software CSMA-CA backoff logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
+ *
+ * Define to 1 if you want to enable software energy scanning logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+ *
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
+
+/**
+ * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
+ *
+ * Define to 1 to enable NCP UART support.
+ *
+ */
+#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1
+
+#endif // OPENTHREAD_CORE_EFR32_CONFIG_H_
diff --git a/examples/platforms/efr32mg1/platform-band.h b/examples/platforms/efr32mg1/platform-band.h
new file mode 100644
index 0000000..7c4d912
--- /dev/null
+++ b/examples/platforms/efr32mg1/platform-band.h
@@ -0,0 +1,95 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file defines the frequency band configuration structure for efr32.
+ *
+ */
+
+#ifndef PLATFORM_BAND_H_
+#define PLATFORM_BAND_H_
+
+#include <openthread/platform/radio.h>
+
+#include "rail.h"
+#include "rail_config.h"
+#include "rail_ieee802154.h"
+
+#define RAIL_TX_FIFO_SIZE (OT_RADIO_FRAME_MAX_SIZE + 1)
+
+#define RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY 255
+#define RADIO_SCHEDULER_CHANNEL_SCAN_PRIORITY 255
+#define RADIO_SCHEDULER_CHANNEL_SLIP_TIME 500000UL
+#define RADIO_SCHEDULER_TX_PRIORITY 100
+#define RADIO_SCHEDULER_TX_SLIP_TIME 500000UL
+
+#define RADIO_TIMING_CSMA_OVERHEAD_US 500
+#define RADIO_TIMING_DEFAULT_BYTETIME_US 32   // only used if RAIL_GetBitRate returns 0
+#define RADIO_TIMING_DEFAULT_SYMBOLTIME_US 16 // only used if RAIL_GetSymbolRate returns 0
+
+typedef struct efr32RadioCounters
+{
+    uint64_t mRailPlatTxTriggered;
+    uint64_t mRailPlatRadioReceiveDoneCbCount;
+    uint64_t mRailPlatRadioEnergyScanDoneCbCount;
+    uint64_t mRailPlatRadioTxDoneCbCount;
+    uint64_t mRailTxStarted;
+    uint64_t mRailTxStartFailed;
+    uint64_t mRailEventConfigScheduled;
+    uint64_t mRailEventConfigUnScheduled;
+    uint64_t mRailEventPacketSent;
+    uint64_t mRailEventChannelBusy;
+    uint64_t mRailEventEnergyScanCompleted;
+    uint64_t mRailEventCalNeeded;
+    uint64_t mRailEventPacketReceived;
+    uint64_t mRailEventNoAck;
+    uint64_t mRailEventTxAbort;
+    uint64_t mRailEventSchedulerStatusError;
+    uint64_t mRailEventsSchedulerStatusTransmitBusy;
+    uint32_t mRailEventsSchedulerStatusLastStatus;
+} efr32RadioCounters;
+
+typedef struct efr32CommonConfig
+{
+    RAIL_Config_t mRailConfig;
+#if RADIO_CONFIG_DMP_SUPPORT
+    RAILSched_Config_t railSchedState;
+#endif
+    uint8_t
+        mRailTxFifo[RAIL_TX_FIFO_SIZE]; // must be 2 power between 64 and 4096, and bigger than OT_RADIO_FRAME_MAX_SIZE
+} efr32CommonConfig;
+
+typedef struct efr32BandConfig
+{
+    const RAIL_ChannelConfig_t *mChannelConfig;
+    uint8_t                     mChannelMin;
+    uint8_t                     mChannelMax;
+} efr32BandConfig;
+
+#endif // PLATFORM_BAND_H_
diff --git a/examples/platforms/efr32mg1/platform-efr32.h b/examples/platforms/efr32mg1/platform-efr32.h
new file mode 100644
index 0000000..5ec48e2
--- /dev/null
+++ b/examples/platforms/efr32mg1/platform-efr32.h
@@ -0,0 +1,138 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes the platform-specific initializers.
+ *
+ */
+
+#ifndef PLATFORM_EFR32_H_
+#define PLATFORM_EFR32_H_
+
+#include <openthread/instance.h>
+
+#include "em_device.h"
+#include "em_system.h"
+
+#include "core_cm4.h"
+#include "rail.h"
+
+// Global OpenThread instance structure
+extern otInstance *sInstance;
+
+// Global reference to rail handle
+extern RAIL_Handle_t gRailHandle;
+
+/**
+ * This function initializes the alarm service used by OpenThread.
+ *
+ */
+void efr32AlarmInit(void);
+
+/**
+ * This function performs alarm driver processing.
+ *
+ * @param[in]  aInstance  The OpenThread instance structure.
+ *
+ */
+void efr32AlarmProcess(otInstance *aInstance);
+
+/**
+ * This function initializes the radio service used by OpenThead.
+ *
+ */
+void efr32RadioInit(void);
+
+/**
+ * This function deinitializes the radio service used by OpenThead.
+ *
+ */
+void efr32RadioDeinit(void);
+
+/**
+ * This function performs radio driver processing.
+ *
+ * @param[in]  aInstance  The OpenThread instance structure.
+ *
+ */
+void efr32RadioProcess(otInstance *aInstance);
+
+/**
+ * This function performs UART driver processing.
+ *
+ */
+void efr32UartProcess(void);
+
+/**
+ * Initialization of Misc module.
+ *
+ */
+void efr32MiscInit(void);
+
+/**
+ * Initialization of ADC module for random number generator.
+ *
+ */
+void efr32RandomInit(void);
+
+/**
+ * Initialization of Logger driver.
+ *
+ */
+void efr32LogInit(void);
+
+/**
+ * Deinitialization of Logger driver.
+ *
+ */
+void efr32LogDeinit(void);
+
+/**
+ * Registers the sleep callback handler.  The callback is used to check that
+ * the application has no work pending and that it is safe to put the EFR32
+ * into a low energy sleep mode.
+ *
+ * The callback should return true if it is ok to enter sleep mode. Note
+ * that the callback itself is run with interrupts disabled and so should
+ * be kept as short as possible.  Anny interrupt including those from timers
+ * will wake the EFR32 out of sleep mode.
+ *
+ * @param[in]  aCallback  Callback function.
+ *
+ */
+void efr32SetSleepCallback(bool (*aCallback)(void));
+
+/**
+ * Put the EFR32 into a low power mode.  Before sleeping it will call a callback
+ * in the application registered with efr32SetSleepCallback to ensure that there
+ * is no outstanding work in the application to do.
+ */
+void efr32Sleep(void);
+
+#endif // PLATFORM_EFR32_H_
diff --git a/examples/platforms/efr32mg1/radio.c b/examples/platforms/efr32mg1/radio.c
new file mode 100644
index 0000000..764be71
--- /dev/null
+++ b/examples/platforms/efr32mg1/radio.c
@@ -0,0 +1,1173 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for radio communication.
+ *
+ */
+
+#include <assert.h>
+
+#include "openthread-system.h"
+#include <openthread/config.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+#include <openthread/platform/radio.h>
+
+#include "common/logging.hpp"
+#include "utils/code_utils.h"
+
+#include "utils/soft_source_match_table.h"
+
+#include "board_config.h"
+#include "em_cmu.h"
+#include "em_core.h"
+#include "em_system.h"
+#include "hal-config.h"
+#include "openthread-core-efr32-config.h"
+#include "pa_conversions_efr32.h"
+#include "platform-band.h"
+#include "rail.h"
+#include "rail_config.h"
+#include "rail_ieee802154.h"
+
+enum
+{
+    IEEE802154_MIN_LENGTH = 5,
+    IEEE802154_MAX_LENGTH = 127,
+    IEEE802154_ACK_LENGTH = 5,
+
+    // FCF + DSN + dest PANID + dest addr + src PANID + src addr (without security header)
+    IEEE802154_MAX_MHR_LENGTH = 2 + 1 + 2 + 8 + 2 + 8,
+
+    IEEE802154_FRAME_TYPE_MASK        = 0x7,
+    IEEE802154_FRAME_TYPE_ACK         = 0x2,
+    IEEE802154_FRAME_TYPE_MAC_COMMAND = 0x3,
+    IEEE802154_ACK_REQUEST            = 1 << 5,
+    IEEE802154_DSN_OFFSET             = 2,
+    IEEE802154_FCF_OFFSET             = 0,
+};
+
+enum
+{
+    EFR32_RECEIVE_SENSITIVITY    = -100, // dBm
+    EFR32_RSSI_AVERAGING_TIME    = 16,   // us
+    EFR32_RSSI_AVERAGING_TIMEOUT = 300,  // us
+};
+
+enum
+{
+    EFR32_SCHEDULER_SAMPLE_RSSI_PRIORITY = 10, // High priority
+    EFR32_SCHEDULER_TX_PRIORITY          = 10, // High priority
+    EFR32_SCHEDULER_RX_PRIORITY          = 20, // Low priority
+};
+
+enum
+{
+#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT && RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
+    EFR32_NUM_BAND_CONFIGS = 2,
+#else
+    EFR32_NUM_BAND_CONFIGS = 1,
+#endif
+};
+
+typedef enum
+{
+    ENERGY_SCAN_STATUS_IDLE,
+    ENERGY_SCAN_STATUS_IN_PROGRESS,
+    ENERGY_SCAN_STATUS_COMPLETED
+} energyScanStatus;
+
+typedef enum
+{
+    ENERGY_SCAN_MODE_SYNC,
+    ENERGY_SCAN_MODE_ASYNC
+} energyScanMode;
+
+RAIL_Handle_t gRailHandle;
+
+static volatile bool sTransmitBusy = false;
+static bool          sPromiscuous  = false;
+static otRadioState  sState        = OT_RADIO_STATE_DISABLED;
+
+enum
+{
+    ACKED_WITH_FP_MATCH_LENGTH = 1 + IEEE802154_MAX_MHR_LENGTH, // PHR and MHR
+    ACKED_WITH_FP_SLOTS = 16, // maximum number of Data Request packets in the RX FIFO. Length should be a power of 2.
+};
+
+typedef struct efr32AckedWithFP
+{
+    uint8_t mLength;
+    uint8_t mPacket[ACKED_WITH_FP_MATCH_LENGTH];
+} efr32AckedWithFP;
+static bool              sIsSrcMatchEnabled = false;
+static efr32AckedWithFP  sAckedWithFPFifo[ACKED_WITH_FP_SLOTS];
+static uint32_t          sAckedWithFPReadIndex;
+static volatile uint32_t sAckedWithFPWriteIndex;
+
+static uint8_t      sReceivePsdu[IEEE802154_MAX_LENGTH];
+static otRadioFrame sReceiveFrame;
+static otError      sReceiveError;
+
+static otRadioFrame     sTransmitFrame;
+static uint8_t          sTransmitPsdu[IEEE802154_MAX_LENGTH];
+static volatile otError sTransmitError;
+
+static efr32CommonConfig sCommonConfig;
+static efr32BandConfig   sBandConfigs[EFR32_NUM_BAND_CONFIGS];
+
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+static efr32RadioCounters sRailDebugCounters;
+#endif
+
+static volatile energyScanStatus sEnergyScanStatus;
+static volatile int8_t           sEnergyScanResultDbm;
+static energyScanMode            sEnergyScanMode;
+
+#define QUARTER_DBM_IN_DBM 4
+#define US_IN_MS 1000
+
+static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents);
+
+static const RAIL_IEEE802154_Config_t sRailIeee802154Config = {
+    .addresses = NULL,
+    .ackConfig =
+        {
+            .enable     = true,
+            .ackTimeout = 864,
+            .rxTransitions =
+                {
+                    .success = RAIL_RF_STATE_RX,
+                    .error   = RAIL_RF_STATE_RX,
+                },
+            .txTransitions =
+                {
+                    .success = RAIL_RF_STATE_RX,
+                    .error   = RAIL_RF_STATE_RX,
+                },
+        },
+    .timings =
+        {
+            .idleToRx            = 100,
+            .txToRx              = 192 - 10,
+            .idleToTx            = 100,
+            .rxToTx              = 192,
+            .rxSearchTimeout     = 0,
+            .txToRxSearchTimeout = 0,
+        },
+    .framesMask       = RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES,
+    .promiscuousMode  = false,
+    .isPanCoordinator = false,
+};
+
+#if RADIO_CONFIG_PA_USES_DCDC
+RAIL_DECLARE_TX_POWER_DCDC_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp);
+#else
+RAIL_DECLARE_TX_POWER_VBAT_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp);
+#endif
+
+static int8_t sTxPowerDbm = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
+
+static int8_t sCcaThresholdDbm = -75; // default -75dBm energy detect threshold
+
+static efr32BandConfig *sCurrentBandConfig = NULL;
+
+static RAIL_Handle_t efr32RailInit(efr32CommonConfig *aCommonConfig)
+{
+    RAIL_Status_t status;
+    RAIL_Handle_t handle;
+
+    handle = RAIL_Init(&aCommonConfig->mRailConfig, NULL);
+    assert(handle != NULL);
+
+    status = RAIL_ConfigCal(handle, RAIL_CAL_ALL);
+    assert(status == RAIL_STATUS_NO_ERROR);
+
+    status = RAIL_IEEE802154_Init(handle, &sRailIeee802154Config);
+    assert(status == RAIL_STATUS_NO_ERROR);
+
+    status = RAIL_ConfigEvents(handle, RAIL_EVENTS_ALL,
+                               RAIL_EVENT_RX_ACK_TIMEOUT |                      //
+                                   RAIL_EVENTS_TX_COMPLETION |                  //
+                                   RAIL_EVENT_RX_PACKET_RECEIVED |              //
+                                   RAIL_EVENT_RSSI_AVERAGE_DONE |               //
+                                   RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND | //
+                                   RAIL_EVENT_CAL_NEEDED |                      //
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+                                   RAIL_EVENT_CONFIG_SCHEDULED |   //
+                                   RAIL_EVENT_CONFIG_UNSCHEDULED | //
+#endif
+                                   RAIL_EVENT_SCHEDULER_STATUS //
+    );
+    assert(status == RAIL_STATUS_NO_ERROR);
+
+    uint16_t actualLenth = RAIL_SetTxFifo(handle, aCommonConfig->mRailTxFifo, 0, sizeof(aCommonConfig->mRailTxFifo));
+    assert(actualLenth == sizeof(aCommonConfig->mRailTxFifo));
+
+    return handle;
+}
+
+static void efr32RailConfigLoad(efr32BandConfig *aBandConfig)
+{
+    RAIL_Status_t status;
+#if HAL_PA_2P4_LOWPOWER == 1
+    RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_LP, HAL_PA_VOLTAGE, 10};
+#else
+    RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_HP, HAL_PA_VOLTAGE, 10};
+#endif
+    if (aBandConfig->mChannelConfig != NULL)
+    {
+        uint16_t firstChannel = RAIL_ConfigChannels(gRailHandle, aBandConfig->mChannelConfig, NULL);
+        assert(firstChannel == aBandConfig->mChannelMin);
+
+        txPowerConfig.mode = RAIL_TX_POWER_MODE_SUBGIG;
+    }
+    else
+    {
+        status = RAIL_IEEE802154_Config2p4GHzRadio(gRailHandle);
+        assert(status == RAIL_STATUS_NO_ERROR);
+    }
+    status = RAIL_ConfigTxPower(gRailHandle, &txPowerConfig);
+    assert(status == RAIL_STATUS_NO_ERROR);
+}
+
+static void efr32RadioSetTxPower(int8_t aPowerDbm)
+{
+    RAIL_Status_t              status;
+    RAIL_TxPowerCurvesConfig_t txPowerCurvesConfig = {curves24Hp, curvesSg, curves24Lp, piecewiseSegments};
+
+    status = RAIL_InitTxPowerCurves(&txPowerCurvesConfig);
+    assert(status == RAIL_STATUS_NO_ERROR);
+
+    status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aPowerDbm) * 10);
+    assert(status == RAIL_STATUS_NO_ERROR);
+}
+
+static efr32BandConfig *efr32RadioGetBandConfig(uint8_t aChannel)
+{
+    efr32BandConfig *config = NULL;
+
+    for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
+    {
+        if ((sBandConfigs[i].mChannelMin <= aChannel) && (aChannel <= sBandConfigs[i].mChannelMax))
+        {
+            config = &sBandConfigs[i];
+            break;
+        }
+    }
+
+    return config;
+}
+
+static void efr32ConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle, RAIL_Events_t events))
+{
+    sCommonConfig.mRailConfig.eventsCallback = aEventCallback;
+    sCommonConfig.mRailConfig.protocol       = NULL; // only used by Bluetooth stack
+#if RADIO_CONFIG_DMP_SUPPORT
+    sCommonConfig.mRailConfig.scheduler = &(sCommonConfig.railSchedState);
+#else
+    sCommonConfig.mRailConfig.scheduler = NULL; // only needed for DMP
+#endif
+
+    uint8_t index = 0;
+
+#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
+    sBandConfigs[index].mChannelConfig = NULL;
+    sBandConfigs[index].mChannelMin    = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN;
+    sBandConfigs[index].mChannelMax    = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX;
+
+    index++;
+#endif
+
+#if RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
+    sBandConfigs[index].mChannelConfig = channelConfigs[0];
+    sBandConfigs[index].mChannelMin    = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN;
+    sBandConfigs[index].mChannelMax    = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX;
+#endif
+
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+    memset(&sRailDebugCounters, 0x00, sizeof(efr32RadioCounters));
+#endif
+
+    gRailHandle = efr32RailInit(&sCommonConfig);
+    assert(gRailHandle != NULL);
+    efr32RailConfigLoad(&(sBandConfigs[0]));
+}
+
+void efr32RadioInit(void)
+{
+    RAIL_Status_t status;
+
+    // check if RAIL_TX_FIFO_SIZE is power of two..
+    assert((RAIL_TX_FIFO_SIZE & (RAIL_TX_FIFO_SIZE - 1)) == 0);
+
+    // check the limits of the RAIL_TX_FIFO_SIZE.
+    assert((RAIL_TX_FIFO_SIZE >= 64) || (RAIL_TX_FIFO_SIZE <= 4096));
+
+    efr32ConfigInit(RAILCb_Generic);
+
+    CMU_ClockEnable(cmuClock_PRS, true);
+
+    status = RAIL_ConfigSleep(gRailHandle, RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED);
+    assert(status == RAIL_STATUS_NO_ERROR);
+
+    sReceiveFrame.mLength  = 0;
+    sReceiveFrame.mPsdu    = sReceivePsdu;
+    sTransmitFrame.mLength = 0;
+    sTransmitFrame.mPsdu   = sTransmitPsdu;
+
+    sCurrentBandConfig = efr32RadioGetBandConfig(OPENTHREAD_CONFIG_DEFAULT_CHANNEL);
+    assert(sCurrentBandConfig != NULL);
+
+    memset(sAckedWithFPFifo, 0, sizeof(sAckedWithFPFifo));
+    sAckedWithFPWriteIndex = 0;
+    sAckedWithFPReadIndex  = 0;
+
+    efr32RadioSetTxPower(sTxPowerDbm);
+
+    sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
+    sTransmitError    = OT_ERROR_NONE;
+    sTransmitBusy     = false;
+
+    otLogInfoPlat("Initialized", NULL);
+}
+
+void efr32RadioDeinit(void)
+{
+    RAIL_Status_t status;
+
+    RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
+    status = RAIL_ConfigEvents(gRailHandle, RAIL_EVENTS_ALL, 0);
+    assert(status == RAIL_STATUS_NO_ERROR);
+
+    sCurrentBandConfig = NULL;
+}
+
+static otError efr32StartEnergyScan(energyScanMode aMode, uint16_t aChannel, RAIL_Time_t aAveragingTimeUs)
+{
+    RAIL_Status_t    status;
+    otError          error  = OT_ERROR_NONE;
+    efr32BandConfig *config = NULL;
+
+    otEXPECT_ACTION(sEnergyScanStatus == ENERGY_SCAN_STATUS_IDLE, error = OT_ERROR_BUSY);
+
+    sEnergyScanStatus = ENERGY_SCAN_STATUS_IN_PROGRESS;
+    sEnergyScanMode   = aMode;
+
+    RAIL_Idle(gRailHandle, RAIL_IDLE, true);
+
+    config = efr32RadioGetBandConfig(aChannel);
+    otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS);
+
+    if (sCurrentBandConfig != config)
+    {
+        efr32RailConfigLoad(config);
+        sCurrentBandConfig = config;
+    }
+
+    RAIL_SchedulerInfo_t scanSchedulerInfo = {.priority        = RADIO_SCHEDULER_CHANNEL_SCAN_PRIORITY,
+                                              .slipTime        = RADIO_SCHEDULER_CHANNEL_SLIP_TIME,
+                                              .transactionTime = aAveragingTimeUs};
+
+    status = RAIL_StartAverageRssi(gRailHandle, aChannel, aAveragingTimeUs, &scanSchedulerInfo);
+    otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
+
+exit:
+    return error;
+}
+
+void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint64_t eui64;
+    uint8_t *eui64Ptr = NULL;
+
+    eui64    = SYSTEM_GetUnique();
+    eui64Ptr = (uint8_t *)&eui64;
+
+    for (uint8_t i = 0; i < OT_EXT_ADDRESS_SIZE; i++)
+    {
+        aIeeeEui64[i] = eui64Ptr[(OT_EXT_ADDRESS_SIZE - 1) - i];
+    }
+}
+
+void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    RAIL_Status_t status;
+
+    otLogInfoPlat("PANID=%X", aPanId);
+
+    utilsSoftSrcMatchSetPanId(aPanId);
+
+    status = RAIL_IEEE802154_SetPanId(gRailHandle, aPanId, 0);
+    assert(status == RAIL_STATUS_NO_ERROR);
+}
+
+void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    RAIL_Status_t status;
+
+    otLogInfoPlat("ExtAddr=%X%X%X%X%X%X%X%X", aAddress->m8[7], aAddress->m8[6], aAddress->m8[5], aAddress->m8[4],
+                  aAddress->m8[3], aAddress->m8[2], aAddress->m8[1], aAddress->m8[0]);
+
+    status = RAIL_IEEE802154_SetLongAddress(gRailHandle, (uint8_t *)aAddress->m8, 0);
+    assert(status == RAIL_STATUS_NO_ERROR);
+}
+
+void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    RAIL_Status_t status;
+
+    otLogInfoPlat("ShortAddr=%X", aAddress);
+
+    status = RAIL_IEEE802154_SetShortAddress(gRailHandle, aAddress, 0);
+    assert(status == RAIL_STATUS_NO_ERROR);
+}
+
+bool otPlatRadioIsEnabled(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return (sState != OT_RADIO_STATE_DISABLED);
+}
+
+otError otPlatRadioEnable(otInstance *aInstance)
+{
+    otEXPECT(!otPlatRadioIsEnabled(aInstance));
+
+    otLogInfoPlat("State=OT_RADIO_STATE_SLEEP", NULL);
+    sState = OT_RADIO_STATE_SLEEP;
+
+exit:
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioDisable(otInstance *aInstance)
+{
+    otEXPECT(otPlatRadioIsEnabled(aInstance));
+
+    otLogInfoPlat("State=OT_RADIO_STATE_DISABLED", NULL);
+    sState = OT_RADIO_STATE_DISABLED;
+
+exit:
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioSleep(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION((sState != OT_RADIO_STATE_TRANSMIT) && (sState != OT_RADIO_STATE_DISABLED),
+                    error = OT_ERROR_INVALID_STATE);
+
+    otLogInfoPlat("State=OT_RADIO_STATE_SLEEP", NULL);
+
+    RAIL_Idle(gRailHandle, RAIL_IDLE, true);
+    sState = OT_RADIO_STATE_SLEEP;
+
+exit:
+    return error;
+}
+
+otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
+{
+    otError          error = OT_ERROR_NONE;
+    RAIL_Status_t    status;
+    efr32BandConfig *config;
+
+    OT_UNUSED_VARIABLE(aInstance);
+    otEXPECT_ACTION(sState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
+
+    config = efr32RadioGetBandConfig(aChannel);
+    otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS);
+
+    if (sCurrentBandConfig != config)
+    {
+        RAIL_Idle(gRailHandle, RAIL_IDLE, true);
+        efr32RailConfigLoad(config);
+        sCurrentBandConfig = config;
+    }
+
+    RAIL_SchedulerInfo_t bgRxSchedulerInfo = {
+        .priority = RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY,
+        // sliptime/transaction time is not used for bg rx
+    };
+
+    status = RAIL_StartRx(gRailHandle, aChannel, &bgRxSchedulerInfo);
+    otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
+
+    otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL);
+    sState                 = OT_RADIO_STATE_RECEIVE;
+    sReceiveFrame.mChannel = aChannel;
+
+exit:
+    return error;
+}
+
+otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
+{
+    otError           error      = OT_ERROR_NONE;
+    RAIL_CsmaConfig_t csmaConfig = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA;
+    RAIL_TxOptions_t  txOptions  = RAIL_TX_OPTIONS_DEFAULT;
+    efr32BandConfig * config;
+    RAIL_Status_t     status;
+    uint8_t           frameLength;
+
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+    sRailDebugCounters.mRailPlatTxTriggered++;
+#endif
+
+    assert(sTransmitBusy == false);
+
+    otEXPECT_ACTION((sState != OT_RADIO_STATE_DISABLED) && (sState != OT_RADIO_STATE_TRANSMIT),
+                    error = OT_ERROR_INVALID_STATE);
+
+    config = efr32RadioGetBandConfig(aFrame->mChannel);
+    otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS);
+
+    sState         = OT_RADIO_STATE_TRANSMIT;
+    sTransmitError = OT_ERROR_NONE;
+    sTransmitBusy  = true;
+
+    if (sCurrentBandConfig != config)
+    {
+        RAIL_Idle(gRailHandle, RAIL_IDLE, true);
+        efr32RailConfigLoad(config);
+        sCurrentBandConfig = config;
+    }
+
+    frameLength = (uint8_t)aFrame->mLength;
+    RAIL_WriteTxFifo(gRailHandle, &frameLength, sizeof frameLength, true);
+    RAIL_WriteTxFifo(gRailHandle, aFrame->mPsdu, frameLength - 2, false);
+
+    RAIL_SchedulerInfo_t txSchedulerInfo = {
+        .priority        = RADIO_SCHEDULER_TX_PRIORITY,
+        .slipTime        = RADIO_SCHEDULER_CHANNEL_SLIP_TIME,
+        .transactionTime = 0, // will be calculated later if DMP is used
+    };
+
+    if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST)
+    {
+        txOptions |= RAIL_TX_OPTION_WAIT_FOR_ACK;
+
+#if RADIO_CONFIG_DMP_SUPPORT
+        // time we wait for ACK
+        if (RAIL_GetSymbolRate(gRailHandle) > 0)
+        {
+            txSchedulerInfo.transactionTime += 12 * 1e6 / RAIL_GetSymbolRate(gRailHandle);
+        }
+        else
+        {
+            txSchedulerInfo.transactionTime += 12 * RADIO_TIMING_DEFAULT_SYMBOLTIME_US;
+        }
+#endif
+    }
+
+#if RADIO_CONFIG_DMP_SUPPORT
+    // time needed for the frame itself
+    // 4B preamble, 1B SFD, 1B PHR is not counted in frameLength
+    if (RAIL_GetBitRate(gRailHandle) > 0)
+    {
+        txSchedulerInfo.transactionTime = (frameLength + 4 + 1 + 1) * 8 * 1e6 / RAIL_GetBitRate(gRailHandle);
+    }
+    else
+    { // assume 250kbps
+        txSchedulerInfo.transactionTime = (frameLength + 4 + 1 + 1) * RADIO_TIMING_DEFAULT_BYTETIME_US;
+    }
+#endif
+
+    if (aFrame->mInfo.mTxInfo.mCsmaCaEnabled)
+    {
+#if RADIO_CONFIG_DMP_SUPPORT
+        // time needed for CSMA/CA
+        txSchedulerInfo.transactionTime += RADIO_TIMING_CSMA_OVERHEAD_US;
+#endif
+        csmaConfig.csmaTries    = aFrame->mInfo.mTxInfo.mMaxCsmaBackoffs;
+        csmaConfig.ccaThreshold = sCcaThresholdDbm;
+
+        status = RAIL_StartCcaCsmaTx(gRailHandle, aFrame->mChannel, txOptions, &csmaConfig, &txSchedulerInfo);
+    }
+    else
+    {
+        status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, &txSchedulerInfo);
+    }
+
+    if (status == RAIL_STATUS_NO_ERROR)
+    {
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        sRailDebugCounters.mRailTxStarted++;
+#endif
+        otPlatRadioTxStarted(aInstance, aFrame);
+    }
+    else
+    {
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        sRailDebugCounters.mRailTxStartFailed++;
+#endif
+        sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
+        sTransmitBusy  = false;
+        otSysEventSignalPending();
+    }
+
+exit:
+    return error;
+}
+
+otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return &sTransmitFrame;
+}
+
+int8_t otPlatRadioGetRssi(otInstance *aInstance)
+{
+    otError  error;
+    uint32_t start;
+    int8_t   rssi = OT_RADIO_RSSI_INVALID;
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    error = efr32StartEnergyScan(ENERGY_SCAN_MODE_SYNC, sReceiveFrame.mChannel, EFR32_RSSI_AVERAGING_TIME);
+    otEXPECT(error == OT_ERROR_NONE);
+
+    start = RAIL_GetTime();
+
+    // waiting for the event RAIL_EVENT_RSSI_AVERAGE_DONE
+    while (sEnergyScanStatus == ENERGY_SCAN_STATUS_IN_PROGRESS &&
+           ((RAIL_GetTime() - start) < EFR32_RSSI_AVERAGING_TIMEOUT))
+        ;
+
+    if (sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED)
+    {
+        rssi = sEnergyScanResultDbm;
+    }
+
+    sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
+exit:
+    return rssi;
+}
+
+otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN;
+}
+
+bool otPlatRadioGetPromiscuous(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return sPromiscuous;
+}
+
+void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    RAIL_Status_t status;
+
+    sPromiscuous = aEnable;
+
+    status = RAIL_IEEE802154_SetPromiscuousMode(gRailHandle, aEnable);
+    assert(status == RAIL_STATUS_NO_ERROR);
+}
+
+void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    // set Frame Pending bit for all outgoing ACKs if aEnable is false
+    sIsSrcMatchEnabled = aEnable;
+}
+
+static bool sAckedWithFPFifoIsFull(void)
+{
+    return (uint32_t)(sAckedWithFPWriteIndex - sAckedWithFPReadIndex) == otARRAY_LENGTH(sAckedWithFPFifo);
+}
+
+static bool sAckedWithFPFifoIsEmpty(void)
+{
+    return (uint32_t)(sAckedWithFPWriteIndex - sAckedWithFPReadIndex) == 0;
+}
+
+static efr32AckedWithFP *sAckedWithFPFifoGetWriteSlot(void)
+{
+    uint32_t idx = sAckedWithFPWriteIndex & (otARRAY_LENGTH(sAckedWithFPFifo) - 1);
+    return &sAckedWithFPFifo[idx];
+}
+
+static const efr32AckedWithFP *sAckedWithFPFifoGetReadSlot(void)
+{
+    uint32_t idx = sAckedWithFPReadIndex & (otARRAY_LENGTH(sAckedWithFPFifo) - 1);
+    return &sAckedWithFPFifo[idx];
+}
+
+static void insertIeee802154DataRequestCommand(RAIL_Handle_t aRailHandle)
+{
+    assert(!sAckedWithFPFifoIsFull());
+    efr32AckedWithFP *const slot = sAckedWithFPFifoGetWriteSlot();
+
+    RAIL_RxPacketInfo_t packetInfo;
+
+    RAIL_GetRxIncomingPacketInfo(aRailHandle, &packetInfo);
+    assert(packetInfo.packetBytes >= 4); // PHR + FCF + DSN
+
+    if (packetInfo.packetBytes > sizeof(slot->mPacket))
+    {
+        packetInfo.packetBytes = sizeof(slot->mPacket);
+        if (packetInfo.firstPortionBytes >= sizeof(slot->mPacket))
+        {
+            packetInfo.firstPortionBytes = sizeof(slot->mPacket);
+            packetInfo.lastPortionData   = NULL;
+        }
+    }
+    slot->mLength = packetInfo.packetBytes;
+    RAIL_CopyRxPacket(slot->mPacket, &packetInfo);
+
+    ++sAckedWithFPWriteIndex;
+}
+
+static bool wasAckedWithFramePending(const uint8_t *aPsdu, uint8_t aPsduLength)
+{
+    bool     ackedWithFramePending = false;
+    uint16_t fcf                   = aPsdu[IEEE802154_FCF_OFFSET] | (aPsdu[IEEE802154_FCF_OFFSET + 1] << 8);
+
+    otEXPECT((fcf & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_MAC_COMMAND);
+
+    while (!(ackedWithFramePending || sAckedWithFPFifoIsEmpty()))
+    {
+        const efr32AckedWithFP *const slot = sAckedWithFPFifoGetReadSlot();
+        if ((slot->mPacket[0] == aPsduLength) && (memcmp(slot->mPacket + 1, aPsdu, slot->mLength - 1) == 0))
+        {
+            ackedWithFramePending = true;
+        }
+        ++sAckedWithFPReadIndex;
+    }
+
+exit:
+    return ackedWithFramePending;
+}
+
+static void processNextRxPacket(otInstance *aInstance)
+{
+    RAIL_RxPacketHandle_t  packetHandle = RAIL_RX_PACKET_HANDLE_INVALID;
+    RAIL_RxPacketInfo_t    packetInfo;
+    RAIL_RxPacketDetails_t packetDetails;
+    RAIL_Status_t          status;
+    uint16_t               length;
+
+    packetHandle = RAIL_GetRxPacketInfo(gRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo);
+
+    otEXPECT_ACTION(packetHandle != RAIL_RX_PACKET_HANDLE_INVALID &&
+                        packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS,
+                    packetHandle = RAIL_RX_PACKET_HANDLE_INVALID);
+
+    status = RAIL_GetRxPacketDetailsAlt(gRailHandle, packetHandle, &packetDetails);
+    otEXPECT(status == RAIL_STATUS_NO_ERROR);
+
+    length = packetInfo.packetBytes + 1;
+
+    // check the length in recv packet info structure; RAIL should take care of this.
+    assert(length == packetInfo.firstPortionData[0]);
+
+    // check the length validity of recv packet; RAIL should take care of this.
+    assert(length >= IEEE802154_MIN_LENGTH && length <= IEEE802154_MAX_LENGTH);
+
+    otLogInfoPlat("Received data:%d", length);
+
+    // skip length byte
+    assert(packetInfo.firstPortionBytes > 0);
+    packetInfo.firstPortionData++;
+    packetInfo.firstPortionBytes--;
+    packetInfo.packetBytes--;
+
+    // read packet
+    RAIL_CopyRxPacket(sReceiveFrame.mPsdu, &packetInfo);
+
+    status = RAIL_ReleaseRxPacket(gRailHandle, packetHandle);
+    if (status == RAIL_STATUS_NO_ERROR)
+    {
+        packetHandle = RAIL_RX_PACKET_HANDLE_INVALID;
+    }
+
+    sReceiveFrame.mLength = length;
+
+    if (packetDetails.isAck)
+    {
+        assert((length == IEEE802154_ACK_LENGTH) &&
+               (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK);
+
+        RAIL_YieldRadio(gRailHandle);
+        sTransmitBusy = false;
+
+        if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])
+        {
+            sTransmitError = OT_ERROR_NONE;
+        }
+        else
+        {
+            sTransmitError = OT_ERROR_NO_ACK;
+        }
+    }
+    else
+    {
+        // signal MAC layer for each received frame if promiscuous is enabled
+        // otherwise only signal MAC layer for non-ACK frame
+        otEXPECT(sPromiscuous || (length != IEEE802154_ACK_LENGTH));
+
+        sReceiveError = OT_ERROR_NONE;
+
+        sReceiveFrame.mInfo.mRxInfo.mRssi = packetDetails.rssi;
+        sReceiveFrame.mInfo.mRxInfo.mLqi  = packetDetails.lqi;
+
+        // Get the timestamp when the SFD was received
+        assert(packetDetails.timeReceived.timePosition != RAIL_PACKET_TIME_INVALID);
+        packetDetails.timeReceived.totalPacketBytes = length + 1;
+
+        status = RAIL_GetRxTimeSyncWordEndAlt(gRailHandle, &packetDetails);
+        assert(status == RAIL_STATUS_NO_ERROR);
+        sReceiveFrame.mInfo.mRxInfo.mTimestamp = packetDetails.timeReceived.packetTime;
+
+        // Set this flag only when the packet is really acknowledged with frame pending set.
+        sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending =
+            wasAckedWithFramePending(sReceiveFrame.mPsdu, sReceiveFrame.mLength);
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+        if (otPlatDiagModeGet())
+        {
+            otPlatDiagRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
+        }
+        else
+#endif
+        {
+            otLogInfoPlat("Received %d bytes", sReceiveFrame.mLength);
+            otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+            sRailDebugCounters.mRailPlatRadioReceiveDoneCbCount++;
+#endif
+        }
+    }
+
+    otSysEventSignalPending();
+
+exit:
+
+    if (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID)
+    {
+        RAIL_ReleaseRxPacket(gRailHandle, packetHandle);
+    }
+}
+
+static void ieee802154DataRequestCommand(RAIL_Handle_t aRailHandle)
+{
+    RAIL_Status_t status;
+
+    if (sIsSrcMatchEnabled)
+    {
+        RAIL_IEEE802154_Address_t sourceAddress;
+
+        status = RAIL_IEEE802154_GetAddress(aRailHandle, &sourceAddress);
+        assert(status == RAIL_STATUS_NO_ERROR);
+
+        if ((sourceAddress.length == RAIL_IEEE802154_LongAddress &&
+             utilsSoftSrcMatchExtFindEntry((otExtAddress *)sourceAddress.longAddress) >= 0) ||
+            (sourceAddress.length == RAIL_IEEE802154_ShortAddress &&
+             utilsSoftSrcMatchShortFindEntry(sourceAddress.shortAddress) >= 0))
+        {
+            status = RAIL_IEEE802154_SetFramePending(aRailHandle);
+            assert(status == RAIL_STATUS_NO_ERROR);
+            insertIeee802154DataRequestCommand(aRailHandle);
+        }
+    }
+    else
+    {
+        status = RAIL_IEEE802154_SetFramePending(aRailHandle);
+        assert(status == RAIL_STATUS_NO_ERROR);
+        insertIeee802154DataRequestCommand(aRailHandle);
+    }
+}
+
+static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
+{
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+    if (aEvents & RAIL_EVENT_CONFIG_SCHEDULED)
+    {
+        sRailDebugCounters.mRailEventConfigScheduled++;
+    }
+    if (aEvents & RAIL_EVENT_CONFIG_UNSCHEDULED)
+    {
+        sRailDebugCounters.mRailEventConfigUnScheduled++;
+    }
+#endif
+    if (aEvents & RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND)
+    {
+        ieee802154DataRequestCommand(aRailHandle);
+    }
+
+    if (aEvents & RAIL_EVENTS_TX_COMPLETION)
+    {
+        if (aEvents & RAIL_EVENT_TX_PACKET_SENT)
+        {
+            if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
+            {
+                RAIL_YieldRadio(aRailHandle);
+                sTransmitError = OT_ERROR_NONE;
+                sTransmitBusy  = false;
+            }
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+            sRailDebugCounters.mRailEventPacketSent++;
+#endif
+        }
+        else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY)
+        {
+            RAIL_YieldRadio(aRailHandle);
+            sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
+            sTransmitBusy  = false;
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+            sRailDebugCounters.mRailEventChannelBusy++;
+#endif
+        }
+        else
+        {
+            RAIL_YieldRadio(aRailHandle);
+            sTransmitError = OT_ERROR_ABORT;
+            sTransmitBusy  = false;
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+            sRailDebugCounters.mRailEventTxAbort++;
+#endif
+        }
+    }
+
+    if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT)
+    {
+        RAIL_YieldRadio(aRailHandle);
+        sTransmitError = OT_ERROR_NO_ACK;
+        sTransmitBusy  = false;
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        sRailDebugCounters.mRailEventNoAck++;
+#endif
+    }
+
+    if (aEvents & RAIL_EVENT_RX_PACKET_RECEIVED)
+    {
+        RAIL_HoldRxPacket(aRailHandle);
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        sRailDebugCounters.mRailEventPacketReceived++;
+#endif
+    }
+
+    if (aEvents & RAIL_EVENT_CAL_NEEDED)
+    {
+        RAIL_Status_t status;
+
+        status = RAIL_Calibrate(aRailHandle, NULL, RAIL_CAL_ALL_PENDING);
+        assert(status == RAIL_STATUS_NO_ERROR);
+
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        sRailDebugCounters.mRailEventCalNeeded++;
+#endif
+    }
+
+    if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE)
+    {
+        const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle);
+        RAIL_YieldRadio(aRailHandle);
+
+        sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED;
+
+        if (energyScanResultQuarterDbm == RAIL_RSSI_INVALID)
+        {
+            sEnergyScanResultDbm = OT_RADIO_RSSI_INVALID;
+        }
+        else
+        {
+            sEnergyScanResultDbm = energyScanResultQuarterDbm / QUARTER_DBM_IN_DBM;
+        }
+
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        sRailDebugCounters.mRailPlatRadioEnergyScanDoneCbCount++;
+#endif
+    }
+    if (aEvents & RAIL_EVENT_SCHEDULER_STATUS)
+    {
+        RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle);
+
+        assert(status != RAIL_SCHEDULER_STATUS_INTERNAL_ERROR);
+
+        if (status == RAIL_SCHEDULER_STATUS_CCA_CSMA_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL ||
+            status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL ||
+            (status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy) ||
+            (status == RAIL_SCHEDULER_STATUS_EVENT_INTERRUPTED && sTransmitBusy))
+        {
+            sTransmitError = OT_ERROR_ABORT;
+            sTransmitBusy  = false;
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+            sRailDebugCounters.mRailEventSchedulerStatusError++;
+#endif
+        }
+        else if (status == RAIL_SCHEDULER_STATUS_AVERAGE_RSSI_FAIL)
+        {
+            sEnergyScanStatus    = ENERGY_SCAN_STATUS_COMPLETED;
+            sEnergyScanResultDbm = OT_RADIO_RSSI_INVALID;
+        }
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        else if (sTransmitBusy)
+        {
+            sRailDebugCounters.mRailEventsSchedulerStatusLastStatus = status;
+            sRailDebugCounters.mRailEventsSchedulerStatusTransmitBusy++;
+        }
+#endif
+    }
+
+    otSysEventSignalPending();
+}
+
+otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return efr32StartEnergyScan(ENERGY_SCAN_MODE_ASYNC, aScanChannel, (RAIL_Time_t)aScanDuration * US_IN_MS);
+}
+
+void efr32RadioProcess(otInstance *aInstance)
+{
+    // We should process the received packet first. Adding it at the end of this function,
+    // will delay the stack notification until the next call to efr32RadioProcess()
+    processNextRxPacket(aInstance);
+
+    if (sState == OT_RADIO_STATE_TRANSMIT && sTransmitBusy == false)
+    {
+        if (sTransmitError != OT_ERROR_NONE)
+        {
+            otLogDebgPlat("Transmit failed ErrorCode=%d", sTransmitError);
+        }
+
+        sState = OT_RADIO_STATE_RECEIVE;
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+        if (otPlatDiagModeGet())
+        {
+            otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, sTransmitError);
+        }
+        else
+#endif
+            if (((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) || (sTransmitError != OT_ERROR_NONE))
+        {
+            otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, sTransmitError);
+        }
+        else
+        {
+            otPlatRadioTxDone(aInstance, &sTransmitFrame, &sReceiveFrame, sTransmitError);
+        }
+
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        sRailDebugCounters.mRailPlatRadioTxDoneCbCount++;
+#endif
+
+        otSysEventSignalPending();
+    }
+    else if (sEnergyScanMode == ENERGY_SCAN_MODE_ASYNC && sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED)
+    {
+        sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
+        otPlatRadioEnergyScanDone(aInstance, sEnergyScanResultDbm);
+        otSysEventSignalPending();
+
+#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
+        sRailDebugCounters.mRailEventEnergyScanCompleted++;
+#endif
+    }
+}
+
+otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(aPower != NULL, error = OT_ERROR_INVALID_ARGS);
+    *aPower = sTxPowerDbm;
+
+exit:
+    return error;
+}
+
+otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    RAIL_Status_t status;
+
+    status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aPower) * 10);
+    assert(status == RAIL_STATUS_NO_ERROR);
+
+    sTxPowerDbm = aPower;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NONE;
+    otEXPECT_ACTION(aThreshold != NULL, error = OT_ERROR_INVALID_ARGS);
+
+    *aThreshold = sCcaThresholdDbm;
+
+exit:
+    return error;
+}
+
+otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sCcaThresholdDbm = aThreshold;
+
+    return OT_ERROR_NONE;
+}
+
+int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return EFR32_RECEIVE_SENSITIVITY;
+}
diff --git a/examples/platforms/efr32mg1/rail_config.h b/examples/platforms/efr32mg1/rail_config.h
new file mode 100644
index 0000000..5a62825
--- /dev/null
+++ b/examples/platforms/efr32mg1/rail_config.h
@@ -0,0 +1,14 @@
+#ifndef __RAIL_CONFIG_H__
+#define __RAIL_CONFIG_H__
+
+#include "board_config.h"
+#include "rail_types.h"
+#include <stdint.h>
+
+#define RADIO_CONFIG_XTAL_FREQUENCY 38400000UL
+
+#if RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
+extern const RAIL_ChannelConfig_t *channelConfigs[];
+#endif
+
+#endif // __RAIL_CONFIG_H__
diff --git a/examples/platforms/efr32mg1/startup-gcc.c b/examples/platforms/efr32mg1/startup-gcc.c
new file mode 100644
index 0000000..85c9e2a
--- /dev/null
+++ b/examples/platforms/efr32mg1/startup-gcc.c
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements gcc-specific startup code for the efr32.
+ */
+
+__extension__ typedef int __guard __attribute__((mode(__DI__)));
+
+int __cxa_guard_acquire(__guard *g)
+{
+    return !*(char *)(g);
+}
+
+void __cxa_guard_release(__guard *g)
+{
+    *(char *)g = 1;
+}
+
+void __cxa_guard_abort(__guard *g)
+{
+    (void)g;
+}
+
+void __cxa_pure_virtual(void)
+{
+    while (1)
+        ;
+}
diff --git a/examples/platforms/efr32mg1/system.c b/examples/platforms/efr32mg1/system.c
new file mode 100644
index 0000000..7b1aa3c
--- /dev/null
+++ b/examples/platforms/efr32mg1/system.c
@@ -0,0 +1,178 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *   This file includes the platform-specific initializers.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "openthread-system.h"
+#include <openthread/platform/uart.h>
+
+#include "common/logging.hpp"
+
+#include "bsp.h"
+#include "em_chip.h"
+#include "em_cmu.h"
+#include "em_core.h"
+#include "em_emu.h"
+#include "em_system.h"
+#include "hal-config.h"
+#include "hal_common.h"
+#include "rail.h"
+#include "sl_mpu.h"
+#include "sl_sleeptimer.h"
+
+#include "openthread-core-efr32-config.h"
+#include "platform-efr32.h"
+
+#if (HAL_FEM_ENABLE)
+#include "fem-control.h"
+#endif
+
+#define USE_EFR32_LOG (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
+
+void halInitChipSpecific(void);
+
+otInstance *sInstance;
+static bool (*sCanSleepCallback)(void);
+
+void otSysInit(int argc, char *argv[])
+{
+    OT_UNUSED_VARIABLE(argc);
+    OT_UNUSED_VARIABLE(argv);
+    sl_status_t status;
+
+    __disable_irq();
+
+#undef FIXED_EXCEPTION
+#define FIXED_EXCEPTION(vectorNumber, functionName, deviceIrqn, deviceIrqHandler)
+#define EXCEPTION(vectorNumber, functionName, deviceIrqn, deviceIrqHandler, priorityLevel, subpriority) \
+    NVIC_SetPriority(deviceIrqn, NVIC_EncodePriority(PRIGROUP_POSITION, priorityLevel, subpriority));
+#include NVIC_CONFIG
+#undef EXCEPTION
+
+    NVIC_SetPriorityGrouping(PRIGROUP_POSITION);
+    CHIP_Init();
+    halInitChipSpecific();
+    BSP_Init(BSP_INIT_BCC);
+
+    CMU_ClockSelectSet(cmuClock_LFE, cmuSelect_LFRCO);
+    CMU_ClockEnable(cmuClock_CORELE, true);
+    CMU_ClockEnable(cmuClock_RTCC, true);
+    status = sl_sleeptimer_init();
+    assert(status == SL_STATUS_OK);
+
+#if (HAL_FEM_ENABLE)
+    initFem();
+    wakeupFem();
+#endif
+
+    __enable_irq();
+
+#if USE_EFR32_LOG
+    efr32LogInit();
+#endif
+    efr32RadioInit();
+    efr32AlarmInit();
+    efr32MiscInit();
+    efr32RandomInit();
+}
+
+bool otSysPseudoResetWasRequested(void)
+{
+    return false;
+}
+
+void otSysDeinit(void)
+{
+    efr32RadioDeinit();
+
+#if USE_EFR32_LOG
+    efr32LogDeinit();
+#endif
+}
+
+void efr32SetSleepCallback(bool (*aCallback)(void))
+{
+    sCanSleepCallback = aCallback;
+}
+
+void efr32Sleep(void)
+{
+    bool canDeepSleep      = false;
+    int  wakeupProcessTime = 1000;
+    CORE_DECLARE_IRQ_STATE;
+
+    if (RAIL_Sleep(wakeupProcessTime, &canDeepSleep) == RAIL_STATUS_NO_ERROR)
+    {
+        if (canDeepSleep)
+        {
+            CORE_ENTER_ATOMIC();
+            if (sCanSleepCallback != NULL && sCanSleepCallback())
+            {
+                EMU_EnterEM2(true);
+            }
+            CORE_EXIT_ATOMIC();
+            // TODO OT will handle an interrupt here and it mustn't call any RAIL APIs
+
+            while (RAIL_Wake(0) != RAIL_STATUS_NO_ERROR)
+            {
+            }
+        }
+        else
+        {
+            CORE_ENTER_ATOMIC();
+            if (sCanSleepCallback != NULL && sCanSleepCallback())
+            {
+                EMU_EnterEM1();
+            }
+            CORE_EXIT_ATOMIC();
+        }
+    }
+}
+
+void otSysProcessDrivers(otInstance *aInstance)
+{
+    sInstance = aInstance;
+
+    // should sleep and wait for interrupts here
+
+    efr32UartProcess();
+    efr32RadioProcess(aInstance);
+    efr32AlarmProcess(aInstance);
+}
+
+__WEAK void otSysEventSignalPending(void)
+{
+    // Intentionally empty
+}
diff --git a/examples/platforms/efr32mg1/uart.c b/examples/platforms/efr32mg1/uart.c
new file mode 100644
index 0000000..f93f75f
--- /dev/null
+++ b/examples/platforms/efr32mg1/uart.c
@@ -0,0 +1,194 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for UART communication.
+ *
+ */
+
+#include <stddef.h>
+
+#include "openthread-system.h"
+#include <openthread/platform/uart.h>
+
+#include "utils/code_utils.h"
+
+#include "em_core.h"
+#include "uartdrv.h"
+
+#include "hal-config.h"
+
+enum
+{
+    kReceiveFifoSize = 128,
+};
+
+#define USART_INIT                                                                               \
+    {                                                                                            \
+        USART0,                                               /* USART port */                   \
+            115200,                                           /* Baud rate */                    \
+            BSP_SERIAL_APP_TX_LOC,                            /* USART Tx pin location number */ \
+            BSP_SERIAL_APP_RX_LOC,                            /* USART Rx pin location number */ \
+            (USART_Stopbits_TypeDef)USART_FRAME_STOPBITS_ONE, /* Stop bits */                    \
+            (USART_Parity_TypeDef)USART_FRAME_PARITY_NONE,    /* Parity */                       \
+            (USART_OVS_TypeDef)USART_CTRL_OVS_X16,            /* Oversampling mode*/             \
+            false,                                            /* Majority vote disable */        \
+            HAL_SERIAL_APP_FLOW_CONTROL,                      /* Flow control */                 \
+            BSP_SERIAL_APP_CTS_PORT,                          /* CTS port number */              \
+            BSP_SERIAL_APP_CTS_PIN,                           /* CTS pin number */               \
+            BSP_SERIAL_APP_RTS_PORT,                          /* RTS port number */              \
+            BSP_SERIAL_APP_RTS_PIN,                           /* RTS pin number */               \
+            (UARTDRV_Buffer_FifoQueue_t *)&sUartRxQueue,      /* RX operation queue */           \
+            (UARTDRV_Buffer_FifoQueue_t *)&sUartTxQueue,      /* TX operation queue */           \
+            BSP_SERIAL_APP_CTS_LOC,                           /* CTS location */                 \
+            BSP_SERIAL_APP_RTS_LOC                            /* RTS location */                 \
+    }
+
+DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_RX_BUFS, sUartRxQueue);
+DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_TX_BUFS, sUartTxQueue);
+
+static UARTDRV_HandleData_t sUartHandleData;
+static UARTDRV_Handle_t     sUartHandle = &sUartHandleData;
+static uint8_t              sReceiveBuffer[2];
+static const uint8_t *      sTransmitBuffer = NULL;
+static volatile uint16_t    sTransmitLength = 0;
+
+typedef struct ReceiveFifo_t
+{
+    // The data buffer
+    uint8_t mBuffer[kReceiveFifoSize];
+    // The offset of the first item written to the list.
+    volatile uint16_t mHead;
+    // The offset of the next item to be written to the list.
+    volatile uint16_t mTail;
+} ReceiveFifo_t;
+
+static ReceiveFifo_t sReceiveFifo;
+
+static void processReceive(void);
+
+static void receiveDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
+{
+    // We can only write if incrementing mTail doesn't equal mHead
+    if (sReceiveFifo.mHead != (sReceiveFifo.mTail + 1) % kReceiveFifoSize)
+    {
+        sReceiveFifo.mBuffer[sReceiveFifo.mTail] = aData[0];
+        sReceiveFifo.mTail                       = (sReceiveFifo.mTail + 1) % kReceiveFifoSize;
+    }
+
+    UARTDRV_Receive(aHandle, aData, 1, receiveDone);
+    otSysEventSignalPending();
+}
+
+static void transmitDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
+{
+    sTransmitLength = 0;
+    otSysEventSignalPending();
+}
+
+static void processReceive(void)
+{
+    // Copy tail to prevent multiple reads
+    uint16_t tail = sReceiveFifo.mTail;
+
+    // If the data wraps around, process the first part
+    if (sReceiveFifo.mHead > tail)
+    {
+        otPlatUartReceived(sReceiveFifo.mBuffer + sReceiveFifo.mHead, kReceiveFifoSize - sReceiveFifo.mHead);
+
+        // Reset the buffer mHead back to zero.
+        sReceiveFifo.mHead = 0;
+    }
+
+    // For any data remaining, process it
+    if (sReceiveFifo.mHead != tail)
+    {
+        otPlatUartReceived(sReceiveFifo.mBuffer + sReceiveFifo.mHead, tail - sReceiveFifo.mHead);
+
+        // Set mHead to the local tail we have cached
+        sReceiveFifo.mHead = tail;
+    }
+}
+
+otError otPlatUartFlush(void)
+{
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+static void processTransmit(void)
+{
+    if (sTransmitBuffer != NULL && sTransmitLength == 0)
+    {
+        sTransmitBuffer = NULL;
+        otPlatUartSendDone();
+    }
+}
+
+otError otPlatUartEnable(void)
+{
+    UARTDRV_Init_t uartInit = USART_INIT;
+
+    sReceiveFifo.mHead = 0;
+    sReceiveFifo.mTail = 0;
+
+    UARTDRV_Init(sUartHandle, &uartInit);
+
+    for (uint8_t i = 0; i < sizeof(sReceiveBuffer); i++)
+    {
+        UARTDRV_Receive(sUartHandle, &sReceiveBuffer[i], sizeof(sReceiveBuffer[i]), receiveDone);
+    }
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartDisable(void)
+{
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(sTransmitBuffer == NULL, error = OT_ERROR_BUSY);
+
+    sTransmitBuffer = aBuf;
+    sTransmitLength = aBufLength;
+
+    UARTDRV_Transmit(sUartHandle, (uint8_t *)sTransmitBuffer, sTransmitLength, transmitDone);
+
+exit:
+    return error;
+}
+
+void efr32UartProcess(void)
+{
+    processReceive();
+    processTransmit();
+}
diff --git a/examples/platforms/efr32mg12/Makefile.am b/examples/platforms/efr32mg12/Makefile.am
index 62890aa..6243d9e 100644
--- a/examples/platforms/efr32mg12/Makefile.am
+++ b/examples/platforms/efr32mg12/Makefile.am
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2017, The OpenThread Authors.
+#  Copyright (c) 2020, The OpenThread Authors.
 #  All rights reserved.
 #
 #  Redistribution and use in source and binary forms, with or without
@@ -76,6 +76,8 @@
     -I$(SDK_SRC_DIR)/platform/emdrv/ustimer/inc                                 \
     -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/inc                                  \
     -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/config                               \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/inc                                    \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/config                                 \
     -I$(SDK_SRC_DIR)/platform/emlib/inc                                         \
     -I$(SDK_SRC_DIR)/platform/halconfig/inc/hal-config                          \
     -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32                         \
@@ -123,10 +125,6 @@
     $(PLATFORM_SOURCES)                                                         \
     $(NULL)
 
-PRETTY_FILES                                                                  = \
-    $(PLATFORM_SOURCES)                                                         \
-    $(NULL)
-
 Dash = -
 libopenthread_efr32mg12_a_LIBADD                                                                     = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")             \
@@ -135,13 +133,9 @@
 DIST_SUBDIRS                                                                  = \
     sleepy-demo                                                                 \
     $(NULL)
-    
+
 SUBDIRS                                                                       = \
     sleepy-demo                                                                 \
     $(NULL)
 
-PRETTY_SUBDIRS                                                                = \
-    sleepy-demo                                                                 \
-    $(NULL)
-    
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/efr32mg12/Makefile.platform.am b/examples/platforms/efr32mg12/Makefile.platform.am
index 6ea5003..fc31052 100644
--- a/examples/platforms/efr32mg12/Makefile.platform.am
+++ b/examples/platforms/efr32mg12/Makefile.platform.am
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2017, The OpenThread Authors.
+#  Copyright (c) 2020, The OpenThread Authors.
 #  All rights reserved.
 #
 #  Redistribution and use in source and binary forms, with or without
@@ -41,8 +41,9 @@
     $(top_builddir)/examples/platforms/efr32mg12/libopenthread-efr32mg12.a       \
     $(top_builddir)/third_party/silabs/libsilabs-efr32mg12-sdk.a                 \
     $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/radio/rail_lib/autogen/librail_release/$(LIBRAIL) \
+    $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \
     $(NULL)
 
 LDFLAGS_COMMON                                                                += \
-    -T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
+    -T $(top_srcdir)/examples/platforms/efr32mg12/efr32mg12.ld                   \
     $(NULL)
diff --git a/examples/platforms/efr32mg12/README.md b/examples/platforms/efr32mg12/README.md
index 9f811c1..5cc8837 100644
--- a/examples/platforms/efr32mg12/README.md
+++ b/examples/platforms/efr32mg12/README.md
@@ -1,20 +1,14 @@
 # OpenThread on EFR32MG12 Example
 
-This directory contains example platform drivers for the [Silicon Labs EFR32MG12][efr32mg12]
-based on [EFR32™ Mighty Gecko Wireless Starter Kit][SLWSTK6000B] or [Thunderboard™ Sense 2 Sensor-to-Cloud Advanced IoT Development Kit][SLTB004A].
+This directory contains example platform drivers for the [Silicon Labs EFR32MG12][efr32mg12] based on [EFR32™ Mighty Gecko Wireless Starter Kit][slwstk6000b] or [Thunderboard™ Sense 2 Sensor-to-Cloud Advanced IoT Development Kit][sltb004a].
 
 [efr32mg]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc
-[SLWSTK6000B]: http://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit
-[SLTB004A]: https://www.silabs.com/products/development-tools/thunderboard/thunderboard-sense-two-kit
+[slwstk6000b]: http://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit
+[sltb004a]: https://www.silabs.com/products/development-tools/thunderboard/thunderboard-sense-two-kit
 
-The example platform drivers are intended to present the minimal code
-necessary to support OpenThread. [EFR32MG12P SoC][efr32mg12p]
-has rich memory and peripheral resources which can support all OpenThread
-capabilities. See the "Run the example with EFR32MG12 boards" section below
-for an example using basic OpenThread capabilities.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. [EFR32MG12P SoC][efr32mg12p] has rich memory and peripheral resources which can support all OpenThread capabilities. See the "Run the example with EFR32MG12 boards" section below for an example using basic OpenThread capabilities.
 
-See [sleepy-demo/README.md](sleepy-demo/README.md) for instructions for an example that uses the low-energy
-modes of the EFR32MG12 when running as a Sleepy End Device.
+See [sleepy-demo/README.md](sleepy-demo/README.md) for instructions for an example that uses the low-energy modes of the EFR32MG12 when running as a Sleepy End Device.
 
 [efr32mg12p]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc/device.EFR32MG12P432F1024GL125
 
@@ -24,8 +18,7 @@
 
 [gnu-toolchain]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -43,15 +36,13 @@
    - Find Flex SDK v2.7 in the Software Update page and click Install.
    - Flex SDK v2.7 will be installed in the path: `/SimplicityStudio_v4/developer/sdks/gecko_sdk_suite`.
 
-For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32)
-portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the 
-Wireless Gecko (EFR32™) Portfolio][QSG138]. For more information
-on RAIL, see [Radio Abstraction Interface Layer][rail].
+For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32) portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the Wireless Gecko (EFR32™) Portfolio][qsg138]. For more information on RAIL, see [Radio Abstraction Interface Layer][rail].
 
-[QSG138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
+[qsg138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
 [rail]: http://www.silabs.com/products/development-tools/software/radio-abstraction-interface-layer-sdk
 
 3. Configure the path to Flex SDK source code.
+
 ```bash
 $ cd <path-to-openthread>/third_party
 $ mkdir silabs
@@ -60,6 +51,7 @@
 ```
 
 Alternatively create a symbolic link to the Flex SDK source code.
+
 ```bash
 $ cd <path-to-openthread>/third_party
 $ mkdir silabs
@@ -67,27 +59,29 @@
 ```
 
 4. Build OpenThread Firmware (CLI example) on EFR32 platform.
+
 ```bash
 $ cd <path-to-openthread>
 $ ./bootstrap
 ```
+
 For EFR32MG12™ Mighty Gecko Wireless Starter Kit:
+
 ```bash
 $ make -f examples/Makefile-efr32mg12 BOARD=BRD4161A
 ```
+
 or alternatively for the Thunderboard™ Sense 2:
 
 ```bash
 $ make -f examples/Makefile-efr32mg12 BOARD=BRD4166A
 ```
 
-After a successful build, the `elf` files are found in
-`<path-to-openthread>/output/efr32mg12/bin`.
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/efr32mg12/bin`.
 
 ## Flash Binaries
 
-Compiled binaries may be flashed onto the EFR32 using [JLinkGDBServer][jlinkgdbserver].
-EFR32 Starter kit mainboard integrates an on-board SEGGER J-Link debugger.
+Compiled binaries may be flashed onto the EFR32 using [JLinkGDBServer][jlinkgdbserver]. EFR32 Starter kit mainboard integrates an on-board SEGGER J-Link debugger.
 
 [jlinkgdbserver]: https://www.segger.com/jlink-gdb-server.html
 
@@ -104,8 +98,7 @@
 
 Note: Support for the "EFR32MG12PxxxF1024" device was added to JLinkGDBServer V6.14d.
 
-Or 
-Compiled binaries also may be flashed onto the specified EFR32 dev board using [J-Link Commander][j-link-commander].
+Or Compiled binaries also may be flashed onto the specified EFR32 dev board using [J-Link Commander][j-link-commander].
 
 [j-link-commander]: https://www.segger.com/products/debug-probes/j-link/tools/j-link-commander/
 
@@ -132,16 +125,12 @@
 $ <path-to-simplicity-studio>/developer/adapter_packs/commander/commander
 ```
 
-In the J-Link Device drop-down list select the serial number of the device to flash.  Click the Adapter Connect button.
-Esnure the Debug Interface drop-down list is set to SWD and click the Target Connect button.
-Click on the Flash icon on the left side of the window to switch to the flash page.
-In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button.
-Click the Flash button located under the Browse... button.
+In the J-Link Device drop-down list select the serial number of the device to flash. Click the Adapter Connect button. Ensure the Debug Interface drop-down list is set to SWD and click the Target Connect button. Click on the Flash icon on the left side of the window to switch to the flash page. In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button. Click the Flash button located under the Browse... button.
 
 ## Run the example with EFR32MG12 boards
+
 1. Flash two EFR32 boards with the `CLI example` firmware (as shown above).
-2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1).
-   Type `help` for a list of commands.
+2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1). Type `help` for a list of commands.
 
    ```bash
    > help
@@ -204,8 +193,7 @@
    Done
    ```
 
-4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1)
-   and attach it to the Thread network as a Router.
+4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1) and attach it to the Thread network as a Router.
 
    ```bash
    > dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
@@ -244,8 +232,7 @@
    16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
    ```
 
-The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner,
-joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
+The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner, joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
 
 ```bash
 $ cd <path-to-openthread>
@@ -253,14 +240,16 @@
 $ make -f examples/Makefile-efr32mg12 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1
 ```
 
-For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
 
-[CLI]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
+[cli]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
 
 ## Verification
 
 The following toolchain has been used for testing and verification:
-   - gcc version 7.3.1
+
+- gcc version 7.3.1
 
 The EFR32 example has been verified with following Flex SDK/RAIL Library version:
-   - Flex SDK version 2.7.0.0
+
+- Flex SDK version 2.7.0.0
diff --git a/examples/platforms/efr32mg12/alarm.c b/examples/platforms/efr32mg12/alarm.c
index ab0a5c6..71a39c0 100644
--- a/examples/platforms/efr32mg12/alarm.c
+++ b/examples/platforms/efr32mg12/alarm.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/brd4161a/board_config.h b/examples/platforms/efr32mg12/brd4161a/board_config.h
index fdcf413..d798d52 100644
--- a/examples/platforms/efr32mg12/brd4161a/board_config.h
+++ b/examples/platforms/efr32mg12/brd4161a/board_config.h
@@ -35,16 +35,17 @@
 #ifndef __BOARD_CONFIG_H__
 #define __BOARD_CONFIG_H__
 
-#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1   /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 0 /// Dev board doesn't support OQPSK modulation in 915MHz band.
 
 #ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
 #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
 #endif
 
 #ifndef RADIO_CONFIG_DMP_SUPPORT
-#define RADIO_CONFIG_DMP_SUPPORT 0            /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
+#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
 #endif
 
-#define RADIO_CONFIG_PA_USES_DCDC 0           /// The PA(s) is(are) fed from VBAT
+#define RADIO_CONFIG_PA_USES_DCDC 0 /// The PA(s) is(are) fed from VBAT
 
 #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg12/brd4161a/hal-config.h b/examples/platforms/efr32mg12/brd4161a/hal-config.h
index 20b658d..24a9a5e 100644
--- a/examples/platforms/efr32mg12/brd4161a/hal-config.h
+++ b/examples/platforms/efr32mg12/brd4161a/hal-config.h
@@ -33,35 +33,38 @@
 // [BULBPWM_COLOR]$
 
 // $[BUTTON]
-#define BSP_BUTTON_PRESENT                            (1)
+#define BSP_BUTTON_PRESENT (1)
 
-#define BSP_BUTTON0_PIN                               (6U)
-#define BSP_BUTTON0_PORT                              (gpioPortF)
+#define BSP_BUTTON0_PIN (6U)
+#define BSP_BUTTON0_PORT (gpioPortF)
 
-#define BSP_BUTTON1_PIN                               (7U)
-#define BSP_BUTTON1_PORT                              (gpioPortF)
+#define BSP_BUTTON1_PIN (7U)
+#define BSP_BUTTON1_PORT (gpioPortF)
 
-#define BSP_BUTTON_COUNT                              (2U)
-#define BSP_BUTTON_INIT                               { { BSP_BUTTON0_PORT, BSP_BUTTON0_PIN }, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } }
-#define BSP_BUTTON_GPIO_DOUT                          (HAL_GPIO_DOUT_LOW)
-#define BSP_BUTTON_GPIO_MODE                          (HAL_GPIO_MODE_INPUT)
+#define BSP_BUTTON_COUNT (2U)
+#define BSP_BUTTON_INIT                                                            \
+    {                                                                              \
+        {BSP_BUTTON0_PORT, BSP_BUTTON0_PIN}, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } \
+    }
+#define BSP_BUTTON_GPIO_DOUT (HAL_GPIO_DOUT_LOW)
+#define BSP_BUTTON_GPIO_MODE (HAL_GPIO_MODE_INPUT)
 // [BUTTON]$
 
 // $[CMU]
-#define HAL_CLK_HFCLK_SOURCE                  (HAL_CLK_HFCLK_SOURCE_HFXO)
-#define HAL_CLK_LFECLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define HAL_CLK_LFBCLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_LFXO_PRESENT                  (1)
-#define BSP_CLK_HFXO_PRESENT                  (1)
-#define BSP_CLK_LFXO_INIT                      CMU_LFXOINIT_DEFAULT
-#define BSP_CLK_LFXO_CTUNE                    (0)
-#define BSP_CLK_LFXO_FREQ                     (32768)
-#define HAL_CLK_LFACLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_HFXO_FREQ                     (38400000)
-#define BSP_CLK_HFXO_CTUNE                    (338)
-#define BSP_CLK_HFXO_INIT                      CMU_HFXOINIT_DEFAULT
-#define BSP_CLK_HFXO_CTUNE_TOKEN              (0)
-#define HAL_CLK_HFXO_AUTOSTART                (HAL_CLK_HFXO_AUTOSTART_NONE)
+#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
+#define HAL_CLK_LFECLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define HAL_CLK_LFBCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_LFXO_PRESENT (1)
+#define BSP_CLK_HFXO_PRESENT (1)
+#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
+#define BSP_CLK_LFXO_CTUNE (0)
+#define BSP_CLK_LFXO_FREQ (32768U)
+#define HAL_CLK_LFACLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_HFXO_FREQ (38400000UL)
+#define BSP_CLK_HFXO_CTUNE (338)
+#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
+#define BSP_CLK_HFXO_CTUNE_TOKEN (0)
+#define HAL_CLK_HFXO_AUTOSTART (HAL_CLK_HFXO_AUTOSTART_NONE)
 // [CMU]$
 
 // $[COEX]
@@ -74,10 +77,10 @@
 // [CSEN0]$
 
 // $[DCDC]
-#define BSP_DCDC_PRESENT                      (1)
+#define BSP_DCDC_PRESENT (1)
 
-#define HAL_DCDC_BYPASS                       (0)
-#define BSP_DCDC_INIT                          EMU_DCDCINIT_DEFAULT
+#define HAL_DCDC_BYPASS (0)
+#define BSP_DCDC_INIT EMU_DCDCINIT_DEFAULT
 // [DCDC]$
 
 // $[EMU]
@@ -90,47 +93,47 @@
 // [EZRADIOPRO]$
 
 // $[GPIO]
-#define PORTIO_GPIO_SWCLKTCK_PIN              (0)
-#define PORTIO_GPIO_SWCLKTCK_PORT             (gpioPortF)
-#define PORTIO_GPIO_DBGROUTE_LOC              (0)
+#define PORTIO_GPIO_SWCLKTCK_PIN (0)
+#define PORTIO_GPIO_SWCLKTCK_PORT (gpioPortF)
+#define PORTIO_GPIO_DBGROUTE_LOC (0)
 
-#define PORTIO_GPIO_SWDIOTMS_PIN              (1)
-#define PORTIO_GPIO_SWDIOTMS_PORT             (gpioPortF)
+#define PORTIO_GPIO_SWDIOTMS_PIN (1)
+#define PORTIO_GPIO_SWDIOTMS_PORT (gpioPortF)
 
-#define PORTIO_GPIO_SWV_PIN                   (2)
-#define PORTIO_GPIO_SWV_PORT                  (gpioPortF)
-#define PORTIO_GPIO_SWV_LOC                   (0)
+#define PORTIO_GPIO_SWV_PIN (2)
+#define PORTIO_GPIO_SWV_PORT (gpioPortF)
+#define PORTIO_GPIO_SWV_LOC (0)
 
-#define PORTIO_GPIO_TCLK_PIN                  (8)
-#define PORTIO_GPIO_TCLK_PORT                 (gpioPortF)
-#define PORTIO_GPIO_TCLK_LOC                  (0)
+#define PORTIO_GPIO_TCLK_PIN (8)
+#define PORTIO_GPIO_TCLK_PORT (gpioPortF)
+#define PORTIO_GPIO_TCLK_LOC (0)
 
-#define PORTIO_GPIO_TD0_PIN                   (9)
-#define PORTIO_GPIO_TD0_PORT                  (gpioPortF)
-#define PORTIO_GPIO_TD0_LOC                   (0)
+#define PORTIO_GPIO_TD0_PIN (9)
+#define PORTIO_GPIO_TD0_PORT (gpioPortF)
+#define PORTIO_GPIO_TD0_LOC (0)
 
-#define PORTIO_GPIO_TD1_PIN                   (10)
-#define PORTIO_GPIO_TD1_PORT                  (gpioPortF)
-#define PORTIO_GPIO_TD1_LOC                   (0)
+#define PORTIO_GPIO_TD1_PIN (10)
+#define PORTIO_GPIO_TD1_PORT (gpioPortF)
+#define PORTIO_GPIO_TD1_LOC (0)
 
-#define PORTIO_GPIO_TD2_PIN                   (11)
-#define PORTIO_GPIO_TD2_PORT                  (gpioPortF)
-#define PORTIO_GPIO_TD2_LOC                   (0)
+#define PORTIO_GPIO_TD2_PIN (11)
+#define PORTIO_GPIO_TD2_PORT (gpioPortF)
+#define PORTIO_GPIO_TD2_LOC (0)
 
-#define PORTIO_GPIO_TD3_PIN                   (12)
-#define PORTIO_GPIO_TD3_PORT                  (gpioPortF)
-#define PORTIO_GPIO_TD3_LOC                   (0)
+#define PORTIO_GPIO_TD3_PIN (12)
+#define PORTIO_GPIO_TD3_PORT (gpioPortF)
+#define PORTIO_GPIO_TD3_LOC (0)
 
 // [GPIO]$
 
 // $[I2C0]
-#define PORTIO_I2C0_SCL_PIN                   (10)
-#define PORTIO_I2C0_SCL_PORT                  (gpioPortC)
-#define PORTIO_I2C0_SCL_LOC                   (14)
+#define PORTIO_I2C0_SCL_PIN (10)
+#define PORTIO_I2C0_SCL_PORT (gpioPortC)
+#define PORTIO_I2C0_SCL_LOC (14)
 
-#define PORTIO_I2C0_SDA_PIN                   (11)
-#define PORTIO_I2C0_SDA_PORT                  (gpioPortC)
-#define PORTIO_I2C0_SDA_LOC                   (16)
+#define PORTIO_I2C0_SDA_PIN (11)
+#define PORTIO_I2C0_SDA_PORT (gpioPortC)
+#define PORTIO_I2C0_SDA_LOC (16)
 
 // [I2C0]$
 
@@ -147,18 +150,24 @@
 // [IOEXP]$
 
 // $[LED]
-#define BSP_LED_PRESENT                       (1)
+#define BSP_LED_PRESENT (1)
 
-#define BSP_LED0_PIN                          (4)
-#define BSP_LED0_PORT                         (gpioPortF)
+#define BSP_LED0_PIN (4)
+#define BSP_LED0_PORT (gpioPortF)
 
-#define BSP_LED1_PIN                          (5)
-#define BSP_LED1_PORT                         (gpioPortF)
+#define BSP_LED1_PIN (5)
+#define BSP_LED1_PORT (gpioPortF)
 
-#define HAL_LED_ENABLE                        { 0, 1 }
-#define HAL_LED_COUNT                         (2)
-#define BSP_LED_COUNT                         (2)
-#define BSP_LED_INIT                          { { BSP_LED0_PORT, BSP_LED0_PIN }, { BSP_LED1_PORT, BSP_LED1_PIN } }
+#define HAL_LED_ENABLE \
+    {                  \
+        0, 1           \
+    }
+#define HAL_LED_COUNT (2)
+#define BSP_LED_COUNT (2)
+#define BSP_LED_INIT                                                   \
+    {                                                                  \
+        {BSP_LED0_PORT, BSP_LED0_PIN}, { BSP_LED1_PORT, BSP_LED1_PIN } \
+    }
 // [LED]$
 
 // $[LESENSE]
@@ -177,13 +186,13 @@
 // [LNA]$
 
 // $[PA]
-#define HAL_PA_ENABLE                         (1)
+#define HAL_PA_ENABLE (1)
 
-#define HAL_PA_RAMP                           (10)
-#define HAL_PA_2P4_LOWPOWER                   (0)
-#define HAL_PA_POWER                          (252)
-#define HAL_PA_VOLTAGE                        (3300)
-#define HAL_PA_CURVE_HEADER                    "pa_curves_efr32.h"
+#define HAL_PA_RAMP (10)
+#define HAL_PA_2P4_LOWPOWER (0)
+#define HAL_PA_POWER (252)
+#define HAL_PA_VOLTAGE (3300)
+#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
 // [PA]$
 
 // $[PCNT0]
@@ -199,67 +208,67 @@
 // [PORTIO]$
 
 // $[PRS]
-#define PORTIO_PRS_CH4_PIN                    (13)
-#define PORTIO_PRS_CH4_PORT                   (gpioPortD)
-#define PORTIO_PRS_CH4_LOC                    (4)
+#define PORTIO_PRS_CH4_PIN (13)
+#define PORTIO_PRS_CH4_PORT (gpioPortD)
+#define PORTIO_PRS_CH4_LOC (4)
 
 // [PRS]$
 
 // $[PTI]
-#define PORTIO_PTI_DFRAME_PIN                 (13)
-#define PORTIO_PTI_DFRAME_PORT                (gpioPortB)
-#define PORTIO_PTI_DFRAME_LOC                 (6)
+#define PORTIO_PTI_DFRAME_PIN (13)
+#define PORTIO_PTI_DFRAME_PORT (gpioPortB)
+#define PORTIO_PTI_DFRAME_LOC (6)
 
-#define PORTIO_PTI_DOUT_PIN                   (12)
-#define PORTIO_PTI_DOUT_PORT                  (gpioPortB)
-#define PORTIO_PTI_DOUT_LOC                   (6)
+#define PORTIO_PTI_DOUT_PIN (12)
+#define PORTIO_PTI_DOUT_PORT (gpioPortB)
+#define PORTIO_PTI_DOUT_LOC (6)
 
-#define HAL_PTI_ENABLE                        (1)
+#define HAL_PTI_ENABLE (1)
 
-#define BSP_PTI_DFRAME_PIN                    (13)
-#define BSP_PTI_DFRAME_PORT                   (gpioPortB)
-#define BSP_PTI_DFRAME_LOC                    (6)
+#define BSP_PTI_DFRAME_PIN (13)
+#define BSP_PTI_DFRAME_PORT (gpioPortB)
+#define BSP_PTI_DFRAME_LOC (6)
 
-#define BSP_PTI_DOUT_PIN                      (12)
-#define BSP_PTI_DOUT_PORT                     (gpioPortB)
-#define BSP_PTI_DOUT_LOC                      (6)
+#define BSP_PTI_DOUT_PIN (12)
+#define BSP_PTI_DOUT_PORT (gpioPortB)
+#define BSP_PTI_DOUT_LOC (6)
 
-#define HAL_PTI_MODE                          (HAL_PTI_MODE_UART)
-#define HAL_PTI_BAUD_RATE                     (1600000)
+#define HAL_PTI_MODE (HAL_PTI_MODE_UART)
+#define HAL_PTI_BAUD_RATE (1600000)
 // [PTI]$
 
 // $[PYD1698]
 // [PYD1698]$
 
 // $[SERIAL]
-#define HAL_SERIAL_USART0_ENABLE              (0)
-#define HAL_SERIAL_LEUART0_ENABLE             (0)
-#define HAL_SERIAL_USART1_ENABLE              (0)
-#define HAL_SERIAL_USART2_ENABLE              (0)
-#define HAL_SERIAL_USART3_ENABLE              (0)
-#define HAL_SERIAL_RXWAKE_ENABLE              (0)
-#define BSP_SERIAL_APP_CTS_PIN                (2)
-#define BSP_SERIAL_APP_CTS_PORT               (gpioPortA)
-#define BSP_SERIAL_APP_CTS_LOC                (30)
+#define HAL_SERIAL_USART0_ENABLE (0)
+#define HAL_SERIAL_LEUART0_ENABLE (0)
+#define HAL_SERIAL_USART1_ENABLE (0)
+#define HAL_SERIAL_USART2_ENABLE (0)
+#define HAL_SERIAL_USART3_ENABLE (0)
+#define HAL_SERIAL_RXWAKE_ENABLE (0)
+#define BSP_SERIAL_APP_CTS_PIN (2)
+#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_CTS_LOC (30)
 
-#define BSP_SERIAL_APP_RX_PIN                 (1)
-#define BSP_SERIAL_APP_RX_PORT                (gpioPortA)
-#define BSP_SERIAL_APP_RX_LOC                 (0)
+#define BSP_SERIAL_APP_RX_PIN (1)
+#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RX_LOC (0)
 
-#define BSP_SERIAL_APP_TX_PIN                 (0)
-#define BSP_SERIAL_APP_TX_PORT                (gpioPortA)
-#define BSP_SERIAL_APP_TX_LOC                 (0)
+#define BSP_SERIAL_APP_TX_PIN (0)
+#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_TX_LOC (0)
 
-#define BSP_SERIAL_APP_RTS_PIN                (3)
-#define BSP_SERIAL_APP_RTS_PORT               (gpioPortA)
-#define BSP_SERIAL_APP_RTS_LOC                (30)
+#define BSP_SERIAL_APP_RTS_PIN (3)
+#define BSP_SERIAL_APP_RTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RTS_LOC (30)
 
-#define HAL_SERIAL_APP_RX_QUEUE_SIZE          (128)
-#define HAL_SERIAL_APP_BAUD_RATE              (115200)
-#define HAL_SERIAL_APP_RXSTOP                 (16)
-#define HAL_SERIAL_APP_RXSTART                (16)
-#define HAL_SERIAL_APP_TX_QUEUE_SIZE          (128)
-#define HAL_SERIAL_APP_FLOW_CONTROL           (HAL_USART_FLOW_CONTROL_HWUART)
+#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128)
+#define HAL_SERIAL_APP_BAUD_RATE (115200)
+#define HAL_SERIAL_APP_RXSTOP (16)
+#define HAL_SERIAL_APP_RXSTART (16)
+#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128)
+#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
 // [SERIAL]$
 
 // $[SPIDISPLAY]
@@ -278,102 +287,102 @@
 // [UARTNCP]$
 
 // $[USART0]
-#define PORTIO_USART0_CTS_PIN                 (2)
-#define PORTIO_USART0_CTS_PORT                (gpioPortA)
-#define PORTIO_USART0_CTS_LOC                 (30)
+#define PORTIO_USART0_CTS_PIN (2)
+#define PORTIO_USART0_CTS_PORT (gpioPortA)
+#define PORTIO_USART0_CTS_LOC (30)
 
-#define PORTIO_USART0_RTS_PIN                 (3)
-#define PORTIO_USART0_RTS_PORT                (gpioPortA)
-#define PORTIO_USART0_RTS_LOC                 (30)
+#define PORTIO_USART0_RTS_PIN (3)
+#define PORTIO_USART0_RTS_PORT (gpioPortA)
+#define PORTIO_USART0_RTS_LOC (30)
 
-#define PORTIO_USART0_RX_PIN                  (1)
-#define PORTIO_USART0_RX_PORT                 (gpioPortA)
-#define PORTIO_USART0_RX_LOC                  (0)
+#define PORTIO_USART0_RX_PIN (1)
+#define PORTIO_USART0_RX_PORT (gpioPortA)
+#define PORTIO_USART0_RX_LOC (0)
 
-#define PORTIO_USART0_TX_PIN                  (0)
-#define PORTIO_USART0_TX_PORT                 (gpioPortA)
-#define PORTIO_USART0_TX_LOC                  (0)
+#define PORTIO_USART0_TX_PIN (0)
+#define PORTIO_USART0_TX_PORT (gpioPortA)
+#define PORTIO_USART0_TX_LOC (0)
 
-#define HAL_USART0_ENABLE                     (1)
+#define HAL_USART0_ENABLE (1)
 
-#define BSP_USART0_CTS_PIN                    (2)
-#define BSP_USART0_CTS_PORT                   (gpioPortA)
-#define BSP_USART0_CTS_LOC                    (30)
+#define BSP_USART0_CTS_PIN (2)
+#define BSP_USART0_CTS_PORT (gpioPortA)
+#define BSP_USART0_CTS_LOC (30)
 
-#define BSP_USART0_RX_PIN                     (1)
-#define BSP_USART0_RX_PORT                    (gpioPortA)
-#define BSP_USART0_RX_LOC                     (0)
+#define BSP_USART0_RX_PIN (1)
+#define BSP_USART0_RX_PORT (gpioPortA)
+#define BSP_USART0_RX_LOC (0)
 
-#define BSP_USART0_TX_PIN                     (0)
-#define BSP_USART0_TX_PORT                    (gpioPortA)
-#define BSP_USART0_TX_LOC                     (0)
+#define BSP_USART0_TX_PIN (0)
+#define BSP_USART0_TX_PORT (gpioPortA)
+#define BSP_USART0_TX_LOC (0)
 
-#define BSP_USART0_RTS_PIN                    (3)
-#define BSP_USART0_RTS_PORT                   (gpioPortA)
-#define BSP_USART0_RTS_LOC                    (30)
+#define BSP_USART0_RTS_PIN (3)
+#define BSP_USART0_RTS_PORT (gpioPortA)
+#define BSP_USART0_RTS_LOC (30)
 
-#define HAL_USART0_RX_QUEUE_SIZE              (128)
-#define HAL_USART0_BAUD_RATE                  (115200)
-#define HAL_USART0_RXSTOP                     (16)
-#define HAL_USART0_RXSTART                    (16)
-#define HAL_USART0_TX_QUEUE_SIZE              (128)
-#define HAL_USART0_FLOW_CONTROL               (HAL_USART_FLOW_CONTROL_NONE)
+#define HAL_USART0_RX_QUEUE_SIZE (128)
+#define HAL_USART0_BAUD_RATE (115200)
+#define HAL_USART0_RXSTOP (16)
+#define HAL_USART0_RXSTART (16)
+#define HAL_USART0_TX_QUEUE_SIZE (128)
+#define HAL_USART0_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
 // [USART0]$
 
 // $[USART1]
-#define PORTIO_USART1_CLK_PIN                 (8)
-#define PORTIO_USART1_CLK_PORT                (gpioPortC)
-#define PORTIO_USART1_CLK_LOC                 (11)
+#define PORTIO_USART1_CLK_PIN (8)
+#define PORTIO_USART1_CLK_PORT (gpioPortC)
+#define PORTIO_USART1_CLK_LOC (11)
 
-#define PORTIO_USART1_CS_PIN                  (9)
-#define PORTIO_USART1_CS_PORT                 (gpioPortC)
-#define PORTIO_USART1_CS_LOC                  (11)
+#define PORTIO_USART1_CS_PIN (9)
+#define PORTIO_USART1_CS_PORT (gpioPortC)
+#define PORTIO_USART1_CS_LOC (11)
 
-#define PORTIO_USART1_RX_PIN                  (7)
-#define PORTIO_USART1_RX_PORT                 (gpioPortC)
-#define PORTIO_USART1_RX_LOC                  (11)
+#define PORTIO_USART1_RX_PIN (7)
+#define PORTIO_USART1_RX_PORT (gpioPortC)
+#define PORTIO_USART1_RX_LOC (11)
 
-#define PORTIO_USART1_TX_PIN                  (6)
-#define PORTIO_USART1_TX_PORT                 (gpioPortC)
-#define PORTIO_USART1_TX_LOC                  (11)
+#define PORTIO_USART1_TX_PIN (6)
+#define PORTIO_USART1_TX_PORT (gpioPortC)
+#define PORTIO_USART1_TX_LOC (11)
 
 // [USART1]$
 
 // $[USART2]
-#define PORTIO_USART2_CLK_PIN                 (8)
-#define PORTIO_USART2_CLK_PORT                (gpioPortA)
-#define PORTIO_USART2_CLK_LOC                 (1)
+#define PORTIO_USART2_CLK_PIN (8)
+#define PORTIO_USART2_CLK_PORT (gpioPortA)
+#define PORTIO_USART2_CLK_LOC (1)
 
-#define PORTIO_USART2_CS_PIN                  (9)
-#define PORTIO_USART2_CS_PORT                 (gpioPortA)
-#define PORTIO_USART2_CS_LOC                  (1)
+#define PORTIO_USART2_CS_PIN (9)
+#define PORTIO_USART2_CS_PORT (gpioPortA)
+#define PORTIO_USART2_CS_LOC (1)
 
-#define PORTIO_USART2_RX_PIN                  (7)
-#define PORTIO_USART2_RX_PORT                 (gpioPortA)
-#define PORTIO_USART2_RX_LOC                  (1)
+#define PORTIO_USART2_RX_PIN (7)
+#define PORTIO_USART2_RX_PORT (gpioPortA)
+#define PORTIO_USART2_RX_LOC (1)
 
-#define PORTIO_USART2_TX_PIN                  (6)
-#define PORTIO_USART2_TX_PORT                 (gpioPortA)
-#define PORTIO_USART2_TX_LOC                  (1)
+#define PORTIO_USART2_TX_PIN (6)
+#define PORTIO_USART2_TX_PORT (gpioPortA)
+#define PORTIO_USART2_TX_LOC (1)
 
 // [USART2]$
 
 // $[USART3]
-#define PORTIO_USART3_CTS_PIN                 (8)
-#define PORTIO_USART3_CTS_PORT                (gpioPortD)
-#define PORTIO_USART3_CTS_LOC                 (28)
+#define PORTIO_USART3_CTS_PIN (8)
+#define PORTIO_USART3_CTS_PORT (gpioPortD)
+#define PORTIO_USART3_CTS_LOC (28)
 
-#define PORTIO_USART3_RTS_PIN                 (9)
-#define PORTIO_USART3_RTS_PORT                (gpioPortD)
-#define PORTIO_USART3_RTS_LOC                 (28)
+#define PORTIO_USART3_RTS_PIN (9)
+#define PORTIO_USART3_RTS_PORT (gpioPortD)
+#define PORTIO_USART3_RTS_LOC (28)
 
-#define PORTIO_USART3_RX_PIN                  (7)
-#define PORTIO_USART3_RX_PORT                 (gpioPortB)
-#define PORTIO_USART3_RX_LOC                  (10)
+#define PORTIO_USART3_RX_PIN (7)
+#define PORTIO_USART3_RX_PORT (gpioPortB)
+#define PORTIO_USART3_RX_LOC (10)
 
-#define PORTIO_USART3_TX_PIN                  (6)
-#define PORTIO_USART3_TX_PORT                 (gpioPortB)
-#define PORTIO_USART3_TX_LOC                  (10)
+#define PORTIO_USART3_TX_PIN (6)
+#define PORTIO_USART3_TX_PORT (gpioPortB)
+#define PORTIO_USART3_TX_LOC (10)
 
 // [USART3]$
 
@@ -396,4 +405,3 @@
 // [WTIMER1]$
 
 #endif /* HAL_CONFIG_H */
-
diff --git a/examples/platforms/efr32mg12/brd4166a/board_config.h b/examples/platforms/efr32mg12/brd4166a/board_config.h
index 3e5ff29..1f9b939 100644
--- a/examples/platforms/efr32mg12/brd4166a/board_config.h
+++ b/examples/platforms/efr32mg12/brd4166a/board_config.h
@@ -35,16 +35,17 @@
 #ifndef __BOARD_CONFIG_H__
 #define __BOARD_CONFIG_H__
 
-#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1   /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 0 /// Dev board doesn't support OQPSK modulation in 915MHz band.
 
 #ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
 #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
 #endif
 
 #ifndef RADIO_CONFIG_DMP_SUPPORT
-#define RADIO_CONFIG_DMP_SUPPORT 0            /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
+#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
 #endif
 
-#define RADIO_CONFIG_PA_USES_DCDC 1           /// The PA(s) is(are) fed from the DCDC
+#define RADIO_CONFIG_PA_USES_DCDC 1 /// The PA(s) is(are) fed from the DCDC
 
 #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg12/brd4166a/hal-config.h b/examples/platforms/efr32mg12/brd4166a/hal-config.h
index 60f5401..e65e777 100644
--- a/examples/platforms/efr32mg12/brd4166a/hal-config.h
+++ b/examples/platforms/efr32mg12/brd4166a/hal-config.h
@@ -33,35 +33,38 @@
 // [BULBPWM_COLOR]$
 
 // $[BUTTON]
-#define BSP_BUTTON_PRESENT                   (1)
+#define BSP_BUTTON_PRESENT (1)
 
-#define BSP_BUTTON0_PIN                      (14U)
-#define BSP_BUTTON0_PORT                     (gpioPortD)
+#define BSP_BUTTON0_PIN (14U)
+#define BSP_BUTTON0_PORT (gpioPortD)
 
-#define BSP_BUTTON1_PIN                      (15U)
-#define BSP_BUTTON1_PORT                     (gpioPortD)
+#define BSP_BUTTON1_PIN (15U)
+#define BSP_BUTTON1_PORT (gpioPortD)
 
-#define BSP_BUTTON_COUNT                     (2U)
-#define BSP_BUTTON_INIT                      { { BSP_BUTTON0_PORT, BSP_BUTTON0_PIN }, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } }
-#define BSP_BUTTON_GPIO_DOUT                 (HAL_GPIO_DOUT_LOW)
-#define BSP_BUTTON_GPIO_MODE                 (HAL_GPIO_MODE_INPUT)
+#define BSP_BUTTON_COUNT (2U)
+#define BSP_BUTTON_INIT                                                            \
+    {                                                                              \
+        {BSP_BUTTON0_PORT, BSP_BUTTON0_PIN}, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } \
+    }
+#define BSP_BUTTON_GPIO_DOUT (HAL_GPIO_DOUT_LOW)
+#define BSP_BUTTON_GPIO_MODE (HAL_GPIO_MODE_INPUT)
 // [BUTTON]$
 
 // $[CMU]
-#define HAL_CLK_HFCLK_SOURCE                  (HAL_CLK_HFCLK_SOURCE_HFXO)
-#define HAL_CLK_LFECLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define HAL_CLK_LFBCLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_LFXO_PRESENT                  (1)
-#define BSP_CLK_HFXO_PRESENT                  (1)
-#define BSP_CLK_LFXO_INIT                      CMU_LFXOINIT_DEFAULT
-#define BSP_CLK_LFXO_CTUNE                    (0)
-#define BSP_CLK_LFXO_FREQ                     (32768)
-#define HAL_CLK_LFACLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_HFXO_FREQ                     (38400000)
-#define BSP_CLK_HFXO_CTUNE                    (338)
-#define BSP_CLK_HFXO_INIT                      CMU_HFXOINIT_DEFAULT
-#define BSP_CLK_HFXO_CTUNE_TOKEN              (0)
-#define HAL_CLK_HFXO_AUTOSTART                (HAL_CLK_HFXO_AUTOSTART_NONE)
+#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
+#define HAL_CLK_LFECLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define HAL_CLK_LFBCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_LFXO_PRESENT (1)
+#define BSP_CLK_HFXO_PRESENT (1)
+#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
+#define BSP_CLK_LFXO_CTUNE (32U)
+#define BSP_CLK_LFXO_FREQ (32768U)
+#define HAL_CLK_LFACLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_HFXO_FREQ (38400000UL)
+#define BSP_CLK_HFXO_CTUNE (332)
+#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
+#define BSP_CLK_HFXO_CTUNE_TOKEN (0)
+#define HAL_CLK_HFXO_AUTOSTART (HAL_CLK_HFXO_AUTOSTART_NONE)
 // [CMU]$
 
 // $[COEX]
@@ -74,10 +77,10 @@
 // [CSEN0]$
 
 // $[DCDC]
-#define BSP_DCDC_PRESENT                      (1)
+#define BSP_DCDC_PRESENT (1)
 
-#define HAL_DCDC_BYPASS                       (0)
-#define BSP_DCDC_INIT                          EMU_DCDCINIT_DEFAULT
+#define HAL_DCDC_BYPASS (0)
+#define BSP_DCDC_INIT EMU_DCDCINIT_DEFAULT
 // [DCDC]$
 
 // $[EMU]
@@ -90,47 +93,47 @@
 // [EZRADIOPRO]$
 
 // $[GPIO]
-#define PORTIO_GPIO_SWCLKTCK_PIN              (0)
-#define PORTIO_GPIO_SWCLKTCK_PORT             (gpioPortF)
-#define PORTIO_GPIO_DBGROUTE_LOC              (0)
+#define PORTIO_GPIO_SWCLKTCK_PIN (0)
+#define PORTIO_GPIO_SWCLKTCK_PORT (gpioPortF)
+#define PORTIO_GPIO_DBGROUTE_LOC (0)
 
-#define PORTIO_GPIO_SWDIOTMS_PIN              (1)
-#define PORTIO_GPIO_SWDIOTMS_PORT             (gpioPortF)
+#define PORTIO_GPIO_SWDIOTMS_PIN (1)
+#define PORTIO_GPIO_SWDIOTMS_PORT (gpioPortF)
 
-#define PORTIO_GPIO_SWV_PIN                   (2)
-#define PORTIO_GPIO_SWV_PORT                  (gpioPortF)
-#define PORTIO_GPIO_SWV_LOC                   (0)
+#define PORTIO_GPIO_SWV_PIN (2)
+#define PORTIO_GPIO_SWV_PORT (gpioPortF)
+#define PORTIO_GPIO_SWV_LOC (0)
 
-#define PORTIO_GPIO_TCLK_PIN                  (8)
-#define PORTIO_GPIO_TCLK_PORT                 (gpioPortF)
-#define PORTIO_GPIO_TCLK_LOC                  (0)
+#define PORTIO_GPIO_TCLK_PIN (8)
+#define PORTIO_GPIO_TCLK_PORT (gpioPortF)
+#define PORTIO_GPIO_TCLK_LOC (0)
 
-#define PORTIO_GPIO_TD0_PIN                   (9)
-#define PORTIO_GPIO_TD0_PORT                  (gpioPortF)
-#define PORTIO_GPIO_TD0_LOC                   (0)
+#define PORTIO_GPIO_TD0_PIN (9)
+#define PORTIO_GPIO_TD0_PORT (gpioPortF)
+#define PORTIO_GPIO_TD0_LOC (0)
 
-#define PORTIO_GPIO_TD1_PIN                   (10)
-#define PORTIO_GPIO_TD1_PORT                  (gpioPortF)
-#define PORTIO_GPIO_TD1_LOC                   (0)
+#define PORTIO_GPIO_TD1_PIN (10)
+#define PORTIO_GPIO_TD1_PORT (gpioPortF)
+#define PORTIO_GPIO_TD1_LOC (0)
 
-#define PORTIO_GPIO_TD2_PIN                   (11)
-#define PORTIO_GPIO_TD2_PORT                  (gpioPortF)
-#define PORTIO_GPIO_TD2_LOC                   (0)
+#define PORTIO_GPIO_TD2_PIN (11)
+#define PORTIO_GPIO_TD2_PORT (gpioPortF)
+#define PORTIO_GPIO_TD2_LOC (0)
 
-#define PORTIO_GPIO_TD3_PIN                   (12)
-#define PORTIO_GPIO_TD3_PORT                  (gpioPortF)
-#define PORTIO_GPIO_TD3_LOC                   (0)
+#define PORTIO_GPIO_TD3_PIN (12)
+#define PORTIO_GPIO_TD3_PORT (gpioPortF)
+#define PORTIO_GPIO_TD3_LOC (0)
 
 // [GPIO]$
 
 // $[I2C0]
-#define PORTIO_I2C0_SCL_PIN                   (10)
-#define PORTIO_I2C0_SCL_PORT                  (gpioPortC)
-#define PORTIO_I2C0_SCL_LOC                   (14)
+#define PORTIO_I2C0_SCL_PIN (10)
+#define PORTIO_I2C0_SCL_PORT (gpioPortC)
+#define PORTIO_I2C0_SCL_LOC (14)
 
-#define PORTIO_I2C0_SDA_PIN                   (11)
-#define PORTIO_I2C0_SDA_PORT                  (gpioPortC)
-#define PORTIO_I2C0_SDA_LOC                   (16)
+#define PORTIO_I2C0_SDA_PIN (11)
+#define PORTIO_I2C0_SDA_PORT (gpioPortC)
+#define PORTIO_I2C0_SDA_LOC (16)
 
 // [I2C0]$
 
@@ -147,18 +150,24 @@
 // [IOEXP]$
 
 // $[LED]
-#define BSP_LED_PRESENT                       (1)
+#define BSP_LED_PRESENT (1)
 
-#define BSP_LED0_PIN                          (8)
-#define BSP_LED0_PORT                         (gpioPortD)
+#define BSP_LED0_PIN (8)
+#define BSP_LED0_PORT (gpioPortD)
 
-#define BSP_LED1_PIN                          (9)
-#define BSP_LED1_PORT                         (gpioPortD)
+#define BSP_LED1_PIN (9)
+#define BSP_LED1_PORT (gpioPortD)
 
-#define HAL_LED_ENABLE                        { 0, 1 }
-#define HAL_LED_COUNT                         (2)
-#define BSP_LED_COUNT                         (2)
-#define BSP_LED_INIT                          { { BSP_LED0_PORT, BSP_LED0_PIN }, { BSP_LED1_PORT, BSP_LED1_PIN } }
+#define HAL_LED_ENABLE \
+    {                  \
+        0, 1           \
+    }
+#define HAL_LED_COUNT (2)
+#define BSP_LED_COUNT (2)
+#define BSP_LED_INIT                                                   \
+    {                                                                  \
+        {BSP_LED0_PORT, BSP_LED0_PIN}, { BSP_LED1_PORT, BSP_LED1_PIN } \
+    }
 // [LED]$
 
 // $[LESENSE]
@@ -177,13 +186,13 @@
 // [LNA]$
 
 // $[PA]
-#define HAL_PA_ENABLE                         (1)
+#define HAL_PA_ENABLE (1)
 
-#define HAL_PA_RAMP                           (10)
-#define HAL_PA_2P4_LOWPOWER                   (0)
-#define HAL_PA_POWER                          (252)
-#define HAL_PA_VOLTAGE                        (3300)
-#define HAL_PA_CURVE_HEADER                    "pa_curves_efr32.h"
+#define HAL_PA_RAMP (10)
+#define HAL_PA_2P4_LOWPOWER (0)
+#define HAL_PA_POWER (252)
+#define HAL_PA_VOLTAGE (3300)
+#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
 // [PA]$
 
 // $[PCNT0]
@@ -199,67 +208,67 @@
 // [PORTIO]$
 
 // $[PRS]
-#define PORTIO_PRS_CH4_PIN                    (13)
-#define PORTIO_PRS_CH4_PORT                   (gpioPortD)
-#define PORTIO_PRS_CH4_LOC                    (4)
+#define PORTIO_PRS_CH4_PIN (13)
+#define PORTIO_PRS_CH4_PORT (gpioPortD)
+#define PORTIO_PRS_CH4_LOC (4)
 
 // [PRS]$
 
 // $[PTI]
-#define PORTIO_PTI_DFRAME_PIN                 (13)
-#define PORTIO_PTI_DFRAME_PORT                (gpioPortB)
-#define PORTIO_PTI_DFRAME_LOC                 (6)
+#define PORTIO_PTI_DFRAME_PIN (13)
+#define PORTIO_PTI_DFRAME_PORT (gpioPortB)
+#define PORTIO_PTI_DFRAME_LOC (6)
 
-#define PORTIO_PTI_DOUT_PIN                   (12)
-#define PORTIO_PTI_DOUT_PORT                  (gpioPortB)
-#define PORTIO_PTI_DOUT_LOC                   (6)
+#define PORTIO_PTI_DOUT_PIN (12)
+#define PORTIO_PTI_DOUT_PORT (gpioPortB)
+#define PORTIO_PTI_DOUT_LOC (6)
 
-#define HAL_PTI_ENABLE                        (1)
+#define HAL_PTI_ENABLE (1)
 
-#define BSP_PTI_DFRAME_PIN                    (13)
-#define BSP_PTI_DFRAME_PORT                   (gpioPortB)
-#define BSP_PTI_DFRAME_LOC                    (6)
+#define BSP_PTI_DFRAME_PIN (13)
+#define BSP_PTI_DFRAME_PORT (gpioPortB)
+#define BSP_PTI_DFRAME_LOC (6)
 
-#define BSP_PTI_DOUT_PIN                      (12)
-#define BSP_PTI_DOUT_PORT                     (gpioPortB)
-#define BSP_PTI_DOUT_LOC                      (6)
+#define BSP_PTI_DOUT_PIN (12)
+#define BSP_PTI_DOUT_PORT (gpioPortB)
+#define BSP_PTI_DOUT_LOC (6)
 
-#define HAL_PTI_MODE                          (HAL_PTI_MODE_UART)
-#define HAL_PTI_BAUD_RATE                     (1600000)
+#define HAL_PTI_MODE (HAL_PTI_MODE_UART)
+#define HAL_PTI_BAUD_RATE (1600000)
 // [PTI]$
 
 // $[PYD1698]
 // [PYD1698]$
 
 // $[SERIAL]
-#define HAL_SERIAL_USART0_ENABLE              (0)
-#define HAL_SERIAL_LEUART0_ENABLE             (0)
-#define HAL_SERIAL_USART1_ENABLE              (0)
-#define HAL_SERIAL_USART2_ENABLE              (0)
-#define HAL_SERIAL_USART3_ENABLE              (0)
-#define HAL_SERIAL_RXWAKE_ENABLE              (0)
-#define BSP_SERIAL_APP_CTS_PIN                (2)
-#define BSP_SERIAL_APP_CTS_PORT               (gpioPortA)
-#define BSP_SERIAL_APP_CTS_LOC                (30)
+#define HAL_SERIAL_USART0_ENABLE (0)
+#define HAL_SERIAL_LEUART0_ENABLE (0)
+#define HAL_SERIAL_USART1_ENABLE (0)
+#define HAL_SERIAL_USART2_ENABLE (0)
+#define HAL_SERIAL_USART3_ENABLE (0)
+#define HAL_SERIAL_RXWAKE_ENABLE (0)
+#define BSP_SERIAL_APP_CTS_PIN (2)
+#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_CTS_LOC (30)
 
-#define BSP_SERIAL_APP_RX_PIN                 (1)
-#define BSP_SERIAL_APP_RX_PORT                (gpioPortA)
-#define BSP_SERIAL_APP_RX_LOC                 (0)
+#define BSP_SERIAL_APP_RX_PIN (1)
+#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RX_LOC (0)
 
-#define BSP_SERIAL_APP_TX_PIN                 (0)
-#define BSP_SERIAL_APP_TX_PORT                (gpioPortA)
-#define BSP_SERIAL_APP_TX_LOC                 (0)
+#define BSP_SERIAL_APP_TX_PIN (0)
+#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_TX_LOC (0)
 
-#define BSP_SERIAL_APP_RTS_PIN                (3)
-#define BSP_SERIAL_APP_RTS_PORT               (gpioPortA)
-#define BSP_SERIAL_APP_RTS_LOC                (30)
+#define BSP_SERIAL_APP_RTS_PIN (3)
+#define BSP_SERIAL_APP_RTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RTS_LOC (30)
 
-#define HAL_SERIAL_APP_RX_QUEUE_SIZE          (128)
-#define HAL_SERIAL_APP_BAUD_RATE              (115200)
-#define HAL_SERIAL_APP_RXSTOP                 (16)
-#define HAL_SERIAL_APP_RXSTART                (16)
-#define HAL_SERIAL_APP_TX_QUEUE_SIZE          (128)
-#define HAL_SERIAL_APP_FLOW_CONTROL           (HAL_USART_FLOW_CONTROL_NONE)
+#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128)
+#define HAL_SERIAL_APP_BAUD_RATE (115200)
+#define HAL_SERIAL_APP_RXSTOP (16)
+#define HAL_SERIAL_APP_RXSTART (16)
+#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128)
+#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
 // [SERIAL]$
 
 // $[SPIDISPLAY]
@@ -278,102 +287,102 @@
 // [UARTNCP]$
 
 // $[USART0]
-#define PORTIO_USART0_CTS_PIN                 (2)
-#define PORTIO_USART0_CTS_PORT                (gpioPortA)
-#define PORTIO_USART0_CTS_LOC                 (30)
+#define PORTIO_USART0_CTS_PIN (2)
+#define PORTIO_USART0_CTS_PORT (gpioPortA)
+#define PORTIO_USART0_CTS_LOC (30)
 
-#define PORTIO_USART0_RTS_PIN                 (3)
-#define PORTIO_USART0_RTS_PORT                (gpioPortA)
-#define PORTIO_USART0_RTS_LOC                 (30)
+#define PORTIO_USART0_RTS_PIN (3)
+#define PORTIO_USART0_RTS_PORT (gpioPortA)
+#define PORTIO_USART0_RTS_LOC (30)
 
-#define PORTIO_USART0_RX_PIN                  (1)
-#define PORTIO_USART0_RX_PORT                 (gpioPortA)
-#define PORTIO_USART0_RX_LOC                  (0)
+#define PORTIO_USART0_RX_PIN (1)
+#define PORTIO_USART0_RX_PORT (gpioPortA)
+#define PORTIO_USART0_RX_LOC (0)
 
-#define PORTIO_USART0_TX_PIN                  (0)
-#define PORTIO_USART0_TX_PORT                 (gpioPortA)
-#define PORTIO_USART0_TX_LOC                  (0)
+#define PORTIO_USART0_TX_PIN (0)
+#define PORTIO_USART0_TX_PORT (gpioPortA)
+#define PORTIO_USART0_TX_LOC (0)
 
-#define HAL_USART0_ENABLE                     (1)
+#define HAL_USART0_ENABLE (1)
 
-#define BSP_USART0_CTS_PIN                    (2)
-#define BSP_USART0_CTS_PORT                   (gpioPortA)
-#define BSP_USART0_CTS_LOC                    (30)
+#define BSP_USART0_CTS_PIN (2)
+#define BSP_USART0_CTS_PORT (gpioPortA)
+#define BSP_USART0_CTS_LOC (30)
 
-#define BSP_USART0_RX_PIN                     (1)
-#define BSP_USART0_RX_PORT                    (gpioPortA)
-#define BSP_USART0_RX_LOC                     (0)
+#define BSP_USART0_RX_PIN (1)
+#define BSP_USART0_RX_PORT (gpioPortA)
+#define BSP_USART0_RX_LOC (0)
 
-#define BSP_USART0_TX_PIN                     (0)
-#define BSP_USART0_TX_PORT                    (gpioPortA)
-#define BSP_USART0_TX_LOC                     (0)
+#define BSP_USART0_TX_PIN (0)
+#define BSP_USART0_TX_PORT (gpioPortA)
+#define BSP_USART0_TX_LOC (0)
 
-#define BSP_USART0_RTS_PIN                    (3)
-#define BSP_USART0_RTS_PORT                   (gpioPortA)
-#define BSP_USART0_RTS_LOC                    (30)
+#define BSP_USART0_RTS_PIN (3)
+#define BSP_USART0_RTS_PORT (gpioPortA)
+#define BSP_USART0_RTS_LOC (30)
 
-#define HAL_USART0_RX_QUEUE_SIZE              (128)
-#define HAL_USART0_BAUD_RATE                  (115200)
-#define HAL_USART0_RXSTOP                     (16)
-#define HAL_USART0_RXSTART                    (16)
-#define HAL_USART0_TX_QUEUE_SIZE              (128)
-#define HAL_USART0_FLOW_CONTROL               (HAL_USART_FLOW_CONTROL_NONE)
+#define HAL_USART0_RX_QUEUE_SIZE (128)
+#define HAL_USART0_BAUD_RATE (115200)
+#define HAL_USART0_RXSTOP (16)
+#define HAL_USART0_RXSTART (16)
+#define HAL_USART0_TX_QUEUE_SIZE (128)
+#define HAL_USART0_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
 // [USART0]$
 
 // $[USART1]
-#define PORTIO_USART1_CLK_PIN                 (8)
-#define PORTIO_USART1_CLK_PORT                (gpioPortC)
-#define PORTIO_USART1_CLK_LOC                 (11)
+#define PORTIO_USART1_CLK_PIN (8)
+#define PORTIO_USART1_CLK_PORT (gpioPortC)
+#define PORTIO_USART1_CLK_LOC (11)
 
-#define PORTIO_USART1_CS_PIN                  (9)
-#define PORTIO_USART1_CS_PORT                 (gpioPortC)
-#define PORTIO_USART1_CS_LOC                  (11)
+#define PORTIO_USART1_CS_PIN (9)
+#define PORTIO_USART1_CS_PORT (gpioPortC)
+#define PORTIO_USART1_CS_LOC (11)
 
-#define PORTIO_USART1_RX_PIN                  (7)
-#define PORTIO_USART1_RX_PORT                 (gpioPortC)
-#define PORTIO_USART1_RX_LOC                  (11)
+#define PORTIO_USART1_RX_PIN (7)
+#define PORTIO_USART1_RX_PORT (gpioPortC)
+#define PORTIO_USART1_RX_LOC (11)
 
-#define PORTIO_USART1_TX_PIN                  (6)
-#define PORTIO_USART1_TX_PORT                 (gpioPortC)
-#define PORTIO_USART1_TX_LOC                  (11)
+#define PORTIO_USART1_TX_PIN (6)
+#define PORTIO_USART1_TX_PORT (gpioPortC)
+#define PORTIO_USART1_TX_LOC (11)
 
 // [USART1]$
 
 // $[USART2]
-#define PORTIO_USART2_CLK_PIN                 (8)
-#define PORTIO_USART2_CLK_PORT                (gpioPortA)
-#define PORTIO_USART2_CLK_LOC                 (1)
+#define PORTIO_USART2_CLK_PIN (8)
+#define PORTIO_USART2_CLK_PORT (gpioPortA)
+#define PORTIO_USART2_CLK_LOC (1)
 
-#define PORTIO_USART2_CS_PIN                  (9)
-#define PORTIO_USART2_CS_PORT                 (gpioPortA)
-#define PORTIO_USART2_CS_LOC                  (1)
+#define PORTIO_USART2_CS_PIN (9)
+#define PORTIO_USART2_CS_PORT (gpioPortA)
+#define PORTIO_USART2_CS_LOC (1)
 
-#define PORTIO_USART2_RX_PIN                  (7)
-#define PORTIO_USART2_RX_PORT                 (gpioPortA)
-#define PORTIO_USART2_RX_LOC                  (1)
+#define PORTIO_USART2_RX_PIN (7)
+#define PORTIO_USART2_RX_PORT (gpioPortA)
+#define PORTIO_USART2_RX_LOC (1)
 
-#define PORTIO_USART2_TX_PIN                  (6)
-#define PORTIO_USART2_TX_PORT                 (gpioPortA)
-#define PORTIO_USART2_TX_LOC                  (1)
+#define PORTIO_USART2_TX_PIN (6)
+#define PORTIO_USART2_TX_PORT (gpioPortA)
+#define PORTIO_USART2_TX_LOC (1)
 
 // [USART2]$
 
 // $[USART3]
-#define PORTIO_USART3_CTS_PIN                 (8)
-#define PORTIO_USART3_CTS_PORT                (gpioPortD)
-#define PORTIO_USART3_CTS_LOC                 (28)
+#define PORTIO_USART3_CTS_PIN (8)
+#define PORTIO_USART3_CTS_PORT (gpioPortD)
+#define PORTIO_USART3_CTS_LOC (28)
 
-#define PORTIO_USART3_RTS_PIN                 (9)
-#define PORTIO_USART3_RTS_PORT                (gpioPortD)
-#define PORTIO_USART3_RTS_LOC                 (28)
+#define PORTIO_USART3_RTS_PIN (9)
+#define PORTIO_USART3_RTS_PORT (gpioPortD)
+#define PORTIO_USART3_RTS_LOC (28)
 
-#define PORTIO_USART3_RX_PIN                  (7)
-#define PORTIO_USART3_RX_PORT                 (gpioPortB)
-#define PORTIO_USART3_RX_LOC                  (10)
+#define PORTIO_USART3_RX_PIN (7)
+#define PORTIO_USART3_RX_PORT (gpioPortB)
+#define PORTIO_USART3_RX_LOC (10)
 
-#define PORTIO_USART3_TX_PIN                  (6)
-#define PORTIO_USART3_TX_PORT                 (gpioPortB)
-#define PORTIO_USART3_TX_LOC                  (10)
+#define PORTIO_USART3_TX_PIN (6)
+#define PORTIO_USART3_TX_PORT (gpioPortB)
+#define PORTIO_USART3_TX_LOC (10)
 
 // [USART3]$
 
@@ -396,4 +405,3 @@
 // [WTIMER1]$
 
 #endif /* HAL_CONFIG_H */
-
diff --git a/examples/platforms/efr32mg12/brd4170a/board_config.h b/examples/platforms/efr32mg12/brd4170a/board_config.h
index 9ec59c0..2e946b9 100644
--- a/examples/platforms/efr32mg12/brd4170a/board_config.h
+++ b/examples/platforms/efr32mg12/brd4170a/board_config.h
@@ -35,17 +35,17 @@
 #ifndef __BOARD_CONFIG_H__
 #define __BOARD_CONFIG_H__
 
-#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1   /// Dev board suppports OQPSK modulation in 2.4GHz band.
-#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 1   /// Dev board suppports OQPSK modulation in 915MHz band.
+#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 915MHz band.
 
 #ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
 #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
 #endif
 
 #ifndef RADIO_CONFIG_DMP_SUPPORT
-#define RADIO_CONFIG_DMP_SUPPORT 0            /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
+#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
 #endif
 
-#define RADIO_CONFIG_PA_USES_DCDC 0           /// The PA(s) is(are) fed from VBAT
+#define RADIO_CONFIG_PA_USES_DCDC 0 /// The PA(s) is(are) fed from VBAT
 
 #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg12/brd4170a/hal-config.h b/examples/platforms/efr32mg12/brd4170a/hal-config.h
index 1ff70df..30cc2d8 100644
--- a/examples/platforms/efr32mg12/brd4170a/hal-config.h
+++ b/examples/platforms/efr32mg12/brd4170a/hal-config.h
@@ -33,37 +33,43 @@
 // [BULBPWM_COLOR]$
 
 // $[BUTTON]
-#define BSP_BUTTON_PRESENT                    (1)
+#define BSP_BUTTON_PRESENT (1)
 
-#define BSP_BUTTON0_PIN                       (6U)
-#define BSP_BUTTON0_PORT                      (gpioPortF)
+#define BSP_BUTTON0_PIN (6U)
+#define BSP_BUTTON0_PORT (gpioPortF)
 
-#define BSP_BUTTON1_PIN                       (7U)
-#define BSP_BUTTON1_PORT                      (gpioPortF)
+#define BSP_BUTTON1_PIN (7U)
+#define BSP_BUTTON1_PORT (gpioPortF)
 
-#define BSP_BUTTON_COUNT                      (2U)
-#define BSP_BUTTON_INIT                       { { BSP_BUTTON0_PORT, BSP_BUTTON0_PIN }, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } }
-#define BSP_BUTTON_GPIO_DOUT                  (HAL_GPIO_DOUT_LOW)
-#define BSP_BUTTON_GPIO_MODE                  (HAL_GPIO_MODE_INPUT)
-#define HAL_BUTTON_ENABLE                     { 0, 1 }
-#define HAL_BUTTON_COUNT                      (2U)
+#define BSP_BUTTON_COUNT (2U)
+#define BSP_BUTTON_INIT                                                            \
+    {                                                                              \
+        {BSP_BUTTON0_PORT, BSP_BUTTON0_PIN}, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } \
+    }
+#define BSP_BUTTON_GPIO_DOUT (HAL_GPIO_DOUT_LOW)
+#define BSP_BUTTON_GPIO_MODE (HAL_GPIO_MODE_INPUT)
+#define HAL_BUTTON_ENABLE \
+    {                     \
+        0, 1              \
+    }
+#define HAL_BUTTON_COUNT (2U)
 // [BUTTON]$
 
 // $[CMU]
-#define HAL_CLK_HFCLK_SOURCE                  (HAL_CLK_HFCLK_SOURCE_HFXO)
-#define HAL_CLK_LFECLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define HAL_CLK_LFBCLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_LFXO_PRESENT                  (1)
-#define BSP_CLK_HFXO_PRESENT                  (1)
-#define BSP_CLK_LFXO_INIT                      CMU_LFXOINIT_DEFAULT
-#define BSP_CLK_LFXO_CTUNE                    (32U)
-#define BSP_CLK_LFXO_FREQ                     (32768U)
-#define HAL_CLK_LFACLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_HFXO_FREQ                     (38400000UL)
-#define BSP_CLK_HFXO_CTUNE                    (342)
-#define BSP_CLK_HFXO_INIT                      CMU_HFXOINIT_DEFAULT
-#define BSP_CLK_HFXO_CTUNE_TOKEN              (0)
-#define HAL_CLK_HFXO_AUTOSTART                (HAL_CLK_HFXO_AUTOSTART_NONE)
+#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
+#define HAL_CLK_LFECLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define HAL_CLK_LFBCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_LFXO_PRESENT (1)
+#define BSP_CLK_HFXO_PRESENT (1)
+#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
+#define BSP_CLK_LFXO_CTUNE (32U)
+#define BSP_CLK_LFXO_FREQ (32768U)
+#define HAL_CLK_LFACLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_HFXO_FREQ (38400000UL)
+#define BSP_CLK_HFXO_CTUNE (342)
+#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
+#define BSP_CLK_HFXO_CTUNE_TOKEN (0)
+#define HAL_CLK_HFXO_AUTOSTART (HAL_CLK_HFXO_AUTOSTART_NONE)
 // [CMU]$
 
 // $[COEX]
@@ -76,10 +82,10 @@
 // [CSEN]$
 
 // $[DCDC]
-#define BSP_DCDC_PRESENT                      (1)
+#define BSP_DCDC_PRESENT (1)
 
-#define HAL_DCDC_BYPASS                       (0)
-#define BSP_DCDC_INIT                          EMU_DCDCINIT_DEFAULT
+#define HAL_DCDC_BYPASS (0)
+#define BSP_DCDC_INIT EMU_DCDCINIT_DEFAULT
 // [DCDC]$
 
 // $[EMU]
@@ -113,18 +119,24 @@
 // [IOEXP]$
 
 // $[LED]
-#define BSP_LED_PRESENT                       (1)
+#define BSP_LED_PRESENT (1)
 
-#define BSP_LED0_PIN                          (4U)
-#define BSP_LED0_PORT                         (gpioPortF)
+#define BSP_LED0_PIN (4U)
+#define BSP_LED0_PORT (gpioPortF)
 
-#define BSP_LED1_PIN                          (5U)
-#define BSP_LED1_PORT                         (gpioPortF)
+#define BSP_LED1_PIN (5U)
+#define BSP_LED1_PORT (gpioPortF)
 
-#define HAL_LED_ENABLE                        { 0, 1 }
-#define HAL_LED_COUNT                         (2U)
-#define BSP_LED_COUNT                         (2U)
-#define BSP_LED_INIT                          { { BSP_LED0_PORT, BSP_LED0_PIN }, { BSP_LED1_PORT, BSP_LED1_PIN } }
+#define HAL_LED_ENABLE \
+    {                  \
+        0, 1           \
+    }
+#define HAL_LED_COUNT (2U)
+#define BSP_LED_COUNT (2U)
+#define BSP_LED_INIT                                                   \
+    {                                                                  \
+        {BSP_LED0_PORT, BSP_LED0_PIN}, { BSP_LED1_PORT, BSP_LED1_PIN } \
+    }
 // [LED]$
 
 // $[LESENSE]
@@ -140,13 +152,13 @@
 // [LFXO]$
 
 // $[PA]
-#define HAL_PA_ENABLE                         (1)
+#define HAL_PA_ENABLE (1)
 
-#define HAL_PA_RAMP                           (10UL)
-#define HAL_PA_2P4_LOWPOWER                   (0)
-#define HAL_PA_POWER                          (252U)
-#define HAL_PA_VOLTAGE                        (3300U)
-#define HAL_PA_CURVE_HEADER                    "pa_curves_efr32.h"
+#define HAL_PA_RAMP (10UL)
+#define HAL_PA_2P4_LOWPOWER (0)
+#define HAL_PA_POWER (252U)
+#define HAL_PA_VOLTAGE (3300U)
+#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
 // [PA]$
 
 // $[PCNT0]
@@ -165,65 +177,65 @@
 // [PRS]$
 
 // $[PTI]
-#define PORTIO_PTI_DCLK_PIN                   (11U)
-#define PORTIO_PTI_DCLK_PORT                  (gpioPortB)
-#define PORTIO_PTI_DCLK_LOC                   (6U)
+#define PORTIO_PTI_DCLK_PIN (11U)
+#define PORTIO_PTI_DCLK_PORT (gpioPortB)
+#define PORTIO_PTI_DCLK_LOC (6U)
 
-#define PORTIO_PTI_DFRAME_PIN                 (13U)
-#define PORTIO_PTI_DFRAME_PORT                (gpioPortB)
-#define PORTIO_PTI_DFRAME_LOC                 (6U)
+#define PORTIO_PTI_DFRAME_PIN (13U)
+#define PORTIO_PTI_DFRAME_PORT (gpioPortB)
+#define PORTIO_PTI_DFRAME_LOC (6U)
 
-#define PORTIO_PTI_DOUT_PIN                   (12U)
-#define PORTIO_PTI_DOUT_PORT                  (gpioPortB)
-#define PORTIO_PTI_DOUT_LOC                   (6U)
+#define PORTIO_PTI_DOUT_PIN (12U)
+#define PORTIO_PTI_DOUT_PORT (gpioPortB)
+#define PORTIO_PTI_DOUT_LOC (6U)
 
-#define HAL_PTI_ENABLE                        (1)
+#define HAL_PTI_ENABLE (1)
 
-#define BSP_PTI_DFRAME_PIN                    (13U)
-#define BSP_PTI_DFRAME_PORT                   (gpioPortB)
-#define BSP_PTI_DFRAME_LOC                    (6U)
+#define BSP_PTI_DFRAME_PIN (13U)
+#define BSP_PTI_DFRAME_PORT (gpioPortB)
+#define BSP_PTI_DFRAME_LOC (6U)
 
-#define BSP_PTI_DOUT_PIN                      (12U)
-#define BSP_PTI_DOUT_PORT                     (gpioPortB)
-#define BSP_PTI_DOUT_LOC                      (6U)
+#define BSP_PTI_DOUT_PIN (12U)
+#define BSP_PTI_DOUT_PORT (gpioPortB)
+#define BSP_PTI_DOUT_LOC (6U)
 
-#define HAL_PTI_MODE                          (HAL_PTI_MODE_UART)
-#define HAL_PTI_BAUD_RATE                     (1600000UL)
+#define HAL_PTI_MODE (HAL_PTI_MODE_UART)
+#define HAL_PTI_BAUD_RATE (1600000UL)
 // [PTI]$
 
 // $[PYD1698]
 // [PYD1698]$
 
 // $[SERIAL]
-#define HAL_SERIAL_USART0_ENABLE              (0)
-#define HAL_SERIAL_LEUART0_ENABLE             (0)
-#define HAL_SERIAL_USART1_ENABLE              (0)
-#define HAL_SERIAL_USART2_ENABLE              (0)
-#define HAL_SERIAL_USART3_ENABLE              (0)
-#define HAL_SERIAL_RXWAKE_ENABLE              (0)
-#define HAL_SERIAL_IDLE_WAKE_ENABLE           (1)
-#define BSP_SERIAL_APP_CTS_PIN                (2U)
-#define BSP_SERIAL_APP_CTS_PORT               (gpioPortA)
-#define BSP_SERIAL_APP_CTS_LOC                (30U)
+#define HAL_SERIAL_USART0_ENABLE (0)
+#define HAL_SERIAL_LEUART0_ENABLE (0)
+#define HAL_SERIAL_USART1_ENABLE (0)
+#define HAL_SERIAL_USART2_ENABLE (0)
+#define HAL_SERIAL_USART3_ENABLE (0)
+#define HAL_SERIAL_RXWAKE_ENABLE (0)
+#define HAL_SERIAL_IDLE_WAKE_ENABLE (1)
+#define BSP_SERIAL_APP_CTS_PIN (2U)
+#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_CTS_LOC (30U)
 
-#define BSP_SERIAL_APP_RX_PIN                 (1U)
-#define BSP_SERIAL_APP_RX_PORT                (gpioPortA)
-#define BSP_SERIAL_APP_RX_LOC                 (0U)
+#define BSP_SERIAL_APP_RX_PIN (1U)
+#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RX_LOC (0U)
 
-#define BSP_SERIAL_APP_TX_PIN                 (0U)
-#define BSP_SERIAL_APP_TX_PORT                (gpioPortA)
-#define BSP_SERIAL_APP_TX_LOC                 (0U)
+#define BSP_SERIAL_APP_TX_PIN (0U)
+#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_TX_LOC (0U)
 
-#define BSP_SERIAL_APP_RTS_PIN                (3U)
-#define BSP_SERIAL_APP_RTS_PORT               (gpioPortA)
-#define BSP_SERIAL_APP_RTS_LOC                (30U)
+#define BSP_SERIAL_APP_RTS_PIN (3U)
+#define BSP_SERIAL_APP_RTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RTS_LOC (30U)
 
-#define HAL_SERIAL_APP_RX_QUEUE_SIZE          (128UL)
-#define HAL_SERIAL_APP_BAUD_RATE              (115200UL)
-#define HAL_SERIAL_APP_RXSTOP                 (16UL)
-#define HAL_SERIAL_APP_RXSTART                (16UL)
-#define HAL_SERIAL_APP_TX_QUEUE_SIZE          (128UL)
-#define HAL_SERIAL_APP_FLOW_CONTROL           (HAL_USART_FLOW_CONTROL_HWUART)
+#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128UL)
+#define HAL_SERIAL_APP_BAUD_RATE (115200UL)
+#define HAL_SERIAL_APP_RXSTOP (16UL)
+#define HAL_SERIAL_APP_RXSTART (16UL)
+#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128UL)
+#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
 // [SERIAL]$
 
 // $[SPIDISPLAY]
@@ -242,46 +254,46 @@
 // [UARTNCP]$
 
 // $[USART0]
-#define PORTIO_USART0_CTS_PIN                 (2U)
-#define PORTIO_USART0_CTS_PORT                (gpioPortA)
-#define PORTIO_USART0_CTS_LOC                 (30U)
+#define PORTIO_USART0_CTS_PIN (2U)
+#define PORTIO_USART0_CTS_PORT (gpioPortA)
+#define PORTIO_USART0_CTS_LOC (30U)
 
-#define PORTIO_USART0_RTS_PIN                 (3U)
-#define PORTIO_USART0_RTS_PORT                (gpioPortA)
-#define PORTIO_USART0_RTS_LOC                 (30U)
+#define PORTIO_USART0_RTS_PIN (3U)
+#define PORTIO_USART0_RTS_PORT (gpioPortA)
+#define PORTIO_USART0_RTS_LOC (30U)
 
-#define PORTIO_USART0_RX_PIN                  (1U)
-#define PORTIO_USART0_RX_PORT                 (gpioPortA)
-#define PORTIO_USART0_RX_LOC                  (0U)
+#define PORTIO_USART0_RX_PIN (1U)
+#define PORTIO_USART0_RX_PORT (gpioPortA)
+#define PORTIO_USART0_RX_LOC (0U)
 
-#define PORTIO_USART0_TX_PIN                  (0U)
-#define PORTIO_USART0_TX_PORT                 (gpioPortA)
-#define PORTIO_USART0_TX_LOC                  (0U)
+#define PORTIO_USART0_TX_PIN (0U)
+#define PORTIO_USART0_TX_PORT (gpioPortA)
+#define PORTIO_USART0_TX_LOC (0U)
 
-#define HAL_USART0_ENABLE                     (1)
+#define HAL_USART0_ENABLE (1)
 
-#define BSP_USART0_CTS_PIN                    (2U)
-#define BSP_USART0_CTS_PORT                   (gpioPortA)
-#define BSP_USART0_CTS_LOC                    (30U)
+#define BSP_USART0_CTS_PIN (2U)
+#define BSP_USART0_CTS_PORT (gpioPortA)
+#define BSP_USART0_CTS_LOC (30U)
 
-#define BSP_USART0_RX_PIN                     (1U)
-#define BSP_USART0_RX_PORT                    (gpioPortA)
-#define BSP_USART0_RX_LOC                     (0U)
+#define BSP_USART0_RX_PIN (1U)
+#define BSP_USART0_RX_PORT (gpioPortA)
+#define BSP_USART0_RX_LOC (0U)
 
-#define BSP_USART0_TX_PIN                     (0U)
-#define BSP_USART0_TX_PORT                    (gpioPortA)
-#define BSP_USART0_TX_LOC                     (0U)
+#define BSP_USART0_TX_PIN (0U)
+#define BSP_USART0_TX_PORT (gpioPortA)
+#define BSP_USART0_TX_LOC (0U)
 
-#define BSP_USART0_RTS_PIN                    (3U)
-#define BSP_USART0_RTS_PORT                   (gpioPortA)
-#define BSP_USART0_RTS_LOC                    (30U)
+#define BSP_USART0_RTS_PIN (3U)
+#define BSP_USART0_RTS_PORT (gpioPortA)
+#define BSP_USART0_RTS_LOC (30U)
 
-#define HAL_USART0_RX_QUEUE_SIZE              (128UL)
-#define HAL_USART0_BAUD_RATE                  (115200UL)
-#define HAL_USART0_RXSTOP                     (16UL)
-#define HAL_USART0_RXSTART                    (16UL)
-#define HAL_USART0_TX_QUEUE_SIZE              (128UL)
-#define HAL_USART0_FLOW_CONTROL               (HAL_USART_FLOW_CONTROL_NONE)
+#define HAL_USART0_RX_QUEUE_SIZE (128UL)
+#define HAL_USART0_BAUD_RATE (115200UL)
+#define HAL_USART0_RXSTOP (16UL)
+#define HAL_USART0_RXSTART (16UL)
+#define HAL_USART0_TX_QUEUE_SIZE (128UL)
+#define HAL_USART0_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
 // [USART0]$
 
 // $[USART1]
@@ -294,10 +306,10 @@
 // [USART3]$
 
 // $[VCOM]
-#define HAL_VCOM_ENABLE                       (1)
+#define HAL_VCOM_ENABLE (1)
 
-#define BSP_VCOM_ENABLE_PIN                   (5U)
-#define BSP_VCOM_ENABLE_PORT                  (gpioPortA)
+#define BSP_VCOM_ENABLE_PIN (5U)
+#define BSP_VCOM_ENABLE_PORT (gpioPortA)
 
 // [VCOM]$
 
diff --git a/examples/platforms/efr32mg12/brd4304a/board_config.h b/examples/platforms/efr32mg12/brd4304a/board_config.h
index fdcf413..d798d52 100644
--- a/examples/platforms/efr32mg12/brd4304a/board_config.h
+++ b/examples/platforms/efr32mg12/brd4304a/board_config.h
@@ -35,16 +35,17 @@
 #ifndef __BOARD_CONFIG_H__
 #define __BOARD_CONFIG_H__
 
-#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1   /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 0 /// Dev board doesn't support OQPSK modulation in 915MHz band.
 
 #ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
 #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
 #endif
 
 #ifndef RADIO_CONFIG_DMP_SUPPORT
-#define RADIO_CONFIG_DMP_SUPPORT 0            /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
+#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
 #endif
 
-#define RADIO_CONFIG_PA_USES_DCDC 0           /// The PA(s) is(are) fed from VBAT
+#define RADIO_CONFIG_PA_USES_DCDC 0 /// The PA(s) is(are) fed from VBAT
 
 #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg12/brd4304a/hal-config.h b/examples/platforms/efr32mg12/brd4304a/hal-config.h
index dfad665..a615567 100644
--- a/examples/platforms/efr32mg12/brd4304a/hal-config.h
+++ b/examples/platforms/efr32mg12/brd4304a/hal-config.h
@@ -33,35 +33,38 @@
 // [BULBPWM_COLOR]$
 
 // $[BUTTON]
-#define BSP_BUTTON_PRESENT                            (1)
+#define BSP_BUTTON_PRESENT (1)
 
-#define BSP_BUTTON0_PIN                               (6U)
-#define BSP_BUTTON0_PORT                              (gpioPortF)
+#define BSP_BUTTON0_PIN (6U)
+#define BSP_BUTTON0_PORT (gpioPortF)
 
-#define BSP_BUTTON1_PIN                               (7U)
-#define BSP_BUTTON1_PORT                              (gpioPortF)
+#define BSP_BUTTON1_PIN (7U)
+#define BSP_BUTTON1_PORT (gpioPortF)
 
-#define BSP_BUTTON_COUNT                              (2U)
-#define BSP_BUTTON_INIT                               { { BSP_BUTTON0_PORT, BSP_BUTTON0_PIN }, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } }
-#define BSP_BUTTON_GPIO_DOUT                          (HAL_GPIO_DOUT_LOW)
-#define BSP_BUTTON_GPIO_MODE                          (HAL_GPIO_MODE_INPUT)
+#define BSP_BUTTON_COUNT (2U)
+#define BSP_BUTTON_INIT                                                            \
+    {                                                                              \
+        {BSP_BUTTON0_PORT, BSP_BUTTON0_PIN}, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } \
+    }
+#define BSP_BUTTON_GPIO_DOUT (HAL_GPIO_DOUT_LOW)
+#define BSP_BUTTON_GPIO_MODE (HAL_GPIO_MODE_INPUT)
 // [BUTTON]$
 
 // $[CMU]
-#define HAL_CLK_HFCLK_SOURCE                  (HAL_CLK_HFCLK_SOURCE_HFXO)
-#define HAL_CLK_LFECLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define HAL_CLK_LFBCLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_LFXO_PRESENT                  (1)
-#define BSP_CLK_HFXO_PRESENT                  (1)
-#define BSP_CLK_LFXO_INIT                      CMU_LFXOINIT_DEFAULT
-#define BSP_CLK_LFXO_CTUNE                    (0U)
-#define BSP_CLK_LFXO_FREQ                     (32768U)
-#define HAL_CLK_LFACLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_HFXO_FREQ                     (38400000UL)
-#define BSP_CLK_HFXO_CTUNE                    (285)
-#define BSP_CLK_HFXO_INIT                      CMU_HFXOINIT_DEFAULT
-#define BSP_CLK_HFXO_CTUNE_TOKEN              (1)
-#define HAL_CLK_HFXO_AUTOSTART                (HAL_CLK_HFXO_AUTOSTART_NONE)
+#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
+#define HAL_CLK_LFECLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define HAL_CLK_LFBCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_LFXO_PRESENT (1)
+#define BSP_CLK_HFXO_PRESENT (1)
+#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
+#define BSP_CLK_LFXO_CTUNE (0U)
+#define BSP_CLK_LFXO_FREQ (32768U)
+#define HAL_CLK_LFACLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_HFXO_FREQ (38400000UL)
+#define BSP_CLK_HFXO_CTUNE (285)
+#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
+#define BSP_CLK_HFXO_CTUNE_TOKEN (1)
+#define HAL_CLK_HFXO_AUTOSTART (HAL_CLK_HFXO_AUTOSTART_NONE)
 // [CMU]$
 
 // $[COEX]
@@ -74,10 +77,10 @@
 // [CSEN]$
 
 // $[DCDC]
-#define BSP_DCDC_PRESENT                      (1)
+#define BSP_DCDC_PRESENT (1)
 
-#define HAL_DCDC_BYPASS                       (0)
-#define BSP_DCDC_INIT                          EMU_DCDCINIT_DEFAULT
+#define HAL_DCDC_BYPASS (0)
+#define BSP_DCDC_INIT EMU_DCDCINIT_DEFAULT
 // [DCDC]$
 
 // $[EMU]
@@ -90,39 +93,39 @@
 // [EZRADIOPRO]$
 
 // $[FEM]
-#define HAL_FEM_ENABLE                        (1)
+#define HAL_FEM_ENABLE (1)
 
-#define BSP_FEM_RX_PIN                        (10U)
-#define BSP_FEM_RX_PORT                       (gpioPortD)
-#define BSP_FEM_RX_LOC                        (0U)
+#define BSP_FEM_RX_PIN (10U)
+#define BSP_FEM_RX_PORT (gpioPortD)
+#define BSP_FEM_RX_LOC (0U)
 
-#define BSP_FEM_SLEEP_PIN                     (11U)
-#define BSP_FEM_SLEEP_PORT                    (gpioPortD)
-#define BSP_FEM_SLEEP_LOC                     (13U)
+#define BSP_FEM_SLEEP_PIN (11U)
+#define BSP_FEM_SLEEP_PORT (gpioPortD)
+#define BSP_FEM_SLEEP_LOC (13U)
 
-#define HAL_FEM_RX_ACTIVE                     (1)
-#define BSP_FEM_RX_CHANNEL                    (5)
-#define HAL_FEM_TX_ACTIVE                     (0)
-#define HAL_FEM_BYPASS_ENABLE                 (0)
-#define BSP_FEM_SLEEP_CHANNEL                 (6)
-#define HAL_FEM_TX_HIGH_POWER                 (0)
+#define HAL_FEM_RX_ACTIVE (1)
+#define BSP_FEM_RX_CHANNEL (5)
+#define HAL_FEM_TX_ACTIVE (0)
+#define HAL_FEM_BYPASS_ENABLE (0)
+#define BSP_FEM_SLEEP_CHANNEL (6)
+#define HAL_FEM_TX_HIGH_POWER (0)
 // [FEM]$
 
 // $[GPIO]
-#define PORTIO_GPIO_SWV_PIN                   (2U)
-#define PORTIO_GPIO_SWV_PORT                  (gpioPortF)
-#define PORTIO_GPIO_SWV_LOC                   (0U)
+#define PORTIO_GPIO_SWV_PIN (2U)
+#define PORTIO_GPIO_SWV_PORT (gpioPortF)
+#define PORTIO_GPIO_SWV_LOC (0U)
 
 // [GPIO]$
 
 // $[I2C0]
-#define PORTIO_I2C0_SCL_PIN                   (11U)
-#define PORTIO_I2C0_SCL_PORT                  (gpioPortC)
-#define PORTIO_I2C0_SCL_LOC                   (15U)
+#define PORTIO_I2C0_SCL_PIN (11U)
+#define PORTIO_I2C0_SCL_PORT (gpioPortC)
+#define PORTIO_I2C0_SCL_LOC (15U)
 
-#define PORTIO_I2C0_SDA_PIN                   (10U)
-#define PORTIO_I2C0_SDA_PORT                  (gpioPortC)
-#define PORTIO_I2C0_SDA_LOC                   (15U)
+#define PORTIO_I2C0_SDA_PIN (10U)
+#define PORTIO_I2C0_SDA_PORT (gpioPortC)
+#define PORTIO_I2C0_SDA_LOC (15U)
 
 // [I2C0]$
 
@@ -139,18 +142,24 @@
 // [IOEXP]$
 
 // $[LED]
-#define BSP_LED_PRESENT                       (1)
+#define BSP_LED_PRESENT (1)
 
-#define BSP_LED0_PIN                          (6U)
-#define BSP_LED0_PORT                         (gpioPortF)
+#define BSP_LED0_PIN (6U)
+#define BSP_LED0_PORT (gpioPortF)
 
-#define BSP_LED1_PIN                          (7U)
-#define BSP_LED1_PORT                         (gpioPortF)
+#define BSP_LED1_PIN (7U)
+#define BSP_LED1_PORT (gpioPortF)
 
-#define HAL_LED_ENABLE                        { 0, 1 }
-#define HAL_LED_COUNT                         (2U)
-#define BSP_LED_COUNT                         (2U)
-#define BSP_LED_INIT                          { { BSP_LED0_PORT, BSP_LED0_PIN }, { BSP_LED1_PORT, BSP_LED1_PIN } }
+#define HAL_LED_ENABLE \
+    {                  \
+        0, 1           \
+    }
+#define HAL_LED_COUNT (2U)
+#define BSP_LED_COUNT (2U)
+#define BSP_LED_INIT                                                   \
+    {                                                                  \
+        {BSP_LED0_PORT, BSP_LED0_PIN}, { BSP_LED1_PORT, BSP_LED1_PIN } \
+    }
 // [LED]$
 
 // $[LESENSE]
@@ -166,13 +175,13 @@
 // [LFXO]$
 
 // $[PA]
-#define HAL_PA_ENABLE                         (1)
+#define HAL_PA_ENABLE (1)
 
-#define HAL_PA_RAMP                           (10UL)
-#define HAL_PA_2P4_LOWPOWER                   (0)
-#define HAL_PA_POWER                          (252U)
-#define HAL_PA_VOLTAGE                        (3300U)
-#define HAL_PA_CURVE_HEADER                    "pa_curves_efr32.h"
+#define HAL_PA_RAMP (10UL)
+#define HAL_PA_2P4_LOWPOWER (0)
+#define HAL_PA_POWER (252U)
+#define HAL_PA_VOLTAGE (3300U)
+#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
 // [PA]$
 
 // $[PCNT0]
@@ -188,75 +197,75 @@
 // [PORTIO]$
 
 // $[PRS]
-#define PORTIO_PRS_CH4_PIN                    (13U)
-#define PORTIO_PRS_CH4_PORT                   (gpioPortD)
-#define PORTIO_PRS_CH4_LOC                    (4U)
+#define PORTIO_PRS_CH4_PIN (13U)
+#define PORTIO_PRS_CH4_PORT (gpioPortD)
+#define PORTIO_PRS_CH4_LOC (4U)
 
-#define PORTIO_PRS_CH5_PIN                    (10U)
-#define PORTIO_PRS_CH5_PORT                   (gpioPortD)
-#define PORTIO_PRS_CH5_LOC                    (0U)
+#define PORTIO_PRS_CH5_PIN (10U)
+#define PORTIO_PRS_CH5_PORT (gpioPortD)
+#define PORTIO_PRS_CH5_LOC (0U)
 
-#define PORTIO_PRS_CH6_PIN                    (11U)
-#define PORTIO_PRS_CH6_PORT                   (gpioPortD)
-#define PORTIO_PRS_CH6_LOC                    (13U)
+#define PORTIO_PRS_CH6_PIN (11U)
+#define PORTIO_PRS_CH6_PORT (gpioPortD)
+#define PORTIO_PRS_CH6_LOC (13U)
 
 // [PRS]$
 
 // $[PTI]
-#define PORTIO_PTI_DFRAME_PIN                 (13U)
-#define PORTIO_PTI_DFRAME_PORT                (gpioPortB)
-#define PORTIO_PTI_DFRAME_LOC                 (6U)
+#define PORTIO_PTI_DFRAME_PIN (13U)
+#define PORTIO_PTI_DFRAME_PORT (gpioPortB)
+#define PORTIO_PTI_DFRAME_LOC (6U)
 
-#define PORTIO_PTI_DOUT_PIN                   (11U)
-#define PORTIO_PTI_DOUT_PORT                  (gpioPortB)
-#define PORTIO_PTI_DOUT_LOC                   (5U)
+#define PORTIO_PTI_DOUT_PIN (11U)
+#define PORTIO_PTI_DOUT_PORT (gpioPortB)
+#define PORTIO_PTI_DOUT_LOC (5U)
 
-#define HAL_PTI_ENABLE                        (1)
+#define HAL_PTI_ENABLE (1)
 
-#define BSP_PTI_DFRAME_PIN                    (13U)
-#define BSP_PTI_DFRAME_PORT                   (gpioPortB)
-#define BSP_PTI_DFRAME_LOC                    (6U)
+#define BSP_PTI_DFRAME_PIN (13U)
+#define BSP_PTI_DFRAME_PORT (gpioPortB)
+#define BSP_PTI_DFRAME_LOC (6U)
 
-#define BSP_PTI_DOUT_PIN                      (11U)
-#define BSP_PTI_DOUT_PORT                     (gpioPortB)
-#define BSP_PTI_DOUT_LOC                      (5U)
+#define BSP_PTI_DOUT_PIN (11U)
+#define BSP_PTI_DOUT_PORT (gpioPortB)
+#define BSP_PTI_DOUT_LOC (5U)
 
-#define HAL_PTI_MODE                          (HAL_PTI_MODE_UART)
-#define HAL_PTI_BAUD_RATE                     (1600000UL)
+#define HAL_PTI_MODE (HAL_PTI_MODE_UART)
+#define HAL_PTI_BAUD_RATE (1600000UL)
 // [PTI]$
 
 // $[PYD1698]
 // [PYD1698]$
 
 // $[SERIAL]
-#define HAL_SERIAL_USART0_ENABLE              (0)
-#define HAL_SERIAL_LEUART0_ENABLE             (0)
-#define HAL_SERIAL_USART1_ENABLE              (0)
-#define HAL_SERIAL_USART2_ENABLE              (0)
-#define HAL_SERIAL_USART3_ENABLE              (0)
-#define HAL_SERIAL_RXWAKE_ENABLE              (0)
-#define BSP_SERIAL_APP_CTS_PIN                (2U)
-#define BSP_SERIAL_APP_CTS_PORT               (gpioPortA)
-#define BSP_SERIAL_APP_CTS_LOC                (30U)
+#define HAL_SERIAL_USART0_ENABLE (0)
+#define HAL_SERIAL_LEUART0_ENABLE (0)
+#define HAL_SERIAL_USART1_ENABLE (0)
+#define HAL_SERIAL_USART2_ENABLE (0)
+#define HAL_SERIAL_USART3_ENABLE (0)
+#define HAL_SERIAL_RXWAKE_ENABLE (0)
+#define BSP_SERIAL_APP_CTS_PIN (2U)
+#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_CTS_LOC (30U)
 
-#define BSP_SERIAL_APP_RX_PIN                 (1U)
-#define BSP_SERIAL_APP_RX_PORT                (gpioPortA)
-#define BSP_SERIAL_APP_RX_LOC                 (0U)
+#define BSP_SERIAL_APP_RX_PIN (1U)
+#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RX_LOC (0U)
 
-#define BSP_SERIAL_APP_TX_PIN                 (0U)
-#define BSP_SERIAL_APP_TX_PORT                (gpioPortA)
-#define BSP_SERIAL_APP_TX_LOC                 (0U)
+#define BSP_SERIAL_APP_TX_PIN (0U)
+#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_TX_LOC (0U)
 
-#define BSP_SERIAL_APP_RTS_PIN                (3U)
-#define BSP_SERIAL_APP_RTS_PORT               (gpioPortA)
-#define BSP_SERIAL_APP_RTS_LOC                (30U)
+#define BSP_SERIAL_APP_RTS_PIN (3U)
+#define BSP_SERIAL_APP_RTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RTS_LOC (30U)
 
-#define HAL_SERIAL_APP_RX_QUEUE_SIZE          (128UL)
-#define HAL_SERIAL_APP_BAUD_RATE              (115200UL)
-#define HAL_SERIAL_APP_RXSTOP                 (16UL)
-#define HAL_SERIAL_APP_RXSTART                (16UL)
-#define HAL_SERIAL_APP_TX_QUEUE_SIZE          (128UL)
-#define HAL_SERIAL_APP_FLOW_CONTROL           (HAL_USART_FLOW_CONTROL_HWUART)
+#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128UL)
+#define HAL_SERIAL_APP_BAUD_RATE (115200UL)
+#define HAL_SERIAL_APP_RXSTOP (16UL)
+#define HAL_SERIAL_APP_RXSTART (16UL)
+#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128UL)
+#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
 // [SERIAL]$
 
 // $[SPIDISPLAY]
@@ -275,64 +284,64 @@
 // [UARTNCP]$
 
 // $[USART0]
-#define PORTIO_USART0_CTS_PIN                 (2U)
-#define PORTIO_USART0_CTS_PORT                (gpioPortA)
-#define PORTIO_USART0_CTS_LOC                 (30U)
+#define PORTIO_USART0_CTS_PIN (2U)
+#define PORTIO_USART0_CTS_PORT (gpioPortA)
+#define PORTIO_USART0_CTS_LOC (30U)
 
-#define PORTIO_USART0_RTS_PIN                 (3U)
-#define PORTIO_USART0_RTS_PORT                (gpioPortA)
-#define PORTIO_USART0_RTS_LOC                 (30U)
+#define PORTIO_USART0_RTS_PIN (3U)
+#define PORTIO_USART0_RTS_PORT (gpioPortA)
+#define PORTIO_USART0_RTS_LOC (30U)
 
-#define PORTIO_USART0_RX_PIN                  (1U)
-#define PORTIO_USART0_RX_PORT                 (gpioPortA)
-#define PORTIO_USART0_RX_LOC                  (0U)
+#define PORTIO_USART0_RX_PIN (1U)
+#define PORTIO_USART0_RX_PORT (gpioPortA)
+#define PORTIO_USART0_RX_LOC (0U)
 
-#define PORTIO_USART0_TX_PIN                  (0U)
-#define PORTIO_USART0_TX_PORT                 (gpioPortA)
-#define PORTIO_USART0_TX_LOC                  (0U)
+#define PORTIO_USART0_TX_PIN (0U)
+#define PORTIO_USART0_TX_PORT (gpioPortA)
+#define PORTIO_USART0_TX_LOC (0U)
 
-#define HAL_USART0_ENABLE                     (1)
+#define HAL_USART0_ENABLE (1)
 
-#define BSP_USART0_CTS_PIN                    (2U)
-#define BSP_USART0_CTS_PORT                   (gpioPortA)
-#define BSP_USART0_CTS_LOC                    (30U)
+#define BSP_USART0_CTS_PIN (2U)
+#define BSP_USART0_CTS_PORT (gpioPortA)
+#define BSP_USART0_CTS_LOC (30U)
 
-#define BSP_USART0_RX_PIN                     (1U)
-#define BSP_USART0_RX_PORT                    (gpioPortA)
-#define BSP_USART0_RX_LOC                     (0U)
+#define BSP_USART0_RX_PIN (1U)
+#define BSP_USART0_RX_PORT (gpioPortA)
+#define BSP_USART0_RX_LOC (0U)
 
-#define BSP_USART0_TX_PIN                     (0U)
-#define BSP_USART0_TX_PORT                    (gpioPortA)
-#define BSP_USART0_TX_LOC                     (0U)
+#define BSP_USART0_TX_PIN (0U)
+#define BSP_USART0_TX_PORT (gpioPortA)
+#define BSP_USART0_TX_LOC (0U)
 
-#define BSP_USART0_RTS_PIN                    (3U)
-#define BSP_USART0_RTS_PORT                   (gpioPortA)
-#define BSP_USART0_RTS_LOC                    (30U)
+#define BSP_USART0_RTS_PIN (3U)
+#define BSP_USART0_RTS_PORT (gpioPortA)
+#define BSP_USART0_RTS_LOC (30U)
 
-#define HAL_USART0_RX_QUEUE_SIZE              (128UL)
-#define HAL_USART0_BAUD_RATE                  (115200UL)
-#define HAL_USART0_RXSTOP                     (16UL)
-#define HAL_USART0_RXSTART                    (16UL)
-#define HAL_USART0_TX_QUEUE_SIZE              (128UL)
-#define HAL_USART0_FLOW_CONTROL               (HAL_USART_FLOW_CONTROL_HWUART)
+#define HAL_USART0_RX_QUEUE_SIZE (128UL)
+#define HAL_USART0_BAUD_RATE (115200UL)
+#define HAL_USART0_RXSTOP (16UL)
+#define HAL_USART0_RXSTART (16UL)
+#define HAL_USART0_TX_QUEUE_SIZE (128UL)
+#define HAL_USART0_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
 // [USART0]$
 
 // $[USART1]
-#define PORTIO_USART1_CLK_PIN                 (8U)
-#define PORTIO_USART1_CLK_PORT                (gpioPortC)
-#define PORTIO_USART1_CLK_LOC                 (11U)
+#define PORTIO_USART1_CLK_PIN (8U)
+#define PORTIO_USART1_CLK_PORT (gpioPortC)
+#define PORTIO_USART1_CLK_LOC (11U)
 
-#define PORTIO_USART1_CS_PIN                  (9U)
-#define PORTIO_USART1_CS_PORT                 (gpioPortC)
-#define PORTIO_USART1_CS_LOC                  (11U)
+#define PORTIO_USART1_CS_PIN (9U)
+#define PORTIO_USART1_CS_PORT (gpioPortC)
+#define PORTIO_USART1_CS_LOC (11U)
 
-#define PORTIO_USART1_RX_PIN                  (7U)
-#define PORTIO_USART1_RX_PORT                 (gpioPortC)
-#define PORTIO_USART1_RX_LOC                  (11U)
+#define PORTIO_USART1_RX_PIN (7U)
+#define PORTIO_USART1_RX_PORT (gpioPortC)
+#define PORTIO_USART1_RX_LOC (11U)
 
-#define PORTIO_USART1_TX_PIN                  (6U)
-#define PORTIO_USART1_TX_PORT                 (gpioPortC)
-#define PORTIO_USART1_TX_LOC                  (11U)
+#define PORTIO_USART1_TX_PIN (6U)
+#define PORTIO_USART1_TX_PORT (gpioPortC)
+#define PORTIO_USART1_TX_LOC (11U)
 
 // [USART1]$
 
@@ -361,4 +370,3 @@
 // [WTIMER1]$
 
 #endif /* HAL_CONFIG_H */
-
diff --git a/examples/platforms/efr32mg12/crypto/efr32-mbedtls-config.h b/examples/platforms/efr32mg12/crypto/efr32-mbedtls-config.h
index 4a88790..14f1d1c 100644
--- a/examples/platforms/efr32mg12/crypto/efr32-mbedtls-config.h
+++ b/examples/platforms/efr32mg12/crypto/efr32-mbedtls-config.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  *  POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
 #ifndef EFR32_MBEDTLS_CONFIG_H
 #define EFR32_MBEDTLS_CONFIG_H
 
@@ -86,7 +86,7 @@
  * See MBEDTLS_SHA256_C for more information.
  */
 #if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
-//#define MBEDTLS_SHA256_ALT
+#define MBEDTLS_SHA256_ALT
 #endif
 
 #endif // EFR32_MBEDTLS_CONFIG_H
diff --git a/examples/platforms/efr32mg12/diag.c b/examples/platforms/efr32mg12/diag.c
index 9da4bdf..a7c3357 100644
--- a/examples/platforms/efr32mg12/diag.c
+++ b/examples/platforms/efr32mg12/diag.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -51,15 +51,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
-
-    // Add more platform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/efr32mg12/efr32mg12.ld b/examples/platforms/efr32mg12/efr32mg12.ld
new file mode 100644
index 0000000..7ba26f6
--- /dev/null
+++ b/examples/platforms/efr32mg12/efr32mg12.ld
@@ -0,0 +1,246 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**
+ * @file
+ *   This file implements the OpenThread linker script for the
+ *   Silicon Labs efr32mg12 platform.
+ *
+ */
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1024K
+  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 256K
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __copy_table_start__
+ *   __copy_table_end__
+ *   __zero_table_start__
+ *   __zero_table_end__
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __Vectors_End
+ *   __Vectors_Size
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+  .text :
+  {
+    KEEP(*(.vectors))
+    __Vectors_End = .;
+    __Vectors_Size = __Vectors_End - __Vectors;
+    __end__ = .;
+
+    *(.text*)
+
+    KEEP(*(.init))
+    KEEP(*(.fini))
+
+    /* .ctors */
+    *crtbegin.o(.ctors)
+    *crtbegin?.o(.ctors)
+    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+    *(SORT(.ctors.*))
+    *(.ctors)
+
+    /* .dtors */
+    *crtbegin.o(.dtors)
+    *crtbegin?.o(.dtors)
+    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+    *(SORT(.dtors.*))
+    *(.dtors)
+
+    *(.rodata*)
+
+    KEEP(*(.eh_frame*))
+  } > FLASH
+
+  .ARM.extab :
+  {
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+  } > FLASH
+
+  __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } > FLASH
+  __exidx_end = .;
+
+  /* To copy multiple ROM to RAM sections,
+   * uncomment .copy.table section and,
+   * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
+  /*
+  .copy.table :
+  {
+    . = ALIGN(4);
+    __copy_table_start__ = .;
+    LONG (__etext)
+    LONG (__data_start__)
+    LONG (__data_end__ - __data_start__)
+    LONG (__etext2)
+    LONG (__data2_start__)
+    LONG (__data2_end__ - __data2_start__)
+    __copy_table_end__ = .;
+  } > FLASH
+  */
+
+  /* To clear multiple BSS sections,
+   * uncomment .zero.table section and,
+   * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
+  /*
+  .zero.table :
+  {
+    . = ALIGN(4);
+    __zero_table_start__ = .;
+    LONG (__bss_start__)
+    LONG (__bss_end__ - __bss_start__)
+    LONG (__bss2_start__)
+    LONG (__bss2_end__ - __bss2_start__)
+    __zero_table_end__ = .;
+  } > FLASH
+  */
+
+  __etext = .;
+
+  .data : AT (__etext)
+  {
+    __data_start__ = .;
+    *(vtable)
+    *(.data*)
+    . = ALIGN (4);
+    PROVIDE (__ram_func_section_start = .);
+    *(.ram)
+    PROVIDE (__ram_func_section_end = .);
+
+    . = ALIGN(4);
+    /* preinit data */
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP(*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+
+    . = ALIGN(4);
+    /* init data */
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP(*(SORT(.init_array.*)))
+    KEEP(*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+
+    . = ALIGN(4);
+    /* finit data */
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP(*(SORT(.fini_array.*)))
+    KEEP(*(.fini_array))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+
+    KEEP(*(.jcr*))
+    . = ALIGN(4);
+    /* All data end */
+    __data_end__ = .;
+
+  } > RAM
+
+  .bss :
+  {
+    . = ALIGN(4);
+    __bss_start__ = .;
+    *(.bss*)
+    *(COMMON)
+    . = ALIGN(4);
+    __bss_end__ = .;
+  } > RAM
+
+  .heap (COPY):
+  {
+    __HeapBase = .;
+    __end__ = .;
+    end = __end__;
+    _end = __end__;
+    KEEP(*(.heap*))
+    __HeapLimit = .;
+  } > RAM
+
+  /* .stack_dummy section doesn't contains any symbols. It is only
+   * used for linker to calculate size of stack sections, and assign
+   * values to stack symbols later */
+  .stack_dummy (COPY):
+  {
+    KEEP(*(.stack*))
+  } > RAM
+
+  /* Set stack top to end of RAM, and stack limit move down by
+   * size of stack_dummy section */
+  __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+  PROVIDE(__stack = __StackTop);
+
+  /*******************************************************************/
+  /* Define flash block for nvm3                                     */
+  .nvm (DSECT) : {
+    KEEP(*(.simee*))
+  } > FLASH
+
+  linker_nvm_end = ORIGIN(FLASH) + LENGTH(FLASH);
+  linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm);
+  linker_nvm_size = SIZEOF(.nvm);
+  __nvm3Base = linker_nvm_begin;
+  /*******************************************************************/
+
+  /* Check if data + heap + stack exceeds RAM limit */
+  ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+
+  /* Check if FLASH usage exceeds FLASH size */
+  ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
+}
diff --git a/examples/platforms/efr32mg12/entropy.c b/examples/platforms/efr32mg12/entropy.c
index f085a59..2b196bb 100644
--- a/examples/platforms/efr32mg12/entropy.c
+++ b/examples/platforms/efr32mg12/entropy.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2019, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/fem-control.c b/examples/platforms/efr32mg12/fem-control.c
index 5ee527e..f66415c 100644
--- a/examples/platforms/efr32mg12/fem-control.c
+++ b/examples/platforms/efr32mg12/fem-control.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/flash.c b/examples/platforms/efr32mg12/flash.c
index 83ce5a4..15d46ea 100644
--- a/examples/platforms/efr32mg12/flash.c
+++ b/examples/platforms/efr32mg12/flash.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -31,114 +31,334 @@
  *   This file implements the OpenThread platform abstraction for the non-volatile storage.
  */
 
-#include <openthread-core-config.h>
-
+#include "openthread-core-efr32-config.h"
 #include <openthread/config.h>
-#include <openthread/platform/alarm-milli.h>
 
-#include "utils/code_utils.h"
-#include "utils/flash.h"
+#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE // Use OT NV system
 
 #include "em_msc.h"
+#include <string.h>
+#include <openthread/instance.h>
 
-// clang-format off
-#define FLASH_DATA_END_ADDR     (FLASH_BASE + FLASH_SIZE)
-#define FLASH_DATA_START_ADDR   (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM))
-// clang-format on
+#define FLASH_PAGE_NUM 2
+#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
+#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * FLASH_PAGE_NUM))
+#define FLASH_SWAP_PAGE_NUM (FLASH_PAGE_NUM / 2)
+#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * FLASH_SWAP_PAGE_NUM)
 
-static inline uint32_t mapAddress(uint32_t aAddress)
+static inline uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    return aAddress + FLASH_DATA_START_ADDR;
+    uint32_t address;
+
+    address = FLASH_DATA_START_ADDR + aOffset;
+
+    if (aSwapIndex)
+    {
+        address += FLASH_SWAP_SIZE;
+    }
+
+    return address;
 }
 
-static otError returnTypeConvert(int32_t aStatus)
+void otPlatFlashInit(otInstance *aInstance)
 {
-    otError error = OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
+}
 
-    switch (aStatus)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return FLASH_SWAP_SIZE;
+}
+
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address = mapAddress(aSwapIndex, 0);
+
+    for (uint32_t n = 0; n < FLASH_SWAP_PAGE_NUM; n++, address += FLASH_PAGE_SIZE)
     {
-    case mscReturnOk:
-        error = OT_ERROR_NONE;
+        MSC_ErasePage((uint32_t *)address);
+    }
+}
+
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    MSC_WriteWord((uint32_t *)mapAddress(aSwapIndex, aOffset), aData, aSize);
+}
+
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    memcpy(aData, (const uint8_t *)mapAddress(aSwapIndex, aOffset), aSize);
+}
+
+#else // Defaults to Silabs nvm3 system
+
+#include "nvm3.h"
+#include "nvm3_default.h"
+#include <string.h>
+#include <openthread/platform/settings.h>
+#include "common/code_utils.hpp"
+#include "common/logging.hpp"
+
+#define NVM3KEY_DOMAIN_OPENTHREAD 0x20000U
+#define NUM_INDEXED_SETTINGS \
+    OPENTHREAD_CONFIG_MLE_MAX_CHILDREN // Indexed key types are only supported for kKeyChildInfo (=='child table').
+#define ENUM_NVM3_KEY_LIST_SIZE 4      // List size used when enumerating nvm3 keys.
+
+static otError          addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
+static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index);
+static otError          mapNvm3Error(Ecode_t nvm3Res);
+
+void otPlatSettingsInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    if (mapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)) != OT_ERROR_NONE)
+    {
+        otLogDebgPlat("Error initializing nvm3 instance");
+    }
+}
+
+void otPlatSettingsDeinit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    nvm3_close(nvm3_defaultHandle);
+}
+
+otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
+{
+    // Searches through all matching nvm3 keys to find the one with the required
+    // 'index', then reads the nvm3 data into the destination buffer.
+    // (Repeatedly enumerates a list of matching keys from the nvm3 until the
+    // required index is found).
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError  err;
+    uint16_t valueLength = 0;
+
+    nvm3_ObjectKey_t nvm3Key  = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
+    bool             idxFound = false;
+    int              idx      = 0;
+    err                       = OT_ERROR_NOT_FOUND;
+    while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
+    {
+        // Get the next nvm3 key list.
+        nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
+        size_t           objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, nvm3Key,
+                                         makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
+        for (size_t i = 0; i < objCnt; ++i)
+        {
+            nvm3Key = keys[i];
+            if (idx == aIndex)
+            {
+                uint32_t objType;
+                size_t   objLen;
+                err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+                if (err == OT_ERROR_NONE)
+                {
+                    valueLength = objLen;
+
+                    // Only perform read if an input buffer was passed in.
+                    if ((aValue != NULL) && (aValueLength != NULL))
+                    {
+                        // Read all nvm3 obj bytes into a tmp buffer, then copy the required
+                        // number of bytes to the read destination buffer.
+                        uint8_t *buf = malloc(valueLength);
+                        err          = mapNvm3Error(nvm3_readData(nvm3_defaultHandle, nvm3Key, buf, valueLength));
+                        if (err == OT_ERROR_NONE)
+                        {
+                            memcpy(aValue, buf, (valueLength < *aValueLength) ? valueLength : *aValueLength);
+                        }
+                        free(buf);
+                        SuccessOrExit(err);
+                    }
+                }
+                idxFound = true;
+                break;
+            }
+            ++idx;
+        }
+        if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
+        {
+            // Stop searching (there are no more matching nvm3 objects).
+            break;
+        }
+        ++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
+    }
+
+exit:
+    if (aValueLength != NULL)
+    {
+        *aValueLength = valueLength; // always return actual nvm3 object length.
+    }
+
+    return err;
+}
+
+otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError err;
+
+    // Delete all nvm3 objects matching the input key (i.e. the 'setting indexes' of the key).
+    err = otPlatSettingsDelete(aInstance, aKey, -1);
+    if ((err == OT_ERROR_NONE) || (err == OT_ERROR_NOT_FOUND))
+    {
+        // Add new setting object (i.e. 'index0' of the key).
+        err = addSetting(aKey, aValue, aValueLength);
+        SuccessOrExit(err);
+    }
+
+exit:
+    return err;
+}
+
+otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return addSetting(aKey, aValue, aValueLength);
+}
+
+otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
+{
+    // Searches through all matching nvm3 keys to find the one with the required
+    // 'index' (or index = -1 to delete all), then deletes the nvm3 object.
+    // (Repeatedly enumerates a list of matching keys from the nvm3 until the
+    // required index is found).
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError          err;
+    nvm3_ObjectKey_t nvm3Key  = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
+    bool             idxFound = false;
+    int              idx      = 0;
+    err                       = OT_ERROR_NOT_FOUND;
+    while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
+    {
+        // Get the next nvm3 key list.
+        nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
+        size_t           objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, nvm3Key,
+                                         makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
+        for (size_t i = 0; i < objCnt; ++i)
+        {
+            nvm3Key = keys[i];
+            if ((idx == aIndex) || (aIndex == -1))
+            {
+                uint32_t objType;
+                size_t   objLen;
+                err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+                if (err == OT_ERROR_NONE)
+                {
+                    // Delete the nvm3 object.
+                    err = mapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, nvm3Key));
+                    SuccessOrExit(err);
+                }
+                if (aIndex != -1)
+                {
+                    idxFound = true;
+                    break;
+                }
+            }
+            ++idx;
+        }
+        if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
+        {
+            // Stop searching (there are no more matching nvm3 objects).
+            break;
+        }
+        ++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
+    }
+
+exit:
+    return err;
+}
+
+void otPlatSettingsWipe(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    // Delete nvm3 objects for all OT Settings keys (and any of their associated 'indexes').
+    // Note- any OT User nvm3 objects in the OT nvm3 area are NOT be erased.
+    for (uint16_t aKey = 0; aKey < 8; ++aKey)
+    {
+        otPlatSettingsDelete(NULL, aKey, -1);
+    }
+}
+
+// Local functions..
+
+static otError addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    // Helper function- writes input buffer data to a NEW nvm3 object.
+    // nvm3 object is created at the first available Key + index.
+
+    otError err;
+
+    if ((aValueLength == 0) || (aValue == NULL))
+    {
+        err = OT_ERROR_INVALID_ARGS;
+    }
+    else
+    {
+        for (int idx = 0; idx <= NUM_INDEXED_SETTINGS; ++idx)
+        {
+            nvm3_ObjectKey_t nvm3Key;
+            nvm3Key = makeNvm3ObjKey(aKey, idx);
+
+            uint32_t objType;
+            size_t   objLen;
+            err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+            if (err == OT_ERROR_NOT_FOUND)
+            {
+                // Use this index for the new nvm3 object.
+                // Write the binary data to nvm3 (Creates nvm3 object if required).
+                err = mapNvm3Error(nvm3_writeData(nvm3_defaultHandle, nvm3Key, aValue, aValueLength));
+                break;
+            }
+            else if (err != OT_ERROR_NONE)
+            {
+                break;
+            }
+        }
+    }
+
+    return err;
+}
+
+static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index)
+{
+    return (NVM3KEY_DOMAIN_OPENTHREAD | (otSettingsKey << 8) | (index & 0xFF));
+}
+
+static otError mapNvm3Error(Ecode_t nvm3Res)
+{
+    otError err;
+
+    switch (nvm3Res)
+    {
+    case ECODE_NVM3_OK:
+        err = OT_ERROR_NONE;
         break;
 
-    case mscReturnInvalidAddr:
-    case mscReturnUnaligned:
-        error = OT_ERROR_INVALID_ARGS;
+    case ECODE_NVM3_ERR_KEY_NOT_FOUND:
+        err = OT_ERROR_NOT_FOUND;
         break;
 
     default:
-        error = OT_ERROR_FAILED;
+        err = OT_ERROR_FAILED;
+        break;
     }
 
-    return error;
+    return err;
 }
 
-otError utilsFlashInit(void)
-{
-    MSC_Init();
-    return OT_ERROR_NONE;
-}
-
-uint32_t utilsFlashGetSize(void)
-{
-    return FLASH_DATA_END_ADDR - FLASH_DATA_START_ADDR;
-}
-
-otError utilsFlashErasePage(uint32_t aAddress)
-{
-    int32_t status;
-
-    status = MSC_ErasePage((uint32_t *)mapAddress(aAddress));
-
-    return returnTypeConvert(status);
-}
-
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    otError  error = OT_ERROR_BUSY;
-    uint32_t start = otPlatAlarmMilliGetNow();
-
-    do
-    {
-        if (MSC->STATUS & MSC_STATUS_WDATAREADY)
-        {
-            error = OT_ERROR_NONE;
-            break;
-        }
-    } while (aTimeout && ((otPlatAlarmMilliGetNow() - start) < aTimeout));
-
-    return error;
-}
-
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t rval = aSize;
-    int32_t  status;
-
-    otEXPECT_ACTION(aData, rval = 0);
-    otEXPECT_ACTION(((aAddress + aSize) < utilsFlashGetSize()) && (!(aAddress & 3)) && (!(aSize & 3)), rval = 0);
-
-    status = MSC_WriteWord((uint32_t *)mapAddress(aAddress), aData, aSize);
-    otEXPECT_ACTION(returnTypeConvert(status) == OT_ERROR_NONE, rval = 0);
-
-exit:
-    return rval;
-}
-
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t rval     = aSize;
-    uint32_t pAddress = mapAddress(aAddress);
-    uint8_t *byte     = aData;
-
-    otEXPECT_ACTION(aData, rval = 0);
-    otEXPECT_ACTION((aAddress + aSize) < utilsFlashGetSize(), rval = 0);
-
-    while (aSize--)
-    {
-        *byte++ = (*(uint8_t *)(pAddress++));
-    }
-
-exit:
-    return rval;
-}
+#endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
diff --git a/examples/platforms/efr32mg12/logging.c b/examples/platforms/efr32mg12/logging.c
index ad873dd..fa0a4dd 100644
--- a/examples/platforms/efr32mg12/logging.c
+++ b/examples/platforms/efr32mg12/logging.c
@@ -39,8 +39,7 @@
 
 #include <utils/logging_rtt.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 void efr32LogInit(void)
 {
     utilsLogRttInit();
diff --git a/examples/platforms/efr32mg12/misc.c b/examples/platforms/efr32mg12/misc.c
index 23c1510..4b2076f 100644
--- a/examples/platforms/efr32mg12/misc.c
+++ b/examples/platforms/efr32mg12/misc.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/openthread-core-efr32-config-check.h b/examples/platforms/efr32mg12/openthread-core-efr32-config-check.h
index b1ed392..2c722a6 100644
--- a/examples/platforms/efr32mg12/openthread-core-efr32-config-check.h
+++ b/examples/platforms/efr32mg12/openthread-core-efr32-config-check.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2019, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/openthread-core-efr32-config.h b/examples/platforms/efr32mg12/openthread-core-efr32-config.h
index e34b165..d1cbde6 100644
--- a/examples/platforms/efr32mg12/openthread-core-efr32-config.h
+++ b/examples/platforms/efr32mg12/openthread-core-efr32-config.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -80,52 +80,46 @@
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32"
 
 /*
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
  *
  * Define to 1 if you want to enable software energy scanning logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 0
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of settings.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
  *
  */
-#define SETTINGS_CONFIG_BASE_ADDRESS 0
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_SIZE FLASH_PAGE_SIZE
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_NUM 4
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
 
 /**
  * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
diff --git a/examples/platforms/efr32mg12/platform-band.h b/examples/platforms/efr32mg12/platform-band.h
index cba0a64..7c4d912 100644
--- a/examples/platforms/efr32mg12/platform-band.h
+++ b/examples/platforms/efr32mg12/platform-band.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2018, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/platform-efr32.h b/examples/platforms/efr32mg12/platform-efr32.h
index c956fb7..5ec48e2 100644
--- a/examples/platforms/efr32mg12/platform-efr32.h
+++ b/examples/platforms/efr32mg12/platform-efr32.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/radio.c b/examples/platforms/efr32mg12/radio.c
index 57a39d7..764be71 100644
--- a/examples/platforms/efr32mg12/radio.c
+++ b/examples/platforms/efr32mg12/radio.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2019, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -77,6 +77,7 @@
 enum
 {
     EFR32_RECEIVE_SENSITIVITY    = -100, // dBm
+    EFR32_RSSI_AVERAGING_TIME    = 16,   // us
     EFR32_RSSI_AVERAGING_TIMEOUT = 300,  // us
 };
 
@@ -497,7 +498,7 @@
 
     otLogInfoPlat("State=OT_RADIO_STATE_SLEEP", NULL);
 
-    RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true); // abort packages under reception
+    RAIL_Idle(gRailHandle, RAIL_IDLE, true);
     sState = OT_RADIO_STATE_SLEEP;
 
 exit:
@@ -518,7 +519,7 @@
 
     if (sCurrentBandConfig != config)
     {
-        RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
+        RAIL_Idle(gRailHandle, RAIL_IDLE, true);
         efr32RailConfigLoad(config);
         sCurrentBandConfig = config;
     }
@@ -566,7 +567,7 @@
 
     if (sCurrentBandConfig != config)
     {
-        RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
+        RAIL_Idle(gRailHandle, RAIL_IDLE, true);
         efr32RailConfigLoad(config);
         sCurrentBandConfig = config;
     }
@@ -657,19 +658,29 @@
 
 int8_t otPlatRadioGetRssi(otInstance *aInstance)
 {
-    int8_t rssi = OT_RADIO_RSSI_INVALID;
+    otError  error;
+    uint32_t start;
+    int8_t   rssi = OT_RADIO_RSSI_INVALID;
+
     OT_UNUSED_VARIABLE(aInstance);
 
-    if ((RAIL_GetRadioState(gRailHandle) & RAIL_RF_STATE_RX))
+    error = efr32StartEnergyScan(ENERGY_SCAN_MODE_SYNC, sReceiveFrame.mChannel, EFR32_RSSI_AVERAGING_TIME);
+    otEXPECT(error == OT_ERROR_NONE);
+
+    start = RAIL_GetTime();
+
+    // waiting for the event RAIL_EVENT_RSSI_AVERAGE_DONE
+    while (sEnergyScanStatus == ENERGY_SCAN_STATUS_IN_PROGRESS &&
+           ((RAIL_GetTime() - start) < EFR32_RSSI_AVERAGING_TIMEOUT))
+        ;
+
+    if (sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED)
     {
-        int16_t railRssi = RAIL_RSSI_INVALID;
-        railRssi         = RAIL_GetRssi(gRailHandle, true);
-        if (railRssi != RAIL_RSSI_INVALID)
-        {
-            rssi = railRssi / QUARTER_DBM_IN_DBM;
-        }
+        rssi = sEnergyScanResultDbm;
     }
 
+    sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
+exit:
     return rssi;
 }
 
@@ -838,7 +849,7 @@
     }
     else
     {
-        // signal MAC layer for each received frame if promiscous is enabled
+        // signal MAC layer for each received frame if promiscuous is enabled
         // otherwise only signal MAC layer for non-ACK frame
         otEXPECT(sPromiscuous || (length != IEEE802154_ACK_LENGTH));
 
@@ -1059,6 +1070,10 @@
 
 void efr32RadioProcess(otInstance *aInstance)
 {
+    // We should process the received packet first. Adding it at the end of this function,
+    // will delay the stack notification until the next call to efr32RadioProcess()
+    processNextRxPacket(aInstance);
+
     if (sState == OT_RADIO_STATE_TRANSMIT && sTransmitBusy == false)
     {
         if (sTransmitError != OT_ERROR_NONE)
@@ -1099,8 +1114,6 @@
         sRailDebugCounters.mRailEventEnergyScanCompleted++;
 #endif
     }
-
-    processNextRxPacket(aInstance);
 }
 
 otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
diff --git a/examples/platforms/efr32mg12/sleepy-demo/Makefile.am b/examples/platforms/efr32mg12/sleepy-demo/Makefile.am
index e9ff42f..9be5713 100644
--- a/examples/platforms/efr32mg12/sleepy-demo/Makefile.am
+++ b/examples/platforms/efr32mg12/sleepy-demo/Makefile.am
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2019, The OpenThread Authors.
+#  Copyright (c) 2020, The OpenThread Authors.
 #  All rights reserved.
 #
 #  Redistribution and use in source and binary forms, with or without
@@ -44,11 +44,4 @@
 SUBDIRS                                += sleepy-demo-mtd sleepy-demo-ftd
 endif
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    sleepy-demo-mtd                       \
-    sleepy-demo-ftd                       \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/efr32mg12/sleepy-demo/README.md b/examples/platforms/efr32mg12/sleepy-demo/README.md
index b7167c8..f386466 100644
--- a/examples/platforms/efr32mg12/sleepy-demo/README.md
+++ b/examples/platforms/efr32mg12/sleepy-demo/README.md
@@ -1,13 +1,9 @@
-
 # EFR32MG12 Sleepy Demo Example
 
-The EFR32 Sleepy applications demonstrates Sleepy End Device behaviour using
-the EFR32's low power EM2 mode. The steps below will take you through the
-process of building and running the demo
+The EFR32 Sleepy applications demonstrates Sleepy End Device behavior using the EFR32's low power EM2 mode. The steps below will take you through the process of building and running the demo
 
 For setting up the build environment refer to [examples/platforms/efr32mg12/README.md](../README.md).
 
-
 ## 1. Build
 
 ```bash
@@ -24,18 +20,13 @@
 $ arm-none-eabi-objcopy -O srec sleepy-demo-ftd sleepy-demo-ftd.s37
 ```
 
-In Silicon Labs Simplicity Studio flash one device with the sleepy-demo-mtd.s37
-image and the other device with the sleepy-demo-ftd.s37 image.
+In Silicon Labs Simplicity Studio flash one device with the sleepy-demo-mtd.s37 image and the other device with the sleepy-demo-ftd.s37 image.
 
 For instructions on flashing firmware see [examples/platforms/efr32mg12/README.md](../README.md#flash-binaries)
 
-
 ## 2. Starting nodes
 
-For demonstration purposes the network settings are hardcoded within the source files.
-The devices start Thread and form a network within a few seconds of powering on. In a real-life
-application the devices should implement and go through a commissioning process to create
-a network and add devices.
+For demonstration purposes the network settings are hardcoded within the source files. The devices start Thread and form a network within a few seconds of powering on. In a real-life application the devices should implement and go through a commissioning process to create a network and add devices.
 
 When the sleepy-demo-ftd device is started in the CLI the user shall see:
 
@@ -44,8 +35,7 @@
 sleepy-demo-ftd changed to leader
 ```
 
-When the sleepy-demo-mtd device starts it joins the preconfigured Thread network
-before disabling Rx-On-Idle to become a Sleepy-End-Device.
+When the sleepy-demo-mtd device starts it joins the pre-configured Thread network before disabling Rx-On-Idle to become a Sleepy-End-Device.
 
 Use the command "child table" in the FTD console and observe the R flag of the child is 0.
 
@@ -58,43 +48,26 @@
 Done
 ```
 
-
 ## 3. Buttons on the MTD
 
-Pressing button 0 on the MTD toggles between operating as a Minimal End Device (MED) and
-a Sleepy End Device (SED) with the RX off when idle.
+Pressing button 0 on the MTD toggles between operating as a Minimal End Device (MED) and a Sleepy End Device (SED) with the RX off when idle.
 
-Pressing button 1 on the MTD sends a multicast UDP message containing the
-string "mtd button".  The FTD listens on the multicast address and will toggle
-LED 0 and display a message in the CLI showing "Message Received: mtd button".
+Pressing button 1 on the MTD sends a multicast UDP message containing the string "mtd button". The FTD listens on the multicast address and will toggle LED 0 and display a message in the CLI showing "Message Received: mtd button".
 
 ## 4. Buttons on the FTD
 
-Pressing either button 0 or 1 on the FTD will send a UDP message to the FTD containing the string
-"ftd button". The MTD must first send a multicast message by pressing the MTD's button 1 so that
-the FTD knows the address of the MTD to send messages to.
+Pressing either button 0 or 1 on the FTD will send a UDP message to the FTD containing the string "ftd button". The MTD must first send a multicast message by pressing the MTD's button 1 so that the FTD knows the address of the MTD to send messages to.
 
-This will toggle the state of LED0 on the MTD.  If the MTD is operating as a sleepy end device then
-the MTD polls the parent every 5 seconds for messages and will update the LED state on the
-next poll.
+This will toggle the state of LED0 on the MTD. If the MTD is operating as a sleepy end device then the MTD polls the parent every 5 seconds for messages and will update the LED state on the next poll.
 
 ## 5. Monitoring power consumption of the MTD
 
-Open the Energy Profiler within Silicon Labs Simplicity Studio.  Within the Quick Access menu
-select Start Energy Capture... and select the MTD device.  When operating as a Sleepy End Device
-with no LEDs on the current should be under 20 microamps with occassional spikes during waking
-and polling the parent.  With the LED on the MTD has a current consumption of approximately 1mA.
+Open the Energy Profiler within Silicon Labs Simplicity Studio. Within the Quick Access menu select Start Energy Capture... and select the MTD device. When operating as a Sleepy End Device with no LEDs on the current should be under 20 microamps with occasional spikes during waking and polling the parent. With the LED on the MTD has a current consumption of approximately 1mA.
 
-When operating as a Minial End Device with the Rx on Idle observe that the current is in the order
-of 10ma.
+When operating as a Minimal End Device with the Rx on Idle observe that the current is in the order of 10ma.
 
-With further configuration of GPIOs and peripherals it is possible to reduce the sleepy current
-consumption further.
+With further configuration of GPIOs and peripherals it is possible to reduce the sleepy current consumption further.
 
 ## 6. Notes on sleeping, sleepy callback and interrupts
 
-To allow the EFR32 to enter sleepy mode the application must register a callback with efr32SetSleepCallback.
-The return value of callback is used to indicate that the application has no further work to do and that
-it is safe to go into a low power mode.  The callback is called with interrupts disabled so should do
-the minimum required to check if it can sleep.
-
+To allow the EFR32 to enter sleepy mode the application must register a callback with efr32SetSleepCallback. The return value of callback is used to indicate that the application has no further work to do and that it is safe to go into a low power mode. The callback is called with interrupts disabled so should do the minimum required to check if it can sleep.
diff --git a/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/Makefile.am b/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/Makefile.am
index 91df591..2443898 100644
--- a/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/Makefile.am
+++ b/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/Makefile.am
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2019, The OpenThread Authors.
+#  Copyright (c) 2020, The OpenThread Authors.
 #  All rights reserved.
 #
 #  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/main.c b/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/main.c
index d6d7758..7a489b1 100644
--- a/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/main.c
+++ b/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/main.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2019, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -237,10 +237,10 @@
         return;
     }
 
-    error = otUdpBind(&sFtdSocket, &sockaddr);
+    error = otUdpBind(instance, &sFtdSocket, &sockaddr);
     if (error != OT_ERROR_NONE)
     {
-        otUdpClose(&sFtdSocket);
+        otUdpClose(instance, &sFtdSocket);
         otCliOutputFormat("FTD failed to bind udp multicast\r\n");
         return;
     }
@@ -277,7 +277,7 @@
 
                 if (error == OT_ERROR_NONE)
                 {
-                    error = otUdpSend(&sFtdSocket, message, &messageInfo);
+                    error = otUdpSend(instance, &sFtdSocket, message, &messageInfo);
 
                     if (error == OT_ERROR_NONE)
                     {
diff --git a/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/Makefile.am b/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/Makefile.am
index a3b7585..c72759b 100644
--- a/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/Makefile.am
+++ b/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/Makefile.am
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2019, The OpenThread Authors.
+#  Copyright (c) 2020, The OpenThread Authors.
 #  All rights reserved.
 #
 #  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/main.c b/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/main.c
index 26ef873..b1d34a3 100644
--- a/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/main.c
+++ b/examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/main.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2019, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -277,11 +277,11 @@
         return;
     }
 
-    error = otUdpBind(&sMtdSocket, &sockaddr);
+    error = otUdpBind(instance, &sMtdSocket, &sockaddr);
 
     if (error != OT_ERROR_NONE)
     {
-        otUdpClose(&sMtdSocket);
+        otUdpClose(instance, &sMtdSocket);
         return;
     }
 }
@@ -333,7 +333,7 @@
 
             if (error == OT_ERROR_NONE)
             {
-                error = otUdpSend(&sMtdSocket, message, &messageInfo);
+                error = otUdpSend(instance, &sMtdSocket, message, &messageInfo);
 
                 if (error == OT_ERROR_NONE)
                 {
diff --git a/examples/platforms/efr32mg12/startup-gcc.c b/examples/platforms/efr32mg12/startup-gcc.c
index 611d441..85c9e2a 100644
--- a/examples/platforms/efr32mg12/startup-gcc.c
+++ b/examples/platforms/efr32mg12/startup-gcc.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg12/system.c b/examples/platforms/efr32mg12/system.c
index 73e4aca..7b1aa3c 100644
--- a/examples/platforms/efr32mg12/system.c
+++ b/examples/platforms/efr32mg12/system.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -59,9 +59,7 @@
 #include "fem-control.h"
 #endif
 
-#define USE_EFR32_LOG                                                                   \
-    ((OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-     (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL))
+#define USE_EFR32_LOG (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 
 void halInitChipSpecific(void);
 
@@ -91,7 +89,6 @@
     CMU_ClockSelectSet(cmuClock_LFE, cmuSelect_LFRCO);
     CMU_ClockEnable(cmuClock_CORELE, true);
     CMU_ClockEnable(cmuClock_RTCC, true);
-
     status = sl_sleeptimer_init();
     assert(status == SL_STATUS_OK);
 
diff --git a/examples/platforms/efr32mg12/uart.c b/examples/platforms/efr32mg12/uart.c
index e81ebf0..f93f75f 100644
--- a/examples/platforms/efr32mg12/uart.c
+++ b/examples/platforms/efr32mg12/uart.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
diff --git a/examples/platforms/efr32mg13/Makefile.am b/examples/platforms/efr32mg13/Makefile.am
index d019a34..2a54b24 100644
--- a/examples/platforms/efr32mg13/Makefile.am
+++ b/examples/platforms/efr32mg13/Makefile.am
@@ -76,6 +76,8 @@
     -I$(SDK_SRC_DIR)/platform/emdrv/ustimer/inc                                 \
     -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/inc                                  \
     -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/config                               \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/inc                                    \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/config                                 \
     -I$(SDK_SRC_DIR)/platform/emlib/inc                                         \
     -I$(SDK_SRC_DIR)/platform/halconfig/inc/hal-config                          \
     -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32                         \
@@ -123,10 +125,6 @@
     $(PLATFORM_SOURCES)                                                         \
     $(NULL)
 
-PRETTY_FILES                                                                  = \
-    $(PLATFORM_SOURCES)                                                         \
-    $(NULL)
-
 Dash = -
 libopenthread_efr32mg13_a_LIBADD                                                                     = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")             \
@@ -135,13 +133,9 @@
 DIST_SUBDIRS                                                                  = \
     sleepy-demo                                                                 \
     $(NULL)
-    
+
 SUBDIRS                                                                       = \
     sleepy-demo                                                                 \
     $(NULL)
 
-PRETTY_SUBDIRS                                                                = \
-    sleepy-demo                                                                 \
-    $(NULL)
-    
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/efr32mg13/Makefile.platform.am b/examples/platforms/efr32mg13/Makefile.platform.am
index c65e045..5addd35 100644
--- a/examples/platforms/efr32mg13/Makefile.platform.am
+++ b/examples/platforms/efr32mg13/Makefile.platform.am
@@ -41,8 +41,9 @@
     $(top_builddir)/examples/platforms/efr32mg13/libopenthread-efr32mg13.a       \
     $(top_builddir)/third_party/silabs/libsilabs-efr32mg13-sdk.a                 \
     $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/radio/rail_lib/autogen/librail_release/$(LIBRAIL) \
+    $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \
     $(NULL)
 
 LDFLAGS_COMMON                                                                += \
-    -T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/Device/SiliconLabs/EFR32MG13P/Source/GCC/efr32mg13p.ld \
+    -T $(top_srcdir)/examples/platforms/efr32mg13/efr32mg13.ld                   \
     $(NULL)
diff --git a/examples/platforms/efr32mg13/README.md b/examples/platforms/efr32mg13/README.md
index 9c756ea..710b828 100644
--- a/examples/platforms/efr32mg13/README.md
+++ b/examples/platforms/efr32mg13/README.md
@@ -1,19 +1,13 @@
 # OpenThread on EFR32MG13 Example
 
-This directory contains example platform drivers for the [Silicon Labs EFR32MG13][efr32mg13]
-based on [EFR32™ Mighty Gecko Wireless Starter Kit][SLWSTK6000B].
+This directory contains example platform drivers for the [Silicon Labs EFR32MG13][efr32mg13] based on [EFR32™ Mighty Gecko Wireless Starter Kit][slwstk6000b].
 
 [efr32mg]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc
-[SLWSTK6000B]: http://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit
+[slwstk6000b]: http://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit
 
-The example platform drivers are intended to present the minimal code
-necessary to support OpenThread. [EFR32MG13P SoC][efr32mg13p]
-has rich memory and peripheral resources which can support all OpenThread
-capabilities. See the "Run the example with EFR32MG13 boards" section below
-for an example using basic OpenThread capabilities.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. [EFR32MG13P SoC][efr32mg13p] has rich memory and peripheral resources which can support all OpenThread capabilities. See the "Run the example with EFR32MG13 boards" section below for an example using basic OpenThread capabilities.
 
-See [sleepy-demo/README.md](sleepy-demo/README.md) for instructions for an example that uses the low-energy
-modes of the EFR32MG13 when running as a Sleepy End Device.
+See [sleepy-demo/README.md](sleepy-demo/README.md) for instructions for an example that uses the low-energy modes of the EFR32MG13 when running as a Sleepy End Device.
 
 [efr32mg13p]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc/device.EFR32MG13P432F1024GL125
 
@@ -23,8 +17,7 @@
 
 [gnu-toolchain]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -42,15 +35,13 @@
    - Find Flex SDK v2.7 in the Software Update page and click Install.
    - Flex SDK v2.7 will be installed in the path: `/SimplicityStudio_v4/developer/sdks/gecko_sdk_suite`.
 
-For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32)
-portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the 
-Wireless Gecko (EFR32™) Portfolio][QSG138]. For more information
-on RAIL, see [Radio Abstraction Interface Layer][rail].
+For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32) portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the Wireless Gecko (EFR32™) Portfolio][qsg138]. For more information on RAIL, see [Radio Abstraction Interface Layer][rail].
 
-[QSG138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
+[qsg138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
 [rail]: http://www.silabs.com/products/development-tools/software/radio-abstraction-interface-layer-sdk
 
 3. Configure the path to Flex SDK source code.
+
 ```bash
 $ cd <path-to-openthread>/third_party
 $ mkdir silabs
@@ -59,6 +50,7 @@
 ```
 
 Alternatively create a symbolic link to the Flex SDK source code.
+
 ```bash
 $ cd <path-to-openthread>/third_party
 $ mkdir silabs
@@ -66,22 +58,23 @@
 ```
 
 4. Build OpenThread Firmware (CLI example) on EFR32 platform.
+
 ```bash
 $ cd <path-to-openthread>
 $ ./bootstrap
 ```
+
 For EFR32MG13™ Mighty Gecko Wireless Starter Kit:
+
 ```bash
 $ make -f examples/Makefile-efr32mg13 BOARD=BRD4168A
 ```
 
-After a successful build, the `elf` files are found in
-`<path-to-openthread>/output/efr32mg13/bin`.
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/efr32mg13/bin`.
 
 ## Flash Binaries
 
-Compiled binaries may be flashed onto the EFR32 using [JLinkGDBServer][jlinkgdbserver].
-EFR32 Starter kit mainboard integrates an on-board SEGGER J-Link debugger.
+Compiled binaries may be flashed onto the EFR32 using [JLinkGDBServer][jlinkgdbserver]. EFR32 Starter kit mainboard integrates an on-board SEGGER J-Link debugger.
 
 [jlinkgdbserver]: https://www.segger.com/jlink-gdb-server.html
 
@@ -98,8 +91,7 @@
 
 Note: Support for the "EFR32MG13PxxxF1024" device was added to JLinkGDBServer V6.14d.
 
-Or 
-Compiled binaries also may be flashed onto the specified EFR32 dev board using [J-Link Commander][j-link-commander].
+Or Compiled binaries also may be flashed onto the specified EFR32 dev board using [J-Link Commander][j-link-commander].
 
 [j-link-commander]: https://www.segger.com/products/debug-probes/j-link/tools/j-link-commander/
 
@@ -126,16 +118,12 @@
 $ <path-to-simplicity-studio>/developer/adapter_packs/commander/commander
 ```
 
-In the J-Link Device drop-down list select the serial number of the device to flash.  Click the Adapter Connect button.
-Esnure the Debug Interface drop-down list is set to SWD and click the Target Connect button.
-Click on the Flash icon on the left side of the window to switch to the flash page.
-In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button.
-Click the Flash button located under the Browse... button.
+In the J-Link Device drop-down list select the serial number of the device to flash. Click the Adapter Connect button. Ensure the Debug Interface drop-down list is set to SWD and click the Target Connect button. Click on the Flash icon on the left side of the window to switch to the flash page. In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button. Click the Flash button located under the Browse... button.
 
 ## Run the example with EFR32MG13 boards
+
 1. Flash two EFR32 boards with the `CLI example` firmware (as shown above).
-2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1).
-   Type `help` for a list of commands.
+2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1). Type `help` for a list of commands.
 
    ```bash
    > help
@@ -198,8 +186,7 @@
    Done
    ```
 
-4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1)
-   and attach it to the Thread network as a Router.
+4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1) and attach it to the Thread network as a Router.
 
    ```bash
    > dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
@@ -238,8 +225,7 @@
    16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
    ```
 
-The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner,
-joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
+The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner, joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
 
 ```bash
 $ cd <path-to-openthread>
@@ -247,14 +233,16 @@
 $ make -f examples/Makefile-efr32mg13 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1
 ```
 
-For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
 
-[CLI]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
+[cli]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
 
 ## Verification
 
 The following toolchain has been used for testing and verification:
-   - gcc version 7.3.1
+
+- gcc version 7.3.1
 
 The EFR32 example has been verified with following Flex SDK/RAIL Library version:
-   - Flex SDK version 2.7.0.0
+
+- Flex SDK version 2.7.0.0
diff --git a/examples/platforms/efr32mg13/brd4168a/board_config.h b/examples/platforms/efr32mg13/brd4168a/board_config.h
index 6cac36d..8d1a1ec 100644
--- a/examples/platforms/efr32mg13/brd4168a/board_config.h
+++ b/examples/platforms/efr32mg13/brd4168a/board_config.h
@@ -35,14 +35,18 @@
 #ifndef __BOARD_CONFIG_H__
 #define __BOARD_CONFIG_H__
 
-#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1   /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 0 /// Dev board doesn't support OQPSK modulation in 915MHz band.
 
 #ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
 #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
 #endif
 
 #ifndef RADIO_CONFIG_DMP_SUPPORT
-#define RADIO_CONFIG_DMP_SUPPORT 0            /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
+#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
+
+#define RADIO_CONFIG_PA_USES_DCDC 0 /// The PA(s) is(are) fed from VBAT
+
 #endif
 
 #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg13/brd4168a/hal-config.h b/examples/platforms/efr32mg13/brd4168a/hal-config.h
index d1b4be9..e9ce347 100644
--- a/examples/platforms/efr32mg13/brd4168a/hal-config.h
+++ b/examples/platforms/efr32mg13/brd4168a/hal-config.h
@@ -26,8 +26,8 @@
 
 // $[BTL_BUTTON]
 
-#define BSP_BTL_BUTTON_PIN                            (6U)
-#define BSP_BTL_BUTTON_PORT                           (gpioPortF)
+#define BSP_BTL_BUTTON_PIN (6U)
+#define BSP_BTL_BUTTON_PORT (gpioPortF)
 
 // [BTL_BUTTON]$
 
@@ -38,33 +38,36 @@
 // [BULBPWM_COLOR]$
 
 // $[BUTTON]
-#define BSP_BUTTON_PRESENT                            (1)
+#define BSP_BUTTON_PRESENT (1)
 
-#define BSP_BUTTON0_PIN                               (6U)
-#define BSP_BUTTON0_PORT                              (gpioPortF)
+#define BSP_BUTTON0_PIN (6U)
+#define BSP_BUTTON0_PORT (gpioPortF)
 
-#define BSP_BUTTON1_PIN                               (7U)
-#define BSP_BUTTON1_PORT                              (gpioPortF)
+#define BSP_BUTTON1_PIN (7U)
+#define BSP_BUTTON1_PORT (gpioPortF)
 
-#define BSP_BUTTON_COUNT                              (2U)
-#define BSP_BUTTON_INIT                               { { BSP_BUTTON0_PORT, BSP_BUTTON0_PIN }, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } }
-#define BSP_BUTTON_GPIO_DOUT                          (HAL_GPIO_DOUT_LOW)
-#define BSP_BUTTON_GPIO_MODE                          (HAL_GPIO_MODE_INPUT)
+#define BSP_BUTTON_COUNT (2U)
+#define BSP_BUTTON_INIT                                                            \
+    {                                                                              \
+        {BSP_BUTTON0_PORT, BSP_BUTTON0_PIN}, { BSP_BUTTON1_PORT, BSP_BUTTON1_PIN } \
+    }
+#define BSP_BUTTON_GPIO_DOUT (HAL_GPIO_DOUT_LOW)
+#define BSP_BUTTON_GPIO_MODE (HAL_GPIO_MODE_INPUT)
 // [BUTTON]$
 
 // $[CMU]
-#define HAL_CLK_HFCLK_SOURCE                          (HAL_CLK_HFCLK_SOURCE_HFXO)
-#define HAL_CLK_LFECLK_SOURCE                         (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define HAL_CLK_LFBCLK_SOURCE                         (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
+#define HAL_CLK_LFECLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define HAL_CLK_LFBCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
 
-#define BSP_CLK_HFXO_PRESENT                          (1)
-#define BSP_CLK_HFXO_FREQ                             (38400000UL)
-#define BSP_CLK_HFXO_INIT                              CMU_HFXOINIT_DEFAULT
-#define BSP_CLK_HFXO_CTUNE                            (330)
-#define BSP_CLK_LFXO_PRESENT                          (1)
-#define BSP_CLK_LFXO_INIT                              CMU_LFXOINIT_DEFAULT
-#define BSP_CLK_LFXO_FREQ                             (32768U)
-#define BSP_CLK_LFXO_CTUNE                            (32U)
+#define BSP_CLK_HFXO_PRESENT (1)
+#define BSP_CLK_HFXO_FREQ (38400000UL)
+#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
+#define BSP_CLK_HFXO_CTUNE (330)
+#define BSP_CLK_LFXO_PRESENT (1)
+#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
+#define BSP_CLK_LFXO_FREQ (32768U)
+#define BSP_CLK_LFXO_CTUNE (32U)
 // [CMU]$
 
 // $[COEX]
@@ -77,31 +80,31 @@
 // [CSEN]$
 
 // $[DCDC]
-#define BSP_DCDC_PRESENT                              (1)
+#define BSP_DCDC_PRESENT (1)
 
-#define BSP_DCDC_INIT                                  EMU_DCDCINIT_DEFAULT
+#define BSP_DCDC_INIT EMU_DCDCINIT_DEFAULT
 // [DCDC]$
 
 // $[EMU]
 // [EMU]$
 
 // $[EXTFLASH]
-#define BSP_EXTFLASH_CS_PIN                           (4U)
-#define BSP_EXTFLASH_CS_PORT                          (gpioPortA)
+#define BSP_EXTFLASH_CS_PIN (4U)
+#define BSP_EXTFLASH_CS_PORT (gpioPortA)
 
-#define BSP_EXTFLASH_INTERNAL                         (0)
-#define BSP_EXTFLASH_USART                            (HAL_SPI_PORT_USART1)
-#define BSP_EXTFLASH_MOSI_PIN                         (6U)
-#define BSP_EXTFLASH_MOSI_PORT                        (gpioPortC)
-#define BSP_EXTFLASH_MOSI_LOC                         (11U)
+#define BSP_EXTFLASH_INTERNAL (0)
+#define BSP_EXTFLASH_USART (HAL_SPI_PORT_USART1)
+#define BSP_EXTFLASH_MOSI_PIN (6U)
+#define BSP_EXTFLASH_MOSI_PORT (gpioPortC)
+#define BSP_EXTFLASH_MOSI_LOC (11U)
 
-#define BSP_EXTFLASH_MISO_PIN                         (7U)
-#define BSP_EXTFLASH_MISO_PORT                        (gpioPortC)
-#define BSP_EXTFLASH_MISO_LOC                         (11U)
+#define BSP_EXTFLASH_MISO_PIN (7U)
+#define BSP_EXTFLASH_MISO_PORT (gpioPortC)
+#define BSP_EXTFLASH_MISO_LOC (11U)
 
-#define BSP_EXTFLASH_CLK_PIN                          (8U)
-#define BSP_EXTFLASH_CLK_PORT                         (gpioPortC)
-#define BSP_EXTFLASH_CLK_LOC                          (11U)
+#define BSP_EXTFLASH_CLK_PIN (8U)
+#define BSP_EXTFLASH_CLK_PORT (gpioPortC)
+#define BSP_EXTFLASH_CLK_LOC (11U)
 
 // [EXTFLASH]$
 
@@ -112,32 +115,32 @@
 // [FEM]$
 
 // $[GPIO]
-#define PORTIO_GPIO_SWV_PIN                           (2U)
-#define PORTIO_GPIO_SWV_PORT                          (gpioPortF)
-#define PORTIO_GPIO_SWV_LOC                           (0U)
+#define PORTIO_GPIO_SWV_PIN (2U)
+#define PORTIO_GPIO_SWV_PORT (gpioPortF)
+#define PORTIO_GPIO_SWV_LOC (0U)
 
-#define BSP_TRACE_SWO_PIN                             (2U)
-#define BSP_TRACE_SWO_PORT                            (gpioPortF)
-#define BSP_TRACE_SWO_LOC                             (0U)
+#define BSP_TRACE_SWO_PIN (2U)
+#define BSP_TRACE_SWO_PORT (gpioPortF)
+#define BSP_TRACE_SWO_LOC (0U)
 
 // [GPIO]$
 
 // $[I2C0]
-#define PORTIO_I2C0_SCL_PIN                           (10U)
-#define PORTIO_I2C0_SCL_PORT                          (gpioPortC)
-#define PORTIO_I2C0_SCL_LOC                           (14U)
+#define PORTIO_I2C0_SCL_PIN (10U)
+#define PORTIO_I2C0_SCL_PORT (gpioPortC)
+#define PORTIO_I2C0_SCL_LOC (14U)
 
-#define PORTIO_I2C0_SDA_PIN                           (11U)
-#define PORTIO_I2C0_SDA_PORT                          (gpioPortC)
-#define PORTIO_I2C0_SDA_LOC                           (16U)
+#define PORTIO_I2C0_SDA_PIN (11U)
+#define PORTIO_I2C0_SDA_PORT (gpioPortC)
+#define PORTIO_I2C0_SDA_LOC (16U)
 
-#define BSP_I2C0_SCL_PIN                              (10U)
-#define BSP_I2C0_SCL_PORT                             (gpioPortC)
-#define BSP_I2C0_SCL_LOC                              (14U)
+#define BSP_I2C0_SCL_PIN (10U)
+#define BSP_I2C0_SCL_PORT (gpioPortC)
+#define BSP_I2C0_SCL_LOC (14U)
 
-#define BSP_I2C0_SDA_PIN                              (11U)
-#define BSP_I2C0_SDA_PORT                             (gpioPortC)
-#define BSP_I2C0_SDA_LOC                              (16U)
+#define BSP_I2C0_SDA_PIN (11U)
+#define BSP_I2C0_SDA_PORT (gpioPortC)
+#define BSP_I2C0_SDA_LOC (16U)
 
 // [I2C0]$
 
@@ -146,17 +149,17 @@
 
 // $[I2CSENSOR]
 
-#define BSP_I2CSENSOR_ENABLE_PIN                      (15U)
-#define BSP_I2CSENSOR_ENABLE_PORT                     (gpioPortD)
+#define BSP_I2CSENSOR_ENABLE_PIN (15U)
+#define BSP_I2CSENSOR_ENABLE_PORT (gpioPortD)
 
-#define BSP_I2CSENSOR_PERIPHERAL                      (HAL_I2C_PORT_I2C0)
-#define BSP_I2CSENSOR_SCL_PIN                         (10U)
-#define BSP_I2CSENSOR_SCL_PORT                        (gpioPortC)
-#define BSP_I2CSENSOR_SCL_LOC                         (14U)
+#define BSP_I2CSENSOR_PERIPHERAL (HAL_I2C_PORT_I2C0)
+#define BSP_I2CSENSOR_SCL_PIN (10U)
+#define BSP_I2CSENSOR_SCL_PORT (gpioPortC)
+#define BSP_I2CSENSOR_SCL_LOC (14U)
 
-#define BSP_I2CSENSOR_SDA_PIN                         (11U)
-#define BSP_I2CSENSOR_SDA_PORT                        (gpioPortC)
-#define BSP_I2CSENSOR_SDA_LOC                         (16U)
+#define BSP_I2CSENSOR_SDA_PIN (11U)
+#define BSP_I2CSENSOR_SDA_PORT (gpioPortC)
+#define BSP_I2CSENSOR_SDA_LOC (16U)
 
 // [I2CSENSOR]$
 
@@ -167,17 +170,20 @@
 // [IOEXP]$
 
 // $[LED]
-#define BSP_LED_PRESENT                               (1)
+#define BSP_LED_PRESENT (1)
 
-#define BSP_LED0_PIN                                  (4U)
-#define BSP_LED0_PORT                                 (gpioPortF)
+#define BSP_LED0_PIN (4U)
+#define BSP_LED0_PORT (gpioPortF)
 
-#define BSP_LED1_PIN                                  (5U)
-#define BSP_LED1_PORT                                 (gpioPortF)
+#define BSP_LED1_PIN (5U)
+#define BSP_LED1_PORT (gpioPortF)
 
-#define BSP_LED_COUNT                                 (2U)
-#define BSP_LED_INIT                                  { { BSP_LED0_PORT, BSP_LED0_PIN }, { BSP_LED1_PORT, BSP_LED1_PIN } }
-#define BSP_LED_POLARITY                              (1)
+#define BSP_LED_COUNT (2U)
+#define BSP_LED_INIT                                                   \
+    {                                                                  \
+        {BSP_LED0_PORT, BSP_LED0_PIN}, { BSP_LED1_PORT, BSP_LED1_PIN } \
+    }
+#define BSP_LED_POLARITY (1)
 // [LED]$
 
 // $[LESENSE]
@@ -197,7 +203,7 @@
 
 // $[PA]
 
-#define BSP_PA_VOLTAGE                                (3300U)
+#define BSP_PA_VOLTAGE (3300U)
 // [PA]$
 
 // $[PCNT0]
@@ -207,32 +213,32 @@
 // [PORTIO]$
 
 // $[PRS]
-#define PORTIO_PRS_CH4_PIN                            (13U)
-#define PORTIO_PRS_CH4_PORT                           (gpioPortD)
-#define PORTIO_PRS_CH4_LOC                            (4U)
+#define PORTIO_PRS_CH4_PIN (13U)
+#define PORTIO_PRS_CH4_PORT (gpioPortD)
+#define PORTIO_PRS_CH4_LOC (4U)
 
 // [PRS]$
 
 // $[PTI]
-#define PORTIO_PTI_DCLK_PIN                           (11U)
-#define PORTIO_PTI_DCLK_PORT                          (gpioPortB)
-#define PORTIO_PTI_DCLK_LOC                           (6U)
+#define PORTIO_PTI_DCLK_PIN (11U)
+#define PORTIO_PTI_DCLK_PORT (gpioPortB)
+#define PORTIO_PTI_DCLK_LOC (6U)
 
-#define PORTIO_PTI_DFRAME_PIN                         (13U)
-#define PORTIO_PTI_DFRAME_PORT                        (gpioPortB)
-#define PORTIO_PTI_DFRAME_LOC                         (6U)
+#define PORTIO_PTI_DFRAME_PIN (13U)
+#define PORTIO_PTI_DFRAME_PORT (gpioPortB)
+#define PORTIO_PTI_DFRAME_LOC (6U)
 
-#define PORTIO_PTI_DOUT_PIN                           (12U)
-#define PORTIO_PTI_DOUT_PORT                          (gpioPortB)
-#define PORTIO_PTI_DOUT_LOC                           (6U)
+#define PORTIO_PTI_DOUT_PIN (12U)
+#define PORTIO_PTI_DOUT_PORT (gpioPortB)
+#define PORTIO_PTI_DOUT_LOC (6U)
 
-#define BSP_PTI_DFRAME_PIN                            (13U)
-#define BSP_PTI_DFRAME_PORT                           (gpioPortB)
-#define BSP_PTI_DFRAME_LOC                            (6U)
+#define BSP_PTI_DFRAME_PIN (13U)
+#define BSP_PTI_DFRAME_PORT (gpioPortB)
+#define BSP_PTI_DFRAME_LOC (6U)
 
-#define BSP_PTI_DOUT_PIN                              (12U)
-#define BSP_PTI_DOUT_PORT                             (gpioPortB)
-#define BSP_PTI_DOUT_LOC                              (6U)
+#define BSP_PTI_DOUT_PIN (12U)
+#define BSP_PTI_DOUT_PORT (gpioPortB)
+#define BSP_PTI_DOUT_LOC (6U)
 
 // [PTI]$
 
@@ -240,83 +246,83 @@
 // [PYD1698]$
 
 // $[SERIAL]
-#define BSP_SERIAL_APP_PORT                           (HAL_SERIAL_PORT_USART0)
-#define BSP_SERIAL_APP_TX_PIN                         (0U)
-#define BSP_SERIAL_APP_TX_PORT                        (gpioPortA)
-#define BSP_SERIAL_APP_TX_LOC                         (0U)
+#define BSP_SERIAL_APP_PORT (HAL_SERIAL_PORT_USART0)
+#define BSP_SERIAL_APP_TX_PIN (0U)
+#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_TX_LOC (0U)
 
-#define BSP_SERIAL_APP_RX_PIN                         (1U)
-#define BSP_SERIAL_APP_RX_PORT                        (gpioPortA)
-#define BSP_SERIAL_APP_RX_LOC                         (0U)
+#define BSP_SERIAL_APP_RX_PIN (1U)
+#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RX_LOC (0U)
 
-#define BSP_SERIAL_APP_CTS_PIN                        (2U)
-#define BSP_SERIAL_APP_CTS_PORT                       (gpioPortA)
-#define BSP_SERIAL_APP_CTS_LOC                        (30U)
+#define BSP_SERIAL_APP_CTS_PIN (2U)
+#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_CTS_LOC (30U)
 
-#define BSP_SERIAL_APP_RTS_PIN                        (3U)
-#define BSP_SERIAL_APP_RTS_PORT                       (gpioPortA)
-#define BSP_SERIAL_APP_RTS_LOC                        (30U)
+#define BSP_SERIAL_APP_RTS_PIN (3U)
+#define BSP_SERIAL_APP_RTS_PORT (gpioPortA)
+#define BSP_SERIAL_APP_RTS_LOC (30U)
 
-#define HAL_SERIAL_APP_RX_QUEUE_SIZE                  (128)
-#define HAL_SERIAL_APP_BAUD_RATE                      (115200)
-#define HAL_SERIAL_APP_RXSTOP                         (16)
-#define HAL_SERIAL_APP_RXSTART                        (16)
-#define HAL_SERIAL_APP_TX_QUEUE_SIZE                  (128)
-#define HAL_SERIAL_APP_FLOW_CONTROL                   (HAL_USART_FLOW_CONTROL_HWUART)
+#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128)
+#define HAL_SERIAL_APP_BAUD_RATE (115200)
+#define HAL_SERIAL_APP_RXSTOP (16)
+#define HAL_SERIAL_APP_RXSTART (16)
+#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128)
+#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
 // [SERIAL]$
 
 // $[SPIDISPLAY]
 
-#define BSP_SPIDISPLAY_CS_PIN                         (14U)
-#define BSP_SPIDISPLAY_CS_PORT                        (gpioPortD)
+#define BSP_SPIDISPLAY_CS_PIN (14U)
+#define BSP_SPIDISPLAY_CS_PORT (gpioPortD)
 
-#define BSP_SPIDISPLAY_ENABLE_PIN                     (15U)
-#define BSP_SPIDISPLAY_ENABLE_PORT                    (gpioPortD)
+#define BSP_SPIDISPLAY_ENABLE_PIN (15U)
+#define BSP_SPIDISPLAY_ENABLE_PORT (gpioPortD)
 
-#define BSP_SPIDISPLAY_EXTCOMIN_PIN                   (13U)
-#define BSP_SPIDISPLAY_EXTCOMIN_PORT                  (gpioPortD)
-#define BSP_SPIDISPLAY_EXTCOMIN_LOC                   (4U)
+#define BSP_SPIDISPLAY_EXTCOMIN_PIN (13U)
+#define BSP_SPIDISPLAY_EXTCOMIN_PORT (gpioPortD)
+#define BSP_SPIDISPLAY_EXTCOMIN_LOC (4U)
 
-#define BSP_SPIDISPLAY_DISPLAY                        (HAL_DISPLAY_SHARP_LS013B7DH03)
-#define BSP_SPIDISPLAY_USART                          (HAL_SPI_PORT_USART1)
-#define BSP_SPIDISPLAY_EXTCOMIN_CHANNEL               (4)
-#define BSP_SPIDISPLAY_MOSI_PIN                       (6U)
-#define BSP_SPIDISPLAY_MOSI_PORT                      (gpioPortC)
-#define BSP_SPIDISPLAY_MOSI_LOC                       (11U)
+#define BSP_SPIDISPLAY_DISPLAY (HAL_DISPLAY_SHARP_LS013B7DH03)
+#define BSP_SPIDISPLAY_USART (HAL_SPI_PORT_USART1)
+#define BSP_SPIDISPLAY_EXTCOMIN_CHANNEL (4)
+#define BSP_SPIDISPLAY_MOSI_PIN (6U)
+#define BSP_SPIDISPLAY_MOSI_PORT (gpioPortC)
+#define BSP_SPIDISPLAY_MOSI_LOC (11U)
 
-#define BSP_SPIDISPLAY_MISO_PIN                       (7U)
-#define BSP_SPIDISPLAY_MISO_PORT                      (gpioPortC)
-#define BSP_SPIDISPLAY_MISO_LOC                       (11U)
+#define BSP_SPIDISPLAY_MISO_PIN (7U)
+#define BSP_SPIDISPLAY_MISO_PORT (gpioPortC)
+#define BSP_SPIDISPLAY_MISO_LOC (11U)
 
-#define BSP_SPIDISPLAY_CLK_PIN                        (8U)
-#define BSP_SPIDISPLAY_CLK_PORT                       (gpioPortC)
-#define BSP_SPIDISPLAY_CLK_LOC                        (11U)
+#define BSP_SPIDISPLAY_CLK_PIN (8U)
+#define BSP_SPIDISPLAY_CLK_PORT (gpioPortC)
+#define BSP_SPIDISPLAY_CLK_LOC (11U)
 
 // [SPIDISPLAY]$
 
 // $[SPINCP]
-#define BSP_SPINCP_NHOSTINT_PIN                       (6U)
-#define BSP_SPINCP_NHOSTINT_PORT                      (gpioPortF)
+#define BSP_SPINCP_NHOSTINT_PIN (6U)
+#define BSP_SPINCP_NHOSTINT_PORT (gpioPortF)
 
-#define BSP_SPINCP_NWAKE_PIN                          (7U)
-#define BSP_SPINCP_NWAKE_PORT                         (gpioPortF)
+#define BSP_SPINCP_NWAKE_PIN (7U)
+#define BSP_SPINCP_NWAKE_PORT (gpioPortF)
 
-#define BSP_SPINCP_USART_PORT                         (HAL_SPI_PORT_USART1)
-#define BSP_SPINCP_MOSI_PIN                           (6U)
-#define BSP_SPINCP_MOSI_PORT                          (gpioPortC)
-#define BSP_SPINCP_MOSI_LOC                           (11U)
+#define BSP_SPINCP_USART_PORT (HAL_SPI_PORT_USART1)
+#define BSP_SPINCP_MOSI_PIN (6U)
+#define BSP_SPINCP_MOSI_PORT (gpioPortC)
+#define BSP_SPINCP_MOSI_LOC (11U)
 
-#define BSP_SPINCP_MISO_PIN                           (7U)
-#define BSP_SPINCP_MISO_PORT                          (gpioPortC)
-#define BSP_SPINCP_MISO_LOC                           (11U)
+#define BSP_SPINCP_MISO_PIN (7U)
+#define BSP_SPINCP_MISO_PORT (gpioPortC)
+#define BSP_SPINCP_MISO_LOC (11U)
 
-#define BSP_SPINCP_CLK_PIN                            (8U)
-#define BSP_SPINCP_CLK_PORT                           (gpioPortC)
-#define BSP_SPINCP_CLK_LOC                            (11U)
+#define BSP_SPINCP_CLK_PIN (8U)
+#define BSP_SPINCP_CLK_PORT (gpioPortC)
+#define BSP_SPINCP_CLK_LOC (11U)
 
-#define BSP_SPINCP_CS_PIN                             (9U)
-#define BSP_SPINCP_CS_PORT                            (gpioPortC)
-#define BSP_SPINCP_CS_LOC                             (11U)
+#define BSP_SPINCP_CS_PIN (9U)
+#define BSP_SPINCP_CS_PORT (gpioPortC)
+#define BSP_SPINCP_CS_LOC (11U)
 
 // [SPINCP]$
 
@@ -327,92 +333,92 @@
 // [TIMER1]$
 
 // $[UARTNCP]
-#define BSP_UARTNCP_USART_PORT                        (HAL_SERIAL_PORT_USART0)
-#define BSP_UARTNCP_TX_PIN                            (0U)
-#define BSP_UARTNCP_TX_PORT                           (gpioPortA)
-#define BSP_UARTNCP_TX_LOC                            (0U)
+#define BSP_UARTNCP_USART_PORT (HAL_SERIAL_PORT_USART0)
+#define BSP_UARTNCP_TX_PIN (0U)
+#define BSP_UARTNCP_TX_PORT (gpioPortA)
+#define BSP_UARTNCP_TX_LOC (0U)
 
-#define BSP_UARTNCP_RX_PIN                            (1U)
-#define BSP_UARTNCP_RX_PORT                           (gpioPortA)
-#define BSP_UARTNCP_RX_LOC                            (0U)
+#define BSP_UARTNCP_RX_PIN (1U)
+#define BSP_UARTNCP_RX_PORT (gpioPortA)
+#define BSP_UARTNCP_RX_LOC (0U)
 
-#define BSP_UARTNCP_CTS_PIN                           (2U)
-#define BSP_UARTNCP_CTS_PORT                          (gpioPortA)
-#define BSP_UARTNCP_CTS_LOC                           (30U)
+#define BSP_UARTNCP_CTS_PIN (2U)
+#define BSP_UARTNCP_CTS_PORT (gpioPortA)
+#define BSP_UARTNCP_CTS_LOC (30U)
 
-#define BSP_UARTNCP_RTS_PIN                           (3U)
-#define BSP_UARTNCP_RTS_PORT                          (gpioPortA)
-#define BSP_UARTNCP_RTS_LOC                           (30U)
+#define BSP_UARTNCP_RTS_PIN (3U)
+#define BSP_UARTNCP_RTS_PORT (gpioPortA)
+#define BSP_UARTNCP_RTS_LOC (30U)
 
 // [UARTNCP]$
 
 // $[USART0]
-#define PORTIO_USART0_CTS_PIN                         (2U)
-#define PORTIO_USART0_CTS_PORT                        (gpioPortA)
-#define PORTIO_USART0_CTS_LOC                         (30U)
+#define PORTIO_USART0_CTS_PIN (2U)
+#define PORTIO_USART0_CTS_PORT (gpioPortA)
+#define PORTIO_USART0_CTS_LOC (30U)
 
-#define PORTIO_USART0_RTS_PIN                         (3U)
-#define PORTIO_USART0_RTS_PORT                        (gpioPortA)
-#define PORTIO_USART0_RTS_LOC                         (30U)
+#define PORTIO_USART0_RTS_PIN (3U)
+#define PORTIO_USART0_RTS_PORT (gpioPortA)
+#define PORTIO_USART0_RTS_LOC (30U)
 
-#define PORTIO_USART0_RX_PIN                          (1U)
-#define PORTIO_USART0_RX_PORT                         (gpioPortA)
-#define PORTIO_USART0_RX_LOC                          (0U)
+#define PORTIO_USART0_RX_PIN (1U)
+#define PORTIO_USART0_RX_PORT (gpioPortA)
+#define PORTIO_USART0_RX_LOC (0U)
 
-#define PORTIO_USART0_TX_PIN                          (0U)
-#define PORTIO_USART0_TX_PORT                         (gpioPortA)
-#define PORTIO_USART0_TX_LOC                          (0U)
+#define PORTIO_USART0_TX_PIN (0U)
+#define PORTIO_USART0_TX_PORT (gpioPortA)
+#define PORTIO_USART0_TX_LOC (0U)
 
-#define BSP_USART0_TX_PIN                             (0U)
-#define BSP_USART0_TX_PORT                            (gpioPortA)
-#define BSP_USART0_TX_LOC                             (0U)
+#define BSP_USART0_TX_PIN (0U)
+#define BSP_USART0_TX_PORT (gpioPortA)
+#define BSP_USART0_TX_LOC (0U)
 
-#define BSP_USART0_RX_PIN                             (1U)
-#define BSP_USART0_RX_PORT                            (gpioPortA)
-#define BSP_USART0_RX_LOC                             (0U)
+#define BSP_USART0_RX_PIN (1U)
+#define BSP_USART0_RX_PORT (gpioPortA)
+#define BSP_USART0_RX_LOC (0U)
 
-#define BSP_USART0_CTS_PIN                            (2U)
-#define BSP_USART0_CTS_PORT                           (gpioPortA)
-#define BSP_USART0_CTS_LOC                            (30U)
+#define BSP_USART0_CTS_PIN (2U)
+#define BSP_USART0_CTS_PORT (gpioPortA)
+#define BSP_USART0_CTS_LOC (30U)
 
-#define BSP_USART0_RTS_PIN                            (3U)
-#define BSP_USART0_RTS_PORT                           (gpioPortA)
-#define BSP_USART0_RTS_LOC                            (30U)
+#define BSP_USART0_RTS_PIN (3U)
+#define BSP_USART0_RTS_PORT (gpioPortA)
+#define BSP_USART0_RTS_LOC (30U)
 
 // [USART0]$
 
 // $[USART1]
-#define PORTIO_USART1_CLK_PIN                         (8U)
-#define PORTIO_USART1_CLK_PORT                        (gpioPortC)
-#define PORTIO_USART1_CLK_LOC                         (11U)
+#define PORTIO_USART1_CLK_PIN (8U)
+#define PORTIO_USART1_CLK_PORT (gpioPortC)
+#define PORTIO_USART1_CLK_LOC (11U)
 
-#define PORTIO_USART1_CS_PIN                          (9U)
-#define PORTIO_USART1_CS_PORT                         (gpioPortC)
-#define PORTIO_USART1_CS_LOC                          (11U)
+#define PORTIO_USART1_CS_PIN (9U)
+#define PORTIO_USART1_CS_PORT (gpioPortC)
+#define PORTIO_USART1_CS_LOC (11U)
 
-#define PORTIO_USART1_RX_PIN                          (7U)
-#define PORTIO_USART1_RX_PORT                         (gpioPortC)
-#define PORTIO_USART1_RX_LOC                          (11U)
+#define PORTIO_USART1_RX_PIN (7U)
+#define PORTIO_USART1_RX_PORT (gpioPortC)
+#define PORTIO_USART1_RX_LOC (11U)
 
-#define PORTIO_USART1_TX_PIN                          (6U)
-#define PORTIO_USART1_TX_PORT                         (gpioPortC)
-#define PORTIO_USART1_TX_LOC                          (11U)
+#define PORTIO_USART1_TX_PIN (6U)
+#define PORTIO_USART1_TX_PORT (gpioPortC)
+#define PORTIO_USART1_TX_LOC (11U)
 
-#define BSP_USART1_MOSI_PIN                           (6U)
-#define BSP_USART1_MOSI_PORT                          (gpioPortC)
-#define BSP_USART1_MOSI_LOC                           (11U)
+#define BSP_USART1_MOSI_PIN (6U)
+#define BSP_USART1_MOSI_PORT (gpioPortC)
+#define BSP_USART1_MOSI_LOC (11U)
 
-#define BSP_USART1_MISO_PIN                           (7U)
-#define BSP_USART1_MISO_PORT                          (gpioPortC)
-#define BSP_USART1_MISO_LOC                           (11U)
+#define BSP_USART1_MISO_PIN (7U)
+#define BSP_USART1_MISO_PORT (gpioPortC)
+#define BSP_USART1_MISO_LOC (11U)
 
-#define BSP_USART1_CLK_PIN                            (8U)
-#define BSP_USART1_CLK_PORT                           (gpioPortC)
-#define BSP_USART1_CLK_LOC                            (11U)
+#define BSP_USART1_CLK_PIN (8U)
+#define BSP_USART1_CLK_PORT (gpioPortC)
+#define BSP_USART1_CLK_LOC (11U)
 
-#define BSP_USART1_CS_PIN                             (9U)
-#define BSP_USART1_CS_PORT                            (gpioPortC)
-#define BSP_USART1_CS_LOC                             (11U)
+#define BSP_USART1_CS_PIN (9U)
+#define BSP_USART1_CS_PORT (gpioPortC)
+#define BSP_USART1_CS_LOC (11U)
 
 // [USART1]$
 
@@ -421,8 +427,8 @@
 
 // $[VCOM]
 
-#define BSP_VCOM_ENABLE_PIN                           (5U)
-#define BSP_VCOM_ENABLE_PORT                          (gpioPortA)
+#define BSP_VCOM_ENABLE_PIN (5U)
+#define BSP_VCOM_ENABLE_PORT (gpioPortA)
 
 // [VCOM]$
 
diff --git a/examples/platforms/efr32mg13/crypto/efr32-mbedtls-config.h b/examples/platforms/efr32mg13/crypto/efr32-mbedtls-config.h
index ba70588..14f1d1c 100644
--- a/examples/platforms/efr32mg13/crypto/efr32-mbedtls-config.h
+++ b/examples/platforms/efr32mg13/crypto/efr32-mbedtls-config.h
@@ -25,7 +25,7 @@
  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  *  POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
 #ifndef EFR32_MBEDTLS_CONFIG_H
 #define EFR32_MBEDTLS_CONFIG_H
 
@@ -86,7 +86,7 @@
  * See MBEDTLS_SHA256_C for more information.
  */
 #if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
-//#define MBEDTLS_SHA256_ALT
+#define MBEDTLS_SHA256_ALT
 #endif
 
 #endif // EFR32_MBEDTLS_CONFIG_H
diff --git a/examples/platforms/efr32mg13/diag.c b/examples/platforms/efr32mg13/diag.c
index c28ad6b..a7c3357 100644
--- a/examples/platforms/efr32mg13/diag.c
+++ b/examples/platforms/efr32mg13/diag.c
@@ -51,15 +51,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
-
-    // Add more platform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/efr32mg13/efr32mg13.ld b/examples/platforms/efr32mg13/efr32mg13.ld
new file mode 100644
index 0000000..22be579
--- /dev/null
+++ b/examples/platforms/efr32mg13/efr32mg13.ld
@@ -0,0 +1,246 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**
+ * @file
+ *   This file implements the OpenThread linker script for the
+ *   Silicon Labs efr32mg13 platform.
+ *
+ */
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
+  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 64K
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __copy_table_start__
+ *   __copy_table_end__
+ *   __zero_table_start__
+ *   __zero_table_end__
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __Vectors_End
+ *   __Vectors_Size
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+  .text :
+  {
+    KEEP(*(.vectors))
+    __Vectors_End = .;
+    __Vectors_Size = __Vectors_End - __Vectors;
+    __end__ = .;
+
+    *(.text*)
+
+    KEEP(*(.init))
+    KEEP(*(.fini))
+
+    /* .ctors */
+    *crtbegin.o(.ctors)
+    *crtbegin?.o(.ctors)
+    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+    *(SORT(.ctors.*))
+    *(.ctors)
+
+    /* .dtors */
+    *crtbegin.o(.dtors)
+    *crtbegin?.o(.dtors)
+    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+    *(SORT(.dtors.*))
+    *(.dtors)
+
+    *(.rodata*)
+
+    KEEP(*(.eh_frame*))
+  } > FLASH
+
+  .ARM.extab :
+  {
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+  } > FLASH
+
+  __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } > FLASH
+  __exidx_end = .;
+
+  /* To copy multiple ROM to RAM sections,
+   * uncomment .copy.table section and,
+   * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
+  /*
+  .copy.table :
+  {
+    . = ALIGN(4);
+    __copy_table_start__ = .;
+    LONG (__etext)
+    LONG (__data_start__)
+    LONG (__data_end__ - __data_start__)
+    LONG (__etext2)
+    LONG (__data2_start__)
+    LONG (__data2_end__ - __data2_start__)
+    __copy_table_end__ = .;
+  } > FLASH
+  */
+
+  /* To clear multiple BSS sections,
+   * uncomment .zero.table section and,
+   * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
+  /*
+  .zero.table :
+  {
+    . = ALIGN(4);
+    __zero_table_start__ = .;
+    LONG (__bss_start__)
+    LONG (__bss_end__ - __bss_start__)
+    LONG (__bss2_start__)
+    LONG (__bss2_end__ - __bss2_start__)
+    __zero_table_end__ = .;
+  } > FLASH
+  */
+
+  __etext = .;
+  
+  .data : AT (__etext)
+  {
+    __data_start__ = .;
+    *(vtable)
+    *(.data*)
+    . = ALIGN (4);
+    PROVIDE (__ram_func_section_start = .);
+    *(.ram)
+    PROVIDE (__ram_func_section_end = .);
+
+    . = ALIGN(4);
+    /* preinit data */
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP(*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+
+    . = ALIGN(4);
+    /* init data */
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP(*(SORT(.init_array.*)))
+    KEEP(*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+
+    . = ALIGN(4);
+    /* finit data */
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP(*(SORT(.fini_array.*)))
+    KEEP(*(.fini_array))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+
+    KEEP(*(.jcr*))
+    . = ALIGN(4);
+    /* All data end */
+    __data_end__ = .;
+
+  } > RAM
+
+  .bss :
+  {
+    . = ALIGN(4);
+    __bss_start__ = .;
+    *(.bss*)
+    *(COMMON)
+    . = ALIGN(4);
+    __bss_end__ = .;
+  } > RAM
+
+  .heap (COPY):
+  {
+    __HeapBase = .;
+    __end__ = .;
+    end = __end__;
+    _end = __end__;
+    KEEP(*(.heap*))
+    __HeapLimit = .;
+  } > RAM
+
+  /* .stack_dummy section doesn't contains any symbols. It is only
+   * used for linker to calculate size of stack sections, and assign
+   * values to stack symbols later */
+  .stack_dummy (COPY):
+  {
+    KEEP(*(.stack*))
+  } > RAM
+
+  /* Set stack top to end of RAM, and stack limit move down by
+   * size of stack_dummy section */
+  __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+  PROVIDE(__stack = __StackTop);
+
+  /*******************************************************************/
+  /* Define flash block for nvm3                                     */
+  .nvm (DSECT) : {
+    KEEP(*(.simee*))
+  } > FLASH
+
+  linker_nvm_end = ORIGIN(FLASH) + LENGTH(FLASH);
+  linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm);
+  linker_nvm_size = SIZEOF(.nvm);
+  __nvm3Base = linker_nvm_begin;
+  /*******************************************************************/
+
+  /* Check if data + heap + stack exceeds RAM limit */
+  ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+
+  /* Check if FLASH usage exceeds FLASH size */
+  ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
+}
diff --git a/examples/platforms/efr32mg13/flash.c b/examples/platforms/efr32mg13/flash.c
index b3cafff..15d46ea 100644
--- a/examples/platforms/efr32mg13/flash.c
+++ b/examples/platforms/efr32mg13/flash.c
@@ -31,114 +31,334 @@
  *   This file implements the OpenThread platform abstraction for the non-volatile storage.
  */
 
-#include <openthread-core-config.h>
-
+#include "openthread-core-efr32-config.h"
 #include <openthread/config.h>
-#include <openthread/platform/alarm-milli.h>
 
-#include "utils/code_utils.h"
-#include "utils/flash.h"
+#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE // Use OT NV system
 
 #include "em_msc.h"
+#include <string.h>
+#include <openthread/instance.h>
 
-// clang-format off
-#define FLASH_DATA_END_ADDR     (FLASH_BASE + FLASH_SIZE)
-#define FLASH_DATA_START_ADDR   (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM))
-// clang-format on
+#define FLASH_PAGE_NUM 2
+#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
+#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * FLASH_PAGE_NUM))
+#define FLASH_SWAP_PAGE_NUM (FLASH_PAGE_NUM / 2)
+#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * FLASH_SWAP_PAGE_NUM)
 
-static inline uint32_t mapAddress(uint32_t aAddress)
+static inline uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    return aAddress + FLASH_DATA_START_ADDR;
+    uint32_t address;
+
+    address = FLASH_DATA_START_ADDR + aOffset;
+
+    if (aSwapIndex)
+    {
+        address += FLASH_SWAP_SIZE;
+    }
+
+    return address;
 }
 
-static otError returnTypeConvert(int32_t aStatus)
+void otPlatFlashInit(otInstance *aInstance)
 {
-    otError error = OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
+}
 
-    switch (aStatus)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return FLASH_SWAP_SIZE;
+}
+
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address = mapAddress(aSwapIndex, 0);
+
+    for (uint32_t n = 0; n < FLASH_SWAP_PAGE_NUM; n++, address += FLASH_PAGE_SIZE)
     {
-    case mscReturnOk:
-        error = OT_ERROR_NONE;
+        MSC_ErasePage((uint32_t *)address);
+    }
+}
+
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    MSC_WriteWord((uint32_t *)mapAddress(aSwapIndex, aOffset), aData, aSize);
+}
+
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    memcpy(aData, (const uint8_t *)mapAddress(aSwapIndex, aOffset), aSize);
+}
+
+#else // Defaults to Silabs nvm3 system
+
+#include "nvm3.h"
+#include "nvm3_default.h"
+#include <string.h>
+#include <openthread/platform/settings.h>
+#include "common/code_utils.hpp"
+#include "common/logging.hpp"
+
+#define NVM3KEY_DOMAIN_OPENTHREAD 0x20000U
+#define NUM_INDEXED_SETTINGS \
+    OPENTHREAD_CONFIG_MLE_MAX_CHILDREN // Indexed key types are only supported for kKeyChildInfo (=='child table').
+#define ENUM_NVM3_KEY_LIST_SIZE 4      // List size used when enumerating nvm3 keys.
+
+static otError          addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
+static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index);
+static otError          mapNvm3Error(Ecode_t nvm3Res);
+
+void otPlatSettingsInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    if (mapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)) != OT_ERROR_NONE)
+    {
+        otLogDebgPlat("Error initializing nvm3 instance");
+    }
+}
+
+void otPlatSettingsDeinit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    nvm3_close(nvm3_defaultHandle);
+}
+
+otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
+{
+    // Searches through all matching nvm3 keys to find the one with the required
+    // 'index', then reads the nvm3 data into the destination buffer.
+    // (Repeatedly enumerates a list of matching keys from the nvm3 until the
+    // required index is found).
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError  err;
+    uint16_t valueLength = 0;
+
+    nvm3_ObjectKey_t nvm3Key  = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
+    bool             idxFound = false;
+    int              idx      = 0;
+    err                       = OT_ERROR_NOT_FOUND;
+    while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
+    {
+        // Get the next nvm3 key list.
+        nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
+        size_t           objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, nvm3Key,
+                                         makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
+        for (size_t i = 0; i < objCnt; ++i)
+        {
+            nvm3Key = keys[i];
+            if (idx == aIndex)
+            {
+                uint32_t objType;
+                size_t   objLen;
+                err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+                if (err == OT_ERROR_NONE)
+                {
+                    valueLength = objLen;
+
+                    // Only perform read if an input buffer was passed in.
+                    if ((aValue != NULL) && (aValueLength != NULL))
+                    {
+                        // Read all nvm3 obj bytes into a tmp buffer, then copy the required
+                        // number of bytes to the read destination buffer.
+                        uint8_t *buf = malloc(valueLength);
+                        err          = mapNvm3Error(nvm3_readData(nvm3_defaultHandle, nvm3Key, buf, valueLength));
+                        if (err == OT_ERROR_NONE)
+                        {
+                            memcpy(aValue, buf, (valueLength < *aValueLength) ? valueLength : *aValueLength);
+                        }
+                        free(buf);
+                        SuccessOrExit(err);
+                    }
+                }
+                idxFound = true;
+                break;
+            }
+            ++idx;
+        }
+        if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
+        {
+            // Stop searching (there are no more matching nvm3 objects).
+            break;
+        }
+        ++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
+    }
+
+exit:
+    if (aValueLength != NULL)
+    {
+        *aValueLength = valueLength; // always return actual nvm3 object length.
+    }
+
+    return err;
+}
+
+otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError err;
+
+    // Delete all nvm3 objects matching the input key (i.e. the 'setting indexes' of the key).
+    err = otPlatSettingsDelete(aInstance, aKey, -1);
+    if ((err == OT_ERROR_NONE) || (err == OT_ERROR_NOT_FOUND))
+    {
+        // Add new setting object (i.e. 'index0' of the key).
+        err = addSetting(aKey, aValue, aValueLength);
+        SuccessOrExit(err);
+    }
+
+exit:
+    return err;
+}
+
+otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return addSetting(aKey, aValue, aValueLength);
+}
+
+otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
+{
+    // Searches through all matching nvm3 keys to find the one with the required
+    // 'index' (or index = -1 to delete all), then deletes the nvm3 object.
+    // (Repeatedly enumerates a list of matching keys from the nvm3 until the
+    // required index is found).
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError          err;
+    nvm3_ObjectKey_t nvm3Key  = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
+    bool             idxFound = false;
+    int              idx      = 0;
+    err                       = OT_ERROR_NOT_FOUND;
+    while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
+    {
+        // Get the next nvm3 key list.
+        nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
+        size_t           objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, nvm3Key,
+                                         makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
+        for (size_t i = 0; i < objCnt; ++i)
+        {
+            nvm3Key = keys[i];
+            if ((idx == aIndex) || (aIndex == -1))
+            {
+                uint32_t objType;
+                size_t   objLen;
+                err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+                if (err == OT_ERROR_NONE)
+                {
+                    // Delete the nvm3 object.
+                    err = mapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, nvm3Key));
+                    SuccessOrExit(err);
+                }
+                if (aIndex != -1)
+                {
+                    idxFound = true;
+                    break;
+                }
+            }
+            ++idx;
+        }
+        if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
+        {
+            // Stop searching (there are no more matching nvm3 objects).
+            break;
+        }
+        ++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
+    }
+
+exit:
+    return err;
+}
+
+void otPlatSettingsWipe(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    // Delete nvm3 objects for all OT Settings keys (and any of their associated 'indexes').
+    // Note- any OT User nvm3 objects in the OT nvm3 area are NOT be erased.
+    for (uint16_t aKey = 0; aKey < 8; ++aKey)
+    {
+        otPlatSettingsDelete(NULL, aKey, -1);
+    }
+}
+
+// Local functions..
+
+static otError addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    // Helper function- writes input buffer data to a NEW nvm3 object.
+    // nvm3 object is created at the first available Key + index.
+
+    otError err;
+
+    if ((aValueLength == 0) || (aValue == NULL))
+    {
+        err = OT_ERROR_INVALID_ARGS;
+    }
+    else
+    {
+        for (int idx = 0; idx <= NUM_INDEXED_SETTINGS; ++idx)
+        {
+            nvm3_ObjectKey_t nvm3Key;
+            nvm3Key = makeNvm3ObjKey(aKey, idx);
+
+            uint32_t objType;
+            size_t   objLen;
+            err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+            if (err == OT_ERROR_NOT_FOUND)
+            {
+                // Use this index for the new nvm3 object.
+                // Write the binary data to nvm3 (Creates nvm3 object if required).
+                err = mapNvm3Error(nvm3_writeData(nvm3_defaultHandle, nvm3Key, aValue, aValueLength));
+                break;
+            }
+            else if (err != OT_ERROR_NONE)
+            {
+                break;
+            }
+        }
+    }
+
+    return err;
+}
+
+static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index)
+{
+    return (NVM3KEY_DOMAIN_OPENTHREAD | (otSettingsKey << 8) | (index & 0xFF));
+}
+
+static otError mapNvm3Error(Ecode_t nvm3Res)
+{
+    otError err;
+
+    switch (nvm3Res)
+    {
+    case ECODE_NVM3_OK:
+        err = OT_ERROR_NONE;
         break;
 
-    case mscReturnInvalidAddr:
-    case mscReturnUnaligned:
-        error = OT_ERROR_INVALID_ARGS;
+    case ECODE_NVM3_ERR_KEY_NOT_FOUND:
+        err = OT_ERROR_NOT_FOUND;
         break;
 
     default:
-        error = OT_ERROR_FAILED;
+        err = OT_ERROR_FAILED;
+        break;
     }
 
-    return error;
+    return err;
 }
 
-otError utilsFlashInit(void)
-{
-    MSC_Init();
-    return OT_ERROR_NONE;
-}
-
-uint32_t utilsFlashGetSize(void)
-{
-    return FLASH_DATA_END_ADDR - FLASH_DATA_START_ADDR;
-}
-
-otError utilsFlashErasePage(uint32_t aAddress)
-{
-    int32_t status;
-
-    status = MSC_ErasePage((uint32_t *)mapAddress(aAddress));
-
-    return returnTypeConvert(status);
-}
-
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    otError  error = OT_ERROR_BUSY;
-    uint32_t start = otPlatAlarmMilliGetNow();
-
-    do
-    {
-        if (MSC->STATUS & MSC_STATUS_WDATAREADY)
-        {
-            error = OT_ERROR_NONE;
-            break;
-        }
-    } while (aTimeout && ((otPlatAlarmMilliGetNow() - start) < aTimeout));
-
-    return error;
-}
-
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t rval = aSize;
-    int32_t  status;
-
-    otEXPECT_ACTION(aData, rval = 0);
-    otEXPECT_ACTION(((aAddress + aSize) < utilsFlashGetSize()) && (!(aAddress & 3)) && (!(aSize & 3)), rval = 0);
-
-    status = MSC_WriteWord((uint32_t *)mapAddress(aAddress), aData, aSize);
-    otEXPECT_ACTION(returnTypeConvert(status) == OT_ERROR_NONE, rval = 0);
-
-exit:
-    return rval;
-}
-
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t rval     = aSize;
-    uint32_t pAddress = mapAddress(aAddress);
-    uint8_t *byte     = aData;
-
-    otEXPECT_ACTION(aData, rval = 0);
-    otEXPECT_ACTION((aAddress + aSize) < utilsFlashGetSize(), rval = 0);
-
-    while (aSize--)
-    {
-        *byte++ = (*(uint8_t *)(pAddress++));
-    }
-
-exit:
-    return rval;
-}
+#endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
diff --git a/examples/platforms/efr32mg13/logging.c b/examples/platforms/efr32mg13/logging.c
index ad873dd..fa0a4dd 100644
--- a/examples/platforms/efr32mg13/logging.c
+++ b/examples/platforms/efr32mg13/logging.c
@@ -39,8 +39,7 @@
 
 #include <utils/logging_rtt.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 void efr32LogInit(void)
 {
     utilsLogRttInit();
diff --git a/examples/platforms/efr32mg13/openthread-core-efr32-config.h b/examples/platforms/efr32mg13/openthread-core-efr32-config.h
index c7920f7..d1cbde6 100644
--- a/examples/platforms/efr32mg13/openthread-core-efr32-config.h
+++ b/examples/platforms/efr32mg13/openthread-core-efr32-config.h
@@ -53,7 +53,7 @@
  * Define to 1 if you want to enable physical layer to support OQPSK modulation in 915MHz band.
  *
  */
-#ifdef RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
+#if RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
 #define OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT 1
 #else
 #define OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT 0
@@ -65,7 +65,7 @@
  * Define to 1 if you want to enable physical layer to support OQPSK modulation in 2.4GHz band.
  *
  */
-#ifdef RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
+#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
 #define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 1
 #else
 #define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 0
@@ -80,68 +80,46 @@
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32"
 
 /*
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
  *
  * Define to 1 if you want to enable software energy scanning logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of settings.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
  *
  */
-#define SETTINGS_CONFIG_BASE_ADDRESS 0
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_SIZE FLASH_PAGE_SIZE
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_NUM 4
-
-/**
- * @def RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
- *
- * The number of short source address table entries.
- *
- */
-#define RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM 6
-
-/**
- * @def RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
- *
- * The number of extended source address table entries.
- *
- */
-#define RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM 6
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
 
 /**
  * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
diff --git a/examples/platforms/efr32mg13/radio.c b/examples/platforms/efr32mg13/radio.c
index c1e6cc2..2f8bcdc 100644
--- a/examples/platforms/efr32mg13/radio.c
+++ b/examples/platforms/efr32mg13/radio.c
@@ -59,19 +59,25 @@
 
 enum
 {
-    IEEE802154_MIN_LENGTH      = 5,
-    IEEE802154_MAX_LENGTH      = 127,
-    IEEE802154_ACK_LENGTH      = 5,
-    IEEE802154_FRAME_TYPE_MASK = 0x7,
-    IEEE802154_FRAME_TYPE_ACK  = 0x2,
-    IEEE802154_FRAME_PENDING   = 1 << 4,
-    IEEE802154_ACK_REQUEST     = 1 << 5,
-    IEEE802154_DSN_OFFSET      = 2,
+    IEEE802154_MIN_LENGTH = 5,
+    IEEE802154_MAX_LENGTH = 127,
+    IEEE802154_ACK_LENGTH = 5,
+
+    // FCF + DSN + dest PANID + dest addr + src PANID + src addr (without security header)
+    IEEE802154_MAX_MHR_LENGTH = 2 + 1 + 2 + 8 + 2 + 8,
+
+    IEEE802154_FRAME_TYPE_MASK        = 0x7,
+    IEEE802154_FRAME_TYPE_ACK         = 0x2,
+    IEEE802154_FRAME_TYPE_MAC_COMMAND = 0x3,
+    IEEE802154_ACK_REQUEST            = 1 << 5,
+    IEEE802154_DSN_OFFSET             = 2,
+    IEEE802154_FCF_OFFSET             = 0,
 };
 
 enum
 {
     EFR32_RECEIVE_SENSITIVITY    = -100, // dBm
+    EFR32_RSSI_AVERAGING_TIME    = 16,   // us
     EFR32_RSSI_AVERAGING_TIMEOUT = 300,  // us
 };
 
@@ -106,10 +112,25 @@
 
 RAIL_Handle_t gRailHandle;
 
-static volatile bool sTransmitBusy      = false;
-static bool          sPromiscuous       = false;
-static bool          sIsSrcMatchEnabled = false;
-static otRadioState  sState             = OT_RADIO_STATE_DISABLED;
+static volatile bool sTransmitBusy = false;
+static bool          sPromiscuous  = false;
+static otRadioState  sState        = OT_RADIO_STATE_DISABLED;
+
+enum
+{
+    ACKED_WITH_FP_MATCH_LENGTH = 1 + IEEE802154_MAX_MHR_LENGTH, // PHR and MHR
+    ACKED_WITH_FP_SLOTS = 16, // maximum number of Data Request packets in the RX FIFO. Length should be a power of 2.
+};
+
+typedef struct efr32AckedWithFP
+{
+    uint8_t mLength;
+    uint8_t mPacket[ACKED_WITH_FP_MATCH_LENGTH];
+} efr32AckedWithFP;
+static bool              sIsSrcMatchEnabled = false;
+static efr32AckedWithFP  sAckedWithFPFifo[ACKED_WITH_FP_SLOTS];
+static uint32_t          sAckedWithFPReadIndex;
+static volatile uint32_t sAckedWithFPWriteIndex;
 
 static uint8_t      sReceivePsdu[IEEE802154_MAX_LENGTH];
 static otRadioFrame sReceiveFrame;
@@ -140,7 +161,7 @@
     .ackConfig =
         {
             .enable     = true,
-            .ackTimeout = 894,
+            .ackTimeout = 864,
             .rxTransitions =
                 {
                     .success = RAIL_RF_STATE_RX,
@@ -166,10 +187,16 @@
     .isPanCoordinator = false,
 };
 
+#if RADIO_CONFIG_PA_USES_DCDC
+RAIL_DECLARE_TX_POWER_DCDC_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp);
+#else
 RAIL_DECLARE_TX_POWER_VBAT_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp);
+#endif
 
 static int8_t sTxPowerDbm = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
 
+static int8_t sCcaThresholdDbm = -75; // default -75dBm energy detect threshold
+
 static efr32BandConfig *sCurrentBandConfig = NULL;
 
 static RAIL_Handle_t efr32RailInit(efr32CommonConfig *aCommonConfig)
@@ -319,6 +346,10 @@
     sCurrentBandConfig = efr32RadioGetBandConfig(OPENTHREAD_CONFIG_DEFAULT_CHANNEL);
     assert(sCurrentBandConfig != NULL);
 
+    memset(sAckedWithFPFifo, 0, sizeof(sAckedWithFPFifo));
+    sAckedWithFPWriteIndex = 0;
+    sAckedWithFPReadIndex  = 0;
+
     efr32RadioSetTxPower(sTxPowerDbm);
 
     sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
@@ -398,11 +429,8 @@
 
     utilsSoftSrcMatchSetPanId(aPanId);
 
-    for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
-    {
-        status = RAIL_IEEE802154_SetPanId(gRailHandle, aPanId, 0);
-        assert(status == RAIL_STATUS_NO_ERROR);
-    }
+    status = RAIL_IEEE802154_SetPanId(gRailHandle, aPanId, 0);
+    assert(status == RAIL_STATUS_NO_ERROR);
 }
 
 void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress)
@@ -414,11 +442,8 @@
     otLogInfoPlat("ExtAddr=%X%X%X%X%X%X%X%X", aAddress->m8[7], aAddress->m8[6], aAddress->m8[5], aAddress->m8[4],
                   aAddress->m8[3], aAddress->m8[2], aAddress->m8[1], aAddress->m8[0]);
 
-    for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
-    {
-        status = RAIL_IEEE802154_SetLongAddress(gRailHandle, (uint8_t *)aAddress->m8, 0);
-        assert(status == RAIL_STATUS_NO_ERROR);
-    }
+    status = RAIL_IEEE802154_SetLongAddress(gRailHandle, (uint8_t *)aAddress->m8, 0);
+    assert(status == RAIL_STATUS_NO_ERROR);
 }
 
 void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
@@ -429,11 +454,8 @@
 
     otLogInfoPlat("ShortAddr=%X", aAddress);
 
-    for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
-    {
-        status = RAIL_IEEE802154_SetShortAddress(gRailHandle, aAddress, 0);
-        assert(status == RAIL_STATUS_NO_ERROR);
-    }
+    status = RAIL_IEEE802154_SetShortAddress(gRailHandle, aAddress, 0);
+    assert(status == RAIL_STATUS_NO_ERROR);
 }
 
 bool otPlatRadioIsEnabled(otInstance *aInstance)
@@ -476,7 +498,7 @@
 
     otLogInfoPlat("State=OT_RADIO_STATE_SLEEP", NULL);
 
-    RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true); // abort packages under reception
+    RAIL_Idle(gRailHandle, RAIL_IDLE, true);
     sState = OT_RADIO_STATE_SLEEP;
 
 exit:
@@ -497,7 +519,7 @@
 
     if (sCurrentBandConfig != config)
     {
-        RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
+        RAIL_Idle(gRailHandle, RAIL_IDLE, true);
         efr32RailConfigLoad(config);
         sCurrentBandConfig = config;
     }
@@ -545,7 +567,7 @@
 
     if (sCurrentBandConfig != config)
     {
-        RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
+        RAIL_Idle(gRailHandle, RAIL_IDLE, true);
         efr32RailConfigLoad(config);
         sCurrentBandConfig = config;
     }
@@ -596,6 +618,9 @@
         // time needed for CSMA/CA
         txSchedulerInfo.transactionTime += RADIO_TIMING_CSMA_OVERHEAD_US;
 #endif
+        csmaConfig.csmaTries    = aFrame->mInfo.mTxInfo.mMaxCsmaBackoffs;
+        csmaConfig.ccaThreshold = sCcaThresholdDbm;
+
         status = RAIL_StartCcaCsmaTx(gRailHandle, aFrame->mChannel, txOptions, &csmaConfig, &txSchedulerInfo);
     }
     else
@@ -617,6 +642,7 @@
 #endif
         sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
         sTransmitBusy  = false;
+        otSysEventSignalPending();
     }
 
 exit:
@@ -632,19 +658,29 @@
 
 int8_t otPlatRadioGetRssi(otInstance *aInstance)
 {
-    int8_t rssi = OT_RADIO_RSSI_INVALID;
+    otError  error;
+    uint32_t start;
+    int8_t   rssi = OT_RADIO_RSSI_INVALID;
+
     OT_UNUSED_VARIABLE(aInstance);
 
-    if ((RAIL_GetRadioState(gRailHandle) & RAIL_RF_STATE_RX))
+    error = efr32StartEnergyScan(ENERGY_SCAN_MODE_SYNC, sReceiveFrame.mChannel, EFR32_RSSI_AVERAGING_TIME);
+    otEXPECT(error == OT_ERROR_NONE);
+
+    start = RAIL_GetTime();
+
+    // waiting for the event RAIL_EVENT_RSSI_AVERAGE_DONE
+    while (sEnergyScanStatus == ENERGY_SCAN_STATUS_IN_PROGRESS &&
+           ((RAIL_GetTime() - start) < EFR32_RSSI_AVERAGING_TIMEOUT))
+        ;
+
+    if (sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED)
     {
-        int16_t railRssi = RAIL_RSSI_INVALID;
-        railRssi         = RAIL_GetRssi(gRailHandle, true);
-        if (railRssi != RAIL_RSSI_INVALID)
-        {
-            rssi = railRssi / QUARTER_DBM_IN_DBM;
-        }
+        rssi = sEnergyScanResultDbm;
     }
 
+    sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
+exit:
     return rssi;
 }
 
@@ -670,11 +706,8 @@
 
     sPromiscuous = aEnable;
 
-    for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
-    {
-        status = RAIL_IEEE802154_SetPromiscuousMode(gRailHandle, aEnable);
-        assert(status == RAIL_STATUS_NO_ERROR);
-    }
+    status = RAIL_IEEE802154_SetPromiscuousMode(gRailHandle, aEnable);
+    assert(status == RAIL_STATUS_NO_ERROR);
 }
 
 void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
@@ -685,6 +718,74 @@
     sIsSrcMatchEnabled = aEnable;
 }
 
+static bool sAckedWithFPFifoIsFull(void)
+{
+    return (uint32_t)(sAckedWithFPWriteIndex - sAckedWithFPReadIndex) == otARRAY_LENGTH(sAckedWithFPFifo);
+}
+
+static bool sAckedWithFPFifoIsEmpty(void)
+{
+    return (uint32_t)(sAckedWithFPWriteIndex - sAckedWithFPReadIndex) == 0;
+}
+
+static efr32AckedWithFP *sAckedWithFPFifoGetWriteSlot(void)
+{
+    uint32_t idx = sAckedWithFPWriteIndex & (otARRAY_LENGTH(sAckedWithFPFifo) - 1);
+    return &sAckedWithFPFifo[idx];
+}
+
+static const efr32AckedWithFP *sAckedWithFPFifoGetReadSlot(void)
+{
+    uint32_t idx = sAckedWithFPReadIndex & (otARRAY_LENGTH(sAckedWithFPFifo) - 1);
+    return &sAckedWithFPFifo[idx];
+}
+
+static void insertIeee802154DataRequestCommand(RAIL_Handle_t aRailHandle)
+{
+    assert(!sAckedWithFPFifoIsFull());
+    efr32AckedWithFP *const slot = sAckedWithFPFifoGetWriteSlot();
+
+    RAIL_RxPacketInfo_t packetInfo;
+
+    RAIL_GetRxIncomingPacketInfo(aRailHandle, &packetInfo);
+    assert(packetInfo.packetBytes >= 4); // PHR + FCF + DSN
+
+    if (packetInfo.packetBytes > sizeof(slot->mPacket))
+    {
+        packetInfo.packetBytes = sizeof(slot->mPacket);
+        if (packetInfo.firstPortionBytes >= sizeof(slot->mPacket))
+        {
+            packetInfo.firstPortionBytes = sizeof(slot->mPacket);
+            packetInfo.lastPortionData   = NULL;
+        }
+    }
+    slot->mLength = packetInfo.packetBytes;
+    RAIL_CopyRxPacket(slot->mPacket, &packetInfo);
+
+    ++sAckedWithFPWriteIndex;
+}
+
+static bool wasAckedWithFramePending(const uint8_t *aPsdu, uint8_t aPsduLength)
+{
+    bool     ackedWithFramePending = false;
+    uint16_t fcf                   = aPsdu[IEEE802154_FCF_OFFSET] | (aPsdu[IEEE802154_FCF_OFFSET + 1] << 8);
+
+    otEXPECT((fcf & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_MAC_COMMAND);
+
+    while (!(ackedWithFramePending || sAckedWithFPFifoIsEmpty()))
+    {
+        const efr32AckedWithFP *const slot = sAckedWithFPFifoGetReadSlot();
+        if ((slot->mPacket[0] == aPsduLength) && (memcmp(slot->mPacket + 1, aPsdu, slot->mLength - 1) == 0))
+        {
+            ackedWithFramePending = true;
+        }
+        ++sAckedWithFPReadIndex;
+    }
+
+exit:
+    return ackedWithFramePending;
+}
+
 static void processNextRxPacket(otInstance *aInstance)
 {
     RAIL_RxPacketHandle_t  packetHandle = RAIL_RX_PACKET_HANDLE_INVALID;
@@ -704,11 +805,11 @@
 
     length = packetInfo.packetBytes + 1;
 
-    // check the length in recv packet info structure
-    otEXPECT(length == packetInfo.firstPortionData[0]);
+    // check the length in recv packet info structure; RAIL should take care of this.
+    assert(length == packetInfo.firstPortionData[0]);
 
-    // check the length validity of recv packet
-    otEXPECT(length >= IEEE802154_MIN_LENGTH && length <= IEEE802154_MAX_LENGTH);
+    // check the length validity of recv packet; RAIL should take care of this.
+    assert(length >= IEEE802154_MIN_LENGTH && length <= IEEE802154_MAX_LENGTH);
 
     otLogInfoPlat("Received data:%d", length);
 
@@ -719,9 +820,7 @@
     packetInfo.packetBytes--;
 
     // read packet
-    memcpy(sReceiveFrame.mPsdu, packetInfo.firstPortionData, packetInfo.firstPortionBytes);
-    memcpy(sReceiveFrame.mPsdu + packetInfo.firstPortionBytes, packetInfo.lastPortionData,
-           packetInfo.packetBytes - packetInfo.firstPortionBytes);
+    RAIL_CopyRxPacket(sReceiveFrame.mPsdu, &packetInfo);
 
     status = RAIL_ReleaseRxPacket(gRailHandle, packetHandle);
     if (status == RAIL_STATUS_NO_ERROR)
@@ -750,20 +849,26 @@
     }
     else
     {
-        otEXPECT(length != IEEE802154_ACK_LENGTH);
+        // signal MAC layer for each received frame if promiscuous is enabled
+        // otherwise only signal MAC layer for non-ACK frame
+        otEXPECT(sPromiscuous || (length != IEEE802154_ACK_LENGTH));
 
         sReceiveError = OT_ERROR_NONE;
 
         sReceiveFrame.mInfo.mRxInfo.mRssi = packetDetails.rssi;
         sReceiveFrame.mInfo.mRxInfo.mLqi  = packetDetails.lqi;
 
-        // TODO: grab timestamp and handle conversion to msec/usec and RAIL_GetRxTimeSyncWordEndAlt
-        // sReceiveFrame.mInfo.mRxInfo.mMsec = packetDetails.packetTime;
-        // sReceiveFrame.mInfo.mRxInfo.mUsec = packetDetails.packetTime;
+        // Get the timestamp when the SFD was received
+        assert(packetDetails.timeReceived.timePosition != RAIL_PACKET_TIME_INVALID);
+        packetDetails.timeReceived.totalPacketBytes = length + 1;
 
-        // TODO Set this flag only when the packet is really acknowledged with frame pending set.
-        // See https://github.com/openthread/openthread/pull/3785
-        sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true;
+        status = RAIL_GetRxTimeSyncWordEndAlt(gRailHandle, &packetDetails);
+        assert(status == RAIL_STATUS_NO_ERROR);
+        sReceiveFrame.mInfo.mRxInfo.mTimestamp = packetDetails.timeReceived.packetTime;
+
+        // Set this flag only when the packet is really acknowledged with frame pending set.
+        sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending =
+            wasAckedWithFramePending(sReceiveFrame.mPsdu, sReceiveFrame.mLength);
 
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
 
@@ -774,16 +879,11 @@
         else
 #endif
         {
-            // signal MAC layer for each received frame if promiscous is enabled
-            // otherwise only signal MAC layer for non-ACK frame
-            if (sPromiscuous || sReceiveFrame.mLength > IEEE802154_ACK_LENGTH)
-            {
-                otLogInfoPlat("Received %d bytes", sReceiveFrame.mLength);
-                otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
+            otLogInfoPlat("Received %d bytes", sReceiveFrame.mLength);
+            otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
 #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
-                sRailDebugCounters.mRailPlatRadioReceiveDoneCbCount++;
+            sRailDebugCounters.mRailPlatRadioReceiveDoneCbCount++;
 #endif
-            }
         }
     }
 
@@ -815,12 +915,14 @@
         {
             status = RAIL_IEEE802154_SetFramePending(aRailHandle);
             assert(status == RAIL_STATUS_NO_ERROR);
+            insertIeee802154DataRequestCommand(aRailHandle);
         }
     }
     else
     {
         status = RAIL_IEEE802154_SetFramePending(aRailHandle);
         assert(status == RAIL_STATUS_NO_ERROR);
+        insertIeee802154DataRequestCommand(aRailHandle);
     }
 }
 
@@ -840,6 +942,7 @@
     {
         ieee802154DataRequestCommand(aRailHandle);
     }
+
     if (aEvents & RAIL_EVENTS_TX_COMPLETION)
     {
         if (aEvents & RAIL_EVENT_TX_PACKET_SENT)
@@ -967,6 +1070,10 @@
 
 void efr32RadioProcess(otInstance *aInstance)
 {
+    // We should process the received packet first. Adding it at the end of this function,
+    // will delay the stack notification until the next call to efr32RadioProcess()
+    processNextRxPacket(aInstance);
+
     if (sState == OT_RADIO_STATE_TRANSMIT && sTransmitBusy == false)
     {
         if (sTransmitError != OT_ERROR_NONE)
@@ -1007,8 +1114,6 @@
         sRailDebugCounters.mRailEventEnergyScanCompleted++;
 #endif
     }
-
-    processNextRxPacket(aInstance);
 }
 
 otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
@@ -1041,17 +1146,23 @@
 otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
 {
     OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aThreshold);
 
-    return OT_ERROR_NOT_IMPLEMENTED;
+    otError error = OT_ERROR_NONE;
+    otEXPECT_ACTION(aThreshold != NULL, error = OT_ERROR_INVALID_ARGS);
+
+    *aThreshold = sCcaThresholdDbm;
+
+exit:
+    return error;
 }
 
 otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
 {
     OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aThreshold);
 
-    return OT_ERROR_NOT_IMPLEMENTED;
+    sCcaThresholdDbm = aThreshold;
+
+    return OT_ERROR_NONE;
 }
 
 int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
diff --git a/examples/platforms/efr32mg13/sleepy-demo/Makefile.am b/examples/platforms/efr32mg13/sleepy-demo/Makefile.am
index 22cb725..9be5713 100644
--- a/examples/platforms/efr32mg13/sleepy-demo/Makefile.am
+++ b/examples/platforms/efr32mg13/sleepy-demo/Makefile.am
@@ -44,11 +44,4 @@
 SUBDIRS                                += sleepy-demo-mtd sleepy-demo-ftd
 endif
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    sleepy-demo-mtd                       \
-    sleepy-demo-ftd                       \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/efr32mg13/sleepy-demo/README.md b/examples/platforms/efr32mg13/sleepy-demo/README.md
index 7af6fe8..847f8a0 100644
--- a/examples/platforms/efr32mg13/sleepy-demo/README.md
+++ b/examples/platforms/efr32mg13/sleepy-demo/README.md
@@ -1,13 +1,9 @@
-
 # EFR32MG13 Sleepy Demo Example
 
-The EFR32 Sleepy applications demonstrates Sleepy End Device behaviour using
-the EFR32's low power EM2 mode. The steps below will take you through the
-process of building and running the demo
+The EFR32 Sleepy applications demonstrates Sleepy End Device behavior using the EFR32's low power EM2 mode. The steps below will take you through the process of building and running the demo
 
 For setting up the build environment refer to [examples/platforms/efr32mg13/README.md](../README.md).
 
-
 ## 1. Build
 
 ```bash
@@ -24,18 +20,13 @@
 $ arm-none-eabi-objcopy -O srec sleepy-demo-ftd sleepy-demo-ftd.s37
 ```
 
-In Silicon Labs Simplicity Studio flash one device with the sleepy-demo-mtd.s37
-image and the other device with the sleepy-demo-ftd.s37 image.
+In Silicon Labs Simplicity Studio flash one device with the sleepy-demo-mtd.s37 image and the other device with the sleepy-demo-ftd.s37 image.
 
 For instructions on flashing firmware see [examples/platforms/efr32mg13/README.md](../README.md#flash-binaries)
 
-
 ## 2. Starting nodes
 
-For demonstration purposes the network settings are hardcoded within the source files.
-The devices start Thread and form a network within a few seconds of powering on. In a real-life
-application the devices should implement and go through a commissioning process to create
-a network and add devices.
+For demonstration purposes the network settings are hardcoded within the source files. The devices start Thread and form a network within a few seconds of powering on. In a real-life application the devices should implement and go through a commissioning process to create a network and add devices.
 
 When the sleepy-demo-ftd device is started in the CLI the user shall see:
 
@@ -44,8 +35,7 @@
 sleepy-demo-ftd changed to leader
 ```
 
-When the sleepy-demo-mtd device starts it joins the preconfigured Thread network
-before disabling Rx-On-Idle to become a Sleepy-End-Device.
+When the sleepy-demo-mtd device starts it joins the pre-configured Thread network before disabling Rx-On-Idle to become a Sleepy-End-Device.
 
 Use the command "child table" in the FTD console and observe the R flag of the child is 0.
 
@@ -58,43 +48,26 @@
 Done
 ```
 
-
 ## 3. Buttons on the MTD
 
-Pressing button 0 on the MTD toggles between operating as a Minimal End Device (MED) and
-a Sleepy End Device (SED) with the RX off when idle.
+Pressing button 0 on the MTD toggles between operating as a Minimal End Device (MED) and a Sleepy End Device (SED) with the RX off when idle.
 
-Pressing button 1 on the MTD sends a multicast UDP message containing the
-string "mtd button".  The FTD listens on the multicast address and will toggle
-LED 0 and display a message in the CLI showing "Message Received: mtd button".
+Pressing button 1 on the MTD sends a multicast UDP message containing the string "mtd button". The FTD listens on the multicast address and will toggle LED 0 and display a message in the CLI showing "Message Received: mtd button".
 
 ## 4. Buttons on the FTD
 
-Pressing either button 0 or 1 on the FTD will send a UDP message to the FTD containing the string
-"ftd button". The MTD must first send a multicast message by pressing the MTD's button 1 so that
-the FTD knows the address of the MTD to send messages to.
+Pressing either button 0 or 1 on the FTD will send a UDP message to the FTD containing the string "ftd button". The MTD must first send a multicast message by pressing the MTD's button 1 so that the FTD knows the address of the MTD to send messages to.
 
-This will toggle the state of LED0 on the MTD.  If the MTD is operating as a sleepy end device then
-the MTD polls the parent every 5 seconds for messages and will update the LED state on the
-next poll.
+This will toggle the state of LED0 on the MTD. If the MTD is operating as a sleepy end device then the MTD polls the parent every 5 seconds for messages and will update the LED state on the next poll.
 
 ## 5. Monitoring power consumption of the MTD
 
-Open the Energy Profiler within Silicon Labs Simplicity Studio.  Within the Quick Access menu
-select Start Energy Capture... and select the MTD device.  When operating as a Sleepy End Device
-with no LEDs on the current should be under 20 microamps with occassional spikes during waking
-and polling the parent.  With the LED on the MTD has a current consumption of approximately 1mA.
+Open the Energy Profiler within Silicon Labs Simplicity Studio. Within the Quick Access menu select Start Energy Capture... and select the MTD device. When operating as a Sleepy End Device with no LEDs on the current should be under 20 microamps with occasional spikes during waking and polling the parent. With the LED on the MTD has a current consumption of approximately 1mA.
 
-When operating as a Minial End Device with the Rx on Idle observe that the current is in the order
-of 10ma.
+When operating as a Minimal End Device with the Rx on Idle observe that the current is in the order of 10ma.
 
-With further configuration of GPIOs and peripherals it is possible to reduce the sleepy current
-consumption further.
+With further configuration of GPIOs and peripherals it is possible to reduce the sleepy current consumption further.
 
 ## 6. Notes on sleeping, sleepy callback and interrupts
 
-To allow the EFR32 to enter sleepy mode the application must register a callback with efr32SetSleepCallback.
-The return value of callback is used to indicate that the application has no further work to do and that
-it is safe to go into a low power mode.  The callback is called with interrupts disabled so should do
-the minimum required to check if it can sleep.
-
+To allow the EFR32 to enter sleepy mode the application must register a callback with efr32SetSleepCallback. The return value of callback is used to indicate that the application has no further work to do and that it is safe to go into a low power mode. The callback is called with interrupts disabled so should do the minimum required to check if it can sleep.
diff --git a/examples/platforms/efr32mg13/sleepy-demo/sleepy-demo-ftd/main.c b/examples/platforms/efr32mg13/sleepy-demo/sleepy-demo-ftd/main.c
index a6715b2..7a489b1 100644
--- a/examples/platforms/efr32mg13/sleepy-demo/sleepy-demo-ftd/main.c
+++ b/examples/platforms/efr32mg13/sleepy-demo/sleepy-demo-ftd/main.c
@@ -237,10 +237,10 @@
         return;
     }
 
-    error = otUdpBind(&sFtdSocket, &sockaddr);
+    error = otUdpBind(instance, &sFtdSocket, &sockaddr);
     if (error != OT_ERROR_NONE)
     {
-        otUdpClose(&sFtdSocket);
+        otUdpClose(instance, &sFtdSocket);
         otCliOutputFormat("FTD failed to bind udp multicast\r\n");
         return;
     }
@@ -277,7 +277,7 @@
 
                 if (error == OT_ERROR_NONE)
                 {
-                    error = otUdpSend(&sFtdSocket, message, &messageInfo);
+                    error = otUdpSend(instance, &sFtdSocket, message, &messageInfo);
 
                     if (error == OT_ERROR_NONE)
                     {
diff --git a/examples/platforms/efr32mg13/sleepy-demo/sleepy-demo-mtd/main.c b/examples/platforms/efr32mg13/sleepy-demo/sleepy-demo-mtd/main.c
index 7037bc0..b1d34a3 100644
--- a/examples/platforms/efr32mg13/sleepy-demo/sleepy-demo-mtd/main.c
+++ b/examples/platforms/efr32mg13/sleepy-demo/sleepy-demo-mtd/main.c
@@ -277,11 +277,11 @@
         return;
     }
 
-    error = otUdpBind(&sMtdSocket, &sockaddr);
+    error = otUdpBind(instance, &sMtdSocket, &sockaddr);
 
     if (error != OT_ERROR_NONE)
     {
-        otUdpClose(&sMtdSocket);
+        otUdpClose(instance, &sMtdSocket);
         return;
     }
 }
@@ -333,7 +333,7 @@
 
             if (error == OT_ERROR_NONE)
             {
-                error = otUdpSend(&sMtdSocket, message, &messageInfo);
+                error = otUdpSend(instance, &sMtdSocket, message, &messageInfo);
 
                 if (error == OT_ERROR_NONE)
                 {
diff --git a/examples/platforms/efr32mg13/system.c b/examples/platforms/efr32mg13/system.c
index beac140..7b1aa3c 100644
--- a/examples/platforms/efr32mg13/system.c
+++ b/examples/platforms/efr32mg13/system.c
@@ -59,9 +59,7 @@
 #include "fem-control.h"
 #endif
 
-#define USE_EFR32_LOG                                                                   \
-    ((OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-     (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL))
+#define USE_EFR32_LOG (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 
 void halInitChipSpecific(void);
 
diff --git a/examples/platforms/efr32mg21/Makefile.am b/examples/platforms/efr32mg21/Makefile.am
index f11691b..ef1eab6 100644
--- a/examples/platforms/efr32mg21/Makefile.am
+++ b/examples/platforms/efr32mg21/Makefile.am
@@ -72,6 +72,8 @@
     -I$(SDK_SRC_DIR)/platform/emdrv/ustimer/inc                                 \
     -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/inc                                  \
     -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/config                               \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/inc                                    \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/config                                 \
     -I$(SDK_SRC_DIR)/platform/emlib/inc                                         \
     -I$(SDK_SRC_DIR)/platform/halconfig/inc/hal-config                          \
     -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32                         \
@@ -118,10 +120,6 @@
     $(PLATFORM_SOURCES)                                                         \
     $(NULL)
 
-PRETTY_FILES                                                                  = \
-    $(PLATFORM_SOURCES)                                                         \
-    $(NULL)
-
 Dash = -
 libopenthread_efr32mg21_a_LIBADD                                                                     = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")             \
@@ -130,13 +128,9 @@
 DIST_SUBDIRS                                                                  = \
     sleepy-demo                                                                 \
     $(NULL)
-    
+
 SUBDIRS                                                                       = \
     sleepy-demo                                                                 \
     $(NULL)
 
-PRETTY_SUBDIRS                                                                = \
-    sleepy-demo                                                                 \
-    $(NULL)
-    
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/efr32mg21/Makefile.platform.am b/examples/platforms/efr32mg21/Makefile.platform.am
index adcfac4..03a85ae 100644
--- a/examples/platforms/efr32mg21/Makefile.platform.am
+++ b/examples/platforms/efr32mg21/Makefile.platform.am
@@ -41,8 +41,9 @@
     $(top_builddir)/examples/platforms/efr32mg21/libopenthread-efr32mg21.a       \
     $(top_builddir)/third_party/silabs/libsilabs-efr32mg21-sdk.a                 \
     $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/radio/rail_lib/autogen/librail_release/$(LIBRAIL) \
+    $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/emdrv/nvm3/lib/libnvm3_CM33_gcc.a \
     $(NULL)
-
+    
 LDFLAGS_COMMON                                                                += \
-    -T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/efr32mg21.ld \
+    -T $(top_srcdir)/examples/platforms/efr32mg21/efr32mg21.ld                   \
     $(NULL)
diff --git a/examples/platforms/efr32mg21/README.md b/examples/platforms/efr32mg21/README.md
index 07c21a1..ae6310a 100644
--- a/examples/platforms/efr32mg21/README.md
+++ b/examples/platforms/efr32mg21/README.md
@@ -1,16 +1,11 @@
 # OpenThread on EFR32MG21 Example
 
-This directory contains example platform drivers for the [Silicon Labs EFR32MG21][efr32mg]
-based on [EFR32™ Mighty Gecko Wireless Starter Kit][SLWSTK6000B] 
+This directory contains example platform drivers for the [Silicon Labs EFR32MG21][efr32mg] based on [EFR32™ Mighty Gecko Wireless Starter Kit][slwstk6000b]
 
 [efr32mg]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc
-[SLWSTK6000B]: http://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit
+[slwstk6000b]: http://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit
 
-The example platform drivers are intended to present the minimal code
-necessary to support OpenThread. [EFR32MG21 SoC][efr32mg21]
-has rich memory and peripheral resources which can support all OpenThread
-capabilities. See the "Run the example with EFR32 boards" section below
-for an example using basic OpenThread capabilities.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. [EFR32MG21 SoC][efr32mg21] has rich memory and peripheral resources which can support all OpenThread capabilities. See the "Run the example with EFR32 boards" section below for an example using basic OpenThread capabilities.
 
 [efr32mg21]: https://www.silabs.com/products/wireless/mesh-networking/series-2-efr32-mighty-gecko-zigbee-thread-soc/device.efr32mg21a020f768im32
 
@@ -20,8 +15,7 @@
 
 [gnu-toolchain]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -39,29 +33,26 @@
    - Find Flex SDK v2.7 in the Software Update page and click Install.
    - Flex SDK v2.7 will be installed in the path: `/SimplicityStudio_v4/developer/sdks/gecko_sdk_suite`.
 
-For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32)
-portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the 
-Wireless Gecko (EFR32™) Portfolio][QSG138]. For more information
-on RAIL, see [Radio Abstraction Interface Layer][rail].
+For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32) portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the Wireless Gecko (EFR32™) Portfolio][qsg138]. For more information on RAIL, see [Radio Abstraction Interface Layer][rail].
 
-[QSG138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
+[qsg138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
 [rail]: http://www.silabs.com/products/development-tools/software/radio-abstraction-interface-layer-sdk
 
 3. Configure the path to Flex SDK source code.
+
 ```bash
 $ cd <path-to-Simplicity-Studio>/developer/sdks
 $ cp -rf gecko_sdk_suite <path-to-openthread>/third_party/silabs/
 ```
 
 Alternatively create a symbolic link to the Flex SDK source code.
+
 ```bash
 $ cd <path-to-openthread>/third_party
 $ ln -s <path-to-Simplicity-Studio>/developer/sdks/gecko_sdk_suite silabs/gecko_sdk_suite
 ```
 
-Note: Due to an error in the core_cm33.h file provided by ARM, the compiler will throw an error when pedantic
-option is used on the builds. To avoid this, please add the following lines of code at the top of the
-file core_cm33.h:
+Note: Due to an error in the core_cm33.h file provided by ARM, the compiler will throw an error when pedantic option is used on the builds. To avoid this, please add the following lines of code at the top of the file core_cm33.h:
 
 ```
 #if defined(__GNUC__)
@@ -76,17 +67,19 @@
 ```
 
 4. Build OpenThread Firmware (CLI example) on EFR32 platform.
+
 ```bash
 $ cd <path-to-openthread>
 $ ./bootstrap
 ```
+
 For EFR32MG21™ Mighty Gecko Wireless Starter Kit:
+
 ```bash
 $ make -f examples/Makefile-efr32mg21 BOARD=BRD4180A
 ```
 
-After a successful build, the `elf` files are found in
-`<path-to-openthread>/output/efr32mg21/bin`.
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/efr32mg21/bin`.
 
 ## Flash Binaries
 
@@ -98,16 +91,12 @@
 $ <path-to-simplicity-studio>/developer/adapter_packs/commander/commander
 ```
 
-In the J-Link Device drop-down list select the serial number of the device to flash.  Click the Adapter Connect button.
-Esnure the Debug Interface drop-down list is set to SWD and click the Target Connect button.
-Click on the Flash icon on the left side of the window to switch to the flash page.
-In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button.
-Click the Flash button located under the Browse... button.
+In the J-Link Device drop-down list select the serial number of the device to flash. Click the Adapter Connect button. Ensure the Debug Interface drop-down list is set to SWD and click the Target Connect button. Click on the Flash icon on the left side of the window to switch to the flash page. In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button. Click the Flash button located under the Browse... button.
 
 ## Run the example with EFR32MG21 boards
+
 1. Flash two EFR32 boards with the `CLI example` firmware (as shown above).
-2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1).
-   Type `help` for a list of commands.
+2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1). Type `help` for a list of commands.
 
 ```bash
 > help
@@ -156,8 +145,7 @@
 Done
 ```
 
-4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1)
-   and attach it to the Thread network as a Router.
+4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1) and attach it to the Thread network as a Router.
 
 ```bash
 > panid 0xface
@@ -194,8 +182,7 @@
 8 bytes from fdde:ad00:beef:0:5b:3bcd:deff:7786: icmp_seq=1 hlim=64 time=24ms
 ```
 
-The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner,
-joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
+The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner, joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
 
 ```bash
 $ cd <path-to-openthread>
@@ -203,14 +190,16 @@
 $ make -f examples/Makefile-efr32mg21 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1
 ```
 
-For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
 
-[CLI]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
+[cli]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
 
 ## Verification
 
 The following toolchain has been used for testing and verification:
-   - gcc version 7.3.1
+
+- gcc version 7.3.1
 
 The EFR32 example has been verified with following Flex SDK/RAIL Library version:
-   - Flex SDK version 2.7.0.0
+
+- Flex SDK version 2.7.0.0
diff --git a/examples/platforms/efr32mg21/brd4180a/board_config.h b/examples/platforms/efr32mg21/brd4180a/board_config.h
index ee009f6..51aa1e1 100644
--- a/examples/platforms/efr32mg21/brd4180a/board_config.h
+++ b/examples/platforms/efr32mg21/brd4180a/board_config.h
@@ -35,14 +35,14 @@
 #ifndef __BOARD_CONFIG_H__
 #define __BOARD_CONFIG_H__
 
-#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1   /// Dev board suppports OQPSK modulation in 2.4GHz band.
+#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band.
 
 #ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
 #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
 #endif
 
 #ifndef RADIO_CONFIG_DMP_SUPPORT
-#define RADIO_CONFIG_DMP_SUPPORT 0            /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
+#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
 #endif
 
 #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg21/brd4180a/hal-config.h b/examples/platforms/efr32mg21/brd4180a/hal-config.h
index d467dfb..b74f973 100644
--- a/examples/platforms/efr32mg21/brd4180a/hal-config.h
+++ b/examples/platforms/efr32mg21/brd4180a/hal-config.h
@@ -36,18 +36,18 @@
 // [BUTTON]$
 
 // $[CMU]
-#define HAL_CLK_HFCLK_SOURCE                  (HAL_CLK_HFCLK_SOURCE_HFXO)
-#define BSP_CLK_LFXO_PRESENT                  (1)
-#define HAL_CLK_EM4CLK_SOURCE                 (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define HAL_CLK_EM23CLK_SOURCE                (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_HFXO_PRESENT                  (1)
-#define BSP_CLK_LFXO_INIT                     CMU_LFXOINIT_DEFAULT
-#define BSP_CLK_LFXO_CTUNE                    (79U)
-#define HAL_CLK_RTCCCLK_SOURCE                (HAL_CLK_LFCLK_SOURCE_LFRCO)
-#define BSP_CLK_LFXO_FREQ                     (32768U)
-#define BSP_CLK_HFXO_FREQ                     (38400000UL)
-#define BSP_CLK_HFXO_CTUNE                    (129)
-#define BSP_CLK_HFXO_INIT                     CMU_HFXOINIT_DEFAULT
+#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
+#define BSP_CLK_LFXO_PRESENT (1)
+#define HAL_CLK_EM4CLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define HAL_CLK_EM23CLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_HFXO_PRESENT (1)
+#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
+#define BSP_CLK_LFXO_CTUNE (79U)
+#define HAL_CLK_RTCCCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
+#define BSP_CLK_LFXO_FREQ (32768U)
+#define BSP_CLK_HFXO_FREQ (38400000UL)
+#define BSP_CLK_HFXO_CTUNE (129)
+#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
 // [CMU]$
 
 // $[COEX]
@@ -63,11 +63,11 @@
 // [EZRADIOPRO]$
 
 // $[GPIO]
-#define PORTIO_GPIO_SWV_PIN                   (3U)
-#define PORTIO_GPIO_SWV_PORT                  (gpioPortA)
+#define PORTIO_GPIO_SWV_PIN (3U)
+#define PORTIO_GPIO_SWV_PORT (gpioPortA)
 
-#define BSP_TRACE_SWO_PIN                     (3U)
-#define BSP_TRACE_SWO_PORT                    (gpioPortA)
+#define BSP_TRACE_SWO_PIN (3U)
+#define BSP_TRACE_SWO_PORT (gpioPortA)
 
 // [GPIO]$
 
@@ -87,19 +87,25 @@
 // [IOEXP]$
 
 // $[LED]
-#define BSP_LED_PRESENT                       (1)
+#define BSP_LED_PRESENT (1)
 
-#define BSP_LED0_PIN                          (0U)
-#define BSP_LED0_PORT                         (gpioPortB)
+#define BSP_LED0_PIN (0U)
+#define BSP_LED0_PORT (gpioPortB)
 
-#define BSP_LED1_PIN                          (1U)
-#define BSP_LED1_PORT                         (gpioPortB)
+#define BSP_LED1_PIN (1U)
+#define BSP_LED1_PORT (gpioPortB)
 
-#define HAL_LED_ENABLE                        { 0, 1 }
-#define BSP_LED_POLARITY                      (1)
-#define HAL_LED_COUNT                         (2U)
-#define BSP_LED_COUNT                         (2U)
-#define BSP_LED_INIT                          { { BSP_LED0_PORT, BSP_LED0_PIN }, { BSP_LED1_PORT, BSP_LED1_PIN } }
+#define HAL_LED_ENABLE \
+    {                  \
+        0, 1           \
+    }
+#define BSP_LED_POLARITY (1)
+#define HAL_LED_COUNT (2U)
+#define BSP_LED_COUNT (2U)
+#define BSP_LED_INIT                                                   \
+    {                                                                  \
+        {BSP_LED0_PORT, BSP_LED0_PIN}, { BSP_LED1_PORT, BSP_LED1_PIN } \
+    }
 // [LED]$
 
 // $[LETIMER0]
@@ -112,13 +118,13 @@
 // [MODEM]$
 
 // $[PA]
-#define HAL_PA_ENABLE                         (1)
+#define HAL_PA_ENABLE (1)
 
-#define HAL_PA_RAMP                           (10UL)
-#define HAL_PA_SELECTION                      (HAL_PA_SELECTION_2P4_HP)
-#define HAL_PA_POWER                          (252U)
-#define HAL_PA_VOLTAGE                        (3300U)
-#define HAL_PA_CURVE_HEADER                   "pa_curves_efr32.h"
+#define HAL_PA_RAMP (10UL)
+#define HAL_PA_SELECTION (HAL_PA_SELECTION_2P4_HP)
+#define HAL_PA_POWER (252U)
+#define HAL_PA_VOLTAGE (3300U)
+#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
 // [PA]$
 
 // $[PORTIO]
@@ -128,49 +134,49 @@
 // [PRS]$
 
 // $[PTI]
-#define PORTIO_PTI_DFRAME_PIN                 (5U)
-#define PORTIO_PTI_DFRAME_PORT                (gpioPortC)
+#define PORTIO_PTI_DFRAME_PIN (5U)
+#define PORTIO_PTI_DFRAME_PORT (gpioPortC)
 
-#define PORTIO_PTI_DOUT_PIN                   (4U)
-#define PORTIO_PTI_DOUT_PORT                  (gpioPortC)
+#define PORTIO_PTI_DOUT_PIN (4U)
+#define PORTIO_PTI_DOUT_PORT (gpioPortC)
 
-#define HAL_PTI_ENABLE                        (1)
+#define HAL_PTI_ENABLE (1)
 
-#define BSP_PTI_DFRAME_PIN                    (5U)
-#define BSP_PTI_DFRAME_PORT                   (gpioPortC)
+#define BSP_PTI_DFRAME_PIN (5U)
+#define BSP_PTI_DFRAME_PORT (gpioPortC)
 
-#define BSP_PTI_DOUT_PIN                      (4U)
-#define BSP_PTI_DOUT_PORT                     (gpioPortC)
+#define BSP_PTI_DOUT_PIN (4U)
+#define BSP_PTI_DOUT_PORT (gpioPortC)
 
-#define HAL_PTI_MODE                          (HAL_PTI_MODE_UART)
-#define HAL_PTI_BAUD_RATE                     (1600000UL)
+#define HAL_PTI_MODE (HAL_PTI_MODE_UART)
+#define HAL_PTI_BAUD_RATE (1600000UL)
 // [PTI]$
 
 // $[SERIAL]
-#define HAL_SERIAL_USART0_ENABLE              (0)
-#define HAL_SERIAL_LEUART0_ENABLE             (0)
-#define HAL_SERIAL_USART1_ENABLE              (0)
-#define HAL_SERIAL_USART2_ENABLE              (0)
-#define HAL_SERIAL_USART3_ENABLE              (0)
-#define HAL_SERIAL_RXWAKE_ENABLE              (0)
-#define BSP_SERIAL_APP_CTS_PIN                (4U)
-#define BSP_SERIAL_APP_CTS_PORT               (gpioPortA)
+#define HAL_SERIAL_USART0_ENABLE (0)
+#define HAL_SERIAL_LEUART0_ENABLE (0)
+#define HAL_SERIAL_USART1_ENABLE (0)
+#define HAL_SERIAL_USART2_ENABLE (0)
+#define HAL_SERIAL_USART3_ENABLE (0)
+#define HAL_SERIAL_RXWAKE_ENABLE (0)
+#define BSP_SERIAL_APP_CTS_PIN (4U)
+#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
 
-#define BSP_SERIAL_APP_RX_PIN                 (6U)
-#define BSP_SERIAL_APP_RX_PORT                (gpioPortA)
+#define BSP_SERIAL_APP_RX_PIN (6U)
+#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
 
-#define BSP_SERIAL_APP_TX_PIN                 (5U)
-#define BSP_SERIAL_APP_TX_PORT                (gpioPortA)
+#define BSP_SERIAL_APP_TX_PIN (5U)
+#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
 
-#define BSP_SERIAL_APP_RTS_PIN                (1U)
-#define BSP_SERIAL_APP_RTS_PORT               (gpioPortC)
+#define BSP_SERIAL_APP_RTS_PIN (1U)
+#define BSP_SERIAL_APP_RTS_PORT (gpioPortC)
 
-#define HAL_SERIAL_APP_RX_QUEUE_SIZE          (128UL)
-#define HAL_SERIAL_APP_BAUD_RATE              (115200UL)
-#define HAL_SERIAL_APP_RXSTOP                 (16UL)
-#define HAL_SERIAL_APP_RXSTART                (16UL)
-#define HAL_SERIAL_APP_TX_QUEUE_SIZE          (128UL)
-#define HAL_SERIAL_APP_FLOW_CONTROL           (HAL_USART_FLOW_CONTROL_HWUART)
+#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128UL)
+#define HAL_SERIAL_APP_BAUD_RATE (115200UL)
+#define HAL_SERIAL_APP_RXSTOP (16UL)
+#define HAL_SERIAL_APP_RXSTART (16UL)
+#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128UL)
+#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
 // [SERIAL]$
 
 // $[SPIDISPLAY]
@@ -195,38 +201,38 @@
 // [UARTNCP]$
 
 // $[USART0]
-#define PORTIO_USART0_CTS_PIN                 (4U)
-#define PORTIO_USART0_CTS_PORT                (gpioPortA)
+#define PORTIO_USART0_CTS_PIN (4U)
+#define PORTIO_USART0_CTS_PORT (gpioPortA)
 
-#define PORTIO_USART0_RTS_PIN                 (1U)
-#define PORTIO_USART0_RTS_PORT                (gpioPortC)
+#define PORTIO_USART0_RTS_PIN (1U)
+#define PORTIO_USART0_RTS_PORT (gpioPortC)
 
-#define PORTIO_USART0_RX_PIN                  (6U)
-#define PORTIO_USART0_RX_PORT                 (gpioPortA)
+#define PORTIO_USART0_RX_PIN (6U)
+#define PORTIO_USART0_RX_PORT (gpioPortA)
 
-#define PORTIO_USART0_TX_PIN                  (5U)
-#define PORTIO_USART0_TX_PORT                 (gpioPortA)
+#define PORTIO_USART0_TX_PIN (5U)
+#define PORTIO_USART0_TX_PORT (gpioPortA)
 
-#define HAL_USART0_ENABLE                     (1)
+#define HAL_USART0_ENABLE (1)
 
-#define BSP_USART0_CTS_PIN                    (4U)
-#define BSP_USART0_CTS_PORT                   (gpioPortA)
+#define BSP_USART0_CTS_PIN (4U)
+#define BSP_USART0_CTS_PORT (gpioPortA)
 
-#define BSP_USART0_RX_PIN                     (6U)
-#define BSP_USART0_RX_PORT                    (gpioPortA)
+#define BSP_USART0_RX_PIN (6U)
+#define BSP_USART0_RX_PORT (gpioPortA)
 
-#define BSP_USART0_TX_PIN                     (5U)
-#define BSP_USART0_TX_PORT                    (gpioPortA)
+#define BSP_USART0_TX_PIN (5U)
+#define BSP_USART0_TX_PORT (gpioPortA)
 
-#define BSP_USART0_RTS_PIN                    (1U)
-#define BSP_USART0_RTS_PORT                   (gpioPortC)
+#define BSP_USART0_RTS_PIN (1U)
+#define BSP_USART0_RTS_PORT (gpioPortC)
 
-#define HAL_USART0_RX_QUEUE_SIZE              (128UL)
-#define HAL_USART0_BAUD_RATE                  (115200UL)
-#define HAL_USART0_RXSTOP                     (16UL)
-#define HAL_USART0_RXSTART                    (16UL)
-#define HAL_USART0_TX_QUEUE_SIZE              (128UL)
-#define HAL_USART0_FLOW_CONTROL               (HAL_USART_FLOW_CONTROL_HWUART)
+#define HAL_USART0_RX_QUEUE_SIZE (128UL)
+#define HAL_USART0_BAUD_RATE (115200UL)
+#define HAL_USART0_RXSTOP (16UL)
+#define HAL_USART0_RXSTART (16UL)
+#define HAL_USART0_TX_QUEUE_SIZE (128UL)
+#define HAL_USART0_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
 // [USART0]$
 
 // $[USART1]
@@ -236,10 +242,10 @@
 // [USART2]$
 
 // $[VCOM]
-#define HAL_VCOM_ENABLE                       (1)
+#define HAL_VCOM_ENABLE (1)
 
-#define BSP_VCOM_ENABLE_PIN                   (4U)
-#define BSP_VCOM_ENABLE_PORT                  (gpioPortD)
+#define BSP_VCOM_ENABLE_PIN (4U)
+#define BSP_VCOM_ENABLE_PORT (gpioPortD)
 
 // [VCOM]$
 
@@ -247,7 +253,7 @@
 // [VUART]$
 
 // $[WDOG]
-#define HAL_WDOG_ENABLE                       (0)
+#define HAL_WDOG_ENABLE (0)
 
 // [WDOG]$
 
@@ -255,6 +261,4 @@
 #include "sl_module.h"
 #endif
 
-
 #endif /* HAL_CONFIG_H */
-
diff --git a/examples/platforms/efr32mg21/crypto/efr32-mbedtls-config.h b/examples/platforms/efr32mg21/crypto/efr32-mbedtls-config.h
index 28ec63e..d392df0 100644
--- a/examples/platforms/efr32mg21/crypto/efr32-mbedtls-config.h
+++ b/examples/platforms/efr32mg21/crypto/efr32-mbedtls-config.h
@@ -25,7 +25,7 @@
  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  *  POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
 #ifndef EFR32_MBEDTLS_CONFIG_H
 #define EFR32_MBEDTLS_CONFIG_H
 
@@ -52,53 +52,32 @@
  *
  */
 #define MBEDTLS_ENTROPY_HARDWARE_ALT
-#define MBEDTLS_SHA256_C
 
+/* Turn on all hardware acceleration provided by the EFR32xG21's built-in SE */
+#define MBEDTLS_SHA1_ALT
+#define MBEDTLS_SHA1_PROCESS_ALT
+#define MBEDTLS_SHA256_ALT
+#define MBEDTLS_SHA256_PROCESS_ALT
+#define MBEDTLS_SHA512_ALT
+#define MBEDTLS_SHA512_PROCESS_ALT
 
-/**
- * \def MBEDTLS_ECP_INTERNAL_ALT
- * \def ECP_SHORTWEIERSTRASS
- * \def MBEDTLS_ECP_ADD_MIXED_ALT
- * \def MBEDTLS_ECP_DOUBLE_JAC_ALT
- * \def MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
- * \def MBEDTLS_ECP_NORMALIZE_JAC_ALT
- *
- * Enable hardware acceleration for the elliptic curve over GF(p) library.
- *
- * Module:  sl_crypto/src/crypto_ecp.c
- * Caller:  library/ecp.c
- *
- * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_ECP_C and at least one
- * MBEDTLS_ECP_DP_XXX_ENABLED and (CRYPTO_COUNT > 0)
- */
-#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
-#define MBEDTLS_ECP_INTERNAL_ALT
-#define ECP_SHORTWEIERSTRASS
-#define MBEDTLS_ECP_ADD_MIXED_ALT
-#define MBEDTLS_ECP_DOUBLE_JAC_ALT
-#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
-#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
-#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
-#endif
+#define MBEDTLS_CCM_ALT
+#define MBEDTLS_CMAC_ALT
 
-/**
- * \def MBEDTLS_SHA256_ALT
- *
- * Enable hardware acceleration for the SHA-224 and SHA-256 cryptographic
- * hash algorithms.
- *
- * Module:  sl_crypto/src/crypto_sha.c
- * Caller:  library/entropy.c
- *          library/mbedtls_md.c
- *          library/ssl_cli.c
- *          library/ssl_srv.c
- *          library/ssl_tls.c
- *
- * Requires: MBEDTLS_SHA256_C and (CRYPTO_COUNT > 0)
- * See MBEDTLS_SHA256_C for more information.
- */
-#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
-//#define MBEDTLS_SHA256_ALT
-#endif
+/* Turning on ECC acceleration is dependant on not requiring curve25519 when
+ * running on EFR32xG21A devices */
+#if (defined(_SILICON_LABS_SECURITY_FEATURE) &&                                   \
+     (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)) || \
+    !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
+#define MBEDTLS_ECDSA_GENKEY_ALT
+#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
+#define MBEDTLS_ECDSA_SIGN_ALT
+#define MBEDTLS_ECDSA_VERIFY_ALT
+/* Incompatibility in header files between mbedTLS version in OT and GSDK means
+ * we can't turn on EC-JPAKE acceleration on EFR32xG21 just yet. Will be fixed
+ * for the next GSDK update */
+//#define MBEDTLS_ECJPAKE_ALT
+#endif /* EFR32xG21B or curve25519 not enabled */
 
 #endif // EFR32_MBEDTLS_CONFIG_H
diff --git a/examples/platforms/efr32mg21/diag.c b/examples/platforms/efr32mg21/diag.c
index 1d87bc3..d3fb43b 100644
--- a/examples/platforms/efr32mg21/diag.c
+++ b/examples/platforms/efr32mg21/diag.c
@@ -51,15 +51,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
-
-    // Add more platform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/efr32mg21/efr32mg21.ld b/examples/platforms/efr32mg21/efr32mg21.ld
new file mode 100644
index 0000000..3d877e8
--- /dev/null
+++ b/examples/platforms/efr32mg21/efr32mg21.ld
@@ -0,0 +1,246 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**
+ * @file
+ *   This file implements the OpenThread linker script for the
+ *   Silicon Labs efr32mg21 platform.
+ *
+ */
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1024K
+  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 96K
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __copy_table_start__
+ *   __copy_table_end__
+ *   __zero_table_start__
+ *   __zero_table_end__
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __Vectors_End
+ *   __Vectors_Size
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+  .text :
+  {
+    KEEP(*(.vectors))
+    __Vectors_End = .;
+    __Vectors_Size = __Vectors_End - __Vectors;
+    __end__ = .;
+
+    *(.text*)
+
+    KEEP(*(.init))
+    KEEP(*(.fini))
+
+    /* .ctors */
+    *crtbegin.o(.ctors)
+    *crtbegin?.o(.ctors)
+    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+    *(SORT(.ctors.*))
+    *(.ctors)
+
+    /* .dtors */
+    *crtbegin.o(.dtors)
+    *crtbegin?.o(.dtors)
+    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+    *(SORT(.dtors.*))
+    *(.dtors)
+
+    *(.rodata*)
+
+    KEEP(*(.eh_frame*))
+  } > FLASH
+
+  .ARM.extab :
+  {
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+  } > FLASH
+
+  __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } > FLASH
+  __exidx_end = .;
+
+  /* To copy multiple ROM to RAM sections,
+   * uncomment .copy.table section and,
+   * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
+  /*
+  .copy.table :
+  {
+    . = ALIGN(4);
+    __copy_table_start__ = .;
+    LONG (__etext)
+    LONG (__data_start__)
+    LONG (__data_end__ - __data_start__)
+    LONG (__etext2)
+    LONG (__data2_start__)
+    LONG (__data2_end__ - __data2_start__)
+    __copy_table_end__ = .;
+  } > FLASH
+  */
+
+  /* To clear multiple BSS sections,
+   * uncomment .zero.table section and,
+   * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
+  /*
+  .zero.table :
+  {
+    . = ALIGN(4);
+    __zero_table_start__ = .;
+    LONG (__bss_start__)
+    LONG (__bss_end__ - __bss_start__)
+    LONG (__bss2_start__)
+    LONG (__bss2_end__ - __bss2_start__)
+    __zero_table_end__ = .;
+  } > FLASH
+  */
+
+  __etext = .;
+
+  .data : AT (__etext)
+  {
+    __data_start__ = .;
+    *(vtable)
+    *(.data*)
+    . = ALIGN (4);
+    PROVIDE (__ram_func_section_start = .);
+    *(.ram)
+    PROVIDE (__ram_func_section_end = .);
+
+    . = ALIGN(4);
+    /* preinit data */
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP(*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+
+    . = ALIGN(4);
+    /* init data */
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP(*(SORT(.init_array.*)))
+    KEEP(*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+
+    . = ALIGN(4);
+    /* finit data */
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP(*(SORT(.fini_array.*)))
+    KEEP(*(.fini_array))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+
+    KEEP(*(.jcr*))
+    . = ALIGN(4);
+    /* All data end */
+    __data_end__ = .;
+
+  } > RAM
+
+  .bss :
+  {
+    . = ALIGN(4);
+    __bss_start__ = .;
+    *(.bss*)
+    *(COMMON)
+    . = ALIGN(4);
+    __bss_end__ = .;
+  } > RAM
+
+  .heap (COPY):
+  {
+    __HeapBase = .;
+    __end__ = .;
+    end = __end__;
+    _end = __end__;
+    KEEP(*(.heap*))
+    __HeapLimit = .;
+  } > RAM
+
+  /* .stack_dummy section doesn't contains any symbols. It is only
+   * used for linker to calculate size of stack sections, and assign
+   * values to stack symbols later */
+  .stack_dummy (COPY):
+  {
+    KEEP(*(.stack*))
+  } > RAM
+
+  /* Set stack top to end of RAM, and stack limit move down by
+   * size of stack_dummy section */
+  __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+  PROVIDE(__stack = __StackTop);
+
+  /*******************************************************************/
+  /* Define flash block for nvm3                                     */
+  .nvm (DSECT) : {
+    KEEP(*(.simee*))
+  } > FLASH
+
+  linker_nvm_end = ORIGIN(FLASH) + LENGTH(FLASH);
+  linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm);
+  linker_nvm_size = SIZEOF(.nvm);
+  __nvm3Base = linker_nvm_begin;
+  /*******************************************************************/
+
+  /* Check if data + heap + stack exceeds RAM limit */
+  ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+
+  /* Check if FLASH usage exceeds FLASH size */
+  /*ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")*/
+}
\ No newline at end of file
diff --git a/examples/platforms/efr32mg21/flash.c b/examples/platforms/efr32mg21/flash.c
index 38bfb31..15d46ea 100644
--- a/examples/platforms/efr32mg21/flash.c
+++ b/examples/platforms/efr32mg21/flash.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2019, The OpenThread Authors.
+ *  Copyright (c) 2020, The OpenThread Authors.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -31,114 +31,334 @@
  *   This file implements the OpenThread platform abstraction for the non-volatile storage.
  */
 
-#include <openthread-core-config.h>
-
+#include "openthread-core-efr32-config.h"
 #include <openthread/config.h>
-#include <openthread/platform/alarm-milli.h>
 
-#include "utils/code_utils.h"
-#include "utils/flash.h"
+#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE // Use OT NV system
 
 #include "em_msc.h"
+#include <string.h>
+#include <openthread/instance.h>
 
-// clang-format off
-#define FLASH_DATA_END_ADDR     (FLASH_BASE + FLASH_SIZE)
-#define FLASH_DATA_START_ADDR   (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM))
-// clang-format on
+#define FLASH_PAGE_NUM 2
+#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
+#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * FLASH_PAGE_NUM))
+#define FLASH_SWAP_PAGE_NUM (FLASH_PAGE_NUM / 2)
+#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * FLASH_SWAP_PAGE_NUM)
 
-static inline uint32_t mapAddress(uint32_t aAddress)
+static inline uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    return aAddress + FLASH_DATA_START_ADDR;
+    uint32_t address;
+
+    address = FLASH_DATA_START_ADDR + aOffset;
+
+    if (aSwapIndex)
+    {
+        address += FLASH_SWAP_SIZE;
+    }
+
+    return address;
 }
 
-static otError returnTypeConvert(int32_t aStatus)
+void otPlatFlashInit(otInstance *aInstance)
 {
-    otError error = OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
+}
 
-    switch (aStatus)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return FLASH_SWAP_SIZE;
+}
+
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address = mapAddress(aSwapIndex, 0);
+
+    for (uint32_t n = 0; n < FLASH_SWAP_PAGE_NUM; n++, address += FLASH_PAGE_SIZE)
     {
-    case mscReturnOk:
-        error = OT_ERROR_NONE;
+        MSC_ErasePage((uint32_t *)address);
+    }
+}
+
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    MSC_WriteWord((uint32_t *)mapAddress(aSwapIndex, aOffset), aData, aSize);
+}
+
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    memcpy(aData, (const uint8_t *)mapAddress(aSwapIndex, aOffset), aSize);
+}
+
+#else // Defaults to Silabs nvm3 system
+
+#include "nvm3.h"
+#include "nvm3_default.h"
+#include <string.h>
+#include <openthread/platform/settings.h>
+#include "common/code_utils.hpp"
+#include "common/logging.hpp"
+
+#define NVM3KEY_DOMAIN_OPENTHREAD 0x20000U
+#define NUM_INDEXED_SETTINGS \
+    OPENTHREAD_CONFIG_MLE_MAX_CHILDREN // Indexed key types are only supported for kKeyChildInfo (=='child table').
+#define ENUM_NVM3_KEY_LIST_SIZE 4      // List size used when enumerating nvm3 keys.
+
+static otError          addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
+static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index);
+static otError          mapNvm3Error(Ecode_t nvm3Res);
+
+void otPlatSettingsInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    if (mapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)) != OT_ERROR_NONE)
+    {
+        otLogDebgPlat("Error initializing nvm3 instance");
+    }
+}
+
+void otPlatSettingsDeinit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    nvm3_close(nvm3_defaultHandle);
+}
+
+otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
+{
+    // Searches through all matching nvm3 keys to find the one with the required
+    // 'index', then reads the nvm3 data into the destination buffer.
+    // (Repeatedly enumerates a list of matching keys from the nvm3 until the
+    // required index is found).
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError  err;
+    uint16_t valueLength = 0;
+
+    nvm3_ObjectKey_t nvm3Key  = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
+    bool             idxFound = false;
+    int              idx      = 0;
+    err                       = OT_ERROR_NOT_FOUND;
+    while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
+    {
+        // Get the next nvm3 key list.
+        nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
+        size_t           objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, nvm3Key,
+                                         makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
+        for (size_t i = 0; i < objCnt; ++i)
+        {
+            nvm3Key = keys[i];
+            if (idx == aIndex)
+            {
+                uint32_t objType;
+                size_t   objLen;
+                err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+                if (err == OT_ERROR_NONE)
+                {
+                    valueLength = objLen;
+
+                    // Only perform read if an input buffer was passed in.
+                    if ((aValue != NULL) && (aValueLength != NULL))
+                    {
+                        // Read all nvm3 obj bytes into a tmp buffer, then copy the required
+                        // number of bytes to the read destination buffer.
+                        uint8_t *buf = malloc(valueLength);
+                        err          = mapNvm3Error(nvm3_readData(nvm3_defaultHandle, nvm3Key, buf, valueLength));
+                        if (err == OT_ERROR_NONE)
+                        {
+                            memcpy(aValue, buf, (valueLength < *aValueLength) ? valueLength : *aValueLength);
+                        }
+                        free(buf);
+                        SuccessOrExit(err);
+                    }
+                }
+                idxFound = true;
+                break;
+            }
+            ++idx;
+        }
+        if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
+        {
+            // Stop searching (there are no more matching nvm3 objects).
+            break;
+        }
+        ++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
+    }
+
+exit:
+    if (aValueLength != NULL)
+    {
+        *aValueLength = valueLength; // always return actual nvm3 object length.
+    }
+
+    return err;
+}
+
+otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError err;
+
+    // Delete all nvm3 objects matching the input key (i.e. the 'setting indexes' of the key).
+    err = otPlatSettingsDelete(aInstance, aKey, -1);
+    if ((err == OT_ERROR_NONE) || (err == OT_ERROR_NOT_FOUND))
+    {
+        // Add new setting object (i.e. 'index0' of the key).
+        err = addSetting(aKey, aValue, aValueLength);
+        SuccessOrExit(err);
+    }
+
+exit:
+    return err;
+}
+
+otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return addSetting(aKey, aValue, aValueLength);
+}
+
+otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
+{
+    // Searches through all matching nvm3 keys to find the one with the required
+    // 'index' (or index = -1 to delete all), then deletes the nvm3 object.
+    // (Repeatedly enumerates a list of matching keys from the nvm3 until the
+    // required index is found).
+
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError          err;
+    nvm3_ObjectKey_t nvm3Key  = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
+    bool             idxFound = false;
+    int              idx      = 0;
+    err                       = OT_ERROR_NOT_FOUND;
+    while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
+    {
+        // Get the next nvm3 key list.
+        nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
+        size_t           objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, nvm3Key,
+                                         makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
+        for (size_t i = 0; i < objCnt; ++i)
+        {
+            nvm3Key = keys[i];
+            if ((idx == aIndex) || (aIndex == -1))
+            {
+                uint32_t objType;
+                size_t   objLen;
+                err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+                if (err == OT_ERROR_NONE)
+                {
+                    // Delete the nvm3 object.
+                    err = mapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, nvm3Key));
+                    SuccessOrExit(err);
+                }
+                if (aIndex != -1)
+                {
+                    idxFound = true;
+                    break;
+                }
+            }
+            ++idx;
+        }
+        if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
+        {
+            // Stop searching (there are no more matching nvm3 objects).
+            break;
+        }
+        ++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
+    }
+
+exit:
+    return err;
+}
+
+void otPlatSettingsWipe(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    // Delete nvm3 objects for all OT Settings keys (and any of their associated 'indexes').
+    // Note- any OT User nvm3 objects in the OT nvm3 area are NOT be erased.
+    for (uint16_t aKey = 0; aKey < 8; ++aKey)
+    {
+        otPlatSettingsDelete(NULL, aKey, -1);
+    }
+}
+
+// Local functions..
+
+static otError addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    // Helper function- writes input buffer data to a NEW nvm3 object.
+    // nvm3 object is created at the first available Key + index.
+
+    otError err;
+
+    if ((aValueLength == 0) || (aValue == NULL))
+    {
+        err = OT_ERROR_INVALID_ARGS;
+    }
+    else
+    {
+        for (int idx = 0; idx <= NUM_INDEXED_SETTINGS; ++idx)
+        {
+            nvm3_ObjectKey_t nvm3Key;
+            nvm3Key = makeNvm3ObjKey(aKey, idx);
+
+            uint32_t objType;
+            size_t   objLen;
+            err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
+            if (err == OT_ERROR_NOT_FOUND)
+            {
+                // Use this index for the new nvm3 object.
+                // Write the binary data to nvm3 (Creates nvm3 object if required).
+                err = mapNvm3Error(nvm3_writeData(nvm3_defaultHandle, nvm3Key, aValue, aValueLength));
+                break;
+            }
+            else if (err != OT_ERROR_NONE)
+            {
+                break;
+            }
+        }
+    }
+
+    return err;
+}
+
+static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index)
+{
+    return (NVM3KEY_DOMAIN_OPENTHREAD | (otSettingsKey << 8) | (index & 0xFF));
+}
+
+static otError mapNvm3Error(Ecode_t nvm3Res)
+{
+    otError err;
+
+    switch (nvm3Res)
+    {
+    case ECODE_NVM3_OK:
+        err = OT_ERROR_NONE;
         break;
 
-    case mscReturnInvalidAddr:
-    case mscReturnUnaligned:
-        error = OT_ERROR_INVALID_ARGS;
+    case ECODE_NVM3_ERR_KEY_NOT_FOUND:
+        err = OT_ERROR_NOT_FOUND;
         break;
 
     default:
-        error = OT_ERROR_FAILED;
+        err = OT_ERROR_FAILED;
+        break;
     }
 
-    return error;
+    return err;
 }
 
-otError utilsFlashInit(void)
-{
-    MSC_Init();
-    return OT_ERROR_NONE;
-}
-
-uint32_t utilsFlashGetSize(void)
-{
-    return FLASH_DATA_END_ADDR - FLASH_DATA_START_ADDR;
-}
-
-otError utilsFlashErasePage(uint32_t aAddress)
-{
-    int32_t status;
-
-    status = MSC_ErasePage((uint32_t *)mapAddress(aAddress));
-
-    return returnTypeConvert(status);
-}
-
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    otError  error = OT_ERROR_BUSY;
-    uint32_t start = otPlatAlarmMilliGetNow();
-
-    do
-    {
-        if (MSC->STATUS & MSC_STATUS_WDATAREADY)
-        {
-            error = OT_ERROR_NONE;
-            break;
-        }
-    } while (aTimeout && ((otPlatAlarmMilliGetNow() - start) < aTimeout));
-
-    return error;
-}
-
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t rval = aSize;
-    int32_t  status;
-
-    otEXPECT_ACTION(aData, rval = 0);
-    otEXPECT_ACTION(((aAddress + aSize) < utilsFlashGetSize()) && (!(aAddress & 3)) && (!(aSize & 3)), rval = 0);
-
-    status = MSC_WriteWord((uint32_t *)mapAddress(aAddress), aData, aSize);
-    otEXPECT_ACTION(returnTypeConvert(status) == OT_ERROR_NONE, rval = 0);
-
-exit:
-    return rval;
-}
-
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t rval     = aSize;
-    uint32_t pAddress = mapAddress(aAddress);
-    uint8_t *byte     = aData;
-
-    otEXPECT_ACTION(aData, rval = 0);
-    otEXPECT_ACTION((aAddress + aSize) < utilsFlashGetSize(), rval = 0);
-
-    while (aSize--)
-    {
-        *byte++ = (*(uint8_t *)(pAddress++));
-    }
-
-exit:
-    return rval;
-}
+#endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
diff --git a/examples/platforms/efr32mg21/logging.c b/examples/platforms/efr32mg21/logging.c
index d035ca3..a6fdbba 100644
--- a/examples/platforms/efr32mg21/logging.c
+++ b/examples/platforms/efr32mg21/logging.c
@@ -39,8 +39,7 @@
 
 #include <utils/logging_rtt.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 void efr32LogInit(void)
 {
     utilsLogRttInit();
diff --git a/examples/platforms/efr32mg21/openthread-core-efr32-config.h b/examples/platforms/efr32mg21/openthread-core-efr32-config.h
index 95bead1..a4e53d4 100644
--- a/examples/platforms/efr32mg21/openthread-core-efr32-config.h
+++ b/examples/platforms/efr32mg21/openthread-core-efr32-config.h
@@ -77,52 +77,46 @@
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32"
 
 /*
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
  *
  * Define to 1 if you want to enable software energy scanning logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 1
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of settings.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
  *
  */
-#define SETTINGS_CONFIG_BASE_ADDRESS 0
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_SIZE FLASH_PAGE_SIZE
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_NUM 4
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
 
 /**
  * @def RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
diff --git a/examples/platforms/efr32mg21/radio.c b/examples/platforms/efr32mg21/radio.c
index badb76b..60e4dbe 100644
--- a/examples/platforms/efr32mg21/radio.c
+++ b/examples/platforms/efr32mg21/radio.c
@@ -756,7 +756,7 @@
         else
 #endif
         {
-            // signal MAC layer for each received frame if promiscous is enabled
+            // signal MAC layer for each received frame if promiscuous is enabled
             // otherwise only signal MAC layer for non-ACK frame
             if (sPromiscuous || sReceiveFrame.mLength > IEEE802154_ACK_LENGTH)
             {
@@ -949,6 +949,10 @@
 
 void efr32RadioProcess(otInstance *aInstance)
 {
+    // We should process the received packet first. Adding it at the end of this function,
+    // will delay the stack notification until the next call to efr32RadioProcess()
+    processNextRxPacket(aInstance, sRxBandConfig->mRailHandle);
+
     if (sState == OT_RADIO_STATE_TRANSMIT && sTransmitBusy == false)
     {
         if (sTransmitError != OT_ERROR_NONE)
@@ -989,8 +993,6 @@
         sRailDebugCounters.mRailEventEnergyScanCompleted++;
 #endif
     }
-
-    processNextRxPacket(aInstance, sRxBandConfig->mRailHandle);
 }
 
 otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
diff --git a/examples/platforms/efr32mg21/sleepy-demo/Makefile.am b/examples/platforms/efr32mg21/sleepy-demo/Makefile.am
index e9ff42f..5404255 100644
--- a/examples/platforms/efr32mg21/sleepy-demo/Makefile.am
+++ b/examples/platforms/efr32mg21/sleepy-demo/Makefile.am
@@ -44,11 +44,4 @@
 SUBDIRS                                += sleepy-demo-mtd sleepy-demo-ftd
 endif
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    sleepy-demo-mtd                       \
-    sleepy-demo-ftd                       \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/efr32mg21/sleepy-demo/README.md b/examples/platforms/efr32mg21/sleepy-demo/README.md
index 2e91c77..462cc9f 100644
--- a/examples/platforms/efr32mg21/sleepy-demo/README.md
+++ b/examples/platforms/efr32mg21/sleepy-demo/README.md
@@ -1,13 +1,9 @@
-
 # EFR32MG21 Sleepy Demo Example
 
-The EFR32 Sleepy applications demonstrates Sleepy End Device behaviour using
-the EFR32's low power EM2 mode. The steps below will take you through the
-process of building and running the demo
+The EFR32 Sleepy applications demonstrates Sleepy End Device behavior using the EFR32's low power EM2 mode. The steps below will take you through the process of building and running the demo
 
 For setting up the build environment refer to [examples/platforms/efr32mg21/README.md](../README.md).
 
-
 ## 1. Build
 
 ```bash
@@ -24,18 +20,13 @@
 $ arm-none-eabi-objcopy -O srec sleepy-demo-ftd sleepy-demo-ftd.s37
 ```
 
-In Silicon Labs Simplicity Studio flash one device with the sleepy-demo-mtd.s37
-image and the other device with the sleepy-demo-ftd.s37 image.
+In Silicon Labs Simplicity Studio flash one device with the sleepy-demo-mtd.s37 image and the other device with the sleepy-demo-ftd.s37 image.
 
 For instructions on flashing firmware see [examples/platforms/efr32mg21/README.md](../README.md#flash-binaries)
 
-
 ## 2. Starting nodes
 
-For demonstration purposes the network settings are hardcoded within the source files.
-The devices start Thread and form a network within a few seconds of powering on. In a real-life
-application the devices should implement and go through a commissioning process to create
-a network and add devices.
+For demonstration purposes the network settings are hardcoded within the source files. The devices start Thread and form a network within a few seconds of powering on. In a real-life application the devices should implement and go through a commissioning process to create a network and add devices.
 
 When the sleepy-demo-ftd device is started in the CLI the user shall see:
 
@@ -44,8 +35,7 @@
 sleepy-demo-ftd changed to leader
 ```
 
-When the sleepy-demo-mtd device starts it joins the preconfigured Thread network
-before disabling Rx-On-Idle to become a Sleepy-End-Device.
+When the sleepy-demo-mtd device starts it joins the pre-configured Thread network before disabling Rx-On-Idle to become a Sleepy-End-Device.
 
 Use the command "child table" in the FTD console and observe the R flag of the child is 0.
 
@@ -58,30 +48,18 @@
 Done
 ```
 
+## 3. MTD behavior on wake-up
 
-## 3. MTD behaviour on wakeup
-
-MTD wakes up every 5 seconds and sends a multicast UDP message containing the
-string "mtd is awake".  The FTD listens on the multicast address and will toggle
-LED 0 and display a message in the CLI showing "Message Received: mtd is awake".
+MTD wakes up every 5 seconds and sends a multicast UDP message containing the string "mtd is awake". The FTD listens on the multicast address and will toggle LED 0 and display a message in the CLI showing "Message Received: mtd is awake".
 
 ## 4. Monitoring power consumption of the MTD
 
-Open the Energy Profiler within Silicon Labs Simplicity Studio.  Within the Quick Access menu
-select Start Energy Capture... and select the MTD device.  When operating as a Sleepy End Device
-with no LEDs on the current should be under 20-80 microamps with occassional spikes during waking
-and polling the parent.  With the LED on the MTD has a current consumption of approximately 1mA.
+Open the Energy Profiler within Silicon Labs Simplicity Studio. Within the Quick Access menu select Start Energy Capture... and select the MTD device. When operating as a Sleepy End Device with no LEDs on the current should be under 20-80 microamps with occasional spikes during waking and polling the parent. With the LED on the MTD has a current consumption of approximately 1mA.
 
-When operating as a Minial End Device with the Rx on Idle observe that the current is in the order
-of 10ma.
+When operating as a Minimal End Device with the Rx on Idle observe that the current is in the order of 10ma.
 
-With further configuration of GPIOs and peripherals it is possible to reduce the sleepy current
-consumption further.
+With further configuration of GPIOs and peripherals it is possible to reduce the sleepy current consumption further.
 
 ## 5. Notes on sleeping, sleepy callback and interrupts
 
-To allow the EFR32 to enter sleepy mode the application must register a callback with efr32SetSleepCallback.
-The return value of callback is used to indicate that the application has no further work to do and that
-it is safe to go into a low power mode.  The callback is called with interrupts disabled so should do
-the minimum required to check if it can sleep.
-
+To allow the EFR32 to enter sleepy mode the application must register a callback with efr32SetSleepCallback. The return value of callback is used to indicate that the application has no further work to do and that it is safe to go into a low power mode. The callback is called with interrupts disabled so should do the minimum required to check if it can sleep.
diff --git a/examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-ftd/main.c b/examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-ftd/main.c
index b45e132..e54fe82 100644
--- a/examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-ftd/main.c
+++ b/examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-ftd/main.c
@@ -237,10 +237,10 @@
         return;
     }
 
-    error = otUdpBind(&sFtdSocket, &sockaddr);
+    error = otUdpBind(instance, &sFtdSocket, &sockaddr);
     if (error != OT_ERROR_NONE)
     {
-        otUdpClose(&sFtdSocket);
+        otUdpClose(instance, &sFtdSocket);
         otCliOutputFormat("FTD failed to bind udp multicast\r\n");
         return;
     }
@@ -277,7 +277,7 @@
 
                 if (error == OT_ERROR_NONE)
                 {
-                    error = otUdpSend(&sFtdSocket, message, &messageInfo);
+                    error = otUdpSend(instance, &sFtdSocket, message, &messageInfo);
 
                     if (error == OT_ERROR_NONE)
                     {
diff --git a/examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-mtd/main.c b/examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-mtd/main.c
index 4c3e842..ebb3169 100644
--- a/examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-mtd/main.c
+++ b/examples/platforms/efr32mg21/sleepy-demo/sleepy-demo-mtd/main.c
@@ -295,11 +295,11 @@
         return;
     }
 
-    error = otUdpBind(&sMtdSocket, &sockaddr);
+    error = otUdpBind(instance, &sMtdSocket, &sockaddr);
 
     if (error != OT_ERROR_NONE)
     {
-        otUdpClose(&sMtdSocket);
+        otUdpClose(instance, &sMtdSocket);
         return;
     }
 }
@@ -351,7 +351,7 @@
 
             if (error == OT_ERROR_NONE)
             {
-                error = otUdpSend(&sMtdSocket, message, &messageInfo);
+                error = otUdpSend(instance, &sMtdSocket, message, &messageInfo);
 
                 if (error == OT_ERROR_NONE)
                 {
diff --git a/examples/platforms/efr32mg21/system.c b/examples/platforms/efr32mg21/system.c
index ec5a37c..58bf86a 100644
--- a/examples/platforms/efr32mg21/system.c
+++ b/examples/platforms/efr32mg21/system.c
@@ -59,9 +59,7 @@
 #include "fem-control.h"
 #endif
 
-#define USE_EFR32_LOG                                                                   \
-    ((OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-     (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL))
+#define USE_EFR32_LOG (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 
 void halInitChipSpecific(void);
 
diff --git a/examples/platforms/gp712/Makefile.am b/examples/platforms/gp712/Makefile.am
index 6731973..9009d46 100644
--- a/examples/platforms/gp712/Makefile.am
+++ b/examples/platforms/gp712/Makefile.am
@@ -28,6 +28,10 @@
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
 
+# Do not enable -Wcast-align for this platform
+override CFLAGS    := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS  := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 lib_LIBRARIES                             = libopenthread-gp712.a
 
 libopenthread_gp712_a_CPPFLAGS            = \
@@ -65,10 +69,6 @@
     $(PLATFORM_SOURCES)                     \
     $(NULL)
 
-PRETTY_FILES                              = \
-    $(PLATFORM_SOURCES)                     \
-    $(NULL)
-
 if OPENTHREAD_BUILD_COVERAGE
 CLEANFILES                                = $(wildcard *.gcda *.gcno)
 endif # OPENTHREAD_BUILD_COVERAGE
diff --git a/examples/platforms/gp712/README.md b/examples/platforms/gp712/README.md
index 67edc4e..aa9a058 100644
--- a/examples/platforms/gp712/README.md
+++ b/examples/platforms/gp712/README.md
@@ -4,15 +4,16 @@
 
 ## Toolchain
 
-This example use the GNU GCC toolchain on the Raspberry Pi.
-To build on the Pi:
-1) Download the repo to the Pi
-2) go to the subfolder in the openthread repo: third_party/nlbuild-autotools/repo/tools/packages and enter this command:
+This example use the GNU GCC toolchain on the Raspberry Pi. To build on the Pi:
+
+1. Download the repo to the Pi
+2. go to the subfolder in the openthread repo: third_party/nlbuild-autotools/repo/tools/packages and enter this command:
+
 ```bash
 $ sudo /bin/bash build
 ```
-Note that you may need to install additional packages to make this build work, depending on your actual RPi OS version.
-The build process will complain if additional packages are required.
+
+Note that you may need to install additional packages to make this build work, depending on your actual RPi OS version. The build process will complain if additional packages are required.
 
 ## Build Examples
 
@@ -23,8 +24,7 @@
 $ REFERENCE_DEVICE=1 CLI_LOGGING=1 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 BORDER_ROUTER=1 make -f examples/Makefile-gp712
 ```
 
-After a successful build, the `elf` files are found in
-`<path-to-openthread>/output/gp712/bin`.
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/gp712/bin`.
 
 Building a variant which interfaces via a tcp socket is also possible. Replace the uart-posix.c with uart-socket.c in the Makefile.am from examples/platforms/gp712/Makefile.am and rebuild. Now it should be possible to open a telnet to socket 9190 of the raspberry pi from a remote PC. This also easier testing with the official Thread Test Harness.
 
diff --git a/examples/platforms/gp712/diag.c b/examples/platforms/gp712/diag.c
index 75132c1..45b933e 100644
--- a/examples/platforms/gp712/diag.c
+++ b/examples/platforms/gp712/diag.c
@@ -43,15 +43,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
-
-    // Add more platform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/gp712/flash.c b/examples/platforms/gp712/flash.c
index e1b95dd..1d94a9b 100644
--- a/examples/platforms/gp712/flash.c
+++ b/examples/platforms/gp712/flash.c
@@ -30,6 +30,7 @@
 
 #include "platform_qorvo.h"
 
+#include <assert.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -38,20 +39,18 @@
 #include <unistd.h>
 
 #include <openthread/config.h>
+#include <openthread/platform/flash.h>
 
-#include "utils/code_utils.h"
-#include "utils/flash.h"
+static int sFlashFd = -1;
 
-static int sFlashFd;
-uint32_t   sEraseAddress;
-
-#define FLASH_SIZE 0x40000
-#define FLASH_PAGE_SIZE 0x800
-#define FLASH_PAGE_NUM 128
-
-otError utilsFlashInit(void)
+enum
 {
-    otError     error = OT_ERROR_NONE;
+    SWAP_SIZE = 2048,
+    SWAP_NUM  = 2,
+};
+
+void otPlatFlashInit(otInstance *aInstance)
+{
     char        fileName[20];
     struct stat st;
     bool        create = false;
@@ -70,89 +69,80 @@
         create = true;
     }
 
-    sFlashFd = open(fileName, O_RDWR | O_CREAT, 0666);
+    sFlashFd = open(fileName, O_RDWR | O_CREAT, 0600);
     lseek(sFlashFd, 0, SEEK_SET);
 
-    otEXPECT_ACTION(sFlashFd >= 0, error = OT_ERROR_FAILED);
+    assert(sFlashFd >= 0);
 
     if (create)
     {
-        for (uint16_t index = 0; index < FLASH_PAGE_NUM; index++)
+        for (uint8_t index = 0; index < SWAP_NUM; index++)
         {
-            error = utilsFlashErasePage(index * FLASH_PAGE_SIZE);
-            otEXPECT(error == OT_ERROR_NONE);
+            otPlatFlashErase(aInstance, index);
         }
     }
-
-exit:
-    return error;
 }
 
-uint32_t utilsFlashGetSize(void)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
 {
-    return FLASH_SIZE;
+    OT_UNUSED_VARIABLE(aInstance);
+    return SWAP_SIZE;
 }
 
-otError utilsFlashErasePage(uint32_t aAddress)
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
 {
-    otError  error = OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
     uint32_t address;
-    uint8_t  dummyPage[FLASH_SIZE];
+    uint8_t  buffer[SWAP_SIZE];
     ssize_t  r;
 
-    otEXPECT_ACTION(sFlashFd >= 0, error = OT_ERROR_FAILED);
-    otEXPECT_ACTION(aAddress < FLASH_SIZE, error = OT_ERROR_INVALID_ARGS);
+    assert((sFlashFd) >= 0 && (aSwapIndex < SWAP_NUM));
 
-    // Get start address of the flash page that includes aAddress
-    address = aAddress & (~(uint32_t)(FLASH_PAGE_SIZE - 1));
-
-    // set the page to the erased state.
-    memset((void *)(&dummyPage[0]), 0xff, FLASH_PAGE_SIZE);
+    address = aSwapIndex ? SWAP_SIZE : 0;
+    memset(buffer, 0xff, sizeof(buffer));
 
     // Write the page
-    r = pwrite(sFlashFd, &(dummyPage[0]), FLASH_PAGE_SIZE, (off_t)address);
-    otEXPECT_ACTION((r) == ((FLASH_PAGE_SIZE)), error = OT_ERROR_FAILED);
-
-exit:
-    return error;
+    r = pwrite(sFlashFd, buffer, sizeof(buffer), (off_t)address);
+    assert(r == SWAP_SIZE);
 }
 
-otError utilsFlashStatusWait(uint32_t aTimeout)
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
 {
-    OT_UNUSED_VARIABLE(aTimeout);
+    OT_UNUSED_VARIABLE(aInstance);
 
-    return OT_ERROR_NONE;
+    uint32_t address;
+    ssize_t  rval;
+
+    assert((sFlashFd >= 0) && (aSwapIndex < SWAP_NUM) && (aSize <= SWAP_SIZE) && (aOffset <= (SWAP_SIZE - aSize)));
+
+    address = aSwapIndex ? SWAP_SIZE : 0;
+
+    rval = pread(sFlashFd, aData, aSize, (off_t)(address + aOffset));
+    assert((uint32_t)rval == aSize);
 }
 
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
 {
-    uint32_t ret   = 0;
-    uint32_t index = 0;
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address;
     uint8_t  byte;
+    ssize_t  rval;
 
-    otEXPECT(sFlashFd >= 0 && aAddress < FLASH_SIZE);
+    assert((sFlashFd >= 0) && (aSwapIndex < SWAP_NUM) && (aSize <= SWAP_SIZE) && (aOffset <= (SWAP_SIZE - aSize)));
 
-    for (index = 0; index < aSize; index++)
+    address = aSwapIndex ? SWAP_SIZE : 0;
+    address += aOffset;
+
+    for (uint32_t offset = 0; offset < aSize; offset++)
     {
-        ret = utilsFlashRead(aAddress + index, &byte, 1);
-        otEXPECT(ret == 1);
+        rval = pread(sFlashFd, &byte, sizeof(byte), (off_t)(address + offset));
+        assert(rval == sizeof(byte));
+
         // Use bitwise AND to emulate the behavior of flash memory
-        byte &= aData[index];
-        ret = (uint32_t)pwrite(sFlashFd, &byte, 1, (off_t)(aAddress + index));
-        otEXPECT(ret == 1);
+        byte &= ((uint8_t *)aData)[offset];
+
+        rval = pwrite(sFlashFd, &byte, sizeof(byte), (off_t)(address + offset));
+        assert(rval == sizeof(byte));
     }
-
-exit:
-    return index;
-}
-
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t ret = 0;
-
-    otEXPECT(sFlashFd >= 0 && aAddress < FLASH_SIZE);
-    ret = (uint32_t)pread(sFlashFd, aData, aSize, (off_t)aAddress);
-
-exit:
-    return ret;
 }
diff --git a/examples/platforms/gp712/logging.c b/examples/platforms/gp712/logging.c
index 5538a8e..6e8d1f7 100644
--- a/examples/platforms/gp712/logging.c
+++ b/examples/platforms/gp712/logging.c
@@ -51,8 +51,7 @@
     offset += (unsigned int)charsWritten;                                                 \
     otEXPECT_ACTION(offset < sizeof(logString), logString[sizeof(logString) - 1] = 0)
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 
 int PlatOtLogLevelToSysLogLevel(otLogLevel aLogLevel)
 {
diff --git a/examples/platforms/gp712/openthread-core-gp712-config.h b/examples/platforms/gp712/openthread-core-gp712-config.h
index 5fd0a9a..e71718f 100644
--- a/examples/platforms/gp712/openthread-core-gp712-config.h
+++ b/examples/platforms/gp712/openthread-core-gp712-config.h
@@ -42,4 +42,15 @@
  */
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "GP712"
 
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_INFO
+ *
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs
+ * instead of the otPlatSettings*
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
+
 #endif // OPENTHREAD_CORE_GP712_CONFIG_H_
diff --git a/examples/platforms/gp712/radio.c b/examples/platforms/gp712/radio.c
index f10b5f8..faa5c65 100644
--- a/examples/platforms/gp712/radio.c
+++ b/examples/platforms/gp712/radio.c
@@ -274,7 +274,7 @@
     qorvoRadioEnableSrcMatch(aEnable);
 }
 
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -288,7 +288,7 @@
     return qorvoRadioAddSrcMatchExtEntry(aExtAddress->m8, otCachedSettings.panid);
 }
 
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
diff --git a/examples/platforms/gp712/radio_qorvo.h b/examples/platforms/gp712/radio_qorvo.h
index 91144ef..0749ee1 100644
--- a/examples/platforms/gp712/radio_qorvo.h
+++ b/examples/platforms/gp712/radio_qorvo.h
@@ -144,7 +144,7 @@
  * @param[in]  panid          The panid.
  *
  */
-otError qorvoRadioAddSrcMatchShortEntry(const uint16_t aShortAddress, uint16_t panid);
+otError qorvoRadioAddSrcMatchShortEntry(uint16_t aShortAddress, uint16_t panid);
 
 /**
  * This function adds an extended address plus panid to the source address match list.
@@ -162,7 +162,7 @@
  * @param[in]  panid          The panid.
  *
  */
-otError qorvoRadioClearSrcMatchShortEntry(const uint16_t aShortAddress, uint16_t panid);
+otError qorvoRadioClearSrcMatchShortEntry(uint16_t aShortAddress, uint16_t panid);
 
 /**
  * This function removes an extended address plus panid from the source address match list.
diff --git a/examples/platforms/gp712/uart-posix.c b/examples/platforms/gp712/uart-posix.c
index fee2e21..e98c977 100644
--- a/examples/platforms/gp712/uart-posix.c
+++ b/examples/platforms/gp712/uart-posix.c
@@ -43,13 +43,13 @@
 
 #include "utils/code_utils.h"
 
-#ifdef OPENTHREAD_TARGET_LINUX
+#ifdef __linux__
 #include <sys/prctl.h>
 int   posix_openpt(int oflag);
 int   grantpt(int fildes);
 int   unlockpt(int fd);
 char *ptsname(int fd);
-#endif // OPENTHREAD_TARGET_LINUX
+#endif // __linux__
 
 static uint8_t        s_receive_buffer[128];
 static const uint8_t *s_write_buffer;
@@ -104,7 +104,7 @@
     otError        error = OT_ERROR_NONE;
     struct termios termios;
 
-#ifdef OPENTHREAD_TARGET_LINUX
+#ifdef __linux__
     // Ensure we terminate this process if the
     // parent process dies.
     prctl(PR_SET_PDEATHSIG, SIGHUP);
diff --git a/examples/platforms/gp712/uart-socket.c b/examples/platforms/gp712/uart-socket.c
index 754d56e..b516581 100644
--- a/examples/platforms/gp712/uart-socket.c
+++ b/examples/platforms/gp712/uart-socket.c
@@ -32,26 +32,26 @@
  *
  */
 
-#include "platform_qorvo.h"
 #include "alarm_qorvo.h"
+#include "platform_qorvo.h"
 #include "uart_qorvo.h"
 
 #include <assert.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <poll.h>
-#include <stdlib.h>
+#include <signal.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <termios.h>
 #include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
 
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <netdb.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
-#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 
 #include <pthread.h>
 
@@ -62,27 +62,28 @@
 
 #include "utils/code_utils.h"
 
-#define BUFFER_MAX_SIZE     255
+#define BUFFER_MAX_SIZE 255
 #define SOCKET_PORT 9190
-#define SOCKET_WRITE(socketInfo, buf, length)       sendto(socketInfo.socketId, (const char*)buf, length, 0, &socketInfo.addr, sizeof(socketInfo.addr))
-#define SOCKET_READ(socketId, buf, length)          recv(socketId, buf, length, 0)
+#define SOCKET_WRITE(socketInfo, buf, length) \
+    sendto(socketInfo.socketId, (const char *)buf, length, 0, &socketInfo.addr, sizeof(socketInfo.addr))
+#define SOCKET_READ(socketId, buf, length) recv(socketId, buf, length, 0)
 
 typedef struct
 {
-    uint32_t socketId;
-    bool isValid;
+    uint32_t        socketId;
+    bool            isValid;
     struct sockaddr addr;
-    pthread_t rfReadThread;
+    pthread_t       rfReadThread;
 } PlatSocket_t;
 
-PlatSocket_t   PlatSocketConnection;
-int PlatSocketPipeFd [2];
-int PlatServerSocketId;
+PlatSocket_t PlatSocketConnection;
+int          PlatSocketPipeFd[2];
+int          PlatServerSocketId;
 
 void PlatSocketRxNewConn(uint8_t id);
 void PlatSocketInit(void);
 void PlatSocketDeInit(void);
-int PlatSocketTxData(uint16_t length, uint8_t *pData, uint32_t socketId);
+int  PlatSocketTxData(uint16_t length, uint8_t *pData, uint32_t socketId);
 
 #define PLAT_UART_MAX_CHAR 1024
 
@@ -91,9 +92,9 @@
 void PlatSocketSendInput(void *buffer)
 {
     uint8_t  len = 0;
-    uint8_t *buf = (uint8_t *) buffer;
-    len = strlen((char *)buf);
-    otPlatUartReceived((uint8_t *) buf, (uint16_t)len);
+    uint8_t *buf = (uint8_t *)buffer;
+    len          = strlen((char *)buf);
+    otPlatUartReceived((uint8_t *)buf, (uint16_t)len);
     free(buf);
     buf = 0;
     len = 0;
@@ -110,7 +111,7 @@
         memcpy(buf, buffer, length);
         buf[length]     = '\n';
         buf[length + 1] = 0;
-        qorvoAlarmScheduleEventArg(0, PlatSocketSendInput, (void *) buf);
+        qorvoAlarmScheduleEventArg(0, PlatSocketSendInput, (void *)buf);
     }
 }
 
@@ -142,7 +143,7 @@
 
     if (PlatSocketId)
     {
-        PlatSocketTxData(aBufLength, (uint8_t *) aBuf, PlatSocketId);
+        PlatSocketTxData(aBufLength, (uint8_t *)aBuf, PlatSocketId);
     }
 
     otPlatUartSendDone();
@@ -164,11 +165,11 @@
 
 int PlatSocketListenForClients()
 {
-    //Setup server side socket
-    int      sockfd;
-    struct   sockaddr_in serv_addr;
-    uint32_t flag = 1;
-    int      ret;
+    // Setup server side socket
+    int                sockfd;
+    struct sockaddr_in serv_addr;
+    uint32_t           flag = 1;
+    int                ret;
 
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     otEXPECT_ACTION(sockfd >= 0, sockfd = -1);
@@ -180,9 +181,9 @@
     memset(&serv_addr, 0, sizeof(serv_addr));
 
     serv_addr.sin_addr.s_addr = INADDR_ANY;
-    serv_addr.sin_family = AF_INET;
-    serv_addr.sin_port = htons(SOCKET_PORT);
-    ret = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
+    serv_addr.sin_family      = AF_INET;
+    serv_addr.sin_port        = htons(SOCKET_PORT);
+    ret                       = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
     otEXPECT_ACTION(ret >= 0, close(sockfd); sockfd = -1);
     ret = listen(sockfd, 10);
     otEXPECT_ACTION(ret != -1, exit(1));
@@ -194,15 +195,15 @@
 {
     OT_UNUSED_VARIABLE(id);
 
-    //Dummy callback function to flush pipe
+    // Dummy callback function to flush pipe
     uint8_t readChar;
-    //Remove trigger byte from pipe
-    read(PlatSocketPipeFd [0], &readChar, 1);
+    // Remove trigger byte from pipe
+    read(PlatSocketPipeFd[0], &readChar, 1);
 }
 
 void *PlatSocketReadThread(void *pClientSocket)
 {
-    char buffer[BUFFER_MAX_SIZE];
+    char          buffer[BUFFER_MAX_SIZE];
     PlatSocket_t *clientSocket = ((PlatSocket_t *)pClientSocket);
 
     memset(buffer, 0, BUFFER_MAX_SIZE);
@@ -224,11 +225,11 @@
             }
 
             {
-                uint8_t someByte = 0x12; //No functional use  only using pipe to kick main thread
+                uint8_t someByte = 0x12; // No functional use  only using pipe to kick main thread
 
                 PlatSocketRx(readLen, buffer, clientSocket->socketId);
 
-                write(PlatSocketPipeFd [1], &someByte, 1); //[1] = write fd
+                write(PlatSocketPipeFd[1], &someByte, 1); //[1] = write fd
             }
         }
     }
@@ -244,22 +245,20 @@
 
 void PlatSocketRxNewConn(uint8_t id)
 {
-    //Find first non-valid client in list - add here
+    // Find first non-valid client in list - add here
     if (PlatSocketConnection.isValid == 0)
     {
-        //Add new client to client list
+        // Add new client to client list
         socklen_t len;
-        len = sizeof(PlatSocketConnection.addr);
-        int retval = accept(id, (struct sockaddr *)&PlatSocketConnection.addr, (socklen_t *) &len);
+        len        = sizeof(PlatSocketConnection.addr);
+        int retval = accept(id, (struct sockaddr *)&PlatSocketConnection.addr, (socklen_t *)&len);
 
         if (retval >= 0)
         {
             int retErr;
             PlatSocketConnection.socketId = retval;
-            retErr = pthread_create(&PlatSocketConnection.rfReadThread,
-                                    NULL,
-                                    PlatSocketReadThread,
-                                    &PlatSocketConnection);
+            retErr =
+                pthread_create(&PlatSocketConnection.rfReadThread, NULL, PlatSocketReadThread, &PlatSocketConnection);
 
             if (retErr)
             {
@@ -273,7 +272,6 @@
     }
     else
     {
-
         int tempfd;
         tempfd = accept(id, (struct sockaddr *)NULL, NULL);
 
@@ -298,7 +296,7 @@
 
     // hack
     pipe(PlatSocketPipeFd);
-    qorvoPlatRegisterPollFunction(PlatSocketPipeFd [0], PlatSocketRxSignaled);
+    qorvoPlatRegisterPollFunction(PlatSocketPipeFd[0], PlatSocketRxSignaled);
 }
 
 void platformUartRestore(void)
@@ -320,7 +318,7 @@
 {
     int result = -1;
 
-    //All sockets
+    // All sockets
     if (PlatSocketConnection.isValid)
     {
         if (PlatSocketConnection.socketId == socketId)
@@ -340,4 +338,3 @@
 
     return result;
 }
-
diff --git a/examples/platforms/k32w/Makefile.am b/examples/platforms/k32w/Makefile.am
new file mode 100755
index 0000000..b2f7528
--- /dev/null
+++ b/examples/platforms/k32w/Makefile.am
@@ -0,0 +1,40 @@
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Use automake includes since we cannot use SUBDIRS feature due to  cleanup
+# errors - few targets may use the same source file but dependency file is
+# created only once which leads to errors when auto-generated Makefile tries
+# to remove .Po files that were already removed
+
+if OPENTHREAD_EXAMPLES_JN5189
+include jn5189/Makefile.am
+endif
+
+if OPENTHREAD_EXAMPLES_K32W061
+include k32w061/Makefile.am
+endif
diff --git a/examples/platforms/k32w/README.md b/examples/platforms/k32w/README.md
new file mode 100755
index 0000000..c13d1b0
--- /dev/null
+++ b/examples/platforms/k32w/README.md
@@ -0,0 +1,14 @@
+# OpenThread on K32W Example
+
+This directory contains example platform drivers for [NXP Semiconductors K32W061 SoC][k32w061] and [NXP Semiconductors JN5189 SoC][jn5189].
+
+[k32w061]: https://www.nxp.com/products/wireless/thread/k32w061-41-high-performance-secure-and-ultra-low-power-mcu-for-zigbeethread-and-bluetooth-le-5-0-with-built-in-nfc-option:K32W061_41
+[jn5189]: https://www.nxp.com/products/wireless/thread/jn5189-88-t-high-performance-and-ultra-low-power-mcus-for-zigbee-and-thread-with-built-in-nfc-option:JN5189_88_T
+
+To learn more about building and running the examples please check:
+
+- [OpenThread on K32W061 examples][k32w061-page]
+- [OpenThread on JN5189 examples][jn5189-page]
+
+[k32w061-page]: ./k32w061/README.md
+[jn5189-page]: ./jn5189/README.md
diff --git a/examples/platforms/k32w/jn5189/Makefile.am b/examples/platforms/k32w/jn5189/Makefile.am
new file mode 100755
index 0000000..512d628
--- /dev/null
+++ b/examples/platforms/k32w/jn5189/Makefile.am
@@ -0,0 +1,141 @@
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+
+lib_LIBRARIES                                                                                                      = \
+    libopenthread-jn5189_plat.a                                                                                      \
+    libopenthread-jn5189_sdk.a
+    $(NULL)
+
+# Do not enable -pedantic-errors for jn5189 driver library
+override CFLAGS                                      := $(filter-out -pedantic-errors,$(CFLAGS))
+override CXXFLAGS                                    := $(filter-out -pedantic-errors,$(CXXFLAGS))
+
+# Do not enable -Wcast-align for jn5189 driver library
+override CFLAGS                                      := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                                    := $(filter-out -Wcast-align,$(CXXFLAGS))
+
+LIB_FLAGS                                                                                                          = \
+    -DCPU_JN518X                                                                                                     \
+    -DCPU_JN518X_REV=2                                                                                               \
+    -DJENNIC_CHIP_FAMILY_JN518x                                                                                      \
+    -DJENNIC_CHIP_FAMILY_NAME=_JN518x                                                                                \
+    -DUSE_RTOS=0                                                                                                     \
+    -DgPWR_LDOMEM_0_9V_PD=0                                                                                          \
+    -DNO_SYSCORECLK_UPD=0                                                                                            \
+    -I$(top_srcdir)/include                                                                                          \
+    -I$(top_srcdir)/examples/platforms                                                                               \
+    -I$(top_srcdir)/src/core                                                                                         \
+    -I$(top_srcdir)/third_party/nxp                                                                                  \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6                                                                        \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/devices/JN5189                                                         \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk                                           \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/components/serial_manager                                              \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/components/uart                                                        \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/devices/JN5189/drivers                                                 \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console                                 \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str                                           \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement               \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/CMSIS/Include                                                          \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/middleware/wireless/ieee-802.15.4/uMac/Include                         \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/DK6/Build/Include                   \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/DK6                                 \
+    -I$(top_srcdir)/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common                                   \
+    -Wno-unknown-pragmas                                                                                             \
+    -Wno-sign-compare                                                                                                \
+    -Wno-unused-function                                                                                             \
+    -Wno-unused-parameter                                                                                            \
+    -Wno-empty-body                                                                                                  \
+    -fno-strict-aliasing                                                                                             \
+    $(NULL)
+
+libopenthread_jn5189_sdk_a_CPPFLAGS                                                                                = \
+    $(LIB_FLAGS)                                                                                                     \
+    $(NULL)
+
+libopenthread_jn5189_plat_a_CPPFLAGS                                                                               = \
+    $(LIB_FLAGS)                                                                                                     \
+    $(NULL)
+
+PLATFORM_SOURCES                                                                                                   = \
+    src/alarm.c                                                                                                      \
+    src/diag.c                                                                                                       \
+    src/flash.c                                                                                                      \
+    src/logging.c                                                                                                    \
+    src/misc.c                                                                                                       \
+    src/radio.c                                                                                                      \
+    src/entropy.c                                                                                                    \
+    src/system.c                                                                                                     \
+    src/uart.c                                                                                                       \
+    src/settings_k32w.c                                                                                              \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/utilities/fsl_assert.c                                   \
+    @top_builddir@/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/aes_alt.c                                  \
+    @top_builddir@/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c                             \
+    $(NULL)
+
+libopenthread_jn5189_sdk_a_SOURCES                                                                                 = \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/mcuxpresso/startup_JN5189.c                              \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/system_JN5189.c                                          \
+    @top_builddir@/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/pin_mux.c      \
+    @top_builddir@/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/clock_config.c \
+    @top_builddir@/third_party/nxp/JN5189DK6/components/serial_manager/serial_manager.c                              \
+    @top_builddir@/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_uart.c                            \
+    @top_builddir@/third_party/nxp/JN5189DK6/components/uart/usart_adapter.c                                         \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_gpio.c                                       \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_clock.c                                      \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_ctimer.c                                     \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_wtimer.c                                     \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flash.c                                      \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_usart.c                                      \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_rng.c                                        \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flexcomm.c                                   \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_reset.c                                      \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_power.c                                      \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_aes.c                                        \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_sha.c                                        \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console.c              \
+    @top_builddir@/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str/fsl_str.c                                  \
+    @top_builddir@/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroInt_arm_sdk2.c                \
+    $(NULL)
+
+libopenthread_jn5189_plat_a_SOURCES                                                                                = \
+    $(PLATFORM_SOURCES)                                                                                              \
+    $(NULL)
+
+PRETTY_FILES                                                                                                       = \
+    $(PLATFORM_SOURCES)                                                                                              \
+    $(NULL)
+
+Dash                                                                                                               = -
+libopenthread_jn5189_sdk_a_LIBADD                                                                                  = \
+    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
+libopenthread_jn5189_plat_a_LIBADD                                                                                 = \
+    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/k32w/jn5189/Makefile.platform.am b/examples/platforms/k32w/jn5189/Makefile.platform.am
new file mode 100755
index 0000000..0e279c9
--- /dev/null
+++ b/examples/platforms/k32w/jn5189/Makefile.platform.am
@@ -0,0 +1,42 @@
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# JN5189 platform-specific Makefile
+#
+
+LDADD_COMMON                                                                                    += \
+    $(top_builddir)/examples/platforms/k32w/libopenthread-jn5189_plat.a                            \
+    $(top_builddir)/examples/platforms/k32w/libopenthread-jn5189_sdk.a                             \
+    $(top_srcdir)/third_party/nxp/JN5189DK6/middleware/wireless/ieee-802.15.4/lib/libMiniMac.a     \
+    $(top_srcdir)/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/lib/libRadio.a      \
+    $(NULL)
+
+LDFLAGS_COMMON                                                                                  += \
+    -T $(top_srcdir)/examples/platforms/k32w/jn5189/jn5189.ld                                      \
+    $(NULL)
diff --git a/examples/platforms/k32w/jn5189/README.md b/examples/platforms/k32w/jn5189/README.md
new file mode 100755
index 0000000..0210190
--- /dev/null
+++ b/examples/platforms/k32w/jn5189/README.md
@@ -0,0 +1,125 @@
+# OpenThread on NXP JN5189 Example
+
+This directory contains example platform drivers for the [NXP JN5189][jn5189] based on [JN5189-DK006][jn5189-dk006] hardware platform.
+
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. As a result, the example platform drivers do not necessarily highlight the platform's full capabilities.
+
+## Toolchain
+
+OpenThread environment is suited to be run on a Linux-based OS. Recommended OS is Ubuntu 18.04.2 LTS. Download and install the [MCUXpresso IDE][mcuxpresso ide].
+
+[mcuxpresso ide]: https://www.nxp.com/support/developer-resources/software-development-tools/mcuxpresso-software-and-tools/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE
+
+In a Bash terminal (found, for example, in Ubuntu OS), follow these instructions to install the GNU toolchain and other dependencies.
+
+```bash
+$ cd <path-to-openthread>
+$ ./script/bootstrap
+```
+
+If a network connection timeout is encountered, re-run the script.
+
+Python-pip is also required for the build. User can install it by running "sudo apt-get install Python-pip" in bash. After installing Python-pip, execute "pip install pycryptodome" in bash. This is needed for signing the built binary in order to load it on the board. Also, pycrypto "pip install pycrypto" is required for PKCS1.
+
+Windows 10 offers the possibility of running bash by installing "Ubuntu on Windows" from Microsoft Store. This application allows the user to use Ubuntu Terminal and run Ubuntu command line utilities including bash, ssh, git, apt and many more. If this option is used, it is recommended to add instructions for the path mapping in MCUXpresso IDE. This can be done after adding the project to the workspace by going to Run->"Debug Configuration"->"C/C++(NXP Semiconductors) MCU Application"->Source->Add. Then the user should create a path mapping such that MCUXpresso IDE will find the mount point for the "Ubuntu in Windows" subsystem. For example, user can enter compilation path recognized by Ubuntu as /mnt/c/<path-to-openthread>, while equivalent "Local file system path" is C:/<path-to-openthread>. This example assumes that the openthread package is installed on the C drive.
+
+## Build Examples
+
+```bash
+$ cd <path-to-openthread>
+$ ./bootstrap
+$ make -f examples/Makefile-jn5189
+```
+
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/jn5189/bin`.
+
+## Flash Binaries
+
+Connect to the board by plugging a mini-USB cable to the connector marked with TARGET on the DK6 board. This connector is situated on the same side with the power connector.
+
+OpenThread example application compiled binaries can be found in `<path-to-openthread>/output/jn5189/bin` and include FTD (Full Thread Device) and MTD (Minimal Thread Device) variants of CLI and NCP applications. The compiled binaries can be flashed onto the JN5189 using MCUXpresso IDE. This requires the following steps:
+
+1. Import the JN5189 SDK into MCUXpresso IDE. This can be done by dragging and dropping the SDK archive into MCUXpresso IDE's Installed SDKs tab. The archive for SDK_2.6.0_JN5189DK6 is available for download at https://mcuxpresso.nxp.com/en/welcome
+2. In MCUXpresso IDE, go to File->Import->C/C++->"Existing Code as Makefile Project" and click Next.
+3. Select the OpenThread folder as the "Existing Code Location". In the "Toolchain for Indexer Settings" list, be sure to keep the setting to <none>. Click Finish.
+4. Right click on the newly created openthread project in the Workspace and go to Properties->"C/C++ Build"->"MCU Settings". Select the JN518x from the SDK MCUs list.
+5. Go to C/C++ Build->"Tool Chain Editor" and untick the "Display compatible toolchains only" checkbox. In the drop-down menu named "Current toolchain", select "NXP MCU Tools". Click "Apply and Close".
+6. Right click on the openthread project and select "Debug As"->"MCUXpresso IDE LinkServer (inc. CMSIS-DAP) probes"
+7. A window to select the binary will appear. Select "output/jn5189/bin/ot-<application>" and click Ok.
+8. Under the menu bar, towards the center of the screen, there is a green bug icon with a drop-down arrow next to it. Click on the arrow and select "Debug Configurations".
+9. In the right side of the Debug Configurations window, go to "C/C++ (NXP Semiconductors) MCU Application"->"openthread LinkServer Default".
+10. Make sure that in the "C/C++ Application:" text box contains "output\jn5189\bin\ot-<application>" path.
+11. Go to "GUI Flash Tool" tab. In "Target Operations"->Program->Options, select "bin" as the "Format to use for programming". Make sure the "Base address" is 0x0.
+12. Click Debug.
+13. A pop-up window entitled "Errors in Workspace" will appear. Click Proceed.
+14. The board is now flashed.
+
+[cmsis-dap]: https://os.mbed.com/handbook/CMSIS-DAP
+
+## Running the example
+
+1. Prepare two boards with the flashed `CLI Example` (as shown above). Make sure that the JN4 jumper is set to RX and the JN7 jumper is set to TX, connecting the LPC and JN UART0 pins.
+2. The CLI example uses UART connection. To view raw UART output, start a terminal emulator like PuTTY and connect to the used COM port with the following UART settings:
+
+   - Baud rate: 115200
+   - 8 data bits
+   - 1 stop bit
+   - No parity
+   - No flow control
+
+3. Open a terminal connection on the first board and start a new Thread network.
+
+```bash
+> panid 0xabcd
+Done
+> ifconfig up
+Done
+> thread start
+Done
+```
+
+4. After a couple of seconds the node will become a Leader of the network.
+
+```bash
+> state
+Leader
+```
+
+5. Open a terminal connection on the second board and attach a node to the network.
+
+```bash
+> panid 0xabcd
+Done
+> ifconfig up
+Done
+> thread start
+Done
+```
+
+6. After a couple of seconds the second node will attach and become a Child.
+
+```bash
+> state
+Child
+```
+
+7. List all IPv6 addresses of the first board.
+
+```bash
+> ipaddr
+fdde:ad00:beef:0:0:ff:fe00:fc00
+fdde:ad00:beef:0:0:ff:fe00:9c00
+fdde:ad00:beef:0:4bcb:73a5:7c28:318e
+fe80:0:0:0:5c91:c61:b67c:271c
+```
+
+8. Choose one of them and send an ICMPv6 ping from the second board.
+
+```bash
+> ping fdde:ad00:beef:0:0:ff:fe00:fc00
+16 bytes from fdde:ad00:beef:0:0:ff:fe00:fc00: icmp_seq=1 hlim=64 time=8ms
+```
+
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
+
+[cli]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
diff --git a/examples/platforms/k32w/jn5189/jn5189-mbedtls-config.h b/examples/platforms/k32w/jn5189/jn5189-mbedtls-config.h
new file mode 100755
index 0000000..d4c2ebc
--- /dev/null
+++ b/examples/platforms/k32w/jn5189/jn5189-mbedtls-config.h
@@ -0,0 +1,248 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JN5189_MBEDTLS_CONFIG_H
+#define JN5189_MBEDTLS_CONFIG_H
+
+#if defined(MBEDTLS_ECP_WINDOW_SIZE)
+#undef MBEDTLS_ECP_WINDOW_SIZE
+#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */
+#endif
+
+#if defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
+#undef MBEDTLS_ECP_FIXED_POINT_OPTIM
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
+#endif
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * Enable hardware acceleration for the AES block cipher
+ *
+ * See MBEDTLS_AES_C for more information.
+ */
+#define MBEDTLS_AES_ALT
+
+#if defined(MBEDTLS_AES_ALT)
+/**************************** KSDK ********************************************/
+#include "fsl_device_registers.h"
+
+/* Enable LTC use in library if there is LTC on chip. */
+#if defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0)
+#include "fsl_ltc.h"
+
+#define LTC_INSTANCE LTC0 /* LTC base register.*/
+
+#if FSL_FEATURE_LTC_HAS_SHA
+#define MBEDTLS_FREESCALE_LTC_SHA1   /* Enable use of LTC SHA.*/
+#define MBEDTLS_FREESCALE_LTC_SHA256 /* Enable use of LTC SHA256.*/
+#endif
+#if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES
+#define MBEDTLS_FREESCALE_LTC_DES /* Enable use of LTC DES.*/
+#endif
+#define MBEDTLS_FREESCALE_LTC_AES /* Enable use of LTC AES.*/
+#if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM
+#define MBEDTLS_FREESCALE_LTC_AES_GCM /* Enable use of LTC AES GCM.*/
+#endif
+#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
+#define MBEDTLS_FREESCALE_LTC_PKHA /* Enable use of LTC PKHA.*/
+#define FREESCALE_PKHA_INT_MAX_BYTES 256
+#endif
+#endif
+
+/* Enable MMCAU use in library if there is MMCAU on chip. */
+#if defined(FSL_FEATURE_SOC_MMCAU_COUNT) && (FSL_FEATURE_SOC_MMCAU_COUNT > 0)
+#include "fsl_mmcau.h"
+
+#define MBEDTLS_FREESCALE_MMCAU_MD5    /* Enable use of MMCAU MD5.*/
+#define MBEDTLS_FREESCALE_MMCAU_SHA1   /* Enable use of MMCAU SHA1.*/
+#define MBEDTLS_FREESCALE_MMCAU_SHA256 /* Enable use of MMCAU SHA256.*/
+#define MBEDTLS_FREESCALE_MMCAU_DES    /* Enable use of MMCAU DES, when LTC is disabled.*/
+#define MBEDTLS_FREESCALE_MMCAU_AES    /* Enable use of MMCAU AES, when LTC is disabled.*/
+#endif
+
+/* Enable CAU3 use in library if there is CAU3 on chip. */
+#if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)
+#include "cau3_pkha.h"
+#include "fsl_cau3.h"
+
+#define MBEDTLS_CAU3_COMPLETION_SIGNAL CAU3_CC_CMD_EVT
+#define MBEDTLS_SHA256_ALT_NO_224
+
+#define MBEDTLS_FREESCALE_CAU3_AES    /* Enable use of CAU3 AES.*/
+#define MBEDTLS_FREESCALE_CAU3_SHA256 /* Enable use of CAU3 SHA256.*/
+#define MBEDTLS_FREESCALE_CAU3_PKHA   /* Enable use of CAU3 PKHA.*/
+#define FREESCALE_PKHA_INT_MAX_BYTES 512
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+/*
+ * This FREESCALE_PKHA_LONG_OPERANDS_ENABLE macro can be defined.
+ * In such a case both software and hardware algorithm for TFM is linked in.
+ * The decision for which algorithm is used is determined at runtime
+ * from size of inputs. If inputs and result can fit into LTC (see FREESCALE_PKHA_INT_MAX_BYTES)
+ * then we call hardware algorithm, otherwise we call software algorithm.
+ *
+ * Note that mbedTLS algorithms break modular operations unefficiently into two steps.
+ * First is normal operation, for example non-modular multiply, which can produce number
+ * with greater size than operands. Second is modular reduction.
+ * The implication of this is that if for example FREESCALE_PKHA_INT_MAX_BYTES is 256 (2048 bits),
+ * RSA-2048 still requires the FREESCALE_PKHA_LONG_OPERANDS_ENABLE macro to be defined,
+ * otherwise it fails at runtime.
+ */
+//#define FREESCALE_PKHA_LONG_OPERANDS_ENABLE
+#endif
+
+/* Enable AES use in library if there is AES on chip. */
+#if defined(FSL_FEATURE_SOC_AES_COUNT) && (FSL_FEATURE_SOC_AES_COUNT > 0)
+#include "fsl_aes.h"
+
+#define AES_INSTANCE AES0             /* AES base register.*/
+#define MBEDTLS_FREESCALE_LPC_AES     /* Enable use of LPC AES.*/
+#define MBEDTLS_FREESCALE_LPC_AES_GCM /* Enable use of LPC AES GCM.*/
+
+#endif
+
+/* Enable SHA use in library if there is SHA on chip. */
+#if defined(FSL_FEATURE_SOC_SHA_COUNT) && (FSL_FEATURE_SOC_SHA_COUNT > 0)
+#include "fsl_sha.h"
+
+//#define SHA_INSTANCE SHA0            /* AES base register.*/
+#define MBEDTLS_FREESCALE_LPC_SHA1 /* Enable use of LPC SHA.*/
+//#define MBEDTLS_FREESCALE_LPC_SHA256 /* Enable use of LPC SHA256.*/
+
+#endif
+
+/* Define ALT MMCAU & LTC functions. Do not change it. */
+#if defined(MBEDTLS_FREESCALE_MMCAU_DES) || defined(MBEDTLS_FREESCALE_LTC_DES)
+#define MBEDTLS_DES_SETKEY_ENC_ALT
+#define MBEDTLS_DES_SETKEY_DEC_ALT
+#define MBEDTLS_DES_CRYPT_ECB_ALT
+#define MBEDTLS_DES3_CRYPT_ECB_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_DES)
+#define MBEDTLS_DES_CRYPT_CBC_ALT
+#define MBEDTLS_DES3_CRYPT_CBC_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_MMCAU_AES) || \
+    defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES)
+#define MBEDTLS_AES_SETKEY_ENC_ALT
+#define MBEDTLS_AES_SETKEY_DEC_ALT
+#define MBEDTLS_AES_ENCRYPT_ALT
+#define MBEDTLS_AES_DECRYPT_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+#define MBEDTLS_AES_CRYPT_CBC_ALT
+#define MBEDTLS_AES_CRYPT_CTR_ALT
+#define MBEDTLS_CCM_CRYPT_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_AES_GCM) || defined(MBEDTLS_FREESCALE_LPC_AES_GCM)
+#define MBEDTLS_GCM_CRYPT_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+#define MBEDTLS_MPI_ADD_ABS_ALT
+#define MBEDTLS_MPI_SUB_ABS_ALT
+#define MBEDTLS_MPI_MUL_MPI_ALT
+#define MBEDTLS_MPI_MOD_MPI_ALT
+#define MBEDTLS_MPI_EXP_MOD_ALT
+#define MBEDTLS_MPI_GCD_ALT
+#define MBEDTLS_MPI_INV_MOD_ALT
+#define MBEDTLS_MPI_IS_PRIME_ALT
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA)
+#define MBEDTLS_ECP_MUL_COMB_ALT
+#define MBEDTLS_ECP_ADD_ALT
+#endif
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_SHA1) || defined(MBEDTLS_FREESCALE_LPC_SHA1)
+#define MBEDTLS_SHA1_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_SHA256) || defined(MBEDTLS_FREESCALE_LPC_SHA256)
+//#define MBEDTLS_SHA256_ALT
+/*
+ * LPC SHA module does not support SHA-224.
+ *
+ * Since mbed TLS does not provide separate APIs for SHA-224 and SHA-256
+ * and SHA-224 is not widely used, this implementation provides HW accelerated SHA-256 only
+ * and SHA-224 is not available at all (calls will fail).
+ *
+ * To use SHA-224 on LPC, do not define MBEDTLS_SHA256_ALT and both SHA-224 and SHA-256 will use
+ * original mbed TLS software implementation.
+ */
+#if defined(MBEDTLS_FREESCALE_LPC_SHA256)
+#define MBEDTLS_SHA256_ALT_NO_224
+#endif
+#endif
+#if defined(MBEDTLS_FREESCALE_MMCAU_MD5)
+#define MBEDTLS_MD5_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_MMCAU_SHA1)
+#define MBEDTLS_SHA1_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_MMCAU_SHA256)
+#define MBEDTLS_SHA256_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_CAU3_SHA256)
+#define MBEDTLS_SHA256_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_CAU3_AES)
+#define MBEDTLS_AES_ALT_NO_192
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+#if !defined(FSL_FEATURE_LTC_HAS_AES192) || !FSL_FEATURE_LTC_HAS_AES192
+#define MBEDTLS_AES_ALT_NO_192
+#endif
+#if !defined(FSL_FEATURE_LTC_HAS_AES256) || !FSL_FEATURE_LTC_HAS_AES256
+#define MBEDTLS_AES_ALT_NO_256
+#endif
+#endif
+#if defined(MBEDTLS_FREESCALE_LPC_AES)
+#define MBEDTLS_AES_CRYPT_CBC_ALT
+#define MBEDTLS_AES_CRYPT_CFB_ALT
+#define MBEDTLS_AES_CRYPT_CTR_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LPC_SHA1)
+#define MBEDTLS_SHA1_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LPC_SHA256)
+#define MBEDTLS_SHA256_PROCESS_ALT
+#endif
+
+#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
+#include "FreeRTOS.h"
+
+void *pvPortCalloc(size_t num, size_t size); /*Calloc for HEAP3.*/
+
+#define MBEDTLS_PLATFORM_MEMORY
+#define MBEDTLS_PLATFORM_STD_CALLOC pvPortCalloc
+#define MBEDTLS_PLATFORM_STD_FREE vPortFree
+
+#endif /* USE_RTOS*/
+/**************************** KSDK end ****************************************/
+#endif /* MBEDTLS_AES_ALT || MBEDTLS_SHA256_ALT */
+
+#endif // JN5189_MBEDTLS_CONFIG_H
diff --git a/examples/platforms/k32w/jn5189/jn5189.ld b/examples/platforms/k32w/jn5189/jn5189.ld
new file mode 100755
index 0000000..44608e8
--- /dev/null
+++ b/examples/platforms/k32w/jn5189/jn5189.ld
@@ -0,0 +1,304 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   GCC linker script for JN5189.
+ */
+
+/*
+ * stack size for the boot rom during warm boot and application
+ * 256 is sufficient (pwrm_test) but keep it large to 1024
+ */
+BOOT_RESUME_STACK_SIZE = 1024;
+
+/* Set Stack size to 4K minus 32Bytes reserved for ROM code at end of BANK7 so
+   the stack fits in BANK7. In practice the active stack size at the time of
+   going to sleep is more important than the total available stack size */
+STACK_SIZE             = (4096 - 32);
+
+MEM_RAM0_BASE = 0x4000400;
+MEM_RAM0_SIZE = 0x0015c00;
+
+MEMORY
+{
+  /* Define each memory region. RAM0 definition leaves the first 1kB for the
+     boot code */
+  Flash640 (rx) : ORIGIN = 0, LENGTH = 0x00a0000            /* 640K bytes (alias Flash) */
+  RAM0 (rwx)    : ORIGIN = 0x4000400,  LENGTH = 0x0015c00   /* 87K bytes (alias RAM) */
+  RAM1 (rwx)    : ORIGIN = 0x4020000,      LENGTH = 0x10000 /* 64K bytes (alias RAM2) */
+}
+
+/* Define a symbol for the top of each memory region */
+__top_RAM0      = MEM_RAM0_BASE + MEM_RAM0_SIZE; /* 87K bytes */
+
+HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x2F4;
+
+/*** flash memory characteristics definitions required for OTA ***/
+m_flash_start   = 0x00000000;
+m_flash_end     = 0x0009FFFF;
+m_flash_size    = 0x000A0000;
+m_sector_size   = 512;
+m_fsl_prodInfo_size = m_sector_size;
+
+m_fsl_prodInfo_end                             = m_flash_size - 17 * m_sector_size - 1;
+m_fsl_prodInfo_start                           = m_fsl_prodInfo_end - m_fsl_prodInfo_size + 1;
+
+NV_STORAGE_MAX_SECTORS                         = 64;
+NV_STORAGE_SIZE                                = NV_STORAGE_MAX_SECTORS * m_sector_size;
+NV_STORAGE_END_ADDRESS                         = m_fsl_prodInfo_start - 1;
+NV_STORAGE_START_ADDRESS                       = NV_STORAGE_END_ADDRESS - NV_STORAGE_SIZE + 1;
+
+INT_STORAGE_END                                = NV_STORAGE_START_ADDRESS - 1;
+INT_STORAGE_START                              = 0x48000;
+INT_STORAGE_SIZE                               = INT_STORAGE_END - INT_STORAGE_START;
+
+FREESCALE_PROD_DATA_BASE_ADDR                  = m_fsl_prodInfo_start;
+INT_STORAGE_SECTOR_SIZE                        = m_sector_size;
+m_app_size                                     = 0x48000;
+
+ENTRY(ResetISR)
+
+SECTIONS
+{
+    /* MAIN TEXT SECTION */
+    .header : ALIGN(4)
+    {
+        _flash_start = ABSOLUTE(.);
+        _flash_beg = ABSOLUTE(.);
+
+        FILL(0xff)
+        __vectors_start__ = ABSOLUTE(.) ;
+        KEEP(*(.isr_vector))
+        /* Global Section Table */
+        . = ALIGN(4) ;
+        __section_table_start = .;
+        __data_section_table = .;
+        LONG(LOADADDR(.data));
+        LONG(    ADDR(.data));
+        LONG(  SIZEOF(.data));
+        LONG(LOADADDR(.data_RAM2));
+        LONG(    ADDR(.data_RAM2));
+        LONG(  SIZEOF(.data_RAM2));
+        __data_section_table_end = .;
+        __bss_section_table = .;
+        LONG(    ADDR(.bss));
+        LONG(  SIZEOF(.bss));
+        LONG(    ADDR(.bss_RAM2));
+        LONG(  SIZEOF(.bss_RAM2));
+        __bss_section_table_end = .;
+        __section_table_end = . ;
+        /* End of Global Section Table */
+
+        FILL(0xff)
+        . = ALIGN (0x10);
+    } >Flash640
+
+    .ro_nonce : ALIGN(0x10)
+    {
+        _FlsNonceStart = ABSOLUTE(.);
+        *(.ro_nonce) /* nonce value is 16 bytes.*/
+        FILL(0xff)
+        . = ALIGN (0x10);
+    } > Flash640
+
+    .ro_ota_header : ALIGN(0x10)
+    {
+        _enc_start = ABSOLUTE(.);
+        _enc_offset = (_enc_start & 0x0000000F);
+        _FlsOtaHeader = ABSOLUTE(.);
+        *(.ro_ota_header) /* Ota Header 69 bytes*/
+        FILL(0xff)
+        . = ALIGN (0x10);
+    } > Flash640
+
+    .ro_se_lnkKey (ALIGN((. - _enc_offset), 16) + _enc_offset):
+    {
+        _FlsLinkKey = ABSOLUTE(.);
+        *(.ro_se_lnkKey)  /* Link Key 16 bytes*/
+        FILL(0xff)
+        . = ALIGN (0x10);
+    } > Flash640
+
+    .filler :
+    {
+        BYTE(0xff)
+        FILL(0xff);
+        . = ALIGN(0x40);
+    } > Flash640
+
+    .text : ALIGN(0x40)
+    {
+        FILL(0xff)
+
+       *(.after_vectors*)
+       *(.text*)
+        *(.rodata .rodata.* .constdata .constdata.*)
+        . = ALIGN(4);
+    } > Flash640
+    /*
+     * for exception handling/unwind - some Newlib functions (in common
+     * with C++ and STDC++) use this.
+     */
+    .ARM.extab : ALIGN(4)
+    {
+       FILL(0xff)
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+    } > Flash640
+    __exidx_start = .;
+
+    .ARM.exidx : ALIGN(4)
+    {
+       FILL(0xff)
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > Flash640
+    __exidx_end = .;
+
+    _etext = .;
+
+    /* RAM1/RAM2 (different names for same thing) SECTION */
+    /* RAM1 contents are specified before RAM0 as they have specific input
+       sections and we do not want the RAM0 wildcards to catch them */
+    /* DATA section for RAM1 */
+    .data_RAM2 : ALIGN(4)
+    {
+        FILL(0xff)
+        PROVIDE(__start_data_RAM2 = .) ;
+        *(.ramfunc.$RAM2)
+        *(.ramfunc.$RAM1)
+        *(.data.$RAM2*)
+        *(.data.$RAM1*)
+        . = ALIGN(4) ;
+        PROVIDE(__end_data_RAM2 = .) ;
+     } > RAM1 AT>Flash640
+
+    /* MAIN DATA SECTION */
+    .uninit_RESERVED : ALIGN(4)
+    {
+        KEEP(*(.bss.$RESERVED*))
+        . = ALIGN(4) ;
+        _end_uninit_RESERVED = .;
+    } > RAM0
+
+    /* Main DATA section (RAM0) */
+    .data : ALIGN(4)
+    {
+       FILL(0xff)
+       _data = . ;
+       *(vtable)
+       *(.ramfunc*)
+       *(.data*)
+       . = ALIGN(4) ;
+       _edata = . ;
+    } > RAM0 AT>Flash640
+
+
+    /* BSS section for RAM1 */
+    .bss_RAM2 (NOLOAD) : ALIGN(4)
+    {
+       PROVIDE(__start_bss_RAM2 = .) ;
+       *(.bss.$RAM2*)
+       *(.bss.$RAM1*)
+       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
+       PROVIDE(__end_bss_RAM2 = .) ;
+    } > RAM1
+
+    /* MAIN BSS SECTION */
+    .bss (NOLOAD) : ALIGN(4)
+    {
+        _bss = .;
+        *(.bss*)
+        *(COMMON)
+        *(g_u32NwkFrameCounter)
+        . = ALIGN(4) ;
+        _ebss = .;
+
+        PROVIDE(end = .);
+    } > RAM0
+
+    /* BSS section for MAC buffers */
+    .bss_MAC (NOLOAD) : ALIGN(4)
+    {
+       /* MAC buffer section: must be within 128kB block. __mac_buffer_base is
+          defined further down to be on 128kB alignment */
+        __mac_buffer_start = .;
+       *(.mac_buffer)
+
+        . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
+    } > RAM0
+
+    /* HEAP */
+    .heap (NOLOAD): ALIGN(4)
+    {
+        _heap = .;
+        . += HEAP_SIZE;
+        . = ALIGN(4) ;
+        _end_heap = .;
+    } > RAM0
+
+    /* NOINIT section for RAM1 */
+    .noinit_RAM2 (NOLOAD) : ALIGN(4)
+    {
+       *(.noinit.$RAM2*)
+       *(.noinit.$RAM1*)
+       . = ALIGN(4) ;
+    } > RAM1
+
+    /* DEFAULT NOINIT SECTION */
+    .noinit (NOLOAD): ALIGN(4)
+    {
+        _noinit = .;
+        *(.noinit*)
+        . = ALIGN(4) ;
+        _end_noinit = .;
+    } > RAM0
+
+    /* stack for rom boot during warm resume */
+    .boot_resume_stack (NOLOAD): ALIGN(4)
+    {
+        _boot_resume_stack = .;
+        *(.boot_resume_stack*)
+        . += BOOT_RESUME_STACK_SIZE;
+        . = ALIGN(4) ;
+        _end_boot_resume_stack = .;
+    } > RAM0
+
+    __nv_storage_end_address = NV_STORAGE_END_ADDRESS;
+    __nv_storage_start_address = NV_STORAGE_START_ADDRESS;
+
+    PROVIDE(_vStackTop = __top_RAM0 - 32);
+    PROVIDE(__mac_buffer_base = (__mac_buffer_start & 0xfffe0000));
+    PROVIDE(BOOT_GetStartPowerMode = 0x03000e9d);
+    PROVIDE(ROM_GetFlash = 0x03000e0d);
+    PROVIDE(pmc_reset_get_cause = 0x030046e9);
+    PROVIDE(psector_ReadIeee802_15_4_MacId1 = 0x030053b1);
+    PROVIDE(Chip_LOWPOWER_ChipSoftwareReset = 0x03003fa1);
+
+    __StackLimit = _vStackTop - STACK_SIZE;
+    ASSERT(__StackLimit >= _end_boot_resume_stack, "Possible stack corruption with data/bss/boot_stack")
+}
\ No newline at end of file
diff --git a/examples/platforms/k32w/jn5189/openthread-core-jn5189-config-check.h b/examples/platforms/k32w/jn5189/openthread-core-jn5189-config-check.h
new file mode 100755
index 0000000..cfc656d
--- /dev/null
+++ b/examples/platforms/k32w/jn5189/openthread-core-jn5189-config-check.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OPENTHREAD_CORE_JN5189_CONFIG_CHECK_H_
+#define OPENTHREAD_CORE_JN5189_CONFIG_CHECK_H_
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+#error "Platform jn5189 doesn't support configuration option: OPENTHREAD_CONFIG_TIME_SYNC_ENABLE"
+#endif
+
+#ifndef RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
+#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+#error "Platform jn5189 not configured to support configuration option: OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT"
+#endif
+#endif
+
+#endif /* OPENTHREAD_CORE_JN5189_CONFIG_CHECK_H_ */
diff --git a/examples/platforms/k32w/jn5189/openthread-core-jn5189-config.h b/examples/platforms/k32w/jn5189/openthread-core-jn5189-config.h
new file mode 100755
index 0000000..b9df980
--- /dev/null
+++ b/examples/platforms/k32w/jn5189/openthread-core-jn5189-config.h
@@ -0,0 +1,214 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes jn5189 compile-time configuration constants
+ *   for OpenThread.
+ */
+
+#ifndef OPENTHREAD_CORE_JN5189_CONFIG_H_
+#define OPENTHREAD_CORE_JN5189_CONFIG_H_
+
+/**
+ * @def OPENTHREAD_CONFIG_LOG_OUTPUT
+ *
+ * The emsk platform provides an otPlatLog() function.
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
+#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_INFO
+ *
+ * The platform-specific string to insert into the OpenThread version string.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_INFO "JN5189"
+
+/**
+ * @def SETTINGS_CONFIG_BASE_ADDRESS
+ *
+ * The base address of settings.
+ *
+ */
+#define SETTINGS_CONFIG_BASE_ADDRESS 0
+
+/**
+ * @def SETTINGS_CONFIG_PAGE_SIZE
+ *
+ * The page size of settings.
+ *
+ */
+#define SETTINGS_CONFIG_PAGE_SIZE 0x200
+
+/**
+ * @def SETTINGS_CONFIG_PAGE_NUM
+ *
+ * The page number of settings.
+ *
+ */
+
+#define SETTINGS_CONFIG_PAGE_NUM 64
+
+/**
+ * @def RADIO_CONFIG_SRC_MATCH_ENTRY_NUM
+ *
+ * The number of source address table entries.
+ *
+ */
+#define RADIO_CONFIG_SRC_MATCH_ENTRY_NUM 128
+
+/**
+ * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT
+ *
+ * Define to 1 if you want to enable software retransmission logic.
+ *
+ */
+/* TODO */
+
+/**
+ * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF
+ *
+ * Define to 1 if you want to enable software CSMA-CA backoff logic.
+ *
+ */
+/* TODO */
+
+/**
+ * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
+ *
+ * Define to 1 to enable NCP UART support.
+ *
+ */
+#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1
+
+/**
+ * @def OPENTHREAD_SETTINGS_RAM
+ *
+ * Define to 1 if you want to use JN589 Flash implementation.
+ *
+ */
+#define OPENTHREAD_SETTINGS_RAM 1
+
+/**
+ * @def OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE
+ *
+ * The size of NCP message buffer in bytes.
+ *
+ */
+#define OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE 1024
+
+/**
+ * @def OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE
+ *
+ * The size of heap buffer when DTLS is enabled.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE
+#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE (2048 * sizeof(void *))
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_COAP_API_ENABLE
+ *
+ * Define to 1 to enable the CoAP API.
+ *
+ */
+#define OPENTHREAD_CONFIG_COAP_API_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_JOINER_ENABLE
+ *
+ * Define to 1 to enable Joiner support.
+ *
+ */
+#define OPENTHREAD_CONFIG_JOINER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
+ *
+ * Define to 1 to enable Commissioner support.
+ *
+ */
+#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
+ *
+ * Define to 1 to enable UDP forward support.
+ *
+ */
+#define OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
+ *
+ * Define to 1 to enable the Border Router service.
+ *
+ */
+#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
+ *
+ * Define to 1 to enable the DHCP CLIENT service.
+ *
+ */
+#define OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
+ *
+ * Define to 1 to enable the DHCP SERVER service.
+ *
+ */
+#define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+ *
+ * Define as 1 to enable the time synchronization service feature.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+#define OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_DIAG_ENABLE
+ *
+ * Define as 1 to enable the diag feature.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_DIAG_ENABLE
+#define OPENTHREAD_CONFIG_DIAG_ENABLE 0
+#endif
+
+#endif // OPENTHREAD_CORE_JN5189_CONFIG_H_
diff --git a/examples/platforms/k32w/k32w061/Makefile.am b/examples/platforms/k32w/k32w061/Makefile.am
new file mode 100755
index 0000000..46b3a3f
--- /dev/null
+++ b/examples/platforms/k32w/k32w061/Makefile.am
@@ -0,0 +1,143 @@
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  Copyright (c) 2019, NXP.
+#  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 $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+
+lib_LIBRARIES                                                                                                        = \
+    libopenthread-k32w061_plat.a                                                                                       \
+    libopenthread-k32w061_sdk.a
+    $(NULL)
+
+# Do not enable -pedantic-errors for k32w061 driver library
+override CFLAGS                                      := $(filter-out -pedantic-errors,$(CFLAGS))
+override CXXFLAGS                                    := $(filter-out -pedantic-errors,$(CXXFLAGS))
+
+# Do not enable -Wcast-align for k32w061 driver library
+override CFLAGS                                      := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                                    := $(filter-out -Wcast-align,$(CXXFLAGS))
+
+LIB_FLAGS                                                                                                            = \
+    -DCPU_K32W061HN                                                                                                    \
+    -DCPU_JN518X                                                                                                       \
+    -DCPU_JN518X_REV=2                                                                                                 \
+    -DJENNIC_CHIP_FAMILY_JN518x                                                                                        \
+    -DJENNIC_CHIP_FAMILY_NAME=_JN518x                                                                                  \
+    -DUSE_RTOS=0                                                                                                       \
+    -DgPWR_LDOMEM_0_9V_PD=0                                                                                            \
+    -DNO_SYSCORECLK_UPD=0                                                                                              \
+    -I$(top_srcdir)/include                                                                                            \
+    -I$(top_srcdir)/examples/platforms                                                                                 \
+    -I$(top_srcdir)/src/core                                                                                           \
+    -I$(top_srcdir)/third_party/nxp                                                                                    \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6                                                                         \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/devices/K32W061                                                         \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk                                            \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/components/serial_manager                                               \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/components/uart                                                         \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/devices/K32W061/drivers                                                 \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console                                 \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str                                           \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/CMSIS/Include                                                           \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/middleware/wireless/ieee-802.15.4/uMac/Include                          \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/DK6/Build/Include                    \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/DK6                                  \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/                                   \
+    -I$(top_srcdir)/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement               \
+    -Wno-unknown-pragmas                                                                                               \
+    -Wno-sign-compare                                                                                                  \
+    -Wno-unused-function                                                                                               \
+    -Wno-unused-parameter                                                                                              \
+    -Wno-empty-body                                                                                                    \
+    -fno-strict-aliasing                                                                                               \
+    $(NULL)
+
+libopenthread_k32w061_sdk_a_CPPFLAGS                                                                                 = \
+    $(LIB_FLAGS)                                                                                                       \
+    $(NULL)
+
+libopenthread_k32w061_plat_a_CPPFLAGS                                                                                = \
+    $(LIB_FLAGS)                                                                                                       \
+	$(NULL)
+
+PLATFORM_SOURCES                                                                                                     = \
+    src/alarm.c                                                                                                        \
+    src/diag.c                                                                                                         \
+    src/flash.c                                                                                                        \
+    src/logging.c                                                                                                      \
+    src/misc.c                                                                                                         \
+    src/radio.c                                                                                                        \
+    src/entropy.c                                                                                                      \
+    src/system.c                                                                                                       \
+    src/uart.c                                                                                                         \
+    src/settings_k32w.c                                                                                                \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/utilities/fsl_assert.c                                   \
+    @top_builddir@/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/aes_alt.c                                   \
+    @top_builddir@/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c                              \
+    $(NULL)
+
+libopenthread_k32w061_sdk_a_SOURCES                                                                                  = \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/mcuxpresso/startup_k32w061.c                             \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/system_K32W061.c                                         \
+    @top_builddir@/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/pin_mux.c      \
+    @top_builddir@/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/clock_config.c \
+    @top_builddir@/third_party/nxp/K32W061DK6/components/serial_manager/serial_manager.c                               \
+    @top_builddir@/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_uart.c                             \
+    @top_builddir@/third_party/nxp/K32W061DK6/components/uart/usart_adapter.c                                          \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_gpio.c                                       \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_clock.c                                      \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_ctimer.c                                     \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_wtimer.c                                     \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flash.c                                      \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_usart.c                                      \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_rng.c                                        \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flexcomm.c                                   \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_reset.c                                      \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_power.c                                      \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_aes.c                                        \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_sha.c                                        \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console.c              \
+    @top_builddir@/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str/fsl_str.c                                  \
+    @top_builddir@/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroInt_arm_sdk2.c                 \
+    $(NULL)
+
+libopenthread_k32w061_plat_a_SOURCES                                                                                 = \
+    $(PLATFORM_SOURCES)                                                                                                \
+    $(NULL)
+
+PRETTY_FILES                                                                                                         = \
+    $(PLATFORM_SOURCES)                                                                                                \
+    $(NULL)
+
+Dash                                                                                                                 = -
+libopenthread_k32w061_sdk_a_LIBADD                                                                                   = \
+    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
+libopenthread_k32w061_plat_a_LIBADD                                                                                  = \
+    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/k32w/k32w061/Makefile.platform.am b/examples/platforms/k32w/k32w061/Makefile.platform.am
new file mode 100755
index 0000000..b79dbd1
--- /dev/null
+++ b/examples/platforms/k32w/k32w061/Makefile.platform.am
@@ -0,0 +1,43 @@
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  Copyright (c) 2019, NXP.
+#  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.
+#
+
+#
+# K32W061 platform-specific Makefile
+#
+
+LDADD_COMMON                                                                                   += \
+    $(top_builddir)/examples/platforms/k32w/libopenthread-k32w061_plat.a                          \
+    $(top_builddir)/examples/platforms/k32w/libopenthread-k32w061_sdk.a                           \
+    $(top_srcdir)/third_party/nxp/K32W061DK6/middleware/wireless/ieee-802.15.4/lib/libMiniMac.a   \
+    $(top_srcdir)/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/lib/libRadio.a    \
+    $(NULL)
+
+LDFLAGS_COMMON                                                                                 += \
+    -T $(top_srcdir)/examples/platforms/k32w/k32w061/k32w061.ld                                   \
+    $(NULL)
diff --git a/examples/platforms/k32w/k32w061/README.md b/examples/platforms/k32w/k32w061/README.md
new file mode 100755
index 0000000..281ef21
--- /dev/null
+++ b/examples/platforms/k32w/k32w061/README.md
@@ -0,0 +1,125 @@
+# OpenThread on NXP K32W061 Example
+
+This directory contains example platform drivers for the [NXP K32W061][k32w061] based on [K32W061-DK006][k32w061-dk006] hardware platform.
+
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. As a result, the example platform drivers do not necessarily highlight the platform's full capabilities.
+
+## Toolchain
+
+OpenThread environment is suited to be run on a Linux-based OS. Recommended OS is Ubuntu 18.04.2 LTS. Download and install the [MCUXpresso IDE][mcuxpresso ide].
+
+[mcuxpresso ide]: https://www.nxp.com/support/developer-resources/software-development-tools/mcuxpresso-software-and-tools/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE
+
+In a Bash terminal (found, for example, in Ubuntu OS), follow these instructions to install the GNU toolchain and other dependencies.
+
+```bash
+$ cd <path-to-openthread>
+$ ./script/bootstrap
+```
+
+If a network connection timeout is encountered, re-run the script.
+
+Python-pip is also required for the build. User can install it by running "sudo apt-get install python-pip" in bash. After installing Python-pip, execute "pip install pycryptodome" in bash. This is needed for signing the built binary in order to load it on the board. Also, pycrypto "pip install pycrypto" is required for PKCS1.
+
+Windows 10 offers the possibility of running bash by installing "Ubuntu on Windows" from Microsoft Store. This application allows the user to use Ubuntu Terminal and run Ubuntu command line utilities including bash, ssh, git, apt and many more. If this option is used, it is recommended to add instructions for the path mapping in MCUXpresso IDE. This can be done after adding the project to the workspace by going to Run->"Debug Configuration"->"C/C++(NXP Semiconductors) MCU Application"->Source->Add. Then the user should create a path mapping such that MCUXpresso IDE will find the mount point for the "Ubuntu in Windows" subsystem. For example, user can enter compilation path recognized by Ubuntu as /mnt/c/<path-to-openthread>, while equivalent "Local file system path" is C:/<path-to-openthread>. This example assumes that the openthread package is installed on the C drive.
+
+## Build Examples
+
+```bash
+$ cd <path-to-openthread>
+$ ./bootstrap
+$ make -f examples/Makefile-k32w061
+```
+
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/k32w061/bin`.
+
+## Flash Binaries
+
+Connect to the board by plugging a mini-USB cable to the connector marked with TARGET on the DK6 board. This connector is situated on the same side with the power connector.
+
+OpenThread example application compiled binaries can be found in `<path-to-openthread>/output/k32w061/bin` and include FTD (Full Thread Device) and MTD (Minimal Thread Device) variants of CLI and NCP applications. The compiled binaries can be flashed onto the K32W061 using MCUXpresso IDE. This requires the following steps:
+
+1. Import the K32W061 SDK into MCUXpresso IDE. This can be done by dragging and dropping the SDK archive into MCUXpresso IDE's Installed SDKs tab. The archive for SDK_2.6.0_K32W061DK6 is available for download at https://mcuxpresso.nxp.com/en/welcome
+2. In MCUXpresso IDE, go to File->Import->C/C++->"Existing Code as Makefile Project" and click Next.
+3. Select the OpenThread folder as the "Existing Code Location". In the "Toolchain for Indexer Settings" list, be sure to keep the setting to <none>. Click Finish.
+4. Right click on the newly created openthread project in the Workspace and go to Properties->"C/C++ Build"->"MCU Settings". Select the JN518x from the SDK MCUs list.
+5. Go to C/C++ Build->"Tool Chain Editor" and untick the "Display compatible toolchains only" checkbox. In the drop-down menu named "Current toolchain", select "NXP MCU Tools". Click "Apply and Close".
+6. Right click on the openthread project and select "Debug As"->"MCUXpresso IDE LinkServer (inc. CMSIS-DAP) probes"
+7. A window to select the binary will appear. Select "output/k32w061/bin/ot-<application>" and click Ok.
+8. Under the menu bar, towards the center of the screen, there is a green bug icon with a drop-down arrow next to it. Click on the arrow and select "Debug Configurations".
+9. In the right side of the Debug Configurations window, go to "C/C++ (NXP Semiconductors) MCU Application"->"openthread LinkServer Default".
+10. Make sure that in the "C/C++ Application:" text box contains "output\k32w061\bin\ot-<application>" path.
+11. Go to "GUI Flash Tool" tab. In "Target Operations"->Program->Options, select "bin" as the "Format to use for programming". Make sure the "Base address" is 0x0.
+12. Click Debug.
+13. A pop-up window entitled "Errors in Workspace" will appear. Click Proceed.
+14. The board is now flashed.
+
+[cmsis-dap]: https://os.mbed.com/handbook/CMSIS-DAP
+
+## Running the example
+
+1. Prepare two boards with the flashed `CLI Example` (as shown above). Make sure that the JN4 jumper is set to RX and the JN7 jumper is set to TX, connecting the LPC and JN UART0 pins.
+2. The CLI example uses UART connection. To view raw UART output, start a terminal emulator like PuTTY and connect to the used COM port with the following UART settings:
+
+   - Baud rate: 115200
+   - 8 data bits
+   - 1 stop bit
+   - No parity
+   - No flow control
+
+3. Open a terminal connection on the first board and start a new Thread network.
+
+```bash
+> panid 0xabcd
+Done
+> ifconfig up
+Done
+> thread start
+Done
+```
+
+4. After a couple of seconds the node will become a Leader of the network.
+
+```bash
+> state
+Leader
+```
+
+5. Open a terminal connection on the second board and attach a node to the network.
+
+```bash
+> panid 0xabcd
+Done
+> ifconfig up
+Done
+> thread start
+Done
+```
+
+6. After a couple of seconds the second node will attach and become a Child.
+
+```bash
+> state
+Child
+```
+
+7. List all IPv6 addresses of the first board.
+
+```bash
+> ipaddr
+fdde:ad00:beef:0:0:ff:fe00:fc00
+fdde:ad00:beef:0:0:ff:fe00:9c00
+fdde:ad00:beef:0:4bcb:73a5:7c28:318e
+fe80:0:0:0:5c91:c61:b67c:271c
+```
+
+8. Choose one of them and send an ICMPv6 ping from the second board.
+
+```bash
+> ping fdde:ad00:beef:0:0:ff:fe00:fc00
+16 bytes from fdde:ad00:beef:0:0:ff:fe00:fc00: icmp_seq=1 hlim=64 time=8ms
+```
+
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
+
+[cli]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
diff --git a/examples/platforms/k32w/k32w061/k32w061-mbedtls-config.h b/examples/platforms/k32w/k32w061/k32w061-mbedtls-config.h
new file mode 100755
index 0000000..c82b351
--- /dev/null
+++ b/examples/platforms/k32w/k32w061/k32w061-mbedtls-config.h
@@ -0,0 +1,248 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef K32W061_MBEDTLS_CONFIG_H
+#define K32W061_MBEDTLS_CONFIG_H
+
+#if defined(MBEDTLS_ECP_WINDOW_SIZE)
+#undef MBEDTLS_ECP_WINDOW_SIZE
+#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */
+#endif
+
+#if defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
+#undef MBEDTLS_ECP_FIXED_POINT_OPTIM
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
+#endif
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * Enable hardware acceleration for the AES block cipher
+ *
+ * See MBEDTLS_AES_C for more information.
+ */
+#define MBEDTLS_AES_ALT
+
+#if defined(MBEDTLS_AES_ALT)
+/**************************** KSDK ********************************************/
+#include "fsl_device_registers.h"
+
+/* Enable LTC use in library if there is LTC on chip. */
+#if defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0)
+#include "fsl_ltc.h"
+
+#define LTC_INSTANCE LTC0 /* LTC base register.*/
+
+#if FSL_FEATURE_LTC_HAS_SHA
+#define MBEDTLS_FREESCALE_LTC_SHA1   /* Enable use of LTC SHA.*/
+#define MBEDTLS_FREESCALE_LTC_SHA256 /* Enable use of LTC SHA256.*/
+#endif
+#if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES
+#define MBEDTLS_FREESCALE_LTC_DES /* Enable use of LTC DES.*/
+#endif
+#define MBEDTLS_FREESCALE_LTC_AES /* Enable use of LTC AES.*/
+#if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM
+#define MBEDTLS_FREESCALE_LTC_AES_GCM /* Enable use of LTC AES GCM.*/
+#endif
+#if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
+#define MBEDTLS_FREESCALE_LTC_PKHA /* Enable use of LTC PKHA.*/
+#define FREESCALE_PKHA_INT_MAX_BYTES 256
+#endif
+#endif
+
+/* Enable MMCAU use in library if there is MMCAU on chip. */
+#if defined(FSL_FEATURE_SOC_MMCAU_COUNT) && (FSL_FEATURE_SOC_MMCAU_COUNT > 0)
+#include "fsl_mmcau.h"
+
+#define MBEDTLS_FREESCALE_MMCAU_MD5    /* Enable use of MMCAU MD5.*/
+#define MBEDTLS_FREESCALE_MMCAU_SHA1   /* Enable use of MMCAU SHA1.*/
+#define MBEDTLS_FREESCALE_MMCAU_SHA256 /* Enable use of MMCAU SHA256.*/
+#define MBEDTLS_FREESCALE_MMCAU_DES    /* Enable use of MMCAU DES, when LTC is disabled.*/
+#define MBEDTLS_FREESCALE_MMCAU_AES    /* Enable use of MMCAU AES, when LTC is disabled.*/
+#endif
+
+/* Enable CAU3 use in library if there is CAU3 on chip. */
+#if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)
+#include "cau3_pkha.h"
+#include "fsl_cau3.h"
+
+#define MBEDTLS_CAU3_COMPLETION_SIGNAL CAU3_CC_CMD_EVT
+#define MBEDTLS_SHA256_ALT_NO_224
+
+#define MBEDTLS_FREESCALE_CAU3_AES    /* Enable use of CAU3 AES.*/
+#define MBEDTLS_FREESCALE_CAU3_SHA256 /* Enable use of CAU3 SHA256.*/
+#define MBEDTLS_FREESCALE_CAU3_PKHA   /* Enable use of CAU3 PKHA.*/
+#define FREESCALE_PKHA_INT_MAX_BYTES 512
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+/*
+ * This FREESCALE_PKHA_LONG_OPERANDS_ENABLE macro can be defined.
+ * In such a case both software and hardware algorithm for TFM is linked in.
+ * The decision for which algorithm is used is determined at runtime
+ * from size of inputs. If inputs and result can fit into LTC (see FREESCALE_PKHA_INT_MAX_BYTES)
+ * then we call hardware algorithm, otherwise we call software algorithm.
+ *
+ * Note that mbedTLS algorithms break modular operations unefficiently into two steps.
+ * First is normal operation, for example non-modular multiply, which can produce number
+ * with greater size than operands. Second is modular reduction.
+ * The implication of this is that if for example FREESCALE_PKHA_INT_MAX_BYTES is 256 (2048 bits),
+ * RSA-2048 still requires the FREESCALE_PKHA_LONG_OPERANDS_ENABLE macro to be defined,
+ * otherwise it fails at runtime.
+ */
+//#define FREESCALE_PKHA_LONG_OPERANDS_ENABLE
+#endif
+
+/* Enable AES use in library if there is AES on chip. */
+#if defined(FSL_FEATURE_SOC_AES_COUNT) && (FSL_FEATURE_SOC_AES_COUNT > 0)
+#include "fsl_aes.h"
+
+#define AES_INSTANCE AES0             /* AES base register.*/
+#define MBEDTLS_FREESCALE_LPC_AES     /* Enable use of LPC AES.*/
+#define MBEDTLS_FREESCALE_LPC_AES_GCM /* Enable use of LPC AES GCM.*/
+
+#endif
+
+/* Enable SHA use in library if there is SHA on chip. */
+#if defined(FSL_FEATURE_SOC_SHA_COUNT) && (FSL_FEATURE_SOC_SHA_COUNT > 0)
+#include "fsl_sha.h"
+
+//#define SHA_INSTANCE SHA0            /* AES base register.*/
+#define MBEDTLS_FREESCALE_LPC_SHA1 /* Enable use of LPC SHA.*/
+//#define MBEDTLS_FREESCALE_LPC_SHA256 /* Enable use of LPC SHA256.*/
+
+#endif
+
+/* Define ALT MMCAU & LTC functions. Do not change it. */
+#if defined(MBEDTLS_FREESCALE_MMCAU_DES) || defined(MBEDTLS_FREESCALE_LTC_DES)
+#define MBEDTLS_DES_SETKEY_ENC_ALT
+#define MBEDTLS_DES_SETKEY_DEC_ALT
+#define MBEDTLS_DES_CRYPT_ECB_ALT
+#define MBEDTLS_DES3_CRYPT_ECB_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_DES)
+#define MBEDTLS_DES_CRYPT_CBC_ALT
+#define MBEDTLS_DES3_CRYPT_CBC_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_MMCAU_AES) || \
+    defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES)
+#define MBEDTLS_AES_SETKEY_ENC_ALT
+#define MBEDTLS_AES_SETKEY_DEC_ALT
+#define MBEDTLS_AES_ENCRYPT_ALT
+#define MBEDTLS_AES_DECRYPT_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+#define MBEDTLS_AES_CRYPT_CBC_ALT
+#define MBEDTLS_AES_CRYPT_CTR_ALT
+#define MBEDTLS_CCM_CRYPT_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_AES_GCM) || defined(MBEDTLS_FREESCALE_LPC_AES_GCM)
+#define MBEDTLS_GCM_CRYPT_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+#define MBEDTLS_MPI_ADD_ABS_ALT
+#define MBEDTLS_MPI_SUB_ABS_ALT
+#define MBEDTLS_MPI_MUL_MPI_ALT
+#define MBEDTLS_MPI_MOD_MPI_ALT
+#define MBEDTLS_MPI_EXP_MOD_ALT
+#define MBEDTLS_MPI_GCD_ALT
+#define MBEDTLS_MPI_INV_MOD_ALT
+#define MBEDTLS_MPI_IS_PRIME_ALT
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA)
+#define MBEDTLS_ECP_MUL_COMB_ALT
+#define MBEDTLS_ECP_ADD_ALT
+#endif
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_SHA1) || defined(MBEDTLS_FREESCALE_LPC_SHA1)
+#define MBEDTLS_SHA1_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_SHA256) || defined(MBEDTLS_FREESCALE_LPC_SHA256)
+//#define MBEDTLS_SHA256_ALT
+/*
+ * LPC SHA module does not support SHA-224.
+ *
+ * Since mbed TLS does not provide separate APIs for SHA-224 and SHA-256
+ * and SHA-224 is not widely used, this implementation provides HW accelerated SHA-256 only
+ * and SHA-224 is not available at all (calls will fail).
+ *
+ * To use SHA-224 on LPC, do not define MBEDTLS_SHA256_ALT and both SHA-224 and SHA-256 will use
+ * original mbed TLS software implementation.
+ */
+#if defined(MBEDTLS_FREESCALE_LPC_SHA256)
+#define MBEDTLS_SHA256_ALT_NO_224
+#endif
+#endif
+#if defined(MBEDTLS_FREESCALE_MMCAU_MD5)
+#define MBEDTLS_MD5_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_MMCAU_SHA1)
+#define MBEDTLS_SHA1_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_MMCAU_SHA256)
+#define MBEDTLS_SHA256_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_CAU3_SHA256)
+#define MBEDTLS_SHA256_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_CAU3_AES)
+#define MBEDTLS_AES_ALT_NO_192
+#endif
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+#if !defined(FSL_FEATURE_LTC_HAS_AES192) || !FSL_FEATURE_LTC_HAS_AES192
+#define MBEDTLS_AES_ALT_NO_192
+#endif
+#if !defined(FSL_FEATURE_LTC_HAS_AES256) || !FSL_FEATURE_LTC_HAS_AES256
+#define MBEDTLS_AES_ALT_NO_256
+#endif
+#endif
+#if defined(MBEDTLS_FREESCALE_LPC_AES)
+#define MBEDTLS_AES_CRYPT_CBC_ALT
+#define MBEDTLS_AES_CRYPT_CFB_ALT
+#define MBEDTLS_AES_CRYPT_CTR_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LPC_SHA1)
+#define MBEDTLS_SHA1_PROCESS_ALT
+#endif
+#if defined(MBEDTLS_FREESCALE_LPC_SHA256)
+#define MBEDTLS_SHA256_PROCESS_ALT
+#endif
+
+#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
+#include "FreeRTOS.h"
+
+void *pvPortCalloc(size_t num, size_t size); /*Calloc for HEAP3.*/
+
+#define MBEDTLS_PLATFORM_MEMORY
+#define MBEDTLS_PLATFORM_STD_CALLOC pvPortCalloc
+#define MBEDTLS_PLATFORM_STD_FREE vPortFree
+
+#endif /* USE_RTOS*/
+/**************************** KSDK end ****************************************/
+#endif /* MBEDTLS_AES_ALT || MBEDTLS_SHA256_ALT */
+
+#endif // K32W061_MBEDTLS_CONFIG_H
diff --git a/examples/platforms/k32w/k32w061/k32w061.ld b/examples/platforms/k32w/k32w061/k32w061.ld
new file mode 100755
index 0000000..fbebd64
--- /dev/null
+++ b/examples/platforms/k32w/k32w061/k32w061.ld
@@ -0,0 +1,304 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   GCC linker script for K32W061.
+ */
+
+/*
+ * stack size for the boot rom during warm boot and application
+ * 256 is sufficient (pwrm_test) but keep it large to 1024
+ */
+BOOT_RESUME_STACK_SIZE = 1024;
+
+/* Set Stack size to 4K minus 32Bytes reserved for ROM code at end of BANK7 so
+   the stack fits in BANK7. In practice the active stack size at the time of
+   going to sleep is more important than the total available stack size */
+STACK_SIZE             = (4096 - 32);
+
+MEM_RAM0_BASE = 0x4000400;
+MEM_RAM0_SIZE = 0x0015c00;
+
+MEMORY
+{
+  /* Define each memory region. RAM0 definition leaves the first 1kB for the
+     boot code */
+  Flash640 (rx) : ORIGIN = 0, LENGTH = 0x00a0000            /* 640K bytes (alias Flash) */
+  RAM0 (rwx)    : ORIGIN = 0x4000400,  LENGTH = 0x0015c00   /* 87K bytes (alias RAM) */
+  RAM1 (rwx)    : ORIGIN = 0x4020000,      LENGTH = 0x10000 /* 64K bytes (alias RAM2) */
+}
+
+/* Define a symbol for the top of each memory region */
+__top_RAM0      = MEM_RAM0_BASE + MEM_RAM0_SIZE; /* 87K bytes */
+
+HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x2F4;
+
+/*** flash memory characteristics definitions required for OTA ***/
+m_flash_start   = 0x00000000;
+m_flash_end     = 0x0009FFFF;
+m_flash_size    = 0x000A0000;
+m_sector_size   = 512;
+m_fsl_prodInfo_size = m_sector_size;
+
+m_fsl_prodInfo_end                             = m_flash_size - 17 * m_sector_size - 1;
+m_fsl_prodInfo_start                           = m_fsl_prodInfo_end - m_fsl_prodInfo_size + 1;
+
+NV_STORAGE_MAX_SECTORS                         = 64;
+NV_STORAGE_SIZE                                = NV_STORAGE_MAX_SECTORS * m_sector_size;
+NV_STORAGE_END_ADDRESS                         = m_fsl_prodInfo_start - 1;
+NV_STORAGE_START_ADDRESS                       = NV_STORAGE_END_ADDRESS - NV_STORAGE_SIZE + 1;
+
+INT_STORAGE_END                                = NV_STORAGE_START_ADDRESS - 1;
+INT_STORAGE_START                              = 0x48000;
+INT_STORAGE_SIZE                               = INT_STORAGE_END - INT_STORAGE_START;
+
+FREESCALE_PROD_DATA_BASE_ADDR                  = m_fsl_prodInfo_start;
+INT_STORAGE_SECTOR_SIZE                        = m_sector_size;
+m_app_size                                     = 0x48000;
+
+ENTRY(ResetISR)
+
+SECTIONS
+{
+    /* MAIN TEXT SECTION */
+    .header : ALIGN(4)
+    {
+        _flash_start = ABSOLUTE(.);
+        _flash_beg = ABSOLUTE(.);
+
+        FILL(0xff)
+        __vectors_start__ = ABSOLUTE(.) ;
+        KEEP(*(.isr_vector))
+        /* Global Section Table */
+        . = ALIGN(4) ;
+        __section_table_start = .;
+        __data_section_table = .;
+        LONG(LOADADDR(.data));
+        LONG(    ADDR(.data));
+        LONG(  SIZEOF(.data));
+        LONG(LOADADDR(.data_RAM2));
+        LONG(    ADDR(.data_RAM2));
+        LONG(  SIZEOF(.data_RAM2));
+        __data_section_table_end = .;
+        __bss_section_table = .;
+        LONG(    ADDR(.bss));
+        LONG(  SIZEOF(.bss));
+        LONG(    ADDR(.bss_RAM2));
+        LONG(  SIZEOF(.bss_RAM2));
+        __bss_section_table_end = .;
+        __section_table_end = . ;
+        /* End of Global Section Table */
+
+        FILL(0xff)
+        . = ALIGN (0x10);
+    } >Flash640
+
+    .ro_nonce : ALIGN(0x10)
+    {
+        _FlsNonceStart = ABSOLUTE(.);
+        *(.ro_nonce) /* nonce value is 16 bytes.*/
+        FILL(0xff)
+        . = ALIGN (0x10);
+    } > Flash640
+
+    .ro_ota_header : ALIGN(0x10)
+    {
+        _enc_start = ABSOLUTE(.);
+        _enc_offset = (_enc_start & 0x0000000F);
+        _FlsOtaHeader = ABSOLUTE(.);
+        *(.ro_ota_header) /* Ota Header 69 bytes*/
+        FILL(0xff)
+        . = ALIGN (0x10);
+    } > Flash640
+
+    .ro_se_lnkKey (ALIGN((. - _enc_offset), 16) + _enc_offset):
+    {
+        _FlsLinkKey = ABSOLUTE(.);
+        *(.ro_se_lnkKey)  /* Link Key 16 bytes*/
+        FILL(0xff)
+        . = ALIGN (0x10);
+    } > Flash640
+
+    .filler :
+    {
+        BYTE(0xff)
+        FILL(0xff);
+        . = ALIGN(0x40);
+    } > Flash640
+
+    .text : ALIGN(0x40)
+    {
+        FILL(0xff)
+
+       *(.after_vectors*)
+       *(.text*)
+        *(.rodata .rodata.* .constdata .constdata.*)
+        . = ALIGN(4);
+    } > Flash640
+    /*
+     * for exception handling/unwind - some Newlib functions (in common
+     * with C++ and STDC++) use this.
+     */
+    .ARM.extab : ALIGN(4)
+    {
+       FILL(0xff)
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+    } > Flash640
+    __exidx_start = .;
+
+    .ARM.exidx : ALIGN(4)
+    {
+       FILL(0xff)
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > Flash640
+    __exidx_end = .;
+
+    _etext = .;
+
+    /* RAM1/RAM2 (different names for same thing) SECTION */
+    /* RAM1 contents are specified before RAM0 as they have specific input
+       sections and we do not want the RAM0 wildcards to catch them */
+    /* DATA section for RAM1 */
+    .data_RAM2 : ALIGN(4)
+    {
+        FILL(0xff)
+        PROVIDE(__start_data_RAM2 = .) ;
+        *(.ramfunc.$RAM2)
+        *(.ramfunc.$RAM1)
+        *(.data.$RAM2*)
+        *(.data.$RAM1*)
+        . = ALIGN(4) ;
+        PROVIDE(__end_data_RAM2 = .) ;
+     } > RAM1 AT>Flash640
+
+    /* MAIN DATA SECTION */
+    .uninit_RESERVED : ALIGN(4)
+    {
+        KEEP(*(.bss.$RESERVED*))
+        . = ALIGN(4) ;
+        _end_uninit_RESERVED = .;
+    } > RAM0
+
+    /* Main DATA section (RAM0) */
+    .data : ALIGN(4)
+    {
+       FILL(0xff)
+       _data = . ;
+       *(vtable)
+       *(.ramfunc*)
+       *(.data*)
+       . = ALIGN(4) ;
+       _edata = . ;
+    } > RAM0 AT>Flash640
+
+
+    /* BSS section for RAM1 */
+    .bss_RAM2 (NOLOAD) : ALIGN(4)
+    {
+       PROVIDE(__start_bss_RAM2 = .) ;
+       *(.bss.$RAM2*)
+       *(.bss.$RAM1*)
+       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
+       PROVIDE(__end_bss_RAM2 = .) ;
+    } > RAM1
+
+    /* MAIN BSS SECTION */
+    .bss (NOLOAD) : ALIGN(4)
+    {
+        _bss = .;
+        *(.bss*)
+        *(COMMON)
+        *(g_u32NwkFrameCounter)
+        . = ALIGN(4) ;
+        _ebss = .;
+
+        PROVIDE(end = .);
+    } > RAM0
+
+    /* BSS section for MAC buffers */
+    .bss_MAC (NOLOAD) : ALIGN(4)
+    {
+       /* MAC buffer section: must be within 128kB block. __mac_buffer_base is
+          defined further down to be on 128kB alignment */
+        __mac_buffer_start = .;
+       *(.mac_buffer)
+
+        . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
+    } > RAM0
+
+    /* HEAP */
+    .heap (NOLOAD): ALIGN(4)
+    {
+        _heap = .;
+        . += HEAP_SIZE;
+        . = ALIGN(4) ;
+        _end_heap = .;
+    } > RAM0
+
+    /* NOINIT section for RAM1 */
+    .noinit_RAM2 (NOLOAD) : ALIGN(4)
+    {
+       *(.noinit.$RAM2*)
+       *(.noinit.$RAM1*)
+       . = ALIGN(4) ;
+    } > RAM1
+
+    /* DEFAULT NOINIT SECTION */
+    .noinit (NOLOAD): ALIGN(4)
+    {
+        _noinit = .;
+        *(.noinit*)
+        . = ALIGN(4) ;
+        _end_noinit = .;
+    } > RAM0
+
+    /* stack for rom boot during warm resume */
+    .boot_resume_stack (NOLOAD): ALIGN(4)
+    {
+        _boot_resume_stack = .;
+        *(.boot_resume_stack*)
+        . += BOOT_RESUME_STACK_SIZE;
+        . = ALIGN(4) ;
+        _end_boot_resume_stack = .;
+    } > RAM0
+
+    __nv_storage_end_address = NV_STORAGE_END_ADDRESS;
+    __nv_storage_start_address = NV_STORAGE_START_ADDRESS;
+
+    PROVIDE(_vStackTop = __top_RAM0 - 32);
+    PROVIDE(__mac_buffer_base = (__mac_buffer_start & 0xfffe0000));
+    PROVIDE(BOOT_GetStartPowerMode = 0x03000e9d);
+    PROVIDE(ROM_GetFlash = 0x03000e0d);
+    PROVIDE(pmc_reset_get_cause = 0x030046e9);
+    PROVIDE(psector_ReadIeee802_15_4_MacId1 = 0x030053b1);
+    PROVIDE(Chip_LOWPOWER_ChipSoftwareReset = 0x03003fa1);
+
+    __StackLimit = _vStackTop - STACK_SIZE;
+    ASSERT(__StackLimit >= _end_boot_resume_stack, "Possible stack corruption with data/bss/boot_stack")
+}
\ No newline at end of file
diff --git a/examples/platforms/k32w/k32w061/openthread-core-k32w061-config-check.h b/examples/platforms/k32w/k32w061/openthread-core-k32w061-config-check.h
new file mode 100755
index 0000000..95a1124
--- /dev/null
+++ b/examples/platforms/k32w/k32w061/openthread-core-k32w061-config-check.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OPENTHREAD_CORE_K32W061_CONFIG_CHECK_H_
+#define OPENTHREAD_CORE_K32W061_CONFIG_CHECK_H_
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+#error "Platform k32w061 doesn't support configuration option: OPENTHREAD_CONFIG_TIME_SYNC_ENABLE"
+#endif
+
+#ifndef RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
+#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+#error "Platform k32w061 not configured to support configuration option: OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT"
+#endif
+#endif
+
+#endif /* OPENTHREAD_CORE_K32W061_CONFIG_CHECK_H_ */
diff --git a/examples/platforms/k32w/k32w061/openthread-core-k32w061-config.h b/examples/platforms/k32w/k32w061/openthread-core-k32w061-config.h
new file mode 100755
index 0000000..bd2efab
--- /dev/null
+++ b/examples/platforms/k32w/k32w061/openthread-core-k32w061-config.h
@@ -0,0 +1,214 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes k32w061 compile-time configuration constants
+ *   for OpenThread.
+ */
+
+#ifndef OPENTHREAD_CORE_K32W061_CONFIG_H_
+#define OPENTHREAD_CORE_K32W061_CONFIG_H_
+
+/**
+ * @def OPENTHREAD_CONFIG_LOG_OUTPUT
+ *
+ * The emsk platform provides an otPlatLog() function.
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
+#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_INFO
+ *
+ * The platform-specific string to insert into the OpenThread version string.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_INFO "K32W061"
+
+/**
+ * @def SETTINGS_CONFIG_BASE_ADDRESS
+ *
+ * The base address of settings.
+ *
+ */
+#define SETTINGS_CONFIG_BASE_ADDRESS 0
+
+/**
+ * @def SETTINGS_CONFIG_PAGE_SIZE
+ *
+ * The page size of settings.
+ *
+ */
+#define SETTINGS_CONFIG_PAGE_SIZE 0x200
+
+/**
+ * @def SETTINGS_CONFIG_PAGE_NUM
+ *
+ * The page number of settings.
+ *
+ */
+
+#define SETTINGS_CONFIG_PAGE_NUM 64
+
+/**
+ * @def RADIO_CONFIG_SRC_MATCH_ENTRY_NUM
+ *
+ * The number of source address table entries.
+ *
+ */
+#define RADIO_CONFIG_SRC_MATCH_ENTRY_NUM 128
+
+/**
+ * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT
+ *
+ * Define to 1 if you want to enable software retransmission logic.
+ *
+ */
+/* TODO */
+
+/**
+ * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF
+ *
+ * Define to 1 if you want to enable software CSMA-CA backoff logic.
+ *
+ */
+/* TODO */
+
+/**
+ * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
+ *
+ * Define to 1 to enable NCP UART support.
+ *
+ */
+#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1
+
+/**
+ * @def OPENTHREAD_SETTINGS_RAM
+ *
+ * Define to 1 if you want to use K32W061 Flash implementation.
+ *
+ */
+#define OPENTHREAD_SETTINGS_RAM 1
+
+/**
+ * @def OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE
+ *
+ * The size of NCP message buffer in bytes.
+ *
+ */
+#define OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE 1024
+
+/**
+ * @def OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE
+ *
+ * The size of heap buffer when DTLS is enabled.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE
+#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE (2048 * sizeof(void *))
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_COAP_API_ENABLE
+ *
+ * Define to 1 to enable the CoAP API.
+ *
+ */
+#define OPENTHREAD_CONFIG_COAP_API_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_JOINER_ENABLE
+ *
+ * Define to 1 to enable Joiner support.
+ *
+ */
+#define OPENTHREAD_CONFIG_JOINER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
+ *
+ * Define to 1 to enable Commissioner support.
+ *
+ */
+#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
+ *
+ * Define to 1 to enable UDP forward support.
+ *
+ */
+#define OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
+ *
+ * Define to 1 to enable the Border Router service.
+ *
+ */
+#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
+ *
+ * Define to 1 to enable the DHCP CLIENT service.
+ *
+ */
+#define OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
+ *
+ * Define to 1 to enable the DHCP SERVER service.
+ *
+ */
+#define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+ *
+ * Define as 1 to enable the time synchronization service feature.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+#define OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_DIAG_ENABLE
+ *
+ * Define as 1 to enable the diag feature.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_DIAG_ENABLE
+#define OPENTHREAD_CONFIG_DIAG_ENABLE 0
+#endif
+
+#endif // OPENTHREAD_CORE_K32W061_CONFIG_H_
diff --git a/examples/platforms/k32w/src/alarm.c b/examples/platforms/k32w/src/alarm.c
new file mode 100755
index 0000000..5919fd2
--- /dev/null
+++ b/examples/platforms/k32w/src/alarm.c
@@ -0,0 +1,234 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for the alarm.
+ *
+ */
+
+/* Openthread configuration */
+#include OPENTHREAD_PROJECT_CORE_CONFIG_FILE
+
+#include "fsl_clock.h"
+#include "fsl_ctimer.h"
+#include "fsl_device_registers.h"
+#include "fsl_wtimer.h"
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+
+#define ALARM_USE_CTIMER 0
+#define ALARM_USE_WTIMER 1
+
+/* Timer frequency in Hz needed for 1ms tick */
+#define TARGET_FREQ 1000U
+/* Wake Timer max count value that is loaded in the register */
+#define TIMER0_MAX_COUNT_VALUE 0xffffffff
+#define TIMER1_MAX_COUNT_VALUE 0x0fffffff
+
+static bool     sEventFired = false;
+static uint32_t refClk;
+
+#if ALARM_USE_CTIMER
+/* Match Configuration for Channel 0 */
+static ctimer_match_config_t sMatchConfig = {.enableCounterReset = false,
+                                             .enableCounterStop  = false,
+                                             .matchValue         = 0x00,
+                                             .outControl         = kCTIMER_Output_NoAction,
+                                             .outPinInitState    = false,
+                                             .enableInterrupt    = true};
+#else
+static uint32_t sRemainingTicks;
+#endif
+
+void K32WAlarmInit(void)
+{
+#if ALARM_USE_CTIMER
+    ctimer_config_t config;
+    CTIMER_GetDefaultConfig(&config);
+
+    /* Get clk frequency and use prescale to lower it */
+    refClk = CLOCK_GetFreq(kCLOCK_Timer0);
+
+    config.prescale = refClk / TARGET_FREQ;
+    CTIMER_Init(CTIMER0, &config);
+    CTIMER_StartTimer(CTIMER0);
+
+    CTIMER_EnableInterrupts(CTIMER0, kCTIMER_Match0InterruptEnable);
+    NVIC_ClearPendingIRQ(Timer0_IRQn);
+    NVIC_EnableIRQ(Timer0_IRQn);
+
+#else
+    RESET_PeripheralReset(kWKT_RST_SHIFT_RSTn);
+    WTIMER_Init();
+
+    /* Get clk frequency and use prescale to lower it */
+    refClk = CLOCK_GetFreq(kCLOCK_Xtal32k);
+
+    /* Wake timer 0 is 41 bits long and is used for keepig the timestamp */
+    WTIMER_EnableInterrupts(WTIMER_TIMER0_ID);
+    /* Wake timer 1 is 28 bits long and is used for alarm events, including waking up the MCU
+       from sleep */
+    WTIMER_EnableInterrupts(WTIMER_TIMER1_ID);
+
+    /* Start wake timer 0 counter for timestamp - the counter counts down to 0 so a simple
+       substracion from TIMER0_MAX_COUNT_VALUE will give us the timestamp */
+    WTIMER_StartTimer(WTIMER_TIMER0_ID, TIMER0_MAX_COUNT_VALUE);
+#endif
+}
+
+void K32WAlarmClean(void)
+{
+#if ALARM_USE_CTIMER
+    CTIMER_StopTimer(CTIMER0);
+    CTIMER_Deinit(CTIMER0);
+    CTIMER_DisableInterrupts(CTIMER0, kCTIMER_Match0InterruptEnable);
+    NVIC_ClearPendingIRQ(Timer0_IRQn);
+#else
+    WTIMER_StopTimer(WTIMER_TIMER0_ID);
+    WTIMER_StopTimer(WTIMER_TIMER1_ID);
+    WTIMER_DeInit();
+
+    NVIC_DisableIRQ(WAKE_UP_TIMER0_IRQn);
+    NVIC_ClearPendingIRQ(WAKE_UP_TIMER0_IRQn);
+    NVIC_DisableIRQ(WAKE_UP_TIMER1_IRQn);
+    NVIC_ClearPendingIRQ(WAKE_UP_TIMER1_IRQn);
+#endif
+}
+
+void K32WAlarmProcess(otInstance *aInstance)
+{
+    if (sEventFired)
+    {
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+        if (otPlatDiagModeGet())
+        {
+            otPlatDiagAlarmFired(aInstance);
+        }
+        else
+#endif
+        {
+            otPlatAlarmMilliFired(aInstance);
+        }
+    }
+}
+
+void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+#if ALARM_USE_CTIMER
+    /* Load match register with current counter + app time */
+    sMatchConfig.matchValue = aT0 + aDt;
+
+    CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_0, &sMatchConfig);
+#else
+    /* Calculate the difference between now and the requested timestamp aT0 - this time will be
+       substracted from the total time until the event needs to fire */
+    uint32_t timestamp = otPlatAlarmMilliGetNow();
+    timestamp          = timestamp - aT0;
+
+    uint64_t targetTicks = ((aDt - timestamp) * refClk) / TARGET_FREQ;
+
+    /* Because timer 1 is only 28 bits long we need to take into account and event longer than this
+       so we arm the timer with the maximum value and re-arm with the remaing time once it fires */
+    if (targetTicks < TIMER1_MAX_COUNT_VALUE)
+    {
+        WTIMER_StartTimer(WTIMER_TIMER1_ID, targetTicks);
+        sRemainingTicks = 0;
+    }
+    else
+    {
+        WTIMER_StartTimer(WTIMER_TIMER1_ID, TIMER1_MAX_COUNT_VALUE);
+        sRemainingTicks = targetTicks - TIMER1_MAX_COUNT_VALUE;
+    }
+
+#endif
+}
+
+void otPlatAlarmMilliStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sEventFired = false;
+
+#if ALARM_USE_CTIMER
+    sMatchConfig.matchValue = 0;
+    CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_0, &sMatchConfig);
+#else
+    sRemainingTicks = 0;
+    WTIMER_StopTimer(WTIMER_TIMER1_ID);
+#endif
+}
+
+uint32_t otPlatAlarmMilliGetNow(void)
+{
+#if ALARM_USE_CTIMER
+    return CTIMER0->TC;
+#else
+    uint32_t timestamp  = WTIMER_ReadTimerSafe(WTIMER_TIMER0_ID);
+    uint64_t tempTstamp = (TIMER0_MAX_COUNT_VALUE - timestamp);
+
+    tempTstamp *= TARGET_FREQ;
+    tempTstamp /= refClk;
+    return (uint32_t)tempTstamp;
+#endif
+}
+
+#if ALARM_USE_CTIMER
+/**
+ * Timer interrupt handler function.
+ *
+ */
+void CTIMER0_IRQHandler(void)
+{
+    uint32_t flags = CTIMER_GetStatusFlags(CTIMER0);
+    CTIMER_ClearStatusFlags(CTIMER0, flags);
+    sEventFired = true;
+}
+#else
+void WAKE_UP_TIMER0_DriverIRQHandler()
+{
+    WTIMER_ClearStatusFlags(WTIMER_TIMER0_ID);
+    WTIMER_StartTimer(WTIMER_TIMER0_ID, TIMER0_MAX_COUNT_VALUE);
+}
+void WAKE_UP_TIMER1_DriverIRQHandler()
+{
+    WTIMER_ClearStatusFlags(WTIMER_TIMER1_ID);
+    if (sRemainingTicks)
+    {
+        WTIMER_StartTimer(WTIMER_TIMER1_ID, sRemainingTicks);
+        sRemainingTicks = 0;
+    }
+    else
+    {
+        sEventFired = true;
+    }
+}
+#endif
diff --git a/examples/platforms/k32w/src/diag.c b/examples/platforms/k32w/src/diag.c
new file mode 100755
index 0000000..8682fc6
--- /dev/null
+++ b/examples/platforms/k32w/src/diag.c
@@ -0,0 +1,92 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for the diagnostics.
+ *
+ */
+
+/* Openthread configuration */
+#include OPENTHREAD_PROJECT_CORE_CONFIG_FILE
+
+#include <stdio.h>
+#include <openthread/config.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/radio.h>
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+/**
+ * Diagnostics mode variables.
+ *
+ */
+static bool sDiagMode = false;
+
+void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(argc);
+
+    // Add more platform specific diagnostics features here.
+    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
+}
+
+void otPlatDiagModeSet(bool aMode)
+{
+    sDiagMode = aMode;
+}
+
+bool otPlatDiagModeGet()
+{
+    return sDiagMode;
+}
+
+void otPlatDiagChannelSet(uint8_t aChannel)
+{
+    OT_UNUSED_VARIABLE(aChannel);
+}
+
+void otPlatDiagTxPowerSet(int8_t aTxPower)
+{
+    OT_UNUSED_VARIABLE(aTxPower);
+}
+
+void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aFrame);
+    OT_UNUSED_VARIABLE(aError);
+}
+
+void otPlatDiagAlarmCallback(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+#endif // OPENTHREAD_ENABLE_DIAG
diff --git a/examples/platforms/k32w/src/entropy.c b/examples/platforms/k32w/src/entropy.c
new file mode 100755
index 0000000..1cadb22
--- /dev/null
+++ b/examples/platforms/k32w/src/entropy.c
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements an entropy source based on TRNG.
+ *
+ */
+
+#include "openthread/platform/entropy.h"
+#include "fsl_device_registers.h"
+#include "fsl_rng.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <utils/code_utils.h>
+
+void K32WRandomInit(void)
+{
+    trng_config_t config;
+    uint32_t      seed;
+
+    TRNG_GetDefaultConfig(&config);
+    config.mode = trng_FreeRunning;
+
+    otEXPECT(TRNG_Init(RNG, &config) == kStatus_Success);
+
+    otEXPECT(TRNG_GetRandomData(RNG, &seed, sizeof(seed)) == kStatus_Success);
+
+    srand(seed);
+
+exit:
+    return;
+}
+
+otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
+{
+    otError status = OT_ERROR_NONE;
+
+    otEXPECT_ACTION((aOutput != NULL), status = OT_ERROR_INVALID_ARGS);
+
+    otEXPECT_ACTION(TRNG_GetRandomData(RNG, aOutput, aOutputLength) == kStatus_Success, status = OT_ERROR_FAILED);
+
+exit:
+    return status;
+}
diff --git a/examples/platforms/k32w/src/flash.c b/examples/platforms/k32w/src/flash.c
new file mode 100755
index 0000000..32f843b
--- /dev/null
+++ b/examples/platforms/k32w/src/flash.c
@@ -0,0 +1,281 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "openthread/platform/flash.h"
+#include "fsl_device_registers.h"
+#include "fsl_flash.h"
+#include "openthread-core-config.h"
+#include <utils/code_utils.h>
+#include "openthread/platform/alarm-milli.h"
+
+#define USE_MEM_COPY_FOR_READ 0
+
+#define NUMBER_OF_INTEGERS 4
+#define ONE_READ 1
+#define BYTES_IN_ONE_READ (NUMBER_OF_INTEGERS * sizeof(uint32_t))
+#define NORMAL_READ_MODE 0
+#define ONE_PAGE 1
+#define BYTES_ALINGMENT 16
+
+uint8_t         pageBuffer[FLASH_PAGE_SIZE] __attribute__((aligned(4))) = {0};
+static uint32_t sNvFlashStartAddr;
+static uint32_t sNvFlashEndAddr;
+
+static bool     mapToNvFlashAddress(uint32_t *aAddress);
+static void     copyFromFlash(uint8_t *pDst, uint8_t *pSrc, uint32_t cBytes);
+static uint32_t blankCheckAndErase(uint8_t *pageAddr);
+
+void otPlatFlashInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    extern uint32_t __nv_storage_start_address;
+    extern uint32_t __nv_storage_end_address;
+
+    FLASH_Init(FLASH);
+
+    sNvFlashStartAddr = (uint32_t)&__nv_storage_start_address;
+    sNvFlashEndAddr   = (uint32_t)&__nv_storage_end_address;
+}
+
+otError utilsFlashErasePage(uint32_t aAddress)
+{
+    otError  error = OT_ERROR_INVALID_ARGS;
+    status_t status;
+    uint32_t address = aAddress;
+
+    /* Map address to NV Flash space and check boundaries */
+    if (mapToNvFlashAddress(&address))
+    {
+        /* If address is aligned to page size */
+        if ((address % FLASH_PAGE_SIZE) == 0)
+        {
+            error = OT_ERROR_NONE;
+
+            status = blankCheckAndErase((uint8_t *)address);
+            otEXPECT_ACTION((status & FLASH_DONE), error = OT_ERROR_FAILED);
+        }
+    }
+
+exit:
+    return error;
+}
+
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    uint32_t result = 0;
+    status_t status;
+    uint32_t address = aOffset;
+    uint32_t alignAddr;
+    uint32_t bytes;
+
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aSwapIndex);
+
+    /* Map address to NV Flash space and check boundaries */
+    if (mapToNvFlashAddress(&address))
+    {
+        /* Check to see if data is written outside NV Flash space */
+        if ((address + aSize) <= sNvFlashEndAddr)
+        {
+            alignAddr = address - (address % FLASH_PAGE_SIZE);
+            bytes     = (address - alignAddr);
+            result    = aSize;
+
+            if (bytes)
+            {
+                uint32_t unalignedBytes = FLASH_PAGE_SIZE - bytes;
+
+                if (unalignedBytes > aSize)
+                {
+                    unalignedBytes = aSize;
+                }
+
+                copyFromFlash(pageBuffer, (void *)alignAddr, FLASH_PAGE_SIZE);
+                memcpy(&pageBuffer[bytes], aData, unalignedBytes);
+
+                status = blankCheckAndErase((uint8_t *)alignAddr);
+                otEXPECT_ACTION((status & FLASH_DONE), result = 0);
+
+                status = FLASH_Program(FLASH, (uint32_t *)alignAddr, (uint32_t *)pageBuffer, FLASH_PAGE_SIZE);
+                otEXPECT_ACTION((status & FLASH_DONE), result = 0);
+
+                address += unalignedBytes;
+                /* if size is less than the distance to the end of program block
+                   unalignedBytes has been shrunk , after size is decremented it will become 0 */
+                aData += unalignedBytes;
+                aSize -= unalignedBytes;
+            }
+
+            bytes = aSize & ~(FLASH_PAGE_SIZE - 1U);
+
+            /* Now dest is on an aligned boundary */
+            /* bytes is an integer number of program blocks (pages) */
+            while (bytes)
+            {
+                status = blankCheckAndErase((uint8_t *)address);
+                otEXPECT_ACTION((status & FLASH_DONE), result = 0);
+
+                status = FLASH_Program(FLASH, (uint32_t *)address, (uint32_t *)aData, FLASH_PAGE_SIZE);
+                otEXPECT_ACTION((status & FLASH_DONE), result = 0);
+
+                address += FLASH_PAGE_SIZE;
+                aData += FLASH_PAGE_SIZE;
+                aSize -= FLASH_PAGE_SIZE;
+                bytes -= FLASH_PAGE_SIZE;
+            }
+
+            /* dest is still aligned because we have increased it by a multiple of the program block (page) */
+            if (aSize)
+            {
+                status = blankCheckAndErase((uint8_t *)address);
+                otEXPECT_ACTION((status & FLASH_DONE), result = 0);
+
+                status = FLASH_Program(FLASH, (uint32_t *)address, (uint32_t *)aData, aSize);
+                otEXPECT_ACTION((status & FLASH_DONE), result = 0);
+            }
+        }
+    }
+
+exit:
+    /* There are times when the result != 0.
+     * Use this workaround until we replace the flash code with the Packet Data Manager.
+     */
+    if (result)
+    {
+        result = 0;
+    }
+}
+
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
+{
+    uint32_t address = aOffset;
+
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aSwapIndex);
+
+    /* Map address to NV Flash space and check boundaries */
+    if (mapToNvFlashAddress(&address))
+    {
+        /* Check to see if data is read outside NV Flash space */
+        if ((address + aSize) <= sNvFlashEndAddr)
+        {
+            copyFromFlash(aData, (uint8_t *)address, aSize);
+        }
+    }
+}
+
+static bool mapToNvFlashAddress(uint32_t *aAddress)
+{
+    bool     status  = true;
+    uint32_t address = *aAddress + sNvFlashStartAddr;
+
+    if ((address < sNvFlashStartAddr) || (address > sNvFlashEndAddr))
+    {
+        status = false;
+    }
+    else
+    {
+        *aAddress = address;
+    }
+
+    return status;
+}
+
+uint32_t blankCheckAndErase(uint8_t *pageAddr)
+{
+    uint32_t status = FLASH_BlankCheck(FLASH, pageAddr, pageAddr + FLASH_PAGE_SIZE - 1);
+    if (status & FLASH_FAIL)
+    {
+        status = FLASH_Erase(FLASH, pageAddr, (pageAddr + FLASH_PAGE_SIZE - 1));
+    }
+    else
+    {
+        status = FLASH_DONE;
+    }
+
+    return status;
+}
+
+static void copyFromFlash(uint8_t *pDst, uint8_t *pSrc, uint32_t cBytes)
+{
+#if !USE_MEM_COPY_FOR_READ
+
+    uint32_t nbOfReads;
+    uint32_t aligningOffset;
+    uint32_t temp[NUMBER_OF_INTEGERS];
+    uint32_t bytesLeft   = cBytes;
+    uint32_t bytesToRead = 0;
+
+    /* Flash driver reads 16 bytes in one run, so calculating the number of reads from Flash
+       is needed */
+    nbOfReads = cBytes / BYTES_IN_ONE_READ;
+    if (cBytes % BYTES_IN_ONE_READ)
+    {
+        nbOfReads++;
+    }
+
+    /* calculate aligning offset -> the number of bytes from a 16 byte aligned address the
+       read address is located */
+    aligningOffset = (uint32_t)pSrc % BYTES_ALINGMENT;
+
+    for (uint32_t i = 0; i < nbOfReads; i++)
+    {
+        /* Read from Flash */
+        FLASH_Read(FLASH, (uint8_t *)(pSrc - aligningOffset + i * BYTES_IN_ONE_READ), NORMAL_READ_MODE,
+                   (uint32_t *)temp);
+
+        if (0 == i)
+        {
+            bytesToRead =
+                (bytesLeft < BYTES_IN_ONE_READ - aligningOffset) ? bytesLeft : BYTES_IN_ONE_READ - aligningOffset;
+
+            /* first read must take into account align offset */
+            memcpy((void *)pDst, (void *)temp + aligningOffset, bytesToRead);
+            bytesLeft -= bytesToRead;
+            pDst += bytesToRead;
+        }
+        else
+        {
+            bytesToRead = (bytesLeft < BYTES_IN_ONE_READ) ? bytesLeft : BYTES_IN_ONE_READ;
+            memcpy((void *)pDst, (void *)temp, bytesToRead);
+            bytesLeft -= bytesToRead;
+            pDst += bytesToRead;
+        }
+    }
+
+#else
+    while (cBytes)
+    {
+        *(pDst) = *(pSrc);
+        pDst    = pDst + 1;
+        pSrc    = pSrc + 1;
+        cBytes--;
+    }
+#endif
+}
diff --git a/examples/platforms/k32w/src/logging.c b/examples/platforms/k32w/src/logging.c
new file mode 100755
index 0000000..af55c2d
--- /dev/null
+++ b/examples/platforms/k32w/src/logging.c
@@ -0,0 +1,91 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file logging.c
+ * Platform abstraction for the logging
+ *
+ */
+
+#include "platform-k32w.h"
+#include <openthread-core-config.h>
+#include <utils/code_utils.h>
+#include <openthread/config.h>
+#include <openthread/platform/logging.h>
+#include <openthread/platform/toolchain.h>
+#include <openthread/platform/uart.h>
+
+#include "stdio.h"
+#include "string.h"
+
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
+
+/* defines */
+#define TX_BUFFER_SIZE 256 /* Length of the send buffer */
+#define EOL_CHARS "\r\n"   /* End of Line Characters */
+#define EOL_CHARS_LEN 2    /* Length of EOL */
+
+/* static functions */
+static void K32WLogOutput(const char *aFormat, va_list ap);
+
+/* static variables */
+static char sTxBuffer[TX_BUFFER_SIZE + 1]; /* Transmit Buffer */
+
+OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
+{
+    OT_UNUSED_VARIABLE(aLogLevel);
+    OT_UNUSED_VARIABLE(aLogRegion);
+    va_list ap;
+
+    va_start(ap, aFormat);
+    K32WLogOutput(aFormat, ap);
+    va_end(ap);
+}
+
+/**
+ * Write Blocking data
+ *
+ * @param[in]    aFormat*     A pointer to the format string
+ * @param[in]    ap           Variable List Argument
+ *
+ */
+static void K32WLogOutput(const char *aFormat, va_list ap)
+{
+    int len = 0;
+
+    len = vsnprintf(sTxBuffer, TX_BUFFER_SIZE - EOL_CHARS_LEN, aFormat, ap);
+    otEXPECT(len >= 0);
+    memcpy(sTxBuffer + len, EOL_CHARS, EOL_CHARS_LEN);
+    len += EOL_CHARS_LEN;
+    K32WWriteBlocking((const uint8_t *)sTxBuffer, len);
+
+exit:
+    return;
+}
+
+#endif
diff --git a/examples/platforms/k32w/src/misc.c b/examples/platforms/k32w/src/misc.c
new file mode 100755
index 0000000..6f87af9
--- /dev/null
+++ b/examples/platforms/k32w/src/misc.c
@@ -0,0 +1,93 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "openthread/platform/misc.h"
+#include "fsl_device_registers.h"
+#include "fsl_power.h"
+#include "fsl_reset.h"
+
+void otPlatReset(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    RESET_SystemReset();
+
+    while (1)
+    {
+    }
+}
+
+otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otPlatResetReason reason;
+    reset_cause_t     cause = POWER_GetResetCause();
+
+    if (cause & RESET_POR)
+    {
+        reason = OT_PLAT_RESET_REASON_POWER_ON;
+    }
+    else if ((cause & RESET_SYS_REQ) || (cause & RESET_SW_REQ))
+    {
+        reason = OT_PLAT_RESET_REASON_SOFTWARE;
+    }
+    else if (cause & RESET_WDT)
+    {
+        reason = OT_PLAT_RESET_REASON_WATCHDOG;
+    }
+    else if (cause & RESET_EXT_PIN)
+    {
+        reason = OT_PLAT_RESET_REASON_EXTERNAL;
+    }
+    else if (cause & RESET_BOR)
+    {
+        reason = OT_PLAT_RESET_REASON_FAULT;
+    }
+    else if ((cause & RESET_WAKE_DEEP_PD) || (cause & RESET_WAKE_PD))
+    {
+        reason = OT_PLAT_RESET_REASON_ASSERT;
+    }
+    else
+    {
+        reason = OT_PLAT_RESET_REASON_OTHER;
+    }
+
+    return reason;
+}
+
+void otPlatAssertFail(const char *aFilename, int aLineNumber)
+{
+    OT_UNUSED_VARIABLE(aFilename);
+    OT_UNUSED_VARIABLE(aLineNumber);
+}
+
+void otPlatWakeHost(void)
+{
+    /* TODO */
+}
diff --git a/examples/platforms/k32w/src/platform-k32w.h b/examples/platforms/k32w/src/platform-k32w.h
new file mode 100755
index 0000000..ec32664
--- /dev/null
+++ b/examples/platforms/k32w/src/platform-k32w.h
@@ -0,0 +1,93 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes the platform-specific initializers.
+ *
+ */
+
+#ifndef PLATFORM_K32W_H_
+#define PLATFORM_K32W_H_
+
+#include <openthread-core-config.h>
+#include <openthread/config.h>
+
+#include <stdint.h>
+
+#include <openthread/instance.h>
+
+/**
+ * This function initializes the alarm service used by OpenThread.
+ *
+ */
+void K32WAlarmInit(void);
+
+/**
+ * This function performs alarm driver processing.
+ *
+ * @param[in]  aInstance  The OpenThread instance structure.
+ *
+ */
+void K32WAlarmProcess(otInstance *aInstance);
+
+/**
+ * This function initializes the radio service used by OpenThread.
+ *
+ */
+void K32WRadioInit(void);
+
+/**
+ * This function performs radio driver processing.
+ *
+ * @param[in]  aInstance  The OpenThread instance structure.
+ *
+ */
+void K32WRadioProcess(otInstance *aInstance);
+
+/**
+ * This function initializes the random number service used by OpenThread.
+ *
+ */
+void K32WRandomInit(void);
+
+/**
+ * This function performs UART driver processing.
+ *
+ */
+void K32WUartProcess(void);
+
+/**
+ * This function performs UART Blocking Send
+ *
+ * @param[in]  aBuf  Buffer to be sent over UART
+ * @param[in]  len   Length of the above buffer
+ *
+ */
+void K32WWriteBlocking(const uint8_t *aBuf, uint32_t len);
+#endif // PLATFORM_K32W_H_
diff --git a/examples/platforms/k32w/src/radio.c b/examples/platforms/k32w/src/radio.c
new file mode 100755
index 0000000..d42fd86
--- /dev/null
+++ b/examples/platforms/k32w/src/radio.c
@@ -0,0 +1,1290 @@
+/*
+ *  Copyright (c) 2017, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for radio communication.
+ *
+ */
+
+/* Openthread configuration */
+#include OPENTHREAD_PROJECT_CORE_CONFIG_FILE
+
+/* memcpy */
+#include "string.h"
+
+/* uMac, MMAC, Radio */
+#include "MMAC.h"
+#include "MicroSpecific_arm_sdk2.h"
+#include "radio.h"
+
+/* Openthread general */
+#include <utils/code_utils.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+#include <openthread/platform/radio.h>
+
+extern void BOARD_LedDongleToggle(void);
+
+/* Defines */
+#define BIT_SET(arg, posn) ((arg) |= (1ULL << (posn)))
+#define BIT_CLR(arg, posn) ((arg) &= ~(1ULL << (posn)))
+#define BIT_TST(arg, posn) (!!((arg) & (1ULL << (posn))))
+
+#define ALL_FFs_BYTE (0xFF)
+
+#define K32W_RADIO_MIN_TX_POWER_DBM (-30)
+#define K32W_RADIO_MAX_TX_POWER_DBM (15)
+#define K32W_RADIO_RX_SENSITIVITY_DBM (-100)
+#define K32W_RADIO_DEFAULT_CHANNEL (11)
+
+#define US_PER_SYMBOL (16) /* Duration of a single symbol in [us] */
+#define SYMBOLS_TO_US(symbols) ((symbols)*US_PER_SYMBOL)
+#define US_TO_MILI_DIVIDER (1000)
+
+#define MAX_FP_ADDRS (10)   /* max number of frame pending children */
+#define K32W_RX_BUFFERS (8) /* max number of RX buffers */
+
+/* check IEEE Std. 802.15.4 - 2015: Table 8-81 - MAC sublayer constants */
+#define MAC_TX_ATTEMPTS (4)
+#define MAC_TX_CSMA_MIN_BE (3)
+#define MAC_TX_CSMA_MAX_BE (5)
+#define MAC_TX_CSMA_MAX_BACKOFFS (4)
+
+/* Structures */
+typedef struct
+{
+    uint16_t macAddress;
+    uint16_t panId;
+} fpNeighShortAddr;
+
+typedef struct
+{
+    uint32_t u32L;
+    uint32_t u32H;
+} extMacAddr;
+
+typedef struct
+{
+    extMacAddr extAddr;
+    uint16_t   panId;
+} fpNeighExtAddr;
+
+typedef struct
+{
+    tsRxFrameFormat *buffer[K32W_RX_BUFFERS];
+    uint8_t          head;
+    uint8_t          tail;
+    bool             isFull;
+} rxRingBuffer;
+
+typedef enum
+{
+    kFcfSize             = sizeof(uint16_t),
+    kDsnSize             = sizeof(uint8_t),
+    kSecurityControlSize = sizeof(uint8_t),
+    kFrameCounterSize    = sizeof(uint32_t),
+    kKeyIndexSize        = sizeof(uint8_t),
+
+    kMacFcfLowOffset = 0, /* Offset of FCF first byte inside Mac Hdr */
+    kMacFrameDataReq = 4,
+
+    kFcfTypeBeacon       = 0,
+    kFcfTypeMacData      = 1,
+    kFcfTypeAck          = 2,
+    kFcfTypeMacCommand   = 3,
+    kFcfMacFrameTypeMask = 7 << 0,
+
+    kFcfAckRequest        = 1 << 5,
+    kFcfPanidCompression  = 1 << 6,
+    kFcfSeqNbSuppresssion = 1 << 8,
+    kFcfDstAddrNone       = 0 << 10,
+    kFcfDstAddrShort      = 2 << 10,
+    kFcfDstAddrExt        = 3 << 10,
+    kFcfDstAddrMask       = 3 << 10,
+    kFcfSrcAddrNone       = 0 << 14,
+    kFcfSrcAddrShort      = 2 << 14,
+    kFcfSrcAddrExt        = 3 << 14,
+    kFcfSrcAddrMask       = 3 << 14,
+
+    kSecLevelMask            = 7 << 0,
+    kFrameCounterSuppression = 1 << 5,
+
+    kKeyIdMode0    = 0 << 3,
+    kKeyIdMode1    = 1 << 3,
+    kKeyIdMode2    = 2 << 3,
+    kKeyIdMode3    = 3 << 3,
+    kKeyIdModeMask = 3 << 3,
+
+    kKeySourceSizeMode0 = 0,
+    kKeySourceSizeMode1 = 0,
+    kKeySourceSizeMode2 = 4,
+    kKeySourceSizeMode3 = 8,
+} macHdr;
+
+typedef enum
+{
+    macToOtFrame, /* RX */
+    otToMacFrame, /* TX */
+} frameConversionType;
+
+/* Private functions declaration */
+static void             K32WISR(uint32_t u32IntBitmap);
+static void             K32WProcessMacHeader(tsRxFrameFormat *aRxFrame);
+static void             K32WProcessRxFrames(otInstance *aInstance);
+static void             K32WProcessTxFrame(otInstance *aInstance);
+static bool             K32WCheckIfFpRequired(tsRxFrameFormat *aRxFrame);
+static bool_t           K32WIsDataReq(tsRxFrameFormat *aRxFrame);
+static otError          K32WFrameConversion(tsRxFrameFormat *   aMacFormatFrame,
+                                            otRadioFrame *      aOtFrame,
+                                            frameConversionType convType);
+static void             K32WCopy(uint8_t *aFieldValue, uint8_t **aPsdu, uint8_t copySize, frameConversionType convType);
+static void             K32WResetRxRingBuffer(rxRingBuffer *aRxRing);
+static void             K32WPushRxRingBuffer(rxRingBuffer *aRxRing, tsRxFrameFormat *aRxFrame);
+static tsRxFrameFormat *K32WPopRxRingBuffer(rxRingBuffer *aRxRing);
+static bool             K32WIsEmptyRxRingBuffer(rxRingBuffer *aRxRing);
+static tsRxFrameFormat *K32WGetFrame(tsRxFrameFormat *aRxFrame, uint8_t *aRxFrameIndex);
+static void             K32WEnableReceive(bool_t isNewFrameNeeded);
+static void             K32WRestartRx(void);
+
+/* Private variables declaration */
+static otRadioState sState = OT_RADIO_STATE_DISABLED;
+static otInstance * sInstance;    /* Saved OT Instance */
+static int8_t       sTxPwrLevel;  /* Default power is 0 dBm */
+static uint8_t      sChannel = 0; /* Default channel - must be invalid so it
+                                     updates the first time it is set */
+static bool_t    sIsFpEnabled;    /* Frame Pending enabled? */
+static uint16_t  sPanId;          /* PAN ID currently in use */
+static uint16_t  sShortAddress;
+static tsExtAddr sExtAddress;
+static uint64_t  sCustomExtAddr = 0;
+
+static fpNeighShortAddr sFpShortAddr[MAX_FP_ADDRS]; /* Frame Pending short addresses array */
+static uint16_t         sFpShortAddrMask;           /* Mask - sFpShortAddr valid entries */
+
+static fpNeighExtAddr sFpExtAddr[MAX_FP_ADDRS]; /* Frame Pending extended addresses array */
+static uint16_t       sFpExtAddrMask;           /* Mask - sFpExtAddr is valid */
+
+static rxRingBuffer     sRxRing;                       /* Receive Ring Buffer */
+static tsRxFrameFormat  sRxFrame[K32W_RX_BUFFERS];     /* RX Buffers */
+static tsRxFrameFormat *sRxFrameInProcess;             /* RX Frame currently in processing */
+static bool_t           sIsRxDisabled;                 /* TRUE if RX was disabled due to no RX bufs */
+static uint8_t          sRxFrameIndex;                 /* Index tracking the sRxFrame array */
+static teRxOption       sRxOpt = E_MMAC_RX_START_NOW | /* RX Options */
+                           E_MMAC_RX_ALIGN_NORMAL | E_MMAC_RX_USE_AUTO_ACK | E_MMAC_RX_NO_MALFORMED |
+                           E_MMAC_RX_NO_FCS_ERROR | E_MMAC_RX_ADDRESS_MATCH;
+
+tsRxFrameFormat        sTxMacFrame;                      /* TX Frame */
+static tsRxFrameFormat sRxAckFrame;                      /* Frame used for keeping the ACK */
+static otRadioFrame    sRxOtFrame;                       /* Used for TX/RX frame conversion */
+static uint8           sRxData[OT_RADIO_FRAME_MAX_SIZE]; /* mPsdu buffer for sRxOtFrame */
+
+static bool         sRadioInitForLp    = FALSE;
+static bool         sPromiscuousEnable = FALSE;
+static bool         sTxDone;                          /* TRUE if a TX frame was sent into the air */
+static otError      sTxStatus;                        /* Status of the latest TX operation */
+static otRadioFrame sTxOtFrame;                       /* OT TX Frame to be send */
+static uint8_t      sTxData[OT_RADIO_FRAME_MAX_SIZE]; /* mPsdu buffer for sTxOtFrame */
+
+/* Stub functions for controlling low power mode */
+WEAK void App_AllowDeviceToSleep();
+WEAK void App_DisallowDeviceToSleep();
+/* Stub functions for controlling LEDs on OT RCP USB dongle */
+WEAK void BOARD_LedDongleToggle();
+
+/**
+ * Stub function used for controlling low power mode
+ *
+ */
+WEAK void App_AllowDeviceToSleep()
+{
+}
+
+/**
+ * Stub function used for controlling low power mode
+ *
+ */
+WEAK void App_DisallowDeviceToSleep()
+{
+}
+
+/**
+ * Stub functions for controlling LEDs on OT RCP USB dongle
+ *
+ */
+WEAK void BOARD_LedDongleToggle()
+{
+}
+
+void App_SetCustomEui64(uint8_t *aIeeeEui64)
+{
+    memcpy((uint8_t *)&sCustomExtAddr, aIeeeEui64, sizeof(sCustomExtAddr));
+}
+
+void K32WRadioInit(void)
+{
+    /* RX initialization */
+    memset(sRxFrame, 0, sizeof(tsRxFrameFormat) * K32W_RX_BUFFERS);
+    sRxFrameIndex = 0;
+
+    /* TX initialization */
+    sTxOtFrame.mPsdu = sTxData;
+    sRxOtFrame.mPsdu = sRxData;
+}
+
+void K32WRadioProcess(otInstance *aInstance)
+{
+    K32WProcessRxFrames(aInstance);
+    K32WProcessTxFrame(aInstance);
+}
+
+otRadioState otPlatRadioGetState(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return sState;
+}
+
+void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    if (0 == sCustomExtAddr)
+    {
+        tsExtAddr euiAddr;
+        vMMAC_GetMacAddress(&euiAddr);
+
+        memcpy(aIeeeEui64, &euiAddr.u32L, sizeof(uint32_t));
+        memcpy(aIeeeEui64 + sizeof(uint32_t), &euiAddr.u32H, sizeof(uint32_t));
+    }
+    else
+    {
+        memcpy(aIeeeEui64, (uint8_t *)&sCustomExtAddr, sizeof(sCustomExtAddr));
+    }
+}
+
+void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sPanId = aPanId;
+    vMMAC_SetRxPanId(aPanId);
+}
+
+void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    if (aExtAddress)
+    {
+        memcpy(&sExtAddress.u32L, aExtAddress->m8, sizeof(uint32_t));
+        memcpy(&sExtAddress.u32H, aExtAddress->m8 + sizeof(uint32_t), sizeof(uint32_t));
+        vMMAC_SetRxExtendedAddr(&sExtAddress);
+    }
+}
+
+void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aShortAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sShortAddress = aShortAddress;
+    vMMAC_SetRxShortAddr(aShortAddress);
+}
+
+otError otPlatRadioEnable(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    K32WResetRxRingBuffer(&sRxRing);
+    sRxFrameIndex = 0;
+    vMMAC_Enable();
+    vMMAC_EnableInterrupts(K32WISR);
+    vMMAC_ConfigureInterruptSources(E_MMAC_INT_TX_COMPLETE | E_MMAC_INT_RX_HEADER | E_MMAC_INT_RX_COMPLETE);
+    vMMAC_ConfigureRadio();
+    vMMAC_SetTxParameters(MAC_TX_ATTEMPTS, MAC_TX_CSMA_MIN_BE, MAC_TX_CSMA_MAX_BE, MAC_TX_CSMA_MAX_BACKOFFS);
+
+    if (sRadioInitForLp)
+    {
+        /* Re-set modem settings after low power exit */
+        vMMAC_SetChannelAndPower(sChannel, sTxPwrLevel);
+        vMMAC_SetRxExtendedAddr(&sExtAddress);
+        vMMAC_SetRxPanId(sPanId);
+        vMMAC_SetRxShortAddr(sShortAddress);
+    }
+
+    sTxOtFrame.mLength = 0;
+    sRxOtFrame.mLength = 0;
+
+    sInstance = aInstance;
+    sState    = OT_RADIO_STATE_SLEEP;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioDisable(otInstance *aInstance)
+{
+    otError error = OT_ERROR_INVALID_STATE;
+
+    otEXPECT(otPlatRadioIsEnabled(aInstance));
+
+    K32WResetRxRingBuffer(&sRxRing);
+    sRxFrameIndex = 0;
+    vMMAC_Disable();
+    sState = OT_RADIO_STATE_DISABLED;
+    error  = OT_ERROR_NONE;
+
+exit:
+    return error;
+}
+
+bool otPlatRadioIsEnabled(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return sState != OT_RADIO_STATE_DISABLED;
+}
+
+otError otPlatRadioSleep(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    otError status = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(((sState != OT_RADIO_STATE_TRANSMIT) && (sState != OT_RADIO_STATE_DISABLED)),
+                    status = OT_ERROR_INVALID_STATE);
+
+    /* The radio has been init and configuration should be restored in otPlatRadioEnable when
+       exiting low power */
+    sRadioInitForLp = TRUE;
+
+    sState = OT_RADIO_STATE_SLEEP;
+    vMMAC_RadioToOffAndWait();
+    App_AllowDeviceToSleep();
+
+exit:
+    return status;
+}
+
+otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError      error            = OT_ERROR_NONE;
+    bool_t       isNewFrameNeeded = TRUE;
+    otRadioState tempState        = sState;
+
+    otEXPECT_ACTION(((sState != OT_RADIO_STATE_TRANSMIT) && (sState != OT_RADIO_STATE_DISABLED)),
+                    error = OT_ERROR_INVALID_STATE);
+
+    App_DisallowDeviceToSleep();
+
+    /* Check if the channel needs to be changed */
+    if (sChannel != aChannel)
+    {
+        sChannel = aChannel;
+
+        /* The state is set to sleep to prevent a lockup caused by an RX interrup firing during
+         * the radio off command called inside set channel and power */
+        sState = OT_RADIO_STATE_SLEEP;
+        vMMAC_SetChannelAndPower(sChannel, sTxPwrLevel);
+        sState = tempState;
+    }
+
+    if (OT_RADIO_STATE_RECEIVE != sState)
+    {
+        sState = OT_RADIO_STATE_RECEIVE;
+    }
+    else
+    {
+        /* this might happen when the channel is switched
+         * in the middle of a receive operation */
+        isNewFrameNeeded = FALSE;
+    }
+    K32WEnableReceive(isNewFrameNeeded);
+
+exit:
+    return error;
+}
+
+void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sIsFpEnabled = aEnable;
+}
+
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NO_BUFS;
+    uint8_t idx   = 0;
+
+    for (; idx < MAX_FP_ADDRS; idx++)
+    {
+        if (!BIT_TST(sFpShortAddrMask, idx))
+        {
+            sFpShortAddr[idx].panId      = sPanId;
+            sFpShortAddr[idx].macAddress = aShortAddress;
+            BIT_SET(sFpShortAddrMask, idx);
+            error = OT_ERROR_NONE;
+            break;
+        }
+    }
+
+    return error;
+}
+
+otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NO_BUFS;
+    uint8_t idx   = 0;
+
+    for (; idx < MAX_FP_ADDRS; idx++)
+    {
+        if (!BIT_TST(sFpExtAddrMask, idx))
+        {
+            sFpExtAddr[idx].panId = sPanId;
+            memcpy(&sFpExtAddr[idx].extAddr.u32L, aExtAddress->m8, sizeof(uint32_t));
+            memcpy(&sFpExtAddr[idx].extAddr.u32H, aExtAddress->m8 + sizeof(uint32_t), sizeof(uint32_t));
+            BIT_SET(sFpExtAddrMask, idx);
+            error = OT_ERROR_NONE;
+            break;
+        }
+    }
+
+    return error;
+}
+
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NO_ADDRESS;
+    uint8_t idx   = 0;
+
+    for (; idx < MAX_FP_ADDRS; idx++)
+    {
+        if (BIT_TST(sFpShortAddrMask, idx) && (sFpShortAddr[idx].macAddress == aShortAddress))
+        {
+            BIT_CLR(sFpShortAddrMask, idx);
+            error = OT_ERROR_NONE;
+            break;
+        }
+    }
+
+    return error;
+}
+
+otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NO_ADDRESS;
+    uint8_t idx   = 0;
+
+    for (; idx < MAX_FP_ADDRS; idx++)
+    {
+        if (BIT_TST(sFpExtAddrMask, idx) && !memcmp(&sFpExtAddr[idx].extAddr.u32L, aExtAddress->m8, sizeof(uint32_t)) &&
+            !memcmp(&sFpExtAddr[idx].extAddr.u32H, aExtAddress->m8 + sizeof(uint32_t), sizeof(uint32_t)))
+        {
+            BIT_CLR(sFpExtAddrMask, idx);
+            error = OT_ERROR_NONE;
+            break;
+        }
+    }
+
+    return error;
+}
+
+void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sFpShortAddrMask = 0;
+}
+
+void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sFpExtAddrMask = 0;
+}
+
+otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return &sTxOtFrame;
+}
+
+otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
+{
+    otError    error    = OT_ERROR_NONE;
+    teTxOption eOptions = E_MMAC_TX_START_NOW | E_MMAC_TX_USE_AUTO_ACK;
+
+    otEXPECT_ACTION(OT_RADIO_STATE_RECEIVE == sState, error = OT_ERROR_INVALID_STATE);
+
+    /* go to TX state */
+    sState    = OT_RADIO_STATE_TRANSMIT;
+    sTxStatus = OT_ERROR_NONE;
+
+    /* set tx channel */
+    if (sChannel != aFrame->mChannel)
+    {
+        vMMAC_SetChannelAndPower(aFrame->mChannel, sTxPwrLevel);
+    }
+
+    if (aFrame->mInfo.mTxInfo.mCsmaCaEnabled)
+    {
+        eOptions |= E_MMAC_TX_USE_CCA;
+    }
+
+    K32WFrameConversion(&sTxMacFrame, aFrame, otToMacFrame);
+
+    /* stop rx is handled by uMac tx function */
+    vMMAC_StartMacTransmit(&sTxMacFrame.sFrameBody, eOptions);
+
+    /* Set RX buffer pointer for ACK */
+    vMMAC_SetRxFrame(&sRxAckFrame);
+
+    otPlatRadioTxStarted(aInstance, aFrame);
+
+exit:
+    return error;
+}
+
+int8_t otPlatRadioGetRssi(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    int8_t  rssidBm       = 127;
+    int16_t rssiValSigned = 0;
+    bool_t  stateChanged  = FALSE;
+
+    /* in RCP designs, the RSSI function is called while the radio is in
+     * OT_RADIO_STATE_RECEIVE. Turn off the radio before reading RSSI,
+     * otherwise we may end up waiting until a packet is received
+     * (in i16Radio_GetRSSI, while loop)
+     */
+
+    if (sState == OT_RADIO_STATE_RECEIVE)
+    {
+        sState = OT_RADIO_STATE_SLEEP;
+        vMMAC_RadioToOffAndWait();
+        stateChanged = TRUE;
+    }
+
+    rssiValSigned = i16Radio_GetRSSI(0, FALSE, NULL);
+
+    if (stateChanged)
+    {
+        sState = OT_RADIO_STATE_RECEIVE;
+        K32WEnableReceive(TRUE);
+    }
+
+    rssiValSigned = i16Radio_BoundRssiValue(rssiValSigned);
+
+    /* RSSI reported by radio is in 1/4 dBm step,
+     * meaning values are 4 times larger than real dBm value.
+     */
+    rssidBm = (int8_t)(rssiValSigned >> 2);
+
+    return rssidBm;
+}
+
+otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_CSMA_BACKOFF;
+}
+
+bool otPlatRadioGetPromiscuous(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return sPromiscuousEnable;
+}
+
+void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    if (sPromiscuousEnable != aEnable)
+    {
+        sPromiscuousEnable = aEnable;
+
+        if (aEnable)
+        {
+            sRxOpt &= ~E_MMAC_RX_ADDRESS_MATCH;
+        }
+        else
+        {
+            sRxOpt |= E_MMAC_RX_ADDRESS_MATCH;
+        }
+    }
+}
+
+otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError status = OT_ERROR_NOT_IMPLEMENTED;
+
+    return status;
+}
+
+otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
+{
+    otError error = OT_ERROR_NONE;
+    otEXPECT_ACTION(aPower != NULL, error = OT_ERROR_INVALID_ARGS);
+
+    *aPower = i8Radio_GetTxPowerLevel_dBm();
+    return OT_ERROR_NONE;
+
+exit:
+    return error;
+}
+
+otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    otRadioState tempState = sState;
+    sState                 = OT_RADIO_STATE_SLEEP;
+
+    /* trim the values to the radio capabilities */
+    if (aPower < K32W_RADIO_MIN_TX_POWER_DBM)
+    {
+        aPower = K32W_RADIO_MIN_TX_POWER_DBM;
+    }
+    else if (aPower > K32W_RADIO_MAX_TX_POWER_DBM)
+    {
+        aPower = K32W_RADIO_MAX_TX_POWER_DBM;
+    }
+
+    /* save for later use */
+    sTxPwrLevel = aPower;
+
+    /* The state is set to sleep to prevent a lockup caused by an RX interrup firing during
+     * the radio off command called inside set channel and power */
+    if (0 != sChannel)
+    {
+        vMMAC_SetChannelAndPower(sChannel, aPower);
+    }
+    else
+    {
+        /* if the channel has not yet been initialized use K32W_RADIO_DEFAULT_CHANNEL as default */
+        vMMAC_SetChannelAndPower(K32W_RADIO_DEFAULT_CHANNEL, aPower);
+    }
+    sState = tempState;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aThreshold);
+
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aThreshold);
+
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return K32W_RADIO_RX_SENSITIVITY_DBM;
+}
+
+/**
+ * Interrupt service routine (e.g.: TX/RX/MAC HDR received)
+ *
+ * @param[in] u32IntBitmap  Bitmap telling which interrupt fired
+ *
+ */
+static void K32WISR(uint32_t u32IntBitmap)
+{
+    tsRxFrameFormat *pRxFrame = NULL;
+
+    switch (sState)
+    {
+    case OT_RADIO_STATE_RECEIVE:
+
+        /* no rx errors */
+        if (0 == u32MMAC_GetRxErrors())
+        {
+            if (u32IntBitmap & E_MMAC_INT_RX_HEADER)
+            {
+                /* go back one index from current frame index */
+                pRxFrame = &sRxFrame[(sRxFrameIndex + K32W_RX_BUFFERS - 1) % K32W_RX_BUFFERS];
+
+                /* FP processing first */
+                K32WProcessMacHeader(pRxFrame);
+
+                /* RX interrupt fired so it's safe to consume the frame */
+                K32WPushRxRingBuffer(&sRxRing, pRxFrame);
+
+                if (0 == (pRxFrame->sFrameBody.u16FCF & kFcfAckRequest))
+                {
+                    K32WEnableReceive(TRUE);
+                }
+            }
+            else if (u32IntBitmap & E_MMAC_INT_RX_COMPLETE)
+            {
+                K32WEnableReceive(TRUE);
+            }
+        }
+        else
+        {
+            /* restart RX and keep same buffer as data received contains errors */
+            K32WEnableReceive(FALSE);
+        }
+
+        BOARD_LedDongleToggle();
+        break;
+    case OT_RADIO_STATE_TRANSMIT:
+
+        if (u32IntBitmap & E_MMAC_INT_TX_COMPLETE)
+        {
+            uint32_t txErrors = u32MMAC_GetTxErrors();
+            sTxDone           = TRUE;
+
+            if (txErrors & E_MMAC_TXSTAT_CCA_BUSY)
+            {
+                sTxStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
+            }
+            else if (txErrors & E_MMAC_TXSTAT_NO_ACK)
+            {
+                sTxStatus = OT_ERROR_NO_ACK;
+            }
+            else if (txErrors & E_MMAC_TXSTAT_ABORTED)
+            {
+                sTxStatus = OT_ERROR_ABORT;
+            }
+            else if ((txErrors & E_MMAC_TXSTAT_TXPCTO) || (txErrors & E_MMAC_TXSTAT_TXTO))
+            {
+                /* The JN518x/K32W0x1 has a TXTO timeout that we are using to catch and cope with the curious
+                hang-up issue */
+                vMMAC_AbortRadio();
+
+                /* Describe failure as a CCA failure for onward processing */
+                sTxStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
+            }
+
+            /* go to RX and restore channel */
+            if (sChannel != sTxOtFrame.mChannel)
+            {
+                vMMAC_SetChannelAndPower(sChannel, sTxPwrLevel);
+            }
+
+            BOARD_LedDongleToggle();
+            sState = OT_RADIO_STATE_RECEIVE;
+            K32WEnableReceive(TRUE);
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+/**
+ * Process the MAC Header of the latest received packet
+ * We are in interrupt context - we need to compute the FP
+ * while the hardware generates the ACK.
+ *
+ * @param[in] aRxFrame     Pointer to the latest received MAC packet
+ *
+ */
+static void K32WProcessMacHeader(tsRxFrameFormat *aRxFrame)
+{
+    /* check if frame pending processing is required */
+    if (aRxFrame && sIsFpEnabled)
+    {
+        /* Intra-PAN bit set? */
+        if ((kFcfPanidCompression & aRxFrame->sFrameBody.u16FCF) &&
+            (kFcfDstAddrNone != (aRxFrame->sFrameBody.u16FCF & kFcfDstAddrMask)))
+        {
+            /* Read destination PAN ID into source PAN ID: they are the same */
+            aRxFrame->sFrameBody.u16SrcPAN = aRxFrame->sFrameBody.u16DestPAN;
+        }
+
+        if (K32WIsDataReq(aRxFrame))
+        {
+            vMMAC_SetTxPend(K32WCheckIfFpRequired(aRxFrame));
+        }
+        else
+        {
+            /* Make sure this is set to 0 when we are not dealing with a data request */
+            aRxFrame->sFrameBody.u16Unused = 0;
+        }
+    }
+}
+
+/**
+ * Check if aRxFrame is a MAC Data Request Command
+ *
+ * @param[in] aRxFrame     Pointer to the latest received MAC packet
+ *
+ * @return TRUE 	aRxFrame is a MAC Data Request Frame
+ * @return FALSE	aRxFrame is not a MAC Data Request Frame
+ */
+static bool_t K32WIsDataReq(tsRxFrameFormat *aRxFrame)
+{
+    bool_t  isDataReq = FALSE;
+    uint8_t offset    = 0;
+
+    if (kFcfTypeMacCommand == (aRxFrame->sFrameBody.u16FCF & kFcfMacFrameTypeMask))
+    {
+        uint8_t secControlField = aRxFrame->sFrameBody.uPayload.au8Byte[0];
+
+        if (secControlField & kSecLevelMask)
+        {
+            offset += kSecurityControlSize;
+        }
+
+        if (!(secControlField & kFrameCounterSuppression))
+        {
+            offset += kFrameCounterSize;
+        }
+
+        switch (secControlField & kKeyIdModeMask)
+        {
+        case kKeyIdMode0:
+            offset += kKeySourceSizeMode0;
+            break;
+
+        case kKeyIdMode1:
+            offset += kKeySourceSizeMode1 + kKeyIndexSize;
+            break;
+
+        case kKeyIdMode2:
+            offset += kKeySourceSizeMode2 + kKeyIndexSize;
+            break;
+
+        case kKeyIdMode3:
+            offset += kKeySourceSizeMode3 + kKeyIndexSize;
+            break;
+        }
+
+        if (kMacFrameDataReq == aRxFrame->sFrameBody.uPayload.au8Byte[offset])
+        {
+            isDataReq = TRUE;
+        }
+    }
+
+    return isDataReq;
+}
+
+/**
+ * Check if Frame Pending was requested by aPsRxFrame
+ * We are in interrupt context.
+ *
+ * @param[in] aRxFrame  Pointer to a Data Request Frame
+ *
+ * @return    TRUE 	    Frame Pending bit should be set in the reply
+ * @return    FALSE	    Frame Pending bit shouldn't be set in the reply
+ *
+ */
+static bool K32WCheckIfFpRequired(tsRxFrameFormat *aRxFrame)
+{
+    bool     isFpRequired = FALSE;
+    uint16_t panId        = aRxFrame->sFrameBody.u16SrcPAN;
+    uint8_t  idx          = 0;
+
+    if (kFcfSrcAddrShort == (aRxFrame->sFrameBody.u16FCF & kFcfSrcAddrMask))
+    {
+        uint16_t shortAddr = aRxFrame->sFrameBody.uSrcAddr.u16Short;
+
+        for (idx = 0; idx < MAX_FP_ADDRS; idx++)
+        {
+            if (BIT_TST(sFpShortAddrMask, idx) && (sFpShortAddr[idx].macAddress == shortAddr) &&
+                sFpShortAddr[idx].panId == panId)
+            {
+                isFpRequired = TRUE;
+                break;
+            }
+        }
+    }
+    else
+    {
+        for (idx = 0; idx < MAX_FP_ADDRS; idx++)
+        {
+            if (BIT_TST(sFpExtAddrMask, idx) &&
+                (sFpExtAddr[idx].extAddr.u32L == aRxFrame->sFrameBody.uSrcAddr.sExt.u32L) &&
+                (sFpExtAddr[idx].extAddr.u32H == aRxFrame->sFrameBody.uSrcAddr.sExt.u32H) &&
+                sFpExtAddr[idx].panId == panId)
+            {
+                isFpRequired = TRUE;
+                break;
+            }
+        }
+    }
+    /* use the unsued filed to store if the frame was ack'ed with FP and report this back to OT stack */
+    aRxFrame->sFrameBody.u16Unused = isFpRequired;
+
+    return isFpRequired;
+}
+
+/**
+ * Process RX frames in process context and call the upper layer call-backs
+ *
+ * @param[in] aInstance  Pointer to OT instance
+ */
+static void K32WProcessRxFrames(otInstance *aInstance)
+{
+    tsRxFrameFormat *pRxMacFormatFrame = NULL;
+    uint32_t         savedInterrupts;
+
+    while ((pRxMacFormatFrame = K32WPopRxRingBuffer(&sRxRing)) != NULL)
+    {
+        if (OT_ERROR_NONE == K32WFrameConversion(pRxMacFormatFrame, &sRxOtFrame, macToOtFrame))
+        {
+            otPlatRadioReceiveDone(aInstance, &sRxOtFrame, OT_ERROR_NONE);
+        }
+        else
+        {
+            otPlatRadioReceiveDone(aInstance, NULL, OT_ERROR_ABORT);
+        }
+        memset(pRxMacFormatFrame, 0, sizeof(tsRxFrameFormat));
+
+        MICRO_DISABLE_AND_SAVE_INTERRUPTS(savedInterrupts);
+        sRxFrameInProcess = NULL;
+        if (sIsRxDisabled)
+        {
+            K32WEnableReceive(TRUE);
+        }
+        MICRO_RESTORE_INTERRUPTS(savedInterrupts);
+    }
+}
+
+/**
+ * Process TX frame in process context and call the upper layer call-backs
+ *
+ * @param[in] aInstance  Pointer to OT instance
+ */
+static void K32WProcessTxFrame(otInstance *aInstance)
+{
+    if (sTxDone)
+    {
+        sTxDone = FALSE;
+        if ((sTxOtFrame.mPsdu[kMacFcfLowOffset] & kFcfAckRequest) && (OT_ERROR_NONE == sTxStatus))
+        {
+            K32WFrameConversion(&sRxAckFrame, &sRxOtFrame, macToOtFrame);
+            otPlatRadioTxDone(aInstance, &sTxOtFrame, &sRxOtFrame, sTxStatus);
+        }
+        else
+        {
+            otPlatRadioTxDone(aInstance, &sTxOtFrame, NULL, sTxStatus);
+        }
+    }
+}
+
+/**
+ * aMacFormatFrame <-> aOtFrame bidirectional conversion
+ *
+ * @param[in] aMacFrameFormat  Pointer to a MAC Format frame
+ * @param[in] aOtFrame         Pointer to OpenThread Frame
+ * @param[in] convType         Conversion direction
+ *
+ * @return    OT_ERROR_NONE      No conversion error
+ * @return    OT_ERROR_PARSE     Conversion failed due to parsing error
+ */
+static otError K32WFrameConversion(tsRxFrameFormat *   aMacFormatFrame,
+                                   otRadioFrame *      aOtFrame,
+                                   frameConversionType convType)
+{
+    tsMacFrame *pMacFrame         = &aMacFormatFrame->sFrameBody;
+    uint8_t *   pSavedStartRxPSDU = aOtFrame->mPsdu;
+    uint8_t *   pPsdu             = aOtFrame->mPsdu;
+    uint16_t    aFcf              = 0;
+    otError     error             = OT_ERROR_NONE;
+
+    /* frame control field */
+    K32WCopy((uint8_t *)&pMacFrame->u16FCF, &pPsdu, kFcfSize, convType);
+    aFcf = pMacFrame->u16FCF;
+
+    /* sequence number */
+    if (0 == (aFcf & kFcfSeqNbSuppresssion))
+    {
+        K32WCopy(&pMacFrame->u8SequenceNum, &pPsdu, kDsnSize, convType);
+    }
+
+    /* destination Pan Id + address */
+    switch (aFcf & kFcfDstAddrMask)
+    {
+    case kFcfDstAddrNone:
+        break;
+
+    case kFcfDstAddrShort:
+        K32WCopy((uint8_t *)&pMacFrame->u16DestPAN, &pPsdu, sizeof(otPanId), convType);
+        K32WCopy((uint8_t *)&pMacFrame->uDestAddr.u16Short, &pPsdu, sizeof(otShortAddress), convType);
+        break;
+
+    case kFcfDstAddrExt:
+        K32WCopy((uint8_t *)&pMacFrame->u16DestPAN, &pPsdu, sizeof(otPanId), convType);
+        K32WCopy((uint8_t *)&pMacFrame->uDestAddr.sExt.u32L, &pPsdu, sizeof(uint32_t), convType);
+        K32WCopy((uint8_t *)&pMacFrame->uDestAddr.sExt.u32H, &pPsdu, sizeof(uint32_t), convType);
+        break;
+
+    default:
+        error = OT_ERROR_PARSE;
+        otEXPECT(false);
+    }
+
+    /* Source Pan Id */
+    if ((aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone && (aFcf & kFcfPanidCompression) == 0)
+    {
+        K32WCopy((uint8_t *)&pMacFrame->u16SrcPAN, &pPsdu, sizeof(otPanId), convType);
+    }
+
+    /* Source Address */
+    switch (aFcf & kFcfSrcAddrMask)
+    {
+    case kFcfSrcAddrNone:
+        break;
+
+    case kFcfSrcAddrShort:
+        K32WCopy((uint8_t *)&pMacFrame->uSrcAddr.u16Short, &pPsdu, sizeof(otShortAddress), convType);
+        break;
+
+    case kFcfSrcAddrExt:
+        K32WCopy((uint8_t *)&pMacFrame->uSrcAddr.sExt.u32L, &pPsdu, sizeof(uint32_t), convType);
+        K32WCopy((uint8_t *)&pMacFrame->uSrcAddr.sExt.u32H, &pPsdu, sizeof(uint32_t), convType);
+        break;
+
+    default:
+        error = OT_ERROR_PARSE;
+        otEXPECT(false);
+    }
+
+    if (convType == otToMacFrame)
+    {
+        pMacFrame->u8PayloadLength = aOtFrame->mLength - (pPsdu - pSavedStartRxPSDU) - kFcfSize;
+    }
+    else
+    {
+        aOtFrame->mInfo.mRxInfo.mAckedWithFramePending = (bool)aMacFormatFrame->sFrameBody.u16Unused;
+        aOtFrame->mInfo.mRxInfo.mLqi                   = aMacFormatFrame->u8LinkQuality;
+        aOtFrame->mInfo.mRxInfo.mRssi                  = i8Radio_GetLastPacketRSSI();
+        aOtFrame->mChannel                             = sChannel;
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+#error Time sync requires the timestamp of SFD rather than that of rx done!
+#else
+        if (otPlatRadioGetPromiscuous(sInstance))
+#endif
+        {
+            aOtFrame->mInfo.mRxInfo.mTimestamp = otPlatAlarmMilliGetNow() * 1000;
+        }
+
+        aOtFrame->mLength = pPsdu + (pMacFrame->u8PayloadLength) - pSavedStartRxPSDU + sizeof(pMacFrame->u16FCS);
+    }
+    K32WCopy((uint8_t *)&pMacFrame->uPayload, &pPsdu, pMacFrame->u8PayloadLength, convType);
+
+exit:
+    return error;
+}
+
+/**
+ * Helper function for aMacFrame <-> aOtFrame bidirectional conversion
+ * Copies from/to PSDU to/from specific field
+ *
+ * @param[in] aFieldValue     Pointer to field Value which needs to be copied/filled
+ * @param[in] aPsdu           Pointer to PSDU part which needs to be copied/filled
+ * @param[in] copySize        Bytes copied
+ * @param[in] convType        Conversion Type
+ *
+ * @return    OT_ERROR_NONE      No conversion error
+ * @return    OT_ERROR_PARSE     Conversion failed due to parsing error
+ */
+static void K32WCopy(uint8_t *aFieldValue, uint8_t **aPsdu, uint8_t copySize, frameConversionType convType)
+{
+    if (convType == macToOtFrame)
+    {
+        memcpy(*aPsdu, aFieldValue, copySize);
+    }
+    else
+    {
+        memcpy(aFieldValue, *aPsdu, copySize);
+    }
+
+    (*aPsdu) += copySize;
+}
+
+/**
+ * Function used to init/reset an RX Ring Buffer
+ *
+ * @param[in] aRxRing         Pointer to an RX Ring Buffer
+ */
+static void K32WResetRxRingBuffer(rxRingBuffer *aRxRing)
+{
+    aRxRing->head   = 0;
+    aRxRing->tail   = 0;
+    aRxRing->isFull = FALSE;
+}
+
+/**
+ * Function used to push the address of a received frame to the RX Ring buffer.
+ * In case the ring buffer is full, the oldest address is overwritten.
+ *
+ * @param[in] aRxRing             Pointer to the RX Ring Buffer
+ * @param[in] rxFrame             The address for a received frame
+ */
+static void K32WPushRxRingBuffer(rxRingBuffer *aRxRing, tsRxFrameFormat *aRxFrame)
+{
+    aRxRing->buffer[aRxRing->head] = aRxFrame;
+    if (aRxRing->isFull)
+    {
+        aRxRing->tail = (aRxRing->tail + 1) % K32W_RX_BUFFERS;
+    }
+
+    aRxRing->head   = (aRxRing->head + 1) % K32W_RX_BUFFERS;
+    aRxRing->isFull = (aRxRing->head == aRxRing->tail);
+}
+
+/**
+ * Function used to pop the address of a received frame from the RX Ring buffer
+ * Process Context: the consumer will pop frames with the interrupts disabled
+ *                  to make sure the interrupt context(ISR) doesn't push in
+ *                  the middle of a pop.
+ *
+ * @param[in] aRxRing           Pointer to the RX Ring Buffer
+ *
+ * @return    tsRxFrameFormat   Pointer to a received frame
+ * @return    NULL              In case the RX Ring buffer is empty
+ */
+static tsRxFrameFormat *K32WPopRxRingBuffer(rxRingBuffer *aRxRing)
+{
+    tsRxFrameFormat *rxFrame = NULL;
+    uint32_t         savedInterrupts;
+
+    MICRO_DISABLE_AND_SAVE_INTERRUPTS(savedInterrupts);
+    if (!K32WIsEmptyRxRingBuffer(aRxRing))
+    {
+        rxFrame         = aRxRing->buffer[aRxRing->tail];
+        aRxRing->isFull = FALSE;
+        aRxRing->tail   = (aRxRing->tail + 1) % K32W_RX_BUFFERS;
+    }
+    MICRO_RESTORE_INTERRUPTS(savedInterrupts);
+
+    return rxFrame;
+}
+
+/**
+ * Function used to check if an RX Ring buffer is empty
+ *
+ * @param[in] aRxRing           Pointer to the RX Ring Buffer
+ *
+ * @return    TRUE              RX Ring Buffer is not empty
+ * @return    FALSE             RX Ring Buffer is empty
+ */
+static bool K32WIsEmptyRxRingBuffer(rxRingBuffer *aRxRing)
+{
+    return (!aRxRing->isFull && (aRxRing->head == aRxRing->tail));
+}
+
+/**
+ * Function used to get the next frame from aRxFrame pointed by aRxFrameIndex.
+ *
+ * This is the address where the BBC should DMA a received frame. Once the
+ * reception is complete (the RX interrupt fires) this address is added to the
+ * ring buffer and the frame can be consumed by the process context.
+ *
+ * @param[in] aRxFrame            Pointer to an array of tsRxFrameFormat
+ * @param[in] aRxFrameIndex       Pointer to the current index in aRxFrame array
+ *
+ * @return    tsRxFrameFormat     Pointer to a tsRxFrameFormat
+ */
+static tsRxFrameFormat *K32WGetFrame(tsRxFrameFormat *aRxFrame, uint8_t *aRxFrameIndex)
+{
+    tsRxFrameFormat *frame = NULL;
+
+    frame = &aRxFrame[*aRxFrameIndex];
+    if (frame != sRxFrameInProcess)
+    {
+        *aRxFrameIndex = (*aRxFrameIndex + 1) % K32W_RX_BUFFERS;
+    }
+    else
+    {
+        /* this can happen only if the RX buffer is full and the
+         * process context is interrupted right in the middle of
+         * starting to process a frame. In this case, wait for
+         * the process context to finish the processing then
+         * re-enable RX
+         */
+
+        sIsRxDisabled = TRUE;
+        frame         = NULL;
+    }
+
+    return frame;
+}
+
+/**
+ * Function used to enable the receiving of a frame
+ *
+ * @param[in] isNewFrameNeeded FALSE in case the current RX buffer can be
+ *                             used for a new RX operation.
+ *
+ */
+static void K32WEnableReceive(bool_t isNewFrameNeeded)
+{
+    tsRxFrameFormat *pRxFrame = NULL;
+
+    if (isNewFrameNeeded)
+    {
+        if ((pRxFrame = K32WGetFrame(sRxFrame, &sRxFrameIndex)) != NULL)
+        {
+            vMMAC_SetRxFrame(pRxFrame);
+            K32WRestartRx();
+        }
+    }
+    else
+    {
+        K32WRestartRx();
+    }
+}
+
+/**
+ * Function used for MMAC-RX Restart
+ *
+ */
+static void K32WRestartRx(void)
+{
+    vMMAC_SetRxProm(((uint32)sRxOpt >> 8) & ALL_FFs_BYTE);
+    vMMAC_RxCtlUpdate(((uint32)sRxOpt) & ALL_FFs_BYTE);
+}
diff --git a/examples/platforms/k32w/src/random.c b/examples/platforms/k32w/src/random.c
new file mode 100755
index 0000000..4376bfc
--- /dev/null
+++ b/examples/platforms/k32w/src/random.c
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements a random number generator.
+ *
+ */
+
+#include "openthread/platform/random.h"
+#include "fsl_device_registers.h"
+#include "fsl_rng.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <utils/code_utils.h>
+
+void JN5189RandomInit(void)
+{
+    trng_config_t config;
+    uint32_t      seed;
+
+    TRNG_GetDefaultConfig(&config);
+    config.mode = trng_FreeRunning;
+
+    otEXPECT(TRNG_Init(RNG, &config) == kStatus_Success);
+
+    otEXPECT(TRNG_GetRandomData(RNG, &seed, sizeof(seed)) == kStatus_Success);
+
+    srand(seed);
+
+exit:
+    return;
+}
+
+uint32_t otPlatRandomGet(void)
+{
+    return (uint32_t)rand();
+}
+
+otError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength)
+{
+    otError status = OT_ERROR_NONE;
+
+    otEXPECT_ACTION((aOutput != NULL), status = OT_ERROR_INVALID_ARGS);
+
+    otEXPECT_ACTION(TRNG_GetRandomData(RNG, aOutput, aOutputLength) == kStatus_Success, status = OT_ERROR_FAILED);
+
+exit:
+    return status;
+}
diff --git a/examples/platforms/k32w/src/settings_k32w.c b/examples/platforms/k32w/src/settings_k32w.c
new file mode 100755
index 0000000..f92dff9
--- /dev/null
+++ b/examples/platforms/k32w/src/settings_k32w.c
@@ -0,0 +1,623 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for non-volatile storage of
+ *   settings on K32W platform. It has been modified and optimized from the original
+ *   Open Thread settings implementation to work with K32W's flash particularities.
+ *
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openthread-core-config.h>
+
+#include <openthread/instance.h>
+#include <openthread/platform/settings.h>
+
+#include "utils/code_utils.h"
+
+#include "openthread/platform/flash.h"
+
+#define OT_FLASH_BLOCK_ADD_BEGIN_FLAG (1 << 0)
+#define OT_FLASH_BLOCK_ADD_COMPLETE_FLAG (1 << 1)
+#define OT_FLASH_BLOCK_DELETE_FLAG (1 << 2)
+#define OT_FLASH_BLOCK_INDEX_0_FLAG (1 << 3)
+/* Compact flag is used to indicate that the next settings block follows at the next 16 bytes
+ * aligned address after the data portion of the current one. Otherwise the next block will be
+ * placed in the next flash page */
+#define OT_FLASH_BLOCK_COMPACT_FLAG (1 << 4)
+
+#define OT_SETTINGS_FLAG_SIZE 16
+#define OT_SETTINGS_BLOCK_DATA_SIZE 256
+
+/* K32W erases the flash to value 0x00 */
+#define FLASH_ERASE_VALUE 0x00
+#define FLASH_ALIGN_SIZE 16
+#define FLASH_BLOCK_PAD1_SIZE 10
+#define FLASH_BLOCK_PAD2_SIZE 15
+
+#define OT_SETTINGS_IN_USE 0xbe5cc5ee
+
+extern otError utilsFlashErasePage(uint32_t aAddress);
+
+/* Added padding to make settings block structure align to minimum flash write size of 16 bytes.
+ * The delFlag field has an offset of 16 bytes from the beginning of the structure to allow a new
+ * write on the field. */
+
+OT_TOOL_PACKED_BEGIN
+struct settingsBlock
+{
+    uint16_t key;
+    uint16_t flag;
+    uint16_t length;
+    uint8_t  padding1[FLASH_BLOCK_PAD1_SIZE];
+    uint8_t  delFlag;
+    uint8_t  padding2[FLASH_BLOCK_PAD2_SIZE];
+} OT_TOOL_PACKED_END;
+
+/**
+ * @def SETTINGS_CONFIG_BASE_ADDRESS
+ *
+ * The base address of settings.
+ *
+ */
+#ifndef SETTINGS_CONFIG_BASE_ADDRESS
+#define SETTINGS_CONFIG_BASE_ADDRESS 0
+#endif // SETTINGS_CONFIG_BASE_ADDRESS
+
+/**
+ * @def SETTINGS_CONFIG_PAGE_SIZE
+ *
+ * The page size of settings.
+ *
+ */
+#ifndef SETTINGS_CONFIG_PAGE_SIZE
+#define SETTINGS_CONFIG_PAGE_SIZE 0x800
+#endif // SETTINGS_CONFIG_PAGE_SIZE
+
+/**
+ * @def SETTINGS_CONFIG_PAGE_NUM
+ *
+ * The page number of settings.
+ *
+ */
+#ifndef SETTINGS_CONFIG_PAGE_NUM
+#define SETTINGS_CONFIG_PAGE_NUM 2
+#endif // SETTINGS_CONFIG_PAGE_NUM
+
+#if (SETTINGS_CONFIG_PAGE_NUM <= 1)
+#error "Invalid value for `SETTINGS_CONFIG_PAGE_NUM` (should be >= 2)"
+#endif
+
+/**
+ * @def FLASH_ERASE_VALUE
+ *
+ * The value a byte in flash takes after an erase operation.
+ *
+ */
+#ifndef FLASH_ERASE_VALUE
+#define FLASH_ERASE_VALUE 0xFF
+#endif // FLASH_ERASE_VALUE
+
+/* macros for setting/clearing bits in a flash byte depending on flash erase value */
+#if (FLASH_ERASE_VALUE == 0xFF)
+#define SET_FLASH_BLOCK_FLAG(aVar, aFlag) ((aVar) &= (~(aFlag)))
+#define FLASH_BLOCK_FLAG_IS_SET(aVar, aFlag) (!((aVar) & (aFlag)))
+
+#else
+// FLASH_ERASE_VALUE = 0x00
+#define SET_FLASH_BLOCK_FLAG(aVar, aFlag) ((aVar) |= (aFlag))
+#define FLASH_BLOCK_FLAG_IS_SET(aVar, aFlag) ((aVar) & (aFlag))
+
+#endif
+
+static uint32_t sSettingsBaseAddress;
+static uint32_t sSettingsUsedSize;
+static uint32_t sSettingsPageNum;
+
+/* linker file symbol for the number of flash sectors used for NVM */
+extern uint32_t NV_STORAGE_MAX_SECTORS;
+extern uint8_t  pageBuffer[];
+
+/**
+ * Calculates the aligned length of data for current settings block based on Compact flag
+ *
+ * @param[in] currentPos     Offset from the beginning of settings base address where the current
+ *                           block is located
+ * @param[in] blockFlag      Settings block flags value
+ * @param[in] length         Length of current block data
+
+ * @return uint16_t  Length of aligned data
+ */
+static uint16_t getAlignLength(uint16_t currentPos, uint8_t blockFlag, uint16_t length)
+{
+    uint16_t alignLen;
+    /* in case the compact flag is set length is calculated based on real one aligned to
+     * FLASH_ALIGN_SIZE(16 in this case) */
+    if (FLASH_BLOCK_FLAG_IS_SET(blockFlag, OT_FLASH_BLOCK_COMPACT_FLAG))
+    {
+        alignLen = (length + 1) & 0xfffe;
+    }
+    else
+    {
+        /* if the block is not compacted the length will be calculated so that the next block starts
+         * in the next flash page */
+        uint16_t pageOffset = currentPos % SETTINGS_CONFIG_PAGE_SIZE;
+        alignLen            = SETTINGS_CONFIG_PAGE_SIZE - pageOffset - sizeof(struct settingsBlock);
+    }
+
+    return alignLen;
+}
+
+static void setSettingsFlag(uint32_t aBase, uint32_t aFlag)
+{
+    otPlatFlashWrite(0, 0, aBase, (uint8_t *)&aFlag, sizeof(aFlag));
+}
+
+static void eraseSettings(uint32_t aBase)
+{
+    uint32_t address      = aBase;
+    uint32_t settingsSize = SETTINGS_CONFIG_PAGE_SIZE * sSettingsPageNum / 2;
+
+    while (address < (aBase + settingsSize))
+    {
+        utilsFlashErasePage(address);
+        address += SETTINGS_CONFIG_PAGE_SIZE;
+    }
+}
+
+static void initSettings(uint32_t aBase, uint32_t aFlag)
+{
+    eraseSettings(aBase);
+    setSettingsFlag(aBase, aFlag);
+}
+
+static uint32_t swapSettingsBlock(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t oldBase        = sSettingsBaseAddress;
+    uint32_t swapAddress    = oldBase;
+    uint32_t usedSize       = sSettingsUsedSize;
+    uint32_t settingsSize   = SETTINGS_CONFIG_PAGE_SIZE * sSettingsPageNum / 2;
+    bool     pageBufferUsed = true;
+    uint8_t  tempFlag;
+
+    /* New settings base address */
+    sSettingsBaseAddress =
+        (swapAddress == SETTINGS_CONFIG_BASE_ADDRESS) ? (swapAddress + settingsSize) : SETTINGS_CONFIG_BASE_ADDRESS;
+
+    /* Erase new settings */
+    eraseSettings(sSettingsBaseAddress);
+    /* Erase the page buffer used to accumulate data that will be written to a flash page once it is
+     * full */
+    memset(pageBuffer, FLASH_ERASE_VALUE, SETTINGS_CONFIG_PAGE_SIZE);
+
+    *((uint32_t *)pageBuffer) = OT_SETTINGS_IN_USE;
+    sSettingsUsedSize         = OT_SETTINGS_FLAG_SIZE;
+    swapAddress += OT_SETTINGS_FLAG_SIZE;
+
+    while (swapAddress < (oldBase + usedSize))
+    {
+        OT_TOOL_PACKED_BEGIN
+        struct addSettingsBlock
+        {
+            struct settingsBlock block;
+            uint8_t              data[OT_SETTINGS_BLOCK_DATA_SIZE];
+        } OT_TOOL_PACKED_END addBlock;
+        bool                 valid = true;
+
+        otPlatFlashRead(aInstance, 0, swapAddress, (uint8_t *)(&addBlock.block), sizeof(struct settingsBlock));
+        swapAddress += sizeof(struct settingsBlock);
+        tempFlag = addBlock.block.flag;
+
+        if ((FLASH_BLOCK_FLAG_IS_SET(addBlock.block.flag, OT_FLASH_BLOCK_ADD_COMPLETE_FLAG)) &&
+            (0 == FLASH_BLOCK_FLAG_IS_SET(addBlock.block.delFlag, OT_FLASH_BLOCK_DELETE_FLAG)))
+
+        {
+            uint32_t address = swapAddress + getAlignLength(swapAddress - sizeof(struct settingsBlock),
+                                                            addBlock.block.flag, addBlock.block.length);
+
+            while (address < (oldBase + usedSize))
+            {
+                struct settingsBlock block;
+
+                otPlatFlashRead(aInstance, 0, address, (uint8_t *)(&block), sizeof(block));
+
+                if ((FLASH_BLOCK_FLAG_IS_SET(block.flag, OT_FLASH_BLOCK_ADD_COMPLETE_FLAG)) &&
+                    (0 == FLASH_BLOCK_FLAG_IS_SET(block.delFlag, OT_FLASH_BLOCK_DELETE_FLAG)) &&
+                    (FLASH_BLOCK_FLAG_IS_SET(block.flag, OT_FLASH_BLOCK_INDEX_0_FLAG)) &&
+                    (block.key == addBlock.block.key))
+
+                {
+                    valid = false;
+                    break;
+                }
+
+                address += (getAlignLength(address, block.flag, block.length) + sizeof(struct settingsBlock));
+            }
+
+            if (valid)
+            {
+                /* Calculate the size of data(block + settings data) that will be written to the
+                 * page buffer */
+                uint32_t writeSize = sizeof(struct settingsBlock);
+
+                if (!FLASH_BLOCK_FLAG_IS_SET(addBlock.block.flag, OT_FLASH_BLOCK_COMPACT_FLAG))
+                {
+                    /* Once a swap is initiated every settings block is compacted in the new flash
+                     * region */
+                    SET_FLASH_BLOCK_FLAG(addBlock.block.flag, OT_FLASH_BLOCK_COMPACT_FLAG);
+                }
+
+                /* current pos parameter doesn't count in this case */
+                writeSize += getAlignLength(0, OT_FLASH_BLOCK_COMPACT_FLAG, addBlock.block.length);
+
+                otPlatFlashRead(aInstance, 0, swapAddress, addBlock.data, addBlock.block.length);
+                /* contents fits in current page - we can copy it to page buffer until there is
+                 * enough data to program a page */
+                if ((sSettingsUsedSize % SETTINGS_CONFIG_PAGE_SIZE) + writeSize <= SETTINGS_CONFIG_PAGE_SIZE)
+                {
+                    pageBufferUsed = false;
+                    memcpy(pageBuffer + (sSettingsUsedSize % SETTINGS_CONFIG_PAGE_SIZE), (uint8_t *)(&addBlock),
+                           writeSize);
+                }
+                else
+                {
+                    /* Page buffer is full and can be written to a flash page */
+                    pageBufferUsed = true;
+
+                    uint32_t remPageSize = SETTINGS_CONFIG_PAGE_SIZE - (sSettingsUsedSize % SETTINGS_CONFIG_PAGE_SIZE);
+                    memcpy(pageBuffer + (sSettingsUsedSize % SETTINGS_CONFIG_PAGE_SIZE), (uint8_t *)(&addBlock),
+                           remPageSize);
+
+                    /* calculate page address that we are going to write */
+                    uint32_t alignAddress = sSettingsBaseAddress + sSettingsUsedSize;
+                    alignAddress          = alignAddress - (alignAddress % SETTINGS_CONFIG_PAGE_SIZE);
+                    otPlatFlashWrite(aInstance, 0, alignAddress, pageBuffer, SETTINGS_CONFIG_PAGE_SIZE);
+
+                    /* After the page buffer is erased copy what dind't fit the previous page */
+                    memset(pageBuffer, FLASH_ERASE_VALUE, SETTINGS_CONFIG_PAGE_SIZE);
+                    memcpy(pageBuffer, (uint8_t *)(&addBlock) + remPageSize, writeSize - remPageSize);
+                }
+
+                sSettingsUsedSize += writeSize;
+            }
+        }
+        else if (addBlock.block.flag == FLASH_ERASE_VALUE)
+        {
+            break;
+        }
+        swapAddress += getAlignLength(swapAddress - sizeof(struct settingsBlock), tempFlag, addBlock.block.length);
+    }
+
+    if (false == pageBufferUsed)
+    {
+        /* If the page buffer has been used and it's not full write to flash at the end */
+        uint32_t alignAddr = sSettingsBaseAddress + sSettingsUsedSize;
+        alignAddr          = alignAddr - (alignAddr % SETTINGS_CONFIG_PAGE_SIZE);
+        otPlatFlashWrite(aInstance, 0, alignAddr, pageBuffer, SETTINGS_CONFIG_PAGE_SIZE);
+    }
+    /* Clear the old settings zone */
+    eraseSettings(oldBase);
+
+    return settingsSize - sSettingsUsedSize;
+}
+
+static otError addSetting(otInstance *   aInstance,
+                          uint16_t       aKey,
+                          bool           aIndex0,
+                          const uint8_t *aValue,
+                          uint16_t       aValueLength)
+{
+    otError error = OT_ERROR_NONE;
+    OT_TOOL_PACKED_BEGIN
+    struct addSettingsBlock
+    {
+        struct settingsBlock block;
+        uint8_t              data[OT_SETTINGS_BLOCK_DATA_SIZE];
+    } OT_TOOL_PACKED_END addBlock;
+    uint32_t             settingsSize = SETTINGS_CONFIG_PAGE_SIZE * sSettingsPageNum / 2;
+
+    /* Add all the settings flags once and optimize for one write to flash */
+    addBlock.block.flag    = FLASH_ERASE_VALUE;
+    addBlock.block.delFlag = FLASH_ERASE_VALUE;
+    addBlock.block.key     = aKey;
+    memset(addBlock.block.padding1, FLASH_ERASE_VALUE, FLASH_BLOCK_PAD1_SIZE);
+    memset(addBlock.block.padding2, FLASH_ERASE_VALUE, FLASH_BLOCK_PAD2_SIZE);
+
+    if (aIndex0)
+    {
+        SET_FLASH_BLOCK_FLAG(addBlock.block.flag, OT_FLASH_BLOCK_INDEX_0_FLAG);
+    }
+
+    SET_FLASH_BLOCK_FLAG(addBlock.block.flag, OT_FLASH_BLOCK_ADD_BEGIN_FLAG);
+    addBlock.block.length = aValueLength;
+
+    if ((sSettingsUsedSize + getAlignLength(sSettingsUsedSize, addBlock.block.flag, addBlock.block.length) +
+         sizeof(struct settingsBlock)) >= settingsSize)
+    {
+        otEXPECT_ACTION(swapSettingsBlock(aInstance) >=
+                            (getAlignLength(sSettingsUsedSize, addBlock.block.flag, addBlock.block.length) +
+                             sizeof(struct settingsBlock)),
+                        error = OT_ERROR_NO_BUFS);
+    }
+
+    memset(addBlock.data, FLASH_ERASE_VALUE, OT_SETTINGS_BLOCK_DATA_SIZE);
+    memcpy(addBlock.data, aValue, addBlock.block.length);
+
+    SET_FLASH_BLOCK_FLAG(addBlock.block.flag, OT_FLASH_BLOCK_ADD_COMPLETE_FLAG);
+    otPlatFlashWrite(aInstance, 0, sSettingsBaseAddress + sSettingsUsedSize, (uint8_t *)(&addBlock.block),
+                     sizeof(struct settingsBlock) + addBlock.block.length);
+    /* The next settings block will be written to the next flash page to optimize the number of
+     * writes made to a page */
+    sSettingsUsedSize +=
+        (sizeof(struct settingsBlock) + getAlignLength(sSettingsUsedSize, addBlock.block.flag, addBlock.block.length));
+
+exit:
+    return error;
+}
+
+// settings API
+void otPlatSettingsInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint8_t              index;
+    struct settingsBlock block;
+
+    /* exported symbol from linker file */
+    sSettingsPageNum      = (uint32_t)&NV_STORAGE_MAX_SECTORS;
+    uint32_t settingsSize = SETTINGS_CONFIG_PAGE_SIZE * sSettingsPageNum / 2;
+
+    sSettingsBaseAddress = SETTINGS_CONFIG_BASE_ADDRESS;
+
+    otPlatFlashInit(aInstance);
+
+    for (index = 0; index < 2; index++)
+    {
+        uint32_t blockFlag;
+
+        sSettingsBaseAddress += settingsSize * index;
+        otPlatFlashRead(aInstance, 0, sSettingsBaseAddress, (uint8_t *)(&blockFlag), sizeof(blockFlag));
+
+        if (blockFlag == OT_SETTINGS_IN_USE)
+        {
+            break;
+        }
+    }
+
+    if (index == 2)
+    {
+        initSettings(sSettingsBaseAddress, (uint32_t)OT_SETTINGS_IN_USE);
+    }
+
+    sSettingsUsedSize = OT_SETTINGS_FLAG_SIZE;
+
+    while (sSettingsUsedSize < settingsSize)
+    {
+        otPlatFlashRead(aInstance, 0, sSettingsBaseAddress + sSettingsUsedSize, (uint8_t *)(&block), sizeof(block));
+
+        if (FLASH_BLOCK_FLAG_IS_SET(block.flag, OT_FLASH_BLOCK_ADD_BEGIN_FLAG))
+        {
+            sSettingsUsedSize +=
+                (getAlignLength(sSettingsUsedSize, block.flag, block.length) + sizeof(struct settingsBlock));
+        }
+        else
+        {
+            break;
+        }
+    }
+}
+
+void otPlatSettingsDeinit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+otError otPlatSettingsBeginChange(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatSettingsCommitChange(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatSettingsAbandonChange(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError  error       = OT_ERROR_NOT_FOUND;
+    uint32_t address     = sSettingsBaseAddress + OT_SETTINGS_FLAG_SIZE;
+    uint16_t valueLength = 0;
+    int      index       = 0;
+
+    while (address < (sSettingsBaseAddress + sSettingsUsedSize))
+    {
+        struct settingsBlock block;
+
+        otPlatFlashRead(aInstance, 0, address, (uint8_t *)(&block), sizeof(block));
+
+        if (block.key == aKey)
+        {
+            if (FLASH_BLOCK_FLAG_IS_SET(block.flag, OT_FLASH_BLOCK_INDEX_0_FLAG))
+            {
+                index = 0;
+            }
+
+            if ((FLASH_BLOCK_FLAG_IS_SET(block.flag, OT_FLASH_BLOCK_ADD_COMPLETE_FLAG)) &&
+                (0 == FLASH_BLOCK_FLAG_IS_SET(block.delFlag, OT_FLASH_BLOCK_DELETE_FLAG)))
+            {
+                if (index == aIndex)
+                {
+                    uint16_t readLength = block.length;
+
+                    // only perform read if an input buffer was passed in
+                    if (aValue != NULL && aValueLength != NULL)
+                    {
+                        // adjust read length if input buffer length is smaller
+                        if (readLength > *aValueLength)
+                        {
+                            readLength = *aValueLength;
+                        }
+
+                        otPlatFlashRead(aInstance, 0, address + sizeof(struct settingsBlock), aValue, readLength);
+                    }
+
+                    valueLength = block.length;
+                    error       = OT_ERROR_NONE;
+                }
+
+                index++;
+            }
+        }
+
+        address += (getAlignLength(address, block.flag, block.length) + sizeof(struct settingsBlock));
+    }
+
+    if (aValueLength != NULL)
+    {
+        *aValueLength = valueLength;
+    }
+
+    return error;
+}
+
+otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    return addSetting(aInstance, aKey, true, aValue, aValueLength);
+}
+
+otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    uint16_t length;
+    bool     index0;
+
+    index0 = (otPlatSettingsGet(aInstance, aKey, 0, NULL, &length) == OT_ERROR_NOT_FOUND ? true : false);
+    return addSetting(aInstance, aKey, index0, aValue, aValueLength);
+}
+
+otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError  error   = OT_ERROR_NOT_FOUND;
+    uint32_t address = sSettingsBaseAddress + OT_SETTINGS_FLAG_SIZE;
+    int      index   = 0;
+
+    while (address < (sSettingsBaseAddress + sSettingsUsedSize))
+    {
+        struct settingsBlock block;
+
+        otPlatFlashRead(aInstance, 0, address, (uint8_t *)(&block), sizeof(block));
+
+        if (block.key == aKey)
+        {
+            if (FLASH_BLOCK_FLAG_IS_SET(block.flag, OT_FLASH_BLOCK_INDEX_0_FLAG))
+            {
+                index = 0;
+            }
+
+            if ((FLASH_BLOCK_FLAG_IS_SET(block.flag, OT_FLASH_BLOCK_ADD_COMPLETE_FLAG)) &&
+                (0 == FLASH_BLOCK_FLAG_IS_SET(block.delFlag, OT_FLASH_BLOCK_DELETE_FLAG)))
+            {
+                bool flashWrite = false;
+
+                if (aIndex == index || aIndex == -1)
+                {
+                    error = OT_ERROR_NONE;
+                    SET_FLASH_BLOCK_FLAG(block.delFlag, OT_FLASH_BLOCK_DELETE_FLAG);
+                    flashWrite = true;
+                }
+
+                if (index == 1 && aIndex == 0)
+                {
+                    SET_FLASH_BLOCK_FLAG(block.flag, OT_FLASH_BLOCK_INDEX_0_FLAG);
+                    flashWrite = true;
+                }
+
+                if (flashWrite)
+                {
+                    otPlatFlashWrite(aInstance, 0, address, (uint8_t *)(&block), sizeof(block));
+                }
+
+                index++;
+            }
+        }
+
+        address += (getAlignLength(address, block.flag, block.length) + sizeof(struct settingsBlock));
+    }
+
+    return error;
+}
+
+void otPlatSettingsWipe(otInstance *aInstance)
+{
+    uint32_t address = SETTINGS_CONFIG_BASE_ADDRESS;
+
+    /* Clears all the flash pages during a factory reset */
+    for (uint32_t i = 0; i < sSettingsPageNum; i++)
+    {
+        /* This function protects against erasing an already erased page so we can just erase all
+         * pages to have and have all the settings storage clean */
+        utilsFlashErasePage(address);
+        address += SETTINGS_CONFIG_PAGE_SIZE;
+    }
+
+    /* Each time a factory reset is invoked start the settings zone in the alternate region to
+     * maximize wear leveling */
+    if (SETTINGS_CONFIG_BASE_ADDRESS == sSettingsBaseAddress)
+    {
+        sSettingsBaseAddress = SETTINGS_CONFIG_BASE_ADDRESS + (SETTINGS_CONFIG_PAGE_SIZE * sSettingsPageNum / 2);
+    }
+    else
+    {
+        sSettingsBaseAddress = SETTINGS_CONFIG_BASE_ADDRESS;
+    }
+    setSettingsFlag(sSettingsBaseAddress, OT_SETTINGS_IN_USE);
+
+    otPlatSettingsInit(aInstance);
+}
diff --git a/examples/platforms/k32w/src/system.c b/examples/platforms/k32w/src/system.c
new file mode 100755
index 0000000..6dbc2de
--- /dev/null
+++ b/examples/platforms/k32w/src/system.c
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes the platform-specific initializers.
+ *
+ */
+#include "board.h"
+#include "pin_mux.h"
+#include "platform-k32w.h"
+#include "openthread/platform/uart.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+otInstance *sInstance;
+
+void otSysInit(int argc, char *argv[])
+{
+    bool bHwInit = true;
+
+    if ((argc == 1) && (!strcmp(argv[0], "app")))
+    {
+        bHwInit = false;
+    }
+
+    if (bHwInit)
+    {
+        /* Security code to allow debug access */
+        SYSCON->CODESECURITYPROT = 0x87654320;
+
+        BOARD_BootClockRUN();
+        BOARD_InitPins();
+    }
+
+    K32WAlarmInit();
+    K32WRandomInit();
+    K32WRadioInit();
+}
+
+bool otSysPseudoResetWasRequested(void)
+{
+    /* TODO */
+    return false;
+}
+
+void otSysDeinit(void)
+{
+    /* TODO */
+}
+
+void otSysProcessDrivers(otInstance *aInstance)
+{
+    K32WRadioProcess(aInstance);
+    K32WUartProcess();
+    K32WAlarmProcess(aInstance);
+}
+
+void otSysEventSignalPending(void)
+{
+    /* TODO */
+}
diff --git a/examples/platforms/k32w/src/uart.c b/examples/platforms/k32w/src/uart.c
new file mode 100755
index 0000000..dbb2d7f
--- /dev/null
+++ b/examples/platforms/k32w/src/uart.c
@@ -0,0 +1,347 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for UART communication.
+ *
+ */
+
+/* NXP UART includes */
+#include "board.h"
+#include "fsl_clock.h"
+#include "fsl_flexcomm.h"
+#include "fsl_reset.h"
+#include "fsl_usart.h"
+
+/* Openthread general includes */
+#include <utils/code_utils.h>
+#include "openthread/platform/uart.h"
+
+/* Defines */
+#define K32W_UART_RX_BUFFERS 256
+#define K32W_UART_BAUD_RATE 115200
+
+/* Structures */
+typedef struct
+{
+    uint8_t buffer[K32W_UART_RX_BUFFERS];
+    uint8_t head;
+    uint8_t tail;
+    bool    isFull;
+} rxRingBuffer;
+
+/* Enums */
+typedef enum
+{
+    UART_IDLE, /* TX idle. */
+    UART_BUSY, /* TX busy. */
+} K32WUartStates;
+
+/* Private functions declaration */
+static void     K32WResetRxRingBuffer(rxRingBuffer *aRxRing);
+static uint8_t *K32WPopRxRingBuffer(rxRingBuffer *aRxRing);
+static bool     K32WIsEmptyRxRingBuffer(rxRingBuffer *aRxRing);
+static void     K32WPushRxRingBuffer(rxRingBuffer *aRxRing, uint8_t aCharacter);
+static void     K32WProcessReceive(void);
+static void     K32WProcessTransmit(void);
+static void     USART0_IRQHandler(USART_Type *base, usart_handle_t *handle);
+
+/* Private variables declaration */
+static bool           sIsUartInitialized; /* Is UART module initialized? */
+static bool           sIsTransmitDone;    /* Transmit done for the latest user-data buffer */
+static usart_handle_t sUartHandle;        /* Handle to the UART module */
+static rxRingBuffer   sUartRxRing;        /* Receive Ring Buffer */
+
+void K32WUartProcess(void)
+{
+    if (sIsUartInitialized)
+    {
+        K32WProcessTransmit();
+        K32WProcessReceive();
+    }
+}
+
+otError otPlatUartEnable(void)
+{
+    status_t uartStatus;
+    otError  error = OT_ERROR_NONE;
+
+    usart_config_t config;
+    uint32_t       kPlatformClock = CLOCK_GetFreq(kCLOCK_Fro32M);
+
+    /* attach clock for USART0 */
+    CLOCK_AttachClk(kOSC32M_to_USART_CLK);
+
+    /* reset FLEXCOMM0 for USART0 */
+    RESET_PeripheralReset(kFC0_RST_SHIFT_RSTn);
+
+    memset(&sUartHandle, 0, sizeof(sUartHandle));
+    sUartHandle.txState = UART_IDLE;
+
+    USART_GetDefaultConfig(&config);
+    config.baudRate_Bps = K32W_UART_BAUD_RATE;
+    config.enableTx     = true;
+    config.enableRx     = true;
+    config.rxWatermark  = kUSART_RxFifo1;
+
+    uartStatus = USART_Init(USART0, &config, kPlatformClock);
+    otEXPECT_ACTION(uartStatus == kStatus_Success, error = OT_ERROR_INVALID_ARGS);
+
+    K32WResetRxRingBuffer(&sUartRxRing);
+
+    FLEXCOMM_SetIRQHandler(USART0, (flexcomm_irq_handler_t)USART0_IRQHandler, &sUartHandle);
+
+    /* Enable interrupt in NVIC. */
+    EnableIRQ(USART0_IRQn);
+
+    /* Enable RX interrupt. */
+    USART_EnableInterrupts(USART0, kUSART_RxLevelInterruptEnable | kUSART_RxErrorInterruptEnable);
+
+    sIsUartInitialized = true;
+
+exit:
+    return error;
+}
+
+otError otPlatUartDisable(void)
+{
+    sIsUartInitialized = false;
+    USART_Deinit(USART0);
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(!sUartHandle.txData, error = OT_ERROR_BUSY);
+    sUartHandle.txData        = (uint8_t *)aBuf;
+    sUartHandle.txDataSize    = aBufLength;
+    sUartHandle.txDataSizeAll = aBufLength;
+
+    /* Enable transmitter interrupt. */
+    USART_EnableInterrupts(USART0, kUSART_TxLevelInterruptEnable);
+
+exit:
+    return error;
+}
+
+otError otPlatUartFlush(void)
+{
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * Function used for blocking-write to the UART module.
+ *
+ * @param[in] aBuf             Pointer to the character buffer
+ * @param[in] len              Length of the character buffer
+ */
+void K32WWriteBlocking(const uint8_t *aBuf, uint32_t len)
+{
+    otEXPECT(sIsUartInitialized && sUartHandle.txState != UART_BUSY);
+
+    sUartHandle.txState = UART_BUSY;
+    USART_WriteBlocking(USART0, aBuf, len);
+    sUartHandle.txState = UART_IDLE;
+
+exit:
+    return;
+}
+
+/**
+ * Process TX characters in process context and call the upper layer call-backs.
+ */
+static void K32WProcessTransmit(void)
+{
+    if (sIsTransmitDone)
+    {
+        sIsTransmitDone = false;
+        otPlatUartSendDone();
+    }
+}
+
+/**
+ * Process RX characters in process context and call the upper layer call-backs.
+ */
+static void K32WProcessReceive(void)
+{
+    uint8_t  rx[K32W_UART_RX_BUFFERS];
+    uint16_t rxIndex = 0;
+    uint8_t *pCharacter;
+
+    while ((pCharacter = K32WPopRxRingBuffer(&sUartRxRing)) != NULL)
+    {
+        rx[rxIndex] = *pCharacter;
+        rxIndex++;
+    }
+    otPlatUartReceived(rx, rxIndex);
+}
+
+static void USART0_IRQHandler(USART_Type *base, usart_handle_t *handle)
+{
+    (void)base;
+    (void)handle;
+
+    bool isReceiveEnabled = true;
+    bool isSendEnabled    = (sUartHandle.txDataSize != 0);
+
+    /* If RX overrun. */
+    if (USART0->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK)
+    {
+        /* Clear RX error state. */
+        USART0->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
+        /* clear RX FIFO */
+        USART0->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+    }
+    while ((isReceiveEnabled && (USART0->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK)) ||
+           (isSendEnabled && (USART0->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK)))
+    {
+        /* RX: an interrupt is fired for each received character */
+        if (isReceiveEnabled && (USART0->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK))
+        {
+            volatile uint8_t rx_data = USART_ReadByte(USART0);
+
+            {
+                K32WPushRxRingBuffer(&sUartRxRing, rx_data);
+            }
+        }
+
+        /* There are times when the UART interrupt fires unnecessarily
+         * having the TXNOTFULL and TXEMPY bits set. Disable this!
+         */
+        if ((!sUartHandle.txDataSize) && (USART0->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) &&
+            (USART0->FIFOSTAT & USART_FIFOSTAT_TXEMPTY_MASK))
+        {
+            USART0->FIFOINTENCLR = USART_FIFOINTENCLR_TXLVL_MASK;
+        }
+
+        /* TX: an interrupt is fired for each sent character */
+        if (isSendEnabled && (USART0->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK))
+        {
+            USART0->FIFOWR = *sUartHandle.txData;
+            sUartHandle.txDataSize--;
+            sUartHandle.txData++;
+            isSendEnabled = (sUartHandle.txDataSize != 0);
+
+            if (!isSendEnabled)
+            {
+                USART0->FIFOINTENCLR = USART_FIFOINTENCLR_TXLVL_MASK;
+                sUartHandle.txData   = NULL;
+                sIsTransmitDone      = true;
+            }
+        }
+    }
+}
+
+/**
+ * Function used to push a received character to the RX Ring buffer.
+ * In case the ring buffer is full, the oldest address is overwritten.
+ *
+ * @param[in] aRxRing             Pointer to the RX Ring Buffer
+ * @param[in] aCharacter          The received character
+ */
+static void K32WPushRxRingBuffer(rxRingBuffer *aRxRing, uint8_t aCharacter)
+{
+    aRxRing->buffer[aRxRing->head] = aCharacter;
+
+    if (aRxRing->isFull)
+    {
+        aRxRing->tail = (aRxRing->tail + 1) % K32W_UART_RX_BUFFERS;
+    }
+
+    aRxRing->head   = (aRxRing->head + 1) % K32W_UART_RX_BUFFERS;
+    aRxRing->isFull = (aRxRing->head == aRxRing->tail);
+}
+
+/**
+ * Function used to pop the address of a received character from the RX Ring buffer
+ * Process Context: the consumer will pop frames with the interrupts disabled
+ *                  to make sure the interrupt context(ISR) doesn't push in
+ *                  the middle of a pop.
+ *
+ * @param[in] aRxRing           Pointer to the RX Ring Buffer
+ *
+ * @return    tsRxFrameFormat   Pointer to a received character
+ * @return    NULL              In case the RX Ring buffer is empty
+ */
+static uint8_t *K32WPopRxRingBuffer(rxRingBuffer *aRxRing)
+{
+    uint8_t *pCharacter = NULL;
+
+    DisableIRQ(USART0_IRQn);
+    if (!K32WIsEmptyRxRingBuffer(aRxRing))
+    {
+        pCharacter      = &(aRxRing->buffer[aRxRing->tail]);
+        aRxRing->isFull = false;
+        aRxRing->tail   = (aRxRing->tail + 1) % K32W_UART_RX_BUFFERS;
+    }
+    EnableIRQ(USART0_IRQn);
+
+    return pCharacter;
+}
+
+/**
+ * Function used to check if an RX Ring buffer is empty
+ *
+ * @param[in] aRxRing           Pointer to the RX Ring Buffer
+ *
+ * @return    TRUE              RX Ring Buffer is not empty
+ * @return    FALSE             RX Ring Buffer is empty
+ */
+static bool K32WIsEmptyRxRingBuffer(rxRingBuffer *aRxRing)
+{
+    return (!aRxRing->isFull && (aRxRing->head == aRxRing->tail));
+}
+
+/**
+ * Function used to init/reset an RX Ring Buffer
+ *
+ * @param[in] aRxRing         Pointer to an RX Ring Buffer
+ */
+static void K32WResetRxRingBuffer(rxRingBuffer *aRxRing)
+{
+    aRxRing->head   = 0;
+    aRxRing->tail   = 0;
+    aRxRing->isFull = false;
+}
+
+/**
+ * The UART driver weak functions definition.
+ *
+ */
+OT_TOOL_WEAK void otPlatUartSendDone(void)
+{
+}
+
+OT_TOOL_WEAK void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    OT_UNUSED_VARIABLE(aBuf);
+    OT_UNUSED_VARIABLE(aBufLength);
+}
diff --git a/examples/platforms/kw41z/CMakeLists.txt b/examples/platforms/kw41z/CMakeLists.txt
new file mode 100644
index 0000000..d76e883
--- /dev/null
+++ b/examples/platforms/kw41z/CMakeLists.txt
@@ -0,0 +1,86 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(OT_PLATFORM_LIB "openthread-kw41z" PARENT_SCOPE)
+
+if(NOT OT_CONFIG)
+    set(OT_CONFIG "openthread-core-kw41z-config.h")
+    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES
+    "OPENTHREAD_CORE_CONFIG_PLATFORM_CHECK_FILE=\"openthread-core-kw41z-config-check.h\""
+)
+set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
+
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+
+add_library(openthread-kw41z
+    alarm.c
+    diag.c
+    entropy.c
+    flash.c
+    logging.c
+    misc.c
+    radio.c
+    system.c
+    uart.c
+)
+
+set_target_properties(
+    openthread-kw41z
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_link_libraries(openthread-kw41z PRIVATE nxp-kw41z-driver ot-config)
+target_link_options(openthread-kw41z PRIVATE -T${PROJECT_SOURCE_DIR}/examples/platforms/kw41z/MKW41Z512xxx4.ld)
+target_link_options(openthread-kw41z PRIVATE -Wl,--gc-sections -Wl,-Map=$<TARGET_PROPERTY:NAME>.map)
+
+target_compile_definitions(openthread-kw41z
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-kw41z
+    PRIVATE
+        ${OT_CFLAGS}
+        -Wno-unknown-pragmas
+        -Wno-sign-compare
+        -Wno-unused-function
+        -Wno-unused-parameter
+        -Wno-empty-body
+)
+
+target_include_directories(openthread-kw41z
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        ${PROJECT_SOURCE_DIR}/examples/platforms
+        ${PROJECT_SOURCE_DIR}/src/core
+)
diff --git a/examples/platforms/kw41z/Makefile.am b/examples/platforms/kw41z/Makefile.am
index 33d7ef4..3522d2b 100644
--- a/examples/platforms/kw41z/Makefile.am
+++ b/examples/platforms/kw41z/Makefile.am
@@ -34,6 +34,10 @@
 override CFLAGS                              := $(filter-out -Wundef,$(CFLAGS))
 override CXXFLAGS                            := $(filter-out -Wundef,$(CXXFLAGS))
 
+# Do not enable -Wcast-align for this platform
+override CFLAGS                              := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                            := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 libopenthread_kw41z_a_CPPFLAGS                                                                     = \
     -DCPU_MKW41Z512VHT4                                                                              \
     -I$(top_srcdir)/include                                                                          \
@@ -99,10 +103,6 @@
     $(PLATFORM_SOURCES)                                                                              \
     $(NULL)
 
-PRETTY_FILES                                                                                       = \
-    $(PLATFORM_SOURCES)                                                                              \
-    $(NULL)
-
 Dash                                                                                               = -
 libopenthread_kw41z_a_LIBADD                                                                       = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
diff --git a/examples/platforms/kw41z/README.md b/examples/platforms/kw41z/README.md
index 78f71f2..7950545 100644
--- a/examples/platforms/kw41z/README.md
+++ b/examples/platforms/kw41z/README.md
@@ -1,14 +1,11 @@
 # OpenThread on NXP(Freescale) Kinetis MKW41Z512 Example
 
-This directory contains example platform drivers for the [NXP(Freescale) Kinetis MKW41Z512][mkw41z512]
-based on [FRDM-KW41Z][frdm-kw41z] hardware platform.
+This directory contains example platform drivers for the [NXP(Freescale) Kinetis MKW41Z512][mkw41z512] based on [FRDM-KW41Z][frdm-kw41z] hardware platform.
 
 [mkw41z512]: http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/kinetis-cortex-m-mcus/w-series-wireless-m0-plus-m4/kinetis-kw41z-2.4-ghz-dual-mode-ble-and-802.15.4-wireless-radio-microcontroller-mcu-based-on-arm-cortex-m0-plus-core:KW41Z
 [frdm-kw41z]: http://www.nxp.com/products/software-and-tools/hardware-development-tools/freedom-development-boards/nxp-freedom-development-kit-for-kinetis-kw41z-31z-21z-mcus:FRDM-KW41Z
 
-The example platform drivers are intended to present the minimal code
-necessary to support OpenThread.  As a result, the example platform
-drivers do not necessarily highlight the platform's full capabilities.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. As a result, the example platform drivers do not necessarily highlight the platform's full capabilities.
 
 ## Toolchain
 
@@ -16,8 +13,7 @@
 
 [gnu-toolchain]: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -32,18 +28,15 @@
 $ make -f examples/Makefile-kw41z
 ```
 
-After a successful build, the `elf` files are found in
-`<path-to-openthread>/output/kw41z/bin`.  You can convert them to `bin`
-files using `arm-none-eabi-objcopy`:
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/kw41z/bin`. You can convert them to `bin` files using `arm-none-eabi-objcopy`:
+
 ```bash
 $ arm-none-eabi-objcopy -O binary ot-cli-ftd ot-cli-ftd.bin
 ```
 
 ## Flash Binaries
 
-Compiled binaries may be flashed onto the MKW41Z512 using drag-and-drop into the board's MSD Bootloader
- or the [NXP(Freescale) Test Tool][test-tool] or [JTAG interface][jtag].
-The [NXP(Freescale) Test Tool][test-tool] provides a convenient method for flashing a MKW41Z512 via the [J-Link][jlink].
+Compiled binaries may be flashed onto the MKW41Z512 using drag-and-drop into the board's MSD Bootloader or the [NXP(Freescale) Test Tool][test-tool] or [JTAG interface][jtag]. The [NXP(Freescale) Test Tool][test-tool] provides a convenient method for flashing a MKW41Z512 via the [J-Link][jlink].
 
 [test-tool]: http://www.nxp.com/webapp/sps/download/license.jsp?colCode=TESTTOOL_SETUP
 [jtag]: https://en.wikipedia.org/wiki/JTAG
@@ -52,84 +45,84 @@
 ## Running the example
 
 1. Prepare two boards with the flashed `CLI Example` (as shown above).
-2. The CLI example uses UART connection. To view raw UART output, start a terminal
-   emulator like PuTTY and connect to the used COM port with the following UART settings:
-    - Baud rate: 115200
-    - 8 data bits
-    - 1 stop bit
-    - No parity
-    - No flow control
+2. The CLI example uses UART connection. To view raw UART output, start a terminal emulator like PuTTY and connect to the used COM port with the following UART settings:
+
+   - Baud rate: 115200
+   - 8 data bits
+   - 1 stop bit
+   - No parity
+   - No flow control
 
 3. Open a terminal connection on the first board and start a new Thread network.
 
-    ```bash
-    > dataset init new
-    Done
-    > dataset
-    Active Timestamp: 1
-    Channel: 13
-    Channel Mask: 07fff800
-    Ext PAN ID: d63e8e3e495ebbc3
-    Mesh Local Prefix: fd3d:b50b:f96d:722d/64
-    Master Key: dfd34f0f05cad978ec4e32b0413038ff
-    Network Name: OpenThread-8f28
-    PAN ID: 0x8f28
-    PSKc: c23a76e98f1a6483639b1ac1271e2e27
-    Security Policy: 0, onrcb
-    Done
-    > dataset commit active
-    Done
-    > ifconfig up
-    Done
-    > thread start
-    Done
-    ```
+   ```bash
+   > dataset init new
+   Done
+   > dataset
+   Active Timestamp: 1
+   Channel: 13
+   Channel Mask: 07fff800
+   Ext PAN ID: d63e8e3e495ebbc3
+   Mesh Local Prefix: fd3d:b50b:f96d:722d/64
+   Master Key: dfd34f0f05cad978ec4e32b0413038ff
+   Network Name: OpenThread-8f28
+   PAN ID: 0x8f28
+   PSKc: c23a76e98f1a6483639b1ac1271e2e27
+   Security Policy: 0, onrcb
+   Done
+   > dataset commit active
+   Done
+   > ifconfig up
+   Done
+   > thread start
+   Done
+   ```
 
 4. After a couple of seconds the node will become a Leader of the network.
 
-    ```bash
-    > state
-    leader
-    ```
+   ```bash
+   > state
+   leader
+   ```
 
 5. Open a terminal connection on the second board and attach a node to the network.
 
-    ```bash
-    > dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
-    Done
-    > dataset commit active
-    Done
-    > ifconfig up
-    Done
-    > thread start
-    Done
-    ```
+   ```bash
+   > dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
+   Done
+   > dataset commit active
+   Done
+   > ifconfig up
+   Done
+   > thread start
+   Done
+   ```
 
 6. After a couple of seconds the second node will attach and become a Child.
 
-    ```bash
-    > state
-    child
-    ```
+   ```bash
+   > state
+   child
+   ```
 
 7. List all IPv6 addresses of the first board.
 
-    ```bash
-    > ipaddr
-    fd3d:b50b:f96d:722d:0:ff:fe00:fc00
-    fd3d:b50b:f96d:722d:0:ff:fe00:c00
-    fd3d:b50b:f96d:722d:7a73:bff6:9093:9117
-    fe80:0:0:0:6c41:9001:f3d6:4148
-    Done
-    ```
+   ```bash
+   > ipaddr
+   fd3d:b50b:f96d:722d:0:ff:fe00:fc00
+   fd3d:b50b:f96d:722d:0:ff:fe00:c00
+   fd3d:b50b:f96d:722d:7a73:bff6:9093:9117
+   fe80:0:0:0:6c41:9001:f3d6:4148
+   Done
+   ```
 
 8. Choose one of them and send an ICMPv6 ping from the second board.
 
-    ```bash
-    > ping fd3d:b50b:f96d:722d:7a73:bff6:9093:9117
-    16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
-    ```
+   ```bash
+   > ping fd3d:b50b:f96d:722d:7a73:bff6:9093:9117
+   16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
+   ```
 
-For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
 
-[CLI]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
+[cli]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
diff --git a/examples/platforms/kw41z/arm-none-eabi.cmake b/examples/platforms/kw41z/arm-none-eabi.cmake
new file mode 100644
index 0000000..d67bcb6
--- /dev/null
+++ b/examples/platforms/kw41z/arm-none-eabi.cmake
@@ -0,0 +1,50 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(CMAKE_SYSTEM_NAME              Generic)
+set(CMAKE_SYSTEM_PROCESSOR         ARM)
+
+set(CMAKE_C_COMPILER               arm-none-eabi-gcc)
+set(CMAKE_CXX_COMPILER             arm-none-eabi-g++)
+set(CMAKE_ASM_COMPILER             arm-none-eabi-as)
+set(CMAKE_RANLIB                   arm-none-eabi-ranlib)
+
+set(COMMON_C_FLAGS                 "-mthumb -fdata-sections -ffunction-sections -mcpu=cortex-m0plus -mfloat-abi=soft")
+
+set(CMAKE_C_FLAGS                  "${COMMON_C_FLAGS} -std=gnu99")
+set(CMAKE_CXX_FLAGS                "${COMMON_C_FLAGS} -fno-exceptions -fno-rtti")
+set(CMAKE_ASM_FLAGS                "${COMMON_C_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS_INIT    "${COMMON_C_FLAGS} -specs=nano.specs -specs=nosys.specs")
+
+set(CMAKE_C_FLAGS_DEBUG            "-Og -g")
+set(CMAKE_CXX_FLAGS_DEBUG          "-Og -g")
+set(CMAKE_ASM_FLAGS_DEBUG          "-g")
+
+set(CMAKE_C_FLAGS_RELEASE          "-Os")
+set(CMAKE_CXX_FLAGS_RELEASE        "-Os")
+set(CMAKE_ASM_FLAGS_RELEASE        "")
diff --git a/examples/platforms/kw41z/diag.c b/examples/platforms/kw41z/diag.c
index f0fcc87..2796f52 100644
--- a/examples/platforms/kw41z/diag.c
+++ b/examples/platforms/kw41z/diag.c
@@ -49,15 +49,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
-
-    // Add more platform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/kw41z/flash.c b/examples/platforms/kw41z/flash.c
index 9d94410..5b66799 100644
--- a/examples/platforms/kw41z/flash.c
+++ b/examples/platforms/kw41z/flash.c
@@ -26,85 +26,67 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stdint.h>
+
+#include <openthread/instance.h>
+
 #include "fsl_device_registers.h"
 #include "fsl_flash.h"
-#include <stdint.h>
-#include <utils/code_utils.h>
-#include <utils/flash.h>
-#include "openthread/platform/alarm-milli.h"
+
+#define FLASH_BASE_ADDRESS 0x40000
+#define FLASH_PAGE_SIZE 0x800
+#define FLASH_PAGE_NUM 2
+#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * (FLASH_PAGE_NUM / 2))
 
 static flash_config_t sFlashConfig;
 
-otError utilsFlashInit(void)
+static uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    otError error = OT_ERROR_NONE;
+    uint32_t address = FLASH_BASE_ADDRESS + aOffset;
 
-    if (FLASH_Init(&sFlashConfig) != kStatus_FLASH_Success)
+    if (aSwapIndex)
     {
-        error = OT_ERROR_FAILED;
+        address += FLASH_SWAP_SIZE;
     }
 
-    return error;
+    return address;
 }
 
-uint32_t utilsFlashGetSize(void)
+void otPlatFlashInit(otInstance *aInstance)
 {
-    return FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE;
+    OT_UNUSED_VARIABLE(aInstance);
+
+    FLASH_Init(&sFlashConfig);
 }
 
-otError utilsFlashErasePage(uint32_t aAddress)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
 {
-    otError  error;
-    status_t status;
+    OT_UNUSED_VARIABLE(aInstance);
 
-    status = FLASH_Erase(&sFlashConfig, aAddress, FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE, kFLASH_ApiEraseKey);
+    return FLASH_SWAP_SIZE;
+}
 
-    if (status == kStatus_FLASH_Success)
+void otPlatFlashErase(otInstance *aInstance, uint32_t aSwapIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    FLASH_Erase(&sFlashConfig, mapAddress(aSwapIndex, 0), FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE,
+                kFLASH_ApiEraseKey);
+    while ((FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK) == 0)
     {
-        error = OT_ERROR_NONE;
     }
-    else if (status == kStatus_FLASH_AlignmentError)
-    {
-        error = OT_ERROR_INVALID_ARGS;
-    }
-    else
-    {
-        error = OT_ERROR_FAILED;
-    }
-
-    return error;
 }
 
-otError utilsFlashStatusWait(uint32_t aTimeout)
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
 {
-    otError  error = OT_ERROR_BUSY;
-    uint32_t start = otPlatAlarmMilliGetNow();
+    OT_UNUSED_VARIABLE(aInstance);
 
-    do
-    {
-        if (FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK)
-        {
-            error = OT_ERROR_NONE;
-            break;
-        }
-    } while (aTimeout && ((otPlatAlarmMilliGetNow() - start) < aTimeout));
-
-    return error;
+    FLASH_Program(&sFlashConfig, mapAddress(aSwapIndex, aOffset), (uint32_t *)aData, aSize);
 }
 
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
 {
-    if (FLASH_Program(&sFlashConfig, aAddress, (uint32_t *)aData, aSize) != kStatus_FLASH_Success)
-    {
-        aSize = 0;
-    }
+    OT_UNUSED_VARIABLE(aInstance);
 
-    return aSize;
-}
-
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    memcpy(aData, (uint8_t *)aAddress, aSize);
-
-    return aSize;
+    memcpy(aData, (void *)mapAddress(aSwapIndex, aOffset), aSize);
 }
diff --git a/examples/platforms/kw41z/logging.c b/examples/platforms/kw41z/logging.c
index 4d3023e..82158ae 100644
--- a/examples/platforms/kw41z/logging.c
+++ b/examples/platforms/kw41z/logging.c
@@ -37,8 +37,7 @@
 #include <openthread/platform/logging.h>
 #include <openthread/platform/toolchain.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
 {
     OT_UNUSED_VARIABLE(aLogLevel);
diff --git a/examples/platforms/kw41z/openthread-core-kw41z-config.h b/examples/platforms/kw41z/openthread-core-kw41z-config.h
index ecb8097..923dc03 100644
--- a/examples/platforms/kw41z/openthread-core-kw41z-config.h
+++ b/examples/platforms/kw41z/openthread-core-kw41z-config.h
@@ -53,28 +53,14 @@
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "KW41Z"
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of settings.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
  *
  */
-#define SETTINGS_CONFIG_BASE_ADDRESS 0x40000
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_SIZE 0x800
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_NUM 2
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
 
 /**
  * @def RADIO_CONFIG_SRC_MATCH_ENTRY_NUM
@@ -85,20 +71,28 @@
 #define RADIO_CONFIG_SRC_MATCH_ENTRY_NUM 128
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0
 
 /**
  * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
diff --git a/examples/platforms/kw41z/radio.c b/examples/platforms/kw41z/radio.c
index 4baa443..ec4b321 100644
--- a/examples/platforms/kw41z/radio.c
+++ b/examples/platforms/kw41z/radio.c
@@ -283,7 +283,7 @@
     }
 }
 
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -301,7 +301,7 @@
     return rf_add_addr_table_entry(checksum, true);
 }
 
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
diff --git a/examples/platforms/nrf528xx/DIAG.md b/examples/platforms/nrf528xx/DIAG.md
index b54448a..1801d24 100644
--- a/examples/platforms/nrf528xx/DIAG.md
+++ b/examples/platforms/nrf528xx/DIAG.md
@@ -1,34 +1,33 @@
 ## Diagnostic module
 
-nRF52811 and nRF52840 ports extend [OpenThread Diagnostics Module][DIAG].
+nRF52811 and nRF52840 ports extend [OpenThread Diagnostics Module][diag].
 
 New commands allow for more accurate low level radio testing.
 
 ### New commands
- * [diag ccathreshold](#diag-ccathreshold)
- * [diag gpio](#diag-gpio)
- * [diag id](#diag-id)
- * [diag listen](#diag-listen)
- * [diag temp](#diag-temp)
- * [diag transmit](#diag-transmit)
+
+- [diag ccathreshold](#diag-ccathreshold)
+- [diag gpio](#diag-gpio)
+- [diag id](#diag-id)
+- [diag listen](#diag-listen)
+- [diag temp](#diag-temp)
+- [diag transmit](#diag-transmit)
 
 ### Diagnostic radio packet
+
 [diag listen](#diag-listen) and [diag transmit](#diag-transmit) use radio frame payload specified below.
 
- ```c
- struct PlatformDiagMessage
- {
-     const char mMessageDescriptor[11];
-     uint8_t mChannel;
-     int16_t mID;
-     uint32_t mCnt;
- };
- ```
+```c
+struct PlatformDiagMessage
+{
+    const char mMessageDescriptor[11];
+    uint8_t mChannel;
+    int16_t mID;
+    uint32_t mCnt;
+};
+```
 
-`mMessageDescriptor` is a constant string `"DiagMessage"`.<br />
-`mChannel` contains the channel number on which the packet was transmitted.<br />
-`mID` contains the board ID set with the [diag id](#diag-id) command.<br />
-`mCnt` is a counter incremented every time the board transmits diagnostic radio packet.
+`mMessageDescriptor` is a constant string `"DiagMessage"`.<br /> `mChannel` contains the channel number on which the packet was transmitted.<br /> `mID` contains the board ID set with the [diag id](#diag-id) command.<br /> `mCnt` is a counter incremented every time the board transmits diagnostic radio packet.
 
 If the [listen mode](#diag-listen) is enabled and OpenThread was built with the`DEFAULT_LOGGING` flag, JSON string is printed every time a diagnostic radio packet is received.
 
@@ -44,9 +43,11 @@
 ```
 
 ### diag ccathreshold
+
 Get the current CCA threshold.
 
 ### diag ccathreshold \<threshold\>
+
 Set the CCA threshold.
 
 Value range: 0 to 255.
@@ -54,16 +55,19 @@
 Default: `45`.
 
 ### diag gpio
+
 Manage GPIO pins.
 
 ### diag gpio \<pinnum\>
+
 Return the current value of the gpio.
 
-Note: \<pinnum\> is an integer that combines port and pin into a single,
-contiguous number space as follows:
+Note: \<pinnum\> is an integer that combines port and pin into a single, contiguous number space as follows:
+
 ```
    pinnum = (port * 32) + pin
 ```
+
 See also the [`NRF_GPIO_PIN_MAP`](../../../third_party/NordicSemiconductor/hal/nrf_gpio.h) macro.
 
 ```bash
@@ -72,37 +76,47 @@
 ```
 
 ### diag gpio out \<pinnum\>
+
 Set the given GPIO to the output mode.
+
 ```bash
 > diag gpio out 47
 gpio 47: out
 ```
 
 ### diag gpio in \<pinnum\>
+
 Sets the given GPIO to the input mode with no pull variant.
+
 ```bash
 > diag gpio in 47
 gpio 47: in no pull
 ```
 
 ### diag gpio set \<pinnum\>
+
 Sets the given output gpio to high.
+
 ```bash
 > diag gpio set 47
 gpio 47 = 1
 ```
 
 ### diag gpio clr \<pinnum\>
+
 Sets the given output gpio to low.
+
 ```bash
 > diag gpio clr 47
 gpio 47 = 0
 ```
 
 ### diag id
+
 Get board ID.
 
 ### diag id \<id\>
+
 Set board ID.
 
 Value range: 0 to 32767.
@@ -110,23 +124,27 @@
 Default: `-1`.
 
 ### diag listen
+
 Get the listen state.
 
 ### diag listen \<listen\>
+
 Set the listen state.
 
-`0` disables the listen state.<br />
-`1` enables the listen state.
+`0` disables the listen state.<br /> `1` enables the listen state.
 
 By default, the listen state is disabled.
 
 ### diag temp
+
 Get the temperature from the internal temperature sensor (in degrees Celsius).
 
 ### diag transmit
+
 Get the message count and the interval between the messages that will be transmitted after `diag transmit start`.
 
 ### diag transmit interval \<interval\>
+
 Set the interval in ms between the transmitted messages.
 
 Value range: 1 to 4294967295.
@@ -134,21 +152,23 @@
 Default: `1`.
 
 ### diag transmit count \<count\>
+
 Set the number of messages to be transmitted.
 
-Value range: 1 to 2147483647<br />
-or<br />
-For continuous transmission: `-1`
+Value range: 1 to 2147483647<br /> or<br /> For continuous transmission: `-1`
 
 Default: `1`
 
 ### diag transmit stop
+
 Stop the ongoing transmission regardless of the remaining number of messages to be sent.
 
 ### diag transmit start
+
 Start transmiting messages with specified interval.
 
 ### diag transmit carrier
+
 Start transmitting continuous carrier wave.
 
-[DIAG]: ./../../../src/core/diags/README.md
+[diag]: ./../../../src/core/diags/README.md
diff --git a/examples/platforms/nrf528xx/Makefile.am b/examples/platforms/nrf528xx/Makefile.am
index b726c17..b227c27 100644
--- a/examples/platforms/nrf528xx/Makefile.am
+++ b/examples/platforms/nrf528xx/Makefile.am
@@ -27,29 +27,18 @@
 #
 
 # Use automake includes since we cannot use SUBDIRS feature due to  cleanup
-# errors - few targets may use the same source file but dependency file is 
+# errors - few targets may use the same source file but dependency file is
 # created only once which leads to errors when auto-generated Makefile tries
 # to remove .Po files that were already removed
 
-if OPENTHREAD_EXAMPLES_NRF52811
+if OPENTHREAD_PLATFORM_NRF52811
 include nrf52811/Makefile.am
 endif
 
-if OPENTHREAD_EXAMPLES_NRF52833
+if OPENTHREAD_PLATFORM_NRF52833
 include nrf52833/Makefile.am
 endif
 
-if OPENTHREAD_EXAMPLES_NRF52840
+if OPENTHREAD_PLATFORM_NRF52840
 include nrf52840/Makefile.am
 endif
-
-include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
-
-PRETTY_FILES                            = \
-    src/platform-fem.h                    \
-    src/platform-nrf5.h                   \
-    $(wildcard $(srcdir)/**/*.c)          \
-    $(wildcard $(srcdir)/**/*.h)          \
-    $(NULL)
-
-include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/nrf528xx/README.md b/examples/platforms/nrf528xx/README.md
index 98715c7..f94a180 100644
--- a/examples/platforms/nrf528xx/README.md
+++ b/examples/platforms/nrf528xx/README.md
@@ -1,16 +1,17 @@
 # OpenThread on nRF528xx Example
 
-This directory contains example platform drivers for [Nordic Semiconductor nRF52840 SoC][nRF52840], [Nordic Semiconductor nRF52833 SoC][nRF52833] and [Nordic Semiconductor nRF52811 SoC][nRF52811].
+This directory contains example platform drivers for [Nordic Semiconductor nRF52840 SoC][nrf52840], [Nordic Semiconductor nRF52833 SoC][nrf52833] and [Nordic Semiconductor nRF52811 SoC][nrf52811].
 
-[nRF52840]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52840
-[nRF52833]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52833
-[nRF52811]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52811
+[nrf52840]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52840
+[nrf52833]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52833
+[nrf52811]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52811
 
 To learn more about building and running the examples please check:
-* [OpenThread on nRF52840 examples][nrf52840-page]
-* [OpenThread on nRF52833 examples][nrf52833-page]
-* [OpenThread on nRF52811 examples][nrf52811-page]
+
+- [OpenThread on nRF52840 examples][nrf52840-page]
+- [OpenThread on nRF52833 examples][nrf52833-page]
+- [OpenThread on nRF52811 examples][nrf52811-page]
 
 [nrf52840-page]: ./nrf52840/README.md
 [nrf52833-page]: ./nrf52833/README.md
-[nrf52811-page]: ./nrf52811/README.md
\ No newline at end of file
+[nrf52811-page]: ./nrf52811/README.md
diff --git a/examples/platforms/nrf528xx/nrf52811/Makefile.am b/examples/platforms/nrf528xx/nrf52811/Makefile.am
index 8011fc6..386e152 100644
--- a/examples/platforms/nrf528xx/nrf52811/Makefile.am
+++ b/examples/platforms/nrf528xx/nrf52811/Makefile.am
@@ -31,6 +31,7 @@
 lib_LIBRARIES                                                                                              = \
     libopenthread-nrf52811.a                                                                                 \
     libopenthread-nrf52811-sdk.a                                                                             \
+    libopenthread-nrf52811-transport.a                                                                       \
     $(NULL)
 
 # Do not enable -pedantic-errors for nRF52811 driver library
@@ -41,26 +42,49 @@
 override CFLAGS                                      := $(filter-out -Wundef,$(CFLAGS))
 override CXXFLAGS                                    := $(filter-out -Wundef,$(CXXFLAGS))
 
+# Do not enable -Wcast-align for nRF52811 driver library
+override CFLAGS                                      := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                                    := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 COMMONCPPFLAGS                                                                                             = \
     -DCONFIG_GPIO_AS_PINRESET                                                                                \
     -DNRF52811_XXAA                                                                                          \
+    -DUSE_APP_CONFIG=1                                                                                       \
     -I$(srcdir)                                                                                              \
     -I$(top_srcdir)/include                                                                                  \
     -I$(top_srcdir)/examples/platforms                                                                       \
     -I$(top_srcdir)/examples/platforms/nrf528xx/src                                                          \
+    -I$(top_srcdir)/examples/platforms/nrf528xx/src/transport                                                \
     -I$(top_srcdir)/src/core                                                                                 \
-    -I$(top_srcdir)/third_party/NordicSemiconductor                                                          \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                    \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                             \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock                                            \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common                                           \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio                                            \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal                                        \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features                               \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/three_pin_gpio                         \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator                 \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch                                       \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal                                  \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer                          \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/temperature                       \
+    -Wno-unused-parameter                                                                                    \
+    $(NULL)
+
+# Only reference the SDK header files included in third_party/NordicSemiconductor
+# when building the example applications.
+#
+# When building just the platform libraries, the caller of configure is expected
+# to provide the correct -I arguments to locate the necessary header files in an
+# external copy of the Nordic nRF5 SDK.
+#
+# Note that an exception is made for the 802.15.4 radio driver, which is always
+# built using the sources in third_party/NordicSemiconductor/drivers/radio.
+if OPENTHREAD_ENABLE_EXAMPLES
+COMMONCPPFLAGS                                                                                            += \
+    -I$(top_srcdir)/third_party/NordicSemiconductor                                                          \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                    \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config                                                   \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52811/config                                   \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                             \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock                                            \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common                                           \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power                                            \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick                                          \
     -I$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error                                      \
@@ -75,7 +99,9 @@
     -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include                                     \
     -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk                                                 \
     -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/soc                                                 \
+    -Wno-unused-parameter                                                                                    \
     $(NULL)
+endif
 
 PLATFORM_COMMON_SOURCES                                                                                    = \
     src/alarm.c                                                                                              \
@@ -86,10 +112,14 @@
     src/logging.c                                                                                            \
     src/misc.c                                                                                               \
     src/radio.c                                                                                              \
-    src/spi-slave.c                                                                                          \
     src/system.c                                                                                             \
     src/temp.c                                                                                               \
-    src/uart.c                                                                                               \
+    $(NULL)
+
+TRANSPORT_SOURCES                                                                                          = \
+    src/transport/spi-slave.c                                                                                \
+    src/transport/uart.c                                                                                     \
+    src/transport/transport.c                                                                                \
     $(NULL)
 
 SINGLEPHY_SOURCES                                                                                          = \
@@ -124,6 +154,14 @@
     $(SINGLEPHY_SOURCES)                                                                                     \
     $(NULL)
 
+libopenthread_nrf52811_transport_a_CPPFLAGS                                                                = \
+    $(COMMONCPPFLAGS)                                                                                        \
+    $(NULL)
+
+libopenthread_nrf52811_transport_a_SOURCES                                                                 = \
+    $(TRANSPORT_SOURCES)                                                                                     \
+    $(NULL)
+
 Dash                                                                                                       = -
 
 libopenthread_nrf52811_a_LIBADD                                                                            = \
@@ -133,4 +171,7 @@
 libopenthread_nrf52811_sdk_a_LIBADD                                                                        = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
 
+libopenthread_nrf52811_transport_a_LIBADD                                                                  = \
+    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
+
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/nrf528xx/nrf52811/Makefile.platform.am b/examples/platforms/nrf528xx/nrf52811/Makefile.platform.am
index f05f377..d0042b0 100644
--- a/examples/platforms/nrf528xx/nrf52811/Makefile.platform.am
+++ b/examples/platforms/nrf528xx/nrf52811/Makefile.platform.am
@@ -32,6 +32,7 @@
 
 LDADD_COMMON                                                                                 += \
     $(top_builddir)/examples/platforms/nrf528xx/libopenthread-nrf52811.a                        \
+    $(top_builddir)/examples/platforms/nrf528xx/libopenthread-nrf52811-transport.a              \
     $(top_builddir)/third_party/NordicSemiconductor/libnordicsemi-nrf52811-sdk.a                \
     $(top_builddir)/third_party/NordicSemiconductor/libnordicsemi-nrf52811-radio-driver.a       \
     $(NULL)
diff --git a/examples/platforms/nrf528xx/nrf52811/README.md b/examples/platforms/nrf528xx/nrf52811/README.md
index d667022..be0dc8c 100644
--- a/examples/platforms/nrf528xx/nrf52811/README.md
+++ b/examples/platforms/nrf528xx/nrf52811/README.md
@@ -1,19 +1,16 @@
 # OpenThread on nRF52811 Example
 
-This directory contains example platform drivers for [Nordic Semiconductor nRF52811 SoC][nRF52811].
+This directory contains example platform drivers for [Nordic Semiconductor nRF52811 SoC][nrf52811].
 
-[nRF52811]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52811
+[nrf52811]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52811
 
-This SoC is meant to be used in the configuration that involves the Host Processor and the IEEE 802.15.4 radio.
-In this configuration, the full OpenThread stack is running on the Host Processor and the nRF52811 SoC acts as an IEEE 802.15.4 radio.
-The radio is running a minimal OpenThread implementation that allows for communication between the Host Processor and the nRF52811.
-In this architecture the nRF52811 SoC device is called RCP (Radio Co-Processor).
+This SoC is meant to be used in the configuration that involves the Host Processor and the IEEE 802.15.4 radio. In this configuration, the full OpenThread stack is running on the Host Processor and the nRF52811 SoC acts as an IEEE 802.15.4 radio. The radio is running a minimal OpenThread implementation that allows for communication between the Host Processor and the nRF52811. In this architecture the nRF52811 SoC device is called RCP (Radio Co-Processor).
 
 The nRF52811 platform is currently under development.
 
-For the SoC capable to a run full OpenThread stack, see the [nRF52840 platform][nRF52840-page].
+For the SoC capable to a run full OpenThread stack, see the [nRF52840 platform][nrf52840-page].
 
-[nRF52840-page]: ./../nrf52840/README.md
+[nrf52840-page]: ./../nrf52840/README.md
 
 ## Emulation on nRF52840
 
@@ -38,28 +35,28 @@
 
 ### Flashing and debugging tools
 
-[nRF-Command-Line-Tools]: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools
+[nrf-command-line-tools]: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools
 
-Install the [nRF Command Line Tools][nRF-Command-Line-Tools] to flash, debug, and make use of logging features on the nRF52811 DK with SEGGER J-Link.
+Install the [nRF Command Line Tools][nrf-command-line-tools] to flash, debug, and make use of logging features on the nRF52811 DK with SEGGER J-Link.
 
 ## Building the examples
 
 With this platform, you can build:
- - Limited version of CLI example (e.g. without Thread commissioning functionality)
- - RCP example that consists of two parts:
-    - firmware that is flashed to the nRF52811 SoC
-    - host executables to be executed on a POSIX platform in case of the RCP usage
+
+- Limited version of CLI example (e.g. without Thread commissioning functionality)
+- RCP example that consists of two parts:
+  - firmware that is flashed to the nRF52811 SoC
+  - host executables to be executed on a POSIX platform in case of the RCP usage
 
 ### Building host executables
+
 ```bash
 $ cd <path-to-openthread>
 $ ./bootstrap
 $ make -f src/posix/Makefile-posix
 ```
 
-After a successful build, executables can be found in
-`<path-to-openthread>/openthread/output/posix/<system-architecture>/bin`.
-It is recommended to copy them to `/usr/bin` for easier access.
+After a successful build, executables can be found in `<path-to-openthread>/openthread/output/posix/<system-architecture>/bin`. It is recommended to copy them to `/usr/bin` for easier access.
 
 ### Building the firmware with UART support
 
@@ -71,9 +68,8 @@
 $ make -f examples/Makefile-nrf52811
 ```
 
-After a successful build, the `elf` files can be found in
-`<path-to-openthread>/output/nrf52811/bin`.
-You can convert them to hex using `arm-none-eabi-objcopy`:
+After a successful build, the `elf` files can be found in `<path-to-openthread>/output/nrf52811/bin`. You can convert them to hex using `arm-none-eabi-objcopy`:
+
 ```bash
 $ arm-none-eabi-objcopy -O ihex ot-cli-mtd ot-cli-mtd.hex
 $ arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex
@@ -81,22 +77,21 @@
 
 ### Building the firmware with native SPI support
 
-You can build the libraries with support for the native SPI Slave.
-To do so, build the libraries with the following parameter:
+You can build the libraries with support for the native SPI Slave. To do so, build the libraries with the following parameter:
+
 ```
 $ make -f examples/Makefile-nrf52811 NCP_SPI=1
 ```
 
 With this option enabled, the RCP example can communicate through SPI with wpantund (provided that the wpantund host supports SPI Master). To achieve this communication, choose the right SPI device in the wpantund configuration file, `/etc/wpantund.conf`. See the following example.
 
-
 ```
 Config:NCP:SocketPath "system:/usr/bin/ot-ncp /usr/bin/spi-hdlc-adapter -- '--stdio -i /sys/class/gpio/gpio25 /dev/spidev0.1'"
 ```
 
 In this example, [spi-hdlc-adapter][spi-hdlc-adapter] is a tool that you can use to communicate between RCP and wpantund over SPI. For this example, `spi-hdlc-adapter` is installed in `/usr/bin`.
 
-The default SPI Slave pin configuration for nRF52811 is defined in `examples/platforms/nrf52811/platform-config.h`.
+The default SPI Slave pin configuration for nRF52811 is defined in `examples/platforms/nrf52811/transport-config.h`.
 
 [spi-hdlc-adapter]: https://github.com/openthread/openthread/tree/master/tools/spi-hdlc-adapter
 
@@ -105,8 +100,9 @@
 When the Thread device is configured to obtain the Thread Network security credentials with either Thread Commissioning or an out-of-band method, the extended MAC address should be constructed out of the globally unique IEEE EUI-64.
 
 The IEEE EUI-64 address consists of two parts:
- - 24 bits of MA-L (MAC Address Block Large), formerly called OUI (Organizationally Unique Identifier)
- - 40-bit device unique identifier
+
+- 24 bits of MA-L (MAC Address Block Large), formerly called OUI (Organizationally Unique Identifier)
+- 40-bit device unique identifier
 
 By default, the device uses Nordic Semiconductor's MA-L (f4-ce-36). You can modify it by overwriting the `OPENTHREAD_CONFIG_STACK_VENDOR_OUI` define, located in the `openthread-core-nrf52811-config.h` file. This value must be publicly registered by the IEEE Registration Authority.
 
@@ -116,8 +112,7 @@
 
 ## Flashing binaries
 
-Once the examples and libraries are built, flash the compiled binaries onto nRF52811
-using `nrfjprog` that is part of the [nRF Command Line Tools][nRF-Command-Line-Tools].
+Once the examples and libraries are built, flash the compiled binaries onto nRF52811 using `nrfjprog` that is part of the [nRF Command Line Tools][nrf-command-line-tools].
 
 Run the following command:
 
@@ -137,9 +132,7 @@
 
 4. Connect the RCP to the PC.
 
-5. Start the ot-cli host application and connect with the RCP.
-   It is assumed that the default UART version of RCP is being used (make executed without the NCP-SPI=1 flag).
-   On Linux system, call a port name, for example `/dev/ttyACM0` for the first connected development kit, and `/dev/ttyACM1` for the second one.
+5. Start the ot-cli host application and connect with the RCP. It is assumed that the default UART version of RCP is being used (make executed without the NCP-SPI=1 flag). On Linux system, call a port name, for example `/dev/ttyACM0` for the first connected development kit, and `/dev/ttyACM1` for the second one.
 
    ```bash
    $ /usr/bin/ot-cli /dev/ttyACM0 115200
@@ -185,20 +178,19 @@
 
    b. Connect to the used COM port with the following direct UART settings:
 
-   * Baud rate: 115200
-   * 8 data bits
-   * 1 stop bit
-   * No parity
-   * HW flow control: RTS/CTS
-     This allows you to view the raw UART output.
+   - Baud rate: 115200
+   - 8 data bits
+   - 1 stop bit
+   - No parity
+   - HW flow control: RTS/CTS This allows you to view the raw UART output.
 
    c. Run the following command to connect to the second board.
 
-      ```shell
-      screen /dev/ttyACM1 115200
-      ```
+   ```shell
+   screen /dev/ttyACM1 115200
+   ```
 
-      You are now connected with the CLI on the second board
+   You are now connected with the CLI on the second board
 
 8. Use the following commands to attach to the network on the second board:
 
@@ -238,9 +230,9 @@
     16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
     ```
 
-For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
 
-[CLI]: ./../../../src/cli/README.md
+[cli]: ./../../../src/cli/README.md
 
 ## SEGGER J-Link tools
 
@@ -248,12 +240,12 @@
 
 ### Working with RTT logging
 
-By default, the OpenThread's logging module provides functions to output logging
-information over SEGGER's Real Time Transfer (RTT).
+By default, the OpenThread's logging module provides functions to output logging information over SEGGER's Real Time Transfer (RTT).
 
 You can set the desired log level by using the `OPENTHREAD_CONFIG_LOG_LEVEL` define.
 
 To enable the highest verbosity level, append `FULL_LOGS` flag to the `make` command:
+
 ```
 $ make -f examples/Makefile-nrf52811 FULL_LOGS=1
 ```
@@ -269,10 +261,13 @@
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52810_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID> -RTTTelnetPort 19021
 ```
+
 3. Run `JLinkRTTTelnet` to obtain the RTT logs from the connected device in a separate console. For example:
+
 ```
 JLinkRTTClient -RTTTelnetPort 19021
 ```
@@ -288,22 +283,28 @@
 3. From the Specify Target Device dropdown menu, select `NRF52810_XXAA`.
 4. From the Target Interface & Speed dropdown menu, select `SWD`.
 5. Run the following command:
+
 ```
 MSDDisable
 ```
+
 6. Power cycle the DK.
 
 #### Disabling the Mass Storage Device on Linux
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52810_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID>
 ```
+
 3. Run the following command:
+
 ```
 MSDDisable
 ```
+
 4. Power cycle the DK.
 
 ### Hardware Flow Control detection
@@ -321,39 +322,45 @@
 3. From the Specify Target Device dropdown menu, select `NRF52810_XXAA`.
 4. From the Target Interface & Speed dropdown menu, select `SWD`.
 5. Run the following command:
+
 ```
 SetHWFC Force
 ```
+
 6. Power cycle the DK.
 
 #### Disabling the HWFC detection on Linux
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52810_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID>
 ```
+
 3. Run the following command:
+
 ```
 SetHWFC Force
 ```
+
 4. Power cycle the DK.
 
-You can find more details [here][J-Link-OB].
+You can find more details [here][j-link-ob].
 
-[J-Link-OB]: https://wiki.segger.com/J-Link_OB_SAM3U_NordicSemi#Hardware_flow_control_support
+[j-link-ob]: https://wiki.segger.com/J-Link_OB_SAM3U_NordicSemi#Hardware_flow_control_support
 
 ## Diagnostic module
 
-nRF52811 supports [OpenThread Diagnostics Module][DIAG], with some additional features.
+nRF52811 supports [OpenThread Diagnostics Module][diag], with some additional features.
 
-For more information, see [nRF Diag command reference][nRFDIAG].
+For more information, see [nRF Diag command reference][nrfdiag].
 
-[DIAG]: ./../../../src/core/diags/README.md
-[nRFDIAG]: ./../DIAG.md
+[diag]: ./../../../src/core/diags/README.md
+[nrfdiag]: ./../DIAG.md
 
 ## Radio driver documentation
 
-The radio driver documentation includes *.uml state machines sequence diagrams that can be opened with [PlantUML][PlantUML-url].
+The radio driver documentation includes \*.uml state machines sequence diagrams that can be opened with [PlantUML][plantuml-url].
 
-[PlantUML-url]: http://plantuml.com/
+[plantuml-url]: http://plantuml.com/
diff --git a/examples/platforms/nrf528xx/nrf52811/openthread-core-nrf52811-config.h b/examples/platforms/nrf528xx/nrf52811/openthread-core-nrf52811-config.h
index 8494fd0..47854e8 100644
--- a/examples/platforms/nrf528xx/nrf52811/openthread-core-nrf52811-config.h
+++ b/examples/platforms/nrf528xx/nrf52811/openthread-core-nrf52811-config.h
@@ -111,33 +111,43 @@
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
  *
  * Define to 1 if you want to enable software ACK timeout logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 0
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
 #endif
 
 /**
@@ -151,53 +161,15 @@
 #endif
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of settings.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
  *
  */
-#ifndef SETTINGS_CONFIG_BASE_ADDRESS
-#define SETTINGS_CONFIG_BASE_ADDRESS 0
-#endif
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_PAGE_SIZE
-#define SETTINGS_CONFIG_PAGE_SIZE 4096
-#endif
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_PAGE_NUM
-#define SETTINGS_CONFIG_PAGE_NUM 2
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE
- *
- * The size of heap buffer when DTLS is enabled.
- *
- */
-#ifndef OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE
-#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE (4096 * sizeof(void *))
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE_NO_DTLS
- *
- * The size of heap buffer when DTLS is disabled.
- *
- */
-#ifndef OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE_NO_DTLS
-#define OPENTHREAD_CONFIG_HEAP_INTERNAL_SIZE_NO_DTLS 2048
+#ifndef OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
 #endif
 
 /**
diff --git a/examples/platforms/nrf528xx/nrf52811/platform-config.h b/examples/platforms/nrf528xx/nrf52811/platform-config.h
index 40ad62f..e98954a 100644
--- a/examples/platforms/nrf528xx/nrf52811/platform-config.h
+++ b/examples/platforms/nrf528xx/nrf52811/platform-config.h
@@ -36,8 +36,8 @@
 #define PLATFORM_CONFIG_H_
 
 #include "nrf.h"
+#include "nrf_drv_clock.h"
 #include "nrf_peripherals.h"
-#include "drivers/clock/nrf_drv_clock.h"
 #include "hal/nrf_radio.h"
 #include "hal/nrf_uart.h"
 
@@ -45,142 +45,6 @@
 #include <openthread/config.h>
 
 /*******************************************************************************
- * @section UART Driver Configuration.
- ******************************************************************************/
-
-/**
- * @def UART_INSTANCE
- *
- * UART Instance.
- *
- */
-#ifndef UART_INSTANCE
-#define UART_INSTANCE NRF_UART0
-#endif
-
-/**
- * @def UART_PARITY
- *
- * UART Parity configuration.
- *
- * @brief Possible values:
- *         \ref NRF_UART_PARITY_EXCLUDED - Parity bit is not present.
- *         \ref NRF_UART_PARITY_INCLUDED - Parity bit is present.
- *
- */
-#ifndef UART_PARITY
-#define UART_PARITY NRF_UART_PARITY_EXCLUDED
-#endif
-
-/**
- * @def UART_HWFC_ENABLED
- *
- * Enable UART Hardware Flow Control.
- *
- */
-#ifndef UART_HWFC_ENABLED
-#define UART_HWFC_ENABLED 1
-#endif
-
-/**
- * @def UART_BAUDRATE
- *
- * UART Baudrate.
- *
- * @brief Possible values:
- *         \ref NRF_UART_BAUDRATE_1200 - 1200 baud.
- *         \ref NRF_UART_BAUDRATE_2400 - 2400 baud.
- *         \ref NRF_UART_BAUDRATE_4800 - 4800 baud.
- *         \ref NRF_UART_BAUDRATE_9600 - 9600 baud.
- *         \ref NRF_UART_BAUDRATE_14400 - 14400 baud.
- *         \ref NRF_UART_BAUDRATE_19200 - 19200 baud.
- *         \ref NRF_UART_BAUDRATE_28800 - 28800 baud.
- *         \ref NRF_UART_BAUDRATE_38400 - 38400 baud.
- *         \ref NRF_UART_BAUDRATE_57600 - 57600 baud.
- *         \ref NRF_UART_BAUDRATE_76800 - 76800 baud.
- *         \ref NRF_UART_BAUDRATE_115200 - 115200 baud.
- *         \ref NRF_UART_BAUDRATE_230400 - 230400 baud.
- *         \ref NRF_UART_BAUDRATE_250000 - 250000 baud.
- *         \ref NRF_UART_BAUDRATE_460800 - 460800 baud.
- *         \ref NRF_UART_BAUDRATE_921600 - 921600 baud.
- *         \ref NRF_UART_BAUDRATE_1000000 - 1000000 baud.
- *
- */
-#ifndef UART_BAUDRATE
-#define UART_BAUDRATE NRF_UART_BAUDRATE_115200
-#endif
-
-/**
- *  @def UART_IRQN
- *
- * UART Interrupt number.
- *
- */
-#ifndef UART_IRQN
-#define UART_IRQN UARTE0_UART0_IRQn
-#endif
-
-/**
- * @def UART_IRQ_PRIORITY
- *
- * UART Interrupt priority.
- *
- */
-#ifndef UART_IRQ_PRIORITY
-#define UART_IRQ_PRIORITY 6
-#endif
-
-/**
- * @def UART_RX_BUFFER_SIZE
- *
- * UART Receive buffer size.
- *
- */
-#ifndef UART_RX_BUFFER_SIZE
-#define UART_RX_BUFFER_SIZE 256
-#endif
-
-/**
- * @def UART_PIN_TX
- *
- * UART TX Pin.
- *
- */
-#ifndef UART_PIN_TX
-#define UART_PIN_TX 6
-#endif
-
-/**
- * @def UART_PIN_RX
- *
- * UART RX Pin.
- *
- */
-#ifndef UART_PIN_RX
-#define UART_PIN_RX 8
-#endif
-
-/**
- * @def UART_PIN_CTS
- *
- * UART CTS Pin.
- *
- */
-#ifndef UART_PIN_CTS
-#define UART_PIN_CTS 7
-#endif
-
-/**
- * @def UART_PIN_RTS
- *
- * UART RTS Pin.
- *
- */
-#ifndef UART_PIN_RTS
-#define UART_PIN_RTS 5
-#endif
-
-/*******************************************************************************
  * @section Alarm Driver Configuration.
  ******************************************************************************/
 
@@ -249,80 +113,19 @@
 #endif
 
 /*******************************************************************************
- * @section SPI Slave configuration.
+ * @section Platform Flash Configuration
  ******************************************************************************/
 
 /**
- * @def SPIS Instance.
- */
-#ifndef SPIS_INSTANCE
-#define SPIS_INSTANCE 0
-#endif
-
-/**
- * @def SPIS mode.
+ * @def PLATFORM_FLASH_PAGE_NUM
  *
- * @brief Possible values:
- *         \ref NRF_SPIS_MODE_0 - SCK active high, sample on leading edge of clock.
- *         \ref NRF_SPIS_MODE_1 - SCK active high, sample on trailing edge of clock.
- *         \ref NRF_SPIS_MODE_2 - SCK active low, sample on leading edge of clock.
- *         \ref NRF_SPIS_MODE_3 - SCK active low, sample on trailing edge of clock.
- */
-#ifndef SPIS_MODE
-#define SPIS_MODE NRF_SPIS_MODE_0
-#endif
-
-/**
- * @def SPIS bit orders.
+ * Number of flash pages to use for OpenThread's non-volatile settings.
  *
- * @brief Possible values:
- *         \ref NRF_SPIS_BIT_ORDER_MSB_FIRST - Most significant bit shifted out first.
- *         \ref NRF_SPIS_BIT_ORDER_LSB_FIRST - Least significant bit shifted out first.
+ * @note This define applies only for MDK-ARM Keil toolchain configuration.
+ *
  */
-#ifndef SPIS_BIT_ORDER
-#define SPIS_BIT_ORDER NRF_SPIS_BIT_ORDER_MSB_FIRST
-#endif
-
-/**
- * @def SPIS Interrupt priority.
- */
-#ifndef SPIS_IRQ_PRIORITY
-#define SPIS_IRQ_PRIORITY 6
-#endif
-
-/**
- * @def SPIS MOSI Pin.
- */
-#ifndef SPIS_PIN_MOSI
-#define SPIS_PIN_MOSI 4
-#endif
-
-/**
- * @def SPIS MISO Pin.
- */
-#ifndef SPIS_PIN_MISO
-#define SPIS_PIN_MISO 28
-#endif
-
-/**
- * @def SPIS SCK Pin.
- */
-#ifndef SPIS_PIN_SCK
-#define SPIS_PIN_SCK 3
-#endif
-
-/**
- * @def SPIS CSN Pin.
- */
-#ifndef SPIS_PIN_CSN
-#define SPIS_PIN_CSN 29
-#endif
-
-/**
- * @def SPIS Host IRQ Pin.
- */
-#ifndef SPIS_PIN_HOST_IRQ
-#define SPIS_PIN_HOST_IRQ 30
+#ifndef PLATFORM_FLASH_PAGE_NUM
+#define PLATFORM_FLASH_PAGE_NUM 2
 #endif
 
 /*******************************************************************************
diff --git a/examples/platforms/nrf528xx/nrf52811/transport-config.h b/examples/platforms/nrf528xx/nrf52811/transport-config.h
new file mode 100644
index 0000000..9a9a5be
--- /dev/null
+++ b/examples/platforms/nrf528xx/nrf52811/transport-config.h
@@ -0,0 +1,260 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes the transport-specific configuration.
+ *
+ */
+
+#ifndef TRANSPORT_CONFIG_H_
+#define TRANSPORT_CONFIG_H_
+
+#include "nrf.h"
+#include "nrf_drv_clock.h"
+#include "nrf_peripherals.h"
+#include "hal/nrf_radio.h"
+#include "hal/nrf_uart.h"
+
+#include "openthread-core-config.h"
+#include <openthread/config.h>
+
+/*******************************************************************************
+ * @section UART Driver Configuration.
+ ******************************************************************************/
+
+/**
+ * @def UART_INSTANCE
+ *
+ * UART Instance.
+ *
+ */
+#ifndef UART_INSTANCE
+#define UART_INSTANCE NRF_UART0
+#endif
+
+/**
+ * @def UART_PARITY
+ *
+ * UART Parity configuration.
+ *
+ * @brief Possible values:
+ *         \ref NRF_UART_PARITY_EXCLUDED - Parity bit is not present.
+ *         \ref NRF_UART_PARITY_INCLUDED - Parity bit is present.
+ *
+ */
+#ifndef UART_PARITY
+#define UART_PARITY NRF_UART_PARITY_EXCLUDED
+#endif
+
+/**
+ * @def UART_HWFC_ENABLED
+ *
+ * Enable UART Hardware Flow Control.
+ *
+ */
+#ifndef UART_HWFC_ENABLED
+#define UART_HWFC_ENABLED 1
+#endif
+
+/**
+ * @def UART_BAUDRATE
+ *
+ * UART Baudrate.
+ *
+ * @brief Possible values:
+ *         \ref NRF_UART_BAUDRATE_1200 - 1200 baud.
+ *         \ref NRF_UART_BAUDRATE_2400 - 2400 baud.
+ *         \ref NRF_UART_BAUDRATE_4800 - 4800 baud.
+ *         \ref NRF_UART_BAUDRATE_9600 - 9600 baud.
+ *         \ref NRF_UART_BAUDRATE_14400 - 14400 baud.
+ *         \ref NRF_UART_BAUDRATE_19200 - 19200 baud.
+ *         \ref NRF_UART_BAUDRATE_28800 - 28800 baud.
+ *         \ref NRF_UART_BAUDRATE_38400 - 38400 baud.
+ *         \ref NRF_UART_BAUDRATE_57600 - 57600 baud.
+ *         \ref NRF_UART_BAUDRATE_76800 - 76800 baud.
+ *         \ref NRF_UART_BAUDRATE_115200 - 115200 baud.
+ *         \ref NRF_UART_BAUDRATE_230400 - 230400 baud.
+ *         \ref NRF_UART_BAUDRATE_250000 - 250000 baud.
+ *         \ref NRF_UART_BAUDRATE_460800 - 460800 baud.
+ *         \ref NRF_UART_BAUDRATE_921600 - 921600 baud.
+ *         \ref NRF_UART_BAUDRATE_1000000 - 1000000 baud.
+ *
+ */
+#ifndef UART_BAUDRATE
+#define UART_BAUDRATE NRF_UART_BAUDRATE_115200
+#endif
+
+/**
+ *  @def UART_IRQN
+ *
+ * UART Interrupt number.
+ *
+ */
+#ifndef UART_IRQN
+#define UART_IRQN UARTE0_UART0_IRQn
+#endif
+
+/**
+ * @def UART_IRQ_PRIORITY
+ *
+ * UART Interrupt priority.
+ *
+ */
+#ifndef UART_IRQ_PRIORITY
+#define UART_IRQ_PRIORITY 6
+#endif
+
+/**
+ * @def UART_RX_BUFFER_SIZE
+ *
+ * UART Receive buffer size.
+ *
+ */
+#ifndef UART_RX_BUFFER_SIZE
+#define UART_RX_BUFFER_SIZE 256
+#endif
+
+/**
+ * @def UART_PIN_TX
+ *
+ * UART TX Pin.
+ *
+ */
+#ifndef UART_PIN_TX
+#define UART_PIN_TX 6
+#endif
+
+/**
+ * @def UART_PIN_RX
+ *
+ * UART RX Pin.
+ *
+ */
+#ifndef UART_PIN_RX
+#define UART_PIN_RX 8
+#endif
+
+/**
+ * @def UART_PIN_CTS
+ *
+ * UART CTS Pin.
+ *
+ */
+#ifndef UART_PIN_CTS
+#define UART_PIN_CTS 7
+#endif
+
+/**
+ * @def UART_PIN_RTS
+ *
+ * UART RTS Pin.
+ *
+ */
+#ifndef UART_PIN_RTS
+#define UART_PIN_RTS 5
+#endif
+
+/*******************************************************************************
+ * @section SPI Slave configuration.
+ ******************************************************************************/
+
+/**
+ * @def SPIS Instance.
+ */
+#ifndef SPIS_INSTANCE
+#define SPIS_INSTANCE 0
+#endif
+
+/**
+ * @def SPIS mode.
+ *
+ * @brief Possible values:
+ *         \ref NRF_SPIS_MODE_0 - SCK active high, sample on leading edge of clock.
+ *         \ref NRF_SPIS_MODE_1 - SCK active high, sample on trailing edge of clock.
+ *         \ref NRF_SPIS_MODE_2 - SCK active low, sample on leading edge of clock.
+ *         \ref NRF_SPIS_MODE_3 - SCK active low, sample on trailing edge of clock.
+ */
+#ifndef SPIS_MODE
+#define SPIS_MODE NRF_SPIS_MODE_0
+#endif
+
+/**
+ * @def SPIS bit orders.
+ *
+ * @brief Possible values:
+ *         \ref NRF_SPIS_BIT_ORDER_MSB_FIRST - Most significant bit shifted out first.
+ *         \ref NRF_SPIS_BIT_ORDER_LSB_FIRST - Least significant bit shifted out first.
+ */
+#ifndef SPIS_BIT_ORDER
+#define SPIS_BIT_ORDER NRF_SPIS_BIT_ORDER_MSB_FIRST
+#endif
+
+/**
+ * @def SPIS Interrupt priority.
+ */
+#ifndef SPIS_IRQ_PRIORITY
+#define SPIS_IRQ_PRIORITY 6
+#endif
+
+/**
+ * @def SPIS MOSI Pin.
+ */
+#ifndef SPIS_PIN_MOSI
+#define SPIS_PIN_MOSI 4
+#endif
+
+/**
+ * @def SPIS MISO Pin.
+ */
+#ifndef SPIS_PIN_MISO
+#define SPIS_PIN_MISO 28
+#endif
+
+/**
+ * @def SPIS SCK Pin.
+ */
+#ifndef SPIS_PIN_SCK
+#define SPIS_PIN_SCK 3
+#endif
+
+/**
+ * @def SPIS CSN Pin.
+ */
+#ifndef SPIS_PIN_CSN
+#define SPIS_PIN_CSN 29
+#endif
+
+/**
+ * @def SPIS Host IRQ Pin.
+ */
+#ifndef SPIS_PIN_HOST_IRQ
+#define SPIS_PIN_HOST_IRQ 30
+#endif
+
+#endif // TRANSPORT_CONFIG_H_
diff --git a/examples/platforms/nrf528xx/nrf52833/Makefile.am b/examples/platforms/nrf528xx/nrf52833/Makefile.am
index ee34bdb..eb59eb5 100644
--- a/examples/platforms/nrf528xx/nrf52833/Makefile.am
+++ b/examples/platforms/nrf528xx/nrf52833/Makefile.am
@@ -32,6 +32,7 @@
     libopenthread-nrf52833.a                                                                                 \
     libopenthread-nrf52833-sdk.a                                                                             \
     libopenthread-nrf52833-softdevice-sdk.a                                                                  \
+    libopenthread-nrf52833-transport.a                                                                       \
     $(NULL)
 
 # Do not enable -pedantic-errors for nRF52833 driver library
@@ -42,26 +43,50 @@
 override CFLAGS                                      := $(filter-out -Wundef,$(CFLAGS))
 override CXXFLAGS                                    := $(filter-out -Wundef,$(CXXFLAGS))
 
+# Do not enable -Wcast-align for nRF52833 driver library
+override CFLAGS                                      := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                                    := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 COMMONCPPFLAGS                                                                                             = \
     -DCONFIG_GPIO_AS_PINRESET                                                                                \
     -DNRF52833_XXAA                                                                                          \
+    -DUSE_APP_CONFIG=1                                                                                       \
     -I$(srcdir)                                                                                              \
     -I$(top_srcdir)/include                                                                                  \
     -I$(top_srcdir)/examples/platforms                                                                       \
     -I$(top_srcdir)/examples/platforms/nrf528xx/src                                                          \
+    -I$(top_srcdir)/examples/platforms/nrf528xx/src/transport                                                \
     -I$(top_srcdir)/src/core                                                                                 \
-    -I$(top_srcdir)/third_party/NordicSemiconductor                                                          \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                    \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                             \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock                                            \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common                                           \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio                                            \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/three_pin_gpio                         \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal                                        \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features                               \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator                 \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch                                       \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal                                  \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice                       \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer                          \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/temperature                       \
+    -Wno-unused-parameter                                                                                    \
+    $(NULL)
+
+# Only reference the SDK header files included in third_party/NordicSemiconductor
+# when building the example applications.
+#
+# When building just the platform libraries, the caller of configure is expected
+# to provide the correct -I arguments to locate the necessary header files in an
+# external copy of the Nordic nRF5 SDK.
+#
+# Note that an exception is made for the 802.15.4 radio driver, which is always
+# built using the sources in third_party/NordicSemiconductor/drivers/radio.
+if OPENTHREAD_ENABLE_EXAMPLES
+COMMONCPPFLAGS                                                                                            += \
+    -I$(top_srcdir)/third_party/NordicSemiconductor                                                          \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                    \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config                                                   \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52833/config                                   \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                             \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock                                            \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common                                           \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power                                            \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick                                          \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd                                             \
@@ -83,7 +108,9 @@
     -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/soc                                                 \
     -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers                                  \
     -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf52                            \
+    -Wno-unused-parameter                                                                                    \
     $(NULL)
+endif
 
 PLATFORM_COMMON_SOURCES                                                                                    = \
     src/alarm.c                                                                                              \
@@ -94,11 +121,15 @@
     src/logging.c                                                                                            \
     src/misc.c                                                                                               \
     src/radio.c                                                                                              \
-    src/temp.c                                                                                               \
-    src/spi-slave.c                                                                                          \
     src/system.c                                                                                             \
-    src/uart.c                                                                                               \
-    src/usb-cdc-uart.c                                                                                       \
+    src/temp.c                                                                                               \
+    $(NULL)
+
+TRANSPORT_SOURCES                                                                                          = \
+    src/transport/spi-slave.c                                                                                \
+    src/transport/uart.c                                                                                     \
+    src/transport/usb-cdc-uart.c                                                                             \
+    src/transport/transport.c                                                                                \
     $(NULL)
 
 SINGLEPHY_SOURCES                                                                                          = \
@@ -111,8 +142,6 @@
     $(NULL)
 
 SOFTDEVICE_CPPFLAGS                                                                                        = \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice                       \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers                                  \
     -DSOFTDEVICE_PRESENT                                                                                     \
     -DS140                                                                                                   \
     $(NULL)
@@ -151,6 +180,14 @@
     $(SOFTDEVICE_SOURCES)                                                                                    \
     $(NULL)
 
+libopenthread_nrf52833_transport_a_CPPFLAGS                                                                = \
+    $(COMMONCPPFLAGS)                                                                                        \
+    $(NULL)
+
+libopenthread_nrf52833_transport_a_SOURCES                                                                 = \
+    $(TRANSPORT_SOURCES)                                                                                     \
+    $(NULL)
+
 Dash                                                                                                       = -
 
 libopenthread_nrf52833_a_LIBADD                                                                            = \
@@ -163,4 +200,7 @@
 libopenthread_nrf52833_softdevice_sdk_a_LIBADD                                                             = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
 
+libopenthread_nrf52833_transport_a_LIBADD                                                                  = \
+    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
+
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/nrf528xx/nrf52833/Makefile.platform.am b/examples/platforms/nrf528xx/nrf52833/Makefile.platform.am
index ab0fc8d..1412d57 100644
--- a/examples/platforms/nrf528xx/nrf52833/Makefile.platform.am
+++ b/examples/platforms/nrf528xx/nrf52833/Makefile.platform.am
@@ -32,6 +32,7 @@
 
 LDADD_COMMON                                                                                 += \
     $(top_builddir)/examples/platforms/nrf528xx/libopenthread-nrf52833.a                        \
+    $(top_builddir)/examples/platforms/nrf528xx/libopenthread-nrf52833-transport.a              \
     $(top_builddir)/third_party/NordicSemiconductor/libnordicsemi-nrf52833-sdk.a                \
     $(top_builddir)/third_party/NordicSemiconductor/libnordicsemi-nrf52833-radio-driver.a       \
     $(NULL)
diff --git a/examples/platforms/nrf528xx/nrf52833/README.md b/examples/platforms/nrf528xx/nrf52833/README.md
index bd6bdd8..dbdb731 100644
--- a/examples/platforms/nrf528xx/nrf52833/README.md
+++ b/examples/platforms/nrf528xx/nrf52833/README.md
@@ -1,11 +1,11 @@
 # OpenThread on nRF52833 Example
 
-This directory contains example platform drivers for [Nordic Semiconductor nRF52833 SoC][nRF52833].
+This directory contains example platform drivers for [Nordic Semiconductor nRF52833 SoC][nrf52833].
 
-To facilitate Thread products development with the nRF52833 platform, Nordic Semiconductor provides <i>nRF5 SDK for Thread and Zigbee</i>. See [Nordic Semiconductor's nRF5 SDK for Thread and Zigbee][nRF5-SDK-section] section for more details.
+To facilitate Thread products development with the nRF52833 platform, Nordic Semiconductor provides <i>nRF5 SDK for Thread and Zigbee</i>. See [Nordic Semiconductor's nRF5 SDK for Thread and Zigbee][nrf5-sdk-section] section for more details.
 
-[nRF52833]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52833
-[nRF5-SDK-section]: #nordic-semiconductors-nrf5-sdk-for-thread-and-zigbee
+[nrf52833]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52833
+[nrf5-sdk-section]: #nordic-semiconductors-nrf5-sdk-for-thread-and-zigbee
 
 ## Prerequisites
 
@@ -26,13 +26,13 @@
 
 ### Flashing and debugging tools
 
-[nRF5-Command-Line-Tools]: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF5-Command-Line-Tools
+[nrf5-command-line-tools]: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF5-Command-Line-Tools
 
-Install the [nRF5 Command Line Tools][nRF5-Command-Line-Tools] to flash, debug, and make use of logging features on the nRF52833 DK with SEGGER J-Link.
+Install the [nRF5 Command Line Tools][nrf5-command-line-tools] to flash, debug, and make use of logging features on the nRF52833 DK with SEGGER J-Link.
 
 ## Building the examples
 
- To build the examples, run the following command in Bash:
+To build the examples, run the following command in Bash:
 
 ```bash
 $ cd <path-to-openthread>
@@ -40,60 +40,57 @@
 $ make -f examples/Makefile-nrf52833
 ```
 
-After a successful build, the `elf` files can be found in
-`<path-to-openthread>/output/nrf52833/bin`.
-You can convert them to hex using `arm-none-eabi-objcopy`:
+After a successful build, the `elf` files can be found in `<path-to-openthread>/output/nrf52833/bin`. You can convert them to hex using `arm-none-eabi-objcopy`:
+
 ```bash
 $ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex
 ```
 
 ### USB CDC ACM support
 
-You can build the libraries with support for the native USB CDC ACM as a serial transport.
-To do so, build the firmware with the following parameter:
+You can build the libraries with support for the native USB CDC ACM as a serial transport. To do so, build the firmware with the following parameter:
+
 ```
 $ make -f examples/Makefile-nrf52833 USB=1
 ```
 
 Note that the USB CDC ACM serial transport is not supported with Engineering sample A of the nRF52833 chip.
 
-If you are using Windows 7 or earlier, you must load an additional USB CDC driver.
-The driver can be found in `third_party/NordicSemiconductor/libraries/usb/nordic_cdc_acm_example.inf`.
+If you are using Windows 7 or earlier, you must load an additional USB CDC driver. The driver can be found in `third_party/NordicSemiconductor/libraries/usb/nordic_cdc_acm_example.inf`.
 
 ### Bootloader support
 
 The examples support the following bootloaders for performing a Device Firmware Upgrade (DFU):
-* USB bootloader
-* UART bootloader
-* BLE bootloader
+
+- USB bootloader
+- UART bootloader
+- BLE bootloader
 
 The support for a particular bootloader can be enabled with the following switches:
-* USB: `BOOTLOADER=USB`
-* UART: `BOOTLOADER=UART`
-* BLE: `BOOTLOADER=BLE`
+
+- USB: `BOOTLOADER=USB`
+- UART: `BOOTLOADER=UART`
+- BLE: `BOOTLOADER=BLE`
 
 ### Native SPI support
 
-You can build the libraries with support for native SPI Slave.
-To build the libraries, run make with the following parameter:
+You can build the libraries with support for native SPI Slave. To build the libraries, run make with the following parameter:
 
 ```
 $ make -f examples/Makefile-nrf52833 NCP_SPI=1
 ```
 
-With this option enabled, SPI communication between the NCP example and wpantund is possible
-(provided that the wpantund host supports SPI Master). To achieve that, an appropriate SPI device
-should be chosen in wpantund configuration file, `/etc/wpantund.conf`. You can find an example below.
+With this option enabled, SPI communication between the NCP example and wpantund is possible (provided that the wpantund host supports SPI Master). To achieve that, an appropriate SPI device should be chosen in wpantund configuration file, `/etc/wpantund.conf`. You can find an example below.
+
 ```
 Config:NCP:SocketPath "system:/usr/bin/spi-hdlc-adapter --gpio-int /sys/class/gpio/gpio25 /dev/spidev0.0"
 ```
 
 In this example, [spi-hdlc-adapter][spi-hdlc-adapter] is a tool that you can use to communicate between NCP and wpantund over SPI. For this example, `spi-hdlc-adapter` is installed in `/usr/bin`.
 
-The default SPI Slave pin configuration for nRF52833 is defined in `examples/platforms/nrf52833/platform-config.h`.
+The default SPI Slave pin configuration for nRF52833 is defined in `examples/platforms/nrf52833/transport-config.h`.
 
-Note that the native SPI Slave support is not intended to be used with Engineering sample A of the nRF52833 chip due to
-single transfer size limitation.
+Note that the native SPI Slave support is not intended to be used with Engineering sample A of the nRF52833 chip due to single transfer size limitation.
 
 [spi-hdlc-adapter]: https://github.com/openthread/openthread/tree/master/tools/spi-hdlc-adapter
 
@@ -106,7 +103,9 @@
 ```
 $ make -f examples/Makefile-nrf52833 USB=1 CCPREFIX=ccache
 ```
+
 ### Optional mbedTLS threading support
+
 By default, mbedTLS library is built without support for multiple threads. You can enable this built-in support by building OpenThread with the following parameter:
 
 ```
@@ -134,8 +133,9 @@
 When the Thread device is configured to obtain the Thread Network security credentials with either Thread Commissioning or an out-of-band method, the extended MAC address should be constructed out of the globally unique IEEE EUI-64.
 
 The IEEE EUI-64 address consists of two parts:
- - 24 bits of MA-L (MAC Address Block Large), formerly called OUI (Organizationally Unique Identifier)
- - 40-bit device unique identifier
+
+- 24 bits of MA-L (MAC Address Block Large), formerly called OUI (Organizationally Unique Identifier)
+- 40-bit device unique identifier
 
 By default, the device uses Nordic Semiconductor's MA-L (f4-ce-36). You can modify it by overwriting the `OPENTHREAD_CONFIG_STACK_VENDOR_OUI` define, located in the `openthread-core-nrf52833-config.h` file. This value must be publicly registered by the IEEE Registration Authority.
 
@@ -145,8 +145,7 @@
 
 ## Flashing the binaries
 
-Flash the compiled binaries onto nRF52833 using `nrfjprog` which is
-part of the [nRF5 Command Line Tools][nRF5-Command-Line-Tools].
+Flash the compiled binaries onto nRF52833 using `nrfjprog` which is part of the [nRF5 Command Line Tools][nrf5-command-line-tools].
 
 ```bash
 $ nrfjprog -f nrf52 --chiperase --program output/nrf52833/bin/ot-cli-ftd.hex --reset
@@ -164,12 +163,11 @@
 
    b. Connect to the used COM port with the following direct UART settings:
 
-   * Baud rate: 115200
-   * 8 data bits
-   * 1 stop bit
-   * No parity
-   * HW flow control: RTS/CTS
-     This allows you to view the raw UART output.
+   - Baud rate: 115200
+   - 8 data bits
+   - 1 stop bit
+   - No parity
+   - HW flow control: RTS/CTS This allows you to view the raw UART output.
 
      On Linux system a port name should be called e.g. `/dev/ttyACM0` or `/dev/ttyACM1`.
 
@@ -251,9 +249,9 @@
    16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
    ```
 
-For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
 
-[CLI]: ./../../../src/cli/README.md
+[cli]: ./../../../src/cli/README.md
 
 ## SEGGER J-Link tools
 
@@ -261,12 +259,12 @@
 
 ### Working with RTT logging
 
-By default, the OpenThread's logging module provides functions to output logging
-information over SEGGER's Real Time Transfer (RTT).
+By default, the OpenThread's logging module provides functions to output logging information over SEGGER's Real Time Transfer (RTT).
 
 You can set the desired log level by using the `OPENTHREAD_CONFIG_LOG_LEVEL` define.
 
 To enable the highest verbosity level, append `FULL_LOGS` flag to the `make` command:
+
 ```
 $ make -f examples/Makefile-nrf52833 FULL_LOGS=1
 ```
@@ -282,10 +280,13 @@
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52833_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID> -RTTTelnetPort 19021
 ```
+
 3. Run `JLinkRTTTelnet` to obtain the RTT logs from the connected device in a separate console. For example:
+
 ```
 JLinkRTTClient -RTTTelnetPort 19021
 ```
@@ -301,22 +302,28 @@
 3. From the Specify Target Device dropdown menu, select `NRF52833_XXAA`.
 4. From the Target Interface & Speed dropdown menu, select `SWD`.
 5. Run the following command:
+
 ```
 MSDDisable
 ```
+
 6. Power cycle the DK.
 
 #### Disabling the Mass Storage Device on Linux
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52833_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID>
 ```
+
 3. Run the following command:
+
 ```
 MSDDisable
 ```
+
 4. Power cycle the DK.
 
 ### Hardware Flow Control detection
@@ -334,61 +341,67 @@
 3. From the Specify Target Device dropdown menu, select `NRF52833_XXAA`.
 4. From the Target Interface & Speed dropdown menu, select `SWD`.
 5. Run the following command:
+
 ```
 SetHWFC Force
 ```
+
 6. Power cycle the DK.
 
 #### Disabling the HWFC detection on Linux
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52833_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID>
 ```
+
 3. Run the following command:
+
 ```
 SetHWFC Force
 ```
+
 4. Power cycle the DK.
 
-You can find more details [here][J-Link-OB].
+You can find more details [here][j-link-ob].
 
-[J-Link-OB]: https://wiki.segger.com/J-Link_OB_SAM3U_NordicSemi#Hardware_flow_control_support
+[j-link-ob]: https://wiki.segger.com/J-Link_OB_SAM3U_NordicSemi#Hardware_flow_control_support
 
 ## Diagnostic module
 
-nRF52833 port extends [OpenThread Diagnostics Module][DIAG].
+nRF52833 port extends [OpenThread Diagnostics Module][diag].
 
-You can read about all the features [here][nRFDIAG].
+You can read about all the features [here][nrfdiag].
 
-[DIAG]: ./../../../src/core/diags/README.md
-[nRFDIAG]: ./../DIAG.md
+[diag]: ./../../../src/core/diags/README.md
+[nrfdiag]: ./../DIAG.md
 
 ## Radio driver documentation
 
-The radio driver comes with documentation that describes the operation of state
-machines in this module. To open the `*.uml` sequence diagrams, use [PlantUML][PlantUML-url].
+The radio driver comes with documentation that describes the operation of state machines in this module. To open the `*.uml` sequence diagrams, use [PlantUML][plantuml-url].
 
-[PlantUML-url]: http://plantuml.com/
+[plantuml-url]: http://plantuml.com/
 
 # Nordic Semiconductor's nRF5 SDK for Thread and Zigbee
 
-Use [nRF5 Software Development Kit (SDK) for Thread and Zigbee][nRF5-SDK-Thread-Zigbee] when developing Thread products with Nordic Semiconductor's advanced nRF52840, nRF52833 or nRF52811 SoCs.
+Use [nRF5 Software Development Kit (SDK) for Thread and Zigbee][nrf5-sdk-thread-zigbee] when developing Thread products with Nordic Semiconductor's advanced nRF52840, nRF52833 or nRF52811 SoCs.
 
 The <i>nRF5 SDK for Thread and Zigbee</i> includes:
- - a pre-built OpenThread stack for the Nordic nRF52840, nRF52833 and nRF52811 SoCs,
- - support for hardware-accelerated cryptographic operations using ARM® CryptoCell-310,
- - unique Thread/Bluetooth Low Energy dynamic multiprotocol solution which allows for concurrent operation of Thread and Bluetooth Low Energy utilizing OpenThread and SoftDevice (Nordic’s Bluetooth Low Energy stack) with accompanying example applications,
- - Thread/Bluetooth Low Energy switched multiprotocol solution with accompanying example applications,
- - unique support for DFU-over-Thread (Device Firmware Upgrade),
- - examples to demonstrate interactions between nodes performing different Thread roles with the use of OpenThread and CoAP, CoAP Secure or MQTT-SN protocols,
- - support for OpenThread Network Co-Processor (NCP) and Radio Co-Processor (RCP) using UART, USB or SPI transport protocol,
- - Border Router and cloud connectivity example (e.g. with Google Cloud Platform),
- - Thread native commissioning with NFC example,
- - example applications demonstrating the use of FreeRTOS with OpenThread,
- - support for IAR, Keil MDK-ARM and SEGGER Embedded Studio (SES) IDEs for OpenThread stack and all example applications,
- - range of PC tools including Thread Topology Monitor and nRF Sniffer for 802.15.4,
- - software modules inherited from the nRF5 SDK e.g. peripheral drivers, NFC libraries, Bluetooth Low Energy libraries etc.
 
-[nRF5-SDK-Thread-Zigbee]: https://www.nordicsemi.com/Software-and-Tools/Software/nRF5-SDK-for-Thread-and-Zigbee
+- a pre-built OpenThread stack for the Nordic nRF52840, nRF52833 and nRF52811 SoCs,
+- support for hardware-accelerated cryptographic operations using ARM® CryptoCell-310,
+- unique Thread/Bluetooth Low Energy dynamic multiprotocol solution which allows for concurrent operation of Thread and Bluetooth Low Energy utilizing OpenThread and SoftDevice (Nordic’s Bluetooth Low Energy stack) with accompanying example applications,
+- Thread/Bluetooth Low Energy switched multiprotocol solution with accompanying example applications,
+- unique support for DFU-over-Thread (Device Firmware Upgrade),
+- examples to demonstrate interactions between nodes performing different Thread roles with the use of OpenThread and CoAP, CoAP Secure or MQTT-SN protocols,
+- support for OpenThread Network Co-Processor (NCP) and Radio Co-Processor (RCP) using UART, USB or SPI transport protocol,
+- Border Router and cloud connectivity example (e.g. with Google Cloud Platform),
+- Thread native commissioning with NFC example,
+- example applications demonstrating the use of FreeRTOS with OpenThread,
+- support for IAR, Keil MDK-ARM and SEGGER Embedded Studio (SES) IDEs for OpenThread stack and all example applications,
+- range of PC tools including Thread Topology Monitor and nRF Sniffer for 802.15.4,
+- software modules inherited from the nRF5 SDK e.g. peripheral drivers, NFC libraries, Bluetooth Low Energy libraries etc.
+
+[nrf5-sdk-thread-zigbee]: https://www.nordicsemi.com/Software-and-Tools/Software/nRF5-SDK-for-Thread-and-Zigbee
diff --git a/examples/platforms/nrf528xx/nrf52833/nrf52833.ld b/examples/platforms/nrf528xx/nrf52833/nrf52833.ld
index 88e85f7..5939881 100644
--- a/examples/platforms/nrf528xx/nrf52833/nrf52833.ld
+++ b/examples/platforms/nrf528xx/nrf52833/nrf52833.ld
@@ -45,7 +45,7 @@
 ENTRY(Reset_Handler)
 
 FLASH_PAGE_SIZE       = 4096;
-FLASH_DATA_PAGES_USED = 4;
+FLASH_DATA_PAGES_USED = 2;
 
 SECTIONS
 {
diff --git a/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_ble.ld b/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_ble.ld
index 0126016..c826fe0 100644
--- a/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_ble.ld
+++ b/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_ble.ld
@@ -45,7 +45,7 @@
 ENTRY(Reset_Handler)
 
 FLASH_PAGE_SIZE       = 4096;
-FLASH_DATA_PAGES_USED = 4;
+FLASH_DATA_PAGES_USED = 2;
 
 SECTIONS
 {
diff --git a/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_uart.ld b/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_uart.ld
index 44ef3a9..3c955fb 100644
--- a/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_uart.ld
+++ b/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_uart.ld
@@ -45,7 +45,7 @@
 ENTRY(Reset_Handler)
 
 FLASH_PAGE_SIZE       = 4096;
-FLASH_DATA_PAGES_USED = 4;
+FLASH_DATA_PAGES_USED = 2;
 
 SECTIONS
 {
diff --git a/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_usb.ld b/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_usb.ld
index dc4366c..3e60bcf 100644
--- a/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_usb.ld
+++ b/examples/platforms/nrf528xx/nrf52833/nrf52833_bootloader_usb.ld
@@ -45,7 +45,7 @@
 ENTRY(Reset_Handler)
 
 FLASH_PAGE_SIZE       = 4096;
-FLASH_DATA_PAGES_USED = 4;
+FLASH_DATA_PAGES_USED = 2;
 
 SECTIONS
 {
diff --git a/examples/platforms/nrf528xx/nrf52833/openthread-core-nrf52833-config.h b/examples/platforms/nrf528xx/nrf52833/openthread-core-nrf52833-config.h
index 29f4ce9..d61579d 100644
--- a/examples/platforms/nrf528xx/nrf52833/openthread-core-nrf52833-config.h
+++ b/examples/platforms/nrf528xx/nrf52833/openthread-core-nrf52833-config.h
@@ -133,33 +133,43 @@
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
  *
  * Define to 1 if you want to enable software ACK timeout logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 0
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
 #endif
 
 /**
@@ -173,33 +183,15 @@
 #endif
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of settings.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
  *
  */
-#ifndef SETTINGS_CONFIG_BASE_ADDRESS
-#define SETTINGS_CONFIG_BASE_ADDRESS 0
-#endif
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_PAGE_SIZE
-#define SETTINGS_CONFIG_PAGE_SIZE 4096
-#endif
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_PAGE_NUM
-#define SETTINGS_CONFIG_PAGE_NUM 4
+#ifndef OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
 #endif
 
 /**
diff --git a/examples/platforms/nrf528xx/nrf52833/platform-config.h b/examples/platforms/nrf528xx/nrf52833/platform-config.h
index 8dd54f4..e4b829d 100644
--- a/examples/platforms/nrf528xx/nrf52833/platform-config.h
+++ b/examples/platforms/nrf528xx/nrf52833/platform-config.h
@@ -36,151 +36,14 @@
 #define PLATFORM_CONFIG_H_
 
 #include "nrf.h"
+#include "nrf_drv_clock.h"
 #include "nrf_peripherals.h"
-#include "drivers/clock/nrf_drv_clock.h"
 #include "hal/nrf_radio.h"
-#include "hal/nrf_uart.h"
 
 #include "openthread-core-config.h"
 #include <openthread/config.h>
 
 /*******************************************************************************
- * @section UART Driver Configuration.
- ******************************************************************************/
-
-/**
- * @def UART_INSTANCE
- *
- * UART Instance.
- *
- */
-#ifndef UART_INSTANCE
-#define UART_INSTANCE NRF_UART0
-#endif
-
-/**
- * @def UART_PARITY
- *
- * UART Parity configuration.
- *
- * @brief Possible values:
- *         \ref NRF_UART_PARITY_EXCLUDED - Parity bit is not present.
- *         \ref NRF_UART_PARITY_INCLUDED - Parity bit is present.
- *
- */
-#ifndef UART_PARITY
-#define UART_PARITY NRF_UART_PARITY_EXCLUDED
-#endif
-
-/**
- * @def UART_HWFC_ENABLED
- *
- * Enable UART Hardware Flow Control.
- *
- */
-#ifndef UART_HWFC_ENABLED
-#define UART_HWFC_ENABLED 1
-#endif
-
-/**
- * @def UART_BAUDRATE
- *
- * UART Baudrate.
- *
- * @brief Possible values:
- *         \ref NRF_UART_BAUDRATE_1200 - 1200 baud.
- *         \ref NRF_UART_BAUDRATE_2400 - 2400 baud.
- *         \ref NRF_UART_BAUDRATE_4800 - 4800 baud.
- *         \ref NRF_UART_BAUDRATE_9600 - 9600 baud.
- *         \ref NRF_UART_BAUDRATE_14400 - 14400 baud.
- *         \ref NRF_UART_BAUDRATE_19200 - 19200 baud.
- *         \ref NRF_UART_BAUDRATE_28800 - 28800 baud.
- *         \ref NRF_UART_BAUDRATE_38400 - 38400 baud.
- *         \ref NRF_UART_BAUDRATE_57600 - 57600 baud.
- *         \ref NRF_UART_BAUDRATE_76800 - 76800 baud.
- *         \ref NRF_UART_BAUDRATE_115200 - 115200 baud.
- *         \ref NRF_UART_BAUDRATE_230400 - 230400 baud.
- *         \ref NRF_UART_BAUDRATE_250000 - 250000 baud.
- *         \ref NRF_UART_BAUDRATE_460800 - 460800 baud.
- *         \ref NRF_UART_BAUDRATE_921600 - 921600 baud.
- *         \ref NRF_UART_BAUDRATE_1000000 - 1000000 baud.
- *
- */
-#ifndef UART_BAUDRATE
-#define UART_BAUDRATE NRF_UART_BAUDRATE_115200
-#endif
-
-/**
- *  @def UART_IRQN
- *
- * UART Interrupt number.
- *
- */
-#ifndef UART_IRQN
-#define UART_IRQN UARTE0_UART0_IRQn
-#endif
-
-/**
- * @def UART_IRQ_PRIORITY
- *
- * UART Interrupt priority.
- *
- */
-#ifndef UART_IRQ_PRIORITY
-#define UART_IRQ_PRIORITY 6
-#endif
-
-/**
- * @def UART_RX_BUFFER_SIZE
- *
- * UART Receive buffer size.
- *
- */
-#ifndef UART_RX_BUFFER_SIZE
-#define UART_RX_BUFFER_SIZE 512
-#endif
-
-/**
- * @def UART_PIN_TX
- *
- * UART TX Pin.
- *
- */
-#ifndef UART_PIN_TX
-#define UART_PIN_TX 6
-#endif
-
-/**
- * @def UART_PIN_RX
- *
- * UART RX Pin.
- *
- */
-#ifndef UART_PIN_RX
-#define UART_PIN_RX 8
-#endif
-
-/**
- * @def UART_PIN_CTS
- *
- * UART CTS Pin.
- *
- */
-#ifndef UART_PIN_CTS
-#define UART_PIN_CTS 7
-#endif
-
-/**
- * @def UART_PIN_RTS
- *
- * UART RTS Pin.
- *
- */
-#ifndef UART_PIN_RTS
-#define UART_PIN_RTS 5
-#endif
-
-/*******************************************************************************
  * @section Alarm Driver Configuration.
  ******************************************************************************/
 
@@ -249,134 +112,19 @@
 #endif
 
 /*******************************************************************************
- * @section SPI Slave configuration.
+ * @section Platform Flash Configuration
  ******************************************************************************/
 
 /**
- * @def SPIS Instance.
- */
-#ifndef SPIS_INSTANCE
-#define SPIS_INSTANCE 0
-#endif
-
-/**
- * @def SPIS mode.
+ * @def PLATFORM_FLASH_PAGE_NUM
  *
- * @brief Possible values:
- *         \ref NRF_SPIS_MODE_0 - SCK active high, sample on leading edge of clock.
- *         \ref NRF_SPIS_MODE_1 - SCK active high, sample on trailing edge of clock.
- *         \ref NRF_SPIS_MODE_2 - SCK active low, sample on leading edge of clock.
- *         \ref NRF_SPIS_MODE_3 - SCK active low, sample on trailing edge of clock.
- */
-#ifndef SPIS_MODE
-#define SPIS_MODE NRF_SPIS_MODE_0
-#endif
-
-/**
- * @def SPIS bit orders.
+ * Number of flash pages to use for OpenThread's non-volatile settings.
  *
- * @brief Possible values:
- *         \ref NRF_SPIS_BIT_ORDER_MSB_FIRST - Most significant bit shifted out first.
- *         \ref NRF_SPIS_BIT_ORDER_LSB_FIRST - Least significant bit shifted out first.
- */
-#ifndef SPIS_BIT_ORDER
-#define SPIS_BIT_ORDER NRF_SPIS_BIT_ORDER_MSB_FIRST
-#endif
-
-/**
- * @def SPIS Interrupt priority.
- */
-#ifndef SPIS_IRQ_PRIORITY
-#define SPIS_IRQ_PRIORITY 6
-#endif
-
-/**
- * @def SPIS MOSI Pin.
- */
-#ifndef SPIS_PIN_MOSI
-#define SPIS_PIN_MOSI 4
-#endif
-
-/**
- * @def SPIS MISO Pin.
- */
-#ifndef SPIS_PIN_MISO
-#define SPIS_PIN_MISO 28
-#endif
-
-/**
- * @def SPIS SCK Pin.
- */
-#ifndef SPIS_PIN_SCK
-#define SPIS_PIN_SCK 3
-#endif
-
-/**
- * @def SPIS CSN Pin.
- */
-#ifndef SPIS_PIN_CSN
-#define SPIS_PIN_CSN 29
-#endif
-
-/**
- * @def SPIS Host IRQ Pin.
- */
-#ifndef SPIS_PIN_HOST_IRQ
-#define SPIS_PIN_HOST_IRQ 30
-#endif
-
-/*******************************************************************************
- * @section USB driver configuration.
- ******************************************************************************/
-
-/**
- * @def USB_HOST_UART_CONFIG_DELAY_MS
- *
- * Delay after DTR gets asserted that we start send any queued data. This allows slow
- * Linux-based hosts to have enough time to configure their port for raw mode.
+ * @note This define applies only for MDK-ARM Keil toolchain configuration.
  *
  */
-#ifndef USB_HOST_UART_CONFIG_DELAY_MS
-#define USB_HOST_UART_CONFIG_DELAY_MS 10
-#endif
-
-/**
- * @def USB_CDC_AS_SERIAL_TRANSPORT
- *
- * Use USB CDC driver for serial communication.
- */
-#ifndef USB_CDC_AS_SERIAL_TRANSPORT
-#define USB_CDC_AS_SERIAL_TRANSPORT 0
-#endif
-
-/**
- * @def The USB interface to use for CDC ACM COMM.
- *
- * According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
- * limitation. Takes values between 0-255.
- */
-#ifndef USB_CDC_ACM_COMM_INTERFACE
-#define USB_CDC_ACM_COMM_INTERFACE 1
-#endif
-
-/**
- * @def The USB interface to use for CDC ACM DATA.
- *
- * According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
- * limitation. Takes values between 0-255.
- */
-#ifndef USB_CDC_ACM_DATA_INTERFACE
-#define USB_CDC_ACM_DATA_INTERFACE 2
-#endif
-
-/**
- * @def OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
- *
- * Reset the application, not the chip, when a software reset is requested.
- * via `otPlatReset()`.
- */
-#ifndef OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
-#define OPENTHREAD_PLATFORM_USE_PSEUDO_RESET USB_CDC_AS_SERIAL_TRANSPORT
+#ifndef PLATFORM_FLASH_PAGE_NUM
+#define PLATFORM_FLASH_PAGE_NUM 2
 #endif
 
 /*******************************************************************************
diff --git a/examples/platforms/nrf528xx/nrf52833/transport-config.h b/examples/platforms/nrf528xx/nrf52833/transport-config.h
new file mode 100644
index 0000000..3e1b897
--- /dev/null
+++ b/examples/platforms/nrf528xx/nrf52833/transport-config.h
@@ -0,0 +1,309 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes the transport-specific configuration.
+ *
+ */
+
+#ifndef TRANSPORT_CONFIG_H_
+#define TRANSPORT_CONFIG_H_
+
+#include "nrf.h"
+#include "hal/nrf_spis.h"
+#include "hal/nrf_uart.h"
+
+/*******************************************************************************
+ * @section UART Driver Configuration.
+ ******************************************************************************/
+
+/**
+ * @def UART_INSTANCE
+ *
+ * UART Instance.
+ *
+ */
+#ifndef UART_INSTANCE
+#define UART_INSTANCE NRF_UART0
+#endif
+
+/**
+ * @def UART_PARITY
+ *
+ * UART Parity configuration.
+ *
+ * @brief Possible values:
+ *         \ref NRF_UART_PARITY_EXCLUDED - Parity bit is not present.
+ *         \ref NRF_UART_PARITY_INCLUDED - Parity bit is present.
+ *
+ */
+#ifndef UART_PARITY
+#define UART_PARITY NRF_UART_PARITY_EXCLUDED
+#endif
+
+/**
+ * @def UART_HWFC_ENABLED
+ *
+ * Enable UART Hardware Flow Control.
+ *
+ */
+#ifndef UART_HWFC_ENABLED
+#define UART_HWFC_ENABLED 1
+#endif
+
+/**
+ * @def UART_BAUDRATE
+ *
+ * UART Baudrate.
+ *
+ * @brief Possible values:
+ *         \ref NRF_UART_BAUDRATE_1200 - 1200 baud.
+ *         \ref NRF_UART_BAUDRATE_2400 - 2400 baud.
+ *         \ref NRF_UART_BAUDRATE_4800 - 4800 baud.
+ *         \ref NRF_UART_BAUDRATE_9600 - 9600 baud.
+ *         \ref NRF_UART_BAUDRATE_14400 - 14400 baud.
+ *         \ref NRF_UART_BAUDRATE_19200 - 19200 baud.
+ *         \ref NRF_UART_BAUDRATE_28800 - 28800 baud.
+ *         \ref NRF_UART_BAUDRATE_38400 - 38400 baud.
+ *         \ref NRF_UART_BAUDRATE_57600 - 57600 baud.
+ *         \ref NRF_UART_BAUDRATE_76800 - 76800 baud.
+ *         \ref NRF_UART_BAUDRATE_115200 - 115200 baud.
+ *         \ref NRF_UART_BAUDRATE_230400 - 230400 baud.
+ *         \ref NRF_UART_BAUDRATE_250000 - 250000 baud.
+ *         \ref NRF_UART_BAUDRATE_460800 - 460800 baud.
+ *         \ref NRF_UART_BAUDRATE_921600 - 921600 baud.
+ *         \ref NRF_UART_BAUDRATE_1000000 - 1000000 baud.
+ *
+ */
+#ifndef UART_BAUDRATE
+#define UART_BAUDRATE NRF_UART_BAUDRATE_115200
+#endif
+
+/**
+ *  @def UART_IRQN
+ *
+ * UART Interrupt number.
+ *
+ */
+#ifndef UART_IRQN
+#define UART_IRQN UARTE0_UART0_IRQn
+#endif
+
+/**
+ * @def UART_IRQ_PRIORITY
+ *
+ * UART Interrupt priority.
+ *
+ */
+#ifndef UART_IRQ_PRIORITY
+#define UART_IRQ_PRIORITY 6
+#endif
+
+/**
+ * @def UART_RX_BUFFER_SIZE
+ *
+ * UART Receive buffer size.
+ *
+ */
+#ifndef UART_RX_BUFFER_SIZE
+#define UART_RX_BUFFER_SIZE 512
+#endif
+
+/**
+ * @def UART_PIN_TX
+ *
+ * UART TX Pin.
+ *
+ */
+#ifndef UART_PIN_TX
+#define UART_PIN_TX 6
+#endif
+
+/**
+ * @def UART_PIN_RX
+ *
+ * UART RX Pin.
+ *
+ */
+#ifndef UART_PIN_RX
+#define UART_PIN_RX 8
+#endif
+
+/**
+ * @def UART_PIN_CTS
+ *
+ * UART CTS Pin.
+ *
+ */
+#ifndef UART_PIN_CTS
+#define UART_PIN_CTS 7
+#endif
+
+/**
+ * @def UART_PIN_RTS
+ *
+ * UART RTS Pin.
+ *
+ */
+#ifndef UART_PIN_RTS
+#define UART_PIN_RTS 5
+#endif
+
+/*******************************************************************************
+ * @section SPI Slave configuration.
+ ******************************************************************************/
+
+/**
+ * @def SPIS Instance.
+ */
+#ifndef SPIS_INSTANCE
+#define SPIS_INSTANCE 0
+#endif
+
+/**
+ * @def SPIS mode.
+ *
+ * @brief Possible values:
+ *         \ref NRF_SPIS_MODE_0 - SCK active high, sample on leading edge of clock.
+ *         \ref NRF_SPIS_MODE_1 - SCK active high, sample on trailing edge of clock.
+ *         \ref NRF_SPIS_MODE_2 - SCK active low, sample on leading edge of clock.
+ *         \ref NRF_SPIS_MODE_3 - SCK active low, sample on trailing edge of clock.
+ */
+#ifndef SPIS_MODE
+#define SPIS_MODE NRF_SPIS_MODE_0
+#endif
+
+/**
+ * @def SPIS bit orders.
+ *
+ * @brief Possible values:
+ *         \ref NRF_SPIS_BIT_ORDER_MSB_FIRST - Most significant bit shifted out first.
+ *         \ref NRF_SPIS_BIT_ORDER_LSB_FIRST - Least significant bit shifted out first.
+ */
+#ifndef SPIS_BIT_ORDER
+#define SPIS_BIT_ORDER NRF_SPIS_BIT_ORDER_MSB_FIRST
+#endif
+
+/**
+ * @def SPIS Interrupt priority.
+ */
+#ifndef SPIS_IRQ_PRIORITY
+#define SPIS_IRQ_PRIORITY 6
+#endif
+
+/**
+ * @def SPIS MOSI Pin.
+ */
+#ifndef SPIS_PIN_MOSI
+#define SPIS_PIN_MOSI 4
+#endif
+
+/**
+ * @def SPIS MISO Pin.
+ */
+#ifndef SPIS_PIN_MISO
+#define SPIS_PIN_MISO 28
+#endif
+
+/**
+ * @def SPIS SCK Pin.
+ */
+#ifndef SPIS_PIN_SCK
+#define SPIS_PIN_SCK 3
+#endif
+
+/**
+ * @def SPIS CSN Pin.
+ */
+#ifndef SPIS_PIN_CSN
+#define SPIS_PIN_CSN 29
+#endif
+
+/**
+ * @def SPIS Host IRQ Pin.
+ */
+#ifndef SPIS_PIN_HOST_IRQ
+#define SPIS_PIN_HOST_IRQ 30
+#endif
+
+/*******************************************************************************
+ * @section USB driver configuration.
+ ******************************************************************************/
+
+/**
+ * @def USB_HOST_UART_CONFIG_DELAY_MS
+ *
+ * Delay after DTR gets asserted that we start send any queued data. This allows slow
+ * Linux-based hosts to have enough time to configure their port for raw mode.
+ *
+ */
+#ifndef USB_HOST_UART_CONFIG_DELAY_MS
+#define USB_HOST_UART_CONFIG_DELAY_MS 10
+#endif
+
+/**
+ * @def USB_CDC_AS_SERIAL_TRANSPORT
+ *
+ * Use USB CDC driver for serial communication.
+ */
+#ifndef USB_CDC_AS_SERIAL_TRANSPORT
+#define USB_CDC_AS_SERIAL_TRANSPORT 0
+#endif
+
+/**
+ * @def The USB interface to use for CDC ACM COMM.
+ *
+ * According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
+ * limitation. Takes values between 0-255.
+ */
+#ifndef USB_CDC_ACM_COMM_INTERFACE
+#define USB_CDC_ACM_COMM_INTERFACE 1
+#endif
+
+/**
+ * @def The USB interface to use for CDC ACM DATA.
+ *
+ * According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
+ * limitation. Takes values between 0-255.
+ */
+#ifndef USB_CDC_ACM_DATA_INTERFACE
+#define USB_CDC_ACM_DATA_INTERFACE 2
+#endif
+
+/**
+ * @def OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+ *
+ * Reset the application, not the chip, when a software reset is requested.
+ * via `otPlatReset()`.
+ */
+#ifndef OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+#define OPENTHREAD_PLATFORM_USE_PSEUDO_RESET USB_CDC_AS_SERIAL_TRANSPORT
+#endif
+
+#endif // TRANSPORT_CONFIG_H_
diff --git a/examples/platforms/nrf528xx/nrf52840/Makefile.am b/examples/platforms/nrf528xx/nrf52840/Makefile.am
index 6a06149..6062fa4 100644
--- a/examples/platforms/nrf528xx/nrf52840/Makefile.am
+++ b/examples/platforms/nrf528xx/nrf52840/Makefile.am
@@ -32,6 +32,7 @@
     libopenthread-nrf52840.a                                                                                 \
     libopenthread-nrf52840-sdk.a                                                                             \
     libopenthread-nrf52840-softdevice-sdk.a                                                                  \
+    libopenthread-nrf52840-transport.a                                                                       \
     $(NULL)
 
 # Do not enable -pedantic-errors for nRF52840 driver library
@@ -42,26 +43,50 @@
 override CFLAGS                                      := $(filter-out -Wundef,$(CFLAGS))
 override CXXFLAGS                                    := $(filter-out -Wundef,$(CXXFLAGS))
 
+# Do not enable -Wcast-align for nRF52840 driver library
+override CFLAGS                                      := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                                    := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 COMMONCPPFLAGS                                                                                             = \
     -DCONFIG_GPIO_AS_PINRESET                                                                                \
     -DNRF52840_XXAA                                                                                          \
+    -DUSE_APP_CONFIG=1                                                                                       \
     -I$(srcdir)                                                                                              \
     -I$(top_srcdir)/include                                                                                  \
     -I$(top_srcdir)/examples/platforms                                                                       \
     -I$(top_srcdir)/examples/platforms/nrf528xx/src                                                          \
+    -I$(top_srcdir)/examples/platforms/nrf528xx/src/transport                                                \
     -I$(top_srcdir)/src/core                                                                                 \
-    -I$(top_srcdir)/third_party/NordicSemiconductor                                                          \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                    \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                             \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock                                            \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common                                           \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio                                            \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/three_pin_gpio                         \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal                                        \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features                               \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator                 \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch                                       \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal                                  \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice                       \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer                          \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/temperature                       \
+    -Wno-unused-parameter                                                                                    \
+    $(NULL)
+
+# Only reference the SDK header files included in third_party/NordicSemiconductor
+# when building the example applications.
+#
+# When building just the platform libraries, the caller of configure is expected
+# to provide the correct -I arguments to locate the necessary header files in an
+# external copy of the Nordic nRF5 SDK.
+#
+# Note that an exception is made for the 802.15.4 radio driver, which is always
+# built using the sources in third_party/NordicSemiconductor/drivers/radio.
+if OPENTHREAD_ENABLE_EXAMPLES
+COMMONCPPFLAGS                                                                                            += \
+    -I$(top_srcdir)/third_party/NordicSemiconductor                                                          \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                    \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config                                                   \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52840/config                                   \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                             \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock                                            \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common                                           \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power                                            \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick                                          \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd                                             \
@@ -83,7 +108,9 @@
     -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/soc                                                 \
     -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers                                  \
     -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf52                            \
+    -Wno-unused-parameter                                                                                    \
     $(NULL)
+endif
 
 PLATFORM_COMMON_SOURCES                                                                                    = \
     src/alarm.c                                                                                              \
@@ -94,11 +121,15 @@
     src/logging.c                                                                                            \
     src/misc.c                                                                                               \
     src/radio.c                                                                                              \
-    src/spi-slave.c                                                                                          \
     src/system.c                                                                                             \
     src/temp.c                                                                                               \
-    src/uart.c                                                                                               \
-    src/usb-cdc-uart.c                                                                                       \
+    $(NULL)
+
+TRANSPORT_SOURCES                                                                                          = \
+    src/transport/spi-slave.c                                                                                \
+    src/transport/uart.c                                                                                     \
+    src/transport/usb-cdc-uart.c                                                                             \
+    src/transport/transport.c                                                                                \
     $(NULL)
 
 SINGLEPHY_SOURCES                                                                                          = \
@@ -112,8 +143,6 @@
     $(NULL)
 
 SOFTDEVICE_CPPFLAGS                                                                                        = \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice                       \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers                                  \
     -DSOFTDEVICE_PRESENT                                                                                     \
     -DS140                                                                                                   \
     $(NULL)
@@ -153,6 +182,14 @@
     $(SOFTDEVICE_SOURCES)                                                                                    \
     $(NULL)
 
+libopenthread_nrf52840_transport_a_CPPFLAGS                                                                = \
+    $(COMMONCPPFLAGS)                                                                                        \
+    $(NULL)
+
+libopenthread_nrf52840_transport_a_SOURCES                                                                 = \
+    $(TRANSPORT_SOURCES)                                                                                     \
+    $(NULL)
+
 Dash                                                                                                       = -
 
 libopenthread_nrf52840_a_LIBADD                                                                            = \
@@ -165,4 +202,7 @@
 libopenthread_nrf52840_softdevice_sdk_a_LIBADD                                                             = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
 
+libopenthread_nrf52840_transport_a_LIBADD                                                                  = \
+    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
+
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/nrf528xx/nrf52840/Makefile.platform.am b/examples/platforms/nrf528xx/nrf52840/Makefile.platform.am
index 10c191a..1fa02b6 100644
--- a/examples/platforms/nrf528xx/nrf52840/Makefile.platform.am
+++ b/examples/platforms/nrf528xx/nrf52840/Makefile.platform.am
@@ -32,6 +32,7 @@
 
 LDADD_COMMON                                                                           += \
     $(top_builddir)/examples/platforms/nrf528xx/libopenthread-nrf52840.a                  \
+    $(top_builddir)/examples/platforms/nrf528xx/libopenthread-nrf52840-transport.a        \
     $(top_builddir)/third_party/NordicSemiconductor/libnordicsemi-nrf52840-sdk.a          \
     $(top_builddir)/third_party/NordicSemiconductor/libnordicsemi-nrf52840-radio-driver.a \
     $(NULL)
@@ -46,7 +47,7 @@
     $(top_srcdir)/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_tls_vanilla.a        \
     $(top_srcdir)/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_x509_vanilla.a       \
     $(top_srcdir)/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_base_vanilla.a       \
-    $(top_srcdir)/third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.1.a   \
+    $(top_srcdir)/third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.2.a   \
     $(NULL)
 endif
 
diff --git a/examples/platforms/nrf528xx/nrf52840/README.md b/examples/platforms/nrf528xx/nrf52840/README.md
index 1b6eca2..29c0564 100644
--- a/examples/platforms/nrf528xx/nrf52840/README.md
+++ b/examples/platforms/nrf528xx/nrf52840/README.md
@@ -4,13 +4,13 @@
 <img src="https://cdn.rawgit.com/openthread/openthread/ab4c4e1e/doc/images/certified.svg" alt="Thread Certified Component" width="150px" align="right">
 </a>
 
-This directory contains example platform drivers for [Nordic Semiconductor nRF52840 SoC][nRF52840]. The OpenThread stack has been officially certified as a *Thread Certified Component* on this platform.
+This directory contains example platform drivers for [Nordic Semiconductor nRF52840 SoC][nrf52840]. The OpenThread stack has been officially certified as a _Thread Certified Component_ on this platform.
 
-[nRF52840]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52840
+[nrf52840]: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52840
 
-To facilitate Thread products development with the nRF52840 platform, Nordic Semiconductor provides <i>nRF5 SDK for Thread and Zigbee</i>. See [Nordic Semiconductor's nRF5 SDK for Thread and Zigbee][nRF5-SDK-section] section for more details.
+To facilitate Thread products development with the nRF52840 platform, Nordic Semiconductor provides <i>nRF5 SDK for Thread and Zigbee</i>. See [Nordic Semiconductor's nRF5 SDK for Thread and Zigbee][nrf5-sdk-section] section for more details.
 
-[nRF5-SDK-section]: #nordic-semiconductors-nrf5-sdk-for-thread-and-zigbee
+[nrf5-sdk-section]: #nordic-semiconductors-nrf5-sdk-for-thread-and-zigbee
 
 ## Prerequisites
 
@@ -31,13 +31,13 @@
 
 ### Flashing and debugging tools
 
-[nRF-Command-Line-Tools]: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools
+[nrf-command-line-tools]: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools
 
-Install the [nRF Command Line Tools][nRF-Command-Line-Tools] to flash, debug, and make use of logging features on the nRF52840 DK with SEGGER J-Link.
+Install the [nRF Command Line Tools][nrf-command-line-tools] to flash, debug, and make use of logging features on the nRF52840 DK with SEGGER J-Link.
 
 ## Building the examples
 
- To build the examples, run the following command in Bash:
+To build the examples, run the following command in Bash:
 
 ```bash
 $ cd <path-to-openthread>
@@ -45,37 +45,37 @@
 $ make -f examples/Makefile-nrf52840
 ```
 
-After a successful build, the `elf` files can be found in
-`<path-to-openthread>/output/nrf52840/bin`.
-You can convert them to hex using `arm-none-eabi-objcopy`:
+After a successful build, the `elf` files can be found in `<path-to-openthread>/output/nrf52840/bin`. You can convert them to hex using `arm-none-eabi-objcopy`:
+
 ```bash
 $ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex
 ```
 
 ### USB CDC ACM support
 
-You can build the libraries with support for the native USB CDC ACM as a serial transport.
-To do so, build the firmware with the following parameter:
+You can build the libraries with support for the native USB CDC ACM as a serial transport. To do so, build the firmware with the following parameter:
+
 ```
 $ make -f examples/Makefile-nrf52840 USB=1
 ```
 
 Note that the USB CDC ACM serial transport is not supported with Engineering sample A of the nRF52840 chip.
 
-If you are using Windows 7 or earlier, you must load an additional USB CDC driver.
-The driver can be found in `third_party/NordicSemiconductor/libraries/usb/nordic_cdc_acm_example.inf`.
+If you are using Windows 7 or earlier, you must load an additional USB CDC driver. The driver can be found in `third_party/NordicSemiconductor/libraries/usb/nordic_cdc_acm_example.inf`.
 
 ### Bootloader support
 
 The examples support the following bootloaders for performing a Device Firmware Upgrade (DFU):
-* USB bootloader
-* UART bootloader
-* BLE bootloader
+
+- USB bootloader
+- UART bootloader
+- BLE bootloader
 
 The support for a particular bootloader can be enabled with the following switches:
-* USB: `BOOTLOADER=USB`
-* UART: `BOOTLOADER=UART`
-* BLE: `BOOTLOADER=BLE`
+
+- USB: `BOOTLOADER=USB`
+- UART: `BOOTLOADER=UART`
+- BLE: `BOOTLOADER=BLE`
 
 ### nRF52840 dongle support (PCA10059)
 
@@ -93,26 +93,23 @@
 
 ### Native SPI support
 
-You can build the libraries with support for native SPI Slave.
-To build the libraries, run make with the following parameter:
+You can build the libraries with support for native SPI Slave. To build the libraries, run make with the following parameter:
 
 ```
 $ make -f examples/Makefile-nrf52840 NCP_SPI=1
 ```
 
-With this option enabled, SPI communication between the NCP example and wpantund is possible
-(provided that the wpantund host supports SPI Master). To achieve that, an appropriate SPI device
-should be chosen in wpantund configuration file, `/etc/wpantund.conf`. You can find an example below.
+With this option enabled, SPI communication between the NCP example and wpantund is possible (provided that the wpantund host supports SPI Master). To achieve that, an appropriate SPI device should be chosen in wpantund configuration file, `/etc/wpantund.conf`. You can find an example below.
+
 ```
 Config:NCP:SocketPath "system:/usr/bin/spi-hdlc-adapter --gpio-int /sys/class/gpio/gpio25 /dev/spidev0.0"
 ```
 
 In this example, [spi-hdlc-adapter][spi-hdlc-adapter] is a tool that you can use to communicate between NCP and wpantund over SPI. For this example, `spi-hdlc-adapter` is installed in `/usr/bin`.
 
-The default SPI Slave pin configuration for nRF52840 is defined in `examples/platforms/nrf52840/platform-config.h`.
+The default SPI Slave pin configuration for nRF52840 is defined in `examples/platforms/nrf52840/transport-config.h`.
 
-Note that the native SPI Slave support is not intended to be used with Engineering sample A of the nRF52840 chip due to
-single transfer size limitation.
+Note that the native SPI Slave support is not intended to be used with Engineering sample A of the nRF52840 chip due to single transfer size limitation.
 
 [spi-hdlc-adapter]: https://github.com/openthread/openthread/tree/master/tools/spi-hdlc-adapter
 
@@ -129,12 +126,14 @@
 ### CryptoCell 310 support
 
 By default, OpenThread uses mbedTLS library with support for CryptoCell 310 hardware acceleration of cryptographic operations. When building the application, an explicit setup is needed (error checking omitted):
+
 ```
 mbedtls_platform_set_calloc_free(calloc, free);
 mbedtls_platform_setup(NULL);
 ```
 
 When building an external application with OpenThread libraries and CryptoCell 310 hardware acceleration, use the following configuration:
+
 - Crypto libraries:
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue.a`
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_cc310.a`
@@ -144,23 +143,26 @@
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_tls_vanilla.a`
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_x509_vanilla.a`
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_base_vanilla.a`
-  - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.1.a`
+  - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.2.a`
 - Include directories:
   - `third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_platform_config`
   - `third_party/NordicSemiconductor/libraries/nrf_security/include`
   - `third_party/NordicSemiconductor/libraries/nrf_security/config`
   - `third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_platform/include`
 - Defines:
-  - `MBEDTLS_CONFIG_FILE` set to  `"nrf-config.h"`
+  - `MBEDTLS_CONFIG_FILE` set to `"nrf-config.h"`
   - `MBEDTLS_USER_CONFIG_FILE` set to `"nrf52840-mbedtls-config.h"`
+
 ### Optional disabling of CryptoCell 310 support
 
 By default, OpenThread uses mbedTLS library with support for CryptoCell 310 hardware acceleration of cryptographic operations. You can disable CryptoCell 310 and use software cryptography instead by building OpenThread with the following parameter:
+
 ```
 $ make -f examples/Makefile-nrf52840 DISABLE_BUILTIN_MBEDTLS=0 ...
 ```
 
 When building an external application with OpenThread libraries and software cryptography, use the following configuration:
+
 - Crypto libraries:
   - `output/nrf52840/lib/libmbedcrypto.a` (present after successful build)
 - Include directories:
@@ -168,12 +170,13 @@
   - `third_party/mbedtls`
   - `third_party/mbedtls/repo/include`
 - Defines:
-  - `MBEDTLS_CONFIG_FILE` set to  `"mbedtls-config.h"`
+  - `MBEDTLS_CONFIG_FILE` set to `"mbedtls-config.h"`
   - `MBEDTLS_USER_CONFIG_FILE` set to `"nrf52840-mbedtls-config.h"`
 
 ### CryptoCell 310 abort mechanism
 
 The CryptoCell 310 platform implements an abort mechanism. By default, any fault in the CryptoCell 310 library results in the system reset. This behavior can be changed by a call to the `nrf_cc310_platform_set_abort()` function. This function must be called before `mbedtls_platform_setup`:
+
 ```
 void nrf_cc310_platform_set_abort(
 	nrf_cc310_platform_abort_apis_t const * const apis)
@@ -182,6 +185,7 @@
 ### CryptoCell 310 RTOS support
 
 The hardware-accelerated mbedTLS library supports access from multiple threads. By default, simple blocking implementation of mutexes is used. The locking mechanism can be replaced by using the `nrf_cc310_platform_set_mutexes()` function. This function must be called before `mbedtls_platform_setup`:
+
 ```
 void nrf_cc310_platform_set_mutexes(nrf_cc310_platform_mutex_apis_t const * const apis,
                                     nrf_cc310_platform_mutexes_t const * const mutexes)
@@ -192,6 +196,7 @@
 The sample implementation of the abort functionality for FreeRTOS and Zephyr operating systems can be found in `nrf_cc310_platform_abort_freertos.c` and `nrf_cc310_platform_abort_zephyr.c`. Both files implement the function `void nrf_cc310_platform_abort_init(void)`. This function must be called before `mbedtls_platform_setup`.
 
 The typical setup in the RTOS environment (error checking omitted) is as follows:
+
 ```
 mbedtls_platform_set_calloc_free(calloc, free);
 nrf_cc310_platform_abort_init();
@@ -200,6 +205,7 @@
 ```
 
 When building an external application that uses RTOS with OpenThread libraries and the CryptoCell 310 hardware acceleration, use the following configuration:
+
 - Crypto libraries:
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue.a`
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_cc310.a`
@@ -209,14 +215,14 @@
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_tls_vanilla.a`
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_x509_vanilla.a`
   - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_base_vanilla.a`
-  - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.1.a`
+  - `third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.2.a`
 - Include directories:
   - `third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_platform_config`
   - `third_party/NordicSemiconductor/libraries/nrf_security/include`
   - `third_party/NordicSemiconductor/libraries/nrf_security/config`
   - `third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_platform/include`
 - Defines:
-  - `MBEDTLS_CONFIG_FILE` set to  `"nrf-config.h"`
+  - `MBEDTLS_CONFIG_FILE` set to `"nrf-config.h"`
   - `MBEDTLS_USER_CONFIG_FILE` set to `"nrf52840-mbedtls-config.h"`
 - Sources:
   - `nrf_cc310_platform_mutex_freertos.c` or `nrf_cc310_platform_mutex_zephyr.c` from `third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_platform/src`, depending on the RTOS used.
@@ -245,6 +251,7 @@
 ```
 
 When building an external application that uses RTOS with OpenThread libraries and software cryptography, use the following configuration:
+
 - Crypto libraries:
   - `output/nrf52840/lib/libmbedcrypto.a` (present after successful build)
 - Include directories:
@@ -253,7 +260,7 @@
   - `third_party/mbedtls/repo/include`
   - `third_party/NordicSemiconductor/libraries/nrf_security/include/software-only-threading`
 - Defines:
-  - `MBEDTLS_CONFIG_FILE` set to  `"mbedtls-config.h"`
+  - `MBEDTLS_CONFIG_FILE` set to `"mbedtls-config.h"`
   - `MBEDTLS_USER_CONFIG_FILE` set to `"nrf52840-mbedtls-config.h"`
   - `MBEDTLS_THREADING_C`
   - `MBEDTLS_THREADING_ALT`
@@ -267,8 +274,9 @@
 When the Thread device is configured to obtain the Thread Network security credentials with either Thread Commissioning or an out-of-band method, the extended MAC address should be constructed out of the globally unique IEEE EUI-64.
 
 The IEEE EUI-64 address consists of two parts:
- - 24 bits of MA-L (MAC Address Block Large), formerly called OUI (Organizationally Unique Identifier)
- - 40-bit device unique identifier
+
+- 24 bits of MA-L (MAC Address Block Large), formerly called OUI (Organizationally Unique Identifier)
+- 40-bit device unique identifier
 
 By default, the device uses Nordic Semiconductor's MA-L (f4-ce-36). You can modify it by overwriting the `OPENTHREAD_CONFIG_STACK_VENDOR_OUI` define, located in the `openthread-core-nrf52840-config.h` file. This value must be publicly registered by the IEEE Registration Authority.
 
@@ -278,8 +286,7 @@
 
 ## Flashing the binaries
 
-Flash the compiled binaries onto nRF52840 using `nrfjprog` which is
-part of the [nRF Command Line Tools][nRF-Command-Line-Tools].
+Flash the compiled binaries onto nRF52840 using `nrfjprog` which is part of the [nRF Command Line Tools][nrf-command-line-tools].
 
 ```bash
 $ nrfjprog -f nrf52 --chiperase --program output/nrf52840/bin/ot-cli-ftd.hex --reset
@@ -297,12 +304,11 @@
 
    b. Connect to the used COM port with the following direct UART settings:
 
-   * Baud rate: 115200
-   * 8 data bits
-   * 1 stop bit
-   * No parity
-   * HW flow control: RTS/CTS
-     This allows you to view the raw UART output.
+   - Baud rate: 115200
+   - 8 data bits
+   - 1 stop bit
+   - No parity
+   - HW flow control: RTS/CTS This allows you to view the raw UART output.
 
      On Linux system a port name should be called e.g. `/dev/ttyACM0` or `/dev/ttyACM1`.
 
@@ -384,9 +390,9 @@
    16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
    ```
 
-For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
 
-[CLI]: ./../../../src/cli/README.md
+[cli]: ./../../../src/cli/README.md
 
 ## SEGGER J-Link tools
 
@@ -394,12 +400,12 @@
 
 ### Working with RTT logging
 
-By default, the OpenThread's logging module provides functions to output logging
-information over SEGGER's Real Time Transfer (RTT).
+By default, the OpenThread's logging module provides functions to output logging information over SEGGER's Real Time Transfer (RTT).
 
 You can set the desired log level by using the `OPENTHREAD_CONFIG_LOG_LEVEL` define.
 
 To enable the highest verbosity level, append `FULL_LOGS` flag to the `make` command:
+
 ```
 $ make -f examples/Makefile-nrf52840 FULL_LOGS=1
 ```
@@ -415,10 +421,13 @@
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52840_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID> -RTTTelnetPort 19021
 ```
+
 3. Run `JLinkRTTTelnet` to obtain the RTT logs from the connected device in a separate console. For example:
+
 ```
 JLinkRTTClient -RTTTelnetPort 19021
 ```
@@ -434,22 +443,28 @@
 3. From the Specify Target Device dropdown menu, select `NRF52840_XXAA`.
 4. From the Target Interface & Speed dropdown menu, select `SWD`.
 5. Run the following command:
+
 ```
 MSDDisable
 ```
+
 6. Power cycle the DK.
 
 #### Disabling the Mass Storage Device on Linux
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52840_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID>
 ```
+
 3. Run the following command:
+
 ```
 MSDDisable
 ```
+
 4. Power cycle the DK.
 
 ### Hardware Flow Control detection
@@ -467,85 +482,94 @@
 3. From the Specify Target Device dropdown menu, select `NRF52840_XXAA`.
 4. From the Target Interface & Speed dropdown menu, select `SWD`.
 5. Run the following command:
+
 ```
 SetHWFC Force
 ```
+
 6. Power cycle the DK.
 
 #### Disabling the HWFC detection on Linux
 
 1. Connect the DK to your machine with a USB cable.
 2. Run `JLinkExe` to connect to the target. For example:
+
 ```
 JLinkExe -device NRF52840_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <SEGGER_ID>
 ```
+
 3. Run the following command:
+
 ```
 SetHWFC Force
 ```
+
 4. Power cycle the DK.
 
-You can find more details [here][J-Link-OB].
+You can find more details [here][j-link-ob].
 
-[J-Link-OB]: https://wiki.segger.com/J-Link_OB_SAM3U_NordicSemi#Hardware_flow_control_support
+[j-link-ob]: https://wiki.segger.com/J-Link_OB_SAM3U_NordicSemi#Hardware_flow_control_support
 
 ## Diagnostic module
 
-nRF52840 port extends [OpenThread Diagnostics Module][DIAG].
+nRF52840 port extends [OpenThread Diagnostics Module][diag].
 
-You can read about all the features [here][nRFDIAG].
+You can read about all the features [here][nrfdiag].
 
-[DIAG]: ./../../../src/core/diags/README.md
-[nRFDIAG]: ./../DIAG.md
+[diag]: ./../../../src/core/diags/README.md
+[nrfdiag]: ./../DIAG.md
 
 ## Radio driver documentation
 
-The radio driver comes with documentation that describes the operation of state
-machines in this module. To open the `*.uml` sequence diagrams, use [PlantUML][PlantUML-url].
+The radio driver comes with documentation that describes the operation of state machines in this module. To open the `*.uml` sequence diagrams, use [PlantUML][plantuml-url].
 
-[PlantUML-url]: http://plantuml.com/
+[plantuml-url]: http://plantuml.com/
 
 ## Verification
 
 The following development kits have been used for testing and verification:
-  - PCA10056 1.0.0
-  - PCA10059 1.0.0
-  - PCA10068 0.5.0
+
+- PCA10056 1.0.0
+- PCA10059 1.0.0
+- PCA10068 0.5.0
 
 The following toolchains have been used for testing and verification:
-  - GCC: GCC ARM Embedded 7.2018 q2 update
-  - IAR: IAR Workbench 7.80.4
-  - SES: SES 4.12
-  - ARM: MDK-ARM version 5.25
 
- The following OpenThread commits have been verified with nRF52840 and nRF52811 examples by Nordic Semiconductor:
-  - `2279ef6` - 23.05.2019 (the latest checked)
-  - `23ff101` - 22.03.2019
-  - `704511c` - 18.09.2018
-  - `ec59d7e` - 06.04.2018
-  - `a89eb88` - 16.11.2017
-  - `6a15261` - 29.06.2017
-  - `030efba` - 22.04.2017
-  - `de48acf` - 02.03.2017
-  - `50db58d` - 23.01.2017
+- GCC: GCC ARM Embedded 7.2018 q2 update
+- IAR: IAR Workbench 7.80.4
+- SES: SES 4.12
+- ARM: MDK-ARM version 5.25
+
+The following OpenThread commits have been verified with nRF52840 and nRF52811 examples by Nordic Semiconductor:
+
+- `2279ef6` - 23.05.2019 (the latest checked)
+- `23ff101` - 22.03.2019
+- `704511c` - 18.09.2018
+- `ec59d7e` - 06.04.2018
+- `a89eb88` - 16.11.2017
+- `6a15261` - 29.06.2017
+- `030efba` - 22.04.2017
+- `de48acf` - 02.03.2017
+- `50db58d` - 23.01.2017
 
 # Nordic Semiconductor's nRF5 SDK for Thread and Zigbee
 
-Use [nRF5 Software Development Kit (SDK) for Thread and Zigbee][nRF5-SDK-Thread-Zigbee] when developing Thread products with Nordic Semiconductor's advanced nRF52840, nRF52833 or nRF52811 SoCs.
+Use [nRF5 Software Development Kit (SDK) for Thread and Zigbee][nrf5-sdk-thread-zigbee] when developing Thread products with Nordic Semiconductor's advanced nRF52840, nRF52833 or nRF52811 SoCs.
 
 The <i>nRF5 SDK for Thread and Zigbee</i> includes:
- - a pre-built OpenThread stack for the Nordic nRF52840 and nRF52811 SoCs,
- - support for hardware-accelerated cryptographic operations using ARM® CryptoCell-310,
- - unique Thread/Bluetooth Low Energy dynamic multiprotocol solution which allows for concurrent operation of Thread and Bluetooth Low Energy utilizing OpenThread and SoftDevice (Nordic’s Bluetooth Low Energy stack) with accompanying example applications,
- - Thread/Bluetooth Low Energy switched multiprotocol solution with accompanying example applications,
- - unique support for DFU-over-Thread (Device Firmware Upgrade),
- - examples to demonstrate interactions between nodes performing different Thread roles with the use of OpenThread and CoAP, CoAP Secure or MQTT-SN protocols,
- - support for OpenThread Network Co-Processor (NCP) and Radio Co-Processor (RCP) using UART, USB or SPI transport protocol,
- - Border Router and cloud connectivity example (e.g. with Google Cloud Platform),
- - Thread native commissioning with NFC example,
- - example applications demonstrating the use of FreeRTOS with OpenThread,
- - support for IAR, Keil MDK-ARM and SEGGER Embedded Studio (SES) IDEs for OpenThread stack and all example applications,
- - range of PC tools including Thread Topology Monitor and nRF Sniffer for 802.15.4,
- - software modules inherited from the nRF5 SDK e.g. peripheral drivers, NFC libraries, Bluetooth Low Energy libraries etc.
 
-[nRF5-SDK-Thread-Zigbee]: https://www.nordicsemi.com/Software-and-Tools/Software/nRF5-SDK-for-Thread-and-Zigbee
+- a pre-built OpenThread stack for the Nordic nRF52840 and nRF52811 SoCs,
+- support for hardware-accelerated cryptographic operations using ARM® CryptoCell-310,
+- unique Thread/Bluetooth Low Energy dynamic multiprotocol solution which allows for concurrent operation of Thread and Bluetooth Low Energy utilizing OpenThread and SoftDevice (Nordic’s Bluetooth Low Energy stack) with accompanying example applications,
+- Thread/Bluetooth Low Energy switched multiprotocol solution with accompanying example applications,
+- unique support for DFU-over-Thread (Device Firmware Upgrade),
+- examples to demonstrate interactions between nodes performing different Thread roles with the use of OpenThread and CoAP, CoAP Secure or MQTT-SN protocols,
+- support for OpenThread Network Co-Processor (NCP) and Radio Co-Processor (RCP) using UART, USB or SPI transport protocol,
+- Border Router and cloud connectivity example (e.g. with Google Cloud Platform),
+- Thread native commissioning with NFC example,
+- example applications demonstrating the use of FreeRTOS with OpenThread,
+- support for IAR, Keil MDK-ARM and SEGGER Embedded Studio (SES) IDEs for OpenThread stack and all example applications,
+- range of PC tools including Thread Topology Monitor and nRF Sniffer for 802.15.4,
+- software modules inherited from the nRF5 SDK e.g. peripheral drivers, NFC libraries, Bluetooth Low Energy libraries etc.
+
+[nrf5-sdk-thread-zigbee]: https://www.nordicsemi.com/Software-and-Tools/Software/nRF5-SDK-for-Thread-and-Zigbee
diff --git a/examples/platforms/nrf528xx/nrf52840/openthread-core-nrf52840-config.h b/examples/platforms/nrf528xx/nrf52840/openthread-core-nrf52840-config.h
index 72ebe92..a41610e 100644
--- a/examples/platforms/nrf528xx/nrf52840/openthread-core-nrf52840-config.h
+++ b/examples/platforms/nrf528xx/nrf52840/openthread-core-nrf52840-config.h
@@ -133,33 +133,43 @@
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
  *
  * Define to 1 if you want to enable software ACK timeout logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 0
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
 #endif
 
 /**
@@ -173,33 +183,15 @@
 #endif
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of settings.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
  *
  */
-#ifndef SETTINGS_CONFIG_BASE_ADDRESS
-#define SETTINGS_CONFIG_BASE_ADDRESS 0
-#endif
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_PAGE_SIZE
-#define SETTINGS_CONFIG_PAGE_SIZE 4096
-#endif
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_PAGE_NUM
-#define SETTINGS_CONFIG_PAGE_NUM 4
+#ifndef OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
 #endif
 
 /**
diff --git a/examples/platforms/nrf528xx/nrf52840/platform-config.h b/examples/platforms/nrf528xx/nrf52840/platform-config.h
index 5eb8a47..fba9616 100644
--- a/examples/platforms/nrf528xx/nrf52840/platform-config.h
+++ b/examples/platforms/nrf528xx/nrf52840/platform-config.h
@@ -36,151 +36,14 @@
 #define PLATFORM_CONFIG_H_
 
 #include "nrf.h"
+#include "nrf_drv_clock.h"
 #include "nrf_peripherals.h"
-#include "drivers/clock/nrf_drv_clock.h"
 #include "hal/nrf_radio.h"
-#include "hal/nrf_uart.h"
 
 #include "openthread-core-config.h"
 #include <openthread/config.h>
 
 /*******************************************************************************
- * @section UART Driver Configuration.
- ******************************************************************************/
-
-/**
- * @def UART_INSTANCE
- *
- * UART Instance.
- *
- */
-#ifndef UART_INSTANCE
-#define UART_INSTANCE NRF_UART0
-#endif
-
-/**
- * @def UART_PARITY
- *
- * UART Parity configuration.
- *
- * @brief Possible values:
- *         \ref NRF_UART_PARITY_EXCLUDED - Parity bit is not present.
- *         \ref NRF_UART_PARITY_INCLUDED - Parity bit is present.
- *
- */
-#ifndef UART_PARITY
-#define UART_PARITY NRF_UART_PARITY_EXCLUDED
-#endif
-
-/**
- * @def UART_HWFC_ENABLED
- *
- * Enable UART Hardware Flow Control.
- *
- */
-#ifndef UART_HWFC_ENABLED
-#define UART_HWFC_ENABLED 1
-#endif
-
-/**
- * @def UART_BAUDRATE
- *
- * UART Baudrate.
- *
- * @brief Possible values:
- *         \ref NRF_UART_BAUDRATE_1200 - 1200 baud.
- *         \ref NRF_UART_BAUDRATE_2400 - 2400 baud.
- *         \ref NRF_UART_BAUDRATE_4800 - 4800 baud.
- *         \ref NRF_UART_BAUDRATE_9600 - 9600 baud.
- *         \ref NRF_UART_BAUDRATE_14400 - 14400 baud.
- *         \ref NRF_UART_BAUDRATE_19200 - 19200 baud.
- *         \ref NRF_UART_BAUDRATE_28800 - 28800 baud.
- *         \ref NRF_UART_BAUDRATE_38400 - 38400 baud.
- *         \ref NRF_UART_BAUDRATE_57600 - 57600 baud.
- *         \ref NRF_UART_BAUDRATE_76800 - 76800 baud.
- *         \ref NRF_UART_BAUDRATE_115200 - 115200 baud.
- *         \ref NRF_UART_BAUDRATE_230400 - 230400 baud.
- *         \ref NRF_UART_BAUDRATE_250000 - 250000 baud.
- *         \ref NRF_UART_BAUDRATE_460800 - 460800 baud.
- *         \ref NRF_UART_BAUDRATE_921600 - 921600 baud.
- *         \ref NRF_UART_BAUDRATE_1000000 - 1000000 baud.
- *
- */
-#ifndef UART_BAUDRATE
-#define UART_BAUDRATE NRF_UART_BAUDRATE_115200
-#endif
-
-/**
- *  @def UART_IRQN
- *
- * UART Interrupt number.
- *
- */
-#ifndef UART_IRQN
-#define UART_IRQN UARTE0_UART0_IRQn
-#endif
-
-/**
- * @def UART_IRQ_PRIORITY
- *
- * UART Interrupt priority.
- *
- */
-#ifndef UART_IRQ_PRIORITY
-#define UART_IRQ_PRIORITY 6
-#endif
-
-/**
- * @def UART_RX_BUFFER_SIZE
- *
- * UART Receive buffer size.
- *
- */
-#ifndef UART_RX_BUFFER_SIZE
-#define UART_RX_BUFFER_SIZE 512
-#endif
-
-/**
- * @def UART_PIN_TX
- *
- * UART TX Pin.
- *
- */
-#ifndef UART_PIN_TX
-#define UART_PIN_TX 6
-#endif
-
-/**
- * @def UART_PIN_RX
- *
- * UART RX Pin.
- *
- */
-#ifndef UART_PIN_RX
-#define UART_PIN_RX 8
-#endif
-
-/**
- * @def UART_PIN_CTS
- *
- * UART CTS Pin.
- *
- */
-#ifndef UART_PIN_CTS
-#define UART_PIN_CTS 7
-#endif
-
-/**
- * @def UART_PIN_RTS
- *
- * UART RTS Pin.
- *
- */
-#ifndef UART_PIN_RTS
-#define UART_PIN_RTS 5
-#endif
-
-/*******************************************************************************
  * @section Alarm Driver Configuration.
  ******************************************************************************/
 
@@ -249,134 +112,19 @@
 #endif
 
 /*******************************************************************************
- * @section SPI Slave configuration.
+ * @section Platform Flash Configuration
  ******************************************************************************/
 
 /**
- * @def SPIS Instance.
- */
-#ifndef SPIS_INSTANCE
-#define SPIS_INSTANCE 0
-#endif
-
-/**
- * @def SPIS mode.
+ * @def PLATFORM_FLASH_PAGE_NUM
  *
- * @brief Possible values:
- *         \ref NRF_SPIS_MODE_0 - SCK active high, sample on leading edge of clock.
- *         \ref NRF_SPIS_MODE_1 - SCK active high, sample on trailing edge of clock.
- *         \ref NRF_SPIS_MODE_2 - SCK active low, sample on leading edge of clock.
- *         \ref NRF_SPIS_MODE_3 - SCK active low, sample on trailing edge of clock.
- */
-#ifndef SPIS_MODE
-#define SPIS_MODE NRF_SPIS_MODE_0
-#endif
-
-/**
- * @def SPIS bit orders.
+ * Number of flash pages to use for OpenThread's non-volatile settings.
  *
- * @brief Possible values:
- *         \ref NRF_SPIS_BIT_ORDER_MSB_FIRST - Most significant bit shifted out first.
- *         \ref NRF_SPIS_BIT_ORDER_LSB_FIRST - Least significant bit shifted out first.
- */
-#ifndef SPIS_BIT_ORDER
-#define SPIS_BIT_ORDER NRF_SPIS_BIT_ORDER_MSB_FIRST
-#endif
-
-/**
- * @def SPIS Interrupt priority.
- */
-#ifndef SPIS_IRQ_PRIORITY
-#define SPIS_IRQ_PRIORITY 6
-#endif
-
-/**
- * @def SPIS MOSI Pin.
- */
-#ifndef SPIS_PIN_MOSI
-#define SPIS_PIN_MOSI 4
-#endif
-
-/**
- * @def SPIS MISO Pin.
- */
-#ifndef SPIS_PIN_MISO
-#define SPIS_PIN_MISO 28
-#endif
-
-/**
- * @def SPIS SCK Pin.
- */
-#ifndef SPIS_PIN_SCK
-#define SPIS_PIN_SCK 3
-#endif
-
-/**
- * @def SPIS CSN Pin.
- */
-#ifndef SPIS_PIN_CSN
-#define SPIS_PIN_CSN 29
-#endif
-
-/**
- * @def SPIS Host IRQ Pin.
- */
-#ifndef SPIS_PIN_HOST_IRQ
-#define SPIS_PIN_HOST_IRQ 30
-#endif
-
-/*******************************************************************************
- * @section USB driver configuration.
- ******************************************************************************/
-
-/**
- * @def USB_HOST_UART_CONFIG_DELAY_MS
- *
- * Delay after DTR gets asserted that we start send any queued data. This allows slow
- * Linux-based hosts to have enough time to configure their port for raw mode.
+ * @note This define applies only for MDK-ARM Keil toolchain configuration.
  *
  */
-#ifndef USB_HOST_UART_CONFIG_DELAY_MS
-#define USB_HOST_UART_CONFIG_DELAY_MS 10
-#endif
-
-/**
- * @def USB_CDC_AS_SERIAL_TRANSPORT
- *
- * Use USB CDC driver for serial communication.
- */
-#ifndef USB_CDC_AS_SERIAL_TRANSPORT
-#define USB_CDC_AS_SERIAL_TRANSPORT 0
-#endif
-
-/**
- * @def The USB interface to use for CDC ACM COMM.
- *
- * According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
- * limitation. Takes values between 0-255.
- */
-#ifndef USB_CDC_ACM_COMM_INTERFACE
-#define USB_CDC_ACM_COMM_INTERFACE 1
-#endif
-
-/**
- * @def The USB interface to use for CDC ACM DATA.
- *
- * According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
- * limitation. Takes values between 0-255.
- */
-#ifndef USB_CDC_ACM_DATA_INTERFACE
-#define USB_CDC_ACM_DATA_INTERFACE 2
-#endif
-
-/**
- * @def OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
- *
- * Reset the application, not the chip, when a software reset is requested.
- * via `otPlatReset()`.
- */
-#ifndef OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
-#define OPENTHREAD_PLATFORM_USE_PSEUDO_RESET USB_CDC_AS_SERIAL_TRANSPORT
+#ifndef PLATFORM_FLASH_PAGE_NUM
+#define PLATFORM_FLASH_PAGE_NUM 4
 #endif
 
 /*******************************************************************************
diff --git a/examples/platforms/nrf528xx/nrf52840/transport-config.h b/examples/platforms/nrf528xx/nrf52840/transport-config.h
new file mode 100644
index 0000000..3e1b897
--- /dev/null
+++ b/examples/platforms/nrf528xx/nrf52840/transport-config.h
@@ -0,0 +1,309 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes the transport-specific configuration.
+ *
+ */
+
+#ifndef TRANSPORT_CONFIG_H_
+#define TRANSPORT_CONFIG_H_
+
+#include "nrf.h"
+#include "hal/nrf_spis.h"
+#include "hal/nrf_uart.h"
+
+/*******************************************************************************
+ * @section UART Driver Configuration.
+ ******************************************************************************/
+
+/**
+ * @def UART_INSTANCE
+ *
+ * UART Instance.
+ *
+ */
+#ifndef UART_INSTANCE
+#define UART_INSTANCE NRF_UART0
+#endif
+
+/**
+ * @def UART_PARITY
+ *
+ * UART Parity configuration.
+ *
+ * @brief Possible values:
+ *         \ref NRF_UART_PARITY_EXCLUDED - Parity bit is not present.
+ *         \ref NRF_UART_PARITY_INCLUDED - Parity bit is present.
+ *
+ */
+#ifndef UART_PARITY
+#define UART_PARITY NRF_UART_PARITY_EXCLUDED
+#endif
+
+/**
+ * @def UART_HWFC_ENABLED
+ *
+ * Enable UART Hardware Flow Control.
+ *
+ */
+#ifndef UART_HWFC_ENABLED
+#define UART_HWFC_ENABLED 1
+#endif
+
+/**
+ * @def UART_BAUDRATE
+ *
+ * UART Baudrate.
+ *
+ * @brief Possible values:
+ *         \ref NRF_UART_BAUDRATE_1200 - 1200 baud.
+ *         \ref NRF_UART_BAUDRATE_2400 - 2400 baud.
+ *         \ref NRF_UART_BAUDRATE_4800 - 4800 baud.
+ *         \ref NRF_UART_BAUDRATE_9600 - 9600 baud.
+ *         \ref NRF_UART_BAUDRATE_14400 - 14400 baud.
+ *         \ref NRF_UART_BAUDRATE_19200 - 19200 baud.
+ *         \ref NRF_UART_BAUDRATE_28800 - 28800 baud.
+ *         \ref NRF_UART_BAUDRATE_38400 - 38400 baud.
+ *         \ref NRF_UART_BAUDRATE_57600 - 57600 baud.
+ *         \ref NRF_UART_BAUDRATE_76800 - 76800 baud.
+ *         \ref NRF_UART_BAUDRATE_115200 - 115200 baud.
+ *         \ref NRF_UART_BAUDRATE_230400 - 230400 baud.
+ *         \ref NRF_UART_BAUDRATE_250000 - 250000 baud.
+ *         \ref NRF_UART_BAUDRATE_460800 - 460800 baud.
+ *         \ref NRF_UART_BAUDRATE_921600 - 921600 baud.
+ *         \ref NRF_UART_BAUDRATE_1000000 - 1000000 baud.
+ *
+ */
+#ifndef UART_BAUDRATE
+#define UART_BAUDRATE NRF_UART_BAUDRATE_115200
+#endif
+
+/**
+ *  @def UART_IRQN
+ *
+ * UART Interrupt number.
+ *
+ */
+#ifndef UART_IRQN
+#define UART_IRQN UARTE0_UART0_IRQn
+#endif
+
+/**
+ * @def UART_IRQ_PRIORITY
+ *
+ * UART Interrupt priority.
+ *
+ */
+#ifndef UART_IRQ_PRIORITY
+#define UART_IRQ_PRIORITY 6
+#endif
+
+/**
+ * @def UART_RX_BUFFER_SIZE
+ *
+ * UART Receive buffer size.
+ *
+ */
+#ifndef UART_RX_BUFFER_SIZE
+#define UART_RX_BUFFER_SIZE 512
+#endif
+
+/**
+ * @def UART_PIN_TX
+ *
+ * UART TX Pin.
+ *
+ */
+#ifndef UART_PIN_TX
+#define UART_PIN_TX 6
+#endif
+
+/**
+ * @def UART_PIN_RX
+ *
+ * UART RX Pin.
+ *
+ */
+#ifndef UART_PIN_RX
+#define UART_PIN_RX 8
+#endif
+
+/**
+ * @def UART_PIN_CTS
+ *
+ * UART CTS Pin.
+ *
+ */
+#ifndef UART_PIN_CTS
+#define UART_PIN_CTS 7
+#endif
+
+/**
+ * @def UART_PIN_RTS
+ *
+ * UART RTS Pin.
+ *
+ */
+#ifndef UART_PIN_RTS
+#define UART_PIN_RTS 5
+#endif
+
+/*******************************************************************************
+ * @section SPI Slave configuration.
+ ******************************************************************************/
+
+/**
+ * @def SPIS Instance.
+ */
+#ifndef SPIS_INSTANCE
+#define SPIS_INSTANCE 0
+#endif
+
+/**
+ * @def SPIS mode.
+ *
+ * @brief Possible values:
+ *         \ref NRF_SPIS_MODE_0 - SCK active high, sample on leading edge of clock.
+ *         \ref NRF_SPIS_MODE_1 - SCK active high, sample on trailing edge of clock.
+ *         \ref NRF_SPIS_MODE_2 - SCK active low, sample on leading edge of clock.
+ *         \ref NRF_SPIS_MODE_3 - SCK active low, sample on trailing edge of clock.
+ */
+#ifndef SPIS_MODE
+#define SPIS_MODE NRF_SPIS_MODE_0
+#endif
+
+/**
+ * @def SPIS bit orders.
+ *
+ * @brief Possible values:
+ *         \ref NRF_SPIS_BIT_ORDER_MSB_FIRST - Most significant bit shifted out first.
+ *         \ref NRF_SPIS_BIT_ORDER_LSB_FIRST - Least significant bit shifted out first.
+ */
+#ifndef SPIS_BIT_ORDER
+#define SPIS_BIT_ORDER NRF_SPIS_BIT_ORDER_MSB_FIRST
+#endif
+
+/**
+ * @def SPIS Interrupt priority.
+ */
+#ifndef SPIS_IRQ_PRIORITY
+#define SPIS_IRQ_PRIORITY 6
+#endif
+
+/**
+ * @def SPIS MOSI Pin.
+ */
+#ifndef SPIS_PIN_MOSI
+#define SPIS_PIN_MOSI 4
+#endif
+
+/**
+ * @def SPIS MISO Pin.
+ */
+#ifndef SPIS_PIN_MISO
+#define SPIS_PIN_MISO 28
+#endif
+
+/**
+ * @def SPIS SCK Pin.
+ */
+#ifndef SPIS_PIN_SCK
+#define SPIS_PIN_SCK 3
+#endif
+
+/**
+ * @def SPIS CSN Pin.
+ */
+#ifndef SPIS_PIN_CSN
+#define SPIS_PIN_CSN 29
+#endif
+
+/**
+ * @def SPIS Host IRQ Pin.
+ */
+#ifndef SPIS_PIN_HOST_IRQ
+#define SPIS_PIN_HOST_IRQ 30
+#endif
+
+/*******************************************************************************
+ * @section USB driver configuration.
+ ******************************************************************************/
+
+/**
+ * @def USB_HOST_UART_CONFIG_DELAY_MS
+ *
+ * Delay after DTR gets asserted that we start send any queued data. This allows slow
+ * Linux-based hosts to have enough time to configure their port for raw mode.
+ *
+ */
+#ifndef USB_HOST_UART_CONFIG_DELAY_MS
+#define USB_HOST_UART_CONFIG_DELAY_MS 10
+#endif
+
+/**
+ * @def USB_CDC_AS_SERIAL_TRANSPORT
+ *
+ * Use USB CDC driver for serial communication.
+ */
+#ifndef USB_CDC_AS_SERIAL_TRANSPORT
+#define USB_CDC_AS_SERIAL_TRANSPORT 0
+#endif
+
+/**
+ * @def The USB interface to use for CDC ACM COMM.
+ *
+ * According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
+ * limitation. Takes values between 0-255.
+ */
+#ifndef USB_CDC_ACM_COMM_INTERFACE
+#define USB_CDC_ACM_COMM_INTERFACE 1
+#endif
+
+/**
+ * @def The USB interface to use for CDC ACM DATA.
+ *
+ * According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
+ * limitation. Takes values between 0-255.
+ */
+#ifndef USB_CDC_ACM_DATA_INTERFACE
+#define USB_CDC_ACM_DATA_INTERFACE 2
+#endif
+
+/**
+ * @def OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+ *
+ * Reset the application, not the chip, when a software reset is requested.
+ * via `otPlatReset()`.
+ */
+#ifndef OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+#define OPENTHREAD_PLATFORM_USE_PSEUDO_RESET USB_CDC_AS_SERIAL_TRANSPORT
+#endif
+
+#endif // TRANSPORT_CONFIG_H_
diff --git a/examples/platforms/nrf528xx/src/alarm.c b/examples/platforms/nrf528xx/src/alarm.c
index 3d60856..5e74eaa 100644
--- a/examples/platforms/nrf528xx/src/alarm.c
+++ b/examples/platforms/nrf528xx/src/alarm.c
@@ -49,11 +49,10 @@
 
 #include "platform-config.h"
 #include "platform-nrf5.h"
-#include "cmsis/core_cmFunc.h"
 
-#include <drivers/clock/nrf_drv_clock.h>
-#include <drivers/radio/nrf_802154_utils.h>
-#include <drivers/radio/platform/lp_timer/nrf_802154_lp_timer.h>
+#include <nrf_802154_lp_timer.h>
+#include <nrf_802154_utils.h>
+#include <nrf_drv_clock.h>
 
 #include <hal/nrf_rtc.h>
 
@@ -689,7 +688,6 @@
     }
 }
 
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 uint64_t otPlatTimeGet(void)
 {
     return nrf5AlarmGetCurrentTime();
@@ -699,4 +697,3 @@
 {
     return XTAL_ACCURACY;
 }
-#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
diff --git a/examples/platforms/nrf528xx/src/diag.c b/examples/platforms/nrf528xx/src/diag.c
index 7918f09..32c78cb 100644
--- a/examples/platforms/nrf528xx/src/diag.c
+++ b/examples/platforms/nrf528xx/src/diag.c
@@ -46,7 +46,7 @@
 #include <openthread/platform/toolchain.h>
 
 #include <common/logging.hpp>
-#include <drivers/radio/nrf_802154.h>
+#include <nrf_802154.h>
 #include <utils/code_utils.h>
 
 typedef enum
@@ -59,7 +59,7 @@
 struct PlatformDiagCommand
 {
     const char *mName;
-    void (*mCommand)(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
+    otError (*mCommand)(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
 };
 
 struct PlatformDiagMessage
@@ -88,10 +88,10 @@
                                                   .mID                = 0,
                                                   .mCnt               = 0};
 
-static otError parseLong(char *argv, long *aValue)
+static otError parseLong(char *aArgs, long *aValue)
 {
     char *endptr;
-    *aValue = strtol(argv, &endptr, 0);
+    *aValue = strtol(aArgs, &endptr, 0);
     return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_PARSE;
 }
 
@@ -111,7 +111,11 @@
     return nrf_802154_continuous_carrier();
 }
 
-static void processListen(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+static otError processListen(otInstance *aInstance,
+                             uint8_t     aArgsLength,
+                             char *      aArgs[],
+                             char *      aOutput,
+                             size_t      aOutputMaxLen)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -119,7 +123,7 @@
 
     otEXPECT_ACTION(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         snprintf(aOutput, aOutputMaxLen, "listen: %s\r\n", sListen == true ? "yes" : "no");
     }
@@ -127,7 +131,7 @@
     {
         long value;
 
-        error = parseLong(argv[0], &value);
+        error = parseLong(aArgs[0], &value);
         otEXPECT(error == OT_ERROR_NONE);
         sListen = (bool)(value);
         snprintf(aOutput, aOutputMaxLen, "set listen to %s\r\nstatus 0x%02x\r\n", sListen == true ? "yes" : "no",
@@ -136,9 +140,10 @@
 
 exit:
     appendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-static void processID(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+static otError processID(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -146,7 +151,7 @@
 
     otEXPECT_ACTION(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         snprintf(aOutput, aOutputMaxLen, "ID: %" PRId16 "\r\n", sID);
     }
@@ -154,7 +159,7 @@
     {
         long value;
 
-        error = parseLong(argv[0], &value);
+        error = parseLong(aArgs[0], &value);
         otEXPECT(error == OT_ERROR_NONE);
         otEXPECT_ACTION(value >= 0, error = OT_ERROR_INVALID_ARGS);
         sID = (int16_t)(value);
@@ -163,21 +168,26 @@
 
 exit:
     appendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-static void processTransmit(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+static otError processTransmit(otInstance *aInstance,
+                               uint8_t     aArgsLength,
+                               char *      aArgs[],
+                               char *      aOutput,
+                               size_t      aOutputMaxLen)
 {
     otError error = OT_ERROR_NONE;
 
     otEXPECT_ACTION(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         snprintf(aOutput, aOutputMaxLen,
                  "transmit will send %" PRId32 " diagnostic messages with %" PRIu32 " ms interval\r\nstatus 0x%02x\r\n",
                  sTxRequestedCount, sTxPeriod, error);
     }
-    else if (strcmp(argv[0], "stop") == 0)
+    else if (strcmp(aArgs[0], "stop") == 0)
     {
         otEXPECT_ACTION(sTransmitMode != kDiagTransmitModeIdle, error = OT_ERROR_INVALID_STATE);
 
@@ -186,7 +196,7 @@
         sTransmitMode = kDiagTransmitModeIdle;
         otPlatRadioReceive(aInstance, sChannel);
     }
-    else if (strcmp(argv[0], "start") == 0)
+    else if (strcmp(aArgs[0], "start") == 0)
     {
         otEXPECT_ACTION(sTransmitMode == kDiagTransmitModeIdle, error = OT_ERROR_INVALID_STATE);
 
@@ -199,7 +209,7 @@
                  "sending %" PRId32 " diagnostic messages with %" PRIu32 " ms interval\r\nstatus 0x%02x\r\n",
                  sTxRequestedCount, sTxPeriod, error);
     }
-    else if (strcmp(argv[0], "carrier") == 0)
+    else if (strcmp(aArgs[0], "carrier") == 0)
     {
         otEXPECT_ACTION(sTransmitMode == kDiagTransmitModeIdle, error = OT_ERROR_INVALID_STATE);
 
@@ -210,26 +220,26 @@
         snprintf(aOutput, aOutputMaxLen, "sending carrier on channel %d with tx power %d\r\nstatus 0x%02x\r\n",
                  sChannel, sTxPower, error);
     }
-    else if (strcmp(argv[0], "interval") == 0)
+    else if (strcmp(aArgs[0], "interval") == 0)
     {
         long value;
 
-        otEXPECT_ACTION(argc == 2, error = OT_ERROR_INVALID_ARGS);
+        otEXPECT_ACTION(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
 
-        error = parseLong(argv[1], &value);
+        error = parseLong(aArgs[1], &value);
         otEXPECT(error == OT_ERROR_NONE);
         otEXPECT_ACTION(value > 0, error = OT_ERROR_INVALID_ARGS);
         sTxPeriod = (uint32_t)(value);
         snprintf(aOutput, aOutputMaxLen, "set diagnostic messages interval to %" PRIu32 " ms\r\nstatus 0x%02x\r\n",
                  sTxPeriod, error);
     }
-    else if (strcmp(argv[0], "count") == 0)
+    else if (strcmp(aArgs[0], "count") == 0)
     {
         long value;
 
-        otEXPECT_ACTION(argc == 2, error = OT_ERROR_INVALID_ARGS);
+        otEXPECT_ACTION(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
 
-        error = parseLong(argv[1], &value);
+        error = parseLong(aArgs[1], &value);
         otEXPECT(error == OT_ERROR_NONE);
         otEXPECT_ACTION((value > 0) || (value == -1), error = OT_ERROR_INVALID_ARGS);
         sTxRequestedCount = (uint32_t)(value);
@@ -243,9 +253,14 @@
 
 exit:
     appendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-static void processGpio(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+static otError processGpio(otInstance *aInstance,
+                           uint8_t     aArgsLength,
+                           char *      aArgs[],
+                           char *      aOutput,
+                           size_t      aOutputMaxLen)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -254,12 +269,12 @@
 
     otEXPECT_ACTION(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
 
-    if (argc == 1)
+    if (aArgsLength == 1)
     {
         uint32_t           value;
         nrf_gpio_pin_dir_t pindir;
 
-        error = parseLong(argv[0], &pinnum);
+        error = parseLong(aArgs[0], &pinnum);
         otEXPECT(error == OT_ERROR_NONE);
 
         pindir = nrf_gpio_pin_dir_get(pinnum);
@@ -275,40 +290,40 @@
 
         snprintf(aOutput, aOutputMaxLen, "gpio %d = %d\r\n", (uint8_t)pinnum, (uint8_t)value);
     }
-    else if (strcmp(argv[0], "set") == 0)
+    else if (strcmp(aArgs[0], "set") == 0)
     {
-        otEXPECT_ACTION(argc == 2, error = OT_ERROR_INVALID_ARGS);
-        error = parseLong(argv[1], &pinnum);
+        otEXPECT_ACTION(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
+        error = parseLong(aArgs[1], &pinnum);
         otEXPECT(error == OT_ERROR_NONE);
 
         nrf_gpio_pin_set(pinnum);
 
         snprintf(aOutput, aOutputMaxLen, "gpio %d = 1\r\n", (uint8_t)pinnum);
     }
-    else if (strcmp(argv[0], "clr") == 0)
+    else if (strcmp(aArgs[0], "clr") == 0)
     {
-        otEXPECT_ACTION(argc == 2, error = OT_ERROR_INVALID_ARGS);
-        error = parseLong(argv[1], &pinnum);
+        otEXPECT_ACTION(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
+        error = parseLong(aArgs[1], &pinnum);
         otEXPECT(error == OT_ERROR_NONE);
 
         nrf_gpio_pin_clear(pinnum);
 
         snprintf(aOutput, aOutputMaxLen, "gpio %d = 0\r\n", (uint8_t)pinnum);
     }
-    else if (strcmp(argv[0], "out") == 0)
+    else if (strcmp(aArgs[0], "out") == 0)
     {
-        otEXPECT_ACTION(argc == 2, error = OT_ERROR_INVALID_ARGS);
-        error = parseLong(argv[1], &pinnum);
+        otEXPECT_ACTION(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
+        error = parseLong(aArgs[1], &pinnum);
         otEXPECT(error == OT_ERROR_NONE);
 
         nrf_gpio_cfg_output(pinnum);
 
         snprintf(aOutput, aOutputMaxLen, "gpio %d: out\r\n", (uint8_t)pinnum);
     }
-    else if (strcmp(argv[0], "in") == 0)
+    else if (strcmp(aArgs[0], "in") == 0)
     {
-        otEXPECT_ACTION(argc == 2, error = OT_ERROR_INVALID_ARGS);
-        error = parseLong(argv[1], &pinnum);
+        otEXPECT_ACTION(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
+        error = parseLong(aArgs[1], &pinnum);
         otEXPECT(error == OT_ERROR_NONE);
 
         nrf_gpio_cfg_input(pinnum, NRF_GPIO_PIN_NOPULL);
@@ -322,18 +337,23 @@
 
 exit:
     appendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-static void processTemp(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+static otError processTemp(otInstance *aInstance,
+                           uint8_t     aArgsLength,
+                           char *      aArgs[],
+                           char *      aOutput,
+                           size_t      aOutputMaxLen)
 {
     OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError error = OT_ERROR_NONE;
     int32_t temperature;
 
     otEXPECT_ACTION(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
-    otEXPECT_ACTION(argc == 0, error = OT_ERROR_INVALID_ARGS);
+    otEXPECT_ACTION(aArgsLength == 0, error = OT_ERROR_INVALID_ARGS);
 
     temperature = nrf5TempGet();
 
@@ -343,9 +363,14 @@
 
 exit:
     appendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-static void processCcaThreshold(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+static otError processCcaThreshold(otInstance *aInstance,
+                                   uint8_t     aArgsLength,
+                                   char *      aArgs[],
+                                   char *      aOutput,
+                                   size_t      aOutputMaxLen)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -354,7 +379,7 @@
 
     otEXPECT_ACTION(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         nrf_802154_cca_cfg_get(&ccaConfig);
 
@@ -363,7 +388,7 @@
     else
     {
         long value;
-        error = parseLong(argv[0], &value);
+        error = parseLong(aArgs[0], &value);
         otEXPECT(error == OT_ERROR_NONE);
         otEXPECT_ACTION(value >= 0 && value <= 0xFF, error = OT_ERROR_INVALID_ARGS);
 
@@ -377,6 +402,7 @@
 
 exit:
     appendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
 const struct PlatformDiagCommand sCommands[] = {
@@ -388,23 +414,26 @@
     {"transmit", &processTransmit},
 };
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+otError otPlatDiagProcess(otInstance *aInstance,
+                          uint8_t     aArgsLength,
+                          char *      aArgs[],
+                          char *      aOutput,
+                          size_t      aOutputMaxLen)
 {
-    size_t i;
+    otError error = OT_ERROR_INVALID_COMMAND;
+    size_t  i;
 
     for (i = 0; i < otARRAY_LENGTH(sCommands); i++)
     {
-        if (strcmp(argv[0], sCommands[i].mName) == 0)
+        if (strcmp(aArgs[0], sCommands[i].mName) == 0)
         {
-            sCommands[i].mCommand(aInstance, argc - 1, argc > 1 ? &argv[1] : NULL, aOutput, aOutputMaxLen);
+            error = sCommands[i].mCommand(aInstance, aArgsLength - 1, aArgsLength > 1 ? &aArgs[1] : NULL, aOutput,
+                                          aOutputMaxLen);
             break;
         }
     }
 
-    if (i == otARRAY_LENGTH(sCommands))
-    {
-        snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-    }
+    return error;
 }
 
 void otPlatDiagModeSet(bool aMode)
diff --git a/examples/platforms/nrf528xx/src/flash.c b/examples/platforms/nrf528xx/src/flash.c
index bb3ae91..31d7af2 100644
--- a/examples/platforms/nrf528xx/src/flash.c
+++ b/examples/platforms/nrf528xx/src/flash.c
@@ -26,32 +26,49 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-
 #include <assert.h>
 #include <stdint.h>
 #include <string.h>
 
-#include <utils/code_utils.h>
-#include <utils/flash.h>
-#include <openthread/platform/alarm-milli.h>
-
 #include "platform-nrf5.h"
 
+/**
+ * @def PLATFORM_FLASH_PAGE_NUM
+ *
+ * Number of flash pages to use for OpenThread's non-volatile settings.
+ *
+ * @note This define applies only for MDK-ARM Keil toolchain configuration.
+ *
+ */
+#ifndef PLATFORM_FLASH_PAGE_NUM
+#define PLATFORM_FLASH_PAGE_NUM 4
+#endif
+
 #define FLASH_PAGE_ADDR_MASK 0xFFFFF000
 #define FLASH_PAGE_SIZE 4096
 
 static uint32_t sFlashDataStart;
 static uint32_t sFlashDataEnd;
+static uint32_t sSwapSize;
 
-static inline uint32_t mapAddress(uint32_t aAddress)
+static inline uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    return aAddress + sFlashDataStart;
+    uint32_t address;
+
+    address = sFlashDataStart + aOffset;
+
+    if (aSwapIndex)
+    {
+        address += sSwapSize;
+    }
+
+    return address;
 }
 
-otError utilsFlashInit(void)
+void otPlatFlashInit(otInstance *aInstance)
 {
+    OT_UNUSED_VARIABLE(aInstance);
+
 #if defined(__CC_ARM)
     // Temporary solution for Keil compiler.
     uint32_t const bootloaderAddr = NRF_UICR->NRFFW[0];
@@ -67,7 +84,7 @@
         sFlashDataEnd = pageSize * codeSize;
     }
 
-    sFlashDataStart = sFlashDataEnd - (pageSize * SETTINGS_CONFIG_PAGE_NUM);
+    sFlashDataStart = sFlashDataEnd - (pageSize * PLATFORM_FLASH_PAGE_NUM);
 
 #elif defined(__GNUC__) || defined(__ICCARM__)
     extern uint32_t __start_ot_flash_data;
@@ -82,75 +99,47 @@
     assert((sFlashDataStart % FLASH_PAGE_SIZE) == 0);
     assert((sFlashDataEnd % FLASH_PAGE_SIZE) == 0);
 
-    return OT_ERROR_NONE;
+    sSwapSize = ((sFlashDataEnd - sFlashDataStart) / FLASH_PAGE_SIZE / 2) * FLASH_PAGE_SIZE;
+    assert(sSwapSize > 0);
 }
 
-uint32_t utilsFlashGetSize(void)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
 {
-    return sFlashDataEnd - sFlashDataStart;
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return sSwapSize;
 }
 
-otError utilsFlashErasePage(uint32_t aAddress)
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
 {
-    otError error = OT_ERROR_NONE;
-    otEXPECT_ACTION(aAddress < utilsFlashGetSize(), error = OT_ERROR_INVALID_ARGS);
+    OT_UNUSED_VARIABLE(aInstance);
 
-    error = nrf5FlashPageErase(mapAddress(aAddress & FLASH_PAGE_ADDR_MASK));
+    otError error;
 
-exit:
-    return error;
-}
-
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    otError error = OT_ERROR_BUSY;
-
-    if (aTimeout == 0)
+    for (uint32_t offset = 0; offset < sSwapSize; offset += FLASH_PAGE_SIZE)
     {
-        if (!nrf5FlashIsBusy())
+        error = nrf5FlashPageErase(mapAddress(aSwapIndex, offset));
+        assert(error == OT_ERROR_NONE);
+
+        while (nrf5FlashIsBusy())
         {
-            error = OT_ERROR_NONE;
         }
     }
-    else
-    {
-        uint32_t startTime = otPlatAlarmMilliGetNow();
-
-        do
-        {
-            if (!nrf5FlashIsBusy())
-            {
-                error = OT_ERROR_NONE;
-                break;
-            }
-        } while (otPlatAlarmMilliGetNow() - startTime < aTimeout);
-    }
-
-    return error;
 }
 
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
 {
-    uint32_t result = 0;
-    otEXPECT(aData);
-    otEXPECT(aAddress < utilsFlashGetSize());
-    otEXPECT(aSize);
+    OT_UNUSED_VARIABLE(aInstance);
 
-    result = nrf5FlashWrite(mapAddress(aAddress), aData, aSize);
+    otError error;
 
-exit:
-    return result;
+    error = nrf5FlashWrite(mapAddress(aSwapIndex, aOffset), aData, aSize);
+    assert(error == OT_ERROR_NONE);
 }
 
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
 {
-    uint32_t result = 0;
-    otEXPECT(aData);
-    otEXPECT(aAddress < utilsFlashGetSize());
+    OT_UNUSED_VARIABLE(aInstance);
 
-    memcpy(aData, (uint8_t *)mapAddress(aAddress), aSize);
-    result = aSize;
-
-exit:
-    return result;
+    memcpy(aData, (uint8_t *)mapAddress(aSwapIndex, aOffset), aSize);
 }
diff --git a/examples/platforms/nrf528xx/src/flash_nosd.c b/examples/platforms/nrf528xx/src/flash_nosd.c
index 0be99d0..711ab38 100644
--- a/examples/platforms/nrf528xx/src/flash_nosd.c
+++ b/examples/platforms/nrf528xx/src/flash_nosd.c
@@ -26,22 +26,14 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-
-#include <assert.h>
 #include <stdint.h>
-#include <string.h>
-
-#include <utils/code_utils.h>
-#include <utils/flash.h>
 
 #include "platform-nrf5.h"
-#include "hal/nrf_nvmc.h"
+#include "drivers/include/nrfx_nvmc.h"
 
 otError nrf5FlashPageErase(uint32_t aAddress)
 {
-    nrf_nvmc_page_erase(aAddress);
+    nrfx_nvmc_page_erase(aAddress);
 
     return OT_ERROR_NONE;
 }
@@ -51,8 +43,9 @@
     return NRF_NVMC->READY != NVMC_READY_READY_Ready;
 }
 
-uint32_t nrf5FlashWrite(uint32_t aAddress, const uint8_t *aData, uint32_t aSize)
+otError nrf5FlashWrite(uint32_t aAddress, const uint8_t *aData, uint32_t aSize)
 {
-    nrf_nvmc_write_bytes(aAddress, aData, aSize);
-    return aSize;
+    nrfx_nvmc_bytes_write(aAddress, aData, aSize);
+
+    return OT_ERROR_NONE;
 }
diff --git a/examples/platforms/nrf528xx/src/flash_sd.c b/examples/platforms/nrf528xx/src/flash_sd.c
index 50d31ab..fbac9d3 100644
--- a/examples/platforms/nrf528xx/src/flash_sd.c
+++ b/examples/platforms/nrf528xx/src/flash_sd.c
@@ -36,13 +36,12 @@
 #include <openthread/platform/alarm-milli.h>
 
 #include <utils/code_utils.h>
-#include <utils/flash.h>
 
 #include "platform-nrf5.h"
 #include "softdevice.h"
 
 #define FLASH_PAGE_SIZE 4096
-#define FLASH_TIMEOUT 500
+#define FLASH_MAX_RETRY 5
 
 typedef enum
 {
@@ -100,58 +99,57 @@
 
 static void waitInState(SdFlashState state)
 {
-    uint32_t startTime = otPlatAlarmMilliGetNow();
-
     do
     {
         nrf_sdh_evts_poll();
 
-        if (sState != state)
-        {
-            break;
-        }
-    } while (otPlatAlarmMilliGetNow() - startTime < FLASH_TIMEOUT);
+    } while (sState == state);
 }
 
 static otError sdFlashSingleWrite(uint32_t aAddress, const uint8_t *aData, uint32_t aSize)
 {
     uint32_t retval;
-
-    nrf_sdh_suspend();
+    uint32_t maxRetry = FLASH_MAX_RETRY;
 
     do
     {
-        sState = FLASH_STATE_PENDING;
+        nrf_sdh_suspend();
 
-        retval = sd_flash_write((uint32_t *)aAddress, (uint32_t *)aData, aSize);
+        do
+        {
+            sState = FLASH_STATE_PENDING;
 
-        if (retval == NRF_SUCCESS)
+            retval = sd_flash_write((uint32_t *)aAddress, (uint32_t *)aData, aSize);
+
+            if (retval == NRF_SUCCESS)
+            {
+                break;
+            }
+            else if (retval == NRF_ERROR_BUSY)
+            {
+                sState = FLASH_STATE_WAITING_FOR_IDLE;
+            }
+            else
+            {
+                assert(false);
+            }
+
+            waitInState(FLASH_STATE_WAITING_FOR_IDLE);
+
+        } while (retval == NRF_ERROR_BUSY);
+
+        waitInState(FLASH_STATE_PENDING);
+
+        if (sState != FLASH_STATE_COMPLETE_SUCCESS)
         {
-            break;
-        }
-        else if (retval == NRF_ERROR_BUSY)
-        {
-            sState = FLASH_STATE_WAITING_FOR_IDLE;
-        }
-        else
-        {
-            assert(false);
+            retval = NRF_ERROR_INTERNAL;
         }
 
-        waitInState(FLASH_STATE_WAITING_FOR_IDLE);
+        sState = FLASH_STATE_IDLE;
 
-    } while (retval == NRF_ERROR_BUSY);
+        nrf_sdh_resume();
 
-    waitInState(FLASH_STATE_PENDING);
-
-    if (sState != FLASH_STATE_COMPLETE_SUCCESS)
-    {
-        retval = NRF_ERROR_INTERNAL;
-    }
-
-    sState = FLASH_STATE_IDLE;
-
-    nrf_sdh_resume();
+    } while (retval != NRF_SUCCESS && maxRetry--);
 
     return nrf5SdErrorToOtError(retval);
 }
@@ -159,42 +157,47 @@
 otError nrf5FlashPageErase(uint32_t aAddress)
 {
     uint32_t retval;
-
-    nrf_sdh_suspend();
+    uint32_t maxRetry = FLASH_MAX_RETRY;
 
     do
     {
-        sState = FLASH_STATE_PENDING;
+        nrf_sdh_suspend();
 
-        retval = sd_flash_page_erase(aAddress / FLASH_PAGE_SIZE);
+        do
+        {
+            sState = FLASH_STATE_PENDING;
 
-        if (retval == NRF_SUCCESS)
+            retval = sd_flash_page_erase(aAddress / FLASH_PAGE_SIZE);
+
+            if (retval == NRF_SUCCESS)
+            {
+                break;
+            }
+            else if (retval == NRF_ERROR_BUSY)
+            {
+                sState = FLASH_STATE_WAITING_FOR_IDLE;
+            }
+            else
+            {
+                assert(false);
+            }
+
+            waitInState(FLASH_STATE_WAITING_FOR_IDLE);
+
+        } while (retval == NRF_ERROR_BUSY);
+
+        waitInState(FLASH_STATE_PENDING);
+
+        if (sState != FLASH_STATE_COMPLETE_SUCCESS)
         {
-            break;
-        }
-        else if (retval == NRF_ERROR_BUSY)
-        {
-            sState = FLASH_STATE_WAITING_FOR_IDLE;
-        }
-        else
-        {
-            assert(false);
+            retval = NRF_ERROR_INTERNAL;
         }
 
-        waitInState(FLASH_STATE_WAITING_FOR_IDLE);
+        sState = FLASH_STATE_IDLE;
 
-    } while (retval == NRF_ERROR_BUSY);
+        nrf_sdh_resume();
 
-    waitInState(FLASH_STATE_PENDING);
-
-    if (sState != FLASH_STATE_COMPLETE_SUCCESS)
-    {
-        retval = NRF_ERROR_INTERNAL;
-    }
-
-    sState = FLASH_STATE_IDLE;
-
-    nrf_sdh_resume();
+    } while (retval != NRF_SUCCESS && maxRetry--);
 
     return nrf5SdErrorToOtError(retval);
 }
@@ -204,15 +207,14 @@
     return sState != FLASH_STATE_IDLE;
 }
 
-uint32_t nrf5FlashWrite(uint32_t aAddress, const uint8_t *aData, uint32_t aSize)
+otError nrf5FlashWrite(uint32_t aAddress, const uint8_t *aData, uint32_t aSize)
 {
     otError  error     = OT_ERROR_NONE;
-    uint32_t result    = 0;
     uint32_t remainder = (aAddress % sizeof(uint32_t));
     uint32_t blockSize;
     uint32_t blockValue;
 
-    otEXPECT(sState == FLASH_STATE_IDLE);
+    otEXPECT_ACTION(sState == FLASH_STATE_IDLE, error = OT_ERROR_BUSY);
 
     // Check if @p aAddress is aligned to full word size. If not, make additional
     // flash write at the beginning.
@@ -230,7 +232,6 @@
         aAddress += blockSize;
         aData += blockSize;
         aSize -= blockSize;
-        result += blockSize;
     }
 
     otEXPECT(aSize);
@@ -246,7 +247,6 @@
     aAddress += blockSize;
     aData += blockSize;
     aSize -= blockSize;
-    result += blockSize;
 
     // Store any additional bytes that didn't fit into middle block.
     if (remainder)
@@ -258,10 +258,8 @@
         error = sdFlashSingleWrite(aAddress, (uint8_t *)&blockValue, sizeof(blockValue) / sizeof(uint32_t));
 
         otEXPECT(error == OT_ERROR_NONE);
-
-        result += remainder;
     }
 
 exit:
-    return result;
+    return error;
 }
diff --git a/examples/platforms/nrf528xx/src/logging.c b/examples/platforms/nrf528xx/src/logging.c
index c8bdbde..9110f39 100644
--- a/examples/platforms/nrf528xx/src/logging.c
+++ b/examples/platforms/nrf528xx/src/logging.c
@@ -39,8 +39,7 @@
 
 #include <utils/logging_rtt.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 void nrf5LogInit(void)
 {
     utilsLogRttInit();
diff --git a/examples/platforms/nrf528xx/src/misc.c b/examples/platforms/nrf528xx/src/misc.c
index 6858f2e..740fc8d 100644
--- a/examples/platforms/nrf528xx/src/misc.c
+++ b/examples/platforms/nrf528xx/src/misc.c
@@ -32,6 +32,7 @@
 
 #include <nrf.h>
 
+#include "platform-nrf5-transport.h"
 #include "platform-nrf5.h"
 
 #if SOFTDEVICE_PRESENT
@@ -74,12 +75,16 @@
 {
     OT_UNUSED_VARIABLE(aInstance);
 
-#if OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
-    gPlatformPseudoResetWasRequested = true;
-    sResetReason                     = POWER_RESETREAS_SREQ_Msk;
-#else  // if OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
-    NVIC_SystemReset();
-#endif // else OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+    gPlatformPseudoResetWasRequested = nrf5TransportPseudoResetRequired();
+
+    if (gPlatformPseudoResetWasRequested)
+    {
+        sResetReason = POWER_RESETREAS_SREQ_Msk;
+    }
+    else
+    {
+        NVIC_SystemReset();
+    }
 }
 
 otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
diff --git a/examples/platforms/nrf528xx/src/platform-nrf5-transport.h b/examples/platforms/nrf528xx/src/platform-nrf5-transport.h
new file mode 100644
index 0000000..e10507f
--- /dev/null
+++ b/examples/platforms/nrf528xx/src/platform-nrf5-transport.h
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes the platform-specific transport initializers.
+ *
+ */
+
+#ifndef PLATFORM_NRF5_TRANSPORT_H_
+#define PLATFORM_NRF5_TRANSPORT_H_
+
+#include <stdbool.h>
+
+#include "transport-config.h"
+
+/**
+ * Initialization of transport.
+ *
+ */
+void nrf5TransportInit(bool aPseudoReset);
+
+/**
+ * Deinitialization of transport.
+ *
+ */
+void nrf5TransportDeinit(bool aPseudoReset);
+
+/**
+ * This function performs transport processing.
+ *
+ */
+void nrf5TransportProcess(void);
+
+/**
+ * This function returns true if transport driver should not be affected
+ * by reset. Otherwise, false is returned.
+ */
+bool nrf5TransportPseudoResetRequired(void);
+
+#endif
diff --git a/examples/platforms/nrf528xx/src/platform-nrf5.h b/examples/platforms/nrf528xx/src/platform-nrf5.h
index 4f4e3f7..339f0b9 100644
--- a/examples/platforms/nrf528xx/src/platform-nrf5.h
+++ b/examples/platforms/nrf528xx/src/platform-nrf5.h
@@ -41,34 +41,6 @@
 
 #include "platform-config.h"
 
-/**
- * Initialization of UART driver.
- *
- */
-void nrf5UartInit(void);
-
-/**
- * Deinitialization of UART driver.
- *
- */
-void nrf5UartDeinit(void);
-
-/**
- * Clear pending UART data.
- *
- */
-void nrf5UartClearPendingData(void);
-
-/**
- * This function performs UART driver processing.
- *
- */
-void nrf5UartProcess(void);
-
-/**
- * Initialization of Alarm driver.
- *
- */
 void nrf5AlarmInit(void);
 
 /**
@@ -120,23 +92,6 @@
 void nrf5LogDeinit(void);
 
 /**
- * Initialization of SPI Slave driver.
- *
- */
-void nrf5SpiSlaveInit(void);
-
-/**
- * Deinitialization of SPI Slave driver.
- *
- */
-void nrf5SpiSlaveDeinit(void);
-
-/**
- * Function for processing SPI Slave driver.
- */
-void nrf5SpiSlaveProcess(void);
-
-/**
  * Initialization of Misc module.
  *
  */
@@ -200,7 +155,7 @@
  * Function for writing data into flash.
  *
  */
-uint32_t nrf5FlashWrite(uint32_t aAddress, const uint8_t *aData, uint32_t aSize);
+otError nrf5FlashWrite(uint32_t aAddress, const uint8_t *aData, uint32_t aSize);
 
 /**
  * Initialization of temperature controller.
diff --git a/examples/platforms/nrf528xx/src/radio.c b/examples/platforms/nrf528xx/src/radio.c
index d97aaab..d8612ac 100644
--- a/examples/platforms/nrf528xx/src/radio.c
+++ b/examples/platforms/nrf528xx/src/radio.c
@@ -66,10 +66,14 @@
 #define SHORT_ADDRESS_SIZE    2            ///< Size of MAC short address.
 #define US_PER_MS             1000ULL      ///< Microseconds in millisecond.
 
-#define ACK_REQUEST_OFFSET    1            ///< Byte containing Ack request bit (+1 for frame length byte).
-#define ACK_REQUEST_BIT       (1 << 5)     ///< Ack request bit.
-#define FRAME_PENDING_OFFSET  1            ///< Byte containing pending bit (+1 for frame length byte).
-#define FRAME_PENDING_BIT     (1 << 4)     ///< Frame Pending bit.
+#define ACK_REQUEST_OFFSET       1         ///< Byte containing Ack request bit (+1 for frame length byte).
+#define ACK_REQUEST_BIT          (1 << 5)  ///< Ack request bit.
+#define FRAME_PENDING_OFFSET     1         ///< Byte containing pending bit (+1 for frame length byte).
+#define FRAME_PENDING_BIT        (1 << 4)  ///< Frame Pending bit.
+#define SECURITY_ENABLED_OFFSET  1         ///< Byte containing security enabled bit (+1 for frame length byte).
+#define SECURITY_ENABLED_BIT     (1 << 3)  ///< Security enabled bit.
+
+#define RSSI_SETTLE_TIME_US   40           ///< RSSI settle time in microseconds.
 
 #if defined(__ICCARM__)
 _Pragma("diag_suppress=Pe167")
@@ -118,6 +122,17 @@
 
 static uint32_t sPendingEvents;
 
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+static uint32_t        sMacFrameCounter;
+static uint8_t         sKeyId;
+static struct otMacKey sPrevKey;
+static struct otMacKey sCurrKey;
+static struct otMacKey sNextKey;
+static bool            sAckedWithSecEnhAck;
+static uint32_t        sAckFrameCounter;
+static uint8_t         sAckKeyId;
+#endif
+
 static void dataInit(void)
 {
     sDisabled = true;
@@ -189,6 +204,57 @@
     } while (__STREXW(pendingEvents, (uint32_t *)&sPendingEvents));
 }
 
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+static void txAckProcessSecurity(uint8_t *aAckFrame)
+{
+    otRadioFrame     ackFrame;
+    struct otMacKey *key = NULL;
+    uint8_t          keyId;
+
+    sAckedWithSecEnhAck = false;
+    otEXPECT(aAckFrame[SECURITY_ENABLED_OFFSET] & SECURITY_ENABLED_BIT);
+
+    memset(&ackFrame, 0, sizeof(ackFrame));
+    ackFrame.mPsdu   = &aAckFrame[1];
+    ackFrame.mLength = aAckFrame[0];
+
+    keyId = otMacFrameGetKeyId(&ackFrame);
+
+    otEXPECT(otMacFrameIsKeyIdMode1(&ackFrame) && keyId != 0);
+
+    if (keyId == sKeyId)
+    {
+        key = &sCurrKey;
+    }
+    else if (keyId == sKeyId - 1)
+    {
+        key = &sPrevKey;
+    }
+    else if (keyId == sKeyId + 1)
+    {
+        key = &sNextKey;
+    }
+    else
+    {
+        otEXPECT(false);
+    }
+
+    sAckFrameCounter    = sMacFrameCounter;
+    sAckKeyId           = keyId;
+    sAckedWithSecEnhAck = true;
+
+    ackFrame.mInfo.mTxInfo.mAesKey = key;
+
+    otMacFrameSetKeyId(&ackFrame, keyId);
+    otMacFrameSetFrameCounter(&ackFrame, sMacFrameCounter++);
+
+    otMacFrameProcessTransmitAesCcm(&ackFrame, &sExtAddress);
+
+exit:
+    return;
+}
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+
 #if !OPENTHREAD_CONFIG_ENABLE_PLATFORM_EUI64_CUSTOM_SOURCE
 void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
 {
@@ -413,6 +479,12 @@
 {
     OT_UNUSED_VARIABLE(aInstance);
 
+    // Ensure the RSSI measurement is done after RSSI settling time.
+    // This is necessary for the Channel Monitor feature which quickly switches between channels.
+    NRFX_DELAY_US(RSSI_SETTLE_TIME_US);
+
+    nrf_802154_rssi_measure_begin();
+
     return nrf_802154_rssi_last_get();
 }
 
@@ -420,7 +492,11 @@
 {
     OT_UNUSED_VARIABLE(aInstance);
 
-    return (otRadioCaps)(OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF);
+    return (otRadioCaps)(OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF |
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+                         OT_RADIO_CAPS_TRANSMIT_SEC |
+#endif
+                         OT_RADIO_CAPS_SLEEP_TO_TX);
 }
 
 bool otPlatRadioGetPromiscuous(otInstance *aInstance)
@@ -444,7 +520,7 @@
     nrf_802154_auto_pending_bit_set(aEnable);
 }
 
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -483,7 +559,7 @@
     return error;
 }
 
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
 
@@ -815,6 +891,18 @@
 
     sAckedWithFramePending = false;
 
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    // Inform if this frame was acknowledged with secured Enh-ACK.
+    if (p_data[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT && otMacFrameIsVersion2015(receivedFrame))
+    {
+        receivedFrame->mInfo.mRxInfo.mAckedWithSecEnhAck = sAckedWithSecEnhAck;
+        receivedFrame->mInfo.mRxInfo.mAckFrameCounter    = sAckFrameCounter;
+        receivedFrame->mInfo.mRxInfo.mAckKeyId           = sAckKeyId;
+    }
+
+    sAckedWithSecEnhAck = false;
+#endif
+
     otSysEventSignalPending();
 }
 
@@ -848,14 +936,22 @@
     }
 
     sAckedWithFramePending = false;
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    sAckedWithSecEnhAck = false;
+#endif
 
     setPendingEvent(kPendingEventReceiveFailed);
 }
 
-void nrf_802154_tx_ack_started(const uint8_t *p_data)
+void nrf_802154_tx_ack_started(uint8_t *p_data)
 {
     // Check if the frame pending bit is set in ACK frame.
     sAckedWithFramePending = p_data[FRAME_PENDING_OFFSET] & FRAME_PENDING_BIT;
+
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    // Update IE and secure Enh-ACK.
+    txAckProcessSecurity(p_data);
+#endif
 }
 
 void nrf_802154_transmitted_raw(const uint8_t *aFrame, uint8_t *aAckPsdu, int8_t aPower, uint8_t aLqi)
@@ -919,9 +1015,10 @@
 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
 void nrf_802154_tx_started(const uint8_t *aFrame)
 {
-    bool notifyFrameUpdated = false;
+    bool processSecurity = false;
     assert(aFrame == sTransmitPsdu);
 
+    // Update IE and secure transmit frame
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     if (sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0)
     {
@@ -937,14 +1034,30 @@
             *(++timeIe) = (uint8_t)(time & 0xff);
         }
 
-        notifyFrameUpdated = true;
+        processSecurity = true;
     }
 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 
-    if (notifyFrameUpdated)
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    otEXPECT(otMacFrameIsSecurityEnabled(&sTransmitFrame) && otMacFrameIsKeyIdMode1(&sTransmitFrame) &&
+             !sTransmitFrame.mInfo.mTxInfo.mIsSecurityProcessed);
+
+    sTransmitFrame.mInfo.mTxInfo.mAesKey = &sCurrKey;
+
+    if (!sTransmitFrame.mInfo.mTxInfo.mIsARetx)
     {
-        otMacFrameProcessTransmitAesCcm(&sTransmitFrame, &sExtAddress);
+        otMacFrameSetKeyId(&sTransmitFrame, sKeyId);
+        otMacFrameSetFrameCounter(&sTransmitFrame, sMacFrameCounter++);
     }
+
+    processSecurity = true;
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+
+    otEXPECT(processSecurity);
+    otMacFrameProcessTransmitAesCcm(&sTransmitFrame, &sExtAddress);
+
+exit:
+    return;
 }
 #endif
 
@@ -962,3 +1075,38 @@
 {
     return otRandomNonCryptoGetUint32();
 }
+
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+void otPlatRadioSetMacKey(otInstance *    aInstance,
+                          uint8_t         aKeyIdMode,
+                          uint8_t         aKeyId,
+                          const otMacKey *aPrevKey,
+                          const otMacKey *aCurrKey,
+                          const otMacKey *aNextKey)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aKeyIdMode);
+
+    assert(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL);
+
+    CRITICAL_REGION_ENTER();
+
+    sKeyId = aKeyId;
+    memcpy(sPrevKey.m8, aPrevKey->m8, OT_MAC_KEY_SIZE);
+    memcpy(sCurrKey.m8, aCurrKey->m8, OT_MAC_KEY_SIZE);
+    memcpy(sNextKey.m8, aNextKey->m8, OT_MAC_KEY_SIZE);
+
+    CRITICAL_REGION_EXIT();
+}
+
+void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    CRITICAL_REGION_ENTER();
+
+    sMacFrameCounter = aMacFrameCounter;
+
+    CRITICAL_REGION_EXIT();
+}
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
diff --git a/examples/platforms/nrf528xx/src/spi-slave.c b/examples/platforms/nrf528xx/src/spi-slave.c
deleted file mode 100644
index 481b4b2..0000000
--- a/examples/platforms/nrf528xx/src/spi-slave.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements the OpenThread platform abstraction for SPIS communication.
- *
- */
-#include <assert.h>
-
-#include <utils/code_utils.h>
-#include <openthread/platform/spi-slave.h>
-
-#include <hal/nrf_gpio.h>
-#include <nrfx.h>
-#include <nrfx_spis.h>
-#include <platform-nrf5.h>
-
-#include "openthread-system.h"
-
-#if (SPIS_AS_SERIAL_TRANSPORT == 1)
-
-/**
- *  SPI Slave transaction variables.
- */
-static void *                                    sContext                = NULL;
-static uint8_t *                                 sOutputBuf              = NULL;
-static uint16_t                                  sOutputBufLen           = 0;
-static uint8_t *                                 sInputBuf               = NULL;
-static uint16_t                                  sInputBufLen            = 0;
-static bool                                      sRequestTransactionFlag = false;
-static bool                                      sFurtherProcessingFlag  = false;
-static otPlatSpiSlaveTransactionProcessCallback  sProcessCallback        = NULL;
-static otPlatSpiSlaveTransactionCompleteCallback sCompleteCallback       = NULL;
-static const nrfx_spis_t                         sSpiSlaveInstance       = NRFX_SPIS_INSTANCE(SPIS_INSTANCE);
-
-static void spisEventHandler(nrfx_spis_evt_t const *aEvent, void *aContext)
-{
-    OT_UNUSED_VARIABLE(aContext);
-
-    switch (aEvent->evt_type)
-    {
-    case NRFX_SPIS_BUFFERS_SET_DONE:
-        if (sRequestTransactionFlag)
-        {
-            // Host IRQ pin is active low.
-            nrf_gpio_pin_clear(SPIS_PIN_HOST_IRQ);
-        }
-        break;
-
-    case NRFX_SPIS_XFER_DONE:
-        // Ensure Host IRQ pin is set.
-        nrf_gpio_pin_set(SPIS_PIN_HOST_IRQ);
-
-        // Execute application callback.
-        if (sCompleteCallback(sContext, sOutputBuf, sOutputBufLen, sInputBuf, sInputBufLen, aEvent->rx_amount))
-        {
-            // Further processing is required.
-            sFurtherProcessingFlag = true;
-
-            otSysEventSignalPending();
-        }
-        break;
-
-    default:
-        assert(false);
-        break;
-    }
-}
-
-void nrf5SpiSlaveInit(void)
-{
-    // Intentionally empty.
-}
-
-void nrf5SpiSlaveDeinit(void)
-{
-    sOutputBuf              = NULL;
-    sOutputBufLen           = 0;
-    sInputBuf               = NULL;
-    sInputBufLen            = 0;
-    sRequestTransactionFlag = false;
-
-    otPlatSpiSlaveDisable();
-}
-
-void nrf5SpiSlaveProcess(void)
-{
-    otEXPECT(sFurtherProcessingFlag == true);
-
-    // Clear further processing flag.
-    sFurtherProcessingFlag = false;
-
-    // Perform any further processing if necessary.
-    sProcessCallback(sContext);
-
-exit:
-    return;
-}
-
-otError otPlatSpiSlaveEnable(otPlatSpiSlaveTransactionCompleteCallback aCompleteCallback,
-                             otPlatSpiSlaveTransactionProcessCallback  aProcessCallback,
-                             void *                                    aContext)
-{
-    otError            result = OT_ERROR_NONE;
-    nrfx_err_t         error  = NRFX_SUCCESS;
-    nrfx_spis_config_t config = NRFX_SPIS_DEFAULT_CONFIG;
-
-    assert(aCompleteCallback != NULL);
-    assert(aProcessCallback != NULL);
-
-    // Check if SPI Slave interface is already enabled.
-    otEXPECT_ACTION(sCompleteCallback == NULL, error = OT_ERROR_ALREADY);
-
-    config.csn_pin      = SPIS_PIN_CSN;
-    config.miso_pin     = SPIS_PIN_MISO;
-    config.mosi_pin     = SPIS_PIN_MOSI;
-    config.sck_pin      = SPIS_PIN_SCK;
-    config.mode         = SPIS_MODE;
-    config.bit_order    = SPIS_BIT_ORDER;
-    config.irq_priority = SPIS_IRQ_PRIORITY;
-
-    error = nrfx_spis_init(&sSpiSlaveInstance, &config, spisEventHandler, NULL);
-    assert(error == NRFX_SUCCESS);
-
-    // Set up Host IRQ pin.
-    nrf_gpio_pin_set(SPIS_PIN_HOST_IRQ);
-    nrf_gpio_cfg_output(SPIS_PIN_HOST_IRQ);
-
-    // Set proper callback and context.
-    sProcessCallback  = aProcessCallback;
-    sCompleteCallback = aCompleteCallback;
-    sContext          = aContext;
-
-exit:
-    return result;
-}
-
-void otPlatSpiSlaveDisable(void)
-{
-    nrfx_spis_uninit(&sSpiSlaveInstance);
-}
-
-otError otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf,
-                                         uint16_t aOutputBufLen,
-                                         uint8_t *aInputBuf,
-                                         uint16_t aInputBufLen,
-                                         bool     aRequestTransactionFlag)
-{
-    otError            result           = OT_ERROR_NONE;
-    nrfx_err_t         error            = NRFX_SUCCESS;
-    nrf_spis_semstat_t semaphore_status = nrf_spis_semaphore_status_get(sSpiSlaveInstance.p_reg);
-
-    assert(sCompleteCallback != NULL);
-
-    otEXPECT_ACTION(((semaphore_status != NRF_SPIS_SEMSTAT_SPIS) && (semaphore_status != NRF_SPIS_SEMSTAT_CPUPENDING)),
-                    error = OT_ERROR_BUSY);
-
-    if (aOutputBuf != NULL)
-    {
-        sOutputBuf    = aOutputBuf;
-        sOutputBufLen = aOutputBufLen;
-    }
-
-    if (aInputBuf != NULL)
-    {
-        sInputBuf    = aInputBuf;
-        sInputBufLen = aInputBufLen;
-    }
-
-    sRequestTransactionFlag = aRequestTransactionFlag;
-
-    error = nrfx_spis_buffers_set(&sSpiSlaveInstance, sOutputBuf, sOutputBufLen, sInputBuf, sInputBufLen);
-    assert(error == NRFX_SUCCESS);
-
-exit:
-    return result;
-}
-
-#endif // SPIS_AS_SERIAL_TRANSPORT == 1
diff --git a/examples/platforms/nrf528xx/src/system.c b/examples/platforms/nrf528xx/src/system.c
index 61c7754..eaea7cc 100644
--- a/examples/platforms/nrf528xx/src/system.c
+++ b/examples/platforms/nrf528xx/src/system.c
@@ -39,9 +39,10 @@
 
 #include "openthread-system.h"
 #include "platform-fem.h"
+#include "platform-nrf5-transport.h"
 #include "platform-nrf5.h"
-#include <drivers/clock/nrf_drv_clock.h>
 #include <nrf.h>
+#include <nrf_drv_clock.h>
 
 #include <openthread/config.h>
 
@@ -86,31 +87,18 @@
 
     nrf_drv_clock_init();
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
     nrf5LogInit();
 #endif
     nrf5AlarmInit();
     nrf5RandomInit();
     if (!gPlatformPseudoResetWasRequested)
     {
-#if ((UART_AS_SERIAL_TRANSPORT == 1) || (USB_CDC_AS_SERIAL_TRANSPORT == 1))
-        nrf5UartInit();
-#endif
 #if NRF52840_XXAA
         nrf5CryptoInit();
 #endif
     }
-    else
-    {
-#if ((UART_AS_SERIAL_TRANSPORT == 1) || (USB_CDC_AS_SERIAL_TRANSPORT == 1))
-        nrf5UartClearPendingData();
-#endif
-    }
-
-#if (SPIS_AS_SERIAL_TRANSPORT == 1)
-    nrf5SpiSlaveInit();
-#endif
+    nrf5TransportInit(gPlatformPseudoResetWasRequested);
     nrf5MiscInit();
     nrf5RadioInit();
     nrf5TempInit();
@@ -127,22 +115,16 @@
     nrf5TempDeinit();
     nrf5RadioDeinit();
     nrf5MiscDeinit();
-#if (SPIS_AS_SERIAL_TRANSPORT == 1)
-    nrf5SpiSlaveDeinit();
-#endif
     if (!gPlatformPseudoResetWasRequested)
     {
 #if NRF52840_XXAA
         nrf5CryptoDeinit();
 #endif
-#if ((UART_AS_SERIAL_TRANSPORT == 1) || (USB_CDC_AS_SERIAL_TRANSPORT == 1))
-        nrf5UartDeinit();
-#endif
     }
+    nrf5TransportDeinit(gPlatformPseudoResetWasRequested);
     nrf5RandomDeinit();
     nrf5AlarmDeinit();
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
     nrf5LogDeinit();
 #endif
 
@@ -159,12 +141,7 @@
 void otSysProcessDrivers(otInstance *aInstance)
 {
     nrf5RadioProcess(aInstance);
-#if ((UART_AS_SERIAL_TRANSPORT == 1) || (USB_CDC_AS_SERIAL_TRANSPORT == 1))
-    nrf5UartProcess();
-#endif
-#if (SPIS_AS_SERIAL_TRANSPORT == 1)
-    nrf5SpiSlaveProcess();
-#endif
+    nrf5TransportProcess();
     nrf5TempProcess();
     nrf5AlarmProcess(aInstance);
 }
diff --git a/examples/platforms/nrf528xx/src/temp.c b/examples/platforms/nrf528xx/src/temp.c
index bb72274..7550439 100644
--- a/examples/platforms/nrf528xx/src/temp.c
+++ b/examples/platforms/nrf528xx/src/temp.c
@@ -34,7 +34,7 @@
 #include <utils/code_utils.h>
 
 #include "platform-nrf5.h"
-#include <drivers/radio/platform/temperature/nrf_802154_temperature.h>
+#include <nrf_802154_temperature.h>
 
 #if SOFTDEVICE_PRESENT
 #include "softdevice.h"
diff --git a/examples/platforms/nrf528xx/src/transport/spi-slave.c b/examples/platforms/nrf528xx/src/transport/spi-slave.c
new file mode 100644
index 0000000..2c8219f
--- /dev/null
+++ b/examples/platforms/nrf528xx/src/transport/spi-slave.c
@@ -0,0 +1,205 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for SPIS communication.
+ *
+ */
+#include <assert.h>
+
+#include <utils/code_utils.h>
+#include <openthread/platform/spi-slave.h>
+
+#include "platform-nrf5-transport.h"
+#include <hal/nrf_gpio.h>
+#include <nrfx.h>
+#include <nrfx_spis.h>
+
+#include "openthread-system.h"
+
+#if (SPIS_AS_SERIAL_TRANSPORT == 1)
+
+/**
+ *  SPI Slave transaction variables.
+ */
+static void *                                    sContext                = NULL;
+static uint8_t *                                 sOutputBuf              = NULL;
+static uint16_t                                  sOutputBufLen           = 0;
+static uint8_t *                                 sInputBuf               = NULL;
+static uint16_t                                  sInputBufLen            = 0;
+static bool                                      sRequestTransactionFlag = false;
+static bool                                      sFurtherProcessingFlag  = false;
+static otPlatSpiSlaveTransactionProcessCallback  sProcessCallback        = NULL;
+static otPlatSpiSlaveTransactionCompleteCallback sCompleteCallback       = NULL;
+static const nrfx_spis_t                         sSpiSlaveInstance       = NRFX_SPIS_INSTANCE(SPIS_INSTANCE);
+
+static void spisEventHandler(nrfx_spis_evt_t const *aEvent, void *aContext)
+{
+    OT_UNUSED_VARIABLE(aContext);
+
+    switch (aEvent->evt_type)
+    {
+    case NRFX_SPIS_BUFFERS_SET_DONE:
+        if (sRequestTransactionFlag)
+        {
+            // Host IRQ pin is active low.
+            nrf_gpio_pin_clear(SPIS_PIN_HOST_IRQ);
+        }
+        break;
+
+    case NRFX_SPIS_XFER_DONE:
+        // Ensure Host IRQ pin is set.
+        nrf_gpio_pin_set(SPIS_PIN_HOST_IRQ);
+
+        // Execute application callback.
+        if (sCompleteCallback(sContext, sOutputBuf, sOutputBufLen, sInputBuf, sInputBufLen, aEvent->rx_amount))
+        {
+            // Further processing is required.
+            sFurtherProcessingFlag = true;
+
+            otSysEventSignalPending();
+        }
+        break;
+
+    default:
+        assert(false);
+        break;
+    }
+}
+
+void nrf5SpiSlaveInit(void)
+{
+    // Intentionally empty.
+}
+
+void nrf5SpiSlaveDeinit(void)
+{
+    sOutputBuf              = NULL;
+    sOutputBufLen           = 0;
+    sInputBuf               = NULL;
+    sInputBufLen            = 0;
+    sRequestTransactionFlag = false;
+
+    otPlatSpiSlaveDisable();
+}
+
+void nrf5SpiSlaveProcess(void)
+{
+    otEXPECT(sFurtherProcessingFlag == true);
+
+    // Clear further processing flag.
+    sFurtherProcessingFlag = false;
+
+    // Perform any further processing if necessary.
+    sProcessCallback(sContext);
+
+exit:
+    return;
+}
+
+otError otPlatSpiSlaveEnable(otPlatSpiSlaveTransactionCompleteCallback aCompleteCallback,
+                             otPlatSpiSlaveTransactionProcessCallback  aProcessCallback,
+                             void *                                    aContext)
+{
+    otError            result = OT_ERROR_NONE;
+    nrfx_err_t         error  = NRFX_SUCCESS;
+    nrfx_spis_config_t config = NRFX_SPIS_DEFAULT_CONFIG;
+
+    assert(aCompleteCallback != NULL);
+    assert(aProcessCallback != NULL);
+
+    // Check if SPI Slave interface is already enabled.
+    otEXPECT_ACTION(sCompleteCallback == NULL, error = OT_ERROR_ALREADY);
+
+    config.csn_pin      = SPIS_PIN_CSN;
+    config.miso_pin     = SPIS_PIN_MISO;
+    config.mosi_pin     = SPIS_PIN_MOSI;
+    config.sck_pin      = SPIS_PIN_SCK;
+    config.mode         = SPIS_MODE;
+    config.bit_order    = SPIS_BIT_ORDER;
+    config.irq_priority = SPIS_IRQ_PRIORITY;
+
+    error = nrfx_spis_init(&sSpiSlaveInstance, &config, spisEventHandler, NULL);
+    assert(error == NRFX_SUCCESS);
+
+    // Set up Host IRQ pin.
+    nrf_gpio_pin_set(SPIS_PIN_HOST_IRQ);
+    nrf_gpio_cfg_output(SPIS_PIN_HOST_IRQ);
+
+    // Set proper callback and context.
+    sProcessCallback  = aProcessCallback;
+    sCompleteCallback = aCompleteCallback;
+    sContext          = aContext;
+
+exit:
+    return result;
+}
+
+void otPlatSpiSlaveDisable(void)
+{
+    nrfx_spis_uninit(&sSpiSlaveInstance);
+}
+
+otError otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf,
+                                         uint16_t aOutputBufLen,
+                                         uint8_t *aInputBuf,
+                                         uint16_t aInputBufLen,
+                                         bool     aRequestTransactionFlag)
+{
+    otError            result           = OT_ERROR_NONE;
+    nrfx_err_t         error            = NRFX_SUCCESS;
+    nrf_spis_semstat_t semaphore_status = nrf_spis_semaphore_status_get(sSpiSlaveInstance.p_reg);
+
+    assert(sCompleteCallback != NULL);
+
+    otEXPECT_ACTION(((semaphore_status != NRF_SPIS_SEMSTAT_SPIS) && (semaphore_status != NRF_SPIS_SEMSTAT_CPUPENDING)),
+                    error = OT_ERROR_BUSY);
+
+    if (aOutputBuf != NULL)
+    {
+        sOutputBuf    = aOutputBuf;
+        sOutputBufLen = aOutputBufLen;
+    }
+
+    if (aInputBuf != NULL)
+    {
+        sInputBuf    = aInputBuf;
+        sInputBufLen = aInputBufLen;
+    }
+
+    sRequestTransactionFlag = aRequestTransactionFlag;
+
+    error = nrfx_spis_buffers_set(&sSpiSlaveInstance, sOutputBuf, sOutputBufLen, sInputBuf, sInputBufLen);
+    assert(error == NRFX_SUCCESS);
+
+exit:
+    return result;
+}
+
+#endif // SPIS_AS_SERIAL_TRANSPORT == 1
diff --git a/examples/platforms/nrf528xx/src/transport/transport-drivers.h b/examples/platforms/nrf528xx/src/transport/transport-drivers.h
new file mode 100644
index 0000000..fd46d00
--- /dev/null
+++ b/examples/platforms/nrf528xx/src/transport/transport-drivers.h
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes UART/USB and SPI driver initializers.
+ *
+ */
+
+#ifndef TRANSPORT_DRIVERS_H_
+#define TRANSPORT_DRIVERS_H_
+
+/**
+ * Initialization of UART driver.
+ *
+ */
+void nrf5UartInit(void);
+
+/**
+ * Deinitialization of UART driver.
+ *
+ */
+void nrf5UartDeinit(void);
+
+/**
+ * Clear pending UART data.
+ *
+ */
+void nrf5UartClearPendingData(void);
+
+/**
+ * This function performs UART driver processing.
+ *
+ */
+void nrf5UartProcess(void);
+
+/**
+ * Initialization of SPI Slave driver.
+ *
+ */
+void nrf5SpiSlaveInit(void);
+
+/**
+ * Deinitialization of SPI Slave driver.
+ *
+ */
+void nrf5SpiSlaveDeinit(void);
+
+/**
+ * Function for processing SPI Slave driver.
+ */
+void nrf5SpiSlaveProcess(void);
+
+#endif
diff --git a/examples/platforms/nrf528xx/src/transport/transport.c b/examples/platforms/nrf528xx/src/transport/transport.c
new file mode 100644
index 0000000..2ffe205
--- /dev/null
+++ b/examples/platforms/nrf528xx/src/transport/transport.c
@@ -0,0 +1,92 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the nrf5 platform transport initialization functions.
+ *
+ */
+
+#include <openthread/platform/toolchain.h>
+
+#include "platform-nrf5-transport.h"
+
+#include "transport-drivers.h"
+
+void nrf5TransportInit(bool aPseudoReset)
+{
+#if ((UART_AS_SERIAL_TRANSPORT == 1) || (USB_CDC_AS_SERIAL_TRANSPORT == 1))
+    if (!aPseudoReset)
+    {
+        nrf5UartInit();
+    }
+    else
+    {
+        nrf5UartClearPendingData();
+    }
+#endif
+
+#if (SPIS_AS_SERIAL_TRANSPORT == 1)
+    OT_UNUSED_VARIABLE(aPseudoReset);
+    nrf5SpiSlaveInit();
+#endif
+}
+
+void nrf5TransportDeinit(bool aPseudoReset)
+{
+#if ((UART_AS_SERIAL_TRANSPORT == 1) || (USB_CDC_AS_SERIAL_TRANSPORT == 1))
+    if (!aPseudoReset)
+    {
+        nrf5UartDeinit();
+    }
+#endif
+
+#if (SPIS_AS_SERIAL_TRANSPORT == 1)
+    OT_UNUSED_VARIABLE(aPseudoReset);
+    nrf5SpiSlaveDeinit();
+#endif
+}
+
+void nrf5TransportProcess(void)
+{
+#if ((UART_AS_SERIAL_TRANSPORT == 1) || (USB_CDC_AS_SERIAL_TRANSPORT == 1))
+    nrf5UartProcess();
+#endif
+#if (SPIS_AS_SERIAL_TRANSPORT == 1)
+    nrf5SpiSlaveProcess();
+#endif
+}
+
+bool nrf5TransportPseudoResetRequired(void)
+{
+#if OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+    return true;
+#else // if OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+    return false;
+#endif
+}
diff --git a/examples/platforms/nrf528xx/src/transport/uart.c b/examples/platforms/nrf528xx/src/transport/uart.c
new file mode 100644
index 0000000..8fc18fb
--- /dev/null
+++ b/examples/platforms/nrf528xx/src/transport/uart.c
@@ -0,0 +1,345 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for UART communication.
+ *
+ */
+
+#include <openthread-core-config.h>
+#include <openthread/config.h>
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <utils/code_utils.h>
+#include <openthread/platform/toolchain.h>
+#include <openthread/platform/uart.h>
+
+#include "openthread-system.h"
+
+#include "platform-nrf5-transport.h"
+#include <hal/nrf_gpio.h>
+#include <hal/nrf_uart.h>
+#include <nrf_drv_clock.h>
+
+#if (UART_AS_SERIAL_TRANSPORT == 1)
+
+bool sUartEnabled = false;
+
+/**
+ *  UART TX buffer variables.
+ */
+static volatile const uint8_t *sTransmitBuffer = NULL;
+static volatile uint16_t       sTransmitLength = 0;
+static volatile bool           sTransmitDone   = 0;
+
+/**
+ *  UART RX ring buffer variables.
+ */
+static uint8_t           sReceiveBuffer[UART_RX_BUFFER_SIZE];
+static volatile uint16_t sReceiveHead = 0;
+static volatile uint16_t sReceiveTail = 0;
+
+/**
+ * Function for checking if RX buffer is full.
+ *
+ * @retval true  RX buffer is full.
+ * @retval false RX buffer is not full.
+ */
+static __INLINE bool isRxBufferFull()
+{
+    uint16_t next = (sReceiveHead + 1) % UART_RX_BUFFER_SIZE;
+    return (next == sReceiveTail);
+}
+
+/**
+ * Function for checking if RX buffer is empty.
+ *
+ * @retval true  RX buffer is empty.
+ * @retval false RX buffer is not empty.
+ */
+static __INLINE bool isRxBufferEmpty()
+{
+    uint16_t head = sReceiveHead;
+    return (head == sReceiveTail);
+}
+
+/**
+ * Function for notifying application about new bytes received.
+ */
+static void processReceive(void)
+{
+    // Set head position to not be changed during read procedure.
+    uint16_t head = sReceiveHead;
+    uint8_t *position;
+
+    otEXPECT(isRxBufferEmpty() == false);
+
+    // In case head roll back to the beginning of the buffer, notify about left
+    // bytes from the end of the buffer.
+    if (head < sReceiveTail)
+    {
+        position = &sReceiveBuffer[sReceiveTail];
+        otPlatUartReceived(position, (UART_RX_BUFFER_SIZE - sReceiveTail));
+        sReceiveTail = 0;
+    }
+
+    // Notify about received bytes.
+    if (head > sReceiveTail)
+    {
+        position = &sReceiveBuffer[sReceiveTail];
+        otPlatUartReceived(position, (head - sReceiveTail));
+        sReceiveTail = head;
+    }
+
+exit:
+    return;
+}
+
+otError otPlatUartFlush(void)
+{
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * Function for notifying application about transmission being done.
+ */
+static void processTransmit(void)
+{
+    otEXPECT(sTransmitBuffer != NULL);
+
+    if (sTransmitDone)
+    {
+        // Clear Transmition transaction and notify application.
+        sTransmitBuffer = NULL;
+        sTransmitLength = 0;
+        sTransmitDone   = false;
+        otPlatUartSendDone();
+    }
+
+exit:
+    return;
+}
+
+void nrf5UartProcess(void)
+{
+    processReceive();
+    processTransmit();
+}
+
+void nrf5UartInit(void)
+{
+    // Intentionally empty.
+}
+
+void nrf5UartClearPendingData(void)
+{
+    // Intentionally empty.
+}
+
+void nrf5UartDeinit(void)
+{
+    if (sUartEnabled)
+    {
+        otPlatUartDisable();
+    }
+}
+
+otError otPlatUartEnable(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(sUartEnabled == false, error = OT_ERROR_ALREADY);
+
+    // Set up TX and RX pins.
+    nrf_gpio_pin_set(UART_PIN_TX);
+    nrf_gpio_cfg_output(UART_PIN_TX);
+    nrf_gpio_cfg_input(UART_PIN_RX, NRF_GPIO_PIN_NOPULL);
+    nrf_uart_txrx_pins_set(UART_INSTANCE, UART_PIN_TX, UART_PIN_RX);
+
+#if (UART_HWFC_ENABLED == 1)
+    // Set up CTS and RTS pins.
+    nrf_gpio_cfg_input(UART_PIN_CTS, NRF_GPIO_PIN_NOPULL);
+    nrf_gpio_pin_set(UART_PIN_RTS);
+    nrf_gpio_cfg_output(UART_PIN_RTS);
+    nrf_uart_hwfc_pins_set(UART_INSTANCE, UART_PIN_RTS, UART_PIN_CTS);
+
+    nrf_uart_configure(UART_INSTANCE, UART_PARITY, NRF_UART_HWFC_ENABLED);
+#else
+    nrf_uart_configure(UART_INSTANCE, UART_PARITY, NRF_UART_HWFC_DISABLED);
+#endif
+
+    // Configure baudrate.
+    nrf_uart_baudrate_set(UART_INSTANCE, UART_BAUDRATE);
+
+    // Clear UART specific events.
+    nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
+    nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR);
+    nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
+
+    // Enable interrupts for TX.
+    nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
+
+    // Enable interrupts for RX.
+    nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
+
+    // Configure NVIC to handle UART interrupts.
+    NVIC_SetPriority(UART_IRQN, UART_IRQ_PRIORITY);
+    NVIC_ClearPendingIRQ(UART_IRQN);
+    NVIC_EnableIRQ(UART_IRQN);
+
+    // Start HFCLK
+    nrf_drv_clock_hfclk_request(NULL);
+
+    while (!nrf_drv_clock_hfclk_is_running())
+    {
+    }
+
+    // Enable UART instance, and start RX on it.
+    nrf_uart_enable(UART_INSTANCE);
+    nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTRX);
+
+    sUartEnabled = true;
+
+exit:
+    return error;
+}
+
+otError otPlatUartDisable(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(sUartEnabled == true, error = OT_ERROR_ALREADY);
+
+    // Disable NVIC interrupt.
+    NVIC_DisableIRQ(UART_IRQN);
+    NVIC_ClearPendingIRQ(UART_IRQN);
+    NVIC_SetPriority(UART_IRQN, 0);
+
+    // Disable interrupts for TX.
+    nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
+
+    // Disable interrupts for RX.
+    nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
+
+    // Disable UART instance.
+    nrf_uart_disable(UART_INSTANCE);
+
+    // Release HF clock.
+    nrf_drv_clock_hfclk_release();
+
+    sUartEnabled = false;
+
+exit:
+    return error;
+}
+
+otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(sTransmitBuffer == NULL, error = OT_ERROR_BUSY);
+
+    // Set up transmit buffer and its size without counting first triggered byte.
+    sTransmitBuffer = aBuf;
+    sTransmitLength = aBufLength - 1;
+
+    // Initiate Transmission process.
+    nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
+    nrf_uart_txd_set(UART_INSTANCE, *sTransmitBuffer++);
+    nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTTX);
+
+exit:
+    return error;
+}
+
+/**
+ * Interrupt handler of UART0 peripherial.
+ */
+void UARTE0_UART0_IRQHandler(void)
+{
+    // Check if any error has been detected.
+    if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_ERROR))
+    {
+        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR);
+    }
+    else if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_RXDRDY))
+    {
+        // Clear RXDRDY event.
+        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
+
+        // Read byte from the UART buffer.
+        uint8_t byte = nrf_uart_rxd_get(UART_INSTANCE);
+
+        if (!isRxBufferFull())
+        {
+            sReceiveBuffer[sReceiveHead] = byte;
+            sReceiveHead                 = (sReceiveHead + 1) % UART_RX_BUFFER_SIZE;
+
+            otSysEventSignalPending();
+        }
+    }
+
+    if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY))
+    {
+        // Clear TXDRDY event.
+        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
+
+        // Send any more bytes if available or call application about TX done.
+        if (sTransmitLength)
+        {
+            nrf_uart_txd_set(UART_INSTANCE, *sTransmitBuffer++);
+            sTransmitLength--;
+        }
+        else
+        {
+            sTransmitDone = true;
+            nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STOPTX);
+
+            otSysEventSignalPending();
+        }
+    }
+}
+
+#endif // UART_AS_SERIAL_TRANSPORT == 1
+
+/**
+ * The UART driver weak functions definition.
+ *
+ */
+OT_TOOL_WEAK void otPlatUartSendDone(void)
+{
+}
+
+OT_TOOL_WEAK void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    OT_UNUSED_VARIABLE(aBuf);
+    OT_UNUSED_VARIABLE(aBufLength);
+}
diff --git a/examples/platforms/nrf528xx/src/transport/usb-cdc-uart.c b/examples/platforms/nrf528xx/src/transport/usb-cdc-uart.c
new file mode 100644
index 0000000..31e53a0
--- /dev/null
+++ b/examples/platforms/nrf528xx/src/transport/usb-cdc-uart.c
@@ -0,0 +1,370 @@
+/*
+ *  Copyright (c) 2017, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread platform abstraction for UART communication over USB CDC.
+ *
+ */
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
+#include <openthread-core-config.h>
+#include <openthread/config.h>
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <common/logging.hpp>
+#include <openthread-system.h>
+#include <utils/code_utils.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+#include <openthread/platform/misc.h>
+#include <openthread/platform/uart.h>
+
+#include "platform-nrf5-transport.h"
+
+#include "app_usbd.h"
+#include "app_usbd_serial_num.h"
+#include "nrf_dfu_trigger_usb.h"
+#include "nrf_drv_clock.h"
+#include "nrf_drv_power.h"
+#include "class/cdc/acm/app_usbd_cdc_acm.h"
+
+#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
+
+static void cdcAcmUserEventHandler(app_usbd_class_inst_t const *aInstance, app_usbd_cdc_acm_user_event_t aEvent);
+
+#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
+
+#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
+#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
+
+APP_USBD_CDC_ACM_GLOBAL_DEF(sAppCdcAcm,
+                            cdcAcmUserEventHandler,
+                            USB_CDC_ACM_COMM_INTERFACE,
+                            USB_CDC_ACM_DATA_INTERFACE,
+                            CDC_ACM_COMM_EPIN,
+                            CDC_ACM_DATA_EPIN,
+                            CDC_ACM_DATA_EPOUT,
+                            APP_USBD_CDC_COMM_PROTOCOL_NONE);
+
+// Rx buffer length must by multiple of NRF_DRV_USBD_EPSIZE.
+static char sRxBuffer[NRF_DRV_USBD_EPSIZE * ((UART_RX_BUFFER_SIZE + NRF_DRV_USBD_EPSIZE - 1) / NRF_DRV_USBD_EPSIZE)];
+
+static struct
+{
+    const uint8_t *mTxBuffer;
+    uint16_t       mTxSize;
+    size_t         mReceivedDataSize;
+    bool           mUartEnabled;
+    bool           mLastConnectionStatus;
+    uint32_t       mOpenTimestamp;
+    volatile bool  mConnected;
+    volatile bool  mReadyToStart;
+    volatile bool  mTransferInProgress;
+    volatile bool  mTransferDone;
+    volatile bool  mReceiveDone;
+} sUsbState;
+
+static void cdcAcmUserEventHandler(app_usbd_class_inst_t const *aCdcAcmInstance, app_usbd_cdc_acm_user_event_t aEvent)
+{
+    app_usbd_cdc_acm_t const *cdcAcmClass = app_usbd_cdc_acm_class_get(aCdcAcmInstance);
+
+    switch (aEvent)
+    {
+    case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
+        // Setup first transfer.
+        (void)app_usbd_cdc_acm_read_any(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer));
+        sUsbState.mOpenTimestamp = otPlatAlarmMilliGetNow();
+        break;
+
+    case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
+        break;
+
+    case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
+        sUsbState.mTransferDone = true;
+        break;
+
+    case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
+        sUsbState.mReceiveDone = true;
+        // Get amount of data received.
+        sUsbState.mReceivedDataSize = app_usbd_cdc_acm_rx_size(cdcAcmClass);
+        break;
+
+    default:
+        break;
+    }
+}
+
+static void usbdIsrHandler(app_usbd_internal_evt_t const *const aEvent, bool aQueued)
+{
+    (void)aEvent;
+    (void)aQueued;
+
+    otSysEventSignalPending();
+}
+
+static void usbdUserEventHandler(app_usbd_event_type_t aEvent)
+{
+    switch (aEvent)
+    {
+    case APP_USBD_EVT_STOPPED:
+        app_usbd_disable();
+        break;
+
+    case APP_USBD_EVT_POWER_DETECTED:
+        // Workaround for missing port open event.
+        sAppCdcAcm.specific.p_data->ctx.line_state = 0;
+
+        sUsbState.mConnected = true;
+        break;
+
+    case APP_USBD_EVT_POWER_REMOVED:
+        sUsbState.mConnected = false;
+        break;
+
+    case APP_USBD_EVT_POWER_READY:
+        sUsbState.mReadyToStart = true;
+        break;
+
+    default:
+        break;
+    }
+}
+
+static bool hasPortOpenDelayPassed(void)
+{
+    int32_t timeDiff = otPlatAlarmMilliGetNow() - sUsbState.mOpenTimestamp;
+
+    return (timeDiff < 0) || (timeDiff > USB_HOST_UART_CONFIG_DELAY_MS);
+}
+
+static bool isPortOpened(void)
+{
+    uint32_t value;
+
+    if (app_usbd_cdc_acm_line_state_get(&sAppCdcAcm, APP_USBD_CDC_ACM_LINE_STATE_DTR, &value) == NRF_SUCCESS)
+    {
+        return (value != 0) && hasPortOpenDelayPassed();
+    }
+
+    return false;
+}
+
+static void processConnection(void)
+{
+    bool connectionStatus = sUsbState.mUartEnabled && sUsbState.mConnected;
+
+    if (sUsbState.mLastConnectionStatus != connectionStatus)
+    {
+        sUsbState.mLastConnectionStatus = connectionStatus;
+
+        if (connectionStatus)
+        {
+            if (!nrf_drv_usbd_is_enabled())
+            {
+                app_usbd_enable();
+            }
+        }
+        else
+        {
+            if (nrf_drv_usbd_is_started())
+            {
+                app_usbd_stop();
+            }
+            else
+            {
+                app_usbd_disable();
+            }
+        }
+    }
+
+    // Provide some delay so the OS can re-enumerate the device in case of reset.
+    if (sUsbState.mReadyToStart)
+    {
+        sUsbState.mReadyToStart = false;
+
+        if (nrf_drv_usbd_is_enabled())
+        {
+            app_usbd_start();
+        }
+    }
+}
+
+static void processReceive(void)
+{
+    if (sUsbState.mReceiveDone)
+    {
+        if (sUsbState.mReceivedDataSize != 0)
+        {
+            otPlatUartReceived((const uint8_t *)sRxBuffer, sUsbState.mReceivedDataSize);
+            sUsbState.mReceivedDataSize = 0;
+        }
+
+        // Setup next transfer.
+        if (app_usbd_cdc_acm_read_any(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer)) == NRF_SUCCESS)
+        {
+            sUsbState.mReceiveDone = false;
+        }
+    }
+}
+
+static void processTransmit(void)
+{
+    // If some data was requested to send while port was closed, send it now.
+    if ((sUsbState.mTxBuffer != NULL) && isPortOpened())
+    {
+        if (app_usbd_cdc_acm_write(&sAppCdcAcm, sUsbState.mTxBuffer, sUsbState.mTxSize) == NRF_SUCCESS)
+        {
+            sUsbState.mTransferInProgress = true;
+            sUsbState.mTxBuffer           = NULL;
+            sUsbState.mTxSize             = 0;
+        }
+    }
+    else if (sUsbState.mTransferDone)
+    {
+        sUsbState.mTransferDone       = false;
+        sUsbState.mTransferInProgress = false;
+
+        otPlatUartSendDone();
+    }
+}
+
+void nrf5UartInit(void)
+{
+    static const app_usbd_config_t usbdConfig = {
+        .ev_state_proc  = usbdUserEventHandler,
+        .ev_isr_handler = usbdIsrHandler,
+    };
+
+    memset((void *)&sUsbState, 0, sizeof(sUsbState));
+
+    app_usbd_serial_num_generate();
+
+    ret_code_t ret = app_usbd_init(&usbdConfig);
+    assert(ret == NRF_SUCCESS);
+
+#if NRF_MODULE_ENABLED(APP_USBD_NRF_DFU_TRIGGER)
+    ret = nrf_dfu_trigger_usb_init();
+    assert(ret == NRF_SUCCESS);
+#endif // NRF_MODULE_ENABLED(APP_USBD_NRF_DFU_TRIGGER)
+
+    app_usbd_class_inst_t const *cdcAcmInstance = app_usbd_cdc_acm_class_inst_get(&sAppCdcAcm);
+    ret                                         = app_usbd_class_append(cdcAcmInstance);
+    assert(ret == NRF_SUCCESS);
+
+    ret = app_usbd_power_events_enable();
+    assert(ret == NRF_SUCCESS);
+}
+
+void nrf5UartDeinit(void)
+{
+    if (nrf_drv_usbd_is_started())
+    {
+        app_usbd_stop();
+
+        while (app_usbd_event_queue_process())
+        {
+        }
+    }
+    else if (nrf_drv_usbd_is_enabled())
+    {
+        app_usbd_disable();
+    }
+
+    app_usbd_class_remove_all();
+    app_usbd_uninit();
+}
+
+void nrf5UartClearPendingData(void)
+{
+    sUsbState.mTransferInProgress = false;
+    sUsbState.mTxBuffer           = NULL;
+    sUsbState.mTxSize             = 0;
+}
+
+void nrf5UartProcess(void)
+{
+    while (app_usbd_event_queue_process())
+    {
+    }
+
+    processConnection();
+    processReceive();
+    processTransmit();
+}
+
+otError otPlatUartEnable(void)
+{
+    sUsbState.mUartEnabled = true;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartDisable(void)
+{
+    sUsbState.mUartEnabled = false;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(sUsbState.mTransferInProgress == false, error = OT_ERROR_BUSY);
+    otEXPECT_ACTION(sUsbState.mTxBuffer == NULL, error = OT_ERROR_BUSY);
+
+    if (!isPortOpened())
+    {
+        // If port is closed, queue the message until it can be sent.
+        sUsbState.mTxBuffer = aBuf;
+        sUsbState.mTxSize   = aBufLength;
+    }
+    else
+    {
+        otEXPECT_ACTION(app_usbd_cdc_acm_write(&sAppCdcAcm, aBuf, aBufLength) == NRF_SUCCESS, error = OT_ERROR_FAILED);
+        sUsbState.mTransferInProgress = true;
+    }
+
+exit:
+
+    return error;
+}
+
+otError otPlatUartFlush(void)
+{
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
diff --git a/examples/platforms/nrf528xx/src/uart.c b/examples/platforms/nrf528xx/src/uart.c
deleted file mode 100644
index e4c3131..0000000
--- a/examples/platforms/nrf528xx/src/uart.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements the OpenThread platform abstraction for UART communication.
- *
- */
-
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <utils/code_utils.h>
-#include <openthread/platform/toolchain.h>
-#include <openthread/platform/uart.h>
-
-#include "openthread-system.h"
-
-#include "platform-nrf5.h"
-#include <drivers/clock/nrf_drv_clock.h>
-#include <hal/nrf_gpio.h>
-#include <hal/nrf_uart.h>
-
-#if (UART_AS_SERIAL_TRANSPORT == 1)
-
-bool sUartEnabled = false;
-
-/**
- *  UART TX buffer variables.
- */
-static const uint8_t *sTransmitBuffer = NULL;
-static uint16_t       sTransmitLength = 0;
-static bool           sTransmitDone   = 0;
-
-/**
- *  UART RX ring buffer variables.
- */
-static uint8_t  sReceiveBuffer[UART_RX_BUFFER_SIZE];
-static uint16_t sReceiveHead = 0;
-static uint16_t sReceiveTail = 0;
-
-/**
- * Function for checking if RX buffer is full.
- *
- * @retval true  RX buffer is full.
- * @retval false RX buffer is not full.
- */
-static __INLINE bool isRxBufferFull()
-{
-    uint16_t next = (sReceiveHead + 1) % UART_RX_BUFFER_SIZE;
-    return (next == sReceiveTail);
-}
-
-/**
- * Function for checking if RX buffer is empty.
- *
- * @retval true  RX buffer is empty.
- * @retval false RX buffer is not empty.
- */
-static __INLINE bool isRxBufferEmpty()
-{
-    return (sReceiveHead == sReceiveTail);
-}
-
-/**
- * Function for notifying application about new bytes received.
- */
-static void processReceive(void)
-{
-    // Set head position to not be changed during read procedure.
-    uint16_t head = sReceiveHead;
-
-    otEXPECT(isRxBufferEmpty() == false);
-
-    // In case head roll back to the beginning of the buffer, notify about left
-    // bytes from the end of the buffer.
-    if (head < sReceiveTail)
-    {
-        otPlatUartReceived(&sReceiveBuffer[sReceiveTail], (UART_RX_BUFFER_SIZE - sReceiveTail));
-        sReceiveTail = 0;
-    }
-
-    // Notify about received bytes.
-    if (head > sReceiveTail)
-    {
-        otPlatUartReceived(&sReceiveBuffer[sReceiveTail], (head - sReceiveTail));
-        sReceiveTail = head;
-    }
-
-exit:
-    return;
-}
-
-otError otPlatUartFlush(void)
-{
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-/**
- * Function for notifying application about transmission being done.
- */
-static void processTransmit(void)
-{
-    otEXPECT(sTransmitBuffer != NULL);
-
-    if (sTransmitDone)
-    {
-        // Clear Transmition transaction and notify application.
-        sTransmitBuffer = NULL;
-        sTransmitLength = 0;
-        sTransmitDone   = false;
-        otPlatUartSendDone();
-    }
-
-exit:
-    return;
-}
-
-void nrf5UartProcess(void)
-{
-    processReceive();
-    processTransmit();
-}
-
-void nrf5UartInit(void)
-{
-    // Intentionally empty.
-}
-
-void nrf5UartClearPendingData(void)
-{
-    // Intentionally empty.
-}
-
-void nrf5UartDeinit(void)
-{
-    if (sUartEnabled)
-    {
-        otPlatUartDisable();
-    }
-}
-
-otError otPlatUartEnable(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    otEXPECT_ACTION(sUartEnabled == false, error = OT_ERROR_ALREADY);
-
-    // Set up TX and RX pins.
-    nrf_gpio_pin_set(UART_PIN_TX);
-    nrf_gpio_cfg_output(UART_PIN_TX);
-    nrf_gpio_cfg_input(UART_PIN_RX, NRF_GPIO_PIN_NOPULL);
-    nrf_uart_txrx_pins_set(UART_INSTANCE, UART_PIN_TX, UART_PIN_RX);
-
-#if (UART_HWFC_ENABLED == 1)
-    // Set up CTS and RTS pins.
-    nrf_gpio_cfg_input(UART_PIN_CTS, NRF_GPIO_PIN_NOPULL);
-    nrf_gpio_pin_set(UART_PIN_RTS);
-    nrf_gpio_cfg_output(UART_PIN_RTS);
-    nrf_uart_hwfc_pins_set(UART_INSTANCE, UART_PIN_RTS, UART_PIN_CTS);
-
-    nrf_uart_configure(UART_INSTANCE, UART_PARITY, NRF_UART_HWFC_ENABLED);
-#else
-    nrf_uart_configure(UART_INSTANCE, UART_PARITY, NRF_UART_HWFC_DISABLED);
-#endif
-
-    // Configure baudrate.
-    nrf_uart_baudrate_set(UART_INSTANCE, UART_BAUDRATE);
-
-    // Clear UART specific events.
-    nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
-    nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR);
-    nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
-
-    // Enable interrupts for TX.
-    nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
-
-    // Enable interrupts for RX.
-    nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
-
-    // Configure NVIC to handle UART interrupts.
-    NVIC_SetPriority(UART_IRQN, UART_IRQ_PRIORITY);
-    NVIC_ClearPendingIRQ(UART_IRQN);
-    NVIC_EnableIRQ(UART_IRQN);
-
-    // Start HFCLK
-    nrf_drv_clock_hfclk_request(NULL);
-
-    while (!nrf_drv_clock_hfclk_is_running())
-    {
-    }
-
-    // Enable UART instance, and start RX on it.
-    nrf_uart_enable(UART_INSTANCE);
-    nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTRX);
-
-    sUartEnabled = true;
-
-exit:
-    return error;
-}
-
-otError otPlatUartDisable(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    otEXPECT_ACTION(sUartEnabled == true, error = OT_ERROR_ALREADY);
-
-    // Disable NVIC interrupt.
-    NVIC_DisableIRQ(UART_IRQN);
-    NVIC_ClearPendingIRQ(UART_IRQN);
-    NVIC_SetPriority(UART_IRQN, 0);
-
-    // Disable interrupts for TX.
-    nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
-
-    // Disable interrupts for RX.
-    nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
-
-    // Disable UART instance.
-    nrf_uart_disable(UART_INSTANCE);
-
-    // Release HF clock.
-    nrf_drv_clock_hfclk_release();
-
-    sUartEnabled = false;
-
-exit:
-    return error;
-}
-
-otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
-{
-    otError error = OT_ERROR_NONE;
-
-    otEXPECT_ACTION(sTransmitBuffer == NULL, error = OT_ERROR_BUSY);
-
-    // Set up transmit buffer and its size without counting first triggered byte.
-    sTransmitBuffer = aBuf;
-    sTransmitLength = aBufLength - 1;
-
-    // Initiate Transmission process.
-    nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
-    nrf_uart_txd_set(UART_INSTANCE, *sTransmitBuffer++);
-    nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTTX);
-
-exit:
-    return error;
-}
-
-/**
- * Interrupt handler of UART0 peripherial.
- */
-void UARTE0_UART0_IRQHandler(void)
-{
-    // Check if any error has been detected.
-    if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_ERROR))
-    {
-        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR);
-    }
-    else if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_RXDRDY))
-    {
-        // Clear RXDRDY event.
-        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
-
-        // Read byte from the UART buffer.
-        uint8_t byte = nrf_uart_rxd_get(UART_INSTANCE);
-
-        if (!isRxBufferFull())
-        {
-            sReceiveBuffer[sReceiveHead] = byte;
-            sReceiveHead                 = (sReceiveHead + 1) % UART_RX_BUFFER_SIZE;
-
-            otSysEventSignalPending();
-        }
-    }
-
-    if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY))
-    {
-        // Clear TXDRDY event.
-        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
-
-        // Send any more bytes if available or call application about TX done.
-        if (sTransmitLength)
-        {
-            nrf_uart_txd_set(UART_INSTANCE, *sTransmitBuffer++);
-            sTransmitLength--;
-        }
-        else
-        {
-            sTransmitDone = true;
-            nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STOPTX);
-
-            otSysEventSignalPending();
-        }
-    }
-}
-
-#endif // UART_AS_SERIAL_TRANSPORT == 1
-
-/**
- * The UART driver weak functions definition.
- *
- */
-OT_TOOL_WEAK void otPlatUartSendDone(void)
-{
-}
-
-OT_TOOL_WEAK void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength)
-{
-    OT_UNUSED_VARIABLE(aBuf);
-    OT_UNUSED_VARIABLE(aBufLength);
-}
diff --git a/examples/platforms/nrf528xx/src/usb-cdc-uart.c b/examples/platforms/nrf528xx/src/usb-cdc-uart.c
deleted file mode 100644
index 48e0ce3..0000000
--- a/examples/platforms/nrf528xx/src/usb-cdc-uart.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- *  Copyright (c) 2017, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements the OpenThread platform abstraction for UART communication over USB CDC.
- *
- */
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic ignored "-Wpedantic"
-#endif
-
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include <common/logging.hpp>
-#include <openthread-system.h>
-#include <utils/code_utils.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/diag.h>
-#include <openthread/platform/misc.h>
-#include <openthread/platform/uart.h>
-
-#include "platform-nrf5.h"
-
-#include "drivers/clock/nrf_drv_clock.h"
-#include "drivers/power/nrf_drv_power.h"
-#include "libraries/usb/app_usbd.h"
-#include "libraries/usb/app_usbd_serial_num.h"
-#include "libraries/usb/class/cdc/acm/app_usbd_cdc_acm.h"
-#include "libraries/usb/nrf_dfu_trigger_usb.h"
-
-#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
-
-static void cdcAcmUserEventHandler(app_usbd_class_inst_t const *aInstance, app_usbd_cdc_acm_user_event_t aEvent);
-
-#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
-
-#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
-#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
-
-APP_USBD_CDC_ACM_GLOBAL_DEF(sAppCdcAcm,
-                            cdcAcmUserEventHandler,
-                            USB_CDC_ACM_COMM_INTERFACE,
-                            USB_CDC_ACM_DATA_INTERFACE,
-                            CDC_ACM_COMM_EPIN,
-                            CDC_ACM_DATA_EPIN,
-                            CDC_ACM_DATA_EPOUT,
-                            APP_USBD_CDC_COMM_PROTOCOL_NONE);
-
-// Rx buffer length must by multiple of NRF_DRV_USBD_EPSIZE.
-static char sRxBuffer[NRF_DRV_USBD_EPSIZE * ((UART_RX_BUFFER_SIZE + NRF_DRV_USBD_EPSIZE - 1) / NRF_DRV_USBD_EPSIZE)];
-
-static struct
-{
-    const uint8_t *mTxBuffer;
-    uint16_t       mTxSize;
-    size_t         mReceivedDataSize;
-    bool           mUartEnabled;
-    bool           mLastConnectionStatus;
-    uint32_t       mOpenTimestamp;
-    volatile bool  mConnected;
-    volatile bool  mReadyToStart;
-    volatile bool  mTransferInProgress;
-    volatile bool  mTransferDone;
-    volatile bool  mReceiveDone;
-} sUsbState;
-
-static void cdcAcmUserEventHandler(app_usbd_class_inst_t const *aCdcAcmInstance, app_usbd_cdc_acm_user_event_t aEvent)
-{
-    app_usbd_cdc_acm_t const *cdcAcmClass = app_usbd_cdc_acm_class_get(aCdcAcmInstance);
-
-    switch (aEvent)
-    {
-    case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
-        // Setup first transfer.
-        (void)app_usbd_cdc_acm_read_any(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer));
-        sUsbState.mOpenTimestamp = otPlatAlarmMilliGetNow();
-        break;
-
-    case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
-        break;
-
-    case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
-        sUsbState.mTransferDone = true;
-        break;
-
-    case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
-        sUsbState.mReceiveDone = true;
-        // Get amount of data received.
-        sUsbState.mReceivedDataSize = app_usbd_cdc_acm_rx_size(cdcAcmClass);
-        break;
-
-    default:
-        break;
-    }
-}
-
-static void usbdIsrHandler(app_usbd_internal_evt_t const *const aEvent, bool aQueued)
-{
-    (void)aEvent;
-    (void)aQueued;
-
-    otSysEventSignalPending();
-}
-
-static void usbdUserEventHandler(app_usbd_event_type_t aEvent)
-{
-    switch (aEvent)
-    {
-    case APP_USBD_EVT_STOPPED:
-        app_usbd_disable();
-        break;
-
-    case APP_USBD_EVT_POWER_DETECTED:
-        // Workaround for missing port open event.
-        sAppCdcAcm.specific.p_data->ctx.line_state = 0;
-
-        sUsbState.mConnected = true;
-        break;
-
-    case APP_USBD_EVT_POWER_REMOVED:
-        sUsbState.mConnected = false;
-        break;
-
-    case APP_USBD_EVT_POWER_READY:
-        sUsbState.mReadyToStart = true;
-        break;
-
-    default:
-        break;
-    }
-}
-
-static bool hasPortOpenDelayPassed(void)
-{
-    int32_t timeDiff = otPlatAlarmMilliGetNow() - sUsbState.mOpenTimestamp;
-
-    return (timeDiff < 0) || (timeDiff > USB_HOST_UART_CONFIG_DELAY_MS);
-}
-
-static bool isPortOpened(void)
-{
-    uint32_t value;
-
-    if (app_usbd_cdc_acm_line_state_get(&sAppCdcAcm, APP_USBD_CDC_ACM_LINE_STATE_DTR, &value) == NRF_SUCCESS)
-    {
-        return (value != 0) && hasPortOpenDelayPassed();
-    }
-
-    return false;
-}
-
-static void processConnection(void)
-{
-    bool connectionStatus = sUsbState.mUartEnabled && sUsbState.mConnected;
-
-    if (sUsbState.mLastConnectionStatus != connectionStatus)
-    {
-        sUsbState.mLastConnectionStatus = connectionStatus;
-
-        if (connectionStatus)
-        {
-            if (!nrf_drv_usbd_is_enabled())
-            {
-                app_usbd_enable();
-            }
-        }
-        else
-        {
-            if (nrf_drv_usbd_is_started())
-            {
-                app_usbd_stop();
-            }
-            else
-            {
-                app_usbd_disable();
-            }
-        }
-    }
-
-    // Provide some delay so the OS can re-enumerate the device in case of reset.
-    if (sUsbState.mReadyToStart)
-    {
-        sUsbState.mReadyToStart = false;
-
-        if (nrf_drv_usbd_is_enabled())
-        {
-            app_usbd_start();
-        }
-    }
-}
-
-static void processReceive(void)
-{
-    if (sUsbState.mReceiveDone)
-    {
-        if (sUsbState.mReceivedDataSize != 0)
-        {
-            otPlatUartReceived((const uint8_t *)sRxBuffer, sUsbState.mReceivedDataSize);
-            sUsbState.mReceivedDataSize = 0;
-        }
-
-        // Setup next transfer.
-        if (app_usbd_cdc_acm_read_any(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer)) == NRF_SUCCESS)
-        {
-            sUsbState.mReceiveDone = false;
-        }
-    }
-}
-
-static void processTransmit(void)
-{
-    // If some data was requested to send while port was closed, send it now.
-    if ((sUsbState.mTxBuffer != NULL) && isPortOpened())
-    {
-        if (app_usbd_cdc_acm_write(&sAppCdcAcm, sUsbState.mTxBuffer, sUsbState.mTxSize) == NRF_SUCCESS)
-        {
-            sUsbState.mTransferInProgress = true;
-            sUsbState.mTxBuffer           = NULL;
-            sUsbState.mTxSize             = 0;
-        }
-    }
-    else if (sUsbState.mTransferDone)
-    {
-        sUsbState.mTransferDone       = false;
-        sUsbState.mTransferInProgress = false;
-
-        otPlatUartSendDone();
-    }
-}
-
-void nrf5UartInit(void)
-{
-    static const app_usbd_config_t usbdConfig = {
-        .ev_state_proc  = usbdUserEventHandler,
-        .ev_isr_handler = usbdIsrHandler,
-    };
-
-    memset((void *)&sUsbState, 0, sizeof(sUsbState));
-
-    app_usbd_serial_num_generate();
-
-    ret_code_t ret = app_usbd_init(&usbdConfig);
-    assert(ret == NRF_SUCCESS);
-
-#if NRF_MODULE_ENABLED(APP_USBD_NRF_DFU_TRIGGER)
-    ret = nrf_dfu_trigger_usb_init();
-    assert(ret == NRF_SUCCESS);
-#endif // NRF_MODULE_ENABLED(APP_USBD_NRF_DFU_TRIGGER)
-
-    app_usbd_class_inst_t const *cdcAcmInstance = app_usbd_cdc_acm_class_inst_get(&sAppCdcAcm);
-    ret                                         = app_usbd_class_append(cdcAcmInstance);
-    assert(ret == NRF_SUCCESS);
-
-    ret = app_usbd_power_events_enable();
-    assert(ret == NRF_SUCCESS);
-}
-
-void nrf5UartDeinit(void)
-{
-    if (nrf_drv_usbd_is_started())
-    {
-        app_usbd_stop();
-
-        while (app_usbd_event_queue_process())
-        {
-        }
-    }
-    else if (nrf_drv_usbd_is_enabled())
-    {
-        app_usbd_disable();
-    }
-
-    app_usbd_class_remove_all();
-    app_usbd_uninit();
-}
-
-void nrf5UartClearPendingData(void)
-{
-    sUsbState.mTransferInProgress = false;
-    sUsbState.mTxBuffer           = NULL;
-    sUsbState.mTxSize             = 0;
-}
-
-void nrf5UartProcess(void)
-{
-    while (app_usbd_event_queue_process())
-    {
-    }
-
-    processConnection();
-    processReceive();
-    processTransmit();
-}
-
-otError otPlatUartEnable(void)
-{
-    sUsbState.mUartEnabled = true;
-
-    return OT_ERROR_NONE;
-}
-
-otError otPlatUartDisable(void)
-{
-    sUsbState.mUartEnabled = false;
-
-    return OT_ERROR_NONE;
-}
-
-otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
-{
-    otError error = OT_ERROR_NONE;
-
-    otEXPECT_ACTION(sUsbState.mTransferInProgress == false, error = OT_ERROR_BUSY);
-    otEXPECT_ACTION(sUsbState.mTxBuffer == NULL, error = OT_ERROR_BUSY);
-
-    if (!isPortOpened())
-    {
-        // If port is closed, queue the message until it can be sent.
-        sUsbState.mTxBuffer = aBuf;
-        sUsbState.mTxSize   = aBufLength;
-    }
-    else
-    {
-        otEXPECT_ACTION(app_usbd_cdc_acm_write(&sAppCdcAcm, aBuf, aBufLength) == NRF_SUCCESS, error = OT_ERROR_FAILED);
-        sUsbState.mTransferInProgress = true;
-    }
-
-exit:
-
-    return error;
-}
-
-otError otPlatUartFlush(void)
-{
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
diff --git a/examples/platforms/posix/CMakeLists.txt b/examples/platforms/posix/CMakeLists.txt
deleted file mode 100644
index b4d7229..0000000
--- a/examples/platforms/posix/CMakeLists.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-#  Copyright (c) 2019, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-set(OT_PLATFORM_LIB "openthread-posix" PARENT_SCOPE)
-
-if(NOT OT_CONFIG)
-    set(OT_CONFIG "openthread-core-posix-config.h")
-    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
-endif()
-
-list(APPEND OT_PLATFORM_DEFINES
-    "OPENTHREAD_EXAMPLES_POSIX=1"
-    "OPENTHREAD_POSIX=1"
-    "OPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
-)
-set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
-
-list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
-
-add_library(openthread-posix
-    alarm.c
-    diag.c
-    entropy.c
-    flash.c
-    logging.c
-    misc.c
-    radio.c
-    spi-stubs.c
-    system.c
-    uart-posix.c
-    sim/alarm-sim.c
-    sim/platform-sim.c
-    $<TARGET_OBJECTS:openthread-platform-utils>
-)
-
-find_library(LIBRT rt)
-if(LIBRT)
-    target_link_libraries(openthread-posix PRIVATE ${LIBRT})
-endif()
-
-target_link_libraries(openthread-posix PRIVATE openthread-platform-utils)
-
-target_compile_definitions(openthread-posix PUBLIC ${OT_PLATFORM_DEFINES})
-
-target_include_directories(openthread-posix PRIVATE
-    ${OT_PUBLIC_INCLUDES}
-    ${OT_PRIVATE_INCLUDES}
-    ${PROJECT_SOURCE_DIR}/examples/platforms
-    ${PROJECT_SOURCE_DIR}/src/core
-)
diff --git a/examples/platforms/posix/Makefile.am b/examples/platforms/posix/Makefile.am
deleted file mode 100644
index fe9e3dc..0000000
--- a/examples/platforms/posix/Makefile.am
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-#  Copyright (c) 2016, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
-
-lib_LIBRARIES                             = libopenthread-posix.a
-
-libopenthread_posix_a_CPPFLAGS            = \
-    -I$(top_srcdir)/include                 \
-    -I$(top_srcdir)/examples/platforms      \
-    -I$(top_srcdir)/src/core                \
-    -D_GNU_SOURCE                           \
-    $(NULL)
-
-PLATFORM_SOURCES                          = \
-    alarm.c                                 \
-    diag.c                                  \
-    entropy.c                               \
-    flash.c                                 \
-    logging.c                               \
-    misc.c                                  \
-    openthread-core-posix-config.h          \
-    platform-posix.h                        \
-    radio.c                                 \
-    spi-stubs.c                             \
-    system.c                                \
-    uart-posix.c                            \
-    sim/alarm-sim.c                         \
-    sim/platform-sim.c                      \
-    $(NULL)
-
-libopenthread_posix_a_SOURCES             = \
-    $(PLATFORM_SOURCES)                     \
-    $(NULL)
-
-PRETTY_FILES                              = \
-    $(PLATFORM_SOURCES)                     \
-    $(NULL)
-
-Dash                                      = -
-libopenthread_posix_a_LIBADD              = \
-    $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
-
-if OPENTHREAD_BUILD_COVERAGE
-libopenthread_posix_a_CPPFLAGS           += \
-    -DOPENTHREAD_ENABLE_COVERAGE            \
-    $(NULL)
-
-CLEANFILES                                = $(wildcard *.gcda *.gcno)
-endif # OPENTHREAD_BUILD_COVERAGE
-
-include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/posix/Makefile.platform.am b/examples/platforms/posix/Makefile.platform.am
deleted file mode 100644
index b875e63..0000000
--- a/examples/platforms/posix/Makefile.platform.am
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-#  Copyright (c) 2017, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-#
-# posix platform-specific Makefile
-#
-
-LDADD_COMMON                                                          += \
-    $(top_builddir)/examples/platforms/posix/libopenthread-posix.a       \
-    $(NULL)
-
-if OPENTHREAD_TARGET_LINUX
-LDADD_COMMON                                                          += \
-    -lrt                                                                 \
-    $(NULL)
-endif
diff --git a/examples/platforms/posix/README.md b/examples/platforms/posix/README.md
deleted file mode 100644
index 7f4bae0..0000000
--- a/examples/platforms/posix/README.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# OpenThread on POSIX Emulation Example
-
-This directory contains example platform drivers for POSIX emulation.
-
-## Build Examples
-
-### Build using autotools
-
-```bash
-$ cd <path-to-openthread>
-$ ./bootstrap
-$ make -f examples/Makefile-posix
-```
-
-After a successful build, the `elf` files are found in:
-
-- `<path-to-openthread>/output/<platform>/bin`
-
-### Build using cmake/ninja
-
-```bash
-$ cd <path-to-openthread>
-$ mkdir build && cd build
-$ cmake -GNinja -DOT_PLATFORM=posix ..
-$ ninja
-```
-
-After a successful build, the `elf` files are found in:
-
-- `<path-to-openthread>/build/examples/apps/cli`
-- `<path-to-openthread>/build/examples/apps/ncp`
-
-## Interact
-
-1. Spawn the process:
-
-```bash
-$ cd <path-to-openthread>/output/<platform>/bin
-$ ./ot-cli-ftd 1
-```
-
-2. Type `help` for list of commands.
-
-```bash
-> help
-help
-channel
-childtimeout
-contextreusedelay
-extaddr
-extpanid
-ipaddr
-keysequence
-leaderweight
-masterkey
-mode
-netdataregister
-networkidtimeout
-networkname
-panid
-ping
-prefix
-releaserouterid
-rloc16
-route
-routerupgradethreshold
-scan
-start
-state
-stop
-whitelist
-```
diff --git a/examples/platforms/posix/alarm.c b/examples/platforms/posix/alarm.c
deleted file mode 100644
index 808b2e6..0000000
--- a/examples/platforms/posix/alarm.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "utils/code_utils.h"
-
-#ifndef __linux__
-#define __linux__ 0
-#endif
-
-// linux microsecond timer
-#if __linux__
-
-#include <signal.h>
-#include <time.h>
-
-#ifndef OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL
-#define OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL SIGRTMIN
-#endif
-
-timer_t sMicroTimer;
-#endif // __linux__
-
-#include <openthread/platform/alarm-micro.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/diag.h>
-
-#define MS_PER_S 1000
-#define NS_PER_US 1000
-#define US_PER_MS 1000
-#define US_PER_S 1000000
-
-#define DEFAULT_TIMEOUT 10 // seconds
-
-static bool     sIsMsRunning = false;
-static uint32_t sMsAlarm     = 0;
-
-static bool     sIsUsRunning = false;
-static uint32_t sUsAlarm     = 0;
-
-static uint32_t sSpeedUpFactor = 1;
-
-#if __linux__
-static void microTimerHandler(int aSignal, siginfo_t *aSignalInfo, void *aUserContext)
-{
-    assert(aSignal == OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL);
-    assert(aSignalInfo->si_value.sival_ptr == &sMicroTimer);
-    (void)aUserContext;
-}
-#endif
-
-void platformAlarmInit(uint32_t aSpeedUpFactor)
-{
-    sSpeedUpFactor = aSpeedUpFactor;
-
-#if __linux__
-    {
-        struct sigaction sa;
-
-        sa.sa_flags     = SA_SIGINFO;
-        sa.sa_sigaction = microTimerHandler;
-        sigemptyset(&sa.sa_mask);
-
-        if (sigaction(OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL, &sa, NULL) == -1)
-        {
-            perror("sigaction");
-            exit(EXIT_FAILURE);
-        }
-
-        struct sigevent sev;
-
-        sev.sigev_notify          = SIGEV_SIGNAL;
-        sev.sigev_signo           = OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL;
-        sev.sigev_value.sival_ptr = &sMicroTimer;
-
-        if (-1 == timer_create(CLOCK_REALTIME, &sev, &sMicroTimer))
-        {
-            perror("timer_create");
-            exit(EXIT_FAILURE);
-        }
-    }
-#endif
-}
-
-#if defined(CLOCK_MONOTONIC_RAW) || defined(CLOCK_MONOTONIC)
-uint64_t platformGetNow(void)
-{
-    struct timespec now;
-    int             err;
-
-#ifdef CLOCK_MONOTONIC_RAW
-    err = clock_gettime(CLOCK_MONOTONIC_RAW, &now);
-#else
-    err = clock_gettime(CLOCK_MONOTONIC, &now);
-#endif
-
-    assert(err == 0);
-
-    return (uint64_t)now.tv_sec * sSpeedUpFactor * US_PER_S + (uint64_t)now.tv_nsec * sSpeedUpFactor / NS_PER_US;
-}
-#else
-uint64_t platformGetNow(void)
-{
-    struct timeval tv;
-    int            err;
-
-    err = gettimeofday(&tv, NULL);
-
-    assert(err == 0);
-
-    return (uint64_t)tv.tv_sec * sSpeedUpFactor * US_PER_S + (uint64_t)tv.tv_usec * sSpeedUpFactor;
-}
-#endif // defined(CLOCK_MONOTONIC_RAW) || defined(CLOCK_MONOTONIC)
-
-uint32_t otPlatAlarmMilliGetNow(void)
-{
-    return (uint32_t)(platformGetNow() / US_PER_MS);
-}
-
-void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sMsAlarm     = aT0 + aDt;
-    sIsMsRunning = true;
-}
-
-void otPlatAlarmMilliStop(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sIsMsRunning = false;
-}
-
-uint32_t otPlatAlarmMicroGetNow(void)
-{
-    return (uint32_t)platformGetNow();
-}
-
-void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sUsAlarm     = aT0 + aDt;
-    sIsUsRunning = true;
-
-#if __linux__
-    {
-        struct itimerspec its;
-        uint32_t          diff = sUsAlarm - otPlatAlarmMicroGetNow();
-
-        its.it_value.tv_sec  = diff / US_PER_S;
-        its.it_value.tv_nsec = (diff % US_PER_S) * NS_PER_US;
-
-        its.it_interval.tv_sec  = 0;
-        its.it_interval.tv_nsec = 0;
-
-        if (-1 == timer_settime(sMicroTimer, 0, &its, NULL))
-        {
-            perror("otPlatAlarmMicroStartAt timer_settime()");
-            exit(EXIT_FAILURE);
-        }
-    }
-#endif // __linux__
-}
-
-void otPlatAlarmMicroStop(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sIsUsRunning = false;
-
-#if __linux__
-    {
-        struct itimerspec its = {{0, 0}, {0, 0}};
-
-        if (-1 == timer_settime(sMicroTimer, 0, &its, NULL))
-        {
-            perror("otPlatAlarmMicroStop timer_settime()");
-            exit(EXIT_FAILURE);
-        }
-    }
-#endif // __linux__
-}
-
-void platformAlarmUpdateTimeout(struct timeval *aTimeout)
-{
-    int32_t usRemaining = DEFAULT_TIMEOUT * US_PER_S;
-    int32_t msRemaining = DEFAULT_TIMEOUT * MS_PER_S;
-
-    if (aTimeout == NULL)
-    {
-        return;
-    }
-
-    if (sIsUsRunning)
-    {
-        usRemaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
-    }
-
-    if (sIsMsRunning)
-    {
-        msRemaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
-    }
-
-    if (usRemaining <= 0 || msRemaining <= 0)
-    {
-        aTimeout->tv_sec  = 0;
-        aTimeout->tv_usec = 0;
-    }
-    else
-    {
-        int64_t remaining = ((int64_t)msRemaining) * US_PER_MS;
-
-        if (usRemaining < remaining)
-        {
-            remaining = usRemaining;
-        }
-
-        remaining /= sSpeedUpFactor;
-
-        if (remaining == 0)
-        {
-            remaining = 1;
-        }
-
-        aTimeout->tv_sec  = (time_t)remaining / US_PER_S;
-        aTimeout->tv_usec = remaining % US_PER_S;
-    }
-}
-
-void platformAlarmProcess(otInstance *aInstance)
-{
-    int32_t remaining;
-
-    if (sIsMsRunning)
-    {
-        remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
-
-        if (remaining <= 0)
-        {
-            sIsMsRunning = false;
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-
-            if (otPlatDiagModeGet())
-            {
-                otPlatDiagAlarmFired(aInstance);
-            }
-            else
-#endif
-            {
-                otPlatAlarmMilliFired(aInstance);
-            }
-        }
-    }
-
-#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-
-    if (sIsUsRunning)
-    {
-        remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
-
-        if (remaining <= 0)
-        {
-            sIsUsRunning = false;
-
-            otPlatAlarmMicroFired(aInstance);
-        }
-    }
-
-#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-}
-
-uint64_t otPlatTimeGet(void)
-{
-    return platformGetNow();
-}
-
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-uint16_t otPlatTimeGetXtalAccuracy(void)
-{
-    return 0;
-}
-#endif
-
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME == 0
diff --git a/examples/platforms/posix/diag.c b/examples/platforms/posix/diag.c
deleted file mode 100644
index a93c017..0000000
--- a/examples/platforms/posix/diag.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-
-#include <openthread/config.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/radio.h>
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-
-/**
- * Diagnostics mode variables.
- *
- */
-static bool sDiagMode = false;
-
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
-
-    // Add more platform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-}
-
-void otPlatDiagModeSet(bool aMode)
-{
-    sDiagMode = aMode;
-}
-
-bool otPlatDiagModeGet()
-{
-    return sDiagMode;
-}
-
-void otPlatDiagChannelSet(uint8_t aChannel)
-{
-    OT_UNUSED_VARIABLE(aChannel);
-}
-
-void otPlatDiagTxPowerSet(int8_t aTxPower)
-{
-    OT_UNUSED_VARIABLE(aTxPower);
-}
-
-void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aFrame);
-    OT_UNUSED_VARIABLE(aError);
-}
-
-void otPlatDiagAlarmCallback(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
diff --git a/examples/platforms/posix/entropy.c b/examples/platforms/posix/entropy.c
deleted file mode 100644
index 815f113..0000000
--- a/examples/platforms/posix/entropy.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements an entropy source based on /dev/urandom or pseudo-random generator.
- *
- */
-
-#include "platform-posix.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-#include <openthread/platform/entropy.h>
-
-#include "utils/code_utils.h"
-
-#ifndef __SANITIZE_ADDRESS__
-#define __SANITIZE_ADDRESS__ 0
-#endif
-
-#if __SANITIZE_ADDRESS__ != 0
-
-static uint32_t sState = 1;
-
-#endif // __SANITIZE_ADDRESS__
-
-void platformRandomInit(void)
-{
-#if __SANITIZE_ADDRESS__ != 0
-
-    // Multiplying gNodeId assures that no two nodes gets the same seed within an hour.
-    sState = (uint32_t)time(NULL) + (3600 * gNodeId);
-
-#endif // __SANITIZE_ADDRESS__
-}
-
-#if __SANITIZE_ADDRESS__ != 0
-
-static uint32_t randomUint32Get(void)
-{
-    uint32_t mlcg, p, q;
-    uint64_t tmpstate;
-
-    tmpstate = (uint64_t)33614 * (uint64_t)sState;
-    q        = tmpstate & 0xffffffff;
-    q        = q >> 1;
-    p        = tmpstate >> 32;
-    mlcg     = p + q;
-
-    if (mlcg & 0x80000000)
-    {
-        mlcg &= 0x7fffffff;
-        mlcg++;
-    }
-
-    sState = mlcg;
-
-    return mlcg;
-}
-
-#endif // __SANITIZE_ADDRESS__
-
-otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
-{
-    otError error = OT_ERROR_NONE;
-
-#if __SANITIZE_ADDRESS__ == 0
-
-    FILE * file = NULL;
-    size_t readLength;
-
-    otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
-
-    file = fopen("/dev/urandom", "rb");
-    otEXPECT_ACTION(file != NULL, error = OT_ERROR_FAILED);
-
-    readLength = fread(aOutput, 1, aOutputLength, file);
-    otEXPECT_ACTION(readLength == aOutputLength, error = OT_ERROR_FAILED);
-
-exit:
-
-    if (file != NULL)
-    {
-        fclose(file);
-    }
-
-#else // __SANITIZE_ADDRESS__
-
-    /*
-     * THE IMPLEMENTATION BELOW IS NOT COMPLIANT WITH THE THREAD SPECIFICATION.
-     *
-     * Address Sanitizer triggers test failures when reading random
-     * values from /dev/urandom.  The pseudo-random number generator
-     * implementation below is only used to enable continuous
-     * integration checks with Address Sanitizer enabled.
-     */
-    otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
-
-    for (uint16_t length = 0; length < aOutputLength; length++)
-    {
-        aOutput[length] = (uint8_t)randomUint32Get();
-    }
-
-exit:
-
-#endif // __SANITIZE_ADDRESS__
-
-    return error;
-}
diff --git a/examples/platforms/posix/flash.c b/examples/platforms/posix/flash.c
deleted file mode 100644
index 2df47df..0000000
--- a/examples/platforms/posix/flash.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <openthread/config.h>
-
-#include "utils/code_utils.h"
-#include "utils/flash.h"
-
-static int sFlashFd = -1;
-uint32_t   sEraseAddress;
-
-enum
-{
-    FLASH_SIZE      = 0x40000,
-    FLASH_PAGE_SIZE = 0x800,
-    FLASH_PAGE_NUM  = 128,
-};
-
-otError utilsFlashInit(void)
-{
-    otError     error = OT_ERROR_NONE;
-    const char *path  = OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH;
-    char        fileName[sizeof(OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH) + 32];
-    struct stat st;
-    bool        create = false;
-    const char *offset = getenv("PORT_OFFSET");
-
-    memset(&st, 0, sizeof(st));
-
-    if (stat(path, &st) == -1)
-    {
-        mkdir(path, 0777);
-    }
-
-    if (offset == NULL)
-    {
-        offset = "0";
-    }
-
-    snprintf(fileName, sizeof(fileName), "%s/%s_%d.flash", path, offset, gNodeId);
-
-    if (access(fileName, 0))
-    {
-        create = true;
-    }
-
-    sFlashFd = open(fileName, O_RDWR | O_CREAT | O_CLOEXEC, 0600);
-    lseek(sFlashFd, 0, SEEK_SET);
-
-    otEXPECT_ACTION(sFlashFd >= 0, error = OT_ERROR_FAILED);
-
-    if (create)
-    {
-        for (uint16_t index = 0; index < FLASH_PAGE_NUM; index++)
-        {
-            error = utilsFlashErasePage(index * FLASH_PAGE_SIZE);
-            otEXPECT(error == OT_ERROR_NONE);
-        }
-    }
-
-exit:
-    return error;
-}
-
-uint32_t utilsFlashGetSize(void)
-{
-    return FLASH_SIZE;
-}
-
-otError utilsFlashErasePage(uint32_t aAddress)
-{
-    otError  error = OT_ERROR_NONE;
-    uint32_t address;
-    uint8_t  dummyPage[FLASH_SIZE];
-
-    otEXPECT_ACTION(sFlashFd >= 0, error = OT_ERROR_FAILED);
-    otEXPECT_ACTION(aAddress < FLASH_SIZE, error = OT_ERROR_INVALID_ARGS);
-
-    // Get start address of the flash page that includes aAddress
-    address = aAddress & (~(uint32_t)(FLASH_PAGE_SIZE - 1));
-
-    // set the page to the erased state.
-    memset((void *)(&dummyPage[0]), 0xff, FLASH_PAGE_SIZE);
-
-    // Write the page
-    ssize_t r;
-    r = pwrite(sFlashFd, &(dummyPage[0]), FLASH_PAGE_SIZE, (off_t)address);
-    otEXPECT_ACTION(((int)r) == ((int)(FLASH_PAGE_SIZE)), error = OT_ERROR_FAILED);
-
-exit:
-    return error;
-}
-
-otError utilsFlashStatusWait(uint32_t aTimeout)
-{
-    OT_UNUSED_VARIABLE(aTimeout);
-
-    return OT_ERROR_NONE;
-}
-
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t ret   = 0;
-    uint32_t index = 0;
-    uint8_t  byte;
-
-    otEXPECT(sFlashFd >= 0 && aAddress < FLASH_SIZE);
-
-    for (index = 0; index < aSize; index++)
-    {
-        otEXPECT((ret = utilsFlashRead(aAddress + index, &byte, 1)) == 1);
-        // Use bitwise AND to emulate the behavior of flash memory
-        byte &= aData[index];
-        otEXPECT((ret = (uint32_t)pwrite(sFlashFd, &byte, 1, (off_t)(aAddress + index))) == 1);
-    }
-
-exit:
-    return index;
-}
-
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t ret = 0;
-
-    otEXPECT(sFlashFd >= 0 && aAddress < FLASH_SIZE);
-    ret = (uint32_t)pread(sFlashFd, aData, aSize, (off_t)aAddress);
-
-exit:
-    return ret;
-}
diff --git a/examples/platforms/posix/logging.c b/examples/platforms/posix/logging.c
deleted file mode 100644
index 21f3e59..0000000
--- a/examples/platforms/posix/logging.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-
-#include <ctype.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-
-#include <openthread/platform/logging.h>
-#include <openthread/platform/toolchain.h>
-
-#include "utils/code_utils.h"
-
-// Macro to append content to end of the log string.
-
-#define LOG_PRINTF(...)                                                                   \
-    charsWritten = snprintf(&logString[offset], sizeof(logString) - offset, __VA_ARGS__); \
-    otEXPECT_ACTION(charsWritten >= 0, logString[offset] = 0);                            \
-    offset += (unsigned int)charsWritten;                                                 \
-    otEXPECT_ACTION(offset < sizeof(logString), logString[sizeof(logString) - 1] = 0)
-
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
-OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
-{
-    OT_UNUSED_VARIABLE(aLogLevel);
-    OT_UNUSED_VARIABLE(aLogRegion);
-
-    char         logString[512];
-    unsigned int offset;
-    int          charsWritten;
-    va_list      args;
-
-    offset = 0;
-
-    LOG_PRINTF("[%d] ", gNodeId);
-
-    va_start(args, aFormat);
-    charsWritten = vsnprintf(&logString[offset], sizeof(logString) - offset, aFormat, args);
-    va_end(args);
-
-    otEXPECT_ACTION(charsWritten >= 0, logString[offset] = 0);
-
-exit:
-    syslog(LOG_CRIT, "%s", logString);
-}
-
-#endif // #if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
diff --git a/examples/platforms/posix/misc.c b/examples/platforms/posix/misc.c
deleted file mode 100644
index 35fe8b6..0000000
--- a/examples/platforms/posix/misc.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-
-#include <setjmp.h>
-#include <unistd.h>
-
-#include <openthread/platform/misc.h>
-
-#include "openthread-system.h"
-
-extern jmp_buf gResetJump;
-
-static otPlatResetReason   sPlatResetReason = OT_PLAT_RESET_REASON_POWER_ON;
-bool                       gPlatformPseudoResetWasRequested;
-static otPlatMcuPowerState gPlatMcuPowerState = OT_PLAT_MCU_POWER_STATE_ON;
-
-void otPlatReset(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-#if OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
-    gPlatformPseudoResetWasRequested = true;
-    sPlatResetReason                 = OT_PLAT_RESET_REASON_SOFTWARE;
-
-#else // OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
-    // Restart the process using execvp.
-    otSysDeinit();
-    platformUartRestore();
-
-    longjmp(gResetJump, 1);
-    assert(false);
-
-#endif // OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
-}
-
-otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    return sPlatResetReason;
-}
-
-void otPlatWakeHost(void)
-{
-    // TODO: implement an operation to wake the host from sleep state.
-}
-
-otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    otError error = OT_ERROR_NONE;
-
-    switch (aState)
-    {
-    case OT_PLAT_MCU_POWER_STATE_ON:
-    case OT_PLAT_MCU_POWER_STATE_LOW_POWER:
-        gPlatMcuPowerState = aState;
-        break;
-
-    default:
-        error = OT_ERROR_FAILED;
-        break;
-    }
-
-    return error;
-}
-
-otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    return gPlatMcuPowerState;
-}
diff --git a/examples/platforms/posix/openthread-core-posix-config.h b/examples/platforms/posix/openthread-core-posix-config.h
deleted file mode 100644
index 465c69b..0000000
--- a/examples/platforms/posix/openthread-core-posix-config.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- *  Copyright (c) 2017, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes posix compile-time configuration constants
- *   for OpenThread.
- */
-
-#ifndef OPENTHREAD_CORE_POSIX_CONFIG_H_
-#define OPENTHREAD_CORE_POSIX_CONFIG_H_
-
-#ifndef OPENTHREAD_RADIO
-#define OPENTHREAD_RADIO 0
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_PLATFORM_INFO
- *
- * The platform-specific string to insert into the OpenThread version string.
- *
- */
-#define OPENTHREAD_CONFIG_PLATFORM_INFO "POSIX"
-
-/**
- * @def OPENTHREAD_CONFIG_LOG_OUTPUT
- *
- * Specify where the log output should go.
- *
- */
-#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
-#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
- *
- * Define as 1 to enable support for adding of auto-configured SLAAC addresses by OpenThread.
- *
- */
-#ifndef OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE /* allows command line override */
-#define OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 1
-#endif
-
-#if OPENTHREAD_RADIO
-/**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
- *
- * Define to 1 if you want to enable software ACK timeout logic.
- *
- */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 1
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
- *
- * Define to 1 if you want to enable software energy scanning logic.
- *
- * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set).
- *
- */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 1
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
- *
- * Define to 1 if you want to enable software retransmission logic.
- *
- * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set).
- *
- */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
- *
- * Define to 1 if you want to enable software CSMA-CA backoff logic.
- *
- * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set).
- *
- */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1
-#endif
-#endif // OPENTHREAD_RADIO
-
-/**
- * @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
- *
- * Define to 1 if you want to support microsecond timer in platform.
- *
- */
-#define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 1
-
-/**
- * @def CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
- *
- * Define to 1 to use DefaultHandler for unhandled requests
- *
- */
-#define CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER 1
-
-/**
- * @def OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
- *
- * Define to 1 if you want to enable radio coexistence implemented in platform.
- *
- */
-#ifndef OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
-#define OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE 1
-#endif
-
-#ifndef OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
-#define OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1
-#endif
-
-#endif // OPENTHREAD_CORE_POSIX_CONFIG_H_
diff --git a/examples/platforms/posix/platform-config.h b/examples/platforms/posix/platform-config.h
deleted file mode 100644
index d7fc98d..0000000
--- a/examples/platforms/posix/platform-config.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Copyright (c) 2018, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes the platform-specific configuration.
- *
- */
-
-/**
- * @def OPENTHREAD_POSIX_UART_BAUDRATE
- *
- * This setting configures the baud rate of the UART.
- *
- */
-#ifndef OPENTHREAD_POSIX_UART_BAUDRATE
-#define OPENTHREAD_POSIX_UART_BAUDRATE B115200
-#endif
-
-/**
- * @def OPENTHREAD_POSIX_VIRTUAL_TIME
- *
- * This setting configures whether to use virtual time (used for simulation) in POSIX platform.
- *
- */
-#ifndef OPENTHREAD_POSIX_VIRTUAL_TIME
-#define OPENTHREAD_POSIX_VIRTUAL_TIME 0
-#endif
-
-/**
- * @def OPENTHREAD_POSIX_VIRTUAL_TIME_UART
- *
- * This setting configures whether to use virtual time for UART.
- *
- */
-#ifndef OPENTHREAD_POSIX_VIRTUAL_TIME_UART
-#define OPENTHREAD_POSIX_VIRTUAL_TIME_UART 0
-#endif
-
-/**
- * @def OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
- *
- * Define as 1 to enable pseudo-reset.
- *
- */
-#ifndef OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
-#define OPENTHREAD_PLATFORM_USE_PSEUDO_RESET 0
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_NCP_SPI_ENABLE
- *
- * Define as 1 to enable SPI NCP interface.
- *
- */
-#ifndef OPENTHREAD_CONFIG_NCP_SPI_ENABLE
-#define OPENTHREAD_CONFIG_NCP_SPI_ENABLE 0
-#endif
diff --git a/examples/platforms/posix/platform-posix.h b/examples/platforms/posix/platform-posix.h
deleted file mode 100644
index 4829bf0..0000000
--- a/examples/platforms/posix/platform-posix.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- * @brief
- *   This file includes the platform-specific initializers.
- */
-
-#ifndef PLATFORM_POSIX_H_
-#define PLATFORM_POSIX_H_
-
-#include <openthread-core-config.h>
-#include <openthread/config.h>
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <poll.h>
-#include <signal.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#include <openthread/instance.h>
-
-#include "openthread-core-config.h"
-#include "platform-config.h"
-
-enum
-{
-    OT_SIM_EVENT_ALARM_FIRED        = 0,
-    OT_SIM_EVENT_RADIO_RECEIVED     = 1,
-    OT_SIM_EVENT_UART_WRITE         = 2,
-    OT_SIM_EVENT_RADIO_SPINEL_WRITE = 3,
-    OT_EVENT_DATA_MAX_SIZE          = 1024,
-};
-
-OT_TOOL_PACKED_BEGIN
-struct Event
-{
-    uint64_t mDelay;
-    uint8_t  mEvent;
-    uint16_t mDataLength;
-    uint8_t  mData[OT_EVENT_DATA_MAX_SIZE];
-} OT_TOOL_PACKED_END;
-
-enum
-{
-    WELLKNOWN_NODE_ID = 34, ///< Well-known Unique ID used by a simulated radio that supports promiscuous mode.
-};
-
-/**
- * Unique node ID.
- *
- */
-extern uint32_t gNodeId;
-
-/**
- * This function initializes the alarm service used by OpenThread.
- *
- */
-void platformAlarmInit(uint32_t aSpeedUpFactor);
-
-/**
- * This function retrieves the time remaining until the alarm fires.
- *
- * @param[out]  aTimeval  A pointer to the timeval struct.
- *
- */
-void platformAlarmUpdateTimeout(struct timeval *tv);
-
-/**
- * This function performs alarm driver processing.
- *
- * @param[in]  aInstance  The OpenThread instance structure.
- *
- */
-void platformAlarmProcess(otInstance *aInstance);
-
-/**
- * This function returns the next alarm event time.
- *
- * @returns The next alarm fire time.
- *
- */
-int32_t platformAlarmGetNext(void);
-
-/**
- * This function returns the current alarm time.
- *
- * @returns The current alarm time.
- *
- */
-uint64_t platformAlarmGetNow(void);
-
-/**
- * This function advances the alarm time by @p aDelta.
- *
- * @param[in]  aDelta  The amount of time to advance.
- *
- */
-void platformAlarmAdvanceNow(uint64_t aDelta);
-
-/**
- * This function initializes the radio service used by OpenThread.
- *
- */
-void platformRadioInit(void);
-
-/**
- * This function shuts down the radio service used by OpenThread.
- *
- */
-void platformRadioDeinit(void);
-
-/**
- * This function inputs a received radio frame.
- *
- * @param[in]  aInstance   A pointer to the OpenThread instance.
- * @param[in]  aBuf        A pointer to the received radio frame.
- * @param[in]  aBufLength  The size of the received radio frame.
- *
- */
-void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLength);
-
-/**
- * This function updates the file descriptor sets with file descriptors used by the radio driver.
- *
- * @param[inout]  aReadFdSet   A pointer to the read file descriptors.
- * @param[inout]  aWriteFdSet  A pointer to the write file descriptors.
- * @param[inout]  aMaxFd       A pointer to the max file descriptor.
- *
- */
-void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd);
-
-/**
- * This function performs radio driver processing.
- *
- * @param[in]  aInstance    The OpenThread instance structure.
- * @param[in]  aReadFdSet   A pointer to the read file descriptors.
- * @param[in]  aWriteFdSet  A pointer to the write file descriptors.
- *
- */
-void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet);
-
-/**
- * This function initializes the random number service used by OpenThread.
- *
- */
-void platformRandomInit(void);
-
-/**
- * This function updates the file descriptor sets with file descriptors used by the UART driver.
- *
- * @param[inout]  aReadFdSet   A pointer to the read file descriptors.
- * @param[inout]  aWriteFdSet  A pointer to the write file descriptors.
- * @param[inout]  aMaxFd       A pointer to the max file descriptor.
- *
- */
-void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd);
-
-/**
- * This function performs radio driver processing.
- *
- */
-void platformUartProcess(void);
-
-/**
- * This function restores the Uart.
- *
- */
-void platformUartRestore(void);
-
-/**
- * This function sends a simulation event.
- *
- * @param[in]   aEvent  A pointer to the simulation event to send
- *
- */
-void otSimSendEvent(const struct Event *aEvent);
-
-/**
- * This function sends Uart data through simulation.
- *
- * @param[in]   aData       A pointer to the UART data.
- * @param[in]   aLength     Length of UART data.
- *
- */
-void otSimSendUartWriteEvent(const uint8_t *aData, uint16_t aLength);
-
-/**
- * This function checks if radio transmitting is pending.
- *
- * @returns Whether radio transmitting is pending.
- *
- */
-bool platformRadioIsTransmitPending(void);
-
-#endif // PLATFORM_POSIX_H_
diff --git a/examples/platforms/posix/radio.c b/examples/platforms/posix/radio.c
deleted file mode 100644
index 5d1d6f4..0000000
--- a/examples/platforms/posix/radio.c
+++ /dev/null
@@ -1,884 +0,0 @@
-/*
- *  Copyright (c) 2016-2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-
-#include <errno.h>
-
-#include <openthread/dataset.h>
-#include <openthread/random_noncrypto.h>
-#include <openthread/platform/alarm-micro.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/diag.h>
-#include <openthread/platform/radio.h>
-#include <openthread/platform/time.h>
-
-#include "utils/code_utils.h"
-#include "utils/mac_frame.h"
-#include "utils/soft_source_match_table.h"
-
-// The IPv4 group for receiving packets of radio simulation
-#define OT_RADIO_GROUP "224.0.0.116"
-
-enum
-{
-    IEEE802154_ACK_LENGTH = 5,
-
-    IEEE802154_FRAME_TYPE_ACK = 2 << 0,
-
-    IEEE802154_FRAME_PENDING = 1 << 4,
-};
-
-enum
-{
-    POSIX_RECEIVE_SENSITIVITY = -100, // dBm
-
-    POSIX_HIGH_RSSI_SAMPLE               = -30, // dBm
-    POSIX_LOW_RSSI_SAMPLE                = -98, // dBm
-    POSIX_HIGH_RSSI_PROB_INC_PER_CHANNEL = 5,
-};
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-extern int      sSockFd;
-extern uint16_t sPortOffset;
-#else
-static int      sTxFd       = -1;
-static int      sRxFd       = -1;
-static uint16_t sPortOffset = 0;
-static uint16_t sPort       = 0;
-#endif
-
-enum
-{
-    POSIX_RADIO_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
-    POSIX_RADIO_CHANNEL_MAX = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX,
-};
-
-OT_TOOL_PACKED_BEGIN
-struct RadioMessage
-{
-    uint8_t mChannel;
-    uint8_t mPsdu[OT_RADIO_FRAME_MAX_SIZE];
-} OT_TOOL_PACKED_END;
-
-static void radioTransmit(struct RadioMessage *aMessage, const struct otRadioFrame *aFrame);
-static void radioSendMessage(otInstance *aInstance);
-static void radioSendAck(void);
-static void radioProcessFrame(otInstance *aInstance);
-
-static otRadioState        sState = OT_RADIO_STATE_DISABLED;
-static struct RadioMessage sReceiveMessage;
-static struct RadioMessage sTransmitMessage;
-static struct RadioMessage sAckMessage;
-static otRadioFrame        sReceiveFrame;
-static otRadioFrame        sTransmitFrame;
-static otRadioFrame        sAckFrame;
-
-#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
-static otRadioIeInfo sTransmitIeInfo;
-#endif
-
-static otExtAddress   sExtAddress;
-static otShortAddress sShortAddress;
-static otPanId        sPanid;
-static bool           sPromiscuous = false;
-static bool           sTxWait      = false;
-static int8_t         sTxPower     = 0;
-static int8_t         sCcaEdThresh = -74;
-
-static bool sSrcMatchEnabled = false;
-
-#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
-static bool sRadioCoexEnabled = true;
-#endif
-
-static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin)
-{
-    for (size_t i = 0; i < sizeof(*aReversed); i++)
-    {
-        aReversed->m8[i] = aOrigin->m8[sizeof(*aOrigin) - 1 - i];
-    }
-}
-
-static bool isDataRequestAndHasFramePending(const otRadioFrame *aFrame)
-{
-    bool         rval = false;
-    otMacAddress src;
-
-    otEXPECT(otMacFrameIsDataRequest(aFrame));
-    otEXPECT_ACTION(sSrcMatchEnabled, rval = true);
-    otEXPECT(otMacFrameGetSrcAddr(aFrame, &src) == OT_ERROR_NONE);
-
-    switch (src.mType)
-    {
-    case OT_MAC_ADDRESS_TYPE_SHORT:
-        rval = utilsSoftSrcMatchShortFindEntry(src.mAddress.mShortAddress) >= 0;
-        break;
-    case OT_MAC_ADDRESS_TYPE_EXTENDED:
-    {
-        otExtAddress extAddr;
-
-        ReverseExtAddress(&extAddr, &src.mAddress.mExtAddress);
-        rval = utilsSoftSrcMatchExtFindEntry(&extAddr) >= 0;
-        break;
-    }
-    default:
-        break;
-    }
-
-exit:
-    return rval;
-}
-
-static uint16_t crc16_citt(uint16_t aFcs, uint8_t aByte)
-{
-    // CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
-    // width=16 poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189 name="KERMIT"
-    // http://reveng.sourceforge.net/crc-catalogue/16.htm#crc.cat.kermit
-    static const uint16_t sFcsTable[256] = {
-        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5,
-        0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52,
-        0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3,
-        0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9,
-        0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e,
-        0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f,
-        0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862,
-        0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb,
-        0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948,
-        0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226,
-        0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497,
-        0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704,
-        0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb,
-        0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c,
-        0x3de3, 0x2c6a, 0x1ef1, 0x0f78};
-    return (aFcs >> 8) ^ sFcsTable[(aFcs ^ aByte) & 0xff];
-}
-
-void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    aIeeeEui64[0] = 0x18;
-    aIeeeEui64[1] = 0xb4;
-    aIeeeEui64[2] = 0x30;
-    aIeeeEui64[3] = 0x00;
-    aIeeeEui64[4] = (gNodeId >> 24) & 0xff;
-    aIeeeEui64[5] = (gNodeId >> 16) & 0xff;
-    aIeeeEui64[6] = (gNodeId >> 8) & 0xff;
-    aIeeeEui64[7] = gNodeId & 0xff;
-}
-
-void otPlatRadioSetPanId(otInstance *aInstance, otPanId aPanid)
-{
-    assert(aInstance != NULL);
-
-    sPanid = aPanid;
-    utilsSoftSrcMatchSetPanId(aPanid);
-}
-
-void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
-{
-    assert(aInstance != NULL);
-
-    ReverseExtAddress(&sExtAddress, aExtAddress);
-}
-
-void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aAddress)
-{
-    assert(aInstance != NULL);
-
-    sShortAddress = aAddress;
-}
-
-void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
-{
-    assert(aInstance != NULL);
-
-    sPromiscuous = aEnable;
-}
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-static void initFds(void)
-{
-    int                fd;
-    int                one = 1;
-    struct sockaddr_in sockaddr;
-
-    memset(&sockaddr, 0, sizeof(sockaddr));
-
-    otEXPECT_ACTION((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1, perror("socket(sTxFd)"));
-
-    sPort                    = (uint16_t)(9000 + sPortOffset + gNodeId);
-    sockaddr.sin_family      = AF_INET;
-    sockaddr.sin_port        = htons(sPort);
-    sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
-
-    otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &sockaddr.sin_addr, sizeof(sockaddr.sin_addr)) != -1,
-                    perror("setsockopt(sTxFd, IP_MULTICAST_IF)"));
-
-    otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one)) != -1,
-                    perror("setsockopt(sRxFd, IP_MULTICAST_LOOP)"));
-
-    otEXPECT_ACTION(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != -1, perror("bind(sTxFd)"));
-
-    // Tx fd is successfully initialized.
-    sTxFd = fd;
-
-    otEXPECT_ACTION((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1, perror("socket(sRxFd)"));
-
-    otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != -1,
-                    perror("setsockopt(sRxFd, SO_REUSEADDR)"));
-    otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != -1,
-                    perror("setsockopt(sRxFd, SO_REUSEPORT)"));
-
-    {
-        struct ip_mreqn mreq;
-
-        memset(&mreq, 0, sizeof(mreq));
-        inet_pton(AF_INET, OT_RADIO_GROUP, &mreq.imr_multiaddr);
-
-        // Always use loopback device to send simulation packets.
-        mreq.imr_address.s_addr = inet_addr("127.0.0.1");
-
-        otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq.imr_address, sizeof(mreq.imr_address)) != -1,
-                        perror("setsockopt(sRxFd, IP_MULTICAST_IF)"));
-        otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != -1,
-                        perror("setsockopt(sRxFd, IP_ADD_MEMBERSHIP)"));
-    }
-
-    sockaddr.sin_family      = AF_INET;
-    sockaddr.sin_port        = htons((uint16_t)(9000 + sPortOffset + WELLKNOWN_NODE_ID));
-    sockaddr.sin_addr.s_addr = inet_addr(OT_RADIO_GROUP);
-
-    otEXPECT_ACTION(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != -1, perror("bind(sRxFd)"));
-
-    // Rx fd is successfully initialized.
-    sRxFd = fd;
-
-exit:
-    if (sRxFd == -1 || sTxFd == -1)
-    {
-        exit(EXIT_FAILURE);
-    }
-}
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-
-void platformRadioInit(void)
-{
-#if OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-    char *offset;
-
-    offset = getenv("PORT_OFFSET");
-
-    if (offset)
-    {
-        char *endptr;
-
-        sPortOffset = (uint16_t)strtol(offset, &endptr, 0);
-
-        if (*endptr != '\0')
-        {
-            fprintf(stderr, "Invalid PORT_OFFSET: %s\n", offset);
-            exit(EXIT_FAILURE);
-        }
-
-        sPortOffset *= WELLKNOWN_NODE_ID;
-    }
-
-    initFds();
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-
-    sReceiveFrame.mPsdu  = sReceiveMessage.mPsdu;
-    sTransmitFrame.mPsdu = sTransmitMessage.mPsdu;
-    sAckFrame.mPsdu      = sAckMessage.mPsdu;
-
-#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
-    sTransmitFrame.mInfo.mTxInfo.mIeInfo = &sTransmitIeInfo;
-#else
-    sTransmitFrame.mInfo.mTxInfo.mIeInfo = NULL;
-#endif
-}
-
-bool otPlatRadioIsEnabled(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    return (sState != OT_RADIO_STATE_DISABLED) ? true : false;
-}
-
-otError otPlatRadioEnable(otInstance *aInstance)
-{
-    if (!otPlatRadioIsEnabled(aInstance))
-    {
-        sState = OT_RADIO_STATE_SLEEP;
-    }
-
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioDisable(otInstance *aInstance)
-{
-    otError error = OT_ERROR_NONE;
-
-    otEXPECT(otPlatRadioIsEnabled(aInstance));
-    otEXPECT_ACTION(sState == OT_RADIO_STATE_SLEEP, error = OT_ERROR_INVALID_STATE);
-
-    sState = OT_RADIO_STATE_DISABLED;
-
-exit:
-    return error;
-}
-
-otError otPlatRadioSleep(otInstance *aInstance)
-{
-    assert(aInstance != NULL);
-
-    otError error = OT_ERROR_INVALID_STATE;
-
-    if (sState == OT_RADIO_STATE_SLEEP || sState == OT_RADIO_STATE_RECEIVE)
-    {
-        error  = OT_ERROR_NONE;
-        sState = OT_RADIO_STATE_SLEEP;
-    }
-
-    return error;
-}
-
-otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
-{
-    assert(aInstance != NULL);
-
-    otError error = OT_ERROR_INVALID_STATE;
-
-    if (sState != OT_RADIO_STATE_DISABLED)
-    {
-        error                  = OT_ERROR_NONE;
-        sState                 = OT_RADIO_STATE_RECEIVE;
-        sTxWait                = false;
-        sReceiveFrame.mChannel = aChannel;
-    }
-
-    return error;
-}
-
-otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aRadio)
-{
-    assert(aInstance != NULL);
-    assert(aRadio != NULL);
-
-    otError error = OT_ERROR_INVALID_STATE;
-
-    if (sState == OT_RADIO_STATE_RECEIVE)
-    {
-        error  = OT_ERROR_NONE;
-        sState = OT_RADIO_STATE_TRANSMIT;
-    }
-
-    return error;
-}
-
-otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
-{
-    assert(aInstance != NULL);
-
-    return &sTransmitFrame;
-}
-
-int8_t otPlatRadioGetRssi(otInstance *aInstance)
-{
-    assert(aInstance != NULL);
-
-    int8_t   rssi    = POSIX_LOW_RSSI_SAMPLE;
-    uint8_t  channel = sReceiveFrame.mChannel;
-    uint32_t probabilityThreshold;
-
-    otEXPECT((POSIX_RADIO_CHANNEL_MIN <= channel) && channel <= (POSIX_RADIO_CHANNEL_MAX));
-
-    // To emulate a simple interference model, we return either a high or
-    // a low  RSSI value with a fixed probability per each channel. The
-    // probability is increased per channel by a constant.
-
-    probabilityThreshold = (channel - POSIX_RADIO_CHANNEL_MIN) * POSIX_HIGH_RSSI_PROB_INC_PER_CHANNEL;
-
-    if (otRandomNonCryptoGetUint16() < (probabilityThreshold * 0xffff / 100))
-    {
-        rssi = POSIX_HIGH_RSSI_SAMPLE;
-    }
-
-exit:
-    return rssi;
-}
-
-otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
-{
-    assert(aInstance != NULL);
-
-    return OT_RADIO_CAPS_NONE;
-}
-
-bool otPlatRadioGetPromiscuous(otInstance *aInstance)
-{
-    assert(aInstance != NULL);
-
-    return sPromiscuous;
-}
-
-static void radioReceive(otInstance *aInstance)
-{
-    bool isTxDone = false;
-    bool isAck    = otMacFrameIsAck(&sReceiveFrame);
-
-    otEXPECT(sReceiveFrame.mChannel == sReceiveMessage.mChannel);
-    otEXPECT(sState == OT_RADIO_STATE_RECEIVE || sState == OT_RADIO_STATE_TRANSMIT);
-
-    // Unable to simulate SFD, so use the rx done timestamp instead.
-    sReceiveFrame.mInfo.mRxInfo.mTimestamp = otPlatTimeGet();
-
-    if (sTxWait)
-    {
-        if (otMacFrameIsAckRequested(&sTransmitFrame))
-        {
-            isTxDone = isAck && otMacFrameGetSequence(&sReceiveFrame) == otMacFrameGetSequence(&sTransmitFrame);
-        }
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-        // Simulate tx done when receiving the echo frame.
-        else
-        {
-            isTxDone = !isAck && sTransmitFrame.mLength == sReceiveFrame.mLength &&
-                       memcmp(sTransmitFrame.mPsdu, sReceiveFrame.mPsdu, sTransmitFrame.mLength) == 0;
-        }
-#endif
-    }
-
-    if (isTxDone)
-    {
-        sState  = OT_RADIO_STATE_RECEIVE;
-        sTxWait = false;
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-
-        if (otPlatDiagModeGet())
-        {
-            otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_NONE);
-        }
-        else
-#endif
-        {
-            otPlatRadioTxDone(aInstance, &sTransmitFrame, (isAck ? &sReceiveFrame : NULL), OT_ERROR_NONE);
-        }
-    }
-    else if (!isAck || sPromiscuous)
-    {
-        radioProcessFrame(aInstance);
-    }
-
-exit:
-    return;
-}
-
-static void radioComputeCrc(struct RadioMessage *aMessage, uint16_t aLength)
-{
-    uint16_t crc        = 0;
-    uint16_t crc_offset = aLength - sizeof(uint16_t);
-
-    for (uint16_t i = 0; i < crc_offset; i++)
-    {
-        crc = crc16_citt(crc, aMessage->mPsdu[i]);
-    }
-
-    aMessage->mPsdu[crc_offset]     = crc & 0xff;
-    aMessage->mPsdu[crc_offset + 1] = crc >> 8;
-}
-
-void radioSendMessage(otInstance *aInstance)
-{
-#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
-    bool notifyFrameUpdated = false;
-
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    if (sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0)
-    {
-        uint8_t *timeIe = sTransmitFrame.mPsdu + sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset;
-        uint64_t time = (uint64_t)((int64_t)otPlatTimeGet() + sTransmitFrame.mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset);
-
-        *timeIe = sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeSyncSeq;
-
-        *(++timeIe) = (uint8_t)(time & 0xff);
-        for (uint8_t i = 1; i < sizeof(uint64_t); i++)
-        {
-            time        = time >> 8;
-            *(++timeIe) = (uint8_t)(time & 0xff);
-        }
-
-        notifyFrameUpdated = true;
-    }
-#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-
-    if (notifyFrameUpdated)
-    {
-        otMacFrameProcessTransmitAesCcm(&sTransmitFrame, &sExtAddress);
-    }
-#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
-
-    sTransmitMessage.mChannel = sTransmitFrame.mChannel;
-
-    otPlatRadioTxStarted(aInstance, &sTransmitFrame);
-    radioComputeCrc(&sTransmitMessage, sTransmitFrame.mLength);
-    radioTransmit(&sTransmitMessage, &sTransmitFrame);
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-    sTxWait = otMacFrameIsAckRequested(&sTransmitFrame);
-
-    if (!sTxWait)
-    {
-        sState = OT_RADIO_STATE_RECEIVE;
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-
-        if (otPlatDiagModeGet())
-        {
-            otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_NONE);
-        }
-        else
-#endif
-        {
-            otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, OT_ERROR_NONE);
-        }
-    }
-#else
-    // Wait for echo radio in virtual time mode.
-    sTxWait = true;
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
-}
-
-bool platformRadioIsTransmitPending(void)
-{
-    return sState == OT_RADIO_STATE_TRANSMIT && !sTxWait;
-}
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLength)
-{
-    assert(sizeof(sReceiveMessage) >= aBufLength);
-
-    memcpy(&sReceiveMessage, aBuf, aBufLength);
-
-    sReceiveFrame.mLength = (uint8_t)(aBufLength - 1);
-
-    radioReceive(aInstance);
-}
-#else
-void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd)
-{
-    if (aReadFdSet != NULL && (sState != OT_RADIO_STATE_TRANSMIT || sTxWait))
-    {
-        FD_SET(sRxFd, aReadFdSet);
-
-        if (aMaxFd != NULL && *aMaxFd < sRxFd)
-        {
-            *aMaxFd = sRxFd;
-        }
-    }
-
-    if (aWriteFdSet != NULL && platformRadioIsTransmitPending())
-    {
-        FD_SET(sTxFd, aWriteFdSet);
-
-        if (aMaxFd != NULL && *aMaxFd < sTxFd)
-        {
-            *aMaxFd = sTxFd;
-        }
-    }
-}
-
-// no need to close in virtual time mode.
-void platformRadioDeinit(void)
-{
-    if (sRxFd != -1)
-    {
-        close(sRxFd);
-    }
-
-    if (sTxFd != -1)
-    {
-        close(sTxFd);
-    }
-}
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
-
-void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
-{
-    OT_UNUSED_VARIABLE(aReadFdSet);
-    OT_UNUSED_VARIABLE(aWriteFdSet);
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-    if (FD_ISSET(sRxFd, aReadFdSet))
-    {
-        struct sockaddr_in sockaddr;
-        socklen_t          len = sizeof(sockaddr);
-        ssize_t            rval;
-
-        memset(&sockaddr, 0, sizeof(sockaddr));
-        rval =
-            recvfrom(sRxFd, (char *)&sReceiveMessage, sizeof(sReceiveMessage), 0, (struct sockaddr *)&sockaddr, &len);
-
-        if (rval > 0)
-        {
-            if (sockaddr.sin_port != htons(sPort))
-            {
-                sReceiveFrame.mLength = (uint16_t)(rval - 1);
-
-                radioReceive(aInstance);
-            }
-        }
-        else if (rval == 0)
-        {
-            // socket is closed, which should not happen
-            assert(false);
-        }
-        else if (errno != EINTR && errno != EAGAIN)
-        {
-            perror("recvfrom(sRxFd)");
-            exit(EXIT_FAILURE);
-        }
-    }
-#endif
-
-    if (platformRadioIsTransmitPending())
-    {
-        radioSendMessage(aInstance);
-    }
-}
-
-void radioTransmit(struct RadioMessage *aMessage, const struct otRadioFrame *aFrame)
-{
-#if OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-    ssize_t            rval;
-    struct sockaddr_in sockaddr;
-
-    memset(&sockaddr, 0, sizeof(sockaddr));
-    sockaddr.sin_family = AF_INET;
-    inet_pton(AF_INET, OT_RADIO_GROUP, &sockaddr.sin_addr);
-
-    sockaddr.sin_port = htons((uint16_t)(9000 + sPortOffset + WELLKNOWN_NODE_ID));
-    rval =
-        sendto(sTxFd, (const char *)aMessage, 1 + aFrame->mLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
-
-    if (rval < 0)
-    {
-        perror("sendto(sTxFd)");
-        exit(EXIT_FAILURE);
-    }
-#else  // OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-    struct Event event;
-
-    event.mDelay      = 1; // 1us for now
-    event.mEvent      = OT_SIM_EVENT_RADIO_RECEIVED;
-    event.mDataLength = 1 + aFrame->mLength; // include channel in first byte
-    memcpy(event.mData, aMessage, event.mDataLength);
-
-    otSimSendEvent(&event);
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-}
-
-void radioSendAck(void)
-{
-    sAckFrame.mLength    = IEEE802154_ACK_LENGTH;
-    sAckMessage.mPsdu[0] = IEEE802154_FRAME_TYPE_ACK;
-
-    if (isDataRequestAndHasFramePending(&sReceiveFrame))
-    {
-        sAckMessage.mPsdu[0] |= IEEE802154_FRAME_PENDING;
-        sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true;
-    }
-
-    sAckMessage.mPsdu[1] = 0;
-    sAckMessage.mPsdu[2] = otMacFrameGetSequence(&sReceiveFrame);
-
-    sAckMessage.mChannel = sReceiveFrame.mChannel;
-
-    radioComputeCrc(&sAckMessage, sAckFrame.mLength);
-    radioTransmit(&sAckMessage, &sAckFrame);
-}
-
-void radioProcessFrame(otInstance *aInstance)
-{
-    otError error = OT_ERROR_NONE;
-
-    sReceiveFrame.mInfo.mRxInfo.mRssi = -20;
-    sReceiveFrame.mInfo.mRxInfo.mLqi  = OT_RADIO_LQI_NONE;
-
-    sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = false;
-
-    otEXPECT(sPromiscuous == false);
-
-    otEXPECT_ACTION(otMacFrameDoesAddrMatch(&sReceiveFrame, sPanid, sShortAddress, &sExtAddress),
-                    error = OT_ERROR_ABORT);
-
-    // generate acknowledgment
-    if (otMacFrameIsAckRequested(&sReceiveFrame))
-    {
-        radioSendAck();
-    }
-
-exit:
-
-    if (error != OT_ERROR_ABORT)
-    {
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-        if (otPlatDiagModeGet())
-        {
-            otPlatDiagRadioReceiveDone(aInstance, error == OT_ERROR_NONE ? &sReceiveFrame : NULL, error);
-        }
-        else
-#endif
-        {
-            otPlatRadioReceiveDone(aInstance, error == OT_ERROR_NONE ? &sReceiveFrame : NULL, error);
-        }
-    }
-}
-
-void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
-{
-    assert(aInstance != NULL);
-
-    sSrcMatchEnabled = aEnable;
-}
-
-otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
-{
-    assert(aInstance != NULL);
-    assert(aScanChannel >= POSIX_RADIO_CHANNEL_MIN && aScanChannel <= POSIX_RADIO_CHANNEL_MAX);
-    assert(aScanDuration > 0);
-
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
-{
-    assert(aInstance != NULL);
-
-    *aPower = sTxPower;
-
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
-{
-    assert(aInstance != NULL);
-
-    sTxPower = aPower;
-
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
-{
-    assert(aInstance != NULL);
-
-    *aThreshold = sCcaEdThresh;
-
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
-{
-    assert(aInstance != NULL);
-
-    sCcaEdThresh = aThreshold;
-
-    return OT_ERROR_NONE;
-}
-
-int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
-{
-    assert(aInstance != NULL);
-
-    return POSIX_RECEIVE_SENSITIVITY;
-}
-
-otRadioState otPlatRadioGetState(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    return sState;
-}
-
-#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
-otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled)
-{
-    assert(aInstance != NULL);
-
-    sRadioCoexEnabled = aEnabled;
-    return OT_ERROR_NONE;
-}
-
-bool otPlatRadioIsCoexEnabled(otInstance *aInstance)
-{
-    assert(aInstance != NULL);
-
-    return sRadioCoexEnabled;
-}
-
-otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics)
-{
-    otError error = OT_ERROR_NONE;
-
-    assert(aInstance != NULL);
-    otEXPECT_ACTION(aCoexMetrics != NULL, error = OT_ERROR_INVALID_ARGS);
-
-    memset(aCoexMetrics, 0, sizeof(otRadioCoexMetrics));
-
-    aCoexMetrics->mStopped                            = false;
-    aCoexMetrics->mNumGrantGlitch                     = 1;
-    aCoexMetrics->mNumTxRequest                       = 2;
-    aCoexMetrics->mNumTxGrantImmediate                = 3;
-    aCoexMetrics->mNumTxGrantWait                     = 4;
-    aCoexMetrics->mNumTxGrantWaitActivated            = 5;
-    aCoexMetrics->mNumTxGrantWaitTimeout              = 6;
-    aCoexMetrics->mNumTxGrantDeactivatedDuringRequest = 7;
-    aCoexMetrics->mNumTxDelayedGrant                  = 8;
-    aCoexMetrics->mAvgTxRequestToGrantTime            = 9;
-    aCoexMetrics->mNumRxRequest                       = 10;
-    aCoexMetrics->mNumRxGrantImmediate                = 11;
-    aCoexMetrics->mNumRxGrantWait                     = 12;
-    aCoexMetrics->mNumRxGrantWaitActivated            = 13;
-    aCoexMetrics->mNumRxGrantWaitTimeout              = 14;
-    aCoexMetrics->mNumRxGrantDeactivatedDuringRequest = 15;
-    aCoexMetrics->mNumRxDelayedGrant                  = 16;
-    aCoexMetrics->mAvgRxRequestToGrantTime            = 17;
-    aCoexMetrics->mNumRxGrantNone                     = 18;
-
-exit:
-    return error;
-}
-#endif
diff --git a/examples/platforms/posix/sim/alarm-sim.c b/examples/platforms/posix/sim/alarm-sim.c
deleted file mode 100644
index 5238782..0000000
--- a/examples/platforms/posix/sim/alarm-sim.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  Copyright (c) 2018, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <openthread/platform/alarm-micro.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/diag.h>
-
-#define US_PER_MS 1000
-
-extern uint64_t sNow; // microseconds
-
-static bool     sIsMsRunning = false;
-static uint32_t sMsAlarm     = 0;
-
-static bool     sIsUsRunning = false;
-static uint32_t sUsAlarm     = 0;
-
-void platformAlarmInit(uint32_t aSpeedUpFactor)
-{
-    OT_UNUSED_VARIABLE(aSpeedUpFactor);
-
-    sNow = 0;
-}
-
-uint64_t platformAlarmGetNow(void)
-{
-    return sNow;
-}
-
-void platformAlarmAdvanceNow(uint64_t aDelta)
-{
-    sNow += aDelta;
-}
-
-uint32_t otPlatAlarmMilliGetNow(void)
-{
-    return (uint32_t)(sNow / US_PER_MS);
-}
-
-void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sMsAlarm     = aT0 + aDt;
-    sIsMsRunning = true;
-}
-
-void otPlatAlarmMilliStop(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sIsMsRunning = false;
-}
-
-uint32_t otPlatAlarmMicroGetNow(void)
-{
-    return (uint32_t)sNow;
-}
-
-void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sUsAlarm     = aT0 + aDt;
-    sIsUsRunning = true;
-}
-
-void otPlatAlarmMicroStop(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sIsUsRunning = false;
-}
-
-int32_t platformAlarmGetNext(void)
-{
-    int32_t remaining = INT32_MAX;
-
-    if (sIsMsRunning)
-    {
-        int32_t milli = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
-
-        remaining = milli * US_PER_MS;
-
-        if (remaining < 0 && milli > 0)
-        {
-            remaining = INT32_MAX;
-        }
-    }
-
-#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-
-    if (sIsUsRunning)
-    {
-        int32_t micro = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
-
-        if (remaining > micro)
-        {
-            remaining = micro;
-        }
-    }
-
-#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-
-    return remaining;
-}
-
-void platformAlarmProcess(otInstance *aInstance)
-{
-    int32_t remaining;
-
-    if (sIsMsRunning)
-    {
-        remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
-
-        if (remaining <= 0)
-        {
-            sIsMsRunning = false;
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-
-            if (otPlatDiagModeGet())
-            {
-                otPlatDiagAlarmFired(aInstance);
-            }
-            else
-#endif
-            {
-                otPlatAlarmMilliFired(aInstance);
-            }
-        }
-    }
-
-#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-
-    if (sIsUsRunning)
-    {
-        remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
-
-        if (remaining <= 0)
-        {
-            sIsUsRunning = false;
-
-            otPlatAlarmMicroFired(aInstance);
-        }
-    }
-
-#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-}
-
-uint64_t otPlatTimeGet(void)
-{
-    return platformAlarmGetNow();
-}
-
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-uint16_t otPlatTimeGetXtalAccuracy(void)
-{
-    return 0;
-}
-#endif
-
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
diff --git a/examples/platforms/posix/sim/platform-sim.c b/examples/platforms/posix/sim/platform-sim.c
deleted file mode 100644
index 87936c6..0000000
--- a/examples/platforms/posix/sim/platform-sim.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- *  Copyright (c) 2018, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- * @brief
- *   This file includes the platform-specific initializers.
- */
-
-#include "platform-posix.h"
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-
-#include <assert.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <libgen.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <syslog.h>
-
-#include <openthread/tasklet.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/uart.h>
-
-uint32_t gNodeId = 1;
-
-extern bool          gPlatformPseudoResetWasRequested;
-static volatile bool gTerminate = false;
-
-int    gArgumentsCount = 0;
-char **gArguments      = NULL;
-
-uint64_t sNow = 0; // microseconds
-int      sSockFd;
-uint16_t sPortOffset;
-
-static void handleSignal(int aSignal)
-{
-    OT_UNUSED_VARIABLE(aSignal);
-
-    gTerminate = true;
-}
-
-void otSimSendEvent(const struct Event *aEvent)
-{
-    ssize_t            rval;
-    struct sockaddr_in sockaddr;
-
-    memset(&sockaddr, 0, sizeof(sockaddr));
-    sockaddr.sin_family = AF_INET;
-    inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr);
-    sockaddr.sin_port = htons(9000 + sPortOffset);
-
-    rval = sendto(sSockFd, aEvent, offsetof(struct Event, mData) + aEvent->mDataLength, 0, (struct sockaddr *)&sockaddr,
-                  sizeof(sockaddr));
-
-    if (rval < 0)
-    {
-        perror("sendto");
-        exit(EXIT_FAILURE);
-    }
-}
-
-static void receiveEvent(otInstance *aInstance)
-{
-    struct Event event;
-    ssize_t      rval = recvfrom(sSockFd, (char *)&event, sizeof(event), 0, NULL, NULL);
-
-    if (rval < 0 || (uint16_t)rval < offsetof(struct Event, mData))
-    {
-        perror("recvfrom");
-        exit(EXIT_FAILURE);
-    }
-
-    platformAlarmAdvanceNow(event.mDelay);
-
-    switch (event.mEvent)
-    {
-    case OT_SIM_EVENT_ALARM_FIRED:
-        break;
-
-    case OT_SIM_EVENT_RADIO_RECEIVED:
-        platformRadioReceive(aInstance, event.mData, event.mDataLength);
-        break;
-
-    case OT_SIM_EVENT_UART_WRITE:
-        otPlatUartReceived(event.mData, event.mDataLength);
-        break;
-
-    default:
-        assert(false);
-    }
-}
-
-static void platformSendSleepEvent(void)
-{
-    struct Event event;
-
-    assert(platformAlarmGetNext() > 0);
-
-    event.mDelay      = (uint64_t)platformAlarmGetNext();
-    event.mEvent      = OT_SIM_EVENT_ALARM_FIRED;
-    event.mDataLength = 0;
-
-    otSimSendEvent(&event);
-}
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME_UART
-void platformUartRestore(void)
-{
-}
-
-otError otPlatUartEnable(void)
-{
-    return OT_ERROR_NONE;
-}
-
-otError otPlatUartDisable(void)
-{
-    return OT_ERROR_NONE;
-}
-
-otError otPlatUartSend(const uint8_t *aData, uint16_t aLength)
-{
-    otError      error = OT_ERROR_NONE;
-    struct Event event;
-
-    event.mDelay      = 0;
-    event.mEvent      = OT_SIM_EVENT_UART_WRITE;
-    event.mDataLength = aLength;
-
-    memcpy(event.mData, aData, aLength);
-
-    otSimSendEvent(&event);
-
-    otPlatUartSendDone();
-
-    return error;
-}
-
-otError otPlatUartFlush(void)
-{
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME_UART
-
-static void socket_init(void)
-{
-    struct sockaddr_in sockaddr;
-    char *             offset;
-    memset(&sockaddr, 0, sizeof(sockaddr));
-    sockaddr.sin_family = AF_INET;
-
-    offset = getenv("PORT_OFFSET");
-
-    if (offset)
-    {
-        char *endptr;
-
-        sPortOffset = (uint16_t)strtol(offset, &endptr, 0);
-
-        if (*endptr != '\0')
-        {
-            fprintf(stderr, "Invalid PORT_OFFSET: %s\n", offset);
-            exit(EXIT_FAILURE);
-        }
-
-        sPortOffset *= WELLKNOWN_NODE_ID;
-    }
-
-    sockaddr.sin_port        = htons(9000 + sPortOffset + gNodeId);
-    sockaddr.sin_addr.s_addr = INADDR_ANY;
-
-    sSockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
-    if (sSockFd == -1)
-    {
-        perror("socket");
-        exit(EXIT_FAILURE);
-    }
-
-    if (bind(sSockFd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == -1)
-    {
-        perror("bind");
-        exit(EXIT_FAILURE);
-    }
-}
-
-void otSysInit(int argc, char *argv[])
-{
-    char *endptr;
-
-    if (gPlatformPseudoResetWasRequested)
-    {
-        gPlatformPseudoResetWasRequested = false;
-        return;
-    }
-
-    if (argc != 2)
-    {
-        exit(EXIT_FAILURE);
-    }
-
-    openlog(basename(argv[0]), LOG_PID, LOG_USER);
-    setlogmask(setlogmask(0) & LOG_UPTO(LOG_NOTICE));
-
-    gArgumentsCount = argc;
-    gArguments      = argv;
-
-    gNodeId = (uint32_t)strtol(argv[1], &endptr, 0);
-
-    if (*endptr != '\0' || gNodeId < 1 || gNodeId >= WELLKNOWN_NODE_ID)
-    {
-        fprintf(stderr, "Invalid NodeId: %s\n", argv[1]);
-        exit(EXIT_FAILURE);
-    }
-
-    socket_init();
-
-    platformAlarmInit(1);
-    platformRadioInit();
-    platformRandomInit();
-
-    signal(SIGTERM, &handleSignal);
-    signal(SIGHUP, &handleSignal);
-}
-
-bool otSysPseudoResetWasRequested(void)
-{
-    return gPlatformPseudoResetWasRequested;
-}
-
-void otSysDeinit(void)
-{
-    close(sSockFd);
-}
-
-void otSysProcessDrivers(otInstance *aInstance)
-{
-    fd_set read_fds;
-    fd_set write_fds;
-    fd_set error_fds;
-    int    max_fd = -1;
-    int    rval;
-
-    if (gTerminate)
-    {
-        exit(0);
-    }
-
-    FD_ZERO(&read_fds);
-    FD_ZERO(&write_fds);
-    FD_ZERO(&error_fds);
-
-    FD_SET(sSockFd, &read_fds);
-    max_fd = sSockFd;
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME_UART == 0
-    platformUartUpdateFdSet(&read_fds, &write_fds, &error_fds, &max_fd);
-#endif
-
-    if (!otTaskletsArePending(aInstance) && platformAlarmGetNext() > 0 && !platformRadioIsTransmitPending())
-    {
-        platformSendSleepEvent();
-
-        rval = select(max_fd + 1, &read_fds, &write_fds, &error_fds, NULL);
-
-        if ((rval < 0) && (errno != EINTR))
-        {
-            perror("select");
-            exit(EXIT_FAILURE);
-        }
-
-        if (rval > 0 && FD_ISSET(sSockFd, &read_fds))
-        {
-            receiveEvent(aInstance);
-        }
-    }
-
-    platformAlarmProcess(aInstance);
-    platformRadioProcess(aInstance, &read_fds, &write_fds);
-#if OPENTHREAD_POSIX_VIRTUAL_TIME_UART == 0
-    platformUartProcess();
-#endif
-}
-
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
diff --git a/examples/platforms/posix/spi-stubs.c b/examples/platforms/posix/spi-stubs.c
deleted file mode 100644
index 4bfe343..0000000
--- a/examples/platforms/posix/spi-stubs.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <openthread/config.h>
-#include <openthread/platform/spi-slave.h>
-#include <openthread/platform/uart.h>
-
-#if OPENTHREAD_CONFIG_NCP_SPI_ENABLE
-
-// Spi-slave stubs
-
-otError otPlatSpiSlaveEnable(otPlatSpiSlaveTransactionCompleteCallback aCompleteCallback,
-                             otPlatSpiSlaveTransactionProcessCallback  aProcessCallback,
-                             void *                                    aContext)
-{
-    OT_UNUSED_VARIABLE(aCompleteCallback);
-    OT_UNUSED_VARIABLE(aProcessCallback);
-    OT_UNUSED_VARIABLE(aContext);
-
-    fprintf(stderr, "\nNo SPI support for posix platform.");
-    exit(0);
-
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-void otPlatSpiSlaveDisable(void)
-{
-}
-
-otError otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf,
-                                         uint16_t aOutputBufLen,
-                                         uint8_t *aInputBuf,
-                                         uint16_t aInputBufLen,
-                                         bool     aRequestTransactionFlag)
-{
-    OT_UNUSED_VARIABLE(aOutputBuf);
-    OT_UNUSED_VARIABLE(aOutputBufLen);
-    OT_UNUSED_VARIABLE(aInputBuf);
-    OT_UNUSED_VARIABLE(aInputBufLen);
-    OT_UNUSED_VARIABLE(aRequestTransactionFlag);
-
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-// Uart
-
-void otPlatUartSendDone(void)
-{
-}
-
-void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength)
-{
-    OT_UNUSED_VARIABLE(aBuf);
-    OT_UNUSED_VARIABLE(aBufLength);
-}
-
-#endif // OPENTHREAD_CONFIG_NCP_SPI_ENABLE
diff --git a/examples/platforms/posix/system.c b/examples/platforms/posix/system.c
deleted file mode 100644
index e509543..0000000
--- a/examples/platforms/posix/system.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- * @brief
- *   This file includes the platform-specific initializers.
- */
-
-#include "platform-posix.h"
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME == 0
-
-#include <assert.h>
-#include <errno.h>
-#include <libgen.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <syslog.h>
-
-#include <openthread/tasklet.h>
-#include <openthread/platform/alarm-milli.h>
-
-uint32_t gNodeId = 1;
-
-extern bool gPlatformPseudoResetWasRequested;
-
-static volatile bool gTerminate = false;
-
-static void handleSignal(int aSignal)
-{
-    OT_UNUSED_VARIABLE(aSignal);
-
-    gTerminate = true;
-}
-
-void otSysInit(int aArgCount, char *aArgVector[])
-{
-    char *   endptr;
-    uint32_t speedUpFactor = 1;
-
-    if (gPlatformPseudoResetWasRequested)
-    {
-        gPlatformPseudoResetWasRequested = false;
-        return;
-    }
-
-    if (aArgCount < 2)
-    {
-        fprintf(stderr, "Syntax:\n    %s NodeId [TimeSpeedUpFactor]\n", aArgVector[0]);
-        exit(EXIT_FAILURE);
-    }
-
-    openlog(basename(aArgVector[0]), LOG_PID, LOG_USER);
-    setlogmask(setlogmask(0) & LOG_UPTO(LOG_NOTICE));
-
-    signal(SIGTERM, &handleSignal);
-    signal(SIGHUP, &handleSignal);
-
-    gNodeId = (uint32_t)strtol(aArgVector[1], &endptr, 0);
-
-    if (*endptr != '\0' || gNodeId < 1 || gNodeId >= WELLKNOWN_NODE_ID)
-    {
-        fprintf(stderr, "Invalid NodeId: %s\n", aArgVector[1]);
-        exit(EXIT_FAILURE);
-    }
-
-    if (aArgCount > 2)
-    {
-        speedUpFactor = (uint32_t)strtol(aArgVector[2], &endptr, 0);
-
-        if (*endptr != '\0' || speedUpFactor == 0)
-        {
-            fprintf(stderr, "Invalid value for TimerSpeedUpFactor: %s\n", aArgVector[2]);
-            exit(EXIT_FAILURE);
-        }
-    }
-
-    platformAlarmInit(speedUpFactor);
-    platformRadioInit();
-    platformRandomInit();
-}
-
-bool otSysPseudoResetWasRequested(void)
-{
-    return gPlatformPseudoResetWasRequested;
-}
-
-void otSysDeinit(void)
-{
-    platformRadioDeinit();
-}
-
-void otSysProcessDrivers(otInstance *aInstance)
-{
-    fd_set         read_fds;
-    fd_set         write_fds;
-    fd_set         error_fds;
-    int            max_fd = -1;
-    struct timeval timeout;
-    int            rval;
-
-    FD_ZERO(&read_fds);
-    FD_ZERO(&write_fds);
-    FD_ZERO(&error_fds);
-
-    platformUartUpdateFdSet(&read_fds, &write_fds, &error_fds, &max_fd);
-    platformRadioUpdateFdSet(&read_fds, &write_fds, &max_fd);
-    platformAlarmUpdateTimeout(&timeout);
-
-    if (otTaskletsArePending(aInstance))
-    {
-        timeout.tv_sec  = 0;
-        timeout.tv_usec = 0;
-    }
-
-    rval = select(max_fd + 1, &read_fds, &write_fds, &error_fds, &timeout);
-
-    if (rval >= 0)
-    {
-        platformUartProcess();
-        platformRadioProcess(aInstance, &read_fds, &write_fds);
-    }
-    else if (errno != EINTR)
-    {
-        perror("select");
-        exit(EXIT_FAILURE);
-    }
-
-    platformAlarmProcess(aInstance);
-
-    if (gTerminate)
-    {
-        exit(0);
-    }
-}
-
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME == 0
diff --git a/examples/platforms/posix/uart-posix.c b/examples/platforms/posix/uart-posix.c
deleted file mode 100644
index 04d3281..0000000
--- a/examples/platforms/posix/uart-posix.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform-posix.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include <openthread/platform/debug_uart.h>
-#include <openthread/platform/uart.h>
-
-#include "utils/code_utils.h"
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME_UART == 0
-#ifdef OPENTHREAD_TARGET_LINUX
-#include <sys/prctl.h>
-int   posix_openpt(int oflag);
-int   grantpt(int fildes);
-int   unlockpt(int fd);
-char *ptsname(int fd);
-#endif // OPENTHREAD_TARGET_LINUX
-
-static uint8_t        s_receive_buffer[128];
-static const uint8_t *s_write_buffer;
-static uint16_t       s_write_length;
-static int            s_in_fd;
-static int            s_out_fd;
-
-static struct termios original_stdin_termios;
-static struct termios original_stdout_termios;
-
-static void restore_stdin_termios(void)
-{
-    tcsetattr(s_in_fd, TCSAFLUSH, &original_stdin_termios);
-}
-
-static void restore_stdout_termios(void)
-{
-    tcsetattr(s_out_fd, TCSAFLUSH, &original_stdout_termios);
-}
-
-void platformUartRestore(void)
-{
-    restore_stdin_termios();
-    restore_stdout_termios();
-    dup2(s_out_fd, STDOUT_FILENO);
-}
-
-otError otPlatUartEnable(void)
-{
-    otError        error = OT_ERROR_NONE;
-    struct termios termios;
-
-#ifdef OPENTHREAD_TARGET_LINUX
-    // Ensure we terminate this process if the
-    // parent process dies.
-    prctl(PR_SET_PDEATHSIG, SIGHUP);
-#endif
-
-    s_in_fd  = dup(STDIN_FILENO);
-    s_out_fd = dup(STDOUT_FILENO);
-    dup2(STDERR_FILENO, STDOUT_FILENO);
-
-    // We need this signal to make sure that this
-    // process terminates properly.
-    signal(SIGPIPE, SIG_DFL);
-
-    if (isatty(s_in_fd))
-    {
-        tcgetattr(s_in_fd, &original_stdin_termios);
-        atexit(&restore_stdin_termios);
-    }
-
-    if (isatty(s_out_fd))
-    {
-        tcgetattr(s_out_fd, &original_stdout_termios);
-        atexit(&restore_stdout_termios);
-    }
-
-    if (isatty(s_in_fd))
-    {
-        // get current configuration
-        otEXPECT_ACTION(tcgetattr(s_in_fd, &termios) == 0, perror("tcgetattr"); error = OT_ERROR_GENERIC);
-
-        // Set up the termios settings for raw mode. This turns
-        // off input/output processing, line processing, and character processing.
-        cfmakeraw(&termios);
-
-        // Set up our cflags for local use. Turn on hangup-on-close.
-        termios.c_cflag |= HUPCL | CREAD | CLOCAL;
-
-        // "Minimum number of characters for noncanonical read"
-        termios.c_cc[VMIN] = 1;
-
-        // "Timeout in deciseconds for noncanonical read"
-        termios.c_cc[VTIME] = 0;
-
-        // configure baud rate
-        otEXPECT_ACTION(cfsetispeed(&termios, OPENTHREAD_POSIX_UART_BAUDRATE) == 0, perror("cfsetispeed");
-                        error = OT_ERROR_GENERIC);
-
-        // set configuration
-        otEXPECT_ACTION(tcsetattr(s_in_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = OT_ERROR_GENERIC);
-    }
-
-    if (isatty(s_out_fd))
-    {
-        // get current configuration
-        otEXPECT_ACTION(tcgetattr(s_out_fd, &termios) == 0, perror("tcgetattr"); error = OT_ERROR_GENERIC);
-
-        // Set up the termios settings for raw mode. This turns
-        // off input/output processing, line processing, and character processing.
-        cfmakeraw(&termios);
-
-        // Absolutely obliterate all output processing.
-        termios.c_oflag = 0;
-
-        // Set up our cflags for local use. Turn on hangup-on-close.
-        termios.c_cflag |= HUPCL | CREAD | CLOCAL;
-
-        // configure baud rate
-        otEXPECT_ACTION(cfsetospeed(&termios, OPENTHREAD_POSIX_UART_BAUDRATE) == 0, perror("cfsetospeed");
-                        error = OT_ERROR_GENERIC);
-
-        // set configuration
-        otEXPECT_ACTION(tcsetattr(s_out_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = OT_ERROR_GENERIC);
-    }
-
-    return error;
-
-exit:
-    close(s_in_fd);
-    close(s_out_fd);
-    return error;
-}
-
-otError otPlatUartDisable(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    close(s_in_fd);
-    close(s_out_fd);
-
-    return error;
-}
-
-otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
-{
-    otError error = OT_ERROR_NONE;
-
-    otEXPECT_ACTION(s_write_length == 0, error = OT_ERROR_BUSY);
-
-    s_write_buffer = aBuf;
-    s_write_length = aBufLength;
-
-exit:
-    return error;
-}
-
-void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
-{
-    if (aReadFdSet != NULL)
-    {
-        FD_SET(s_in_fd, aReadFdSet);
-
-        if (aErrorFdSet != NULL)
-        {
-            FD_SET(s_in_fd, aErrorFdSet);
-        }
-
-        if (aMaxFd != NULL && *aMaxFd < s_in_fd)
-        {
-            *aMaxFd = s_in_fd;
-        }
-    }
-
-    if ((aWriteFdSet != NULL) && (s_write_length > 0))
-    {
-        FD_SET(s_out_fd, aWriteFdSet);
-
-        if (aErrorFdSet != NULL)
-        {
-            FD_SET(s_out_fd, aErrorFdSet);
-        }
-
-        if (aMaxFd != NULL && *aMaxFd < s_out_fd)
-        {
-            *aMaxFd = s_out_fd;
-        }
-    }
-}
-
-otError otPlatUartFlush(void)
-{
-    otError error = OT_ERROR_NONE;
-    ssize_t count;
-
-    otEXPECT_ACTION(s_write_buffer != NULL && s_write_length > 0, error = OT_ERROR_INVALID_STATE);
-
-    while ((count = write(s_out_fd, s_write_buffer, s_write_length)) > 0 && (s_write_length -= count) > 0)
-    {
-        s_write_buffer += count;
-    }
-
-    if (count != -1)
-    {
-        assert(s_write_length == 0);
-        s_write_buffer = NULL;
-    }
-    else
-    {
-        perror("write(UART)");
-        exit(EXIT_FAILURE);
-    }
-
-exit:
-    return error;
-}
-
-void platformUartProcess(void)
-{
-    ssize_t       rval;
-    const int     error_flags = POLLERR | POLLNVAL | POLLHUP;
-    struct pollfd pollfd[]    = {
-        {s_in_fd, POLLIN | error_flags, 0},
-        {s_out_fd, POLLOUT | error_flags, 0},
-    };
-
-    errno = 0;
-
-    rval = poll(pollfd, sizeof(pollfd) / sizeof(*pollfd), 0);
-
-    if (rval < 0)
-    {
-        perror("poll");
-        exit(EXIT_FAILURE);
-    }
-
-    if (rval > 0)
-    {
-        if ((pollfd[0].revents & error_flags) != 0)
-        {
-            perror("s_in_fd");
-            exit(EXIT_FAILURE);
-        }
-
-        if ((pollfd[1].revents & error_flags) != 0)
-        {
-            perror("s_out_fd");
-            exit(EXIT_FAILURE);
-        }
-
-        if (pollfd[0].revents & POLLIN)
-        {
-            rval = read(s_in_fd, s_receive_buffer, sizeof(s_receive_buffer));
-
-            if (rval <= 0)
-            {
-                perror("read");
-                exit(EXIT_FAILURE);
-            }
-
-            otPlatUartReceived(s_receive_buffer, (uint16_t)rval);
-        }
-
-        if ((s_write_length > 0) && (pollfd[1].revents & POLLOUT))
-        {
-            rval = write(s_out_fd, s_write_buffer, s_write_length);
-
-            if (rval >= 0)
-            {
-                s_write_buffer += (uint16_t)rval;
-                s_write_length -= (uint16_t)rval;
-
-                if (s_write_length == 0)
-                {
-                    otPlatUartSendDone();
-                }
-            }
-            else if (errno != EINTR)
-            {
-                perror("write");
-                exit(EXIT_FAILURE);
-            }
-        }
-    }
-}
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME_UART == 0
-
-#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART && (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART)
-
-static FILE *posix_logfile;
-
-otError otPlatDebugUart_logfile(const char *filename)
-{
-    posix_logfile = fopen(filename, "wt");
-
-    return posix_logfile ? OT_ERROR_NONE : OT_ERROR_FAILED;
-}
-
-void otPlatDebugUart_putchar_raw(int c)
-{
-    FILE *fp;
-
-    /* note: log file will have a mix of cr/lf and
-     * in some/many cases duplicate cr because in
-     * some cases the log function {ie: Mbed} already
-     * includes the CR or LF... but other log functions
-     * do not include cr/lf and expect it appended
-     */
-    fp = posix_logfile;
-
-    if (fp != NULL)
-    {
-        /* log is lost ... until a file is setup */
-        fputc(c, fp);
-        /* we could "fflush" but will not */
-    }
-}
-
-int otPlatDebugUart_kbhit(void)
-{
-    /* not supported */
-    return 0;
-}
-
-int otPlatDebugUart_getc(void)
-{
-    /* not supported */
-    return -1;
-}
-
-#endif
diff --git a/examples/platforms/qpg6095/CMakeLists.txt b/examples/platforms/qpg6095/CMakeLists.txt
new file mode 100644
index 0000000..2851208
--- /dev/null
+++ b/examples/platforms/qpg6095/CMakeLists.txt
@@ -0,0 +1,106 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(OT_PLATFORM_LIB "openthread-qpg6095" PARENT_SCOPE)
+
+if(NOT OT_CONFIG)
+    set(OT_CONFIG "openthread-core-qpg6095-config.h")
+    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES
+    "OPENTHREAD_CORE_CONFIG_PLATFORM_CHECK_FILE=\"openthread-core-qpg6095-config-check.h\""
+)
+set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
+
+target_compile_definitions(ot-config INTERFACE "MBEDTLS_USER_CONFIG_FILE=\"qpg6095-mbedtls-config.h\"")
+
+list(APPEND OT_PUBLIC_INCLUDES
+    "${CMAKE_CURRENT_SOURCE_DIR}/crypto"
+)
+set(OT_PUBLIC_INCLUDES ${OT_PUBLIC_INCLUDES} PARENT_SCOPE)
+
+if(OT_CFLAGS MATCHES "-pedantic-errors")
+    string(REPLACE "-pedantic-errors" "" OT_CFLAGS "${OT_CFLAGS}")
+endif()
+
+if(OT_CFLAGS MATCHES "-Wno-c\\+\\+14-compat")
+    string(REPLACE "-Wno-c++14-compat" "" OT_CFLAGS "${OT_CFLAGS}")
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+
+add_library(openthread-qpg6095
+    alarm.c
+    diag.c
+    entropy.c
+    logging.c
+    misc.c
+    platform.c
+    radio.c
+    settings.cpp
+    uart.c
+)
+
+set_target_properties(
+    openthread-qpg6095
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_link_libraries(openthread-qpg6095
+    PRIVATE
+        qpg6095-driver
+        ${OT_MBEDTLS}
+        ot-config
+)
+
+target_link_options(openthread-qpg6095
+    PUBLIC
+        -T${CMAKE_CURRENT_SOURCE_DIR}/qpg6095.ld
+        -Wl,--gc-sections
+        -Wl,-Map=$<TARGET_PROPERTY:NAME>.map
+)
+
+target_compile_definitions(openthread-qpg6095
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-qpg6095
+    PRIVATE
+        ${OT_CFLAGS}
+)
+
+target_include_directories(openthread-qpg6095
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        ${PROJECT_SOURCE_DIR}/src/core
+        ${PROJECT_SOURCE_DIR}/examples/platforms
+)
diff --git a/examples/platforms/qpg6095/Makefile.am b/examples/platforms/qpg6095/Makefile.am
index 3b24cca..b9122d4 100644
--- a/examples/platforms/qpg6095/Makefile.am
+++ b/examples/platforms/qpg6095/Makefile.am
@@ -28,6 +28,10 @@
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
 
+# Do not enable -Wcast-align for this platform
+override CFLAGS    := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS  := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 lib_LIBRARIES                               = libopenthread-qpg6095.a
 
 libopenthread_qpg6095_a_CPPFLAGS            = \
diff --git a/examples/platforms/qpg6095/arm-none-eabi.cmake b/examples/platforms/qpg6095/arm-none-eabi.cmake
new file mode 100644
index 0000000..227520a
--- /dev/null
+++ b/examples/platforms/qpg6095/arm-none-eabi.cmake
@@ -0,0 +1,50 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(CMAKE_SYSTEM_NAME              Generic)
+set(CMAKE_SYSTEM_PROCESSOR         ARM)
+
+set(CMAKE_C_COMPILER               arm-none-eabi-gcc)
+set(CMAKE_CXX_COMPILER             arm-none-eabi-g++)
+set(CMAKE_ASM_COMPILER             arm-none-eabi-as)
+set(CMAKE_RANLIB                   arm-none-eabi-ranlib)
+
+set(COMMON_C_FLAGS                 "-mcpu=cortex-m4 -mthumb -fdata-sections -ffunction-sections")
+
+set(CMAKE_C_FLAGS                  "${COMMON_C_FLAGS} -std=gnu99")
+set(CMAKE_CXX_FLAGS                "${COMMON_C_FLAGS} -fno-exceptions -fno-rtti")
+set(CMAKE_ASM_FLAGS                "${COMMON_C_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS_INIT    "${COMMON_C_FLAGS} -specs=nano.specs -specs=nosys.specs")
+
+set(CMAKE_C_FLAGS_DEBUG            "-Og -g")
+set(CMAKE_CXX_FLAGS_DEBUG          "-Og -g")
+set(CMAKE_ASM_FLAGS_DEBUG          "-g")
+
+set(CMAKE_C_FLAGS_RELEASE          "-Os")
+set(CMAKE_CXX_FLAGS_RELEASE        "-Os")
+set(CMAKE_ASM_FLAGS_RELEASE        "")
diff --git a/examples/platforms/qpg6095/crypto/qpg6095-mbedtls-config.h b/examples/platforms/qpg6095/crypto/qpg6095-mbedtls-config.h
index a447fcb..95c23b8 100644
--- a/examples/platforms/qpg6095/crypto/qpg6095-mbedtls-config.h
+++ b/examples/platforms/qpg6095/crypto/qpg6095-mbedtls-config.h
@@ -25,4 +25,3 @@
  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  *  POSSIBILITY OF SUCH DAMAGE.
  */
-
diff --git a/examples/platforms/qpg6095/diag.c b/examples/platforms/qpg6095/diag.c
index df89b4e..27f541d 100644
--- a/examples/platforms/qpg6095/diag.c
+++ b/examples/platforms/qpg6095/diag.c
@@ -42,14 +42,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    // Add more plarform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/qpg6095/radio.c b/examples/platforms/qpg6095/radio.c
index 61a82a2..2376214 100644
--- a/examples/platforms/qpg6095/radio.c
+++ b/examples/platforms/qpg6095/radio.c
@@ -263,7 +263,7 @@
     qorvoRadioEnableSrcMatch(aEnable);
 }
 
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
     return qorvoRadioAddSrcMatchShortEntry(aShortAddress, otCachedSettings.panid);
@@ -275,7 +275,7 @@
     return qorvoRadioAddSrcMatchExtEntry(aExtAddress->m8, otCachedSettings.panid);
 }
 
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
     return qorvoRadioClearSrcMatchShortEntry(aShortAddress, otCachedSettings.panid);
diff --git a/examples/platforms/qpg6095/radio_qorvo.h b/examples/platforms/qpg6095/radio_qorvo.h
index 84c56bb..678a096 100644
--- a/examples/platforms/qpg6095/radio_qorvo.h
+++ b/examples/platforms/qpg6095/radio_qorvo.h
@@ -143,7 +143,7 @@
  * @param[in]  panid          The panid.
  *
  */
-otError qorvoRadioAddSrcMatchShortEntry(const uint16_t aShortAddress, uint16_t panid);
+otError qorvoRadioAddSrcMatchShortEntry(uint16_t aShortAddress, uint16_t panid);
 
 /**
  * This function adds an extended address plus panid to the source address match list.
@@ -161,7 +161,7 @@
  * @param[in]  panid          The panid.
  *
  */
-otError qorvoRadioClearSrcMatchShortEntry(const uint16_t aShortAddress, uint16_t panid);
+otError qorvoRadioClearSrcMatchShortEntry(uint16_t aShortAddress, uint16_t panid);
 
 /**
  * This function removes an extended address plus panid from the source address match list.
diff --git a/examples/platforms/qpg6095/settings.cpp b/examples/platforms/qpg6095/settings.cpp
index f4e4108..a6e4e44 100644
--- a/examples/platforms/qpg6095/settings.cpp
+++ b/examples/platforms/qpg6095/settings.cpp
@@ -5,7 +5,7 @@
  *  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
- *     noqtice, this list of conditions and the following disclaimer.
+ *     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.
@@ -72,7 +72,7 @@
 
     if (error == OT_ERROR_NOT_FOUND)
     {
-        if (aValue != NULL)
+        if (aValue != nullptr)
         {
             *aValueLength = 0;
         }
@@ -110,7 +110,7 @@
     otError error = OT_ERROR_NOT_FOUND;
     OT_UNUSED_VARIABLE(aInstance);
 
-    if (otPlatSettingsGet(aInstance, aKey, 0, NULL, NULL) == OT_ERROR_NONE)
+    if (otPlatSettingsGet(aInstance, aKey, 0, nullptr, nullptr) == OT_ERROR_NONE)
     {
         qorvoSettingsDelete(aKey, aIndex);
         error = OT_ERROR_NONE;
diff --git a/examples/platforms/samr21/CMakeLists.txt b/examples/platforms/samr21/CMakeLists.txt
new file mode 100644
index 0000000..48db69f
--- /dev/null
+++ b/examples/platforms/samr21/CMakeLists.txt
@@ -0,0 +1,105 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(OT_PLATFORM_LIB "openthread-samr21" PARENT_SCOPE)
+
+if(NOT OT_CONFIG)
+    set(OT_CONFIG "openthread-core-samr21-config.h")
+    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES
+    "OPENTHREAD_CORE_CONFIG_PLATFORM_CHECK_FILE=\"openthread-core-samr21-config-check.h\""
+)
+set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
+
+target_compile_definitions(ot-config INTERFACE "MBEDTLS_USER_CONFIG_FILE=\"samr21-mbedtls-config.h\"")
+list(APPEND OT_PUBLIC_INCLUDES
+    "${PROJECT_SOURCE_DIR}/examples/platforms/samr21/crypto"
+)
+set(OT_PUBLIC_INCLUDES ${OT_PUBLIC_INCLUDES} PARENT_SCOPE)
+
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+
+add_library(openthread-samr21
+    alarm.c
+    crypto/aes_alt.c
+    cxx_helpers.c
+    diag.c
+    entropy.c
+    flash.c
+    logging.c
+    misc.c
+    radio.c
+    system.c
+    uart.c
+)
+
+set_target_properties(
+    openthread-samr21
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+if(OT_CFLAGS MATCHES "-pedantic-errors")
+    string(REPLACE "-pedantic-errors" "" OT_CFLAGS "${OT_CFLAGS}")
+endif()
+
+target_link_libraries(openthread-samr21
+    PUBLIC
+        samr21-driver
+    PRIVATE
+        ${OT_MBEDTLS}
+        ot-config
+)
+
+target_link_options(openthread-samr21
+    PUBLIC
+        -Wl,--gc-sections
+        -Wl,-Map=$<TARGET_PROPERTY:NAME>.map
+)
+
+target_compile_definitions(openthread-samr21
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-samr21
+    PRIVATE
+        -Wno-implicit-function-declaration
+        -Wno-expansion-to-defined
+        ${OT_CFLAGS}
+)
+
+target_include_directories(openthread-samr21
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        ${PROJECT_SOURCE_DIR}/src/core
+        ${PROJECT_SOURCE_DIR}/examples/platforms
+)
diff --git a/examples/platforms/samr21/Makefile.am b/examples/platforms/samr21/Makefile.am
index e5a21ac..f7763c2 100644
--- a/examples/platforms/samr21/Makefile.am
+++ b/examples/platforms/samr21/Makefile.am
@@ -37,6 +37,10 @@
 override CFLAGS                              := $(filter-out -Wundef,$(CFLAGS))
 override CXXFLAGS                            := $(filter-out -Wundef,$(CXXFLAGS))
 
+# Do not enable -Wcast-align for this platform
+override CFLAGS                              := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                            := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 libopenthread_samr21_a_CPPFLAGS                                                                              = \
     -D ARM_MATH_CM0PLUS=true                                                                                   \
     -D PHY_AT86RF233                                                                                           \
@@ -137,10 +141,6 @@
     @top_builddir@/third_party/microchip/asf/thirdparty/wireless/services/trx_access/trx_access.c              \
     $(NULL)
 
-PRETTY_FILES                                                                                                 = \
-    $(PLATFORM_SOURCES)                                                                                        \
-    $(NULL)
-
 Dash                                                                                                         = -
 libopenthread_samr21_a_LIBADD                                                                                = \
     $(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
diff --git a/examples/platforms/samr21/README.md b/examples/platforms/samr21/README.md
index a7635db..24f4346 100644
--- a/examples/platforms/samr21/README.md
+++ b/examples/platforms/samr21/README.md
@@ -1,14 +1,11 @@
 # OpenThread on SAMR21 Example
 
-This directory contains example platform drivers for the [Microchip ATSAMR21G18A][samr21]
-based on [SAM R21 Xplained Pro Evaluation Kit][SAMR21_XPLAINED_PRO].
+This directory contains example platform drivers for the [Microchip ATSAMR21G18A][samr21] based on [SAM R21 Xplained Pro Evaluation Kit][samr21_xplained_pro].
 
 [samr21]: http://www.microchip.com/wwwproducts/en/ATSAMR21G18A
-[SAMR21_XPLAINED_PRO]: https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMR21-XPRO
+[samr21_xplained_pro]: https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMR21-XPRO
 
-The example platform drivers are intended to present the minimal code
-necessary to support OpenThread. See the "Run the example with SAMR21 boards" section below
-for an example using basic OpenThread capabilities.
+The example platform drivers are intended to present the minimal code necessary to support OpenThread. See the "Run the example with SAMR21 boards" section below for an example using basic OpenThread capabilities.
 
 ## Toolchain
 
@@ -16,8 +13,7 @@
 
 [gnu-toolchain]: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm
 
-In a Bash terminal, follow these instructions to install the GNU toolchain and
-other dependencies.
+In a Bash terminal, follow these instructions to install the GNU toolchain and other dependencies.
 
 ```bash
 $ cd <path-to-openthread>
@@ -26,14 +22,14 @@
 
 ## Build Examples
 
-1. Download [Advanced Software Framework (ASF)][ASF].
+1. Download [Advanced Software Framework (ASF)][asf].
 
-[ASF]: https://www.microchip.com/mplab/avr-support/advanced-software-framework
+[asf]: https://www.microchip.com/mplab/avr-support/advanced-software-framework
 
 2. Unzip it to <path-to-openthread>/third_party/microchip folder
 
 ```bash
-$ unzip asf-standalone-archive-3.45.0.85.zip 
+$ unzip asf-standalone-archive-3.45.0.85.zip
 $ cp xdk-asf-3.45.0 -rf  <path-to-openthread>/third_party/microchip/asf
 ```
 
@@ -46,34 +42,32 @@
 ```
 
 4. This example can be built for other SAMR21 based modules e.g.:
-* [ATSAMR21G18-MR210UA][MODULE-MR210UA]
-* [ATSAMR21B18-MZ210PA][MODULE-MZ210PA]
+
+- [ATSAMR21G18-MR210UA][module-mr210ua]
+- [ATSAMR21B18-MZ210PA][module-mz210pa]
 
 To build for these modules set BOARD variable in command line as following:
+
 ```bash
 $ make -f examples/Makefile-samr21 BOARD=<MODULE>
 ```
 
 where:
 
-
 | `<module>`            | Board                               |
-| ----------------------|-------------------------------------|
+| --------------------- | ----------------------------------- |
 | `SAMR21_XPLAINED_PRO` | SAM R21 Xplained Pro Evaluation Kit |
 | `SAMR21G18_MODULE`    | ATSAMR21G18-MR210UA                 |
 | `SAMR21B18_MODULE`    | ATSAMR21B18-MZ210PA                 |
 
-[MODULE-MR210UA]: http://ww1.microchip.com/downloads/en/devicedoc/atmel-42475-atsamr21g18-mr210ua_datasheet.pdf
-[MODULE-MZ210PA]: http://ww1.microchip.com/downloads/en/devicedoc/atmel-42486-atsamr21b18-mz210pa_datasheet.pdf
+[module-mr210ua]: http://ww1.microchip.com/downloads/en/devicedoc/atmel-42475-atsamr21g18-mr210ua_datasheet.pdf
+[module-mz210pa]: http://ww1.microchip.com/downloads/en/devicedoc/atmel-42486-atsamr21b18-mz210pa_datasheet.pdf
 
-
-After a successful build, the `elf` files are found in
-`<path-to-openthread>/output/samr21/bin`.
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/samr21/bin`.
 
 ## Flash Binaries
 
-Compiled binaries may be flashed onto the SAM R21 Xplained Pro using embedded
-debugger EDBG.
+Compiled binaries may be flashed onto the SAM R21 Xplained Pro using embedded debugger EDBG.
 
 ```bash
 $ openocd -f board/atmel_samr21_xplained_pro.cfg
@@ -86,9 +80,9 @@
 ```
 
 ## Run the example with SAM R21 Xplained Pro boards
+
 1. Flash two SAM R21 Xplained Pro boards with the `CLI example` firmware (as shown above).
-2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1).
-   Type `help` for a list of commands.
+2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1). Type `help` for a list of commands.
 
    ```bash
    > help
@@ -147,13 +141,13 @@
 
    wait a couple of seconds...
 
-   > state
-   leader
-   Done
+   > state leader Done
+
    ```
 
-4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1)
-   and attach it to the Thread network as a Router.
+   ```
+
+4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1) and attach it to the Thread network as a Router.
 
    ```bash
    > dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
@@ -192,8 +186,7 @@
    16 bytes from fd3d:b50b:f96d:722d:558:f56b:d688:799: icmp_seq=1 hlim=64 time=24ms
    ```
 
-The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner,
-joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
+The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner, joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
 
 ```bash
 $ cd <path-to-openthread>
@@ -201,14 +194,15 @@
 $ make -f examples/Makefile-samr21 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1
 ```
 
-For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
+For a list of all available commands, visit [OpenThread CLI Reference README.md][cli].
 
-[CLI]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
+[cli]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
 
 ## Other boards
 
 ## Verification
 
 The following toolchain has been used for testing and verification:
-   - gcc version 7.3.1
-   - Advanced Software Framework (ASF) version 3.45.0
+
+- gcc version 7.3.1
+- Advanced Software Framework (ASF) version 3.45.0
diff --git a/examples/platforms/samr21/arm-none-eabi.cmake b/examples/platforms/samr21/arm-none-eabi.cmake
new file mode 100644
index 0000000..ff983a5
--- /dev/null
+++ b/examples/platforms/samr21/arm-none-eabi.cmake
@@ -0,0 +1,50 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(CMAKE_SYSTEM_NAME              Generic)
+set(CMAKE_SYSTEM_PROCESSOR         ARM)
+
+set(CMAKE_C_COMPILER               arm-none-eabi-gcc)
+set(CMAKE_CXX_COMPILER             arm-none-eabi-g++)
+set(CMAKE_ASM_COMPILER             arm-none-eabi-as)
+set(CMAKE_RANLIB                   arm-none-eabi-ranlib)
+
+set(COMMON_C_FLAGS                 "-mcpu=cortex-m0plus -mfloat-abi=soft -mthumb -fdata-sections -ffunction-sections")
+
+set(CMAKE_C_FLAGS                  "${COMMON_C_FLAGS} -std=gnu99")
+set(CMAKE_CXX_FLAGS                "${COMMON_C_FLAGS} -fno-exceptions -fno-rtti")
+set(CMAKE_ASM_FLAGS                "${COMMON_C_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS_INIT    "${COMMON_C_FLAGS} -specs=nano.specs -specs=nosys.specs -Wl,--entry=Reset_Handler")
+
+set(CMAKE_C_FLAGS_DEBUG            "-Og -g")
+set(CMAKE_CXX_FLAGS_DEBUG          "-Og -g")
+set(CMAKE_ASM_FLAGS_DEBUG          "-g")
+
+set(CMAKE_C_FLAGS_RELEASE          "-Os")
+set(CMAKE_CXX_FLAGS_RELEASE        "-Os")
+set(CMAKE_ASM_FLAGS_RELEASE        "")
diff --git a/examples/platforms/samr21/crypto/aes_alt.h b/examples/platforms/samr21/crypto/aes_alt.h
index 7707688..cfe3729 100644
--- a/examples/platforms/samr21/crypto/aes_alt.h
+++ b/examples/platforms/samr21/crypto/aes_alt.h
@@ -43,9 +43,9 @@
 
 typedef struct
 {
-        uint8_t hwKeyLen;
-        unsigned char aes_enc_key[32]; /* Encryption key */
-        unsigned char aes_dec_key[32]; /* Decryption key */
+    uint8_t       hwKeyLen;
+    unsigned char aes_enc_key[32]; /* Encryption key */
+    unsigned char aes_dec_key[32]; /* Decryption key */
 } mbedtls_aes_context;
 
 /**
@@ -71,8 +71,7 @@
  *
  * \return         0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
  */
-int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
-                           unsigned int keybits);
+int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits);
 
 /**
  * \brief          AES key schedule (decryption)
@@ -83,8 +82,7 @@
  *
  * \return         0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
  */
-int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
-                           unsigned int keybits);
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits);
 
 /**
  * \brief          AES-ECB block encryption/decryption
@@ -96,8 +94,7 @@
  *
  * \return         0 if successful
  */
-int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16],
-                          unsigned char output[16]);
+int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16]);
 
 /**
  * \brief          AES-CBC buffer encryption/decryption
@@ -121,12 +118,12 @@
  *
  * \return         0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
  */
-int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
-                    int mode,
-                    size_t length,
-                    unsigned char iv[16],
-                    const unsigned char *input,
-                    unsigned char *output );
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int                  mode,
+                          size_t               length,
+                          unsigned char        iv[16],
+                          const unsigned char *input,
+                          unsigned char *      output);
 
 /**
  * \brief               AES-CTR buffer encryption/decryption
@@ -150,13 +147,13 @@
  *
  * \return         0 if successful
  */
-int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
-                       size_t length,
-                       size_t *nc_off,
-                       unsigned char nonce_counter[16],
-                       unsigned char stream_block[16],
-                       const unsigned char *input,
-                       unsigned char *output );
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t               length,
+                          size_t *             nc_off,
+                          unsigned char        nonce_counter[16],
+                          unsigned char        stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *      output);
 
 #ifdef __cplusplus
 }
diff --git a/examples/platforms/samr21/crypto/samr21-mbedtls-config.h b/examples/platforms/samr21/crypto/samr21-mbedtls-config.h
index 8da1d8b..193a689 100644
--- a/examples/platforms/samr21/crypto/samr21-mbedtls-config.h
+++ b/examples/platforms/samr21/crypto/samr21-mbedtls-config.h
@@ -25,7 +25,7 @@
  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  *  POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
 #ifndef SAMR21_MBEDTLS_CONFIG_H
 #define SAMR21_MBEDTLS_CONFIG_H
 
diff --git a/examples/platforms/samr21/diag.c b/examples/platforms/samr21/diag.c
index 67f9806..856abf8 100644
--- a/examples/platforms/samr21/diag.c
+++ b/examples/platforms/samr21/diag.c
@@ -45,15 +45,6 @@
  */
 static bool sDiagMode = false;
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
-
-    // Add more platform specific diagnostics features here.
-    snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
-}
-
 void otPlatDiagModeSet(bool aMode)
 {
     sDiagMode = aMode;
diff --git a/examples/platforms/samr21/flash.c b/examples/platforms/samr21/flash.c
index 35765f7..2feb467 100644
--- a/examples/platforms/samr21/flash.c
+++ b/examples/platforms/samr21/flash.c
@@ -31,112 +31,98 @@
  *   This file implements the OpenThread platform abstraction for the non-volatile storage.
  */
 
+#include <string.h>
+
+#include <openthread/instance.h>
+
 #include "asf.h"
 
-#include "utils/code_utils.h"
-#include "utils/flash.h"
+#define OT_FLASH_BASE_ADDRESS ((uint32_t)&__d_nv_mem_start)
+#define OT_FLASH_PAGE_SIZE 0x100
 
-#include "openthread-core-samr21-config.h"
+/*
+ * This value should not exceed:
+ *     (((uint32_t)&__d_nv_mem_end - (uint32_t)&__d_nv_mem_start) / OT_FLASH_PAGE_SIZE)
+ *
+ * __d_nv_mem_start and __d_nv_mem_end is defined in linker script.
+ * The size of NVRAM region is 4k. Page size is 256 bytes. Maximum OT_FLASH_PAGE_NUM
+ * should be equal or less than 16.
+ *
+ */
+#define OT_FLASH_PAGE_NUM 16
 
-otError utilsFlashInit(void)
+#define OT_FLASH_SWAP_SIZE (OT_FLASH_PAGE_SIZE * (OT_FLASH_PAGE_NUM / 2))
+
+extern uint32_t __d_nv_mem_start;
+extern uint32_t __d_nv_mem_end;
+
+static uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
 {
-    otError           error = OT_ERROR_NONE;
+    uint32_t address = OT_FLASH_BASE_ADDRESS + aOffset;
+
+    if (aSwapIndex)
+    {
+        address += OT_FLASH_SWAP_SIZE;
+    }
+
+    return address;
+}
+
+void otPlatFlashInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
     struct nvm_config configNvm;
+    enum status_code  status;
 
     nvm_get_config_defaults(&configNvm);
 
     configNvm.manual_page_write = false;
-
-    enum status_code status;
-
     while ((status = nvm_set_config(&configNvm)) == STATUS_BUSY)
-        ;
-
-    if (status != STATUS_OK)
     {
-        error = OT_ERROR_FAILED;
     }
-
-    return error;
 }
 
-uint32_t utilsFlashGetSize(void)
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
 {
-    return SETTINGS_CONFIG_PAGE_NUM * SETTINGS_CONFIG_PAGE_SIZE;
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return OT_FLASH_SWAP_SIZE;
 }
 
-otError utilsFlashErasePage(uint32_t aAddress)
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
 {
-    otError error = OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
 
-    if (nvm_erase_row(aAddress) != STATUS_OK)
+    nvm_erase_row(mapAddress(aSwapIndex, 0));
+    while (!nvm_is_ready())
     {
-        error = OT_ERROR_FAILED;
     }
-
-    return error;
 }
 
-otError utilsFlashStatusWait(uint32_t aTimeout)
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
 {
-    otError  error = OT_ERROR_BUSY;
-    uint32_t start = otPlatAlarmMilliGetNow();
+    OT_UNUSED_VARIABLE(aInstance);
 
-    do
-    {
-        if (nvm_is_ready())
-        {
-            error = OT_ERROR_NONE;
-            break;
-        }
-    } while (aTimeout && ((otPlatAlarmMilliGetNow() - start) < aTimeout));
-
-    return error;
-}
-
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
-{
-    uint32_t rval = aSize;
-
-    otEXPECT_ACTION(aData, rval = 0);
-    otEXPECT_ACTION(aAddress >= SETTINGS_CONFIG_BASE_ADDRESS, rval = 0);
-    otEXPECT_ACTION((aAddress - SETTINGS_CONFIG_BASE_ADDRESS + aSize) <= utilsFlashGetSize(), rval = 0);
-    otEXPECT_ACTION(((aAddress & 3) == 0) && ((aSize & 3) == 0), rval = 0);
+    uint32_t address = mapAddress(aSwapIndex, aOffset);
 
     for (uint32_t i = 0; i < (aSize / sizeof(uint32_t)); i++)
     {
-        *((volatile uint32_t *)aAddress) = *((uint32_t *)aData);
+        *((volatile uint32_t *)address) = *((uint32_t *)aData);
         aData += sizeof(uint32_t);
-        aAddress += sizeof(uint32_t);
+        address += sizeof(uint32_t);
     }
 
     // check if write page command is required
-    if ((aAddress) & (NVMCTRL_PAGE_SIZE - 1))
+    if ((address) & (NVMCTRL_PAGE_SIZE - 1))
     {
-        enum status_code status;
-
-        status = nvm_execute_command(NVM_COMMAND_WRITE_PAGE, aAddress & (~(NVMCTRL_PAGE_SIZE - 1)), 0);
-
-        otEXPECT_ACTION(status == STATUS_OK, rval = 0);
+        nvm_execute_command(NVM_COMMAND_WRITE_PAGE, address & (~(NVMCTRL_PAGE_SIZE - 1)), 0);
     }
-
-exit:
-    return rval;
 }
 
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
 {
-    uint32_t rval = aSize;
+    OT_UNUSED_VARIABLE(aInstance);
 
-    otEXPECT_ACTION(aData, rval = 0);
-    otEXPECT_ACTION(aAddress >= SETTINGS_CONFIG_BASE_ADDRESS, rval = 0);
-    otEXPECT_ACTION((aAddress - SETTINGS_CONFIG_BASE_ADDRESS + aSize) <= utilsFlashGetSize(), rval = 0);
-
-    while (aSize--)
-    {
-        *aData++ = (*(uint8_t *)(aAddress++));
-    }
-
-exit:
-    return rval;
+    memcpy(aData, (void *)mapAddress(aSwapIndex, aOffset), aSize);
 }
diff --git a/examples/platforms/samr21/logging.c b/examples/platforms/samr21/logging.c
index a8f938a..926f314 100644
--- a/examples/platforms/samr21/logging.c
+++ b/examples/platforms/samr21/logging.c
@@ -32,20 +32,19 @@
  *
  */
 
-#include <openthread-core-config.h>
+#include "openthread-core-config.h"
+
 #include <utils/code_utils.h>
-#include <openthread/config.h>
 #include <openthread/platform/logging.h>
 #include <openthread/platform/toolchain.h>
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
-
-#if BOARD == SAMR21_XPLAINED_PRO
-
 #include "board.h"
 #include "spi.h"
 
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
+
+#if BOARD == SAMR21_XPLAINED_PRO
+
 #define LOG_PARSE_BUFFER_SIZE 128
 #define LOG_TIMESTAMP_ENABLE 1
 
diff --git a/examples/platforms/samr21/openthread-core-samr21-config.h b/examples/platforms/samr21/openthread-core-samr21-config.h
index 1809ff4..0397a42 100644
--- a/examples/platforms/samr21/openthread-core-samr21-config.h
+++ b/examples/platforms/samr21/openthread-core-samr21-config.h
@@ -49,35 +49,14 @@
 #define OPENTHREAD_CONFIG_PLATFORM_INFO "SAMR21"
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
  *
- * The base address of settings.
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
  *
  */
-#define SETTINGS_CONFIG_BASE_ADDRESS ((uint32_t)&__d_nv_mem_start)
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#define SETTINGS_CONFIG_PAGE_SIZE 0x100
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- * This value should not exceeds:
- *     (((uint32_t)&__d_nv_mem_end - (uint32_t)&__d_nv_mem_start) / SETTINGS_CONFIG_PAGE_SIZE)
- *
- * __d_nv_mem_start and __d_nv_mem_end is defined in linker script.
- * The size of NVRAM region is 4k. Page size is 256 bytes. Maximum SETTINGS_CONFIG_PAGE_NUM
- * should be equal or less than 16.
- *
- */
-#define SETTINGS_CONFIG_PAGE_NUM 16
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
 
 /**
  * @def RADIO_CONFIG_SRC_MATCH_ENTRY_NUM
diff --git a/examples/platforms/samr21/radio.c b/examples/platforms/samr21/radio.c
index 1f951e1..b38011c 100644
--- a/examples/platforms/samr21/radio.c
+++ b/examples/platforms/samr21/radio.c
@@ -586,7 +586,7 @@
     OT_UNUSED_VARIABLE(aEnable);
 }
 
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     return OT_ERROR_NOT_IMPLEMENTED;
 }
@@ -596,7 +596,7 @@
     return OT_ERROR_NOT_IMPLEMENTED;
 }
 
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     return OT_ERROR_NOT_IMPLEMENTED;
 }
diff --git a/examples/platforms/samr21/system.c b/examples/platforms/samr21/system.c
index 804f1c6..da4a9bc 100644
--- a/examples/platforms/samr21/system.c
+++ b/examples/platforms/samr21/system.c
@@ -174,8 +174,7 @@
     getKitData();
 #endif
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
     samr21LogInit();
 #endif
     samr21AlarmInit();
diff --git a/examples/platforms/simulation/CMakeLists.txt b/examples/platforms/simulation/CMakeLists.txt
new file mode 100644
index 0000000..c103432
--- /dev/null
+++ b/examples/platforms/simulation/CMakeLists.txt
@@ -0,0 +1,112 @@
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(OT_PLATFORM_LIB "openthread-simulation" PARENT_SCOPE)
+
+option(OT_SIMULATION_VIRTUAL_TIME "enable virtual time")
+if(OT_SIMULATION_VIRTUAL_TIME)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_SIMULATION_VIRTUAL_TIME=1")
+endif()
+
+option(OT_SIMULATION_VIRTUAL_TIME_UART "enable virtual time for UART")
+if(OT_SIMULATION_VIRTUAL_TIME_UART)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART=1")
+endif()
+
+if(NOT OT_CONFIG)
+    set(OT_CONFIG "openthread-core-simulation-config.h")
+    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES
+    "_BSD_SOURCE=1"
+    "_DEFAULT_SOURCE=1"
+    "OPENTHREAD_EXAMPLES_SIMULATION=1"
+    "OPENTHREAD_POSIX=1"
+    "OPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
+)
+set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
+
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+
+add_library(openthread-simulation
+    alarm.c
+    diag.c
+    entropy.c
+    flash.c
+    logging.c
+    misc.c
+    radio.c
+    spi-stubs.c
+    system.c
+    uart.c
+    virtual_time/alarm-sim.c
+    virtual_time/otns.c
+    virtual_time/platform-sim.c
+    $<TARGET_OBJECTS:openthread-platform-utils>
+)
+
+set_target_properties(
+    openthread-simulation
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+find_library(LIBRT rt)
+if(LIBRT)
+    target_link_libraries(openthread-simulation PRIVATE ${LIBRT})
+endif()
+
+target_link_libraries(openthread-simulation PRIVATE
+    openthread-platform
+    ot-config)
+
+target_compile_definitions(openthread-simulation
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-simulation PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_include_directories(openthread-simulation PRIVATE
+    ${OT_PUBLIC_INCLUDES}
+    ${PROJECT_SOURCE_DIR}/examples/platforms
+    ${PROJECT_SOURCE_DIR}/src
+    ${PROJECT_SOURCE_DIR}/src/core
+)
+
+if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
+    set(CPACK_PACKAGE_NAME "openthread-simulation")
+    set(CPACK_GENERATOR "DEB")
+    set(CPACK_DEBIAN_PACKAGE_MAINTAINER "OpenThread Authors <openthread-users@googlegroups.com")
+    set(CPACK_PACKAGE_CONTACT "OpenThread Authors <openthread-users@googlegroups.com")
+    include(CPack)
+endif()
diff --git a/examples/platforms/simulation/Makefile.am b/examples/platforms/simulation/Makefile.am
new file mode 100644
index 0000000..6e3b40d
--- /dev/null
+++ b/examples/platforms/simulation/Makefile.am
@@ -0,0 +1,79 @@
+#
+#  Copyright (c) 2016, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+include $(top_srcdir)/src/lib/common.am
+
+lib_LIBRARIES                             = libopenthread-simulation.a
+
+libopenthread_simulation_a_CPPFLAGS       = \
+    -I$(top_srcdir)/include                 \
+    -I$(top_srcdir)/examples/platforms      \
+    -I$(top_srcdir)/src                     \
+    -I$(top_srcdir)/src/core                \
+    -D_GNU_SOURCE                           \
+    $(NULL)
+
+PLATFORM_SOURCES                          = \
+    alarm.c                                 \
+    diag.c                                  \
+    entropy.c                               \
+    flash.c                                 \
+    logging.c                               \
+    misc.c                                  \
+    openthread-core-simulation-config.h     \
+    platform-config.h                       \
+    platform-simulation.h                   \
+    radio.c                                 \
+    spi-stubs.c                             \
+    system.c                                \
+    uart.c                                  \
+    virtual_time/alarm-sim.c                \
+    virtual_time/otns.c                     \
+    virtual_time/platform-sim.c             \
+    $(NULL)
+
+libopenthread_simulation_a_SOURCES        = \
+    $(PLATFORM_SOURCES)                     \
+    $(NULL)
+
+Dash                                      = -
+libopenthread_simulation_a_LIBADD         = \
+    $(call ot_list_objects,$(top_builddir)/examples/platforms/utils/libopenthread-platform-utils.a) \
+    $(call ot_list_objects,$(top_builddir)/src/lib/platform/libopenthread-platform.a)               \
+    $(NULL)
+
+if OPENTHREAD_BUILD_COVERAGE
+libopenthread_simulation_a_CPPFLAGS      += \
+    -DOPENTHREAD_ENABLE_COVERAGE            \
+    $(NULL)
+
+CLEANFILES                                = $(wildcard *.gcda *.gcno)
+endif # OPENTHREAD_BUILD_COVERAGE
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/examples/platforms/simulation/Makefile.platform.am b/examples/platforms/simulation/Makefile.platform.am
new file mode 100644
index 0000000..d2cb725
--- /dev/null
+++ b/examples/platforms/simulation/Makefile.platform.am
@@ -0,0 +1,41 @@
+#
+#  Copyright (c) 2017, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Simulation platform-specific Makefile
+#
+
+LDADD_COMMON                                                                 += \
+    $(top_builddir)/examples/platforms/simulation/libopenthread-simulation.a    \
+    $(NULL)
+
+if OPENTHREAD_TARGET_LINUX
+LDADD_COMMON                                                          += \
+    -lrt                                                                 \
+    $(NULL)
+endif
diff --git a/examples/platforms/simulation/README.md b/examples/platforms/simulation/README.md
new file mode 100644
index 0000000..cc3bdb6
--- /dev/null
+++ b/examples/platforms/simulation/README.md
@@ -0,0 +1,72 @@
+# OpenThread Simulation on POSIX
+
+This directory contains example platform drivers for simulation on POSIX.
+
+## Build Examples
+
+### Build using autotools
+
+```bash
+$ cd <path-to-openthread>
+$ ./bootstrap
+$ make -f examples/Makefile-simulation
+```
+
+After a successful build, the `elf` files are found in:
+
+- `<path-to-openthread>/output/<platform>/bin`
+
+### Build using cmake/ninja
+
+```bash
+$ cd <path-to-openthread>
+$ mkdir build && cd build
+$ cmake -GNinja -DOT_PLATFORM=simulation ..
+$ ninja
+```
+
+After a successful build, the `elf` files are found in:
+
+- `<path-to-openthread>/build/examples/apps/cli`
+- `<path-to-openthread>/build/examples/apps/ncp`
+
+## Interact
+
+1. Spawn the process:
+
+```bash
+$ cd <path-to-openthread>/output/<platform>/bin
+$ ./ot-cli-ftd 1
+```
+
+2. Type `help` for list of commands.
+
+```bash
+> help
+help
+channel
+childtimeout
+contextreusedelay
+extaddr
+extpanid
+ipaddr
+keysequence
+leaderweight
+masterkey
+mode
+netdataregister
+networkidtimeout
+networkname
+panid
+ping
+prefix
+releaserouterid
+rloc16
+route
+routerupgradethreshold
+scan
+start
+state
+stop
+whitelist
+```
diff --git a/examples/platforms/simulation/alarm.c b/examples/platforms/simulation/alarm.c
new file mode 100644
index 0000000..4157e5e
--- /dev/null
+++ b/examples/platforms/simulation/alarm.c
@@ -0,0 +1,320 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "utils/code_utils.h"
+
+#ifdef __linux__
+#include <signal.h>
+#include <time.h>
+
+#ifndef OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL
+#define OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL SIGRTMIN
+#endif
+
+timer_t sMicroTimer;
+#endif // __linux__
+
+#include <openthread/platform/alarm-micro.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+
+#include "core/common/logging.hpp"
+#include "lib/platform/exit_code.h"
+
+#define MS_PER_S 1000
+#define NS_PER_US 1000
+#define US_PER_MS 1000
+#define US_PER_S 1000000
+
+#define DEFAULT_TIMEOUT 10 // seconds
+
+#ifdef CLOCK_MONOTONIC_RAW
+#define OT_SIMULATION_CLOCK_ID CLOCK_MONOTONIC_RAW
+#else
+#define OT_SIMULATION_CLOCK_ID CLOCK_MONOTONIC
+#endif
+
+static bool     sIsMsRunning = false;
+static uint32_t sMsAlarm     = 0;
+
+static bool     sIsUsRunning = false;
+static uint32_t sUsAlarm     = 0;
+
+static uint32_t sSpeedUpFactor = 1;
+
+#ifdef __linux__
+static void microTimerHandler(int aSignal, siginfo_t *aSignalInfo, void *aUserContext)
+{
+    assert(aSignal == OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL);
+    assert(aSignalInfo->si_value.sival_ptr == &sMicroTimer);
+    (void)aSignal;
+    (void)aSignalInfo;
+    (void)aUserContext;
+}
+#endif
+
+void platformAlarmInit(uint32_t aSpeedUpFactor)
+{
+    sSpeedUpFactor = aSpeedUpFactor;
+
+#ifdef __linux__
+    {
+        struct sigaction sa;
+
+        sa.sa_flags     = SA_SIGINFO;
+        sa.sa_sigaction = microTimerHandler;
+        sigemptyset(&sa.sa_mask);
+
+        if (sigaction(OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL, &sa, NULL) == -1)
+        {
+            perror("sigaction");
+            exit(EXIT_FAILURE);
+        }
+
+        struct sigevent sev;
+
+        sev.sigev_notify          = SIGEV_SIGNAL;
+        sev.sigev_signo           = OPENTHREAD_CONFIG_MICRO_TIMER_SIGNAL;
+        sev.sigev_value.sival_ptr = &sMicroTimer;
+
+        if (-1 == timer_create(CLOCK_MONOTONIC, &sev, &sMicroTimer))
+        {
+            perror("timer_create");
+            exit(EXIT_FAILURE);
+        }
+    }
+#endif
+}
+
+#if defined(CLOCK_MONOTONIC_RAW) || defined(CLOCK_MONOTONIC)
+uint64_t platformGetNow(void)
+{
+    struct timespec now;
+    int             err;
+
+    err = clock_gettime(OT_SIMULATION_CLOCK_ID, &now);
+
+    VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
+
+    return (uint64_t)now.tv_sec * sSpeedUpFactor * US_PER_S + (uint64_t)now.tv_nsec * sSpeedUpFactor / NS_PER_US;
+}
+#else
+uint64_t platformGetNow(void)
+{
+    struct timeval tv;
+    int            err;
+
+    err = gettimeofday(&tv, NULL);
+
+    assert(err == 0);
+
+    return (uint64_t)tv.tv_sec * sSpeedUpFactor * US_PER_S + (uint64_t)tv.tv_usec * sSpeedUpFactor;
+}
+#endif // defined(CLOCK_MONOTONIC_RAW) || defined(CLOCK_MONOTONIC)
+
+uint32_t otPlatAlarmMilliGetNow(void)
+{
+    return (uint32_t)(platformGetNow() / US_PER_MS);
+}
+
+void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sMsAlarm     = aT0 + aDt;
+    sIsMsRunning = true;
+}
+
+void otPlatAlarmMilliStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sIsMsRunning = false;
+}
+
+uint32_t otPlatAlarmMicroGetNow(void)
+{
+    return (uint32_t)platformGetNow();
+}
+
+void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sUsAlarm     = aT0 + aDt;
+    sIsUsRunning = true;
+
+#ifdef __linux__
+    {
+        struct itimerspec its;
+        uint32_t          diff = sUsAlarm - otPlatAlarmMicroGetNow();
+
+        its.it_value.tv_sec  = diff / US_PER_S;
+        its.it_value.tv_nsec = (diff % US_PER_S) * NS_PER_US;
+
+        its.it_interval.tv_sec  = 0;
+        its.it_interval.tv_nsec = 0;
+
+        if (-1 == timer_settime(sMicroTimer, 0, &its, NULL))
+        {
+            perror("otPlatAlarmMicroStartAt timer_settime()");
+            exit(EXIT_FAILURE);
+        }
+    }
+#endif // __linux__
+}
+
+void otPlatAlarmMicroStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sIsUsRunning = false;
+
+#ifdef __linux__
+    {
+        struct itimerspec its = {{0, 0}, {0, 0}};
+
+        if (-1 == timer_settime(sMicroTimer, 0, &its, NULL))
+        {
+            perror("otPlatAlarmMicroStop timer_settime()");
+            exit(EXIT_FAILURE);
+        }
+    }
+#endif // __linux__
+}
+
+void platformAlarmUpdateTimeout(struct timeval *aTimeout)
+{
+    int32_t usRemaining = DEFAULT_TIMEOUT * US_PER_S;
+    int32_t msRemaining = DEFAULT_TIMEOUT * MS_PER_S;
+
+    if (aTimeout == NULL)
+    {
+        return;
+    }
+
+    if (sIsUsRunning)
+    {
+        usRemaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
+    }
+
+    if (sIsMsRunning)
+    {
+        msRemaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
+    }
+
+    if (usRemaining <= 0 || msRemaining <= 0)
+    {
+        aTimeout->tv_sec  = 0;
+        aTimeout->tv_usec = 0;
+    }
+    else
+    {
+        int64_t remaining = ((int64_t)msRemaining) * US_PER_MS;
+
+        if (usRemaining < remaining)
+        {
+            remaining = usRemaining;
+        }
+
+        remaining /= sSpeedUpFactor;
+
+        if (remaining == 0)
+        {
+            remaining = 1;
+        }
+
+        aTimeout->tv_sec  = (time_t)remaining / US_PER_S;
+        aTimeout->tv_usec = remaining % US_PER_S;
+    }
+}
+
+void platformAlarmProcess(otInstance *aInstance)
+{
+    int32_t remaining;
+
+    if (sIsMsRunning)
+    {
+        remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
+
+        if (remaining <= 0)
+        {
+            sIsMsRunning = false;
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+            if (otPlatDiagModeGet())
+            {
+                otPlatDiagAlarmFired(aInstance);
+            }
+            else
+#endif
+            {
+                otPlatAlarmMilliFired(aInstance);
+            }
+        }
+    }
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+
+    if (sIsUsRunning)
+    {
+        remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
+
+        if (remaining <= 0)
+        {
+            sIsUsRunning = false;
+
+            otPlatAlarmMicroFired(aInstance);
+        }
+    }
+
+#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+}
+
+uint64_t otPlatTimeGet(void)
+{
+    return platformGetNow();
+}
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+uint16_t otPlatTimeGetXtalAccuracy(void)
+{
+    return 0;
+}
+#endif
+
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
diff --git a/examples/platforms/simulation/diag.c b/examples/platforms/simulation/diag.c
new file mode 100644
index 0000000..ddb8c26
--- /dev/null
+++ b/examples/platforms/simulation/diag.c
@@ -0,0 +1,80 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <openthread/config.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/radio.h>
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+/**
+ * Diagnostics mode variables.
+ *
+ */
+static bool sDiagMode = false;
+
+void otPlatDiagModeSet(bool aMode)
+{
+    sDiagMode = aMode;
+}
+
+bool otPlatDiagModeGet()
+{
+    return sDiagMode;
+}
+
+void otPlatDiagChannelSet(uint8_t aChannel)
+{
+    OT_UNUSED_VARIABLE(aChannel);
+}
+
+void otPlatDiagTxPowerSet(int8_t aTxPower)
+{
+    OT_UNUSED_VARIABLE(aTxPower);
+}
+
+void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aFrame);
+    OT_UNUSED_VARIABLE(aError);
+}
+
+void otPlatDiagAlarmCallback(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
diff --git a/examples/platforms/simulation/entropy.c b/examples/platforms/simulation/entropy.c
new file mode 100644
index 0000000..bcb04a4
--- /dev/null
+++ b/examples/platforms/simulation/entropy.c
@@ -0,0 +1,136 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements an entropy source based on /dev/urandom or pseudo-random generator.
+ *
+ */
+
+#include "platform-simulation.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <openthread/platform/entropy.h>
+
+#include "utils/code_utils.h"
+
+#ifndef __SANITIZE_ADDRESS__
+#define __SANITIZE_ADDRESS__ 0
+#endif
+
+#if __SANITIZE_ADDRESS__ != 0
+
+static uint32_t sState = 1;
+
+#endif // __SANITIZE_ADDRESS__
+
+void platformRandomInit(void)
+{
+#if __SANITIZE_ADDRESS__ != 0
+
+    // Multiplying gNodeId assures that no two nodes gets the same seed within an hour.
+    sState = (uint32_t)time(NULL) + (3600 * gNodeId);
+
+#endif // __SANITIZE_ADDRESS__
+}
+
+#if __SANITIZE_ADDRESS__ != 0
+
+static uint32_t randomUint32Get(void)
+{
+    uint32_t mlcg, p, q;
+    uint64_t tmpstate;
+
+    tmpstate = (uint64_t)33614 * (uint64_t)sState;
+    q        = tmpstate & 0xffffffff;
+    q        = q >> 1;
+    p        = tmpstate >> 32;
+    mlcg     = p + q;
+
+    if (mlcg & 0x80000000)
+    {
+        mlcg &= 0x7fffffff;
+        mlcg++;
+    }
+
+    sState = mlcg;
+
+    return mlcg;
+}
+
+#endif // __SANITIZE_ADDRESS__
+
+otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
+{
+    otError error = OT_ERROR_NONE;
+
+#if __SANITIZE_ADDRESS__ == 0
+
+    FILE * file = NULL;
+    size_t readLength;
+
+    otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
+
+    file = fopen("/dev/urandom", "rb");
+    otEXPECT_ACTION(file != NULL, error = OT_ERROR_FAILED);
+
+    readLength = fread(aOutput, 1, aOutputLength, file);
+    otEXPECT_ACTION(readLength == aOutputLength, error = OT_ERROR_FAILED);
+
+exit:
+
+    if (file != NULL)
+    {
+        fclose(file);
+    }
+
+#else // __SANITIZE_ADDRESS__
+
+    /*
+     * THE IMPLEMENTATION BELOW IS NOT COMPLIANT WITH THE THREAD SPECIFICATION.
+     *
+     * Address Sanitizer triggers test failures when reading random
+     * values from /dev/urandom.  The pseudo-random number generator
+     * implementation below is only used to enable continuous
+     * integration checks with Address Sanitizer enabled.
+     */
+    otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
+
+    for (uint16_t length = 0; length < aOutputLength; length++)
+    {
+        aOutput[length] = (uint8_t)randomUint32Get();
+    }
+
+exit:
+
+#endif // __SANITIZE_ADDRESS__
+
+    return error;
+}
diff --git a/examples/platforms/simulation/flash.c b/examples/platforms/simulation/flash.c
new file mode 100644
index 0000000..fe634a8
--- /dev/null
+++ b/examples/platforms/simulation/flash.c
@@ -0,0 +1,157 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <openthread/config.h>
+#include <openthread/platform/flash.h>
+
+#include "core/common/logging.hpp"
+#include "lib/platform/exit_code.h"
+
+static int sFlashFd = -1;
+
+enum
+{
+    SWAP_SIZE = 2048,
+    SWAP_NUM  = 2,
+};
+
+void otPlatFlashInit(otInstance *aInstance)
+{
+    const char *path = OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH;
+    char        fileName[sizeof(OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH) + 32];
+    struct stat st;
+    bool        create = false;
+    const char *offset = getenv("PORT_OFFSET");
+
+    memset(&st, 0, sizeof(st));
+
+    if (stat(path, &st) == -1)
+    {
+        mkdir(path, 0777);
+    }
+
+    if (offset == NULL)
+    {
+        offset = "0";
+    }
+
+    snprintf(fileName, sizeof(fileName), "%s/%s_%d.flash", path, offset, gNodeId);
+
+    if (access(fileName, 0))
+    {
+        create = true;
+    }
+
+    sFlashFd = open(fileName, O_RDWR | O_CREAT | O_CLOEXEC, 0600);
+    lseek(sFlashFd, 0, SEEK_SET);
+
+    VerifyOrDie(sFlashFd >= 0, OT_EXIT_ERROR_ERRNO);
+
+    if (create)
+    {
+        for (uint8_t index = 0; index < SWAP_NUM; index++)
+        {
+            otPlatFlashErase(aInstance, index);
+        }
+    }
+}
+
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return SWAP_SIZE;
+}
+
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint8_t  buffer[SWAP_SIZE];
+    uint32_t address;
+    ssize_t  rval;
+
+    assert((sFlashFd >= 0) && (aSwapIndex < SWAP_NUM));
+
+    address = aSwapIndex ? SWAP_SIZE : 0;
+    memset(buffer, 0xff, sizeof(buffer));
+
+    rval = pwrite(sFlashFd, buffer, sizeof(buffer), (off_t)address);
+    VerifyOrDie(rval == SWAP_SIZE, OT_EXIT_ERROR_ERRNO);
+}
+
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address;
+    ssize_t  rval;
+
+    assert((sFlashFd >= 0) && (aSwapIndex < SWAP_NUM) && (aSize <= SWAP_SIZE) && (aOffset <= (SWAP_SIZE - aSize)));
+
+    address = aSwapIndex ? SWAP_SIZE : 0;
+
+    rval = pread(sFlashFd, aData, aSize, (off_t)(address + aOffset));
+    VerifyOrDie((uint32_t)rval == aSize, OT_EXIT_ERROR_ERRNO);
+}
+
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address;
+    uint8_t  byte;
+    ssize_t  rval;
+
+    assert((sFlashFd >= 0) && (aSwapIndex < SWAP_NUM) && (aSize <= SWAP_SIZE) && (aOffset <= (SWAP_SIZE - aSize)));
+
+    address = aSwapIndex ? SWAP_SIZE : 0;
+    address += aOffset;
+
+    for (uint32_t offset = 0; offset < aSize; offset++)
+    {
+        rval = pread(sFlashFd, &byte, sizeof(byte), (off_t)(address + offset));
+        VerifyOrDie(rval == sizeof(byte), OT_EXIT_ERROR_ERRNO);
+
+        // Use bitwise AND to emulate the behavior of flash memory
+        byte &= ((uint8_t *)aData)[offset];
+
+        rval = pwrite(sFlashFd, &byte, sizeof(byte), (off_t)(address + offset));
+        VerifyOrDie(rval == sizeof(byte), OT_EXIT_ERROR_ERRNO);
+    }
+}
diff --git a/examples/platforms/simulation/logging.c b/examples/platforms/simulation/logging.c
new file mode 100644
index 0000000..5b0d6ea
--- /dev/null
+++ b/examples/platforms/simulation/logging.c
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+#include <openthread-core-config.h>
+#include <openthread/config.h>
+
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <openthread/platform/logging.h>
+#include <openthread/platform/toolchain.h>
+
+#include "utils/code_utils.h"
+
+// Macro to append content to end of the log string.
+
+#define LOG_PRINTF(...)                                                                   \
+    charsWritten = snprintf(&logString[offset], sizeof(logString) - offset, __VA_ARGS__); \
+    otEXPECT_ACTION(charsWritten >= 0, logString[offset] = 0);                            \
+    offset += (unsigned int)charsWritten;                                                 \
+    otEXPECT_ACTION(offset < sizeof(logString), logString[sizeof(logString) - 1] = 0)
+
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
+OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
+{
+    OT_UNUSED_VARIABLE(aLogLevel);
+    OT_UNUSED_VARIABLE(aLogRegion);
+
+    char         logString[512];
+    unsigned int offset;
+    int          charsWritten;
+    va_list      args;
+
+    offset = 0;
+
+    LOG_PRINTF("[%d] ", gNodeId);
+
+    va_start(args, aFormat);
+    charsWritten = vsnprintf(&logString[offset], sizeof(logString) - offset, aFormat, args);
+    va_end(args);
+
+    otEXPECT_ACTION(charsWritten >= 0, logString[offset] = 0);
+
+exit:
+    syslog(LOG_CRIT, "%s", logString);
+}
+
+#endif // #if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
diff --git a/examples/platforms/simulation/misc.c b/examples/platforms/simulation/misc.c
new file mode 100644
index 0000000..aefbca5
--- /dev/null
+++ b/examples/platforms/simulation/misc.c
@@ -0,0 +1,101 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#include <setjmp.h>
+#include <unistd.h>
+
+#include <openthread/platform/misc.h>
+
+#include "openthread-system.h"
+
+extern jmp_buf gResetJump;
+
+static otPlatResetReason   sPlatResetReason = OT_PLAT_RESET_REASON_POWER_ON;
+bool                       gPlatformPseudoResetWasRequested;
+static otPlatMcuPowerState gPlatMcuPowerState = OT_PLAT_MCU_POWER_STATE_ON;
+
+void otPlatReset(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+#if OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+    gPlatformPseudoResetWasRequested = true;
+    sPlatResetReason                 = OT_PLAT_RESET_REASON_SOFTWARE;
+
+#else // OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+    // Restart the process using execvp.
+    otSysDeinit();
+    platformUartRestore();
+
+    longjmp(gResetJump, 1);
+    assert(false);
+
+#endif // OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+}
+
+otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return sPlatResetReason;
+}
+
+void otPlatWakeHost(void)
+{
+    // TODO: implement an operation to wake the host from sleep state.
+}
+
+otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NONE;
+
+    switch (aState)
+    {
+    case OT_PLAT_MCU_POWER_STATE_ON:
+    case OT_PLAT_MCU_POWER_STATE_LOW_POWER:
+        gPlatMcuPowerState = aState;
+        break;
+
+    default:
+        error = OT_ERROR_FAILED;
+        break;
+    }
+
+    return error;
+}
+
+otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return gPlatMcuPowerState;
+}
diff --git a/examples/platforms/simulation/openthread-core-simulation-config.h b/examples/platforms/simulation/openthread-core-simulation-config.h
new file mode 100644
index 0000000..9fd31ac
--- /dev/null
+++ b/examples/platforms/simulation/openthread-core-simulation-config.h
@@ -0,0 +1,172 @@
+/*
+ *  Copyright (c) 2017, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes simulation compile-time configuration constants
+ *   for OpenThread.
+ */
+
+#ifndef OPENTHREAD_CORE_SIMULATION_CONFIG_H_
+#define OPENTHREAD_CORE_SIMULATION_CONFIG_H_
+
+#ifndef OPENTHREAD_RADIO
+#define OPENTHREAD_RADIO 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_INFO
+ *
+ * The platform-specific string to insert into the OpenThread version string.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_INFO "SIMULATION"
+
+/**
+ * @def OPENTHREAD_CONFIG_LOG_OUTPUT
+ *
+ * Specify where the log output should go.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
+#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
+ *
+ * Define as 1 to enable support for adding of auto-configured SLAAC addresses by OpenThread.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE /* allows command line override */
+#define OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 1
+#endif
+
+#if OPENTHREAD_RADIO
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
+ *
+ * Define to 1 if you want to enable software ACK timeout logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 1
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
+ *
+ * Define to 1 if you want to enable software energy scanning logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 1
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
+ *
+ * Define to 1 if you want to enable software retransmission logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
+ *
+ * Define to 1 if you want to enable software CSMA-CA backoff logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+#endif
+#endif // OPENTHREAD_RADIO
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+ *
+ * Define to 1 if you want to support microsecond timer in platform.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+ *
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
+
+/**
+ * @def CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
+ *
+ * Define to 1 to use DefaultHandler for unhandled requests
+ *
+ */
+#define CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER 1
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
+ *
+ * Define to 1 if you want to enable radio coexistence implemented in platform.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
+#define OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE 1
+#endif
+
+#ifndef OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
+#define OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_LOG_PLATFORM
+ *
+ * Define to enable platform region logging.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_PLATFORM
+#define OPENTHREAD_CONFIG_LOG_PLATFORM 1
+#endif
+
+#endif // OPENTHREAD_CORE_SIMULATION_CONFIG_H_
diff --git a/examples/platforms/simulation/platform-config.h b/examples/platforms/simulation/platform-config.h
new file mode 100644
index 0000000..6305cb5
--- /dev/null
+++ b/examples/platforms/simulation/platform-config.h
@@ -0,0 +1,95 @@
+/*
+ *  Copyright (c) 2018, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes the platform-specific configuration.
+ *
+ */
+
+/**
+ * @def OPENTHREAD_SIMULATION_UART_BAUDRATE
+ *
+ * This setting configures the baud rate of the UART.
+ *
+ */
+#ifndef OPENTHREAD_SIMULATION_UART_BAUDRATE
+#define OPENTHREAD_SIMULATION_UART_BAUDRATE B115200
+#endif
+
+/**
+ * @def OPENTHREAD_SIMULATION_VIRTUAL_TIME
+ *
+ * This setting configures whether to use virtual time (used for simulation) in simulation platform.
+ *
+ */
+#ifndef OPENTHREAD_SIMULATION_VIRTUAL_TIME
+#define OPENTHREAD_SIMULATION_VIRTUAL_TIME 0
+#endif
+
+/**
+ * @def OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART
+ *
+ * This setting configures whether to use virtual time for UART.
+ *
+ */
+#ifndef OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART
+#define OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART 0
+#endif
+
+/**
+ * @def OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+ *
+ * Define as 1 to enable pseudo-reset.
+ *
+ */
+#ifndef OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
+#define OPENTHREAD_PLATFORM_USE_PSEUDO_RESET 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_NCP_SPI_ENABLE
+ *
+ * Define as 1 to enable SPI NCP interface.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_NCP_SPI_ENABLE
+#define OPENTHREAD_CONFIG_NCP_SPI_ENABLE 0
+#endif
+
+/**
+ * Check OTNS configurations
+ *
+ */
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+
+#if !OPENTHREAD_SIMULATION_VIRTUAL_TIME
+#error "OTNS requires virtual time simulations"
+#endif
+
+#endif // OPENTHREAD_CONFIG_OTNS_ENABLE
diff --git a/examples/platforms/simulation/platform-simulation.h b/examples/platforms/simulation/platform-simulation.h
new file mode 100644
index 0000000..b80ab0a
--- /dev/null
+++ b/examples/platforms/simulation/platform-simulation.h
@@ -0,0 +1,238 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *   This file includes the platform-specific initializers.
+ */
+
+#ifndef PLATFORM_SIMULATION_H_
+#define PLATFORM_SIMULATION_H_
+
+#include <openthread-core-config.h>
+#include <openthread/config.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <signal.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <openthread/instance.h>
+
+#include "openthread-core-config.h"
+#include "platform-config.h"
+
+enum
+{
+    OT_SIM_EVENT_ALARM_FIRED        = 0,
+    OT_SIM_EVENT_RADIO_RECEIVED     = 1,
+    OT_SIM_EVENT_UART_WRITE         = 2,
+    OT_SIM_EVENT_RADIO_SPINEL_WRITE = 3,
+    OT_SIM_EVENT_OTNS_STATUS_PUSH   = 5,
+    OT_EVENT_DATA_MAX_SIZE          = 1024,
+};
+
+OT_TOOL_PACKED_BEGIN
+struct Event
+{
+    uint64_t mDelay;
+    uint8_t  mEvent;
+    uint16_t mDataLength;
+    uint8_t  mData[OT_EVENT_DATA_MAX_SIZE];
+} OT_TOOL_PACKED_END;
+
+enum
+{
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+    WELLKNOWN_NODE_ID = 1000, ///< Well-known Unique ID used by a simulated radio that supports promiscuous mode.
+#else
+    WELLKNOWN_NODE_ID = 34, ///< Well-known Unique ID used by a simulated radio that supports promiscuous mode.
+#endif
+};
+
+/**
+ * Unique node ID.
+ *
+ */
+extern uint32_t gNodeId;
+
+/**
+ * This function initializes the alarm service used by OpenThread.
+ *
+ */
+void platformAlarmInit(uint32_t aSpeedUpFactor);
+
+/**
+ * This function retrieves the time remaining until the alarm fires.
+ *
+ * @param[out]  aTimeval  A pointer to the timeval struct.
+ *
+ */
+void platformAlarmUpdateTimeout(struct timeval *tv);
+
+/**
+ * This function performs alarm driver processing.
+ *
+ * @param[in]  aInstance  The OpenThread instance structure.
+ *
+ */
+void platformAlarmProcess(otInstance *aInstance);
+
+/**
+ * This function returns the next alarm event time.
+ *
+ * @returns The next alarm fire time.
+ *
+ */
+int32_t platformAlarmGetNext(void);
+
+/**
+ * This function returns the current alarm time.
+ *
+ * @returns The current alarm time.
+ *
+ */
+uint64_t platformAlarmGetNow(void);
+
+/**
+ * This function advances the alarm time by @p aDelta.
+ *
+ * @param[in]  aDelta  The amount of time to advance.
+ *
+ */
+void platformAlarmAdvanceNow(uint64_t aDelta);
+
+/**
+ * This function initializes the radio service used by OpenThread.
+ *
+ */
+void platformRadioInit(void);
+
+/**
+ * This function shuts down the radio service used by OpenThread.
+ *
+ */
+void platformRadioDeinit(void);
+
+/**
+ * This function inputs a received radio frame.
+ *
+ * @param[in]  aInstance   A pointer to the OpenThread instance.
+ * @param[in]  aBuf        A pointer to the received radio frame.
+ * @param[in]  aBufLength  The size of the received radio frame.
+ *
+ */
+void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLength);
+
+/**
+ * This function updates the file descriptor sets with file descriptors used by the radio driver.
+ *
+ * @param[inout]  aReadFdSet   A pointer to the read file descriptors.
+ * @param[inout]  aWriteFdSet  A pointer to the write file descriptors.
+ * @param[inout]  aMaxFd       A pointer to the max file descriptor.
+ *
+ */
+void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd);
+
+/**
+ * This function performs radio driver processing.
+ *
+ * @param[in]  aInstance    The OpenThread instance structure.
+ * @param[in]  aReadFdSet   A pointer to the read file descriptors.
+ * @param[in]  aWriteFdSet  A pointer to the write file descriptors.
+ *
+ */
+void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet);
+
+/**
+ * This function initializes the random number service used by OpenThread.
+ *
+ */
+void platformRandomInit(void);
+
+/**
+ * This function updates the file descriptor sets with file descriptors used by the UART driver.
+ *
+ * @param[inout]  aReadFdSet   A pointer to the read file descriptors.
+ * @param[inout]  aWriteFdSet  A pointer to the write file descriptors.
+ * @param[inout]  aMaxFd       A pointer to the max file descriptor.
+ *
+ */
+void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd);
+
+/**
+ * This function performs radio driver processing.
+ *
+ */
+void platformUartProcess(void);
+
+/**
+ * This function restores the Uart.
+ *
+ */
+void platformUartRestore(void);
+
+/**
+ * This function sends a simulation event.
+ *
+ * @param[in]   aEvent  A pointer to the simulation event to send
+ *
+ */
+void otSimSendEvent(const struct Event *aEvent);
+
+/**
+ * This function sends Uart data through simulation.
+ *
+ * @param[in]   aData       A pointer to the UART data.
+ * @param[in]   aLength     Length of UART data.
+ *
+ */
+void otSimSendUartWriteEvent(const uint8_t *aData, uint16_t aLength);
+
+/**
+ * This function checks if radio transmitting is pending.
+ *
+ * @returns Whether radio transmitting is pending.
+ *
+ */
+bool platformRadioIsTransmitPending(void);
+
+#endif // PLATFORM_SIMULATION_H_
diff --git a/examples/platforms/simulation/radio.c b/examples/platforms/simulation/radio.c
new file mode 100644
index 0000000..028b910
--- /dev/null
+++ b/examples/platforms/simulation/radio.c
@@ -0,0 +1,1045 @@
+/*
+ *  Copyright (c) 2016-2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#include <errno.h>
+
+#include <openthread/dataset.h>
+#include <openthread/random_noncrypto.h>
+#include <openthread/platform/alarm-micro.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+#include <openthread/platform/radio.h>
+#include <openthread/platform/time.h>
+
+#include "utils/code_utils.h"
+#include "utils/mac_frame.h"
+#include "utils/soft_source_match_table.h"
+
+// The IPv4 group for receiving packets of radio simulation
+#define OT_RADIO_GROUP "224.0.0.116"
+
+enum
+{
+    IEEE802154_ACK_LENGTH = 5,
+
+    IEEE802154_FRAME_TYPE_ACK = 2 << 0,
+
+    IEEE802154_FRAME_PENDING = 1 << 4,
+};
+
+enum
+{
+    SIM_RECEIVE_SENSITIVITY = -100, // dBm
+
+    SIM_HIGH_RSSI_SAMPLE               = -30, // dBm
+    SIM_LOW_RSSI_SAMPLE                = -98, // dBm
+    SIM_HIGH_RSSI_PROB_INC_PER_CHANNEL = 5,
+};
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME
+extern int      sSockFd;
+extern uint16_t sPortOffset;
+#else
+static int      sTxFd       = -1;
+static int      sRxFd       = -1;
+static uint16_t sPortOffset = 0;
+static uint16_t sPort       = 0;
+#endif
+
+enum
+{
+    SIM_RADIO_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
+    SIM_RADIO_CHANNEL_MAX = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX,
+};
+
+OT_TOOL_PACKED_BEGIN
+struct RadioMessage
+{
+    uint8_t mChannel;
+    uint8_t mPsdu[OT_RADIO_FRAME_MAX_SIZE];
+} OT_TOOL_PACKED_END;
+
+static void radioTransmit(struct RadioMessage *aMessage, const struct otRadioFrame *aFrame);
+static void radioSendMessage(otInstance *aInstance);
+static void radioSendAck(void);
+static void radioProcessFrame(otInstance *aInstance);
+
+static otRadioState        sState = OT_RADIO_STATE_DISABLED;
+static struct RadioMessage sReceiveMessage;
+static struct RadioMessage sTransmitMessage;
+static struct RadioMessage sAckMessage;
+static otRadioFrame        sReceiveFrame;
+static otRadioFrame        sTransmitFrame;
+static otRadioFrame        sAckFrame;
+
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+static otRadioIeInfo sTransmitIeInfo;
+#endif
+
+static otExtAddress   sExtAddress;
+static otShortAddress sShortAddress;
+static otPanId        sPanid;
+static bool           sPromiscuous = false;
+static bool           sTxWait      = false;
+static int8_t         sTxPower     = 0;
+static int8_t         sCcaEdThresh = -74;
+
+static bool sSrcMatchEnabled = false;
+
+#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
+static bool sRadioCoexEnabled = true;
+#endif
+
+otRadioCaps gRadioCaps =
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    OT_RADIO_CAPS_TRANSMIT_SEC;
+#else
+    OT_RADIO_CAPS_NONE;
+#endif
+
+static uint32_t        sMacFrameCounter;
+static uint8_t         sKeyId;
+static struct otMacKey sPrevKey;
+static struct otMacKey sCurrKey;
+static struct otMacKey sNextKey;
+
+static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin)
+{
+    for (size_t i = 0; i < sizeof(*aReversed); i++)
+    {
+        aReversed->m8[i] = aOrigin->m8[sizeof(*aOrigin) - 1 - i];
+    }
+}
+
+static bool HasFramePending(const otRadioFrame *aFrame)
+{
+    bool         rval = false;
+    otMacAddress src;
+
+    otEXPECT_ACTION(sSrcMatchEnabled, rval = true);
+    otEXPECT(otMacFrameGetSrcAddr(aFrame, &src) == OT_ERROR_NONE);
+
+    switch (src.mType)
+    {
+    case OT_MAC_ADDRESS_TYPE_SHORT:
+        rval = utilsSoftSrcMatchShortFindEntry(src.mAddress.mShortAddress) >= 0;
+        break;
+    case OT_MAC_ADDRESS_TYPE_EXTENDED:
+    {
+        otExtAddress extAddr;
+
+        ReverseExtAddress(&extAddr, &src.mAddress.mExtAddress);
+        rval = utilsSoftSrcMatchExtFindEntry(&extAddr) >= 0;
+        break;
+    }
+    default:
+        break;
+    }
+
+exit:
+    return rval;
+}
+
+static uint16_t crc16_citt(uint16_t aFcs, uint8_t aByte)
+{
+    // CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
+    // width=16 poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189 name="KERMIT"
+    // http://reveng.sourceforge.net/crc-catalogue/16.htm#crc.cat.kermit
+    static const uint16_t sFcsTable[256] = {
+        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5,
+        0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52,
+        0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3,
+        0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9,
+        0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e,
+        0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f,
+        0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862,
+        0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb,
+        0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948,
+        0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226,
+        0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497,
+        0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704,
+        0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb,
+        0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c,
+        0x3de3, 0x2c6a, 0x1ef1, 0x0f78};
+    return (aFcs >> 8) ^ sFcsTable[(aFcs ^ aByte) & 0xff];
+}
+
+void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    aIeeeEui64[0] = 0x18;
+    aIeeeEui64[1] = 0xb4;
+    aIeeeEui64[2] = 0x30;
+    aIeeeEui64[3] = 0x00;
+    aIeeeEui64[4] = (gNodeId >> 24) & 0xff;
+    aIeeeEui64[5] = (gNodeId >> 16) & 0xff;
+    aIeeeEui64[6] = (gNodeId >> 8) & 0xff;
+    aIeeeEui64[7] = gNodeId & 0xff;
+}
+
+void otPlatRadioSetPanId(otInstance *aInstance, otPanId aPanid)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    sPanid = aPanid;
+    utilsSoftSrcMatchSetPanId(aPanid);
+}
+
+void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    ReverseExtAddress(&sExtAddress, aExtAddress);
+}
+
+void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    sShortAddress = aAddress;
+}
+
+void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    sPromiscuous = aEnable;
+}
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+static void initFds(void)
+{
+    int                fd;
+    int                one = 1;
+    struct sockaddr_in sockaddr;
+
+    memset(&sockaddr, 0, sizeof(sockaddr));
+
+    otEXPECT_ACTION((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1, perror("socket(sTxFd)"));
+
+    sPort                    = (uint16_t)(9000 + sPortOffset + gNodeId);
+    sockaddr.sin_family      = AF_INET;
+    sockaddr.sin_port        = htons(sPort);
+    sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+    otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &sockaddr.sin_addr, sizeof(sockaddr.sin_addr)) != -1,
+                    perror("setsockopt(sTxFd, IP_MULTICAST_IF)"));
+
+    otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one)) != -1,
+                    perror("setsockopt(sRxFd, IP_MULTICAST_LOOP)"));
+
+    otEXPECT_ACTION(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != -1, perror("bind(sTxFd)"));
+
+    // Tx fd is successfully initialized.
+    sTxFd = fd;
+
+    otEXPECT_ACTION((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1, perror("socket(sRxFd)"));
+
+    otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != -1,
+                    perror("setsockopt(sRxFd, SO_REUSEADDR)"));
+    otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != -1,
+                    perror("setsockopt(sRxFd, SO_REUSEPORT)"));
+
+    {
+        struct ip_mreqn mreq;
+
+        memset(&mreq, 0, sizeof(mreq));
+        inet_pton(AF_INET, OT_RADIO_GROUP, &mreq.imr_multiaddr);
+
+        // Always use loopback device to send simulation packets.
+        mreq.imr_address.s_addr = inet_addr("127.0.0.1");
+
+        otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq.imr_address, sizeof(mreq.imr_address)) != -1,
+                        perror("setsockopt(sRxFd, IP_MULTICAST_IF)"));
+        otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != -1,
+                        perror("setsockopt(sRxFd, IP_ADD_MEMBERSHIP)"));
+    }
+
+    sockaddr.sin_family      = AF_INET;
+    sockaddr.sin_port        = htons((uint16_t)(9000 + sPortOffset + WELLKNOWN_NODE_ID));
+    sockaddr.sin_addr.s_addr = inet_addr(OT_RADIO_GROUP);
+
+    otEXPECT_ACTION(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != -1, perror("bind(sRxFd)"));
+
+    // Rx fd is successfully initialized.
+    sRxFd = fd;
+
+exit:
+    if (sRxFd == -1 || sTxFd == -1)
+    {
+        exit(EXIT_FAILURE);
+    }
+}
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+
+void platformRadioInit(void)
+{
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+    char *offset;
+
+    offset = getenv("PORT_OFFSET");
+
+    if (offset)
+    {
+        char *endptr;
+
+        sPortOffset = (uint16_t)strtol(offset, &endptr, 0);
+
+        if (*endptr != '\0')
+        {
+            fprintf(stderr, "Invalid PORT_OFFSET: %s\n", offset);
+            exit(EXIT_FAILURE);
+        }
+
+        sPortOffset *= WELLKNOWN_NODE_ID;
+    }
+
+    initFds();
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+
+    sReceiveFrame.mPsdu  = sReceiveMessage.mPsdu;
+    sTransmitFrame.mPsdu = sTransmitMessage.mPsdu;
+    sAckFrame.mPsdu      = sAckMessage.mPsdu;
+
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+    sTransmitFrame.mInfo.mTxInfo.mIeInfo = &sTransmitIeInfo;
+#else
+    sTransmitFrame.mInfo.mTxInfo.mIeInfo = NULL;
+#endif
+}
+
+bool otPlatRadioIsEnabled(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return (sState != OT_RADIO_STATE_DISABLED) ? true : false;
+}
+
+otError otPlatRadioEnable(otInstance *aInstance)
+{
+    if (!otPlatRadioIsEnabled(aInstance))
+    {
+        sState = OT_RADIO_STATE_SLEEP;
+    }
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioDisable(otInstance *aInstance)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT(otPlatRadioIsEnabled(aInstance));
+    otEXPECT_ACTION(sState == OT_RADIO_STATE_SLEEP, error = OT_ERROR_INVALID_STATE);
+
+    sState = OT_RADIO_STATE_DISABLED;
+
+exit:
+    return error;
+}
+
+otError otPlatRadioSleep(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    otError error = OT_ERROR_INVALID_STATE;
+
+    if (sState == OT_RADIO_STATE_SLEEP || sState == OT_RADIO_STATE_RECEIVE)
+    {
+        error  = OT_ERROR_NONE;
+        sState = OT_RADIO_STATE_SLEEP;
+    }
+
+    return error;
+}
+
+otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    otError error = OT_ERROR_INVALID_STATE;
+
+    if (sState != OT_RADIO_STATE_DISABLED)
+    {
+        error                  = OT_ERROR_NONE;
+        sState                 = OT_RADIO_STATE_RECEIVE;
+        sTxWait                = false;
+        sReceiveFrame.mChannel = aChannel;
+    }
+
+    return error;
+}
+
+otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aRadio)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aRadio);
+
+    assert(aInstance != NULL);
+    assert(aRadio != NULL);
+
+    otError error = OT_ERROR_INVALID_STATE;
+
+    if (sState == OT_RADIO_STATE_RECEIVE)
+    {
+        error  = OT_ERROR_NONE;
+        sState = OT_RADIO_STATE_TRANSMIT;
+    }
+
+    return error;
+}
+
+otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    return &sTransmitFrame;
+}
+
+int8_t otPlatRadioGetRssi(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    int8_t   rssi    = SIM_LOW_RSSI_SAMPLE;
+    uint8_t  channel = sReceiveFrame.mChannel;
+    uint32_t probabilityThreshold;
+
+    otEXPECT((SIM_RADIO_CHANNEL_MIN <= channel) && channel <= (SIM_RADIO_CHANNEL_MAX));
+
+    // To emulate a simple interference model, we return either a high or
+    // a low  RSSI value with a fixed probability per each channel. The
+    // probability is increased per channel by a constant.
+
+    probabilityThreshold = (channel - SIM_RADIO_CHANNEL_MIN) * SIM_HIGH_RSSI_PROB_INC_PER_CHANNEL;
+
+    if (otRandomNonCryptoGetUint16() < (probabilityThreshold * 0xffff / 100))
+    {
+        rssi = SIM_HIGH_RSSI_SAMPLE;
+    }
+
+exit:
+    return rssi;
+}
+
+otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    return gRadioCaps;
+}
+
+bool otPlatRadioGetPromiscuous(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    return sPromiscuous;
+}
+
+static void radioReceive(otInstance *aInstance)
+{
+    bool isTxDone = false;
+    bool isAck    = otMacFrameIsAck(&sReceiveFrame);
+
+    otEXPECT(sReceiveFrame.mChannel == sReceiveMessage.mChannel);
+    otEXPECT(sState == OT_RADIO_STATE_RECEIVE || sState == OT_RADIO_STATE_TRANSMIT);
+
+    // Unable to simulate SFD, so use the rx done timestamp instead.
+    sReceiveFrame.mInfo.mRxInfo.mTimestamp = otPlatTimeGet();
+
+    if (sTxWait)
+    {
+        if (otMacFrameIsAckRequested(&sTransmitFrame))
+        {
+            isTxDone = isAck && otMacFrameGetSequence(&sReceiveFrame) == otMacFrameGetSequence(&sTransmitFrame);
+        }
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME
+        // Simulate tx done when receiving the echo frame.
+        else
+        {
+            isTxDone = !isAck && sTransmitFrame.mLength == sReceiveFrame.mLength &&
+                       memcmp(sTransmitFrame.mPsdu, sReceiveFrame.mPsdu, sTransmitFrame.mLength) == 0;
+        }
+#endif
+    }
+
+    if (isTxDone)
+    {
+        sState  = OT_RADIO_STATE_RECEIVE;
+        sTxWait = false;
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+        if (otPlatDiagModeGet())
+        {
+            otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_NONE);
+        }
+        else
+#endif
+        {
+            otPlatRadioTxDone(aInstance, &sTransmitFrame, (isAck ? &sReceiveFrame : NULL), OT_ERROR_NONE);
+        }
+    }
+    else if (!isAck || sPromiscuous)
+    {
+        radioProcessFrame(aInstance);
+    }
+
+exit:
+    return;
+}
+
+static void radioComputeCrc(struct RadioMessage *aMessage, uint16_t aLength)
+{
+    uint16_t crc        = 0;
+    uint16_t crc_offset = aLength - sizeof(uint16_t);
+
+    for (uint16_t i = 0; i < crc_offset; i++)
+    {
+        crc = crc16_citt(crc, aMessage->mPsdu[i]);
+    }
+
+    aMessage->mPsdu[crc_offset]     = crc & 0xff;
+    aMessage->mPsdu[crc_offset + 1] = crc >> 8;
+}
+
+static otError radioProcessTransmitSecurity(otRadioFrame *aFrame)
+{
+    otError error = OT_ERROR_NONE;
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    struct otMacKey *key = NULL;
+    uint8_t          keyId;
+
+    otEXPECT(otMacFrameIsSecurityEnabled(aFrame) && otMacFrameIsKeyIdMode1(aFrame) &&
+             !aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
+
+    if (otMacFrameIsAck(aFrame))
+    {
+        keyId = otMacFrameGetKeyId(aFrame);
+
+        otEXPECT_ACTION(keyId != 0, error = OT_ERROR_FAILED);
+
+        if (keyId == sKeyId)
+        {
+            key = &sCurrKey;
+        }
+        else if (keyId == sKeyId - 1)
+        {
+            key = &sPrevKey;
+        }
+        else if (keyId == sKeyId + 1)
+        {
+            key = &sNextKey;
+        }
+        else
+        {
+            error = OT_ERROR_SECURITY;
+            otEXPECT(false);
+        }
+    }
+    else
+    {
+        key   = &sCurrKey;
+        keyId = sKeyId;
+    }
+
+    aFrame->mInfo.mTxInfo.mAesKey = key;
+
+    if (!aFrame->mInfo.mTxInfo.mIsARetx)
+    {
+        otMacFrameSetKeyId(aFrame, keyId);
+        otMacFrameSetFrameCounter(aFrame, sMacFrameCounter++);
+    }
+#else
+    otEXPECT(!aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+
+    otMacFrameProcessTransmitAesCcm(aFrame, &sExtAddress);
+
+exit:
+    return error;
+}
+
+void radioSendMessage(otInstance *aInstance)
+{
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    if (sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0)
+    {
+        uint8_t *timeIe = sTransmitFrame.mPsdu + sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset;
+        uint64_t time = (uint64_t)((int64_t)otPlatTimeGet() + sTransmitFrame.mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset);
+
+        *timeIe = sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeSyncSeq;
+
+        *(++timeIe) = (uint8_t)(time & 0xff);
+        for (uint8_t i = 1; i < sizeof(uint64_t); i++)
+        {
+            time        = time >> 8;
+            *(++timeIe) = (uint8_t)(time & 0xff);
+        }
+    }
+#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+
+    sTransmitMessage.mChannel = sTransmitFrame.mChannel;
+
+    otEXPECT(radioProcessTransmitSecurity(&sTransmitFrame) == OT_ERROR_NONE);
+    otPlatRadioTxStarted(aInstance, &sTransmitFrame);
+    radioComputeCrc(&sTransmitMessage, sTransmitFrame.mLength);
+    radioTransmit(&sTransmitMessage, &sTransmitFrame);
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+    sTxWait = otMacFrameIsAckRequested(&sTransmitFrame);
+
+    if (!sTxWait)
+    {
+        sState = OT_RADIO_STATE_RECEIVE;
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+        if (otPlatDiagModeGet())
+        {
+            otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_NONE);
+        }
+        else
+#endif
+        {
+            otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, OT_ERROR_NONE);
+        }
+    }
+#else
+    // Wait for echo radio in virtual time mode.
+    sTxWait = true;
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME
+exit:
+    return;
+}
+
+bool platformRadioIsTransmitPending(void)
+{
+    return sState == OT_RADIO_STATE_TRANSMIT && !sTxWait;
+}
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME
+void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLength)
+{
+    assert(sizeof(sReceiveMessage) >= aBufLength);
+
+    memcpy(&sReceiveMessage, aBuf, aBufLength);
+
+    sReceiveFrame.mLength = (uint8_t)(aBufLength - 1);
+
+    radioReceive(aInstance);
+}
+#else
+void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd)
+{
+    if (aReadFdSet != NULL && (sState != OT_RADIO_STATE_TRANSMIT || sTxWait))
+    {
+        FD_SET(sRxFd, aReadFdSet);
+
+        if (aMaxFd != NULL && *aMaxFd < sRxFd)
+        {
+            *aMaxFd = sRxFd;
+        }
+    }
+
+    if (aWriteFdSet != NULL && platformRadioIsTransmitPending())
+    {
+        FD_SET(sTxFd, aWriteFdSet);
+
+        if (aMaxFd != NULL && *aMaxFd < sTxFd)
+        {
+            *aMaxFd = sTxFd;
+        }
+    }
+}
+
+// no need to close in virtual time mode.
+void platformRadioDeinit(void)
+{
+    if (sRxFd != -1)
+    {
+        close(sRxFd);
+    }
+
+    if (sTxFd != -1)
+    {
+        close(sTxFd);
+    }
+}
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME
+
+void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
+{
+    OT_UNUSED_VARIABLE(aReadFdSet);
+    OT_UNUSED_VARIABLE(aWriteFdSet);
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+    if (FD_ISSET(sRxFd, aReadFdSet))
+    {
+        struct sockaddr_in sockaddr;
+        socklen_t          len = sizeof(sockaddr);
+        ssize_t            rval;
+
+        memset(&sockaddr, 0, sizeof(sockaddr));
+        rval =
+            recvfrom(sRxFd, (char *)&sReceiveMessage, sizeof(sReceiveMessage), 0, (struct sockaddr *)&sockaddr, &len);
+
+        if (rval > 0)
+        {
+            if (sockaddr.sin_port != htons(sPort))
+            {
+                sReceiveFrame.mLength = (uint16_t)(rval - 1);
+
+                radioReceive(aInstance);
+            }
+        }
+        else if (rval == 0)
+        {
+            // socket is closed, which should not happen
+            assert(false);
+        }
+        else if (errno != EINTR && errno != EAGAIN)
+        {
+            perror("recvfrom(sRxFd)");
+            exit(EXIT_FAILURE);
+        }
+    }
+#endif
+
+    if (platformRadioIsTransmitPending())
+    {
+        radioSendMessage(aInstance);
+    }
+}
+
+void radioTransmit(struct RadioMessage *aMessage, const struct otRadioFrame *aFrame)
+{
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+    ssize_t            rval;
+    struct sockaddr_in sockaddr;
+
+    memset(&sockaddr, 0, sizeof(sockaddr));
+    sockaddr.sin_family = AF_INET;
+    inet_pton(AF_INET, OT_RADIO_GROUP, &sockaddr.sin_addr);
+
+    sockaddr.sin_port = htons((uint16_t)(9000 + sPortOffset + WELLKNOWN_NODE_ID));
+    rval =
+        sendto(sTxFd, (const char *)aMessage, 1 + aFrame->mLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
+
+    if (rval < 0)
+    {
+        perror("sendto(sTxFd)");
+        exit(EXIT_FAILURE);
+    }
+#else  // OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+    struct Event event;
+
+    event.mDelay      = 1; // 1us for now
+    event.mEvent      = OT_SIM_EVENT_RADIO_RECEIVED;
+    event.mDataLength = 1 + aFrame->mLength; // include channel in first byte
+    memcpy(event.mData, aMessage, event.mDataLength);
+
+    otSimSendEvent(&event);
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+}
+
+void radioSendAck(void)
+{
+    if (
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+        // Determine if frame pending should be set
+        (otMacFrameIsData(&sReceiveFrame) || otMacFrameIsDataRequest(&sReceiveFrame))
+#else
+        otMacFrameIsDataRequest(&sReceiveFrame)
+#endif
+        && HasFramePending(&sReceiveFrame))
+    {
+        sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true;
+    }
+
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    // Use enh-ack for 802.15.4-2015 frames
+    if (otMacFrameIsVersion2015(&sReceiveFrame))
+    {
+        otEXPECT(otMacFrameGenerateEnhAck(&sReceiveFrame, sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending, NULL, 0,
+                                          &sAckFrame) == OT_ERROR_NONE);
+        otEXPECT(radioProcessTransmitSecurity(&sAckFrame) == OT_ERROR_NONE);
+    }
+    else
+#endif
+    {
+        otMacFrameGenerateImmAck(&sReceiveFrame, sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending, &sAckFrame);
+    }
+
+    sAckMessage.mChannel = sReceiveFrame.mChannel;
+
+    radioComputeCrc(&sAckMessage, sAckFrame.mLength);
+    radioTransmit(&sAckMessage, &sAckFrame);
+
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+exit:
+#endif
+    return;
+}
+
+void radioProcessFrame(otInstance *aInstance)
+{
+    otError error = OT_ERROR_NONE;
+
+    sReceiveFrame.mInfo.mRxInfo.mRssi = -20;
+    sReceiveFrame.mInfo.mRxInfo.mLqi  = OT_RADIO_LQI_NONE;
+
+    sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = false;
+    sReceiveFrame.mInfo.mRxInfo.mAckedWithSecEnhAck    = false;
+
+    otEXPECT(sPromiscuous == false);
+
+    otEXPECT_ACTION(otMacFrameDoesAddrMatch(&sReceiveFrame, sPanid, sShortAddress, &sExtAddress),
+                    error = OT_ERROR_ABORT);
+
+    // generate acknowledgment
+    if (otMacFrameIsAckRequested(&sReceiveFrame))
+    {
+        radioSendAck();
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+        if (otMacFrameIsSecurityEnabled(&sAckFrame))
+        {
+            sReceiveFrame.mInfo.mRxInfo.mAckedWithSecEnhAck = true;
+            sReceiveFrame.mInfo.mRxInfo.mAckFrameCounter    = otMacFrameGetFrameCounter(&sAckFrame);
+        }
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    }
+
+exit:
+
+    if (error != OT_ERROR_ABORT)
+    {
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+        if (otPlatDiagModeGet())
+        {
+            otPlatDiagRadioReceiveDone(aInstance, error == OT_ERROR_NONE ? &sReceiveFrame : NULL, error);
+        }
+        else
+#endif
+        {
+            otPlatRadioReceiveDone(aInstance, error == OT_ERROR_NONE ? &sReceiveFrame : NULL, error);
+        }
+    }
+}
+
+void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    sSrcMatchEnabled = aEnable;
+}
+
+otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aScanChannel);
+    OT_UNUSED_VARIABLE(aScanDuration);
+
+    assert(aInstance != NULL);
+    assert(aScanChannel >= SIM_RADIO_CHANNEL_MIN && aScanChannel <= SIM_RADIO_CHANNEL_MAX);
+    assert(aScanDuration > 0);
+
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    *aPower = sTxPower;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    sTxPower = aPower;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    *aThreshold = sCcaEdThresh;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    sCcaEdThresh = aThreshold;
+
+    return OT_ERROR_NONE;
+}
+
+int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    return SIM_RECEIVE_SENSITIVITY;
+}
+
+otRadioState otPlatRadioGetState(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return sState;
+}
+
+#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
+otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    sRadioCoexEnabled = aEnabled;
+    return OT_ERROR_NONE;
+}
+
+bool otPlatRadioIsCoexEnabled(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    assert(aInstance != NULL);
+
+    return sRadioCoexEnabled;
+}
+
+otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NONE;
+
+    assert(aInstance != NULL);
+    otEXPECT_ACTION(aCoexMetrics != NULL, error = OT_ERROR_INVALID_ARGS);
+
+    memset(aCoexMetrics, 0, sizeof(otRadioCoexMetrics));
+
+    aCoexMetrics->mStopped                            = false;
+    aCoexMetrics->mNumGrantGlitch                     = 1;
+    aCoexMetrics->mNumTxRequest                       = 2;
+    aCoexMetrics->mNumTxGrantImmediate                = 3;
+    aCoexMetrics->mNumTxGrantWait                     = 4;
+    aCoexMetrics->mNumTxGrantWaitActivated            = 5;
+    aCoexMetrics->mNumTxGrantWaitTimeout              = 6;
+    aCoexMetrics->mNumTxGrantDeactivatedDuringRequest = 7;
+    aCoexMetrics->mNumTxDelayedGrant                  = 8;
+    aCoexMetrics->mAvgTxRequestToGrantTime            = 9;
+    aCoexMetrics->mNumRxRequest                       = 10;
+    aCoexMetrics->mNumRxGrantImmediate                = 11;
+    aCoexMetrics->mNumRxGrantWait                     = 12;
+    aCoexMetrics->mNumRxGrantWaitActivated            = 13;
+    aCoexMetrics->mNumRxGrantWaitTimeout              = 14;
+    aCoexMetrics->mNumRxGrantDeactivatedDuringRequest = 15;
+    aCoexMetrics->mNumRxDelayedGrant                  = 16;
+    aCoexMetrics->mAvgRxRequestToGrantTime            = 17;
+    aCoexMetrics->mNumRxGrantNone                     = 18;
+
+exit:
+    return error;
+}
+#endif
+
+void otPlatRadioSetMacKey(otInstance *    aInstance,
+                          uint8_t         aKeyIdMode,
+                          uint8_t         aKeyId,
+                          const otMacKey *aPrevKey,
+                          const otMacKey *aCurrKey,
+                          const otMacKey *aNextKey)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aKeyIdMode);
+
+    otEXPECT(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL);
+
+    sKeyId = aKeyId;
+    memcpy(sPrevKey.m8, aPrevKey->m8, OT_MAC_KEY_SIZE);
+    memcpy(sCurrKey.m8, aCurrKey->m8, OT_MAC_KEY_SIZE);
+    memcpy(sNextKey.m8, aNextKey->m8, OT_MAC_KEY_SIZE);
+
+exit:
+    return;
+}
+
+void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sMacFrameCounter = aMacFrameCounter;
+}
diff --git a/examples/platforms/simulation/spi-stubs.c b/examples/platforms/simulation/spi-stubs.c
new file mode 100644
index 0000000..7c0dd62
--- /dev/null
+++ b/examples/platforms/simulation/spi-stubs.c
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openthread/config.h>
+#include <openthread/platform/spi-slave.h>
+#include <openthread/platform/uart.h>
+
+#if OPENTHREAD_CONFIG_NCP_SPI_ENABLE
+
+// Spi-slave stubs
+
+otError otPlatSpiSlaveEnable(otPlatSpiSlaveTransactionCompleteCallback aCompleteCallback,
+                             otPlatSpiSlaveTransactionProcessCallback  aProcessCallback,
+                             void *                                    aContext)
+{
+    OT_UNUSED_VARIABLE(aCompleteCallback);
+    OT_UNUSED_VARIABLE(aProcessCallback);
+    OT_UNUSED_VARIABLE(aContext);
+
+    fprintf(stderr, "\nNo SPI support for simulation platform.");
+    exit(0);
+
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+void otPlatSpiSlaveDisable(void)
+{
+}
+
+otError otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf,
+                                         uint16_t aOutputBufLen,
+                                         uint8_t *aInputBuf,
+                                         uint16_t aInputBufLen,
+                                         bool     aRequestTransactionFlag)
+{
+    OT_UNUSED_VARIABLE(aOutputBuf);
+    OT_UNUSED_VARIABLE(aOutputBufLen);
+    OT_UNUSED_VARIABLE(aInputBuf);
+    OT_UNUSED_VARIABLE(aInputBufLen);
+    OT_UNUSED_VARIABLE(aRequestTransactionFlag);
+
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+// Uart
+
+void otPlatUartSendDone(void)
+{
+}
+
+void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    OT_UNUSED_VARIABLE(aBuf);
+    OT_UNUSED_VARIABLE(aBufLength);
+}
+
+#endif // OPENTHREAD_CONFIG_NCP_SPI_ENABLE
diff --git a/examples/platforms/simulation/system.c b/examples/platforms/simulation/system.c
new file mode 100644
index 0000000..993b3f9
--- /dev/null
+++ b/examples/platforms/simulation/system.c
@@ -0,0 +1,176 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *   This file includes the platform-specific initializers.
+ */
+
+#include "platform-simulation.h"
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
+
+#include <assert.h>
+#include <errno.h>
+#include <libgen.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+
+#include <openthread/tasklet.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/radio.h>
+
+uint32_t gNodeId = 1;
+
+extern bool        gPlatformPseudoResetWasRequested;
+extern otRadioCaps gRadioCaps;
+
+static volatile bool gTerminate = false;
+
+static void handleSignal(int aSignal)
+{
+    OT_UNUSED_VARIABLE(aSignal);
+
+    gTerminate = true;
+}
+
+void otSysInit(int aArgCount, char *aArgVector[])
+{
+    char *   endptr;
+    uint32_t speedUpFactor = 1;
+    int      argIndex      = 0;
+
+    if (gPlatformPseudoResetWasRequested)
+    {
+        gPlatformPseudoResetWasRequested = false;
+        return;
+    }
+
+    if (aArgCount < 2)
+    {
+        fprintf(stderr, "Syntax:\n    %s [--sleep-to-tx] NodeId [TimeSpeedUpFactor]\n", aArgVector[0]);
+        exit(EXIT_FAILURE);
+    }
+
+    openlog(basename(aArgVector[argIndex++]), LOG_PID, LOG_USER);
+    setlogmask(setlogmask(0) & LOG_UPTO(LOG_NOTICE));
+
+    signal(SIGTERM, &handleSignal);
+    signal(SIGHUP, &handleSignal);
+
+    if (!strcmp(aArgVector[argIndex], "--sleep-to-tx"))
+    {
+        gRadioCaps |= OT_RADIO_CAPS_SLEEP_TO_TX;
+        ++argIndex;
+    }
+
+    gNodeId = (uint32_t)strtol(aArgVector[argIndex], &endptr, 0);
+
+    if (*endptr != '\0' || gNodeId < 1 || gNodeId >= WELLKNOWN_NODE_ID)
+    {
+        fprintf(stderr, "Invalid NodeId: %s\n", aArgVector[argIndex]);
+        exit(EXIT_FAILURE);
+    }
+
+    ++argIndex;
+
+    if (aArgCount > argIndex)
+    {
+        speedUpFactor = (uint32_t)strtol(aArgVector[argIndex], &endptr, 0);
+
+        if (*endptr != '\0' || speedUpFactor == 0)
+        {
+            fprintf(stderr, "Invalid value for TimerSpeedUpFactor: %s\n", aArgVector[argIndex]);
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    platformAlarmInit(speedUpFactor);
+    platformRadioInit();
+    platformRandomInit();
+}
+
+bool otSysPseudoResetWasRequested(void)
+{
+    return gPlatformPseudoResetWasRequested;
+}
+
+void otSysDeinit(void)
+{
+    platformRadioDeinit();
+}
+
+void otSysProcessDrivers(otInstance *aInstance)
+{
+    fd_set         read_fds;
+    fd_set         write_fds;
+    fd_set         error_fds;
+    int            max_fd = -1;
+    struct timeval timeout;
+    int            rval;
+
+    FD_ZERO(&read_fds);
+    FD_ZERO(&write_fds);
+    FD_ZERO(&error_fds);
+
+    platformUartUpdateFdSet(&read_fds, &write_fds, &error_fds, &max_fd);
+    platformRadioUpdateFdSet(&read_fds, &write_fds, &max_fd);
+    platformAlarmUpdateTimeout(&timeout);
+
+    if (otTaskletsArePending(aInstance))
+    {
+        timeout.tv_sec  = 0;
+        timeout.tv_usec = 0;
+    }
+
+    rval = select(max_fd + 1, &read_fds, &write_fds, &error_fds, &timeout);
+
+    if (rval >= 0)
+    {
+        platformUartProcess();
+        platformRadioProcess(aInstance, &read_fds, &write_fds);
+    }
+    else if (errno != EINTR)
+    {
+        perror("select");
+        exit(EXIT_FAILURE);
+    }
+
+    platformAlarmProcess(aInstance);
+
+    if (gTerminate)
+    {
+        exit(0);
+    }
+}
+
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
diff --git a/examples/platforms/simulation/uart.c b/examples/platforms/simulation/uart.c
new file mode 100644
index 0000000..777bbed
--- /dev/null
+++ b/examples/platforms/simulation/uart.c
@@ -0,0 +1,352 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <openthread/platform/debug_uart.h>
+#include <openthread/platform/uart.h>
+
+#include "utils/code_utils.h"
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART == 0
+
+static uint8_t        s_receive_buffer[128];
+static const uint8_t *s_write_buffer;
+static uint16_t       s_write_length;
+static int            s_in_fd;
+static int            s_out_fd;
+
+static struct termios original_stdin_termios;
+static struct termios original_stdout_termios;
+
+static void restore_stdin_termios(void)
+{
+    tcsetattr(s_in_fd, TCSAFLUSH, &original_stdin_termios);
+}
+
+static void restore_stdout_termios(void)
+{
+    tcsetattr(s_out_fd, TCSAFLUSH, &original_stdout_termios);
+}
+
+void platformUartRestore(void)
+{
+    restore_stdin_termios();
+    restore_stdout_termios();
+    dup2(s_out_fd, STDOUT_FILENO);
+}
+
+otError otPlatUartEnable(void)
+{
+    otError        error = OT_ERROR_NONE;
+    struct termios termios;
+
+    s_in_fd  = dup(STDIN_FILENO);
+    s_out_fd = dup(STDOUT_FILENO);
+    dup2(STDERR_FILENO, STDOUT_FILENO);
+
+    // We need this signal to make sure that this
+    // process terminates properly.
+    signal(SIGPIPE, SIG_DFL);
+
+    if (isatty(s_in_fd))
+    {
+        tcgetattr(s_in_fd, &original_stdin_termios);
+        atexit(&restore_stdin_termios);
+    }
+
+    if (isatty(s_out_fd))
+    {
+        tcgetattr(s_out_fd, &original_stdout_termios);
+        atexit(&restore_stdout_termios);
+    }
+
+    if (isatty(s_in_fd))
+    {
+        // get current configuration
+        otEXPECT_ACTION(tcgetattr(s_in_fd, &termios) == 0, perror("tcgetattr"); error = OT_ERROR_GENERIC);
+
+        // Set up the termios settings for raw mode. This turns
+        // off input/output processing, line processing, and character processing.
+        cfmakeraw(&termios);
+
+        // Set up our cflags for local use. Turn on hangup-on-close.
+        termios.c_cflag |= HUPCL | CREAD | CLOCAL;
+
+        // "Minimum number of characters for noncanonical read"
+        termios.c_cc[VMIN] = 1;
+
+        // "Timeout in deciseconds for noncanonical read"
+        termios.c_cc[VTIME] = 0;
+
+        // configure baud rate
+        otEXPECT_ACTION(cfsetispeed(&termios, OPENTHREAD_SIMULATION_UART_BAUDRATE) == 0, perror("cfsetispeed");
+                        error = OT_ERROR_GENERIC);
+
+        // set configuration
+        otEXPECT_ACTION(tcsetattr(s_in_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = OT_ERROR_GENERIC);
+    }
+
+    if (isatty(s_out_fd))
+    {
+        // get current configuration
+        otEXPECT_ACTION(tcgetattr(s_out_fd, &termios) == 0, perror("tcgetattr"); error = OT_ERROR_GENERIC);
+
+        // Set up the termios settings for raw mode. This turns
+        // off input/output processing, line processing, and character processing.
+        cfmakeraw(&termios);
+
+        // Absolutely obliterate all output processing.
+        termios.c_oflag = 0;
+
+        // Set up our cflags for local use. Turn on hangup-on-close.
+        termios.c_cflag |= HUPCL | CREAD | CLOCAL;
+
+        // configure baud rate
+        otEXPECT_ACTION(cfsetospeed(&termios, OPENTHREAD_SIMULATION_UART_BAUDRATE) == 0, perror("cfsetospeed");
+                        error = OT_ERROR_GENERIC);
+
+        // set configuration
+        otEXPECT_ACTION(tcsetattr(s_out_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = OT_ERROR_GENERIC);
+    }
+
+    return error;
+
+exit:
+    close(s_in_fd);
+    close(s_out_fd);
+    return error;
+}
+
+otError otPlatUartDisable(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    close(s_in_fd);
+    close(s_out_fd);
+
+    return error;
+}
+
+otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    otEXPECT_ACTION(s_write_length == 0, error = OT_ERROR_BUSY);
+
+    s_write_buffer = aBuf;
+    s_write_length = aBufLength;
+
+exit:
+    return error;
+}
+
+void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
+{
+    if (aReadFdSet != NULL)
+    {
+        FD_SET(s_in_fd, aReadFdSet);
+
+        if (aErrorFdSet != NULL)
+        {
+            FD_SET(s_in_fd, aErrorFdSet);
+        }
+
+        if (aMaxFd != NULL && *aMaxFd < s_in_fd)
+        {
+            *aMaxFd = s_in_fd;
+        }
+    }
+
+    if ((aWriteFdSet != NULL) && (s_write_length > 0))
+    {
+        FD_SET(s_out_fd, aWriteFdSet);
+
+        if (aErrorFdSet != NULL)
+        {
+            FD_SET(s_out_fd, aErrorFdSet);
+        }
+
+        if (aMaxFd != NULL && *aMaxFd < s_out_fd)
+        {
+            *aMaxFd = s_out_fd;
+        }
+    }
+}
+
+otError otPlatUartFlush(void)
+{
+    otError error = OT_ERROR_NONE;
+    ssize_t count;
+
+    otEXPECT_ACTION(s_write_buffer != NULL && s_write_length > 0, error = OT_ERROR_INVALID_STATE);
+
+    while ((count = write(s_out_fd, s_write_buffer, s_write_length)) > 0 && (s_write_length -= count) > 0)
+    {
+        s_write_buffer += count;
+    }
+
+    if (count != -1)
+    {
+        assert(s_write_length == 0);
+        s_write_buffer = NULL;
+    }
+    else
+    {
+        perror("write(UART)");
+        exit(EXIT_FAILURE);
+    }
+
+exit:
+    return error;
+}
+
+void platformUartProcess(void)
+{
+    ssize_t       rval;
+    const int     error_flags = POLLERR | POLLNVAL | POLLHUP;
+    struct pollfd pollfd[]    = {
+        {s_in_fd, POLLIN | error_flags, 0},
+        {s_out_fd, POLLOUT | error_flags, 0},
+    };
+
+    errno = 0;
+
+    rval = poll(pollfd, sizeof(pollfd) / sizeof(*pollfd), 0);
+
+    if (rval < 0)
+    {
+        perror("poll");
+        exit(EXIT_FAILURE);
+    }
+
+    if (rval > 0)
+    {
+        if ((pollfd[0].revents & error_flags) != 0)
+        {
+            perror("s_in_fd");
+            exit(EXIT_FAILURE);
+        }
+
+        if ((pollfd[1].revents & error_flags) != 0)
+        {
+            perror("s_out_fd");
+            exit(EXIT_FAILURE);
+        }
+
+        if (pollfd[0].revents & POLLIN)
+        {
+            rval = read(s_in_fd, s_receive_buffer, sizeof(s_receive_buffer));
+
+            if (rval <= 0)
+            {
+                perror("read");
+                exit(EXIT_FAILURE);
+            }
+
+            otPlatUartReceived(s_receive_buffer, (uint16_t)rval);
+        }
+
+        if ((s_write_length > 0) && (pollfd[1].revents & POLLOUT))
+        {
+            rval = write(s_out_fd, s_write_buffer, s_write_length);
+
+            if (rval >= 0)
+            {
+                s_write_buffer += (uint16_t)rval;
+                s_write_length -= (uint16_t)rval;
+
+                if (s_write_length == 0)
+                {
+                    otPlatUartSendDone();
+                }
+            }
+            else if (errno != EINTR)
+            {
+                perror("write");
+                exit(EXIT_FAILURE);
+            }
+        }
+    }
+}
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART == 0
+
+#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART && (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART)
+
+static FILE *posix_logfile;
+
+otError otPlatDebugUart_logfile(const char *filename)
+{
+    posix_logfile = fopen(filename, "wt");
+
+    return posix_logfile ? OT_ERROR_NONE : OT_ERROR_FAILED;
+}
+
+void otPlatDebugUart_putchar_raw(int c)
+{
+    FILE *fp;
+
+    /* note: log file will have a mix of cr/lf and
+     * in some/many cases duplicate cr because in
+     * some cases the log function {ie: Mbed} already
+     * includes the CR or LF... but other log functions
+     * do not include cr/lf and expect it appended
+     */
+    fp = posix_logfile;
+
+    if (fp != NULL)
+    {
+        /* log is lost ... until a file is setup */
+        fputc(c, fp);
+        /* we could "fflush" but will not */
+    }
+}
+
+int otPlatDebugUart_kbhit(void)
+{
+    /* not supported */
+    return 0;
+}
+
+int otPlatDebugUart_getc(void)
+{
+    /* not supported */
+    return -1;
+}
+
+#endif
diff --git a/examples/platforms/simulation/virtual_time/alarm-sim.c b/examples/platforms/simulation/virtual_time/alarm-sim.c
new file mode 100644
index 0000000..479036f
--- /dev/null
+++ b/examples/platforms/simulation/virtual_time/alarm-sim.c
@@ -0,0 +1,196 @@
+/*
+ *  Copyright (c) 2018, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openthread/platform/alarm-micro.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+
+#define US_PER_MS 1000
+
+extern uint64_t sNow; // microseconds
+
+static bool     sIsMsRunning = false;
+static uint32_t sMsAlarm     = 0;
+
+static bool     sIsUsRunning = false;
+static uint32_t sUsAlarm     = 0;
+
+void platformAlarmInit(uint32_t aSpeedUpFactor)
+{
+    OT_UNUSED_VARIABLE(aSpeedUpFactor);
+
+    sNow = 0;
+}
+
+uint64_t platformAlarmGetNow(void)
+{
+    return sNow;
+}
+
+void platformAlarmAdvanceNow(uint64_t aDelta)
+{
+    sNow += aDelta;
+}
+
+uint32_t otPlatAlarmMilliGetNow(void)
+{
+    return (uint32_t)(sNow / US_PER_MS);
+}
+
+void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sMsAlarm     = aT0 + aDt;
+    sIsMsRunning = true;
+}
+
+void otPlatAlarmMilliStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sIsMsRunning = false;
+}
+
+uint32_t otPlatAlarmMicroGetNow(void)
+{
+    return (uint32_t)sNow;
+}
+
+void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sUsAlarm     = aT0 + aDt;
+    sIsUsRunning = true;
+}
+
+void otPlatAlarmMicroStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sIsUsRunning = false;
+}
+
+int32_t platformAlarmGetNext(void)
+{
+    int32_t remaining = INT32_MAX;
+
+    if (sIsMsRunning)
+    {
+        int32_t milli = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
+
+        remaining = milli * US_PER_MS;
+
+        if (remaining < 0 && milli > 0)
+        {
+            remaining = INT32_MAX;
+        }
+    }
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+
+    if (sIsUsRunning)
+    {
+        int32_t micro = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
+
+        if (remaining > micro)
+        {
+            remaining = micro;
+        }
+    }
+
+#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+
+    return remaining;
+}
+
+void platformAlarmProcess(otInstance *aInstance)
+{
+    int32_t remaining;
+
+    if (sIsMsRunning)
+    {
+        remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
+
+        if (remaining <= 0)
+        {
+            sIsMsRunning = false;
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+            if (otPlatDiagModeGet())
+            {
+                otPlatDiagAlarmFired(aInstance);
+            }
+            else
+#endif
+            {
+                otPlatAlarmMilliFired(aInstance);
+            }
+        }
+    }
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+
+    if (sIsUsRunning)
+    {
+        remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
+
+        if (remaining <= 0)
+        {
+            sIsUsRunning = false;
+
+            otPlatAlarmMicroFired(aInstance);
+        }
+    }
+
+#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+}
+
+uint64_t otPlatTimeGet(void)
+{
+    return platformAlarmGetNow();
+}
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+uint16_t otPlatTimeGetXtalAccuracy(void)
+{
+    return 0;
+}
+#endif
+
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME
diff --git a/examples/platforms/simulation/virtual_time/otns.c b/examples/platforms/simulation/virtual_time/otns.c
new file mode 100644
index 0000000..9b02048
--- /dev/null
+++ b/examples/platforms/simulation/virtual_time/otns.c
@@ -0,0 +1,50 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform-simulation.h"
+
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+
+#include <openthread/platform/alarm-micro.h>
+
+void otPlatOtnsStatus(const char *aStatus)
+{
+    struct Event event;
+    uint16_t     statusLength = (uint16_t)strlen(aStatus);
+
+    assert(statusLength < sizeof(event.mData));
+
+    memcpy(event.mData, aStatus, statusLength);
+    event.mDataLength = statusLength;
+    event.mDelay      = 0;
+    event.mEvent      = OT_SIM_EVENT_OTNS_STATUS_PUSH;
+
+    otSimSendEvent(&event);
+}
+
+#endif // OPENTHREAD_CONFIG_OTNS_ENABLE
diff --git a/examples/platforms/simulation/virtual_time/platform-sim.c b/examples/platforms/simulation/virtual_time/platform-sim.c
new file mode 100644
index 0000000..b676b5a
--- /dev/null
+++ b/examples/platforms/simulation/virtual_time/platform-sim.c
@@ -0,0 +1,315 @@
+/*
+ *  Copyright (c) 2018, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *   This file includes the platform-specific initializers.
+ */
+
+#include "platform-simulation.h"
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <libgen.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+
+#include <openthread/tasklet.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/uart.h>
+
+uint32_t gNodeId = 1;
+
+extern bool          gPlatformPseudoResetWasRequested;
+static volatile bool gTerminate = false;
+
+int    gArgumentsCount = 0;
+char **gArguments      = NULL;
+
+uint64_t sNow = 0; // microseconds
+int      sSockFd;
+uint16_t sPortOffset;
+
+static void handleSignal(int aSignal)
+{
+    OT_UNUSED_VARIABLE(aSignal);
+
+    gTerminate = true;
+}
+
+void otSimSendEvent(const struct Event *aEvent)
+{
+    ssize_t            rval;
+    struct sockaddr_in sockaddr;
+
+    memset(&sockaddr, 0, sizeof(sockaddr));
+    sockaddr.sin_family = AF_INET;
+    inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr);
+    sockaddr.sin_port = htons(9000 + sPortOffset);
+
+    rval = sendto(sSockFd, aEvent, offsetof(struct Event, mData) + aEvent->mDataLength, 0, (struct sockaddr *)&sockaddr,
+                  sizeof(sockaddr));
+
+    if (rval < 0)
+    {
+        perror("sendto");
+        exit(EXIT_FAILURE);
+    }
+}
+
+static void receiveEvent(otInstance *aInstance)
+{
+    struct Event event;
+    ssize_t      rval = recvfrom(sSockFd, (char *)&event, sizeof(event), 0, NULL, NULL);
+
+    if (rval < 0 || (uint16_t)rval < offsetof(struct Event, mData))
+    {
+        perror("recvfrom");
+        exit(EXIT_FAILURE);
+    }
+
+    platformAlarmAdvanceNow(event.mDelay);
+
+    switch (event.mEvent)
+    {
+    case OT_SIM_EVENT_ALARM_FIRED:
+        break;
+
+    case OT_SIM_EVENT_RADIO_RECEIVED:
+        platformRadioReceive(aInstance, event.mData, event.mDataLength);
+        break;
+
+    case OT_SIM_EVENT_UART_WRITE:
+        otPlatUartReceived(event.mData, event.mDataLength);
+        break;
+
+    default:
+        assert(false);
+    }
+}
+
+static void platformSendSleepEvent(void)
+{
+    struct Event event;
+
+    assert(platformAlarmGetNext() > 0);
+
+    event.mDelay      = (uint64_t)platformAlarmGetNext();
+    event.mEvent      = OT_SIM_EVENT_ALARM_FIRED;
+    event.mDataLength = 0;
+
+    otSimSendEvent(&event);
+}
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART
+void platformUartRestore(void)
+{
+}
+
+otError otPlatUartEnable(void)
+{
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartDisable(void)
+{
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartSend(const uint8_t *aData, uint16_t aLength)
+{
+    otError      error = OT_ERROR_NONE;
+    struct Event event;
+
+    event.mDelay      = 0;
+    event.mEvent      = OT_SIM_EVENT_UART_WRITE;
+    event.mDataLength = aLength;
+
+    memcpy(event.mData, aData, aLength);
+
+    otSimSendEvent(&event);
+
+    otPlatUartSendDone();
+
+    return error;
+}
+
+otError otPlatUartFlush(void)
+{
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART
+
+static void socket_init(void)
+{
+    struct sockaddr_in sockaddr;
+    char *             offset;
+    memset(&sockaddr, 0, sizeof(sockaddr));
+    sockaddr.sin_family = AF_INET;
+
+    offset = getenv("PORT_OFFSET");
+
+    if (offset)
+    {
+        char *endptr;
+
+        sPortOffset = (uint16_t)strtol(offset, &endptr, 0);
+
+        if (*endptr != '\0')
+        {
+            fprintf(stderr, "Invalid PORT_OFFSET: %s\n", offset);
+            exit(EXIT_FAILURE);
+        }
+
+        sPortOffset *= WELLKNOWN_NODE_ID;
+    }
+
+    sockaddr.sin_port        = htons((uint16_t)(9000 + sPortOffset + gNodeId));
+    sockaddr.sin_addr.s_addr = INADDR_ANY;
+
+    sSockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+    if (sSockFd == -1)
+    {
+        perror("socket");
+        exit(EXIT_FAILURE);
+    }
+
+    if (bind(sSockFd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == -1)
+    {
+        perror("bind");
+        exit(EXIT_FAILURE);
+    }
+}
+
+void otSysInit(int argc, char *argv[])
+{
+    char *endptr;
+
+    if (gPlatformPseudoResetWasRequested)
+    {
+        gPlatformPseudoResetWasRequested = false;
+        return;
+    }
+
+    if (argc != 2)
+    {
+        exit(EXIT_FAILURE);
+    }
+
+    openlog(basename(argv[0]), LOG_PID, LOG_USER);
+    setlogmask(setlogmask(0) & LOG_UPTO(LOG_NOTICE));
+
+    gArgumentsCount = argc;
+    gArguments      = argv;
+
+    gNodeId = (uint32_t)strtol(argv[1], &endptr, 0);
+
+    if (*endptr != '\0' || gNodeId < 1 || gNodeId >= WELLKNOWN_NODE_ID)
+    {
+        fprintf(stderr, "Invalid NodeId: %s\n", argv[1]);
+        exit(EXIT_FAILURE);
+    }
+
+    socket_init();
+
+    platformAlarmInit(1);
+    platformRadioInit();
+    platformRandomInit();
+
+    signal(SIGTERM, &handleSignal);
+    signal(SIGHUP, &handleSignal);
+}
+
+bool otSysPseudoResetWasRequested(void)
+{
+    return gPlatformPseudoResetWasRequested;
+}
+
+void otSysDeinit(void)
+{
+    close(sSockFd);
+}
+
+void otSysProcessDrivers(otInstance *aInstance)
+{
+    fd_set read_fds;
+    fd_set write_fds;
+    fd_set error_fds;
+    int    max_fd = -1;
+    int    rval;
+
+    if (gTerminate)
+    {
+        exit(0);
+    }
+
+    FD_ZERO(&read_fds);
+    FD_ZERO(&write_fds);
+    FD_ZERO(&error_fds);
+
+    FD_SET(sSockFd, &read_fds);
+    max_fd = sSockFd;
+
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART == 0
+    platformUartUpdateFdSet(&read_fds, &write_fds, &error_fds, &max_fd);
+#endif
+
+    if (!otTaskletsArePending(aInstance) && platformAlarmGetNext() > 0 && !platformRadioIsTransmitPending())
+    {
+        platformSendSleepEvent();
+
+        rval = select(max_fd + 1, &read_fds, &write_fds, &error_fds, NULL);
+
+        if ((rval < 0) && (errno != EINTR))
+        {
+            perror("select");
+            exit(EXIT_FAILURE);
+        }
+
+        if (rval > 0 && FD_ISSET(sSockFd, &read_fds))
+        {
+            receiveEvent(aInstance);
+        }
+    }
+
+    platformAlarmProcess(aInstance);
+    platformRadioProcess(aInstance, &read_fds, &write_fds);
+#if OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART == 0
+    platformUartProcess();
+#endif
+}
+
+#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME
diff --git a/examples/platforms/utils/CMakeLists.txt b/examples/platforms/utils/CMakeLists.txt
index 0526e37..4712015 100644
--- a/examples/platforms/utils/CMakeLists.txt
+++ b/examples/platforms/utils/CMakeLists.txt
@@ -30,24 +30,29 @@
     debug_uart.c
     logging_rtt.c
     mac_frame.cpp
+    otns_utils.cpp
     settings_ram.c
-    settings_flash.c
     soft_source_match_table.c
 )
 
+set_target_properties(
+    openthread-platform-utils
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
 target_compile_definitions(openthread-platform-utils PRIVATE
-    ${OT_PRIVATE_DEFINES}
+    $<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
 )
 
 target_include_directories(openthread-platform-utils PRIVATE
     ${OT_PUBLIC_INCLUDES}
-    ${OT_PRIVATE_INCLUDES}
+    $<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>
     ${PROJECT_SOURCE_DIR}/examples/platforms
     ${PROJECT_SOURCE_DIR}/examples/platforms/utils
-    ${PROJECT_SOURCE_DIR}/src/core
     ${PROJECT_SOURCE_DIR}/third_party/jlink/SEGGER_RTT_V640/RTT
 )
 
 # Provide a static library implementation of platform-utils for non-cmake platforms
 add_library(openthread-platform-utils-static $<TARGET_OBJECTS:openthread-platform-utils>)
-target_link_libraries(openthread-platform-utils-static PUBLIC openthread-platform-utils)
diff --git a/examples/platforms/utils/Makefile.am b/examples/platforms/utils/Makefile.am
index aa29b83..8096701 100644
--- a/examples/platforms/utils/Makefile.am
+++ b/examples/platforms/utils/Makefile.am
@@ -40,14 +40,13 @@
 libopenthread_platform_utils_a_SOURCES  = \
     code_utils.h                          \
     debug_uart.c                          \
-    flash.h                               \
     logging_rtt.c                         \
     logging_rtt.h                         \
     mac_frame.cpp                         \
     mac_frame.h                           \
+    otns_utils.cpp                        \
     settings.h                            \
     settings_ram.c                        \
-    settings_flash.c                      \
     soft_source_match_table.c             \
     soft_source_match_table.h             \
     $(NULL)
diff --git a/examples/platforms/utils/encoding.h b/examples/platforms/utils/encoding.h
new file mode 100644
index 0000000..55e3f43
--- /dev/null
+++ b/examples/platforms/utils/encoding.h
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes macros for validating runtime conditions.
+ */
+
+#ifndef PLATFORM_UTILS_ENCODING_H
+#define PLATFORM_UTILS_ENCODING_H
+
+#include <stdint.h>
+
+/**
+ * Converts a 64-bit unsigned integer stored as a little-endian byte
+ * array to uint64_t.
+ *
+ * Allows for the array to be byte-aligned, so that loading the
+ * uint64_t value via this function avoids a processor exception due
+ * to unaligned access.
+ *
+ * @param[in]  aSource  The byte array.
+ *
+ * @returns The 64-bit value as a uint64_t.
+ *
+ */
+static inline uint64_t otEncodingReadUint64Le(const uint8_t *aSource)
+{
+    uint64_t value = 0;
+
+    value |= (uint64_t)aSource[0];
+    value |= ((uint64_t)aSource[1]) << 8;
+    value |= ((uint64_t)aSource[2]) << 16;
+    value |= ((uint64_t)aSource[3]) << 24;
+    value |= ((uint64_t)aSource[4]) << 32;
+    value |= ((uint64_t)aSource[5]) << 40;
+    value |= ((uint64_t)aSource[6]) << 48;
+    value |= ((uint64_t)aSource[7]) << 56;
+
+    return value;
+}
+
+#endif // PLATFORM_UTILS_ENCODING_H
diff --git a/examples/platforms/utils/flash.h b/examples/platforms/utils/flash.h
deleted file mode 100644
index 659e787..0000000
--- a/examples/platforms/utils/flash.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- * @brief
- *   This file defines the flash interface used by settings.cpp.
- */
-
-#ifndef UTILS_FLASH_H
-#define UTILS_FLASH_H
-
-#include <stdint.h>
-
-#include <openthread/error.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Perform any initialization for flash driver.
- *
- * @retval ::OT_ERROR_NONE    Initialize flash driver success.
- * @retval ::OT_ERROR_FAILED  Initialize flash driver fail.
- */
-otError utilsFlashInit(void);
-
-/**
- * Get the size of flash that can be read/write by the caller.
- * The usable flash size is always the multiple of flash page size.
- *
- * @returns The size of the flash.
- */
-uint32_t utilsFlashGetSize(void);
-
-/**
- * Erase one flash page that include the input address.
- * This is a non-blocking function. It can work with utilsFlashStatusWait to check when erase is done.
- *
- * The flash address starts from 0, and this function maps the input address to the physical address of flash for
- * erasing. 0 is always mapped to the beginning of one flash page. The input address should never be mapped to the
- * firmware space or any other protected flash space.
- *
- * @param[in]  aAddress  The start address of the flash to erase.
- *
- * @retval OT_ERROR_NONE           Erase flash operation is started.
- * @retval OT_ERROR_FAILED         Erase flash operation is not started.
- * @retval OT_ERROR_INVALID_ARGS    aAddress is out of range of flash or not aligned.
- */
-otError utilsFlashErasePage(uint32_t aAddress);
-
-/**
- * Check whether flash is ready or busy.
- *
- * @param[in]  aTimeout  The interval in milliseconds waiting for the flash operation to be done and become ready again.
- *                       zero indicates that it is a polling function, and returns current status of flash immediately.
- *                       non-zero indicates that it is blocking there until the operation is done and become ready, or
- * timeout expires.
- *
- * @retval OT_ERROR_NONE           Flash is ready for any operation.
- * @retval OT_ERROR_BUSY           Flash is busy.
- */
-otError utilsFlashStatusWait(uint32_t aTimeout);
-
-/**
- * Write flash. The write operation only clears bits, but never set bits.
- *
- * The flash address starts from 0, and this function maps the input address to the physical address of flash for
- * writing. 0 is always mapped to the beginning of one flash page. The input address should never be mapped to the
- * firmware space or any other protected flash space.
- *
- * @param[in]  aAddress  The start address of the flash to write.
- * @param[in]  aData     The pointer of the data to write.
- * @param[in]  aSize     The size of the data to write.
- *
- * @returns The actual size of octets write to flash.
- *          It is expected the same as aSize, and may be less than aSize.
- *          0 indicates that something wrong happens when writing.
- */
-uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize);
-
-/**
- * Read flash.
- *
- * The flash address starts from 0, and this function maps the input address to the physical address of flash for
- * reading. 0 is always mapped to the beginning of one flash page. The input address should never be mapped to the
- * firmware space or any other protected flash space.
- *
- * @param[in]   aAddress  The start address of the flash to read.
- * @param[Out]  aData     The pointer of buffer for reading.
- * @param[in]   aSize     The size of the data to read.
- *
- * @returns The actual size of octets read to buffer.
- *          It is expected the same as aSize, and may be less than aSize.
- *          0 indicates that something wrong happens when reading.
- */
-uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // UTILS_FLASH_H
diff --git a/examples/platforms/utils/logging_rtt.c b/examples/platforms/utils/logging_rtt.c
index 242ad25..3372cab 100644
--- a/examples/platforms/utils/logging_rtt.c
+++ b/examples/platforms/utils/logging_rtt.c
@@ -42,8 +42,7 @@
 #include "SEGGER_RTT.h"
 #include "logging_rtt.h"
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
-    (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
 #if (LOG_RTT_COLOR_ENABLE == 1)
 #define RTT_COLOR_CODE_DEFAULT "\x1B[0m"
 #define RTT_COLOR_CODE_RED "\x1B[1;31m"
@@ -176,5 +175,4 @@
 exit:
     return;
 }
-#endif // (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) ||
-       // (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#endif // (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
diff --git a/examples/platforms/utils/mac_frame.cpp b/examples/platforms/utils/mac_frame.cpp
index 276e38b..7a32728 100644
--- a/examples/platforms/utils/mac_frame.cpp
+++ b/examples/platforms/utils/mac_frame.cpp
@@ -28,6 +28,7 @@
 
 #include "mac_frame.h"
 
+#include <assert.h>
 #include "mac/mac_frame.hpp"
 
 using namespace ot;
@@ -72,6 +73,11 @@
     return static_cast<const Mac::Frame *>(aFrame)->GetType() == Mac::Frame::kFcfFrameAck;
 }
 
+bool otMacFrameIsData(const otRadioFrame *aFrame)
+{
+    return static_cast<const Mac::Frame *>(aFrame)->GetType() == Mac::Frame::kFcfFrameData;
+}
+
 bool otMacFrameIsDataRequest(const otRadioFrame *aFrame)
 {
     return static_cast<const Mac::Frame *>(aFrame)->IsDataRequestCommand();
@@ -120,3 +126,79 @@
 {
     static_cast<Mac::TxFrame *>(aFrame)->ProcessTransmitAesCcm(*static_cast<const Mac::ExtAddress *>(aExtAddress));
 }
+
+bool otMacFrameIsVersion2015(const otRadioFrame *aFrame)
+{
+    return static_cast<const Mac::Frame *>(aFrame)->IsVersion2015();
+}
+
+void otMacFrameGenerateImmAck(const otRadioFrame *aFrame, bool aIsFramePending, otRadioFrame *aAckFrame)
+{
+    assert(aFrame != nullptr && aAckFrame != nullptr);
+
+    static_cast<Mac::TxFrame *>(aAckFrame)->GenerateImmAck(*static_cast<const Mac::RxFrame *>(aFrame), aIsFramePending);
+}
+
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+otError otMacFrameGenerateEnhAck(const otRadioFrame *aFrame,
+                                 bool                aIsFramePending,
+                                 const uint8_t *     aIeData,
+                                 uint8_t             aIeLength,
+                                 otRadioFrame *      aAckFrame)
+{
+    assert(aFrame != nullptr && aAckFrame != nullptr);
+
+    return static_cast<Mac::TxFrame *>(aAckFrame)->GenerateEnhAck(*static_cast<const Mac::RxFrame *>(aFrame),
+                                                                  aIsFramePending, aIeData, aIeLength);
+}
+#endif
+
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCslPhase)
+{
+    static_cast<Mac::Frame *>(aFrame)->SetCslIe(aCslPeriod, aCslPhase);
+}
+#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+
+bool otMacFrameIsSecurityEnabled(otRadioFrame *aFrame)
+{
+    return static_cast<const Mac::Frame *>(aFrame)->GetSecurityEnabled();
+}
+
+bool otMacFrameIsKeyIdMode1(otRadioFrame *aFrame)
+{
+    uint8_t keyIdMode;
+    otError error;
+
+    error = static_cast<const Mac::Frame *>(aFrame)->GetKeyIdMode(keyIdMode);
+
+    return (error == OT_ERROR_NONE) ? (keyIdMode == Mac::Frame::kKeyIdMode1) : false;
+}
+
+uint8_t otMacFrameGetKeyId(otRadioFrame *aFrame)
+{
+    uint8_t keyId = 0;
+
+    IgnoreError(static_cast<const Mac::Frame *>(aFrame)->GetKeyId(keyId));
+
+    return keyId;
+}
+
+void otMacFrameSetKeyId(otRadioFrame *aFrame, uint8_t aKeyId)
+{
+    static_cast<Mac::Frame *>(aFrame)->SetKeyId(aKeyId);
+}
+
+uint32_t otMacFrameGetFrameCounter(otRadioFrame *aFrame)
+{
+    uint32_t frameCounter = UINT32_MAX;
+
+    IgnoreError(static_cast<Mac::Frame *>(aFrame)->GetFrameCounter(frameCounter));
+
+    return frameCounter;
+}
+
+void otMacFrameSetFrameCounter(otRadioFrame *aFrame, uint32_t aFrameCounter)
+{
+    static_cast<Mac::Frame *>(aFrame)->SetFrameCounter(aFrameCounter);
+}
diff --git a/examples/platforms/utils/mac_frame.h b/examples/platforms/utils/mac_frame.h
index 429a753..f7fff11 100644
--- a/examples/platforms/utils/mac_frame.h
+++ b/examples/platforms/utils/mac_frame.h
@@ -80,6 +80,17 @@
 bool otMacFrameIsAck(const otRadioFrame *aFrame);
 
 /**
+ * Check if @p aFrame is a Data frame.
+ *
+ * @param[in]   aFrame          A pointer to the frame.
+ *
+ * @retval  true    It is a Data frame.
+ * @retval  false   It is not a Data frame.
+ *
+ */
+bool otMacFrameIsData(const otRadioFrame *aFrame);
+
+/**
  * Check if @p aFrame is an Data Request Command.
  *
  * @param[in]   aFrame          A pointer to the frame.
@@ -150,6 +161,116 @@
  */
 void otMacFrameProcessTransmitAesCcm(otRadioFrame *aFrame, const otExtAddress *aExtAddress);
 
+/**
+ * Tell if the version of @p aFrame is 2015.
+ *
+ * @param[in]   aFrame          A pointer to the frame.
+ *
+ * @retval  true    It is a version 2015 frame.
+ * @retval  false   It is not a version 2015 frame.
+ *
+ */
+bool otMacFrameIsVersion2015(const otRadioFrame *aFrame);
+
+/**
+ * Generate Imm-Ack for @p aFrame.
+ *
+ * @param[in]    aFrame             A pointer to the frame.
+ * @param[in]    aIsFramePending    Value of the ACK's frame pending bit.
+ * @param[out]   aAckFrame          A pointer to the ack frame to be generated.
+ *
+ */
+void otMacFrameGenerateImmAck(const otRadioFrame *aFrame, bool aIsFramePending, otRadioFrame *aAckFrame);
+
+/**
+ * Generate Enh-Ack for @p aFrame.
+ *
+ * @param[in]    aFrame             A pointer to the frame.
+ * @param[in]    aIsFramePending    Value of the ACK's frame pending bit.
+ * @param[in]    aIeData            A pointer to the IE data portion of the ACK to be sent.
+ * @param[in]    aIeLength          The length of IE data portion of the ACK to be sent.
+ * @param[out]   aAckFrame          A pointer to the ack frame to be generated.
+ *
+ * @retval  OT_ERROR_NONE           Successfully generated Enh Ack in @p aAckFrame.
+ * @retval  OT_ERROR_PARSE          @p aFrame has incorrect format.
+ *
+ */
+otError otMacFrameGenerateEnhAck(const otRadioFrame *aFrame,
+                                 bool                aIsFramePending,
+                                 const uint8_t *     aIeData,
+                                 uint8_t             aIeLength,
+                                 otRadioFrame *      aAckFrame);
+
+/**
+ * Set CSL IE content into the frame.
+ *
+ * @param[inout]    aFrame         A pointer to the frame to be modified.
+ * @param[in]       aCslPeriod     CSL Period in CSL IE.
+ * @param[in]       aCslPhase      CSL Phase in CSL IE.
+ *
+ */
+void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCslPhase);
+
+/**
+ * Tell if the security of @p aFrame is enabled.
+ *
+ * @param[in]   aFrame          A pointer to the frame.
+ *
+ * @retval  true    The frame has security enabled.
+ * @retval  false   The frame does not have security enabled.
+ *
+ */
+bool otMacFrameIsSecurityEnabled(otRadioFrame *aFrame);
+
+/**
+ * Tell if the key ID mode of @p aFrame is 1.
+ *
+ * @param[in]   aFrame          A pointer to the frame.
+ *
+ * @retval  true    The frame key ID mode is 1.
+ * @retval  false   The frame security is not enabled or key ID mode is not 1.
+ *
+ */
+bool otMacFrameIsKeyIdMode1(otRadioFrame *aFrame);
+
+/**
+ * Get the key ID of @p aFrame.
+ *
+ * @param[in]   aFrame          A pointer to the frame.
+ *
+ * @returns The key ID of the frame with key ID mode 1. Returns 0 if failed.
+ *
+ */
+uint8_t otMacFrameGetKeyId(otRadioFrame *aFrame);
+
+/**
+ * Set key ID to @p aFrame with key ID mode 1.
+ *
+ * @param[inout]    aFrame     A pointer to the frame to be modified.
+ * @param[in]       aKeyId     Key ID to be set to the frame.
+ *
+ */
+void otMacFrameSetKeyId(otRadioFrame *aFrame, uint8_t aKeyId);
+
+/**
+ * Get the frame counter of @p aFrame.
+ *
+ * @param[in]   aFrame          A pointer to the frame.
+ *
+ * @returns The frame counter of the frame. Returns UINT32_MAX if failed.
+ *
+ */
+uint32_t otMacFrameGetFrameCounter(otRadioFrame *aFrame);
+
+/**
+ * Set frame counter to @p aFrame.
+ *
+ * @param[inout]    aFrame         A pointer to the frame to be modified.
+ * @param[in]       aFrameCounter  Frame counter to be set to the frame.
+ *
+ */
+void otMacFrameSetFrameCounter(otRadioFrame *aFrame, uint32_t aFrameCounter);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/examples/platforms/utils/otns_utils.cpp b/examples/platforms/utils/otns_utils.cpp
new file mode 100644
index 0000000..b2875e1
--- /dev/null
+++ b/examples/platforms/utils/otns_utils.cpp
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <openthread-core-config.h>
+#include <openthread/config.h>
+
+#include <openthread/platform/otns.h>
+#include <openthread/platform/toolchain.h>
+
+#include "common/logging.hpp"
+
+/*
+ * Implementation note:
+ *   These are all "weak" so that a platform may if it chooses to override the instance.
+ */
+
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+
+OT_TOOL_WEAK
+void otPlatOtnsStatus(const char *aStatus)
+{
+    otLogOtns("[OTNS] %s", aStatus);
+}
+
+#endif // OPENTHREAD_CONFIG_OTNS_ENABLE
diff --git a/examples/platforms/utils/settings.h b/examples/platforms/utils/settings.h
index 6cae2be..7b4e545 100644
--- a/examples/platforms/utils/settings.h
+++ b/examples/platforms/utils/settings.h
@@ -38,36 +38,6 @@
 #include <openthread-core-config.h>
 
 /**
- * @def SETTINGS_CONFIG_BASE_ADDRESS
- *
- * The base address of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_BASE_ADDRESS
-#define SETTINGS_CONFIG_BASE_ADDRESS 0x39000
-#endif
-
-/**
- * @def SETTINGS_CONFIG_PAGE_SIZE
- *
- * The page size of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_PAGE_SIZE
-#define SETTINGS_CONFIG_PAGE_SIZE 0x800
-#endif
-
-/**
- * @def SETTINGS_CONFIG_PAGE_NUM
- *
- * The page number of settings.
- *
- */
-#ifndef SETTINGS_CONFIG_PAGE_NUM
-#define SETTINGS_CONFIG_PAGE_NUM 2
-#endif
-
-/**
  * @def OPENTHREAD_SETTINGS_RAM
  *
  * Define as 1 to enable saving the settings in RAM instead of flash.
diff --git a/examples/platforms/utils/settings_flash.c b/examples/platforms/utils/settings_flash.c
deleted file mode 100644
index a75ea07..0000000
--- a/examples/platforms/utils/settings_flash.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements the OpenThread platform abstraction for non-volatile storage of settings.
- *
- */
-
-#include "settings.h"
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <openthread/instance.h>
-#include <openthread/platform/settings.h>
-
-#include "utils/code_utils.h"
-
-#include "flash.h"
-
-#define OT_FLASH_BLOCK_ADD_BEGIN_FLAG (1 << 0)
-#define OT_FLASH_BLOCK_ADD_COMPLETE_FLAG (1 << 1)
-#define OT_FLASH_BLOCK_DELETE_FLAG (1 << 2)
-#define OT_FLASH_BLOCK_INDEX_0_FLAG (1 << 3)
-
-#define OT_SETTINGS_FLAG_SIZE 4
-#define OT_SETTINGS_BLOCK_DATA_SIZE 255
-
-#define OT_SETTINGS_IN_SWAP 0xbe5cc5ef
-#define OT_SETTINGS_IN_USE 0xbe5cc5ee
-#define OT_SETTINGS_NOT_USED 0xbe5cc5ec
-
-OT_TOOL_PACKED_BEGIN
-struct settingsBlock
-{
-    uint16_t key;
-    uint16_t flag;
-    uint16_t length;
-    uint16_t reserved;
-} OT_TOOL_PACKED_END;
-
-#if (SETTINGS_CONFIG_PAGE_NUM <= 1)
-#error "Invalid value for `SETTINGS_CONFIG_PAGE_NUM` (should be >= 2)"
-#endif
-
-#if !OPENTHREAD_SETTINGS_RAM
-
-static uint32_t sSettingsBaseAddress;
-static uint32_t sSettingsUsedSize;
-
-static uint16_t getAlignLength(uint16_t length)
-{
-    return (length + 3) & 0xfffc;
-}
-
-static void setSettingsFlag(uint32_t aBase, uint32_t aFlag)
-{
-    utilsFlashWrite(aBase, (uint8_t *)&aFlag, sizeof(aFlag));
-}
-
-static void initSettings(uint32_t aBase, uint32_t aFlag)
-{
-    uint32_t address      = aBase;
-    uint32_t settingsSize = SETTINGS_CONFIG_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM / 2;
-
-    while (address < (aBase + settingsSize))
-    {
-        utilsFlashErasePage(address);
-        utilsFlashStatusWait(1000);
-        address += SETTINGS_CONFIG_PAGE_SIZE;
-    }
-
-    setSettingsFlag(aBase, aFlag);
-}
-
-static uint32_t swapSettingsBlock(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    uint32_t oldBase      = sSettingsBaseAddress;
-    uint32_t swapAddress  = oldBase;
-    uint32_t usedSize     = sSettingsUsedSize;
-    uint32_t settingsSize = SETTINGS_CONFIG_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM / 2;
-
-    sSettingsBaseAddress =
-        (swapAddress == SETTINGS_CONFIG_BASE_ADDRESS) ? (swapAddress + settingsSize) : SETTINGS_CONFIG_BASE_ADDRESS;
-
-    initSettings(sSettingsBaseAddress, (uint32_t)OT_SETTINGS_IN_SWAP);
-    sSettingsUsedSize = OT_SETTINGS_FLAG_SIZE;
-    swapAddress += OT_SETTINGS_FLAG_SIZE;
-
-    while (swapAddress < (oldBase + usedSize))
-    {
-        OT_TOOL_PACKED_BEGIN
-        struct addSettingsBlock
-        {
-            struct settingsBlock block;
-            uint8_t              data[OT_SETTINGS_BLOCK_DATA_SIZE];
-        } OT_TOOL_PACKED_END addBlock;
-        bool                 valid = true;
-
-        utilsFlashRead(swapAddress, (uint8_t *)(&addBlock.block), sizeof(struct settingsBlock));
-        swapAddress += sizeof(struct settingsBlock);
-
-        if (!(addBlock.block.flag & OT_FLASH_BLOCK_ADD_COMPLETE_FLAG) &&
-            (addBlock.block.flag & OT_FLASH_BLOCK_DELETE_FLAG))
-        {
-            uint32_t address = swapAddress + getAlignLength(addBlock.block.length);
-
-            while (address < (oldBase + usedSize))
-            {
-                struct settingsBlock block;
-
-                utilsFlashRead(address, (uint8_t *)(&block), sizeof(block));
-
-                if (!(block.flag & OT_FLASH_BLOCK_ADD_COMPLETE_FLAG) && (block.flag & OT_FLASH_BLOCK_DELETE_FLAG) &&
-                    !(block.flag & OT_FLASH_BLOCK_INDEX_0_FLAG) && (block.key == addBlock.block.key))
-                {
-                    valid = false;
-                    break;
-                }
-
-                address += (getAlignLength(block.length) + sizeof(struct settingsBlock));
-            }
-
-            if (valid)
-            {
-                utilsFlashRead(swapAddress, addBlock.data, getAlignLength(addBlock.block.length));
-                utilsFlashWrite(sSettingsBaseAddress + sSettingsUsedSize, (uint8_t *)(&addBlock),
-                                getAlignLength(addBlock.block.length) + sizeof(struct settingsBlock));
-                sSettingsUsedSize += (sizeof(struct settingsBlock) + getAlignLength(addBlock.block.length));
-            }
-        }
-        else if (addBlock.block.flag == 0xff)
-        {
-            break;
-        }
-
-        swapAddress += getAlignLength(addBlock.block.length);
-    }
-
-    setSettingsFlag(sSettingsBaseAddress, (uint32_t)OT_SETTINGS_IN_USE);
-    setSettingsFlag(oldBase, (uint32_t)OT_SETTINGS_NOT_USED);
-
-    return settingsSize - sSettingsUsedSize;
-}
-
-static otError addSetting(otInstance *   aInstance,
-                          uint16_t       aKey,
-                          bool           aIndex0,
-                          const uint8_t *aValue,
-                          uint16_t       aValueLength)
-{
-    otError error = OT_ERROR_NONE;
-    OT_TOOL_PACKED_BEGIN
-    struct addSettingsBlock
-    {
-        struct settingsBlock block;
-        uint8_t              data[OT_SETTINGS_BLOCK_DATA_SIZE];
-    } OT_TOOL_PACKED_END addBlock;
-    uint32_t             settingsSize = SETTINGS_CONFIG_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM / 2;
-
-    addBlock.block.flag = 0xff;
-    addBlock.block.key  = aKey;
-
-    if (aIndex0)
-    {
-        addBlock.block.flag &= (~OT_FLASH_BLOCK_INDEX_0_FLAG);
-    }
-
-    addBlock.block.flag &= (~OT_FLASH_BLOCK_ADD_BEGIN_FLAG);
-    addBlock.block.length = aValueLength;
-
-    if ((sSettingsUsedSize + getAlignLength(addBlock.block.length) + sizeof(struct settingsBlock)) >= settingsSize)
-    {
-        otEXPECT_ACTION(swapSettingsBlock(aInstance) >=
-                            (getAlignLength(addBlock.block.length) + sizeof(struct settingsBlock)),
-                        error = OT_ERROR_NO_BUFS);
-    }
-
-    utilsFlashWrite(sSettingsBaseAddress + sSettingsUsedSize, (uint8_t *)(&addBlock.block),
-                    sizeof(struct settingsBlock));
-
-    memset(addBlock.data, 0xff, OT_SETTINGS_BLOCK_DATA_SIZE);
-    memcpy(addBlock.data, aValue, addBlock.block.length);
-
-    utilsFlashWrite(sSettingsBaseAddress + sSettingsUsedSize + sizeof(struct settingsBlock), (uint8_t *)(addBlock.data),
-                    getAlignLength(addBlock.block.length));
-
-    addBlock.block.flag &= (~OT_FLASH_BLOCK_ADD_COMPLETE_FLAG);
-    utilsFlashWrite(sSettingsBaseAddress + sSettingsUsedSize, (uint8_t *)(&addBlock.block),
-                    sizeof(struct settingsBlock));
-    sSettingsUsedSize += (sizeof(struct settingsBlock) + getAlignLength(addBlock.block.length));
-
-exit:
-    return error;
-}
-
-// settings API
-void otPlatSettingsInit(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    uint8_t  index;
-    uint32_t settingsSize = SETTINGS_CONFIG_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM / 2;
-
-    sSettingsBaseAddress = SETTINGS_CONFIG_BASE_ADDRESS;
-
-    utilsFlashInit();
-
-    for (index = 0; index < 2; index++)
-    {
-        uint32_t blockFlag;
-
-        sSettingsBaseAddress += settingsSize * index;
-        utilsFlashRead(sSettingsBaseAddress, (uint8_t *)(&blockFlag), sizeof(blockFlag));
-
-        if (blockFlag == OT_SETTINGS_IN_USE)
-        {
-            break;
-        }
-    }
-
-    if (index == 2)
-    {
-        initSettings(sSettingsBaseAddress, (uint32_t)OT_SETTINGS_IN_USE);
-    }
-
-    sSettingsUsedSize = OT_SETTINGS_FLAG_SIZE;
-
-    while (sSettingsUsedSize < settingsSize)
-    {
-        struct settingsBlock block;
-
-        utilsFlashRead(sSettingsBaseAddress + sSettingsUsedSize, (uint8_t *)(&block), sizeof(block));
-
-        if (!(block.flag & OT_FLASH_BLOCK_ADD_BEGIN_FLAG))
-        {
-            sSettingsUsedSize += (getAlignLength(block.length) + sizeof(struct settingsBlock));
-        }
-        else
-        {
-            break;
-        }
-    }
-}
-
-void otPlatSettingsDeinit(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    otError  error       = OT_ERROR_NOT_FOUND;
-    uint32_t address     = sSettingsBaseAddress + OT_SETTINGS_FLAG_SIZE;
-    uint16_t valueLength = 0;
-    int      index       = 0;
-
-    while (address < (sSettingsBaseAddress + sSettingsUsedSize))
-    {
-        struct settingsBlock block;
-
-        utilsFlashRead(address, (uint8_t *)(&block), sizeof(block));
-
-        if (block.key == aKey)
-        {
-            if (!(block.flag & OT_FLASH_BLOCK_INDEX_0_FLAG))
-            {
-                index = 0;
-            }
-
-            if (!(block.flag & OT_FLASH_BLOCK_ADD_COMPLETE_FLAG) && (block.flag & OT_FLASH_BLOCK_DELETE_FLAG))
-            {
-                if (index == aIndex)
-                {
-                    uint16_t readLength = block.length;
-
-                    // only perform read if an input buffer was passed in
-                    if (aValue != NULL && aValueLength != NULL)
-                    {
-                        // adjust read length if input buffer length is smaller
-                        if (readLength > *aValueLength)
-                        {
-                            readLength = *aValueLength;
-                        }
-
-                        utilsFlashRead(address + sizeof(struct settingsBlock), aValue, readLength);
-                    }
-
-                    valueLength = block.length;
-                    error       = OT_ERROR_NONE;
-                }
-
-                index++;
-            }
-        }
-
-        address += (getAlignLength(block.length) + sizeof(struct settingsBlock));
-    }
-
-    if (aValueLength != NULL)
-    {
-        *aValueLength = valueLength;
-    }
-
-    return error;
-}
-
-otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
-{
-    return addSetting(aInstance, aKey, true, aValue, aValueLength);
-}
-
-otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
-{
-    uint16_t length;
-    bool     index0;
-
-    index0 = (otPlatSettingsGet(aInstance, aKey, 0, NULL, &length) == OT_ERROR_NOT_FOUND ? true : false);
-    return addSetting(aInstance, aKey, index0, aValue, aValueLength);
-}
-
-otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    otError  error   = OT_ERROR_NOT_FOUND;
-    uint32_t address = sSettingsBaseAddress + OT_SETTINGS_FLAG_SIZE;
-    int      index   = 0;
-
-    while (address < (sSettingsBaseAddress + sSettingsUsedSize))
-    {
-        struct settingsBlock block;
-
-        utilsFlashRead(address, (uint8_t *)(&block), sizeof(block));
-
-        if (block.key == aKey)
-        {
-            if (!(block.flag & OT_FLASH_BLOCK_INDEX_0_FLAG))
-            {
-                index = 0;
-            }
-
-            if (!(block.flag & OT_FLASH_BLOCK_ADD_COMPLETE_FLAG) && (block.flag & OT_FLASH_BLOCK_DELETE_FLAG))
-            {
-                if (aIndex == index || aIndex == -1)
-                {
-                    error = OT_ERROR_NONE;
-                    block.flag &= (~OT_FLASH_BLOCK_DELETE_FLAG);
-                    utilsFlashWrite(address, (uint8_t *)(&block), sizeof(block));
-                }
-
-                if (index == 1 && aIndex == 0)
-                {
-                    block.flag &= (~OT_FLASH_BLOCK_INDEX_0_FLAG);
-                    utilsFlashWrite(address, (uint8_t *)(&block), sizeof(block));
-                }
-
-                index++;
-            }
-        }
-
-        address += (getAlignLength(block.length) + sizeof(struct settingsBlock));
-    }
-
-    return error;
-}
-
-void otPlatSettingsWipe(otInstance *aInstance)
-{
-    initSettings(sSettingsBaseAddress, (uint32_t)OT_SETTINGS_IN_USE);
-    otPlatSettingsInit(aInstance);
-}
-
-#endif /* OPENTHREAD_SETTINGS_RAM */
diff --git a/examples/platforms/utils/settings_ram.c b/examples/platforms/utils/settings_ram.c
index 4ac9e2c..bd20c00 100644
--- a/examples/platforms/utils/settings_ram.c
+++ b/examples/platforms/utils/settings_ram.c
@@ -49,11 +49,12 @@
 static uint8_t  sSettingsBuf[SETTINGS_BUFFER_SIZE];
 static uint16_t sSettingsBufLength;
 
+OT_TOOL_PACKED_BEGIN
 struct settingsBlock
 {
     uint16_t key;
     uint16_t length;
-};
+} OT_TOOL_PACKED_END;
 
 // settings API
 void otPlatSettingsInit(otInstance *aInstance)
diff --git a/include/Makefile.am b/include/Makefile.am
index de63beb..e6ab560 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -40,12 +40,6 @@
     openthread                            \
     $(NULL)
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    openthread                            \
-    $(NULL)
-
 install-headers: install-includeHEADERS
 
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/include/openthread-config-android.h b/include/openthread-config-android.h
index 02acf9e..6f1659f 100644
--- a/include/openthread-config-android.h
+++ b/include/openthread-config-android.h
@@ -51,20 +51,17 @@
 #define OPENTHREAD_CONFIG_JOINER_ENABLE 1
 
 /* Define to 1 if you want to use legacy network support */
-#define OPENTHREAD_CONFIG_LEGACY_ENABLE 1
+#define OPENTHREAD_CONFIG_LEGACY_ENABLE 0
 
 /* Define to 1 to enable the NCP UART interface. */
-#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1
+#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 0
 
-/* Define to 1 to build posix application. */
-#define OPENTHREAD_PLATFORM_POSIX_APP 1
+/* Define to 1 to enable posix platform. */
+#define OPENTHREAD_PLATFORM_POSIX 0
 
 /* Define to 1 if you want to enable Service */
 #define OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1
 
-/* Define to 1 to enable the UDP forward feature. */
-#define OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE 1
-
 /* OpenThread examples */
 #define OPENTHREAD_EXAMPLES none
 
diff --git a/include/openthread/Makefile.am b/include/openthread/Makefile.am
index b1b5d5e..448d8e0 100644
--- a/include/openthread/Makefile.am
+++ b/include/openthread/Makefile.am
@@ -40,13 +40,11 @@
     platform                              \
     $(NULL)
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    platform                              \
-    $(NULL)
-
 openthread_headers                      = \
+    backbone_router.h                     \
+    backbone_router_ftd.h                 \
+    border_agent.h                        \
+    border_router.h                       \
     channel_manager.h                     \
     channel_monitor.h                     \
     child_supervision.h                   \
@@ -54,10 +52,7 @@
     coap_secure.h                         \
     coap.h                                \
     commissioner.h                        \
-    config.h                              \
     crypto.h                              \
-    border_agent.h                        \
-    border_router.h                       \
     dataset.h                             \
     dataset_ftd.h                         \
     diag.h                                \
@@ -76,6 +71,7 @@
     message.h                             \
     ncp.h                                 \
     netdata.h                             \
+    netdiag.h                             \
     network_time.h                        \
     random_crypto.h                       \
     random_noncrypto.h                    \
@@ -93,6 +89,10 @@
 include_HEADERS                         = \
     $(NULL)
 
+noinst_HEADERS                          = \
+    config.h                              \
+    $(NULL)
+
 install-headers: install-includeHEADERS
 
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/include/openthread/backbone_router.h b/include/openthread/backbone_router.h
new file mode 100644
index 0000000..23cb4d4
--- /dev/null
+++ b/include/openthread/backbone_router.h
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *  This file defines the OpenThread Backbone Router API (Thread 1.2)
+ */
+
+#ifndef OPENTHREAD_BACKBONE_ROUTER_H_
+#define OPENTHREAD_BACKBONE_ROUTER_H_
+
+#include <openthread/instance.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup api-backbone-router
+ *
+ * @brief
+ *  This module includes functions for the OpenThread Backbone Router Service.
+ *
+ * @{
+ *
+ */
+
+/**
+ * This structure represents Backbone Router configuration.
+ *
+ */
+typedef struct otBackboneRouterConfig
+{
+    uint16_t mServer16;            ///< Only used when get Primary Backbone Router information in the Thread Network
+    uint16_t mReregistrationDelay; ///< Reregistration Delay (in seconds)
+    uint32_t mMlrTimeout;          ///< Multicast Listener Registration Timeout (in seconds)
+    uint8_t  mSequenceNumber;      ///< Sequence Number
+} otBackboneRouterConfig;
+
+/**
+ * This function gets the Primary Backbone Router information in the Thread Network.
+ *
+ * @param[in]   aInstance            A pointer to an OpenThread instance.
+ * @param[out]  aConfig              A pointer to where to put Primary Backbone Router information.
+ *
+ * @retval OT_ERROR_NONE              Successfully got Primary Backbone Router information.
+ * @retval OT_ERROR_NOT_FOUND         No Primary Backbone Router exists.
+ *
+ */
+otError otBackboneRouterGetPrimary(otInstance *aInstance, otBackboneRouterConfig *aConfig);
+
+/**
+ * @}
+ *
+ */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // OPENTHREAD_BACKBONE_ROUTER_H_
diff --git a/include/openthread/backbone_router_ftd.h b/include/openthread/backbone_router_ftd.h
new file mode 100644
index 0000000..4eca8f6
--- /dev/null
+++ b/include/openthread/backbone_router_ftd.h
@@ -0,0 +1,186 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *  This file defines the OpenThread Backbone Router API (for Thread 1.2 FTD with
+ *  `OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE`).
+ *
+ */
+
+#ifndef OPENTHREAD_BACKBONE_ROUTER_FTD_H_
+#define OPENTHREAD_BACKBONE_ROUTER_FTD_H_
+
+#include <openthread/backbone_router.h>
+#include <openthread/ip6.h>
+#include <openthread/netdata.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup api-backbone-router
+ *
+ * @{
+ *
+ */
+
+/**
+ * Represents the Backbone Router Status.
+ *
+ */
+typedef enum
+{
+    OT_BACKBONE_ROUTER_STATE_DISABLED  = 0, ///< Backbone function is disabled.
+    OT_BACKBONE_ROUTER_STATE_SECONDARY = 1, ///< Secondary Backbone Router.
+    OT_BACKBONE_ROUTER_STATE_PRIMARY   = 2, ///< The Primary Backbone Router.
+} otBackboneRouterState;
+
+/**
+ * This function enables or disables Backbone functionality.
+ *
+ * @param[in] aInstance A pointer to an OpenThread instance.
+ * @param[in] aEnable   TRUE to enable Backbone functionality, FALSE otherwise.
+ *
+ * @sa otBackboneRouterGetState
+ * @sa otBackboneRouterGetConfig
+ * @sa otBackboneRouterSetConfig
+ * @sa otBackboneRouterRegister
+ *
+ */
+void otBackboneRouterSetEnabled(otInstance *aInstance, bool aEnable);
+
+/**
+ * This function gets the Backbone Router state.
+ *
+ * @param[in] aInstance       A pointer to an OpenThread instance.
+ *
+ * @retval OT_BACKBONE_ROUTER_STATE_DISABLED   Backbone functionality is disabled.
+ * @retval OT_BACKBONE_ROUTER_STATE_SECONDARY  Secondary Backbone Router.
+ * @retval OT_BACKBONE_ROUTER_STATE_PRIMARY    The Primary Backbone Router.
+ *
+ * @sa otBackboneRouterSetEnabled
+ * @sa otBackboneRouterGetConfig
+ * @sa otBackboneRouterSetConfig
+ * @sa otBackboneRouterRegister
+ *
+ */
+otBackboneRouterState otBackboneRouterGetState(otInstance *aInstance);
+
+/**
+ * This function gets the local Backbone Router configuration.
+ *
+ * @param[in]   aInstance            A pointer to an OpenThread instance.
+ * @param[out]  aConfig              A pointer where to put local Backbone Router configuration.
+ *
+ *
+ * @sa otBackboneRouterSetEnabled
+ * @sa otBackboneRouterGetState
+ * @sa otBackboneRouterSetConfig
+ * @sa otBackboneRouterRegister
+ *
+ */
+void otBackboneRouterGetConfig(otInstance *aInstance, otBackboneRouterConfig *aConfig);
+
+/**
+ * This function sets the local Backbone Router configuration.
+ *
+ * @param[in]  aInstance             A pointer to an OpenThread instance.
+ * @param[in]  aConfig               A pointer to the Backbone Router configuration to take effect.
+ *
+ * @retval OT_ERROR_NONE          Successfully updated configuration.
+ * @retval OT_ERROR_INVALID_ARGS  The configuration in @p aConfig is invalid.
+ *
+ * @sa otBackboneRouterSetEnabled
+ * @sa otBackboneRouterGetState
+ * @sa otBackboneRouterGetConfig
+ * @sa otBackboneRouterRegister
+ *
+ */
+otError otBackboneRouterSetConfig(otInstance *aInstance, const otBackboneRouterConfig *aConfig);
+
+/**
+ * This function explicitly registers local Backbone Router configuration.
+ *
+ * @param[in]  aInstance             A pointer to an OpenThread instance.
+ *
+ * @retval OT_ERROR_NO_BUFS           Insufficient space to add the Backbone Router service.
+ * @retval OT_ERROR_NONE              Successfully queued a Server Data Request message for delivery.
+ *
+ * @sa otBackboneRouterSetEnabled
+ * @sa otBackboneRouterGetState
+ * @sa otBackboneRouterGetConfig
+ * @sa otBackboneRouterSetConfig
+ *
+ */
+otError otBackboneRouterRegister(otInstance *aInstance);
+
+/**
+ * This method returns the Backbone Router registration jitter value.
+ *
+ * @returns The Backbone Router registration jitter value.
+ *
+ * @sa otBackboneRouterSetRegistrationJitter
+ *
+ */
+uint8_t otBackboneRouterGetRegistrationJitter(otInstance *aInstance);
+
+/**
+ * This method sets the Backbone Router registration jitter value.
+ *
+ * @param[in]  aJitter the Backbone Router registration jitter value to set.
+ *
+ * @sa otBackboneRouterGetRegistrationJitter
+ *
+ */
+void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitter);
+
+/**
+ * This method gets the local Domain Prefix configuration.
+ *
+ * @param[in]  aInstance A pointer to an OpenThread instance.
+ * @param[out] aConfig   A pointer to the Domain Prefix configuration.
+ *
+ * @retval OT_ERROR_NONE       Successfully got the Domain Prefix configuration.
+ * @retval OT_ERROR_NOT_FOUND  No Domain Prefix was configured.
+ *
+ */
+otError otBackboneRouterGetDomainPrefix(otInstance *aInstance, otBorderRouterConfig *aConfig);
+
+/**
+ * @}
+ *
+ */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // OPENTHREAD_BACKBONE_ROUTER_FTD_H_
diff --git a/include/openthread/cli.h b/include/openthread/cli.h
index 9f64ce1..1683c23 100644
--- a/include/openthread/cli.h
+++ b/include/openthread/cli.h
@@ -51,8 +51,8 @@
  */
 typedef struct otCliCommand
 {
-    const char *mName;                        ///< A pointer to the command string.
-    void (*mCommand)(int argc, char *argv[]); ///< A function pointer to process the command.
+    const char *mName;                                    ///< A pointer to the command string.
+    void (*mCommand)(uint8_t aArgsLength, char *aArgs[]); ///< A function pointer to process the command.
 } otCliCommand;
 
 /**
diff --git a/include/openthread/coap.h b/include/openthread/coap.h
index f02cb1b..f7733d9 100644
--- a/include/openthread/coap.h
+++ b/include/openthread/coap.h
@@ -60,6 +60,10 @@
 
 #define OT_COAP_MAX_TOKEN_LENGTH 8 ///< Max token length as specified (RFC 7252).
 
+#define OT_COAP_MAX_RETRANSMIT 30 ///< Max retransmit supported by OpenThread.
+
+#define OT_COAP_MIN_ACK_TIMEOUT 1000 ///< Minimal ACK timeout in milliseconds supported by OpenThread.
+
 /**
  * CoAP Type values.
  *
@@ -90,12 +94,13 @@
     OT_COAP_CODE_PUT    = OT_COAP_CODE(0, 3), ///< Put
     OT_COAP_CODE_DELETE = OT_COAP_CODE(0, 4), ///< Delete
 
-    OT_COAP_CODE_RESPONSE_MIN = OT_COAP_CODE(2, 0), ///< 2.00
-    OT_COAP_CODE_CREATED      = OT_COAP_CODE(2, 1), ///< Created
-    OT_COAP_CODE_DELETED      = OT_COAP_CODE(2, 2), ///< Deleted
-    OT_COAP_CODE_VALID        = OT_COAP_CODE(2, 3), ///< Valid
-    OT_COAP_CODE_CHANGED      = OT_COAP_CODE(2, 4), ///< Changed
-    OT_COAP_CODE_CONTENT      = OT_COAP_CODE(2, 5), ///< Content
+    OT_COAP_CODE_RESPONSE_MIN = OT_COAP_CODE(2, 0),  ///< 2.00
+    OT_COAP_CODE_CREATED      = OT_COAP_CODE(2, 1),  ///< Created
+    OT_COAP_CODE_DELETED      = OT_COAP_CODE(2, 2),  ///< Deleted
+    OT_COAP_CODE_VALID        = OT_COAP_CODE(2, 3),  ///< Valid
+    OT_COAP_CODE_CHANGED      = OT_COAP_CODE(2, 4),  ///< Changed
+    OT_COAP_CODE_CONTENT      = OT_COAP_CODE(2, 5),  ///< Content
+    OT_COAP_CODE_CONTINUE     = OT_COAP_CODE(2, 31), ///< RFC7959 Continue
 
     OT_COAP_CODE_BAD_REQUEST         = OT_COAP_CODE(4, 0),  ///< Bad Request
     OT_COAP_CODE_UNAUTHORIZED        = OT_COAP_CODE(4, 1),  ///< Unauthorized
@@ -104,6 +109,7 @@
     OT_COAP_CODE_NOT_FOUND           = OT_COAP_CODE(4, 4),  ///< Not Found
     OT_COAP_CODE_METHOD_NOT_ALLOWED  = OT_COAP_CODE(4, 5),  ///< Method Not Allowed
     OT_COAP_CODE_NOT_ACCEPTABLE      = OT_COAP_CODE(4, 6),  ///< Not Acceptable
+    OT_COAP_CODE_REQUEST_INCOMPLETE  = OT_COAP_CODE(4, 8),  ///< RFC7959 Request Entity Incomplete
     OT_COAP_CODE_PRECONDITION_FAILED = OT_COAP_CODE(4, 12), ///< Precondition Failed
     OT_COAP_CODE_REQUEST_TOO_LARGE   = OT_COAP_CODE(4, 13), ///< Request Entity Too Large
     OT_COAP_CODE_UNSUPPORTED_FORMAT  = OT_COAP_CODE(4, 15), ///< Unsupported Content-Format
@@ -125,7 +131,7 @@
     OT_COAP_OPTION_URI_HOST       = 3,  ///< Uri-Host
     OT_COAP_OPTION_E_TAG          = 4,  ///< ETag
     OT_COAP_OPTION_IF_NONE_MATCH  = 5,  ///< If-None-Match
-    OT_COAP_OPTION_OBSERVE        = 6,  ///< Observe
+    OT_COAP_OPTION_OBSERVE        = 6,  ///< Observe [RFC7641]
     OT_COAP_OPTION_URI_PORT       = 7,  ///< Uri-Port
     OT_COAP_OPTION_LOCATION_PATH  = 8,  ///< Location-Path
     OT_COAP_OPTION_URI_PATH       = 11, ///< Uri-Path
@@ -134,12 +140,28 @@
     OT_COAP_OPTION_URI_QUERY      = 15, ///< Uri-Query
     OT_COAP_OPTION_ACCEPT         = 17, ///< Accept
     OT_COAP_OPTION_LOCATION_QUERY = 20, ///< Location-Query
+    OT_COAP_OPTION_BLOCK2         = 23, ///< Block2 (RFC7959)
+    OT_COAP_OPTION_BLOCK1         = 27, ///< Block1 (RFC7959)
     OT_COAP_OPTION_PROXY_URI      = 35, ///< Proxy-Uri
     OT_COAP_OPTION_PROXY_SCHEME   = 39, ///< Proxy-Scheme
     OT_COAP_OPTION_SIZE1          = 60, ///< Size1
 } otCoapOptionType;
 
 /**
+ * CoAP Block Size Exponents
+ */
+typedef enum otCoapBlockSize
+{
+    OT_COAP_BLOCK_SIZE_16   = 0,
+    OT_COAP_BLOCK_SIZE_32   = 1,
+    OT_COAP_BLOCK_SIZE_64   = 2,
+    OT_COAP_BLOCK_SIZE_128  = 3,
+    OT_COAP_BLOCK_SIZE_256  = 4,
+    OT_COAP_BLOCK_SIZE_512  = 5,
+    OT_COAP_BLOCK_SIZE_1024 = 6,
+} otCoapBlockSize;
+
+/**
  * This structure represents a CoAP option.
  *
  */
@@ -344,6 +366,40 @@
 } otCoapResource;
 
 /**
+ * This structure represents the CoAP transmission parameters.
+ *
+ */
+typedef struct otCoapTxParameters
+{
+    /**
+     * Minimum spacing before first retransmission when ACK is not received, in milliseconds (RFC7252 default value is
+     * 2000ms).
+     *
+     */
+    uint32_t mAckTimeout;
+
+    /**
+     * Numerator of ACK_RANDOM_FACTOR used to calculate maximum spacing before first retransmission when ACK is not
+     * received (RFC7252 default value of ACK_RANDOM_FACTOR is 1.5; must not be decreased below 1).
+     *
+     */
+    uint8_t mAckRandomFactorNumerator;
+
+    /**
+     * Denominator of ACK_RANDOM_FACTOR used to calculate maximum spacing before first retransmission when ACK is not
+     * received (RFC7252 default value of ACK_RANDOM_FACTOR is 1.5; must not be decreased below 1).
+     *
+     */
+    uint8_t mAckRandomFactorDenominator;
+
+    /**
+     * Maximum number of retransmissions for CoAP Confirmable messages (RFC7252 default value is 4).
+     *
+     */
+    uint8_t mMaxRetransmit;
+} otCoapTxParameters;
+
+/**
  * This function initializes the CoAP header.
  *
  * @param[inout] aMessage   A pointer to the CoAP message to initialize.
@@ -439,6 +495,7 @@
  * @retval OT_ERROR_INVALID_ARGS  The option type is not equal or greater than the last option type.
  * @retval OT_ERROR_NO_BUFS       The option length exceeds the buffer size.
  *
+ * @see otCoapMessageGetOptionUintValue
  */
 otError otCoapMessageAppendUintOption(otMessage *aMessage, uint16_t aNumber, uint32_t aValue);
 
@@ -469,6 +526,46 @@
 otError otCoapMessageAppendUriPathOptions(otMessage *aMessage, const char *aUriPath);
 
 /**
+ * This function converts a CoAP Block option SZX field to the actual block size
+ *
+ * @param[in]     aSize     Block size exponent.
+ *
+ * @returns The actual size exponent value.
+ *
+ */
+uint16_t otCoapBlockSizeFromExponent(otCoapBlockSize aSize);
+
+/**
+ * This function appends a Block2 option
+ *
+ * @param[inout]  aMessage  A pointer to the CoAP message.
+ * @param[in]     aNum      Current block number.
+ * @param[in]     aMore     Boolean to indicate more blocks are to be sent.
+ * @param[in]     aSize     Block Size Exponent.
+ *
+ * @retval OT_ERROR_NONE          Successfully appended the option.
+ * @retval OT_ERROR_INVALID_ARGS  The option type is not equal or greater than the last option type.
+ * @retval OT_ERROR_NO_BUFS       The option length exceeds the buffer size.
+ *
+ */
+otError otCoapMessageAppendBlock2Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSize aSize);
+
+/**
+ * This function appends a Block1 option
+ *
+ * @param[inout]  aMessage  A pointer to the CoAP message.
+ * @param[in]     aNum      Current block number.
+ * @param[in]     aMore     Boolean to indicate more blocks are to be sent.
+ * @param[in]     aSize     Block Size Exponent.
+ *
+ * @retval OT_ERROR_NONE          Successfully appended the option.
+ * @retval OT_ERROR_INVALID_ARGS  The option type is not equal or greater than the last option type.
+ * @retval OT_ERROR_NO_BUFS       The option length exceeds the buffer size.
+ *
+ */
+otError otCoapMessageAppendBlock1Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSize aSize);
+
+/**
  * This function appends a Proxy-Uri option.
  *
  * @param[inout]  aMessage  A pointer to the CoAP message.
@@ -590,6 +687,17 @@
 otError otCoapOptionIteratorInit(otCoapOptionIterator *aIterator, const otMessage *aMessage);
 
 /**
+ * This function returns a pointer to the first option matching the specified option number.
+ *
+ * @param[in]  aIterator A pointer to the CoAP message option iterator.
+ * @param[in]  aOption   The option number sought.
+ *
+ * @returns A pointer to the first matching option. If no matching option is present NULL pointer is returned.
+ *
+ */
+const otCoapOption *otCoapOptionIteratorGetFirstOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption);
+
+/**
  * This function returns a pointer to the first option.
  *
  * @param[inout]  aIterator A pointer to the CoAP message option iterator.
@@ -600,6 +708,17 @@
 const otCoapOption *otCoapOptionIteratorGetFirstOption(otCoapOptionIterator *aIterator);
 
 /**
+ * This function returns a pointer to the next option matching the specified option number.
+ *
+ * @param[in]  aIterator A pointer to the CoAP message option iterator.
+ * @param[in]  aOption   The option number sought.
+ *
+ * @returns A pointer to the next matching option. If no further matching option is present NULL pointer is returned.
+ *
+ */
+const otCoapOption *otCoapOptionIteratorGetNextOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption);
+
+/**
  * This function returns a pointer to the next option.
  *
  * @param[inout]  aIterator A pointer to the CoAP message option iterator.
@@ -610,6 +729,21 @@
 const otCoapOption *otCoapOptionIteratorGetNextOption(otCoapOptionIterator *aIterator);
 
 /**
+ * This function fills current option value into @p aValue assuming the current value is an unsigned integer encoded
+ * according to https://tools.ietf.org/html/rfc7252#section-3.2
+ *
+ * @param[inout]    aIterator   A pointer to the CoAP message option iterator.
+ * @param[out]      aValue      A pointer to an unsigned integer to receive the option value.
+ *
+ * @retval  OT_ERROR_NONE       Successfully filled value.
+ * @retval  OT_ERROR_NOT_FOUND  No current option.
+ * @retval  OT_ERROR_NO_BUFS    Value is too long to fit in a uint64_t.
+ *
+ * @see otCoapMessageAppendUintOption
+ */
+otError otCoapOptionIteratorGetOptionUintValue(otCoapOptionIterator *aIterator, uint64_t *const aValue);
+
+/**
  * This function fills current option value into @p aValue.
  *
  * @param[inout]  aIterator A pointer to the CoAP message option iterator.
@@ -636,6 +770,35 @@
 otMessage *otCoapNewMessage(otInstance *aInstance, const otMessageSettings *aSettings);
 
 /**
+ * This function sends a CoAP request with custom transmission parameters.
+ *
+ * If a response for a request is expected, respective function and context information should be provided.
+ * If no response is expected, these arguments should be NULL pointers.
+ *
+ * @param[in]  aInstance        A pointer to an OpenThread instance.
+ * @param[in]  aMessage         A pointer to the message to send.
+ * @param[in]  aMessageInfo     A pointer to the message info associated with @p aMessage.
+ * @param[in]  aHandler         A function pointer that shall be called on response reception or timeout.
+ * @param[in]  aContext         A pointer to arbitrary context information. May be NULL if not used.
+ * @param[in]  aTxParameters    A pointer to transmission parameters for this request. Use NULL for defaults.
+ *                              Otherwise, parameters given must meet the following conditions:
+ *                              1. mMaxRetransmit is no more than OT_COAP_MAX_RETRANSMIT.
+ *                              2. mAckRandomFactorNumerator / mAckRandomFactorDenominator must not be below 1.0.
+ *                              3. The calculated exchange life time must not overflow uint32_t.
+ *
+ * @retval OT_ERROR_INVALID_ARGS    @p aTxParameters is invalid.
+ * @retval OT_ERROR_NONE            Successfully sent CoAP message.
+ * @retval OT_ERROR_NO_BUFS         Failed to allocate retransmission data.
+ *
+ */
+otError otCoapSendRequestWithParameters(otInstance *              aInstance,
+                                        otMessage *               aMessage,
+                                        const otMessageInfo *     aMessageInfo,
+                                        otCoapResponseHandler     aHandler,
+                                        void *                    aContext,
+                                        const otCoapTxParameters *aTxParameters);
+
+/**
  * This function sends a CoAP request.
  *
  * If a response for a request is expected, respective function and context information should be provided.
@@ -651,11 +814,14 @@
  * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data.
  *
  */
-otError otCoapSendRequest(otInstance *          aInstance,
-                          otMessage *           aMessage,
-                          const otMessageInfo * aMessageInfo,
-                          otCoapResponseHandler aHandler,
-                          void *                aContext);
+static inline otError otCoapSendRequest(otInstance *          aInstance,
+                                        otMessage *           aMessage,
+                                        const otMessageInfo * aMessageInfo,
+                                        otCoapResponseHandler aHandler,
+                                        void *                aContext)
+{
+    return otCoapSendRequestWithParameters(aInstance, aMessage, aMessageInfo, aHandler, aContext, NULL);
+}
 
 /**
  * This function starts the CoAP server.
@@ -684,11 +850,8 @@
  * @param[in]  aInstance  A pointer to an OpenThread instance.
  * @param[in]  aResource  A pointer to the resource.
  *
- * @retval OT_ERROR_NONE     Successfully added @p aResource.
- * @retval OT_ERROR_ALREADY  The @p aResource was already added.
- *
  */
-otError otCoapAddResource(otInstance *aInstance, otCoapResource *aResource);
+void otCoapAddResource(otInstance *aInstance, otCoapResource *aResource);
 
 /**
  * This function removes a resource from the CoAP server.
@@ -710,6 +873,23 @@
 void otCoapSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext);
 
 /**
+ * This function sends a CoAP response from the server with custom transmission parameters.
+ *
+ * @param[in]  aInstance        A pointer to an OpenThread instance.
+ * @param[in]  aMessage         A pointer to the CoAP response to send.
+ * @param[in]  aMessageInfo     A pointer to the message info associated with @p aMessage.
+ * @param[in]  aTxParameters    A pointer to transmission parameters for this response. Use NULL for defaults.
+ *
+ * @retval OT_ERROR_NONE     Successfully enqueued the CoAP response message.
+ * @retval OT_ERROR_NO_BUFS  Insufficient buffers available to send the CoAP response.
+ *
+ */
+otError otCoapSendResponseWithParameters(otInstance *              aInstance,
+                                         otMessage *               aMessage,
+                                         const otMessageInfo *     aMessageInfo,
+                                         const otCoapTxParameters *aTxParameters);
+
+/**
  * This function sends a CoAP response from the server.
  *
  * @param[in]  aInstance     A pointer to an OpenThread instance.
@@ -720,7 +900,10 @@
  * @retval OT_ERROR_NO_BUFS  Insufficient buffers available to send the CoAP response.
  *
  */
-otError otCoapSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+static inline otError otCoapSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo)
+{
+    return otCoapSendResponseWithParameters(aInstance, aMessage, aMessageInfo, NULL);
+}
 
 /**
  * @}
diff --git a/include/openthread/coap_secure.h b/include/openthread/coap_secure.h
index e939fe5..11caec5 100644
--- a/include/openthread/coap_secure.h
+++ b/include/openthread/coap_secure.h
@@ -257,11 +257,8 @@
  * @param[in]  aInstance  A pointer to an OpenThread instance.
  * @param[in]  aResource  A pointer to the resource.
  *
- * @retval OT_ERROR_NONE     Successfully added @p aResource.
- * @retval OT_ERROR_ALREADY  The @p aResource was already added.
- *
  */
-otError otCoapSecureAddResource(otInstance *aInstance, otCoapResource *aResource);
+void otCoapSecureAddResource(otInstance *aInstance, otCoapResource *aResource);
 
 /**
  * This function removes a resource from the CoAP Secure server.
diff --git a/include/openthread/commissioner.h b/include/openthread/commissioner.h
index 169ac1e..42d3cce 100644
--- a/include/openthread/commissioner.h
+++ b/include/openthread/commissioner.h
@@ -37,6 +37,7 @@
 
 #include <openthread/dataset.h>
 #include <openthread/ip6.h>
+#include <openthread/joiner.h>
 #include <openthread/platform/radio.h>
 #include <openthread/platform/toolchain.h>
 
@@ -112,7 +113,27 @@
     bool mIsJoinerUdpPortSet : 1; ///< TRUE if Joiner UDP Port is set, FALSE otherwise.
 } otCommissioningDataset;
 
-#define OT_PSKD_MAX_SIZE 32 ///< Size of a Joiner PSKd (bytes)
+#define OT_JOINER_MAX_PSKD_LENGTH 32 ///< Maximum string length of a Joiner PSKd (does not include null char).
+
+/**
+ * This structure represents a Joiner PSKd.
+ *
+ */
+typedef struct otJoinerPskd
+{
+    char m8[OT_JOINER_MAX_PSKD_LENGTH + 1]; ///< Char string array (must be null terminated - +1 is for null char).
+} otJoinerPskd;
+
+/**
+ * This enumeration defines a Joiner Info Typer.
+ *
+ */
+typedef enum otJoinerInfoType
+{
+    OT_JOINER_INFO_TYPE_ANY       = 0, ///< Accept any Joiner (no EUI64 or Discerner is specified).
+    OT_JOINER_INFO_TYPE_EUI64     = 1, ///< Joiner EUI-64 is specified (`mSharedId.mEui64` in `otJoinerInfo`).
+    OT_JOINER_INFO_TYPE_DISCERNER = 2, ///< Joiner Discerner is specified (`mSharedId.mDiscerner` in `otJoinerInfo`).
+} otJoinerInfoType;
 
 /**
  * This structure represents a Joiner Info.
@@ -120,11 +141,14 @@
  */
 typedef struct otJoinerInfo
 {
-    otExtAddress mEui64;                     ///< Joiner eui64
-    char         mPsk[OT_PSKD_MAX_SIZE + 1]; ///< Joiner pskd
-    uint32_t     mExpirationTime;            ///< Joiner expiration time in msec
-
-    bool mAny : 1; /// TRUE if eui64 isn't set, FALSE otherwise.
+    otJoinerInfoType mType; ///< Joiner type.
+    union
+    {
+        otExtAddress      mEui64;     ///< Joiner EUI64 (when `mType` is `OT_JOINER_INFO_TYPE_EUI64`)
+        otJoinerDiscerner mDiscerner; ///< Joiner Discerner (when `mType` is `OT_JOINER_INFO_TYPE_DISCERNER`)
+    } mSharedId;                      ///< Shared fields
+    otJoinerPskd mPskd;               ///< Joiner PSKd
+    uint32_t     mExpirationTime;     ///< Joiner expiration time in msec
 } otJoinerInfo;
 
 /**
@@ -141,12 +165,14 @@
 /**
  * This function pointer is called whenever the joiner state changes.
  *
- * @param[in]  aEvent     The joiner event type.
- * @param[in]  aJoinerId  A pointer to the Joiner ID.
- * @param[in]  aContext   A pointer to application-specific context.
+ * @param[in]  aEvent       The joiner event type.
+ * @param[in]  aJoinerInfo  A pointer to the Joiner Info.
+ * @param[in]  aJoinerId    A pointer to the Joiner ID (if not known, it will be NULL).
+ * @param[in]  aContext     A pointer to application-specific context.
  *
  */
 typedef void (*otCommissionerJoinerCallback)(otCommissionerJoinerEvent aEvent,
+                                             const otJoinerInfo *      aJoinerInfo,
                                              const otExtAddress *      aJoinerId,
                                              void *                    aContext);
 
@@ -158,8 +184,9 @@
  * @param[in]  aJoinerCallback   A pointer to a function that is called with a joiner event occurs.
  * @param[in]  aCallbackContext  A pointer to application-specific context.
  *
- * @retval OT_ERROR_NONE           Successfully started the Commissioner role.
- * @retval OT_ERROR_INVALID_STATE  Commissioner is already started.
+ * @retval OT_ERROR_NONE           Successfully started the Commissioner service.
+ * @retval OT_ERROR_ALREADY        Commissioner is already started.
+ * @retval OT_ERROR_INVALID_STATE  Device is not currently attached to a network.
  *
  */
 otError otCommissionerStart(otInstance *                 aInstance,
@@ -172,8 +199,8 @@
  *
  * @param[in]  aInstance         A pointer to an OpenThread instance.
  *
- * @retval OT_ERROR_NONE           Successfully stopped the Commissioner role.
- * @retval OT_ERROR_INVALID_STATE  Commissioner is already stopped.
+ * @retval OT_ERROR_NONE     Successfully stopped the Commissioner service.
+ * @retval OT_ERROR_ALREADY  Commissioner is already stopped.
  *
  */
 otError otCommissionerStop(otInstance *aInstance);
@@ -200,6 +227,27 @@
                                 uint32_t            aTimeout);
 
 /**
+ * This function adds a Joiner entry with a given Joiner Discerner value.
+ *
+ * @param[in]  aInstance          A pointer to an OpenThread instance.
+ * @param[in]  aDiscerner         A pointer to the Joiner Discerner.
+ * @param[in]  aPskd              A pointer to the PSKd.
+ * @param[in]  aTimeout           A time after which a Joiner is automatically removed, in seconds.
+ *
+ * @retval OT_ERROR_NONE          Successfully added the Joiner.
+ * @retval OT_ERROR_NO_BUFS       No buffers available to add the Joiner.
+ * @retval OT_ERROR_INVALID_ARGS  @p aDiscerner or @p aPskd is invalid.
+ * @retval OT_ERROR_INVALID_STATE The commissioner is not active.
+ *
+ * @note Only use this after successfully starting the Commissioner role with otCommissionerStart().
+ *
+ */
+otError otCommissionerAddJoinerWithDiscerner(otInstance *             aInstance,
+                                             const otJoinerDiscerner *aDiscerner,
+                                             const char *             aPskd,
+                                             uint32_t                 aTimeout);
+
+/**
  * This method get joiner info at aIterator position.
  *
  * @param[in]      aInstance   A pointer to instance.
@@ -229,6 +277,22 @@
 otError otCommissionerRemoveJoiner(otInstance *aInstance, const otExtAddress *aEui64);
 
 /**
+ * This function removes a Joiner entry.
+ *
+ * @param[in]  aInstance          A pointer to an OpenThread instance.
+ * @param[in]  aEui64             A pointer to the Joiner Discerner.
+ *
+ * @retval OT_ERROR_NONE          Successfully removed the Joiner.
+ * @retval OT_ERROR_NOT_FOUND     The Joiner specified by @p aEui64 was not found.
+ * @retval OT_ERROR_INVALID_ARGS  @p aDiscerner is invalid.
+ * @retval OT_ERROR_INVALID_STATE The commissioner is not active.
+ *
+ * @note Only use this after successfully starting the Commissioner role with otCommissionerStart().
+ *
+ */
+otError otCommissionerRemoveJoinerWithDiscerner(otInstance *aInstance, const otJoinerDiscerner *aDiscerner);
+
+/**
  * This function gets the Provisioning URL.
  *
  * @param[in]    aInstance       A pointer to an OpenThread instance.
@@ -403,25 +467,6 @@
 otCommissionerState otCommissionerGetState(otInstance *aInstance);
 
 /**
- * This helper function generates PSKc from a given pass-phrase, network name, and extended PAN Id.
- *
- * PSKc is used to establish the Commissioner Session.
- *
- * @param[in]  aPassPhrase   The commissioning pass-phrase.
- * @param[in]  aNetworkName  The network name for PSKc computation.
- * @param[in]  aExtPanId     The extended PAN ID for PSKc computation.
- * @param[out] aPskc         A pointer to variable to output the generated PSKc.
- *
- * @retval OT_ERROR_NONE          Successfully generate PSKc.
- * @retval OT_ERROR_INVALID_ARGS  If any of the input arguments is invalid.
- *
- */
-otError otCommissionerGeneratePskc(const char *           aPassPhrase,
-                                   const char *           aNetworkName,
-                                   const otExtendedPanId *aExtPanId,
-                                   otPskc *               aPskc);
-
-/**
  * @}
  *
  */
diff --git a/include/openthread/dataset.h b/include/openthread/dataset.h
index 35a4f15..344b7e7 100644
--- a/include/openthread/dataset.h
+++ b/include/openthread/dataset.h
@@ -99,23 +99,13 @@
  */
 typedef struct otExtendedPanId otExtendedPanId;
 
-#define OT_MESH_LOCAL_PREFIX_SIZE 8 ///< Size of the Mesh Local Prefix (bytes)
+#define OT_MESH_LOCAL_PREFIX_SIZE OT_IP6_PREFIX_SIZE ///< Size of the Mesh Local Prefix (bytes)
 
 /**
  * This structure represents a Mesh Local Prefix.
  *
  */
-OT_TOOL_PACKED_BEGIN
-struct otMeshLocalPrefix
-{
-    uint8_t m8[OT_MESH_LOCAL_PREFIX_SIZE]; ///< Byte values
-} OT_TOOL_PACKED_END;
-
-/**
- * This structure represents a Mesh Local Prefix.
- *
- */
-typedef struct otMeshLocalPrefix otMeshLocalPrefix;
+typedef otIp6NetworkPrefix otMeshLocalPrefix;
 
 #define OT_PSKC_MAX_SIZE 16 ///< Maximum size of the PSKc (bytes)
 
@@ -235,6 +225,24 @@
 } otOperationalDataset;
 
 /**
+ * Maximum length of Operational Dataset in bytes.
+ *
+ */
+#define OT_OPERATIONAL_DATASET_MAX_LENGTH 254
+
+/**
+ * This structure represents an Active or Pending Operational Dataset.
+ *
+ * The Operational Dataset is TLV encoded as specified by Thread.
+ *
+ */
+typedef struct otOperationalDatasetTlvs
+{
+    uint8_t mTlvs[OT_OPERATIONAL_DATASET_MAX_LENGTH]; ///< Operational Dataset TLVs.
+    uint8_t mLength;                                  ///< Size of Operational Dataset in bytes.
+} otOperationalDatasetTlvs;
+
+/**
  * This enumeration represents meshcop TLV types.
  *
  */
@@ -298,12 +306,24 @@
  * @param[out]  aDataset  A pointer to where the Active Operational Dataset will be placed.
  *
  * @retval OT_ERROR_NONE          Successfully retrieved the Active Operational Dataset.
- * @retval OT_ERROR_INVALID_ARGS  @p aDataset was NULL.
+ * @retval OT_ERROR_NOT_FOUND     No corresponding value in the setting store.
  *
  */
 otError otDatasetGetActive(otInstance *aInstance, otOperationalDataset *aDataset);
 
 /**
+ * This function gets the Active Operational Dataset.
+ *
+ * @param[in]   aInstance A pointer to an OpenThread instance.
+ * @param[out]  aDataset  A pointer to where the Active Operational Dataset will be placed.
+ *
+ * @retval OT_ERROR_NONE          Successfully retrieved the Active Operational Dataset.
+ * @retval OT_ERROR_NOT_FOUND     No corresponding value in the setting store.
+ *
+ */
+otError otDatasetGetActiveTlvs(otInstance *aInstance, otOperationalDatasetTlvs *aDataset);
+
+/**
  * This function sets the Active Operational Dataset.
  *
  * If the dataset does not include an Active Timestamp, the dataset is only partially complete.
@@ -322,39 +342,90 @@
  * @param[in]  aInstance A pointer to an OpenThread instance.
  * @param[in]  aDataset  A pointer to the Active Operational Dataset.
  *
- * @retval OT_ERROR_NONE          Successfully set the Active Operational Dataset.
- * @retval OT_ERROR_NO_BUFS       Insufficient buffer space to set the Active Operational Dataset.
- * @retval OT_ERROR_INVALID_ARGS  @p aDataset was NULL.
+ * @retval OT_ERROR_NONE             Successfully set the Active Operational Dataset.
+ * @retval OT_ERROR_NO_BUFS          Insufficient buffer space to set the Active Operational Dataset.
+ * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
  *
  */
 otError otDatasetSetActive(otInstance *aInstance, const otOperationalDataset *aDataset);
 
 /**
+ * This function sets the Active Operational Dataset.
+ *
+ * If the dataset does not include an Active Timestamp, the dataset is only partially complete.
+ *
+ * If Thread is enabled on a device that has a partially complete Active Dataset, the device will attempt to attach to
+ * an existing Thread network using any existing information in the dataset. Only the Thread Master Key is needed to
+ * attach to a network.
+ *
+ * If channel is not included in the dataset, the device will send MLE Announce messages across different channels to
+ * find neighbors on other channels.
+ *
+ * If the device successfully attaches to a Thread network, the device will then retrieve the full Active Dataset from
+ * its Parent. Note that a router-capable device will not transition to the Router or Leader roles until it has a
+ * complete Active Dataset.
+ *
+ * @param[in]  aInstance A pointer to an OpenThread instance.
+ * @param[in]  aDataset  A pointer to the Active Operational Dataset.
+ *
+ * @retval OT_ERROR_NONE             Successfully set the Active Operational Dataset.
+ * @retval OT_ERROR_NO_BUFS          Insufficient buffer space to set the Active Operational Dataset.
+ * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+ *
+ */
+otError otDatasetSetActiveTlvs(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset);
+
+/**
  * This function gets the Pending Operational Dataset.
  *
  * @param[in]   aInstance A pointer to an OpenThread instance.
  * @param[out]  aDataset  A pointer to where the Pending Operational Dataset will be placed.
  *
  * @retval OT_ERROR_NONE          Successfully retrieved the Pending Operational Dataset.
- * @retval OT_ERROR_INVALID_ARGS  @p aDataset was NULL.
+ * @retval OT_ERROR_NOT_FOUND     No corresponding value in the setting store.
  *
  */
 otError otDatasetGetPending(otInstance *aInstance, otOperationalDataset *aDataset);
 
 /**
+ * This function gets the Pending Operational Dataset.
+ *
+ * @param[in]   aInstance A pointer to an OpenThread instance.
+ * @param[out]  aDataset  A pointer to where the Pending Operational Dataset will be placed.
+ *
+ * @retval OT_ERROR_NONE          Successfully retrieved the Pending Operational Dataset.
+ * @retval OT_ERROR_NOT_FOUND     No corresponding value in the setting store.
+ *
+ */
+otError otDatasetGetPendingTlvs(otInstance *aInstance, otOperationalDatasetTlvs *aDataset);
+
+/**
  * This function sets the Pending Operational Dataset.
  *
  * @param[in]  aInstance A pointer to an OpenThread instance.
  * @param[in]  aDataset  A pointer to the Pending Operational Dataset.
  *
- * @retval OT_ERROR_NONE          Successfully set the Pending Operational Dataset.
- * @retval OT_ERROR_NO_BUFS       Insufficient buffer space to set the Pending Operational Dataset.
- * @retval OT_ERROR_INVALID_ARGS  @p aDataset was NULL.
+ * @retval OT_ERROR_NONE             Successfully set the Pending Operational Dataset.
+ * @retval OT_ERROR_NO_BUFS          Insufficient buffer space to set the Pending Operational Dataset.
+ * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
  *
  */
 otError otDatasetSetPending(otInstance *aInstance, const otOperationalDataset *aDataset);
 
 /**
+ * This function sets the Pending Operational Dataset.
+ *
+ * @param[in]  aInstance A pointer to an OpenThread instance.
+ * @param[in]  aDataset  A pointer to the Pending Operational Dataset.
+ *
+ * @retval OT_ERROR_NONE             Successfully set the Pending Operational Dataset.
+ * @retval OT_ERROR_NO_BUFS          Insufficient buffer space to set the Pending Operational Dataset.
+ * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+ *
+ */
+otError otDatasetSetPendingTlvs(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset);
+
+/**
  * This function sends MGMT_ACTIVE_GET.
  *
  * @param[in]  aInstance           A pointer to an OpenThread instance.
@@ -427,6 +498,25 @@
                                     uint8_t                     aLength);
 
 /**
+ * This function generates PSKc from a given pass-phrase, network name, and extended PAN ID.
+ *
+ * PSKc is used to establish the Commissioner Session.
+ *
+ * @param[in]  aPassPhrase   The commissioning pass-phrase.
+ * @param[in]  aNetworkName  The network name for PSKc computation.
+ * @param[in]  aExtPanId     The extended PAN ID for PSKc computation.
+ * @param[out] aPskc         A pointer to variable to output the generated PSKc.
+ *
+ * @retval OT_ERROR_NONE          Successfully generate PSKc.
+ * @retval OT_ERROR_INVALID_ARGS  If any of the input arguments is invalid.
+ *
+ */
+otError otDatasetGeneratePskc(const char *           aPassPhrase,
+                              const otNetworkName *  aNetworkName,
+                              const otExtendedPanId *aExtPanId,
+                              otPskc *               aPskc);
+
+/**
  * @}
  *
  */
diff --git a/include/openthread/diag.h b/include/openthread/diag.h
index f43d050..869400a 100644
--- a/include/openthread/diag.h
+++ b/include/openthread/diag.h
@@ -55,13 +55,21 @@
  * This function processes a factory diagnostics command line.
  *
  * @param[in]   aInstance       A pointer to an OpenThread instance.
- * @param[in]   aArgCount       The argument counter of diagnostics command line.
- * @param[in]   aArgVector      The argument vector of diagnostics command line.
+ * @param[in]   aArgsLength     The number of elements in @p aArgs.
+ * @param[in]   aArgs           An array of arguments.
  * @param[out]  aOutput         The diagnostics execution result.
  * @param[in]   aOutputMaxLen   The output buffer size.
  *
+ * @retval  OT_ERROR_INVALID_ARGS       The command is supported but invalid arguments provided.
+ * @retval  OT_ERROR_NONE               The command is successfully process.
+ * @retval  OT_ERROR_NOT_IMPLEMENTED    The command is not supported.
+ *
  */
-void otDiagProcessCmd(otInstance *aInstance, int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
+otError otDiagProcessCmd(otInstance *aInstance,
+                         uint8_t     aArgsLength,
+                         char *      aArgs[],
+                         char *      aOutput,
+                         size_t      aOutputMaxLen);
 
 /**
  * This function processes a factory diagnostics command line.
diff --git a/include/openthread/error.h b/include/openthread/error.h
index e1019a2..e571026 100644
--- a/include/openthread/error.h
+++ b/include/openthread/error.h
@@ -55,7 +55,7 @@
  * This enumeration represents error codes used throughout OpenThread.
  *
  */
-typedef enum otError
+typedef enum OT_MUST_USE_RESULT otError
 {
     /**
      * No error.
@@ -88,7 +88,7 @@
     OT_ERROR_BUSY = 5,
 
     /**
-     * Failed to parse message or arguments.
+     * Failed to parse message.
      */
     OT_ERROR_PARSE = 6,
 
@@ -224,6 +224,11 @@
     OT_ERROR_LINK_MARGIN_LOW = 34,
 
     /**
+     * Input (CLI) command is invalid.
+     */
+    OT_ERROR_INVALID_COMMAND = 35,
+
+    /**
      * The number of defined errors.
      */
     OT_NUM_ERRORS,
diff --git a/include/openthread/icmp6.h b/include/openthread/icmp6.h
index d249f20..ca8c624 100644
--- a/include/openthread/icmp6.h
+++ b/include/openthread/icmp6.h
@@ -58,11 +58,12 @@
  */
 typedef enum otIcmp6Type
 {
-    OT_ICMP6_TYPE_DST_UNREACH   = 1,   ///< Destination Unreachable
-    OT_ICMP6_TYPE_PACKET_TO_BIG = 2,   ///< Packet To Big
-    OT_ICMP6_TYPE_TIME_EXCEEDED = 3,   ///< Time Exceeded
-    OT_ICMP6_TYPE_ECHO_REQUEST  = 128, ///< Echo Request
-    OT_ICMP6_TYPE_ECHO_REPLY    = 129, ///< Echo Reply
+    OT_ICMP6_TYPE_DST_UNREACH       = 1,   ///< Destination Unreachable
+    OT_ICMP6_TYPE_PACKET_TO_BIG     = 2,   ///< Packet To Big
+    OT_ICMP6_TYPE_TIME_EXCEEDED     = 3,   ///< Time Exceeded
+    OT_ICMP6_TYPE_PARAMETER_PROBLEM = 4,   ///< Parameter Problem
+    OT_ICMP6_TYPE_ECHO_REQUEST      = 128, ///< Echo Request
+    OT_ICMP6_TYPE_ECHO_REPLY        = 129, ///< Echo Reply
 } otIcmp6Type;
 
 /**
diff --git a/include/openthread/instance.h b/include/openthread/instance.h
index 1657bf7..e144eed 100644
--- a/include/openthread/instance.h
+++ b/include/openthread/instance.h
@@ -46,6 +46,16 @@
 #endif
 
 /**
+ * The OpenThread API monotonic version number.
+ *
+ * This number MUST increase by one each time the contents of public OpenThread API include headers change.
+ *
+ * @note This number versions both OpenThread platform and user APIs.
+ *
+ */
+#define OPENTHREAD_API_VERSION (17)
+
+/**
  * @addtogroup api-instance
  *
  * @brief
@@ -122,31 +132,34 @@
  */
 enum
 {
-    OT_CHANGED_IP6_ADDRESS_ADDED           = 1 << 0,  ///< IPv6 address was added
-    OT_CHANGED_IP6_ADDRESS_REMOVED         = 1 << 1,  ///< IPv6 address was removed
-    OT_CHANGED_THREAD_ROLE                 = 1 << 2,  ///< Role (disabled, detached, child, router, leader) changed
-    OT_CHANGED_THREAD_LL_ADDR              = 1 << 3,  ///< The link-local address changed
-    OT_CHANGED_THREAD_ML_ADDR              = 1 << 4,  ///< The mesh-local address changed
-    OT_CHANGED_THREAD_RLOC_ADDED           = 1 << 5,  ///< RLOC was added
-    OT_CHANGED_THREAD_RLOC_REMOVED         = 1 << 6,  ///< RLOC was removed
-    OT_CHANGED_THREAD_PARTITION_ID         = 1 << 7,  ///< Partition ID changed
-    OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER = 1 << 8,  ///< Thread Key Sequence changed
-    OT_CHANGED_THREAD_NETDATA              = 1 << 9,  ///< Thread Network Data changed
-    OT_CHANGED_THREAD_CHILD_ADDED          = 1 << 10, ///< Child was added
-    OT_CHANGED_THREAD_CHILD_REMOVED        = 1 << 11, ///< Child was removed
-    OT_CHANGED_IP6_MULTICAST_SUBSCRIBED    = 1 << 12, ///< Subscribed to a IPv6 multicast address
-    OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED  = 1 << 13, ///< Unsubscribed from a IPv6 multicast address
-    OT_CHANGED_THREAD_CHANNEL              = 1 << 14, ///< Thread network channel changed
-    OT_CHANGED_THREAD_PANID                = 1 << 15, ///< Thread network PAN Id changed
-    OT_CHANGED_THREAD_NETWORK_NAME         = 1 << 16, ///< Thread network name changed
-    OT_CHANGED_THREAD_EXT_PANID            = 1 << 17, ///< Thread network extended PAN ID changed
-    OT_CHANGED_MASTER_KEY                  = 1 << 18, ///< Master key changed
-    OT_CHANGED_PSKC                        = 1 << 19, ///< PSKc changed
-    OT_CHANGED_SECURITY_POLICY             = 1 << 20, ///< Security Policy changed
-    OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL = 1 << 21, ///< Channel Manager new pending Thread channel changed
-    OT_CHANGED_SUPPORTED_CHANNEL_MASK      = 1 << 22, ///< Supported channel mask changed
-    OT_CHANGED_BORDER_AGENT_STATE          = 1 << 23, ///< Border agent state changed
-    OT_CHANGED_THREAD_NETIF_STATE          = 1 << 24, ///< Thread network interface state changed
+    OT_CHANGED_IP6_ADDRESS_ADDED            = 1 << 0,  ///< IPv6 address was added
+    OT_CHANGED_IP6_ADDRESS_REMOVED          = 1 << 1,  ///< IPv6 address was removed
+    OT_CHANGED_THREAD_ROLE                  = 1 << 2,  ///< Role (disabled, detached, child, router, leader) changed
+    OT_CHANGED_THREAD_LL_ADDR               = 1 << 3,  ///< The link-local address changed
+    OT_CHANGED_THREAD_ML_ADDR               = 1 << 4,  ///< The mesh-local address changed
+    OT_CHANGED_THREAD_RLOC_ADDED            = 1 << 5,  ///< RLOC was added
+    OT_CHANGED_THREAD_RLOC_REMOVED          = 1 << 6,  ///< RLOC was removed
+    OT_CHANGED_THREAD_PARTITION_ID          = 1 << 7,  ///< Partition ID changed
+    OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER  = 1 << 8,  ///< Thread Key Sequence changed
+    OT_CHANGED_THREAD_NETDATA               = 1 << 9,  ///< Thread Network Data changed
+    OT_CHANGED_THREAD_CHILD_ADDED           = 1 << 10, ///< Child was added
+    OT_CHANGED_THREAD_CHILD_REMOVED         = 1 << 11, ///< Child was removed
+    OT_CHANGED_IP6_MULTICAST_SUBSCRIBED     = 1 << 12, ///< Subscribed to a IPv6 multicast address
+    OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED   = 1 << 13, ///< Unsubscribed from a IPv6 multicast address
+    OT_CHANGED_THREAD_CHANNEL               = 1 << 14, ///< Thread network channel changed
+    OT_CHANGED_THREAD_PANID                 = 1 << 15, ///< Thread network PAN Id changed
+    OT_CHANGED_THREAD_NETWORK_NAME          = 1 << 16, ///< Thread network name changed
+    OT_CHANGED_THREAD_EXT_PANID             = 1 << 17, ///< Thread network extended PAN ID changed
+    OT_CHANGED_MASTER_KEY                   = 1 << 18, ///< Master key changed
+    OT_CHANGED_PSKC                         = 1 << 19, ///< PSKc changed
+    OT_CHANGED_SECURITY_POLICY              = 1 << 20, ///< Security Policy changed
+    OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL  = 1 << 21, ///< Channel Manager new pending Thread channel changed
+    OT_CHANGED_SUPPORTED_CHANNEL_MASK       = 1 << 22, ///< Supported channel mask changed
+    OT_CHANGED_COMMISSIONER_STATE           = 1 << 23, ///< Commissioner state changed
+    OT_CHANGED_THREAD_NETIF_STATE           = 1 << 24, ///< Thread network interface state changed
+    OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE = 1 << 25, ///< Backbone Router state changed
+    OT_CHANGED_THREAD_BACKBONE_ROUTER_LOCAL = 1 << 26, ///< Local Backbone Router configuration changed
+    OT_CHANGED_JOINER_STATE                 = 1 << 27, ///< Joiner state changed
 };
 
 /**
diff --git a/include/openthread/ip6.h b/include/openthread/ip6.h
index d20d38f..e1f99c2 100644
--- a/include/openthread/ip6.h
+++ b/include/openthread/ip6.h
@@ -58,6 +58,66 @@
 #define OT_IP6_ADDRESS_SIZE 16                         ///< Size of an IPv6 address (bytes)
 
 /**
+ * @struct otIp6InterfaceIdentifier
+ *
+ * This structure represents the Interface Identifier of an IPv6 address.
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+struct otIp6InterfaceIdentifier
+{
+    union OT_TOOL_PACKED_FIELD
+    {
+        uint8_t  m8[OT_IP6_IID_SIZE];                     ///< 8-bit fields
+        uint16_t m16[OT_IP6_IID_SIZE / sizeof(uint16_t)]; ///< 16-bit fields
+        uint32_t m32[OT_IP6_IID_SIZE / sizeof(uint32_t)]; ///< 32-bit fields
+    } mFields;                                            ///< The Interface Identifier accessor fields
+} OT_TOOL_PACKED_END;
+
+/**
+ * This structure represents the Interface Identifier of an IPv6 address.
+ *
+ */
+typedef struct otIp6InterfaceIdentifier otIp6InterfaceIdentifier;
+
+/**
+ * @struct otIp6NetworkPrefix
+ *
+ * This structure represents the Network Prefix of an IPv6 address (most significant 64 bits of the address).
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+struct otIp6NetworkPrefix
+{
+    uint8_t m8[OT_IP6_PREFIX_SIZE]; ///< The Network Prefix.
+} OT_TOOL_PACKED_END;
+
+/**
+ * This structure represents the Network Prefix of an IPv6 address (most significant 64 bits of the address).
+ *
+ */
+typedef struct otIp6NetworkPrefix otIp6NetworkPrefix;
+
+/**
+ * @struct otIp6AddressComponents
+ *
+ * This structure represents the components of an IPv6 address.
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+struct otIp6AddressComponents
+{
+    otIp6NetworkPrefix       mNetworkPrefix; ///< The Network Prefix (most significant 64 bits of the address)
+    otIp6InterfaceIdentifier mIid;           ///< The Interface Identifier (least significant 64 bits of the address)
+} OT_TOOL_PACKED_END;
+
+/**
+ * This structure represents the components of an IPv6 address.
+ *
+ */
+typedef struct otIp6AddressComponents otIp6AddressComponents;
+
+/**
  * @struct otIp6Address
  *
  * This structure represents an IPv6 address.
@@ -68,10 +128,11 @@
 {
     union OT_TOOL_PACKED_FIELD
     {
-        uint8_t  m8[OT_IP6_ADDRESS_SIZE];                     ///< 8-bit fields
-        uint16_t m16[OT_IP6_ADDRESS_SIZE / sizeof(uint16_t)]; ///< 16-bit fields
-        uint32_t m32[OT_IP6_ADDRESS_SIZE / sizeof(uint32_t)]; ///< 32-bit fields
-    } mFields;                                                ///< IPv6 accessor fields
+        uint8_t                m8[OT_IP6_ADDRESS_SIZE];                     ///< 8-bit fields
+        uint16_t               m16[OT_IP6_ADDRESS_SIZE / sizeof(uint16_t)]; ///< 16-bit fields
+        uint32_t               m32[OT_IP6_ADDRESS_SIZE / sizeof(uint32_t)]; ///< 32-bit fields
+        otIp6AddressComponents mComponents;                                 ///< IPv6 address components
+    } mFields;                                                              ///< IPv6 accessor fields
 } OT_TOOL_PACKED_END;
 
 /**
@@ -88,7 +149,7 @@
 struct otIp6Prefix
 {
     otIp6Address mPrefix; ///< The IPv6 prefix.
-    uint8_t      mLength; ///< The IPv6 prefix length.
+    uint8_t      mLength; ///< The IPv6 prefix length (in bits).
 } OT_TOOL_PACKED_END;
 
 /**
@@ -98,13 +159,26 @@
 typedef struct otIp6Prefix otIp6Prefix;
 
 /**
+ * IPv6 Address origins
+ *
+ */
+enum
+{
+    OT_ADDRESS_ORIGIN_THREAD = 0, ///< Thread assigned address (ALOC, RLOC, MLEID, etc)
+    OT_ADDRESS_ORIGIN_SLAAC  = 1, ///< SLAAC assigned address
+    OT_ADDRESS_ORIGIN_DHCPV6 = 2, ///< DHCPv6 assigned address
+    OT_ADDRESS_ORIGIN_MANUAL = 3, ///< Manually assigned address
+};
+
+/**
  * This structure represents an IPv6 network interface unicast address.
  *
  */
 typedef struct otNetifAddress
 {
     otIp6Address           mAddress;                ///< The IPv6 unicast address.
-    uint8_t                mPrefixLength;           ///< The Prefix length.
+    uint8_t                mPrefixLength;           ///< The Prefix length (in bits).
+    uint8_t                mAddressOrigin;          ///< The IPv6 address origin.
     bool                   mPreferred : 1;          ///< TRUE if the address is preferred, FALSE otherwise.
     bool                   mValid : 1;              ///< TRUE if the address is valid, FALSE otherwise.
     bool                   mScopeOverrideValid : 1; ///< TRUE if the mScopeOverride value is valid, FALSE otherwise.
@@ -418,8 +492,9 @@
  * @param[in]  aInstance A pointer to an OpenThread instance.
  * @param[in]  aPort     The port value.
  *
- * @retval OT_ERROR_NONE     The port was successfully added to the allowed unsecure port list.
- * @retval OT_ERROR_NO_BUFS  The unsecure port list is full.
+ * @retval OT_ERROR_NONE         The port was successfully added to the allowed unsecure port list.
+ * @retval OT_ERROR_INVALID_ARGS The port is invalid (value 0 is reserved for internal use).
+ * @retval OT_ERROR_NO_BUFS      The unsecure port list is full.
  *
  */
 otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort);
@@ -434,8 +509,9 @@
  * @param[in]  aInstance A pointer to an OpenThread instance.
  * @param[in]  aPort     The port value.
  *
- * @retval OT_ERROR_NONE       The port was successfully removed from the allowed unsecure port list.
- * @retval OT_ERROR_NOT_FOUND  The port was not found in the unsecure port list.
+ * @retval OT_ERROR_NONE         The port was successfully removed from the allowed unsecure port list.
+ * @retval OT_ERROR_INVALID_ARGS The port is invalid (value 0 is reserved for internal use).
+ * @retval OT_ERROR_NOT_FOUND    The port was not found in the unsecure port list.
  *
  */
 otError otIp6RemoveUnsecurePort(otInstance *aInstance, uint16_t aPort);
diff --git a/include/openthread/joiner.h b/include/openthread/joiner.h
index 13162cf..15e35c2 100644
--- a/include/openthread/joiner.h
+++ b/include/openthread/joiner.h
@@ -69,6 +69,18 @@
     OT_JOINER_STATE_JOINED    = 5,
 } otJoinerState;
 
+#define OT_JOINER_MAX_DISCERNER_LENGTH 64 ///< Maximum length of a Joiner Discerner in bits.
+
+/**
+ * This structure represents a Joiner Discerner.
+ *
+ */
+typedef struct otJoinerDiscerner
+{
+    uint64_t mValue;  ///< Discerner value (the lowest `mLength` bits specify the discerner).
+    uint8_t  mLength; ///< Length (number of bits) - must be non-zero and at most `OT_JOINER_MAX_DISCERNER_LENGTH`.
+} otJoinerDiscerner;
+
 /**
  * This function pointer is called to notify the completion of a join operation.
  *
@@ -94,8 +106,10 @@
  * @param[in]  aCallback         A pointer to a function that is called when the join operation completes.
  * @param[in]  aContext          A pointer to application-specific context.
  *
- * @retval OT_ERROR_NONE              Successfully started the Commissioner role.
+ * @retval OT_ERROR_NONE              Successfully started the Joiner role.
+ * @retval OT_ERROR_BUSY              The previous attempt is still on-going.
  * @retval OT_ERROR_INVALID_ARGS      @p aPskd or @p aProvisioningUrl is invalid.
+ * @retval OT_ERROR_INVALID_STATE     The IPv6 stack is not enabled or Thread stack is fully enabled.
  *
  */
 otError otJoinerStart(otInstance *     aInstance,
@@ -132,16 +146,48 @@
 otJoinerState otJoinerGetState(otInstance *aInstance);
 
 /**
- * Get the Joiner ID.
+ * This method gets the Joiner ID.
  *
- * Joiner ID is the first 64 bits of the result of computing SHA-256 over factory-assigned
- * IEEE EUI-64, which is used as IEEE 802.15.4 Extended Address during commissioning process.
+ * If a Joiner Discerner is not set, Joiner ID is the first 64 bits of the result of computing SHA-256 over
+ * factory-assigned IEEE EUI-64. Otherwise the Joiner ID is calculated from the Joiner Discerner value.
+ *
+ * The Joiner ID is also used as the device's IEEE 802.15.4 Extended Address during commissioning process.
  *
  * @param[in]   aInstance  A pointer to the OpenThread instance.
- * @param[out]  aJoinerId  A pointer to where the Joiner ID is placed.
+ *
+ * @returns A pointer to the Joiner ID.
  *
  */
-void otJoinerGetId(otInstance *aInstance, otExtAddress *aJoinerId);
+const otExtAddress *otJoinerGetId(otInstance *aInstance);
+
+/**
+ * This method sets the Joiner Discerner.
+ *
+ * The Joiner Discerner is used to calculate the Joiner ID used during commissioning/joining process.
+ *
+ * By default (when a discerner is not provided or set to NULL), Joiner ID is derived as first 64 bits of the result
+ * of computing SHA-256 over factory-assigned IEEE EUI-64. Note that this is the main behavior expected by Thread
+ * specification.
+ *
+ * @param[in]   aInstance    A pointer to the OpenThread instance.
+ * @param[in]   aDiscerner   A pointer to a Joiner Discerner. If NULL clears any previously set discerner.
+ *
+ * @retval OT_ERROR_NONE           The Joiner Discerner updated successfully.
+ * @retval OT_ERROR_INVALID_ARGS   @p aDiscerner is not valid (specified length is not within valid range).
+ * @retval OT_ERROR_INVALID_STATE  There is an ongoing Joining process so Joiner Discerner could not be changed.
+ *
+ */
+otError otJoinerSetDiscerner(otInstance *aInstance, otJoinerDiscerner *aDiscerner);
+
+/**
+ * This method gets the Joiner Discerner.
+ *
+ * @param[in]   aInstance       A pointer to the OpenThread instance.
+ *
+ * @returns A pointer to Joiner Discerner or NULL if none is set.
+ *
+ */
+const otJoinerDiscerner *otJoinerGetDiscerner(otInstance *aInstance);
 
 /**
  * @}
diff --git a/include/openthread/link.h b/include/openthread/link.h
index 98fff20..4e6f7a9 100644
--- a/include/openthread/link.h
+++ b/include/openthread/link.h
@@ -113,23 +113,23 @@
      * Note that this counter is incremented for each MAC transmission request only by one,
      * regardless of the amount of CCA failures, CSMA-CA attempts, or retransmissions.
      *
-     * This incrementation rule applies to the following counters:
-     *   @p mTxUnicast
-     *   @p mTxBroadcast
-     *   @p mTxAckRequested
-     *   @p mTxNoAckRequested
-     *   @p mTxData
-     *   @p mTxDataPoll
-     *   @p mTxBeacon
-     *   @p mTxBeaconRequest
-     *   @p mTxOther
-     *   @p mTxErrAbort
-     *   @p mTxErrBusyChannel
+     * This increment rule applies to the following counters:
+     *   - @p mTxUnicast
+     *   - @p mTxBroadcast
+     *   - @p mTxAckRequested
+     *   - @p mTxNoAckRequested
+     *   - @p mTxData
+     *   - @p mTxDataPoll
+     *   - @p mTxBeacon
+     *   - @p mTxBeaconRequest
+     *   - @p mTxOther
+     *   - @p mTxErrAbort
+     *   - @p mTxErrBusyChannel
      *
      * The following equations are valid:
-     *     @p mTxTotal = @p mTxUnicast + @p mTxBroadcast
-     *     @p mTxTotal = @p mTxAckRequested + @p mTxNoAckRequested
-     *     @p mTxTotal = @p mTxData + @p mTxDataPoll + @p mTxBeacon + @p mTxBeaconRequest + @p mTxOther
+     *   - @p mTxTotal = @p mTxUnicast + @p mTxBroadcast
+     *   - @p mTxTotal = @p mTxAckRequested + @p mTxNoAckRequested
+     *   - @p mTxTotal = @p mTxData + @p mTxDataPoll + @p mTxBeacon + @p mTxBeaconRequest + @p mTxOther
      *
      */
     uint32_t mTxTotal;
@@ -191,7 +191,7 @@
     /**
      * The total number of unique other MAC frame transmission requests.
      *
-     * This counter is currently unused.
+     * This counter is currently used for counting out-of-band frames.
      *
      */
     uint32_t mTxOther;
@@ -203,15 +203,16 @@
      * triggered by lack of acknowledgement, CSMA/CA failure, or other type of transmission error.
      * The @p mTxRetry counter is incremented both for unicast and broadcast MAC frames.
      *
-     * Check the following configuration parameters to control the amount of retransmissions in the system:
-     *   @sa OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT
-     *   @sa OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_INDIRECT
-     *   @sa OPENTHREAD_CONFIG_MAC_TX_NUM_BCAST
-     *   @sa OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT
-     *   @sa OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_INDIRECT
+     * Modify the following configuration parameters to control the amount of retransmissions in the system:
+     *
+     * - OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT
+     * - OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_INDIRECT
+     * - OPENTHREAD_CONFIG_MAC_TX_NUM_BCAST
+     * - OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT
+     * - OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_INDIRECT
      *
      * Currently, this counter is invalid if the platform's radio driver capability includes
-     * @sa OT_RADIO_CAPS_TRANSMIT_RETRIES.
+     * @ref OT_RADIO_CAPS_TRANSMIT_RETRIES.
      *
      */
     uint32_t mTxRetry;
@@ -233,12 +234,12 @@
      *
      * The meaning of this counter can be different and it depends on the platform's radio driver capabilities.
      *
-     * If @sa OT_RADIO_CAPS_CSMA_BACKOFF is enabled, this counter represents the total number of full CSMA/CA
+     * If @ref OT_RADIO_CAPS_CSMA_BACKOFF is enabled, this counter represents the total number of full CSMA/CA
      * failed attempts and it is incremented by one also for each retransmission (in case of a CSMA/CA fail).
      *
-     * If @sa OT_RADIO_CAPS_TRANSMIT_RETRIES is enabled, this counter represents the total number of full CSMA/CA
-     * failed attempts and it is incremented by one for each individual data frame request (regardless of the amount of
-     * retransmissions).
+     * If @ref OT_RADIO_CAPS_TRANSMIT_RETRIES is enabled, this counter represents the total number of full CSMA/CA
+     * failed attempts and it is incremented by one for each individual data frame request (regardless of the
+     * amount of retransmissions).
      *
      */
     uint32_t mTxErrCca;
@@ -721,106 +722,59 @@
 /**
  * This function gets the address mode of MAC filter.
  *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
  * @param[in]  aInstance  A pointer to an OpenThread instance.
  *
  * @returns  the address mode.
  *
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterClearRssIn
- * @sa otLinkFilterGetNextRssIn
- *
  */
 otMacFilterAddressMode otLinkFilterGetAddressMode(otInstance *aInstance);
 
 /**
  * This function sets the address mode of MAC filter.
  *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
  * @param[in]  aInstance  A pointer to an OpenThread instance.
  * @param[in]  aMode      The address mode to set.
  *
- * @retval OT_ERROR_NONE           Successfully set the address mode.
- * @retval OT_ERROR_INVALID_ARGS   @p aMode is not valid.
- *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterClearRssIn
- * @sa otLinkFilterGetNextRssIn
- *
  */
-otError otLinkFilterSetAddressMode(otInstance *aInstance, otMacFilterAddressMode aMode);
+void otLinkFilterSetAddressMode(otInstance *aInstance, otMacFilterAddressMode aMode);
 
 /**
  * This method adds an Extended Address to MAC filter.
  *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
  * @param[in]  aInstance    A pointer to an OpenThread instance.
- * @param[in]  aExtAddress  A reference to the Extended Address.
+ * @param[in]  aExtAddress  A pointer to the Extended Address (MUST NOT be NULL).
  *
  * @retval OT_ERROR_NONE           Successfully added @p aExtAddress to MAC filter.
- * @retval OT_ERROR_ALREADY        If @p aExtAddress was already in MAC filter.
- * @retval OT_ERROR_INVALID_ARGS   If @p aExtAddress is NULL.
  * @retval OT_ERROR_NO_BUFS        No available entry exists.
  *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterClearRssIn
- * @sa otLinkFilterGetNextRssIn
- *
  */
 otError otLinkFilterAddAddress(otInstance *aInstance, const otExtAddress *aExtAddress);
 
 /**
  * This method removes an Extended Address from MAC filter.
  *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
+ * No action is performed if there is no existing entry in Filter matching the given Extended Address.
+ *
  * @param[in]  aInstance    A pointer to an OpenThread instance.
- * @param[in]  aExtAddress  A reference to the Extended Address.
- *
- * @retval OT_ERROR_NONE           Successfully removed @p aExtAddress from MAC filter.
- * @retval OT_ERROR_INVALID_ARGS   If @p aExtAddress is NULL.
- * @retval OT_ERROR_NOT_FOUND      @p aExtAddress is not in MAC filter.
- *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterClearRssIn
- * @sa otLinkFilterGetNextRssIn
+ * @param[in]  aExtAddress  A pointer to the Extended Address (MUST NOT be NULL).
  *
  */
-otError otLinkFilterRemoveAddress(otInstance *aInstance, const otExtAddress *aExtAddress);
+void otLinkFilterRemoveAddress(otInstance *aInstance, const otExtAddress *aExtAddress);
 
 /**
  * This method clears all the Extended Addresses from MAC filter.
  *
- * @param[in]  aInstance  A pointer to an OpenThread instance.
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
  *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterClearRssIn
- * @sa otLinkFilterGetNextRssIn
+ * @param[in]  aInstance  A pointer to an OpenThread instance.
  *
  */
 void otLinkFilterClearAddresses(otInstance *aInstance);
@@ -828,120 +782,97 @@
 /**
  * This method gets an in-use address filter entry.
  *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
  * @param[in]     aInstance  A pointer to an OpenThread instance.
  * @param[inout]  aIterator  A pointer to the MAC filter iterator context. To get the first in-use address filter entry,
- *                           it should be set to OT_MAC_FILTER_ITERATOR_INIT.
- * @param[out]    aEntry     A pointer to where the information is placed.
+ *                           it should be set to OT_MAC_FILTER_ITERATOR_INIT. MUST NOT be NULL.
+ * @param[out]    aEntry     A pointer to where the information is placed. MUST NOT be NULL.
  *
  * @retval OT_ERROR_NONE          Successfully retrieved an in-use address filter entry.
- * @retval OT_ERROR_INVALID_ARGS  If @p aIterator or @p aEntry is NULL.
  * @retval OT_ERROR_NOT_FOUND     No subsequent entry exists.
  *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterClearRssIn
- * @sa otLinkFilterGetNextRssIn
- *
  */
 otError otLinkFilterGetNextAddress(otInstance *aInstance, otMacFilterIterator *aIterator, otMacFilterEntry *aEntry);
 
 /**
- * This method sets the received signal strength (in dBm) for the messages from the Extended Address.
- * The default received signal strength for all received messages would be set if no Extended Address is specified.
+ * This method adds a fixed received signal strength (in dBm) entry for the messages from a given Extended Address in
+ * MAC Filter.
+ *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
  *
  * @param[in]  aInstance    A pointer to an OpenThread instance.
- * @param[in]  aExtAddress  A pointer to the IEEE 802.15.4 Extended Address, or NULL to set the default received signal
- *                          strength.
- * @param[in]  aRss         The received signal strength (in dBm) to set.
+ * @param[in]  aExtAddress  A pointer to the IEEE 802.15.4 Extended Address. MUST NOT be NULL.
+ * @param[in]  aRss         A received signal strength (in dBm).
  *
- * @retval OT_ERROR_NONE           Successfully set @p aRss for @p aExtAddress or set the default @p aRss for all
- *                                 received messages if @p aExtAddress is NULL.
+ * @retval OT_ERROR_NONE           Successfully added an entry for @p aExtAddress and @p aRss.
  * @retval OT_ERROR_NO_BUFS        No available entry exists.
  *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterClearRssIn
- * @sa otLinkFilterGetNextRssIn
- *
  */
 otError otLinkFilterAddRssIn(otInstance *aInstance, const otExtAddress *aExtAddress, int8_t aRss);
 
 /**
- * This method removes the received signal strength setting for the received messages from the Extended Address or
- * removes the default received signal strength setting if no Extended Address is specified.
+ * This method removes a MAC Filter entry for fixed received signal strength setting for a given Extended Address.
+ *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
+ * No action is performed if there is no existing entry in Filter matching the given Extended Address.
  *
  * @param[in]  aInstance    A pointer to an OpenThread instance.
- * @param[in]  aExtAddress  A pointer to the IEEE 802.15.4 Extended Address, or NULL to reset the default received
- *                          signal strength.
- *
- * @retval OT_ERROR_NONE       Successfully removed received signal strength setting for @p aExtAddress or
- *                             removed the default received signal strength setting if @p aExtAddress is NULL.
- * @retval OT_ERROR_NOT_FOUND  @p aExtAddress is not in MAC filter if it is not NULL.
- *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterClearRssIn
- * @sa otLinkFilterGetNextRssIn
+ * @param[in]  aExtAddress  A pointer to the IEEE 802.15.4 Extended Address. MUST NOT be NULL.
  *
  */
-otError otLinkFilterRemoveRssIn(otInstance *aInstance, const otExtAddress *aExtAddress);
+void otLinkFilterRemoveRssIn(otInstance *aInstance, const otExtAddress *aExtAddress);
 
 /**
- * This method clears all the received signal strength settings.
+ * This method sets the default received signal strength (in dBm) on MAC Filter.
+ *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
+ * The default RSS value is used for all received frames from addresses for which there is no explicit RSS-IN entry
+ * in the Filter list (added using `otLinkFilterAddRssIn()`).
+ *
+ * @param[in]  aInstance    A pointer to an OpenThread instance.
+ * @param[in]  aRss         The default received signal strength (in dBm) to set.
+ *
+ */
+void otLinkFilterSetDefaultRssIn(otInstance *aInstance, int8_t aRss);
+
+/**
+ * This method clears any previously set default received signal strength (in dBm) on MAC Filter.
+ *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
+ * @param[in]  aInstance    A pointer to an OpenThread instance.
+ *
+ */
+void otLinkFilterClearDefaultRssIn(otInstance *aInstance);
+
+/**
+ * This method clears all the received signal strength entries (including default RSS-in) on MAC Filter.
+ *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
  *
  * @param[in]  aInstance A pointer to an OpenThread instance.
  *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterGetNextRssIn
- *
  */
-void otLinkFilterClearRssIn(otInstance *aInstance);
+void otLinkFilterClearAllRssIn(otInstance *aInstance);
 
 /**
  * This method gets an in-use RssIn filter entry.
  *
+ * This function is available when OPENTHREAD_CONFIG_MAC_FILTER_ENABLE configuration is enabled.
+ *
  * @param[in]     aInstance  A pointer to an OpenThread instance.
- * @param[inout]  aIterator  A reference to the MAC filter iterator context. To get the first in-use RssIn Filter entry,
- *                           it should be set to OT_MAC_FILTER_ITERATOR_INIT.
- * @param[out]    aEntry     A reference to where the information is placed. The last entry would have the extended
+ * @param[inout]  aIterator  A pointer to the MAC filter iterator context. MUST NOT be NULL.
+ *                           To get the first entry, it should be set to OT_MAC_FILTER_ITERATOR_INIT.
+ * @param[out]    aEntry     A pointer to where the information is placed. The last entry would have the extended
  *                           address as all 0xff to indicate the default received signal strength if it was set.
+                             @p aEntry MUST NOT be NULL.
  *
- * @retval OT_ERROR_NONE          Successfully retrieved an in-use RssIn Filter entry.
- * @retval OT_ERROR_INVALID_ARGS  If @p aIterator or @p aEntry is NULL.
+ * @retval OT_ERROR_NONE          Successfully retrieved the next entry.
  * @retval OT_ERROR_NOT_FOUND     No subsequent entry exists.
  *
- * @sa otLinkFilterGetAddressMode
- * @sa otLinkFilterSetAddressMode
- * @sa otLinkFilterAddAddress
- * @sa otLinkFilterRemoveAddress
- * @sa otLinkFilterClearAddresses
- * @sa otLinkFilterGetNextAddress
- * @sa otLinkFilterAddRssIn
- * @sa otLinkFilterRemoveRssIn
- * @sa otLinkFilterClearRssIn
- *
  */
 otError otLinkFilterGetNextRssIn(otInstance *aInstance, otMacFilterIterator *aIterator, otMacFilterEntry *aEntry);
 
diff --git a/include/openthread/link_raw.h b/include/openthread/link_raw.h
index 1983298..24626d2 100644
--- a/include/openthread/link_raw.h
+++ b/include/openthread/link_raw.h
@@ -52,16 +52,29 @@
  */
 
 /**
+ * This function pointer on receipt of a IEEE 802.15.4 frame.
+ *
+ * @param[in]  aInstance    A pointer to an OpenThread instance.
+ * @param[in]  aFrame       A pointer to the received frame or NULL if the receive operation was aborted.
+ * @param[in]  aError       OT_ERROR_NONE when successfully received a frame.
+ *                          OT_ERROR_ABORT when reception was aborted and a frame was not received.
+ *
+ */
+typedef void (*otLinkRawReceiveDone)(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
+
+/**
  * This function enables/disables the raw link-layer.
  *
  * @param[in] aInstance     A pointer to an OpenThread instance.
- * @param[in] aEnabled      TRUE to enable raw link-layer, FALSE otherwise.
+ * @param[in] aCallback     A pointer to a function called on receipt of a IEEE 802.15.4 frame. NULL to disable the
+ * raw-link layer.
  *
- * @retval OT_ERROR_NONE            If the enable state was successfully set.
+ * @retval OT_ERROR_FAILED          The radio could not be enabled/disabled.
  * @retval OT_ERROR_INVALID_STATE   If the OpenThread Ip6 interface is already enabled.
+ * @retval OT_ERROR_NONE            If the enable state was successfully set.
  *
  */
-otError otLinkRawSetEnable(otInstance *aInstance, bool aEnabled);
+otError otLinkRawSetReceiveDone(otInstance *aInstance, otLinkRawReceiveDone aCallback);
 
 /**
  * This function indicates whether or not the raw link-layer is enabled.
@@ -123,28 +136,16 @@
 otError otLinkRawSleep(otInstance *aInstance);
 
 /**
- * This function pointer on receipt of a IEEE 802.15.4 frame.
- *
- * @param[in]  aInstance    A pointer to an OpenThread instance.
- * @param[in]  aFrame       A pointer to the received frame or NULL if the receive operation was aborted.
- * @param[in]  aError       OT_ERROR_NONE when successfully received a frame.
- *                          OT_ERROR_ABORT when reception was aborted and a frame was not received.
- *
- */
-typedef void (*otLinkRawReceiveDone)(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
-
-/**
  * Transitioning the radio from Sleep to Receive.
  * Turn on the radio.
  *
  * @param[in]  aInstance    A pointer to an OpenThread instance.
- * @param[in]  aCallback    A pointer to a function called on receipt of a IEEE 802.15.4 frame.
  *
  * @retval OT_ERROR_NONE             Successfully transitioned to Receive.
  * @retval OT_ERROR_INVALID_STATE    The radio was disabled or transmitting.
  *
  */
-otError otLinkRawReceive(otInstance *aInstance, otLinkRawReceiveDone aCallback);
+otError otLinkRawReceive(otInstance *aInstance);
 
 /**
  * The radio transitions from Transmit to Receive.
@@ -331,6 +332,49 @@
 otError otLinkRawSrcMatchClearExtEntries(otInstance *aInstance);
 
 /**
+ * Update MAC keys and key index.
+ *
+ * @param[in]   aInstance    A pointer to an OpenThread instance.
+ * @param[in]   aKeyIdMode   The key ID mode.
+ * @param[in]   aKeyId       The key index.
+ * @param[in]   aPrevKey     The previous MAC key.
+ * @param[in]   aCurrKey     The current MAC key.
+ * @param[in]   aNextKey     The next MAC key.
+ *
+ * @retval OT_ERROR_NONE             If successful.
+ * @retval OT_ERROR_INVALID_STATE    If the raw link-layer isn't enabled.
+ *
+ */
+otError otLinkRawSetMacKey(otInstance *    aInstance,
+                           uint8_t         aKeyIdMode,
+                           uint8_t         aKeyId,
+                           const otMacKey *aPrevKey,
+                           const otMacKey *aCurrKey,
+                           const otMacKey *aNextKey);
+
+/**
+ * Sets the current MAC frame counter value.
+ *
+ * @param[in]   aInstance         A pointer to an OpenThread instance.
+ * @param[in]   aMacFrameCounter  The MAC frame counter value.
+ *
+ * @retval OT_ERROR_NONE             If successful.
+ * @retval OT_ERROR_INVALID_STATE    If the raw link-layer isn't enabled.
+ *
+ */
+otError otLinkRawSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter);
+
+/**
+ * Get current platform time (64bits width) of the radio chip.
+ *
+ * @param[in]  aInstance    A pointer to an OpenThread instance.
+ *
+ * @returns The current radio time in microseconds.
+ *
+ */
+uint64_t otLinkRawGetRadioTime(otInstance *aInstance);
+
+/**
  * @}
  *
  */
diff --git a/include/openthread/logging.h b/include/openthread/logging.h
index 1473a74..b406301 100644
--- a/include/openthread/logging.h
+++ b/include/openthread/logging.h
@@ -70,8 +70,11 @@
  *
  * @param[in]  aLogLevel               The log level.
  *
+ * @retval OT_ERROR_NONE            Successfully updated log level.
+ * @retval OT_ERROR_INVALID_ARGS    Log level value is invalid.
+ *
  */
-void otLoggingSetLevel(otLogLevel aLogLevel);
+otError otLoggingSetLevel(otLogLevel aLogLevel);
 
 /**
  * @}
diff --git a/include/openthread/message.h b/include/openthread/message.h
index b1766ae..ba35279 100644
--- a/include/openthread/message.h
+++ b/include/openthread/message.h
@@ -188,9 +188,6 @@
  * @param[in]  aMessage  A pointer to a message buffer.
  * @param[in]  aOffset   An offset in bytes.
  *
- * @retval OT_ERROR_NONE          Successfully set the message offset.
- * @retval OT_ERROR_INVALID_ARGS  The offset is beyond the message length.
- *
  * @sa otMessageFree
  * @sa otMessageAppend
  * @sa otMessageGetLength
@@ -200,7 +197,7 @@
  * @sa otMessageWrite
  *
  */
-otError otMessageSetOffset(otMessage *aMessage, uint16_t aOffset);
+void otMessageSetOffset(otMessage *aMessage, uint16_t aOffset);
 
 /**
  * This function indicates whether or not link security is enabled for the message.
@@ -321,11 +318,8 @@
  * @param[in]  aQueue    A pointer to the message queue.
  * @param[in]  aMessage  The message to add.
  *
- * @retval OT_ERROR_NONE     Successfully added the message to the queue.
- * @retval OT_ERROR_ALREADY  The message is already enqueued in a queue.
- *
  */
-otError otMessageQueueEnqueue(otMessageQueue *aQueue, otMessage *aMessage);
+void otMessageQueueEnqueue(otMessageQueue *aQueue, otMessage *aMessage);
 
 /**
  * This function adds a message at the head/front of the given message queue.
@@ -333,11 +327,8 @@
  * @param[in]  aQueue    A pointer to the message queue.
  * @param[in]  aMessage  The message to add.
  *
- * @retval OT_ERROR_NONE     Successfully added the message to the queue.
- * @retval OT_ERROR_ALREADY  The message is already enqueued in a queue.
- *
  */
-otError otMessageQueueEnqueueAtHead(otMessageQueue *aQueue, otMessage *aMessage);
+void otMessageQueueEnqueueAtHead(otMessageQueue *aQueue, otMessage *aMessage);
 
 /**
  * This function removes a message from the given message queue.
@@ -345,11 +336,8 @@
  * @param[in]  aQueue    A pointer to the message queue.
  * @param[in]  aMessage  The message to remove.
  *
- * @retval OT_ERROR_NONE       Successfully removed the message from the queue.
- * @retval OT_ERROR_NOT_FOUND  The message is not enqueued in this queue.
- *
  */
-otError otMessageQueueDequeue(otMessageQueue *aQueue, otMessage *aMessage);
+void otMessageQueueDequeue(otMessageQueue *aQueue, otMessage *aMessage);
 
 /**
  * This function returns a pointer to the message at the head of the queue.
diff --git a/include/openthread/netdata.h b/include/openthread/netdata.h
index d1eb81d..6e29bd5 100644
--- a/include/openthread/netdata.h
+++ b/include/openthread/netdata.h
@@ -65,7 +65,7 @@
     /**
      * A 2-bit signed integer indicating router preference as defined in RFC 4191.
      */
-    int mPreference : 2;
+    signed int mPreference : 2;
 
     /**
      * TRUE, if @p mPrefix is preferred.  FALSE, otherwise.
@@ -103,6 +103,18 @@
     bool mStable : 1;
 
     /**
+     * TRUE, if this border router is able to supply DNS infomration obtained via ND.  FALSE, otherwise.
+     */
+    bool mNdDns : 1;
+
+    /**
+     * TRUE, if this prefix is a Thread Domain Prefix.  FALSE, otherwise.
+     *
+     * Note: Domain Prefix is introduced since Thread 1.2.
+     */
+    bool mDp : 1;
+
+    /**
      * The Border Agent Rloc.
      */
     uint16_t mRloc16;
@@ -129,7 +141,7 @@
     /**
      * A 2-bit signed integer indicating router preference as defined in RFC 4191.
      */
-    int mPreference : 2;
+    signed int mPreference : 2;
 
     /**
      * TRUE, if this configuration is considered Stable Network Data.  FALSE, otherwise.
@@ -179,7 +191,7 @@
  */
 typedef struct otServiceConfig
 {
-    uint8_t        mServiceID;         ///< Used to return service ID when iterating over the partition's Network Data.
+    uint8_t        mServiceId;         ///< Used to return Service ID when iterating over the partition's Network Data.
     uint32_t       mEnterpriseNumber;  ///< IANA Enterprise Number.
     uint8_t        mServiceDataLength; ///< Length of service data.
     uint8_t        mServiceData[OT_SERVICE_DATA_MAX_SIZE]; ///< Service data bytes.
@@ -187,7 +199,7 @@
 } otServiceConfig;
 
 /**
- * This method provides a full or stable copy of the Parition's Thread Network Data.
+ * This method provides a full or stable copy of the Partition's Thread Network Data.
  *
  * @param[in]     aInstance    A pointer to an OpenThread instance.
  * @param[in]     aStable      TRUE when copying the stable version, FALSE when copying the full version.
diff --git a/include/openthread/netdiag.h b/include/openthread/netdiag.h
new file mode 100644
index 0000000..b35e95e
--- /dev/null
+++ b/include/openthread/netdiag.h
@@ -0,0 +1,350 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *  This file defines the OpenThread Network Diagnostic API.
+ */
+
+#ifndef OPENTHREAD_NETDIAG_H_
+#define OPENTHREAD_NETDIAG_H_
+
+#include <openthread/ip6.h>
+#include <openthread/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup api-thread-general
+ *
+ * @{
+ *
+ */
+
+/**
+ * Maximum Number of Network Diagnostic TLV Types to Request or Reset.
+ */
+#define OT_NETWORK_DIAGNOSTIC_TYPELIST_MAX_ENTRIES 19
+
+/**
+ * Size of Network Diagnostic Child Table entry.
+ */
+#define OT_NETWORK_DIAGNOSTIC_CHILD_TABLE_ENTRY_SIZE 3
+
+/**
+ * Initializer for otNetworkDiagIterator.
+ */
+#define OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT 0
+
+enum
+{
+    OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS       = 0,  ///< MAC Extended Address TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS     = 1,  ///< Address16 TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_MODE              = 2,  ///< Mode TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT           = 3,  ///< Timeout TLV (the maximum polling time period for SEDs)
+    OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY      = 4,  ///< Connectivity TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_ROUTE             = 5,  ///< Route64 TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA       = 6,  ///< Leader Data TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA      = 7,  ///< Network Data TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST     = 8,  ///< IPv6 Address List TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS      = 9,  ///< MAC Counters TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL     = 14, ///< Battery Level TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE    = 15, ///< Supply Voltage TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE       = 16, ///< Child Table TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES     = 17, ///< Channel Pages TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST         = 18, ///< Type List TLV
+    OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT = 19, ///< Max Child Timeout TLV
+};
+
+typedef uint16_t otNetworkDiagIterator; ///< Used to iterate through Network Diagnostic TLV.
+
+/**
+ * This structure represents a Network Diagnostic Connectivity value.
+ *
+ */
+typedef struct otNetworkDiagConnectivity
+{
+    /**
+     * The priority of the sender as a parent.
+     */
+    int8_t mParentPriority;
+
+    /**
+     * The number of neighboring devices with which the sender shares a link of quality 3.
+     */
+    uint8_t mLinkQuality3;
+
+    /**
+     * The number of neighboring devices with which the sender shares a link of quality 2.
+     */
+    uint8_t mLinkQuality2;
+
+    /**
+     * The number of neighboring devices with which the sender shares a link of quality 1.
+     */
+    uint8_t mLinkQuality1;
+
+    /**
+     * The sender's routing cost to the Leader.
+     */
+    uint8_t mLeaderCost;
+
+    /**
+     * The most recent ID sequence number received by the sender.
+     */
+    uint8_t mIdSequence;
+
+    /**
+     * The number of active Routers in the sender's Thread Network Partition.
+     */
+    uint8_t mActiveRouters;
+
+    /**
+     * The guaranteed buffer capacity in octets for all IPv6 datagrams destined to a given SED. Optional.
+     */
+    uint16_t mSedBufferSize;
+
+    /**
+     * The guaranteed queue capacity in number of IPv6 datagrams destined to a given SED. Optional.
+     */
+    uint8_t mSedDatagramCount;
+} otNetworkDiagConnectivity;
+
+/**
+ * This structure represents a Network Diagnostic Route data.
+ *
+ */
+typedef struct otNetworkDiagRouteData
+{
+    uint8_t mRouterId;           ///< The Assigned Router ID.
+    uint8_t mLinkQualityOut : 2; ///< Link Quality Out.
+    uint8_t mLinkQualityIn : 2;  ///< Link Quality In.
+    uint8_t mRouteCost : 4;      ///< Routing Cost. Infinite routing cost is represented by value 0.
+} otNetworkDiagRouteData;
+
+/**
+ * This structure represents a Network Diagnostic Route TLV value.
+ *
+ */
+typedef struct otNetworkDiagRoute
+{
+    /**
+     * The sequence number associated with the set of Router ID assignments in #mRouteData.
+     */
+    uint8_t mIdSequence;
+
+    /**
+     * Number of elements in #mRouteData.
+     */
+    uint8_t mRouteCount;
+
+    /**
+     * Link Quality and Routing Cost data.
+     */
+    otNetworkDiagRouteData mRouteData[OT_NETWORK_MAX_ROUTER_ID + 1];
+} otNetworkDiagRoute;
+
+/**
+ * This structure represents a Network Diagnostic Mac Counters value.
+ *
+ * See <a href="https://www.ietf.org/rfc/rfc2863">RFC 2863</a> for definitions of member fields.
+ *
+ */
+typedef struct otNetworkDiagMacCounters
+{
+    uint32_t mIfInUnknownProtos;
+    uint32_t mIfInErrors;
+    uint32_t mIfOutErrors;
+    uint32_t mIfInUcastPkts;
+    uint32_t mIfInBroadcastPkts;
+    uint32_t mIfInDiscards;
+    uint32_t mIfOutUcastPkts;
+    uint32_t mIfOutBroadcastPkts;
+    uint32_t mIfOutDiscards;
+} otNetworkDiagMacCounters;
+
+/**
+ * This structure represents a Network Diagnostic Child Table Entry.
+ *
+ */
+typedef struct otNetworkDiagChildEntry
+{
+    /**
+     * Expected poll time expressed as 2^(Timeout-4) seconds.
+     */
+    uint16_t mTimeout : 5;
+
+    /**
+     * Child ID from which an RLOC can be generated.
+     */
+    uint16_t mChildId : 9;
+
+    /**
+     * Link mode bits.
+     */
+    otLinkModeConfig mMode;
+} otNetworkDiagChildEntry;
+
+/**
+ * This structure represents a Network Diagnostic TLV.
+ *
+ */
+typedef struct otNetworkDiagTlv
+{
+    /**
+     * The Network Diagnostic TLV type.
+     */
+    uint8_t mType;
+
+    union
+    {
+        otExtAddress              mExtAddress;
+        uint16_t                  mAddr16;
+        otLinkModeConfig          mMode;
+        uint32_t                  mTimeout;
+        otNetworkDiagConnectivity mConnectivity;
+        otNetworkDiagRoute        mRoute;
+        otLeaderData              mLeaderData;
+        otNetworkDiagMacCounters  mMacCounters;
+        uint8_t                   mBatteryLevel;
+        uint16_t                  mSupplyVoltage;
+        uint32_t                  mMaxChildTimeout;
+        struct
+        {
+            uint8_t mCount;
+            uint8_t m8[OT_NETWORK_BASE_TLV_MAX_LENGTH];
+        } mNetworkData;
+        struct
+        {
+            uint8_t      mCount;
+            otIp6Address mList[OT_NETWORK_BASE_TLV_MAX_LENGTH / OT_IP6_ADDRESS_SIZE];
+        } mIp6AddrList;
+        struct
+        {
+            uint8_t mCount;
+            otNetworkDiagChildEntry
+                mTable[OT_NETWORK_BASE_TLV_MAX_LENGTH / OT_NETWORK_DIAGNOSTIC_CHILD_TABLE_ENTRY_SIZE];
+        } mChildTable;
+        struct
+        {
+            uint8_t mCount;
+            uint8_t m8[OT_NETWORK_BASE_TLV_MAX_LENGTH];
+        } mChannelPages;
+    } mData;
+} otNetworkDiagTlv;
+
+/**
+ * This function gets the next Network Diagnostic TLV in the message.
+ *
+ * @param[in]     aMessage         A pointer to a message.
+ * @param[inout]  aIterator        A pointer to the Network Diagnostic iterator context. To get the first
+ *                                 Network Diagnostic TLV it should be set to OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT.
+ * @param[out]    aNetworkDiagTlv  A pointer to where the Network Diagnostic TLV information will be placed.
+ *
+ * @retval OT_ERROR_NONE       Successfully found the next Network Diagnostic TLV.
+ * @retval OT_ERROR_NOT_FOUND  No subsequent Network Diagnostic TLV exists in the message.
+ * @retval OT_ERROR_PARSE      Parsing the next Network Diagnostic failed.
+ *
+ * @Note A subsequent call to this function is allowed only when current return value is OT_ERROR_NONE.
+ *
+ */
+otError otThreadGetNextDiagnosticTlv(const otMessage *      aMessage,
+                                     otNetworkDiagIterator *aIterator,
+                                     otNetworkDiagTlv *     aNetworkDiagTlv);
+
+/**
+ * This function pointer is called when Network Diagnostic Get response is received.
+ *
+ * @param[in]  aMessage      A pointer to the message buffer containing the received Network Diagnostic
+ *                           Get response payload.
+ * @param[in]  aMessageInfo  A pointer to the message info for @p aMessage.
+ * @param[in]  aContext      A pointer to application-specific context.
+ *
+ */
+typedef void (*otReceiveDiagnosticGetCallback)(otMessage *aMessage, const otMessageInfo *aMessageInfo, void *aContext);
+
+/**
+ * This function registers a callback to provide received raw Network Diagnostic Get response payload.
+ *
+ * @param[in]  aInstance         A pointer to an OpenThread instance.
+ * @param[in]  aCallback         A pointer to a function that is called when Network Diagnostic Get response
+ *                               is received or NULL to disable the callback.
+ * @param[in]  aCallbackContext  A pointer to application-specific context.
+ *
+ */
+void otThreadSetReceiveDiagnosticGetCallback(otInstance *                   aInstance,
+                                             otReceiveDiagnosticGetCallback aCallback,
+                                             void *                         aCallbackContext);
+
+/**
+ * Send a Network Diagnostic Get request.
+ *
+ * @param[in]  aInstance      A pointer to an OpenThread instance.
+ * @param[in]  aDestination   A pointer to destination address.
+ * @param[in]  aTlvTypes      An array of Network Diagnostic TLV types.
+ * @param[in]  aCount         Number of types in aTlvTypes.
+ *
+ * @retval OT_ERROR_NONE    Successfully queued the DIAG_GET.req.
+ * @retval OT_ERROR_NO_BUFS Insufficient message buffers available to send DIAG_GET.req.
+ *
+ */
+otError otThreadSendDiagnosticGet(otInstance *        aInstance,
+                                  const otIp6Address *aDestination,
+                                  const uint8_t       aTlvTypes[],
+                                  uint8_t             aCount);
+
+/**
+ * Send a Network Diagnostic Reset request.
+ *
+ * @param[in]  aInstance      A pointer to an OpenThread instance.
+ * @param[in]  aDestination   A pointer to destination address.
+ * @param[in]  aTlvTypes      An array of Network Diagnostic TLV types. Currently only Type 9 is allowed.
+ * @param[in]  aCount         Number of types in aTlvTypes
+ *
+ * @retval OT_ERROR_NONE    Successfully queued the DIAG_RST.ntf.
+ * @retval OT_ERROR_NO_BUFS Insufficient message buffers available to send DIAG_RST.ntf.
+ *
+ */
+otError otThreadSendDiagnosticReset(otInstance *        aInstance,
+                                    const otIp6Address *aDestination,
+                                    const uint8_t       aTlvTypes[],
+                                    uint8_t             aCount);
+
+/**
+ * @}
+ *
+ */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // OPENTHREAD_NETDIAG_H_
diff --git a/include/openthread/platform/Makefile.am b/include/openthread/platform/Makefile.am
index 4500796..3441ae4 100644
--- a/include/openthread/platform/Makefile.am
+++ b/include/openthread/platform/Makefile.am
@@ -33,10 +33,12 @@
     alarm-milli.h                         \
     ble.h                                 \
     diag.h                                \
+    flash.h                               \
     entropy.h                             \
     memory.h                              \
     misc.h                                \
     logging.h                             \
+    otns.h                                \
     radio.h                               \
     time.h                                \
     uart.h                                \
diff --git a/include/openthread/platform/debug_uart.h b/include/openthread/platform/debug_uart.h
index 9a4f864..b0410af 100644
--- a/include/openthread/platform/debug_uart.h
+++ b/include/openthread/platform/debug_uart.h
@@ -173,7 +173,7 @@
 void otPlatDebugUart_puts_no_nl(const char *s);
 
 /**
- * Some platforms (posix) can log to a file.
+ * Some platforms (simulation) can log to a file.
  *
  * @returns OT_ERROR_NONE
  * @returns OT_ERROR_FAILED
diff --git a/include/openthread/platform/diag.h b/include/openthread/platform/diag.h
index 5413725..d8dcc9d 100644
--- a/include/openthread/platform/diag.h
+++ b/include/openthread/platform/diag.h
@@ -60,13 +60,21 @@
  * This function processes a factory diagnostics command line.
  *
  * @param[in]   aInstance       The OpenThread instance for current request.
- * @param[in]   argc            The argument counter of diagnostics command line.
- * @param[in]   argv            The argument vector of diagnostics command line.
+ * @param[in]   aArgsLength     The number of arguments in @p aArgs.
+ * @param[in]   aArgs           The arguments of diagnostics command line.
  * @param[out]  aOutput         The diagnostics execution result.
  * @param[in]   aOutputMaxLen   The output buffer size.
  *
+ * @retval  OT_ERROR_INVALID_ARGS       The command is supported but invalid arguments provided.
+ * @retval  OT_ERROR_NONE               The command is successfully process.
+ * @retval  OT_ERROR_INVALID_COMMAND    The command is not valid or not supported.
+ *
  */
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
+otError otPlatDiagProcess(otInstance *aInstance,
+                          uint8_t     aArgsLength,
+                          char *      aArgs[],
+                          char *      aOutput,
+                          size_t      aOutputMaxLen);
 
 /**
  * This function enables/disables the factory diagnostics mode.
diff --git a/include/openthread/platform/flash.h b/include/openthread/platform/flash.h
new file mode 100644
index 0000000..bbb7f3e
--- /dev/null
+++ b/include/openthread/platform/flash.h
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OPENTHREAD_PLATFORM_FLASH_H_
+#define OPENTHREAD_PLATFORM_FLASH_H_
+
+#include <stdint.h>
+
+#include <openthread/instance.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This function initializes the flash driver.
+ *
+ * @param[in] aInstance  The OpenThread instance structure.
+ *
+ */
+void otPlatFlashInit(otInstance *aInstance);
+
+/**
+ * This function gets the size of the swap space.
+ *
+ * @param[in] aInstance  The OpenThread instance structure.
+ *
+ * @returns The size of the swap space in bytes.
+ *
+ */
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance);
+
+/**
+ * This function erases the swap space indicated by @p aSwapIndex.
+ *
+ * @param[in] aInstance   The OpenThread instance structure.
+ * @param[in] aSwapIndex  A value in [0, 1] that indicates the swap space.
+ *
+ */
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex);
+
+/**
+ * This function reads @p aSize bytes into @p aData.
+ *
+ * @param[in]  aInstance   The OpenThread instance structure.
+ * @param[in]  aSwapIndex  A value in [0, 1] that indicates the swap space.
+ * @param[in]  aOffset     A byte offset within the swap space.
+ * @param[out] aData       A pointer to the data buffer for reading.
+ * @param[in]  aSize       Number of bytes to read.
+ *
+ */
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize);
+
+/**
+ * This function writes @p aSize bytes from @p aData.
+ *
+ * @param[in]  aInstance   The OpenThread instance structure.
+ * @param[in]  aSwapIndex  A value in [0, 1] that indicates the swap space.
+ * @param[in]  aOffset     A byte offset within the swap space.
+ * @param[out] aData       A pointer to the data to write.
+ * @param[in]  aSize       Number of bytes to write.
+ *
+ *
+ */
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // OPENTHREAD_PLATFORM_FLASH_H_
diff --git a/include/openthread/platform/logging.h b/include/openthread/platform/logging.h
index 68687ed..df40aee 100644
--- a/include/openthread/platform/logging.h
+++ b/include/openthread/platform/logging.h
@@ -134,6 +134,8 @@
     OT_LOG_REGION_CLI      = 14, ///< CLI
     OT_LOG_REGION_CORE     = 15, ///< OpenThread Core
     OT_LOG_REGION_UTIL     = 16, ///< Utility module
+    OT_LOG_REGION_BBR      = 17, ///< Backbone Router (available since Thread 1.2)
+    OT_LOG_REGION_MLR      = 18, ///< Multicast Listener Registration (available since Thread 1.2)
 } otLogRegion;
 
 /**
diff --git a/include/openthread/platform/misc.h b/include/openthread/platform/misc.h
index 99c3ed3..a5d5e44 100644
--- a/include/openthread/platform/misc.h
+++ b/include/openthread/platform/misc.h
@@ -198,6 +198,21 @@
  *
  */
 
+#if defined(OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE) && OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+/**
+ * This function gets the name and index of the platform's network interface (if it exists).
+ *
+ * @param[in]  aInstance      A pointer to OpenThread instance.
+ * @param[out] outNetIfName   A pointer for the returned network interface name.
+ * @param[out] outNetIfIndex  A pointer for the returned network interface index (i.e., if_nametoindex).
+ *
+ * @retval OT_ERROR_NONE     Successfully returned the network interface and index.
+ * @retval OT_ERROR_FAILED   The network interface is not enabled or is unknown.
+ *
+ */
+otError otPlatGetNetif(otInstance *aInstance, const char **outNetIfName, unsigned int *outNetIfIndex);
+#endif
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/include/openthread/platform/otns.h b/include/openthread/platform/otns.h
new file mode 100644
index 0000000..6d862e2
--- /dev/null
+++ b/include/openthread/platform/otns.h
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *   This file includes the abstraction for the platform OTNS utilities.
+ *
+ *   OTNS is an OpenThread Network Simulator that simulates Thread networks using OpenThread simulation instances and
+ *   provides visualization and management of those simulated networks.
+ *   Refer to https://github.com/openthread/ot-ns for more information about OTNS.
+ */
+
+#ifndef OPENTHREAD_PLATFORM_OTNS_H_
+#define OPENTHREAD_PLATFORM_OTNS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup plat-otns
+ *
+ * @brief
+ *   This module includes the platform abstraction for OTNS.
+ *
+ * @{
+ *
+ */
+
+/**
+ * This function exports status information to OTNS.
+ *
+ * The status information is represented by a null-terminated string with format recognizable by OTNS.
+ * Each call to `otPlatOtnsStatus` can send multiple statuses, separated by ';', e.x. "parid=577fbc37;lrid=5".
+ * Each status contains key and value separated by '='.
+ * Status value can be further separated into multiple fields using ',',
+ * e.x. "ping_request=fdde:ad00:beef:0:459e:d7b4:b65e:5480,4,112000".
+ *
+ * New statuses should follow these conventions.
+ *
+ * Currently, OTNS only supports virtual time simulation.
+ *
+ * @param[in]  aStatus  The status string.
+ *
+ */
+void otPlatOtnsStatus(const char *aStatus);
+
+/**
+ * @}
+ *
+ */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // OPENTHREAD_PLATFORM_OTNS_H_
diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h
index f5c74c7..23a5a5d 100644
--- a/include/openthread/platform/radio.h
+++ b/include/openthread/platform/radio.h
@@ -123,6 +123,8 @@
     OT_RADIO_CAPS_ENERGY_SCAN      = 1 << 1, ///< Radio supports Energy Scans.
     OT_RADIO_CAPS_TRANSMIT_RETRIES = 1 << 2, ///< Radio supports tx retry logic with collision avoidance (CSMA).
     OT_RADIO_CAPS_CSMA_BACKOFF     = 1 << 3, ///< Radio supports CSMA backoff for frame transmission (but no retry).
+    OT_RADIO_CAPS_SLEEP_TO_TX      = 1 << 4, ///< Radio supports direct transition from sleep to TX with CSMA.
+    OT_RADIO_CAPS_TRANSMIT_SEC     = 1 << 5, ///< Radio supports tx security.
 };
 
 #define OT_PANID_BROADCAST 0xffff ///< IEEE 802.15.4 Broadcast PAN ID
@@ -159,6 +161,26 @@
  */
 typedef struct otExtAddress otExtAddress;
 
+#define OT_MAC_KEY_SIZE 16 ///< Size of the MAC Key in bytes.
+
+/**
+ * @struct otMacKey
+ *
+ * This structure represents a MAC Key.
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+struct otMacKey
+{
+    uint8_t m8[OT_MAC_KEY_SIZE]; ///< MAC Key bytes.
+} OT_TOOL_PACKED_END;
+
+/**
+ * This structure represents a MAC Key.
+ *
+ */
+typedef struct otMacKey otMacKey;
+
 /**
  * This structure represents the IEEE 802.15.4 Header IE (Information Element) related information of a radio frame.
  */
@@ -189,12 +211,13 @@
          */
         struct
         {
-            const uint8_t *mAesKey;            ///< The key used for AES-CCM frame security.
-            otRadioIeInfo *mIeInfo;            ///< The pointer to the Header IE(s) related information.
-            uint8_t        mMaxCsmaBackoffs;   ///< Maximum number of backoffs attempts before declaring CCA failure.
-            uint8_t        mMaxFrameRetries;   ///< Maximum number of retries allowed after a transmission failure.
-            bool           mIsARetx : 1;       ///< True if this frame is a retransmission (ignored by radio driver).
-            bool           mCsmaCaEnabled : 1; ///< Set to true to enable CSMA-CA for this packet, false otherwise.
+            const otMacKey *mAesKey;            ///< The key used for AES-CCM frame security.
+            otRadioIeInfo * mIeInfo;            ///< The pointer to the Header IE(s) related information.
+            uint8_t         mMaxCsmaBackoffs;   ///< Maximum number of backoffs attempts before declaring CCA failure.
+            uint8_t         mMaxFrameRetries;   ///< Maximum number of retries allowed after a transmission failure.
+            bool            mIsARetx : 1;       ///< True if this frame is a retransmission (ignored by radio driver).
+            bool            mCsmaCaEnabled : 1; ///< Set to true to enable CSMA-CA for this packet, false otherwise.
+            bool            mIsSecurityProcessed : 1; ///< True if SubMac should skip the AES processing of this frame.
         } mTxInfo;
 
         /**
@@ -211,11 +234,14 @@
              */
             uint64_t mTimestamp;
 
-            int8_t  mRssi; ///< Received signal strength indicator in dBm for received frames.
-            uint8_t mLqi;  ///< Link Quality Indicator for received frames.
+            uint32_t mAckFrameCounter; ///< ACK security frame counter (applicable when `mAckedWithSecEnhAck` is set).
+            uint8_t  mAckKeyId;        ///< ACK security key index (applicable when `mAckedWithSecEnhAck` is set).
+            int8_t   mRssi;            ///< Received signal strength indicator in dBm for received frames.
+            uint8_t  mLqi;             ///< Link Quality Indicator for received frames.
 
             // Flags
-            bool mAckedWithFramePending : 1; /// This indicates if this frame was acknowledged with frame pending set.
+            bool mAckedWithFramePending : 1; ///< This indicates if this frame was acknowledged with frame pending set.
+            bool mAckedWithSecEnhAck : 1; ///< This indicates if this frame was acknowledged with secured enhance ACK.
         } mRxInfo;
     } mInfo;
 } otRadioFrame;
@@ -244,6 +270,10 @@
  *  +----------+  Disable() +-------+   Sleep()  +---------+   Receive()   +----------+
  *                                    (Radio OFF)                 or
  *                                                        signal TransmitDone
+ *
+ * During the IEEE 802.15.4 data request command the transition Sleep->Receive->Transmit
+ * can be shortened to direct transition from Sleep to Transmit if the platform supports
+ * the OT_RADIO_CAPS_SLEEP_TO_TX capability.
  */
 
 /**
@@ -429,6 +459,47 @@
 void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable);
 
 /**
+ * Update MAC keys and key index
+ *
+ * This function is used when radio provides OT_RADIO_CAPS_TRANSMIT_SEC capability.
+ *
+ * @param[in]   aInstance    A pointer to an OpenThread instance.
+ * @param[in]   aKeyIdMode   The key ID mode.
+ * @param[in]   aKeyId       Current MAC key index.
+ * @param[in]   aPrevKey     A pointer to the previous MAC key.
+ * @param[in]   aCurrKey     A pointer to the current MAC key.
+ * @param[in]   aNextKey     A pointer to the next MAC key.
+ *
+ */
+void otPlatRadioSetMacKey(otInstance *    aInstance,
+                          uint8_t         aKeyIdMode,
+                          uint8_t         aKeyId,
+                          const otMacKey *aPrevKey,
+                          const otMacKey *aCurrKey,
+                          const otMacKey *aNextKey);
+
+/**
+ * This method sets the current MAC frame counter value.
+ *
+ * This function is used when radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability.
+ *
+ * @param[in]   aInstance         A pointer to an OpenThread instance.
+ * @param[in]   aMacFrameCounter  The MAC frame counter value.
+ *
+ */
+void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter);
+
+/**
+ * Get the current estimated time (64bits width) of the radio chip.
+ *
+ * @param[in]   aInstance    A pointer to an OpenThread instance.
+ *
+ * @returns The current time in microseconds. UINT64_MAX when platform does not support or radio time is not ready.
+ *
+ */
+uint64_t otPlatRadioGetNow(otInstance *aInstance);
+
+/**
  * @}
  *
  */
@@ -558,7 +629,9 @@
  * requesting transmission.  The channel and transmit power are also included in the otRadioFrame structure.
  *
  * The transmit sequence consists of:
- * 1. Transitioning the radio to Transmit from Receive.
+ * 1. Transitioning the radio to Transmit from one of the following states:
+ *    - Receive if RX is on when the device is idle or OT_RADIO_CAPS_SLEEP_TO_TX is not supported
+ *    - Sleep if RX is off when the device is idle and OT_RADIO_CAPS_SLEEP_TO_TX is supported.
  * 2. Transmits the psdu on the given channel and at the given transmit power.
  *
  * @param[in] aInstance  The OpenThread instance structure.
@@ -586,6 +659,9 @@
  * The radio driver calls this function to notify OpenThread that the transmit operation has completed,
  * providing both the transmitted frame and, if applicable, the received ack frame.
  *
+ * When radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability, radio platform layer updates @p aFrame
+ * with the security frame counter and key index values maintained by the radio.
+ *
  * @param[in]  aInstance  The OpenThread instance structure.
  * @param[in]  aFrame     A pointer to the frame that was transmitted.
  * @param[in]  aAckFrame  A pointer to the ACK frame, NULL if no ACK was received.
diff --git a/include/openthread/platform/toolchain.h b/include/openthread/platform/toolchain.h
index 7eea6a6..c1f3a00 100644
--- a/include/openthread/platform/toolchain.h
+++ b/include/openthread/platform/toolchain.h
@@ -64,6 +64,24 @@
 #endif
 
 /**
+ * @def OT_MUST_USE_RESULT
+ *
+ * Compiler-specific indication that a class or enum must be used when it is
+ * the return value of a function.
+ *
+ * @note This is currently only available with clang (C++17 implements it
+ *       as attribute [[nodiscard]]).
+ * @note To suppress the 'unused-result' warning/error, please use the
+ *       '-Wno-unused-result' compiler option.
+ *
+ */
+#if defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 9))
+#define OT_MUST_USE_RESULT __attribute__((warn_unused_result))
+#else
+#define OT_MUST_USE_RESULT
+#endif
+
+/**
  * @def OT_TOOL_PACKED_BEGIN
  *
  * Compiler-specific indication that a class or struct must be byte packed.
@@ -231,6 +249,14 @@
 #endif
 #endif
 
+#ifdef __APPLE__
+#define OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(...)                                               \
+    _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wgnu-folding-constant\"") \
+        __VA_ARGS__ _Pragma("GCC diagnostic pop")
+#else
+#define OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(...) __VA_ARGS__
+#endif
+
 /**
  * @}
  *
diff --git a/include/openthread/thread.h b/include/openthread/thread.h
index 396d022..bcd4570 100644
--- a/include/openthread/thread.h
+++ b/include/openthread/thread.h
@@ -54,9 +54,11 @@
  */
 
 /**
- * Maximum Number of Network Diagnostic TLV Types to Request or Reset.
+ * Maximum value length of Thread Base TLV.
  */
-#define OT_NETWORK_DIAGNOSTIC_TYPELIST_MAX_ENTRIES 19
+#define OT_NETWORK_BASE_TLV_MAX_LENGTH 254
+
+#define OT_NETWORK_MAX_ROUTER_ID 62 ///< Maximum Router ID
 
 /**
  * Represents a Thread device role.
@@ -473,6 +475,66 @@
 otError otThreadSetNetworkName(otInstance *aInstance, const char *aNetworkName);
 
 /**
+ * Get the Thread Domain Name.
+ *
+ * This function is only available since Thread 1.2.
+ *
+ * @param[in]  aInstance A pointer to an OpenThread instance.
+ *
+ * @returns A pointer to the Thread Domain Name.
+ *
+ * @sa otThreadSetDomainName
+ *
+ */
+const char *otThreadGetDomainName(otInstance *aInstance);
+
+/**
+ * Set the Thread Domain Name.
+ *
+ * This function is only available since Thread 1.2.
+ * This function succeeds only when Thread protocols are disabled.
+ *
+ * @param[in]  aInstance     A pointer to an OpenThread instance.
+ * @param[in]  aDomainName   A pointer to the Thread Domain Name.
+ *
+ * @retval OT_ERROR_NONE           Successfully set the Thread Domain Name.
+ * @retval OT_ERROR_INVALID_STATE  Thread protocols are enabled.
+ *
+ * @sa otThreadGetDomainName
+ *
+ */
+otError otThreadSetDomainName(otInstance *aInstance, const char *aDomainName);
+
+/**
+ * Set/Clear the Interface Identifier manually specified for the Thread Domain Unicast Address.
+ *
+ * This function is only available since Thread 1.2 when `OPENTHREAD_CONFIG_DUA_ENABLE` is enabled.
+ *
+ * @param[in]  aInstance   A pointer to an OpenThread instance.
+ * @param[in]  aIid        A pointer to the Interface Identifier to set or NULL to clear.
+ *
+ * @retval OT_ERROR_NONE           Successfully set/cleared the Interface Identifier.
+ * @retval OT_ERROR_INVALID_ARGS   The specified Interface Identifier is reserved.
+ *
+ * @sa otThreadGetFixedDuaInterfaceIdentifier
+ */
+otError otThreadSetFixedDuaInterfaceIdentifier(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid);
+
+/**
+ * Get the Interface Identifier manually specified for the Thread Domain Unicast Address.
+ *
+ * This function is only available since Thread 1.2 when `OPENTHREAD_CONFIG_DUA_ENABLE` is enabled.
+ *
+ * @param[in]  aInstance A pointer to an OpenThread instance.
+ *
+ * @returns A pointer to the Interface Identifier which was set manually, or NULL if none was set.
+ *
+ * @sa otThreadSetFixedDuaInterfaceIdentifier
+ *
+ */
+const otIp6InterfaceIdentifier *otThreadGetFixedDuaInterfaceIdentifier(otInstance *aInstance);
+
+/**
  * Get the thrKeySequenceCounter.
  *
  * @param[in]  aInstance A pointer to an OpenThread instance.
@@ -587,7 +649,6 @@
  *
  * @retval OT_ERROR_NONE          Successfully retrieved the leader data.
  * @retval OT_ERROR_DETACHED      Not currently attached.
- * @retval OT_ERROR_INVALID_ARGS  @p aLeaderData is NULL.
  *
  */
 otError otThreadGetLeaderData(otInstance *aInstance, otLeaderData *aLeaderData);
@@ -664,58 +725,6 @@
 otError otThreadGetParentLastRssi(otInstance *aInstance, int8_t *aLastRssi);
 
 /**
- * This function pointer is called when Network Diagnostic Get response is received.
- *
- * @param[in]  aMessage      A pointer to the message buffer containing the received Network Diagnostic
- *                           Get response payload.
- * @param[in]  aMessageInfo  A pointer to the message info for @p aMessage.
- * @param[in]  aContext      A pointer to application-specific context.
- *
- */
-typedef void (*otReceiveDiagnosticGetCallback)(otMessage *aMessage, const otMessageInfo *aMessageInfo, void *aContext);
-
-/**
- * This function registers a callback to provide received raw Network Diagnostic Get response payload.
- *
- * @param[in]  aInstance         A pointer to an OpenThread instance.
- * @param[in]  aCallback         A pointer to a function that is called when Network Diagnostic Get response
- *                               is received or NULL to disable the callback.
- * @param[in]  aCallbackContext  A pointer to application-specific context.
- *
- */
-void otThreadSetReceiveDiagnosticGetCallback(otInstance *                   aInstance,
-                                             otReceiveDiagnosticGetCallback aCallback,
-                                             void *                         aCallbackContext);
-
-/**
- * Send a Network Diagnostic Get request.
- *
- * @param[in]  aInstance      A pointer to an OpenThread instance.
- * @param[in]  aDestination   A pointer to destination address.
- * @param[in]  aTlvTypes      An array of Network Diagnostic TLV types.
- * @param[in]  aCount         Number of types in aTlvTypes
- *
- */
-otError otThreadSendDiagnosticGet(otInstance *        aInstance,
-                                  const otIp6Address *aDestination,
-                                  const uint8_t       aTlvTypes[],
-                                  uint8_t             aCount);
-
-/**
- * Send a Network Diagnostic Reset request.
- *
- * @param[in]  aInstance      A pointer to an OpenThread instance.
- * @param[in]  aDestination   A pointer to destination address.
- * @param[in]  aTlvTypes      An array of Network Diagnostic TLV types. Currently only Type 9 is allowed.
- * @param[in]  aCount         Number of types in aTlvTypes
- *
- */
-otError otThreadSendDiagnosticReset(otInstance *        aInstance,
-                                    const otIp6Address *aDestination,
-                                    const uint8_t       aTlvTypes[],
-                                    uint8_t             aCount);
-
-/**
  * Get the IPv6 counters.
  *
  * @param[in]  aInstance  A pointer to an OpenThread instance.
diff --git a/include/openthread/thread_ftd.h b/include/openthread/thread_ftd.h
index 3a59fe5..d9db862 100644
--- a/include/openthread/thread_ftd.h
+++ b/include/openthread/thread_ftd.h
@@ -79,16 +79,45 @@
 typedef uint16_t otChildIp6AddressIterator; ///< Used to iterate through IPv6 addresses of a Thread Child entry.
 
 /**
+ * This enumeration defines the EID cache entry state.
+ *
+ */
+typedef enum otCacheEntryState
+{
+    OT_CACHE_ENTRY_STATE_CACHED      = 0, // Entry is cached and in-use.
+    OT_CACHE_ENTRY_STATE_SNOOPED     = 1, // Entry is created by snoop optimization (inspection of received msg).
+    OT_CACHE_ENTRY_STATE_QUERY       = 2, // Entry represents an ongoing query for the EID.
+    OT_CACHE_ENTRY_STATE_RETRY_QUERY = 3, // Entry is in retry wait mode (a prior query did not get a response).
+} otCacheEntryState;
+
+/**
  * This structure represents an EID cache entry.
  *
  */
-typedef struct otEidCacheEntry
+typedef struct otCacheEntryInfo
 {
-    otIp6Address   mTarget;    ///< Target
-    otShortAddress mRloc16;    ///< RLOC16
-    uint8_t        mAge;       ///< Age (order of use, 0 indicates most recently used entry)
-    bool           mValid : 1; ///< Indicates whether or not the cache entry is valid
-} otEidCacheEntry;
+    otIp6Address      mTarget;             ///< Target EID
+    otShortAddress    mRloc16;             ///< RLOC16
+    otCacheEntryState mState;              ///< Entry state
+    bool              mCanEvict : 1;       ///< Indicates whether the entry can be evicted.
+    bool              mValidLastTrans : 1; ///< Indicates whether last transaction time and ML-EID are valid.
+    uint32_t          mLastTransTime;      ///< Last transaction time (applicable in cached state).
+    otIp6Address      mMeshLocalEid;       ///< Mesh Local EID (applicable if entry in cached state).
+    uint16_t          mTimeout;            ///< Timeout in seconds (applicable if in snooped/query/retry-query states).
+    uint16_t          mRetryDelay;         ///< Retry delay in seconds (applicable if in query-retry state).
+} otCacheEntryInfo;
+
+/**
+ * This type represents an iterator used for iterating through the EID cache table entries.
+ *
+ * To initialize the iterator and start from the first entry in the cache table, set all its fields in the structure to
+ * zero (e.g., `memset` the iterator to zero).
+ *
+ */
+typedef struct otCacheEntryIterator
+{
+    const void *mData[2]; ///< Opaque data used by the core implementation. Should not be changed by user.
+} otCacheEntryIterator;
 
 /**
  * Get the maximum number of children currently allowed.
@@ -507,17 +536,19 @@
 otError otThreadGetRouterInfo(otInstance *aInstance, uint16_t aRouterId, otRouterInfo *aRouterInfo);
 
 /**
- * This function gets an EID cache entry.
+ * This function gets the next EID cache entry (using an iterator).
  *
- * @param[in]   aInstance A pointer to an OpenThread instance.
- * @param[in]   aIndex    An index into the EID cache table.
- * @param[out]  aEntry    A pointer to where the EID information is placed.
+ * @param[in]    aInstance   A pointer to an OpenThread instance.
+ * @param[out]   aEntryInfo  A pointer to where the EID cache entry information is placed.
+ * @param[inout] aIterator   A pointer to an iterator. It will be updated to point to next entry on success. To get the
+ *                           first entry, initialize the iterator by setting all its fields to zero (e.g., `memset` the
+ *                           the iterator structure to zero).
  *
- * @retval OT_ERROR_NONE          Successfully retrieved the EID cache entry.
- * @retval OT_ERROR_INVALID_ARGS  @p aIndex was out of bounds or @p aEntry was NULL.
+ * @retval OT_ERROR_NONE          Successfully populated @p aEntryInfo for next EID cache entry.
+ * @retval OT_ERROR_NOT_FOUND     No more entries in the address cache table.
  *
  */
-otError otThreadGetEidCacheEntry(otInstance *aInstance, uint8_t aIndex, otEidCacheEntry *aEntry);
+otError otThreadGetNextCacheEntry(otInstance *aInstance, otCacheEntryInfo *aEntryInfo, otCacheEntryIterator *aIterator);
 
 /**
  * Get the Thread PSKc
@@ -579,6 +610,37 @@
 otError otThreadSetParentPriority(otInstance *aInstance, int8_t aParentPriority);
 
 /**
+ * This function gets the maximum number of IP addresses that each MTD child may register with this device as parent.
+ *
+ * @param[in]  aInstance    A pointer to an OpenThread instance.
+ *
+ * @returns The maximum number of IP addresses that each MTD child may register with this device as parent.
+ *
+ * @sa otThreadSetMaxChildIpAddresses
+ *
+ */
+uint8_t otThreadGetMaxChildIpAddresses(otInstance *aInstance);
+
+/**
+ * This function sets/restores the maximum number of IP addresses that each MTD child may register with this
+ * device as parent.
+ *
+ * @note This API requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE`, and is only used by Thread Test Harness
+ *       to limit the address registrations of the reference parent in order to test the MTD DUT reaction.
+ *
+ * @param[in]  aInstance        A pointer to an OpenThread instance.
+ * @param[in]  aMaxIpAddresses  The maximum number of IP addresses that each MTD child may register with this
+ *                              device as parent. 0 to clear the setting and restore the default.
+ *
+ * @retval OT_ERROR_NONE           Successfully set/cleared the number.
+ * @retval OT_ERROR_INVALID_ARGS   If exceeds the allowed maximum number.
+ *
+ * @sa otThreadGetMaxChildIpAddresses
+ *
+ */
+otError otThreadSetMaxChildIpAddresses(otInstance *aInstance, uint8_t aMaxIpAddresses);
+
+/**
  * This enumeration defines the constants used in `otNeighborTableCallback` to indicate whether a child or router
  * neighbor is being added or removed.
  *
diff --git a/include/openthread/udp.h b/include/openthread/udp.h
index 6e925ff..f11d5d7 100644
--- a/include/openthread/udp.h
+++ b/include/openthread/udp.h
@@ -126,7 +126,7 @@
     otSockAddr          mPeerName; ///< The peer IPv6 socket address.
     otUdpReceive        mHandler;  ///< A function pointer to the application callback.
     void *              mContext;  ///< A pointer to application-specific context.
-    void *              mHandle;   ///< A handle to platform's UDP
+    void *              mHandle;   ///< A handle to platform's UDP.
     struct otUdpSocket *mNext;     ///< A pointer to the next UDP socket (internal use only).
 } otUdpSocket;
 
@@ -137,7 +137,7 @@
  * OT_MESSAGE_PRIORITY_NORMAL by default.
  *
  * @param[in]  aInstance  A pointer to an OpenThread instance.
- * @param[in]  aSettings  A pointer to the message settings or NULL to set default settings.
+ * @param[in]  aSettings  A pointer to the message settings or NULL to use default settings.
  *
  * @returns A pointer to the message buffer or NULL if no message buffers are available or parameters are invalid.
  *
@@ -157,68 +157,51 @@
  * @retval OT_ERROR_NONE    Successfully opened the socket.
  * @retval OT_ERROR_FAILED  Failed to open the socket.
  *
- * @sa otUdpNewMessage
- * @sa otUdpClose
- * @sa otUdpBind
- * @sa otUdpConnect
- * @sa otUdpSend
- *
  */
 otError otUdpOpen(otInstance *aInstance, otUdpSocket *aSocket, otUdpReceive aCallback, void *aContext);
 
 /**
  * Close a UDP/IPv6 socket.
  *
- * @param[in]  aSocket  A pointer to a UDP socket structure.
+ * @param[in]  aInstance  A pointer to an OpenThread instance.
+ * @param[in]  aSocket    A pointer to a UDP socket structure.
  *
- * @retval OT_ERROR_NONE  Successfully closed the socket.
- *
- * @sa otUdpNewMessage
- * @sa otUdpOpen
- * @sa otUdpBind
- * @sa otUdpConnect
- * @sa otUdpSend
+ * @retval OT_ERROR_NONE   Successfully closed the socket.
+ * @retval OT_ERROR_FAILED Failed to close UDP Socket.
  *
  */
-otError otUdpClose(otUdpSocket *aSocket);
+otError otUdpClose(otInstance *aInstance, otUdpSocket *aSocket);
 
 /**
  * Bind a UDP/IPv6 socket.
  *
+ * @param[in]  aInstance  A pointer to an OpenThread instance.
  * @param[in]  aSocket    A pointer to a UDP socket structure.
  * @param[in]  aSockName  A pointer to an IPv6 socket address structure.
  *
- * @retval OT_ERROR_NONE  Bind operation was successful.
- *
- * @sa otUdpNewMessage
- * @sa otUdpOpen
- * @sa otUdpConnect
- * @sa otUdpClose
- * @sa otUdpSend
+ * @retval OT_ERROR_NONE   Bind operation was successful.
+ * @retval OT_ERROR_FAILED Failed to bind UDP socket.
  *
  */
-otError otUdpBind(otUdpSocket *aSocket, otSockAddr *aSockName);
+otError otUdpBind(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName);
 
 /**
  * Connect a UDP/IPv6 socket.
  *
+ * @param[in]  aInstance  A pointer to an OpenThread instance.
  * @param[in]  aSocket    A pointer to a UDP socket structure.
  * @param[in]  aSockName  A pointer to an IPv6 socket address structure.
  *
- * @retval OT_ERROR_NONE  Connect operation was successful.
- *
- * @sa otUdpNewMessage
- * @sa otUdpOpen
- * @sa otUdpBind
- * @sa otUdpClose
- * @sa otUdpSend
+ * @retval OT_ERROR_NONE   Connect operation was successful.
+ * @retval OT_ERROR_FAILED Failed to connect UDP socket.
  *
  */
-otError otUdpConnect(otUdpSocket *aSocket, otSockAddr *aSockName);
+otError otUdpConnect(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName);
 
 /**
  * Send a UDP/IPv6 message.
  *
+ * @param[in]  aInstance     A pointer to an OpenThread instance.
  * @param[in]  aSocket       A pointer to a UDP socket structure.
  * @param[in]  aMessage      A pointer to a message buffer.
  * @param[in]  aMessageInfo  A pointer to a message info structure.
@@ -227,18 +210,22 @@
  * reference @p aMessage. If the return value is not OT_ERROR_NONE, the caller retains ownership of @p aMessage,
  * including freeing @p aMessage if the message buffer is no longer needed.
  *
- * @retval OT_ERROR_NONE            The message is successfully scheduled for sending.
- * @retval OT_ERROR_INVALID_ARGS    Invalid arguments are given.
- *
- * @sa otUdpNewMessage
- * @sa otUdpOpen
- * @sa otUdpClose
- * @sa otUdpBind
- * @sa otUdpConnect
- * @sa otUdpSend
+ * @retval OT_ERROR_NONE           The message is successfully scheduled for sending.
+ * @retval OT_ERROR_INVALID_ARGS   Invalid arguments are given.
+ * @retval OT_ERROR_NO_BUFS        Insufficient available buffer to add the UDP and IPv6 headers.
  *
  */
-otError otUdpSend(otUdpSocket *aSocket, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+otError otUdpSend(otInstance *aInstance, otUdpSocket *aSocket, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+
+/**
+ * This function gets the head of linked list of UDP Sockets.
+ *
+ * @param[in]  aInstance  A pointer to an OpenThread instance.
+ *
+ * @returns A pointer to the head of UDP Socket linked list.
+ *
+ */
+otUdpSocket *otUdpGetSockets(otInstance *aInstance);
 
 /**
  * @}
@@ -303,16 +290,6 @@
                          uint16_t            aSockPort);
 
 /**
- * This function gets the existing UDP Sockets.
- *
- * @param[in]  aInstance            A pointer to an OpenThread instance.
- *
- * @returns A pointer to the first UDP Socket.
- *
- */
-otUdpSocket *otUdpGetSockets(otInstance *aInstance);
-
-/**
  * @}
  *
  */
diff --git a/script/bootstrap b/script/bootstrap
index 1106e39..f3ceb24 100755
--- a/script/bootstrap
+++ b/script/bootstrap
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 #  Copyright (c) 2017, The OpenThread Authors.
 #  All rights reserved.
@@ -31,31 +31,48 @@
 #      example compilation and programming.
 #
 
-die()
-{
-    echo " *** ERROR: " $*
-    exit 1
-}
+set -euxo pipefail
 
 install_packages_apt()
 {
-    # apt update and install dependencies
-    sudo apt-get update || die
-    sudo apt-get -y install automake g++ libtool lsb-release make || die
+    echo 'Installing toolchain dependencies...'
+
+    # apt-get update and install dependencies
+    sudo apt-get update
+    sudo apt-get --no-install-recommends install -y automake g++ libtool lsb-release make cmake ninja-build shellcheck
+
+    echo 'Installing GNU Arm Embedded Toolchain...'
 
     PLATFORM=$(lsb_release -is)
+    RELEASE=$(lsb_release -rs)
+    UBUNTU2004=20.04
 
-    if [ $PLATFORM = "Raspbian" ]; then
-        sudo apt-get -y install binutils-arm-none-eabi gcc-arm-none-eabi gdb-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib || die
-    else
+    if [ "$PLATFORM" = "Raspbian" ]; then
+        sudo apt-get --no-install-recommends install -y binutils-arm-none-eabi gcc-arm-none-eabi gdb-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
+    elif [ "$PLATFORM" = "Ubuntu" ] && [[ ! $RELEASE < $UBUNTU2004 ]]; then
+        echo "Ubuntu Release >= $UBUNTU2004"
+        # no need to use ppa
+        sudo apt-get --no-install-recommends install -y gcc-arm-none-eabi gdb-multiarch libnewlib-arm-none-eabi
+    elif ! command -v arm-none-eabi-g++; then
         # add gcc-arm-embedded ppa
-        sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa -y || die
-        sudo apt-get update || die
-        sudo apt-get -y install gcc-arm-embedded || die
+        sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa -y
+        sudo apt-get update
+        sudo apt-get --no-install-recommends install -y gcc-arm-embedded
     fi
 
+    echo 'Installing pretty tools useful for code contributions...'
+
     # add clang-format for pretty
-    sudo apt-get -y install clang-format-6.0
+    sudo apt-get --no-install-recommends install -y clang-format-6.0
+
+    # add yapf for pretty
+    python3 -m pip install yapf==0.29.0 || echo 'WARNING: could not install yapf, which is useful if you plan to contribute python code to the OpenThread project.'
+
+    # add mdv for local size report
+    python3 -m pip install mdv || echo 'WARNING: could not install mdv, which is useful if you plan to contribute markdown to the OpenThread project.'
+
+    # add shfmt for shell pretty, try brew only because snap does not support home directory not being /home and doesn't work in docker.
+    command -v shfmt || brew install shfmt || echo 'WARNING: could not install shfmt, which is useful if you plan to contribute shell scripts to the OpenThread project.'
 }
 
 install_packages_opkg()
@@ -70,25 +87,34 @@
 
 install_packages_brew()
 {
-    # add autotools
-    brew install automake libtool
+    echo 'Installing toolchain dependencies...'
+
+    # add build tools
+    brew install automake libtool cmake ninja shfmt shellcheck
+
+    echo 'Installing GNU Arm Embedded Toolchain...'
 
     # add ARM toolchain
     brew tap ArmMbed/homebrew-formulae
     brew install arm-none-eabi-gcc
 
-    # check for gcc for posix examples
-    if ! which gcc; then
-        echo 'warning: clang/gcc needed for posix examples'
+    # check for gcc for simulation
+    if ! command -v gcc; then
+        echo 'warning: clang/gcc needed for simulation'
         echo 'warning: please install Command Line Tools from https://developer.apple.com/download/more/'
     fi
 
+    echo 'Installing pretty tools useful for code contributions...'
+
     # add clang-format for pretty
     CLANG_FORMAT_VERSION="clang-format version 6.0"
-    which clang-format-6.0 || (which clang-format && (clang-format --version | grep -q "${CLANG_FORMAT_VERSION}")) || {
+    command -v clang-format-6.0 || (command -v clang-format && (clang-format --version | grep -q "${CLANG_FORMAT_VERSION}")) || {
         brew install llvm@6
         sudo ln -s "$(brew --prefix llvm@6)/bin/clang-format" /usr/local/bin/clang-format-6.0
     }
+
+    # add yapf for pretty
+    python3 -m pip install yapf || echo 'Failed to install python code formatter yapf. Install it manually if you need.'
 }
 
 install_packages_source()
@@ -99,13 +125,13 @@
 install_packages()
 {
     PM=source
-    if which apt-get; then
+    if command -v apt-get; then
         PM=apt
-    elif which rpm; then
+    elif command -v rpm; then
         PM=rpm
-    elif which opkg; then
+    elif command -v opkg; then
         PM=opkg
-    elif which brew; then
+    elif command -v brew; then
         PM=brew
     fi
     install_packages_$PM
@@ -114,6 +140,7 @@
 main()
 {
     install_packages
+    echo 'bootstrap completed successfully.'
 }
 
 main
diff --git a/script/check-android-build b/script/check-android-build
new file mode 100755
index 0000000..5acc038
--- /dev/null
+++ b/script/check-android-build
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+#  Copyright (c) 2018, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Run this command on parent directory of openthread
+#
+
+set -euxo pipefail
+
+check_targets()
+{
+    for target in "$@"; do
+        make showcommands "${target}"
+        test -x "out/target/product/generic/system/bin/${target}"
+    done
+
+    for target in "$@"; do
+        make "clean-${target}" || true
+    done
+}
+
+main()
+{
+    USE_OTBR_DAEMON=1 check_targets ot-cli ot-ctl ot-ncp
+    check_targets ot-cli ot-ncp spi-hdlc-adapter
+}
+
+main "$@"
diff --git a/script/check-api-version b/script/check-api-version
new file mode 100755
index 0000000..351d144
--- /dev/null
+++ b/script/check-api-version
@@ -0,0 +1,73 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euo pipefail
+
+readonly OT_SHA_OLD="$(git cat-file -p HEAD | grep 'parent ' | head -n1 | cut -d' ' -f2)"
+readonly OT_VERSIONS_FILE=tmp/api_versions
+
+die()
+{
+    echo >&2 "ERROR: $*"
+    exit 1
+}
+
+main()
+{
+    mkdir -p tmp
+
+    echo "The master branch must be ${OT_SHA_OLD}"
+
+    git fetch --depth 1 origin "${OT_SHA_OLD}"
+
+    if git diff --quiet "${OT_SHA_OLD}" -- include; then
+        echo 'No OpenThread public APIs updates.'
+        exit 0
+    fi
+
+    git diff "${OT_SHA_OLD}" -- include | tee >(cat >&2) | grep -aP '[-+]#define OPENTHREAD_API_VERSION (.+)' >"${OT_VERSIONS_FILE}" || die 'Version number is not updated!'
+
+    [[ $(wc -l <"${OT_VERSIONS_FILE}") == 2 ]] || die 'Multiple OPENTHREAD_API_VERSION definitions found!'
+
+    old_version=$(grep -aoP '(?<=-#define OPENTHREAD_API_VERSION ).+' "${OT_VERSIONS_FILE}") || die 'Failed to find old version!'
+    new_version=$(grep -aoP '(?<=\+#define OPENTHREAD_API_VERSION ).+' "${OT_VERSIONS_FILE}") || die 'Failed to find new version!'
+
+    echo -e '\n--------------------------\n'
+
+    echo "Old version: ${old_version}"
+    echo "New version: ${new_version}"
+
+    [[ $((new_version - old_version)) -gt 0 ]] || die 'Version is not increased!'
+
+    echo -e '\n--------------------------\n'
+
+    echo 'PASS: version check.'
+}
+
+main "$@"
diff --git a/script/check-arm-build b/script/check-arm-build
new file mode 100755
index 0000000..2f302d6
--- /dev/null
+++ b/script/check-arm-build
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+main()
+{
+    "$(dirname "$0")"/check-arm-build-autotools
+    "$(dirname "$0")"/check-arm-build-cmake
+}
+
+main "$@"
diff --git a/script/check-arm-build-autotools b/script/check-arm-build-autotools
new file mode 100755
index 0000000..ceebe1f
--- /dev/null
+++ b/script/check-arm-build-autotools
@@ -0,0 +1,301 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+reset_source()
+{
+    rm -rf build output tmp
+}
+
+build_cc1352()
+{
+    local options=(
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "JOINER=1"
+        "SLAAC=1"
+    )
+
+    reset_source
+    make -f examples/Makefile-cc1352 "${options[@]}"
+}
+
+build_cc2538()
+{
+    local options=(
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "JOINER=1"
+        "SLAAC=1"
+    )
+
+    reset_source
+    make -f examples/Makefile-cc2538 "${options[@]}"
+}
+
+build_cc2650()
+{
+    reset_source
+    make -f examples/Makefile-cc2650
+}
+
+build_cc2652()
+{
+    local options=(
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "JOINER=1"
+        "SLAAC=1"
+    )
+
+    reset_source
+    make -f examples/Makefile-cc2652 "${options[@]}"
+}
+
+build_jn5189()
+{
+    local options=(
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "JOINER=1"
+        "SLAAC=1"
+    )
+
+    reset_source
+    make -f examples/Makefile-jn5189 "${options[@]}"
+}
+
+build_k32w061()
+{
+    local options=(
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "JOINER=1"
+        "SLAAC=1"
+    )
+
+    reset_source
+    make -f examples/Makefile-k32w061 "${options[@]}"
+}
+
+build_kw41z()
+{
+    local options=(
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "JOINER=1"
+        "SLAAC=1"
+    )
+
+    reset_source
+    make -f examples/Makefile-kw41z "${options[@]}"
+}
+
+build_nrf52811()
+{
+    local options=(
+        "BORDER_ROUTER=1"
+        "COAP=1"
+        "DNS_CLIENT=1"
+        "LINK_RAW=1"
+        "MAC_FILTER=1"
+        "MTD_NETDIAG=1"
+    )
+
+    # UART transport
+    reset_source
+    make -f examples/Makefile-nrf52811 "${options[@]}"
+
+    # SPI transport for NCP
+    reset_source
+    make -f examples/Makefile-nrf52811 "${options[@]}" NCP_SPI=1
+
+    # Build without transport (no CLI or NCP applications)
+    reset_source
+    make -f examples/Makefile-nrf52811 DISABLE_TRANSPORTS=1
+}
+
+build_nrf52833()
+{
+    local options=(
+        "BORDER_AGENT=1"
+        "BORDER_ROUTER=1"
+        "COAP=1"
+        "COAPS=1"
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "ECDSA=1"
+        "FULL_LOGS=1"
+        "IP6_FRAGM=1"
+        "JOINER=1"
+        "LINK_RAW=1"
+        "MAC_FILTER=1"
+        "MTD_NETDIAG=1"
+        "SERVICE=1"
+        "SLAAC=1"
+        "SNTP_CLIENT=1"
+        "UDP_FORWARD=1"
+    )
+
+    # UART transport
+    reset_source
+    make -f examples/Makefile-nrf52833 "${options[@]}"
+
+    # USB transport
+    reset_source
+    make -f examples/Makefile-nrf52833 "${options[@]}" USB=1
+
+    # SPI transport for NCP
+    reset_source
+    make -f examples/Makefile-nrf52833 "${options[@]}" NCP_SPI=1
+
+    # Build without transport (no CLI or NCP applications)
+    reset_source
+    make -f examples/Makefile-nrf52833 "${options[@]}" DISABLE_TRANSPORTS=1
+}
+
+build_nrf52840()
+{
+    local options=(
+        "BORDER_AGENT=1"
+        "BORDER_ROUTER=1"
+        "COAP=1"
+        "COAPS=1"
+        "COMMISSIONER=1"
+        "DEBUG=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "ECDSA=1"
+        "FULL_LOGS=1"
+        "IP6_FRAGM=1"
+        "JOINER=1"
+        "LINK_RAW=1"
+        "MAC_FILTER=1"
+        "MTD_NETDIAG=1"
+        "SERVICE=1"
+        "SLAAC=1"
+        "SNTP_CLIENT=1"
+        "UDP_FORWARD=1"
+    )
+
+    # UART transport
+    reset_source
+    make -f examples/Makefile-nrf52840 "${options[@]}"
+
+    # USB transport with bootloader e.g. to support PCA10059 dongle
+    reset_source
+    make -f examples/Makefile-nrf52840 "${options[@]}" BOOTLOADER=1 USB=1
+
+    # SPI transport for NCP
+    reset_source
+    make -f examples/Makefile-nrf52840 "${options[@]}" NCP_SPI=1
+
+    # Build without transport (no CLI or NCP applications)
+    reset_source
+    make -f examples/Makefile-nrf52840 "${options[@]}" DISABLE_TRANSPORTS=1
+
+    # Software cryptography
+    reset_source
+    make -f examples/Makefile-nrf52840 "${options[@]}" DISABLE_BUILTIN_MBEDTLS=0
+
+    # Software cryptography with threading support
+    reset_source
+    make -f examples/Makefile-nrf52840 "${options[@]}" DISABLE_BUILTIN_MBEDTLS=0 MBEDTLS_THREADING=1
+}
+
+build_qpg6095()
+{
+    local options=(
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "JOINER=1"
+        "SLAAC=1"
+    )
+
+    reset_source
+    make -f examples/Makefile-qpg6095 "${options[@]}"
+}
+
+build_samr21()
+{
+    local options=(
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DNS_CLIENT=1"
+        "JOINER=1"
+        "SLAAC=1"
+    )
+
+    reset_source
+
+    wget http://ww1.microchip.com/downloads/en/DeviceDoc/asf-standalone-archive-3.45.0.85.zip
+    unzip -qq asf-standalone-archive-3.45.0.85.zip
+    mv xdk-asf-3.45.0 third_party/microchip/asf
+
+    make -f examples/Makefile-samr21 "${options[@]}"
+}
+
+main()
+{
+    ./bootstrap
+
+    build_cc1352
+    build_cc2538
+    build_cc2650
+    build_cc2652
+    build_jn5189
+    build_k32w061
+    build_kw41z
+    build_nrf52811
+    build_nrf52833
+    build_nrf52840
+    build_qpg6095
+    build_samr21
+}
+
+main "$@"
diff --git a/script/check-arm-build-cmake b/script/check-arm-build-cmake
new file mode 100755
index 0000000..3c924fe
--- /dev/null
+++ b/script/check-arm-build-cmake
@@ -0,0 +1,110 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+readonly OT_BUILDDIR="$(pwd)/build"
+
+readonly OT_COMMON_OPTIONS=(
+    "-DOT_COMPILE_WARNING_AS_ERROR=ON"
+)
+
+readonly OT_BASIC_CHECK_OPTIONS=(
+    "-DOT_COMMISSIONER=ON"
+    "-DOT_DHCP6_CLIENT=ON"
+    "-DOT_DHCP6_SERVER=ON"
+    "-DOT_DNS_CLIENT=ON"
+    "-DOT_JOINER=ON"
+)
+
+reset_source()
+{
+    rm -rf "$OT_BUILDDIR"
+}
+
+build_cc1352()
+{
+    reset_source
+    "$(dirname "$0")"/cmake-build cc1352 "${OT_COMMON_OPTIONS[@]}" "${OT_BASIC_CHECK_OPTIONS[@]}"
+}
+
+build_cc2538()
+{
+    reset_source
+    "$(dirname "$0")"/cmake-build cc2538 "${OT_COMMON_OPTIONS[@]}" "${OT_BASIC_CHECK_OPTIONS[@]}"
+}
+
+build_cc2650()
+{
+    reset_source
+    "$(dirname "$0")"/cmake-build cc2650 "${OT_COMMON_OPTIONS[@]}"
+}
+
+build_cc2652()
+{
+    reset_source
+    "$(dirname "$0")"/cmake-build cc2652 "${OT_COMMON_OPTIONS[@]}" "${OT_BASIC_CHECK_OPTIONS[@]}"
+}
+
+build_kw41z()
+{
+    reset_source
+    "$(dirname "$0")"/cmake-build kw41z "${OT_COMMON_OPTIONS[@]}" "${OT_BASIC_CHECK_OPTIONS[@]}"
+}
+
+build_qpg6095()
+{
+    reset_source
+    "$(dirname "$0")"/cmake-build qpg6095 "${OT_COMMON_OPTIONS[@]}" "${OT_BASIC_CHECK_OPTIONS[@]}"
+}
+
+build_samr21()
+{
+    reset_source
+
+    asfzip=asf-standalone-archive-3.45.0.85.zip
+    wget http://ww1.microchip.com/downloads/en/DeviceDoc/${asfzip}
+    unzip -qq ${asfzip}
+    mv xdk-asf-3.45.0 third_party/microchip/asf
+
+    "$(dirname "$0")"/cmake-build samr21 "${OT_COMMON_OPTIONS[@]}" "${OT_BASIC_CHECK_OPTIONS[@]}"
+}
+
+main()
+{
+    build_cc1352
+    build_cc2538
+    build_cc2650
+    build_cc2652
+    build_kw41z
+    build_qpg6095
+    build_samr21
+}
+
+main "$@"
diff --git a/script/check-gn-build b/script/check-gn-build
new file mode 100755
index 0000000..f4f9add
--- /dev/null
+++ b/script/check-gn-build
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Run this command on parent directory of openthread
+#
+
+set -e
+set -x
+
+main()
+{
+    gn gen gn-out
+    ninja -C gn-out
+    test -f gn-out/obj/lib-ot-core.a
+}
+
+main "$@"
diff --git a/script/check-ncp-rcp-migrate b/script/check-ncp-rcp-migrate
new file mode 100755
index 0000000..a52836d
--- /dev/null
+++ b/script/check-ncp-rcp-migrate
@@ -0,0 +1,150 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -e
+set -x
+
+at_exit()
+{
+    EXIT_CODE=$?
+
+    killall expect || true
+    killall ot-cli-ftd || true
+    killall ot-cli || true
+    killall ot-rcp || true
+
+    exit $EXIT_CODE
+}
+
+build()
+{
+    make -f examples/Makefile-simulation
+    make -f src/posix/Makefile-posix
+}
+
+check()
+{
+    trap at_exit INT TERM EXIT
+
+    rm -rf tmp/
+
+    PANID="0xc001"
+    EXT_PANID="0123456789abcdef"
+    NETWORK_NAME="OT_NCP_TO_RCP"
+    CHANNEL="20"
+    MASTER_KEY="0123456789abcdef0123456789abcdef"
+
+    echo "Step 1. Start NCP platform and form a PAN..."
+    RADIO_NCP_CMD="$(pwd)/$(ls output/*linux*/bin/ot-cli-ftd)"
+
+    expect <<EOF
+spawn ${RADIO_NCP_CMD} 1
+set timeout 2
+expect_after {
+    timeout { exit 1 }
+}
+send "panid ${PANID}\r\n"
+expect "Done"
+send "extpanid ${EXT_PANID}\r\n"
+expect "Done"
+send "networkname ${NETWORK_NAME}\r\n"
+expect "Done"
+send "channel ${CHANNEL}\r\n"
+expect "Done"
+send "masterkey ${MASTER_KEY}\r\n"
+expect "Done"
+send "ifconfig up\r\n"
+expect "Done"
+send "thread start\r\n"
+expect "Done"
+sleep 5
+send "state\r\n"
+expect "leader"
+expect "Done"
+send "exit\r\n"
+expect eof
+EOF
+
+    echo "Step 2. Start retrieving dataset from Radio..."
+    RADIO_NCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-ncp-ftd)"
+    "$(pwd)/$(ls output/posix/*linux*/bin/ot-ncp)" -n --radio-version "spinel+hdlc+forkpty://${RADIO_NCP_PATH}?forkpty-arg=1&ncp-dataset=1"
+
+    echo "Step 3. Start posix app and check whether PAN dataset is the same..."
+    RADIO_RCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-rcp)"
+
+    OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) spinel+hdlc+forkpty://${RADIO_RCP_PATH}?forkpty-arg=1"
+
+    expect <<EOF
+spawn ${OT_CLI_CMD}
+set timeout 2
+expect_after {
+    timeout { exit 1 }
+}
+send "panid\r\n"
+expect ${PANID}
+expect "Done"
+send "extpanid\r\n"
+expect ${EXT_PANID}
+expect "Done"
+send "networkname\r\n"
+expect ${NETWORK_NAME}
+expect "Done"
+send "channel\r\n"
+expect ${CHANNEL}
+expect "Done"
+send "masterkey\r\n"
+expect ${MASTER_KEY}
+expect "Done"
+send "exit\r\n"
+expect eof
+EOF
+
+    echo "Step 4. Start posix app and check whether it can get radio firmware version..."
+    RADIO_VERSION="$("$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)" -n --radio-version "spinel+hdlc+forkpty://${RADIO_RCP_PATH}?forkpty-arg=1&ncp-dataset=1")" || true
+    echo "${RADIO_VERSION}"
+    test -n "{RADIO_VERSION}"
+}
+
+main()
+{
+    case "$1" in
+        build)
+            build
+            ;;
+        check)
+            check
+            ;;
+        *)
+            build
+            check
+            ;;
+    esac
+}
+
+main "$@"
diff --git a/script/check-posix-build b/script/check-posix-build
new file mode 100755
index 0000000..5be4ed8
--- /dev/null
+++ b/script/check-posix-build
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+main()
+{
+    "$(dirname "$0")"/check-posix-build-autotools
+    "$(dirname "$0")"/check-posix-build-cmake
+}
+
+main "$@"
diff --git a/script/check-posix-build-autotools b/script/check-posix-build-autotools
new file mode 100755
index 0000000..a8cc3d2
--- /dev/null
+++ b/script/check-posix-build-autotools
@@ -0,0 +1,55 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+reset_source()
+{
+    rm -rf build output tmp
+}
+
+build()
+{
+    reset_source
+    make -f src/posix/Makefile-posix
+
+    if [[ $OSTYPE != "darwin"* ]]; then
+        reset_source
+        make -f src/posix/Makefile-posix RCP_BUS=spi
+    fi
+}
+
+main()
+{
+    ./bootstrap
+
+    build
+}
+
+main "$@"
diff --git a/script/check-posix-build-cmake b/script/check-posix-build-cmake
new file mode 100755
index 0000000..9fb5ff6
--- /dev/null
+++ b/script/check-posix-build-cmake
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+readonly OT_BUILDDIR="$(pwd)/build"
+
+reset_source()
+{
+    rm -rf "$OT_BUILDDIR"
+}
+
+build()
+{
+    local options=("$@")
+
+    options+=(
+        "-DOT_FULL_LOGS=ON"
+    )
+
+    "$(dirname "$0")"/cmake-build posix "${options[@]}"
+}
+
+main()
+{
+    reset_source
+    build
+
+    if [[ $OSTYPE != "darwin"* ]]; then
+        reset_source
+        build -DOT_POSIX_CONFIG_RCP_BUS=SPI
+    fi
+}
+
+main "$@"
diff --git a/script/check-posix-pty b/script/check-posix-pty
new file mode 100755
index 0000000..78fde38
--- /dev/null
+++ b/script/check-posix-pty
@@ -0,0 +1,183 @@
+#!/bin/bash
+#
+#  Copyright (c) 2018, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -e
+set -x
+
+die()
+{
+    echo " *** ERROR: " "$*"
+    exit 1
+}
+
+at_exit()
+{
+    EXIT_CODE=$?
+
+    sudo killall expect || true
+    killall ot-ctl || true
+    killall ot-daemon || true
+    killall socat || true
+
+    exit $EXIT_CODE
+}
+
+build()
+{
+    make -f examples/Makefile-simulation
+    make -f src/posix/Makefile-posix PLATFORM_NETIF=1 PLATFORM_UDP=1 UDP_FORWARD=0 MAX_POWER_TABLE=1
+}
+
+check()
+{
+    trap at_exit INT TERM EXIT
+
+    SOCAT_OUTPUT=/tmp/ot-socat
+    OT_OUTPUT=/tmp/ot-output
+    socat -d -d pty,raw,echo=0 pty,raw,echo=0 >/dev/null 2>$SOCAT_OUTPUT &
+    while true; do
+        if test "$(head -n2 $SOCAT_OUTPUT | wc -l)" = 2; then
+            RADIO_PTY=$(head -n1 $SOCAT_OUTPUT | grep -o '/dev/.\+')
+            CORE_PTY=$(head -n2 $SOCAT_OUTPUT | tail -n1 | grep -o '/dev/.\+')
+            break
+        fi
+        echo 'Waiting for socat ready...'
+        sleep 1
+    done
+    echo 'RADIO_PTY' "$RADIO_PTY"
+    echo 'CORE_PTY' "$CORE_PTY"
+
+    RADIO_NCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-rcp)"
+
+    # shellcheck disable=SC2094
+    $RADIO_NCP_PATH 1 >"$RADIO_PTY" <"$RADIO_PTY" &
+
+    # Cover setting a valid network interface name.
+    readonly VALID_NETIF_NAME="wan$(date +%H%M%S)"
+
+    RADIO_URL="spinel+hdlc+uart://${CORE_PTY}?max-power-table=11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26"
+
+    if [[ ${DAEMON} == 1 ]]; then
+        sudo "$(pwd)/$(ls output/posix/*linux*/bin/ot-daemon)" -I "${VALID_NETIF_NAME}" "${RADIO_URL}" &
+        sleep 1
+        OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-ctl)"
+        sudo "${OT_CLI_CMD}" panid 0xface | grep 'Done' || die 'failed to set panid with ot-ctl'
+
+        # verify this reset and factoryreset end immediately
+        sudo "${OT_CLI_CMD}" reset
+        # sleep a while for daemon ready
+        sleep 2
+        sudo "${OT_CLI_CMD}" factoryreset
+    else
+        OT_CLI="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)"
+        sudo "${OT_CLI}" -I "${VALID_NETIF_NAME}" -n "${RADIO_URL}"
+
+        # Cover setting a too long(max is 15 characters) network interface name.
+        # Expect exit code to be 2(OT_EXIT_INVALID_ARGUMENTS).
+        readonly INVALID_NETIF_NAME="wan0123456789123"
+        sudo "${OT_CLI}" -I "${INVALID_NETIF_NAME}" -n "${RADIO_URL}" || test $? = 2
+
+        OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) ${RADIO_URL}"
+    fi
+
+    sudo expect <<EOF | tee "${OT_OUTPUT}" &
+spawn ${OT_CLI_CMD}
+send "panid 0xface\r\n"
+expect "Done"
+send "ifconfig up\r\n"
+expect "Done"
+send "thread start\r\n"
+expect "Done"
+sleep 5
+send "state\r\n"
+expect "leader"
+expect "Done"
+send "extaddr\r\n"
+expect "Done"
+send "ipaddr\r\n"
+expect "Done"
+send "coex\r\n"
+expect "Done"
+wait
+EOF
+
+    # wait until the node becomes leader
+    while true; do
+        sleep 5
+        if grep -q leader $OT_OUTPUT; then
+            break
+        else
+            echo 'Still waiting for leader'
+        fi
+    done
+
+    netstat -an | grep -q 61631 || die 'TMF port is not available!'
+
+    extaddr=$(awk '/extaddr/{getline; print}' $OT_OUTPUT | tr -d '\r\n')
+    echo "Extended address is: ${extaddr}"
+
+    if [[ ${DAEMON} == 1 ]]; then
+        sudo killall -9 expect || true
+        sudo killall -9 ot-ctl || true
+        NETIF_INDEX=$(ip link show "${VALID_NETIF_NAME}" | cut -f 1 -d ":" | head -n 1)
+        sudo PATH="$(dirname "${OT_CLI_CMD}"):${PATH}" \
+            python3 "$PWD/tests/scripts/misc/test_multicast_join.py" "${NETIF_INDEX}" \
+            || die 'multicast group join failed'
+    fi
+
+    LEADER_ALOC=fdde:ad00:beef::ff:fe00:fc00
+    # Retrievie extended address through network diagnostic get
+    coap_response=$(echo -n '120100' | xxd -r -p | coap-client -m POST coap://[${LEADER_ALOC}]:61631/d/dg -f- | xxd -p | grep 0008)
+    echo "CoAP response is: ${coap_response}"
+
+    # Verify CoAP response contains the extended address
+    if [[ ${coap_response} == *${extaddr}* ]]; then
+        echo 'Success'
+    else
+        die 'Failed to get extended address'
+    fi
+}
+
+main()
+{
+    case $1 in
+        build)
+            build
+            ;;
+        check)
+            check
+            ;;
+        *)
+            build
+            check
+            ;;
+    esac
+}
+
+main "$@"
diff --git a/script/check-scan-build b/script/check-scan-build
new file mode 100755
index 0000000..9d4292f
--- /dev/null
+++ b/script/check-scan-build
@@ -0,0 +1,113 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+readonly OT_BUILD_JOBS=$(getconf _NPROCESSORS_ONLN)
+
+do_scan_build()
+{
+    local options=(
+        "-DOPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_COAP_API_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DIAG_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_ECDSA_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_IP6_SLAAC_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_JOINER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_LEGACY_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_BEACON_RSP_WHEN_JOINABLE_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE"
+        "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
+    )
+    options+=(
+        "-DMBEDTLS_DEBUG_C"
+        "-I$(pwd)/third_party/mbedtls"
+        "-I$(pwd)/third_party/mbedtls/repo/include"
+        '-DMBEDTLS_CONFIG_FILE=\"mbedtls-config.h\"'
+    )
+
+    configure_options=(
+        "--enable-builtin-mbedtls=no"
+        "--enable-cli"
+        "--enable-executable=no"
+        "--enable-ftd"
+        "--enable-mtd"
+        "--enable-ncp"
+        "--enable-radio-only"
+        "--with-examples=simulation"
+    )
+
+    export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1"
+    scan-build ./configure "${configure_options[@]}"
+    scan-build --status-bugs -analyze-headers -v make -j"${OT_BUILD_JOBS}"
+
+    export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
+    scan-build ./configure "${configure_options[@]}"
+    scan-build --status-bugs -analyze-headers -v make -j"${OT_BUILD_JOBS}"
+}
+
+main()
+{
+    ./bootstrap
+
+    do_scan_build
+}
+
+main "$@"
diff --git a/script/check-simulation-build b/script/check-simulation-build
new file mode 100755
index 0000000..4c31fd9
--- /dev/null
+++ b/script/check-simulation-build
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+main()
+{
+    "$(dirname "$0")"/check-simulation-build-autotools
+    "$(dirname "$0")"/check-simulation-build-cmake
+}
+
+main "$@"
diff --git a/script/check-simulation-build-autotools b/script/check-simulation-build-autotools
new file mode 100755
index 0000000..ed68111
--- /dev/null
+++ b/script/check-simulation-build-autotools
@@ -0,0 +1,196 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+readonly OT_BUILD_JOBS=$(getconf _NPROCESSORS_ONLN)
+
+reset_source()
+{
+    rm -rf build output tmp
+}
+
+build_all_features()
+{
+    local options=(
+        "-DOPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_COAP_API_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DIAG_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_ECDSA_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_IP6_SLAAC_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_JOINER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_LEGACY_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_BEACON_RSP_WHEN_JOINABLE_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE"
+        "-DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
+    )
+
+    local options_1_2=(
+        "-DOPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DUA_ENABLE=1"
+    )
+
+    export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_NONE"
+    reset_source
+    make -f examples/Makefile-simulation
+
+    export CPPFLAGS="${options[*]}"
+    reset_source
+    make -f examples/Makefile-simulation FULL_LOGS=1
+
+    export CPPFLAGS="${options[*]} ${options_1_2[*]} -DOPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_NONE"
+    reset_source
+    make -f examples/Makefile-simulation THREAD_VERSION=1.2
+
+    export CPPFLAGS="${options[*]} ${options_1_2[*]}"
+    reset_source
+    make -f examples/Makefile-simulation THREAD_VERSION=1.2 FULL_LOGS=1
+
+    export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_ASSERT_ENABLE=0"
+    reset_source
+    make -f examples/Makefile-simulation
+
+    export CPPFLAGS="${options[*]}"
+    reset_source
+    make -f examples/Makefile-simulation OTNS=1
+}
+
+build_nest_common()
+{
+    local options=(
+        "-DOPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_DIAG_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_LEGACY_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
+    )
+    export CPPFLAGS="${options[*]}"
+
+    reset_source
+    mkdir build && cd build
+    ../configure \
+        --enable-cli \
+        --enable-mtd \
+        --with-examples=simulation \
+        --disable-docs \
+        --disable-tests
+    make -j"${OT_BUILD_JOBS}"
+    cd ..
+
+    options=(
+        "-DOPENTHREAD_CONFIG_ANOUNCE_SENDER_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
+    )
+    export CPPFLAGS="${options[*]}"
+
+    reset_source
+    mkdir build && cd build
+    ../configure \
+        --enable-cli \
+        --enable-ftd \
+        --enable-mtd \
+        --enable-ncp \
+        --enable-radio-only \
+        --disable-docs \
+        --disable-tests \
+        --with-examples=simulation
+    make -j"${OT_BUILD_JOBS}"
+    cd ..
+
+    options=(
+        "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
+        "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1"
+    )
+    export CPPFLAGS="${options[*]}"
+
+    reset_source
+    mkdir build && cd build
+    ../configure \
+        --enable-ftd \
+        --enable-mtd \
+        --enable-ncp \
+        --with-examples=simulation \
+        --disable-docs \
+        --disable-tests \
+        --with-vendor-extension=../src/core/common/extension_example.cpp \
+        --with-ncp-vendor-hook-source=../src/ncp/example_vendor_hook.cpp
+    make -j"${OT_BUILD_JOBS}"
+    cd ..
+}
+
+main()
+{
+    ./bootstrap
+
+    build_all_features
+    build_nest_common
+}
+
+main "$@"
diff --git a/script/check-simulation-build-cmake b/script/check-simulation-build-cmake
new file mode 100755
index 0000000..a52c84c
--- /dev/null
+++ b/script/check-simulation-build-cmake
@@ -0,0 +1,62 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euxo pipefail
+
+readonly OT_BUILDDIR="$(pwd)/build"
+
+reset_source()
+{
+    rm -rf "$OT_BUILDDIR"
+}
+
+build_all_features()
+{
+    reset_source
+    "$(dirname "$0")"/cmake-build simulation
+    reset_source
+    "$(dirname "$0")"/cmake-build simulation -DOT_OTNS=ON -DOT_SIMULATION_VIRTUAL_TIME=ON
+}
+
+build_toranj()
+{
+    reset_source
+    top_builddir="$OT_BUILDDIR" ./tests/toranj/build.sh cmake
+
+    reset_source
+    top_builddir="$OT_BUILDDIR" ./tests/toranj/build.sh cmake-posix
+}
+
+main()
+{
+    build_all_features
+    build_toranj
+}
+
+main "$@"
diff --git a/script/check-size b/script/check-size
new file mode 100755
index 0000000..f1f0ab5
--- /dev/null
+++ b/script/check-size
@@ -0,0 +1,199 @@
+#!/bin/bash
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -euo pipefail
+
+readonly OT_TMP_DIR=/tmp/ot-size-report
+readonly OT_SHA_NEW=${GITHUB_SHA:-$(git rev-parse HEAD)}
+readonly OT_SHA_OLD="$(git cat-file -p "${OT_SHA_NEW}" | grep 'parent ' | head -n1 | cut -d' ' -f2)"
+readonly OT_REPORT_FILE=/tmp/size_report
+
+setup_arm_gcc_7()
+{
+    if arm-none-eabi-gcc --version | grep -q 'Arm Embedded Processors 7'; then
+        return 0
+    fi
+
+    (cd /tmp/ \
+        && wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2 \
+        && tar xjf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2)
+    export PATH=/tmp/gcc-arm-none-eabi-7-2018-q2-update/bin:$PATH
+
+    arm-none-eabi-gcc --version
+}
+
+setup()
+{
+    setup_arm_gcc_7
+}
+
+markdown_init()
+{
+    echo '|  name  |  branch  |  text  | data  | bss  | total |'
+    echo '| :----: | :------: | -----: | ----: | ---: | ----: |'
+}
+
+markdown_size()
+{
+    local name
+    name=$(basename "$1")
+
+    read -r -a size_old <<<"$(size "$1" | awk '{text+=$1} {bss+=$2} {data+=$3} {total+=$4} END {printf "%d %d %d %d", text, bss, data, total}')"
+    read -r -a size_new <<<"$(size "$2" | awk '{text+=$1} {bss+=$2} {data+=$3} {total+=$4} END {printf "%d %d %d %d", text, bss, data, total}')"
+
+    local -a size_diff
+
+    for i in 0 1 2 3; do
+        size_diff[$i]="$((size_new["$i"] - size_old["$i"]))"
+        if [[ ${size_diff["$i"]} != 0 ]]; then
+            size_diff["$i"]=$(printf '%+d' "${size_diff["$i"]}")
+        fi
+    done
+
+    echo "| ${name} | -${OT_SHA_OLD:0:7} | ${size_old[0]} | ${size_old[1]} | ${size_old[2]} | ${size_old[3]} |"
+    echo "|  | +${OT_SHA_NEW:0:7} | ${size_new[0]} | ${size_new[1]} | ${size_new[2]} | ${size_new[3]} |"
+    echo "|  | +/- | ${size_diff[0]} | ${size_diff[1]} | ${size_diff[2]} | ${size_diff[3]} |"
+}
+
+markdown()
+{
+    case "$1" in
+        init)
+            shift
+            markdown_init "$@" >"${OT_REPORT_FILE}"
+            ;;
+        size)
+            shift
+            markdown_size "$@" >>"${OT_REPORT_FILE}"
+            ;;
+        post)
+            mdv "${OT_REPORT_FILE}"
+            ;;
+    esac
+}
+
+size_nrf52840()
+{
+    local flags=(
+        "BORDER_AGENT=1"
+        "BORDER_ROUTER=1"
+        "CHANNEL_MANAGER=1"
+        "CHANNEL_MONITOR=1"
+        "CHILD_SUPERVISION=1"
+        "COAP=1"
+        "COAPS=1"
+        "COMMISSIONER=1"
+        "DHCP6_CLIENT=1"
+        "DHCP6_SERVER=1"
+        "DIAGNOSTIC=1"
+        "DISABLE_DOC=1"
+        "DNS_CLIENT=1"
+        "ECDSA=1"
+        "FULL_LOGS=1"
+        "JAM_DETECTION=1"
+        "JOINER=1"
+        "LINK_RAW=1"
+        "MAC_FILTER=1"
+        "MTD_NETDIAG=1"
+        "SERVICE=1"
+        "SLAAC=1"
+        "SNTP_CLIENT=1"
+        "TIME_SYNC=1"
+        "UDP_FORWARD=1"
+    )
+
+    rm -rf "${OT_TMP_DIR}"
+
+    # new commit
+    mkdir -p "${OT_TMP_DIR}/b"
+    git archive "${OT_SHA_NEW}" | tar x -C "${OT_TMP_DIR}/b"
+
+    (cd "${OT_TMP_DIR}/b" \
+        && ./bootstrap \
+        && make -f examples/Makefile-nrf52840 "${flags[@]}")
+
+    # old commit
+    if [[ "${GITHUB_ACTIONS+x}" ]]; then
+        git fetch --depth 1 --no-recurse-submodules origin "${OT_SHA_OLD}"
+    fi
+
+    mkdir -p "${OT_TMP_DIR}/a"
+    git archive "${OT_SHA_OLD}" | tar x -C "${OT_TMP_DIR}/a"
+    (cd "${OT_TMP_DIR}/a" \
+        && ./bootstrap \
+        && make -f examples/Makefile-nrf52840 "${flags[@]}")
+
+    local reporter
+
+    # not on GitHub Actions or not a pull request event
+    if [[ ! ${GITHUB_ACTIONS+x} || ! ${GITHUB_REF-} =~ ^refs/pull/[0-9]+/merge ]]; then
+        reporter=markdown
+    else
+        reporter=./size-report
+        curl -s --retry 5 "${SIZE_REPORT_URL}/bash" >size-report
+        chmod a+x size-report
+        export OT_SHA_NEW OT_SHA_OLD
+    fi
+
+    "${reporter}" init OpenThread
+
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/bin/ot-cli-ftd "${OT_TMP_DIR}"/b/output/nrf52840/bin/ot-cli-ftd
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/bin/ot-cli-mtd "${OT_TMP_DIR}"/b/output/nrf52840/bin/ot-cli-mtd
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/bin/ot-ncp-ftd "${OT_TMP_DIR}"/b/output/nrf52840/bin/ot-ncp-ftd
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/bin/ot-ncp-mtd "${OT_TMP_DIR}"/b/output/nrf52840/bin/ot-ncp-mtd
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/bin/ot-rcp "${OT_TMP_DIR}"/b/output/nrf52840/bin/ot-rcp
+
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/lib/libopenthread-cli-ftd.a "${OT_TMP_DIR}"/b/output/nrf52840/lib/libopenthread-cli-ftd.a
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/lib/libopenthread-cli-mtd.a "${OT_TMP_DIR}"/b/output/nrf52840/lib/libopenthread-cli-mtd.a
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/lib/libopenthread-ftd.a "${OT_TMP_DIR}"/b/output/nrf52840/lib/libopenthread-ftd.a
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/lib/libopenthread-mtd.a "${OT_TMP_DIR}"/b/output/nrf52840/lib/libopenthread-mtd.a
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/lib/libopenthread-ncp-ftd.a "${OT_TMP_DIR}"/b/output/nrf52840/lib/libopenthread-ncp-ftd.a
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/lib/libopenthread-ncp-mtd.a "${OT_TMP_DIR}"/b/output/nrf52840/lib/libopenthread-ncp-mtd.a
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/lib/libopenthread-rcp.a "${OT_TMP_DIR}"/b/output/nrf52840/lib/libopenthread-rcp.a
+    "${reporter}" size "${OT_TMP_DIR}"/a/output/nrf52840/lib/libopenthread-radio.a "${OT_TMP_DIR}"/b/output/nrf52840/lib/libopenthread-radio.a
+
+    "${reporter}" post
+}
+
+main()
+{
+    if [[ $# == 0 ]]; then
+        setup
+        size_nrf52840
+    elif [[ $1 == setup ]]; then
+        setup
+    elif [[ $1 == nrf52840 ]]; then
+        size_nrf52840
+    else
+        echo "USAGE: $0 [setup|nrf52840]"
+        exit 128
+    fi
+}
+
+main "$@"
diff --git a/script/clang-format b/script/clang-format
new file mode 100755
index 0000000..2624ece
--- /dev/null
+++ b/script/clang-format
@@ -0,0 +1,74 @@
+#!/bin/bash
+#
+#  Copyright (c) 2018, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+CLANG_FORMAT_VERSION="clang-format version 6.0"
+
+die()
+{
+    echo " *** ERROR: $*"
+    exit 1
+}
+
+# Aliases are not expanded when the shell is not interactive, unless the
+# expand_aliases shell option is set using shopt.
+shopt -s expand_aliases
+
+if command -v clang-format-6.0 >/dev/null; then
+    alias clang-format=clang-format-6.0
+elif command -v clang-format >/dev/null; then
+    case "$(clang-format --version)" in
+        "$CLANG_FORMAT_VERSION"*) ;;
+
+        *)
+            die "$(clang-format --version); clang-format 6.0 required"
+            ;;
+    esac
+else
+    die "clang-format 6.0 required"
+fi
+
+clang-format "$@" || die
+
+# ensure EOF newline
+REPLACE=no
+for arg; do
+    case $arg in
+        -i)
+            REPLACE=yes
+            ;;
+    esac
+done
+
+file=$arg
+
+[ $REPLACE != yes ] || {
+    [ -n "$(tail -c1 "$file")" ] && echo >>"$file"
+}
+
+exit 0
diff --git a/script/clang-format-check b/script/clang-format-check
new file mode 100755
index 0000000..9d1b101
--- /dev/null
+++ b/script/clang-format-check
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+#  Copyright (c) 2018, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# clang-format does not return a non-zero exit code.  This wrapper
+# exits with a non-zero exit code if clang-format outputs any
+# replacements.
+#
+
+set -euo pipefail
+
+die()
+{
+    echo " *** ERROR:  $*"
+    exit 1
+}
+
+# from `man diff`:
+# Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
+
+for file in "$@"; do
+    echo "Checking ${file}"
+    "$(dirname "$0")"/clang-format -style=file "${file}" | diff -u "${file}" - || die "${file} is not pretty."
+    [ -z "$(tail -c1 "${file}")" ] || die "${file} misses EOF newline."
+done
diff --git a/script/clang-format-check.sh b/script/clang-format-check.sh
deleted file mode 100755
index 1a2824d..0000000
--- a/script/clang-format-check.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-#
-#  Copyright (c) 2018, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-#
-# clang-format does not return a non-zero exit code.  This wrapper
-# exits with a non-zero exit code if clang-format outputs any
-# replacements.
-#
-
-set -x
-
-die() {
-    echo " *** ERROR: " $*
-    exit 1
-}
-
-# from `man diff`:
-# Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
-
-$(dirname "$0")/clang-format.sh -style=file $@  | diff -u $@ - || die
-
-for arg; do true; done
-file=$arg
-[ -n "$(tail -c1 $file)" ] && {
-    echo " *** ERROR: Missing EOF newline: " $file
-    exit 1
-}
-
-exit 0
diff --git a/script/clang-format.sh b/script/clang-format.sh
deleted file mode 100755
index 2b54a40..0000000
--- a/script/clang-format.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-#
-#  Copyright (c) 2018, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-CLANG_FORMAT_VERSION="clang-format version 6.0"
-
-die() {
-    echo " *** ERROR: " $*
-    exit 1
-}
-
-if which clang-format-6.0 > /dev/null; then
-    alias clang-format=clang-format-6.0
-elif which clang-format > /dev/null; then
-    case "$(clang-format --version)" in
-        "$CLANG_FORMAT_VERSION"*)
-            ;;
-        *)
-            die "$(clang-format --version); clang-format 6.0 required"
-            ;;
-    esac
-else
-    die "clang-format 6.0 required"
-fi
-
-clang-format $@ || die
-
-# ensure EOF newline
-REPLACE=no
-for arg
-do
-    case $arg in
-        -i)
-            REPLACE=yes
-            ;;
-    esac
-done
-
-file=$arg
-
-[ $REPLACE != yes ] || {
-    [ -n "$(tail -c1 $file)" ] && echo >> $file
-}
-
-exit 0
diff --git a/script/cmake-build b/script/cmake-build
new file mode 100755
index 0000000..3ceb657
--- /dev/null
+++ b/script/cmake-build
@@ -0,0 +1,169 @@
+#!/bin/bash
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+#  This script calls cmake and ninja to compile OpenThread for the given platform.
+#
+#  Compile with default build options:
+#
+#      script/cmake-build ${platform}
+#
+#  Compile with the specified build option enabled:
+#
+#      script/cmake-build ${platform} -D${option}=ON
+#
+#  Compile with the specified build option disabled that already enabled by default:
+#
+#      script/cmake-build ${platform} -D${option}=OFF
+#
+#  Compile with the specified ninja build target:
+#
+#      OT_CMAKE_NINJA_TARGET="ot-cli-ftd" script/cmake-build ${platform}
+#
+#  Compile with the specified build directory:
+#
+#      OT_CMAKE_BUILD_DIR="./build/temp"  script/cmake-build ${platform}
+#
+#  Examples:
+#
+#      script/cmake-build simulation
+#
+#      script/cmake-build simulation -DOT_FULL_LOGS=ON -DOT_CHANNEL_MANAGER=OFF
+#
+#      OT_CMAKE_NINJA_TARGET="ot-cli-mtd" OT_CMAKE_BUILD_DIR="./build/temp" script/cmake-build simulation -DOT_FULL_LOGS=ON -DOT_CHANNEL_MANAGER=OFF
+#
+
+set -euxo pipefail
+
+OT_CMAKE_NINJA_TARGET=${OT_CMAKE_NINJA_TARGET:-}
+
+readonly OT_SRCDIR="$(pwd)"
+readonly OT_PLATFORMS=(cc1352 cc2538 cc2650 cc2652 kw41z qpg6095 samr21 simulation posix)
+readonly OT_POSIX_SIM_COMMON_OPTIONS=(
+    "-DOT_BORDER_AGENT=ON"
+    "-DOT_BORDER_ROUTER=ON"
+    "-DOT_COAP=ON"
+    "-DOT_COAP_OBSERVE=ON"
+    "-DOT_COAPS=ON"
+    "-DOT_COMMISSIONER=ON"
+    "-DOT_CHANNEL_MANAGER=ON"
+    "-DOT_CHANNEL_MONITOR=ON"
+    "-DOT_CHILD_SUPERVISION=ON"
+    "-DOT_DHCP6_CLIENT=ON"
+    "-DOT_DHCP6_SERVER=ON"
+    "-DOT_DIAGNOSTIC=ON"
+    "-DOT_DNS_CLIENT=ON"
+    "-DOT_ECDSA=ON"
+    "-DOT_IP6_FRAGM=ON"
+    "-DOT_JAM_DETECTION=ON"
+    "-DOT_JOINER=ON"
+    "-DOT_LEGACY=ON"
+    "-DOT_MAC_FILTER=ON"
+    "-DOT_MTD_NETDIAG=ON"
+    "-DOT_REFERENCE_DEVICE=ON"
+    "-DOT_SERVICE=ON"
+    "-DOT_SNTP_CLIENT=ON"
+    "-DOT_COVERAGE=ON"
+    "-DOT_LOG_LEVEL_DYNAMIC=ON"
+    "-DOT_COMPILE_WARNING_AS_ERROR=ON"
+)
+
+die()
+{
+    echo " ** ERROR: Openthread CMake doesn't support platform \"$1\""
+    exit 1
+}
+
+build()
+{
+    local platform=$1
+    local builddir="${OT_CMAKE_BUILD_DIR:-build/${platform}}"
+    shift
+
+    mkdir -p "${builddir}"
+    cd "${builddir}"
+
+    cmake -GNinja "$@" "${OT_SRCDIR}"
+
+    if [[ -n ${OT_CMAKE_NINJA_TARGET[*]} ]]; then
+        ninja "${OT_CMAKE_NINJA_TARGET[@]}"
+    else
+        ninja
+    fi
+
+    cd "${OT_SRCDIR}"
+}
+
+main()
+{
+    if [[ $# == 0 ]]; then
+        echo "Please specify a platform: ${OT_PLATFORMS[*]}"
+        exit 1
+    fi
+
+    local platform="$1"
+    shift
+    local local_options=()
+    local options=(
+        "-DOT_PLATFORM=${platform}"
+        "-DOT_SLAAC=ON"
+    )
+
+    # Check if the platform supports cmake.
+    echo "${OT_PLATFORMS[@]}" | grep -wq "${platform}" || die "${platform}"
+
+    case "${platform}" in
+        posix)
+            local_options+=(
+                "-DOT_LOG_OUTPUT=PLATFORM_DEFINED"
+                "-DOT_POSIX_MAX_POWER_TABLE=ON"
+            )
+            options+=("${OT_POSIX_SIM_COMMON_OPTIONS[@]}" "${local_options[@]}")
+            ;;
+        simulation)
+            local_options=("-DOT_LINK_RAW=ON")
+            options+=("${OT_POSIX_SIM_COMMON_OPTIONS[@]}" "${local_options[@]}")
+            ;;
+        cc2650)
+            OT_CMAKE_NINJA_TARGET=("ot-cli-mtd" "ot-ncp-mtd")
+            options+=("-DCMAKE_TOOLCHAIN_FILE=examples/platforms/${platform}/arm-none-eabi.cmake" "-DCMAKE_BUILD_TYPE=Release")
+            ;;
+        cc1352 | cc2652 | samr21 | qpg6095)
+            options+=("-DCMAKE_TOOLCHAIN_FILE=examples/platforms/${platform}/arm-none-eabi.cmake" "-DCMAKE_BUILD_TYPE=Release")
+            ;;
+        *)
+            options+=("-DCMAKE_TOOLCHAIN_FILE=examples/platforms/${platform}/arm-none-eabi.cmake")
+            ;;
+    esac
+
+    options+=("$@")
+    build "${platform}" "${options[@]}"
+}
+
+main "$@"
diff --git a/script/make-pretty b/script/make-pretty
index f254ee1..096f887 100755
--- a/script/make-pretty
+++ b/script/make-pretty
@@ -27,32 +27,175 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-set -e -x -o pipefail
+#
+# The script to check or format source code of OpenThread.
+#
+# Format c/c++, markdown, python, and shell:
+#
+#     script/make-pretty
+#
+# Format c/c++ only:
+#
+#     script/make-pretty clang
+#
+# Format markdown only:
+#
+#     script/make-pretty markdown
+#
+# Format python only:
+#
+#     script/make-pretty python
+#
+# Format shell only:
+#
+#     script/make-pretty shell
+#
+# Check only:
+#
+#     script/make-pretty check clang
+#     script/make-pretty check markdown
+#     script/make-pretty check python
+#     script/make-pretty check shell
+#
 
-readonly TMP_DIR="/tmp/ot-make-pretty-$(date +%Y%m%d%H%M%S)"
-readonly SRC_DIR="$PWD"
+set -euo pipefail
 
-at_exit()
+readonly OT_BUILD_JOBS=$(getconf _NPROCESSORS_ONLN)
+readonly OT_EXCLUDE_DIRS=(third_party doc/site)
+
+readonly OT_CLANG_SOURCES=('*.c' '*.cc' '*.cpp' '*.h' '*.hpp')
+readonly OT_MARKDOWN_SOURCES=('*.md')
+readonly OT_PYTHON_SOURCES=('*.py')
+
+do_clang_format()
 {
-    EXIT_CODE=$?
+    echo -e '====================='
+    echo -e '     format c/c++'
+    echo -e '====================='
 
-    [[ ! -d "${TMP_DIR}" ]] || rm -rf "${TMP_DIR}"
-    exit $EXIT_CODE
+    git ls-files "${OT_CLANG_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n3 -P"$OT_BUILD_JOBS" script/clang-format -style=file -i -verbose
 }
 
-make_pretty()
+do_clang_check()
 {
-    ./bootstrap
-    mkdir "${TMP_DIR}"
-    cd "${TMP_DIR}"
-    "${SRC_DIR}/configure"
-    make pretty
+    echo -e '====================='
+    echo -e '     check c/c++'
+    echo -e '====================='
+
+    git ls-files "${OT_CLANG_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n3 -P"$OT_BUILD_JOBS" script/clang-format-check
+}
+
+do_markdown_format()
+{
+    echo -e '======================'
+    echo -e '     format markdown'
+    echo -e '======================'
+
+    git ls-files "${OT_MARKDOWN_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n10 -P"$OT_BUILD_JOBS" npx prettier@2.0.4 --write
+}
+
+do_markdown_check()
+{
+    echo -e '======================'
+    echo -e '     check markdown'
+    echo -e '======================'
+
+    git ls-files "${OT_MARKDOWN_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n10 -P"$OT_BUILD_JOBS" npx prettier@2.0.4 --check
+}
+
+do_python_format()
+{
+    echo -e '======================'
+    echo -e '     format python'
+    echo -e '======================'
+
+    git ls-files "${OT_PYTHON_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n10 -P"$OT_BUILD_JOBS" python3 -m yapf --verbose --style google -ipr
+}
+
+do_python_check()
+{
+    echo -e '====================='
+    echo -e '     check python'
+    echo -e '====================='
+
+    git ls-files "${OT_PYTHON_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n10 -P"$OT_BUILD_JOBS" python3 -m yapf --verbose --style google -dpr
+}
+
+do_shell_format()
+{
+    echo -e '====================='
+    echo -e '     format shell'
+    echo -e '====================='
+
+    shfmt -f . | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n10 -P"$OT_BUILD_JOBS" shfmt -i 4 -bn -ci -fn -s -w
+}
+
+do_shell_check()
+{
+    echo -e '====================='
+    echo -e '     check shell'
+    echo -e '====================='
+
+    shfmt -f . | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n10 -P"$OT_BUILD_JOBS" shfmt -i 4 -bn -ci -fn -s -d
+
+    shfmt -f . | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \
+        | xargs -n10 -P"$OT_BUILD_JOBS" shellcheck
+}
+
+do_check()
+{
+    if [ $# == 0 ]; then
+        do_clang_check
+        do_markdown_check
+        do_python_check
+        do_shell_check
+    elif [ "$1" == 'clang' ]; then
+        do_clang_check
+    elif [ "$1" == 'markdown' ]; then
+        do_markdown_check
+    elif [ "$1" == 'python' ]; then
+        do_python_check
+    elif [ "$1" == 'shell' ]; then
+        do_shell_check
+    else
+        echo >&2 "Unsupported check: $1. Supported: clang, markdown, python, shell"
+        # 128 for Invalid arguments
+        exit 128
+    fi
 }
 
 main()
 {
-    trap at_exit INT TERM EXIT
-    make_pretty
+    if [ $# == 0 ]; then
+        do_clang_format
+        do_markdown_format
+        do_python_format
+        do_shell_format
+    elif [ "$1" == 'clang' ]; then
+        do_clang_format
+    elif [ "$1" == 'markdown' ]; then
+        do_markdown_format
+    elif [ "$1" == 'python' ]; then
+        do_python_format
+    elif [ "$1" == 'shell' ]; then
+        do_shell_format
+    elif [ "$1" == 'check' ]; then
+        shift
+        do_check "$@"
+    else
+        echo >&2 "Unsupported action: $1. Supported: clang, markdown, python, shell"
+        # 128 for Invalid arguments
+        exit 128
+    fi
+
 }
 
 main "$@"
diff --git a/script/pystyle.cfg b/script/pystyle.cfg
deleted file mode 100644
index dd64ac1..0000000
--- a/script/pystyle.cfg
+++ /dev/null
@@ -1,16 +0,0 @@
-[flake8]
-# it's not a bug that we aren't using all of hacking, ignore:
-# E203: White space before ':' (see #python#black#315).
-# W503: Line break occurred before a binary operator (see #python#black#README.md).
-ignore = E203, W503
-
-# relax the length limitation for now.
-max-line-length = 119
-max-doc-length = 119
-
-# Print the source code generating the error/warning in question.
-show_source = True
-show-source = True
-
-# print the total number of errors.
-count = True
diff --git a/script/test b/script/test
index 5fd6c44..a3bad2d 100755
--- a/script/test
+++ b/script/test
@@ -30,45 +30,251 @@
 #      This file runs various tests of OpenThread.
 #
 
-set -e
-set -o pipefail
+set -euo pipefail
 
-readonly SYSTEM_TRIPLET="$(third_party/nlbuild-autotools/repo/third_party/autoconf/config.guess | sed -e 's/[[:digit:].]*$//g')"
-export top_builddir="build/${SYSTEM_TRIPLET}"
+readonly OT_BUILDDIR="$(pwd)/build"
+readonly OT_SRCDIR="$(pwd)"
 
-do_build() {
-    if [[ -n "${RADIO_DEVICE}" && "${VIRTUAL_TIME}" = 1 ]]; then
-        VIRTUAL_TIME_UART=1 make -f examples/Makefile-posix
-    else
-        make -f examples/Makefile-posix
+readonly COLOR_PASS='\033[0;32m'
+readonly COLOR_FAIL='\033[0;31m'
+readonly COLOR_NONE='\033[0m'
+
+readonly NODE_MODE="${NODE_MODE:-standalone}"
+readonly NODE_TYPE="${NODE_TYPE:-sim}"
+readonly OT_NATIVE_IP="${OT_NATIVE_IP:-0}"
+readonly THREAD_VERSION="${THREAD_VERSION:-1.1}"
+readonly VERBOSE="${VERBOSE:-0}"
+
+build_simulation()
+{
+    local version="$1"
+    local options=("-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON")
+
+    if [[ ${version} == "1.2" ]]; then
+        options+=("-DOT_DUA=ON")
     fi
 
-    if [[ -n "${RADIO_DEVICE}" ]]; then
-        make -f src/posix/Makefile-posix
+    if [[ ${VIRTUAL_TIME} == 1 ]]; then
+        options+=("-DOT_SIMULATION_VIRTUAL_TIME=ON")
+
+        if [[ ${NODE_MODE} == "rcp" ]]; then
+            options+=("-DOT_SIMULATION_VIRTUAL_TIME_UART=ON")
+        fi
+
+    fi
+
+    if [[ ${version} == "1.2" ]]; then
+        options+=("-DOT_CSL_RECEIVER=ON")
+    fi
+
+    if [[ ${ot_extra_options[*]+x} ]]; then
+        options+=("${ot_extra_options[@]}")
+    fi
+
+    OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/cmake/openthread-simulation-${version}" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}"
+
+    if [[ ${version} == "1.2" ]]; then
+
+        options+=("-DOT_BACKBONE_ROUTER=ON")
+
+        OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/cmake/openthread-simulation-${version}-bbr" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}"
+
     fi
 }
 
-do_clean() {
-    rm -rfv "build/${SYSTEM_TRIPLET}" "build/posix/${SYSTEM_TRIPLET}"
+build_posix()
+{
+    local version="$1"
+    local options=("-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON")
+
+    if [[ ${version} == "1.2" ]]; then
+        options+=("-DOT_DUA=ON")
+    fi
+
+    if [[ ${VIRTUAL_TIME} == 1 ]]; then
+        options+=("-DOT_POSIX_VIRTUAL_TIME=ON")
+    fi
+
+    if [[ ${OT_NATIVE_IP} == 1 ]]; then
+        options+=("-DOT_PLATFORM_UDP=ON" "-DOT_PLATFORM_NETIF=ON")
+    fi
+
+    if [[ ${ot_extra_options[*]+x} ]]; then
+        options+=("${ot_extra_options[@]}")
+    fi
+
+    OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/cmake/openthread-posix-${version}" "${OT_SRCDIR}"/script/cmake-build posix "${options[@]}"
+
+    if [[ ${version} == "1.2" ]]; then
+
+        options+=("-DOT_BACKBONE_ROUTER=ON")
+
+        OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/cmake/openthread-posix-${version}-bbr" "${OT_SRCDIR}"/script/cmake-build posix "${options[@]}"
+    fi
 }
 
-do_cert() {
+do_build()
+{
+    build_simulation "${THREAD_VERSION}"
+
+    if [[ ${NODE_MODE} == "rcp" ]]; then
+        build_posix "${THREAD_VERSION}"
+    fi
+
+    # Extra 1.1 build for 1.2 tests
+    if [[ ${THREAD_VERSION} == "1.2" ]]; then
+        build_simulation 1.1
+
+        if [[ ${NODE_MODE} == "rcp" ]]; then
+            build_posix 1.1
+        fi
+    fi
+}
+
+do_clean()
+{
+    rm -rfv "${OT_BUILDDIR}" || sudo rm -rfv "${OT_BUILDDIR}"
+}
+
+do_unit()
+{
+    local builddir="${OT_BUILDDIR}/cmake/openthread-simulation-${THREAD_VERSION}"
+    if [[ ! -d ${builddir} ]]; then
+        echo "Cannot find build directory!"
+        exit 1
+    fi
+
+    cd "${builddir}"
+    ninja test
+}
+
+do_cert()
+{
+    export top_builddir="${OT_BUILDDIR}/cmake/openthread-simulation-${THREAD_VERSION}"
+
+    if [[ ${THREAD_VERSION} == "1.2" ]]; then
+        export top_builddir_1_1="${OT_BUILDDIR}/cmake/openthread-simulation-1.1"
+        export top_builddir_1_2_bbr="${OT_BUILDDIR}/cmake/openthread-simulation-1.2-bbr"
+    fi
+
     [[ ! -d tmp ]] || rm -rvf tmp
     PYTHONUNBUFFERED=1 "$1"
 }
 
-print_usage() {
+do_cert_suite()
+{
+    export top_builddir="${OT_BUILDDIR}/cmake/openthread-simulation-${THREAD_VERSION}"
+
+    if [[ ${THREAD_VERSION} == "1.2" ]]; then
+        export top_builddir_1_1="${OT_BUILDDIR}/cmake/openthread-simulation-1.1"
+        export top_builddir_1_2_bbr="${OT_BUILDDIR}/cmake/openthread-simulation-1.2-bbr"
+    fi
+
+    local pass_count=0
+    local fail_count=0
+
+    [[ ! -f fail.log ]] || rm fail.log
+
+    for test_case in "$@"; do
+        rm -rf tmp || sudo rm -rf tmp
+        if "${test_case}" &>test.log; then
+            echo -e "${COLOR_PASS}PASS${COLOR_NONE} ${test_case}"
+            pass_count=$((pass_count + 1))
+        else
+            echo -e "${COLOR_FAIL}FAIL${COLOR_NONE} ${test_case}"
+            fail_count=$((fail_count + 1))
+            {
+                echo "=============================="
+                echo "!!! FAIL:${test_case}"
+                echo "=============================="
+                cat test.log
+            } >>fail.log
+        fi
+    done
+
+    echo "=================================="
+    echo "         Test Summary"
+    echo "=================================="
+    echo "# TOTAL: $((pass_count + fail_count))"
+    echo "# PASS: ${pass_count}"
+    echo "# FAIL: ${fail_count}"
+
+    if [[ ${fail_count} -gt 0 ]]; then
+        tr -dc '[:print:]\r\n\t' <fail.log
+        exit 1
+    else
+        exit 0
+    fi
+}
+
+do_expect()
+{
+    local ot_command
+    local rcp_command=
+    local test_patterns
+
+    if [[ ${NODE_MODE} == rcp ]]; then
+        ot_command="${OT_CLI_PATH}"
+        rcp_command="${RADIO_DEVICE}"
+        if [[ ${OT_NATIVE_IP} == 1 ]]; then
+            test_patterns=(-name 'tun-*.exp')
+        else
+            test_patterns=(-name 'posix-*.exp' -o -name 'cli-*.exp')
+        fi
+    else
+        ot_command="${OT_BUILDDIR}/cmake/openthread-simulation-${THREAD_VERSION}/examples/apps/cli/ot-cli-ftd"
+        test_patterns=(-name 'cli-*.exp' -o -name 'simulation-*.exp')
+    fi
+
+    local log_file="tmp/log_expect"
+    while read -r script; do
+        sudo rm -rf tmp
+        mkdir tmp
+        {
+            if [[ ${OT_NATIVE_IP} == 1 ]]; then
+                OT_COMMAND="${ot_command}" RCP_COMMAND="${rcp_command}" sudo -E expect -df "${script}" 2>"${log_file}"
+            else
+                OT_COMMAND="${ot_command}" RCP_COMMAND="${rcp_command}" expect -df "${script}" 2>"${log_file}"
+            fi
+        } || {
+            local exit_code=$?
+            cat "${log_file}" >&2
+            echo -e "${COLOR_FAIL}FAIL${COLOR_NONE} ${script}"
+            exit "${exit_code}"
+        }
+        if [[ ${VERBOSE} == 1 ]]; then
+            cat "${log_file}" >&2
+        fi
+        echo -e "${COLOR_PASS}PASS${COLOR_NONE} ${script}"
+    done < <(
+        if [[ $# != 0 ]]; then
+            for script in "$@"; do echo ${script}; done
+        else
+            find tests/scripts/expect -type f -executable \( "${test_patterns[@]}" \)
+        fi
+    )
+
+    exit 0
+}
+
+print_usage()
+{
     echo "USAGE: [ENVIRONMENTS] $0 COMMANDS
 
 ENVIRONMENTS:
     NODE_TYPE       'sim' for CLI, 'ncp-sim' for NCP. The default is 'sim'.
-    NODE_MODE       'transceiver' for transceiver mode, otherwise for standalone mode. The default is standalone mode.
-    VIRTUAL_TIME    1 for virtual time, otherwise real time. The default is 1
+    NODE_MODE       'rcp' for RCP mode, otherwise for standalone mode. The default is standalone mode.
+    VERBOSE         1 to build or test verbosely. The default is 0.
+    VIRTUAL_TIME    1 for virtual time, otherwise real time. The default is 1.
+    THREAD_VERSION  1.1 for Thread 1.1 stack, 1.2 for Thread 1.2 stack. The default is 1.1.
 
 COMMANDS:
     clean           Clean built files to prepare for new build.
     build           Build project for running tests. This can be used to rebuild the project for changes.
     cert            Run a single thread-cert test. ENVIRONMENTS should be the same as those given to build or update.
+    cert_suite      Run a batch of thread-cert tests and summarize the test results. Only echo logs for failing tests.
+    unit            Run all the unit tests. This should be called after simulation is built.
+    expect          Run expect tests.
     help            Print this help.
 
 EXAMPLES:
@@ -81,38 +287,107 @@
     NODE_TYPE=ncp-sim $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
 
     # Test CLI with radio only
-    NODE_MODE=transceiver $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
-    NODE_MODE=transceiver $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
+    NODE_MODE=rcp $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
+    NODE_MODE=rcp $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
 
     # Test CLI with real time
     VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
     VIRTUAL_TIME=0 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
-"
 
-    exit $1
+    # Test Thread 1.2 with real time
+    THREAD_VERSION=1.2 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_router_5_1_1.py
+    THREAD_VERSION=1.2 VIRTUAL_TIME=0 $0 clean build cert_suite tests/scripts/thread-cert/v1_2_*
+
+    # Run a single expect test
+    $0 clean build expect tests/scripts/expect/cli-log-level.exp
+
+    # Run all expect tests
+    $0 clean build expect
+    "
+
+    exit "$1"
+}
+
+do_package()
+{
+    local builddir
+    local options=("-DCMAKE_BUILD_TYPE=Release")
+
+    if [[ ${ot_extra_options[*]+x} ]]; then
+        options+=("${ot_extra_options[@]}")
+    fi
+
+    builddir="${OT_BUILDDIR}/cmake/openthread-sim"
+    OT_CMAKE_NINJA_TARGET="package" OT_CMAKE_BUILD_DIR="${builddir}" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}"
+    ls "${builddir}"/openthread-simulation-*.deb
+
+    builddir="${OT_BUILDDIR}/cmake/openthread-host"
+    OT_CMAKE_NINJA_TARGET="package" OT_CMAKE_BUILD_DIR="${builddir}" "${OT_SRCDIR}"/script/cmake-build posix "${options[@]}"
+    ls "${builddir}"/openthread-standalone-*.deb
+
+    builddir="${OT_BUILDDIR}/cmake/openthread-daemon"
+    OT_CMAKE_NINJA_TARGET="package" OT_CMAKE_BUILD_DIR="${builddir}" "${OT_SRCDIR}"/script/cmake-build posix -DOT_DAEMON=ON -DOT_PLATFORM_NETIF=ON -DOT_PLATFORM_UDP=ON "${options[@]}"
+    ls "${builddir}"/openthread-daemon-*.deb
+}
+
+envsetup()
+{
+    if [[ ${NODE_MODE} == 'rcp' ]]; then
+        export RADIO_DEVICE="${OT_BUILDDIR}/cmake/openthread-simulation-${THREAD_VERSION}/examples/apps/ncp/ot-rcp"
+        export OT_CLI_PATH="${OT_BUILDDIR}/cmake/openthread-posix-${THREAD_VERSION}/src/posix/ot-cli"
+        export OT_NCP_PATH="${OT_BUILDDIR}/cmake/openthread-posix-${THREAD_VERSION}/src/posix/ot-ncp"
+
+        if [[ ${THREAD_VERSION} == "1.2" ]]; then
+            export RADIO_DEVICE_1_1="${OT_BUILDDIR}/cmake/openthread-simulation-1.1/examples/apps/ncp/ot-rcp"
+            export OT_CLI_PATH_1_1="${OT_BUILDDIR}/cmake/openthread-posix-1.1/src/posix/ot-cli"
+            export OT_NCP_PATH_1_1="${OT_BUILDDIR}/cmake/openthread-posix-1.1/src/posix/ot-ncp"
+            export OT_CLI_PATH_1_2_BBR="${OT_BUILDDIR}/cmake/openthread-posix-1.2-bbr/src/posix/ot-cli"
+            export OT_NCP_PATH_1_2_BBR="${OT_BUILDDIR}/cmake/openthread-posix-1.2-bbr/src/posix/ot-ncp"
+        fi
+    fi
+
+    if [[ ! ${VIRTUAL_TIME+x} ]]; then
+        # All expect tests only works in real time mode.
+        VIRTUAL_TIME=1
+        for arg in "$@"; do
+            if [[ $arg == expect ]]; then
+                VIRTUAL_TIME=0
+                break
+            fi
+        done
+    fi
+
+    readonly VIRTUAL_TIME
+    export NODE_TYPE VIRTUAL_TIME
+
+    # CMake always works in verbose mode if VERBOSE exists in environments.
+    if [[ ${VERBOSE} == 1 ]]; then
+        export VERBOSE
+    else
+        export -n VERBOSE
+    fi
+
+    if [[ ${OT_OPTIONS+x} ]]; then
+        read -r -a ot_extra_options <<<"${OT_OPTIONS}"
+    else
+        ot_extra_options=()
+    fi
 }
 
 main()
 {
-    export NODE_TYPE="${NODE_TYPE:-sim}"
-    export VERBOSE="${VERBOSE:-1}"
-    export VIRTUAL_TIME="${VIRTUAL_TIME:-1}"
+    envsetup "$@"
 
-    if [[ "${NODE_MODE}" = 'transceiver' ]] ; then
-        export RADIO_DEVICE="build/${SYSTEM_TRIPLET}/examples/apps/ncp/ot-rcp"
-        export OT_CLI_PATH="build/posix/${SYSTEM_TRIPLET}/src/posix/ot-cli"
-        export OT_NCP_PATH="build/posix/${SYSTEM_TRIPLET}/src/posix/ot-ncp"
-    fi
-
-    if [[ -z "$1" ]]; then
+    if [[ -z $1 ]]; then
         print_usage 1
     fi
 
-    [[ -n "${RADIO_DEVICE}" ]] && echo "Using transceiver mode" || echo "Using standalone mode"
-    [[ "${NODE_TYPE}" = "ncp-sim" ]] && echo "Using NCP node" || echo "Using CLI node"
-    [[ "${VIRTUAL_TIME}" = 1 ]] && echo "Using virtual time" || echo "Using real time"
+    [[ ${NODE_MODE} == "rcp" ]] && echo "Using rcp mode" || echo "Using standalone mode"
+    [[ ${NODE_TYPE} == "ncp-sim" ]] && echo "Using NCP node" || echo "Using CLI node"
+    [[ ${VIRTUAL_TIME} == 1 ]] && echo "Using virtual time" || echo "Using real time"
+    [[ ${THREAD_VERSION} == "1.2" ]] && echo "Using Thread 1.2 stack" || echo "Using Thread 1.1 stack"
 
-    while [[ -n "$1" ]]; do
+    while [[ $# != 0 ]]; do
         case "$1" in
             clean)
                 do_clean
@@ -124,9 +399,23 @@
                 shift
                 do_cert "$1"
                 ;;
+            cert_suite)
+                shift
+                do_cert_suite "$@"
+                ;;
+            unit)
+                do_unit
+                ;;
             help)
                 print_usage
                 ;;
+            package)
+                do_package
+                ;;
+            expect)
+                shift
+                do_expect "$@"
+                ;;
         esac
         shift
     done
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 71a6143..9b6bc02 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,4 +28,5 @@
 
 add_subdirectory(cli)
 add_subdirectory(core)
+add_subdirectory(lib)
 add_subdirectory(ncp)
diff --git a/src/Makefile.am b/src/Makefile.am
index 9107ec9..b06a7e4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,6 +33,7 @@
 DIST_SUBDIRS                            = \
     core                                  \
     cli                                   \
+    lib                                   \
     ncp                                   \
     posix                                 \
     $(NULL)
@@ -41,6 +42,7 @@
 
 SUBDIRS                                 = \
     core                                  \
+    lib                                   \
     $(NULL)
 
 if OPENTHREAD_ENABLE_CLI
@@ -51,17 +53,8 @@
 SUBDIRS                                += ncp
 endif
 
-if OPENTHREAD_PLATFORM_POSIX_APP
+if OPENTHREAD_PLATFORM_POSIX
 SUBDIRS                                += posix
 endif
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    cli                                   \
-    core                                  \
-    ncp                                   \
-    posix                                 \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt
index 33c9d9e..2dbbde3 100644
--- a/src/cli/CMakeLists.txt
+++ b/src/cli/CMakeLists.txt
@@ -29,18 +29,30 @@
 add_library(openthread-cli-ftd)
 add_library(openthread-cli-mtd)
 
+set_target_properties(
+    openthread-cli-ftd openthread-cli-mtd
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
 target_compile_definitions(openthread-cli-ftd PRIVATE
-    ${OT_PRIVATE_DEFINES}
     OPENTHREAD_FTD=1
 )
 
 target_compile_definitions(openthread-cli-mtd PRIVATE
-    ${OT_PRIVATE_DEFINES}
     OPENTHREAD_MTD=1
 )
 
+target_compile_options(openthread-cli-ftd PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_compile_options(openthread-cli-mtd PRIVATE
+    ${OT_CFLAGS}
+)
+
 set(COMMON_INCLUDES
-    ${OT_PRIVATE_INCLUDES}
     ${PROJECT_SOURCE_DIR}/src
     ${PROJECT_SOURCE_DIR}/src/core
 )
@@ -63,3 +75,19 @@
 
 target_sources(openthread-cli-ftd PRIVATE ${COMMON_SOURCES})
 target_sources(openthread-cli-mtd PRIVATE ${COMMON_SOURCES})
+
+target_link_libraries(openthread-cli-ftd
+    PUBLIC
+        openthread-ftd
+    PRIVATE
+        ${OT_MBEDTLS}
+        ot-config
+)
+
+target_link_libraries(openthread-cli-mtd
+    PUBLIC
+        openthread-mtd
+    PRIVATE
+        ${OT_MBEDTLS}
+        ot-config
+)
diff --git a/src/cli/README.md b/src/cli/README.md
index 98b54a4..cbe631c 100644
--- a/src/cli/README.md
+++ b/src/cli/README.md
@@ -1,82 +1,222 @@
 # OpenThread CLI Reference
 
-The OpenThread CLI exposes configuration and management APIs via a
-command line interface. Use the CLI to play with OpenThread, which
-can also be used with additional application code. The
-OpenThread test scripts use the CLI to execute test cases.
+The OpenThread CLI exposes configuration and management APIs via a command line interface. Use the CLI to play with OpenThread, which can also be used with additional application code. The OpenThread test scripts use the CLI to execute test cases.
+
+## Separator and escaping characters
+
+The whitespace character (`' '`) is used to delimit the command name and the different arguments, together with tab (`'\t'`) and new line characters (`'\r'`, `'\n'`).
+
+Some arguments might require to accept whitespaces on them. For those cases the backslash character (`'\'`) can be used to escape separators or the backslash itself.
+
+Example:
+
+```bash
+> networkname Test\ Network
+Done
+> networkname
+Test Network
+Done
+>
+```
 
 ## OpenThread Command List
 
-* [bufferinfo](#bufferinfo)
-* [channel](#channel)
-* [child](#child-list)
-* [childip](#childip)
-* [childmax](#childmax)
-* [childtimeout](#childtimeout)
-* [coap](README_COAP.md)
-* [coaps](README_COAPS.md)
-* [commissioner](README_COMMISSIONER.md)
-* [contextreusedelay](#contextreusedelay)
-* [counters](#counters)
-* [dataset](README_DATASET.md)
-* [delaytimermin](#delaytimermin)
-* [diag](#diag)
-* [discover](#discover-channel)
-* [dns](#dns-resolve-hostname-dns-server-ip-dns-server-port)
-* [eidcache](#eidcache)
-* [eui64](#eui64)
-* [extaddr](#extaddr)
-* [extpanid](#extpanid)
-* [factoryreset](#factoryreset)
-* [ifconfig](#ifconfig)
-* [ipaddr](#ipaddr)
-* [ipmaddr](#ipmaddr)
-* [joiner](README_JOINER.md)
-* [joinerport](#joinerport-port)
-* [keysequence](#keysequence-counter)
-* [leaderdata](#leaderdata)
-* [leaderpartitionid](#leaderpartitionid)
-* [leaderweight](#leaderweight)
-* [linkquality](#linkquality-extaddr)
-* [logfilename](#logfilename-filename)
-* [mac](#mac-retries-direct)
-* [macfilter](#macfilter)
-* [masterkey](#masterkey)
-* [mode](#mode)
-* [neighbor](#neighbor-list)
-* [netdataregister](#netdataregister)
-* [netdatashow](#netdatashow)
-* [networkdiagnostic](#networkdiagnostic-get-addr-type-)
-* [networkidtimeout](#networkidtimeout)
-* [networkname](#networkname)
-* [networktime](#networktime)
-* [panid](#panid)
-* [parent](#parent)
-* [parentpriority](#parentpriority)
-* [ping](#ping-ipaddr-size-count-interval-hoplimit)
-* [pollperiod](#pollperiod-pollperiod)
-* [prefix](#prefix-add-prefix-pvdcsr-prf)
-* [promiscuous](#promiscuous)
-* [releaserouterid](#releaserouterid-routerid)
-* [reset](#reset)
-* [rloc16](#rloc16)
-* [route](#route-add-prefix-s-prf)
-* [router](#router-list)
-* [routerdowngradethreshold](#routerdowngradethreshold)
-* [routereligible](#routereligible)
-* [routerselectionjitter](#routerselectionjitter)
-* [routerupgradethreshold](#routerupgradethreshold)
-* [scan](#scan-channel)
-* [service](#service)
-* [singleton](#singleton)
-* [sntp](#sntp-query-sntp-server-ip-sntp-server-port)
-* [state](#state)
-* [thread](#thread-start)
-* [txpower](#txpower)
-* [version](#version)
+- [bbr](#bbr)
+- [bufferinfo](#bufferinfo)
+- [channel](#channel)
+- [child](#child-list)
+- [childip](#childip)
+- [childmax](#childmax)
+- [childtimeout](#childtimeout)
+- [coap](README_COAP.md)
+- [coaps](README_COAPS.md)
+- [commissioner](README_COMMISSIONER.md)
+- [contextreusedelay](#contextreusedelay)
+- [counters](#counters)
+- [dataset](README_DATASET.md)
+- [delaytimermin](#delaytimermin)
+- [diag](#diag)
+- [discover](#discover-channel)
+- [dns](#dns-resolve-hostname-dns-server-ip-dns-server-port)
+- [domainname](#domainname)
+- [dua](#dua-iid)
+- [eidcache](#eidcache)
+- [eui64](#eui64)
+- [extaddr](#extaddr)
+- [extpanid](#extpanid)
+- [factoryreset](#factoryreset)
+- [ifconfig](#ifconfig)
+- [ipaddr](#ipaddr)
+- [ipmaddr](#ipmaddr)
+- [joiner](README_JOINER.md)
+- [joinerport](#joinerport-port)
+- [keysequence](#keysequence-counter)
+- [leaderdata](#leaderdata)
+- [leaderpartitionid](#leaderpartitionid)
+- [leaderweight](#leaderweight)
+- [linkquality](#linkquality-extaddr)
+- [log](#log-filename-filename)
+- [mac](#mac-retries-direct)
+- [macfilter](#macfilter)
+- [masterkey](#masterkey)
+- [mode](#mode)
+- [neighbor](#neighbor-list)
+- [netdataregister](#netdataregister)
+- [netdatashow](#netdatashow)
+- [netstat](#netstat)
+- [networkdiagnostic](#networkdiagnostic-get-addr-type-)
+- [networkidtimeout](#networkidtimeout)
+- [networkname](#networkname)
+- [networktime](#networktime)
+- [panid](#panid)
+- [parent](#parent)
+- [parentpriority](#parentpriority)
+- [ping](#ping-ipaddr-size-count-interval-hoplimit)
+- [pollperiod](#pollperiod-pollperiod)
+- [preferrouterid](#preferrouterid-routerid)
+- [prefix](#prefix-add-prefix-padcrosnD-prf)
+- [promiscuous](#promiscuous)
+- [pskc](#pskc--p-keypassphrase)
+- [rcp](#rcp)
+- [releaserouterid](#releaserouterid-routerid)
+- [reset](#reset)
+- [rloc16](#rloc16)
+- [route](#route-add-prefix-s-prf)
+- [router](#router-list)
+- [routerdowngradethreshold](#routerdowngradethreshold)
+- [routereligible](#routereligible)
+- [routerselectionjitter](#routerselectionjitter)
+- [routerupgradethreshold](#routerupgradethreshold)
+- [scan](#scan-channel)
+- [service](#service)
+- [singleton](#singleton)
+- [sntp](#sntp-query-sntp-server-ip-sntp-server-port)
+- [state](#state)
+- [thread](#thread-start)
+- [txpower](#txpower)
+- [version](#version)
 
 ## OpenThread Command Details
 
+### bbr
+
+Show current Primary Backbone Router information for Thread 1.2 device.
+
+```bash
+> bbr
+BBR Primary:
+server16: 0xE400
+seqno:    10
+delay:    120 secs
+timeout:  300 secs
+Done
+```
+
+```bash
+> bbr
+BBR Primary: None
+Done
+```
+
+### bbr state
+
+Show local Backbone state ([`Disabled`,`Primary`, `Secondary`]) for Thread 1.2 FTD.
+
+`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
+
+```bash
+> bbr state
+Disabled
+Done
+
+> bbr state
+Primary
+Done
+
+> bbr state
+Secondary
+Done
+```
+
+### bbr enable
+
+Enable Backbone Router Service for Thread 1.2 FTD. `SRV_DATA.ntf` would be triggerred for attached device if there is no Backbone Router Service in Thread Network Data.
+
+`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
+
+```bash
+> bbr enable
+Done
+```
+
+### bbr disable
+
+Disable Backbone Router Service for Thread 1.2 FTD. `SRV_DATA.ntf` would be triggerred if Backbone Router is Primary state. o `OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
+
+```bash
+> bbr disable
+Done
+```
+
+### bbr register
+
+Register Backbone Router Service for Thread 1.2 FTD. `SRV_DATA.ntf` would be triggerred for attached device.
+
+`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
+
+```bash
+> bbr register
+Done
+```
+
+### bbr config
+
+Show local Backbone Router configuration for Thread 1.2 FTD.
+
+`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
+
+```bash
+> bbr config
+seqno:    10
+delay:    120 secs
+timeout:  300 secs
+Done
+```
+
+### bbr config \[seqno \<seqno\>\] \[delay \<delay\>\] \[timeout \<timeout\>\]
+
+Configure local Backbone Router configuration for Thread 1.2 FTD. `bbr register` should be issued explicitly to register Backbone Router service to Leader for Secondary Backbone Router. `SRV_DATA.ntf` would be initiated automatically if BBR Dataset changes for Primary Backbone Router.
+
+`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
+
+```bash
+> bbr config seqno 20 delay 30
+Done
+```
+
+### bbr jitter
+
+Show jitter (in seconds) for Backbone Router registration for Thread 1.2 FTD.
+
+`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
+
+```bash
+> bbr jitter
+20
+Done
+```
+
+### bbr jitter \<jitter\>
+
+Set jitter (in seconds) for Backbone Router registration for Thread 1.2 FTD.
+
+`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
+
+```bash
+> bbr jitter 10
+Done
+```
+
 ### bufferinfo
 
 Show the current message buffer information.
@@ -159,7 +299,7 @@
 
 ### child \<id\>
 
-Print diagnostic information for an attached Thread Child.  The `id` may be a Child ID or an RLOC16.
+Print diagnostic information for an attached Thread Child. The `id` may be a Child ID or an RLOC16.
 
 ```bash
 > child 1
@@ -185,6 +325,27 @@
 Done
 ```
 
+### childip max
+
+Get the maximum number of IP addresses that each MTD child may register with this device as parent.
+
+```bash
+> childip max
+4
+Done
+```
+
+### childip max \<count\>
+
+Set the maximum number of IP addresses that each MTD child may register with this device as parent. 0 to clear the setting and restore the default.
+
+`OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is required.
+
+```bash
+> childip max 2
+Done
+```
+
 ### childmax
 
 Get the Thread maximum number of allowed children.
@@ -331,8 +492,8 @@
 
 Set time sync parameters
 
-* timesyncperiod: The time synchronization period, in seconds.
-* xtalthreshold: The XTAL accuracy threshold for a device to become Router-Capable device, in PPM.
+- timesyncperiod: The time synchronization period, in seconds.
+- xtalthreshold: The XTAL accuracy threshold for a device to become Router-Capable device, in PPM.
 
 ```bash
 > networktime 100 300
@@ -362,7 +523,7 @@
 
 Perform an MLE Discovery operation.
 
-* channel: The channel to discover on.  If no channel is provided, the discovery will cover all valid channels.
+- channel: The channel to discover on. If no channel is provided, the discovery will cover all valid channels.
 
 ```bash
 > discover
@@ -374,16 +535,63 @@
 
 ### dns resolve \<hostname\> \[DNS server IP\] \[DNS server port\]
 
-Send DNS Query to obtain IPv6 address for given hostname.
-The latter two parameters have following default values:
- * DNS server IP: 2001:4860:4860::8888 (Google DNS Server)
- * DNS server port: 53
+Send DNS Query to obtain IPv6 address for given hostname. The latter two parameters have following default values:
+
+- DNS server IP: 2001:4860:4860::8888 (Google DNS Server)
+- DNS server port: 53
 
 ```bash
 > dns resolve ipv6.google.com
 > DNS response for ipv6.google.com - 2a00:1450:401b:801:0:0:0:200e TTL: 300
 ```
 
+### domainname
+
+Get the Thread Domain Name for Thread 1.2 device.
+
+```bash
+> domainname
+Thread
+Done
+```
+
+### domainname \<name\>
+
+Set the Thread Domain Name for Thread 1.2 device.
+
+```bash
+> domainname Test\ Thread
+Done
+```
+
+### dua iid
+
+Get the Interface Identifier mannually specified for Thread Domain Unicast Address on Thread 1.2 device.
+
+```bash
+> dua iid
+0004000300020001
+Done
+```
+
+### dua iid \<iid\>
+
+Set the Interface Identifier mannually specified for Thread Domain Unicast Address on Thread 1.2 device.
+
+```bash
+> dua iid 0004000300020001
+Done
+```
+
+### dua iid clear
+
+Clear the Interface Identifier mannually specified for Thread Domain Unicast Address on Thread 1.2 device.
+
+```bash
+> dua iid clear
+Done
+```
+
 ### eidcache
 
 Print the EID-to-RLOC cache entries.
@@ -429,6 +637,8 @@
 
 Get the Thread Extended PAN ID value.
 
+**NOTE** The current commissioning credential becomes stale after changing this value. Use [pskc](#pskc--p-keypassphrase) to reset.
+
 ```bash
 > extpanid
 dead00beef00cafe
@@ -445,6 +655,7 @@
 ```
 
 ### factoryreset
+
 Delete all stored settings, and signal a platform reset.
 
 ```bash
@@ -637,8 +848,7 @@
 
 ### keysequence guardtime \<guardtime\>
 
-Set Thread Key Switch Guard Time (in hours)
-0 means Thread Key Switch imediately if key index match
+Set Thread Key Switch Guard Time (in hours) 0 means Thread Key Switch imediately if key index match
 
 ```bash
 > keysequence guardtime 0
@@ -716,14 +926,31 @@
 Done
 ```
 
-### logfilename \<filename\>
+### log filename \<filename\>
 
-- Note: POSIX Platform Only, ie: `OPENTHREAD_EXAMPLES_POSIX`
+- Note: Simulation Only, ie: `OPENTHREAD_EXAMPLES_SIMULATION`
 - Requires `OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART`
 
-Specifies filename to capture otPlatLog() messages, useful when
-debugging automated test scripts on Linux when logging disrupts
-the automated test scripts.
+Specifies filename to capture otPlatLog() messages, useful when debugging automated test scripts on Linux when logging disrupts the automated test scripts.
+
+### log level
+
+Get the log level.
+
+```bash
+> log level
+1
+Done
+```
+
+### log level \<level\>
+
+Set the log level.
+
+```bash
+> log level 4
+Done
+```
 
 ### masterkey
 
@@ -748,10 +975,10 @@
 
 Get the Thread Device Mode value.
 
-* r: rx-on-when-idle
-* s: Secure IEEE 802.15.4 data requests
-* d: Full Thread Device
-* n: Full Network Data
+- r: rx-on-when-idle
+- s: Secure IEEE 802.15.4 data requests
+- d: Full Thread Device
+- n: Full Network Data
 
 ```bash
 > mode
@@ -763,10 +990,10 @@
 
 Set the Thread Device Mode value.
 
-* r: rx-on-when-idle
-* s: Secure IEEE 802.15.4 data requests
-* d: Full Thread Device
-* n: Full Network Data
+- r: rx-on-when-idle
+- s: Secure IEEE 802.15.4 data requests
+- d: Full Thread Device
+- n: Full Network Data
 
 ```bash
 > mode rsdn
@@ -816,20 +1043,49 @@
 Done
 ```
 
+### netstat
+
+List all UDP sockets.
+
+```bash
+> netstat
+|                 Local Address                 |                  Peer Address                 |
++-----------------------------------------------+-----------------------------------------------+
+| 0:0:0:0:0:0:0:0:49153                         | 0:0:0:0:0:0:0:0:*                             |
+| 0:0:0:0:0:0:0:0:49152                         | 0:0:0:0:0:0:0:0:*                             |
+| 0:0:0:0:0:0:0:0:61631                         | 0:0:0:0:0:0:0:0:*                             |
+| 0:0:0:0:0:0:0:0:19788                         | 0:0:0:0:0:0:0:0:*                             |
+Done
+```
+
 ### networkdiagnostic get \<addr\> \<type\> ..
 
 Send network diagnostic request to retrieve tlv of \<type\>s.
 
-If \<addr\> is unicast address, `Diagnostic Get` will be sent.
-if \<addr\> is multicast address, `Diagnostic Query` will be sent.
+If \<addr\> is unicast address, `Diagnostic Get` will be sent. if \<addr\> is multicast address, `Diagnostic Query` will be sent.
 
 ```bash
-> networkdiagnostic get fdde:ad00:beef:0:0:ff:fe00:f400 0 1 6
-DIAG_GET.rsp: 00088e18ad17a24b0b740102f400060841dcb82d40bac63d
+> networkdiagnostic get fdde:ad00:beef:0:0:ff:fe00:fc00 0 1 6
+> DIAG_GET.rsp/ans: 00080e336e1c41494e1c01020c000608640b0f674074c503
+Ext Address: '0e336e1c41494e1c'
+Rloc16: 0x0c00
+Leader Data:
+    PartitionId: 0x640b0f67
+    Weighting: 64
+    DataVersion: 116
+    StableDataVersion: 197
+    LeaderRouterId: 0x03
+Done
 
 > networkdiagnostic get ff02::1 0 1
-DIAG_GET.rsp: 0008567e31a79667a8cc0102f000
-DIAG_GET.rsp: 0008aaa7e584759e4e6401025400
+> DIAG_GET.rsp/ans: 00080e336e1c41494e1c01020c00
+Ext Address: '0e336e1c41494e1c'
+Rloc16: 0x0c00
+Done
+DIAG_GET.rsp/ans: 00083efcdb7e3f9eb0f201021800
+Ext Address: '3efcdb7e3f9eb0f2'
+Rloc16: 0x1800
+Done
 ```
 
 ### networkdiagnostic reset \<addr\> \<type\> ..
@@ -874,6 +1130,8 @@
 
 Set the Thread Network Name.
 
+**NOTE** The current commissioning credential becomes stale after changing this value. Use [pskc](#pskc--p-keypassphrase) to reset.
+
 ```bash
 > networkname OpenThread
 Done
@@ -902,11 +1160,7 @@
 
 Get the diagnostic information for a Thread Router as parent.
 
-Note: When operating as a Thread Router, this command will return the cached
-      information from when the device was previously attached as a Thread
-      Child. Returning cached information is necessary to support the Thread
-      Test Harness - Test Scenario 8.2.x requests the former parent (i.e. Joiner
-      Router's) MAC address even if the device has already promoted to a router.
+Note: When operating as a Thread Router, this command will return the cached information from when the device was previously attached as a Thread Child. Returning cached information is necessary to support the Thread Test Harness - Test Scenario 8.2.x requests the former parent (i.e. Joiner Router's) MAC address even if the device has already promoted to a router.
 
 ```bash
 > parent
@@ -937,14 +1191,14 @@
 Done
 ```
 
-### ping \<ipaddr\> [size] [count] [interval] [hoplimit]
+### ping \<ipaddr\> [size][count] [interval][hoplimit]
 
 Send an ICMPv6 Echo Request.
 
-* size: The number of data bytes to be sent.
-* count: The number of ICMPv6 Echo Requests to be sent.
-* interval: The interval between two consecutive ICMPv6 Echo Requests in seconds. The value may have fractional form, for example `0.5`.
-* hoplimit: The hoplimit of ICMPv6 Echo Request to be sent.
+- size: The number of data bytes to be sent.
+- count: The number of ICMPv6 Echo Requests to be sent.
+- interval: The interval between two consecutive ICMPv6 Echo Requests in seconds. The value may have fractional form, for example `0.5`.
+- hoplimit: The hoplimit of ICMPv6 Echo Request to be sent.
 
 ```bash
 > ping fdde:ad00:beef:0:558:f56b:d688:799
@@ -981,32 +1235,60 @@
 Done
 ```
 
+### pskc [-p] \<key\>|\<passphrase\>
+
+With `-p` generate pskc from \<passphrase\> (UTF-8 encoded) together with **current** network name and extended PAN ID, otherwise set pskc as \<key\> (hex format).
+
+```bash
+> pskc 67c0c203aa0b042bfb5381c47aef4d9e
+Done
+> pskc -p 123456
+Done
+```
+
+### preferrouterid \<routerid\>
+
+Prefer a Router ID when solicit router id from Leader.
+
+```bash
+> preferrouterid 16
+Done
+```
+
 ### prefix
 
-Get the prefix list in the local Network Data.
+Get the prefix list in the local Network Data. Note: For the Thread 1.2 border router with backbone capability, the local Domain Prefix would be listed as well (with flag `D`), with preceeding `-` if backbone functionality is disabled.
 
 ```bash
 > prefix
 2001:dead:beef:cafe::/64 paros med
+- fd00:7d03:7d03:7d03::/64 prosD med
 Done
 ```
 
-### prefix add \<prefix\> [pvdcsr] [prf]
+### prefix add \<prefix\> [padcrosnD][prf]
 
 Add a valid prefix to the Network Data.
 
-* p: Preferred flag
-* a: Stateless IPv6 Address Autoconfiguration flag
-* d: DHCPv6 IPv6 Address Configuration flag
-* c: DHCPv6 Other Configuration flag
-* r: Default Route flag
-* o: On Mesh flag
-* s: Stable flag
-* prf: Default router preference, which may be 'high', 'med', or 'low'.
+Note: The Domain Prefix flag (`D`) is only available for Thread 1.2.
+
+- p: Preferred flag
+- a: Stateless IPv6 Address Autoconfiguration flag
+- d: DHCPv6 IPv6 Address Configuration flag
+- c: DHCPv6 Other Configuration flag
+- r: Default Route flag
+- o: On Mesh flag
+- s: Stable flag
+- n: Nd Dns flag
+- D: Domain Prefix flag
+- prf: Default router preference, which may be 'high', 'med', or 'low'.
 
 ```bash
 > prefix add 2001:dead:beef:cafe::/64 paros med
 Done
+
+> prefix add fd00:7d03:7d03:7d03::/64 prosD med
+Done
 ```
 
 ### prefix remove \<prefix\>
@@ -1046,7 +1328,22 @@
 Done
 ```
 
+### rcp
+
+RCP-related commands.
+
+### rcp version
+
+Print RCP version string.
+
+```bash
+> rcp version
+OPENTHREAD/20191113-00825-g82053cc9d-dirty; SIMULATION; Jun  4 2020 17:53:16
+Done
+```
+
 ### releaserouterid \<routerid\>
+
 Release a Router ID that has been allocated by the device in the Leader role.
 
 ```bash
@@ -1055,6 +1352,7 @@
 ```
 
 ### reset
+
 Signal a platform reset.
 
 ```bash
@@ -1081,12 +1379,12 @@
 Done
 ```
 
-### route add \<prefix\> [s] [prf]
+### route add \<prefix\> [s][prf]
 
 Add a valid external route to the Network Data.
 
-* s: Stable flag
-* prf: Default Router Preference, which may be: 'high', 'med', or 'low'.
+- s: Stable flag
+- prf: Default Router Preference, which may be: 'high', 'med', or 'low'.
 
 ```bash
 > route add 2001:dead:beef:cafe::/64 s med
@@ -1127,7 +1425,7 @@
 
 ### router \<id\>
 
-Print diagnostic information for a Thread Router.  The `id` may be a Router ID or an RLOC16.
+Print diagnostic information for a Thread Router. The `id` may be a Router ID or an RLOC16.
 
 ```bash
 > router 50
@@ -1248,7 +1546,7 @@
 
 Perform an IEEE 802.15.4 Active Scan.
 
-* channel: The channel to scan on.  If no channel is provided, the active scan will cover all valid channels.
+- channel: The channel to scan on. If no channel is provided, the active scan will cover all valid channels.
 
 ```bash
 > scan
@@ -1262,7 +1560,7 @@
 
 Perform an IEEE 802.15.4 Energy Scan.
 
-* duration: The time in milliseconds to spend scanning each channel.
+- duration: The time in milliseconds to spend scanning each channel.
 
 ```bash
 > scan energy 10
@@ -1288,6 +1586,7 @@
 ```
 
 ### singleton
+
 Return true when there are no other nodes in the network, otherwise return false.
 
 ```bash
@@ -1298,10 +1597,10 @@
 
 ### sntp query \[SNTP server IP\] \[SNTP server port\]
 
-Send SNTP Query to obtain current unix epoch time (from 1st January 1970).
-The latter two parameters have following default values:
- * NTP server IP: 2001:4860:4806:8:: (Google IPv6 NTP Server)
- * NTP server port: 123
+Send SNTP Query to obtain current unix epoch time (from 1st January 1970). The latter two parameters have following default values:
+
+- NTP server IP: 2001:4860:4806:8:: (Google IPv6 NTP Server)
+- NTP server port: 123
 
 ```bash
 > sntp query
@@ -1309,12 +1608,14 @@
 ```
 
 You can use NAT64 of OpenThread Border Router to reach e.g. Google IPv4 NTP Server:
+
 ```bash
 > sntp query 64:ff9b::d8ef:2308
 > SNTP response - Unix time: 1540898611 (era: 0)
 ```
 
 ### state
+
 Return state of current state.
 
 ```bash
@@ -1324,6 +1625,7 @@
 ```
 
 ### state <state>
+
 Try to switch to state `detached`, `child`, `router` or `leader`.
 
 ```bash
@@ -1482,8 +1784,7 @@
 
 ### macfilter addr add \<extaddr\> \[rss\]
 
-Add an IEEE 802.15.4 Extended Address to the address filter, and fixed the received singal strength for
-the messages from the address if rss is specified.
+Add an IEEE 802.15.4 Extended Address to the address filter, and fixed the received singal strength for the messages from the address if rss is specified.
 
 ```bash
 > macfilter addr add 0f6127e33af6b403 -95
@@ -1526,9 +1827,7 @@
 
 ### macfilter rss add \<extaddr\> \<rss\>
 
-Set the received signal strength for the messages from the IEEE802.15.4 Extended Address.
-If extaddr is \*, default received signal strength for all received messages would be set.
-
+Set the received signal strength for the messages from the IEEE802.15.4 Extended Address. If extaddr is \*, default received signal strength for all received messages would be set.
 
 ```bash
 > macfilter rss add * -50
@@ -1542,10 +1841,7 @@
 
 ### macfilter rss add-lqi \<extaddr\> \<lqi\>
 
-Set the received link quality for the messages from the IEEE802.15.4 Extended Address. Valid lqi range [0,3]
-If extaddr is \*, default received link quality for all received messages would be set.
-Equivalent with 'filter rss add' with similar usage
-
+Set the received link quality for the messages from the IEEE802.15.4 Extended Address. Valid lqi range [0,3] If extaddr is \*, default received link quality for all received messages would be set. Equivalent with 'filter rss add' with similar usage
 
 ```bash
 > macfilter rss add-lqi * 3
@@ -1559,8 +1855,7 @@
 
 ### macfilter rss remove \<extaddr\>
 
-Removes the received signal strength or received link quality setting on the Extended Address.
-If extaddr is \*, default received signal strength or link quality for all received messages would be unset.
+Removes the received signal strength or received link quality setting on the Extended Address. If extaddr is \*, default received signal strength or link quality for all received messages would be unset.
 
 ```bash
 > macfilter rss remove *
@@ -1583,14 +1878,11 @@
 
 ### diag
 
-Factory Diagnostics module is enabled only when building OpenThread with `OPENTHREAD_CONFIG_DIAG_ENABLE=1` option.
-Go [diagnostics module][DIAG] for more information.
+Factory Diagnostics module is enabled only when building OpenThread with `OPENTHREAD_CONFIG_DIAG_ENABLE=1` option. Go [diagnostics module][diag] for more information.
 
 ### service
 
-Module for controlling service registration in Network Data.
-Each change in service registration must be sent to leader by `netdataregister` command
-before taking effect.
+Module for controlling service registration in Network Data. Each change in service registration must be sent to leader by `netdataregister` command before taking effect.
 
 ### service add \<enterpriseNumber\> \<serviceData\> \<serverData\>
 
@@ -1627,4 +1919,4 @@
 Done
 ```
 
-[DIAG]:../../src/core/diags/README.md
+[diag]: ../../src/core/diags/README.md
diff --git a/src/cli/README_COAP.md b/src/cli/README_COAP.md
index a83adbd..1dc8630 100644
--- a/src/cli/README_COAP.md
+++ b/src/cli/README_COAP.md
@@ -10,7 +10,7 @@
 
 ```bash
 > ./bootstrap
-> make -f examples/Makefile-posix COAP=1
+> make -f examples/Makefile-simulation COAP=1
 ```
 
 ### Form Network
@@ -54,14 +54,18 @@
 
 ## Command List
 
-* [help](#help)
-* [delete](#delete-address-uri-path-type-payload)
-* [get](#get-address-uri-path-type)
-* [post](#post-address-uri-path-type-payload)
-* [put](#put-address-uri-path-type-payload)
-* [resource](#resource-uri-path)
-* [start](#start)
-* [stop](#stop)
+- [help](#help)
+- [cancel](#cancel)
+- [delete](#delete-address-uri-path-type-payload)
+- [get](#get-address-uri-path-type)
+- [observe](#observe-address-uri-path-type)
+- [parameters](#parameters)
+- [post](#post-address-uri-path-type-payload)
+- [put](#put-address-uri-path-type-payload)
+- [resource](#resource-uri-path)
+- [set](#set-new-content)
+- [start](#start)
+- [stop](#stop)
 
 ## Command Details
 
@@ -70,11 +74,15 @@
 ```bash
 > coap help
 help
+cancel
 delete
 get
+observe
+parameters
 post
 put
 resource
+set
 start
 stop
 Done
@@ -82,12 +90,21 @@
 
 List the CoAP CLI commands.
 
+### cancel
+
+Request the cancellation of an existing observation subscription to a remote resource.
+
+```bash
+> coap cancel
+Done
+```
+
 ### delete \<address\> \<uri-path\> \[type\] \[payload\]
 
-* address: IPv6 address of the CoAP server.
-* uri-path: URI path of the resource.
-* type: "con" for Confirmable or "non-con" for Non-confirmable (default).
-* payload: CoAP request payload.
+- address: IPv6 address of the CoAP server.
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+- payload: CoAP request payload.
 
 ```bash
 > coap delete fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con payload
@@ -96,21 +113,71 @@
 
 ### get \<address\> \<uri-path\> \[type\]
 
-* address: IPv6 address of the CoAP server.
-* uri-path: URI path of the resource.
-* type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+- address: IPv6 address of the CoAP server.
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
 
 ```bash
 > coap get fdde:ad00:beef:0:2780:9423:166c:1aac test-resource
 Done
 ```
 
+### observe \<address\> \<uri-path\> \[type\]
+
+This is the same a `get`, but the `Observe` parameter will be sent, set to 0 triggering a subscription request.
+
+- address: IPv6 address of the CoAP server.
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+
+```bash
+> coap observe fdde:ad00:beef:0:2780:9423:166c:1aac test-resource
+Done
+```
+
+### parameters \<type\> \["default"|<ack_timeout\> <ack_random_factor_numerator\> <ack_random_factor_denominator\> <max_retransmit\>\]
+
+Sets transmission parameters for the following interactions.
+
+- type: "request" for CoAP requests and "response" for CoAP responses.
+
+If no more parameters are given, the command prints the current configuration:
+
+```bash
+> coap parameters request
+Transmission parameters for request:
+ACK_TIMEOUT=1000 ms, ACK_RANDOM_FACTOR=255/254, MAX_RETRANSMIT=2
+Done
+```
+
+If `"default"` is given, the command sets the default configuration for the transmission parameters.
+
+```bash
+> coap parameters request default
+Transmission parameters for request:
+default
+Done
+```
+
+Also, you can specify the transmission parameters in the command line:
+
+- ack_timeout (0~UINT32_MAX): RFC7252 ACK_TIMEOUT, in milliseconds.
+- ack_random_factor_numerator, ack_random_factor_denominator (0~255): RFC7252 ACK_RANDOM_FACTOR=ack_random_factor_numerator/ack_random_factor_denominator.
+- max_retransmit (0~255): RFC7252 MAX_RETRANSMIT.
+
+```bash
+> coap parameters request 1000 255 254 2
+Transmission parameters for request:
+ACK_TIMEOUT=1000 ms, ACK_RANDOM_FACTOR=255/254, MAX_RETRANSMIT=2
+Done
+```
+
 ### post \<address\> \<uri-path\> \[type\] \[payload\]
 
-* address: IPv6 address of the CoAP server.
-* uri-path: URI path of the resource.
-* type: "con" for Confirmable or "non-con" for Non-confirmable (default).
-* payload: CoAP request payload.
+- address: IPv6 address of the CoAP server.
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+- payload: CoAP request payload.
 
 ```bash
 > coap post fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con payload
@@ -119,10 +186,10 @@
 
 ### put \<address\> \<uri-path\> \[type\] \[payload\]
 
-* address: IPv6 address of the CoAP server.
-* uri-path: URI path of the resource.
-* type: "con" for Confirmable or "non-con" for Non-confirmable (default).
-* payload: CoAP request payload.
+- address: IPv6 address of the CoAP server.
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+- payload: CoAP request payload.
 
 ```bash
 > coap put fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con payload
@@ -141,6 +208,15 @@
 Done
 ```
 
+### set \[new-content\]
+
+Sets the content sent by the test resource. If a CoAP client is observing the resource, a notification is sent to that client.
+
+```bash
+> coap set Testing123
+Done
+```
+
 ### start
 
 Starts the application coap service.
diff --git a/src/cli/README_COAPS.md b/src/cli/README_COAPS.md
index c28a4cc..2d31fee 100644
--- a/src/cli/README_COAPS.md
+++ b/src/cli/README_COAPS.md
@@ -6,11 +6,11 @@
 
 ### Build with CoAPS API support
 
-Use the   `COAPS=1` build       switch to enable CoAPS API support.
+Use the `COAPS=1` build switch to enable CoAPS API support.
 
 ```bash
 > ./bootstrap
-> make -f examples/Makefile-posix COAPS=1
+> make -f examples/Makefile-simulation COAPS=1
 ```
 
 ### Form Network
@@ -23,22 +23,23 @@
 
 This example supports two ciphersuites:
 
-* TLS_PSK_WITH_AES_128_CCM_8
+- TLS_PSK_WITH_AES_128_CCM_8
+
   ```bash
   > coaps psk <your-psk> <your-psk-id>
   Done
   ```
 
-* TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+- TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
   ```bash
   > coaps x509
   Done
   ```
-The X.509 certificate stored in `core/cli/x509_cert_key.hpp`.
+  The X.509 certificate stored in `core/cli/x509_cert_key.hpp`.
 
 ### Node 1
 
-On node  1, setup CoAPS server with resource `test-resource`.
+On node 1, setup CoAPS server with resource `test-resource`.
 
 ```bash
 > coaps start
@@ -90,18 +91,19 @@
 
 ## Command List
 
-* [help](#help)
-* [connect](#connect-address)
-* [delete](#delete-uri-path-type-payload)
-* [disconnect](#disconnect)
-* [get](#get-uri-path-type)
-* [post](#post-uri-path-type-payload)
-* [psk](#psk-psk-pskid)
-* [put](#put-uri-path-type-payload)
-* [resource](#resource-uri-path)
-* [start](#start)
-* [stop](#stop)
-* [x509](#x509)
+- [help](#help)
+- [connect](#connect-address)
+- [delete](#delete-uri-path-type-payload)
+- [disconnect](#disconnect)
+- [get](#get-uri-path-type)
+- [post](#post-uri-path-type-payload)
+- [psk](#psk-psk-pskid)
+- [put](#put-uri-path-type-payload)
+- [resource](#resource-uri-path)
+- [set](#set-new-content)
+- [start](#start)
+- [stop](#stop)
+- [x509](#x509)
 
 ## Command Details
 
@@ -118,6 +120,7 @@
 psk
 put
 resource
+set
 start
 stop
 x509
@@ -130,7 +133,7 @@
 
 Establish DTLS session.
 
-* address: IPv6 address of the peer.
+- address: IPv6 address of the peer.
 
 ```bash
 > coaps connect fdde:ad00:beef:0:9903:14b:27e0:5744
@@ -140,9 +143,9 @@
 
 ### delete \<uri-path\> \[type\] \[payload\]
 
-* uri-path: URI path of the resource.
-* type: "con" for Confirmable or "non-con" for Non-confirmable (default).
-* payload: CoAPS request payload.
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+- payload: CoAPS request payload.
 
 ```bash
 > coaps delete test-resource con payload
@@ -159,8 +162,8 @@
 
 ### get \<uri-path\> \[type\]
 
-* uri-path: URI path of the resource.
-* type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
 
 ```bash
 > coaps get test-resource
@@ -169,9 +172,9 @@
 
 ### post \<uri-path\> \[type\] \[payload\]
 
-* uri-path: URI path of the resource.
-* type: "con" for Confirmable or "non-con" for Non-confirmable (default).
-* payload: CoAPS request payload.
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+- payload: CoAPS request payload.
 
 ```bash
 > coaps post test-resource con payload
@@ -182,8 +185,8 @@
 
 Set DTLS ciphersuite to `TLS_PSK_WITH_AES_128_CCM_8`.
 
-* psk: pre-shared key
-* pskid: pre-shared key identifier
+- psk: pre-shared key
+- pskid: pre-shared key identifier
 
 ```bash
 > coaps psk 123 pskid
@@ -192,9 +195,9 @@
 
 ### put \<uri-path\> \[type\] \[payload\]
 
-* uri-path: URI path of the resource.
-* type: "con" for Confirmable or "non-con" for Non-confirmable (default).
-* payload: CoAPS request payload.
+- uri-path: URI path of the resource.
+- type: "con" for Confirmable or "non-con" for Non-confirmable (default).
+- payload: CoAPS request payload.
 
 ```bash
 > coaps put test-resource con payload
@@ -213,11 +216,20 @@
 Done
 ```
 
+### set \[new-content\]
+
+Sets the content sent by the test resource.
+
+```bash
+> coaps set Testing123
+Done
+```
+
 ### start
 
 Starts the application coaps service.
 
-* checkPeerCert: Peer Certificate Check can be disabled by typing false.
+- checkPeerCert: Peer Certificate Check can be disabled by typing false.
 
 ```bash
 > coaps start
diff --git a/src/cli/README_COMMISSIONER.md b/src/cli/README_COMMISSIONER.md
index 59ccbd1..d199cf6 100644
--- a/src/cli/README_COMMISSIONER.md
+++ b/src/cli/README_COMMISSIONER.md
@@ -85,7 +85,7 @@
 
 Add a Joiner entry.
 
-- eui64: The IEEE EUI-64 of the Joiner or '*' to match any Joiner.
+- eui64: The IEEE EUI-64 of the Joiner or '\*' to match any Joiner.
 - pskd: Pre-Shared Key for the Joiner.
 
 ```bash
@@ -99,7 +99,7 @@
 
 Remove a Joiner entry.
 
-- eui64: The IEEE EUI-64 of the Joiner or '*' to match any Joiner.
+- eui64: The IEEE EUI-64 of the Joiner or '\*' to match any Joiner.
 
 ```bash
 > commissioner joiner remove d45e64fa83f81cf7
diff --git a/src/cli/README_COMMISSIONING.md b/src/cli/README_COMMISSIONING.md
index b61d7bd..b2aa378 100644
--- a/src/cli/README_COMMISSIONING.md
+++ b/src/cli/README_COMMISSIONING.md
@@ -8,7 +8,7 @@
 
 ```bash
 > ./bootstrap
-> make -f examples/Makefile-posix JOINER=1
+> make -f examples/Makefile-simulation JOINER=1
 ```
 
 ### Build with Commissioner support
@@ -17,7 +17,7 @@
 
 ```bash
 > ./bootstrap
-> make -f examples/Makefile-posix COMMISSIONER=1
+> make -f examples/Makefile-simulation COMMISSIONER=1
 ```
 
 ### Form Network
@@ -26,38 +26,38 @@
 
 1. Generate and view new network configuration.
 
-    ```bash
-    > dataset init new
-    Done
-    > dataset
-    Active Timestamp: 1
-    Channel: 13
-    Channel Mask: 07fff800
-    Ext PAN ID: d63e8e3e495ebbc3
-    Mesh Local Prefix: fd3d:b50b:f96d:722d/64
-    Master Key: dfd34f0f05cad978ec4e32b0413038ff
-    Network Name: OpenThread-8f28
-    PAN ID: 0x8f28
-    PSKc: c23a76e98f1a6483639b1ac1271e2e27
-    Security Policy: 0, onrcb
-    Done
-    ```
+   ```bash
+   > dataset init new
+   Done
+   > dataset
+   Active Timestamp: 1
+   Channel: 13
+   Channel Mask: 07fff800
+   Ext PAN ID: d63e8e3e495ebbc3
+   Mesh Local Prefix: fd3d:b50b:f96d:722d/64
+   Master Key: dfd34f0f05cad978ec4e32b0413038ff
+   Network Name: OpenThread-8f28
+   PAN ID: 0x8f28
+   PSKc: c23a76e98f1a6483639b1ac1271e2e27
+   Security Policy: 0, onrcb
+   Done
+   ```
 
 2. Commit new dataset to the Active Operational Dataset in non-volatile storage.
 
-    ```bash
-    dataset commit active
-    Done
-    ```
+   ```bash
+   dataset commit active
+   Done
+   ```
 
 3. Enable Thread interface
 
-    ```bash
-    > ifconfig up
-    Done
-    > thread start
-    Done
-    ```
+   ```bash
+   > ifconfig up
+   Done
+   > thread start
+   Done
+   ```
 
 ### Obtain Joiner IEEE EUI-64
 
@@ -89,7 +89,13 @@
 
 ### Start Joiner
 
-1. Start the Joiner process.
+1. Factory reset the device.
+
+   ```bash
+   > factoryreset
+   ```
+
+2. Start the Joiner process.
 
    ```bash
    > ifconfig up
@@ -99,14 +105,14 @@
    Join success
    ```
 
-2. Attach to Thread network
+3. Attach to Thread network
 
    ```bash
    > thread start
    Done
    ```
 
-3. After successful attach, validate the device has the same Active Operational Dataset as above.
+4. After successful attach, validate the device has the same Active Operational Dataset as above.
 
    ```bash
    > dataset active
diff --git a/src/cli/README_DATASET.md b/src/cli/README_DATASET.md
index a72dd91..a0ce1d9 100644
--- a/src/cli/README_DATASET.md
+++ b/src/cli/README_DATASET.md
@@ -8,22 +8,22 @@
 
 The Active Operational Dataset includes parameters that are currently in use across an entire Thread network. The Active Operational Dataset contains:
 
-* Active Timestamp
-* Channel
-* Channel Mask
-* Extended PAN ID
-* Mesh-Local Prefix
-* Network Name
-* PAN ID
-* PSKc
-* Security Policy
+- Active Timestamp
+- Channel
+- Channel Mask
+- Extended PAN ID
+- Mesh-Local Prefix
+- Network Name
+- PAN ID
+- PSKc
+- Security Policy
 
 ### Pending Operational Dataset
 
 The Pending Operational Dataset is used to communicate changes to the Active Operational Dataset before they take effect. The Pending Operational Dataset contains all the parameters from the Active Operational Dataset, with the addition of:
 
-* Delay Timer
-* Pending Timestamp
+- Delay Timer
+- Pending Timestamp
 
 ## Quick Start
 
@@ -31,38 +31,38 @@
 
 1. Generate and view new network configuration.
 
-    ```bash
-    > dataset init new
-    Done
-    > dataset
-    Active Timestamp: 1
-    Channel: 13
-    Channel Mask: 07fff800
-    Ext PAN ID: d63e8e3e495ebbc3
-    Mesh Local Prefix: fd3d:b50b:f96d:722d/64
-    Master Key: dfd34f0f05cad978ec4e32b0413038ff
-    Network Name: OpenThread-8f28
-    PAN ID: 0x8f28
-    PSKc: c23a76e98f1a6483639b1ac1271e2e27
-    Security Policy: 0, onrcb
-    Done
-    ```
+   ```bash
+   > dataset init new
+   Done
+   > dataset
+   Active Timestamp: 1
+   Channel: 13
+   Channel Mask: 07fff800
+   Ext PAN ID: d63e8e3e495ebbc3
+   Mesh Local Prefix: fd3d:b50b:f96d:722d/64
+   Master Key: dfd34f0f05cad978ec4e32b0413038ff
+   Network Name: OpenThread-8f28
+   PAN ID: 0x8f28
+   PSKc: c23a76e98f1a6483639b1ac1271e2e27
+   Security Policy: 0, onrcb
+   Done
+   ```
 
 2. Commit new dataset to the Active Operational Dataset in non-volatile storage.
 
-    ```bash
-    dataset commit active
-    Done
-    ```
+   ```bash
+   dataset commit active
+   Done
+   ```
 
 3. Enable Thread interface
 
-    ```bash
-    > ifconfig up
-    Done
-    > thread start
-    Done
-    ```
+   ```bash
+   > ifconfig up
+   Done
+   > thread start
+   Done
+   ```
 
 ### Attach to Existing Network
 
@@ -74,38 +74,38 @@
 
 1. Create a partial Active Operational Dataset.
 
-    ```bash
-    > dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
-    Done
-    > dataset commit active
-    Done
-    ```
+   ```bash
+   > dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
+   Done
+   > dataset commit active
+   Done
+   ```
 
 2. Enable Thread interface.
 
-    ```bash
-    > ifconfig up
-    Done
-    > thread start
-    Done
-    ```
+   ```bash
+   > ifconfig up
+   Done
+   > thread start
+   Done
+   ```
 
 3. After attaching, validate that the device received the complete Active Operational Dataset.
 
-    ```bash
-    > dataset active
-    Active Timestamp: 1
-    Channel: 13
-    Channel Mask: 07fff800
-    Ext PAN ID: d63e8e3e495ebbc3
-    Mesh Local Prefix: fd3d:b50b:f96d:722d/64
-    Master Key: dfd34f0f05cad978ec4e32b0413038ff
-    Network Name: OpenThread-8f28
-    PAN ID: 0x8f28
-    PSKc: c23a76e98f1a6483639b1ac1271e2e27
-    Security Policy: 0, onrcb
-    Done
-    ```
+   ```bash
+   > dataset active
+   Active Timestamp: 1
+   Channel: 13
+   Channel Mask: 07fff800
+   Ext PAN ID: d63e8e3e495ebbc3
+   Mesh Local Prefix: fd3d:b50b:f96d:722d/64
+   Master Key: dfd34f0f05cad978ec4e32b0413038ff
+   Network Name: OpenThread-8f28
+   PAN ID: 0x8f28
+   PSKc: c23a76e98f1a6483639b1ac1271e2e27
+   Security Policy: 0, onrcb
+   Done
+   ```
 
 ## Command List
 
@@ -165,9 +165,9 @@
 
 ### active
 
-Usage: `dataset active`
+Usage: `dataset active [binary]`
 
-Print Active Operational Dataset.
+Print Active Operational Dataset in human-readable form.
 
 ```bash
 > dataset active
@@ -184,6 +184,14 @@
 Done
 ```
 
+Print Active Operational Dataset as hex-encoded TLVs.
+
+```bash
+> dataset active binary
+0e080000000000010000000300001035060004001fffe002084eb74ab03c56e6d00708fdc7fe165c83a67805108e2104f183e698da87e96efc1e45aa51030f4f70656e5468726561642d383631310102861104108d6273023d82c841eff0e68db86f35740c030000ff
+Done
+```
+
 ### activetimestamp
 
 Usage: `dataset activetimestamp <timestamp>`
@@ -191,7 +199,7 @@
 Set active timestamp.
 
 ```bash
-> dataset activestamp 123456789
+> dataset activetimestamp 123456789
 Done
 ```
 
@@ -256,6 +264,8 @@
 
 Set extended panid.
 
+**NOTE** The commissioning credential in the dataset buffer becomes stale after changing this value. Use [pskc](#pskc) to reset.
+
 ```bash
 > dataset extpanid 000db80123456789
 Done
@@ -322,6 +332,8 @@
 
 Set network name.
 
+**NOTE** The commissioning credential in the dataset buffer becomes stale after changing this value. Use [pskc](#pskc) to reset.
+
 ```bash
 > dataset networkname OpenThread
 Done
@@ -340,9 +352,9 @@
 
 ### pending
 
-Usage: `dataset pending`
+Usage: `dataset pending [binary]`
 
-Print Pending Operational Dataset.
+Print Pending Operational Dataset in human-readable form.
 
 ```bash
 > dataset pending
@@ -361,6 +373,14 @@
 Done
 ```
 
+Print Pending Operational Dataset as hex-encoded TLVs.
+
+```bash
+> dataset pending binary
+0e080000000000010000000300001035060004001fffe002084eb74ab03c56e6d00708fdc7fe165c83a67805108e2104f183e698da87e96efc1e45aa51030f4f70656e5468726561642d383631310102861104108d6273023d82c841eff0e68db86f35740c030000ff
+Done
+```
+
 ### pendingtimestamp
 
 Usage: `dataset pendingtimestamp <timestamp>`
@@ -374,13 +394,15 @@
 
 ### pskc
 
-Usage: `dataset pskc <key>`
+Usage: `pskc [-p] <key>|<passphrase>`
 
-Set pskc with hex format.
+With `-p`(**only for FTD**) generate pskc from \<passphrase\> (UTF-8 encoded) together with network name and extended PAN ID in the dataset buffer if set or values in the current stack if not, otherwise set pskc as \<key\> (hex format).
 
 ```bash
 > dataset pskc 67c0c203aa0b042bfb5381c47aef4d9e
 Done
+> dataset pskc -p 123456
+Done
 ```
 
 ### securitypolicy
@@ -389,13 +411,31 @@
 
 Set security policy.
 
-* o: Obtaining the Master Key for out-of-band commissioning is enabled.
-* n: Native Commissioning using PSKc is allowed.
-* r: Thread 1.x Routers are enabled.
-* c: External Commissioner authentication is allowed using PSKc.
-* b: Thread 1.x Beacons are enabled.
+- o: Obtaining the Master Key for out-of-band commissioning is enabled.
+- n: Native Commissioning using PSKc is allowed.
+- r: Thread 1.x Routers are enabled.
+- c: External Commissioner authentication is allowed using PSKc.
+- b: Thread 1.x Beacons are enabled.
 
 ```bash
 > dataset securitypolicy 672 onrcb
 Done
 ```
+
+### set
+
+Usage: `dataset set <active|pending> <dataset>`
+
+Set the Active Operational Dataset using hex-encoded TLVs.
+
+```bash
+dataset set active 0e080000000000010000000300001035060004001fffe002084eb74ab03c56e6d00708fdc7fe165c83a67805108e2104f183e698da87e96efc1e45aa51030f4f70656e5468726561642d383631310102861104108d6273023d82c841eff0e68db86f35740c030000ff
+Done
+```
+
+Set the Pending Operational Dataset using hex-encoded TLVs.
+
+```bash
+dataset set pending 0e080000000000010000000300001035060004001fffe002084eb74ab03c56e6d00708fdc7fe165c83a67805108e2104f183e698da87e96efc1e45aa51030f4f70656e5468726561642d383631310102861104108d6273023d82c841eff0e68db86f35740c030000ff
+Done
+```
diff --git a/src/cli/README_JOINER.md b/src/cli/README_JOINER.md
index 8422dab..02ff245 100644
--- a/src/cli/README_JOINER.md
+++ b/src/cli/README_JOINER.md
@@ -6,10 +6,10 @@
 
 ## Command List
 
-* [help](#help)
-* [id](#id)
-* [start](#start)
-* [stop](#stop)
+- [help](#help)
+- [id](#id)
+- [start](#start)
+- [stop](#stop)
 
 ## Command Details
 
@@ -46,8 +46,8 @@
 
 Start the Joiner role.
 
-* pskd: Pre-Shared Key for the Joiner.
-* provisioning-url: Provisioning URL for the Joiner (optional).
+- pskd: Pre-Shared Key for the Joiner.
+- provisioning-url: Provisioning URL for the Joiner (optional).
 
 This command will cause the device to start the Joiner process.
 
diff --git a/src/cli/README_UDP.md b/src/cli/README_UDP.md
index 24592c1..b62fdb7 100644
--- a/src/cli/README_UDP.md
+++ b/src/cli/README_UDP.md
@@ -38,12 +38,12 @@
 
 ## Command List
 
-* [help](#help)
-* [bind](#bind-ip-port)
-* [close](#close)
-* [connect](#connect-ip-port)
-* [open](#open)
-* [send](#send-ip-port-message)
+- [help](#help)
+- [bind](#bind-ip-port)
+- [close](#close)
+- [connect](#connect-ip-port)
+- [open](#open)
+- [send](#send-ip-port-message)
 
 ## Command Details
 
@@ -65,8 +65,9 @@
 ### bind \<ip\> \<port\>
 
 Assigns a name (i.e. IPv6 address and port) to the example socket.
-* ip: the IPv6 address or the unspecified IPv6 address (`::`).
-* port: the UDP port
+
+- ip: the IPv6 address or the unspecified IPv6 address (`::`).
+- port: the UDP port
 
 ```bash
 > udp bind :: 1234
@@ -86,8 +87,8 @@
 
 Specifies the peer with which the socket is to be associated.
 
-* ip: the peer's IPv6 address.
-* port: the peer's UDP port.
+- ip: the peer's IPv6 address.
+- port: the peer's UDP port.
 
 ```bash
 > udp connect fdde:ad00:beef:0:bb1:ebd6:ad10:f33 1234
@@ -107,26 +108,23 @@
 
 Send a UDP message.
 
-* ip: the IPv6 destination address.
-* port: the UDP destination port.
-* message: the message to send.
+- ip: the IPv6 destination address.
+- port: the UDP destination port.
+- message: the message to send.
 
 ```bash
 > udp send fdde:ad00:beef:0:bb1:ebd6:ad10:f33 1234 hello
 Done
 ```
 
-### send \<ip\> \<port\> \<type\> \<value\> 
+### send \<ip\> \<port\> \<type\> \<value\>
 
 Send a few bytes over UDP.
 
-* ip: the IPv6 destination address.
-* port: the UDP destination port.
-* type: the type of the message:
-        * `-t`: text payload in the `value`, same as without specifying the type. 
-        * `-s`: autogenerated payload with specified length indicated in the `value`.  
-        * `-x`: binary data in hexadecimal representation in the `value`.
-         
+- ip: the IPv6 destination address.
+- port: the UDP destination port.
+- type: the type of the message: _ `-t`: text payload in the `value`, same as without specifying the type. _ `-s`: autogenerated payload with specified length indicated in the `value`.  
+   \* `-x`: binary data in hexadecimal representation in the `value`.
 
 ```bash
 > udp send fdde:ad00:beef:0:bb1:ebd6:ad10:f33 1234 -t hello
@@ -139,11 +137,12 @@
 Done
 
 ```
+
 ### send \<message\>
 
 Send a UDP message on a connected socket.
 
-* message: the message to send.
+- message: the message to send.
 
 ```bash
 > udp send hello
@@ -154,10 +153,7 @@
 
 Send a few bytes over UDP.
 
-* type: the type of the message:
-        * `-t`: text payload in the `value`, same as without specifying the type.
-        * `-s`: autogenerated payload with specified length indicated in the `value`.
-        * `-x`: binary data in hexadecimal representation in the `value`.
+- type: the type of the message: _ `-t`: text payload in the `value`, same as without specifying the type. _ `-s`: autogenerated payload with specified length indicated in the `value`. \* `-x`: binary data in hexadecimal representation in the `value`.
 
 ```bash
 > udp send -t hello
diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp
index d446bc3..169cf1f 100644
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -61,10 +61,22 @@
 
 #include <openthread/diag.h>
 #include <openthread/icmp6.h>
+#include <openthread/logging.h>
 #include <openthread/platform/uart.h>
+#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+#include <openthread/platform/misc.h>
+#endif
 
 #include "common/new.hpp"
 #include "net/ip6.hpp"
+#include "utils/otns.hpp"
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+#include <openthread/backbone_router.h>
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+#include <openthread/backbone_router_ftd.h>
+#endif
+#endif
 
 #include "cli_dataset.hpp"
 
@@ -87,11 +99,16 @@
 using ot::Encoding::BigEndian::HostSwap16;
 using ot::Encoding::BigEndian::HostSwap32;
 
+#define INDENT_SIZE (4)
+
 namespace ot {
 
 namespace Cli {
 
 const struct Command Interpreter::sCommands[] = {
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    {"bbr", &Interpreter::ProcessBackboneRouter},
+#endif
     {"bufferinfo", &Interpreter::ProcessBufferInfo},
     {"channel", &Interpreter::ProcessChannel},
 #if OPENTHREAD_FTD
@@ -127,6 +144,12 @@
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
     {"dns", &Interpreter::ProcessDns},
 #endif
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    {"domainname", &Interpreter::ProcessDomainName},
+#endif
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    {"dua", &Interpreter::ProcessDua},
+#endif
 #if OPENTHREAD_FTD
     {"eidcache", &Interpreter::ProcessEidCache},
 #endif
@@ -134,9 +157,7 @@
 #if OPENTHREAD_POSIX
     {"exit", &Interpreter::ProcessExit},
 #endif
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
-    {"logfilename", &Interpreter::ProcessLogFilename},
-#endif
+    {"log", &Interpreter::ProcessLog},
     {"extaddr", &Interpreter::ProcessExtAddress},
     {"extpanid", &Interpreter::ProcessExtPanId},
     {"factoryreset", &Interpreter::ProcessFactoryReset},
@@ -169,6 +190,10 @@
     {"netdataregister", &Interpreter::ProcessNetworkDataRegister},
 #endif
     {"netdatashow", &Interpreter::ProcessNetworkDataShow},
+#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+    {"netif", &Interpreter::ProcessNetif},
+#endif
+    {"netstat", &Interpreter::ProcessNetstat},
 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
     {"networkdiagnostic", &Interpreter::ProcessNetworkDiagnostic},
 #endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
@@ -191,7 +216,11 @@
     {"prefix", &Interpreter::ProcessPrefix},
 #endif
 #if OPENTHREAD_FTD
+    {"preferrouterid", &Interpreter::ProcessPreferRouterId},
     {"pskc", &Interpreter::ProcessPskc},
+#endif
+    {"rcp", &Interpreter::ProcessRcp},
+#if OPENTHREAD_FTD
     {"releaserouterid", &Interpreter::ProcessReleaseRouterId},
 #endif
     {"reset", &Interpreter::ProcessReset},
@@ -222,13 +251,16 @@
 };
 
 Interpreter::Interpreter(Instance *aInstance)
-    : mUserCommands(NULL)
+    : mUserCommands(nullptr)
     , mUserCommandsLength(0)
-    , mServer(NULL)
-    , mLength(8)
-    , mCount(1)
-    , mInterval(1000)
-    , mPingTimer(*aInstance, &Interpreter::HandlePingTimer, this)
+    , mServer(nullptr)
+    , mPingLength(kDefaultPingLength)
+    , mPingCount(kDefaultPingCount)
+    , mPingInterval(kDefaultPingInterval)
+    , mPingHopLimit(0)
+    , mPingAllowZeroHopLimit(false)
+    , mPingIdentifier(0)
+    , mPingTimer(*aInstance, Interpreter::HandlePingTimer, this)
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
     , mResolvingInProgress(0)
 #endif
@@ -257,7 +289,7 @@
 
     mIcmpHandler.mReceiveCallback = Interpreter::HandleIcmpReceive;
     mIcmpHandler.mContext         = this;
-    otIcmp6RegisterHandler(mInstance, &mIcmpHandler);
+    IgnoreError(otIcmp6RegisterHandler(mInstance, &mIcmpHandler));
 
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
     memset(mResolvingHostname, 0, sizeof(mResolvingHostname));
@@ -345,9 +377,9 @@
     }
 }
 
-void Interpreter::OutputIp6Address(const otIp6Address &aAddress) const
+int Interpreter::OutputIp6Address(const otIp6Address &aAddress) const
 {
-    mServer->OutputFormat(
+    return mServer->OutputFormat(
         "%x:%x:%x:%x:%x:%x:%x:%x", HostSwap16(aAddress.mFields.m16[0]), HostSwap16(aAddress.mFields.m16[1]),
         HostSwap16(aAddress.mFields.m16[2]), HostSwap16(aAddress.mFields.m16[3]), HostSwap16(aAddress.mFields.m16[4]),
         HostSwap16(aAddress.mFields.m16[5]), HostSwap16(aAddress.mFields.m16[6]), HostSwap16(aAddress.mFields.m16[7]));
@@ -357,14 +389,14 @@
 {
     char *endptr;
     aLong = strtol(aString, &endptr, 0);
-    return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_PARSE;
+    return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_INVALID_ARGS;
 }
 
 otError Interpreter::ParseUnsignedLong(char *aString, unsigned long &aUnsignedLong)
 {
     char *endptr;
     aUnsignedLong = strtoul(aString, &endptr, 0);
-    return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_PARSE;
+    return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_INVALID_ARGS;
 }
 
 otError Interpreter::ParsePingInterval(const char *aString, uint32_t &aInterval)
@@ -396,14 +428,14 @@
         else if (*aString == '.')
         {
             // Accept only one dot character.
-            VerifyOrExit(factor == msFactor, error = OT_ERROR_PARSE);
+            VerifyOrExit(factor == msFactor, error = OT_ERROR_INVALID_ARGS);
 
             // Start analyzing hundreds of milliseconds.
             factor /= 10;
         }
         else
         {
-            ExitNow(error = OT_ERROR_PARSE);
+            ExitNow(error = OT_ERROR_INVALID_ARGS);
         }
 
         aString++;
@@ -413,26 +445,224 @@
     return error;
 }
 
-void Interpreter::ProcessHelp(int argc, char *argv[])
+void Interpreter::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     for (unsigned int i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
         mServer->OutputFormat("%s\r\n", sCommands[i].mName);
     }
 
-    for (unsigned int i = 0; i < mUserCommandsLength; i++)
+    for (uint8_t i = 0; i < mUserCommandsLength; i++)
     {
         mServer->OutputFormat("%s\r\n", mUserCommands[i].mName);
     }
+
+    AppendResult(OT_ERROR_NONE);
 }
 
-void Interpreter::ProcessBufferInfo(int argc, char *argv[])
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+void Interpreter::ProcessBackboneRouter(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgs);
+    otError                error = OT_ERROR_INVALID_COMMAND;
+    otBackboneRouterConfig config;
+
+    if (aArgsLength == 0)
+    {
+        if (otBackboneRouterGetPrimary(mInstance, &config) == OT_ERROR_NONE)
+        {
+            mServer->OutputFormat("BBR Primary:\r\n");
+            mServer->OutputFormat("server16: 0x%04X\r\n", config.mServer16);
+            mServer->OutputFormat("seqno:    %d\r\n", config.mSequenceNumber);
+            mServer->OutputFormat("delay:    %d secs\r\n", config.mReregistrationDelay);
+            mServer->OutputFormat("timeout:  %d secs\r\n", config.mMlrTimeout);
+        }
+        else
+        {
+            mServer->OutputFormat("BBR Primary: None\r\n");
+        }
+
+        error = OT_ERROR_NONE;
+    }
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    else
+    {
+        error = ProcessBackboneRouterLocal(aArgsLength, aArgs);
+    }
+#endif
+
+    AppendResult(error);
+}
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+otError Interpreter::ProcessBackboneRouterLocal(uint8_t aArgsLength, char *aArgs[])
+{
+    otError                error = OT_ERROR_NONE;
+    otBackboneRouterConfig config;
+    unsigned long          value;
+
+    if (strcmp(aArgs[0], "disable") == 0)
+    {
+        otBackboneRouterSetEnabled(mInstance, false);
+    }
+    else if (strcmp(aArgs[0], "enable") == 0)
+    {
+        otBackboneRouterSetEnabled(mInstance, true);
+    }
+    else if (strcmp(aArgs[0], "jitter") == 0)
+    {
+        if (aArgsLength == 1)
+        {
+            mServer->OutputFormat("%d\r\n", otBackboneRouterGetRegistrationJitter(mInstance));
+        }
+        else if (aArgsLength == 2)
+        {
+            SuccessOrExit(error = ParseUnsignedLong(aArgs[1], value));
+            otBackboneRouterSetRegistrationJitter(mInstance, static_cast<uint8_t>(value));
+        }
+    }
+    else if (strcmp(aArgs[0], "register") == 0)
+    {
+        SuccessOrExit(error = otBackboneRouterRegister(mInstance));
+    }
+    else if (strcmp(aArgs[0], "state") == 0)
+    {
+        switch (otBackboneRouterGetState(mInstance))
+        {
+        case OT_BACKBONE_ROUTER_STATE_DISABLED:
+            mServer->OutputFormat("Disabled\r\n");
+            break;
+        case OT_BACKBONE_ROUTER_STATE_SECONDARY:
+            mServer->OutputFormat("Secondary\r\n");
+            break;
+        case OT_BACKBONE_ROUTER_STATE_PRIMARY:
+            mServer->OutputFormat("Primary\r\n");
+            break;
+        }
+    }
+    else if (strcmp(aArgs[0], "config") == 0)
+    {
+        otBackboneRouterGetConfig(mInstance, &config);
+
+        if (aArgsLength == 1)
+        {
+            mServer->OutputFormat("seqno:    %d\r\n", config.mSequenceNumber);
+            mServer->OutputFormat("delay:    %d secs\r\n", config.mReregistrationDelay);
+            mServer->OutputFormat("timeout:  %d secs\r\n", config.mMlrTimeout);
+        }
+        else
+        {
+            // Set local Backbone Router configuration.
+            for (int argCur = 1; argCur < aArgsLength; argCur++)
+            {
+                VerifyOrExit(argCur + 1 < aArgsLength, error = OT_ERROR_INVALID_ARGS);
+
+                if (strcmp(aArgs[argCur], "seqno") == 0)
+                {
+                    SuccessOrExit(error = ParseUnsignedLong(aArgs[++argCur], value));
+                    config.mSequenceNumber = static_cast<uint8_t>(value);
+                }
+                else if (strcmp(aArgs[argCur], "delay") == 0)
+                {
+                    SuccessOrExit(error = ParseUnsignedLong(aArgs[++argCur], value));
+                    config.mReregistrationDelay = static_cast<uint16_t>(value);
+                }
+                else if (strcmp(aArgs[argCur], "timeout") == 0)
+                {
+                    SuccessOrExit(error = ParseUnsignedLong(aArgs[++argCur], value));
+                    config.mMlrTimeout = static_cast<uint32_t>(value);
+                }
+                else
+                {
+                    ExitNow(error = OT_ERROR_INVALID_ARGS);
+                }
+            }
+
+            SuccessOrExit(error = otBackboneRouterSetConfig(mInstance, &config));
+        }
+    }
+    else
+    {
+        error = OT_ERROR_INVALID_COMMAND;
+    }
+
+exit:
+    return error;
+}
+#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+
+void Interpreter::ProcessDomainName(uint8_t aArgsLength, char *aArgs[])
+{
+    otError error = OT_ERROR_NONE;
+
+    if (aArgsLength == 0)
+    {
+        const char *domainName = otThreadGetDomainName(mInstance);
+        mServer->OutputFormat("%s\r\n", static_cast<const char *>(domainName));
+    }
+    else
+    {
+        SuccessOrExit(error = otThreadSetDomainName(mInstance, aArgs[0]));
+    }
+
+exit:
+    AppendResult(error);
+}
+
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+void Interpreter::ProcessDua(uint8_t aArgsLength, char *aArgs[])
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(aArgsLength >= 1 && strcmp(aArgs[0], "iid") == 0, error = OT_ERROR_INVALID_COMMAND);
+
+    switch (aArgsLength)
+    {
+    case 1:
+    {
+        const otIp6InterfaceIdentifier *iid = otThreadGetFixedDuaInterfaceIdentifier(mInstance);
+
+        if (iid != nullptr)
+        {
+            OutputBytes(iid->mFields.m8, sizeof(otIp6InterfaceIdentifier));
+            mServer->OutputFormat("\r\n");
+        }
+        break;
+    }
+    case 2:
+        if (strcmp(aArgs[1], "clear") == 0)
+        {
+            SuccessOrExit(error = otThreadSetFixedDuaInterfaceIdentifier(mInstance, nullptr));
+        }
+        else
+        {
+            otIp6InterfaceIdentifier iid;
+
+            VerifyOrExit(Hex2Bin(aArgs[1], iid.mFields.m8, sizeof(otIp6InterfaceIdentifier)) ==
+                             sizeof(otIp6InterfaceIdentifier),
+                         error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = otThreadSetFixedDuaInterfaceIdentifier(mInstance, &iid));
+        }
+        break;
+    default:
+        error = OT_ERROR_INVALID_ARGS;
+        break;
+    }
+
+exit:
+    AppendResult(error);
+}
+#endif // OPENTHREAD_CONFIG_DUA_ENABLE
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
+void Interpreter::ProcessBufferInfo(uint8_t aArgsLength, char *aArgs[])
+{
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otBufferInfo bufferInfo;
 
@@ -454,27 +684,27 @@
     AppendResult(OT_ERROR_NONE);
 }
 
-void Interpreter::ProcessChannel(int argc, char *argv[])
+void Interpreter::ProcessChannel(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otLinkGetChannel(mInstance));
     }
-    else if (strcmp(argv[0], "supported") == 0)
+    else if (strcmp(aArgs[0], "supported") == 0)
     {
         mServer->OutputFormat("0x%x\r\n", otPlatRadioGetSupportedChannelMask(mInstance));
     }
-    else if (strcmp(argv[0], "preferred") == 0)
+    else if (strcmp(aArgs[0], "preferred") == 0)
     {
         mServer->OutputFormat("0x%x\r\n", otPlatRadioGetPreferredChannelMask(mInstance));
     }
 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
-    else if (strcmp(argv[0], "monitor") == 0)
+    else if (strcmp(aArgs[0], "monitor") == 0)
     {
-        if (argc == 1)
+        if (aArgsLength == 1)
         {
             mServer->OutputFormat("enabled: %d\r\n", otChannelMonitorIsEnabled(mInstance));
             if (otChannelMonitorIsEnabled(mInstance))
@@ -506,11 +736,11 @@
                 mServer->OutputFormat("\r\n");
             }
         }
-        else if (strcmp(argv[1], "start") == 0)
+        else if (strcmp(aArgs[1], "start") == 0)
         {
             error = otChannelMonitorSetEnabled(mInstance, true);
         }
-        else if (strcmp(argv[1], "stop") == 0)
+        else if (strcmp(aArgs[1], "stop") == 0)
         {
             error = otChannelMonitorSetEnabled(mInstance, false);
         }
@@ -521,9 +751,9 @@
     }
 #endif
 #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && OPENTHREAD_FTD
-    else if (strcmp(argv[0], "manager") == 0)
+    else if (strcmp(aArgs[0], "manager") == 0)
     {
-        if (argc == 1)
+        if (aArgsLength == 1)
         {
             mServer->OutputFormat("channel: %d\r\n", otChannelManagerGetRequestedChannel(mInstance));
             mServer->OutputFormat("auto: %d\r\n", otChannelManagerGetAutoChannelSelectionEnabled(mInstance));
@@ -539,48 +769,48 @@
                 mServer->OutputFormat("favored: %s\r\n", supportedMask.ToString().AsCString());
             }
         }
-        else if (strcmp(argv[1], "change") == 0)
+        else if (strcmp(aArgs[1], "change") == 0)
         {
-            VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             otChannelManagerRequestChannelChange(mInstance, static_cast<uint8_t>(value));
         }
 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
-        else if (strcmp(argv[1], "select") == 0)
+        else if (strcmp(aArgs[1], "select") == 0)
         {
-            VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             error = otChannelManagerRequestChannelSelect(mInstance, (value != 0) ? true : false);
         }
 #endif
-        else if (strcmp(argv[1], "auto") == 0)
+        else if (strcmp(aArgs[1], "auto") == 0)
         {
-            VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             otChannelManagerSetAutoChannelSelectionEnabled(mInstance, (value != 0) ? true : false);
         }
-        else if (strcmp(argv[1], "delay") == 0)
+        else if (strcmp(aArgs[1], "delay") == 0)
         {
-            VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             error = otChannelManagerSetDelay(mInstance, static_cast<uint8_t>(value));
         }
-        else if (strcmp(argv[1], "interval") == 0)
+        else if (strcmp(aArgs[1], "interval") == 0)
         {
-            VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             error = otChannelManagerSetAutoChannelSelectionInterval(mInstance, static_cast<uint32_t>(value));
         }
-        else if (strcmp(argv[1], "supported") == 0)
+        else if (strcmp(aArgs[1], "supported") == 0)
         {
-            VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             otChannelManagerSetSupportedChannels(mInstance, static_cast<uint32_t>(value));
         }
-        else if (strcmp(argv[1], "favored") == 0)
+        else if (strcmp(aArgs[1], "favored") == 0)
         {
-            VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             otChannelManagerSetFavoredChannels(mInstance, static_cast<uint32_t>(value));
         }
         else
@@ -591,7 +821,7 @@
 #endif
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         error = otLinkSetChannel(mInstance, static_cast<uint8_t>(value));
     }
 
@@ -600,18 +830,18 @@
 }
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessChild(int argc, char *argv[])
+void Interpreter::ProcessChild(uint8_t aArgsLength, char *aArgs[])
 {
     otError     error = OT_ERROR_NONE;
     otChildInfo childInfo;
     long        value;
     bool        isTable;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    isTable = (strcmp(argv[0], "table") == 0);
+    isTable = (strcmp(aArgs[0], "table") == 0);
 
-    if (isTable || strcmp(argv[0], "list") == 0)
+    if (isTable || strcmp(aArgs[0], "list") == 0)
     {
         uint16_t maxChildren;
 
@@ -663,7 +893,7 @@
         ExitNow();
     }
 
-    SuccessOrExit(error = ParseLong(argv[0], value));
+    SuccessOrExit(error = ParseLong(aArgs[0], value));
     SuccessOrExit(error = otThreadGetChildInfoById(mInstance, static_cast<uint16_t>(value), &childInfo));
 
     mServer->OutputFormat("Child ID: %d\r\n", childInfo.mChildId);
@@ -710,54 +940,79 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessChildIp(int argc, char *argv[])
+void Interpreter::ProcessChildIp(uint8_t aArgsLength, char *aArgs[])
 {
-    otError  error = OT_ERROR_NONE;
-    uint16_t maxChildren;
+    OT_UNUSED_VARIABLE(aArgs);
+    otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc == 0, error = OT_ERROR_INVALID_ARGS);
-
-    maxChildren = otThreadGetMaxAllowedChildren(mInstance);
-
-    for (uint16_t childIndex = 0; childIndex < maxChildren; childIndex++)
+    if (aArgsLength == 0)
     {
-        otChildIp6AddressIterator iterator = OT_CHILD_IP6_ADDRESS_ITERATOR_INIT;
-        otIp6Address              ip6Address;
-        otChildInfo               childInfo;
+        uint16_t maxChildren = otThreadGetMaxAllowedChildren(mInstance);
 
-        if ((otThreadGetChildInfoByIndex(mInstance, childIndex, &childInfo) != OT_ERROR_NONE) ||
-            childInfo.mIsStateRestoring)
+        for (uint16_t childIndex = 0; childIndex < maxChildren; childIndex++)
         {
-            continue;
-        }
+            otChildIp6AddressIterator iterator = OT_CHILD_IP6_ADDRESS_ITERATOR_INIT;
+            otIp6Address              ip6Address;
+            otChildInfo               childInfo;
 
-        iterator = OT_CHILD_IP6_ADDRESS_ITERATOR_INIT;
+            if ((otThreadGetChildInfoByIndex(mInstance, childIndex, &childInfo) != OT_ERROR_NONE) ||
+                childInfo.mIsStateRestoring)
+            {
+                continue;
+            }
 
-        while (otThreadGetChildNextIp6Address(mInstance, childIndex, &iterator, &ip6Address) == OT_ERROR_NONE)
-        {
-            mServer->OutputFormat("%04x: ", childInfo.mRloc16);
-            OutputIp6Address(ip6Address);
-            mServer->OutputFormat("\r\n");
+            iterator = OT_CHILD_IP6_ADDRESS_ITERATOR_INIT;
+
+            while (otThreadGetChildNextIp6Address(mInstance, childIndex, &iterator, &ip6Address) == OT_ERROR_NONE)
+            {
+                mServer->OutputFormat("%04x: ", childInfo.mRloc16);
+                OutputIp6Address(ip6Address);
+                mServer->OutputFormat("\r\n");
+            }
         }
     }
+    else if (strcmp(aArgs[0], "max") == 0)
+    {
+        if (aArgsLength == 1)
+        {
+            mServer->OutputFormat("%d\r\n", otThreadGetMaxChildIpAddresses(mInstance));
+        }
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
+        else if (aArgsLength == 2)
+        {
+            unsigned long value;
+            SuccessOrExit(error = ParseUnsignedLong(aArgs[1], value));
+            SuccessOrExit(error = otThreadSetMaxChildIpAddresses(mInstance, static_cast<uint8_t>(value)));
+        }
+#endif
+        else
+        {
+            error = OT_ERROR_INVALID_ARGS;
+        }
+    }
+    else
+    {
+        error = OT_ERROR_INVALID_COMMAND;
+    }
 
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
 exit:
-    OT_UNUSED_VARIABLE(argv);
+#endif
     AppendResult(error);
 }
 
-void Interpreter::ProcessChildMax(int argc, char *argv[])
+void Interpreter::ProcessChildMax(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetMaxAllowedChildren(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         SuccessOrExit(error = otThreadSetMaxAllowedChildren(mInstance, static_cast<uint16_t>(value)));
     }
 
@@ -766,18 +1021,18 @@
 }
 #endif // OPENTHREAD_FTD
 
-void Interpreter::ProcessChildTimeout(int argc, char *argv[])
+void Interpreter::ProcessChildTimeout(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetChildTimeout(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         otThreadSetChildTimeout(mInstance, static_cast<uint32_t>(value));
     }
 
@@ -787,10 +1042,10 @@
 
 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
 
-void Interpreter::ProcessCoap(int argc, char *argv[])
+void Interpreter::ProcessCoap(uint8_t aArgsLength, char *aArgs[])
 {
     otError error;
-    error = mCoap.Process(argc, argv);
+    error = mCoap.Process(aArgsLength, aArgs);
     AppendResult(error);
 }
 
@@ -798,33 +1053,33 @@
 
 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 
-void Interpreter::ProcessCoapSecure(int argc, char *argv[])
+void Interpreter::ProcessCoapSecure(uint8_t aArgsLength, char *aArgs[])
 {
     otError error;
-    error = mCoapSecure.Process(argc, argv);
+    error = mCoapSecure.Process(aArgsLength, aArgs);
     AppendResult(error);
 }
 
 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 
 #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
-void Interpreter::ProcessCoexMetrics(int argc, char *argv[])
+void Interpreter::ProcessCoexMetrics(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%s\r\n", otPlatRadioIsCoexEnabled(mInstance) ? "Enabled" : "Disabled");
     }
-    else if (strcmp(argv[0], "enable") == 0)
+    else if (strcmp(aArgs[0], "enable") == 0)
     {
         error = otPlatRadioSetCoexEnabled(mInstance, true);
     }
-    else if (strcmp(argv[0], "disable") == 0)
+    else if (strcmp(aArgs[0], "disable") == 0)
     {
         error = otPlatRadioSetCoexEnabled(mInstance, false);
     }
-    else if (strcmp(argv[0], "metrics") == 0)
+    else if (strcmp(aArgs[0], "metrics") == 0)
     {
         otRadioCoexMetrics metrics;
 
@@ -865,18 +1120,18 @@
 #endif // OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessContextIdReuseDelay(int argc, char *argv[])
+void Interpreter::ProcessContextIdReuseDelay(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetContextIdReuseDelay(mInstance));
     }
     else
     {
-        SuccessOrExit(ParseLong(argv[0], value));
+        SuccessOrExit(ParseLong(aArgs[0], value));
         otThreadSetContextIdReuseDelay(mInstance, static_cast<uint32_t>(value));
     }
 
@@ -885,18 +1140,18 @@
 }
 #endif // OPENTHREAD_FTD
 
-void Interpreter::ProcessCounters(int argc, char *argv[])
+void Interpreter::ProcessCounters(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("mac\r\n");
         mServer->OutputFormat("mle\r\n");
     }
-    else if (strcmp(argv[0], "mac") == 0)
+    else if (strcmp(aArgs[0], "mac") == 0)
     {
-        if (argc == 1)
+        if (aArgsLength == 1)
         {
             const otMacCounters *macCounters = otLinkGetCounters(mInstance);
 
@@ -932,7 +1187,7 @@
             mServer->OutputFormat("    RxErrFcs: %d\r\n", macCounters->mRxErrFcs);
             mServer->OutputFormat("    RxErrOther: %d\r\n", macCounters->mRxErrOther);
         }
-        else if ((argc == 2) && (strcmp(argv[0], "reset") == 0))
+        else if ((aArgsLength == 2) && (strcmp(aArgs[1], "reset") == 0))
         {
             otLinkResetCounters(mInstance);
         }
@@ -941,9 +1196,9 @@
             ExitNow(error = OT_ERROR_INVALID_ARGS);
         }
     }
-    else if (strcmp(argv[0], "mle") == 0)
+    else if (strcmp(aArgs[0], "mle") == 0)
     {
-        if (argc == 1)
+        if (aArgsLength == 1)
         {
             const otMleCounters *mleCounters = otThreadGetMleCounters(mInstance);
 
@@ -958,7 +1213,7 @@
                                   mleCounters->mBetterPartitionAttachAttempts);
             mServer->OutputFormat("Parent Changes: %d\r\n", mleCounters->mParentChanges);
         }
-        else if ((argc == 2) && (strcmp(argv[0], "reset") == 0))
+        else if ((aArgsLength == 2) && (strcmp(aArgs[1], "reset") == 0))
         {
             otThreadResetMleCounters(mInstance);
         }
@@ -977,23 +1232,23 @@
 }
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessDelayTimerMin(int argc, char *argv[])
+void Interpreter::ProcessDelayTimerMin(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", (otDatasetGetDelayTimerMinimal(mInstance) / 1000));
     }
-    else if (argc == 1)
+    else if (aArgsLength == 1)
     {
         unsigned long value;
-        SuccessOrExit(error = ParseUnsignedLong(argv[0], value));
+        SuccessOrExit(error = ParseUnsignedLong(aArgs[0], value));
         SuccessOrExit(error = otDatasetSetDelayTimerMinimal(mInstance, static_cast<uint32_t>(value * 1000)));
     }
     else
     {
-        error = OT_ERROR_INVALID_ARGS;
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
     }
 
 exit:
@@ -1001,15 +1256,15 @@
 }
 #endif
 
-void Interpreter::ProcessDiscover(int argc, char *argv[])
+void Interpreter::ProcessDiscover(uint8_t aArgsLength, char *aArgs[])
 {
     otError  error        = OT_ERROR_NONE;
     uint32_t scanChannels = 0;
     long     value;
 
-    if (argc > 0)
+    if (aArgsLength > 0)
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         VerifyOrExit((0 <= value) && (value < static_cast<long>(sizeof(scanChannels) * CHAR_BIT)),
                      error = OT_ERROR_INVALID_ARGS);
         scanChannels = 1 << value;
@@ -1020,33 +1275,34 @@
     mServer->OutputFormat("| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |\r\n");
     mServer->OutputFormat("+---+------------------+------------------+------+------------------+----+-----+-----+\r\n");
 
-    return;
-
 exit:
-    AppendResult(error);
+    if (error != OT_ERROR_NONE)
+    {
+        AppendResult(error);
+    }
 }
 
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
-void Interpreter::ProcessDns(int argc, char *argv[])
+void Interpreter::ProcessDns(uint8_t aArgsLength, char *aArgs[])
 {
     otError          error = OT_ERROR_NONE;
     long             port  = OT_DNS_DEFAULT_SERVER_PORT;
     Ip6::MessageInfo messageInfo;
     otDnsQuery       query;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "resolve") == 0)
+    if (strcmp(aArgs[0], "resolve") == 0)
     {
         VerifyOrExit(!mResolvingInProgress, error = OT_ERROR_BUSY);
-        VerifyOrExit(argc > 1, error = OT_ERROR_INVALID_ARGS);
-        VerifyOrExit(strlen(argv[1]) < OT_DNS_MAX_HOSTNAME_LENGTH, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(aArgsLength > 1, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(strlen(aArgs[1]) < OT_DNS_MAX_HOSTNAME_LENGTH, error = OT_ERROR_INVALID_ARGS);
 
-        strcpy(mResolvingHostname, argv[1]);
+        strcpy(mResolvingHostname, aArgs[1]);
 
-        if (argc > 2)
+        if (aArgsLength > 2)
         {
-            SuccessOrExit(error = messageInfo.GetPeerAddr().FromString(argv[2]));
+            SuccessOrExit(error = messageInfo.GetPeerAddr().FromString(aArgs[2]));
         }
         else
         {
@@ -1054,9 +1310,9 @@
             SuccessOrExit(error = messageInfo.GetPeerAddr().FromString(OT_DNS_DEFAULT_SERVER_IP));
         }
 
-        if (argc > 3)
+        if (aArgsLength > 3)
         {
-            SuccessOrExit(error = ParseLong(argv[3], port));
+            SuccessOrExit(error = ParseLong(aArgs[3], port));
         }
 
         messageInfo.SetPeerPort(static_cast<uint16_t>(port));
@@ -1071,7 +1327,7 @@
     }
     else
     {
-        ExitNow(error = OT_ERROR_INVALID_ARGS);
+        ExitNow(error = OT_ERROR_INVALID_COMMAND);
     }
 
 exit:
@@ -1097,37 +1353,33 @@
 
     if (aResult == OT_ERROR_NONE)
     {
-        if (aAddress != NULL)
+        if (aAddress != nullptr)
         {
             OutputIp6Address(*aAddress);
         }
         mServer->OutputFormat(" TTL: %d\r\n", aTtl);
     }
-    else
-    {
-        AppendResult(aResult);
-    }
+
+    AppendResult(aResult);
 
     mResolvingInProgress = false;
 }
 #endif
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessEidCache(int argc, char *argv[])
+void Interpreter::ProcessEidCache(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
-    otEidCacheEntry entry;
+    otCacheEntryIterator iterator;
+    otCacheEntryInfo     entry;
+
+    memset(&iterator, 0, sizeof(iterator));
 
     for (uint8_t i = 0;; i++)
     {
-        SuccessOrExit(otThreadGetEidCacheEntry(mInstance, i, &entry));
-
-        if (!entry.mValid)
-        {
-            continue;
-        }
+        SuccessOrExit(otThreadGetNextCacheEntry(mInstance, &entry, &iterator));
 
         OutputIp6Address(entry.mTarget);
         mServer->OutputFormat(" %04x\r\n", entry.mRloc16);
@@ -1138,14 +1390,14 @@
 }
 #endif // OPENTHREAD_FTD
 
-void Interpreter::ProcessEui64(int argc, char *argv[])
+void Interpreter::ProcessEui64(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError      error = OT_ERROR_NONE;
     otExtAddress extAddress;
 
-    VerifyOrExit(argc == 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength == 0, error = OT_ERROR_INVALID_ARGS);
 
     otLinkGetFactoryAssignedIeeeEui64(mInstance, &extAddress);
     OutputBytes(extAddress.m8, OT_EXT_ADDRESS_SIZE);
@@ -1155,11 +1407,11 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessExtAddress(int argc, char *argv[])
+void Interpreter::ProcessExtAddress(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         const uint8_t *extAddress = reinterpret_cast<const uint8_t *>(otLinkGetExtendedAddress(mInstance));
         OutputBytes(extAddress, OT_EXT_ADDRESS_SIZE);
@@ -1169,7 +1421,9 @@
     {
         otExtAddress extAddress;
 
-        VerifyOrExit(Hex2Bin(argv[0], extAddress.m8, sizeof(otExtAddress)) >= 0, error = OT_ERROR_PARSE);
+        memset(&extAddress, 0, sizeof(extAddress));
+        VerifyOrExit(Hex2Bin(aArgs[0], extAddress.m8, sizeof(extAddress.m8)) == sizeof(extAddress.m8),
+                     error = OT_ERROR_INVALID_ARGS);
 
         error = otLinkSetExtendedAddress(mInstance, &extAddress);
     }
@@ -1179,35 +1433,62 @@
 }
 
 #if OPENTHREAD_POSIX
-void Interpreter::ProcessExit(int argc, char *argv[])
+void Interpreter::ProcessExit(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     exit(EXIT_SUCCESS);
 }
 #endif
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
-
-void Interpreter::ProcessLogFilename(int argc, char *argv[])
+void Interpreter::ProcessLog(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc == 1, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength >= 1, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = otPlatDebugUart_logfile(argv[0]));
+    if (!strcmp(aArgs[0], "level"))
+    {
+        if (aArgsLength == 1)
+        {
+            mServer->OutputFormat("%d\r\n", otLoggingGetLevel());
+        }
+#if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
+        else if (aArgsLength == 2)
+        {
+            long level;
+
+            SuccessOrExit(error = ParseLong(aArgs[1], level));
+            SuccessOrExit(error = otLoggingSetLevel(static_cast<otLogLevel>(level)));
+        }
+#endif
+        else
+        {
+            ExitNow(error = OT_ERROR_INVALID_ARGS);
+        }
+    }
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
+    else if (!strcmp(aArgs[0], "filename"))
+    {
+        VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
+        SuccessOrExit(error = otPlatDebugUart_logfile(aArgs[1]));
+    }
+#endif
+    else
+    {
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
+    }
 
 exit:
     AppendResult(error);
 }
-#endif
 
-void Interpreter::ProcessExtPanId(int argc, char *argv[])
+void Interpreter::ProcessExtPanId(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         const uint8_t *extPanId = reinterpret_cast<const uint8_t *>(otThreadGetExtendedPanId(mInstance));
         OutputBytes(extPanId, OT_EXT_PAN_ID_SIZE);
@@ -1217,7 +1498,8 @@
     {
         otExtendedPanId extPanId;
 
-        VerifyOrExit(Hex2Bin(argv[0], extPanId.m8, sizeof(extPanId)) >= 0, error = OT_ERROR_PARSE);
+        VerifyOrExit(Hex2Bin(aArgs[0], extPanId.m8, sizeof(extPanId)) == sizeof(extPanId),
+                     error = OT_ERROR_INVALID_ARGS);
 
         error = otThreadSetExtendedPanId(mInstance, &extPanId);
     }
@@ -1226,19 +1508,19 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessFactoryReset(int argc, char *argv[])
+void Interpreter::ProcessFactoryReset(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otInstanceFactoryReset(mInstance);
 }
 
-void Interpreter::ProcessIfconfig(int argc, char *argv[])
+void Interpreter::ProcessIfconfig(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         if (otIp6IsEnabled(mInstance))
         {
@@ -1249,11 +1531,11 @@
             mServer->OutputFormat("down\r\n");
         }
     }
-    else if (strcmp(argv[0], "up") == 0)
+    else if (strcmp(aArgs[0], "up") == 0)
     {
         SuccessOrExit(error = otIp6SetEnabled(mInstance, true));
     }
-    else if (strcmp(argv[0], "down") == 0)
+    else if (strcmp(aArgs[0], "down") == 0)
     {
         SuccessOrExit(error = otIp6SetEnabled(mInstance, false));
     }
@@ -1266,42 +1548,43 @@
     AppendResult(error);
 }
 
-otError Interpreter::ProcessIpAddrAdd(int argc, char *argv[])
+otError Interpreter::ProcessIpAddrAdd(uint8_t aArgsLength, char *aArgs[])
 {
     otError        error;
     otNetifAddress aAddress;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[0], &aAddress.mAddress));
-    aAddress.mPrefixLength = 64;
-    aAddress.mPreferred    = true;
-    aAddress.mValid        = true;
-    error                  = otIp6AddUnicastAddress(mInstance, &aAddress);
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[0], &aAddress.mAddress));
+    aAddress.mPrefixLength  = 64;
+    aAddress.mPreferred     = true;
+    aAddress.mValid         = true;
+    aAddress.mAddressOrigin = OT_ADDRESS_ORIGIN_MANUAL;
+    error                   = otIp6AddUnicastAddress(mInstance, &aAddress);
 
 exit:
     return error;
 }
 
-otError Interpreter::ProcessIpAddrDel(int argc, char *argv[])
+otError Interpreter::ProcessIpAddrDel(uint8_t aArgsLength, char *aArgs[])
 {
     otError             error;
     struct otIp6Address address;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[0], &address));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[0], &address));
     error = otIp6RemoveUnicastAddress(mInstance, &address);
 
 exit:
     return error;
 }
 
-void Interpreter::ProcessIpAddr(int argc, char *argv[])
+void Interpreter::ProcessIpAddr(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         const otNetifAddress *unicastAddrs = otIp6GetUnicastAddresses(mInstance);
 
@@ -1313,32 +1596,32 @@
     }
     else
     {
-        if (strcmp(argv[0], "add") == 0)
+        if (strcmp(aArgs[0], "add") == 0)
         {
-            SuccessOrExit(error = ProcessIpAddrAdd(argc - 1, argv + 1));
+            SuccessOrExit(error = ProcessIpAddrAdd(aArgsLength - 1, aArgs + 1));
         }
-        else if (strcmp(argv[0], "del") == 0)
+        else if (strcmp(aArgs[0], "del") == 0)
         {
-            SuccessOrExit(error = ProcessIpAddrDel(argc - 1, argv + 1));
+            SuccessOrExit(error = ProcessIpAddrDel(aArgsLength - 1, aArgs + 1));
         }
-        else if (strcmp(argv[0], "linklocal") == 0)
+        else if (strcmp(aArgs[0], "linklocal") == 0)
         {
             OutputIp6Address(*otThreadGetLinkLocalIp6Address(mInstance));
             mServer->OutputFormat("\r\n");
         }
-        else if (strcmp(argv[0], "rloc") == 0)
+        else if (strcmp(aArgs[0], "rloc") == 0)
         {
             OutputIp6Address(*otThreadGetRloc(mInstance));
             mServer->OutputFormat("\r\n");
         }
-        else if (strcmp(argv[0], "mleid") == 0)
+        else if (strcmp(aArgs[0], "mleid") == 0)
         {
             OutputIp6Address(*otThreadGetMeshLocalEid(mInstance));
             mServer->OutputFormat("\r\n");
         }
         else
         {
-            ExitNow(error = OT_ERROR_INVALID_ARGS);
+            ExitNow(error = OT_ERROR_INVALID_COMMAND);
         }
     }
 
@@ -1346,39 +1629,39 @@
     AppendResult(error);
 }
 
-otError Interpreter::ProcessIpMulticastAddrAdd(int argc, char *argv[])
+otError Interpreter::ProcessIpMulticastAddrAdd(uint8_t aArgsLength, char *aArgs[])
 {
     otError             error;
     struct otIp6Address address;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[0], &address));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[0], &address));
     error = otIp6SubscribeMulticastAddress(mInstance, &address);
 
 exit:
     return error;
 }
 
-otError Interpreter::ProcessIpMulticastAddrDel(int argc, char *argv[])
+otError Interpreter::ProcessIpMulticastAddrDel(uint8_t aArgsLength, char *aArgs[])
 {
     otError             error;
     struct otIp6Address address;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[0], &address));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[0], &address));
     error = otIp6UnsubscribeMulticastAddress(mInstance, &address);
 
 exit:
     return error;
 }
 
-otError Interpreter::ProcessMulticastPromiscuous(int argc, char *argv[])
+otError Interpreter::ProcessMulticastPromiscuous(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         if (otIp6IsMulticastPromiscuousEnabled(mInstance))
         {
@@ -1391,11 +1674,11 @@
     }
     else
     {
-        if (strcmp(argv[0], "enable") == 0)
+        if (strcmp(aArgs[0], "enable") == 0)
         {
             otIp6SetMulticastPromiscuousEnabled(mInstance, true);
         }
-        else if (strcmp(argv[0], "disable") == 0)
+        else if (strcmp(aArgs[0], "disable") == 0)
         {
             otIp6SetMulticastPromiscuousEnabled(mInstance, false);
         }
@@ -1409,11 +1692,11 @@
     return error;
 }
 
-void Interpreter::ProcessIpMulticastAddr(int argc, char *argv[])
+void Interpreter::ProcessIpMulticastAddr(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         for (const otNetifMulticastAddress *addr = otIp6GetMulticastAddresses(mInstance); addr; addr = addr->mNext)
         {
@@ -1423,21 +1706,21 @@
     }
     else
     {
-        if (strcmp(argv[0], "add") == 0)
+        if (strcmp(aArgs[0], "add") == 0)
         {
-            SuccessOrExit(error = ProcessIpMulticastAddrAdd(argc - 1, argv + 1));
+            SuccessOrExit(error = ProcessIpMulticastAddrAdd(aArgsLength - 1, aArgs + 1));
         }
-        else if (strcmp(argv[0], "del") == 0)
+        else if (strcmp(aArgs[0], "del") == 0)
         {
-            SuccessOrExit(error = ProcessIpMulticastAddrDel(argc - 1, argv + 1));
+            SuccessOrExit(error = ProcessIpMulticastAddrDel(aArgsLength - 1, aArgs + 1));
         }
-        else if (strcmp(argv[0], "promiscuous") == 0)
+        else if (strcmp(aArgs[0], "promiscuous") == 0)
         {
-            SuccessOrExit(error = ProcessMulticastPromiscuous(argc - 1, argv + 1));
+            SuccessOrExit(error = ProcessMulticastPromiscuous(aArgsLength - 1, aArgs + 1));
         }
         else
         {
-            ExitNow(error = OT_ERROR_INVALID_ARGS);
+            ExitNow(error = OT_ERROR_INVALID_COMMAND);
         }
     }
 
@@ -1445,34 +1728,34 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessKeySequence(int argc, char *argv[])
+void Interpreter::ProcessKeySequence(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc == 1 || argc == 2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength == 1 || aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "counter") == 0)
+    if (strcmp(aArgs[0], "counter") == 0)
     {
-        if (argc == 1)
+        if (aArgsLength == 1)
         {
             mServer->OutputFormat("%d\r\n", otThreadGetKeySequenceCounter(mInstance));
         }
         else
         {
-            SuccessOrExit(error = ParseLong(argv[1], value));
+            SuccessOrExit(error = ParseLong(aArgs[1], value));
             otThreadSetKeySequenceCounter(mInstance, static_cast<uint32_t>(value));
         }
     }
-    else if (strcmp(argv[0], "guardtime") == 0)
+    else if (strcmp(aArgs[0], "guardtime") == 0)
     {
-        if (argc == 1)
+        if (aArgsLength == 1)
         {
             mServer->OutputFormat("%d\r\n", otThreadGetKeySwitchGuardTime(mInstance));
         }
         else
         {
-            SuccessOrExit(error = ParseLong(argv[1], value));
+            SuccessOrExit(error = ParseLong(aArgs[1], value));
             otThreadSetKeySwitchGuardTime(mInstance, static_cast<uint32_t>(value));
         }
     }
@@ -1485,10 +1768,10 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessLeaderData(int argc, char *argv[])
+void Interpreter::ProcessLeaderData(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError      error;
     otLeaderData leaderData;
@@ -1506,18 +1789,18 @@
 }
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessLeaderPartitionId(int argc, char *argv[])
+void Interpreter::ProcessLeaderPartitionId(uint8_t aArgsLength, char *aArgs[])
 {
     otError       error = OT_ERROR_NONE;
     unsigned long value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%u\r\n", otThreadGetLocalLeaderPartitionId(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseUnsignedLong(argv[0], value));
+        SuccessOrExit(error = ParseUnsignedLong(aArgs[0], value));
         otThreadSetLocalLeaderPartitionId(mInstance, static_cast<uint32_t>(value));
     }
 
@@ -1525,18 +1808,18 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessLeaderWeight(int argc, char *argv[])
+void Interpreter::ProcessLeaderWeight(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetLocalLeaderWeight(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         otThreadSetLocalLeaderWeight(mInstance, static_cast<uint8_t>(value));
     }
 
@@ -1546,11 +1829,11 @@
 #endif // OPENTHREAD_FTD
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessPskc(int argc, char *argv[])
+void Interpreter::ProcessPskc(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         const otPskc *pskc = otThreadGetPskc(mInstance);
 
@@ -1565,7 +1848,21 @@
     {
         otPskc pskc;
 
-        VerifyOrExit(Hex2Bin(argv[0], pskc.m8, sizeof(pskc)) == OT_PSKC_MAX_SIZE, error = OT_ERROR_PARSE);
+        if (aArgsLength == 1)
+        {
+            VerifyOrExit(Hex2Bin(aArgs[0], pskc.m8, sizeof(pskc)) == sizeof(pskc), error = OT_ERROR_INVALID_ARGS);
+        }
+        else if (!strcmp(aArgs[0], "-p"))
+        {
+            SuccessOrExit(error = otDatasetGeneratePskc(
+                              aArgs[1], reinterpret_cast<const otNetworkName *>(otThreadGetNetworkName(mInstance)),
+                              otThreadGetExtendedPanId(mInstance), &pskc));
+        }
+        else
+        {
+            ExitNow(error = OT_ERROR_INVALID_ARGS);
+        }
+
         SuccessOrExit(error = otThreadSetPskc(mInstance, &pskc));
     }
 
@@ -1574,11 +1871,11 @@
 }
 #endif
 
-void Interpreter::ProcessMasterKey(int argc, char *argv[])
+void Interpreter::ProcessMasterKey(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         const uint8_t *key = reinterpret_cast<const uint8_t *>(otThreadGetMasterKey(mInstance));
 
@@ -1593,7 +1890,7 @@
     {
         otMasterKey key;
 
-        VerifyOrExit(Hex2Bin(argv[0], key.m8, sizeof(key.m8)) == OT_MASTER_KEY_SIZE, error = OT_ERROR_PARSE);
+        VerifyOrExit(Hex2Bin(aArgs[0], key.m8, sizeof(key.m8)) == OT_MASTER_KEY_SIZE, error = OT_ERROR_INVALID_ARGS);
         SuccessOrExit(error = otThreadSetMasterKey(mInstance, &key));
     }
 
@@ -1601,14 +1898,14 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessMode(int argc, char *argv[])
+void Interpreter::ProcessMode(uint8_t aArgsLength, char *aArgs[])
 {
     otError          error = OT_ERROR_NONE;
     otLinkModeConfig linkMode;
 
     memset(&linkMode, 0, sizeof(otLinkModeConfig));
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         linkMode = otThreadGetLinkMode(mInstance);
 
@@ -1636,7 +1933,7 @@
     }
     else
     {
-        for (char *arg = argv[0]; *arg != '\0'; arg++)
+        for (char *arg = aArgs[0]; *arg != '\0'; arg++)
         {
             switch (*arg)
             {
@@ -1657,7 +1954,7 @@
                 break;
 
             default:
-                ExitNow(error = OT_ERROR_PARSE);
+                ExitNow(error = OT_ERROR_INVALID_ARGS);
             }
         }
 
@@ -1669,18 +1966,18 @@
 }
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessNeighbor(int argc, char *argv[])
+void Interpreter::ProcessNeighbor(uint8_t aArgsLength, char *aArgs[])
 {
     otError                error = OT_ERROR_NONE;
     otNeighborInfo         neighborInfo;
     bool                   isTable;
     otNeighborInfoIterator iterator = OT_NEIGHBOR_INFO_ITERATOR_INIT;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    isTable = (strcmp(argv[0], "table") == 0);
+    isTable = (strcmp(aArgs[0], "table") == 0);
 
-    if (isTable || strcmp(argv[0], "list") == 0)
+    if (isTable || strcmp(aArgs[0], "list") == 0)
     {
         if (isTable)
         {
@@ -1728,10 +2025,10 @@
 }
 #endif
 
-void Interpreter::ProcessNetworkDataShow(int argc, char *argv[])
+void Interpreter::ProcessNetworkDataShow(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError error = OT_ERROR_NONE;
     uint8_t data[255];
@@ -1746,53 +2043,136 @@
     AppendResult(error);
 }
 
+#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+void Interpreter::ProcessNetif(uint8_t aArgsLength, char *aArgs[])
+{
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
+
+    otError      error    = OT_ERROR_NONE;
+    const char * netif    = nullptr;
+    unsigned int netifidx = 0;
+
+    SuccessOrExit(error = otPlatGetNetif(mInstance, &netif, &netifidx));
+
+    mServer->OutputFormat("%s:%u\r\n", netif ? netif : "(null)", netifidx);
+
+exit:
+    AppendResult(error);
+}
+#endif
+
+void Interpreter::ProcessNetstat(uint8_t aArgsLength, char *aArgs[])
+{
+    otUdpSocket *socket = otUdpGetSockets(mInstance);
+
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
+
+    mServer->OutputFormat(
+        "|                 Local Address                 |                  Peer Address                 |\n");
+    mServer->OutputFormat(
+        "+-----------------------------------------------+-----------------------------------------------+\n");
+
+    while (socket)
+    {
+        constexpr int kMaxOutputLength = 45;
+        int           outputLength;
+
+        mServer->OutputFormat("| ");
+
+        outputLength = OutputSocketAddress(socket->mSockName);
+        for (int i = outputLength; 0 <= i && i < kMaxOutputLength; ++i)
+        {
+            mServer->OutputFormat(" ");
+        }
+        mServer->OutputFormat(" | ");
+
+        outputLength = OutputSocketAddress(socket->mPeerName);
+        for (int i = outputLength; 0 <= i && i < kMaxOutputLength; ++i)
+        {
+            mServer->OutputFormat(" ");
+        }
+        mServer->OutputFormat(" |\n");
+
+        socket = socket->mNext;
+    }
+
+    AppendResult(OT_ERROR_NONE);
+}
+
+int Interpreter::OutputSocketAddress(const otSockAddr &aAddress)
+{
+    int outputLength;
+    int result = 0;
+
+    VerifyOrExit((outputLength = OutputIp6Address(aAddress.mAddress)) >= 0, result = -1);
+    result += outputLength;
+
+    VerifyOrExit((outputLength = mServer->OutputFormat(":")) >= 0, result = -1);
+    result += outputLength;
+    if (aAddress.mPort == 0)
+    {
+        VerifyOrExit((outputLength = mServer->OutputFormat("*")) >= 0, result = -1);
+        result += outputLength;
+    }
+    else
+    {
+        VerifyOrExit((outputLength = mServer->OutputFormat("%d", aAddress.mPort)) >= 0, result = -1);
+        result += outputLength;
+    }
+
+exit:
+    return result;
+}
+
 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
-void Interpreter::ProcessService(int argc, char *argv[])
+void Interpreter::ProcessService(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "add") == 0)
+    if (strcmp(aArgs[0], "add") == 0)
     {
         otServiceConfig cfg;
         long            enterpriseNumber;
         size_t          length;
 
-        VerifyOrExit(argc > 3, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(aArgsLength > 3, error = OT_ERROR_INVALID_ARGS);
 
-        SuccessOrExit(error = ParseLong(argv[1], enterpriseNumber));
+        SuccessOrExit(error = ParseLong(aArgs[1], enterpriseNumber));
         cfg.mEnterpriseNumber = static_cast<uint32_t>(enterpriseNumber);
 
-        length = strlen(argv[2]);
+        length = strlen(aArgs[2]);
         VerifyOrExit(length <= sizeof(cfg.mServiceData), error = OT_ERROR_NO_BUFS);
         cfg.mServiceDataLength = static_cast<uint8_t>(length);
-        memcpy(cfg.mServiceData, argv[2], cfg.mServiceDataLength);
+        memcpy(cfg.mServiceData, aArgs[2], cfg.mServiceDataLength);
 
-        length = strlen(argv[3]);
+        length = strlen(aArgs[3]);
         VerifyOrExit(length <= sizeof(cfg.mServerConfig.mServerData), error = OT_ERROR_NO_BUFS);
         cfg.mServerConfig.mServerDataLength = static_cast<uint8_t>(length);
-        memcpy(cfg.mServerConfig.mServerData, argv[3], cfg.mServerConfig.mServerDataLength);
+        memcpy(cfg.mServerConfig.mServerData, aArgs[3], cfg.mServerConfig.mServerDataLength);
 
         cfg.mServerConfig.mStable = true;
 
         SuccessOrExit(error = otServerAddService(mInstance, &cfg));
     }
-    else if (strcmp(argv[0], "remove") == 0)
+    else if (strcmp(aArgs[0], "remove") == 0)
     {
         long enterpriseNumber = 0;
 
-        VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
 
-        SuccessOrExit(error = ParseLong(argv[1], enterpriseNumber));
+        SuccessOrExit(error = ParseLong(aArgs[1], enterpriseNumber));
 
         SuccessOrExit(error = otServerRemoveService(mInstance, static_cast<uint32_t>(enterpriseNumber),
-                                                    reinterpret_cast<uint8_t *>(argv[2]),
-                                                    static_cast<uint8_t>(strlen(argv[2]))));
+                                                    reinterpret_cast<uint8_t *>(aArgs[2]),
+                                                    static_cast<uint8_t>(strlen(aArgs[2]))));
     }
     else
     {
-        ExitNow(error = OT_ERROR_INVALID_ARGS);
+        ExitNow(error = OT_ERROR_INVALID_COMMAND);
     }
 
 exit:
@@ -1801,10 +2181,10 @@
 #endif
 
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
-void Interpreter::ProcessNetworkDataRegister(int argc, char *argv[])
+void Interpreter::ProcessNetworkDataRegister(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError error = OT_ERROR_NONE;
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
@@ -1819,18 +2199,18 @@
 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessNetworkIdTimeout(int argc, char *argv[])
+void Interpreter::ProcessNetworkIdTimeout(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetNetworkIdTimeout(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         otThreadSetNetworkIdTimeout(mInstance, static_cast<uint8_t>(value));
     }
 
@@ -1839,18 +2219,18 @@
 }
 #endif // OPENTHREAD_FTD
 
-void Interpreter::ProcessNetworkName(int argc, char *argv[])
+void Interpreter::ProcessNetworkName(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         const char *networkName = otThreadGetNetworkName(mInstance);
-        mServer->OutputFormat("%.*s\r\n", OT_NETWORK_NAME_MAX_SIZE, static_cast<const char *>(networkName));
+        mServer->OutputFormat("%s\r\n", static_cast<const char *>(networkName));
     }
     else
     {
-        SuccessOrExit(error = otThreadSetNetworkName(mInstance, argv[0]));
+        SuccessOrExit(error = otThreadSetNetworkName(mInstance, aArgs[0]));
     }
 
 exit:
@@ -1858,12 +2238,12 @@
 }
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-void Interpreter::ProcessNetworkTime(int argc, char *argv[])
+void Interpreter::ProcessNetworkTime(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         uint64_t            time;
         otNetworkTimeStatus networkTimeStatus;
@@ -1893,12 +2273,12 @@
         mServer->OutputFormat("Time Sync Period: %ds\r\n", otNetworkTimeGetSyncPeriod(mInstance));
         mServer->OutputFormat("XTAL Threshold:   %dppm\r\n", otNetworkTimeGetXtalThreshold(mInstance));
     }
-    else if (argc == 2)
+    else if (aArgsLength == 2)
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         SuccessOrExit(error = otNetworkTimeSetSyncPeriod(mInstance, static_cast<uint16_t>(value)));
 
-        SuccessOrExit(error = ParseLong(argv[1], value));
+        SuccessOrExit(error = ParseLong(aArgs[1], value));
         SuccessOrExit(error = otNetworkTimeSetXtalThreshold(mInstance, static_cast<uint16_t>(value)));
     }
     else
@@ -1911,18 +2291,18 @@
 }
 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 
-void Interpreter::ProcessPanId(int argc, char *argv[])
+void Interpreter::ProcessPanId(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("0x%04x\r\n", otLinkGetPanId(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         error = otLinkSetPanId(mInstance, static_cast<otPanId>(value));
     }
 
@@ -1930,10 +2310,10 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessParent(int argc, char *argv[])
+void Interpreter::ProcessParent(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError      error = OT_ERROR_NONE;
     otRouterInfo parentInfo;
@@ -1958,18 +2338,18 @@
 }
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessParentPriority(int argc, char *argv[])
+void Interpreter::ProcessParentPriority(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetParentPriority(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         error = otThreadSetParentPriority(mInstance, static_cast<int8_t>(value));
     }
 
@@ -1983,97 +2363,92 @@
                                     const otMessageInfo *aMessageInfo,
                                     const otIcmp6Header *aIcmpHeader)
 {
-    static_cast<Interpreter *>(aContext)->HandleIcmpReceive(*static_cast<Message *>(aMessage),
-                                                            *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
-                                                            *static_cast<const Ip6::IcmpHeader *>(aIcmpHeader));
+    static_cast<Interpreter *>(aContext)->HandleIcmpReceive(aMessage, aMessageInfo, aIcmpHeader);
 }
 
-void Interpreter::HandleIcmpReceive(Message &               aMessage,
-                                    const Ip6::MessageInfo &aMessageInfo,
-                                    const otIcmp6Header &   aIcmpHeader)
+void Interpreter::HandleIcmpReceive(otMessage *          aMessage,
+                                    const otMessageInfo *aMessageInfo,
+                                    const otIcmp6Header *aIcmpHeader)
 {
     uint32_t timestamp = 0;
+    uint16_t dataSize;
 
-    VerifyOrExit(aIcmpHeader.mType == OT_ICMP6_TYPE_ECHO_REPLY);
+    VerifyOrExit(aIcmpHeader->mType == OT_ICMP6_TYPE_ECHO_REPLY, OT_NOOP);
+    VerifyOrExit((mPingIdentifier != 0) && (mPingIdentifier == HostSwap16(aIcmpHeader->mData.m16[0])), OT_NOOP);
 
-    mServer->OutputFormat("%u bytes from ",
-                          aMessage.GetLength() - aMessage.GetOffset() + static_cast<uint16_t>(sizeof(otIcmp6Header)));
+    dataSize = otMessageGetLength(aMessage) - otMessageGetOffset(aMessage);
+    mServer->OutputFormat("%u bytes from ", dataSize + static_cast<uint16_t>(sizeof(otIcmp6Header)));
 
-    OutputIp6Address(aMessageInfo.GetPeerAddr());
+    OutputIp6Address(aMessageInfo->mPeerAddr);
 
-    mServer->OutputFormat(": icmp_seq=%d hlim=%d", HostSwap16(aIcmpHeader.mData.m16[1]), aMessageInfo.mHopLimit);
+    mServer->OutputFormat(": icmp_seq=%d hlim=%d", HostSwap16(aIcmpHeader->mData.m16[1]), aMessageInfo->mHopLimit);
 
-    if (aMessage.Read(aMessage.GetOffset(), sizeof(uint32_t), &timestamp) >= static_cast<int>(sizeof(uint32_t)))
+    if (otMessageRead(aMessage, otMessageGetOffset(aMessage), &timestamp, sizeof(uint32_t)) == sizeof(uint32_t))
     {
         mServer->OutputFormat(" time=%dms", TimerMilli::GetNow().GetValue() - HostSwap32(timestamp));
     }
 
     mServer->OutputFormat("\r\n");
 
+    SignalPingReply(static_cast<const Ip6::MessageInfo *>(aMessageInfo)->GetPeerAddr(), dataSize, HostSwap32(timestamp),
+                    aMessageInfo->mHopLimit);
+
 exit:
     return;
 }
 
-void Interpreter::ProcessPing(int argc, char *argv[])
+void Interpreter::ProcessPing(uint8_t aArgsLength, char *aArgs[])
 {
     otError  error = OT_ERROR_NONE;
     uint8_t  index = 1;
     long     value;
     uint32_t interval;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "stop") == 0)
+    if (strcmp(aArgs[0], "stop") == 0)
     {
-        if (!mPingTimer.IsRunning())
-        {
-            error = OT_ERROR_INVALID_STATE;
-        }
-        else
-        {
-            mPingTimer.Stop();
-        }
-
+        mPingIdentifier = 0;
+        VerifyOrExit(mPingTimer.IsRunning(), error = OT_ERROR_INVALID_STATE);
+        mPingTimer.Stop();
         ExitNow();
     }
 
     VerifyOrExit(!mPingTimer.IsRunning(), error = OT_ERROR_BUSY);
 
-    mMessageInfo = Ip6::MessageInfo();
-    SuccessOrExit(error = mMessageInfo.GetPeerAddr().FromString(argv[0]));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[0], &mPingDestAddress));
 
-    mLength   = 8;
-    mCount    = 1;
-    mInterval = 1000;
+    mPingLength            = kDefaultPingLength;
+    mPingCount             = kDefaultPingCount;
+    mPingInterval          = kDefaultPingInterval;
+    mPingHopLimit          = 0;
+    mPingAllowZeroHopLimit = false;
 
-    while (index < argc)
+    while (index < aArgsLength)
     {
         switch (index)
         {
         case 1:
-            SuccessOrExit(error = ParseLong(argv[index], value));
-            mLength = static_cast<uint16_t>(value);
+            SuccessOrExit(error = ParseLong(aArgs[index], value));
+            mPingLength = static_cast<uint16_t>(value);
             break;
 
         case 2:
-            SuccessOrExit(error = ParseLong(argv[index], value));
-            mCount = static_cast<uint16_t>(value);
+            SuccessOrExit(error = ParseLong(aArgs[index], value));
+            mPingCount = static_cast<uint16_t>(value);
             break;
 
         case 3:
-            SuccessOrExit(error = ParsePingInterval(argv[index], interval));
+            SuccessOrExit(error = ParsePingInterval(aArgs[index], interval));
             VerifyOrExit(0 < interval && interval <= Timer::kMaxDelay, error = OT_ERROR_INVALID_ARGS);
-            mInterval = interval;
+            mPingInterval = interval;
             break;
 
         case 4:
-            SuccessOrExit(error = ParseLong(argv[index], value));
+            SuccessOrExit(error = ParseLong(aArgs[index], value));
             VerifyOrExit(0 <= value && value <= 255, error = OT_ERROR_INVALID_ARGS);
-            mMessageInfo.mHopLimit = static_cast<uint8_t>(value);
-            if (value == 0)
-            {
-                mMessageInfo.mAllowZeroHopLimit = true;
-            }
+            mPingHopLimit          = static_cast<uint8_t>(value);
+            mPingAllowZeroHopLimit = (mPingHopLimit == 0);
             break;
 
         default:
@@ -2083,9 +2458,14 @@
         index++;
     }
 
-    HandlePingTimer();
+    mPingIdentifier++;
 
-    return;
+    if (mPingIdentifier == 0)
+    {
+        mPingIdentifier++;
+    }
+
+    SendPing();
 
 exit:
     AppendResult(error);
@@ -2093,47 +2473,56 @@
 
 void Interpreter::HandlePingTimer(Timer &aTimer)
 {
-    GetOwner(aTimer).HandlePingTimer();
+    GetOwner(aTimer).SendPing();
 }
 
-void Interpreter::HandlePingTimer()
+void Interpreter::SendPing(void)
 {
-    otError  error     = OT_ERROR_NONE;
-    uint32_t timestamp = HostSwap32(TimerMilli::GetNow().GetValue());
+    uint32_t      timestamp = HostSwap32(TimerMilli::GetNow().GetValue());
+    otMessage *   message   = nullptr;
+    otMessageInfo messageInfo;
 
-    otMessage *          message;
-    const otMessageInfo *messageInfo = static_cast<const otMessageInfo *>(&mMessageInfo);
+    memset(&messageInfo, 0, sizeof(messageInfo));
+    messageInfo.mPeerAddr          = mPingDestAddress;
+    messageInfo.mHopLimit          = mPingHopLimit;
+    messageInfo.mAllowZeroHopLimit = mPingAllowZeroHopLimit;
 
-    VerifyOrExit((message = otIp6NewMessage(mInstance, NULL)) != NULL, error = OT_ERROR_NO_BUFS);
-    SuccessOrExit(error = otMessageAppend(message, &timestamp, sizeof(timestamp)));
-    SuccessOrExit(error = otMessageSetLength(message, mLength));
-    SuccessOrExit(error = otIcmp6SendEchoRequest(mInstance, message, messageInfo, 1));
+    message = otIp6NewMessage(mInstance, nullptr);
+    VerifyOrExit(message != nullptr, OT_NOOP);
+
+    SuccessOrExit(otMessageAppend(message, &timestamp, sizeof(timestamp)));
+    SuccessOrExit(otMessageSetLength(message, mPingLength));
+    SuccessOrExit(otIcmp6SendEchoRequest(mInstance, message, &messageInfo, mPingIdentifier));
+
+    SignalPingRequest(static_cast<Ip6::MessageInfo *>(&messageInfo)->GetPeerAddr(), mPingLength, HostSwap32(timestamp),
+                      messageInfo.mHopLimit);
+
+    message = nullptr;
 
 exit:
-
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (message != nullptr)
     {
         otMessageFree(message);
     }
 
-    if (--mCount)
+    if (--mPingCount)
     {
-        mPingTimer.Start(mInterval);
+        mPingTimer.Start(mPingInterval);
     }
 }
 
-void Interpreter::ProcessPollPeriod(int argc, char *argv[])
+void Interpreter::ProcessPollPeriod(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otLinkGetPollPeriod(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         error = otLinkSetPollPeriod(mInstance, static_cast<uint32_t>(value));
     }
 
@@ -2141,11 +2530,11 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessPromiscuous(int argc, char *argv[])
+void Interpreter::ProcessPromiscuous(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         if (otLinkIsPromiscuous(mInstance) && otPlatRadioGetPromiscuous(mInstance))
         {
@@ -2158,14 +2547,14 @@
     }
     else
     {
-        if (strcmp(argv[0], "enable") == 0)
+        if (strcmp(aArgs[0], "enable") == 0)
         {
-            otLinkSetPcapCallback(mInstance, &HandleLinkPcapReceive, this);
             SuccessOrExit(error = otLinkSetPromiscuous(mInstance, true));
+            otLinkSetPcapCallback(mInstance, &HandleLinkPcapReceive, this);
         }
-        else if (strcmp(argv[0], "disable") == 0)
+        else if (strcmp(aArgs[0], "disable") == 0)
         {
-            otLinkSetPcapCallback(mInstance, NULL, NULL);
+            otLinkSetPcapCallback(mInstance, nullptr, nullptr);
             SuccessOrExit(error = otLinkSetPromiscuous(mInstance, false));
         }
         else
@@ -2252,54 +2641,52 @@
 }
 
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
-otError Interpreter::ProcessPrefixAdd(int argc, char *argv[])
+otError Interpreter::ProcessPrefixAdd(uint8_t aArgsLength, char *aArgs[])
 {
     otError              error = OT_ERROR_NONE;
     otBorderRouterConfig config;
-    int                  argcur = 0;
+    uint8_t              argcur = 0;
+    char *               prefixLengthStr;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
     memset(&config, 0, sizeof(otBorderRouterConfig));
 
-    char *prefixLengthStr;
-    char *endptr;
-
-    if ((prefixLengthStr = strchr(argv[argcur], '/')) == NULL)
+    if ((prefixLengthStr = strchr(aArgs[argcur], '/')) == nullptr)
     {
         ExitNow();
     }
 
     *prefixLengthStr++ = '\0';
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[argcur], &config.mPrefix.mPrefix));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[argcur], &config.mPrefix.mPrefix));
 
-    config.mPrefix.mLength = static_cast<uint8_t>(strtol(prefixLengthStr, &endptr, 0));
-
-    if (*endptr != '\0')
     {
-        ExitNow(error = OT_ERROR_PARSE);
+        unsigned long length;
+
+        SuccessOrExit(error = ParseUnsignedLong(prefixLengthStr, length));
+        config.mPrefix.mLength = static_cast<uint8_t>(length);
     }
 
     argcur++;
 
-    for (; argcur < argc; argcur++)
+    for (; argcur < aArgsLength; argcur++)
     {
-        if (strcmp(argv[argcur], "high") == 0)
+        if (strcmp(aArgs[argcur], "high") == 0)
         {
             config.mPreference = OT_ROUTE_PREFERENCE_HIGH;
         }
-        else if (strcmp(argv[argcur], "med") == 0)
+        else if (strcmp(aArgs[argcur], "med") == 0)
         {
             config.mPreference = OT_ROUTE_PREFERENCE_MED;
         }
-        else if (strcmp(argv[argcur], "low") == 0)
+        else if (strcmp(aArgs[argcur], "low") == 0)
         {
             config.mPreference = OT_ROUTE_PREFERENCE_LOW;
         }
         else
         {
-            for (char *arg = argv[argcur]; *arg != '\0'; arg++)
+            for (char *arg = aArgs[argcur]; *arg != '\0'; arg++)
             {
                 switch (*arg)
                 {
@@ -2331,8 +2718,17 @@
                     config.mStable = true;
                     break;
 
+                case 'n':
+                    config.mNdDns = true;
+                    break;
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+                case 'D':
+                    config.mDp = true;
+                    break;
+#endif
                 default:
-                    ExitNow(error = OT_ERROR_PARSE);
+                    ExitNow(error = OT_ERROR_INVALID_ARGS);
                 }
             }
         }
@@ -2344,35 +2740,33 @@
     return error;
 }
 
-otError Interpreter::ProcessPrefixRemove(int argc, char *argv[])
+otError Interpreter::ProcessPrefixRemove(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
+    OT_UNUSED_VARIABLE(aArgsLength);
 
     otError            error = OT_ERROR_NONE;
     struct otIp6Prefix prefix;
-    int                argcur = 0;
+    uint8_t            argcur = 0;
+    char *             prefixLengthStr;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
     memset(&prefix, 0, sizeof(otIp6Prefix));
 
-    char *prefixLengthStr;
-    char *endptr;
-
-    if ((prefixLengthStr = strchr(argv[argcur], '/')) == NULL)
+    if ((prefixLengthStr = strchr(aArgs[argcur], '/')) == nullptr)
     {
         ExitNow();
     }
 
     *prefixLengthStr++ = '\0';
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[argcur], &prefix.mPrefix));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[argcur], &prefix.mPrefix));
 
-    prefix.mLength = static_cast<uint8_t>(strtol(prefixLengthStr, &endptr, 0));
-
-    if (*endptr != '\0')
     {
-        ExitNow(error = OT_ERROR_PARSE);
+        unsigned long length;
+
+        SuccessOrExit(error = ParseUnsignedLong(prefixLengthStr, length));
+        prefix.mLength = static_cast<uint8_t>(length);
     }
 
     error = otBorderRouterRemoveOnMeshPrefix(mInstance, &prefix);
@@ -2381,6 +2775,76 @@
     return error;
 }
 
+void Interpreter::OutputPrefix(otBorderRouterConfig &aConfig)
+{
+    mServer->OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[0]),
+                          HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[1]),
+                          HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[2]),
+                          HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[3]), aConfig.mPrefix.mLength);
+
+    if (aConfig.mPreferred)
+    {
+        mServer->OutputFormat("p");
+    }
+
+    if (aConfig.mSlaac)
+    {
+        mServer->OutputFormat("a");
+    }
+
+    if (aConfig.mDhcp)
+    {
+        mServer->OutputFormat("d");
+    }
+
+    if (aConfig.mConfigure)
+    {
+        mServer->OutputFormat("c");
+    }
+
+    if (aConfig.mDefaultRoute)
+    {
+        mServer->OutputFormat("r");
+    }
+
+    if (aConfig.mOnMesh)
+    {
+        mServer->OutputFormat("o");
+    }
+
+    if (aConfig.mStable)
+    {
+        mServer->OutputFormat("s");
+    }
+
+    if (aConfig.mNdDns)
+    {
+        mServer->OutputFormat("n");
+    }
+
+    if (aConfig.mDp)
+    {
+        mServer->OutputFormat("D");
+    }
+
+    switch (aConfig.mPreference)
+    {
+    case OT_ROUTE_PREFERENCE_LOW:
+        mServer->OutputFormat(" low");
+        break;
+
+    case OT_ROUTE_PREFERENCE_MED:
+        mServer->OutputFormat(" med");
+        break;
+
+    case OT_ROUTE_PREFERENCE_HIGH:
+        mServer->OutputFormat(" high");
+        break;
+    }
+
+    mServer->OutputFormat("\r\n");
+}
+
 otError Interpreter::ProcessPrefixList(void)
 {
     otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
@@ -2388,80 +2852,75 @@
 
     while (otBorderRouterGetNextOnMeshPrefix(mInstance, &iterator, &config) == OT_ERROR_NONE)
     {
-        mServer->OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(config.mPrefix.mPrefix.mFields.m16[0]),
-                              HostSwap16(config.mPrefix.mPrefix.mFields.m16[1]),
-                              HostSwap16(config.mPrefix.mPrefix.mFields.m16[2]),
-                              HostSwap16(config.mPrefix.mPrefix.mFields.m16[3]), config.mPrefix.mLength);
-
-        if (config.mPreferred)
-        {
-            mServer->OutputFormat("p");
-        }
-
-        if (config.mSlaac)
-        {
-            mServer->OutputFormat("a");
-        }
-
-        if (config.mDhcp)
-        {
-            mServer->OutputFormat("d");
-        }
-
-        if (config.mConfigure)
-        {
-            mServer->OutputFormat("c");
-        }
-
-        if (config.mDefaultRoute)
-        {
-            mServer->OutputFormat("r");
-        }
-
-        if (config.mOnMesh)
-        {
-            mServer->OutputFormat("o");
-        }
-
-        if (config.mStable)
-        {
-            mServer->OutputFormat("s");
-        }
-
-        switch (config.mPreference)
-        {
-        case OT_ROUTE_PREFERENCE_LOW:
-            mServer->OutputFormat(" low\r\n");
-            break;
-
-        case OT_ROUTE_PREFERENCE_MED:
-            mServer->OutputFormat(" med\r\n");
-            break;
-
-        case OT_ROUTE_PREFERENCE_HIGH:
-            mServer->OutputFormat(" high\r\n");
-            break;
-        }
+        OutputPrefix(config);
     }
 
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    if (otBackboneRouterGetState(mInstance) == OT_BACKBONE_ROUTER_STATE_DISABLED)
+    {
+        SuccessOrExit(otBackboneRouterGetDomainPrefix(mInstance, &config));
+        mServer->OutputFormat("- ");
+        OutputPrefix(config);
+    }
+    // Else already printed via above while loop.
+exit:
+#endif
+
     return OT_ERROR_NONE;
 }
 
-void Interpreter::ProcessPrefix(int argc, char *argv[])
+void Interpreter::ProcessPrefix(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         SuccessOrExit(error = ProcessPrefixList());
     }
-    else if (strcmp(argv[0], "add") == 0)
+    else if (strcmp(aArgs[0], "add") == 0)
     {
-        SuccessOrExit(error = ProcessPrefixAdd(argc - 1, argv + 1));
+        SuccessOrExit(error = ProcessPrefixAdd(aArgsLength - 1, aArgs + 1));
     }
-    else if (strcmp(argv[0], "remove") == 0)
+    else if (strcmp(aArgs[0], "remove") == 0)
     {
-        SuccessOrExit(error = ProcessPrefixRemove(argc - 1, argv + 1));
+        SuccessOrExit(error = ProcessPrefixRemove(aArgsLength - 1, aArgs + 1));
+    }
+    else
+    {
+        ExitNow(error = OT_ERROR_INVALID_COMMAND);
+    }
+
+exit:
+    AppendResult(error);
+}
+#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
+
+#if OPENTHREAD_FTD
+void Interpreter::ProcessPreferRouterId(uint8_t aArgsLength, char *aArgs[])
+{
+    otError       error = OT_ERROR_NONE;
+    unsigned long value;
+
+    VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
+    SuccessOrExit(error = ParseUnsignedLong(aArgs[0], value));
+    error = otThreadSetPreferredRouterId(mInstance, static_cast<uint8_t>(value));
+
+exit:
+    AppendResult(error);
+}
+#endif
+
+void Interpreter::ProcessRcp(uint8_t aArgsLength, char *aArgs[])
+{
+    otError     error   = OT_ERROR_NONE;
+    const char *version = otPlatRadioGetVersionString(mInstance);
+
+    VerifyOrExit(version != otGetVersionString(), error = OT_ERROR_NOT_IMPLEMENTED);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+
+    if (strcmp(aArgs[0], "version") == 0)
+    {
+        mServer->OutputFormat("%s\r\n", version);
     }
     else
     {
@@ -2471,94 +2930,91 @@
 exit:
     AppendResult(error);
 }
-#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessReleaseRouterId(int argc, char *argv[])
+void Interpreter::ProcessReleaseRouterId(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = ParseLong(argv[0], value));
+    SuccessOrExit(error = ParseLong(aArgs[0], value));
     SuccessOrExit(error = otThreadReleaseRouterId(mInstance, static_cast<uint8_t>(value)));
 
 exit:
     AppendResult(error);
 }
-#endif // OPENTHREAD_FTD
+#endif
 
-void Interpreter::ProcessReset(int argc, char *argv[])
+void Interpreter::ProcessReset(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otInstanceReset(mInstance);
 }
 
-void Interpreter::ProcessRloc16(int argc, char *argv[])
+void Interpreter::ProcessRloc16(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     mServer->OutputFormat("%04x\r\n", otThreadGetRloc16(mInstance));
-    mServer->OutputFormat("Done\r\n");
+    AppendResult(OT_ERROR_NONE);
 }
 
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
-otError Interpreter::ProcessRouteAdd(int argc, char *argv[])
+otError Interpreter::ProcessRouteAdd(uint8_t aArgsLength, char *aArgs[])
 {
     otError               error = OT_ERROR_NONE;
     otExternalRouteConfig config;
-    int                   argcur = 0;
+    uint8_t               argcur = 0;
+    char *                prefixLengthStr;
 
     memset(&config, 0, sizeof(otExternalRouteConfig));
 
-    char *prefixLengthStr;
-    char *endptr;
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-
-    if ((prefixLengthStr = strchr(argv[argcur], '/')) == NULL)
+    if ((prefixLengthStr = strchr(aArgs[argcur], '/')) == nullptr)
     {
         ExitNow();
     }
 
     *prefixLengthStr++ = '\0';
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[argcur], &config.mPrefix.mPrefix));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[argcur], &config.mPrefix.mPrefix));
 
-    config.mPrefix.mLength = static_cast<uint8_t>(strtol(prefixLengthStr, &endptr, 0));
-
-    if (*endptr != '\0')
     {
-        ExitNow(error = OT_ERROR_PARSE);
+        unsigned long length;
+
+        SuccessOrExit(error = ParseUnsignedLong(prefixLengthStr, length));
+        config.mPrefix.mLength = static_cast<uint8_t>(length);
     }
 
     argcur++;
 
-    for (; argcur < argc; argcur++)
+    for (; argcur < aArgsLength; argcur++)
     {
-        if (strcmp(argv[argcur], "s") == 0)
+        if (strcmp(aArgs[argcur], "s") == 0)
         {
             config.mStable = true;
         }
-        else if (strcmp(argv[argcur], "high") == 0)
+        else if (strcmp(aArgs[argcur], "high") == 0)
         {
             config.mPreference = OT_ROUTE_PREFERENCE_HIGH;
         }
-        else if (strcmp(argv[argcur], "med") == 0)
+        else if (strcmp(aArgs[argcur], "med") == 0)
         {
             config.mPreference = OT_ROUTE_PREFERENCE_MED;
         }
-        else if (strcmp(argv[argcur], "low") == 0)
+        else if (strcmp(aArgs[argcur], "low") == 0)
         {
             config.mPreference = OT_ROUTE_PREFERENCE_LOW;
         }
         else
         {
-            ExitNow(error = OT_ERROR_PARSE);
+            ExitNow(error = OT_ERROR_INVALID_ARGS);
         }
     }
 
@@ -2568,32 +3024,31 @@
     return error;
 }
 
-otError Interpreter::ProcessRouteRemove(int argc, char *argv[])
+otError Interpreter::ProcessRouteRemove(uint8_t aArgsLength, char *aArgs[])
 {
     otError            error = OT_ERROR_NONE;
     struct otIp6Prefix prefix;
-    int                argcur = 0;
+    uint8_t            argcur = 0;
+    char *             prefixLengthStr;
 
     memset(&prefix, 0, sizeof(struct otIp6Prefix));
-    char *prefixLengthStr;
-    char *endptr;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if ((prefixLengthStr = strchr(argv[argcur], '/')) == NULL)
+    if ((prefixLengthStr = strchr(aArgs[argcur], '/')) == nullptr)
     {
         ExitNow();
     }
 
     *prefixLengthStr++ = '\0';
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[argcur], &prefix.mPrefix));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[argcur], &prefix.mPrefix));
 
-    prefix.mLength = static_cast<uint8_t>(strtol(prefixLengthStr, &endptr, 0));
-
-    if (*endptr != '\0')
     {
-        ExitNow(error = OT_ERROR_PARSE);
+        unsigned long length;
+
+        SuccessOrExit(error = ParseUnsignedLong(prefixLengthStr, length));
+        prefix.mLength = static_cast<uint8_t>(length);
     }
 
     error = otBorderRouterRemoveRoute(mInstance, &prefix);
@@ -2638,25 +3093,25 @@
     return OT_ERROR_NONE;
 }
 
-void Interpreter::ProcessRoute(int argc, char *argv[])
+void Interpreter::ProcessRoute(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         SuccessOrExit(error = ProcessRouteList());
     }
-    else if (strcmp(argv[0], "add") == 0)
+    else if (strcmp(aArgs[0], "add") == 0)
     {
-        SuccessOrExit(error = ProcessRouteAdd(argc - 1, argv + 1));
+        SuccessOrExit(error = ProcessRouteAdd(aArgsLength - 1, aArgs + 1));
     }
-    else if (strcmp(argv[0], "remove") == 0)
+    else if (strcmp(aArgs[0], "remove") == 0)
     {
-        SuccessOrExit(error = ProcessRouteRemove(argc - 1, argv + 1));
+        SuccessOrExit(error = ProcessRouteRemove(aArgsLength - 1, aArgs + 1));
     }
     else
     {
-        ExitNow(error = OT_ERROR_INVALID_ARGS);
+        ExitNow(error = OT_ERROR_INVALID_COMMAND);
     }
 
 exit:
@@ -2665,18 +3120,18 @@
 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessRouter(int argc, char *argv[])
+void Interpreter::ProcessRouter(uint8_t aArgsLength, char *aArgs[])
 {
     otError      error = OT_ERROR_NONE;
     otRouterInfo routerInfo;
     long         value;
     bool         isTable;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    isTable = (strcmp(argv[0], "table") == 0);
+    isTable = (strcmp(aArgs[0], "table") == 0);
 
-    if (isTable || strcmp(argv[0], "list") == 0)
+    if (isTable || strcmp(aArgs[0], "list") == 0)
     {
         uint8_t maxRouterId;
 
@@ -2725,7 +3180,7 @@
         ExitNow();
     }
 
-    SuccessOrExit(error = ParseLong(argv[0], value));
+    SuccessOrExit(error = ParseLong(aArgs[0], value));
     SuccessOrExit(error = otThreadGetRouterInfo(mInstance, static_cast<uint16_t>(value), &routerInfo));
 
     mServer->OutputFormat("Alloc: %d\r\n", routerInfo.mAllocated);
@@ -2758,18 +3213,18 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessRouterDowngradeThreshold(int argc, char *argv[])
+void Interpreter::ProcessRouterDowngradeThreshold(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetRouterDowngradeThreshold(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         otThreadSetRouterDowngradeThreshold(mInstance, static_cast<uint8_t>(value));
     }
 
@@ -2777,11 +3232,11 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessRouterEligible(int argc, char *argv[])
+void Interpreter::ProcessRouterEligible(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         if (otThreadIsRouterEligible(mInstance))
         {
@@ -2792,11 +3247,11 @@
             mServer->OutputFormat("Disabled\r\n");
         }
     }
-    else if (strcmp(argv[0], "enable") == 0)
+    else if (strcmp(aArgs[0], "enable") == 0)
     {
         error = otThreadSetRouterEligible(mInstance, true);
     }
-    else if (strcmp(argv[0], "disable") == 0)
+    else if (strcmp(aArgs[0], "disable") == 0)
     {
         error = otThreadSetRouterEligible(mInstance, false);
     }
@@ -2809,18 +3264,18 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessRouterSelectionJitter(int argc, char *argv[])
+void Interpreter::ProcessRouterSelectionJitter(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetRouterSelectionJitter(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         VerifyOrExit(0 < value && value < 256, error = OT_ERROR_INVALID_ARGS);
         otThreadSetRouterSelectionJitter(mInstance, static_cast<uint8_t>(value));
     }
@@ -2829,18 +3284,18 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessRouterUpgradeThreshold(int argc, char *argv[])
+void Interpreter::ProcessRouterUpgradeThreshold(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetRouterUpgradeThreshold(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         otThreadSetRouterUpgradeThreshold(mInstance, static_cast<uint8_t>(value));
     }
 
@@ -2849,7 +3304,7 @@
 }
 #endif // OPENTHREAD_FTD
 
-void Interpreter::ProcessScan(int argc, char *argv[])
+void Interpreter::ProcessScan(uint8_t aArgsLength, char *aArgs[])
 {
     otError  error        = OT_ERROR_NONE;
     uint32_t scanChannels = 0;
@@ -2857,21 +3312,21 @@
     bool     energyScan   = false;
     long     value;
 
-    if (argc > 0)
+    if (aArgsLength > 0)
     {
-        if (strcmp(argv[0], "energy") == 0)
+        if (strcmp(aArgs[0], "energy") == 0)
         {
             energyScan = true;
 
-            if (argc > 1)
+            if (aArgsLength > 1)
             {
-                SuccessOrExit(error = ParseLong(argv[1], value));
+                SuccessOrExit(error = ParseLong(aArgs[1], value));
                 scanDuration = static_cast<uint16_t>(value);
             }
         }
         else
         {
-            SuccessOrExit(error = ParseLong(argv[0], value));
+            SuccessOrExit(error = ParseLong(aArgs[0], value));
             VerifyOrExit((0 <= value) && (value < static_cast<long>(sizeof(scanChannels) * CHAR_BIT)),
                          error = OT_ERROR_INVALID_ARGS);
             scanChannels = 1 << value;
@@ -2895,10 +3350,11 @@
                                                &Interpreter::HandleActiveScanResult, this));
     }
 
-    return;
-
 exit:
-    AppendResult(error);
+    if (error != OT_ERROR_NONE)
+    {
+        AppendResult(error);
+    }
 }
 
 void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult, void *aContext)
@@ -2908,9 +3364,9 @@
 
 void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult)
 {
-    if (aResult == NULL)
+    if (aResult == nullptr)
     {
-        mServer->OutputFormat("Done\r\n");
+        AppendResult(OT_ERROR_NONE);
         ExitNow();
     }
 
@@ -2939,9 +3395,9 @@
 
 void Interpreter::HandleEnergyScanResult(otEnergyScanResult *aResult)
 {
-    if (aResult == NULL)
+    if (aResult == nullptr)
     {
-        mServer->OutputFormat("Done\r\n");
+        AppendResult(OT_ERROR_NONE);
         ExitNow();
     }
 
@@ -2951,10 +3407,10 @@
     return;
 }
 
-void Interpreter::ProcessSingleton(int argc, char *argv[])
+void Interpreter::ProcessSingleton(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError error = OT_ERROR_NONE;
 
@@ -2971,22 +3427,22 @@
 }
 
 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
-void Interpreter::ProcessSntp(int argc, char *argv[])
+void Interpreter::ProcessSntp(uint8_t aArgsLength, char *aArgs[])
 {
     otError          error = OT_ERROR_NONE;
     long             port  = OT_SNTP_DEFAULT_SERVER_PORT;
     Ip6::MessageInfo messageInfo;
     otSntpQuery      query;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "query") == 0)
+    if (strcmp(aArgs[0], "query") == 0)
     {
         VerifyOrExit(!mSntpQueryingInProgress, error = OT_ERROR_BUSY);
 
-        if (argc > 1)
+        if (aArgsLength > 1)
         {
-            SuccessOrExit(error = messageInfo.GetPeerAddr().FromString(argv[1]));
+            SuccessOrExit(error = messageInfo.GetPeerAddr().FromString(aArgs[1]));
         }
         else
         {
@@ -2994,9 +3450,9 @@
             SuccessOrExit(error = messageInfo.GetPeerAddr().FromString(OT_SNTP_DEFAULT_SERVER_IP));
         }
 
-        if (argc > 2)
+        if (aArgsLength > 2)
         {
-            SuccessOrExit(error = ParseLong(argv[2], port));
+            SuccessOrExit(error = ParseLong(aArgs[2], port));
         }
 
         messageInfo.SetPeerPort(static_cast<uint16_t>(port));
@@ -3009,7 +3465,7 @@
     }
     else
     {
-        ExitNow(error = OT_ERROR_INVALID_ARGS);
+        ExitNow(error = OT_ERROR_INVALID_COMMAND);
     }
 
 exit:
@@ -3039,14 +3495,16 @@
     }
 
     mSntpQueryingInProgress = false;
+
+    AppendResult(OT_ERROR_NONE);
 }
 #endif
 
-void Interpreter::ProcessState(int argc, char *argv[])
+void Interpreter::ProcessState(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         switch (otThreadGetDeviceRole(mInstance))
         {
@@ -3080,21 +3538,21 @@
     }
     else
     {
-        if (strcmp(argv[0], "detached") == 0)
+        if (strcmp(aArgs[0], "detached") == 0)
         {
             SuccessOrExit(error = otThreadBecomeDetached(mInstance));
         }
-        else if (strcmp(argv[0], "child") == 0)
+        else if (strcmp(aArgs[0], "child") == 0)
         {
             SuccessOrExit(error = otThreadBecomeChild(mInstance));
         }
 
 #if OPENTHREAD_FTD
-        else if (strcmp(argv[0], "router") == 0)
+        else if (strcmp(aArgs[0], "router") == 0)
         {
             SuccessOrExit(error = otThreadBecomeRouter(mInstance));
         }
-        else if (strcmp(argv[0], "leader") == 0)
+        else if (strcmp(aArgs[0], "leader") == 0)
         {
             SuccessOrExit(error = otThreadBecomeLeader(mInstance));
         }
@@ -3110,48 +3568,48 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessThread(int argc, char *argv[])
+void Interpreter::ProcessThread(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "start") == 0)
+    if (strcmp(aArgs[0], "start") == 0)
     {
         SuccessOrExit(error = otThreadSetEnabled(mInstance, true));
     }
-    else if (strcmp(argv[0], "stop") == 0)
+    else if (strcmp(aArgs[0], "stop") == 0)
     {
         SuccessOrExit(error = otThreadSetEnabled(mInstance, false));
     }
-    else if (strcmp(argv[0], "version") == 0)
+    else if (strcmp(aArgs[0], "version") == 0)
     {
         mServer->OutputFormat("%u\r\n", otThreadGetVersion());
     }
     else
     {
-        ExitNow(error = OT_ERROR_INVALID_ARGS);
+        ExitNow(error = OT_ERROR_INVALID_COMMAND);
     }
 
 exit:
     AppendResult(error);
 }
 
-void Interpreter::ProcessDataset(int argc, char *argv[])
+void Interpreter::ProcessDataset(uint8_t aArgsLength, char *aArgs[])
 {
     otError error;
-    error = mDataset.Process(argc, argv);
+    error = mDataset.Process(aArgsLength, aArgs);
     AppendResult(error);
 }
 
-void Interpreter::ProcessTxPower(int argc, char *argv[])
+void Interpreter::ProcessTxPower(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         int8_t power;
 
@@ -3162,7 +3620,7 @@
     {
         long value;
 
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         SuccessOrExit(error = otPlatRadioSetTransmitPower(mInstance, static_cast<int8_t>(value)));
     }
 
@@ -3170,17 +3628,17 @@
     AppendResult(error);
 }
 
-void Interpreter::ProcessUdp(int argc, char *argv[])
+void Interpreter::ProcessUdp(uint8_t aArgsLength, char *aArgs[])
 {
     otError error;
-    error = mUdp.Process(argc, argv);
+    error = mUdp.Process(aArgsLength, aArgs);
     AppendResult(error);
 }
 
-void Interpreter::ProcessVersion(int argc, char *argv[])
+void Interpreter::ProcessVersion(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     const char *version = otGetVersionString();
     mServer->OutputFormat("%s\r\n", static_cast<const char *>(version));
@@ -3189,10 +3647,10 @@
 
 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
 
-void Interpreter::ProcessCommissioner(int argc, char *argv[])
+void Interpreter::ProcessCommissioner(uint8_t aArgsLength, char *aArgs[])
 {
     otError error;
-    error = mCommissioner.Process(argc, argv);
+    error = mCommissioner.Process(aArgsLength, aArgs);
     AppendResult(error);
 }
 
@@ -3200,28 +3658,28 @@
 
 #if OPENTHREAD_CONFIG_JOINER_ENABLE
 
-void Interpreter::ProcessJoiner(int argc, char *argv[])
+void Interpreter::ProcessJoiner(uint8_t aArgsLength, char *aArgs[])
 {
     otError error;
-    error = mJoiner.Process(argc, argv);
+    error = mJoiner.Process(aArgsLength, aArgs);
     AppendResult(error);
 }
 
 #endif
 
 #if OPENTHREAD_FTD
-void Interpreter::ProcessJoinerPort(int argc, char *argv[])
+void Interpreter::ProcessJoinerPort(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         mServer->OutputFormat("%d\r\n", otThreadGetJoinerUdpPort(mInstance));
     }
     else
     {
-        SuccessOrExit(error = ParseLong(argv[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         error = otThreadSetJoinerUdpPort(mInstance, static_cast<uint16_t>(value));
     }
 
@@ -3231,27 +3689,27 @@
 #endif
 
 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
-void Interpreter::ProcessMacFilter(int argc, char *argv[])
+void Interpreter::ProcessMacFilter(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         PrintMacFilter();
     }
     else
     {
-        if (strcmp(argv[0], "addr") == 0)
+        if (strcmp(aArgs[0], "addr") == 0)
         {
-            error = ProcessMacFilterAddress(argc - 1, argv + 1);
+            error = ProcessMacFilterAddress(aArgsLength - 1, aArgs + 1);
         }
-        else if (strcmp(argv[0], "rss") == 0)
+        else if (strcmp(aArgs[0], "rss") == 0)
         {
-            error = ProcessMacFilterRss(argc - 1, argv + 1);
+            error = ProcessMacFilterRss(aArgsLength - 1, aArgs + 1);
         }
         else
         {
-            error = OT_ERROR_INVALID_ARGS;
+            error = OT_ERROR_INVALID_COMMAND;
         }
     }
 
@@ -3319,7 +3777,7 @@
     }
 }
 
-otError Interpreter::ProcessMacFilterAddress(int argc, char *argv[])
+otError Interpreter::ProcessMacFilterAddress(uint8_t aArgsLength, char *aArgs[])
 {
     otError                error = OT_ERROR_NONE;
     otExtAddress           extAddr;
@@ -3328,7 +3786,7 @@
     otMacFilterAddressMode mode     = otLinkFilterGetAddressMode(mInstance);
     long                   value;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         if (mode == OT_MAC_FILTER_ADDRESS_MODE_DISABLED)
         {
@@ -3358,55 +3816,55 @@
     }
     else
     {
-        if (strcmp(argv[0], "disable") == 0)
+        if (strcmp(aArgs[0], "disable") == 0)
         {
-            VerifyOrExit(argc == 1, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = otLinkFilterSetAddressMode(mInstance, OT_MAC_FILTER_ADDRESS_MODE_DISABLED));
+            VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
+            otLinkFilterSetAddressMode(mInstance, OT_MAC_FILTER_ADDRESS_MODE_DISABLED);
         }
-        else if (strcmp(argv[0], "whitelist") == 0)
+        else if (strcmp(aArgs[0], "whitelist") == 0)
         {
-            VerifyOrExit(argc == 1, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = otLinkFilterSetAddressMode(mInstance, OT_MAC_FILTER_ADDRESS_MODE_WHITELIST));
+            VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
+            otLinkFilterSetAddressMode(mInstance, OT_MAC_FILTER_ADDRESS_MODE_WHITELIST);
         }
-        else if (strcmp(argv[0], "blacklist") == 0)
+        else if (strcmp(aArgs[0], "blacklist") == 0)
         {
-            VerifyOrExit(argc == 1, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = otLinkFilterSetAddressMode(mInstance, OT_MAC_FILTER_ADDRESS_MODE_BLACKLIST));
+            VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
+            otLinkFilterSetAddressMode(mInstance, OT_MAC_FILTER_ADDRESS_MODE_BLACKLIST);
         }
-        else if (strcmp(argv[0], "add") == 0)
+        else if (strcmp(aArgs[0], "add") == 0)
         {
-            VerifyOrExit(argc >= 2, error = OT_ERROR_INVALID_ARGS);
-            VerifyOrExit(Hex2Bin(argv[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
-                         error = OT_ERROR_PARSE);
+            VerifyOrExit(aArgsLength >= 2, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(Hex2Bin(aArgs[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
+                         error = OT_ERROR_INVALID_ARGS);
 
             error = otLinkFilterAddAddress(mInstance, &extAddr);
 
-            VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_ALREADY);
+            VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_ALREADY, OT_NOOP);
 
-            if (argc > 2)
+            if (aArgsLength > 2)
             {
                 int8_t rss = 0;
-                VerifyOrExit(argc == 3, error = OT_ERROR_INVALID_ARGS);
-                SuccessOrExit(error = ParseLong(argv[2], value));
+                VerifyOrExit(aArgsLength == 3, error = OT_ERROR_INVALID_ARGS);
+                SuccessOrExit(error = ParseLong(aArgs[2], value));
                 rss = static_cast<int8_t>(value);
                 SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, &extAddr, rss));
             }
         }
-        else if (strcmp(argv[0], "remove") == 0)
+        else if (strcmp(aArgs[0], "remove") == 0)
         {
-            VerifyOrExit(argc == 2, error = OT_ERROR_INVALID_ARGS);
-            VerifyOrExit(Hex2Bin(argv[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
-                         error = OT_ERROR_PARSE);
-            SuccessOrExit(error = otLinkFilterRemoveAddress(mInstance, &extAddr));
+            VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(Hex2Bin(aArgs[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
+                         error = OT_ERROR_INVALID_ARGS);
+            otLinkFilterRemoveAddress(mInstance, &extAddr);
         }
-        else if (strcmp(argv[0], "clear") == 0)
+        else if (strcmp(aArgs[0], "clear") == 0)
         {
-            VerifyOrExit(argc == 1, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
             otLinkFilterClearAddresses(mInstance);
         }
         else
         {
-            error = OT_ERROR_INVALID_ARGS;
+            error = OT_ERROR_INVALID_COMMAND;
         }
     }
 
@@ -3414,7 +3872,7 @@
     return error;
 }
 
-otError Interpreter::ProcessMacFilterRss(int argc, char *argv[])
+otError Interpreter::ProcessMacFilterRss(uint8_t aArgsLength, char *aArgs[])
 {
     otError             error = OT_ERROR_NONE;
     otMacFilterEntry    entry;
@@ -3423,7 +3881,7 @@
     long                value;
     int8_t              rss;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         while (otLinkFilterGetNextRssIn(mInstance, &iterator, &entry) == OT_ERROR_NONE)
         {
@@ -3452,68 +3910,68 @@
     }
     else
     {
-        if (strcmp(argv[0], "add-lqi") == 0)
+        if (strcmp(aArgs[0], "add-lqi") == 0)
         {
             uint8_t linkquality = 0;
-            VerifyOrExit(argc == 3, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength == 3, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             linkquality = static_cast<uint8_t>(value);
-            VerifyOrExit(linkquality <= 3, error = OT_ERROR_PARSE);
+            VerifyOrExit(linkquality <= 3, error = OT_ERROR_INVALID_ARGS);
             rss = otLinkConvertLinkQualityToRss(mInstance, linkquality);
 
-            if (strcmp(argv[1], "*") == 0)
+            if (strcmp(aArgs[1], "*") == 0)
             {
-                SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, NULL, rss));
+                otLinkFilterSetDefaultRssIn(mInstance, rss);
             }
             else
             {
-                VerifyOrExit(Hex2Bin(argv[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
-                             error = OT_ERROR_PARSE);
+                VerifyOrExit(Hex2Bin(aArgs[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
+                             error = OT_ERROR_INVALID_ARGS);
 
                 SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, &extAddr, rss));
             }
         }
-        else if (strcmp(argv[0], "add") == 0)
+        else if (strcmp(aArgs[0], "add") == 0)
         {
-            VerifyOrExit(argc == 3, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = ParseLong(argv[2], value));
+            VerifyOrExit(aArgsLength == 3, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = ParseLong(aArgs[2], value));
             rss = static_cast<int8_t>(value);
 
-            if (strcmp(argv[1], "*") == 0)
+            if (strcmp(aArgs[1], "*") == 0)
             {
-                SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, NULL, rss));
+                otLinkFilterSetDefaultRssIn(mInstance, rss);
             }
             else
             {
-                VerifyOrExit(Hex2Bin(argv[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
-                             error = OT_ERROR_PARSE);
+                VerifyOrExit(Hex2Bin(aArgs[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
+                             error = OT_ERROR_INVALID_ARGS);
 
                 SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, &extAddr, rss));
             }
         }
-        else if (strcmp(argv[0], "remove") == 0)
+        else if (strcmp(aArgs[0], "remove") == 0)
         {
-            VerifyOrExit(argc == 2, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
 
-            if (strcmp(argv[1], "*") == 0)
+            if (strcmp(aArgs[1], "*") == 0)
             {
-                SuccessOrExit(error = otLinkFilterRemoveRssIn(mInstance, NULL));
+                otLinkFilterClearDefaultRssIn(mInstance);
             }
             else
             {
-                VerifyOrExit(Hex2Bin(argv[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
-                             error = OT_ERROR_PARSE);
+                VerifyOrExit(Hex2Bin(aArgs[1], extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE,
+                             error = OT_ERROR_INVALID_ARGS);
 
-                SuccessOrExit(error = otLinkFilterRemoveRssIn(mInstance, &extAddr));
+                otLinkFilterRemoveRssIn(mInstance, &extAddr);
             }
         }
-        else if (strcmp(argv[0], "clear") == 0)
+        else if (strcmp(aArgs[0], "clear") == 0)
         {
-            otLinkFilterClearRssIn(mInstance);
+            otLinkFilterClearAllRssIn(mInstance);
         }
         else
         {
-            error = OT_ERROR_INVALID_ARGS;
+            error = OT_ERROR_INVALID_COMMAND;
         }
     }
 
@@ -3523,34 +3981,34 @@
 
 #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
 
-void Interpreter::ProcessMac(int argc, char *argv[])
+void Interpreter::ProcessMac(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "retries") == 0)
+    if (strcmp(aArgs[0], "retries") == 0)
     {
-        error = ProcessMacRetries(argc - 1, argv + 1);
+        error = ProcessMacRetries(aArgsLength - 1, aArgs + 1);
     }
     else
     {
-        error = OT_ERROR_INVALID_ARGS;
+        error = OT_ERROR_INVALID_COMMAND;
     }
 
 exit:
     AppendResult(error);
 }
 
-otError Interpreter::ProcessMacRetries(int argc, char *argv[])
+otError Interpreter::ProcessMacRetries(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc > 0 && argc <= 2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0 && aArgsLength <= 2, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "direct") == 0)
+    if (strcmp(aArgs[0], "direct") == 0)
     {
-        if (argc == 1)
+        if (aArgsLength == 1)
         {
             mServer->OutputFormat("%d\r\n", otLinkGetMaxFrameRetriesDirect(mInstance));
         }
@@ -3558,16 +4016,16 @@
         {
             unsigned long value;
 
-            SuccessOrExit(error = ParseUnsignedLong(argv[1], value));
+            SuccessOrExit(error = ParseUnsignedLong(aArgs[1], value));
             VerifyOrExit(value <= 0xff, error = OT_ERROR_INVALID_ARGS);
 
             otLinkSetMaxFrameRetriesDirect(mInstance, static_cast<uint8_t>(value));
         }
     }
 #if OPENTHREAD_FTD
-    else if (strcmp(argv[0], "indirect") == 0)
+    else if (strcmp(aArgs[0], "indirect") == 0)
     {
-        if (argc == 1)
+        if (aArgsLength == 1)
         {
             mServer->OutputFormat("%d\r\n", otLinkGetMaxFrameRetriesIndirect(mInstance));
         }
@@ -3575,7 +4033,7 @@
         {
             unsigned long value;
 
-            SuccessOrExit(error = ParseUnsignedLong(argv[1], value));
+            SuccessOrExit(error = ParseUnsignedLong(aArgs[1], value));
             VerifyOrExit(value <= 0xff, error = OT_ERROR_INVALID_ARGS);
 
             otLinkSetMaxFrameRetriesIndirect(mInstance, static_cast<uint8_t>(value));
@@ -3592,32 +4050,37 @@
 }
 
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
-void Interpreter::ProcessDiag(int argc, char *argv[])
+void Interpreter::ProcessDiag(uint8_t aArgsLength, char *aArgs[])
 {
-    char output[OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE];
+    otError error;
+    char    output[OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE];
 
     // all diagnostics related features are processed within diagnostics module
+    output[0]                  = '\0';
     output[sizeof(output) - 1] = '\0';
-    otDiagProcessCmd(mInstance, argc, argv, output, sizeof(output) - 1);
+
+    error = otDiagProcessCmd(mInstance, aArgsLength, aArgs, output, sizeof(output) - 1);
     mServer->Output(output, static_cast<uint16_t>(strlen(output)));
+    AppendResult(error);
 }
 #endif
 
 void Interpreter::ProcessLine(char *aBuf, uint16_t aBufLength, Server &aServer)
 {
-    char *  argv[kMaxArgs] = {NULL};
+    char *  aArgs[kMaxArgs] = {nullptr};
     char *  cmd;
-    uint8_t argc = 0, i = 0;
+    uint8_t aArgsLength = 0;
+    size_t  i           = 0;
 
     mServer = &aServer;
 
-    VerifyOrExit(aBuf != NULL && StringLength(aBuf, aBufLength + 1) <= aBufLength);
+    VerifyOrExit(aBuf != nullptr && StringLength(aBuf, aBufLength + 1) <= aBufLength, OT_NOOP);
 
-    VerifyOrExit(Utils::CmdLineParser::ParseCmd(aBuf, argc, argv, kMaxArgs) == OT_ERROR_NONE,
+    VerifyOrExit(Utils::CmdLineParser::ParseCmd(aBuf, aArgsLength, aArgs, kMaxArgs) == OT_ERROR_NONE,
                  mServer->OutputFormat("Error: too many args (max %d)\r\n", kMaxArgs));
-    VerifyOrExit(argc >= 1, mServer->OutputFormat("Error: no given command.\r\n"));
+    VerifyOrExit(aArgsLength >= 1, mServer->OutputFormat("Error: no given command.\r\n"));
 
-    cmd = argv[0];
+    cmd = aArgs[0];
 
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
     VerifyOrExit(
@@ -3629,7 +4092,7 @@
     {
         if (strcmp(cmd, sCommands[i].mName) == 0)
         {
-            (this->*sCommands[i].mCommand)(argc - 1, &argv[1]);
+            (this->*sCommands[i].mCommand)(aArgsLength - 1, &aArgs[1]);
             break;
         }
     }
@@ -3642,14 +4105,14 @@
         {
             if (strcmp(cmd, mUserCommands[i].mName) == 0)
             {
-                mUserCommands[i].mCommand(argc - 1, &argv[1]);
+                mUserCommands[i].mCommand(aArgsLength - 1, &aArgs[1]);
                 break;
             }
         }
 
         if (i == mUserCommandsLength)
         {
-            AppendResult(OT_ERROR_PARSE);
+            AppendResult(OT_ERROR_INVALID_COMMAND);
         }
     }
 
@@ -3658,41 +4121,41 @@
 }
 
 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
-void Interpreter::ProcessNetworkDiagnostic(int argc, char *argv[])
+void Interpreter::ProcessNetworkDiagnostic(uint8_t aArgsLength, char *aArgs[])
 {
     otError             error = OT_ERROR_NONE;
     struct otIp6Address address;
     uint8_t             tlvTypes[OT_NETWORK_DIAGNOSTIC_TYPELIST_MAX_ENTRIES];
     uint8_t             count     = 0;
-    uint8_t             argvIndex = 0;
+    uint8_t             argsIndex = 0;
 
     // Include operation, address and type tlv list.
-    VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = otIp6AddressFromString(argv[1], &address));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[1], &address));
 
-    argvIndex = 2;
+    argsIndex = 2;
 
-    while (argvIndex < argc && count < sizeof(tlvTypes))
+    while (argsIndex < aArgsLength && count < sizeof(tlvTypes))
     {
         long value;
-        SuccessOrExit(error = ParseLong(argv[argvIndex++], value));
+        SuccessOrExit(error = ParseLong(aArgs[argsIndex++], value));
         tlvTypes[count++] = static_cast<uint8_t>(value);
     }
 
-    if (strcmp(argv[0], "get") == 0)
+    if (strcmp(aArgs[0], "get") == 0)
     {
-        otThreadSendDiagnosticGet(mInstance, &address, tlvTypes, count);
+        IgnoreError(otThreadSendDiagnosticGet(mInstance, &address, tlvTypes, count));
         ExitNow();
     }
-    else if (strcmp(argv[0], "reset") == 0)
+    else if (strcmp(aArgs[0], "reset") == 0)
     {
-        otThreadSendDiagnosticReset(mInstance, &address, tlvTypes, count);
+        IgnoreError(otThreadSendDiagnosticReset(mInstance, &address, tlvTypes, count));
         AppendResult(OT_ERROR_NONE);
     }
     else
     {
-        ExitNow(error = OT_ERROR_INVALID_ARGS);
+        ExitNow(error = OT_ERROR_INVALID_COMMAND);
     }
 
 exit:
@@ -3701,27 +4164,29 @@
         AppendResult(error);
     }
 }
-#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
 
 void Interpreter::HandleDiagnosticGetResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, void *aContext)
 {
     static_cast<Interpreter *>(aContext)->HandleDiagnosticGetResponse(
-        *static_cast<Message *>(aMessage), *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
+        *aMessage, *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
 }
 
-void Interpreter::HandleDiagnosticGetResponse(Message &aMessage, const Ip6::MessageInfo &)
+void Interpreter::HandleDiagnosticGetResponse(const otMessage &aMessage, const Ip6::MessageInfo &)
 {
-    uint8_t  buf[16];
-    uint16_t bytesToPrint;
-    uint16_t bytesPrinted = 0;
-    uint16_t length       = aMessage.GetLength() - aMessage.GetOffset();
+    uint8_t               buf[16];
+    uint16_t              bytesToPrint;
+    uint16_t              bytesPrinted = 0;
+    uint16_t              length       = otMessageGetLength(&aMessage) - otMessageGetOffset(&aMessage);
+    otNetworkDiagTlv      diagTlv;
+    otNetworkDiagIterator iterator = OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT;
+    otError               error    = OT_ERROR_NONE;
 
     mServer->OutputFormat("DIAG_GET.rsp/ans: ");
 
     while (length > 0)
     {
         bytesToPrint = (length < sizeof(buf)) ? length : sizeof(buf);
-        aMessage.Read(aMessage.GetOffset() + bytesPrinted, bytesToPrint, buf);
+        otMessageRead(&aMessage, otMessageGetOffset(&aMessage) + bytesPrinted, buf, bytesToPrint);
 
         OutputBytes(buf, static_cast<uint8_t>(bytesToPrint));
 
@@ -3730,8 +4195,242 @@
     }
 
     mServer->OutputFormat("\r\n");
+
+    // Output Network Diagnostic TLV values in standard YAML format.
+    while ((error = otThreadGetNextDiagnosticTlv(&aMessage, &iterator, &diagTlv)) == OT_ERROR_NONE)
+    {
+        uint16_t column = 0;
+        switch (diagTlv.mType)
+        {
+        case OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS:
+            mServer->OutputFormat("Ext Address: '");
+            OutputBytes(diagTlv.mData.mExtAddress.m8, sizeof(diagTlv.mData.mExtAddress.m8));
+            mServer->OutputFormat("'\r\n");
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS:
+            mServer->OutputFormat("Rloc16: 0x%04x\r\n", diagTlv.mData.mAddr16);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_MODE:
+            mServer->OutputFormat("Mode:\r\n");
+            OutputMode(diagTlv.mData.mMode, column + INDENT_SIZE);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT:
+            mServer->OutputFormat("Timeout: %u\r\n", diagTlv.mData.mTimeout);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY:
+            mServer->OutputFormat("Connectivity:\r\n");
+            OutputConnectivity(diagTlv.mData.mConnectivity, column + INDENT_SIZE);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_ROUTE:
+            mServer->OutputFormat("Route:\r\n");
+            OutputRoute(diagTlv.mData.mRoute, column + INDENT_SIZE);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA:
+            mServer->OutputFormat("Leader Data:\r\n");
+            OutputLeaderData(diagTlv.mData.mLeaderData, column + INDENT_SIZE);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA:
+            mServer->OutputFormat("Network Data: '");
+            OutputBytes(diagTlv.mData.mNetworkData.m8, diagTlv.mData.mNetworkData.mCount);
+            mServer->OutputFormat("'\r\n");
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST:
+            mServer->OutputFormat("IP6 Address List:\r\n");
+            for (uint16_t i = 0; i < diagTlv.mData.mIp6AddrList.mCount; ++i)
+            {
+                OutputSpaces(column + INDENT_SIZE);
+                mServer->OutputFormat("- ");
+                OutputIp6Address(diagTlv.mData.mIp6AddrList.mList[i]);
+                mServer->OutputFormat("\r\n");
+            }
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS:
+            mServer->OutputFormat("MAC Counters:\r\n");
+            OutputNetworkDiagMacCounters(diagTlv.mData.mMacCounters, column + INDENT_SIZE);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL:
+            mServer->OutputFormat("Battery Level: %u%%\r\n", diagTlv.mData.mBatteryLevel);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE:
+            mServer->OutputFormat("Supply Voltage: %umV\r\n", diagTlv.mData.mSupplyVoltage);
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE:
+            mServer->OutputFormat("Child Table:\r\n");
+            for (uint16_t i = 0; i < diagTlv.mData.mChildTable.mCount; ++i)
+            {
+                OutputSpaces(column + INDENT_SIZE);
+                mServer->OutputFormat("- ");
+                OutputChildTableEntry(diagTlv.mData.mChildTable.mTable[i], column + INDENT_SIZE + 2);
+            }
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES:
+            mServer->OutputFormat("Channel Pages: '");
+            OutputBytes(diagTlv.mData.mChannelPages.m8, diagTlv.mData.mChannelPages.mCount);
+            mServer->OutputFormat("'\r\n");
+            break;
+        case OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT:
+            mServer->OutputFormat("Max Child Timeout: %u\r\n", diagTlv.mData.mMaxChildTimeout);
+            break;
+        }
+    }
+
+    AppendResult(error == OT_ERROR_NOT_FOUND ? OT_ERROR_NONE : error);
 }
 
+void Interpreter::OutputSpaces(uint16_t aCount)
+{
+    static const uint16_t kSpaceStrLen = 16;
+    char                  spaceStr[kSpaceStrLen + 1];
+
+    memset(spaceStr, ' ', kSpaceStrLen);
+    spaceStr[kSpaceStrLen] = '\0';
+
+    for (uint16_t i = 0; i < aCount; i += kSpaceStrLen)
+    {
+        uint16_t idx = (i + kSpaceStrLen <= aCount) ? 0 : (i + kSpaceStrLen - aCount);
+        mServer->OutputFormat(&spaceStr[idx]);
+    }
+}
+
+void Interpreter::OutputMode(const otLinkModeConfig &aMode, uint16_t aColumn)
+{
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("RxOnWhenIdle: %d\r\n", aMode.mRxOnWhenIdle);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("SecureDataRequests: %d\r\n", aMode.mSecureDataRequests);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("DeviceType: %d\r\n", aMode.mDeviceType);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("NetworkData: %d\r\n", aMode.mNetworkData);
+}
+
+void Interpreter::OutputConnectivity(const otNetworkDiagConnectivity &aConnectivity, uint16_t aColumn)
+{
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("ParentPriority: %d\r\n", aConnectivity.mParentPriority);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("LinkQuality3: %u\r\n", aConnectivity.mLinkQuality3);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("LinkQuality2: %u\r\n", aConnectivity.mLinkQuality2);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("LinkQuality1: %u\r\n", aConnectivity.mLinkQuality1);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("LeaderCost: %u\r\n", aConnectivity.mLeaderCost);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IdSequence: %u\r\n", aConnectivity.mIdSequence);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("ActiveRouters: %u\r\n", aConnectivity.mActiveRouters);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("SedBufferSize: %u\r\n", aConnectivity.mSedBufferSize);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("SedDatagramCount: %u\r\n", aConnectivity.mSedDatagramCount);
+}
+
+void Interpreter::OutputRoute(const otNetworkDiagRoute &aRoute, uint16_t aColumn)
+{
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IdSequence: %u\r\n", aRoute.mIdSequence);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("RouteData:\r\n");
+
+    aColumn += INDENT_SIZE;
+    for (uint16_t i = 0; i < aRoute.mRouteCount; ++i)
+    {
+        OutputSpaces(aColumn);
+        mServer->OutputFormat("- ");
+
+        OutputRouteData(aRoute.mRouteData[i], aColumn + 2);
+    }
+}
+
+void Interpreter::OutputRouteData(const otNetworkDiagRouteData &aRouteData, uint16_t aColumn)
+{
+    mServer->OutputFormat("RouteId: 0x%02x\r\n", aRouteData.mRouterId);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("LinkQualityOut: %u\r\n", aRouteData.mLinkQualityOut);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("LinkQualityIn: %u\r\n", aRouteData.mLinkQualityIn);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("RouteCost: %u\r\n", aRouteData.mRouteCost);
+}
+
+void Interpreter::OutputLeaderData(const otLeaderData &aLeaderData, uint16_t aColumn)
+{
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("PartitionId: 0x%08x\r\n", aLeaderData.mPartitionId);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("Weighting: %u\r\n", aLeaderData.mWeighting);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("DataVersion: %u\r\n", aLeaderData.mDataVersion);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("StableDataVersion: %u\r\n", aLeaderData.mStableDataVersion);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("LeaderRouterId: 0x%02x\r\n", aLeaderData.mLeaderRouterId);
+}
+
+void Interpreter::OutputNetworkDiagMacCounters(const otNetworkDiagMacCounters &aMacCounters, uint16_t aColumn)
+{
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfInUnknownProtos: %u\r\n", aMacCounters.mIfInUnknownProtos);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfInErrors: %u\r\n", aMacCounters.mIfInErrors);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfOutErrors: %u\r\n", aMacCounters.mIfOutErrors);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfInUcastPkts: %u\r\n", aMacCounters.mIfInUcastPkts);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfInBroadcastPkts: %u\r\n", aMacCounters.mIfInBroadcastPkts);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfInDiscards: %u\r\n", aMacCounters.mIfInDiscards);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfOutUcastPkts: %u\r\n", aMacCounters.mIfOutUcastPkts);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfOutBroadcastPkts: %u\r\n", aMacCounters.mIfOutBroadcastPkts);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("IfOutDiscards: %u\r\n", aMacCounters.mIfOutDiscards);
+}
+
+void Interpreter::OutputChildTableEntry(const otNetworkDiagChildEntry &aChildEntry, uint16_t aColumn)
+{
+    mServer->OutputFormat("ChildId: 0x%04x\r\n", aChildEntry.mChildId);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("Timeout: %u\r\n", aChildEntry.mTimeout);
+
+    OutputSpaces(aColumn);
+    mServer->OutputFormat("Mode:\r\n");
+
+    OutputMode(aChildEntry.mMode, aColumn + INDENT_SIZE);
+}
+#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
+
 void Interpreter::SetUserCommands(const otCliCommand *aCommands, uint8_t aLength)
 {
     mUserCommands       = aCommands;
@@ -3750,6 +4449,36 @@
     return interpreter;
 }
 
+void Interpreter::SignalPingRequest(const Ip6::Address &aPeerAddress,
+                                    uint16_t            aPingLength,
+                                    uint32_t            aTimestamp,
+                                    uint8_t             aHopLimit)
+{
+    OT_UNUSED_VARIABLE(aPeerAddress);
+    OT_UNUSED_VARIABLE(aPingLength);
+    OT_UNUSED_VARIABLE(aTimestamp);
+    OT_UNUSED_VARIABLE(aHopLimit);
+
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+    mInstance->Get<Utils::Otns>().EmitPingRequest(aPeerAddress, aPingLength, aTimestamp, aHopLimit);
+#endif
+}
+
+void Interpreter::SignalPingReply(const Ip6::Address &aPeerAddress,
+                                  uint16_t            aPingLength,
+                                  uint32_t            aTimestamp,
+                                  uint8_t             aHopLimit)
+{
+    OT_UNUSED_VARIABLE(aPeerAddress);
+    OT_UNUSED_VARIABLE(aPingLength);
+    OT_UNUSED_VARIABLE(aTimestamp);
+    OT_UNUSED_VARIABLE(aHopLimit);
+
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+    mInstance->Get<Utils::Otns>().EmitPingReply(aPeerAddress, aPingLength, aTimestamp, aHopLimit);
+#endif
+}
+
 extern "C" void otCliSetUserCommands(const otCliCommand *aUserCommands, uint8_t aLength)
 {
     Server::sServer->GetInterpreter().SetUserCommands(aUserCommands, aLength);
@@ -3783,7 +4512,7 @@
     OT_UNUSED_VARIABLE(aLogLevel);
     OT_UNUSED_VARIABLE(aLogRegion);
 
-    VerifyOrExit(Server::sServer != NULL);
+    VerifyOrExit(Server::sServer != nullptr, OT_NOOP);
 
     Server::sServer->OutputFormatV(aFormat, aArgs);
     Server::sServer->OutputFormat("\r\n");
diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp
index c7c465a..59eadd3 100644
--- a/src/cli/cli.hpp
+++ b/src/cli/cli.hpp
@@ -85,8 +85,8 @@
  */
 struct Command
 {
-    const char *mName;                                     ///< A pointer to the command string.
-    void (Interpreter::*mCommand)(int argc, char *argv[]); ///< A function pointer to process the command.
+    const char *mName;                                                 ///< A pointer to the command string.
+    void (Interpreter::*mCommand)(uint8_t aArgsLength, char *aArgs[]); ///< A function pointer to process the command.
 };
 
 /**
@@ -126,8 +126,8 @@
      * @param[in]   aString  A pointer to the ASCII string.
      * @param[out]  aLong    A reference to where the parsed long is placed.
      *
-     * @retval OT_ERROR_NONE   Successfully parsed the ASCII string.
-     * @retval OT_ERROR_PARSE  Could not parse the ASCII string.
+     * @retval OT_ERROR_NONE          Successfully parsed the ASCII string.
+     * @retval OT_ERROR_INVALID_ARGS  @p aString is not a valid long integer.
      *
      */
     static otError ParseLong(char *aString, long &aLong);
@@ -138,8 +138,8 @@
      * @param[in]   aString          A pointer to the ASCII string.
      * @param[out]  aUnsignedLong    A reference to where the parsed unsigned long is placed.
      *
-     * @retval OT_ERROR_NONE   Successfully parsed the ASCII string.
-     * @retval OT_ERROR_PARSE  Could not parse the ASCII string.
+     * @retval OT_ERROR_NONE          Successfully parsed the ASCII string.
+     * @retval OT_ERROR_INVALID_ARGS  @p aString is not a valid unsigned long integer.
      *
      */
     static otError ParseUnsignedLong(char *aString, unsigned long &aUnsignedLong);
@@ -153,8 +153,8 @@
      * @param[in]   aAllowTruncate  TRUE if @p aBinLength may be less than what is required
      *                              to convert @p aHex to binary representation, FALSE otherwise.
      *
+     * @returns  The number of bytes in the binary representation, or -1 if @p aHex is not a valid hex string
      *
-     * @returns The number of bytes in the binary representation.
      */
     static int Hex2Bin(const char *aHex, uint8_t *aBin, uint16_t aBinLength, bool aAllowTruncate = false);
 
@@ -177,8 +177,13 @@
      * Write an IPv6 address to the CLI console.
      *
      * @param[in]  aAddress  A reference to the IPv6 address.
+     *
+     * @returns The number of bytes placed in the output queue.
+     *
+     * @retval  -1  Driver is broken.
+     *
      */
-    void OutputIp6Address(const otIp6Address &aAddress) const;
+    int OutputIp6Address(const otIp6Address &aAddress) const;
 
     /**
      * Set a user command table.
@@ -193,151 +198,187 @@
     {
         kMaxArgs          = 32,
         kMaxAutoAddresses = 8,
+
+        kDefaultPingInterval = 1000, // (in mses)
+        kDefaultPingLength   = 8,    // (in bytes)
+        kDefaultPingCount    = 1,
     };
 
     otError ParsePingInterval(const char *aString, uint32_t &aInterval);
-    void    ProcessHelp(int argc, char *argv[]);
-    void    ProcessBufferInfo(int argc, char *argv[]);
-    void    ProcessChannel(int argc, char *argv[]);
-#if OPENTHREAD_FTD
-    void ProcessChild(int argc, char *argv[]);
-    void ProcessChildIp(int argc, char *argv[]);
-    void ProcessChildMax(int argc, char *argv[]);
+    void    ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
+    void    ProcessBufferInfo(uint8_t aArgsLength, char *aArgs[]);
+    void    ProcessChannel(uint8_t aArgsLength, char *aArgs[]);
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    void ProcessBackboneRouter(uint8_t aArgsLength, char *aArgs[]);
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    otError ProcessBackboneRouterLocal(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessChildTimeout(int argc, char *argv[]);
+
+    void ProcessDomainName(uint8_t aArgsLength, char *aArgs[]);
+
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    void ProcessDua(uint8_t aArgsLength, char *aArgs[]);
+#endif
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
+#if OPENTHREAD_FTD
+    void ProcessChild(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessChildIp(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessChildMax(uint8_t aArgsLength, char *aArgs[]);
+#endif
+    void ProcessChildTimeout(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
-    void ProcessCoap(int argc, char *argv[]);
+    void ProcessCoap(uint8_t aArgsLength, char *aArgs[]);
 #endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
-    void ProcessCoapSecure(int argc, char *argv[]);
+    void ProcessCoapSecure(uint8_t aArgsLength, char *aArgs[]);
 #endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
 #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
-    void ProcessCoexMetrics(int argc, char *argv[]);
+    void ProcessCoexMetrics(uint8_t aArgsLength, char *aArgs[]);
 #endif
 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
-    void ProcessCommissioner(int argc, char *argv[]);
+    void ProcessCommissioner(uint8_t aArgsLength, char *aArgs[]);
 #endif
 #if OPENTHREAD_FTD
-    void ProcessContextIdReuseDelay(int argc, char *argv[]);
+    void ProcessContextIdReuseDelay(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessCounters(int argc, char *argv[]);
+    void ProcessCounters(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_FTD
-    void ProcessDelayTimerMin(int argc, char *argv[]);
+    void ProcessDelayTimerMin(uint8_t aArgsLength, char *aArgs[]);
 #endif
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
-    void ProcessDiag(int argc, char *argv[]);
+    void ProcessDiag(uint8_t aArgsLength, char *aArgs[]);
 #endif // OPENTHREAD_CONFIG_DIAG_ENABLE
-    void ProcessDiscover(int argc, char *argv[]);
+    void ProcessDiscover(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
-    void ProcessDns(int argc, char *argv[]);
+    void ProcessDns(uint8_t aArgsLength, char *aArgs[]);
 #endif
 #if OPENTHREAD_FTD
-    void ProcessEidCache(int argc, char *argv[]);
+    void ProcessEidCache(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessEui64(int argc, char *argv[]);
+    void ProcessEui64(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_POSIX
-    void ProcessExit(int argc, char *argv[]);
+    void ProcessExit(uint8_t aArgsLength, char *aArgs[]);
 #endif
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
-    void ProcessLogFilename(int argc, char *argv[]);
-#endif
-    void    ProcessExtAddress(int argc, char *argv[]);
-    void    ProcessExtPanId(int argc, char *argv[]);
-    void    ProcessFactoryReset(int argc, char *argv[]);
-    void    ProcessIfconfig(int argc, char *argv[]);
-    void    ProcessIpAddr(int argc, char *argv[]);
-    otError ProcessIpAddrAdd(int argc, char *argv[]);
-    otError ProcessIpAddrDel(int argc, char *argv[]);
-    void    ProcessIpMulticastAddr(int argc, char *argv[]);
-    otError ProcessIpMulticastAddrAdd(int argc, char *argv[]);
-    otError ProcessIpMulticastAddrDel(int argc, char *argv[]);
-    otError ProcessMulticastPromiscuous(int argc, char *argv[]);
+    void    ProcessLog(uint8_t aArgsLength, char *aArgs[]);
+    void    ProcessExtAddress(uint8_t aArgsLength, char *aArgs[]);
+    void    ProcessExtPanId(uint8_t aArgsLength, char *aArgs[]);
+    void    ProcessFactoryReset(uint8_t aArgsLength, char *aArgs[]);
+    void    ProcessIfconfig(uint8_t aArgsLength, char *aArgs[]);
+    void    ProcessIpAddr(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessIpAddrAdd(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessIpAddrDel(uint8_t aArgsLength, char *aArgs[]);
+    void    ProcessIpMulticastAddr(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessIpMulticastAddrAdd(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessIpMulticastAddrDel(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMulticastPromiscuous(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_CONFIG_JOINER_ENABLE
-    void ProcessJoiner(int argc, char *argv[]);
+    void ProcessJoiner(uint8_t aArgsLength, char *aArgs[]);
 #endif
 #if OPENTHREAD_FTD
-    void ProcessJoinerPort(int argc, char *argv[]);
+    void ProcessJoinerPort(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessKeySequence(int argc, char *argv[]);
-    void ProcessLeaderData(int argc, char *argv[]);
+    void ProcessKeySequence(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessLeaderData(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_FTD
-    void ProcessLeaderPartitionId(int argc, char *argv[]);
-    void ProcessLeaderWeight(int argc, char *argv[]);
+    void ProcessLeaderPartitionId(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessLeaderWeight(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessMasterKey(int argc, char *argv[]);
-    void ProcessMode(int argc, char *argv[]);
+    void ProcessMasterKey(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessMode(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_FTD
-    void ProcessNeighbor(int argc, char *argv[]);
+    void ProcessNeighbor(uint8_t aArgsLength, char *aArgs[]);
 #endif
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
-    void ProcessNetworkDataRegister(int argc, char *argv[]);
+    void ProcessNetworkDataRegister(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessNetworkDataShow(int argc, char *argv[]);
+    void ProcessNetworkDataShow(uint8_t aArgsLength, char *aArgs[]);
+#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+    void ProcessNetif(uint8_t aArgsLength, char *aArgs[]);
+#endif
+    void ProcessNetstat(uint8_t aArgsLength, char *aArgs[]);
+    int  OutputSocketAddress(const otSockAddr &aAddress);
 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
-    void ProcessService(int argc, char *argv[]);
+    void ProcessService(uint8_t aArgsLength, char *aArgs[]);
 #endif
 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
-    void ProcessNetworkDiagnostic(int argc, char *argv[]);
+    void ProcessNetworkDiagnostic(uint8_t aArgsLength, char *aArgs[]);
 #endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
 #if OPENTHREAD_FTD
-    void ProcessNetworkIdTimeout(int argc, char *argv[]);
+    void ProcessNetworkIdTimeout(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessNetworkName(int argc, char *argv[]);
+    void ProcessNetworkName(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    void ProcessNetworkTime(int argc, char *argv[]);
+    void ProcessNetworkTime(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessPanId(int argc, char *argv[]);
-    void ProcessParent(int argc, char *argv[]);
+    void ProcessPanId(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessParent(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_FTD
-    void ProcessParentPriority(int argc, char *argv[]);
+    void ProcessParentPriority(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessPing(int argc, char *argv[]);
-    void ProcessPollPeriod(int argc, char *argv[]);
+    void ProcessPing(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessPollPeriod(uint8_t aArgsLength, char *aArgs[]);
+    void SignalPingRequest(const Ip6::Address &aPeerAddress,
+                           uint16_t            aPingLength,
+                           uint32_t            aTimestamp,
+                           uint8_t             aHopLimit);
+    void SignalPingReply(const Ip6::Address &aPeerAddress,
+                         uint16_t            aPingLength,
+                         uint32_t            aTimestamp,
+                         uint8_t             aHopLimit);
+
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
-    void    ProcessPrefix(int argc, char *argv[]);
-    otError ProcessPrefixAdd(int argc, char *argv[]);
-    otError ProcessPrefixRemove(int argc, char *argv[]);
+    void    ProcessPrefix(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessPrefixAdd(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessPrefixRemove(uint8_t aArgsLength, char *aArgs[]);
     otError ProcessPrefixList(void);
+    void    OutputPrefix(otBorderRouterConfig &aConfig);
 #endif
-    void ProcessPromiscuous(int argc, char *argv[]);
+    void ProcessPromiscuous(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_FTD
-    void ProcessPskc(int argc, char *argv[]);
-    void ProcessReleaseRouterId(int argc, char *argv[]);
+    void ProcessPreferRouterId(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessPskc(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessReset(int argc, char *argv[]);
+    void ProcessRcp(uint8_t aArgsLength, char *aArgs[]);
+#if OPENTHREAD_FTD
+    void ProcessReleaseRouterId(uint8_t aArgsLength, char *aArgs[]);
+#endif
+    void ProcessReset(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
-    void    ProcessRoute(int argc, char *argv[]);
-    otError ProcessRouteAdd(int argc, char *argv[]);
-    otError ProcessRouteRemove(int argc, char *argv[]);
+    void    ProcessRoute(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessRouteAdd(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessRouteRemove(uint8_t aArgsLength, char *aArgs[]);
     otError ProcessRouteList(void);
 #endif
 #if OPENTHREAD_FTD
-    void ProcessRouter(int argc, char *argv[]);
-    void ProcessRouterDowngradeThreshold(int argc, char *argv[]);
-    void ProcessRouterEligible(int argc, char *argv[]);
-    void ProcessRouterSelectionJitter(int argc, char *argv[]);
-    void ProcessRouterUpgradeThreshold(int argc, char *argv[]);
+    void ProcessRouter(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessRouterDowngradeThreshold(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessRouterEligible(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessRouterSelectionJitter(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessRouterUpgradeThreshold(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessRloc16(int argc, char *argv[]);
-    void ProcessScan(int argc, char *argv[]);
-    void ProcessSingleton(int argc, char *argv[]);
+    void ProcessRloc16(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessScan(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessSingleton(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
-    void ProcessSntp(int argc, char *argv[]);
+    void ProcessSntp(uint8_t aArgsLength, char *aArgs[]);
 #endif
-    void ProcessState(int argc, char *argv[]);
-    void ProcessThread(int argc, char *argv[]);
-    void ProcessDataset(int argc, char *argv[]);
-    void ProcessTxPower(int argc, char *argv[]);
-    void ProcessUdp(int argc, char *argv[]);
-    void ProcessVersion(int argc, char *argv[]);
+    void ProcessState(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessThread(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessDataset(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessTxPower(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessUdp(uint8_t aArgsLength, char *aArgs[]);
+    void ProcessVersion(uint8_t aArgsLength, char *aArgs[]);
 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
-    void    ProcessMacFilter(int argc, char *argv[]);
+    void    ProcessMacFilter(uint8_t aArgsLength, char *aArgs[]);
     void    PrintMacFilter(void);
-    otError ProcessMacFilterAddress(int argc, char *argv[]);
-    otError ProcessMacFilterRss(int argc, char *argv[]);
+    otError ProcessMacFilterAddress(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMacFilterRss(uint8_t aArgsLength, char *aArgs[]);
 #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
-    void    ProcessMac(int argc, char *argv[]);
-    otError ProcessMacRetries(int argc, char *argv[]);
+    void    ProcessMac(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMacRetries(uint8_t aArgsLength, char *aArgs[]);
 
     static void HandleIcmpReceive(void *               aContext,
                                   otMessage *          aMessage,
@@ -347,7 +388,19 @@
     static void HandleActiveScanResult(otActiveScanResult *aResult, void *aContext);
     static void HandleEnergyScanResult(otEnergyScanResult *aResult, void *aContext);
     static void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext);
+
+#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
+    void        HandleDiagnosticGetResponse(const otMessage &aMessage, const Ip6::MessageInfo &aMessageInfo);
     static void HandleDiagnosticGetResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, void *aContext);
+    void        OutputSpaces(uint16_t aCount);
+    void        OutputMode(const otLinkModeConfig &aMode, uint16_t aColumn);
+    void        OutputConnectivity(const otNetworkDiagConnectivity &aConnectivity, uint16_t aColumn);
+    void        OutputRoute(const otNetworkDiagRoute &aRoute, uint16_t aColumn);
+    void        OutputRouteData(const otNetworkDiagRouteData &aRouteData, uint16_t aColumn);
+    void        OutputLeaderData(const otLeaderData &aLeaderData, uint16_t aColumn);
+    void        OutputNetworkDiagMacCounters(const otNetworkDiagMacCounters &aMacCounters, uint16_t aColumn);
+    void        OutputChildTableEntry(const otNetworkDiagChildEntry &aChildEntry, uint16_t aColumn);
+#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
 
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
     static void HandleDnsResponse(void *              aContext,
@@ -361,12 +414,11 @@
     static void HandleSntpResponse(void *aContext, uint64_t aTime, otError aResult);
 #endif
 
-    void HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const otIcmp6Header &aIcmpHeader);
-    void HandlePingTimer();
+    void HandleIcmpReceive(otMessage *aMessage, const otMessageInfo *aMessageInfo, const otIcmp6Header *aIcmpHeader);
+    void SendPing(void);
     void HandleActiveScanResult(otActiveScanResult *aResult);
     void HandleEnergyScanResult(otEnergyScanResult *aResult);
     void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx);
-    void HandleDiagnosticGetResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
     void HandleDnsResponse(const char *aHostname, const Ip6::Address *aAddress, uint32_t aTtl, otError aResult);
 #endif
@@ -379,10 +431,13 @@
     const otCliCommand *        mUserCommands;
     uint8_t                     mUserCommandsLength;
     Server *                    mServer;
-    Ip6::MessageInfo            mMessageInfo;
-    uint16_t                    mLength;
-    uint16_t                    mCount;
-    uint32_t                    mInterval;
+    uint16_t                    mPingLength;
+    uint16_t                    mPingCount;
+    uint32_t                    mPingInterval;
+    uint8_t                     mPingHopLimit;
+    bool                        mPingAllowZeroHopLimit;
+    uint16_t                    mPingIdentifier;
+    otIp6Address                mPingDestAddress;
     TimerMilli                  mPingTimer;
     otIcmp6Handler              mIcmpHandler;
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
diff --git a/src/cli/cli_coap.cpp b/src/cli/cli_coap.cpp
index cf9418a..89a9f04 100644
--- a/src/cli/cli_coap.cpp
+++ b/src/cli/cli_coap.cpp
@@ -45,17 +45,93 @@
 namespace Cli {
 
 const struct Coap::Command Coap::sCommands[] = {
-    {"help", &Coap::ProcessHelp},    {"delete", &Coap::ProcessRequest}, {"get", &Coap::ProcessRequest},
-    {"post", &Coap::ProcessRequest}, {"put", &Coap::ProcessRequest},    {"resource", &Coap::ProcessResource},
-    {"start", &Coap::ProcessStart},  {"stop", &Coap::ProcessStop},
+    {"help", &Coap::ProcessHelp},
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    {"cancel", &Coap::ProcessCancel},
+#endif
+    {"delete", &Coap::ProcessRequest},
+    {"get", &Coap::ProcessRequest},
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    {"observe", &Coap::ProcessRequest},
+#endif
+    {"parameters", &Coap::ProcessParameters},
+    {"post", &Coap::ProcessRequest},
+    {"put", &Coap::ProcessRequest},
+    {"resource", &Coap::ProcessResource},
+    {"set", &Coap::ProcessSet},
+    {"start", &Coap::ProcessStart},
+    {"stop", &Coap::ProcessStop},
 };
 
 Coap::Coap(Interpreter &aInterpreter)
     : mInterpreter(aInterpreter)
+    , mUseDefaultRequestTxParameters(true)
+    , mUseDefaultResponseTxParameters(true)
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    , mObserveSerial(0)
+    , mRequestTokenLength(0)
+    , mSubscriberTokenLength(0)
+    , mSubscriberConfirmableNotifications(false)
+#endif
 {
     memset(&mResource, 0, sizeof(mResource));
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    memset(&mRequestAddr, 0, sizeof(mRequestAddr));
+    memset(&mSubscriberSock, 0, sizeof(mSubscriberSock));
+    memset(&mRequestToken, 0, sizeof(mRequestToken));
+    memset(&mSubscriberToken, 0, sizeof(mSubscriberToken));
+    memset(&mRequestUri, 0, sizeof(mRequestUri));
+#endif
+    memset(&mUriPath, 0, sizeof(mUriPath));
+    strncpy(mResourceContent, "0", sizeof(mResourceContent));
+    mResourceContent[sizeof(mResourceContent) - 1] = '\0';
 }
 
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+otError Coap::CancelResourceSubscription(void)
+{
+    otError       error   = OT_ERROR_NONE;
+    otMessage *   message = nullptr;
+    otMessageInfo messageInfo;
+
+    memset(&messageInfo, 0, sizeof(messageInfo));
+    messageInfo.mPeerAddr = mRequestAddr;
+    messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
+
+    VerifyOrExit(mRequestTokenLength != 0, error = OT_ERROR_INVALID_STATE);
+
+    message = otCoapNewMessage(mInterpreter.mInstance, nullptr);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
+
+    otCoapMessageInit(message, OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_GET);
+
+    SuccessOrExit(error = otCoapMessageSetToken(message, mRequestToken, mRequestTokenLength));
+    SuccessOrExit(error = otCoapMessageAppendObserveOption(message, 1));
+    SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, mRequestUri));
+    SuccessOrExit(error =
+                      otCoapSendRequest(mInterpreter.mInstance, message, &messageInfo, &Coap::HandleResponse, this));
+
+    memset(&mRequestAddr, 0, sizeof(mRequestAddr));
+    memset(&mRequestUri, 0, sizeof(mRequestUri));
+    mRequestTokenLength = 0;
+
+exit:
+
+    if ((error != OT_ERROR_NONE) && (message != nullptr))
+    {
+        otMessageFree(message);
+    }
+
+    return error;
+}
+
+void Coap::CancelSubscriber(void)
+{
+    memset(&mSubscriberSock, 0, sizeof(mSubscriberSock));
+    mSubscriberTokenLength = 0;
+}
+#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+
 void Coap::PrintPayload(otMessage *aMessage) const
 {
     uint8_t  buf[kMaxBufferSize];
@@ -82,10 +158,20 @@
     mInterpreter.mServer->OutputFormat("\r\n");
 }
 
-otError Coap::ProcessHelp(int argc, char *argv[])
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+otError Coap::ProcessCancel(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
+
+    return CancelResourceSubscription();
+}
+#endif
+
+otError Coap::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
+{
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
@@ -95,20 +181,20 @@
     return OT_ERROR_NONE;
 }
 
-otError Coap::ProcessResource(int argc, char *argv[])
+otError Coap::ProcessResource(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc > 1)
+    if (aArgsLength > 1)
     {
-        VerifyOrExit(strlen(argv[1]) < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(strlen(aArgs[1]) < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
 
         mResource.mUriPath = mUriPath;
         mResource.mContext = this;
         mResource.mHandler = &Coap::HandleRequest;
 
-        strncpy(mUriPath, argv[1], sizeof(mUriPath) - 1);
-        SuccessOrExit(error = otCoapAddResource(mInterpreter.mInstance, &mResource));
+        strncpy(mUriPath, aArgs[1], sizeof(mUriPath) - 1);
+        otCoapAddResource(mInterpreter.mInstance, &mResource);
     }
     else
     {
@@ -116,31 +202,166 @@
     }
 
 exit:
-    return OT_ERROR_NONE;
+    return error;
 }
 
-otError Coap::ProcessStart(int argc, char *argv[])
+otError Coap::ProcessSet(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    otMessage *   notificationMessage = nullptr;
+    otMessageInfo messageInfo;
+#endif
+    otError error = OT_ERROR_NONE;
+
+    if (aArgsLength > 1)
+    {
+        VerifyOrExit(strlen(aArgs[1]) < sizeof(mResourceContent), error = OT_ERROR_INVALID_ARGS);
+        strncpy(mResourceContent, aArgs[1], sizeof(mResourceContent));
+        mResourceContent[sizeof(mResourceContent) - 1] = '\0';
+
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+        if (mSubscriberTokenLength > 0)
+        {
+            // Notify the subscriber
+            memset(&messageInfo, 0, sizeof(messageInfo));
+            messageInfo.mPeerAddr = mSubscriberSock.mAddress;
+            messageInfo.mPeerPort = mSubscriberSock.mPort;
+
+            mInterpreter.mServer->OutputFormat("sending coap notification to ");
+            mInterpreter.OutputIp6Address(mSubscriberSock.mAddress);
+            mInterpreter.mServer->OutputFormat("\r\n");
+
+            notificationMessage = otCoapNewMessage(mInterpreter.mInstance, nullptr);
+            VerifyOrExit(notificationMessage != nullptr, error = OT_ERROR_NO_BUFS);
+
+            otCoapMessageInit(
+                notificationMessage,
+                ((mSubscriberConfirmableNotifications) ? OT_COAP_TYPE_CONFIRMABLE : OT_COAP_TYPE_NON_CONFIRMABLE),
+                OT_COAP_CODE_CONTENT);
+
+            SuccessOrExit(error = otCoapMessageSetToken(notificationMessage, mSubscriberToken, mSubscriberTokenLength));
+            SuccessOrExit(error = otCoapMessageAppendObserveOption(notificationMessage, mObserveSerial++));
+            SuccessOrExit(error = otCoapMessageSetPayloadMarker(notificationMessage));
+            SuccessOrExit(error = otMessageAppend(notificationMessage, mResourceContent,
+                                                  static_cast<uint16_t>(strlen(mResourceContent))));
+
+            SuccessOrExit(error = otCoapSendRequest(mInterpreter.mInstance, notificationMessage, &messageInfo,
+                                                    &Coap::HandleNotificationResponse, this));
+        }
+#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    }
+    else
+    {
+        mInterpreter.mServer->OutputFormat("%s\r\n", mResourceContent);
+    }
+
+exit:
+
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    if ((error != OT_ERROR_NONE) && (notificationMessage != nullptr))
+    {
+        otMessageFree(notificationMessage);
+    }
+#endif
+
+    return error;
+}
+
+otError Coap::ProcessStart(uint8_t aArgsLength, char *aArgs[])
+{
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     return otCoapStart(mInterpreter.mInstance, OT_DEFAULT_COAP_PORT);
 }
 
-otError Coap::ProcessStop(int argc, char *argv[])
+otError Coap::ProcessStop(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otCoapRemoveResource(mInterpreter.mInstance, &mResource);
 
     return otCoapStop(mInterpreter.mInstance);
 }
 
-otError Coap::ProcessRequest(int argc, char *argv[])
+otError Coap::ProcessParameters(uint8_t aArgsLength, char *aArgs[])
+{
+    otError             error = OT_ERROR_NONE;
+    bool *              defaultTxParameters;
+    otCoapTxParameters *txParameters;
+
+    VerifyOrExit(aArgsLength > 1, error = OT_ERROR_INVALID_ARGS);
+
+    if (strcmp(aArgs[1], "request") == 0)
+    {
+        txParameters        = &mRequestTxParameters;
+        defaultTxParameters = &mUseDefaultRequestTxParameters;
+    }
+    else if (strcmp(aArgs[1], "response") == 0)
+    {
+        txParameters        = &mResponseTxParameters;
+        defaultTxParameters = &mUseDefaultResponseTxParameters;
+    }
+    else
+    {
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
+    }
+
+    if (aArgsLength > 2)
+    {
+        if (strcmp(aArgs[2], "default") == 0)
+        {
+            *defaultTxParameters = true;
+        }
+        else
+        {
+            unsigned long value;
+
+            VerifyOrExit(aArgsLength >= 6, error = OT_ERROR_INVALID_ARGS);
+
+            SuccessOrExit(error = mInterpreter.ParseUnsignedLong(aArgs[2], value));
+            txParameters->mAckTimeout = static_cast<uint32_t>(value);
+
+            SuccessOrExit(error = mInterpreter.ParseUnsignedLong(aArgs[3], value));
+            VerifyOrExit(value <= 255, error = OT_ERROR_INVALID_ARGS);
+            txParameters->mAckRandomFactorNumerator = static_cast<uint8_t>(value);
+
+            SuccessOrExit(error = mInterpreter.ParseUnsignedLong(aArgs[4], value));
+            VerifyOrExit(value <= 255, error = OT_ERROR_INVALID_ARGS);
+            txParameters->mAckRandomFactorDenominator = static_cast<uint8_t>(value);
+
+            SuccessOrExit(error = mInterpreter.ParseUnsignedLong(aArgs[5], value));
+            VerifyOrExit(value <= 255, error = OT_ERROR_INVALID_ARGS);
+            txParameters->mMaxRetransmit = static_cast<uint8_t>(value);
+
+            VerifyOrExit(txParameters->mAckRandomFactorNumerator > txParameters->mAckRandomFactorDenominator,
+                         error = OT_ERROR_INVALID_ARGS);
+
+            *defaultTxParameters = false;
+        }
+    }
+
+    mInterpreter.mServer->OutputFormat("Transmission parameters for %s:\r\n", aArgs[1]);
+    if (*defaultTxParameters)
+    {
+        mInterpreter.mServer->OutputFormat("default\r\n");
+    }
+    else
+    {
+        mInterpreter.mServer->OutputFormat("ACK_TIMEOUT=%u ms, ACK_RANDOM_FACTOR=%u/%u, MAX_RETRANSMIT=%u\r\n",
+                                           txParameters->mAckTimeout, txParameters->mAckRandomFactorNumerator,
+                                           txParameters->mAckRandomFactorDenominator, txParameters->mMaxRetransmit);
+    }
+
+exit:
+    return error;
+}
+
+otError Coap::ProcessRequest(uint8_t aArgsLength, char *aArgs[])
 {
     otError       error   = OT_ERROR_NONE;
-    otMessage *   message = NULL;
+    otMessage *   message = nullptr;
     otMessageInfo messageInfo;
     uint16_t      payloadLength = 0;
 
@@ -149,23 +370,34 @@
     otCoapType   coapType               = OT_COAP_TYPE_NON_CONFIRMABLE;
     otCoapCode   coapCode               = OT_COAP_CODE_GET;
     otIp6Address coapDestinationIp;
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    bool coapObserve = false;
+#endif
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
     // CoAP-Code
-    if (strcmp(argv[0], "get") == 0)
+    if (strcmp(aArgs[0], "get") == 0)
     {
         coapCode = OT_COAP_CODE_GET;
     }
-    else if (strcmp(argv[0], "post") == 0)
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    else if (strcmp(aArgs[0], "observe") == 0)
+    {
+        // Observe request.  This is a GET with Observe=0
+        coapCode    = OT_COAP_CODE_GET;
+        coapObserve = true;
+    }
+#endif
+    else if (strcmp(aArgs[0], "post") == 0)
     {
         coapCode = OT_COAP_CODE_POST;
     }
-    else if (strcmp(argv[0], "put") == 0)
+    else if (strcmp(aArgs[0], "put") == 0)
     {
         coapCode = OT_COAP_CODE_PUT;
     }
-    else if (strcmp(argv[0], "delete") == 0)
+    else if (strcmp(aArgs[0], "delete") == 0)
     {
         coapCode = OT_COAP_CODE_DELETE;
     }
@@ -175,9 +407,9 @@
     }
 
     // Destination IPv6 address
-    if (argc > 1)
+    if (aArgsLength > 1)
     {
-        SuccessOrExit(error = otIp6AddressFromString(argv[1], &coapDestinationIp));
+        SuccessOrExit(error = otIp6AddressFromString(aArgs[1], &coapDestinationIp));
     }
     else
     {
@@ -185,10 +417,10 @@
     }
 
     // CoAP-URI
-    if (argc > 2)
+    if (aArgsLength > 2)
     {
-        VerifyOrExit(strlen(argv[2]) < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
-        strncpy(coapUri, argv[2], sizeof(coapUri) - 1);
+        VerifyOrExit(strlen(aArgs[2]) < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
+        strncpy(coapUri, aArgs[2], sizeof(coapUri) - 1);
     }
     else
     {
@@ -196,24 +428,40 @@
     }
 
     // CoAP-Type
-    if (argc > 3)
+    if (aArgsLength > 3)
     {
-        if (strcmp(argv[3], "con") == 0)
+        if (strcmp(aArgs[3], "con") == 0)
         {
             coapType = OT_COAP_TYPE_CONFIRMABLE;
         }
     }
 
-    message = otCoapNewMessage(mInterpreter.mInstance, NULL);
-    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    if (coapObserve && mRequestTokenLength)
+    {
+        // New observe request, cancel any existing observation
+        SuccessOrExit(error = CancelResourceSubscription());
+    }
+#endif
+
+    message = otCoapNewMessage(mInterpreter.mInstance, nullptr);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
     otCoapMessageInit(message, coapType, coapCode);
     otCoapMessageGenerateToken(message, ot::Coap::Message::kDefaultTokenLength);
+
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    if (coapObserve)
+    {
+        SuccessOrExit(error = otCoapMessageAppendObserveOption(message, 0));
+    }
+#endif
+
     SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, coapUri));
 
-    if (argc > 4)
+    if (aArgsLength > 4)
     {
-        payloadLength = static_cast<uint16_t>(strlen(argv[4]));
+        payloadLength = static_cast<uint16_t>(strlen(aArgs[4]));
 
         if (payloadLength > 0)
         {
@@ -224,25 +472,39 @@
     // Embed content into message if given
     if (payloadLength > 0)
     {
-        SuccessOrExit(error = otMessageAppend(message, argv[4], payloadLength));
+        SuccessOrExit(error = otMessageAppend(message, aArgs[4], payloadLength));
     }
 
     memset(&messageInfo, 0, sizeof(messageInfo));
     messageInfo.mPeerAddr = coapDestinationIp;
     messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
 
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    if (coapObserve)
+    {
+        // Make a note of the message details for later so we can cancel it later.
+        memcpy(&mRequestAddr, &coapDestinationIp, sizeof(mRequestAddr));
+        mRequestTokenLength = otCoapMessageGetTokenLength(message);
+        memcpy(mRequestToken, otCoapMessageGetToken(message), mRequestTokenLength);
+        strncpy(mRequestUri, coapUri, sizeof(mRequestUri) - 1);
+        mRequestUri[sizeof(mRequestUri) - 1] = '\0'; // Fix gcc-9.2 warning
+    }
+#endif
+
     if ((coapType == OT_COAP_TYPE_CONFIRMABLE) || (coapCode == OT_COAP_CODE_GET))
     {
-        error = otCoapSendRequest(mInterpreter.mInstance, message, &messageInfo, &Coap::HandleResponse, this);
+        error = otCoapSendRequestWithParameters(mInterpreter.mInstance, message, &messageInfo, &Coap::HandleResponse,
+                                                this, GetRequestTxParameters());
     }
     else
     {
-        error = otCoapSendRequest(mInterpreter.mInstance, message, &messageInfo, NULL, NULL);
+        error = otCoapSendRequestWithParameters(mInterpreter.mInstance, message, &messageInfo, nullptr, nullptr,
+                                                GetResponseTxParameters());
     }
 
 exit:
 
-    if ((error != OT_ERROR_NONE) && (message != NULL))
+    if ((error != OT_ERROR_NONE) && (message != nullptr))
     {
         otMessageFree(message);
     }
@@ -250,22 +512,22 @@
     return error;
 }
 
-otError Coap::Process(int argc, char *argv[])
+otError Coap::Process(uint8_t aArgsLength, char *aArgs[])
 {
-    otError error = OT_ERROR_PARSE;
+    otError error = OT_ERROR_INVALID_COMMAND;
 
-    if (argc < 1)
+    if (aArgsLength < 1)
     {
-        ProcessHelp(0, NULL);
+        IgnoreError(ProcessHelp(0, nullptr));
         error = OT_ERROR_INVALID_ARGS;
     }
     else
     {
         for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
         {
-            if (strcmp(argv[0], sCommands[i].mName) == 0)
+            if (strcmp(aArgs[0], sCommands[i].mName) == 0)
             {
-                error = (this->*sCommands[i].mCommand)(argc, argv);
+                error = (this->*sCommands[i].mCommand)(aArgsLength, aArgs);
                 break;
             }
         }
@@ -282,9 +544,13 @@
 void Coap::HandleRequest(otMessage *aMessage, const otMessageInfo *aMessageInfo)
 {
     otError    error           = OT_ERROR_NONE;
-    otMessage *responseMessage = NULL;
+    otMessage *responseMessage = nullptr;
     otCoapCode responseCode    = OT_COAP_CODE_EMPTY;
-    char       responseContent = '0';
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    uint64_t             observe        = 0;
+    bool                 observePresent = false;
+    otCoapOptionIterator iterator;
+#endif
 
     mInterpreter.mServer->OutputFormat("coap request from ");
     mInterpreter.OutputIp6Address(aMessageInfo->mPeerAddr);
@@ -294,6 +560,16 @@
     {
     case OT_COAP_CODE_GET:
         mInterpreter.mServer->OutputFormat("GET");
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+        SuccessOrExit(error = otCoapOptionIteratorInit(&iterator, aMessage));
+        if (otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_OBSERVE) != nullptr)
+        {
+            SuccessOrExit(error = otCoapOptionIteratorGetOptionUintValue(&iterator, &observe));
+            observePresent = true;
+
+            mInterpreter.mServer->OutputFormat(" OBS=%lu", static_cast<uint32_t>(observe));
+        }
+#endif
         break;
 
     case OT_COAP_CODE_DELETE:
@@ -318,35 +594,85 @@
     if (otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE ||
         otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
     {
-        if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+        if (observePresent && (mSubscriberTokenLength > 0) && (observe == 0))
+        {
+            // There is already a subscriber
+            responseCode = OT_COAP_CODE_SERVICE_UNAVAILABLE;
+        }
+        else
+#endif
+            if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
         {
             responseCode = OT_COAP_CODE_CONTENT;
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+            if (observePresent)
+            {
+                if (observe == 0)
+                {
+                    // New subscriber
+                    mInterpreter.mServer->OutputFormat("Subscribing client\r\n");
+                    mSubscriberSock.mAddress = aMessageInfo->mPeerAddr;
+                    mSubscriberSock.mPort    = aMessageInfo->mPeerPort;
+                    mSubscriberTokenLength   = otCoapMessageGetTokenLength(aMessage);
+                    memcpy(mSubscriberToken, otCoapMessageGetToken(aMessage), mSubscriberTokenLength);
+
+                    /*
+                     * Implementer note.
+                     *
+                     * Here, we try to match a confirmable GET request with confirmable
+                     * notifications, however this is not a requirement of RFC7641:
+                     * the server can send notifications of either type regardless of
+                     * what the client used to subscribe initially.
+                     */
+                    mSubscriberConfirmableNotifications = (otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE);
+                }
+                else if (observe == 1)
+                {
+                    // See if it matches our subscriber token
+                    if ((otCoapMessageGetTokenLength(aMessage) == mSubscriberTokenLength) &&
+                        (memcmp(otCoapMessageGetToken(aMessage), mSubscriberToken, mSubscriberTokenLength) == 0))
+                    {
+                        // Unsubscribe request
+                        CancelSubscriber();
+                    }
+                }
+            }
+#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
         }
         else
         {
             responseCode = OT_COAP_CODE_VALID;
         }
 
-        responseMessage = otCoapNewMessage(mInterpreter.mInstance, NULL);
-        VerifyOrExit(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
+        responseMessage = otCoapNewMessage(mInterpreter.mInstance, nullptr);
+        VerifyOrExit(responseMessage != nullptr, error = OT_ERROR_NO_BUFS);
 
         SuccessOrExit(
             error = otCoapMessageInitResponse(responseMessage, aMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode));
 
-        if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
+        if (responseCode == OT_COAP_CODE_CONTENT)
         {
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+            if (observePresent && (observe == 0))
+            {
+                SuccessOrExit(error = otCoapMessageAppendObserveOption(responseMessage, mObserveSerial++));
+            }
+#endif
             SuccessOrExit(error = otCoapMessageSetPayloadMarker(responseMessage));
-            SuccessOrExit(error = otMessageAppend(responseMessage, &responseContent, sizeof(responseContent)));
+            SuccessOrExit(error = otMessageAppend(responseMessage, mResourceContent,
+                                                  static_cast<uint16_t>(strlen(mResourceContent))));
         }
 
-        SuccessOrExit(error = otCoapSendResponse(mInterpreter.mInstance, responseMessage, aMessageInfo));
+        SuccessOrExit(error = otCoapSendResponseWithParameters(mInterpreter.mInstance, responseMessage, aMessageInfo,
+                                                               GetResponseTxParameters()));
     }
 
 exit:
 
     if (error != OT_ERROR_NONE)
     {
-        if (responseMessage != NULL)
+        if (responseMessage != nullptr)
         {
             mInterpreter.mServer->OutputFormat("coap send response error %d: %s\r\n", error,
                                                otThreadErrorToString(error));
@@ -359,6 +685,39 @@
     }
 }
 
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+void Coap::HandleNotificationResponse(void *               aContext,
+                                      otMessage *          aMessage,
+                                      const otMessageInfo *aMessageInfo,
+                                      otError              aError)
+{
+    static_cast<Coap *>(aContext)->HandleNotificationResponse(aMessage, aMessageInfo, aError);
+}
+
+void Coap::HandleNotificationResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
+{
+    OT_UNUSED_VARIABLE(aMessage);
+
+    switch (aError)
+    {
+    case OT_ERROR_NONE:
+        if (aMessageInfo != nullptr)
+        {
+            mInterpreter.mServer->OutputFormat("Received ACK in reply to notification from ");
+            mInterpreter.OutputIp6Address(aMessageInfo->mPeerAddr);
+            mInterpreter.mServer->OutputFormat("\r\n");
+        }
+        break;
+
+    default:
+        mInterpreter.mServer->OutputFormat("coap receive notification response error %d: %s\r\n", aError,
+                                           otThreadErrorToString(aError));
+        CancelSubscriber();
+        break;
+    }
+}
+#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+
 void Coap::HandleResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
 {
     static_cast<Coap *>(aContext)->HandleResponse(aMessage, aMessageInfo, aError);
@@ -371,11 +730,33 @@
         mInterpreter.mServer->OutputFormat("coap receive response error %d: %s\r\n", aError,
                                            otThreadErrorToString(aError));
     }
-    else
+    else if ((aMessageInfo != nullptr) && (aMessage != nullptr))
     {
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+        otCoapOptionIterator iterator;
+#endif
+
         mInterpreter.mServer->OutputFormat("coap response from ");
         mInterpreter.OutputIp6Address(aMessageInfo->mPeerAddr);
 
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+        if (otCoapOptionIteratorInit(&iterator, aMessage) == OT_ERROR_NONE)
+        {
+            const otCoapOption *observeOpt =
+                otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_OBSERVE);
+
+            if (observeOpt != nullptr)
+            {
+                uint64_t observeVal = 0;
+                otError  error      = otCoapOptionIteratorGetOptionUintValue(&iterator, &observeVal);
+
+                if (error == OT_ERROR_NONE)
+                {
+                    mInterpreter.mServer->OutputFormat(" OBS=%u", observeVal);
+                }
+            }
+        }
+#endif
         PrintPayload(aMessage);
     }
 }
diff --git a/src/cli/cli_coap.hpp b/src/cli/cli_coap.hpp
index cc534a3..a406683 100644
--- a/src/cli/cli_coap.hpp
+++ b/src/cli/cli_coap.hpp
@@ -63,11 +63,11 @@
     /**
      * This method interprets a list of CLI arguments.
      *
-     * @param[in]  argc  The number of elements in argv.
-     * @param[in]  argv  A pointer to an array of command line arguments.
+     * @param[in]  aArgsLength  The number of elements in @p aArgs.
+     * @param[in]  aArgs        An array of command line arguments.
      *
      */
-    otError Process(int argc, char *argv[]);
+    otError Process(uint8_t aArgsLength, char *aArgs[]);
 
 private:
     enum
@@ -79,28 +79,76 @@
     struct Command
     {
         const char *mName;
-        otError (Coap::*mCommand)(int argc, char *argv[]);
+        otError (Coap::*mCommand)(uint8_t aArgsLength, char *aArgs[]);
     };
 
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    otError CancelResourceSubscription(void);
+    void    CancelSubscriber(void);
+#endif
+
     void PrintPayload(otMessage *aMessage) const;
 
-    otError ProcessHelp(int argc, char *argv[]);
-    otError ProcessRequest(int argc, char *argv[]);
-    otError ProcessResource(int argc, char *argv[]);
-    otError ProcessStart(int argc, char *argv[]);
-    otError ProcessStop(int argc, char *argv[]);
+    otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    otError ProcessCancel(uint8_t aArgsLength, char *aArgs[]);
+#endif
+    otError ProcessParameters(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessRequest(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessResource(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessSet(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessStart(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessStop(uint8_t aArgsLength, char *aArgs[]);
 
     static void HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleRequest(otMessage *aMessage, const otMessageInfo *aMessageInfo);
 
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    static void HandleNotificationResponse(void *               aContext,
+                                           otMessage *          aMessage,
+                                           const otMessageInfo *aMessageInfo,
+                                           otError              aError);
+    void        HandleNotificationResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError);
+#endif
+
     static void HandleResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError);
     void        HandleResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError);
 
+    const otCoapTxParameters *GetRequestTxParameters(void) const
+    {
+        return mUseDefaultRequestTxParameters ? nullptr : &mRequestTxParameters;
+    }
+
+    const otCoapTxParameters *GetResponseTxParameters(void) const
+    {
+        return mUseDefaultResponseTxParameters ? nullptr : &mResponseTxParameters;
+    }
+
     static const Command sCommands[];
     Interpreter &        mInterpreter;
 
+    bool mUseDefaultRequestTxParameters;
+    bool mUseDefaultResponseTxParameters;
+
+    otCoapTxParameters mRequestTxParameters;
+    otCoapTxParameters mResponseTxParameters;
+
     otCoapResource mResource;
-    char           mUriPath[kMaxUriLength];
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    otIp6Address mRequestAddr;
+    otSockAddr   mSubscriberSock;
+    char         mRequestUri[kMaxUriLength];
+    uint8_t      mRequestToken[OT_COAP_MAX_TOKEN_LENGTH];
+    uint8_t      mSubscriberToken[OT_COAP_MAX_TOKEN_LENGTH];
+#endif
+    char mUriPath[kMaxUriLength];
+    char mResourceContent[kMaxBufferSize];
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    uint32_t mObserveSerial;
+    uint8_t  mRequestTokenLength;
+    uint8_t  mSubscriberTokenLength;
+    bool     mSubscriberConfirmableNotifications;
+#endif
 };
 
 } // namespace Cli
diff --git a/src/cli/cli_coap_secure.cpp b/src/cli/cli_coap_secure.cpp
index 3c14f7be..0787a0d 100644
--- a/src/cli/cli_coap_secure.cpp
+++ b/src/cli/cli_coap_secure.cpp
@@ -51,7 +51,8 @@
     {"delete", &CoapSecure::ProcessRequest}, {"disconnect", &CoapSecure::ProcessDisconnect},
     {"get", &CoapSecure::ProcessRequest},    {"post", &CoapSecure::ProcessRequest},
     {"put", &CoapSecure::ProcessRequest},    {"resource", &CoapSecure::ProcessResource},
-    {"start", &CoapSecure::ProcessStart},    {"stop", &CoapSecure::ProcessStop},
+    {"set", &CoapSecure::ProcessSet},        {"start", &CoapSecure::ProcessStart},
+    {"stop", &CoapSecure::ProcessStop},
 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
     {"psk", &CoapSecure::ProcessPsk},
 #endif
@@ -70,6 +71,8 @@
     memset(&mResource, 0, sizeof(mResource));
     memset(&mPsk, 0, sizeof(mPsk));
     memset(&mPskId, 0, sizeof(mPskId));
+    strncpy(mResourceContent, "0", sizeof(mResourceContent));
+    mResourceContent[sizeof(mResourceContent) - 1] = '\0';
 }
 
 void CoapSecure::PrintPayload(otMessage *aMessage) const
@@ -98,10 +101,10 @@
     mInterpreter.mServer->OutputFormat("\r\n");
 }
 
-otError CoapSecure::ProcessHelp(int argc, char *argv[])
+otError CoapSecure::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
@@ -111,20 +114,20 @@
     return OT_ERROR_NONE;
 }
 
-otError CoapSecure::ProcessResource(int argc, char *argv[])
+otError CoapSecure::ProcessResource(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    if (argc > 1)
+    if (aArgsLength > 1)
     {
-        VerifyOrExit(strlen(argv[1]) < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(strlen(aArgs[1]) < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
 
         mResource.mUriPath = mUriPath;
         mResource.mContext = this;
         mResource.mHandler = &CoapSecure::HandleRequest;
 
-        strncpy(mUriPath, argv[1], sizeof(mUriPath) - 1);
-        SuccessOrExit(error = otCoapSecureAddResource(mInterpreter.mInstance, &mResource));
+        strncpy(mUriPath, aArgs[1], sizeof(mUriPath) - 1);
+        otCoapSecureAddResource(mInterpreter.mInstance, &mResource);
     }
     else
     {
@@ -132,21 +135,40 @@
     }
 
 exit:
-    return OT_ERROR_NONE;
+    return error;
 }
 
-otError CoapSecure::ProcessStart(int argc, char *argv[])
+otError CoapSecure::ProcessSet(uint8_t aArgsLength, char *aArgs[])
+{
+    otError error = OT_ERROR_NONE;
+
+    if (aArgsLength > 1)
+    {
+        VerifyOrExit(strlen(aArgs[1]) < sizeof(mResourceContent), error = OT_ERROR_INVALID_ARGS);
+        strncpy(mResourceContent, aArgs[1], sizeof(mResourceContent));
+        mResourceContent[sizeof(mResourceContent) - 1] = '\0';
+    }
+    else
+    {
+        mInterpreter.mServer->OutputFormat("%s\r\n", mResourceContent);
+    }
+
+exit:
+    return error;
+}
+
+otError CoapSecure::ProcessStart(uint8_t aArgsLength, char *aArgs[])
 {
     otError error;
     bool    verifyPeerCert = true;
 
-    if (argc > 1)
+    if (aArgsLength > 1)
     {
-        if (strcmp(argv[1], "false") == 0)
+        if (strcmp(aArgs[1], "false") == 0)
         {
             verifyPeerCert = false;
         }
-        else if (strcmp(argv[1], "true") != 0)
+        else if (strcmp(aArgs[1], "true") != 0)
         {
             ExitNow(error = OT_ERROR_INVALID_ARGS);
         }
@@ -165,10 +187,10 @@
     return error;
 }
 
-otError CoapSecure::ProcessStop(int argc, char *argv[])
+otError CoapSecure::ProcessStop(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otCoapRemoveResource(mInterpreter.mInstance, &mResource);
 
@@ -185,10 +207,10 @@
     return OT_ERROR_NONE;
 }
 
-otError CoapSecure::ProcessRequest(int argc, char *argv[])
+otError CoapSecure::ProcessRequest(uint8_t aArgsLength, char *aArgs[])
 {
     otError       error   = OT_ERROR_NONE;
-    otMessage *   message = NULL;
+    otMessage *   message = nullptr;
     otMessageInfo messageInfo;
     uint16_t      payloadLength = 0;
     uint8_t       indexShifter  = 0;
@@ -199,34 +221,34 @@
     otCoapCode   coapCode               = OT_COAP_CODE_GET;
     otIp6Address coapDestinationIp;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
     // CoAP-Code
-    if (strcmp(argv[0], "get") == 0)
+    if (strcmp(aArgs[0], "get") == 0)
     {
         coapCode = OT_COAP_CODE_GET;
     }
-    else if (strcmp(argv[0], "post") == 0)
+    else if (strcmp(aArgs[0], "post") == 0)
     {
         coapCode = OT_COAP_CODE_POST;
     }
-    else if (strcmp(argv[0], "put") == 0)
+    else if (strcmp(aArgs[0], "put") == 0)
     {
         coapCode = OT_COAP_CODE_PUT;
     }
-    else if (strcmp(argv[0], "delete") == 0)
+    else if (strcmp(aArgs[0], "delete") == 0)
     {
         coapCode = OT_COAP_CODE_DELETE;
     }
     else
     {
-        ExitNow(error = OT_ERROR_PARSE);
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
     }
 
     // Destination IPv6 address
-    if (argc > 1)
+    if (aArgsLength > 1)
     {
-        error = otIp6AddressFromString(argv[1], &coapDestinationIp);
+        error = otIp6AddressFromString(aArgs[1], &coapDestinationIp);
     }
     else
     {
@@ -245,30 +267,30 @@
     }
 
     // CoAP-URI
-    if (argc > (2 - indexShifter))
+    if (aArgsLength > (2 - indexShifter))
     {
-        strncpy(coapUri, argv[2 - indexShifter], sizeof(coapUri) - 1);
+        strncpy(coapUri, aArgs[2 - indexShifter], sizeof(coapUri) - 1);
     }
 
     // CoAP-Type
-    if (argc > (3 - indexShifter))
+    if (aArgsLength > (3 - indexShifter))
     {
-        if (strcmp(argv[3 - indexShifter], "con") == 0)
+        if (strcmp(aArgs[3 - indexShifter], "con") == 0)
         {
             coapType = OT_COAP_TYPE_CONFIRMABLE;
         }
     }
 
-    message = otCoapNewMessage(mInterpreter.mInstance, NULL);
-    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+    message = otCoapNewMessage(mInterpreter.mInstance, nullptr);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
     otCoapMessageInit(message, coapType, coapCode);
     otCoapMessageGenerateToken(message, ot::Coap::Message::kDefaultTokenLength);
     SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, coapUri));
 
-    if (argc > (4 - indexShifter))
+    if (aArgsLength > (4 - indexShifter))
     {
-        payloadLength = static_cast<uint16_t>(strlen(argv[4 - indexShifter]));
+        payloadLength = static_cast<uint16_t>(strlen(aArgs[4 - indexShifter]));
 
         if (payloadLength > 0)
         {
@@ -279,7 +301,7 @@
     // add payload
     if (payloadLength > 0)
     {
-        SuccessOrExit(error = otMessageAppend(message, argv[4 - indexShifter], payloadLength));
+        SuccessOrExit(error = otMessageAppend(message, aArgs[4 - indexShifter], payloadLength));
     }
 
     memset(&messageInfo, 0, sizeof(messageInfo));
@@ -292,12 +314,12 @@
     }
     else
     {
-        error = otCoapSecureSendRequest(mInterpreter.mInstance, message, NULL, NULL);
+        error = otCoapSecureSendRequest(mInterpreter.mInstance, message, nullptr, nullptr);
     }
 
 exit:
 
-    if ((error != OT_ERROR_NONE) && (message != NULL))
+    if ((error != OT_ERROR_NONE) && (message != nullptr))
     {
         otMessageFree(message);
     }
@@ -305,24 +327,24 @@
     return error;
 }
 
-otError CoapSecure::ProcessConnect(int argc, char *argv[])
+otError CoapSecure::ProcessConnect(uint8_t aArgsLength, char *aArgs[])
 {
     otError    error;
     otSockAddr sockaddr;
 
-    VerifyOrExit(argc > 1, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 1, error = OT_ERROR_INVALID_ARGS);
 
     // Destination IPv6 address
     memset(&sockaddr, 0, sizeof(sockaddr));
-    SuccessOrExit(error = otIp6AddressFromString(argv[1], &sockaddr.mAddress));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[1], &sockaddr.mAddress));
     sockaddr.mPort = OT_DEFAULT_COAP_SECURE_PORT;
 
     // check for port specification
-    if (argc > 2)
+    if (aArgsLength > 2)
     {
         long value;
 
-        error = Interpreter::ParseLong(argv[2], value);
+        error = Interpreter::ParseLong(aArgs[2], value);
         SuccessOrExit(error);
         sockaddr.mPort = static_cast<uint16_t>(value);
     }
@@ -333,10 +355,10 @@
     return error;
 }
 
-otError CoapSecure::ProcessDisconnect(int argc, char *argv[])
+otError CoapSecure::ProcessDisconnect(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otCoapSecureDisconnect(mInterpreter.mInstance);
 
@@ -344,22 +366,22 @@
 }
 
 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
-otError CoapSecure::ProcessPsk(int argc, char *argv[])
+otError CoapSecure::ProcessPsk(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     size_t  length;
 
-    VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
 
-    length = strlen(argv[1]);
+    length = strlen(aArgs[1]);
     VerifyOrExit(length <= sizeof(mPsk), error = OT_ERROR_INVALID_ARGS);
     mPskLength = static_cast<uint8_t>(length);
-    memcpy(mPsk, argv[1], mPskLength);
+    memcpy(mPsk, aArgs[1], mPskLength);
 
-    length = strlen(argv[2]);
+    length = strlen(aArgs[2]);
     VerifyOrExit(length <= sizeof(mPskId), error = OT_ERROR_INVALID_ARGS);
     mPskIdLength = static_cast<uint8_t>(length);
-    memcpy(mPskId, argv[2], mPskIdLength);
+    memcpy(mPskId, aArgs[2], mPskIdLength);
 
     otCoapSecureSetPsk(mInterpreter.mInstance, mPsk, mPskLength, mPskId, mPskIdLength);
     mUseCertificate = false;
@@ -370,10 +392,10 @@
 #endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
 
 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-otError CoapSecure::ProcessX509(int argc, char *argv[])
+otError CoapSecure::ProcessX509(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otCoapSecureSetCertificate(mInterpreter.mInstance, (const uint8_t *)OT_CLI_COAPS_X509_CERT,
                                sizeof(OT_CLI_COAPS_X509_CERT), (const uint8_t *)OT_CLI_COAPS_PRIV_KEY,
@@ -387,22 +409,22 @@
 }
 #endif
 
-otError CoapSecure::Process(int argc, char *argv[])
+otError CoapSecure::Process(uint8_t aArgsLength, char *aArgs[])
 {
-    otError error = OT_ERROR_PARSE;
+    otError error = OT_ERROR_INVALID_COMMAND;
 
-    if (argc < 1)
+    if (aArgsLength < 1)
     {
-        ProcessHelp(0, NULL);
+        IgnoreError(ProcessHelp(0, nullptr));
         error = OT_ERROR_INVALID_ARGS;
     }
     else
     {
         for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
         {
-            if (strcmp(argv[0], sCommands[i].mName) == 0)
+            if (strcmp(aArgs[0], sCommands[i].mName) == 0)
             {
-                error = (this->*sCommands[i].mCommand)(argc, argv);
+                error = (this->*sCommands[i].mCommand)(aArgsLength, aArgs);
                 break;
             }
         }
@@ -447,10 +469,9 @@
 
 void CoapSecure::HandleRequest(otMessage *aMessage, const otMessageInfo *aMessageInfo)
 {
-    otError    error             = OT_ERROR_NONE;
-    otMessage *responseMessage   = NULL;
-    otCoapCode responseCode      = OT_COAP_CODE_EMPTY;
-    char       responseContent[] = "helloWorld";
+    otError    error           = OT_ERROR_NONE;
+    otMessage *responseMessage = nullptr;
+    otCoapCode responseCode    = OT_COAP_CODE_EMPTY;
 
     mInterpreter.mServer->OutputFormat("coaps request from ");
     mInterpreter.OutputIp6Address(aMessageInfo->mPeerAddr);
@@ -493,8 +514,8 @@
             responseCode = OT_COAP_CODE_VALID;
         }
 
-        responseMessage = otCoapNewMessage(mInterpreter.mInstance, NULL);
-        VerifyOrExit(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
+        responseMessage = otCoapNewMessage(mInterpreter.mInstance, nullptr);
+        VerifyOrExit(responseMessage != nullptr, error = OT_ERROR_NO_BUFS);
 
         SuccessOrExit(
             error = otCoapMessageInitResponse(responseMessage, aMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode));
@@ -506,7 +527,8 @@
 
         if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
         {
-            SuccessOrExit(error = otMessageAppend(responseMessage, &responseContent, sizeof(responseContent)));
+            SuccessOrExit(error = otMessageAppend(responseMessage, &mResourceContent,
+                                                  static_cast<uint16_t>(strlen(mResourceContent))));
         }
 
         SuccessOrExit(error = otCoapSecureSendResponse(mInterpreter.mInstance, responseMessage, aMessageInfo));
@@ -516,7 +538,7 @@
 
     if (error != OT_ERROR_NONE)
     {
-        if (responseMessage != NULL)
+        if (responseMessage != nullptr)
         {
             mInterpreter.mServer->OutputFormat("coaps send response error %d: %s\r\n", error,
                                                otThreadErrorToString(error));
@@ -561,13 +583,13 @@
 void CoapSecure::DefaultHandler(otMessage *aMessage, const otMessageInfo *aMessageInfo)
 {
     otError    error           = OT_ERROR_NONE;
-    otMessage *responseMessage = NULL;
+    otMessage *responseMessage = nullptr;
 
     if ((otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE) ||
         (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET))
     {
-        responseMessage = otCoapNewMessage(mInterpreter.mInstance, NULL);
-        VerifyOrExit(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
+        responseMessage = otCoapNewMessage(mInterpreter.mInstance, nullptr);
+        VerifyOrExit(responseMessage != nullptr, error = OT_ERROR_NO_BUFS);
 
         SuccessOrExit(error = otCoapMessageInitResponse(responseMessage, aMessage, OT_COAP_TYPE_NON_CONFIRMABLE,
                                                         OT_COAP_CODE_NOT_FOUND));
@@ -576,7 +598,7 @@
     }
 
 exit:
-    if (error != OT_ERROR_NONE && responseMessage != NULL)
+    if (error != OT_ERROR_NONE && responseMessage != nullptr)
     {
         otMessageFree(responseMessage);
     }
diff --git a/src/cli/cli_coap_secure.hpp b/src/cli/cli_coap_secure.hpp
index 6d6b414..e81e24f 100644
--- a/src/cli/cli_coap_secure.hpp
+++ b/src/cli/cli_coap_secure.hpp
@@ -68,11 +68,11 @@
     /**
      * This method interprets a list of CLI arguments.
      *
-     * @param[in]  argc  The number of elements in argv.
-     * @param[in]  argv  A pointer to an array of command line arguments.
+     * @param[in]  aArgsLength  The number of elements in @p aArgs.
+     * @param[in]  aArgs        An array of command line arguments.
      *
      */
-    otError Process(int argc, char *argv[]);
+    otError Process(uint8_t aArgsLength, char *aArgs[]);
 
 private:
     enum
@@ -86,20 +86,21 @@
     struct Command
     {
         const char *mName;
-        otError (CoapSecure::*mCommand)(int argc, char *argv[]);
+        otError (CoapSecure::*mCommand)(uint8_t aArgsLength, char *aArgs[]);
     };
 
     void PrintPayload(otMessage *aMessage) const;
 
-    otError ProcessHelp(int argc, char *argv[]);
-    otError ProcessConnect(int argc, char *argv[]);
-    otError ProcessDisconnect(int argc, char *argv[]);
-    otError ProcessPsk(int argc, char *argv[]);
-    otError ProcessRequest(int argc, char *argv[]);
-    otError ProcessResource(int argc, char *argv[]);
-    otError ProcessStart(int argc, char *argv[]);
-    otError ProcessStop(int argc, char *argv[]);
-    otError ProcessX509(int argc, char *argv[]);
+    otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessConnect(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessDisconnect(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessPsk(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessRequest(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessResource(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessSet(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessStart(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessStop(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessX509(uint8_t aArgsLength, char *aArgs[]);
 
     void Stop(void);
 
@@ -122,6 +123,7 @@
 
     otCoapResource mResource;
     char           mUriPath[kMaxUriLength];
+    char           mResourceContent[kMaxBufferSize];
 
     bool    mShutdownFlag;
     bool    mUseCertificate;
diff --git a/src/cli/cli_commissioner.cpp b/src/cli/cli_commissioner.cpp
index 82e4895..7aec85a 100644
--- a/src/cli/cli_commissioner.cpp
+++ b/src/cli/cli_commissioner.cpp
@@ -50,10 +50,10 @@
     {"stop", &Commissioner::ProcessStop},
 };
 
-otError Commissioner::ProcessHelp(int argc, char *argv[])
+otError Commissioner::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
@@ -63,7 +63,7 @@
     return OT_ERROR_NONE;
 }
 
-otError Commissioner::ProcessAnnounce(int argc, char *argv[])
+otError Commissioner::ProcessAnnounce(uint8_t aArgsLength, char *aArgs[])
 {
     otError      error;
     long         mask;
@@ -71,12 +71,12 @@
     long         period;
     otIp6Address address;
 
-    VerifyOrExit(argc > 4, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 4, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = Interpreter::ParseLong(argv[1], mask));
-    SuccessOrExit(error = Interpreter::ParseLong(argv[2], count));
-    SuccessOrExit(error = Interpreter::ParseLong(argv[3], period));
-    SuccessOrExit(error = otIp6AddressFromString(argv[4], &address));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[1], mask));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[2], count));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[3], period));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[4], &address));
 
     SuccessOrExit(error = otCommissionerAnnounceBegin(mInterpreter.mInstance, static_cast<uint32_t>(mask),
                                                       static_cast<uint8_t>(count), static_cast<uint16_t>(period),
@@ -86,7 +86,7 @@
     return error;
 }
 
-otError Commissioner::ProcessEnergy(int argc, char *argv[])
+otError Commissioner::ProcessEnergy(uint8_t aArgsLength, char *aArgs[])
 {
     otError      error;
     long         mask;
@@ -95,13 +95,13 @@
     long         scanDuration;
     otIp6Address address;
 
-    VerifyOrExit(argc > 5, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 5, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = Interpreter::ParseLong(argv[1], mask));
-    SuccessOrExit(error = Interpreter::ParseLong(argv[2], count));
-    SuccessOrExit(error = Interpreter::ParseLong(argv[3], period));
-    SuccessOrExit(error = Interpreter::ParseLong(argv[4], scanDuration));
-    SuccessOrExit(error = otIp6AddressFromString(argv[5], &address));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[1], mask));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[2], count));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[3], period));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[4], scanDuration));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[5], &address));
 
     SuccessOrExit(error = otCommissionerEnergyScan(mInterpreter.mInstance, static_cast<uint32_t>(mask),
                                                    static_cast<uint8_t>(count), static_cast<uint16_t>(period),
@@ -112,39 +112,40 @@
     return error;
 }
 
-otError Commissioner::ProcessJoiner(int argc, char *argv[])
+otError Commissioner::ProcessJoiner(uint8_t aArgsLength, char *aArgs[])
 {
     otError             error;
     otExtAddress        addr;
     const otExtAddress *addrPtr;
 
-    VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[2], "*") == 0)
+    if (strcmp(aArgs[2], "*") == 0)
     {
-        addrPtr = NULL;
+        addrPtr = nullptr;
     }
     else
     {
-        VerifyOrExit(Interpreter::Hex2Bin(argv[2], addr.m8, sizeof(addr)) == sizeof(addr), error = OT_ERROR_PARSE);
+        VerifyOrExit(Interpreter::Hex2Bin(aArgs[2], addr.m8, sizeof(addr)) == sizeof(addr),
+                     error = OT_ERROR_INVALID_ARGS);
         addrPtr = &addr;
     }
 
-    if (strcmp(argv[1], "add") == 0)
+    if (strcmp(aArgs[1], "add") == 0)
     {
-        VerifyOrExit(argc > 3, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(aArgsLength > 3, error = OT_ERROR_INVALID_ARGS);
         // Timeout parameter is optional - if not specified, use default value.
         unsigned long timeout = kDefaultJoinerTimeout;
 
-        if (argc > 4)
+        if (aArgsLength > 4)
         {
-            SuccessOrExit(error = Interpreter::ParseUnsignedLong(argv[4], timeout));
+            SuccessOrExit(error = Interpreter::ParseUnsignedLong(aArgs[4], timeout));
         }
 
         SuccessOrExit(
-            error = otCommissionerAddJoiner(mInterpreter.mInstance, addrPtr, argv[3], static_cast<uint32_t>(timeout)));
+            error = otCommissionerAddJoiner(mInterpreter.mInstance, addrPtr, aArgs[3], static_cast<uint32_t>(timeout)));
     }
-    else if (strcmp(argv[1], "remove") == 0)
+    else if (strcmp(aArgs[1], "remove") == 0)
     {
         SuccessOrExit(error = otCommissionerRemoveJoiner(mInterpreter.mInstance, addrPtr));
     }
@@ -157,41 +158,41 @@
     return error;
 }
 
-otError Commissioner::ProcessMgmtGet(int argc, char *argv[])
+otError Commissioner::ProcessMgmtGet(uint8_t aArgsLength, char *aArgs[])
 {
     otError error;
     uint8_t tlvs[32];
     long    value;
     int     length = 0;
 
-    for (uint8_t index = 1; index < argc; index++)
+    for (uint8_t index = 1; index < aArgsLength; index++)
     {
         VerifyOrExit(static_cast<size_t>(length) < sizeof(tlvs), error = OT_ERROR_NO_BUFS);
 
-        if (strcmp(argv[index], "locator") == 0)
+        if (strcmp(aArgs[index], "locator") == 0)
         {
             tlvs[length++] = OT_MESHCOP_TLV_BORDER_AGENT_RLOC;
         }
-        else if (strcmp(argv[index], "sessionid") == 0)
+        else if (strcmp(aArgs[index], "sessionid") == 0)
         {
             tlvs[length++] = OT_MESHCOP_TLV_COMM_SESSION_ID;
         }
-        else if (strcmp(argv[index], "steeringdata") == 0)
+        else if (strcmp(aArgs[index], "steeringdata") == 0)
         {
             tlvs[length++] = OT_MESHCOP_TLV_STEERING_DATA;
         }
-        else if (strcmp(argv[index], "joinerudpport") == 0)
+        else if (strcmp(aArgs[index], "joinerudpport") == 0)
         {
             tlvs[length++] = OT_MESHCOP_TLV_JOINER_UDP_PORT;
         }
-        else if (strcmp(argv[index], "binary") == 0)
+        else if (strcmp(aArgs[index], "binary") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
-            value = static_cast<long>(strlen(argv[index]) + 1) / 2;
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
+            value = static_cast<long>(strlen(aArgs[index]) + 1) / 2;
             VerifyOrExit(static_cast<size_t>(value) <= (sizeof(tlvs) - static_cast<size_t>(length)),
                          error = OT_ERROR_NO_BUFS);
-            VerifyOrExit(Interpreter::Hex2Bin(argv[index], tlvs + length, static_cast<uint16_t>(value)) >= 0,
-                         error = OT_ERROR_PARSE);
+            VerifyOrExit(Interpreter::Hex2Bin(aArgs[index], tlvs + length, static_cast<uint16_t>(value)) == value,
+                         error = OT_ERROR_INVALID_ARGS);
             length += value;
         }
         else
@@ -206,7 +207,7 @@
     return error;
 }
 
-otError Commissioner::ProcessMgmtSet(int argc, char *argv[])
+otError Commissioner::ProcessMgmtSet(uint8_t aArgsLength, char *aArgs[])
 {
     otError                error;
     otCommissioningDataset dataset;
@@ -214,54 +215,54 @@
     long                   value;
     int                    length = 0;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
     memset(&dataset, 0, sizeof(dataset));
 
-    for (uint8_t index = 1; index < argc; index++)
+    for (uint8_t index = 1; index < aArgsLength; index++)
     {
         VerifyOrExit(static_cast<size_t>(length) < sizeof(tlvs), error = OT_ERROR_NO_BUFS);
 
-        if (strcmp(argv[index], "locator") == 0)
+        if (strcmp(aArgs[index], "locator") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mIsLocatorSet = true;
-            SuccessOrExit(error = Interpreter::Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::Interpreter::ParseLong(aArgs[index], value));
             dataset.mLocator = static_cast<uint16_t>(value);
         }
-        else if (strcmp(argv[index], "sessionid") == 0)
+        else if (strcmp(aArgs[index], "sessionid") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mIsSessionIdSet = true;
-            SuccessOrExit(error = Interpreter::Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::Interpreter::ParseLong(aArgs[index], value));
             dataset.mSessionId = static_cast<uint16_t>(value);
         }
-        else if (strcmp(argv[index], "steeringdata") == 0)
+        else if (strcmp(aArgs[index], "steeringdata") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mIsSteeringDataSet = true;
-            length                     = static_cast<int>((strlen(argv[index]) + 1) / 2);
+            length                     = static_cast<int>((strlen(aArgs[index]) + 1) / 2);
             VerifyOrExit(static_cast<size_t>(length) <= OT_STEERING_DATA_MAX_LENGTH, error = OT_ERROR_NO_BUFS);
-            VerifyOrExit(Interpreter::Hex2Bin(argv[index], dataset.mSteeringData.m8, static_cast<uint16_t>(length)) >=
-                             0,
-                         error = OT_ERROR_PARSE);
+            VerifyOrExit(Interpreter::Hex2Bin(aArgs[index], dataset.mSteeringData.m8, static_cast<uint16_t>(length)) ==
+                             length,
+                         error = OT_ERROR_INVALID_ARGS);
             dataset.mSteeringData.mLength = static_cast<uint8_t>(length);
             length                        = 0;
         }
-        else if (strcmp(argv[index], "joinerudpport") == 0)
+        else if (strcmp(aArgs[index], "joinerudpport") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mIsJoinerUdpPortSet = true;
-            SuccessOrExit(error = Interpreter::Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::Interpreter::ParseLong(aArgs[index], value));
             dataset.mJoinerUdpPort = static_cast<uint16_t>(value);
         }
-        else if (strcmp(argv[index], "binary") == 0)
+        else if (strcmp(aArgs[index], "binary") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
-            length = static_cast<int>((strlen(argv[index]) + 1) / 2);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
+            length = static_cast<int>((strlen(aArgs[index]) + 1) / 2);
             VerifyOrExit(static_cast<size_t>(length) <= sizeof(tlvs), error = OT_ERROR_NO_BUFS);
-            VerifyOrExit(Interpreter::Hex2Bin(argv[index], tlvs, static_cast<uint16_t>(length)) >= 0,
-                         error = OT_ERROR_PARSE);
+            VerifyOrExit(Interpreter::Hex2Bin(aArgs[index], tlvs, static_cast<uint16_t>(length)) == length,
+                         error = OT_ERROR_INVALID_ARGS);
         }
         else
         {
@@ -276,18 +277,18 @@
     return error;
 }
 
-otError Commissioner::ProcessPanId(int argc, char *argv[])
+otError Commissioner::ProcessPanId(uint8_t aArgsLength, char *aArgs[])
 {
     otError      error;
     long         panid;
     long         mask;
     otIp6Address address;
 
-    VerifyOrExit(argc > 3, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 3, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = Interpreter::ParseLong(argv[1], panid));
-    SuccessOrExit(error = Interpreter::ParseLong(argv[2], mask));
-    SuccessOrExit(error = otIp6AddressFromString(argv[3], &address));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[1], panid));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[2], mask));
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[3], &address));
 
     SuccessOrExit(error = otCommissionerPanIdQuery(mInterpreter.mInstance, static_cast<uint16_t>(panid),
                                                    static_cast<uint32_t>(mask), &address,
@@ -297,25 +298,25 @@
     return error;
 }
 
-otError Commissioner::ProcessProvisioningUrl(int argc, char *argv[])
+otError Commissioner::ProcessProvisioningUrl(uint8_t aArgsLength, char *aArgs[])
 {
-    return otCommissionerSetProvisioningUrl(mInterpreter.mInstance, (argc > 1) ? argv[1] : NULL);
+    return otCommissionerSetProvisioningUrl(mInterpreter.mInstance, (aArgsLength > 1) ? aArgs[1] : nullptr);
 }
 
-otError Commissioner::ProcessSessionId(int argc, char *argv[])
+otError Commissioner::ProcessSessionId(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     mInterpreter.mServer->OutputFormat("%d\r\n", otCommissionerGetSessionId(mInterpreter.mInstance));
 
     return OT_ERROR_NONE;
 }
 
-otError Commissioner::ProcessStart(int argc, char *argv[])
+otError Commissioner::ProcessStart(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     return otCommissionerStart(mInterpreter.mInstance, &Commissioner::HandleStateChanged,
                                &Commissioner::HandleJoinerEvent, this);
@@ -344,13 +345,20 @@
     }
 }
 
-void Commissioner::HandleJoinerEvent(otCommissionerJoinerEvent aEvent, const otExtAddress *aJoinerId, void *aContext)
+void Commissioner::HandleJoinerEvent(otCommissionerJoinerEvent aEvent,
+                                     const otJoinerInfo *      aJoinerInfo,
+                                     const otExtAddress *      aJoinerId,
+                                     void *                    aContext)
 {
-    static_cast<Commissioner *>(aContext)->HandleJoinerEvent(aEvent, aJoinerId);
+    static_cast<Commissioner *>(aContext)->HandleJoinerEvent(aEvent, aJoinerInfo, aJoinerId);
 }
 
-void Commissioner::HandleJoinerEvent(otCommissionerJoinerEvent aEvent, const otExtAddress *aJoinerId)
+void Commissioner::HandleJoinerEvent(otCommissionerJoinerEvent aEvent,
+                                     const otJoinerInfo *      aJoinerInfo,
+                                     const otExtAddress *      aJoinerId)
 {
+    OT_UNUSED_VARIABLE(aJoinerInfo);
+
     mInterpreter.mServer->OutputFormat("Commissioner: Joiner ");
 
     switch (aEvent)
@@ -372,34 +380,37 @@
         break;
     }
 
-    mInterpreter.OutputBytes(aJoinerId->m8, sizeof(*aJoinerId));
+    if (aJoinerId != nullptr)
+    {
+        mInterpreter.OutputBytes(aJoinerId->m8, sizeof(*aJoinerId));
+    }
 
     mInterpreter.mServer->OutputFormat("\r\n");
 }
 
-otError Commissioner::ProcessStop(int argc, char *argv[])
+otError Commissioner::ProcessStop(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     return otCommissionerStop(mInterpreter.mInstance);
 }
 
-otError Commissioner::Process(int argc, char *argv[])
+otError Commissioner::Process(uint8_t aArgsLength, char *aArgs[])
 {
-    otError error = OT_ERROR_INVALID_ARGS;
+    otError error = OT_ERROR_INVALID_COMMAND;
 
-    if (argc < 1)
+    if (aArgsLength < 1)
     {
-        ProcessHelp(0, NULL);
+        IgnoreError(ProcessHelp(0, nullptr));
     }
     else
     {
         for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
         {
-            if (strcmp(argv[0], sCommands[i].mName) == 0)
+            if (strcmp(aArgs[0], sCommands[i].mName) == 0)
             {
-                error = (this->*sCommands[i].mCommand)(argc, argv);
+                error = (this->*sCommands[i].mCommand)(aArgsLength, aArgs);
                 break;
             }
         }
diff --git a/src/cli/cli_commissioner.hpp b/src/cli/cli_commissioner.hpp
index ae2a5d6..0b5b071 100644
--- a/src/cli/cli_commissioner.hpp
+++ b/src/cli/cli_commissioner.hpp
@@ -66,11 +66,11 @@
     /**
      * This method interprets a list of CLI arguments.
      *
-     * @param[in]  argc  The number of elements in argv.
-     * @param[in]  argv  A pointer to an array of command line arguments.
+     * @param[in]  aArgsLength  The number of elements in @p aArgs.
+     * @param[in]  aArgs        An array of command line arguments.
      *
      */
-    otError Process(int argc, char *argv[]);
+    otError Process(uint8_t aArgsLength, char *aArgs[]);
 
 private:
     enum
@@ -81,28 +81,31 @@
     struct Command
     {
         const char *mName;
-        otError (Commissioner::*mCommand)(int argc, char *argv[]);
+        otError (Commissioner::*mCommand)(uint8_t aArgsLength, char *aArgs[]);
     };
 
-    otError ProcessHelp(int argc, char *argv[]);
-    otError ProcessAnnounce(int argc, char *argv[]);
-    otError ProcessEnergy(int argc, char *argv[]);
-    otError ProcessJoiner(int argc, char *argv[]);
-    otError ProcessMgmtGet(int argc, char *argv[]);
-    otError ProcessMgmtSet(int argc, char *argv[]);
-    otError ProcessPanId(int argc, char *argv[]);
-    otError ProcessProvisioningUrl(int argc, char *argv[]);
-    otError ProcessSessionId(int argc, char *argv[]);
-    otError ProcessStart(int argc, char *argv[]);
-    otError ProcessStop(int argc, char *argv[]);
+    otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessAnnounce(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessEnergy(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessJoiner(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMgmtGet(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMgmtSet(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessPanId(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessProvisioningUrl(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessSessionId(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessStart(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessStop(uint8_t aArgsLength, char *aArgs[]);
 
     static void HandleStateChanged(otCommissionerState aState, void *aContext);
     void        HandleStateChanged(otCommissionerState aState);
 
     static void HandleJoinerEvent(otCommissionerJoinerEvent aJoinerEvent,
+                                  const otJoinerInfo *      aJoinerInfo,
                                   const otExtAddress *      aJoinerId,
                                   void *                    aContext);
-    void        HandleJoinerEvent(otCommissionerJoinerEvent aJoinerEvent, const otExtAddress *aJoinerId);
+    void        HandleJoinerEvent(otCommissionerJoinerEvent aJoinerEvent,
+                                  const otJoinerInfo *      aJoinerInfo,
+                                  const otExtAddress *      aJoinerId);
 
     static void HandleEnergyReport(uint32_t       aChannelMask,
                                    const uint8_t *aEnergyList,
diff --git a/src/cli/cli_console.cpp b/src/cli/cli_console.cpp
index e2da74a..97fdcbd 100644
--- a/src/cli/cli_console.cpp
+++ b/src/cli/cli_console.cpp
@@ -62,8 +62,8 @@
 
 Console::Console(Instance *aInstance)
     : Server(aInstance)
-    , mCallback(NULL)
-    , mContext(NULL)
+    , mCallback(nullptr)
+    , mContext(nullptr)
 {
 }
 
diff --git a/src/cli/cli_dataset.cpp b/src/cli/cli_dataset.cpp
index 36bf134..2d4fed7 100644
--- a/src/cli/cli_dataset.cpp
+++ b/src/cli/cli_dataset.cpp
@@ -66,6 +66,7 @@
     {"pendingtimestamp", &Dataset::ProcessPendingTimestamp},
     {"pskc", &Dataset::ProcessPskc},
     {"securitypolicy", &Dataset::ProcessSecurityPolicy},
+    {"set", &Dataset::ProcessSet},
 };
 
 otOperationalDataset Dataset::sDataset;
@@ -182,20 +183,20 @@
     return OT_ERROR_NONE;
 }
 
-otError Dataset::Process(int argc, char *argv[])
+otError Dataset::Process(uint8_t aArgsLength, char *aArgs[])
 {
-    otError error = OT_ERROR_PARSE;
+    otError error = OT_ERROR_INVALID_COMMAND;
 
-    if (argc == 0)
+    if (aArgsLength == 0)
     {
         ExitNow(error = Print(sDataset));
     }
 
-    for (unsigned int i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
-        if (strcmp(argv[0], sCommands[i].mName) == 0)
+        if (strcmp(aArgs[0], sCommands[i].mName) == 0)
         {
-            error = (this->*sCommands[i].mCommand)(argc - 1, argv + 1);
+            error = (this->*sCommands[i].mCommand)(aArgsLength - 1, aArgs + 1);
             break;
         }
     }
@@ -204,12 +205,12 @@
     return error;
 }
 
-otError Dataset::ProcessHelp(int argc, char *argv[])
+otError Dataset::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
-    for (unsigned int i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
         mInterpreter.mServer->OutputFormat("%s\r\n", sCommands[i].mName);
     }
@@ -217,22 +218,22 @@
     return OT_ERROR_NONE;
 }
 
-otError Dataset::ProcessInit(int argc, char *argv[])
+otError Dataset::ProcessInit(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "active") == 0)
+    if (strcmp(aArgs[0], "active") == 0)
     {
         SuccessOrExit(error = otDatasetGetActive(mInterpreter.mInstance, &sDataset));
     }
-    else if (strcmp(argv[0], "pending") == 0)
+    else if (strcmp(aArgs[0], "pending") == 0)
     {
         SuccessOrExit(error = otDatasetGetPending(mInterpreter.mInstance, &sDataset));
     }
 #if OPENTHREAD_FTD
-    else if (strcmp(argv[0], "new") == 0)
+    else if (strcmp(aArgs[0], "new") == 0)
     {
         SuccessOrExit(error = otDatasetCreateNewNetwork(mInterpreter.mInstance, &sDataset));
     }
@@ -246,43 +247,73 @@
     return error;
 }
 
-otError Dataset::ProcessActive(int argc, char *argv[])
+otError Dataset::ProcessActive(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    otError error;
 
-    otOperationalDataset dataset;
-    otError              error;
+    if (aArgsLength == 0)
+    {
+        otOperationalDataset dataset;
 
-    SuccessOrExit(error = otDatasetGetActive(mInterpreter.mInstance, &dataset));
-    error = Print(dataset);
+        SuccessOrExit(error = otDatasetGetActive(mInterpreter.mInstance, &dataset));
+        error = Print(dataset);
+    }
+    else if ((aArgsLength == 1) && (strcmp(aArgs[0], "binary") == 0))
+    {
+        otOperationalDatasetTlvs dataset;
+
+        VerifyOrExit(strlen(aArgs[0]) <= OT_OPERATIONAL_DATASET_MAX_LENGTH * 2, error = OT_ERROR_NO_BUFS);
+
+        SuccessOrExit(error = otDatasetGetActiveTlvs(mInterpreter.mInstance, &dataset));
+        mInterpreter.OutputBytes(dataset.mTlvs, dataset.mLength);
+        mInterpreter.mServer->OutputFormat("\r\n");
+    }
+    else
+    {
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
+    }
 
 exit:
     return error;
 }
 
-otError Dataset::ProcessPending(int argc, char *argv[])
+otError Dataset::ProcessPending(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    otError error;
 
-    otOperationalDataset dataset;
-    otError              error;
+    if (aArgsLength == 0)
+    {
+        otOperationalDataset dataset;
 
-    SuccessOrExit(error = otDatasetGetPending(mInterpreter.mInstance, &dataset));
-    error = Print(dataset);
+        SuccessOrExit(error = otDatasetGetPending(mInterpreter.mInstance, &dataset));
+        error = Print(dataset);
+    }
+    else if ((aArgsLength == 1) && (strcmp(aArgs[0], "binary") == 0))
+    {
+        otOperationalDatasetTlvs dataset;
+
+        VerifyOrExit(strlen(aArgs[0]) <= OT_OPERATIONAL_DATASET_MAX_LENGTH * 2, error = OT_ERROR_NO_BUFS);
+
+        SuccessOrExit(error = otDatasetGetPendingTlvs(mInterpreter.mInstance, &dataset));
+        mInterpreter.OutputBytes(dataset.mTlvs, dataset.mLength);
+        mInterpreter.mServer->OutputFormat("\r\n");
+    }
+    else
+    {
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
+    }
 
 exit:
     return error;
 }
 
-otError Dataset::ProcessActiveTimestamp(int argc, char *argv[])
+otError Dataset::ProcessActiveTimestamp(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    SuccessOrExit(error = Interpreter::ParseLong(argv[0], value));
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[0], value));
     sDataset.mActiveTimestamp                      = static_cast<uint64_t>(value);
     sDataset.mComponents.mIsActiveTimestampPresent = true;
 
@@ -290,13 +321,13 @@
     return error;
 }
 
-otError Dataset::ProcessChannel(int argc, char *argv[])
+otError Dataset::ProcessChannel(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    SuccessOrExit(error = Interpreter::ParseLong(argv[0], value));
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[0], value));
     sDataset.mChannel                      = static_cast<uint16_t>(value);
     sDataset.mComponents.mIsChannelPresent = true;
 
@@ -304,13 +335,13 @@
     return error;
 }
 
-otError Dataset::ProcessChannelMask(int argc, char *argv[])
+otError Dataset::ProcessChannelMask(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    SuccessOrExit(error = Interpreter::ParseLong(argv[0], value));
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[0], value));
     sDataset.mChannelMask                      = static_cast<uint32_t>(value);
     sDataset.mComponents.mIsChannelMaskPresent = true;
 
@@ -318,26 +349,26 @@
     return error;
 }
 
-otError Dataset::ProcessClear(int argc, char *argv[])
+otError Dataset::ProcessClear(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     memset(&sDataset, 0, sizeof(sDataset));
     return OT_ERROR_NONE;
 }
 
-otError Dataset::ProcessCommit(int argc, char *argv[])
+otError Dataset::ProcessCommit(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(argv[0], "active") == 0)
+    if (strcmp(aArgs[0], "active") == 0)
     {
         SuccessOrExit(error = otDatasetSetActive(mInterpreter.mInstance, &sDataset));
     }
-    else if (strcmp(argv[0], "pending") == 0)
+    else if (strcmp(aArgs[0], "pending") == 0)
     {
         SuccessOrExit(error = otDatasetSetPending(mInterpreter.mInstance, &sDataset));
     }
@@ -350,13 +381,13 @@
     return error;
 }
 
-otError Dataset::ProcessDelay(int argc, char *argv[])
+otError Dataset::ProcessDelay(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    SuccessOrExit(error = Interpreter::ParseLong(argv[0], value));
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[0], value));
     sDataset.mDelay                      = static_cast<uint32_t>(value);
     sDataset.mComponents.mIsDelayPresent = true;
 
@@ -364,13 +395,14 @@
     return error;
 }
 
-otError Dataset::ProcessExtPanId(int argc, char *argv[])
+otError Dataset::ProcessExtPanId(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     uint8_t extPanId[OT_EXT_PAN_ID_SIZE];
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit(Interpreter::Hex2Bin(argv[0], extPanId, sizeof(extPanId)) >= 0, error = OT_ERROR_PARSE);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(Interpreter::Hex2Bin(aArgs[0], extPanId, sizeof(extPanId)) == sizeof(extPanId),
+                 error = OT_ERROR_INVALID_ARGS);
 
     memcpy(sDataset.mExtendedPanId.m8, extPanId, sizeof(sDataset.mExtendedPanId));
     sDataset.mComponents.mIsExtendedPanIdPresent = true;
@@ -379,13 +411,14 @@
     return error;
 }
 
-otError Dataset::ProcessMasterKey(int argc, char *argv[])
+otError Dataset::ProcessMasterKey(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     uint8_t key[OT_MASTER_KEY_SIZE];
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit((Interpreter::Hex2Bin(argv[0], key, sizeof(key))) == OT_MASTER_KEY_SIZE, error = OT_ERROR_PARSE);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit((Interpreter::Hex2Bin(aArgs[0], key, sizeof(key))) == OT_MASTER_KEY_SIZE,
+                 error = OT_ERROR_INVALID_ARGS);
 
     memcpy(sDataset.mMasterKey.m8, key, sizeof(sDataset.mMasterKey));
     sDataset.mComponents.mIsMasterKeyPresent = true;
@@ -394,13 +427,13 @@
     return error;
 }
 
-otError Dataset::ProcessMeshLocalPrefix(int argc, char *argv[])
+otError Dataset::ProcessMeshLocalPrefix(uint8_t aArgsLength, char *aArgs[])
 {
     otError      error = OT_ERROR_NONE;
     otIp6Address prefix;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    SuccessOrExit(error = otIp6AddressFromString(argv[0], &prefix));
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    SuccessOrExit(error = otIp6AddressFromString(aArgs[0], &prefix));
 
     memcpy(sDataset.mMeshLocalPrefix.m8, prefix.mFields.m8, sizeof(sDataset.mMeshLocalPrefix.m8));
     sDataset.mComponents.mIsMeshLocalPrefixPresent = true;
@@ -409,29 +442,29 @@
     return error;
 }
 
-otError Dataset::ProcessNetworkName(int argc, char *argv[])
+otError Dataset::ProcessNetworkName(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     size_t  length;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit((length = strlen(argv[0])) <= OT_NETWORK_NAME_MAX_SIZE, error = OT_ERROR_PARSE);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit((length = strlen(aArgs[0])) <= OT_NETWORK_NAME_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
 
     memset(&sDataset.mNetworkName, 0, sizeof(sDataset.mNetworkName));
-    memcpy(sDataset.mNetworkName.m8, argv[0], length);
+    memcpy(sDataset.mNetworkName.m8, aArgs[0], length);
     sDataset.mComponents.mIsNetworkNamePresent = true;
 
 exit:
     return error;
 }
 
-otError Dataset::ProcessPanId(int argc, char *argv[])
+otError Dataset::ProcessPanId(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    SuccessOrExit(error = Interpreter::ParseLong(argv[0], value));
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[0], value));
     sDataset.mPanId                      = static_cast<otPanId>(value);
     sDataset.mComponents.mIsPanIdPresent = true;
 
@@ -439,13 +472,13 @@
     return error;
 }
 
-otError Dataset::ProcessPendingTimestamp(int argc, char *argv[])
+otError Dataset::ProcessPendingTimestamp(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    SuccessOrExit(error = Interpreter::ParseLong(argv[0], value));
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[0], value));
     sDataset.mPendingTimestamp                      = static_cast<uint64_t>(value);
     sDataset.mComponents.mIsPendingTimestampPresent = true;
 
@@ -453,7 +486,7 @@
     return error;
 }
 
-otError Dataset::ProcessMgmtSetCommand(int argc, char *argv[])
+otError Dataset::ProcessMgmtSetCommand(uint8_t aArgsLength, char *aArgs[])
 {
     otError              error = OT_ERROR_NONE;
     otOperationalDataset dataset;
@@ -462,95 +495,95 @@
     int                  length = 0;
     otIp6Address         prefix;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
     memset(&dataset, 0, sizeof(dataset));
 
-    for (uint8_t index = 1; index < argc; index++)
+    for (uint8_t index = 1; index < aArgsLength; index++)
     {
-        if (strcmp(argv[index], "activetimestamp") == 0)
+        if (strcmp(aArgs[index], "activetimestamp") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsActiveTimestampPresent = true;
-            SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::ParseLong(aArgs[index], value));
             dataset.mActiveTimestamp = static_cast<uint64_t>(value);
         }
-        else if (strcmp(argv[index], "pendingtimestamp") == 0)
+        else if (strcmp(aArgs[index], "pendingtimestamp") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsPendingTimestampPresent = true;
-            SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::ParseLong(aArgs[index], value));
             dataset.mPendingTimestamp = static_cast<uint64_t>(value);
         }
-        else if (strcmp(argv[index], "masterkey") == 0)
+        else if (strcmp(aArgs[index], "masterkey") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsMasterKeyPresent = true;
-            VerifyOrExit((length = Interpreter::Hex2Bin(argv[index], dataset.mMasterKey.m8,
+            VerifyOrExit((length = Interpreter::Hex2Bin(aArgs[index], dataset.mMasterKey.m8,
                                                         sizeof(dataset.mMasterKey.m8))) == OT_MASTER_KEY_SIZE,
-                         error = OT_ERROR_PARSE);
+                         error = OT_ERROR_INVALID_ARGS);
             length = 0;
         }
-        else if (strcmp(argv[index], "networkname") == 0)
+        else if (strcmp(aArgs[index], "networkname") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsNetworkNamePresent = true;
-            VerifyOrExit((length = static_cast<int>(strlen(argv[index]))) <= OT_NETWORK_NAME_MAX_SIZE,
-                         error = OT_ERROR_PARSE);
+            VerifyOrExit((length = static_cast<int>(strlen(aArgs[index]))) <= OT_NETWORK_NAME_MAX_SIZE,
+                         error = OT_ERROR_INVALID_ARGS);
             memset(&dataset.mNetworkName, 0, sizeof(sDataset.mNetworkName));
-            memcpy(dataset.mNetworkName.m8, argv[index], static_cast<size_t>(length));
+            memcpy(dataset.mNetworkName.m8, aArgs[index], static_cast<size_t>(length));
             length = 0;
         }
-        else if (strcmp(argv[index], "extpanid") == 0)
+        else if (strcmp(aArgs[index], "extpanid") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsExtendedPanIdPresent = true;
-            VerifyOrExit(
-                Interpreter::Hex2Bin(argv[index], dataset.mExtendedPanId.m8, sizeof(dataset.mExtendedPanId.m8)) >= 0,
-                error = OT_ERROR_PARSE);
+            VerifyOrExit(Interpreter::Hex2Bin(aArgs[index], dataset.mExtendedPanId.m8,
+                                              sizeof(dataset.mExtendedPanId.m8)) == sizeof(dataset.mExtendedPanId.m8),
+                         error = OT_ERROR_INVALID_ARGS);
         }
-        else if (strcmp(argv[index], "localprefix") == 0)
+        else if (strcmp(aArgs[index], "localprefix") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsMeshLocalPrefixPresent = true;
-            SuccessOrExit(error = otIp6AddressFromString(argv[index], &prefix));
+            SuccessOrExit(error = otIp6AddressFromString(aArgs[index], &prefix));
             memcpy(dataset.mMeshLocalPrefix.m8, prefix.mFields.m8, sizeof(dataset.mMeshLocalPrefix.m8));
         }
-        else if (strcmp(argv[index], "delaytimer") == 0)
+        else if (strcmp(aArgs[index], "delaytimer") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsDelayPresent = true;
-            SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::ParseLong(aArgs[index], value));
             dataset.mDelay = static_cast<uint32_t>(value);
         }
-        else if (strcmp(argv[index], "panid") == 0)
+        else if (strcmp(aArgs[index], "panid") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsPanIdPresent = true;
-            SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::ParseLong(aArgs[index], value));
             dataset.mPanId = static_cast<otPanId>(value);
         }
-        else if (strcmp(argv[index], "channel") == 0)
+        else if (strcmp(aArgs[index], "channel") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsChannelPresent = true;
-            SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::ParseLong(aArgs[index], value));
             dataset.mChannel = static_cast<uint16_t>(value);
         }
-        else if (strcmp(argv[index], "channelmask") == 0)
+        else if (strcmp(aArgs[index], "channelmask") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
             dataset.mComponents.mIsChannelMaskPresent = true;
-            SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
+            SuccessOrExit(error = Interpreter::ParseLong(aArgs[index], value));
             dataset.mChannelMask = static_cast<uint32_t>(value);
         }
-        else if (strcmp(argv[index], "binary") == 0)
+        else if (strcmp(aArgs[index], "binary") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
-            length = static_cast<int>((strlen(argv[index]) + 1) / 2);
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
+            length = static_cast<int>((strlen(aArgs[index]) + 1) / 2);
             VerifyOrExit(static_cast<size_t>(length) <= sizeof(tlvs), error = OT_ERROR_NO_BUFS);
-            VerifyOrExit(Interpreter::Hex2Bin(argv[index], tlvs, static_cast<uint16_t>(length)) >= 0,
-                         error = OT_ERROR_PARSE);
+            VerifyOrExit(Interpreter::Hex2Bin(aArgs[index], tlvs, static_cast<uint16_t>(length)) == length,
+                         error = OT_ERROR_INVALID_ARGS);
         }
         else
         {
@@ -558,12 +591,12 @@
         }
     }
 
-    if (strcmp(argv[0], "active") == 0)
+    if (strcmp(aArgs[0], "active") == 0)
     {
         SuccessOrExit(
             error = otDatasetSendMgmtActiveSet(mInterpreter.mInstance, &dataset, tlvs, static_cast<uint8_t>(length)));
     }
-    else if (strcmp(argv[0], "pending") == 0)
+    else if (strcmp(aArgs[0], "pending") == 0)
     {
         SuccessOrExit(
             error = otDatasetSendMgmtPendingSet(mInterpreter.mInstance, &dataset, tlvs, static_cast<uint8_t>(length)));
@@ -577,7 +610,7 @@
     return error;
 }
 
-otError Dataset::ProcessMgmtGetCommand(int argc, char *argv[])
+otError Dataset::ProcessMgmtGetCommand(uint8_t aArgsLength, char *aArgs[])
 {
     otError                        error = OT_ERROR_NONE;
     otOperationalDatasetComponents datasetComponents;
@@ -587,64 +620,64 @@
     bool                           destAddrSpecified = false;
     otIp6Address                   address;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
     memset(&datasetComponents, 0, sizeof(datasetComponents));
 
-    for (uint8_t index = 1; index < argc; index++)
+    for (uint8_t index = 1; index < aArgsLength; index++)
     {
         VerifyOrExit(static_cast<size_t>(length) < sizeof(tlvs), error = OT_ERROR_NO_BUFS);
 
-        if (strcmp(argv[index], "activetimestamp") == 0)
+        if (strcmp(aArgs[index], "activetimestamp") == 0)
         {
             datasetComponents.mIsActiveTimestampPresent = true;
         }
-        else if (strcmp(argv[index], "pendingtimestamp") == 0)
+        else if (strcmp(aArgs[index], "pendingtimestamp") == 0)
         {
             datasetComponents.mIsPendingTimestampPresent = true;
         }
-        else if (strcmp(argv[index], "masterkey") == 0)
+        else if (strcmp(aArgs[index], "masterkey") == 0)
         {
             datasetComponents.mIsMasterKeyPresent = true;
         }
-        else if (strcmp(argv[index], "networkname") == 0)
+        else if (strcmp(aArgs[index], "networkname") == 0)
         {
             datasetComponents.mIsNetworkNamePresent = true;
         }
-        else if (strcmp(argv[index], "extpanid") == 0)
+        else if (strcmp(aArgs[index], "extpanid") == 0)
         {
             datasetComponents.mIsExtendedPanIdPresent = true;
         }
-        else if (strcmp(argv[index], "localprefix") == 0)
+        else if (strcmp(aArgs[index], "localprefix") == 0)
         {
             datasetComponents.mIsMeshLocalPrefixPresent = true;
         }
-        else if (strcmp(argv[index], "delaytimer") == 0)
+        else if (strcmp(aArgs[index], "delaytimer") == 0)
         {
             datasetComponents.mIsDelayPresent = true;
         }
-        else if (strcmp(argv[index], "panid") == 0)
+        else if (strcmp(aArgs[index], "panid") == 0)
         {
             datasetComponents.mIsPanIdPresent = true;
         }
-        else if (strcmp(argv[index], "channel") == 0)
+        else if (strcmp(aArgs[index], "channel") == 0)
         {
             datasetComponents.mIsChannelPresent = true;
         }
-        else if (strcmp(argv[index], "binary") == 0)
+        else if (strcmp(aArgs[index], "binary") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
-            value = static_cast<long>(strlen(argv[index]) + 1) / 2;
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
+            value = static_cast<long>(strlen(aArgs[index]) + 1) / 2;
             VerifyOrExit(static_cast<size_t>(value) <= (sizeof(tlvs) - static_cast<size_t>(length)),
                          error = OT_ERROR_NO_BUFS);
-            VerifyOrExit(Interpreter::Hex2Bin(argv[index], tlvs + length, static_cast<uint16_t>(value)) >= 0,
-                         error = OT_ERROR_PARSE);
+            VerifyOrExit(Interpreter::Hex2Bin(aArgs[index], tlvs + length, static_cast<uint16_t>(value)) == value,
+                         error = OT_ERROR_INVALID_ARGS);
             length += value;
         }
-        else if (strcmp(argv[index], "address") == 0)
+        else if (strcmp(aArgs[index], "address") == 0)
         {
-            VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
-            SuccessOrExit(error = otIp6AddressFromString(argv[index], &address));
+            VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
+            SuccessOrExit(error = otIp6AddressFromString(aArgs[index], &address));
             destAddrSpecified = true;
         }
         else
@@ -653,17 +686,17 @@
         }
     }
 
-    if (strcmp(argv[0], "active") == 0)
+    if (strcmp(aArgs[0], "active") == 0)
     {
         SuccessOrExit(error = otDatasetSendMgmtActiveGet(mInterpreter.mInstance, &datasetComponents, tlvs,
                                                          static_cast<uint8_t>(length),
-                                                         destAddrSpecified ? &address : NULL));
+                                                         destAddrSpecified ? &address : nullptr));
     }
-    else if (strcmp(argv[0], "pending") == 0)
+    else if (strcmp(aArgs[0], "pending") == 0)
     {
         SuccessOrExit(error = otDatasetSendMgmtPendingGet(mInterpreter.mInstance, &datasetComponents, tlvs,
                                                           static_cast<uint8_t>(length),
-                                                          destAddrSpecified ? &address : NULL));
+                                                          destAddrSpecified ? &address : nullptr));
     }
     else
     {
@@ -674,16 +707,34 @@
     return error;
 }
 
-otError Dataset::ProcessPskc(int argc, char *argv[])
+otError Dataset::ProcessPskc(uint8_t aArgsLength, char *aArgs[])
 {
-    otError  error = OT_ERROR_NONE;
-    uint16_t length;
+    otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
-    length = static_cast<uint16_t>((strlen(argv[0]) + 1) / 2);
-    VerifyOrExit(length <= OT_PSKC_MAX_SIZE, error = OT_ERROR_NO_BUFS);
-    VerifyOrExit(Interpreter::Hex2Bin(argv[0], sDataset.mPskc.m8 + OT_PSKC_MAX_SIZE - length, length) == length,
-                 error = OT_ERROR_PARSE);
+    if (aArgsLength == 1)
+    {
+        VerifyOrExit(Interpreter::Hex2Bin(aArgs[0], sDataset.mPskc.m8, sizeof(sDataset.mPskc)) ==
+                         sizeof(sDataset.mPskc),
+                     error = OT_ERROR_INVALID_ARGS);
+    }
+#if OPENTHREAD_FTD
+    else if (aArgsLength == 2 && !strcmp(aArgs[0], "-p"))
+    {
+        SuccessOrExit(
+            error = otDatasetGeneratePskc(
+                aArgs[1],
+                (sDataset.mComponents.mIsNetworkNamePresent
+                     ? &sDataset.mNetworkName
+                     : reinterpret_cast<const otNetworkName *>(otThreadGetNetworkName(mInterpreter.mInstance))),
+                (sDataset.mComponents.mIsExtendedPanIdPresent ? &sDataset.mExtendedPanId
+                                                              : otThreadGetExtendedPanId(mInterpreter.mInstance)),
+                &sDataset.mPskc));
+    }
+#endif
+    else
+    {
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
+    }
 
     sDataset.mComponents.mIsPskcPresent = true;
 
@@ -691,20 +742,20 @@
     return error;
 }
 
-otError Dataset::ProcessSecurityPolicy(int argc, char *argv[])
+otError Dataset::ProcessSecurityPolicy(uint8_t aArgsLength, char *aArgs[])
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = Interpreter::ParseLong(argv[0], value));
+    SuccessOrExit(error = Interpreter::ParseLong(aArgs[0], value));
     sDataset.mSecurityPolicy.mRotationTime = static_cast<uint16_t>(value);
     sDataset.mSecurityPolicy.mFlags        = 0;
 
-    if (argc > 1)
+    if (aArgsLength > 1)
     {
-        for (char *arg = argv[1]; *arg != '\0'; arg++)
+        for (char *arg = aArgs[1]; *arg != '\0'; arg++)
         {
             switch (*arg)
             {
@@ -729,7 +780,7 @@
                 break;
 
             default:
-                ExitNow(error = OT_ERROR_PARSE);
+                ExitNow(error = OT_ERROR_INVALID_ARGS);
             }
         }
     }
@@ -740,5 +791,31 @@
     return error;
 }
 
+otError Dataset::ProcessSet(uint8_t aArgsLength, char *aArgs[])
+{
+    otError                  error = OT_ERROR_NONE;
+    otOperationalDatasetTlvs dataset;
+
+    VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
+
+    if (strcmp(aArgs[0], "active") == 0)
+    {
+        dataset.mLength = static_cast<uint8_t>(Interpreter::Hex2Bin(aArgs[1], dataset.mTlvs, sizeof(dataset.mTlvs)));
+        SuccessOrExit(error = otDatasetSetActiveTlvs(mInterpreter.mInstance, &dataset));
+    }
+    else if (strcmp(aArgs[0], "pending") == 0)
+    {
+        dataset.mLength = static_cast<uint8_t>(Interpreter::Hex2Bin(aArgs[1], dataset.mTlvs, sizeof(dataset.mTlvs)));
+        SuccessOrExit(error = otDatasetSetPendingTlvs(mInterpreter.mInstance, &dataset));
+    }
+    else
+    {
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
+    }
+
+exit:
+    return error;
+}
+
 } // namespace Cli
 } // namespace ot
diff --git a/src/cli/cli_dataset.hpp b/src/cli/cli_dataset.hpp
index 767933f..130994a 100644
--- a/src/cli/cli_dataset.hpp
+++ b/src/cli/cli_dataset.hpp
@@ -60,42 +60,43 @@
     /**
      * This method interprets a list of CLI arguments.
      *
-     * @param[in]  argc  The number of elements in argv.
-     * @param[in]  argv  A pointer to an array of command line arguments.
+     * @param[in]  aArgsLength  The number of elements in @p aArgs.
+     * @param[in]  aArgs        An array of command line arguments.
      *
      */
-    otError Process(int argc, char *argv[]);
+    otError Process(uint8_t aArgsLength, char *aArgs[]);
 
 private:
     struct Command
     {
         const char *mName;
-        otError (Dataset::*mCommand)(int argc, char *argv[]);
+        otError (Dataset::*mCommand)(uint8_t aArgsLength, char *aArgs[]);
     };
 
     void    OutputBytes(const uint8_t *aBytes, uint8_t aLength);
     otError Print(otOperationalDataset &aDataset);
 
-    otError ProcessHelp(int argc, char *argv[]);
-    otError ProcessActive(int argc, char *argv[]);
-    otError ProcessActiveTimestamp(int argc, char *argv[]);
-    otError ProcessChannel(int argc, char *argv[]);
-    otError ProcessChannelMask(int argc, char *argv[]);
-    otError ProcessClear(int argc, char *argv[]);
-    otError ProcessCommit(int argc, char *argv[]);
-    otError ProcessDelay(int argc, char *argv[]);
-    otError ProcessExtPanId(int argc, char *argv[]);
-    otError ProcessInit(int argc, char *argv[]);
-    otError ProcessMasterKey(int argc, char *argv[]);
-    otError ProcessMeshLocalPrefix(int argc, char *argv[]);
-    otError ProcessNetworkName(int argc, char *argv[]);
-    otError ProcessPanId(int argc, char *argv[]);
-    otError ProcessPending(int argc, char *argv[]);
-    otError ProcessPendingTimestamp(int argc, char *argv[]);
-    otError ProcessMgmtSetCommand(int argc, char *argv[]);
-    otError ProcessMgmtGetCommand(int argc, char *argv[]);
-    otError ProcessPskc(int argc, char *argv[]);
-    otError ProcessSecurityPolicy(int argc, char *argv[]);
+    otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessActive(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessActiveTimestamp(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessChannel(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessChannelMask(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessClear(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessCommit(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessDelay(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessExtPanId(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessInit(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMasterKey(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMeshLocalPrefix(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessNetworkName(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessPanId(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessPending(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessPendingTimestamp(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMgmtSetCommand(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessMgmtGetCommand(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessPskc(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessSecurityPolicy(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessSet(uint8_t aArgsLength, char *aArgs[]);
 
     Interpreter &mInterpreter;
 
diff --git a/src/cli/cli_joiner.cpp b/src/cli/cli_joiner.cpp
index 9715551..856cc33 100644
--- a/src/cli/cli_joiner.cpp
+++ b/src/cli/cli_joiner.cpp
@@ -48,10 +48,10 @@
     {"stop", &Joiner::ProcessStop},
 };
 
-otError Joiner::ProcessHelp(int argc, char *argv[])
+otError Joiner::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
@@ -61,65 +61,65 @@
     return OT_ERROR_NONE;
 }
 
-otError Joiner::ProcessId(int argc, char *argv[])
+otError Joiner::ProcessId(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
-    otExtAddress joinerId;
+    const otExtAddress *joinerId;
 
-    otJoinerGetId(mInterpreter.mInstance, &joinerId);
+    joinerId = otJoinerGetId(mInterpreter.mInstance);
 
-    mInterpreter.OutputBytes(joinerId.m8, sizeof(joinerId));
+    mInterpreter.OutputBytes(joinerId->m8, sizeof(otExtAddress));
     mInterpreter.mServer->OutputFormat("\r\n");
 
     return OT_ERROR_NONE;
 }
 
-otError Joiner::ProcessStart(int argc, char *argv[])
+otError Joiner::ProcessStart(uint8_t aArgsLength, char *aArgs[])
 {
     otError     error;
-    const char *provisioningUrl = NULL;
+    const char *provisioningUrl = nullptr;
 
-    VerifyOrExit(argc > 1, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 1, error = OT_ERROR_INVALID_ARGS);
 
-    if (argc > 2)
+    if (aArgsLength > 2)
     {
-        provisioningUrl = argv[2];
+        provisioningUrl = aArgs[2];
     }
 
-    error = otJoinerStart(mInterpreter.mInstance, argv[1], provisioningUrl, PACKAGE_NAME,
-                          OPENTHREAD_CONFIG_PLATFORM_INFO, PACKAGE_VERSION, NULL, &Joiner::HandleCallback, this);
+    error = otJoinerStart(mInterpreter.mInstance, aArgs[1], provisioningUrl, PACKAGE_NAME,
+                          OPENTHREAD_CONFIG_PLATFORM_INFO, PACKAGE_VERSION, nullptr, &Joiner::HandleCallback, this);
 
 exit:
     return error;
 }
 
-otError Joiner::ProcessStop(int argc, char *argv[])
+otError Joiner::ProcessStop(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otJoinerStop(mInterpreter.mInstance);
 
     return OT_ERROR_NONE;
 }
 
-otError Joiner::Process(int argc, char *argv[])
+otError Joiner::Process(uint8_t aArgsLength, char *aArgs[])
 {
-    otError error = OT_ERROR_INVALID_ARGS;
+    otError error = OT_ERROR_INVALID_COMMAND;
 
-    if (argc < 1)
+    if (aArgsLength < 1)
     {
-        ProcessHelp(0, NULL);
+        IgnoreError(ProcessHelp(0, nullptr));
     }
     else
     {
         for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
         {
-            if (strcmp(argv[0], sCommands[i].mName) == 0)
+            if (strcmp(aArgs[0], sCommands[i].mName) == 0)
             {
-                error = (this->*sCommands[i].mCommand)(argc, argv);
+                error = (this->*sCommands[i].mCommand)(aArgsLength, aArgs);
                 break;
             }
         }
diff --git a/src/cli/cli_joiner.hpp b/src/cli/cli_joiner.hpp
index c161bd5..802de29 100644
--- a/src/cli/cli_joiner.hpp
+++ b/src/cli/cli_joiner.hpp
@@ -66,23 +66,23 @@
     /**
      * This method interprets a list of CLI arguments.
      *
-     * @param[in]  argc  The number of elements in argv.
-     * @param[in]  argv  A pointer to an array of command line arguments.
+     * @param[in]  aArgsLength  The number of elements in @p aArgs.
+     * @param[in]  aArgs        A pointer to an array of command line arguments.
      *
      */
-    otError Process(int argc, char *argv[]);
+    otError Process(uint8_t aArgsLength, char *aArgs[]);
 
 private:
     struct Command
     {
         const char *mName;
-        otError (Joiner::*mCommand)(int argc, char *argv[]);
+        otError (Joiner::*mCommand)(uint8_t aArgsLength, char *aArgs[]);
     };
 
-    otError ProcessHelp(int argc, char *argv[]);
-    otError ProcessId(int argc, char *argv[]);
-    otError ProcessStart(int argc, char *argv[]);
-    otError ProcessStop(int argc, char *argv[]);
+    otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessId(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessStart(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessStop(uint8_t aArgsLength, char *aArgs[]);
 
     static void HandleCallback(otError aError, void *aContext);
     void        HandleCallback(otError aError);
diff --git a/src/cli/cli_server.cpp b/src/cli/cli_server.cpp
index a646fe1..0339c1f 100644
--- a/src/cli/cli_server.cpp
+++ b/src/cli/cli_server.cpp
@@ -36,7 +36,7 @@
 namespace ot {
 namespace Cli {
 
-Server *Server::sServer = NULL;
+Server *Server::sServer = nullptr;
 
 int Server::OutputFormat(const char *aFormat, ...)
 {
diff --git a/src/cli/cli_uart.cpp b/src/cli/cli_uart.cpp
index a574e22..c35b34d 100644
--- a/src/cli/cli_uart.cpp
+++ b/src/cli/cli_uart.cpp
@@ -51,7 +51,6 @@
 #include "common/logging.hpp"
 #include "common/new.hpp"
 #include "common/tasklet.hpp"
-#include "utils/static_assert.hpp"
 
 #if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART
 #include <openthread/platform/debug_uart.h>
@@ -90,14 +89,14 @@
 #endif // OT_CLI_UART_LOCK_HDR_FILE
 
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
-OT_STATIC_ASSERT(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <= OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE,
-                 "diag output buffer should be smaller than CLI UART tx buffer");
-OT_STATIC_ASSERT(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE,
-                 "diag command line should be smaller than CLI UART rx buffer");
+static_assert(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <= OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE,
+              "diag output buffer should be smaller than CLI UART tx buffer");
+static_assert(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE,
+              "diag command line should be smaller than CLI UART rx buffer");
 #endif
 
-OT_STATIC_ASSERT(OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH <= OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE,
-                 "command line should be should be smaller than CLI rx buffer");
+static_assert(OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH <= OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE,
+              "command line should be should be smaller than CLI rx buffer");
 
 namespace ot {
 namespace Cli {
@@ -119,7 +118,7 @@
     mTxLength   = 0;
     mSendLength = 0;
 
-    otPlatUartEnable();
+    IgnoreError(otPlatUartEnable());
 }
 
 extern "C" void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength)
@@ -150,7 +149,7 @@
             if (mRxLength > 0)
             {
                 mRxBuffer[mRxLength] = '\0';
-                ProcessCommand();
+                IgnoreError(ProcessCommand());
             }
 
             Output(sCommandPrompt, sizeof(sCommandPrompt));
@@ -294,7 +293,7 @@
 
 void Uart::Send(void)
 {
-    VerifyOrExit(mSendLength == 0);
+    VerifyOrExit(mSendLength == 0, OT_NOOP);
 
     if (mTxLength > kTxBufferSize - mTxHead)
     {
@@ -311,7 +310,7 @@
         /* duplicate the output to the debug uart */
         otPlatDebugUart_write_bytes(reinterpret_cast<uint8_t *>(mTxBuffer + mTxHead), mSendLength);
 #endif
-        otPlatUartSend(reinterpret_cast<uint8_t *>(mTxBuffer + mTxHead), mSendLength);
+        IgnoreError(otPlatUartSend(reinterpret_cast<uint8_t *>(mTxBuffer + mTxHead), mSendLength));
     }
 
 exit:
diff --git a/src/cli/cli_udp.cpp b/src/cli/cli_udp.cpp
index ef28f66..1454908 100644
--- a/src/cli/cli_udp.cpp
+++ b/src/cli/cli_udp.cpp
@@ -55,12 +55,12 @@
     memset(&mSocket, 0, sizeof(mSocket));
 }
 
-otError UdpExample::ProcessHelp(int argc, char *argv[])
+otError UdpExample::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
-    for (unsigned int i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
         mInterpreter.mServer->OutputFormat("%s\r\n", sCommands[i].mName);
     }
@@ -68,124 +68,124 @@
     return OT_ERROR_NONE;
 }
 
-otError UdpExample::ProcessBind(int argc, char *argv[])
+otError UdpExample::ProcessBind(uint8_t aArgsLength, char *aArgs[])
 {
     otError    error;
     otSockAddr sockaddr;
     long       value;
 
-    VerifyOrExit(argc == 2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
 
     memset(&sockaddr, 0, sizeof(sockaddr));
 
-    error = otIp6AddressFromString(argv[0], &sockaddr.mAddress);
+    error = otIp6AddressFromString(aArgs[0], &sockaddr.mAddress);
     SuccessOrExit(error);
 
-    error = Interpreter::ParseLong(argv[1], value);
+    error = Interpreter::ParseLong(aArgs[1], value);
     SuccessOrExit(error);
 
     sockaddr.mPort = static_cast<uint16_t>(value);
 
-    error = otUdpBind(&mSocket, &sockaddr);
+    error = otUdpBind(mInterpreter.mInstance, &mSocket, &sockaddr);
 
 exit:
     return error;
 }
 
-otError UdpExample::ProcessConnect(int argc, char *argv[])
+otError UdpExample::ProcessConnect(uint8_t aArgsLength, char *aArgs[])
 {
     otError    error;
     otSockAddr sockaddr;
     long       value;
 
-    VerifyOrExit(argc == 2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
 
     memset(&sockaddr, 0, sizeof(sockaddr));
 
-    error = otIp6AddressFromString(argv[0], &sockaddr.mAddress);
+    error = otIp6AddressFromString(aArgs[0], &sockaddr.mAddress);
     SuccessOrExit(error);
 
-    error = Interpreter::ParseLong(argv[1], value);
+    error = Interpreter::ParseLong(aArgs[1], value);
     SuccessOrExit(error);
 
     sockaddr.mPort = static_cast<uint16_t>(value);
 
-    error = otUdpConnect(&mSocket, &sockaddr);
+    error = otUdpConnect(mInterpreter.mInstance, &mSocket, &sockaddr);
 
 exit:
     return error;
 }
 
-otError UdpExample::ProcessClose(int argc, char *argv[])
+otError UdpExample::ProcessClose(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
-    return otUdpClose(&mSocket);
+    return otUdpClose(mInterpreter.mInstance, &mSocket);
 }
 
-otError UdpExample::ProcessOpen(int argc, char *argv[])
+otError UdpExample::ProcessOpen(uint8_t aArgsLength, char *aArgs[])
 {
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     return otUdpOpen(mInterpreter.mInstance, &mSocket, HandleUdpReceive, this);
 }
 
-otError UdpExample::ProcessSend(int argc, char *argv[])
+otError UdpExample::ProcessSend(uint8_t aArgsLength, char *aArgs[])
 {
     otError       error = OT_ERROR_NONE;
     otMessageInfo messageInfo;
-    otMessage *   message       = NULL;
-    int           curArg        = 0;
+    otMessage *   message       = nullptr;
+    uint8_t       curArg        = 0;
     uint16_t      payloadLength = 0;
     PayloadType   payloadType   = kTypeText;
 
     memset(&messageInfo, 0, sizeof(messageInfo));
 
-    VerifyOrExit(argc >= 1 && argc <= 4, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength >= 1 && aArgsLength <= 4, error = OT_ERROR_INVALID_ARGS);
 
-    if (argc > 2)
+    if (aArgsLength > 2)
     {
         long value;
-        error = otIp6AddressFromString(argv[curArg++], &messageInfo.mPeerAddr);
+        error = otIp6AddressFromString(aArgs[curArg++], &messageInfo.mPeerAddr);
         SuccessOrExit(error);
 
-        error = Interpreter::ParseLong(argv[curArg++], value);
+        error = Interpreter::ParseLong(aArgs[curArg++], value);
         SuccessOrExit(error);
 
         messageInfo.mPeerPort = static_cast<uint16_t>(value);
     }
 
-    if (argc == 2 || argc == 4)
+    if (aArgsLength == 2 || aArgsLength == 4)
     {
-        int typePos = curArg++;
+        uint8_t typePos = curArg++;
 
-        if (strcmp(argv[typePos], "-s") == 0)
+        if (strcmp(aArgs[typePos], "-s") == 0)
         {
             unsigned long value;
             payloadType = kTypeAutoSize;
-            SuccessOrExit(error = Interpreter::ParseUnsignedLong(argv[curArg], value));
+            SuccessOrExit(error = Interpreter::ParseUnsignedLong(aArgs[curArg], value));
             payloadLength = static_cast<uint16_t>(value);
         }
-        else if (strcmp(argv[typePos], "-x") == 0)
+        else if (strcmp(aArgs[typePos], "-x") == 0)
         {
-            payloadLength = static_cast<uint16_t>(strlen(argv[curArg]));
+            payloadLength = static_cast<uint16_t>(strlen(aArgs[curArg]));
             payloadType   = kTypeHexString;
         }
-        else if (strcmp(argv[typePos], "-t") == 0)
+        else if (strcmp(aArgs[typePos], "-t") == 0)
         {
             payloadType = kTypeText;
         }
     }
 
-    message = otUdpNewMessage(mInterpreter.mInstance, NULL);
-    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+    message = otUdpNewMessage(mInterpreter.mInstance, nullptr);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
     switch (payloadType)
     {
     case kTypeText:
-        SuccessOrExit(error = otMessageAppend(message, argv[curArg], static_cast<uint16_t>(strlen(argv[curArg]))));
+        SuccessOrExit(error = otMessageAppend(message, aArgs[curArg], static_cast<uint16_t>(strlen(aArgs[curArg]))));
         break;
     case kTypeAutoSize:
         SuccessOrExit(error = WriteCharToBuffer(message, payloadLength));
@@ -195,7 +195,7 @@
         uint8_t     buf[50];
         int16_t     bufLen;
         uint16_t    conversionLength = 0;
-        const char *hexString        = argv[curArg];
+        const char *hexString        = aArgs[curArg];
 
         while (payloadLength > 0)
         {
@@ -218,11 +218,11 @@
     }
     }
 
-    error = otUdpSend(&mSocket, message, &messageInfo);
+    error = otUdpSend(mInterpreter.mInstance, &mSocket, message, &messageInfo);
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         otMessageFree(message);
     }
@@ -258,22 +258,22 @@
     return error;
 }
 
-otError UdpExample::Process(int argc, char *argv[])
+otError UdpExample::Process(uint8_t aArgsLength, char *aArgs[])
 {
-    otError error = OT_ERROR_PARSE;
+    otError error = OT_ERROR_INVALID_COMMAND;
 
-    if (argc < 1)
+    if (aArgsLength < 1)
     {
-        ProcessHelp(0, NULL);
+        IgnoreError(ProcessHelp(0, nullptr));
         error = OT_ERROR_INVALID_ARGS;
     }
     else
     {
         for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
         {
-            if (strcmp(argv[0], sCommands[i].mName) == 0)
+            if (strcmp(aArgs[0], sCommands[i].mName) == 0)
             {
-                error = (this->*sCommands[i].mCommand)(argc - 1, argv + 1);
+                error = (this->*sCommands[i].mCommand)(aArgsLength - 1, aArgs + 1);
                 break;
             }
         }
diff --git a/src/cli/cli_udp.hpp b/src/cli/cli_udp.hpp
index 1fc34a4..201b10c 100644
--- a/src/cli/cli_udp.hpp
+++ b/src/cli/cli_udp.hpp
@@ -61,17 +61,17 @@
     /**
      * This method interprets a list of CLI arguments.
      *
-     * @param[in]  argc  The number of elements in argv.
-     * @param[in]  argv  A pointer to an array of command line arguments.
+     * @param[in]  aArgsLength  The number of elements in @p aArgs.
+     * @param[in]  aArgs        An array of command line arguments.
      *
      */
-    otError Process(int argc, char *argv[]);
+    otError Process(uint8_t aArgsLength, char *aArgs[]);
 
 private:
     struct Command
     {
         const char *mName;
-        otError (UdpExample::*mCommand)(int argc, char *argv[]);
+        otError (UdpExample::*mCommand)(uint8_t aArgsLength, char *aArgs[]);
     };
 
     enum PayloadType
@@ -81,12 +81,12 @@
         kTypeHexString = 2,
     };
 
-    otError ProcessHelp(int argc, char *argv[]);
-    otError ProcessBind(int argc, char *argv[]);
-    otError ProcessClose(int argc, char *argv[]);
-    otError ProcessConnect(int argc, char *argv[]);
-    otError ProcessOpen(int argc, char *argv[]);
-    otError ProcessSend(int argc, char *argv[]);
+    otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessBind(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessClose(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessConnect(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessOpen(uint8_t aArgsLength, char *aArgs[]);
+    otError ProcessSend(uint8_t aArgsLength, char *aArgs[]);
     otError WriteCharToBuffer(otMessage *aMessage, uint16_t aSize);
 
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 99c58cd..a860e1e 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -30,27 +30,44 @@
 add_library(openthread-mtd)
 add_library(openthread-radio)
 
+set_target_properties(
+    openthread-ftd openthread-mtd openthread-radio
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
 target_compile_definitions(openthread-ftd PRIVATE
-    ${OT_PRIVATE_DEFINES}
     OPENTHREAD_FTD=1
 )
 
 target_compile_definitions(openthread-mtd PRIVATE
-    ${OT_PRIVATE_DEFINES}
     OPENTHREAD_MTD=1
 )
 
 target_compile_definitions(openthread-radio PRIVATE
-    ${OT_PRIVATE_DEFINES}
     OPENTHREAD_RADIO=1
 )
 
+target_compile_options(openthread-ftd PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_compile_options(openthread-mtd PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_compile_options(openthread-radio PRIVATE
+    ${OT_CFLAGS}
+)
+
 set(COMMON_INCLUDES
-    ${OT_PRIVATE_INCLUDES}
     ${PROJECT_SOURCE_DIR}/src/core
 )
 
 set(COMMON_SOURCES
+    api/backbone_router_api.cpp
+    api/backbone_router_ftd_api.cpp
     api/border_router_api.cpp
     api/channel_manager_api.cpp
     api/channel_monitor_api.cpp
@@ -75,6 +92,7 @@
     api/logging_api.cpp
     api/message_api.cpp
     api/netdata_api.cpp
+    api/netdiag_api.cpp
     api/network_time_api.cpp
     api/random_crypto_api.cpp
     api/random_noncrypto_api.cpp
@@ -84,6 +102,8 @@
     api/thread_api.cpp
     api/thread_ftd_api.cpp
     api/udp_api.cpp
+    backbone_router/bbr_leader.cpp
+    backbone_router/bbr_local.cpp
     coap/coap.cpp
     coap/coap_message.cpp
     coap/coap_secure.cpp
@@ -128,8 +148,8 @@
     meshcop/energy_scan_client.cpp
     meshcop/joiner.cpp
     meshcop/joiner_router.cpp
-    meshcop/leader.cpp
     meshcop/meshcop.cpp
+    meshcop/meshcop_leader.cpp
     meshcop/meshcop_tlvs.cpp
     meshcop/panid_query_client.cpp
     meshcop/timestamp.cpp
@@ -145,13 +165,15 @@
     net/netif.cpp
     net/sntp_client.cpp
     net/udp6.cpp
+    radio/radio.cpp
     radio/radio_callbacks.cpp
     radio/radio_platform.cpp
     thread/address_resolver.cpp
     thread/announce_begin_server.cpp
     thread/announce_sender.cpp
     thread/child_table.cpp
-    thread/device_mode.cpp
+    thread/discover_scanner.cpp
+    thread/dua_manager.cpp
     thread/energy_scan_server.cpp
     thread/indirect_sender.cpp
     thread/key_manager.cpp
@@ -162,10 +184,12 @@
     thread/mesh_forwarder_mtd.cpp
     thread/mle.cpp
     thread/mle_router.cpp
+    thread/mle_types.cpp
     thread/network_data.cpp
     thread/network_data_leader.cpp
     thread/network_data_leader_ftd.cpp
     thread/network_data_local.cpp
+    thread/network_data_notifier.cpp
     thread/network_diagnostic.cpp
     thread/panid_query_server.cpp
     thread/router_table.cpp
@@ -176,8 +200,10 @@
     utils/channel_manager.cpp
     utils/channel_monitor.cpp
     utils/child_supervision.cpp
+    utils/flash.cpp
     utils/heap.cpp
     utils/jam_detector.cpp
+    utils/otns.cpp
     utils/parse_cmdline.cpp
     utils/slaac_address.cpp
 )
@@ -202,14 +228,35 @@
     common/string.cpp
     common/tasklet.cpp
     common/timer.cpp
+    crypto/aes_ccm.cpp
+    crypto/aes_ecb.cpp
     diags/factory_diags.cpp
     mac/link_raw.cpp
     mac/mac_frame.cpp
     mac/mac_types.cpp
     mac/sub_mac.cpp
     mac/sub_mac_callbacks.cpp
+    radio/radio.cpp
     radio/radio_callbacks.cpp
     radio/radio_platform.cpp
     thread/link_quality.cpp
     utils/parse_cmdline.cpp
 )
+
+target_link_libraries(openthread-ftd
+    PRIVATE
+        ${OT_MBEDTLS}
+        ot-config
+)
+
+target_link_libraries(openthread-mtd
+    PRIVATE
+        ${OT_MBEDTLS}
+        ot-config
+)
+
+target_link_libraries(openthread-radio
+    PRIVATE
+        ${OT_MBEDTLS}
+        ot-config
+)
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 9a493ae..aefdccd 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -108,6 +108,8 @@
 #
 
 SOURCES_COMMON                             = \
+    api/backbone_router_api.cpp              \
+    api/backbone_router_ftd_api.cpp          \
     api/border_router_api.cpp                \
     api/channel_manager_api.cpp              \
     api/channel_monitor_api.cpp              \
@@ -132,6 +134,7 @@
     api/logging_api.cpp                      \
     api/message_api.cpp                      \
     api/netdata_api.cpp                      \
+    api/netdiag_api.cpp                      \
     api/network_time_api.cpp                 \
     api/random_crypto_api.cpp                \
     api/random_noncrypto_api.cpp             \
@@ -141,6 +144,8 @@
     api/thread_api.cpp                       \
     api/thread_ftd_api.cpp                   \
     api/udp_api.cpp                          \
+    backbone_router/bbr_leader.cpp           \
+    backbone_router/bbr_local.cpp            \
     coap/coap.cpp                            \
     coap/coap_message.cpp                    \
     coap/coap_secure.cpp                     \
@@ -185,8 +190,8 @@
     meshcop/energy_scan_client.cpp           \
     meshcop/joiner.cpp                       \
     meshcop/joiner_router.cpp                \
-    meshcop/leader.cpp                       \
     meshcop/meshcop.cpp                      \
+    meshcop/meshcop_leader.cpp               \
     meshcop/meshcop_tlvs.cpp                 \
     meshcop/panid_query_client.cpp           \
     meshcop/timestamp.cpp                    \
@@ -202,13 +207,15 @@
     net/netif.cpp                            \
     net/sntp_client.cpp                      \
     net/udp6.cpp                             \
+    radio/radio.cpp                          \
     radio/radio_callbacks.cpp                \
     radio/radio_platform.cpp                 \
     thread/address_resolver.cpp              \
     thread/announce_begin_server.cpp         \
     thread/announce_sender.cpp               \
     thread/child_table.cpp                   \
-    thread/device_mode.cpp                   \
+    thread/discover_scanner.cpp              \
+    thread/dua_manager.cpp                   \
     thread/energy_scan_server.cpp            \
     thread/indirect_sender.cpp               \
     thread/key_manager.cpp                   \
@@ -219,10 +226,12 @@
     thread/mesh_forwarder_mtd.cpp            \
     thread/mle.cpp                           \
     thread/mle_router.cpp                    \
+    thread/mle_types.cpp                     \
     thread/network_data.cpp                  \
     thread/network_data_leader.cpp           \
     thread/network_data_leader_ftd.cpp       \
     thread/network_data_local.cpp            \
+    thread/network_data_notifier.cpp         \
     thread/network_diagnostic.cpp            \
     thread/panid_query_server.cpp            \
     thread/router_table.cpp                  \
@@ -233,8 +242,10 @@
     utils/channel_manager.cpp                \
     utils/channel_monitor.cpp                \
     utils/child_supervision.cpp              \
+    utils/flash.cpp                          \
     utils/heap.cpp                           \
     utils/jam_detector.cpp                   \
+    utils/otns.cpp                           \
     utils/parse_cmdline.cpp                  \
     utils/slaac_address.cpp                  \
     $(NULL)
@@ -257,12 +268,15 @@
     common/string.cpp                        \
     common/tasklet.cpp                       \
     common/timer.cpp                         \
+    crypto/aes_ccm.cpp                       \
+    crypto/aes_ecb.cpp                       \
     diags/factory_diags.cpp                  \
     mac/link_raw.cpp                         \
     mac/mac_frame.cpp                        \
     mac/mac_types.cpp                        \
     mac/sub_mac.cpp                          \
     mac/sub_mac_callbacks.cpp                \
+    radio/radio.cpp                          \
     radio/radio_callbacks.cpp                \
     radio/radio_platform.cpp                 \
     thread/link_quality.cpp                  \
@@ -301,13 +315,17 @@
 
 HEADERS_COMMON                             = \
     openthread-core-config.h                 \
+    backbone_router/bbr_leader.hpp           \
+    backbone_router/bbr_local.hpp            \
     coap/coap.hpp                            \
     coap/coap_message.hpp                    \
     coap/coap_secure.hpp                     \
+    common/clearable.hpp                     \
     common/code_utils.hpp                    \
     common/crc16.hpp                         \
     common/debug.hpp                         \
     common/encoding.hpp                      \
+    common/equatable.hpp                     \
     common/extension.hpp                     \
     common/instance.hpp                      \
     common/linked_list.hpp                   \
@@ -316,7 +334,9 @@
     common/logging.hpp                       \
     common/message.hpp                       \
     common/new.hpp                           \
+    common/non_copyable.hpp                  \
     common/notifier.hpp                      \
+    common/pool.hpp                          \
     common/random.hpp                        \
     common/random_manager.hpp                \
     common/settings.hpp                      \
@@ -327,6 +347,7 @@
     common/tlvs.hpp                          \
     common/trickle_timer.hpp                 \
     config/announce_sender.h                 \
+    config/backbone_router.h                 \
     config/border_router.h                   \
     config/channel_manager.h                 \
     config/channel_monitor.h                 \
@@ -378,8 +399,8 @@
     meshcop/energy_scan_client.hpp           \
     meshcop/joiner.hpp                       \
     meshcop/joiner_router.hpp                \
-    meshcop/leader.hpp                       \
     meshcop/meshcop.hpp                      \
+    meshcop/meshcop_leader.hpp               \
     meshcop/meshcop_tlvs.hpp                 \
     meshcop/panid_query_client.hpp           \
     meshcop/timestamp.hpp                    \
@@ -403,8 +424,10 @@
     thread/address_resolver.hpp              \
     thread/announce_begin_server.hpp         \
     thread/announce_sender.hpp               \
+    thread/child_mask.hpp                    \
     thread/child_table.hpp                   \
-    thread/device_mode.hpp                   \
+    thread/discover_scanner.hpp              \
+    thread/dua_manager.hpp                   \
     thread/energy_scan_server.hpp            \
     thread/indirect_sender.hpp               \
     thread/indirect_sender_frame_context.hpp \
@@ -413,15 +436,14 @@
     thread/lowpan.hpp                        \
     thread/mesh_forwarder.hpp                \
     thread/mle.hpp                           \
-    thread/mle_constants.hpp                 \
     thread/mle_router.hpp                    \
-    thread/mle_router_ftd.hpp                \
-    thread/mle_router_mtd.hpp                \
     thread/mle_tlvs.hpp                      \
+    thread/mle_types.hpp                     \
     thread/network_data.hpp                  \
     thread/network_data_leader.hpp           \
     thread/network_data_leader_ftd.hpp       \
     thread/network_data_local.hpp            \
+    thread/network_data_notifier.hpp         \
     thread/network_data_tlvs.hpp             \
     thread/network_diagnostic.hpp            \
     thread/network_diagnostic_tlvs.hpp       \
@@ -436,23 +458,18 @@
     utils/channel_manager.hpp                \
     utils/channel_monitor.hpp                \
     utils/child_supervision.hpp              \
+    utils/flash.hpp                          \
     utils/heap.hpp                           \
     utils/jam_detector.hpp                   \
+    utils/otns.hpp                           \
     utils/parse_cmdline.hpp                  \
     utils/slaac_address.hpp                  \
-    utils/static_assert.hpp                  \
     $(NULL)
 
 noinst_HEADERS                             = \
     $(HEADERS_COMMON)                        \
     $(NULL)
 
-PRETTY_FILES                               = \
-    $(HEADERS_COMMON)                        \
-    $(SOURCES_COMMON)                        \
-    $(EXTRA_DIST)                            \
-    $(NULL)
-
 if OPENTHREAD_BUILD_COVERAGE
 Dash       = -
 CLEANFILES = $(shell find $(top_builddir)/src/core $(Dash)name "*.gcda" $(Dash)o $(Dash)name "*.gcno")
diff --git a/src/core/api/backbone_router_api.cpp b/src/core/api/backbone_router_api.cpp
new file mode 100644
index 0000000..a27a621
--- /dev/null
+++ b/src/core/api/backbone_router_api.cpp
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *  This file defines the OpenThread Backbone Router API (Thread 1.2)
+ */
+
+#include "openthread-core-config.h"
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+#include <openthread/backbone_router.h>
+#include "common/instance.hpp"
+
+using namespace ot;
+
+otError otBackboneRouterGetPrimary(otInstance *aInstance, otBackboneRouterConfig *aConfig)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    OT_ASSERT(aConfig != nullptr);
+
+    return instance.Get<BackboneRouter::Leader>().GetConfig(*aConfig);
+}
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
diff --git a/src/core/api/backbone_router_ftd_api.cpp b/src/core/api/backbone_router_ftd_api.cpp
new file mode 100644
index 0000000..738aea5
--- /dev/null
+++ b/src/core/api/backbone_router_ftd_api.cpp
@@ -0,0 +1,113 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *  This file defines the OpenThread Backbone Router API (for Thread 1.2 FTD with
+ *  `OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE`).
+ */
+
+#include "openthread-core-config.h"
+
+#include <openthread/backbone_router_ftd.h>
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+#include "common/instance.hpp"
+
+using namespace ot;
+
+void otBackboneRouterSetEnabled(otInstance *aInstance, bool aEnabled)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<BackboneRouter::Local>().SetEnabled(aEnabled);
+}
+
+otBackboneRouterState otBackboneRouterGetState(otInstance *aInstance)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<BackboneRouter::Local>().GetState();
+}
+
+void otBackboneRouterGetConfig(otInstance *aInstance, otBackboneRouterConfig *aConfig)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    OT_ASSERT(aConfig != nullptr);
+
+    instance.Get<BackboneRouter::Local>().GetConfig(*aConfig);
+}
+
+otError otBackboneRouterSetConfig(otInstance *aInstance, const otBackboneRouterConfig *aConfig)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    OT_ASSERT(aConfig != nullptr);
+
+    return instance.Get<BackboneRouter::Local>().SetConfig(*aConfig);
+}
+
+otError otBackboneRouterRegister(otInstance *aInstance)
+{
+    otError error = OT_ERROR_NONE;
+
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    SuccessOrExit(error = instance.Get<BackboneRouter::Local>().AddService(true /* Force registration */));
+
+    instance.Get<NetworkData::Notifier>().HandleServerDataUpdated();
+
+exit:
+    return error;
+}
+
+uint8_t otBackboneRouterGetRegistrationJitter(otInstance *aInstance)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<BackboneRouter::Local>().GetRegistrationJitter();
+}
+
+void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitter)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<BackboneRouter::Local>().SetRegistrationJitter(aJitter);
+}
+
+otError otBackboneRouterGetDomainPrefix(otInstance *aInstance, otBorderRouterConfig *aConfig)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    OT_ASSERT(aConfig != nullptr);
+
+    return instance.Get<BackboneRouter::Local>().GetDomainPrefix(*aConfig);
+}
+
+#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
diff --git a/src/core/api/border_router_api.cpp b/src/core/api/border_router_api.cpp
index 4dcaed8..1a2048d 100644
--- a/src/core/api/border_router_api.cpp
+++ b/src/core/api/border_router_api.cpp
@@ -47,59 +47,56 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aData != NULL && aDataLength != NULL);
+    OT_ASSERT(aData != nullptr && aDataLength != nullptr);
 
     return instance.Get<NetworkData::Local>().GetNetworkData(aStable, aData, *aDataLength);
 }
 
 otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRouterConfig *aConfig)
 {
-    uint8_t   flags    = 0;
+    otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aConfig != NULL);
+    OT_ASSERT(aConfig != nullptr);
+    // Add Prefix validation check:
+    // Thread 1.1 Specification 5.13.2 says
+    // "A valid prefix MUST NOT allow both DHCPv6 and SLAAC for address configuration"
+    VerifyOrExit(!aConfig->mDhcp || !aConfig->mSlaac, error = OT_ERROR_INVALID_ARGS);
 
-    if (aConfig->mPreferred)
+    error = instance.Get<NetworkData::Local>().AddOnMeshPrefix(*aConfig);
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    // Only try to configure Domain Prefix after the parameter is vaidated via above `AddOnMeshPrefix()`.
+    if (error == OT_ERROR_NONE && aConfig->mDp)
     {
-        flags |= NetworkData::BorderRouterEntry::kPreferredFlag;
-    }
+        // Restore local server data
+        IgnoreError(instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(aConfig->mPrefix.mPrefix.mFields.m8,
+                                                                          aConfig->mPrefix.mLength));
 
-    if (aConfig->mSlaac)
-    {
-        flags |= NetworkData::BorderRouterEntry::kSlaacFlag;
+        instance.Get<BackboneRouter::Local>().SetDomainPrefix(*aConfig);
     }
+#endif
 
-    if (aConfig->mDhcp)
-    {
-        flags |= NetworkData::BorderRouterEntry::kDhcpFlag;
-    }
-
-    if (aConfig->mConfigure)
-    {
-        flags |= NetworkData::BorderRouterEntry::kConfigureFlag;
-    }
-
-    if (aConfig->mDefaultRoute)
-    {
-        flags |= NetworkData::BorderRouterEntry::kDefaultRouteFlag;
-    }
-
-    if (aConfig->mOnMesh)
-    {
-        flags |= NetworkData::BorderRouterEntry::kOnMeshFlag;
-    }
-
-    return instance.Get<NetworkData::Local>().AddOnMeshPrefix(
-        aConfig->mPrefix.mPrefix.mFields.m8, aConfig->mPrefix.mLength, aConfig->mPreference, flags, aConfig->mStable);
+exit:
+    return error;
 }
 
 otError otBorderRouterRemoveOnMeshPrefix(otInstance *aInstance, const otIp6Prefix *aPrefix)
 {
+    otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aPrefix != NULL);
+    OT_ASSERT(aPrefix != nullptr);
 
-    return instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(aPrefix->mPrefix.mFields.m8, aPrefix->mLength);
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    error = instance.Get<BackboneRouter::Local>().RemoveDomainPrefix(*aPrefix);
+
+    if (error == OT_ERROR_NOT_FOUND)
+#endif
+    {
+        error = instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(aPrefix->mPrefix.mFields.m8, aPrefix->mLength);
+    }
+
+    return error;
 }
 
 otError otBorderRouterGetNextOnMeshPrefix(otInstance *           aInstance,
@@ -108,7 +105,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aIterator != NULL && aConfig != NULL);
+    OT_ASSERT(aIterator != nullptr && aConfig != nullptr);
 
     return instance.Get<NetworkData::Local>().GetNextOnMeshPrefix(*aIterator, *aConfig);
 }
@@ -117,7 +114,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aConfig != NULL);
+    OT_ASSERT(aConfig != nullptr);
 
     return instance.Get<NetworkData::Local>().AddHasRoutePrefix(
         aConfig->mPrefix.mPrefix.mFields.m8, aConfig->mPrefix.mLength, aConfig->mPreference, aConfig->mStable);
@@ -127,7 +124,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aPrefix != NULL);
+    OT_ASSERT(aPrefix != nullptr);
 
     return instance.Get<NetworkData::Local>().RemoveHasRoutePrefix(aPrefix->mPrefix.mFields.m8, aPrefix->mLength);
 }
@@ -138,7 +135,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aIterator != NULL && aConfig != NULL);
+    OT_ASSERT(aIterator != nullptr && aConfig != nullptr);
 
     return instance.Get<NetworkData::Local>().GetNextExternalRoute(*aIterator, *aConfig);
 }
@@ -147,7 +144,9 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<NetworkData::Local>().SendServerDataNotification();
+    instance.Get<NetworkData::Notifier>().HandleServerDataUpdated();
+
+    return OT_ERROR_NONE;
 }
 
 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
diff --git a/src/core/api/channel_monitor_api.cpp b/src/core/api/channel_monitor_api.cpp
index 19ccfe7..bb1970e 100644
--- a/src/core/api/channel_monitor_api.cpp
+++ b/src/core/api/channel_monitor_api.cpp
@@ -43,7 +43,7 @@
 
 otError otChannelMonitorSetEnabled(otInstance *aInstance, bool aEnabled)
 {
-    Utils::ChannelMonitor monitor = static_cast<Instance *>(aInstance)->Get<Utils::ChannelMonitor>();
+    Utils::ChannelMonitor &monitor = static_cast<Instance *>(aInstance)->Get<Utils::ChannelMonitor>();
 
     return aEnabled ? monitor.Start() : monitor.Stop();
 }
diff --git a/src/core/api/coap_api.cpp b/src/core/api/coap_api.cpp
index 3cd99ac..a817319 100644
--- a/src/core/api/coap_api.cpp
+++ b/src/core/api/coap_api.cpp
@@ -45,18 +45,9 @@
 
 otMessage *otCoapNewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
 {
-    Message * message;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    if (aSettings != NULL)
-    {
-        VerifyOrExit(aSettings->mPriority <= OT_MESSAGE_PRIORITY_HIGH, message = NULL);
-    }
-
-    message = instance.GetApplicationCoap().NewMessage(aSettings);
-
-exit:
-    return message;
+    return instance.GetApplicationCoap().NewMessage(Message::Settings(aSettings));
 }
 
 void otCoapMessageInit(otMessage *aMessage, otCoapType aType, otCoapCode aCode)
@@ -82,7 +73,7 @@
 
 void otCoapMessageGenerateToken(otMessage *aMessage, uint8_t aTokenLength)
 {
-    static_cast<Coap::Message *>(aMessage)->SetToken(aTokenLength);
+    IgnoreError(static_cast<Coap::Message *>(aMessage)->SetToken(aTokenLength));
 }
 
 otError otCoapMessageAppendContentFormatOption(otMessage *aMessage, otCoapOptionContentFormat aContentFormat)
@@ -110,6 +101,22 @@
     return static_cast<Coap::Message *>(aMessage)->AppendUriPathOptions(aUriPath);
 }
 
+uint16_t otCoapBlockSizeFromExponent(otCoapBlockSize aSize)
+{
+    return static_cast<uint16_t>(
+        1 << (static_cast<uint8_t>(aSize) + static_cast<uint8_t>(Coap::Message::kBlockSzxBase)));
+}
+
+otError otCoapMessageAppendBlock2Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSize aSize)
+{
+    return static_cast<Coap::Message *>(aMessage)->AppendBlockOption(Coap::Message::kBlockType2, aNum, aMore, aSize);
+}
+
+otError otCoapMessageAppendBlock1Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSize aSize)
+{
+    return static_cast<Coap::Message *>(aMessage)->AppendBlockOption(Coap::Message::kBlockType1, aNum, aMore, aSize);
+}
+
 otError otCoapMessageAppendProxyUriOption(otMessage *aMessage, const char *aUriPath)
 {
     return static_cast<Coap::Message *>(aMessage)->AppendProxyUriOption(aUriPath);
@@ -165,32 +172,58 @@
     return static_cast<Coap::OptionIterator *>(aIterator)->Init(static_cast<const Coap::Message *>(aMessage));
 }
 
+const otCoapOption *otCoapOptionIteratorGetFirstOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption)
+{
+    return static_cast<Coap::OptionIterator *>(aIterator)->GetFirstOptionMatching(aOption);
+}
+
 const otCoapOption *otCoapOptionIteratorGetFirstOption(otCoapOptionIterator *aIterator)
 {
     return static_cast<Coap::OptionIterator *>(aIterator)->GetFirstOption();
 }
 
+const otCoapOption *otCoapOptionIteratorGetNextOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption)
+{
+    return static_cast<Coap::OptionIterator *>(aIterator)->GetNextOptionMatching(aOption);
+}
+
 const otCoapOption *otCoapOptionIteratorGetNextOption(otCoapOptionIterator *aIterator)
 {
     return static_cast<Coap::OptionIterator *>(aIterator)->GetNextOption();
 }
 
+otError otCoapOptionIteratorGetOptionUintValue(otCoapOptionIterator *aIterator, uint64_t *const aValue)
+{
+    return static_cast<Coap::OptionIterator *>(aIterator)->GetOptionValue(*aValue);
+}
+
 otError otCoapOptionIteratorGetOptionValue(otCoapOptionIterator *aIterator, void *aValue)
 {
     return static_cast<Coap::OptionIterator *>(aIterator)->GetOptionValue(aValue);
 }
 
-otError otCoapSendRequest(otInstance *          aInstance,
-                          otMessage *           aMessage,
-                          const otMessageInfo * aMessageInfo,
-                          otCoapResponseHandler aHandler,
-                          void *                aContext)
+otError otCoapSendRequestWithParameters(otInstance *              aInstance,
+                                        otMessage *               aMessage,
+                                        const otMessageInfo *     aMessageInfo,
+                                        otCoapResponseHandler     aHandler,
+                                        void *                    aContext,
+                                        const otCoapTxParameters *aTxParameters)
 {
-    Instance &instance = *static_cast<Instance *>(aInstance);
+    otError                   error;
+    Instance &                instance     = *static_cast<Instance *>(aInstance);
+    const Coap::TxParameters &txParameters = Coap::TxParameters::From(aTxParameters);
 
-    return instance.GetApplicationCoap().SendMessage(*static_cast<Coap::Message *>(aMessage),
-                                                     *static_cast<const Ip6::MessageInfo *>(aMessageInfo), aHandler,
-                                                     aContext);
+    if (aTxParameters != nullptr)
+    {
+        VerifyOrExit(txParameters.IsValid(), error = OT_ERROR_INVALID_ARGS);
+    }
+
+    error = instance.GetApplicationCoap().SendMessage(*static_cast<Coap::Message *>(aMessage),
+                                                      *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
+                                                      txParameters, aHandler, aContext);
+
+exit:
+    return error;
 }
 
 otError otCoapStart(otInstance *aInstance, uint16_t aPort)
@@ -207,11 +240,11 @@
     return instance.GetApplicationCoap().Stop();
 }
 
-otError otCoapAddResource(otInstance *aInstance, otCoapResource *aResource)
+void otCoapAddResource(otInstance *aInstance, otCoapResource *aResource)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.GetApplicationCoap().AddResource(*static_cast<Coap::Resource *>(aResource));
+    instance.GetApplicationCoap().AddResource(*static_cast<Coap::Resource *>(aResource));
 }
 
 void otCoapRemoveResource(otInstance *aInstance, otCoapResource *aResource)
@@ -228,12 +261,16 @@
     instance.GetApplicationCoap().SetDefaultHandler(aHandler, aContext);
 }
 
-otError otCoapSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo)
+otError otCoapSendResponseWithParameters(otInstance *              aInstance,
+                                         otMessage *               aMessage,
+                                         const otMessageInfo *     aMessageInfo,
+                                         const otCoapTxParameters *aTxParameters)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
     return instance.GetApplicationCoap().SendMessage(*static_cast<Coap::Message *>(aMessage),
-                                                     *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
+                                                     *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
+                                                     Coap::TxParameters::From(aTxParameters), nullptr, nullptr);
 }
 
 #endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
diff --git a/src/core/api/coap_secure_api.cpp b/src/core/api/coap_secure_api.cpp
index 76e4be8..942bc78 100644
--- a/src/core/api/coap_secure_api.cpp
+++ b/src/core/api/coap_secure_api.cpp
@@ -61,7 +61,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aX509Cert != NULL && aX509Length != 0 && aPrivateKey != NULL && aPrivateKeyLength != 0);
+    OT_ASSERT(aX509Cert != nullptr && aX509Length != 0 && aPrivateKey != nullptr && aPrivateKeyLength != 0);
 
     instance.GetApplicationCoapSecure().SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
 }
@@ -72,7 +72,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aX509CaCertificateChain != NULL && aX509CaCertChainLength != 0);
+    OT_ASSERT(aX509CaCertificateChain != nullptr && aX509CaCertChainLength != 0);
 
     instance.GetApplicationCoapSecure().SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength);
 }
@@ -87,7 +87,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aPsk != NULL && aPskLength != 0 && aPskIdentity != NULL && aPskIdLength != 0);
+    OT_ASSERT(aPsk != nullptr && aPskLength != 0 && aPskIdentity != nullptr && aPskIdLength != 0);
 
     instance.GetApplicationCoapSecure().SetPreSharedKey(aPsk, aPskLength, aPskIdentity, aPskIdLength);
 }
@@ -161,11 +161,11 @@
     return instance.GetApplicationCoapSecure().SendMessage(*static_cast<Coap::Message *>(aMessage), aHandler, aContext);
 }
 
-otError otCoapSecureAddResource(otInstance *aInstance, otCoapResource *aResource)
+void otCoapSecureAddResource(otInstance *aInstance, otCoapResource *aResource)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.GetApplicationCoapSecure().AddResource(*static_cast<Coap::Resource *>(aResource));
+    instance.GetApplicationCoapSecure().AddResource(*static_cast<Coap::Resource *>(aResource));
 }
 
 void otCoapSecureRemoveResource(otInstance *aInstance, otCoapResource *aResource)
diff --git a/src/core/api/commissioner_api.cpp b/src/core/api/commissioner_api.cpp
index 9e9f382..4c0c1d5 100644
--- a/src/core/api/commissioner_api.cpp
+++ b/src/core/api/commissioner_api.cpp
@@ -46,39 +46,44 @@
                             otCommissionerJoinerCallback aJoinerCallback,
                             void *                       aCallbackContext)
 {
-    otError error;
-
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
-    SuccessOrExit(error = instance.Get<MeshCoP::BorderAgent>().Stop());
-#endif
-    SuccessOrExit(error =
-                      instance.Get<MeshCoP::Commissioner>().Start(aStateCallback, aJoinerCallback, aCallbackContext));
-exit:
-    return error;
+    return instance.Get<MeshCoP::Commissioner>().Start(aStateCallback, aJoinerCallback, aCallbackContext);
 }
 
 otError otCommissionerStop(otInstance *aInstance)
 {
-    otError   error;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    SuccessOrExit(error = instance.Get<MeshCoP::Commissioner>().Stop());
-#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
-    SuccessOrExit(error = instance.Get<MeshCoP::BorderAgent>().Start());
-#endif
+    return instance.Get<MeshCoP::Commissioner>().Stop(/* aResign */ true);
+}
+
+otError otCommissionerAddJoiner(otInstance *aInstance, const otExtAddress *aEui64, const char *aPskd, uint32_t aTimeout)
+{
+    otError                error;
+    MeshCoP::Commissioner &commissioner = static_cast<Instance *>(aInstance)->Get<MeshCoP::Commissioner>();
+
+    if (aEui64 == nullptr)
+    {
+        error = commissioner.AddJoinerAny(aPskd, aTimeout);
+        ExitNow();
+    }
+
+    error = commissioner.AddJoiner(*static_cast<const Mac::ExtAddress *>(aEui64), aPskd, aTimeout);
 
 exit:
     return error;
 }
 
-otError otCommissionerAddJoiner(otInstance *aInstance, const otExtAddress *aEui64, const char *aPskd, uint32_t aTimeout)
+otError otCommissionerAddJoinerWithDiscerner(otInstance *             aInstance,
+                                             const otJoinerDiscerner *aDiscerner,
+                                             const char *             aPskd,
+                                             uint32_t                 aTimeout)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<MeshCoP::Commissioner>().AddJoiner(static_cast<const Mac::ExtAddress *>(aEui64), aPskd,
-                                                           aTimeout);
+    return instance.Get<MeshCoP::Commissioner>().AddJoiner(*static_cast<const MeshCoP::JoinerDiscerner *>(aDiscerner),
+                                                           aPskd, aTimeout);
 }
 
 otError otCommissionerGetNextJoinerInfo(otInstance *aInstance, uint16_t *aIterator, otJoinerInfo *aJoiner)
@@ -90,9 +95,27 @@
 
 otError otCommissionerRemoveJoiner(otInstance *aInstance, const otExtAddress *aEui64)
 {
+    otError                error;
+    MeshCoP::Commissioner &commissioner = static_cast<Instance *>(aInstance)->Get<MeshCoP::Commissioner>();
+
+    if (aEui64 == nullptr)
+    {
+        error = commissioner.RemoveJoinerAny(/* aTimeout */ 0);
+        ExitNow();
+    }
+
+    error = commissioner.RemoveJoiner(*static_cast<const Mac::ExtAddress *>(aEui64), /* aTimeout */ 0);
+
+exit:
+    return error;
+}
+
+otError otCommissionerRemoveJoinerWithDiscerner(otInstance *aInstance, const otJoinerDiscerner *aDiscerner)
+{
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<MeshCoP::Commissioner>().RemoveJoiner(static_cast<const Mac::ExtAddress *>(aEui64), 0);
+    return instance.Get<MeshCoP::Commissioner>().RemoveJoiner(
+        *static_cast<const MeshCoP::JoinerDiscerner *>(aDiscerner), 0);
 }
 
 otError otCommissionerSetProvisioningUrl(otInstance *aInstance, const char *aProvisioningUrl)
@@ -181,12 +204,4 @@
     return instance.Get<MeshCoP::Commissioner>().GetState();
 }
 
-otError otCommissionerGeneratePskc(const char *           aPassPhrase,
-                                   const char *           aNetworkName,
-                                   const otExtendedPanId *aExtPanId,
-                                   otPskc *               aPskc)
-{
-    return MeshCoP::Commissioner::GeneratePskc(
-        aPassPhrase, aNetworkName, *static_cast<const Mac::ExtendedPanId *>(aExtPanId), *static_cast<Pskc *>(aPskc));
-}
 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
diff --git a/src/core/api/crypto_api.cpp b/src/core/api/crypto_api.cpp
index 835979d..9023a4b 100644
--- a/src/core/api/crypto_api.cpp
+++ b/src/core/api/crypto_api.cpp
@@ -52,7 +52,7 @@
 {
     HmacSha256 hmac;
 
-    assert((aKey != NULL) && (aBuf != NULL) && (aHash != NULL));
+    OT_ASSERT((aKey != nullptr) && (aBuf != nullptr) && (aHash != nullptr));
 
     hmac.Start(aKey, aKeyLength);
     hmac.Update(aBuf, aBufLength);
@@ -72,27 +72,22 @@
                     bool           aEncrypt,
                     void *         aTag)
 {
-    AesCcm  aesCcm;
-    uint8_t tagLength;
+    AesCcm aesCcm;
 
-    assert((aKey != NULL) && (aNonce != NULL) && (aPlainText != NULL) && (aCipherText != NULL) && (aTag != NULL));
+    OT_ASSERT((aKey != nullptr) && (aNonce != nullptr) && (aPlainText != nullptr) && (aCipherText != nullptr) &&
+              (aTag != nullptr));
 
     aesCcm.SetKey(aKey, aKeyLength);
-    SuccessOrExit(aesCcm.Init(aHeaderLength, aLength, aTagLength, aNonce, aNonceLength));
+    aesCcm.Init(aHeaderLength, aLength, aTagLength, aNonce, aNonceLength);
 
     if (aHeaderLength != 0)
     {
-        assert(aHeader != NULL);
+        OT_ASSERT(aHeader != nullptr);
         aesCcm.Header(aHeader, aHeaderLength);
     }
 
-    aesCcm.Payload(aPlainText, aCipherText, aLength, aEncrypt);
-    aesCcm.Finalize(aTag, &tagLength);
-
-    assert(aTagLength == tagLength);
-
-exit:
-    return;
+    aesCcm.Payload(aPlainText, aCipherText, aLength, aEncrypt ? AesCcm::kEncrypt : AesCcm::kDecrypt);
+    aesCcm.Finalize(aTag);
 }
 
 #if OPENTHREAD_CONFIG_ECDSA_ENABLE
@@ -104,7 +99,7 @@
                           const uint8_t *aPrivateKey,
                           uint16_t       aPrivateKeyLength)
 {
-    return Ecdsa::Sign(aOutput, aOutputLength, aInputHash, aInputHashLength, aPrivateKey, aPrivateKeyLength);
+    return Ecdsa::Sign(aOutput, *aOutputLength, aInputHash, aInputHashLength, aPrivateKey, aPrivateKeyLength);
 }
 
 #endif // OPENTHREAD_CONFIG_ECDSA_ENABLE
diff --git a/src/core/api/dataset_api.cpp b/src/core/api/dataset_api.cpp
index 463155d..a55812e 100644
--- a/src/core/api/dataset_api.cpp
+++ b/src/core/api/dataset_api.cpp
@@ -38,6 +38,7 @@
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
 #include "meshcop/dataset_manager.hpp"
+#include "meshcop/meshcop.hpp"
 
 using namespace ot;
 
@@ -60,7 +61,16 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aDataset != NULL);
+    OT_ASSERT(aDataset != nullptr);
+
+    return instance.Get<MeshCoP::ActiveDataset>().Read(*aDataset);
+}
+
+otError otDatasetGetActiveTlvs(otInstance *aInstance, otOperationalDatasetTlvs *aDataset)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    OT_ASSERT(aDataset != nullptr);
 
     return instance.Get<MeshCoP::ActiveDataset>().Read(*aDataset);
 }
@@ -69,7 +79,16 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aDataset != NULL);
+    OT_ASSERT(aDataset != nullptr);
+
+    return instance.Get<MeshCoP::ActiveDataset>().Save(*aDataset);
+}
+
+otError otDatasetSetActiveTlvs(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    OT_ASSERT(aDataset != nullptr);
 
     return instance.Get<MeshCoP::ActiveDataset>().Save(*aDataset);
 }
@@ -78,7 +97,16 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aDataset != NULL);
+    OT_ASSERT(aDataset != nullptr);
+
+    return instance.Get<MeshCoP::PendingDataset>().Read(*aDataset);
+}
+
+otError otDatasetGetPendingTlvs(otInstance *aInstance, otOperationalDatasetTlvs *aDataset)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    OT_ASSERT(aDataset != nullptr);
 
     return instance.Get<MeshCoP::PendingDataset>().Read(*aDataset);
 }
@@ -87,7 +115,16 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aDataset != NULL);
+    OT_ASSERT(aDataset != nullptr);
+
+    return instance.Get<MeshCoP::PendingDataset>().Save(*aDataset);
+}
+
+otError otDatasetSetPendingTlvs(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    OT_ASSERT(aDataset != nullptr);
 
     return instance.Get<MeshCoP::PendingDataset>().Save(*aDataset);
 }
@@ -133,3 +170,14 @@
 
     return instance.Get<MeshCoP::PendingDataset>().SendSetRequest(*aDataset, aTlvs, aLength);
 }
+
+#if OPENTHREAD_FTD
+otError otDatasetGeneratePskc(const char *           aPassPhrase,
+                              const otNetworkName *  aNetworkName,
+                              const otExtendedPanId *aExtPanId,
+                              otPskc *               aPskc)
+{
+    return MeshCoP::GeneratePskc(aPassPhrase, *static_cast<const Mac::NetworkName *>(aNetworkName),
+                                 *static_cast<const Mac::ExtendedPanId *>(aExtPanId), *static_cast<Pskc *>(aPskc));
+}
+#endif // OPENTHREAD_FTD
diff --git a/src/core/api/diags_api.cpp b/src/core/api/diags_api.cpp
index 4b35012..77f8a89 100644
--- a/src/core/api/diags_api.cpp
+++ b/src/core/api/diags_api.cpp
@@ -49,11 +49,11 @@
     instance.Get<FactoryDiags::Diags>().ProcessLine(aString, aOutput, aOutputMaxLen);
 }
 
-void otDiagProcessCmd(otInstance *aInstance, int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError otDiagProcessCmd(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    instance.Get<FactoryDiags::Diags>().ProcessCmd(aArgCount, aArgVector, aOutput, aOutputMaxLen);
+    return instance.Get<FactoryDiags::Diags>().ProcessCmd(aArgsLength, aArgs, aOutput, aOutputMaxLen);
 }
 
 bool otDiagIsEnabled(otInstance *aInstance)
diff --git a/src/core/api/heap_api.cpp b/src/core/api/heap_api.cpp
index 3810960..d921954 100644
--- a/src/core/api/heap_api.cpp
+++ b/src/core/api/heap_api.cpp
@@ -47,10 +47,10 @@
     OT_UNUSED_VARIABLE(aSize);
 
     // Should never get called!
-    assert(false);
+    OT_ASSERT(false);
 
     // This function is reachable when asserts are disabled
-    OT_UNREACHABLE_CODE(return NULL;)
+    OT_UNREACHABLE_CODE(return nullptr;)
 }
 
 void otHeapFree(void *aPointer)
@@ -58,7 +58,7 @@
     OT_UNUSED_VARIABLE(aPointer);
 
     // Should never get called!
-    assert(false);
+    OT_ASSERT(false);
 }
 
 #else // OPENTHREAD_RADIO
diff --git a/src/core/api/icmp6_api.cpp b/src/core/api/icmp6_api.cpp
index f23f18f..aaa8100 100644
--- a/src/core/api/icmp6_api.cpp
+++ b/src/core/api/icmp6_api.cpp
@@ -58,7 +58,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Ip6::Icmp>().RegisterHandler(*static_cast<Ip6::IcmpHandler *>(aHandler));
+    return instance.Get<Ip6::Icmp>().RegisterHandler(*static_cast<Ip6::Icmp::Handler *>(aHandler));
 }
 
 otError otIcmp6SendEchoRequest(otInstance *         aInstance,
diff --git a/src/core/api/ip6_api.cpp b/src/core/api/ip6_api.cpp
index faa5088..3157b1b 100644
--- a/src/core/api/ip6_api.cpp
+++ b/src/core/api/ip6_api.cpp
@@ -170,17 +170,8 @@
 otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
-    Message * message;
 
-    if (aSettings != NULL)
-    {
-        VerifyOrExit(aSettings->mPriority <= OT_MESSAGE_PRIORITY_HIGH, message = NULL);
-    }
-
-    message = instance.Get<Ip6::Ip6>().NewMessage(0, aSettings);
-
-exit:
-    return message;
+    return instance.Get<Ip6::Ip6>().NewMessage(0, Message::Settings(aSettings));
 }
 
 otMessage *otIp6NewMessageFromBuffer(otInstance *             aInstance,
@@ -191,9 +182,15 @@
     Instance &instance = *static_cast<Instance *>(aInstance);
     Message * message;
 
-    VerifyOrExit((message = instance.Get<Ip6::Ip6>().NewMessage(aData, aDataLength, aSettings)) != NULL);
+    if (aSettings != nullptr)
+    {
+        message = instance.Get<Ip6::Ip6>().NewMessage(aData, aDataLength, Message::Settings(aSettings));
+    }
+    else
+    {
+        message = instance.Get<Ip6::Ip6>().NewMessage(aData, aDataLength);
+    }
 
-exit:
     return message;
 }
 
@@ -237,7 +234,7 @@
 
 uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond)
 {
-    assert(aFirst != NULL && aSecond != NULL);
+    OT_ASSERT(aFirst != nullptr && aSecond != nullptr);
 
     return static_cast<const Ip6::Address *>(aFirst)->PrefixMatch(*static_cast<const Ip6::Address *>(aSecond));
 }
@@ -254,7 +251,7 @@
     const Ip6::NetifUnicastAddress *netifAddr;
 
     netifAddr = instance.Get<Ip6::Ip6>().SelectSourceAddress(*static_cast<Ip6::MessageInfo *>(aMessageInfo));
-    VerifyOrExit(netifAddr != NULL, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(netifAddr != nullptr, error = OT_ERROR_NOT_FOUND);
     memcpy(&aMessageInfo->mSockAddr, &netifAddr->mAddress, sizeof(aMessageInfo->mSockAddr));
 
 exit:
diff --git a/src/core/api/joiner_api.cpp b/src/core/api/joiner_api.cpp
index c2e1c49..0b35e26 100644
--- a/src/core/api/joiner_api.cpp
+++ b/src/core/api/joiner_api.cpp
@@ -71,10 +71,35 @@
     return instance.Get<MeshCoP::Joiner>().GetState();
 }
 
-void otJoinerGetId(otInstance *aInstance, otExtAddress *aJoinerId)
+const otExtAddress *otJoinerGetId(otInstance *aInstance)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    instance.Get<MeshCoP::Joiner>().GetJoinerId(*static_cast<Mac::ExtAddress *>(aJoinerId));
+    return &instance.Get<MeshCoP::Joiner>().GetId();
 }
+
+otError otJoinerSetDiscerner(otInstance *aInstance, otJoinerDiscerner *aDiscerner)
+{
+    otError          error  = OT_ERROR_NONE;
+    MeshCoP::Joiner &joiner = static_cast<Instance *>(aInstance)->Get<MeshCoP::Joiner>();
+
+    if (aDiscerner != NULL)
+    {
+        error = joiner.SetDiscerner(*static_cast<const MeshCoP::JoinerDiscerner *>(aDiscerner));
+    }
+    else
+    {
+        error = joiner.ClearDiscerner();
+    }
+
+    return error;
+}
+
+const otJoinerDiscerner *otJoinerGetDiscerner(otInstance *aInstance)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<MeshCoP::Joiner>().GetDiscerner();
+}
+
 #endif // OPENTHREAD_CONFIG_JOINER_ENABLE
diff --git a/src/core/api/link_api.cpp b/src/core/api/link_api.cpp
index 970220d..a6ea3e7 100644
--- a/src/core/api/link_api.cpp
+++ b/src/core/api/link_api.cpp
@@ -74,7 +74,7 @@
     }
 #endif
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     SuccessOrExit(error = instance.Get<Mac::Mac>().SetPanChannel(aChannel));
     instance.Get<MeshCoP::ActiveDataset>().Clear();
@@ -96,7 +96,7 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     instance.Get<Mac::Mac>().SetSupportedChannelMask(static_cast<Mac::ChannelMask>(aChannelMask));
 
@@ -116,8 +116,8 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aExtAddress != NULL);
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    OT_ASSERT(aExtAddress != nullptr);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     instance.Get<Mac::Mac>().SetExtAddress(*static_cast<const Mac::ExtAddress *>(aExtAddress));
 
@@ -146,7 +146,7 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     instance.Get<Mac::Mac>().SetPanId(aPanId);
     instance.Get<MeshCoP::ActiveDataset>().Clear();
@@ -222,32 +222,32 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mac::Filter>().GetAddressMode();
+    return static_cast<otMacFilterAddressMode>(instance.Get<Mac::Filter>().GetMode());
 }
 
-otError otLinkFilterSetAddressMode(otInstance *aInstance, otMacFilterAddressMode aMode)
+void otLinkFilterSetAddressMode(otInstance *aInstance, otMacFilterAddressMode aMode)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mac::Filter>().SetAddressMode(aMode);
+    instance.Get<Mac::Filter>().SetMode(static_cast<Mac::Filter::Mode>(aMode));
 }
 
 otError otLinkFilterAddAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aExtAddress != NULL);
+    OT_ASSERT(aExtAddress != nullptr);
 
     return instance.Get<Mac::Filter>().AddAddress(*static_cast<const Mac::ExtAddress *>(aExtAddress));
 }
 
-otError otLinkFilterRemoveAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
+void otLinkFilterRemoveAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aExtAddress != NULL);
+    OT_ASSERT(aExtAddress != nullptr);
 
-    return instance.Get<Mac::Filter>().RemoveAddress(*static_cast<const Mac::ExtAddress *>(aExtAddress));
+    instance.Get<Mac::Filter>().RemoveAddress(*static_cast<const Mac::ExtAddress *>(aExtAddress));
 }
 
 void otLinkFilterClearAddresses(otInstance *aInstance)
@@ -261,7 +261,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aIterator != NULL && aEntry != NULL);
+    OT_ASSERT(aIterator != nullptr && aEntry != nullptr);
 
     return instance.Get<Mac::Filter>().GetNextAddress(*aIterator, *aEntry);
 }
@@ -270,28 +270,46 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mac::Filter>().AddRssIn(static_cast<const Mac::ExtAddress *>(aExtAddress), aRss);
+    OT_ASSERT(aExtAddress != nullptr);
+
+    return instance.Get<Mac::Filter>().AddRssIn(*static_cast<const Mac::ExtAddress *>(aExtAddress), aRss);
 }
 
-otError otLinkFilterRemoveRssIn(otInstance *aInstance, const otExtAddress *aExtAddress)
+void otLinkFilterRemoveRssIn(otInstance *aInstance, const otExtAddress *aExtAddress)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mac::Filter>().RemoveRssIn(static_cast<const Mac::ExtAddress *>(aExtAddress));
+    OT_ASSERT(aExtAddress != nullptr);
+
+    instance.Get<Mac::Filter>().RemoveRssIn(*static_cast<const Mac::ExtAddress *>(aExtAddress));
 }
 
-void otLinkFilterClearRssIn(otInstance *aInstance)
+void otLinkFilterSetDefaultRssIn(otInstance *aInstance, int8_t aRss)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    instance.Get<Mac::Filter>().ClearRssIn();
+    instance.Get<Mac::Filter>().SetDefaultRssIn(aRss);
+}
+
+void otLinkFilterClearDefaultRssIn(otInstance *aInstance)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    instance.Get<Mac::Filter>().ClearDefaultRssIn();
+}
+
+void otLinkFilterClearAllRssIn(otInstance *aInstance)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    instance.Get<Mac::Filter>().ClearAllRssIn();
 }
 
 otError otLinkFilterGetNextRssIn(otInstance *aInstance, otMacFilterIterator *aIterator, otMacFilterEntry *aEntry)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aIterator != NULL && aEntry != NULL);
+    OT_ASSERT(aIterator != nullptr && aEntry != nullptr);
 
     return instance.Get<Mac::Filter>().GetNextRssIn(*aIterator, *aEntry);
 }
@@ -322,7 +340,7 @@
 
 const uint32_t *otLinkGetTxIndirectRetrySuccessHistogram(otInstance *aInstance, uint8_t *aNumberOfEntries)
 {
-    const uint32_t *histogram = NULL;
+    const uint32_t *histogram = nullptr;
 
 #if OPENTHREAD_FTD
     Instance &instance = *static_cast<Instance *>(aInstance);
diff --git a/src/core/api/link_raw_api.cpp b/src/core/api/link_raw_api.cpp
index bd2ec26..98d67d0 100644
--- a/src/core/api/link_raw_api.cpp
+++ b/src/core/api/link_raw_api.cpp
@@ -37,12 +37,12 @@
 #include <openthread/diag.h>
 #include <openthread/thread.h>
 #include <openthread/platform/diag.h>
+#include <openthread/platform/time.h>
 
 #include "common/debug.hpp"
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
 #include "common/random.hpp"
-#include "mac/mac.hpp"
 #include "mac/mac_frame.hpp"
 #include "utils/parse_cmdline.hpp"
 
@@ -50,9 +50,9 @@
 
 using namespace ot;
 
-otError otLinkRawSetEnable(otInstance *aInstance, bool aEnabled)
+otError otLinkRawSetReceiveDone(otInstance *aInstance, otLinkRawReceiveDone aCallback)
 {
-    return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetEnabled(aEnabled);
+    return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetReceiveDone(aCallback);
 }
 
 bool otLinkRawIsEnabled(otInstance *aInstance)
@@ -95,9 +95,9 @@
     return error;
 }
 
-otError otLinkRawReceive(otInstance *aInstance, otLinkRawReceiveDone aCallback)
+otError otLinkRawReceive(otInstance *aInstance)
 {
-    return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().Receive(aCallback);
+    return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().Receive();
 }
 
 otRadioFrame *otLinkRawGetTransmitBuffer(otInstance *aInstance)
@@ -141,7 +141,7 @@
     return error;
 }
 
-otError otLinkRawSrcMatchAddShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otLinkRawSrcMatchAddShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
@@ -169,7 +169,7 @@
     return error;
 }
 
-otError otLinkRawSrcMatchClearShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otLinkRawSrcMatchClearShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
@@ -222,6 +222,29 @@
     return error;
 }
 
+otError otLinkRawSetMacKey(otInstance *    aInstance,
+                           uint8_t         aKeyIdMode,
+                           uint8_t         aKeyId,
+                           const otMacKey *aPrevKey,
+                           const otMacKey *aCurrKey,
+                           const otMacKey *aNextKey)
+{
+    return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetMacKey(
+        aKeyIdMode, aKeyId, *static_cast<const Mac::Key *>(aPrevKey), *static_cast<const Mac::Key *>(aCurrKey),
+        *static_cast<const Mac::Key *>(aNextKey));
+}
+
+otError otLinkRawSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
+{
+    return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetMacFrameCounter(aMacFrameCounter);
+}
+
+uint64_t otLinkRawGetRadioTime(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return otPlatTimeGet();
+}
+
 #if OPENTHREAD_RADIO
 
 otDeviceRole otThreadGetDeviceRole(otInstance *aInstance)
diff --git a/src/core/api/logging_api.cpp b/src/core/api/logging_api.cpp
index 6bad81e..571ae1d 100644
--- a/src/core/api/logging_api.cpp
+++ b/src/core/api/logging_api.cpp
@@ -49,8 +49,19 @@
 }
 
 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
-void otLoggingSetLevel(otLogLevel aLogLevel)
+otError otLoggingSetLevel(otLogLevel aLogLevel)
 {
-    Instance::Get().SetLogLevel(aLogLevel);
+    otError error = OT_ERROR_NONE;
+
+    if (aLogLevel <= OT_LOG_LEVEL_DEBG && aLogLevel >= OT_LOG_LEVEL_NONE)
+    {
+        Instance::Get().SetLogLevel(aLogLevel);
+    }
+    else
+    {
+        error = OT_ERROR_INVALID_ARGS;
+    }
+
+    return error;
 }
 #endif
diff --git a/src/core/api/message_api.cpp b/src/core/api/message_api.cpp
index 511b2dc..52b7428 100644
--- a/src/core/api/message_api.cpp
+++ b/src/core/api/message_api.cpp
@@ -63,10 +63,10 @@
     return message.GetOffset();
 }
 
-otError otMessageSetOffset(otMessage *aMessage, uint16_t aOffset)
+void otMessageSetOffset(otMessage *aMessage, uint16_t aOffset)
 {
     Message &message = *static_cast<Message *>(aMessage);
-    return message.SetOffset(aOffset);
+    message.SetOffset(aOffset);
 }
 
 bool otMessageIsLinkSecurityEnabled(const otMessage *aMessage)
@@ -115,28 +115,31 @@
 
 void otMessageQueueInit(otMessageQueue *aQueue)
 {
-    aQueue->mData = NULL;
+    aQueue->mData = nullptr;
 }
 
-otError otMessageQueueEnqueue(otMessageQueue *aQueue, otMessage *aMessage)
+void otMessageQueueEnqueue(otMessageQueue *aQueue, otMessage *aMessage)
 {
     Message &     message = *static_cast<Message *>(aMessage);
     MessageQueue &queue   = *static_cast<MessageQueue *>(aQueue);
-    return queue.Enqueue(message);
+
+    queue.Enqueue(message);
 }
 
-otError otMessageQueueEnqueueAtHead(otMessageQueue *aQueue, otMessage *aMessage)
+void otMessageQueueEnqueueAtHead(otMessageQueue *aQueue, otMessage *aMessage)
 {
     Message &     message = *static_cast<Message *>(aMessage);
     MessageQueue &queue   = *static_cast<MessageQueue *>(aQueue);
-    return queue.Enqueue(message, MessageQueue::kQueuePositionHead);
+
+    queue.Enqueue(message, MessageQueue::kQueuePositionHead);
 }
 
-otError otMessageQueueDequeue(otMessageQueue *aQueue, otMessage *aMessage)
+void otMessageQueueDequeue(otMessageQueue *aQueue, otMessage *aMessage)
 {
     Message &     message = *static_cast<Message *>(aMessage);
     MessageQueue &queue   = *static_cast<MessageQueue *>(aQueue);
-    return queue.Dequeue(message);
+
+    queue.Dequeue(message);
 }
 
 otMessage *otMessageQueueGetHead(otMessageQueue *aQueue)
@@ -149,13 +152,13 @@
 {
     Message *next;
 
-    VerifyOrExit(aMessage != NULL, next = NULL);
+    VerifyOrExit(aMessage != nullptr, next = nullptr);
 
     {
         const Message &message = *static_cast<const Message *>(aMessage);
         MessageQueue & queue   = *static_cast<MessageQueue *>(aQueue);
 
-        VerifyOrExit(message.GetMessageQueue() == &queue, next = NULL);
+        VerifyOrExit(message.GetMessageQueue() == &queue, next = nullptr);
         next = message.GetNext();
     }
 
@@ -187,7 +190,12 @@
 
     instance.Get<Ip6::Ip6>().GetSendQueue().GetInfo(aBufferInfo->mIp6Messages, aBufferInfo->mIp6Buffers);
 
+#if OPENTHREAD_FTD
     instance.Get<Ip6::Mpl>().GetBufferedMessageSet().GetInfo(aBufferInfo->mMplMessages, aBufferInfo->mMplBuffers);
+#else
+    aBufferInfo->mMplMessages             = 0;
+    aBufferInfo->mMplBuffers              = 0;
+#endif
 
     instance.Get<Mle::MleRouter>().GetMessageQueue().GetInfo(aBufferInfo->mMleMessages, aBufferInfo->mMleBuffers);
 
diff --git a/src/core/api/netdata_api.cpp b/src/core/api/netdata_api.cpp
index 47c0b31..2c49c6c 100644
--- a/src/core/api/netdata_api.cpp
+++ b/src/core/api/netdata_api.cpp
@@ -44,7 +44,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aData != NULL && aDataLength != NULL);
+    OT_ASSERT(aData != nullptr && aDataLength != nullptr);
 
     return instance.Get<NetworkData::Leader>().GetNetworkData(aStable, aData, *aDataLength);
 }
@@ -94,12 +94,12 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mle::MleRouter>().GetLeaderDataTlv().GetDataVersion();
+    return instance.Get<Mle::MleRouter>().GetLeaderData().GetDataVersion();
 }
 
 uint8_t otNetDataGetStableVersion(otInstance *aInstance)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mle::MleRouter>().GetLeaderDataTlv().GetStableDataVersion();
+    return instance.Get<Mle::MleRouter>().GetLeaderData().GetStableDataVersion();
 }
diff --git a/src/core/api/netdiag_api.cpp b/src/core/api/netdiag_api.cpp
new file mode 100644
index 0000000..5b75e0e
--- /dev/null
+++ b/src/core/api/netdiag_api.cpp
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the OpenThread Network Diagnostic API.
+ */
+
+#include "openthread-core-config.h"
+
+#include <openthread/netdiag.h>
+
+#include "common/instance.hpp"
+
+using namespace ot;
+
+#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
+
+otError otThreadGetNextDiagnosticTlv(const otMessage *      aMessage,
+                                     otNetworkDiagIterator *aIterator,
+                                     otNetworkDiagTlv *     aNetworkDiagTlv)
+{
+    return NetworkDiagnostic::NetworkDiagnostic::GetNextDiagTlv(*static_cast<const Coap::Message *>(aMessage),
+                                                                *aIterator, *aNetworkDiagTlv);
+}
+
+void otThreadSetReceiveDiagnosticGetCallback(otInstance *                   aInstance,
+                                             otReceiveDiagnosticGetCallback aCallback,
+                                             void *                         aCallbackContext)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    instance.Get<NetworkDiagnostic::NetworkDiagnostic>().SetReceiveDiagnosticGetCallback(aCallback, aCallbackContext);
+}
+
+otError otThreadSendDiagnosticGet(otInstance *        aInstance,
+                                  const otIp6Address *aDestination,
+                                  const uint8_t       aTlvTypes[],
+                                  uint8_t             aCount)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<NetworkDiagnostic::NetworkDiagnostic>().SendDiagnosticGet(
+        *static_cast<const Ip6::Address *>(aDestination), aTlvTypes, aCount);
+}
+
+otError otThreadSendDiagnosticReset(otInstance *        aInstance,
+                                    const otIp6Address *aDestination,
+                                    const uint8_t       aTlvTypes[],
+                                    uint8_t             aCount)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<NetworkDiagnostic::NetworkDiagnostic>().SendDiagnosticReset(
+        *static_cast<const Ip6::Address *>(aDestination), aTlvTypes, aCount);
+}
+
+#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
diff --git a/src/core/api/network_time_api.cpp b/src/core/api/network_time_api.cpp
index 156f363..49893da 100644
--- a/src/core/api/network_time_api.cpp
+++ b/src/core/api/network_time_api.cpp
@@ -54,7 +54,7 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     instance.Get<TimeSync>().SetTimeSyncPeriod(aTimeSyncPeriod);
 
@@ -74,7 +74,7 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     instance.Get<TimeSync>().SetXtalThreshold(aXtalThreshold);
 
diff --git a/src/core/api/server_api.cpp b/src/core/api/server_api.cpp
index 4054bcc..3d01e1c 100644
--- a/src/core/api/server_api.cpp
+++ b/src/core/api/server_api.cpp
@@ -46,7 +46,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aData != NULL && aDataLength != NULL);
+    OT_ASSERT(aData != nullptr && aDataLength != nullptr);
 
     return instance.Get<NetworkData::Local>().GetNetworkData(aStable, aData, *aDataLength);
 }
@@ -88,7 +88,9 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<NetworkData::Local>().SendServerDataNotification();
+    instance.Get<NetworkData::Notifier>().HandleServerDataUpdated();
+
+    return OT_ERROR_NONE;
 }
 
 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
diff --git a/src/core/api/tasklet_api.cpp b/src/core/api/tasklet_api.cpp
index 12f63a1..fe63361 100644
--- a/src/core/api/tasklet_api.cpp
+++ b/src/core/api/tasklet_api.cpp
@@ -46,7 +46,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(otInstanceIsInitialized(aInstance));
+    VerifyOrExit(otInstanceIsInitialized(aInstance), OT_NOOP);
     instance.Get<TaskletScheduler>().ProcessQueuedTasklets();
 
 exit:
@@ -58,7 +58,7 @@
     bool      retval   = false;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(otInstanceIsInitialized(aInstance));
+    VerifyOrExit(otInstanceIsInitialized(aInstance), OT_NOOP);
     retval = instance.Get<TaskletScheduler>().AreTaskletsPending();
 
 exit:
diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp
index 4d53e4c..ca260de 100644
--- a/src/core/api/thread_api.cpp
+++ b/src/core/api/thread_api.cpp
@@ -38,7 +38,6 @@
 #include "common/debug.hpp"
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
-#include "common/logging.hpp"
 #include "common/settings.hpp"
 
 using namespace ot;
@@ -67,18 +66,16 @@
 
 otError otThreadSetExtendedPanId(otInstance *aInstance, const otExtendedPanId *aExtendedPanId)
 {
-    otError           error    = OT_ERROR_NONE;
-    Instance &        instance = *static_cast<Instance *>(aInstance);
-    otMeshLocalPrefix prefix;
+    otError                   error    = OT_ERROR_NONE;
+    Instance &                instance = *static_cast<Instance *>(aInstance);
+    const Mac::ExtendedPanId &extPanId = *static_cast<const Mac::ExtendedPanId *>(aExtendedPanId);
+    Mle::MeshLocalPrefix      prefix;
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
-    instance.Get<Mac::Mac>().SetExtendedPanId(*static_cast<const Mac::ExtendedPanId *>(aExtendedPanId));
+    instance.Get<Mac::Mac>().SetExtendedPanId(extPanId);
 
-    prefix.m8[0] = 0xfd;
-    memcpy(&prefix.m8[1], aExtendedPanId->m8, 5);
-    prefix.m8[6] = 0x00;
-    prefix.m8[7] = 0x00;
+    prefix.SetFromExtendedPanId(extPanId);
     instance.Get<Mle::MleRouter>().SetMeshLocalPrefix(prefix);
 
     instance.Get<MeshCoP::ActiveDataset>().Clear();
@@ -92,7 +89,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aLeaderRloc != NULL);
+    OT_ASSERT(aLeaderRloc != nullptr);
 
     return instance.Get<Mle::MleRouter>().GetLeaderAddress(*static_cast<Ip6::Address *>(aLeaderRloc));
 }
@@ -126,9 +123,9 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aKey != NULL);
+    OT_ASSERT(aKey != nullptr);
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     error = instance.Get<KeyManager>().SetMasterKey(*static_cast<const MasterKey *>(aKey));
     instance.Get<MeshCoP::ActiveDataset>().Clear();
@@ -164,9 +161,9 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
-    instance.Get<Mle::MleRouter>().SetMeshLocalPrefix(*aMeshLocalPrefix);
+    instance.Get<Mle::MleRouter>().SetMeshLocalPrefix(*static_cast<const Mle::MeshLocalPrefix *>(aMeshLocalPrefix));
     instance.Get<MeshCoP::ActiveDataset>().Clear();
     instance.Get<MeshCoP::PendingDataset>().Clear();
 
@@ -193,7 +190,7 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     error = instance.Get<Mac::Mac>().SetNetworkName(aNetworkName);
     instance.Get<MeshCoP::ActiveDataset>().Clear();
@@ -203,6 +200,62 @@
     return error;
 }
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+const char *otThreadGetDomainName(otInstance *aInstance)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<Mac::Mac>().GetDomainName().GetAsCString();
+}
+
+otError otThreadSetDomainName(otInstance *aInstance, const char *aDomainName)
+{
+    otError   error    = OT_ERROR_NONE;
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
+
+    error = instance.Get<Mac::Mac>().SetDomainName(aDomainName);
+
+exit:
+    return error;
+}
+
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+otError otThreadSetFixedDuaInterfaceIdentifier(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+    otError   error    = OT_ERROR_NONE;
+
+    if (aIid)
+    {
+        error = instance.Get<DuaManager>().SetFixedDuaInterfaceIdentifier(
+            *static_cast<const Ip6::InterfaceIdentifier *>(aIid));
+    }
+    else
+    {
+        instance.Get<DuaManager>().ClearFixedDuaInterfaceIdentifier();
+    }
+
+    return error;
+}
+
+const otIp6InterfaceIdentifier *otThreadGetFixedDuaInterfaceIdentifier(otInstance *aInstance)
+{
+    Instance &                      instance = *static_cast<Instance *>(aInstance);
+    const otIp6InterfaceIdentifier *iid      = nullptr;
+
+    if (instance.Get<DuaManager>().IsFixedDuaInterfaceIdentifierSet())
+    {
+        iid = &instance.Get<DuaManager>().GetFixedDuaInterfaceIdentifier();
+    }
+
+    return iid;
+}
+#endif // OPENTHREAD_CONFIG_DUA_ENABLE
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
 uint32_t otThreadGetKeySequenceCounter(otInstance *aInstance)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
@@ -249,7 +302,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert((aInfo != NULL) && (aIterator != NULL));
+    OT_ASSERT((aInfo != nullptr) && (aIterator != nullptr));
 
     return instance.Get<Mle::MleRouter>().GetNextNeighborInfo(*aIterator, *aInfo);
 }
@@ -264,31 +317,36 @@
 otError otThreadGetLeaderData(otInstance *aInstance, otLeaderData *aLeaderData)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
+    otError   error    = OT_ERROR_NONE;
 
-    assert(aLeaderData != NULL);
+    OT_ASSERT(aLeaderData != nullptr);
 
-    return instance.Get<Mle::MleRouter>().GetLeaderData(*aLeaderData);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsAttached(), error = OT_ERROR_DETACHED);
+    *aLeaderData = instance.Get<Mle::MleRouter>().GetLeaderData();
+
+exit:
+    return error;
 }
 
 uint8_t otThreadGetLeaderRouterId(otInstance *aInstance)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mle::MleRouter>().GetLeaderDataTlv().GetLeaderRouterId();
+    return instance.Get<Mle::MleRouter>().GetLeaderId();
 }
 
 uint8_t otThreadGetLeaderWeight(otInstance *aInstance)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mle::MleRouter>().GetLeaderDataTlv().GetWeighting();
+    return instance.Get<Mle::MleRouter>().GetLeaderData().GetWeighting();
 }
 
 uint32_t otThreadGetPartitionId(otInstance *aInstance)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mle::MleRouter>().GetLeaderDataTlv().GetPartitionId();
+    return instance.Get<Mle::MleRouter>().GetLeaderData().GetPartitionId();
 }
 
 uint16_t otThreadGetRloc16(otInstance *aInstance)
@@ -304,11 +362,11 @@
     otError   error    = OT_ERROR_NONE;
     Router *  parent;
 
-    assert(aParentInfo != NULL);
+    OT_ASSERT(aParentInfo != nullptr);
 
     // Reference device needs get the original parent's info even after the node state changed.
 #if !OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_CHILD, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsChild(), error = OT_ERROR_INVALID_STATE);
 #endif
 
     parent = &instance.Get<Mle::MleRouter>().GetParent();
@@ -335,7 +393,7 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aParentRssi != NULL);
+    OT_ASSERT(aParentRssi != nullptr);
 
     *aParentRssi = instance.Get<Mle::MleRouter>().GetParent().GetLinkInfo().GetAverageRss();
 
@@ -350,7 +408,7 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aLastRssi != NULL);
+    OT_ASSERT(aLastRssi != nullptr);
 
     *aLastRssi = instance.Get<Mle::MleRouter>().GetParent().GetLinkInfo().GetLastRss();
 
@@ -360,39 +418,6 @@
     return error;
 }
 
-#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
-void otThreadSetReceiveDiagnosticGetCallback(otInstance *                   aInstance,
-                                             otReceiveDiagnosticGetCallback aCallback,
-                                             void *                         aCallbackContext)
-{
-    Instance &instance = *static_cast<Instance *>(aInstance);
-
-    instance.Get<NetworkDiagnostic::NetworkDiagnostic>().SetReceiveDiagnosticGetCallback(aCallback, aCallbackContext);
-}
-
-otError otThreadSendDiagnosticGet(otInstance *        aInstance,
-                                  const otIp6Address *aDestination,
-                                  const uint8_t       aTlvTypes[],
-                                  uint8_t             aCount)
-{
-    Instance &instance = *static_cast<Instance *>(aInstance);
-
-    return instance.Get<NetworkDiagnostic::NetworkDiagnostic>().SendDiagnosticGet(
-        *static_cast<const Ip6::Address *>(aDestination), aTlvTypes, aCount);
-}
-
-otError otThreadSendDiagnosticReset(otInstance *        aInstance,
-                                    const otIp6Address *aDestination,
-                                    const uint8_t       aTlvTypes[],
-                                    uint8_t             aCount)
-{
-    Instance &instance = *static_cast<Instance *>(aInstance);
-
-    return instance.Get<NetworkDiagnostic::NetworkDiagnostic>().SendDiagnosticReset(
-        *static_cast<const Ip6::Address *>(aDestination), aTlvTypes, aCount);
-}
-#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
-
 otError otThreadSetEnabled(otInstance *aInstance, bool aEnabled)
 {
     otError   error    = OT_ERROR_NONE;
@@ -412,7 +437,7 @@
 
 uint16_t otThreadGetVersion(void)
 {
-    return OPENTHREAD_THREAD_VERSION;
+    return OPENTHREAD_CONFIG_THREAD_VERSION;
 }
 
 bool otThreadIsSingleton(otInstance *aInstance)
@@ -432,15 +457,16 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mle::MleRouter>().Discover(static_cast<Mac::ChannelMask>(aScanChannels), aPanId, aJoiner,
-                                                   aEnableEui64Filtering, aCallback, aCallbackContext);
+    return instance.Get<Mle::DiscoverScanner>().Discover(
+        static_cast<Mac::ChannelMask>(aScanChannels), aPanId, aJoiner, aEnableEui64Filtering,
+        /* aFilterIndexes (use hash of factory EUI64) */ nullptr, aCallback, aCallbackContext);
 }
 
 bool otThreadIsDiscoverInProgress(otInstance *aInstance)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Mle::MleRouter>().IsDiscoverInProgress();
+    return instance.Get<Mle::DiscoverScanner>().IsInProgress();
 }
 
 const otIpCounters *otThreadGetIp6Counters(otInstance *aInstance)
diff --git a/src/core/api/thread_ftd_api.cpp b/src/core/api/thread_ftd_api.cpp
index 4746ed9..738a265 100644
--- a/src/core/api/thread_ftd_api.cpp
+++ b/src/core/api/thread_ftd_api.cpp
@@ -39,7 +39,7 @@
 
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
-#include "thread/mle_constants.hpp"
+#include "thread/mle_types.hpp"
 #include "thread/topology.hpp"
 
 using namespace ot;
@@ -58,6 +58,22 @@
     return instance.Get<ChildTable>().SetMaxChildrenAllowed(aMaxChildren);
 }
 
+uint8_t otThreadGetMaxChildIpAddresses(otInstance *aInstance)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<Mle::MleRouter>().GetMaxChildIpAddresses();
+}
+
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
+otError otThreadSetMaxChildIpAddresses(otInstance *aInstance, uint8_t aMaxIpAddresses)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<Mle::MleRouter>().SetMaxChildIpAddresses(aMaxIpAddresses);
+}
+#endif
+
 bool otThreadIsRouterEligible(otInstance *aInstance)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
@@ -185,16 +201,16 @@
 
     switch (instance.Get<Mle::MleRouter>().GetRole())
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
+    case Mle::kRoleDisabled:
+    case Mle::kRoleDetached:
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case Mle::kRoleChild:
         error = instance.Get<Mle::MleRouter>().BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest);
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case Mle::kRoleRouter:
+    case Mle::kRoleLeader:
         error = OT_ERROR_NONE;
         break;
     }
@@ -234,14 +250,14 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    instance.Get<Mle::MleRouter>().SetRouterSelectionJitter(aRouterJitter);
+    IgnoreError(instance.Get<Mle::MleRouter>().SetRouterSelectionJitter(aRouterJitter));
 }
 
 otError otThreadGetChildInfoById(otInstance *aInstance, uint16_t aChildId, otChildInfo *aChildInfo)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aChildInfo != NULL);
+    OT_ASSERT(aChildInfo != nullptr);
 
     return instance.Get<Mle::MleRouter>().GetChildInfoById(aChildId, *aChildInfo);
 }
@@ -250,7 +266,7 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aChildInfo != NULL);
+    OT_ASSERT(aChildInfo != nullptr);
 
     return instance.Get<Mle::MleRouter>().GetChildInfoByIndex(aChildIndex, *aChildInfo);
 }
@@ -265,7 +281,7 @@
     Child::Ip6AddressIterator iterator;
     Ip6::Address *            address;
 
-    assert(aIterator != NULL && aAddress != NULL);
+    OT_ASSERT(aIterator != nullptr && aAddress != nullptr);
 
     address = static_cast<Ip6::Address *>(aAddress);
     iterator.Set(*aIterator);
@@ -295,17 +311,18 @@
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aRouterInfo != NULL);
+    OT_ASSERT(aRouterInfo != nullptr);
 
     return instance.Get<RouterTable>().GetRouterInfo(aRouterId, *aRouterInfo);
 }
 
-otError otThreadGetEidCacheEntry(otInstance *aInstance, uint8_t aIndex, otEidCacheEntry *aEntry)
+otError otThreadGetNextCacheEntry(otInstance *aInstance, otCacheEntryInfo *aEntryInfo, otCacheEntryIterator *aIterator)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    assert(aEntry != NULL);
-    return instance.Get<AddressResolver>().GetEntry(aIndex, *aEntry);
+    OT_ASSERT((aIterator != nullptr) && (aEntryInfo != nullptr));
+
+    return instance.Get<AddressResolver>().GetNextCacheEntry(*aEntryInfo, *aIterator);
 }
 
 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
@@ -329,7 +346,7 @@
     otError   error    = OT_ERROR_NONE;
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(instance.Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     instance.Get<KeyManager>().SetPskc(*static_cast<const Pskc *>(aPskc));
     instance.Get<MeshCoP::ActiveDataset>().Clear();
@@ -346,7 +363,7 @@
     return instance.Get<Mle::MleRouter>().GetAssignParentPriority();
 }
 
-otError otThreadSetParentPriority(otInstance *aInstance, const int8_t aParentPriority)
+otError otThreadSetParentPriority(otInstance *aInstance, int8_t aParentPriority)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
diff --git a/src/core/api/udp_api.cpp b/src/core/api/udp_api.cpp
index 7f286e6..bd907e7 100644
--- a/src/core/api/udp_api.cpp
+++ b/src/core/api/udp_api.cpp
@@ -45,56 +45,54 @@
 otMessage *otUdpNewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
-    Message * message;
 
-    if (aSettings != NULL)
-    {
-        VerifyOrExit(aSettings->mPriority <= OT_MESSAGE_PRIORITY_HIGH, message = NULL);
-    }
-
-    message = instance.Get<Ip6::Udp>().NewMessage(0, aSettings);
-
-exit:
-    return message;
+    return instance.Get<Ip6::Udp>().NewMessage(0, Message::Settings(aSettings));
 }
 
 otError otUdpOpen(otInstance *aInstance, otUdpSocket *aSocket, otUdpReceive aCallback, void *aContext)
 {
-    otError         error;
-    Instance &      instance = *static_cast<Instance *>(aInstance);
-    Ip6::UdpSocket &socket   = *new (aSocket) Ip6::UdpSocket(instance.Get<Ip6::Udp>());
+    Instance &instance = *static_cast<Instance *>(aInstance);
 
-    error = socket.Open(aCallback, aContext);
-
-    return error;
+    return instance.Get<Ip6::Udp>().Open(*static_cast<Ip6::Udp::SocketHandle *>(aSocket), aCallback, aContext);
 }
 
-otError otUdpClose(otUdpSocket *aSocket)
+otError otUdpClose(otInstance *aInstance, otUdpSocket *aSocket)
 {
-    otError         error  = OT_ERROR_INVALID_STATE;
-    Ip6::UdpSocket &socket = *static_cast<Ip6::UdpSocket *>(aSocket);
+    Instance &instance = *static_cast<Instance *>(aInstance);
 
-    error = socket.Close();
-
-    return error;
+    return instance.Get<Ip6::Udp>().Close(*static_cast<Ip6::Udp::SocketHandle *>(aSocket));
 }
 
-otError otUdpBind(otUdpSocket *aSocket, otSockAddr *aSockName)
+otError otUdpBind(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName)
 {
-    Ip6::UdpSocket &socket = *static_cast<Ip6::UdpSocket *>(aSocket);
-    return socket.Bind(*static_cast<const Ip6::SockAddr *>(aSockName));
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<Ip6::Udp>().Bind(*static_cast<Ip6::Udp::SocketHandle *>(aSocket),
+                                         *static_cast<const Ip6::SockAddr *>(aSockName));
 }
 
-otError otUdpConnect(otUdpSocket *aSocket, otSockAddr *aSockName)
+otError otUdpConnect(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName)
 {
-    Ip6::UdpSocket &socket = *static_cast<Ip6::UdpSocket *>(aSocket);
-    return socket.Connect(*static_cast<const Ip6::SockAddr *>(aSockName));
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<Ip6::Udp>().Connect(*static_cast<Ip6::Udp::SocketHandle *>(aSocket),
+                                            *static_cast<const Ip6::SockAddr *>(aSockName));
 }
 
-otError otUdpSend(otUdpSocket *aSocket, otMessage *aMessage, const otMessageInfo *aMessageInfo)
+otError otUdpSend(otInstance *aInstance, otUdpSocket *aSocket, otMessage *aMessage, const otMessageInfo *aMessageInfo)
 {
-    Ip6::UdpSocket &socket = *static_cast<Ip6::UdpSocket *>(aSocket);
-    return socket.SendTo(*static_cast<Message *>(aMessage), *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<Ip6::Udp>().SendTo(*static_cast<Ip6::Udp::SocketHandle *>(aSocket),
+                                           *static_cast<Message *>(aMessage),
+                                           *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
+}
+
+otUdpSocket *otUdpGetSockets(otInstance *aInstance)
+{
+    Instance &instance = *static_cast<Instance *>(aInstance);
+
+    return instance.Get<Ip6::Udp>().GetUdpSockets();
 }
 
 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
@@ -114,7 +112,7 @@
     Ip6::MessageInfo messageInfo;
     Instance &       instance = *static_cast<Instance *>(aInstance);
 
-    assert(aMessage != NULL && aPeerAddr != NULL);
+    OT_ASSERT(aMessage != nullptr && aPeerAddr != nullptr);
 
     messageInfo.SetSockAddr(instance.Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetSockPort(aSockPort);
@@ -128,27 +126,18 @@
 }
 #endif // OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
 
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-otUdpSocket *otUdpGetSockets(otInstance *aInstance)
-{
-    Instance &instance = *static_cast<Instance *>(aInstance);
-
-    return instance.Get<Ip6::Udp>().GetUdpSockets();
-}
-#endif
-
 otError otUdpAddReceiver(otInstance *aInstance, otUdpReceiver *aUdpReceiver)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Ip6::Udp>().AddReceiver(*static_cast<Ip6::UdpReceiver *>(aUdpReceiver));
+    return instance.Get<Ip6::Udp>().AddReceiver(*static_cast<Ip6::Udp::Receiver *>(aUdpReceiver));
 }
 
 otError otUdpRemoveReceiver(otInstance *aInstance, otUdpReceiver *aUdpReceiver)
 {
     Instance &instance = *static_cast<Instance *>(aInstance);
 
-    return instance.Get<Ip6::Udp>().RemoveReceiver(*static_cast<Ip6::UdpReceiver *>(aUdpReceiver));
+    return instance.Get<Ip6::Udp>().RemoveReceiver(*static_cast<Ip6::Udp::Receiver *>(aUdpReceiver));
 }
 
 otError otUdpSendDatagram(otInstance *aInstance, otMessage *aMessage, otMessageInfo *aMessageInfo)
diff --git a/src/core/backbone_router/bbr_leader.cpp b/src/core/backbone_router/bbr_leader.cpp
new file mode 100644
index 0000000..ee09bf1
--- /dev/null
+++ b/src/core/backbone_router/bbr_leader.cpp
@@ -0,0 +1,299 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements Primary Backbone Router service management in the Thread Network.
+ */
+
+#include "bbr_leader.hpp"
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
+#include "common/instance.hpp"
+#include "common/locator-getters.hpp"
+#include "common/logging.hpp"
+
+namespace ot {
+namespace BackboneRouter {
+
+Leader::Leader(Instance &aInstance)
+    : InstanceLocator(aInstance)
+{
+    Reset();
+}
+
+void Leader::Reset(void)
+{
+    // Invalid server short address indicates no available Backbone Router service in the Thread Network.
+    mConfig.mServer16 = Mac::kShortAddrInvalid;
+
+    // Domain Prefix Length 0 indicates no available Domain Prefix in the Thread network.
+    mDomainPrefix.mLength = 0;
+}
+
+otError Leader::GetConfig(BackboneRouterConfig &aConfig) const
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(HasPrimary(), error = OT_ERROR_NOT_FOUND);
+
+    aConfig = mConfig;
+
+exit:
+    return error;
+}
+
+otError Leader::GetServiceId(uint8_t &aServiceId) const
+{
+    otError error       = OT_ERROR_NONE;
+    uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter;
+
+    VerifyOrExit(HasPrimary(), error = OT_ERROR_NOT_FOUND);
+
+    error = Get<NetworkData::Leader>().GetServiceId(NetworkData::ServiceTlv::kThreadEnterpriseNumber, &serviceData,
+                                                    sizeof(serviceData), true, aServiceId);
+
+exit:
+    return error;
+}
+
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_BBR == 1)
+void Leader::LogBackboneRouterPrimary(State aState, const BackboneRouterConfig &aConfig) const
+{
+    OT_UNUSED_VARIABLE(aConfig);
+
+    otLogInfoBbr("PBBR state: %s", StateToString(aState));
+
+    if (aState != kStateRemoved && aState != kStateNone)
+    {
+        otLogInfoBbr("Rloc16: 0x%4X, seqno: %d, delay: %d, timeout %d", aConfig.mServer16, aConfig.mSequenceNumber,
+                     aConfig.mReregistrationDelay, aConfig.mMlrTimeout);
+    }
+}
+
+void Leader::LogDomainPrefix(DomainPrefixState aState, const otIp6Prefix &aPrefix) const
+{
+    otLogInfoBbr("Domain Prefix: %s/%d, state: %s",
+                 aPrefix.mLength == 0 ? ""
+                                      : static_cast<const Ip6::Address *>(&aPrefix.mPrefix)->ToString().AsCString(),
+                 aPrefix.mLength, DomainPrefixStateToString(aState));
+}
+
+const char *Leader::StateToString(State aState)
+{
+    const char *logString = "Unknown";
+
+    switch (aState)
+    {
+    case kStateNone:
+        logString = "None";
+        break;
+
+    case kStateAdded:
+        logString = "Added";
+        break;
+
+    case kStateRemoved:
+        logString = "Removed";
+        break;
+
+    case kStateToTriggerRereg:
+        logString = "Rereg triggered";
+        break;
+
+    case kStateRefreshed:
+        logString = "Refreshed";
+        break;
+
+    case kStateUnchanged:
+        logString = "Unchanged";
+        break;
+
+    default:
+        break;
+    }
+
+    return logString;
+}
+
+const char *Leader::DomainPrefixStateToString(DomainPrefixState aState)
+{
+    const char *logString = "Unknown";
+
+    switch (aState)
+    {
+    case kDomainPrefixNone:
+        logString = "None";
+        break;
+
+    case kDomainPrefixAdded:
+        logString = "Added";
+        break;
+
+    case kDomainPrefixRemoved:
+        logString = "Removed";
+        break;
+
+    case kDomainPrefixRefreshed:
+        logString = "Refreshed";
+        break;
+
+    case kDomainPrefixUnchanged:
+        logString = "Unchanged";
+        break;
+    }
+
+    return logString;
+}
+#endif
+
+void Leader::Update(void)
+{
+    UpdateBackboneRouterPrimary();
+    UpdateDomainPrefixConfig();
+}
+
+void Leader::UpdateBackboneRouterPrimary(void)
+{
+    BackboneRouterConfig config;
+    State                state;
+
+    IgnoreError(Get<NetworkData::Leader>().GetBackboneRouterPrimary(config));
+
+    if (config.mServer16 != mConfig.mServer16)
+    {
+        if (config.mServer16 == Mac::kShortAddrInvalid)
+        {
+            state = kStateRemoved;
+        }
+        else if (mConfig.mServer16 == Mac::kShortAddrInvalid)
+        {
+            state = kStateAdded;
+        }
+        else
+        {
+            // Short Address of PBBR changes.
+            state = kStateToTriggerRereg;
+        }
+    }
+    else if (config.mServer16 == Mac::kShortAddrInvalid)
+    {
+        // If no Primary all the time.
+        state = kStateNone;
+    }
+    else if (config.mSequenceNumber != mConfig.mSequenceNumber)
+    {
+        state = kStateToTriggerRereg;
+    }
+    else if (config.mReregistrationDelay != mConfig.mReregistrationDelay || config.mMlrTimeout != mConfig.mMlrTimeout)
+    {
+        state = kStateRefreshed;
+    }
+    else
+    {
+        state = kStateUnchanged;
+    }
+
+    mConfig = config;
+    LogBackboneRouterPrimary(state, mConfig);
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    Get<BackboneRouter::Local>().HandleBackboneRouterPrimaryUpdate(state, mConfig);
+#endif
+}
+
+void Leader::UpdateDomainPrefixConfig(void)
+{
+    NetworkData::Iterator           iterator = NetworkData::kIteratorInit;
+    NetworkData::OnMeshPrefixConfig config;
+    DomainPrefixState               state;
+    bool                            found = false;
+
+    while (Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, config) == OT_ERROR_NONE)
+    {
+        if (config.mDp)
+        {
+            found = true;
+            break;
+        }
+    }
+
+    if (!found)
+    {
+        if (mDomainPrefix.mLength != 0)
+        {
+            // Domain Prefix does not exist any more.
+            mDomainPrefix.mLength = 0;
+            state                 = kDomainPrefixRemoved;
+        }
+        else
+        {
+            state = kDomainPrefixNone;
+        }
+    }
+    else if (config.mPrefix.mLength == mDomainPrefix.mLength &&
+             Ip6::Address::PrefixMatch(mDomainPrefix.mPrefix.mFields.m8, config.mPrefix.mPrefix.mFields.m8,
+                                       BitVectorBytes(mDomainPrefix.mLength)) >= mDomainPrefix.mLength)
+    {
+        state = kDomainPrefixUnchanged;
+    }
+    else
+    {
+        if (mDomainPrefix.mLength == 0)
+        {
+            state = kDomainPrefixAdded;
+        }
+        else
+        {
+            state = kDomainPrefixRefreshed;
+        }
+
+        mDomainPrefix = config.mPrefix;
+    }
+
+    LogDomainPrefix(state, mDomainPrefix);
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    Get<Local>().UpdateAllDomainBackboneRouters(state);
+#endif
+
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    Get<DuaManager>().UpdateDomainUnicastAddress(state);
+#endif
+}
+
+bool Leader::IsDomainUnicast(const Ip6::Address &aAddress) const
+{
+    return HasDomainPrefix() && aAddress.PrefixMatch(mDomainPrefix.mPrefix) >= mDomainPrefix.mLength;
+}
+
+} // namespace BackboneRouter
+} // namespace ot
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
diff --git a/src/core/backbone_router/bbr_leader.hpp b/src/core/backbone_router/bbr_leader.hpp
new file mode 100644
index 0000000..5df7ac0
--- /dev/null
+++ b/src/core/backbone_router/bbr_leader.hpp
@@ -0,0 +1,193 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for Primary Backbone Router service management in the Thread Network.
+ */
+
+#ifndef BACKBONE_ROUTER_LEADER_HPP_
+#define BACKBONE_ROUTER_LEADER_HPP_
+
+#include "openthread-core-config.h"
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+#include <openthread/backbone_router.h>
+#include <openthread/ip6.h>
+
+#include "common/locator.hpp"
+#include "net/ip6_address.hpp"
+
+namespace ot {
+
+namespace BackboneRouter {
+
+typedef otBackboneRouterConfig BackboneRouterConfig;
+
+/**
+ * This class implements the basic Primary Backbone Router service operations.
+ *
+ */
+class Leader : public InstanceLocator
+{
+public:
+    // Primary Backbone Router Service state or state change.
+    enum State
+    {
+        kStateNone = 0,       ///< Not exist (trigger Backbone Router register its service).
+        kStateAdded,          ///< Newly added.
+        kStateRemoved,        ///< Newly removed (trigger Backbone Router register its service).
+        kStateToTriggerRereg, ///< Short address or sequence number changes (trigger re-registration).
+                              ///< May also have ReregistrationDelay or MlrTimeout update.
+        kStateRefreshed,      ///< Only ReregistrationDelay or MlrTimeout changes.
+        kStateUnchanged,      ///< No change on Primary Backbone Router information (only for logging).
+    };
+
+    // Domain Prefix state or state change.
+    enum DomainPrefixState
+    {
+        kDomainPrefixNone = 0,  ///< Not available.
+        kDomainPrefixAdded,     ///< Added.
+        kDomainPrefixRemoved,   ///< Removed.
+        kDomainPrefixRefreshed, ///< Changed.
+        kDomainPrefixUnchanged, ///< Nothing changed.
+    };
+
+    /**
+     * This constructor initializes the `Leader`.
+     *
+     * @param[in] aInstance  A reference to the OpenThread instance.
+     *
+     */
+    explicit Leader(Instance &aInstance);
+
+    /**
+     * This method resets the cached Primary Backbone Router.
+     *
+     */
+    void Reset(void);
+
+    /**
+     * This method updates the cached Primary Backbone Router if any when new network data is available.
+     *
+     */
+    void Update(void);
+
+    /**
+     * This method gets the Primary Backbone Router in the Thread Network.
+     *
+     * @param[out]  aConfig        The Primary Backbone Router information.
+     *
+     * @retval OT_ERROR_NONE       Successfully got the Primary Backbone Router information.
+     * @retval OT_ERROR_NOT_FOUND  No Backbone Router in the Thread Network.
+     *
+     */
+    otError GetConfig(BackboneRouterConfig &aConfig) const;
+
+    /**
+     * This method gets the Backbone Router Service ID.
+     *
+     * @param[out]  aServiceId     The reference whether to put the Backbone Router Service ID.
+     *
+     * @retval OT_ERROR_NONE       Successfully got the Backbone Router Service ID.
+     * @retval OT_ERROR_NOT_FOUND  Backbone Router service doesn't exist.
+     *
+     */
+    otError GetServiceId(uint8_t &aServiceId) const;
+
+    /**
+     * This method gets the short address of the Primary Backbone Router.
+     *
+     * @returns short address of Primary Backbone Router, or Mac::kShortAddrInvalid if no Primary Backbone Router.
+     *
+     */
+    uint16_t GetServer16(void) const { return mConfig.mServer16; }
+
+    /**
+     * This method indicates whether or not there is Primary Backbone Router.
+     *
+     * @retval TRUE if there is Primary Backbone Router, FALSE otherwise.
+     *
+     */
+    bool HasPrimary(void) const { return mConfig.mServer16 != Mac::kShortAddrInvalid; }
+
+    /**
+     * This method gets the Domain Prefix in the Thread Network.
+     *
+     * @retval A pointer to the Domain Prefix or nullptr if there is no Domain Prefix.
+     *
+     */
+    const otIp6Prefix *GetDomainPrefix(void) const { return (mDomainPrefix.mLength == 0) ? nullptr : &mDomainPrefix; }
+
+    /**
+     * This method indicates whether or not the Domain Prefix is available in the Thread Network.
+     *
+     * @retval TRUE if there is Domain Prefix, FALSE otherwise.
+     *
+     */
+    bool HasDomainPrefix(void) const { return (mDomainPrefix.mLength > 0); }
+
+    /**
+     * This method indicates whether or not the address is a Domain Unicast Address.
+     *
+     * @param[in]  aAddress A reference to the address.
+     *
+     * @retval true  @p aAddress is a domain unicast address.
+     * @retval false @p aAddress is not a domain unicast address.
+     *
+     */
+    bool IsDomainUnicast(const Ip6::Address &aAddress) const;
+
+private:
+    void UpdateBackboneRouterPrimary(void);
+    void UpdateDomainPrefixConfig(void);
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_BBR == 1)
+    void               LogBackboneRouterPrimary(State aState, const BackboneRouterConfig &aConfig) const;
+    void               LogDomainPrefix(DomainPrefixState aState, const otIp6Prefix &aPrefix) const;
+    static const char *StateToString(State aState);
+    static const char *DomainPrefixStateToString(DomainPrefixState aState);
+#else
+    void LogBackboneRouterPrimary(State, const BackboneRouterConfig &) const {}
+    void LogDomainPrefix(DomainPrefixState, const otIp6Prefix &) const {}
+#endif
+
+    BackboneRouterConfig mConfig;       ///< Primary Backbone Router information.
+    otIp6Prefix          mDomainPrefix; ///< Domain Prefix in the Thread network.
+};
+
+} // namespace BackboneRouter
+
+/**
+ * @}
+ */
+
+} // namespace ot
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
+#endif // BACKBONE_ROUTER_LEADER_HPP_
diff --git a/src/core/backbone_router/bbr_local.cpp b/src/core/backbone_router/bbr_local.cpp
new file mode 100644
index 0000000..0a9d70e
--- /dev/null
+++ b/src/core/backbone_router/bbr_local.cpp
@@ -0,0 +1,450 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements local Backbone Router service.
+ */
+
+#include "bbr_local.hpp"
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+
+#include "common/code_utils.hpp"
+#include "common/instance.hpp"
+#include "common/locator-getters.hpp"
+#include "common/logging.hpp"
+#include "common/random.hpp"
+#include "thread/mle_types.hpp"
+#include "thread/thread_netif.hpp"
+
+namespace ot {
+
+namespace BackboneRouter {
+
+Local::Local(Instance &aInstance)
+    : InstanceLocator(aInstance)
+    , mState(OT_BACKBONE_ROUTER_STATE_DISABLED)
+    , mMlrTimeout(Mle::kMlrTimeoutDefault)
+    , mReregistrationDelay(Mle::kRegistrationDelayDefault)
+    , mSequenceNumber(Random::NonCrypto::GetUint8())
+    , mRegistrationJitter(Mle::kBackboneRouterRegistrationJitter)
+    , mIsServiceAdded(false)
+{
+    mDomainPrefixConfig.mPrefix.mLength = 0;
+
+    // Primary Backbone Router Aloc
+    mBackboneRouterPrimaryAloc.Clear();
+
+    mBackboneRouterPrimaryAloc.mPrefixLength       = Mle::MeshLocalPrefix::kLength;
+    mBackboneRouterPrimaryAloc.mAddressOrigin      = OT_ADDRESS_ORIGIN_THREAD;
+    mBackboneRouterPrimaryAloc.mPreferred          = true;
+    mBackboneRouterPrimaryAloc.mValid              = true;
+    mBackboneRouterPrimaryAloc.mScopeOverride      = Ip6::Address::kRealmLocalScope;
+    mBackboneRouterPrimaryAloc.mScopeOverrideValid = true;
+    mBackboneRouterPrimaryAloc.GetAddress().GetIid().SetLocator(Mle::kAloc16BackboneRouterPrimary);
+
+    // All Network Backbone Routers Multicast Address.
+    mAllNetworkBackboneRouters.Clear();
+
+    mAllNetworkBackboneRouters.GetAddress().mFields.m8[0]  = 0xff; // Multicast
+    mAllNetworkBackboneRouters.GetAddress().mFields.m8[1]  = 0x32; // Flags = 3, Scope = 2
+    mAllNetworkBackboneRouters.GetAddress().mFields.m8[2]  = 0;    // Reserved
+    mAllNetworkBackboneRouters.GetAddress().mFields.m8[15] = 3;    // Group ID = 3
+
+    // All Domain Backbone Routers Multicast Address.
+    mAllDomainBackboneRouters.Clear();
+
+    mAllDomainBackboneRouters.GetAddress().mFields.m8[0]  = 0xff; // Multicast
+    mAllDomainBackboneRouters.GetAddress().mFields.m8[1]  = 0x32; // Flags = 3, Scope = 2
+    mAllDomainBackboneRouters.GetAddress().mFields.m8[2]  = 0;    // Reserved
+    mAllDomainBackboneRouters.GetAddress().mFields.m8[15] = 3;    // Group ID = 3
+}
+
+void Local::SetEnabled(bool aEnable)
+{
+    VerifyOrExit(aEnable == (mState == OT_BACKBONE_ROUTER_STATE_DISABLED), OT_NOOP);
+
+    if (aEnable)
+    {
+        SetState(OT_BACKBONE_ROUTER_STATE_SECONDARY);
+        AddDomainPrefixToNetworkData();
+        IgnoreError(AddService());
+    }
+    else
+    {
+        RemoveDomainPrefixFromNetworkData();
+        IgnoreError(RemoveService());
+        SetState(OT_BACKBONE_ROUTER_STATE_DISABLED);
+    }
+
+    Get<NetworkData::Notifier>().HandleServerDataUpdated();
+
+exit:
+    return;
+}
+
+void Local::Reset(void)
+{
+    VerifyOrExit(mState != OT_BACKBONE_ROUTER_STATE_DISABLED, OT_NOOP);
+
+    if (RemoveService() == OT_ERROR_NONE)
+    {
+        Get<NetworkData::Notifier>().HandleServerDataUpdated();
+    }
+
+    if (mState == OT_BACKBONE_ROUTER_STATE_PRIMARY)
+    {
+        // Increase sequence number when changing from Primary to Secondary.
+        mSequenceNumber++;
+        Get<Notifier>().Signal(kEventThreadBackboneRouterLocalChanged);
+        SetState(OT_BACKBONE_ROUTER_STATE_SECONDARY);
+    }
+
+exit:
+    return;
+}
+
+void Local::GetConfig(BackboneRouterConfig &aConfig) const
+{
+    aConfig.mSequenceNumber      = mSequenceNumber;
+    aConfig.mReregistrationDelay = mReregistrationDelay;
+    aConfig.mMlrTimeout          = mMlrTimeout;
+}
+
+otError Local::SetConfig(const BackboneRouterConfig &aConfig)
+{
+    otError error  = OT_ERROR_NONE;
+    bool    update = false;
+
+    VerifyOrExit(aConfig.mMlrTimeout >= Mle::kMlrTimeoutMin, error = OT_ERROR_INVALID_ARGS);
+    // Validate configuration according to Thread 1.2.1 Specification 5.21.3.3:
+    // "The Reregistration Delay in seconds MUST be lower than (0.5 * MLR Timeout). It MUST be at least 1."
+    VerifyOrExit(aConfig.mReregistrationDelay >= 1, error = OT_ERROR_INVALID_ARGS);
+    static_assert(sizeof(aConfig.mReregistrationDelay) < sizeof(aConfig.mMlrTimeout),
+                  "the calculation below might overflow");
+    VerifyOrExit(aConfig.mReregistrationDelay * 2 < aConfig.mMlrTimeout, error = OT_ERROR_INVALID_ARGS);
+
+    if (aConfig.mReregistrationDelay != mReregistrationDelay)
+    {
+        mReregistrationDelay = aConfig.mReregistrationDelay;
+        update               = true;
+    }
+
+    if (aConfig.mMlrTimeout != mMlrTimeout)
+    {
+        mMlrTimeout = aConfig.mMlrTimeout;
+        update      = true;
+    }
+
+    if (aConfig.mSequenceNumber != mSequenceNumber)
+    {
+        mSequenceNumber = aConfig.mSequenceNumber;
+        update          = true;
+    }
+
+    if (update)
+    {
+        Get<Notifier>().Signal(kEventThreadBackboneRouterLocalChanged);
+
+        if (AddService() == OT_ERROR_NONE)
+        {
+            Get<NetworkData::Notifier>().HandleServerDataUpdated();
+        }
+    }
+
+exit:
+    LogBackboneRouterService("Set", error);
+    return error;
+}
+
+otError Local::AddService(bool aForce)
+{
+    otError                               error       = OT_ERROR_INVALID_STATE;
+    uint8_t                               serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter;
+    NetworkData::BackboneRouterServerData serverData;
+
+    VerifyOrExit(mState != OT_BACKBONE_ROUTER_STATE_DISABLED && Get<Mle::Mle>().IsAttached(), OT_NOOP);
+
+    VerifyOrExit(aForce /* if register by force */ ||
+                     !Get<BackboneRouter::Leader>().HasPrimary() /* if no available Backbone Router service */ ||
+                     Get<BackboneRouter::Leader>().GetServer16() == Get<Mle::MleRouter>().GetRloc16()
+                 /* If the device itself should be BBR. */
+                 ,
+                 OT_NOOP);
+
+    serverData.SetSequenceNumber(mSequenceNumber);
+    serverData.SetReregistrationDelay(mReregistrationDelay);
+    serverData.SetMlrTimeout(mMlrTimeout);
+
+    SuccessOrExit(error = Get<NetworkData::Local>().AddService(
+                      NetworkData::ServiceTlv::kThreadEnterpriseNumber, &serviceData, sizeof(serviceData), true,
+                      reinterpret_cast<const uint8_t *>(&serverData), sizeof(serverData)));
+
+    mIsServiceAdded = true;
+
+exit:
+    LogBackboneRouterService("Add", error);
+    return error;
+}
+
+otError Local::RemoveService(void)
+{
+    otError error;
+    uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter;
+
+    SuccessOrExit(error = Get<NetworkData::Local>().RemoveService(NetworkData::ServiceTlv::kThreadEnterpriseNumber,
+                                                                  &serviceData, sizeof(serviceData)));
+
+    mIsServiceAdded = false;
+
+exit:
+    LogBackboneRouterService("Remove", error);
+    return error;
+}
+
+void Local::SetState(BackboneRouterState aState)
+{
+    VerifyOrExit(mState != aState, OT_NOOP);
+
+    if (mState == OT_BACKBONE_ROUTER_STATE_DISABLED)
+    {
+        // Subscribe All Network Backbone Routers Multicast Address for both Secondary and Primary state.
+        mAllNetworkBackboneRouters.GetAddress().SetMulticastNetworkPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
+        Get<ThreadNetif>().SubscribeMulticast(mAllNetworkBackboneRouters);
+    }
+    else if (aState == OT_BACKBONE_ROUTER_STATE_DISABLED)
+    {
+        Get<ThreadNetif>().UnsubscribeMulticast(mAllNetworkBackboneRouters);
+    }
+
+    if (mState == OT_BACKBONE_ROUTER_STATE_PRIMARY)
+    {
+        Get<ThreadNetif>().RemoveUnicastAddress(mBackboneRouterPrimaryAloc);
+    }
+    else if (aState == OT_BACKBONE_ROUTER_STATE_PRIMARY)
+    {
+        // Add Primary Backbone Router Aloc for Primary Backbone Router.
+        mBackboneRouterPrimaryAloc.GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
+        Get<ThreadNetif>().AddUnicastAddress(mBackboneRouterPrimaryAloc);
+    }
+
+    mState = aState;
+
+    Get<Notifier>().Signal(kEventThreadBackboneRouterStateChanged);
+
+exit:
+    return;
+}
+
+void Local::HandleBackboneRouterPrimaryUpdate(Leader::State aState, const BackboneRouterConfig &aConfig)
+{
+    OT_UNUSED_VARIABLE(aState);
+
+    VerifyOrExit(mState != OT_BACKBONE_ROUTER_STATE_DISABLED && Get<Mle::MleRouter>().IsAttached(), OT_NOOP);
+
+    // Wait some jitter before trying to Register.
+    if (aConfig.mServer16 == Mac::kShortAddrInvalid)
+    {
+        uint8_t delay = 1;
+
+        if (!Get<Mle::MleRouter>().IsLeader())
+        {
+            delay += Random::NonCrypto::GetUint8InRange(0, mRegistrationJitter < 255 ? mRegistrationJitter + 1
+                                                                                     : mRegistrationJitter);
+        }
+
+        // Here uses the timer resource in Mle.
+        Get<Mle::MleRouter>().SetBackboneRouterRegistrationDelay(delay);
+    }
+    else if (aConfig.mServer16 != Get<Mle::MleRouter>().GetRloc16())
+    {
+        Reset();
+    }
+    else if (!mIsServiceAdded)
+    {
+        // Here original PBBR restores its Backbone Router Service from Thread Network,
+        // Intentionally skips the state update as PBBR will refresh its service.
+        mSequenceNumber      = aConfig.mSequenceNumber + 1;
+        mReregistrationDelay = aConfig.mReregistrationDelay;
+        mMlrTimeout          = aConfig.mMlrTimeout;
+        Get<Notifier>().Signal(kEventThreadBackboneRouterLocalChanged);
+        if (AddService(true /* Force registration to refresh and restore Primary state */) == OT_ERROR_NONE)
+        {
+            Get<NetworkData::Notifier>().HandleServerDataUpdated();
+        }
+    }
+    else
+    {
+        SetState(OT_BACKBONE_ROUTER_STATE_PRIMARY);
+    }
+
+exit:
+    return;
+}
+
+otError Local::GetDomainPrefix(NetworkData::OnMeshPrefixConfig &aConfig)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mDomainPrefixConfig.mPrefix.mLength > 0, error = OT_ERROR_NOT_FOUND);
+
+    aConfig = mDomainPrefixConfig;
+
+exit:
+    return error;
+}
+
+otError Local::RemoveDomainPrefix(const otIp6Prefix &aPrefix)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(aPrefix.mLength > 0, error = OT_ERROR_INVALID_ARGS);
+
+    VerifyOrExit(mDomainPrefixConfig.mPrefix.mLength == aPrefix.mLength, error = OT_ERROR_NOT_FOUND);
+
+    VerifyOrExit(Ip6::Address::PrefixMatch(mDomainPrefixConfig.mPrefix.mPrefix.mFields.m8, aPrefix.mPrefix.mFields.m8,
+                                           BitVectorBytes(aPrefix.mLength)) >= aPrefix.mLength,
+                 error = OT_ERROR_NOT_FOUND);
+
+    if (IsEnabled())
+    {
+        RemoveDomainPrefixFromNetworkData();
+    }
+
+    mDomainPrefixConfig.mPrefix.mLength = 0;
+
+exit:
+    return error;
+}
+
+void Local::SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig)
+{
+    if (IsEnabled())
+    {
+        RemoveDomainPrefixFromNetworkData();
+    }
+
+    mDomainPrefixConfig = aConfig;
+    LogDomainPrefix("Set", OT_ERROR_NONE);
+
+    if (IsEnabled())
+    {
+        AddDomainPrefixToNetworkData();
+    }
+}
+
+void Local::ApplyMeshLocalPrefix(void)
+{
+    VerifyOrExit(IsEnabled(), OT_NOOP);
+
+    Get<ThreadNetif>().UnsubscribeMulticast(mAllNetworkBackboneRouters);
+    mAllNetworkBackboneRouters.GetAddress().SetMulticastNetworkPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
+    Get<ThreadNetif>().SubscribeMulticast(mAllNetworkBackboneRouters);
+
+    if (IsPrimary())
+    {
+        Get<ThreadNetif>().RemoveUnicastAddress(mBackboneRouterPrimaryAloc);
+        mBackboneRouterPrimaryAloc.GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
+        Get<ThreadNetif>().AddUnicastAddress(mBackboneRouterPrimaryAloc);
+    }
+
+exit:
+    return;
+}
+
+void Local::UpdateAllDomainBackboneRouters(Leader::DomainPrefixState aState)
+{
+    if (!IsEnabled())
+    {
+        Get<ThreadNetif>().UnsubscribeMulticast(mAllDomainBackboneRouters);
+        ExitNow();
+    }
+
+    if (aState == Leader::kDomainPrefixRemoved || aState == Leader::kDomainPrefixRefreshed)
+    {
+        Get<ThreadNetif>().UnsubscribeMulticast(mAllDomainBackboneRouters);
+    }
+
+    if (aState == Leader::kDomainPrefixAdded || aState == Leader::kDomainPrefixRefreshed)
+    {
+        mAllDomainBackboneRouters.GetAddress().SetMulticastNetworkPrefix(*Get<Leader>().GetDomainPrefix());
+        Get<ThreadNetif>().SubscribeMulticast(mAllDomainBackboneRouters);
+    }
+
+exit:
+    return;
+}
+
+void Local::RemoveDomainPrefixFromNetworkData(void)
+{
+    otError error = OT_ERROR_NOT_FOUND; // only used for logging.
+
+    if (mDomainPrefixConfig.mPrefix.mLength > 0)
+    {
+        error = Get<NetworkData::Local>().RemoveOnMeshPrefix(mDomainPrefixConfig.mPrefix.mPrefix.mFields.m8,
+                                                             mDomainPrefixConfig.mPrefix.mLength);
+    }
+
+    LogDomainPrefix("Remove", error);
+}
+
+void Local::AddDomainPrefixToNetworkData(void)
+{
+    otError error = OT_ERROR_NOT_FOUND; // only used for logging.
+
+    if (mDomainPrefixConfig.mPrefix.mLength > 0)
+    {
+        error = Get<NetworkData::Local>().AddOnMeshPrefix(mDomainPrefixConfig);
+    }
+
+    LogDomainPrefix("Add", error);
+}
+
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_BBR == 1)
+void Local::LogDomainPrefix(const char *aAction, otError aError)
+{
+    otLogInfoBbr("%s Domain Prefix: %s/%d, %s", aAction,
+                 mDomainPrefixConfig.mPrefix.mLength > 0
+                     ? (*static_cast<Ip6::Address *>(&mDomainPrefixConfig.mPrefix.mPrefix)).ToString().AsCString()
+                     : "",
+                 mDomainPrefixConfig.mPrefix.mLength, otThreadErrorToString(aError));
+}
+
+void Local::LogBackboneRouterService(const char *aAction, otError aError)
+{
+    otLogInfoBbr("%s BBR Service: seqno (%d), delay (%ds), timeout (%ds), %s", aAction, mSequenceNumber,
+                 mReregistrationDelay, mMlrTimeout, otThreadErrorToString(aError));
+}
+#endif
+
+} // namespace BackboneRouter
+
+} // namespace ot
+
+#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
diff --git a/src/core/backbone_router/bbr_local.hpp b/src/core/backbone_router/bbr_local.hpp
new file mode 100644
index 0000000..fc37c9f
--- /dev/null
+++ b/src/core/backbone_router/bbr_local.hpp
@@ -0,0 +1,278 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for local Backbone Router service.
+ */
+
+#ifndef BACKBONE_ROUTER_LOCAL_HPP_
+#define BACKBONE_ROUTER_LOCAL_HPP_
+
+#include "openthread-core-config.h"
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+#include <openthread/backbone_router.h>
+#include <openthread/backbone_router_ftd.h>
+
+#include "backbone_router/bbr_leader.hpp"
+#include "common/locator.hpp"
+#include "net/netif.hpp"
+#include "thread/network_data.hpp"
+
+namespace ot {
+
+namespace BackboneRouter {
+
+/**
+ * This class implements the definitions for local Backbone Router service.
+ *
+ */
+class Local : public InstanceLocator
+{
+public:
+    typedef otBackboneRouterState BackboneRouterState;
+
+    /**
+     * This constructor initializes the local Backbone Router.
+     *
+     * @param[in] aInstance  A reference to the OpenThread instance.
+     *
+     */
+    explicit Local(Instance &aInstance);
+
+    /**
+     * This methhod enables/disables Backbone function.
+     *
+     * @param[in]  aEnable  TRUE to enable the backbone function, FALSE otherwise.
+     *
+     */
+    void SetEnabled(bool aEnable);
+
+    /**
+     * This methhod retrieves the Backbone Router state.
+     *
+     *
+     * @retval OT_BACKBONE_ROUTER_STATE_DISABLED   Backbone function is disabled.
+     * @retval OT_BACKBONE_ROUTER_STATE_SECONDARY  Secondary Backbone Router.
+     * @retval OT_BACKBONE_ROUTER_STATE_PRIMARY    Primary Backbone Router.
+     *
+     */
+    BackboneRouterState GetState(void) const { return mState; }
+
+    /**
+     * This method resets the local Thread Network Data.
+     *
+     */
+    void Reset(void);
+
+    /**
+     * This method gets local Backbone Router configuration.
+     *
+     * @param[out]  aConfig  The local Backbone Router configuration.
+     *
+     */
+    void GetConfig(BackboneRouterConfig &aConfig) const;
+
+    /**
+     * This method sets local Backbone Router configuration.
+     *
+     * @param[in]  aConfig  The configuration to set.
+     *
+     * @retval OT_ERROR_NONE          Successfully updated configuration.
+     * @retval OT_ERROR_INVALID_ARGS  The configuration in @p aConfig is invalid.
+     *
+     */
+    otError SetConfig(const BackboneRouterConfig &aConfig);
+
+    /**
+     * This method registers Backbone Router Dataset to Leader.
+     *
+     * @param[in]  aForce True to force registration regardless of current BackboneRouterState.
+     *                    False to decide based on current BackboneRouterState.
+     *
+     *
+     * @retval OT_ERROR_NONE             Successfully added the Service entry.
+     * @retval OT_ERROR_INVALID_STATE    Not in the ready state to register.
+     * @retval OT_ERROR_NO_BUFS          Insufficient space to add the Service entry.
+     *
+     */
+    otError AddService(bool aForce = false);
+
+    /**
+     * This method indicates whether or not the Backbone Router is Primary.
+     *
+     * @retval  True  if the Backbone Router is Primary.
+     * @retval  False if the Backbone Router is not Primary.
+     *
+     */
+    bool IsPrimary(void) const { return mState == OT_BACKBONE_ROUTER_STATE_PRIMARY; }
+
+    /**
+     * This method indicates whether or not the Backbone Router is enabled.
+     *
+     * @retval  True  if the Backbone Router is enabled.
+     * @retval  False if the Backbone Router is not enabled.
+     *
+     */
+    bool IsEnabled(void) const { return mState != OT_BACKBONE_ROUTER_STATE_DISABLED; }
+
+    /**
+     * This method sets the Backbone Router registration jitter value.
+     *
+     * @param[in]  aRegistrationJitter the Backbone Router registration jitter value to set.
+     *
+     */
+    void SetRegistrationJitter(uint8_t aRegistrationJitter) { mRegistrationJitter = aRegistrationJitter; }
+
+    /**
+     * This method returns the Backbone Router registration jitter value.
+     *
+     * @returns The Backbone Router registration jitter value.
+     *
+     */
+    uint8_t GetRegistrationJitter(void) const { return mRegistrationJitter; }
+
+    /**
+     * This method notifies Primary Backbone Router status.
+     *
+     * @param[in]  aState   The state or state change of Primary Backbone Router.
+     * @param[in]  aConfig  The Primary Backbone Router service.
+     *
+     */
+    void HandleBackboneRouterPrimaryUpdate(Leader::State aState, const BackboneRouterConfig &aConfig);
+
+    /**
+     * This method gets the Domain Prefix configuration.
+     *
+     * @param[out]  aConfig  A reference to the Domain Prefix configuration.
+     *
+     * @retval OT_ERROR_NONE       Successfully got the Domain Prefix configuration.
+     * @retval OT_ERROR_NOT_FOUND  No Domain Prefix was configured.
+     *
+     */
+    otError GetDomainPrefix(NetworkData::OnMeshPrefixConfig &aConfig);
+
+    /**
+     * This method removes the local Domain Prefix configuration.
+     *
+     * @param[in]  aPrefix A reference to the IPv6 Domain Prefix.
+     *
+     * @retval OT_ERROR_NONE          Successfully removed the Domain Prefix.
+     * @retval OT_ERROR_INVALID_ARGS  @p aPrefix is invalid.
+     * @retval OT_ERROR_NOT_FOUND     No Domain Prefix was configured or @p aPrefix doesn't match.
+     *
+     */
+    otError RemoveDomainPrefix(const otIp6Prefix &aPrefix);
+
+    /**
+     * This method sets the local Domain Prefix configuration.
+     *
+     * @param[in]  aConfig A reference to the Domain Prefix configuration.
+     *
+     */
+    void SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig);
+
+    /**
+     * This method returns a reference to the All Network Backbone Routers Multicast Address.
+     *
+     * @returns A reference to the All Network Backbone Routers Multicast Address.
+     *
+     */
+    const Ip6::Address &GetAllNetworkBackboneRoutersAddress(void) const
+    {
+        return mAllNetworkBackboneRouters.GetAddress();
+    }
+
+    /**
+     * This method returns a reference to the All Domain Backbone Routers Multicast Address.
+     *
+     * @returns A reference to the All Domain Backbone Routers Multicast Address.
+     *
+     */
+    const Ip6::Address &GetAllDomainBackboneRoutersAddress(void) const
+    {
+        return mAllDomainBackboneRouters.GetAddress();
+    }
+
+    /**
+     * This method applies the Mesh Local Prefix.
+     *
+     */
+    void ApplyMeshLocalPrefix(void);
+
+    /**
+     * This method updates the subscription of All Domain Backbone Routers Multicast Address.
+     *
+     * @param[in]  aState  The Domain Prefix state or state change.
+     *
+     */
+    void UpdateAllDomainBackboneRouters(Leader::DomainPrefixState aState);
+
+private:
+    void    SetState(BackboneRouterState aState);
+    otError RemoveService(void);
+    void    AddDomainPrefixToNetworkData(void);
+    void    RemoveDomainPrefixFromNetworkData(void);
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_BBR == 1)
+    void LogBackboneRouterService(const char *aAction, otError aError);
+    void LogDomainPrefix(const char *aAction, otError aError);
+#else
+    void LogBackboneRouterService(const char *, otError) {}
+    void LogDomainPrefix(const char *, otError) {}
+#endif
+
+    BackboneRouterState mState;
+    uint32_t            mMlrTimeout;
+    uint16_t            mReregistrationDelay;
+    uint8_t             mSequenceNumber;
+    uint8_t             mRegistrationJitter;
+
+    // Indicates whether or not already add Backbone Router Service to local server data.
+    // Used to check whether or not in restore stage after reset or whether to remove
+    // Backbone Router service for Secondary Backbone Router if it was added by force.
+    bool mIsServiceAdded;
+
+    NetworkData::OnMeshPrefixConfig mDomainPrefixConfig;
+
+    Ip6::NetifUnicastAddress   mBackboneRouterPrimaryAloc;
+    Ip6::NetifMulticastAddress mAllNetworkBackboneRouters;
+    Ip6::NetifMulticastAddress mAllDomainBackboneRouters;
+};
+
+} // namespace BackboneRouter
+
+/**
+ * @}
+ */
+
+} // namespace ot
+
+#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+
+#endif // BACKBONE_ROUTER_LOCAL_HPP_
diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp
index 6bf5df2..5e34539 100644
--- a/src/core/coap/coap.cpp
+++ b/src/core/coap/coap.cpp
@@ -48,82 +48,104 @@
 
 CoapBase::CoapBase(Instance &aInstance, Sender aSender)
     : InstanceLocator(aInstance)
-    , mRetransmissionTimer(aInstance, &Coap::HandleRetransmissionTimer, this)
+    , mPendingRequests()
+    , mMessageId(Random::NonCrypto::GetUint16())
+    , mRetransmissionTimer(aInstance, Coap::HandleRetransmissionTimer, this)
     , mResources()
-    , mContext(NULL)
-    , mInterceptor(NULL)
+    , mContext(nullptr)
+    , mInterceptor(nullptr)
     , mResponsesQueue(aInstance)
-    , mDefaultHandler(NULL)
-    , mDefaultHandlerContext(NULL)
+    , mDefaultHandler(nullptr)
+    , mDefaultHandlerContext(nullptr)
     , mSender(aSender)
 {
-    mMessageId = Random::NonCrypto::GetUint16();
 }
 
 void CoapBase::ClearRequestsAndResponses(void)
 {
-    Message *    message = static_cast<Message *>(mPendingRequests.GetHead());
-    Message *    messageToRemove;
-    CoapMetadata coapMetadata;
-
-    // Remove all pending messages.
-    while (message != NULL)
-    {
-        messageToRemove = message;
-        message         = static_cast<Message *>(message->GetNext());
-
-        coapMetadata.ReadFrom(*messageToRemove);
-        FinalizeCoapTransaction(*messageToRemove, coapMetadata, NULL, NULL, OT_ERROR_ABORT);
-    }
-
+    ClearRequests(nullptr); // Clear requests matching any address.
     mResponsesQueue.DequeueAllResponses();
 }
 
-otError CoapBase::AddResource(Resource &aResource)
+void CoapBase::ClearRequests(const Ip6::Address &aAddress)
 {
-    return mResources.Add(aResource);
+    ClearRequests(&aAddress);
+}
+
+void CoapBase::ClearRequests(const Ip6::Address *aAddress)
+{
+    Message *nextMessage;
+
+    for (Message *message = mPendingRequests.GetHead(); message != nullptr; message = nextMessage)
+    {
+        Metadata metadata;
+
+        nextMessage = message->GetNextCoapMessage();
+        metadata.ReadFrom(*message);
+
+        if ((aAddress == nullptr) || (metadata.mSourceAddress == *aAddress))
+        {
+            FinalizeCoapTransaction(*message, metadata, nullptr, nullptr, OT_ERROR_ABORT);
+        }
+    }
+}
+
+void CoapBase::AddResource(Resource &aResource)
+{
+    IgnoreError(mResources.Add(aResource));
 }
 
 void CoapBase::RemoveResource(Resource &aResource)
 {
-    mResources.Remove(aResource);
-    aResource.SetNext(NULL);
+    IgnoreError(mResources.Remove(aResource));
+    aResource.SetNext(nullptr);
 }
 
-void CoapBase::SetDefaultHandler(otCoapRequestHandler aHandler, void *aContext)
+void CoapBase::SetDefaultHandler(RequestHandler aHandler, void *aContext)
 {
     mDefaultHandler        = aHandler;
     mDefaultHandlerContext = aContext;
 }
 
-Message *CoapBase::NewMessage(const otMessageSettings *aSettings)
+void CoapBase::SetInterceptor(Interceptor aInterceptor, void *aContext)
 {
-    Message *message = NULL;
+    mInterceptor = aInterceptor;
+    mContext     = aContext;
+}
 
-    VerifyOrExit((message = static_cast<Message *>(Get<Ip6::Udp>().NewMessage(0, aSettings))) != NULL);
+Message *CoapBase::NewMessage(const Message::Settings &aSettings)
+{
+    Message *message = nullptr;
+
+    VerifyOrExit((message = static_cast<Message *>(Get<Ip6::Udp>().NewMessage(0, aSettings))) != nullptr, OT_NOOP);
     message->SetOffset(0);
 
 exit:
     return message;
 }
 
+otError CoapBase::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+    return mSender(*this, aMessage, aMessageInfo);
+}
+
 otError CoapBase::SendMessage(Message &               aMessage,
                               const Ip6::MessageInfo &aMessageInfo,
-                              otCoapResponseHandler   aHandler,
+                              const TxParameters &    aTxParameters,
+                              ResponseHandler         aHandler,
                               void *                  aContext)
 {
-    otError      error;
-    CoapMetadata coapMetadata;
-    Message *    storedCopy = NULL;
-    uint16_t     copyLength = 0;
+    otError  error;
+    Message *storedCopy = nullptr;
+    uint16_t copyLength = 0;
 
     switch (aMessage.GetType())
     {
     case OT_COAP_TYPE_ACKNOWLEDGMENT:
-        mResponsesQueue.EnqueueResponse(aMessage, aMessageInfo);
+        mResponsesQueue.EnqueueResponse(aMessage, aMessageInfo, aTxParameters);
         break;
     case OT_COAP_TYPE_RESET:
-        assert(aMessage.GetCode() == OT_COAP_CODE_EMPTY);
+        OT_ASSERT(aMessage.GetCode() == OT_COAP_CODE_EMPTY);
         break;
     default:
         aMessage.SetMessageId(mMessageId++);
@@ -134,27 +156,77 @@
 
     if (aMessage.IsConfirmable())
     {
-        // Create a copy of entire message and enqueue it.
         copyLength = aMessage.GetLength();
     }
-    else if (aMessage.IsNonConfirmable() && (aHandler != NULL))
+    else if (aMessage.IsNonConfirmable() && (aHandler != nullptr))
     {
-        // As we do not retransmit non confirmable messages, create a copy of header only, for token information.
+        // As we do not retransmit non confirmable messages, create a
+        // copy of header only, for token information.
         copyLength = aMessage.GetOptionStart();
     }
 
     if (copyLength > 0)
     {
-        coapMetadata = CoapMetadata(aMessage.IsConfirmable(), aMessageInfo, aHandler, aContext);
-        VerifyOrExit((storedCopy = CopyAndEnqueueMessage(aMessage, copyLength, coapMetadata)) != NULL,
-                     error = OT_ERROR_NO_BUFS);
+        Metadata metadata;
+
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+        // Whether or not to turn on special "Observe" handling.
+        OptionIterator iterator;
+        bool           observe;
+
+        SuccessOrExit(error = iterator.Init(&aMessage));
+        observe = (iterator.GetFirstOptionMatching(OT_COAP_OPTION_OBSERVE) != nullptr);
+
+        // Special case, if we're sending a GET with Observe=1, that is a cancellation.
+        if (observe && (aMessage.GetCode() == OT_COAP_CODE_GET))
+        {
+            uint64_t observeVal = 0;
+
+            SuccessOrExit(error = iterator.GetOptionValue(observeVal));
+
+            if (observeVal == 1)
+            {
+                Metadata handlerMetadata;
+
+                // We're cancelling our subscription, so disable special-case handling on this request.
+                observe = false;
+
+                // If we can find the previous handler context, cancel that too.  Peer address
+                // and tokens, etc should all match.
+                Message *origRequest = FindRelatedRequest(aMessage, aMessageInfo, handlerMetadata);
+                if (origRequest != nullptr)
+                {
+                    FinalizeCoapTransaction(*origRequest, handlerMetadata, nullptr, nullptr, OT_ERROR_NONE);
+                }
+            }
+        }
+#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+
+        metadata.mSourceAddress            = aMessageInfo.GetSockAddr();
+        metadata.mDestinationPort          = aMessageInfo.GetPeerPort();
+        metadata.mDestinationAddress       = aMessageInfo.GetPeerAddr();
+        metadata.mResponseHandler          = aHandler;
+        metadata.mResponseContext          = aContext;
+        metadata.mRetransmissionsRemaining = aTxParameters.mMaxRetransmit;
+        metadata.mRetransmissionTimeout    = aTxParameters.CalculateInitialRetransmissionTimeout();
+        metadata.mAcknowledged             = false;
+        metadata.mConfirmable              = aMessage.IsConfirmable();
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+        metadata.mObserve = observe;
+#endif
+        metadata.mNextTimerShot =
+            TimerMilli::GetNow() +
+            (metadata.mConfirmable ? metadata.mRetransmissionTimeout : aTxParameters.CalculateMaxTransmitWait());
+
+        storedCopy = CopyAndEnqueueMessage(aMessage, copyLength, metadata);
+        VerifyOrExit(storedCopy != nullptr, error = OT_ERROR_NO_BUFS);
     }
 
     SuccessOrExit(error = Send(aMessage, aMessageInfo));
 
 exit:
 
-    if (error != OT_ERROR_NONE && storedCopy != NULL)
+    if (error != OT_ERROR_NONE && storedCopy != nullptr)
     {
         DequeueMessage(*storedCopy);
     }
@@ -162,14 +234,43 @@
     return error;
 }
 
+otError CoapBase::SendMessage(Message &               aMessage,
+                              const Ip6::MessageInfo &aMessageInfo,
+                              ResponseHandler         aHandler,
+                              void *                  aContext)
+{
+    return SendMessage(aMessage, aMessageInfo, TxParameters::GetDefault(), aHandler, aContext);
+}
+
+otError CoapBase::SendReset(Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
+{
+    return SendEmptyMessage(OT_COAP_TYPE_RESET, aRequest, aMessageInfo);
+}
+
+otError CoapBase::SendAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
+{
+    return SendEmptyMessage(OT_COAP_TYPE_ACKNOWLEDGMENT, aRequest, aMessageInfo);
+}
+
+otError CoapBase::SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
+{
+    return (aRequest.IsConfirmable() ? SendHeaderResponse(OT_COAP_CODE_CHANGED, aRequest, aMessageInfo)
+                                     : OT_ERROR_INVALID_ARGS);
+}
+
+otError CoapBase::SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
+{
+    return SendHeaderResponse(OT_COAP_CODE_NOT_FOUND, aRequest, aMessageInfo);
+}
+
 otError CoapBase::SendEmptyMessage(Message::Type aType, const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
 {
     otError  error   = OT_ERROR_NONE;
-    Message *message = NULL;
+    Message *message = nullptr;
 
-    VerifyOrExit(aRequest.GetType() == OT_COAP_TYPE_CONFIRMABLE, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aRequest.IsConfirmable(), error = OT_ERROR_INVALID_ARGS);
 
-    VerifyOrExit((message = NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     message->Init(aType, OT_COAP_CODE_EMPTY);
     message->SetMessageId(aRequest.GetMessageId());
@@ -179,7 +280,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -190,10 +291,10 @@
 otError CoapBase::SendHeaderResponse(Message::Code aCode, const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
 {
     otError  error   = OT_ERROR_NONE;
-    Message *message = NULL;
+    Message *message = nullptr;
 
     VerifyOrExit(aRequest.IsRequest(), error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit((message = NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     switch (aRequest.GetType())
     {
@@ -208,7 +309,7 @@
 
     default:
         ExitNow(error = OT_ERROR_INVALID_ARGS);
-        break;
+        OT_UNREACHABLE_CODE(break);
     }
 
     SuccessOrExit(error = message->SetToken(aRequest.GetToken(), aRequest.GetTokenLength()));
@@ -217,7 +318,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -234,46 +335,53 @@
 {
     TimeMilli        now      = TimerMilli::GetNow();
     TimeMilli        nextTime = now.GetDistantFuture();
-    CoapMetadata     coapMetadata;
-    Message *        message;
+    Metadata         metadata;
     Message *        nextMessage;
     Ip6::MessageInfo messageInfo;
 
-    for (message = static_cast<Message *>(mPendingRequests.GetHead()); message != NULL; message = nextMessage)
+    for (Message *message = mPendingRequests.GetHead(); message != nullptr; message = nextMessage)
     {
-        nextMessage = static_cast<Message *>(message->GetNext());
+        nextMessage = message->GetNextCoapMessage();
 
-        coapMetadata.ReadFrom(*message);
+        metadata.ReadFrom(*message);
 
-        if (now >= coapMetadata.mNextTimerShot)
+        if (now >= metadata.mNextTimerShot)
         {
-            if (!coapMetadata.mConfirmable || (coapMetadata.mRetransmissionCount >= kMaxRetransmit))
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+            if (message->IsRequest() && metadata.mObserve && metadata.mAcknowledged)
+            {
+                // This is a RFC7641 subscription.  Do not time out.
+                continue;
+            }
+#endif
+
+            if (!metadata.mConfirmable || (metadata.mRetransmissionsRemaining == 0))
             {
                 // No expected response or acknowledgment.
-                FinalizeCoapTransaction(*message, coapMetadata, NULL, NULL, OT_ERROR_RESPONSE_TIMEOUT);
+                FinalizeCoapTransaction(*message, metadata, nullptr, nullptr, OT_ERROR_RESPONSE_TIMEOUT);
                 continue;
             }
 
             // Increment retransmission counter and timer.
-            coapMetadata.mRetransmissionCount++;
-            coapMetadata.mRetransmissionTimeout *= 2;
-            coapMetadata.mNextTimerShot = now + coapMetadata.mRetransmissionTimeout;
-            coapMetadata.UpdateIn(*message);
+            metadata.mRetransmissionsRemaining--;
+            metadata.mRetransmissionTimeout *= 2;
+            metadata.mNextTimerShot = now + metadata.mRetransmissionTimeout;
+            metadata.UpdateIn(*message);
 
             // Retransmit
-            if (!coapMetadata.mAcknowledged)
+            if (!metadata.mAcknowledged)
             {
-                messageInfo.SetPeerAddr(coapMetadata.mDestinationAddress);
-                messageInfo.SetPeerPort(coapMetadata.mDestinationPort);
-                messageInfo.SetSockAddr(coapMetadata.mSourceAddress);
+                messageInfo.SetPeerAddr(metadata.mDestinationAddress);
+                messageInfo.SetPeerPort(metadata.mDestinationPort);
+                messageInfo.SetSockAddr(metadata.mSourceAddress);
 
                 SendCopy(*message, messageInfo);
             }
         }
 
-        if (nextTime > coapMetadata.mNextTimerShot)
+        if (nextTime > metadata.mNextTimerShot)
         {
-            nextTime = coapMetadata.mNextTimerShot;
+            nextTime = metadata.mNextTimerShot;
         }
     }
 
@@ -284,34 +392,33 @@
 }
 
 void CoapBase::FinalizeCoapTransaction(Message &               aRequest,
-                                       const CoapMetadata &    aCoapMetadata,
+                                       const Metadata &        aMetadata,
                                        Message *               aResponse,
                                        const Ip6::MessageInfo *aMessageInfo,
                                        otError                 aResult)
 {
     DequeueMessage(aRequest);
 
-    if (aCoapMetadata.mResponseHandler != NULL)
+    if (aMetadata.mResponseHandler != nullptr)
     {
-        aCoapMetadata.mResponseHandler(aCoapMetadata.mResponseContext, aResponse, aMessageInfo, aResult);
+        aMetadata.mResponseHandler(aMetadata.mResponseContext, aResponse, aMessageInfo, aResult);
     }
 }
 
-otError CoapBase::AbortTransaction(otCoapResponseHandler aHandler, void *aContext)
+otError CoapBase::AbortTransaction(ResponseHandler aHandler, void *aContext)
 {
-    otError      error = OT_ERROR_NOT_FOUND;
-    Message *    message;
-    Message *    nextMessage;
-    CoapMetadata coapMetadata;
+    otError  error = OT_ERROR_NOT_FOUND;
+    Message *nextMessage;
+    Metadata metadata;
 
-    for (message = static_cast<Message *>(mPendingRequests.GetHead()); message != NULL; message = nextMessage)
+    for (Message *message = mPendingRequests.GetHead(); message != nullptr; message = nextMessage)
     {
-        nextMessage = static_cast<Message *>(message->GetNext());
-        coapMetadata.ReadFrom(*message);
+        nextMessage = message->GetNextCoapMessage();
+        metadata.ReadFrom(*message);
 
-        if (coapMetadata.mResponseHandler == aHandler && coapMetadata.mResponseContext == aContext)
+        if (metadata.mResponseHandler == aHandler && metadata.mResponseContext == aContext)
         {
-            FinalizeCoapTransaction(*message, coapMetadata, NULL, NULL, OT_ERROR_ABORT);
+            FinalizeCoapTransaction(*message, metadata, nullptr, nullptr, OT_ERROR_ABORT);
             error = OT_ERROR_NONE;
         }
     }
@@ -319,30 +426,25 @@
     return error;
 }
 
-Message *CoapBase::CopyAndEnqueueMessage(const Message &     aMessage,
-                                         uint16_t            aCopyLength,
-                                         const CoapMetadata &aCoapMetadata)
+Message *CoapBase::CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, const Metadata &aMetadata)
 {
     otError  error       = OT_ERROR_NONE;
-    Message *messageCopy = NULL;
+    Message *messageCopy = nullptr;
 
-    // Create a message copy of requested size.
-    VerifyOrExit((messageCopy = aMessage.Clone(aCopyLength)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((messageCopy = aMessage.Clone(aCopyLength)) != nullptr, error = OT_ERROR_NO_BUFS);
 
-    // Append the copy with retransmission data.
-    SuccessOrExit(error = aCoapMetadata.AppendTo(*messageCopy));
+    SuccessOrExit(error = aMetadata.AppendTo(*messageCopy));
 
-    mRetransmissionTimer.FireAtIfEarlier(aCoapMetadata.mNextTimerShot);
+    mRetransmissionTimer.FireAtIfEarlier(aMetadata.mNextTimerShot);
 
-    // Enqueue the message.
     mPendingRequests.Enqueue(*messageCopy);
 
 exit:
 
-    if (error != OT_ERROR_NONE && messageCopy != NULL)
+    if (error != OT_ERROR_NONE && messageCopy != nullptr)
     {
         messageCopy->Free();
-        messageCopy = NULL;
+        messageCopy = nullptr;
     }
 
     return messageCopy;
@@ -352,55 +454,55 @@
 {
     mPendingRequests.Dequeue(aMessage);
 
-    if (mRetransmissionTimer.IsRunning() && (mPendingRequests.GetHead() == NULL))
+    if (mRetransmissionTimer.IsRunning() && (mPendingRequests.GetHead() == nullptr))
     {
-        // No more requests pending, stop the timer.
         mRetransmissionTimer.Stop();
     }
 
-    // Free the message memory.
     aMessage.Free();
 
     // No need to worry that the earliest pending message was removed -
     // the timer would just shoot earlier and then it'd be setup again.
 }
 
-otError CoapBase::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+void CoapBase::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError  error;
-    Message *messageCopy = NULL;
+    Message *messageCopy = nullptr;
 
     // Create a message copy for lower layers.
-    VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(CoapMetadata))) != NULL,
-                 error = OT_ERROR_NO_BUFS);
+    messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(Metadata));
+    VerifyOrExit(messageCopy != nullptr, error = OT_ERROR_NO_BUFS);
 
-    // Send the copy.
     SuccessOrExit(error = Send(*messageCopy, aMessageInfo));
 
 exit:
 
-    if (error != OT_ERROR_NONE && messageCopy != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        messageCopy->Free();
-    }
+        otLogWarnCoap("Failed to send copy: %s", otThreadErrorToString(error));
 
-    return error;
+        if (messageCopy != nullptr)
+        {
+            messageCopy->Free();
+        }
+    }
 }
 
 Message *CoapBase::FindRelatedRequest(const Message &         aResponse,
                                       const Ip6::MessageInfo &aMessageInfo,
-                                      CoapMetadata &          aCoapMetadata)
+                                      Metadata &              aMetadata)
 {
-    Message *message = static_cast<Message *>(mPendingRequests.GetHead());
+    Message *message;
 
-    while (message != NULL)
+    for (message = mPendingRequests.GetHead(); message != nullptr; message = message->GetNextCoapMessage())
     {
-        aCoapMetadata.ReadFrom(*message);
+        aMetadata.ReadFrom(*message);
 
-        if (((aCoapMetadata.mDestinationAddress == aMessageInfo.GetPeerAddr()) ||
-             aCoapMetadata.mDestinationAddress.IsMulticast() ||
-             aCoapMetadata.mDestinationAddress.IsAnycastRoutingLocator()) &&
-            (aCoapMetadata.mDestinationPort == aMessageInfo.GetPeerPort()))
+        if (((aMetadata.mDestinationAddress == aMessageInfo.GetPeerAddr()) ||
+             aMetadata.mDestinationAddress.IsMulticast() ||
+             aMetadata.mDestinationAddress.GetIid().IsAnycastLocator()) &&
+            (aMetadata.mDestinationPort == aMessageInfo.GetPeerPort()))
         {
             switch (aResponse.GetType())
             {
@@ -423,8 +525,6 @@
                 break;
             }
         }
-
-        message = static_cast<Message *>(message->GetNext());
     }
 
 exit:
@@ -438,6 +538,11 @@
     if (message.ParseHeader() != OT_ERROR_NONE)
     {
         otLogDebgCoap("Failed to parse CoAP header");
+
+        if (!aMessageInfo.GetSockAddr().IsMulticast() && message.IsConfirmable())
+        {
+            IgnoreError(SendReset(message, aMessageInfo));
+        }
     }
     else if (message.IsRequest())
     {
@@ -451,23 +556,33 @@
 
 void CoapBase::ProcessReceivedResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    CoapMetadata coapMetadata;
-    Message *    request = NULL;
-    otError      error   = OT_ERROR_NONE;
+    Metadata metadata;
+    Message *request = nullptr;
+    otError  error   = OT_ERROR_NONE;
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    bool responseObserve = false;
+#endif
 
-    request = FindRelatedRequest(aMessage, aMessageInfo, coapMetadata);
+    request = FindRelatedRequest(aMessage, aMessageInfo, metadata);
+    VerifyOrExit(request != nullptr, OT_NOOP);
 
-    if (request == NULL)
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+    if (metadata.mObserve && request->IsRequest())
     {
-        ExitNow();
+        // We sent Observe in our request, see if we received Observe in the response too.
+        OptionIterator iterator;
+
+        SuccessOrExit(error = iterator.Init(&aMessage));
+        responseObserve = (iterator.GetFirstOptionMatching(OT_COAP_OPTION_OBSERVE) != nullptr);
     }
+#endif
 
     switch (aMessage.GetType())
     {
     case OT_COAP_TYPE_RESET:
         if (aMessage.IsEmpty())
         {
-            FinalizeCoapTransaction(*request, coapMetadata, NULL, NULL, OT_ERROR_ABORT);
+            FinalizeCoapTransaction(*request, metadata, nullptr, nullptr, OT_ERROR_ABORT);
         }
 
         // Silently ignore non-empty reset messages (RFC 7252, p. 4.2).
@@ -477,22 +592,54 @@
         if (aMessage.IsEmpty())
         {
             // Empty acknowledgment.
-            if (coapMetadata.mConfirmable)
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+            if (metadata.mObserve && !request->IsRequest())
             {
-                coapMetadata.mAcknowledged = true;
-                coapMetadata.UpdateIn(*request);
+                // This is the ACK to our RFC7641 notification.  There will be no
+                // "separate" response so pass it back as if it were a piggy-backed
+                // response so we can stop re-sending and the application can move on.
+                FinalizeCoapTransaction(*request, metadata, &aMessage, &aMessageInfo, OT_ERROR_NONE);
             }
-
-            // Remove the message if response is not expected, otherwise await response.
-            if (coapMetadata.mResponseHandler == NULL)
+            else
+#endif
             {
-                DequeueMessage(*request);
+                // This is not related to RFC7641 or the outgoing "request" was not a
+                // notification.
+                if (metadata.mConfirmable)
+                {
+                    metadata.mAcknowledged = true;
+                    metadata.UpdateIn(*request);
+                }
+
+                // Remove the message if response is not expected, otherwise await
+                // response.
+                if (metadata.mResponseHandler == nullptr)
+                {
+                    DequeueMessage(*request);
+                }
             }
         }
         else if (aMessage.IsResponse() && aMessage.IsTokenEqual(*request))
         {
-            // Piggybacked response.
-            FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE);
+            // Piggybacked response.  If there's an Observe option present in both
+            // request and response, and we have a response handler; then we're
+            // dealing with RFC7641 rules here.
+            // (If there is no response handler, then we're wasting our time!)
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+            if (metadata.mObserve && responseObserve && (metadata.mResponseHandler != nullptr))
+            {
+                // This is a RFC7641 notification.  The request is *not* done!
+                metadata.mResponseHandler(metadata.mResponseContext, &aMessage, &aMessageInfo, OT_ERROR_NONE);
+
+                // Consider the message acknowledged at this point.
+                metadata.mAcknowledged = true;
+                metadata.UpdateIn(*request);
+            }
+            else
+#endif
+            {
+                FinalizeCoapTransaction(*request, metadata, &aMessage, &aMessageInfo, OT_ERROR_NONE);
+            }
         }
 
         // Silently ignore acknowledgments carrying requests (RFC 7252, p. 4.2)
@@ -501,21 +648,25 @@
 
     case OT_COAP_TYPE_CONFIRMABLE:
         // Send empty ACK if it is a CON message.
-        SendAck(aMessage, aMessageInfo);
-        FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE);
-        break;
-
+        IgnoreError(SendAck(aMessage, aMessageInfo));
+        // Fall through
+        // Handling of RFC7641 and multicast is below.
     case OT_COAP_TYPE_NON_CONFIRMABLE:
-        // Separate response.
-
-        if (coapMetadata.mDestinationAddress.IsMulticast() && coapMetadata.mResponseHandler != NULL)
+        // Separate response or observation notification.  If the request was to a multicast
+        // address, OR both the request and response carry Observe options, then this is NOT
+        // the final message, we may see multiples.
+        if ((metadata.mResponseHandler != nullptr) && (metadata.mDestinationAddress.IsMulticast()
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+                                                       || (metadata.mObserve && responseObserve)
+#endif
+                                                           ))
         {
             // If multicast non-confirmable request, allow multiple responses
-            coapMetadata.mResponseHandler(coapMetadata.mResponseContext, &aMessage, &aMessageInfo, OT_ERROR_NONE);
+            metadata.mResponseHandler(metadata.mResponseContext, &aMessage, &aMessageInfo, OT_ERROR_NONE);
         }
         else
         {
-            FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE);
+            FinalizeCoapTransaction(*request, metadata, &aMessage, &aMessageInfo, OT_ERROR_NONE);
         }
 
         break;
@@ -523,12 +674,13 @@
 
 exit:
 
-    if (error == OT_ERROR_NONE && request == NULL)
+    if (error == OT_ERROR_NONE && request == nullptr)
     {
         if (aMessage.IsConfirmable() || aMessage.IsNonConfirmable())
         {
-            // Successfully parsed a header but no matching request was found - reject the message by sending reset.
-            SendReset(aMessage, aMessageInfo);
+            // Successfully parsed a header but no matching request was
+            // found - reject the message by sending reset.
+            IgnoreError(SendReset(aMessage, aMessageInfo));
         }
     }
 }
@@ -537,11 +689,11 @@
 {
     char           uriPath[Resource::kMaxReceivedUriPath];
     char *         curUriPath     = uriPath;
-    Message *      cachedResponse = NULL;
+    Message *      cachedResponse = nullptr;
     otError        error          = OT_ERROR_NOT_FOUND;
     OptionIterator iterator;
 
-    if (mInterceptor != NULL)
+    if (mInterceptor != nullptr)
     {
         SuccessOrExit(error = mInterceptor(aMessage, aMessageInfo, mContext));
     }
@@ -551,8 +703,8 @@
     case OT_ERROR_NONE:
         cachedResponse->Finish();
         error = Send(*cachedResponse, aMessageInfo);
+
         // fall through
-        ;
 
     case OT_ERROR_NO_BUFS:
         ExitNow();
@@ -563,7 +715,7 @@
     }
 
     SuccessOrExit(error = iterator.Init(&aMessage));
-    for (const otCoapOption *option = iterator.GetFirstOption(); option != NULL; option = iterator.GetNextOption())
+    for (const otCoapOption *option = iterator.GetFirstOption(); option != nullptr; option = iterator.GetNextOption())
     {
         switch (option->mNumber)
         {
@@ -573,9 +725,9 @@
                 *curUriPath++ = '/';
             }
 
-            VerifyOrExit(option->mLength < sizeof(uriPath) - static_cast<size_t>(curUriPath + 1 - uriPath));
+            VerifyOrExit(option->mLength < sizeof(uriPath) - static_cast<size_t>(curUriPath + 1 - uriPath), OT_NOOP);
 
-            iterator.GetOptionValue(curUriPath);
+            IgnoreError(iterator.GetOptionValue(curUriPath));
             curUriPath += option->mLength;
             break;
 
@@ -610,50 +762,32 @@
 
         if (error == OT_ERROR_NOT_FOUND && !aMessageInfo.GetSockAddr().IsMulticast())
         {
-            SendNotFound(aMessage, aMessageInfo);
+            IgnoreError(SendNotFound(aMessage, aMessageInfo));
         }
 
-        if (cachedResponse != NULL)
+        if (cachedResponse != nullptr)
         {
             cachedResponse->Free();
         }
     }
 }
 
-CoapMetadata::CoapMetadata(bool                    aConfirmable,
-                           const Ip6::MessageInfo &aMessageInfo,
-                           otCoapResponseHandler   aHandler,
-                           void *                  aContext)
+void CoapBase::Metadata::ReadFrom(const Message &aMessage)
 {
-    mSourceAddress         = aMessageInfo.GetSockAddr();
-    mDestinationPort       = aMessageInfo.GetPeerPort();
-    mDestinationAddress    = aMessageInfo.GetPeerAddr();
-    mResponseHandler       = aHandler;
-    mResponseContext       = aContext;
-    mRetransmissionCount   = 0;
-    mRetransmissionTimeout = Time::SecToMsec(kAckTimeout);
-    mRetransmissionTimeout += Random::NonCrypto::GetUint32InRange(
-        0, Time::SecToMsec(kAckTimeout) * kAckRandomFactorNumerator / kAckRandomFactorDenominator -
-               Time::SecToMsec(kAckTimeout) + 1);
+    uint16_t length = aMessage.GetLength();
 
-    if (aConfirmable)
-    {
-        // Set next retransmission timeout.
-        mNextTimerShot = TimerMilli::GetNow() + mRetransmissionTimeout;
-    }
-    else
-    {
-        // Set overall response timeout.
-        mNextTimerShot = TimerMilli::GetNow() + Time::SecToMsec(kMaxTransmitWait);
-    }
+    OT_ASSERT(length >= sizeof(*this));
+    aMessage.Read(length - sizeof(*this), sizeof(*this), this);
+}
 
-    mAcknowledged = false;
-    mConfirmable  = aConfirmable;
+int CoapBase::Metadata::UpdateIn(Message &aMessage) const
+{
+    return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
 }
 
 ResponsesQueue::ResponsesQueue(Instance &aInstance)
     : mQueue()
-    , mTimer(aInstance, &ResponsesQueue::HandleTimer, this)
+    , mTimer(aInstance, ResponsesQueue::HandleTimer, this)
 {
 }
 
@@ -665,10 +799,10 @@
     const Message *cacheResponse;
 
     cacheResponse = FindMatchedResponse(aRequest, aMessageInfo);
-    VerifyOrExit(cacheResponse != NULL, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(cacheResponse != nullptr, error = OT_ERROR_NOT_FOUND);
 
-    *aResponse = cacheResponse->Clone(cacheResponse->GetLength() - sizeof(EnqueuedResponseHeader));
-    VerifyOrExit(*aResponse != NULL, error = OT_ERROR_NO_BUFS);
+    *aResponse = cacheResponse->Clone(cacheResponse->GetLength() - sizeof(ResponseMetadata));
+    VerifyOrExit(*aResponse != nullptr, error = OT_ERROR_NO_BUFS);
 
 exit:
     return error;
@@ -676,95 +810,95 @@
 
 const Message *ResponsesQueue::FindMatchedResponse(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) const
 {
-    Message *matchedResponse = NULL;
-
-    for (Message *message = static_cast<Message *>(mQueue.GetHead()); message != NULL;
-         message          = static_cast<Message *>(message->GetNext()))
-    {
-        EnqueuedResponseHeader enqueuedResponseHeader;
-        Ip6::MessageInfo       messageInfo;
-
-        enqueuedResponseHeader.ReadFrom(*message);
-        messageInfo = enqueuedResponseHeader.GetMessageInfo();
-
-        // Check source endpoint
-        if (messageInfo.GetPeerPort() != aMessageInfo.GetPeerPort())
-        {
-            continue;
-        }
-
-        if (messageInfo.GetPeerAddr() != aMessageInfo.GetPeerAddr())
-        {
-            continue;
-        }
-
-        // Check Message Id
-        if (message->GetMessageId() != aRequest.GetMessageId())
-        {
-            continue;
-        }
-
-        ExitNow(matchedResponse = message);
-    }
-
-exit:
-    return matchedResponse;
-}
-
-void ResponsesQueue::EnqueueResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
-    otError                error        = OT_ERROR_NONE;
-    Message *              responseCopy = NULL;
-    EnqueuedResponseHeader enqueuedResponseHeader(aMessageInfo);
-    uint16_t               messageCount;
-    uint16_t               bufferCount;
-
-    // return success if matched response already exists in the cache
-    VerifyOrExit(FindMatchedResponse(aMessage, aMessageInfo) == NULL);
-
-    mQueue.GetInfo(messageCount, bufferCount);
-
-    if (messageCount >= kMaxCachedResponses)
-    {
-        DequeueOldestResponse();
-    }
-
-    VerifyOrExit((responseCopy = aMessage.Clone()) != NULL);
-
-    SuccessOrExit(error = enqueuedResponseHeader.AppendTo(*responseCopy));
-    mQueue.Enqueue(*responseCopy);
-
-    if (!mTimer.IsRunning())
-    {
-        mTimer.Start(Time::SecToMsec(kExchangeLifetime));
-    }
-
-exit:
-
-    if (error != OT_ERROR_NONE && responseCopy != NULL)
-    {
-        responseCopy->Free();
-    }
-
-    return;
-}
-
-void ResponsesQueue::DequeueOldestResponse(void)
-{
     Message *message;
 
-    VerifyOrExit((message = static_cast<Message *>(mQueue.GetHead())) != NULL);
-    DequeueResponse(*message);
+    for (message = mQueue.GetHead(); message != nullptr; message = message->GetNextCoapMessage())
+    {
+        if (message->GetMessageId() == aRequest.GetMessageId())
+        {
+            ResponseMetadata metadata;
+
+            metadata.ReadFrom(*message);
+
+            if ((metadata.mMessageInfo.GetPeerPort() == aMessageInfo.GetPeerPort()) &&
+                (metadata.mMessageInfo.GetPeerAddr() == aMessageInfo.GetPeerAddr()))
+            {
+                break;
+            }
+        }
+    }
+
+    return message;
+}
+
+void ResponsesQueue::EnqueueResponse(Message &               aMessage,
+                                     const Ip6::MessageInfo &aMessageInfo,
+                                     const TxParameters &    aTxParameters)
+{
+    Message *        responseCopy;
+    ResponseMetadata metadata;
+
+    metadata.mDequeueTime = TimerMilli::GetNow() + aTxParameters.CalculateExchangeLifetime();
+    metadata.mMessageInfo = aMessageInfo;
+
+    VerifyOrExit(FindMatchedResponse(aMessage, aMessageInfo) == nullptr, OT_NOOP);
+
+    UpdateQueue();
+
+    VerifyOrExit((responseCopy = aMessage.Clone()) != nullptr, OT_NOOP);
+
+    VerifyOrExit(metadata.AppendTo(*responseCopy) == OT_ERROR_NONE, responseCopy->Free());
+
+    mQueue.Enqueue(*responseCopy);
+
+    mTimer.FireAtIfEarlier(metadata.mDequeueTime);
 
 exit:
     return;
 }
 
+void ResponsesQueue::UpdateQueue(void)
+{
+    uint16_t  msgCount    = 0;
+    Message * earliestMsg = nullptr;
+    TimeMilli earliestDequeueTime(0);
+
+    // Check the number of messages in the queue and if number is at
+    // `kMaxCachedResponses` remove the one with earliest dequeue
+    // time.
+
+    for (Message *message = mQueue.GetHead(); message != nullptr; message = message->GetNextCoapMessage())
+    {
+        ResponseMetadata metadata;
+
+        metadata.ReadFrom(*message);
+
+        if ((earliestMsg == nullptr) || (metadata.mDequeueTime < earliestDequeueTime))
+        {
+            earliestMsg         = message;
+            earliestDequeueTime = metadata.mDequeueTime;
+        }
+
+        msgCount++;
+    }
+
+    if (msgCount >= kMaxCachedResponses)
+    {
+        DequeueResponse(*earliestMsg);
+    }
+}
+
+void ResponsesQueue::DequeueResponse(Message &aMessage)
+{
+    mQueue.Dequeue(aMessage);
+    aMessage.Free();
+}
+
 void ResponsesQueue::DequeueAllResponses(void)
 {
     Message *message;
 
-    while ((message = static_cast<Message *>(mQueue.GetHead())) != NULL)
+    while ((message = mQueue.GetHead()) != nullptr)
     {
         DequeueResponse(*message);
     }
@@ -777,41 +911,110 @@
 
 void ResponsesQueue::HandleTimer(void)
 {
-    Message *              message;
-    EnqueuedResponseHeader enqueuedResponseHeader;
+    TimeMilli now             = TimerMilli::GetNow();
+    TimeMilli nextDequeueTime = now.GetDistantFuture();
+    Message * nextMessage;
 
-    while ((message = static_cast<Message *>(mQueue.GetHead())) != NULL)
+    for (Message *message = mQueue.GetHead(); message != nullptr; message = nextMessage)
     {
-        enqueuedResponseHeader.ReadFrom(*message);
+        ResponseMetadata metadata;
 
-        if (TimerMilli::GetNow() >= enqueuedResponseHeader.mDequeueTime)
+        nextMessage = message->GetNextCoapMessage();
+
+        metadata.ReadFrom(*message);
+
+        if (now >= metadata.mDequeueTime)
         {
             DequeueResponse(*message);
+            continue;
         }
-        else
+
+        if (metadata.mDequeueTime < nextDequeueTime)
         {
-            mTimer.Start(enqueuedResponseHeader.GetRemainingTime());
-            break;
+            nextDequeueTime = metadata.mDequeueTime;
         }
     }
+
+    if (nextDequeueTime < now.GetDistantFuture())
+    {
+        mTimer.FireAt(nextDequeueTime);
+    }
 }
 
-uint32_t EnqueuedResponseHeader::GetRemainingTime(void) const
+void ResponsesQueue::ResponseMetadata::ReadFrom(const Message &aMessage)
 {
-    TimeMilli now           = TimerMilli::GetNow();
-    uint32_t  remainingTime = 0;
+    uint16_t length = aMessage.GetLength();
 
-    if (mDequeueTime > now)
+    OT_ASSERT(length >= sizeof(*this));
+    aMessage.Read(length - sizeof(*this), sizeof(*this), this);
+}
+
+/// Return product of @p aValueA and @p aValueB if no overflow otherwise 0.
+static uint32_t Multiply(uint32_t aValueA, uint32_t aValueB)
+{
+    uint32_t result = 0;
+
+    VerifyOrExit(aValueA, OT_NOOP);
+
+    result = aValueA * aValueB;
+    result = (result / aValueA == aValueB) ? result : 0;
+
+exit:
+    return result;
+}
+
+bool TxParameters::IsValid(void) const
+{
+    bool rval = false;
+
+    if ((mAckRandomFactorDenominator > 0) && (mAckRandomFactorNumerator >= mAckRandomFactorDenominator) &&
+        (mAckTimeout >= OT_COAP_MIN_ACK_TIMEOUT) && (mMaxRetransmit <= OT_COAP_MAX_RETRANSMIT))
     {
-        remainingTime = mDequeueTime - now;
+        // Calulate exchange lifetime step by step and verify no overflow.
+        uint32_t tmp = Multiply(mAckTimeout, (1U << (mMaxRetransmit + 1)) - 1);
+
+        tmp /= mAckRandomFactorDenominator;
+        tmp = Multiply(tmp, mAckRandomFactorNumerator);
+
+        rval = (tmp != 0 && (tmp + mAckTimeout + 2 * kDefaultMaxLatency) > tmp);
     }
 
-    return remainingTime;
+    return rval;
 }
 
+uint32_t TxParameters::CalculateInitialRetransmissionTimeout(void) const
+{
+    return Random::NonCrypto::GetUint32InRange(
+        mAckTimeout, mAckTimeout * mAckRandomFactorNumerator / mAckRandomFactorDenominator + 1);
+}
+
+uint32_t TxParameters::CalculateExchangeLifetime(void) const
+{
+    // Final `mAckTimeout` is to account for processing delay.
+    return CalculateSpan(mMaxRetransmit) + 2 * kDefaultMaxLatency + mAckTimeout;
+}
+
+uint32_t TxParameters::CalculateMaxTransmitWait(void) const
+{
+    return CalculateSpan(mMaxRetransmit + 1);
+}
+
+uint32_t TxParameters::CalculateSpan(uint8_t aMaxRetx) const
+{
+    return static_cast<uint32_t>(mAckTimeout * ((1U << aMaxRetx) - 1) / mAckRandomFactorDenominator *
+                                 mAckRandomFactorNumerator);
+}
+
+const otCoapTxParameters TxParameters::kDefaultTxParameters = {
+    kDefaultAckTimeout,
+    kDefaultAckRandomFactorNumerator,
+    kDefaultAckRandomFactorDenominator,
+    kDefaultMaxRetransmit,
+};
+
 Coap::Coap(Instance &aInstance)
     : CoapBase(aInstance, &Coap::Send)
-    , mSocket(aInstance.Get<Ip6::Udp>())
+    , mSocket(aInstance)
 {
 }
 
@@ -822,7 +1025,7 @@
 
     sockaddr.mPort = aPort;
     SuccessOrExit(error = mSocket.Open(&Coap::HandleUdpReceive, this));
-    VerifyOrExit((error = mSocket.Bind(sockaddr)) == OT_ERROR_NONE, mSocket.Close());
+    VerifyOrExit((error = mSocket.Bind(sockaddr)) == OT_ERROR_NONE, IgnoreError(mSocket.Close()));
 
 exit:
     return error;
@@ -845,6 +1048,11 @@
                                            *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
 }
 
+otError Coap::Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+    return static_cast<Coap &>(aCoapBase).Send(aMessage, aMessageInfo);
+}
+
 otError Coap::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     return mSocket.IsBound() ? mSocket.SendTo(aMessage, aMessageInfo) : OT_ERROR_INVALID_STATE;
diff --git a/src/core/coap/coap.hpp b/src/core/coap/coap.hpp
index dc2f96a..828d91b 100644
--- a/src/core/coap/coap.hpp
+++ b/src/core/coap/coap.hpp
@@ -38,6 +38,7 @@
 #include "common/linked_list.hpp"
 #include "common/locator.hpp"
 #include "common/message.hpp"
+#include "common/non_copyable.hpp"
 #include "common/timer.hpp"
 #include "net/ip6.hpp"
 #include "net/netif.hpp"
@@ -60,116 +61,80 @@
  */
 
 /**
- * Protocol Constants (RFC 7252).
+ * This type represents a function pointer which is called when a CoAP response is received or on the request timeout.
+ *
+ * Please see otCoapResponseHandler for details.
  *
  */
-enum
-{
-    kAckTimeout                 = OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT,
-    kAckRandomFactorNumerator   = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR,
-    kAckRandomFactorDenominator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR,
-    kMaxRetransmit              = OPENTHREAD_CONFIG_COAP_MAX_RETRANSMIT,
-    kNStart                     = 1,
-    kDefaultLeisure             = 5,
-    kProbingRate                = 1,
-
-    // Note that 2 << (kMaxRetransmit - 1) is equal to kMaxRetransmit power of 2
-    kMaxTransmitSpan =
-        kAckTimeout * ((2 << (kMaxRetransmit - 1)) - 1) * kAckRandomFactorNumerator / kAckRandomFactorDenominator,
-    kMaxTransmitWait =
-        kAckTimeout * ((2 << kMaxRetransmit) - 1) * kAckRandomFactorNumerator / kAckRandomFactorDenominator,
-    kMaxLatency       = 100,
-    kProcessingDelay  = kAckTimeout,
-    kMaxRtt           = 2 * kMaxLatency + kProcessingDelay,
-    kExchangeLifetime = kMaxTransmitSpan + 2 * (kMaxLatency) + kProcessingDelay,
-    kNonLifetime      = kMaxTransmitSpan + kMaxLatency
-};
+typedef otCoapResponseHandler ResponseHandler;
 
 /**
- * This class implements metadata required for CoAP retransmission.
+ * This type represents a function pointer which is called when a CoAP request associated with a given URI path is
+ * received.
+ *
+ * Please see otCoapRequestHandler for details.
  *
  */
-class CoapMetadata
+typedef otCoapRequestHandler RequestHandler;
+
+/**
+ * This structure represents the CoAP transmission parameters.
+ *
+ */
+class TxParameters : public otCoapTxParameters
 {
     friend class CoapBase;
+    friend class ResponsesQueue;
 
 public:
     /**
-     * Default constructor for the object.
+     * This static method coverts a pointer to `otCoapTxParameters` to `Coap::TxParamters`
+     *
+     * If the pointer is nullptr, the default parameters are used instead.
+     *
+     * @param[in] aTxParameters   A pointer to tx parameter.
+     *
+     * @returns A reference to corresponding `TxParamters` if  @p aTxParameters is not nullptr, otherwise the default tx
+     * parameters.
      *
      */
-    CoapMetadata(void)
-        : mDestinationPort(0)
-        , mResponseHandler(NULL)
-        , mResponseContext(NULL)
-        , mNextTimerShot(0)
-        , mRetransmissionTimeout(0)
-        , mRetransmissionCount(0)
-        , mAcknowledged(false)
-        , mConfirmable(false){};
-
-    /**
-     * This constructor initializes the object with specific values.
-     *
-     * @param[in]  aConfirmable  Information if the request is confirmable or not.
-     * @param[in]  aMessageInfo  Addressing information.
-     * @param[in]  aHandler      Pointer to a handler function for the response.
-     * @param[in]  aContext      Context for the handler function.
-     *
-     */
-    CoapMetadata(bool                    aConfirmable,
-                 const Ip6::MessageInfo &aMessageInfo,
-                 otCoapResponseHandler   aHandler,
-                 void *                  aContext);
-
-    /**
-     * This method appends request data to the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     * @retval OT_ERROR_NONE     Successfully appended the bytes.
-     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
-     *
-     */
-    otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
-
-    /**
-     * This method reads request data from the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     */
-    void ReadFrom(const Message &aMessage)
+    static const TxParameters &From(const otCoapTxParameters *aTxParameters)
     {
-        uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-        assert(length == sizeof(*this));
-        OT_UNUSED_VARIABLE(length);
+        return aTxParameters ? *static_cast<const TxParameters *>(aTxParameters) : GetDefault();
     }
 
     /**
-     * This method updates request data in the message.
+     * This method validates whether the CoAP transmission parameters are valid.
      *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     * @returns The number of bytes updated.
+     * @returns Whether the parameters are valid.
      *
      */
-    int UpdateIn(Message &aMessage) const
-    {
-        return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-    }
+    bool IsValid(void) const;
+
+    /**
+     * This static method returns default CoAP tx parameters.
+     *
+     * @returns The default tx parameters.
+     *
+     */
+    static const TxParameters &GetDefault(void) { return static_cast<const TxParameters &>(kDefaultTxParameters); }
 
 private:
-    Ip6::Address          mSourceAddress;         ///< IPv6 address of the message source.
-    Ip6::Address          mDestinationAddress;    ///< IPv6 address of the message destination.
-    uint16_t              mDestinationPort;       ///< UDP port of the message destination.
-    otCoapResponseHandler mResponseHandler;       ///< A function pointer that is called on response reception.
-    void *                mResponseContext;       ///< A pointer to arbitrary context information.
-    TimeMilli             mNextTimerShot;         ///< Time when the timer should shoot for this message.
-    uint32_t              mRetransmissionTimeout; ///< Delay that is applied to next retransmission.
-    uint8_t               mRetransmissionCount;   ///< Number of retransmissions.
-    bool                  mAcknowledged : 1;      ///< Information that request was acknowledged.
-    bool                  mConfirmable : 1;       ///< Information that message is confirmable.
+    enum
+    {
+        kDefaultAckTimeout                 = 2000, // in millisecond
+        kDefaultAckRandomFactorNumerator   = 3,
+        kDefaultAckRandomFactorDenominator = 2,
+        kDefaultMaxRetransmit              = 4,
+        kDefaultMaxLatency                 = 100000, // in millisecond
+    };
+
+    uint32_t CalculateInitialRetransmissionTimeout(void) const;
+    uint32_t CalculateExchangeLifetime(void) const;
+    uint32_t CalculateMaxTransmitWait(void) const;
+    uint32_t CalculateSpan(uint8_t aMaxRetx) const;
+
+    static const otCoapTxParameters kDefaultTxParameters;
 };
 
 /**
@@ -189,22 +154,22 @@
     /**
      * This constructor initializes the resource.
      *
-     * @param[in]  aUriPath  A pointer to a NULL-terminated string for the Uri-Path.
+     * @param[in]  aUriPath  A pointer to a null-terminated string for the URI path.
      * @param[in]  aHandler  A function pointer that is called when receiving a CoAP message for @p aUriPath.
      * @param[in]  aContext  A pointer to arbitrary context information.
      */
-    Resource(const char *aUriPath, otCoapRequestHandler aHandler, void *aContext)
+    Resource(const char *aUriPath, RequestHandler aHandler, void *aContext)
     {
         mUriPath = aUriPath;
         mHandler = aHandler;
         mContext = aContext;
-        mNext    = NULL;
+        mNext    = nullptr;
     }
 
     /**
-     * This method returns a pointer to the Uri-Path.
+     * This method returns a pointer to the URI path.
      *
-     * @returns A pointer to the Uri-Path.
+     * @returns A pointer to the URI path.
      *
      */
     const char *GetUriPath(void) const { return mUriPath; }
@@ -217,81 +182,6 @@
 };
 
 /**
- * This class implements metadata required for caching CoAP responses.
- *
- */
-class EnqueuedResponseHeader
-{
-    friend class ResponsesQueue;
-
-public:
-    /**
-     * Default constructor creating empty object.
-     *
-     */
-    EnqueuedResponseHeader(void)
-        : mDequeueTime(0)
-        , mMessageInfo()
-    {
-    }
-
-    /**
-     * Constructor creating object with valid dequeue time and message info.
-     *
-     * @param[in]  aMessageInfo  The message info containing source endpoint identification.
-     *
-     */
-    explicit EnqueuedResponseHeader(const Ip6::MessageInfo &aMessageInfo)
-        : mDequeueTime(TimerMilli::GetNow() + Time::SecToMsec(kExchangeLifetime))
-        , mMessageInfo(aMessageInfo)
-    {
-    }
-
-    /**
-     * This method appends metadata to the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     * @retval OT_ERROR_NONE     Successfully appended the bytes.
-     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
-     */
-    otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
-
-    /**
-     * This method reads request data from the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     */
-    void ReadFrom(const Message &aMessage)
-    {
-        uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-        assert(length == sizeof(*this));
-        OT_UNUSED_VARIABLE(length);
-    }
-
-    /**
-     * This method returns number of milliseconds in which the message should be sent.
-     *
-     * @returns  The number of milliseconds in which the message should be sent.
-     *
-     */
-    uint32_t GetRemainingTime(void) const;
-
-    /**
-     * This method returns the message info of cached CoAP response.
-     *
-     * @returns  The message info of the cached CoAP response.
-     *
-     */
-    const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
-
-private:
-    TimeMilli              mDequeueTime;
-    const Ip6::MessageInfo mMessageInfo;
-};
-
-/**
  * This class caches CoAP responses to implement message deduplication.
  *
  */
@@ -316,15 +206,10 @@
      *
      * @param[in]  aMessage      The CoAP response to add to the cache.
      * @param[in]  aMessageInfo  The message info corresponding to @p aMessage.
+     * @param[in]  aTxParameters Transmission parameters.
      *
      */
-    void EnqueueResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
-    /**
-     * This method removes the oldest response from the cache.
-     *
-     */
-    void DequeueOldestResponse(void);
+    void EnqueueResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const TxParameters &aTxParameters);
 
     /**
      * This method removes all responses from the cache.
@@ -360,23 +245,18 @@
         kMaxCachedResponses = OPENTHREAD_CONFIG_COAP_SERVER_MAX_CACHED_RESPONSES,
     };
 
-    /**
-     * This method checks whether a CoAP response exists in the cache that matches a given Message ID and source
-     * endpoint.
-     *
-     * @param[in]  aRequest      The CoAP message containing Message ID.
-     * @param[in]  aMessageInfo  The message info containing source endpoint address and port.
-     *
-     * @returns A pointer to the matching cached response or NULL if not found.
-     *
-     */
-    const Message *FindMatchedResponse(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) const;
-
-    void DequeueResponse(Message &aMessage)
+    struct ResponseMetadata
     {
-        mQueue.Dequeue(aMessage);
-        aMessage.Free();
-    }
+        otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
+        void    ReadFrom(const Message &aMessage);
+
+        TimeMilli        mDequeueTime;
+        Ip6::MessageInfo mMessageInfo;
+    };
+
+    const Message *FindMatchedResponse(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) const;
+    void           DequeueResponse(Message &aMessage);
+    void           UpdateQueue(void);
 
     static void HandleTimer(Timer &aTimer);
     void        HandleTimer(void);
@@ -389,25 +269,12 @@
  * This class implements the CoAP client and server.
  *
  */
-class CoapBase : public InstanceLocator
+class CoapBase : public InstanceLocator, private NonCopyable
 {
     friend class ResponsesQueue;
 
 public:
     /**
-     * This function pointer is called to send a CoAP message.
-     *
-     * @param[in]  aCoapBase     A reference to the CoAP agent.
-     * @param[in]  aMessage      A reference to the message to send.
-     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
-     *
-     * @retval OT_ERROR_NONE     Successfully sent CoAP message.
-     * @retval OT_ERROR_NO_BUFS  Failed to allocate retransmission data.
-     *
-     */
-    typedef otError (*Sender)(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
-    /**
      * This function pointer is called before CoAP server processing a CoAP message.
      *
      * @param[in]   aMessage        A reference to the message.
@@ -429,15 +296,20 @@
     void ClearRequestsAndResponses(void);
 
     /**
+     * This method clears requests with specified source address used by this CoAP agent.
+     *
+     * @param[in]  aAddress A reference to the specified address.
+     *
+     */
+    void ClearRequests(const Ip6::Address &aAddress);
+
+    /**
      * This method adds a resource to the CoAP server.
      *
      * @param[in]  aResource  A reference to the resource.
      *
-     * @retval OT_ERROR_NONE     Successfully added @p aResource.
-     * @retval OT_ERROR_ALREADY  The @p aResource was already added.
-     *
      */
-    otError AddResource(Resource &aResource);
+    void AddResource(Resource &aResource);
 
     /**
      * This method removes a resource from the CoAP server.
@@ -450,29 +322,60 @@
     /* This method sets the default handler for unhandled CoAP requests.
      *
      * @param[in]  aHandler   A function pointer that shall be called when an unhandled request arrives.
-     * @param[in]  aContext   A pointer to arbitrary context information. May be NULL if not used.
+     * @param[in]  aContext   A pointer to arbitrary context information. May be nullptr if not used.
      *
      */
-    void SetDefaultHandler(otCoapRequestHandler aHandler, void *aContext);
+    void SetDefaultHandler(RequestHandler aHandler, void *aContext);
 
     /**
      * This method creates a new message with a CoAP header.
      *
-     * @note If @p aSettings is 'NULL', the link layer security is enabled and the message priority is set to
-     * OT_MESSAGE_PRIORITY_NORMAL by default.
+     * @param[in]  aSettings  The message settings.
      *
-     * @param[in]  aSettings  A pointer to the message settings or NULL to set default settings.
-     *
-     * @returns A pointer to the message or NULL if failed to allocate message.
+     * @returns A pointer to the message or nullptr if failed to allocate message.
      *
      */
-    Message *NewMessage(const otMessageSettings *aSettings = NULL);
+    Message *NewMessage(const Message::Settings &aSettings = Message::Settings::GetDefault());
 
     /**
-     * This method sends a CoAP message.
+     * This method creates a new message with a CoAP header that has Network Control priority level.
+     *
+     * @returns A pointer to the message or nullptr if failed to allocate message.
+     *
+     */
+    Message *NewPriorityMessage(void)
+    {
+        return NewMessage(Message::Settings(Message::kWithLinkSecurity, Message::kPriorityNet));
+    }
+
+    /**
+     * This method sends a CoAP message with custom transmission parameters.
      *
      * If a response for a request is expected, respective function and context information should be provided.
-     * If no response is expected, these arguments should be NULL pointers.
+     * If no response is expected, these arguments should be nullptr pointers.
+     * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
+     *
+     * @param[in]  aMessage      A reference to the message to send.
+     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
+     * @param[in]  aTxParameters A reference to transmission parameters for this message.
+     * @param[in]  aHandler      A function pointer that shall be called on response reception or time-out.
+     * @param[in]  aContext      A pointer to arbitrary context information.
+     *
+     * @retval OT_ERROR_NONE     Successfully sent CoAP message.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffers available to send the CoAP message.
+     *
+     */
+    otError SendMessage(Message &               aMessage,
+                        const Ip6::MessageInfo &aMessageInfo,
+                        const TxParameters &    aTxParameters,
+                        ResponseHandler         aHandler = nullptr,
+                        void *                  aContext = nullptr);
+
+    /**
+     * This method sends a CoAP message with default transmission parameters.
+     *
+     * If a response for a request is expected, respective function and context information should be provided.
+     * If no response is expected, these arguments should be nullptr pointers.
      * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
      *
      * @param[in]  aMessage      A reference to the message to send.
@@ -481,13 +384,13 @@
      * @param[in]  aContext      A pointer to arbitrary context information.
      *
      * @retval OT_ERROR_NONE     Successfully sent CoAP message.
-     * @retval OT_ERROR_NO_BUFS  Failed to allocate retransmission data.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffers available to send the CoAP response.
      *
      */
     otError SendMessage(Message &               aMessage,
                         const Ip6::MessageInfo &aMessageInfo,
-                        otCoapResponseHandler   aHandler = NULL,
-                        void *                  aContext = NULL);
+                        ResponseHandler         aHandler = nullptr,
+                        void *                  aContext = nullptr);
 
     /**
      * This method sends a CoAP reset message.
@@ -500,10 +403,7 @@
      * @retval OT_ERROR_INVALID_ARGS  The @p aRequest is not of confirmable type.
      *
      */
-    otError SendReset(Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
-    {
-        return SendEmptyMessage(OT_COAP_TYPE_RESET, aRequest, aMessageInfo);
-    }
+    otError SendReset(Message &aRequest, const Ip6::MessageInfo &aMessageInfo);
 
     /**
      * This method sends header-only CoAP response message.
@@ -530,10 +430,7 @@
      * @retval OT_ERROR_INVALID_ARGS  The @p aRequest header is not of confirmable type.
      *
      */
-    otError SendAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
-    {
-        return SendEmptyMessage(OT_COAP_TYPE_ACKNOWLEDGMENT, aRequest, aMessageInfo);
-    }
+    otError SendAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);
 
     /**
      * This method sends a CoAP ACK message on which a dummy CoAP response is piggybacked.
@@ -546,12 +443,7 @@
      * @retval OT_ERROR_INVALID_ARGS  The @p aRequest header is not of confirmable type.
      *
      */
-    otError SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
-    {
-        return (aRequest.GetType() == OT_COAP_TYPE_CONFIRMABLE
-                    ? SendHeaderResponse(OT_COAP_CODE_CHANGED, aRequest, aMessageInfo)
-                    : OT_ERROR_INVALID_ARGS);
-    }
+    otError SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);
 
     /**
      * This method sends a header-only CoAP message to indicate no resource matched for the request.
@@ -563,10 +455,7 @@
      * @retval OT_ERROR_NO_BUFS      Insufficient buffers available to send the CoAP response.
      *
      */
-    otError SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
-    {
-        return SendHeaderResponse(OT_COAP_CODE_NOT_FOUND, aRequest, aMessageInfo);
-    }
+    otError SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);
 
     /**
      * This method aborts CoAP transactions associated with given handler and context.
@@ -580,7 +469,7 @@
      * @retval OT_ERROR_NOT_FOUND  CoAP transaction associated with given handler was not found.
      *
      */
-    otError AbortTransaction(otCoapResponseHandler aHandler, void *aContext);
+    otError AbortTransaction(ResponseHandler aHandler, void *aContext);
 
     /**
      * This method sets interceptor to be called before processing a CoAP packet.
@@ -589,11 +478,7 @@
      * @param[in]   aContext        A pointer to arbitrary context information.
      *
      */
-    void SetInterceptor(Interceptor aInterceptor, void *aContext)
-    {
-        mInterceptor = aInterceptor;
-        mContext     = aContext;
-    }
+    void SetInterceptor(Interceptor aInterceptor, void *aContext);
 
     /**
      * This method returns a reference to the request message list.
@@ -613,6 +498,19 @@
 
 protected:
     /**
+     * This function pointer is called to send a CoAP message.
+     *
+     * @param[in]  aCoapBase     A reference to the CoAP agent.
+     * @param[in]  aMessage      A reference to the message to send.
+     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
+     *
+     * @retval OT_ERROR_NONE     Successfully sent CoAP message.
+     * @retval OT_ERROR_NO_BUFS  Failed to allocate retransmission data.
+     *
+     */
+    typedef otError (*Sender)(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
+    /**
      * This constructor initializes the object.
      *
      * @param[in]  aInstance        A reference to the OpenThread instance.
@@ -620,7 +518,7 @@
      *                              member method of a descendant of this class.
      *
      */
-    explicit CoapBase(Instance &aInstance, Sender aSender);
+    CoapBase(Instance &aInstance, Sender aSender);
 
     /**
      * This method receives a CoAP message.
@@ -632,16 +530,36 @@
     void Receive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
 private:
+    struct Metadata
+    {
+        otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
+        void    ReadFrom(const Message &aMessage);
+        int     UpdateIn(Message &aMessage) const;
+
+        Ip6::Address    mSourceAddress;            // IPv6 address of the message source.
+        Ip6::Address    mDestinationAddress;       // IPv6 address of the message destination.
+        uint16_t        mDestinationPort;          // UDP port of the message destination.
+        ResponseHandler mResponseHandler;          // A function pointer that is called on response reception.
+        void *          mResponseContext;          // A pointer to arbitrary context information.
+        TimeMilli       mNextTimerShot;            // Time when the timer should shoot for this message.
+        uint32_t        mRetransmissionTimeout;    // Delay that is applied to next retransmission.
+        uint8_t         mRetransmissionsRemaining; // Number of retransmissions remaining.
+        bool            mAcknowledged : 1;         // Information that request was acknowledged.
+        bool            mConfirmable : 1;          // Information that message is confirmable.
+#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+        bool mObserve : 1; // Information that this request involves Observations.
+#endif
+    };
+
     static void HandleRetransmissionTimer(Timer &aTimer);
     void        HandleRetransmissionTimer(void);
 
-    Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, const CoapMetadata &aCoapMetadata);
+    void     ClearRequests(const Ip6::Address *aAddress);
+    Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, const Metadata &aMetadata);
     void     DequeueMessage(Message &aMessage);
-    Message *FindRelatedRequest(const Message &         aResponse,
-                                const Ip6::MessageInfo &aMessageInfo,
-                                CoapMetadata &          aCoapMetadata);
+    Message *FindRelatedRequest(const Message &aResponse, const Ip6::MessageInfo &aMessageInfo, Metadata &aMetadata);
     void     FinalizeCoapTransaction(Message &               aRequest,
-                                     const CoapMetadata &    aCoapMetadata,
+                                     const Metadata &        aMetadata,
                                      Message *               aResponse,
                                      const Ip6::MessageInfo *aMessageInfo,
                                      otError                 aResult);
@@ -649,23 +567,10 @@
     void ProcessReceivedRequest(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
     void ProcessReceivedResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
-    otError SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    void    SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
     otError SendEmptyMessage(Message::Type aType, const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);
 
-    /**
-     * This method sends a message.
-     *
-     * @param[in]  aMessage      A reference to the message to send.
-     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
-     *
-     * @retval OT_ERROR_NONE     Successfully sent CoAP message.
-     * @retval OT_ERROR_NO_BUFS  Failed to allocate retransmission data.
-     *
-     */
-    otError Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-    {
-        return mSender(*this, aMessage, aMessageInfo);
-    }
+    otError Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
     MessageQueue      mPendingRequests;
     uint16_t          mMessageId;
@@ -677,10 +582,10 @@
     Interceptor    mInterceptor;
     ResponsesQueue mResponsesQueue;
 
-    otCoapRequestHandler mDefaultHandler;
-    void *               mDefaultHandlerContext;
+    RequestHandler mDefaultHandler;
+    void *         mDefaultHandlerContext;
 
-    Sender mSender;
+    const Sender mSender;
 };
 
 /**
@@ -719,15 +624,11 @@
     otError Stop(void);
 
 private:
-    static otError Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-    {
-        return static_cast<Coap &>(aCoapBase).Send(aMessage, aMessageInfo);
-    }
-    otError Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    static otError Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    static void    HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+    otError        Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
-    static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
-
-    Ip6::UdpSocket mSocket;
+    Ip6::Udp::Socket mSocket;
 };
 
 } // namespace Coap
diff --git a/src/core/coap/coap_message.cpp b/src/core/coap/coap_message.cpp
index c1a54ea..5d03b9d 100644
--- a/src/core/coap/coap_message.cpp
+++ b/src/core/coap/coap_message.cpp
@@ -50,7 +50,7 @@
     SetOffset(0);
     GetHelpData().mHeaderLength = kMinHeaderLength;
 
-    SetLength(GetHelpData().mHeaderLength);
+    IgnoreError(SetLength(GetHelpData().mHeaderLength));
 }
 
 void Message::Init(Type aType, Code aCode)
@@ -175,7 +175,7 @@
     const char *cur   = aUriPath;
     const char *end;
 
-    while ((end = strchr(cur, '/')) != NULL)
+    while ((end = strchr(cur, '/')) != nullptr)
     {
         SuccessOrExit(error = AppendOption(OT_COAP_OPTION_URI_PATH, static_cast<uint16_t>(end - cur), cur));
         cur = end + 1;
@@ -187,6 +187,24 @@
     return error;
 }
 
+otError Message::AppendBlockOption(Message::BlockType aType, uint32_t aNum, bool aMore, otCoapBlockSize aSize)
+{
+    otError  error   = OT_ERROR_NONE;
+    uint32_t encoded = aSize;
+
+    VerifyOrExit(aType == kBlockType1 || aType == kBlockType2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aSize <= OT_COAP_BLOCK_SIZE_1024, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aNum < kBlockNumMax, error = OT_ERROR_INVALID_ARGS);
+
+    encoded |= static_cast<uint32_t>(aMore << kBlockMOffset);
+    encoded |= aNum << kBlockNumOffset;
+
+    error = AppendUintOption((aType == kBlockType1) ? OT_COAP_OPTION_BLOCK1 : OT_COAP_OPTION_BLOCK2, encoded);
+
+exit:
+    return error;
+}
+
 otError Message::AppendProxyUriOption(const char *aProxyUri)
 {
     return AppendStringOption(OT_COAP_OPTION_PROXY_URI, aProxyUri);
@@ -228,17 +246,19 @@
     otError        error = OT_ERROR_NONE;
     OptionIterator iterator;
 
-    assert(mBuffer.mHead.mInfo.mReserved >=
-           sizeof(GetHelpData()) +
-               static_cast<size_t>((reinterpret_cast<uint8_t *>(&GetHelpData()) - mBuffer.mHead.mData)));
+    OT_ASSERT(mBuffer.mHead.mMetadata.mReserved >=
+              sizeof(GetHelpData()) +
+                  static_cast<size_t>((reinterpret_cast<uint8_t *>(&GetHelpData()) - mBuffer.mHead.mData)));
 
     GetHelpData().Clear();
 
     GetHelpData().mHeaderOffset = GetOffset();
     Read(GetHelpData().mHeaderOffset, sizeof(GetHelpData().mHeader), &GetHelpData().mHeader);
 
+    VerifyOrExit(GetTokenLength() <= kMaxTokenLength, error = OT_ERROR_PARSE);
+
     SuccessOrExit(error = iterator.Init(this));
-    for (const otCoapOption *option = iterator.GetFirstOption(); option != NULL; option = iterator.GetNextOption())
+    for (const otCoapOption *option = iterator.GetFirstOption(); option != nullptr; option = iterator.GetNextOption())
     {
     }
 
@@ -264,9 +284,9 @@
 {
     uint8_t token[kMaxTokenLength] = {0};
 
-    assert(aTokenLength <= sizeof(token));
+    OT_ASSERT(aTokenLength <= sizeof(token));
 
-    Random::NonCrypto::FillBuffer(token, aTokenLength);
+    IgnoreError(Random::Crypto::FillBuffer(token, aTokenLength));
 
     return SetToken(token, aTokenLength);
 }
@@ -284,7 +304,7 @@
 {
     Message *message = static_cast<Message *>(ot::Message::Clone(aLength));
 
-    VerifyOrExit(message != NULL);
+    VerifyOrExit(message != nullptr, OT_NOOP);
 
     memcpy(&message->GetHelpData(), &GetHelpData(), sizeof(GetHelpData()));
 
@@ -412,9 +432,26 @@
     return err;
 }
 
+const otCoapOption *OptionIterator::GetFirstOptionMatching(uint16_t aOption)
+{
+    const otCoapOption *rval = nullptr;
+
+    for (const otCoapOption *option = GetFirstOption(); option != nullptr; option = GetNextOption())
+    {
+        if (option->mNumber == aOption)
+        {
+            // Found, stop searching
+            rval = option;
+            break;
+        }
+    }
+
+    return rval;
+}
+
 const otCoapOption *OptionIterator::GetFirstOption(void)
 {
-    const otCoapOption *option  = NULL;
+    const otCoapOption *option  = nullptr;
     const Message &     message = GetMessage();
 
     ClearOption();
@@ -429,6 +466,23 @@
     return option;
 }
 
+const otCoapOption *OptionIterator::GetNextOptionMatching(uint16_t aOption)
+{
+    const otCoapOption *rval = nullptr;
+
+    for (const otCoapOption *option = GetNextOption(); option != nullptr; option = GetNextOption())
+    {
+        if (option->mNumber == aOption)
+        {
+            // Found, stop searching
+            rval = option;
+            break;
+        }
+    }
+
+    return rval;
+}
+
 const otCoapOption *OptionIterator::GetNextOption(void)
 {
     otError        error = OT_ERROR_NONE;
@@ -436,7 +490,7 @@
     uint16_t       optionLength;
     uint8_t        buf[Message::kMaxOptionHeaderSize];
     uint8_t *      cur     = buf + 1;
-    otCoapOption * rval    = NULL;
+    otCoapOption * rval    = nullptr;
     const Message &message = GetMessage();
 
     VerifyOrExit(mNextOptionOffset < message.GetLength(), error = OT_ERROR_NOT_FOUND);
@@ -512,6 +566,25 @@
     return rval;
 }
 
+otError OptionIterator::GetOptionValue(uint64_t &aValue) const
+{
+    otError error = OT_ERROR_NONE;
+    uint8_t value[sizeof(aValue)];
+
+    VerifyOrExit(mOption.mLength <= sizeof(aValue), error = OT_ERROR_NO_BUFS);
+    SuccessOrExit(error = GetOptionValue(value));
+
+    aValue = 0;
+    for (uint16_t pos = 0; pos < mOption.mLength; pos++)
+    {
+        aValue <<= 8;
+        aValue |= value[pos];
+    }
+
+exit:
+    return error;
+}
+
 otError OptionIterator::GetOptionValue(void *aValue) const
 {
     otError error = OT_ERROR_NONE;
diff --git a/src/core/coap/coap_message.hpp b/src/core/coap/coap_message.hpp
index f343100..87697c1 100644
--- a/src/core/coap/coap_message.hpp
+++ b/src/core/coap/coap_message.hpp
@@ -38,10 +38,10 @@
 
 #include <openthread/coap.h>
 
+#include "common/clearable.hpp"
 #include "common/code_utils.hpp"
 #include "common/encoding.hpp"
 #include "common/message.hpp"
-#include "utils/static_assert.hpp"
 
 namespace ot {
 
@@ -98,6 +98,21 @@
     typedef otCoapCode Code;
 
     /**
+     * CoAP Block1/Block2 Types
+     *
+     */
+    enum BlockType
+    {
+        kBlockType1 = 1,
+        kBlockType2 = 2,
+    };
+
+    enum
+    {
+        kBlockSzxBase = 4,
+    };
+
+    /**
      * This method initializes the CoAP header.
      *
      */
@@ -117,7 +132,7 @@
      *
      * @param[in]  aType              The Type value.
      * @param[in]  aCode              The Code value.
-     * @param[in]  aUriPath           A pointer to a NULL-terminated string.
+     * @param[in]  aUriPath           A pointer to a null-terminated string.
      *
      * @retval OT_ERROR_NONE          Successfully appended the option.
      * @retval OT_ERROR_NO_BUFS       The option length exceeds the buffer size.
@@ -326,7 +341,7 @@
     /**
      * This method appends a Uri-Path option.
      *
-     * @param[in]  aUriPath           A pointer to a NULL-terminated string.
+     * @param[in]  aUriPath           A pointer to a null-terminated string.
      *
      * @retval OT_ERROR_NONE          Successfully appended the option.
      * @retval OT_ERROR_INVALID_ARGS  The option type is not equal or greater than the last option type.
@@ -336,9 +351,24 @@
     otError AppendUriPathOptions(const char *aUriPath);
 
     /**
+     * This method appends a Block option
+     *
+     * @param[in]  aType              Type of block option, 1 or 2.
+     * @param[in]  aNum               Current block number.
+     * @param[in]  aMore              Boolean to indicate more blocks are to be sent.
+     * @param[in]  aSize              Maximum block size.
+     *
+     * @retval OT_ERROR_NONE          Successfully appended the option.
+     * @retval OT_ERROR_INVALID_ARGS  The option type is not equal or greater than the last option type.
+     * @retval OT_ERROR_NO_BUFS       The option length exceeds the buffer size.
+     *
+     */
+    otError AppendBlockOption(BlockType aType, uint32_t aNum, bool aMore, otCoapBlockSize aSize);
+
+    /**
      * This method appends a Proxy-Uri option.
      *
-     * @param[in]  aProxyUri          A pointer to a NULL-terminated string.
+     * @param[in]  aProxyUri          A pointer to a null-terminated string.
      *
      * @retval OT_ERROR_NONE          Successfully appended the option.
      * @retval OT_ERROR_INVALID_ARGS  The option type is not equal or greater than the last option type.
@@ -373,7 +403,7 @@
     /**
      * This method appends a single Uri-Query option.
      *
-     * @param[in]  aUriQuery  A pointer to NULL-terminated string, which should contain a single key=value pair.
+     * @param[in]  aUriQuery  A pointer to null-terminated string, which should contain a single key=value pair.
      *
      * @retval OT_ERROR_NONE          Successfully appended the option.
      * @retval OT_ERROR_INVALID_ARGS  The option type is not equal or greater than the last option type.
@@ -492,7 +522,7 @@
      *
      * @param[in] aLength  Number of payload bytes to copy.
      *
-     * @returns A pointer to the message or NULL if insufficient message buffers are available.
+     * @returns A pointer to the message or nullptr if insufficient message buffers are available.
      *
      */
     Message *Clone(uint16_t aLength) const;
@@ -504,7 +534,7 @@
      * `Type`, `SubType`, `LinkSecurity`, `Offset`, `InterfaceId`, and `Priority` fields on the cloned message are also
      * copied from the original one.
      *
-     * @returns A pointer to the message or NULL if insufficient message buffers are available.
+     * @returns A pointer to the message or nullptr if insufficient message buffers are available.
      *
      */
     Message *Clone(void) const { return Clone(GetLength()); }
@@ -515,6 +545,28 @@
      */
     static uint16_t GetHelpDataReserved(void) { return sizeof(HelpData) + kHelpDataAlignment; }
 
+    /**
+     * This method returns a pointer to the next message after this as a `Coap::Message`.
+     *
+     * This method should be used when the message is in a `Coap::MessageQueue` (i.e., a queue containing only CoAP
+     * messages).
+     *
+     * @returns A pointer to the next message in the queue or nullptr if at the end of the queue.
+     *
+     */
+    Message *GetNextCoapMessage(void) { return static_cast<Message *>(GetNext()); }
+
+    /**
+     * This method returns a pointer to the next message after this as a `Coap::Message`.
+     *
+     * This method should be used when the message is in a `Coap::MessageQueue` (i.e., a queue containing only CoAP
+     * messages).
+     *
+     * @returns A pointer to the next message in the queue or nullptr if at the end of the queue.
+     *
+     */
+    const Message *GetNextCoapMessage(void) const { return static_cast<const Message *>(GetNext()); }
+
 private:
     /**
      * Protocol Constants (RFC 7252).
@@ -547,6 +599,18 @@
         kHelpDataAlignment = sizeof(uint16_t), ///< Alignment of help data.
     };
 
+    enum
+    {
+        kBlockSzxOffset = 0,
+        kBlockMOffset   = 3,
+        kBlockNumOffset = 4,
+    };
+
+    enum
+    {
+        kBlockNumMax = 0xFFFFF,
+    };
+
     /**
      * This structure represents a CoAP header excluding CoAP options.
      *
@@ -564,10 +628,8 @@
      * This structure represents a HelpData used by this CoAP message.
      *
      */
-    struct HelpData
+    struct HelpData : public Clearable<HelpData>
     {
-        void Clear(void) { memset(this, 0, sizeof(*this)); }
-
         Header   mHeader;
         uint16_t mOptionLast;
         uint16_t mHeaderOffset; ///< The byte offset for the CoAP Header
@@ -576,8 +638,8 @@
 
     const HelpData &GetHelpData(void) const
     {
-        OT_STATIC_ASSERT(sizeof(mBuffer.mHead.mInfo) + sizeof(HelpData) + kHelpDataAlignment <= sizeof(mBuffer),
-                         "Insufficient buffer size for CoAP processing!");
+        static_assert(sizeof(mBuffer.mHead.mMetadata) + sizeof(HelpData) + kHelpDataAlignment <= sizeof(mBuffer),
+                      "Insufficient buffer size for CoAP processing!");
 
         return *static_cast<const HelpData *>(OT_ALIGN(mBuffer.mHead.mData, kHelpDataAlignment));
     }
@@ -585,35 +647,130 @@
     HelpData &GetHelpData(void) { return const_cast<HelpData &>(static_cast<const Message *>(this)->GetHelpData()); }
 };
 
+/**
+ * This class implements a CoAP message queue.
+ *
+ */
+class MessageQueue : public ot::MessageQueue
+{
+public:
+    /**
+     * This constructor initializes the message queue.
+     *
+     */
+    MessageQueue(void)
+        : ot::MessageQueue()
+    {
+    }
+
+    /**
+     * This method returns a pointer to the first message.
+     *
+     * @returns A pointer to the first message.
+     *
+     */
+    Message *GetHead(void) const { return static_cast<Message *>(ot::MessageQueue::GetHead()); }
+
+    /**
+     * This method adds a message to the end of the queue.
+     *
+     * @param[in]  aMessage  The message to add.
+     *
+     */
+    void Enqueue(Message &aMessage) { Enqueue(aMessage, kQueuePositionTail); }
+
+    /**
+     * This method adds a message at a given position (head/tail) of the queue.
+     *
+     * @param[in]  aMessage  The message to add.
+     * @param[in]  aPosition The position (head or tail) where to add the message.
+     *
+     */
+    void Enqueue(Message &aMessage, QueuePosition aPosition) { ot::MessageQueue::Enqueue(aMessage, aPosition); }
+
+    /**
+     * This method removes a message from the queue.
+     *
+     * @param[in]  aMessage  The message to remove.
+     *
+     */
+    void Dequeue(Message &aMessage) { ot::MessageQueue::Dequeue(aMessage); }
+};
+
+/**
+ * This class acts as an iterator for CoAP options.
+ *
+ */
 class OptionIterator : public ::otCoapOptionIterator
 {
 public:
     /**
-     * Initialise the state of the iterator to iterate over the given message.
+     * Initialize the state of the iterator to iterate over the given message.
      *
-     * @retval  OT_ERROR_NONE   Successfully initialised
+     * @retval  OT_ERROR_NONE   Successfully initialized
      * @retval  OT_ERROR_PARSE  Message state is inconsistent
      *
      */
     otError Init(const Message *aMessage);
 
     /**
+     * This method returns a pointer to the first option matching the given option number.
+     *
+     * The internal option pointer is advanced until matching option is seen, if no matching
+     * option is seen, the iterator will advance to the end of the options block.
+     *
+     * @param[in]   aOption         Option number to look for.
+     *
+     * @returns A pointer to the first matching option. If no option matching @p aOption is seen, nullptr pointer is
+     *          returned.
+     */
+    const otCoapOption *GetFirstOptionMatching(uint16_t aOption);
+
+    /**
      * This method returns a pointer to the first option.
      *
-     * @returns A pointer to the first option. If no option is present NULL pointer is returned.
+     * @returns A pointer to the first option. If no option is present nullptr pointer is returned.
      */
     const otCoapOption *GetFirstOption(void);
 
     /**
+     * This method returns a pointer to the next option matching the given option number.
+     *
+     * The internal option pointer is advanced until matching option is seen, if no matching
+     * option is seen, the iterator will advance to the end of the options block.
+     *
+     * @param[in]   aOption         Option number to look for.
+     *
+     * @returns A pointer to the next matching option (relative to current iterator position). If no option matching @p
+     *          aOption is seen, nullptr pointer is returned.
+     */
+    const otCoapOption *GetNextOptionMatching(uint16_t aOption);
+
+    /**
      * This method returns a pointer to the next option.
      *
-     * @returns A pointer to the next option. If no more options are present NULL pointer is returned.
+     * @returns A pointer to the next option. If no more options are present nullptr pointer is returned.
      */
     const otCoapOption *GetNextOption(void);
 
     /**
+     * This function fills current option value into @p aValue.  The option is assumed to be an unsigned integer.
+     *
+     * @param[out]  aValue          Buffer to store the option value.
+     *
+     * @retval  OT_ERROR_NONE       Successfully filled value.
+     * @retval  OT_ERROR_NOT_FOUND  No more options, aIterator->mNextOptionOffset is set to offset of payload.
+     * @retval  OT_ERROR_NO_BUFS    Value is too long to fit in a uint64_t.
+     *
+     */
+    otError GetOptionValue(uint64_t &aValue) const;
+
+    /**
      * This function fills current option value into @p aValue.
      *
+     * @param[out]  aValue          Buffer to store the option value.  This buffer is assumed to be sufficiently large
+     *                              (see @ref otCoapOption::mLength).
+     *
      * @retval  OT_ERROR_NONE       Successfully filled value.
      * @retval  OT_ERROR_NOT_FOUND  No more options, mNextOptionOffset is set to offset of payload.
      *
diff --git a/src/core/coap/coap_secure.cpp b/src/core/coap/coap_secure.cpp
index ffdec6c..f29e037 100644
--- a/src/core/coap/coap_secure.cpp
+++ b/src/core/coap/coap_secure.cpp
@@ -48,10 +48,10 @@
 CoapSecure::CoapSecure(Instance &aInstance, bool aLayerTwoSecurity)
     : CoapBase(aInstance, &CoapSecure::Send)
     , mDtls(aInstance, aLayerTwoSecurity)
-    , mConnectedCallback(NULL)
-    , mConnectedContext(NULL)
+    , mConnectedCallback(nullptr)
+    , mConnectedContext(nullptr)
     , mTransmitQueue()
-    , mTransmitTask(aInstance, &CoapSecure::HandleTransmit, this)
+    , mTransmitTask(aInstance, CoapSecure::HandleTransmit, this)
 {
 }
 
@@ -59,8 +59,8 @@
 {
     otError error = OT_ERROR_NONE;
 
-    mConnectedCallback = NULL;
-    mConnectedContext  = NULL;
+    mConnectedCallback = nullptr;
+    mConnectedContext  = nullptr;
 
     SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
     SuccessOrExit(error = mDtls.Bind(aPort));
@@ -73,8 +73,8 @@
 {
     otError error = OT_ERROR_NONE;
 
-    mConnectedCallback = NULL;
-    mConnectedContext  = NULL;
+    mConnectedCallback = nullptr;
+    mConnectedContext  = nullptr;
 
     SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
     SuccessOrExit(error = mDtls.Bind(aCallback, aContext));
@@ -83,17 +83,11 @@
     return error;
 }
 
-void CoapSecure::SetConnectedCallback(ConnectedCallback aCallback, void *aContext)
-{
-    mConnectedCallback = aCallback;
-    mConnectedContext  = aContext;
-}
-
 void CoapSecure::Stop(void)
 {
     mDtls.Close();
 
-    for (ot::Message *message = mTransmitQueue.GetHead(); message != NULL; message = message->GetNext())
+    for (ot::Message *message = mTransmitQueue.GetHead(); message != nullptr; message = message->GetNext())
     {
         mTransmitQueue.Dequeue(*message);
         message->Free();
@@ -110,55 +104,28 @@
     return mDtls.Connect(aSockAddr);
 }
 
-otError CoapSecure::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
+void CoapSecure::SetPsk(const MeshCoP::JoinerPskd &aPskd)
 {
-    return mDtls.SetPsk(aPsk, aPskLength);
+    otError error;
+
+    OT_UNUSED_VARIABLE(error);
+
+    static_assert(static_cast<uint16_t>(MeshCoP::JoinerPskd::kMaxLength) <=
+                      static_cast<uint16_t>(MeshCoP::Dtls::kPskMaxLength),
+                  "The maximum length of DTLS PSK is smaller than joiner PSKd");
+
+    error = mDtls.SetPsk(reinterpret_cast<const uint8_t *>(aPskd.GetAsCString()), aPskd.GetLength());
+
+    OT_ASSERT(error == OT_ERROR_NONE);
 }
 
-#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
-
-#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-void CoapSecure::SetCertificate(const uint8_t *aX509Cert,
-                                uint32_t       aX509Length,
-                                const uint8_t *aPrivateKey,
-                                uint32_t       aPrivateKeyLength)
-{
-    mDtls.SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
-}
-
-void CoapSecure::SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength)
-{
-    mDtls.SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength);
-}
-#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-
-#ifdef MBEDTLS_BASE64_C
-otError CoapSecure::GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize)
-{
-    return mDtls.GetPeerCertificateBase64(aPeerCert, aCertLength, aCertBufferSize);
-}
-#endif // MBEDTLS_BASE64_C
-
-void CoapSecure::SetClientConnectedCallback(ConnectedCallback aCallback, void *aContext)
-{
-    mConnectedCallback = aCallback;
-    mConnectedContext  = aContext;
-}
-
-void CoapSecure::SetSslAuthMode(bool aVerifyPeerCertificate)
-{
-    mDtls.SetSslAuthMode(aVerifyPeerCertificate);
-}
-
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
-
-otError CoapSecure::SendMessage(Message &aMessage, otCoapResponseHandler aHandler, void *aContext)
+otError CoapSecure::SendMessage(Message &aMessage, ResponseHandler aHandler, void *aContext)
 {
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(IsConnected(), error = OT_ERROR_INVALID_STATE);
 
-    error = CoapBase::SendMessage(aMessage, mDtls.GetPeerAddress(), aHandler, aContext);
+    error = CoapBase::SendMessage(aMessage, mDtls.GetMessageInfo(), aHandler, aContext);
 
 exit:
     return error;
@@ -166,7 +133,7 @@
 
 otError CoapSecure::SendMessage(Message &               aMessage,
                                 const Ip6::MessageInfo &aMessageInfo,
-                                otCoapResponseHandler   aHandler,
+                                ResponseHandler         aHandler,
                                 void *                  aContext)
 {
     return CoapBase::SendMessage(aMessage, aMessageInfo, aHandler, aContext);
@@ -176,13 +143,10 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    otError error;
-
-    SuccessOrExit(error = mTransmitQueue.Enqueue(aMessage));
+    mTransmitQueue.Enqueue(aMessage);
     mTransmitTask.Post();
 
-exit:
-    return error;
+    return OT_ERROR_NONE;
 }
 
 void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected)
@@ -192,7 +156,7 @@
 
 void CoapSecure::HandleDtlsConnected(bool aConnected)
 {
-    if (mConnectedCallback != NULL)
+    if (mConnectedCallback != nullptr)
     {
         mConnectedCallback(aConnected, mConnectedContext);
     }
@@ -205,16 +169,17 @@
 
 void CoapSecure::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
 {
-    ot::Message *message = NULL;
+    ot::Message *message = nullptr;
 
-    VerifyOrExit((message = Get<MessagePool>().New(Message::kTypeIp6, Message::GetHelpDataReserved())) != NULL);
+    VerifyOrExit((message = Get<MessagePool>().New(Message::kTypeIp6, Message::GetHelpDataReserved())) != nullptr,
+                 OT_NOOP);
     SuccessOrExit(message->Append(aBuf, aLength));
 
-    CoapBase::Receive(*message, mDtls.GetPeerAddress());
+    CoapBase::Receive(*message, mDtls.GetMessageInfo());
 
 exit:
 
-    if (message != NULL)
+    if (message != nullptr)
     {
         message->Free();
     }
@@ -230,10 +195,10 @@
     otError      error   = OT_ERROR_NONE;
     ot::Message *message = mTransmitQueue.GetHead();
 
-    VerifyOrExit(message != NULL);
+    VerifyOrExit(message != nullptr, OT_NOOP);
     mTransmitQueue.Dequeue(*message);
 
-    if (mTransmitQueue.GetHead() != NULL)
+    if (mTransmitQueue.GetHead() != nullptr)
     {
         mTransmitTask.Post();
     }
diff --git a/src/core/coap/coap_secure.hpp b/src/core/coap/coap_secure.hpp
index 65f62fc..889ed74 100644
--- a/src/core/coap/coap_secure.hpp
+++ b/src/core/coap/coap_secure.hpp
@@ -33,6 +33,7 @@
 
 #include "coap/coap.hpp"
 #include "meshcop/dtls.hpp"
+#include "meshcop/meshcop.hpp"
 
 #include <openthread/coap_secure.h>
 
@@ -96,7 +97,11 @@
      * @param[in]  aContext   A pointer to arbitrary context information.
      *
      */
-    void SetConnectedCallback(ConnectedCallback aCallback, void *aContext);
+    void SetConnectedCallback(ConnectedCallback aCallback, void *aContext)
+    {
+        mConnectedCallback = aCallback;
+        mConnectedContext  = aContext;
+    }
 
     /**
      * This method stops the secure CoAP agent.
@@ -158,7 +163,15 @@
      * @retval OT_ERROR_INVALID_ARGS  The PSK is invalid.
      *
      */
-    otError SetPsk(const uint8_t *aPsk, uint8_t aPskLength);
+    otError SetPsk(const uint8_t *aPsk, uint8_t aPskLength) { return mDtls.SetPsk(aPsk, aPskLength); }
+
+    /**
+     * This method sets the PSK.
+     *
+     * @param[in]  aPskd  A Joiner PSKd.
+     *
+     */
+    void SetPsk(const MeshCoP::JoinerPskd &aPskd);
 
 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 
@@ -195,7 +208,10 @@
     void SetCertificate(const uint8_t *aX509Cert,
                         uint32_t       aX509Length,
                         const uint8_t *aPrivateKey,
-                        uint32_t       aPrivateKeyLength);
+                        uint32_t       aPrivateKeyLength)
+    {
+        mDtls.SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
+    }
 
     /**
      * This method sets the trusted top level CAs. It is needed for validate the certificate of the peer.
@@ -206,7 +222,10 @@
      * @param[in]  aX509CaCertChainLength   The length of chain.
      *
      */
-    void SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength);
+    void SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength)
+    {
+        mDtls.SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength);
+    }
 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 
 #ifdef MBEDTLS_BASE64_C
@@ -223,7 +242,10 @@
      * @retval OT_ERROR_NO_BUFS  Can't allocate memory for certificate.
      *
      */
-    otError GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize);
+    otError GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize)
+    {
+        return mDtls.GetPeerCertificateBase64(aPeerCert, aCertLength, aCertBufferSize);
+    }
 #endif // MBEDTLS_BASE64_C
 
     /**
@@ -233,7 +255,11 @@
      * @param[in]  aContext      A pointer to arbitrary context information.
      *
      */
-    void SetClientConnectedCallback(ConnectedCallback aCallback, void *aContext);
+    void SetClientConnectedCallback(ConnectedCallback aCallback, void *aContext)
+    {
+        mConnectedCallback = aCallback;
+        mConnectedContext  = aContext;
+    }
 
     /**
      * This method sets the authentication mode for the CoAP secure connection. It disables or enables the verification
@@ -242,7 +268,7 @@
      * @param[in]  aVerifyPeerCertificate  true, if the peer certificate should be verified
      *
      */
-    void SetSslAuthMode(bool aVerifyPeerCertificate);
+    void SetSslAuthMode(bool aVerifyPeerCertificate) { mDtls.SetSslAuthMode(aVerifyPeerCertificate); }
 
 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 
@@ -250,7 +276,7 @@
      * This method sends a CoAP message over secure DTLS connection.
      *
      * If a response for a request is expected, respective function and context information should be provided.
-     * If no response is expected, these arguments should be NULL pointers.
+     * If no response is expected, these arguments should be nullptr pointers.
      * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
      *
      * @param[in]  aMessage      A reference to the message to send.
@@ -262,13 +288,13 @@
      * @retval OT_ERROR_INVALID_STATE  DTLS connection was not initialized.
      *
      */
-    otError SendMessage(Message &aMessage, otCoapResponseHandler aHandler = NULL, void *aContext = NULL);
+    otError SendMessage(Message &aMessage, ResponseHandler aHandler = nullptr, void *aContext = nullptr);
 
     /**
      * This method sends a CoAP message over secure DTLS connection.
      *
      * If a response for a request is expected, respective function and context information should be provided.
-     * If no response is expected, these arguments should be NULL pointers.
+     * If no response is expected, these arguments should be nullptr pointers.
      * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
      *
      * @param[in]  aMessage      A reference to the message to send.
@@ -283,8 +309,8 @@
      */
     otError SendMessage(Message &               aMessage,
                         const Ip6::MessageInfo &aMessageInfo,
-                        otCoapResponseHandler   aHandler = NULL,
-                        void *                  aContext = NULL);
+                        ResponseHandler         aHandler = nullptr,
+                        void *                  aContext = nullptr);
 
     /**
      * This method is used to pass UDP messages to the secure CoAP server.
@@ -304,7 +330,7 @@
      * @return DTLS session's message info.
      *
      */
-    const Ip6::MessageInfo &GetPeerAddress(void) const { return mDtls.GetPeerAddress(); }
+    const Ip6::MessageInfo &GetMessageInfo(void) const { return mDtls.GetMessageInfo(); }
 
 private:
     static otError Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
@@ -325,7 +351,7 @@
     MeshCoP::Dtls     mDtls;
     ConnectedCallback mConnectedCallback;
     void *            mConnectedContext;
-    MessageQueue      mTransmitQueue;
+    ot::MessageQueue  mTransmitQueue;
     TaskletContext    mTransmitTask;
 };
 
diff --git a/src/core/common/clearable.hpp b/src/core/common/clearable.hpp
new file mode 100644
index 0000000..2cef091
--- /dev/null
+++ b/src/core/common/clearable.hpp
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for Clearable class for OpenThread objects.
+ */
+
+#ifndef CLEARABLE_HPP_
+#define CLEARABLE_HPP_
+
+#include "openthread-core-config.h"
+
+#include <string.h>
+
+namespace ot {
+
+/**
+ * This template class defines a Clearable object which provides `Clear()` method.
+ *
+ * The `Clear` implementation simply sets all the bytes of a `Type` instance to zero.
+ *
+ * Users of this class should follow CRTP-style inheritance, i.e., the `Type` class itself should publicly inherit
+ * from `Clearable<Type>`.
+ *
+ */
+template <typename Type> class Clearable
+{
+public:
+    void Clear(void) { memset(reinterpret_cast<void *>(this), 0, sizeof(Type)); }
+};
+
+} // namespace ot
+
+#endif // CLEARABLE_HPP_
diff --git a/src/core/common/code_utils.hpp b/src/core/common/code_utils.hpp
index 3589b77..61cbfad 100644
--- a/src/core/common/code_utils.hpp
+++ b/src/core/common/code_utils.hpp
@@ -34,11 +34,9 @@
 #ifndef CODE_UTILS_HPP_
 #define CODE_UTILS_HPP_
 
-#include "openthread-core-config.h"
-
 #include <stdbool.h>
 
-#include "utils/static_assert.hpp"
+#include <openthread/error.h>
 
 /**
  * This macro calculates the number of elements in an array.
@@ -99,21 +97,27 @@
     } while (false)
 
 /**
+ * Use this macro in conjunction with `VerifyOrExit()` when no action is specified.
+ *
+ */
+#define OT_NOOP
+
+/**
  * This macro checks for the specified condition, which is expected to commonly be true, and both executes @a ... and
  * branches to the local label 'exit' if the condition is false.
  *
  * @param[in]  aCondition  A Boolean expression to be evaluated.
- * @param[in]  ...         An expression or block to execute when the assertion fails.
+ * @param[in]  aAction     An expression or block to execute when the assertion fails.
  *
  */
-#define VerifyOrExit(aCondition, ...) \
-    do                                \
-    {                                 \
-        if (!(aCondition))            \
-        {                             \
-            __VA_ARGS__;              \
-            goto exit;                \
-        }                             \
+#define VerifyOrExit(aCondition, aAction) \
+    do                                    \
+    {                                     \
+        if (!(aCondition))                \
+        {                                 \
+            aAction;                      \
+            goto exit;                    \
+        }                                 \
     } while (false)
 
 /**
@@ -149,4 +153,18 @@
         }                             \
     } while (false)
 
+/**
+ * This function ignores an error explicitly.
+ *
+ * This is primarily used to indicate the intention of developer that
+ * the error can be safely ignored or there is guaranteed to be no error.
+ *
+ * @param[in]  aError  The error to be ignored.
+ *
+ */
+static inline void IgnoreError(otError aError)
+{
+    OT_UNUSED_VARIABLE(aError);
+}
+
 #endif // CODE_UTILS_HPP_
diff --git a/src/core/common/debug.hpp b/src/core/common/debug.hpp
index 1c3f3d4..50dd2b2 100644
--- a/src/core/common/debug.hpp
+++ b/src/core/common/debug.hpp
@@ -39,10 +39,14 @@
 #include <ctype.h>
 #include <stdio.h>
 
-#if defined(OPENTHREAD_TARGET_DARWIN) || defined(OPENTHREAD_TARGET_LINUX)
+#if OPENTHREAD_CONFIG_ASSERT_ENABLE
+
+#if defined(__APPLE__) || defined(__linux__)
 
 #include <assert.h>
 
+#define OT_ASSERT(cond) assert(cond)
+
 #elif OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT
 
 #include "openthread/platform/misc.h"
@@ -55,11 +59,7 @@
 #define FILE_NAME __FILE__
 #endif
 
-#ifdef assert
-#undef assert
-#endif
-
-#define assert(cond)                               \
+#define OT_ASSERT(cond)                            \
     do                                             \
     {                                              \
         if (!(cond))                               \
@@ -71,23 +71,25 @@
         }                                          \
     } while (0)
 
-#else
+#else // OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT
 
-#ifdef assert
-#undef assert
-#endif
-
-#define assert(cond)  \
-    do                \
-    {                 \
-        if (!(cond))  \
-        {             \
-            while (1) \
-            {         \
-            }         \
-        }             \
+#define OT_ASSERT(cond) \
+    do                  \
+    {                   \
+        if (!(cond))    \
+        {               \
+            while (1)   \
+            {           \
+            }           \
+        }               \
     } while (0)
 
-#endif
+#endif // OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT
+
+#else // OPENTHREAD_CONFIG_ASSERT_ENABLE
+
+#define OT_ASSERT(cond)
+
+#endif // OPENTHREAD_CONFIG_ASSERT_ENABLE
 
 #endif // DEBUG_HPP_
diff --git a/src/core/common/encoding.hpp b/src/core/common/encoding.hpp
index 0d4ba72..07da01b 100644
--- a/src/core/common/encoding.hpp
+++ b/src/core/common/encoding.hpp
@@ -37,8 +37,13 @@
 #include "openthread-core-config.h"
 
 #ifndef BYTE_ORDER_BIG_ENDIAN
+#if defined(WORDS_BIGENDIAN) || \
+    defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define BYTE_ORDER_BIG_ENDIAN 1
+#else
 #define BYTE_ORDER_BIG_ENDIAN 0
 #endif
+#endif
 
 #include <limits.h>
 #include <stdint.h>
@@ -144,6 +149,22 @@
 }
 
 /**
+ * This function reads a `uint64_t` value from a given buffer assuming big-ending encoding.
+ *
+ * @param[in] aBuffer   Pointer to buffer to read from.
+ *
+ * @returns The `uint64_t` value read from buffer.
+ *
+ */
+inline uint64_t ReadUint64(const uint8_t *aBuffer)
+{
+    return ((static_cast<uint64_t>(aBuffer[0]) << 56) | (static_cast<uint64_t>(aBuffer[1]) << 48) |
+            (static_cast<uint64_t>(aBuffer[2]) << 40) | (static_cast<uint64_t>(aBuffer[3]) << 32) |
+            (static_cast<uint64_t>(aBuffer[4]) << 24) | (static_cast<uint64_t>(aBuffer[5]) << 16) |
+            (static_cast<uint64_t>(aBuffer[6]) << 8) | (static_cast<uint64_t>(aBuffer[7]) << 0));
+}
+
+/**
  * This function writes a `uint16_t` value to a given buffer using big-ending encoding.
  *
  * @param[in]  aValue    The value to write to buffer.
@@ -171,6 +192,25 @@
     aBuffer[3] = (aValue >> 0) & 0xff;
 }
 
+/**
+ * This function writes a `uint64_t` value to a given buffer using big-ending encoding.
+ *
+ * @param[in]  aValue    The value to write to buffer.
+ * @param[out] aBuffer   Pointer to buffer where the value will be written.
+ *
+ */
+inline void WriteUint64(uint64_t aValue, uint8_t *aBuffer)
+{
+    aBuffer[0] = (aValue >> 56) & 0xff;
+    aBuffer[1] = (aValue >> 48) & 0xff;
+    aBuffer[2] = (aValue >> 40) & 0xff;
+    aBuffer[3] = (aValue >> 32) & 0xff;
+    aBuffer[4] = (aValue >> 24) & 0xff;
+    aBuffer[5] = (aValue >> 16) & 0xff;
+    aBuffer[6] = (aValue >> 8) & 0xff;
+    aBuffer[7] = (aValue >> 0) & 0xff;
+}
+
 } // namespace BigEndian
 
 namespace LittleEndian {
@@ -235,6 +275,22 @@
 }
 
 /**
+ * This function reads a `uint64_t` value from a given buffer assuming little-ending encoding.
+ *
+ * @param[in] aBuffer   Pointer to buffer to read from.
+ *
+ * @returns The `uint64_t` value read from buffer.
+ *
+ */
+inline uint64_t ReadUint64(const uint8_t *aBuffer)
+{
+    return ((static_cast<uint64_t>(aBuffer[0]) << 0) | (static_cast<uint64_t>(aBuffer[1]) << 8) |
+            (static_cast<uint64_t>(aBuffer[2]) << 16) | (static_cast<uint64_t>(aBuffer[3]) << 24) |
+            (static_cast<uint64_t>(aBuffer[4]) << 32) | (static_cast<uint64_t>(aBuffer[5]) << 40) |
+            (static_cast<uint64_t>(aBuffer[6]) << 48) | (static_cast<uint64_t>(aBuffer[7]) << 56));
+}
+
+/**
  * This function writes a `uint16_t` value to a given buffer using little-ending encoding.
  *
  * @param[in]  aValue    The value to write to buffer.
@@ -262,6 +318,25 @@
     aBuffer[3] = (aValue >> 24) & 0xff;
 }
 
+/**
+ * This function writes a `uint64_t` value to a given buffer using little-ending encoding.
+ *
+ * @param[in]  aValue   The value to write to buffer.
+ * @param[out] aBuffer  Pointer to buffer where the value will be written.
+ *
+ */
+inline void WriteUint64(uint64_t aValue, uint8_t *aBuffer)
+{
+    aBuffer[0] = (aValue >> 0) & 0xff;
+    aBuffer[1] = (aValue >> 8) & 0xff;
+    aBuffer[2] = (aValue >> 16) & 0xff;
+    aBuffer[3] = (aValue >> 24) & 0xff;
+    aBuffer[4] = (aValue >> 32) & 0xff;
+    aBuffer[5] = (aValue >> 40) & 0xff;
+    aBuffer[6] = (aValue >> 48) & 0xff;
+    aBuffer[7] = (aValue >> 56) & 0xff;
+}
+
 } // namespace LittleEndian
 } // namespace Encoding
 } // namespace ot
diff --git a/src/core/common/equatable.hpp b/src/core/common/equatable.hpp
new file mode 100644
index 0000000..83ab05b
--- /dev/null
+++ b/src/core/common/equatable.hpp
@@ -0,0 +1,80 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for Equatable class for OpenThread objects.
+ */
+
+#ifndef EQUATABLE_HPP_
+#define EQUATABLE_HPP_
+
+#include "openthread-core-config.h"
+
+#include <string.h>
+
+namespace ot {
+
+/**
+ * This template class defines overloads of operators `==` and `!=`.
+ *
+ * The `==` implementation simply compares all the bytes of two `Type` instances to be equal (using `memcmp()`).
+ *
+ * Users of this class should follow CRTP-style inheritance, i.e., the `Type` class itself should publicly inherit
+ * from `Equatable<Type>`.
+ *
+ */
+template <class Type> class Equatable
+{
+public:
+    /**
+     * This method overloads operator `==` to evaluate whether or not two instances of `Type` are equal.
+     *
+     * @param[in]  aOther  The other `Type` instance to compare with.
+     *
+     * @retval TRUE   If the two `Type` instances are equal.
+     * @retval FALSE  If the two `Type` instances are not equal.
+     *
+     */
+    bool operator==(const Type &aOther) const { return memcmp(this, &aOther, sizeof(Type)) == 0; }
+
+    /**
+     * This method overloads operator `!=` to evaluate whether or not two instances of `Type` are equal.
+     *
+     * @param[in]  aOther  The other `Type` instance to compare with.
+     *
+     * @retval TRUE   If the two `Type` instances are not equal.
+     * @retval FALSE  If the two `Type` instances are equal.
+     *
+     */
+    bool operator!=(const Type &aOther) const { return !(*this == aOther); }
+};
+
+} // namespace ot
+
+#endif // EQUATABLE_HPP_
diff --git a/src/core/common/extension.hpp b/src/core/common/extension.hpp
index 2a5a543..01fde91 100644
--- a/src/core/common/extension.hpp
+++ b/src/core/common/extension.hpp
@@ -37,6 +37,7 @@
 #include "openthread-core-config.h"
 
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 
 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
 
@@ -65,7 +66,7 @@
  * Support for vendor extension can be enabled using `OPENTHREAD_ENABLE_VENDOR_EXTENSION` configuration option.
  *
  */
-class ExtensionBase : public InstanceLocator
+class ExtensionBase : public InstanceLocator, private NonCopyable
 {
 public:
     /**
diff --git a/src/core/common/extension_example.cpp b/src/core/common/extension_example.cpp
index 833b0ce..290914d 100644
--- a/src/core/common/extension_example.cpp
+++ b/src/core/common/extension_example.cpp
@@ -68,7 +68,7 @@
 {
     ExtensionBase *ext = reinterpret_cast<ExtensionBase *>(&sExtensionRaw);
 
-    VerifyOrExit(!ext->mIsInitialized);
+    VerifyOrExit(!ext->mIsInitialized, OT_NOOP);
 
     ext = new (&sExtensionRaw) Extension(aInstance);
 
diff --git a/src/core/common/instance.cpp b/src/core/common/instance.cpp
index 90e9b9d..550423d 100644
--- a/src/core/common/instance.cpp
+++ b/src/core/common/instance.cpp
@@ -37,7 +37,6 @@
 
 #include "common/logging.hpp"
 #include "common/new.hpp"
-#include "thread/router_table.hpp"
 
 namespace ot {
 
@@ -52,8 +51,8 @@
 
 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
 
-otHeapFreeFn   ot::Instance::mFree   = NULL;
-otHeapCAllocFn ot::Instance::mCAlloc = NULL;
+otHeapFreeFn   ot::Instance::mFree   = nullptr;
+otHeapCAllocFn ot::Instance::mCAlloc = nullptr;
 
 #endif // OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
 
@@ -76,6 +75,7 @@
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
     , mNotifier(*this)
     , mSettings(*this)
+    , mSettingsDriver(*this)
     , mMessagePool(*this)
     , mIp6(*this)
     , mThreadNetif(*this)
@@ -94,6 +94,9 @@
 #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
     , mAnnounceSender(*this)
 #endif
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+    , mOtns(*this)
+#endif
 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
     , mLinkRaw(*this)
@@ -117,7 +120,7 @@
 {
     Instance *instance = &Get();
 
-    VerifyOrExit(!instance->mIsInitialized);
+    VerifyOrExit(!instance->mIsInitialized, OT_NOOP);
 
     instance = new (&gInstanceRaw) Instance();
 
@@ -138,14 +141,14 @@
 
 Instance *Instance::Init(void *aBuffer, size_t *aBufferSize)
 {
-    Instance *instance = NULL;
+    Instance *instance = nullptr;
 
-    VerifyOrExit(aBufferSize != NULL);
+    VerifyOrExit(aBufferSize != nullptr, OT_NOOP);
 
     // Make sure the input buffer is big enough
     VerifyOrExit(sizeof(Instance) <= *aBufferSize, *aBufferSize = sizeof(Instance));
 
-    VerifyOrExit(aBuffer != NULL);
+    VerifyOrExit(aBuffer != nullptr, OT_NOOP);
 
     instance = new (aBuffer) Instance();
 
@@ -170,7 +173,7 @@
     // Restore datasets and network information
 
     Get<Settings>().Init();
-    Get<Mle::MleRouter>().Restore();
+    IgnoreError(Get<Mle::MleRouter>().Restore());
 
 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
 
@@ -181,18 +184,20 @@
 
 void Instance::Finalize(void)
 {
-    VerifyOrExit(mIsInitialized);
+    VerifyOrExit(mIsInitialized, OT_NOOP);
 
     mIsInitialized = false;
 
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
-    IgnoreReturnValue(otThreadSetEnabled(this, false));
-    IgnoreReturnValue(otIp6SetEnabled(this, false));
-    IgnoreReturnValue(otLinkSetEnabled(this, false));
+    IgnoreError(otThreadSetEnabled(this, false));
+    IgnoreError(otIp6SetEnabled(this, false));
+    IgnoreError(otLinkSetEnabled(this, false));
 
     Get<Settings>().Deinit();
 #endif
 
+    IgnoreError(Get<Mac::SubMac>().Disable());
+
 #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
 
     /**
@@ -218,7 +223,7 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(Get<Mle::MleRouter>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
     Get<Settings>().Wipe();
 
 exit:
diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp
index 735eddd..df6f7b5 100644
--- a/src/core/common/instance.hpp
+++ b/src/core/common/instance.hpp
@@ -42,7 +42,11 @@
 #include <openthread/error.h>
 #include <openthread/heap.h>
 #include <openthread/platform/logging.h>
+#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
+#include <openthread/platform/memory.h>
+#endif
 
+#include "common/non_copyable.hpp"
 #include "common/random_manager.hpp"
 #include "common/tasklet.hpp"
 #include "common/timer.hpp"
@@ -73,11 +77,23 @@
 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
 #include "utils/channel_monitor.hpp"
 #endif
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+#include "backbone_router/bbr_leader.hpp"
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+#include "backbone_router/bbr_local.hpp"
+#endif
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
 #include "common/extension.hpp"
 #endif
-
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+#include "utils/otns.hpp"
+#endif
 /**
  * @addtogroup core-instance
  *
@@ -104,7 +120,7 @@
  * This class contains all the components used by OpenThread.
  *
  */
-class Instance : public otInstance
+class Instance : public otInstance, private NonCopyable
 {
 public:
 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
@@ -185,7 +201,11 @@
      * @param[in] aLogLevel  A log level.
      *
      */
-    void SetLogLevel(otLogLevel aLogLevel) { mLogLevel = aLogLevel; }
+    void SetLogLevel(otLogLevel aLogLevel)
+    {
+        OT_ASSERT(aLogLevel <= OT_LOG_LEVEL_DEBG && aLogLevel >= OT_LOG_LEVEL_NONE);
+        mLogLevel = aLogLevel;
+    }
 #endif
 
     /**
@@ -217,14 +237,14 @@
 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
     void HeapFree(void *aPointer)
     {
-        assert(mFree != NULL);
+        OT_ASSERT(mFree != nullptr);
 
         mFree(aPointer);
     }
 
     void *HeapCAlloc(size_t aCount, size_t aSize)
     {
-        assert(mCAlloc != NULL);
+        OT_ASSERT(mCAlloc != nullptr);
 
         return mCAlloc(aCount, aSize);
     }
@@ -245,6 +265,9 @@
      *
      */
     Utils::Heap &GetHeap(void) { return mHeap; }
+#else
+    void  HeapFree(void *aPointer) { otPlatFree(aPointer); }
+    void *HeapCAlloc(size_t aCount, size_t aSize) { return otPlatCAlloc(aCount, aSize); }
 #endif // OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
 
 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
@@ -323,9 +346,10 @@
     // Notifier, Settings, and MessagePool are initialized  before
     // other member variables since other classes/objects from their
     // constructor may use them.
-    Notifier    mNotifier;
-    Settings    mSettings;
-    MessagePool mMessagePool;
+    Notifier       mNotifier;
+    Settings       mSettings;
+    SettingsDriver mSettingsDriver;
+    MessagePool    mMessagePool;
 
     Ip6::Ip6    mIp6;
     ThreadNetif mThreadNetif;
@@ -350,6 +374,10 @@
     AnnounceSender mAnnounceSender;
 #endif
 
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+    Utils::Otns mOtns;
+#endif
+
 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
     Mac::LinkRaw mLinkRaw;
@@ -390,6 +418,11 @@
     return mSettings;
 }
 
+template <> inline SettingsDriver &Instance::Get(void)
+{
+    return mSettingsDriver;
+}
+
 template <> inline MeshForwarder &Instance::Get(void)
 {
     return mThreadNetif.mMeshForwarder;
@@ -405,6 +438,12 @@
     return mThreadNetif.mMleRouter;
 }
 
+template <> inline Mle::DiscoverScanner &Instance::Get(void)
+{
+    return mThreadNetif.mDiscoverScanner;
+}
+
+#if OPENTHREAD_FTD
 template <> inline ChildTable &Instance::Get(void)
 {
     return mThreadNetif.mMleRouter.mChildTable;
@@ -414,6 +453,7 @@
 {
     return mThreadNetif.mMleRouter.mRouterTable;
 }
+#endif
 
 template <> inline Ip6::Netif &Instance::Get(void)
 {
@@ -527,6 +567,13 @@
     return mThreadNetif.mNetworkDataLeader;
 }
 
+#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+template <> inline NetworkData::Notifier &Instance::Get(void)
+{
+    return mThreadNetif.mNetworkDataNotifier;
+}
+#endif
+
 template <> inline Ip6::Udp &Instance::Get(void)
 {
     return mIp6.mUdp;
@@ -677,6 +724,36 @@
     return mMessagePool;
 }
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
+template <> inline BackboneRouter::Leader &Instance::Get(void)
+{
+    return mThreadNetif.mBackboneRouterLeader;
+}
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+template <> inline BackboneRouter::Local &Instance::Get(void)
+{
+    return mThreadNetif.mBackboneRouterLocal;
+}
+#endif
+
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+template <> inline DuaManager &Instance::Get(void)
+{
+    return mThreadNetif.mDuaManager;
+}
+#endif
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+template <> inline Utils::Otns &Instance::Get(void)
+{
+    return mOtns;
+}
+#endif
+
 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
 
 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
diff --git a/src/core/common/linked_list.hpp b/src/core/common/linked_list.hpp
index 2f65044..166405f 100644
--- a/src/core/common/linked_list.hpp
+++ b/src/core/common/linked_list.hpp
@@ -69,7 +69,7 @@
     /**
      * This method gets the next entry in the linked list.
      *
-     * @returns A pointer to the next entry in the linked list or NULL if at the end of the list.
+     * @returns A pointer to the next entry in the linked list or nullptr if at the end of the list.
      *
      */
     const Type *GetNext(void) const { return static_cast<const Type *>(static_cast<const Type *>(this)->mNext); }
@@ -77,7 +77,7 @@
     /**
      * This method gets the next entry in the linked list.
      *
-     * @returns A pointer to the next entry in the linked list or NULL if at the end of the list.
+     * @returns A pointer to the next entry in the linked list or nullptr if at the end of the list.
      *
      */
     Type *GetNext(void) { return static_cast<Type *>(static_cast<Type *>(this)->mNext); }
@@ -106,14 +106,14 @@
      *
      */
     LinkedList(void)
-        : mHead(NULL)
+        : mHead(nullptr)
     {
     }
 
     /**
      * This method returns the entry at the head of the linked list
      *
-     * @returns Pointer to the entry at the head of the linked list, or NULL if list is empty.
+     * @returns Pointer to the entry at the head of the linked list, or nullptr if the list is empty.
      *
      */
     Type *GetHead(void) { return mHead; }
@@ -121,7 +121,7 @@
     /**
      * This method returns the entry at the head of the linked list.
      *
-     * @returns Pointer to the entry at the head of the linked list, or NULL if list is empty.
+     * @returns Pointer to the entry at the head of the linked list, or nullptr if the list is empty.
      *
      */
     const Type *GetHead(void) const { return mHead; }
@@ -138,7 +138,7 @@
      * This method clears the linked list.
      *
      */
-    void Clear(void) { mHead = NULL; }
+    void Clear(void) { mHead = nullptr; }
 
     /**
      * This method indicates whether the linked list is empty or not.
@@ -147,7 +147,7 @@
      * @retval FALSE  If the linked list is not empty.
      *
      */
-    bool IsEmpty(void) const { return (mHead == NULL); }
+    bool IsEmpty(void) const { return (mHead == nullptr); }
 
     /**
      * This method pushes an entry at the head of the linked list.
@@ -179,14 +179,14 @@
      *
      * @note This method does not change the popped entry itself, i.e., the popped entry next pointer stays as before.
      *
-     * @returns The entry that was popped if list is not empty, or NULL if list is empty.
+     * @returns The entry that was popped if the list is not empty, or nullptr if the list is empty.
      *
      */
     Type *Pop(void)
     {
         Type *entry = mHead;
 
-        if (mHead != NULL)
+        if (mHead != nullptr)
         {
             mHead = mHead->GetNext();
         }
@@ -199,18 +199,28 @@
      *
      * @note This method does not change the popped entry itself, i.e., the popped entry next pointer stays as before.
      *
-     * @param[in] aPrevEntry  A reference to n previous entry (the entry after this will be popped).
-
-     * @returns The entry that was popped if list is not empty, or NULL if there is no entry after the given one.
+     * @param[in] aPrevEntry  A pointer to a previous entry. If it is not nullptr the entry after this will be popped,
+     *                        otherwise (if it is nullptr) the entry at the head of the list is popped.
+     *
+     * @returns Pointer to the entry that was popped, or nullptr if there is no entry to pop.
      *
      */
-    Type *PopAfter(Type &aPrevEntry)
+    Type *PopAfter(Type *aPrevEntry)
     {
-        Type *entry = aPrevEntry.GetNext();
+        Type *entry;
 
-        if (entry != NULL)
+        if (aPrevEntry == nullptr)
         {
-            aPrevEntry.SetNext(entry->GetNext());
+            entry = Pop();
+        }
+        else
+        {
+            entry = aPrevEntry->GetNext();
+
+            if (entry != nullptr)
+            {
+                aPrevEntry->SetNext(entry->GetNext());
+            }
         }
 
         return entry;
@@ -225,20 +235,33 @@
      * @retval FALSE  The linked list does not contain @p aEntry.
      *
      */
-    bool Contains(Type &aEntry) const
+    bool Contains(const Type &aEntry) const
     {
-        bool contains = false;
+        const Type *prev;
 
-        for (Type *cur = mHead; cur != NULL; cur = cur->GetNext())
-        {
-            if (cur == &aEntry)
-            {
-                contains = true;
-                break;
-            }
-        }
+        return Find(aEntry, prev) == OT_ERROR_NONE;
+    }
 
-        return contains;
+    /**
+     * This template method indicates whether the linked list contains an entry matching a given entry indicator.
+     *
+     * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
+     * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
+     * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
+     *
+     *     bool Type::Matches(const Indicator &aIndicator) const
+     *
+     * @param[in] aIndicator   An entry indicator to match against entries in the list.
+     *
+     * @retval TRUE   The linked list contains an entry matching @p aIndicator.
+     * @retval FALSE  The linked list contains no entry matching @p aIndicator.
+     *
+     */
+    template <typename Indicator> bool ContainsMatching(const Indicator &aIndicator) const
+    {
+        const Type *prev;
+
+        return FindMatching(aIndicator, prev) != nullptr;
     }
 
     /**
@@ -269,7 +292,7 @@
     /**
      * This method removes an entry from the linked list.
      *
-     * @note This method does not change the removed entry @p aEntry itself (it is `const`), i.e., the  entry next
+     * @note This method does not change the removed entry @p aEntry itself (it is `const`), i.e., the entry next
      * pointer of @p aEntry stays as before.
      *
      * @param[in] aEntry   A reference to an entry to remove.
@@ -280,23 +303,72 @@
      */
     otError Remove(const Type &aEntry)
     {
+        Type *  prev;
+        otError error = Find(aEntry, prev);
+
+        if (error == OT_ERROR_NONE)
+        {
+            PopAfter(prev);
+        }
+
+        return error;
+    }
+
+    /**
+     * This template method removes an entry matching a given entry indicator from the linked list.
+     *
+     * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
+     * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
+     * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
+     *
+     *     bool Type::Matches(const Indicator &aIndicator) const
+     *
+     * @note This method does not change the removed entry itself (which is returned in case of success), i.e., the
+     * entry next pointer stays as before.
+     *
+     *
+     * @param[in] aIndicator   An entry indicator to match against entries in the list.
+     *
+     * @returns A pointer to the removed matching entry if one could be found, or nullptr if no matching entry is found.
+     *
+     */
+    template <typename Indicator> Type *RemoveMatching(const Indicator &aIndicator)
+    {
+        Type *prev;
+        Type *entry = FindMatching(aIndicator, prev);
+
+        if (entry != nullptr)
+        {
+            PopAfter(prev);
+        }
+
+        return entry;
+    }
+
+    /**
+     * This method searches within the linked list to find an entry and if found returns a pointer to previous entry.
+     *
+     * @param[in]  aEntry      A reference to an entry to find.
+     * @param[out] aPrevEntry  A pointer to output the previous entry on success (when @p aEntry is found in the list).
+     *                         @p aPrevEntry is set to nullptr if @p aEntry is the head of the list. Otherwise it is
+     *                         updated to point to the previous entry before @p aEntry in the list.
+     *
+     * @retval OT_ERROR_NONE       The entry was found in the list and @p aPrevEntry was updated successfully.
+     * @retval OT_ERROR_NOT_FOUND  The entry was not found in the list.
+     *
+     */
+    otError Find(const Type &aEntry, const Type *&aPrevEntry) const
+    {
         otError error = OT_ERROR_NOT_FOUND;
 
-        if (mHead == &aEntry)
+        aPrevEntry = nullptr;
+
+        for (const Type *entry = mHead; entry != nullptr; aPrevEntry = entry, entry = entry->GetNext())
         {
-            Pop();
-            error = OT_ERROR_NONE;
-        }
-        else if (mHead != NULL)
-        {
-            for (Type *cur = mHead; cur->GetNext() != NULL; cur = cur->GetNext())
+            if (entry == &aEntry)
             {
-                if (cur->GetNext() == &aEntry)
-                {
-                    cur->SetNext(cur->GetNext()->GetNext());
-                    error = OT_ERROR_NONE;
-                    break;
-                }
+                error = OT_ERROR_NONE;
+                break;
             }
         }
 
@@ -307,52 +379,90 @@
      * This method searches within the linked list to find an entry and if found returns a pointer to previous entry.
      *
      * @param[in]  aEntry      A reference to an entry to find.
-     * @param[out] aPrevEntry  A pointer to output previous entry on success (when @p aEntry is found is the list).
-     *                         @p aPrevEntry is set to NULL if the @p aEntry is head of the list. Otherwise it
-     *                         is updated to point to previous entry before @p aEntry in the list.
+     * @param[out] aPrevEntry  A pointer to output the previous entry on success (when @p aEntry is found in the list).
+     *                         @p aPrevEntry is set to nullptr if @p aEntry is the head of the list. Otherwise it is
+     *                         updated to point to the previous entry before @p aEntry in the list.
      *
      * @retval OT_ERROR_NONE       The entry was found in the list and @p aPrevEntry was updated successfully.
      * @retval OT_ERROR_NOT_FOUND  The entry was not found in the list.
      *
      */
-    otError Find(const Type &aEntry, Type *&aPrevEntry) const
+    otError Find(const Type &aEntry, Type *&aPrevEntry)
     {
-        otError error = OT_ERROR_NOT_FOUND;
+        return const_cast<const LinkedList *>(this)->Find(aEntry, const_cast<const Type *&>(aPrevEntry));
+    }
 
-        if (mHead == &aEntry)
+    /**
+     * This template method searches within the linked list to find an entry matching a given indicator.
+     *
+     * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
+     * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
+     * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
+     *
+     *     bool Type::Matches(const Indicator &aIndicator) const
+     *
+     * @param[in]  aIndicator  An indicator to match with entries in the list..
+     * @param[out] aPrevEntry  A pointer to output the previous entry on success (when a match is found in the list).
+     *                         @p aPrevEntry is set to nullptr if the matching entry is the head of the list. Otherwise
+     *                         it is updated to point to the previous entry before the matching entry in the list.
+     *
+     * @returns A pointer to the matching entry if one is found, or nullptr if no matching entry was found.
+     *
+     */
+    template <typename Inidcator> const Type *FindMatching(const Inidcator &aIndicator, const Type *&aPrevEntry) const
+    {
+        const Type *entry;
+
+        aPrevEntry = nullptr;
+
+        for (entry = mHead; entry != nullptr; aPrevEntry = entry, entry = entry->GetNext())
         {
-            aPrevEntry = NULL;
-            error      = OT_ERROR_NONE;
-        }
-        else
-        {
-            for (Type *cur = mHead; cur->GetNext() != NULL; cur = cur->GetNext())
+            if (entry->Matches(aIndicator))
             {
-                if (cur->GetNext() == &aEntry)
-                {
-                    aPrevEntry = cur;
-                    error      = OT_ERROR_NONE;
-                    break;
-                }
+                break;
             }
         }
 
-        return error;
+        return entry;
+    }
+
+    /**
+     * This template method searches within the linked list to find an entry matching a given indicator, and if found
+     * returns a pointer to its previous entry in the list.
+     *
+     * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
+     * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
+     * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
+     *
+     *     bool Type::Matches(const Indicator &aIndicator) const
+     *
+     * @param[in]  aIndicator  An indicator to match with entries in the list..
+     * @param[out] aPrevEntry  A pointer to output the previous entry on success (when a match is found in the list).
+     *                         @p aPrevEntry is set to nullptr if the matching entry is the head of the list. Otherwise
+     *                         it is updated to point to the previous entry before the matching entry in the list.
+     *
+     * @returns A pointer to the matching entry if one is found, or nullptr if no matching entry was found.
+     *
+     */
+    template <typename Inidcator> Type *FindMatching(const Inidcator &aIndicator, Type *&aPrevEntry)
+    {
+        return const_cast<Type *>(
+            const_cast<const LinkedList *>(this)->FindMatching(aIndicator, const_cast<const Type *&>(aPrevEntry)));
     }
 
     /**
      * This method returns the tail of the linked list (i.e., the last entry in the list).
      *
-     * @returns A pointer to tail entry in the linked list or NULL if list is empty.
+     * @returns A pointer to the tail entry in the linked list or nullptr if the list is empty.
      *
      */
     const Type *GetTail(void) const
     {
         const Type *tail = mHead;
 
-        if (tail != NULL)
+        if (tail != nullptr)
         {
-            while (tail->GetNext() != NULL)
+            while (tail->GetNext() != nullptr)
             {
                 tail = tail->GetNext();
             }
@@ -364,10 +474,10 @@
     /**
      * This method returns the tail of the linked list (i.e., the last entry in the list).
      *
-     * @returns A pointer to tail entry in the linked list or NULL if list is empty.
+     * @returns A pointer to the tail entry in the linked list or nullptr if the list is empty.
      *
      */
-    Type *GetTail(void) { return const_cast<Type *>(const_cast<const LinkedList<Type> *>(this)->GetTail()); }
+    Type *GetTail(void) { return const_cast<Type *>(const_cast<const LinkedList *>(this)->GetTail()); }
 
 private:
     Type *mHead;
diff --git a/src/core/common/locator.hpp b/src/core/common/locator.hpp
index cf22013..8655cac 100644
--- a/src/core/common/locator.hpp
+++ b/src/core/common/locator.hpp
@@ -71,6 +71,8 @@
  */
 class InstanceLocator
 {
+    friend class InstanceLocatorInit;
+
 public:
     /**
      * This method returns a reference to the parent OpenThread Instance.
@@ -79,7 +81,7 @@
      *
      */
 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
-    Instance &GetInstance(void) const { return mInstance; }
+    Instance &GetInstance(void) const { return *mInstance; }
 #else
     Instance &GetInstance(void) const { return *reinterpret_cast<Instance *>(&gInstanceRaw); }
 #endif
@@ -101,24 +103,65 @@
     /**
      * This constructor initializes the object.
      *
-     * @param[in]  aInstance  A pointer to the otInstance.
+     * @param[in]  aInstance  A reference to the OpenThread Instance.
      *
      */
     explicit InstanceLocator(Instance &aInstance)
 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
-        : mInstance(aInstance)
+        : mInstance(&aInstance)
 #endif
     {
         OT_UNUSED_VARIABLE(aInstance);
     }
 
-#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
 private:
-    Instance &mInstance;
+    InstanceLocator(void) {}
+
+#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
+    Instance *mInstance;
 #endif
 };
 
 /**
+ * This class implements a locator for an OpenThread Instance object.
+ *
+ * The `InstanceLocatorInit` is similar to `InstanceLocator` but provides a default constructor (instead of a
+ * parameterized one) and allows an inheriting class to initialize the object (set the OpenThread Instance) post
+ * constructor call using the `Init()` method. This class is intended for types that require a default constructor and
+ * cannot use a parameterized one. (e.g., `Neighbor`/`Child`/`Router` classes which are used as a C array element type
+ * in`ChildTable`/`RouterTable`).
+ *
+ * The inheriting class from `InstanceLocatorInit` should ensure that object is properly initialized after the object
+ * is created and more importantly that it is re-initialized when/if it is cleared or reset.
+ *
+ */
+class InstanceLocatorInit : public InstanceLocator
+{
+protected:
+    /**
+     * This is the default constructor for the `InstanceLocatorInit` object.
+     *
+     */
+    InstanceLocatorInit(void)
+        : InstanceLocator()
+    {
+    }
+
+    /**
+     * This method (re)initializes the object and sets the OpenThread Instance.
+     *
+     * @param[in] aInstance  A reference to the OpenThread Instance.
+     */
+    void Init(Instance &aInstance)
+    {
+#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
+        mInstance = &aInstance;
+#endif
+        OT_UNUSED_VARIABLE(aInstance);
+    }
+};
+
+/**
  * This class implements a locator for owner of an object.
  *
  * This is used as the base class for objects that provide a callback (e.g., `Timer` or `Tasklet`).
diff --git a/src/core/common/logging.cpp b/src/core/common/logging.cpp
index 9f1b551..7d5136e 100644
--- a/src/core/common/logging.cpp
+++ b/src/core/common/logging.cpp
@@ -44,8 +44,7 @@
 #error OPENTHREAD_CONFIG_ENABLE_DEBUG_UART_LOG requires OPENTHREAD_CONFIG_ENABLE_DEBUG_UART
 #endif
 
-#define otLogDump(aFormat, ...) \
-    _otDynamicLog(aLogLevel, aLogRegion, aFormat OPENTHREAD_CONFIG_LOG_SUFFIX, ##__VA_ARGS__)
+#define otLogDump(aFormat, ...) _otDynamicLog(aLogLevel, aLogRegion, aFormat OPENTHREAD_CONFIG_LOG_SUFFIX, __VA_ARGS__)
 
 #ifdef __cplusplus
 extern "C" {
@@ -124,7 +123,7 @@
         cur += strlen(cur);
     }
 
-    snprintf(cur, sizeof(buf) - static_cast<size_t>(cur - buf), "[%s len=%03u]", aId, static_cast<uint16_t>(aLength));
+    snprintf(cur, sizeof(buf) - static_cast<size_t>(cur - buf), "[%s len=%03u]", aId, static_cast<unsigned>(aLength));
     cur += strlen(cur);
 
     for (size_t i = 0; i < (width - idlen) / 2 - 4; i++)
@@ -192,6 +191,7 @@
     "NonLowpanDataFrame",         // OT_ERROR_NOT_LOWPAN_DATA_FRAME = 32
     "ReservedError33",            // otError 33 is reserved
     "LinkMarginLow",              // OT_ERROR_LINK_MARGIN_LOW = 34
+    "InvalidCommand",             // OT_ERROR_INVALID_COMMAND = 35
 };
 
 const char *otThreadErrorToString(otError aError)
diff --git a/src/core/common/logging.hpp b/src/core/common/logging.hpp
index d5d886c..6e9ff16 100644
--- a/src/core/common/logging.hpp
+++ b/src/core/common/logging.hpp
@@ -89,6 +89,8 @@
 #define _OT_REGION_CLI_PREFIX "-CLI-----: "
 #define _OT_REGION_CORE_PREFIX "-CORE----: "
 #define _OT_REGION_UTIL_PREFIX "-UTIL----: "
+#define _OT_REGION_BBR_PREFIX "-BBR-----: "
+#define _OT_REGION_MLR_PREFIX "-MLR-----: "
 #else
 #define _OT_REGION_API_PREFIX _OT_REGION_SUFFIX
 #define _OT_REGION_MLE_PREFIX _OT_REGION_SUFFIX
@@ -106,6 +108,8 @@
 #define _OT_REGION_CLI_PREFIX _OT_REGION_SUFFIX
 #define _OT_REGION_CORE_PREFIX _OT_REGION_SUFFIX
 #define _OT_REGION_UTIL_PREFIX _OT_REGION_SUFFIX
+#define _OT_REGION_BBR_PREFIX _OT_REGION_SUFFIX
+#define _OT_REGION_MLR_PREFIX _OT_REGION_SUFFIX
 #endif
 
 /**
@@ -114,15 +118,13 @@
  * Logging at log level critical.
  *
  * @param[in]  aRegion   The log region.
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_CRIT
-#define otLogCrit(aRegion, aFormat, ...) \
-    _otLogFormatter(OT_LOG_LEVEL_CRIT, aRegion, _OT_LEVEL_CRIT_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCrit(aRegion, ...) _otLogFormatter(OT_LOG_LEVEL_CRIT, aRegion, _OT_LEVEL_CRIT_PREFIX __VA_ARGS__, NULL)
 #else
-#define otLogCrit(aRegion, aFormat, ...)
+#define otLogCrit(aRegion, ...)
 #endif
 
 /**
@@ -131,15 +133,13 @@
  * Logging at log level warning.
  *
  * @param[in]  aRegion   The log region.
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN
-#define otLogWarn(aRegion, aFormat, ...) \
-    _otLogFormatter(OT_LOG_LEVEL_WARN, aRegion, _OT_LEVEL_WARN_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogWarn(aRegion, ...) _otLogFormatter(OT_LOG_LEVEL_WARN, aRegion, _OT_LEVEL_WARN_PREFIX __VA_ARGS__, NULL)
 #else
-#define otLogWarn(aRegion, aFormat, ...)
+#define otLogWarn(aRegion, ...)
 #endif
 
 /**
@@ -148,15 +148,13 @@
  * Logging at log level note
  *
  * @param[in]  aRegion   The log region.
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE
-#define otLogNote(aRegion, aFormat, ...) \
-    _otLogFormatter(OT_LOG_LEVEL_NOTE, aRegion, _OT_LEVEL_NOTE_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogNote(aRegion, ...) _otLogFormatter(OT_LOG_LEVEL_NOTE, aRegion, _OT_LEVEL_NOTE_PREFIX __VA_ARGS__, NULL)
 #else
-#define otLogNote(aRegion, aFormat, ...)
+#define otLogNote(aRegion, ...)
 #endif
 
 /**
@@ -165,15 +163,13 @@
  * Logging at log level info.
  *
  * @param[in]  aRegion   The log region.
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO
-#define otLogInfo(aRegion, aFormat, ...) \
-    _otLogFormatter(OT_LOG_LEVEL_INFO, aRegion, _OT_LEVEL_INFO_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogInfo(aRegion, ...) _otLogFormatter(OT_LOG_LEVEL_INFO, aRegion, _OT_LEVEL_INFO_PREFIX __VA_ARGS__, NULL)
 #else
-#define otLogInfo(aRegion, aFormat, ...)
+#define otLogInfo(aRegion, ...)
 #endif
 
 /**
@@ -182,15 +178,13 @@
  * Logging at log level debug.
  *
  * @param[in]  aRegion   The log region.
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_DEBG
-#define otLogDebg(aRegion, aFormat, ...) \
-    _otLogFormatter(OT_LOG_LEVEL_DEBG, aRegion, _OT_LEVEL_DEBG_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogDebg(aRegion, ...) _otLogFormatter(OT_LOG_LEVEL_DEBG, aRegion, _OT_LEVEL_DEBG_PREFIX __VA_ARGS__, NULL)
 #else
-#define otLogDebg(aRegion, aFormat, ...)
+#define otLogDebg(aRegion, ...)
 #endif
 
 /**
@@ -198,8 +192,7 @@
  *
  * This method generates a log with level critical for the API region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -208,8 +201,7 @@
  *
  * This method generates a log with level warning for the API region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -218,8 +210,7 @@
  *
  * This method generates a log with level note for the API region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -228,8 +219,7 @@
  *
  * This method generates a log with level info for the API region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -238,22 +228,21 @@
  *
  * This method generates a log with level debug for the API region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_API == 1
-#define otLogCritApi(aFormat, ...) otLogCrit(OT_LOG_REGION_API, _OT_REGION_API_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnApi(aFormat, ...) otLogWarn(OT_LOG_REGION_API, _OT_REGION_API_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteApi(aFormat, ...) otLogNote(OT_LOG_REGION_API, _OT_REGION_API_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoApi(aFormat, ...) otLogInfo(OT_LOG_REGION_API, _OT_REGION_API_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgApi(aFormat, ...) otLogDebg(OT_LOG_REGION_API, _OT_REGION_API_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritApi(...) otLogCrit(OT_LOG_REGION_API, _OT_REGION_API_PREFIX __VA_ARGS__)
+#define otLogWarnApi(...) otLogWarn(OT_LOG_REGION_API, _OT_REGION_API_PREFIX __VA_ARGS__)
+#define otLogNoteApi(...) otLogNote(OT_LOG_REGION_API, _OT_REGION_API_PREFIX __VA_ARGS__)
+#define otLogInfoApi(...) otLogInfo(OT_LOG_REGION_API, _OT_REGION_API_PREFIX __VA_ARGS__)
+#define otLogDebgApi(...) otLogDebg(OT_LOG_REGION_API, _OT_REGION_API_PREFIX __VA_ARGS__)
 #else
-#define otLogCritApi(aFormat, ...)
-#define otLogWarnApi(aFormat, ...)
-#define otLogNoteApi(aFormat, ...)
-#define otLogInfoApi(aFormat, ...)
-#define otLogDebgApi(aFormat, ...)
+#define otLogCritApi(...)
+#define otLogWarnApi(...)
+#define otLogNoteApi(...)
+#define otLogInfoApi(...)
+#define otLogDebgApi(...)
 #endif
 
 /**
@@ -261,8 +250,7 @@
  *
  * This method generates a log with level critical for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  *
  */
@@ -272,8 +260,7 @@
  *
  * This method generates a log with level warning for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -282,8 +269,7 @@
  *
  * This method generates a log with level note for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -292,8 +278,7 @@
  *
  * This method generates a log with level info for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -302,42 +287,35 @@
  *
  * This method generates a log with level debug for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
-#if OPENTHREAD_CONFIG_LOG_MLE == 1
-#define otLogCritMeshCoP(aFormat, ...) \
-    otLogCrit(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnMeshCoP(aFormat, ...) \
-    otLogWarn(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteMeshCoP(aFormat, ...) \
-    otLogNote(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoMeshCoP(aFormat, ...) \
-    otLogInfo(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgMeshCoP(aFormat, ...) \
-    otLogDebg(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX aFormat, ##__VA_ARGS__)
+#if OPENTHREAD_CONFIG_LOG_MESHCOP == 1
+#define otLogCritMeshCoP(...) otLogCrit(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX __VA_ARGS__)
+#define otLogWarnMeshCoP(...) otLogWarn(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX __VA_ARGS__)
+#define otLogNoteMeshCoP(...) otLogNote(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX __VA_ARGS__)
+#define otLogInfoMeshCoP(...) otLogInfo(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX __VA_ARGS__)
+#define otLogDebgMeshCoP(...) otLogDebg(OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX __VA_ARGS__)
 #else
-#define otLogCritMeshCoP(aFormat, ...)
-#define otLogWarnMeshCoP(aFormat, ...)
-#define otLogNoteMeshCoP(aFormat, ...)
-#define otLogInfoMeshCoP(aFormat, ...)
-#define otLogDebgMeshCoP(aFormat, ...)
+#define otLogCritMeshCoP(...)
+#define otLogWarnMeshCoP(...)
+#define otLogNoteMeshCoP(...)
+#define otLogInfoMeshCoP(...)
+#define otLogDebgMeshCoP(...)
 #endif
 
-#define otLogCritMbedTls(aFormat, ...) otLogCritMeshCoP(aFormat, ##__VA_ARGS__)
-#define otLogWarnMbedTls(aFormat, ...) otLogWarnMeshCoP(aFormat, ##__VA_ARGS__)
-#define otLogNoteMbedTls(aFormat, ...) otLogNoteMeshCoP(aFormat, ##__VA_ARGS__)
-#define otLogInfoMbedTls(aFormat, ...) otLogInfoMeshCoP(aFormat, ##__VA_ARGS__)
-#define otLogDebgMbedTls(aFormat, ...) otLogDebgMeshCoP(aFormat, ##__VA_ARGS__)
+#define otLogCritMbedTls(...) otLogCritMeshCoP(__VA_ARGS__)
+#define otLogWarnMbedTls(...) otLogWarnMeshCoP(__VA_ARGS__)
+#define otLogNoteMbedTls(...) otLogNoteMeshCoP(__VA_ARGS__)
+#define otLogInfoMbedTls(...) otLogInfoMeshCoP(__VA_ARGS__)
+#define otLogDebgMbedTls(...) otLogDebgMeshCoP(__VA_ARGS__)
 
 /**
  * @def otLogCritMle
  *
  * This method generates a log with level critical for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -346,8 +324,7 @@
  *
  * This method generates a log with level warning for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -356,8 +333,7 @@
  *
  * This method generates a log with level note for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -366,8 +342,7 @@
  *
  * This method generates a log with level info for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -376,23 +351,22 @@
  *
  * This method generates a log with level debug for the MLE region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  *
  */
 #if OPENTHREAD_CONFIG_LOG_MLE == 1
-#define otLogCritMle(aFormat, ...) otLogCrit(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnMle(aFormat, ...) otLogWarn(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteMle(aFormat, ...) otLogNote(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoMle(aFormat, ...) otLogInfo(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgMle(aFormat, ...) otLogDebg(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritMle(...) otLogCrit(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX __VA_ARGS__)
+#define otLogWarnMle(...) otLogWarn(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX __VA_ARGS__)
+#define otLogNoteMle(...) otLogNote(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX __VA_ARGS__)
+#define otLogInfoMle(...) otLogInfo(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX __VA_ARGS__)
+#define otLogDebgMle(...) otLogDebg(OT_LOG_REGION_MLE, _OT_REGION_MLE_PREFIX __VA_ARGS__)
 #else
-#define otLogCritMle(aFormat, ...)
-#define otLogWarnMle(aFormat, ...)
-#define otLogNoteMle(aFormat, ...)
-#define otLogInfoMle(aFormat, ...)
-#define otLogDebgMle(aFormat, ...)
+#define otLogCritMle(...)
+#define otLogWarnMle(...)
+#define otLogNoteMle(...)
+#define otLogInfoMle(...)
+#define otLogDebgMle(...)
 #endif
 
 /**
@@ -400,8 +374,7 @@
  *
  * This method generates a log with level critical for the EID-to-RLOC mapping region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -410,18 +383,16 @@
  *
  * This method generates a log with level warning for the EID-to-RLOC mapping region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
 /**
- * @def otLogInfoArp
+ * @def otLogNoteArp
  *
  * This method generates a log with level note for the EID-to-RLOC mapping region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -430,8 +401,7 @@
  *
  * This method generates a log with level info for the EID-to-RLOC mapping region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -440,22 +410,137 @@
  *
  * This method generates a log with level debug for the EID-to-RLOC mapping region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_ARP == 1
-#define otLogCritArp(aFormat, ...) otLogCrit(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnArp(aFormat, ...) otLogWarn(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteArp(aFormat, ...) otLogNote(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoArp(aFormat, ...) otLogInfo(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgArp(aFormat, ...) otLogDebg(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritArp(...) otLogCrit(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX __VA_ARGS__)
+#define otLogWarnArp(...) otLogWarn(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX __VA_ARGS__)
+#define otLogNoteArp(...) otLogNote(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX __VA_ARGS__)
+#define otLogInfoArp(...) otLogInfo(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX __VA_ARGS__)
+#define otLogDebgArp(...) otLogDebg(OT_LOG_REGION_ARP, _OT_REGION_ARP_PREFIX __VA_ARGS__)
 #else
-#define otLogCritArp(aFormat, ...)
-#define otLogWarnArp(aFormat, ...)
-#define otLogNoteArp(aFormat, ...)
-#define otLogInfoArp(aFormat, ...)
-#define otLogDebgArp(aFormat, ...)
+#define otLogCritArp(...)
+#define otLogWarnArp(...)
+#define otLogNoteArp(...)
+#define otLogInfoArp(...)
+#define otLogDebgArp(...)
+#endif
+
+/**
+ * @def otLogCritBbr
+ *
+ * This method generates a log with level critical for the Backbone Router (BBR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogWarnBbr
+ *
+ * This method generates a log with level warning for the Backbone Router (BBR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogNoteBbr
+ *
+ * This method generates a log with level note for the Backbone Router (BBR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogInfoBbr
+ *
+ * This method generates a log with level info for the Backbone Router (BBR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogDebgBbr
+ *
+ * This method generates a log with level debug for the Backbone Router (BBR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+#if OPENTHREAD_CONFIG_LOG_BBR == 1
+#define otLogCritBbr(...) otLogCrit(OT_LOG_REGION_BBR, _OT_REGION_BBR_PREFIX __VA_ARGS__)
+#define otLogWarnBbr(...) otLogWarn(OT_LOG_REGION_BBR, _OT_REGION_BBR_PREFIX __VA_ARGS__)
+#define otLogNoteBbr(...) otLogNote(OT_LOG_REGION_BBR, _OT_REGION_BBR_PREFIX __VA_ARGS__)
+#define otLogInfoBbr(...) otLogInfo(OT_LOG_REGION_BBR, _OT_REGION_BBR_PREFIX __VA_ARGS__)
+#define otLogDebgBbr(...) otLogDebg(OT_LOG_REGION_BBR, _OT_REGION_BBR_PREFIX __VA_ARGS__)
+#else
+#define otLogCritBbr(...)
+#define otLogWarnBbr(...)
+#define otLogNoteBbr(...)
+#define otLogInfoBbr(...)
+#define otLogDebgBbr(...)
+#endif
+
+/**
+ * @def otLogCritMlr
+ *
+ * This method generates a log with level critical for the Multicast Listener Registration (MLR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogWarnMlr
+ *
+ * This method generates a log with level warning for the Multicast Listener Registration (MLR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogNoteMlr
+ *
+ * This method generates a log with level note for the Multicast Listener Registration (MLR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogInfoMlr
+ *
+ * This method generates a log with level info for the Multicast Listener Registration (MLR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogDebgMlr
+ *
+ * This method generates a log with level debug for the Multicast Listener Registration (MLR) region.
+ *
+ * @param[in]  ...  Arguments for the format specification.
+ *
+ */
+#if OPENTHREAD_CONFIG_LOG_MLR == 1
+#define otLogCritMlr(...) otLogCrit(OT_LOG_REGION_MLR, _OT_REGION_MLR_PREFIX __VA_ARGS__)
+#define otLogWarnMlr(...) otLogWarn(OT_LOG_REGION_MLR, _OT_REGION_MLR_PREFIX __VA_ARGS__)
+#define otLogNoteMlr(...) otLogNote(OT_LOG_REGION_MLR, _OT_REGION_MLR_PREFIX __VA_ARGS__)
+#define otLogInfoMlr(...) otLogInfo(OT_LOG_REGION_MLR, _OT_REGION_MLR_PREFIX __VA_ARGS__)
+#define otLogDebgMlr(...) otLogDebg(OT_LOG_REGION_MLR, _OT_REGION_MLR_PREFIX __VA_ARGS__)
+#else
+#define otLogCritMlr(...)
+#define otLogWarnMlr(...)
+#define otLogNoteMlr(...)
+#define otLogInfoMlr(...)
+#define otLogDebgMlr(...)
 #endif
 
 /**
@@ -463,8 +548,7 @@
  *
  * This method generates a log with level critical for the Network Data region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -473,18 +557,16 @@
  *
  * This method generates a log with level warning for the Network Data region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
 /**
- * @def otLogInfoNetData
+ * @def otLogNoteNetData
  *
  * This method generates a log with level note for the Network Data region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -493,8 +575,7 @@
  *
  * This method generates a log with level info for the Network Data region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -503,27 +584,21 @@
  *
  * This method generates a log with level debug for the Network Data region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_NETDATA == 1
-#define otLogCritNetData(aFormat, ...) \
-    otLogCrit(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnNetData(aFormat, ...) \
-    otLogWarn(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteNetData(aFormat, ...) \
-    otLogNote(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoNetData(aFormat, ...) \
-    otLogInfo(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgNetData(aFormat, ...) \
-    otLogDebg(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritNetData(...) otLogCrit(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX __VA_ARGS__)
+#define otLogWarnNetData(...) otLogWarn(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX __VA_ARGS__)
+#define otLogNoteNetData(...) otLogNote(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX __VA_ARGS__)
+#define otLogInfoNetData(...) otLogInfo(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX __VA_ARGS__)
+#define otLogDebgNetData(...) otLogDebg(OT_LOG_REGION_NET_DATA, _OT_REGION_NET_DATA_PREFIX __VA_ARGS__)
 #else
-#define otLogCritNetData(aFormat, ...)
-#define otLogWarnNetData(aFormat, ...)
-#define otLogNoteNetData(aFormat, ...)
-#define otLogInfoNetData(aFormat, ...)
-#define otLogDebgNetData(aFormat, ...)
+#define otLogCritNetData(...)
+#define otLogWarnNetData(...)
+#define otLogNoteNetData(...)
+#define otLogInfoNetData(...)
+#define otLogDebgNetData(...)
 #endif
 
 /**
@@ -531,8 +606,7 @@
  *
  * This method generates a log with level critical for the ICMPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -541,8 +615,7 @@
  *
  * This method generates a log with level warning for the ICMPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -551,8 +624,7 @@
  *
  * This method generates a log with level note for the ICMPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -561,8 +633,7 @@
  *
  * This method generates a log with level info for the ICMPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -571,22 +642,21 @@
  *
  * This method generates a log with level debug for the ICMPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_ICMP == 1
-#define otLogCritIcmp(aFormat, ...) otLogCrit(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnIcmp(aFormat, ...) otLogWarn(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteIcmp(aFormat, ...) otLogNote(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoIcmp(aFormat, ...) otLogInfo(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgIcmp(aFormat, ...) otLogDebg(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritIcmp(...) otLogCrit(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX __VA_ARGS__)
+#define otLogWarnIcmp(...) otLogWarn(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX __VA_ARGS__)
+#define otLogNoteIcmp(...) otLogNote(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX __VA_ARGS__)
+#define otLogInfoIcmp(...) otLogInfo(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX __VA_ARGS__)
+#define otLogDebgIcmp(...) otLogDebg(OT_LOG_REGION_ICMP, _OT_REGION_ICMP_PREFIX __VA_ARGS__)
 #else
-#define otLogCritIcmp(aFormat, ...)
-#define otLogWarnIcmp(aFormat, ...)
-#define otLogNoteIcmp(aFormat, ...)
-#define otLogInfoIcmp(aFormat, ...)
-#define otLogDebgIcmp(aFormat, ...)
+#define otLogCritIcmp(...)
+#define otLogWarnIcmp(...)
+#define otLogNoteIcmp(...)
+#define otLogInfoIcmp(...)
+#define otLogDebgIcmp(...)
 #endif
 
 /**
@@ -594,8 +664,7 @@
  *
  * This method generates a log with level critical for the IPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -604,8 +673,7 @@
  *
  * This method generates a log with level warning for the IPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -614,8 +682,7 @@
  *
  * This method generates a log with level note for the IPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -624,8 +691,7 @@
  *
  * This method generates a log with level info for the IPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -634,22 +700,21 @@
  *
  * This method generates a log with level debug for the IPv6 region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_IP6 == 1
-#define otLogCritIp6(aFormat, ...) otLogCrit(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnIp6(aFormat, ...) otLogWarn(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteIp6(aFormat, ...) otLogNote(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoIp6(aFormat, ...) otLogInfo(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgIp6(aFormat, ...) otLogDebg(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritIp6(...) otLogCrit(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX __VA_ARGS__)
+#define otLogWarnIp6(...) otLogWarn(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX __VA_ARGS__)
+#define otLogNoteIp6(...) otLogNote(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX __VA_ARGS__)
+#define otLogInfoIp6(...) otLogInfo(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX __VA_ARGS__)
+#define otLogDebgIp6(...) otLogDebg(OT_LOG_REGION_IP6, _OT_REGION_IP6_PREFIX __VA_ARGS__)
 #else
-#define otLogCritIp6(aFormat, ...)
-#define otLogWarnIp6(aFormat, ...)
-#define otLogNoteIp6(aFormat, ...)
-#define otLogInfoIp6(aFormat, ...)
-#define otLogDebgIp6(aFormat, ...)
+#define otLogCritIp6(...)
+#define otLogWarnIp6(...)
+#define otLogNoteIp6(...)
+#define otLogInfoIp6(...)
+#define otLogDebgIp6(...)
 #endif
 
 /**
@@ -657,8 +722,7 @@
  *
  * This method generates a log with level critical for the MAC region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -667,8 +731,7 @@
  *
  * This method generates a log with level warning for the MAC region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -677,8 +740,7 @@
  *
  * This method generates a log with level note for the MAC region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -687,8 +749,7 @@
  *
  * This method generates a log with level info for the MAC region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -697,8 +758,7 @@
  *
  * This method generates a log with level debug for the MAC region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -707,34 +767,34 @@
  *
  * This method generates a log with a given log level for the MAC region.
  *
- * @param[in]  aLogLevel    A log level.
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  aLogLevel  A log level.
+ * @param[in]  aFormat    A pointer to the format string.
+ * @param[in]  ...        Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_MAC == 1
-#define otLogCritMac(aFormat, ...) otLogCrit(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnMac(aFormat, ...) otLogWarn(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteMac(aFormat, ...) otLogNote(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoMac(aFormat, ...) otLogInfo(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgMac(aFormat, ...) otLogDebg(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritMac(...) otLogCrit(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX __VA_ARGS__)
+#define otLogWarnMac(...) otLogWarn(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX __VA_ARGS__)
+#define otLogNoteMac(...) otLogNote(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX __VA_ARGS__)
+#define otLogInfoMac(...) otLogInfo(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX __VA_ARGS__)
+#define otLogDebgMac(...) otLogDebg(OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX __VA_ARGS__)
 #define otLogMac(aLogLevel, aFormat, ...)                                                     \
     do                                                                                        \
     {                                                                                         \
         if (otLoggingGetLevel() >= aLogLevel)                                                 \
         {                                                                                     \
             _otLogFormatter(aLogLevel, OT_LOG_REGION_MAC, "%s" _OT_REGION_MAC_PREFIX aFormat, \
-                            otLogLevelToPrefixString(aLogLevel), ##__VA_ARGS__);              \
+                            otLogLevelToPrefixString(aLogLevel), __VA_ARGS__);                \
         }                                                                                     \
     } while (false)
 
 #else
-#define otLogCritMac(aFormat, ...)
-#define otLogWarnMac(aFormat, ...)
-#define otLogNoteMac(aFormat, ...)
-#define otLogInfoMac(aFormat, ...)
-#define otLogDebgMac(aFormat, ...)
-#define otLogMac(aLogLevel, aFormat, ...)
+#define otLogCritMac(...)
+#define otLogWarnMac(...)
+#define otLogNoteMac(...)
+#define otLogInfoMac(...)
+#define otLogDebgMac(...)
+#define otLogMac(aLogLevel, ...)
 #endif
 
 /**
@@ -742,8 +802,7 @@
  *
  * This method generates a log with level critical for the Core region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -752,8 +811,7 @@
  *
  * This method generates a log with level warning for the Core region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -762,8 +820,7 @@
  *
  * This method generates a log with level note for the Core region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -772,8 +829,7 @@
  *
  * This method generates a log with level info for the Core region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -782,21 +838,20 @@
  *
  * This method generates a log with level debug for the Core region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_CORE == 1
-#define otLogCritCore(aFormat, ...) otLogCrit(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnCore(aFormat, ...) otLogWarn(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteCore(aFormat, ...) otLogNote(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoCore(aFormat, ...) otLogInfo(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgCore(aFormat, ...) otLogDebg(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritCore(...) otLogCrit(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX __VA_ARGS__)
+#define otLogWarnCore(...) otLogWarn(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX __VA_ARGS__)
+#define otLogNoteCore(...) otLogNote(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX __VA_ARGS__)
+#define otLogInfoCore(...) otLogInfo(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX __VA_ARGS__)
+#define otLogDebgCore(...) otLogDebg(OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX __VA_ARGS__)
 #else
-#define otLogCritCore(aFormat, ...)
-#define otLogWarnCore(aFormat, ...)
-#define otLogInfoCore(aFormat, ...)
-#define otLogDebgCore(aFormat, ...)
+#define otLogCritCore(...)
+#define otLogWarnCore(...)
+#define otLogInfoCore(...)
+#define otLogDebgCore(...)
 #endif
 
 /**
@@ -804,8 +859,7 @@
  *
  * This method generates a log with level critical for the memory region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -814,8 +868,7 @@
  *
  * This method generates a log with level warning for the memory region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -824,8 +877,7 @@
  *
  * This method generates a log with level note for the memory region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -834,8 +886,7 @@
  *
  * This method generates a log with level info for the memory region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -844,22 +895,21 @@
  *
  * This method generates a log with level debug for the memory region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_MEM == 1
-#define otLogCritMem(aFormat, ...) otLogCrit(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnMem(aFormat, ...) otLogWarn(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteMem(aFormat, ...) otLogNote(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoMem(aFormat, ...) otLogInfo(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgMem(aFormat, ...) otLogDebg(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritMem(...) otLogCrit(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX __VA_ARGS__)
+#define otLogWarnMem(...) otLogWarn(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX __VA_ARGS__)
+#define otLogNoteMem(...) otLogNote(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX __VA_ARGS__)
+#define otLogInfoMem(...) otLogInfo(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX __VA_ARGS__)
+#define otLogDebgMem(...) otLogDebg(OT_LOG_REGION_MEM, _OT_REGION_MEM_PREFIX __VA_ARGS__)
 #else
-#define otLogCritMem(aFormat, ...)
-#define otLogWarnMem(aFormat, ...)
-#define otLogNoteMem(aFormat, ...)
-#define otLogInfoMem(aFormat, ...)
-#define otLogDebgMem(aFormat, ...)
+#define otLogCritMem(...)
+#define otLogWarnMem(...)
+#define otLogNoteMem(...)
+#define otLogInfoMem(...)
+#define otLogDebgMem(...)
 #endif
 
 /**
@@ -867,8 +917,7 @@
  *
  * This method generates a log with level critical for the Util region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -877,8 +926,7 @@
  *
  * This method generates a log with level warning for the Util region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -887,8 +935,7 @@
  *
  * This method generates a log with level note for the Util region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -897,8 +944,7 @@
  *
  * This method generates a log with level info for the Util region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -907,22 +953,21 @@
  *
  * This method generates a log with level debug for the Util region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_UTIL == 1
-#define otLogCritUtil(aFormat, ...) otLogCrit(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnUtil(aFormat, ...) otLogWarn(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteUtil(aFormat, ...) otLogNote(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoUtil(aFormat, ...) otLogInfo(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgUtil(aFormat, ...) otLogDebg(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritUtil(...) otLogCrit(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX __VA_ARGS__)
+#define otLogWarnUtil(...) otLogWarn(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX __VA_ARGS__)
+#define otLogNoteUtil(...) otLogNote(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX __VA_ARGS__)
+#define otLogInfoUtil(...) otLogInfo(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX __VA_ARGS__)
+#define otLogDebgUtil(...) otLogDebg(OT_LOG_REGION_UTIL, _OT_REGION_UTIL_PREFIX __VA_ARGS__)
 #else
-#define otLogCritUtil(aFormat, ...)
-#define otLogWarnUtil(aFormat, ...)
-#define otLogNoteUtil(aFormat, ...)
-#define otLogInfoUtil(aFormat, ...)
-#define otLogDebgUtil(aFormat, ...)
+#define otLogCritUtil(...)
+#define otLogWarnUtil(...)
+#define otLogNoteUtil(...)
+#define otLogInfoUtil(...)
+#define otLogDebgUtil(...)
 #endif
 
 /**
@@ -930,8 +975,7 @@
  *
  * This method generates a log with level critical for the NETDIAG region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -940,8 +984,7 @@
  *
  * This method generates a log with level warning for the NETDIAG region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -950,8 +993,7 @@
  *
  * This method generates a log with level note for the NETDIAG region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -960,8 +1002,7 @@
  *
  * This method generates a log with level info for the NETDIAG region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -970,27 +1011,21 @@
  *
  * This method generates a log with level debug for the NETDIAG region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_NETDIAG == 1
-#define otLogCritNetDiag(aFormat, ...) \
-    otLogCrit(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnNetDiag(aFormat, ...) \
-    otLogWarn(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteNetDiag(aFormat, ...) \
-    otLogNote(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoNetDiag(aFormat, ...) \
-    otLogInfo(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgNetDiag(aFormat, ...) \
-    otLogDebg(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritNetDiag(...) otLogCrit(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX __VA_ARGS__)
+#define otLogWarnNetDiag(...) otLogWarn(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX __VA_ARGS__)
+#define otLogNoteNetDiag(...) otLogNote(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX __VA_ARGS__)
+#define otLogInfoNetDiag(...) otLogInfo(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX __VA_ARGS__)
+#define otLogDebgNetDiag(...) otLogDebg(OT_LOG_REGION_NET_DIAG, _OT_REGION_NET_DIAG_PREFIX __VA_ARGS__)
 #else
-#define otLogCritNetDiag(aFormat, ...)
-#define otLogWarnNetDiag(aFormat, ...)
-#define otLogNoteNetDiag(aFormat, ...)
-#define otLogInfoNetDiag(aFormat, ...)
-#define otLogDebgNetDiag(aFormat, ...)
+#define otLogCritNetDiag(...)
+#define otLogWarnNetDiag(...)
+#define otLogNoteNetDiag(...)
+#define otLogInfoNetDiag(...)
+#define otLogDebgNetDiag(...)
 #endif
 
 /**
@@ -998,16 +1033,14 @@
  *
  * This method generates a log with level none for the certification test.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  *
  */
 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
-#define otLogCertMeshCoP(aFormat, ...) \
-    _otLogFormatter(OT_LOG_LEVEL_NONE, OT_LOG_REGION_MESH_COP, aFormat, ##__VA_ARGS__)
+#define otLogCertMeshCoP(...) _otLogFormatter(OT_LOG_LEVEL_NONE, OT_LOG_REGION_MESH_COP, __VA_ARGS__, NULL)
 #else
-#define otLogCertMeshCoP(aFormat, ...)
+#define otLogCertMeshCoP(...)
 #endif
 
 /**
@@ -1015,8 +1048,7 @@
  *
  * This method generates a log with level critical for the CLI region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -1025,18 +1057,16 @@
  *
  * This method generates a log with level warning for the CLI region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
 /**
- * @def otLogInfoCli
+ * @def otLogNoteCli
  *
  * This method generates a log with level note for the CLI region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -1045,8 +1075,7 @@
  *
  * This method generates a log with level info for the CLI region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -1055,23 +1084,22 @@
  *
  * This method generates a log with level debug for the CLI region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_CLI == 1
 
-#define otLogCritCli(aFormat, ...) otLogCrit(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnCli(aFormat, ...) otLogWarn(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteCli(aFormat, ...) otLogNote(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoCli(aFormat, ...) otLogInfo(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgCli(aFormat, ...) otLogDebg(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritCli(...) otLogCrit(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX __VA_ARGS__)
+#define otLogWarnCli(...) otLogWarn(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX __VA_ARGS__)
+#define otLogNoteCli(...) otLogNote(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX __VA_ARGS__)
+#define otLogInfoCli(...) otLogInfo(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX __VA_ARGS__)
+#define otLogDebgCli(...) otLogDebg(OT_LOG_REGION_CLI, _OT_REGION_CLI_PREFIX __VA_ARGS__)
 #else
-#define otLogCritCli(aFormat, ...)
-#define otLogWarnCli(aFormat, ...)
-#define otLogNoteCli(aFormat, ...)
-#define otLogInfoCli(aFormat, ...)
-#define otLogDebgCli(aFormat, ...)
+#define otLogCritCli(...)
+#define otLogWarnCli(...)
+#define otLogNoteCli(...)
+#define otLogInfoCli(...)
+#define otLogDebgCli(...)
 #endif
 
 /**
@@ -1079,8 +1107,7 @@
  *
  * This method generates a log with level critical for the CoAP region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -1089,8 +1116,7 @@
  *
  * This method generates a log with level warning for the CoAP region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -1099,8 +1125,7 @@
  *
  * This method generates a log with level note for the CoAP region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -1109,8 +1134,7 @@
  *
  * This method generates a log with level info for the CoAP region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 
@@ -1119,22 +1143,21 @@
  *
  * This method generates a log with level debug for the CoAP region.
  *
- * @param[in]  aFormat      A pointer to the format string.
- * @param[in]  ...          Arguments for the format specification.
+ * @param[in]  ...  Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_COAP == 1
-#define otLogCritCoap(aFormat, ...) otLogCrit(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnCoap(aFormat, ...) otLogWarn(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNoteCoap(aFormat, ...) otLogNote(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoCoap(aFormat, ...) otLogInfo(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgCoap(aFormat, ...) otLogDebg(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritCoap(...) otLogCrit(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX __VA_ARGS__)
+#define otLogWarnCoap(...) otLogWarn(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX __VA_ARGS__)
+#define otLogNoteCoap(...) otLogNote(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX __VA_ARGS__)
+#define otLogInfoCoap(...) otLogInfo(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX __VA_ARGS__)
+#define otLogDebgCoap(...) otLogDebg(OT_LOG_REGION_COAP, _OT_REGION_COAP_PREFIX __VA_ARGS__)
 #else
-#define otLogCritCoap(aFormat, ...)
-#define otLogWarnCoap(aFormat, ...)
-#define otLogNoteCoap(aFormat, ...)
-#define otLogInfoCoap(aFormat, ...)
-#define otLogDebgCoap(aFormat, ...)
+#define otLogCritCoap(...)
+#define otLogWarnCoap(...)
+#define otLogNoteCoap(...)
+#define otLogInfoCoap(...)
+#define otLogDebgCoap(...)
 #endif
 
 /**
@@ -1142,7 +1165,6 @@
  *
  * This method generates a log with level critical for the Platform region.
  *
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
@@ -1152,7 +1174,6 @@
  *
  * This method generates a log with level warning for the Platform region.
  *
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
@@ -1162,7 +1183,6 @@
  *
  * This method generates a log with level note for the Platform region.
  *
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
@@ -1172,7 +1192,6 @@
  *
  * This method generates a log with level info for the Platform region.
  *
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
@@ -1182,22 +1201,34 @@
  *
  * This method generates a log with level debug for the Platform region.
  *
- * @param[in]  aFormat   A pointer to the format string.
  * @param[in]  ...       Arguments for the format specification.
  *
  */
 #if OPENTHREAD_CONFIG_LOG_PLATFORM == 1
-#define otLogCritPlat(aFormat, ...) otLogCrit(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogWarnPlat(aFormat, ...) otLogWarn(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogNotePlat(aFormat, ...) otLogNote(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogInfoPlat(aFormat, ...) otLogInfo(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX aFormat, ##__VA_ARGS__)
-#define otLogDebgPlat(aFormat, ...) otLogDebg(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX aFormat, ##__VA_ARGS__)
+#define otLogCritPlat(...) otLogCrit(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX __VA_ARGS__)
+#define otLogWarnPlat(...) otLogWarn(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX __VA_ARGS__)
+#define otLogNotePlat(...) otLogNote(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX __VA_ARGS__)
+#define otLogInfoPlat(...) otLogInfo(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX __VA_ARGS__)
+#define otLogDebgPlat(...) otLogDebg(OT_LOG_REGION_PLATFORM, _OT_REGION_PLATFORM_PREFIX __VA_ARGS__)
 #else
-#define otLogCritPlat(aFormat, ...)
-#define otLogWarnPlat(aFormat, ...)
-#define otLogNotePlat(aFormat, ...)
-#define otLogInfoPlat(aFormat, ...)
-#define otLogDebgPlat(aFormat, ...)
+#define otLogCritPlat(...)
+#define otLogWarnPlat(...)
+#define otLogNotePlat(...)
+#define otLogInfoPlat(...)
+#define otLogDebgPlat(...)
+#endif
+
+/**
+ * @def otLogOtns
+ *
+ * This method generates a log with level none for the Core region,
+ * and is specifically for OTNS visualization use.
+ *
+ * @param[in]  ...       Arguments for the format specification.
+ *
+ */
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+#define otLogOtns(...) _otLogFormatter(OT_LOG_LEVEL_NONE, OT_LOG_REGION_CORE, _OT_LEVEL_NONE_PREFIX __VA_ARGS__, NULL)
 #endif
 
 /**
@@ -1248,7 +1279,7 @@
 #if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE
 #define otDumpNote(aRegion, aId, aBuf, aLength) otDump(OT_LOG_LEVEL_NOTE, aRegion, aId, aBuf, aLength)
 #else
-#define otDumpInfo(aRegion, aId, aBuf, aLength)
+#define otDumpNote(aRegion, aId, aBuf, aLength)
 #endif
 
 /**
@@ -1485,6 +1516,142 @@
 #endif
 
 /**
+ * @def otDumpCritBbr
+ *
+ * This method generates a memory dump with log level critical and region Backbone Router (BBR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+
+/**
+ * @def otDumpWarnBbr
+ *
+ * This method generates a memory dump with log level warning and region Backbone Router (BBR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+
+/**
+ * @def otDumpNoteBbr
+ *
+ * This method generates a memory dump with log level note and region Backbone Router (BBR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+
+/**
+ * @def otDumpInfoBbr
+ *
+ * This method generates a memory dump with log level info and region Backbone Router (BBR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+
+/**
+ * @def otDumpDebgBbr
+ *
+ * This method generates a memory dump with log level debug and region Backbone Router (BBR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+#if OPENTHREAD_CONFIG_LOG_BBR == 1
+#define otDumpCritBbr(aId, aBuf, aLength) otDumpCrit(OT_LOG_REGION_BBR, aId, aBuf, aLength)
+#define otDumpWarnBbr(aId, aBuf, aLength) otDumpWarn(OT_LOG_REGION_BBR, aId, aBuf, aLength)
+#define otDumpNoteBbr(aId, aBuf, aLength) otDumpNote(OT_LOG_REGION_BBR, aId, aBuf, aLength)
+#define otDumpInfoBbr(aId, aBuf, aLength) otDumpInfo(OT_LOG_REGION_BBR, aId, aBuf, aLength)
+#define otDumpDebgBbr(aId, aBuf, aLength) otDumpDebg(OT_LOG_REGION_BBR, aId, aBuf, aLength)
+#else
+#define otDumpCritBbr(aId, aBuf, aLength)
+#define otDumpWarnBbr(aId, aBuf, aLength)
+#define otDumpNoteBbr(aId, aBuf, aLength)
+#define otDumpInfoBbr(aId, aBuf, aLength)
+#define otDumpDebgBbr(aId, aBuf, aLength)
+#endif
+
+/**
+ * @def otDumpCritMlr
+ *
+ * This method generates a memory dump with log level critical and region Multicast Listener Registration (MLR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+
+/**
+ * @def otDumpWarnMlr
+ *
+ * This method generates a memory dump with log level warning and region Multicast Listener Registration (MLR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+
+/**
+ * @def otDumpNoteMlr
+ *
+ * This method generates a memory dump with log level note and region Multicast Listener Registration (MLR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+
+/**
+ * @def otDumpInfoMlr
+ *
+ * This method generates a memory dump with log level info and region Multicast Listener Registration (MLR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+
+/**
+ * @def otDumpDebgMlr
+ *
+ * This method generates a memory dump with log level debug and region Multicast Listener Registration (MLR).
+ *
+ * @param[in]  aId          A pointer to a NULL-terminated string that is printed before the bytes.
+ * @param[in]  aBuf         A pointer to the buffer.
+ * @param[in]  aLength      Number of bytes to print.
+ *
+ */
+#if OPENTHREAD_CONFIG_LOG_MLR == 1
+#define otDumpCritMlr(aId, aBuf, aLength) otDumpCrit(OT_LOG_REGION_MLR, aId, aBuf, aLength)
+#define otDumpWarnMlr(aId, aBuf, aLength) otDumpWarn(OT_LOG_REGION_MLR, aId, aBuf, aLength)
+#define otDumpNoteMlr(aId, aBuf, aLength) otDumpNote(OT_LOG_REGION_MLR, aId, aBuf, aLength)
+#define otDumpInfoMlr(aId, aBuf, aLength) otDumpInfo(OT_LOG_REGION_MLR, aId, aBuf, aLength)
+#define otDumpDebgMlr(aId, aBuf, aLength) otDumpDebg(OT_LOG_REGION_MLR, aId, aBuf, aLength)
+#else
+#define otDumpCritMlr(aId, aBuf, aLength)
+#define otDumpWarnMlr(aId, aBuf, aLength)
+#define otDumpNoteMlr(aId, aBuf, aLength)
+#define otDumpInfoMlr(aId, aBuf, aLength)
+#define otDumpDebgMlr(aId, aBuf, aLength)
+#endif
+
+/**
  * @def otDumpCritIcmp
  *
  * This method generates a memory dump with log level debug and region ICMPv6.
@@ -1866,23 +2033,23 @@
  * Local/private macro to format the log message
  */
 #define _otLogFormatter(aLogLevel, aRegion, aFormat, ...) \
-    _otDynamicLog(aLogLevel, aRegion, aFormat OPENTHREAD_CONFIG_LOG_SUFFIX, ##__VA_ARGS__)
+    _otDynamicLog(aLogLevel, aRegion, aFormat OPENTHREAD_CONFIG_LOG_SUFFIX, __VA_ARGS__)
 
 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE == 1
 
 /**
  * Local/private macro to dynamically filter log level.
  */
-#define _otDynamicLog(aLogLevel, aRegion, aFormat, ...)             \
-    do                                                              \
-    {                                                               \
-        if (otLoggingGetLevel() >= aLogLevel)                       \
-            _otPlatLog(aLogLevel, aRegion, aFormat, ##__VA_ARGS__); \
+#define _otDynamicLog(aLogLevel, aRegion, ...)           \
+    do                                                   \
+    {                                                    \
+        if (otLoggingGetLevel() >= aLogLevel)            \
+            _otPlatLog(aLogLevel, aRegion, __VA_ARGS__); \
     } while (false)
 
 #else // OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
 
-#define _otDynamicLog(aLogLevel, aRegion, aFormat, ...) _otPlatLog(aLogLevel, aRegion, aFormat, ##__VA_ARGS__)
+#define _otDynamicLog(aLogLevel, aRegion, ...) _otPlatLog(aLogLevel, aRegion, __VA_ARGS__)
 
 #endif // OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
 
@@ -1891,8 +2058,7 @@
  * function/macro to be used for logging in OpenThread. By default it is set to `otPlatLog()`.
  *
  */
-#define _otPlatLog(aLogLevel, aRegion, aFormat, ...) \
-    OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION(aLogLevel, aRegion, aFormat, ##__VA_ARGS__)
+#define _otPlatLog(aLogLevel, aRegion, ...) OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION(aLogLevel, aRegion, __VA_ARGS__)
 
 #ifdef __cplusplus
 }
diff --git a/src/core/common/message.cpp b/src/core/common/message.cpp
index 1990713..a70e84a 100644
--- a/src/core/common/message.cpp
+++ b/src/core/common/message.cpp
@@ -44,31 +44,22 @@
 
 MessagePool::MessagePool(Instance &aInstance)
     : InstanceLocator(aInstance)
+#if !OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT
+    , mNumFreeBuffers(kNumBuffers)
+    , mBufferPool()
+#endif
 {
 #if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT
-    // Initialize Platform buffer pool management.
     otPlatMessagePoolInit(&GetInstance(), kNumBuffers, sizeof(Buffer));
-#else
-    memset(mBuffers, 0, sizeof(mBuffers));
-
-    mFreeBuffers = mBuffers;
-
-    for (uint16_t i = 0; i < kNumBuffers - 1; i++)
-    {
-        mBuffers[i].SetNextBuffer(&mBuffers[i + 1]);
-    }
-
-    mBuffers[kNumBuffers - 1].SetNextBuffer(NULL);
-    mNumFreeBuffers = kNumBuffers;
 #endif
 }
 
-Message *MessagePool::New(uint8_t aType, uint16_t aReserveHeader, uint8_t aPriority)
+Message *MessagePool::New(Message::Type aType, uint16_t aReserveHeader, Message::Priority aPriority)
 {
-    otError  error   = OT_ERROR_NONE;
-    Message *message = NULL;
+    otError  error = OT_ERROR_NONE;
+    Message *message;
 
-    VerifyOrExit((message = static_cast<Message *>(NewBuffer(aPriority))) != NULL);
+    VerifyOrExit((message = static_cast<Message *>(NewBuffer(aPriority))) != nullptr, OT_NOOP);
 
     memset(message, 0, sizeof(*message));
     message->SetMessagePool(this);
@@ -83,33 +74,19 @@
     if (error != OT_ERROR_NONE)
     {
         Free(message);
-        message = NULL;
+        message = nullptr;
     }
 
     return message;
 }
 
-Message *MessagePool::New(uint8_t aType, uint16_t aReserveHeader, const otMessageSettings *aSettings)
+Message *MessagePool::New(Message::Type aType, uint16_t aReserveHeader, const Message::Settings &aSettings)
 {
-    Message *message;
-    bool     linkSecurityEnabled;
-    uint8_t  priority;
+    Message *message = New(aType, aReserveHeader, aSettings.GetPriority());
 
-    if (aSettings == NULL)
-    {
-        linkSecurityEnabled = true;
-        priority            = OT_MESSAGE_PRIORITY_NORMAL;
-    }
-    else
-    {
-        linkSecurityEnabled = aSettings->mLinkSecurityEnabled;
-        priority            = aSettings->mPriority;
-    }
-
-    message = New(aType, aReserveHeader, priority);
     if (message)
     {
-        message->SetLinkSecurityEnabled(linkSecurityEnabled);
+        message->SetLinkSecurityEnabled(aSettings.IsLinkSecurityEnabled());
     }
 
     return message;
@@ -117,14 +94,14 @@
 
 void MessagePool::Free(Message *aMessage)
 {
-    assert(aMessage->Next() == NULL && aMessage->Prev() == NULL);
+    OT_ASSERT(aMessage->Next() == nullptr && aMessage->Prev() == nullptr);
 
     FreeBuffers(static_cast<Buffer *>(aMessage));
 }
 
-Buffer *MessagePool::NewBuffer(uint8_t aPriority)
+Buffer *MessagePool::NewBuffer(Message::Priority aPriority)
 {
-    Buffer *buffer = NULL;
+    Buffer *buffer = nullptr;
 
     SuccessOrExit(ReclaimBuffers(1, aPriority));
 
@@ -134,42 +111,39 @@
 
 #else
 
-    if (mFreeBuffers != NULL)
-    {
-        buffer       = mFreeBuffers;
-        mFreeBuffers = mFreeBuffers->GetNextBuffer();
-        buffer->SetNextBuffer(NULL);
-        mNumFreeBuffers--;
-    }
+    buffer = mBufferPool.Allocate();
+    VerifyOrExit(buffer != nullptr, OT_NOOP);
+
+    mNumFreeBuffers--;
+    buffer->SetNextBuffer(nullptr);
 
 #endif
 
-    if (buffer == NULL)
+exit:
+    if (buffer == nullptr)
     {
         otLogInfoMem("No available message buffer");
     }
 
-exit:
     return buffer;
 }
 
 void MessagePool::FreeBuffers(Buffer *aBuffer)
 {
-    while (aBuffer != NULL)
+    while (aBuffer != nullptr)
     {
-        Buffer *tmpBuffer = aBuffer->GetNextBuffer();
+        Buffer *next = aBuffer->GetNextBuffer();
 #if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT
         otPlatMessagePoolFree(&GetInstance(), aBuffer);
-#else  // OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT
-        aBuffer->SetNextBuffer(mFreeBuffers);
-        mFreeBuffers = aBuffer;
+#else
+        mBufferPool.Free(*aBuffer);
         mNumFreeBuffers++;
-#endif // OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT
-        aBuffer = tmpBuffer;
+#endif
+        aBuffer = next;
     }
 }
 
-otError MessagePool::ReclaimBuffers(int aNumBuffers, uint8_t aPriority)
+otError MessagePool::ReclaimBuffers(int aNumBuffers, Message::Priority aPriority)
 {
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
     while (aNumBuffers > GetFreeBufferCount())
@@ -178,9 +152,9 @@
     }
 
 exit:
-#else  // OPENTHREAD_MTD || OPENTHREAD_FTD
+#else
     OT_UNUSED_VARIABLE(aPriority);
-#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
+#endif
 
     // First comparison is to get around issues with comparing
     // signed and unsigned numbers, if aNumBuffers is negative then
@@ -201,6 +175,20 @@
     return rval;
 }
 
+const Message::Settings Message::Settings::kDefault(Message::kWithLinkSecurity, Message::kPriorityNormal);
+
+Message::Settings::Settings(LinkSecurityMode aSecurityMode, Priority aPriority)
+    : mLinkSecurityEnabled(aSecurityMode == kWithLinkSecurity)
+    , mPriority(aPriority)
+{
+}
+
+Message::Settings::Settings(const otMessageSettings *aSettings)
+    : mLinkSecurityEnabled((aSettings != nullptr) ? aSettings->mLinkSecurityEnabled : true)
+    , mPriority((aSettings != nullptr) ? static_cast<Priority>(aSettings->mPriority) : kPriorityNormal)
+{
+}
+
 otError Message::ResizeMessage(uint16_t aLength)
 {
     otError error = OT_ERROR_NONE;
@@ -212,10 +200,10 @@
 
     while (curLength < aLength)
     {
-        if (curBuffer->GetNextBuffer() == NULL)
+        if (curBuffer->GetNextBuffer() == nullptr)
         {
             curBuffer->SetNextBuffer(GetMessagePool()->NewBuffer(GetPriority()));
-            VerifyOrExit(curBuffer->GetNextBuffer() != NULL, error = OT_ERROR_NO_BUFS);
+            VerifyOrExit(curBuffer->GetNextBuffer() != nullptr, error = OT_ERROR_NO_BUFS);
         }
 
         curBuffer = curBuffer->GetNextBuffer();
@@ -225,7 +213,7 @@
     // remove buffers
     lastBuffer = curBuffer;
     curBuffer  = curBuffer->GetNextBuffer();
-    lastBuffer->SetNextBuffer(NULL);
+    lastBuffer->SetNextBuffer(nullptr);
 
     GetMessagePool()->FreeBuffers(curBuffer);
 
@@ -243,20 +231,20 @@
     Message *next;
     Message *tail;
 
-    if (mBuffer.mHead.mInfo.mInPriorityQ)
+    if (GetMetadata().mInPriorityQ)
     {
         PriorityQueue *priorityQueue = GetPriorityQueue();
-        VerifyOrExit(priorityQueue != NULL, next = NULL);
+        VerifyOrExit(priorityQueue != nullptr, next = nullptr);
         tail = priorityQueue->GetTail();
     }
     else
     {
         MessageQueue *messageQueue = GetMessageQueue();
-        VerifyOrExit(messageQueue != NULL, next = NULL);
+        VerifyOrExit(messageQueue != nullptr, next = nullptr);
         tail = messageQueue->GetTail();
     }
 
-    next = (this == tail) ? NULL : Next();
+    next = (this == tail) ? nullptr : Next();
 
 exit:
     return next;
@@ -284,7 +272,7 @@
     SuccessOrExit(error = GetMessagePool()->ReclaimBuffers(bufs, GetPriority()));
 
     SuccessOrExit(error = ResizeMessage(totalLengthRequest));
-    mBuffer.mHead.mInfo.mLength = aLength;
+    GetMetadata().mLength = aLength;
 
     // Correct offset in case shorter length is set.
     if (GetOffset() > aLength)
@@ -308,38 +296,24 @@
     return rval;
 }
 
-otError Message::MoveOffset(int aDelta)
+void Message::MoveOffset(int aDelta)
 {
-    otError error = OT_ERROR_NONE;
-
-    assert(GetOffset() + aDelta <= GetLength());
-    VerifyOrExit(GetOffset() + aDelta <= GetLength(), error = OT_ERROR_INVALID_ARGS);
-
-    mBuffer.mHead.mInfo.mOffset += static_cast<int16_t>(aDelta);
-    assert(mBuffer.mHead.mInfo.mOffset <= GetLength());
-
-exit:
-    return error;
+    OT_ASSERT(GetOffset() + aDelta <= GetLength());
+    GetMetadata().mOffset += static_cast<int16_t>(aDelta);
+    OT_ASSERT(GetMetadata().mOffset <= GetLength());
 }
 
-otError Message::SetOffset(uint16_t aOffset)
+void Message::SetOffset(uint16_t aOffset)
 {
-    otError error = OT_ERROR_NONE;
-
-    assert(aOffset <= GetLength());
-    VerifyOrExit(aOffset <= GetLength(), error = OT_ERROR_INVALID_ARGS);
-
-    mBuffer.mHead.mInfo.mOffset = aOffset;
-
-exit:
-    return error;
+    OT_ASSERT(aOffset <= GetLength());
+    GetMetadata().mOffset = aOffset;
 }
 
 bool Message::IsSubTypeMle(void) const
 {
     bool rval;
 
-    switch (mBuffer.mHead.mInfo.mSubType)
+    switch (GetMetadata().mSubType)
     {
     case kSubTypeMleGeneral:
     case kSubTypeMleAnnounce:
@@ -359,25 +333,26 @@
     return rval;
 }
 
-otError Message::SetPriority(uint8_t aPriority)
+otError Message::SetPriority(Priority aPriority)
 {
     otError        error         = OT_ERROR_NONE;
-    PriorityQueue *priorityQueue = NULL;
+    uint8_t        priority      = static_cast<uint8_t>(aPriority);
+    PriorityQueue *priorityQueue = nullptr;
 
-    VerifyOrExit(aPriority < kNumPriorities, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(priority < kNumPriorities, error = OT_ERROR_INVALID_ARGS);
 
-    VerifyOrExit(IsInAQueue(), mBuffer.mHead.mInfo.mPriority = aPriority);
-    VerifyOrExit(mBuffer.mHead.mInfo.mPriority != aPriority);
+    VerifyOrExit(IsInAQueue(), GetMetadata().mPriority = priority);
+    VerifyOrExit(GetMetadata().mPriority != priority, OT_NOOP);
 
-    if (mBuffer.mHead.mInfo.mInPriorityQ)
+    if (GetMetadata().mInPriorityQ)
     {
-        priorityQueue = mBuffer.mHead.mInfo.mQueue.mPriority;
+        priorityQueue = GetMetadata().mQueue.mPriority;
         priorityQueue->Dequeue(*this);
     }
 
-    mBuffer.mHead.mInfo.mPriority = aPriority;
+    GetMetadata().mPriority = priority;
 
-    if (priorityQueue != NULL)
+    if (priorityQueue != nullptr)
     {
         priorityQueue->Enqueue(*this);
     }
@@ -395,7 +370,7 @@
     SuccessOrExit(error = SetLength(GetLength() + aLength));
     bytesWritten = Write(oldLength, aLength, aBuf);
 
-    assert(bytesWritten == (int)aLength);
+    OT_ASSERT(bytesWritten == (int)aLength);
     OT_UNUSED_VARIABLE(bytesWritten);
 
 exit:
@@ -405,11 +380,11 @@
 otError Message::Prepend(const void *aBuf, uint16_t aLength)
 {
     otError error     = OT_ERROR_NONE;
-    Buffer *newBuffer = NULL;
+    Buffer *newBuffer = nullptr;
 
     while (aLength > GetReserved())
     {
-        VerifyOrExit((newBuffer = GetMessagePool()->NewBuffer(GetPriority())) != NULL, error = OT_ERROR_NO_BUFS);
+        VerifyOrExit((newBuffer = GetMessagePool()->NewBuffer(GetPriority())) != nullptr, error = OT_ERROR_NO_BUFS);
 
         newBuffer->SetNextBuffer(GetNextBuffer());
         SetNextBuffer(newBuffer);
@@ -425,10 +400,10 @@
     }
 
     SetReserved(GetReserved() - aLength);
-    mBuffer.mHead.mInfo.mLength += aLength;
+    GetMetadata().mLength += aLength;
     SetOffset(GetOffset() + aLength);
 
-    if (aBuf != NULL)
+    if (aBuf != nullptr)
     {
         Write(0, aLength, aBuf);
     }
@@ -439,26 +414,26 @@
 
 void Message::RemoveHeader(uint16_t aLength)
 {
-    assert(aLength <= mBuffer.mHead.mInfo.mLength);
+    OT_ASSERT(aLength <= GetMetadata().mLength);
 
-    mBuffer.mHead.mInfo.mReserved += aLength;
-    mBuffer.mHead.mInfo.mLength -= aLength;
+    GetMetadata().mReserved += aLength;
+    GetMetadata().mLength -= aLength;
 
-    if (mBuffer.mHead.mInfo.mOffset > aLength)
+    if (GetMetadata().mOffset > aLength)
     {
-        mBuffer.mHead.mInfo.mOffset -= aLength;
+        GetMetadata().mOffset -= aLength;
     }
     else
     {
-        mBuffer.mHead.mInfo.mOffset = 0;
+        GetMetadata().mOffset = 0;
     }
 }
 
 uint16_t Message::Read(uint16_t aOffset, uint16_t aLength, void *aBuf) const
 {
-    Buffer * curBuffer;
-    uint16_t bytesCopied = 0;
-    uint16_t bytesToCopy;
+    const Buffer *curBuffer;
+    uint16_t      bytesCopied = 0;
+    uint16_t      bytesToCopy;
 
     if (aOffset >= GetLength())
     {
@@ -500,7 +475,7 @@
 
     while (aOffset >= kBufferDataSize)
     {
-        assert(curBuffer != NULL);
+        OT_ASSERT(curBuffer != nullptr);
 
         curBuffer = curBuffer->GetNextBuffer();
         aOffset -= kBufferDataSize;
@@ -509,7 +484,7 @@
     // begin copy
     while (aLength > 0)
     {
-        assert(curBuffer != NULL);
+        OT_ASSERT(curBuffer != nullptr);
 
         bytesToCopy = kBufferDataSize - aOffset;
 
@@ -538,7 +513,7 @@
     uint16_t bytesCopied = 0;
     uint16_t bytesToCopy;
 
-    assert(aOffset + aLength <= GetLength());
+    OT_ASSERT(aOffset + aLength <= GetLength());
 
     if (aOffset + aLength >= GetLength())
     {
@@ -575,7 +550,7 @@
 
     while (aOffset >= kBufferDataSize)
     {
-        assert(curBuffer != NULL);
+        OT_ASSERT(curBuffer != nullptr);
 
         curBuffer = curBuffer->GetNextBuffer();
         aOffset -= kBufferDataSize;
@@ -584,7 +559,7 @@
     // begin copy
     while (aLength > 0)
     {
-        assert(curBuffer != NULL);
+        OT_ASSERT(curBuffer != nullptr);
 
         bytesToCopy = kBufferDataSize - aOffset;
 
@@ -634,7 +609,7 @@
     Message *messageCopy;
     uint16_t offset;
 
-    VerifyOrExit((messageCopy = GetMessagePool()->New(GetType(), GetReserved(), GetPriority())) != NULL,
+    VerifyOrExit((messageCopy = GetMessagePool()->New(GetType(), GetReserved(), GetPriority())) != nullptr,
                  error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = messageCopy->SetLength(aLength));
     CopyTo(0, 0, aLength, *messageCopy);
@@ -651,10 +626,10 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && messageCopy != NULL)
+    if (error != OT_ERROR_NONE && messageCopy != nullptr)
     {
         messageCopy->Free();
-        messageCopy = NULL;
+        messageCopy = nullptr;
     }
 
     return messageCopy;
@@ -662,36 +637,22 @@
 
 bool Message::GetChildMask(uint16_t aChildIndex) const
 {
-    assert(aChildIndex < sizeof(mBuffer.mHead.mInfo.mChildMask) * 8);
-    return (mBuffer.mHead.mInfo.mChildMask[aChildIndex / 8] & (0x80 >> (aChildIndex % 8))) != 0;
+    return GetMetadata().mChildMask.Get(aChildIndex);
 }
 
 void Message::ClearChildMask(uint16_t aChildIndex)
 {
-    assert(aChildIndex < sizeof(mBuffer.mHead.mInfo.mChildMask) * 8);
-    mBuffer.mHead.mInfo.mChildMask[aChildIndex / 8] &= ~(0x80 >> (aChildIndex % 8));
+    GetMetadata().mChildMask.Clear(aChildIndex);
 }
 
 void Message::SetChildMask(uint16_t aChildIndex)
 {
-    assert(aChildIndex < sizeof(mBuffer.mHead.mInfo.mChildMask) * 8);
-    mBuffer.mHead.mInfo.mChildMask[aChildIndex / 8] |= 0x80 >> (aChildIndex % 8);
+    GetMetadata().mChildMask.Set(aChildIndex);
 }
 
 bool Message::IsChildPending(void) const
 {
-    bool rval = false;
-
-    for (size_t i = 0; i < sizeof(mBuffer.mHead.mInfo.mChildMask); i++)
-    {
-        if (mBuffer.mHead.mInfo.mChildMask[i] != 0)
-        {
-            ExitNow(rval = true);
-        }
-    }
-
-exit:
-    return rval;
+    return GetMetadata().mChildMask.HasAny();
 }
 
 uint16_t Message::UpdateChecksum(uint16_t aChecksum, uint16_t aValue)
@@ -714,11 +675,11 @@
 
 uint16_t Message::UpdateChecksum(uint16_t aChecksum, uint16_t aOffset, uint16_t aLength) const
 {
-    Buffer * curBuffer;
-    uint16_t bytesCovered = 0;
-    uint16_t bytesToCover;
+    const Buffer *curBuffer;
+    uint16_t      bytesCovered = 0;
+    uint16_t      bytesToCover;
 
-    assert(aOffset + aLength <= GetLength());
+    OT_ASSERT(aOffset + aLength <= GetLength());
 
     aOffset += GetReserved();
 
@@ -749,7 +710,7 @@
 
     while (aOffset >= kBufferDataSize)
     {
-        assert(curBuffer != NULL);
+        OT_ASSERT(curBuffer != nullptr);
 
         curBuffer = curBuffer->GetNextBuffer();
         aOffset -= kBufferDataSize;
@@ -758,7 +719,7 @@
     // begin copy
     while (aLength > 0)
     {
-        assert(curBuffer != NULL);
+        OT_ASSERT(curBuffer != nullptr);
 
         bytesToCover = kBufferDataSize - aOffset;
 
@@ -779,39 +740,45 @@
     return aChecksum;
 }
 
+bool Message::IsTimeSync(void) const
+{
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    return GetMetadata().mTimeSync;
+#else
+    return false;
+#endif
+}
+
 void Message::SetMessageQueue(MessageQueue *aMessageQueue)
 {
-    mBuffer.mHead.mInfo.mQueue.mMessage = aMessageQueue;
-    mBuffer.mHead.mInfo.mInPriorityQ    = false;
+    GetMetadata().mQueue.mMessage = aMessageQueue;
+    GetMetadata().mInPriorityQ    = false;
 }
 
 void Message::SetPriorityQueue(PriorityQueue *aPriorityQueue)
 {
-    mBuffer.mHead.mInfo.mQueue.mPriority = aPriorityQueue;
-    mBuffer.mHead.mInfo.mInPriorityQ     = true;
+    GetMetadata().mQueue.mPriority = aPriorityQueue;
+    GetMetadata().mInPriorityQ     = true;
 }
 
 MessageQueue::MessageQueue(void)
 {
-    SetTail(NULL);
+    SetTail(nullptr);
 }
 
 Message *MessageQueue::GetHead(void) const
 {
-    return (GetTail() == NULL) ? NULL : GetTail()->Next();
+    return (GetTail() == nullptr) ? nullptr : GetTail()->Next();
 }
 
-otError MessageQueue::Enqueue(Message &aMessage, QueuePosition aPosition)
+void MessageQueue::Enqueue(Message &aMessage, QueuePosition aPosition)
 {
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(!aMessage.IsInAQueue(), error = OT_ERROR_ALREADY);
+    OT_ASSERT(!aMessage.IsInAQueue());
+    OT_ASSERT((aMessage.Next() == nullptr) && (aMessage.Prev() == nullptr));
 
     aMessage.SetMessageQueue(this);
 
-    assert((aMessage.Next() == NULL) && (aMessage.Prev() == NULL));
-
-    if (GetTail() == NULL)
+    if (GetTail() == nullptr)
     {
         aMessage.Next() = &aMessage;
         aMessage.Prev() = &aMessage;
@@ -833,18 +800,12 @@
             SetTail(&aMessage);
         }
     }
-
-exit:
-    return error;
 }
 
-otError MessageQueue::Dequeue(Message &aMessage)
+void MessageQueue::Dequeue(Message &aMessage)
 {
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(aMessage.GetMessageQueue() == this, error = OT_ERROR_NOT_FOUND);
-
-    assert((aMessage.Next() != NULL) && (aMessage.Prev() != NULL));
+    OT_ASSERT(aMessage.GetMessageQueue() == this);
+    OT_ASSERT((aMessage.Next() != nullptr) && (aMessage.Prev() != nullptr));
 
     if (&aMessage == GetTail())
     {
@@ -852,20 +813,17 @@
 
         if (&aMessage == GetTail())
         {
-            SetTail(NULL);
+            SetTail(nullptr);
         }
     }
 
     aMessage.Prev()->Next() = aMessage.Next();
     aMessage.Next()->Prev() = aMessage.Prev();
 
-    aMessage.Prev() = NULL;
-    aMessage.Next() = NULL;
+    aMessage.Prev() = nullptr;
+    aMessage.Next() = nullptr;
 
-    aMessage.SetMessageQueue(NULL);
-
-exit:
-    return error;
+    aMessage.SetMessageQueue(nullptr);
 }
 
 void MessageQueue::GetInfo(uint16_t &aMessageCount, uint16_t &aBufferCount) const
@@ -873,7 +831,7 @@
     aMessageCount = 0;
     aBufferCount  = 0;
 
-    for (const Message *message = GetHead(); message != NULL; message = message->GetNext())
+    for (const Message *message = GetHead(); message != nullptr; message = message->GetNext())
     {
         aMessageCount++;
         aBufferCount += message->GetBufferCount();
@@ -884,20 +842,20 @@
 {
     for (int priority = 0; priority < Message::kNumPriorities; priority++)
     {
-        mTails[priority] = NULL;
+        mTails[priority] = nullptr;
     }
 }
 
-Message *PriorityQueue::FindFirstNonNullTail(uint8_t aStartPriorityLevel) const
+Message *PriorityQueue::FindFirstNonNullTail(Message::Priority aStartPriorityLevel) const
 {
-    Message *tail = NULL;
+    Message *tail = nullptr;
     uint8_t  priority;
 
-    priority = aStartPriorityLevel;
+    priority = static_cast<uint8_t>(aStartPriorityLevel);
 
     do
     {
-        if (mTails[priority] != NULL)
+        if (mTails[priority] != nullptr)
         {
             tail = mTails[priority];
             break;
@@ -913,27 +871,27 @@
 {
     Message *tail;
 
-    tail = FindFirstNonNullTail(0);
+    tail = FindFirstNonNullTail(Message::kPriorityLow);
 
-    return (tail == NULL) ? NULL : tail->Next();
+    return (tail == nullptr) ? nullptr : tail->Next();
 }
 
-Message *PriorityQueue::GetHeadForPriority(uint8_t aPriority) const
+Message *PriorityQueue::GetHeadForPriority(Message::Priority aPriority) const
 {
     Message *head;
     Message *previousTail;
 
-    if (mTails[aPriority] != NULL)
+    if (mTails[aPriority] != nullptr)
     {
-        previousTail = FindFirstNonNullTail(PrevPriority(aPriority));
+        previousTail = FindFirstNonNullTail(static_cast<Message::Priority>(PrevPriority(aPriority)));
 
-        assert(previousTail != NULL);
+        OT_ASSERT(previousTail != nullptr);
 
         head = previousTail->Next();
     }
     else
     {
-        head = NULL;
+        head = nullptr;
     }
 
     return head;
@@ -941,17 +899,16 @@
 
 Message *PriorityQueue::GetTail(void) const
 {
-    return FindFirstNonNullTail(0);
+    return FindFirstNonNullTail(Message::kPriorityLow);
 }
 
-otError PriorityQueue::Enqueue(Message &aMessage)
+void PriorityQueue::Enqueue(Message &aMessage)
 {
-    otError  error = OT_ERROR_NONE;
-    uint8_t  priority;
-    Message *tail;
-    Message *next;
+    Message::Priority priority;
+    Message *         tail;
+    Message *         next;
 
-    VerifyOrExit(!aMessage.IsInAQueue(), error = OT_ERROR_ALREADY);
+    OT_ASSERT(!aMessage.IsInAQueue());
 
     aMessage.SetPriorityQueue(this);
 
@@ -959,7 +916,7 @@
 
     tail = FindFirstNonNullTail(priority);
 
-    if (tail != NULL)
+    if (tail != nullptr)
     {
         next = tail->Next();
 
@@ -975,18 +932,14 @@
     }
 
     mTails[priority] = &aMessage;
-
-exit:
-    return error;
 }
 
-otError PriorityQueue::Dequeue(Message &aMessage)
+void PriorityQueue::Dequeue(Message &aMessage)
 {
-    otError  error = OT_ERROR_NONE;
-    uint8_t  priority;
-    Message *tail;
+    Message::Priority priority;
+    Message *         tail;
 
-    VerifyOrExit(aMessage.GetPriorityQueue() == this, error = OT_ERROR_NOT_FOUND);
+    OT_ASSERT(aMessage.GetPriorityQueue() == this);
 
     priority = aMessage.GetPriority();
 
@@ -998,7 +951,7 @@
 
         if ((&aMessage == tail) || (tail->GetPriority() != priority))
         {
-            tail = NULL;
+            tail = nullptr;
         }
 
         mTails[priority] = tail;
@@ -1006,13 +959,10 @@
 
     aMessage.Next()->Prev() = aMessage.Prev();
     aMessage.Prev()->Next() = aMessage.Next();
-    aMessage.Next()         = NULL;
-    aMessage.Prev()         = NULL;
+    aMessage.Next()         = nullptr;
+    aMessage.Prev()         = nullptr;
 
-    aMessage.SetMessageQueue(NULL);
-
-exit:
-    return error;
+    aMessage.SetMessageQueue(nullptr);
 }
 
 void PriorityQueue::GetInfo(uint16_t &aMessageCount, uint16_t &aBufferCount) const
@@ -1020,7 +970,7 @@
     aMessageCount = 0;
     aBufferCount  = 0;
 
-    for (const Message *message = GetHead(); message != NULL; message = message->GetNext())
+    for (const Message *message = GetHead(); message != nullptr; message = message->GetNext())
     {
         aMessageCount++;
         aBufferCount += message->GetBufferCount();
diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp
index 97f7c98..1d15ec8 100644
--- a/src/core/common/message.hpp
+++ b/src/core/common/message.hpp
@@ -43,8 +43,12 @@
 
 #include "common/code_utils.hpp"
 #include "common/encoding.hpp"
+#include "common/linked_list.hpp"
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
+#include "common/pool.hpp"
 #include "mac/mac_types.hpp"
+#include "thread/child_mask.hpp"
 #include "thread/link_quality.hpp"
 
 namespace ot {
@@ -61,9 +65,8 @@
 
 enum
 {
-    kNumBuffers     = OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS,
-    kBufferSize     = OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE,
-    kChildMaskBytes = BitVectorBytes(OPENTHREAD_CONFIG_MLE_MAX_CHILDREN),
+    kNumBuffers = OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS,
+    kBufferSize = OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE,
 };
 
 class Message;
@@ -72,10 +75,10 @@
 class PriorityQueue;
 
 /**
- * This structure contains metdata about a Message.
+ * This structure contains metadata about a Message.
  *
  */
-struct MessageInfo
+struct MessageMetadata
 {
     Message *    mNext;        ///< A pointer to the next Message in a doubly linked list.
     Message *    mPrev;        ///< A pointer to the previous Message in a doubly linked list.
@@ -93,8 +96,9 @@
     uint16_t    mOffset;      ///< A byte offset within the message.
     RssAverager mRssAverager; ///< The averager maintaining the received signal strength (RSS) average.
 
-    uint8_t mChildMask[kChildMaskBytes]; ///< A bit-vector to indicate which sleepy children need to receive this.
-    uint8_t mTimeout;                    ///< Seconds remaining before dropping the message.
+    ChildMask mChildMask; ///< A ChildMask to indicate which sleepy children need to receive this.
+    uint16_t  mMeshDest;  ///< Used for unicast non-link-local messages.
+    uint8_t   mTimeout;   ///< Seconds remaining before dropping the message.
     union
     {
         uint16_t mPanId;   ///< Used for MLE Discover Request and Response messages.
@@ -105,7 +109,7 @@
     uint8_t mSubType : 4;      ///< Identifies the message sub type.
     bool    mDirectTx : 1;     ///< Used to indicate whether a direct transmission is required.
     bool    mLinkSecurity : 1; ///< Indicates whether or not link security is enabled.
-    uint8_t mPriority : 2;     ///< Identifies the message priority level (lower value is higher priority).
+    uint8_t mPriority : 2;     ///< Identifies the message priority level (higher value is higher priority).
     bool    mInPriorityQ : 1;  ///< Indicates whether the message is queued in normal or priority queue.
     bool    mTxSuccess : 1;    ///< Indicates whether the direct tx of the message was successful.
     bool    mDoNotEvict : 1;   ///< Indicates whether or not this message may be evicted.
@@ -120,7 +124,7 @@
  * This class represents a Message buffer.
  *
  */
-class Buffer : public ::otMessage
+class Buffer : public otMessage, public LinkedListEntry<Buffer>
 {
     friend class Message;
 
@@ -131,16 +135,42 @@
      * @returns A pointer to the next message buffer.
      *
      */
-    class Buffer *GetNextBuffer(void) const { return static_cast<Buffer *>(mNext); }
+    Buffer *GetNextBuffer(void) { return GetNext(); }
+
+    /**
+     * This method returns a pointer to the next message buffer.
+     *
+     * @returns A pointer to the next message buffer.
+     *
+     */
+    const Buffer *GetNextBuffer(void) const { return GetNext(); }
 
     /**
      * This method sets the pointer to the next message buffer.
      *
+     * @param[in] aNext  A pointer to the next buffer.
+     *
      */
-    void SetNextBuffer(class Buffer *buf) { mNext = static_cast<otMessage *>(buf); }
+    void SetNextBuffer(Buffer *aNext) { SetNext(aNext); }
 
 private:
     /**
+     * This method returns the message metadata in the first message buffer.
+     *
+     * @returns The message metadata structure.
+     *
+     */
+    MessageMetadata &GetMetadata(void) { return mBuffer.mHead.mMetadata; }
+
+    /**
+     * This method returns the message metadata in the first message buffer.
+     *
+     * @returns The message metadata structure.
+     *
+     */
+    const MessageMetadata &GetMetadata(void) const { return mBuffer.mHead.mMetadata; }
+
+    /**
      * This method returns a pointer to the first byte of data in the first message buffer.
      *
      * @returns A pointer to the first data byte.
@@ -174,8 +204,8 @@
 
     enum
     {
-        kBufferDataSize     = kBufferSize - sizeof(struct otMessage),
-        kHeadBufferDataSize = kBufferDataSize - sizeof(struct MessageInfo),
+        kBufferDataSize     = kBufferSize - sizeof(otMessage),
+        kHeadBufferDataSize = kBufferDataSize - sizeof(MessageMetadata),
     };
 
 protected:
@@ -183,8 +213,8 @@
     {
         struct
         {
-            MessageInfo mInfo;
-            uint8_t     mData[kHeadBufferDataSize];
+            MessageMetadata mMetadata;
+            uint8_t         mData[kHeadBufferDataSize];
         } mHead;
         uint8_t mData[kBufferDataSize];
     } mBuffer;
@@ -201,14 +231,23 @@
     friend class PriorityQueue;
 
 public:
-    enum
+    /**
+     * This enumeration represents the message type.
+     *
+     */
+    enum Type
     {
         kTypeIp6         = 0, ///< A full uncompressed IPv6 packet
         kType6lowpan     = 1, ///< A 6lowpan frame
         kTypeSupervision = 2, ///< A child supervision frame.
+        kTypeOther       = 3, ///< Other (data) message.
     };
 
-    enum
+    /**
+     * This enumeration represents the message sub-type.
+     *
+     */
+    enum SubType
     {
         kSubTypeNone                   = 0,  ///< None
         kSubTypeMleAnnounce            = 1,  ///< MLE Announce
@@ -223,17 +262,86 @@
         kSubTypeMleChildIdRequest      = 10, ///< MLE Child ID Request
     };
 
-    enum
+    enum Priority
     {
         kPriorityLow    = OT_MESSAGE_PRIORITY_LOW,      ///< Low priority level.
         kPriorityNormal = OT_MESSAGE_PRIORITY_NORMAL,   ///< Normal priority level.
         kPriorityHigh   = OT_MESSAGE_PRIORITY_HIGH,     ///< High priority level.
         kPriorityNet    = OT_MESSAGE_PRIORITY_HIGH + 1, ///< Network Control priority level.
+    };
 
+    enum
+    {
         kNumPriorities = 4, ///< Number of priority levels.
     };
 
     /**
+     * This enumeration represents the link security mode (used by `Settings` constructor).
+     *
+     */
+    enum LinkSecurityMode
+    {
+        kNoLinkSecurity,   ///< Link security disabled (no link security).
+        kWithLinkSecurity, ///< Link security enabled.
+    };
+
+    /**
+     * This class represents settings used for creating a new message.
+     *
+     */
+    class Settings
+    {
+    public:
+        /**
+         * This constructor initializes the Settings object.
+         *
+         * @param[in]  aSecurityMode  A link security mode.
+         * @param[in]  aPriority      A message priority.
+         *
+         */
+        Settings(LinkSecurityMode aSecurityMode, Priority aPriority);
+
+        /**
+         * This constructor initializes the `Settings` object from a given `otMessageSettings`.
+         *
+         * @param[in] aSettings  A pointer to `otMessageSettings` to covert from. If nullptr default settings (link
+         *                       security enabled with `kPriorityNormal` priority) would be used.
+         *
+         */
+        Settings(const otMessageSettings *aSettings);
+
+        /**
+         * This method gets the message priority.
+         *
+         * @returns The message priority.
+         *
+         */
+        Priority GetPriority(void) const { return mPriority; }
+
+        /**
+         * This method indicates whether the link security should be enabled.
+         *
+         * @returns TRUE if link security should be enabled, FALSE otherwise.
+         *
+         */
+        bool IsLinkSecurityEnabled(void) const { return mLinkSecurityEnabled; }
+
+        /**
+         * This static method returns the default settings with link security enabled and `kPriorityNormal` priority.
+         *
+         * @returns A reference to the default settings (link security enable and `kPriorityNormal` priority).
+         *
+         */
+        static const Settings &GetDefault(void) { return kDefault; }
+
+    private:
+        static const Settings kDefault;
+
+        bool     mLinkSecurityEnabled;
+        Priority mPriority;
+    };
+
+    /**
      * This method frees this message buffer.
      *
      */
@@ -242,7 +350,7 @@
     /**
      * This method returns a pointer to the next message.
      *
-     * @returns A pointer to the next message in the list or NULL if at the end of the list.
+     * @returns A pointer to the next message in the list or nullptr if at the end of the list.
      *
      */
     Message *GetNext(void) const;
@@ -252,7 +360,7 @@
      *
      * @returns The number of bytes in the message.
      */
-    uint16_t GetLength(void) const { return mBuffer.mHead.mInfo.mLength; }
+    uint16_t GetLength(void) const { return GetMetadata().mLength; }
 
     /**
      * This method sets the number of bytes in the message.
@@ -277,29 +385,23 @@
      * @returns A byte offset within the message.
      *
      */
-    uint16_t GetOffset(void) const { return mBuffer.mHead.mInfo.mOffset; }
+    uint16_t GetOffset(void) const { return GetMetadata().mOffset; }
 
     /**
      * This method moves the byte offset within the message.
      *
      * @param[in]  aDelta  The number of bytes to move the current offset, which may be positive or negative.
      *
-     * @retval OT_ERROR_NONE          Successfully moved the byte offset.
-     * @retval OT_ERROR_INVALID_ARGS  The resulting byte offset is not within the existing message.
-     *
      */
-    otError MoveOffset(int aDelta);
+    void MoveOffset(int aDelta);
 
     /**
      * This method sets the byte offset within the message.
      *
-     * @param[in]  aOffset  The number of bytes to move the current offset, which may be positive or negative.
-     *
-     * @retval OT_ERROR_NONE          Successfully moved the byte offset.
-     * @retval OT_ERROR_INVALID_ARGS  The requested byte offset is not within the existing message.
+     * @param[in]  aOffset  The byte offset within the message.
      *
      */
-    otError SetOffset(uint16_t aOffset);
+    void SetOffset(uint16_t aOffset);
 
     /**
      * This method returns the type of the message.
@@ -307,7 +409,7 @@
      * @returns The type of the message.
      *
      */
-    uint8_t GetType(void) const { return mBuffer.mHead.mInfo.mType; }
+    Type GetType(void) const { return static_cast<Type>(GetMetadata().mType); }
 
     /**
      * This method sets the message type.
@@ -315,7 +417,7 @@
      * @param[in]  aType  The message type.
      *
      */
-    void SetType(uint8_t aType) { mBuffer.mHead.mInfo.mType = aType; }
+    void SetType(Type aType) { GetMetadata().mType = aType; }
 
     /**
      * This method returns the sub type of the message.
@@ -323,7 +425,7 @@
      * @returns The sub type of the message.
      *
      */
-    uint8_t GetSubType(void) const { return mBuffer.mHead.mInfo.mSubType; }
+    SubType GetSubType(void) const { return static_cast<SubType>(GetMetadata().mSubType); }
 
     /**
      * This method sets the message sub type.
@@ -331,7 +433,7 @@
      * @param[in]  aSubType  The message sub type.
      *
      */
-    void SetSubType(uint8_t aSubType) { mBuffer.mHead.mInfo.mSubType = aSubType; }
+    void SetSubType(SubType aSubType) { GetMetadata().mSubType = aSubType; }
 
     /**
      * This method returns whether or not the message is of MLE subtype.
@@ -348,7 +450,7 @@
      * @returns The priority level associated with this message.
      *
      */
-    uint8_t GetPriority(void) const { return mBuffer.mHead.mInfo.mPriority; }
+    Priority GetPriority(void) const { return static_cast<Priority>(GetMetadata().mPriority); }
 
     /**
      * This method sets the messages priority.
@@ -361,7 +463,7 @@
      * @retval OT_ERROR_INVALID_ARGS   Priority level is not invalid.
      *
      */
-    otError SetPriority(uint8_t aPriority);
+    otError SetPriority(Priority aPriority);
 
     /**
      * This method prepends bytes to the front of the message.
@@ -445,7 +547,7 @@
      *
      * @param[in] aLength  Number of payload bytes to copy.
      *
-     * @returns A pointer to the message or NULL if insufficient message buffers are available.
+     * @returns A pointer to the message or nullptr if insufficient message buffers are available.
      *
      */
     Message *Clone(uint16_t aLength) const;
@@ -457,7 +559,7 @@
      * `Type`, `SubType`, `LinkSecurity`, `Offset`, `InterfaceId`, and `Priority` fields on the cloned message are also
      * copied from the original one.
      *
-     * @returns A pointer to the message or NULL if insufficient message buffers are available.
+     * @returns A pointer to the message or nullptr if insufficient message buffers are available.
      *
      */
     Message *Clone(void) const { return Clone(GetLength()); }
@@ -469,7 +571,7 @@
      * @returns The 6LoWPAN datagram tag or the IPv6 fragment identification.
      *
      */
-    uint32_t GetDatagramTag(void) const { return mBuffer.mHead.mInfo.mDatagramTag; }
+    uint32_t GetDatagramTag(void) const { return GetMetadata().mDatagramTag; }
 
     /**
      * This method sets the datagram tag used for 6LoWPAN fragmentation.
@@ -477,7 +579,7 @@
      * @param[in]  aTag  The 6LoWPAN datagram tag.
      *
      */
-    void SetDatagramTag(uint32_t aTag) { mBuffer.mHead.mInfo.mDatagramTag = aTag; }
+    void SetDatagramTag(uint32_t aTag) { GetMetadata().mDatagramTag = aTag; }
 
     /**
      * This method returns whether or not the message forwarding is scheduled for the child.
@@ -516,6 +618,26 @@
     bool IsChildPending(void) const;
 
     /**
+     * This method returns the RLOC16 of the mesh destination.
+     *
+     * @note Only use this for non-link-local unicast messages.
+     *
+     * @returns The IEEE 802.15.4 Destination PAN ID.
+     *
+     */
+    uint16_t GetMeshDest(void) const { return GetMetadata().mMeshDest; }
+
+    /**
+     * This method sets the RLOC16 of the mesh destination.
+     *
+     * @note Only use this when sending non-link-local unicast messages.
+     *
+     * @param[in]  aMeshDest  The IEEE 802.15.4 Destination PAN ID.
+     *
+     */
+    void SetMeshDest(uint16_t aMeshDest) { GetMetadata().mMeshDest = aMeshDest; }
+
+    /**
      * This method returns the IEEE 802.15.4 Destination PAN ID.
      *
      * @note Only use this when sending MLE Discover Request or Response messages.
@@ -523,7 +645,7 @@
      * @returns The IEEE 802.15.4 Destination PAN ID.
      *
      */
-    uint16_t GetPanId(void) const { return mBuffer.mHead.mInfo.mPanIdChannel.mPanId; }
+    uint16_t GetPanId(void) const { return GetMetadata().mPanIdChannel.mPanId; }
 
     /**
      * This method sets the IEEE 802.15.4 Destination PAN ID.
@@ -533,7 +655,7 @@
      * @param[in]  aPanId  The IEEE 802.15.4 Destination PAN ID.
      *
      */
-    void SetPanId(uint16_t aPanId) { mBuffer.mHead.mInfo.mPanIdChannel.mPanId = aPanId; }
+    void SetPanId(uint16_t aPanId) { GetMetadata().mPanIdChannel.mPanId = aPanId; }
 
     /**
      * This method returns the IEEE 802.15.4 Channel to use for transmission.
@@ -543,7 +665,7 @@
      * @returns The IEEE 802.15.4 Channel to use for transmission.
      *
      */
-    uint8_t GetChannel(void) const { return mBuffer.mHead.mInfo.mPanIdChannel.mChannel; }
+    uint8_t GetChannel(void) const { return GetMetadata().mPanIdChannel.mChannel; }
 
     /**
      * This method sets the IEEE 802.15.4 Channel to use for transmission.
@@ -553,7 +675,7 @@
      * @param[in]  aChannel  The IEEE 802.15.4 Channel to use for transmission.
      *
      */
-    void SetChannel(uint8_t aChannel) { mBuffer.mHead.mInfo.mPanIdChannel.mChannel = aChannel; }
+    void SetChannel(uint8_t aChannel) { GetMetadata().mPanIdChannel.mChannel = aChannel; }
 
     /**
      * This method returns the timeout used for 6LoWPAN reassembly.
@@ -561,7 +683,7 @@
      * @returns The time remaining in seconds.
      *
      */
-    uint8_t GetTimeout(void) const { return mBuffer.mHead.mInfo.mTimeout; }
+    uint8_t GetTimeout(void) const { return GetMetadata().mTimeout; }
 
     /**
      * This method sets the timeout used for 6LoWPAN reassembly.
@@ -569,13 +691,13 @@
      * @param[in]  aTimeout  The timeout value.
      *
      */
-    void SetTimeout(uint8_t aTimeout) { mBuffer.mHead.mInfo.mTimeout = aTimeout; }
+    void SetTimeout(uint8_t aTimeout) { GetMetadata().mTimeout = aTimeout; }
 
     /**
      * This method decrements the timeout.
      *
      */
-    void DecrementTimeout(void) { mBuffer.mHead.mInfo.mTimeout--; }
+    void DecrementTimeout(void) { GetMetadata().mTimeout--; }
 
     /**
      * This method returns whether or not message forwarding is scheduled for direct transmission.
@@ -584,19 +706,19 @@
      * @retval FALSE  If message forwarding is not scheduled for direct transmission.
      *
      */
-    bool GetDirectTransmission(void) const { return mBuffer.mHead.mInfo.mDirectTx; }
+    bool GetDirectTransmission(void) const { return GetMetadata().mDirectTx; }
 
     /**
      * This method unschedules forwarding using direct transmission.
      *
      */
-    void ClearDirectTransmission(void) { mBuffer.mHead.mInfo.mDirectTx = false; }
+    void ClearDirectTransmission(void) { GetMetadata().mDirectTx = false; }
 
     /**
      * This method schedules forwarding using direct transmission.
      *
      */
-    void SetDirectTransmission(void) { mBuffer.mHead.mInfo.mDirectTx = true; }
+    void SetDirectTransmission(void) { GetMetadata().mDirectTx = true; }
 
     /**
      * This method indicates whether the direct transmission of message was successful.
@@ -605,7 +727,7 @@
      * @retval FALSE  If direct transmission of message failed (at least one fragment failed).
      *
      */
-    bool GetTxSuccess(void) const { return mBuffer.mHead.mInfo.mTxSuccess; }
+    bool GetTxSuccess(void) const { return GetMetadata().mTxSuccess; }
 
     /**
      * This method sets whether the direct transmission of message was successful.
@@ -614,7 +736,7 @@
      *                         fragment transmission failed).
      *
      */
-    void SetTxSuccess(bool aTxSuccess) { mBuffer.mHead.mInfo.mTxSuccess = aTxSuccess; }
+    void SetTxSuccess(bool aTxSuccess) { GetMetadata().mTxSuccess = aTxSuccess; }
 
     /**
      * This method indicates whether the message may be evicted.
@@ -623,7 +745,7 @@
      * @retval FALSE  If the message may be evicted.
      *
      */
-    bool GetDoNotEvict(void) const { return mBuffer.mHead.mInfo.mDoNotEvict; }
+    bool GetDoNotEvict(void) const { return GetMetadata().mDoNotEvict; }
 
     /**
      * This method sets whether the message may be evicted.
@@ -631,7 +753,7 @@
      * @param[in]  aDoNotEvict  TRUE if the message may not be evicted, FALSE otherwise.
      *
      */
-    void SetDoNotEvict(bool aDoNotEvict) { mBuffer.mHead.mInfo.mDoNotEvict = aDoNotEvict; }
+    void SetDoNotEvict(bool aDoNotEvict) { GetMetadata().mDoNotEvict = aDoNotEvict; }
 
     /**
      * This method indicates whether or not link security is enabled for the message.
@@ -640,7 +762,7 @@
      * @retval FALSE  If link security is not enabled.
      *
      */
-    bool IsLinkSecurityEnabled(void) const { return mBuffer.mHead.mInfo.mLinkSecurity; }
+    bool IsLinkSecurityEnabled(void) const { return GetMetadata().mLinkSecurity; }
 
     /**
      * This method sets whether or not link security is enabled for the message.
@@ -648,7 +770,7 @@
      * @param[in]  aEnabled  TRUE if link security is enabled, FALSE otherwise.
      *
      */
-    void SetLinkSecurityEnabled(bool aEnabled) { mBuffer.mHead.mInfo.mLinkSecurity = aEnabled; }
+    void SetLinkSecurityEnabled(bool aEnabled) { GetMetadata().mLinkSecurity = aEnabled; }
 
     /**
      * This method updates the average RSS (Received Signal Strength) associated with the message by adding the given
@@ -658,7 +780,7 @@
      * @param[in] aRss A new RSS value (in dBm) to be added to average.
      *
      */
-    void AddRss(int8_t aRss) { mBuffer.mHead.mInfo.mRssAverager.Add(aRss); }
+    void AddRss(int8_t aRss) { IgnoreError(GetMetadata().mRssAverager.Add(aRss)); }
 
     /**
      * This method returns the average RSS (Received Signal Strength) associated with the message.
@@ -666,7 +788,7 @@
      * @returns The current average RSS value (in dBm) or OT_RADIO_RSSI_INVALID if no average is available.
      *
      */
-    int8_t GetAverageRss(void) const { return mBuffer.mHead.mInfo.mRssAverager.GetAverage(); }
+    int8_t GetAverageRss(void) const { return GetMetadata().mRssAverager.GetAverage(); }
 
     /**
      * This method returns a const reference to RssAverager of the message.
@@ -674,7 +796,7 @@
      * @returns A const reference to the RssAverager of the message.
      *
      */
-    const RssAverager &GetRssAverager(void) const { return mBuffer.mHead.mInfo.mRssAverager; }
+    const RssAverager &GetRssAverager(void) const { return GetMetadata().mRssAverager; }
 
     /**
      * This static method updates a checksum.
@@ -714,31 +836,44 @@
     /**
      * This method returns a pointer to the message queue (if any) where this message is queued.
      *
-     * @returns A pointer to the message queue or NULL if not in any message queue.
+     * @returns A pointer to the message queue or nullptr if not in any message queue.
      *
      */
     MessageQueue *GetMessageQueue(void) const
     {
-        return (!mBuffer.mHead.mInfo.mInPriorityQ) ? mBuffer.mHead.mInfo.mQueue.mMessage : NULL;
+        return (!GetMetadata().mInPriorityQ) ? GetMetadata().mQueue.mMessage : nullptr;
     }
 
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    /**
+     * This method returns a pointer to the priority message queue (if any) where this message is queued.
+     *
+     * @returns A pointer to the priority queue or nullptr if not in any priority queue.
+     *
+     */
+    PriorityQueue *GetPriorityQueue(void) const
+    {
+        return (GetMetadata().mInPriorityQ) ? GetMetadata().mQueue.mPriority : nullptr;
+    }
+
     /**
      * This method indicates whether or not the message is also used for time sync purpose.
      *
+     * When OPENTHREAD_CONFIG_TIME_SYNC_ENABLE is 0, this method always return false.
+     *
      * @retval TRUE   If the message is also used for time sync purpose.
      * @retval FALSE  If the message is not used for time sync purpose.
      *
      */
-    bool IsTimeSync(void) const { return mBuffer.mHead.mInfo.mTimeSync; }
+    bool IsTimeSync(void) const;
 
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     /**
      * This method sets whether or not the message is also used for time sync purpose.
      *
      * @param[in]  aEnabled  TRUE if the message is also used for time sync purpose, FALSE otherwise.
      *
      */
-    void SetTimeSync(bool aEnabled) { mBuffer.mHead.mInfo.mTimeSync = aEnabled; }
+    void SetTimeSync(bool aEnabled) { GetMetadata().mTimeSync = aEnabled; }
 
     /**
      * This method sets the offset to network time.
@@ -746,10 +881,7 @@
      * @param[in]  aNetworkTimeOffset  The offset to network time.
      *
      */
-    void SetNetworkTimeOffset(int64_t aNetworkTimeOffset)
-    {
-        mBuffer.mHead.mInfo.mNetworkTimeOffset = aNetworkTimeOffset;
-    }
+    void SetNetworkTimeOffset(int64_t aNetworkTimeOffset) { GetMetadata().mNetworkTimeOffset = aNetworkTimeOffset; }
 
     /**
      * This method gets the offset to network time.
@@ -757,7 +889,7 @@
      * @returns  The offset to network time.
      *
      */
-    int64_t GetNetworkTimeOffset(void) const { return mBuffer.mHead.mInfo.mNetworkTimeOffset; }
+    int64_t GetNetworkTimeOffset(void) const { return GetMetadata().mNetworkTimeOffset; }
 
     /**
      * This method sets the time sync sequence.
@@ -765,7 +897,7 @@
      * @param[in]  aTimeSyncSeq  The time sync sequence.
      *
      */
-    void SetTimeSyncSeq(uint8_t aTimeSyncSeq) { mBuffer.mHead.mInfo.mTimeSyncSeq = aTimeSyncSeq; }
+    void SetTimeSyncSeq(uint8_t aTimeSyncSeq) { GetMetadata().mTimeSyncSeq = aTimeSyncSeq; }
 
     /**
      * This method gets the time sync sequence.
@@ -773,7 +905,7 @@
      * @returns  The time sync sequence.
      *
      */
-    uint8_t GetTimeSyncSeq(void) const { return mBuffer.mHead.mInfo.mTimeSyncSeq; }
+    uint8_t GetTimeSyncSeq(void) const { return GetMetadata().mTimeSyncSeq; }
 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 
 private:
@@ -783,7 +915,7 @@
      * @returns A pointer to the message pool.
      *
      */
-    MessagePool *GetMessagePool(void) const { return mBuffer.mHead.mInfo.mMessagePool; }
+    MessagePool *GetMessagePool(void) const { return GetMetadata().mMessagePool; }
 
     /**
      * This method sets the message pool this message to which this message belongs.
@@ -791,7 +923,7 @@
      * @param[in] aMessagePool  A pointer to the message pool
      *
      */
-    void SetMessagePool(MessagePool *aMessagePool) { mBuffer.mHead.mInfo.mMessagePool = aMessagePool; }
+    void SetMessagePool(MessagePool *aMessagePool) { GetMetadata().mMessagePool = aMessagePool; }
 
     /**
      * This method returns `true` if the message is enqueued in any queue (`MessageQueue` or `PriorityQueue`).
@@ -799,7 +931,7 @@
      * @returns `true` if the message is in any queue, `false` otherwise.
      *
      */
-    bool IsInAQueue(void) const { return (mBuffer.mHead.mInfo.mQueue.mMessage != NULL); }
+    bool IsInAQueue(void) const { return (GetMetadata().mQueue.mMessage != nullptr); }
 
     /**
      * This method sets the message queue information for the message.
@@ -810,17 +942,6 @@
     void SetMessageQueue(MessageQueue *aMessageQueue);
 
     /**
-     * This method returns a pointer to the priority message queue (if any) where this message is queued.
-     *
-     * @returns A pointer to the priority queue or NULL if not in any priority queue.
-     *
-     */
-    PriorityQueue *GetPriorityQueue(void) const
-    {
-        return (mBuffer.mHead.mInfo.mInPriorityQ) ? mBuffer.mHead.mInfo.mQueue.mPriority : NULL;
-    }
-
-    /**
      * This method sets the message queue information for the message.
      *
      * @param[in]  aPriorityQueue  A pointer to the priority queue where this message is queued.
@@ -834,7 +955,7 @@
      * @returns A reference to the mNext pointer.
      *
      */
-    Message *&Next(void) { return mBuffer.mHead.mInfo.mNext; }
+    Message *&Next(void) { return GetMetadata().mNext; }
 
     /**
      * This method returns a reference to the `mNext` pointer (const pointer).
@@ -843,7 +964,7 @@
      * @returns A reference to the mNext pointer.
      *
      */
-    Message *const &Next(void) const { return mBuffer.mHead.mInfo.mNext; }
+    Message *const &Next(void) const { return GetMetadata().mNext; }
 
     /**
      * This method returns a reference to the `mPrev` pointer.
@@ -851,7 +972,7 @@
      * @returns A reference to the mPrev pointer.
      *
      */
-    Message *&Prev(void) { return mBuffer.mHead.mInfo.mPrev; }
+    Message *&Prev(void) { return GetMetadata().mPrev; }
 
     /**
      * This method returns the number of reserved header bytes.
@@ -859,7 +980,7 @@
      * @returns The number of reserved header bytes.
      *
      */
-    uint16_t GetReserved(void) const { return mBuffer.mHead.mInfo.mReserved; }
+    uint16_t GetReserved(void) const { return GetMetadata().mReserved; }
 
     /**
      * This method sets the number of reserved header bytes.
@@ -867,7 +988,7 @@
      * @param[in] aReservedHeader  The number of header bytes to reserve.
      *
      */
-    void SetReserved(uint16_t aReservedHeader) { mBuffer.mHead.mInfo.mReserved = aReservedHeader; }
+    void SetReserved(uint16_t aReservedHeader) { GetMetadata().mReserved = aReservedHeader; }
 
     /**
      * This method adds or frees message buffers to meet the requested length.
@@ -921,11 +1042,8 @@
      *
      * @param[in]  aMessage  The message to add.
      *
-     * @retval OT_ERROR_NONE     Successfully added the message to the list.
-     * @retval OT_ERROR_ALREADY  The message is already enqueued in a list.
-     *
      */
-    otError Enqueue(Message &aMessage) { return Enqueue(aMessage, kQueuePositionTail); }
+    void Enqueue(Message &aMessage) { Enqueue(aMessage, kQueuePositionTail); }
 
     /**
      * This method adds a message at a given position (head/tail) of the list.
@@ -933,22 +1051,16 @@
      * @param[in]  aMessage  The message to add.
      * @param[in]  aPosition The position (head or tail) where to add the message.
      *
-     * @retval OT_ERROR_NONE     Successfully added the message to the list.
-     * @retval OT_ERROR_ALREADY  The message is already enqueued in a list.
-     *
      */
-    otError Enqueue(Message &aMessage, QueuePosition aPosition);
+    void Enqueue(Message &aMessage, QueuePosition aPosition);
 
     /**
      * This method removes a message from the list.
      *
      * @param[in]  aMessage  The message to remove.
      *
-     * @retval OT_ERROR_NONE       Successfully removed the message from the list.
-     * @retval OT_ERROR_NOT_FOUND  The message is not enqueued in a list.
-     *
      */
-    otError Dequeue(Message &aMessage);
+    void Dequeue(Message &aMessage);
 
     /**
      * This method returns the number of messages and buffers enqueued.
@@ -1007,33 +1119,27 @@
      *
      * @param[in] aPriority   Priority level.
      *
-     * @returns A pointer to the first message with given priority level or NULL if there is no messages with
+     * @returns A pointer to the first message with given priority level or nullptr if there is no messages with
      *          this priority level.
      *
      */
-    Message *GetHeadForPriority(uint8_t aPriority) const;
+    Message *GetHeadForPriority(Message::Priority aPriority) const;
 
     /**
      * This method adds a message to the queue.
      *
      * @param[in]  aMessage  The message to add.
      *
-     * @retval OT_ERROR_NONE     Successfully added the message to the list.
-     * @retval OT_ERROR_ALREADY  The message is already enqueued in a list.
-     *
      */
-    otError Enqueue(Message &aMessage);
+    void Enqueue(Message &aMessage);
 
     /**
      * This method removes a message from the list.
      *
      * @param[in]  aMessage  The message to remove.
      *
-     * @retval OT_ERROR_NONE       Successfully removed the message from the list.
-     * @retval OT_ERROR_NOT_FOUND  The message is not enqueued in a list.
-     *
      */
-    otError Dequeue(Message &aMessage);
+    void Dequeue(Message &aMessage);
 
     /**
      * This method returns the number of messages and buffers enqueued.
@@ -1067,15 +1173,15 @@
     }
 
     /**
-     * This private method finds the first non-NULL tail starting from the given priority level and moving forward.
+     * This private method finds the first non-nullptr tail starting from the given priority level and moving forward.
      * It wraps from priority value `kNumPriorities` -1 back to 0.
      *
      * aStartPriorityLevel  Starting priority level.
      *
-     * @returns The first non-NULL tail pointer, or NULL if all the
+     * @returns The first non-nullptr tail pointer, or nullptr if all the
      *
      */
-    Message *FindFirstNonNullTail(uint8_t aStartPriorityLevel) const;
+    Message *FindFirstNonNullTail(Message::Priority aStartPriorityLevel) const;
 
 private:
     Message *mTails[Message::kNumPriorities]; ///< Tail pointers associated with different priority levels.
@@ -1085,7 +1191,7 @@
  * This class represents a message pool
  *
  */
-class MessagePool : public InstanceLocator
+class MessagePool : public InstanceLocator, private NonCopyable
 {
     friend class Message;
     friend class MessageQueue;
@@ -1099,32 +1205,33 @@
     explicit MessagePool(Instance &aInstance);
 
     /**
-     * This method is used to obtain a new message. The default priority `kDefaultMessagePriority`
-     * is assigned to the message.
+     * This method is used to obtain a new message.
+     *
+     * The link security is enabled by default on the newly obtained message.
      *
      * @param[in]  aType           The message type.
      * @param[in]  aReserveHeader  The number of header bytes to reserve.
      * @param[in]  aPriority       The priority level of the message.
      *
-     * @returns A pointer to the message or NULL if no message buffers are available.
+     * @returns A pointer to the message or nullptr if no message buffers are available.
      *
      */
-    Message *New(uint8_t aType, uint16_t aReserveHeader, uint8_t aPriority = kDefaultMessagePriority);
+    Message *New(Message::Type aType, uint16_t aReserveHeader, Message::Priority aPriority);
 
+public:
     /**
      * This method is used to obtain a new message with specified settings.
      *
-     * @note If @p aSettings is 'NULL', the link layer security is enabled and the message priority is set to
-     * OT_MESSAGE_PRIORITY_NORMAL by default.
-     *
      * @param[in]  aType           The message type.
      * @param[in]  aReserveHeader  The number of header bytes to reserve.
-     * @param[in]  aSettings       A pointer to the message settings or NULL to set default settings.
+     * @param[in]  aSettings       The message settings.
      *
-     * @returns A pointer to the message or NULL if no message buffers are available.
+     * @returns A pointer to the message or nullptr if no message buffers are available.
      *
      */
-    Message *New(uint8_t aType, uint16_t aReserveHeader, const otMessageSettings *aSettings);
+    Message *New(Message::Type            aType,
+                 uint16_t                 aReserveHeader,
+                 const Message::Settings &aSettings = Message::Settings::GetDefault());
 
     /**
      * This method is used to free a message and return all message buffers to the buffer pool.
@@ -1143,19 +1250,13 @@
     uint16_t GetFreeBufferCount(void) const;
 
 private:
-    enum
-    {
-        kDefaultMessagePriority = Message::kPriorityNormal,
-    };
-
-    Buffer *NewBuffer(uint8_t aPriority);
+    Buffer *NewBuffer(Message::Priority aPriority);
     void    FreeBuffers(Buffer *aBuffer);
-    otError ReclaimBuffers(int aNumBuffers, uint8_t aPriority);
+    otError ReclaimBuffers(int aNumBuffers, Message::Priority aPriority);
 
 #if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT == 0
-    uint16_t mNumFreeBuffers;
-    Buffer   mBuffers[kNumBuffers];
-    Buffer * mFreeBuffers;
+    uint16_t                  mNumFreeBuffers;
+    Pool<Buffer, kNumBuffers> mBufferPool;
 #endif
 };
 
diff --git a/src/core/common/non_copyable.hpp b/src/core/common/non_copyable.hpp
new file mode 100644
index 0000000..e57afe4
--- /dev/null
+++ b/src/core/common/non_copyable.hpp
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes a common base class for disabling copying.
+ */
+
+#ifndef NON_COPYABLE_HPP_
+#define NON_COPYABLE_HPP_
+
+namespace ot {
+
+/**
+ * This class makes any class that derives from it non-copyable. It is
+ * intended to be used as a private base class.
+ */
+class NonCopyable
+{
+protected:
+    NonCopyable(void) {}
+    ~NonCopyable(void) {}
+
+private:
+    NonCopyable(const NonCopyable &);
+    NonCopyable &operator=(const NonCopyable &);
+};
+
+} // namespace ot
+
+#endif // NON_COPYABLE_HPP_
diff --git a/src/core/common/notifier.cpp b/src/core/common/notifier.cpp
index 749f8cf..12f6c1c 100644
--- a/src/core/common/notifier.cpp
+++ b/src/core/common/notifier.cpp
@@ -40,48 +40,46 @@
 
 namespace ot {
 
-Notifier::Callback::Callback(Instance &aInstance, Handler aHandler, void *aOwner)
-    : OwnerLocator(aOwner)
-    , mHandler(aHandler)
-    , mNext(NULL)
+Notifier::Receiver::Receiver(Instance &aInstance, Handler aHandler)
+    : mHandler(aHandler)
+    , mNext(nullptr)
 {
-    assert(aHandler != NULL);
-    aInstance.Get<Notifier>().RegisterCallback(*this);
+    aInstance.Get<Notifier>().RegisterReceiver(*this);
 }
 
 Notifier::Notifier(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mFlagsToSignal(0)
-    , mSignaledFlags(0)
-    , mTask(aInstance, &Notifier::HandleStateChanged, this)
-    , mCallbacks()
+    , mEventsToSignal()
+    , mSignaledEvents()
+    , mTask(aInstance, Notifier::EmitEvents, this)
+    , mReceivers()
 {
     for (unsigned int i = 0; i < kMaxExternalHandlers; i++)
     {
-        mExternalCallbacks[i].mHandler = NULL;
-        mExternalCallbacks[i].mContext = NULL;
+        mExternalCallbacks[i].mHandler = nullptr;
+        mExternalCallbacks[i].mContext = nullptr;
     }
 }
 
-void Notifier::RegisterCallback(Callback &aCallback)
+void Notifier::RegisterReceiver(Receiver &aReceiver)
 {
-    mCallbacks.Push(aCallback);
+    mReceivers.Push(aReceiver);
 }
 
 otError Notifier::RegisterCallback(otStateChangedCallback aCallback, void *aContext)
 {
     otError           error          = OT_ERROR_NONE;
-    ExternalCallback *unusedCallback = NULL;
+    ExternalCallback *unusedCallback = nullptr;
 
-    VerifyOrExit(aCallback != NULL);
+    VerifyOrExit(aCallback != nullptr, OT_NOOP);
 
     for (unsigned int i = 0; i < kMaxExternalHandlers; i++)
     {
         ExternalCallback &callback = mExternalCallbacks[i];
 
-        if (callback.mHandler == NULL)
+        if (callback.mHandler == nullptr)
         {
-            if (unusedCallback == NULL)
+            if (unusedCallback == nullptr)
             {
                 unusedCallback = &callback;
             }
@@ -92,7 +90,7 @@
         VerifyOrExit((callback.mHandler != aCallback) || (callback.mContext != aContext), error = OT_ERROR_ALREADY);
     }
 
-    VerifyOrExit(unusedCallback != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(unusedCallback != nullptr, error = OT_ERROR_NO_BUFS);
 
     unusedCallback->mHandler = aCallback;
     unusedCallback->mContext = aContext;
@@ -103,7 +101,7 @@
 
 void Notifier::RemoveCallback(otStateChangedCallback aCallback, void *aContext)
 {
-    VerifyOrExit(aCallback != NULL);
+    VerifyOrExit(aCallback != nullptr, OT_NOOP);
 
     for (unsigned int i = 0; i < kMaxExternalHandlers; i++)
     {
@@ -111,8 +109,8 @@
 
         if ((callback.mHandler == aCallback) && (callback.mContext == aContext))
         {
-            callback.mHandler = NULL;
-            callback.mContext = NULL;
+            callback.mHandler = nullptr;
+            callback.mContext = nullptr;
         }
     }
 
@@ -120,48 +118,52 @@
     return;
 }
 
-void Notifier::Signal(otChangedFlags aFlags)
+void Notifier::Signal(Event aEvent)
 {
-    mFlagsToSignal |= aFlags;
-    mSignaledFlags |= aFlags;
+    mEventsToSignal.Add(aEvent);
+    mSignaledEvents.Add(aEvent);
     mTask.Post();
 }
 
-void Notifier::SignalIfFirst(otChangedFlags aFlags)
+void Notifier::SignalIfFirst(Event aEvent)
 {
-    if (!HasSignaled(aFlags))
+    if (!HasSignaled(aEvent))
     {
-        Signal(aFlags);
+        Signal(aEvent);
     }
 }
 
-void Notifier::HandleStateChanged(Tasklet &aTasklet)
+void Notifier::EmitEvents(Tasklet &aTasklet)
 {
-    aTasklet.GetOwner<Notifier>().HandleStateChanged();
+    aTasklet.GetOwner<Notifier>().EmitEvents();
 }
 
-void Notifier::HandleStateChanged(void)
+void Notifier::EmitEvents(void)
 {
-    otChangedFlags flags = mFlagsToSignal;
+    Events events;
 
-    VerifyOrExit(flags != 0);
+    VerifyOrExit(!mEventsToSignal.IsEmpty(), OT_NOOP);
 
-    mFlagsToSignal = 0;
+    // Note that the callbacks may signal new events, so we create a
+    // copy of `mEventsToSignal` and then clear it.
 
-    LogChangedFlags(flags);
+    events = mEventsToSignal;
+    mEventsToSignal.Clear();
 
-    for (Callback *callback = mCallbacks.GetHead(); callback != NULL; callback = callback->GetNext())
+    LogEvents(events);
+
+    for (Receiver *receiver = mReceivers.GetHead(); receiver != nullptr; receiver = receiver->GetNext())
     {
-        callback->Invoke(flags);
+        receiver->Emit(events);
     }
 
     for (unsigned int i = 0; i < kMaxExternalHandlers; i++)
     {
         ExternalCallback &callback = mExternalCallbacks[i];
 
-        if (callback.mHandler != NULL)
+        if (callback.mHandler != nullptr)
         {
-            callback.mHandler(flags, callback.mContext);
+            callback.mHandler(events.GetAsFlags(), callback.mContext);
         }
     }
 
@@ -173,29 +175,29 @@
 
 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_CORE == 1)
 
-void Notifier::LogChangedFlags(otChangedFlags aFlags) const
+void Notifier::LogEvents(Events aEvents) const
 {
-    otChangedFlags                 flags    = aFlags;
+    Events::Flags                  flags    = aEvents.GetAsFlags();
     bool                           addSpace = false;
     bool                           didLog   = false;
     String<kFlagsStringBufferSize> string;
 
-    for (uint8_t bit = 0; bit < sizeof(otChangedFlags) * CHAR_BIT; bit++)
+    for (uint8_t bit = 0; bit < sizeof(Events::Flags) * CHAR_BIT; bit++)
     {
-        VerifyOrExit(flags != 0);
+        VerifyOrExit(flags != 0, OT_NOOP);
 
         if (flags & (1 << bit))
         {
             if (string.GetLength() >= kFlagsStringLineLimit)
             {
-                otLogInfoCore("Notifier: StateChanged (0x%08x) %s%s ...", aFlags, didLog ? "... " : "[",
+                otLogInfoCore("Notifier: StateChanged (0x%08x) %s%s ...", aEvents.GetAsFlags(), didLog ? "... " : "[",
                               string.AsCString());
                 string.Clear();
                 didLog   = true;
                 addSpace = false;
             }
 
-            string.Append("%s%s", addSpace ? " " : "", FlagToString(1 << bit));
+            IgnoreError(string.Append("%s%s", addSpace ? " " : "", EventToString(static_cast<Event>(1 << bit))));
             addSpace = true;
 
             flags ^= (1 << bit);
@@ -203,10 +205,11 @@
     }
 
 exit:
-    otLogInfoCore("Notifier: StateChanged (0x%08x) %s%s] ", aFlags, didLog ? "... " : "[", string.AsCString());
+    otLogInfoCore("Notifier: StateChanged (0x%08x) %s%s] ", aEvents.GetAsFlags(), didLog ? "... " : "[",
+                  string.AsCString());
 }
 
-const char *Notifier::FlagToString(otChangedFlags aFlag) const
+const char *Notifier::EventToString(Event aEvent) const
 {
     const char *retval = "(unknown)";
 
@@ -214,109 +217,118 @@
     // strings from this method should have shorter length than
     // `kMaxFlagNameLength` value.
 
-    switch (aFlag)
+    switch (aEvent)
     {
-    case OT_CHANGED_IP6_ADDRESS_ADDED:
+    case kEventIp6AddressAdded:
         retval = "Ip6+";
         break;
 
-    case OT_CHANGED_IP6_ADDRESS_REMOVED:
+    case kEventIp6AddressRemoved:
         retval = "Ip6-";
         break;
 
-    case OT_CHANGED_THREAD_ROLE:
+    case kEventThreadRoleChanged:
         retval = "Role";
         break;
 
-    case OT_CHANGED_THREAD_LL_ADDR:
+    case kEventThreadLinkLocalAddrChanged:
         retval = "LLAddr";
         break;
 
-    case OT_CHANGED_THREAD_ML_ADDR:
+    case kEventThreadMeshLocalAddrChanged:
         retval = "MLAddr";
         break;
 
-    case OT_CHANGED_THREAD_RLOC_ADDED:
+    case kEventThreadRlocAdded:
         retval = "Rloc+";
         break;
 
-    case OT_CHANGED_THREAD_RLOC_REMOVED:
+    case kEventThreadRlocRemoved:
         retval = "Rloc-";
         break;
 
-    case OT_CHANGED_THREAD_PARTITION_ID:
+    case kEventThreadPartitionIdChanged:
         retval = "PartitionId";
         break;
 
-    case OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER:
+    case kEventThreadKeySeqCounterChanged:
         retval = "KeySeqCntr";
         break;
 
-    case OT_CHANGED_THREAD_NETDATA:
+    case kEventThreadNetdataChanged:
         retval = "NetData";
         break;
 
-    case OT_CHANGED_THREAD_CHILD_ADDED:
+    case kEventThreadChildAdded:
         retval = "Child+";
         break;
 
-    case OT_CHANGED_THREAD_CHILD_REMOVED:
+    case kEventThreadChildRemoved:
         retval = "Child-";
         break;
 
-    case OT_CHANGED_IP6_MULTICAST_SUBSCRIBED:
+    case kEventIp6MulticastSubscribed:
         retval = "Ip6Mult+";
         break;
 
-    case OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED:
+    case kEventIp6MulticastUnsubscribed:
         retval = "Ip6Mult-";
         break;
 
-    case OT_CHANGED_THREAD_CHANNEL:
+    case kEventThreadChannelChanged:
         retval = "Channel";
         break;
 
-    case OT_CHANGED_THREAD_PANID:
+    case kEventThreadPanIdChanged:
         retval = "PanId";
         break;
 
-    case OT_CHANGED_THREAD_NETWORK_NAME:
+    case kEventThreadNetworkNameChanged:
         retval = "NetName";
         break;
 
-    case OT_CHANGED_THREAD_EXT_PANID:
+    case kEventThreadExtPanIdChanged:
         retval = "ExtPanId";
         break;
 
-    case OT_CHANGED_MASTER_KEY:
+    case kEventMasterKeyChanged:
         retval = "MstrKey";
         break;
 
-    case OT_CHANGED_PSKC:
+    case kEventPskcChanged:
         retval = "PSKc";
         break;
 
-    case OT_CHANGED_SECURITY_POLICY:
+    case kEventSecurityPolicyChanged:
         retval = "SecPolicy";
         break;
 
-    case OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL:
+    case kEventChannelManagerNewChannelChanged:
         retval = "CMNewChan";
         break;
 
-    case OT_CHANGED_SUPPORTED_CHANNEL_MASK:
+    case kEventSupportedChannelMaskChanged:
         retval = "ChanMask";
         break;
 
-    case OT_CHANGED_BORDER_AGENT_STATE:
-        retval = "BorderAgentState";
+    case kEventCommissionerStateChanged:
+        retval = "CommissionerState";
         break;
 
-    case OT_CHANGED_THREAD_NETIF_STATE:
+    case kEventThreadNetifStateChanged:
         retval = "NetifState";
         break;
 
-    default:
+    case kEventThreadBackboneRouterStateChanged:
+        retval = "BbrState";
+        break;
+
+    case kEventThreadBackboneRouterLocalChanged:
+        retval = "BbrLocal";
+        break;
+
+    case kEventJoinerStateChanged:
+        retval = "JoinerState";
         break;
     }
 
@@ -325,11 +337,11 @@
 
 #else // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_CORE == 1)
 
-void Notifier::LogChangedFlags(otChangedFlags) const
+void Notifier::LogEvents(Events) const
 {
 }
 
-const char *Notifier::FlagToString(otChangedFlags) const
+const char *Notifier::EventToString(Event) const
 {
     return "";
 }
diff --git a/src/core/common/notifier.hpp b/src/core/common/notifier.hpp
index 65e98fd..b3c6bcf 100644
--- a/src/core/common/notifier.hpp
+++ b/src/core/common/notifier.hpp
@@ -44,6 +44,7 @@
 
 #include "common/linked_list.hpp"
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 #include "common/tasklet.hpp"
 
 namespace ot {
@@ -59,57 +60,178 @@
  */
 
 /**
+ * This enumeration type represents events emitted from OpenThread Notifier.
+ *
+ */
+enum Event
+{
+    kEventIp6AddressAdded                  = OT_CHANGED_IP6_ADDRESS_ADDED,            ///< IPv6 address was added
+    kEventIp6AddressRemoved                = OT_CHANGED_IP6_ADDRESS_REMOVED,          ///< IPv6 address was removed
+    kEventThreadRoleChanged                = OT_CHANGED_THREAD_ROLE,                  ///< Role changed
+    kEventThreadLinkLocalAddrChanged       = OT_CHANGED_THREAD_LL_ADDR,               ///< Link-local address changed
+    kEventThreadMeshLocalAddrChanged       = OT_CHANGED_THREAD_ML_ADDR,               ///< Mesh-local address changed
+    kEventThreadRlocAdded                  = OT_CHANGED_THREAD_RLOC_ADDED,            ///< RLOC was added
+    kEventThreadRlocRemoved                = OT_CHANGED_THREAD_RLOC_REMOVED,          ///< RLOC was removed
+    kEventThreadPartitionIdChanged         = OT_CHANGED_THREAD_PARTITION_ID,          ///< Partition ID changed
+    kEventThreadKeySeqCounterChanged       = OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER,  ///< Key Sequence changed
+    kEventThreadNetdataChanged             = OT_CHANGED_THREAD_NETDATA,               ///< Network Data changed
+    kEventThreadChildAdded                 = OT_CHANGED_THREAD_CHILD_ADDED,           ///< Child was added
+    kEventThreadChildRemoved               = OT_CHANGED_THREAD_CHILD_REMOVED,         ///< Child was removed
+    kEventIp6MulticastSubscribed           = OT_CHANGED_IP6_MULTICAST_SUBSCRIBED,     ///< Multicast address added
+    kEventIp6MulticastUnsubscribed         = OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED,   ///< Multicast address removed
+    kEventThreadChannelChanged             = OT_CHANGED_THREAD_CHANNEL,               ///< Network channel changed
+    kEventThreadPanIdChanged               = OT_CHANGED_THREAD_PANID,                 ///< Network PAN ID changed
+    kEventThreadNetworkNameChanged         = OT_CHANGED_THREAD_NETWORK_NAME,          ///< Network name changed
+    kEventThreadExtPanIdChanged            = OT_CHANGED_THREAD_EXT_PANID,             ///< Extended PAN ID changed
+    kEventMasterKeyChanged                 = OT_CHANGED_MASTER_KEY,                   ///< Master Key changed
+    kEventPskcChanged                      = OT_CHANGED_PSKC,                         ///< PSKc changed
+    kEventSecurityPolicyChanged            = OT_CHANGED_SECURITY_POLICY,              ///< Security Policy changed
+    kEventChannelManagerNewChannelChanged  = OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL,  ///< New Channel (channel-manager)
+    kEventSupportedChannelMaskChanged      = OT_CHANGED_SUPPORTED_CHANNEL_MASK,       ///< Channel mask changed
+    kEventCommissionerStateChanged         = OT_CHANGED_COMMISSIONER_STATE,           ///< Commissioner state changed
+    kEventThreadNetifStateChanged          = OT_CHANGED_THREAD_NETIF_STATE,           ///< Netif state changed
+    kEventThreadBackboneRouterStateChanged = OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE, ///< Backbone Router state changed
+    kEventThreadBackboneRouterLocalChanged = OT_CHANGED_THREAD_BACKBONE_ROUTER_LOCAL, ///< Local Backbone Router changed
+    kEventJoinerStateChanged               = OT_CHANGED_JOINER_STATE,                 ///< Joiner state changed
+};
+
+/**
+ * This type represents a list of events.
+ *
+ */
+class Events
+{
+public:
+    /**
+     * This type represents a bit-field indicating a list of events (with values from `Event`)
+     *
+     */
+    typedef otChangedFlags Flags;
+
+    /**
+     * This constructor initializes the `Events` list (as empty).
+     *
+     */
+    Events(void)
+        : mEventFlags(0)
+    {
+    }
+
+    /**
+     * This method clears the `Events` list.
+     *
+     */
+    void Clear(void) { mEventFlags = 0; }
+
+    /**
+     * This method indicates whether the `Events` list contains a given event.
+     *
+     * @param[in] aEvent  The event to check.
+     *
+     * @returns TRUE if the list contains the @p aEvent, FALSE otherwise.
+     *
+     */
+    bool Contains(Event aEvent) const { return (mEventFlags & aEvent) != 0; }
+
+    /**
+     * This method indicates whether the `Events` list contains any of a given set of events.
+     *
+     * @param[in] aEvents  The events set to check (must be a collection of `Event` constants combined using `|`).
+     *
+     * @returns TRUE if the list contains any of the @p aEvents set, FALSE otherwise.
+     *
+     */
+    bool ContainsAny(Flags aEvents) const { return (mEventFlags & aEvents) != 0; }
+
+    /**
+     * This method indicates whether the `Events` list contains all of a given set of events.
+     *
+     * @param[in] aEvents  The events set to check (must be collection of `Event` constants combined using `|`).
+     *
+     * @returns TRUE if the list contains all of the @p aEvents set, FALSE otherwise.
+     *
+     */
+    bool ContainsAll(Flags aEvents) const { return (mEventFlags & aEvents) == aEvents; }
+
+    /**
+     * This method adds a given event to the `Events` list.
+     *
+     * @param[in] aEvent  The event to add.
+     *
+     */
+    void Add(Event aEvent) { mEventFlags |= aEvent; }
+
+    /**
+     * This method indicates whether the `Events` list is empty.
+     *
+     * @returns TRUE if the list is empty, FALSE otherwise.
+     *
+     */
+    bool IsEmpty(void) const { return (mEventFlags == 0); }
+
+    /**
+     * This method gets the `Events` list as bit-field `Flags` value.
+     *
+     * @returns The list as bit-field `Flags` value.
+     *
+     */
+    Flags GetAsFlags(void) const { return mEventFlags; }
+
+private:
+    Flags mEventFlags;
+};
+
+/**
  * This class implements the OpenThread Notifier.
  *
  * It can be used to register callbacks that notify of state or configuration changes within OpenThread.
  *
  * Two callback models are provided:
  *
- * - A `Notifier::Callback` object that upon initialization (from its constructor) auto-registers itself with
- *   the `Notifier`. This model is mainly used by OpenThread core modules.
+ * - A `Notifier::Receiver` class which should be inherited by OpenThread core types to register themselves as a
+ *    receiver of `Notifier` events.
  *
  * - A `otStateChangedCallback` callback handler which needs to be explicitly registered with the `Notifier`. This is
  *   commonly used by external users (provided as an OpenThread public API). Max number of such callbacks that can be
  *   registered at the same time is specified by `OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS` configuration parameter.
  *
  */
-class Notifier : public InstanceLocator
+class Notifier : public InstanceLocator, private NonCopyable
 {
 public:
     /**
-     * This class defines a `Notifier` callback instance.
+     * This class defines a `Notifier::Receiver` instance.
      *
      */
-    class Callback : public OwnerLocator, public LinkedListEntry<Callback>
+    class Receiver : public LinkedListEntry<Receiver>
     {
         friend class Notifier;
-        friend class LinkedListEntry<Callback>;
+        friend class LinkedListEntry<Receiver>;
 
     public:
         /**
-         * This type defines the function pointer which is called to notify of state or configuration changes.
+         * This type defines the function reference which is invoked to notify of events (state/configuration changes)..
          *
-         * @param[in] aCallback    A reference to callback instance.
-         * @param[in] aFlags       A bit-field indicating specific state or configuration that has changed.
+         * @param[in] aReceiver    A reference to `Receiver` instance.
+         * @param[in] aEvents      The list of events.
          *
          */
-        typedef void (*Handler)(Callback &aCallback, otChangedFlags aFlags);
+        typedef void (&Handler)(Receiver &aReceiver, Events aEvents);
 
         /**
-         * This constructor initializes a `Callback` instance and registers it with `Notifier`.
+         * This constructor initializes a `Receiver` instance and registers it with `Notifier`.
          *
          * @param[in] aInstance   A reference to OpenThread instance.
-         * @param[in] aHandler    A function pointer to the callback handler.
-         * @param[in] aOwner      A pointer to the owner of the `Callback` instance.
+         * @param[in] aHandler    The handler function reference.
          *
          */
-        Callback(Instance &aInstance, Handler aHandler, void *aOwner);
+        Receiver(Instance &aInstance, Handler aHandler);
 
     private:
-        void Invoke(otChangedFlags aFlags) { mHandler(*this, aFlags); }
+        void Emit(Events aEvents) { mHandler(*this, aEvents); }
 
         Handler   mHandler;
-        Callback *mNext;
+        Receiver *mNext;
     };
 
     /**
@@ -143,70 +265,69 @@
     void RemoveCallback(otStateChangedCallback aCallback, void *aContext);
 
     /**
-     * This method schedules signaling of changed flags.
+     * This method schedules signaling of an event.
      *
-     * @param[in]  aFlags       A bit-field indicating what configuration or state has changed.
+     * @param[in]  aEvent     The event to signal.
      *
      */
-    void Signal(otChangedFlags aFlags);
+    void Signal(Event aEvent);
 
     /**
-     * This method schedules signaling of changed flags only if the set of flags has not been signaled before (first
-     * time signal).
+     * This method schedules signaling of am event only if the event has not been signaled before (first time signal).
      *
-     * @param[in]  aFlags       A bit-field indicating what configuration or state has changed.
+     * @param[in]  aEvent     The event to signal.
      *
      */
-    void SignalIfFirst(otChangedFlags aFlags);
+    void SignalIfFirst(Event aFlags);
 
     /**
-     * This method indicates whether or not a changed callback is pending.
+     * This method indicates whether or not an event signal callback is pending/scheduled.
      *
-     * @returns TRUE if a state changed callback is pending, FALSE otherwise.
+     * @returns TRUE if a callback is pending, FALSE otherwise.
      *
      */
-    bool IsPending(void) const { return (mFlagsToSignal != 0); }
+    bool IsPending(void) const { return !mEventsToSignal.IsEmpty(); }
 
     /**
-     * This method indicates whether or not a changed notification for a given set of flags has been signaled before.
+     * This method indicates whether or not an event has been signaled before.
      *
-     * @param[in]  aFlags   A bit-field containing the flag-bits to check.
+     * @param[in]  aEvent    The event to check.
      *
-     * @retval TRUE    All flag bits in @p aFlags have been signaled before.
-     * @retval FALSE   At least one flag bit in @p aFlags has not been signaled before.
+     * @retval TRUE    The event @p aEvent have been signaled before.
+     * @retval FALSE   The event @p aEvent has not been signaled before.
      *
      */
-    bool HasSignaled(otChangedFlags aFlags) const { return (mSignaledFlags & aFlags) == aFlags; }
+    bool HasSignaled(Event aEvent) const { return mSignaledEvents.Contains(aEvent); }
 
     /**
-     * This template method updates a variable of a type `Type` with a new value and signals the given changed flags.
+     * This template method updates a variable of a type `Type` with a new value and signals the given event.
      *
-     * If the variable is already set to the same value, this method returns `OT_ERROR_ALREADY` and the changed flags
-     * is signaled using `SignalIfFirst()` (i.e. signal is scheduled only if the flag has not been signaled before).
+     * If the variable is already set to the same value, this method returns `OT_ERROR_ALREADY` and the event is
+     * signaled using `SignalIfFirst()` (i.e., signal is scheduled only if event has not been signaled before).
      *
      * The template `Type` should support comparison operator `==` and assignment operator `=`.
      *
      * @param[inout] aVariable    A reference to the variable to update.
      * @param[in]    aNewValue    The new value.
-     * @param[in]    aFlags       The changed flags to signal.
+     * @param[in]    aEvent       The event to signal.
      *
-     * @retval OT_ERROR_NONE      The variable was update successfully and @p aFlags was signaled.
+     * @retval OT_ERROR_NONE      The variable was update successfully and @p aEvent was signaled.
      * @retval OT_ERROR_ALREADY   The variable was already set to the same value.
      *
      */
-    template <typename Type> otError Update(Type &aVariable, const Type &aNewValue, otChangedFlags aFlags)
+    template <typename Type> otError Update(Type &aVariable, const Type &aNewValue, Event aEvent)
     {
         otError error = OT_ERROR_NONE;
 
         if (aVariable == aNewValue)
         {
-            SignalIfFirst(aFlags);
+            SignalIfFirst(aEvent);
             error = OT_ERROR_ALREADY;
         }
         else
         {
             aVariable = aNewValue;
-            Signal(aFlags);
+            Signal(aEvent);
         }
 
         return error;
@@ -227,17 +348,17 @@
         void *                 mContext;
     };
 
-    void        RegisterCallback(Callback &aCallback);
-    static void HandleStateChanged(Tasklet &aTasklet);
-    void        HandleStateChanged(void);
+    void        RegisterReceiver(Receiver &aReceiver);
+    static void EmitEvents(Tasklet &aTasklet);
+    void        EmitEvents(void);
 
-    void        LogChangedFlags(otChangedFlags aFlags) const;
-    const char *FlagToString(otChangedFlags aFlag) const;
+    void        LogEvents(Events aEvents) const;
+    const char *EventToString(Event aEvent) const;
 
-    otChangedFlags       mFlagsToSignal;
-    otChangedFlags       mSignaledFlags;
+    Events               mEventsToSignal;
+    Events               mSignaledEvents;
     Tasklet              mTask;
-    LinkedList<Callback> mCallbacks;
+    LinkedList<Receiver> mReceivers;
     ExternalCallback     mExternalCallbacks[kMaxExternalHandlers];
 };
 
diff --git a/src/core/common/pool.hpp b/src/core/common/pool.hpp
new file mode 100644
index 0000000..e2c4007
--- /dev/null
+++ b/src/core/common/pool.hpp
@@ -0,0 +1,185 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for a generic object pool.
+ */
+
+#ifndef POOL_HPP_
+#define POOL_HPP_
+
+#include "openthread-core-config.h"
+
+#include "common/linked_list.hpp"
+#include "common/non_copyable.hpp"
+
+namespace ot {
+
+class Instance;
+
+/**
+ * @addtogroup core-pool
+ *
+ * @brief
+ *   This module includes definitions for OpenThread object pool.
+ *
+ * @{
+ *
+ */
+
+/**
+ * This template class represents an object pool.
+ *
+ * @tparam Type         The object type. Type should provide `GetNext() and `SetNext()` so that it can be added to a
+ *                      linked list.
+ * @tparam kPoolSize    Specifies the pool size (maximum number of objects in the pool).
+ *
+ */
+template <class Type, uint16_t kPoolSize> class Pool : private NonCopyable
+{
+public:
+    /**
+     * This constructor initializes the pool.
+     *
+     */
+    Pool(void)
+        : mFreeList()
+    {
+        for (Type &entry : mPool)
+        {
+            mFreeList.Push(entry);
+        }
+    }
+
+    /**
+     * This constructor initializes the pool.
+     *
+     * This constructor version requires the `Type` class to provide method `void Init(Instance &)` to initialize
+     * each `Type` entry object. This can be realized by the `Type` class inheriting from `InstaceLocatorInit()`.
+     *
+     * @param[in] aInstance   A reference to the OpenThread instance.
+     *
+     */
+    Pool(Instance &aInstance)
+        : mFreeList()
+    {
+        for (Type &entry : mPool)
+        {
+            entry.Init(aInstance);
+            mFreeList.Push(entry);
+        }
+    }
+
+    /**
+     * This method allocates a new object from the pool.
+     *
+     * @returns A pointer to the newly allocated object, or nullptr if all entries from the pool are already allocated.
+     *
+     */
+    Type *Allocate(void) { return mFreeList.Pop(); }
+
+    /**
+     * This method frees a previously allocated object.
+     *
+     * The @p aEntry MUST be an entry from the pool previously allocated using `Allocate()` method and not yet freed.
+     * An already freed entry MUST not be freed again.
+     *
+     * @param[in]  aEntry   The pool object entry to free.
+     *
+     */
+    void Free(Type &aEntry) { mFreeList.Push(aEntry); }
+
+    /**
+     * This method returns the pool size.
+     *
+     * @returns The pool size (maximum number of objects in the pool).
+     *
+     */
+    uint16_t GetSize(void) const { return kPoolSize; }
+
+    /**
+     * This method indicates whether or not a given `Type` object is from the pool.
+     *
+     * @param[in]  aObject   A reference to a `Type` object.
+     *
+     * @retval TRUE if @p aObject is from the pool.
+     * @retval FALSE if @p aObject is not from the pool.
+     *
+     */
+    bool IsPoolEntry(const Type &aObject) const { return (&mPool[0] <= &aObject) && (&aObject < OT_ARRAY_END(mPool)); }
+
+    /**
+     * This method returns the associated index of a given entry from the pool.
+     *
+     * The @p aEntry MUST be from the pool, otherwise the behavior of this method is undefined.
+     *
+     * @param[in] aEntry  A reference to an entry from the pool.
+     *
+     * @returns The associated index of @p aEntry.
+     *
+     */
+    uint16_t GetIndexOf(const Type &aEntry) const { return static_cast<uint16_t>(&aEntry - mPool); }
+
+    /**
+     * This method retrieves a pool entry at a given index.
+     *
+     * The @p aIndex MUST be from an earlier call to `GetIndexOf()`.
+     *
+     * @param[in] aIndex  An index.
+     *
+     * @returns A reference to entry at index @p aIndex.
+     *
+     */
+    Type &GetEntryAt(uint16_t aIndex) { return mPool[aIndex]; }
+
+    /**
+     * This method retrieves a pool entry at a given index.
+     *
+     * The @p aIndex MUST be from an earlier call to `GetIndexOf()`.
+     *
+     * @param[in] aIndex  An index.
+     *
+     * @returns A reference to entry at index @p aIndex.
+     *
+     */
+    const Type &GetEntryAt(uint16_t aIndex) const { return mPool[aIndex]; }
+
+private:
+    LinkedList<Type> mFreeList;
+    Type             mPool[kPoolSize];
+};
+
+/**
+ * @}
+ *
+ */
+
+} // namespace ot
+
+#endif // POOL_HPP_
diff --git a/src/core/common/random.hpp b/src/core/common/random.hpp
index 3fadb92..3ddc1af 100644
--- a/src/core/common/random.hpp
+++ b/src/core/common/random.hpp
@@ -90,7 +90,7 @@
  */
 inline uint8_t GetUint8InRange(uint8_t aMin, uint8_t aMax)
 {
-    assert(aMax > aMin);
+    OT_ASSERT(aMax > aMin);
     return (aMin + (GetUint8() % (aMax - aMin)));
 }
 
@@ -106,7 +106,7 @@
  */
 inline uint16_t GetUint16InRange(uint16_t aMin, uint16_t aMax)
 {
-    assert(aMax > aMin);
+    OT_ASSERT(aMax > aMin);
     return (aMin + (GetUint16() % (aMax - aMin)));
 }
 
@@ -123,7 +123,7 @@
  */
 inline uint32_t GetUint32InRange(uint32_t aMin, uint32_t aMax)
 {
-    assert(aMax > aMin);
+    OT_ASSERT(aMax > aMin);
     return (aMin + (GetUint32() % (aMax - aMin)));
 }
 
diff --git a/src/core/common/random_manager.cpp b/src/core/common/random_manager.cpp
index 128fe6a..2ffd082 100644
--- a/src/core/common/random_manager.cpp
+++ b/src/core/common/random_manager.cpp
@@ -59,19 +59,21 @@
     uint32_t seed;
     otError  error;
 
-    assert(sInitCount < 0xffff);
+    OT_UNUSED_VARIABLE(error);
 
-    VerifyOrExit(sInitCount == 0);
+    OT_ASSERT(sInitCount < 0xffff);
+
+    VerifyOrExit(sInitCount == 0, OT_NOOP);
 
 #if !OPENTHREAD_RADIO
     sEntropy.Init();
     sCtrDrbg.Init();
 
     error = Random::Crypto::FillBuffer(reinterpret_cast<uint8_t *>(&seed), sizeof(seed));
-    assert(error == OT_ERROR_NONE);
+    OT_ASSERT(error == OT_ERROR_NONE);
 #else
     error = otPlatEntropyGet(reinterpret_cast<uint8_t *>(&seed), sizeof(seed));
-    assert(error == OT_ERROR_NONE);
+    OT_ASSERT(error == OT_ERROR_NONE);
 #endif
 
     sPrng.Init(seed);
@@ -82,10 +84,10 @@
 
 RandomManager::~RandomManager(void)
 {
-    assert(sInitCount > 0);
+    OT_ASSERT(sInitCount > 0);
 
     sInitCount--;
-    VerifyOrExit(sInitCount == 0);
+    VerifyOrExit(sInitCount == 0, OT_NOOP);
 
 #if !OPENTHREAD_RADIO
     sCtrDrbg.Deinit();
@@ -98,7 +100,7 @@
 
 uint32_t RandomManager::NonCryptoGetUint32(void)
 {
-    assert(sInitCount > 0);
+    OT_ASSERT(sInitCount > 0);
 
     return sPrng.GetNext();
 }
@@ -151,7 +153,7 @@
     mbedtls_entropy_init(&mEntropyContext);
 
 #ifndef OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
-    mbedtls_entropy_add_source(&mEntropyContext, &RandomManager::Entropy::HandleMbedtlsEntropyPoll, NULL,
+    mbedtls_entropy_add_source(&mEntropyContext, &RandomManager::Entropy::HandleMbedtlsEntropyPoll, nullptr,
                                MBEDTLS_ENTROPY_MIN_HARDWARE, MBEDTLS_ENTROPY_SOURCE_STRONG);
 #endif // OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
 }
@@ -173,7 +175,7 @@
     SuccessOrExit(otPlatEntropyGet(reinterpret_cast<uint8_t *>(aOutput), static_cast<uint16_t>(aInLen)));
     rval = 0;
 
-    VerifyOrExit(aOutLen != NULL);
+    VerifyOrExit(aOutLen != nullptr, OT_NOOP);
     *aOutLen = aInLen;
 
 exit:
@@ -189,7 +191,7 @@
 void RandomManager::CryptoCtrDrbg::Init(void)
 {
     mbedtls_ctr_drbg_init(&mCtrDrbg);
-    mbedtls_ctr_drbg_seed(&mCtrDrbg, mbedtls_entropy_func, RandomManager::GetMbedTlsEntropyContext(), NULL, 0);
+    mbedtls_ctr_drbg_seed(&mCtrDrbg, mbedtls_entropy_func, RandomManager::GetMbedTlsEntropyContext(), nullptr, 0);
 }
 
 void RandomManager::CryptoCtrDrbg::Deinit(void)
diff --git a/src/core/common/random_manager.hpp b/src/core/common/random_manager.hpp
index ea11bdb..7106033 100644
--- a/src/core/common/random_manager.hpp
+++ b/src/core/common/random_manager.hpp
@@ -44,6 +44,8 @@
 #include <mbedtls/entropy.h>
 #endif
 
+#include "common/non_copyable.hpp"
+
 #if (!defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \
      (!defined(MBEDTLS_NO_PLATFORM_ENTROPY) || defined(MBEDTLS_HAVEGE_C) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT)))
 #define OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
@@ -55,7 +57,7 @@
  * This class manages random number generator initialization/deinitialization.
  *
  */
-class RandomManager
+class RandomManager : private NonCopyable
 {
 public:
     /**
diff --git a/src/core/common/settings.cpp b/src/core/common/settings.cpp
index 9956d91..8f6d5c7 100644
--- a/src/core/common/settings.cpp
+++ b/src/core/common/settings.cpp
@@ -37,6 +37,7 @@
 
 #include "common/code_utils.hpp"
 #include "common/instance.hpp"
+#include "common/locator-getters.hpp"
 #include "common/logging.hpp"
 #include "meshcop/dataset.hpp"
 #include "thread/mle.hpp"
@@ -50,29 +51,37 @@
 
 void SettingsBase::LogNetworkInfo(const char *aAction, const NetworkInfo &aNetworkInfo) const
 {
-    otLogInfoCore("Non-volatile: %s NetworkInfo {rloc:0x%04x, extaddr:%s, role:%s, mode:0x%02x, keyseq:0x%x, ...",
-                  aAction, aNetworkInfo.mRloc16, aNetworkInfo.mExtAddress.ToString().AsCString(),
-                  Mle::Mle::RoleToString(static_cast<otDeviceRole>(aNetworkInfo.mRole)), aNetworkInfo.mDeviceMode,
-                  aNetworkInfo.mKeySequence);
+    otLogInfoCore(
+        "Non-volatile: %s NetworkInfo {rloc:0x%04x, extaddr:%s, role:%s, mode:0x%02x, version:%hu, keyseq:0x%x, ...",
+        aAction, aNetworkInfo.GetRloc16(), aNetworkInfo.GetExtAddress().ToString().AsCString(),
+        Mle::Mle::RoleToString(static_cast<Mle::DeviceRole>(aNetworkInfo.GetRole())), aNetworkInfo.GetDeviceMode(),
+        aNetworkInfo.GetVersion(), aNetworkInfo.GetKeySequence());
 
-    otLogInfoCore("Non-volatile: ... pid:0x%x, mlecntr:0x%x, maccntr:0x%x, mliid:%02x%02x%02x%02x%02x%02x%02x%02x}",
-                  aNetworkInfo.mPreviousPartitionId, aNetworkInfo.mMleFrameCounter, aNetworkInfo.mMacFrameCounter,
-                  aNetworkInfo.mMlIid[0], aNetworkInfo.mMlIid[1], aNetworkInfo.mMlIid[2], aNetworkInfo.mMlIid[3],
-                  aNetworkInfo.mMlIid[4], aNetworkInfo.mMlIid[5], aNetworkInfo.mMlIid[6], aNetworkInfo.mMlIid[7]);
+    otLogInfoCore("Non-volatile: ... pid:0x%x, mlecntr:0x%x, maccntr:0x%x, mliid:%s}",
+                  aNetworkInfo.GetPreviousPartitionId(), aNetworkInfo.GetMleFrameCounter(),
+                  aNetworkInfo.GetMacFrameCounter(), aNetworkInfo.GetMeshLocalIid().ToString().AsCString());
 }
 
 void SettingsBase::LogParentInfo(const char *aAction, const ParentInfo &aParentInfo) const
 {
-    otLogInfoCore("Non-volatile: %s ParentInfo {extaddr:%s}", aAction, aParentInfo.mExtAddress.ToString().AsCString());
+    otLogInfoCore("Non-volatile: %s ParentInfo {extaddr:%s, version:%hu}", aAction,
+                  aParentInfo.GetExtAddress().ToString().AsCString(), aParentInfo.GetVersion());
 }
 
 void SettingsBase::LogChildInfo(const char *aAction, const ChildInfo &aChildInfo) const
 {
-    otLogInfoCore("Non-volatile: %s ChildInfo {rloc:0x%04x, extaddr:%s, timeout:%u, mode:0x%02x}", aAction,
-                  aChildInfo.mRloc16, aChildInfo.mExtAddress.ToString().AsCString(), aChildInfo.mTimeout,
-                  aChildInfo.mMode);
+    otLogInfoCore("Non-volatile: %s ChildInfo {rloc:0x%04x, extaddr:%s, timeout:%u, mode:0x%02x, version:%hu}", aAction,
+                  aChildInfo.GetRloc16(), aChildInfo.GetExtAddress().ToString().AsCString(), aChildInfo.GetTimeout(),
+                  aChildInfo.GetMode(), aChildInfo.GetVersion());
 }
 
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+void SettingsBase::LogDadInfo(const char *aAction, const DadInfo &aDadInfo) const
+{
+    otLogInfoCore("Non-volatile: %s DadInfo {DadCounter:%2d}", aAction, aDadInfo.GetDadCounter());
+}
+#endif
+
 #endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO)
 
 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN)
@@ -90,19 +99,105 @@
 
 // LCOV_EXCL_STOP
 
-void Settings::Init(void)
+#if !OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+
+SettingsDriver::SettingsDriver(Instance &aInstance)
+    : InstanceLocator(aInstance)
+{
+}
+
+void SettingsDriver::Init(void)
 {
     otPlatSettingsInit(&GetInstance());
 }
 
-void Settings::Deinit(void)
+void SettingsDriver::Deinit(void)
 {
     otPlatSettingsDeinit(&GetInstance());
 }
 
-void Settings::Wipe(void)
+otError SettingsDriver::Add(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    return otPlatSettingsAdd(&GetInstance(), aKey, aValue, aValueLength);
+}
+
+otError SettingsDriver::Delete(uint16_t aKey, int aIndex)
+{
+    return otPlatSettingsDelete(&GetInstance(), aKey, aIndex);
+}
+
+otError SettingsDriver::Get(uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) const
+{
+    return otPlatSettingsGet(&GetInstance(), aKey, aIndex, aValue, aValueLength);
+}
+
+otError SettingsDriver::Set(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    return otPlatSettingsSet(&GetInstance(), aKey, aValue, aValueLength);
+}
+
+void SettingsDriver::Wipe(void)
 {
     otPlatSettingsWipe(&GetInstance());
+}
+
+#else // !OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+
+SettingsDriver::SettingsDriver(Instance &aInstance)
+    : InstanceLocator(aInstance)
+    , mFlash(aInstance)
+{
+}
+
+void SettingsDriver::Init(void)
+{
+    mFlash.Init();
+}
+
+void SettingsDriver::Deinit(void)
+{
+}
+
+otError SettingsDriver::Add(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    return mFlash.Add(aKey, aValue, aValueLength);
+}
+
+otError SettingsDriver::Delete(uint16_t aKey, int aIndex)
+{
+    return mFlash.Delete(aKey, aIndex);
+}
+
+otError SettingsDriver::Get(uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) const
+{
+    return mFlash.Get(aKey, aIndex, aValue, aValueLength);
+}
+
+otError SettingsDriver::Set(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    return mFlash.Set(aKey, aValue, aValueLength);
+}
+
+void SettingsDriver::Wipe(void)
+{
+    mFlash.Wipe();
+}
+
+#endif // !OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+
+void Settings::Init(void)
+{
+    Get<SettingsDriver>().Init();
+}
+
+void Settings::Deinit(void)
+{
+    Get<SettingsDriver>().Deinit();
+}
+
+void Settings::Wipe(void)
+{
+    Get<SettingsDriver>().Wipe();
     otLogInfoCore("Non-volatile: Wiped all info");
 }
 
@@ -116,11 +211,12 @@
 
 otError Settings::ReadOperationalDataset(bool aIsActive, MeshCoP::Dataset &aDataset) const
 {
-    otError  error = OT_ERROR_NONE;
-    uint16_t length;
+    otError  error  = OT_ERROR_NONE;
+    uint16_t length = MeshCoP::Dataset::kMaxSize;
 
-    SuccessOrExit(error = Read(aIsActive ? kKeyActiveDataset : kKeyPendingDataset, aDataset.GetBytes(),
-                               MeshCoP::Dataset::kMaxSize, length));
+    SuccessOrExit(error = Read(aIsActive ? kKeyActiveDataset : kKeyPendingDataset, aDataset.GetBytes(), length));
+    VerifyOrExit(length <= MeshCoP::Dataset::kMaxSize, error = OT_ERROR_NOT_FOUND);
+
     aDataset.SetSize(length);
 
 exit:
@@ -138,9 +234,11 @@
 
 otError Settings::ReadNetworkInfo(NetworkInfo &aNetworkInfo) const
 {
-    otError error;
+    otError  error;
+    uint16_t length = sizeof(NetworkInfo);
 
-    SuccessOrExit(error = ReadFixedSize(kKeyNetworkInfo, &aNetworkInfo, sizeof(NetworkInfo)));
+    aNetworkInfo.Init();
+    SuccessOrExit(error = Read(kKeyNetworkInfo, &aNetworkInfo, length));
     LogNetworkInfo("Read", aNetworkInfo);
 
 exit:
@@ -151,8 +249,9 @@
 {
     otError     error = OT_ERROR_NONE;
     NetworkInfo prevNetworkInfo;
+    uint16_t    length = sizeof(prevNetworkInfo);
 
-    if ((ReadFixedSize(kKeyNetworkInfo, &prevNetworkInfo, sizeof(NetworkInfo)) == OT_ERROR_NONE) &&
+    if ((Read(kKeyNetworkInfo, &prevNetworkInfo, length) == OT_ERROR_NONE) && (length == sizeof(NetworkInfo)) &&
         (memcmp(&prevNetworkInfo, &aNetworkInfo, sizeof(NetworkInfo)) == 0))
     {
         LogNetworkInfo("Re-saved", aNetworkInfo);
@@ -181,9 +280,11 @@
 
 otError Settings::ReadParentInfo(ParentInfo &aParentInfo) const
 {
-    otError error;
+    otError  error;
+    uint16_t length = sizeof(ParentInfo);
 
-    SuccessOrExit(error = ReadFixedSize(kKeyParentInfo, &aParentInfo, sizeof(ParentInfo)));
+    aParentInfo.Init();
+    SuccessOrExit(error = Read(kKeyParentInfo, &aParentInfo, length));
     LogParentInfo("Read", aParentInfo);
 
 exit:
@@ -194,8 +295,9 @@
 {
     otError    error = OT_ERROR_NONE;
     ParentInfo prevParentInfo;
+    uint16_t   length = sizeof(ParentInfo);
 
-    if ((ReadFixedSize(kKeyParentInfo, &prevParentInfo, sizeof(ParentInfo)) == OT_ERROR_NONE) &&
+    if ((Read(kKeyParentInfo, &prevParentInfo, length) == OT_ERROR_NONE) && (length == sizeof(ParentInfo)) &&
         (memcmp(&prevParentInfo, &aParentInfo, sizeof(ParentInfo)) == 0))
     {
         LogParentInfo("Re-saved", aParentInfo);
@@ -275,7 +377,7 @@
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(!mIsDone, error = OT_ERROR_INVALID_STATE);
-    SuccessOrExit(error = otPlatSettingsDelete(&GetInstance(), kKeyChildInfo, mIndex));
+    SuccessOrExit(error = Get<SettingsDriver>().Delete(kKeyChildInfo, mIndex));
     LogChildInfo("Removed", mChildInfo);
 
 exit:
@@ -285,55 +387,84 @@
 
 void Settings::ChildInfoIterator::Read(void)
 {
-    uint16_t size = sizeof(ChildInfo);
+    uint16_t length = sizeof(ChildInfo);
     otError  error;
 
-    SuccessOrExit(error = otPlatSettingsGet(&GetInstance(), kKeyChildInfo, mIndex,
-                                            reinterpret_cast<uint8_t *>(&mChildInfo), &size));
-    VerifyOrExit(size >= sizeof(ChildInfo), error = OT_ERROR_NOT_FOUND);
+    mChildInfo.Init();
+    SuccessOrExit(
+        error = Get<SettingsDriver>().Get(kKeyChildInfo, mIndex, reinterpret_cast<uint8_t *>(&mChildInfo), &length));
     LogChildInfo("Read", mChildInfo);
 
 exit:
     mIsDone = (error != OT_ERROR_NONE);
 }
 
-otError Settings::ReadFixedSize(Key aKey, void *aBuffer, uint16_t aExpectedSize) const
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+otError Settings::ReadDadInfo(DadInfo &aDadInfo) const
 {
-    uint16_t size = aExpectedSize;
     otError  error;
+    uint16_t length = sizeof(DadInfo);
 
-    SuccessOrExit(error = otPlatSettingsGet(&GetInstance(), aKey, 0, reinterpret_cast<uint8_t *>(aBuffer), &size));
-    VerifyOrExit(size >= aExpectedSize, error = OT_ERROR_NOT_FOUND);
+    aDadInfo.Init();
+    SuccessOrExit(error = Read(kKeyDadInfo, &aDadInfo, length));
+    LogDadInfo("Read", aDadInfo);
 
 exit:
     return error;
 }
 
-otError Settings::Read(Key aKey, void *aBuffer, uint16_t aMaxBufferSize, uint16_t &aReadSize) const
+otError Settings::SaveDadInfo(const DadInfo &aDadInfo)
 {
-    uint16_t size = aMaxBufferSize;
-    otError  error;
+    otError  error = OT_ERROR_NONE;
+    DadInfo  prevDadInfo;
+    uint16_t length = sizeof(DadInfo);
 
-    SuccessOrExit(error = otPlatSettingsGet(&GetInstance(), aKey, 0, reinterpret_cast<uint8_t *>(aBuffer), &size));
-    aReadSize = (size <= aMaxBufferSize) ? size : aMaxBufferSize;
+    if ((Read(kKeyDadInfo, &prevDadInfo, length) == OT_ERROR_NONE) && (length == sizeof(DadInfo)) &&
+        (memcmp(&prevDadInfo, &aDadInfo, sizeof(DadInfo)) == 0))
+    {
+        LogDadInfo("Re-saved", aDadInfo);
+        ExitNow();
+    }
+
+    SuccessOrExit(error = Save(kKeyDadInfo, &aDadInfo, sizeof(DadInfo)));
+    LogDadInfo("Saved", aDadInfo);
 
 exit:
+    LogFailure(error, "saving DadInfo", false);
     return error;
 }
 
+otError Settings::DeleteDadInfo(void)
+{
+    otError error;
+
+    SuccessOrExit(error = Delete(kKeyDadInfo));
+    otLogInfoCore("Non-volatile: Deleted DadInfo");
+
+exit:
+    LogFailure(error, "deleting DadInfo", true);
+    return error;
+}
+#endif // OPENTHREAD_CONFIG_DUA_ENABLE
+
+otError Settings::Read(Key aKey, void *aBuffer, uint16_t &aSize) const
+{
+    return Get<SettingsDriver>().Get(aKey, 0, reinterpret_cast<uint8_t *>(aBuffer), &aSize);
+}
+
 otError Settings::Save(Key aKey, const void *aValue, uint16_t aSize)
 {
-    return otPlatSettingsSet(&GetInstance(), aKey, reinterpret_cast<const uint8_t *>(aValue), aSize);
+    return Get<SettingsDriver>().Set(aKey, reinterpret_cast<const uint8_t *>(aValue), aSize);
 }
 
 otError Settings::Add(Key aKey, const void *aValue, uint16_t aSize)
 {
-    return otPlatSettingsAdd(&GetInstance(), aKey, reinterpret_cast<const uint8_t *>(aValue), aSize);
+    return Get<SettingsDriver>().Add(aKey, reinterpret_cast<const uint8_t *>(aValue), aSize);
 }
 
 otError Settings::Delete(Key aKey)
 {
-    return otPlatSettingsDelete(&GetInstance(), aKey, -1);
+    return Get<SettingsDriver>().Delete(aKey, -1);
 }
 
 } // namespace ot
diff --git a/src/core/common/settings.hpp b/src/core/common/settings.hpp
index ae9e406..ed151d3 100644
--- a/src/core/common/settings.hpp
+++ b/src/core/common/settings.hpp
@@ -36,8 +36,12 @@
 
 #include "openthread-core-config.h"
 
+#include "common/encoding.hpp"
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 #include "mac/mac_types.hpp"
+#include "net/ip6_address.hpp"
+#include "utils/flash.hpp"
 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
 #include "utils/slaac_address.hpp"
 #endif
@@ -48,13 +52,108 @@
 class Dataset;
 }
 
+class SettingsDriver : public InstanceLocator, private NonCopyable
+{
+public:
+    /**
+     * Constructor.
+     */
+    explicit SettingsDriver(Instance &aInstance);
+
+    /**
+     * This method initializes the settings storage driver.
+     *
+     */
+    void Init(void);
+
+    /**
+     * This method deinitializes the settings driver.
+     *
+     */
+    void Deinit(void);
+
+    /**
+     * This method adds a value to @p aKey.
+     *
+     * @param[in]  aKey          The key associated with the value.
+     * @param[in]  aValue        A pointer to where the new value of the setting should be read from.
+     *                           MUST NOT be nullptr if @p aValueLength is non-zero.
+     * @param[in]  aValueLength  The length of the data pointed to by @p aValue. May be zero.
+     *
+     * @retval OT_ERROR_NONE     The value was added.
+     * @retval OT_ERROR_NO_BUFS  Not enough space to store the value.
+     *
+     */
+    otError Add(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
+
+    /**
+     * This method removes a value from @p aKey.
+     *
+     * @param[in] aKey    The key associated with the value.
+     * @param[in] aIndex  The index of the value to be removed.
+     *                    If set to -1, all values for @p aKey will be removed.
+     *
+     * @retval OT_ERROR_NONE       The given key and index was found and removed successfully.
+     * @retval OT_ERROR_NOT_FOUND  The given key or index was not found.
+     *
+     */
+    otError Delete(uint16_t aKey, int aIndex);
+
+    /**
+     * This method fetches the value identified by @p aKey.
+     *
+     * @param[in]     aKey          The key associated with the requested value.
+     * @param[in]     aIndex        The index of the specific item to get.
+     * @param[out]    aValue        A pointer to where the value of the setting should be written.
+     *                              May be nullptr if just testing for the presence or length of a key.
+     * @param[inout]  aValueLength  A pointer to the length of the value.
+     *                              When called, this should point to an integer containing the maximum bytes that
+     *                              can be written to @p aValue.
+     *                              At return, the actual length of the setting is written.
+     *                              May be nullptr if performing a presence check.
+     *
+     * @retval OT_ERROR_NONE        The value was fetched successfully.
+     * @retval OT_ERROR_NOT_FOUND   The key was not found.
+     *
+     */
+    otError Get(uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) const;
+
+    /**
+     * This method sets or replaces the value identified by @p aKey.
+     *
+     * If there was more than one value previously associated with @p aKey, then they are all deleted and replaced with
+     * this single entry.
+     *
+     * @param[in]  aKey          The key associated with the value.
+     * @param[in]  aValue        A pointer to where the new value of the setting should be read from.
+     *                           MUST NOT be nullptr if @p aValueLength is non-zero.
+     * @param[in]  aValueLength  The length of the data pointed to by @p aValue. May be zero.
+     *
+     * @retval OT_ERROR_NONE     The value was changed.
+     * @retval OT_ERROR_NO_BUFS  Not enough space to store the value.
+     *
+     */
+    otError Set(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
+
+    /**
+     * This method remves all values.
+     *
+     */
+    void Wipe(void);
+
+#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+private:
+    Flash mFlash;
+#endif
+};
+
 /**
  * This class defines the base class used by `Settings` and `Settings::ChildInfoIterator`.
  *
  * This class provides structure definitions for different settings keys.
  *
  */
-class SettingsBase : public InstanceLocator
+class SettingsBase : public InstanceLocator, private NonCopyable
 {
 public:
     /**
@@ -83,57 +182,396 @@
      * This structure represents the device's own network information for settings storage.
      *
      */
-    struct NetworkInfo
+    OT_TOOL_PACKED_BEGIN
+    class NetworkInfo
     {
+    public:
         /**
          * This method clears the struct object (setting all the fields to zero).
          *
          */
-        void Clear(void) { memset(this, 0, sizeof(*this)); }
+        void Init(void)
+        {
+            memset(this, 0, sizeof(*this));
+            SetVersion(OT_THREAD_VERSION_1_1);
+        }
 
-        uint8_t         mRole;                   ///< Current Thread role.
-        uint8_t         mDeviceMode;             ///< Device mode setting.
-        uint16_t        mRloc16;                 ///< RLOC16
-        uint32_t        mKeySequence;            ///< Key Sequence
-        uint32_t        mMleFrameCounter;        ///< MLE Frame Counter
-        uint32_t        mMacFrameCounter;        ///< MAC Frame Counter
-        uint32_t        mPreviousPartitionId;    ///< PartitionId
-        Mac::ExtAddress mExtAddress;             ///< Extended Address
-        uint8_t         mMlIid[OT_IP6_IID_SIZE]; ///< IID from ML-EID
-    };
+        /**
+         * This method returns the Thread role.
+         *
+         * @returns The Thread role.
+         *
+         */
+        uint8_t GetRole(void) const { return mRole; }
+
+        /**
+         * This method sets the Thread role.
+         *
+         * @param[in] aRole  The Thread Role.
+         *
+         */
+        void SetRole(uint8_t aRole) { mRole = aRole; }
+
+        /**
+         * This method returns the Thread device mode.
+         *
+         * @returns the Thread device mode.
+         *
+         */
+        uint8_t GetDeviceMode(void) const { return mDeviceMode; }
+
+        /**
+         * This method sets the Thread device mode.
+         *
+         * @param[in] aDeviceMode  The Thread device mode.
+         *
+         */
+        void SetDeviceMode(uint8_t aDeviceMode) { mDeviceMode = aDeviceMode; }
+
+        /**
+         * This method returns the RLOC16.
+         *
+         * @returns The RLOC16.
+         *
+         */
+        uint16_t GetRloc16(void) const { return Encoding::LittleEndian::HostSwap16(mRloc16); }
+
+        /**
+         * This method sets the RLOC16.
+         *
+         * @param[in] aRloc16  The RLOC16.
+         *
+         */
+        void SetRloc16(uint16_t aRloc16) { mRloc16 = Encoding::LittleEndian::HostSwap16(aRloc16); }
+
+        /**
+         * This method returns the key sequence.
+         *
+         * @returns The key sequence.
+         *
+         */
+        uint32_t GetKeySequence(void) const { return Encoding::LittleEndian::HostSwap32(mKeySequence); }
+
+        /**
+         * This method sets the key sequence.
+         *
+         * @param[in] aKeySequence  The key sequence.
+         *
+         */
+        void SetKeySequence(uint32_t aKeySequence) { mKeySequence = Encoding::LittleEndian::HostSwap32(aKeySequence); }
+
+        /**
+         * This method returns the MLE frame counter.
+         *
+         * @returns The MLE frame counter.
+         *
+         */
+        uint32_t GetMleFrameCounter(void) const { return Encoding::LittleEndian::HostSwap32(mMleFrameCounter); }
+
+        /**
+         * This method sets the MLE frame counter.
+         *
+         * @param[in] aMleFrameCounter  The MLE frame counter.
+         *
+         */
+        void SetMleFrameCounter(uint32_t aMleFrameCounter)
+        {
+            mMleFrameCounter = Encoding::LittleEndian::HostSwap32(aMleFrameCounter);
+        }
+
+        /**
+         * This method returns the MAC frame counter.
+         *
+         * @returns The MAC frame counter.
+         *
+         */
+        uint32_t GetMacFrameCounter(void) const { return Encoding::LittleEndian::HostSwap32(mMacFrameCounter); }
+
+        /**
+         * This method sets the MAC frame counter.
+         *
+         * @param[in] aMacFrameCounter  The MAC frame counter.
+         *
+         */
+        void SetMacFrameCounter(uint32_t aMacFrameCounter)
+        {
+            mMacFrameCounter = Encoding::LittleEndian::HostSwap32(aMacFrameCounter);
+        }
+
+        /**
+         * This method returns the previous partition ID.
+         *
+         * @returns The previous partition ID.
+         *
+         */
+        uint32_t GetPreviousPartitionId(void) const { return Encoding::LittleEndian::HostSwap32(mPreviousPartitionId); }
+
+        /**
+         * This method sets the previous partition id.
+         *
+         * @param[in] aPreviousPartitionId  The previous partition ID.
+         *
+         */
+        void SetPreviousPartitionId(uint32_t aPreviousPartitionId)
+        {
+            mPreviousPartitionId = Encoding::LittleEndian::HostSwap32(aPreviousPartitionId);
+        }
+
+        /**
+         * This method returns the extended address.
+         *
+         * @returns The extended address.
+         *
+         */
+        const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
+
+        /**
+         * This method sets the extended address.
+         *
+         * @param[in] aExtAddress  The extended address.
+         *
+         */
+        void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
+
+        /**
+         * This method returns the Mesh Local Interface Identifier.
+         *
+         * @returns The Mesh Local Interface Identifier.
+         *
+         */
+        const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMlIid; }
+
+        /**
+         * This method sets the Mesh Local Interface Identifier.
+         *
+         * @param[in] aMeshLocalIid  The Mesh Local Interface Identifier.
+         *
+         */
+        void SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMeshLocalIid) { mMlIid = aMeshLocalIid; }
+
+        /**
+         * This method returns the Thread version.
+         *
+         * @returns The Thread version.
+         *
+         */
+        uint16_t GetVersion(void) const { return Encoding::LittleEndian::HostSwap16(mVersion); }
+
+        /**
+         * This method sets the Thread version.
+         *
+         * @param[in] aVersion  The Thread version.
+         *
+         */
+        void SetVersion(uint16_t aVersion) { mVersion = Encoding::LittleEndian::HostSwap16(aVersion); }
+
+    private:
+        uint8_t                  mRole;                ///< Current Thread role.
+        uint8_t                  mDeviceMode;          ///< Device mode setting.
+        uint16_t                 mRloc16;              ///< RLOC16
+        uint32_t                 mKeySequence;         ///< Key Sequence
+        uint32_t                 mMleFrameCounter;     ///< MLE Frame Counter
+        uint32_t                 mMacFrameCounter;     ///< MAC Frame Counter
+        uint32_t                 mPreviousPartitionId; ///< PartitionId
+        Mac::ExtAddress          mExtAddress;          ///< Extended Address
+        Ip6::InterfaceIdentifier mMlIid;               ///< IID from ML-EID
+        uint16_t                 mVersion;             ///< Version
+    } OT_TOOL_PACKED_END;
 
     /**
      * This structure represents the parent information for settings storage.
      *
      */
-    struct ParentInfo
+    OT_TOOL_PACKED_BEGIN
+    class ParentInfo
     {
+    public:
         /**
          * This method clears the struct object (setting all the fields to zero).
          *
          */
-        void Clear(void) { memset(this, 0, sizeof(*this)); }
+        void Init(void)
+        {
+            memset(this, 0, sizeof(*this));
+            SetVersion(OT_THREAD_VERSION_1_1);
+        }
 
+        /**
+         * This method returns the extended address.
+         *
+         * @returns The extended address.
+         *
+         */
+        const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
+
+        /**
+         * This method sets the extended address.
+         *
+         * @param[in] aExtAddress  The extended address.
+         *
+         */
+        void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
+
+        /**
+         * This method returns the Thread version.
+         *
+         * @returns The Thread version.
+         *
+         */
+        uint16_t GetVersion(void) const { return Encoding::LittleEndian::HostSwap16(mVersion); }
+
+        /**
+         * This method sets the Thread version.
+         *
+         * @param[in] aVersion  The Thread version.
+         *
+         */
+        void SetVersion(uint16_t aVersion) { mVersion = Encoding::LittleEndian::HostSwap16(aVersion); }
+
+    private:
         Mac::ExtAddress mExtAddress; ///< Extended Address
-    };
+        uint16_t        mVersion;    ///< Version
+    } OT_TOOL_PACKED_END;
 
     /**
      * This structure represents the child information for settings storage.
      *
      */
-    struct ChildInfo
+    OT_TOOL_PACKED_BEGIN
+    class ChildInfo
     {
+    public:
         /**
          * This method clears the struct object (setting all the fields to zero).
          *
          */
-        void Clear(void) { memset(this, 0, sizeof(*this)); }
+        void Init(void)
+        {
+            memset(this, 0, sizeof(*this));
+            SetVersion(OT_THREAD_VERSION_1_1);
+        }
 
+        /**
+         * This method returns the extended address.
+         *
+         * @returns The extended address.
+         *
+         */
+        const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
+
+        /**
+         * This method sets the extended address.
+         *
+         * @param[in] aExtAddress  The extended address.
+         *
+         */
+        void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
+
+        /**
+         * This method returns the child timeout.
+         *
+         * @returns The child timeout.
+         *
+         */
+        uint32_t GetTimeout(void) const { return Encoding::LittleEndian::HostSwap32(mTimeout); }
+
+        /**
+         * This method sets the child timeout.
+         *
+         * @param[in] aTimeout  The child timeout.
+         *
+         */
+        void SetTimeout(uint32_t aTimeout) { mTimeout = Encoding::LittleEndian::HostSwap32(aTimeout); }
+
+        /**
+         * This method returns the RLOC16.
+         *
+         * @returns The RLOC16.
+         *
+         */
+        uint16_t GetRloc16(void) const { return Encoding::LittleEndian::HostSwap16(mRloc16); }
+
+        /**
+         * This method sets the RLOC16.
+         *
+         * @param[in] aRloc16  The RLOC16.
+         *
+         */
+        void SetRloc16(uint16_t aRloc16) { mRloc16 = Encoding::LittleEndian::HostSwap16(aRloc16); }
+
+        /**
+         * This method returns the Thread device mode.
+         *
+         * @returns The Thread device mode.
+         *
+         */
+        uint8_t GetMode(void) const { return mMode; }
+
+        /**
+         * This method sets the Thread device mode.
+         *
+         * @param[in] aRloc16  The Thread device mode.
+         *
+         */
+        void SetMode(uint8_t aMode) { mMode = aMode; }
+
+        /**
+         * This method returns the Thread version.
+         *
+         * @returns The Thread version.
+         *
+         */
+        uint16_t GetVersion(void) const { return Encoding::LittleEndian::HostSwap16(mVersion); }
+
+        /**
+         * This method sets the Thread version.
+         *
+         * @param[in] aVersion  The Thread version.
+         *
+         */
+        void SetVersion(uint16_t aVersion) { mVersion = Encoding::LittleEndian::HostSwap16(aVersion); }
+
+    private:
         Mac::ExtAddress mExtAddress; ///< Extended Address
         uint32_t        mTimeout;    ///< Timeout
         uint16_t        mRloc16;     ///< RLOC16
         uint8_t         mMode;       ///< The MLE device mode
-    };
+        uint16_t        mVersion;    ///< Version
+    } OT_TOOL_PACKED_END;
+
+    /**
+     * This structure represents the duplicate address detection information for settings storage.
+     *
+     */
+    OT_TOOL_PACKED_BEGIN
+    class DadInfo
+    {
+    public:
+        /**
+         * This method clears the struct object (setting all the fields to zero).
+         *
+         */
+        void Init(void) { memset(this, 0, sizeof(*this)); }
+
+        /**
+         * This method returns the Dad Counter.
+         *
+         * @returns The Dad Counter value.
+         *
+         */
+        uint8_t GetDadCounter(void) const { return mDadCounter; }
+
+        /**
+         * This method sets the Dad Counter.
+         *
+         * @param[in] aDadCounter The Dad Counter value.
+         *
+         */
+        void SetDadCounter(uint8_t aDadCounter) { mDadCounter = aDadCounter; }
+
+    private:
+        uint8_t mDadCounter; ///< Dad Counter used to resolve address conflict in Thread 1.2 DUA feature.
+    } OT_TOOL_PACKED_END;
 
     /**
      * This enumeration defines the keys of settings.
@@ -148,6 +586,7 @@
         kKeyChildInfo         = 0x0005, ///< Child information
         kKeyReserved          = 0x0006, ///< Reserved (previously auto-start)
         kKeySlaacIidSecretKey = 0x0007, ///< Secret key used by SLAAC module for generating semantically opaque IID
+        kKeyDadInfo           = 0x0008, ///< Duplicate Address Detection (DAD) information.
     };
 
 protected:
@@ -160,11 +599,17 @@
     void LogNetworkInfo(const char *aAction, const NetworkInfo &aNetworkInfo) const;
     void LogParentInfo(const char *aAction, const ParentInfo &aParentInfo) const;
     void LogChildInfo(const char *aAction, const ChildInfo &aChildInfo) const;
-#else
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    void LogDadInfo(const char *aAction, const DadInfo &aDadInfo) const;
+#endif
+#else // (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_UTIL != 0)
     void LogNetworkInfo(const char *, const NetworkInfo &) const {}
     void LogParentInfo(const char *, const ParentInfo &) const {}
     void LogChildInfo(const char *, const ChildInfo &) const {}
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    void LogDadInfo(const char *, const DadInfo &) const {}
 #endif
+#endif // (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_UTIL != 0)
 
 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN) && (OPENTHREAD_CONFIG_LOG_UTIL != 0)
     void LogFailure(otError aError, const char *aAction, bool aIsDelete) const;
@@ -341,7 +786,9 @@
      */
     otError ReadSlaacIidSecretKey(Utils::Slaac::IidSecretKey &aKey)
     {
-        return ReadFixedSize(kKeySlaacIidSecretKey, &aKey, sizeof(Utils::Slaac::IidSecretKey));
+        uint16_t length = sizeof(aKey);
+
+        return Read(kKeySlaacIidSecretKey, &aKey, length);
     }
 
     /**
@@ -455,13 +902,48 @@
         void Read(void);
 
         ChildInfo mChildInfo;
-        uint8_t   mIndex;
+        uint16_t  mIndex;
         bool      mIsDone;
     };
 
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+
+    /**
+     * This method saves duplicate address detection information.
+     *
+     * @param[in]   aDadInfo           A reference to a `DadInfo` structure to be saved.
+     *
+     * @retval OT_ERROR_NONE              Successfully saved duplicate address detection information in settings.
+     * @retval OT_ERROR_NOT_IMPLEMENTED   The platform does not implement settings functionality.
+     *
+     */
+    otError SaveDadInfo(const DadInfo &aDadInfo);
+
+    /**
+     * This method reads duplicate address detection information.
+     *
+     * @param[out]   aDadInfo         A reference to a `DadInfo` structure to output the read content.
+     *
+     * @retval OT_ERROR_NONE              Successfully read the duplicate address detection information.
+     * @retval OT_ERROR_NOT_FOUND         No corresponding value in the setting store.
+     * @retval OT_ERROR_NOT_IMPLEMENTED   The platform does not implement settings functionality.
+     *
+     */
+    otError ReadDadInfo(DadInfo &aDadInfo) const;
+
+    /**
+     * This method deletes duplicate address detection information from settings.
+     *
+     * @retval OT_ERROR_NONE             Successfully deleted the value.
+     * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+     *
+     */
+    otError DeleteDadInfo(void);
+
+#endif // OPENTHREAD_CONFIG_DUA_ENABLE
+
 private:
-    otError ReadFixedSize(Key aKey, void *aBuffer, uint16_t aExpectedSize) const;
-    otError Read(Key aKey, void *aBuffer, uint16_t aMaxBufferSize, uint16_t &aReadSize) const;
+    otError Read(Key aKey, void *aBuffer, uint16_t &aSize) const;
     otError Save(Key aKey, const void *aValue, uint16_t aSize);
     otError Add(Key aKey, const void *aValue, uint16_t aSize);
     otError Delete(Key aKey);
diff --git a/src/core/common/string.hpp b/src/core/common/string.hpp
index b7619bf..661272e 100644
--- a/src/core/common/string.hpp
+++ b/src/core/common/string.hpp
@@ -57,12 +57,13 @@
  */
 
 /**
- * This function returns the number of characters that precede the terminating NULL character.
+ * This function returns the number of characters that precede the terminating nullptr character.
  *
  * @param[in] aString      A pointer to the string.
  * @param[in] aMaxLength   The maximum length in bytes.
  *
- * @returns The number of characters that precede the terminating NULL character or @p aMaxLength, whichever is smaller.
+ * @returns The number of characters that precede the terminating nullptr character or @p aMaxLength, whichever is
+ * smaller.
  *
  */
 uint16_t StringLength(const char *aString, uint16_t aMaxLength);
@@ -124,7 +125,7 @@
     {
         va_list args;
         va_start(args, aFormat);
-        Write(mBuffer, kSize, mLength, aFormat, args);
+        IgnoreError(Write(mBuffer, kSize, mLength, aFormat, args));
         va_end(args);
     }
 
@@ -211,6 +212,29 @@
         return error;
     }
 
+    /**
+     * This method appends an array of bytes in hex representation (using "%02x" style) to the `String` object.
+     *
+     * @param[in] aBytes    A pointer to buffer containing the bytes to append.
+     * @param[in] aLength   The length of @p aBytes buffer (in bytes).
+     *
+     * @retval OT_ERROR_NONE           Updated the string successfully.
+     * @retval OT_ERROR_NO_BUFS        String could not fit in the storage.
+     *
+     */
+    otError AppendHexBytes(const uint8_t *aBytes, uint16_t aLength)
+    {
+        otError error = OT_ERROR_NONE;
+
+        while (aLength--)
+        {
+            SuccessOrExit(error = Append("%02x", *aBytes++));
+        }
+
+    exit:
+        return error;
+    }
+
 private:
     uint16_t mLength;
     char     mBuffer[kSize];
diff --git a/src/core/common/tasklet.cpp b/src/core/common/tasklet.cpp
index 3481af9..de8bab9 100644
--- a/src/core/common/tasklet.cpp
+++ b/src/core/common/tasklet.cpp
@@ -45,23 +45,20 @@
     : InstanceLocator(aInstance)
     , OwnerLocator(aOwner)
     , mHandler(aHandler)
-    , mNext(NULL)
+    , mNext(nullptr)
 {
 }
 
-otError Tasklet::Post(void)
+void Tasklet::Post(void)
 {
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(!IsPosted(), error = OT_ERROR_ALREADY);
-    Get<TaskletScheduler>().PostTasklet(*this);
-
-exit:
-    return error;
+    if (!IsPosted())
+    {
+        Get<TaskletScheduler>().PostTasklet(*this);
+    }
 }
 
 TaskletScheduler::TaskletScheduler(void)
-    : mTail(NULL)
+    : mTail(nullptr)
 {
 }
 
@@ -69,7 +66,7 @@
 {
     // Tasklets are saved in a circular singly linked list.
 
-    if (mTail == NULL)
+    if (mTail == nullptr)
     {
         mTail        = &aTasklet;
         mTail->mNext = mTail;
@@ -89,26 +86,26 @@
 
     // This method processes all tasklets queued when this is called. We
     // keep a copy the current list and then clear the main list by
-    // setting `mTail` to NULL. A newly posted tasklet while processing
+    // setting `mTail` to nullptr. A newly posted tasklet while processing
     // the currently queued tasklets will then trigger a call to
     // `otTaskletsSignalPending()`.
 
-    mTail = NULL;
+    mTail = nullptr;
 
-    while (tail != NULL)
+    while (tail != nullptr)
     {
         Tasklet *tasklet = tail->mNext;
 
         if (tasklet == tail)
         {
-            tail = NULL;
+            tail = nullptr;
         }
         else
         {
             tail->mNext = tasklet->mNext;
         }
 
-        tasklet->mNext = NULL;
+        tasklet->mNext = nullptr;
         tasklet->RunTask();
     }
 }
diff --git a/src/core/common/tasklet.hpp b/src/core/common/tasklet.hpp
index f8fb8dd..198858c 100644
--- a/src/core/common/tasklet.hpp
+++ b/src/core/common/tasklet.hpp
@@ -41,6 +41,7 @@
 #include <openthread/tasklet.h>
 
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 
 namespace ot {
 
@@ -66,12 +67,12 @@
 
 public:
     /**
-     * This function pointer is called when the tasklet is run.
+     * This function reference is called when the tasklet is run.
      *
      * @param[in]  aTasklet  A reference to the tasklet being run.
      *
      */
-    typedef void (*Handler)(Tasklet &aTasklet);
+    typedef void (&Handler)(Tasklet &aTasklet);
 
     /**
      * This constructor creates a tasklet instance.
@@ -86,8 +87,10 @@
     /**
      * This method puts the tasklet on the tasklet scheduler run queue.
      *
+     * If the tasklet is already posted, no change is made and run queue stays as before.
+     *
      */
-    otError Post(void);
+    void Post(void);
 
     /**
      * This method indicates whether the tasklet is posted or not.
@@ -96,7 +99,7 @@
      * @retval FALSE The tasklet is not posted.
      *
      */
-    bool IsPosted(void) const { return (mNext != NULL); }
+    bool IsPosted(void) const { return (mNext != nullptr); }
 
 private:
     void RunTask(void) { mHandler(*this); }
@@ -147,7 +150,7 @@
  * This class implements the tasklet scheduler.
  *
  */
-class TaskletScheduler
+class TaskletScheduler : private NonCopyable
 {
     friend class Tasklet;
 
@@ -165,7 +168,7 @@
      * @retval FALSE  If there are no tasklets pending.
      *
      */
-    bool AreTaskletsPending(void) const { return mTail != NULL; }
+    bool AreTaskletsPending(void) const { return mTail != nullptr; }
 
     /**
      * This method processes all tasklets queued when this is called.
diff --git a/src/core/common/timer.cpp b/src/core/common/timer.cpp
index 3dda583..2a0ad2f 100644
--- a/src/core/common/timer.cpp
+++ b/src/core/common/timer.cpp
@@ -75,7 +75,7 @@
 
 void TimerMilli::StartAt(TimeMilli aStartTime, uint32_t aDelay)
 {
-    assert(aDelay <= kMaxDelay);
+    OT_ASSERT(aDelay <= kMaxDelay);
     FireAt(aStartTime + aDelay);
 }
 
@@ -100,7 +100,7 @@
 
 void TimerScheduler::Add(Timer &aTimer, const AlarmApi &aAlarmApi)
 {
-    Timer *prev = NULL;
+    Timer *prev = nullptr;
     Time   now(aAlarmApi.AlarmGetNow());
 
     Remove(aTimer, aAlarmApi);
@@ -113,7 +113,7 @@
         }
     }
 
-    if (prev == NULL)
+    if (prev == nullptr)
     {
         mTimerList.Push(aTimer);
         SetAlarm(aAlarmApi);
@@ -126,7 +126,7 @@
 
 void TimerScheduler::Remove(Timer &aTimer, const AlarmApi &aAlarmApi)
 {
-    VerifyOrExit(aTimer.IsRunning());
+    VerifyOrExit(aTimer.IsRunning(), OT_NOOP);
 
     if (mTimerList.GetHead() == &aTimer)
     {
@@ -135,7 +135,7 @@
     }
     else
     {
-        mTimerList.Remove(aTimer);
+        IgnoreError(mTimerList.Remove(aTimer));
     }
 
     aTimer.SetNext(&aTimer);
@@ -188,7 +188,7 @@
 {
     Instance *instance = static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(otInstanceIsInitialized(aInstance));
+    VerifyOrExit(otInstanceIsInitialized(aInstance), OT_NOOP);
     instance->Get<TimerMilliScheduler>().ProcessTimers();
 
 exit:
@@ -205,7 +205,7 @@
 
 void TimerMicro::StartAt(TimeMicro aStartTime, uint32_t aDelay)
 {
-    assert(aDelay <= kMaxDelay);
+    OT_ASSERT(aDelay <= kMaxDelay);
     FireAt(aStartTime + aDelay);
 }
 
@@ -224,7 +224,7 @@
 {
     Instance *instance = static_cast<Instance *>(aInstance);
 
-    VerifyOrExit(otInstanceIsInitialized(aInstance));
+    VerifyOrExit(otInstanceIsInitialized(aInstance), OT_NOOP);
     instance->Get<TimerMicroScheduler>().ProcessTimers();
 
 exit:
diff --git a/src/core/common/timer.hpp b/src/core/common/timer.hpp
index 1b899a9..d60c5bd 100644
--- a/src/core/common/timer.hpp
+++ b/src/core/common/timer.hpp
@@ -45,6 +45,7 @@
 #include "common/debug.hpp"
 #include "common/linked_list.hpp"
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 #include "common/tasklet.hpp"
 #include "common/time.hpp"
 
@@ -79,12 +80,12 @@
     static const uint32_t kMaxDelay = (Time::kMaxDuration >> 1);
 
     /**
-     * This function pointer is called when the timer expires.
+     * This type defines a function reference which is invoked when the timer expires.
      *
      * @param[in]  aTimer    A reference to the expired timer instance.
      *
      */
-    typedef void (*Handler)(Timer &aTimer);
+    typedef void (&Handler)(Timer &aTimer);
 
     /**
      * This constructor creates a timer instance.
@@ -251,7 +252,7 @@
  * This class implements the base timer scheduler.
  *
  */
-class TimerScheduler : public InstanceLocator
+class TimerScheduler : public InstanceLocator, private NonCopyable
 {
     friend class Timer;
 
diff --git a/src/core/common/tlvs.cpp b/src/core/common/tlvs.cpp
index 3a79f33..447c347 100644
--- a/src/core/common/tlvs.cpp
+++ b/src/core/common/tlvs.cpp
@@ -37,6 +37,9 @@
 #include "common/debug.hpp"
 #include "common/message.hpp"
 
+using ot::Encoding::BigEndian::HostSwap16;
+using ot::Encoding::BigEndian::HostSwap32;
+
 namespace ot {
 
 uint32_t Tlv::GetSize(void) const
@@ -55,13 +58,22 @@
     return reinterpret_cast<const uint8_t *>(this) + (IsExtended() ? sizeof(ExtendedTlv) : sizeof(Tlv));
 }
 
-otError Tlv::Get(const Message &aMessage, uint8_t aType, uint16_t aMaxSize, Tlv &aTlv)
+otError Tlv::AppendTo(Message &aMessage) const
+{
+    uint32_t size = GetSize();
+
+    // OT_ASSERT(size <= UINT16_MAX);
+
+    return aMessage.Append(this, static_cast<uint16_t>(size));
+}
+
+otError Tlv::FindTlv(const Message &aMessage, uint8_t aType, uint16_t aMaxSize, Tlv &aTlv)
 {
     otError  error;
     uint16_t offset;
     uint16_t size;
 
-    SuccessOrExit(error = Find(aMessage, aType, &offset, &size, NULL));
+    SuccessOrExit(error = Find(aMessage, aType, &offset, &size, nullptr));
 
     if (aMaxSize > size)
     {
@@ -74,12 +86,12 @@
     return error;
 }
 
-otError Tlv::GetOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset)
+otError Tlv::FindTlvOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset)
 {
-    return Find(aMessage, aType, &aOffset, NULL, NULL);
+    return Find(aMessage, aType, &aOffset, nullptr, nullptr);
 }
 
-otError Tlv::GetValueOffset(const Message &aMessage, uint8_t aType, uint16_t &aValueOffset, uint16_t &aLength)
+otError Tlv::FindTlvValueOffset(const Message &aMessage, uint8_t aType, uint16_t &aValueOffset, uint16_t &aLength)
 {
     otError  error;
     uint16_t offset;
@@ -111,12 +123,12 @@
     Tlv      tlv;
     uint32_t size;
 
-    VerifyOrExit(offset <= remainingLen);
+    VerifyOrExit(offset <= remainingLen, OT_NOOP);
     remainingLen -= offset;
 
     while (true)
     {
-        VerifyOrExit(sizeof(Tlv) <= remainingLen);
+        VerifyOrExit(sizeof(Tlv) <= remainingLen, OT_NOOP);
         aMessage.Read(offset, sizeof(Tlv), &tlv);
 
         if (tlv.mLength != kExtendedLength)
@@ -127,28 +139,28 @@
         {
             ExtendedTlv extTlv;
 
-            VerifyOrExit(sizeof(ExtendedTlv) <= remainingLen);
+            VerifyOrExit(sizeof(ExtendedTlv) <= remainingLen, OT_NOOP);
             aMessage.Read(offset, sizeof(ExtendedTlv), &extTlv);
 
-            VerifyOrExit(extTlv.GetLength() <= (remainingLen - sizeof(ExtendedTlv)));
+            VerifyOrExit(extTlv.GetLength() <= (remainingLen - sizeof(ExtendedTlv)), OT_NOOP);
             size = extTlv.GetSize();
         }
 
-        VerifyOrExit(size <= remainingLen);
+        VerifyOrExit(size <= remainingLen, OT_NOOP);
 
         if (tlv.GetType() == aType)
         {
-            if (aOffset != NULL)
+            if (aOffset != nullptr)
             {
                 *aOffset = offset;
             }
 
-            if (aSize != NULL)
+            if (aSize != nullptr)
             {
                 *aSize = static_cast<uint16_t>(size);
             }
 
-            if (aIsExtendedTlv != NULL)
+            if (aIsExtendedTlv != nullptr)
             {
                 *aIsExtendedTlv = (tlv.mLength == kExtendedLength);
             }
@@ -165,13 +177,135 @@
     return error;
 }
 
-otError Tlv::AppendTo(Message &aMessage) const
+otError Tlv::ReadUint8Tlv(const Message &aMessage, uint16_t aOffset, uint8_t &aValue)
 {
-    uint32_t size = GetSize();
+    return ReadTlv(aMessage, aOffset, &aValue, sizeof(uint8_t));
+}
 
-    assert(size <= UINT16_MAX);
+otError Tlv::ReadUint16Tlv(const Message &aMessage, uint16_t aOffset, uint16_t &aValue)
+{
+    otError error;
 
-    return aMessage.Append(this, static_cast<uint16_t>(size));
+    SuccessOrExit(error = ReadTlv(aMessage, aOffset, &aValue, sizeof(uint16_t)));
+    aValue = HostSwap16(aValue);
+
+exit:
+    return error;
+}
+
+otError Tlv::ReadUint32Tlv(const Message &aMessage, uint16_t aOffset, uint32_t &aValue)
+{
+    otError error;
+
+    SuccessOrExit(error = ReadTlv(aMessage, aOffset, &aValue, sizeof(uint32_t)));
+    aValue = HostSwap32(aValue);
+
+exit:
+    return error;
+}
+
+otError Tlv::ReadTlv(const Message &aMessage, uint16_t aOffset, void *aValue, uint8_t aLength)
+{
+    otError error = OT_ERROR_NONE;
+    Tlv     tlv;
+
+    VerifyOrExit(aMessage.Read(aOffset, sizeof(Tlv), &tlv) == sizeof(Tlv), error = OT_ERROR_PARSE);
+    VerifyOrExit(!tlv.IsExtended() && (tlv.GetLength() >= aLength), error = OT_ERROR_PARSE);
+    VerifyOrExit(tlv.GetSize() + aOffset <= aMessage.GetLength(), error = OT_ERROR_PARSE);
+
+    aMessage.Read(aOffset + sizeof(Tlv), aLength, aValue);
+
+exit:
+    return error;
+}
+
+otError Tlv::FindUint8Tlv(const Message &aMessage, uint8_t aType, uint8_t &aValue)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t offset;
+
+    SuccessOrExit(error = FindTlvOffset(aMessage, aType, offset));
+    error = ReadUint8Tlv(aMessage, offset, aValue);
+
+exit:
+    return error;
+}
+
+otError Tlv::FindUint16Tlv(const Message &aMessage, uint8_t aType, uint16_t &aValue)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t offset;
+
+    SuccessOrExit(error = FindTlvOffset(aMessage, aType, offset));
+    error = ReadUint16Tlv(aMessage, offset, aValue);
+
+exit:
+    return error;
+}
+
+otError Tlv::FindUint32Tlv(const Message &aMessage, uint8_t aType, uint32_t &aValue)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t offset;
+
+    SuccessOrExit(error = FindTlvOffset(aMessage, aType, offset));
+    error = ReadUint32Tlv(aMessage, offset, aValue);
+
+exit:
+    return error;
+}
+
+otError Tlv::FindTlv(const Message &aMessage, uint8_t aType, void *aValue, uint8_t aLength)
+{
+    otError  error;
+    uint16_t offset;
+    uint16_t length;
+
+    SuccessOrExit(error = FindTlvValueOffset(aMessage, aType, offset, length));
+    VerifyOrExit(length >= aLength, error = OT_ERROR_PARSE);
+    aMessage.Read(offset, aLength, static_cast<uint8_t *>(aValue));
+
+exit:
+    return error;
+}
+
+otError Tlv::AppendUint8Tlv(Message &aMessage, uint8_t aType, uint8_t aValue)
+{
+    uint8_t value8 = aValue;
+
+    return AppendTlv(aMessage, aType, &value8, sizeof(uint8_t));
+}
+
+otError Tlv::AppendUint16Tlv(Message &aMessage, uint8_t aType, uint16_t aValue)
+{
+    uint16_t value16 = HostSwap16(aValue);
+
+    return AppendTlv(aMessage, aType, &value16, sizeof(uint16_t));
+}
+
+otError Tlv::AppendUint32Tlv(Message &aMessage, uint8_t aType, uint32_t aValue)
+{
+    uint32_t value32 = HostSwap32(aValue);
+
+    return AppendTlv(aMessage, aType, &value32, sizeof(uint32_t));
+}
+
+otError Tlv::AppendTlv(Message &aMessage, uint8_t aType, const void *aValue, uint8_t aLength)
+{
+    otError error = OT_ERROR_NONE;
+    Tlv     tlv;
+
+    OT_ASSERT(aLength <= Tlv::kBaseTlvMaxLength);
+
+    tlv.SetType(aType);
+    tlv.SetLength(aLength);
+    SuccessOrExit(error = aMessage.Append(&tlv, sizeof(tlv)));
+
+    VerifyOrExit(aLength > 0, OT_NOOP);
+    error = aMessage.Append(aValue, aLength);
+
+exit:
+    return error;
 }
 
 } // namespace ot
diff --git a/src/core/common/tlvs.hpp b/src/core/common/tlvs.hpp
index 0931929..8fe2cd4 100644
--- a/src/core/common/tlvs.hpp
+++ b/src/core/common/tlvs.hpp
@@ -37,6 +37,7 @@
 #include "openthread-core-config.h"
 
 #include <openthread/error.h>
+#include <openthread/thread.h>
 #include <openthread/platform/toolchain.h>
 
 #include "common/encoding.hpp"
@@ -44,7 +45,6 @@
 namespace ot {
 
 using ot::Encoding::BigEndian::HostSwap16;
-using ot::Encoding::BigEndian::HostSwap32;
 
 class Message;
 
@@ -62,7 +62,7 @@
      */
     enum
     {
-        kBaseTlvMaxLength = 254, ///< The maximum length of the Base TLV format.
+        kBaseTlvMaxLength = OT_NETWORK_BASE_TLV_MAX_LENGTH, ///< The maximum length of the Base TLV format.
     };
 
     /**
@@ -164,6 +164,72 @@
     }
 
     /**
+     * This method appends a TLV to the end of the message.
+     *
+     * On success, this method grows the message by the size of the TLV.
+     *
+     * @param[in]  aMessage      A reference to the message to append to.
+     *
+     * @retval OT_ERROR_NONE     Successfully appended the TLV to the message.
+     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
+     *
+     */
+    otError AppendTo(Message &aMessage) const;
+
+    /**
+     * This static method reads a TLV from a message at a given offset with TLV's value as an `uint8_t`.
+     *
+     * @param[in]   aMessage  The message to read from.
+     * @param[in]   aOffset   The offset into the message pointing to the start of the TLV.
+     * @param[out]  aValue    A reference to a `uint8_t` to output the TLV's value.
+     *
+     * @retval OT_ERROR_NONE        Successfully read the TLV and updated @p aValue.
+     * @retval OT_ERROR_PARSE       The TLV was not well-formed and could not be parsed.
+     *
+     */
+    static otError ReadUint8Tlv(const Message &aMessage, uint16_t aOffset, uint8_t &aValue);
+
+    /**
+     * This static method reads a TLV from a message at a given offset with TLV's value as an `uint16_t`.
+     *
+     * @param[in]   aMessage  The message to read from.
+     * @param[in]   aOffset   The offset into the message pointing to the start of the TLV.
+     * @param[out]  aValue    A reference to a `uint16_t` to output the TLV's value.
+     *
+     * @retval OT_ERROR_NONE        Successfully read the TLV and updated @p aValue.
+     * @retval OT_ERROR_PARSE       The TLV was not well-formed and could not be parsed.
+     *
+     */
+    static otError ReadUint16Tlv(const Message &aMessage, uint16_t aOffset, uint16_t &aValue);
+
+    /**
+     * This static method reads a TLV from a message at a given offset with TLV's value as an `uint32_t`.
+     *
+     * @param[in]   aMessage  The message to read from.
+     * @param[in]   aOffset   The offset into the message pointing to the start of the TLV.
+     * @param[out]  aValue    A reference to a `uint32_t` to output the TLV's value.
+     *
+     * @retval OT_ERROR_NONE        Successfully read the TLV and updated @p aValue.
+     * @retval OT_ERROR_PARSE       The TLV was not well-formed and could not be parsed.
+     *
+     */
+    static otError ReadUint32Tlv(const Message &aMessage, uint16_t aOffset, uint32_t &aValue);
+
+    /**
+     * This static method reads a TLV in a message at a given offset expecting a minimum length for the value.
+     *
+     * @param[in]   aMessage    The message to read from.
+     * @param[in]   aOffset     The offset into the message pointing to the start of the TLV.
+     * @param[out]  aValue      A buffer to output the TLV's value, must contain (at least) @p aMinLength bytes.
+     * @param[in]   aMinLength  The minimum expected length of TLV and number of bytes to copy into @p aValue buffer.
+     *
+     * @retval OT_ERROR_NONE        Successfully read the TLV and copied @p aMinLength into @p aValue.
+     * @retval OT_ERROR_PARSE       The TLV was not well-formed and could not be parsed.
+     *
+     */
+    static otError ReadTlv(const Message &aMessage, uint16_t aOffset, void *aValue, uint8_t aMinLength);
+
+    /**
      * This static method reads the requested TLV out of @p aMessage.
      *
      * This method can be used independent of whether the read TLV (from message) is an Extended TLV or not.
@@ -177,7 +243,7 @@
      * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
      *
      */
-    static otError Get(const Message &aMessage, uint8_t aType, uint16_t aMaxSize, Tlv &aTlv);
+    static otError FindTlv(const Message &aMessage, uint8_t aType, uint16_t aMaxSize, Tlv &aTlv);
 
     /**
      * This static method obtains the offset of a TLV within @p aMessage.
@@ -192,7 +258,7 @@
      * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
      *
      */
-    static otError GetOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset);
+    static otError FindTlvOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset);
 
     /**
      * This static method finds the offset and length of a given TLV type.
@@ -208,20 +274,132 @@
      * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
      *
      */
-    static otError GetValueOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset, uint16_t &aLength);
+    static otError FindTlvValueOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset, uint16_t &aLength);
 
     /**
-     * This method appends a TLV to the end of the message.
+     * This static method searches for a TLV with a given type in a message and reads its value as an `uint8_t`.
      *
-     * On success, this method grows the message by the size of the TLV.
+     * @param[in]   aMessage        A reference to the message.
+     * @param[in]   aType           The TLV type to search for.
+     * @param[out]  aValue          A reference to a `uint8_t` to output the TLV's value.
+     *
+     * @retval OT_ERROR_NONE        Successfully found the TLV and updated @p aValue.
+     * @retval OT_ERROR_NOT_FOUND   Could not find the TLV with Type @p aType.
+     * @retval OT_ERROR_PARSE       TLV was found but it was not well-formed and could not be parsed.
+     *
+     */
+    static otError FindUint8Tlv(const Message &aMessage, uint8_t aType, uint8_t &aValue);
+
+    /**
+     * This static method searches for a TLV with a given type in a message and reads its value as an `uint16_t`.
+     *
+     * @param[in]   aMessage        A reference to the message.
+     * @param[in]   aType           The TLV type to search for.
+     * @param[out]  aValue          A reference to a `uint16_t` to output the TLV's value.
+     *
+     * @retval OT_ERROR_NONE        Successfully found the TLV and updated @p aValue.
+     * @retval OT_ERROR_NOT_FOUND   Could not find the TLV with Type @p aType.
+     * @retval OT_ERROR_PARSE       TLV was found but it was not well-formed and could not be parsed.
+     *
+     */
+    static otError FindUint16Tlv(const Message &aMessage, uint8_t aType, uint16_t &aValue);
+
+    /**
+     * This static method searches for a TLV with a given type in a message and reads its value as an `uint32_t`.
+     *
+     * @param[in]   aMessage        A reference to the message.
+     * @param[in]   aType           The TLV type to search for.
+     * @param[out]  aValue          A reference to a `uint32_t` to output the TLV's value.
+     *
+     * @retval OT_ERROR_NONE        Successfully found the TLV and updated @p aValue.
+     * @retval OT_ERROR_NOT_FOUND   Could not find the TLV with Type @p aType.
+     * @retval OT_ERROR_PARSE       TLV was found but it was not well-formed and could not be parsed.
+     *
+     */
+    static otError FindUint32Tlv(const Message &aMessage, uint8_t aType, uint32_t &aValue);
+
+    /**
+     * This static method searches for a TLV with a given type in a message, ensures its length is same or larger than
+     * an expected minimum value, and then reads its value into a given buffer.
+     *
+     * If the TLV length is smaller than the minimum length @p aLength, the TLV is considered invalid. In this case,
+     * this method returns `OT_ERROR_PARSE` and the @p aValue buffer is not updated.
+     *
+     * If the TLV length is larger than @p aLength, the TLV is considered valid, but only the first @p aLength bytes
+     * of the value are read and copied into the @p aValue buffer.
+     *
+     * @param[in]    aMessage    A reference to the message.
+     * @param[in]    aType       The TLV type to search for.
+     * @param[out]   aValue      A buffer to output the value (must contain at least @p aLength bytes).
+     * @param[in]    aLength     The expected (minimum) length of the TLV value.
+     *
+     * @retval OT_ERROR_NONE       The TLV was found and read successfully. @p aValue is updated.
+     * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
+     * @retval OT_ERROR_PARSE      TLV was found but it was not well-formed and could not be parsed.
+     *
+     */
+    static otError FindTlv(const Message &aMessage, uint8_t aType, void *aValue, uint8_t aLength);
+
+    /**
+     * This static method appends a simple TLV with a given type and an `uint8_t` value to a message.
+     *
+     * On success this method grows the message by the size of the TLV.
      *
      * @param[in]  aMessage      A reference to the message to append to.
+     * @param[in]  aType         The TLV type.
+     * @param[in]  aValue        The TLV value (`uint8_t`).
      *
      * @retval OT_ERROR_NONE     Successfully appended the TLV to the message.
      * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
      *
      */
-    otError AppendTo(Message &aMessage) const;
+    static otError AppendUint8Tlv(Message &aMessage, uint8_t aType, uint8_t aValue);
+
+    /**
+     * This static method appends a simple TLV with a given type and an `uint16_t` value to a message.
+     *
+     * On success this method grows the message by the size of the TLV.
+     *
+     * @param[in]  aMessage      A reference to the message to append to.
+     * @param[in]  aType         The TLV type.
+     * @param[in]  aValue        The TLV value (`uint16_t`).
+     *
+     * @retval OT_ERROR_NONE     Successfully appended the TLV to the message.
+     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
+     *
+     */
+    static otError AppendUint16Tlv(Message &aMessage, uint8_t aType, uint16_t aValue);
+
+    /**
+     * This static method appends a (simple) TLV with a given type and an `uint32_t` value to a message.
+     *
+     * On success this method grows the message by the size of the TLV.
+     *
+     * @param[in]  aMessage      A reference to the message to append to.
+     * @param[in]  aType         The TLV type.
+     * @param[in]  aValue        The TLV value (`uint32_t`).
+     *
+     * @retval OT_ERROR_NONE     Successfully appended the TLV to the message.
+     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
+     *
+     */
+    static otError AppendUint32Tlv(Message &aMessage, uint8_t aType, uint32_t aValue);
+
+    /**
+     * This static method appends a TLV with a given type and value to a message.
+     *
+     * On success this method grows the message by the size of the TLV.
+     *
+     * @param[in]  aMessage      A reference to the message to append to.
+     * @param[in]  aType         The TLV type.
+     * @param[in]  aValue        A buffer containing the TLV value.
+     * @param[in]  aLength       The value length (in bytes).
+     *
+     * @retval OT_ERROR_NONE     Successfully appended the TLV to the message.
+     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
+     *
+     */
+    static otError AppendTlv(Message &aMessage, uint8_t aType, const void *aValue, uint8_t aLength);
 
 protected:
     enum
@@ -234,7 +412,7 @@
      * This private static method searches within a given message for TLV type and outputs the TLV offset, size and
      * whether it is an Extended TLV.
      *
-     * A NULL pointer can be used for output parameters @p aOffset, @p aSize, or @p aIsExtendedTlv if the parameter
+     * A nullptr pointer can be used for output parameters @p aOffset, @p aSize, or @p aIsExtendedTlv if the parameter
      * is not required.
      *
      * @param[in]   aMessage       A reference to the message to search within.
diff --git a/src/core/common/trickle_timer.cpp b/src/core/common/trickle_timer.cpp
index e81d738..cbfb2ee 100644
--- a/src/core/common/trickle_timer.cpp
+++ b/src/core/common/trickle_timer.cpp
@@ -46,7 +46,7 @@
                            Handler aTransmitHandler,
                            Handler aIntervalExpiredHandler,
                            void *  aOwner)
-    : TimerMilli(aInstance, &TrickleTimer::HandleTimer, aOwner)
+    : TimerMilli(aInstance, TrickleTimer::HandleTimer, aOwner)
 #ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
     , mRedundancyConstant(aRedundancyConstant)
     , mCounter(0)
@@ -61,15 +61,13 @@
     , mIsRunning(false)
     , mInTransmitPhase(false)
 {
-    assert(aTransmitHandler != NULL);
+    OT_ASSERT(aTransmitHandler != nullptr);
 }
 
-otError TrickleTimer::Start(uint32_t aIntervalMin, uint32_t aIntervalMax, Mode aMode)
+void TrickleTimer::Start(uint32_t aIntervalMin, uint32_t aIntervalMax, Mode aMode)
 {
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(aIntervalMax >= aIntervalMin, error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit(aIntervalMin != 0 || aIntervalMax != 0, error = OT_ERROR_INVALID_ARGS);
+    OT_ASSERT(aIntervalMax >= aIntervalMin);
+    OT_ASSERT(aIntervalMin != 0 || aIntervalMax != 0);
 
     mIntervalMin = aIntervalMin;
     mIntervalMax = aIntervalMax;
@@ -80,9 +78,6 @@
     mInterval = Random::NonCrypto::GetUint32InRange(mIntervalMin, mIntervalMax + 1);
 
     StartNewInterval();
-
-exit:
-    return error;
 }
 
 void TrickleTimer::Stop(void)
@@ -95,7 +90,7 @@
 {
     // If interval is equal to minimum when an "inconsistent" event
     // is received, do nothing.
-    VerifyOrExit(mIsRunning && (mInterval != mIntervalMin));
+    VerifyOrExit(mIsRunning && (mInterval != mIntervalMin), OT_NOOP);
 
     mInterval = mIntervalMin;
     StartNewInterval();
diff --git a/src/core/common/trickle_timer.hpp b/src/core/common/trickle_timer.hpp
index 6a13dcf..e8ed1d0 100644
--- a/src/core/common/trickle_timer.hpp
+++ b/src/core/common/trickle_timer.hpp
@@ -113,11 +113,8 @@
      * @param[in]  aIntervalMax  The maximum interval for the timer in milliseconds.
      * @param[in]  aMode         The operating mode for the timer.
      *
-     * @retval OT_ERROR_NONE           The timer started successfully.
-     * @retval OT_ERROR_INVALID_ARGS   The given parameters are invalid (i.e., max interval is smaller than min).
-     *
      */
-    otError Start(uint32_t aIntervalMin, uint32_t aIntervalMax, Mode aMode);
+    void Start(uint32_t aIntervalMin, uint32_t aIntervalMax, Mode aMode);
 
     /**
      * This method stops the trickle timer.
diff --git a/src/core/config/backbone_router.h b/src/core/config/backbone_router.h
new file mode 100644
index 0000000..204e3f4
--- /dev/null
+++ b/src/core/config/backbone_router.h
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes compile-time configurations for Backbone Router services.
+ *
+ */
+
+#ifndef CONFIG_BACKBONE_ROUTER_H_
+#define CONFIG_BACKBONE_ROUTER_H_
+
+/**
+ * @def OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+ *
+ * Define to 1 to enable Backbone Router support.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+#define OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 0
+#endif
+
+#endif // CONFIG_BACKBONE_ROUTER_H_
diff --git a/src/core/config/coap.h b/src/core/config/coap.h
index d958c9d..712c57e 100644
--- a/src/core/config/coap.h
+++ b/src/core/config/coap.h
@@ -36,48 +36,6 @@
 #define CONFIG_COAP_H_
 
 /**
- * @def OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT
- *
- * Minimum spacing before first retransmission when ACK is not received (RFC7252 default value is 2).
- *
- */
-#ifndef OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT
-#define OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT 2
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR
- *
- * Numerator of ACK_RANDOM_FACTOR used to calculate maximum spacing before first retransmission when
- * ACK is not received (RFC7252 default value of ACK_RANDOM_FACTOR is 1.5, must not be decreased below 1).
- *
- */
-#ifndef OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR
-#define OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR 3
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR
- *
- * Denominator of ACK_RANDOM_FACTOR used to calculate maximum spacing before first retransmission when
- * ACK is not received (RFC7252 default value of ACK_RANDOM_FACTOR is 1.5, must not be decreased below 1).
- *
- */
-#ifndef OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR
-#define OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR 2
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_COAP_MAX_RETRANSMIT
- *
- * Maximum number of retransmissions for CoAP Confirmable messages (RFC7252 default value is 4).
- *
- */
-#ifndef OPENTHREAD_CONFIG_COAP_MAX_RETRANSMIT
-#define OPENTHREAD_CONFIG_COAP_MAX_RETRANSMIT 4
-#endif
-
-/**
  * @def OPENTHREAD_CONFIG_COAP_SERVER_MAX_CACHED_RESPONSES
  *
  * Maximum number of cached responses for CoAP Confirmable messages.
@@ -100,6 +58,16 @@
 #endif
 
 /**
+ * @def OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+ *
+ * Define to 1 to enable the CoAP Observe (RFC7641) API.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
+#define OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE 0
+#endif
+
+/**
  * @def OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
  *
  * Define to 1 to enable the CoAP Secure API.
diff --git a/src/core/config/ip6.h b/src/core/config/ip6.h
index 56320db..0db4a80 100644
--- a/src/core/config/ip6.h
+++ b/src/core/config/ip6.h
@@ -160,4 +160,21 @@
 #define OPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE 0
 #endif
 
+/**
+ * @def OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE
+ *
+ * Define as 1 to enable dynamic unsecure port management
+ *
+ * If this feature is enabled, OpenThread will automaitically disable link-level
+ * security for packets sent with unsecure source ports. Once we receive a secure
+ * packet sent to the unsecure port, this port will be removed from the unsecure
+ * port list.
+ *
+ * Enable only if you know well about its behavior.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE
+#define OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE 0
+#endif
+
 #endif // CONFIG_IP6_H_
diff --git a/src/core/config/link_raw.h b/src/core/config/link_raw.h
index 1b9dda2..6c2ceeb 100644
--- a/src/core/config/link_raw.h
+++ b/src/core/config/link_raw.h
@@ -45,52 +45,4 @@
 #define OPENTHREAD_CONFIG_LINK_RAW_ENABLE 0
 #endif
 
-/**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
- *
- * Define to 1 to enable software ACK timeout logic.
- *
- * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set).
- *
- */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 0
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
- *
- * Define to 1 to enable software retransmission logic.
- *
- * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set).
- *
- */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 0
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
- *
- * Define to 1 to enable software CSMA-CA backoff logic.
- *
- * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set).
- *
- */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0
-#endif
-
-/**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
- *
- * Define to 1 to enable software energy scanning logic.
- *
- * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set).
- *
- */
-#ifndef OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
-#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 0
-#endif
-
 #endif // CONFIG_LINK_RAW_H_
diff --git a/src/core/config/logging.h b/src/core/config/logging.h
index 5a2bd8e..c8d46ed 100644
--- a/src/core/config/logging.h
+++ b/src/core/config/logging.h
@@ -45,7 +45,6 @@
  * - @sa OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART
  * - @sa OPENTHREAD_CONFIG_LOG_OUTPUT_APP
  * - @sa OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
- * - @sa OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL
  * - and others
  *
  * Note:
@@ -68,8 +67,6 @@
 #define OPENTHREAD_CONFIG_LOG_OUTPUT_APP 2
 /** Log output is handled by a platform defined function */
 #define OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED 3
-/** Log output for NCP goes to Spinel `STREAM_LOG` property (for CLI platform defined function is expected) */
-#define OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL 4
 
 /**
  * @def OPENTHREAD_CONFIG_LOG_LEVEL
@@ -127,6 +124,16 @@
 #endif
 
 /**
+ * @def OPENTHREAD_CONFIG_LOG_MESHCOP
+ *
+ * Define to enable MeshCoP logging.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_MESHCOP
+#define OPENTHREAD_CONFIG_LOG_MESHCOP 1
+#endif
+
+/**
  * @def OPENTHREAD_CONFIG_LOG_ARP
  *
  * Define to enable EID-to-RLOC map logging.
@@ -257,6 +264,30 @@
 #endif
 
 /**
+ * @def OPENTHREAD_CONFIG_LOG_BBR
+ *
+ * Note: available since Thread 1.2.
+ *
+ * Define to enable Backbone Router (BBR) region logging.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_BBR
+#define OPENTHREAD_CONFIG_LOG_BBR 1
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_LOG_MLR
+ *
+ * Note: available since Thread 1.2.
+ *
+ * Define to enable Multicast Listener Registration (MLR) region logging.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_MLR
+#define OPENTHREAD_CONFIG_LOG_MLR 1
+#endif
+
+/**
  * @def OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL
  *
  * Define to prepend the log level to all log messages.
diff --git a/src/core/config/mac.h b/src/core/config/mac.h
index bee1dea..34349db 100644
--- a/src/core/config/mac.h
+++ b/src/core/config/mac.h
@@ -173,16 +173,6 @@
 #endif
 
 /**
- * @def OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT
- *
- * Define as 1 to disable CSMA-CA on the last transmit attempt.
- *
- */
-#ifndef OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT
-#define OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT 0
-#endif
-
-/**
  * @def OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
  *
  * Define as 1 to stay awake between fragments while transmitting a large packet,
@@ -200,7 +190,7 @@
  *
  */
 #ifndef OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION
-#define OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION OPENTHREAD_THREAD_VERSION
+#define OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION OPENTHREAD_CONFIG_THREAD_VERSION
 #endif
 
 /**
@@ -222,12 +212,13 @@
  * Define as 1 to support IEEE 802.15.4-2015 Header IE (Information Element) generation and parsing, it must be set
  * to support following features:
  *    1. Time synchronization service feature (i.e., OPENTHREAD_CONFIG_TIME_SYNC_ENABLE is set).
+ *    2. Thread 1.2.
  *
  * @note If it's enabled, platform must support interrupt context and concurrent access AES.
  *
  */
 #ifndef OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
 #define OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 1
 #else
 #define OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 0
@@ -264,4 +255,75 @@
 #define OPENTHREAD_CONFIG_MAC_RETX_POLL_PERIOD 1000
 #endif
 
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
+ *
+ * Define to 1 to enable software ACK timeout logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
+ *
+ * Define to 1 to enable software retransmission logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
+ *
+ * Define to 1 to enable software CSMA-CA backoff logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 to enable software transmission security logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
+ *
+ * Define to 1 to enable software energy scanning logic.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0
+#endif
+
+/**
+ *
+ * This setting configures the CSL transmitter feature in Thread 1.2.
+ * This is compulsory for 1.2 FTD.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE \
+    (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) && OPENTHREAD_FTD
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+ *
+ * This setting configures the CSL receiver feature in Thread 1.2.
+ * This is compulsory for 1.2 MTD, optional for 1.2 FTD.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+#define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE \
+    (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) && OPENTHREAD_MTD
+#endif
+
 #endif // CONFIG_MAC_H_
diff --git a/src/core/config/openthread-core-config-check.h b/src/core/config/openthread-core-config-check.h
index c553356..dedd88f 100644
--- a/src/core/config/openthread-core-config-check.h
+++ b/src/core/config/openthread-core-config-check.h
@@ -42,6 +42,10 @@
 #error "OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT requires OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE to be also set."
 #endif
 
+#if OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT && OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
+#error "OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT requires DHCPv6 server on Border Router side to be enabled."
+#endif
+
 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
 #error "Dynamic log level is not supported along with multiple OT instance feature"
@@ -59,9 +63,11 @@
  *
  */
 
-#ifdef OPENTHREAD_CONFIG_DISABLE_CCA_ON_LAST_ATTEMPT
+#if defined(OPENTHREAD_CONFIG_DISABLE_CCA_ON_LAST_ATTEMPT) ||     \
+    defined(OPENTHREAD_CONFIG_DISABLE_CSMA_CA_ON_LAST_ATTEMPT) || \
+    defined(OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT)
 #error \
-    "OPENTHREAD_CONFIG_DISABLE_CCA_ON_LAST_ATTEMPT was replaced by OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT."
+    "OPENTHREAD_CONFIG_DISABLE_CCA_ON_LAST_ATTEMPT, OPENTHREAD_CONFIG_DISABLE_CSMA_CA_ON_LAST_ATTEMPT and OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT were removed."
 #endif
 
 #ifdef OPENTHREAD_CONFIG_MAX_TX_ATTEMPTS_DIRECT
@@ -315,19 +321,41 @@
 #endif
 
 #ifdef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT
-#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT was replaced by OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE."
+#error \
+    "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE."
+#endif
+
+#ifdef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
+#error \
+    "OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE."
 #endif
 
 #ifdef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT
-#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT was replaced by OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE."
+#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE."
+#endif
+
+#ifdef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+#error "OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE."
 #endif
 
 #ifdef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF
-#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF was replaced by OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE."
+#error \
+    "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE."
+#endif
+
+#ifdef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+#error \
+    "OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE."
 #endif
 
 #ifdef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN
-#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN was replaced by OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE."
+#error \
+    "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE."
+#endif
+
+#ifdef OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
+#error \
+    "OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE."
 #endif
 
 #ifdef OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
@@ -394,11 +422,6 @@
 #error "OPENTHREAD_CONFIG_ENABLE_DYNAMIC_MPL_INTERVAL was replaced by OPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE."
 #endif
 
-#ifdef OPENTHREAD_CONFIG_DISABLE_CSMA_CA_ON_LAST_ATTEMPT
-#error \
-    "OPENTHREAD_CONFIG_DISABLE_CSMA_CA_ON_LAST_ATTEMPT was replaced by OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT."
-#endif
-
 #ifdef OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES
 #error "OPENTHREAD_CONFIG_ENABLE_LONG_ROUTES was replaced by OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE."
 #endif
@@ -463,4 +486,43 @@
 #error "OPENTHREAD_CONFIG_INITIAL_LOG_LEVEL was replaced by OPENTHREAD_CONFIG_LOG_LEVEL_INIT."
 #endif
 
+#ifdef OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT
+#error \
+    "OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT (in seconds) was replaced by OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT_MILLIS (in milliseconds)"
+#endif
+
+#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+#if (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
+#error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE"
+#endif
+
+#if !OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+#error "OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE is required for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE"
+#endif
+
+#endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+
+#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
+#if (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
+#error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE"
+#endif
+#if (!OPENTHREAD_FTD)
+#error "FTD is required for OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE"
+#endif
+#endif // OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
+
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+#if (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
+#error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE"
+#endif
+#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+
+#if OPENTHREAD_CONFIG_DUA_ENABLE && (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
+#error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_DUA_ENABLE"
+#endif
+
+#ifdef OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL
+#error "OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL is removed, use OPENTHREAD_CONFIG_LOG_OUTPUT_APP instead"
+#endif
+
 #endif // OPENTHREAD_CORE_CONFIG_CHECK_H_
diff --git a/src/core/config/openthread-core-default-config.h b/src/core/config/openthread-core-default-config.h
index c55306d..f9a8423 100644
--- a/src/core/config/openthread-core-default-config.h
+++ b/src/core/config/openthread-core-default-config.h
@@ -108,16 +108,6 @@
 #endif
 
 /**
- * @def OPENTHREAD_ENABLE_POSIX_APP_DAEMON
- *
- * Define to 1 to enable posix-app daemon support.
- *
- */
-#ifndef OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-#define OPENTHREAD_ENABLE_POSIX_APP_DAEMON 0
-#endif
-
-/**
  * @def OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
  *
  * Define to 1 to enable Thread Test Harness reference device support.
@@ -301,6 +291,16 @@
 #endif
 
 /**
+ * @def OPENTHREAD_CONFIG_ASSERT_ENABLE
+ *
+ * Define as 1 to enable assert function `OT_ASSERT()` within OpenThread code and its libraries.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_ASSERT_ENABLE
+#define OPENTHREAD_CONFIG_ASSERT_ENABLE 1
+#endif
+
+/**
  * @def OPENTHREAD_CONFIG_ENABLE_DEBUG_UART
  *
  * Enable the "Debug Uart" platform feature.
@@ -333,6 +333,18 @@
 #endif
 
 /**
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+ *
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
+#endif
+
+/**
  * @def OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS
  *
  * This setting configures the number of consecutive MCPS.DATA-Confirms having Status NO_ACK
@@ -428,4 +440,24 @@
 #define OPENTHREAD_CONFIG_LEGACY_ENABLE 0
 #endif
 
+/**
+ * @def OPENTHREAD_CONFIG_OTNS_ENABLE
+ *
+ * Define to 1 to enable OTNS interactions.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_OTNS_ENABLE
+#define OPENTHREAD_CONFIG_OTNS_ENABLE 0
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_DUA_ENABLE
+ *
+ * Define as 1 to support Thread 1.2 Domain Unicast Address feature.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_DUA_ENABLE
+#define OPENTHREAD_CONFIG_DUA_ENABLE 0
+#endif
+
 #endif // OPENTHREAD_CORE_DEFAULT_CONFIG_H_
diff --git a/src/core/config/tmf.h b/src/core/config/tmf.h
index 37f891b..e1f54c9 100644
--- a/src/core/config/tmf.h
+++ b/src/core/config/tmf.h
@@ -46,6 +46,31 @@
 #endif
 
 /**
+ * @def OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES
+ *
+ * The maximum number of EID-to-RLOC cache entries that can be used for "snoop optimization" where an entry is created
+ * by inspecting a received message.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES
+#define OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES 2
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_TMF_SNOOP_CACHE_ENTRY_TIMEOUT
+ *
+ * The timeout value (in seconds) blocking eviction of an address cache entry created through snoop optimization (i.e.,
+ * inspection of a received message). After the timeout expires the entry can be reclaimed again. This timeout allows
+ * a longer response delay for a received message giving more chance that a snooped entry will be used (avoiding
+ * sending Address Query when a response message is sent to same destination from which the message was received
+ * earlier).
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_TMF_SNOOP_CACHE_ENTRY_TIMEOUT
+#define OPENTHREAD_CONFIG_TMF_SNOOP_CACHE_ENTRY_TIMEOUT 3
+#endif
+
+/**
  * @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT
  *
  * The timeout value (in seconds) waiting for a address notification response after sending an address query.
diff --git a/src/core/crypto/aes_ccm.cpp b/src/core/crypto/aes_ccm.cpp
index 8cea413..a46cba4 100644
--- a/src/core/crypto/aes_ccm.cpp
+++ b/src/core/crypto/aes_ccm.cpp
@@ -33,41 +33,39 @@
 
 #include "aes_ccm.hpp"
 
+#include <limits.h>
+
 #include "common/code_utils.hpp"
 #include "common/debug.hpp"
+#include "common/encoding.hpp"
 
 namespace ot {
 namespace Crypto {
 
 void AesCcm::SetKey(const uint8_t *aKey, uint16_t aKeyLength)
 {
-    mEcb.SetKey(aKey, 8 * aKeyLength);
+    mEcb.SetKey(aKey, CHAR_BIT * aKeyLength);
 }
 
-otError AesCcm::Init(uint32_t    aHeaderLength,
-                     uint32_t    aPlainTextLength,
-                     uint8_t     aTagLength,
-                     const void *aNonce,
-                     uint8_t     aNonceLength)
+void AesCcm::SetKey(const Mac::Key &aMacKey)
+{
+    SetKey(aMacKey.GetKey(), Mac::Key::kSize);
+}
+
+void AesCcm::Init(uint32_t    aHeaderLength,
+                  uint32_t    aPlainTextLength,
+                  uint8_t     aTagLength,
+                  const void *aNonce,
+                  uint8_t     aNonceLength)
 {
     const uint8_t *nonceBytes  = reinterpret_cast<const uint8_t *>(aNonce);
-    otError        error       = OT_ERROR_NONE;
     uint8_t        blockLength = 0;
     uint32_t       len;
     uint8_t        L;
     uint8_t        i;
 
-    // aTagLength must be even
-    aTagLength &= ~1;
-
-    if (aTagLength > sizeof(mBlock))
-    {
-        aTagLength = sizeof(mBlock);
-    }
-    else if (aTagLength < kTagLengthMin)
-    {
-        ExitNow(error = OT_ERROR_INVALID_ARGS);
-    }
+    // Tag length must be even and within [kMinTagLength, kMaxTagLength]
+    OT_ASSERT(((aTagLength & 0x1) == 0) && (kMinTagLength <= aTagLength) && (aTagLength <= kMaxTagLength));
 
     L = 0;
 
@@ -105,10 +103,7 @@
                  static_cast<uint8_t>(L - 1));
 
     // write nonce
-    for (i = 0; i < aNonceLength; i++)
-    {
-        mBlock[1 + i] = nonceBytes[i];
-    }
+    memcpy(&mBlock[1], nonceBytes, aNonceLength);
 
     // write len
     len = aPlainTextLength;
@@ -144,16 +139,8 @@
 
     // init counter
     mCtr[0] = L - 1;
-
-    for (i = 0; i < aNonceLength; i++)
-    {
-        mCtr[1 + i] = nonceBytes[i];
-    }
-
-    for (i = i + 1; i < sizeof(mCtr); i++)
-    {
-        mCtr[i] = 0;
-    }
+    memcpy(&mCtr[1], nonceBytes, aNonceLength);
+    memset(&mCtr[aNonceLength + 1], 0, sizeof(mCtr) - aNonceLength - 1);
 
     mNonceLength     = aNonceLength;
     mHeaderLength    = aHeaderLength;
@@ -163,16 +150,13 @@
     mBlockLength     = blockLength;
     mCtrLength       = sizeof(mCtrPad);
     mTagLength       = aTagLength;
-
-exit:
-    return error;
 }
 
 void AesCcm::Header(const void *aHeader, uint32_t aHeaderLength)
 {
     const uint8_t *headerBytes = reinterpret_cast<const uint8_t *>(aHeader);
 
-    assert(mHeaderCur + aHeaderLength <= mHeaderLength);
+    OT_ASSERT(mHeaderCur + aHeaderLength <= mHeaderLength);
 
     // process header
     for (unsigned i = 0; i < aHeaderLength; i++)
@@ -200,13 +184,13 @@
     }
 }
 
-void AesCcm::Payload(void *aPlainText, void *aCipherText, uint32_t aLength, bool aEncrypt)
+void AesCcm::Payload(void *aPlainText, void *aCipherText, uint32_t aLength, Mode aMode)
 {
     uint8_t *plaintextBytes  = reinterpret_cast<uint8_t *>(aPlainText);
     uint8_t *ciphertextBytes = reinterpret_cast<uint8_t *>(aCipherText);
     uint8_t  byte;
 
-    assert(mPlainTextCur + aLength <= mPlainTextLength);
+    OT_ASSERT(mPlainTextCur + aLength <= mPlainTextLength);
 
     for (unsigned i = 0; i < aLength; i++)
     {
@@ -224,7 +208,7 @@
             mCtrLength = 0;
         }
 
-        if (aEncrypt)
+        if (aMode == kEncrypt)
         {
             byte               = plaintextBytes[i];
             ciphertextBytes[i] = byte ^ mCtrPad[mCtrLength++];
@@ -254,33 +238,36 @@
         }
 
         // reset counter
-        for (uint8_t i = mNonceLength + 1; i < sizeof(mCtr); i++)
-        {
-            mCtr[i] = 0;
-        }
+        memset(&mCtr[mNonceLength + 1], 0, sizeof(mCtr) - mNonceLength - 1);
     }
 }
 
-void AesCcm::Finalize(void *aTag, uint8_t *aTagLength)
+void AesCcm::Finalize(void *aTag)
 {
     uint8_t *tagBytes = reinterpret_cast<uint8_t *>(aTag);
 
-    assert(mPlainTextCur == mPlainTextLength);
+    OT_ASSERT(mPlainTextCur == mPlainTextLength);
 
-    if (mTagLength > 0)
+    mEcb.Encrypt(mCtr, mCtrPad);
+
+    for (int i = 0; i < mTagLength; i++)
     {
-        mEcb.Encrypt(mCtr, mCtrPad);
-
-        for (int i = 0; i < mTagLength; i++)
-        {
-            tagBytes[i] = mBlock[i] ^ mCtrPad[i];
-        }
+        tagBytes[i] = mBlock[i] ^ mCtrPad[i];
     }
+}
 
-    if (aTagLength)
-    {
-        *aTagLength = mTagLength;
-    }
+void AesCcm::GenerateNonce(const Mac::ExtAddress &aAddress,
+                           uint32_t               aFrameCounter,
+                           uint8_t                aSecurityLevel,
+                           uint8_t *              aNonce)
+{
+    memcpy(aNonce, aAddress.m8, sizeof(Mac::ExtAddress));
+    aNonce += sizeof(Mac::ExtAddress);
+
+    Encoding::BigEndian::WriteUint32(aFrameCounter, aNonce);
+    aNonce += sizeof(uint32_t);
+
+    aNonce[0] = aSecurityLevel;
 }
 
 } // namespace Crypto
diff --git a/src/core/crypto/aes_ccm.hpp b/src/core/crypto/aes_ccm.hpp
index ba4099b..9efae0e 100644
--- a/src/core/crypto/aes_ccm.hpp
+++ b/src/core/crypto/aes_ccm.hpp
@@ -41,6 +41,7 @@
 #include <openthread/error.h>
 
 #include "crypto/aes_ecb.hpp"
+#include "mac/mac_types.hpp"
 
 namespace ot {
 namespace Crypto {
@@ -59,6 +60,23 @@
 class AesCcm
 {
 public:
+    enum
+    {
+        kMinTagLength = 4,                  ///< Minimum tag length (in bytes).
+        kMaxTagLength = AesEcb::kBlockSize, ///< Maximum tag length (in bytes).
+        kNonceSize    = 13,                 ///< Size of IEEE 802.15.4 Nonce (in bytes).
+    };
+
+    /**
+     * This enumeration type represent the encryption vs decryption mode.
+     *
+     */
+    enum Mode
+    {
+        kEncrypt, // Encryption mode.
+        kDecrypt, // Decryption mode.
+    };
+
     /**
      * This method sets the key.
      *
@@ -69,23 +87,28 @@
     void SetKey(const uint8_t *aKey, uint16_t aKeyLength);
 
     /**
+     * This method sets the key.
+     *
+     * @param[in]  aMacKey        A MAC key.
+     *
+     */
+    void SetKey(const Mac::Key &aMacKey);
+
+    /**
      * This method initializes the AES CCM computation.
      *
      * @param[in]  aHeaderLength     Length of header in bytes.
      * @param[in]  aPlainTextLength  Length of plaintext in bytes.
-     * @param[in]  aTagLength        Length of tag in bytes.
+     * @param[in]  aTagLength        Length of tag in bytes (must be even and in `[kMinTagLength, kMaxTagLength]`).
      * @param[in]  aNonce            A pointer to the nonce.
      * @param[in]  aNonceLength      Length of nonce in bytes.
      *
-     * @retval OT_ERROR_NONE          Initialization was successful.
-     * @retval OT_ERROR_INVALID_ARGS  Initialization failed.
-     *
      */
-    otError Init(uint32_t    aHeaderLength,
-                 uint32_t    aPlainTextLength,
-                 uint8_t     aTagLength,
-                 const void *aNonce,
-                 uint8_t     aNonceLength);
+    void Init(uint32_t    aHeaderLength,
+              uint32_t    aPlainTextLength,
+              uint8_t     aTagLength,
+              const void *aNonce,
+              uint8_t     aNonceLength);
 
     /**
      * This method processes the header.
@@ -102,37 +125,53 @@
      * @param[inout]  aPlainText   A pointer to the plaintext.
      * @param[inout]  aCipherText  A pointer to the ciphertext.
      * @param[in]     aLength      Payload length in bytes.
-     * @param[in]     aEncrypt     TRUE on encrypt and FALSE on decrypt.
+     * @param[in]     aMode        Mode to indicate whether to encrypt (`kEncrypt`) or decrypt (`kDecrypt`).
      *
      */
-    void Payload(void *aPlainText, void *aCipherText, uint32_t aLength, bool aEncrypt);
+    void Payload(void *aPlainText, void *aCipherText, uint32_t aLength, Mode aMode);
+
+    /**
+     * This method returns the tag length in bytes.
+     *
+     * @returns The tag length in bytes.
+     *
+     */
+    uint8_t GetTagLength(void) const { return mTagLength; }
 
     /**
      * This method generates the tag.
      *
-     * @param[out]  aTag        A pointer to the tag.
-     * @param[out]  aTagLength  Length of the tag in bytes.
+     * @param[out]  aTag        A pointer to the tag (must have `GetTagLength()` bytes).
      *
      */
-    void Finalize(void *aTag, uint8_t *aTagLength);
+    void Finalize(void *aTag);
+
+    /**
+     * This static method generates IEEE 802.15.4 nonce byte sequence.
+     *
+     * @param[in]  aAddress        An extended address.
+     * @param[in]  aFrameCounter   A frame counter.
+     * @param[in]  aSecurityLevel  A security level.
+     * @param[out] aNonce          A buffer (with `kNonceSize` bytes) to place the generated nonce.
+     *
+     */
+    static void GenerateNonce(const Mac::ExtAddress &aAddress,
+                              uint32_t               aFrameCounter,
+                              uint8_t                aSecurityLevel,
+                              uint8_t *              aNonce);
 
 private:
-    enum
-    {
-        kTagLengthMin = 4,
-    };
-
     AesEcb   mEcb;
     uint8_t  mBlock[AesEcb::kBlockSize];
     uint8_t  mCtr[AesEcb::kBlockSize];
     uint8_t  mCtrPad[AesEcb::kBlockSize];
-    uint8_t  mNonceLength;
     uint32_t mHeaderLength;
     uint32_t mHeaderCur;
     uint32_t mPlainTextLength;
     uint32_t mPlainTextCur;
     uint16_t mBlockLength;
     uint16_t mCtrLength;
+    uint8_t  mNonceLength;
     uint8_t  mTagLength;
 };
 
diff --git a/src/core/crypto/aes_ecb.cpp b/src/core/crypto/aes_ecb.cpp
index 2c252a0..77fea90 100644
--- a/src/core/crypto/aes_ecb.cpp
+++ b/src/core/crypto/aes_ecb.cpp
@@ -36,7 +36,7 @@
 namespace ot {
 namespace Crypto {
 
-AesEcb::AesEcb()
+AesEcb::AesEcb(void)
 {
     mbedtls_aes_init(&mContext);
 }
@@ -51,7 +51,7 @@
     mbedtls_aes_crypt_ecb(&mContext, MBEDTLS_AES_ENCRYPT, aInput, aOutput);
 }
 
-AesEcb::~AesEcb()
+AesEcb::~AesEcb(void)
 {
     mbedtls_aes_free(&mContext);
 }
diff --git a/src/core/crypto/aes_ecb.hpp b/src/core/crypto/aes_ecb.hpp
index 1d86ecc..085ccfa 100644
--- a/src/core/crypto/aes_ecb.hpp
+++ b/src/core/crypto/aes_ecb.hpp
@@ -64,19 +64,19 @@
      * Constructor to initialize the mbedtls_aes_context.
      *
      */
-    AesEcb();
+    AesEcb(void);
 
     /**
      * Destructor to free the mbedtls_aes_context.
      *
      */
-    ~AesEcb();
+    ~AesEcb(void);
 
     /**
      * This method sets the key.
      *
      * @param[in]  aKey        A pointer to the key.
-     * @param[in]  aKeyLength  The key length in bytes.
+     * @param[in]  aKeyLength  The key length in bits.
      *
      */
     void SetKey(const uint8_t *aKey, uint16_t aKeyLength);
diff --git a/src/core/crypto/ecdsa.cpp b/src/core/crypto/ecdsa.cpp
index 1d84efd..3b50ee0 100644
--- a/src/core/crypto/ecdsa.cpp
+++ b/src/core/crypto/ecdsa.cpp
@@ -47,7 +47,7 @@
 #if OPENTHREAD_CONFIG_ECDSA_ENABLE
 
 otError Ecdsa::Sign(uint8_t *      aOutput,
-                    uint16_t *     aOutputLength,
+                    uint16_t &     aOutputLength,
                     const uint8_t *aInputHash,
                     uint16_t       aInputHashLength,
                     const uint8_t *aPrivateKey,
@@ -66,12 +66,12 @@
     mbedtls_mpi_init(&sMpi);
 
     // Parse a private key in PEM format.
-    VerifyOrExit(mbedtls_pk_parse_key(&pkCtx, aPrivateKey, aPrivateKeyLength, NULL, 0) == 0,
+    VerifyOrExit(mbedtls_pk_parse_key(&pkCtx, aPrivateKey, aPrivateKeyLength, nullptr, 0) == 0,
                  error = OT_ERROR_INVALID_ARGS);
     VerifyOrExit(mbedtls_pk_get_type(&pkCtx) == MBEDTLS_PK_ECKEY, error = OT_ERROR_INVALID_ARGS);
 
     keypair = mbedtls_pk_ec(pkCtx);
-    assert(keypair != NULL);
+    OT_ASSERT(keypair != nullptr);
 
     VerifyOrExit(mbedtls_ecdsa_from_keypair(&ctx, keypair) == 0, error = OT_ERROR_FAILED);
 
@@ -79,15 +79,15 @@
     VerifyOrExit(mbedtls_ecdsa_sign(&ctx.grp, &rMpi, &sMpi, &ctx.d, aInputHash, aInputHashLength,
                                     mbedtls_ctr_drbg_random, Random::Crypto::MbedTlsContextGet()) == 0,
                  error = OT_ERROR_FAILED);
-    VerifyOrExit(mbedtls_mpi_size(&rMpi) + mbedtls_mpi_size(&sMpi) <= *aOutputLength, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(mbedtls_mpi_size(&rMpi) + mbedtls_mpi_size(&sMpi) <= aOutputLength, error = OT_ERROR_NO_BUFS);
 
     // Concatenate the two octet sequences in the order R and then S.
     VerifyOrExit(mbedtls_mpi_write_binary(&rMpi, aOutput, mbedtls_mpi_size(&rMpi)) == 0, error = OT_ERROR_FAILED);
-    *aOutputLength = static_cast<uint16_t>(mbedtls_mpi_size(&rMpi));
+    aOutputLength = static_cast<uint16_t>(mbedtls_mpi_size(&rMpi));
 
-    VerifyOrExit(mbedtls_mpi_write_binary(&sMpi, aOutput + *aOutputLength, mbedtls_mpi_size(&sMpi)) == 0,
+    VerifyOrExit(mbedtls_mpi_write_binary(&sMpi, aOutput + aOutputLength, mbedtls_mpi_size(&sMpi)) == 0,
                  error = OT_ERROR_FAILED);
-    *aOutputLength += mbedtls_mpi_size(&sMpi);
+    aOutputLength += mbedtls_mpi_size(&sMpi);
 
 exit:
     mbedtls_mpi_free(&rMpi);
diff --git a/src/core/crypto/ecdsa.hpp b/src/core/crypto/ecdsa.hpp
index 0c169ab..2215ab0 100644
--- a/src/core/crypto/ecdsa.hpp
+++ b/src/core/crypto/ecdsa.hpp
@@ -72,9 +72,10 @@
      * @retval  OT_ERROR_NO_BUFS      Output buffer is too small.
      * @retval  OT_ERROR_INVALID_ARGS Private key is not valid EC Private Key.
      * @retval  OT_ERROR_FAILED       Error during signing.
+     *
      */
     static otError Sign(uint8_t *      aOutput,
-                        uint16_t *     aOutputLength,
+                        uint16_t &     aOutputLength,
                         const uint8_t *aInputHash,
                         uint16_t       aInputHashLength,
                         const uint8_t *aPrivateKey,
diff --git a/src/core/crypto/hmac_sha256.cpp b/src/core/crypto/hmac_sha256.cpp
index 17358b5..0187d99 100644
--- a/src/core/crypto/hmac_sha256.cpp
+++ b/src/core/crypto/hmac_sha256.cpp
@@ -36,15 +36,15 @@
 namespace ot {
 namespace Crypto {
 
-HmacSha256::HmacSha256()
+HmacSha256::HmacSha256(void)
 {
-    const mbedtls_md_info_t *mdInfo = NULL;
+    const mbedtls_md_info_t *mdInfo = nullptr;
     mbedtls_md_init(&mContext);
     mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
     mbedtls_md_setup(&mContext, mdInfo, 1);
 }
 
-HmacSha256::~HmacSha256()
+HmacSha256::~HmacSha256(void)
 {
     mbedtls_md_free(&mContext);
 }
diff --git a/src/core/crypto/hmac_sha256.hpp b/src/core/crypto/hmac_sha256.hpp
index fe28d3f..ed3a844 100644
--- a/src/core/crypto/hmac_sha256.hpp
+++ b/src/core/crypto/hmac_sha256.hpp
@@ -66,13 +66,13 @@
      * Constructor for initialization of mbedtls_md_context_t.
      *
      */
-    HmacSha256();
+    HmacSha256(void);
 
     /**
      * Destructor for freeing of mbedtls_md_context_t.
      *
      */
-    ~HmacSha256();
+    ~HmacSha256(void);
 
     /**
      * This method sets the key.
diff --git a/src/core/crypto/mbedtls.cpp b/src/core/crypto/mbedtls.cpp
index a83d345..58b183c 100644
--- a/src/core/crypto/mbedtls.cpp
+++ b/src/core/crypto/mbedtls.cpp
@@ -74,11 +74,11 @@
 #endif // !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE && OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT
 }
 
-otError MbedTls::MapError(int rval)
+otError MbedTls::MapError(int aMbedTlsError)
 {
     otError error = OT_ERROR_NONE;
 
-    switch (rval)
+    switch (aMbedTlsError)
     {
 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
     case MBEDTLS_ERR_PK_TYPE_MISMATCH:
@@ -154,7 +154,7 @@
         break;
 
     default:
-        assert(rval >= 0);
+        OT_ASSERT(aMbedTlsError >= 0);
         break;
     }
 
diff --git a/src/core/crypto/mbedtls.hpp b/src/core/crypto/mbedtls.hpp
index d4386b5..b2df719 100644
--- a/src/core/crypto/mbedtls.hpp
+++ b/src/core/crypto/mbedtls.hpp
@@ -38,6 +38,8 @@
 
 #include <openthread/instance.h>
 
+#include "common/non_copyable.hpp"
+
 namespace ot {
 namespace Crypto {
 
@@ -52,7 +54,7 @@
  * This class implements mbedTLS memory.
  *
  */
-class MbedTls
+class MbedTls : private NonCopyable
 {
 public:
     /**
@@ -62,9 +64,14 @@
     MbedTls(void);
 
     /**
-     * This method converts from MbedTls error to OpenThread error.
+     * This method converts an mbed TLS error to OpenThread error.
+     *
+     * @param[in] aMbedTlsError  The mbed TLS error.
+     *
+     * @returns The mapped otError.
+     *
      */
-    static otError MapError(int rval);
+    static otError MapError(int aMbedTlsError);
 };
 
 /**
diff --git a/src/core/crypto/pbkdf2_cmac.cpp b/src/core/crypto/pbkdf2_cmac.cpp
index ef14ee1..1af07f0 100644
--- a/src/core/crypto/pbkdf2_cmac.cpp
+++ b/src/core/crypto/pbkdf2_cmac.cpp
@@ -39,7 +39,7 @@
 
 #include <mbedtls/cmac.h>
 
-#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
+#if OPENTHREAD_FTD
 
 void otPbkdf2Cmac(const uint8_t *aPassword,
                   uint16_t       aPasswordLen,
@@ -60,9 +60,14 @@
     uint16_t     useLen       = 0;
 
     memcpy(prfInput, aSalt, aSaltLen);
-    assert(aIterationCounter % 2 == 0);
+    OT_ASSERT(aIterationCounter % 2 == 0);
     aIterationCounter /= 2;
 
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    // limit iterations to avoid OSS-Fuzz timeouts
+    aIterationCounter = 2;
+#endif
+
     while (keyLen)
     {
         ++blockCounter;
@@ -106,4 +111,4 @@
     }
 }
 
-#endif // OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
+#endif // OPENTHREAD_FTD
diff --git a/src/core/crypto/sha256.cpp b/src/core/crypto/sha256.cpp
index 6ca028e..5715192 100644
--- a/src/core/crypto/sha256.cpp
+++ b/src/core/crypto/sha256.cpp
@@ -36,12 +36,12 @@
 namespace ot {
 namespace Crypto {
 
-Sha256::Sha256()
+Sha256::Sha256(void)
 {
     mbedtls_sha256_init(&mContext);
 }
 
-Sha256::~Sha256()
+Sha256::~Sha256(void)
 {
     mbedtls_sha256_free(&mContext);
 }
diff --git a/src/core/crypto/sha256.hpp b/src/core/crypto/sha256.hpp
index a5efeda..ab7ed68 100644
--- a/src/core/crypto/sha256.hpp
+++ b/src/core/crypto/sha256.hpp
@@ -66,13 +66,13 @@
      * Constructor for initializing mbedtls_sha256_context.
      *
      */
-    Sha256();
+    Sha256(void);
 
     /**
      * Destructor for freeing mbedtls_sha256_context.
      *
      */
-    ~Sha256();
+    ~Sha256(void);
 
     /**
      * This method starts the SHA-256 computation.
diff --git a/src/core/diags/README.md b/src/core/diags/README.md
index 879a25b..51c883a 100644
--- a/src/core/diags/README.md
+++ b/src/core/diags/README.md
@@ -4,19 +4,17 @@
 
 The diagnostics module supports common diagnostics features that are listed below, and it also provides a mechanism for expanding platform specific diagnostics features.
 
-
 ## Common Diagnostics Command List
 
-* [diag](#diag)
-* [diag start](#diag-start)
-* [diag channel](#diag-channel)
-* [diag power](#diag-power)
-* [diag send](#diag-send-packets-length)
-* [diag repeat](#diag-repeat-delay-length)
-* [diag radio](#diag-radio)
-* [diag stats](#diag-stats)
-* [diag stop](#diag-stop)
-
+- [diag](#diag)
+- [diag start](#diag-start)
+- [diag channel](#diag-channel)
+- [diag power](#diag-power)
+- [diag send](#diag-send-packets-length)
+- [diag repeat](#diag-repeat-delay-length)
+- [diag radio](#diag-radio)
+- [diag stats](#diag-stats)
+- [diag stop](#diag-stop)
 
 ### diag
 
@@ -154,6 +152,7 @@
 > diag stats clear
 stats cleared
 ```
+
 ### diag stop
 
 Stop diagnostics mode and print statistics.
@@ -168,4 +167,3 @@
 stop diagnostics mode
 status 0x00
 ```
-
diff --git a/src/core/diags/factory_diags.cpp b/src/core/diags/factory_diags.cpp
index b7f1798..ac13716 100644
--- a/src/core/diags/factory_diags.cpp
+++ b/src/core/diags/factory_diags.cpp
@@ -45,6 +45,22 @@
 #include "radio/radio.hpp"
 #include "utils/parse_cmdline.hpp"
 
+OT_TOOL_WEAK
+otError otPlatDiagProcess(otInstance *aInstance,
+                          uint8_t     aArgsLength,
+                          char *      aArgs[],
+                          char *      aOutput,
+                          size_t      aOutputMaxLen)
+{
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aOutput);
+    OT_UNUSED_VARIABLE(aOutputMaxLen);
+
+    return OT_ERROR_INVALID_COMMAND;
+}
+
 namespace ot {
 namespace FactoryDiags {
 
@@ -63,55 +79,61 @@
 {
 }
 
-void Diags::ProcessChannel(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessChannel(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(aArgCount == 1, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = ParseLong(aArgVector[0], value));
+    SuccessOrExit(error = ParseLong(aArgs[0], value));
     VerifyOrExit(value >= Radio::kChannelMin && value <= Radio::kChannelMax, error = OT_ERROR_INVALID_ARGS);
 
     otPlatDiagChannelSet(static_cast<uint8_t>(value));
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-void Diags::ProcessPower(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessPower(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
-    VerifyOrExit(aArgCount == 1, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = ParseLong(aArgVector[0], value));
+    SuccessOrExit(error = ParseLong(aArgs[0], value));
 
     otPlatDiagTxPowerSet(static_cast<int8_t>(value));
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-void Diags::ProcessStart(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessStart(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
-    OT_UNUSED_VARIABLE(aArgCount);
-    OT_UNUSED_VARIABLE(aArgVector);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
     OT_UNUSED_VARIABLE(aOutput);
     OT_UNUSED_VARIABLE(aOutputMaxLen);
 
     otPlatDiagModeSet(true);
+
+    return OT_ERROR_NONE;
 }
 
-void Diags::ProcessStop(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessStop(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
-    OT_UNUSED_VARIABLE(aArgCount);
-    OT_UNUSED_VARIABLE(aArgVector);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
     OT_UNUSED_VARIABLE(aOutput);
     OT_UNUSED_VARIABLE(aOutputMaxLen);
 
     otPlatDiagModeSet(false);
+
+    return OT_ERROR_NONE;
 }
 
 extern "C" void otPlatDiagAlarmFired(otInstance *aInstance)
@@ -138,18 +160,15 @@
     , mRepeatActive(false)
 {
     mStats.Clear();
-
-    otPlatDiagChannelSet(mChannel);
-    otPlatDiagTxPowerSet(mTxPower);
 }
 
-void Diags::ProcessChannel(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessChannel(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
 
-    if (aArgCount == 0)
+    if (aArgsLength == 0)
     {
         snprintf(aOutput, aOutputMaxLen, "channel: %d\r\n", mChannel);
     }
@@ -157,11 +176,11 @@
     {
         long value;
 
-        SuccessOrExit(error = ParseLong(aArgVector[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         VerifyOrExit(value >= Radio::kChannelMin && value <= Radio::kChannelMax, error = OT_ERROR_INVALID_ARGS);
 
         mChannel = static_cast<uint8_t>(value);
-        Get<Radio>().Receive(mChannel);
+        IgnoreError(Get<Radio>().Receive(mChannel));
         otPlatDiagChannelSet(mChannel);
 
         snprintf(aOutput, aOutputMaxLen, "set channel to %d\r\nstatus 0x%02x\r\n", mChannel, error);
@@ -169,15 +188,16 @@
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-void Diags::ProcessPower(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessPower(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
 
-    if (aArgCount == 0)
+    if (aArgsLength == 0)
     {
         snprintf(aOutput, aOutputMaxLen, "tx power: %d dBm\r\n", mTxPower);
     }
@@ -185,7 +205,7 @@
     {
         long value;
 
-        SuccessOrExit(error = ParseLong(aArgVector[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
 
         mTxPower = static_cast<int8_t>(value);
         SuccessOrExit(error = Get<Radio>().SetTransmitPower(mTxPower));
@@ -196,16 +216,17 @@
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-void Diags::ProcessRepeat(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessRepeat(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(aArgCount > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(aArgVector[0], "stop") == 0)
+    if (strcmp(aArgs[0], "stop") == 0)
     {
         otPlatAlarmMilliStop(&GetInstance());
         mRepeatActive = false;
@@ -215,12 +236,12 @@
     {
         long value;
 
-        VerifyOrExit(aArgCount == 2, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
 
-        SuccessOrExit(error = ParseLong(aArgVector[0], value));
+        SuccessOrExit(error = ParseLong(aArgs[0], value));
         mTxPeriod = static_cast<uint32_t>(value);
 
-        SuccessOrExit(error = ParseLong(aArgVector[1], value));
+        SuccessOrExit(error = ParseLong(aArgs[1], value));
         VerifyOrExit(value <= OT_RADIO_FRAME_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
         mTxLen = static_cast<uint8_t>(value);
 
@@ -233,20 +254,21 @@
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-void Diags::ProcessSend(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessSend(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     otError error = OT_ERROR_NONE;
     long    value;
 
     VerifyOrExit(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(aArgCount == 2, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(error = ParseLong(aArgVector[0], value));
+    SuccessOrExit(error = ParseLong(aArgs[0], value));
     mTxPackets = static_cast<uint32_t>(value);
 
-    SuccessOrExit(error = ParseLong(aArgVector[1], value));
+    SuccessOrExit(error = ParseLong(aArgs[1], value));
     VerifyOrExit(value <= OT_RADIO_FRAME_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
     mTxLen = static_cast<uint8_t>(value);
 
@@ -256,16 +278,20 @@
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-void Diags::ProcessStart(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessStart(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
-    OT_UNUSED_VARIABLE(aArgCount);
-    OT_UNUSED_VARIABLE(aArgVector);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError error = OT_ERROR_NONE;
 
-    Get<Radio>().Enable();
+    otPlatDiagChannelSet(mChannel);
+    otPlatDiagTxPowerSet(mTxPower);
+
+    IgnoreError(Get<Radio>().Enable());
     Get<Radio>().SetPromiscuous(true);
     otPlatAlarmMilliStop(&GetInstance());
     SuccessOrExit(error = Get<Radio>().Receive(mChannel));
@@ -276,22 +302,23 @@
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-void Diags::ProcessStats(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessStats(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
 
-    if ((aArgCount == 1) && (strcmp(aArgVector[0], "clear") == 0))
+    if ((aArgsLength == 1) && (strcmp(aArgs[0], "clear") == 0))
     {
         mStats.Clear();
         snprintf(aOutput, aOutputMaxLen, "stats cleared\r\n");
     }
     else
     {
-        VerifyOrExit(aArgCount == 0, error = OT_ERROR_INVALID_ARGS);
+        VerifyOrExit(aArgsLength == 0, error = OT_ERROR_INVALID_ARGS);
         snprintf(aOutput, aOutputMaxLen,
                  "received packets: %d\r\nsent packets: %d\r\n"
                  "first received packet: rssi=%d, lqi=%d\r\n"
@@ -303,12 +330,13 @@
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
-void Diags::ProcessStop(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessStop(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
-    OT_UNUSED_VARIABLE(aArgCount);
-    OT_UNUSED_VARIABLE(aArgVector);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
 
     otError error = OT_ERROR_NONE;
 
@@ -329,6 +357,7 @@
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
 void Diags::TransmitPacket(void)
@@ -341,22 +370,22 @@
         mTxPacket->mPsdu[i] = i;
     }
 
-    Get<Radio>().Transmit(*static_cast<Mac::TxFrame *>(mTxPacket));
+    IgnoreError(Get<Radio>().Transmit(*static_cast<Mac::TxFrame *>(mTxPacket)));
 }
 
-void Diags::ProcessRadio(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessRadio(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     otError error = OT_ERROR_INVALID_ARGS;
 
     VerifyOrExit(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(aArgCount > 0, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
 
-    if (strcmp(aArgVector[0], "sleep") == 0)
+    if (strcmp(aArgs[0], "sleep") == 0)
     {
         SuccessOrExit(error = Get<Radio>().Sleep());
         snprintf(aOutput, aOutputMaxLen, "set radio from receive to sleep \r\nstatus 0x%02x\r\n", error);
     }
-    else if (strcmp(aArgVector[0], "receive") == 0)
+    else if (strcmp(aArgs[0], "receive") == 0)
     {
         SuccessOrExit(error = Get<Radio>().Receive(mChannel));
         SuccessOrExit(error = Get<Radio>().SetTransmitPower(mTxPower));
@@ -366,7 +395,7 @@
         snprintf(aOutput, aOutputMaxLen, "set radio from sleep to receive on channel %d\r\nstatus 0x%02x\r\n", mChannel,
                  error);
     }
-    else if (strcmp(aArgVector[0], "state") == 0)
+    else if (strcmp(aArgs[0], "state") == 0)
     {
         otRadioState state = Get<Radio>().GetState();
 
@@ -398,6 +427,7 @@
 
 exit:
     AppendErrorResult(error, aOutput, aOutputMaxLen);
+    return error;
 }
 
 extern "C" void otPlatDiagAlarmFired(otInstance *aInstance)
@@ -458,7 +488,7 @@
         }
     }
 
-    VerifyOrExit(!mRepeatActive);
+    VerifyOrExit(!mRepeatActive, OT_NOOP);
     TransmitPacket();
 
 exit:
@@ -492,13 +522,13 @@
 
     otError error = OT_ERROR_NONE;
     char    buffer[kMaxCommandBuffer];
-    char *  argVector[kMaxArgs];
+    char *  aArgsector[kMaxArgs];
     uint8_t argCount = 0;
 
     VerifyOrExit(StringLength(aString, kMaxCommandBuffer) < kMaxCommandBuffer, error = OT_ERROR_NO_BUFS);
 
     strcpy(buffer, aString);
-    error = ot::Utils::CmdLineParser::ParseCmd(buffer, argCount, argVector, kMaxArgs);
+    error = ot::Utils::CmdLineParser::ParseCmd(buffer, argCount, aArgsector, kMaxArgs);
 
 exit:
 
@@ -506,7 +536,7 @@
     {
     case OT_ERROR_NONE:
 
-        ProcessCmd(argCount, &argVector[0], aOutput, aOutputMaxLen);
+        IgnoreError(ProcessCmd(argCount, &aArgsector[0], aOutput, aOutputMaxLen));
         break;
 
     case OT_ERROR_NO_BUFS:
@@ -523,29 +553,51 @@
     }
 }
 
-void Diags::ProcessCmd(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
+otError Diags::ProcessCmd(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
-    if (aArgCount == 0)
+    otError error = OT_ERROR_NONE;
+
+    // This `rcp` command is for debugging and testing only, building only when NDEBUG is not defined
+    // so that it will be excluded from release build.
+#if !defined(NDEBUG) && defined(OPENTHREAD_RADIO)
+    if (aArgsLength > 0 && !strcmp(aArgs[0], "rcp"))
+    {
+        aArgs++;
+        aArgsLength--;
+    }
+#endif
+
+    if (aArgsLength == 0)
     {
         snprintf(aOutput, aOutputMaxLen, "diagnostics mode is %s\r\n", otPlatDiagModeGet() ? "enabled" : "disabled");
         ExitNow();
     }
+    else
+    {
+        aOutput[0] = '\0';
+    }
 
     for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
     {
-        if (strcmp(aArgVector[0], sCommands[i].mName) == 0)
+        if (strcmp(aArgs[0], sCommands[i].mName) == 0)
         {
-            (this->*sCommands[i].mCommand)(aArgCount - 1, (aArgCount > 1) ? &aArgVector[1] : NULL, aOutput,
-                                           aOutputMaxLen);
+            error = (this->*sCommands[i].mCommand)(aArgsLength - 1, (aArgsLength > 1) ? &aArgs[1] : nullptr, aOutput,
+                                                   aOutputMaxLen);
             ExitNow();
         }
     }
 
     // more platform specific features will be processed under platform layer
-    otPlatDiagProcess(&GetInstance(), aArgCount, aArgVector, aOutput, aOutputMaxLen);
+    error = otPlatDiagProcess(&GetInstance(), aArgsLength, aArgs, aOutput, aOutputMaxLen);
 
 exit:
-    return;
+    // Add more platform specific diagnostics features here.
+    if (error == OT_ERROR_INVALID_COMMAND && aArgsLength > 1)
+    {
+        snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", aArgs[0]);
+    }
+
+    return error;
 }
 
 bool Diags::IsEnabled(void)
diff --git a/src/core/diags/factory_diags.hpp b/src/core/diags/factory_diags.hpp
index 56c3112..3c3dd41 100644
--- a/src/core/diags/factory_diags.hpp
+++ b/src/core/diags/factory_diags.hpp
@@ -41,13 +41,14 @@
 #include <openthread/platform/radio.h>
 
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 
 namespace ot {
 namespace FactoryDiags {
 
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
 
-class Diags : public InstanceLocator
+class Diags : public InstanceLocator, private NonCopyable
 {
 public:
     /**
@@ -61,7 +62,7 @@
     /**
      * This method processes a factory diagnostics command line.
      *
-     * @param[in]   aString        A NULL-terminated input string.
+     * @param[in]   aString        A null-terminated input string.
      * @param[out]  aOutput        The diagnostics execution result.
      * @param[in]   aOutputMaxLen  The output buffer size.
      *
@@ -71,13 +72,17 @@
     /**
      * This method processes a factory diagnostics command line.
      *
-     * @param[in]   aArgCount      The argument counter of diagnostics command line.
-     * @param[in]   aArgVector     The argument vector of diagnostics command line.
+     * @param[in]   aArgsLength    The number of args in @p aArgs.
+     * @param[in]   aArgs          The arguments of diagnostics command line.
      * @param[out]  aOutput        The diagnostics execution result.
      * @param[in]   aOutputMaxLen  The output buffer size.
      *
+     * @retval  OT_ERROR_INVALID_ARGS       The command is supported but invalid arguments provided.
+     * @retval  OT_ERROR_NONE               The command is successfully process.
+     * @retval  OT_ERROR_NOT_IMPLEMENTED    The command is not supported.
+     *
      */
-    void ProcessCmd(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessCmd(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
 
     /**
      * This method indicates whether or not the factory diagnostics mode is enabled.
@@ -97,7 +102,7 @@
     /**
      * The radio driver calls this method to notify OpenThread diagnostics module of a received frame.
      *
-     * @param[in]  aFrame  A pointer to the received frame or NULL if the receive operation failed.
+     * @param[in]  aFrame  A pointer to the received frame or nullptr if the receive operation failed.
      * @param[in]  aError  OT_ERROR_NONE when successfully received a frame,
      *                     OT_ERROR_ABORT when reception was aborted and a frame was not received,
      *                     OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
@@ -119,7 +124,7 @@
     struct Command
     {
         const char *mName;
-        void (Diags::*mCommand)(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
+        otError (Diags::*mCommand)(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
     };
 
     struct Stats
@@ -134,14 +139,14 @@
         uint8_t  mLastLqi;
     };
 
-    void ProcessChannel(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
-    void ProcessPower(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
-    void ProcessRadio(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
-    void ProcessRepeat(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
-    void ProcessSend(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
-    void ProcessStart(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
-    void ProcessStats(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
-    void ProcessStop(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessChannel(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessPower(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessRadio(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessRepeat(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessSend(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessStart(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessStats(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
+    otError ProcessStop(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen);
 
     void TransmitPacket(void);
 
diff --git a/src/core/mac/channel_mask.cpp b/src/core/mac/channel_mask.cpp
index a51442b..a310456 100644
--- a/src/core/mac/channel_mask.cpp
+++ b/src/core/mac/channel_mask.cpp
@@ -78,7 +78,7 @@
     uint8_t channel = kChannelIteratorFirst;
     uint8_t randomIndex;
 
-    VerifyOrExit(!IsEmpty());
+    VerifyOrExit(!IsEmpty(), OT_NOOP);
 
     randomIndex = Random::NonCrypto::GetUint8InRange(0, GetNumberOfChannels());
 
@@ -100,7 +100,7 @@
     bool       addComma = false;
     otError    error;
 
-    string.Append("{");
+    IgnoreError(string.Append("{"));
 
     error = GetNextChannel(channel);
 
@@ -119,16 +119,16 @@
             rangeEnd = channel;
         }
 
-        string.Append("%s%d", addComma ? ", " : " ", rangeStart);
+        IgnoreError(string.Append("%s%d", addComma ? ", " : " ", rangeStart));
         addComma = true;
 
         if (rangeStart < rangeEnd)
         {
-            string.Append("%s%d", rangeEnd == rangeStart + 1 ? ", " : "-", rangeEnd);
+            IgnoreError(string.Append("%s%d", rangeEnd == rangeStart + 1 ? ", " : "-", rangeEnd));
         }
     }
 
-    string.Append("}");
+    IgnoreError(string.Append("}"));
 
     return string;
 }
diff --git a/src/core/mac/channel_mask.hpp b/src/core/mac/channel_mask.hpp
index 2c7fc82..b90ad65 100644
--- a/src/core/mac/channel_mask.hpp
+++ b/src/core/mac/channel_mask.hpp
@@ -41,7 +41,6 @@
 
 #include "common/string.hpp"
 #include "radio/radio.hpp"
-#include "utils/static_assert.hpp"
 
 namespace ot {
 namespace Mac {
@@ -252,8 +251,8 @@
     InfoString ToString(void) const;
 
 private:
-    OT_STATIC_ASSERT((Radio::kChannelMin < 32) && (Radio::kChannelMax < 32),
-                     "The channel number is larger than 32. `ChannelMask` uses 32 bit mask.");
+    static_assert((Radio::kChannelMin < 32) && (Radio::kChannelMax < 32),
+                  "The channel number is larger than 32. `ChannelMask` uses 32 bit mask.");
     uint32_t mMask;
 };
 
diff --git a/src/core/mac/data_poll_handler.cpp b/src/core/mac/data_poll_handler.cpp
index 98978dc..032b0bf 100644
--- a/src/core/mac/data_poll_handler.cpp
+++ b/src/core/mac/data_poll_handler.cpp
@@ -71,7 +71,7 @@
 
 DataPollHandler::DataPollHandler(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mIndirectTxChild(NULL)
+    , mIndirectTxChild(nullptr)
     , mFrameContext()
     , mCallbacks(aInstance)
 {
@@ -79,16 +79,15 @@
 
 void DataPollHandler::Clear(void)
 {
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateAnyExceptInvalid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
     {
-        Child &child = *iter.GetChild();
         child.SetDataPollPending(false);
         child.SetFrameReplacePending(false);
         child.SetFramePurgePending(false);
         child.ResetIndirectTxAttempts();
     }
 
-    mIndirectTxChild = NULL;
+    mIndirectTxChild = nullptr;
 }
 
 void DataPollHandler::HandleNewFrame(Child &aChild)
@@ -130,12 +129,12 @@
     Child *      child;
     uint16_t     indirectMsgCount;
 
-    VerifyOrExit(aFrame.GetSecurityEnabled());
-    VerifyOrExit(Get<Mle::MleRouter>().GetRole() != OT_DEVICE_ROLE_DETACHED);
+    VerifyOrExit(aFrame.GetSecurityEnabled(), OT_NOOP);
+    VerifyOrExit(!Get<Mle::MleRouter>().IsDetached(), OT_NOOP);
 
     SuccessOrExit(aFrame.GetSrcAddr(macSource));
     child = Get<ChildTable>().FindChild(macSource, Child::kInStateValidOrRestoring);
-    VerifyOrExit(child != NULL);
+    VerifyOrExit(child != nullptr, OT_NOOP);
 
     child->SetLastHeard(TimerMilli::GetNow());
     child->ResetLinkFailures();
@@ -154,7 +153,7 @@
         ExitNow();
     }
 
-    if (mIndirectTxChild == NULL)
+    if (mIndirectTxChild == nullptr)
     {
         mIndirectTxChild = child;
         Get<Mac::Mac>().RequestIndirectFrameTransmission();
@@ -172,7 +171,7 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(mIndirectTxChild != NULL, error = OT_ERROR_ABORT);
+    VerifyOrExit(mIndirectTxChild != nullptr, error = OT_ERROR_ABORT);
 
     SuccessOrExit(error = mCallbacks.PrepareFrameForChild(aFrame, mFrameContext, *mIndirectTxChild));
 
@@ -204,9 +203,9 @@
 {
     Child *child = mIndirectTxChild;
 
-    VerifyOrExit(child != NULL);
+    VerifyOrExit(child != nullptr, OT_NOOP);
 
-    mIndirectTxChild = NULL;
+    mIndirectTxChild = nullptr;
     HandleSentFrame(aFrame, aError, *child);
 
 exit:
@@ -263,10 +262,10 @@
                 uint32_t frameCounter;
                 uint8_t  keyId;
 
-                aFrame.GetFrameCounter(frameCounter);
+                IgnoreError(aFrame.GetFrameCounter(frameCounter));
                 aChild.SetIndirectFrameCounter(frameCounter);
 
-                aFrame.GetKeyId(keyId);
+                IgnoreError(aFrame.GetKeyId(keyId));
                 aChild.SetIndirectKeyId(keyId);
             }
 
@@ -277,8 +276,8 @@
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
     mCallbacks.HandleSentFrameToChild(aFrame, mFrameContext, aError, aChild);
@@ -289,24 +288,22 @@
 
 void DataPollHandler::ProcessPendingPolls(void)
 {
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
     {
-        Child *child = iter.GetChild();
-
-        if (!child->IsDataPollPending())
+        if (!child.IsDataPollPending())
         {
             continue;
         }
 
         // Find the child with earliest poll receive time.
 
-        if ((mIndirectTxChild == NULL) || (child->GetLastHeard() < mIndirectTxChild->GetLastHeard()))
+        if ((mIndirectTxChild == nullptr) || (child.GetLastHeard() < mIndirectTxChild->GetLastHeard()))
         {
-            mIndirectTxChild = child;
+            mIndirectTxChild = &child;
         }
     }
 
-    if (mIndirectTxChild != NULL)
+    if (mIndirectTxChild != nullptr)
     {
         mIndirectTxChild->SetDataPollPending(false);
         Get<Mac::Mac>().RequestIndirectFrameTransmission();
diff --git a/src/core/mac/data_poll_handler.hpp b/src/core/mac/data_poll_handler.hpp
index c6657e7..bf66724 100644
--- a/src/core/mac/data_poll_handler.hpp
+++ b/src/core/mac/data_poll_handler.hpp
@@ -122,7 +122,7 @@
         bool     mFramePurgePending : 1;   // Indicates a pending purge request for the current indirect frame.
         bool     mFrameReplacePending : 1; // Indicates a pending replace request for the current indirect frame.
 
-        OT_STATIC_ASSERT(kMaxPollTriggeredTxAttempts < (1 << 5), "mIndirectTxAttempts cannot fit max!");
+        static_assert(kMaxPollTriggeredTxAttempts < (1 << 5), "mIndirectTxAttempts cannot fit max!");
     };
 
     /**
@@ -157,7 +157,7 @@
          * This callback method requests a frame to be prepared for indirect transmission to a given sleepy child.
          *
          * @param[out] aFrame    A reference to a MAC frame where the new frame would be placed.
-         * @prarm[out] aContext  A reference to a `FrameContext` where the context for the new frame would be placed.
+         * @param[out] aContext  A reference to a `FrameContext` where the context for the new frame would be placed.
          * @param[in]  aChild    The child for which to prepare the frame.
          *
          * @retval OT_ERROR_NONE   Frame was prepared successfully
@@ -268,7 +268,7 @@
 
     // In the current implementation of `DataPollHandler`, we can have a
     // single indirect tx operation active at MAC layer at each point of
-    // time. `mIndirectTxChild` indicates the child being handled (NULL
+    // time. `mIndirectTxChild` indicates the child being handled (nullptr
     // indicates no active indirect tx). `mFrameContext` tracks the
     // context for the prepared frame for the current indirect tx.
 
diff --git a/src/core/mac/data_poll_sender.cpp b/src/core/mac/data_poll_sender.cpp
index e1395d1..25b1f26 100644
--- a/src/core/mac/data_poll_sender.cpp
+++ b/src/core/mac/data_poll_sender.cpp
@@ -52,7 +52,7 @@
     , mPollPeriod(0)
     , mExternalPollPeriod(0)
     , mFastPollsUsers(0)
-    , mTimer(aInstance, &DataPollSender::HandlePollTimer, this)
+    , mTimer(aInstance, DataPollSender::HandlePollTimer, this)
     , mEnabled(false)
     , mAttachMode(false)
     , mRetxMode(false)
@@ -69,18 +69,17 @@
     return parentCandidate.IsStateValid() ? parentCandidate : Get<Mle::MleRouter>().GetParent();
 }
 
-otError DataPollSender::StartPolling(void)
+void DataPollSender::StartPolling(void)
 {
-    otError error = OT_ERROR_NONE;
+    VerifyOrExit(!mEnabled, OT_NOOP);
 
-    VerifyOrExit(!mEnabled, error = OT_ERROR_ALREADY);
-    VerifyOrExit(!Get<Mle::MleRouter>().IsRxOnWhenIdle(), error = OT_ERROR_INVALID_STATE);
+    OT_ASSERT(!Get<Mle::MleRouter>().IsRxOnWhenIdle());
 
     mEnabled = true;
     ScheduleNextPoll(kRecalculatePollPeriod);
 
 exit:
-    return error;
+    return;
 }
 
 void DataPollSender::StopPolling(void)
@@ -204,18 +203,18 @@
     Mac::Address macDest;
     bool         shouldRecalculatePollPeriod = false;
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     if (!aFrame.IsEmpty())
     {
-        aFrame.GetDstAddr(macDest);
+        IgnoreError(aFrame.GetDstAddr(macDest));
         Get<MeshForwarder>().UpdateNeighborOnSentFrame(aFrame, aError, macDest);
     }
 
     if (GetParent().IsStateInvalid())
     {
         StopPolling();
-        Get<Mle::MleRouter>().BecomeDetached();
+        IgnoreError(Get<Mle::MleRouter>().BecomeDetached());
         ExitNow();
     }
 
@@ -288,7 +287,7 @@
     // a data poll indicated that a frame was pending, but no frame
     // was received after timeout interval.
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     mPollTimeoutCounter++;
 
@@ -296,7 +295,7 @@
 
     if (mPollTimeoutCounter < kQuickPollsAfterTimeout)
     {
-        SendDataPoll();
+        IgnoreError(SendDataPoll());
     }
     else
     {
@@ -307,16 +306,22 @@
     return;
 }
 
-void DataPollSender::CheckFramePending(Mac::RxFrame &aFrame)
+void DataPollSender::ProcessFrame(const Mac::RxFrame &aFrame)
 {
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     mPollTimeoutCounter = 0;
 
     if (aFrame.GetFramePending())
     {
-        SendDataPoll();
+        IgnoreError(SendDataPoll());
     }
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    else if (aFrame.IsAck())
+    {
+        ResetKeepAliveTimer();
+    }
+#endif
 
 exit:
     return;
@@ -373,25 +378,32 @@
     }
 }
 
-otError DataPollSender::StopFastPolls(void)
+void DataPollSender::StopFastPolls(void)
 {
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mFastPollsUsers != 0);
+    VerifyOrExit(mFastPollsUsers != 0, OT_NOOP);
 
     // If `mFastPollsUsers` hits the max, let it be cleared
     // from `HandlePollSent()` (after all fast polls are sent).
-    VerifyOrExit(mFastPollsUsers < kMaxFastPollsUsers);
+    VerifyOrExit(mFastPollsUsers < kMaxFastPollsUsers, OT_NOOP);
 
     mFastPollsUsers--;
 
-    VerifyOrExit(mFastPollsUsers == 0, error = OT_ERROR_BUSY);
+    VerifyOrExit(mFastPollsUsers == 0, OT_NOOP);
 
     mRemainingFastPolls = 0;
     ScheduleNextPoll(kRecalculatePollPeriod);
 
 exit:
-    return error;
+    return;
+}
+
+void DataPollSender::ResetKeepAliveTimer(void)
+{
+    if (mTimer.IsRunning() && mPollPeriod == GetDefaultPollPeriod())
+    {
+        mTimerStartTime = TimerMilli::GetNow();
+        mTimer.StartAt(mTimerStartTime, mPollPeriod);
+    }
 }
 
 void DataPollSender::ScheduleNextPoll(PollPeriodSelector aPollPeriodSelector)
@@ -479,7 +491,7 @@
 
 void DataPollSender::HandlePollTimer(Timer &aTimer)
 {
-    aTimer.GetOwner<DataPollSender>().SendDataPoll();
+    IgnoreError(aTimer.GetOwner<DataPollSender>().SendDataPoll());
 }
 
 uint32_t DataPollSender::GetDefaultPollPeriod(void) const
diff --git a/src/core/mac/data_poll_sender.hpp b/src/core/mac/data_poll_sender.hpp
index 4d6dc40..0aa0403 100644
--- a/src/core/mac/data_poll_sender.hpp
+++ b/src/core/mac/data_poll_sender.hpp
@@ -79,12 +79,8 @@
     /**
      * This method instructs the data poll sender to start sending periodic data polls.
      *
-     * @retval OT_ERROR_NONE            Successfully started sending periodic data polls.
-     * @retval OT_ERROR_ALREADY         Periodic data poll transmission is already started/enabled.
-     * @retval OT_ERROR_INVALID_STATE   Device is not in rx-off-when-idle mode.
-     *
      */
-    otError StartPolling(void);
+    void StartPolling(void);
 
     /**
      * This method instructs the data poll sender to stop sending periodic data polls.
@@ -167,12 +163,16 @@
     void HandlePollTimeout(void);
 
     /**
-     * This method informs the data poll sender that a mac frame has been received. It checks the "frame pending" in
-     * the received frame header and if it is set, data poll sender will send an immediate data poll to retrieve the
-     * pending frame.
+     * This method informs the data poll sender to process a MAC frame.
+     *
+     *   1. Data Frame: send an immediate data poll if "frame pending" is set.
+     *   2. Ack Frame for a secured data frame in version 1.2 or newer: send an immediate data poll if
+     *      "frame pending" is set, otherwise reset the keep-alive timer for sending next poll.
+     *
+     * @param[in] aFrame     The frame to process.
      *
      */
-    void CheckFramePending(Mac::RxFrame &aFrame);
+    void ProcessFrame(const Mac::RxFrame &aFrame);
 
     /**
      * This method asks the data poll sender to recalculate the poll period.
@@ -215,11 +215,8 @@
     /**
      * This method asks data poll sender to stop fast polls when the expecting response is received.
      *
-     * @retval OT_ERROR_NONE            Successfully stopped fast polls when no other responses are expected.
-     * @retval OT_ERROR_BUSY            There are other callers who are waiting for responses.
-     *
      */
-    otError StopFastPolls(void);
+    void StopFastPolls(void);
 
     /**
      * This method gets the maximum data polling period in use.
@@ -233,6 +230,12 @@
     uint32_t GetKeepAlivePollPeriod(void) const;
 
     /**
+     * This method resets the timer for sending keep-alive messages.
+     *
+     */
+    void ResetKeepAliveTimer(void);
+
+    /**
      * This method returns the default maximum poll period.
      *
      * The default poll period is determined based on the child timeout interval, ensuing the child would send data poll
diff --git a/src/core/mac/link_raw.cpp b/src/core/mac/link_raw.cpp
index fdf01c7..9fa17ce 100644
--- a/src/core/mac/link_raw.cpp
+++ b/src/core/mac/link_raw.cpp
@@ -42,7 +42,6 @@
 #include "common/locator-getters.hpp"
 #include "common/logging.hpp"
 #include "common/random.hpp"
-#include "mac/mac.hpp"
 #include "mac/mac_frame.hpp"
 
 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
@@ -52,12 +51,11 @@
 
 LinkRaw::LinkRaw(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mEnabled(false)
     , mReceiveChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
     , mPanId(kPanIdBroadcast)
-    , mReceiveDoneCallback(NULL)
-    , mTransmitDoneCallback(NULL)
-    , mEnergyScanDoneCallback(NULL)
+    , mReceiveDoneCallback(nullptr)
+    , mTransmitDoneCallback(nullptr)
+    , mEnergyScanDoneCallback(nullptr)
 #if OPENTHREAD_RADIO
     , mSubMac(aInstance)
 #elif OPENTHREAD_CONFIG_LINK_RAW_ENABLE
@@ -66,26 +64,26 @@
 {
 }
 
-otError LinkRaw::SetEnabled(bool aEnabled)
+otError LinkRaw::SetReceiveDone(otLinkRawReceiveDone aCallback)
 {
     otError error = OT_ERROR_NONE;
 
-    otLogDebgMac("LinkRaw::Enabled(%s)", aEnabled ? "true" : "false");
+    otLogDebgMac("LinkRaw::Enabled(%s)", (aCallback != NULL ? "true" : "false"));
 
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
     VerifyOrExit(!Get<ThreadNetif>().IsUp(), error = OT_ERROR_INVALID_STATE);
 #endif
 
-    if (aEnabled)
+    if (aCallback)
     {
         SuccessOrExit(error = mSubMac.Enable());
     }
     else
     {
-        mSubMac.Disable();
+        IgnoreError(mSubMac.Disable());
     }
 
-    mEnabled = aEnabled;
+    mReceiveDoneCallback = aCallback;
 
 exit:
     return error;
@@ -136,14 +134,13 @@
     return error;
 }
 
-otError LinkRaw::Receive(otLinkRawReceiveDone aCallback)
+otError LinkRaw::Receive(void)
 {
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
 
     SuccessOrExit(error = mSubMac.Receive(mReceiveChannel));
-    mReceiveDoneCallback = aCallback;
 
 exit:
     return error;
@@ -151,7 +148,7 @@
 
 void LinkRaw::InvokeReceiveDone(RxFrame *aFrame, otError aError)
 {
-    otLogDebgMac("LinkRaw::ReceiveDone(%d bytes), error:%s", (aFrame != NULL) ? aFrame->mLength : 0,
+    otLogDebgMac("LinkRaw::ReceiveDone(%d bytes), error:%s", (aFrame != nullptr) ? aFrame->mLength : 0,
                  otThreadErrorToString(aError));
 
     if (mReceiveDoneCallback && (aError == OT_ERROR_NONE))
@@ -180,7 +177,7 @@
     if (mTransmitDoneCallback)
     {
         mTransmitDoneCallback(&GetInstance(), &aFrame, aAckFrame, aError);
-        mTransmitDoneCallback = NULL;
+        mTransmitDoneCallback = nullptr;
     }
 }
 
@@ -199,13 +196,39 @@
 
 void LinkRaw::InvokeEnergyScanDone(int8_t aEnergyScanMaxRssi)
 {
-    if (IsEnabled() && mEnergyScanDoneCallback != NULL)
+    if (IsEnabled() && mEnergyScanDoneCallback != nullptr)
     {
         mEnergyScanDoneCallback(&GetInstance(), aEnergyScanMaxRssi);
-        mEnergyScanDoneCallback = NULL;
+        mEnergyScanDoneCallback = nullptr;
     }
 }
 
+otError LinkRaw::SetMacKey(uint8_t    aKeyIdMode,
+                           uint8_t    aKeyId,
+                           const Key &aPrevKey,
+                           const Key &aCurrKey,
+                           const Key &aNextKey)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
+    mSubMac.SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey);
+
+exit:
+    return error;
+}
+
+otError LinkRaw::SetMacFrameCounter(uint32_t aMacFrameCounter)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
+    mSubMac.SetFrameCounter(aMacFrameCounter);
+
+exit:
+    return error;
+}
+
 // LCOV_EXCL_START
 
 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
diff --git a/src/core/mac/link_raw.hpp b/src/core/mac/link_raw.hpp
index 6e21817..5de1854 100644
--- a/src/core/mac/link_raw.hpp
+++ b/src/core/mac/link_raw.hpp
@@ -39,6 +39,7 @@
 #include <openthread/link_raw.h>
 
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 #include "mac/mac_frame.hpp"
 #include "mac/sub_mac.hpp"
 
@@ -51,7 +52,7 @@
  * This class defines the raw link-layer object.
  *
  */
-class LinkRaw : public InstanceLocator
+class LinkRaw : public InstanceLocator, private NonCopyable
 {
     friend class ot::Instance;
 
@@ -70,19 +71,21 @@
      * @returns true if enabled, false otherwise.
      *
      */
-    bool IsEnabled(void) const { return mEnabled; }
+    bool IsEnabled(void) const { return mReceiveDoneCallback != NULL; }
 
     /**
      * This method enables/disables the raw link-layer.
      *
-     * @param[in]   aEnabled    Whether enable raw link-layer.
+     * @param[in]   aCallback    A pointer to a function called on receipt of a IEEE 802.15.4 frame, NULL to disable
+     * raw link-layer.
+     *
      *
      * @retval OT_ERROR_INVALID_STATE   Thread stack is enabled.
-     * @retval OT_ERROR_FAILED          The radio could not be enabled.
+     * @retval OT_ERROR_FAILED          The radio could not be enabled/disabled.
      * @retval OT_ERROR_NONE            Successfully enabled/disabled raw link.
      *
      */
-    otError SetEnabled(bool aEnabled);
+    otError SetReceiveDone(otLinkRawReceiveDone aCallback);
 
     /**
      * This method returns the capabilities of the raw link-layer.
@@ -95,18 +98,16 @@
     /**
      * This method starts a (recurring) Receive on the link-layer.
      *
-     * @param[in]  aCallback    A pointer to a function called on receipt of a IEEE 802.15.4 frame.
-     *
      * @retval OT_ERROR_NONE             Successfully transitioned to Receive.
      * @retval OT_ERROR_INVALID_STATE    The radio was disabled or transmitting.
      *
      */
-    otError Receive(otLinkRawReceiveDone aCallback);
+    otError Receive(void);
 
     /**
      * This method invokes the mReceiveDoneCallback, if set.
      *
-     * @param[in]  aFrame    A pointer to the received frame or NULL if the receive operation failed.
+     * @param[in]  aFrame    A pointer to the received frame or nullptr if the receive operation failed.
      * @param[in]  aError    OT_ERROR_NONE when successfully received a frame,
      *                       OT_ERROR_ABORT when reception was aborted and a frame was not received,
      *                       OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
@@ -139,7 +140,7 @@
      * This method invokes the mTransmitDoneCallback, if set.
      *
      * @param[in]  aFrame     The transmitted frame.
-     * @param[in]  aAckFrame  A pointer to the ACK frame, NULL if no ACK was received.
+     * @param[in]  aAckFrame  A pointer to the ACK frame, nullptr if no ACK was received.
      * @param[in]  aError     OT_ERROR_NONE when the frame was transmitted,
      *                        OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
      *                        OT_ERROR_CHANNEL_ACCESS_FAILURE tx failed due to activity on the channel,
@@ -244,13 +245,43 @@
     otError SetExtAddress(const ExtAddress &aExtAddress);
 
     /**
+     * This method updates MAC keys and key index.
+     *
+     * @param[in]   aKeyIdMode        The key ID mode.
+     * @param[in]   aKeyId            The key index.
+     * @param[in]   aPrevKey          The previous MAC key.
+     * @param[in]   aCurrKey          The current MAC key.
+     * @param[in]   aNextKey          The next MAC key.
+     *
+     * @retval OT_ERROR_NONE             If successful.
+     * @retval OT_ERROR_INVALID_STATE    If the raw link-layer isn't enabled.
+     *
+     */
+    otError SetMacKey(uint8_t    aKeyIdMode,
+                      uint8_t    aKeyId,
+                      const Key &aPrevKey,
+                      const Key &aCurrKey,
+                      const Key &aNextKey);
+
+    /**
+     * This method sets the current MAC frame counter value.
+     *
+     * @param[in] aMacFrameCounter  The MAC frame counter value.
+     *
+     * @retval OT_ERROR_NONE             If successful.
+     * @retval OT_ERROR_INVALID_STATE    If the raw link-layer isn't enabled.
+     *
+     */
+    otError SetMacFrameCounter(uint32_t aMacFrameCounter);
+
+    /**
      * This method records the status of a frame transmission attempt and is mainly used for logging failures.
      *
      * Unlike `HandleTransmitDone` which is called after all transmission attempts of frame to indicate final status
      * of a frame transmission request, this method is invoked on all frame transmission attempts.
      *
      * @param[in] aFrame      The transmitted frame.
-     * @param[in] aAckFrame   A pointer to the ACK frame, or NULL if no ACK was received.
+     * @param[in] aAckFrame   A pointer to the ACK frame, or nullptr if no ACK was received.
      * @param[in] aError      OT_ERROR_NONE when the frame was transmitted successfully,
      *                        OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
      *                        OT_ERROR_CHANNEL_ACCESS_FAILURE tx failed due to activity on the channel,
@@ -271,7 +302,6 @@
 #endif
 
 private:
-    bool                    mEnabled;
     uint8_t                 mReceiveChannel;
     PanId                   mPanId;
     otLinkRawReceiveDone    mReceiveDoneCallback;
diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp
index 6c24620..30a77d5 100644
--- a/src/core/mac/mac.cpp
+++ b/src/core/mac/mac.cpp
@@ -54,8 +54,8 @@
 namespace ot {
 namespace Mac {
 
-const uint8_t Mac::sMode2Key[] = {0x78, 0x58, 0x16, 0x86, 0xfd, 0xb4, 0x58, 0x0f,
-                                  0xb0, 0x92, 0x54, 0x6a, 0xec, 0xbd, 0x15, 0x66};
+const otMacKey Mac::sMode2Key = {
+    {0x78, 0x58, 0x16, 0x86, 0xfd, 0xb4, 0x58, 0x0f, 0xb0, 0x92, 0x54, 0x6a, 0xec, 0xbd, 0x15, 0x66}};
 
 const otExtAddress Mac::sMode2ExtAddress = {
     {0x35, 0x06, 0xfe, 0xb8, 0x23, 0xd4, 0x87, 0x12},
@@ -67,9 +67,13 @@
 
 const char Mac::sNetworkNameInit[] = "OpenThread";
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+const char Mac::sDomainNameInit[] = "Thread";
+#endif
+
 Mac::Mac(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mEnabled(true)
+    , mEnabled(false)
     , mPendingActiveScan(false)
     , mPendingEnergyScan(false)
     , mPendingTransmitBeacon(false)
@@ -98,6 +102,9 @@
     , mRadioChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
     , mSupportedChannelMask(Get<Radio>().GetSupportedChannelMask())
     , mNetworkName()
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    , mDomainName()
+#endif
     , mScanChannel(Radio::kChannelMin)
     , mScanDuration(0)
     , mScanChannelMask()
@@ -105,12 +112,12 @@
 #if OPENTHREAD_FTD
     , mMaxFrameRetriesIndirect(kDefaultMaxFrameRetriesIndirect)
 #endif
-    , mActiveScanHandler(NULL) // Initialize `mActiveScanHandler` and `mEnergyScanHandler` union
-    , mScanHandlerContext(NULL)
+    , mActiveScanHandler(nullptr) // Initialize `mActiveScanHandler` and `mEnergyScanHandler` union
+    , mScanHandlerContext(nullptr)
     , mSubMac(aInstance)
-    , mOperationTask(aInstance, &Mac::HandleOperationTask, this)
-    , mTimer(aInstance, &Mac::HandleTimer, this)
-    , mOobFrame(NULL)
+    , mOperationTask(aInstance, Mac::HandleOperationTask, this)
+    , mTimer(aInstance, Mac::HandleTimer, this)
+    , mOobFrame(nullptr)
     , mKeyIdMode2FrameCounter(0)
     , mCcaSampleCount(0)
 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
@@ -125,10 +132,15 @@
     ResetCounters();
     mExtendedPanId.Clear();
 
-    mSubMac.Enable();
+    SetEnabled(true);
+    IgnoreError(mSubMac.Enable());
 
+    Get<KeyManager>().UpdateKeyMaterial();
     SetExtendedPanId(static_cast<const ExtendedPanId &>(sExtendedPanidInit));
-    SetNetworkName(sNetworkNameInit);
+    IgnoreError(SetNetworkName(sNetworkNameInit));
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    IgnoreError(SetDomainName(sDomainNameInit));
+#endif
     SetPanId(mPanId);
     SetExtAddress(randomExtAddress);
     SetShortAddress(GetShortAddress());
@@ -138,7 +150,7 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(!IsActiveScanInProgress() && !IsEnergyScanInProgress(), error = OT_ERROR_BUSY);
 
     mActiveScanHandler  = aHandler;
@@ -159,7 +171,7 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(!IsActiveScanInProgress() && !IsEnergyScanInProgress(), error = OT_ERROR_BUSY);
 
     mEnergyScanHandler  = aHandler;
@@ -217,20 +229,20 @@
 {
     otError              error = OT_ERROR_NONE;
     Address              address;
-    const Beacon *       beacon        = NULL;
-    const BeaconPayload *beaconPayload = NULL;
+    const Beacon *       beacon        = nullptr;
+    const BeaconPayload *beaconPayload = nullptr;
     uint16_t             payloadLength;
 
     memset(&aResult, 0, sizeof(ActiveScanResult));
 
-    VerifyOrExit(aBeaconFrame != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aBeaconFrame != nullptr, error = OT_ERROR_INVALID_ARGS);
 
     VerifyOrExit(aBeaconFrame->GetType() == Frame::kFcfFrameBeacon, error = OT_ERROR_PARSE);
     SuccessOrExit(error = aBeaconFrame->GetSrcAddr(address));
     VerifyOrExit(address.IsExtended(), error = OT_ERROR_PARSE);
     aResult.mExtAddress = address.GetExtended();
 
-    aBeaconFrame->GetSrcPanId(aResult.mPanId);
+    IgnoreError(aBeaconFrame->GetSrcPanId(aResult.mPanId));
     aResult.mChannel = aBeaconFrame->GetChannel();
     aResult.mRssi    = aBeaconFrame->GetRssi();
     aResult.mLqi     = aBeaconFrame->GetLqi();
@@ -245,7 +257,7 @@
         aResult.mVersion    = beaconPayload->GetProtocolVersion();
         aResult.mIsJoinable = beaconPayload->IsJoiningPermitted();
         aResult.mIsNative   = beaconPayload->IsNative();
-        static_cast<NetworkName &>(aResult.mNetworkName).Set(beaconPayload->GetNetworkName());
+        IgnoreError(static_cast<NetworkName &>(aResult.mNetworkName).Set(beaconPayload->GetNetworkName()));
         aResult.mExtendedPanId = beaconPayload->GetExtendedPanId();
     }
 
@@ -259,7 +271,7 @@
 {
     otError error;
 
-    VerifyOrExit(mEnabled, error = OT_ERROR_ABORT);
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_ABORT);
 
     error = mScanChannelMask.GetNextChannel(mScanChannel);
 
@@ -278,18 +290,18 @@
     {
         mSubMac.SetPanId(mPanId);
         FinishOperation();
-        ReportActiveScanResult(NULL);
+        ReportActiveScanResult(nullptr);
         PerformNextOperation();
     }
 }
 
 void Mac::ReportActiveScanResult(const RxFrame *aBeaconFrame)
 {
-    VerifyOrExit(mActiveScanHandler != NULL);
+    VerifyOrExit(mActiveScanHandler != nullptr, OT_NOOP);
 
-    if (aBeaconFrame == NULL)
+    if (aBeaconFrame == nullptr)
     {
-        mActiveScanHandler(NULL, mScanHandlerContext);
+        mActiveScanHandler(nullptr, mScanHandlerContext);
     }
     else
     {
@@ -313,7 +325,7 @@
     {
         while (true)
         {
-            mSubMac.Receive(mScanChannel);
+            IgnoreError(mSubMac.Receive(mScanChannel));
             ReportEnergyScanResult(mSubMac.GetRssi());
             SuccessOrExit(error = UpdateScanChannel());
         }
@@ -329,9 +341,9 @@
     {
         FinishOperation();
 
-        if (mEnergyScanHandler != NULL)
+        if (mEnergyScanHandler != nullptr)
         {
-            mEnergyScanHandler(NULL, mScanHandlerContext);
+            mEnergyScanHandler(nullptr, mScanHandlerContext);
         }
 
         PerformNextOperation();
@@ -342,7 +354,7 @@
 {
     EnergyScanResult result;
 
-    VerifyOrExit((mEnergyScanHandler != NULL) && (aRssi != kInvalidRssiValue));
+    VerifyOrExit((mEnergyScanHandler != nullptr) && (aRssi != kInvalidRssiValue), OT_NOOP);
 
     result.mChannel = mScanChannel;
     result.mMaxRssi = aRssi;
@@ -361,7 +373,7 @@
 
 void Mac::SetRxOnWhenIdle(bool aRxOnWhenIdle)
 {
-    VerifyOrExit(mRxOnWhenIdle != aRxOnWhenIdle);
+    VerifyOrExit(mRxOnWhenIdle != aRxOnWhenIdle, OT_NOOP);
 
     mRxOnWhenIdle = aRxOnWhenIdle;
 
@@ -403,11 +415,11 @@
 
     VerifyOrExit(mSupportedChannelMask.ContainsChannel(aChannel), error = OT_ERROR_INVALID_ARGS);
 
-    SuccessOrExit(Get<Notifier>().Update(mPanChannel, aChannel, OT_CHANGED_THREAD_CHANNEL));
+    SuccessOrExit(Get<Notifier>().Update(mPanChannel, aChannel, kEventThreadChannelChanged));
 
     mCcaSuccessRateTracker.Reset();
 
-    VerifyOrExit(!mUsingTemporaryChannel);
+    VerifyOrExit(!mUsingTemporaryChannel, OT_NOOP);
 
     mRadioChannel = mPanChannel;
 
@@ -447,12 +459,12 @@
     ChannelMask newMask = aMask;
 
     newMask.Intersect(ChannelMask(Get<Radio>().GetSupportedChannelMask()));
-    Get<Notifier>().Update(mSupportedChannelMask, newMask, OT_CHANGED_SUPPORTED_CHANNEL_MASK);
+    IgnoreError(Get<Notifier>().Update(mSupportedChannelMask, newMask, kEventSupportedChannelMaskChanged));
 }
 
 otError Mac::SetNetworkName(const char *aNameString)
 {
-    // When setting Network Name from a string, we treat it as `Data`
+    // When setting Network Name from a string, we treat it as `NameData`
     // with `kMaxSize + 1` chars. `NetworkName::Set(data)` will look
     // for null char in the data (within its given size) to calculate
     // the name's length and ensure that the name fits in `kMaxSize`
@@ -460,32 +472,61 @@
     // longer than `kMaxSize` is correctly rejected (returning error
     // `OT_ERROR_INVALID_ARGS`).
 
-    NetworkName::Data data(aNameString, NetworkName::kMaxSize + 1);
+    NameData data(aNameString, NetworkName::kMaxSize + 1);
 
     return SetNetworkName(data);
 }
 
-otError Mac::SetNetworkName(const NetworkName::Data &aName)
+otError Mac::SetNetworkName(const NameData &aNameData)
 {
-    otError error = mNetworkName.Set(aName);
+    otError error = mNetworkName.Set(aNameData);
 
     if (error == OT_ERROR_ALREADY)
     {
-        Get<Notifier>().SignalIfFirst(OT_CHANGED_THREAD_NETWORK_NAME);
+        Get<Notifier>().SignalIfFirst(kEventThreadNetworkNameChanged);
         error = OT_ERROR_NONE;
         ExitNow();
     }
 
     SuccessOrExit(error);
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETWORK_NAME);
+    Get<Notifier>().Signal(kEventThreadNetworkNameChanged);
 
 exit:
     return error;
 }
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+otError Mac::SetDomainName(const char *aNameString)
+{
+    // When setting Domain Name from a string, we treat it as `NameData`
+    // with `kMaxSize + 1` chars. `DomainName::Set(data)` will look
+    // for null char in the data (within its given size) to calculate
+    // the name's length and ensure that the name fits in `kMaxSize`
+    // chars. The `+ 1` ensures that a `aNameString` with length
+    // longer than `kMaxSize` is correctly rejected (returning error
+    // `OT_ERROR_INVALID_ARGS`).
+
+    NameData data(aNameString, DomainName::kMaxSize + 1);
+
+    return SetDomainName(data);
+}
+
+otError Mac::SetDomainName(const NameData &aNameData)
+{
+    otError error = mDomainName.Set(aNameData);
+
+    if (error == OT_ERROR_ALREADY)
+    {
+        error = OT_ERROR_NONE;
+    }
+
+    return error;
+}
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
 void Mac::SetPanId(PanId aPanId)
 {
-    SuccessOrExit(Get<Notifier>().Update(mPanId, aPanId, OT_CHANGED_THREAD_PANID));
+    SuccessOrExit(Get<Notifier>().Update(mPanId, aPanId, kEventThreadPanIdChanged));
     mSubMac.SetPanId(mPanId);
 
 exit:
@@ -494,35 +535,30 @@
 
 void Mac::SetExtendedPanId(const ExtendedPanId &aExtendedPanId)
 {
-    Get<Notifier>().Update(mExtendedPanId, aExtendedPanId, OT_CHANGED_THREAD_EXT_PANID);
+    IgnoreError(Get<Notifier>().Update(mExtendedPanId, aExtendedPanId, kEventThreadExtPanIdChanged));
 }
 
-otError Mac::RequestDirectFrameTransmission(void)
+void Mac::RequestDirectFrameTransmission(void)
 {
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(!mPendingTransmitDataDirect && (mOperation != kOperationTransmitDataDirect), error = OT_ERROR_ALREADY);
+    VerifyOrExit(IsEnabled(), OT_NOOP);
+    VerifyOrExit(!mPendingTransmitDataDirect && (mOperation != kOperationTransmitDataDirect), OT_NOOP);
 
     StartOperation(kOperationTransmitDataDirect);
 
 exit:
-    return error;
+    return;
 }
 
 #if OPENTHREAD_FTD
-otError Mac::RequestIndirectFrameTransmission(void)
+void Mac::RequestIndirectFrameTransmission(void)
 {
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(!mPendingTransmitDataIndirect && (mOperation != kOperationTransmitDataIndirect),
-                 error = OT_ERROR_ALREADY);
+    VerifyOrExit(IsEnabled(), OT_NOOP);
+    VerifyOrExit(!mPendingTransmitDataIndirect && (mOperation != kOperationTransmitDataIndirect), OT_NOOP);
 
     StartOperation(kOperationTransmitDataIndirect);
 
 exit:
-    return error;
+    return;
 }
 #endif
 
@@ -530,8 +566,8 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(aOobFrame != NULL, error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(aOobFrame != nullptr, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(!mPendingTransmitOobFrame && (mOperation != kOperationTransmitOutOfBandFrame),
                  error = OT_ERROR_ALREADY);
 
@@ -547,7 +583,7 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(!mPendingTransmitPoll && (mOperation != kOperationTransmitPoll), error = OT_ERROR_ALREADY);
 
     // We ensure data frame and data poll tx requests are handled in the
@@ -566,7 +602,7 @@
 {
     bool shouldSleep = !mRxOnWhenIdle && !mPromiscuous;
 
-    VerifyOrExit(mOperation == kOperationIdle);
+    VerifyOrExit(mOperation == kOperationIdle, OT_NOOP);
 
 #if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
     if (mShouldDelaySleep)
@@ -585,12 +621,12 @@
 
     if (shouldSleep)
     {
-        mSubMac.Sleep();
+        IgnoreError(mSubMac.Sleep());
         otLogDebgMac("Idle mode: Radio sleeping");
     }
     else
     {
-        mSubMac.Receive(mRadioChannel);
+        IgnoreError(mSubMac.Receive(mRadioChannel));
         otLogDebgMac("Idle mode: Radio receiving on channel %d", mRadioChannel);
     }
 
@@ -668,9 +704,9 @@
 
 void Mac::PerformNextOperation(void)
 {
-    VerifyOrExit(mOperation == kOperationIdle);
+    VerifyOrExit(mOperation == kOperationIdle, OT_NOOP);
 
-    if (!mEnabled)
+    if (!IsEnabled())
     {
         mPendingWaitingForData     = false;
         mPendingTransmitOobFrame   = false;
@@ -773,7 +809,7 @@
         break;
 
     case kOperationWaitingForData:
-        mSubMac.Receive(mRadioChannel);
+        IgnoreError(mSubMac.Receive(mRadioChannel));
         break;
     }
 
@@ -796,8 +832,8 @@
     SuccessOrExit(error = Get<DataPollSender>().GetPollDestinationAddress(dst));
     VerifyOrExit(!dst.IsNone(), error = OT_ERROR_ABORT);
 
-    fcf = Frame::kFcfFrameMacCmd | Frame::kFcfPanidCompression | Frame::kFcfFrameVersion2006 | Frame::kFcfAckRequest |
-          Frame::kFcfSecurityEnabled;
+    fcf = Frame::kFcfFrameMacCmd | Frame::kFcfPanidCompression | Frame::kFcfAckRequest | Frame::kFcfSecurityEnabled;
+    UpdateFrameControlField(/* aIsTimeSync */ false, fcf);
 
     if (dst.IsExtended())
     {
@@ -814,7 +850,7 @@
     aFrame.SetDstPanId(GetPanId());
     aFrame.SetSrcAddr(src);
     aFrame.SetDstAddr(dst);
-    aFrame.SetCommandId(Frame::kMacCmdDataRequest);
+    IgnoreError(aFrame.SetCommandId(Frame::kMacCmdDataRequest));
 
 exit:
     return error;
@@ -827,7 +863,7 @@
     aFrame.InitMacHeader(fcf, Frame::kSecNone);
     aFrame.SetDstPanId(kShortAddrBroadcast);
     aFrame.SetDstAddr(kShortAddrBroadcast);
-    aFrame.SetCommandId(Frame::kMacCmdBeaconRequest);
+    IgnoreError(aFrame.SetCommandId(Frame::kMacCmdBeaconRequest));
 
     otLogInfoMac("Sending Beacon Request");
 }
@@ -836,12 +872,12 @@
 {
     uint8_t        beaconLength;
     uint16_t       fcf;
-    Beacon *       beacon        = NULL;
-    BeaconPayload *beaconPayload = NULL;
+    Beacon *       beacon        = nullptr;
+    BeaconPayload *beaconPayload = nullptr;
 
     fcf = Frame::kFcfFrameBeacon | Frame::kFcfDstAddrNone | Frame::kFcfSrcAddrExt;
     aFrame.InitMacHeader(fcf, Frame::kSecNone);
-    aFrame.SetSrcPanId(mPanId);
+    IgnoreError(aFrame.SetSrcPanId(mPanId));
     aFrame.SetSrcAddr(GetExtAddress());
 
     beacon = reinterpret_cast<Beacon *>(aFrame.GetPayload());
@@ -850,7 +886,7 @@
 
     beaconPayload = reinterpret_cast<BeaconPayload *>(beacon->GetPayload());
 
-    if (Get<KeyManager>().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_BEACONS)
+    if (Get<KeyManager>().IsThreadBeaconEnabled())
     {
         beaconPayload->Init();
 
@@ -878,7 +914,7 @@
 {
     bool shouldSend = false;
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(IsEnabled(), OT_NOOP);
 
     shouldSend = IsBeaconEnabled();
 
@@ -909,15 +945,15 @@
     return (numUnsecurePorts != 0);
 }
 
-void Mac::ProcessTransmitSecurity(TxFrame &aFrame, bool aProcessAesCcm)
+void Mac::ProcessTransmitSecurity(TxFrame &aFrame)
 {
     KeyManager &      keyManager = Get<KeyManager>();
     uint8_t           keyIdMode;
-    const ExtAddress *extAddress = NULL;
+    const ExtAddress *extAddress = nullptr;
 
-    VerifyOrExit(aFrame.GetSecurityEnabled());
+    VerifyOrExit(aFrame.GetSecurityEnabled(), OT_NOOP);
 
-    aFrame.GetKeyIdMode(keyIdMode);
+    IgnoreError(aFrame.GetKeyIdMode(keyIdMode));
 
     switch (keyIdMode)
     {
@@ -934,28 +970,15 @@
         break;
 
     case Frame::kKeyIdMode1:
-        aFrame.SetAesKey(keyManager.GetCurrentMacKey());
-        extAddress = &GetExtAddress();
-
-        // If the frame is marked as a retransmission, `MeshForwarder` which
-        // prepared the frame should set the frame counter and key id to the
-        // same values used in the earlier transmit attempt. For a new frame (not
-        // a retransmission), we get a new frame counter and key id from the key
-        // manager.
-
-        if (!aFrame.IsARetransmission())
-        {
-            aFrame.SetFrameCounter(keyManager.GetMacFrameCounter());
-            keyManager.IncrementMacFrameCounter();
-            aFrame.SetKeyId((keyManager.GetCurrentKeySequence() & 0x7f) + 1);
-        }
-
+        // For MAC Key ID Mode 1, the security frame counter update and CCM* is done at SubMac or Radio depending on
+        // `OT_RADIO_CAPS_TRANSMIT_SEC`.
+        ExitNow();
         break;
 
     case Frame::kKeyIdMode2:
     {
         const uint8_t keySource[] = {0xff, 0xff, 0xff, 0xff};
-        aFrame.SetAesKey(sMode2Key);
+        aFrame.SetAesKey(static_cast<const Key &>(sMode2Key));
         mKeyIdMode2FrameCounter++;
         aFrame.SetFrameCounter(mKeyIdMode2FrameCounter);
         aFrame.SetKeySource(keySource);
@@ -965,14 +988,16 @@
     }
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
-    if (aProcessAesCcm)
-    {
-        aFrame.ProcessTransmitAesCcm(*extAddress);
-    }
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    // Transmit security will be processed after time IE content is updated.
+    VerifyOrExit(aFrame.GetTimeIeOffset() == 0, OT_NOOP);
+#endif
+
+    aFrame.ProcessTransmitAesCcm(*extAddress);
 
 exit:
     return;
@@ -980,13 +1005,12 @@
 
 void Mac::BeginTransmit(void)
 {
-    otError  error                 = OT_ERROR_NONE;
-    bool     applyTransmitSecurity = true;
-    bool     processTransmitAesCcm = true;
-    TxFrame &sendFrame             = mSubMac.GetTransmitFrame();
+    otError  error     = OT_ERROR_NONE;
+    TxFrame &sendFrame = mSubMac.GetTransmitFrame();
 
-    VerifyOrExit(mEnabled, error = OT_ERROR_ABORT);
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_ABORT);
     sendFrame.SetIsARetransmission(false);
+    sendFrame.SetIsSecurityProcessed(false);
 
     switch (mOperation)
     {
@@ -1040,12 +1064,12 @@
 
     case kOperationTransmitOutOfBandFrame:
         sendFrame.CopyFrom(*mOobFrame);
-        applyTransmitSecurity = false;
+        sendFrame.SetIsSecurityProcessed(true);
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
@@ -1056,17 +1080,15 @@
 
         if (timeIeOffset != 0)
         {
-            // Transmit security will be processed after time IE content is updated.
-            processTransmitAesCcm = false;
             sendFrame.SetTimeSyncSeq(Get<TimeSync>().GetTimeSyncSeq());
             sendFrame.SetNetworkTimeOffset(Get<TimeSync>().GetNetworkTimeOffset());
         }
     }
 #endif
 
-    if (applyTransmitSecurity)
+    if (!sendFrame.IsSecurityProcessed())
     {
-        ProcessTransmitSecurity(sendFrame, processTransmitAesCcm);
+        ProcessTransmitSecurity(sendFrame);
     }
 
     mBroadcastTransmitCount = 0;
@@ -1092,7 +1114,7 @@
         // the radio platform aborting the tx operation.
 
         sendFrame.SetLength(0);
-        HandleTransmitDone(sendFrame, NULL, OT_ERROR_ABORT);
+        HandleTransmitDone(sendFrame, nullptr, OT_ERROR_ABORT);
     }
 }
 
@@ -1127,14 +1149,14 @@
     Address   dstAddr;
     Neighbor *neighbor;
 
-    VerifyOrExit(!aFrame.IsEmpty());
+    VerifyOrExit(!aFrame.IsEmpty(), OT_NOOP);
 
-    aFrame.GetDstAddr(dstAddr);
+    IgnoreError(aFrame.GetDstAddr(dstAddr));
     neighbor = Get<Mle::MleRouter>().GetNeighbor(dstAddr);
 
     // Record frame transmission success/failure state (for a neighbor).
 
-    if ((neighbor != NULL) && ackRequested)
+    if ((neighbor != nullptr) && ackRequested)
     {
         bool frameTxSuccess = true;
 
@@ -1179,9 +1201,9 @@
 
     // Update neighbor's RSSI link info from the received Ack.
 
-    if ((aError == OT_ERROR_NONE) && ackRequested && (aAckFrame != NULL) && (neighbor != NULL))
+    if ((aError == OT_ERROR_NONE) && ackRequested && (aAckFrame != nullptr) && (neighbor != nullptr))
     {
-        neighbor->GetLinkInfo().AddRss(GetNoiseFloor(), aAckFrame->GetRssi());
+        neighbor->GetLinkInfo().AddRss(aAckFrame->GetRssi());
     }
 
     // Update MAC counters.
@@ -1233,7 +1255,7 @@
 
         // Determine whether to re-transmit a broadcast frame.
 
-        aFrame.GetDstAddr(dstAddr);
+        IgnoreError(aFrame.GetDstAddr(dstAddr));
 
         if (dstAddr.IsBroadcast())
         {
@@ -1241,7 +1263,7 @@
 
             if (mBroadcastTransmitCount < kTxNumBcast)
             {
-                mSubMac.Send();
+                IgnoreError(mSubMac.Send());
                 ExitNow();
             }
 
@@ -1265,13 +1287,13 @@
         break;
 
     case kOperationTransmitPoll:
-        assert(aFrame.IsEmpty() || aFrame.GetAckRequest());
+        OT_ASSERT(aFrame.IsEmpty() || aFrame.GetAckRequest());
 
-        if ((aError == OT_ERROR_NONE) && (aAckFrame != NULL))
+        if ((aError == OT_ERROR_NONE) && (aAckFrame != nullptr))
         {
             bool framePending = aAckFrame->GetFramePending();
 
-            if (mEnabled && framePending)
+            if (IsEnabled() && framePending)
             {
                 mTimer.Start(kDataPollTimeout);
                 StartOperation(kOperationWaitingForData);
@@ -1303,6 +1325,13 @@
         otDumpDebgMac("TX", aFrame.GetHeader(), aFrame.GetLength());
         FinishOperation();
         Get<MeshForwarder>().HandleSentFrame(aFrame, aError);
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+        if (aError == OT_ERROR_NONE && Get<Mle::Mle>().GetParent().IsEnhancedKeepAliveSupported() &&
+            aFrame.GetSecurityEnabled() && aAckFrame != nullptr)
+        {
+            Get<DataPollSender>().ProcessFrame(*aAckFrame);
+        }
+#endif
         PerformNextOperation();
         break;
 
@@ -1329,13 +1358,15 @@
 #endif
 
     case kOperationTransmitOutOfBandFrame:
+        // count Oob frames
+        mCounters.mTxOther++;
         FinishOperation();
         PerformNextOperation();
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
 exit:
@@ -1375,8 +1406,8 @@
 #endif
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 }
 
@@ -1387,51 +1418,52 @@
     uint8_t           securityLevel;
     uint8_t           keyIdMode;
     uint32_t          frameCounter;
-    uint8_t           nonce[KeyManager::kNonceSize];
+    uint8_t           nonce[Crypto::AesCcm::kNonceSize];
     uint8_t           tag[Frame::kMaxMicSize];
     uint8_t           tagLength;
     uint8_t           keyid;
     uint32_t          keySequence = 0;
-    const uint8_t *   macKey;
+    const Key *       macKey;
     const ExtAddress *extAddress;
     Crypto::AesCcm    aesCcm;
 
     VerifyOrExit(aFrame.GetSecurityEnabled(), error = OT_ERROR_NONE);
 
-    aFrame.GetSecurityLevel(securityLevel);
-    aFrame.GetFrameCounter(frameCounter);
+    IgnoreError(aFrame.GetSecurityLevel(securityLevel));
+    VerifyOrExit(securityLevel == Frame::kSecEncMic32, OT_NOOP);
+
+    IgnoreError(aFrame.GetFrameCounter(frameCounter));
     otLogDebgMac("Rx security - frame counter %u", frameCounter);
 
-    aFrame.GetKeyIdMode(keyIdMode);
+    IgnoreError(aFrame.GetKeyIdMode(keyIdMode));
 
     switch (keyIdMode)
     {
     case Frame::kKeyIdMode0:
-        macKey = keyManager.GetKek();
-        VerifyOrExit(macKey != NULL);
+        macKey     = &keyManager.GetKek();
         extAddress = &aSrcAddr.GetExtended();
         break;
 
     case Frame::kKeyIdMode1:
-        VerifyOrExit(aNeighbor != NULL);
+        VerifyOrExit(aNeighbor != nullptr, OT_NOOP);
 
-        aFrame.GetKeyId(keyid);
+        IgnoreError(aFrame.GetKeyId(keyid));
         keyid--;
 
         if (keyid == (keyManager.GetCurrentKeySequence() & 0x7f))
         {
             keySequence = keyManager.GetCurrentKeySequence();
-            macKey      = keyManager.GetCurrentMacKey();
+            macKey      = &mSubMac.GetCurrentMacKey();
         }
         else if (keyid == ((keyManager.GetCurrentKeySequence() - 1) & 0x7f))
         {
             keySequence = keyManager.GetCurrentKeySequence() - 1;
-            macKey      = keyManager.GetTemporaryMacKey(keySequence);
+            macKey      = &mSubMac.GetPreviousMacKey();
         }
         else if (keyid == ((keyManager.GetCurrentKeySequence() + 1) & 0x7f))
         {
             keySequence = keyManager.GetCurrentKeySequence() + 1;
-            macKey      = keyManager.GetTemporaryMacKey(keySequence);
+            macKey      = &mSubMac.GetNextMacKey();
         }
         else
         {
@@ -1445,14 +1477,14 @@
 
         if (aNeighbor->IsStateValid())
         {
-            VerifyOrExit(keySequence >= aNeighbor->GetKeySequence());
+            VerifyOrExit(keySequence >= aNeighbor->GetKeySequence(), OT_NOOP);
 
             if (keySequence == aNeighbor->GetKeySequence())
             {
                 // If frame counter is one off, then frame is a duplicate.
                 VerifyOrExit((frameCounter + 1) != aNeighbor->GetLinkFrameCounter(), error = OT_ERROR_DUPLICATED);
 
-                VerifyOrExit(frameCounter >= aNeighbor->GetLinkFrameCounter());
+                VerifyOrExit(frameCounter >= aNeighbor->GetLinkFrameCounter(), OT_NOOP);
             }
         }
 
@@ -1461,34 +1493,34 @@
         break;
 
     case Frame::kKeyIdMode2:
-        macKey     = sMode2Key;
+        macKey     = static_cast<const Key *>(&sMode2Key);
         extAddress = static_cast<const ExtAddress *>(&sMode2ExtAddress);
         break;
 
     default:
         ExitNow();
-        break;
+        OT_UNREACHABLE_CODE(break);
     }
 
-    KeyManager::GenerateNonce(*extAddress, frameCounter, securityLevel, nonce);
+    Crypto::AesCcm::GenerateNonce(*extAddress, frameCounter, securityLevel, nonce);
     tagLength = aFrame.GetFooterLength() - Frame::kFcsSize;
 
-    aesCcm.SetKey(macKey, 16);
+    aesCcm.SetKey(*macKey);
 
-    SuccessOrExit(aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce)));
-
+    aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce));
     aesCcm.Header(aFrame.GetHeader(), aFrame.GetHeaderLength());
+
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-    aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), false);
+    aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), Crypto::AesCcm::kDecrypt);
 #else
     // For fuzz tests, execute AES but do not alter the payload
     uint8_t fuzz[OT_RADIO_FRAME_MAX_SIZE];
-    aesCcm.Payload(fuzz, aFrame.GetPayload(), aFrame.GetPayloadLength(), false);
+    aesCcm.Payload(fuzz, aFrame.GetPayload(), aFrame.GetPayloadLength(), Crypto::AesCcm::kDecrypt);
 #endif
-    aesCcm.Finalize(tag, &tagLength);
+    aesCcm.Finalize(tag);
 
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-    VerifyOrExit(memcmp(tag, aFrame.GetFooter(), tagLength) == 0);
+    VerifyOrExit(memcmp(tag, aFrame.GetFooter(), tagLength) == 0, OT_NOOP);
 #endif
 
     if ((keyIdMode == Frame::kKeyIdMode1) && aNeighbor->IsStateValid())
@@ -1524,15 +1556,15 @@
     mCounters.mRxTotal++;
 
     SuccessOrExit(error);
-    VerifyOrExit(aFrame != NULL, error = OT_ERROR_NO_FRAME_RECEIVED);
-    VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(aFrame != nullptr, error = OT_ERROR_NO_FRAME_RECEIVED);
+    VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
 
     // Ensure we have a valid frame before attempting to read any contents of
     // the buffer received from the radio.
     SuccessOrExit(error = aFrame->ValidatePsdu());
 
-    aFrame->GetSrcAddr(srcaddr);
-    aFrame->GetDstAddr(dstaddr);
+    IgnoreError(aFrame->GetSrcAddr(srcaddr));
+    IgnoreError(aFrame->GetDstAddr(dstaddr));
     neighbor = Get<Mle::MleRouter>().GetNeighbor(srcaddr);
 
     // Destination Address Filtering
@@ -1542,21 +1574,23 @@
         break;
 
     case Address::kTypeShort:
-        aFrame->GetDstPanId(panid);
+        IgnoreError(aFrame->GetDstPanId(panid));
         VerifyOrExit((panid == kShortAddrBroadcast || panid == mPanId) &&
                          ((mRxOnWhenIdle && dstaddr.IsBroadcast()) || dstaddr.GetShort() == GetShortAddress()),
                      error = OT_ERROR_DESTINATION_ADDRESS_FILTERED);
 
-        // Allow  multicasts from neighbor routers if FTD
-        if (neighbor == NULL && dstaddr.IsBroadcast() && Get<Mle::MleRouter>().IsFullThreadDevice())
+#if OPENTHREAD_FTD
+        // Allow multicasts from neighbor routers if FTD
+        if (neighbor == nullptr && dstaddr.IsBroadcast() && Get<Mle::MleRouter>().IsFullThreadDevice())
         {
             neighbor = Get<Mle::MleRouter>().GetRxOnlyNeighborRouter(srcaddr);
         }
+#endif
 
         break;
 
     case Address::kTypeExtended:
-        aFrame->GetDstPanId(panid);
+        IgnoreError(aFrame->GetDstPanId(panid));
         VerifyOrExit(panid == mPanId && dstaddr.GetExtended() == GetExtAddress(),
                      error = OT_ERROR_DESTINATION_ADDRESS_FILTERED);
         break;
@@ -1571,7 +1605,7 @@
     case Address::kTypeShort:
         otLogDebgMac("Received frame from short address 0x%04x", srcaddr.GetShort());
 
-        VerifyOrExit(neighbor != NULL, error = OT_ERROR_UNKNOWN_NEIGHBOR);
+        VerifyOrExit(neighbor != nullptr, error = OT_ERROR_UNKNOWN_NEIGHBOR);
 
         srcaddr.SetExtended(neighbor->GetExtAddress());
 
@@ -1594,7 +1628,7 @@
 
                 // Clear any previous link info to ensure the fixed RSSI
                 // value takes effect quickly.
-                if (neighbor != NULL)
+                if (neighbor != nullptr)
                 {
                     neighbor->GetLinkInfo().Clear();
                 }
@@ -1633,7 +1667,7 @@
         // so the duplicate frame will not be passed to next
         // layer (`MeshForwarder`).
 
-        VerifyOrExit(mOperation == kOperationWaitingForData);
+        VerifyOrExit(mOperation == kOperationWaitingForData, OT_NOOP);
 
         // Fall through
 
@@ -1644,11 +1678,11 @@
         ExitNow();
     }
 
-    Get<DataPollSender>().CheckFramePending(*aFrame);
+    Get<DataPollSender>().ProcessFrame(*aFrame);
 
-    if (neighbor != NULL)
+    if (neighbor != nullptr)
     {
-        neighbor->GetLinkInfo().AddRss(GetNoiseFloor(), aFrame->GetRssi());
+        neighbor->GetLinkInfo().AddRss(aFrame->GetRssi());
 
         if (aFrame->GetSecurityEnabled())
         {
@@ -1667,6 +1701,15 @@
             default:
                 ExitNow(error = OT_ERROR_UNKNOWN_NEIGHBOR);
             }
+
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 && OPENTHREAD_FTD
+            // From Thread 1.2, MAC Data Frame can also act as keep-alive message if child supports
+            if (aFrame->GetType() == Frame::kFcfFrameData && !neighbor->IsRxOnWhenIdle() &&
+                neighbor->IsEnhancedKeepAliveSupported())
+            {
+                neighbor->SetLastHeard(TimerMilli::GetNow());
+            }
+#endif
         }
     }
 
@@ -1795,7 +1838,7 @@
     bool    didHandle = false;
     uint8_t commandId;
 
-    aFrame.GetCommandId(commandId);
+    IgnoreError(aFrame.GetCommandId(commandId));
 
     switch (commandId)
     {
@@ -1877,11 +1920,6 @@
 }
 #endif // OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
 
-int8_t Mac::GetNoiseFloor(void)
-{
-    return Get<Radio>().GetReceiveSensitivity();
-}
-
 // LCOV_EXCL_START
 
 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
@@ -1951,7 +1989,7 @@
         break;
     }
 
-    if (aFrame == NULL)
+    if (aFrame == nullptr)
     {
         otLogMac(logLevel, "Frame rx failed, error:%s", otThreadErrorToString(aError));
     }
@@ -1999,10 +2037,10 @@
 {
     uint8_t        offset = 0;
     const uint8_t *base   = aFrame.GetPsdu();
-    const uint8_t *cur    = NULL;
+    const uint8_t *cur    = nullptr;
 
     cur = reinterpret_cast<const uint8_t *>(aFrame.GetTimeIe());
-    VerifyOrExit(cur != NULL);
+    VerifyOrExit(cur != nullptr, OT_NOOP);
 
     cur += sizeof(VendorIeHeader);
     offset = static_cast<uint8_t>(cur - base);
@@ -2012,5 +2050,69 @@
 }
 #endif
 
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+otError Mac::AppendHeaderIe(bool aIsTimeSync, TxFrame &aFrame)
+{
+    OT_UNUSED_VARIABLE(aIsTimeSync);
+
+    const size_t kMaxNumHeaderIe = 3; // TimeSync + Csl + Termination2
+    HeaderIe     ieList[kMaxNumHeaderIe];
+    otError      error   = OT_ERROR_NONE;
+    uint8_t      ieCount = 0;
+
+    VerifyOrExit(aFrame.IsVersion2015() && aFrame.IsIePresent(), OT_NOOP);
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    if (aIsTimeSync)
+    {
+        ieList[ieCount].Init();
+        ieList[ieCount].SetId(Frame::kHeaderIeVendor);
+        ieList[ieCount].SetLength(sizeof(TimeIe));
+        ieCount++;
+    }
+#endif
+
+    if (ieCount > 0)
+    {
+        ieList[ieCount].Init();
+        ieList[ieCount].SetId(Frame::kHeaderIeTermination2);
+        ieList[ieCount].SetLength(0);
+
+        SuccessOrExit(error = aFrame.AppendHeaderIe(ieList, ++ieCount));
+    }
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    if (aIsTimeSync)
+    {
+        uint8_t *cur = aFrame.GetHeaderIe(Frame::kHeaderIeVendor);
+        TimeIe * ie  = reinterpret_cast<TimeIe *>(cur + sizeof(HeaderIe));
+
+        ie->Init();
+    }
+#endif
+
+exit:
+    return error;
+}
+#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+
+void Mac::UpdateFrameControlField(bool aIsTimeSync, uint16_t &aFcf)
+{
+    OT_UNUSED_VARIABLE(aIsTimeSync);
+
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    if (aIsTimeSync)
+    {
+        aFcf |= Frame::kFcfFrameVersion2015 | Frame::kFcfIePresent;
+    }
+    else
+#endif
+#endif
+    {
+        aFcf |= Frame::kFcfFrameVersion2006;
+    }
+}
+
 } // namespace Mac
 } // namespace ot
diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp
index 24f3b11..c2ae35d 100644
--- a/src/core/mac/mac.hpp
+++ b/src/core/mac/mac.hpp
@@ -206,23 +206,15 @@
     /**
      * This method requests a direct data frame transmission.
      *
-     * @retval OT_ERROR_NONE           Frame transmission request is scheduled successfully.
-     * @retval OT_ERROR_ALREADY        MAC is busy sending earlier transmission request.
-     * @retval OT_ERROR_INVALID_STATE  The MAC layer is not enabled.
-     *
      */
-    otError RequestDirectFrameTransmission(void);
+    void RequestDirectFrameTransmission(void);
 
 #if OPENTHREAD_FTD
     /**
      * This method requests an indirect data frame transmission.
      *
-     * @retval OT_ERROR_NONE           Frame transmission request is scheduled successfully.
-     * @retval OT_ERROR_ALREADY        MAC is busy sending earlier transmission request.
-     * @retval OT_ERROR_INVALID_STATE  The MAC layer is not enabled.
-     *
      */
-    otError RequestIndirectFrameTransmission(void);
+    void RequestIndirectFrameTransmission(void);
 #endif
 
     /**
@@ -235,7 +227,7 @@
      * @retval OT_ERROR_NONE           Successfully scheduled the frame transmission.
      * @retval OT_ERROR_ALREADY        MAC layer is busy sending a previously requested frame.
      * @retval OT_ERROR_INVALID_STATE  The MAC layer is not enabled.
-     * @retval OT_ERROR_INVALID_ARGS   The argument @p aOobFrame is NULL.
+     * @retval OT_ERROR_INVALID_ARGS   The argument @p aOobFrame is nullptr.
      *
      */
     otError RequestOutOfBandFrameTransmission(otRadioFrame *aOobFrame);
@@ -367,7 +359,39 @@
      * @retval OT_ERROR_INVALID_ARGS   Given name is too long.
      *
      */
-    otError SetNetworkName(const NetworkName::Data &aNameData);
+    otError SetNetworkName(const NameData &aNameData);
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    /**
+     * This method returns the Thread Domain Name.
+     *
+     * @returns The Thread Domain Name.
+     *
+     */
+    const DomainName &GetDomainName(void) const { return mDomainName; }
+
+    /**
+     * This method sets the Thread Domain Name.
+     *
+     * @param[in]  aNameString   A pointer to a string character array. Must be null terminated.
+     *
+     * @retval OT_ERROR_NONE           Successfully set the Thread Domain Name.
+     * @retval OT_ERROR_INVALID_ARGS   Given name is too long.
+     *
+     */
+    otError SetDomainName(const char *aNameString);
+
+    /**
+     * This method sets the Thread Domain Name.
+     *
+     * @param[in]  aNameData     A name data (pointer to char buffer and length).
+     *
+     * @retval OT_ERROR_NONE           Successfully set the Thread Domain Name.
+     * @retval OT_ERROR_INVALID_ARGS   Given name is too long.
+     *
+     */
+    otError SetDomainName(const NameData &aNameData);
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
 
     /**
      * This method returns the IEEE 802.15.4 PAN ID.
@@ -441,7 +465,7 @@
     /**
      * This method is called to handle a received frame.
      *
-     * @param[in]  aFrame  A pointer to the received frame, or NULL if the receive operation was aborted.
+     * @param[in]  aFrame  A pointer to the received frame, or nullptr if the receive operation was aborted.
      * @param[in]  aError  OT_ERROR_NONE when successfully received a frame,
      *                     OT_ERROR_ABORT when reception was aborted and a frame was not received.
      *
@@ -464,7 +488,7 @@
      * of a frame transmission request, this method is invoked on all frame transmission attempts.
      *
      * @param[in] aFrame      The transmitted frame.
-     * @param[in] aAckFrame   A pointer to the ACK frame, or NULL if no ACK was received.
+     * @param[in] aAckFrame   A pointer to the ACK frame, or nullptr if no ACK was received.
      * @param[in] aError      OT_ERROR_NONE when the frame was transmitted successfully,
      *                        OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
      *                        OT_ERROR_CHANNEL_ACCESS_FAILURE tx failed due to activity on the channel,
@@ -484,7 +508,7 @@
      * This method is called to handle transmit events.
      *
      * @param[in]  aFrame      The frame that was transmitted.
-     * @param[in]  aAckFrame   A pointer to the ACK frame, NULL if no ACK was received.
+     * @param[in]  aAckFrame   A pointer to the ACK frame, nullptr if no ACK was received.
      * @param[in]  aError      OT_ERROR_NONE when the frame was transmitted successfully,
      *                         OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
      *                         OT_ERROR_CHANNEL_ACCESS_FAILURE when the tx failed due to activity on the channel,
@@ -529,7 +553,7 @@
      * This method registers a callback to provide received raw IEEE 802.15.4 frames.
      *
      * @param[in]  aPcapCallback     A pointer to a function that is called when receiving an IEEE 802.15.4 link frame
-     * or NULL to disable the callback.
+     * or nullptr to disable the callback.
      * @param[in]  aCallbackContext  A pointer to application-specific context.
      *
      */
@@ -609,7 +633,7 @@
      * @returns The noise floor value in dBm.
      *
      */
-    int8_t GetNoiseFloor(void);
+    int8_t GetNoiseFloor(void) { return mSubMac.GetNoiseFloor(); }
 
     /**
      * This method returns the current CCA (Clear Channel Assessment) failure rate.
@@ -639,6 +663,34 @@
      */
     bool IsEnabled(void) const { return mEnabled; }
 
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+    /**
+     * This method appends header IEs to a TX-frame according to its
+     * frame control field and if time sync is enabled.
+     *
+     * @param[in]      aIsTimeSync  A boolean indicates if time sync is being used.
+     * @param[in,out]  aFrame       A reference to the TX-frame to which the IEs will be appended.
+     *
+     * @retval OT_ERROR_NONE       If append header IEs successfully.
+     * @retval OT_ERROR_NOT_FOUND  If cannot find header IE position in the frame.
+     *
+     */
+    static otError AppendHeaderIe(bool aIsTimeSync, TxFrame &aFrame);
+#endif
+
+    /**
+     * This method updates frame control field.
+     *
+     * If the frame would contain header IEs, IE present field would be set.
+     * If this is a csl transmission frame or header IE is present in this frame,
+     * the version should be set to 2015. Otherwise, the version would be set to 2006.
+     *
+     * @param[in]   aIsTimeSync  A boolean indicates if time sync is being used.
+     * @param[out]  aFcf         A reference to the frame control field to set.
+     *
+     */
+    static void UpdateFrameControlField(bool aIsTimeSync, uint16_t &aFcf);
+
 private:
     enum
     {
@@ -685,19 +737,7 @@
     };
 #endif // OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
 
-    /**
-     * This method processes transmit security on the frame which is going to be sent.
-     *
-     * This method prepares the frame, fills Mac auxiliary header, and perform AES CCM immediately in most cases
-     * (depends on @p aProcessAesCcm). If aProcessAesCcm is False, it probably means that some content in the frame
-     * will be updated just before transmission, so AES CCM will be performed after that (before transmission).
-     *
-     * @param[in]  aFrame          A reference to the MAC frame buffer which is going to be sent.
-     * @param[in]  aProcessAesCcm  TRUE to perform AES CCM immediately, FALSE otherwise.
-     *
-     */
-    void ProcessTransmitSecurity(TxFrame &aFrame, bool aProcessAesCcm);
-
+    void    ProcessTransmitSecurity(TxFrame &aFrame);
     otError ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neighbor *aNeighbor);
     void    UpdateIdleMode(void);
     void    StartOperation(Operation aOperation);
@@ -733,10 +773,11 @@
 
     static const char *OperationToString(Operation aOperation);
 
-    static const uint8_t         sMode2Key[];
+    static const otMacKey        sMode2Key;
     static const otExtAddress    sMode2ExtAddress;
     static const otExtendedPanId sExtendedPanidInit;
     static const char            sNetworkNameInit[];
+    static const char            sDomainNameInit[];
 
     bool mEnabled : 1;
     bool mPendingActiveScan : 1;
@@ -769,10 +810,13 @@
     ChannelMask   mSupportedChannelMask;
     ExtendedPanId mExtendedPanId;
     NetworkName   mNetworkName;
-    uint8_t       mScanChannel;
-    uint16_t      mScanDuration;
-    ChannelMask   mScanChannelMask;
-    uint8_t       mMaxFrameRetriesDirect;
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    DomainName mDomainName;
+#endif
+    uint8_t     mScanChannel;
+    uint16_t    mScanDuration;
+    ChannelMask mScanChannelMask;
+    uint8_t     mMaxFrameRetriesDirect;
 #if OPENTHREAD_FTD
     uint8_t mMaxFrameRetriesIndirect;
 #endif
diff --git a/src/core/mac/mac_filter.cpp b/src/core/mac/mac_filter.cpp
index 82703c3..80dd275 100644
--- a/src/core/mac/mac_filter.cpp
+++ b/src/core/mac/mac_filter.cpp
@@ -41,61 +41,46 @@
 namespace Mac {
 
 Filter::Filter(void)
-    : mAddressMode(OT_MAC_FILTER_ADDRESS_MODE_DISABLED)
+    : mMode(kModeRssInOnly)
     , mDefaultRssIn(kFixedRssDisabled)
 {
-    for (FilterEntry *entry = &mFilterEntries[0]; entry < OT_ARRAY_END(mFilterEntries); entry++)
+    for (FilterEntry &entry : mFilterEntries)
     {
-        entry->mFiltered = false;
-        entry->mRssIn    = kFixedRssDisabled;
+        entry.mFiltered = false;
+        entry.mRssIn    = kFixedRssDisabled;
     }
 }
 
 Filter::FilterEntry *Filter::FindEntry(const ExtAddress &aExtAddress)
 {
-    FilterEntry *entry;
+    FilterEntry *rval = nullptr;
 
-    for (entry = &mFilterEntries[0]; entry < OT_ARRAY_END(mFilterEntries); entry++)
+    for (FilterEntry &entry : mFilterEntries)
     {
-        if (entry->IsInUse() && (aExtAddress == entry->mExtAddress))
+        if (entry.IsInUse() && (aExtAddress == entry.mExtAddress))
         {
-            ExitNow();
+            ExitNow(rval = &entry);
         }
     }
 
-    entry = NULL;
-
 exit:
-    return entry;
+    return rval;
 }
 
 Filter::FilterEntry *Filter::FindAvailableEntry(void)
 {
-    FilterEntry *entry;
+    FilterEntry *rval = nullptr;
 
-    for (entry = &mFilterEntries[0]; entry < OT_ARRAY_END(mFilterEntries); entry++)
+    for (FilterEntry &entry : mFilterEntries)
     {
-        VerifyOrExit(entry->IsInUse());
+        if (!entry.IsInUse())
+        {
+            ExitNow(rval = &entry);
+        }
     }
 
-    entry = NULL;
-
 exit:
-    return entry;
-}
-
-otError Filter::SetAddressMode(otMacFilterAddressMode aMode)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(aMode == OT_MAC_FILTER_ADDRESS_MODE_DISABLED || aMode == OT_MAC_FILTER_ADDRESS_MODE_WHITELIST ||
-                     aMode == OT_MAC_FILTER_ADDRESS_MODE_BLACKLIST,
-                 error = OT_ERROR_INVALID_ARGS);
-
-    mAddressMode = aMode;
-
-exit:
-    return error;
+    return rval;
 }
 
 otError Filter::AddAddress(const ExtAddress &aExtAddress)
@@ -103,40 +88,33 @@
     otError      error = OT_ERROR_NONE;
     FilterEntry *entry = FindEntry(aExtAddress);
 
-    if (entry == NULL)
+    if (entry == nullptr)
     {
-        VerifyOrExit((entry = FindAvailableEntry()) != NULL, error = OT_ERROR_NO_BUFS);
+        VerifyOrExit((entry = FindAvailableEntry()) != nullptr, error = OT_ERROR_NO_BUFS);
         entry->mExtAddress = aExtAddress;
     }
 
-    VerifyOrExit(!entry->mFiltered, error = OT_ERROR_ALREADY);
     entry->mFiltered = true;
 
 exit:
     return error;
 }
 
-otError Filter::RemoveAddress(const ExtAddress &aExtAddress)
+void Filter::RemoveAddress(const ExtAddress &aExtAddress)
 {
-    otError      error = OT_ERROR_NONE;
     FilterEntry *entry = FindEntry(aExtAddress);
 
-    if (entry == NULL || !entry->mFiltered)
+    if (entry != nullptr)
     {
-        ExitNow(error = OT_ERROR_NOT_FOUND);
+        entry->mFiltered = false;
     }
-
-    entry->mFiltered = false;
-
-exit:
-    return error;
 }
 
 void Filter::ClearAddresses(void)
 {
-    for (FilterEntry *entry = &mFilterEntries[0]; entry < OT_ARRAY_END(mFilterEntries); entry++)
+    for (FilterEntry &entry : mFilterEntries)
     {
-        entry->mFiltered = false;
+        entry.mFiltered = false;
     }
 }
 
@@ -161,22 +139,17 @@
     return error;
 }
 
-otError Filter::AddRssIn(const ExtAddress *aExtAddress, int8_t aRss)
+otError Filter::AddRssIn(const ExtAddress &aExtAddress, int8_t aRss)
 {
     otError      error = OT_ERROR_NONE;
-    FilterEntry *entry;
+    FilterEntry *entry = FindEntry(aExtAddress);
 
-    // Set the default RssIn when aExtAddress is not given (NULL)
-    VerifyOrExit(aExtAddress != NULL, mDefaultRssIn = aRss);
-
-    entry = FindEntry(*aExtAddress);
-
-    if (entry == NULL)
+    if (entry == nullptr)
     {
         entry = FindAvailableEntry();
-        VerifyOrExit(entry != NULL, error = OT_ERROR_NO_BUFS);
+        VerifyOrExit(entry != nullptr, error = OT_ERROR_NO_BUFS);
 
-        entry->mExtAddress = *aExtAddress;
+        entry->mExtAddress = aExtAddress;
     }
 
     entry->mRssIn = aRss;
@@ -185,27 +158,23 @@
     return error;
 }
 
-otError Filter::RemoveRssIn(const ExtAddress *aExtAddress)
+void Filter::RemoveRssIn(const ExtAddress &aExtAddress)
 {
-    otError      error = OT_ERROR_NONE;
-    FilterEntry *entry;
+    FilterEntry *entry = FindEntry(aExtAddress);
 
-    // If no aExtAddress is given, remove default RssIn
-    VerifyOrExit(aExtAddress != NULL, mDefaultRssIn = kFixedRssDisabled);
+    VerifyOrExit(entry != nullptr, OT_NOOP);
 
-    entry = FindEntry(*aExtAddress);
-    VerifyOrExit(entry != NULL, error = OT_ERROR_NOT_FOUND);
     entry->mRssIn = kFixedRssDisabled;
 
 exit:
-    return error;
+    return;
 }
 
-void Filter::ClearRssIn(void)
+void Filter::ClearAllRssIn(void)
 {
-    for (FilterEntry *entry = &mFilterEntries[0]; entry < OT_ARRAY_END(mFilterEntries); entry++)
+    for (FilterEntry &entry : mFilterEntries)
     {
-        entry->mRssIn = kFixedRssDisabled;
+        entry.mRssIn = kFixedRssDisabled;
     }
 
     mDefaultRssIn = kFixedRssDisabled;
@@ -246,20 +215,31 @@
 {
     otError      error = OT_ERROR_NONE;
     FilterEntry *entry = FindEntry(aExtAddress);
+    bool         isInFilterList;
 
     // Use the default RssIn setting for all receiving messages first.
     aRss = mDefaultRssIn;
 
-    if (mAddressMode == OT_MAC_FILTER_ADDRESS_MODE_WHITELIST)
+    // In whitelist mode, entry must be present in the list, in
+    // blacklist mode it must not be present.
+
+    isInFilterList = (entry != nullptr) && entry->mFiltered;
+
+    switch (mMode)
     {
-        VerifyOrExit(entry != NULL && entry->mFiltered, error = OT_ERROR_ADDRESS_FILTERED);
-    }
-    else if (mAddressMode == OT_MAC_FILTER_ADDRESS_MODE_BLACKLIST)
-    {
-        VerifyOrExit(entry == NULL || !entry->mFiltered, error = OT_ERROR_ADDRESS_FILTERED);
+    case kModeRssInOnly:
+        break;
+
+    case kModeWhitelist:
+        VerifyOrExit(isInFilterList, error = OT_ERROR_ADDRESS_FILTERED);
+        break;
+
+    case kModeBlacklist:
+        VerifyOrExit(!isInFilterList, error = OT_ERROR_ADDRESS_FILTERED);
+        break;
     }
 
-    if ((entry != NULL) && (entry->mRssIn != kFixedRssDisabled))
+    if ((entry != nullptr) && (entry->mRssIn != kFixedRssDisabled))
     {
         aRss = entry->mRssIn;
     }
diff --git a/src/core/mac/mac_filter.hpp b/src/core/mac/mac_filter.hpp
index 0480861..9d49875 100644
--- a/src/core/mac/mac_filter.hpp
+++ b/src/core/mac/mac_filter.hpp
@@ -73,10 +73,20 @@
      */
     typedef otMacFilterIterator Iterator;
 
-    enum
+    /**
+     * This enumeration type represents the MAC Filter mode.
+     *
+     */
+    enum Mode : uint8_t
     {
-        kMaxEntries       = OPENTHREAD_CONFIG_MAC_FILTER_SIZE, ///< The maximum number of filter entries.
-        kFixedRssDisabled = OT_MAC_FILTER_FIXED_RSS_DISABLED,  ///< Value to indicate no fixed RSS is set.
+        kModeRssInOnly = OT_MAC_FILTER_ADDRESS_MODE_DISABLED,  ///< No address filtering. RSS-In update only.
+        kModeWhitelist = OT_MAC_FILTER_ADDRESS_MODE_WHITELIST, ///< Enable whitelist address filter mode.
+        kModeBlacklist = OT_MAC_FILTER_ADDRESS_MODE_BLACKLIST, ///< Enable blacklist address filter mode.
+    };
+
+    enum : int8_t
+    {
+        kFixedRssDisabled = OT_MAC_FILTER_FIXED_RSS_DISABLED, ///< Value to indicate no fixed RSS is set.
     };
 
     /**
@@ -86,23 +96,20 @@
     Filter(void);
 
     /**
-     * This function gets the address mode of the filter.
+     * This method gets the MAC Filter mode.
      *
-     * @returns  the address mode.
+     * @returns  the Filter mode.
      *
      */
-    otMacFilterAddressMode GetAddressMode(void) const { return mAddressMode; }
+    Mode GetMode(void) const { return mMode; }
 
     /**
-     * This function sets the address mode of the filter.
+     * This method sets the address mode of the filter.
      *
-     * @param[in]  aMode  The address mode to set.
-     *
-     * @retval OT_ERROR_NONE           Successfully set the AddressFilter mode.
-     * @retval OT_ERROR_INVALID_ARGS   @p aMode is not valid address mode.
+     * @param[in]  aMode  The new Filter mode.
      *
      */
-    otError SetAddressMode(otMacFilterAddressMode aMode);
+    void SetMode(Mode aMode) { mMode = aMode; }
 
     /**
      * This method adds an Extended Address to filter.
@@ -110,7 +117,6 @@
      * @param[in]  aExtAddress  A reference to the Extended Address.
      *
      * @retval OT_ERROR_NONE           Successfully added @p aExtAddress to the filter.
-     * @retval OT_ERROR_ALREADY        If @p aExtAddress was already in the Filter.
      * @retval OT_ERROR_NO_BUFS        No available entry exists.
      *
      */
@@ -119,13 +125,12 @@
     /**
      * This method removes an Extended Address from the filter.
      *
-     * @param[in]  aExtAddress  A reference to the Extended Address.
+     * No action is performed if there is no existing entry in the filter list matching the given Extended Address.
      *
-     * @retval OT_ERROR_NONE           Successfully removed @p aExtAddress from the filter.
-     * @retval OT_ERROR_NOT_FOUND      @p aExtAddress is not in the filter.
+     * @param[in]  aExtAddress  A reference to the Extended Address to remove.
      *
      */
-    otError RemoveAddress(const ExtAddress &aExtAddress);
+    void RemoveAddress(const ExtAddress &aExtAddress);
 
     /**
      * This method clears all Extended Addresses from the filter.
@@ -147,38 +152,49 @@
     otError GetNextAddress(Iterator &aIterator, Entry &aEntry) const;
 
     /**
-     * This method sets the received signal strength for the messages from the Extended Address.
-     * The default received signal strength for all received messages would be set if no Extended Address is specified.
+     * This method adds a fixed received signal strength entry for the messages from a given Extended Address.
      *
-     * @param[in]  aExtAddress  A pointer to the Extended Address, or NULL to set the default received signal strength.
+     * @param[in]  aExtAddress  An Extended Address
      * @param[in]  aRss         The received signal strength to set.
      *
-     * @retval OT_ERROR_NONE     Successfully set @p aRss for @p aExtAddress, or
-     *                           set the default @p aRss for all received messages if @p aExtAddress is NULL.
+     * @retval OT_ERROR_NONE     Successfully set @p aRss for @p aExtAddress.
      * @retval OT_ERROR_NO_BUFS  No available entry exists.
      *
      */
-    otError AddRssIn(const ExtAddress *aExtAddress, int8_t aRss);
+    otError AddRssIn(const ExtAddress &aExtAddress, int8_t aRss);
 
     /**
-     * This method removes the received signal strength setting for the received messages from the Extended Address,
-     * or removes the default received signal strength setting if no Extended Address is specified.
+     * This method removes a fixed received signal strength entry for a given Extended Address.
      *
-     * @param[in]  aExtAddress  A pointer to the Extended Address.
+     * No action is performed if there is no existing entry in the filter list matching the given Extended Address.
      *
-     * @retval OT_ERROR_NONE       Successfully removed the received signal strength setting for the received
-     *                             messages from @p aExtAddress or removed the default received signal strength
-     *                             setting if @p aExtAddress is NULL.
-     * @retval OT_ERROR_NOT_FOUND  @p aExtAddress is not in the RssIn filter if it is not NULL.
+     * @param[in]  aExtAddress   A Extended Address.
      *
      */
-    otError RemoveRssIn(const ExtAddress *aExtAddress);
+    void RemoveRssIn(const ExtAddress &aExtAddress);
 
     /**
-     * This method clears all the received signal strength settings.
+     * This method sets the default received signal strength.
+     *
+     * The default RSS value is used for all received frames from addresses for which there is no explicit RSS-IN entry
+     * in the Filter list (added using `AddRssIn()`).
+     *
+     * @param[in]  aRss  The default received signal strength to set.
      *
      */
-    void ClearRssIn(void);
+    void SetDefaultRssIn(int8_t aRss) { mDefaultRssIn = aRss; }
+
+    /**
+     * This method clears the default received signal strength.
+     *
+     */
+    void ClearDefaultRssIn(void) { mDefaultRssIn = kFixedRssDisabled; }
+
+    /**
+     * This method clears all the received signal strength settings (inlcuding the default RSS-In).
+     *
+     */
+    void ClearAllRssIn(void);
 
     /**
      * This method iterates through RssIn filter entry.
@@ -209,6 +225,11 @@
     otError Apply(const ExtAddress &aExtAddress, int8_t &aRss);
 
 private:
+    enum
+    {
+        kMaxEntries = OPENTHREAD_CONFIG_MAC_FILTER_SIZE, // The maximum number of filter entries.
+    };
+
     struct FilterEntry
     {
         bool       mFiltered;   // Indicates whether or not this entry is filtered (whitelist/blacklist modes).
@@ -221,9 +242,9 @@
     FilterEntry *FindAvailableEntry(void);
     FilterEntry *FindEntry(const ExtAddress &aExtAddress);
 
-    otMacFilterAddressMode mAddressMode;
-    int8_t                 mDefaultRssIn;
-    FilterEntry            mFilterEntries[kMaxEntries];
+    Mode        mMode;
+    int8_t      mDefaultRssIn;
+    FilterEntry mFilterEntries[kMaxEntries];
 };
 
 /**
diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp
index c475fa6..1e23c53 100644
--- a/src/core/mac/mac_frame.cpp
+++ b/src/core/mac/mac_frame.cpp
@@ -37,94 +37,31 @@
 
 #include "common/code_utils.hpp"
 #include "common/debug.hpp"
+#if !OPENTHREAD_RADIO || OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
 #include "crypto/aes_ccm.hpp"
-#include "thread/key_manager.hpp"
+#endif
 
 namespace ot {
 namespace Mac {
 
 void Frame::InitMacHeader(uint16_t aFcf, uint8_t aSecurityControl)
 {
-    uint8_t *bytes  = GetPsdu();
-    uint8_t  length = 0;
+    uint8_t *bytes = GetPsdu();
+    uint8_t  length;
 
     // Frame Control Field
     Encoding::LittleEndian::WriteUint16(aFcf, bytes);
-    length += kFcfSize;
 
-    // Sequence Number
-    length += kDsnSize;
-
-    // Destination PAN + Address
-    switch (aFcf & kFcfDstAddrMask)
-    {
-    case kFcfDstAddrNone:
-        break;
-
-    case kFcfDstAddrShort:
-        length += sizeof(PanId) + sizeof(ShortAddress);
-        break;
-
-    case kFcfDstAddrExt:
-        length += sizeof(PanId) + sizeof(ExtAddress);
-        break;
-
-    default:
-        assert(false);
-    }
-
-    // Source PAN
-    if (IsSrcPanIdPresent(aFcf))
-    {
-        length += sizeof(PanId);
-    }
-
-    // Source Address
-    switch (aFcf & kFcfSrcAddrMask)
-    {
-    case kFcfSrcAddrNone:
-        break;
-
-    case kFcfSrcAddrShort:
-        length += sizeof(ShortAddress);
-        break;
-
-    case kFcfSrcAddrExt:
-        length += sizeof(ExtAddress);
-        break;
-
-    default:
-        assert(false);
-    }
+    length = CalculateAddrFieldSize(aFcf);
+    OT_ASSERT(length != kInvalidSize);
 
     // Security Header
     if (aFcf & kFcfSecurityEnabled)
     {
         bytes[length] = aSecurityControl;
 
-        if (aSecurityControl & kSecLevelMask)
-        {
-            length += kSecurityControlSize + kFrameCounterSize;
-        }
-
-        switch (aSecurityControl & kKeyIdModeMask)
-        {
-        case kKeyIdMode0:
-            length += kKeySourceSizeMode0;
-            break;
-
-        case kKeyIdMode1:
-            length += kKeySourceSizeMode1 + kKeyIndexSize;
-            break;
-
-        case kKeyIdMode2:
-            length += kKeySourceSizeMode2 + kKeyIndexSize;
-            break;
-
-        case kKeyIdMode3:
-            length += kKeySourceSizeMode3 + kKeyIndexSize;
-            break;
-        }
+        length += CalculateSecurityHeaderSize(aSecurityControl);
+        length += CalculateMicSize(aSecurityControl);
     }
 
     // Command ID
@@ -133,7 +70,10 @@
         length += kCommandIdSize;
     }
 
-    SetPsduLength(length + GetFooterLength());
+    // FCS
+    length += GetFcsSize();
+
+    SetPsduLength(length);
 }
 
 uint16_t Frame::GetFrameControlField(void) const
@@ -190,6 +130,38 @@
     return index;
 }
 
+bool Frame::IsDstPanIdPresent(uint16_t aFcf)
+{
+    bool present = true;
+
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+    if (IsVersion2015(aFcf))
+    {
+        switch (aFcf & (kFcfDstAddrMask | kFcfSrcAddrMask | kFcfPanidCompression))
+        {
+        case (kFcfDstAddrNone | kFcfSrcAddrNone):
+        case (kFcfDstAddrExt | kFcfSrcAddrNone | kFcfPanidCompression):
+        case (kFcfDstAddrShort | kFcfSrcAddrNone | kFcfPanidCompression):
+        case (kFcfDstAddrNone | kFcfSrcAddrExt):
+        case (kFcfDstAddrNone | kFcfSrcAddrShort):
+        case (kFcfDstAddrNone | kFcfSrcAddrExt | kFcfPanidCompression):
+        case (kFcfDstAddrNone | kFcfSrcAddrShort | kFcfPanidCompression):
+        case (kFcfDstAddrExt | kFcfSrcAddrExt | kFcfPanidCompression):
+            present = false;
+            break;
+        default:
+            break;
+        }
+    }
+    else
+#endif
+    {
+        present = IsDstAddrPresent(aFcf);
+    }
+
+    return present;
+}
+
 otError Frame::GetDstPanId(PanId &aPanId) const
 {
     otError error = OT_ERROR_NONE;
@@ -206,13 +178,17 @@
 {
     uint8_t index = FindDstPanIdIndex();
 
-    assert(index != kInvalidIndex);
+    OT_ASSERT(index != kInvalidIndex);
     Encoding::LittleEndian::WriteUint16(aPanId, GetPsdu() + index);
 }
 
 uint8_t Frame::FindDstAddrIndex(void) const
 {
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+    return kFcfSize + kDsnSize + (IsDstPanIdPresent() ? sizeof(PanId) : 0);
+#else
     return kFcfSize + kDsnSize + sizeof(PanId);
+#endif
 }
 
 otError Frame::GetDstAddr(Address &aAddress) const
@@ -243,7 +219,7 @@
 
 void Frame::SetDstAddr(ShortAddress aShortAddress)
 {
-    assert((GetFrameControlField() & kFcfDstAddrMask) == kFcfDstAddrShort);
+    OT_ASSERT((GetFrameControlField() & kFcfDstAddrMask) == kFcfDstAddrShort);
     Encoding::LittleEndian::WriteUint16(aShortAddress, GetPsdu() + FindDstAddrIndex());
 }
 
@@ -251,8 +227,8 @@
 {
     uint8_t index = FindDstAddrIndex();
 
-    assert((GetFrameControlField() & kFcfDstAddrMask) == kFcfDstAddrExt);
-    assert(index != kInvalidIndex);
+    OT_ASSERT((GetFrameControlField() & kFcfDstAddrMask) == kFcfDstAddrExt);
+    OT_ASSERT(index != kInvalidIndex);
 
     aExtAddress.CopyTo(GetPsdu() + index, ExtAddress::kReverseByteOrder);
 }
@@ -270,8 +246,8 @@
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 }
 
@@ -305,7 +281,7 @@
     return index;
 }
 
-bool Frame::IsSrcPanIdPresent(uint16_t aFcf) const
+bool Frame::IsSrcPanIdPresent(uint16_t aFcf)
 {
     bool srcPanIdPresent = false;
 
@@ -318,7 +294,7 @@
         //  Dest Pan ID:        Present
         //  Src Pan ID:         Not Present
         //  Pan ID Compression: 0
-        if ((aFcf & kFcfFrameVersionMask) != kFcfFrameVersion2015 || (aFcf & kFcfDstAddrMask) != kFcfDstAddrExt ||
+        if (!IsVersion2015(aFcf) || (aFcf & kFcfDstAddrMask) != kFcfDstAddrExt ||
             (aFcf & kFcfSrcAddrMask) != kFcfSrcAddrExt)
 #endif
         {
@@ -361,15 +337,21 @@
     // Frame Control Field and Sequence Number
     index += kFcfSize + kDsnSize;
 
-    // Destination PAN + Address
+    // Destination PAN
+    if (IsDstPanIdPresent(fcf))
+    {
+        index += sizeof(PanId);
+    }
+
+    // Destination Address
     switch (fcf & kFcfDstAddrMask)
     {
     case kFcfDstAddrShort:
-        index += sizeof(PanId) + sizeof(ShortAddress);
+        index += sizeof(ShortAddress);
         break;
 
     case kFcfDstAddrExt:
-        index += sizeof(PanId) + sizeof(ExtAddress);
+        index += sizeof(ExtAddress);
         break;
     }
 
@@ -413,8 +395,8 @@
 {
     uint8_t index = FindSrcAddrIndex();
 
-    assert((GetFrameControlField() & kFcfSrcAddrMask) == kFcfSrcAddrShort);
-    assert(index != kInvalidIndex);
+    OT_ASSERT((GetFrameControlField() & kFcfSrcAddrMask) == kFcfSrcAddrShort);
+    OT_ASSERT(index != kInvalidIndex);
 
     Encoding::LittleEndian::WriteUint16(aShortAddress, GetPsdu() + index);
 }
@@ -423,8 +405,8 @@
 {
     uint8_t index = FindSrcAddrIndex();
 
-    assert((GetFrameControlField() & kFcfSrcAddrMask) == kFcfSrcAddrExt);
-    assert(index != kInvalidIndex);
+    OT_ASSERT((GetFrameControlField() & kFcfSrcAddrMask) == kFcfSrcAddrExt);
+    OT_ASSERT(index != kInvalidIndex);
 
     aExtAddress.CopyTo(GetPsdu() + index, ExtAddress::kReverseByteOrder);
 }
@@ -442,50 +424,40 @@
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 }
 
+otError Frame::GetSecurityControlField(uint8_t &aSecurityControlField) const
+{
+    otError error = OT_ERROR_NONE;
+    uint8_t index = FindSecurityHeaderIndex();
+
+    VerifyOrExit(index != kInvalidIndex, error = OT_ERROR_PARSE);
+
+    aSecurityControlField = GetPsdu()[index];
+
+exit:
+    return error;
+}
+
+void Frame::SetSecurityControlField(uint8_t aSecurityControlField)
+{
+    uint8_t index = FindSecurityHeaderIndex();
+
+    OT_ASSERT(index != kInvalidIndex);
+
+    GetPsdu()[index] = aSecurityControlField;
+}
+
 uint8_t Frame::FindSecurityHeaderIndex(void) const
 {
-    uint8_t  index = 0;
-    uint16_t fcf   = GetFrameControlField();
+    uint8_t index;
 
-    VerifyOrExit((fcf & kFcfSecurityEnabled) != 0, index = kInvalidIndex);
-
-    // Frame Control Field and  Sequence Number
-    index += kFcfSize + kDsnSize;
-
-    // Destination PAN + Address
-    switch (fcf & kFcfDstAddrMask)
-    {
-    case kFcfDstAddrShort:
-        index += sizeof(PanId) + sizeof(ShortAddress);
-        break;
-
-    case kFcfDstAddrExt:
-        index += sizeof(PanId) + sizeof(ExtAddress);
-        break;
-    }
-
-    // Source PAN
-    if (IsSrcPanIdPresent(fcf))
-    {
-        index += sizeof(PanId);
-    }
-
-    // Source Address
-    switch (fcf & kFcfSrcAddrMask)
-    {
-    case kFcfSrcAddrShort:
-        index += sizeof(ShortAddress);
-        break;
-
-    case kFcfSrcAddrExt:
-        index += sizeof(ExtAddress);
-        break;
-    }
+    VerifyOrExit(kFcfSize < GetLength(), index = kInvalidIndex);
+    VerifyOrExit(GetSecurityEnabled(), index = kInvalidIndex);
+    index = SkipAddrFieldIndex();
 
 exit:
     return index;
@@ -537,7 +509,7 @@
 {
     uint8_t index = FindSecurityHeaderIndex();
 
-    assert(index != kInvalidIndex);
+    OT_ASSERT(index != kInvalidIndex);
 
     // Security Control
     index += kSecurityControlSize;
@@ -550,7 +522,7 @@
     uint8_t        index = FindSecurityHeaderIndex();
     const uint8_t *buf   = GetPsdu() + index;
 
-    assert(index != kInvalidIndex);
+    OT_ASSERT(index != kInvalidIndex);
 
     // Security Control
     buf += kSecurityControlSize + kFrameCounterSize;
@@ -590,7 +562,7 @@
     uint8_t  index = FindSecurityHeaderIndex();
     uint8_t *buf   = GetPsdu() + index;
 
-    assert(index != kInvalidIndex);
+    OT_ASSERT(index != kInvalidIndex);
 
     keySourceLength = GetKeySourceLength(buf[0] & kKeyIdModeMask);
 
@@ -606,7 +578,7 @@
     uint8_t        index = FindSecurityHeaderIndex();
     const uint8_t *buf   = GetPsdu() + index;
 
-    VerifyOrExit(index != kInvalidIndex);
+    VerifyOrExit(index != kInvalidIndex, OT_NOOP);
 
     keySourceLength = GetKeySourceLength(buf[0] & kKeyIdModeMask);
 
@@ -624,7 +596,7 @@
     uint8_t  index = FindSecurityHeaderIndex();
     uint8_t *buf   = GetPsdu() + index;
 
-    assert(index != kInvalidIndex);
+    OT_ASSERT(index != kInvalidIndex);
 
     keySourceLength = GetKeySourceLength(buf[0] & kKeyIdModeMask);
 
@@ -664,7 +636,7 @@
     bool    isDataRequest = false;
     uint8_t commandId     = 0;
 
-    VerifyOrExit(GetType() == kFcfFrameMacCmd);
+    VerifyOrExit(GetType() == kFcfFrameMacCmd, OT_NOOP);
     SuccessOrExit(GetCommandId(commandId));
     isDataRequest = (commandId == kMacCmdDataRequest);
 
@@ -679,39 +651,44 @@
 
 uint8_t Frame::GetFooterLength(void) const
 {
-    uint8_t footerLength = 0;
+    uint8_t footerLength = static_cast<uint8_t>(GetFcsSize());
     uint8_t index        = FindSecurityHeaderIndex();
 
-    VerifyOrExit(index != kInvalidIndex);
+    VerifyOrExit(index != kInvalidIndex, OT_NOOP);
+    footerLength += CalculateMicSize((GetPsdu() + index)[0]);
 
-    switch ((GetPsdu() + index)[0] & kSecLevelMask)
+exit:
+    return footerLength;
+}
+
+uint8_t Frame::CalculateMicSize(uint8_t aSecurityControl)
+{
+    uint8_t micSize = 0;
+
+    switch (aSecurityControl & kSecLevelMask)
     {
     case kSecNone:
     case kSecEnc:
-        footerLength += kMic0Size;
+        micSize = kMic0Size;
         break;
 
     case kSecMic32:
     case kSecEncMic32:
-        footerLength += kMic32Size;
+        micSize = kMic32Size;
         break;
 
     case kSecMic64:
     case kSecEncMic64:
-        footerLength += kMic64Size;
+        micSize = kMic64Size;
         break;
 
     case kSecMic128:
     case kSecEncMic128:
-        footerLength += kMic128Size;
+        micSize = kMic128Size;
         break;
     }
 
-exit:
-    // Frame Check Sequence
-    footerLength += GetFcsSize();
-
-    return footerLength;
+    return micSize;
 }
 
 uint16_t Frame::GetMaxPayloadLength(void) const
@@ -731,102 +708,141 @@
 
 uint8_t Frame::SkipSecurityHeaderIndex(void) const
 {
-    uint8_t  index = 0;
-    uint16_t fcf;
+    uint8_t index = SkipAddrFieldIndex();
 
-    // Frame Control
-    index += kFcfSize;
-    // Sequence Number
-    index += kDsnSize;
+    VerifyOrExit(index != kInvalidIndex, OT_NOOP);
 
-    VerifyOrExit((index + GetFcsSize()) <= GetPsduLength(), index = kInvalidIndex);
-
-    fcf = GetFrameControlField();
-
-    // Destination PAN + Address
-    switch (fcf & kFcfDstAddrMask)
+    if (GetSecurityEnabled())
     {
-    case kFcfDstAddrNone:
-        break;
+        uint8_t securityControl;
+        uint8_t headerSize;
 
-    case kFcfDstAddrShort:
-        index += sizeof(PanId) + sizeof(ShortAddress);
-        break;
+        VerifyOrExit(index < GetPsduLength(), index = kInvalidIndex);
+        securityControl = *(GetPsdu() + index);
 
-    case kFcfDstAddrExt:
-        index += sizeof(PanId) + sizeof(ExtAddress);
-        break;
+        headerSize = CalculateSecurityHeaderSize(securityControl);
+        VerifyOrExit(headerSize != kInvalidSize, index = kInvalidIndex);
 
-    default:
-        ExitNow(index = kInvalidIndex);
-    }
+        index += headerSize;
 
-    // Source PAN
-    if (IsSrcPanIdPresent(fcf))
-    {
-        index += sizeof(PanId);
-    }
-
-    // Source Address
-    switch (fcf & kFcfSrcAddrMask)
-    {
-    case kFcfSrcAddrNone:
-        break;
-
-    case kFcfSrcAddrShort:
-        index += sizeof(ShortAddress);
-        break;
-
-    case kFcfSrcAddrExt:
-        index += sizeof(ExtAddress);
-        break;
-
-    default:
-        ExitNow(index = kInvalidIndex);
-    }
-
-    VerifyOrExit((index + GetFcsSize()) <= GetPsduLength(), index = kInvalidIndex);
-
-    // Security Control + Frame Counter + Key Identifier
-    if ((fcf & kFcfSecurityEnabled) != 0)
-    {
-        uint8_t securityControl = *(GetPsdu() + index);
-
-        index += kSecurityControlSize + kFrameCounterSize;
-
-        switch (securityControl & kKeyIdModeMask)
-        {
-        case kKeyIdMode0:
-            index += kKeySourceSizeMode0;
-            break;
-
-        case kKeyIdMode1:
-            index += kKeySourceSizeMode1 + kKeyIndexSize;
-            break;
-
-        case kKeyIdMode2:
-            index += kKeySourceSizeMode2 + kKeyIndexSize;
-            break;
-
-        case kKeyIdMode3:
-            index += kKeySourceSizeMode3 + kKeyIndexSize;
-            break;
-        }
+        VerifyOrExit(index <= GetPsduLength(), index = kInvalidIndex);
     }
 
 exit:
     return index;
 }
 
+uint8_t Frame::CalculateSecurityHeaderSize(uint8_t aSecurityControl)
+{
+    uint8_t size = kSecurityControlSize + kFrameCounterSize;
+
+    VerifyOrExit((aSecurityControl & kSecLevelMask) != kSecNone, size = kInvalidSize);
+
+    switch (aSecurityControl & kKeyIdModeMask)
+    {
+    case kKeyIdMode0:
+        size += kKeySourceSizeMode0;
+        break;
+
+    case kKeyIdMode1:
+        size += kKeySourceSizeMode1 + kKeyIndexSize;
+        break;
+
+    case kKeyIdMode2:
+        size += kKeySourceSizeMode2 + kKeyIndexSize;
+        break;
+
+    case kKeyIdMode3:
+        size += kKeySourceSizeMode3 + kKeyIndexSize;
+        break;
+    }
+
+exit:
+    return size;
+}
+
+uint8_t Frame::SkipAddrFieldIndex(void) const
+{
+    uint8_t index;
+
+    VerifyOrExit(kFcfSize + kDsnSize + GetFcsSize() <= GetPsduLength(), index = kInvalidIndex);
+
+    index = CalculateAddrFieldSize(GetFrameControlField());
+
+exit:
+    return index;
+}
+
+uint8_t Frame::CalculateAddrFieldSize(uint16_t aFcf)
+{
+    uint8_t size = kFcfSize + kDsnSize;
+
+    // This static method calculates the size (number of bytes) of
+    // Address header field for a given Frame Control `aFcf` value.
+    // The size includes the Frame Control and Sequence Number fields
+    // along with Destination and Source PAN ID and Short/Extended
+    // Addresses. If the `aFcf` is not valid, this method returns
+    // `kInvalidSize`.
+
+    if (IsDstPanIdPresent(aFcf))
+    {
+        size += sizeof(PanId);
+    }
+
+    switch (aFcf & kFcfDstAddrMask)
+    {
+    case kFcfDstAddrNone:
+        break;
+
+    case kFcfDstAddrShort:
+        size += sizeof(ShortAddress);
+        break;
+
+    case kFcfDstAddrExt:
+        size += sizeof(ExtAddress);
+        break;
+
+    default:
+        ExitNow(size = kInvalidSize);
+        OT_UNREACHABLE_CODE(break);
+    }
+
+    if (IsSrcPanIdPresent(aFcf))
+    {
+        size += sizeof(PanId);
+    }
+
+    switch (aFcf & kFcfSrcAddrMask)
+    {
+    case kFcfSrcAddrNone:
+        break;
+
+    case kFcfSrcAddrShort:
+        size += sizeof(ShortAddress);
+        break;
+
+    case kFcfSrcAddrExt:
+        size += sizeof(ExtAddress);
+        break;
+
+    default:
+        ExitNow(size = kInvalidSize);
+        OT_UNREACHABLE_CODE(break);
+    }
+
+exit:
+    return size;
+}
+
 uint8_t Frame::FindPayloadIndex(void) const
 {
     uint8_t index = SkipSecurityHeaderIndex();
 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
-    const uint8_t *cur    = NULL;
+    const uint8_t *cur    = nullptr;
     const uint8_t *footer = GetFooter();
 #endif
 
-    VerifyOrExit(index != kInvalidIndex);
+    VerifyOrExit(index != kInvalidIndex, OT_NOOP);
 
 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
     cur = GetPsdu() + index;
@@ -871,7 +887,7 @@
     uint8_t        index   = FindPayloadIndex();
     const uint8_t *payload = GetPsdu() + index;
 
-    VerifyOrExit(index != kInvalidIndex, payload = NULL);
+    VerifyOrExit(index != kInvalidIndex, payload = nullptr);
 
 exit:
     return payload;
@@ -902,7 +918,7 @@
     uint8_t *cur;
     uint8_t *base;
 
-    VerifyOrExit(index != kInvalidIndex, error = OT_ERROR_FAILED);
+    VerifyOrExit(index != kInvalidIndex, error = OT_ERROR_NOT_FOUND);
     cur  = GetPsdu() + index;
     base = cur;
 
@@ -922,10 +938,10 @@
 const uint8_t *Frame::GetHeaderIe(uint8_t aIeId) const
 {
     uint8_t        index   = FindHeaderIeIndex();
-    const uint8_t *cur     = NULL;
+    const uint8_t *cur     = nullptr;
     const uint8_t *payload = GetPayload();
 
-    VerifyOrExit(index != kInvalidIndex);
+    VerifyOrExit(index != kInvalidIndex, OT_NOOP);
 
     cur = GetPsdu() + index;
 
@@ -941,14 +957,14 @@
 
         cur += sizeof(HeaderIe);
 
-        VerifyOrExit(cur + len <= payload, cur = NULL);
+        VerifyOrExit(cur + len <= payload, cur = nullptr);
 
         cur += len;
     }
 
     if (cur == payload)
     {
-        cur = NULL;
+        cur = nullptr;
     }
 
 exit:
@@ -956,23 +972,37 @@
 }
 #endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
 
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+void Frame::SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase)
+{
+    uint8_t *cur = GetHeaderIe(Frame::kHeaderIeCsl);
+    CslIe *  csl;
+
+    OT_ASSERT(cur != nullptr);
+
+    csl = reinterpret_cast<CslIe *>(cur + sizeof(HeaderIe));
+    csl->SetPeriod(aCslPeriod);
+    csl->SetPhase(aCslPhase);
+}
+#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 const TimeIe *Frame::GetTimeIe(void) const
 {
-    const TimeIe * timeIe                              = NULL;
-    const uint8_t *cur                                 = NULL;
+    const TimeIe * timeIe                              = nullptr;
+    const uint8_t *cur                                 = nullptr;
     uint8_t        oui[VendorIeHeader::kVendorOuiSize] = {VendorIeHeader::kVendorOuiNest & 0xff,
                                                    (VendorIeHeader::kVendorOuiNest >> 8) & 0xff,
                                                    (VendorIeHeader::kVendorOuiNest >> 16) & 0xff};
 
     cur = GetHeaderIe(kHeaderIeVendor);
-    VerifyOrExit(cur != NULL);
+    VerifyOrExit(cur != nullptr, OT_NOOP);
 
     cur += sizeof(HeaderIe);
 
     timeIe = reinterpret_cast<const TimeIe *>(cur);
-    VerifyOrExit(memcmp(oui, timeIe->GetVendorOui(), VendorIeHeader::kVendorOuiSize) == 0, timeIe = NULL);
-    VerifyOrExit(timeIe->GetSubType() == VendorIeHeader::kVendorIeTime, timeIe = NULL);
+    VerifyOrExit(memcmp(oui, timeIe->GetVendorOui(), VendorIeHeader::kVendorOuiSize) == 0, timeIe = nullptr);
+    VerifyOrExit(timeIe->GetSubType() == VendorIeHeader::kVendorIeTime, timeIe = nullptr);
 
 exit:
     return timeIe;
@@ -1002,38 +1032,165 @@
 
 void TxFrame::ProcessTransmitAesCcm(const ExtAddress &aExtAddress)
 {
-#if OPENTHREAD_RADIO
+#if OPENTHREAD_RADIO && !OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
     OT_UNUSED_VARIABLE(aExtAddress);
 #else
     uint32_t       frameCounter = 0;
     uint8_t        securityLevel;
-    uint8_t        nonce[KeyManager::kNonceSize];
+    uint8_t        nonce[Crypto::AesCcm::kNonceSize];
     uint8_t        tagLength;
     Crypto::AesCcm aesCcm;
-    otError        error;
 
-    VerifyOrExit(GetSecurityEnabled());
+    VerifyOrExit(GetSecurityEnabled(), OT_NOOP);
 
-    SuccessOrExit(error = GetSecurityLevel(securityLevel));
-    SuccessOrExit(error = GetFrameCounter(frameCounter));
+    SuccessOrExit(GetSecurityLevel(securityLevel));
+    SuccessOrExit(GetFrameCounter(frameCounter));
 
-    KeyManager::GenerateNonce(aExtAddress, frameCounter, securityLevel, nonce);
+    Crypto::AesCcm::GenerateNonce(aExtAddress, frameCounter, securityLevel, nonce);
 
-    aesCcm.SetKey(GetAesKey(), 16);
+    aesCcm.SetKey(GetAesKey());
     tagLength = GetFooterLength() - Frame::kFcsSize;
 
-    error = aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, nonce, sizeof(nonce));
-    assert(error == OT_ERROR_NONE);
-
+    aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, nonce, sizeof(nonce));
     aesCcm.Header(GetHeader(), GetHeaderLength());
-    aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), true);
-    aesCcm.Finalize(GetFooter(), &tagLength);
+    aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), Crypto::AesCcm::kEncrypt);
+    aesCcm.Finalize(GetFooter());
+
+    SetIsSecurityProcessed(true);
 
 exit:
     return;
-#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
+#endif // OPENTHREAD_RADIO && !OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
 }
 
+void TxFrame::GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending)
+{
+    uint16_t fcf = kFcfFrameAck | aFrame.GetVersion();
+
+    mChannel = aFrame.mChannel;
+    memset(&mInfo.mTxInfo, 0, sizeof(mInfo.mTxInfo));
+
+    if (aIsFramePending)
+    {
+        fcf |= kFcfFramePending;
+    }
+    Encoding::LittleEndian::WriteUint16(fcf, mPsdu);
+
+    mPsdu[kSequenceIndex] = aFrame.GetSequence();
+
+    mLength = kImmAckLength;
+}
+
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+otError TxFrame::GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, const uint8_t *aIeData, uint8_t aIeLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    uint16_t fcf = kFcfFrameAck | kFcfFrameVersion2015 | kFcfSrcAddrNone;
+    Address  address;
+    PanId    panId;
+    uint8_t  footerLength;
+    uint8_t  securityControlField;
+    uint8_t  keyId;
+
+    mChannel = aFrame.mChannel;
+    memset(&mInfo.mTxInfo, 0, sizeof(mInfo.mTxInfo));
+
+    // Set frame control field
+    if (aIsFramePending)
+    {
+        fcf |= kFcfFramePending;
+    }
+
+    if (aFrame.GetSecurityEnabled())
+    {
+        fcf |= kFcfSecurityEnabled;
+    }
+
+    if (aFrame.IsPanIdCompressed())
+    {
+        fcf |= kFcfPanidCompression;
+    }
+
+    // Destination address mode
+    if ((aFrame.GetFrameControlField() & kFcfSrcAddrMask) == kFcfSrcAddrExt)
+    {
+        fcf |= kFcfDstAddrExt;
+    }
+    else if ((aFrame.GetFrameControlField() & kFcfSrcAddrMask) == kFcfSrcAddrShort)
+    {
+        fcf |= kFcfDstAddrShort;
+    }
+    else
+    {
+        fcf |= kFcfDstAddrNone;
+    }
+
+    if (aIeLength > 0)
+    {
+        fcf |= kFcfIePresent;
+    }
+
+    Encoding::LittleEndian::WriteUint16(fcf, mPsdu);
+
+    // Set sequence number
+    mPsdu[kSequenceIndex] = aFrame.GetSequence();
+
+    // Set address field
+    if (aFrame.IsSrcPanIdPresent())
+    {
+        SuccessOrExit(error = aFrame.GetSrcPanId(panId));
+    }
+    else if (aFrame.IsDstPanIdPresent())
+    {
+        SuccessOrExit(error = aFrame.GetDstPanId(panId));
+    }
+    else
+    {
+        ExitNow(error = OT_ERROR_PARSE);
+    }
+
+    if (IsDstPanIdPresent())
+    {
+        SetDstPanId(panId);
+    }
+
+    if (aFrame.IsSrcAddrPresent())
+    {
+        SuccessOrExit(error = aFrame.GetSrcAddr(address));
+        SetDstAddr(address);
+    }
+
+    SetPsduLength(kMaxPsduSize); // At this time the length of ACK hasn't been determined, set it to
+                                 // `kMaxPsduSize` to call methods that check frame length.
+
+    // Set security header
+    if (aFrame.GetSecurityEnabled())
+    {
+        SuccessOrExit(error = aFrame.GetSecurityControlField(securityControlField));
+        SuccessOrExit(error = aFrame.GetKeyId(keyId));
+
+        SetSecurityControlField(securityControlField);
+        SetKeyId(keyId);
+    }
+
+    // Set header IE
+    if (aIeLength > 0)
+    {
+        OT_ASSERT(aIeData != nullptr);
+        memcpy(GetPsdu() + FindHeaderIeIndex(), aIeData, aIeLength);
+    }
+
+    // Set frame length
+    footerLength = GetFooterLength();
+    OT_ASSERT(footerLength != kInvalidIndex);
+    mLength = SkipSecurityHeaderIndex() + aIeLength + GetFooterLength();
+
+exit:
+    return error;
+}
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+
 // LCOV_EXCL_START
 
 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
@@ -1044,22 +1201,22 @@
     uint8_t    commandId, type;
     Address    src, dst;
 
-    string.Append("len:%d, seqnum:%d, type:", GetLength(), GetSequence());
+    IgnoreError(string.Append("len:%d, seqnum:%d, type:", GetLength(), GetSequence()));
 
     type = GetType();
 
     switch (type)
     {
     case kFcfFrameBeacon:
-        string.Append("Beacon");
+        IgnoreError(string.Append("Beacon"));
         break;
 
     case kFcfFrameData:
-        string.Append("Data");
+        IgnoreError(string.Append("Data"));
         break;
 
     case kFcfFrameAck:
-        string.Append("Ack");
+        IgnoreError(string.Append("Ack"));
         break;
 
     case kFcfFrameMacCmd:
@@ -1071,30 +1228,31 @@
         switch (commandId)
         {
         case kMacCmdDataRequest:
-            string.Append("Cmd(DataReq)");
+            IgnoreError(string.Append("Cmd(DataReq)"));
             break;
 
         case kMacCmdBeaconRequest:
-            string.Append("Cmd(BeaconReq)");
+            IgnoreError(string.Append("Cmd(BeaconReq)"));
             break;
 
         default:
-            string.Append("Cmd(%d)", commandId);
+            IgnoreError(string.Append("Cmd(%d)", commandId));
             break;
         }
 
         break;
 
     default:
-        string.Append("%d", type);
+        IgnoreError(string.Append("%d", type));
         break;
     }
 
-    GetSrcAddr(src);
-    GetDstAddr(dst);
+    IgnoreError(GetSrcAddr(src));
+    IgnoreError(GetDstAddr(dst));
 
-    string.Append(", src:%s, dst:%s, sec:%s, ackreq:%s", src.ToString().AsCString(), dst.ToString().AsCString(),
-                  GetSecurityEnabled() ? "yes" : "no", GetAckRequest() ? "yes" : "no");
+    IgnoreError(string.Append(", src:%s, dst:%s, sec:%s, ackreq:%s", src.ToString().AsCString(),
+                              dst.ToString().AsCString(), GetSecurityEnabled() ? "yes" : "no",
+                              GetAckRequest() ? "yes" : "no"));
 
     return string;
 }
@@ -1103,7 +1261,7 @@
 {
     NetworkName name;
 
-    name.Set(GetNetworkName());
+    IgnoreError(name.Set(GetNetworkName()));
 
     return InfoString("name:%s, xpanid:%s, id:%d, ver:%d, joinable:%s, native:%s", name.GetAsCString(),
                       mExtendedPanId.ToString().AsCString(), GetProtocolId(), GetProtocolVersion(),
diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp
index aac2fad..616f8cb 100644
--- a/src/core/mac/mac_frame.hpp
+++ b/src/core/mac/mac_frame.hpp
@@ -314,9 +314,12 @@
         kMacCmdGtsRequest                 = 9,
 
         kHeaderIeVendor       = 0x00,
+        kHeaderIeCsl          = 0x1a,
         kHeaderIeTermination2 = 0x7f,
 
         kInfoStringSize = 110, ///< Max chars needed for the info string representation (@sa ToInfoString()).
+
+        kImmAckLength = kFcfSize + kDsnSize + kFcsSize,
     };
 
     /**
@@ -361,6 +364,15 @@
     uint8_t GetType(void) const { return GetPsdu()[0] & kFcfFrameTypeMask; }
 
     /**
+     * This method returns whether the frame is an Ack frame.
+     *
+     * @retval TRUE   If this is an Ack.
+     * @retval FALSE  If this is not an Ack.
+     *
+     */
+    bool IsAck(void) const { return GetType() == kFcfFrameAck; }
+
+    /**
      * This method returns the IEEE 802.15.4 Frame Version.
      *
      * @returns The IEEE 802.15.4 Frame Version.
@@ -369,6 +381,14 @@
     uint16_t GetVersion(void) const { return GetFrameControlField() & kFcfFrameVersionMask; }
 
     /**
+     * This method returns if this IEEE 802.15.4 frame's version is 2015.
+     *
+     * @returns TRUE if version is 2015, FALSE otherwise.
+     *
+     */
+    bool IsVersion2015(void) const { return IsVersion2015(GetFrameControlField()); }
+
+    /**
      * This method indicates whether or not security is enabled.
      *
      * @retval TRUE   If security is enabled.
@@ -412,6 +432,15 @@
     void SetAckRequest(bool aAckRequest);
 
     /**
+     * This method indicates whether or not the PanId Compression bit is set.
+     *
+     * @retval TRUE   If the PanId Compression bit is set.
+     * @retval FALSE  If the PanId Compression bit is not set.
+     *
+     */
+    bool IsPanIdCompressed(void) const { return (GetFrameControlField() & kFcfPanidCompression) != 0; }
+
+    /**
      * This method indicates whether or not IEs present.
      *
      * @retval TRUE   If IEs present.
@@ -437,6 +466,14 @@
     void SetSequence(uint8_t aSequence) { GetPsdu()[kSequenceIndex] = aSequence; }
 
     /**
+     * This method indicates whether or not the Destination PAN ID is present.
+     *
+     * @returns TRUE if the Destination PAN ID is present, FALSE otherwise.
+     *
+     */
+    bool IsDstPanIdPresent(void) const { return IsDstPanIdPresent(GetFrameControlField()); }
+
+    /**
      * This method gets the Destination PAN Identifier.
      *
      * @param[out]  aPanId  The Destination PAN Identifier.
@@ -456,6 +493,14 @@
     void SetDstPanId(PanId aPanId);
 
     /**
+     * This method indicates whether or not the Destination Address is present for this object.
+     *
+     * @retval TRUE if the Destination Address is present, FALSE otherwise.
+     *
+     */
+    bool IsDstAddrPresent() const { return IsDstAddrPresent(GetFrameControlField()); }
+
+    /**
      * This method gets the Destination Address.
      *
      * @param[out]  aAddress  The Destination Address.
@@ -490,12 +535,12 @@
     void SetDstAddr(const Address &aAddress);
 
     /**
-     * This method indicates whether or not the Src PanId is present.
+     * This method indicates whether or not the Source Address is present for this object.
      *
-     * @returns TRUE if the Src PanId is present, FALSE otherwise.
+     * @retval TRUE if the Source Address is present, FALSE otherwise.
      *
      */
-    bool IsSrcPanIdPresent(uint16_t aFcf) const;
+    bool IsSrcPanIdPresent(void) const { return IsSrcPanIdPresent(GetFrameControlField()); };
 
     /**
      * This method gets the Source PAN Identifier.
@@ -518,6 +563,14 @@
     otError SetSrcPanId(PanId aPanId);
 
     /**
+     * This method indicates whether or not the Source Address is present for this object.
+     *
+     * @retval TRUE if the Source Address is present, FALSE otherwise.
+     *
+     */
+    bool IsSrcAddrPresent(void) const { return IsSrcAddrPresent(GetFrameControlField()); }
+
+    /**
      * This method gets the Source Address.
      *
      * @param[out]  aAddress  The Source Address.
@@ -552,6 +605,25 @@
     void SetSrcAddr(const Address &aAddress);
 
     /**
+     * This method gets the Security Control Field.
+     *
+     * @param[out]  aSecurityControlField  The Security Control Field.
+     *
+     * @retval OT_ERROR_NONE   Successfully retrieved the Security Level Identifier.
+     * @retval OT_ERROR_PARSE  Failed to find the security control field in the frame.
+     *
+     */
+    otError GetSecurityControlField(uint8_t &aSecurityControlField) const;
+
+    /**
+     * This method sets the Security Control Field.
+     *
+     * @param[in]  aSecurityControlField  The Security Control Field.
+     *
+     */
+    void SetSecurityControlField(uint8_t aSecurityControlField);
+
+    /**
      * This method gets the Security Level Identifier.
      *
      * @param[out]  aSecurityLevel  The Security Level Identifier.
@@ -806,7 +878,7 @@
     /**
      * This method returns a pointer to the vendor specific Time IE.
      *
-     * @returns A pointer to the Time IE, NULL if not found.
+     * @returns A pointer to the Time IE, nullptr if not found.
      *
      */
     TimeIe *GetTimeIe(void) { return const_cast<TimeIe *>(const_cast<const Frame *>(this)->GetTimeIe()); }
@@ -814,7 +886,7 @@
     /**
      * This method returns a pointer to the vendor specific Time IE.
      *
-     * @returns A pointer to the Time IE, NULL if not found.
+     * @returns A pointer to the Time IE, nullptr if not found.
      *
      */
     const TimeIe *GetTimeIe(void) const;
@@ -838,7 +910,7 @@
      *
      * @param[in] aIeId  The Element Id of the Header IE.
      *
-     * @returns A pointer to the Header IE, NULL if not found.
+     * @returns A pointer to the Header IE, nullptr if not found.
      *
      */
     uint8_t *GetHeaderIe(uint8_t aIeId)
@@ -851,10 +923,22 @@
      *
      * @param[in] aIeId  The Element Id of the Header IE.
      *
-     * @returns A pointer to the Header IE, NULL if not found.
+     * @returns A pointer to the Header IE, nullptr if not found.
      *
      */
     const uint8_t *GetHeaderIe(uint8_t aIeId) const;
+
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+    /**
+     * This method finds CSL IE in the frame and modify its content.
+     *
+     * @param[in] aCslPeriod  CSL Period in CSL IE.
+     * @param[in] aCslPhase   CSL Phase in CSL IE.
+     *
+     */
+    void SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase);
+#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+
 #endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
 
     /**
@@ -881,26 +965,46 @@
      */
     InfoString ToInfoString(void) const;
 
-private:
+    /**
+     * This method returns the Frame Control field of the frame.
+     *
+     * @returns The Frame Control field.
+     *
+     */
+    uint16_t GetFrameControlField(void) const;
+
+protected:
     enum
     {
         kInvalidIndex  = 0xff,
+        kInvalidSize   = kInvalidIndex,
+        kMaxPsduSize   = kInvalidSize - 1,
         kSequenceIndex = kFcfSize,
     };
 
-    uint16_t GetFrameControlField(void) const;
-    uint8_t  FindDstPanIdIndex(void) const;
-    uint8_t  FindDstAddrIndex(void) const;
-    uint8_t  FindSrcPanIdIndex(void) const;
-    uint8_t  FindSrcAddrIndex(void) const;
-    uint8_t  FindSecurityHeaderIndex(void) const;
-    uint8_t  SkipSecurityHeaderIndex(void) const;
-    uint8_t  FindPayloadIndex(void) const;
+    uint8_t FindDstPanIdIndex(void) const;
+    uint8_t FindDstAddrIndex(void) const;
+    uint8_t FindSrcPanIdIndex(void) const;
+    uint8_t FindSrcAddrIndex(void) const;
+    uint8_t SkipAddrFieldIndex(void) const;
+    uint8_t FindSecurityHeaderIndex(void) const;
+    uint8_t SkipSecurityHeaderIndex(void) const;
+    uint8_t FindPayloadIndex(void) const;
 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
     uint8_t FindHeaderIeIndex(void) const;
 #endif
 
     static uint8_t GetKeySourceLength(uint8_t aKeyIdMode);
+
+    static bool IsDstAddrPresent(uint16_t aFcf) { return (aFcf & kFcfDstAddrMask) != kFcfDstAddrNone; }
+    static bool IsDstPanIdPresent(uint16_t aFcf);
+    static bool IsSrcAddrPresent(uint16_t aFcf) { return (aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone; }
+    static bool IsSrcPanIdPresent(uint16_t aFcf);
+    static bool IsVersion2015(uint16_t aFcf) { return (aFcf & kFcfFrameVersionMask) == kFcfFrameVersion2015; }
+
+    static uint8_t CalculateAddrFieldSize(uint16_t aFcf);
+    static uint8_t CalculateSecurityHeaderSize(uint8_t aSecurityControl);
+    static uint8_t CalculateMicSize(uint8_t aSecurityControl);
 };
 
 /**
@@ -910,6 +1014,8 @@
 class RxFrame : public Frame
 {
 public:
+    friend class TxFrame;
+
     /**
      * This method returns the RSSI in dBm used for reception.
      *
@@ -1072,7 +1178,7 @@
      * @returns The pointer to the key.
      *
      */
-    const uint8_t *GetAesKey(void) const { return mInfo.mTxInfo.mAesKey; }
+    const Mac::Key &GetAesKey(void) const { return *static_cast<const Mac::Key *>(mInfo.mTxInfo.mAesKey); }
 
     /**
      * This method sets the key used for frame encryption and authentication (AES CCM).
@@ -1080,7 +1186,7 @@
      * @param[in]  aAesKey  The pointer to the key.
      *
      */
-    void SetAesKey(const uint8_t *aAesKey) { mInfo.mTxInfo.mAesKey = aAesKey; }
+    void SetAesKey(const Mac::Key &aAesKey) { mInfo.mTxInfo.mAesKey = &aAesKey; }
 
     /**
      * This method copies the PSDU and all attributes from another frame.
@@ -1101,6 +1207,27 @@
      *
      */
     void ProcessTransmitAesCcm(const ExtAddress &aExtAddress);
+
+    /**
+     * This method indicates whether or not the frame has security processed.
+     *
+     * @retval TRUE   The frame already has security processed.
+     * @retval FALSE  The frame does not have security processed.
+     *
+     */
+    bool IsSecurityProcessed(void) const { return mInfo.mTxInfo.mIsSecurityProcessed; }
+
+    /**
+     * This method sets the security processed flag attribute.
+     *
+     * @param[in]  aIsSecurityProcessed  TRUE if the frame already has security processed.
+     *
+     */
+    void SetIsSecurityProcessed(bool aIsSecurityProcessed)
+    {
+        mInfo.mTxInfo.mIsSecurityProcessed = aIsSecurityProcessed;
+    }
+
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     /**
      * This method sets the Time IE offset.
@@ -1111,6 +1238,14 @@
     void SetTimeIeOffset(uint8_t aOffset) { mInfo.mTxInfo.mIeInfo->mTimeIeOffset = aOffset; }
 
     /**
+     * This method gets the Time IE offset.
+     *
+     * @returns The Time IE offset, 0 means no Time IE.
+     *
+     */
+    uint8_t GetTimeIeOffset(void) const { return mInfo.mTxInfo.mIeInfo->mTimeIeOffset; }
+
+    /**
      * This method sets the offset to network time.
      *
      * @param[in]  aNetworkTimeOffset  The offset to network time.
@@ -1129,6 +1264,29 @@
      */
     void SetTimeSyncSeq(uint8_t aTimeSyncSeq) { mInfo.mTxInfo.mIeInfo->mTimeSyncSeq = aTimeSyncSeq; }
 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+
+    /**
+     * Generate Imm-Ack in this frame object.
+     *
+     * @param[in]    aFrame             A reference to the frame received.
+     * @param[in]    aIsFramePending    Value of the ACK's frame pending bit.
+     *
+     */
+    void GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending);
+
+    /**
+     * Generate Enh-Ack in this frame object.
+     *
+     * @param[in]    aFrame             A reference to the frame received.
+     * @param[in]    aIsFramePending    Value of the ACK's frame pending bit.
+     * @param[in]    aIeData            A pointer to the IE data portion of the ACK to be sent.
+     * @param[in]    aIeLength          The length of IE data portion of the ACK to be sent.
+     *
+     * @retval  OT_ERROR_NONE           Successfully generated Enh Ack.
+     * @retval  OT_ERROR_PARSE          @p aFrame has incorrect format.
+     *
+     */
+    otError GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, const uint8_t *aIeData, uint8_t aIeLength);
 };
 
 OT_TOOL_PACKED_BEGIN
@@ -1303,18 +1461,18 @@
     /**
      * This method gets the Network Name field.
      *
-     * @returns The Network Name field as `NetworkName::Data`.
+     * @returns The Network Name field as `NameData`.
      *
      */
-    NetworkName::Data GetNetworkName(void) const { return NetworkName::Data(mNetworkName, sizeof(mNetworkName)); }
+    NameData GetNetworkName(void) const { return NameData(mNetworkName, sizeof(mNetworkName)); }
 
     /**
      * This method sets the Network Name field.
      *
-     * @param[in]  aNameData  The Network Name (as a `NetworkName::Data`).
+     * @param[in]  aNameData  The Network Name (as a `NameData`).
      *
      */
-    void SetNetworkName(const NetworkName::Data &aNameData) { aNameData.CopyTo(mNetworkName, sizeof(mNetworkName)); }
+    void SetNetworkName(const NameData &aNameData) { aNameData.CopyTo(mNetworkName, sizeof(mNetworkName)); }
 
     /**
      * This method returns the Extended PAN ID field.
@@ -1348,6 +1506,51 @@
 } OT_TOOL_PACKED_END;
 
 /**
+ * This class implements CSL IE data structure.
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+class CslIe
+{
+public:
+    /**
+     * This method returns the CSL Period.
+     *
+     * @returns the CSL Period.
+     *
+     */
+    uint16_t GetPeriod(void) const { return Encoding::LittleEndian::HostSwap16(mPeriod); }
+
+    /**
+     * This method sets the CSL Period.
+     *
+     * @param[in]  aPeriod  The CSL Period.
+     *
+     */
+    void SetPeriod(uint16_t aPeriod) { mPeriod = Encoding::LittleEndian::HostSwap16(aPeriod); }
+
+    /**
+     * This method returns the CSL Phase.
+     *
+     * @returns the CSL Phase.
+     *
+     */
+    uint16_t GetPhase(void) const { return Encoding::LittleEndian::HostSwap16(mPhase); }
+
+    /**
+     * This method sets the CSL Phase.
+     *
+     * @param[in]  aPhase  The CSL Phase.
+     *
+     */
+    void SetPhase(uint16_t aPhase) { mPhase = Encoding::LittleEndian::HostSwap16(aPhase); }
+
+private:
+    uint16_t mPhase;
+    uint16_t mPeriod;
+} OT_TOOL_PACKED_END;
+
+/**
  * @}
  *
  */
diff --git a/src/core/mac/mac_types.cpp b/src/core/mac/mac_types.cpp
index c2ef352..f787322 100644
--- a/src/core/mac/mac_types.cpp
+++ b/src/core/mac/mac_types.cpp
@@ -54,21 +54,22 @@
     return panId;
 }
 
+#if !OPENTHREAD_RADIO
 void ExtAddress::GenerateRandom(void)
 {
-    Random::NonCrypto::FillBuffer(m8, sizeof(ExtAddress));
+    IgnoreError(Random::Crypto::FillBuffer(m8, sizeof(ExtAddress)));
     SetGroup(false);
     SetLocal(true);
 }
-
-bool ExtAddress::operator==(const ExtAddress &aOther) const
-{
-    return memcmp(m8, aOther.m8, sizeof(ExtAddress)) == 0;
-}
+#endif
 
 ExtAddress::InfoString ExtAddress::ToString(void) const
 {
-    return InfoString("%02x%02x%02x%02x%02x%02x%02x%02x", m8[0], m8[1], m8[2], m8[3], m8[4], m8[5], m8[6], m8[7]);
+    InfoString string;
+
+    IgnoreError(string.AppendHexBytes(m8, sizeof(ExtAddress)));
+
+    return string;
 }
 
 void ExtAddress::CopyAddress(uint8_t *aDst, const uint8_t *aSrc, CopyByteOrder aByteOrder)
@@ -95,17 +96,16 @@
                                     : (mType == kTypeNone ? InfoString("None") : InfoString("0x%04x", GetShort()));
 }
 
-bool ExtendedPanId::operator==(const ExtendedPanId &aOther) const
-{
-    return memcmp(m8, aOther.m8, sizeof(ExtendedPanId)) == 0;
-}
-
 ExtendedPanId::InfoString ExtendedPanId::ToString(void) const
 {
-    return InfoString("%02x%02x%02x%02x%02x%02x%02x%02x", m8[0], m8[1], m8[2], m8[3], m8[4], m8[5], m8[6], m8[7]);
+    InfoString string;
+
+    IgnoreError(string.AppendHexBytes(m8, sizeof(ExtendedPanId)));
+
+    return string;
 }
 
-uint8_t NetworkName::Data::CopyTo(char *aBuffer, uint8_t aMaxSize) const
+uint8_t NameData::CopyTo(char *aBuffer, uint8_t aMaxSize) const
 {
     uint8_t len = GetLength();
 
@@ -121,14 +121,14 @@
     return len;
 }
 
-NetworkName::Data NetworkName::GetAsData(void) const
+NameData NetworkName::GetAsData(void) const
 {
     uint8_t len = static_cast<uint8_t>(StringLength(m8, kMaxSize + 1));
 
-    return Data(m8, len);
+    return NameData(m8, len);
 }
 
-otError NetworkName::Set(const Data &aNameData)
+otError NetworkName::Set(const NameData &aNameData)
 {
     otError error  = OT_ERROR_NONE;
     uint8_t newLen = static_cast<uint8_t>(StringLength(aNameData.GetBuffer(), aNameData.GetLength()));
@@ -145,5 +145,31 @@
     return error;
 }
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+NameData DomainName::GetAsData(void) const
+{
+    uint8_t len = static_cast<uint8_t>(StringLength(m8, kMaxSize + 1));
+
+    return NameData(m8, len);
+}
+
+otError DomainName::Set(const NameData &aNameData)
+{
+    otError error  = OT_ERROR_NONE;
+    uint8_t newLen = static_cast<uint8_t>(StringLength(aNameData.GetBuffer(), aNameData.GetLength()));
+
+    VerifyOrExit(newLen <= kMaxSize, error = OT_ERROR_INVALID_ARGS);
+
+    // Ensure the new name does not match the current one.
+    VerifyOrExit(memcmp(m8, aNameData.GetBuffer(), newLen) || (m8[newLen] != '\0'), error = OT_ERROR_ALREADY);
+
+    memcpy(m8, aNameData.GetBuffer(), newLen);
+    m8[newLen] = '\0';
+
+exit:
+    return error;
+}
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
 } // namespace Mac
 } // namespace ot
diff --git a/src/core/mac/mac_types.hpp b/src/core/mac/mac_types.hpp
index cc6ed17..a332c30 100644
--- a/src/core/mac/mac_types.hpp
+++ b/src/core/mac/mac_types.hpp
@@ -40,7 +40,10 @@
 #include <string.h>
 
 #include <openthread/link.h>
+#include <openthread/thread.h>
 
+#include "common/clearable.hpp"
+#include "common/equatable.hpp"
 #include "common/string.hpp"
 
 namespace ot {
@@ -85,7 +88,7 @@
  *
  */
 OT_TOOL_PACKED_BEGIN
-class ExtAddress : public otExtAddress
+class ExtAddress : public otExtAddress, public Equatable<ExtAddress>, public Clearable<ExtAddress>
 {
 public:
     enum
@@ -110,12 +113,6 @@
     };
 
     /**
-     * This method clears the Extended Address (sets all bytes to zero).
-     *
-     */
-    void Clear(void) { Fill(0); }
-
-    /**
      * This method fills all bytes of address with a given byte value.
      *
      * @param[in] aByte A byte value to fill address with.
@@ -221,28 +218,6 @@
     }
 
     /**
-     * This method evaluates whether or not the Extended Addresses match.
-     *
-     * @param[in]  aOther  The Extended Address to compare.
-     *
-     * @retval TRUE   If the Extended Addresses match.
-     * @retval FALSE  If the Extended Addresses do not match.
-     *
-     */
-    bool operator==(const ExtAddress &aOther) const;
-
-    /**
-     * This method evaluates whether or not the Extended Addresses match.
-     *
-     * @param[in]  aOther  The Extended Address to compare.
-     *
-     * @retval TRUE   If the Extended Addresses do not match.
-     * @retval FALSE  If the Extended Addresses match.
-     *
-     */
-    bool operator!=(const ExtAddress &aOther) const { return !(*this == aOther); }
-
-    /**
      * This method converts an address to a string.
      *
      * @returns An `InfoString` containing the string representation of the Extended Address.
@@ -442,11 +417,34 @@
 };
 
 /**
+ * This class represents a MAC key.
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+class Key : public otMacKey, public Equatable<Key>, public Clearable<Key>
+{
+public:
+    enum
+    {
+        kSize = OT_MAC_KEY_SIZE, // Key size in bytes.
+    };
+
+    /**
+     * This method gets a pointer to the buffer containing the key.
+     *
+     * @returns A pointer to the buffer containing the key.
+     *
+     */
+    const uint8_t *GetKey(void) const { return m8; }
+
+} OT_TOOL_PACKED_END;
+
+/**
  * This structure represents an IEEE 802.15.4 Extended PAN Identifier.
  *
  */
 OT_TOOL_PACKED_BEGIN
-class ExtendedPanId : public otExtendedPanId
+class ExtendedPanId : public otExtendedPanId, public Equatable<ExtendedPanId>, public Clearable<ExtendedPanId>
 {
 public:
     enum
@@ -461,34 +459,6 @@
     typedef String<kInfoStringSize> InfoString;
 
     /**
-     * This method clears the Extended PAN Identifier (sets all bytes to zero).
-     *
-     */
-    void Clear(void) { memset(this, 0, sizeof(*this)); }
-
-    /**
-     * This method evaluates whether or not the Extended PAN Identifiers match.
-     *
-     * @param[in]  aOther  The Extended PAN Id to compare.
-     *
-     * @retval TRUE   If the Extended PAN Identifiers match.
-     * @retval FALSE  If the Extended PAN Identifiers do not match.
-     *
-     */
-    bool operator==(const ExtendedPanId &aOther) const;
-
-    /**
-     * This method evaluates whether or not the Extended PAN Identifiers match.
-     *
-     * @param[in]  aOther  The Extended PAN Id to compare.
-     *
-     * @retval TRUE   If the Extended Addresses do not match.
-     * @retval FALSE  If the Extended Addresses match.
-     *
-     */
-    bool operator!=(const ExtendedPanId &aOther) const { return !(*this == aOther); }
-
-    /**
      * This method converts an address to a string.
      *
      * @returns An `InfoString` containing the string representation of the Extended PAN Identifier.
@@ -499,6 +469,63 @@
 } OT_TOOL_PACKED_END;
 
 /**
+ * This class represents a name string as data (pointer to a char buffer along with a length).
+ *
+ * @note The char array does NOT need to be null terminated.
+ *
+ */
+class NameData
+{
+public:
+    /**
+     * This constructor initializes the NameData object.
+     *
+     * @param[in] aBuffer   A pointer to a `char` buffer (does not need to be null terminated).
+     * @param[in] aLength   The length (number of chars) in the buffer.
+     *
+     */
+    NameData(const char *aBuffer, uint8_t aLength)
+        : mBuffer(aBuffer)
+        , mLength(aLength)
+    {
+    }
+
+    /**
+     * This method returns the pointer to char buffer (not necessarily null terminated).
+     *
+     * @returns The pointer to the char buffer.
+     *
+     */
+    const char *GetBuffer(void) const { return mBuffer; }
+
+    /**
+     * This method returns the length (number of chars in buffer).
+     *
+     * @returns The name length.
+     *
+     */
+    uint8_t GetLength(void) const { return mLength; }
+
+    /**
+     * This method copies the name data into a given char buffer with a given size.
+     *
+     * The given buffer is cleared (`memset` to zero) before copying the name into it. The copied string
+     * in @p aBuffer is NOT necessarily null terminated.
+     *
+     * @param[out] aBuffer   A pointer to a buffer where to copy the name into.
+     * @param[in]  aMaxSize  Size of @p aBuffer (maximum number of chars to write into @p aBuffer).
+     *
+     * @returns The actual number of chars copied into @p aBuffer.
+     *
+     */
+    uint8_t CopyTo(char *aBuffer, uint8_t aMaxSize) const;
+
+private:
+    const char *mBuffer;
+    uint8_t     mLength;
+};
+
+/**
  * This structure represents an IEEE802.15.4 Network Name.
  *
  */
@@ -511,63 +538,6 @@
     };
 
     /**
-     * This class represents an IEEE802.15.4 Network Name as Data (pointer to a char buffer along with a length).
-     *
-     * @note The char array does NOT need to be null terminated.
-     *
-     */
-    class Data
-    {
-    public:
-        /**
-         * This constructor initializes the Data object.
-         *
-         * @param[in] aBuffer   A pointer to a `char` buffer (does not need to be null terminated).
-         * @param[in] aLength   The length (number of chars) in the buffer.
-         *
-         */
-        Data(const char *aBuffer, uint8_t aLength)
-            : mBuffer(aBuffer)
-            , mLength(aLength)
-        {
-        }
-
-        /**
-         * This method returns the pointer to char buffer (not necessarily null terminated).
-         *
-         * @returns The pointer to the char buffer.
-         *
-         */
-        const char *GetBuffer(void) const { return mBuffer; }
-
-        /**
-         * This method returns the length (number of chars in buffer).
-         *
-         * @returns The name length.
-         *
-         */
-        uint8_t GetLength(void) const { return mLength; }
-
-        /**
-         * This method copies the name data into a given char buffer with a given size.
-         *
-         * The given buffer is cleared (`memset` to zero) before copying the Network Name into it. The copied string
-         * in @p aBuffer is NOT necessarily null terminated.
-         *
-         * @param[out] aBuffer   A pointer to a buffer where to copy the Network Name into.
-         * @param[in]  aMaxSize  Size of @p aBuffer (maximum number of chars to write into @p aBuffer).
-         *
-         * @returns The actual number of chars copied into @p aBuffer.
-         *
-         */
-        uint8_t CopyTo(char *aBuffer, uint8_t aMaxSize) const;
-
-    private:
-        const char *mBuffer;
-        uint8_t     mLength;
-    };
-
-    /**
      * This constructor initializes the IEEE802.15.4 Network Name as an empty string.
      *
      */
@@ -582,12 +552,12 @@
     const char *GetAsCString(void) const { return m8; }
 
     /**
-     * This method gets the IEEE802.15.4 Network Name as Data.
+     * This method gets the IEEE802.15.4 Network Name as NameData.
      *
-     * @returns The Network Name as Data.
+     * @returns The Network Name as NameData.
      *
      */
-    Data GetAsData(void) const;
+    NameData GetAsData(void) const;
 
     /**
      * This method sets the IEEE 802.15.4 Network Name.
@@ -599,9 +569,61 @@
      * @retval OT_ERROR_INVALID_ARGS   Given name is too long.
      *
      */
-    otError Set(const Data &aNameData);
+    otError Set(const NameData &aNameData);
 };
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+/**
+ * This structure represents a Thread Domain Name.
+ *
+ */
+class DomainName
+{
+public:
+    enum
+    {
+        kMaxSize = 16, // Maximum number of chars in Domain Name (excludes null char).
+    };
+
+    /**
+     * This constructor initializes the Thread Domain Name as an empty string.
+     *
+     */
+    DomainName(void) { m8[0] = '\0'; }
+
+    /**
+     * This method gets the Thread Domain Name as a null terminated C string.
+     *
+     * @returns The Domain Name as a null terminated C string array.
+     *
+     */
+    const char *GetAsCString(void) const { return m8; }
+
+    /**
+     * This method gets the Thread Domain Name as NameData.
+     *
+     * @returns The Domain Name as NameData.
+     *
+     */
+    NameData GetAsData(void) const;
+
+    /**
+     * This method sets the Thread Domain Name.
+     *
+     * @param[in]  aNameData           A reference to name data.
+     *
+     * @retval OT_ERROR_NONE           Successfully set the Thread Domain Name.
+     * @retval OT_ERROR_ALREADY        The name is already set to the same string.
+     * @retval OT_ERROR_INVALID_ARGS   Given name is too long.
+     *
+     */
+    otError Set(const NameData &aNameData);
+
+private:
+    char m8[kMaxSize + 1]; ///< Byte values.
+};
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
 /**
  * @}
  *
diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp
index c5c05ac..9a4e650 100644
--- a/src/core/mac/sub_mac.cpp
+++ b/src/core/mac/sub_mac.cpp
@@ -57,11 +57,16 @@
     , mEnergyScanEndTime(0)
     , mTransmitFrame(Get<Radio>().GetTransmitBuffer())
     , mCallbacks(aInstance)
-    , mPcapCallback(NULL)
-    , mPcapCallbackContext(NULL)
-    , mTimer(aInstance, &SubMac::HandleTimer, this)
+    , mPcapCallback(nullptr)
+    , mPcapCallbackContext(nullptr)
+    , mFrameCounter(0)
+    , mKeyId(0)
+    , mTimer(aInstance, SubMac::HandleTimer, this)
 {
     mExtAddress.Clear();
+    mPrevKey.Clear();
+    mCurrKey.Clear();
+    mNextKey.Clear();
 }
 
 otRadioCaps SubMac::GetCaps(void) const
@@ -70,25 +75,29 @@
 
 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
 
-#if OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
+#if OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
     caps |= OT_RADIO_CAPS_ACK_TIMEOUT;
 #endif
 
-#if OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+#if OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
     caps |= OT_RADIO_CAPS_CSMA_BACKOFF;
 #endif
 
-#if OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+#if OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
     caps |= OT_RADIO_CAPS_TRANSMIT_RETRIES;
 #endif
 
-#if OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE
+#if OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
     caps |= OT_RADIO_CAPS_ENERGY_SCAN;
 #endif
 
+#if OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+    caps |= OT_RADIO_CAPS_TRANSMIT_SEC;
+#endif
+
 #else
     caps = OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES |
-           OT_RADIO_CAPS_ENERGY_SCAN;
+           OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_TRANSMIT_SEC;
 #endif
 
     return caps;
@@ -130,14 +139,14 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(mState == kStateDisabled);
+    VerifyOrExit(mState == kStateDisabled, OT_NOOP);
 
     SuccessOrExit(error = Get<Radio>().Enable());
     SuccessOrExit(error = Get<Radio>().Sleep());
     SetState(kStateSleep);
 
 exit:
-    assert(error == OT_ERROR_NONE);
+    OT_ASSERT(error == OT_ERROR_NONE);
     return error;
 }
 
@@ -188,11 +197,16 @@
 
 void SubMac::HandleReceiveDone(RxFrame *aFrame, otError aError)
 {
-    if (mPcapCallback && (aFrame != NULL) && (aError == OT_ERROR_NONE))
+    if (mPcapCallback && (aFrame != nullptr) && (aError == OT_ERROR_NONE))
     {
         mPcapCallback(aFrame, false, mPcapCallbackContext);
     }
 
+    if (!ShouldHandleTransmitSecurity() && aFrame != nullptr && aFrame->mInfo.mRxInfo.mAckedWithSecEnhAck)
+    {
+        UpdateFrameCounter(aFrame->mInfo.mRxInfo.mAckFrameCounter);
+    }
+
     mCallbacks.ReceiveDone(aFrame, aError);
 }
 
@@ -207,13 +221,14 @@
     case kStateTransmit:
     case kStateEnergyScan:
         ExitNow(error = OT_ERROR_INVALID_STATE);
-        break;
+        OT_UNREACHABLE_CODE(break);
 
     case kStateSleep:
     case kStateReceive:
         break;
     }
 
+    ProcessTransmitSecurity();
     mCsmaBackoffs    = 0;
     mTransmitRetries = 0;
     StartCsmaBackoff();
@@ -222,6 +237,42 @@
     return error;
 }
 
+void SubMac::ProcessTransmitSecurity(void)
+{
+    const ExtAddress *extAddress = nullptr;
+    uint8_t           keyIdMode;
+
+    VerifyOrExit(ShouldHandleTransmitSecurity(), OT_NOOP);
+    VerifyOrExit(mTransmitFrame.GetSecurityEnabled(), OT_NOOP);
+    VerifyOrExit(!mTransmitFrame.IsSecurityProcessed(), OT_NOOP);
+
+    SuccessOrExit(mTransmitFrame.GetKeyIdMode(keyIdMode));
+    VerifyOrExit(keyIdMode == Frame::kKeyIdMode1, OT_NOOP);
+
+    mTransmitFrame.SetAesKey(GetCurrentMacKey());
+
+    if (!mTransmitFrame.IsARetransmission())
+    {
+        uint32_t frameCounter = GetFrameCounter();
+
+        mTransmitFrame.SetKeyId(mKeyId);
+        mTransmitFrame.SetFrameCounter(frameCounter);
+        UpdateFrameCounter(frameCounter + 1);
+    }
+
+    extAddress = &GetExtAddress();
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    // Transmit security will be processed after time IE content is updated.
+    VerifyOrExit(mTransmitFrame.GetTimeIeOffset() == 0, OT_NOOP);
+#endif
+
+    mTransmitFrame.ProcessTransmitAesCcm(*extAddress);
+
+exit:
+    return;
+}
+
 void SubMac::StartCsmaBackoff(void)
 {
     uint32_t backoff;
@@ -231,14 +282,6 @@
 
     VerifyOrExit(ShouldHandleCsmaBackOff(), BeginTransmit());
 
-#if OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT
-    if ((mTransmitRetries > 0) && (mTransmitRetries == mTransmitFrame.GetMaxFrameRetries()))
-    {
-        BeginTransmit();
-        ExitNow();
-    }
-#endif
-
     if (backoffExponent > kMaxBE)
     {
         backoffExponent = kMaxBE;
@@ -249,11 +292,11 @@
 
     if (mRxOnWhenBackoff)
     {
-        Get<Radio>().Receive(mTransmitFrame.GetChannel());
+        IgnoreError(Get<Radio>().Receive(mTransmitFrame.GetChannel()));
     }
     else
     {
-        Get<Radio>().Sleep();
+        IgnoreError(Get<Radio>().Sleep());
     }
 
 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
@@ -270,21 +313,17 @@
 {
     otError error;
 
-    VerifyOrExit(mState == kStateCsmaBackoff);
+    OT_UNUSED_VARIABLE(error);
 
-#if OPENTHREAD_CONFIG_MAC_DISABLE_CSMA_CA_ON_LAST_ATTEMPT
-    if ((mTransmitRetries > 0) && (mTransmitRetries == mTransmitFrame.GetMaxFrameRetries()))
-    {
-        mTransmitFrame.SetCsmaCaEnabled(false);
-    }
-    else
-#endif
-    {
-        mTransmitFrame.SetCsmaCaEnabled(true);
-    }
+    VerifyOrExit(mState == kStateCsmaBackoff, OT_NOOP);
 
-    error = Get<Radio>().Receive(mTransmitFrame.GetChannel());
-    assert(error == OT_ERROR_NONE);
+    mTransmitFrame.SetCsmaCaEnabled(true);
+
+    if ((mRadioCaps & OT_RADIO_CAPS_SLEEP_TO_TX) == 0)
+    {
+        error = Get<Radio>().Receive(mTransmitFrame.GetChannel());
+        OT_ASSERT(error == OT_ERROR_NONE);
+    }
 
     SetState(kStateTransmit);
 
@@ -294,7 +333,7 @@
     }
 
     error = Get<Radio>().Transmit(mTransmitFrame);
-    assert(error == OT_ERROR_NONE);
+    OT_ASSERT(error == OT_ERROR_NONE);
 
 exit:
     return;
@@ -345,10 +384,23 @@
         break;
 
     default:
-        assert(false);
+        OT_ASSERT(false);
         OT_UNREACHABLE_CODE(ExitNow());
     }
 
+    if (!ShouldHandleTransmitSecurity() && aFrame.GetSecurityEnabled())
+    {
+        uint8_t  keyIdMode;
+        uint32_t frameCounter = 0;
+
+        IgnoreError(aFrame.GetKeyIdMode(keyIdMode));
+        if (keyIdMode == Frame::kKeyIdMode1)
+        {
+            OT_ASSERT(aFrame.GetFrameCounter(frameCounter) == OT_ERROR_NONE);
+            UpdateFrameCounter(frameCounter);
+        }
+    }
+
     // Determine whether a CSMA retry is required.
 
     if (!ccaSuccess && ShouldHandleCsmaBackOff() && mCsmaBackoffs < aFrame.GetMaxCsmaBackoffs())
@@ -388,6 +440,11 @@
     return Get<Radio>().GetRssi();
 }
 
+int8_t SubMac::GetNoiseFloor(void)
+{
+    return Get<Radio>().GetReceiveSensitivity();
+}
+
 otError SubMac::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration)
 {
     otError error = OT_ERROR_NONE;
@@ -407,13 +464,13 @@
 
     if (RadioSupportsEnergyScan())
     {
-        Get<Radio>().EnergyScan(aScanChannel, aScanDuration);
+        IgnoreError(Get<Radio>().EnergyScan(aScanChannel, aScanDuration));
         SetState(kStateEnergyScan);
     }
     else if (ShouldHandleEnergyScan())
     {
         error = Get<Radio>().Receive(aScanChannel);
-        assert(error == OT_ERROR_NONE);
+        OT_ASSERT(error == OT_ERROR_NONE);
 
         SetState(kStateEnergyScan);
         mEnergyScanMaxRssi = kInvalidRssiValue;
@@ -431,6 +488,8 @@
 
 void SubMac::SampleRssi(void)
 {
+    OT_ASSERT(!RadioSupportsEnergyScan());
+
     int8_t rssi = GetRssi();
 
     if (rssi != kInvalidRssiValue)
@@ -443,7 +502,11 @@
 
     if (TimerMilli::GetNow() < mEnergyScanEndTime)
     {
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+        mTimer.StartAt(mTimer.GetFireTime(), kEnergyScanRssiSampleInterval * 1000UL);
+#else
         mTimer.StartAt(mTimer.GetFireTime(), kEnergyScanRssiSampleInterval);
+#endif
     }
     else
     {
@@ -472,8 +535,8 @@
 
     case kStateTransmit:
         otLogDebgMac("Ack timer timed out");
-        Get<Radio>().Receive(mTransmitFrame.GetChannel());
-        HandleTransmitDone(mTransmitFrame, NULL, OT_ERROR_NO_ACK);
+        IgnoreError(Get<Radio>().Receive(mTransmitFrame.GetChannel()));
+        HandleTransmitDone(mTransmitFrame, nullptr, OT_ERROR_NO_ACK);
         break;
 
     case kStateEnergyScan:
@@ -485,6 +548,24 @@
     }
 }
 
+bool SubMac::ShouldHandleTransmitSecurity(void) const
+{
+    bool swTxSecurity = true;
+
+    VerifyOrExit(!RadioSupportsTransmitSecurity(), swTxSecurity = false);
+
+#if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
+    VerifyOrExit(Get<LinkRaw>().IsEnabled(), OT_NOOP);
+#endif
+
+#if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO
+    swTxSecurity = OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE;
+#endif
+
+exit:
+    return swTxSecurity;
+}
+
 bool SubMac::ShouldHandleCsmaBackOff(void) const
 {
     bool swCsma = true;
@@ -492,11 +573,11 @@
     VerifyOrExit(!RadioSupportsCsmaBackoff(), swCsma = false);
 
 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
-    VerifyOrExit(Get<LinkRaw>().IsEnabled());
+    VerifyOrExit(Get<LinkRaw>().IsEnabled(), OT_NOOP);
 #endif
 
 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO
-    swCsma = OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE;
+    swCsma = OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE;
 #endif
 
 exit:
@@ -510,11 +591,11 @@
     VerifyOrExit(!RadioSupportsAckTimeout(), swAckTimeout = false);
 
 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
-    VerifyOrExit(Get<LinkRaw>().IsEnabled());
+    VerifyOrExit(Get<LinkRaw>().IsEnabled(), OT_NOOP);
 #endif
 
 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO
-    swAckTimeout = OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE;
+    swAckTimeout = OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE;
 #endif
 
 exit:
@@ -528,11 +609,11 @@
     VerifyOrExit(!RadioSupportsRetries(), swRetries = false);
 
 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
-    VerifyOrExit(Get<LinkRaw>().IsEnabled());
+    VerifyOrExit(Get<LinkRaw>().IsEnabled(), OT_NOOP);
 #endif
 
 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO
-    swRetries = OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE;
+    swRetries = OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE;
 #endif
 
 exit:
@@ -546,11 +627,11 @@
     VerifyOrExit(!RadioSupportsEnergyScan(), swEnergyScan = false);
 
 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
-    VerifyOrExit(Get<LinkRaw>().IsEnabled());
+    VerifyOrExit(Get<LinkRaw>().IsEnabled(), OT_NOOP);
 #endif
 
 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO
-    swEnergyScan = OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE;
+    swEnergyScan = OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE;
 #endif
 
 exit:
@@ -566,6 +647,56 @@
     }
 }
 
+void SubMac::SetMacKey(uint8_t    aKeyIdMode,
+                       uint8_t    aKeyId,
+                       const Key &aPrevKey,
+                       const Key &aCurrKey,
+                       const Key &aNextKey)
+{
+    switch (aKeyIdMode)
+    {
+    case Frame::kKeyIdMode0:
+    case Frame::kKeyIdMode2:
+        break;
+    case Frame::kKeyIdMode1:
+        mKeyId   = aKeyId;
+        mPrevKey = aPrevKey;
+        mCurrKey = aCurrKey;
+        mNextKey = aNextKey;
+        break;
+
+    default:
+        OT_ASSERT(false);
+        break;
+    }
+
+    VerifyOrExit(!ShouldHandleTransmitSecurity(), OT_NOOP);
+
+    Get<Radio>().SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey);
+
+exit:
+    return;
+}
+
+void SubMac::UpdateFrameCounter(uint32_t aFrameCounter)
+{
+    mFrameCounter = aFrameCounter;
+
+    mCallbacks.FrameCounterUpdated(aFrameCounter);
+}
+
+void SubMac::SetFrameCounter(uint32_t aFrameCounter)
+{
+    mFrameCounter = aFrameCounter;
+
+    VerifyOrExit(!ShouldHandleTransmitSecurity(), OT_NOOP);
+
+    Get<Radio>().SetMacFrameCounter(aFrameCounter);
+
+exit:
+    return;
+}
+
 // LCOV_EXCL_START
 
 const char *SubMac::StateToString(State aState)
diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp
index 6c08643..05875c9 100644
--- a/src/core/mac/sub_mac.hpp
+++ b/src/core/mac/sub_mac.hpp
@@ -102,7 +102,7 @@
         /**
          * This method notifies user of `SubMac` of a received frame.
          *
-         * @param[in]  aFrame    A pointer to the received frame or NULL if the receive operation failed.
+         * @param[in]  aFrame    A pointer to the received frame or nullptr if the receive operation failed.
          * @param[in]  aError    OT_ERROR_NONE when successfully received a frame,
          *                       OT_ERROR_ABORT when reception was aborted and a frame was not received,
          *                       OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
@@ -130,7 +130,7 @@
          * of a frame transmission, this method is invoked on all frame transmission attempts.
          *
          * @param[in] aFrame      The transmitted frame.
-         * @param[in] aAckFrame   A pointer to the ACK frame, or NULL if no ACK was received.
+         * @param[in] aAckFrame   A pointer to the ACK frame, or nullptr if no ACK was received.
          * @param[in] aError      OT_ERROR_NONE when the frame was transmitted successfully,
          *                        OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
          *                        OT_ERROR_CHANNEL_ACCESS_FAILURE tx failed due to activity on the channel,
@@ -151,7 +151,7 @@
          * the received ACK frame.
          *
          * @param[in]  aFrame     The transmitted frame.
-         * @param[in]  aAckFrame  A pointer to the ACK frame, NULL if no ACK was received.
+         * @param[in]  aAckFrame  A pointer to the ACK frame, nullptr if no ACK was received.
          * @param[in]  aError     OT_ERROR_NONE when the frame was transmitted,
          *                        OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
          *                        OT_ERROR_CHANNEL_ACCESS_FAILURE tx failed due to activity on the channel,
@@ -167,6 +167,14 @@
          *
          */
         void EnergyScanDone(int8_t aMaxRssi);
+
+        /**
+         * This method notifies user of `SubMac` that MAC frame counter is updated.
+         *
+         * @param[in]  aFrameCounter  The MAC frame counter value.
+         *
+         */
+        void FrameCounterUpdated(uint32_t aFrameCounter);
     };
 
     /**
@@ -237,7 +245,7 @@
      * This method registers a callback to provide received packet capture for IEEE 802.15.4 frames.
      *
      * @param[in]  aPcapCallback     A pointer to a function that is called when receiving an IEEE 802.15.4 link frame
-     *                                or NULL to disable the callback.
+     *                                or nullptr to disable the callback.
      * @param[in]  aCallbackContext  A pointer to application-specific context.
      *
      */
@@ -339,6 +347,66 @@
      */
     otError EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration);
 
+    /**
+     * This method returns the noise floor value (currently use the radio receive sensitivity value).
+     *
+     * @returns The noise floor value in dBm.
+     *
+     */
+    int8_t GetNoiseFloor(void);
+
+    /**
+     * This method sets MAC keys and key index.
+     *
+     * @param[in] aKeyIdMode  MAC key ID mode.
+     * @param[in] aKeyId      The key ID.
+     * @param[in] aPrevKey    The previous MAC key.
+     * @param[in] aCurrKey    The current MAC key.
+     * @param[in] aNextKey    The next MAC key.
+     *
+     */
+    void SetMacKey(uint8_t aKeyIdMode, uint8_t aKeyId, const Key &aPrevKey, const Key &aCurrKey, const Key &aNextKey);
+
+    /**
+     * This method returns a reference to the current MAC key.
+     *
+     * @returns A reference to the current MAC key.
+     *
+     */
+    const Key &GetCurrentMacKey(void) const { return mCurrKey; }
+
+    /**
+     * This method returns a reference to the previous MAC key.
+     *
+     * @returns A reference to the previous MAC key.
+     *
+     */
+    const Key &GetPreviousMacKey(void) const { return mPrevKey; }
+
+    /**
+     * This method returns a reference to the next MAC key.
+     *
+     * @returns A reference to the next MAC key.
+     *
+     */
+    const Key &GetNextMacKey(void) const { return mNextKey; }
+
+    /**
+     * This method returns the current MAC frame counter value.
+     *
+     * @returns The current MAC frame counter value.
+     *
+     */
+    uint32_t GetFrameCounter(void) const { return mFrameCounter; };
+
+    /**
+     * This method sets the current MAC Frame Counter value.
+     *
+     * @param[in] aFrameCounter  The MAC Frame Counter value.
+     *
+     */
+    void SetFrameCounter(uint32_t aFrameCounter);
+
 private:
     enum
     {
@@ -370,15 +438,19 @@
         return ((mRadioCaps & (OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES)) != 0);
     }
 
+    bool RadioSupportsTransmitSecurity(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_SEC) != 0); }
     bool RadioSupportsRetries(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_RETRIES) != 0); }
     bool RadioSupportsAckTimeout(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ACK_TIMEOUT) != 0); }
     bool RadioSupportsEnergyScan(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN) != 0); }
 
+    bool ShouldHandleTransmitSecurity(void) const;
     bool ShouldHandleCsmaBackOff(void) const;
     bool ShouldHandleAckTimeout(void) const;
     bool ShouldHandleRetries(void) const;
     bool ShouldHandleEnergyScan(void) const;
 
+    void ProcessTransmitSecurity(void);
+    void UpdateFrameCounter(uint32_t aFrameCounter);
     void StartCsmaBackoff(void);
     void BeginTransmit(void);
     void SampleRssi(void);
@@ -407,6 +479,11 @@
     Callbacks          mCallbacks;
     otLinkPcapCallback mPcapCallback;
     void *             mPcapCallbackContext;
+    Key                mPrevKey;
+    Key                mCurrKey;
+    Key                mNextKey;
+    uint32_t           mFrameCounter;
+    uint8_t            mKeyId;
 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
     TimerMicro mTimer;
 #else
diff --git a/src/core/mac/sub_mac_callbacks.cpp b/src/core/mac/sub_mac_callbacks.cpp
index 1014594..6fa84b7 100644
--- a/src/core/mac/sub_mac_callbacks.cpp
+++ b/src/core/mac/sub_mac_callbacks.cpp
@@ -36,7 +36,10 @@
 #include "common/code_utils.hpp"
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
+
+#if OPENTHREAD_FTD || OPENTHREAD_MTD
 #include "mac/mac.hpp"
+#endif
 
 namespace ot {
 namespace Mac {
@@ -104,6 +107,11 @@
     }
 }
 
+void SubMac::Callbacks::FrameCounterUpdated(uint32_t aFrameCounter)
+{
+    Get<KeyManager>().MacFrameCounterUpdated(aFrameCounter);
+}
+
 #elif OPENTHREAD_RADIO
 
 void SubMac::Callbacks::ReceiveDone(RxFrame *aFrame, otError aError)
@@ -134,6 +142,11 @@
     Get<LinkRaw>().InvokeEnergyScanDone(aMaxRssi);
 }
 
+void SubMac::Callbacks::FrameCounterUpdated(uint32_t aFrameCounter)
+{
+    OT_UNUSED_VARIABLE(aFrameCounter);
+}
+
 #endif // OPENTHREAD_RADIO
 
 } // namespace Mac
diff --git a/src/core/meshcop/announce_begin_client.cpp b/src/core/meshcop/announce_begin_client.cpp
index e12676c..cff05ee 100644
--- a/src/core/meshcop/announce_begin_client.cpp
+++ b/src/core/meshcop/announce_begin_client.cpp
@@ -58,38 +58,28 @@
                                          uint16_t            aPeriod,
                                          const Ip6::Address &aAddress)
 {
-    otError                           error = OT_ERROR_NONE;
-    MeshCoP::CommissionerSessionIdTlv sessionId;
-    MeshCoP::ChannelMaskTlv           channelMask;
-    MeshCoP::CountTlv                 count;
-    MeshCoP::PeriodTlv                period;
-
-    Ip6::MessageInfo messageInfo;
-    Coap::Message *  message = NULL;
+    otError                 error = OT_ERROR_NONE;
+    MeshCoP::ChannelMaskTlv channelMask;
+    Ip6::MessageInfo        messageInfo;
+    Coap::Message *         message = nullptr;
 
     VerifyOrExit(Get<MeshCoP::Commissioner>().IsActive(), error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error =
                       message->Init(aAddress.IsMulticast() ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE,
                                     OT_COAP_CODE_POST, OT_URI_PATH_ANNOUNCE_BEGIN));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    sessionId.Init();
-    sessionId.SetCommissionerSessionId(Get<MeshCoP::Commissioner>().GetSessionId());
-    SuccessOrExit(error = sessionId.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kCommissionerSessionId,
+                                               Get<MeshCoP::Commissioner>().GetSessionId()));
 
     channelMask.Init();
     channelMask.SetChannelMask(aChannelMask);
     SuccessOrExit(error = channelMask.AppendTo(*message));
 
-    count.Init();
-    count.SetCount(aCount);
-    SuccessOrExit(error = count.AppendTo(*message));
-
-    period.Init();
-    period.SetPeriod(aPeriod);
-    SuccessOrExit(error = period.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, MeshCoP::Tlv::kCount, aCount));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kPeriod, aPeriod));
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetPeerAddr(aAddress);
@@ -101,7 +91,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
diff --git a/src/core/meshcop/border_agent.cpp b/src/core/meshcop/border_agent.cpp
index f97ed5c..6f84e27 100644
--- a/src/core/meshcop/border_agent.cpp
+++ b/src/core/meshcop/border_agent.cpp
@@ -100,7 +100,7 @@
     /**
      * This method generate the response header according to the saved metadata.
      *
-     * @param[out]  aHeader     A refernce to the response header.
+     * @param[out]  aHeader     A reference to the response header.
      * @param[in]   aCode       The response code to fill in the response header.
      *
      * @retval OT_ERROR_NONE     Successfully generated the response header.
@@ -165,16 +165,16 @@
 static void SendErrorMessage(Coap::CoapSecure &aCoapSecure, ForwardContext &aForwardContext, otError aError)
 {
     otError        error   = OT_ERROR_NONE;
-    Coap::Message *message = NULL;
+    Coap::Message *message = nullptr;
 
-    VerifyOrExit((message = NewMeshCoPMessage(aCoapSecure)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(aCoapSecure)) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = aForwardContext.ToHeader(*message, CoapCodeFromError(aError)));
-    SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerAddress()));
+    SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetMessageInfo()));
 
 exit:
     if (error != OT_ERROR_NONE)
     {
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -189,11 +189,11 @@
                              otError              aError)
 {
     otError        error   = OT_ERROR_NONE;
-    Coap::Message *message = NULL;
+    Coap::Message *message = nullptr;
 
-    VerifyOrExit((message = NewMeshCoPMessage(aCoapSecure)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(aCoapSecure)) != nullptr, error = OT_ERROR_NO_BUFS);
 
-    if (aRequest.GetType() == OT_COAP_TYPE_NON_CONFIRMABLE || aSeparate)
+    if (aRequest.IsNonConfirmable() || aSeparate)
     {
         message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, CoapCodeFromError(aError));
     }
@@ -209,12 +209,12 @@
 
     SuccessOrExit(error = message->SetToken(aRequest.GetToken(), aRequest.GetTokenLength()));
 
-    SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerAddress()));
+    SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetMessageInfo()));
 
 exit:
     if (error != OT_ERROR_NONE)
     {
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -234,31 +234,28 @@
     BorderAgent &        borderAgent    = forwardContext.GetBorderAgent();
     Instance &           instance       = borderAgent.GetInstance();
     const Coap::Message *response       = static_cast<const Coap::Message *>(aMessage);
-    Coap::Message *      message        = NULL;
+    Coap::Message *      message        = nullptr;
     otError              error;
 
     SuccessOrExit(error = aResult);
-    VerifyOrExit((message = NewMeshCoPMessage(instance.Get<Coap::CoapSecure>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(instance.Get<Coap::CoapSecure>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     if (forwardContext.IsPetition() && response->GetCode() == OT_COAP_CODE_CHANGED)
     {
-        StateTlv stateTlv;
+        uint8_t state;
 
-        SuccessOrExit(error = Tlv::GetTlv(*response, Tlv::kState, sizeof(stateTlv), stateTlv));
-        VerifyOrExit(stateTlv.IsValid(), error = OT_ERROR_PARSE);
+        SuccessOrExit(error = Tlv::FindUint8Tlv(*response, Tlv::kState, state));
 
-        if (stateTlv.GetState() == StateTlv::kAccept)
+        if (state == StateTlv::kAccept)
         {
-            CommissionerSessionIdTlv sessionIdTlv;
+            uint16_t sessionId;
 
-            SuccessOrExit(error =
-                              Tlv::GetTlv(*response, Tlv::kCommissionerSessionId, sizeof(sessionIdTlv), sessionIdTlv));
-            VerifyOrExit(sessionIdTlv.IsValid(), error = OT_ERROR_PARSE);
+            SuccessOrExit(error = Tlv::FindUint16Tlv(*response, Tlv::kCommissionerSessionId, sessionId));
 
-            instance.Get<Mle::MleRouter>().GetCommissionerAloc(borderAgent.mCommissionerAloc.GetAddress(),
-                                                               sessionIdTlv.GetCommissionerSessionId());
+            IgnoreError(instance.Get<Mle::MleRouter>().GetCommissionerAloc(borderAgent.mCommissionerAloc.GetAddress(),
+                                                                           sessionId));
             instance.Get<ThreadNetif>().AddUnicastAddress(borderAgent.mCommissionerAloc);
-            instance.Get<Ip6::Udp>().AddReceiver(borderAgent.mUdpReceiver);
+            IgnoreError(instance.Get<Ip6::Udp>().AddReceiver(borderAgent.mUdpReceiver));
         }
     }
 
@@ -274,7 +271,7 @@
 exit:
     if (error != OT_ERROR_NONE)
     {
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -293,9 +290,9 @@
                                                                      otMessage *          aMessage,
                                                                      const otMessageInfo *aMessageInfo)
 {
-    static_cast<BorderAgent *>(aContext)->ForwardToLeader(*static_cast<Coap::Message *>(aMessage),
-                                                          *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
-                                                          OT_URI_PATH_LEADER_PETITION, true, true);
+    IgnoreError(static_cast<BorderAgent *>(aContext)->ForwardToLeader(
+        *static_cast<Coap::Message *>(aMessage), *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
+        OT_URI_PATH_LEADER_PETITION, true, true));
 }
 
 template <>
@@ -336,6 +333,7 @@
 
 BorderAgent::BorderAgent(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , Notifier::Receiver(aInstance, BorderAgent::HandleNotifierEvents)
     , mCommissionerPetition(OT_URI_PATH_COMMISSIONER_PETITION,
                             BorderAgent::HandleRequest<&BorderAgent::mCommissionerPetition>,
                             this)
@@ -357,15 +355,42 @@
 {
     mCommissionerAloc.Clear();
     mCommissionerAloc.mPrefixLength       = 64;
+    mCommissionerAloc.mAddressOrigin      = OT_ADDRESS_ORIGIN_THREAD;
     mCommissionerAloc.mPreferred          = true;
     mCommissionerAloc.mValid              = true;
     mCommissionerAloc.mScopeOverride      = Ip6::Address::kRealmLocalScope;
     mCommissionerAloc.mScopeOverrideValid = true;
 }
 
+void BorderAgent::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
+{
+    static_cast<BorderAgent &>(aReceiver).HandleNotifierEvents(aEvents);
+}
+
+void BorderAgent::HandleNotifierEvents(Events aEvents)
+{
+    VerifyOrExit(aEvents.ContainsAny(kEventThreadRoleChanged | kEventCommissionerStateChanged), OT_NOOP);
+
+#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
+    VerifyOrExit(Get<MeshCoP::Commissioner>().IsDisabled(), OT_NOOP);
+#endif
+
+    if (Get<Mle::MleRouter>().IsAttached())
+    {
+        IgnoreError(Start());
+    }
+    else
+    {
+        IgnoreError(Stop());
+    }
+
+exit:
+    return;
+}
+
 void BorderAgent::HandleProxyTransmit(const Coap::Message &aMessage)
 {
-    Message *        message = NULL;
+    Message *        message = nullptr;
     Ip6::MessageInfo messageInfo;
     uint16_t         offset;
     otError          error;
@@ -373,10 +398,10 @@
     {
         UdpEncapsulationTlv tlv;
 
-        SuccessOrExit(error = Tlv::GetOffset(aMessage, Tlv::kUdpEncapsulation, offset));
+        SuccessOrExit(error = Tlv::FindTlvOffset(aMessage, Tlv::kUdpEncapsulation, offset));
         VerifyOrExit(aMessage.Read(offset, sizeof(tlv), &tlv) == sizeof(tlv), error = OT_ERROR_PARSE);
 
-        VerifyOrExit((message = Get<Ip6::Udp>().NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
+        VerifyOrExit((message = Get<Ip6::Udp>().NewMessage(0)) != nullptr, error = OT_ERROR_NO_BUFS);
         SuccessOrExit(error = message->SetLength(tlv.GetUdpLength()));
         aMessage.CopyTo(offset + sizeof(tlv), 0, tlv.GetUdpLength(), *message);
 
@@ -385,12 +410,8 @@
         messageInfo.SetPeerPort(tlv.GetDestinationPort());
     }
 
-    {
-        IPv6AddressTlv tlv;
-
-        SuccessOrExit(error = Tlv::Get(aMessage, Tlv::kIPv6Address, sizeof(tlv), tlv));
-        messageInfo.SetPeerAddr(tlv.GetAddress());
-    }
+    SuccessOrExit(
+        error = Tlv::FindTlv(aMessage, Tlv::kIPv6Address, messageInfo.GetPeerAddr().mFields.m8, sizeof(Ip6::Address)));
 
     SuccessOrExit(error = Get<Ip6::Udp>().SendDatagram(*message, messageInfo, Ip6::kProtoUdp));
     otLogInfoMeshCoP("Proxy transmit sent");
@@ -400,7 +421,7 @@
     {
         otLogWarnMeshCoP("Failed to send proxy stream: %s", otThreadErrorToString(error));
 
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -410,14 +431,14 @@
 bool BorderAgent::HandleUdpReceive(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError        error;
-    Coap::Message *message = NULL;
+    Coap::Message *message = nullptr;
 
     VerifyOrExit(aMessageInfo.GetSockAddr() == mCommissionerAloc.GetAddress(),
                  error = OT_ERROR_DESTINATION_ADDRESS_FILTERED);
 
     VerifyOrExit(aMessage.GetLength() > 0, error = OT_ERROR_NONE);
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST);
     SuccessOrExit(error = message->AppendUriPathOptions(OT_URI_PATH_PROXY_RX));
@@ -439,20 +460,15 @@
         aMessage.CopyTo(aMessage.GetOffset(), offset, udpLength, *message);
     }
 
-    {
-        IPv6AddressTlv tlv;
+    SuccessOrExit(error =
+                      Tlv::AppendTlv(*message, Tlv::kIPv6Address, &aMessageInfo.GetPeerAddr(), sizeof(Ip6::Address)));
 
-        tlv.Init();
-        tlv.SetAddress(aMessageInfo.GetPeerAddr());
-        SuccessOrExit(error = tlv.AppendTo(*message));
-    }
-
-    SuccessOrExit(error = Get<Coap::CoapSecure>().SendMessage(*message, Get<Coap::CoapSecure>().GetPeerAddress()));
+    SuccessOrExit(error = Get<Coap::CoapSecure>().SendMessage(*message, Get<Coap::CoapSecure>().GetMessageInfo()));
 
     otLogInfoMeshCoP("Sent to commissioner on %s", OT_URI_PATH_PROXY_RX);
 
 exit:
-    if (message != NULL && error != OT_ERROR_NONE)
+    if (message != nullptr && error != OT_ERROR_NONE)
     {
         otLogWarnMeshCoP("Failed notify commissioner on %s", OT_URI_PATH_PROXY_RX);
         message->Free();
@@ -463,12 +479,11 @@
 
 void BorderAgent::HandleRelayReceive(const Coap::Message &aMessage)
 {
-    Coap::Message *message = NULL;
+    Coap::Message *message = nullptr;
     otError        error;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_NON_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST,
-                 error = OT_ERROR_DROP);
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(aMessage.IsNonConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, error = OT_ERROR_DROP);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST);
     SuccessOrExit(error = message->AppendUriPathOptions(OT_URI_PATH_RELAY_RX));
@@ -482,7 +497,7 @@
     otLogInfoMeshCoP("Sent to commissioner on %s", OT_URI_PATH_RELAY_RX);
 
 exit:
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -498,7 +513,7 @@
     aMessage.CopyTo(aMessage.GetOffset(), offset, aMessage.GetLength() - aMessage.GetOffset(), aForwardMessage);
 
     SuccessOrExit(error =
-                      Get<Coap::CoapSecure>().SendMessage(aForwardMessage, Get<Coap::CoapSecure>().GetPeerAddress()));
+                      Get<Coap::CoapSecure>().SendMessage(aForwardMessage, Get<Coap::CoapSecure>().GetMessageInfo()));
 
     otLogInfoMeshCoP("Sent to commissioner");
 
@@ -525,18 +540,17 @@
 
 void BorderAgent::HandleRelayTransmit(const Coap::Message &aMessage)
 {
-    otError                error = OT_ERROR_NONE;
-    JoinerRouterLocatorTlv joinerRouterRloc;
-    Coap::Message *        message = NULL;
-    Ip6::MessageInfo       messageInfo;
-    uint16_t               offset = 0;
+    otError          error = OT_ERROR_NONE;
+    uint16_t         joinerRouterRloc;
+    Coap::Message *  message = nullptr;
+    Ip6::MessageInfo messageInfo;
+    uint16_t         offset = 0;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_NON_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsNonConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerRouterLocator, sizeof(joinerRouterRloc), joinerRouterRloc));
-    VerifyOrExit(joinerRouterRloc.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kJoinerRouterLocator, joinerRouterRloc));
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_RELAY_TX));
     SuccessOrExit(error = message->SetPayloadMarker());
@@ -549,7 +563,7 @@
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetPeerPort(kCoapUdpPort);
     messageInfo.SetPeerAddr(Get<Mle::MleRouter>().GetMeshLocal16());
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(joinerRouterRloc.GetJoinerRouterLocator());
+    messageInfo.GetPeerAddr().GetIid().SetLocator(joinerRouterRloc);
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
 
@@ -560,7 +574,7 @@
     {
         otLogWarnMeshCoP("Failed to sent to joiner router request " OT_URI_PATH_RELAY_TX " %s",
                          otThreadErrorToString(error));
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -574,12 +588,12 @@
                                      bool                    aSeparate)
 {
     otError          error          = OT_ERROR_NONE;
-    ForwardContext * forwardContext = NULL;
+    ForwardContext * forwardContext = nullptr;
     Ip6::MessageInfo messageInfo;
-    Coap::Message *  message = NULL;
+    Coap::Message *  message = nullptr;
     uint16_t         offset  = 0;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     if (aSeparate)
     {
@@ -587,7 +601,7 @@
     }
 
     forwardContext = static_cast<ForwardContext *>(GetInstance().HeapCAlloc(1, sizeof(ForwardContext)));
-    VerifyOrExit(forwardContext != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(forwardContext != nullptr, error = OT_ERROR_NO_BUFS);
 
     forwardContext = new (forwardContext) ForwardContext(*this, aMessage, aPetition, aSeparate);
 
@@ -611,19 +625,19 @@
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo, HandleCoapResponse, forwardContext));
 
     // HandleCoapResponse is responsible to free this forward context.
-    forwardContext = NULL;
+    forwardContext = nullptr;
 
     otLogInfoMeshCoP("Forwarded request to leader on %s", aPath);
 
 exit:
     if (error != OT_ERROR_NONE)
     {
-        if (forwardContext != NULL)
+        if (forwardContext != nullptr)
         {
             GetInstance().HeapFree(forwardContext);
         }
 
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -731,10 +745,24 @@
     if (mState != aState)
     {
         mState = aState;
-        Get<Notifier>().Signal(OT_CHANGED_BORDER_AGENT_STATE);
     }
 }
 
+void BorderAgent::ApplyMeshLocalPrefix(void)
+{
+    VerifyOrExit(mState == OT_BORDER_AGENT_STATE_ACTIVE, OT_NOOP);
+
+    if (Get<ThreadNetif>().HasUnicastAddress(mCommissionerAloc))
+    {
+        Get<ThreadNetif>().RemoveUnicastAddress(mCommissionerAloc);
+        mCommissionerAloc.GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
+        Get<ThreadNetif>().AddUnicastAddress(mCommissionerAloc);
+    }
+
+exit:
+    return;
+}
+
 } // namespace MeshCoP
 } // namespace ot
 
diff --git a/src/core/meshcop/border_agent.hpp b/src/core/meshcop/border_agent.hpp
index f3a01f2..78b9ca4 100644
--- a/src/core/meshcop/border_agent.hpp
+++ b/src/core/meshcop/border_agent.hpp
@@ -40,6 +40,7 @@
 
 #include "coap/coap.hpp"
 #include "common/locator.hpp"
+#include "common/notifier.hpp"
 #include "net/udp6.hpp"
 
 namespace ot {
@@ -48,7 +49,7 @@
 
 namespace MeshCoP {
 
-class BorderAgent : public InstanceLocator
+class BorderAgent : public InstanceLocator, public Notifier::Receiver
 {
 public:
     /**
@@ -63,7 +64,7 @@
      * This method starts the Border Agent service.
      *
      * @retval OT_ERROR_NONE    Successfully started the Border Agent service.
-     * @retval OT_ERROR_ALREADY Already started.
+     * @retval OT_ERROR_ALREADY Border Agent is already started.
      *
      */
     otError Start(void);
@@ -71,7 +72,8 @@
     /**
      * This method stops the Border Agent service.
      *
-     * @retval OT_ERROR_NONE  Successfully stopped the Border Agent service.
+     * @retval OT_ERROR_NONE    Successfully stopped the Border Agent service.
+     * @retval OT_ERROR_ALREADY Border Agent is already stopped.
      *
      */
     otError Stop(void);
@@ -84,7 +86,16 @@
      */
     otBorderAgentState GetState(void) const { return mState; }
 
+    /**
+     * This method applies the Mesh Local Prefix.
+     *
+     */
+    void ApplyMeshLocalPrefix(void);
+
 private:
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
+
     static void HandleConnected(bool aConnected, void *aContext)
     {
         static_cast<BorderAgent *>(aContext)->HandleConnected(aConnected);
@@ -94,9 +105,9 @@
     template <Coap::Resource BorderAgent::*aResource>
     static void HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
     {
-        static_cast<BorderAgent *>(aContext)->ForwardToLeader(
+        IgnoreError(static_cast<BorderAgent *>(aContext)->ForwardToLeader(
             *static_cast<Coap::Message *>(aMessage), *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
-            (static_cast<BorderAgent *>(aContext)->*aResource).GetUriPath(), false, false);
+            (static_cast<BorderAgent *>(aContext)->*aResource).GetUriPath(), false, false));
     }
 
     static void HandleTimeout(Timer &aTimer);
@@ -146,7 +157,7 @@
     Coap::Resource mPendingSet;
     Coap::Resource mProxyTransmit;
 
-    Ip6::UdpReceiver         mUdpReceiver; ///< The UDP receiver to receive packets from external commissioner
+    Ip6::Udp::Receiver       mUdpReceiver; ///< The UDP receiver to receive packets from external commissioner
     Ip6::NetifUnicastAddress mCommissionerAloc;
 
     TimerMilli         mTimer;
diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp
index 06578bd..032493c 100644
--- a/src/core/meshcop/commissioner.cpp
+++ b/src/core/meshcop/commissioner.cpp
@@ -42,6 +42,7 @@
 #include "common/logging.hpp"
 #include "common/string.hpp"
 #include "crypto/pbkdf2_cmac.h"
+#include "meshcop/joiner.hpp"
 #include "meshcop/joiner_router.hpp"
 #include "meshcop/meshcop.hpp"
 #include "meshcop/meshcop_tlvs.hpp"
@@ -56,10 +57,10 @@
 
 Commissioner::Commissioner(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , mActiveJoiner(nullptr)
     , mJoinerPort(0)
     , mJoinerRloc(0)
     , mSessionId(0)
-    , mJoinerIndex(0)
     , mTransmitAttempts(0)
     , mJoinerExpirationTimer(aInstance, HandleJoinerExpirationTimer, this)
     , mTimer(aInstance, HandleTimer, this)
@@ -69,10 +70,10 @@
     , mAnnounceBegin(aInstance)
     , mEnergyScan(aInstance)
     , mPanIdQuery(aInstance)
-    , mStateCallback(NULL)
-    , mJoinerCallback(NULL)
-    , mCallbackContext(NULL)
     , mState(OT_COMMISSIONER_STATE_DISABLED)
+    , mStateCallback(nullptr)
+    , mJoinerCallback(nullptr)
+    , mCallbackContext(nullptr)
 {
     memset(mJoiners, 0, sizeof(mJoiners));
 
@@ -88,11 +89,12 @@
 
 void Commissioner::SetState(otCommissionerState aState)
 {
-    VerifyOrExit(mState != aState);
+    otCommissionerState oldState = mState;
+    OT_UNUSED_VARIABLE(oldState);
 
-    otLogInfoMeshCoP("Commissioner State: %s -> %s", StateToString(mState), StateToString(aState));
+    SuccessOrExit(Get<Notifier>().Update(mState, aState, kEventCommissionerStateChanged));
 
-    mState = aState;
+    otLogInfoMeshCoP("CommissionerState: %s -> %s", StateToString(oldState), StateToString(aState));
 
     if (mStateCallback)
     {
@@ -103,12 +105,33 @@
     return;
 }
 
-void Commissioner::SignalJoinerEvent(otCommissionerJoinerEvent aEvent, const Mac::ExtAddress &aJoinerId)
+void Commissioner::SignalJoinerEvent(otCommissionerJoinerEvent aEvent, const Joiner *aJoiner) const
 {
-    if (mJoinerCallback)
+    otJoinerInfo    joinerInfo;
+    Mac::ExtAddress joinerId;
+    bool            noJoinerId = false;
+
+    VerifyOrExit((mJoinerCallback != nullptr) && (aJoiner != nullptr), OT_NOOP);
+
+    aJoiner->CopyToJoinerInfo(joinerInfo);
+
+    if (aJoiner->mType == Joiner::kTypeEui64)
     {
-        mJoinerCallback(aEvent, &aJoinerId, mCallbackContext);
+        ComputeJoinerId(aJoiner->mSharedId.mEui64, joinerId);
     }
+    else if (aJoiner == mActiveJoiner)
+    {
+        mJoinerIid.ConvertToExtAddress(joinerId);
+    }
+    else
+    {
+        noJoinerId = true;
+    }
+
+    mJoinerCallback(aEvent, &joinerInfo, noJoinerId ? nullptr : &joinerId, mCallbackContext);
+
+exit:
+    return;
 }
 
 void Commissioner::AddCoapResources(void)
@@ -132,15 +155,142 @@
 
 void Commissioner::HandleCoapsConnected(bool aConnected)
 {
-    otCommissionerJoinerEvent event;
-    Mac::ExtAddress           joinerId;
+    SignalJoinerEvent(aConnected ? OT_COMMISSIONER_JOINER_CONNECTED : OT_COMMISSIONER_JOINER_END, mActiveJoiner);
+}
 
-    event = aConnected ? OT_COMMISSIONER_JOINER_CONNECTED : OT_COMMISSIONER_JOINER_END;
+Commissioner::Joiner *Commissioner::GetUnusedJoinerEntry(void)
+{
+    Joiner *rval = nullptr;
 
-    joinerId.Set(mJoinerIid);
-    joinerId.ToggleLocal();
+    for (Joiner &joiner : mJoiners)
+    {
+        if (joiner.mType == Joiner::kTypeUnused)
+        {
+            rval = &joiner;
+            break;
+        }
+    }
 
-    SignalJoinerEvent(event, joinerId);
+    return rval;
+}
+
+Commissioner::Joiner *Commissioner::FindJoinerEntry(const Mac::ExtAddress *aEui64)
+{
+    Joiner *rval = nullptr;
+
+    for (Joiner &joiner : mJoiners)
+    {
+        switch (joiner.mType)
+        {
+        case Joiner::kTypeUnused:
+        case Joiner::kTypeDiscerner:
+            break;
+
+        case Joiner::kTypeAny:
+            if (aEui64 == nullptr)
+            {
+                ExitNow(rval = &joiner);
+            }
+            break;
+
+        case Joiner::kTypeEui64:
+            if ((aEui64 != nullptr) && (joiner.mSharedId.mEui64 == *aEui64))
+            {
+                ExitNow(rval = &joiner);
+            }
+            break;
+        }
+    }
+
+exit:
+    return rval;
+}
+
+Commissioner::Joiner *Commissioner::FindJoinerEntry(const JoinerDiscerner &aDiscerner)
+{
+    Joiner *rval = nullptr;
+
+    for (Joiner &joiner : mJoiners)
+    {
+        if ((joiner.mType == Joiner::kTypeDiscerner) && (aDiscerner == joiner.mSharedId.mDiscerner))
+        {
+            rval = &joiner;
+            break;
+        }
+    }
+
+    return rval;
+}
+
+Commissioner::Joiner *Commissioner::FindBestMatchingJoinerEntry(const Mac::ExtAddress &aReceivedJoinerId)
+{
+    Joiner *        best = nullptr;
+    Mac::ExtAddress joinerId;
+
+    // Prefer a full Joiner ID match, if not found use the entry
+    // accepting any joiner.
+
+    for (Joiner &joiner : mJoiners)
+    {
+        switch (joiner.mType)
+        {
+        case Joiner::kTypeUnused:
+            break;
+
+        case Joiner::kTypeAny:
+            if (best == nullptr)
+            {
+                best = &joiner;
+            }
+            break;
+
+        case Joiner::kTypeEui64:
+            ComputeJoinerId(joiner.mSharedId.mEui64, joinerId);
+            if (joinerId == aReceivedJoinerId)
+            {
+                ExitNow(best = &joiner);
+            }
+            break;
+
+        case Joiner::kTypeDiscerner:
+            if (joiner.mSharedId.mDiscerner.Matches(aReceivedJoinerId))
+            {
+                if ((best == nullptr) ||
+                    ((best->mType == Joiner::kTypeDiscerner) &&
+                     (best->mSharedId.mDiscerner.GetLength() < joiner.mSharedId.mDiscerner.GetLength())))
+                {
+                    best = &joiner;
+                }
+            }
+            break;
+        }
+    }
+
+exit:
+    return best;
+}
+
+void Commissioner::RemoveJoinerEntry(Commissioner::Joiner &aJoiner)
+{
+    // Create a copy of `aJoiner` to use for signaling joiner event
+    // and logging after the entry is removed. This ensures the joiner
+    // event callback is invoked after all states are cleared.
+
+    Joiner joinerCopy = aJoiner;
+
+    aJoiner.mType = Joiner::kTypeUnused;
+
+    if (&aJoiner == mActiveJoiner)
+    {
+        mActiveJoiner = nullptr;
+    }
+
+    UpdateJoinerExpirationTimer();
+
+    SendCommissionerSet();
+
+    LogJoinerEntry("Removed", joinerCopy);
+    SignalJoinerEvent(OT_COMMISSIONER_JOINER_REMOVED, &joinerCopy);
 }
 
 otError Commissioner::Start(otCommissionerStateCallback  aStateCallback,
@@ -150,7 +300,12 @@
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(Get<Mle::MleRouter>().IsAttached(), error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(mState == OT_COMMISSIONER_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(mState == OT_COMMISSIONER_STATE_DISABLED, error = OT_ERROR_ALREADY);
+
+#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
+    error = Get<MeshCoP::BorderAgent>().Stop();
+    VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_ALREADY, OT_NOOP);
+#endif
 
     SuccessOrExit(error = Get<Coap::CoapSecure>().Start(SendRelayTransmit, this));
     Get<Coap::CoapSecure>().SetConnectedCallback(&Commissioner::HandleCoapsConnected, this);
@@ -164,154 +319,223 @@
     SetState(OT_COMMISSIONER_STATE_PETITION);
 
 exit:
+    if (error != OT_ERROR_NONE)
+    {
+        otLogWarnMeshCoP("Failed to start commissioner: %s", otThreadErrorToString(error));
+        if (error != OT_ERROR_ALREADY)
+        {
+            Get<Coap::CoapSecure>().Stop();
+        }
+    }
+
     return error;
 }
 
-otError Commissioner::Stop(void)
+otError Commissioner::Stop(bool aResign)
 {
-    otError error = OT_ERROR_NONE;
+    otError error      = OT_ERROR_NONE;
+    bool    needResign = false;
 
-    VerifyOrExit(mState != OT_COMMISSIONER_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(mState != OT_COMMISSIONER_STATE_DISABLED, error = OT_ERROR_ALREADY);
 
     Get<Coap::CoapSecure>().Stop();
 
-    Get<ThreadNetif>().RemoveUnicastAddress(mCommissionerAloc);
-    RemoveCoapResources();
-    ClearJoiners();
-    mTransmitAttempts = 0;
+    if (mState == OT_COMMISSIONER_STATE_ACTIVE)
+    {
+        Get<ThreadNetif>().RemoveUnicastAddress(mCommissionerAloc);
+        RemoveCoapResources();
+        ClearJoiners();
+        needResign = true;
+    }
+    else if (mState == OT_COMMISSIONER_STATE_PETITION)
+    {
+        mTransmitAttempts = 0;
+    }
 
     mTimer.Stop();
 
     SetState(OT_COMMISSIONER_STATE_DISABLED);
 
-    SendKeepAlive();
+    if (needResign && aResign)
+    {
+        SendKeepAlive();
+    }
 
 exit:
+    if (error != OT_ERROR_NONE)
+    {
+        otLogWarnMeshCoP("Failed to stop Commissioner: %s", otThreadErrorToString(error));
+    }
+
     return error;
 }
 
-otError Commissioner::SendCommissionerSet(void)
+void Commissioner::ComputeBloomFilter(SteeringData &aSteeringData) const
 {
-    otError                error;
+    Mac::ExtAddress joinerId;
+
+    aSteeringData.Init();
+
+    for (const Joiner &joiner : mJoiners)
+    {
+        switch (joiner.mType)
+        {
+        case Joiner::kTypeUnused:
+            break;
+
+        case Joiner::kTypeEui64:
+            ComputeJoinerId(joiner.mSharedId.mEui64, joinerId);
+            aSteeringData.UpdateBloomFilter(joinerId);
+            break;
+
+        case Joiner::kTypeDiscerner:
+            aSteeringData.UpdateBloomFilter(joiner.mSharedId.mDiscerner);
+            break;
+
+        case Joiner::kTypeAny:
+            aSteeringData.SetToPermitAllJoiners();
+            ExitNow();
+        }
+    }
+
+exit:
+    return;
+}
+
+void Commissioner::SendCommissionerSet(void)
+{
+    otError                error = OT_ERROR_NONE;
     otCommissioningDataset dataset;
-    SteeringDataTlv        steeringData;
-    Mac::ExtAddress        joinerId;
 
     VerifyOrExit(mState == OT_COMMISSIONER_STATE_ACTIVE, error = OT_ERROR_INVALID_STATE);
 
     memset(&dataset, 0, sizeof(dataset));
 
-    // session id
     dataset.mSessionId      = mSessionId;
     dataset.mIsSessionIdSet = true;
 
-    // compute bloom filter
-    steeringData.Init();
-    steeringData.Clear();
-
-    for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++)
-    {
-        if (!joiner->mValid)
-        {
-            continue;
-        }
-
-        if (joiner->mAny)
-        {
-            steeringData.SetLength(1);
-            steeringData.Set();
-            break;
-        }
-
-        ComputeJoinerId(joiner->mEui64, joinerId);
-        steeringData.ComputeBloomFilter(joinerId);
-    }
-
-    // set bloom filter
-    dataset.mSteeringData.mLength = steeringData.GetSteeringDataLength();
-    memcpy(dataset.mSteeringData.m8, steeringData.GetValue(), dataset.mSteeringData.mLength);
+    ComputeBloomFilter(static_cast<SteeringData &>(dataset.mSteeringData));
     dataset.mIsSteeringDataSet = true;
 
-    SuccessOrExit(error = SendMgmtCommissionerSetRequest(dataset, NULL, 0));
+    error = SendMgmtCommissionerSetRequest(dataset, nullptr, 0);
 
 exit:
-    return error;
+    if (error != OT_ERROR_NONE)
+    {
+        otLogWarnMeshCoP("Failed to send MGMT_COMMISSIONER_SET.req: %s", otThreadErrorToString(error));
+    }
 }
 
 void Commissioner::ClearJoiners(void)
 {
-    for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++)
+    for (Joiner &joiner : mJoiners)
     {
-        joiner->mValid = false;
+        joiner.mType = Joiner::kTypeUnused;
     }
 
     SendCommissionerSet();
 }
 
-otError Commissioner::AddJoiner(const Mac::ExtAddress *aEui64, const char *aPskd, uint32_t aTimeout)
+otError Commissioner::AddJoiner(const Mac::ExtAddress *aEui64,
+                                const JoinerDiscerner *aDiscerner,
+                                const char *           aPskd,
+                                uint32_t               aTimeout)
 {
-    otError error = OT_ERROR_NO_BUFS;
+    otError error = OT_ERROR_NONE;
+    Joiner *joiner;
 
     VerifyOrExit(mState == OT_COMMISSIONER_STATE_ACTIVE, error = OT_ERROR_INVALID_STATE);
 
-    VerifyOrExit(StringLength(aPskd, Dtls::kPskMaxLength + 1) <= Dtls::kPskMaxLength, error = OT_ERROR_INVALID_ARGS);
-
-    RemoveJoiner(aEui64, 0); // remove immediately
-
-    for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++)
+    if (aDiscerner != nullptr)
     {
-        if (joiner->mValid)
-        {
-            continue;
-        }
-
-        if (aEui64 != NULL)
-        {
-            joiner->mEui64 = *aEui64;
-            joiner->mAny   = false;
-        }
-        else
-        {
-            joiner->mAny = true;
-        }
-
-        strncpy(joiner->mPsk, aPskd, sizeof(joiner->mPsk) - 1);
-        joiner->mValid          = true;
-        joiner->mExpirationTime = TimerMilli::GetNow() + Time::SecToMsec(aTimeout);
-
-        UpdateJoinerExpirationTimer();
-
-        SendCommissionerSet();
-
-        otLogInfoMeshCoP("Added Joiner (%s, %s)", (aEui64 != NULL) ? aEui64->ToString().AsCString() : "*", aPskd);
-
-        ExitNow(error = OT_ERROR_NONE);
+        VerifyOrExit(aDiscerner->IsValid(), error = OT_ERROR_INVALID_ARGS);
+        joiner = FindJoinerEntry(*aDiscerner);
     }
+    else
+    {
+        joiner = FindJoinerEntry(aEui64);
+    }
+
+    if (joiner == nullptr)
+    {
+        joiner = GetUnusedJoinerEntry();
+    }
+
+    VerifyOrExit(joiner != nullptr, error = OT_ERROR_NO_BUFS);
+
+    SuccessOrExit(error = joiner->mPskd.SetFrom(aPskd));
+
+    if (aDiscerner != nullptr)
+    {
+        joiner->mType                = Joiner::kTypeDiscerner;
+        joiner->mSharedId.mDiscerner = *aDiscerner;
+    }
+    else if (aEui64 != nullptr)
+    {
+        joiner->mType            = Joiner::kTypeEui64;
+        joiner->mSharedId.mEui64 = *aEui64;
+    }
+    else
+    {
+        joiner->mType = Joiner::kTypeAny;
+    }
+
+    joiner->mExpirationTime = TimerMilli::GetNow() + Time::SecToMsec(aTimeout);
+
+    UpdateJoinerExpirationTimer();
+
+    SendCommissionerSet();
+
+    LogJoinerEntry("Added", *joiner);
 
 exit:
     return error;
 }
 
-otError Commissioner::GetNextJoinerInfo(uint16_t &aIterator, otJoinerInfo &aJoiner) const
+void Commissioner::Joiner::CopyToJoinerInfo(otJoinerInfo &aInfo) const
+{
+    memset(&aInfo, 0, sizeof(aInfo));
+
+    switch (mType)
+    {
+    case kTypeAny:
+        aInfo.mType = OT_JOINER_INFO_TYPE_ANY;
+        break;
+
+    case kTypeEui64:
+        aInfo.mType            = OT_JOINER_INFO_TYPE_EUI64;
+        aInfo.mSharedId.mEui64 = mSharedId.mEui64;
+        break;
+
+    case kTypeDiscerner:
+        aInfo.mType                = OT_JOINER_INFO_TYPE_DISCERNER;
+        aInfo.mSharedId.mDiscerner = mSharedId.mDiscerner;
+        break;
+
+    case kTypeUnused:
+        ExitNow();
+    }
+
+    aInfo.mPskd           = mPskd;
+    aInfo.mExpirationTime = mExpirationTime - TimerMilli::GetNow();
+
+exit:
+    return;
+}
+
+otError Commissioner::GetNextJoinerInfo(uint16_t &aIterator, otJoinerInfo &aInfo) const
 {
     otError error = OT_ERROR_NONE;
-    size_t  index;
 
-    for (index = aIterator; index < OT_ARRAY_LENGTH(mJoiners); index++)
+    while (aIterator < OT_ARRAY_LENGTH(mJoiners))
     {
-        if (!mJoiners[index].mValid)
+        const Joiner &joiner = mJoiners[aIterator++];
+
+        if (joiner.mType != Joiner::kTypeUnused)
         {
-            continue;
+            joiner.CopyToJoinerInfo(aInfo);
+            ExitNow();
         }
-
-        memset(&aJoiner, 0, sizeof(aJoiner));
-
-        aJoiner.mAny   = mJoiners[index].mAny;
-        aJoiner.mEui64 = mJoiners[index].mEui64;
-        strncpy(aJoiner.mPsk, mJoiners[index].mPsk, sizeof(aJoiner.mPsk) - 1);
-        aJoiner.mExpirationTime = mJoiners[index].mExpirationTime - TimerMilli::GetNow();
-        aIterator               = static_cast<uint16_t>(index) + 1;
-        ExitNow();
     }
 
     error = OT_ERROR_NOT_FOUND;
@@ -320,68 +544,55 @@
     return error;
 }
 
-otError Commissioner::RemoveJoiner(const Mac::ExtAddress *aEui64, uint32_t aDelay)
+otError Commissioner::RemoveJoiner(const Mac::ExtAddress *aEui64, const JoinerDiscerner *aDiscerner, uint32_t aDelay)
 {
-    otError error = OT_ERROR_NOT_FOUND;
+    otError error = OT_ERROR_NONE;
+    Joiner *joiner;
 
     VerifyOrExit(mState == OT_COMMISSIONER_STATE_ACTIVE, error = OT_ERROR_INVALID_STATE);
 
-    for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++)
+    if (aDiscerner != nullptr)
     {
-        if (!joiner->mValid)
-        {
-            continue;
-        }
-
-        if (aEui64 != NULL)
-        {
-            if (joiner->mEui64 != *aEui64)
-            {
-                continue;
-            }
-        }
-        else if (!joiner->mAny)
-        {
-            continue;
-        }
-
-        if (aDelay > 0)
-        {
-            TimeMilli now = TimerMilli::GetNow();
-
-            if ((joiner->mExpirationTime > now) && (joiner->mExpirationTime - now > Time::SecToMsec(aDelay)))
-            {
-                joiner->mExpirationTime = now + Time::SecToMsec(aDelay);
-                UpdateJoinerExpirationTimer();
-            }
-        }
-        else
-        {
-            Mac::ExtAddress joinerId;
-
-            joiner->mValid = false;
-            UpdateJoinerExpirationTimer();
-            SendCommissionerSet();
-
-            otLogInfoMeshCoP("Removed Joiner (%s)", (aEui64 != NULL) ? aEui64->ToString().AsCString() : "*");
-
-            ComputeJoinerId(joiner->mEui64, joinerId);
-            SignalJoinerEvent(OT_COMMISSIONER_JOINER_REMOVED, joinerId);
-        }
-
-        ExitNow(error = OT_ERROR_NONE);
+        VerifyOrExit(aDiscerner->IsValid(), error = OT_ERROR_INVALID_ARGS);
+        joiner = FindJoinerEntry(*aDiscerner);
     }
+    else
+    {
+        joiner = FindJoinerEntry(aEui64);
+    }
+
+    VerifyOrExit(joiner != nullptr, error = OT_ERROR_NOT_FOUND);
+
+    RemoveJoiner(*joiner, aDelay);
 
 exit:
     return error;
 }
 
+void Commissioner::RemoveJoiner(Joiner &aJoiner, uint32_t aDelay)
+{
+    if (aDelay > 0)
+    {
+        TimeMilli newExpirationTime = TimerMilli::GetNow() + Time::SecToMsec(aDelay);
+
+        if (aJoiner.mExpirationTime > newExpirationTime)
+        {
+            aJoiner.mExpirationTime = newExpirationTime;
+            UpdateJoinerExpirationTimer();
+        }
+    }
+    else
+    {
+        RemoveJoinerEntry(aJoiner);
+    }
+}
+
 otError Commissioner::SetProvisioningUrl(const char *aProvisioningUrl)
 {
     otError error = OT_ERROR_NONE;
     uint8_t len;
 
-    if (aProvisioningUrl == NULL)
+    if (aProvisioningUrl == nullptr)
     {
         mProvisioningUrl[0] = '\0';
         ExitNow();
@@ -411,7 +622,7 @@
         break;
 
     case OT_COMMISSIONER_STATE_PETITION:
-        SendPetition();
+        IgnoreError(SendPetition());
         break;
 
     case OT_COMMISSIONER_STATE_ACTIVE:
@@ -429,18 +640,17 @@
 {
     TimeMilli now = TimerMilli::GetNow();
 
-    // Remove Joiners.
-    for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++)
+    for (Joiner &joiner : mJoiners)
     {
-        if (!joiner->mValid)
+        if (joiner.mType == Joiner::kTypeUnused)
         {
             continue;
         }
 
-        if (now >= joiner->mExpirationTime)
+        if (joiner.mExpirationTime <= now)
         {
             otLogDebgMeshCoP("removing joiner due to timeout or successfully joined");
-            RemoveJoiner(&joiner->mEui64, 0); // remove immediately
+            RemoveJoinerEntry(joiner);
         }
     }
 
@@ -449,41 +659,32 @@
 
 void Commissioner::UpdateJoinerExpirationTimer(void)
 {
-    TimeMilli now         = TimerMilli::GetNow();
-    uint32_t  nextTimeout = TimeMilli::kMaxDuration;
+    TimeMilli now  = TimerMilli::GetNow();
+    TimeMilli next = now.GetDistantFuture();
 
-    // Check if timer should be set for next Joiner.
-    for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++)
+    for (Joiner &joiner : mJoiners)
     {
-        uint32_t diff;
-
-        if (!joiner->mValid)
+        if (joiner.mType == Joiner::kTypeUnused)
         {
             continue;
         }
 
-        if (now >= joiner->mExpirationTime)
+        if (joiner.mExpirationTime <= now)
         {
-            nextTimeout = 0;
-            break;
+            next = now;
         }
-
-        diff = joiner->mExpirationTime - now;
-
-        if (diff < nextTimeout)
+        else if (joiner.mExpirationTime < next)
         {
-            nextTimeout = diff;
+            next = joiner.mExpirationTime;
         }
     }
 
-    if (nextTimeout != TimeMilli::kMaxDuration)
+    if (next < now.GetDistantFuture())
     {
-        // Update the timer to the timeout of the next Joiner.
-        mJoinerExpirationTimer.Start(nextTimeout);
+        mJoinerExpirationTimer.FireAt(next);
     }
     else
     {
-        // No Joiners, stop the timer.
         mJoinerExpirationTimer.Stop();
     }
 }
@@ -495,7 +696,7 @@
     Ip6::MessageInfo messageInfo;
     MeshCoP::Tlv     tlv;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_COMMISSIONER_GET));
 
@@ -522,7 +723,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -545,7 +746,7 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage->GetCode() == OT_COAP_CODE_CHANGED);
+    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage->GetCode() == OT_COAP_CODE_CHANGED, OT_NOOP);
     otLogInfoMeshCoP("received MGMT_COMMISSIONER_GET response");
 
 exit:
@@ -560,42 +761,31 @@
     Coap::Message *  message;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_COMMISSIONER_SET));
     SuccessOrExit(error = message->SetPayloadMarker());
 
     if (aDataset.mIsLocatorSet)
     {
-        MeshCoP::BorderAgentLocatorTlv locator;
-        locator.Init();
-        locator.SetBorderAgentLocator(aDataset.mLocator);
-        SuccessOrExit(error = locator.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kBorderAgentLocator, aDataset.mLocator));
     }
 
     if (aDataset.mIsSessionIdSet)
     {
-        MeshCoP::CommissionerSessionIdTlv sessionId;
-        sessionId.Init();
-        sessionId.SetCommissionerSessionId(aDataset.mSessionId);
-        SuccessOrExit(error = sessionId.AppendTo(*message));
+        SuccessOrExit(error =
+                          Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kCommissionerSessionId, aDataset.mSessionId));
     }
 
     if (aDataset.mIsSteeringDataSet)
     {
-        MeshCoP::SteeringDataTlv steeringData;
-        steeringData.Init();
-        steeringData.SetLength(aDataset.mSteeringData.mLength);
-        SuccessOrExit(error = message->Append(&steeringData, sizeof(MeshCoP::Tlv)));
-        SuccessOrExit(error = message->Append(&aDataset.mSteeringData.m8, aDataset.mSteeringData.mLength));
+        SuccessOrExit(error = Tlv::AppendTlv(*message, MeshCoP::Tlv::kSteeringData, aDataset.mSteeringData.m8,
+                                             aDataset.mSteeringData.mLength));
     }
 
     if (aDataset.mIsJoinerUdpPortSet)
     {
-        MeshCoP::JoinerUdpPortTlv joinerUdpPort;
-        joinerUdpPort.Init();
-        joinerUdpPort.SetUdpPort(aDataset.mJoinerUdpPort);
-        SuccessOrExit(error = joinerUdpPort.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kJoinerUdpPort, aDataset.mJoinerUdpPort));
     }
 
     if (aLength > 0)
@@ -606,7 +796,7 @@
     if (message->GetLength() == message->GetOffset())
     {
         // no payload, remove coap payload marker
-        message->SetLength(message->GetLength() - 1);
+        IgnoreError(message->SetLength(message->GetLength() - 1));
     }
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
@@ -619,7 +809,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -642,7 +832,7 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage->GetCode() == OT_COAP_CODE_CHANGED);
+    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage->GetCode() == OT_COAP_CODE_CHANGED, OT_NOOP);
     otLogInfoMeshCoP("received MGMT_COMMISSIONER_SET response");
 
 exit:
@@ -652,13 +842,13 @@
 otError Commissioner::SendPetition(void)
 {
     otError           error   = OT_ERROR_NONE;
-    Coap::Message *   message = NULL;
+    Coap::Message *   message = nullptr;
     Ip6::MessageInfo  messageInfo;
     CommissionerIdTlv commissionerId;
 
     mTransmitAttempts++;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_LEADER_PETITION));
     SuccessOrExit(error = message->SetPayloadMarker());
@@ -678,7 +868,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -701,25 +891,29 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    StateTlv                 state;
-    CommissionerSessionIdTlv sessionId;
-    bool                     retransmit = false;
+    uint8_t state;
+    bool    retransmit = false;
 
-    VerifyOrExit(mState == OT_COMMISSIONER_STATE_PETITION, SetState(OT_COMMISSIONER_STATE_DISABLED));
-    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage->GetCode() == OT_COAP_CODE_CHANGED, retransmit = true);
+    VerifyOrExit(mState != OT_COMMISSIONER_STATE_ACTIVE, OT_NOOP);
+    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage->GetCode() == OT_COAP_CODE_CHANGED,
+                 retransmit = (mState == OT_COMMISSIONER_STATE_PETITION));
 
     otLogInfoMeshCoP("received Leader Petition response");
 
-    SuccessOrExit(Tlv::GetTlv(*aMessage, Tlv::kState, sizeof(state), state));
-    VerifyOrExit(state.IsValid());
+    SuccessOrExit(Tlv::FindUint8Tlv(*aMessage, Tlv::kState, state));
+    VerifyOrExit(state == StateTlv::kAccept, IgnoreError(Stop(/* aResign */ false)));
 
-    VerifyOrExit(state.GetState() == StateTlv::kAccept, SetState(OT_COMMISSIONER_STATE_DISABLED));
+    SuccessOrExit(Tlv::FindUint16Tlv(*aMessage, Tlv::kCommissionerSessionId, mSessionId));
 
-    SuccessOrExit(Tlv::GetTlv(*aMessage, Tlv::kCommissionerSessionId, sizeof(sessionId), sessionId));
-    VerifyOrExit(sessionId.IsValid());
-    mSessionId = sessionId.GetCommissionerSessionId();
+    // reject this session by sending KeepAlive reject if commissioner is in disabled state
+    // this could happen if commissioner is stopped by API during petitioning
+    if (mState == OT_COMMISSIONER_STATE_DISABLED)
+    {
+        SendKeepAlive(mSessionId);
+        ExitNow();
+    }
 
-    Get<Mle::MleRouter>().GetCommissionerAloc(mCommissionerAloc.GetAddress(), mSessionId);
+    IgnoreError(Get<Mle::MleRouter>().GetCommissionerAloc(mCommissionerAloc.GetAddress(), mSessionId));
     Get<ThreadNetif>().AddUnicastAddress(mCommissionerAloc);
 
     AddCoapResources();
@@ -734,7 +928,7 @@
     {
         if (mTransmitAttempts >= kPetitionRetryCount)
         {
-            SetState(OT_COMMISSIONER_STATE_DISABLED);
+            IgnoreError(Stop(/* aResign */ false));
         }
         else
         {
@@ -743,26 +937,27 @@
     }
 }
 
-otError Commissioner::SendKeepAlive(void)
+void Commissioner::SendKeepAlive(void)
 {
-    otError                  error   = OT_ERROR_NONE;
-    Coap::Message *          message = NULL;
-    Ip6::MessageInfo         messageInfo;
-    StateTlv                 state;
-    CommissionerSessionIdTlv sessionId;
+    SendKeepAlive(mSessionId);
+}
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+void Commissioner::SendKeepAlive(uint16_t aSessionId)
+{
+    otError          error   = OT_ERROR_NONE;
+    Coap::Message *  message = nullptr;
+    Ip6::MessageInfo messageInfo;
+
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_LEADER_KEEP_ALIVE));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    state.Init();
-    state.SetState(mState == OT_COMMISSIONER_STATE_ACTIVE ? StateTlv::kAccept : StateTlv::kReject);
-    SuccessOrExit(error = state.AppendTo(*message));
+    SuccessOrExit(
+        error = Tlv::AppendUint8Tlv(*message, Tlv::kState,
+                                    (mState == OT_COMMISSIONER_STATE_ACTIVE) ? StateTlv::kAccept : StateTlv::kReject));
 
-    sessionId.Init();
-    sessionId.SetCommissionerSessionId(mSessionId);
-    SuccessOrExit(error = sessionId.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kCommissionerSessionId, aSessionId));
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     SuccessOrExit(error = Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr()));
@@ -774,12 +969,15 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        message->Free();
-    }
+        otLogWarnMeshCoP("Failed to send keep alive: %s", otThreadErrorToString(error));
 
-    return error;
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
 }
 
 void Commissioner::HandleLeaderKeepAliveResponse(void *               aContext,
@@ -797,28 +995,21 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    StateTlv state;
+    uint8_t state;
 
-    VerifyOrExit(mState == OT_COMMISSIONER_STATE_ACTIVE, SetState(OT_COMMISSIONER_STATE_DISABLED));
+    VerifyOrExit(mState == OT_COMMISSIONER_STATE_ACTIVE, OT_NOOP);
     VerifyOrExit(aResult == OT_ERROR_NONE && aMessage->GetCode() == OT_COAP_CODE_CHANGED,
-                 SetState(OT_COMMISSIONER_STATE_DISABLED));
+                 IgnoreError(Stop(/* aResign */ false)));
 
     otLogInfoMeshCoP("received Leader keep-alive response");
 
-    SuccessOrExit(Tlv::GetTlv(*aMessage, Tlv::kState, sizeof(state), state));
-    VerifyOrExit(state.IsValid());
-
-    VerifyOrExit(state.GetState() == StateTlv::kAccept, SetState(OT_COMMISSIONER_STATE_DISABLED));
+    SuccessOrExit(Tlv::FindUint8Tlv(*aMessage, Tlv::kState, state));
+    VerifyOrExit(state == StateTlv::kAccept, IgnoreError(Stop(/* aResign */ false)));
 
     mTimer.Start(Time::SecToMsec(kKeepAliveTimeout) / 2);
 
 exit:
-
-    if (mState != OT_COMMISSIONER_STATE_ACTIVE)
-    {
-        Get<ThreadNetif>().RemoveUnicastAddress(mCommissionerAloc);
-        RemoveCoapResources();
-    }
+    return;
 }
 
 void Commissioner::HandleRelayReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -831,77 +1022,51 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    otError                error;
-    JoinerUdpPortTlv       joinerPort;
-    JoinerIidTlv           joinerIid;
-    JoinerRouterLocatorTlv joinerRloc;
-    Ip6::MessageInfo       joinerMessageInfo;
-    uint16_t               offset;
-    uint16_t               length;
-    bool                   enableJoiner = false;
-    Mac::ExtAddress        receivedId;
-    Mac::ExtAddress        joinerId;
+    otError                  error;
+    uint16_t                 joinerPort;
+    Ip6::InterfaceIdentifier joinerIid;
+    uint16_t                 joinerRloc;
+    Ip6::MessageInfo         joinerMessageInfo;
+    uint16_t                 offset;
+    uint16_t                 length;
 
     VerifyOrExit(mState == OT_COMMISSIONER_STATE_ACTIVE, error = OT_ERROR_INVALID_STATE);
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_NON_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsNonConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerUdpPort, sizeof(joinerPort), joinerPort));
-    VerifyOrExit(joinerPort.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kJoinerUdpPort, joinerPort));
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, Tlv::kJoinerIid, &joinerIid, sizeof(joinerIid)));
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kJoinerRouterLocator, joinerRloc));
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerIid, sizeof(joinerIid), joinerIid));
-    VerifyOrExit(joinerIid.IsValid(), error = OT_ERROR_PARSE);
-
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerRouterLocator, sizeof(joinerRloc), joinerRloc));
-    VerifyOrExit(joinerRloc.IsValid(), error = OT_ERROR_PARSE);
-
-    SuccessOrExit(error = Tlv::GetValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length));
+    SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length));
     VerifyOrExit(length <= aMessage.GetLength() - offset, error = OT_ERROR_PARSE);
 
     if (!Get<Coap::CoapSecure>().IsConnectionActive())
     {
-        memcpy(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid));
+        Mac::ExtAddress receivedId;
+        Joiner *        joiner;
 
-        receivedId.Set(mJoinerIid);
-        receivedId.ToggleLocal();
+        mJoinerIid = joinerIid;
+        mJoinerIid.ConvertToExtAddress(receivedId);
 
-        for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++)
-        {
-            if (!joiner->mValid)
-            {
-                continue;
-            }
+        joiner = FindBestMatchingJoinerEntry(receivedId);
+        VerifyOrExit(joiner != nullptr, OT_NOOP);
 
-            ComputeJoinerId(joiner->mEui64, joinerId);
+        Get<Coap::CoapSecure>().SetPsk(joiner->mPskd);
+        mActiveJoiner = joiner;
 
-            if (joiner->mAny || (joinerId == receivedId))
-            {
-                error = Get<Coap::CoapSecure>().SetPsk(reinterpret_cast<const uint8_t *>(joiner->mPsk),
-                                                       static_cast<uint8_t>(strlen(joiner->mPsk)));
-                SuccessOrExit(error);
-                mJoinerIndex = static_cast<uint8_t>(joiner - mJoiners);
-                enableJoiner = true;
-
-                otLogInfoMeshCoP("found joiner, starting new session");
-                SignalJoinerEvent(OT_COMMISSIONER_JOINER_START, joinerId);
-
-                break;
-            }
-        }
+        LogJoinerEntry("Starting new session with", *joiner);
+        SignalJoinerEvent(OT_COMMISSIONER_JOINER_START, joiner);
     }
     else
     {
-        enableJoiner = (memcmp(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid)) == 0);
+        VerifyOrExit(mJoinerIid == joinerIid, OT_NOOP);
     }
 
-    VerifyOrExit(enableJoiner);
+    mJoinerPort = joinerPort;
+    mJoinerRloc = joinerRloc;
 
-    mJoinerPort = joinerPort.GetUdpPort();
-    mJoinerRloc = joinerRloc.GetJoinerRouterLocator();
-
-    otLogInfoMeshCoP("Remove Relay Receive (%02x%02x%02x%02x%02x%02x%02x%02x, 0x%04x)", mJoinerIid[0], mJoinerIid[1],
-                     mJoinerIid[2], mJoinerIid[3], mJoinerIid[4], mJoinerIid[5], mJoinerIid[6], mJoinerIid[7],
-                     mJoinerRloc);
+    otLogInfoMeshCoP("Remove Relay Receive (%s, 0x%04x)", mJoinerIid.ToString().AsCString(), mJoinerRloc);
 
     aMessage.SetOffset(offset);
     SuccessOrExit(error = aMessage.SetLength(offset + length));
@@ -924,7 +1089,7 @@
 
 void Commissioner::HandleDatasetChanged(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
     otLogInfoMeshCoP("received dataset changed");
 
@@ -951,7 +1116,7 @@
 
     otLogInfoMeshCoP("received joiner finalize");
 
-    if (Tlv::GetTlv(aMessage, Tlv::kProvisioningUrl, sizeof(provisioningUrl), provisioningUrl) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kProvisioningUrl, sizeof(provisioningUrl), provisioningUrl) == OT_ERROR_NONE)
     {
         uint8_t len = static_cast<uint8_t>(StringLength(mProvisioningUrl, sizeof(mProvisioningUrl)));
 
@@ -978,22 +1143,18 @@
 
 void Commissioner::SendJoinFinalizeResponse(const Coap::Message &aRequest, StateTlv::State aState)
 {
-    otError           error = OT_ERROR_NONE;
-    Ip6::MessageInfo  joinerMessageInfo;
-    MeshCoP::StateTlv stateTlv;
-    Coap::Message *   message;
-    Mac::ExtAddress   joinerId;
+    otError          error = OT_ERROR_NONE;
+    Ip6::MessageInfo joinerMessageInfo;
+    Coap::Message *  message;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
     SuccessOrExit(error = message->SetPayloadMarker());
     message->SetOffset(message->GetLength());
     message->SetSubType(Message::kSubTypeJoinerFinalizeResponse);
 
-    stateTlv.Init();
-    stateTlv.SetState(aState);
-    SuccessOrExit(error = stateTlv.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, Tlv::kState, static_cast<uint8_t>(aState)));
 
     joinerMessageInfo.SetPeerAddr(Get<Mle::MleRouter>().GetMeshLocal64());
     joinerMessageInfo.GetPeerAddr().SetIid(mJoinerIid);
@@ -1002,28 +1163,26 @@
 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
     uint8_t buf[OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE];
 
-    VerifyOrExit(message->GetLength() <= sizeof(buf));
+    VerifyOrExit(message->GetLength() <= sizeof(buf), OT_NOOP);
     message->Read(message->GetOffset(), message->GetLength() - message->GetOffset(), buf);
     otDumpCertMeshCoP("[THCI] direction=send | type=JOIN_FIN.rsp |", buf, message->GetLength() - message->GetOffset());
 #endif
 
     SuccessOrExit(error = Get<Coap::CoapSecure>().SendMessage(*message, joinerMessageInfo));
 
-    joinerId.Set(mJoinerIid);
-    joinerId.ToggleLocal();
-    SignalJoinerEvent(OT_COMMISSIONER_JOINER_FINALIZE, joinerId);
+    SignalJoinerEvent(OT_COMMISSIONER_JOINER_FINALIZE, mActiveJoiner);
 
-    if (!mJoiners[mJoinerIndex].mAny)
+    if ((mActiveJoiner != nullptr) && (mActiveJoiner->mType != Joiner::kTypeAny))
     {
-        // remove after kRemoveJoinerDelay (seconds)
-        RemoveJoiner(&mJoiners[mJoinerIndex].mEui64, kRemoveJoinerDelay);
+        // Remove after kRemoveJoinerDelay (seconds)
+        RemoveJoiner(*mActiveJoiner, kRemoveJoinerDelay);
     }
 
     otLogInfoMeshCoP("sent joiner finalize response");
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -1038,39 +1197,26 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    otError                error = OT_ERROR_NONE;
-    JoinerUdpPortTlv       udpPort;
-    JoinerIidTlv           iid;
-    JoinerRouterLocatorTlv rloc;
-    ExtendedTlv            tlv;
-    Coap::Message *        message;
-    uint16_t               offset;
-    Ip6::MessageInfo       messageInfo;
+    otError          error = OT_ERROR_NONE;
+    ExtendedTlv      tlv;
+    Coap::Message *  message;
+    uint16_t         offset;
+    Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST);
     SuccessOrExit(error = message->AppendUriPathOptions(OT_URI_PATH_RELAY_TX));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    udpPort.Init();
-    udpPort.SetUdpPort(mJoinerPort);
-    SuccessOrExit(error = udpPort.AppendTo(*message));
-
-    iid.Init();
-    iid.SetIid(mJoinerIid);
-    SuccessOrExit(error = iid.AppendTo(*message));
-
-    rloc.Init();
-    rloc.SetJoinerRouterLocator(mJoinerRloc);
-    SuccessOrExit(error = rloc.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kJoinerUdpPort, mJoinerPort));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kJoinerIid, &mJoinerIid, sizeof(mJoinerIid)));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kJoinerRouterLocator, mJoinerRloc));
 
     if (aMessage.GetSubType() == Message::kSubTypeJoinerFinalizeResponse)
     {
-        JoinerRouterKekTlv kek;
-        kek.Init();
-        kek.SetKek(Get<KeyManager>().GetKek());
-        SuccessOrExit(error = kek.AppendTo(*message));
+        SuccessOrExit(
+            error = Tlv::AppendTlv(*message, Tlv::kJoinerRouterKek, Get<KeyManager>().GetKek().GetKey(), Kek::kSize));
     }
 
     tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
@@ -1081,7 +1227,7 @@
     aMessage.CopyTo(0, offset, aMessage.GetLength(), *message);
 
     messageInfo.SetPeerAddr(Get<Mle::MleRouter>().GetMeshLocal16());
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(mJoinerRloc);
+    messageInfo.GetPeerAddr().GetIid().SetLocator(mJoinerRloc);
     messageInfo.SetPeerPort(kCoapUdpPort);
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
@@ -1090,7 +1236,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -1098,46 +1244,21 @@
     return error;
 }
 
-otError Commissioner::GeneratePskc(const char *              aPassPhrase,
-                                   const char *              aNetworkName,
-                                   const Mac::ExtendedPanId &aExtPanId,
-                                   Pskc &                    aPskc)
+void Commissioner::ApplyMeshLocalPrefix(void)
 {
-    otError    error        = OT_ERROR_NONE;
-    const char saltPrefix[] = "Thread";
-    uint8_t    salt[OT_PBKDF2_SALT_MAX_LEN];
-    uint16_t   saltLen = 0;
-    uint16_t   passphraseLen;
-    uint8_t    networkNameLen;
+    VerifyOrExit(mState == OT_COMMISSIONER_STATE_ACTIVE, OT_NOOP);
 
-    passphraseLen  = static_cast<uint16_t>(StringLength(aPassPhrase, OT_COMMISSIONING_PASSPHRASE_MAX_SIZE + 1));
-    networkNameLen = static_cast<uint8_t>(StringLength(aNetworkName, OT_NETWORK_NAME_MAX_SIZE + 1));
-
-    VerifyOrExit((passphraseLen >= OT_COMMISSIONING_PASSPHRASE_MIN_SIZE) &&
-                     (passphraseLen <= OT_COMMISSIONING_PASSPHRASE_MAX_SIZE) &&
-                     (networkNameLen <= OT_NETWORK_NAME_MAX_SIZE),
-                 error = OT_ERROR_INVALID_ARGS);
-
-    memset(salt, 0, sizeof(salt));
-    memcpy(salt, saltPrefix, sizeof(saltPrefix) - 1);
-    saltLen += static_cast<uint16_t>(sizeof(saltPrefix) - 1);
-
-    memcpy(salt + saltLen, aExtPanId.m8, sizeof(aExtPanId));
-    saltLen += OT_EXT_PAN_ID_SIZE;
-
-    memcpy(salt + saltLen, aNetworkName, networkNameLen);
-    saltLen += networkNameLen;
-
-    otPbkdf2Cmac(reinterpret_cast<const uint8_t *>(aPassPhrase), passphraseLen, reinterpret_cast<const uint8_t *>(salt),
-                 saltLen, 16384, OT_PSKC_MAX_SIZE, aPskc.m8);
+    Get<ThreadNetif>().RemoveUnicastAddress(mCommissionerAloc);
+    mCommissionerAloc.GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
+    Get<ThreadNetif>().AddUnicastAddress(mCommissionerAloc);
 
 exit:
-    return error;
+    return;
 }
 
 // LCOV_EXCL_START
 
-#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MLE == 1)
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MESHCOP == 1)
 
 const char *Commissioner::StateToString(otCommissionerState aState)
 {
@@ -1161,7 +1282,36 @@
     return str;
 }
 
-#endif // (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MLE == 1)
+void Commissioner::LogJoinerEntry(const char *aAction, const Joiner &aJoiner) const
+{
+    switch (aJoiner.mType)
+    {
+    case Joiner::kTypeUnused:
+        break;
+
+    case Joiner::kTypeAny:
+        otLogInfoMeshCoP("%s Joiner (any, %s)", aAction, aJoiner.mPskd.GetAsCString());
+        break;
+
+    case Joiner::kTypeEui64:
+        otLogInfoMeshCoP("%s Joiner (eui64:%s, %s)", aAction, aJoiner.mSharedId.mEui64.ToString().AsCString(),
+                         aJoiner.mPskd.GetAsCString());
+        break;
+
+    case Joiner::kTypeDiscerner:
+        otLogInfoMeshCoP("%s Joiner (disc:%s, %s)", aAction, aJoiner.mSharedId.mDiscerner.ToString().AsCString(),
+                         aJoiner.mPskd.GetAsCString());
+        break;
+    }
+}
+
+#else
+
+void Commissioner::LogJoinerEntry(const char *, const Joiner &) const
+{
+}
+
+#endif // (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MESHCOP == 1)
 
 // LCOV_EXCL_STOP
 
diff --git a/src/core/meshcop/commissioner.hpp b/src/core/meshcop/commissioner.hpp
index a59dc6e..22ad5be 100644
--- a/src/core/meshcop/commissioner.hpp
+++ b/src/core/meshcop/commissioner.hpp
@@ -47,6 +47,7 @@
 #include "meshcop/dtls.hpp"
 #include "meshcop/energy_scan_client.hpp"
 #include "meshcop/panid_query_client.hpp"
+#include "net/ip6_address.hpp"
 #include "net/udp6.hpp"
 #include "thread/key_manager.hpp"
 #include "thread/mle.hpp"
@@ -74,7 +75,8 @@
      * @param[in]  aCallbackContext  A pointer to application-specific context.
      *
      * @retval OT_ERROR_NONE           Successfully started the Commissioner service.
-     * @retval OT_ERROR_INVALID_STATE  Commissioner is already started.
+     * @retval OT_ERROR_ALREADY        Commissioner is already started.
+     * @retval OT_ERROR_INVALID_STATE  Device is not currently attached to a network.
      *
      */
     otError Start(otCommissionerStateCallback  aStateCallback,
@@ -84,11 +86,13 @@
     /**
      * This method stops the Commissioner service.
      *
-     * @retval OT_ERROR_NONE           Successfully stopped the Commissioner service.
-     * @retval OT_ERROR_INVALID_STATE  Commissioner is already stopped.
+     * @param[in]  aResign      Whether send LEAD_KA.req to resign as Commissioner
+     *
+     * @retval OT_ERROR_NONE     Successfully stopped the Commissioner service.
+     * @retval OT_ERROR_ALREADY  Commissioner is already stopped.
      *
      */
-    otError Stop(void);
+    otError Stop(bool aResign);
 
     /**
      * This method clears all Joiner entries.
@@ -97,9 +101,8 @@
     void ClearJoiners(void);
 
     /**
-     * This method adds a Joiner entry.
+     * This method adds a Joiner entry accepting any Joiner.
      *
-     * @param[in]  aEui64        A pointer to the Joiner's IEEE EUI-64 or NULL for any Joiner.
      * @param[in]  aPskd         A pointer to the PSKd.
      * @param[in]  aTimeout      A time after which a Joiner is automatically removed, in seconds.
      *
@@ -108,7 +111,41 @@
      * @retval OT_ERROR_INVALID_STATE  Commissioner service is not started.
      *
      */
-    otError AddJoiner(const Mac::ExtAddress *aEui64, const char *aPskd, uint32_t aTimeout);
+    otError AddJoinerAny(const char *aPskd, uint32_t aTimeout) { return AddJoiner(nullptr, nullptr, aPskd, aTimeout); }
+
+    /**
+     * This method adds a Joiner entry.
+     *
+     * @param[in]  aEui64        The Joiner's IEEE EUI-64.
+     * @param[in]  aPskd         A pointer to the PSKd.
+     * @param[in]  aTimeout      A time after which a Joiner is automatically removed, in seconds.
+     *
+     * @retval OT_ERROR_NONE           Successfully added the Joiner.
+     * @retval OT_ERROR_NO_BUFS        No buffers available to add the Joiner.
+     * @retval OT_ERROR_INVALID_STATE  Commissioner service is not started.
+     *
+     */
+    otError AddJoiner(const Mac::ExtAddress &aEui64, const char *aPskd, uint32_t aTimeout)
+    {
+        return AddJoiner(&aEui64, nullptr, aPskd, aTimeout);
+    }
+
+    /**
+     * This method adds a Joiner entry with a Joiner Discerner.
+     *
+     * @param[in]  aDiscerner  A Joiner Discerner.
+     * @param[in]  aPskd       A pointer to the PSKd.
+     * @param[in]  aTimeout    A time after which a Joiner is automatically removed, in seconds.
+     *
+     * @retval OT_ERROR_NONE           Successfully added the Joiner.
+     * @retval OT_ERROR_NO_BUFS        No buffers available to add the Joiner.
+     * @retval OT_ERROR_INVALID_STATE  Commissioner service is not started.
+     *
+     */
+    otError AddJoiner(const JoinerDiscerner &aDiscerner, const char *aPskd, uint32_t aTimeout)
+    {
+        return AddJoiner(nullptr, &aDiscerner, aPskd, aTimeout);
+    }
 
     /**
      * This method get joiner info at aIterator position.
@@ -123,17 +160,48 @@
     otError GetNextJoinerInfo(uint16_t &aIterator, otJoinerInfo &aJoiner) const;
 
     /**
+     * This method removes a Joiner entry accepting any Joiner.
+     *
+     * @param[in]  aDelay         The delay to remove Joiner (in seconds).
+     *
+     * @retval OT_ERROR_NONE           Successfully added the Joiner.
+     * @retval OT_ERROR_NOT_FOUND      The Joiner entry accepting any Joiner was not found.
+     * @retval OT_ERROR_INVALID_STATE  Commissioner service is not started.
+     *
+     */
+    otError RemoveJoinerAny(uint32_t aDelay) { return RemoveJoiner(nullptr, nullptr, aDelay); }
+
+    /**
      * This method removes a Joiner entry.
      *
-     * @param[in]  aEui64          A pointer to the Joiner's IEEE EUI-64 or NULL for any Joiner.
-     * @param[in]  aDelay          The delay to remove Joiner (in seconds).
+     * @param[in]  aEui64         The Joiner's IEEE EUI-64.
+     * @param[in]  aDelay         The delay to remove Joiner (in seconds).
      *
      * @retval OT_ERROR_NONE           Successfully added the Joiner.
      * @retval OT_ERROR_NOT_FOUND      The Joiner specified by @p aEui64 was not found.
      * @retval OT_ERROR_INVALID_STATE  Commissioner service is not started.
      *
      */
-    otError RemoveJoiner(const Mac::ExtAddress *aEui64, uint32_t aDelay);
+    otError RemoveJoiner(const Mac::ExtAddress &aEui64, uint32_t aDelay)
+    {
+        return RemoveJoiner(&aEui64, nullptr, aDelay);
+    }
+
+    /**
+     * This method removes a Joiner entry.
+     *
+     * @param[in]  aDiscerner     A Joiner Discerner.
+     * @param[in]  aDelay         The delay to remove Joiner (in seconds).
+     *
+     * @retval OT_ERROR_NONE           Successfully added the Joiner.
+     * @retval OT_ERROR_NOT_FOUND      The Joiner specified by @p aEui64 was not found.
+     * @retval OT_ERROR_INVALID_STATE  Commissioner service is not started.
+     *
+     */
+    otError RemoveJoiner(const JoinerDiscerner &aDiscerner, uint32_t aDelay)
+    {
+        return RemoveJoiner(nullptr, &aDiscerner, aDelay);
+    }
 
     /**
      * This method gets the Provisioning URL.
@@ -146,7 +214,7 @@
     /**
      * This method sets the Provisioning URL.
      *
-     * @param[in]  aProvisioningUrl  A pointer to the Provisioning URL (may be NULL to set URL to empty string).
+     * @param[in]  aProvisioningUrl  A pointer to the Provisioning URL (may be nullptr to set URL to empty string).
      *
      * @retval OT_ERROR_NONE          Successfully set the Provisioning URL.
      * @retval OT_ERROR_INVALID_ARGS  @p aProvisioningUrl is invalid (too long).
@@ -171,6 +239,14 @@
     bool IsActive(void) const { return mState == OT_COMMISSIONER_STATE_ACTIVE; }
 
     /**
+     * This method indicates whether or not the Commissioner role is disabled.
+     *
+     * @returns TRUE if the Commissioner role is disabled, FALSE otherwise.
+     *
+     */
+    bool IsDisabled(void) const { return mState == OT_COMMISSIONER_STATE_DISABLED; }
+
+    /**
      * This function returns the Commissioner State.
      *
      * @param[in]  aInstance  A pointer to an OpenThread instance.
@@ -212,25 +288,6 @@
                                            uint8_t                       aLength);
 
     /**
-     * This static method generates PSKc.
-     *
-     * PSKc is used to establish the Commissioner Session.
-     *
-     * @param[in]  aPassPhrase   The commissioning passphrase.
-     * @param[in]  aNetworkName  The network name for PSKc computation.
-     * @param[in]  aExtPanId     The extended pan id for PSKc computation.
-     * @param[out] aPskc         A reference to a PSKc where the generated PSKc will be placed.
-     *
-     * @retval OT_ERROR_NONE          Successfully generate PSKc.
-     * @retval OT_ERROR_INVALID_ARGS  If the length of passphrase is out of range.
-     *
-     */
-    static otError GeneratePskc(const char *              aPassPhrase,
-                                const char *              aNetworkName,
-                                const Mac::ExtendedPanId &aExtPanId,
-                                Pskc &                    aPskc);
-
-    /**
      * This method returns a reference to the AnnounceBeginClient instance.
      *
      * @returns A reference to the AnnounceBeginClient instance.
@@ -254,6 +311,12 @@
      */
     PanIdQueryClient &GetPanIdQueryClient(void) { return mPanIdQuery; }
 
+    /**
+     * This method applies the Mesh Local Prefix.
+     *
+     */
+    void ApplyMeshLocalPrefix(void);
+
 private:
     enum
     {
@@ -264,6 +327,43 @@
         kRemoveJoinerDelay    = 20, ///< Delay to remove successfully joined joiner
     };
 
+    struct Joiner
+    {
+        enum Type : uint8_t
+        {
+            kTypeUnused = 0, // Need to be 0 to ensure `memset()` clears all `Joiners`
+            kTypeAny,
+            kTypeEui64,
+            kTypeDiscerner,
+        };
+
+        TimeMilli mExpirationTime;
+
+        union
+        {
+            Mac::ExtAddress mEui64;
+            JoinerDiscerner mDiscerner;
+        } mSharedId;
+
+        JoinerPskd mPskd;
+        Type       mType;
+
+        void CopyToJoinerInfo(otJoinerInfo &aInfo) const;
+    };
+
+    Joiner *GetUnusedJoinerEntry(void);
+    Joiner *FindJoinerEntry(const Mac::ExtAddress *aEui64);
+    Joiner *FindJoinerEntry(const JoinerDiscerner &aDiscerner);
+    Joiner *FindBestMatchingJoinerEntry(const Mac::ExtAddress &aRxJoinerId);
+    void    RemoveJoinerEntry(Joiner &aJoiner);
+
+    otError AddJoiner(const Mac::ExtAddress *aEui64,
+                      const JoinerDiscerner *aDiscerner,
+                      const char *           aPskd,
+                      uint32_t               aTimeout);
+    otError RemoveJoiner(const Mac::ExtAddress *aEui64, const JoinerDiscerner *aDiscerner, uint32_t aDelay);
+    void    RemoveJoiner(Joiner &aJoiner, uint32_t aDelay);
+
     void AddCoapResources(void);
     void RemoveCoapResources(void);
 
@@ -317,33 +417,28 @@
     static otError SendRelayTransmit(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
     otError        SendRelayTransmit(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
-    otError SendCommissionerSet(void);
+    void    ComputeBloomFilter(SteeringData &aSteeringData) const;
+    void    SendCommissionerSet(void);
     otError SendPetition(void);
-    otError SendKeepAlive(void);
+    void    SendKeepAlive(void);
+    void    SendKeepAlive(uint16_t aSessionId);
 
     void SetState(otCommissionerState aState);
-    void SignalJoinerEvent(otCommissionerJoinerEvent aEvent, const Mac::ExtAddress &aJoinerId);
+    void SignalJoinerEvent(otCommissionerJoinerEvent aEvent, const Joiner *aJoiner) const;
+    void LogJoinerEntry(const char *aAction, const Joiner &aJoiner) const;
 
     static const char *StateToString(otCommissionerState aState);
 
-    struct Joiner
-    {
-        Mac::ExtAddress mEui64;
-        TimeMilli       mExpirationTime;
-        char            mPsk[Dtls::kPskMaxLength + 1];
-        bool            mValid : 1;
-        bool            mAny : 1;
-    };
     Joiner mJoiners[OPENTHREAD_CONFIG_COMMISSIONER_MAX_JOINER_ENTRIES];
 
-    uint8_t    mJoinerIid[Ip6::Address::kInterfaceIdentifierSize];
-    uint16_t   mJoinerPort;
-    uint16_t   mJoinerRloc;
-    uint16_t   mSessionId;
-    uint8_t    mJoinerIndex;
-    uint8_t    mTransmitAttempts;
-    TimerMilli mJoinerExpirationTimer;
-    TimerMilli mTimer;
+    Joiner *                 mActiveJoiner;
+    Ip6::InterfaceIdentifier mJoinerIid;
+    uint16_t                 mJoinerPort;
+    uint16_t                 mJoinerRloc;
+    uint16_t                 mSessionId;
+    uint8_t                  mTransmitAttempts;
+    TimerMilli               mJoinerExpirationTimer;
+    TimerMilli               mTimer;
 
     Coap::Resource mRelayReceive;
     Coap::Resource mDatasetChanged;
@@ -357,11 +452,11 @@
 
     char mProvisioningUrl[OT_PROVISIONING_URL_MAX_SIZE + 1]; // + 1 is for null char at end of string.
 
+    otCommissionerState mState;
+
     otCommissionerStateCallback  mStateCallback;
     otCommissionerJoinerCallback mJoinerCallback;
     void *                       mCallbackContext;
-
-    otCommissionerState mState;
 };
 
 } // namespace MeshCoP
diff --git a/src/core/meshcop/dataset.cpp b/src/core/meshcop/dataset.cpp
index b3adad1..4ca43ce 100644
--- a/src/core/meshcop/dataset.cpp
+++ b/src/core/meshcop/dataset.cpp
@@ -37,6 +37,7 @@
 #include <stdio.h>
 
 #include "common/code_utils.hpp"
+#include "common/encoding.hpp"
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
 #include "common/logging.hpp"
@@ -47,7 +48,10 @@
 namespace ot {
 namespace MeshCoP {
 
-Dataset::Dataset(Tlv::Type aType)
+using ot::Encoding::BigEndian::HostSwap16;
+using ot::Encoding::BigEndian::HostSwap32;
+
+Dataset::Dataset(Type aType)
     : mUpdateTime(0)
     , mLength(0)
     , mType(aType)
@@ -63,10 +67,9 @@
 bool Dataset::IsValid(void) const
 {
     bool       rval = true;
-    const Tlv *cur  = reinterpret_cast<const Tlv *>(mTlvs);
-    const Tlv *end  = reinterpret_cast<const Tlv *>(mTlvs + mLength);
+    const Tlv *end  = GetTlvsEnd();
 
-    for (; cur < end; cur = cur->GetNext())
+    for (const Tlv *cur = GetTlvsStart(); cur < end; cur = cur->GetNext())
     {
         VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end && Tlv::IsValid(*cur), rval = false);
     }
@@ -75,79 +78,34 @@
     return rval;
 }
 
-Tlv *Dataset::Get(Tlv::Type aType)
+const Tlv *Dataset::GetTlv(Tlv::Type aType) const
 {
-    Tlv *cur  = reinterpret_cast<Tlv *>(mTlvs);
-    Tlv *end  = reinterpret_cast<Tlv *>(mTlvs + mLength);
-    Tlv *rval = NULL;
-
-    while (cur < end)
-    {
-        if (cur->GetType() == aType)
-        {
-            ExitNow(rval = cur);
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return rval;
+    return Tlv::FindTlv(mTlvs, mLength, aType);
 }
 
-const Tlv *Dataset::Get(Tlv::Type aType) const
+void Dataset::ConvertTo(otOperationalDataset &aDataset) const
 {
-    const Tlv *cur  = reinterpret_cast<const Tlv *>(mTlvs);
-    const Tlv *end  = reinterpret_cast<const Tlv *>(mTlvs + mLength);
-    const Tlv *rval = NULL;
-
-    while (cur < end)
-    {
-        if (cur->GetType() == aType)
-        {
-            ExitNow(rval = cur);
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return rval;
-}
-
-void Dataset::Get(otOperationalDataset &aDataset) const
-{
-    const Tlv *cur = reinterpret_cast<const Tlv *>(mTlvs);
-    const Tlv *end = reinterpret_cast<const Tlv *>(mTlvs + mLength);
-
     memset(&aDataset, 0, sizeof(aDataset));
 
-    while (cur < end)
+    for (const Tlv *cur = GetTlvsStart(); cur < GetTlvsEnd(); cur = cur->GetNext())
     {
         switch (cur->GetType())
         {
         case Tlv::kActiveTimestamp:
-        {
-            const ActiveTimestampTlv *tlv                  = static_cast<const ActiveTimestampTlv *>(cur);
-            aDataset.mActiveTimestamp                      = tlv->GetSeconds();
+            aDataset.mActiveTimestamp                      = static_cast<const ActiveTimestampTlv *>(cur)->GetSeconds();
             aDataset.mComponents.mIsActiveTimestampPresent = true;
             break;
-        }
 
         case Tlv::kChannel:
-        {
-            const ChannelTlv *tlv                  = static_cast<const ChannelTlv *>(cur);
-            aDataset.mChannel                      = tlv->GetChannel();
+            aDataset.mChannel                      = static_cast<const ChannelTlv *>(cur)->GetChannel();
             aDataset.mComponents.mIsChannelPresent = true;
             break;
-        }
 
         case Tlv::kChannelMask:
         {
-            const ChannelMaskTlv *tlv = static_cast<const ChannelMaskTlv *>(cur);
-            uint32_t              mask;
+            uint32_t mask;
 
-            if ((mask = tlv->GetChannelMask()) != 0)
+            if ((mask = static_cast<const ChannelMaskTlv *>(cur)->GetChannelMask()) != 0)
             {
                 aDataset.mChannelMask                      = mask;
                 aDataset.mComponents.mIsChannelMaskPresent = true;
@@ -157,68 +115,45 @@
         }
 
         case Tlv::kDelayTimer:
-        {
-            const DelayTimerTlv *tlv             = static_cast<const DelayTimerTlv *>(cur);
-            aDataset.mDelay                      = tlv->GetDelayTimer();
+            aDataset.mDelay                      = static_cast<const DelayTimerTlv *>(cur)->GetDelayTimer();
             aDataset.mComponents.mIsDelayPresent = true;
             break;
-        }
 
         case Tlv::kExtendedPanId:
-        {
-            const ExtendedPanIdTlv *tlv                  = static_cast<const ExtendedPanIdTlv *>(cur);
-            aDataset.mExtendedPanId                      = tlv->GetExtendedPanId();
+            aDataset.mExtendedPanId = static_cast<const ExtendedPanIdTlv *>(cur)->GetExtendedPanId();
             aDataset.mComponents.mIsExtendedPanIdPresent = true;
             break;
-        }
 
         case Tlv::kMeshLocalPrefix:
-        {
-            const MeshLocalPrefixTlv *tlv                  = static_cast<const MeshLocalPrefixTlv *>(cur);
-            aDataset.mMeshLocalPrefix                      = tlv->GetMeshLocalPrefix();
+            aDataset.mMeshLocalPrefix = static_cast<const MeshLocalPrefixTlv *>(cur)->GetMeshLocalPrefix();
             aDataset.mComponents.mIsMeshLocalPrefixPresent = true;
             break;
-        }
 
         case Tlv::kNetworkMasterKey:
-        {
-            const NetworkMasterKeyTlv *tlv           = static_cast<const NetworkMasterKeyTlv *>(cur);
-            aDataset.mMasterKey                      = tlv->GetNetworkMasterKey();
+            aDataset.mMasterKey = static_cast<const NetworkMasterKeyTlv *>(cur)->GetNetworkMasterKey();
             aDataset.mComponents.mIsMasterKeyPresent = true;
             break;
-        }
 
         case Tlv::kNetworkName:
-        {
-            const NetworkNameTlv *tlv = static_cast<const NetworkNameTlv *>(cur);
-            static_cast<Mac::NetworkName &>(aDataset.mNetworkName).Set(tlv->GetNetworkName());
+            IgnoreError(static_cast<Mac::NetworkName &>(aDataset.mNetworkName)
+                            .Set(static_cast<const NetworkNameTlv *>(cur)->GetNetworkName()));
             aDataset.mComponents.mIsNetworkNamePresent = true;
             break;
-        }
 
         case Tlv::kPanId:
-        {
-            const PanIdTlv *panid                = static_cast<const PanIdTlv *>(cur);
-            aDataset.mPanId                      = panid->GetPanId();
+            aDataset.mPanId                      = static_cast<const PanIdTlv *>(cur)->GetPanId();
             aDataset.mComponents.mIsPanIdPresent = true;
             break;
-        }
 
         case Tlv::kPendingTimestamp:
-        {
-            const PendingTimestampTlv *tlv                  = static_cast<const PendingTimestampTlv *>(cur);
-            aDataset.mPendingTimestamp                      = tlv->GetSeconds();
+            aDataset.mPendingTimestamp = static_cast<const PendingTimestampTlv *>(cur)->GetSeconds();
             aDataset.mComponents.mIsPendingTimestampPresent = true;
             break;
-        }
 
         case Tlv::kPskc:
-        {
-            const PskcTlv *tlv                  = static_cast<const PskcTlv *>(cur);
-            aDataset.mPskc                      = tlv->GetPskc();
+            aDataset.mPskc                      = static_cast<const PskcTlv *>(cur)->GetPskc();
             aDataset.mComponents.mIsPskcPresent = true;
             break;
-        }
 
         case Tlv::kSecurityPolicy:
         {
@@ -230,130 +165,119 @@
         }
 
         default:
-        {
             break;
         }
-        }
-
-        cur = cur->GetNext();
     }
 }
 
+void Dataset::ConvertTo(otOperationalDatasetTlvs &aDataset) const
+{
+    memcpy(aDataset.mTlvs, mTlvs, mLength);
+    aDataset.mLength = static_cast<uint8_t>(mLength);
+}
+
 void Dataset::Set(const Dataset &aDataset)
 {
     memcpy(mTlvs, aDataset.mTlvs, aDataset.mLength);
     mLength = aDataset.mLength;
 
-    if (mType == Tlv::kActiveTimestamp)
+    if (mType == kActive)
     {
-        Remove(Tlv::kPendingTimestamp);
-        Remove(Tlv::kDelayTimer);
+        RemoveTlv(Tlv::kPendingTimestamp);
+        RemoveTlv(Tlv::kDelayTimer);
     }
 
     mUpdateTime = aDataset.GetUpdateTime();
 }
 
-otError Dataset::Set(const otOperationalDataset &aDataset)
+void Dataset::SetFrom(const otOperationalDatasetTlvs &aDataset)
+{
+    mLength = aDataset.mLength;
+    memcpy(mTlvs, aDataset.mTlvs, mLength);
+}
+
+otError Dataset::SetFrom(const otOperationalDataset &aDataset)
 {
     otError error = OT_ERROR_NONE;
 
     if (aDataset.mComponents.mIsActiveTimestampPresent)
     {
-        MeshCoP::ActiveTimestampTlv tlv;
+        ActiveTimestampTlv tlv;
         tlv.Init();
         tlv.SetSeconds(aDataset.mActiveTimestamp);
         tlv.SetTicks(0);
-        Set(tlv);
+        IgnoreError(SetTlv(tlv));
     }
 
     if (aDataset.mComponents.mIsPendingTimestampPresent)
     {
-        MeshCoP::PendingTimestampTlv tlv;
+        PendingTimestampTlv tlv;
         tlv.Init();
         tlv.SetSeconds(aDataset.mPendingTimestamp);
         tlv.SetTicks(0);
-        Set(tlv);
+        IgnoreError(SetTlv(tlv));
     }
 
     if (aDataset.mComponents.mIsDelayPresent)
     {
-        MeshCoP::DelayTimerTlv tlv;
-        tlv.Init();
-        tlv.SetDelayTimer(aDataset.mDelay);
-        Set(tlv);
+        IgnoreError(SetUint32Tlv(Tlv::kDelayTimer, aDataset.mDelay));
     }
 
     if (aDataset.mComponents.mIsChannelPresent)
     {
-        MeshCoP::ChannelTlv tlv;
+        ChannelTlv tlv;
         tlv.Init();
         tlv.SetChannel(aDataset.mChannel);
-        Set(tlv);
+        IgnoreError(SetTlv(tlv));
     }
 
     if (aDataset.mComponents.mIsChannelMaskPresent)
     {
-        MeshCoP::ChannelMaskTlv tlv;
+        ChannelMaskTlv tlv;
         tlv.Init();
         tlv.SetChannelMask(aDataset.mChannelMask);
-        Set(tlv);
+        IgnoreError(SetTlv(tlv));
     }
 
     if (aDataset.mComponents.mIsExtendedPanIdPresent)
     {
-        MeshCoP::ExtendedPanIdTlv tlv;
-        tlv.Init();
-        tlv.SetExtendedPanId(static_cast<const Mac::ExtendedPanId &>(aDataset.mExtendedPanId));
-        Set(tlv);
+        IgnoreError(SetTlv(Tlv::kExtendedPanId, &aDataset.mExtendedPanId, sizeof(Mac::ExtendedPanId)));
     }
 
     if (aDataset.mComponents.mIsMeshLocalPrefixPresent)
     {
-        MeshCoP::MeshLocalPrefixTlv tlv;
-        tlv.Init();
-        tlv.SetMeshLocalPrefix(aDataset.mMeshLocalPrefix);
-        Set(tlv);
+        IgnoreError(SetTlv(Tlv::kMeshLocalPrefix, &aDataset.mMeshLocalPrefix, sizeof(Mle::MeshLocalPrefix)));
     }
 
     if (aDataset.mComponents.mIsMasterKeyPresent)
     {
-        MeshCoP::NetworkMasterKeyTlv tlv;
-        tlv.Init();
-        tlv.SetNetworkMasterKey(static_cast<const MasterKey &>(aDataset.mMasterKey));
-        Set(tlv);
+        IgnoreError(SetTlv(Tlv::kNetworkMasterKey, &aDataset.mMasterKey, sizeof(MasterKey)));
     }
 
     if (aDataset.mComponents.mIsNetworkNamePresent)
     {
-        MeshCoP::NetworkNameTlv tlv;
-        tlv.Init();
-        tlv.SetNetworkName(static_cast<const Mac::NetworkName &>(aDataset.mNetworkName).GetAsData());
-        Set(tlv);
+        Mac::NameData nameData = static_cast<const Mac::NetworkName &>(aDataset.mNetworkName).GetAsData();
+
+        IgnoreError(SetTlv(Tlv::kNetworkName, nameData.GetBuffer(), nameData.GetLength()));
     }
 
     if (aDataset.mComponents.mIsPanIdPresent)
     {
-        MeshCoP::PanIdTlv tlv;
-        tlv.Init();
-        tlv.SetPanId(aDataset.mPanId);
-        Set(tlv);
+        IgnoreError(SetUint16Tlv(Tlv::kPanId, aDataset.mPanId));
     }
 
     if (aDataset.mComponents.mIsPskcPresent)
     {
-        MeshCoP::PskcTlv tlv;
-        tlv.Init();
-        tlv.SetPskc(static_cast<const Pskc &>(aDataset.mPskc));
-        Set(tlv);
+        IgnoreError(SetTlv(Tlv::kPskc, &aDataset.mPskc, sizeof(Pskc)));
     }
 
     if (aDataset.mComponents.mIsSecurityPolicyPresent)
     {
-        MeshCoP::SecurityPolicyTlv tlv;
+        SecurityPolicyTlv tlv;
         tlv.Init();
         tlv.SetRotationTime(aDataset.mSecurityPolicy.mRotationTime);
         tlv.SetFlags(aDataset.mSecurityPolicy.mFlags);
-        Set(tlv);
+        IgnoreError(SetTlv(tlv));
     }
 
     mUpdateTime = TimerMilli::GetNow();
@@ -363,18 +287,18 @@
 
 const Timestamp *Dataset::GetTimestamp(void) const
 {
-    const Timestamp *timestamp = NULL;
+    const Timestamp *timestamp = nullptr;
 
-    if (mType == Tlv::kActiveTimestamp)
+    if (mType == kActive)
     {
-        const ActiveTimestampTlv *tlv = static_cast<const ActiveTimestampTlv *>(Get(mType));
-        VerifyOrExit(tlv != NULL);
+        const ActiveTimestampTlv *tlv = GetTlv<ActiveTimestampTlv>();
+        VerifyOrExit(tlv != nullptr, OT_NOOP);
         timestamp = static_cast<const Timestamp *>(tlv);
     }
     else
     {
-        const PendingTimestampTlv *tlv = static_cast<const PendingTimestampTlv *>(Get(mType));
-        VerifyOrExit(tlv != NULL);
+        const PendingTimestampTlv *tlv = GetTlv<PendingTimestampTlv>();
+        VerifyOrExit(tlv != nullptr, OT_NOOP);
         timestamp = static_cast<const Timestamp *>(tlv);
     }
 
@@ -384,44 +308,36 @@
 
 void Dataset::SetTimestamp(const Timestamp &aTimestamp)
 {
-    if (mType == Tlv::kActiveTimestamp)
-    {
-        ActiveTimestampTlv activeTimestamp;
-        activeTimestamp.Init();
-        *static_cast<Timestamp *>(&activeTimestamp) = aTimestamp;
-        Set(activeTimestamp);
-    }
-    else
-    {
-        PendingTimestampTlv pendingTimestamp;
-        pendingTimestamp.Init();
-        *static_cast<Timestamp *>(&pendingTimestamp) = aTimestamp;
-        Set(pendingTimestamp);
-    }
+    IgnoreError(
+        SetTlv((mType == kActive) ? Tlv::kActiveTimestamp : Tlv::kPendingTimestamp, &aTimestamp, sizeof(Timestamp)));
 }
 
-otError Dataset::Set(const Tlv &aTlv)
+otError Dataset::SetTlv(Tlv::Type aType, const void *aValue, uint8_t aLength)
 {
     otError  error          = OT_ERROR_NONE;
     uint16_t bytesAvailable = sizeof(mTlvs) - mLength;
-    Tlv *    old            = Get(aTlv.GetType());
+    Tlv *    old            = GetTlv(aType);
+    Tlv      tlv;
 
-    if (old != NULL)
+    if (old != nullptr)
     {
         bytesAvailable += sizeof(Tlv) + old->GetLength();
     }
 
-    VerifyOrExit(sizeof(Tlv) + aTlv.GetLength() <= bytesAvailable, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(sizeof(Tlv) + aLength <= bytesAvailable, error = OT_ERROR_NO_BUFS);
 
-    // remove old TLV
-    if (old != NULL)
+    if (old != nullptr)
     {
-        Remove(reinterpret_cast<uint8_t *>(old), sizeof(Tlv) + old->GetLength());
+        RemoveTlv(old);
     }
 
-    // add new TLV
-    memcpy(mTlvs + mLength, &aTlv, sizeof(Tlv) + aTlv.GetLength());
-    mLength += sizeof(Tlv) + aTlv.GetLength();
+    tlv.SetType(aType);
+    tlv.SetLength(aLength);
+    memcpy(mTlvs + mLength, &tlv, sizeof(Tlv));
+    mLength += sizeof(Tlv);
+
+    memcpy(mTlvs + mLength, aValue, aLength);
+    mLength += aLength;
 
     mUpdateTime = TimerMilli::GetNow();
 
@@ -429,6 +345,25 @@
     return error;
 }
 
+otError Dataset::SetTlv(const Tlv &aTlv)
+{
+    return SetTlv(aTlv.GetType(), aTlv.GetValue(), aTlv.GetLength());
+}
+
+otError Dataset::SetUint16Tlv(Tlv::Type aType, uint16_t aValue)
+{
+    uint16_t value16 = HostSwap16(aValue);
+
+    return SetTlv(aType, &value16, sizeof(uint16_t));
+}
+
+otError Dataset::SetUint32Tlv(Tlv::Type aType, uint32_t aValue)
+{
+    uint32_t value32 = HostSwap32(aValue);
+
+    return SetTlv(aType, &value32, sizeof(uint32_t));
+}
+
 otError Dataset::Set(const Message &aMessage, uint16_t aOffset, uint8_t aLength)
 {
     otError error = OT_ERROR_NONE;
@@ -442,12 +377,12 @@
     return error;
 }
 
-void Dataset::Remove(Tlv::Type aType)
+void Dataset::RemoveTlv(Tlv::Type aType)
 {
     Tlv *tlv;
 
-    VerifyOrExit((tlv = Get(aType)) != NULL);
-    Remove(reinterpret_cast<uint8_t *>(tlv), sizeof(Tlv) + tlv->GetLength());
+    VerifyOrExit((tlv = GetTlv(aType)) != nullptr, OT_NOOP);
+    RemoveTlv(tlv);
 
 exit:
     return;
@@ -458,20 +393,19 @@
     otError        error = OT_ERROR_NONE;
     Mle::Tlv       tlv;
     Mle::Tlv::Type type;
-    const Tlv *    cur = reinterpret_cast<const Tlv *>(mTlvs);
-    const Tlv *    end = reinterpret_cast<const Tlv *>(mTlvs + mLength);
 
-    VerifyOrExit(mLength > 0);
+    VerifyOrExit(mLength > 0, OT_NOOP);
 
-    type = (mType == Tlv::kActiveTimestamp ? Mle::Tlv::kActiveDataset : Mle::Tlv::kPendingDataset);
+    type = (mType == kActive ? Mle::Tlv::kActiveDataset : Mle::Tlv::kPendingDataset);
 
     tlv.SetType(type);
     tlv.SetLength(static_cast<uint8_t>(mLength) - sizeof(Tlv) - sizeof(Timestamp));
     SuccessOrExit(error = aMessage.Append(&tlv, sizeof(Tlv)));
 
-    while (cur < end)
+    for (const Tlv *cur = GetTlvsStart(); cur < GetTlvsEnd(); cur = cur->GetNext())
     {
-        if (cur->GetType() == mType)
+        if (((mType == kActive) && (cur->GetType() == Tlv::kActiveTimestamp)) ||
+            ((mType == kPending) && (cur->GetType() == Tlv::kPendingTimestamp)))
         {
             ; // skip Active or Pending Timestamp TLV
         }
@@ -495,18 +429,19 @@
         {
             SuccessOrExit(error = cur->AppendTo(aMessage));
         }
-
-        cur = cur->GetNext();
     }
 
 exit:
     return error;
 }
 
-void Dataset::Remove(uint8_t *aStart, uint8_t aLength)
+void Dataset::RemoveTlv(Tlv *aTlv)
 {
-    memmove(aStart, aStart + aLength, mLength - (static_cast<uint8_t>(aStart - mTlvs) + aLength));
-    mLength -= aLength;
+    uint8_t *start  = reinterpret_cast<uint8_t *>(aTlv);
+    uint16_t length = sizeof(Tlv) + aTlv->GetLength();
+
+    memmove(start, start + length, mLength - (static_cast<uint8_t>(start - mTlvs) + length));
+    mLength -= length;
 }
 
 otError Dataset::ApplyConfiguration(Instance &aInstance, bool *aIsMasterKeyUpdated) const
@@ -514,8 +449,6 @@
     Mac::Mac &  mac        = aInstance.Get<Mac::Mac>();
     KeyManager &keyManager = aInstance.Get<KeyManager>();
     otError     error      = OT_ERROR_NONE;
-    const Tlv * cur        = reinterpret_cast<const Tlv *>(mTlvs);
-    const Tlv * end        = reinterpret_cast<const Tlv *>(mTlvs + mLength);
 
     VerifyOrExit(IsValid(), error = OT_ERROR_PARSE);
 
@@ -524,7 +457,7 @@
         *aIsMasterKeyUpdated = false;
     }
 
-    while (cur < end)
+    for (const Tlv *cur = GetTlvsStart(); cur < GetTlvsEnd(); cur = cur->GetNext())
     {
         switch (cur->GetType())
         {
@@ -553,11 +486,8 @@
             break;
 
         case Tlv::kNetworkName:
-        {
-            const NetworkNameTlv *name = static_cast<const NetworkNameTlv *>(cur);
-            mac.SetNetworkName(name->GetNetworkName());
+            IgnoreError(mac.SetNetworkName(static_cast<const NetworkNameTlv *>(cur)->GetNetworkName()));
             break;
-        }
 
         case Tlv::kNetworkMasterKey:
         {
@@ -568,43 +498,34 @@
                 *aIsMasterKeyUpdated = true;
             }
 
-            keyManager.SetMasterKey(key->GetNetworkMasterKey());
+            IgnoreError(keyManager.SetMasterKey(key->GetNetworkMasterKey()));
             break;
         }
 
 #if OPENTHREAD_FTD
 
         case Tlv::kPskc:
-        {
-            const PskcTlv *pskc = static_cast<const PskcTlv *>(cur);
-            keyManager.SetPskc(pskc->GetPskc());
+            keyManager.SetPskc(static_cast<const PskcTlv *>(cur)->GetPskc());
             break;
-        }
 
 #endif
 
         case Tlv::kMeshLocalPrefix:
-        {
-            const MeshLocalPrefixTlv *prefix = static_cast<const MeshLocalPrefixTlv *>(cur);
-            aInstance.Get<Mle::MleRouter>().SetMeshLocalPrefix(prefix->GetMeshLocalPrefix());
+            aInstance.Get<Mle::MleRouter>().SetMeshLocalPrefix(
+                static_cast<const MeshLocalPrefixTlv *>(cur)->GetMeshLocalPrefix());
             break;
-        }
 
         case Tlv::kSecurityPolicy:
         {
             const SecurityPolicyTlv *securityPolicy = static_cast<const SecurityPolicyTlv *>(cur);
-            keyManager.SetKeyRotation(securityPolicy->GetRotationTime());
+            IgnoreError(keyManager.SetKeyRotation(securityPolicy->GetRotationTime()));
             keyManager.SetSecurityPolicyFlags(securityPolicy->GetFlags());
             break;
         }
 
         default:
-        {
             break;
         }
-        }
-
-        cur = cur->GetNext();
     }
 
 exit:
@@ -613,9 +534,14 @@
 
 void Dataset::ConvertToActive(void)
 {
-    Remove(Tlv::kPendingTimestamp);
-    Remove(Tlv::kDelayTimer);
-    mType = Tlv::kActiveTimestamp;
+    RemoveTlv(Tlv::kPendingTimestamp);
+    RemoveTlv(Tlv::kDelayTimer);
+    mType = kActive;
+}
+
+const char *Dataset::TypeToString(Type aType)
+{
+    return (aType == kActive) ? "Active" : "Pending";
 }
 
 } // namespace MeshCoP
diff --git a/src/core/meshcop/dataset.hpp b/src/core/meshcop/dataset.hpp
index 5b43bfc..4a3be2f 100644
--- a/src/core/meshcop/dataset.hpp
+++ b/src/core/meshcop/dataset.hpp
@@ -47,6 +47,10 @@
 namespace ot {
 namespace MeshCoP {
 
+/**
+ * This class represents MeshCop Dataset.
+ *
+ */
 class Dataset
 {
     friend class DatasetLocal;
@@ -54,8 +58,19 @@
 public:
     enum
     {
-        kMaxSize      = 256, ///< Maximum size of MeshCoP Dataset (bytes)
-        kMaxValueSize = 16,  /// < Maximum size of each Dataset TLV value (bytes)
+        kMaxSize      = OT_OPERATIONAL_DATASET_MAX_LENGTH, ///< Maximum size of MeshCoP Dataset (bytes)
+        kMaxValueSize = 16,                                ///< Maximum size of each Dataset TLV value (bytes)
+        kMaxGetTypes  = 64,                                ///< Maximum number of types in MGMT_GET.req
+    };
+
+    /**
+     * This enumeration represents the Dataset type (active or pending).
+     *
+     */
+    enum Type
+    {
+        kActive,  ///< Active Dataset
+        kPending, ///< Pending Dataset
     };
 
     /**
@@ -64,7 +79,7 @@
      * @param[in]  aType       The type of the dataset, active or pending.
      *
      */
-    explicit Dataset(Tlv::Type aType);
+    explicit Dataset(Type aType);
 
     /**
      * This method clears the Dataset.
@@ -81,20 +96,46 @@
     bool IsValid(void) const;
 
     /**
-     * This method returns a pointer to the TLV.
+     * This method returns a pointer to the TLV with a given type.
      *
-     * @returns A pointer to the TLV or NULL if none is found.
+     * @param[in] aType  A TLV type.
+     *
+     * @returns A pointer to the TLV or nullptr if none is found.
      *
      */
-    Tlv *Get(Tlv::Type aType);
+    Tlv *GetTlv(Tlv::Type aType) { return const_cast<Tlv *>(const_cast<const Dataset *>(this)->GetTlv(aType)); }
 
     /**
-     * This method returns a pointer to the TLV.
+     * This method returns a pointer to the TLV with a given type.
      *
-     * @returns A pointer to the TLV or NULL if none is found.
+     * @param[in] aType  The TLV type.
+     *
+     * @returns A pointer to the TLV or nullptr if none is found.
      *
      */
-    const Tlv *Get(Tlv::Type aType) const;
+    const Tlv *GetTlv(Tlv::Type aType) const;
+
+    /**
+     * This template method returns a pointer to the TLV with a given template type `TlvType`
+     *
+     * @returns A pointer to the TLV or nullptr if none is found.
+     *
+     */
+    template <typename TlvType> TlvType *GetTlv(void)
+    {
+        return static_cast<TlvType *>(GetTlv(static_cast<Tlv::Type>(TlvType::kType)));
+    }
+
+    /**
+     * This template method returns a pointer to the TLV with a given template type `TlvType`
+     *
+     * @returns A pointer to the TLV or nullptr if none is found.
+     *
+     */
+    template <typename TlvType> const TlvType *GetTlv(void) const
+    {
+        return static_cast<const TlvType *>(GetTlv(static_cast<Tlv::Type>(TlvType::kType)));
+    }
 
     /**
      * This method returns a pointer to the byte representation of the Dataset.
@@ -115,8 +156,18 @@
     /**
      * This method converts the TLV representation to structure representation.
      *
+     * @param[out] aDataset  A reference to `otOperationalDataset` to output the Dataset.
+     *
      */
-    void Get(otOperationalDataset &aDataset) const;
+    void ConvertTo(otOperationalDataset &aDataset) const;
+
+    /**
+     * This method converts the TLV representation to structure representation.
+     *
+     * @param[out] aDataset  A reference to `otOperationalDatasetTlvs` to output the Dataset.
+     *
+     */
+    void ConvertTo(otOperationalDatasetTlvs &aDataset) const;
 
     /**
      * This method returns the Dataset size in bytes.
@@ -153,6 +204,8 @@
     /**
      * This method sets the Timestamp value.
      *
+     * @param[in] aTimestamp   A Timestamp.
+     *
      */
     void SetTimestamp(const Timestamp &aTimestamp);
 
@@ -165,7 +218,44 @@
      * @retval OT_ERROR_NO_BUFS  Could not set the TLV due to insufficient buffer space.
      *
      */
-    otError Set(const Tlv &aTlv);
+    otError SetTlv(const Tlv &aTlv);
+
+    /**
+     * This method sets a TLV with a given TLV Type and Value.
+     *
+     * @param[in] aType     The TLV Type.
+     * @param[in] aValue    A pointer to TLV Value.
+     * @param[in] aLength   The TLV Length in bytes (length of @p aValue).
+     *
+     * @retval OT_ERROR_NONE     Successfully set the TLV.
+     * @retval OT_ERROR_NO_BUFS  Could not set the TLV due to insufficient buffer space.
+     *
+     */
+    otError SetTlv(Tlv::Type aType, const void *aValue, uint8_t aLength);
+
+    /**
+     * This method sets a TLV with a given TLV Type and a `uint16_t` Value.
+     *
+     * @param[in] aType     The TLV Type.
+     * @param[in] aValue    The TLV value (as `uint16_t`).
+     *
+     * @retval OT_ERROR_NONE     Successfully set the TLV.
+     * @retval OT_ERROR_NO_BUFS  Could not set the TLV due to insufficient buffer space.
+     *
+     */
+    otError SetUint16Tlv(Tlv::Type aType, uint16_t aValue);
+
+    /**
+     * This method sets a TLV with a given TLV Type and a `uint32_t` Value.
+     *
+     * @param[in] aType     The TLV Type.
+     * @param[in] aValue    The TLV value (as `uint32_t`).
+     *
+     * @retval OT_ERROR_NONE     Successfully set the TLV.
+     * @retval OT_ERROR_NO_BUFS  Could not set the TLV due to insufficient buffer space.
+     *
+     */
+    otError SetUint32Tlv(Tlv::Type aType, uint32_t aValue);
 
     /**
      * This method sets the Dataset using TLVs stored in a message buffer.
@@ -192,15 +282,23 @@
     void Set(const Dataset &aDataset);
 
     /**
-     * This method sets the Dataset.
+     * This method sets the Dataset from a given structure representation.
      *
-     * @param[in]  aDataset  The input Dataset.
+     * @param[in]  aDataset  The input Dataset as otOperationalDataset.
      *
      * @retval OT_ERROR_NONE          Successfully set the Dataset.
      * @retval OT_ERROR_INVALID_ARGS  Dataset is missing Active and/or Pending Timestamp.
      *
      */
-    otError Set(const otOperationalDataset &aDataset);
+    otError SetFrom(const otOperationalDataset &aDataset);
+
+    /**
+     * This method sets the Dataset using @p aDataset.
+     *
+     * @param[in]  aDataset  The input Dataset as otOperationalDatasetTlvs.
+     *
+     */
+    void SetFrom(const otOperationalDatasetTlvs &aDataset);
 
     /**
      * This method removes a TLV from the Dataset.
@@ -208,11 +306,13 @@
      * @param[in] aType The type of a specific TLV.
      *
      */
-    void Remove(Tlv::Type aType);
+    void RemoveTlv(Tlv::Type aType);
 
     /**
      * This method appends the MLE Dataset TLV but excluding MeshCoP Sub Timestamp TLV.
      *
+     * @param[in] aMessage       A message to append to.
+     *
      * @retval OT_ERROR_NONE     Successfully append MLE Dataset TLV without MeshCoP Sub Timestamp TLV.
      * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to append the message with MLE Dataset TLV.
      *
@@ -229,7 +329,7 @@
      * @retval OT_ERROR_PARSE  The dataset has at least one TLV with invalid format.
      *
      */
-    otError ApplyConfiguration(Instance &aInstance, bool *aIsMasterKeyUpdated = NULL) const;
+    otError ApplyConfiguration(Instance &aInstance, bool *aIsMasterKeyUpdated = nullptr) const;
 
     /**
      * This method converts a Pending Dataset to an Active Dataset.
@@ -239,13 +339,57 @@
      */
     void ConvertToActive(void);
 
+    /**
+     * This method returns a pointer to the start of Dataset TLVs sequence.
+     *
+     * @return  A pointer to the start of Dataset TLVs sequence.
+     *
+     */
+    Tlv *GetTlvsStart(void) { return reinterpret_cast<Tlv *>(mTlvs); }
+
+    /**
+     * This method returns a pointer to the start of Dataset TLVs sequence.
+     *
+     * @return  A pointer to start of Dataset TLVs sequence.
+     *
+     */
+    const Tlv *GetTlvsStart(void) const { return reinterpret_cast<const Tlv *>(mTlvs); }
+
+    /**
+     * This method returns a pointer to the past-the-end of Dataset TLVs sequence.
+     *
+     * Note that past-the-end points to the byte after the end of the last TLV in Dataset TLVs sequence.
+     *
+     * @return  A pointer to past-the-end of Dataset TLVs sequence.
+     *
+     */
+    Tlv *GetTlvsEnd(void) { return reinterpret_cast<Tlv *>(mTlvs + mLength); }
+
+    /**
+     * This method returns a pointer to the past-the-end of Dataset TLVs sequence.
+     *
+     * Note that past-the-end points to the byte after the end of the last TLV in Dataset TLVs sequence.
+     *
+     * @return  A pointer to past-the-end of Dataset TLVs sequence.
+     *
+     */
+    const Tlv *GetTlvsEnd(void) const { return reinterpret_cast<const Tlv *>(mTlvs + mLength); }
+
+    /**
+     * This static method converts a Dataset Type to a string.
+     *
+     * @param[in]  aType   A Dataset type.
+     *
+     */
+    static const char *TypeToString(Type aType);
+
 private:
-    void Remove(uint8_t *aStart, uint8_t aLength);
+    void RemoveTlv(Tlv *aTlv);
 
     uint8_t   mTlvs[kMaxSize]; ///< The Dataset buffer
     TimeMilli mUpdateTime;     ///< Local time last updated
     uint16_t  mLength;         ///< The number of valid bytes in @var mTlvs
-    Tlv::Type mType;           ///< Active or Pending
+    Type      mType;           ///< Active or Pending
 };
 
 } // namespace MeshCoP
diff --git a/src/core/meshcop/dataset_local.cpp b/src/core/meshcop/dataset_local.cpp
index 8530fc1..37cd5a5 100644
--- a/src/core/meshcop/dataset_local.cpp
+++ b/src/core/meshcop/dataset_local.cpp
@@ -48,7 +48,7 @@
 namespace ot {
 namespace MeshCoP {
 
-DatasetLocal::DatasetLocal(Instance &aInstance, Tlv::Type aType)
+DatasetLocal::DatasetLocal(Instance &aInstance, Dataset::Type aType)
     : InstanceLocator(aInstance)
     , mUpdateTime(0)
     , mType(aType)
@@ -60,7 +60,7 @@
 
 void DatasetLocal::Clear(void)
 {
-    Get<Settings>().DeleteOperationalDataset(IsActive());
+    IgnoreError(Get<Settings>().DeleteOperationalDataset(IsActive()));
     mTimestamp.Init();
     mTimestampPresent = false;
     mSaved            = false;
@@ -79,7 +79,7 @@
     mSaved    = true;
     timestamp = aDataset.GetTimestamp();
 
-    if (timestamp != NULL)
+    if (timestamp != nullptr)
     {
         mTimestamp        = *timestamp;
         mTimestampPresent = true;
@@ -98,15 +98,15 @@
     error = Get<Settings>().ReadOperationalDataset(IsActive(), aDataset);
     VerifyOrExit(error == OT_ERROR_NONE, aDataset.mLength = 0);
 
-    if (mType == Tlv::kActiveTimestamp)
+    if (mType == Dataset::kActive)
     {
-        aDataset.Remove(Tlv::kPendingTimestamp);
-        aDataset.Remove(Tlv::kDelayTimer);
+        aDataset.RemoveTlv(Tlv::kPendingTimestamp);
+        aDataset.RemoveTlv(Tlv::kDelayTimer);
     }
     else
     {
-        delayTimer = static_cast<DelayTimerTlv *>(aDataset.Get(Tlv::kDelayTimer));
-        VerifyOrExit(delayTimer);
+        delayTimer = aDataset.GetTlv<DelayTimerTlv>();
+        VerifyOrExit(delayTimer, OT_NOOP);
 
         elapsed = TimerMilli::GetNow() - mUpdateTime;
 
@@ -133,10 +133,22 @@
 
     memset(&aDataset, 0, sizeof(aDataset));
 
-    error = Read(dataset);
-    SuccessOrExit(error);
+    SuccessOrExit(error = Read(dataset));
+    dataset.ConvertTo(aDataset);
 
-    dataset.Get(aDataset);
+exit:
+    return error;
+}
+
+otError DatasetLocal::Read(otOperationalDatasetTlvs &aDataset) const
+{
+    Dataset dataset(mType);
+    otError error;
+
+    memset(&aDataset, 0, sizeof(aDataset));
+
+    SuccessOrExit(error = Read(dataset));
+    dataset.ConvertTo(aDataset);
 
 exit:
     return error;
@@ -144,19 +156,25 @@
 
 otError DatasetLocal::Save(const otOperationalDataset &aDataset)
 {
-    otError error = OT_ERROR_NONE;
+    otError error;
     Dataset dataset(mType);
 
-    error = dataset.Set(aDataset);
-    SuccessOrExit(error);
-
-    error = Save(dataset);
-    SuccessOrExit(error);
+    SuccessOrExit(error = dataset.SetFrom(aDataset));
+    SuccessOrExit(error = Save(dataset));
 
 exit:
     return error;
 }
 
+otError DatasetLocal::Save(const otOperationalDatasetTlvs &aDataset)
+{
+    Dataset dataset(mType);
+
+    dataset.SetFrom(aDataset);
+
+    return Save(dataset);
+}
+
 otError DatasetLocal::Save(const Dataset &aDataset)
 {
     const Timestamp *timestamp;
@@ -165,20 +183,20 @@
     if (aDataset.GetSize() == 0)
     {
         // do not propagate error back
-        Get<Settings>().DeleteOperationalDataset(IsActive());
+        IgnoreError(Get<Settings>().DeleteOperationalDataset(IsActive()));
         mSaved = false;
-        otLogInfoMeshCoP("%s dataset deleted", mType == Tlv::kActiveTimestamp ? "Active" : "Pending");
+        otLogInfoMeshCoP("%s dataset deleted", Dataset::TypeToString(mType));
     }
     else
     {
         SuccessOrExit(error = Get<Settings>().SaveOperationalDataset(IsActive(), aDataset));
         mSaved = true;
-        otLogInfoMeshCoP("%s dataset set", mType == Tlv::kActiveTimestamp ? "Active" : "Pending");
+        otLogInfoMeshCoP("%s dataset set", Dataset::TypeToString(mType));
     }
 
     timestamp = aDataset.GetTimestamp();
 
-    if (timestamp != NULL)
+    if (timestamp != nullptr)
     {
         mTimestamp        = *timestamp;
         mTimestampPresent = true;
@@ -196,32 +214,8 @@
 
 int DatasetLocal::Compare(const Timestamp *aCompare)
 {
-    int rval = 1;
-
-    if (aCompare == NULL)
-    {
-        if (!mTimestampPresent)
-        {
-            rval = 0;
-        }
-        else
-        {
-            rval = -1;
-        }
-    }
-    else
-    {
-        if (!mTimestampPresent)
-        {
-            rval = 1;
-        }
-        else
-        {
-            rval = mTimestamp.Compare(*aCompare);
-        }
-    }
-
-    return rval;
+    return (aCompare == nullptr) ? (!mTimestampPresent ? 0 : -1)
+                                 : (!mTimestampPresent ? 1 : mTimestamp.Compare(*aCompare));
 }
 
 } // namespace MeshCoP
diff --git a/src/core/meshcop/dataset_local.hpp b/src/core/meshcop/dataset_local.hpp
index efc87cf..84d1705 100644
--- a/src/core/meshcop/dataset_local.hpp
+++ b/src/core/meshcop/dataset_local.hpp
@@ -54,7 +54,7 @@
      * @param[in]  aType      The type of the dataset, active or pending.
      *
      */
-    DatasetLocal(Instance &aInstance, Tlv::Type aType);
+    DatasetLocal(Instance &aInstance, Dataset::Type aType);
 
     /**
      * This method indicates whether this is an Active or Pending Dataset.
@@ -63,7 +63,7 @@
      * @retval Tlv::kPendingTimetamp when this is a Pending Dataset.
      *
      */
-    Tlv::Type GetType(void) const { return mType; }
+    Dataset::Type GetType(void) const { return mType; }
 
     /**
      * This method clears the Dataset.
@@ -125,6 +125,17 @@
     otError Read(otOperationalDataset &aDataset) const;
 
     /**
+     * This method retrieves the dataset from non-volatile memory.
+     *
+     * @param[out]  aDataset  Where to place the dataset.
+     *
+     * @retval OT_ERROR_NONE       Successfully retrieved the dataset.
+     * @retval OT_ERROR_NOT_FOUND  There is no corresponding dataset stored in non-volatile memory.
+     *
+     */
+    otError Read(otOperationalDatasetTlvs &aDataset) const;
+
+    /**
      * This method returns the local time this dataset was last updated or restored.
      *
      * @returns The local time this dataset was last updated or restored.
@@ -135,7 +146,8 @@
     /**
      * This method stores the dataset into non-volatile memory.
      *
-     * @retval OT_ERROR_NONE  Successfully stored the dataset.
+     * @retval OT_ERROR_NONE              Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED   The platform does not implement settings functionality.
      *
      */
     otError Save(const otOperationalDataset &aDataset);
@@ -143,7 +155,17 @@
     /**
      * This method stores the dataset into non-volatile memory.
      *
-     * @retval OT_ERROR_NONE  Successfully stored the dataset.
+     * @retval OT_ERROR_NONE              Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED   The platform does not implement settings functionality.
+     *
+     */
+    otError Save(const otOperationalDatasetTlvs &aDataset);
+
+    /**
+     * This method stores the dataset into non-volatile memory.
+     *
+     * @retval OT_ERROR_NONE              Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED   The platform does not implement settings functionality.
      *
      */
     otError Save(const Dataset &aDataset);
@@ -161,14 +183,14 @@
     int Compare(const Timestamp *aCompare);
 
 private:
-    bool IsActive(void) const { return (mType == Tlv::kActiveTimestamp); }
+    bool IsActive(void) const { return (mType == Dataset::kActive); }
     void SetTimestamp(const Dataset &aDataset);
 
-    Timestamp mTimestamp;            ///< Active or Pending Timestamp
-    TimeMilli mUpdateTime;           ///< Local time last updated
-    Tlv::Type mType;                 ///< Active or Pending
-    bool      mTimestampPresent : 1; ///< Whether a timestamp is present
-    bool      mSaved : 1;            ///< Whether a dataset is saved in non-volatile
+    Timestamp     mTimestamp;            ///< Active or Pending Timestamp
+    TimeMilli     mUpdateTime;           ///< Local time last updated
+    Dataset::Type mType;                 ///< Active or Pending
+    bool          mTimestampPresent : 1; ///< Whether a timestamp is present
+    bool          mSaved : 1;            ///< Whether a dataset is saved in non-volatile
 };
 
 } // namespace MeshCoP
diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp
index 6053dda..16c1eb4 100644
--- a/src/core/meshcop/dataset_manager.cpp
+++ b/src/core/meshcop/dataset_manager.cpp
@@ -49,24 +49,25 @@
 namespace ot {
 namespace MeshCoP {
 
-DatasetManager::DatasetManager(Instance &      aInstance,
-                               const Tlv::Type aType,
-                               const char *    aUriGet,
-                               const char *    aUriSet,
-                               Timer::Handler  aTimerHandler)
+DatasetManager::DatasetManager(Instance &     aInstance,
+                               Dataset::Type  aType,
+                               const char *   aUriGet,
+                               const char *   aUriSet,
+                               Timer::Handler aTimerHandler)
     : InstanceLocator(aInstance)
     , mLocal(aInstance, aType)
     , mTimestampValid(false)
     , mTimer(aInstance, aTimerHandler, this)
     , mUriGet(aUriGet)
     , mUriSet(aUriSet)
+    , mCoapPending(false)
 {
     mTimestamp.Init();
 }
 
 const Timestamp *DatasetManager::GetTimestamp(void) const
 {
-    return mTimestampValid ? &mTimestamp : NULL;
+    return mTimestampValid ? &mTimestamp : nullptr;
 }
 
 int DatasetManager::Compare(const Timestamp &aTimestamp) const
@@ -96,15 +97,15 @@
 
     timestamp = dataset.GetTimestamp();
 
-    if (timestamp != NULL)
+    if (timestamp != nullptr)
     {
         mTimestamp      = *timestamp;
         mTimestampValid = true;
     }
 
-    if (mLocal.GetType() == Tlv::kActiveTimestamp)
+    if (mLocal.GetType() == Dataset::kActive)
     {
-        dataset.ApplyConfiguration(GetInstance());
+        IgnoreError(dataset.ApplyConfiguration(GetInstance()));
     }
 
 exit:
@@ -133,7 +134,7 @@
 
 void DatasetManager::HandleDetach(void)
 {
-    Restore();
+    IgnoreError(Restore());
 }
 
 otError DatasetManager::Save(const Dataset &aDataset)
@@ -145,12 +146,12 @@
 
     timestamp = aDataset.GetTimestamp();
 
-    if (timestamp != NULL)
+    if (timestamp != nullptr)
     {
         mTimestamp      = *timestamp;
         mTimestampValid = true;
 
-        if (mLocal.GetType() == Tlv::kActiveTimestamp)
+        if (mLocal.GetType() == Dataset::kActive)
         {
             SuccessOrExit(error = aDataset.ApplyConfiguration(GetInstance(), &isMasterkeyUpdated));
         }
@@ -160,19 +161,16 @@
 
     if (isMasterkeyUpdated || compare > 0)
     {
-        mLocal.Save(aDataset);
+        IgnoreError(mLocal.Save(aDataset));
 
 #if OPENTHREAD_FTD
-        if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER)
-        {
-            Get<NetworkData::Leader>().IncrementVersion();
-            Get<NetworkData::Leader>().IncrementStableVersion();
-        }
+        Get<NetworkData::Leader>().IncrementVersionAndStableVersion();
 #endif
     }
     else if (compare < 0)
     {
-        mTimer.Start(1000);
+        VerifyOrExit(!Get<Mle::MleRouter>().IsLeader(), error = OT_ERROR_INVALID_STATE);
+        SendSet();
     }
 
 exit:
@@ -181,37 +179,51 @@
 
 otError DatasetManager::Save(const otOperationalDataset &aDataset)
 {
-    otError error = OT_ERROR_NONE;
+    otError error;
 
     SuccessOrExit(error = mLocal.Save(aDataset));
+    HandleDatasetUpdated();
 
+exit:
+    return error;
+}
+
+otError DatasetManager::Save(const otOperationalDatasetTlvs &aDataset)
+{
+    otError error;
+
+    SuccessOrExit(error = mLocal.Save(aDataset));
+    HandleDatasetUpdated();
+
+exit:
+    return error;
+}
+
+void DatasetManager::HandleDatasetUpdated(void)
+{
     switch (Get<Mle::MleRouter>().GetRole())
     {
-    case OT_DEVICE_ROLE_DISABLED:
-        Restore();
+    case Mle::kRoleDisabled:
+        IgnoreError(Restore());
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
-        mTimer.Start(1000);
+    case Mle::kRoleChild:
+        SendSet();
         break;
 #if OPENTHREAD_FTD
-    case OT_DEVICE_ROLE_ROUTER:
-        mTimer.Start(1000);
+    case Mle::kRoleRouter:
+        SendSet();
         break;
 
-    case OT_DEVICE_ROLE_LEADER:
-        Restore();
-        Get<NetworkData::Leader>().IncrementVersion();
-        Get<NetworkData::Leader>().IncrementStableVersion();
+    case Mle::kRoleLeader:
+        IgnoreError(Restore());
+        Get<NetworkData::Leader>().IncrementVersionAndStableVersion();
         break;
 #endif
 
     default:
         break;
     }
-
-exit:
-    return error;
 }
 
 otError DatasetManager::GetChannelMask(Mac::ChannelMask &aChannelMask) const
@@ -223,9 +235,9 @@
 
     SuccessOrExit(error = mLocal.Read(dataset));
 
-    channelMaskTlv = static_cast<const MeshCoP::ChannelMaskTlv *>(dataset.Get(MeshCoP::Tlv::kChannelMask));
-    VerifyOrExit(channelMaskTlv != NULL, error = OT_ERROR_NOT_FOUND);
-    VerifyOrExit((mask = channelMaskTlv->GetChannelMask()) != 0);
+    channelMaskTlv = dataset.GetTlv<ChannelMaskTlv>();
+    VerifyOrExit(channelMaskTlv != nullptr, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit((mask = channelMaskTlv->GetChannelMask()) != 0, OT_NOOP);
 
     aChannelMask.SetMask(mask & Get<Mac::Mac>().GetSupportedChannelMask().GetMask());
 
@@ -237,69 +249,98 @@
 
 void DatasetManager::HandleTimer(void)
 {
-    VerifyOrExit(Get<Mle::MleRouter>().IsAttached());
-
-    VerifyOrExit(mLocal.Compare(GetTimestamp()) < 0);
-
-    if (mLocal.GetType() == Tlv::kActiveTimestamp)
-    {
-        Dataset dataset(Tlv::kPendingTimestamp);
-        Get<PendingDataset>().Read(dataset);
-
-        const ActiveTimestampTlv *tlv = static_cast<const ActiveTimestampTlv *>(dataset.Get(Tlv::kActiveTimestamp));
-        const Timestamp *         pendingActiveTimestamp = static_cast<const Timestamp *>(tlv);
-
-        if (pendingActiveTimestamp != NULL && mLocal.Compare(pendingActiveTimestamp) == 0)
-        {
-            // stop registration attempts during dataset transition
-            ExitNow();
-        }
-    }
-
-    Register();
-    mTimer.Start(1000);
-
-exit:
-    return;
+    SendSet();
 }
 
-otError DatasetManager::Register(void)
+void DatasetManager::SendSet(void)
 {
-    otError          error = OT_ERROR_NONE;
-    Coap::Message *  message;
+    otError          error;
+    Coap::Message *  message = nullptr;
     Ip6::MessageInfo messageInfo;
     Dataset          dataset(mLocal.GetType());
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(!mCoapPending, error = OT_ERROR_BUSY);
+    VerifyOrExit(Get<Mle::MleRouter>().IsAttached(), error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(mLocal.Compare(GetTimestamp()) < 0, error = OT_ERROR_INVALID_STATE);
+
+    if (mLocal.GetType() == Dataset::kActive)
+    {
+        Dataset pendingDataset(Dataset::kPending);
+        IgnoreError(Get<PendingDataset>().Read(pendingDataset));
+
+        const ActiveTimestampTlv *tlv                    = pendingDataset.GetTlv<ActiveTimestampTlv>();
+        const Timestamp *         pendingActiveTimestamp = static_cast<const Timestamp *>(tlv);
+
+        if (pendingActiveTimestamp != nullptr && mLocal.Compare(pendingActiveTimestamp) == 0)
+        {
+            // stop registration attempts during dataset transition
+            ExitNow(error = OT_ERROR_INVALID_STATE);
+        }
+    }
+
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, mUriSet));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    mLocal.Read(dataset);
+    IgnoreError(mLocal.Read(dataset));
     SuccessOrExit(error = message->Append(dataset.GetBytes(), dataset.GetSize()));
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
-    Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr());
+    IgnoreError(Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr()));
     messageInfo.SetPeerPort(kCoapUdpPort);
-    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
+    SuccessOrExit(error =
+                      Get<Coap::Coap>().SendMessage(*message, messageInfo, &DatasetManager::HandleCoapResponse, this));
 
-    otLogInfoMeshCoP("sent dataset to leader");
+    otLogInfoMeshCoP("Sent %s to leader", mUriSet);
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    switch (error)
     {
-        message->Free();
-    }
+    case OT_ERROR_NONE:
+        mCoapPending = true;
+        break;
 
-    return error;
+    case OT_ERROR_NO_BUFS:
+        mTimer.Start(kDelayNoBufs);
+        // fall through
+
+    default:
+        otLogWarnMeshCoP("Failed to send %s to leader: %s", mUriSet, otThreadErrorToString(error));
+
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+
+        break;
+    }
+}
+
+void DatasetManager::HandleCoapResponse(void *               aContext,
+                                        otMessage *          aMessage,
+                                        const otMessageInfo *aMessageInfo,
+                                        otError              aError)
+{
+    OT_UNUSED_VARIABLE(aMessage);
+    OT_UNUSED_VARIABLE(aMessageInfo);
+    OT_UNUSED_VARIABLE(aError);
+
+    static_cast<DatasetManager *>(aContext)->HandleCoapResponse();
+}
+
+void DatasetManager::HandleCoapResponse(void)
+{
+    mCoapPending = false;
+    SendSet();
 }
 
 void DatasetManager::HandleGet(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const
 {
     Tlv      tlv;
     uint16_t offset = aMessage.GetOffset();
-    uint8_t  tlvs[Dataset::kMaxSize];
+    uint8_t  tlvs[Dataset::kMaxGetTypes];
     uint8_t  length = 0;
 
     while (offset < aMessage.GetLength())
@@ -309,6 +350,13 @@
         if (tlv.GetType() == Tlv::kGet)
         {
             length = tlv.GetLength();
+
+            if (length > (sizeof(tlvs) - 1))
+            {
+                // leave space for potential DelayTimer type below
+                length = sizeof(tlvs) - 1;
+            }
+
             aMessage.Read(offset + sizeof(Tlv), length, tlvs);
             break;
         }
@@ -317,24 +365,19 @@
     }
 
     // MGMT_PENDING_GET.rsp must include Delay Timer TLV (Thread 1.1.1 Section 8.7.5.4)
-    if (length != 0 && strcmp(mUriGet, OT_URI_PATH_PENDING_GET) == 0)
+    VerifyOrExit(length > 0 && strcmp(mUriGet, OT_URI_PATH_PENDING_GET) == 0, OT_NOOP);
+
+    for (uint8_t i = 0; i < length; i++)
     {
-        uint16_t i;
-
-        for (i = 0; i < length; i++)
+        if (tlvs[i] == Tlv::kDelayTimer)
         {
-            if (tlvs[i] == Tlv::kDelayTimer)
-            {
-                break;
-            }
-        }
-
-        if (i == length && (i + 1u) <= sizeof(tlvs))
-        {
-            tlvs[length++] = Tlv::kDelayTimer;
+            ExitNow();
         }
     }
 
+    tlvs[length++] = Tlv::kDelayTimer;
+
+exit:
     SendGetResponse(aMessage, aMessageInfo, tlvs, length);
 }
 
@@ -347,27 +390,21 @@
     Coap::Message *message;
     Dataset        dataset(mLocal.GetType());
 
-    mLocal.Read(dataset);
+    IgnoreError(mLocal.Read(dataset));
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
     SuccessOrExit(error = message->SetPayloadMarker());
 
     if (aLength == 0)
     {
-        const Tlv *cur = reinterpret_cast<const Tlv *>(dataset.GetBytes());
-        const Tlv *end = reinterpret_cast<const Tlv *>(dataset.GetBytes() + dataset.GetSize());
-
-        while (cur < end)
+        for (const Tlv *cur = dataset.GetTlvsStart(); cur < dataset.GetTlvsEnd(); cur = cur->GetNext())
         {
-            if (cur->GetType() != Tlv::kNetworkMasterKey ||
-                (Get<KeyManager>().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_OBTAIN_MASTER_KEY))
+            if (cur->GetType() != Tlv::kNetworkMasterKey || Get<KeyManager>().IsObtainMasterKeyEnabled())
             {
                 SuccessOrExit(error = cur->AppendTo(*message));
             }
-
-            cur = cur->GetNext();
         }
     }
     else
@@ -376,13 +413,12 @@
         {
             const Tlv *tlv;
 
-            if (aTlvs[index] == Tlv::kNetworkMasterKey &&
-                !(Get<KeyManager>().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_OBTAIN_MASTER_KEY))
+            if (aTlvs[index] == Tlv::kNetworkMasterKey && !Get<KeyManager>().IsObtainMasterKeyEnabled())
             {
                 continue;
             }
 
-            if ((tlv = dataset.Get(static_cast<Tlv::Type>(aTlvs[index]))) != NULL)
+            if ((tlv = dataset.GetTlv(static_cast<Tlv::Type>(aTlvs[index]))) != nullptr)
             {
                 SuccessOrExit(error = tlv->AppendTo(*message));
             }
@@ -392,7 +428,7 @@
     if (message->GetLength() == message->GetOffset())
     {
         // no payload, remove coap payload marker
-        message->SetLength(message->GetLength() - 1);
+        IgnoreError(message->SetLength(message->GetLength() - 1));
     }
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo));
@@ -401,7 +437,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -413,7 +449,7 @@
     Coap::Message *  message;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, mUriSet));
     SuccessOrExit(error = message->SetPayloadMarker());
@@ -422,11 +458,10 @@
 
     if (Get<Commissioner>().IsActive())
     {
-        const Tlv *cur          = reinterpret_cast<const Tlv *>(aTlvs);
         const Tlv *end          = reinterpret_cast<const Tlv *>(aTlvs + aLength);
         bool       hasSessionId = false;
 
-        for (; cur < end; cur = cur->GetNext())
+        for (const Tlv *cur = reinterpret_cast<const Tlv *>(aTlvs); cur < end; cur = cur->GetNext())
         {
             VerifyOrExit((cur + 1) <= end, error = OT_ERROR_INVALID_ARGS);
 
@@ -439,10 +474,8 @@
 
         if (!hasSessionId)
         {
-            CommissionerSessionIdTlv sessionId;
-            sessionId.Init();
-            sessionId.SetCommissionerSessionId(Get<Commissioner>().GetSessionId());
-            SuccessOrExit(error = sessionId.AppendTo(*message));
+            SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kCommissionerSessionId,
+                                                       Get<Commissioner>().GetSessionId()));
         }
     }
 
@@ -452,8 +485,8 @@
     {
         ActiveTimestampTlv timestamp;
         timestamp.Init();
-        static_cast<Timestamp *>(&timestamp)->SetSeconds(aDataset.mActiveTimestamp);
-        static_cast<Timestamp *>(&timestamp)->SetTicks(0);
+        timestamp.SetSeconds(aDataset.mActiveTimestamp);
+        timestamp.SetTicks(0);
         SuccessOrExit(error = timestamp.AppendTo(*message));
     }
 
@@ -461,17 +494,15 @@
     {
         PendingTimestampTlv timestamp;
         timestamp.Init();
-        static_cast<Timestamp *>(&timestamp)->SetSeconds(aDataset.mPendingTimestamp);
-        static_cast<Timestamp *>(&timestamp)->SetTicks(0);
+        timestamp.SetSeconds(aDataset.mPendingTimestamp);
+        timestamp.SetTicks(0);
         SuccessOrExit(error = timestamp.AppendTo(*message));
     }
 
     if (aDataset.mComponents.mIsMasterKeyPresent)
     {
-        NetworkMasterKeyTlv masterkey;
-        masterkey.Init();
-        masterkey.SetNetworkMasterKey(static_cast<const MasterKey &>(aDataset.mMasterKey));
-        SuccessOrExit(error = masterkey.AppendTo(*message));
+        SuccessOrExit(error =
+                          Tlv::AppendTlv(*message, Tlv::kNetworkMasterKey, &aDataset.mMasterKey, sizeof(MasterKey)));
     }
 
     if (aDataset.mComponents.mIsNetworkNamePresent)
@@ -484,34 +515,24 @@
 
     if (aDataset.mComponents.mIsExtendedPanIdPresent)
     {
-        ExtendedPanIdTlv extpanid;
-        extpanid.Init();
-        extpanid.SetExtendedPanId(static_cast<const Mac::ExtendedPanId &>(aDataset.mExtendedPanId));
-        SuccessOrExit(error = extpanid.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kExtendedPanId, &aDataset.mExtendedPanId,
+                                             sizeof(Mac::ExtendedPanId)));
     }
 
     if (aDataset.mComponents.mIsMeshLocalPrefixPresent)
     {
-        MeshLocalPrefixTlv localprefix;
-        localprefix.Init();
-        localprefix.SetMeshLocalPrefix(aDataset.mMeshLocalPrefix);
-        SuccessOrExit(error = localprefix.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kMeshLocalPrefix, &aDataset.mMeshLocalPrefix,
+                                             sizeof(otMeshLocalPrefix)));
     }
 
     if (aDataset.mComponents.mIsDelayPresent)
     {
-        DelayTimerTlv delaytimer;
-        delaytimer.Init();
-        delaytimer.SetDelayTimer(aDataset.mDelay);
-        SuccessOrExit(error = delaytimer.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendUint32Tlv(*message, Tlv::kDelayTimer, aDataset.mDelay));
     }
 
     if (aDataset.mComponents.mIsPanIdPresent)
     {
-        PanIdTlv panid;
-        panid.Init();
-        panid.SetPanId(aDataset.mPanId);
-        SuccessOrExit(error = panid.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kPanId, aDataset.mPanId));
     }
 
     if (aDataset.mComponents.mIsChannelPresent)
@@ -532,10 +553,7 @@
 
     if (aDataset.mComponents.mIsPskcPresent)
     {
-        PskcTlv pskc;
-        pskc.Init();
-        pskc.SetPskc(static_cast<const Pskc &>(aDataset.mPskc));
-        SuccessOrExit(error = pskc.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kPskc, aDataset.mPskc.m8, sizeof(Pskc)));
     }
 
     if (aDataset.mComponents.mIsSecurityPolicyPresent)
@@ -555,11 +573,11 @@
     if (message->GetLength() == message->GetOffset())
     {
         // no payload, remove coap payload marker
-        message->SetLength(message->GetLength() - 1);
+        IgnoreError(message->SetLength(message->GetLength() - 1));
     }
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
-    Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr());
+    IgnoreError(Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr()));
     messageInfo.SetPeerPort(kCoapUdpPort);
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
 
@@ -567,7 +585,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -649,7 +667,7 @@
         datasetTlvs[length++] = Tlv::kChannelMask;
     }
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, mUriGet));
 
@@ -675,13 +693,13 @@
         }
     }
 
-    if (aAddress != NULL)
+    if (aAddress != nullptr)
     {
         messageInfo.SetPeerAddr(*static_cast<const Ip6::Address *>(aAddress));
     }
     else
     {
-        Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr());
+        IgnoreError(Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr()));
     }
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
@@ -692,7 +710,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -702,10 +720,10 @@
 
 ActiveDataset::ActiveDataset(Instance &aInstance)
     : DatasetManager(aInstance,
-                     Tlv::kActiveTimestamp,
+                     Dataset::kActive,
                      OT_URI_PATH_ACTIVE_GET,
                      OT_URI_PATH_ACTIVE_SET,
-                     &ActiveDataset::HandleTimer)
+                     ActiveDataset::HandleTimer)
     , mResourceGet(OT_URI_PATH_ACTIVE_GET, &ActiveDataset::HandleGet, this)
 #if OPENTHREAD_FTD
     , mResourceSet(OT_URI_PATH_ACTIVE_SET, &ActiveDataset::HandleSet, this)
@@ -726,7 +744,7 @@
 
     SuccessOrExit(error = dataset.Set(aMessage, aOffset, aLength));
     dataset.SetTimestamp(aTimestamp);
-    DatasetManager::Save(dataset);
+    IgnoreError(DatasetManager::Save(dataset));
 
 exit:
     return error;
@@ -750,11 +768,11 @@
 
 PendingDataset::PendingDataset(Instance &aInstance)
     : DatasetManager(aInstance,
-                     Tlv::kPendingTimestamp,
+                     Dataset::kPending,
                      OT_URI_PATH_PENDING_GET,
                      OT_URI_PATH_PENDING_SET,
-                     &PendingDataset::HandleTimer)
-    , mDelayTimer(aInstance, &PendingDataset::HandleDelayTimer, this)
+                     PendingDataset::HandleTimer)
+    , mDelayTimer(aInstance, PendingDataset::HandleDelayTimer, this)
     , mResourceGet(OT_URI_PATH_PENDING_GET, &PendingDataset::HandleGet, this)
 #if OPENTHREAD_FTD
     , mResourceSet(OT_URI_PATH_PENDING_SET, &PendingDataset::HandleSet, this)
@@ -775,12 +793,23 @@
 
     mTimestamp.Init();
     mTimestampValid = false;
-    DatasetManager::Save(dataset);
+    IgnoreError(DatasetManager::Save(dataset));
 }
 
 otError PendingDataset::Save(const otOperationalDataset &aDataset)
 {
-    otError error = OT_ERROR_NONE;
+    otError error;
+
+    SuccessOrExit(error = DatasetManager::Save(aDataset));
+    StartDelayTimer();
+
+exit:
+    return error;
+}
+
+otError PendingDataset::Save(const otOperationalDatasetTlvs &aDataset)
+{
+    otError error;
 
     SuccessOrExit(error = DatasetManager::Save(aDataset));
     StartDelayTimer();
@@ -796,7 +825,7 @@
 
     SuccessOrExit(error = dataset.Set(aMessage, aOffset, aLength));
     dataset.SetTimestamp(aTimestamp);
-    DatasetManager::Save(dataset);
+    IgnoreError(DatasetManager::Save(dataset));
     StartDelayTimer();
 
 exit:
@@ -808,11 +837,11 @@
     DelayTimerTlv *delayTimer;
     Dataset        dataset(mLocal.GetType());
 
-    mLocal.Read(dataset);
+    IgnoreError(mLocal.Read(dataset));
 
     mDelayTimer.Stop();
 
-    if ((delayTimer = static_cast<DelayTimerTlv *>(dataset.Get(Tlv::kDelayTimer))) != NULL)
+    if ((delayTimer = dataset.GetTlv<DelayTimerTlv>()) != nullptr)
     {
         uint32_t delay = delayTimer->GetDelayTimer();
 
@@ -837,11 +866,11 @@
     DelayTimerTlv *delayTimer;
     Dataset        dataset(mLocal.GetType());
 
-    mLocal.Read(dataset);
+    IgnoreError(mLocal.Read(dataset));
 
     // if the Delay Timer value is larger than what our Timer implementation can handle, we have to compute
     // the remainder and wait some more.
-    if ((delayTimer = static_cast<DelayTimerTlv *>(dataset.Get(Tlv::kDelayTimer))) != NULL)
+    if ((delayTimer = dataset.GetTlv<DelayTimerTlv>()) != nullptr)
     {
         uint32_t elapsed = mDelayTimer.GetFireTime() - dataset.GetUpdateTime();
         uint32_t delay   = delayTimer->GetDelayTimer();
diff --git a/src/core/meshcop/dataset_manager.hpp b/src/core/meshcop/dataset_manager.hpp
index cc0967a..b9a46cf 100644
--- a/src/core/meshcop/dataset_manager.hpp
+++ b/src/core/meshcop/dataset_manager.hpp
@@ -104,6 +104,17 @@
     otError Read(otOperationalDataset &aDataset) const { return mLocal.Read(aDataset); }
 
     /**
+     * This method retrieves the dataset from non-volatile memory.
+     *
+     * @param[out]  aDataset  Where to place the dataset.
+     *
+     * @retval OT_ERROR_NONE       Successfully retrieved the dataset.
+     * @retval OT_ERROR_NOT_FOUND  There is no corresponding dataset stored in non-volatile memory.
+     *
+     */
+    otError Read(otOperationalDatasetTlvs &aDataset) const { return mLocal.Read(aDataset); }
+
+    /**
      * This method retrieves the channel mask from local dataset.
      *
      * @param[out]  aChannelMask  A reference to the channel mask.
@@ -134,7 +145,7 @@
     /**
      * This method sends a MGMT_SET request to the Leader.
      *
-     * @param[in]  aDataset  The Operational Datset.
+     * @param[in]  aDataset  The Operational Dataset.
      * @param[in]  aTlvs     Any additional raw TLVs to include.
      * @param[in]  aLength   Number of bytes in @p aTlvs.
      *
@@ -163,6 +174,35 @@
 
 protected:
     /**
+     * This class defines a generic Dataset TLV to read from a message.
+     *
+     */
+    OT_TOOL_PACKED_BEGIN
+    class DatasetTlv : public Tlv
+    {
+    public:
+        /**
+         * This method reads the Dataset TLV from a given message at a given offset.
+         *
+         * @param[in]  aMessage  A message to read the TLV from.
+         * @param[in]  aOffset   An offset into the message to read from.
+         *
+         * @retval OT_ERROR_NONE    The TLV was read successfully.
+         * @retval OT_ERROR_PARSE   The TLV was not well-formed and could not be parsed.
+         *
+         */
+        otError ReadFromMessage(const Message &aMessage, uint16_t aOffset);
+
+    private:
+        enum
+        {
+            kMaxValueSize = 16, // Maximum size of a Dataset TLV value (bytes).
+        };
+
+        uint8_t mValue[Dataset::kMaxValueSize];
+    } OT_TOOL_PACKED_END;
+
+    /**
      * This constructor initializes the object.
      *
      * @param[in]  aInstance      A reference to the OpenThread instance.
@@ -173,7 +213,7 @@
      *
      */
     DatasetManager(Instance &          aInstance,
-                   Tlv::Type           aType,
+                   Dataset::Type       aType,
                    const char *        aUriGet,
                    const char *        aUriSet,
                    TimerMilli::Handler aTimerHandler);
@@ -200,10 +240,24 @@
      *
      * @param[in]  aDataset  The Operational Dataset.
      *
+     * @retval OT_ERROR_NONE             Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+     *
      */
     otError Save(const otOperationalDataset &aDataset);
 
     /**
+     * This method saves the Operational Dataset in non-volatile memory.
+     *
+     * @param[in]  aDataset  The Operational Dataset.
+     *
+     * @retval OT_ERROR_NONE             Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+     *
+     */
+    otError Save(const otOperationalDatasetTlvs &aDataset);
+
+    /**
      * This method sets the Operational Dataset for the partition.
      *
      * This method also updates the non-volatile version if the partition's Operational Dataset is newer.
@@ -241,13 +295,6 @@
      */
     void HandleTimer(void);
 
-    /**
-     * This method re-defines template `Get<Type>()` as the `InstanceLoctaor` (base class) definition is shadowed by
-     * the public `Get(dataset)` methods in this class.
-     *
-     */
-    template <typename Type> inline Type &Get(void) const { return InstanceLocator::Get<Type>(); }
-
     DatasetLocal mLocal;
     Timestamp    mTimestamp;
     bool         mTimestampValid : 1;
@@ -256,15 +303,23 @@
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleUdpReceive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
-    otError Register(void);
-    void    SendGetResponse(const Coap::Message &   aRequest,
-                            const Ip6::MessageInfo &aMessageInfo,
-                            uint8_t *               aTlvs,
-                            uint8_t                 aLength) const;
+    static void HandleCoapResponse(void *               aContext,
+                                   otMessage *          aMessage,
+                                   const otMessageInfo *aMessageInfo,
+                                   otError              aError);
+    void        HandleCoapResponse(void);
+
+    void HandleDatasetUpdated(void);
+    void SendSet(void);
+    void SendGetResponse(const Coap::Message &   aRequest,
+                         const Ip6::MessageInfo &aMessageInfo,
+                         uint8_t *               aTlvs,
+                         uint8_t                 aLength) const;
 
     enum
     {
-        kMaxDatasetTlvs = 16, // Maximum number of TLVs in an `otOperationalDataset`.
+        kMaxDatasetTlvs = 16,   // Maximum number of TLVs in an `otOperationalDataset`.
+        kDelayNoBufs    = 1000, // Milliseconds
     };
 
     TimerMilli mTimer;
@@ -272,6 +327,8 @@
     const char *mUriGet;
     const char *mUriSet;
 
+    bool mCoapPending : 1;
+
 #if OPENTHREAD_FTD
 public:
     /**
@@ -339,7 +396,7 @@
      * @param[in]  aDataset  The Operational Dataset.
      *
      */
-    void Save(const Dataset &aDataset) { DatasetManager::Save(aDataset); }
+    void Save(const Dataset &aDataset) { IgnoreError(DatasetManager::Save(aDataset)); }
 
     /**
      * This method sets the Operational Dataset for the partition.
@@ -360,9 +417,23 @@
      *
      * @param[in]  aDataset  The Operational Dataset.
      *
+     * @retval OT_ERROR_NONE             Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+     *
      */
     otError Save(const otOperationalDataset &aDataset) { return DatasetManager::Save(aDataset); }
 
+    /**
+     * This method sets the Operational Dataset in non-volatile memory.
+     *
+     * @param[in]  aDataset  The Operational Dataset.
+     *
+     * @retval OT_ERROR_NONE             Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+     *
+     */
+    otError Save(const otOperationalDatasetTlvs &aDataset) { return DatasetManager::Save(aDataset); }
+
 #if OPENTHREAD_FTD
 
     /**
@@ -452,10 +523,26 @@
      *
      * @param[in]  aDataset  The Operational Dataset.
      *
+     * @retval OT_ERROR_NONE             Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+     *
      */
     otError Save(const otOperationalDataset &aDataset);
 
     /**
+     * This method saves the Operational Dataset in non-volatile memory.
+     *
+     * This method also starts the Delay Timer.
+     *
+     * @param[in]  aDataset  The Operational Dataset.
+     *
+     * @retval OT_ERROR_NONE             Successfully saved the dataset.
+     * @retval OT_ERROR_NOT_IMPLEMENTED  The platform does not implement settings functionality.
+     *
+     */
+    otError Save(const otOperationalDatasetTlvs &aDataset);
+
+    /**
      * This method sets the Operational Dataset for the partition.
      *
      * This method also updates the non-volatile version if the partition's Operational Dataset is newer.
diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp
index 0b72546..fd67a92 100644
--- a/src/core/meshcop/dataset_manager_ftd.cpp
+++ b/src/core/meshcop/dataset_manager_ftd.cpp
@@ -47,8 +47,8 @@
 #include "common/timer.hpp"
 #include "meshcop/dataset.hpp"
 #include "meshcop/dataset_manager.hpp"
-#include "meshcop/leader.hpp"
 #include "meshcop/meshcop.hpp"
+#include "meshcop/meshcop_leader.hpp"
 #include "meshcop/meshcop_tlvs.hpp"
 #include "thread/thread_netif.hpp"
 #include "thread/thread_tlvs.hpp"
@@ -61,7 +61,7 @@
 {
     Dataset dataset(mLocal.GetType());
 
-    mLocal.Read(dataset);
+    IgnoreError(mLocal.Read(dataset));
 
     return dataset.AppendMleDatasetTlv(aMessage);
 }
@@ -75,63 +75,60 @@
     bool            isUpdateFromCommissioner = false;
     bool            doesAffectConnectivity   = false;
     bool            doesAffectMasterKey      = false;
+    bool            hasMasterKey             = false;
     StateTlv::State state                    = StateTlv::kReject;
     Dataset         dataset(mLocal.GetType());
 
-    ActiveTimestampTlv       activeTimestamp;
-    PendingTimestampTlv      pendingTimestamp;
-    ChannelTlv               channel;
-    CommissionerSessionIdTlv sessionId;
-    MeshLocalPrefixTlv       meshLocalPrefix;
-    NetworkMasterKeyTlv      masterKey;
-    PanIdTlv                 panId;
+    ActiveTimestampTlv   activeTimestamp;
+    PendingTimestampTlv  pendingTimestamp;
+    ChannelTlv           channel;
+    uint16_t             sessionId;
+    Mle::MeshLocalPrefix meshLocalPrefix;
+    MasterKey            masterKey;
+    uint16_t             panId;
 
     activeTimestamp.SetLength(0);
     pendingTimestamp.SetLength(0);
     channel.SetLength(0);
-    masterKey.SetLength(0);
-    meshLocalPrefix.SetLength(0);
-    panId.SetLength(0);
     pendingTimestamp.SetLength(0);
-    sessionId.SetLength(0);
 
-    VerifyOrExit(Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER);
+    VerifyOrExit(Get<Mle::MleRouter>().IsLeader(), OT_NOOP);
 
     // verify that TLV data size is less than maximum TLV value size
     while (offset < aMessage.GetLength())
     {
         aMessage.Read(offset, sizeof(tlv), &tlv);
-        VerifyOrExit(tlv.GetLength() <= Dataset::kMaxValueSize);
+        VerifyOrExit(tlv.GetLength() <= Dataset::kMaxValueSize, OT_NOOP);
         offset += sizeof(tlv) + tlv.GetLength();
     }
 
     // verify that does not overflow dataset buffer
-    VerifyOrExit((offset - aMessage.GetOffset()) <= Dataset::kMaxSize);
+    VerifyOrExit((offset - aMessage.GetOffset()) <= Dataset::kMaxSize, OT_NOOP);
 
     type = (strcmp(mUriSet, OT_URI_PATH_ACTIVE_SET) == 0 ? Tlv::kActiveTimestamp : Tlv::kPendingTimestamp);
 
-    if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) != OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) != OT_ERROR_NONE)
     {
         ExitNow();
     }
 
-    VerifyOrExit(activeTimestamp.IsValid());
+    VerifyOrExit(activeTimestamp.IsValid(), OT_NOOP);
 
-    if (Tlv::GetTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
     {
-        VerifyOrExit(pendingTimestamp.IsValid());
+        VerifyOrExit(pendingTimestamp.IsValid(), OT_NOOP);
     }
 
     // verify the request includes a timestamp that is ahead of the locally stored value
     timestamp = (type == Tlv::kActiveTimestamp) ? static_cast<Timestamp *>(&activeTimestamp)
                                                 : static_cast<Timestamp *>(&pendingTimestamp);
 
-    VerifyOrExit(mLocal.Compare(timestamp) > 0);
+    VerifyOrExit(mLocal.Compare(timestamp) > 0, OT_NOOP);
 
     // check channel
-    if (Tlv::GetTlv(aMessage, Tlv::kChannel, sizeof(channel), channel) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kChannel, sizeof(channel), channel) == OT_ERROR_NONE)
     {
-        VerifyOrExit(channel.IsValid());
+        VerifyOrExit(channel.IsValid(), OT_NOOP);
 
         if (channel.GetChannel() != Get<Mac::Mac>().GetPanChannel())
         {
@@ -140,61 +137,60 @@
     }
 
     // check PAN ID
-    if (Tlv::GetTlv(aMessage, Tlv::kPanId, sizeof(panId), panId) == OT_ERROR_NONE && panId.IsValid() &&
-        panId.GetPanId() != Get<Mac::Mac>().GetPanId())
+    if (Tlv::FindUint16Tlv(aMessage, Tlv::kPanId, panId) == OT_ERROR_NONE && panId != Get<Mac::Mac>().GetPanId())
     {
         doesAffectConnectivity = true;
     }
 
     // check mesh local prefix
-    if (Tlv::GetTlv(aMessage, Tlv::kMeshLocalPrefix, sizeof(meshLocalPrefix), meshLocalPrefix) == OT_ERROR_NONE &&
-        meshLocalPrefix.IsValid() &&
-        memcmp(&meshLocalPrefix.GetMeshLocalPrefix(), &Get<Mle::MleRouter>().GetMeshLocalPrefix(),
-               meshLocalPrefix.GetMeshLocalPrefixLength()))
+    if (Tlv::FindTlv(aMessage, Tlv::kMeshLocalPrefix, &meshLocalPrefix, sizeof(meshLocalPrefix)) == OT_ERROR_NONE &&
+        meshLocalPrefix != Get<Mle::MleRouter>().GetMeshLocalPrefix())
     {
         doesAffectConnectivity = true;
     }
 
     // check network master key
-    if (Tlv::GetTlv(aMessage, Tlv::kNetworkMasterKey, sizeof(masterKey), masterKey) == OT_ERROR_NONE &&
-        masterKey.IsValid() && (masterKey.GetNetworkMasterKey() != Get<KeyManager>().GetMasterKey()))
+    if (Tlv::FindTlv(aMessage, Tlv::kNetworkMasterKey, &masterKey, sizeof(masterKey)) == OT_ERROR_NONE)
     {
-        doesAffectConnectivity = true;
-        doesAffectMasterKey    = true;
+        hasMasterKey = true;
+
+        if (masterKey != Get<KeyManager>().GetMasterKey())
+        {
+            doesAffectConnectivity = true;
+            doesAffectMasterKey    = true;
+        }
     }
 
     // check active timestamp rollback
-    if (type == Tlv::kPendingTimestamp &&
-        ((masterKey.GetLength() == 0) || (masterKey.GetNetworkMasterKey() == Get<KeyManager>().GetMasterKey())))
+    if (type == Tlv::kPendingTimestamp && (!hasMasterKey || (masterKey == Get<KeyManager>().GetMasterKey())))
     {
         // no change to master key, active timestamp must be ahead
         const Timestamp *localActiveTimestamp = Get<ActiveDataset>().GetTimestamp();
 
-        VerifyOrExit(localActiveTimestamp == NULL || localActiveTimestamp->Compare(activeTimestamp) > 0);
+        VerifyOrExit(localActiveTimestamp == nullptr || localActiveTimestamp->Compare(activeTimestamp) > 0, OT_NOOP);
     }
 
     // check commissioner session id
-    if (Tlv::GetTlv(aMessage, Tlv::kCommissionerSessionId, sizeof(sessionId), sessionId) == OT_ERROR_NONE)
+    if (Tlv::FindUint16Tlv(aMessage, Tlv::kCommissionerSessionId, sessionId) == OT_ERROR_NONE)
     {
-        CommissionerSessionIdTlv *localId;
+        const CommissionerSessionIdTlv *localId;
 
         isUpdateFromCommissioner = true;
 
-        localId = static_cast<CommissionerSessionIdTlv *>(
+        localId = static_cast<const CommissionerSessionIdTlv *>(
             Get<NetworkData::Leader>().GetCommissioningDataSubTlv(Tlv::kCommissionerSessionId));
 
-        VerifyOrExit(sessionId.IsValid() && localId != NULL &&
-                     localId->GetCommissionerSessionId() == sessionId.GetCommissionerSessionId());
+        VerifyOrExit(localId != nullptr && localId->GetCommissionerSessionId() == sessionId, OT_NOOP);
     }
 
     // verify an MGMT_ACTIVE_SET.req from a Commissioner does not affect connectivity
-    VerifyOrExit(!isUpdateFromCommissioner || type == Tlv::kPendingTimestamp || !doesAffectConnectivity);
+    VerifyOrExit(!isUpdateFromCommissioner || type == Tlv::kPendingTimestamp || !doesAffectConnectivity, OT_NOOP);
 
     if (isUpdateFromCommissioner)
     {
         // Thread specification allows partial dataset changes for MGMT_ACTIVE_SET.req/MGMT_PENDING_SET.req
         // from Commissioner based on existing active dataset.
-        Get<ActiveDataset>().Read(dataset);
+        IgnoreError(Get<ActiveDataset>().Read(dataset));
     }
 
     if (type == Tlv::kPendingTimestamp || !doesAffectConnectivity)
@@ -203,19 +199,11 @@
 
         while (offset < aMessage.GetLength())
         {
-            OT_TOOL_PACKED_BEGIN
-            struct
-            {
-                Tlv     tlv;
-                uint8_t value[Dataset::kMaxValueSize];
-            } OT_TOOL_PACKED_END data;
+            DatasetTlv datasetTlv;
 
-            VerifyOrExit(aMessage.Read(offset, sizeof(Tlv), &data.tlv) == sizeof(Tlv));
-            VerifyOrExit(data.tlv.GetLength() <= sizeof(data.value));
+            SuccessOrExit(datasetTlv.ReadFromMessage(aMessage, offset));
 
-            VerifyOrExit(aMessage.Read(offset + sizeof(Tlv), data.tlv.GetLength(), data.value) == data.tlv.GetLength());
-
-            switch (data.tlv.GetType())
+            switch (datasetTlv.GetType())
             {
             case Tlv::kCommissionerSessionId:
                 // do not store Commissioner Session ID TLV
@@ -223,31 +211,30 @@
 
             case Tlv::kDelayTimer:
             {
-                DelayTimerTlv *delayTimerTlv = static_cast<DelayTimerTlv *>(&data.tlv);
+                DelayTimerTlv &delayTimerTlv = static_cast<DelayTimerTlv &>(static_cast<Tlv &>(datasetTlv));
 
-                if (doesAffectMasterKey && delayTimerTlv->GetDelayTimer() < DelayTimerTlv::kDelayTimerDefault)
+                if (doesAffectMasterKey && delayTimerTlv.GetDelayTimer() < DelayTimerTlv::kDelayTimerDefault)
                 {
-                    delayTimerTlv->SetDelayTimer(DelayTimerTlv::kDelayTimerDefault);
+                    delayTimerTlv.SetDelayTimer(DelayTimerTlv::kDelayTimerDefault);
                 }
-                else if (delayTimerTlv->GetDelayTimer() < Get<Leader>().GetDelayTimerMinimal())
+                else if (delayTimerTlv.GetDelayTimer() < Get<Leader>().GetDelayTimerMinimal())
                 {
-                    delayTimerTlv->SetDelayTimer(Get<Leader>().GetDelayTimerMinimal());
+                    delayTimerTlv.SetDelayTimer(Get<Leader>().GetDelayTimerMinimal());
                 }
             }
 
                 // fall through
 
             default:
-                SuccessOrExit(dataset.Set(data.tlv));
+                SuccessOrExit(dataset.SetTlv(datasetTlv));
                 break;
             }
 
-            offset += sizeof(Tlv) + data.tlv.GetLength();
+            offset += static_cast<uint16_t>(datasetTlv.GetSize());
         }
 
         SuccessOrExit(Save(dataset));
-        Get<NetworkData::Leader>().IncrementVersion();
-        Get<NetworkData::Leader>().IncrementStableVersion();
+        Get<NetworkData::Leader>().IncrementVersionAndStableVersion();
     }
     else
     {
@@ -259,12 +246,12 @@
     // notify commissioner if update is from thread device
     if (!isUpdateFromCommissioner)
     {
-        CommissionerSessionIdTlv *localSessionId;
-        Ip6::Address              destination;
+        const CommissionerSessionIdTlv *localSessionId;
+        Ip6::Address                    destination;
 
-        localSessionId = static_cast<CommissionerSessionIdTlv *>(
+        localSessionId = static_cast<const CommissionerSessionIdTlv *>(
             Get<NetworkData::Leader>().GetCommissioningDataSubTlv(Tlv::kCommissionerSessionId));
-        VerifyOrExit(localSessionId != NULL);
+        VerifyOrExit(localSessionId != nullptr, OT_NOOP);
 
         SuccessOrExit(
             Get<Mle::MleRouter>().GetCommissionerAloc(destination, localSessionId->GetCommissionerSessionId()));
@@ -274,7 +261,7 @@
 
 exit:
 
-    if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER)
+    if (Get<Mle::MleRouter>().IsLeader())
     {
         SendSetResponse(aMessage, aMessageInfo, state);
     }
@@ -288,16 +275,13 @@
 {
     otError        error = OT_ERROR_NONE;
     Coap::Message *message;
-    StateTlv       state;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    state.Init();
-    state.SetState(aState);
-    SuccessOrExit(error = state.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, Tlv::kState, static_cast<uint8_t>(aState)));
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo));
 
@@ -305,12 +289,25 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
 }
 
+otError DatasetManager::DatasetTlv::ReadFromMessage(const Message &aMessage, uint16_t aOffset)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(aMessage.Read(aOffset, sizeof(Tlv), this) == sizeof(Tlv), error = OT_ERROR_PARSE);
+    VerifyOrExit(GetLength() <= kMaxValueSize, error = OT_ERROR_PARSE);
+    VerifyOrExit(aMessage.Read(aOffset + sizeof(Tlv), GetLength(), mValue) == GetLength(), error = OT_ERROR_PARSE);
+    VerifyOrExit(Tlv::IsValid(*this), error = OT_ERROR_PARSE);
+
+exit:
+    return error;
+}
+
 otError ActiveDataset::CreateNewNetwork(otOperationalDataset &aDataset)
 {
     otError          error             = OT_ERROR_NONE;
@@ -325,8 +322,7 @@
     SuccessOrExit(error = static_cast<Pskc &>(aDataset.mPskc).GenerateRandom());
     SuccessOrExit(error = Random::Crypto::FillBuffer(aDataset.mExtendedPanId.m8, sizeof(aDataset.mExtendedPanId)));
 
-    aDataset.mMeshLocalPrefix.m8[0] = 0xfd;
-    SuccessOrExit(error = Random::Crypto::FillBuffer(&aDataset.mMeshLocalPrefix.m8[1], OT_MESH_LOCAL_PREFIX_SIZE - 1));
+    SuccessOrExit(error = static_cast<Ip6::NetworkPrefix &>(aDataset.mMeshLocalPrefix).GenerateRandomUla());
 
     aDataset.mSecurityPolicy.mFlags = Get<KeyManager>().GetSecurityPolicyFlags();
 
@@ -371,92 +367,67 @@
     VerifyOrExit(Get<Mle::MleRouter>().IsAttached(), error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(!mLocal.IsTimestampPresent(), error = OT_ERROR_ALREADY);
 
-    mLocal.Read(dataset);
+    IgnoreError(mLocal.Read(dataset));
 
-    // Active Timestamp
-    if (dataset.Get(Tlv::kActiveTimestamp) == NULL)
+    if (dataset.GetTlv<ActiveTimestampTlv>() == nullptr)
     {
         ActiveTimestampTlv activeTimestampTlv;
         activeTimestampTlv.Init();
         activeTimestampTlv.SetSeconds(0);
         activeTimestampTlv.SetTicks(0);
-        dataset.Set(activeTimestampTlv);
+        IgnoreError(dataset.SetTlv(activeTimestampTlv));
     }
 
-    // Channel
-    if (dataset.Get(Tlv::kChannel) == NULL)
+    if (dataset.GetTlv<ChannelTlv>() == nullptr)
     {
         ChannelTlv tlv;
         tlv.Init();
         tlv.SetChannel(Get<Mac::Mac>().GetPanChannel());
-        dataset.Set(tlv);
+        IgnoreError(dataset.SetTlv(tlv));
     }
 
-    // channelMask
-    if (dataset.Get(Tlv::kChannelMask) == NULL)
+    if (dataset.GetTlv<ChannelMaskTlv>() == nullptr)
     {
         ChannelMaskTlv tlv;
         tlv.Init();
         tlv.SetChannelMask(Get<Mac::Mac>().GetSupportedChannelMask().GetMask());
-        dataset.Set(tlv);
+        IgnoreError(dataset.SetTlv(tlv));
     }
 
-    // Extended PAN ID
-    if (dataset.Get(Tlv::kExtendedPanId) == NULL)
+    if (dataset.GetTlv<ExtendedPanIdTlv>() == nullptr)
     {
-        ExtendedPanIdTlv tlv;
-        tlv.Init();
-        tlv.SetExtendedPanId(Get<Mac::Mac>().GetExtendedPanId());
-        dataset.Set(tlv);
+        IgnoreError(
+            dataset.SetTlv(Tlv::kExtendedPanId, &Get<Mac::Mac>().GetExtendedPanId(), sizeof(Mac::ExtendedPanId)));
     }
 
-    // Mesh-Local Prefix
-    if (dataset.Get(Tlv::kMeshLocalPrefix) == NULL)
+    if (dataset.GetTlv<MeshLocalPrefixTlv>() == nullptr)
     {
-        MeshLocalPrefixTlv tlv;
-        tlv.Init();
-        tlv.SetMeshLocalPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
-        dataset.Set(tlv);
+        IgnoreError(dataset.SetTlv(Tlv::kMeshLocalPrefix, &Get<Mle::MleRouter>().GetMeshLocalPrefix(),
+                                   sizeof(Mle::MeshLocalPrefix)));
     }
 
-    // Master Key
-    if (dataset.Get(Tlv::kNetworkMasterKey) == NULL)
+    if (dataset.GetTlv<NetworkMasterKeyTlv>() == nullptr)
     {
-        NetworkMasterKeyTlv tlv;
-        tlv.Init();
-        tlv.SetNetworkMasterKey(Get<KeyManager>().GetMasterKey());
-        dataset.Set(tlv);
+        IgnoreError(dataset.SetTlv(Tlv::kNetworkMasterKey, &Get<KeyManager>().GetMasterKey(), sizeof(MasterKey)));
     }
 
-    // Network Name
-    if (dataset.Get(Tlv::kNetworkName) == NULL)
+    if (dataset.GetTlv<NetworkNameTlv>() == nullptr)
     {
-        NetworkNameTlv tlv;
-        tlv.Init();
-        tlv.SetNetworkName(Get<Mac::Mac>().GetNetworkName().GetAsData());
-        dataset.Set(tlv);
+        Mac::NameData nameData = Get<Mac::Mac>().GetNetworkName().GetAsData();
+
+        IgnoreError(dataset.SetTlv(Tlv::kNetworkName, nameData.GetBuffer(), nameData.GetLength()));
     }
 
-    // Pan ID
-    if (dataset.Get(Tlv::kPanId) == NULL)
+    if (dataset.GetTlv<PanIdTlv>() == nullptr)
     {
-        PanIdTlv tlv;
-        tlv.Init();
-        tlv.SetPanId(Get<Mac::Mac>().GetPanId());
-        dataset.Set(tlv);
+        IgnoreError(dataset.SetUint16Tlv(Tlv::kPanId, Get<Mac::Mac>().GetPanId()));
     }
 
-    // PSKc
-    if (dataset.Get(Tlv::kPskc) == NULL)
+    if (dataset.GetTlv<PskcTlv>() == nullptr)
     {
-        PskcTlv tlv;
-
-        tlv.Init();
-
         if (Get<KeyManager>().IsPskcSet())
         {
-            // use configured PSKc
-            tlv.SetPskc(Get<KeyManager>().GetPskc());
+            IgnoreError(dataset.SetTlv(Tlv::kPskc, &Get<KeyManager>().GetPskc(), sizeof(Pskc)));
         }
         else
         {
@@ -464,24 +435,21 @@
             Pskc pskc;
 
             SuccessOrExit(error = pskc.GenerateRandom());
-            tlv.SetPskc(pskc);
+            IgnoreError(dataset.SetTlv(Tlv::kPskc, &pskc, sizeof(Pskc)));
         }
-
-        dataset.Set(tlv);
     }
 
-    // Security Policy
-    if (dataset.Get(Tlv::kSecurityPolicy) == NULL)
+    if (dataset.GetTlv<SecurityPolicyTlv>() == nullptr)
     {
         SecurityPolicyTlv tlv;
         tlv.Init();
         tlv.SetRotationTime(static_cast<uint16_t>(Get<KeyManager>().GetKeyRotation()));
         tlv.SetFlags(Get<KeyManager>().GetSecurityPolicyFlags());
-        dataset.Set(tlv);
+        IgnoreError(dataset.SetTlv(tlv));
     }
 
     SuccessOrExit(error = mLocal.Save(dataset));
-    Restore();
+    IgnoreError(Restore());
 
     otLogInfoMeshCoP("Generated local dataset");
 
@@ -491,7 +459,7 @@
 
 void ActiveDataset::StartLeader(void)
 {
-    GenerateLocal();
+    IgnoreError(GenerateLocal());
     Get<Coap::Coap>().AddResource(mResourceSet);
 }
 
@@ -509,7 +477,7 @@
 void ActiveDataset::HandleSet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     SuccessOrExit(DatasetManager::HandleSet(aMessage, aMessageInfo));
-    ApplyConfiguration();
+    IgnoreError(ApplyConfiguration());
 
 exit:
     return;
@@ -543,35 +511,26 @@
 
 void PendingDataset::ApplyActiveDataset(const Timestamp &aTimestamp, Coap::Message &aMessage)
 {
-    uint16_t      offset = aMessage.GetOffset();
-    Dataset       dataset(mLocal.GetType());
-    DelayTimerTlv delayTimer;
+    uint16_t offset = aMessage.GetOffset();
+    Dataset  dataset(mLocal.GetType());
 
-    VerifyOrExit(Get<Mle::MleRouter>().IsAttached());
+    VerifyOrExit(Get<Mle::MleRouter>().IsAttached(), OT_NOOP);
 
     while (offset < aMessage.GetLength())
     {
-        OT_TOOL_PACKED_BEGIN
-        struct
-        {
-            Tlv     tlv;
-            uint8_t value[Dataset::kMaxValueSize];
-        } OT_TOOL_PACKED_END data;
+        DatasetTlv datasetTlv;
 
-        aMessage.Read(offset, sizeof(Tlv), &data.tlv);
-        aMessage.Read(offset + sizeof(Tlv), data.tlv.GetLength(), data.value);
-        dataset.Set(data.tlv);
-        offset += sizeof(Tlv) + data.tlv.GetLength();
+        SuccessOrExit(datasetTlv.ReadFromMessage(aMessage, offset));
+        offset += static_cast<uint16_t>(datasetTlv.GetSize());
+        IgnoreError(dataset.SetTlv(datasetTlv));
     }
 
     // add delay timer tlv
-    delayTimer.Init();
-    delayTimer.SetDelayTimer(Get<Leader>().GetDelayTimerMinimal());
-    dataset.Set(delayTimer);
+    IgnoreError(dataset.SetUint32Tlv(Tlv::kDelayTimer, Get<Leader>().GetDelayTimerMinimal()));
 
     // add pending timestamp tlv
     dataset.SetTimestamp(aTimestamp);
-    DatasetManager::Save(dataset);
+    IgnoreError(DatasetManager::Save(dataset));
 
     // reset delay timer
     StartDelayTimer();
diff --git a/src/core/meshcop/dtls.cpp b/src/core/meshcop/dtls.cpp
index 4afb7de..a97d79a 100644
--- a/src/core/meshcop/dtls.cpp
+++ b/src/core/meshcop/dtls.cpp
@@ -45,7 +45,6 @@
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
 #include "common/logging.hpp"
-#include "common/new.hpp"
 #include "common/timer.hpp"
 #include "crypto/mbedtls.hpp"
 #include "crypto/sha256.hpp"
@@ -56,46 +55,50 @@
 namespace ot {
 namespace MeshCoP {
 
+const mbedtls_ecp_group_id Dtls::sCurves[] = {MBEDTLS_ECP_DP_SECP256R1, MBEDTLS_ECP_DP_NONE};
+#ifdef MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
+const int Dtls::sHashes[] = {MBEDTLS_MD_NONE};
+#endif
+
 Dtls::Dtls(Instance &aInstance, bool aLayerTwoSecurity)
     : InstanceLocator(aInstance)
     , mState(kStateClosed)
     , mPskLength(0)
     , mVerifyPeerCertificate(true)
-    , mTimer(aInstance, &Dtls::HandleTimer, this)
+    , mTimer(aInstance, Dtls::HandleTimer, this)
     , mTimerIntermediate(0)
     , mTimerSet(false)
     , mLayerTwoSecurity(aLayerTwoSecurity)
-    , mReceiveMessage(NULL)
-    , mConnectedHandler(NULL)
-    , mReceiveHandler(NULL)
-    , mSendHandler(NULL)
-    , mContext(NULL)
-    , mSocket(Get<Ip6::Udp>())
-    , mTransportCallback(NULL)
-    , mTransportContext(NULL)
+    , mReceiveMessage(nullptr)
+    , mConnectedHandler(nullptr)
+    , mReceiveHandler(nullptr)
+    , mContext(nullptr)
+    , mSocket(aInstance)
+    , mTransportCallback(nullptr)
+    , mTransportContext(nullptr)
     , mMessageSubType(Message::kSubTypeNone)
     , mMessageDefaultSubType(Message::kSubTypeNone)
 {
 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
-    mPreSharedKey         = NULL;
-    mPreSharedKeyIdentity = NULL;
+    mPreSharedKey         = nullptr;
+    mPreSharedKeyIdentity = nullptr;
     mPreSharedKeyIdLength = 0;
     mPreSharedKeyLength   = 0;
-#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+#endif
 
 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-    mCaChainSrc       = NULL;
+    mCaChainSrc       = nullptr;
     mCaChainLength    = 0;
-    mOwnCertSrc       = NULL;
+    mOwnCertSrc       = nullptr;
     mOwnCertLength    = 0;
-    mPrivateKeySrc    = NULL;
+    mPrivateKeySrc    = nullptr;
     mPrivateKeyLength = 0;
     memset(&mCaChain, 0, sizeof(mCaChain));
     memset(&mOwnCert, 0, sizeof(mOwnCert));
     memset(&mPrivateKey, 0, sizeof(mPrivateKey));
-#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
+#endif
 
     memset(mCipherSuites, 0, sizeof(mCipherSuites));
     memset(mPsk, 0, sizeof(mPsk));
@@ -109,7 +112,7 @@
 
 void Dtls::FreeMbedtls(void)
 {
-#ifdef MBEDTLS_SSL_COOKIE_C
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
     mbedtls_ssl_cookie_free(&mCookieCtx);
 #endif
 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
@@ -117,8 +120,8 @@
     mbedtls_x509_crt_free(&mCaChain);
     mbedtls_x509_crt_free(&mOwnCert);
     mbedtls_pk_free(&mPrivateKey);
-#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
+#endif
     mbedtls_ssl_config_free(&mConf);
     mbedtls_ssl_free(&mSsl);
 }
@@ -146,8 +149,8 @@
 
     VerifyOrExit(mState == kStateOpen, error = OT_ERROR_INVALID_STATE);
 
-    memcpy(&mPeerAddress.mPeerAddr, &aSockAddr.mAddress, sizeof(mPeerAddress.mPeerAddr));
-    mPeerAddress.mPeerPort = aSockAddr.mPort;
+    mMessageInfo.SetPeerAddr(aSockAddr.GetAddress());
+    mMessageInfo.SetPeerPort(aSockAddr.mPort);
 
     error = Setup(true);
 
@@ -174,18 +177,18 @@
 
         sockAddr.mAddress = aMessageInfo.GetPeerAddr();
         sockAddr.mPort    = aMessageInfo.GetPeerPort();
-        mSocket.Connect(sockAddr);
+        IgnoreError(mSocket.Connect(sockAddr));
 
-        mPeerAddress.SetPeerAddr(aMessageInfo.GetPeerAddr());
-        mPeerAddress.SetPeerPort(aMessageInfo.GetPeerPort());
-        mPeerAddress.SetIsHostInterface(aMessageInfo.IsHostInterface());
+        mMessageInfo.SetPeerAddr(aMessageInfo.GetPeerAddr());
+        mMessageInfo.SetPeerPort(aMessageInfo.GetPeerPort());
+        mMessageInfo.SetIsHostInterface(aMessageInfo.IsHostInterface());
 
-        if (Get<ThreadNetif>().IsUnicastAddress(aMessageInfo.GetSockAddr()))
+        if (Get<ThreadNetif>().HasUnicastAddress(aMessageInfo.GetSockAddr()))
         {
-            mPeerAddress.SetSockAddr(aMessageInfo.GetSockAddr());
+            mMessageInfo.SetSockAddr(aMessageInfo.GetSockAddr());
         }
 
-        mPeerAddress.SetSockPort(aMessageInfo.GetSockPort());
+        mMessageInfo.SetSockPort(aMessageInfo.GetSockPort());
 
         SuccessOrExit(Setup(false));
         break;
@@ -193,15 +196,16 @@
 
     default:
         // Once DTLS session is started, communicate only with a peer.
-        VerifyOrExit((mPeerAddress.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
-                     (mPeerAddress.GetPeerPort() == aMessageInfo.GetPeerPort()));
+        VerifyOrExit((mMessageInfo.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
+                         (mMessageInfo.GetPeerPort() == aMessageInfo.GetPeerPort()),
+                     OT_NOOP);
         break;
     }
 
 #ifdef MBEDTLS_SSL_SRV_C
     if (mState == MeshCoP::Dtls::kStateConnecting)
     {
-        SetClientId(mPeerAddress.GetPeerAddr().mFields.m8, sizeof(mPeerAddress.GetPeerAddr().mFields));
+        IgnoreError(SetClientId(mMessageInfo.GetPeerAddr().mFields.m8, sizeof(mMessageInfo.GetPeerAddr().mFields)));
     }
 #endif
 
@@ -217,7 +221,7 @@
     Ip6::SockAddr sockaddr;
 
     VerifyOrExit(mState == kStateOpen, error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(mTransportCallback == NULL, error = OT_ERROR_ALREADY);
+    VerifyOrExit(mTransportCallback == nullptr, error = OT_ERROR_ALREADY);
 
     sockaddr.mPort = aPort;
     SuccessOrExit(error = mSocket.Bind(sockaddr));
@@ -232,7 +236,7 @@
 
     VerifyOrExit(mState == kStateOpen, error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(!mSocket.IsBound(), error = OT_ERROR_ALREADY);
-    VerifyOrExit(mTransportCallback == NULL, error = OT_ERROR_ALREADY);
+    VerifyOrExit(mTransportCallback == nullptr, error = OT_ERROR_ALREADY);
 
     mTransportCallback = aCallback;
     mTransportContext  = aContext;
@@ -257,12 +261,15 @@
     mbedtls_x509_crt_init(&mCaChain);
     mbedtls_x509_crt_init(&mOwnCert);
     mbedtls_pk_init(&mPrivateKey);
-#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
+#endif
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
+    mbedtls_ssl_cookie_init(&mCookieCtx);
+#endif
 
     rval = mbedtls_ssl_config_defaults(&mConf, aClient ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
                                        MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT);
-    VerifyOrExit(rval == 0);
+    VerifyOrExit(rval == 0, OT_NOOP);
 
 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
     if (mVerifyPeerCertificate && mCipherSuites[0] == MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8)
@@ -275,34 +282,39 @@
     }
 #else
     OT_UNUSED_VARIABLE(mVerifyPeerCertificate);
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
 
     mbedtls_ssl_conf_rng(&mConf, mbedtls_ctr_drbg_random, Random::Crypto::MbedTlsContextGet());
     mbedtls_ssl_conf_min_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
     mbedtls_ssl_conf_max_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
 
-    assert(mCipherSuites[1] == 0);
+    OT_ASSERT(mCipherSuites[1] == 0);
     mbedtls_ssl_conf_ciphersuites(&mConf, mCipherSuites);
+    if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
+    {
+        mbedtls_ssl_conf_curves(&mConf, sCurves);
+#ifdef MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
+        mbedtls_ssl_conf_sig_hashes(&mConf, sHashes);
+#endif
+    }
     mbedtls_ssl_conf_export_keys_cb(&mConf, HandleMbedtlsExportKeys, this);
     mbedtls_ssl_conf_handshake_timeout(&mConf, 8000, 60000);
     mbedtls_ssl_conf_dbg(&mConf, HandleMbedtlsDebug, this);
 
-#ifdef MBEDTLS_SSL_SRV_C
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
     if (!aClient)
     {
-        mbedtls_ssl_cookie_init(&mCookieCtx);
-
         rval = mbedtls_ssl_cookie_setup(&mCookieCtx, mbedtls_ctr_drbg_random, Random::Crypto::MbedTlsContextGet());
-        VerifyOrExit(rval == 0);
+        VerifyOrExit(rval == 0, OT_NOOP);
 
         mbedtls_ssl_conf_dtls_cookies(&mConf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &mCookieCtx);
     }
 #endif
 
     rval = mbedtls_ssl_setup(&mSsl, &mConf);
-    VerifyOrExit(rval == 0);
+    VerifyOrExit(rval == 0, OT_NOOP);
 
-    mbedtls_ssl_set_bio(&mSsl, this, &Dtls::HandleMbedtlsTransmit, HandleMbedtlsReceive, NULL);
+    mbedtls_ssl_set_bio(&mSsl, this, &Dtls::HandleMbedtlsTransmit, HandleMbedtlsReceive, nullptr);
     mbedtls_ssl_set_timer_cb(&mSsl, this, &Dtls::HandleMbedtlsSetTimer, HandleMbedtlsGetTimer);
 
     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
@@ -314,10 +326,10 @@
     {
         rval = SetApplicationCoapSecureKeys();
     }
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
-    VerifyOrExit(rval == 0);
+#endif
+    VerifyOrExit(rval == 0, OT_NOOP);
 
-    mReceiveMessage = NULL;
+    mReceiveMessage = nullptr;
     mMessageSubType = Message::kSubTypeNone;
     mState          = kStateConnecting;
 
@@ -330,7 +342,7 @@
     {
         otLogInfoCoap("Application Coap Secure DTLS started");
     }
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
 
     mState = kStateConnecting;
 
@@ -355,34 +367,34 @@
     {
     case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-        if (mCaChainSrc != NULL)
+        if (mCaChainSrc != nullptr)
         {
             rval = mbedtls_x509_crt_parse(&mCaChain, static_cast<const unsigned char *>(mCaChainSrc),
                                           static_cast<size_t>(mCaChainLength));
-            VerifyOrExit(rval == 0);
-            mbedtls_ssl_conf_ca_chain(&mConf, &mCaChain, NULL);
+            VerifyOrExit(rval == 0, OT_NOOP);
+            mbedtls_ssl_conf_ca_chain(&mConf, &mCaChain, nullptr);
         }
 
-        if (mOwnCertSrc != NULL && mPrivateKeySrc != NULL)
+        if (mOwnCertSrc != nullptr && mPrivateKeySrc != nullptr)
         {
             rval = mbedtls_x509_crt_parse(&mOwnCert, static_cast<const unsigned char *>(mOwnCertSrc),
                                           static_cast<size_t>(mOwnCertLength));
-            VerifyOrExit(rval == 0);
+            VerifyOrExit(rval == 0, OT_NOOP);
             rval = mbedtls_pk_parse_key(&mPrivateKey, static_cast<const unsigned char *>(mPrivateKeySrc),
-                                        static_cast<size_t>(mPrivateKeyLength), NULL, 0);
-            VerifyOrExit(rval == 0);
+                                        static_cast<size_t>(mPrivateKeyLength), nullptr, 0);
+            VerifyOrExit(rval == 0, OT_NOOP);
             rval = mbedtls_ssl_conf_own_cert(&mConf, &mOwnCert, &mPrivateKey);
-            VerifyOrExit(rval == 0);
+            VerifyOrExit(rval == 0, OT_NOOP);
         }
-#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+#endif
         break;
 
     case MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8:
 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
         rval = mbedtls_ssl_conf_psk(&mConf, static_cast<const unsigned char *>(mPreSharedKey), mPreSharedKeyLength,
                                     static_cast<const unsigned char *>(mPreSharedKeyIdentity), mPreSharedKeyIdLength);
-        VerifyOrExit(rval == 0);
-#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+        VerifyOrExit(rval == 0, OT_NOOP);
+#endif
         break;
 
     default:
@@ -396,11 +408,6 @@
     return rval;
 }
 
-void Dtls::SetSslAuthMode(bool aVerifyPeerCertificate)
-{
-    mVerifyPeerCertificate = aVerifyPeerCertificate;
-}
-
 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 
 void Dtls::Close(void)
@@ -408,24 +415,24 @@
     Disconnect();
 
     mState             = kStateClosed;
-    mTransportCallback = NULL;
-    mTransportContext  = NULL;
+    mTransportCallback = nullptr;
+    mTransportContext  = nullptr;
     mTimerSet          = false;
 
-    mSocket.Close();
+    IgnoreError(mSocket.Close());
     mTimer.Stop();
 }
 
 void Dtls::Disconnect(void)
 {
-    VerifyOrExit(mState == kStateConnecting || mState == kStateConnected);
+    VerifyOrExit(mState == kStateConnecting || mState == kStateConnected, OT_NOOP);
 
     mbedtls_ssl_close_notify(&mSsl);
     mState = kStateCloseNotify;
     mTimer.Start(kGuardTimeNewConnectionMilli);
 
-    new (&mPeerAddress) Ip6::MessageInfo();
-    mSocket.Connect(Ip6::SockAddr());
+    mMessageInfo.Clear();
+    IgnoreError(mSocket.Connect(Ip6::SockAddr()));
 
     FreeMbedtls();
 
@@ -456,11 +463,11 @@
                           const uint8_t *aPrivateKey,
                           uint32_t       aPrivateKeyLength)
 {
-    assert(aX509CertLength > 0);
-    assert(aX509Certificate != NULL);
+    OT_ASSERT(aX509CertLength > 0);
+    OT_ASSERT(aX509Certificate != nullptr);
 
-    assert(aPrivateKeyLength > 0);
-    assert(aPrivateKey != NULL);
+    OT_ASSERT(aPrivateKeyLength > 0);
+    OT_ASSERT(aPrivateKey != nullptr);
 
     mOwnCertSrc       = aX509Certificate;
     mOwnCertLength    = aX509CertLength;
@@ -473,8 +480,8 @@
 
 void Dtls::SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength)
 {
-    assert(aX509CaCertChainLength > 0);
-    assert(aX509CaCertificateChain != NULL);
+    OT_ASSERT(aX509CaCertChainLength > 0);
+    OT_ASSERT(aX509CaCertificateChain != nullptr);
 
     mCaChainSrc    = aX509CaCertificateChain;
     mCaChainLength = aX509CaCertChainLength;
@@ -483,13 +490,12 @@
 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 
 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
-
 void Dtls::SetPreSharedKey(const uint8_t *aPsk, uint16_t aPskLength, const uint8_t *aPskIdentity, uint16_t aPskIdLength)
 {
-    assert(aPsk != NULL);
-    assert(aPskIdentity != NULL);
-    assert(aPskLength > 0);
-    assert(aPskIdLength > 0);
+    OT_ASSERT(aPsk != nullptr);
+    OT_ASSERT(aPskIdentity != nullptr);
+    OT_ASSERT(aPskLength > 0);
+    OT_ASSERT(aPskIdLength > 0);
 
     mPreSharedKey         = aPsk;
     mPreSharedKeyLength   = aPskLength;
@@ -499,7 +505,7 @@
     mCipherSuites[0] = MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8;
     mCipherSuites[1] = 0;
 }
-#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+#endif
 
 #ifdef MBEDTLS_BASE64_C
 
@@ -517,7 +523,7 @@
     return error;
 }
 
-#endif // MBEDTLS_BASE64_C
+#endif
 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 
 #ifdef MBEDTLS_SSL_SRV_C
@@ -557,7 +563,7 @@
 
     Process();
 
-    mReceiveMessage = NULL;
+    mReceiveMessage = nullptr;
 }
 
 int Dtls::HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength)
@@ -579,7 +585,7 @@
     {
         otLogDebgCoap("Dtls::ApplicationCoapSecure HandleMbedtlsTransmit");
     }
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
 
     error = HandleDtlsSend(aBuf, static_cast<uint16_t>(aLength), mMessageSubType);
 
@@ -623,9 +629,9 @@
     {
         otLogDebgCoap("Dtls:: ApplicationCoapSecure HandleMbedtlsReceive");
     }
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
 
-    VerifyOrExit(mReceiveMessage != NULL && (rval = mReceiveMessage->GetLength() - mReceiveMessage->GetOffset()) > 0,
+    VerifyOrExit(mReceiveMessage != nullptr && (rval = mReceiveMessage->GetLength() - mReceiveMessage->GetOffset()) > 0,
                  rval = MBEDTLS_ERR_SSL_WANT_READ);
 
     if (aLength > static_cast<size_t>(rval))
@@ -658,7 +664,7 @@
     {
         otLogDebgCoap("Dtls:: ApplicationCoapSecure HandleMbedtlsGetTimer");
     }
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
 
     if (!mTimerSet)
     {
@@ -696,7 +702,7 @@
     {
         otLogDebgCoap("Dtls::ApplicationCoapSecure SetTimer");
     }
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
 
     if (aFinish == 0)
     {
@@ -748,7 +754,7 @@
     {
         otLogDebgCoap("ApplicationCoapSecure Generated KEK");
     }
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
     return 0;
 }
 
@@ -770,15 +776,15 @@
         mState = kStateOpen;
         mTimer.Stop();
 
-        if (mConnectedHandler != NULL)
+        if (mConnectedHandler != nullptr)
         {
             mConnectedHandler(mContext, false);
         }
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 }
 
@@ -798,7 +804,7 @@
             {
                 mState = kStateConnected;
 
-                if (mConnectedHandler != NULL)
+                if (mConnectedHandler != nullptr)
                 {
                     mConnectedHandler(mContext, true);
                 }
@@ -811,7 +817,10 @@
 
         if (rval > 0)
         {
-            mReceiveHandler(mContext, buf, static_cast<uint16_t>(rval));
+            if (mReceiveHandler != nullptr)
+            {
+                mReceiveHandler(mContext, buf, static_cast<uint16_t>(rval));
+            }
         }
         else if (rval == 0 || rval == MBEDTLS_ERR_SSL_WANT_READ || rval == MBEDTLS_ERR_SSL_WANT_WRITE)
         {
@@ -824,7 +833,7 @@
             case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
                 mbedtls_ssl_close_notify(&mSsl);
                 ExitNow(shouldDisconnect = true);
-                break;
+                OT_UNREACHABLE_CODE(break);
 
             case MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED:
                 break;
@@ -832,7 +841,7 @@
             case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
                 mbedtls_ssl_close_notify(&mSsl);
                 ExitNow(shouldDisconnect = true);
-                break;
+                OT_UNREACHABLE_CODE(break);
 
             case MBEDTLS_ERR_SSL_INVALID_MAC:
                 if (mSsl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
@@ -872,40 +881,44 @@
     }
 }
 
-void Dtls::HandleMbedtlsDebug(void *ctx, int level, const char *, int, const char *str)
+void Dtls::HandleMbedtlsDebug(void *aContext, int aLevel, const char *aFile, int aLine, const char *aStr)
 {
-    OT_UNUSED_VARIABLE(str);
+    static_cast<Dtls *>(aContext)->HandleMbedtlsDebug(aLevel, aFile, aLine, aStr);
+}
 
-    Dtls *pThis = static_cast<Dtls *>(ctx);
-    OT_UNUSED_VARIABLE(pThis);
+void Dtls::HandleMbedtlsDebug(int aLevel, const char *aFile, int aLine, const char *aStr)
+{
+    OT_UNUSED_VARIABLE(aStr);
+    OT_UNUSED_VARIABLE(aFile);
+    OT_UNUSED_VARIABLE(aLine);
 
-    switch (level)
+    switch (aLevel)
     {
     case 1:
-        otLogCritMbedTls("[%hu] %s", pThis->mSocket.GetSockName().mPort, str);
+        otLogCritMbedTls("[%hu] %s", mSocket.GetSockName().mPort, aStr);
         break;
 
     case 2:
-        otLogWarnMbedTls("[%hu] %s", pThis->mSocket.GetSockName().mPort, str);
+        otLogWarnMbedTls("[%hu] %s", mSocket.GetSockName().mPort, aStr);
         break;
 
     case 3:
-        otLogInfoMbedTls("[%hu] %s", pThis->mSocket.GetSockName().mPort, str);
+        otLogInfoMbedTls("[%hu] %s", mSocket.GetSockName().mPort, aStr);
         break;
 
     case 4:
     default:
-        otLogDebgMbedTls("[%hu] %s", pThis->mSocket.GetSockName().mPort, str);
+        otLogDebgMbedTls("[%hu] %s", mSocket.GetSockName().mPort, aStr);
         break;
     }
 }
 
-otError Dtls::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
+otError Dtls::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, Message::SubType aMessageSubType)
 {
     otError      error   = OT_ERROR_NONE;
-    ot::Message *message = NULL;
+    ot::Message *message = nullptr;
 
-    VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = mSocket.NewMessage(0)) != nullptr, error = OT_ERROR_NO_BUFS);
     message->SetSubType(aMessageSubType);
     message->SetLinkSecurityEnabled(mLayerTwoSecurity);
 
@@ -919,16 +932,16 @@
 
     if (mTransportCallback)
     {
-        SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mPeerAddress));
+        SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mMessageInfo));
     }
     else
     {
-        SuccessOrExit(error = mSocket.SendTo(*message, mPeerAddress));
+        SuccessOrExit(error = mSocket.SendTo(*message, mMessageInfo));
     }
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
diff --git a/src/core/meshcop/dtls.hpp b/src/core/meshcop/dtls.hpp
index 7100a8f..a3cc414 100644
--- a/src/core/meshcop/dtls.hpp
+++ b/src/core/meshcop/dtls.hpp
@@ -48,8 +48,8 @@
 #include <mbedtls/x509_crl.h>
 #include <mbedtls/x509_crt.h>
 #include <mbedtls/x509_csr.h>
-#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
+#endif
 
 #include "common/locator.hpp"
 #include "common/message.hpp"
@@ -69,23 +69,7 @@
 public:
     enum
     {
-        kPskMaxLength                = 32,
-        kGuardTimeNewConnectionMilli = 2000,
-#if !OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
-        kApplicationDataMaxLength = 512,
-#else
-        kApplicationDataMaxLength = OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH,
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
-    };
-
-    enum State
-    {
-        kStateClosed = 0,
-        kStateOpen,
-        kStateInitializing,
-        kStateConnecting,
-        kStateConnected,
-        kStateCloseNotify,
+        kPskMaxLength = 32, ///< Maximum PSK length.
     };
 
     /**
@@ -127,17 +111,6 @@
     typedef otError (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
     /**
-     * This function pointer is called when data is ready to transmit for the DTLS session.
-     *
-     * @param[in]  aContext         A pointer to application-specific context.
-     * @param[in]  aBuf             A pointer to the transmit data buffer.
-     * @param[in]  aLength          Number of bytes in the transmit data buffer.
-     * @param[in]  aMessageSubtype  A message sub type information for the sender.
-     *
-     */
-    typedef otError (*SendHandler)(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
-
-    /**
      * This method opens the DTLS socket.
      *
      * @param[in]  aReceiveHandler      A pointer to a function that is called to receive DTLS payload.
@@ -156,7 +129,7 @@
      * @param[in]  aPort              The port to bind.
      *
      * @retval OT_ERROR_NONE           Successfully bound the DTLS socket.
-     * @retval OT_ERROR_INVALID_STATE  The DTLS service is not in state kStateOpen.
+     * @retval OT_ERROR_INVALID_STATE  The DTLS socket is not open.
      * @retval OT_ERROR_ALREADY        Already bound.
      *
      */
@@ -169,7 +142,7 @@
      * @param[in]  aContext   A pointer to arbitrary context information.
      *
      * @retval OT_ERROR_NONE           Successfully bound the DTLS socket.
-     * @retval OT_ERROR_INVALID_STATE  The DTLS service is not in state kStateOpen.
+     * @retval OT_ERROR_INVALID_STATE  The DTLS socket is not open.
      * @retval OT_ERROR_ALREADY        Already bound.
      *
      */
@@ -185,7 +158,7 @@
      * @param[in]  aSockAddr               A reference to the remote sockaddr.
      *
      * @retval OT_ERROR_NONE           Successfully started DTLS handshake.
-     * @retval OT_ERROR_INVALID_STATE  The DTLS service is not in state kStateOpen.
+     * @retval OT_ERROR_INVALID_STATE  The DTLS socket is not open.
      *
      */
     otError Connect(const Ip6::SockAddr &aSockAddr);
@@ -193,8 +166,6 @@
     /**
      * This method indicates whether or not the DTLS session is active.
      *
-     * In other words, the state is kStateConnecting, kStateConnected, or kStateCloseNotify.
-     *
      * @retval TRUE  If DTLS session is active.
      * @retval FALSE If DTLS session is not active.
      *
@@ -204,8 +175,6 @@
     /**
      * This method indicates whether or not the DTLS session is connected.
      *
-     * In other words, the state is kStateConnected.
-     *
      * @retval TRUE   The DTLS session is connected.
      * @retval FALSE  The DTLS session is not connected.
      *
@@ -225,18 +194,6 @@
     void Close(void);
 
     /**
-     * This method returns the DTLS connection state.
-     *
-     * @retval kStateClosed       The UDP socket closed.
-     * @retval kStateOpen         The UDP socket is open.
-     * @retval kStateConnecting   The DTLS service is establishing a connection.
-     * @retval kStateConnected    The DTLS service has a connection established.
-     * @retval kStateCloseNotify  The DTLS service is closing a connection.
-     *
-     */
-    State GetState(void) const { return mState; }
-
-    /**
      * This method sets the PSK.
      *
      * @param[in]  aPsk  A pointer to the PSK.
@@ -265,7 +222,7 @@
      */
     void SetPreSharedKey(const uint8_t *aPsk, uint16_t aPskLength, const uint8_t *aPskIdentity, uint16_t aPskIdLength);
 
-#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+#endif
 
 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
     /**
@@ -313,7 +270,7 @@
      *
      */
     otError GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize);
-#endif // MBEDTLS_BASE64_C
+#endif
 
     /**
      * This method set the authentication mode for a dtls connection.
@@ -324,7 +281,7 @@
      * @param[in]  aVerifyPeerCertificate  true, if the peer certificate should verify.
      *
      */
-    void SetSslAuthMode(bool aVerifyPeerCertificate);
+    void SetSslAuthMode(bool aVerifyPeerCertificate) { mVerifyPeerCertificate = aVerifyPeerCertificate; }
 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 
 #ifdef MBEDTLS_SSL_SRV_C
@@ -367,7 +324,7 @@
      * @param[in]  aMessageSubType  The default message sub-type.
      *
      */
-    void SetDefaultMessageSubType(uint8_t aMessageSubType) { mMessageDefaultSubType = aMessageSubType; }
+    void SetDefaultMessageSubType(Message::SubType aMessageSubType) { mMessageDefaultSubType = aMessageSubType; }
 
     /**
      * This method returns the DTLS session's peer address.
@@ -375,11 +332,31 @@
      * @return DTLS session's message info.
      *
      */
-    const Ip6::MessageInfo &GetPeerAddress(void) const { return mPeerAddress; }
+    const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
 
     void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
 private:
+    enum State : uint8_t
+    {
+        kStateClosed,       // UDP socket is closed.
+        kStateOpen,         // UDP socket is open.
+        kStateInitializing, // The DTLS service is initializing.
+        kStateConnecting,   // The DTLS service is establishing a connection.
+        kStateConnected,    // The DTLS service has a connection established.
+        kStateCloseNotify,  // The DTLS service is closing a connection.
+    };
+
+    enum
+    {
+        kGuardTimeNewConnectionMilli = 2000,
+#if !OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+        kApplicationDataMaxLength = 1152,
+#else
+        kApplicationDataMaxLength = OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH,
+#endif
+    };
+
     void    FreeMbedtls(void);
     otError Setup(bool aClient);
 
@@ -391,9 +368,10 @@
      *
      */
     int SetApplicationCoapSecureKeys(void);
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
 
-    static void HandleMbedtlsDebug(void *ctx, int level, const char *file, int line, const char *str);
+    static void HandleMbedtlsDebug(void *aContext, int aLevel, const char *aFile, int aLine, const char *aStr);
+    void        HandleMbedtlsDebug(int aLevel, const char *aFile, int aLine, const char *aStr);
 
     static int HandleMbedtlsGetTimer(void *aContext);
     int        HandleMbedtlsGetTimer(void);
@@ -425,10 +403,7 @@
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
 
     void    HandleDtlsReceive(const uint8_t *aBuf, uint16_t aLength);
-    otError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
-
-    static void HandleUdpTransmit(Tasklet &aTasklet);
-    void        HandleUdpTransmit(void);
+    otError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, Message::SubType aMessageSubType);
 
     void Process(void);
 
@@ -438,9 +413,13 @@
     uint8_t mPsk[kPskMaxLength];
     uint8_t mPskLength;
 
+    static const mbedtls_ecp_group_id sCurves[];
+#ifdef MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
+    static const int sHashes[];
+#endif
+
 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-
     const uint8_t *    mCaChainSrc;
     uint32_t           mCaChainLength;
     const uint8_t *    mOwnCertSrc;
@@ -450,15 +429,14 @@
     mbedtls_x509_crt   mCaChain;
     mbedtls_x509_crt   mOwnCert;
     mbedtls_pk_context mPrivateKey;
-#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-
+#endif
 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
     const uint8_t *mPreSharedKey;
     const uint8_t *mPreSharedKeyIdentity;
     uint16_t       mPreSharedKeyLength;
     uint16_t       mPreSharedKeyIdLength;
-#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
-#endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#endif
+#endif
 
     bool mVerifyPeerCertificate;
 
@@ -480,17 +458,16 @@
 
     ConnectedHandler mConnectedHandler;
     ReceiveHandler   mReceiveHandler;
-    SendHandler      mSendHandler;
     void *           mContext;
 
-    Ip6::MessageInfo mPeerAddress;
-    Ip6::UdpSocket   mSocket;
+    Ip6::MessageInfo mMessageInfo;
+    Ip6::Udp::Socket mSocket;
 
     TransportCallback mTransportCallback;
     void *            mTransportContext;
 
-    uint8_t mMessageSubType;
-    uint8_t mMessageDefaultSubType;
+    Message::SubType mMessageSubType;
+    Message::SubType mMessageDefaultSubType;
 };
 
 } // namespace MeshCoP
diff --git a/src/core/meshcop/energy_scan_client.cpp b/src/core/meshcop/energy_scan_client.cpp
index d4471e2..65971d5 100644
--- a/src/core/meshcop/energy_scan_client.cpp
+++ b/src/core/meshcop/energy_scan_client.cpp
@@ -51,10 +51,10 @@
 
 EnergyScanClient::EnergyScanClient(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , mCallback(nullptr)
+    , mContext(nullptr)
     , mEnergyScan(OT_URI_PATH_ENERGY_REPORT, &EnergyScanClient::HandleReport, this)
 {
-    mContext  = NULL;
-    mCallback = NULL;
     Get<Coap::Coap>().AddResource(mEnergyScan);
 }
 
@@ -66,42 +66,29 @@
                                     otCommissionerEnergyReportCallback aCallback,
                                     void *                             aContext)
 {
-    otError                           error = OT_ERROR_NONE;
-    MeshCoP::CommissionerSessionIdTlv sessionId;
-    MeshCoP::ChannelMaskTlv           channelMask;
-    MeshCoP::CountTlv                 count;
-    MeshCoP::PeriodTlv                period;
-    MeshCoP::ScanDurationTlv          scanDuration;
-    Ip6::MessageInfo                  messageInfo;
-    Coap::Message *                   message = NULL;
+    otError                 error = OT_ERROR_NONE;
+    MeshCoP::ChannelMaskTlv channelMask;
+    Ip6::MessageInfo        messageInfo;
+    Coap::Message *         message = nullptr;
 
     VerifyOrExit(Get<MeshCoP::Commissioner>().IsActive(), error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error =
                       message->Init(aAddress.IsMulticast() ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE,
                                     OT_COAP_CODE_POST, OT_URI_PATH_ENERGY_SCAN));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    sessionId.Init();
-    sessionId.SetCommissionerSessionId(Get<MeshCoP::Commissioner>().GetSessionId());
-    SuccessOrExit(error = sessionId.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kCommissionerSessionId,
+                                               Get<MeshCoP::Commissioner>().GetSessionId()));
 
     channelMask.Init();
     channelMask.SetChannelMask(aChannelMask);
     SuccessOrExit(error = channelMask.AppendTo(*message));
 
-    count.Init();
-    count.SetCount(aCount);
-    SuccessOrExit(error = count.AppendTo(*message));
-
-    period.Init();
-    period.SetPeriod(aPeriod);
-    SuccessOrExit(error = period.AppendTo(*message));
-
-    scanDuration.Init();
-    scanDuration.SetScanDuration(aScanDuration);
-    SuccessOrExit(error = scanDuration.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, MeshCoP::Tlv::kCount, aCount));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kPeriod, aPeriod));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kScanDuration, aScanDuration));
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetPeerAddr(aAddress);
@@ -115,7 +102,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -140,16 +127,16 @@
         uint8_t                list[OPENTHREAD_CONFIG_TMF_ENERGY_SCAN_MAX_RESULTS];
     } OT_TOOL_PACKED_END energyList;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
     otLogInfoMeshCoP("received energy scan report");
 
-    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
+    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0, OT_NOOP);
 
-    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kEnergyList, sizeof(energyList), energyList.tlv));
-    VerifyOrExit(energyList.tlv.IsValid());
+    SuccessOrExit(MeshCoP::Tlv::FindTlv(aMessage, MeshCoP::Tlv::kEnergyList, sizeof(energyList), energyList.tlv));
+    VerifyOrExit(energyList.tlv.IsValid(), OT_NOOP);
 
-    if (mCallback != NULL)
+    if (mCallback != nullptr)
     {
         mCallback(mask, energyList.list, energyList.tlv.GetLength(), mContext);
     }
diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp
index 0f62300..e668e6d 100644
--- a/src/core/meshcop/joiner.cpp
+++ b/src/core/meshcop/joiner.cpp
@@ -41,10 +41,12 @@
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
 #include "common/logging.hpp"
+#include "common/string.hpp"
 #include "meshcop/meshcop.hpp"
 #include "radio/radio.hpp"
 #include "thread/thread_netif.hpp"
 #include "thread/thread_uri_paths.hpp"
+#include "utils/otns.hpp"
 
 #if OPENTHREAD_CONFIG_JOINER_ENABLE
 
@@ -55,31 +57,71 @@
 
 Joiner::Joiner(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , mId()
+    , mDiscerner()
     , mState(OT_JOINER_STATE_IDLE)
-    , mCallback(NULL)
-    , mContext(NULL)
+    , mCallback(nullptr)
+    , mContext(nullptr)
     , mJoinerRouterIndex(0)
-    , mFinalizeMessage(NULL)
-    , mTimer(aInstance, &Joiner::HandleTimer, this)
+    , mFinalizeMessage(nullptr)
+    , mTimer(aInstance, Joiner::HandleTimer, this)
     , mJoinerEntrust(OT_URI_PATH_JOINER_ENTRUST, &Joiner::HandleJoinerEntrust, this)
 {
+    SetIdFromIeeeEui64();
+    mDiscerner.Clear();
     memset(mJoinerRouters, 0, sizeof(mJoinerRouters));
     Get<Coap::Coap>().AddResource(mJoinerEntrust);
 }
 
-void Joiner::GetJoinerId(Mac::ExtAddress &aJoinerId) const
+void Joiner::SetIdFromIeeeEui64(void)
 {
-    Get<Radio>().GetIeeeEui64(aJoinerId);
-    ComputeJoinerId(aJoinerId, aJoinerId);
+    Mac::ExtAddress eui64;
+
+    Get<Radio>().GetIeeeEui64(eui64);
+    ComputeJoinerId(eui64, mId);
+}
+
+const JoinerDiscerner *Joiner::GetDiscerner(void) const
+{
+    return mDiscerner.IsEmpty() ? nullptr : &mDiscerner;
+}
+
+otError Joiner::SetDiscerner(const JoinerDiscerner &aDiscerner)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(aDiscerner.IsValid(), error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(mState == OT_JOINER_STATE_IDLE, error = OT_ERROR_INVALID_STATE);
+
+    mDiscerner = aDiscerner;
+    mDiscerner.GenerateJoinerId(mId);
+
+exit:
+    return error;
+}
+
+otError Joiner::ClearDiscerner(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mState == OT_JOINER_STATE_IDLE, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(!mDiscerner.IsEmpty(), OT_NOOP);
+
+    mDiscerner.Clear();
+    SetIdFromIeeeEui64();
+
+exit:
+    return error;
 }
 
 void Joiner::SetState(otJoinerState aState)
 {
-    VerifyOrExit(aState != mState);
+    otJoinerState oldState = mState;
+    OT_UNUSED_VARIABLE(oldState);
 
-    otLogInfoMeshCoP("JoinerState: %s -> %s", JoinerStateToString(mState), JoinerStateToString(aState));
-    mState = aState;
+    SuccessOrExit(Get<Notifier>().Update(mState, aState, kEventJoinerStateChanged));
 
+    otLogInfoMeshCoP("JoinerState: %s -> %s", JoinerStateToString(oldState), JoinerStateToString(aState));
 exit:
     return;
 }
@@ -93,21 +135,26 @@
                       otJoinerCallback aCallback,
                       void *           aContext)
 {
-    otError         error;
-    Mac::ExtAddress joinerId;
+    otError                      error;
+    JoinerPskd                   joinerPskd;
+    Mac::ExtAddress              randomAddress;
+    SteeringData::HashBitIndexes filterIndexes;
 
     otLogInfoMeshCoP("Joiner starting");
 
     VerifyOrExit(mState == OT_JOINER_STATE_IDLE, error = OT_ERROR_BUSY);
+    VerifyOrExit(Get<ThreadNetif>().IsUp() && Get<Mle::Mle>().GetRole() == Mle::kRoleDisabled,
+                 error = OT_ERROR_INVALID_STATE);
 
-    // Use extended address based on factory-assigned IEEE EUI-64
-    GetJoinerId(joinerId);
-    Get<Mac::Mac>().SetExtAddress(joinerId);
+    SuccessOrExit(error = joinerPskd.SetFrom(aPskd));
+
+    // Use random-generated extended address.
+    randomAddress.GenerateRandom();
+    Get<Mac::Mac>().SetExtAddress(randomAddress);
     Get<Mle::MleRouter>().UpdateLinkLocalAddress();
 
     SuccessOrExit(error = Get<Coap::CoapSecure>().Start(kJoinerUdpPort));
-    SuccessOrExit(error = Get<Coap::CoapSecure>().SetPsk(reinterpret_cast<const uint8_t *>(aPskd),
-                                                         static_cast<uint8_t>(strlen(aPskd))));
+    Get<Coap::CoapSecure>().SetPsk(joinerPskd);
 
     for (JoinerRouter *router = &mJoinerRouters[0]; router < OT_ARRAY_END(mJoinerRouters); router++)
     {
@@ -117,9 +164,18 @@
     SuccessOrExit(error = PrepareJoinerFinalizeMessage(aProvisioningUrl, aVendorName, aVendorModel, aVendorSwVersion,
                                                        aVendorData));
 
-    SuccessOrExit(error = Get<Mle::MleRouter>().Discover(Mac::ChannelMask(0), Get<Mac::Mac>().GetPanId(),
-                                                         /* aJoiner */ true, /* aEnableFiltering */ true,
-                                                         HandleDiscoverResult, this));
+    if (!mDiscerner.IsEmpty())
+    {
+        SteeringData::CalculateHashBitIndexes(mDiscerner, filterIndexes);
+    }
+    else
+    {
+        SteeringData::CalculateHashBitIndexes(mId, filterIndexes);
+    }
+
+    SuccessOrExit(error = Get<Mle::DiscoverScanner>().Discover(Mac::ChannelMask(0), Get<Mac::Mac>().GetPanId(),
+                                                               /* aJoiner */ true, /* aEnableFiltering */ true,
+                                                               &filterIndexes, HandleDiscoverResult, this));
     mCallback = aCallback;
     mContext  = aContext;
 
@@ -128,7 +184,7 @@
 exit:
     if (error != OT_ERROR_NONE)
     {
-        otLogInfoMeshCoP("Error %s while starting joiner", otThreadErrorToString(error));
+        otLogWarnMeshCoP("Failed to start joiner: %s", otThreadErrorToString(error));
         FreeJoinerFinalizeMessage();
     }
 
@@ -139,8 +195,8 @@
 {
     otLogInfoMeshCoP("Joiner stopped");
 
-    // Callback is set to `NULL` to skip calling it from `Finish()`
-    mCallback = NULL;
+    // Callback is set to `nullptr` to skip calling it from `Finish()`
+    mCallback = nullptr;
     Finish(OT_ERROR_ABORT);
 }
 
@@ -156,7 +212,7 @@
     case OT_JOINER_STATE_ENTRUST:
     case OT_JOINER_STATE_JOINED:
         Get<Coap::CoapSecure>().Disconnect();
-        Get<Ip6::Filter>().RemoveUnsecurePort(kJoinerUdpPort);
+        IgnoreError(Get<Ip6::Filter>().RemoveUnsecurePort(kJoinerUdpPort));
         mTimer.Stop();
 
         // Fall through
@@ -220,14 +276,17 @@
 
 void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
 {
-    VerifyOrExit(mState == OT_JOINER_STATE_DISCOVER);
+    VerifyOrExit(mState == OT_JOINER_STATE_DISCOVER, OT_NOOP);
 
-    if (aResult != NULL)
+    if (aResult != nullptr)
     {
         SaveDiscoveredJoinerRouter(*aResult);
     }
     else
     {
+        Get<Mac::Mac>().SetExtAddress(mId);
+        Get<Mle::MleRouter>().UpdateLinkLocalAddress();
+
         mJoinerRouterIndex = 0;
         TryNextJoinerRouter(OT_ERROR_NONE);
     }
@@ -239,19 +298,11 @@
 void Joiner::SaveDiscoveredJoinerRouter(const otActiveScanResult &aResult)
 {
     uint8_t       priority;
-    bool          doesAllowAny = true;
-    JoinerRouter *end          = OT_ARRAY_END(mJoinerRouters);
+    bool          doesAllowAny;
+    JoinerRouter *end = OT_ARRAY_END(mJoinerRouters);
     JoinerRouter *entry;
 
-    // Check whether Steering Data allows any joiner (it is all 0xff).
-    for (uint8_t i = 0; i < aResult.mSteeringData.mLength; i++)
-    {
-        if (aResult.mSteeringData.m8[i] != 0xff)
-        {
-            doesAllowAny = false;
-            break;
-        }
-    }
+    doesAllowAny = static_cast<const SteeringData &>(aResult.mSteeringData).PermitsAllJoiners();
 
     otLogInfoMeshCoP("Joiner discover network: %s, pan:0x%04x, port:%d, chan:%d, rssi:%d, allow-any:%s",
                      static_cast<const Mac::ExtAddress &>(aResult.mExtAddress).ToString().AsCString(), aResult.mPanId,
@@ -270,7 +321,7 @@
         }
     }
 
-    VerifyOrExit(entry < end);
+    VerifyOrExit(entry < end, OT_NOOP);
 
     // Shift elements in array to make room for the new one.
     memmove(entry + 1, entry,
@@ -337,8 +388,7 @@
     SuccessOrExit(error = Get<Mac::Mac>().SetPanChannel(aRouter.mChannel));
     SuccessOrExit(error = Get<Ip6::Filter>().AddUnsecurePort(kJoinerUdpPort));
 
-    sockaddr.GetAddress().mFields.m16[0] = HostSwap16(0xfe80);
-    sockaddr.GetAddress().SetIid(aRouter.mExtAddr);
+    sockaddr.GetAddress().SetToLinkLocalAddress(aRouter.mExtAddr);
     sockaddr.mPort = aRouter.mJoinerUdpPort;
 
     SuccessOrExit(error = Get<Coap::CoapSecure>().Connect(sockaddr, Joiner::HandleSecureCoapClientConnect, this));
@@ -349,7 +399,7 @@
 
     if (error != OT_ERROR_NONE)
     {
-        otLogInfoMeshCoP("Error %s while joiner trying to connect", otThreadErrorToString(error));
+        otLogWarnMeshCoP("Failed to start secure joiner connection: %s", otThreadErrorToString(error));
     }
 
     return error;
@@ -362,7 +412,7 @@
 
 void Joiner::HandleSecureCoapClientConnect(bool aConnected)
 {
-    VerifyOrExit(mState == OT_JOINER_STATE_CONNECT);
+    VerifyOrExit(mState == OT_JOINER_STATE_CONNECT, OT_NOOP);
 
     if (aConnected)
     {
@@ -386,23 +436,20 @@
                                              const char *aVendorData)
 {
     otError               error = OT_ERROR_NONE;
-    StateTlv              stateTlv;
     VendorNameTlv         vendorNameTlv;
     VendorModelTlv        vendorModelTlv;
     VendorSwVersionTlv    vendorSwVersionTlv;
     VendorStackVersionTlv vendorStackVersionTlv;
     ProvisioningUrlTlv    provisioningUrlTlv;
 
-    VerifyOrExit((mFinalizeMessage = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((mFinalizeMessage = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     mFinalizeMessage->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
     SuccessOrExit(error = mFinalizeMessage->AppendUriPathOptions(OT_URI_PATH_JOINER_FINALIZE));
     SuccessOrExit(error = mFinalizeMessage->SetPayloadMarker());
     mFinalizeMessage->SetOffset(mFinalizeMessage->GetLength());
 
-    stateTlv.Init();
-    stateTlv.SetState(MeshCoP::StateTlv::kAccept);
-    SuccessOrExit(error = stateTlv.AppendTo(*mFinalizeMessage));
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*mFinalizeMessage, Tlv::kState, StateTlv::kAccept));
 
     vendorNameTlv.Init();
     vendorNameTlv.SetVendorName(aVendorName);
@@ -423,7 +470,7 @@
     vendorStackVersionTlv.SetRevision(OPENTHREAD_CONFIG_STACK_VERSION_REV);
     SuccessOrExit(error = vendorStackVersionTlv.AppendTo(*mFinalizeMessage));
 
-    if (aVendorData != NULL)
+    if (aVendorData != nullptr)
     {
         VendorDataTlv vendorDataTlv;
         vendorDataTlv.Init();
@@ -450,10 +497,10 @@
 
 void Joiner::FreeJoinerFinalizeMessage(void)
 {
-    VerifyOrExit(mState == OT_JOINER_STATE_IDLE && mFinalizeMessage != NULL);
+    VerifyOrExit(mState == OT_JOINER_STATE_IDLE && mFinalizeMessage != nullptr, OT_NOOP);
 
     mFinalizeMessage->Free();
-    mFinalizeMessage = NULL;
+    mFinalizeMessage = nullptr;
 
 exit:
     return;
@@ -461,14 +508,14 @@
 
 void Joiner::SendJoinerFinalize(void)
 {
-    assert(mFinalizeMessage != NULL);
+    OT_ASSERT(mFinalizeMessage != nullptr);
 
 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
     LogCertMessage("[THCI] direction=send | type=JOIN_FIN.req |", *mFinalizeMessage);
 #endif
 
     SuccessOrExit(Get<Coap::CoapSecure>().SendMessage(*mFinalizeMessage, Joiner::HandleJoinerFinalizeResponse, this));
-    mFinalizeMessage = NULL;
+    mFinalizeMessage = nullptr;
 
     otLogInfoMeshCoP("Joiner sent finalize");
 
@@ -491,18 +538,18 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    StateTlv state;
+    uint8_t state;
 
-    VerifyOrExit(mState == OT_JOINER_STATE_CONNECTED && aResult == OT_ERROR_NONE &&
-                 aMessage.GetType() == OT_COAP_TYPE_ACKNOWLEDGMENT && aMessage.GetCode() == OT_COAP_CODE_CHANGED);
+    VerifyOrExit(mState == OT_JOINER_STATE_CONNECTED && aResult == OT_ERROR_NONE && aMessage.IsAck() &&
+                     aMessage.GetCode() == OT_COAP_CODE_CHANGED,
+                 OT_NOOP);
 
-    SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kState, sizeof(state), state));
-    VerifyOrExit(state.IsValid());
+    SuccessOrExit(Tlv::FindUint8Tlv(aMessage, Tlv::kState, state));
 
     SetState(OT_JOINER_STATE_ENTRUST);
     mTimer.Start(kReponseTimeout);
 
-    otLogInfoMeshCoP("Joiner received finalize response %d", static_cast<uint8_t>(state.GetState()));
+    otLogInfoMeshCoP("Joiner received finalize response %d", state);
 
 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
     LogCertMessage("[THCI] direction=recv | type=JOIN_FIN.rsp |", aMessage);
@@ -510,7 +557,7 @@
 
 exit:
     Get<Coap::CoapSecure>().Disconnect();
-    Get<Ip6::Filter>().RemoveUnsecurePort(kJoinerUdpPort);
+    IgnoreError(Get<Ip6::Filter>().RemoveUnsecurePort(kJoinerUdpPort));
 }
 
 void Joiner::HandleJoinerEntrust(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -522,22 +569,18 @@
 void Joiner::HandleJoinerEntrust(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError              error;
-    NetworkMasterKeyTlv  masterKey;
     otOperationalDataset dataset;
 
-    VerifyOrExit(mState == OT_JOINER_STATE_ENTRUST && aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE &&
+    VerifyOrExit(mState == OT_JOINER_STATE_ENTRUST && aMessage.IsConfirmable() &&
                      aMessage.GetCode() == OT_COAP_CODE_POST,
                  error = OT_ERROR_DROP);
 
     otLogInfoMeshCoP("Joiner received entrust");
     otLogCertMeshCoP("[THCI] direction=recv | type=JOIN_ENT.ntf");
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkMasterKey, sizeof(masterKey), masterKey));
-    VerifyOrExit(masterKey.IsValid(), error = OT_ERROR_PARSE);
-
     memset(&dataset, 0, sizeof(dataset));
 
-    dataset.mMasterKey                      = masterKey.GetNetworkMasterKey();
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, Tlv::kNetworkMasterKey, &dataset.mMasterKey, sizeof(MasterKey)));
     dataset.mComponents.mIsMasterKeyPresent = true;
 
     dataset.mChannel                      = Get<Mac::Mac>().GetPanChannel();
@@ -546,7 +589,7 @@
     dataset.mPanId                      = Get<Mac::Mac>().GetPanId();
     dataset.mComponents.mIsPanIdPresent = true;
 
-    Get<MeshCoP::ActiveDataset>().Save(dataset);
+    IgnoreError(Get<MeshCoP::ActiveDataset>().Save(dataset));
 
     otLogInfoMeshCoP("Joiner successful!");
 
@@ -559,7 +602,7 @@
 
     if (error != OT_ERROR_NONE)
     {
-        otLogWarnMeshCoP("Error %s while processing joiner entrust", otThreadErrorToString(error));
+        otLogWarnMeshCoP("Failed to process joiner entrust: %s", otThreadErrorToString(error));
     }
 }
 
@@ -569,7 +612,7 @@
     Coap::Message *  message;
     Ip6::MessageInfo responseInfo(aRequestInfo);
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
     message->SetSubType(Message::kSubTypeJoinerEntrust);
 
@@ -583,7 +626,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -603,8 +646,8 @@
     case OT_JOINER_STATE_IDLE:
     case OT_JOINER_STATE_DISCOVER:
     case OT_JOINER_STATE_CONNECT:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
 
     case OT_JOINER_STATE_CONNECTED:
     case OT_JOINER_STATE_ENTRUST:
@@ -625,7 +668,7 @@
     Finish(error);
 }
 
-// LOCV_EXCL_START
+// LCOV_EXCL_START
 
 const char *Joiner::JoinerStateToString(otJoinerState aState)
 {
@@ -661,7 +704,7 @@
 {
     uint8_t buf[OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE];
 
-    VerifyOrExit(aMessage.GetLength() <= sizeof(buf));
+    VerifyOrExit(aMessage.GetLength() <= sizeof(buf), OT_NOOP);
     aMessage.Read(aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset(), buf);
 
     otDumpCertMeshCoP(aText, buf, aMessage.GetLength() - aMessage.GetOffset());
diff --git a/src/core/meshcop/joiner.hpp b/src/core/meshcop/joiner.hpp
index 168edb9..08bb3e7 100644
--- a/src/core/meshcop/joiner.hpp
+++ b/src/core/meshcop/joiner.hpp
@@ -46,6 +46,7 @@
 #include "common/message.hpp"
 #include "mac/mac_types.hpp"
 #include "meshcop/dtls.hpp"
+#include "meshcop/meshcop.hpp"
 #include "meshcop/meshcop_tlvs.hpp"
 
 namespace ot {
@@ -67,15 +68,17 @@
      * This method starts the Joiner service.
      *
      * @param[in]  aPskd             A pointer to the PSKd.
-     * @param[in]  aProvisioningUrl  A pointer to the Provisioning URL (may be NULL).
-     * @param[in]  aVendorName       A pointer to the Vendor Name (may be NULL).
-     * @param[in]  aVendorModel      A pointer to the Vendor Model (may be NULL).
-     * @param[in]  aVendorSwVersion  A pointer to the Vendor SW Version (may be NULL).
-     * @param[in]  aVendorData       A pointer to the Vendor Data (may be NULL).
+     * @param[in]  aProvisioningUrl  A pointer to the Provisioning URL (may be nullptr).
+     * @param[in]  aVendorName       A pointer to the Vendor Name (may be nullptr).
+     * @param[in]  aVendorModel      A pointer to the Vendor Model (may be nullptr).
+     * @param[in]  aVendorSwVersion  A pointer to the Vendor SW Version (may be nullptr).
+     * @param[in]  aVendorData       A pointer to the Vendor Data (may be nullptr).
      * @param[in]  aCallback         A pointer to a function that is called when the join operation completes.
      * @param[in]  aContext          A pointer to application-specific context.
      *
-     * @retval OT_ERROR_NONE  Successfully started the Joiner service.
+     * @retval OT_ERROR_NONE          Successfully started the Joiner service.
+     * @retval OT_ERROR_BUSY          The previous attempt is still on-going.
+     * @retval OT_ERROR_INVALID_STATE The IPv6 stack is not enabled or Thread stack is fully enabled.
      *
      */
     otError Start(const char *     aPskd,
@@ -104,10 +107,47 @@
     /**
      * This method retrieves the Joiner ID.
      *
-     * @param[out]  aJoinerId  The Joiner ID.
+     * @returns The Joiner ID.
      *
      */
-    void GetJoinerId(Mac::ExtAddress &aJoinerId) const;
+    const Mac::ExtAddress &GetId(void) const { return mId; }
+
+    /**
+     * This method gets the Jointer Discerner.
+     *
+     * @returns A pointer to the current Joiner Discerner or `nullptr` if none is set.
+     *
+     */
+    const JoinerDiscerner *GetDiscerner(void) const;
+
+    /**
+     * This method sets the Joiner Discerner.
+     *
+     * The Joiner Discerner is used to calculate the Joiner ID used during commissioning/joining process.
+     *
+     * By default (when a discerner is not provided or cleared), Joiner ID is derived as first 64 bits of the
+     * result of computing SHA-256 over factory-assigned IEEE EUI-64. Note that this is the main behavior expected by
+     * Thread specification.
+     *
+     * @param[in]   aDiscerner  A Joiner Discerner
+     *
+     * @retval OT_ERROR_NONE           The Joiner Discerner updated successfully.
+     * @retval OT_ERROR_INVALID_ARGS   @p aDiscerner is not valid (specified length is not within valid range).
+     * @retval OT_ERROR_INVALID_STATE  There is an ongoing Joining process so Joiner Discerner could not be changed.
+     *
+     */
+    otError SetDiscerner(const JoinerDiscerner &aDiscerner);
+
+    /**
+     * This method clears any previously set Joiner Discerner.
+     *
+     * When cleared, Joiner ID is derived as first 64 bits of SHA-256 of factory-assigned IEEE EUI-64.
+     *
+     * @retval OT_ERROR_NONE           The Joiner Discerner cleared and Joiner ID updated.
+     * @retval OT_ERROR_INVALID_STATE  There is an ongoing Joining process so Joiner Discerner could not be changed.
+     *
+     */
+    otError ClearDiscerner(void);
 
 private:
     enum
@@ -147,6 +187,7 @@
     static const char *JoinerStateToString(otJoinerState aState);
 
     void    SetState(otJoinerState aState);
+    void    SetIdFromIeeeEui64(void);
     void    SaveDiscoveredJoinerRouter(const otActiveScanResult &aResult);
     void    TryNextJoinerRouter(otError aPrevError);
     otError Connect(JoinerRouter &aRouter);
@@ -166,6 +207,9 @@
     void LogCertMessage(const char *aText, const Coap::Message &aMessage) const;
 #endif
 
+    Mac::ExtAddress mId;
+    JoinerDiscerner mDiscerner;
+
     otJoinerState mState;
 
     otJoinerCallback mCallback;
diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp
index eb94394..5107562 100644
--- a/src/core/meshcop/joiner_router.cpp
+++ b/src/core/meshcop/joiner_router.cpp
@@ -55,45 +55,53 @@
 
 JoinerRouter::JoinerRouter(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mSocket(aInstance.Get<Ip6::Udp>())
+    , Notifier::Receiver(aInstance, JoinerRouter::HandleNotifierEvents)
+    , mSocket(aInstance)
     , mRelayTransmit(OT_URI_PATH_RELAY_TX, &JoinerRouter::HandleRelayTransmit, this)
-    , mTimer(aInstance, &JoinerRouter::HandleTimer, this)
-    , mNotifierCallback(aInstance, &JoinerRouter::HandleStateChanged, this)
+    , mTimer(aInstance, JoinerRouter::HandleTimer, this)
     , mJoinerUdpPort(0)
     , mIsJoinerPortConfigured(false)
-    , mExpectJoinEntRsp(false)
 {
     Get<Coap::Coap>().AddResource(mRelayTransmit);
 }
 
-void JoinerRouter::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags)
+void JoinerRouter::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<JoinerRouter>().HandleStateChanged(aFlags);
+    static_cast<JoinerRouter &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
-void JoinerRouter::HandleStateChanged(otChangedFlags aFlags)
+void JoinerRouter::HandleNotifierEvents(Events aEvents)
 {
-    VerifyOrExit(Get<Mle::MleRouter>().IsFullThreadDevice());
-    VerifyOrExit(aFlags & OT_CHANGED_THREAD_NETDATA);
+    if (aEvents.Contains(kEventThreadNetdataChanged))
+    {
+        Start();
+    }
+}
+
+void JoinerRouter::Start(void)
+{
+    VerifyOrExit(Get<Mle::MleRouter>().IsFullThreadDevice(), OT_NOOP);
 
     if (Get<NetworkData::Leader>().IsJoiningEnabled())
     {
         Ip6::SockAddr sockaddr;
 
-        VerifyOrExit(!mSocket.IsBound());
+        VerifyOrExit(!mSocket.IsBound(), OT_NOOP);
 
         sockaddr.mPort = GetJoinerUdpPort();
 
-        mSocket.Open(&JoinerRouter::HandleUdpReceive, this);
-        mSocket.Bind(sockaddr);
-        Get<Ip6::Filter>().AddUnsecurePort(sockaddr.mPort);
+        IgnoreError(mSocket.Open(&JoinerRouter::HandleUdpReceive, this));
+        IgnoreError(mSocket.Bind(sockaddr));
+        IgnoreError(Get<Ip6::Filter>().AddUnsecurePort(sockaddr.mPort));
         otLogInfoMeshCoP("Joiner Router: start");
     }
     else
     {
-        Get<Ip6::Filter>().RemoveUnsecurePort(mSocket.GetSockName().mPort);
+        VerifyOrExit(mSocket.IsBound(), OT_NOOP);
 
-        mSocket.Close();
+        IgnoreError(Get<Ip6::Filter>().RemoveUnsecurePort(mSocket.GetSockName().mPort));
+
+        IgnoreError(mSocket.Close());
     }
 
 exit:
@@ -102,14 +110,14 @@
 
 uint16_t JoinerRouter::GetJoinerUdpPort(void)
 {
-    uint16_t          rval = OPENTHREAD_CONFIG_JOINER_UDP_PORT;
-    JoinerUdpPortTlv *joinerUdpPort;
+    uint16_t                rval = OPENTHREAD_CONFIG_JOINER_UDP_PORT;
+    const JoinerUdpPortTlv *joinerUdpPort;
 
     VerifyOrExit(!mIsJoinerPortConfigured, rval = mJoinerUdpPort);
 
-    joinerUdpPort =
-        static_cast<JoinerUdpPortTlv *>(Get<NetworkData::Leader>().GetCommissioningDataSubTlv(Tlv::kJoinerUdpPort));
-    VerifyOrExit(joinerUdpPort != NULL);
+    joinerUdpPort = static_cast<const JoinerUdpPortTlv *>(
+        Get<NetworkData::Leader>().GetCommissioningDataSubTlv(Tlv::kJoinerUdpPort));
+    VerifyOrExit(joinerUdpPort != nullptr, OT_NOOP);
 
     rval = joinerUdpPort->GetUdpPort();
 
@@ -121,7 +129,7 @@
 {
     mJoinerUdpPort          = aJoinerUdpPort;
     mIsJoinerPortConfigured = true;
-    HandleStateChanged(OT_CHANGED_THREAD_NETDATA);
+    Start();
 }
 
 void JoinerRouter::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -132,36 +140,26 @@
 
 void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    otError                error;
-    Coap::Message *        message = NULL;
-    Ip6::MessageInfo       messageInfo;
-    JoinerUdpPortTlv       udpPort;
-    JoinerIidTlv           iid;
-    JoinerRouterLocatorTlv rloc;
-    ExtendedTlv            tlv;
-    uint16_t               borderAgentRloc;
-    uint16_t               offset;
+    otError          error;
+    Coap::Message *  message = nullptr;
+    Ip6::MessageInfo messageInfo;
+    ExtendedTlv      tlv;
+    uint16_t         borderAgentRloc;
+    uint16_t         offset;
 
     otLogInfoMeshCoP("JoinerRouter::HandleUdpReceive");
 
     SuccessOrExit(error = GetBorderAgentRloc(Get<ThreadNetif>(), borderAgentRloc));
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_RELAY_RX));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    udpPort.Init();
-    udpPort.SetUdpPort(aMessageInfo.GetPeerPort());
-    SuccessOrExit(error = udpPort.AppendTo(*message));
-
-    iid.Init();
-    iid.SetIid(aMessageInfo.GetPeerAddr().mFields.m8 + 8);
-    SuccessOrExit(error = iid.AppendTo(*message));
-
-    rloc.Init();
-    rloc.SetJoinerRouterLocator(Get<Mle::MleRouter>().GetRloc16());
-    SuccessOrExit(error = rloc.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kJoinerUdpPort, aMessageInfo.GetPeerPort()));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kJoinerIid, &aMessageInfo.GetPeerAddr().GetIid(),
+                                         Ip6::InterfaceIdentifier::kSize));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kJoinerRouterLocator, Get<Mle::MleRouter>().GetRloc16()));
 
     tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
     tlv.SetLength(aMessage.GetLength() - aMessage.GetOffset());
@@ -172,7 +170,7 @@
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetPeerAddr(Get<Mle::MleRouter>().GetMeshLocal16());
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(borderAgentRloc);
+    messageInfo.GetPeerAddr().GetIid().SetLocator(borderAgentRloc);
     messageInfo.SetPeerPort(kCoapUdpPort);
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
@@ -181,7 +179,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -197,41 +195,36 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    otError            error;
-    JoinerUdpPortTlv   joinerPort;
-    JoinerIidTlv       joinerIid;
-    JoinerRouterKekTlv kek;
-    uint16_t           offset;
-    uint16_t           length;
-    Message *          message  = NULL;
-    otMessageSettings  settings = {false, static_cast<otMessagePriority>(kMeshCoPMessagePriority)};
-    Ip6::MessageInfo   messageInfo;
+    otError                  error;
+    uint16_t                 joinerPort;
+    Ip6::InterfaceIdentifier joinerIid;
+    Kek                      kek;
+    uint16_t                 offset;
+    uint16_t                 length;
+    Message *                message = nullptr;
+    Message::Settings        settings(Message::kNoLinkSecurity, Message::kPriorityNet);
+    Ip6::MessageInfo         messageInfo;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_NON_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST,
-                 error = OT_ERROR_DROP);
+    VerifyOrExit(aMessage.IsNonConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, error = OT_ERROR_DROP);
 
     otLogInfoMeshCoP("Received relay transmit");
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerUdpPort, sizeof(joinerPort), joinerPort));
-    VerifyOrExit(joinerPort.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kJoinerUdpPort, joinerPort));
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, Tlv::kJoinerIid, &joinerIid, sizeof(joinerIid)));
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerIid, sizeof(joinerIid), joinerIid));
-    VerifyOrExit(joinerIid.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length));
 
-    SuccessOrExit(error = Tlv::GetValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length));
-
-    VerifyOrExit((message = mSocket.NewMessage(0, &settings)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = mSocket.NewMessage(0, settings)) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->SetLength(length));
     aMessage.CopyTo(offset, 0, length, *message);
 
-    messageInfo.mPeerAddr.mFields.m16[0] = HostSwap16(0xfe80);
-    memcpy(messageInfo.mPeerAddr.mFields.m8 + 8, joinerIid.GetIid(), 8);
-    messageInfo.SetPeerPort(joinerPort.GetUdpPort());
+    messageInfo.GetPeerAddr().SetToLinkLocalAddress(joinerIid);
+    messageInfo.SetPeerPort(joinerPort);
 
     SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
 
-    if (Tlv::GetTlv(aMessage, Tlv::kJoinerRouterKek, sizeof(kek), kek) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kJoinerRouterKek, &kek, sizeof(kek)) == OT_ERROR_NONE)
     {
         otLogInfoMeshCoP("Received kek");
 
@@ -239,122 +232,45 @@
     }
 
 exit:
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
 }
 
-otError JoinerRouter::DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const JoinerRouterKekTlv &aKek)
+void JoinerRouter::DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const Kek &aKek)
 {
-    otError          error;
-    Coap::Message *  message = NULL;
-    Ip6::MessageInfo messageInfo;
-    Dataset          dataset(MeshCoP::Tlv::kActiveTimestamp);
+    otError               error   = OT_ERROR_NONE;
+    Message *             message = Get<MessagePool>().New(Message::kTypeOther, 0);
+    JoinerEntrustMetadata metadata;
 
-    NetworkMasterKeyTlv   masterKey;
-    MeshLocalPrefixTlv    meshLocalPrefix;
-    ExtendedPanIdTlv      extendedPanId;
-    NetworkNameTlv        networkName;
-    NetworkKeySequenceTlv networkKeySequence;
-    const Tlv *           tlv;
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
-    DelayedJoinEntHeader delayedMessage;
+    metadata.mMessageInfo = aMessageInfo;
+    metadata.mMessageInfo.SetPeerPort(kCoapUdpPort);
+    metadata.mSendTime = TimerMilli::GetNow() + kJoinerEntrustTxDelay;
+    metadata.mKek      = aKek;
 
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
-
-    message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
-    SuccessOrExit(error = message->AppendUriPathOptions(OT_URI_PATH_JOINER_ENTRUST));
-    SuccessOrExit(error = message->SetPayloadMarker());
-    message->SetSubType(Message::kSubTypeJoinerEntrust);
-
-    masterKey.Init();
-    masterKey.SetNetworkMasterKey(Get<KeyManager>().GetMasterKey());
-    SuccessOrExit(error = masterKey.AppendTo(*message));
-
-    meshLocalPrefix.Init();
-    meshLocalPrefix.SetMeshLocalPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
-    SuccessOrExit(error = meshLocalPrefix.AppendTo(*message));
-
-    extendedPanId.Init();
-    extendedPanId.SetExtendedPanId(Get<Mac::Mac>().GetExtendedPanId());
-    SuccessOrExit(error = extendedPanId.AppendTo(*message));
-
-    networkName.Init();
-    networkName.SetNetworkName(Get<Mac::Mac>().GetNetworkName().GetAsData());
-    SuccessOrExit(error = networkName.AppendTo(*message));
-
-    Get<ActiveDataset>().Read(dataset);
-
-    if ((tlv = dataset.Get(Tlv::kActiveTimestamp)) != NULL)
-    {
-        SuccessOrExit(error = tlv->AppendTo(*message));
-    }
-    else
-    {
-        ActiveTimestampTlv activeTimestamp;
-        activeTimestamp.Init();
-        SuccessOrExit(error = activeTimestamp.AppendTo(*message));
-    }
-
-    if ((tlv = dataset.Get(Tlv::kChannelMask)) != NULL)
-    {
-        SuccessOrExit(error = tlv->AppendTo(*message));
-    }
-    else
-    {
-        ChannelMaskBaseTlv channelMask;
-        channelMask.Init();
-        SuccessOrExit(error = channelMask.AppendTo(*message));
-    }
-
-    if ((tlv = dataset.Get(Tlv::kPskc)) != NULL)
-    {
-        SuccessOrExit(error = tlv->AppendTo(*message));
-    }
-    else
-    {
-        PskcTlv pskc;
-        pskc.Init();
-        SuccessOrExit(error = pskc.AppendTo(*message));
-    }
-
-    if ((tlv = dataset.Get(Tlv::kSecurityPolicy)) != NULL)
-    {
-        SuccessOrExit(error = tlv->AppendTo(*message));
-    }
-    else
-    {
-        SecurityPolicyTlv securityPolicy;
-        securityPolicy.Init();
-        SuccessOrExit(error = securityPolicy.AppendTo(*message));
-    }
-
-    networkKeySequence.Init();
-    networkKeySequence.SetNetworkKeySequence(Get<KeyManager>().GetCurrentKeySequence());
-    SuccessOrExit(error = networkKeySequence.AppendTo(*message));
-
-    messageInfo = aMessageInfo;
-    messageInfo.SetPeerPort(kCoapUdpPort);
-
-    delayedMessage.Init(TimerMilli::GetNow() + kDelayJoinEnt, messageInfo, aKek.GetKek());
-    SuccessOrExit(error = delayedMessage.AppendTo(*message));
+    SuccessOrExit(error = metadata.AppendTo(*message));
 
     mDelayedJoinEnts.Enqueue(*message);
 
     if (!mTimer.IsRunning())
     {
-        mTimer.Start(kDelayJoinEnt);
+        mTimer.FireAt(metadata.mSendTime);
     }
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        message->Free();
-    }
+        otLogNoteMeshCoP("Failed to schedule joiner entrust: %s", otThreadErrorToString(error));
 
-    return error;
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
 }
 
 void JoinerRouter::HandleTimer(Timer &aTimer)
@@ -369,39 +285,27 @@
 
 void JoinerRouter::SendDelayedJoinerEntrust(void)
 {
-    DelayedJoinEntHeader delayedJoinEnt;
-    Coap::Message *      message = static_cast<Coap::Message *>(mDelayedJoinEnts.GetHead());
-    Ip6::MessageInfo     messageInfo;
+    JoinerEntrustMetadata metadata;
+    Message *             message = mDelayedJoinEnts.GetHead();
 
-    VerifyOrExit(message != NULL);
-    VerifyOrExit(!mTimer.IsRunning());
+    VerifyOrExit(message != nullptr, OT_NOOP);
+    VerifyOrExit(!mTimer.IsRunning(), OT_NOOP);
 
-    delayedJoinEnt.ReadFrom(*message);
+    metadata.ReadFrom(*message);
 
-    // The message can be sent during CoAP transaction if KEK did not change (i.e. retransmission).
-    VerifyOrExit(!mExpectJoinEntRsp ||
-                 memcmp(Get<KeyManager>().GetKek(), delayedJoinEnt.GetKek(), KeyManager::kMaxKeyLength) == 0);
-
-    if (TimerMilli::GetNow() < delayedJoinEnt.GetSendTime())
+    if (TimerMilli::GetNow() < metadata.mSendTime)
     {
-        mTimer.FireAt(delayedJoinEnt.GetSendTime());
+        mTimer.FireAt(metadata.mSendTime);
     }
     else
     {
         mDelayedJoinEnts.Dequeue(*message);
+        message->Free();
 
-        // Remove the DelayedJoinEntHeader from the message.
-        DelayedJoinEntHeader::RemoveFrom(*message);
+        Get<KeyManager>().SetKek(metadata.mKek);
 
-        // Set KEK to one used for this message.
-        Get<KeyManager>().SetKek(delayedJoinEnt.GetKek());
-
-        // Send the message.
-        memcpy(&messageInfo, delayedJoinEnt.GetMessageInfo(), sizeof(messageInfo));
-
-        if (SendJoinerEntrust(*message, messageInfo) != OT_ERROR_NONE)
+        if (SendJoinerEntrust(metadata.mMessageInfo) != OT_ERROR_NONE)
         {
-            message->Free();
             mTimer.Start(0);
         }
     }
@@ -410,23 +314,119 @@
     return;
 }
 
-otError JoinerRouter::SendJoinerEntrust(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+otError JoinerRouter::SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo)
 {
-    otError error;
+    otError        error = OT_ERROR_NONE;
+    Coap::Message *message;
 
-    Get<Coap::Coap>().AbortTransaction(&JoinerRouter::HandleJoinerEntrustResponse, this);
+    message = PrepareJoinerEntrustMessage();
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
+
+    IgnoreError(Get<Coap::Coap>().AbortTransaction(&JoinerRouter::HandleJoinerEntrustResponse, this));
 
     otLogInfoMeshCoP("Sending JOIN_ENT.ntf");
-    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(aMessage, aMessageInfo,
+    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo,
                                                         &JoinerRouter::HandleJoinerEntrustResponse, this));
 
-    otLogInfoMeshCoP("Sent joiner entrust length = %d", aMessage.GetLength());
+    otLogInfoMeshCoP("Sent joiner entrust length = %d", message->GetLength());
     otLogCertMeshCoP("[THCI] direction=send | type=JOIN_ENT.ntf");
 
-    mExpectJoinEntRsp = true;
+exit:
+    if (error != OT_ERROR_NONE && message != nullptr)
+    {
+        message->Free();
+    }
+
+    return error;
+}
+
+Coap::Message *JoinerRouter::PrepareJoinerEntrustMessage(void)
+{
+    otError        error;
+    Coap::Message *message = nullptr;
+    Dataset        dataset(Dataset::kActive);
+
+    NetworkNameTlv networkName;
+    const Tlv *    tlv;
+
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
+
+    message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
+    SuccessOrExit(error = message->AppendUriPathOptions(OT_URI_PATH_JOINER_ENTRUST));
+    SuccessOrExit(error = message->SetPayloadMarker());
+    message->SetSubType(Message::kSubTypeJoinerEntrust);
+
+    SuccessOrExit(
+        error = Tlv::AppendTlv(*message, Tlv::kNetworkMasterKey, &Get<KeyManager>().GetMasterKey(), sizeof(MasterKey)));
+
+    SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kMeshLocalPrefix, &Get<Mle::MleRouter>().GetMeshLocalPrefix(),
+                                         sizeof(otMeshLocalPrefix)));
+
+    SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kExtendedPanId, &Get<Mac::Mac>().GetExtendedPanId(),
+                                         sizeof(Mac::ExtendedPanId)));
+
+    networkName.Init();
+    networkName.SetNetworkName(Get<Mac::Mac>().GetNetworkName().GetAsData());
+    SuccessOrExit(error = networkName.AppendTo(*message));
+
+    IgnoreError(Get<ActiveDataset>().Read(dataset));
+
+    if ((tlv = dataset.GetTlv<ActiveTimestampTlv>()) != nullptr)
+    {
+        SuccessOrExit(error = tlv->AppendTo(*message));
+    }
+    else
+    {
+        ActiveTimestampTlv activeTimestamp;
+        activeTimestamp.Init();
+        SuccessOrExit(error = activeTimestamp.AppendTo(*message));
+    }
+
+    if ((tlv = dataset.GetTlv<ChannelMaskTlv>()) != nullptr)
+    {
+        SuccessOrExit(error = tlv->AppendTo(*message));
+    }
+    else
+    {
+        ChannelMaskBaseTlv channelMask;
+        channelMask.Init();
+        SuccessOrExit(error = channelMask.AppendTo(*message));
+    }
+
+    if ((tlv = dataset.GetTlv<PskcTlv>()) != nullptr)
+    {
+        SuccessOrExit(error = tlv->AppendTo(*message));
+    }
+    else
+    {
+        PskcTlv pskc;
+        pskc.Init();
+        SuccessOrExit(error = pskc.AppendTo(*message));
+    }
+
+    if ((tlv = dataset.GetTlv<SecurityPolicyTlv>()) != nullptr)
+    {
+        SuccessOrExit(error = tlv->AppendTo(*message));
+    }
+    else
+    {
+        SecurityPolicyTlv securityPolicy;
+        securityPolicy.Init();
+        SuccessOrExit(error = securityPolicy.AppendTo(*message));
+    }
+
+    SuccessOrExit(
+        error = Tlv::AppendUint32Tlv(*message, Tlv::kNetworkKeySequence, Get<KeyManager>().GetCurrentKeySequence()));
 
 exit:
-    return error;
+
+    if (error != OT_ERROR_NONE && message != nullptr)
+    {
+        message->Free();
+        message = nullptr;
+    }
+
+    return message;
 }
 
 void JoinerRouter::HandleJoinerEntrustResponse(void *               aContext,
@@ -444,12 +444,11 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    mExpectJoinEntRsp = false;
     SendDelayedJoinerEntrust();
 
-    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage != NULL);
+    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage != nullptr, OT_NOOP);
 
-    VerifyOrExit(aMessage->GetCode() == OT_COAP_CODE_CHANGED);
+    VerifyOrExit(aMessage->GetCode() == OT_COAP_CODE_CHANGED, OT_NOOP);
 
     otLogInfoMeshCoP("Receive joiner entrust response");
     otLogCertMeshCoP("[THCI] direction=recv | type=JOIN_ENT.rsp");
@@ -458,6 +457,14 @@
     return;
 }
 
+void JoinerRouter::JoinerEntrustMetadata::ReadFrom(const Message &aMessage)
+{
+    uint16_t length = aMessage.GetLength();
+
+    OT_ASSERT(length >= sizeof(*this));
+    aMessage.Read(length - sizeof(*this), sizeof(*this), this);
+}
+
 } // namespace MeshCoP
 } // namespace ot
 
diff --git a/src/core/meshcop/joiner_router.hpp b/src/core/meshcop/joiner_router.hpp
index c562c42..0f26a7d 100644
--- a/src/core/meshcop/joiner_router.hpp
+++ b/src/core/meshcop/joiner_router.hpp
@@ -51,7 +51,7 @@
 
 namespace MeshCoP {
 
-class JoinerRouter : public InstanceLocator
+class JoinerRouter : public InstanceLocator, public Notifier::Receiver
 {
 public:
     /**
@@ -81,11 +81,21 @@
 private:
     enum
     {
-        kDelayJoinEnt = 50, ///< milliseconds
+        kJoinerEntrustTxDelay = 50, ///< milliseconds
     };
 
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags);
-    void        HandleStateChanged(otChangedFlags aFlags);
+    struct JoinerEntrustMetadata
+    {
+        otError AppendTo(Message &aMessage) { return aMessage.Append(this, sizeof(*this)); }
+        void    ReadFrom(const Message &aMessage);
+
+        Ip6::MessageInfo mMessageInfo; // Message info of the message to send.
+        TimeMilli        mSendTime;    // Time when the message shall be sent.
+        Kek              mKek;         // KEK used by MAC layer to encode this message.
+    };
+
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
 
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
@@ -102,111 +112,21 @@
     static void HandleTimer(Timer &aTimer);
     void        HandleTimer(void);
 
-    otError DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const JoinerRouterKekTlv &aKek);
-    void    SendDelayedJoinerEntrust(void);
-    otError SendJoinerEntrust(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    void           Start(void);
+    void           DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const Kek &aKek);
+    void           SendDelayedJoinerEntrust(void);
+    otError        SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo);
+    Coap::Message *PrepareJoinerEntrustMessage(void);
 
-    Ip6::UdpSocket mSocket;
-    Coap::Resource mRelayTransmit;
+    Ip6::Udp::Socket mSocket;
+    Coap::Resource   mRelayTransmit;
 
     TimerMilli   mTimer;
     MessageQueue mDelayedJoinEnts;
 
-    Notifier::Callback mNotifierCallback;
-
     uint16_t mJoinerUdpPort;
 
     bool mIsJoinerPortConfigured : 1;
-    bool mExpectJoinEntRsp : 1;
-};
-
-/**
- * This class implements functionality required for delaying JOIN_ENT.ntf messages.
- *
- */
-class DelayedJoinEntHeader
-{
-public:
-    /**
-     * This method initializes the object with specific values.
-     *
-     * @param[in]  aSendTime     Time when the message shall be sent.
-     * @param[in]  aMessageInfo  IPv6 address of the message destination.
-     * @param[in]  aKek          A pointer to the KEK.
-     *
-     */
-    void Init(TimeMilli aSendTime, Ip6::MessageInfo &aMessageInfo, const uint8_t *aKek)
-    {
-        mSendTime    = aSendTime;
-        mMessageInfo = aMessageInfo;
-        memcpy(&mKek, aKek, sizeof(mKek));
-    }
-
-    /**
-     * This method appends delayed response header to the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     * @retval OT_ERROR_NONE     Successfully appended the bytes.
-     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
-     *
-     */
-    otError AppendTo(Message &aMessage) { return aMessage.Append(this, sizeof(*this)); }
-
-    /**
-     * This method reads delayed response header from the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     */
-    void ReadFrom(const Message &aMessage)
-    {
-        uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-        assert(length == sizeof(*this));
-        OT_UNUSED_VARIABLE(length);
-    }
-
-    /**
-     * This method removes delayed response header from the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     */
-    static void RemoveFrom(Message &aMessage)
-    {
-        otError error = aMessage.SetLength(aMessage.GetLength() - sizeof(DelayedJoinEntHeader));
-        assert(error == OT_ERROR_NONE);
-        OT_UNUSED_VARIABLE(error);
-    }
-
-    /**
-     * This method returns a time when the message shall be sent.
-     *
-     * @returns  A time when the message shall be sent.
-     *
-     */
-    TimeMilli GetSendTime(void) const { return mSendTime; }
-
-    /**
-     * This method returns a destination of the delayed message.
-     *
-     * @returns  A destination of the delayed message.
-     *
-     */
-    const Ip6::MessageInfo *GetMessageInfo(void) const { return &mMessageInfo; }
-
-    /**
-     * This method returns a pointer to the KEK that should be used to send the delayed message.
-     *
-     * @returns  A pointer to the KEK.
-     *
-     */
-    const uint8_t *GetKek(void) const { return mKek; }
-
-private:
-    Ip6::MessageInfo mMessageInfo;                    ///< Message info of the message to send.
-    TimeMilli        mSendTime;                       ///< Time when the message shall be sent.
-    uint8_t          mKek[KeyManager::kMaxKeyLength]; ///< KEK used by MAC layer to encode this message.
 };
 
 } // namespace MeshCoP
diff --git a/src/core/meshcop/leader.cpp b/src/core/meshcop/leader.cpp
deleted file mode 100644
index 29996ad..0000000
--- a/src/core/meshcop/leader.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements a MeshCoP Leader.
- */
-
-#if OPENTHREAD_FTD
-
-#include "leader.hpp"
-
-#include <stdio.h>
-
-#include "coap/coap_message.hpp"
-#include "common/code_utils.hpp"
-#include "common/instance.hpp"
-#include "common/locator-getters.hpp"
-#include "common/logging.hpp"
-#include "common/random.hpp"
-#include "meshcop/meshcop.hpp"
-#include "meshcop/meshcop_tlvs.hpp"
-#include "thread/thread_netif.hpp"
-#include "thread/thread_tlvs.hpp"
-#include "thread/thread_uri_paths.hpp"
-
-namespace ot {
-namespace MeshCoP {
-
-Leader::Leader(Instance &aInstance)
-    : InstanceLocator(aInstance)
-    , mPetition(OT_URI_PATH_LEADER_PETITION, Leader::HandlePetition, this)
-    , mKeepAlive(OT_URI_PATH_LEADER_KEEP_ALIVE, Leader::HandleKeepAlive, this)
-    , mTimer(aInstance, HandleTimer, this)
-    , mDelayTimerMinimal(DelayTimerTlv::kDelayTimerMinimal)
-    , mSessionId(Random::NonCrypto::GetUint16())
-{
-    Get<Coap::Coap>().AddResource(mPetition);
-    Get<Coap::Coap>().AddResource(mKeepAlive);
-}
-
-void Leader::HandlePetition(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
-{
-    static_cast<Leader *>(aContext)->HandlePetition(*static_cast<Coap::Message *>(aMessage),
-                                                    *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
-}
-
-void Leader::HandlePetition(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
-    OT_UNUSED_VARIABLE(aMessageInfo);
-
-    CommissioningData data;
-    CommissionerIdTlv commissionerId;
-    StateTlv::State   state = StateTlv::kReject;
-
-    otLogInfoMeshCoP("received petition");
-
-    VerifyOrExit(Get<Mle::MleRouter>().IsRoutingLocator(aMessageInfo.GetPeerAddr()));
-    SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kCommissionerId, sizeof(commissionerId), commissionerId));
-
-    if (mTimer.IsRunning())
-    {
-        VerifyOrExit((commissionerId.GetCommissionerIdLength() == mCommissionerId.GetCommissionerIdLength()) &&
-                     (!strncmp(commissionerId.GetCommissionerId(), mCommissionerId.GetCommissionerId(),
-                               commissionerId.GetCommissionerIdLength())));
-
-        ResignCommissioner();
-    }
-
-    data.mBorderAgentLocator.Init();
-    data.mBorderAgentLocator.SetBorderAgentLocator(HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[7]));
-
-    data.mCommissionerSessionId.Init();
-    data.mCommissionerSessionId.SetCommissionerSessionId(++mSessionId);
-
-    data.mSteeringData.Init();
-    data.mSteeringData.SetLength(1);
-    data.mSteeringData.Clear();
-
-    SuccessOrExit(
-        Get<NetworkData::Leader>().SetCommissioningData(reinterpret_cast<uint8_t *>(&data), data.GetLength()));
-
-    mCommissionerId = commissionerId;
-
-    if (mCommissionerId.GetLength() > CommissionerIdTlv::kMaxLength)
-    {
-        mCommissionerId.SetLength(CommissionerIdTlv::kMaxLength);
-    }
-
-    state = StateTlv::kAccept;
-    mTimer.Start(Time::SecToMsec(kTimeoutLeaderPetition));
-
-exit:
-    SendPetitionResponse(aMessage, aMessageInfo, state);
-}
-
-otError Leader::SendPetitionResponse(const Coap::Message &   aRequest,
-                                     const Ip6::MessageInfo &aMessageInfo,
-                                     StateTlv::State         aState)
-{
-    otError                  error = OT_ERROR_NONE;
-    StateTlv                 state;
-    CommissionerSessionIdTlv sessionId;
-    Coap::Message *          message;
-
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
-
-    SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
-    SuccessOrExit(error = message->SetPayloadMarker());
-
-    state.Init();
-    state.SetState(aState);
-    SuccessOrExit(error = state.AppendTo(*message));
-
-    if (mTimer.IsRunning())
-    {
-        SuccessOrExit(error = mCommissionerId.AppendTo(*message));
-    }
-
-    if (aState == StateTlv::kAccept)
-    {
-        sessionId.Init();
-        sessionId.SetCommissionerSessionId(mSessionId);
-        SuccessOrExit(error = sessionId.AppendTo(*message));
-    }
-
-    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo));
-
-    otLogInfoMeshCoP("sent petition response");
-
-exit:
-
-    if (error != OT_ERROR_NONE && message != NULL)
-    {
-        message->Free();
-    }
-
-    return error;
-}
-
-void Leader::HandleKeepAlive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
-{
-    static_cast<Leader *>(aContext)->HandleKeepAlive(*static_cast<Coap::Message *>(aMessage),
-                                                     *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
-}
-
-void Leader::HandleKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
-    StateTlv                 state;
-    CommissionerSessionIdTlv sessionId;
-    BorderAgentLocatorTlv *  borderAgentLocator;
-    StateTlv::State          responseState;
-
-    otLogInfoMeshCoP("received keep alive");
-
-    SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kState, sizeof(state), state));
-    VerifyOrExit(state.IsValid());
-
-    SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kCommissionerSessionId, sizeof(sessionId), sessionId));
-    VerifyOrExit(sessionId.IsValid());
-
-    borderAgentLocator = static_cast<BorderAgentLocatorTlv *>(
-        Get<NetworkData::Leader>().GetCommissioningDataSubTlv(Tlv::kBorderAgentLocator));
-
-    if ((borderAgentLocator == NULL) || (sessionId.GetCommissionerSessionId() != mSessionId))
-    {
-        responseState = StateTlv::kReject;
-    }
-    else if (state.GetState() != StateTlv::kAccept)
-    {
-        responseState = StateTlv::kReject;
-        ResignCommissioner();
-    }
-    else
-    {
-        uint16_t rloc = HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[7]);
-
-        if (borderAgentLocator->GetBorderAgentLocator() != rloc)
-        {
-            borderAgentLocator->SetBorderAgentLocator(rloc);
-            Get<NetworkData::Leader>().IncrementVersion();
-        }
-
-        responseState = StateTlv::kAccept;
-        mTimer.Start(Time::SecToMsec(kTimeoutLeaderPetition));
-    }
-
-    SendKeepAliveResponse(aMessage, aMessageInfo, responseState);
-
-exit:
-    return;
-}
-
-otError Leader::SendKeepAliveResponse(const Coap::Message &   aRequest,
-                                      const Ip6::MessageInfo &aMessageInfo,
-                                      StateTlv::State         aState)
-{
-    otError        error = OT_ERROR_NONE;
-    StateTlv       state;
-    Coap::Message *message;
-
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
-
-    SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
-    SuccessOrExit(error = message->SetPayloadMarker());
-
-    state.Init();
-    state.SetState(aState);
-    SuccessOrExit(error = state.AppendTo(*message));
-
-    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo));
-
-    otLogInfoMeshCoP("sent keep alive response");
-
-exit:
-
-    if (error != OT_ERROR_NONE && message != NULL)
-    {
-        message->Free();
-    }
-
-    return error;
-}
-
-otError Leader::SendDatasetChanged(const Ip6::Address &aAddress)
-{
-    otError          error = OT_ERROR_NONE;
-    Ip6::MessageInfo messageInfo;
-    Coap::Message *  message;
-
-    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
-
-    SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_DATASET_CHANGED));
-
-    messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
-    messageInfo.SetPeerAddr(aAddress);
-    messageInfo.SetPeerPort(kCoapUdpPort);
-    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
-
-    otLogInfoMeshCoP("sent dataset changed");
-
-exit:
-
-    if (error != OT_ERROR_NONE && message != NULL)
-    {
-        message->Free();
-    }
-
-    return error;
-}
-
-otError Leader::SetDelayTimerMinimal(uint32_t aDelayTimerMinimal)
-{
-    otError error = OT_ERROR_NONE;
-    VerifyOrExit((aDelayTimerMinimal != 0 && aDelayTimerMinimal < DelayTimerTlv::kDelayTimerDefault),
-                 error = OT_ERROR_INVALID_ARGS);
-    mDelayTimerMinimal = aDelayTimerMinimal;
-
-exit:
-    return error;
-}
-
-uint32_t Leader::GetDelayTimerMinimal(void) const
-{
-    return mDelayTimerMinimal;
-}
-
-void Leader::HandleTimer(Timer &aTimer)
-{
-    aTimer.GetOwner<Leader>().HandleTimer();
-}
-
-void Leader::HandleTimer(void)
-{
-    VerifyOrExit(Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER);
-
-    ResignCommissioner();
-
-exit:
-    return;
-}
-
-void Leader::SetEmptyCommissionerData(void)
-{
-    CommissionerSessionIdTlv mCommissionerSessionId;
-
-    mCommissionerSessionId.Init();
-    mCommissionerSessionId.SetCommissionerSessionId(++mSessionId);
-
-    Get<NetworkData::Leader>().SetCommissioningData(reinterpret_cast<uint8_t *>(&mCommissionerSessionId),
-                                                    sizeof(Tlv) + mCommissionerSessionId.GetLength());
-}
-
-void Leader::ResignCommissioner(void)
-{
-    mTimer.Stop();
-    SetEmptyCommissionerData();
-
-    otLogInfoMeshCoP("commissioner inactive");
-}
-
-} // namespace MeshCoP
-} // namespace ot
-
-#endif // OPENTHREAD_FTD
diff --git a/src/core/meshcop/leader.hpp b/src/core/meshcop/leader.hpp
deleted file mode 100644
index dfadf7e..0000000
--- a/src/core/meshcop/leader.hpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes definitions for a MeshCoP Leader.
- */
-
-#ifndef MESHCOP_LEADER_HPP_
-#define MESHCOP_LEADER_HPP_
-
-#include "openthread-core-config.h"
-
-#include "coap/coap.hpp"
-#include "common/locator.hpp"
-#include "common/timer.hpp"
-#include "meshcop/meshcop_tlvs.hpp"
-#include "net/udp6.hpp"
-#include "thread/mle.hpp"
-
-namespace ot {
-namespace MeshCoP {
-
-OT_TOOL_PACKED_BEGIN
-class CommissioningData
-{
-public:
-    uint8_t GetLength(void) const
-    {
-        return sizeof(Tlv) + mBorderAgentLocator.GetLength() + sizeof(Tlv) + mCommissionerSessionId.GetLength() +
-               sizeof(Tlv) + mSteeringData.GetLength();
-    }
-
-    BorderAgentLocatorTlv    mBorderAgentLocator;
-    CommissionerSessionIdTlv mCommissionerSessionId;
-    SteeringDataTlv          mSteeringData;
-} OT_TOOL_PACKED_END;
-
-class Leader : public InstanceLocator
-{
-public:
-    /**
-     * This constructor initializes the Leader object.
-     *
-     * @param[in]  aInstance     A reference to the OpenThread instance.
-     *
-     */
-    explicit Leader(Instance &aInstance);
-
-    /**
-     * This method sends a MGMT_DATASET_CHANGED message to commissioner.
-     *
-     * @param[in]  aAddress   The IPv6 address of destination.
-     *
-     * @retval OT_ERROR_NONE     Successfully send MGMT_DATASET_CHANGED message.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffers to generate a MGMT_DATASET_CHANGED message.
-     *
-     */
-    otError SendDatasetChanged(const Ip6::Address &aAddress);
-
-    /**
-     * This method sets minimal delay timer.
-     *
-     * @param[in]  aDelayTimerMinimal The value of minimal delay timer (in ms).
-     *
-     * @retval  OT_ERROR_NONE         Successfully set the minimal delay timer.
-     * @retval  OT_ERROR_INVALID_ARGS If @p aDelayTimerMinimal is not valid.
-     *
-     */
-    otError SetDelayTimerMinimal(uint32_t aDelayTimerMinimal);
-
-    /**
-     * This method gets minimal delay timer.
-     *
-     * @retval the minimal delay timer (in ms).
-     *
-     */
-    uint32_t GetDelayTimerMinimal(void) const;
-
-    /**
-     * This method sets empty Commissioner Data TLV in the Thread Network Data.
-     *
-     */
-    void SetEmptyCommissionerData(void);
-
-private:
-    enum
-    {
-        kTimeoutLeaderPetition = 50, ///< TIMEOUT_LEAD_PET (seconds)
-    };
-
-    static void HandleTimer(Timer &aTimer);
-    void        HandleTimer(void);
-
-    static void HandlePetition(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
-    void        HandlePetition(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-    otError     SendPetitionResponse(const Coap::Message &   aRequest,
-                                     const Ip6::MessageInfo &aMessageInfo,
-                                     StateTlv::State         aState);
-
-    static void HandleKeepAlive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
-    void        HandleKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-    otError     SendKeepAliveResponse(const Coap::Message &   aRequest,
-                                      const Ip6::MessageInfo &aMessageInfo,
-                                      StateTlv::State         aState);
-
-    static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
-
-    void ResignCommissioner(void);
-
-    Coap::Resource mPetition;
-    Coap::Resource mKeepAlive;
-    TimerMilli     mTimer;
-
-    uint32_t mDelayTimerMinimal;
-
-    CommissionerIdTlv mCommissionerId;
-    uint16_t          mSessionId;
-};
-
-} // namespace MeshCoP
-} // namespace ot
-
-#endif // MESHCOP_LEADER_HPP_
diff --git a/src/core/meshcop/meshcop.cpp b/src/core/meshcop/meshcop.cpp
index f7c5f23..1a30d87 100644
--- a/src/core/meshcop/meshcop.cpp
+++ b/src/core/meshcop/meshcop.cpp
@@ -31,7 +31,12 @@
  *   This file implements common MeshCoP utility functions.
  */
 
+#include "meshcop.hpp"
+
+#include "common/crc16.hpp"
+#include "common/debug.hpp"
 #include "common/locator-getters.hpp"
+#include "crypto/pbkdf2_cmac.h"
 #include "crypto/sha256.hpp"
 #include "mac/mac_types.hpp"
 #include "thread/thread_netif.hpp"
@@ -39,6 +44,245 @@
 namespace ot {
 namespace MeshCoP {
 
+otError JoinerPskd::SetFrom(const char *aPskdString)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(IsPskdValid(aPskdString), error = OT_ERROR_INVALID_ARGS);
+
+    Clear();
+    memcpy(m8, aPskdString, StringLength(aPskdString, sizeof(m8)));
+
+exit:
+    return error;
+}
+
+bool JoinerPskd::operator==(const JoinerPskd &aOther) const
+{
+    bool isEqual = true;
+
+    for (uint8_t i = 0; i < sizeof(m8); i++)
+    {
+        if (m8[i] != aOther.m8[i])
+        {
+            isEqual = false;
+            ExitNow();
+        }
+
+        if (m8[i] == '\0')
+        {
+            break;
+        }
+    }
+
+exit:
+    return isEqual;
+}
+
+bool JoinerPskd::IsPskdValid(const char *aPskString)
+{
+    bool     valid      = false;
+    uint16_t pskdLength = StringLength(aPskString, kMaxLength + 1);
+
+    VerifyOrExit(pskdLength >= kMinLength && pskdLength <= kMaxLength, OT_NOOP);
+
+    for (uint16_t i = 0; i < pskdLength; i++)
+    {
+        char c = aPskString[i];
+
+        VerifyOrExit(isdigit(c) || isupper(c), OT_NOOP);
+        VerifyOrExit(c != 'I' && c != 'O' && c != 'Q' && c != 'Z', OT_NOOP);
+    }
+
+    valid = true;
+
+exit:
+    return valid;
+}
+
+void JoinerDiscerner::GenerateJoinerId(Mac::ExtAddress &aJoinerId) const
+{
+    aJoinerId.GenerateRandom();
+    CopyTo(aJoinerId);
+    aJoinerId.SetLocal(true);
+}
+
+bool JoinerDiscerner::Matches(const Mac::ExtAddress &aJoinerId) const
+{
+    uint64_t mask;
+
+    OT_ASSERT(IsValid());
+
+    mask = GetMask();
+
+    return (Encoding::BigEndian::ReadUint64(aJoinerId.m8) & mask) == (mValue & mask);
+}
+
+void JoinerDiscerner::CopyTo(Mac::ExtAddress &aExtAddress) const
+{
+    // Copies the discerner value up to its bit length to `aExtAddress`
+    // array, assuming big-endian encoding (i.e., the discerner lowest bits
+    // are copied at end of `aExtAddress.m8[]` array). Any initial/remaining
+    // bits of `aExtAddress` array remain unchanged.
+
+    uint8_t *cur       = &aExtAddress.m8[sizeof(Mac::ExtAddress) - 1];
+    uint8_t  remaining = mLength;
+    uint64_t value     = mValue;
+
+    OT_ASSERT(IsValid());
+
+    // Write full bytes
+    while (remaining >= CHAR_BIT)
+    {
+        *cur = static_cast<uint8_t>(value & 0xff);
+        value >>= CHAR_BIT;
+        cur--;
+        remaining -= CHAR_BIT;
+    }
+
+    // Write any remaining bits (not a full byte)
+    if (remaining != 0)
+    {
+        uint8_t mask = static_cast<uint8_t>((1U << remaining) - 1);
+
+        // `mask` has it lower (lsb) `remaining` bits as `1` and rest as `0`.
+        // Example with `remaining = 3` -> (1 << 3) - 1 = 0b1000 - 1 = 0b0111.
+
+        *cur &= ~mask;
+        *cur |= static_cast<uint8_t>(value & mask);
+    }
+}
+
+bool JoinerDiscerner::operator==(const JoinerDiscerner &aOther) const
+{
+    uint64_t mask = GetMask();
+
+    return IsValid() && (mLength == aOther.mLength) && ((mValue & mask) == (aOther.mValue & mask));
+}
+
+JoinerDiscerner::InfoString JoinerDiscerner::ToString(void) const
+{
+    InfoString str;
+
+    if (mLength <= sizeof(uint16_t) * CHAR_BIT)
+    {
+        IgnoreError(str.Set("0x%04x", static_cast<uint16_t>(mValue)));
+    }
+    else if (mLength <= sizeof(uint32_t) * CHAR_BIT)
+    {
+        IgnoreError(str.Set("0x%08x", static_cast<uint32_t>(mValue)));
+    }
+    else
+    {
+        IgnoreError(str.Set("0x%x-%08x", static_cast<uint32_t>(mValue >> 32), static_cast<uint32_t>(mValue)));
+    }
+
+    IgnoreError(str.Append("/len:%d", mLength));
+
+    return str;
+}
+
+void SteeringData::Init(uint8_t aLength)
+{
+    OT_ASSERT(aLength <= kMaxLength);
+    mLength = aLength;
+    memset(m8, 0, sizeof(m8));
+}
+
+void SteeringData::SetToPermitAllJoiners(void)
+{
+    Init(1);
+    m8[0] = kPermitAll;
+}
+
+void SteeringData::UpdateBloomFilter(const Mac::ExtAddress &aJoinerId)
+{
+    HashBitIndexes indexes;
+
+    CalculateHashBitIndexes(aJoinerId, indexes);
+    UpdateBloomFilter(indexes);
+}
+
+void SteeringData::UpdateBloomFilter(const JoinerDiscerner &aDiscerner)
+{
+    HashBitIndexes indexes;
+
+    CalculateHashBitIndexes(aDiscerner, indexes);
+    UpdateBloomFilter(indexes);
+}
+
+void SteeringData::UpdateBloomFilter(const HashBitIndexes &aIndexes)
+{
+    OT_ASSERT((mLength > 0) && (mLength <= kMaxLength));
+
+    SetBit(aIndexes.mIndex[0] % GetNumBits());
+    SetBit(aIndexes.mIndex[1] % GetNumBits());
+}
+
+bool SteeringData::Contains(const Mac::ExtAddress &aJoinerId) const
+{
+    HashBitIndexes indexes;
+
+    CalculateHashBitIndexes(aJoinerId, indexes);
+
+    return Contains(indexes);
+}
+
+bool SteeringData::Contains(const JoinerDiscerner &aDiscerner) const
+{
+    HashBitIndexes indexes;
+
+    CalculateHashBitIndexes(aDiscerner, indexes);
+
+    return Contains(indexes);
+}
+
+bool SteeringData::Contains(const HashBitIndexes &aIndexes) const
+{
+    return (mLength > 0) && GetBit(aIndexes.mIndex[0] % GetNumBits()) && GetBit(aIndexes.mIndex[1] % GetNumBits());
+}
+
+void SteeringData::CalculateHashBitIndexes(const Mac::ExtAddress &aJoinerId, HashBitIndexes &aIndexes)
+{
+    Crc16 ccitt(Crc16::kCcitt);
+    Crc16 ansi(Crc16::kAnsi);
+
+    for (uint8_t i = 0; i < sizeof(Mac::ExtAddress); i++)
+    {
+        ccitt.Update(aJoinerId.m8[i]);
+        ansi.Update(aJoinerId.m8[i]);
+    }
+
+    aIndexes.mIndex[0] = ccitt.Get();
+    aIndexes.mIndex[1] = ansi.Get();
+}
+
+void SteeringData::CalculateHashBitIndexes(const JoinerDiscerner &aDiscerner, HashBitIndexes &aIndexes)
+{
+    Mac::ExtAddress address;
+
+    address.Clear();
+    aDiscerner.CopyTo(address);
+
+    CalculateHashBitIndexes(address, aIndexes);
+}
+
+bool SteeringData::DoesAllMatch(uint8_t aMatch) const
+{
+    bool matches = true;
+
+    for (uint8_t i = 0; i < mLength; i++)
+    {
+        if (m8[i] != aMatch)
+        {
+            matches = false;
+            break;
+        }
+    }
+
+    return matches;
+}
+
 void ComputeJoinerId(const Mac::ExtAddress &aEui64, Mac::ExtAddress &aJoinerId)
 {
     Crypto::Sha256 sha256;
@@ -54,12 +298,12 @@
 
 otError GetBorderAgentRloc(ThreadNetif &aNetif, uint16_t &aRloc)
 {
-    otError                error = OT_ERROR_NONE;
-    BorderAgentLocatorTlv *borderAgentLocator;
+    otError                      error = OT_ERROR_NONE;
+    const BorderAgentLocatorTlv *borderAgentLocator;
 
-    borderAgentLocator = static_cast<BorderAgentLocatorTlv *>(
+    borderAgentLocator = static_cast<const BorderAgentLocatorTlv *>(
         aNetif.Get<NetworkData::Leader>().GetCommissioningDataSubTlv(Tlv::kBorderAgentLocator));
-    VerifyOrExit(borderAgentLocator != NULL, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(borderAgentLocator != nullptr, error = OT_ERROR_NOT_FOUND);
 
     aRloc = borderAgentLocator->GetBorderAgentLocator();
 
@@ -67,5 +311,44 @@
     return error;
 }
 
+#if OPENTHREAD_FTD
+otError GeneratePskc(const char *              aPassPhrase,
+                     const Mac::NetworkName &  aNetworkName,
+                     const Mac::ExtendedPanId &aExtPanId,
+                     Pskc &                    aPskc)
+{
+    otError    error        = OT_ERROR_NONE;
+    const char saltPrefix[] = "Thread";
+    uint8_t    salt[OT_PBKDF2_SALT_MAX_LEN];
+    uint16_t   saltLen = 0;
+    uint16_t   passphraseLen;
+    uint8_t    networkNameLen;
+
+    passphraseLen  = static_cast<uint16_t>(StringLength(aPassPhrase, OT_COMMISSIONING_PASSPHRASE_MAX_SIZE + 1));
+    networkNameLen = static_cast<uint8_t>(StringLength(aNetworkName.GetAsCString(), OT_NETWORK_NAME_MAX_SIZE + 1));
+
+    VerifyOrExit((passphraseLen >= OT_COMMISSIONING_PASSPHRASE_MIN_SIZE) &&
+                     (passphraseLen <= OT_COMMISSIONING_PASSPHRASE_MAX_SIZE) &&
+                     (networkNameLen <= OT_NETWORK_NAME_MAX_SIZE),
+                 error = OT_ERROR_INVALID_ARGS);
+
+    memset(salt, 0, sizeof(salt));
+    memcpy(salt, saltPrefix, sizeof(saltPrefix) - 1);
+    saltLen += static_cast<uint16_t>(sizeof(saltPrefix) - 1);
+
+    memcpy(salt + saltLen, aExtPanId.m8, sizeof(aExtPanId));
+    saltLen += OT_EXT_PAN_ID_SIZE;
+
+    memcpy(salt + saltLen, aNetworkName.GetAsCString(), networkNameLen);
+    saltLen += networkNameLen;
+
+    otPbkdf2Cmac(reinterpret_cast<const uint8_t *>(aPassPhrase), passphraseLen, reinterpret_cast<const uint8_t *>(salt),
+                 saltLen, 16384, OT_PSKC_MAX_SIZE, aPskc.m8);
+
+exit:
+    return error;
+}
+#endif // OPENTHREAD_FTD
+
 } // namespace MeshCoP
 } // namespace ot
diff --git a/src/core/meshcop/meshcop.hpp b/src/core/meshcop/meshcop.hpp
index d39b79d..1c63500 100644
--- a/src/core/meshcop/meshcop.hpp
+++ b/src/core/meshcop/meshcop.hpp
@@ -37,32 +37,442 @@
 
 #include "openthread-core-config.h"
 
+#include <limits.h>
+
+#include <openthread/commissioner.h>
 #include <openthread/instance.h>
+#include <openthread/joiner.h>
 
 #include "coap/coap.hpp"
+#include "common/clearable.hpp"
 #include "common/message.hpp"
+#include "common/string.hpp"
 #include "mac/mac_types.hpp"
+#include "meshcop/meshcop_tlvs.hpp"
 
 namespace ot {
+
+class ThreadNetif;
+
 namespace MeshCoP {
 
 enum
 {
-    kMeshCoPMessagePriority = Message::kPriorityNet, ///< The priority for MeshCoP message
-    kBorderAgentUdpPort     = 49191,                 ///< UDP port of border agent service.
+    kBorderAgentUdpPort = 49191, ///< UDP port of border agent service.
 };
 
 /**
- * This function create Message for MeshCoP
+ * This type represents a Joiner PSKd.
+ *
+ */
+class JoinerPskd : public otJoinerPskd, public Clearable<JoinerPskd>
+{
+public:
+    enum
+    {
+        kMinLength = 6,                         ///< Minimum PSKd string length (excluding null char).
+        kMaxLength = OT_JOINER_MAX_PSKD_LENGTH, ///< Maximum PSKd string length (excluding null char)
+    };
+
+    /**
+     * This method indicates whether the PSKd if well-formed and valid.
+     *
+     * Per Thread specification, a Joining Device Credential is encoded as uppercase alphanumeric characters
+     * (base32-thread: 0-9, A-Z excluding I, O, Q, and Z for readability) with a minimum length of 6 such characters
+     * and a maximum length of 32 such characters.
+     *
+     * @returns TRUE if the PSKd is valid, FALSE otherwise.
+     *
+     */
+    bool IsValid(void) const { return IsPskdValid(m8); }
+
+    /**
+     * This method sets the joiner PSKd from a given C string.
+     *
+     * @param[in] aPskdString   A pointer to the PSKd C string array.
+     *
+     * @retval OT_ERROR_NONE           The PSKd was updated successfully.
+     * @retval OT_ERROR_INVALID_ARGS   The given PSKd C string is not valid.
+     *
+     */
+    otError SetFrom(const char *aPskdString);
+
+    /**
+     * This method gets the PSKd as a null terminated C string.
+     *
+     * This method must be used after the PSKd is validated, otherwise its behavior is undefined.
+     *
+     * @returns The PSKd as a C string.
+     *
+     */
+    const char *GetAsCString(void) const { return m8; }
+
+    /**
+     * This method gets the PSKd string length.
+     *
+     * This method must be used after the PSKd is validated, otherwise its behavior is undefined.
+     *
+     * @returns The PSKd string length.
+     *
+     */
+    uint8_t GetLength(void) const { return static_cast<uint8_t>(StringLength(m8, kMaxLength + 1)); }
+
+    /**
+     * This method overloads operator `==` to evaluate whether or not two PSKds are equal.
+     *
+     * @param[in]  aOther  The other PSKd to compare with.
+     *
+     * @retval TRUE   If the two are equal.
+     * @retval FALSE  If the two are not equal.
+     *
+     */
+    bool operator==(const JoinerPskd &aOther) const;
+
+    /**
+     * This method overloads operator `!=` to evaluate whether or not two PSKds are unequal.
+     *
+     * @param[in]  aOther  The other PSKd to compare with.
+     *
+     * @retval TRUE   If the two are not equal.
+     * @retval FALSE  If the two are equal.
+     *
+     */
+    bool operator!=(const JoinerPskd &aOther) const { return !(*this == aOther); }
+
+    /**
+     * This static method indicates whether a given PSKd string if well-formed and valid.
+     *
+     * @param[in] aPskdString  A pointer to a PSKd string array.
+     *
+     * @sa IsValid()
+     *
+     * @returns TRUE if @p aPskdString is valid, FALSE otherwise.
+     *
+     */
+    static bool IsPskdValid(const char *aPskdString);
+};
+
+/**
+ * This type represents a Joiner Discerner.
+ *
+ */
+class JoinerDiscerner : public otJoinerDiscerner
+{
+    friend class SteeringData;
+
+public:
+    enum
+    {
+        kMaxLength      = OT_JOINER_MAX_DISCERNER_LENGTH, ///< Maximum length of a Joiner Discerner in bits.
+        kInfoStringSize = 45,                             ///< Size of `InfoString` to use with `ToString()
+    };
+
+    /**
+     * This type defines the fixed-length `String` object returned from `ToString()`.
+     *
+     */
+    typedef String<kInfoStringSize> InfoString;
+
+    /**
+     * This method clears the Joiner Discerner.
+     *
+     */
+    void Clear(void) { mLength = 0; }
+
+    /**
+     * This method indicates whether the Joiner Discerner is empty (no value set).
+     *
+     * @returns TRUE if empty, FALSE otherwise.
+     *
+     */
+    bool IsEmpty(void) const { return mLength == 0; }
+
+    /**
+     * This method gets the Joiner Discerner's value.
+     *
+     * @returns The Joiner Discerner value.
+     *
+     */
+    uint64_t GetValue(void) const { return mValue; }
+
+    /**
+     * This method gets the Joiner Discerner's length (in bits).
+     *
+     * @return The Joiner Discerner length.
+     *
+     */
+    uint8_t GetLength(void) const { return mLength; }
+
+    /**
+     * This method indicates whether the Joiner Discerner is valid (i.e. it not empty and its length is within
+     * valid range).
+     *
+     * @returns TRUE if Joiner Discerner is valid, FALSE otherwise.
+     *
+     */
+    bool IsValid(void) const { return (0 < mLength) && (mLength <= kMaxLength); }
+
+    /**
+     * This method generates a Joiner ID from the Discerner.
+     *
+     * @param[out] aJoinerId   A reference to `Mac::ExtAddress` to output the generated Joiner ID.
+     *
+     */
+    void GenerateJoinerId(Mac::ExtAddress &aJoinerId) const;
+
+    /**
+     * This method indicates whether a given Joiner ID matches the Discerner.
+     *
+     * @param[in] aJoiner  A Joiner ID to match with the Discerner.
+     *
+     * @returns TRUE if the Joiner ID matches the Discerner, FALSE otherwise.
+     *
+     */
+    bool Matches(const Mac::ExtAddress &aJoinerId) const;
+
+    /**
+     * This method overloads operator `==` to evaluate whether or not two Joiner Discerner instances are equal.
+     *
+     * @param[in]  aOther  The other Joiner Discerner to compare with.
+     *
+     * @retval TRUE   If the two are equal.
+     * @retval FALSE  If the two are not equal.
+     *
+     */
+    bool operator==(const JoinerDiscerner &aOther) const;
+
+    /**
+     * This method overloads operator `!=` to evaluate whether or not two Joiner Discerner instances are equal.
+     *
+     * @param[in]  aOther  The other Joiner Discerner to compare with.
+     *
+     * @retval TRUE   If the two are not equal.
+     * @retval FALSE  If the two are equal.
+     *
+     */
+    bool operator!=(const JoinerDiscerner &aOther) const { return !(*this == aOther); }
+
+    /**
+     * This method converts the Joiner Discerner to a string.
+     *
+     * @returns An `InfoString` representation of Joiner Discerner.
+     *
+     */
+    InfoString ToString(void) const;
+
+private:
+    uint64_t GetMask(void) const { return (static_cast<uint64_t>(1ULL) << mLength) - 1; }
+    void     CopyTo(Mac::ExtAddress &aExtAddress) const;
+};
+
+/**
+ * This type represents Steering Data (bloom filter).
+ *
+ */
+class SteeringData : public otSteeringData
+{
+public:
+    enum
+    {
+        kMaxLength = OT_STEERING_DATA_MAX_LENGTH, ///< Maximum Steering Data length (in bytes).
+    };
+
+    /**
+     * This structure represents the hash bit index values for the bloom filter calculated from a Joiner ID.
+     *
+     * The first hash bit index is derived using CRC16-CCITT and second one using CRC16-ANSI.
+     *
+     */
+    struct HashBitIndexes
+    {
+        enum
+        {
+            kNumIndexes = 2, ///< Number of hash bit indexes.
+        };
+
+        uint16_t mIndex[kNumIndexes]; ///< The hash bit index array.
+    };
+
+    /**
+     * This method initializes the Steering Data and clears the bloom filter.
+     *
+     * @param[in]  aLength   The Steering Data length (in bytes) - MUST be smaller than or equal to `kMaxLength`.
+     *
+     */
+    void Init(uint8_t aLength = kMaxLength);
+
+    /**
+     * This method clears the bloom filter (all bits are cleared and no Joiner Id is accepted)..
+     *
+     * The Steering Data length (bloom filter length) is set to one byte with all bits cleared.
+     *
+     */
+    void Clear(void) { Init(1); }
+
+    /**
+     * This method sets the bloom filter to permit all Joiner IDs.
+     *
+     * To permit all Joiner IDs, The Steering Data length (bloom filter length) is set to one byte with all bits set.
+     *
+     */
+    void SetToPermitAllJoiners(void);
+
+    /**
+     * This method returns the Steering Data length (in bytes).
+     *
+     * @returns The Steering Data length (in bytes).
+     *
+     */
+    uint8_t GetLength(void) const { return mLength; }
+
+    /**
+     * This method gets the Steering Data buffer (bloom filter).
+     *
+     * @returns A pointer to the Steering Data buffer.
+     *
+     */
+    const uint8_t *GetData(void) const { return m8; }
+
+    /**
+     * This method gets the Steering Data buffer (bloom filter).
+     *
+     * @returns A pointer to the Steering Data buffer.
+     *
+     */
+    uint8_t *GetData(void) { return m8; }
+
+    /**
+     * This method updates the bloom filter adding the given Joiner ID.
+     *
+     * @param[in]  aJoinerId  The Joiner ID to add to bloom filter.
+     *
+     */
+    void UpdateBloomFilter(const Mac::ExtAddress &aJoinerId);
+
+    /**
+     * This method updates the bloom filter adding a given Joiner Discerner.
+     *
+     * @param[in]  aDiscerner  The Joiner Discerner to add to bloom filter.
+     *
+     */
+    void UpdateBloomFilter(const JoinerDiscerner &aDiscerner);
+
+    /**
+     * This method indicates whether the bloom filter is empty (all the bits are cleared).
+     *
+     * @returns TRUE if the bloom filter is empty, FALSE otherwise.
+     *
+     */
+    bool IsEmpty(void) const { return DoesAllMatch(0); }
+
+    /**
+     * This method indicates whether the bloom filter permits all Joiner IDs (all the bits are set).
+     *
+     * @returns TRUE if the bloom filter permits all Joiners IDs, FALSE otherwise.
+     *
+     */
+    bool PermitsAllJoiners(void) const { return (mLength > 0) && DoesAllMatch(kPermitAll); }
+
+    /**
+     * This method indicates whether the bloom filter contains a given Joiner ID.
+     *
+     * @param[in] aJoinerId  A Joiner ID.
+     *
+     * @returns TRUE if the bloom filter contains @p aJoinerId, FALSE otherwise.
+     *
+     */
+    bool Contains(const Mac::ExtAddress &aJoinerId) const;
+
+    /**
+     * This method indicates whether the bloom filter contains a given Joiner Discerner.
+     *
+     * @param[in] aDiscerner   A Joiner Discerner.
+     *
+     * @returns TRUE if the bloom filter contains @p aDiscerner, FALSE otherwise.
+     *
+     */
+    bool Contains(const JoinerDiscerner &aDiscerner) const;
+
+    /**
+     * This method indicates whether the bloom filter contains the hash bit indexes (derived from a Joiner ID).
+     *
+     * @param[in]  aIndexes   A hash bit index structure (derived from a Joiner ID).
+     *
+     * @returns TRUE if the bloom filter contains the Joiner ID mapping to @p aIndexes, FALSE otherwise.
+     *
+     */
+    bool Contains(const HashBitIndexes &aIndexes) const;
+
+    /**
+     * This static method calculates the bloom filter hash bit indexes from a given Joiner ID.
+     *
+     * The first hash bit index is derived using CRC16-CCITT and second one using CRC16-ANSI.
+     *
+     * @param[in]  aJoinerId  The Joiner ID to calculate the hash bit indexes.
+     * @param[out] aIndexes   A reference to a `HashBitIndexes` structure to output the calculated index values.
+     *
+     */
+    static void CalculateHashBitIndexes(const Mac::ExtAddress &aJoinerId, HashBitIndexes &aIndexes);
+
+    /**
+     * This static method calculates the bloom filter hash bit indexes from a given Joiner Discerner.
+     *
+     * The first hash bit index is derived using CRC16-CCITT and second one using CRC16-ANSI.
+     *
+     * @param[in]  aDiscerner     The Joiner Discerner to calculate the hash bit indexes.
+     * @param[out] aIndexes       A reference to a `HashBitIndexes` structure to output the calculated index values.
+     *
+     */
+    static void CalculateHashBitIndexes(const JoinerDiscerner &aDiscerner, HashBitIndexes &aIndexes);
+
+private:
+    enum
+    {
+        kPermitAll = 0xff,
+    };
+
+    uint8_t GetNumBits(void) const { return (mLength * CHAR_BIT); }
+
+    uint8_t BitIndex(uint8_t aBit) const { return (mLength - 1 - (aBit / CHAR_BIT)); }
+    uint8_t BitFlag(uint8_t aBit) const { return static_cast<uint8_t>(1U << (aBit % CHAR_BIT)); };
+
+    bool GetBit(uint8_t aBit) const { return (m8[BitIndex(aBit)] & BitFlag(aBit)) != 0; }
+    void SetBit(uint8_t aBit) { m8[BitIndex(aBit)] |= BitFlag(aBit); }
+    void ClearBit(uint8_t aBit) { m8[BitIndex(aBit)] &= ~BitFlag(aBit); }
+
+    bool DoesAllMatch(uint8_t aMatch) const;
+    void UpdateBloomFilter(const HashBitIndexes &aIndexes);
+};
+
+/**
+ * This function creates Message for MeshCoP.
  *
  */
 inline Coap::Message *NewMeshCoPMessage(Coap::CoapBase &aCoap)
 {
-    otMessageSettings settings = {true, static_cast<otMessagePriority>(kMeshCoPMessagePriority)};
-    return aCoap.NewMessage(&settings);
+    return aCoap.NewMessage(Message::Settings(Message::kWithLinkSecurity, Message::kPriorityNet));
 }
 
 /**
+ * This function generates PSKc.
+ *
+ * PSKc is used to establish the Commissioner Session.
+ *
+ * @param[in]  aPassPhrase   The commissioning passphrase.
+ * @param[in]  aNetworkName  The network name for PSKc computation.
+ * @param[in]  aExtPanId     The extended PAN ID for PSKc computation.
+ * @param[out] aPskc         A reference to a PSKc where the generated PSKc will be placed.
+ *
+ * @retval OT_ERROR_NONE          Successfully generate PSKc.
+ * @retval OT_ERROR_INVALID_ARGS  If the length of passphrase is out of range.
+ *
+ */
+otError GeneratePskc(const char *              aPassPhrase,
+                     const Mac::NetworkName &  aNetworkName,
+                     const Mac::ExtendedPanId &aExtPanId,
+                     Pskc &                    aPskc);
+
+/**
  * This function computes the Joiner ID from a factory-assigned IEEE EUI-64.
  *
  * @param[in]   aEui64     The factory-assigned IEEE EUI-64.
diff --git a/src/core/meshcop/meshcop_leader.cpp b/src/core/meshcop/meshcop_leader.cpp
new file mode 100644
index 0000000..173d233
--- /dev/null
+++ b/src/core/meshcop/meshcop_leader.cpp
@@ -0,0 +1,329 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements a MeshCoP Leader.
+ */
+
+#if OPENTHREAD_FTD
+
+#include "meshcop_leader.hpp"
+
+#include <stdio.h>
+
+#include "coap/coap_message.hpp"
+#include "common/code_utils.hpp"
+#include "common/instance.hpp"
+#include "common/locator-getters.hpp"
+#include "common/logging.hpp"
+#include "common/random.hpp"
+#include "meshcop/meshcop.hpp"
+#include "meshcop/meshcop_tlvs.hpp"
+#include "thread/thread_netif.hpp"
+#include "thread/thread_tlvs.hpp"
+#include "thread/thread_uri_paths.hpp"
+
+namespace ot {
+namespace MeshCoP {
+
+Leader::Leader(Instance &aInstance)
+    : InstanceLocator(aInstance)
+    , mPetition(OT_URI_PATH_LEADER_PETITION, Leader::HandlePetition, this)
+    , mKeepAlive(OT_URI_PATH_LEADER_KEEP_ALIVE, Leader::HandleKeepAlive, this)
+    , mTimer(aInstance, HandleTimer, this)
+    , mDelayTimerMinimal(DelayTimerTlv::kDelayTimerMinimal)
+    , mSessionId(Random::NonCrypto::GetUint16())
+{
+    Get<Coap::Coap>().AddResource(mPetition);
+    Get<Coap::Coap>().AddResource(mKeepAlive);
+}
+
+void Leader::HandlePetition(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
+{
+    static_cast<Leader *>(aContext)->HandlePetition(*static_cast<Coap::Message *>(aMessage),
+                                                    *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
+}
+
+void Leader::HandlePetition(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+    OT_UNUSED_VARIABLE(aMessageInfo);
+
+    CommissioningData data;
+    CommissionerIdTlv commissionerId;
+    StateTlv::State   state = StateTlv::kReject;
+
+    otLogInfoMeshCoP("received petition");
+
+    VerifyOrExit(Get<Mle::MleRouter>().IsRoutingLocator(aMessageInfo.GetPeerAddr()), OT_NOOP);
+    SuccessOrExit(Tlv::FindTlv(aMessage, Tlv::kCommissionerId, sizeof(commissionerId), commissionerId));
+
+    if (mTimer.IsRunning())
+    {
+        VerifyOrExit((commissionerId.GetCommissionerIdLength() == mCommissionerId.GetCommissionerIdLength()) &&
+                         (!strncmp(commissionerId.GetCommissionerId(), mCommissionerId.GetCommissionerId(),
+                                   commissionerId.GetCommissionerIdLength())),
+                     OT_NOOP);
+
+        ResignCommissioner();
+    }
+
+    data.mBorderAgentLocator.Init();
+    data.mBorderAgentLocator.SetBorderAgentLocator(aMessageInfo.GetPeerAddr().GetIid().GetLocator());
+
+    data.mCommissionerSessionId.Init();
+    data.mCommissionerSessionId.SetCommissionerSessionId(++mSessionId);
+
+    data.mSteeringData.Init();
+    data.mSteeringData.SetLength(1);
+    data.mSteeringData.Clear();
+
+    SuccessOrExit(
+        Get<NetworkData::Leader>().SetCommissioningData(reinterpret_cast<uint8_t *>(&data), data.GetLength()));
+
+    mCommissionerId = commissionerId;
+
+    if (mCommissionerId.GetLength() > CommissionerIdTlv::kMaxLength)
+    {
+        mCommissionerId.SetLength(CommissionerIdTlv::kMaxLength);
+    }
+
+    state = StateTlv::kAccept;
+    mTimer.Start(Time::SecToMsec(kTimeoutLeaderPetition));
+
+exit:
+    SendPetitionResponse(aMessage, aMessageInfo, state);
+}
+
+void Leader::SendPetitionResponse(const Coap::Message &   aRequest,
+                                  const Ip6::MessageInfo &aMessageInfo,
+                                  StateTlv::State         aState)
+{
+    otError        error = OT_ERROR_NONE;
+    Coap::Message *message;
+
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
+
+    SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
+    SuccessOrExit(error = message->SetPayloadMarker());
+
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, Tlv::kState, static_cast<uint8_t>(aState)));
+
+    if (mTimer.IsRunning())
+    {
+        SuccessOrExit(error = mCommissionerId.AppendTo(*message));
+    }
+
+    if (aState == StateTlv::kAccept)
+    {
+        SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kCommissionerSessionId, mSessionId));
+    }
+
+    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo));
+
+    otLogInfoMeshCoP("sent petition response");
+
+exit:
+
+    if (error != OT_ERROR_NONE)
+    {
+        otLogInfoMeshCoP("Failed to send petition response: %s", otThreadErrorToString(error));
+
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
+}
+
+void Leader::HandleKeepAlive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
+{
+    static_cast<Leader *>(aContext)->HandleKeepAlive(*static_cast<Coap::Message *>(aMessage),
+                                                     *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
+}
+
+void Leader::HandleKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+    uint8_t                state;
+    uint16_t               sessionId;
+    BorderAgentLocatorTlv *borderAgentLocator;
+    StateTlv::State        responseState;
+
+    otLogInfoMeshCoP("received keep alive");
+
+    SuccessOrExit(Tlv::FindUint8Tlv(aMessage, Tlv::kState, state));
+
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, Tlv::kCommissionerSessionId, sessionId));
+
+    borderAgentLocator = static_cast<BorderAgentLocatorTlv *>(
+        Get<NetworkData::Leader>().GetCommissioningDataSubTlv(Tlv::kBorderAgentLocator));
+
+    if ((borderAgentLocator == nullptr) || (sessionId != mSessionId))
+    {
+        responseState = StateTlv::kReject;
+    }
+    else if (state != StateTlv::kAccept)
+    {
+        responseState = StateTlv::kReject;
+        ResignCommissioner();
+    }
+    else
+    {
+        uint16_t rloc = aMessageInfo.GetPeerAddr().GetIid().GetLocator();
+
+        if (borderAgentLocator->GetBorderAgentLocator() != rloc)
+        {
+            borderAgentLocator->SetBorderAgentLocator(rloc);
+            Get<NetworkData::Leader>().IncrementVersion();
+        }
+
+        responseState = StateTlv::kAccept;
+        mTimer.Start(Time::SecToMsec(kTimeoutLeaderPetition));
+    }
+
+    SendKeepAliveResponse(aMessage, aMessageInfo, responseState);
+
+exit:
+    return;
+}
+
+void Leader::SendKeepAliveResponse(const Coap::Message &   aRequest,
+                                   const Ip6::MessageInfo &aMessageInfo,
+                                   StateTlv::State         aState)
+{
+    otError        error = OT_ERROR_NONE;
+    Coap::Message *message;
+
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
+
+    SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
+    SuccessOrExit(error = message->SetPayloadMarker());
+
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, Tlv::kState, static_cast<uint8_t>(aState)));
+
+    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo));
+
+    otLogInfoMeshCoP("sent keep alive response");
+
+exit:
+
+    if (error != OT_ERROR_NONE)
+    {
+        otLogWarnMeshCoP("Failed to send keep alive response: %s", otThreadErrorToString(error));
+
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
+}
+
+void Leader::SendDatasetChanged(const Ip6::Address &aAddress)
+{
+    otError          error = OT_ERROR_NONE;
+    Ip6::MessageInfo messageInfo;
+    Coap::Message *  message;
+
+    VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
+
+    SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_DATASET_CHANGED));
+
+    messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
+    messageInfo.SetPeerAddr(aAddress);
+    messageInfo.SetPeerPort(kCoapUdpPort);
+    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
+
+    otLogInfoMeshCoP("sent dataset changed");
+
+exit:
+
+    if (error != OT_ERROR_NONE)
+    {
+        otLogWarnMeshCoP("Failed to send dataset changed: %s", otThreadErrorToString(error));
+
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
+}
+
+otError Leader::SetDelayTimerMinimal(uint32_t aDelayTimerMinimal)
+{
+    otError error = OT_ERROR_NONE;
+    VerifyOrExit((aDelayTimerMinimal != 0 && aDelayTimerMinimal < DelayTimerTlv::kDelayTimerDefault),
+                 error = OT_ERROR_INVALID_ARGS);
+    mDelayTimerMinimal = aDelayTimerMinimal;
+
+exit:
+    return error;
+}
+
+uint32_t Leader::GetDelayTimerMinimal(void) const
+{
+    return mDelayTimerMinimal;
+}
+
+void Leader::HandleTimer(Timer &aTimer)
+{
+    aTimer.GetOwner<Leader>().HandleTimer();
+}
+
+void Leader::HandleTimer(void)
+{
+    VerifyOrExit(Get<Mle::MleRouter>().IsLeader(), OT_NOOP);
+
+    ResignCommissioner();
+
+exit:
+    return;
+}
+
+void Leader::SetEmptyCommissionerData(void)
+{
+    CommissionerSessionIdTlv mCommissionerSessionId;
+
+    mCommissionerSessionId.Init();
+    mCommissionerSessionId.SetCommissionerSessionId(++mSessionId);
+
+    IgnoreError(Get<NetworkData::Leader>().SetCommissioningData(reinterpret_cast<uint8_t *>(&mCommissionerSessionId),
+                                                                sizeof(Tlv) + mCommissionerSessionId.GetLength()));
+}
+
+void Leader::ResignCommissioner(void)
+{
+    mTimer.Stop();
+    SetEmptyCommissionerData();
+
+    otLogInfoMeshCoP("commissioner inactive");
+}
+
+} // namespace MeshCoP
+} // namespace ot
+
+#endif // OPENTHREAD_FTD
diff --git a/src/core/meshcop/meshcop_leader.hpp b/src/core/meshcop/meshcop_leader.hpp
new file mode 100644
index 0000000..25b8c02
--- /dev/null
+++ b/src/core/meshcop/meshcop_leader.hpp
@@ -0,0 +1,146 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for a MeshCoP Leader.
+ */
+
+#ifndef MESHCOP_LEADER_HPP_
+#define MESHCOP_LEADER_HPP_
+
+#include "openthread-core-config.h"
+
+#include "coap/coap.hpp"
+#include "common/locator.hpp"
+#include "common/timer.hpp"
+#include "meshcop/meshcop_tlvs.hpp"
+#include "net/udp6.hpp"
+#include "thread/mle.hpp"
+
+namespace ot {
+namespace MeshCoP {
+
+OT_TOOL_PACKED_BEGIN
+class CommissioningData
+{
+public:
+    uint8_t GetLength(void) const
+    {
+        return sizeof(Tlv) + mBorderAgentLocator.GetLength() + sizeof(Tlv) + mCommissionerSessionId.GetLength() +
+               sizeof(Tlv) + mSteeringData.GetLength();
+    }
+
+    BorderAgentLocatorTlv    mBorderAgentLocator;
+    CommissionerSessionIdTlv mCommissionerSessionId;
+    SteeringDataTlv          mSteeringData;
+} OT_TOOL_PACKED_END;
+
+class Leader : public InstanceLocator
+{
+public:
+    /**
+     * This constructor initializes the Leader object.
+     *
+     * @param[in]  aInstance     A reference to the OpenThread instance.
+     *
+     */
+    explicit Leader(Instance &aInstance);
+
+    /**
+     * This method sends a MGMT_DATASET_CHANGED message to commissioner.
+     *
+     * @param[in]  aAddress   The IPv6 address of destination.
+     *
+     */
+    void SendDatasetChanged(const Ip6::Address &aAddress);
+
+    /**
+     * This method sets minimal delay timer.
+     *
+     * @param[in]  aDelayTimerMinimal The value of minimal delay timer (in ms).
+     *
+     * @retval  OT_ERROR_NONE         Successfully set the minimal delay timer.
+     * @retval  OT_ERROR_INVALID_ARGS If @p aDelayTimerMinimal is not valid.
+     *
+     */
+    otError SetDelayTimerMinimal(uint32_t aDelayTimerMinimal);
+
+    /**
+     * This method gets minimal delay timer.
+     *
+     * @retval the minimal delay timer (in ms).
+     *
+     */
+    uint32_t GetDelayTimerMinimal(void) const;
+
+    /**
+     * This method sets empty Commissioner Data TLV in the Thread Network Data.
+     *
+     */
+    void SetEmptyCommissionerData(void);
+
+private:
+    enum
+    {
+        kTimeoutLeaderPetition = 50, ///< TIMEOUT_LEAD_PET (seconds)
+    };
+
+    static void HandleTimer(Timer &aTimer);
+    void        HandleTimer(void);
+
+    static void HandlePetition(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+    void        HandlePetition(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    void        SendPetitionResponse(const Coap::Message &   aRequest,
+                                     const Ip6::MessageInfo &aMessageInfo,
+                                     StateTlv::State         aState);
+
+    static void HandleKeepAlive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+    void        HandleKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    void        SendKeepAliveResponse(const Coap::Message &   aRequest,
+                                      const Ip6::MessageInfo &aMessageInfo,
+                                      StateTlv::State         aState);
+
+    static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+
+    void ResignCommissioner(void);
+
+    Coap::Resource mPetition;
+    Coap::Resource mKeepAlive;
+    TimerMilli     mTimer;
+
+    uint32_t mDelayTimerMinimal;
+
+    CommissionerIdTlv mCommissionerId;
+    uint16_t          mSessionId;
+};
+
+} // namespace MeshCoP
+} // namespace ot
+
+#endif // MESHCOP_LEADER_HPP_
diff --git a/src/core/meshcop/meshcop_tlvs.cpp b/src/core/meshcop/meshcop_tlvs.cpp
index 51d3e73..e209f9c 100644
--- a/src/core/meshcop/meshcop_tlvs.cpp
+++ b/src/core/meshcop/meshcop_tlvs.cpp
@@ -34,6 +34,7 @@
 #include "meshcop_tlvs.hpp"
 
 #include "common/debug.hpp"
+#include "meshcop/meshcop.hpp"
 
 namespace ot {
 namespace MeshCoP {
@@ -83,7 +84,32 @@
     return rval;
 }
 
-Mac::NetworkName::Data NetworkNameTlv::GetNetworkName(void) const
+const Tlv *Tlv::FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType)
+{
+    const Tlv *tlv;
+    const Tlv *end = reinterpret_cast<const Tlv *>(aTlvsStart + aTlvsLength);
+
+    for (tlv = reinterpret_cast<const Tlv *>(aTlvsStart); tlv < end; tlv = tlv->GetNext())
+    {
+        VerifyOrExit((tlv + 1) <= end, tlv = nullptr);
+        VerifyOrExit(!tlv->IsExtended() ||
+                         (reinterpret_cast<const ExtendedTlv *>(tlv) + 1 <= reinterpret_cast<const ExtendedTlv *>(end)),
+                     tlv = nullptr);
+        VerifyOrExit(tlv->GetNext() <= end, tlv = nullptr);
+
+        if (tlv->GetType() == aType)
+        {
+            ExitNow();
+        }
+    }
+
+    tlv = nullptr;
+
+exit:
+    return tlv;
+}
+
+Mac::NameData NetworkNameTlv::GetNetworkName(void) const
 {
     uint8_t len = GetLength();
 
@@ -92,10 +118,10 @@
         len = sizeof(mNetworkName);
     }
 
-    return Mac::NetworkName::Data(mNetworkName, len);
+    return Mac::NameData(mNetworkName, len);
 }
 
-void NetworkNameTlv::SetNetworkName(const Mac::NetworkName::Data &aNameData)
+void NetworkNameTlv::SetNetworkName(const Mac::NameData &aNameData)
 {
     uint8_t len;
 
@@ -103,46 +129,20 @@
     SetLength(len);
 }
 
-bool SteeringDataTlv::IsCleared(void) const
+void SteeringDataTlv::CopyTo(SteeringData &aSteeringData)
 {
-    bool rval = true;
-
-    for (uint8_t i = 0; i < GetLength(); i++)
-    {
-        if (mSteeringData[i] != 0)
-        {
-            rval = false;
-            break;
-        }
-    }
-
-    return rval;
-}
-
-void SteeringDataTlv::ComputeBloomFilter(const otExtAddress &aJoinerId)
-{
-    Crc16 ccitt(Crc16::kCcitt);
-    Crc16 ansi(Crc16::kAnsi);
-
-    for (size_t j = 0; j < sizeof(otExtAddress); j++)
-    {
-        uint8_t byte = aJoinerId.m8[j];
-        ccitt.Update(byte);
-        ansi.Update(byte);
-    }
-
-    SetBit(ccitt.Get() % GetNumBits());
-    SetBit(ansi.Get() % GetNumBits());
+    aSteeringData.Init(GetSteeringDataLength());
+    memcpy(aSteeringData.GetData(), mSteeringData, GetSteeringDataLength());
 }
 
 bool ChannelTlv::IsValid(void) const
 {
     bool ret = false;
 
-    VerifyOrExit(GetLength() == sizeof(*this) - sizeof(Tlv));
-    VerifyOrExit(mChannelPage <= OT_RADIO_CHANNEL_PAGE_MAX);
-    VerifyOrExit((1U << mChannelPage) & Radio::kSupportedChannelPages);
-    VerifyOrExit(Radio::kChannelMin <= GetChannel() && GetChannel() <= Radio::kChannelMax);
+    VerifyOrExit(GetLength() == sizeof(*this) - sizeof(Tlv), OT_NOOP);
+    VerifyOrExit(mChannelPage <= OT_RADIO_CHANNEL_PAGE_MAX, OT_NOOP);
+    VerifyOrExit((1U << mChannelPage) & Radio::kSupportedChannelPages, OT_NOOP);
+    VerifyOrExit(Radio::kChannelMin <= GetChannel() && GetChannel() <= Radio::kChannelMax, OT_NOOP);
     ret = true;
 
 exit:
@@ -173,12 +173,12 @@
 
 const ChannelMaskEntryBase *ChannelMaskBaseTlv::GetFirstEntry(void) const
 {
-    const ChannelMaskEntryBase *entry = NULL;
+    const ChannelMaskEntryBase *entry = nullptr;
 
-    VerifyOrExit(GetLength() >= sizeof(ChannelMaskEntryBase));
+    VerifyOrExit(GetLength() >= sizeof(ChannelMaskEntryBase), OT_NOOP);
 
     entry = reinterpret_cast<const ChannelMaskEntryBase *>(GetValue());
-    VerifyOrExit(GetLength() >= entry->GetEntrySize(), entry = NULL);
+    VerifyOrExit(GetLength() >= entry->GetEntrySize(), entry = nullptr);
 
 exit:
     return entry;
@@ -199,7 +199,7 @@
 #if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
     if (aChannelMask & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK)
     {
-        assert(entry != NULL);
+        OT_ASSERT(entry != nullptr);
         entry->Init();
         entry->SetChannelPage(OT_RADIO_CHANNEL_PAGE_2);
         entry->SetMask(aChannelMask & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK);
@@ -213,7 +213,7 @@
 #if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
     if (aChannelMask & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK)
     {
-        assert(entry != NULL);
+        OT_ASSERT(entry != nullptr);
         entry->Init();
         entry->SetChannelPage(OT_RADIO_CHANNEL_PAGE_0);
         entry->SetMask(aChannelMask & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK);
@@ -233,7 +233,7 @@
 
     for (; cur < end; cur = static_cast<const ChannelMaskEntry *>(cur->GetNext()))
     {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
+        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, OT_NOOP);
 
 #if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
         if (cur->GetChannelPage() == OT_RADIO_CHANNEL_PAGE_2)
@@ -260,7 +260,7 @@
     uint16_t offset;
     uint16_t end;
 
-    SuccessOrExit(GetValueOffset(aMessage, kChannelMask, offset, end));
+    SuccessOrExit(FindTlvValueOffset(aMessage, kChannelMask, offset, end));
     end += offset;
 
     while (offset + sizeof(ChannelMaskEntryBase) <= end)
@@ -268,7 +268,7 @@
         ChannelMaskEntry entry;
 
         aMessage.Read(offset, sizeof(ChannelMaskEntryBase), &entry);
-        VerifyOrExit(offset + entry.GetEntrySize() <= end);
+        VerifyOrExit(offset + entry.GetEntrySize() <= end, OT_NOOP);
 
         switch (entry.GetChannelPage())
         {
diff --git a/src/core/meshcop/meshcop_tlvs.hpp b/src/core/meshcop/meshcop_tlvs.hpp
index eb7c53a..92a8fa8 100644
--- a/src/core/meshcop/meshcop_tlvs.hpp
+++ b/src/core/meshcop/meshcop_tlvs.hpp
@@ -41,7 +41,6 @@
 #include <openthread/dataset.h>
 #include <openthread/platform/radio.h>
 
-#include "common/crc16.hpp"
 #include "common/encoding.hpp"
 #include "common/message.hpp"
 #include "common/string.hpp"
@@ -51,11 +50,11 @@
 #include "net/ip6_address.hpp"
 #include "radio/radio.hpp"
 #include "thread/key_manager.hpp"
+#include "thread/mle_types.hpp"
 
 namespace ot {
 namespace MeshCoP {
 
-using ot::Encoding::Reverse32;
 using ot::Encoding::BigEndian::HostSwap16;
 using ot::Encoding::BigEndian::HostSwap32;
 
@@ -158,26 +157,34 @@
      * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
      *
      */
-    static otError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv)
+    static otError FindTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv)
     {
-        return ot::Tlv::Get(aMessage, static_cast<uint8_t>(aType), aMaxLength, aTlv);
+        return ot::Tlv::FindTlv(aMessage, static_cast<uint8_t>(aType), aMaxLength, aTlv);
     }
 
     /**
-     * This static method finds the offset and length of a given TLV type.
+     * This static method searches for a TLV with a given type in a message, ensures its length is same or larger than
+     * an expected minimum value, and then reads its value into a given buffer.
      *
-     * @param[in]   aMessage    A reference to the message.
-     * @param[in]   aType       The Type value to search for.
-     * @param[out]  aOffset     The offset where the value starts.
-     * @param[out]  aLength     The length of the value.
+     * If the TLV length is smaller than the minimum length @p aLength, the TLV is considered invalid. In this case,
+     * this method returns `OT_ERROR_PARSE` and the @p aValue buffer is not updated.
      *
-     * @retval OT_ERROR_NONE       Successfully found the TLV.
+     * If the TLV length is larger than @p aLength, the TLV is considered valid, but only the first @p aLength bytes
+     * of the value are read and copied into the @p aValue buffer.
+     *
+     * @param[in]    aMessage    A reference to the message.
+     * @param[in]    aType       The TLV type to search for.
+     * @param[out]   aValue      A buffer to output the value (must contain at least @p aLength bytes).
+     * @param[in]    aLength     The expected (minimum) length of the TLV value.
+     *
+     * @retval OT_ERROR_NONE       The TLV was found and read successfully. @p aValue is updated.
      * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
+     * @retval OT_ERROR_PARSE      TLV was found but it was not well-formed and could not be parsed.
      *
      */
-    static otError GetValueOffset(const Message &aMessage, Type aType, uint16_t &aOffset, uint16_t &aLength)
+    static otError FindTlv(const Message &aMessage, Type aType, void *aValue, uint8_t aLength)
     {
-        return ot::Tlv::GetValueOffset(aMessage, static_cast<uint8_t>(aType), aOffset, aLength);
+        return ot::Tlv::FindTlv(aMessage, aType, aValue, aLength);
     }
 
     /**
@@ -190,6 +197,63 @@
      */
     static bool IsValid(const Tlv &aTlv);
 
+    /**
+     * This static method searches in a given sequence of TLVs to find the first TLV with a given template Type.
+     *
+     * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
+     * @param[in]  aType       The TLV Type to search for.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    static Tlv *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType)
+    {
+        return const_cast<Tlv *>(FindTlv(const_cast<const uint8_t *>(aTlvsStart), aTlvsLength, aType));
+    }
+
+    /**
+     * This static method searches in a given sequence of TLVs to find the first TLV with a given template Type.
+     *
+     * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
+     * @param[in]  aType       The TLV Type to search for.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    static const Tlv *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType);
+
+    /**
+     * This static template method searches in a given sequence of TLVs to find the first TLV with a give template
+     * `TlvType`.
+     *
+     * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    template <typename TlvType> static TlvType *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength)
+    {
+        return static_cast<TlvType *>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::Type>(TlvType::kType)));
+    }
+
+    /**
+     * This static template method searches in a given sequence of TLVs to find the first TLV with a give template
+     * `TlvType`.
+     *
+     * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    template <typename TlvType> static const TlvType *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength)
+    {
+        return static_cast<const TlvType *>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::Type>(TlvType::kType)));
+    }
+
 } OT_TOOL_PACKED_END;
 
 /**
@@ -225,6 +289,11 @@
 class ChannelTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kChannel, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -290,6 +359,11 @@
 class PanIdTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kPanId, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -337,6 +411,11 @@
 class ExtendedPanIdTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kExtendedPanId, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -384,6 +463,11 @@
 class NetworkNameTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kNetworkName, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -406,18 +490,18 @@
     /**
      * This method gets the Network Name value.
      *
-     * @returns The Network Name value (as `NetworkName::Data`).
+     * @returns The Network Name value (as `NameData`).
      *
      */
-    Mac::NetworkName::Data GetNetworkName(void) const;
+    Mac::NameData GetNetworkName(void) const;
 
     /**
      * This method sets the Network Name value.
      *
-     * @param[in] aNameData   A Network Name value (as `NetworkName::Data`).
+     * @param[in] aNameData   A Network Name value (as `NameData`).
      *
      */
-    void SetNetworkName(const Mac::NetworkName::Data &aNameData);
+    void SetNetworkName(const Mac::NameData &aNameData);
 
 private:
     char mNetworkName[Mac::NetworkName::kMaxSize];
@@ -431,6 +515,11 @@
 class PskcTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kPskc, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -478,6 +567,11 @@
 class NetworkMasterKeyTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kNetworkMasterKey, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -525,6 +619,11 @@
 class NetworkKeySequenceTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kNetworkKeySequence, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -572,6 +671,11 @@
 class MeshLocalPrefixTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kMeshLocalPrefix, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -605,7 +709,7 @@
      * @returns The Mesh Local Prefix value.
      *
      */
-    const otMeshLocalPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; }
+    const Mle::MeshLocalPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; }
 
     /**
      * This method sets the Mesh Local Prefix value.
@@ -613,12 +717,14 @@
      * @param[in]  aMeshLocalPrefix  A pointer to the Mesh Local Prefix value.
      *
      */
-    void SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix) { mMeshLocalPrefix = aMeshLocalPrefix; }
+    void SetMeshLocalPrefix(const Mle::MeshLocalPrefix &aMeshLocalPrefix) { mMeshLocalPrefix = aMeshLocalPrefix; }
 
 private:
-    otMeshLocalPrefix mMeshLocalPrefix;
+    Mle::MeshLocalPrefix mMeshLocalPrefix;
 } OT_TOOL_PACKED_END;
 
+class SteeringData;
+
 /**
  * This class implements Steering Data TLV generation and parsing.
  *
@@ -627,6 +733,11 @@
 class SteeringDataTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kSteeringData, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -665,88 +776,12 @@
     void Clear(void) { memset(mSteeringData, 0, GetSteeringDataLength()); }
 
     /**
-     * Ths method sets all bits in the Bloom Filter to one.
+     * This method copies the Steering Data from the TLV into a given `SteeringData` variable.
+     *
+     * @param[out]  aSteeringData   A reference to a `SteeringData` to copy into.
      *
      */
-    void Set(void) { memset(mSteeringData, 0xff, GetSteeringDataLength()); }
-
-    /**
-     * Ths method indicates whether or not the SteeringData allows all Joiners.
-     *
-     * @retval TRUE   If the SteeringData allows all Joiners.
-     * @retval FALSE  If the SteeringData doesn't allow any Joiner.
-     *
-     */
-    bool DoesAllowAny(void)
-    {
-        bool rval = true;
-
-        for (uint8_t i = 0; i < GetSteeringDataLength(); i++)
-        {
-            if (mSteeringData[i] != 0xff)
-            {
-                rval = false;
-                break;
-            }
-        }
-
-        return rval;
-    }
-
-    /**
-     * This method returns the number of bits in the Bloom Filter.
-     *
-     * @returns The number of bits in the Bloom Filter.
-     *
-     */
-    uint8_t GetNumBits(void) const { return GetSteeringDataLength() * 8; }
-
-    /**
-     * This method indicates whether or not bit @p aBit is set.
-     *
-     * @param[in]  aBit  The bit offset.
-     *
-     * @retval TRUE   If bit @p aBit is set.
-     * @retval FALSE  If bit @p aBit is not set.
-     *
-     */
-    bool GetBit(uint8_t aBit) const
-    {
-        return (mSteeringData[GetSteeringDataLength() - 1 - (aBit / 8)] & (1 << (aBit % 8))) != 0;
-    }
-
-    /**
-     * This method clears bit @p aBit.
-     *
-     * @param[in]  aBit  The bit offset.
-     *
-     */
-    void ClearBit(uint8_t aBit) { mSteeringData[GetSteeringDataLength() - 1 - (aBit / 8)] &= ~(1 << (aBit % 8)); }
-
-    /**
-     * This method sets bit @p aBit.
-     *
-     * @param[in]  aBit  The bit offset.
-     *
-     */
-    void SetBit(uint8_t aBit) { mSteeringData[GetSteeringDataLength() - 1 - (aBit / 8)] |= 1 << (aBit % 8); }
-
-    /**
-     * Ths method indicates whether or not the SteeringData is all zeros.
-     *
-     * @retval TRUE   If the SteeringData is all zeros.
-     * @retval FALSE  If the SteeringData isn't all zeros.
-     *
-     */
-    bool IsCleared(void) const;
-
-    /**
-     * This method computes the Bloom Filter.
-     *
-     * @param[in]  aJoinerId  The Joiner ID.
-     *
-     */
-    void ComputeBloomFilter(const otExtAddress &aJoinerId);
+    void CopyTo(SteeringData &aSteeringData);
 
 private:
     uint8_t mSteeringData[OT_STEERING_DATA_MAX_LENGTH];
@@ -760,6 +795,11 @@
 class BorderAgentLocatorTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kBorderAgentLocator, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -809,7 +849,8 @@
 public:
     enum
     {
-        kMaxLength = 64, ///< maximum length (bytes)
+        kType      = kCommissionerId, ///< The TLV Type.
+        kMaxLength = 64,              ///< maximum length (bytes)
     };
 
     /**
@@ -866,6 +907,11 @@
 class CommissionerSessionIdTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kCommissionerSessionId, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -913,6 +959,11 @@
 class SecurityPolicyTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kSecurityPolicy, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -986,6 +1037,11 @@
 class ActiveTimestampTlv : public Tlv, public Timestamp
 {
 public:
+    enum
+    {
+        kType = kActiveTimestamp, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1008,53 +1064,6 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements Commissioner UDP Port TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class CommissionerUdpPortTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kCommissionerUdpPort);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the UDP Port value.
-     *
-     * @returns The UDP Port value.
-     *
-     */
-    uint16_t GetUdpPort(void) const { return HostSwap16(mUdpPort); }
-
-    /**
-     * This method sets the UDP Port value.
-     *
-     * @param[in]  aUdpPort  The UDP Port value.
-     *
-     */
-    void SetUdpPort(uint16_t aUdpPort) { mUdpPort = HostSwap16(aUdpPort); }
-
-private:
-    uint16_t mUdpPort;
-} OT_TOOL_PACKED_END;
-
-/**
  * This class implements State TLV generation and parsing.
  *
  */
@@ -1062,6 +1071,11 @@
 class StateTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kState, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1087,9 +1101,9 @@
      */
     enum State
     {
-        kReject  = -1, ///< Reject
-        kPending = 0,  ///< Pending
-        kAccept  = 1,  ///< Accept
+        kReject  = 0xff, ///< Reject (-1)
+        kPending = 0,    ///< Pending
+        kAccept  = 1,    ///< Accept
     };
 
     /**
@@ -1120,6 +1134,11 @@
 class JoinerUdpPortTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kJoinerUdpPort, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1160,147 +1179,6 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements Joiner IID TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class JoinerIidTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kJoinerIid);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns a pointer to the Joiner IID.
-     *
-     * @returns A pointer to the Joiner IID.
-     *
-     */
-    const uint8_t *GetIid(void) const { return mIid; }
-
-    /**
-     * This method sets the Joiner IID.
-     *
-     * @param[in]  aIid  A pointer to the Joiner IID.
-     *
-     */
-    void SetIid(const uint8_t *aIid) { memcpy(mIid, aIid, sizeof(mIid)); }
-
-private:
-    uint8_t mIid[8];
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Joiner Router Locator TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class JoinerRouterLocatorTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kJoinerRouterLocator);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Joiner Router Locator value.
-     *
-     * @returns The Joiner Router Locator value.
-     *
-     */
-    uint16_t GetJoinerRouterLocator(void) const { return HostSwap16(mLocator); }
-
-    /**
-     * This method sets the Joiner Router Locator value.
-     *
-     * @param[in]  aJoinerRouterLocator  The Joiner Router Locator value.
-     *
-     */
-    void SetJoinerRouterLocator(uint16_t aLocator) { mLocator = HostSwap16(aLocator); }
-
-private:
-    uint16_t mLocator;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Joiner Router KEK TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class JoinerRouterKekTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kJoinerRouterKek);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns a pointer to the Joiner Router KEK.
-     *
-     * @returns A pointer to the Joiner Router KEK.
-     *
-     */
-    const uint8_t *GetKek(void) const { return mKek; }
-
-    /**
-     * This method sets the Joiner Router KEK.
-     *
-     * @param[in]  aIid  A pointer to the Joiner Router KEK.
-     *
-     */
-    void SetKek(const uint8_t *aKek) { memcpy(mKek, aKek, sizeof(mKek)); }
-
-private:
-    uint8_t mKek[16];
-} OT_TOOL_PACKED_END;
-
-/**
  * This class implements Pending Timestamp TLV generation and parsing.
  *
  */
@@ -1308,6 +1186,11 @@
 class PendingTimestampTlv : public Tlv, public Timestamp
 {
 public:
+    enum
+    {
+        kType = kPendingTimestamp, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1337,6 +1220,11 @@
 class DelayTimerTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kDelayTimer, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1540,7 +1428,7 @@
      * @returns The Channel Mask value.
      *
      */
-    uint32_t GetMask(void) const { return Reverse32(HostSwap32(mMask)); }
+    uint32_t GetMask(void) const { return Encoding::Reverse32(HostSwap32(mMask)); }
 
     /**
      * This method sets the Channel Mask value.
@@ -1548,7 +1436,7 @@
      * @param[in]  aMask  The Channel Mask value.
      *
      */
-    void SetMask(uint32_t aMask) { mMask = HostSwap32(Reverse32(aMask)); }
+    void SetMask(uint32_t aMask) { mMask = HostSwap32(Encoding::Reverse32(aMask)); }
 
 private:
     uint32_t mMask;
@@ -1562,6 +1450,11 @@
 class ChannelMaskBaseTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kChannelMask, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1584,7 +1477,7 @@
     /**
      * This method gets the first Channel Mask Entry in the Channel Mask TLV.
      *
-     * @returns A pointer to first Channel Mask Entry or NULL if not found.
+     * @returns A pointer to first Channel Mask Entry or nullptr if not found.
      *
      */
     const ChannelMaskEntryBase *GetFirstEntry(void) const;
@@ -1592,7 +1485,7 @@
     /**
      * This method gets the first Channel Mask Entry in the Channel Mask TLV.
      *
-     * @returns A pointer to first Channel Mask Entry or NULL if not found.
+     * @returns A pointer to first Channel Mask Entry or nullptr if not found.
      *
      */
     ChannelMaskEntryBase *GetFirstEntry(void);
@@ -1653,147 +1546,6 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements Count TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class CountTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kCount);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Count value.
-     *
-     * @returns The Count value.
-     *
-     */
-    uint8_t GetCount(void) const { return mCount; }
-
-    /**
-     * This method sets the Count value.
-     *
-     * @param[in]  aCount  The Count value.
-     *
-     */
-    void SetCount(uint8_t aCount) { mCount = aCount; }
-
-private:
-    uint8_t mCount;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Period TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class PeriodTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kPeriod);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Period value.
-     *
-     * @returns The Period value.
-     *
-     */
-    uint16_t GetPeriod(void) const { return HostSwap16(mPeriod); }
-
-    /**
-     * This method sets the Period value.
-     *
-     * @param[in]  aPeriod  The Period value.
-     *
-     */
-    void SetPeriod(uint16_t aPeriod) { mPeriod = HostSwap16(aPeriod); }
-
-private:
-    uint16_t mPeriod;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Scan Duration TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ScanDurationTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kScanDuration);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Scan Duration value.
-     *
-     * @returns The Scan Duration value.
-     *
-     */
-    uint16_t GetScanDuration(void) const { return HostSwap16(mScanDuration); }
-
-    /**
-     * This method sets the Scan Duration value.
-     *
-     * @param[in]  aScanDuration  The Scan Duration value.
-     *
-     */
-    void SetScanDuration(uint16_t aScanDuration) { mScanDuration = HostSwap16(aScanDuration); }
-
-private:
-    uint16_t mScanDuration;
-} OT_TOOL_PACKED_END;
-
-/**
  * This class implements Energy List TLV generation and parsing.
  *
  */
@@ -1801,6 +1553,11 @@
 class EnergyListTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kEnergyList, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1831,7 +1588,8 @@
 public:
     enum
     {
-        kMaxLength = OT_PROVISIONING_URL_MAX_SIZE, // Maximum number of chars in the Provisioning URL string.
+        kType      = kProvisioningUrl,             ///< The TLV Type.
+        kMaxLength = OT_PROVISIONING_URL_MAX_SIZE, ///< Maximum number of chars in the Provisioning URL string.
     };
 
     /**
@@ -1893,6 +1651,11 @@
 class VendorNameTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kVendorName, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1930,7 +1693,7 @@
      */
     void SetVendorName(const char *aVendorName)
     {
-        uint16_t len = (aVendorName == NULL) ? 0 : StringLength(aVendorName, sizeof(mVendorName));
+        uint16_t len = (aVendorName == nullptr) ? 0 : StringLength(aVendorName, sizeof(mVendorName));
 
         SetLength(static_cast<uint8_t>(len));
 
@@ -1957,6 +1720,11 @@
 class VendorModelTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kVendorModel, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -1994,7 +1762,7 @@
      */
     void SetVendorModel(const char *aVendorModel)
     {
-        uint16_t len = (aVendorModel == NULL) ? 0 : StringLength(aVendorModel, sizeof(mVendorModel));
+        uint16_t len = (aVendorModel == nullptr) ? 0 : StringLength(aVendorModel, sizeof(mVendorModel));
 
         SetLength(static_cast<uint8_t>(len));
 
@@ -2021,6 +1789,11 @@
 class VendorSwVersionTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kVendorSwVersion, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -2058,7 +1831,7 @@
      */
     void SetVendorSwVersion(const char *aVendorSwVersion)
     {
-        uint16_t len = (aVendorSwVersion == NULL) ? 0 : StringLength(aVendorSwVersion, sizeof(mVendorSwVersion));
+        uint16_t len = (aVendorSwVersion == nullptr) ? 0 : StringLength(aVendorSwVersion, sizeof(mVendorSwVersion));
 
         SetLength(static_cast<uint8_t>(len));
 
@@ -2085,6 +1858,11 @@
 class VendorDataTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kVendorData, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -2122,7 +1900,7 @@
      */
     void SetVendorData(const char *aVendorData)
     {
-        uint16_t len = (aVendorData == NULL) ? 0 : StringLength(aVendorData, sizeof(mVendorData));
+        uint16_t len = (aVendorData == nullptr) ? 0 : StringLength(aVendorData, sizeof(mVendorData));
 
         SetLength(static_cast<uint8_t>(len));
 
@@ -2149,6 +1927,11 @@
 class VendorStackVersionTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kVendorStackVersion, ///< The TLV Type.
+    };
+
     /**
      * Default constructor.
      *
@@ -2303,44 +2086,6 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements IPv6 Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class IPv6AddressTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kIPv6Address);
-        SetLength(sizeof(mAddress));
-    }
-
-    /**
-     * This method returns the IPv6 Address.
-     *
-     * @returns A reference to the IPv6 Address.
-     *
-     */
-    const Ip6::Address &GetAddress(void) const { return mAddress; }
-
-    /**
-     * This method sets the IPv6 Address.
-     *
-     * @param[in]   aAddress    A reference to the IPv6 Address.
-     *
-     */
-    void SetAddress(const Ip6::Address &aAddress) { mAddress = aAddress; }
-
-private:
-    Ip6::Address mAddress;
-} OT_TOOL_PACKED_END;
-
-/**
  * This class implements UDP Encapsulation TLV generation and parsing.
  *
  */
@@ -2348,6 +2093,11 @@
 class UdpEncapsulationTlv : public ExtendedTlv
 {
 public:
+    enum
+    {
+        kType = MeshCoP::Tlv::kUdpEncapsulation, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -2428,6 +2178,11 @@
 class DiscoveryRequestTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kDiscoveryRequest, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -2515,6 +2270,11 @@
 class DiscoveryResponseTlv : public Tlv
 {
 public:
+    enum
+    {
+        kType = kDiscoveryResponse, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
diff --git a/src/core/meshcop/panid_query_client.cpp b/src/core/meshcop/panid_query_client.cpp
index da76a42..217ef78 100644
--- a/src/core/meshcop/panid_query_client.cpp
+++ b/src/core/meshcop/panid_query_client.cpp
@@ -50,8 +50,8 @@
 
 PanIdQueryClient::PanIdQueryClient(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mCallback(NULL)
-    , mContext(NULL)
+    , mCallback(nullptr)
+    , mContext(nullptr)
     , mPanIdQuery(OT_URI_PATH_PANID_CONFLICT, &PanIdQueryClient::HandleConflict, this)
 {
     Get<Coap::Coap>().AddResource(mPanIdQuery);
@@ -63,32 +63,27 @@
                                     otCommissionerPanIdConflictCallback aCallback,
                                     void *                              aContext)
 {
-    otError                           error = OT_ERROR_NONE;
-    MeshCoP::CommissionerSessionIdTlv sessionId;
-    MeshCoP::ChannelMaskTlv           channelMask;
-    MeshCoP::PanIdTlv                 panId;
-    Ip6::MessageInfo                  messageInfo;
-    Coap::Message *                   message = NULL;
+    otError                 error = OT_ERROR_NONE;
+    MeshCoP::ChannelMaskTlv channelMask;
+    Ip6::MessageInfo        messageInfo;
+    Coap::Message *         message = nullptr;
 
     VerifyOrExit(Get<MeshCoP::Commissioner>().IsActive(), error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error =
                       message->Init(aAddress.IsMulticast() ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE,
                                     OT_COAP_CODE_POST, OT_URI_PATH_PANID_QUERY));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    sessionId.Init();
-    sessionId.SetCommissionerSessionId(Get<MeshCoP::Commissioner>().GetSessionId());
-    SuccessOrExit(error = sessionId.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kCommissionerSessionId,
+                                               Get<MeshCoP::Commissioner>().GetSessionId()));
 
     channelMask.Init();
     channelMask.SetChannelMask(aChannelMask);
     SuccessOrExit(error = channelMask.AppendTo(*message));
 
-    panId.Init();
-    panId.SetPanId(aPanId);
-    SuccessOrExit(error = panId.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kPanId, aPanId));
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetPeerAddr(aAddress);
@@ -102,7 +97,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -118,22 +113,21 @@
 
 void PanIdQueryClient::HandleConflict(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    MeshCoP::PanIdTlv panId;
-    Ip6::MessageInfo  responseInfo(aMessageInfo);
-    uint32_t          mask;
+    uint16_t         panId;
+    Ip6::MessageInfo responseInfo(aMessageInfo);
+    uint32_t         mask;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
     otLogInfoMeshCoP("received panid conflict");
 
-    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPanId, sizeof(panId), panId));
-    VerifyOrExit(panId.IsValid());
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, MeshCoP::Tlv::kPanId, panId));
 
-    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
+    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0, OT_NOOP);
 
-    if (mCallback != NULL)
+    if (mCallback != nullptr)
     {
-        mCallback(panId.GetPanId(), mask, mContext);
+        mCallback(panId, mask, mContext);
     }
 
     SuccessOrExit(Get<Coap::Coap>().SendEmptyAck(aMessage, responseInfo));
diff --git a/src/core/meshcop/timestamp.hpp b/src/core/meshcop/timestamp.hpp
index 03cd3eb..4149cd6 100644
--- a/src/core/meshcop/timestamp.hpp
+++ b/src/core/meshcop/timestamp.hpp
@@ -47,6 +47,7 @@
 namespace MeshCoP {
 
 using ot::Encoding::BigEndian::HostSwap16;
+using ot::Encoding::BigEndian::HostSwap32;
 
 /**
  * This class implements Timestamp generation and parsing.
@@ -60,11 +61,7 @@
      * This method initializes the Timestamp
      *
      */
-    void Init(void)
-    {
-        memset(mSeconds, 0, sizeof(mSeconds));
-        mTicks = 0;
-    }
+    void Init(void) { memset(this, 0, sizeof(*this)); }
 
     /**
      * This method compares this timestamp to another.
@@ -86,14 +83,7 @@
      */
     uint64_t GetSeconds(void) const
     {
-        uint64_t seconds = 0;
-
-        for (size_t i = 0; i < sizeof(mSeconds); i++)
-        {
-            seconds = (seconds << 8) | mSeconds[i];
-        }
-
-        return seconds;
+        return (static_cast<uint64_t>(HostSwap16(mSeconds16)) << 32) + HostSwap32(mSeconds32);
     }
 
     /**
@@ -104,10 +94,8 @@
      */
     void SetSeconds(uint64_t aSeconds)
     {
-        for (size_t i = 0; i < sizeof(mSeconds); i++, aSeconds >>= 8)
-        {
-            mSeconds[sizeof(mSeconds) - 1 - i] = aSeconds & 0xff;
-        }
+        mSeconds16 = HostSwap16(static_cast<uint16_t>(aSeconds >> 32));
+        mSeconds32 = HostSwap32(static_cast<uint32_t>(aSeconds & 0xffffffff));
     }
 
     /**
@@ -150,8 +138,6 @@
     }
 
 private:
-    uint8_t mSeconds[6];
-
     enum
     {
         kTicksOffset         = 1,
@@ -159,6 +145,9 @@
         kAuthoritativeOffset = 0,
         kAuthoritativeMask   = 1 << kAuthoritativeOffset,
     };
+
+    uint16_t mSeconds16; // bits 32-47
+    uint32_t mSeconds32; // bits 0-31
     uint16_t mTicks;
 } OT_TOOL_PACKED_END;
 
diff --git a/src/core/net/dhcp6_client.cpp b/src/core/net/dhcp6_client.cpp
index b39298b..63faa1c 100644
--- a/src/core/net/dhcp6_client.cpp
+++ b/src/core/net/dhcp6_client.cpp
@@ -53,10 +53,10 @@
 
 Dhcp6Client::Dhcp6Client(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mSocket(Get<Ip6::Udp>())
-    , mTrickleTimer(aInstance, &Dhcp6Client::HandleTrickleTimer, NULL, this)
+    , mSocket(aInstance)
+    , mTrickleTimer(aInstance, Dhcp6Client::HandleTrickleTimer, nullptr, this)
     , mStartTime(0)
-    , mIdentityAssociationCurrent(NULL)
+    , mIdentityAssociationCurrent(nullptr)
 {
     memset(mIdentityAssociations, 0, sizeof(mIdentityAssociations));
 }
@@ -70,13 +70,13 @@
 
 void Dhcp6Client::UpdateAddresses(void)
 {
-    bool                            found    = false;
-    bool                            newAgent = false;
+    bool                            found          = false;
+    bool                            doesAgentExist = false;
     NetworkData::Iterator           iterator;
     NetworkData::OnMeshPrefixConfig config;
 
     // remove addresses directly if prefix not valid in network data
-    for (uint8_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); i++)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); i++)
     {
         IdentityAssociation &ia = mIdentityAssociations[i];
 
@@ -114,21 +114,22 @@
 
     while (Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, config) == OT_ERROR_NONE)
     {
-        IdentityAssociation *ia = NULL;
+        IdentityAssociation *ia = nullptr;
 
         if (!config.mDhcp)
         {
             continue;
         }
 
-        found = false;
+        doesAgentExist = true;
+        found          = false;
 
-        for (uint8_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); i++)
+        for (size_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); i++)
         {
             if (mIdentityAssociations[i].mStatus == kIaStatusInvalid)
             {
                 // record an available ia
-                if (ia == NULL)
+                if (ia == nullptr)
                 {
                     ia = &mIdentityAssociations[i];
                 }
@@ -136,29 +137,31 @@
             else if (MatchNetifAddressWithPrefix(mIdentityAssociations[i].mNetifAddress, config.mPrefix))
             {
                 found = true;
+                ia    = &mIdentityAssociations[i];
                 break;
             }
         }
 
         if (!found)
         {
-            if (ia != NULL)
+            if (ia != nullptr)
             {
-                ia->mPrefixAgentRloc            = config.mRloc16;
                 ia->mNetifAddress.mAddress      = config.mPrefix.mPrefix;
                 ia->mNetifAddress.mPrefixLength = config.mPrefix.mLength;
                 ia->mStatus                     = kIaStatusSolicit;
                 ia->mValidLifetime              = 0;
-                newAgent                        = true;
             }
             else
             {
                 otLogWarnIp6("Insufficient memory for new DHCP prefix");
+                continue;
             }
         }
+
+        ia->mPrefixAgentRloc = config.mRloc16;
     }
 
-    if (newAgent)
+    if (doesAgentExist)
     {
         Start();
     }
@@ -172,16 +175,21 @@
 {
     Ip6::SockAddr sockaddr;
 
+    VerifyOrExit(!mSocket.IsBound(), OT_NOOP);
+
     sockaddr.mPort = kDhcpClientPort;
-    mSocket.Open(&Dhcp6Client::HandleUdpReceive, this);
-    mSocket.Bind(sockaddr);
+    IgnoreError(mSocket.Open(&Dhcp6Client::HandleUdpReceive, this));
+    IgnoreError(mSocket.Bind(sockaddr));
 
     ProcessNextIdentityAssociation();
+
+exit:
+    return;
 }
 
 void Dhcp6Client::Stop(void)
 {
-    mSocket.Close();
+    IgnoreError(mSocket.Close());
 }
 
 bool Dhcp6Client::ProcessNextIdentityAssociation()
@@ -189,11 +197,12 @@
     bool rval = false;
 
     // not interrupt in-progress solicit
-    VerifyOrExit(mIdentityAssociationCurrent == NULL || mIdentityAssociationCurrent->mStatus != kIaStatusSoliciting);
+    VerifyOrExit(mIdentityAssociationCurrent == nullptr || mIdentityAssociationCurrent->mStatus != kIaStatusSoliciting,
+                 OT_NOOP);
 
     mTrickleTimer.Stop();
 
-    for (uint8_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); ++i)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); ++i)
     {
         if (mIdentityAssociations[i].mStatus != kIaStatusSolicit)
         {
@@ -201,7 +210,7 @@
         }
 
         // new transaction id
-        Random::NonCrypto::FillBuffer(mTransactionId, kTransactionIdSize);
+        IgnoreError(Random::Crypto::FillBuffer(mTransactionId, kTransactionIdSize));
 
         mIdentityAssociationCurrent = &mIdentityAssociations[i];
 
@@ -226,7 +235,7 @@
 {
     bool rval = true;
 
-    VerifyOrExit(mIdentityAssociationCurrent != NULL, rval = false);
+    VerifyOrExit(mIdentityAssociationCurrent != nullptr, rval = false);
 
     switch (mIdentityAssociationCurrent->mStatus)
     {
@@ -241,7 +250,7 @@
         break;
 
     case kIaStatusSolicitReplied:
-        mIdentityAssociationCurrent = NULL;
+        mIdentityAssociationCurrent = nullptr;
 
         if (!ProcessNextIdentityAssociation())
         {
@@ -260,13 +269,13 @@
     return rval;
 }
 
-otError Dhcp6Client::Solicit(uint16_t aRloc16)
+void Dhcp6Client::Solicit(uint16_t aRloc16)
 {
     otError          error = OT_ERROR_NONE;
     Message *        message;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = mSocket.NewMessage(0)) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = AppendHeader(*message));
     SuccessOrExit(error = AppendElapsedTime(*message));
@@ -277,15 +286,9 @@
     SuccessOrExit(error = AppendRapidCommit(*message));
 
 #if OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT
-    messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xff03);
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(0x0002);
+    messageInfo.GetPeerAddr().SetToRealmLocalAllRoutersMulticast();
 #else
-    memcpy(messageInfo.GetPeerAddr().mFields.m8, Get<Mle::MleRouter>().GetMeshLocalPrefix().m8,
-           sizeof(otMeshLocalPrefix));
-    messageInfo.GetPeerAddr().mFields.m16[4] = HostSwap16(0x0000);
-    messageInfo.GetPeerAddr().mFields.m16[5] = HostSwap16(0x00ff);
-    messageInfo.GetPeerAddr().mFields.m16[6] = HostSwap16(0xfe00);
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aRloc16);
+    messageInfo.GetPeerAddr().SetToRoutingLocator(Get<Mle::MleRouter>().GetMeshLocalPrefix(), aRloc16);
 #endif
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.mPeerPort = kDhcpServerPort;
@@ -295,12 +298,15 @@
 
 exit:
 
-    if (message != NULL && error != OT_ERROR_NONE)
+    if (message != nullptr)
     {
-        message->Free();
-    }
+        otLogWarnIp6("Failed to send DHCPv6 Solicit: %s", otThreadErrorToString(error));
 
-    return error;
+        if (error != OT_ERROR_NONE)
+        {
+            message->Free();
+        }
+    }
 }
 
 otError Dhcp6Client::AppendHeader(Message &aMessage)
@@ -344,9 +350,9 @@
     uint16_t length = 0;
     IaNa     option;
 
-    VerifyOrExit(mIdentityAssociationCurrent != NULL, error = OT_ERROR_DROP);
+    VerifyOrExit(mIdentityAssociationCurrent != nullptr, error = OT_ERROR_DROP);
 
-    for (uint8_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); ++i)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); ++i)
     {
         if (mIdentityAssociations[i].mStatus == kIaStatusInvalid ||
             mIdentityAssociations[i].mStatus == kIaStatusSolicitReplied)
@@ -383,7 +389,7 @@
 
     option.Init();
 
-    for (uint8_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); ++i)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); ++i)
     {
         if ((mIdentityAssociations[i].mStatus == kIaStatusSolicit ||
              mIdentityAssociations[i].mStatus == kIaStatusSoliciting) &&
@@ -420,7 +426,7 @@
 
     Dhcp6Header header;
 
-    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(header), &header) == sizeof(header));
+    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(header), &header) == sizeof(header), OT_NOOP);
     aMessage.MoveOffset(sizeof(header));
 
     if ((header.GetType() == kTypeReply) && (!memcmp(header.GetTransactionId(), mTransactionId, kTransactionIdSize)))
@@ -444,18 +450,18 @@
     }
 
     // Server Identifier
-    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionServerIdentifier)) > 0);
+    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionServerIdentifier)) > 0, OT_NOOP);
     SuccessOrExit(ProcessServerIdentifier(aMessage, optionOffset));
 
     // Client Identifier
-    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionClientIdentifier)) > 0);
+    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionClientIdentifier)) > 0, OT_NOOP);
     SuccessOrExit(ProcessClientIdentifier(aMessage, optionOffset));
 
     // Rapid Commit
-    VerifyOrExit(FindOption(aMessage, offset, length, kOptionRapidCommit) > 0);
+    VerifyOrExit(FindOption(aMessage, offset, length, kOptionRapidCommit) > 0, OT_NOOP);
 
     // IA_NA
-    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionIaNa)) > 0);
+    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionIaNa)) > 0, OT_NOOP);
     SuccessOrExit(ProcessIaNa(aMessage, optionOffset));
 
     HandleTrickleTimer();
@@ -472,7 +478,7 @@
     while (aOffset <= end)
     {
         Dhcp6Option option;
-        VerifyOrExit(aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option));
+        VerifyOrExit(aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option), OT_NOOP);
 
         if (option.GetCode() == (aCode))
         {
@@ -491,7 +497,7 @@
     otError          error = OT_ERROR_NONE;
     ServerIdentifier option;
 
-    VerifyOrExit((aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option)));
+    VerifyOrExit((aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option)), OT_NOOP);
     VerifyOrExit(((option.GetDuidType() == kDuidLLT) && (option.GetDuidHardwareType() == kHardwareTypeEthernet)) ||
                      ((option.GetLength() == (sizeof(option) - sizeof(Dhcp6Option))) &&
                       (option.GetDuidType() == kDuidLL) && (option.GetDuidHardwareType() == kHardwareTypeEui64)),
@@ -576,7 +582,7 @@
                   (option.GetLength() == (sizeof(option) - sizeof(Dhcp6Option)))),
                  error = OT_ERROR_PARSE);
 
-    for (uint8_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); ++i)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mIdentityAssociations); ++i)
     {
         IdentityAssociation &ia = mIdentityAssociations[i];
 
@@ -587,12 +593,13 @@
 
         if (ia.mNetifAddress.GetAddress().PrefixMatch(option.GetAddress()) >= ia.mNetifAddress.mPrefixLength)
         {
-            mIdentityAssociations[i].mNetifAddress.mAddress   = option.GetAddress();
-            mIdentityAssociations[i].mPreferredLifetime       = option.GetPreferredLifetime();
-            mIdentityAssociations[i].mValidLifetime           = option.GetValidLifetime();
-            mIdentityAssociations[i].mNetifAddress.mPreferred = option.GetPreferredLifetime() != 0;
-            mIdentityAssociations[i].mNetifAddress.mValid     = option.GetValidLifetime() != 0;
-            mIdentityAssociations[i].mStatus                  = kIaStatusSolicitReplied;
+            mIdentityAssociations[i].mNetifAddress.mAddress       = option.GetAddress();
+            mIdentityAssociations[i].mPreferredLifetime           = option.GetPreferredLifetime();
+            mIdentityAssociations[i].mValidLifetime               = option.GetValidLifetime();
+            mIdentityAssociations[i].mNetifAddress.mAddressOrigin = OT_ADDRESS_ORIGIN_DHCPV6;
+            mIdentityAssociations[i].mNetifAddress.mPreferred     = option.GetPreferredLifetime() != 0;
+            mIdentityAssociations[i].mNetifAddress.mValid         = option.GetValidLifetime() != 0;
+            mIdentityAssociations[i].mStatus                      = kIaStatusSolicitReplied;
             Get<ThreadNetif>().AddUnicastAddress(ia.mNetifAddress);
             break;
         }
diff --git a/src/core/net/dhcp6_client.hpp b/src/core/net/dhcp6_client.hpp
index e38ca0d..d0c5a07 100644
--- a/src/core/net/dhcp6_client.hpp
+++ b/src/core/net/dhcp6_client.hpp
@@ -123,7 +123,7 @@
 
     static bool MatchNetifAddressWithPrefix(const Ip6::NetifUnicastAddress &aAddress, const otIp6Prefix &aIp6Prefix);
 
-    otError Solicit(uint16_t aRloc16);
+    void Solicit(uint16_t aRloc16);
 
     void AddIdentityAssociation(uint16_t aRloc16, otIp6Prefix &aIp6Prefix);
     void RemoveIdentityAssociation(uint16_t aRloc16, otIp6Prefix &aIp6Prefix);
@@ -151,7 +151,7 @@
     static bool HandleTrickleTimer(TrickleTimer &aTrickleTimer);
     bool        HandleTrickleTimer(void);
 
-    Ip6::UdpSocket mSocket;
+    Ip6::Udp::Socket mSocket;
 
     TrickleTimer mTrickleTimer;
 
diff --git a/src/core/net/dhcp6_server.cpp b/src/core/net/dhcp6_server.cpp
index b8eadfb..6bf2368 100644
--- a/src/core/net/dhcp6_server.cpp
+++ b/src/core/net/dhcp6_server.cpp
@@ -48,7 +48,7 @@
 
 Dhcp6Server::Dhcp6Server(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mSocket(Get<Ip6::Udp>())
+    , mSocket(aInstance)
     , mPrefixAgentsCount(0)
     , mPrefixAgentsMask(0)
 {
@@ -64,7 +64,7 @@
     Lowpan::Context                 lowpanContext;
 
     // remove dhcp agent aloc and prefix delegation
-    for (int i = 0; i < OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; i++)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mPrefixAgents); i++)
     {
         bool found = false;
 
@@ -135,21 +135,21 @@
     Ip6::SockAddr sockaddr;
 
     sockaddr.mPort = kDhcpServerPort;
-    mSocket.Open(&Dhcp6Server::HandleUdpReceive, this);
-    mSocket.Bind(sockaddr);
+    IgnoreError(mSocket.Open(&Dhcp6Server::HandleUdpReceive, this));
+    IgnoreError(mSocket.Bind(sockaddr));
 }
 
 void Dhcp6Server::Stop(void)
 {
-    mSocket.Close();
+    IgnoreError(mSocket.Close());
 }
 
-otError Dhcp6Server::AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext)
+void Dhcp6Server::AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext)
 {
     otError      error    = OT_ERROR_NONE;
-    PrefixAgent *newEntry = NULL;
+    PrefixAgent *newEntry = nullptr;
 
-    for (int i = 0; i < OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; i++)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mPrefixAgents); i++)
     {
         if (!mPrefixAgents[i].IsValid())
         {
@@ -162,14 +162,18 @@
         }
     }
 
-    VerifyOrExit(newEntry != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(newEntry != nullptr, error = OT_ERROR_NO_BUFS);
 
     newEntry->Set(aIp6Prefix, Get<Mle::MleRouter>().GetMeshLocalPrefix(), aContext.mContextId);
     Get<ThreadNetif>().AddUnicastAddress(newEntry->GetAloc());
     mPrefixAgentsCount++;
 
 exit:
-    return error;
+
+    if (error != OT_ERROR_NONE)
+    {
+        otLogNoteIp6("Failed to add DHCPv6 prefix agent: %s", otThreadErrorToString(error));
+    }
 }
 
 void Dhcp6Server::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -183,11 +187,11 @@
     Dhcp6Header  header;
     otIp6Address dst = aMessageInfo.mPeerAddr;
 
-    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(header), &header) == sizeof(header));
+    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(header), &header) == sizeof(header), OT_NOOP);
     aMessage.MoveOffset(sizeof(header));
 
     // discard if not solicit type
-    VerifyOrExit((header.GetType() == kTypeSolicit));
+    VerifyOrExit((header.GetType() == kTypeSolicit), OT_NOOP);
 
     ProcessSolicit(aMessage, dst, header.GetTransactionId());
 
@@ -204,14 +208,14 @@
     uint16_t         length = aMessage.GetLength() - aMessage.GetOffset();
 
     // Client Identifier (discard if not present)
-    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionClientIdentifier)) > 0);
+    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionClientIdentifier)) > 0, OT_NOOP);
     SuccessOrExit(ProcessClientIdentifier(aMessage, optionOffset, clientIdentifier));
 
     // Server Identifier (assuming Rapid Commit, discard if present)
-    VerifyOrExit(FindOption(aMessage, offset, length, kOptionServerIdentifier) == 0);
+    VerifyOrExit(FindOption(aMessage, offset, length, kOptionServerIdentifier) == 0, OT_NOOP);
 
     // Rapid Commit (assuming Rapid Commit, discard if not present)
-    VerifyOrExit(FindOption(aMessage, offset, length, kOptionRapidCommit) > 0);
+    VerifyOrExit(FindOption(aMessage, offset, length, kOptionRapidCommit) > 0, OT_NOOP);
 
     // Elapsed Time if present
     if ((optionOffset = FindOption(aMessage, offset, length, kOptionElapsedTime)) > 0)
@@ -220,7 +224,7 @@
     }
 
     // IA_NA (discard if not present)
-    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionIaNa)) > 0);
+    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionIaNa)) > 0, OT_NOOP);
     SuccessOrExit(ProcessIaNa(aMessage, optionOffset, iana));
 
     SuccessOrExit(SendReply(aDst, aTransactionId, clientIdentifier, iana));
@@ -237,7 +241,7 @@
     while (aOffset <= end)
     {
         Dhcp6Option option;
-        VerifyOrExit(aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option));
+        VerifyOrExit(aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option), OT_NOOP);
 
         if (option.GetCode() == aCode)
         {
@@ -291,7 +295,7 @@
 
     while (length > 0)
     {
-        VerifyOrExit((optionOffset = FindOption(aMessage, aOffset, length, kOptionIaAddress)) > 0);
+        VerifyOrExit((optionOffset = FindOption(aMessage, aOffset, length, kOptionIaAddress)) > 0, OT_NOOP);
         SuccessOrExit(error = ProcessIaAddress(aMessage, optionOffset));
 
         length -= ((optionOffset - aOffset) + sizeof(IaAddress));
@@ -312,7 +316,7 @@
                  error = OT_ERROR_PARSE);
 
     // mask matching prefix
-    for (uint8_t i = 0; i < OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; i++)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mPrefixAgents); i++)
     {
         if (mPrefixAgents[i].IsValid() && mPrefixAgents[i].IsPrefixMatch(option.GetAddress()))
         {
@@ -331,7 +335,7 @@
     Ip6::MessageInfo messageInfo;
     Message *        message;
 
-    VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = mSocket.NewMessage(0)) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, aTransactionId));
     SuccessOrExit(error = AppendServerIdentifier(*message));
     SuccessOrExit(error = AppendClientIdentifier(*message, aClientId));
@@ -346,7 +350,7 @@
 
 exit:
 
-    if (message != NULL && error != OT_ERROR_NONE)
+    if (message != nullptr && error != OT_ERROR_NONE)
     {
         message->Free();
     }
@@ -394,7 +398,7 @@
 
     if (mPrefixAgentsMask)
     {
-        for (uint8_t i = 0; i < OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; i++)
+        for (size_t i = 0; i < OT_ARRAY_LENGTH(mPrefixAgents); i++)
         {
             if ((mPrefixAgentsMask & (1 << i)))
             {
@@ -434,7 +438,7 @@
     if (mPrefixAgentsMask)
     {
         // if specified, only apply specified prefixes
-        for (uint8_t i = 0; i < OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; i++)
+        for (size_t i = 0; i < OT_ARRAY_LENGTH(mPrefixAgents); i++)
         {
             if (mPrefixAgentsMask & (1 << i))
             {
@@ -445,7 +449,7 @@
     else
     {
         // if not specified, apply all configured prefixes
-        for (uint8_t i = 0; i < OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; i++)
+        for (size_t i = 0; i < OT_ARRAY_LENGTH(mPrefixAgents); i++)
         {
             if (mPrefixAgents[i].IsValid())
             {
@@ -464,8 +468,9 @@
     IaAddress option;
 
     option.Init();
-    memcpy(option.GetAddress().mFields.m8, &aPrefix, OT_IP6_PREFIX_SIZE);
-    option.GetAddress().SetIid(*reinterpret_cast<Mac::ExtAddress *>(aClientId.GetDuidLinkLayerAddress()));
+    option.GetAddress().SetPrefix(aPrefix.mFields.m8, OT_IP6_PREFIX_BITSIZE);
+    option.GetAddress().GetIid().SetFromExtAddress(
+        *reinterpret_cast<Mac::ExtAddress *>(aClientId.GetDuidLinkLayerAddress()));
     option.SetPreferredLifetime(OT_DHCP6_DEFAULT_PREFERRED_LIFETIME);
     option.SetValidLifetime(OT_DHCP6_DEFAULT_VALID_LIFETIME);
     SuccessOrExit(error = aMessage.Append(&option, sizeof(option)));
@@ -482,6 +487,21 @@
     return aMessage.Append(&option, sizeof(option));
 }
 
+void Dhcp6Server::ApplyMeshLocalPrefix(void)
+{
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mPrefixAgents); i++)
+    {
+        if (mPrefixAgents[i].IsValid())
+        {
+            PrefixAgent *entry = &mPrefixAgents[i];
+
+            Get<ThreadNetif>().RemoveUnicastAddress(entry->GetAloc());
+            entry->GetAloc().GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
+            Get<ThreadNetif>().AddUnicastAddress(entry->GetAloc());
+        }
+    }
+}
+
 } // namespace Dhcp6
 } // namespace ot
 
diff --git a/src/core/net/dhcp6_server.hpp b/src/core/net/dhcp6_server.hpp
index b2dc653..528cac6 100644
--- a/src/core/net/dhcp6_server.hpp
+++ b/src/core/net/dhcp6_server.hpp
@@ -83,6 +83,12 @@
      */
     otError UpdateService();
 
+    /**
+     * This method applies the Mesh Local Prefix.
+     *
+     */
+    void ApplyMeshLocalPrefix(void);
+
 private:
     class PrefixAgent
     {
@@ -163,19 +169,15 @@
          * @param[in]  aContextId        The 6LoWPAN Context ID.
          *
          */
-        void Set(const otIp6Prefix &aPrefix, const otMeshLocalPrefix &aMeshLocalPrefix, uint8_t aContextId)
+        void Set(const otIp6Prefix &aPrefix, const Mle::MeshLocalPrefix &aMeshLocalPrefix, uint8_t aContextId)
         {
             mPrefix = aPrefix;
 
-            memcpy(&mAloc.mAddress, &aMeshLocalPrefix, OT_IP6_PREFIX_SIZE);
-            mAloc.mAddress.mFields.m16[4] = HostSwap16(0x0000);
-            mAloc.mAddress.mFields.m16[5] = HostSwap16(0x00ff);
-            mAloc.mAddress.mFields.m16[6] = HostSwap16(0xfe00);
-            mAloc.mAddress.mFields.m8[14] = Ip6::Address::kAloc16Mask;
-            mAloc.mAddress.mFields.m8[15] = aContextId;
-            mAloc.mPrefixLength           = 64;
-            mAloc.mPreferred              = true;
-            mAloc.mValid                  = true;
+            mAloc.GetAddress().SetToAnycastLocator(aMeshLocalPrefix, (Ip6::Address::kAloc16Mask << 8) + aContextId);
+            mAloc.mPrefixLength  = OT_IP6_PREFIX_BITSIZE;
+            mAloc.mAddressOrigin = OT_ADDRESS_ORIGIN_THREAD;
+            mAloc.mPreferred     = true;
+            mAloc.mValid         = true;
         }
 
     private:
@@ -186,7 +188,7 @@
     void Start(void);
     void Stop(void);
 
-    otError AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext);
+    void AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext);
 
     otError AppendHeader(Message &aMessage, uint8_t *aTransactionId);
     otError AppendClientIdentifier(Message &aMessage, ClientIdentifier &aClientId);
@@ -212,7 +214,7 @@
 
     otError SendReply(otIp6Address &aDst, uint8_t *aTransactionId, ClientIdentifier &aClientId, IaNa &aIaNa);
 
-    Ip6::UdpSocket mSocket;
+    Ip6::Udp::Socket mSocket;
 
     PrefixAgent mPrefixAgents[OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES];
     uint8_t     mPrefixAgentsCount;
diff --git a/src/core/net/dns_client.cpp b/src/core/net/dns_client.cpp
index bb928ed..0839623 100644
--- a/src/core/net/dns_client.cpp
+++ b/src/core/net/dns_client.cpp
@@ -32,6 +32,7 @@
 #include "common/debug.hpp"
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
+#include "common/logging.hpp"
 #include "net/udp6.hpp"
 #include "thread/thread_netif.hpp"
 
@@ -48,9 +49,9 @@
 namespace Dns {
 
 QueryMetadata::QueryMetadata(void)
-    : mHostname(NULL)
-    , mResponseHandler(NULL)
-    , mResponseContext(NULL)
+    : mHostname(nullptr)
+    , mResponseHandler(nullptr)
+    , mResponseContext(nullptr)
     , mTransmissionTime()
     , mDestinationPort(0)
     , mRetransmissionCount(0)
@@ -60,7 +61,7 @@
 }
 
 QueryMetadata::QueryMetadata(otDnsResponseHandler aHandler, void *aContext)
-    : mHostname(NULL)
+    : mHostname(nullptr)
     , mResponseHandler(aHandler)
     , mResponseContext(aContext)
     , mTransmissionTime()
@@ -71,10 +72,10 @@
     mDestinationAddress.Clear();
 }
 
-Client::Client(Ip6::Netif &aNetif)
-    : mSocket(aNetif.Get<Ip6::Udp>())
+Client::Client(Instance &aInstance)
+    : mSocket(aInstance)
     , mMessageId(0)
-    , mRetransmissionTimer(aNetif.GetInstance(), &Client::HandleRetransmissionTimer, this)
+    , mRetransmissionTimer(aInstance, Client::HandleRetransmissionTimer, this)
 {
 }
 
@@ -97,13 +98,13 @@
     QueryMetadata queryMetadata;
 
     // Remove all pending queries.
-    while (message != NULL)
+    while (message != nullptr)
     {
         messageToRemove = message;
         message         = message->GetNext();
 
         queryMetadata.ReadFrom(*messageToRemove);
-        FinalizeDnsTransaction(*messageToRemove, queryMetadata, NULL, 0, OT_ERROR_ABORT);
+        FinalizeDnsTransaction(*messageToRemove, queryMetadata, nullptr, 0, OT_ERROR_ABORT);
     }
 
     return mSocket.Close();
@@ -113,13 +114,13 @@
 {
     otError                 error;
     QueryMetadata           queryMetadata(aHandler, aContext);
-    Message *               message     = NULL;
-    Message *               messageCopy = NULL;
+    Message *               message     = nullptr;
+    Message *               messageCopy = nullptr;
     Header                  header;
     QuestionAaaa            question;
     const Ip6::MessageInfo *messageInfo;
 
-    VerifyOrExit(aQuery->mHostname != NULL && aQuery->mMessageInfo != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aQuery->mHostname != nullptr && aQuery->mMessageInfo != nullptr, error = OT_ERROR_INVALID_ARGS);
 
     header.SetMessageId(mMessageId++);
     header.SetType(Header::kTypeQuery);
@@ -132,7 +133,7 @@
 
     header.SetQuestionCount(1);
 
-    VerifyOrExit((message = NewMessage(header)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMessage(header)) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = AppendCompressedHostname(*message, aQuery->mHostname));
     SuccessOrExit(error = question.AppendTo(*message));
@@ -146,7 +147,7 @@
     queryMetadata.mDestinationAddress  = messageInfo->GetPeerAddr();
     queryMetadata.mRetransmissionCount = 0;
 
-    VerifyOrExit((messageCopy = CopyAndEnqueueMessage(*message, queryMetadata)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((messageCopy = CopyAndEnqueueMessage(*message, queryMetadata)) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = SendMessage(*message, *messageInfo));
 
 exit:
@@ -169,10 +170,10 @@
 
 Message *Client::NewMessage(const Header &aHeader)
 {
-    Message *message = NULL;
+    Message *message = nullptr;
 
-    VerifyOrExit((message = mSocket.NewMessage(sizeof(aHeader))) != NULL);
-    message->Prepend(&aHeader, sizeof(aHeader));
+    VerifyOrExit((message = mSocket.NewMessage(sizeof(aHeader))) != nullptr, OT_NOOP);
+    IgnoreError(message->Prepend(&aHeader, sizeof(aHeader)));
     message->SetOffset(0);
 
 exit:
@@ -182,10 +183,10 @@
 Message *Client::CopyAndEnqueueMessage(const Message &aMessage, const QueryMetadata &aQueryMetadata)
 {
     otError  error       = OT_ERROR_NONE;
-    Message *messageCopy = NULL;
+    Message *messageCopy = nullptr;
 
     // Create a message copy for further retransmissions.
-    VerifyOrExit((messageCopy = aMessage.Clone()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((messageCopy = aMessage.Clone()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     // Append the copy with retransmission data and add it to the queue.
     SuccessOrExit(error = aQueryMetadata.AppendTo(*messageCopy));
@@ -195,10 +196,10 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && messageCopy != NULL)
+    if (error != OT_ERROR_NONE && messageCopy != nullptr)
     {
         messageCopy->Free();
-        messageCopy = NULL;
+        messageCopy = nullptr;
     }
 
     return messageCopy;
@@ -208,7 +209,7 @@
 {
     mPendingQueries.Dequeue(aMessage);
 
-    if (mRetransmissionTimer.IsRunning() && (mPendingQueries.GetHead() == NULL))
+    if (mRetransmissionTimer.IsRunning() && (mPendingQueries.GetHead() == nullptr))
     {
         // No more requests pending, stop the timer.
         mRetransmissionTimer.Stop();
@@ -223,13 +224,13 @@
     return mSocket.SendTo(aMessage, aMessageInfo);
 }
 
-otError Client::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+void Client::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError  error;
-    Message *messageCopy = NULL;
+    Message *messageCopy = nullptr;
 
     // Create a message copy for lower layers.
-    VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(QueryMetadata))) != NULL,
+    VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(QueryMetadata))) != nullptr,
                  error = OT_ERROR_NO_BUFS);
 
     // Send the copy.
@@ -237,12 +238,15 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && messageCopy != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        messageCopy->Free();
-    }
+        otLogWarnIp6("Failed to send DNS request: %s", otThreadErrorToString(error));
 
-    return error;
+        if (messageCopy != nullptr)
+        {
+            messageCopy->Free();
+        }
+    }
 }
 
 otError Client::AppendCompressedHostname(Message &aMessage, const char *aHostname)
@@ -359,11 +363,13 @@
     uint16_t messageId;
     Message *message = mPendingQueries.GetHead();
 
-    while (message != NULL)
+    while (message != nullptr)
     {
         // Partially read DNS header to obtain message ID only.
         uint16_t count = message->Read(message->GetOffset(), sizeof(messageId), &messageId);
-        assert(count == sizeof(messageId));
+
+        OT_UNUSED_VARIABLE(count);
+        OT_ASSERT(count == sizeof(messageId));
 
         if (HostSwap16(messageId) == aResponseHeader.GetMessageId())
         {
@@ -386,7 +392,7 @@
 {
     DequeueMessage(aQuery);
 
-    if (aQueryMetadata.mResponseHandler != NULL)
+    if (aQueryMetadata.mResponseHandler != nullptr)
     {
         aQueryMetadata.mResponseHandler(aQueryMetadata.mResponseContext, aQueryMetadata.mHostname, aAddress, aTtl,
                                         aResult);
@@ -407,7 +413,7 @@
     Message *        nextMessage;
     Ip6::MessageInfo messageInfo;
 
-    for (message = mPendingQueries.GetHead(); message != NULL; message = nextMessage)
+    for (message = mPendingQueries.GetHead(); message != nullptr; message = nextMessage)
     {
         nextMessage = message->GetNext();
 
@@ -418,7 +424,7 @@
             if (queryMetadata.mRetransmissionCount >= kMaxRetransmit)
             {
                 // No expected response.
-                FinalizeDnsTransaction(*message, queryMetadata, NULL, 0, OT_ERROR_RESPONSE_TIMEOUT);
+                FinalizeDnsTransaction(*message, queryMetadata, nullptr, 0, OT_ERROR_RESPONSE_TIMEOUT);
 
                 continue;
             }
@@ -464,18 +470,19 @@
     Header             responseHeader;
     QueryMetadata      queryMetadata;
     ResourceRecordAaaa record;
-    Message *          message = NULL;
+    Message *          message = nullptr;
     uint16_t           offset;
 
-    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(responseHeader), &responseHeader) ==
-                 sizeof(responseHeader));
+    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(responseHeader), &responseHeader) == sizeof(responseHeader),
+                 OT_NOOP);
     VerifyOrExit(responseHeader.GetType() == Header::kTypeResponse && responseHeader.GetQuestionCount() == 1 &&
-                 !responseHeader.IsTruncationFlagSet());
+                     !responseHeader.IsTruncationFlagSet(),
+                 OT_NOOP);
 
     aMessage.MoveOffset(sizeof(responseHeader));
     offset = aMessage.GetOffset();
 
-    VerifyOrExit((message = FindRelatedQuery(responseHeader, queryMetadata)) != NULL);
+    VerifyOrExit((message = FindRelatedQuery(responseHeader, queryMetadata)) != nullptr, OT_NOOP);
 
     VerifyOrExit(responseHeader.GetResponseCode() == Header::kResponseSuccess, error = OT_ERROR_FAILED);
 
@@ -510,9 +517,9 @@
 
 exit:
 
-    if (message != NULL && error != OT_ERROR_NONE)
+    if (message != nullptr && error != OT_ERROR_NONE)
     {
-        FinalizeDnsTransaction(*message, queryMetadata, NULL, 0, error);
+        FinalizeDnsTransaction(*message, queryMetadata, nullptr, 0, error);
     }
 }
 
diff --git a/src/core/net/dns_client.hpp b/src/core/net/dns_client.hpp
index 1156d77..32d38a4 100644
--- a/src/core/net/dns_client.hpp
+++ b/src/core/net/dns_client.hpp
@@ -91,7 +91,7 @@
     void ReadFrom(const Message &aMessage)
     {
         uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-        assert(length == sizeof(*this));
+        OT_ASSERT(length == sizeof(*this));
         OT_UNUSED_VARIABLE(length);
     }
 
@@ -129,10 +129,10 @@
     /**
      * This constructor initializes the object.
      *
-     * @param[in]  aNetif    A reference to the network interface that DNS client should be assigned to.
+     * @param[in]  aInstance     A reference to the OpenThread instance.
      *
      */
-    explicit Client(Ip6::Netif &aNetif);
+    explicit Client(Instance &aInstance);
 
     /**
      * This method starts the DNS client.
@@ -197,7 +197,7 @@
     Message *CopyAndEnqueueMessage(const Message &aMessage, const QueryMetadata &aQueryMetadata);
     void     DequeueMessage(Message &aMessage);
     otError  SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-    otError  SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    void     SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
     otError AppendCompressedHostname(Message &aMessage, const char *aHostname);
     otError CompareQuestions(Message &aMessageResponse, Message &aMessageQuery, uint16_t &aOffset);
@@ -216,7 +216,7 @@
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
-    Ip6::UdpSocket mSocket;
+    Ip6::Udp::Socket mSocket;
 
     uint16_t     mMessageId;
     MessageQueue mPendingQueries;
diff --git a/src/core/net/icmp6.cpp b/src/core/net/icmp6.cpp
index 754000b..3341992 100644
--- a/src/core/net/icmp6.cpp
+++ b/src/core/net/icmp6.cpp
@@ -56,10 +56,10 @@
 
 Message *Icmp::NewMessage(uint16_t aReserved)
 {
-    return Get<Ip6>().NewMessage(sizeof(IcmpHeader) + aReserved);
+    return Get<Ip6>().NewMessage(sizeof(Header) + aReserved);
 }
 
-otError Icmp::RegisterHandler(IcmpHandler &aHandler)
+otError Icmp::RegisterHandler(Handler &aHandler)
 {
     return mHandlers.Add(aHandler);
 }
@@ -68,12 +68,12 @@
 {
     otError     error = OT_ERROR_NONE;
     MessageInfo messageInfoLocal;
-    IcmpHeader  icmpHeader;
+    Header      icmpHeader;
 
     messageInfoLocal = aMessageInfo;
 
-    icmpHeader.Init();
-    icmpHeader.SetType(IcmpHeader::kTypeEchoRequest);
+    icmpHeader.Clear();
+    icmpHeader.SetType(Header::kTypeEchoRequest);
     icmpHeader.SetId(aIdentifier);
     icmpHeader.SetSequence(mEchoSequence++);
 
@@ -87,24 +87,38 @@
     return error;
 }
 
-otError Icmp::SendError(IcmpHeader::Type   aType,
-                        IcmpHeader::Code   aCode,
+otError Icmp::SendError(Header::Type       aType,
+                        Header::Code       aCode,
                         const MessageInfo &aMessageInfo,
-                        const Header &     aHeader)
+                        const Message &    aMessage)
 {
-    otError     error = OT_ERROR_NONE;
-    MessageInfo messageInfoLocal;
-    Message *   message = NULL;
-    IcmpHeader  icmp6Header;
+    otError           error = OT_ERROR_NONE;
+    MessageInfo       messageInfoLocal;
+    Message *         message = nullptr;
+    Header            icmp6Header;
+    ot::Ip6::Header   ip6Header;
+    Message::Settings settings(Message::kWithLinkSecurity, Message::kPriorityNet);
+
+    VerifyOrExit(aMessage.GetLength() >= sizeof(ip6Header), error = OT_ERROR_INVALID_ARGS);
+
+    aMessage.Read(0, sizeof(ip6Header), &ip6Header);
+
+    if (ip6Header.GetNextHeader() == kProtoIcmp6)
+    {
+        VerifyOrExit(aMessage.GetLength() >= (sizeof(ip6Header) + sizeof(icmp6Header)), OT_NOOP);
+
+        aMessage.Read(sizeof(ip6Header), sizeof(icmp6Header), &icmp6Header);
+        VerifyOrExit(!icmp6Header.IsError(), OT_NOOP);
+    }
 
     messageInfoLocal = aMessageInfo;
 
-    VerifyOrExit((message = Get<Ip6>().NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
-    SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(aHeader)));
+    VerifyOrExit((message = Get<Ip6>().NewMessage(0, settings)) != nullptr, error = OT_ERROR_NO_BUFS);
+    SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(ip6Header)));
 
-    message->Write(sizeof(icmp6Header), sizeof(aHeader), &aHeader);
+    message->Write(sizeof(icmp6Header), sizeof(ip6Header), &ip6Header);
 
-    icmp6Header.Init();
+    icmp6Header.Clear();
     icmp6Header.SetType(aType);
     icmp6Header.SetCode(aCode);
     message->Write(0, sizeof(icmp6Header), &icmp6Header);
@@ -115,7 +129,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -125,10 +139,10 @@
 
 otError Icmp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
 {
-    otError    error = OT_ERROR_NONE;
-    uint16_t   payloadLength;
-    IcmpHeader icmp6Header;
-    uint16_t   checksum;
+    otError  error = OT_ERROR_NONE;
+    uint16_t payloadLength;
+    Header   icmp6Header;
+    uint16_t checksum;
 
     VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(icmp6Header), &icmp6Header) == sizeof(icmp6Header),
                  error = OT_ERROR_PARSE);
@@ -140,14 +154,14 @@
     checksum = aMessage.UpdateChecksum(checksum, aMessage.GetOffset(), payloadLength);
     VerifyOrExit(checksum == 0xffff, error = OT_ERROR_PARSE);
 
-    if (icmp6Header.GetType() == IcmpHeader::kTypeEchoRequest)
+    if (icmp6Header.GetType() == Header::kTypeEchoRequest)
     {
         SuccessOrExit(error = HandleEchoRequest(aMessage, aMessageInfo));
     }
 
     aMessage.MoveOffset(sizeof(icmp6Header));
 
-    for (IcmpHandler *handler = mHandlers.GetHead(); handler; handler = handler->GetNext())
+    for (Handler *handler = mHandlers.GetHead(); handler; handler = handler->GetNext())
     {
         handler->HandleReceiveMessage(aMessage, aMessageInfo, icmp6Header);
     }
@@ -182,31 +196,30 @@
 otError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo &aMessageInfo)
 {
     otError     error = OT_ERROR_NONE;
-    IcmpHeader  icmp6Header;
-    Message *   replyMessage = NULL;
+    Header      icmp6Header;
+    Message *   replyMessage = nullptr;
     MessageInfo replyMessageInfo;
     uint16_t    payloadLength;
 
     // always handle Echo Request destined for RLOC or ALOC
-    VerifyOrExit(ShouldHandleEchoRequest(aMessageInfo) || aMessageInfo.GetSockAddr().IsRoutingLocator() ||
-                 aMessageInfo.GetSockAddr().IsAnycastRoutingLocator());
+    VerifyOrExit(ShouldHandleEchoRequest(aMessageInfo) || aMessageInfo.GetSockAddr().GetIid().IsLocator(), OT_NOOP);
 
     otLogInfoIcmp("Received Echo Request");
 
-    icmp6Header.Init();
-    icmp6Header.SetType(IcmpHeader::kTypeEchoReply);
+    icmp6Header.Clear();
+    icmp6Header.SetType(Header::kTypeEchoReply);
 
-    if ((replyMessage = Get<Ip6>().NewMessage(0)) == NULL)
+    if ((replyMessage = Get<Ip6>().NewMessage(0)) == nullptr)
     {
         otLogDebgIcmp("Failed to allocate a new message");
         ExitNow();
     }
 
-    payloadLength = aRequestMessage.GetLength() - aRequestMessage.GetOffset() - IcmpHeader::GetDataOffset();
-    SuccessOrExit(error = replyMessage->SetLength(IcmpHeader::GetDataOffset() + payloadLength));
+    payloadLength = aRequestMessage.GetLength() - aRequestMessage.GetOffset() - Header::kDataFieldOffset;
+    SuccessOrExit(error = replyMessage->SetLength(Header::kDataFieldOffset + payloadLength));
 
-    replyMessage->Write(0, IcmpHeader::GetDataOffset(), &icmp6Header);
-    aRequestMessage.CopyTo(aRequestMessage.GetOffset() + IcmpHeader::GetDataOffset(), IcmpHeader::GetDataOffset(),
+    replyMessage->Write(0, Header::kDataFieldOffset, &icmp6Header);
+    aRequestMessage.CopyTo(aRequestMessage.GetOffset() + Header::kDataFieldOffset, Header::kDataFieldOffset,
                            payloadLength, *replyMessage);
 
     replyMessageInfo.SetPeerAddr(aMessageInfo.GetPeerAddr());
@@ -223,7 +236,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && replyMessage != NULL)
+    if (error != OT_ERROR_NONE && replyMessage != nullptr)
     {
         replyMessage->Free();
     }
@@ -241,7 +254,7 @@
     }
 
     aChecksum = HostSwap16(aChecksum);
-    aMessage.Write(aMessage.GetOffset() + IcmpHeader::GetChecksumOffset(), sizeof(aChecksum), &aChecksum);
+    aMessage.Write(aMessage.GetOffset() + Header::kChecksumFieldOffset, sizeof(aChecksum), &aChecksum);
 }
 
 } // namespace Ip6
diff --git a/src/core/net/icmp6.hpp b/src/core/net/icmp6.hpp
index 100af7f..7992406 100644
--- a/src/core/net/icmp6.hpp
+++ b/src/core/net/icmp6.hpp
@@ -38,6 +38,7 @@
 
 #include <openthread/icmp6.h>
 
+#include "common/clearable.hpp"
 #include "common/encoding.hpp"
 #include "common/linked_list.hpp"
 #include "common/locator.hpp"
@@ -58,176 +59,6 @@
  *
  */
 
-/*
- * This class implements ICMPv6 header generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class IcmpHeader : public otIcmp6Header
-{
-public:
-    /**
-     * This method initializes the ICMPv6 header to all zeros.
-     *
-     */
-    void Init(void)
-    {
-        mType        = 0;
-        mCode        = 0;
-        mChecksum    = 0;
-        mData.m32[0] = 0;
-    }
-
-    /**
-     * ICMPv6 Message Types
-     *
-     */
-    enum Type
-    {
-        kTypeDstUnreach   = OT_ICMP6_TYPE_DST_UNREACH,   ///< Destination Unreachable
-        kTypePacketToBig  = OT_ICMP6_TYPE_PACKET_TO_BIG, ///< Packet To Big
-        kTypeTimeExceeded = OT_ICMP6_TYPE_TIME_EXCEEDED, ///< Time Exceeded
-        kTypeEchoRequest  = OT_ICMP6_TYPE_ECHO_REQUEST,  ///< Echo Request
-        kTypeEchoReply    = OT_ICMP6_TYPE_ECHO_REPLY,    ///< Echo Reply
-    };
-
-    /**
-     * ICMPv6 Message Codes
-     *
-     */
-    enum Code
-    {
-        kCodeDstUnreachNoRoute = OT_ICMP6_CODE_DST_UNREACH_NO_ROUTE, ///< Destination Unreachable No Route
-        kCodeFragmReasTimeEx   = OT_ICMP6_CODE_FRAGM_REAS_TIME_EX,   ///< Fragment Reassembly Time Exceeded
-    };
-
-    /**
-     * This method returns the ICMPv6 message type.
-     *
-     * @returns The ICMPv6 message type.
-     *
-     */
-    Type GetType(void) const { return static_cast<Type>(mType); }
-
-    /**
-     * This method sets the ICMPv6 message type.
-     *
-     * @param[in]  aType  The ICMPv6 message type.
-     *
-     */
-    void SetType(Type aType) { mType = static_cast<uint8_t>(aType); }
-
-    /**
-     * This method returns the ICMPv6 message code.
-     *
-     * @returns The ICMPv6 message code.
-     *
-     */
-    Code GetCode(void) const { return static_cast<Code>(mCode); }
-
-    /**
-     * This method sets the ICMPv6 message code.
-     *
-     * @param[in]  aCode  The ICMPv6 message code.
-     */
-    void SetCode(Code aCode) { mCode = static_cast<uint8_t>(aCode); }
-
-    /**
-     * This method returns the ICMPv6 message checksum.
-     *
-     * @returns The ICMPv6 message checksum.
-     *
-     */
-    uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); }
-
-    /**
-     * This method sets the ICMPv6 message checksum.
-     *
-     * @param[in]  aChecksum  The ICMPv6 message checksum.
-     *
-     */
-    void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }
-
-    /**
-     * This method returns the ICMPv6 message ID for Echo Requests and Replies.
-     *
-     * @returns The ICMPv6 message ID.
-     *
-     */
-    uint16_t GetId(void) const { return HostSwap16(mData.m16[0]); }
-
-    /**
-     * This method sets the ICMPv6 message ID for Echo Requests and Replies.
-     *
-     * @param[in]  aId  The ICMPv6 message ID.
-     *
-     */
-    void SetId(uint16_t aId) { mData.m16[0] = HostSwap16(aId); }
-
-    /**
-     * This method returns the ICMPv6 message sequence for Echo Requests and Replies.
-     *
-     * @returns The ICMPv6 message sequence.
-     *
-     */
-    uint16_t GetSequence(void) const { return HostSwap16(mData.m16[1]); }
-
-    /**
-     * This method sets the ICMPv6 message sequence for Echo Requests and Replies.
-     *
-     * @param[in]  aSequence  The ICMPv6 message sequence.
-     *
-     */
-    void SetSequence(uint16_t aSequence) { mData.m16[1] = HostSwap16(aSequence); }
-
-    /**
-     * This static method returns the byte offset of the Checksum field in the ICMPv6 header.
-     *
-     * @returns The byte offset of the Checksum field.
-     *
-     */
-    static uint8_t GetChecksumOffset(void) { return offsetof(otIcmp6Header, mChecksum); }
-
-    /**
-     * This static method returns the byte offset of the ICMPv6 payload.
-     *
-     * @returns The Byte offset of the ICMPv6 payload.
-     *
-     */
-    static uint8_t GetDataOffset(void) { return offsetof(otIcmp6Header, mData); }
-
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements ICMPv6 message handlers.
- *
- */
-class IcmpHandler : public otIcmp6Handler, public LinkedListEntry<IcmpHandler>
-{
-    friend class Icmp;
-
-public:
-    /**
-     * This constructor creates an ICMPv6 message handler.
-     *
-     * @param[in]  aCallback  A pointer to the function that is called when receiving an ICMPv6 message.
-     * @param[in]  aContext   A pointer to arbitrary context information.
-     *
-     */
-    IcmpHandler(otIcmp6ReceiveCallback aCallback, void *aContext)
-    {
-        mReceiveCallback = aCallback;
-        mContext         = aContext;
-        mNext            = NULL;
-    }
-
-private:
-    void HandleReceiveMessage(Message &aMessage, const MessageInfo &aMessageInfo, const IcmpHeader &aIcmp6Header)
-    {
-        mReceiveCallback(mContext, &aMessage, &aMessageInfo, &aIcmp6Header);
-    }
-};
-
 /**
  * This class implements ICMPv6.
  *
@@ -235,6 +66,167 @@
 class Icmp : public InstanceLocator
 {
 public:
+    /*
+     * This class implements ICMPv6 header generation and parsing.
+     *
+     */
+    OT_TOOL_PACKED_BEGIN
+    class Header : public otIcmp6Header, public Clearable<Header>
+    {
+    public:
+        /**
+         * ICMPv6 Message Types
+         *
+         */
+        enum Type : uint8_t
+        {
+            kTypeDstUnreach       = OT_ICMP6_TYPE_DST_UNREACH,       ///< Destination Unreachable
+            kTypePacketToBig      = OT_ICMP6_TYPE_PACKET_TO_BIG,     ///< Packet To Big
+            kTypeTimeExceeded     = OT_ICMP6_TYPE_TIME_EXCEEDED,     ///< Time Exceeded
+            kTypeParameterProblem = OT_ICMP6_TYPE_PARAMETER_PROBLEM, ///< Parameter Problem
+            kTypeEchoRequest      = OT_ICMP6_TYPE_ECHO_REQUEST,      ///< Echo Request
+            kTypeEchoReply        = OT_ICMP6_TYPE_ECHO_REPLY,        ///< Echo Reply
+        };
+
+        /**
+         * ICMPv6 Message Codes
+         *
+         */
+        enum Code : uint8_t
+        {
+            kCodeDstUnreachNoRoute = OT_ICMP6_CODE_DST_UNREACH_NO_ROUTE, ///< Destination Unreachable No Route
+            kCodeFragmReasTimeEx   = OT_ICMP6_CODE_FRAGM_REAS_TIME_EX,   ///< Fragment Reassembly Time Exceeded
+        };
+
+        enum : uint8_t
+        {
+            kTypeFieldOffset     = 0, ///< The byte offset of Type field in ICMP6 header.
+            kCodeFieldOffset     = 1, ///< The byte offset of Code field in ICMP6 header.
+            kChecksumFieldOffset = 2, ///< The byte offset of Checksum field in ICMP6 header.
+            kDataFieldOffset     = 4, ///< The byte offset of Data field in ICMP6 header.
+        };
+
+        /**
+         * This method indicates whether the ICMPv6 message is an error message.
+         *
+         * @retval TRUE if the ICMPv6 message is an error message.
+         * @retval FALSE if the ICMPv6 message is an informational message.
+         *
+         */
+        bool IsError(void) const { return mType < OT_ICMP6_TYPE_ECHO_REQUEST; }
+
+        /**
+         * This method returns the ICMPv6 message type.
+         *
+         * @returns The ICMPv6 message type.
+         *
+         */
+        Type GetType(void) const { return static_cast<Type>(mType); }
+
+        /**
+         * This method sets the ICMPv6 message type.
+         *
+         * @param[in]  aType  The ICMPv6 message type.
+         *
+         */
+        void SetType(Type aType) { mType = static_cast<uint8_t>(aType); }
+
+        /**
+         * This method returns the ICMPv6 message code.
+         *
+         * @returns The ICMPv6 message code.
+         *
+         */
+        Code GetCode(void) const { return static_cast<Code>(mCode); }
+
+        /**
+         * This method sets the ICMPv6 message code.
+         *
+         * @param[in]  aCode  The ICMPv6 message code.
+         *
+         */
+        void SetCode(Code aCode) { mCode = static_cast<uint8_t>(aCode); }
+
+        /**
+         * This method returns the ICMPv6 message checksum.
+         *
+         * @returns The ICMPv6 message checksum.
+         *
+         */
+        uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); }
+
+        /**
+         * This method sets the ICMPv6 message checksum.
+         *
+         * @param[in]  aChecksum  The ICMPv6 message checksum.
+         *
+         */
+        void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }
+
+        /**
+         * This method returns the ICMPv6 message ID for Echo Requests and Replies.
+         *
+         * @returns The ICMPv6 message ID.
+         *
+         */
+        uint16_t GetId(void) const { return HostSwap16(mData.m16[0]); }
+
+        /**
+         * This method sets the ICMPv6 message ID for Echo Requests and Replies.
+         *
+         * @param[in]  aId  The ICMPv6 message ID.
+         *
+         */
+        void SetId(uint16_t aId) { mData.m16[0] = HostSwap16(aId); }
+
+        /**
+         * This method returns the ICMPv6 message sequence for Echo Requests and Replies.
+         *
+         * @returns The ICMPv6 message sequence.
+         *
+         */
+        uint16_t GetSequence(void) const { return HostSwap16(mData.m16[1]); }
+
+        /**
+         * This method sets the ICMPv6 message sequence for Echo Requests and Replies.
+         *
+         * @param[in]  aSequence  The ICMPv6 message sequence.
+         *
+         */
+        void SetSequence(uint16_t aSequence) { mData.m16[1] = HostSwap16(aSequence); }
+
+    } OT_TOOL_PACKED_END;
+
+    /**
+     * This class implements ICMPv6 message handlers.
+     *
+     */
+    class Handler : public otIcmp6Handler, public LinkedListEntry<Handler>
+    {
+        friend class Icmp;
+
+    public:
+        /**
+         * This constructor creates an ICMPv6 message handler.
+         *
+         * @param[in]  aCallback  A pointer to the function that is called when receiving an ICMPv6 message.
+         * @param[in]  aContext   A pointer to arbitrary context information.
+         *
+         */
+        Handler(otIcmp6ReceiveCallback aCallback, void *aContext)
+        {
+            mReceiveCallback = aCallback;
+            mContext         = aContext;
+            mNext            = nullptr;
+        }
+
+    private:
+        void HandleReceiveMessage(Message &aMessage, const MessageInfo &aMessageInfo, const Header &aIcmp6Header)
+        {
+            mReceiveCallback(mContext, &aMessage, &aMessageInfo, &aIcmp6Header);
+        }
+    };
+
     /**
      * This constructor initializes the object.
      *
@@ -248,7 +240,7 @@
      *
      * @param[in]  aReserved  The number of header bytes to reserve after the ICMP header.
      *
-     * @returns A pointer to the message or NULL if no buffers are available.
+     * @returns A pointer to the message or nullptr if no buffers are available.
      *
      */
     Message *NewMessage(uint16_t aReserved);
@@ -262,7 +254,7 @@
      * @retval OT_ERROR_ALREADY  The ICMPv6 handler is already registered.
      *
      */
-    otError RegisterHandler(IcmpHandler &aHandler);
+    otError RegisterHandler(Handler &aHandler);
 
     /**
      * This method sends an ICMPv6 Echo Request message.
@@ -284,16 +276,13 @@
      * @param[in]  aType         The ICMPv6 message type.
      * @param[in]  aCode         The ICMPv6 message code.
      * @param[in]  aMessageInfo  A reference to the message info.
-     * @param[in]  aHeader       The IPv6 header of the error-causing message.
+     * @param[in]  aMessage      The error-causing IPv6 message.
      *
      * @retval OT_ERROR_NONE     Successfully enqueued the ICMPv6 error message.
      * @retval OT_ERROR_NO_BUFS  Insufficient buffers available.
      *
      */
-    otError SendError(IcmpHeader::Type   aType,
-                      IcmpHeader::Code   aCode,
-                      const MessageInfo &aMessageInfo,
-                      const Header &     aHeader);
+    otError SendError(Header::Type aType, Header::Code aCode, const MessageInfo &aMessageInfo, const Message &aMessage);
 
     /**
      * This method handles an ICMPv6 message.
@@ -346,7 +335,7 @@
 private:
     otError HandleEchoRequest(Message &aRequestMessage, const MessageInfo &aMessageInfo);
 
-    LinkedList<IcmpHandler> mHandlers;
+    LinkedList<Handler> mHandlers;
 
     uint16_t        mEchoSequence;
     otIcmp6EchoMode mEchoMode;
diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp
index 303e03e..0ea4917 100644
--- a/src/core/net/ip6.cpp
+++ b/src/core/net/ip6.cpp
@@ -42,6 +42,7 @@
 #include "common/random.hpp"
 #include "net/icmp6.hpp"
 #include "net/ip6_address.hpp"
+#include "net/ip6_filter.hpp"
 #include "net/netif.hpp"
 #include "net/udp6.hpp"
 #include "thread/mle.hpp"
@@ -53,52 +54,57 @@
     : InstanceLocator(aInstance)
     , mForwardingEnabled(false)
     , mIsReceiveIp6FilterEnabled(false)
-    , mReceiveIp6DatagramCallback(NULL)
-    , mReceiveIp6DatagramCallbackContext(NULL)
+    , mReceiveIp6DatagramCallback(nullptr)
+    , mReceiveIp6DatagramCallbackContext(nullptr)
     , mSendQueue()
-    , mSendQueueTask(aInstance, HandleSendQueue, this)
+    , mSendQueueTask(aInstance, Ip6::HandleSendQueue, this)
     , mIcmp(aInstance)
     , mUdp(aInstance)
     , mMpl(aInstance)
 #if OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE
-    , mTimer(aInstance, &Ip6::HandleTimer, this)
+    , mTimer(aInstance, Ip6::HandleTimer, this)
 #endif
 {
 }
 
-Message *Ip6::NewMessage(uint16_t aReserved, const otMessageSettings *aSettings)
+Message *Ip6::NewMessage(uint16_t aReserved, const Message::Settings &aSettings)
 {
     return Get<MessagePool>().New(Message::kTypeIp6,
                                   sizeof(Header) + sizeof(HopByHopHeader) + sizeof(OptionMpl) + aReserved, aSettings);
 }
 
-Message *Ip6::NewMessage(const uint8_t *aData, uint16_t aDataLength, const otMessageSettings *aSettings)
+Message *Ip6::NewMessage(const uint8_t *aData, uint16_t aDataLength, const Message::Settings &aSettings)
 {
-    otMessageSettings settings = {true, OT_MESSAGE_PRIORITY_NORMAL};
-    Message *         message  = NULL;
+    Message *message = Get<MessagePool>().New(Message::kTypeIp6, 0, aSettings);
 
-    if (aSettings != NULL)
-    {
-        settings = *aSettings;
-    }
-
-    SuccessOrExit(GetDatagramPriority(aData, aDataLength, *reinterpret_cast<uint8_t *>(&settings.mPriority)));
-    VerifyOrExit((message = Get<MessagePool>().New(Message::kTypeIp6, 0, &settings)) != NULL);
+    VerifyOrExit(message != nullptr, OT_NOOP);
 
     if (message->Append(aData, aDataLength) != OT_ERROR_NONE)
     {
         message->Free();
-        message = NULL;
+        message = nullptr;
     }
 
 exit:
     return message;
 }
 
-uint8_t Ip6::DscpToPriority(uint8_t aDscp)
+Message *Ip6::NewMessage(const uint8_t *aData, uint16_t aDataLength)
 {
-    uint8_t priority;
-    uint8_t cs = aDscp & kDscpCsMask;
+    Message *         message = nullptr;
+    Message::Priority priority;
+
+    SuccessOrExit(GetDatagramPriority(aData, aDataLength, priority));
+    message = NewMessage(aData, aDataLength, Message::Settings(Message::kWithLinkSecurity, priority));
+
+exit:
+    return message;
+}
+
+Message::Priority Ip6::DscpToPriority(uint8_t aDscp)
+{
+    Message::Priority priority;
+    uint8_t           cs = aDscp & kDscpCsMask;
 
     switch (cs)
     {
@@ -127,7 +133,7 @@
     return priority;
 }
 
-uint8_t Ip6::PriorityToDscp(uint8_t aPriority)
+uint8_t Ip6::PriorityToDscp(Message::Priority aPriority)
 {
     uint8_t dscp = kDscpCs0;
 
@@ -138,6 +144,7 @@
         break;
 
     case Message::kPriorityNormal:
+    case Message::kPriorityNet:
         dscp = kDscpCs0;
         break;
 
@@ -149,12 +156,12 @@
     return dscp;
 }
 
-otError Ip6::GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, uint8_t &aPriority)
+otError Ip6::GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, Message::Priority &aPriority)
 {
     otError       error = OT_ERROR_NONE;
     const Header *header;
 
-    VerifyOrExit((aData != NULL) && (aDataLen >= sizeof(Header)), error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit((aData != nullptr) && (aDataLen >= sizeof(Header)), error = OT_ERROR_INVALID_ARGS);
 
     header = reinterpret_cast<const Header *>(aData);
     VerifyOrExit(header->IsValid(), error = OT_ERROR_PARSE);
@@ -227,9 +234,7 @@
     MessageInfo                messageInfo(aMessageInfo);
 
     // Use IP-in-IP encapsulation (RFC2473) and ALL_MPL_FORWARDERS address.
-    messageInfo.GetPeerAddr().Clear();
-    messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xff03);
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(0x00fc);
+    messageInfo.GetPeerAddr().SetToRealmLocalAllMplForwarders();
 
     tunnelHeader.Init();
     tunnelHeader.SetHopLimit(static_cast<uint8_t>(kDefaultHopLimit));
@@ -237,7 +242,7 @@
     tunnelHeader.SetDestination(messageInfo.GetPeerAddr());
     tunnelHeader.SetNextHeader(kProtoIp6);
 
-    VerifyOrExit((source = SelectSourceAddress(messageInfo)) != NULL, error = OT_ERROR_INVALID_SOURCE_ADDRESS);
+    VerifyOrExit((source = SelectSourceAddress(messageInfo)) != nullptr, error = OT_ERROR_INVALID_SOURCE_ADDRESS);
 
     tunnelHeader.SetSource(source->GetAddress());
 
@@ -253,7 +258,8 @@
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(aHeader.GetDestination().IsMulticast() &&
-                 aHeader.GetDestination().GetScope() >= Address::kRealmLocalScope);
+                     aHeader.GetDestination().GetScope() >= Address::kRealmLocalScope,
+                 OT_NOOP);
 
     if (aHeader.GetDestination().IsRealmLocalMulticast())
     {
@@ -276,7 +282,7 @@
             aMessage.Write(0, sizeof(hbh), &hbh);
 
             // make space for MPL Option + padding by shifting hop-by-hop option header
-            SuccessOrExit(error = aMessage.Prepend(NULL, 8));
+            SuccessOrExit(error = aMessage.Prepend(nullptr, 8));
             aMessage.CopyTo(8, 0, hbhLength, aMessage);
 
             // insert MPL Option
@@ -303,14 +309,15 @@
     }
     else
     {
+#if OPENTHREAD_FTD
         if (aHeader.GetDestination().IsMulticastLargerThanRealmLocal() &&
             Get<Mle::MleRouter>().HasSleepyChildrenSubscribed(aHeader.GetDestination()))
         {
-            Message *messageCopy = NULL;
+            Message *messageCopy = nullptr;
 
-            if ((messageCopy = aMessage.Clone()) != NULL)
+            if ((messageCopy = aMessage.Clone()) != nullptr)
             {
-                HandleDatagram(*messageCopy, NULL, NULL, true);
+                IgnoreError(HandleDatagram(*messageCopy, nullptr, nullptr, true));
                 otLogInfoIp6("Message copy for indirect transmission to sleepy children");
             }
             else
@@ -318,6 +325,7 @@
                 otLogWarnIp6("No enough buffer for message copy for indirect transmission to sleepy children");
             }
         }
+#endif
 
         SuccessOrExit(error = AddTunneledMplOption(aMessage, aHeader, aMessageInfo));
     }
@@ -340,7 +348,7 @@
     offset = 0;
     aMessage.Read(offset, sizeof(ip6Header), &ip6Header);
     offset += sizeof(ip6Header);
-    VerifyOrExit(ip6Header.GetNextHeader() == kProtoHopOpts);
+    VerifyOrExit(ip6Header.GetNextHeader() == kProtoHopOpts, OT_NOOP);
 
     aMessage.Read(offset, sizeof(hbh), &hbh);
     endOffset = offset + (hbh.GetLength() + 1) * 8;
@@ -472,7 +480,7 @@
 
     if (aMessageInfo.GetSockAddr().IsUnspecified() || aMessageInfo.GetSockAddr().IsMulticast())
     {
-        VerifyOrExit((source = SelectSourceAddress(aMessageInfo)) != NULL, error = OT_ERROR_INVALID_SOURCE_ADDRESS);
+        VerifyOrExit((source = SelectSourceAddress(aMessageInfo)) != nullptr, error = OT_ERROR_INVALID_SOURCE_ADDRESS);
         header.SetSource(source->GetAddress());
     }
     else
@@ -508,11 +516,12 @@
 
     if (aMessageInfo.GetPeerAddr().IsMulticastLargerThanRealmLocal())
     {
+#if OPENTHREAD_FTD
         if (Get<Mle::MleRouter>().HasSleepyChildrenSubscribed(header.GetDestination()))
         {
-            Message *messageCopy = NULL;
+            Message *messageCopy = nullptr;
 
-            if ((messageCopy = aMessage.Clone()) != NULL)
+            if ((messageCopy = aMessage.Clone()) != nullptr)
             {
                 otLogInfoIp6("Message copy for indirect transmission to sleepy children");
                 EnqueueDatagram(*messageCopy);
@@ -522,6 +531,7 @@
                 otLogWarnIp6("No enough buffer for message copy for indirect transmission to sleepy children");
             }
         }
+#endif
 
         SuccessOrExit(error = AddTunneledMplOption(aMessage, header, aMessageInfo));
     }
@@ -552,10 +562,10 @@
 {
     Message *message;
 
-    while ((message = mSendQueue.GetHead()) != NULL)
+    while ((message = mSendQueue.GetHead()) != nullptr)
     {
         mSendQueue.Dequeue(*message);
-        HandleDatagram(*message, NULL, NULL, false);
+        IgnoreError(HandleDatagram(*message, nullptr, nullptr, false));
     }
 }
 
@@ -628,18 +638,18 @@
     otError        error = OT_ERROR_NONE;
     Header         header;
     FragmentHeader fragmentHeader;
-    Message *      fragment        = NULL;
+    Message *      fragment        = nullptr;
     uint16_t       fragmentCnt     = 0;
     uint16_t       payloadFragment = 0;
     uint16_t       offset          = 0;
     int            assertValue     = 0;
 
+    OT_UNUSED_VARIABLE(assertValue);
+
     uint16_t maxPayloadFragment =
         FragmentHeader::MakeDivisibleByEight(kMinimalMtu - aMessage.GetOffset() - sizeof(fragmentHeader));
     uint16_t payloadLeft = aMessage.GetLength() - aMessage.GetOffset();
 
-    VerifyOrExit(aMessage.GetLength() <= kMaxAssembledDatagramLength, error = OT_ERROR_NO_BUFS);
-
     VerifyOrExit(aMessage.Read(0, sizeof(header), &header) == sizeof(header), error = OT_ERROR_PARSE);
     header.SetNextHeader(kProtoFragment);
 
@@ -668,16 +678,16 @@
         offset = fragmentCnt * FragmentHeader::BytesToFragmentOffset(maxPayloadFragment);
         fragmentHeader.SetOffset(offset);
 
-        VerifyOrExit((fragment = NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
+        VerifyOrExit((fragment = NewMessage(0)) != nullptr, error = OT_ERROR_NO_BUFS);
         SuccessOrExit(error = fragment->SetLength(aMessage.GetOffset() + sizeof(fragmentHeader) + payloadFragment));
 
         header.SetPayloadLength(payloadFragment + sizeof(fragmentHeader));
         assertValue = fragment->Write(0, sizeof(header), &header);
-        assert(assertValue == sizeof(header));
+        OT_ASSERT(assertValue == sizeof(header));
 
-        SuccessOrExit(error = fragment->SetOffset(aMessage.GetOffset()));
+        fragment->SetOffset(aMessage.GetOffset());
         assertValue = fragment->Write(aMessage.GetOffset(), sizeof(fragmentHeader), &fragmentHeader);
-        assert(assertValue == sizeof(fragmentHeader));
+        OT_ASSERT(assertValue == sizeof(fragmentHeader));
 
         VerifyOrExit(aMessage.CopyTo(aMessage.GetOffset() + FragmentHeader::FragmentOffsetToBytes(offset),
                                      aMessage.GetOffset() + sizeof(fragmentHeader), payloadFragment,
@@ -687,10 +697,11 @@
         EnqueueDatagram(*fragment);
 
         fragmentCnt++;
-        fragment = NULL;
+        fragment = nullptr;
 
         otLogInfoIp6("Fragment %d with %d bytes sent", fragmentCnt, payloadFragment);
     }
+
     aMessage.Free();
 
 exit:
@@ -700,7 +711,7 @@
         otLogWarnIp6("No buffer for Ip6 fragmentation");
     }
 
-    if (error != OT_ERROR_NONE && fragment != NULL)
+    if (error != OT_ERROR_NONE && fragment != nullptr)
     {
         fragment->Free();
     }
@@ -713,12 +724,14 @@
     otError        error = OT_ERROR_NONE;
     Header         header, headerBuffer;
     FragmentHeader fragmentHeader;
-    Message *      message         = NULL;
+    Message *      message         = nullptr;
     uint16_t       offset          = 0;
     uint16_t       payloadFragment = 0;
     int            assertValue     = 0;
     bool           isFragmented    = true;
 
+    OT_UNUSED_VARIABLE(assertValue);
+
     VerifyOrExit(aMessage.Read(0, sizeof(header), &header) == sizeof(header), error = OT_ERROR_PARSE);
 
     VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(fragmentHeader), &fragmentHeader) == sizeof(fragmentHeader),
@@ -727,8 +740,7 @@
     if (fragmentHeader.GetOffset() == 0 && !fragmentHeader.IsMoreFlagSet())
     {
         isFragmented = false;
-        error        = aMessage.MoveOffset(sizeof(fragmentHeader));
-
+        aMessage.MoveOffset(sizeof(fragmentHeader));
         ExitNow();
     }
 
@@ -747,18 +759,27 @@
     offset          = FragmentHeader::FragmentOffsetToBytes(fragmentHeader.GetOffset());
     payloadFragment = aMessage.GetLength() - aMessage.GetOffset() - sizeof(fragmentHeader);
 
-    if (message == NULL)
+    otLogInfoIp6("Fragment with id %d received > %d bytes, offset %d", fragmentHeader.GetIdentification(),
+                 payloadFragment, offset);
+
+    if (offset + payloadFragment + aMessage.GetOffset() > kMaxAssembledDatagramLength)
     {
-        VerifyOrExit((message = NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
+        otLogWarnIp6("Packet too large for fragment buffer");
+        ExitNow(error = OT_ERROR_NO_BUFS);
+    }
+
+    if (message == nullptr)
+    {
+        VerifyOrExit((message = NewMessage(0)) != nullptr, error = OT_ERROR_NO_BUFS);
         SuccessOrExit(error = message->SetLength(aMessage.GetOffset()));
 
         message->SetTimeout(kIp6ReassemblyTimeout);
-        SuccessOrExit(error = message->SetOffset(0));
+        message->SetOffset(0);
         message->SetDatagramTag(fragmentHeader.GetIdentification());
 
         // copying the non-fragmentable header to the fragmentation buffer
         assertValue = aMessage.CopyTo(0, 0, aMessage.GetOffset(), *message);
-        assert(assertValue == aMessage.GetOffset());
+        OT_ASSERT(assertValue == aMessage.GetOffset());
 
         if (!mTimer.IsRunning())
         {
@@ -770,15 +791,6 @@
         otLogDebgIp6("start reassembly.");
     }
 
-    otLogInfoIp6("Fragment with id %d received > %d bytes, offset %d", message->GetDatagramTag(), payloadFragment,
-                 offset);
-
-    if (offset + payloadFragment + aMessage.GetOffset() > kMaxAssembledDatagramLength)
-    {
-        otLogWarnIp6("Package too large for fragment buffer");
-        ExitNow(error = OT_ERROR_NO_BUFS);
-    }
-
     // increase message buffer if necessary
     if (message->GetLength() < offset + payloadFragment + aMessage.GetOffset())
     {
@@ -788,41 +800,39 @@
     // copy the fragment payload into the message buffer
     assertValue = aMessage.CopyTo(aMessage.GetOffset() + sizeof(fragmentHeader), aMessage.GetOffset() + offset,
                                   payloadFragment, *message);
-    assert(assertValue == static_cast<int>(payloadFragment));
+    OT_ASSERT(assertValue == static_cast<int>(payloadFragment));
 
     // check if it is the last frame
     if (!fragmentHeader.IsMoreFlagSet())
     {
         // use the offset value for the whole ip message length
-        SuccessOrExit(error = message->SetOffset(offset + payloadFragment + aMessage.GetOffset()));
-    }
+        message->SetOffset(aMessage.GetOffset() + offset + payloadFragment);
 
-    if (message->GetOffset() >= message->GetLength())
-    {
         // creates the header for the reassembled ipv6 package
         VerifyOrExit(aMessage.Read(0, sizeof(header), &header) == sizeof(header), error = OT_ERROR_PARSE);
         header.SetPayloadLength(message->GetLength() - sizeof(header));
         header.SetNextHeader(fragmentHeader.GetNextHeader());
         assertValue = message->Write(0, sizeof(header), &header);
-        assert(assertValue == sizeof(header));
+        OT_ASSERT(assertValue == sizeof(header));
 
         otLogDebgIp6("Reassembly complete.");
 
         mReassemblyList.Dequeue(*message);
 
-        error = HandleDatagram(*message, aNetif, aMessageInfo.mLinkInfo, aFromNcpHost);
+        IgnoreError(HandleDatagram(*message, aNetif, aMessageInfo.mLinkInfo, aFromNcpHost));
     }
 
 exit:
     if (error != OT_ERROR_DROP && error != OT_ERROR_NONE && isFragmented)
     {
-        if (message != NULL)
+        if (message != nullptr)
         {
             mReassemblyList.Dequeue(*message);
             message->Free();
         }
         otLogWarnIp6("Reassembly failed: %s", otThreadErrorToString(error));
     }
+
     if (isFragmented)
     {
         // drop all fragments, the payload is stored in the fragment buffer
@@ -837,8 +847,8 @@
     for (Message *message = mReassemblyList.GetHead(); message;)
     {
         Message *next = message->GetNext();
-        mReassemblyList.Dequeue(*message);
 
+        mReassemblyList.Dequeue(*message);
         message->Free();
         message = next;
     }
@@ -853,7 +863,7 @@
 {
     UpdateReassemblyList();
 
-    if (mReassemblyList.GetHead() != NULL)
+    if (mReassemblyList.GetHead() != nullptr)
     {
         mTimer.Start(kStateUpdatePeriod);
     }
@@ -874,7 +884,7 @@
         else
         {
             otLogNoteIp6("Reassembly timeout.");
-            SendIcmpError(*message, IcmpHeader::kTypeTimeExceeded, IcmpHeader::kCodeFragmReasTimeEx);
+            SendIcmpError(*message, Icmp::Header::kTypeTimeExceeded, Icmp::Header::kCodeFragmReasTimeEx);
 
             mReassemblyList.Dequeue(*message);
             message->Free();
@@ -882,7 +892,7 @@
     }
 }
 
-otError Ip6::SendIcmpError(Message &aMessage, IcmpHeader::Type aIcmpType, IcmpHeader::Code aIcmpCode)
+void Ip6::SendIcmpError(Message &aMessage, Icmp::Header::Type aIcmpType, Icmp::Header::Code aIcmpCode)
 {
     otError     error = OT_ERROR_NONE;
     Header      header;
@@ -893,12 +903,16 @@
     messageInfo.SetPeerAddr(header.GetSource());
     messageInfo.SetSockAddr(header.GetDestination());
     messageInfo.SetHopLimit(header.GetHopLimit());
-    messageInfo.SetLinkInfo(NULL);
+    messageInfo.SetLinkInfo(nullptr);
 
-    SuccessOrExit(error = mIcmp.SendError(aIcmpType, aIcmpCode, messageInfo, header));
+    error = mIcmp.SendError(aIcmpType, aIcmpCode, messageInfo, aMessage);
 
 exit:
-    return error;
+
+    if (error != OT_ERROR_NONE)
+    {
+        otLogWarnIp6("Failed to send ICMP error: %s", otThreadErrorToString(error));
+    }
 }
 
 #else
@@ -956,6 +970,9 @@
             break;
 
         case kProtoFragment:
+            // Always forward IPv6 fragments to the Host.
+            IgnoreError(ProcessReceiveCallback(aMessage, aMessageInfo, aNextHeader, aFromNcpHost));
+
             SuccessOrExit(error = HandleFragment(aMessage, aNetif, aMessageInfo, aFromNcpHost));
             break;
 
@@ -1009,36 +1026,38 @@
                                     bool               aFromNcpHost)
 {
     otError  error       = OT_ERROR_NONE;
-    Message *messageCopy = NULL;
+    Message *messageCopy = nullptr;
 
     VerifyOrExit(!aFromNcpHost, error = OT_ERROR_NO_ROUTE);
-    VerifyOrExit(mReceiveIp6DatagramCallback != NULL, error = OT_ERROR_NO_ROUTE);
+    VerifyOrExit(mReceiveIp6DatagramCallback != nullptr, error = OT_ERROR_NO_ROUTE);
+
+    // Do not forward reassembled IPv6 packets.
+    VerifyOrExit(aMessage.GetLength() <= kMinimalMtu, error = OT_ERROR_DROP);
 
     if (mIsReceiveIp6FilterEnabled)
     {
         // do not pass messages sent to an RLOC/ALOC, except Service Locator
-        VerifyOrExit(
-            (!aMessageInfo.GetSockAddr().IsRoutingLocator() && !aMessageInfo.GetSockAddr().IsAnycastRoutingLocator()) ||
-                aMessageInfo.GetSockAddr().IsAnycastServiceLocator(),
-            error = OT_ERROR_NO_ROUTE);
+        VerifyOrExit(!aMessageInfo.GetSockAddr().GetIid().IsLocator() ||
+                         aMessageInfo.GetSockAddr().GetIid().IsAnycastServiceLocator(),
+                     error = OT_ERROR_NO_ROUTE);
 
         switch (aIpProto)
         {
         case kProtoIcmp6:
             if (mIcmp.ShouldHandleEchoRequest(aMessageInfo))
             {
-                IcmpHeader icmp;
+                Icmp::Header icmp;
                 aMessage.Read(aMessage.GetOffset(), sizeof(icmp), &icmp);
 
                 // do not pass ICMP Echo Request messages
-                VerifyOrExit(icmp.GetType() != IcmpHeader::kTypeEchoRequest, error = OT_ERROR_DROP);
+                VerifyOrExit(icmp.GetType() != Icmp::Header::kTypeEchoRequest, error = OT_ERROR_DROP);
             }
 
             break;
 
         case kProtoUdp:
         {
-            UdpHeader udp;
+            Udp::Header udp;
             aMessage.Read(aMessage.GetOffset(), sizeof(udp), &udp);
 
             switch (udp.GetDestinationPort())
@@ -1084,8 +1103,8 @@
     }
 
     // make a copy of the datagram to pass to host
-    VerifyOrExit((messageCopy = aMessage.Clone()) != NULL, error = OT_ERROR_NO_BUFS);
-    RemoveMplOption(*messageCopy);
+    VerifyOrExit((messageCopy = aMessage.Clone()) != nullptr, error = OT_ERROR_NO_BUFS);
+    IgnoreError(RemoveMplOption(*messageCopy));
     mReceiveIp6DatagramCallback(messageCopy, mReceiveIp6DatagramCallbackContext);
 
 exit:
@@ -1119,14 +1138,14 @@
     messageInfo.SetPeerAddr(header.GetSource());
     messageInfo.SetSockAddr(header.GetDestination());
     messageInfo.SetHopLimit(header.GetHopLimit());
-    messageInfo.SetLinkInfo(NULL);
+    messageInfo.SetLinkInfo(nullptr);
 
     if (header.GetDestination().IsMulticast())
     {
         SuccessOrExit(error = InsertMplOption(aMessage, header, messageInfo));
     }
 
-    error = HandleDatagram(aMessage, NULL, NULL, true);
+    error = HandleDatagram(aMessage, nullptr, nullptr, true);
     freed = true;
 
 exit:
@@ -1161,7 +1180,7 @@
     // determine destination of packet
     if (header.GetDestination().IsMulticast())
     {
-        if (aNetif != NULL)
+        if (aNetif != nullptr)
         {
             if (aNetif->IsMulticastSubscribed(header.GetDestination()))
             {
@@ -1172,11 +1191,13 @@
                 multicastPromiscuous = true;
             }
 
+#if OPENTHREAD_FTD
             if (header.GetDestination().IsMulticastLargerThanRealmLocal() &&
                 Get<Mle::MleRouter>().HasSleepyChildrenSubscribed(header.GetDestination()))
             {
                 forward = true;
             }
+#endif
         }
         else
         {
@@ -1185,7 +1206,7 @@
     }
     else
     {
-        if (Get<ThreadNetif>().IsUnicastAddress(header.GetDestination()))
+        if (Get<ThreadNetif>().HasUnicastAddress(header.GetDestination()))
         {
             receive = true;
         }
@@ -1193,7 +1214,7 @@
         {
             forward = true;
         }
-        else if (aNetif == NULL)
+        else if (aNetif == nullptr)
         {
             forward = true;
         }
@@ -1214,17 +1235,34 @@
             // Remove encapsulating header.
             aMessage.RemoveHeader(aMessage.GetOffset());
 
-            HandleDatagram(aMessage, aNetif, aLinkMessageInfo, aFromNcpHost);
+            IgnoreError(HandleDatagram(aMessage, aNetif, aLinkMessageInfo, aFromNcpHost));
             ExitNow(tunnel = true);
         }
 
-        ProcessReceiveCallback(aMessage, messageInfo, nextHeader, aFromNcpHost);
+#if OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE
+        if (nextHeader == kProtoTcp || nextHeader == kProtoUdp)
+        {
+            uint16_t dstPort;
+
+            // TCP/UDP shares header uint16_t srcPort, uint16_t dstPort
+            VerifyOrExit(aMessage.Read(aMessage.GetOffset() + sizeof(uint16_t), sizeof(dstPort), &dstPort) ==
+                             sizeof(dstPort),
+                         error = OT_ERROR_PARSE);
+            dstPort = HostSwap16(dstPort);
+            if (aMessage.IsLinkSecurityEnabled() && Get<ot::Ip6::Filter>().IsUnsecurePort(dstPort))
+            {
+                Get<ot::Ip6::Filter>().RemoveUnsecurePort(dstPort);
+            }
+        }
+#endif
+
+        IgnoreError(ProcessReceiveCallback(aMessage, messageInfo, nextHeader, aFromNcpHost));
 
         SuccessOrExit(error = HandlePayload(aMessage, messageInfo, nextHeader));
     }
     else if (multicastPromiscuous)
     {
-        ProcessReceiveCallback(aMessage, messageInfo, nextHeader, aFromNcpHost);
+        IgnoreError(ProcessReceiveCallback(aMessage, messageInfo, nextHeader, aFromNcpHost));
     }
 
     if (forward)
@@ -1240,7 +1278,7 @@
             ExitNow();
         }
 
-        if (aNetif != NULL)
+        if (aNetif != nullptr)
         {
             VerifyOrExit(mForwardingEnabled, forward = false);
             header.SetHopLimit(header.GetHopLimit() - 1);
@@ -1256,6 +1294,24 @@
             hopLimit = header.GetHopLimit();
             aMessage.Write(Header::GetHopLimitOffset(), Header::GetHopLimitSize(), &hopLimit);
 
+#if OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE
+            // check whether source port is an unsecure port
+            if (aFromNcpHost && (nextHeader == kProtoTcp || nextHeader == kProtoUdp))
+            {
+                uint16_t sourcePort;
+
+                VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(sourcePort), &sourcePort) == sizeof(sourcePort),
+                             error = OT_ERROR_PARSE);
+                sourcePort = HostSwap16(sourcePort);
+                if (Get<ot::Ip6::Filter>().IsUnsecurePort(sourcePort))
+                {
+                    aMessage.SetLinkSecurityEnabled(false);
+                    otLogInfoIp6("Disabled link security for packet to %s",
+                                 header.GetDestination().ToString().AsCString());
+                }
+            }
+#endif
+
             // submit aMessage to interface
             SuccessOrExit(error = Get<ThreadNetif>().SendMessage(aMessage));
         }
@@ -1290,7 +1346,7 @@
         // on-link global address
         ExitNow(rval = true);
     }
-    else if (Get<ThreadNetif>().RouteLookup(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), NULL) ==
+    else if (Get<ThreadNetif>().RouteLookup(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), nullptr) ==
              OT_ERROR_NONE)
     {
         // route
@@ -1309,7 +1365,7 @@
 {
     Address *                  destination       = &aMessageInfo.GetPeerAddr();
     uint8_t                    destinationScope  = destination->GetScope();
-    const NetifUnicastAddress *rvalAddr          = NULL;
+    const NetifUnicastAddress *rvalAddr          = nullptr;
     uint8_t                    rvalPrefixMatched = 0;
 
     for (const NetifUnicastAddress *addr = Get<ThreadNetif>().GetUnicastAddresses(); addr; addr = addr->GetNext())
@@ -1318,7 +1374,7 @@
         uint8_t        candidatePrefixMatched;
         uint8_t        overrideScope;
 
-        if (candidateAddr->IsAnycastRoutingLocator())
+        if (candidateAddr->GetIid().IsAnycastLocator())
         {
             // Don't use anycast address as source address.
             continue;
@@ -1336,7 +1392,7 @@
             overrideScope = destinationScope;
         }
 
-        if (rvalAddr == NULL)
+        if (rvalAddr == nullptr)
         {
             // Rule 0: Prefer any address
             rvalAddr          = addr;
@@ -1388,7 +1444,7 @@
             rvalPrefixMatched = candidatePrefixMatched;
         }
         else if ((candidatePrefixMatched == rvalPrefixMatched) &&
-                 (destination->IsRoutingLocator() == candidateAddr->IsRoutingLocator()))
+                 (destination->GetIid().IsRoutingLocator() == candidateAddr->GetIid().IsRoutingLocator()))
         {
             // Additional rule: Prefer RLOC source for RLOC destination, EID source for anything else
             rvalAddr          = addr;
@@ -1414,6 +1470,11 @@
 {
     bool rval = false;
 
+    if (Get<ThreadNetif>().IsOnMesh(aAddress))
+    {
+        ExitNow(rval = true);
+    }
+
     for (const NetifUnicastAddress *cur = Get<ThreadNetif>().GetUnicastAddresses(); cur; cur = cur->GetNext())
     {
         if (cur->GetAddress().PrefixMatch(aAddress) >= cur->mPrefixLength)
diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp
index 05d7aea..7a5fd90 100644
--- a/src/core/net/ip6.hpp
+++ b/src/core/net/ip6.hpp
@@ -44,6 +44,7 @@
 #include "common/encoding.hpp"
 #include "common/locator.hpp"
 #include "common/message.hpp"
+#include "common/non_copyable.hpp"
 #include "common/timer.hpp"
 #include "net/icmp6.hpp"
 #include "net/ip6_address.hpp"
@@ -98,7 +99,7 @@
  * This class implements the core IPv6 message processing.
  *
  */
-class Ip6 : public InstanceLocator
+class Ip6 : public InstanceLocator, private NonCopyable
 {
     friend class ot::Instance;
 
@@ -116,32 +117,40 @@
     /**
      * This method allocates a new message buffer from the buffer pool.
      *
-     * @note If @p aSettings is 'NULL', the link layer security is enabled and the message priority is set to
-     *       OT_MESSAGE_PRIORITY_NORMAL by default.
-     *
      * @param[in]  aReserved  The number of header bytes to reserve following the IPv6 header.
-     * @param[in]  aSettings  A pointer to the message settings or NULL to set default settings.
+     * @param[in]  aSettings  The message settings.
      *
-     * @returns A pointer to the message or NULL if insufficient message buffers are available.
+     * @returns A pointer to the message or nullptr if insufficient message buffers are available.
      *
      */
-    Message *NewMessage(uint16_t aReserved, const otMessageSettings *aSettings = NULL);
+    Message *NewMessage(uint16_t aReserved, const Message::Settings &aSettings = Message::Settings::GetDefault());
 
     /**
      * This method allocates a new message buffer from the buffer pool and writes the IPv6 datagram to the message.
      *
-     * @note If @p aSettings is NULL, the link layer security is enabled and the message priority is obtained from
-     *       IPv6 message itself.
-     *       If @p aSettings is not NULL, the @p aSetting->mPriority is ignored and obtained from IPv6 message itself.
+     * @param[in]  aData        A pointer to the IPv6 datagram buffer.
+     * @param[in]  aDataLength  The size of the IPV6 datagram buffer pointed by @p aData.
+     * @param[in]  aSettings    The message settings.
+     *
+     * @returns A pointer to the message or nullptr if malformed IPv6 header or insufficient message buffers are
+     * available.
+     *
+     */
+    Message *NewMessage(const uint8_t *aData, uint16_t aDataLength, const Message::Settings &aSettings);
+
+    /**
+     * This method allocates a new message buffer from the buffer pool and writes the IPv6 datagram to the message.
+     *
+     * @note The link layer security is enabled and the message priority is obtained from IPv6 message itself.
      *
      * @param[in]  aData        A pointer to the IPv6 datagram buffer.
      * @param[in]  aDataLength  The size of the IPV6 datagram buffer pointed by @p aData.
-     * @param[in]  aSettings    A pointer to the message settings or NULL to set default settings.
      *
-     * @returns A pointer to the message or NULL if malformed IPv6 header or insufficient message buffers are available.
+     * @returns A pointer to the message or nullptr if malformed IPv6 header or insufficient message buffers are
+     * available.
      *
      */
-    Message *NewMessage(const uint8_t *aData, uint16_t aDataLength, const otMessageSettings *aSettings);
+    Message *NewMessage(const uint8_t *aData, uint16_t aDataLength);
 
     /**
      * This method converts the message priority level to IPv6 DSCP value.
@@ -151,7 +160,7 @@
      * @returns The IPv6 DSCP value.
      *
      */
-    static uint8_t PriorityToDscp(uint8_t aPriority);
+    static uint8_t PriorityToDscp(Message::Priority aPriority);
 
     /**
      * This method converts the IPv6 DSCP value to message priority level.
@@ -161,7 +170,7 @@
      * @returns The message priority level.
      *
      */
-    static uint8_t DscpToPriority(uint8_t aDscp);
+    static Message::Priority DscpToPriority(uint8_t aDscp);
 
     /**
      * This constructor initializes the object.
@@ -259,7 +268,7 @@
      * the Thread control traffic filter setting.
      *
      * @param[in]  aCallback         A pointer to a function that is called when an IPv6 datagram is received
-     *                               or NULL to disable the callback.
+     *                               or nullptr to disable the callback.
      * @param[in]  aCallbackContext  A pointer to application-specific context.
      *
      * @sa IsReceiveIp6FilterEnabled
@@ -313,7 +322,7 @@
      *
      * @param[in]  aMessageInfo  A reference to the message information.
      *
-     * @returns A pointer to the selected IPv6 source address or NULL if no source address was found.
+     * @returns A pointer to the selected IPv6 source address or nullptr if no source address was found.
      *
      */
     const NetifUnicastAddress *SelectSourceAddress(MessageInfo &aMessageInfo);
@@ -343,7 +352,7 @@
     static void HandleSendQueue(Tasklet &aTasklet);
     void        HandleSendQueue(void);
 
-    static otError GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, uint8_t &aPriority);
+    static otError GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, Message::Priority &aPriority);
 
     otError ProcessReceiveCallback(const Message &    aMessage,
                                    const MessageInfo &aMessageInfo,
@@ -363,7 +372,7 @@
     void        CleanupFragmentationBuffer(void);
     void        HandleUpdateTimer(void);
     void        UpdateReassemblyList(void);
-    otError     SendIcmpError(Message &aMessage, IcmpHeader::Type aIcmpType, IcmpHeader::Code aIcmpCode);
+    void        SendIcmpError(Message &aMessage, Icmp::Header::Type aIcmpType, Icmp::Header::Code aIcmpCode);
     static void HandleTimer(Timer &aTimer);
 #endif
     otError AddMplOption(Message &aMessage, Header &aHeader);
diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp
index 8e09810..413d528 100644
--- a/src/core/net/ip6_address.cpp
+++ b/src/core/net/ip6_address.cpp
@@ -38,18 +38,136 @@
 #include "common/code_utils.hpp"
 #include "common/encoding.hpp"
 #include "common/instance.hpp"
+#include "common/random.hpp"
+#include "net/netif.hpp"
 
-using ot::Encoding::BigEndian::HostSwap16;
 using ot::Encoding::BigEndian::HostSwap32;
 
 namespace ot {
 namespace Ip6 {
 
-void Address::Clear(void)
+//---------------------------------------------------------------------------------------------------------------------
+// NetworkPrefix methods
+
+otError NetworkPrefix::GenerateRandomUla(void)
 {
-    memset(mFields.m8, 0, sizeof(mFields));
+    m8[0] = 0xfd;
+
+    return Random::Crypto::FillBuffer(&m8[1], kSize - 1);
 }
 
+//---------------------------------------------------------------------------------------------------------------------
+// InterfaceIdentifier methods
+
+bool InterfaceIdentifier::IsUnspecified(void) const
+{
+    return (mFields.m32[0] == 0) && (mFields.m32[1] == 0);
+}
+
+bool InterfaceIdentifier::IsReserved(void) const
+{
+    return IsSubnetRouterAnycast() || IsReservedSubnetAnycast() || IsAnycastLocator();
+}
+
+bool InterfaceIdentifier::IsSubnetRouterAnycast(void) const
+{
+    return (mFields.m32[0] == 0) && (mFields.m32[1] == 0);
+}
+
+bool InterfaceIdentifier::IsReservedSubnetAnycast(void) const
+{
+    // Format of IID in a Reserved Subnet Anycast Address (RFC 2526)
+    //
+    // |      57 bits     |   7 bits   |
+    // +------------------+------------+
+    // | 1111110111...111 | anycast ID |
+    // +------------------+------------+
+
+    return (mFields.m32[0] == HostSwap32(0xfdffffff) && mFields.m16[2] == HostSwap16(0xffff) && mFields.m8[6] == 0xff &&
+            mFields.m8[7] >= 0x80);
+}
+
+void InterfaceIdentifier::GenerateRandom(void)
+{
+    otError error;
+
+    OT_UNUSED_VARIABLE(error);
+
+    error = Random::Crypto::FillBuffer(mFields.m8, kSize);
+
+    OT_ASSERT(error == OT_ERROR_NONE);
+}
+
+void InterfaceIdentifier::SetBytes(const uint8_t *aBuffer)
+{
+    memcpy(mFields.m8, aBuffer, kSize);
+}
+
+void InterfaceIdentifier::SetFromExtAddress(const Mac::ExtAddress &aExtAddress)
+{
+    Mac::ExtAddress addr;
+
+    addr = aExtAddress;
+    addr.ToggleLocal();
+    addr.CopyTo(mFields.m8);
+}
+
+void InterfaceIdentifier::ConvertToExtAddress(Mac::ExtAddress &aExtAddress) const
+{
+    aExtAddress.Set(mFields.m8);
+    aExtAddress.ToggleLocal();
+}
+
+void InterfaceIdentifier::ConvertToMacAddress(Mac::Address &aMacAddress) const
+{
+    aMacAddress.SetExtended(mFields.m8);
+    aMacAddress.GetExtended().ToggleLocal();
+}
+
+void InterfaceIdentifier::SetToLocator(uint16_t aLocator)
+{
+    // Locator IID pattern `0000:00ff:fe00:xxxx`
+    mFields.m32[0] = HostSwap32(0x000000ff);
+    mFields.m16[2] = HostSwap16(0xfe00);
+    mFields.m16[3] = HostSwap16(aLocator);
+}
+
+bool InterfaceIdentifier::IsLocator(void) const
+{
+    // Locator IID pattern 0000:00ff:fe00:xxxx
+    return (mFields.m32[0] == HostSwap32(0x000000ff) && mFields.m16[2] == HostSwap16(0xfe00));
+}
+
+bool InterfaceIdentifier::IsRoutingLocator(void) const
+{
+    return (IsLocator() && (mFields.m8[6] < kAloc16Mask) && ((mFields.m8[6] & kRloc16ReservedBitMask) == 0));
+}
+
+bool InterfaceIdentifier::IsAnycastLocator(void) const
+{
+    // Anycast locator range 0xfc00- 0xfcff (`kAloc16Mask` is 0xfc)
+    return (IsLocator() && (mFields.m8[6] == kAloc16Mask));
+}
+
+bool InterfaceIdentifier::IsAnycastServiceLocator(void) const
+{
+    uint16_t locator = GetLocator();
+
+    return (IsLocator() && (locator >= Mle::kAloc16ServiceStart) && (locator <= Mle::kAloc16ServiceEnd));
+}
+
+InterfaceIdentifier::InfoString InterfaceIdentifier::ToString(void) const
+{
+    InfoString string;
+
+    IgnoreError(string.AppendHexBytes(mFields.m8, kSize));
+
+    return string;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+// Address methods
+
 bool Address::IsUnspecified(void) const
 {
     return (mFields.m32[0] == 0 && mFields.m32[1] == 0 && mFields.m32[2] == 0 && mFields.m32[3] == 0);
@@ -65,6 +183,20 @@
     return (mFields.m16[0] & HostSwap16(0xffc0)) == HostSwap16(0xfe80);
 }
 
+void Address::SetToLinkLocalAddress(const Mac::ExtAddress &aExtAddress)
+{
+    mFields.m32[0] = HostSwap32(0xfe800000);
+    mFields.m32[1] = 0;
+    GetIid().SetFromExtAddress(aExtAddress);
+}
+
+void Address::SetToLinkLocalAddress(const InterfaceIdentifier &aIid)
+{
+    mFields.m32[0] = HostSwap32(0xfe800000);
+    mFields.m32[1] = 0;
+    SetIid(aIid);
+}
+
 bool Address::IsLinkLocalMulticast(void) const
 {
     return IsMulticast() && (GetScope() == kLinkLocalScope);
@@ -72,14 +204,22 @@
 
 bool Address::IsLinkLocalAllNodesMulticast(void) const
 {
-    return (mFields.m32[0] == HostSwap32(0xff020000) && mFields.m32[1] == 0 && mFields.m32[2] == 0 &&
-            mFields.m32[3] == HostSwap32(0x01));
+    return (*this == GetLinkLocalAllNodesMulticast());
+}
+
+void Address::SetToLinkLocalAllNodesMulticast(void)
+{
+    *this = GetLinkLocalAllNodesMulticast();
 }
 
 bool Address::IsLinkLocalAllRoutersMulticast(void) const
 {
-    return (mFields.m32[0] == HostSwap32(0xff020000) && mFields.m32[1] == 0 && mFields.m32[2] == 0 &&
-            mFields.m32[3] == HostSwap32(0x02));
+    return (*this == GetLinkLocalAllRoutersMulticast());
+}
+
+void Address::SetToLinkLocalAllRoutersMulticast(void)
+{
+    *this = GetLinkLocalAllRoutersMulticast();
 }
 
 bool Address::IsRealmLocalMulticast(void) const
@@ -94,80 +234,77 @@
 
 bool Address::IsRealmLocalAllNodesMulticast(void) const
 {
-    return (mFields.m32[0] == HostSwap32(0xff030000) && mFields.m32[1] == 0 && mFields.m32[2] == 0 &&
-            mFields.m32[3] == HostSwap32(0x01));
+    return (*this == GetRealmLocalAllNodesMulticast());
+}
+
+void Address::SetToRealmLocalAllNodesMulticast(void)
+{
+    *this = GetRealmLocalAllNodesMulticast();
 }
 
 bool Address::IsRealmLocalAllRoutersMulticast(void) const
 {
-    return (mFields.m32[0] == HostSwap32(0xff030000) && mFields.m32[1] == 0 && mFields.m32[2] == 0 &&
-            mFields.m32[3] == HostSwap32(0x02));
+    return (*this == GetRealmLocalAllRoutersMulticast());
+}
+
+void Address::SetToRealmLocalAllRoutersMulticast(void)
+{
+    *this = GetRealmLocalAllRoutersMulticast();
 }
 
 bool Address::IsRealmLocalAllMplForwarders(void) const
 {
-    return (mFields.m32[0] == HostSwap32(0xff030000) && mFields.m32[1] == 0 && mFields.m32[2] == 0 &&
-            mFields.m32[3] == HostSwap32(0xfc));
+    return (*this == GetRealmLocalAllMplForwarders());
 }
 
-bool Address::IsRoutingLocator(void) const
+void Address::SetToRealmLocalAllMplForwarders(void)
 {
-    return (mFields.m32[2] == HostSwap32(0x000000ff) && mFields.m16[6] == HostSwap16(0xfe00) &&
-            mFields.m8[14] < kAloc16Mask && (mFields.m8[14] & kRloc16ReservedBitMask) == 0);
+    *this = GetRealmLocalAllMplForwarders();
 }
 
-bool Address::IsAnycastRoutingLocator(void) const
+void Address::SetPrefix(const NetworkPrefix &aNetworkPrefix)
 {
-    return (mFields.m32[2] == HostSwap32(0x000000ff) && mFields.m16[6] == HostSwap16(0xfe00) &&
-            mFields.m8[14] == kAloc16Mask);
+    mFields.mComponents.mNetworkPrefix = aNetworkPrefix;
 }
 
-bool Address::IsAnycastServiceLocator(void) const
+void Address::SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
 {
-    return IsAnycastRoutingLocator() && (mFields.m8[15] >= (Mle::kAloc16ServiceStart & 0xff)) &&
-           (mFields.m8[15] <= (Mle::kAloc16ServiceEnd & 0xff));
+    SetPrefix(0, aPrefix, aPrefixLength);
 }
 
-bool Address::IsSubnetRouterAnycast(void) const
+void Address::SetPrefix(uint8_t aOffset, const uint8_t *aPrefix, uint8_t aPrefixLength)
 {
-    return (mFields.m32[2] == 0 && mFields.m32[3] == 0);
+    uint8_t bytes     = aPrefixLength / CHAR_BIT;
+    uint8_t extraBits = aPrefixLength % CHAR_BIT;
+
+    OT_ASSERT(aPrefixLength <= (sizeof(Address) - aOffset) * CHAR_BIT);
+
+    memcpy(mFields.m8 + aOffset, aPrefix, bytes);
+
+    if (extraBits > 0)
+    {
+        uint8_t index = aOffset + bytes;
+        uint8_t mask  = ((0x80 >> (extraBits - 1)) - 1);
+
+        // `mask` has its higher (msb) `extraBits` bits as `0` and the remaining as `1`.
+        // Example with `extraBits` = 3:
+        // ((0x80 >> 2) - 1) = (0b0010_0000 - 1) = 0b0001_1111
+
+        mFields.m8[index] &= mask;
+        mFields.m8[index] |= (aPrefix[index] & ~mask);
+    }
 }
 
-bool Address::IsReservedSubnetAnycast(void) const
+void Address::SetMulticastNetworkPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
 {
-    return (mFields.m32[2] == HostSwap32(0xfdffffff) && mFields.m16[6] == 0xffff && mFields.m8[14] == 0xff &&
-            mFields.m8[15] >= 0x80);
+    SetPrefix(kMulticastNetworkPrefixOffset, aPrefix, aPrefixLength);
+    mFields.m8[kMulticastNetworkPrefixLengthOffset] = aPrefixLength;
 }
 
-bool Address::IsIidReserved(void) const
+void Address::SetToLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aLocator)
 {
-    return IsSubnetRouterAnycast() || IsReservedSubnetAnycast() || IsAnycastRoutingLocator();
-}
-
-void Address::SetIid(const uint8_t *aIid)
-{
-    memcpy(mFields.m8 + kInterfaceIdentifierOffset, aIid, kInterfaceIdentifierSize);
-}
-
-void Address::SetIid(const Mac::ExtAddress &aExtAddress)
-{
-    Mac::ExtAddress addr;
-
-    addr = aExtAddress;
-    addr.ToggleLocal();
-    addr.CopyTo(mFields.m8 + kInterfaceIdentifierOffset);
-}
-
-void Address::ToExtAddress(Mac::ExtAddress &aExtAddress) const
-{
-    aExtAddress.Set(mFields.m8 + kInterfaceIdentifierOffset);
-    aExtAddress.ToggleLocal();
-}
-
-void Address::ToExtAddress(Mac::Address &aMacAddress) const
-{
-    aMacAddress.SetExtended(mFields.m8 + kInterfaceIdentifierOffset);
-    aMacAddress.GetExtended().ToggleLocal();
+    SetPrefix(aNetworkPrefix);
+    GetIid().SetToLocator(aLocator);
 }
 
 uint8_t Address::GetScope(void) const
@@ -232,18 +369,13 @@
     return PrefixMatch(mFields.m8, aOther.mFields.m8, sizeof(Address));
 }
 
-bool Address::operator==(const Address &aOther) const
-{
-    return memcmp(mFields.m8, aOther.mFields.m8, sizeof(mFields.m8)) == 0;
-}
-
 otError Address::FromString(const char *aBuf)
 {
     otError     error  = OT_ERROR_NONE;
     uint8_t *   dst    = reinterpret_cast<uint8_t *>(mFields.m8);
     uint8_t *   endp   = reinterpret_cast<uint8_t *>(mFields.m8 + 15);
-    uint8_t *   colonp = NULL;
-    const char *colonc = NULL;
+    uint8_t *   colonp = nullptr;
+    const char *colonc = nullptr;
     uint16_t    val    = 0;
     uint8_t     count  = 0;
     bool        first  = true;
@@ -277,7 +409,7 @@
             }
             else if (ch == ':')
             {
-                VerifyOrExit(colonp == NULL || first, error = OT_ERROR_PARSE);
+                VerifyOrExit(colonp == nullptr || first, error = OT_ERROR_PARSE);
                 colonp = dst;
             }
 
@@ -372,5 +504,30 @@
                       HostSwap16(mFields.m16[5]), HostSwap16(mFields.m16[6]), HostSwap16(mFields.m16[7]));
 }
 
+const Address &Address::GetLinkLocalAllNodesMulticast(void)
+{
+    return static_cast<const Address &>(Netif::kLinkLocalAllNodesMulticastAddress.mAddress);
+}
+
+const Address &Address::GetLinkLocalAllRoutersMulticast(void)
+{
+    return static_cast<const Address &>(Netif::kLinkLocalAllRoutersMulticastAddress.mAddress);
+}
+
+const Address &Address::GetRealmLocalAllNodesMulticast(void)
+{
+    return static_cast<const Address &>(Netif::kRealmLocalAllNodesMulticastAddress.mAddress);
+}
+
+const Address &Address::GetRealmLocalAllRoutersMulticast(void)
+{
+    return static_cast<const Address &>(Netif::kRealmLocalAllRoutersMulticastAddress.mAddress);
+}
+
+const Address &Address::GetRealmLocalAllMplForwarders(void)
+{
+    return static_cast<const Address &>(Netif::kRealmLocalAllMplForwardersMulticastAddress.mAddress);
+}
+
 } // namespace Ip6
 } // namespace ot
diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp
index 3b7a9ff..7c23019 100644
--- a/src/core/net/ip6_address.hpp
+++ b/src/core/net/ip6_address.hpp
@@ -38,9 +38,14 @@
 
 #include <stdint.h>
 
+#include "common/clearable.hpp"
+#include "common/encoding.hpp"
+#include "common/equatable.hpp"
 #include "common/string.hpp"
 #include "mac/mac_types.hpp"
 
+using ot::Encoding::BigEndian::HostSwap16;
+
 namespace ot {
 namespace Ip6 {
 
@@ -52,11 +57,237 @@
  */
 
 /**
+ * This class represents the Network Prefix of an IPv6 address (most significant 64 bits of the address).
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+class NetworkPrefix : public otIp6NetworkPrefix, public Equatable<NetworkPrefix>, public Clearable<NetworkPrefix>
+{
+public:
+    enum
+    {
+        kSize   = OT_IP6_PREFIX_SIZE,            ///< Size in bytes.
+        kLength = OT_IP6_PREFIX_SIZE * CHAR_BIT, ///< Length of Network Prefix in bits.
+    };
+
+    /**
+     * This method generates and sets the Network Prefix to a crypto-secure random Unique Local Address (ULA) based
+     * on the pattern `fdxx:xxxx:xxxx:` (RFC 4193).
+     *
+     * @retval OT_ERROR_NONE     Successfully generated a random ULA Network Prefix
+     * @retval OT_ERROR_FAILED   Failed to generate random ULA Network Prefix.
+     *
+     */
+    otError GenerateRandomUla(void);
+
+} OT_TOOL_PACKED_END;
+
+/**
+ * This class represents the Interface Identifier of an IPv6 address.
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+class InterfaceIdentifier : public otIp6InterfaceIdentifier,
+                            public Equatable<InterfaceIdentifier>,
+                            public Clearable<InterfaceIdentifier>
+{
+    friend class Address;
+
+public:
+    enum
+    {
+        kSize           = OT_IP6_IID_SIZE, ///< Size of an IPv6 Interface Identifier (in bytes).
+        kInfoStringSize = 17,              ///< Max chars for the info string (`ToString()`).
+    };
+
+    /**
+     * This type defines the fixed-length `String` object returned from `ToString()`.
+     *
+     */
+    typedef String<kInfoStringSize> InfoString;
+
+    /**
+     * This method indicates whether or not the Interface Identifier is unspecified.
+     *
+     * @retval true  If the Interface Identifier is unspecified.
+     * @retval false If the Interface Identifier is not unspecified.
+     *
+     */
+    bool IsUnspecified(void) const;
+
+    /**
+     * This method indicates whether or not the Interface Identifier is reserved (RFC 5453).
+     *
+     * @retval true  If the Interface Identifier is reserved.
+     * @retval false If the Interface Identifier is not reserved.
+     *
+     */
+    bool IsReserved(void) const;
+
+    /**
+     * This method indicates whether or not the Interface Identifier is Subnet-Router Anycast (RFC 4291).
+     *
+     * @retval TRUE   If the Interface Identifier is a Subnet-Router Anycast address.
+     * @retval FALSE  If the Interface Identifier is not a Subnet-Router Anycast address.
+     *
+     */
+    bool IsSubnetRouterAnycast(void) const;
+
+    /**
+     * This method indicates whether or not the Interface Identifier is Reserved Subnet Anycast (RFC 2526).
+     *
+     * @retval TRUE   If the Interface Identifier is a Reserved Subnet Anycast address.
+     * @retval FALSE  If the Interface Identifier is not a Reserved Subnet Anycast address.
+     *
+     */
+    bool IsReservedSubnetAnycast(void) const;
+
+    /**
+     * This method generates and sets the Interface Identifier to a crypto-secure random byte sequence.
+     *
+     */
+    void GenerateRandom(void);
+
+    /**
+     * This method gets the Interface Identifier as a pointer to a byte array.
+     *
+     * @returns A pointer to a byte array (of size `kSize`) containing the Interface Identifier.
+     *
+     */
+    const uint8_t *GetBytes(void) const { return mFields.m8; }
+
+    /**
+     * This method sets the Interface Identifier from a given byte array.
+     *
+     * @param[in] aBuffer    Pointer to an array containing the Interface Identifier. `kSize` bytes from the buffer
+     *                       are copied to form the Interface Identifier.
+     *
+     */
+    void SetBytes(const uint8_t *aBuffer);
+
+    /**
+     * This method sets the Interface Identifier from a given IEEE 802.15.4 Extended Address.
+     *
+     * @param[in] aExtAddress  An Extended Address.
+     *
+     */
+    void SetFromExtAddress(const Mac::ExtAddress &aExtAddress);
+
+    /**
+     * This method converts the Interface Identifier to an IEEE 802.15.4 Extended Address.
+     *
+     * @param[out]  aExtAddress  A reference to an Extended Address where the converted address is placed.
+     *
+     */
+    void ConvertToExtAddress(Mac::ExtAddress &aExtAddress) const;
+
+    /**
+     * This method converts the Interface Identifier to an IEEE 802.15.4 MAC Address.
+     *
+     * @param[out]  aMacAddress  A reference to a MAC Address where the converted address is placed.
+     *
+     */
+    void ConvertToMacAddress(Mac::Address &aMacAddress) const;
+
+    /**
+     * This method sets the Interface Identifier to Routing/Anycast Locator pattern `0000:00ff:fe00:xxxx` with a given
+     * locator (RLOC16 or ALOC16) value.
+     *
+     * @param[in]  aLocator    RLOC16 or ALOC16.
+     *
+     */
+    void SetToLocator(uint16_t aLocator);
+
+    /**
+     * This method indicates whether or not the Interface Identifier matches the locator pattern `0000:00ff:fe00:xxxx`.
+     *
+     * @retval TRUE   If the IID matches the locator pattern.
+     * @retval FALSE  If the IID does not match the locator pattern.
+     *
+     */
+    bool IsLocator(void) const;
+
+    /**
+     * This method indicates whether or not the Interface Identifier (IID) matches a Routing Locator (RLOC).
+     *
+     * In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also
+     * checks that the locator value is a valid RLOC16.
+     *
+     * @retval TRUE   If the IID matches a RLOC address.
+     * @retval FALSE  If the IID does not match a RLOC address.
+     *
+     */
+    bool IsRoutingLocator(void) const;
+
+    /**
+     * This method indicates whether or not the Interface Identifier (IID) matches an Anycast Locator (ALOC).
+     *
+     * In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also
+     * checks that the locator value is any valid ALOC16 (0xfc00 - 0xfcff).
+     *
+     * @retval TRUE   If the IID matches a ALOC address.
+     * @retval FALSE  If the IID does not match a ALOC address.
+     *
+     */
+    bool IsAnycastLocator(void) const;
+
+    /**
+     * This method indicates whether or not the Interface Identifier (IID) matches a Service Anycast  Locator (ALOC).
+     *
+     * In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also
+     * checks that the locator value is a valid Service ALOC16 (0xfc10 – 0xfc2f).
+     *
+     * @retval TRUE   If the IID matches a ALOC address.
+     * @retval FALSE  If the IID does not match a ALOC address.
+     *
+     */
+    bool IsAnycastServiceLocator(void) const;
+
+    /**
+     * This method gets the Interface Identifier (IID) address locator fields.
+     *
+     * This method assumes the IID to match the locator pattern `0000:00ff:fe00:xxxx` (does not explicitly check this)
+     * and returns the last `uint16` portion of the IID.
+     *
+     * @returns The RLOC16 or ALOC16.
+     *
+     */
+    uint16_t GetLocator(void) const { return HostSwap16(mFields.m16[3]); }
+
+    /**
+     * This method sets the Interface Identifier (IID) address locator field.
+     *
+     * Unlike `SetToLocator()`, this method only changes the last 2 bytes of the IID and keeps the rest of the address
+     * as before.
+     *
+     * @param[in]  aLocator   RLOC16 or ALOC16.
+     *
+     */
+    void SetLocator(uint16_t aLocator) { mFields.m16[3] = HostSwap16(aLocator); }
+
+    /**
+     * This method converts an Interface Identifier to a string.
+     *
+     * @returns An `InfoString` containing the string representation of the Interface Identifier.
+     *
+     */
+    InfoString ToString(void) const;
+
+private:
+    enum : uint8_t
+    {
+        kAloc16Mask            = 0xfc, // The mask for Aloc16.
+        kRloc16ReservedBitMask = 0x02, // The mask for the reserved bit of Rloc16.
+    };
+
+} OT_TOOL_PACKED_END;
+
+/**
  * This class implements an IPv6 address object.
  *
  */
 OT_TOOL_PACKED_BEGIN
-class Address : public otIp6Address
+class Address : public otIp6Address, public Equatable<Address>, public Clearable<Address>
 {
 public:
     /**
@@ -65,8 +296,7 @@
      */
     enum
     {
-        kAloc16Mask            = 0xfc, ///< The mask for Aloc16.
-        kRloc16ReservedBitMask = 0x02, ///< The mask for the reserved bit of Rloc16.
+        kAloc16Mask = InterfaceIdentifier::kAloc16Mask, ///< The mask for Aloc16.
     };
 
     /**
@@ -75,10 +305,8 @@
      */
     enum
     {
-        kInterfaceIdentifierSize = 8,  ///< Interface Identifier size in bytes.
-        kIp6AddressStringSize    = 40, ///< Max buffer size in bytes to store an IPv6 address in string format.
-        kMeshLocalPrefixLength   = 64, ///< Length of Thread mesh local prefix.
-        kMeshLocalPrefixSize     = 8,  ///< Mesh local prefix size in bytes.
+        kSize                 = OT_IP6_ADDRESS_SIZE, ///< Size of an IPv6 Address (in bytes).
+        kIp6AddressStringSize = 40, ///< Max buffer size in bytes to store an IPv6 address in string format.
     };
 
     /**
@@ -103,12 +331,6 @@
     typedef String<kIp6AddressStringSize> InfoString;
 
     /**
-     * This method clears the IPv6 address by setting it to the Unspecified Address "::".
-     *
-     */
-    void Clear(void);
-
-    /**
      * This method indicates whether or not the IPv6 address is the Unspecified Address.
      *
      * @retval TRUE   If the IPv6 address is the Unspecified Address.
@@ -136,6 +358,23 @@
     bool IsLinkLocal(void) const;
 
     /**
+     * This methods sets the IPv6 address to a Link-Local address with Interface Identifier generated from a given
+     * MAC Extended Address.
+     *
+     * @param[in]  aExtAddress  A MAC Extended Address (used to generate the IID).
+     *
+     */
+    void SetToLinkLocalAddress(const Mac::ExtAddress &aExtAddress);
+
+    /**
+     * This methods sets the IPv6 address to a Link-Local address with a given Interface Identifier.
+     *
+     * @param[in]  aIid   An Interface Identifier.
+     *
+     */
+    void SetToLinkLocalAddress(const InterfaceIdentifier &aIid);
+
+    /**
      * This method indicates whether or not the IPv6 address is multicast address.
      *
      * @retval TRUE   If the IPv6 address is a multicast address.
@@ -154,7 +393,7 @@
     bool IsLinkLocalMulticast(void) const;
 
     /**
-     * This method indicates whether or not the IPv6 address is a link-local all nodes multicast address.
+     * This method indicates whether or not the IPv6 address is a link-local all nodes multicast address (ff02::01).
      *
      * @retval TRUE   If the IPv6 address is a link-local all nodes multicast address.
      * @retval FALSE  If the IPv6 address is not a link-local all nodes multicast address.
@@ -163,7 +402,13 @@
     bool IsLinkLocalAllNodesMulticast(void) const;
 
     /**
-     * This method indicates whether or not the IPv6 address is a link-local all routers multicast address.
+     * This method sets the IPv6 address to the link-local all nodes multicast address (ff02::01).
+     *
+     */
+    void SetToLinkLocalAllNodesMulticast(void);
+
+    /**
+     * This method indicates whether or not the IPv6 address is a link-local all routers multicast address (ff02::02).
      *
      * @retval TRUE   If the IPv6 address is a link-local all routers multicast address.
      * @retval FALSE  If the IPv6 address is not a link-local all routers multicast address.
@@ -172,6 +417,12 @@
     bool IsLinkLocalAllRoutersMulticast(void) const;
 
     /**
+     * This method sets the IPv6 address to the link-local all routers multicast address (ff02::02).
+     *
+     */
+    void SetToLinkLocalAllRoutersMulticast(void);
+
+    /**
      * This method indicates whether or not the IPv6 address is a realm-local multicast address.
      *
      * @retval TRUE   If the IPv6 address is a realm-local multicast address.
@@ -181,7 +432,7 @@
     bool IsRealmLocalMulticast(void) const;
 
     /**
-     * This method indicates whether or not the IPv6 address is a realm-local all nodes multicast address.
+     * This method indicates whether or not the IPv6 address is a realm-local all nodes multicast address (ff03::01).
      *
      * @retval TRUE   If the IPv6 address is a realm-local all nodes multicast address.
      * @retval FALSE  If the IPv6 address is not a realm-local all nodes multicast address.
@@ -190,7 +441,13 @@
     bool IsRealmLocalAllNodesMulticast(void) const;
 
     /**
-     * This method indicates whether or not the IPv6 address is a realm-local all routers multicast address.
+     * This method sets the IPv6 address to the realm-local all nodes multicast address (ff03::01)
+     *
+     */
+    void SetToRealmLocalAllNodesMulticast(void);
+
+    /**
+     * This method indicates whether or not the IPv6 address is a realm-local all routers multicast address (ff03::02).
      *
      * @retval TRUE   If the IPv6 address is a realm-local all routers multicast address.
      * @retval FALSE  If the IPv6 address is not a realm-local all routers multicast address.
@@ -199,7 +456,13 @@
     bool IsRealmLocalAllRoutersMulticast(void) const;
 
     /**
-     * This method indicates whether or not the IPv6 address is a realm-local all MPL forwarders address.
+     * This method sets the IPv6 address to the realm-local all routers multicast address (ff03::02).
+     *
+     */
+    void SetToRealmLocalAllRoutersMulticast(void);
+
+    /**
+     * This method indicates whether or not the IPv6 address is a realm-local all MPL forwarders address (ff03::fc).
      *
      * @retval TRUE   If the IPv6 address is a realm-local all MPL forwarders address.
      * @retval FALSE  If the IPv6 address is not a realm-local all MPL forwarders address.
@@ -208,6 +471,12 @@
     bool IsRealmLocalAllMplForwarders(void) const;
 
     /**
+     * This method sets the the IPv6 address to the realm-local all MPL forwarders address (ff03::fc).
+     *
+     */
+    void SetToRealmLocalAllMplForwarders(void);
+
+    /**
      * This method indicates whether or not the IPv6 address is multicast larger than realm local.
      *
      * @retval TRUE   If the IPv6 address is multicast larger than realm local.
@@ -217,106 +486,119 @@
     bool IsMulticastLargerThanRealmLocal(void) const;
 
     /**
-     * This method indicates whether or not the IPv6 address is a RLOC address.
+     * This method sets the IPv6 address to a Routing Locator (RLOC) IPv6 address with a given Network Prefix and
+     * RLOC16 value.
      *
-     * @retval TRUE   If the IPv6 address is a RLOC address.
-     * @retval FALSE  If the IPv6 address is not a RLOC address.
+     * @param[in]  aNetworkPrefix    A Network Prefix.
+     * @param[in]  aRloc16           A RLOC16 value.
      *
      */
-    bool IsRoutingLocator(void) const;
+    void SetToRoutingLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aRloc16)
+    {
+        SetToLocator(aNetworkPrefix, aRloc16);
+    }
 
     /**
-     * This method indicates whether or not the IPv6 address is an Anycast RLOC address.
+     * This method sets the IPv6 address to a Anycast Locator (ALOC) IPv6 address with a given Network Prefix and
+     * ALOC16 value.
      *
-     * @retval TRUE   If the IPv6 address is an Anycast RLOC address.
-     * @retval FALSE  If the IPv6 address is not an Anycast RLOC address.
+     * @param[in]  aNetworkPrefix    A Network Prefix.
+     * @param[in]  aAloc16           A ALOC16 value.
      *
      */
-    bool IsAnycastRoutingLocator(void) const;
+    void SetToAnycastLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aAloc16)
+    {
+        SetToLocator(aNetworkPrefix, aAloc16);
+    }
 
     /**
-     * This method indicates whether or not the IPv6 address is an Anycast Service Locator.
+     * This method returns the Network Prefix of the IPv6 address (most significant 64 bits of the address).
      *
-     * @retval TRUE   If the IPv6 address is an Anycast Service Locator.
-     * @retval FALSE  If the IPv6 address is not an Anycast Service Locator.
+     * @returns A reference to the Network Prefix.
      *
      */
-    bool IsAnycastServiceLocator(void) const;
+    const NetworkPrefix &GetPrefix(void) const
+    {
+        return static_cast<const NetworkPrefix &>(mFields.mComponents.mNetworkPrefix);
+    }
 
     /**
-     * This method indicates whether or not the IPv6 address is Subnet-Router Anycast (RFC 4291),
+     * This method sets the IPv6 address prefix.
      *
-     * @retval TRUE   If the IPv6 address is a Subnet-Router Anycast address.
-     * @retval FALSE  If the IPv6 address is not a Subnet-Router Anycast address.
+     * This method only changes the first @p aPrefixLength bits of the address and keeps the rest of the bits in the
+     * address as before.
+     *
+     * @param[in]  aPrefix         A buffer containing the prefix
+     * @param[in]  aPrefixLength   The prefix length (in bits).
      *
      */
-    bool IsSubnetRouterAnycast(void) const;
+    void SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength);
 
     /**
-     * This method indicates whether or not the IPv6 address is Reserved Subnet Anycast (RFC 2526),
+     * This method sets the IPv6 address prefix to the given Network Prefix.
      *
-     * @retval TRUE   If the IPv6 address is a Reserved Subnet Anycast address.
-     * @retval FALSE  If the IPv6 address is not a Reserved Subnet Anycast address.
+     * @param[in]  aNetworkPrefix   A Network Prefix.
      *
      */
-    bool IsReservedSubnetAnycast(void) const;
+    void SetPrefix(const NetworkPrefix &aNetworkPrefix);
 
     /**
-     * This method indicates whether or not the IPv6 address contains Reserved IPv6 IID (RFC 5453),
+     * This method sets the prefix content of the Prefix-Based Multicast Address.
      *
-     * @retval TRUE   If the IPv6 address contains a reserved IPv6 IID.
-     * @retval FALSE  If the IPv6 address does not contain a reserved IPv6 IID.
+     * @param[in]  aPrefix         A buffer containing the prefix.
+     * @param[in]  aPrefixLength   The prefix length (in bits).
      *
      */
-    bool IsIidReserved(void) const;
+    void SetMulticastNetworkPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength);
 
     /**
-     * This method returns a pointer to the Interface Identifier.
+     * This method sets the prefix content of Prefix-Based Multicast Address.
      *
-     * @returns A pointer to the Interface Identifier.
+     * @param[in]  aNetworkPrefix   A reference to a Network Prefix.
      *
      */
-    const uint8_t *GetIid(void) const { return mFields.m8 + kInterfaceIdentifierOffset; }
+    void SetMulticastNetworkPrefix(const NetworkPrefix &aNetworkPrefix)
+    {
+        SetMulticastNetworkPrefix(aNetworkPrefix.m8, NetworkPrefix::kLength);
+    }
 
     /**
-     * This method returns a pointer to the Interface Identifier.
+     * This method sets the prefix content of Prefix-Based Multicast Address.
      *
-     * @returns A pointer to the Interface Identifier.
+     * @param[in]  aPrefix A reference to an IPv6 Prefix.
      *
      */
-    uint8_t *GetIid(void) { return mFields.m8 + kInterfaceIdentifierOffset; }
+    void SetMulticastNetworkPrefix(const otIp6Prefix &aPrefix)
+    {
+        SetMulticastNetworkPrefix(aPrefix.mPrefix.mFields.m8, aPrefix.mLength);
+    }
+
+    /**
+     * This method returns the Interface Identifier of the IPv6 address.
+     *
+     * @returns A reference to the Interface Identifier.
+     *
+     */
+    const InterfaceIdentifier &GetIid(void) const
+    {
+        return static_cast<const InterfaceIdentifier &>(mFields.mComponents.mIid);
+    }
+
+    /**
+     * This method returns the Interface Identifier of the IPv6 address.
+     *
+     * @returns A reference to the Interface Identifier.
+     *
+     */
+    InterfaceIdentifier &GetIid(void) { return static_cast<InterfaceIdentifier &>(mFields.mComponents.mIid); }
 
     /**
      * This method sets the Interface Identifier.
      *
-     * @param[in]  aIid  A reference to the Interface Identifier.
+     * @param[in]  aIid  An Interface Identifier.
      *
      */
-    void SetIid(const uint8_t *aIid);
-
-    /**
-     * This method sets the Interface Identifier.
-     *
-     * @param[in]  aExtAddress  A reference to the extended address.
-     *
-     */
-    void SetIid(const Mac::ExtAddress &aExtAddress);
-
-    /**
-     * This method converts the IPv6 Interface Identifier to an IEEE 802.15.4 Extended Address.
-     *
-     * @param[out]  aExtAddress  A reference to the extended address.
-     *
-     */
-    void ToExtAddress(Mac::ExtAddress &aExtAddress) const;
-
-    /**
-     * This method converts the IPv6 Interface Identifier to an IEEE 802.15.4 MAC Address.
-     *
-     * @param[out]  aMacAddress  A reference to the MAC address.
-     *
-     */
-    void ToExtAddress(Mac::Address &aMacAddress) const;
+    void SetIid(const InterfaceIdentifier &aIid) { GetIid() = aIid; }
 
     /**
      * This method returns the IPv6 address scope.
@@ -337,31 +619,9 @@
     uint8_t PrefixMatch(const otIp6Address &aOther) const;
 
     /**
-     * This method evaluates whether or not the IPv6 addresses match.
-     *
-     * @param[in]  aOther  The IPv6 address to compare.
-     *
-     * @retval TRUE   If the IPv6 addresses match.
-     * @retval FALSE  If the IPv6 addresses do not match.
-     *
-     */
-    bool operator==(const Address &aOther) const;
-
-    /**
-     * This method evaluates whether or not the IPv6 addresses differ.
-     *
-     * @param[in]  aOther  The IPv6 address to compare.
-     *
-     * @retval TRUE   If the IPv6 addresses differ.
-     * @retval FALSE  If the IPv6 addresses do not differ.
-     *
-     */
-    bool operator!=(const Address &aOther) const { return !(*this == aOther); }
-
-    /**
      * This method converts an IPv6 address string to binary.
      *
-     * @param[in]  aBuf  A pointer to the NULL-terminated string.
+     * @param[in]  aBuf  A pointer to the null-terminated string.
      *
      * @retval OT_ERROR_NONE          Successfully parsed the IPv6 address string.
      * @retval OT_ERROR_INVALID_ARGS  Failed to parse the IPv6 address string.
@@ -390,10 +650,20 @@
     static uint8_t PrefixMatch(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxLength);
 
 private:
+    void SetPrefix(uint8_t aOffset, const uint8_t *aPrefix, uint8_t aPrefixLength);
+    void SetToLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aLocator);
+
+    static const Address &GetLinkLocalAllNodesMulticast(void);
+    static const Address &GetLinkLocalAllRoutersMulticast(void);
+    static const Address &GetRealmLocalAllNodesMulticast(void);
+    static const Address &GetRealmLocalAllRoutersMulticast(void);
+    static const Address &GetRealmLocalAllMplForwarders(void);
+
     enum
     {
-        kInterfaceIdentifierOffset = 8, ///< Interface Identifier offset in bytes.
-        kIp4AddressSize            = 4  ///< Size of the IPv4 address.
+        kIp4AddressSize                     = 4, ///< Size of the IPv4 address.
+        kMulticastNetworkPrefixLengthOffset = 3, ///< Prefix-Based Multicast Address (RFC3306).
+        kMulticastNetworkPrefixOffset       = 4, ///< Prefix-Based Multicast Address (RFC3306).
     };
 } OT_TOOL_PACKED_END;
 
diff --git a/src/core/net/ip6_filter.cpp b/src/core/net/ip6_filter.cpp
index 60e4776..2bedada 100644
--- a/src/core/net/ip6_filter.cpp
+++ b/src/core/net/ip6_filter.cpp
@@ -37,6 +37,7 @@
 
 #include "common/code_utils.hpp"
 #include "common/instance.hpp"
+#include "common/logging.hpp"
 #include "meshcop/meshcop.hpp"
 #include "net/ip6.hpp"
 #include "net/tcp.hpp"
@@ -54,11 +55,11 @@
 
 bool Filter::Accept(Message &aMessage) const
 {
-    bool      rval = false;
-    Header    ip6;
-    UdpHeader udp;
-    TcpHeader tcp;
-    uint16_t  dstport;
+    bool        rval = false;
+    Header      ip6;
+    Udp::Header udp;
+    Tcp::Header tcp;
+    uint16_t    dstport;
 
     // Allow all received IPv6 datagrams with link security enabled
     if (aMessage.IsLinkSecurityEnabled())
@@ -67,16 +68,16 @@
     }
 
     // Read IPv6 header
-    VerifyOrExit(sizeof(ip6) == aMessage.Read(0, sizeof(ip6), &ip6));
+    VerifyOrExit(sizeof(ip6) == aMessage.Read(0, sizeof(ip6), &ip6), OT_NOOP);
 
     // Allow only link-local unicast or multicast
-    VerifyOrExit(ip6.GetDestination().IsLinkLocal() || ip6.GetDestination().IsLinkLocalMulticast());
+    VerifyOrExit(ip6.GetDestination().IsLinkLocal() || ip6.GetDestination().IsLinkLocalMulticast(), OT_NOOP);
 
     switch (ip6.GetNextHeader())
     {
     case kProtoUdp:
         // Read the UDP header and get the dst port
-        VerifyOrExit(sizeof(udp) == aMessage.Read(sizeof(ip6), sizeof(udp), &udp));
+        VerifyOrExit(sizeof(udp) == aMessage.Read(sizeof(ip6), sizeof(udp), &udp), OT_NOOP);
 
         dstport = udp.GetDestinationPort();
 
@@ -95,7 +96,7 @@
 
     case kProtoTcp:
         // Read the TCP header and get the dst port
-        VerifyOrExit(sizeof(tcp) == aMessage.Read(sizeof(ip6), sizeof(tcp), &tcp));
+        VerifyOrExit(sizeof(tcp) == aMessage.Read(sizeof(ip6), sizeof(tcp), &tcp), OT_NOOP);
 
         dstport = tcp.GetDestinationPort();
 
@@ -123,6 +124,8 @@
 {
     otError error = OT_ERROR_NONE;
 
+    VerifyOrExit(aPort != 0, error = OT_ERROR_INVALID_ARGS);
+
     for (int i = 0; i < kMaxUnsecurePorts; i++)
     {
         if (mUnsecurePorts[i] == aPort)
@@ -136,6 +139,7 @@
         if (mUnsecurePorts[i] == 0)
         {
             mUnsecurePorts[i] = aPort;
+            otLogInfoIp6("Added unsecure port %d", aPort);
             ExitNow();
         }
     }
@@ -150,6 +154,8 @@
 {
     otError error = OT_ERROR_NONE;
 
+    VerifyOrExit(aPort != 0, error = OT_ERROR_INVALID_ARGS);
+
     for (int i = 0; i < kMaxUnsecurePorts; i++)
     {
         if (mUnsecurePorts[i] == aPort)
@@ -163,6 +169,7 @@
 
             // Clear the last port entry.
             mUnsecurePorts[i] = 0;
+            otLogInfoIp6("Removed unsecure port %d", aPort);
             ExitNow();
         }
     }
@@ -173,6 +180,21 @@
     return error;
 }
 
+bool Filter::IsUnsecurePort(uint16_t aPort)
+{
+    bool found = false;
+
+    for (int i = 0; i < kMaxUnsecurePorts; i++)
+    {
+        if (mUnsecurePorts[i] == aPort)
+        {
+            found = true;
+            break;
+        }
+    }
+    return found;
+}
+
 void Filter::RemoveAllUnsecurePorts(void)
 {
     memset(mUnsecurePorts, 0, sizeof(mUnsecurePorts));
diff --git a/src/core/net/ip6_filter.hpp b/src/core/net/ip6_filter.hpp
index 0e4ec14..d1c82eb 100644
--- a/src/core/net/ip6_filter.hpp
+++ b/src/core/net/ip6_filter.hpp
@@ -80,8 +80,9 @@
      *
      * @param[in]  aPort  The port value.
      *
-     * @retval OT_ERROR_NONE     The port was successfully added to the allowed unsecure port list.
-     * @retval OT_ERROR_NO_BUFS  The unsecure port list is full.
+     * @retval OT_ERROR_NONE         The port was successfully added to the allowed unsecure port list.
+     * @retval OT_ERROR_INVALID_ARGS The port is invalid (value 0 is reserved for internal use).
+     * @retval OT_ERROR_NO_BUFS      The unsecure port list is full.
      *
      */
     otError AddUnsecurePort(uint16_t aPort);
@@ -91,13 +92,24 @@
      *
      * @param[in]  aPort  The port value.
      *
-     * @retval OT_ERROR_NONE       The port was successfully removed from the allowed unsecure port list.
-     * @retval OT_ERROR_NOT_FOUND  The port was not found in the unsecure port list.
+     * @retval OT_ERROR_NONE         The port was successfully removed from the allowed unsecure port list.
+     * @retval OT_ERROR_INVALID_ARGS The port is invalid (value 0 is reserved for internal use).
+     * @retval OT_ERROR_NOT_FOUND    The port was not found in the unsecure port list.
      *
      */
     otError RemoveUnsecurePort(uint16_t aPort);
 
     /**
+     * This method checks whether a port is in the unsecure port list.
+     *
+     * @param[in]  aPort  The port value.
+     *
+     * @returns Whether the given port is in the unsecure port list.
+     *
+     */
+    bool IsUnsecurePort(uint16_t aPort);
+
+    /**
      * This method removes all ports from the allowed unsecure port list.
      *
      */
diff --git a/src/core/net/ip6_mpl.cpp b/src/core/net/ip6_mpl.cpp
index c1073db..5ab0f41 100644
--- a/src/core/net/ip6_mpl.cpp
+++ b/src/core/net/ip6_mpl.cpp
@@ -43,24 +43,16 @@
 namespace ot {
 namespace Ip6 {
 
-void MplBufferedMessageMetadata::GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval)
-{
-    // Emulate Trickle timer behavior and set up the next retransmission within [0,I) range.
-    uint8_t t = (aInterval == 0) ? aInterval : Random::NonCrypto::GetUint8InRange(0, aInterval);
-
-    // Set transmission time at the beginning of the next interval.
-    SetTransmissionTime(aCurrentTime + static_cast<uint32_t>(GetIntervalOffset() + t));
-    SetIntervalOffset(aInterval - t);
-}
-
 Mpl::Mpl(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mTimerExpirations(0)
-    , mSequence(0)
+    , mMatchingAddress(nullptr)
+    , mSeedSetTimer(aInstance, Mpl::HandleSeedSetTimer, this)
     , mSeedId(0)
-    , mSeedSetTimer(aInstance, &Mpl::HandleSeedSetTimer, this)
-    , mRetransmissionTimer(aInstance, &Mpl::HandleRetransmissionTimer, this)
-    , mMatchingAddress(NULL)
+    , mSequence(0)
+#if OPENTHREAD_FTD
+    , mRetransmissionTimer(aInstance, Mpl::HandleRetransmissionTimer, this)
+    , mTimerExpirations(0)
+#endif
 {
     memset(mSeedSet, 0, sizeof(mSeedSet));
 }
@@ -85,6 +77,42 @@
     }
 }
 
+otError Mpl::ProcessOption(Message &aMessage, const Address &aAddress, bool aIsOutbound)
+{
+    otError   error;
+    OptionMpl option;
+
+    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(option), &option) >= OptionMpl::kMinLength &&
+                     (option.GetSeedIdLength() == OptionMpl::kSeedIdLength0 ||
+                      option.GetSeedIdLength() == OptionMpl::kSeedIdLength2),
+                 error = OT_ERROR_PARSE);
+
+    if (option.GetSeedIdLength() == OptionMpl::kSeedIdLength0)
+    {
+        // Retrieve MPL Seed Id from the IPv6 Source Address.
+        option.SetSeedId(HostSwap16(aAddress.mFields.m16[7]));
+    }
+
+    // Check if the MPL Data Message is new.
+    error = UpdateSeedSet(option.GetSeedId(), option.GetSequence());
+
+    if (error == OT_ERROR_NONE)
+    {
+#if OPENTHREAD_FTD
+        AddBufferedMessage(aMessage, option.GetSeedId(), option.GetSequence(), aIsOutbound);
+#endif
+    }
+    else if (aIsOutbound)
+    {
+        // In case MPL Data Message is generated locally, ignore potential error of the MPL Seed Set
+        // to allow subsequent retransmissions with the same sequence number.
+        ExitNow(error = OT_ERROR_NONE);
+    }
+
+exit:
+    return error;
+}
+
 /*
  * mSeedSet stores recently received (Seed ID, Sequence) values.
  * - (Seed ID, Sequence) values are grouped by Seed ID.
@@ -108,20 +136,20 @@
  */
 otError Mpl::UpdateSeedSet(uint16_t aSeedId, uint8_t aSequence)
 {
-    otError       error    = OT_ERROR_NONE;
-    MplSeedEntry *insert   = NULL;
-    MplSeedEntry *group    = mSeedSet;
-    MplSeedEntry *evict    = mSeedSet;
-    uint8_t       curCount = 0;
-    uint8_t       maxCount = 0;
+    otError    error    = OT_ERROR_NONE;
+    SeedEntry *insert   = nullptr;
+    SeedEntry *group    = mSeedSet;
+    SeedEntry *evict    = mSeedSet;
+    uint8_t    curCount = 0;
+    uint8_t    maxCount = 0;
 
     for (uint32_t i = 0; i < kNumSeedEntries; i++, curCount++)
     {
-        if (mSeedSet[i].GetLifetime() == 0)
+        if (mSeedSet[i].mLifetime == 0)
         {
             // unused entries exist
 
-            if (insert == NULL)
+            if (insert == nullptr)
             {
                 // no existing group, set insert and evict entry to be the same
                 insert = &mSeedSet[i];
@@ -132,11 +160,11 @@
             break;
         }
 
-        if (mSeedSet[i].GetSeedId() != group->GetSeedId())
+        if (mSeedSet[i].mSeedId != group->mSeedId)
         {
             // processing new group
 
-            if (aSeedId == group->GetSeedId() && insert == NULL)
+            if (aSeedId == group->mSeedId && insert == nullptr)
             {
                 // insert at end of existing group
                 insert = &mSeedSet[i];
@@ -154,18 +182,18 @@
             curCount = 0;
         }
 
-        if (aSeedId == mSeedSet[i].GetSeedId())
+        if (aSeedId == mSeedSet[i].mSeedId)
         {
             // have existing entries for aSeedId
 
-            int8_t diff = static_cast<int8_t>(aSequence - mSeedSet[i].GetSequence());
+            int8_t diff = static_cast<int8_t>(aSequence - mSeedSet[i].mSequence);
 
             if (diff == 0)
             {
                 // already received, drop message
                 ExitNow(error = OT_ERROR_DROP);
             }
-            else if (insert == NULL && diff < 0)
+            else if (insert == nullptr && diff < 0)
             {
                 // insert in order of sequence
                 insert = &mSeedSet[i];
@@ -174,12 +202,12 @@
         }
     }
 
-    if (evict->GetLifetime() != 0)
+    if (evict->mLifetime != 0)
     {
         // no free entries available, look to evict an existing entry
-        assert(curCount != 0);
+        OT_ASSERT(curCount != 0);
 
-        if (aSeedId == group->GetSeedId() && insert == NULL)
+        if (aSeedId == group->mSeedId && insert == nullptr)
         {
             // insert at end of existing group
             insert = &mSeedSet[kNumSeedEntries];
@@ -196,7 +224,7 @@
         // require evict group size to have >= 2 entries
         VerifyOrExit(maxCount > 1, error = OT_ERROR_DROP);
 
-        if (insert == NULL)
+        if (insert == nullptr)
         {
             // no existing entries for aSeedId
             insert = evict;
@@ -204,25 +232,25 @@
         else
         {
             // require Sequence to be larger than oldest stored Sequence in group
-            VerifyOrExit(insert > mSeedSet && aSeedId == (insert - 1)->GetSeedId(), error = OT_ERROR_DROP);
+            VerifyOrExit(insert > mSeedSet && aSeedId == (insert - 1)->mSeedId, error = OT_ERROR_DROP);
         }
     }
 
     if (evict > insert)
     {
-        assert(insert >= mSeedSet);
-        memmove(insert + 1, insert, static_cast<size_t>(evict - insert) * sizeof(MplSeedEntry));
+        OT_ASSERT(insert >= mSeedSet);
+        memmove(insert + 1, insert, static_cast<size_t>(evict - insert) * sizeof(SeedEntry));
     }
     else if (evict < insert)
     {
-        assert(evict >= mSeedSet);
-        memmove(evict, evict + 1, static_cast<size_t>(insert - 1 - evict) * sizeof(MplSeedEntry));
+        OT_ASSERT(evict >= mSeedSet);
+        memmove(evict, evict + 1, static_cast<size_t>(insert - 1 - evict) * sizeof(SeedEntry));
         insert--;
     }
 
-    insert->SetSeedId(aSeedId);
-    insert->SetSequence(aSequence);
-    insert->SetLifetime(kSeedEntryLifetime);
+    insert->mSeedId   = aSeedId;
+    insert->mSequence = aSequence;
+    insert->mLifetime = kSeedEntryLifetime;
 
     if (!mSeedSetTimer.IsRunning())
     {
@@ -233,12 +261,46 @@
     return error;
 }
 
+void Mpl::HandleSeedSetTimer(Timer &aTimer)
+{
+    aTimer.GetOwner<Mpl>().HandleSeedSetTimer();
+}
+
+void Mpl::HandleSeedSetTimer(void)
+{
+    bool startTimer = false;
+    int  j          = 0;
+
+    for (int i = 0; i < kNumSeedEntries && mSeedSet[i].mLifetime; i++)
+    {
+        mSeedSet[i].mLifetime--;
+
+        if (mSeedSet[i].mLifetime > 0)
+        {
+            mSeedSet[j++] = mSeedSet[i];
+            startTimer    = true;
+        }
+    }
+
+    for (; j < kNumSeedEntries && mSeedSet[j].mLifetime; j++)
+    {
+        mSeedSet[j].mLifetime = 0;
+    }
+
+    if (startTimer)
+    {
+        mSeedSetTimer.Start(kSeedEntryLifetimeDt);
+    }
+}
+
+#if OPENTHREAD_FTD
+
 void Mpl::AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound)
 {
-    otError                    error       = OT_ERROR_NONE;
-    Message *                  messageCopy = NULL;
-    MplBufferedMessageMetadata messageMetadata;
-    uint8_t                    hopLimit = 0;
+    otError  error       = OT_ERROR_NONE;
+    Message *messageCopy = nullptr;
+    Metadata metadata;
+    uint8_t  hopLimit = 0;
 
 #if OPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE
     // adjust the first MPL forward interval dynamically according to the network scale
@@ -247,8 +309,8 @@
     uint8_t interval = kDataMessageInterval;
 #endif
 
-    VerifyOrExit(GetTimerExpirations() > 0);
-    VerifyOrExit((messageCopy = aMessage.Clone()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(GetTimerExpirations() > 0, OT_NOOP);
+    VerifyOrExit((messageCopy = aMessage.Clone()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     if (!aIsOutbound)
     {
@@ -257,58 +319,25 @@
         messageCopy->Write(Header::GetHopLimitOffset(), Header::GetHopLimitSize(), &hopLimit);
     }
 
-    messageMetadata.SetSeedId(aSeedId);
-    messageMetadata.SetSequence(aSequence);
-    messageMetadata.SetTransmissionCount(aIsOutbound ? 1 : 0);
-    messageMetadata.GenerateNextTransmissionTime(TimerMilli::GetNow(), interval);
+    metadata.mSeedId            = aSeedId;
+    metadata.mSequence          = aSequence;
+    metadata.mTransmissionCount = aIsOutbound ? 1 : 0;
+    metadata.mIntervalOffset    = 0;
+    metadata.GenerateNextTransmissionTime(TimerMilli::GetNow(), interval);
 
-    SuccessOrExit(error = messageMetadata.AppendTo(*messageCopy));
+    SuccessOrExit(error = metadata.AppendTo(*messageCopy));
     mBufferedMessageSet.Enqueue(*messageCopy);
 
-    mRetransmissionTimer.FireAtIfEarlier(messageMetadata.GetTransmissionTime());
+    mRetransmissionTimer.FireAtIfEarlier(metadata.mTransmissionTime);
 
 exit:
 
-    if (error != OT_ERROR_NONE && messageCopy != NULL)
+    if (error != OT_ERROR_NONE && messageCopy != nullptr)
     {
         messageCopy->Free();
     }
 }
 
-otError Mpl::ProcessOption(Message &aMessage, const Address &aAddress, bool aIsOutbound)
-{
-    otError   error;
-    OptionMpl option;
-
-    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(option), &option) >= OptionMpl::kMinLength &&
-                     (option.GetSeedIdLength() == OptionMpl::kSeedIdLength0 ||
-                      option.GetSeedIdLength() == OptionMpl::kSeedIdLength2),
-                 error = OT_ERROR_PARSE);
-
-    if (option.GetSeedIdLength() == OptionMpl::kSeedIdLength0)
-    {
-        // Retrieve MPL Seed Id from the IPv6 Source Address.
-        option.SetSeedId(HostSwap16(aAddress.mFields.m16[7]));
-    }
-
-    // Check if the MPL Data Message is new.
-    error = UpdateSeedSet(option.GetSeedId(), option.GetSequence());
-
-    if (error == OT_ERROR_NONE)
-    {
-        AddBufferedMessage(aMessage, option.GetSeedId(), option.GetSequence(), aIsOutbound);
-    }
-    else if (aIsOutbound)
-    {
-        // In case MPL Data Message is generated locally, ignore potential error of the MPL Seed Set
-        // to allow subsequent retransmissions with the same sequence number.
-        ExitNow(error = OT_ERROR_NONE);
-    }
-
-exit:
-    return error;
-}
-
 void Mpl::HandleRetransmissionTimer(Timer &aTimer)
 {
     aTimer.GetOwner<Mpl>().HandleRetransmissionTimer();
@@ -316,37 +345,37 @@
 
 void Mpl::HandleRetransmissionTimer(void)
 {
-    TimeMilli                  now      = TimerMilli::GetNow();
-    TimeMilli                  nextTime = now.GetDistantFuture();
-    MplBufferedMessageMetadata messageMetadata;
-    Message *                  message;
-    Message *                  nextMessage;
+    TimeMilli now      = TimerMilli::GetNow();
+    TimeMilli nextTime = now.GetDistantFuture();
+    Metadata  metadata;
+    Message * message;
+    Message * nextMessage;
 
-    for (message = mBufferedMessageSet.GetHead(); message != NULL; message = nextMessage)
+    for (message = mBufferedMessageSet.GetHead(); message != nullptr; message = nextMessage)
     {
         nextMessage = message->GetNext();
 
-        messageMetadata.ReadFrom(*message);
+        metadata.ReadFrom(*message);
 
-        if (now < messageMetadata.GetTransmissionTime())
+        if (now < metadata.mTransmissionTime)
         {
-            if (nextTime > messageMetadata.GetTransmissionTime())
+            if (nextTime > metadata.mTransmissionTime)
             {
-                nextTime = messageMetadata.GetTransmissionTime();
+                nextTime = metadata.mTransmissionTime;
             }
         }
         else
         {
             // Update the number of transmission timer expirations.
-            messageMetadata.SetTransmissionCount(messageMetadata.GetTransmissionCount() + 1);
+            metadata.mTransmissionCount++;
 
-            if (messageMetadata.GetTransmissionCount() < GetTimerExpirations())
+            if (metadata.mTransmissionCount < GetTimerExpirations())
             {
-                Message *messageCopy = message->Clone(message->GetLength() - sizeof(MplBufferedMessageMetadata));
+                Message *messageCopy = message->Clone(message->GetLength() - sizeof(Metadata));
 
-                if (messageCopy != NULL)
+                if (messageCopy != nullptr)
                 {
-                    if (messageMetadata.GetTransmissionCount() > 1)
+                    if (metadata.mTransmissionCount > 1)
                     {
                         messageCopy->SetSubType(Message::kSubTypeMplRetransmission);
                     }
@@ -354,27 +383,26 @@
                     Get<Ip6>().EnqueueDatagram(*messageCopy);
                 }
 
-                messageMetadata.GenerateNextTransmissionTime(now, kDataMessageInterval);
-                messageMetadata.UpdateIn(*message);
+                metadata.GenerateNextTransmissionTime(now, kDataMessageInterval);
+                metadata.UpdateIn(*message);
 
-                if (nextTime > messageMetadata.GetTransmissionTime())
+                if (nextTime > metadata.mTransmissionTime)
                 {
-                    nextTime = messageMetadata.GetTransmissionTime();
+                    nextTime = metadata.mTransmissionTime;
                 }
             }
             else
             {
                 mBufferedMessageSet.Dequeue(*message);
 
-                if (messageMetadata.GetTransmissionCount() == GetTimerExpirations())
+                if (metadata.mTransmissionCount == GetTimerExpirations())
                 {
-                    if (messageMetadata.GetTransmissionCount() > 1)
+                    if (metadata.mTransmissionCount > 1)
                     {
                         message->SetSubType(Message::kSubTypeMplRetransmission);
                     }
 
-                    // Remove the extra metadata from the MPL Data Message.
-                    MplBufferedMessageMetadata::RemoveFrom(*message);
+                    metadata.RemoveFrom(*message);
                     Get<Ip6>().EnqueueDatagram(*message);
                 }
                 else
@@ -392,37 +420,38 @@
     }
 }
 
-void Mpl::HandleSeedSetTimer(Timer &aTimer)
+void Mpl::Metadata::ReadFrom(const Message &aMessage)
 {
-    aTimer.GetOwner<Mpl>().HandleSeedSetTimer();
+    uint16_t length = aMessage.GetLength();
+
+    OT_ASSERT(length >= sizeof(*this));
+    aMessage.Read(length - sizeof(*this), sizeof(*this), this);
 }
 
-void Mpl::HandleSeedSetTimer(void)
+void Mpl::Metadata::RemoveFrom(Message &aMessage) const
 {
-    bool startTimer = false;
-    int  j          = 0;
+    otError error = aMessage.SetLength(aMessage.GetLength() - sizeof(*this));
 
-    for (int i = 0; i < kNumSeedEntries && mSeedSet[i].GetLifetime(); i++)
-    {
-        mSeedSet[i].SetLifetime(mSeedSet[i].GetLifetime() - 1);
-
-        if (mSeedSet[i].GetLifetime() > 0)
-        {
-            mSeedSet[j++] = mSeedSet[i];
-            startTimer    = true;
-        }
-    }
-
-    for (; j < kNumSeedEntries && mSeedSet[j].GetLifetime(); j++)
-    {
-        mSeedSet[j].SetLifetime(0);
-    }
-
-    if (startTimer)
-    {
-        mSeedSetTimer.Start(kSeedEntryLifetimeDt);
-    }
+    OT_ASSERT(error == OT_ERROR_NONE);
+    OT_UNUSED_VARIABLE(error);
 }
 
+int Mpl::Metadata::UpdateIn(Message &aMessage) const
+{
+    return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
+}
+
+void Mpl::Metadata::GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval)
+{
+    // Emulate Trickle timer behavior and set up the next retransmission within [0,I) range.
+    uint8_t t = (aInterval == 0) ? aInterval : Random::NonCrypto::GetUint8InRange(0, aInterval);
+
+    // Set transmission time at the beginning of the next interval.
+    mTransmissionTime = aCurrentTime + static_cast<uint32_t>(mIntervalOffset + t);
+    mIntervalOffset   = aInterval - t;
+}
+
+#endif // OPENTHREAD_FTD
+
 } // namespace Ip6
 } // namespace ot
diff --git a/src/core/net/ip6_mpl.hpp b/src/core/net/ip6_mpl.hpp
index adb4b25..b493a84 100644
--- a/src/core/net/ip6_mpl.hpp
+++ b/src/core/net/ip6_mpl.hpp
@@ -183,231 +183,6 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class represents an MPL's Seed Set entry.
- *
- */
-class MplSeedEntry
-{
-public:
-    /**
-     * This method returns the MPL Seed Id value.
-     *
-     * @returns The MPL Seed Id value.
-     *
-     */
-    uint16_t GetSeedId(void) const { return mSeedId; }
-
-    /**
-     * This method sets the MPL Seed Id value.
-     *
-     * @param[in]  aSeedId  The MPL Seed Id value.
-     *
-     */
-    void SetSeedId(uint16_t aSeedId) { mSeedId = aSeedId; }
-
-    /**
-     * This method returns the MPL Sequence value.
-     *
-     * @returns The MPL Sequence value.
-     *
-     */
-    uint8_t GetSequence(void) const { return mSequence; }
-
-    /**
-     * This method sets the MPL Sequence value.
-     *
-     * @param[in]  aSequence  The MPL Sequence value.
-     *
-     */
-    void SetSequence(uint8_t aSequence) { mSequence = aSequence; }
-
-    /**
-     * This method returns the MPL Seed Set entry's remaining lifetime.
-     *
-     * @returns The MPL Seed Set entry's remaining lifetime.
-     *
-     */
-    uint8_t GetLifetime(void) const { return mLifetime; }
-
-    /**
-     * This method sets the remaining lifetime of the Seed Set entry.
-     *
-     * @param[in]  aLifetime  The remaining lifetime of the Seed Set entry.
-     *
-     */
-    void SetLifetime(uint8_t aLifetime) { mLifetime = aLifetime; }
-
-private:
-    uint16_t mSeedId;
-    uint8_t  mSequence;
-    uint8_t  mLifetime;
-};
-
-/**
- * This class represents metadata required for MPL retransmissions.
- *
- */
-class MplBufferedMessageMetadata
-{
-public:
-    /**
-     * Default constructor for the object.
-     *
-     */
-    MplBufferedMessageMetadata(void)
-        : mSeedId(0)
-        , mSequence(0)
-        , mTransmissionCount(0)
-        , mTransmissionTime(0)
-        , mIntervalOffset(0){};
-
-    /**
-     * This method appends MPL Buffered Message metadata to the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     * @retval OT_ERROR_NONE     Successfully appended the bytes.
-     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
-     *
-     */
-    otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
-
-    /**
-     * This method reads request data from the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     */
-    void ReadFrom(const Message &aMessage)
-    {
-        uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-        assert(length == sizeof(*this));
-        OT_UNUSED_VARIABLE(length);
-    }
-
-    /**
-     * This method removes MPL Buffered Message metadata from the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     */
-    static void RemoveFrom(Message &aMessage)
-    {
-        otError error = aMessage.SetLength(aMessage.GetLength() - sizeof(MplBufferedMessageMetadata));
-        assert(error == OT_ERROR_NONE);
-        OT_UNUSED_VARIABLE(error);
-    }
-
-    /**
-     * This method updates MPL Buffered Message metadata in the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     * @returns The number of bytes that have been updated.
-     *
-     */
-    int UpdateIn(Message &aMessage) const
-    {
-        return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-    }
-
-    /**
-     * This method returns the MPL Seed Id value.
-     *
-     * @returns The MPL Seed Id value.
-     *
-     */
-    uint16_t GetSeedId(void) const { return mSeedId; }
-
-    /**
-     * This method sets the MPL Seed Id value.
-     *
-     * @param[in]  aSeedId  The MPL Seed Id value.
-     *
-     */
-    void SetSeedId(uint16_t aSeedId) { mSeedId = aSeedId; }
-
-    /**
-     * This method returns the MPL Sequence value.
-     *
-     * @returns The MPL Sequence value.
-     *
-     */
-    uint8_t GetSequence(void) const { return mSequence; }
-
-    /**
-     * This method sets the MPL Sequence value.
-     *
-     * @param[in]  aSequence  The MPL Sequence value.
-     *
-     */
-    void SetSequence(uint8_t aSequence) { mSequence = aSequence; }
-
-    /**
-     * This method returns the number of already preformed transmissions.
-     *
-     * @returns The number of already preformed transmissions.
-     *
-     */
-    uint8_t GetTransmissionCount(void) const { return mTransmissionCount; }
-
-    /**
-     * This method sets the number of already performed transmissions.
-     *
-     * @param[in]  aTransmissionCount  The number of already performed transmissions.
-     *
-     */
-    void SetTransmissionCount(uint8_t aTransmissionCount) { mTransmissionCount = aTransmissionCount; }
-
-    /**
-     * This method returns the transmission timestamp of the message.
-     *
-     * @returns The transmission timestamp of the message.
-     *
-     */
-    TimeMilli GetTransmissionTime(void) const { return mTransmissionTime; }
-
-    /**
-     * This method sets the transmission timestamp of the message.
-     *
-     * @param[in]  aTransmissionTime  The transmission timestamp of the message.
-     *
-     */
-    void SetTransmissionTime(TimeMilli aTransmissionTime) { mTransmissionTime = aTransmissionTime; }
-
-    /**
-     * This method returns the offset from the transmission time to the end of trickle interval.
-     *
-     * @returns The offset from the transmission time to the end of trickle interval.
-     *
-     */
-    uint8_t GetIntervalOffset(void) const { return mIntervalOffset; }
-
-    /**
-     * This method sets the offset from the transmission time to the end of trickle interval.
-     *
-     * @param[in]  aIntervalOffset  The offset from the transmission time to the end of trickle interval.
-     *
-     */
-    void SetIntervalOffset(uint8_t aIntervalOffset) { mIntervalOffset = aIntervalOffset; }
-
-    /**
-     * This method generates the next transmission time for the MPL Data Message.
-     *
-     * @param[in] aCurrentTime Current time (in milliseconds).
-     * @param[in] aInterval    The current interval size (in milliseconds).
-     */
-    void GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval);
-
-private:
-    uint16_t  mSeedId;
-    uint8_t   mSequence;
-    uint8_t   mTransmissionCount;
-    TimeMilli mTransmissionTime;
-    uint8_t   mIntervalOffset;
-};
-
-/**
  * This class implements MPL message processing.
  *
  */
@@ -464,6 +239,15 @@
     void SetSeedId(uint16_t aSeedId) { mSeedId = aSeedId; }
 
     /**
+     * This method sets the IPv6 matching address, that allows to elide MPL Seed Id.
+     *
+     * @param[in] aAddress The reference to the IPv6 matching address.
+     *
+     */
+    void SetMatchingAddress(const Address &aAddress) { mMatchingAddress = &aAddress; }
+
+#if OPENTHREAD_FTD
+    /**
      * This method gets the MPL number of Trickle timer expirations that occur before
      * terminating the Trickle algorithm's retransmission of a given MPL Data Message.
      *
@@ -482,20 +266,13 @@
     void SetTimerExpirations(uint8_t aTimerExpirations) { mTimerExpirations = aTimerExpirations; }
 
     /**
-     * This method sets the IPv6 matching address, that allows to elide MPL Seed Id.
-     *
-     * @param[in] aAddress The reference to the IPv6 matching address.
-     *
-     */
-    void SetMatchingAddress(const Address &aAddress) { mMatchingAddress = &aAddress; }
-
-    /**
      * This method returns a reference to the buffered message set.
      *
      * @returns A reference to the buffered message set.
      *
      */
     const MessageQueue &GetBufferedMessageSet(void) const { return mBufferedMessageSet; }
+#endif // OPENTHREAD_FTD
 
 private:
     enum
@@ -506,27 +283,49 @@
         kDataMessageInterval = 64
     };
 
-    otError UpdateSeedSet(uint16_t aSeedId, uint8_t aSequence);
-    void    UpdateBufferedSet(uint16_t aSeedId, uint8_t aSequence);
-    void    AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound);
+    struct SeedEntry
+    {
+        uint16_t mSeedId;
+        uint8_t  mSequence;
+        uint8_t  mLifetime;
+    };
 
     static void HandleSeedSetTimer(Timer &aTimer);
     void        HandleSeedSetTimer(void);
 
+    otError UpdateSeedSet(uint16_t aSeedId, uint8_t aSequence);
+
+    SeedEntry      mSeedSet[kNumSeedEntries];
+    const Address *mMatchingAddress;
+    TimerMilli     mSeedSetTimer;
+    uint16_t       mSeedId;
+    uint8_t        mSequence;
+
+#if OPENTHREAD_FTD
+    struct Metadata
+    {
+        otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
+        void    ReadFrom(const Message &aMessage);
+        void    RemoveFrom(Message &aMessage) const;
+        int     UpdateIn(Message &aMessage) const;
+        void    GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval);
+
+        TimeMilli mTransmissionTime;
+        uint16_t  mSeedId;
+        uint8_t   mSequence;
+        uint8_t   mTransmissionCount;
+        uint8_t   mIntervalOffset;
+    };
+
     static void HandleRetransmissionTimer(Timer &aTimer);
     void        HandleRetransmissionTimer(void);
 
-    uint8_t  mTimerExpirations;
-    uint8_t  mSequence;
-    uint16_t mSeedId;
+    void AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound);
 
-    TimerMilli mSeedSetTimer;
-    TimerMilli mRetransmissionTimer;
-
-    const Address *mMatchingAddress;
-
-    MplSeedEntry mSeedSet[kNumSeedEntries];
     MessageQueue mBufferedMessageSet;
+    TimerMilli   mRetransmissionTimer;
+    uint8_t      mTimerExpirations;
+#endif // OPENTHREAD_FTD
 };
 
 /**
diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp
index 372b9d0..a639fcd 100644
--- a/src/core/net/netif.cpp
+++ b/src/core/net/netif.cpp
@@ -33,7 +33,6 @@
 
 #include "netif.hpp"
 
-#include "common/code_utils.hpp"
 #include "common/debug.hpp"
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
@@ -47,7 +46,7 @@
  * Certain fixed multicast addresses are defined as a set of chained (linked-list) constant `otNetifMulticastAddress`
  * entries:
  *
- * LinkLocalAllRouters -> RealmLocalAllRouters -> LinkLocalAll -> RealmLocalAll -> RealmLocalAllMplForwarders -> NULL
+ * LinkLocalAllRouters -> RealmLocalAllRouters -> LinkLocalAll -> RealmLocalAll -> RealmLocalAllMplForwarders -> nullptr
  *
  * All or a portion of the chain is appended to the end of `mMulticastAddresses` linked-list. If the interface is
  * subscribed to all-routers multicast addresses (using `SubscribeAllRoutersMulticast()`) then all the five entries
@@ -58,7 +57,7 @@
 // "ff03::fc"
 const otNetifMulticastAddress Netif::kRealmLocalAllMplForwardersMulticastAddress = {
     {{{0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc}}},
-    NULL};
+    nullptr};
 
 // "ff03::01"
 const otNetifMulticastAddress Netif::kRealmLocalAllNodesMulticastAddress = {
@@ -85,45 +84,27 @@
     , mUnicastAddresses()
     , mMulticastAddresses()
     , mMulticastPromiscuous(false)
-    , mAddressCallback(NULL)
-    , mAddressCallbackContext(NULL)
+    , mAddressCallback(nullptr)
+    , mAddressCallbackContext(nullptr)
+    , mExtUnicastAddressPool()
+    , mExtMulticastAddressPool()
 {
-    for (NetifUnicastAddress *entry = &mExtUnicastAddresses[0]; entry < OT_ARRAY_END(mExtUnicastAddresses); entry++)
-    {
-        entry->MarkAsNotInUse();
-    }
-
-    for (NetifMulticastAddress *entry = &mExtMulticastAddresses[0]; entry < OT_ARRAY_END(mExtMulticastAddresses);
-         entry++)
-    {
-        entry->MarkAsNotInUse();
-    }
 }
 
 bool Netif::IsMulticastSubscribed(const Address &aAddress) const
 {
-    bool rval = false;
+    const NetifMulticastAddress *prev;
 
-    for (const NetifMulticastAddress *cur = mMulticastAddresses.GetHead(); cur; cur = cur->GetNext())
-    {
-        if (cur->GetAddress() == aAddress)
-        {
-            ExitNow(rval = true);
-        }
-    }
-
-exit:
-    return rval;
+    return mMulticastAddresses.FindMatching(aAddress, prev) != nullptr;
 }
 
-otError Netif::SubscribeAllNodesMulticast(void)
+void Netif::SubscribeAllNodesMulticast(void)
 {
-    otError                error = OT_ERROR_NONE;
     NetifMulticastAddress *tail;
     NetifMulticastAddress &linkLocalAllNodesAddress =
         static_cast<NetifMulticastAddress &>(const_cast<otNetifMulticastAddress &>(kLinkLocalAllNodesMulticastAddress));
 
-    VerifyOrExit(!mMulticastAddresses.Contains(linkLocalAllNodesAddress), error = OT_ERROR_ALREADY);
+    VerifyOrExit(!mMulticastAddresses.Contains(linkLocalAllNodesAddress), OT_NOOP);
 
     // Append the fixed chain of three multicast addresses to the
     // tail of the list:
@@ -132,7 +113,7 @@
 
     tail = mMulticastAddresses.GetTail();
 
-    if (tail == NULL)
+    if (tail == nullptr)
     {
         mMulticastAddresses.SetHead(&linkLocalAllNodesAddress);
     }
@@ -141,9 +122,9 @@
         tail->SetNext(&linkLocalAllNodesAddress);
     }
 
-    Get<Notifier>().Signal(OT_CHANGED_IP6_MULTICAST_SUBSCRIBED);
+    Get<Notifier>().Signal(kEventIp6MulticastSubscribed);
 
-    VerifyOrExit(mAddressCallback != NULL);
+    VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
 
     for (const NetifMulticastAddress *entry = &linkLocalAllNodesAddress; entry; entry = entry->GetNext())
     {
@@ -151,12 +132,11 @@
     }
 
 exit:
-    return error;
+    return;
 }
 
-otError Netif::UnsubscribeAllNodesMulticast(void)
+void Netif::UnsubscribeAllNodesMulticast(void)
 {
-    otError                      error = OT_ERROR_NONE;
     NetifMulticastAddress *      prev;
     const NetifMulticastAddress &linkLocalAllNodesAddress =
         static_cast<NetifMulticastAddress &>(const_cast<otNetifMulticastAddress &>(kLinkLocalAllNodesMulticastAddress));
@@ -167,7 +147,7 @@
     //
     //    LinkLocalAll -> RealmLocalAll -> RealmLocalAllMpl.
 
-    SuccessOrExit(error = mMulticastAddresses.Find(linkLocalAllNodesAddress, prev));
+    SuccessOrExit(mMulticastAddresses.Find(linkLocalAllNodesAddress, prev));
 
     // This method MUST be called after `UnsubscribeAllRoutersMulticast().
     // Verify this by checking the chain at the end of the list only
@@ -177,21 +157,21 @@
     //    LinkLocalAllRouters -> RealmLocalAllRouters -> LinkLocalAll
     //         -> RealmLocalAll -> RealmLocalAllMpl.
 
-    assert(prev != static_cast<NetifMulticastAddress *>(
-                       const_cast<otNetifMulticastAddress *>(&kRealmLocalAllRoutersMulticastAddress)));
+    OT_ASSERT(prev != static_cast<NetifMulticastAddress *>(
+                          const_cast<otNetifMulticastAddress *>(&kRealmLocalAllRoutersMulticastAddress)));
 
-    if (prev == NULL)
+    if (prev == nullptr)
     {
         mMulticastAddresses.Clear();
     }
     else
     {
-        prev->SetNext(NULL);
+        prev->SetNext(nullptr);
     }
 
-    Get<Notifier>().Signal(OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED);
+    Get<Notifier>().Signal(kEventIp6MulticastUnsubscribed);
 
-    VerifyOrExit(mAddressCallback != NULL);
+    VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
 
     for (const NetifMulticastAddress *entry = &linkLocalAllNodesAddress; entry; entry = entry->GetNext())
     {
@@ -199,13 +179,13 @@
     }
 
 exit:
-    return error;
+    return;
 }
 
-otError Netif::SubscribeAllRoutersMulticast(void)
+void Netif::SubscribeAllRoutersMulticast(void)
 {
-    otError                error = OT_ERROR_NONE;
-    NetifMulticastAddress *prev;
+    otError                error                      = OT_ERROR_NONE;
+    NetifMulticastAddress *prev                       = nullptr;
     NetifMulticastAddress &linkLocalAllRoutersAddress = static_cast<NetifMulticastAddress &>(
         const_cast<otNetifMulticastAddress &>(kLinkLocalAllRoutersMulticastAddress));
     NetifMulticastAddress &linkLocalAllNodesAddress =
@@ -218,7 +198,8 @@
     // This method MUST be called after `SubscribeAllNodesMulticast()`
     // Ensure that the `LinkLocalAll` was found on the list.
 
-    assert(error == OT_ERROR_NONE);
+    OT_ASSERT(error == OT_ERROR_NONE);
+    OT_UNUSED_VARIABLE(error);
 
     // The tail of multicast address linked list contains the
     // fixed addresses. We either have a chain of five addresses
@@ -234,9 +215,9 @@
     // `RealmLocalAllRouters` then all five addresses are on
     // the list already.
 
-    VerifyOrExit(prev != &realmLocalAllRoutersAddress, error = OT_ERROR_ALREADY);
+    VerifyOrExit(prev != &realmLocalAllRoutersAddress, OT_NOOP);
 
-    if (prev == NULL)
+    if (prev == nullptr)
     {
         mMulticastAddresses.SetHead(&linkLocalAllRoutersAddress);
     }
@@ -245,9 +226,9 @@
         prev->SetNext(&linkLocalAllRoutersAddress);
     }
 
-    Get<Notifier>().Signal(OT_CHANGED_IP6_MULTICAST_SUBSCRIBED);
+    Get<Notifier>().Signal(kEventIp6MulticastSubscribed);
 
-    VerifyOrExit(mAddressCallback != NULL);
+    VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
 
     for (const NetifMulticastAddress *entry = &linkLocalAllRoutersAddress; entry != &linkLocalAllNodesAddress;
          entry                              = entry->GetNext())
@@ -256,12 +237,11 @@
     }
 
 exit:
-    return error;
+    return;
 }
 
-otError Netif::UnsubscribeAllRoutersMulticast(void)
+void Netif::UnsubscribeAllRoutersMulticast(void)
 {
-    otError                error;
     NetifMulticastAddress *prev;
     NetifMulticastAddress &linkLocalAllRoutersAddress = static_cast<NetifMulticastAddress &>(
         const_cast<otNetifMulticastAddress &>(kLinkLocalAllRoutersMulticastAddress));
@@ -278,9 +258,9 @@
     // to point to `LinkLocalAll` instead (so that tail contains the
     // three fixed addresses at end of the chain).
 
-    SuccessOrExit(error = mMulticastAddresses.Find(linkLocalAllRoutersAddress, prev));
+    SuccessOrExit(mMulticastAddresses.Find(linkLocalAllRoutersAddress, prev));
 
-    if (prev == NULL)
+    if (prev == nullptr)
     {
         mMulticastAddresses.SetHead(&linkLocalAllNodesAddress);
     }
@@ -289,9 +269,9 @@
         prev->SetNext(&linkLocalAllNodesAddress);
     }
 
-    Get<Notifier>().Signal(OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED);
+    Get<Notifier>().Signal(kEventIp6MulticastUnsubscribed);
 
-    VerifyOrExit(mAddressCallback != NULL);
+    VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
 
     for (const NetifMulticastAddress *entry = &linkLocalAllRoutersAddress; entry != &linkLocalAllNodesAddress;
          entry                              = entry->GetNext())
@@ -300,68 +280,48 @@
     }
 
 exit:
-    return error;
+    return;
 }
 
-otError Netif::SubscribeMulticast(NetifMulticastAddress &aAddress)
+bool Netif::IsMulticastAddressExternal(const NetifMulticastAddress &aAddress) const
 {
-    otError error;
+    return mExtMulticastAddressPool.IsPoolEntry(aAddress);
+}
 
-    SuccessOrExit(error = mMulticastAddresses.Add(aAddress));
+void Netif::SubscribeMulticast(NetifMulticastAddress &aAddress)
+{
+    SuccessOrExit(mMulticastAddresses.Add(aAddress));
 
-    Get<Notifier>().Signal(OT_CHANGED_IP6_MULTICAST_SUBSCRIBED);
+    Get<Notifier>().Signal(kEventIp6MulticastSubscribed);
 
-    VerifyOrExit(mAddressCallback != NULL);
+    VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
     mAddressCallback(&aAddress.mAddress, kMulticastPrefixLength, /* IsAdded */ true, mAddressCallbackContext);
 
 exit:
-    return error;
+    return;
 }
 
-otError Netif::UnsubscribeMulticast(const NetifMulticastAddress &aAddress)
+void Netif::UnsubscribeMulticast(const NetifMulticastAddress &aAddress)
 {
-    otError error;
+    SuccessOrExit(mMulticastAddresses.Remove(aAddress));
 
-    SuccessOrExit(error = mMulticastAddresses.Remove(aAddress));
+    Get<Notifier>().Signal(kEventIp6MulticastUnsubscribed);
 
-    Get<Notifier>().Signal(OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED);
-
-    VerifyOrExit(mAddressCallback != NULL);
+    VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
     mAddressCallback(&aAddress.mAddress, kMulticastPrefixLength, /* IsAdded */ false, mAddressCallbackContext);
 
 exit:
-    return error;
-}
-
-otError Netif::GetNextExternalMulticast(uint8_t &aIterator, Address &aAddress) const
-{
-    otError error = OT_ERROR_NOT_FOUND;
-    size_t  num   = OT_ARRAY_LENGTH(mExtMulticastAddresses);
-
-    VerifyOrExit(aIterator < num);
-
-    for (uint8_t i = aIterator; i < num; i++)
-    {
-        const NetifMulticastAddress &entry = mExtMulticastAddresses[i];
-
-        if (entry.IsInUse())
-        {
-            aAddress  = entry.GetAddress();
-            aIterator = i + 1;
-            ExitNow(error = OT_ERROR_NONE);
-        }
-    }
-
-exit:
-    return error;
+    return;
 }
 
 otError Netif::SubscribeExternalMulticast(const Address &aAddress)
 {
-    otError                error = OT_ERROR_NONE;
-    NetifMulticastAddress *entry;
+    otError                error                      = OT_ERROR_NONE;
     NetifMulticastAddress &linkLocalAllRoutersAddress = static_cast<NetifMulticastAddress &>(
         const_cast<otNetifMulticastAddress &>(kLinkLocalAllRoutersMulticastAddress));
+    NetifMulticastAddress *entry;
+
+    VerifyOrExit(!IsMulticastSubscribed(aAddress), error = OT_ERROR_ALREADY);
 
     // Check that the address is not one of the fixed addresses:
     // LinkLocalAllRouters -> RealmLocalAllRouters -> LinkLocalAllNodes
@@ -372,20 +332,12 @@
         VerifyOrExit(cur->GetAddress() != aAddress, error = OT_ERROR_INVALID_ARGS);
     }
 
-    VerifyOrExit(!IsMulticastSubscribed(aAddress), error = OT_ERROR_ALREADY);
+    entry = mExtMulticastAddressPool.Allocate();
+    VerifyOrExit(entry != nullptr, error = OT_ERROR_NO_BUFS);
 
-    for (entry = &mExtMulticastAddresses[0]; entry < OT_ARRAY_END(mExtMulticastAddresses); entry++)
-    {
-        if (!entry->IsInUse())
-        {
-            entry->mAddress = aAddress;
-            mMulticastAddresses.Push(*entry);
-            Get<Notifier>().Signal(OT_CHANGED_IP6_MULTICAST_SUBSCRIBED);
-            ExitNow();
-        }
-    }
-
-    error = OT_ERROR_NO_BUFS;
+    entry->mAddress = aAddress;
+    mMulticastAddresses.Push(*entry);
+    Get<Notifier>().Signal(kEventIp6MulticastSubscribed);
 
 exit:
     return error;
@@ -395,35 +347,18 @@
 {
     otError                error = OT_ERROR_NONE;
     NetifMulticastAddress *entry;
-    NetifMulticastAddress *last = NULL;
+    NetifMulticastAddress *prev;
 
-    for (entry = mMulticastAddresses.GetHead(); entry; entry = entry->GetNext())
-    {
-        if (entry->GetAddress() == aAddress)
-        {
-            VerifyOrExit((entry >= &mExtMulticastAddresses[0]) && (entry < OT_ARRAY_END(mExtMulticastAddresses)),
-                         error = OT_ERROR_INVALID_ARGS);
+    entry = mMulticastAddresses.FindMatching(aAddress, prev);
+    VerifyOrExit(entry != nullptr, error = OT_ERROR_NOT_FOUND);
 
-            if (last)
-            {
-                mMulticastAddresses.PopAfter(*last);
-            }
-            else
-            {
-                mMulticastAddresses.Pop();
-            }
+    VerifyOrExit(IsMulticastAddressExternal(*entry), error = OT_ERROR_INVALID_ARGS);
 
-            break;
-        }
+    mMulticastAddresses.PopAfter(prev);
 
-        last = entry;
-    }
+    mExtMulticastAddressPool.Free(*entry);
 
-    VerifyOrExit(entry != NULL, error = OT_ERROR_NOT_FOUND);
-
-    entry->MarkAsNotInUse();
-
-    Get<Notifier>().Signal(OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED);
+    Get<Notifier>().Signal(kEventIp6MulticastUnsubscribed);
 
 exit:
     return error;
@@ -431,12 +366,15 @@
 
 void Netif::UnsubscribeAllExternalMulticastAddresses(void)
 {
-    for (NetifMulticastAddress *entry = &mExtMulticastAddresses[0]; entry < OT_ARRAY_END(mExtMulticastAddresses);
-         entry++)
+    NetifMulticastAddress *next;
+
+    for (NetifMulticastAddress *entry = mMulticastAddresses.GetHead(); entry != nullptr; entry = next)
     {
-        if (entry->IsInUse())
+        next = entry->GetNext();
+
+        if (IsMulticastAddressExternal(*entry))
         {
-            UnsubscribeExternalMulticast(entry->GetAddress());
+            IgnoreError(UnsubscribeExternalMulticast(entry->GetAddress()));
         }
     }
 }
@@ -447,69 +385,59 @@
     mAddressCallbackContext = aCallbackContext;
 }
 
-otError Netif::AddUnicastAddress(NetifUnicastAddress &aAddress)
+void Netif::AddUnicastAddress(NetifUnicastAddress &aAddress)
 {
-    otError error;
+    SuccessOrExit(mUnicastAddresses.Add(aAddress));
 
-    SuccessOrExit(error = mUnicastAddresses.Add(aAddress));
+    Get<Notifier>().Signal(aAddress.mRloc ? kEventThreadRlocAdded : kEventIp6AddressAdded);
 
-    Get<Notifier>().Signal(aAddress.mRloc ? OT_CHANGED_THREAD_RLOC_ADDED : OT_CHANGED_IP6_ADDRESS_ADDED);
-
-    VerifyOrExit(mAddressCallback != NULL);
+    VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
     mAddressCallback(&aAddress.mAddress, aAddress.mPrefixLength, /* IsAdded */ true, mAddressCallbackContext);
 
 exit:
-    return error;
+    return;
 }
 
-otError Netif::RemoveUnicastAddress(const NetifUnicastAddress &aAddress)
+void Netif::RemoveUnicastAddress(const NetifUnicastAddress &aAddress)
 {
-    otError error;
+    SuccessOrExit(mUnicastAddresses.Remove(aAddress));
 
-    SuccessOrExit(error = mUnicastAddresses.Remove(aAddress));
+    Get<Notifier>().Signal(aAddress.mRloc ? kEventThreadRlocRemoved : kEventIp6AddressRemoved);
 
-    Get<Notifier>().Signal(aAddress.mRloc ? OT_CHANGED_THREAD_RLOC_REMOVED : OT_CHANGED_IP6_ADDRESS_REMOVED);
-
-    VerifyOrExit(mAddressCallback != NULL);
+    VerifyOrExit(mAddressCallback != nullptr, OT_NOOP);
     mAddressCallback(&aAddress.mAddress, aAddress.mPrefixLength, /* IsAdded */ false, mAddressCallbackContext);
 
 exit:
-    return error;
+    return;
 }
 
 otError Netif::AddExternalUnicastAddress(const NetifUnicastAddress &aAddress)
 {
     otError              error = OT_ERROR_NONE;
     NetifUnicastAddress *entry;
+    NetifUnicastAddress *prev;
+
+    entry = mUnicastAddresses.FindMatching(aAddress.GetAddress(), prev);
+
+    if (entry != nullptr)
+    {
+        VerifyOrExit(IsUnicastAddressExternal(*entry), error = OT_ERROR_ALREADY);
+
+        entry->mPrefixLength  = aAddress.mPrefixLength;
+        entry->mAddressOrigin = aAddress.mAddressOrigin;
+        entry->mPreferred     = aAddress.mPreferred;
+        entry->mValid         = aAddress.mValid;
+        ExitNow();
+    }
 
     VerifyOrExit(!aAddress.GetAddress().IsLinkLocal(), error = OT_ERROR_INVALID_ARGS);
 
-    for (entry = mUnicastAddresses.GetHead(); entry; entry = entry->GetNext())
-    {
-        if (entry->GetAddress() == aAddress.GetAddress())
-        {
-            VerifyOrExit((entry >= &mExtUnicastAddresses[0]) && (entry < OT_ARRAY_END(mExtUnicastAddresses)),
-                         error = OT_ERROR_INVALID_ARGS);
+    entry = mExtUnicastAddressPool.Allocate();
+    VerifyOrExit(entry != nullptr, error = OT_ERROR_NO_BUFS);
 
-            entry->mPrefixLength = aAddress.mPrefixLength;
-            entry->mPreferred    = aAddress.mPreferred;
-            entry->mValid        = aAddress.mValid;
-            ExitNow();
-        }
-    }
-
-    for (entry = &mExtUnicastAddresses[0]; entry < OT_ARRAY_END(mExtUnicastAddresses); entry++)
-    {
-        if (!entry->IsInUse())
-        {
-            *entry = aAddress;
-            mUnicastAddresses.Push(*entry);
-            Get<Notifier>().Signal(OT_CHANGED_IP6_ADDRESS_ADDED);
-            ExitNow();
-        }
-    }
-
-    error = OT_ERROR_NO_BUFS;
+    *entry = aAddress;
+    mUnicastAddresses.Push(*entry);
+    Get<Notifier>().Signal(kEventIp6AddressAdded);
 
 exit:
     return error;
@@ -519,35 +447,16 @@
 {
     otError              error = OT_ERROR_NONE;
     NetifUnicastAddress *entry;
-    NetifUnicastAddress *last = NULL;
+    NetifUnicastAddress *prev;
 
-    for (entry = mUnicastAddresses.GetHead(); entry; entry = entry->GetNext())
-    {
-        if (entry->GetAddress() == aAddress)
-        {
-            VerifyOrExit((entry >= &mExtUnicastAddresses[0]) && (entry < OT_ARRAY_END(mExtUnicastAddresses)),
-                         error = OT_ERROR_INVALID_ARGS);
+    entry = mUnicastAddresses.FindMatching(aAddress, prev);
+    VerifyOrExit(entry != nullptr, error = OT_ERROR_NOT_FOUND);
 
-            if (last)
-            {
-                mUnicastAddresses.PopAfter(*last);
-            }
-            else
-            {
-                mUnicastAddresses.Pop();
-            }
+    VerifyOrExit(IsUnicastAddressExternal(*entry), error = OT_ERROR_INVALID_ARGS);
 
-            break;
-        }
-
-        last = entry;
-    }
-
-    VerifyOrExit(entry != NULL, error = OT_ERROR_NOT_FOUND);
-
-    entry->MarkAsNotInUse();
-
-    Get<Notifier>().Signal(OT_CHANGED_IP6_ADDRESS_REMOVED);
+    mUnicastAddresses.PopAfter(prev);
+    mExtUnicastAddressPool.Free(*entry);
+    Get<Notifier>().Signal(kEventIp6AddressRemoved);
 
 exit:
     return error;
@@ -555,29 +464,29 @@
 
 void Netif::RemoveAllExternalUnicastAddresses(void)
 {
-    for (NetifUnicastAddress *entry = &mExtUnicastAddresses[0]; entry < OT_ARRAY_END(mExtUnicastAddresses); entry++)
+    NetifUnicastAddress *next;
+
+    for (NetifUnicastAddress *entry = mUnicastAddresses.GetHead(); entry != nullptr; entry = next)
     {
-        if (entry->IsInUse())
+        next = entry->GetNext();
+
+        if (IsUnicastAddressExternal(*entry))
         {
-            RemoveExternalUnicastAddress(entry->GetAddress());
+            IgnoreError(RemoveExternalUnicastAddress(entry->GetAddress()));
         }
     }
 }
 
-bool Netif::IsUnicastAddress(const Address &aAddress) const
+bool Netif::HasUnicastAddress(const Address &aAddress) const
 {
-    bool rval = false;
+    const NetifUnicastAddress *prev;
 
-    for (const NetifUnicastAddress *cur = mUnicastAddresses.GetHead(); cur; cur = cur->GetNext())
-    {
-        if (cur->GetAddress() == aAddress)
-        {
-            ExitNow(rval = true);
-        }
-    }
+    return mUnicastAddresses.FindMatching(aAddress, prev) != nullptr;
+}
 
-exit:
-    return rval;
+bool Netif::IsUnicastAddressExternal(const NetifUnicastAddress &aAddress) const
+{
+    return mExtUnicastAddressPool.IsPoolEntry(aAddress);
 }
 
 } // namespace Ip6
diff --git a/src/core/net/netif.hpp b/src/core/net/netif.hpp
index 1dd4f8e..fa2d81c 100644
--- a/src/core/net/netif.hpp
+++ b/src/core/net/netif.hpp
@@ -36,9 +36,12 @@
 
 #include "openthread-core-config.h"
 
+#include "common/clearable.hpp"
+#include "common/code_utils.hpp"
 #include "common/linked_list.hpp"
 #include "common/locator.hpp"
 #include "common/message.hpp"
+#include "common/non_copyable.hpp"
 #include "common/tasklet.hpp"
 #include "mac/mac_types.hpp"
 #include "net/ip6_address.hpp"
@@ -63,18 +66,15 @@
  * This class implements an IPv6 network interface unicast address.
  *
  */
-class NetifUnicastAddress : public otNetifAddress, public LinkedListEntry<NetifUnicastAddress>
+class NetifUnicastAddress : public otNetifAddress,
+                            public LinkedListEntry<NetifUnicastAddress>,
+                            public Clearable<NetifUnicastAddress>
 {
     friend class Netif;
+    friend class LinkedList<NetifUnicastAddress>;
 
 public:
     /**
-     * This method clears the object (setting all fields to zero).
-     *
-     */
-    void Clear(void) { memset(this, 0, sizeof(*this)); }
-
-    /**
      * This method returns the unicast address.
      *
      * @returns The unicast address.
@@ -102,28 +102,22 @@
     }
 
 private:
-    // In an unused/available entry (i.e., entry not present in a linked
-    // list), the next pointer is set to point back to the entry itself.
-    bool IsInUse(void) const { return GetNext() != this; }
-    void MarkAsNotInUse(void) { SetNext(this); }
+    bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; }
 };
 
 /**
  * This class implements an IPv6 network interface multicast address.
  *
  */
-class NetifMulticastAddress : public otNetifMulticastAddress, public LinkedListEntry<NetifMulticastAddress>
+class NetifMulticastAddress : public otNetifMulticastAddress,
+                              public LinkedListEntry<NetifMulticastAddress>,
+                              public Clearable<NetifMulticastAddress>
 {
     friend class Netif;
+    friend class LinkedList<NetifMulticastAddress>;
 
 public:
     /**
-     * This method clears the object (setting all fields to zero).
-     *
-     */
-    void Clear(void) { memset(this, 0, sizeof(*this)); }
-
-    /**
      * This method returns the multicast address.
      *
      * @returns The multicast address.
@@ -159,19 +153,17 @@
     }
 
 private:
-    // In an unused/available entry (i.e., entry not present in a linked
-    // list), the next pointer is set to point back to the entry itself.
-    bool IsInUse(void) const { return GetNext() != this; }
-    void MarkAsNotInUse(void) { mNext = this; }
+    bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; }
 };
 
 /**
  * This class implements an IPv6 network interface.
  *
  */
-class Netif : public InstanceLocator, public LinkedListEntry<Netif>
+class Netif : public InstanceLocator, public LinkedListEntry<Netif>, private NonCopyable
 {
     friend class Ip6;
+    friend class Address;
 
 public:
     /**
@@ -192,9 +184,9 @@
     void SetAddressCallback(otIp6AddressCallback aCallback, void *aCallbackContext);
 
     /**
-     * This method returns a pointer to the list of unicast addresses.
+     * This method returns a pointer to the head of the linked list of unicast addresses.
      *
-     * @returns A pointer to the list of unicast addresses.
+     * @returns A pointer to the head of the linked list of unicast addresses.
      *
      */
     const NetifUnicastAddress *GetUnicastAddresses(void) const { return mUnicastAddresses.GetHead(); }
@@ -202,28 +194,65 @@
     /**
      * This method adds a unicast address to the network interface.
      *
+     * This method is intended for addresses internal to OpenThread. The @p aAddress instance is directly added in the
+     * unicast address linked list.
+     *
      * @param[in]  aAddress  A reference to the unicast address.
      *
-     * @retval OT_ERROR_NONE      Successfully added the unicast address.
-     * @retval OT_ERROR_ALREADY  The unicast address was already added.
-     *
      */
-    otError AddUnicastAddress(NetifUnicastAddress &aAddress);
+    void AddUnicastAddress(NetifUnicastAddress &aAddress);
 
     /**
      * This method removes a unicast address from the network interface.
      *
+     * This method is intended for addresses internal to OpenThread. The @p aAddress instance is removed from the
+     * unicast address linked list.
+     *
      * @param[in]  aAddress  A reference to the unicast address.
      *
-     * @retval OT_ERROR_NONE       Successfully removed the unicast address.
-     * @retval OT_ERROR_NOT_FOUND  The unicast address wasn't found to be removed.
+     */
+    void RemoveUnicastAddress(const NetifUnicastAddress &aAddress);
+
+    /**
+     * This method indicates whether or not an address is assigned to the interface.
+     *
+     * @param[in]  aAddress  A reference to the unicast address.
+     *
+     * @retval TRUE   If @p aAddress is assigned to the network interface,
+     * @retval FALSE  If @p aAddress is not assigned to the network interface.
      *
      */
-    otError RemoveUnicastAddress(const NetifUnicastAddress &aAddress);
+    bool HasUnicastAddress(const Address &aAddress) const;
+
+    /**
+     * This method indicates whether or not a unicast address is assigned to the network interface.
+     *
+     * @param[in]  aAddress  A reference to the unicast address.
+     *
+     * @retval TRUE   If @p aAddress is assigned to the network interface,
+     * @retval FALSE  If @p aAddress is not assigned to the network interface.
+     *
+     */
+    bool HasUnicastAddress(const NetifUnicastAddress &aAddress) const { return mUnicastAddresses.Contains(aAddress); }
+
+    /**
+     * This method indicates whether a unicast address is an external or internal address.
+     *
+     * @param[in] aAddress  A reference to the unicast address.
+     *
+     * @retval TRUE   The address is an external address.
+     * @retval FALSE  The address is not an external address (it is an OpenThread internal address).
+     *
+     */
+    bool IsUnicastAddressExternal(const NetifUnicastAddress &aAddress) const;
 
     /**
      * This method adds an external (to OpenThread) unicast address to the network interface.
      *
+     * For external address, the @p aAddress instance is not directly used (i.e., it can be temporary). It is copied
+     * into a local entry (allocated from an internal pool) before being added in the unicast address linked list.
+     * The maximum number of external addresses is specified by `OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS`.
+     *
      * @param[in]  aAddress  A reference to the unicast address.
      *
      * @retval OT_ERROR_NONE          Successfully added (or updated) the unicast address.
@@ -253,16 +282,6 @@
     void RemoveAllExternalUnicastAddresses(void);
 
     /**
-     * This method indicates whether or not an address is assigned to this interface.
-     *
-     * @param[in]  aAddress  A reference to the unicast address.
-     *
-     * @returns TRUE if @p aAddress is assigned to this interface, FALSE otherwise.
-     *
-     */
-    bool IsUnicastAddress(const Address &aAddress) const;
-
-    /**
      * This method indicates whether or not the network interface is subscribed to a multicast address.
      *
      * @param[in]  aAddress  The multicast address to check.
@@ -278,68 +297,63 @@
      *
      * @note This method MUST be called after `SubscribeAllNodesMulticast()` or its behavior is undefined.
      *
-     * @retval OT_ERROR_NONE     Successfully subscribed to the link-local and realm-local all routers addresses.
-     * @retval OT_ERROR_ALREADY  The multicast addresses are already subscribed.
-     *
      */
-    otError SubscribeAllRoutersMulticast(void);
+    void SubscribeAllRoutersMulticast(void);
 
     /**
      * This method unsubscribes the network interface to the link-local and realm-local all routers address.
      *
-     * @retval OT_ERROR_NONE       Successfully unsubscribed from the link-local and realm-local all routers address
-     * @retval OT_ERROR_NOT_FOUND  The multicast addresses were not found.
-     *
      */
-    otError UnsubscribeAllRoutersMulticast(void);
+    void UnsubscribeAllRoutersMulticast(void);
 
     /**
-     * This method returns a pointer to the list of multicast addresses.
+     * This method returns a pointer to the head of the linked list of multicast addresses.
      *
-     * @returns A pointer to the list of multicast addresses.
+     * @returns A pointer to the head of the linked list of multicast addresses.
      *
      */
     const NetifMulticastAddress *GetMulticastAddresses(void) const { return mMulticastAddresses.GetHead(); }
 
     /**
+     * This method indicates whether a multicast address is an external or internal address.
+     *
+     * @param[in] aAddress  A reference to the multicast address.
+     *
+     * @retval TRUE   The address is an external address.
+     * @retval FALSE  The address is not an external address (it is an OpenThread internal address).
+     *
+     */
+    bool IsMulticastAddressExternal(const NetifMulticastAddress &aAddress) const;
+
+    /**
      * This method subscribes the network interface to a multicast address.
      *
+     * This method is intended for addresses internal to OpenThread. The @p aAddress instance is directly added in the
+     * multicast address linked list.
+     *
      * @param[in]  aAddress  A reference to the multicast address.
      *
-     * @retval OT_ERROR_NONE     Successfully subscribed to @p aAddress.
-     * @retval OT_ERROR_ALREADY  The multicast address is already subscribed.
-     *
      */
-    otError SubscribeMulticast(NetifMulticastAddress &aAddress);
+    void SubscribeMulticast(NetifMulticastAddress &aAddress);
 
     /**
      * This method unsubscribes the network interface to a multicast address.
      *
+     * This method is intended for addresses internal to OpenThread. The @p aAddress instance is directly removed from
+     * the multicast address linked list.
+     *
      * @param[in]  aAddress  A reference to the multicast address.
      *
-     * @retval OT_ERROR_NONE       Successfully unsubscribed @p aAddress.
-     * @retval OT_ERROR_NOT_FOUND  The multicast address was not found.
-     *
      */
-    otError UnsubscribeMulticast(const NetifMulticastAddress &aAddress);
-
-    /**
-     * This method provides the next external multicast address that the network interface subscribed.
-     * It is used to iterate through the entries of the external multicast address table.
-     *
-     * @param[inout] aIterator A reference to the iterator context. To get the first
-     *                         external multicast address, it should be set to 0.
-     * @param[out]   aAddress  A reference where to place the external multicast address.
-     *
-     * @retval OT_ERROR_NONE       Successfully found the next external multicast address.
-     * @retval OT_ERROR_NOT_FOUND  No subsequent external multicast address.
-     *
-     */
-    otError GetNextExternalMulticast(uint8_t &aIterator, Address &aAddress) const;
+    void UnsubscribeMulticast(const NetifMulticastAddress &aAddress);
 
     /**
      * This method subscribes the network interface to the external (to OpenThread) multicast address.
      *
+     * For external address, the @p aAddress instance is not directly used (i.e., it can be temporary). It is copied
+     * into a local entry (allocated from an internal pool) before being added in the multicast address linked list.
+     * The maximum number of external addresses is specified by `OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS`.
+     *
      * @param[in]  aAddress  A reference to the multicast address.
      *
      * @retval OT_ERROR_NONE           Successfully subscribed to @p aAddress.
@@ -365,6 +379,7 @@
     /**
      * This method unsubscribes the network interface from all previously added external (to OpenThread) multicast
      * addresses.
+     *
      */
     void UnsubscribeAllExternalMulticastAddresses(void);
 
@@ -373,6 +388,7 @@
      *
      * @retval TRUE   If the multicast promiscuous mode is enabled.
      * @retval FALSE  If the multicast promiscuous mode is disabled.
+     *
      */
     bool IsMulticastPromiscuousEnabled(void) const { return mMulticastPromiscuous; }
 
@@ -389,11 +405,8 @@
      * This method subscribes the network interface to the realm-local all MPL forwarders, link-local, and realm-local
      * all nodes address.
      *
-     * @retval OT_ERROR_NONE     Successfully subscribed to all addresses.
-     * @retval OT_ERROR_ALREADY  The multicast addresses are already subscribed.
-     *
      */
-    otError SubscribeAllNodesMulticast(void);
+    void SubscribeAllNodesMulticast(void);
 
     /**
      * This method unsubscribes the network interface from the realm-local all MPL forwarders, link-local and
@@ -401,11 +414,8 @@
      *
      * @note This method MUST be called after `UnsubscribeAllRoutersMulticast()` or its behavior is undefined
      *
-     * @retval OT_ERROR_NONE          Successfully unsubscribed from all addresses.
-     * @retval OT_ERROR_NOT_FOUND     The multicast addresses were not found.
-     *
      */
-    otError UnsubscribeAllNodesMulticast(void);
+    void UnsubscribeAllNodesMulticast(void);
 
 private:
     enum
@@ -420,8 +430,8 @@
     otIp6AddressCallback mAddressCallback;
     void *               mAddressCallbackContext;
 
-    NetifUnicastAddress   mExtUnicastAddresses[OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS];
-    NetifMulticastAddress mExtMulticastAddresses[OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS];
+    Pool<NetifUnicastAddress, OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS>   mExtUnicastAddressPool;
+    Pool<NetifMulticastAddress, OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS> mExtMulticastAddressPool;
 
     static const otNetifMulticastAddress kRealmLocalAllMplForwardersMulticastAddress;
     static const otNetifMulticastAddress kLinkLocalAllNodesMulticastAddress;
diff --git a/src/core/net/sntp_client.cpp b/src/core/net/sntp_client.cpp
index 0376f0b..bfcc59e 100644
--- a/src/core/net/sntp_client.cpp
+++ b/src/core/net/sntp_client.cpp
@@ -67,8 +67,8 @@
 
 QueryMetadata::QueryMetadata(void)
     : mTransmitTimestamp(0)
-    , mResponseHandler(NULL)
-    , mResponseContext(NULL)
+    , mResponseHandler(nullptr)
+    , mResponseContext(nullptr)
     , mTransmissionTime(0)
     , mDestinationPort(0)
     , mRetransmissionCount(0)
@@ -89,9 +89,9 @@
     mDestinationAddress.Clear();
 }
 
-Client::Client(Ip6::Netif &aNetif)
-    : mSocket(aNetif.Get<Ip6::Udp>())
-    , mRetransmissionTimer(aNetif.GetInstance(), &Client::HandleRetransmissionTimer, this)
+Client::Client(Instance &aInstance)
+    : mSocket(aInstance)
+    , mRetransmissionTimer(aInstance, Client::HandleRetransmissionTimer, this)
     , mUnixEra(0)
 {
 }
@@ -115,7 +115,7 @@
     QueryMetadata queryMetadata;
 
     // Remove all pending queries.
-    while (message != NULL)
+    while (message != nullptr)
     {
         messageToRemove = message;
         message         = message->GetNext();
@@ -131,17 +131,17 @@
 {
     otError                 error;
     QueryMetadata           queryMetadata(aHandler, aContext);
-    Message *               message     = NULL;
-    Message *               messageCopy = NULL;
+    Message *               message     = nullptr;
+    Message *               messageCopy = nullptr;
     Header                  header;
     const Ip6::MessageInfo *messageInfo;
 
-    VerifyOrExit(aQuery->mMessageInfo != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aQuery->mMessageInfo != nullptr, error = OT_ERROR_INVALID_ARGS);
 
     // Originate timestamp is used only as a unique token.
     header.SetTransmitTimestampSeconds(TimerMilli::GetNow().GetValue() / 1000 + kTimeAt1970);
 
-    VerifyOrExit((message = NewMessage(header)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMessage(header)) != nullptr, error = OT_ERROR_NO_BUFS);
 
     messageInfo = static_cast<const Ip6::MessageInfo *>(aQuery->mMessageInfo);
 
@@ -152,7 +152,7 @@
     queryMetadata.mDestinationAddress  = messageInfo->GetPeerAddr();
     queryMetadata.mRetransmissionCount = 0;
 
-    VerifyOrExit((messageCopy = CopyAndEnqueueMessage(*message, queryMetadata)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((messageCopy = CopyAndEnqueueMessage(*message, queryMetadata)) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = SendMessage(*message, *messageInfo));
 
 exit:
@@ -175,10 +175,10 @@
 
 Message *Client::NewMessage(const Header &aHeader)
 {
-    Message *message = NULL;
+    Message *message = nullptr;
 
-    VerifyOrExit((message = mSocket.NewMessage(sizeof(aHeader))) != NULL);
-    message->Prepend(&aHeader, sizeof(aHeader));
+    VerifyOrExit((message = mSocket.NewMessage(sizeof(aHeader))) != nullptr, OT_NOOP);
+    IgnoreError(message->Prepend(&aHeader, sizeof(aHeader)));
     message->SetOffset(0);
 
 exit:
@@ -188,10 +188,10 @@
 Message *Client::CopyAndEnqueueMessage(const Message &aMessage, const QueryMetadata &aQueryMetadata)
 {
     otError  error       = OT_ERROR_NONE;
-    Message *messageCopy = NULL;
+    Message *messageCopy = nullptr;
 
     // Create a message copy for further retransmissions.
-    VerifyOrExit((messageCopy = aMessage.Clone()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((messageCopy = aMessage.Clone()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     // Append the copy with retransmission data and add it to the queue.
     SuccessOrExit(error = aQueryMetadata.AppendTo(*messageCopy));
@@ -201,10 +201,10 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && messageCopy != NULL)
+    if (error != OT_ERROR_NONE && messageCopy != nullptr)
     {
         messageCopy->Free();
-        messageCopy = NULL;
+        messageCopy = nullptr;
     }
 
     return messageCopy;
@@ -214,7 +214,7 @@
 {
     mPendingQueries.Dequeue(aMessage);
 
-    if (mRetransmissionTimer.IsRunning() && (mPendingQueries.GetHead() == NULL))
+    if (mRetransmissionTimer.IsRunning() && (mPendingQueries.GetHead() == nullptr))
     {
         // No more requests pending, stop the timer.
         mRetransmissionTimer.Stop();
@@ -229,13 +229,13 @@
     return mSocket.SendTo(aMessage, aMessageInfo);
 }
 
-otError Client::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+void Client::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError  error;
-    Message *messageCopy = NULL;
+    Message *messageCopy = nullptr;
 
     // Create a message copy for lower layers.
-    VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(QueryMetadata))) != NULL,
+    VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(QueryMetadata))) != nullptr,
                  error = OT_ERROR_NO_BUFS);
 
     // Send the copy.
@@ -243,12 +243,15 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && messageCopy != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        messageCopy->Free();
-    }
+        otLogWarnIp6("Failed to send SNTP request: %s", otThreadErrorToString(error));
 
-    return error;
+        if (messageCopy != nullptr)
+        {
+            messageCopy->Free();
+        }
+    }
 }
 
 Message *Client::FindRelatedQuery(const Header &aResponseHeader, QueryMetadata &aQueryMetadata)
@@ -256,7 +259,7 @@
     Header   header;
     Message *message = mPendingQueries.GetHead();
 
-    while (message != NULL)
+    while (message != nullptr)
     {
         // Read originate timestamp.
         aQueryMetadata.ReadFrom(*message);
@@ -280,7 +283,7 @@
 {
     DequeueMessage(aQuery);
 
-    if (aQueryMetadata.mResponseHandler != NULL)
+    if (aQueryMetadata.mResponseHandler != nullptr)
     {
         aQueryMetadata.mResponseHandler(aQueryMetadata.mResponseContext, aTime, aResult);
     }
@@ -300,7 +303,7 @@
     Message *        nextMessage;
     Ip6::MessageInfo messageInfo;
 
-    for (message = mPendingQueries.GetHead(); message != NULL; message = nextMessage)
+    for (message = mPendingQueries.GetHead(); message != nullptr; message = nextMessage)
     {
         nextMessage = message->GetNext();
 
@@ -353,13 +356,13 @@
     otError       error = OT_ERROR_NONE;
     Header        responseHeader;
     QueryMetadata queryMetadata;
-    Message *     message  = NULL;
+    Message *     message  = nullptr;
     uint64_t      unixTime = 0;
 
-    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(responseHeader), &responseHeader) ==
-                 sizeof(responseHeader));
+    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(responseHeader), &responseHeader) == sizeof(responseHeader),
+                 OT_NOOP);
 
-    VerifyOrExit((message = FindRelatedQuery(responseHeader, queryMetadata)) != NULL);
+    VerifyOrExit((message = FindRelatedQuery(responseHeader, queryMetadata)) != nullptr, OT_NOOP);
 
     // Check if response came from the server.
     VerifyOrExit(responseHeader.GetMode() == Header::kModeServer, error = OT_ERROR_FAILED);
@@ -401,7 +404,7 @@
 
 exit:
 
-    if (message != NULL && error != OT_ERROR_NONE)
+    if (message != nullptr && error != OT_ERROR_NONE)
     {
         FinalizeSntpTransaction(*message, queryMetadata, 0, error);
     }
diff --git a/src/core/net/sntp_client.hpp b/src/core/net/sntp_client.hpp
index b5ed685..2e35918 100644
--- a/src/core/net/sntp_client.hpp
+++ b/src/core/net/sntp_client.hpp
@@ -455,7 +455,7 @@
     void ReadFrom(const Message &aMessage)
     {
         uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-        assert(length == sizeof(*this));
+        OT_ASSERT(length == sizeof(*this));
         OT_UNUSED_VARIABLE(length);
     }
 
@@ -493,10 +493,10 @@
     /**
      * This constructor initializes the object.
      *
-     * @param[in]  aNetif    A reference to the network interface that SNTP client should be assigned to.
+     * @param[in]  aInstance     A reference to the OpenThread instance.
      *
      */
-    explicit Client(Ip6::Netif &aNetif);
+    explicit Client(Instance &aInstance);
 
     /**
      * This method starts the SNTP client.
@@ -572,7 +572,7 @@
     Message *CopyAndEnqueueMessage(const Message &aMessage, const QueryMetadata &aQueryMetadata);
     void     DequeueMessage(Message &aMessage);
     otError  SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-    otError  SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    void     SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
     Message *FindRelatedQuery(const Header &aResponseHeader, QueryMetadata &aQueryMetadata);
     void FinalizeSntpTransaction(Message &aQuery, const QueryMetadata &aQueryMetadata, uint64_t aTime, otError aResult);
@@ -583,7 +583,7 @@
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
-    Ip6::UdpSocket mSocket;
+    Ip6::Udp::Socket mSocket;
 
     MessageQueue mPendingQueries;
     TimerMilli   mRetransmissionTimer;
diff --git a/src/core/net/socket.hpp b/src/core/net/socket.hpp
index bbe0a82..a47cde4 100644
--- a/src/core/net/socket.hpp
+++ b/src/core/net/socket.hpp
@@ -36,6 +36,7 @@
 
 #include "openthread-core-config.h"
 
+#include "common/clearable.hpp"
 #include "net/ip6_address.hpp"
 
 namespace ot {
@@ -52,14 +53,14 @@
  * This class implements message information for an IPv6 message.
  *
  */
-class MessageInfo : public otMessageInfo
+class MessageInfo : public otMessageInfo, public Clearable<MessageInfo>
 {
 public:
     /**
      * This constructor initializes the object.
      *
      */
-    MessageInfo(void) { memset(this, 0, sizeof(*this)); }
+    MessageInfo(void) { Clear(); }
 
     /**
      * This method returns a reference to the local socket address.
@@ -204,7 +205,7 @@
  * This class implements a socket address.
  *
  */
-class SockAddr : public otSockAddr
+class SockAddr : public otSockAddr, public Clearable<SockAddr>
 {
 public:
     /**
@@ -214,12 +215,6 @@
     SockAddr(void) { Clear(); }
 
     /**
-     * This method clears the object (sets all fields to zero).
-     *
-     */
-    void Clear(void) { memset(this, 0, sizeof(*this)); }
-
-    /**
      * This method returns a reference to the IPv6 address.
      *
      * @returns A reference to the IPv6 address.
diff --git a/src/core/net/tcp.hpp b/src/core/net/tcp.hpp
index 78f598f..513ce77 100644
--- a/src/core/net/tcp.hpp
+++ b/src/core/net/tcp.hpp
@@ -40,6 +40,7 @@
 
 namespace ot {
 namespace Ip6 {
+namespace Tcp {
 
 /**
  * @addtogroup core-tcp
@@ -51,25 +52,12 @@
  *
  */
 
-OT_TOOL_PACKED_BEGIN
-struct TcpHeaderPoD
-{
-    uint16_t mSource;
-    uint16_t mDestination;
-    uint32_t mSequenceNumber;
-    uint32_t mAckNumber;
-    uint16_t mFlags;
-    uint16_t mWindow;
-    uint16_t mChecksum;
-    uint16_t mUrgentPointer;
-} OT_TOOL_PACKED_END;
-
 /**
  * This class implements TCP header parsing.
  *
  */
 OT_TOOL_PACKED_BEGIN
-class TcpHeader : private TcpHeaderPoD
+class Header
 {
 public:
     /**
@@ -136,6 +124,16 @@
      */
     uint16_t GetUrgentPointer(void) const { return HostSwap16(mUrgentPointer); }
 
+private:
+    uint16_t mSource;
+    uint16_t mDestination;
+    uint32_t mSequenceNumber;
+    uint32_t mAckNumber;
+    uint16_t mFlags;
+    uint16_t mWindow;
+    uint16_t mChecksum;
+    uint16_t mUrgentPointer;
+
 } OT_TOOL_PACKED_END;
 
 /**
@@ -143,6 +141,7 @@
  *
  */
 
+} // namespace Tcp
 } // namespace Ip6
 } // namespace ot
 
diff --git a/src/core/net/udp6.cpp b/src/core/net/udp6.cpp
index 83b949b..f0743a8 100644
--- a/src/core/net/udp6.cpp
+++ b/src/core/net/udp6.cpp
@@ -48,158 +48,66 @@
 namespace ot {
 namespace Ip6 {
 
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-static bool IsMle(Instance &aInstance, uint16_t aPort)
+bool Udp::SocketHandle::Matches(const MessageInfo &aMessageInfo) const
 {
-#if OPENTHREAD_FTD
-    return aPort == ot::Mle::kUdpPort || aPort == aInstance.Get<MeshCoP::JoinerRouter>().GetJoinerUdpPort();
-#else
-    OT_UNUSED_VARIABLE(aInstance);
-    return aPort == ot::Mle::kUdpPort;
-#endif
-}
-#endif
+    bool matches = false;
 
-UdpSocket::UdpSocket(Udp &aUdp)
-    : InstanceLocator(aUdp.GetInstance())
-{
-    mHandle = NULL;
+    VerifyOrExit(GetSockName().mPort == aMessageInfo.GetSockPort(), OT_NOOP);
+
+    VerifyOrExit(aMessageInfo.GetSockAddr().IsMulticast() || GetSockName().GetAddress().IsUnspecified() ||
+                     GetSockName().GetAddress() == aMessageInfo.GetSockAddr(),
+                 OT_NOOP);
+
+    // Verify source if connected socket
+    if (GetPeerName().mPort != 0)
+    {
+        VerifyOrExit(GetPeerName().mPort == aMessageInfo.GetPeerPort(), OT_NOOP);
+
+        VerifyOrExit(GetPeerName().GetAddress().IsUnspecified() ||
+                         GetPeerName().GetAddress() == aMessageInfo.GetPeerAddr(),
+                     OT_NOOP);
+    }
+
+    matches = true;
+
+exit:
+    return matches;
 }
 
-Message *UdpSocket::NewMessage(uint16_t aReserved, const otMessageSettings *aSettings)
+Udp::Socket::Socket(Instance &aInstance)
+    : InstanceLocator(aInstance)
+{
+    mHandle = nullptr;
+}
+
+Message *Udp::Socket::NewMessage(uint16_t aReserved, const Message::Settings &aSettings)
 {
     return Get<Udp>().NewMessage(aReserved, aSettings);
 }
 
-otError UdpSocket::Open(otUdpReceive aHandler, void *aContext)
+otError Udp::Socket::Open(otUdpReceive aHandler, void *aContext)
 {
-    otError error = OT_ERROR_NONE;
-
-    GetSockName().Clear();
-    GetPeerName().Clear();
-    mHandler = aHandler;
-    mContext = aContext;
-
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    SuccessOrExit(error = otPlatUdpSocket(this));
-#endif
-
-    Get<Udp>().AddSocket(*this);
-
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-exit:
-#endif
-    return error;
+    return Get<Udp>().Open(*this, aHandler, aContext);
 }
 
-otError UdpSocket::Bind(const SockAddr &aSockAddr)
+otError Udp::Socket::Bind(const SockAddr &aSockAddr)
 {
-    otError error = OT_ERROR_NONE;
-
-    mSockName = aSockAddr;
-
-    if (!IsBound())
-    {
-        do
-        {
-            mSockName.mPort = Get<Udp>().GetEphemeralPort();
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-            error = otPlatUdpBind(this);
-#endif
-        } while (error != OT_ERROR_NONE);
-    }
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    else if (!IsMle(GetInstance(), mSockName.mPort))
-    {
-        error = otPlatUdpBind(this);
-    }
-#endif
-
-    return error;
+    return Get<Udp>().Bind(*this, aSockAddr);
 }
 
-otError UdpSocket::Connect(const SockAddr &aSockAddr)
+otError Udp::Socket::Connect(const SockAddr &aSockAddr)
 {
-    otError error = OT_ERROR_NONE;
-
-    mPeerName = aSockAddr;
-
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    if (!IsMle(GetInstance(), mSockName.mPort))
-    {
-        error = otPlatUdpConnect(this);
-    }
-#endif
-    return error;
+    return Get<Udp>().Connect(*this, aSockAddr);
 }
 
-otError UdpSocket::Close(void)
+otError Udp::Socket::Close(void)
 {
-    otError error = OT_ERROR_NONE;
-
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    SuccessOrExit(error = otPlatUdpClose(this));
-#endif
-
-    Get<Udp>().RemoveSocket(*this);
-    GetSockName().Clear();
-    GetPeerName().Clear();
-
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-exit:
-#endif
-    return error;
+    return Get<Udp>().Close(*this);
 }
 
-otError UdpSocket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo)
+otError Udp::Socket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo)
 {
-    otError     error = OT_ERROR_NONE;
-    MessageInfo messageInfoLocal;
-
-    VerifyOrExit((aMessageInfo.GetSockPort() == 0) || (GetSockName().mPort == aMessageInfo.GetSockPort()),
-                 error = OT_ERROR_INVALID_ARGS);
-
-    messageInfoLocal = aMessageInfo;
-
-    if (messageInfoLocal.GetPeerAddr().IsUnspecified())
-    {
-        VerifyOrExit(!GetPeerName().GetAddress().IsUnspecified(), error = OT_ERROR_INVALID_ARGS);
-
-        messageInfoLocal.SetPeerAddr(GetPeerName().GetAddress());
-    }
-
-    if (messageInfoLocal.mPeerPort == 0)
-    {
-        VerifyOrExit(GetPeerName().mPort != 0, error = OT_ERROR_INVALID_ARGS);
-        messageInfoLocal.mPeerPort = GetPeerName().mPort;
-    }
-
-    if (messageInfoLocal.GetSockAddr().IsUnspecified())
-    {
-        messageInfoLocal.SetSockAddr(GetSockName().GetAddress());
-    }
-
-    if (!IsBound())
-    {
-        SuccessOrExit(error = Bind(GetSockName()));
-    }
-
-    messageInfoLocal.SetSockPort(GetSockName().mPort);
-
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    if (!IsMle(GetInstance(), mSockName.mPort) &&
-        !(mSockName.mPort == ot::kCoapUdpPort && aMessage.GetSubType() == Message::kSubTypeJoinerEntrust))
-    {
-        SuccessOrExit(error = otPlatUdpSend(this, &aMessage, &messageInfoLocal));
-    }
-    else
-#endif
-    {
-        SuccessOrExit(error = Get<Udp>().SendDatagram(aMessage, messageInfoLocal, kProtoUdp));
-    }
-
-exit:
-    return error;
+    return Get<Udp>().SendTo(*this, aMessage, aMessageInfo);
 }
 
 Udp::Udp(Instance &aInstance)
@@ -208,37 +116,173 @@
     , mReceivers()
     , mSockets()
 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
-    , mUdpForwarderContext(NULL)
-    , mUdpForwarder(NULL)
+    , mUdpForwarderContext(nullptr)
+    , mUdpForwarder(nullptr)
 #endif
 {
 }
 
-otError Udp::AddReceiver(UdpReceiver &aReceiver)
+otError Udp::AddReceiver(Receiver &aReceiver)
 {
     return mReceivers.Add(aReceiver);
 }
 
-otError Udp::RemoveReceiver(UdpReceiver &aReceiver)
+otError Udp::RemoveReceiver(Receiver &aReceiver)
 {
     otError error;
 
     SuccessOrExit(error = mReceivers.Remove(aReceiver));
-    aReceiver.SetNext(NULL);
+    aReceiver.SetNext(nullptr);
 
 exit:
     return error;
 }
 
-void Udp::AddSocket(UdpSocket &aSocket)
+otError Udp::Open(SocketHandle &aSocket, otUdpReceive aHandler, void *aContext)
 {
-    mSockets.Add(aSocket);
+    otError error = OT_ERROR_NONE;
+
+    aSocket.GetSockName().Clear();
+    aSocket.GetPeerName().Clear();
+    aSocket.mHandler = aHandler;
+    aSocket.mContext = aContext;
+
+#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+    error = otPlatUdpSocket(&aSocket);
+#endif
+    SuccessOrExit(error);
+
+    AddSocket(aSocket);
+
+exit:
+    return error;
 }
 
-void Udp::RemoveSocket(UdpSocket &aSocket)
+otError Udp::Bind(SocketHandle &aSocket, const SockAddr &aSockAddr)
+{
+    otError error = OT_ERROR_NONE;
+
+    aSocket.mSockName = aSockAddr;
+
+    if (!aSocket.IsBound())
+    {
+        do
+        {
+            aSocket.mSockName.mPort = GetEphemeralPort();
+#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+            error = otPlatUdpBind(&aSocket);
+#endif
+        } while (error != OT_ERROR_NONE);
+    }
+#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+    else if (!IsMlePort(aSocket.mSockName.mPort))
+    {
+        error = otPlatUdpBind(&aSocket);
+    }
+#endif
+
+    return error;
+}
+
+otError Udp::Connect(SocketHandle &aSocket, const SockAddr &aSockAddr)
+{
+    otError error = OT_ERROR_NONE;
+
+    aSocket.mPeerName = aSockAddr;
+
+    if (!aSocket.IsBound())
+    {
+        SuccessOrExit(error = Bind(aSocket, aSocket.GetSockName()));
+    }
+
+#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+    if (!IsMlePort(aSocket.mSockName.mPort))
+    {
+        error = otPlatUdpConnect(&aSocket);
+    }
+#endif
+
+exit:
+    return error;
+}
+
+otError Udp::Close(SocketHandle &aSocket)
+{
+    otError error = OT_ERROR_NONE;
+
+#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+    error = otPlatUdpClose(&aSocket);
+#endif
+    SuccessOrExit(error);
+
+    RemoveSocket(aSocket);
+    aSocket.GetSockName().Clear();
+    aSocket.GetPeerName().Clear();
+
+exit:
+    return error;
+}
+
+otError Udp::SendTo(SocketHandle &aSocket, Message &aMessage, const MessageInfo &aMessageInfo)
+{
+    otError     error = OT_ERROR_NONE;
+    MessageInfo messageInfoLocal;
+
+    VerifyOrExit((aMessageInfo.GetSockPort() == 0) || (aSocket.GetSockName().mPort == aMessageInfo.GetSockPort()),
+                 error = OT_ERROR_INVALID_ARGS);
+
+    messageInfoLocal = aMessageInfo;
+
+    if (messageInfoLocal.GetPeerAddr().IsUnspecified())
+    {
+        VerifyOrExit(!aSocket.GetPeerName().GetAddress().IsUnspecified(), error = OT_ERROR_INVALID_ARGS);
+
+        messageInfoLocal.SetPeerAddr(aSocket.GetPeerName().GetAddress());
+    }
+
+    if (messageInfoLocal.mPeerPort == 0)
+    {
+        VerifyOrExit(aSocket.GetPeerName().mPort != 0, error = OT_ERROR_INVALID_ARGS);
+        messageInfoLocal.mPeerPort = aSocket.GetPeerName().mPort;
+    }
+
+    if (messageInfoLocal.GetSockAddr().IsUnspecified())
+    {
+        messageInfoLocal.SetSockAddr(aSocket.GetSockName().GetAddress());
+    }
+
+    if (!aSocket.IsBound())
+    {
+        SuccessOrExit(error = Bind(aSocket, aSocket.GetSockName()));
+    }
+
+    messageInfoLocal.SetSockPort(aSocket.GetSockName().mPort);
+
+#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+    if (!IsMlePort(aSocket.mSockName.mPort) &&
+        !(aSocket.mSockName.mPort == ot::kCoapUdpPort && aMessage.GetSubType() == Message::kSubTypeJoinerEntrust))
+    {
+        SuccessOrExit(error = otPlatUdpSend(&aSocket, &aMessage, &messageInfoLocal));
+    }
+    else
+#endif
+    {
+        SuccessOrExit(error = SendDatagram(aMessage, messageInfoLocal, kProtoUdp));
+    }
+
+exit:
+    return error;
+}
+
+void Udp::AddSocket(SocketHandle &aSocket)
+{
+    IgnoreError(mSockets.Add(aSocket));
+}
+
+void Udp::RemoveSocket(SocketHandle &aSocket)
 {
     SuccessOrExit(mSockets.Remove(aSocket));
-    aSocket.SetNext(NULL);
+    aSocket.SetNext(nullptr);
 
 exit:
     return;
@@ -260,9 +304,9 @@
     return rval;
 }
 
-Message *Udp::NewMessage(uint16_t aReserved, const otMessageSettings *aSettings)
+Message *Udp::NewMessage(uint16_t aReserved, const Message::Settings &aSettings)
 {
-    return Get<Ip6>().NewMessage(sizeof(UdpHeader) + aReserved, aSettings);
+    return Get<Ip6>().NewMessage(sizeof(Header) + aReserved, aSettings);
 }
 
 otError Udp::SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, uint8_t aIpProto)
@@ -272,7 +316,7 @@
 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
     if (aMessageInfo.IsHostInterface())
     {
-        VerifyOrExit(mUdpForwarder != NULL, error = OT_ERROR_NO_ROUTE);
+        VerifyOrExit(mUdpForwarder != nullptr, error = OT_ERROR_NO_ROUTE);
         mUdpForwarder(&aMessage, aMessageInfo.mPeerPort, &aMessageInfo.GetPeerAddr(), aMessageInfo.mSockPort,
                       mUdpForwarderContext);
         // message is consumed by the callback
@@ -280,7 +324,7 @@
     else
 #endif
     {
-        UdpHeader udpHeader;
+        Header udpHeader;
 
         udpHeader.SetSourcePort(aMessageInfo.mSockPort);
         udpHeader.SetDestinationPort(aMessageInfo.mPeerPort);
@@ -299,15 +343,15 @@
 
 otError Udp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
 {
-    otError   error = OT_ERROR_NONE;
-    UdpHeader udpHeader;
-    uint16_t  payloadLength;
-    uint16_t  checksum;
+    otError  error = OT_ERROR_NONE;
+    Header   udpHeader;
+    uint16_t payloadLength;
+    uint16_t checksum;
 
     payloadLength = aMessage.GetLength() - aMessage.GetOffset();
 
     // check length
-    VerifyOrExit(payloadLength >= sizeof(UdpHeader), error = OT_ERROR_PARSE);
+    VerifyOrExit(payloadLength >= sizeof(Header), error = OT_ERROR_PARSE);
 
     // verify checksum
     checksum = Ip6::ComputePseudoheaderChecksum(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), payloadLength,
@@ -325,12 +369,12 @@
     aMessageInfo.mSockPort = udpHeader.GetDestinationPort();
 
 #if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    VerifyOrExit(IsMle(GetInstance(), aMessageInfo.mSockPort));
+    VerifyOrExit(IsMlePort(aMessageInfo.mSockPort), OT_NOOP);
 #endif
 
-    for (UdpReceiver *receiver = mReceivers.GetHead(); receiver; receiver = receiver->GetNext())
+    for (Receiver *receiver = mReceivers.GetHead(); receiver; receiver = receiver->GetNext())
     {
-        VerifyOrExit(!receiver->HandleMessage(aMessage, aMessageInfo));
+        VerifyOrExit(!receiver->HandleMessage(aMessage, aMessageInfo), OT_NOOP);
     }
 
     HandlePayload(aMessage, aMessageInfo);
@@ -341,40 +385,18 @@
 
 void Udp::HandlePayload(Message &aMessage, MessageInfo &aMessageInfo)
 {
-    // find socket
-    for (UdpSocket *socket = mSockets.GetHead(); socket; socket = socket->GetNext())
-    {
-        if (socket->GetSockName().mPort != aMessageInfo.GetSockPort())
-        {
-            continue;
-        }
+    SocketHandle *socket;
+    SocketHandle *prev;
 
-        if (!aMessageInfo.GetSockAddr().IsMulticast() && !socket->GetSockName().GetAddress().IsUnspecified() &&
-            socket->GetSockName().GetAddress() != aMessageInfo.GetSockAddr())
-        {
-            continue;
-        }
+    socket = mSockets.FindMatching(aMessageInfo, prev);
+    VerifyOrExit(socket != nullptr, OT_NOOP);
 
-        // verify source if connected socket
-        if (socket->GetPeerName().mPort != 0)
-        {
-            if (socket->GetPeerName().mPort != aMessageInfo.GetPeerPort())
-            {
-                continue;
-            }
+    aMessage.RemoveHeader(aMessage.GetOffset());
+    OT_ASSERT(aMessage.GetOffset() == 0);
+    socket->HandleUdpReceive(aMessage, aMessageInfo);
 
-            if (!socket->GetPeerName().GetAddress().IsUnspecified() &&
-                socket->GetPeerName().GetAddress() != aMessageInfo.GetPeerAddr())
-            {
-                continue;
-            }
-        }
-
-        aMessage.RemoveHeader(aMessage.GetOffset());
-        assert(aMessage.GetOffset() == 0);
-        socket->HandleUdpReceive(aMessage, aMessageInfo);
-        break;
-    }
+exit:
+    return;
 }
 
 void Udp::UpdateChecksum(Message &aMessage, uint16_t aChecksum)
@@ -387,7 +409,18 @@
     }
 
     aChecksum = HostSwap16(aChecksum);
-    aMessage.Write(aMessage.GetOffset() + UdpHeader::GetChecksumOffset(), sizeof(aChecksum), &aChecksum);
+    aMessage.Write(aMessage.GetOffset() + Header::kChecksumFieldOffset, sizeof(aChecksum), &aChecksum);
+}
+
+bool Udp::IsMlePort(uint16_t aPort) const
+{
+    bool isMlePort = (aPort == Mle::kUdpPort);
+
+#if OPENTHREAD_FTD
+    isMlePort = isMlePort || (aPort == Get<MeshCoP::JoinerRouter>().GetJoinerUdpPort());
+#endif
+
+    return isMlePort;
 }
 
 } // namespace Ip6
diff --git a/src/core/net/udp6.hpp b/src/core/net/udp6.hpp
index 645a42b..5cc29fe 100644
--- a/src/core/net/udp6.hpp
+++ b/src/core/net/udp6.hpp
@@ -58,167 +58,279 @@
  */
 
 /**
- * This class implements a UDP receiver.
- *
- */
-class UdpReceiver : public otUdpReceiver, public LinkedListEntry<UdpReceiver>
-{
-    friend class Udp;
-
-public:
-    /**
-     * This constructor initializes the object.
-     *
-     * @param[in]   aUdpHandler     A pointer to the function to handle UDP message.
-     * @param[in]   aContext        A pointer to arbitrary context information.
-     *
-     */
-    UdpReceiver(otUdpHandler aHandler, void *aContext)
-    {
-        mNext    = NULL;
-        mHandler = aHandler;
-        mContext = aContext;
-    }
-
-private:
-    bool HandleMessage(Message &aMessage, const MessageInfo &aMessageInfo)
-    {
-        return mHandler(mContext, &aMessage, &aMessageInfo);
-    }
-};
-
-/**
- * This class implements a UDP/IPv6 socket.
- *
- */
-class UdpSocket : public otUdpSocket, public InstanceLocator, public LinkedListEntry<UdpSocket>
-{
-    friend class Udp;
-
-public:
-    /**
-     * This constructor initializes the object.
-     *
-     * @param[in]  aUdp  A reference to the UDP transport object.
-     *
-     */
-    explicit UdpSocket(Udp &aUdp);
-
-    /**
-     * This method returns a new UDP message with sufficient header space reserved.
-     *
-     * @note If @p aSettings is 'NULL', the link layer security is enabled and the message priority is set to
-     * OT_MESSAGE_PRIORITY_NORMAL by default.
-     *
-     * @param[in]  aReserved  The number of header bytes to reserve after the UDP header.
-     * @param[in]  aSettings  A pointer to the message settings or NULL to set default settings.
-     *
-     * @returns A pointer to the message or NULL if no buffers are available.
-     *
-     */
-    Message *NewMessage(uint16_t aReserved, const otMessageSettings *aSettings = NULL);
-
-    /**
-     * This method opens the UDP socket.
-     *
-     * @param[in]  aHandler  A pointer to a function that is called when receiving UDP messages.
-     * @param[in]  aContext  A pointer to arbitrary context information.
-     *
-     * @retval OT_ERROR_NONE     Successfully opened the socket.
-     * @retval OT_ERROR_ALREADY  The socket is already open.
-     *
-     */
-    otError Open(otUdpReceive aHandler, void *aContext);
-
-    /**
-     * This method binds the UDP socket.
-     *
-     * @param[in]  aSockAddr  A reference to the socket address.
-     *
-     * @retval OT_ERROR_NONE    Successfully bound the socket.
-     * @retval OT_ERROR_FAILED  Failed to bind UDP Socket.
-     *
-     */
-    otError Bind(const SockAddr &aSockAddr);
-
-    /**
-     * This method indicates whether or not the socket is bound.
-     *
-     * @retval TRUE if the socket is bound (i.e. source port is non-zero).
-     * @retval FALSE if the socket is not bound (source port is zero).
-     *
-     */
-    bool IsBound(void) const { return mSockName.mPort != 0; }
-
-    /**
-     * This method connects the UDP socket.
-     *
-     * @param[in]  aSockAddr  A reference to the socket address.
-     *
-     * @retval OT_ERROR_NONE    Successfully connected the socket.
-     * @retval OT_ERROR_FAILED  Failed to connect UDP Socket.
-     *
-     */
-    otError Connect(const SockAddr &aSockAddr);
-
-    /**
-     * This method closes the UDP socket.
-     *
-     * @retval OT_ERROR_NONE    Successfully closed the UDP socket.
-     * @retval OT_ERROR_FAILED  Failed to close UDP Socket.
-     *
-     */
-    otError Close(void);
-
-    /**
-     * This method sends a UDP message.
-     *
-     * @param[in]  aMessage      The message to send.
-     * @param[in]  aMessageInfo  The message info associated with @p aMessage.
-     *
-     * @retval OT_ERROR_NONE          Successfully sent the UDP message.
-     * @retval OT_ERROR_INVALID_ARGS  If no peer is specified in @p aMessageInfo or by connect().
-     * @retval OT_ERROR_NO_BUFS       Insufficient available buffer to add the UDP and IPv6 headers.
-     *
-     */
-    otError SendTo(Message &aMessage, const MessageInfo &aMessageInfo);
-
-    /**
-     * This method returns the local socket address.
-     *
-     * @returns A reference to the local socket address.
-     *
-     */
-    SockAddr &GetSockName(void) { return *static_cast<SockAddr *>(&mSockName); }
-
-    /**
-     * This method returns the peer's socket address.
-     *
-     * @returns A reference to the peer's socket address.
-     *
-     */
-    SockAddr &GetPeerName(void) { return *static_cast<SockAddr *>(&mPeerName); }
-
-private:
-    void HandleUdpReceive(Message &aMessage, const MessageInfo &aMessageInfo)
-    {
-        mHandler(mContext, &aMessage, &aMessageInfo);
-    }
-};
-
-/**
  * This class implements core UDP message handling.
  *
  */
 class Udp : public InstanceLocator
 {
-    friend class UdpSocket;
-
 public:
     /**
+     * This class implements a UDP/IPv6 socket.
+     *
+     */
+    class SocketHandle : public otUdpSocket, public LinkedListEntry<SocketHandle>
+    {
+        friend class Udp;
+        friend class LinkedList<SocketHandle>;
+
+    public:
+        /**
+         * This method indicates whether or not the socket is bound.
+         *
+         * @retval TRUE if the socket is bound (i.e. source port is non-zero).
+         * @retval FALSE if the socket is not bound (source port is zero).
+         *
+         */
+        bool IsBound(void) const { return mSockName.mPort != 0; }
+
+        /**
+         * This method returns the local socket address.
+         *
+         * @returns A reference to the local socket address.
+         *
+         */
+        SockAddr &GetSockName(void) { return *static_cast<SockAddr *>(&mSockName); }
+
+        /**
+         * This method returns the local socket address.
+         *
+         * @returns A reference to the local socket address.
+         *
+         */
+        const SockAddr &GetSockName(void) const { return *static_cast<const SockAddr *>(&mSockName); }
+
+        /**
+         * This method returns the peer's socket address.
+         *
+         * @returns A reference to the peer's socket address.
+         *
+         */
+        SockAddr &GetPeerName(void) { return *static_cast<SockAddr *>(&mPeerName); }
+
+        /**
+         * This method returns the peer's socket address.
+         *
+         * @returns A reference to the peer's socket address.
+         *
+         */
+        const SockAddr &GetPeerName(void) const { return *static_cast<const SockAddr *>(&mPeerName); }
+
+    private:
+        bool Matches(const MessageInfo &aMessageInfo) const;
+
+        void HandleUdpReceive(Message &aMessage, const MessageInfo &aMessageInfo)
+        {
+            mHandler(mContext, &aMessage, &aMessageInfo);
+        }
+    };
+
+    /**
+     * This class implements a UDP/IPv6 socket.
+     *
+     */
+    class Socket : public InstanceLocator, public SocketHandle
+    {
+        friend class Udp;
+
+    public:
+        /**
+         * This constructor initializes the object.
+         *
+         * @param[in]  aInstance  A reference to OpenThread instance.
+         *
+         */
+        explicit Socket(Instance &aInstance);
+
+        /**
+         * This method returns a new UDP message with sufficient header space reserved.
+         *
+         * @param[in]  aReserved  The number of header bytes to reserve after the UDP header.
+         * @param[in]  aSettings  The message settings (default is used if not provided).
+         *
+         * @returns A pointer to the message or nullptr if no buffers are available.
+         *
+         */
+        Message *NewMessage(uint16_t aReserved, const Message::Settings &aSettings = Message::Settings::GetDefault());
+
+        /**
+         * This method opens the UDP socket.
+         *
+         * @param[in]  aHandler  A pointer to a function that is called when receiving UDP messages.
+         * @param[in]  aContext  A pointer to arbitrary context information.
+         *
+         * @retval OT_ERROR_NONE     Successfully opened the socket.
+         * @retval OT_ERROR_FAILED   Failed to open the socket.
+         *
+         */
+        otError Open(otUdpReceive aHandler, void *aContext);
+
+        /**
+         * This method binds the UDP socket.
+         *
+         * @param[in]  aSockAddr  A reference to the socket address.
+         *
+         * @retval OT_ERROR_NONE    Successfully bound the socket.
+         * @retval OT_ERROR_FAILED  Failed to bind UDP Socket.
+         *
+         */
+        otError Bind(const SockAddr &aSockAddr);
+
+        /**
+         * This method connects the UDP socket.
+         *
+         * @param[in]  aSockAddr  A reference to the socket address.
+         *
+         * @retval OT_ERROR_NONE    Successfully connected the socket.
+         * @retval OT_ERROR_FAILED  Failed to connect UDP Socket.
+         *
+         */
+        otError Connect(const SockAddr &aSockAddr);
+
+        /**
+         * This method closes the UDP socket.
+         *
+         * @retval OT_ERROR_NONE    Successfully closed the UDP socket.
+         * @retval OT_ERROR_FAILED  Failed to close UDP Socket.
+         *
+         */
+        otError Close(void);
+
+        /**
+         * This method sends a UDP message.
+         *
+         * @param[in]  aMessage      The message to send.
+         * @param[in]  aMessageInfo  The message info associated with @p aMessage.
+         *
+         * @retval OT_ERROR_NONE          Successfully sent the UDP message.
+         * @retval OT_ERROR_INVALID_ARGS  If no peer is specified in @p aMessageInfo or by Connect().
+         * @retval OT_ERROR_NO_BUFS       Insufficient available buffer to add the UDP and IPv6 headers.
+         *
+         */
+        otError SendTo(Message &aMessage, const MessageInfo &aMessageInfo);
+    };
+
+    /**
+     * This class implements a UDP receiver.
+     *
+     */
+    class Receiver : public otUdpReceiver, public LinkedListEntry<Receiver>
+    {
+        friend class Udp;
+
+    public:
+        /**
+         * This constructor initializes the UDP receiver.
+         *
+         * @param[in]   aUdpHandler     A pointer to the function to handle UDP message.
+         * @param[in]   aContext        A pointer to arbitrary context information.
+         *
+         */
+        Receiver(otUdpHandler aHandler, void *aContext)
+        {
+            mNext    = nullptr;
+            mHandler = aHandler;
+            mContext = aContext;
+        }
+
+    private:
+        bool HandleMessage(Message &aMessage, const MessageInfo &aMessageInfo)
+        {
+            return mHandler(mContext, &aMessage, &aMessageInfo);
+        }
+    };
+
+    /**
+     * This class implements UDP header generation and parsing.
+     *
+     */
+    OT_TOOL_PACKED_BEGIN
+    class Header
+    {
+    public:
+        enum : uint8_t
+        {
+            kSourcePortFieldOffset = 0, ///< The byte offset of Source Port field in UDP header.
+            kDestPortFieldOffset   = 2, ///< The byte offset of Destination Port field in UDP header.
+            kLengthFieldOffset     = 4, ///< The byte offset of Length field in UDP header.
+            kChecksumFieldOffset   = 6, ///< The byte offset of Checksum field in UDP header.
+        };
+
+        /**
+         * This method returns the UDP Source Port.
+         *
+         * @returns The UDP Source Port.
+         *
+         */
+        uint16_t GetSourcePort(void) const { return HostSwap16(mSourcePort); }
+
+        /**
+         * This method sets the UDP Source Port.
+         *
+         * @param[in]  aPort  The UDP Source Port.
+         *
+         */
+        void SetSourcePort(uint16_t aPort) { mSourcePort = HostSwap16(aPort); }
+
+        /**
+         * This method returns the UDP Destination Port.
+         *
+         * @returns The UDP Destination Port.
+         *
+         */
+        uint16_t GetDestinationPort(void) const { return HostSwap16(mDestinationPort); }
+
+        /**
+         * This method sets the UDP Destination Port.
+         *
+         * @param[in]  aPort  The UDP Destination Port.
+         *
+         */
+        void SetDestinationPort(uint16_t aPort) { mDestinationPort = HostSwap16(aPort); }
+
+        /**
+         * This method returns the UDP Length.
+         *
+         * @returns The UDP Length.
+         *
+         */
+        uint16_t GetLength(void) const { return HostSwap16(mLength); }
+
+        /**
+         * This method sets the UDP Length.
+         *
+         * @param[in]  aLength  The UDP Length.
+         *
+         */
+        void SetLength(uint16_t aLength) { mLength = HostSwap16(aLength); }
+
+        /**
+         * This method returns the UDP Checksum.
+         *
+         * @returns The UDP Checksum.
+         *
+         */
+        uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); }
+
+        /**
+         * This method sets the UDP Checksum.
+         *
+         * @param[in]  aChecksum  The UDP Checksum.
+         *
+         */
+        void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }
+
+    private:
+        uint16_t mSourcePort;
+        uint16_t mDestinationPort;
+        uint16_t mLength;
+        uint16_t mChecksum;
+
+    } OT_TOOL_PACKED_END;
+
+    /**
      * This constructor initializes the object.
      *
-     * @param[in]  aIp6  A reference to OpenThread instance.
+     * @param[in]  aInstance  A reference to OpenThread instance.
      *
      */
     explicit Udp(Instance &aInstance);
@@ -232,7 +344,7 @@
      * @retval OT_ERROR_ALREADY The UDP receiver was already added.
      *
      */
-    otError AddReceiver(UdpReceiver &aReceiver);
+    otError AddReceiver(Receiver &aReceiver);
 
     /**
      * This method removes a UDP receiver.
@@ -243,23 +355,69 @@
      * @retval OT_ERROR_NOT_FOUND   The UDP receiver was not added.
      *
      */
-    otError RemoveReceiver(UdpReceiver &aReceiver);
+    otError RemoveReceiver(Receiver &aReceiver);
 
     /**
-     * This method adds a UDP socket.
+     * This method opens a UDP socket.
      *
-     * @param[in]  aSocket  A reference to the UDP socket.
+     * @param[in]  aSocket   A reference to the socket.
+     * @param[in]  aHandler  A pointer to a function that is called when receiving UDP messages.
+     * @param[in]  aContext  A pointer to arbitrary context information.
+     *
+     * @retval OT_ERROR_NONE     Successfully opened the socket.
+     * @retval OT_ERROR_FAILED   Failed to open the socket.
      *
      */
-    void AddSocket(UdpSocket &aSocket);
+    otError Open(SocketHandle &aSocket, otUdpReceive aHandler, void *aContext);
 
     /**
-     * This method removes a UDP socket.
+     * This method binds a UDP socket.
      *
-     * @param[in]  aSocket  A reference to the UDP socket.
+     * @param[in]  aSocket    A reference to the socket.
+     * @param[in]  aSockAddr  A reference to the socket address.
+     *
+     * @retval OT_ERROR_NONE    Successfully bound the socket.
+     * @retval OT_ERROR_FAILED  Failed to bind UDP Socket.
      *
      */
-    void RemoveSocket(UdpSocket &aSocket);
+    otError Bind(SocketHandle &aSocket, const SockAddr &aSockAddr);
+
+    /**
+     * This method connects a UDP socket.
+     *
+     * @param[in]  aSocket    A reference to the socket.
+     * @param[in]  aSockAddr  A reference to the socket address.
+     *
+     * @retval OT_ERROR_NONE    Successfully connected the socket.
+     * @retval OT_ERROR_FAILED  Failed to connect UDP Socket.
+     *
+     */
+    otError Connect(SocketHandle &aSocket, const SockAddr &aSockAddr);
+
+    /**
+     * This method closes the UDP socket.
+     *
+     * @param[in]  aSocket    A reference to the socket.
+     *
+     * @retval OT_ERROR_NONE    Successfully closed the UDP socket.
+     * @retval OT_ERROR_FAILED  Failed to close UDP Socket.
+     *
+     */
+    otError Close(SocketHandle &aSocket);
+
+    /**
+     * This method sends a UDP message using a socket.
+     *
+     * @param[in]  aSocket       A reference to the socket.
+     * @param[in]  aMessage      The message to send.
+     * @param[in]  aMessageInfo  The message info associated with @p aMessage.
+     *
+     * @retval OT_ERROR_NONE          Successfully sent the UDP message.
+     * @retval OT_ERROR_INVALID_ARGS  If no peer is specified in @p aMessageInfo or by Connect().
+     * @retval OT_ERROR_NO_BUFS       Insufficient available buffer to add the UDP and IPv6 headers.
+     *
+     */
+    otError SendTo(SocketHandle &aSocket, Message &aMessage, const MessageInfo &aMessageInfo);
 
     /**
      * This method returns a new ephemeral port.
@@ -273,12 +431,12 @@
      * This method returns a new UDP message with sufficient header space reserved.
      *
      * @param[in]  aReserved  The number of header bytes to reserve after the UDP header.
-     * @param[in]  aPriority  The priority of the message.
+     * @param[in]  aSettings  The message settings.
      *
-     * @returns A pointer to the message or NULL if no buffers are available.
+     * @returns A pointer to the message or nullptr if no buffers are available.
      *
      */
-    Message *NewMessage(uint16_t aReserved, const otMessageSettings *aSettings = NULL);
+    Message *NewMessage(uint16_t aReserved, const Message::Settings &aSettings = Message::Settings::GetDefault());
 
     /**
      * This method sends an IPv6 datagram.
@@ -323,9 +481,13 @@
      */
     void UpdateChecksum(Message &aMessage, uint16_t aChecksum);
 
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    otUdpSocket *GetUdpSockets(void) { return mSockets.GetHead(); }
-#endif
+    /**
+     * This method returns the head of UDP Sockets list.
+     *
+     * @returns A pointer to the head of UDP Socket linked list.
+     *
+     */
+    SocketHandle *GetUdpSockets(void) { return mSockets.GetHead(); }
 
 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
     /**
@@ -340,7 +502,7 @@
         mUdpForwarder        = aForwarder;
         mUdpForwarderContext = aContext;
     }
-#endif // OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
+#endif
 
 private:
     enum
@@ -349,114 +511,19 @@
         kDynamicPortMax = 65535, ///< Service Name and Transport Protocol Port Number Registry
     };
 
-    uint16_t                mEphemeralPort;
-    LinkedList<UdpReceiver> mReceivers;
-    LinkedList<UdpSocket>   mSockets;
+    void AddSocket(SocketHandle &aSocket);
+    void RemoveSocket(SocketHandle &aSocket);
+    bool IsMlePort(uint16_t aPort) const;
+
+    uint16_t                 mEphemeralPort;
+    LinkedList<Receiver>     mReceivers;
+    LinkedList<SocketHandle> mSockets;
 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
     void *         mUdpForwarderContext;
     otUdpForwarder mUdpForwarder;
 #endif
 };
 
-OT_TOOL_PACKED_BEGIN
-struct UdpHeaderPoD
-{
-    uint16_t mSource;
-    uint16_t mDestination;
-    uint16_t mLength;
-    uint16_t mChecksum;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements UDP header generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class UdpHeader : private UdpHeaderPoD
-{
-public:
-    /**
-     * This method returns the UDP Source Port.
-     *
-     * @returns The UDP Source Port.
-     *
-     */
-    uint16_t GetSourcePort(void) const { return HostSwap16(mSource); }
-
-    /**
-     * This method sets the UDP Source Port.
-     *
-     * @param[in]  aPort  The UDP Source Port.
-     *
-     */
-    void SetSourcePort(uint16_t aPort) { mSource = HostSwap16(aPort); }
-
-    /**
-     * This method returns the UDP Destination Port.
-     *
-     * @returns The UDP Destination Port.
-     *
-     */
-    uint16_t GetDestinationPort(void) const { return HostSwap16(mDestination); }
-
-    /**
-     * This method sets the UDP Destination Port.
-     *
-     * @param[in]  aPort  The UDP Destination Port.
-     *
-     */
-    void SetDestinationPort(uint16_t aPort) { mDestination = HostSwap16(aPort); }
-
-    /**
-     * This method returns the UDP Length.
-     *
-     * @returns The UDP Length.
-     *
-     */
-    uint16_t GetLength(void) const { return HostSwap16(mLength); }
-
-    /**
-     * This method sets the UDP Length.
-     *
-     * @param[in]  aLength  The UDP Length.
-     *
-     */
-    void SetLength(uint16_t aLength) { mLength = HostSwap16(aLength); }
-
-    /**
-     * This method returns the UDP Checksum.
-     *
-     * @returns The UDP Checksum.
-     *
-     */
-    uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); }
-
-    /**
-     * This method sets the UDP Checksum.
-     *
-     * @param[in]  aChecksum  The UDP Checksum.
-     *
-     */
-    void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }
-
-    /**
-     * This static method returns the byte offset for the UDP Length.
-     *
-     * @returns The byte offset for the UDP Length.
-     *
-     */
-    static uint8_t GetLengthOffset(void) { return offsetof(UdpHeaderPoD, mLength); }
-
-    /**
-     * This static method returns the byte offset for the UDP Checksum.
-     *
-     * @returns The byte offset for the UDP Checksum.
-     *
-     */
-    static uint8_t GetChecksumOffset(void) { return offsetof(UdpHeaderPoD, mChecksum); }
-
-} OT_TOOL_PACKED_END;
-
 /**
  * @}
  *
diff --git a/src/core/openthread-core-config.h b/src/core/openthread-core-config.h
index 2847187..5f79261 100644
--- a/src/core/openthread-core-config.h
+++ b/src/core/openthread-core-config.h
@@ -36,17 +36,24 @@
 
 #include <openthread/config.h>
 
+#define OT_THREAD_VERSION_INVALID 0
+#define OT_THREAD_VERSION_1_1 2
+#define OT_THREAD_VERSION_1_2 3
+
 #define OPENTHREAD_CORE_CONFIG_H_IN
 
 #ifdef OPENTHREAD_PROJECT_CORE_CONFIG_FILE
 #include OPENTHREAD_PROJECT_CORE_CONFIG_FILE
 #endif
 
-#define OPENTHREAD_THREAD_VERSION (2)
+#ifndef OPENTHREAD_CONFIG_THREAD_VERSION
+#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_1
+#endif
 
 #include "config/openthread-core-default-config.h"
 
 #include "config/announce_sender.h"
+#include "config/backbone_router.h"
 #include "config/border_router.h"
 #include "config/channel_manager.h"
 #include "config/channel_monitor.h"
diff --git a/src/core/radio/radio.cpp b/src/core/radio/radio.cpp
new file mode 100644
index 0000000..33571b6
--- /dev/null
+++ b/src/core/radio/radio.cpp
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "radio.hpp"
+
+#include "common/locator-getters.hpp"
+#include "utils/otns.hpp"
+
+namespace ot {
+
+void Radio::SetExtendedAddress(const Mac::ExtAddress &aExtAddress)
+{
+    otPlatRadioSetExtendedAddress(GetInstance(), &aExtAddress);
+
+#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
+    Get<Utils::Otns>().EmitExtendedAddress(aExtAddress);
+#endif
+}
+
+void Radio::SetShortAddress(Mac::ShortAddress aShortAddress)
+{
+    otPlatRadioSetShortAddress(GetInstance(), aShortAddress);
+
+#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
+    Get<Utils::Otns>().EmitShortAddress(aShortAddress);
+#endif
+}
+
+otError Radio::Transmit(Mac::TxFrame &aFrame)
+{
+#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
+    Get<Utils::Otns>().EmitTransmit(aFrame);
+#endif
+
+    return otPlatRadioTransmit(GetInstance(), &aFrame);
+}
+
+} // namespace ot
diff --git a/src/core/radio/radio.hpp b/src/core/radio/radio.hpp
index 0b55167..f014e6f 100644
--- a/src/core/radio/radio.hpp
+++ b/src/core/radio/radio.hpp
@@ -39,8 +39,8 @@
 #include <openthread/platform/radio.h>
 
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 #include "mac/mac_frame.hpp"
-#include "utils/static_assert.hpp"
 
 namespace ot {
 
@@ -58,7 +58,7 @@
  * This class represents an OpenThread radio abstraction.
  *
  */
-class Radio : public InstanceLocator
+class Radio : public InstanceLocator, private NonCopyable
 {
     friend class Instance;
 
@@ -90,9 +90,9 @@
 #endif
     };
 
-    OT_STATIC_ASSERT((OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT || OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT),
-                     "OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT or OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT "
-                     "must be set to 1 to specify the radio mode");
+    static_assert((OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT || OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT),
+                  "OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT or OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT "
+                  "must be set to 1 to specify the radio mode");
 
     /**
      * This class defines the callbacks from `Radio`.
@@ -106,7 +106,7 @@
         /**
          * This callback method handles a "Receive Done" event from radio platform.
          *
-         * @param[in]  aFrame    A pointer to the received frame or NULL if the receive operation failed.
+         * @param[in]  aFrame    A pointer to the received frame or nullptr if the receive operation failed.
          * @param[in]  aError    OT_ERROR_NONE when successfully received a frame,
          *                       OT_ERROR_ABORT when reception was aborted and a frame was not received,
          *                       OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
@@ -126,7 +126,7 @@
          * This callback method handles a "Transmit Done" event from radio platform.
          *
          * @param[in]  aFrame     The frame that was transmitted.
-         * @param[in]  aAckFrame  A pointer to the ACK frame, NULL if no ACK was received.
+         * @param[in]  aAckFrame  A pointer to the ACK frame, nullptr if no ACK was received.
          * @param[in]  aError     OT_ERROR_NONE when the frame was transmitted,
          *                        OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
          *                        OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the
@@ -151,7 +151,7 @@
         /**
          * This callback method handles a "Receive Done" event from radio platform when diagnostics mode is enabled.
          *
-         * @param[in]  aFrame    A pointer to the received frame or NULL if the receive operation failed.
+         * @param[in]  aFrame    A pointer to the received frame or nullptr if the receive operation failed.
          * @param[in]  aError    OT_ERROR_NONE when successfully received a frame,
          *                       OT_ERROR_ABORT when reception was aborted and a frame was not received,
          *                       OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
@@ -237,10 +237,7 @@
      * @param[in] aExtAddress  The IEEE 802.15.4 Extended Address stored in little-endian byte order.
      *
      */
-    void SetExtendedAddress(const Mac::ExtAddress &aExtAddress)
-    {
-        otPlatRadioSetExtendedAddress(GetInstance(), &aExtAddress);
-    }
+    void SetExtendedAddress(const Mac::ExtAddress &aExtAddress);
 
     /**
      * This method sets the Short Address for address filtering.
@@ -248,7 +245,37 @@
      * @param[in] aShortAddress  The IEEE 802.15.4 Short Address.
      *
      */
-    void SetShortAddress(Mac::ShortAddress aShortAddress) { otPlatRadioSetShortAddress(GetInstance(), aShortAddress); }
+    void SetShortAddress(Mac::ShortAddress aShortAddress);
+
+    /**
+     * This method sets MAC key and key ID.
+     *
+     * @param[in] aKeyIdMode  MAC key ID mode.
+     * @param[in] aKeyId      Current MAC key index.
+     * @param[in] aPrevKey    The previous MAC key.
+     * @param[in] aCurrKey    The current MAC key.
+     * @param[in] aNextKey    The next MAC key.
+     *
+     */
+    void SetMacKey(uint8_t         aKeyIdMode,
+                   uint8_t         aKeyId,
+                   const Mac::Key &aPrevKey,
+                   const Mac::Key &aCurrKey,
+                   const Mac::Key &aNextKey)
+    {
+        otPlatRadioSetMacKey(GetInstance(), aKeyIdMode, aKeyId, &aPrevKey, &aCurrKey, &aNextKey);
+    }
+
+    /**
+     * This method sets the current MAC Frame Counter value.
+     *
+     * @param[in] aMacFrameCounter  The MAC Frame Counter value.
+     *
+     */
+    void SetMacFrameCounter(uint32_t aMacFrameCounter)
+    {
+        otPlatRadioSetMacFrameCounter(GetInstance(), aMacFrameCounter);
+    }
 
     /**
      * This method gets the radio's transmit power in dBm.
@@ -401,7 +428,7 @@
      * @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state.
      *
      */
-    otError Transmit(Mac::TxFrame &aFrame) { return otPlatRadioTransmit(GetInstance(), &aFrame); }
+    otError Transmit(Mac::TxFrame &aFrame);
 
     /**
      * This method gets the most recent RSSI measurement.
diff --git a/src/core/radio/radio_callbacks.cpp b/src/core/radio/radio_callbacks.cpp
index c037061..11d713c 100644
--- a/src/core/radio/radio_callbacks.cpp
+++ b/src/core/radio/radio_callbacks.cpp
@@ -73,7 +73,7 @@
 {
 #if OPENTHREAD_RADIO
     // Pass it to notify OpenThread `Diags` module on host side.
-    HandleTransmitDone(aFrame, NULL, aError);
+    HandleTransmitDone(aFrame, nullptr, aError);
 #else
     OT_UNUSED_VARIABLE(aFrame);
     Get<FactoryDiags::Diags>().TransmitDone(aError);
diff --git a/src/core/radio/radio_platform.cpp b/src/core/radio/radio_platform.cpp
index 014ece1..06d8b1b 100644
--- a/src/core/radio/radio_platform.cpp
+++ b/src/core/radio/radio_platform.cpp
@@ -31,6 +31,7 @@
  */
 
 #include <openthread/instance.h>
+#include <openthread/platform/time.h>
 
 #include "common/instance.hpp"
 #include "radio/radio.hpp"
@@ -124,3 +125,36 @@
 
     return OT_RADIO_STATE_INVALID;
 }
+
+OT_TOOL_WEAK void otPlatRadioSetMacKey(otInstance *    aInstance,
+                                       uint8_t         aKeyIdMode,
+                                       uint8_t         aKeyId,
+                                       const otMacKey *aPrevKey,
+                                       const otMacKey *aCurrKey,
+                                       const otMacKey *aNextKey)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aKeyIdMode);
+    OT_UNUSED_VARIABLE(aKeyId);
+    OT_UNUSED_VARIABLE(aPrevKey);
+    OT_UNUSED_VARIABLE(aCurrKey);
+    OT_UNUSED_VARIABLE(aNextKey);
+}
+
+OT_TOOL_WEAK void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aMacFrameCounter);
+}
+
+OT_TOOL_WEAK uint64_t otPlatTimeGet(void)
+{
+    return UINT64_MAX;
+}
+
+OT_TOOL_WEAK uint64_t otPlatRadioGetNow(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return UINT64_MAX;
+}
diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp
index 11e2adc..7d17bce 100644
--- a/src/core/thread/address_resolver.cpp
+++ b/src/core/thread/address_resolver.cpp
@@ -57,37 +57,117 @@
     , mAddressError(OT_URI_PATH_ADDRESS_ERROR, &AddressResolver::HandleAddressError, this)
     , mAddressQuery(OT_URI_PATH_ADDRESS_QUERY, &AddressResolver::HandleAddressQuery, this)
     , mAddressNotification(OT_URI_PATH_ADDRESS_NOTIFY, &AddressResolver::HandleAddressNotification, this)
+    , mCacheEntryPool(aInstance)
+    , mCachedList()
+    , mSnoopedList()
+    , mQueryList()
+    , mQueryRetryList()
     , mIcmpHandler(&AddressResolver::HandleIcmpReceive, this)
-    , mTimer(aInstance, &AddressResolver::HandleTimer, this)
+    , mTimer(aInstance, AddressResolver::HandleTimer, this)
 {
-    Clear();
-
     Get<Coap::Coap>().AddResource(mAddressError);
     Get<Coap::Coap>().AddResource(mAddressQuery);
     Get<Coap::Coap>().AddResource(mAddressNotification);
 
-    Get<Ip6::Icmp>().RegisterHandler(mIcmpHandler);
+    IgnoreError(Get<Ip6::Icmp>().RegisterHandler(mIcmpHandler));
 }
 
 void AddressResolver::Clear(void)
 {
-    memset(&mCache, 0, sizeof(mCache));
+    CacheEntryList *lists[] = {&mCachedList, &mSnoopedList, &mQueryList, &mQueryRetryList};
 
-    for (uint8_t i = 0; i < kCacheEntries; i++)
+    for (size_t index = 0; index < OT_ARRAY_LENGTH(lists); index++)
     {
-        mCache[i].mAge = i;
+        CacheEntryList *list = lists[index];
+        CacheEntry *    entry;
+
+        while ((entry = list->Pop()) != nullptr)
+        {
+            if (list == &mQueryList)
+            {
+                Get<MeshForwarder>().HandleResolved(entry->GetTarget(), OT_ERROR_DROP);
+            }
+
+            mCacheEntryPool.Free(*entry);
+        }
     }
 }
 
-otError AddressResolver::GetEntry(uint8_t aIndex, otEidCacheEntry &aEntry) const
+otError AddressResolver::GetNextCacheEntry(EntryInfo &aInfo, Iterator &aIterator) const
 {
-    otError error = OT_ERROR_NONE;
+    otError               error = OT_ERROR_NONE;
+    const CacheEntryList *list;
+    const CacheEntry *    entry;
 
-    VerifyOrExit(aIndex < kCacheEntries, error = OT_ERROR_INVALID_ARGS);
-    aEntry.mTarget = mCache[aIndex].mTarget;
-    aEntry.mRloc16 = mCache[aIndex].mRloc16;
-    aEntry.mAge    = mCache[aIndex].mAge;
-    aEntry.mValid  = mCache[aIndex].mState == Cache::kStateCached;
+    list  = reinterpret_cast<const CacheEntryList *>(aIterator.mData[kIteratorListIndex]);
+    entry = reinterpret_cast<const CacheEntry *>(aIterator.mData[kIteratorEntryIndex]);
+
+    while (entry == nullptr)
+    {
+        if (list == nullptr)
+        {
+            list = &mCachedList;
+        }
+        else if (list == &mCachedList)
+        {
+            list = &mSnoopedList;
+        }
+        else if (list == &mSnoopedList)
+        {
+            list = &mQueryList;
+        }
+        else if (list == &mQueryList)
+        {
+            list = &mQueryRetryList;
+        }
+        else
+        {
+            ExitNow(error = OT_ERROR_NOT_FOUND);
+        }
+
+        entry = list->GetHead();
+    }
+
+    // Update the iterator then populate the `aInfo`.
+
+    aIterator.mData[kIteratorEntryIndex] = entry->GetNext();
+    aIterator.mData[kIteratorListIndex]  = list;
+
+    memset(&aInfo, 0, sizeof(aInfo));
+    aInfo.mTarget = entry->GetTarget();
+    aInfo.mRloc16 = entry->GetRloc16();
+
+    if (list == &mCachedList)
+    {
+        aInfo.mState          = OT_CACHE_ENTRY_STATE_CACHED;
+        aInfo.mCanEvict       = true;
+        aInfo.mValidLastTrans = entry->IsLastTransactionTimeValid();
+
+        VerifyOrExit(entry->IsLastTransactionTimeValid(), OT_NOOP);
+
+        aInfo.mLastTransTime = entry->GetLastTransactionTime();
+        static_cast<Ip6::Address &>(aInfo.mMeshLocalEid).SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
+        static_cast<Ip6::Address &>(aInfo.mMeshLocalEid).SetIid(entry->GetMeshLocalIid());
+
+        ExitNow();
+    }
+
+    if (list == &mSnoopedList)
+    {
+        aInfo.mState = OT_CACHE_ENTRY_STATE_SNOOPED;
+    }
+    else if (list == &mQueryList)
+    {
+        aInfo.mState = OT_CACHE_ENTRY_STATE_QUERY;
+    }
+    else
+    {
+        aInfo.mState = OT_CACHE_ENTRY_STATE_RETRY_QUERY;
+    }
+
+    aInfo.mCanEvict   = entry->CanEvict();
+    aInfo.mTimeout    = entry->GetTimeout();
+    aInfo.mRetryDelay = entry->GetRetryDelay();
 
 exit:
     return error;
@@ -95,276 +175,350 @@
 
 void AddressResolver::Remove(uint8_t aRouterId)
 {
-    for (int i = 0; i < kCacheEntries; i++)
-    {
-        if (Mle::Mle::RouterIdFromRloc16(mCache[i].mRloc16) == aRouterId)
-        {
-            InvalidateCacheEntry(mCache[i], kReasonRemovingRouterId);
-        }
-    }
+    Remove(Mle::Mle::Rloc16FromRouterId(aRouterId), /* aMatchRouterId */ true);
 }
 
 void AddressResolver::Remove(uint16_t aRloc16)
 {
-    for (int i = 0; i < kCacheEntries; i++)
+    Remove(aRloc16, /* aMatchRouterId */ false);
+}
+
+AddressResolver::CacheEntry *AddressResolver::GetEntryAfter(CacheEntry *aPrev, CacheEntryList &aList)
+{
+    return (aPrev == nullptr) ? aList.GetHead() : aPrev->GetNext();
+}
+
+void AddressResolver::Remove(Mac::ShortAddress aRloc16, bool aMatchRouterId)
+{
+    CacheEntryList *lists[] = {&mCachedList, &mSnoopedList};
+
+    for (size_t index = 0; index < OT_ARRAY_LENGTH(lists); index++)
     {
-        if (mCache[i].mRloc16 == aRloc16)
+        CacheEntryList *list = lists[index];
+        CacheEntry *    prev = nullptr;
+        CacheEntry *    entry;
+
+        while ((entry = GetEntryAfter(prev, *list)) != nullptr)
         {
-            InvalidateCacheEntry(mCache[i], kReasonRemovingRloc16);
+            if ((aMatchRouterId && Mle::Mle::RouterIdMatch(entry->GetRloc16(), aRloc16)) ||
+                (!aMatchRouterId && (entry->GetRloc16() == aRloc16)))
+            {
+                RemoveCacheEntry(*entry, *list, prev, aMatchRouterId ? kReasonRemovingRouterId : kReasonRemovingRloc16);
+                mCacheEntryPool.Free(*entry);
+
+                // If the entry is removed from list, we keep the same
+                // `prev` pointer.
+            }
+            else
+            {
+                prev = entry;
+            }
         }
     }
 }
 
+AddressResolver::CacheEntry *AddressResolver::FindCacheEntry(const Ip6::Address &aEid,
+                                                             CacheEntryList *&   aList,
+                                                             CacheEntry *&       aPrevEntry)
+{
+    CacheEntry *    entry   = nullptr;
+    CacheEntryList *lists[] = {&mCachedList, &mSnoopedList, &mQueryList, &mQueryRetryList};
+
+    for (size_t index = 0; index < OT_ARRAY_LENGTH(lists); index++)
+    {
+        aList = lists[index];
+        entry = aList->FindMatching(aEid, aPrevEntry);
+        VerifyOrExit(entry == nullptr, OT_NOOP);
+    }
+
+exit:
+    return entry;
+}
+
 void AddressResolver::Remove(const Ip6::Address &aEid)
 {
-    for (int i = 0; i < kCacheEntries; i++)
-    {
-        if (mCache[i].mState == Cache::kStateInvalid || mCache[i].mTarget != aEid)
-        {
-            continue;
-        }
-
-        InvalidateCacheEntry(mCache[i], kReasonRemovingEid);
-        break;
-    }
+    Remove(aEid, kReasonRemovingEid);
 }
 
-AddressResolver::Cache *AddressResolver::NewCacheEntry(void)
+void AddressResolver::Remove(const Ip6::Address &aEid, Reason aReason)
 {
-    Cache *rval = NULL;
+    CacheEntry *    entry;
+    CacheEntry *    prev;
+    CacheEntryList *list;
 
-    for (int i = 0; i < kCacheEntries; i++)
-    {
-        if (mCache[i].mState == Cache::kStateQuery && mCache[i].mFailures == 0)
-        {
-            continue;
-        }
+    entry = FindCacheEntry(aEid, list, prev);
+    VerifyOrExit(entry != nullptr, OT_NOOP);
 
-        if (rval == NULL || rval->mAge < mCache[i].mAge)
-        {
-            rval = &mCache[i];
-        }
-    }
+    RemoveCacheEntry(*entry, *list, prev, aReason);
+    mCacheEntryPool.Free(*entry);
 
-    if (rval != NULL)
-    {
-        InvalidateCacheEntry(*rval, kReasonEvictingForNewEntry);
-    }
-
-    return rval;
+exit:
+    return;
 }
 
-void AddressResolver::MarkCacheEntryAsUsed(Cache &aEntry)
+AddressResolver::CacheEntry *AddressResolver::NewCacheEntry(bool aSnoopedEntry)
 {
-    for (int i = 0; i < kCacheEntries; i++)
+    CacheEntry *    newEntry  = nullptr;
+    CacheEntry *    prevEntry = nullptr;
+    CacheEntryList *lists[]   = {&mSnoopedList, &mQueryRetryList, &mQueryList, &mCachedList};
+
+    // The following order is used when trying to allocate a new cache
+    // entry: First the cache pool is checked, followed by the list
+    // of snooped entries, then query-retry list (entries in delay
+    // retry timeout wait due to a prior query failing to get a
+    // response), then the query list (entries actively querying and
+    // waiting for address notification response), and finally the
+    // cached (in-use) list. Within each list the oldest entry is
+    // reclaimed first (the list's tail). We also make sure the entry
+    // can be evicted (e.g., first time query entries can not be
+    // evicted till timeout).
+
+    newEntry = mCacheEntryPool.Allocate();
+    VerifyOrExit(newEntry == nullptr, OT_NOOP);
+
+    for (size_t index = 0; index < OT_ARRAY_LENGTH(lists); index++)
     {
-        if (mCache[i].mAge < aEntry.mAge)
+        CacheEntryList *list = lists[index];
+        CacheEntry *    prev;
+        CacheEntry *    entry;
+        uint16_t        numNonEvictable = 0;
+
+        for (prev = nullptr; (entry = GetEntryAfter(prev, *list)) != nullptr; prev = entry)
         {
-            mCache[i].mAge++;
+            if ((list != &mCachedList) && !entry->CanEvict())
+            {
+                numNonEvictable++;
+                continue;
+            }
+
+            newEntry  = entry;
+            prevEntry = prev;
+        }
+
+        if (newEntry != nullptr)
+        {
+            RemoveCacheEntry(*newEntry, *list, prevEntry, kReasonEvictingForNewEntry);
+            ExitNow();
+        }
+
+        if (aSnoopedEntry && (list == &mSnoopedList))
+        {
+            // Check if the new entry is being requested for "snoop
+            // optimization" (i.e., inspection of a received message).
+            // When a new snooped entry is added, we do not allow it
+            // to be evicted for a short timeout. This allows some
+            // delay for a response message to use the entry (if entry
+            // is used it will be moved to the cached list). If a
+            // snooped entry is not used after the timeout, we allow
+            // it to be evicted. To ensure snooped entries do not
+            // overwrite other cached entries, we limit the number of
+            // snooped entries that are in timeout mode and cannot be
+            // evicted by `kMaxNonEvictableSnoopedEntries`.
+
+            VerifyOrExit(numNonEvictable < kMaxNonEvictableSnoopedEntries, OT_NOOP);
         }
     }
 
-    aEntry.mAge = 0;
+exit:
+    return newEntry;
 }
 
-const char *AddressResolver::InvalidationReasonToString(InvalidationReason aReason)
+void AddressResolver::RemoveCacheEntry(CacheEntry &    aEntry,
+                                       CacheEntryList &aList,
+                                       CacheEntry *    aPrevEntry,
+                                       Reason          aReason)
 {
-    const char *str = "";
+    aList.PopAfter(aPrevEntry);
 
-    switch (aReason)
+    if (&aList == &mQueryList)
     {
-    case kReasonRemovingRouterId:
-        str = "removing router id";
-        break;
-
-    case kReasonRemovingRloc16:
-        str = "removing rloc16";
-        break;
-
-    case kReasonReceivedIcmpDstUnreachNoRoute:
-        str = "received icmp no route";
-        break;
-
-    case kReasonEvictingForNewEntry:
-        str = "evicting for new entry";
-        break;
-
-    case kReasonRemovingEid:
-        str = "removing eid";
-        break;
+        Get<MeshForwarder>().HandleResolved(aEntry.GetTarget(), OT_ERROR_DROP);
     }
 
-    return str;
-}
-
-void AddressResolver::InvalidateCacheEntry(Cache &aEntry, InvalidationReason aReason)
-{
-    OT_UNUSED_VARIABLE(aReason);
-
-    for (int i = 0; i < kCacheEntries; i++)
-    {
-        if (mCache[i].mAge > aEntry.mAge)
-        {
-            mCache[i].mAge--;
-        }
-    }
-
-    switch (aEntry.mState)
-    {
-    case Cache::kStateCached:
-        otLogNoteArp("Cache entry removed: %s, 0x%04x - %s", aEntry.mTarget.ToString().AsCString(), aEntry.mRloc16,
-                     InvalidationReasonToString(aReason));
-        break;
-
-    case Cache::kStateQuery:
-        otLogNoteArp("Cache entry (query mode) removed: %s, timeout:%d, retry:%d - %s",
-                     aEntry.mTarget.ToString().AsCString(), aEntry.mTimeout, aEntry.mRetryTimeout,
-                     InvalidationReasonToString(aReason));
-        break;
-
-    default:
-        break;
-    }
-
-    aEntry.mAge   = kCacheEntries - 1;
-    aEntry.mState = Cache::kStateInvalid;
+    LogCacheEntryChange(kEntryRemoved, aReason, aEntry, &aList);
 }
 
 otError AddressResolver::UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16)
 {
-    otError error = OT_ERROR_NOT_FOUND;
+    otError         error = OT_ERROR_NONE;
+    CacheEntryList *list;
+    CacheEntry *    entry;
+    CacheEntry *    prev;
 
-    for (int i = 0; i < kCacheEntries; i++)
+    entry = FindCacheEntry(aEid, list, prev);
+    VerifyOrExit(entry != nullptr, error = OT_ERROR_NOT_FOUND);
+
+    if ((list == &mCachedList) || (list == &mSnoopedList))
     {
-        if (mCache[i].mState == Cache::kStateInvalid || mCache[i].mTarget != aEid)
-        {
-            continue;
-        }
+        VerifyOrExit(entry->GetRloc16() != aRloc16, OT_NOOP);
+        entry->SetRloc16(aRloc16);
+    }
+    else
+    {
+        // Entry is in `mQueryList` or `mQueryRetryList`. Remove it
+        // from its current list, update it, and then add it to the
+        // `mCachedList`.
 
-        if (mCache[i].mRloc16 != aRloc16)
-        {
-            // not updating the age here is intentional because this cache entry is not actually being used
-            mCache[i].mRloc16 = aRloc16;
+        list->PopAfter(prev);
 
-            if (mCache[i].mState != Cache::kStateCached)
-            {
-                mCache[i].mRetryTimeout        = 0;
-                mCache[i].mLastTransactionTime = static_cast<uint32_t>(kLastTransactionTimeInvalid);
-                mCache[i].mTimeout             = 0;
-                mCache[i].mFailures            = 0;
-                mCache[i].mState               = Cache::kStateCached;
+        entry->SetRloc16(aRloc16);
+        entry->MarkLastTransactionTimeAsInvalid();
+        mCachedList.Push(*entry);
 
-                Get<MeshForwarder>().HandleResolved(aEid, OT_ERROR_NONE);
-            }
-
-            otLogNoteArp("Cache entry updated (snoop): %s, 0x%04x", aEid.ToString().AsCString(), aRloc16);
-        }
-
-        error = OT_ERROR_NONE;
+        Get<MeshForwarder>().HandleResolved(aEid, OT_ERROR_NONE);
     }
 
-    return error;
-}
-
-otError AddressResolver::AddCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16)
-{
-    otError error = OT_ERROR_NONE;
-    Cache * entry = NewCacheEntry();
-
-    VerifyOrExit(entry != NULL, error = OT_ERROR_NO_BUFS);
-
-    entry->mTarget   = aEid;
-    entry->mRloc16   = aRloc16;
-    entry->mTimeout  = 0;
-    entry->mFailures = 0;
-    entry->mState    = Cache::kStateCached;
-
-    MarkCacheEntryAsUsed(*entry);
+    LogCacheEntryChange(kEntryUpdated, kReasonSnoop, *entry);
 
 exit:
     return error;
 }
 
+void AddressResolver::AddSnoopedCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16)
+{
+    uint16_t    numNonEvictable = 0;
+    CacheEntry *entry;
+
+    entry = NewCacheEntry(/* aSnoopedEntry */ true);
+    VerifyOrExit(entry != nullptr, OT_NOOP);
+
+    for (CacheEntry *snooped = mSnoopedList.GetHead(); snooped != nullptr; snooped = snooped->GetNext())
+    {
+        if (!snooped->CanEvict())
+        {
+            numNonEvictable++;
+        }
+    }
+
+    entry->SetTarget(aEid);
+    entry->SetRloc16(aRloc16);
+
+    if (numNonEvictable < kMaxNonEvictableSnoopedEntries)
+    {
+        entry->SetCanEvict(false);
+        entry->SetTimeout(kSnoopBlockEvictionTimeout);
+
+        if (!mTimer.IsRunning())
+        {
+            mTimer.Start(kStateUpdatePeriod);
+        }
+    }
+    else
+    {
+        entry->SetCanEvict(true);
+        entry->SetTimeout(0);
+    }
+
+    mSnoopedList.Push(*entry);
+
+    LogCacheEntryChange(kEntryAdded, kReasonSnoop, *entry);
+
+exit:
+    return;
+}
+
 void AddressResolver::RestartAddressQueries(void)
 {
-    for (int i = 0; i < kCacheEntries; i++)
+    CacheEntry *tail;
+
+    // We move all entries from `mQueryRetryList` at the tail of
+    // `mQueryList` and then (re)send Address Query for all entries in
+    // the updated `mQueryList`.
+
+    tail = mQueryList.GetTail();
+
+    if (tail == nullptr)
     {
-        Cache &entry = mCache[i];
+        mQueryList.SetHead(mQueryRetryList.GetHead());
+    }
+    else
+    {
+        tail->SetNext(mQueryRetryList.GetHead());
+    }
 
-        if (entry.mState != Cache::kStateQuery)
-        {
-            continue;
-        }
+    mQueryRetryList.Clear();
 
-        SendAddressQuery(entry.mTarget);
+    for (CacheEntry *entry = mQueryList.GetHead(); entry != nullptr; entry = entry->GetNext())
+    {
+        IgnoreError(SendAddressQuery(entry->GetTarget()));
 
-        entry.mTimeout      = kAddressQueryTimeout;
-        entry.mFailures     = 0;
-        entry.mRetryTimeout = kAddressQueryInitialRetryDelay;
+        entry->SetTimeout(kAddressQueryTimeout);
+        entry->SetRetryDelay(kAddressQueryInitialRetryDelay);
+        entry->SetCanEvict(false);
     }
 }
 
 otError AddressResolver::Resolve(const Ip6::Address &aEid, uint16_t &aRloc16)
 {
-    otError error = OT_ERROR_NONE;
-    Cache * entry = NULL;
+    otError         error = OT_ERROR_NONE;
+    CacheEntry *    entry;
+    CacheEntry *    prev = nullptr;
+    CacheEntryList *list;
 
-    for (int i = 0; i < kCacheEntries; i++)
+    entry = FindCacheEntry(aEid, list, prev);
+
+    if (entry == nullptr)
     {
-        if (mCache[i].mState != Cache::kStateInvalid)
-        {
-            if (mCache[i].mTarget == aEid)
-            {
-                entry = &mCache[i];
-                break;
-            }
-        }
+        // If the entry is not present in any of the lists, try to
+        // allocate a new entry and perform address query. We do not
+        // allow first-time address query entries to be evicted till
+        // timeout.
+
+        entry = NewCacheEntry(/* aSnoopedEntry */ false);
+        VerifyOrExit(entry != nullptr, error = OT_ERROR_NO_BUFS);
+
+        entry->SetTarget(aEid);
+        entry->SetRloc16(Mac::kShortAddrInvalid);
+        entry->SetRetryDelay(kAddressQueryInitialRetryDelay);
+        entry->SetCanEvict(false);
+        list = nullptr;
     }
 
-    if (entry == NULL)
+    if ((list == &mCachedList) || (list == &mSnoopedList))
     {
-        entry = NewCacheEntry();
+        // Remove the entry from its current list and push it at the
+        // head of cached list.
+
+        list->PopAfter(prev);
+
+        if (list == &mSnoopedList)
+        {
+            entry->MarkLastTransactionTimeAsInvalid();
+        }
+
+        mCachedList.Push(*entry);
+        aRloc16 = entry->GetRloc16();
+        ExitNow();
     }
 
-    VerifyOrExit(entry != NULL, error = OT_ERROR_NO_BUFS);
-
-    switch (entry->mState)
+    if (list == &mQueryList)
     {
-    case Cache::kStateInvalid:
-        SuccessOrExit(error = SendAddressQuery(aEid));
-        entry->mTarget       = aEid;
-        entry->mRloc16       = Mac::kShortAddrInvalid;
-        entry->mTimeout      = kAddressQueryTimeout;
-        entry->mFailures     = 0;
-        entry->mRetryTimeout = kAddressQueryInitialRetryDelay;
-        entry->mState        = Cache::kStateQuery;
-        error                = OT_ERROR_ADDRESS_QUERY;
-        break;
-
-    case Cache::kStateQuery:
-        if (entry->mTimeout > 0)
-        {
-            error = OT_ERROR_ADDRESS_QUERY;
-        }
-        else if (entry->mTimeout == 0 && entry->mRetryTimeout == 0)
-        {
-            SuccessOrExit(error = SendAddressQuery(aEid));
-            entry->mTimeout = kAddressQueryTimeout;
-            error           = OT_ERROR_ADDRESS_QUERY;
-        }
-        else
-        {
-            error = OT_ERROR_DROP;
-        }
-
-        break;
-
-    case Cache::kStateCached:
-        aRloc16 = entry->mRloc16;
-        MarkCacheEntryAsUsed(*entry);
-        break;
+        ExitNow(error = OT_ERROR_ADDRESS_QUERY);
     }
 
+    if (list == &mQueryRetryList)
+    {
+        // Allow an entry in query-retry mode to resend an Address
+        // Query again only if the timeout (retry delay interval) is
+        // expired.
+
+        VerifyOrExit(entry->IsTimeoutZero(), error = OT_ERROR_DROP);
+        mQueryRetryList.PopAfter(prev);
+    }
+
+    entry->SetTimeout(kAddressQueryTimeout);
+
+    error = SendAddressQuery(aEid);
+    VerifyOrExit(error == OT_ERROR_NONE, mCacheEntryPool.Free(*entry));
+
+    if (list == nullptr)
+    {
+        LogCacheEntryChange(kEntryAdded, kReasonQueryRequest, *entry);
+    }
+
+    mQueryList.Push(*entry);
+    error = OT_ERROR_ADDRESS_QUERY;
+
 exit:
     return error;
 }
@@ -373,21 +527,18 @@
 {
     otError          error;
     Coap::Message *  message;
-    ThreadTargetTlv  targetTlv;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewPriorityMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST);
     SuccessOrExit(error = message->AppendUriPathOptions(OT_URI_PATH_ADDRESS_QUERY));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    targetTlv.Init();
-    targetTlv.SetTarget(aEid);
-    SuccessOrExit(error = targetTlv.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, ThreadTlv::kTarget, &aEid, sizeof(aEid)));
 
-    messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xff03);
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(0x0002);
+    messageInfo.GetPeerAddr().SetToRealmLocalAllRoutersMulticast();
+
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetPeerPort(kCoapUdpPort);
 
@@ -402,7 +553,7 @@
         mTimer.Start(kStateUpdatePeriod);
     }
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -418,115 +569,92 @@
 
 void AddressResolver::HandleAddressNotification(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    ThreadTargetTlv              targetTlv;
-    ThreadMeshLocalEidTlv        mlIidTlv;
-    ThreadRloc16Tlv              rloc16Tlv;
-    ThreadLastTransactionTimeTlv lastTransactionTimeTlv;
-    uint32_t                     lastTransactionTime;
+    Ip6::Address             target;
+    Ip6::InterfaceIdentifier meshLocalIid;
+    uint16_t                 rloc16;
+    uint32_t                 lastTransactionTime;
+    CacheEntryList *         list;
+    CacheEntry *             entry;
+    CacheEntry *             prev;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
-    SuccessOrExit(ThreadTlv::GetTlv(aMessage, ThreadTlv::kTarget, sizeof(targetTlv), targetTlv));
-    VerifyOrExit(targetTlv.IsValid());
-    targetTlv.Init(); // reset TLV length
+    SuccessOrExit(Tlv::FindTlv(aMessage, ThreadTlv::kTarget, &target, sizeof(target)));
+    SuccessOrExit(Tlv::FindTlv(aMessage, ThreadTlv::kMeshLocalEid, &meshLocalIid, sizeof(meshLocalIid)));
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, ThreadTlv::kRloc16, rloc16));
 
-    SuccessOrExit(ThreadTlv::GetTlv(aMessage, ThreadTlv::kMeshLocalEid, sizeof(mlIidTlv), mlIidTlv));
-    VerifyOrExit(mlIidTlv.IsValid());
-    mlIidTlv.Init(); // reset TLV length
-
-    SuccessOrExit(ThreadTlv::GetTlv(aMessage, ThreadTlv::kRloc16, sizeof(rloc16Tlv), rloc16Tlv));
-    VerifyOrExit(rloc16Tlv.IsValid());
-
-    lastTransactionTime = 0;
-
-    if (ThreadTlv::GetTlv(aMessage, ThreadTlv::kLastTransactionTime, sizeof(lastTransactionTimeTlv),
-                          lastTransactionTimeTlv) == OT_ERROR_NONE)
+    switch (Tlv::FindUint32Tlv(aMessage, ThreadTlv::kLastTransactionTime, lastTransactionTime))
     {
-        VerifyOrExit(lastTransactionTimeTlv.IsValid());
-        lastTransactionTime = lastTransactionTimeTlv.GetTime();
+    case OT_ERROR_NONE:
+        break;
+    case OT_ERROR_NOT_FOUND:
+        lastTransactionTime = 0;
+        break;
+    default:
+        ExitNow();
     }
 
     otLogInfoArp("Received address notification from 0x%04x for %s to 0x%04x",
-                 HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[7]), targetTlv.GetTarget().ToString().AsCString(),
-                 rloc16Tlv.GetRloc16());
+                 aMessageInfo.GetPeerAddr().GetIid().GetLocator(), target.ToString().AsCString(), rloc16);
 
-    for (int i = 0; i < kCacheEntries; i++)
+    entry = FindCacheEntry(target, list, prev);
+    VerifyOrExit(entry != nullptr, OT_NOOP);
+
+    if (list == &mCachedList)
     {
-        if (mCache[i].mTarget != targetTlv.GetTarget())
+        if (entry->IsLastTransactionTimeValid())
         {
-            continue;
-        }
+            // Receiving multiple Address Notification for an EID from
+            // different mesh-local IIDs indicates address is in use
+            // by more than one device. Try to resolve the duplicate
+            // address by sending an Address Error message.
 
-        switch (mCache[i].mState)
-        {
-        case Cache::kStateInvalid:
-            break;
+            VerifyOrExit(entry->GetMeshLocalIid() == meshLocalIid, SendAddressError(target, meshLocalIid, nullptr));
 
-        case Cache::kStateCached:
-            if (mCache[i].mLastTransactionTime != kLastTransactionTimeInvalid)
-            {
-                if (memcmp(mCache[i].mMeshLocalIid, mlIidTlv.GetIid(), sizeof(mCache[i].mMeshLocalIid)) != 0)
-                {
-                    SendAddressError(targetTlv, mlIidTlv, NULL);
-                    ExitNow();
-                }
-
-                if (lastTransactionTime >= mCache[i].mLastTransactionTime)
-                {
-                    ExitNow();
-                }
-            }
-
-            // fall through
-
-        case Cache::kStateQuery:
-            memcpy(mCache[i].mMeshLocalIid, mlIidTlv.GetIid(), sizeof(mCache[i].mMeshLocalIid));
-            mCache[i].mRloc16              = rloc16Tlv.GetRloc16();
-            mCache[i].mRetryTimeout        = 0;
-            mCache[i].mLastTransactionTime = lastTransactionTime;
-            mCache[i].mTimeout             = 0;
-            mCache[i].mFailures            = 0;
-            mCache[i].mState               = Cache::kStateCached;
-            MarkCacheEntryAsUsed(mCache[i]);
-
-            otLogNoteArp("Cache entry updated (notification): %s, 0x%04x, lastTrans:%d",
-                         targetTlv.GetTarget().ToString().AsCString(), rloc16Tlv.GetRloc16(), lastTransactionTime);
-
-            if (Get<Coap::Coap>().SendEmptyAck(aMessage, aMessageInfo) == OT_ERROR_NONE)
-            {
-                otLogInfoArp("Sending address notification acknowledgment");
-            }
-
-            Get<MeshForwarder>().HandleResolved(targetTlv.GetTarget(), OT_ERROR_NONE);
-            break;
+            VerifyOrExit(lastTransactionTime < entry->GetLastTransactionTime(), OT_NOOP);
         }
     }
 
+    entry->SetRloc16(rloc16);
+    entry->SetMeshLocalIid(meshLocalIid);
+    entry->SetLastTransactionTime(lastTransactionTime);
+
+    list->PopAfter(prev);
+    mCachedList.Push(*entry);
+
+    LogCacheEntryChange(kEntryUpdated, kReasonReceivedNotification, *entry);
+
+    if (Get<Coap::Coap>().SendEmptyAck(aMessage, aMessageInfo) == OT_ERROR_NONE)
+    {
+        otLogInfoArp("Sending address notification acknowledgment");
+    }
+
+    Get<MeshForwarder>().HandleResolved(target, OT_ERROR_NONE);
+
 exit:
     return;
 }
 
-otError AddressResolver::SendAddressError(const ThreadTargetTlv &      aTarget,
-                                          const ThreadMeshLocalEidTlv &aEid,
-                                          const Ip6::Address *         aDestination)
+void AddressResolver::SendAddressError(const Ip6::Address &            aTarget,
+                                       const Ip6::InterfaceIdentifier &aMeshLocalIid,
+                                       const Ip6::Address *            aDestination)
 {
     otError          error;
     Coap::Message *  message;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
-    message->Init(aDestination == NULL ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
+    message->Init(aDestination == nullptr ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
     SuccessOrExit(error = message->AppendUriPathOptions(OT_URI_PATH_ADDRESS_ERROR));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    SuccessOrExit(error = aTarget.AppendTo(*message));
-    SuccessOrExit(error = aEid.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, ThreadTlv::kTarget, &aTarget, sizeof(aTarget)));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, ThreadTlv::kMeshLocalEid, &aMeshLocalIid, sizeof(aMeshLocalIid)));
 
-    if (aDestination == NULL)
+    if (aDestination == nullptr)
     {
-        messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xff03);
-        messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(0x0002);
+        messageInfo.GetPeerAddr().SetToRealmLocalAllRoutersMulticast();
     }
     else
     {
@@ -538,16 +666,19 @@
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
 
-    otLogInfoArp("Sending address error for target %s", aTarget.GetTarget().ToString().AsCString());
+    otLogInfoArp("Sending address error for target %s", aTarget.ToString().AsCString());
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        message->Free();
-    }
+        otLogInfoArp("Failed to send address error: %s", otThreadErrorToString(error));
 
-    return error;
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
 }
 
 void AddressResolver::HandleAddressError(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -558,14 +689,13 @@
 
 void AddressResolver::HandleAddressError(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    otError               error = OT_ERROR_NONE;
-    ThreadTargetTlv       targetTlv;
-    ThreadMeshLocalEidTlv mlIidTlv;
-    Mac::ExtAddress       macAddr;
-    Ip6::Address          destination;
+    otError                  error = OT_ERROR_NONE;
+    Ip6::Address             target;
+    Ip6::InterfaceIdentifier meshLocalIid;
+    Mac::ExtAddress          extAddr;
+    Ip6::Address             destination;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST,
-                 error = OT_ERROR_DROP);
+    VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST, error = OT_ERROR_DROP);
 
     otLogInfoArp("Received address error notification");
 
@@ -577,19 +707,13 @@
         }
     }
 
-    SuccessOrExit(error = ThreadTlv::GetTlv(aMessage, ThreadTlv::kTarget, sizeof(targetTlv), targetTlv));
-    VerifyOrExit(targetTlv.IsValid(), error = OT_ERROR_PARSE);
-    targetTlv.Init(); // reset TLV length
-
-    SuccessOrExit(error = ThreadTlv::GetTlv(aMessage, ThreadTlv::kMeshLocalEid, sizeof(mlIidTlv), mlIidTlv));
-    VerifyOrExit(mlIidTlv.IsValid(), error = OT_ERROR_PARSE);
-    mlIidTlv.Init(); // reset TLV length
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, ThreadTlv::kTarget, &target, sizeof(target)));
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, ThreadTlv::kMeshLocalEid, &meshLocalIid, sizeof(meshLocalIid)));
 
     for (const Ip6::NetifUnicastAddress *address = Get<ThreadNetif>().GetUnicastAddresses(); address;
          address                                 = address->GetNext())
     {
-        if (address->GetAddress() == targetTlv.GetTarget() &&
-            memcmp(Get<Mle::MleRouter>().GetMeshLocal64().GetIid(), mlIidTlv.GetIid(), 8))
+        if (address->GetAddress() == target && Get<Mle::MleRouter>().GetMeshLocal64().GetIid() != meshLocalIid)
         {
             // Target EID matches address and Mesh Local EID differs
             Get<ThreadNetif>().RemoveUnicastAddress(*address);
@@ -597,30 +721,25 @@
         }
     }
 
-    macAddr.Set(mlIidTlv.GetIid());
-    macAddr.ToggleLocal();
+    meshLocalIid.ConvertToExtAddress(extAddr);
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
     {
-        Child &child = *iter.GetChild();
-
         if (child.IsFullThreadDevice())
         {
             continue;
         }
 
-        if (child.GetExtAddress() != macAddr)
+        if (child.GetExtAddress() != extAddr)
         {
             // Mesh Local EID differs, so check whether Target EID
             // matches a child address and if so remove it.
 
-            if (child.RemoveIp6Address(GetInstance(), targetTlv.GetTarget()) == OT_ERROR_NONE)
+            if (child.RemoveIp6Address(target) == OT_ERROR_NONE)
             {
-                destination.Clear();
-                destination.mFields.m16[0] = HostSwap16(0xfe80);
-                destination.SetIid(child.GetExtAddress());
+                SuccessOrExit(error = Get<Mle::Mle>().GetLocatorAddress(destination, child.GetRloc16()));
 
-                SendAddressError(targetTlv, mlIidTlv, &destination);
+                SendAddressError(target, meshLocalIid, &destination);
                 ExitNow();
             }
         }
@@ -642,44 +761,34 @@
 
 void AddressResolver::HandleAddressQuery(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    ThreadTargetTlv              targetTlv;
-    ThreadMeshLocalEidTlv        mlIidTlv;
-    ThreadLastTransactionTimeTlv lastTransactionTimeTlv;
+    Ip6::Address target;
+    uint32_t     lastTransactionTime;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_NON_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsNonConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
-    SuccessOrExit(ThreadTlv::GetTlv(aMessage, ThreadTlv::kTarget, sizeof(targetTlv), targetTlv));
-    VerifyOrExit(targetTlv.IsValid());
-    targetTlv.Init(); // reset TLV length
+    SuccessOrExit(Tlv::FindTlv(aMessage, ThreadTlv::kTarget, &target, sizeof(target)));
 
-    mlIidTlv.Init();
+    otLogInfoArp("Received address query from 0x%04x for target %s", aMessageInfo.GetPeerAddr().GetIid().GetLocator(),
+                 target.ToString().AsCString());
 
-    lastTransactionTimeTlv.Init();
-
-    otLogInfoArp("Received address query from 0x%04x for target %s",
-                 HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[7]), targetTlv.GetTarget().ToString().AsCString());
-
-    if (Get<ThreadNetif>().IsUnicastAddress(targetTlv.GetTarget()))
+    if (Get<ThreadNetif>().HasUnicastAddress(target))
     {
-        mlIidTlv.SetIid(Get<Mle::MleRouter>().GetMeshLocal64().GetIid());
-        SendAddressQueryResponse(targetTlv, mlIidTlv, NULL, aMessageInfo.GetPeerAddr());
+        SendAddressQueryResponse(target, Get<Mle::MleRouter>().GetMeshLocal64().GetIid(), nullptr,
+                                 aMessageInfo.GetPeerAddr());
         ExitNow();
     }
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
     {
-        Child &child = *iter.GetChild();
-
         if (child.IsFullThreadDevice() || child.GetLinkFailures() >= Mle::kFailedChildTransmissions)
         {
             continue;
         }
 
-        if (child.HasIp6Address(GetInstance(), targetTlv.GetTarget()))
+        if (child.HasIp6Address(target))
         {
-            mlIidTlv.SetIid(child.GetExtAddress());
-            lastTransactionTimeTlv.SetTime(TimerMilli::GetNow() - child.GetLastHeard());
-            SendAddressQueryResponse(targetTlv, mlIidTlv, &lastTransactionTimeTlv, aMessageInfo.GetPeerAddr());
+            lastTransactionTime = TimerMilli::GetNow() - child.GetLastHeard();
+            SendAddressQueryResponse(target, child.GetMeshLocalIid(), &lastTransactionTime, aMessageInfo.GetPeerAddr());
             ExitNow();
         }
     }
@@ -688,32 +797,28 @@
     return;
 }
 
-void AddressResolver::SendAddressQueryResponse(const ThreadTargetTlv &             aTargetTlv,
-                                               const ThreadMeshLocalEidTlv &       aMlEidTlv,
-                                               const ThreadLastTransactionTimeTlv *aLastTransactionTimeTlv,
-                                               const Ip6::Address &                aDestination)
+void AddressResolver::SendAddressQueryResponse(const Ip6::Address &            aTarget,
+                                               const Ip6::InterfaceIdentifier &aMeshLocalIid,
+                                               const uint32_t *                aLastTransactionTime,
+                                               const Ip6::Address &            aDestination)
 {
     otError          error;
     Coap::Message *  message;
-    ThreadRloc16Tlv  rloc16Tlv;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewPriorityMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
     SuccessOrExit(error = message->AppendUriPathOptions(OT_URI_PATH_ADDRESS_NOTIFY));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    SuccessOrExit(error = aTargetTlv.AppendTo(*message));
-    SuccessOrExit(error = aMlEidTlv.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, ThreadTlv::kTarget, &aTarget, sizeof(aTarget)));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, ThreadTlv::kMeshLocalEid, &aMeshLocalIid, sizeof(aMeshLocalIid)));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, ThreadTlv::kRloc16, Get<Mle::MleRouter>().GetRloc16()));
 
-    rloc16Tlv.Init();
-    rloc16Tlv.SetRloc16(Get<Mle::MleRouter>().GetRloc16());
-    SuccessOrExit(error = rloc16Tlv.AppendTo(*message));
-
-    if (aLastTransactionTimeTlv != NULL)
+    if (aLastTransactionTime != nullptr)
     {
-        SuccessOrExit(error = aLastTransactionTimeTlv->AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendUint32Tlv(*message, ThreadTlv::kLastTransactionTime, *aLastTransactionTime));
     }
 
     messageInfo.SetPeerAddr(aDestination);
@@ -722,11 +827,11 @@
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
 
-    otLogInfoArp("Sending address notification for target %s", aTargetTlv.GetTarget().ToString().AsCString());
+    otLogInfoArp("Sending address notification for target %s", aTarget.ToString().AsCString());
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -739,44 +844,77 @@
 
 void AddressResolver::HandleTimer(void)
 {
-    bool continueTimer = false;
+    bool        continueTimer = false;
+    CacheEntry *prev;
+    CacheEntry *entry;
 
-    for (int i = 0; i < kCacheEntries; i++)
+    for (entry = mSnoopedList.GetHead(); entry != nullptr; entry = entry->GetNext())
     {
-        if (mCache[i].mState != Cache::kStateQuery)
+        if (entry->IsTimeoutZero())
         {
             continue;
         }
 
         continueTimer = true;
+        entry->DecrementTimeout();
 
-        if (mCache[i].mTimeout > 0)
+        if (entry->IsTimeoutZero())
         {
-            mCache[i].mTimeout--;
-
-            if (mCache[i].mTimeout == 0)
-            {
-                mCache[i].mRetryTimeout =
-                    static_cast<uint16_t>(kAddressQueryInitialRetryDelay * (1 << mCache[i].mFailures));
-
-                if (mCache[i].mRetryTimeout < kAddressQueryMaxRetryDelay)
-                {
-                    mCache[i].mFailures++;
-                }
-                else
-                {
-                    mCache[i].mRetryTimeout = kAddressQueryMaxRetryDelay;
-                }
-
-                otLogInfoArp("Timed out waiting for address notification for %s, retry: %d",
-                             mCache[i].mTarget.ToString().AsCString(), mCache[i].mRetryTimeout);
-
-                Get<MeshForwarder>().HandleResolved(mCache[i].mTarget, OT_ERROR_DROP);
-            }
+            entry->SetCanEvict(true);
         }
-        else if (mCache[i].mRetryTimeout > 0)
+    }
+
+    for (entry = mQueryRetryList.GetHead(); entry != nullptr; entry = entry->GetNext())
+    {
+        if (entry->IsTimeoutZero())
         {
-            mCache[i].mRetryTimeout--;
+            continue;
+        }
+
+        continueTimer = true;
+        entry->DecrementTimeout();
+    }
+
+    prev = nullptr;
+
+    while ((entry = GetEntryAfter(prev, mQueryList)) != nullptr)
+    {
+        OT_ASSERT(!entry->IsTimeoutZero());
+
+        continueTimer = true;
+        entry->DecrementTimeout();
+
+        if (entry->IsTimeoutZero())
+        {
+            uint16_t retryDelay = entry->GetRetryDelay();
+
+            entry->SetTimeout(retryDelay);
+
+            retryDelay <<= 1;
+
+            if (retryDelay > kAddressQueryMaxRetryDelay)
+            {
+                retryDelay = kAddressQueryMaxRetryDelay;
+            }
+
+            entry->SetRetryDelay(retryDelay);
+            entry->SetCanEvict(true);
+
+            // Move the entry from `mQueryList` to `mQueryRetryList`
+            mQueryList.PopAfter(prev);
+            mQueryRetryList.Push(*entry);
+
+            otLogInfoArp("Timed out waiting for address notification for %s, retry: %d",
+                         entry->GetTarget().ToString().AsCString(), entry->GetTimeout());
+
+            Get<MeshForwarder>().HandleResolved(entry->GetTarget(), OT_ERROR_DROP);
+
+            // When the entry is removed from `mQueryList`
+            // we keep the `prev` pointer same as before.
+        }
+        else
+        {
+            prev = entry;
         }
     }
 
@@ -795,30 +933,131 @@
 
     static_cast<AddressResolver *>(aContext)->HandleIcmpReceive(*static_cast<Message *>(aMessage),
                                                                 *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
-                                                                *static_cast<const Ip6::IcmpHeader *>(aIcmpHeader));
+                                                                *static_cast<const Ip6::Icmp::Header *>(aIcmpHeader));
 }
 
-void AddressResolver::HandleIcmpReceive(Message &               aMessage,
-                                        const Ip6::MessageInfo &aMessageInfo,
-                                        const Ip6::IcmpHeader & aIcmpHeader)
+void AddressResolver::HandleIcmpReceive(Message &                aMessage,
+                                        const Ip6::MessageInfo & aMessageInfo,
+                                        const Ip6::Icmp::Header &aIcmpHeader)
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
     Ip6::Header ip6Header;
 
-    VerifyOrExit(aIcmpHeader.GetType() == Ip6::IcmpHeader::kTypeDstUnreach);
-    VerifyOrExit(aIcmpHeader.GetCode() == Ip6::IcmpHeader::kCodeDstUnreachNoRoute);
-    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(ip6Header), &ip6Header) == sizeof(ip6Header));
+    VerifyOrExit(aIcmpHeader.GetType() == Ip6::Icmp::Header::kTypeDstUnreach, OT_NOOP);
+    VerifyOrExit(aIcmpHeader.GetCode() == Ip6::Icmp::Header::kCodeDstUnreachNoRoute, OT_NOOP);
+    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(ip6Header), &ip6Header) == sizeof(ip6Header), OT_NOOP);
 
-    for (int i = 0; i < kCacheEntries; i++)
+    Remove(ip6Header.GetDestination(), kReasonReceivedIcmpDstUnreachNoRoute);
+
+exit:
+    return;
+}
+
+// LCOV_EXCL_START
+
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_ARP == 1)
+
+void AddressResolver::LogCacheEntryChange(EntryChange       aChange,
+                                          Reason            aReason,
+                                          const CacheEntry &aEntry,
+                                          CacheEntryList *  aList)
+{
+    const char *change = "";
+    const char *reason = "";
+
+    switch (aChange)
     {
-        if (mCache[i].mState != Cache::kStateInvalid && mCache[i].mTarget == ip6Header.GetDestination())
-        {
-            InvalidateCacheEntry(mCache[i], kReasonReceivedIcmpDstUnreachNoRoute);
-            break;
-        }
+    case kEntryAdded:
+        change = "added";
+        break;
+    case kEntryUpdated:
+        change = "updated";
+        break;
+    case kEntryRemoved:
+        change = "removed";
+        break;
     }
 
+    switch (aReason)
+    {
+    case kReasonQueryRequest:
+        reason = "query request";
+        break;
+    case kReasonSnoop:
+        reason = "snoop";
+        break;
+    case kReasonReceivedNotification:
+        reason = "rx notification";
+        break;
+    case kReasonRemovingRouterId:
+        reason = "removing router id";
+        break;
+    case kReasonRemovingRloc16:
+        reason = "removing rloc16";
+        break;
+    case kReasonReceivedIcmpDstUnreachNoRoute:
+        reason = "rx icmp no route";
+        break;
+    case kReasonEvictingForNewEntry:
+        reason = "evicting for new entry";
+        break;
+    case kReasonRemovingEid:
+        reason = "removing eid";
+        break;
+    }
+
+    otLogNoteArp("Cache entry %s: %s, 0x%04x%s%s - %s", change, aEntry.GetTarget().ToString().AsCString(),
+                 aEntry.GetRloc16(), (aList == nullptr) ? "" : ", list:", ListToString(aList), reason);
+}
+
+const char *AddressResolver::ListToString(const CacheEntryList *aList) const
+{
+    const char *str = "";
+
+    VerifyOrExit(aList != &mCachedList, str = "cached");
+    VerifyOrExit(aList != &mSnoopedList, str = "snooped");
+    VerifyOrExit(aList != &mQueryList, str = "query");
+    VerifyOrExit(aList != &mQueryRetryList, str = "query-retry");
+
+exit:
+    return str;
+}
+
+#else // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_ARP == 1)
+
+void AddressResolver::LogCacheEntryChange(EntryChange, Reason, const CacheEntry &, CacheEntryList *)
+{
+}
+
+#endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_ARP == 1)
+
+// LCOV_EXCL_STOP
+
+//---------------------------------------------------------------------------------------------------------------------
+// AddressResolver::CacheEntry
+
+void AddressResolver::CacheEntry::Init(Instance &aInstance)
+{
+    InstanceLocatorInit::Init(aInstance);
+    mNextIndex = kNoNextIndex;
+}
+
+AddressResolver::CacheEntry *AddressResolver::CacheEntry::GetNext(void)
+{
+    return (mNextIndex == kNoNextIndex) ? nullptr : &Get<AddressResolver>().GetCacheEntryPool().GetEntryAt(mNextIndex);
+}
+
+const AddressResolver::CacheEntry *AddressResolver::CacheEntry::GetNext(void) const
+{
+    return (mNextIndex == kNoNextIndex) ? nullptr : &Get<AddressResolver>().GetCacheEntryPool().GetEntryAt(mNextIndex);
+}
+
+void AddressResolver::CacheEntry::SetNext(CacheEntry *aEntry)
+{
+    VerifyOrExit(aEntry != nullptr, mNextIndex = kNoNextIndex);
+    mNextIndex = Get<AddressResolver>().GetCacheEntryPool().GetIndexOf(*aEntry);
+
 exit:
     return;
 }
diff --git a/src/core/thread/address_resolver.hpp b/src/core/thread/address_resolver.hpp
index 0c3b5bf..881dd8b 100644
--- a/src/core/thread/address_resolver.hpp
+++ b/src/core/thread/address_resolver.hpp
@@ -37,6 +37,7 @@
 #include "openthread-core-config.h"
 
 #include "coap/coap.hpp"
+#include "common/linked_list.hpp"
 #include "common/locator.hpp"
 #include "common/timer.hpp"
 #include "mac/mac.hpp"
@@ -63,6 +64,18 @@
 {
 public:
     /**
+     * This type represents an iterator used for iterating through the EID cache table entries.
+     *
+     */
+    typedef otCacheEntryIterator Iterator;
+
+    /**
+     * This type represents an EID cache entry.
+     *
+     */
+    typedef otCacheEntryInfo EntryInfo;
+
+    /**
      * This constructor initializes the object.
      *
      */
@@ -75,16 +88,18 @@
     void Clear(void);
 
     /**
-     * This method gets an EID cache entry.
+     * This method gets the information about the next EID cache entry (using an iterator).
      *
-     * @param[in]   aIndex  An index into the EID cache table.
-     * @param[out]  aEntry  A reference to where the EID information is placed.
+     * @param[out]   aInfo       An `EntryInfo` where the EID cache entry information is placed.
+     * @param[inout] aIterator   An iterator. It will be updated to point to the next entry on success.
+     *                           To get the first entry, initialize the iterator by setting all its fields to zero.
+     *                           e.g., `memset` the the iterator structure to zero.
      *
-     * @retval OT_ERROR_NONE          Successfully retrieved the EID cache entry.
-     * @retval OT_ERROR_INVALID_ARGS  @p aIndex was out of bounds.
+     * @retval OT_ERROR_NONE       Successfully populated @p aInfo with the info for the next EID cache entry.
+     * @retval OT_ERROR_NOT_FOUND  No more entries in the address cache table.
      *
      */
-    otError GetEntry(uint8_t aIndex, otEidCacheEntry &aEntry) const;
+    otError GetNextCacheEntry(EntryInfo &aInfo, Iterator &aIterator) const;
 
     /**
      * This method removes the EID-to-RLOC cache entries corresponding to an RLOC16.
@@ -92,7 +107,7 @@
      * @param[in]  aRloc16  The RLOC16 address.
      *
      */
-    void Remove(uint16_t aRloc16);
+    void Remove(Mac::ShortAddress aRloc16);
 
     /**
      * This method removes all EID-to-RLOC cache entries associated with a Router ID.
@@ -123,16 +138,16 @@
     otError UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16);
 
     /**
-     * This method adds one cache entry for the EID.
+     * This method adds a snooped cache entry for a given EID.
+     *
+     * The method is intended to add an entry for snoop optimization (inspection of a received message to create a
+     * cache entry mapping an EID to a RLOC).
      *
      * @param[in]  aEid               A reference to the EID.
      * @param[in]  aRloc16            The RLOC16 corresponding to @p aEid.
      *
-     * @retval OT_ERROR_NONE           Successfully adds one cache entry.
-     * @retval OT_ERROR_NO_BUFS        Insufficient buffer space available to add one cache entry.
-     *
      */
-    otError AddCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16);
+    void AddSnoopedCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16);
 
     /**
      * This method returns the RLOC16 for a given EID, or initiates an Address Query if the mapping is not known.
@@ -159,48 +174,96 @@
 private:
     enum
     {
-        kCacheEntries      = OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_ENTRIES,
-        kStateUpdatePeriod = 1000u, ///< State update period in milliseconds.
-    };
-
-    /**
-     * Thread Protocol Parameters and Constants
-     *
-     */
-    enum
-    {
+        kCacheEntries                  = OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_ENTRIES,
+        kMaxNonEvictableSnoopedEntries = OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES,
         kAddressQueryTimeout           = OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT,             // in seconds
         kAddressQueryInitialRetryDelay = OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY, // in seconds
         kAddressQueryMaxRetryDelay     = OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY,     // in seconds
+        kSnoopBlockEvictionTimeout     = OPENTHREAD_CONFIG_TMF_SNOOP_CACHE_ENTRY_TIMEOUT,         // in seconds
+        kStateUpdatePeriod             = 1000u,                                                   // in milliseconds
+        kIteratorListIndex             = 0,
+        kIteratorEntryIndex            = 1,
     };
 
-    enum
+    class CacheEntry : public InstanceLocatorInit
     {
-        kLastTransactionTimeInvalid = 0xffffffff, ///< Used when entry is populated using forwarded data message.
-    };
+    public:
+        void Init(Instance &aInstance);
 
-    struct Cache
-    {
-        enum State
+        CacheEntry *      GetNext(void);
+        const CacheEntry *GetNext(void) const;
+        void              SetNext(CacheEntry *aEntry);
+
+        const Ip6::Address &GetTarget(void) const { return mTarget; }
+        void                SetTarget(const Ip6::Address &aTarget) { mTarget = aTarget; }
+
+        Mac::ShortAddress GetRloc16(void) const { return mRloc16; }
+        void              SetRloc16(Mac::ShortAddress aRloc16) { mRloc16 = aRloc16; }
+
+        const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mInfo.mCached.mMeshLocalIid; }
+        void SetMeshLocalIid(const Ip6::InterfaceIdentifier &aIid) { mInfo.mCached.mMeshLocalIid = aIid; }
+
+        uint32_t GetLastTransactionTime(void) const { return mInfo.mCached.mLastTransactionTime; }
+        void     SetLastTransactionTime(uint32_t aTime) { mInfo.mCached.mLastTransactionTime = aTime; }
+        bool     IsLastTransactionTimeValid(void) const { return GetLastTransactionTime() != kInvalidLastTransTime; }
+        void     MarkLastTransactionTimeAsInvalid(void) { SetLastTransactionTime(kInvalidLastTransTime); }
+
+        void     DecrementTimeout(void) { mInfo.mOther.mTimeout--; }
+        bool     IsTimeoutZero(void) const { return mInfo.mOther.mTimeout == 0; }
+        uint16_t GetTimeout(void) const { return mInfo.mOther.mTimeout; }
+        void     SetTimeout(uint16_t aTimeout) { mInfo.mOther.mTimeout = aTimeout; }
+
+        uint16_t GetRetryDelay(void) const { return mInfo.mOther.mRetryDelay; }
+        void     SetRetryDelay(uint16_t aDelay) { mInfo.mOther.mRetryDelay = aDelay; }
+
+        bool CanEvict(void) const { return mInfo.mOther.mCanEvict; }
+        void SetCanEvict(bool aCanEvict) { mInfo.mOther.mCanEvict = aCanEvict; }
+
+        bool Matches(const Ip6::Address &aEid) const { return GetTarget() == aEid; }
+
+    private:
+        enum
         {
-            kStateInvalid,
-            kStateQuery,
-            kStateCached,
+            kNoNextIndex          = 0xffff,     // mNextIndex value when at end of list.
+            kInvalidLastTransTime = 0xffffffff, // Value indicating mLastTransactionTime is invalid.
         };
 
         Ip6::Address      mTarget;
-        uint8_t           mMeshLocalIid[Ip6::Address::kInterfaceIdentifierSize];
-        uint32_t          mLastTransactionTime;
         Mac::ShortAddress mRloc16;
-        uint16_t          mRetryTimeout;
-        uint8_t           mTimeout;
-        uint8_t           mFailures;
-        uint8_t           mAge;
-        State             mState;
+        uint16_t          mNextIndex;
+        union
+        {
+            struct
+            {
+                uint32_t                 mLastTransactionTime;
+                Ip6::InterfaceIdentifier mMeshLocalIid;
+            } mCached;
+
+            struct
+            {
+                uint16_t mTimeout;
+                uint16_t mRetryDelay;
+                bool     mCanEvict;
+            } mOther;
+
+        } mInfo;
     };
 
-    enum InvalidationReason
+    typedef Pool<CacheEntry, kCacheEntries> CacheEntryPool;
+    typedef LinkedList<CacheEntry>          CacheEntryList;
+
+    enum EntryChange
     {
+        kEntryAdded,
+        kEntryUpdated,
+        kEntryRemoved,
+    };
+
+    enum Reason
+    {
+        kReasonQueryRequest,
+        kReasonSnoop,
+        kReasonReceivedNotification,
         kReasonRemovingRouterId,
         kReasonRemovingRloc16,
         kReasonReceivedIcmpDstUnreachNoRoute,
@@ -208,20 +271,22 @@
         kReasonRemovingEid,
     };
 
-    static const char *InvalidationReasonToString(InvalidationReason aReason);
+    CacheEntryPool &GetCacheEntryPool(void) { return mCacheEntryPool; }
 
-    Cache *NewCacheEntry(void);
-    void   MarkCacheEntryAsUsed(Cache &aEntry);
-    void   InvalidateCacheEntry(Cache &aEntry, InvalidationReason aReason);
+    void        Remove(Mac::ShortAddress aRloc16, bool aMatchRouterId);
+    void        Remove(const Ip6::Address &aEid, Reason aReason);
+    CacheEntry *FindCacheEntry(const Ip6::Address &aEid, CacheEntryList *&aList, CacheEntry *&aPrevEntry);
+    CacheEntry *NewCacheEntry(bool aSnoopedEntry);
+    void        RemoveCacheEntry(CacheEntry &aEntry, CacheEntryList &aList, CacheEntry *aPrevEntry, Reason aReason);
 
     otError SendAddressQuery(const Ip6::Address &aEid);
-    otError SendAddressError(const ThreadTargetTlv &      aTarget,
-                             const ThreadMeshLocalEidTlv &aEid,
-                             const Ip6::Address *         aDestination);
-    void    SendAddressQueryResponse(const ThreadTargetTlv &             aTargetTlv,
-                                     const ThreadMeshLocalEidTlv &       aMlEidTlv,
-                                     const ThreadLastTransactionTimeTlv *aLastTransactionTimeTlv,
-                                     const Ip6::Address &                aDestination);
+    void    SendAddressError(const Ip6::Address &            aTarget,
+                             const Ip6::InterfaceIdentifier &aMeshLocalIid,
+                             const Ip6::Address *            aDestination);
+    void    SendAddressQueryResponse(const Ip6::Address &            aTarget,
+                                     const Ip6::InterfaceIdentifier &aMeshLocalIid,
+                                     const uint32_t *                aLastTransactionTimeTlv,
+                                     const Ip6::Address &            aDestination);
 
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
 
@@ -238,17 +303,34 @@
                                   otMessage *          aMessage,
                                   const otMessageInfo *aMessageInfo,
                                   const otIcmp6Header *aIcmpHeader);
-    void HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Ip6::IcmpHeader &aIcmpHeader);
+    void        HandleIcmpReceive(Message &                aMessage,
+                                  const Ip6::MessageInfo & aMessageInfo,
+                                  const Ip6::Icmp::Header &aIcmpHeader);
 
     static void HandleTimer(Timer &aTimer);
     void        HandleTimer(void);
 
-    Coap::Resource   mAddressError;
-    Coap::Resource   mAddressQuery;
-    Coap::Resource   mAddressNotification;
-    Cache            mCache[kCacheEntries];
-    Ip6::IcmpHandler mIcmpHandler;
-    TimerMilli       mTimer;
+    void LogCacheEntryChange(EntryChange       aChange,
+                             Reason            aReason,
+                             const CacheEntry &aEntry,
+                             CacheEntryList *  aList = nullptr);
+
+    const char *ListToString(const CacheEntryList *aList) const;
+
+    static AddressResolver::CacheEntry *GetEntryAfter(CacheEntry *aPrev, CacheEntryList &aList);
+
+    Coap::Resource mAddressError;
+    Coap::Resource mAddressQuery;
+    Coap::Resource mAddressNotification;
+
+    CacheEntryPool mCacheEntryPool;
+    CacheEntryList mCachedList;
+    CacheEntryList mSnoopedList;
+    CacheEntryList mQueryList;
+    CacheEntryList mQueryRetryList;
+
+    Ip6::Icmp::Handler mIcmpHandler;
+    TimerMilli         mTimer;
 };
 
 /**
diff --git a/src/core/thread/announce_begin_server.cpp b/src/core/thread/announce_begin_server.cpp
index 1921614..01ce40c 100644
--- a/src/core/thread/announce_begin_server.cpp
+++ b/src/core/thread/announce_begin_server.cpp
@@ -48,20 +48,15 @@
 namespace ot {
 
 AnnounceBeginServer::AnnounceBeginServer(Instance &aInstance)
-    : AnnounceSenderBase(aInstance, &AnnounceBeginServer::HandleTimer)
+    : AnnounceSenderBase(aInstance, AnnounceBeginServer::HandleTimer)
     , mAnnounceBegin(OT_URI_PATH_ANNOUNCE_BEGIN, &AnnounceBeginServer::HandleRequest, this)
 {
     Get<Coap::Coap>().AddResource(mAnnounceBegin);
 }
 
-otError AnnounceBeginServer::SendAnnounce(uint32_t aChannelMask)
+void AnnounceBeginServer::SendAnnounce(uint32_t aChannelMask, uint8_t aCount, uint16_t aPeriod)
 {
-    return SendAnnounce(aChannelMask, kDefaultCount, kDefaultPeriod);
-}
-
-otError AnnounceBeginServer::SendAnnounce(uint32_t aChannelMask, uint8_t aCount, uint16_t aPeriod)
-{
-    return AnnounceSenderBase::SendAnnounce(Mac::ChannelMask(aChannelMask), aCount, aPeriod, kDefaultJitter);
+    AnnounceSenderBase::SendAnnounce(Mac::ChannelMask(aChannelMask), aCount, aPeriod, kDefaultJitter);
 }
 
 void AnnounceBeginServer::HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -72,21 +67,18 @@
 
 void AnnounceBeginServer::HandleRequest(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    uint32_t           mask;
-    MeshCoP::CountTlv  count;
-    MeshCoP::PeriodTlv period;
-    Ip6::MessageInfo   responseInfo(aMessageInfo);
+    uint32_t         mask;
+    uint8_t          count;
+    uint16_t         period;
+    Ip6::MessageInfo responseInfo(aMessageInfo);
 
-    VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST);
-    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
+    VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
+    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0, OT_NOOP);
 
-    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kCount, sizeof(count), count));
-    VerifyOrExit(count.IsValid());
+    SuccessOrExit(Tlv::FindUint8Tlv(aMessage, MeshCoP::Tlv::kCount, count));
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, MeshCoP::Tlv::kPeriod, period));
 
-    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPeriod, sizeof(period), period));
-    VerifyOrExit(period.IsValid());
-
-    SendAnnounce(mask, count.GetCount(), period.GetPeriod());
+    SendAnnounce(mask, count, period);
 
     if (aMessage.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast())
     {
diff --git a/src/core/thread/announce_begin_server.hpp b/src/core/thread/announce_begin_server.hpp
index b862678..054e54a 100644
--- a/src/core/thread/announce_begin_server.hpp
+++ b/src/core/thread/announce_begin_server.hpp
@@ -58,16 +58,6 @@
     explicit AnnounceBeginServer(Instance &aInstance);
 
     /**
-     * This method begins the MLE Announce transmission process using Count=3 and Period=1s.
-     *
-     * @param[in]  aChannelMask   The channels to use for transmission.
-     *
-     * @retval OT_ERROR_NONE  Successfully started the transmission process.
-     *
-     */
-    otError SendAnnounce(uint32_t aChannelMask);
-
-    /**
      * This method begins the MLE Announce transmission process.
      *
      * @param[in]  aChannelMask   The channels to use for transmission.
@@ -77,7 +67,7 @@
      * @retval OT_ERROR_NONE  Successfully started the transmission process.
      *
      */
-    otError SendAnnounce(uint32_t aChannelMask, uint8_t aCount, uint16_t aPeriod);
+    void SendAnnounce(uint32_t aChannelMask, uint8_t aCount = kDefaultCount, uint16_t aPeriod = kDefaultPeriod);
 
 private:
     enum
diff --git a/src/core/thread/announce_sender.cpp b/src/core/thread/announce_sender.cpp
index 86837bd..d316357 100644
--- a/src/core/thread/announce_sender.cpp
+++ b/src/core/thread/announce_sender.cpp
@@ -57,18 +57,13 @@
 {
 }
 
-otError AnnounceSenderBase::SendAnnounce(Mac::ChannelMask aChannelMask,
-                                         uint8_t          aCount,
-                                         uint32_t         aPeriod,
-                                         uint16_t         aJitter)
+void AnnounceSenderBase::SendAnnounce(Mac::ChannelMask aChannelMask, uint8_t aCount, uint32_t aPeriod, uint16_t aJitter)
 {
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(aPeriod != 0, error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit(aJitter < aPeriod, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aPeriod != 0, OT_NOOP);
+    VerifyOrExit(aJitter < aPeriod, OT_NOOP);
 
     aChannelMask.Intersect(Get<Mac::Mac>().GetSupportedChannelMask());
-    VerifyOrExit(!aChannelMask.IsEmpty(), error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(!aChannelMask.IsEmpty(), OT_NOOP);
 
     mChannelMask = aChannelMask;
     mCount       = aCount;
@@ -78,8 +73,11 @@
 
     mTimer.Start(Random::NonCrypto::AddJitter(mPeriod, mJitter));
 
+    otLogInfoMle("Starting periodic MLE Announcements tx, mask %s, count %u, period %u, jitter %u",
+                 aChannelMask.ToString().AsCString(), aCount, aPeriod, aJitter);
+
 exit:
-    return error;
+    return;
 }
 
 void AnnounceSenderBase::HandleTimer(void)
@@ -93,14 +91,14 @@
         if (mCount != 0)
         {
             mCount--;
-            VerifyOrExit(mCount != 0);
+            VerifyOrExit(mCount != 0, OT_NOOP);
         }
 
         mChannel = Mac::ChannelMask::kChannelIteratorFirst;
         error    = mChannelMask.GetNextChannel(mChannel);
     }
 
-    assert(error == OT_ERROR_NONE);
+    OT_ASSERT(error == OT_ERROR_NONE);
 
     Get<Mle::MleRouter>().SendAnnounce(mChannel, false);
 
@@ -113,8 +111,8 @@
 #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
 
 AnnounceSender::AnnounceSender(Instance &aInstance)
-    : AnnounceSenderBase(aInstance, &AnnounceSender::HandleTimer)
-    , mNotifierCallback(aInstance, HandleStateChanged, this)
+    : AnnounceSenderBase(aInstance, AnnounceSender::HandleTimer)
+    , Notifier::Receiver(aInstance, AnnounceSender::HandleNotifierEvents)
 {
 }
 
@@ -132,22 +130,24 @@
 
     switch (mle.GetRole())
     {
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case Mle::kRoleRouter:
+    case Mle::kRoleLeader:
         interval = kRouterTxInterval;
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case Mle::kRoleChild:
+#if OPENTHREAD_FTD
         if (mle.IsRouterEligible() && mle.IsRxOnWhenIdle())
         {
             interval = kReedTxInterval;
             break;
         }
+#endif
 
         // fall through
 
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
+    case Mle::kRoleDisabled:
+    case Mle::kRoleDetached:
         Stop();
         ExitNow();
     }
@@ -161,13 +161,10 @@
         period = kMinTxPeriod;
     }
 
-    VerifyOrExit(!IsRunning() || (period != GetPeriod()) || (GetChannelMask() != channelMask));
+    VerifyOrExit(!IsRunning() || (period != GetPeriod()) || (GetChannelMask() != channelMask), OT_NOOP);
 
     SendAnnounce(channelMask, 0, period, kMaxJitter);
 
-    otLogInfoMle("Starting periodic MLE Announcements tx, period %u, mask %s", period,
-                 channelMask.ToString().AsCString());
-
 exit:
     return;
 }
@@ -178,14 +175,14 @@
     otLogInfoMle("Stopping periodic MLE Announcements tx");
 }
 
-void AnnounceSender::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags)
+void AnnounceSender::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<AnnounceSender>().HandleStateChanged(aFlags);
+    static_cast<AnnounceSender &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
-void AnnounceSender::HandleStateChanged(otChangedFlags aFlags)
+void AnnounceSender::HandleNotifierEvents(Events aEvents)
 {
-    if ((aFlags & OT_CHANGED_THREAD_ROLE) != 0)
+    if (aEvents.Contains(kEventThreadRoleChanged))
     {
         CheckState();
     }
diff --git a/src/core/thread/announce_sender.hpp b/src/core/thread/announce_sender.hpp
index 7c22a4a..bf20a25 100644
--- a/src/core/thread/announce_sender.hpp
+++ b/src/core/thread/announce_sender.hpp
@@ -37,6 +37,7 @@
 #include "openthread-core-config.h"
 
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 #include "common/notifier.hpp"
 #include "common/timer.hpp"
 #include "mac/mac.hpp"
@@ -49,7 +50,7 @@
  * This class provides APIs to schedule periodic transmission of MLE Announcement messages for a given number
  * transmissions per channel.
  */
-class AnnounceSenderBase : public InstanceLocator
+class AnnounceSenderBase : public InstanceLocator, private NonCopyable
 {
 protected:
     /**
@@ -75,11 +76,8 @@
      * @param[in]  aPeriod        The time between two successive MLE Announce transmissions (in milliseconds).
      * @param[in]  aJitter        Maximum random jitter added to @aPeriod per transmission (in milliseconds).
      *
-     * @retval OT_ERROR_NONE          Successfully started the transmission process.
-     * @retval OT_ERROR_INVALID_ARGS  @p aChanelMask is empty, or @p aPeriod is zero or smaller than @aJitter.
-     *
      */
-    otError SendAnnounce(Mac::ChannelMask aChannelMask, uint8_t aCount, uint32_t aPeriod, uint16_t aJitter);
+    void SendAnnounce(Mac::ChannelMask aChannelMask, uint8_t aCount, uint32_t aPeriod, uint16_t aJitter);
 
     /**
      * This method stops the ongoing MLE Announce transmissions.
@@ -136,7 +134,7 @@
  * This class implements an AnnounceSender.
  *
  */
-class AnnounceSender : public AnnounceSenderBase
+class AnnounceSender : public AnnounceSenderBase, public Notifier::Receiver
 {
 public:
     /**
@@ -159,10 +157,8 @@
     void        CheckState(void);
     void        Stop(void);
     static void HandleTimer(Timer &aTimer);
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags);
-    void        HandleStateChanged(otChangedFlags aFlags);
-
-    Notifier::Callback mNotifierCallback;
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
 };
 
 #endif // OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
diff --git a/src/core/thread/child_mask.hpp b/src/core/thread/child_mask.hpp
new file mode 100644
index 0000000..6eedbbb
--- /dev/null
+++ b/src/core/thread/child_mask.hpp
@@ -0,0 +1,142 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for a child mask.
+ */
+
+#ifndef CHILD_MASK_HPP_
+#define CHILD_MASK_HPP_
+
+#include "openthread-core-config.h"
+
+#include <openthread/error.h>
+
+#include "common/code_utils.hpp"
+#include "common/debug.hpp"
+#include "common/encoding.hpp"
+
+namespace ot {
+
+/**
+ * @addtogroup core-child-mask
+ *
+ * @brief
+ *   This module includes definitions for OpenThread Child Mask.
+ *
+ * @{
+ *
+ */
+
+/**
+ * This class represents a bit-vector of child mask.
+ *
+ */
+class ChildMask
+{
+public:
+    /**
+     * This method returns if a given Child index is masked.
+     *
+     * @param[in] aChildIndex  The Child index.
+     *
+     * @retval TRUE   If the given Child index is set.
+     * @retval FALSE  If the given Child index is clear.
+     *
+     */
+    bool Get(uint16_t aChildIndex) const
+    {
+        OT_ASSERT(aChildIndex < OPENTHREAD_CONFIG_MLE_MAX_CHILDREN);
+        return (mMask[aChildIndex / 8] & (0x80 >> (aChildIndex % 8))) != 0;
+    }
+
+    /**
+     * This method sets the mask of a given Child index.
+     *
+     * @param[in] aChildIndex  The Child index.
+     *
+     */
+    void Set(uint16_t aChildIndex)
+    {
+        OT_ASSERT(aChildIndex < OPENTHREAD_CONFIG_MLE_MAX_CHILDREN);
+        mMask[aChildIndex / 8] |= 0x80 >> (aChildIndex % 8);
+    }
+
+    /**
+     * This method clears the mask of a given Child index.
+     *
+     * @param[in] aChildIndex  The Child index.
+     *
+     */
+    void Clear(uint16_t aChildIndex)
+    {
+        OT_ASSERT(aChildIndex < OPENTHREAD_CONFIG_MLE_MAX_CHILDREN);
+        mMask[aChildIndex / 8] &= ~(0x80 >> (aChildIndex % 8));
+    }
+
+    /**
+     * This method returns if any Child mask is set.
+     *
+     * @retval TRUE   If any Child index is set.
+     * @retval FALSE  If all Child indexes are clear.
+     *
+     */
+    bool HasAny(void) const
+    {
+        bool rval = false;
+
+        for (size_t i = 0; i < sizeof(mMask); i++)
+        {
+            if (mMask[i] != 0)
+            {
+                ExitNow(rval = true);
+            }
+        }
+
+    exit:
+        return rval;
+    }
+
+private:
+    enum
+    {
+        kChildMaskBytes = BitVectorBytes(OPENTHREAD_CONFIG_MLE_MAX_CHILDREN)
+    };
+
+    uint8_t mMask[kChildMaskBytes];
+};
+
+/**
+ * @}
+ *
+ */
+
+} // namespace ot
+
+#endif // CHILD_MASK_HPP_
diff --git a/src/core/thread/child_table.cpp b/src/core/thread/child_table.cpp
index e15281b..b859a94 100644
--- a/src/core/thread/child_table.cpp
+++ b/src/core/thread/child_table.cpp
@@ -44,29 +44,14 @@
 ChildTable::Iterator::Iterator(Instance &aInstance, Child::StateFilter aFilter)
     : InstanceLocator(aInstance)
     , mFilter(aFilter)
-    , mStart(NULL)
-    , mChild(NULL)
-{
-    Reset();
-}
-
-ChildTable::Iterator::Iterator(Instance &aInstance, Child::StateFilter aFilter, Child *aStartingChild)
-    : InstanceLocator(aInstance)
-    , mFilter(aFilter)
-    , mStart(aStartingChild)
-    , mChild(NULL)
+    , mChild(nullptr)
 {
     Reset();
 }
 
 void ChildTable::Iterator::Reset(void)
 {
-    if (mStart == NULL)
-    {
-        mStart = &Get<ChildTable>().mChildren[0];
-    }
-
-    mChild = mStart;
+    mChild = &Get<ChildTable>().mChildren[0];
 
     if (!mChild->MatchesFilter(mFilter))
     {
@@ -76,22 +61,12 @@
 
 void ChildTable::Iterator::Advance(void)
 {
-    ChildTable &childTable = Get<ChildTable>();
-    Child *     listStart  = &childTable.mChildren[0];
-    Child *     listEnd    = &childTable.mChildren[childTable.mMaxChildrenAllowed];
-
-    VerifyOrExit(mChild != NULL);
+    VerifyOrExit(mChild != nullptr, OT_NOOP);
 
     do
     {
         mChild++;
-
-        if (mChild >= listEnd)
-        {
-            mChild = listStart;
-        }
-
-        VerifyOrExit(mChild != mStart, mChild = NULL);
+        VerifyOrExit(mChild < &Get<ChildTable>().mChildren[Get<ChildTable>().mMaxChildrenAllowed], mChild = nullptr);
     } while (!mChild->MatchesFilter(mFilter));
 
 exit:
@@ -102,7 +77,11 @@
     : InstanceLocator(aInstance)
     , mMaxChildrenAllowed(kMaxChildren)
 {
-    Clear();
+    for (Child *child = &mChildren[0]; child < OT_ARRAY_END(mChildren); child++)
+    {
+        child->Init(aInstance);
+        child->Clear();
+    }
 }
 
 void ChildTable::Clear(void)
@@ -115,9 +94,9 @@
 
 Child *ChildTable::GetChildAtIndex(uint16_t aChildIndex)
 {
-    Child *child = NULL;
+    Child *child = nullptr;
 
-    VerifyOrExit(aChildIndex < mMaxChildrenAllowed);
+    VerifyOrExit(aChildIndex < mMaxChildrenAllowed, OT_NOOP);
     child = &mChildren[aChildIndex];
 
 exit:
@@ -137,7 +116,7 @@
         }
     }
 
-    child = NULL;
+    child = nullptr;
 
 exit:
     return child;
@@ -155,7 +134,7 @@
         }
     }
 
-    child = NULL;
+    child = nullptr;
 
 exit:
     return child;
@@ -173,7 +152,7 @@
         }
     }
 
-    child = NULL;
+    child = nullptr;
 
 exit:
     return child;
@@ -181,7 +160,7 @@
 
 Child *ChildTable::FindChild(const Mac::Address &aAddress, Child::StateFilter aFilter)
 {
-    Child *child = NULL;
+    Child *child = nullptr;
 
     switch (aAddress.GetType())
     {
diff --git a/src/core/thread/child_table.hpp b/src/core/thread/child_table.hpp
index c091979..8730037 100644
--- a/src/core/thread/child_table.hpp
+++ b/src/core/thread/child_table.hpp
@@ -36,19 +36,21 @@
 
 #include "openthread-core-config.h"
 
+#if OPENTHREAD_FTD
+
 #include "common/locator.hpp"
 #include "thread/topology.hpp"
 
 namespace ot {
 
-#if OPENTHREAD_FTD
-
 /**
  * This class represents the Thread child table.
  *
  */
 class ChildTable : public InstanceLocator
 {
+    class IteratorBuilder;
+
 public:
     /**
      * This class represents an iterator for iterating through the child entries in the child table.
@@ -56,9 +58,11 @@
      */
     class Iterator : public InstanceLocator
     {
+        friend class IteratorBuilder;
+
     public:
         /**
-         * This constructor initializes an `Iterator` instance to start from beginning of the child table.
+         * This constructor initializes an `Iterator` instance.
          *
          * @param[in] aInstance  A reference to the OpenThread instance.
          * @param[in] aFilter    A child state filter.
@@ -67,22 +71,6 @@
         Iterator(Instance &aInstance, Child::StateFilter aFilter);
 
         /**
-         * This constructor initializes an `Iterator` instance to start from a given child.
-         *
-         * This constructor allows the iterator to start from a given `Child` entry. The iterator will start from the
-         * given child and will go through all entries in the child table (matching the filter) till it gets back to
-         * the starting `Child` entry.
-         *
-         * If the given starting `Child` pointer is `NULL`, then the iterator starts from beginning of the child table.
-         *
-         * @param[in] aInstance        A reference to the OpenThread instance.
-         * @param[in] aFilter          A child state filter.
-         * @param[in] aStartingChild   A pointer to a child. If non-NULL, the iterator starts from the given entry.
-         *
-         */
-        Iterator(Instance &aInstance, Child::StateFilter aFilter, Child *aStartingChild);
-
-        /**
          * This method resets the iterator to start over.
          *
          */
@@ -96,24 +84,14 @@
          * @retval FALSE  The current entry is valid.
          *
          */
-        bool IsDone(void) const { return (mChild == NULL); }
-
-        /**
-         * This method advances the iterator.
-         *
-         * The iterator is moved to point to the next `Child` entry matching the given state filter in the constructor.
-         * If there are no more `Child` entries matching the given filter, the iterator becomes empty (i.e.,
-         * `GetChild()` returns `NULL` and `IsDone()` returns `true`).
-         *
-         */
-        void Advance(void);
+        bool IsDone(void) const { return (mChild == nullptr); }
 
         /**
          * This method overloads `++` operator (pre-increment) to advance the iterator.
          *
          * The iterator is moved to point to the next `Child` entry matching the given state filter in the constructor.
          * If there are no more `Child` entries matching the given filter, the iterator becomes empty (i.e.,
-         * `GetChild()` returns `NULL` and `IsDone()` returns `true`).
+         * `GetChild()` returns `nullptr` and `IsDone()` returns `true`).
          *
          */
         void operator++(void) { Advance(); }
@@ -123,7 +101,7 @@
          *
          * The iterator is moved to point to the next `Child` entry matching the given state filter in the constructor.
          * If there are no more `Child` entries matching the given filter, the iterator becomes empty (i.e.,
-         * `GetChild()` returns `NULL` and `IsDone()` returns `true`).
+         * `GetChild()` returns `nullptr` and `IsDone()` returns `true`).
          *
          */
         void operator++(int) { Advance(); }
@@ -131,14 +109,66 @@
         /**
          * This method gets the `Child` entry to which the iterator is currently pointing.
          *
-         * @returns A pointer to the `Child` entry, or `NULL` if the iterator is done and/or empty.
+         * @returns A pointer to the `Child` entry, or `nullptr` if the iterator is done and/or empty.
          *
          */
         Child *GetChild(void) { return mChild; }
 
+        /**
+         * This method overloads the `*` dereference operator and gets a reference to `Child` entry to which the
+         * iterator is currently pointing.
+         *
+         * This method MUST be used when the iterator is not empty/finished (i.e., `IsDone()` returns `false`).
+         *
+         * @returns A reference to the `Child` entry currently pointed by the iterator.
+         *
+         */
+        Child &operator*(void) { return *mChild; }
+
+        /**
+         * This method overloads the `->` dereference operator and gets a pointer to `Child` entry to which the iterator
+         * is currently pointing.
+         *
+         * @returns A pointer to the `Child` entry associated with the iterator, or `nullptr` if iterator is empty/done.
+         *
+         */
+        Child *operator->(void) { return mChild; }
+
+        /**
+         * This method overloads operator `==` to evaluate whether or not two `Iterator` instances point to the same
+         * child entry.
+         *
+         * @param[in]  aOther  The other `Iterator` to compare with.
+         *
+         * @retval TRUE   If the two `Iterator` objects point to the same child entry or both are done.
+         * @retval FALSE  If the two `Iterator` objects do not point to the same child entry.
+         *
+         */
+        bool operator==(const Iterator &aOther) const { return mChild == aOther.mChild; }
+
+        /**
+         * This method overloads operator `!=` to evaluate whether or not two `Iterator` instances point to the same
+         * child entry.
+         *
+         * @param[in]  aOther  The other `Iterator` to compare with.
+         *
+         * @retval TRUE   If the two `Iterator` objects do not point to the same child entry.
+         * @retval FALSE  If the two `Iterator` objects point to the same child entry or both are done.
+         *
+         */
+        bool operator!=(const Iterator &aOther) const { return mChild != aOther.mChild; }
+
     private:
+        Iterator(Instance &aInstance)
+            : InstanceLocator(aInstance)
+            , mFilter(Child::StateFilter::kInStateValid)
+            , mChild(nullptr)
+        {
+        }
+
+        void Advance(void);
+
         Child::StateFilter mFilter;
-        Child *            mStart;
         Child *            mChild;
     };
 
@@ -167,12 +197,12 @@
     uint16_t GetChildIndex(const Child &aChild) const { return static_cast<uint16_t>(&aChild - mChildren); }
 
     /**
-     * This method returns a pointer to a `Child` entry at a given index, or `NULL` if the index is out of bounds,
+     * This method returns a pointer to a `Child` entry at a given index, or `nullptr` if the index is out of bounds,
      * i.e., index is larger or equal to maximum number of children allowed (@sa GetMaxChildrenAllowed()).
      *
      * @param[in]  aChildIndex  A child index.
      *
-     * @returns A pointer to the `Child` corresponding to the given index, or `NULL` if the index is out of bounds.
+     * @returns A pointer to the `Child` corresponding to the given index, or `nullptr` if the index is out of bounds.
      *
      */
     Child *GetChildAtIndex(uint16_t aChildIndex);
@@ -182,7 +212,7 @@
      *
      * @note The returned child entry will be cleared (`memset` to zero).
      *
-     * @returns A pointer to a new `Child` entry, or `NULL` if all `Child` entries are in use.
+     * @returns A pointer to a new `Child` entry, or `nullptr` if all `Child` entries are in use.
      *
      */
     Child *GetNewChild(void);
@@ -193,7 +223,7 @@
      * @param[in]  aRloc16  A RLOC16 address.
      * @param[in]  aFilter  A child state filter.
      *
-     * @returns  A pointer to the `Child` entry if one is found, or `NULL` otherwise.
+     * @returns  A pointer to the `Child` entry if one is found, or `nullptr` otherwise.
      *
      */
     Child *FindChild(uint16_t aRloc16, Child::StateFilter aFilter);
@@ -205,7 +235,7 @@
      * @param[in]  aAddress A reference to an extended address.
      * @param[in]  aFilter  A child state filter.
      *
-     * @returns  A pointer to the `Child` entry if one is found, or `NULL` otherwise.
+     * @returns  A pointer to the `Child` entry if one is found, or `nullptr` otherwise.
      *
      */
     Child *FindChild(const Mac::ExtAddress &aAddress, Child::StateFilter aFilter);
@@ -216,7 +246,7 @@
      * @param[in]  aAddress A reference to a MAC address.
      * @param[in]  aFilter  A child state filter.
      *
-     * @returns  A pointer to the `Child` entry if one is found, or `NULL` otherwise.
+     * @returns  A pointer to the `Child` entry if one is found, or `nullptr` otherwise.
      *
      */
     Child *FindChild(const Mac::Address &aAddress, Child::StateFilter aFilter);
@@ -275,60 +305,49 @@
      */
     otError SetMaxChildrenAllowed(uint16_t aMaxChildren);
 
+    /**
+     * This method enables range-based `for` loop iteration over all child entries in the child table matching a given
+     * state filter.
+     *
+     * This method should be used as follows:
+     *
+     *     for (Child &child : aChildTable.Iterate(aFilter)) { ... }
+     *
+     * @param[in] aFilter  A child state filter.
+     *
+     * @returns An IteratorBuilder instance.
+     *
+     */
+    IteratorBuilder Iterate(Child::StateFilter aFilter) { return IteratorBuilder(GetInstance(), aFilter); }
+
 private:
     enum
     {
         kMaxChildren = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN,
     };
 
+    class IteratorBuilder : public InstanceLocator
+    {
+    public:
+        IteratorBuilder(Instance &aInstance, Child::StateFilter aFilter)
+            : InstanceLocator(aInstance)
+            , mFilter(aFilter)
+        {
+        }
+
+        Iterator begin(void) { return Iterator(GetInstance(), mFilter); }
+        Iterator end(void) { return Iterator(GetInstance()); }
+
+    private:
+        Child::StateFilter mFilter;
+    };
+
     uint16_t mMaxChildrenAllowed;
     Child    mChildren[kMaxChildren];
 };
 
-#endif // OPENTHREAD_FTD
-
-#if OPENTHREAD_MTD
-
-class ChildTable : public InstanceLocator
-{
-public:
-    class Iterator
-    {
-    public:
-        Iterator(Instance &, Child::StateFilter) {}
-        Iterator(Instance &, Child::StateFilter, Child *) {}
-        void   Reset(void) {}
-        bool   IsDone(void) const { return true; }
-        void   Advance(void) {}
-        void   operator++(void) {}
-        void   operator++(int) {}
-        Child *GetChild(void) { return NULL; }
-    };
-
-    explicit ChildTable(Instance &aInstance)
-        : InstanceLocator(aInstance)
-    {
-    }
-    void Clear(void) {}
-
-    uint16_t GetChildIndex(const Child &) const { return 0; }
-    Child *  GetChildAtIndex(uint16_t) { return NULL; }
-
-    Child *GetNewChild(void) { return NULL; }
-
-    Child *FindChild(uint16_t, Child::StateFilter) { return NULL; }
-    Child *FindChild(const Mac::ExtAddress &, Child::StateFilter) { return NULL; }
-    Child *FindChild(const Mac::Address &, Child::StateFilter) { return NULL; }
-
-    bool     HasChildren(Child::StateFilter) const { return false; }
-    uint16_t GetNumChildren(Child::StateFilter) const { return 0; }
-    uint16_t GetMaxChildren(void) const { return 0; }
-    uint16_t GetMaxChildrenAllowed(void) const { return 0; }
-    otError  SetMaxChildrenAllowed(uint16_t) { return OT_ERROR_INVALID_STATE; }
-};
-
-#endif // OPENTHREAD_MTD
-
 } // namespace ot
 
+#endif // OPENTHREAD_FTD
+
 #endif // CHILD_TABLE_HPP_
diff --git a/src/core/thread/device_mode.cpp b/src/core/thread/device_mode.cpp
deleted file mode 100644
index 0972a54..0000000
--- a/src/core/thread/device_mode.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements of MLE device mode.
- */
-
-#include "device_mode.hpp"
-
-#include "common/code_utils.hpp"
-
-namespace ot {
-namespace Mle {
-
-void DeviceMode::Get(ModeConfig &aModeConfig) const
-{
-    aModeConfig.mRxOnWhenIdle       = IsRxOnWhenIdle();
-    aModeConfig.mSecureDataRequests = IsSecureDataRequest();
-    aModeConfig.mDeviceType         = IsFullThreadDevice();
-    aModeConfig.mNetworkData        = IsFullNetworkData();
-}
-
-void DeviceMode::Set(const ModeConfig &aModeConfig)
-{
-    mMode = 0;
-    mMode |= aModeConfig.mRxOnWhenIdle ? kModeRxOnWhenIdle : 0;
-    mMode |= aModeConfig.mSecureDataRequests ? kModeSecureDataRequest : 0;
-    mMode |= aModeConfig.mDeviceType ? kModeFullThreadDevice : 0;
-    mMode |= aModeConfig.mNetworkData ? kModeFullNetworkData : 0;
-}
-
-DeviceMode::InfoString DeviceMode::ToString(void) const
-{
-    return InfoString("rx-on:%s sec-poll:%s ftd:%s full-net:%s", IsRxOnWhenIdle() ? "yes" : "no",
-                      IsSecureDataRequest() ? "yes" : "no", IsFullThreadDevice() ? "yes" : "no",
-                      IsFullNetworkData() ? "yes" : "no");
-}
-
-} // namespace Mle
-} // namespace ot
diff --git a/src/core/thread/device_mode.hpp b/src/core/thread/device_mode.hpp
deleted file mode 100644
index 32507ac..0000000
--- a/src/core/thread/device_mode.hpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes definitions for MLE device mode.
- */
-
-#ifndef DEVICE_MODE_HPP_
-#define DEVICE_MODE_HPP_
-
-#include "openthread-core-config.h"
-
-#include <stdint.h>
-
-#include <openthread/thread.h>
-
-#include "common/string.hpp"
-
-namespace ot {
-namespace Mle {
-
-/**
- * @addtogroup core-mle-core
- *
- * @brief
- *   This module includes definition for MLE device mode.
- *
- * @{
- *
- */
-
-/**
- * This type represents a MLE device mode.
- *
- */
-class DeviceMode
-{
-public:
-    enum
-    {
-        kModeRxOnWhenIdle      = 1 << 3, ///< If the device has its receiver on when not transmitting.
-        kModeSecureDataRequest = 1 << 2, ///< If the device uses link layer security for all data requests.
-        kModeFullThreadDevice  = 1 << 1, ///< If the device is an FTD.
-        kModeFullNetworkData   = 1 << 0, ///< If the device requires the full Network Data.
-
-        kInfoStringSize = 45, ///< String buffer size used for `ToString()`.
-    };
-
-    /**
-     * This type defines the fixed-length `String` object returned from `ToString()`.
-     *
-     */
-    typedef String<kInfoStringSize> InfoString;
-
-    /**
-     *  This structure represents an MLE Mode configuration.
-     *
-     */
-    typedef otLinkModeConfig ModeConfig;
-
-    /**
-     * This is the default constructor for `DeviceMode` object.
-     *
-     */
-    DeviceMode(void) {}
-
-    /**
-     * This constructor initializes a `DeviceMode` object from a given mode TLV bitmask.
-     *
-     * @param[in] aMode   A mode TLV bitmask to initialize the `DeviceMode` object.
-     *
-     */
-    explicit DeviceMode(uint8_t aMode)
-        : mMode(aMode)
-    {
-    }
-
-    /**
-     * This constructor initializes a `DeviceMode` object from a given mode configuration structure.
-     *
-     * @param[in] aModeConfig   A mode configuration to initialize the `DeviceMode` object.
-     *
-     */
-    explicit DeviceMode(ModeConfig aModeConfig) { Set(aModeConfig); }
-
-    /**
-     * This method gets the device mode as a mode TLV bitmask.
-     *
-     * @returns The device mode as a mode TLV bitmask.
-     *
-     */
-    uint8_t Get(void) const { return mMode; }
-
-    /**
-     * This method sets the device mode from a given mode TLV bitmask.
-     *
-     * @param[in] aMode   A mode TLV bitmask.
-     *
-     */
-    void Set(uint8_t aMode) { mMode = aMode; }
-
-    /**
-     * This method gets the device mode as a mode configuration structure.
-     *
-     * @param[out] aModeConfig   A reference to a mode configuration structure to output the device mode.
-     *
-     */
-    void Get(ModeConfig &aModeConfig) const;
-
-    /**
-     * this method sets the device mode from a given mode configuration structure.
-     *
-     * @param[in] aModeConfig   A mode configuration structure.
-     *
-     */
-    void Set(const ModeConfig &aModeConfig);
-
-    /**
-     * This method indicates whether or not the device is rx-on-when-idle.
-     *
-     * @retval TRUE   If the device is rx-on-when-idle (non-sleepy).
-     * @retval FALSE  If the device is not rx-on-when-idle (sleepy).
-     *
-     */
-    bool IsRxOnWhenIdle(void) const { return (mMode & kModeRxOnWhenIdle) != 0; }
-
-    /**
-     * This method indicates whether or not the device uses secure IEEE 802.15.4 Data Request messages.
-     *
-     * @retval TRUE   If the device uses secure IEEE 802.15.4 Data Request (data poll) messages.
-     * @retval FALSE  If the device uses any IEEE 802.15.4 Data Request (data poll) messages.
-     *
-     */
-    bool IsSecureDataRequest(void) const { return (mMode & kModeSecureDataRequest) != 0; }
-
-    /**
-     * This method indicates whether or not the device is a Full Thread Device.
-     *
-     * @retval TRUE   If the device is Full Thread Device.
-     * @retval FALSE  If the device if not Full Thread Device.
-     *
-     */
-    bool IsFullThreadDevice(void) const { return (mMode & kModeFullThreadDevice) != 0; }
-
-    /**
-     * This method indicates whether or not the device requests Full Network Data.
-     *
-     * @retval TRUE   If the device requests Full Network Data.
-     * @retval FALSE  If the device does not request Full Network Data (only stable Network Data).
-     *
-     */
-    bool IsFullNetworkData(void) const { return (mMode & kModeFullNetworkData) != 0; }
-
-    /**
-     * This method indicates whether or not the device is a Minimal End Device.
-     *
-     * @retval TRUE   If the device is a Minimal End Device.
-     * @retval FALSE  If the device is not a Minimal End Device.
-     *
-     */
-    bool IsMinimalEndDevice(void) const
-    {
-        return (mMode & (kModeFullThreadDevice | kModeRxOnWhenIdle)) != (kModeFullThreadDevice | kModeRxOnWhenIdle);
-    }
-
-    /**
-     * This method indicates whether or not the device mode flags are valid.
-     *
-     * An FTD which is not rx-on-when-idle (is sleepy) is considered invalid.
-     *
-     * @returns TRUE if , FALSE otherwise.
-     * @retval TRUE   If the device mode flags are valid.
-     * @retval FALSE  If the device mode flags are not valid.
-     *
-     */
-    bool IsValid(void) const { return !IsFullThreadDevice() || IsRxOnWhenIdle(); }
-
-    /**
-     *  This method overloads operator `==` to evaluate whether or not two device modes are equal
-     *
-     * @param[in]  aOther  The other device mode to compare with.
-     *
-     * @retval TRUE   If the device modes are equal.
-     * @retval FALSE  If the device modes are not equal.
-     *
-     */
-    bool operator==(const DeviceMode &aOther) const { return (mMode == aOther.mMode); }
-
-    /**
-     * This method overloads operator `!=` to evaluate whether or not two device modes are not equal.
-     *
-     * @param[in]  aOther  The other device mode to compare with.
-     *
-     * @retval TRUE   If the device modes are not equal.
-     * @retval FALSE  If the device modes are equal.
-     *
-     */
-    bool operator!=(const DeviceMode &aOther) const { return !(*this == aOther); }
-
-    /**
-     * This method converts the device mode into a human-readable string.
-     *
-     * @returns An `InfoString` object representing the device mode.
-     *
-     */
-    InfoString ToString(void) const;
-
-private:
-    uint8_t mMode;
-};
-
-/**
- * @}
- *
- */
-
-} // namespace Mle
-} // namespace ot
-
-#endif // DEVICE_MODE_HPP_
diff --git a/src/core/thread/discover_scanner.cpp b/src/core/thread/discover_scanner.cpp
new file mode 100644
index 0000000..31fbf4e
--- /dev/null
+++ b/src/core/thread/discover_scanner.cpp
@@ -0,0 +1,359 @@
+/*
+ *  Copyright (c) 2016-2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements MLE Discover Scan process.
+ */
+
+#include "discover_scanner.hpp"
+
+#include "common/code_utils.hpp"
+#include "common/instance.hpp"
+#include "common/locator-getters.hpp"
+#include "common/logging.hpp"
+#include "thread/mesh_forwarder.hpp"
+#include "thread/mle.hpp"
+#include "thread/mle_router.hpp"
+
+namespace ot {
+namespace Mle {
+
+DiscoverScanner::DiscoverScanner(Instance &aInstance)
+    : InstanceLocator(aInstance)
+    , mHandler(nullptr)
+    , mHandlerContext(nullptr)
+    , mTimer(aInstance, DiscoverScanner::HandleTimer, this)
+    , mFilterIndexes()
+    , mScanChannels()
+    , mState(kStateIdle)
+    , mScanChannel(0)
+    , mEnableFiltering(false)
+    , mShouldRestorePanId(false)
+{
+}
+
+otError DiscoverScanner::Discover(const Mac::ChannelMask &aScanChannels,
+                                  uint16_t                aPanId,
+                                  bool                    aJoiner,
+                                  bool                    aEnableFiltering,
+                                  const FilterIndexes *   aFilterIndexes,
+                                  Handler                 aCallback,
+                                  void *                  aContext)
+{
+    otError                      error   = OT_ERROR_NONE;
+    Message *                    message = nullptr;
+    Ip6::Address                 destination;
+    MeshCoP::DiscoveryRequestTlv discoveryRequest;
+
+    VerifyOrExit(mState == kStateIdle, error = OT_ERROR_BUSY);
+
+    mEnableFiltering = aEnableFiltering;
+
+    if (mEnableFiltering)
+    {
+        if (aFilterIndexes == nullptr)
+        {
+            Mac::ExtAddress extAddress;
+
+            Get<Radio>().GetIeeeEui64(extAddress);
+            MeshCoP::ComputeJoinerId(extAddress, extAddress);
+            MeshCoP::SteeringData::CalculateHashBitIndexes(extAddress, mFilterIndexes);
+        }
+        else
+        {
+            mFilterIndexes = *aFilterIndexes;
+        }
+    }
+
+    mHandler            = aCallback;
+    mHandlerContext     = aContext;
+    mShouldRestorePanId = false;
+    mScanChannels       = Get<Mac::Mac>().GetSupportedChannelMask();
+
+    if (!aScanChannels.IsEmpty())
+    {
+        mScanChannels.Intersect(aScanChannels);
+    }
+
+    VerifyOrExit((message = Get<Mle>().NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
+    message->SetSubType(Message::kSubTypeMleDiscoverRequest);
+    message->SetPanId(aPanId);
+    SuccessOrExit(error = Get<Mle>().AppendHeader(*message, Header::kCommandDiscoveryRequest));
+
+    // Append MLE Discovery TLV with a single sub-TLV (MeshCoP Discovery Request).
+    discoveryRequest.Init();
+    discoveryRequest.SetVersion(kThreadVersion);
+    discoveryRequest.SetJoiner(aJoiner);
+
+    SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kDiscovery, &discoveryRequest, sizeof(discoveryRequest)));
+
+    destination.SetToLinkLocalAllRoutersMulticast();
+
+    SuccessOrExit(error = Get<Mle>().SendMessage(*message, destination));
+
+    if ((aPanId == Mac::kPanIdBroadcast) && (Get<Mac::Mac>().GetPanId() == Mac::kPanIdBroadcast))
+    {
+        // In case a specific PAN ID of a Thread Network to be
+        // discovered is not known, Discovery Request messages MUST
+        // have the Destination PAN ID in the IEEE 802.15.4 MAC
+        // header set to be the Broadcast PAN ID (0xffff) and the
+        // Source PAN ID set to a randomly generated value.
+
+        Get<Mac::Mac>().SetPanId(Mac::GenerateRandomPanId());
+        mShouldRestorePanId = true;
+    }
+
+    mScanChannel = Mac::ChannelMask::kChannelIteratorFirst;
+    mState       = (mScanChannels.GetNextChannel(mScanChannel) == OT_ERROR_NONE) ? kStateScanning : kStateScanDone;
+
+    otLogInfoMle("Send Discovery Request (%s)", destination.ToString().AsCString());
+
+exit:
+
+    if (error != OT_ERROR_NONE && message != nullptr)
+    {
+        message->Free();
+    }
+
+    return error;
+}
+
+otError DiscoverScanner::PrepareDiscoveryRequestFrame(Mac::TxFrame &aFrame)
+{
+    otError error = OT_ERROR_NONE;
+
+    switch (mState)
+    {
+    case kStateIdle:
+    case kStateScanDone:
+        // If scan is finished (no more channels to scan), abort the
+        // Discovery Request frame tx. The handler callback is invoked &
+        // state is cleared from `HandleDiscoveryRequestFrameTxDone()`.
+        error = OT_ERROR_ABORT;
+        break;
+
+    case kStateScanning:
+        aFrame.SetChannel(mScanChannel);
+        IgnoreError(Get<Mac::Mac>().SetTemporaryChannel(mScanChannel));
+        break;
+    }
+
+    return error;
+}
+
+void DiscoverScanner::HandleDiscoveryRequestFrameTxDone(Message &aMessage)
+{
+    switch (mState)
+    {
+    case kStateIdle:
+        break;
+
+    case kStateScanning:
+        // Mark the Discovery Request message for direct tx to ensure it
+        // is not dequeued and freed by `MeshForwarder` and is ready for
+        // the next scan channel. Also pause message tx on `MeshForwarder`
+        // while listening to receive Discovery Responses.
+        aMessage.SetDirectTransmission();
+        Get<MeshForwarder>().PauseMessageTransmissions();
+        mTimer.Start(kDefaultScanDuration);
+        break;
+
+    case kStateScanDone:
+        HandleDiscoverComplete();
+        break;
+    }
+}
+
+void DiscoverScanner::HandleDiscoverComplete(void)
+{
+    switch (mState)
+    {
+    case kStateIdle:
+        break;
+
+    case kStateScanning:
+        mTimer.Stop();
+        Get<MeshForwarder>().ResumeMessageTransmissions();
+
+        // Fall through
+
+    case kStateScanDone:
+        Get<Mac::Mac>().ClearTemporaryChannel();
+
+        if (mShouldRestorePanId)
+        {
+            Get<Mac::Mac>().SetPanId(Mac::kPanIdBroadcast);
+            mShouldRestorePanId = false;
+        }
+
+        mState = kStateIdle;
+
+        if (mHandler)
+        {
+            mHandler(nullptr, mHandlerContext);
+        }
+
+        break;
+    }
+}
+
+void DiscoverScanner::HandleTimer(Timer &aTimer)
+{
+    aTimer.GetOwner<DiscoverScanner>().HandleTimer();
+}
+
+void DiscoverScanner::HandleTimer(void)
+{
+    VerifyOrExit(mState == kStateScanning, OT_NOOP);
+
+    // Move to next scan channel and resume message transmissions on
+    // `MeshForwarder` so that the queued MLE Discovery Request message
+    // is prepared again for the next scan channel. If no more channel
+    // to scan, change the state to `kStateScanDone` which ensures the
+    // frame tx is aborted  from `PrepareDiscoveryRequestFrame()` and
+    // then wraps up the scan (invoking handler callback).
+
+    if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE)
+    {
+        mState = kStateScanDone;
+    }
+
+    Get<MeshForwarder>().ResumeMessageTransmissions();
+
+exit:
+    return;
+}
+
+void DiscoverScanner::HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const
+{
+    otError                       error    = OT_ERROR_NONE;
+    const otThreadLinkInfo *      linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
+    Tlv                           tlv;
+    MeshCoP::Tlv                  meshcopTlv;
+    MeshCoP::DiscoveryResponseTlv discoveryResponse;
+    MeshCoP::NetworkNameTlv       networkName;
+    ScanResult                    result;
+    uint16_t                      offset;
+    uint16_t                      end;
+    bool                          didCheckSteeringData = false;
+
+    otLogInfoMle("Receive Discovery Response (%s)", aMessageInfo.GetPeerAddr().ToString().AsCString());
+
+    VerifyOrExit(mState == kStateScanning, error = OT_ERROR_DROP);
+
+    // Find MLE Discovery TLV
+    VerifyOrExit(Tlv::FindTlvOffset(aMessage, Tlv::kDiscovery, offset) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
+    aMessage.Read(offset, sizeof(tlv), &tlv);
+
+    offset += sizeof(tlv);
+    end = offset + tlv.GetLength();
+
+    memset(&result, 0, sizeof(result));
+    result.mPanId   = linkInfo->mPanId;
+    result.mChannel = linkInfo->mChannel;
+    result.mRssi    = linkInfo->mRss;
+    result.mLqi     = linkInfo->mLqi;
+
+    aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(static_cast<Mac::ExtAddress &>(result.mExtAddress));
+
+    // Process MeshCoP TLVs
+    while (offset < end)
+    {
+        aMessage.Read(offset, sizeof(meshcopTlv), &meshcopTlv);
+
+        switch (meshcopTlv.GetType())
+        {
+        case MeshCoP::Tlv::kDiscoveryResponse:
+            aMessage.Read(offset, sizeof(discoveryResponse), &discoveryResponse);
+            VerifyOrExit(discoveryResponse.IsValid(), error = OT_ERROR_PARSE);
+            result.mVersion  = discoveryResponse.GetVersion();
+            result.mIsNative = discoveryResponse.IsNativeCommissioner();
+            break;
+
+        case MeshCoP::Tlv::kExtendedPanId:
+            SuccessOrExit(error = Tlv::ReadTlv(aMessage, offset, &result.mExtendedPanId, sizeof(Mac::ExtendedPanId)));
+            break;
+
+        case MeshCoP::Tlv::kNetworkName:
+            aMessage.Read(offset, sizeof(networkName), &networkName);
+            IgnoreError(static_cast<Mac::NetworkName &>(result.mNetworkName).Set(networkName.GetNetworkName()));
+            break;
+
+        case MeshCoP::Tlv::kSteeringData:
+            if (meshcopTlv.GetLength() > 0)
+            {
+                MeshCoP::SteeringData &steeringData = static_cast<MeshCoP::SteeringData &>(result.mSteeringData);
+                uint8_t                dataLength   = MeshCoP::SteeringData::kMaxLength;
+
+                if (meshcopTlv.GetLength() < dataLength)
+                {
+                    dataLength = meshcopTlv.GetLength();
+                }
+
+                steeringData.Init(dataLength);
+
+                SuccessOrExit(error = Tlv::ReadTlv(aMessage, offset, steeringData.GetData(), dataLength));
+
+                if (mEnableFiltering)
+                {
+                    VerifyOrExit(steeringData.Contains(mFilterIndexes), OT_NOOP);
+                }
+
+                didCheckSteeringData = true;
+            }
+            break;
+
+        case MeshCoP::Tlv::kJoinerUdpPort:
+            SuccessOrExit(error = Tlv::ReadUint16Tlv(aMessage, offset, result.mJoinerUdpPort));
+            break;
+
+        default:
+            break;
+        }
+
+        offset += sizeof(meshcopTlv) + meshcopTlv.GetLength();
+    }
+
+    VerifyOrExit(!mEnableFiltering || didCheckSteeringData, OT_NOOP);
+
+    if (mHandler)
+    {
+        mHandler(&result, mHandlerContext);
+    }
+
+exit:
+
+    if (error != OT_ERROR_NONE)
+    {
+        otLogWarnMle("Failed to process Discovery Response: %s", otThreadErrorToString(error));
+    }
+}
+
+} // namespace Mle
+} // namespace ot
diff --git a/src/core/thread/discover_scanner.hpp b/src/core/thread/discover_scanner.hpp
new file mode 100644
index 0000000..562978a
--- /dev/null
+++ b/src/core/thread/discover_scanner.hpp
@@ -0,0 +1,171 @@
+/*
+ *  Copyright (c) 2016-2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for MLE Discover Scan process.
+ */
+
+#ifndef DISCOVER_SCANNER_HPP_
+#define DISCOVER_SCANNER_HPP_
+
+#include "openthread-core-config.h"
+
+#include "common/locator.hpp"
+#include "common/timer.hpp"
+#include "mac/channel_mask.hpp"
+#include "mac/mac.hpp"
+#include "mac/mac_types.hpp"
+#include "meshcop/meshcop.hpp"
+#include "thread/mle.hpp"
+
+namespace ot {
+
+class MeshForwarder;
+
+namespace Mle {
+
+/**
+ * This class implements MLE Discover Scan.
+ *
+ */
+class DiscoverScanner : public InstanceLocator
+{
+    friend class ot::Instance;
+    friend class ot::MeshForwarder;
+    friend class Mle;
+
+public:
+    enum
+    {
+        kDefaultScanDuration = Mac::kScanDurationDefault, ///< Default scan duration (per channel), in milliseconds.
+    };
+
+    /**
+     * This type represents Discover Scan result.
+     *
+     */
+    typedef otActiveScanResult ScanResult;
+
+    /**
+     * This type represents the handler function pointer called with any Discover Scan result or when the scan
+     * completes.
+     *
+     * The handler function format is `void (*oHandler)(ScanResult *aResult, void *aContext);`. End of scan is
+     * indicated by `aResult` pointer being set to nullptr.
+     *
+     */
+    typedef otHandleActiveScanResult Handler;
+
+    /**
+     * This type represents the filter indexes, i.e., hash bit index values for the bloom filter (calculated from a
+     * Joiner ID).
+     *
+     * This is used when filtering is enabled during Discover Scan, i.e., received MLE Discovery Responses with steering
+     * data (bloom filter) not containing the given indexes are filtered.
+     *
+     */
+    typedef MeshCoP::SteeringData::HashBitIndexes FilterIndexes;
+
+    /**
+     * This constructor initializes the object.
+     *
+     * @param[in]  aInstance     A reference to the OpenThread instance.
+     *
+     */
+    explicit DiscoverScanner(Instance &aInstance);
+
+    /**
+     * This method starts a Thread Discovery Scan.
+     *
+     * @param[in]  aScanChannels      Channel mask listing channels to scan (if empty, use all supported channels).
+     * @param[in]  aPanId             The PAN ID filter (set to Broadcast PAN to disable filter).
+     * @param[in]  aJoiner            Value of the Joiner Flag in the Discovery Request TLV.
+     * @param[in]  aEnableFiltering   Enable filtering MLE Discovery Responses with steering data not containing a
+     *                                given filter indexes.
+     * @param[in]  aFilterIndexes     A pointer to `FilterIndexes` to use for filtering (when enabled).
+     *                                If set to nullptr, filter indexes are derived from hash of factory-assigned EUI64.
+     * @param[in]  aHandler           A pointer to a function that is called on receiving an MLE Discovery Response.
+     * @param[in]  aContext           A pointer to arbitrary context information.
+     *
+     * @retval OT_ERROR_NONE       Successfully started a Thread Discovery Scan.
+     * @retval OT_ERROR_NO_BUFS    Could not allocate message for Discovery Request.
+     * @retval OT_ERROR_BUSY       Thread Discovery Scan is already in progress.
+     *
+     */
+    otError Discover(const Mac::ChannelMask &aScanChannels,
+                     Mac::PanId              aPanId,
+                     bool                    aJoiner,
+                     bool                    aEnableFiltering,
+                     const FilterIndexes *   aFilterIndexes,
+                     Handler                 aHandler,
+                     void *                  aContext);
+
+    /**
+     * This method indicates whether or not an MLE Thread Discovery Scan is currently in progress.
+     *
+     * @returns true if an MLE Thread Discovery Scan is in progress, false otherwise.
+     *
+     */
+    bool IsInProgress(void) const { return (mState != kStateIdle); }
+
+private:
+    enum State
+    {
+        kStateIdle,
+        kStateScanning,
+        kStateScanDone,
+    };
+
+    // Methods used by `MeshForwarder`
+    otError PrepareDiscoveryRequestFrame(Mac::TxFrame &aFrame);
+    void    HandleDiscoveryRequestFrameTxDone(Message &aMessage);
+    void    Stop(void) { HandleDiscoverComplete(); }
+
+    // Methods used from `Mle`
+    void HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const;
+
+    void        HandleDiscoverComplete(void);
+    static void HandleTimer(Timer &aTimer);
+    void        HandleTimer(void);
+
+    Handler          mHandler;
+    void *           mHandlerContext;
+    TimerMilli       mTimer;
+    FilterIndexes    mFilterIndexes;
+    Mac::ChannelMask mScanChannels;
+    State            mState;
+    uint8_t          mScanChannel;
+    bool             mEnableFiltering : 1;
+    bool             mShouldRestorePanId : 1;
+};
+
+} // namespace Mle
+} // namespace ot
+
+#endif // DISCOVER_SCANNER_HPP_
diff --git a/src/core/thread/dua_manager.cpp b/src/core/thread/dua_manager.cpp
new file mode 100644
index 0000000..6f4c045
--- /dev/null
+++ b/src/core/thread/dua_manager.cpp
@@ -0,0 +1,189 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements managing DUA.
+ */
+
+#include "dua_manager.hpp"
+
+#if (OPENTHREAD_FTD || OPENTHREAD_MTD) && OPENTHREAD_CONFIG_DUA_ENABLE
+
+#include "common/code_utils.hpp"
+#include "common/instance.hpp"
+#include "common/locator-getters.hpp"
+#include "common/logging.hpp"
+#include "common/settings.hpp"
+#include "net/ip6_address.hpp"
+#include "thread/thread_netif.hpp"
+#include "utils/slaac_address.hpp"
+
+namespace ot {
+
+DuaManager::DuaManager(Instance &aInstance)
+    : InstanceLocator(aInstance)
+    , mDadCounter(0)
+{
+    mDomainUnicastAddress.Clear();
+    mDomainUnicastAddress.mAddressOrigin      = OT_ADDRESS_ORIGIN_THREAD;
+    mDomainUnicastAddress.mPreferred          = true;
+    mDomainUnicastAddress.mValid              = true;
+    mDomainUnicastAddress.mScopeOverride      = Ip6::Address::kGlobalScope;
+    mDomainUnicastAddress.mScopeOverrideValid = true;
+
+    mFixedDuaInterfaceIdentifier.Clear();
+}
+
+void DuaManager::UpdateDomainUnicastAddress(BackboneRouter::Leader::DomainPrefixState aState)
+{
+    const otIp6Prefix *prefix;
+
+    if ((aState == BackboneRouter::Leader::kDomainPrefixRemoved) ||
+        (aState == BackboneRouter::Leader::kDomainPrefixRefreshed))
+    {
+        Get<ThreadNetif>().RemoveUnicastAddress(mDomainUnicastAddress);
+    }
+
+    VerifyOrExit((aState == BackboneRouter::Leader::kDomainPrefixAdded) ||
+                     (aState == BackboneRouter::Leader::kDomainPrefixRefreshed),
+                 OT_NOOP);
+
+    prefix = Get<BackboneRouter::Leader>().GetDomainPrefix();
+
+    OT_ASSERT(prefix != nullptr);
+
+    mDomainUnicastAddress.mPrefixLength = prefix->mLength;
+    mDomainUnicastAddress.GetAddress().Clear();
+    mDomainUnicastAddress.GetAddress().SetPrefix(prefix->mPrefix.mFields.m8, prefix->mLength);
+
+    // Apply cached DUA Interface Identifier manually specified.
+    if (IsFixedDuaInterfaceIdentifierSet())
+    {
+        mDomainUnicastAddress.GetAddress().SetIid(mFixedDuaInterfaceIdentifier);
+    }
+    else
+    {
+        SuccessOrExit(GenerateDomainUnicastAddressIid());
+    }
+
+    Get<ThreadNetif>().AddUnicastAddress(mDomainUnicastAddress);
+
+exit:
+    return;
+}
+
+otError DuaManager::GenerateDomainUnicastAddressIid(void)
+{
+    otError error;
+    uint8_t dadCounter = mDadCounter;
+
+    if ((error = Get<Utils::Slaac>().GenerateIid(mDomainUnicastAddress, nullptr, 0, &dadCounter)) == OT_ERROR_NONE)
+    {
+        if (dadCounter != mDadCounter)
+        {
+            mDadCounter = dadCounter;
+            IgnoreError(Store());
+        }
+
+        otLogInfoIp6("Generated DUA: %s", mDomainUnicastAddress.GetAddress().ToString().AsCString());
+    }
+    else
+    {
+        otLogWarnIp6("Generate DUA: %s", otThreadErrorToString(error));
+    }
+
+    return error;
+}
+
+otError DuaManager::SetFixedDuaInterfaceIdentifier(const Ip6::InterfaceIdentifier &aIid)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(!aIid.IsReserved(), error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(mFixedDuaInterfaceIdentifier.IsUnspecified() || mFixedDuaInterfaceIdentifier != aIid, OT_NOOP);
+
+    mFixedDuaInterfaceIdentifier = aIid;
+    otLogInfoIp6("Set DUA IID: %s", mFixedDuaInterfaceIdentifier.ToString().AsCString());
+
+    if (Get<ThreadNetif>().HasUnicastAddress(GetDomainUnicastAddress()))
+    {
+        Get<ThreadNetif>().RemoveUnicastAddress(mDomainUnicastAddress);
+        mDomainUnicastAddress.GetAddress().SetIid(mFixedDuaInterfaceIdentifier);
+        Get<ThreadNetif>().AddUnicastAddress(mDomainUnicastAddress);
+    }
+
+exit:
+    return error;
+}
+
+void DuaManager::ClearFixedDuaInterfaceIdentifier(void)
+{
+    // Nothing to clear.
+    VerifyOrExit(IsFixedDuaInterfaceIdentifierSet(), OT_NOOP);
+
+    if (GetDomainUnicastAddress().GetIid() == mFixedDuaInterfaceIdentifier &&
+        Get<ThreadNetif>().HasUnicastAddress(GetDomainUnicastAddress()))
+    {
+        Get<ThreadNetif>().RemoveUnicastAddress(mDomainUnicastAddress);
+
+        if (GenerateDomainUnicastAddressIid() == OT_ERROR_NONE)
+        {
+            Get<ThreadNetif>().AddUnicastAddress(mDomainUnicastAddress);
+        }
+    }
+
+    otLogInfoIp6("Cleared DUA IID: %s", mFixedDuaInterfaceIdentifier.ToString().AsCString());
+    mFixedDuaInterfaceIdentifier.Clear();
+
+exit:
+    return;
+}
+
+void DuaManager::Restore(void)
+{
+    Settings::DadInfo dadInfo;
+
+    SuccessOrExit(Get<Settings>().ReadDadInfo(dadInfo));
+    mDadCounter = dadInfo.GetDadCounter();
+
+exit:
+    return;
+}
+
+otError DuaManager::Store(void)
+{
+    Settings::DadInfo dadInfo;
+
+    dadInfo.SetDadCounter(mDadCounter);
+    return Get<Settings>().SaveDadInfo(dadInfo);
+}
+
+} // namespace ot
+
+#endif // (OPENTHREAD_FTD || OPENTHREAD_MTD) && OPENTHREAD_CONFIG_DUA_ENABLE
diff --git a/src/core/thread/dua_manager.hpp b/src/core/thread/dua_manager.hpp
new file mode 100644
index 0000000..a0fb863
--- /dev/null
+++ b/src/core/thread/dua_manager.hpp
@@ -0,0 +1,145 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for managing Domain Unicast Address feature defined in Thread 1.2.
+ */
+
+#ifndef DUA_MANAGER_HPP_
+#define DUA_MANAGER_HPP_
+
+#include "openthread-core-config.h"
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
+#include "backbone_router/bbr_leader.hpp"
+#include "common/locator.hpp"
+#include "net/netif.hpp"
+
+namespace ot {
+
+/**
+ * @addtogroup core-dua
+ *
+ * @brief
+ *   This module includes definitions for generating, managing, registering Domain Unicast Address.
+ *
+ * @{
+ *
+ * @defgroup core-dua Dua
+ *
+ * @}
+ *
+ */
+
+/**
+ * This class implements managing DUA.
+ *
+ */
+class DuaManager : public InstanceLocator
+{
+public:
+    /**
+     * This constructor initializes the object.
+     *
+     * @param[in]  aInstance     A reference to the OpenThread instance.
+     *
+     */
+    explicit DuaManager(Instance &aInstance);
+
+    /**
+     * This method updates Domain Unicast Address.
+     *
+     * @param[in]  aState  The Domain Prefix state or state change.
+     *
+     */
+    void UpdateDomainUnicastAddress(BackboneRouter::Leader::DomainPrefixState aState);
+
+    /**
+     * This method returns a reference to the Domain Unicast Address.
+     *
+     * @returns A reference to the Domain Unicast Address.
+     *
+     */
+    const Ip6::Address &GetDomainUnicastAddress(void) const { return mDomainUnicastAddress.GetAddress(); }
+
+    /**
+     * This method sets the Interface Identifier manually specified for the Thread Domain Unicast Address.
+     *
+     * @param[in]  aIid        A reference to the Interface Identifier to set.
+     *
+     * @retval OT_ERROR_NONE           Successfully set the Interface Identifier.
+     * @retval OT_ERROR_INVALID_ARGS   The specified Interface Identifier is reserved.
+     *
+     */
+    otError SetFixedDuaInterfaceIdentifier(const Ip6::InterfaceIdentifier &aIid);
+
+    /**
+     * This method clears the Interface Identifier manually specified for the Thread Domain Unicast Address.
+     *
+     */
+    void ClearFixedDuaInterfaceIdentifier(void);
+
+    /**
+     * This method indicates whether or not there is Interface Identifier manually specified for the Thread
+     * Domain Unicast Address.
+     *
+     * @retval true  If there is Interface Identifier manually specified.
+     * @retval false If there is no Interface Identifier manually specified.
+     *
+     */
+    bool IsFixedDuaInterfaceIdentifierSet(void) { return !mFixedDuaInterfaceIdentifier.IsUnspecified(); }
+
+    /**
+     * This method gets the Interface Identifier for the Thread Domain Unicast Address if manually specified.
+     *
+     * @returns A reference to the Interface Identifier.
+     *
+     */
+    const Ip6::InterfaceIdentifier &GetFixedDuaInterfaceIdentifier(void) const { return mFixedDuaInterfaceIdentifier; }
+
+    /*
+     * This method restores duplicate address detection information from non-volatile memory.
+     *
+     */
+    void Restore(void);
+
+private:
+    otError GenerateDomainUnicastAddressIid(void);
+    otError Store(void);
+
+    Ip6::InterfaceIdentifier mFixedDuaInterfaceIdentifier;
+    Ip6::NetifUnicastAddress mDomainUnicastAddress;
+    uint8_t                  mDadCounter;
+};
+
+} // namespace ot
+
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+#endif // DUA_MANAGER_HPP_
diff --git a/src/core/thread/energy_scan_server.cpp b/src/core/thread/energy_scan_server.cpp
index 0f5e44a..06fba97 100644
--- a/src/core/thread/energy_scan_server.cpp
+++ b/src/core/thread/energy_scan_server.cpp
@@ -48,6 +48,7 @@
 
 EnergyScanServer::EnergyScanServer(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , Notifier::Receiver(aInstance, EnergyScanServer::HandleNotifierEvents)
     , mChannelMask(0)
     , mChannelMaskCurrent(0)
     , mPeriod(0)
@@ -55,8 +56,7 @@
     , mCount(0)
     , mActive(false)
     , mScanResultsLength(0)
-    , mTimer(aInstance, &EnergyScanServer::HandleTimer, this)
-    , mNotifierCallback(aInstance, &EnergyScanServer::HandleStateChanged, this)
+    , mTimer(aInstance, EnergyScanServer::HandleTimer, this)
     , mEnergyScan(OT_URI_PATH_ENERGY_SCAN, &EnergyScanServer::HandleRequest, this)
 {
     Get<Coap::Coap>().AddResource(mEnergyScan);
@@ -70,30 +70,25 @@
 
 void EnergyScanServer::HandleRequest(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    MeshCoP::CountTlv        count;
-    MeshCoP::PeriodTlv       period;
-    MeshCoP::ScanDurationTlv scanDuration;
-    Ip6::MessageInfo         responseInfo(aMessageInfo);
-    uint32_t                 mask;
+    uint8_t          count;
+    uint16_t         period;
+    uint16_t         scanDuration;
+    Ip6::MessageInfo responseInfo(aMessageInfo);
+    uint32_t         mask;
 
-    VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
-    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kCount, sizeof(count), count));
-    VerifyOrExit(count.IsValid());
+    SuccessOrExit(Tlv::FindUint8Tlv(aMessage, MeshCoP::Tlv::kCount, count));
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, MeshCoP::Tlv::kPeriod, period));
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, MeshCoP::Tlv::kScanDuration, scanDuration));
 
-    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPeriod, sizeof(period), period));
-    VerifyOrExit(period.IsValid());
-
-    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kScanDuration, sizeof(scanDuration), scanDuration));
-    VerifyOrExit(scanDuration.IsValid());
-
-    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
+    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0, OT_NOOP);
 
     mChannelMask        = mask;
     mChannelMaskCurrent = mChannelMask;
-    mCount              = count.GetCount();
-    mPeriod             = period.GetPeriod();
-    mScanDuration       = scanDuration.GetScanDuration();
+    mCount              = count;
+    mPeriod             = period;
+    mScanDuration       = scanDuration;
     mScanResultsLength  = 0;
     mActive             = true;
     mTimer.Start(kScanDelay);
@@ -117,13 +112,13 @@
 
 void EnergyScanServer::HandleTimer(void)
 {
-    VerifyOrExit(mActive);
+    VerifyOrExit(mActive, OT_NOOP);
 
     if (mCount)
     {
         // grab the lowest channel to scan
         uint32_t channelMask = mChannelMaskCurrent & ~(mChannelMaskCurrent - 1);
-        Get<Mac::Mac>().EnergyScan(channelMask, mScanDuration, HandleScanResult, this);
+        IgnoreError(Get<Mac::Mac>().EnergyScan(channelMask, mScanDuration, HandleScanResult, this));
     }
     else
     {
@@ -141,10 +136,11 @@
 
 void EnergyScanServer::HandleScanResult(Mac::EnergyScanResult *aResult)
 {
-    VerifyOrExit(mActive);
+    VerifyOrExit(mActive, OT_NOOP);
 
     if (aResult)
     {
+        VerifyOrExit(mScanResultsLength < OPENTHREAD_CONFIG_TMF_ENERGY_SCAN_MAX_RESULTS, OT_NOOP);
         mScanResults[mScanResultsLength++] = aResult->mMaxRssi;
     }
     else
@@ -172,7 +168,7 @@
     return;
 }
 
-otError EnergyScanServer::SendReport(void)
+void EnergyScanServer::SendReport(void)
 {
     otError                 error = OT_ERROR_NONE;
     MeshCoP::ChannelMaskTlv channelMask;
@@ -180,7 +176,7 @@
     Ip6::MessageInfo        messageInfo;
     Coap::Message *         message;
 
-    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_ENERGY_REPORT));
     SuccessOrExit(error = message->SetPayloadMarker());
@@ -203,25 +199,28 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        message->Free();
+        otLogInfoMeshCoP("Failed to send scan results: %s", otThreadErrorToString(error));
+
+        if (message != nullptr)
+        {
+            message->Free();
+        }
     }
 
     mActive = false;
-
-    return error;
 }
 
-void EnergyScanServer::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags)
+void EnergyScanServer::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<EnergyScanServer>().HandleStateChanged(aFlags);
+    static_cast<EnergyScanServer &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
-void EnergyScanServer::HandleStateChanged(otChangedFlags aFlags)
+void EnergyScanServer::HandleNotifierEvents(Events aEvents)
 {
-    if ((aFlags & OT_CHANGED_THREAD_NETDATA) != 0 && !mActive &&
-        Get<NetworkData::Leader>().GetCommissioningData() == NULL)
+    if (aEvents.Contains(kEventThreadNetdataChanged) && !mActive &&
+        Get<NetworkData::Leader>().GetCommissioningData() == nullptr)
     {
         mActive = false;
         mTimer.Stop();
diff --git a/src/core/thread/energy_scan_server.hpp b/src/core/thread/energy_scan_server.hpp
index c3f7a53..5f316eb 100644
--- a/src/core/thread/energy_scan_server.hpp
+++ b/src/core/thread/energy_scan_server.hpp
@@ -50,7 +50,7 @@
  * This class implements handling Energy Scan Requests.
  *
  */
-class EnergyScanServer : public InstanceLocator
+class EnergyScanServer : public InstanceLocator, public Notifier::Receiver
 {
 public:
     /**
@@ -75,10 +75,10 @@
     static void HandleTimer(Timer &aTimer);
     void        HandleTimer(void);
 
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags);
-    void        HandleStateChanged(otChangedFlags aFlags);
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
 
-    otError SendReport(void);
+    void SendReport(void);
 
     Ip6::Address mCommissioner;
     uint32_t     mChannelMask;
@@ -93,8 +93,6 @@
 
     TimerMilli mTimer;
 
-    Notifier::Callback mNotifierCallback;
-
     Coap::Resource mEnergyScan;
 };
 
diff --git a/src/core/thread/indirect_sender.cpp b/src/core/thread/indirect_sender.cpp
index 38428e9..4e006e1 100644
--- a/src/core/thread/indirect_sender.cpp
+++ b/src/core/thread/indirect_sender.cpp
@@ -70,12 +70,12 @@
 
 void IndirectSender::Stop(void)
 {
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateAnyExceptInvalid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
     {
-        iter.GetChild()->SetIndirectMessage(NULL);
-        mSourceMatchController.ResetMessageCount(*iter.GetChild());
+        child.SetIndirectMessage(nullptr);
+        mSourceMatchController.ResetMessageCount(child);
     }
 
     mDataPollHandler.Clear();
@@ -84,15 +84,14 @@
     mEnabled = false;
 }
 
-otError IndirectSender::AddMessageForSleepyChild(Message &aMessage, Child &aChild)
+void IndirectSender::AddMessageForSleepyChild(Message &aMessage, Child &aChild)
 {
-    otError  error = OT_ERROR_NONE;
     uint16_t childIndex;
 
-    VerifyOrExit(!aChild.IsRxOnWhenIdle(), error = OT_ERROR_INVALID_STATE);
+    OT_ASSERT(!aChild.IsRxOnWhenIdle());
 
     childIndex = Get<ChildTable>().GetChildIndex(aChild);
-    VerifyOrExit(!aMessage.GetChildMask(childIndex), error = OT_ERROR_ALREADY);
+    VerifyOrExit(!aMessage.GetChildMask(childIndex), OT_NOOP);
 
     aMessage.SetChildMask(childIndex);
     mSourceMatchController.IncrementMessageCount(aChild);
@@ -100,7 +99,7 @@
     RequestMessageUpdate(aChild);
 
 exit:
-    return error;
+    return;
 }
 
 otError IndirectSender::RemoveMessageFromSleepyChild(Message &aMessage, Child &aChild)
@@ -124,7 +123,7 @@
     Message *message;
     Message *nextMessage;
 
-    VerifyOrExit(aChild.GetIndirectMessageCount() > 0);
+    VerifyOrExit(aChild.GetIndirectMessageCount() > 0, OT_NOOP);
 
     for (message = Get<MeshForwarder>().mSendQueue.GetHead(); message; message = nextMessage)
     {
@@ -136,7 +135,7 @@
         {
             if (Get<MeshForwarder>().mSendMessage == message)
             {
-                Get<MeshForwarder>().mSendMessage = NULL;
+                Get<MeshForwarder>().mSendMessage = nullptr;
             }
 
             Get<MeshForwarder>().mSendQueue.Dequeue(*message);
@@ -144,7 +143,7 @@
         }
     }
 
-    aChild.SetIndirectMessage(NULL);
+    aChild.SetIndirectMessage(nullptr);
     mSourceMatchController.ResetMessageCount(aChild);
 
     mDataPollHandler.RequestFrameChange(DataPollHandler::kPurgeFrame, aChild);
@@ -155,7 +154,7 @@
 
 void IndirectSender::SetChildUseShortAddress(Child &aChild, bool aUseShortAddress)
 {
-    VerifyOrExit(aChild.IsIndirectSourceMatchShort() != aUseShortAddress);
+    VerifyOrExit(aChild.IsIndirectSourceMatchShort() != aUseShortAddress, OT_NOOP);
 
     mSourceMatchController.SetSrcMatchAsShort(aChild, aUseShortAddress);
 
@@ -186,7 +185,7 @@
             }
         }
 
-        aChild.SetIndirectMessage(NULL);
+        aChild.SetIndirectMessage(nullptr);
         mSourceMatchController.ResetMessageCount(aChild);
 
         mDataPollHandler.RequestFrameChange(DataPollHandler::kPurgeFrame, aChild);
@@ -241,12 +240,12 @@
     // case where we have a pending "replace frame" request and while
     // waiting for the callback, the current message is removed.
 
-    if ((curMessage != NULL) && !curMessage->GetChildMask(Get<ChildTable>().GetChildIndex(aChild)))
+    if ((curMessage != nullptr) && !curMessage->GetChildMask(Get<ChildTable>().GetChildIndex(aChild)))
     {
-        // Set the indirect message for this child to NULL to ensure
+        // Set the indirect message for this child to nullptr to ensure
         // it is not processed on `HandleSentFrameToChild()` callback.
 
-        aChild.SetIndirectMessage(NULL);
+        aChild.SetIndirectMessage(nullptr);
 
         // Request a "frame purge" using `RequestFrameChange()` and
         // wait for `HandleFrameChangeDone()` callback for completion
@@ -260,28 +259,28 @@
         ExitNow();
     }
 
-    VerifyOrExit(!aChild.IsWaitingForMessageUpdate());
+    VerifyOrExit(!aChild.IsWaitingForMessageUpdate(), OT_NOOP);
 
     newMessage = FindIndirectMessage(aChild);
 
-    VerifyOrExit(curMessage != newMessage);
+    VerifyOrExit(curMessage != newMessage, OT_NOOP);
 
-    if (curMessage == NULL)
+    if (curMessage == nullptr)
     {
-        // Current message is NULL, but new message is not.
+        // Current message is nullptr, but new message is not.
         // We have a new indirect message.
 
         UpdateIndirectMessage(aChild);
         ExitNow();
     }
 
-    // Current message and new message differ and are both non-NULL.
+    // Current message and new message differ and are both non-nullptr.
     // We need to request the frame to be replaced. The current
     // indirect message can be replaced only if it is the first
     // fragment. If a next fragment frame for message is already
     // prepared, we wait for the entire message to be delivered.
 
-    VerifyOrExit(aChild.GetIndirectFragmentOffset() == 0);
+    VerifyOrExit(aChild.GetIndirectFragmentOffset() == 0, OT_NOOP);
 
     aChild.SetWaitingForMessageUpdate(true);
     mDataPollHandler.RequestFrameChange(DataPollHandler::kReplaceFrame, aChild);
@@ -292,7 +291,7 @@
 
 void IndirectSender::HandleFrameChangeDone(Child &aChild)
 {
-    VerifyOrExit(aChild.IsWaitingForMessageUpdate());
+    VerifyOrExit(aChild.IsWaitingForMessageUpdate(), OT_NOOP);
     UpdateIndirectMessage(aChild);
 
 exit:
@@ -308,7 +307,7 @@
     aChild.SetIndirectFragmentOffset(0);
     aChild.SetIndirectTxSuccess(true);
 
-    if (message != NULL)
+    if (message != nullptr)
     {
         Mac::Address childAddress;
 
@@ -326,7 +325,7 @@
 
     VerifyOrExit(mEnabled, error = OT_ERROR_ABORT);
 
-    if (message == NULL)
+    if (message == nullptr)
     {
         PrepareEmptyFrame(aFrame, aChild, /* aAckRequest */ true);
         ExitNow();
@@ -344,8 +343,8 @@
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
 exit:
@@ -424,7 +423,7 @@
     aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32);
 
     aFrame.SetDstPanId(Get<Mac::Mac>().GetPanId());
-    aFrame.SetSrcPanId(Get<Mac::Mac>().GetPanId());
+    IgnoreError(aFrame.SetSrcPanId(Get<Mac::Mac>().GetPanId()));
     aFrame.SetDstAddr(macDest);
     aFrame.SetSrcAddr(macSource);
     aFrame.SetPayloadLength(0);
@@ -439,7 +438,7 @@
     Message *message    = aChild.GetIndirectMessage();
     uint16_t nextOffset = aContext.mMessageNextOffset;
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     switch (aError)
     {
@@ -458,7 +457,7 @@
         // send any remaining fragments in the message to the child, if all tx
         // attempts of current frame already failed.
 
-        if (message != NULL)
+        if (message != nullptr)
         {
             nextOffset = message->GetLength();
         }
@@ -466,18 +465,18 @@
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
-    if ((message != NULL) && (nextOffset < message->GetLength()))
+    if ((message != nullptr) && (nextOffset < message->GetLength()))
     {
         aChild.SetIndirectFragmentOffset(nextOffset);
         mDataPollHandler.HandleNewFrame(aChild);
         ExitNow();
     }
 
-    if (message != NULL)
+    if (message != nullptr)
     {
         // The indirect tx of this message to the child is done.
 
@@ -485,7 +484,7 @@
         uint16_t     childIndex = Get<ChildTable>().GetChildIndex(aChild);
         Mac::Address macDest;
 
-        aChild.SetIndirectMessage(NULL);
+        aChild.SetIndirectMessage(nullptr);
         aChild.GetLinkInfo().AddMessageTxStatus(aChild.GetIndirectTxSuccess());
 
         // Enable short source address matching after the first indirect
@@ -517,7 +516,7 @@
 
         if (!aFrame.IsEmpty())
         {
-            aFrame.GetDstAddr(macDest);
+            IgnoreError(aFrame.GetDstAddr(macDest));
             Get<MeshForwarder>().LogMessage(MeshForwarder::kMessageTransmit, *message, &macDest, txError);
         }
 
@@ -557,14 +556,14 @@
 
 void IndirectSender::ClearMessagesForRemovedChildren(void)
 {
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateAnyExceptValidOrRestoring); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptValidOrRestoring))
     {
-        if (iter.GetChild()->GetIndirectMessageCount() == 0)
+        if (child.GetIndirectMessageCount() == 0)
         {
             continue;
         }
 
-        ClearAllMessagesForSleepyChild(*iter.GetChild());
+        ClearAllMessagesForSleepyChild(child);
     }
 }
 
diff --git a/src/core/thread/indirect_sender.hpp b/src/core/thread/indirect_sender.hpp
index 7bc47f5..d6fd63b 100644
--- a/src/core/thread/indirect_sender.hpp
+++ b/src/core/thread/indirect_sender.hpp
@@ -40,8 +40,8 @@
 #include "common/message.hpp"
 #include "mac/data_poll_handler.hpp"
 #include "mac/mac_frame.hpp"
-#include "thread/device_mode.hpp"
 #include "thread/indirect_sender_frame_context.hpp"
+#include "thread/mle_types.hpp"
 #include "thread/src_match_controller.hpp"
 
 namespace ot {
@@ -120,8 +120,8 @@
         bool     mUseShortAddress : 1;         // Indicates whether to use short or extended address.
         bool     mSourceMatchPending : 1;      // Indicates whether or not pending to add to src match table.
 
-        OT_STATIC_ASSERT(OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS < (1UL << 14),
-                         "mQueuedMessageCount cannot fit max required!");
+        static_assert(OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS < (1UL << 14),
+                      "mQueuedMessageCount cannot fit max required!");
     };
 
     /**
@@ -152,12 +152,8 @@
      * @param[in] aMessage  The message to add.
      * @param[in] aChild    The (sleepy) child for indirect transmission.
      *
-     * @retval OT_ERROR_NONE           Successfully added the message for indirect transmission.
-     * @retval OT_ERROR_ALREADY        The message was already added for indirect transmission to same child.
-     * @retval OT_ERROR_INVALID_STATE  The child is not sleepy.
-     *
      */
-    otError AddMessageForSleepyChild(Message &aMessage, Child &aChild);
+    void AddMessageForSleepyChild(Message &aMessage, Child &aChild);
 
     /**
      * This method removes a message for indirect transmission to a sleepy child.
diff --git a/src/core/thread/key_manager.cpp b/src/core/thread/key_manager.cpp
index f8abc53..bcb0c6a 100644
--- a/src/core/thread/key_manager.cpp
+++ b/src/core/thread/key_manager.cpp
@@ -38,7 +38,6 @@
 #include "common/instance.hpp"
 #include "common/locator-getters.hpp"
 #include "common/timer.hpp"
-#include "crypto/hmac_sha256.hpp"
 #include "thread/mle_router.hpp"
 #include "thread/thread_netif.hpp"
 
@@ -70,7 +69,6 @@
 KeyManager::KeyManager(Instance &aInstance)
     : InstanceLocator(aInstance)
     , mKeySequence(0)
-    , mMacFrameCounter(0)
     , mMleFrameCounter(0)
     , mStoredMacFrameCounter(0)
     , mStoredMleFrameCounter(0)
@@ -78,14 +76,13 @@
     , mKeyRotationTime(kDefaultKeyRotationTime)
     , mKeySwitchGuardTime(kDefaultKeySwitchGuardTime)
     , mKeySwitchGuardEnabled(false)
-    , mKeyRotationTimer(aInstance, &KeyManager::HandleKeyRotationTimer, this)
+    , mKeyRotationTimer(aInstance, KeyManager::HandleKeyRotationTimer, this)
     , mKekFrameCounter(0)
     , mSecurityPolicyFlags(0xff)
     , mIsPskcSet(false)
 {
     mMasterKey = static_cast<const MasterKey &>(kDefaultMasterKey);
     mPskc.Clear();
-    ComputeKey(mKeySequence, mKey);
 }
 
 void KeyManager::Start(void)
@@ -102,7 +99,7 @@
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
 void KeyManager::SetPskc(const Pskc &aPskc)
 {
-    Get<Notifier>().Update(mPskc, aPskc, OT_CHANGED_PSKC);
+    IgnoreError(Get<Notifier>().Update(mPskc, aPskc, kEventPskcChanged));
     mIsPskcSet = true;
 }
 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
@@ -112,11 +109,10 @@
     otError error = OT_ERROR_NONE;
     Router *parent;
 
-    SuccessOrExit(
-        Get<Notifier>().Update(mMasterKey, aKey, OT_CHANGED_MASTER_KEY | OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER));
-
+    SuccessOrExit(Get<Notifier>().Update(mMasterKey, aKey, kEventMasterKeyChanged));
+    Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
     mKeySequence = 0;
-    ComputeKey(mKeySequence, mKey);
+    UpdateKeyMaterial();
 
     // reset parent frame counters
     parent = &Get<Mle::MleRouter>().GetParent();
@@ -124,6 +120,7 @@
     parent->SetLinkFrameCounter(0);
     parent->SetMleFrameCounter(0);
 
+#if OPENTHREAD_FTD
     // reset router frame counters
     for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++)
     {
@@ -133,18 +130,19 @@
     }
 
     // reset child frame counters
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateAnyExceptInvalid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
     {
-        iter.GetChild()->SetKeySequence(0);
-        iter.GetChild()->SetLinkFrameCounter(0);
-        iter.GetChild()->SetMleFrameCounter(0);
+        child.SetKeySequence(0);
+        child.SetLinkFrameCounter(0);
+        child.SetMleFrameCounter(0);
     }
+#endif
 
 exit:
     return error;
 }
 
-void KeyManager::ComputeKey(uint32_t aKeySequence, uint8_t *aKey)
+void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys)
 {
     Crypto::HmacSha256 hmac;
     uint8_t            keySequenceBytes[sizeof(uint32_t)];
@@ -155,19 +153,35 @@
     hmac.Update(keySequenceBytes, sizeof(keySequenceBytes));
     hmac.Update(kThreadString, sizeof(kThreadString));
 
-    hmac.Finish(aKey);
+    hmac.Finish(aHashKeys.mHash);
+}
+
+void KeyManager::UpdateKeyMaterial(void)
+{
+    HashKeys prev;
+    HashKeys cur;
+    HashKeys next;
+
+    ComputeKeys(mKeySequence - 1, prev);
+    ComputeKeys(mKeySequence, cur);
+    ComputeKeys(mKeySequence + 1, next);
+
+    mMleKey = cur.mKeys.mMleKey;
+
+    Get<Mac::SubMac>().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prev.mKeys.mMacKey,
+                                 cur.mKeys.mMacKey, next.mKeys.mMacKey);
 }
 
 void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence)
 {
-    VerifyOrExit(aKeySequence != mKeySequence, Get<Notifier>().SignalIfFirst(OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER));
+    VerifyOrExit(aKeySequence != mKeySequence, Get<Notifier>().SignalIfFirst(kEventThreadKeySeqCounterChanged));
 
     if ((aKeySequence == (mKeySequence + 1)) && mKeyRotationTimer.IsRunning())
     {
         if (mKeySwitchGuardEnabled)
         {
             // Check if the guard timer has expired if key rotation is requested.
-            VerifyOrExit(mHoursSinceKeyRotation >= mKeySwitchGuardTime);
+            VerifyOrExit(mHoursSinceKeyRotation >= mKeySwitchGuardTime, OT_NOOP);
             StartKeyRotationTimer();
         }
 
@@ -175,36 +189,42 @@
     }
 
     mKeySequence = aKeySequence;
-    ComputeKey(mKeySequence, mKey);
+    UpdateKeyMaterial();
 
-    mMacFrameCounter = 0;
+    SetMacFrameCounter(0);
     mMleFrameCounter = 0;
 
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER);
+    Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
 
 exit:
     return;
 }
 
-const uint8_t *KeyManager::GetTemporaryMacKey(uint32_t aKeySequence)
+const Mle::Key &KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
 {
-    ComputeKey(aKeySequence, mTemporaryKey);
-    return mTemporaryKey + kMacKeyOffset;
+    HashKeys hashKeys;
+
+    ComputeKeys(aKeySequence, hashKeys);
+    mTemporaryMleKey = hashKeys.mKeys.mMleKey;
+
+    return mTemporaryMleKey;
 }
 
-const uint8_t *KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
+uint32_t KeyManager::GetMacFrameCounter(void) const
 {
-    ComputeKey(aKeySequence, mTemporaryKey);
-    return mTemporaryKey;
+    return Get<Mac::SubMac>().GetFrameCounter();
 }
 
-void KeyManager::IncrementMacFrameCounter(void)
+void KeyManager::SetMacFrameCounter(uint32_t aMacFrameCounter)
 {
-    mMacFrameCounter++;
+    Get<Mac::SubMac>().SetFrameCounter(aMacFrameCounter);
+}
 
-    if (mMacFrameCounter >= mStoredMacFrameCounter)
+void KeyManager::MacFrameCounterUpdated(uint32_t aMacFrameCounter)
+{
+    if (aMacFrameCounter >= mStoredMacFrameCounter)
     {
-        Get<Mle::MleRouter>().Store();
+        IgnoreError(Get<Mle::MleRouter>().Store());
     }
 }
 
@@ -214,13 +234,19 @@
 
     if (mMleFrameCounter >= mStoredMleFrameCounter)
     {
-        Get<Mle::MleRouter>().Store();
+        IgnoreError(Get<Mle::MleRouter>().Store());
     }
 }
 
+void KeyManager::SetKek(const Kek &aKek)
+{
+    mKek             = aKek;
+    mKekFrameCounter = 0;
+}
+
 void KeyManager::SetKek(const uint8_t *aKek)
 {
-    memcpy(mKek, aKek, sizeof(mKek));
+    memcpy(mKek.m8, aKek, sizeof(mKek));
     mKekFrameCounter = 0;
 }
 
@@ -238,7 +264,7 @@
 
 void KeyManager::SetSecurityPolicyFlags(uint8_t aSecurityPolicyFlags)
 {
-    Get<Notifier>().Update(mSecurityPolicyFlags, aSecurityPolicyFlags, OT_CHANGED_SECURITY_POLICY);
+    IgnoreError(Get<Notifier>().Update(mSecurityPolicyFlags, aSecurityPolicyFlags, kEventSecurityPolicyChanged));
 }
 
 void KeyManager::StartKeyRotationTimer(void)
@@ -271,18 +297,4 @@
     }
 }
 
-void KeyManager::GenerateNonce(const Mac::ExtAddress &aAddress,
-                               uint32_t               aFrameCounter,
-                               uint8_t                aSecurityLevel,
-                               uint8_t *              aNonce)
-{
-    memcpy(aNonce, aAddress.m8, sizeof(Mac::ExtAddress));
-    aNonce += sizeof(Mac::ExtAddress);
-
-    Encoding::BigEndian::WriteUint32(aFrameCounter, aNonce);
-    aNonce += sizeof(uint32_t);
-
-    aNonce[0] = aSecurityLevel;
-}
-
 } // namespace ot
diff --git a/src/core/thread/key_manager.hpp b/src/core/thread/key_manager.hpp
index c8dfa99..c9c82d6 100644
--- a/src/core/thread/key_manager.hpp
+++ b/src/core/thread/key_manager.hpp
@@ -40,11 +40,14 @@
 
 #include <openthread/dataset.h>
 
+#include "common/clearable.hpp"
+#include "common/equatable.hpp"
 #include "common/locator.hpp"
 #include "common/random.hpp"
 #include "common/timer.hpp"
 #include "crypto/hmac_sha256.hpp"
 #include "mac/mac_types.hpp"
+#include "thread/mle_types.hpp"
 
 namespace ot {
 
@@ -62,31 +65,8 @@
  *
  */
 OT_TOOL_PACKED_BEGIN
-class MasterKey : public otMasterKey
+class MasterKey : public otMasterKey, public Equatable<MasterKey>
 {
-public:
-    /**
-     * This method evaluates whether or not the Thread Master Keys match.
-     *
-     * @param[in]  aOther  The Thread Master Key to compare.
-     *
-     * @retval TRUE   If the Thread Master Keys match.
-     * @retval FALSE  If the Thread Master Keys do not match.
-     *
-     */
-    bool operator==(const MasterKey &aOther) const { return memcmp(m8, aOther.m8, sizeof(MasterKey)) == 0; }
-
-    /**
-     * This method evaluates whether or not the Thread Master Keys match.
-     *
-     * @param[in]  aOther  The Thread Master Key to compare.
-     *
-     * @retval TRUE   If the Thread Master Keys do not match.
-     * @retval FALSE  If the Thread Master Keys match.
-     *
-     */
-    bool operator!=(const MasterKey &aOther) const { return !(*this == aOther); }
-
 } OT_TOOL_PACKED_END;
 
 /**
@@ -94,37 +74,9 @@
  *
  */
 OT_TOOL_PACKED_BEGIN
-class Pskc : public otPskc
+class Pskc : public otPskc, public Equatable<Pskc>, public Clearable<Pskc>
 {
 public:
-    /**
-     * This method clears the PSKc (sets all bytes to zero).
-     *
-     */
-    void Clear(void) { memset(this, 0, sizeof(*this)); }
-
-    /**
-     * This method evaluates whether or not the Thread PSKc values match.
-     *
-     * @param[in]  aOther  The Thread PSKc to compare.
-     *
-     * @retval TRUE   If the Thread PSKc values match.
-     * @retval FALSE  If the Thread PSKc values do not match.
-     *
-     */
-    bool operator==(const Pskc &aOther) const { return memcmp(m8, aOther.m8, sizeof(Pskc)) == 0; }
-
-    /**
-     * This method evaluates whether or not the Thread PSKc values match.
-     *
-     * @param[in]  aOther  The Thread PSKc to compare.
-     *
-     * @retval TRUE   If the Thread PSKc values do not match.
-     * @retval FALSE  If the Thread PSKc values match.
-     *
-     */
-    bool operator!=(const Pskc &aOther) const { return !(*this == aOther); }
-
 #if !OPENTHREAD_RADIO
     /**
      * This method generates a cryptographically secure random sequence to populate the Thread PSKc.
@@ -138,18 +90,19 @@
 } OT_TOOL_PACKED_END;
 
 /**
+ *
+ * This class represents a Key Encryption Key (KEK).
+ *
+ */
+typedef Mac::Key Kek;
+
+/**
  * This class defines Thread Key Manager.
  *
  */
 class KeyManager : public InstanceLocator
 {
 public:
-    enum
-    {
-        kMaxKeyLength = 16,
-        kNonceSize    = 13, ///< Size of IEEE 802.15.4 Nonce (bytes).
-    };
-
     /**
      * This constructor initializes the object.
      *
@@ -235,30 +188,12 @@
     void SetCurrentKeySequence(uint32_t aKeySequence);
 
     /**
-     * This method returns a pointer to the current MAC key.
-     *
-     * @returns A pointer to the current MAC key.
-     *
-     */
-    const uint8_t *GetCurrentMacKey(void) const { return mKey + kMacKeyOffset; }
-
-    /**
      * This method returns a pointer to the current MLE key.
      *
      * @returns A pointer to the current MLE key.
      *
      */
-    const uint8_t *GetCurrentMleKey(void) const { return mKey; }
-
-    /**
-     * This method returns a pointer to a temporary MAC key computed from the given key sequence.
-     *
-     * @param[in]  aKeySequence  The key sequence value.
-     *
-     * @returns A pointer to the temporary MAC key.
-     *
-     */
-    const uint8_t *GetTemporaryMacKey(uint32_t aKeySequence);
+    const Mle::Key &GetCurrentMleKey(void) const { return mMleKey; }
 
     /**
      * This method returns a pointer to a temporary MLE key computed from the given key sequence.
@@ -268,7 +203,7 @@
      * @returns A pointer to the temporary MLE key.
      *
      */
-    const uint8_t *GetTemporaryMleKey(uint32_t aKeySequence);
+    const Mle::Key &GetTemporaryMleKey(uint32_t aKeySequence);
 
     /**
      * This method returns the current MAC Frame Counter value.
@@ -276,7 +211,7 @@
      * @returns The current MAC Frame Counter value.
      *
      */
-    uint32_t GetMacFrameCounter(void) const { return mMacFrameCounter; }
+    uint32_t GetMacFrameCounter(void) const;
 
     /**
      * This method sets the current MAC Frame Counter value.
@@ -284,7 +219,7 @@
      * @param[in]  aMacFrameCounter  The MAC Frame Counter value.
      *
      */
-    void SetMacFrameCounter(uint32_t aMacFrameCounter) { mMacFrameCounter = aMacFrameCounter; }
+    void SetMacFrameCounter(uint32_t aMacFrameCounter);
 
     /**
      * This method sets the MAC Frame Counter value which is stored in non-volatile memory.
@@ -295,12 +230,6 @@
     void SetStoredMacFrameCounter(uint32_t aStoredMacFrameCounter) { mStoredMacFrameCounter = aStoredMacFrameCounter; }
 
     /**
-     * This method increments the current MAC Frame Counter value.
-     *
-     */
-    void IncrementMacFrameCounter(void);
-
-    /**
      * This method returns the current MLE Frame Counter value.
      *
      * @returns The current MLE Frame Counter value.
@@ -336,7 +265,15 @@
      * @returns A pointer to the KEK.
      *
      */
-    const uint8_t *GetKek(void) const { return mKek; }
+    const Kek &GetKek(void) const { return mKek; }
+
+    /**
+     * This method sets the KEK.
+     *
+     * @param[in]  aKek  A KEK.
+     *
+     */
+    void SetKek(const Kek &aKek);
 
     /**
      * This method sets the KEK.
@@ -426,18 +363,74 @@
     void SetSecurityPolicyFlags(uint8_t aSecurityPolicyFlags);
 
     /**
-     * This static method generates IEEE 802.15.4 nonce byte sequence.
+     * This method indicates whether or not obtaining Master key for out-of-band is enabled.
      *
-     * @param[in]  aAddress        An extended address.
-     * @param[in]  aFrameCounter   A frame counter.
-     * @param[in]  aSecurityLevel  A security level.
-     * @param[out] aNonce          A buffer (with `kNonceSize` bytes) to place the generated nonce.
+     * @retval TRUE   If obtaining Master key for out-of-band is enabled.
+     * @retval FALSE  If obtaining Master key for out-of-band is not enabled.
      *
      */
-    static void GenerateNonce(const Mac::ExtAddress &aAddress,
-                              uint32_t               aFrameCounter,
-                              uint8_t                aSecurityLevel,
-                              uint8_t *              aNonce);
+    bool IsObtainMasterKeyEnabled(void) const
+    {
+        return (mSecurityPolicyFlags & OT_SECURITY_POLICY_OBTAIN_MASTER_KEY) != 0;
+    }
+
+    /**
+     * This method indicates whether or not Native Commissioning using PSKc is allowed.
+     *
+     * @retval TRUE   If Native Commissioning using PSKc is allowed.
+     * @retval FALSE  If Native Commissioning using PSKc is not allowed.
+     *
+     */
+    bool IsNativeCommissioningAllowed(void) const
+    {
+        return (mSecurityPolicyFlags & OT_SECURITY_POLICY_NATIVE_COMMISSIONING) != 0;
+    }
+
+    /**
+     * This method indicates whether or not Thread 1.1 Routers are enabled.
+     *
+     * @retval TRUE   If Thread 1.1 Routers are enabled.
+     * @retval FALSE  If Thread 1.1 Routers are not enabled.
+     *
+     */
+    bool IsRouterEnabled(void) const { return (mSecurityPolicyFlags & OT_SECURITY_POLICY_ROUTERS) != 0; }
+
+    /**
+     * This method indicates whether or not external Commissioner authentication is allowed using PSKc.
+     *
+     * @retval TRUE   If the commissioning sessions by an external Commissioner based on the PSKc are allowed
+     *                to be established and that changes to the Commissioner Dataset by on-mesh nodes are allowed.
+     * @retval FALSE  If the commissioning sessions by an external Commissioner based on the PSKc are not allowed
+     *                to be established and that changes to the Commissioner Dataset by on-mesh nodes are not allowed.
+     *
+     */
+    bool IsExternalCommissionerAllowed(void) const
+    {
+        return (mSecurityPolicyFlags & OT_SECURITY_POLICY_EXTERNAL_COMMISSIONER) != 0;
+    }
+
+    /**
+     * This method indicates whether or not Thread Beacons are enabled.
+     *
+     * @retval TRUE   If Thread Beacons are enabled.
+     * @retval FALSE  If Thread Beacons are not enabled.
+     *
+     */
+    bool IsThreadBeaconEnabled(void) const { return (mSecurityPolicyFlags & OT_SECURITY_POLICY_BEACONS) != 0; }
+
+    /**
+     * This method updates the MAC keys and MLE key.
+     *
+     */
+    void UpdateKeyMaterial(void);
+
+    /**
+     * This method handles MAC frame counter change.
+     *
+     * @param[in]  aMacFrameCounter  The MAC frame counter value.
+     *
+     */
+    void MacFrameCounterUpdated(uint32_t aMacFrameCounter);
 
 private:
     enum
@@ -445,11 +438,23 @@
         kMinKeyRotationTime        = 1,
         kDefaultKeyRotationTime    = 672,
         kDefaultKeySwitchGuardTime = 624,
-        kMacKeyOffset              = 16,
         kOneHourIntervalInMsec     = 3600u * 1000u,
     };
 
-    void ComputeKey(uint32_t aKeySequence, uint8_t *aKey);
+    OT_TOOL_PACKED_BEGIN
+    struct Keys
+    {
+        Mle::Key mMleKey;
+        Mac::Key mMacKey;
+    } OT_TOOL_PACKED_END;
+
+    union HashKeys
+    {
+        uint8_t mHash[Crypto::HmacSha256::kHashSize];
+        Keys    mKeys;
+    };
+
+    void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys);
 
     void        StartKeyRotationTimer(void);
     static void HandleKeyRotationTimer(Timer &aTimer);
@@ -461,11 +466,9 @@
     MasterKey mMasterKey;
 
     uint32_t mKeySequence;
-    uint8_t  mKey[Crypto::HmacSha256::kHashSize];
+    Mle::Key mMleKey;
+    Mle::Key mTemporaryMleKey;
 
-    uint8_t mTemporaryKey[Crypto::HmacSha256::kHashSize];
-
-    uint32_t mMacFrameCounter;
     uint32_t mMleFrameCounter;
     uint32_t mStoredMacFrameCounter;
     uint32_t mStoredMleFrameCounter;
@@ -479,7 +482,7 @@
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
     Pskc mPskc;
 #endif
-    uint8_t  mKek[kMaxKeyLength];
+    Kek      mKek;
     uint32_t mKekFrameCounter;
 
     uint8_t mSecurityPolicyFlags;
diff --git a/src/core/thread/link_quality.cpp b/src/core/thread/link_quality.cpp
index 90f246f..6e49568 100644
--- a/src/core/thread/link_quality.cpp
+++ b/src/core/thread/link_quality.cpp
@@ -37,6 +37,7 @@
 
 #include "common/code_utils.hpp"
 #include "common/instance.hpp"
+#include "common/locator-getters.hpp"
 
 namespace ot {
 
@@ -132,8 +133,8 @@
 {
     InfoString string;
 
-    VerifyOrExit(mCount != 0);
-    string.Set("%d.%s", -(mAverage >> kPrecisionBitShift), kDigitsString[mAverage & kPrecisionBitMask]);
+    VerifyOrExit(mCount != 0, OT_NOOP);
+    IgnoreError(string.Set("%d.%s", -(mAverage >> kPrecisionBitShift), kDigitsString[mAverage & kPrecisionBitMask]));
 
 exit:
     return string;
@@ -149,11 +150,11 @@
     mMessageErrorRate.Reset();
 }
 
-void LinkQualityInfo::AddRss(int8_t aNoiseFloor, int8_t aRss)
+void LinkQualityInfo::AddRss(int8_t aRss)
 {
     uint8_t oldLinkQuality = kNoLinkQuality;
 
-    VerifyOrExit(aRss != OT_RADIO_RSSI_INVALID);
+    VerifyOrExit(aRss != OT_RADIO_RSSI_INVALID, OT_NOOP);
 
     mLastRss = aRss;
 
@@ -164,12 +165,17 @@
 
     SuccessOrExit(mRssAverager.Add(aRss));
 
-    SetLinkQuality(CalculateLinkQuality(GetLinkMargin(aNoiseFloor), oldLinkQuality));
+    SetLinkQuality(CalculateLinkQuality(GetLinkMargin(), oldLinkQuality));
 
 exit:
     return;
 }
 
+uint8_t LinkQualityInfo::GetLinkMargin(void) const
+{
+    return ConvertRssToLinkMargin(Get<Mac::SubMac>().GetNoiseFloor(), GetAverageRss());
+}
+
 LinkQualityInfo::InfoString LinkQualityInfo::ToInfoString(void) const
 {
     return InfoString("aveRss:%s, lastRss:%d, linkQuality:%d", mRssAverager.ToString().AsCString(), GetLastRss(),
diff --git a/src/core/thread/link_quality.hpp b/src/core/thread/link_quality.hpp
index 7cb9395..1f9f022 100644
--- a/src/core/thread/link_quality.hpp
+++ b/src/core/thread/link_quality.hpp
@@ -38,6 +38,7 @@
 
 #include <openthread/platform/radio.h>
 
+#include "common/locator.hpp"
 #include "common/string.hpp"
 
 namespace ot {
@@ -215,7 +216,7 @@
  * strength (RSS), last RSS, link margin, and link quality.
  *
  */
-class LinkQualityInfo
+class LinkQualityInfo : public InstanceLocatorInit
 {
 public:
     enum
@@ -230,6 +231,14 @@
     typedef String<kInfoStringSize> InfoString;
 
     /**
+     * This method initializes the `LinkQualityInfo` object.
+     *
+     * @param[in] aInstance  A reference to the OpenThread instance.
+     *
+     */
+    void Init(Instance &aInstance) { InstanceLocatorInit::Init(aInstance); }
+
+    /**
      * This method clears the all the data in the object.
      *
      */
@@ -238,11 +247,10 @@
     /**
      * This method adds a new received signal strength (RSS) value to the average.
      *
-     * @param[in] aNoiseFloor  The noise floor value (in dBm).
      * @param[in] aRss         A new received signal strength value (in dBm) to be added to the average.
      *
      */
-    void AddRss(int8_t aNoiseFloor, int8_t aRss);
+    void AddRss(int8_t aRss);
 
     /**
      * This method returns the current average received signal strength value.
@@ -273,12 +281,10 @@
      * This method returns the link margin. The link margin is calculated using the link's current average received
      * signal strength (RSS) and average noise floor.
      *
-     * @param[in]  aNoiseFloor  The noise floor value (in dBm).
-     *
      * @returns Link margin derived from average received signal strength and average noise floor.
      *
      */
-    uint8_t GetLinkMargin(int8_t aNoiseFloor) const { return ConvertRssToLinkMargin(aNoiseFloor, GetAverageRss()); }
+    uint8_t GetLinkMargin(void) const;
 
     /**
      * Returns the current one-way link quality value. The link quality value is a number 0-3.
@@ -291,8 +297,6 @@
      * frequent changes, a hysteresis of 2 dB is applied when determining the link quality. For example, the average
      * link margin must be at least 12 dB to change a quality 1 link to a quality 2 link.
      *
-     * @param[in]  aNoiseFloor  The noise floor value (in dBm).
-     *
      * @returns The current link quality value (value 0-3 as per Thread specification).
      *
      */
diff --git a/src/core/thread/lowpan.cpp b/src/core/thread/lowpan.cpp
index 75edcad..bd4850e 100644
--- a/src/core/thread/lowpan.cpp
+++ b/src/core/thread/lowpan.cpp
@@ -57,13 +57,7 @@
 
 void Lowpan::CopyContext(const Context &aContext, Ip6::Address &aAddress)
 {
-    memcpy(&aAddress, aContext.mPrefix, aContext.mPrefixLength / CHAR_BIT);
-
-    for (int i = (aContext.mPrefixLength & ~7); i < aContext.mPrefixLength; i++)
-    {
-        aAddress.mFields.m8[i / CHAR_BIT] &= ~(0x80 >> (i % CHAR_BIT));
-        aAddress.mFields.m8[i / CHAR_BIT] |= aContext.mPrefix[i / CHAR_BIT] & (0x80 >> (i % CHAR_BIT));
-    }
+    aAddress.SetPrefix(aContext.mPrefix, aContext.mPrefixLength);
 }
 
 otError Lowpan::ComputeIid(const Mac::Address &aMacAddr, const Context &aContext, Ip6::Address &aIpAddress)
@@ -73,14 +67,11 @@
     switch (aMacAddr.GetType())
     {
     case Mac::Address::kTypeShort:
-        aIpAddress.mFields.m16[4] = HostSwap16(0x0000);
-        aIpAddress.mFields.m16[5] = HostSwap16(0x00ff);
-        aIpAddress.mFields.m16[6] = HostSwap16(0xfe00);
-        aIpAddress.mFields.m16[7] = HostSwap16(aMacAddr.GetShort());
+        aIpAddress.GetIid().SetToLocator(aMacAddr.GetShort());
         break;
 
     case Mac::Address::kTypeExtended:
-        aIpAddress.SetIid(aMacAddr.GetExtended());
+        aIpAddress.GetIid().SetFromExtAddress(aMacAddr.GetExtended());
         break;
 
     default:
@@ -111,18 +102,18 @@
     Ip6::Address ipaddr;
     Mac::Address tmp;
 
-    ComputeIid(aMacAddr, aContext, ipaddr);
+    IgnoreError(ComputeIid(aMacAddr, aContext, ipaddr));
 
-    if (memcmp(ipaddr.GetIid(), aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize) == 0)
+    if (ipaddr.GetIid() == aIpAddr.GetIid())
     {
         aHcCtl |= kHcSrcAddrMode3;
     }
     else
     {
-        tmp.SetShort(HostSwap16(aIpAddr.mFields.m16[7]));
-        ComputeIid(tmp, aContext, ipaddr);
+        tmp.SetShort(aIpAddr.GetIid().GetLocator());
+        IgnoreError(ComputeIid(tmp, aContext, ipaddr));
 
-        if (memcmp(ipaddr.GetIid(), aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize) == 0)
+        if (ipaddr.GetIid() == aIpAddr.GetIid())
         {
             aHcCtl |= kHcSrcAddrMode2;
             SuccessOrExit(error = buf.Write(aIpAddr.mFields.m8 + 14, 2));
@@ -130,7 +121,7 @@
         else
         {
             aHcCtl |= kHcSrcAddrMode1;
-            SuccessOrExit(error = buf.Write(aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize));
+            SuccessOrExit(error = buf.Write(aIpAddr.GetIid().GetBytes(), Ip6::InterfaceIdentifier::kSize));
         }
     }
 
@@ -154,18 +145,18 @@
     Ip6::Address ipaddr;
     Mac::Address tmp;
 
-    ComputeIid(aMacAddr, aContext, ipaddr);
+    IgnoreError(ComputeIid(aMacAddr, aContext, ipaddr));
 
-    if (memcmp(ipaddr.GetIid(), aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize) == 0)
+    if (ipaddr.GetIid() == aIpAddr.GetIid())
     {
         aHcCtl |= kHcDstAddrMode3;
     }
     else
     {
-        tmp.SetShort(HostSwap16(aIpAddr.mFields.m16[7]));
-        ComputeIid(tmp, aContext, ipaddr);
+        tmp.SetShort(aIpAddr.GetIid().GetLocator());
+        IgnoreError(ComputeIid(tmp, aContext, ipaddr));
 
-        if (memcmp(ipaddr.GetIid(), aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize) == 0)
+        if (ipaddr.GetIid() == aIpAddr.GetIid())
         {
             aHcCtl |= kHcDstAddrMode2;
             SuccessOrExit(error = buf.Write(aIpAddr.mFields.m8 + 14, 2));
@@ -173,7 +164,7 @@
         else
         {
             aHcCtl |= kHcDstAddrMode1;
-            SuccessOrExit(error = buf.Write(aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize));
+            SuccessOrExit(error = buf.Write(aIpAddr.GetIid().GetBytes(), Ip6::InterfaceIdentifier::kSize));
         }
     }
 
@@ -253,11 +244,28 @@
                          const Mac::Address &aMacDest,
                          BufferWriter &      aBuf)
 {
+    otError error;
+    uint8_t headerDepth = 0xff;
+
+    do
+    {
+        error = Compress(aMessage, aMacSource, aMacDest, aBuf, headerDepth);
+    } while ((error != OT_ERROR_NONE) && (headerDepth > 0));
+
+    return error;
+}
+
+otError Lowpan::Compress(Message &           aMessage,
+                         const Mac::Address &aMacSource,
+                         const Mac::Address &aMacDest,
+                         BufferWriter &      aBuf,
+                         uint8_t &           aHeaderDepth)
+{
     otError              error       = OT_ERROR_NONE;
     NetworkData::Leader &networkData = Get<NetworkData::Leader>();
     uint16_t             startOffset = aMessage.GetOffset();
     BufferWriter         buf         = aBuf;
-    uint16_t             hcCtl;
+    uint16_t             hcCtl       = kHcDispatch;
     Ip6::Header          ip6Header;
     uint8_t *            ip6HeaderBytes = reinterpret_cast<uint8_t *>(&ip6Header);
     Context              srcContext, dstContext;
@@ -265,13 +273,8 @@
     uint8_t              nextHeader;
     uint8_t              ecn;
     uint8_t              dscp;
-    uint8_t              headerDepth;
-    uint8_t              headerMaxDepth = 0xff;
-
-compress:
-
-    headerDepth = 0;
-    hcCtl       = kHcDispatch;
+    uint8_t              headerDepth    = 0;
+    uint8_t              headerMaxDepth = aHeaderDepth;
 
     VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(ip6Header), &ip6Header) == sizeof(ip6Header),
                  error = OT_ERROR_PARSE);
@@ -281,7 +284,7 @@
 
     if (!srcContextValid)
     {
-        networkData.GetContext(0, srcContext);
+        IgnoreError(networkData.GetContext(0, srcContext));
     }
 
     dstContextValid =
@@ -289,7 +292,7 @@
 
     if (!dstContextValid)
     {
-        networkData.GetContext(0, dstContext);
+        IgnoreError(networkData.GetContext(0, dstContext));
     }
 
     // Lowpan HC Control Bits
@@ -447,22 +450,17 @@
     }
 
 exit:
+    aHeaderDepth = headerDepth;
+
     if (error == OT_ERROR_NONE)
     {
-        IgnoreReturnValue(aBuf.Write(hcCtl >> 8));
-        IgnoreReturnValue(aBuf.Write(hcCtl & 0xff));
+        IgnoreError(aBuf.Write(hcCtl >> 8));
+        IgnoreError(aBuf.Write(hcCtl & 0xff));
         aBuf = buf;
     }
     else
     {
         aMessage.SetOffset(startOffset);
-
-        if (headerDepth > 0)
-        {
-            buf            = aBuf;
-            headerMaxDepth = headerDepth;
-            goto compress;
-        }
     }
 
     return error;
@@ -474,10 +472,8 @@
     BufferWriter         buf         = aBuf;
     uint16_t             startOffset = aMessage.GetOffset();
     Ip6::ExtensionHeader extHeader;
-    Ip6::OptionHeader    optionHeader;
-    uint8_t              len;
+    uint16_t             len;
     uint8_t              padLength = 0;
-    uint16_t             offset;
     uint8_t              tmpByte;
 
     VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(extHeader), &extHeader) == sizeof(extHeader),
@@ -503,15 +499,19 @@
 
     len = (extHeader.GetLength() + 1) * 8 - sizeof(extHeader);
 
+    // RFC 6282 does not support compressing large extension headers
+    VerifyOrExit(len <= kExtHdrMaxLength, error = OT_ERROR_FAILED);
+
     // RFC 6282 says: "IPv6 Hop-by-Hop and Destination Options Headers may use a trailing
     // Pad1 or PadN to achieve 8-octet alignment. When there is a single trailing Pad1 or PadN
     // option of 7 octets or less and the containing header is a multiple of 8 octets, the trailing
     // Pad1 or PadN option MAY be elided by the compressor."
     if (aNextHeader == Ip6::kProtoHopOpts || aNextHeader == Ip6::kProtoDstOpts)
     {
-        offset = aMessage.GetOffset();
+        uint16_t          offset = aMessage.GetOffset();
+        Ip6::OptionHeader optionHeader;
 
-        while (offset < len + aMessage.GetOffset())
+        while ((offset - aMessage.GetOffset()) < len)
         {
             VerifyOrExit(aMessage.Read(offset, sizeof(optionHeader), &optionHeader) == sizeof(optionHeader),
                          error = OT_ERROR_PARSE);
@@ -543,8 +543,8 @@
 
     aNextHeader = static_cast<uint8_t>(extHeader.GetNextHeader());
 
-    SuccessOrExit(error = buf.Write(len));
-    SuccessOrExit(error = buf.Write(aMessage, len));
+    SuccessOrExit(error = buf.Write(static_cast<uint8_t>(len)));
+    SuccessOrExit(error = buf.Write(aMessage, static_cast<uint8_t>(len)));
     aMessage.MoveOffset(len + padLength);
 
 exit:
@@ -562,12 +562,12 @@
 
 otError Lowpan::CompressUdp(Message &aMessage, BufferWriter &aBuf)
 {
-    otError        error       = OT_ERROR_NONE;
-    BufferWriter   buf         = aBuf;
-    uint16_t       startOffset = aMessage.GetOffset();
-    Ip6::UdpHeader udpHeader;
-    uint16_t       source;
-    uint16_t       destination;
+    otError          error       = OT_ERROR_NONE;
+    BufferWriter     buf         = aBuf;
+    uint16_t         startOffset = aMessage.GetOffset();
+    Ip6::Udp::Header udpHeader;
+    uint16_t         source;
+    uint16_t         destination;
 
     VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(udpHeader), &udpHeader) == sizeof(udpHeader),
                  error = OT_ERROR_PARSE);
@@ -597,10 +597,11 @@
     else
     {
         SuccessOrExit(error = buf.Write(kUdpDispatch));
-        SuccessOrExit(error = buf.Write(&udpHeader, Ip6::UdpHeader::GetLengthOffset()));
+        SuccessOrExit(error = buf.Write(&udpHeader, Ip6::Udp::Header::kLengthFieldOffset));
     }
 
-    SuccessOrExit(error = buf.Write(reinterpret_cast<uint8_t *>(&udpHeader) + Ip6::UdpHeader::GetChecksumOffset(), 2));
+    SuccessOrExit(error =
+                      buf.Write(reinterpret_cast<uint8_t *>(&udpHeader) + Ip6::Udp::Header::kChecksumFieldOffset, 2));
 
     aMessage.MoveOffset(sizeof(udpHeader));
 
@@ -675,12 +676,12 @@
     uint8_t              nextHeader;
     uint8_t *            bytes;
 
-    VerifyOrExit(cur + 2 <= end);
+    VerifyOrExit(cur + 2 <= end, OT_NOOP);
     hcCtl = ReadUint16(cur);
     cur += 2;
 
     // check Dispatch bits
-    VerifyOrExit((hcCtl & kHcDispatchMask) == kHcDispatch);
+    VerifyOrExit((hcCtl & kHcDispatchMask) == kHcDispatch, OT_NOOP);
 
     // Context Identifier
     srcContext.mPrefixLength = 0;
@@ -688,7 +689,7 @@
 
     if ((hcCtl & kHcContextId) != 0)
     {
-        VerifyOrExit(cur < end);
+        VerifyOrExit(cur < end, OT_NOOP);
 
         if (networkData.GetContext(cur[0] >> 4, srcContext) != OT_ERROR_NONE)
         {
@@ -704,8 +705,8 @@
     }
     else
     {
-        networkData.GetContext(0, srcContext);
-        networkData.GetContext(0, dstContext);
+        IgnoreError(networkData.GetContext(0, srcContext));
+        IgnoreError(networkData.GetContext(0, dstContext));
     }
 
     memset(&aIp6Header, 0, sizeof(aIp6Header));
@@ -714,7 +715,7 @@
     // Traffic Class and Flow Label
     if ((hcCtl & kHcTrafficFlowMask) != kHcTrafficFlow)
     {
-        VerifyOrExit(cur < end);
+        VerifyOrExit(cur < end, OT_NOOP);
 
         bytes = reinterpret_cast<uint8_t *>(&aIp6Header);
         bytes[1] |= (cur[0] & 0xc0) >> 2;
@@ -728,7 +729,7 @@
 
         if ((hcCtl & kHcFlowLabel) == 0)
         {
-            VerifyOrExit(cur + 3 <= end);
+            VerifyOrExit(cur + 3 <= end, OT_NOOP);
             bytes[1] |= cur[0] & 0x0f;
             bytes[2] |= cur[1];
             bytes[3] |= cur[2];
@@ -739,7 +740,7 @@
     // Next Header
     if ((hcCtl & kHcNextHeader) == 0)
     {
-        VerifyOrExit(cur < end);
+        VerifyOrExit(cur < end, OT_NOOP);
         aIp6Header.SetNextHeader(cur[0]);
         cur++;
         aCompressedNextHeader = false;
@@ -765,7 +766,7 @@
         break;
 
     default:
-        VerifyOrExit(cur < end);
+        VerifyOrExit(cur < end, OT_NOOP);
         aIp6Header.SetHopLimit(cur[0]);
         cur++;
         break;
@@ -777,7 +778,7 @@
     case kHcSrcAddrMode0:
         if ((hcCtl & kHcSrcAddrContext) == 0)
         {
-            VerifyOrExit(cur + sizeof(Ip6::Address) <= end);
+            VerifyOrExit(cur + sizeof(Ip6::Address) <= end, OT_NOOP);
             memcpy(&aIp6Header.GetSource(), cur, sizeof(aIp6Header.GetSource()));
             cur += sizeof(Ip6::Address);
         }
@@ -785,13 +786,13 @@
         break;
 
     case kHcSrcAddrMode1:
-        VerifyOrExit(cur + Ip6::Address::kInterfaceIdentifierSize <= end);
-        aIp6Header.GetSource().SetIid(cur);
-        cur += Ip6::Address::kInterfaceIdentifierSize;
+        VerifyOrExit(cur + Ip6::InterfaceIdentifier::kSize <= end, OT_NOOP);
+        aIp6Header.GetSource().GetIid().SetBytes(cur);
+        cur += Ip6::InterfaceIdentifier::kSize;
         break;
 
     case kHcSrcAddrMode2:
-        VerifyOrExit(cur + 2 <= end);
+        VerifyOrExit(cur + 2 <= end, OT_NOOP);
         aIp6Header.GetSource().mFields.m8[11] = 0xff;
         aIp6Header.GetSource().mFields.m8[12] = 0xfe;
         memcpy(aIp6Header.GetSource().mFields.m8 + 14, cur, 2);
@@ -799,7 +800,7 @@
         break;
 
     case kHcSrcAddrMode3:
-        ComputeIid(aMacSource, srcContext, aIp6Header.GetSource());
+        IgnoreError(ComputeIid(aMacSource, srcContext, aIp6Header.GetSource()));
         break;
     }
 
@@ -811,7 +812,7 @@
         }
         else
         {
-            VerifyOrExit(srcContextValid);
+            VerifyOrExit(srcContextValid, OT_NOOP);
             CopyContext(srcContext, aIp6Header.GetSource());
         }
     }
@@ -823,20 +824,20 @@
         switch (hcCtl & kHcDstAddrModeMask)
         {
         case kHcDstAddrMode0:
-            VerifyOrExit((hcCtl & kHcDstAddrContext) == 0);
-            VerifyOrExit(cur + sizeof(Ip6::Address) <= end);
+            VerifyOrExit((hcCtl & kHcDstAddrContext) == 0, OT_NOOP);
+            VerifyOrExit(cur + sizeof(Ip6::Address) <= end, OT_NOOP);
             memcpy(&aIp6Header.GetDestination(), cur, sizeof(aIp6Header.GetDestination()));
             cur += sizeof(Ip6::Address);
             break;
 
         case kHcDstAddrMode1:
-            VerifyOrExit(cur + Ip6::Address::kInterfaceIdentifierSize <= end);
-            aIp6Header.GetDestination().SetIid(cur);
-            cur += Ip6::Address::kInterfaceIdentifierSize;
+            VerifyOrExit(cur + Ip6::InterfaceIdentifier::kSize <= end, OT_NOOP);
+            aIp6Header.GetDestination().GetIid().SetBytes(cur);
+            cur += Ip6::InterfaceIdentifier::kSize;
             break;
 
         case kHcDstAddrMode2:
-            VerifyOrExit(cur + 2 <= end);
+            VerifyOrExit(cur + 2 <= end, OT_NOOP);
             aIp6Header.GetDestination().mFields.m8[11] = 0xff;
             aIp6Header.GetDestination().mFields.m8[12] = 0xfe;
             memcpy(aIp6Header.GetDestination().mFields.m8 + 14, cur, 2);
@@ -857,7 +858,7 @@
         }
         else
         {
-            VerifyOrExit(dstContextValid);
+            VerifyOrExit(dstContextValid, OT_NOOP);
             CopyContext(dstContext, aIp6Header.GetDestination());
         }
     }
@@ -872,27 +873,27 @@
             switch (hcCtl & kHcDstAddrModeMask)
             {
             case kHcDstAddrMode0:
-                VerifyOrExit(cur + sizeof(Ip6::Address) <= end);
+                VerifyOrExit(cur + sizeof(Ip6::Address) <= end, OT_NOOP);
                 memcpy(aIp6Header.GetDestination().mFields.m8, cur, sizeof(Ip6::Address));
                 cur += sizeof(Ip6::Address);
                 break;
 
             case kHcDstAddrMode1:
-                VerifyOrExit(cur + 6 <= end);
+                VerifyOrExit(cur + 6 <= end, OT_NOOP);
                 aIp6Header.GetDestination().mFields.m8[1] = cur[0];
                 memcpy(aIp6Header.GetDestination().mFields.m8 + 11, cur + 1, 5);
                 cur += 6;
                 break;
 
             case kHcDstAddrMode2:
-                VerifyOrExit(cur + 4 <= end);
+                VerifyOrExit(cur + 4 <= end, OT_NOOP);
                 aIp6Header.GetDestination().mFields.m8[1] = cur[0];
                 memcpy(aIp6Header.GetDestination().mFields.m8 + 13, cur + 1, 3);
                 cur += 4;
                 break;
 
             case kHcDstAddrMode3:
-                VerifyOrExit(cur < end);
+                VerifyOrExit(cur < end, OT_NOOP);
                 aIp6Header.GetDestination().mFields.m8[1]  = 0x02;
                 aIp6Header.GetDestination().mFields.m8[15] = cur[0];
                 cur++;
@@ -904,8 +905,8 @@
             switch (hcCtl & kHcDstAddrModeMask)
             {
             case 0:
-                VerifyOrExit(cur + 6 <= end);
-                VerifyOrExit(dstContextValid);
+                VerifyOrExit(cur + 6 <= end, OT_NOOP);
+                VerifyOrExit(dstContextValid, OT_NOOP);
                 aIp6Header.GetDestination().mFields.m8[1] = cur[0];
                 aIp6Header.GetDestination().mFields.m8[2] = cur[1];
                 aIp6Header.GetDestination().mFields.m8[3] = dstContext.mPrefixLength;
@@ -922,7 +923,7 @@
 
     if ((hcCtl & kHcNextHeader) != 0)
     {
-        VerifyOrExit(cur < end);
+        VerifyOrExit(cur < end, OT_NOOP);
         SuccessOrExit(DispatchToNextHeader(cur[0], nextHeader));
         aIp6Header.SetNextHeader(nextHeader);
     }
@@ -946,30 +947,30 @@
     Ip6::OptionPad1 optionPad1;
     Ip6::OptionPadN optionPadN;
 
-    VerifyOrExit(cur < end);
+    VerifyOrExit(cur < end, OT_NOOP);
     cur++;
 
     // next header
     if (ctl & kExtHdrNextHeader)
     {
-        VerifyOrExit(cur < end);
+        VerifyOrExit(cur < end, OT_NOOP);
 
         len = cur[0];
         cur++;
 
-        VerifyOrExit(cur + len <= end);
+        VerifyOrExit(cur + len <= end, OT_NOOP);
         SuccessOrExit(DispatchToNextHeader(cur[len], nextHeader));
         hdr[0] = static_cast<uint8_t>(nextHeader);
     }
     else
     {
-        VerifyOrExit(cur + 2 <= end);
+        VerifyOrExit(cur + 2 <= end, OT_NOOP);
 
         hdr[0] = cur[0];
         len    = cur[1];
         cur += 2;
 
-        VerifyOrExit(cur + len <= end);
+        VerifyOrExit(cur + len <= end, OT_NOOP);
     }
 
     // length
@@ -1010,18 +1011,18 @@
     return (error == OT_ERROR_NONE) ? static_cast<int>(cur - aBuf) : -1;
 }
 
-int Lowpan::DecompressUdpHeader(Ip6::UdpHeader &aUdpHeader, const uint8_t *aBuf, uint16_t aBufLength)
+int Lowpan::DecompressUdpHeader(Ip6::Udp::Header &aUdpHeader, const uint8_t *aBuf, uint16_t aBufLength)
 {
     otError        error = OT_ERROR_PARSE;
     const uint8_t *cur   = aBuf;
     const uint8_t *end   = aBuf + aBufLength;
     uint8_t        udpCtl;
 
-    VerifyOrExit(cur < end);
+    VerifyOrExit(cur < end, OT_NOOP);
     udpCtl = cur[0];
     cur++;
 
-    VerifyOrExit((udpCtl & kUdpDispatchMask) == kUdpDispatch);
+    VerifyOrExit((udpCtl & kUdpDispatchMask) == kUdpDispatch, OT_NOOP);
 
     memset(&aUdpHeader, 0, sizeof(aUdpHeader));
 
@@ -1029,28 +1030,28 @@
     switch (udpCtl & kUdpPortMask)
     {
     case 0:
-        VerifyOrExit(cur + 4 <= end);
+        VerifyOrExit(cur + 4 <= end, OT_NOOP);
         aUdpHeader.SetSourcePort(ReadUint16(cur));
         aUdpHeader.SetDestinationPort(ReadUint16(cur + 2));
         cur += 4;
         break;
 
     case 1:
-        VerifyOrExit(cur + 3 <= end);
+        VerifyOrExit(cur + 3 <= end, OT_NOOP);
         aUdpHeader.SetSourcePort(ReadUint16(cur));
         aUdpHeader.SetDestinationPort(0xf000 | cur[2]);
         cur += 3;
         break;
 
     case 2:
-        VerifyOrExit(cur + 3 <= end);
+        VerifyOrExit(cur + 3 <= end, OT_NOOP);
         aUdpHeader.SetSourcePort(0xf000 | cur[0]);
         aUdpHeader.SetDestinationPort(ReadUint16(cur + 1));
         cur += 3;
         break;
 
     case 3:
-        VerifyOrExit(cur < end);
+        VerifyOrExit(cur < end, OT_NOOP);
         aUdpHeader.SetSourcePort(0xf0b0 | (cur[0] >> 4));
         aUdpHeader.SetDestinationPort(0xf0b0 | (cur[0] & 0xf));
         cur++;
@@ -1064,7 +1065,7 @@
     }
     else
     {
-        VerifyOrExit(cur + 2 <= end);
+        VerifyOrExit(cur + 2 <= end, OT_NOOP);
         aUdpHeader.SetChecksum(ReadUint16(cur));
         cur += 2;
     }
@@ -1077,11 +1078,11 @@
 
 int Lowpan::DecompressUdpHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength, uint16_t aDatagramLength)
 {
-    Ip6::UdpHeader udpHeader;
-    int            headerLen = -1;
+    Ip6::Udp::Header udpHeader;
+    int              headerLen = -1;
 
     headerLen = DecompressUdpHeader(udpHeader, aBuf, aBufLength);
-    VerifyOrExit(headerLen >= 0);
+    VerifyOrExit(headerLen >= 0, OT_NOOP);
 
     // length
     if (aDatagramLength == 0)
@@ -1117,18 +1118,19 @@
     uint16_t       compressedLength = 0;
     uint16_t       currentOffset    = aMessage.GetOffset();
 
-    VerifyOrExit(remaining >= 2);
-    VerifyOrExit((rval = DecompressBaseHeader(ip6Header, compressed, aMacSource, aMacDest, cur, remaining)) >= 0);
+    VerifyOrExit(remaining >= 2, OT_NOOP);
+    VerifyOrExit((rval = DecompressBaseHeader(ip6Header, compressed, aMacSource, aMacDest, cur, remaining)) >= 0,
+                 OT_NOOP);
 
     cur += rval;
     remaining -= rval;
 
     SuccessOrExit(aMessage.Append(&ip6Header, sizeof(ip6Header)));
-    SuccessOrExit(aMessage.MoveOffset(sizeof(ip6Header)));
+    aMessage.MoveOffset(sizeof(ip6Header));
 
     while (compressed)
     {
-        VerifyOrExit(remaining >= 1);
+        VerifyOrExit(remaining >= 1, OT_NOOP);
 
         if ((cur[0] & kExtHdrDispatchMask) == kExtHdrDispatch)
         {
@@ -1139,25 +1141,26 @@
                 cur++;
                 remaining--;
 
-                VerifyOrExit((rval = Decompress(aMessage, aMacSource, aMacDest, cur, remaining, aDatagramLength)) >= 0);
+                VerifyOrExit((rval = Decompress(aMessage, aMacSource, aMacDest, cur, remaining, aDatagramLength)) >= 0,
+                             OT_NOOP);
             }
             else
             {
                 compressed = (cur[0] & kExtHdrNextHeader) != 0;
-                VerifyOrExit((rval = DecompressExtensionHeader(aMessage, cur, remaining)) >= 0);
+                VerifyOrExit((rval = DecompressExtensionHeader(aMessage, cur, remaining)) >= 0, OT_NOOP);
             }
         }
         else if ((cur[0] & kUdpDispatchMask) == kUdpDispatch)
         {
             compressed = false;
-            VerifyOrExit((rval = DecompressUdpHeader(aMessage, cur, remaining, aDatagramLength)) >= 0);
+            VerifyOrExit((rval = DecompressUdpHeader(aMessage, cur, remaining, aDatagramLength)) >= 0, OT_NOOP);
         }
         else
         {
             ExitNow();
         }
 
-        VerifyOrExit(remaining >= rval);
+        VerifyOrExit(remaining >= rval, OT_NOOP);
         cur += rval;
         remaining -= rval;
     }
@@ -1202,16 +1205,17 @@
     otError error = OT_ERROR_PARSE;
     uint8_t dispatch;
 
-    VerifyOrExit(aFrameLength >= kMinHeaderLength);
+    VerifyOrExit(aFrameLength >= kMinHeaderLength, OT_NOOP);
     dispatch = *aFrame++;
 
-    VerifyOrExit((dispatch & (kDispatchMask | kSourceShort | kDestShort)) == (kDispatch | kSourceShort | kDestShort));
+    VerifyOrExit((dispatch & (kDispatchMask | kSourceShort | kDestShort)) == (kDispatch | kSourceShort | kDestShort),
+                 OT_NOOP);
 
     mHopsLeft = (dispatch & kHopsLeftMask);
 
     if (mHopsLeft == kDeepHopsLeft)
     {
-        VerifyOrExit(aFrameLength >= kDeepHopsHeaderLength);
+        VerifyOrExit(aFrameLength >= kDeepHopsHeaderLength, OT_NOOP);
         mHopsLeft     = *aFrame++;
         aHeaderLength = kDeepHopsHeaderLength;
     }
@@ -1313,14 +1317,14 @@
 {
     otError error = OT_ERROR_PARSE;
 
-    VerifyOrExit(IsFragmentHeader(aFrame, aFrameLength));
+    VerifyOrExit(IsFragmentHeader(aFrame, aFrameLength), OT_NOOP);
 
     mSize = ReadUint16(aFrame + kSizeIndex) & kSizeMask;
     mTag  = ReadUint16(aFrame + kTagIndex);
 
     if ((*aFrame & kOffsetFlag) == kOffsetFlag)
     {
-        VerifyOrExit(aFrameLength >= kSubsequentFragmentHeaderSize);
+        VerifyOrExit(aFrameLength >= kSubsequentFragmentHeaderSize, OT_NOOP);
         mOffset       = aFrame[kOffsetIndex] * 8;
         aHeaderLength = kSubsequentFragmentHeaderSize;
     }
diff --git a/src/core/thread/lowpan.hpp b/src/core/thread/lowpan.hpp
index 8dd0a7e..13bf9a4 100644
--- a/src/core/thread/lowpan.hpp
+++ b/src/core/thread/lowpan.hpp
@@ -197,10 +197,12 @@
         otError error = OT_ERROR_NONE;
         int     rval;
 
+        OT_UNUSED_VARIABLE(rval);
+
         VerifyOrExit(CanWrite(aLength), error = OT_ERROR_NO_BUFS);
 
         rval = aMessage.Read(aMessage.GetOffset(), aLength, mWritePointer);
-        assert(rval == aLength);
+        OT_ASSERT(rval == aLength);
 
         mWritePointer += aLength;
 
@@ -307,7 +309,7 @@
      * @returns The size of the compressed header in bytes or -1 if decompression fails.
      *
      */
-    int DecompressUdpHeader(Ip6::UdpHeader &aUdpHeader, const uint8_t *aBuf, uint16_t aBufLength);
+    int DecompressUdpHeader(Ip6::Udp::Header &aUdpHeader, const uint8_t *aBuf, uint16_t aBufLength);
 
 private:
     enum
@@ -351,6 +353,7 @@
         kExtHdrEidMask     = 0x0e,
 
         kExtHdrNextHeader = 0x01,
+        kExtHdrMaxLength  = 255,
 
         kUdpDispatch     = 0xf0,
         kUdpDispatchMask = 0xf8,
@@ -358,6 +361,12 @@
         kUdpPortMask     = 3 << 0,
     };
 
+    otError Compress(Message &           aMessage,
+                     const Mac::Address &aMacSource,
+                     const Mac::Address &aMacDest,
+                     BufferWriter &      aBuf,
+                     uint8_t &           aHeaderDepth);
+
     otError CompressExtensionHeader(Message &aMessage, BufferWriter &aBuf, uint8_t &aNextHeader);
     otError CompressSourceIid(const Mac::Address &aMacAddr,
                               const Ip6::Address &aIpAddr,
@@ -560,7 +569,7 @@
      * A first fragment header starts at offset zero.
      *
      * @param[in] aSize   The Datagram Size value.
-     * @param[in] aTage   The Datagram Tag value.
+     * @param[in] aTag    The Datagram Tag value.
      *
      */
     void InitFirstFragment(uint16_t aSize, uint16_t aTag) { Init(aSize, aTag, 0); }
@@ -571,7 +580,7 @@
      * The @p aOffset value will be truncated to become a multiple of 8.
      *
      * @param[in] aSize   The Datagram Size value.
-     * @param[in] aTage   The Datagram Tag value.
+     * @param[in] aTag    The Datagram Tag value.
      * @param[in] aOffset The Datagram Offset value.
      *
      */
diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp
index b4691f0..b15ff3b 100644
--- a/src/core/thread/mesh_forwarder.cpp
+++ b/src/core/thread/mesh_forwarder.cpp
@@ -57,20 +57,16 @@
 
 MeshForwarder::MeshForwarder(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mDiscoverTimer(aInstance, &MeshForwarder::HandleDiscoverTimer, this)
-    , mUpdateTimer(aInstance, &MeshForwarder::HandleUpdateTimer, this)
+    , mUpdateTimer(aInstance, MeshForwarder::HandleUpdateTimer, this)
     , mMessageNextOffset(0)
-    , mSendMessage(NULL)
+    , mSendMessage(nullptr)
     , mMeshSource()
     , mMeshDest()
     , mAddMeshHeader(false)
-    , mSendBusy(false)
-    , mScheduleTransmissionTask(aInstance, ScheduleTransmissionTask, this)
     , mEnabled(false)
-    , mScanChannels(0)
-    , mScanChannel(0)
-    , mRestorePanId(Mac::kPanIdBroadcast)
-    , mScanning(false)
+    , mTxPaused(false)
+    , mSendBusy(false)
+    , mScheduleTransmissionTask(aInstance, MeshForwarder::ScheduleTransmissionTask, this)
 #if OPENTHREAD_FTD
     , mIndirectSender(aInstance)
 #endif
@@ -102,23 +98,19 @@
 {
     Message *message;
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     mDataPollSender.StopPolling();
     mUpdateTimer.Stop();
+    Get<Mle::DiscoverScanner>().Stop();
 
-    if (mScanning)
-    {
-        HandleDiscoverComplete();
-    }
-
-    while ((message = mSendQueue.GetHead()) != NULL)
+    while ((message = mSendQueue.GetHead()) != nullptr)
     {
         mSendQueue.Dequeue(*message);
         message->Free();
     }
 
-    while ((message = mReassemblyList.GetHead()) != NULL)
+    while ((message = mReassemblyList.GetHead()) != nullptr)
     {
         mReassemblyList.Dequeue(*message);
         message->Free();
@@ -130,7 +122,7 @@
 #endif
 
     mEnabled     = false;
-    mSendMessage = NULL;
+    mSendMessage = nullptr;
     Get<Mac::Mac>().SetRxOnWhenIdle(false);
 
 exit:
@@ -139,23 +131,39 @@
 
 void MeshForwarder::RemoveMessage(Message &aMessage)
 {
-#if OPENTHREAD_FTD
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateAnyExceptInvalid); !iter.IsDone(); iter++)
+    PriorityQueue *queue = aMessage.GetPriorityQueue();
+
+    OT_ASSERT(queue != nullptr);
+
+    if (queue == &mSendQueue)
     {
-        IgnoreReturnValue(mIndirectSender.RemoveMessageFromSleepyChild(aMessage, *iter.GetChild()));
-    }
+#if OPENTHREAD_FTD
+        for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
+        {
+            IgnoreError(mIndirectSender.RemoveMessageFromSleepyChild(aMessage, child));
+        }
 #endif
 
-    if (mSendMessage == &aMessage)
-    {
-        mSendMessage = NULL;
+        if (mSendMessage == &aMessage)
+        {
+            mSendMessage = nullptr;
+        }
     }
 
-    mSendQueue.Dequeue(aMessage);
-    LogMessage(kMessageEvict, aMessage, NULL, OT_ERROR_NO_BUFS);
+    queue->Dequeue(aMessage);
+    LogMessage(kMessageEvict, aMessage, nullptr, OT_ERROR_NO_BUFS);
     aMessage.Free();
 }
 
+void MeshForwarder::ResumeMessageTransmissions(void)
+{
+    if (mTxPaused)
+    {
+        mTxPaused = false;
+        mScheduleTransmissionTask.Post();
+    }
+}
+
 void MeshForwarder::ScheduleTransmissionTask(Tasklet &aTasklet)
 {
     aTasklet.GetOwner<MeshForwarder>().ScheduleTransmissionTask();
@@ -163,10 +171,10 @@
 
 void MeshForwarder::ScheduleTransmissionTask(void)
 {
-    VerifyOrExit(!mSendBusy);
+    VerifyOrExit(!mSendBusy && !mTxPaused, OT_NOOP);
 
     mSendMessage = GetDirectTransmission();
-    VerifyOrExit(mSendMessage != NULL);
+    VerifyOrExit(mSendMessage != nullptr, OT_NOOP);
 
     if (mSendMessage->GetOffset() == 0)
     {
@@ -179,27 +187,6 @@
     return;
 }
 
-otError MeshForwarder::PrepareDiscoverRequest(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(!mScanning);
-
-    mScanChannel  = Mac::ChannelMask::kChannelIteratorFirst;
-    mRestorePanId = Get<Mac::Mac>().GetPanId();
-
-    mScanning = true;
-
-    if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE)
-    {
-        HandleDiscoverComplete();
-        ExitNow(error = OT_ERROR_DROP);
-    }
-
-exit:
-    return error;
-}
-
 Message *MeshForwarder::GetDirectTransmission(void)
 {
     Message *curMessage, *nextMessage;
@@ -219,12 +206,6 @@
         {
         case Message::kTypeIp6:
             error = UpdateIp6Route(*curMessage);
-
-            if (curMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)
-            {
-                error = PrepareDiscoverRequest();
-            }
-
             break;
 
 #if OPENTHREAD_FTD
@@ -261,7 +242,7 @@
 
         default:
             mSendQueue.Dequeue(*curMessage);
-            LogMessage(kMessageDrop, *curMessage, NULL, error);
+            LogMessage(kMessageDrop, *curMessage, nullptr, error);
             curMessage->Free();
             continue;
         }
@@ -285,7 +266,7 @@
 
     GetMacSourceAddress(ip6Header.GetSource(), mMacSource);
 
-    if (mle.GetRole() == OT_DEVICE_ROLE_DISABLED || mle.GetRole() == OT_DEVICE_ROLE_DETACHED)
+    if (mle.IsDisabled() || mle.IsDetached())
     {
         if (ip6Header.GetDestination().IsLinkLocal() || ip6Header.GetDestination().IsLinkLocalMulticast())
         {
@@ -305,7 +286,7 @@
         // transmits multicasts, as IEEE 802.15.4 unicasts to its
         // parent.
 
-        if (mle.GetRole() == OT_DEVICE_ROLE_CHILD && !aMessage.IsSubTypeMle())
+        if (mle.IsChild() && !aMessage.IsSubTypeMle())
         {
             mMacDest.SetShort(mle.GetNextHop(Mac::kShortAddrBroadcast));
         }
@@ -325,9 +306,9 @@
     else
     {
 #if OPENTHREAD_FTD
-        error = UpdateIp6RouteFtd(ip6Header);
+        error = UpdateIp6RouteFtd(ip6Header, aMessage);
 #else
-        assert(false);
+        OT_ASSERT(false);
 #endif
     }
 
@@ -358,7 +339,7 @@
 
 void MeshForwarder::GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr)
 {
-    aIp6Addr.ToExtAddress(aMacAddr);
+    aIp6Addr.GetIid().ConvertToMacAddress(aMacAddr);
 
     if (aMacAddr.GetExtended() != Get<Mac::Mac>().GetExtAddress())
     {
@@ -372,20 +353,13 @@
     {
         aMacAddr.SetShort(Mac::kShortAddrBroadcast);
     }
-    else if (aIp6Addr.mFields.m16[0] == HostSwap16(0xfe80) && aIp6Addr.mFields.m16[1] == HostSwap16(0x0000) &&
-             aIp6Addr.mFields.m16[2] == HostSwap16(0x0000) && aIp6Addr.mFields.m16[3] == HostSwap16(0x0000) &&
-             aIp6Addr.mFields.m16[4] == HostSwap16(0x0000) && aIp6Addr.mFields.m16[5] == HostSwap16(0x00ff) &&
-             aIp6Addr.mFields.m16[6] == HostSwap16(0xfe00))
-    {
-        aMacAddr.SetShort(HostSwap16(aIp6Addr.mFields.m16[7]));
-    }
     else if (Get<Mle::MleRouter>().IsRoutingLocator(aIp6Addr))
     {
-        aMacAddr.SetShort(HostSwap16(aIp6Addr.mFields.m16[7]));
+        aMacAddr.SetShort(aIp6Addr.GetIid().GetLocator());
     }
     else
     {
-        aIp6Addr.ToExtAddress(aMacAddr);
+        aIp6Addr.GetIid().ConvertToMacAddress(aMacAddr);
     }
 }
 
@@ -427,7 +401,7 @@
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(mEnabled, error = OT_ERROR_ABORT);
-    VerifyOrExit(mSendMessage != NULL, error = OT_ERROR_ABORT);
+    VerifyOrExit(mSendMessage != nullptr, error = OT_ERROR_ABORT);
 
     mSendBusy = true;
 
@@ -436,18 +410,7 @@
     case Message::kTypeIp6:
         if (mSendMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)
         {
-            SuccessOrExit(error = Get<Mac::Mac>().SetTemporaryChannel(mScanChannel));
-
-            aFrame.SetChannel(mScanChannel);
-
-            // In case a specific PAN ID of a Thread Network to be discovered is not known, Discovery
-            // Request messages MUST have the Destination PAN ID in the IEEE 802.15.4 MAC header set
-            // to be the Broadcast PAN ID (0xFFFF) and the Source PAN ID set to a randomly generated
-            // value.
-            if (mSendMessage->GetPanId() == Mac::kPanIdBroadcast && Get<Mac::Mac>().GetPanId() == Mac::kPanIdBroadcast)
-            {
-                Get<Mac::Mac>().SetPanId(Mac::GenerateRandomPanId());
-            }
+            SuccessOrExit(error = Get<Mle::DiscoverScanner>().PrepareDiscoveryRequestFrame(aFrame));
         }
 
         mMessageNextOffset =
@@ -461,7 +424,7 @@
             ExitNow();
         }
 
-        assert(aFrame.GetLength() != 7);
+        OT_ASSERT(aFrame.GetLength() != 7);
         break;
 
 #if OPENTHREAD_FTD
@@ -476,11 +439,14 @@
         // there is a pending indirect supervision message in the send
         // queue for it. The message would be then converted to a
         // direct tx.
+
+        // Fall through
+#endif
+
+    default:
         mMessageNextOffset = mSendMessage->GetLength();
         error              = OT_ERROR_ABORT;
         ExitNow();
-
-#endif
     }
 
     aFrame.SetIsARetransmission(false);
@@ -520,16 +486,7 @@
     // Initialize MAC header
     fcf = Mac::Frame::kFcfFrameData;
 
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    if (aMessage.IsTimeSync())
-    {
-        fcf |= Mac::Frame::kFcfFrameVersion2015 | Mac::Frame::kFcfIePresent;
-    }
-    else
-#endif
-    {
-        fcf |= Mac::Frame::kFcfFrameVersion2006;
-    }
+    Get<Mac::Mac>().UpdateFrameControlField(aMessage.IsTimeSync(), fcf);
 
     fcf |= (aMacDest.IsShort()) ? Mac::Frame::kFcfDstAddrShort : Mac::Frame::kFcfDstAddrExt;
     fcf |= (aMacSource.IsShort()) ? Mac::Frame::kFcfSrcAddrShort : Mac::Frame::kFcfSrcAddrExt;
@@ -606,30 +563,12 @@
 
     aFrame.InitMacHeader(fcf, secCtl);
     aFrame.SetDstPanId(dstpan);
-    aFrame.SetSrcPanId(Get<Mac::Mac>().GetPanId());
+    IgnoreError(aFrame.SetSrcPanId(Get<Mac::Mac>().GetPanId()));
     aFrame.SetDstAddr(aMacDest);
     aFrame.SetSrcAddr(aMacSource);
 
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    if (aMessage.IsTimeSync())
-    {
-        Mac::TimeIe * ie;
-        uint8_t *     cur = NULL;
-        Mac::HeaderIe ieList[2];
-
-        ieList[0].Init();
-        ieList[0].SetId(Mac::Frame::kHeaderIeVendor);
-        ieList[0].SetLength(sizeof(Mac::TimeIe));
-        ieList[1].Init();
-        ieList[1].SetId(Mac::Frame::kHeaderIeTermination2);
-        ieList[1].SetLength(0);
-        aFrame.AppendHeaderIe(ieList, 2);
-
-        cur = aFrame.GetHeaderIe(Mac::Frame::kHeaderIeVendor);
-        ie  = reinterpret_cast<Mac::TimeIe *>(cur + sizeof(Mac::HeaderIe));
-        ie->Init();
-    }
-
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
+    IgnoreError(Get<Mac::Mac>().AppendHeaderIe(aMessage.IsTimeSync(), aFrame));
 #endif
 
     payload = aFrame.GetPayload();
@@ -646,7 +585,7 @@
         uint16_t           meshHeaderLength;
         uint8_t            hopsLeft;
 
-        if (mle.GetRole() == OT_DEVICE_ROLE_CHILD)
+        if (mle.IsChild())
         {
             // REED sets hopsLeft to max (16) + 1. It does not know the route cost.
             hopsLeft = Mle::kMaxRouteCost + 1;
@@ -691,6 +630,8 @@
         Mac::Address         meshSource, meshDest;
         otError              error;
 
+        OT_UNUSED_VARIABLE(error);
+
         if (aAddMeshHeader)
         {
             meshSource.SetShort(aMeshSource);
@@ -703,7 +644,7 @@
         }
 
         error = Get<Lowpan::Lowpan>().Compress(aMessage, meshSource, meshDest, buffer);
-        assert(error == OT_ERROR_NONE);
+        OT_ASSERT(error == OT_ERROR_NONE);
 
         hcLength = static_cast<uint8_t>(buffer.GetWritePointer() - payload);
         headerLength += hcLength;
@@ -768,11 +709,11 @@
         payload += fragmentHeaderLength;
         headerLength += fragmentHeaderLength;
 
-        fragmentLength = (aFrame.GetMaxPayloadLength() - headerLength) & ~0x7;
+        fragmentLength = aFrame.GetMaxPayloadLength() - headerLength;
 
         if (payloadLength > fragmentLength)
         {
-            payloadLength = fragmentLength;
+            payloadLength = (fragmentLength & ~0x7);
         }
 
         // Copy IPv6 Payload
@@ -795,14 +736,14 @@
 
 Neighbor *MeshForwarder::UpdateNeighborOnSentFrame(Mac::TxFrame &aFrame, otError aError, const Mac::Address &aMacDest)
 {
-    Neighbor *neighbor = NULL;
+    Neighbor *neighbor = nullptr;
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     neighbor = Get<Mle::MleRouter>().GetNeighbor(aMacDest);
-    VerifyOrExit(neighbor != NULL);
+    VerifyOrExit(neighbor != nullptr, OT_NOOP);
 
-    VerifyOrExit(aFrame.GetAckRequest());
+    VerifyOrExit(aFrame.GetAckRequest(), OT_NOOP);
 
     if (aError == OT_ERROR_NONE)
     {
@@ -811,11 +752,11 @@
     else if (aError == OT_ERROR_NO_ACK)
     {
         neighbor->IncrementLinkFailures();
-        VerifyOrExit(Mle::Mle::IsActiveRouter(neighbor->GetRloc16()));
+        VerifyOrExit(Mle::Mle::IsActiveRouter(neighbor->GetRloc16()), OT_NOOP);
 
         if (neighbor->GetLinkFailures() >= Mle::kFailedRouterTransmissions)
         {
-            Get<Mle::MleRouter>().RemoveNeighbor(*neighbor);
+            Get<Mle::MleRouter>().RemoveRouterLink(*static_cast<Router *>(neighbor));
         }
     }
 
@@ -825,24 +766,24 @@
 
 void MeshForwarder::HandleSentFrame(Mac::TxFrame &aFrame, otError aError)
 {
-    Neighbor *   neighbor = NULL;
+    Neighbor *   neighbor = nullptr;
     Mac::Address macDest;
 
-    assert((aError == OT_ERROR_NONE) || (aError == OT_ERROR_CHANNEL_ACCESS_FAILURE) || (aError == OT_ERROR_ABORT) ||
-           (aError == OT_ERROR_NO_ACK));
+    OT_ASSERT((aError == OT_ERROR_NONE) || (aError == OT_ERROR_CHANNEL_ACCESS_FAILURE) || (aError == OT_ERROR_ABORT) ||
+              (aError == OT_ERROR_NO_ACK));
 
     mSendBusy = false;
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     if (!aFrame.IsEmpty())
     {
-        aFrame.GetDstAddr(macDest);
+        IgnoreError(aFrame.GetDstAddr(macDest));
         neighbor = UpdateNeighborOnSentFrame(aFrame, aError, macDest);
     }
 
-    VerifyOrExit(mSendMessage != NULL);
-    assert(mSendMessage->GetDirectTransmission());
+    VerifyOrExit(mSendMessage != nullptr, OT_NOOP);
+    OT_ASSERT(mSendMessage->GetDirectTransmission());
 
     if (aError != OT_ERROR_NONE)
     {
@@ -872,7 +813,7 @@
         mSendMessage->ClearDirectTransmission();
         mSendMessage->SetOffset(0);
 
-        if (neighbor != NULL)
+        if (neighbor != nullptr)
         {
             neighbor->GetLinkInfo().AddMessageTxStatus(mSendMessage->GetTxSuccess());
         }
@@ -909,9 +850,7 @@
 
     if (mSendMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)
     {
-        mSendBusy = true;
-        mDiscoverTimer.Start(static_cast<uint16_t>(Mac::kScanDurationDefault));
-        ExitNow();
+        Get<Mle::DiscoverScanner>().HandleDiscoveryRequestFrameTxDone(*mSendMessage);
     }
 
     if (!mSendMessage->GetDirectTransmission() && !mSendMessage->IsChildPending())
@@ -930,7 +869,7 @@
 
         mSendQueue.Dequeue(*mSendMessage);
         mSendMessage->Free();
-        mSendMessage       = NULL;
+        mSendMessage       = nullptr;
         mMessageNextOffset = 0;
     }
 
@@ -942,50 +881,6 @@
     }
 }
 
-void MeshForwarder::SetDiscoverParameters(const Mac::ChannelMask &aScanChannels)
-{
-    uint32_t mask;
-    uint32_t supportedMask = Get<Mac::Mac>().GetSupportedChannelMask().GetMask();
-
-    mask = aScanChannels.IsEmpty() ? supportedMask : aScanChannels.GetMask();
-    mScanChannels.SetMask(mask & supportedMask);
-}
-
-void MeshForwarder::HandleDiscoverTimer(Timer &aTimer)
-{
-    aTimer.GetOwner<MeshForwarder>().HandleDiscoverTimer();
-}
-
-void MeshForwarder::HandleDiscoverTimer(void)
-{
-    if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE)
-    {
-        mSendQueue.Dequeue(*mSendMessage);
-        mSendMessage->Free();
-        mSendMessage = NULL;
-
-        HandleDiscoverComplete();
-        ExitNow();
-    }
-
-    mSendMessage->SetDirectTransmission();
-
-exit:
-    mSendBusy = false;
-    mScheduleTransmissionTask.Post();
-}
-
-void MeshForwarder::HandleDiscoverComplete(void)
-{
-    assert(mScanning);
-
-    Get<Mac::Mac>().ClearTemporaryChannel();
-    Get<Mac::Mac>().SetPanId(mRestorePanId);
-    mScanning = false;
-    Get<Mle::MleRouter>().HandleDiscoverComplete();
-    mDiscoverTimer.Stop();
-}
-
 void MeshForwarder::HandleReceivedFrame(Mac::RxFrame &aFrame)
 {
     otThreadLinkInfo linkInfo;
@@ -1003,13 +898,13 @@
     SuccessOrExit(error = aFrame.GetSrcAddr(macSource));
     SuccessOrExit(error = aFrame.GetDstAddr(macDest));
 
-    aFrame.GetSrcPanId(linkInfo.mPanId);
+    IgnoreError(aFrame.GetSrcPanId(linkInfo.mPanId));
     linkInfo.mChannel      = aFrame.GetChannel();
     linkInfo.mRss          = aFrame.GetRssi();
     linkInfo.mLqi          = aFrame.GetLqi();
     linkInfo.mLinkSecurity = aFrame.GetSecurityEnabled();
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    if (aFrame.GetTimeIe() != NULL)
+    if (aFrame.GetTimeIe() != nullptr)
     {
         linkInfo.mNetworkTimeOffset = aFrame.ComputeNetworkTimeOffset();
         linkInfo.mTimeSyncSeq       = aFrame.ReadTimeSyncSeq();
@@ -1063,7 +958,7 @@
     }
 }
 
-void MeshForwarder::HandleFragment(uint8_t *               aFrame,
+void MeshForwarder::HandleFragment(const uint8_t *         aFrame,
                                    uint16_t                aFrameLength,
                                    const Mac::Address &    aMacSource,
                                    const Mac::Address &    aMacDest,
@@ -1072,7 +967,7 @@
     otError                error = OT_ERROR_NONE;
     Lowpan::FragmentHeader fragmentHeader;
     uint16_t               fragmentHeaderLength;
-    Message *              message = NULL;
+    Message *              message = nullptr;
 
     // Check the fragment header
     SuccessOrExit(error = fragmentHeader.ParseFrom(aFrame, aFrameLength, fragmentHeaderLength));
@@ -1081,14 +976,17 @@
 
     if (fragmentHeader.GetDatagramOffset() == 0)
     {
-        uint8_t priority;
-        int     headerLength;
+        uint16_t datagramSize = fragmentHeader.GetDatagramSize();
 
-        SuccessOrExit(error = GetFramePriority(aFrame, aFrameLength, aMacSource, aMacDest, priority));
+        error = FrameToMessage(aFrame, aFrameLength, datagramSize, aMacSource, aMacDest, message);
+        SuccessOrExit(error);
 
-        message = Get<MessagePool>().New(Message::kTypeIp6, 0, priority);
-        VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+        VerifyOrExit(datagramSize >= message->GetLength(), error = OT_ERROR_PARSE);
+        error = message->SetLength(datagramSize);
+        SuccessOrExit(error);
 
+        message->SetDatagramTag(fragmentHeader.GetDatagramTag());
+        message->SetTimeout(kReassemblyTimeout);
         message->SetLinkSecurityEnabled(aLinkInfo.mLinkSecurity);
         message->SetPanId(aLinkInfo.mPanId);
         message->AddRss(aLinkInfo.mRss);
@@ -1096,25 +994,13 @@
         message->SetTimeSyncSeq(aLinkInfo.mTimeSyncSeq);
         message->SetNetworkTimeOffset(aLinkInfo.mNetworkTimeOffset);
 #endif
-        headerLength = Get<Lowpan::Lowpan>().Decompress(*message, aMacSource, aMacDest, aFrame, aFrameLength,
-                                                        fragmentHeader.GetDatagramSize());
-        VerifyOrExit(headerLength > 0, error = OT_ERROR_PARSE);
 
-        aFrame += headerLength;
-        aFrameLength -= static_cast<uint16_t>(headerLength);
-
-        VerifyOrExit(fragmentHeader.GetDatagramSize() >= message->GetOffset() + aFrameLength, error = OT_ERROR_PARSE);
-
-        SuccessOrExit(error = message->SetLength(fragmentHeader.GetDatagramSize()));
-
-        message->SetDatagramTag(fragmentHeader.GetDatagramTag());
-        message->SetTimeout(kReassemblyTimeout);
-        message->Write(message->GetOffset(), aFrameLength, aFrame);
-        message->MoveOffset(aFrameLength);
-
-        // Security Check
         VerifyOrExit(Get<Ip6::Filter>().Accept(*message), error = OT_ERROR_DROP);
 
+#if OPENTHREAD_FTD
+        SendIcmpErrorIfDstUnreach(*message, aMacSource, aMacDest);
+#endif
+
         // Allow re-assembly of only one message at a time on a SED by clearing
         // any remaining fragments in reassembly list upon receiving of a new
         // (secure) first fragment.
@@ -1152,12 +1038,12 @@
         // message with a new tag. In either case, we can safely clear any
         // remaining fragments stored in the reassembly list.
 
-        if (!GetRxOnWhenIdle() && (message == NULL) && aLinkInfo.mLinkSecurity)
+        if (!GetRxOnWhenIdle() && (message == nullptr) && aLinkInfo.mLinkSecurity)
         {
             ClearReassemblyList();
         }
 
-        VerifyOrExit(message != NULL, error = OT_ERROR_DROP);
+        VerifyOrExit(message != nullptr, error = OT_ERROR_DROP);
 
         message->Write(message->GetOffset(), aFrameLength, aFrame);
         message->MoveOffset(aFrameLength);
@@ -1172,14 +1058,14 @@
         if (message->GetOffset() >= message->GetLength())
         {
             mReassemblyList.Dequeue(*message);
-            HandleDatagram(*message, aLinkInfo, aMacSource);
+            IgnoreError(HandleDatagram(*message, aLinkInfo, aMacSource));
         }
     }
     else
     {
         LogFragmentFrameDrop(error, aFrameLength, aMacSource, aMacDest, fragmentHeader, aLinkInfo.mLinkSecurity);
 
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -1196,7 +1082,7 @@
         next = message->GetNext();
         mReassemblyList.Dequeue(*message);
 
-        LogMessage(kMessageReassemblyDrop, *message, NULL, OT_ERROR_NO_FRAME_RECEIVED);
+        LogMessage(kMessageReassemblyDrop, *message, nullptr, OT_ERROR_NO_FRAME_RECEIVED);
 
         if (message->GetType() == Message::kTypeIp6)
         {
@@ -1228,7 +1114,7 @@
 
 bool MeshForwarder::UpdateReassemblyList(void)
 {
-    Message *next = NULL;
+    Message *next = nullptr;
 
     for (Message *message = mReassemblyList.GetHead(); message; message = next)
     {
@@ -1242,7 +1128,7 @@
         {
             mReassemblyList.Dequeue(*message);
 
-            LogMessage(kMessageReassemblyDrop, *message, NULL, OT_ERROR_REASSEMBLY_TIMEOUT);
+            LogMessage(kMessageReassemblyDrop, *message, nullptr, OT_ERROR_REASSEMBLY_TIMEOUT);
             if (message->GetType() == Message::kTypeIp6)
             {
                 mIpCounters.mRxFailure++;
@@ -1252,26 +1138,57 @@
         }
     }
 
-    return mReassemblyList.GetHead() != NULL;
+    return mReassemblyList.GetHead() != nullptr;
 }
 
-void MeshForwarder::HandleLowpanHC(uint8_t *               aFrame,
+otError MeshForwarder::FrameToMessage(const uint8_t *     aFrame,
+                                      uint16_t            aFrameLength,
+                                      uint16_t            aDatagramSize,
+                                      const Mac::Address &aMacSource,
+                                      const Mac::Address &aMacDest,
+                                      Message *&          aMessage)
+{
+    otError           error = OT_ERROR_NONE;
+    int               headerLength;
+    Message::Priority priority;
+
+    error = GetFramePriority(aFrame, aFrameLength, aMacSource, aMacDest, priority);
+    SuccessOrExit(error);
+
+    aMessage = Get<MessagePool>().New(Message::kTypeIp6, 0, priority);
+    VerifyOrExit(aMessage, error = OT_ERROR_NO_BUFS);
+
+    headerLength =
+        Get<Lowpan::Lowpan>().Decompress(*aMessage, aMacSource, aMacDest, aFrame, aFrameLength, aDatagramSize);
+    VerifyOrExit(headerLength > 0, error = OT_ERROR_PARSE);
+
+    aFrame += headerLength;
+    aFrameLength -= static_cast<uint16_t>(headerLength);
+
+    SuccessOrExit(error = aMessage->SetLength(aMessage->GetLength() + aFrameLength));
+    aMessage->Write(aMessage->GetOffset(), aFrameLength, aFrame);
+    aMessage->MoveOffset(aFrameLength);
+
+exit:
+    return error;
+}
+
+void MeshForwarder::HandleLowpanHC(const uint8_t *         aFrame,
                                    uint16_t                aFrameLength,
                                    const Mac::Address &    aMacSource,
                                    const Mac::Address &    aMacDest,
                                    const otThreadLinkInfo &aLinkInfo)
 {
     otError  error   = OT_ERROR_NONE;
-    Message *message = NULL;
-    int      headerLength;
-    uint8_t  priority;
+    Message *message = nullptr;
 
 #if OPENTHREAD_FTD
     UpdateRoutes(aFrame, aFrameLength, aMacSource, aMacDest);
 #endif
 
-    SuccessOrExit(error = GetFramePriority(aFrame, aFrameLength, aMacSource, aMacDest, priority));
-    VerifyOrExit((message = Get<MessagePool>().New(Message::kTypeIp6, 0, priority)) != NULL, error = OT_ERROR_NO_BUFS);
+    error = FrameToMessage(aFrame, aFrameLength, 0, aMacSource, aMacDest, message);
+    SuccessOrExit(error);
+
     message->SetLinkSecurityEnabled(aLinkInfo.mLinkSecurity);
     message->SetPanId(aLinkInfo.mPanId);
     message->AddRss(aLinkInfo.mRss);
@@ -1280,29 +1197,23 @@
     message->SetNetworkTimeOffset(aLinkInfo.mNetworkTimeOffset);
 #endif
 
-    headerLength = Get<Lowpan::Lowpan>().Decompress(*message, aMacSource, aMacDest, aFrame, aFrameLength, 0);
-    VerifyOrExit(headerLength > 0, error = OT_ERROR_PARSE);
-
-    aFrame += headerLength;
-    aFrameLength -= static_cast<uint16_t>(headerLength);
-
-    SuccessOrExit(error = message->SetLength(message->GetLength() + aFrameLength));
-    message->Write(message->GetOffset(), aFrameLength, aFrame);
-
-    // Security Check
     VerifyOrExit(Get<Ip6::Filter>().Accept(*message), error = OT_ERROR_DROP);
 
+#if OPENTHREAD_FTD
+    SendIcmpErrorIfDstUnreach(*message, aMacSource, aMacDest);
+#endif
+
 exit:
 
     if (error == OT_ERROR_NONE)
     {
-        HandleDatagram(*message, aLinkInfo, aMacSource);
+        IgnoreError(HandleDatagram(*message, aLinkInfo, aMacSource));
     }
     else
     {
         LogLowpanHcFrameDrop(error, aFrameLength, aMacSource, aMacDest, aLinkInfo.mLinkSecurity);
 
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -1329,30 +1240,46 @@
                                         uint16_t            aFrameLength,
                                         const Mac::Address &aMacSource,
                                         const Mac::Address &aMacDest,
-                                        uint8_t &           aPriority)
+                                        Message::Priority & aPriority)
 {
-    otError        error = OT_ERROR_NONE;
-    Ip6::Header    ip6Header;
-    Ip6::UdpHeader udpHeader;
-    uint8_t        headerLength;
-    bool           nextHeaderCompressed;
+    otError           error = OT_ERROR_NONE;
+    Ip6::Header       ip6Header;
+    Ip6::Udp::Header  udpHeader;
+    Ip6::Icmp::Header icmpHeader;
+    uint8_t           headerLength;
+    bool              nextHeaderCompressed;
 
     SuccessOrExit(error = DecompressIp6Header(aFrame, aFrameLength, aMacSource, aMacDest, ip6Header, headerLength,
                                               nextHeaderCompressed));
     aPriority = Ip6::Ip6::DscpToPriority(ip6Header.GetDscp());
-    VerifyOrExit(ip6Header.GetNextHeader() == Ip6::kProtoUdp);
 
     aFrame += headerLength;
     aFrameLength -= headerLength;
 
+    if (ip6Header.GetNextHeader() == Ip6::kProtoIcmp6 && aFrameLength)
+    {
+        // Just check the first byte which is an ICMPv6 type.
+        memcpy(&icmpHeader, aFrame, sizeof(icmpHeader.mType));
+
+        // Only ICMPv6 error messages are prioritized.
+        if (icmpHeader.IsError())
+        {
+            aPriority = Message::kPriorityNet;
+        }
+
+        ExitNow();
+    }
+
+    VerifyOrExit(ip6Header.GetNextHeader() == Ip6::kProtoUdp, OT_NOOP);
+
     if (nextHeaderCompressed)
     {
-        VerifyOrExit(Get<Lowpan::Lowpan>().DecompressUdpHeader(udpHeader, aFrame, aFrameLength) >= 0);
+        VerifyOrExit(Get<Lowpan::Lowpan>().DecompressUdpHeader(udpHeader, aFrame, aFrameLength) >= 0, OT_NOOP);
     }
     else
     {
-        VerifyOrExit(aFrameLength >= sizeof(Ip6::UdpHeader), error = OT_ERROR_PARSE);
-        memcpy(&udpHeader, aFrame, sizeof(Ip6::UdpHeader));
+        VerifyOrExit(aFrameLength >= sizeof(Ip6::Udp::Header), error = OT_ERROR_PARSE);
+        memcpy(&udpHeader, aFrame, sizeof(Ip6::Udp::Header));
     }
 
     if (udpHeader.GetDestinationPort() == Mle::kUdpPort || udpHeader.GetDestinationPort() == kCoapUdpPort)
@@ -1377,28 +1304,32 @@
     otError error = OT_ERROR_PARSE;
     union
     {
-        Ip6::UdpHeader udp;
-        Ip6::TcpHeader tcp;
+        Ip6::Udp::Header udp;
+        Ip6::Tcp::Header tcp;
     } header;
 
     aChecksum   = 0;
     aSourcePort = 0;
     aDestPort   = 0;
 
-    VerifyOrExit(sizeof(Ip6::Header) == aMessage.Read(0, sizeof(Ip6::Header), &aIp6Header));
-    VerifyOrExit(aIp6Header.IsVersion6());
+    VerifyOrExit(sizeof(Ip6::Header) == aMessage.Read(0, sizeof(Ip6::Header), &aIp6Header), OT_NOOP);
+    VerifyOrExit(aIp6Header.IsVersion6(), OT_NOOP);
 
     switch (aIp6Header.GetNextHeader())
     {
     case Ip6::kProtoUdp:
-        VerifyOrExit(sizeof(Ip6::UdpHeader) == aMessage.Read(sizeof(Ip6::Header), sizeof(Ip6::UdpHeader), &header.udp));
+        VerifyOrExit(sizeof(Ip6::Udp::Header) ==
+                         aMessage.Read(sizeof(Ip6::Header), sizeof(Ip6::Udp::Header), &header.udp),
+                     OT_NOOP);
         aChecksum   = header.udp.GetChecksum();
         aSourcePort = header.udp.GetSourcePort();
         aDestPort   = header.udp.GetDestinationPort();
         break;
 
     case Ip6::kProtoTcp:
-        VerifyOrExit(sizeof(Ip6::TcpHeader) == aMessage.Read(sizeof(Ip6::Header), sizeof(Ip6::TcpHeader), &header.tcp));
+        VerifyOrExit(sizeof(Ip6::Tcp::Header) ==
+                         aMessage.Read(sizeof(Ip6::Header), sizeof(Ip6::Tcp::Header), &header.tcp),
+                     OT_NOOP);
         aChecksum   = header.tcp.GetChecksum();
         aSourcePort = header.tcp.GetSourcePort();
         aDestPort   = header.tcp.GetDestinationPort();
@@ -1523,8 +1454,8 @@
     otLogMac(aLogLevel, "%s IPv6 %s msg, len:%d, chksum:%04x%s%s, sec:%s%s%s, prio:%s%s%s",
              MessageActionToString(aAction, aError), Ip6::Ip6::IpProtoToString(ip6Header.GetNextHeader()),
              aMessage.GetLength(), checksum,
-             (aMacAddress == NULL) ? "" : ((aAction == kMessageReceive) ? ", from:" : ", to:"),
-             (aMacAddress == NULL) ? "" : aMacAddress->ToString().AsCString(),
+             (aMacAddress == nullptr) ? "" : ((aAction == kMessageReceive) ? ", from:" : ", to:"),
+             (aMacAddress == nullptr) ? "" : aMacAddress->ToString().AsCString(),
              aMessage.IsLinkSecurityEnabled() ? "yes" : "no", (aError == OT_ERROR_NONE) ? "" : ", error:",
              (aError == OT_ERROR_NONE) ? "" : otThreadErrorToString(aError), MessagePriorityToString(aMessage),
              shouldLogRss ? ", rss:" : "", shouldLogRss ? aMessage.GetRssAverager().ToString().AsCString() : "");
@@ -1560,7 +1491,7 @@
         break;
     }
 
-    VerifyOrExit(GetInstance().GetLogLevel() >= logLevel);
+    VerifyOrExit(GetInstance().GetLogLevel() >= logLevel, OT_NOOP);
 
     switch (aMessage.GetType())
     {
diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp
index 772613a..a2281ac 100644
--- a/src/core/thread/mesh_forwarder.hpp
+++ b/src/core/thread/mesh_forwarder.hpp
@@ -50,6 +50,10 @@
 
 namespace ot {
 
+namespace Mle {
+class DiscoverScanner;
+}
+
 enum
 {
     kReassemblyTimeout = OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT,
@@ -109,7 +113,7 @@
      * @returns The fragment priority value.
      *
      */
-    uint8_t GetPriority(void) const { return mPriority; }
+    Message::Priority GetPriority(void) const { return static_cast<Message::Priority>(mPriority); }
 
     /**
      * This method sets the fragment priority value.
@@ -117,7 +121,7 @@
      * @param[in]  aPriority  The fragment priority value.
      *
      */
-    void SetPriority(uint8_t aPriority) { mPriority = aPriority; }
+    void SetPriority(Message::Priority aPriority) { mPriority = aPriority; }
 
     /**
      * This method returns the fragment priority entry's remaining lifetime.
@@ -171,6 +175,7 @@
     friend class Instance;
     friend class DataPollSender;
     friend class IndirectSender;
+    friend class Mle::DiscoverScanner;
 
 public:
     /**
@@ -254,7 +259,7 @@
      *                       Use Message::kSubTypeNone remove all messages for @p aChild.
      *
      */
-    void RemoveMessages(Child &aChild, uint8_t aSubType);
+    void RemoveMessages(Child &aChild, Message::SubType aSubType);
 
     /**
      * This method frees unicast/multicast MLE Data Responses from Send Message Queue if any.
@@ -271,7 +276,7 @@
      * @retval OT_ERROR_NOT_FOUND  No low priority messages available to evict.
      *
      */
-    otError EvictMessage(uint8_t aPriority);
+    otError EvictMessage(Message::Priority aPriority);
 
     /**
      * This method returns a reference to the send queue.
@@ -310,14 +315,12 @@
      * @returns  A reference to the resolving queue.
      *
      */
-    const MessageQueue &GetResolvingQueue(void) const { return mResolvingQueue; }
+    const PriorityQueue &GetResolvingQueue(void) const { return mResolvingQueue; }
 #endif
-
 private:
     enum
     {
-        kStateUpdatePeriod  = 1000,                     ///< State update period in milliseconds.
-        kDefaultMsgPriority = Message::kPriorityNormal, ///< Default message priority.
+        kStateUpdatePeriod = 1000, ///< State update period in milliseconds.
 
         /**
          * The number of fragment priority entries.
@@ -336,11 +339,14 @@
         kMessageEvict,           ///< Indicates that the message was evicted.
     };
 
-    otError CheckReachability(uint8_t *           aFrame,
+    void    SendIcmpErrorIfDstUnreach(const Message &     aMessage,
+                                      const Mac::Address &aMacSource,
+                                      const Mac::Address &aMacDest);
+    otError CheckReachability(const uint8_t *     aFrame,
                               uint16_t            aFrameLength,
                               const Mac::Address &aMeshSource,
                               const Mac::Address &aMeshDest);
-    void    UpdateRoutes(uint8_t *           aFrame,
+    void    UpdateRoutes(const uint8_t *     aFrame,
                          uint16_t            aFrameLength,
                          const Mac::Address &aMeshSource,
                          const Mac::Address &aMeshDest);
@@ -352,6 +358,12 @@
                                  Ip6::Header &       aIp6Header,
                                  uint8_t &           aHeaderLength,
                                  bool &              aNextHeaderCompressed);
+    otError  FrameToMessage(const uint8_t *     aFrame,
+                            uint16_t            aFrameLength,
+                            uint16_t            aDatagramSize,
+                            const Mac::Address &aMacSource,
+                            const Mac::Address &aMacDest,
+                            Message *&          aMessage);
     otError  GetIp6Header(const uint8_t *     aFrame,
                           uint16_t            aFrameLength,
                           const Mac::Address &aMacSource,
@@ -360,17 +372,16 @@
     void     GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
     void     GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
     Message *GetDirectTransmission(void);
-    otError  PrepareDiscoverRequest(void);
     void     HandleMesh(uint8_t *               aFrame,
                         uint16_t                aFrameLength,
                         const Mac::Address &    aMacSource,
                         const otThreadLinkInfo &aLinkInfo);
-    void     HandleFragment(uint8_t *               aFrame,
+    void     HandleFragment(const uint8_t *         aFrame,
                             uint16_t                aFrameLength,
                             const Mac::Address &    aMacSource,
                             const Mac::Address &    aMacDest,
                             const otThreadLinkInfo &aLinkInfo);
-    void     HandleLowpanHC(uint8_t *               aFrame,
+    void     HandleLowpanHC(const uint8_t *         aFrame,
                             uint16_t                aFrameLength,
                             const Mac::Address &    aMacSource,
                             const Mac::Address &    aMacDest,
@@ -384,15 +395,16 @@
                               uint16_t            aMeshDest      = 0xffff);
 
     void    SendMesh(Message &aMessage, Mac::TxFrame &aFrame);
+    void    SendDestinationUnreachable(uint16_t aMeshSource, const Message &aMessage);
     otError UpdateIp6Route(Message &aMessage);
-    otError UpdateIp6RouteFtd(Ip6::Header &ip6Header);
+    otError UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage);
     otError UpdateMeshRoute(Message &aMessage);
     bool    UpdateReassemblyList(void);
     bool    UpdateFragmentLifetime(void);
     void    UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader,
                                    uint16_t                aFragmentLength,
                                    uint16_t                aSrcRloc16,
-                                   uint8_t                 aPriority);
+                                   Message::Priority       aPriority);
     otError HandleDatagram(Message &aMessage, const otThreadLinkInfo &aLinkInfo, const Mac::Address &aMacSource);
     void    ClearReassemblyList(void);
     void    RemoveMessage(Message &aMessage);
@@ -414,19 +426,24 @@
                              uint16_t            aFrameLength,
                              const Mac::Address &aMacSource,
                              const Mac::Address &aMacDest,
-                             uint8_t &           aPriority);
-    otError GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, uint16_t aSrcRloc16, uint8_t &aPriority);
-    otError GetForwardFramePriority(const uint8_t *     aFrame,
+                             Message::Priority & aPriority);
+    otError GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader,
+                                uint16_t                aSrcRloc16,
+                                Message::Priority &     aPriority);
+    void    GetForwardFramePriority(const uint8_t *     aFrame,
                                     uint16_t            aFrameLength,
                                     const Mac::Address &aMeshSource,
                                     const Mac::Address &aMeshDest,
-                                    uint8_t &           aPriority);
+                                    Message::Priority & aPriority);
 
     FragmentPriorityEntry *FindFragmentPriorityEntry(uint16_t aTag, uint16_t aSrcRloc16);
     FragmentPriorityEntry *GetUnusedFragmentPriorityEntry(void);
 
     otError GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest);
 
+    void PauseMessageTransmissions(void) { mTxPaused = true; }
+    void ResumeMessageTransmissions(void);
+
     void LogMessage(MessageAction aAction, const Message &aMessage, const Mac::Address *aAddress, otError aError);
     void LogFrame(const char *aActionText, const Mac::Frame &aFrame, otError aError);
     void LogFragmentFrameDrop(otError                       aError,
@@ -489,7 +506,6 @@
                        otLogLevel          aLogLevel);
 #endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
 
-    TimerMilli mDiscoverTimer;
     TimerMilli mUpdateTimer;
 
     PriorityQueue mSendQueue;
@@ -503,23 +519,18 @@
     Mac::Address mMacDest;
     uint16_t     mMeshSource;
     uint16_t     mMeshDest;
-    bool         mAddMeshHeader;
-
-    bool mSendBusy;
+    bool         mAddMeshHeader : 1;
+    bool         mEnabled : 1;
+    bool         mTxPaused : 1;
+    bool         mSendBusy : 1;
 
     Tasklet mScheduleTransmissionTask;
-    bool    mEnabled;
-
-    Mac::ChannelMask mScanChannels;
-    uint8_t          mScanChannel;
-    uint16_t         mRestorePanId;
-    bool             mScanning;
 
     otIpCounters mIpCounters;
 
 #if OPENTHREAD_FTD
     FragmentPriorityEntry mFragmentEntries[kNumFragmentPriorityEntries];
-    MessageQueue          mResolvingQueue;
+    PriorityQueue         mResolvingQueue;
     IndirectSender        mIndirectSender;
 #endif
 
diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp
index 7bb0642..c88c413 100644
--- a/src/core/thread/mesh_forwarder_ftd.cpp
+++ b/src/core/thread/mesh_forwarder_ftd.cpp
@@ -52,7 +52,7 @@
 
     aMessage.SetOffset(0);
     aMessage.SetDatagramTag(0);
-    SuccessOrExit(error = mSendQueue.Enqueue(aMessage));
+    mSendQueue.Enqueue(aMessage);
 
     switch (aMessage.GetType())
     {
@@ -80,11 +80,8 @@
                     ip6Header.GetDestination() == mle.GetRealmLocalAllThreadNodesAddress())
                 {
                     // destined for all sleepy children
-                    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone();
-                         iter++)
+                    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
                     {
-                        Child &child = *iter.GetChild();
-
                         if (!child.IsRxOnWhenIdle())
                         {
                             mIndirectSender.AddMessageForSleepyChild(aMessage, child);
@@ -94,11 +91,8 @@
                 else
                 {
                     // destined for some sleepy children which subscribed the multicast address.
-                    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone();
-                         iter++)
+                    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
                     {
-                        Child &child = *iter.GetChild();
-
                         if (mle.IsSleepyChildSubscribed(ip6Header.GetDestination(), child))
                         {
                             mIndirectSender.AddMessageForSleepyChild(aMessage, child);
@@ -107,7 +101,7 @@
                 }
             }
         }
-        else if ((neighbor = mle.GetNeighbor(ip6Header.GetDestination())) != NULL && !neighbor->IsRxOnWhenIdle() &&
+        else if ((neighbor = mle.GetNeighbor(ip6Header.GetDestination())) != nullptr && !neighbor->IsRxOnWhenIdle() &&
                  !aMessage.GetDirectTransmission())
         {
             // destined for a sleepy child
@@ -126,7 +120,7 @@
     case Message::kTypeSupervision:
     {
         Child *child = Get<Utils::ChildSupervisor>().GetDestination(aMessage);
-        assert((child != NULL) && !child->IsRxOnWhenIdle());
+        OT_ASSERT((child != nullptr) && !child->IsRxOnWhenIdle());
         mIndirectSender.AddMessageForSleepyChild(aMessage, *child);
         break;
     }
@@ -138,7 +132,6 @@
 
     mScheduleTransmissionTask.Post();
 
-exit:
     return error;
 }
 
@@ -170,7 +163,7 @@
             }
             else
             {
-                LogMessage(kMessageDrop, *cur, NULL, aError);
+                LogMessage(kMessageDrop, *cur, nullptr, aError);
                 cur->Free();
             }
         }
@@ -182,42 +175,76 @@
     }
 }
 
-otError MeshForwarder::EvictMessage(uint8_t aPriority)
+otError MeshForwarder::EvictMessage(Message::Priority aPriority)
 {
-    otError  error = OT_ERROR_NOT_FOUND;
-    Message *message;
+    otError        error    = OT_ERROR_NOT_FOUND;
+    PriorityQueue *queues[] = {&mResolvingQueue, &mSendQueue};
+    Message *      evict    = nullptr;
 
-    VerifyOrExit((message = mSendQueue.GetTail()) != NULL);
-
-    if (message->GetPriority() < aPriority)
+    // search for a lower priority message to evict (choose lowest priority message among all queues)
+    for (uint8_t index = 0; index < OT_ARRAY_LENGTH(queues); index++)
     {
-        VerifyOrExit(!message->GetDoNotEvict());
-        RemoveMessage(*message);
+        for (uint8_t priority = 0; priority < aPriority; priority++)
+        {
+            for (Message *message = queues[index]->GetHeadForPriority(static_cast<Message::Priority>(priority));
+                 message; message = message->GetNext())
+            {
+                if (message->GetPriority() != priority)
+                {
+                    break;
+                }
+
+                if (message->GetDoNotEvict())
+                {
+                    continue;
+                }
+
+                evict     = message;
+                aPriority = static_cast<Message::Priority>(priority);
+                break;
+            }
+        }
+    }
+
+    if (evict != nullptr)
+    {
         ExitNow(error = OT_ERROR_NONE);
     }
-    else
+
+    for (uint8_t priority = aPriority; priority < Message::kNumPriorities; priority++)
     {
-        while (aPriority <= Message::kPriorityNet)
+        // search for an equal or higher priority indirect message to evict
+        for (Message *message = mSendQueue.GetHeadForPriority(aPriority); message; message = message->GetNext())
         {
-            for (message = mSendQueue.GetHeadForPriority(aPriority); message && (message->GetPriority() == aPriority);
-                 message = message->GetNext())
+            if (message->GetPriority() != priority)
             {
-                if (message->IsChildPending())
-                {
-                    RemoveMessage(*message);
-                    ExitNow(error = OT_ERROR_NONE);
-                }
+                break;
             }
 
-            aPriority++;
+            if (message->GetDoNotEvict())
+            {
+                continue;
+            }
+
+            if (message->IsChildPending())
+            {
+                evict = message;
+                ExitNow(error = OT_ERROR_NONE);
+            }
         }
     }
 
 exit:
+
+    if (error == OT_ERROR_NONE)
+    {
+        RemoveMessage(*evict);
+    }
+
     return error;
 }
 
-void MeshForwarder::RemoveMessages(Child &aChild, uint8_t aSubType)
+void MeshForwarder::RemoveMessages(Child &aChild, Message::SubType aSubType)
 {
     Mle::MleRouter &mle = Get<Mle::MleRouter>();
     Message *       nextMessage;
@@ -253,7 +280,7 @@
             {
                 Lowpan::MeshHeader meshHeader;
 
-                IgnoreReturnValue(meshHeader.ParseFrom(*message));
+                IgnoreError(meshHeader.ParseFrom(*message));
 
                 if (&aChild == static_cast<Child *>(mle.GetNeighbor(meshHeader.GetDestination())))
                 {
@@ -272,7 +299,7 @@
         {
             if (mSendMessage == message)
             {
-                mSendMessage = NULL;
+                mSendMessage = nullptr;
             }
 
             mSendQueue.Dequeue(*message);
@@ -296,19 +323,19 @@
 
         if (!(ip6Header.GetDestination().IsMulticast()))
         {
-            for (ChildTable::Iterator iter(GetInstance(), Child::kInStateAnyExceptInvalid); !iter.IsDone(); iter++)
+            for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
             {
-                IgnoreReturnValue(mIndirectSender.RemoveMessageFromSleepyChild(*message, *iter.GetChild()));
+                IgnoreError(mIndirectSender.RemoveMessageFromSleepyChild(*message, child));
             }
         }
 
         if (mSendMessage == message)
         {
-            mSendMessage = NULL;
+            mSendMessage = nullptr;
         }
 
         mSendQueue.Dequeue(*message);
-        LogMessage(kMessageDrop, *message, NULL, OT_ERROR_NONE);
+        LogMessage(kMessageDrop, *message, nullptr, OT_ERROR_NONE);
         message->Free();
     }
 }
@@ -318,9 +345,9 @@
     uint16_t fcf;
 
     // initialize MAC header
-    fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfFrameVersion2006 |
-          Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort | Mac::Frame::kFcfAckRequest |
-          Mac::Frame::kFcfSecurityEnabled;
+    fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfDstAddrShort |
+          Mac::Frame::kFcfSrcAddrShort | Mac::Frame::kFcfAckRequest | Mac::Frame::kFcfSecurityEnabled;
+    Get<Mac::Mac>().UpdateFrameControlField(aMessage.IsTimeSync(), fcf);
 
     aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32);
     aFrame.SetDstPanId(Get<Mac::Mac>().GetPanId());
@@ -328,7 +355,7 @@
     aFrame.SetSrcAddr(mMacSource.GetShort());
 
     // write payload
-    assert(aMessage.GetLength() <= aFrame.GetMaxPayloadLength());
+    OT_ASSERT(aMessage.GetLength() <= aFrame.GetMaxPayloadLength());
     aMessage.Read(0, aMessage.GetLength(), aFrame.GetPayload());
     aFrame.SetPayloadLength(aMessage.GetLength());
 
@@ -342,7 +369,7 @@
     Neighbor *         neighbor;
     uint16_t           nextHop;
 
-    IgnoreReturnValue(meshHeader.ParseFrom(aMessage));
+    IgnoreError(meshHeader.ParseFrom(aMessage));
 
     nextHop = Get<Mle::MleRouter>().GetNextHop(meshHeader.GetDestination());
 
@@ -355,7 +382,7 @@
         neighbor = Get<Mle::MleRouter>().GetNeighbor(meshHeader.GetDestination());
     }
 
-    if (neighbor == NULL)
+    if (neighbor == nullptr)
     {
         ExitNow(error = OT_ERROR_DROP);
     }
@@ -371,30 +398,30 @@
     return error;
 }
 
-otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header)
+otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage)
 {
     Mle::MleRouter &mle   = Get<Mle::MleRouter>();
     otError         error = OT_ERROR_NONE;
     Neighbor *      neighbor;
 
-    if (mle.IsRoutingLocator(ip6Header.GetDestination()))
+    if (aMessage.GetOffset() > 0)
     {
-        uint16_t rloc16 = HostSwap16(ip6Header.GetDestination().mFields.m16[7]);
+        mMeshDest = aMessage.GetMeshDest();
+    }
+    else if (mle.IsRoutingLocator(ip6Header.GetDestination()))
+    {
+        uint16_t rloc16 = ip6Header.GetDestination().GetIid().GetLocator();
         VerifyOrExit(mle.IsRouterIdValid(Mle::Mle::RouterIdFromRloc16(rloc16)), error = OT_ERROR_DROP);
         mMeshDest = rloc16;
     }
     else if (mle.IsAnycastLocator(ip6Header.GetDestination()))
     {
-        uint16_t aloc16 = HostSwap16(ip6Header.GetDestination().mFields.m16[7]);
+        uint16_t aloc16 = ip6Header.GetDestination().GetIid().GetLocator();
 
         if (aloc16 == Mle::kAloc16Leader)
         {
             mMeshDest = Mle::Mle::Rloc16FromRouterId(mle.GetLeaderId());
         }
-        else if ((aloc16 >= Mle::kAloc16CommissionerStart) && (aloc16 <= Mle::kAloc16CommissionerEnd))
-        {
-            SuccessOrExit(error = MeshCoP::GetBorderAgentRloc(Get<ThreadNetif>(), mMeshDest));
-        }
         else if (aloc16 <= Mle::kAloc16DhcpAgentEnd)
         {
             uint16_t agentRloc16;
@@ -416,18 +443,29 @@
                 mMeshDest = Mle::Mle::Rloc16FromRouterId(routerId);
             }
         }
-        else if ((aloc16 >= Mle::kAloc16ServiceStart) && (aloc16 <= Mle::kAloc16ServiceEnd))
+        else if (aloc16 <= Mle::kAloc16ServiceEnd)
         {
             SuccessOrExit(error = GetDestinationRlocByServiceAloc(aloc16, mMeshDest));
         }
+        else if (aloc16 <= Mle::kAloc16CommissionerEnd)
+        {
+            SuccessOrExit(error = MeshCoP::GetBorderAgentRloc(Get<ThreadNetif>(), mMeshDest));
+        }
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+        else if (aloc16 == Mle::kAloc16BackboneRouterPrimary)
+        {
+            VerifyOrExit(Get<BackboneRouter::Leader>().HasPrimary(), error = OT_ERROR_DROP);
+            mMeshDest = Get<BackboneRouter::Leader>().GetServer16();
+        }
+#endif
         else
         {
             // TODO: support for Neighbor Discovery Agent ALOC
             ExitNow(error = OT_ERROR_DROP);
         }
     }
-    else if ((neighbor = mle.GetNeighbor(ip6Header.GetDestination())) != NULL)
+    else if ((neighbor = mle.GetNeighbor(ip6Header.GetDestination())) != nullptr)
     {
         mMeshDest = neighbor->GetRloc16();
     }
@@ -437,14 +475,16 @@
     }
     else
     {
-        Get<NetworkData::Leader>().RouteLookup(ip6Header.GetSource(), ip6Header.GetDestination(), NULL, &mMeshDest);
+        IgnoreError(Get<NetworkData::Leader>().RouteLookup(ip6Header.GetSource(), ip6Header.GetDestination(), nullptr,
+                                                           &mMeshDest));
     }
 
     VerifyOrExit(mMeshDest != Mac::kShortAddrInvalid, error = OT_ERROR_DROP);
 
     mMeshSource = Get<Mac::Mac>().GetShortAddress();
 
-    SuccessOrExit(error = mle.CheckReachability(mMeshSource, mMeshDest, ip6Header));
+    SuccessOrExit(error = mle.CheckReachability(mMeshDest, ip6Header));
+    aMessage.SetMeshDest(mMeshDest);
     mMacDest.SetShort(mle.GetNextHop(mMeshDest));
 
     if (mMacDest.GetShort() != mMeshDest)
@@ -471,38 +511,102 @@
                                nextHeaderCompressed);
 }
 
-otError MeshForwarder::CheckReachability(uint8_t *           aFrame,
+void MeshForwarder::SendIcmpErrorIfDstUnreach(const Message &     aMessage,
+                                              const Mac::Address &aMacSource,
+                                              const Mac::Address &aMacDest)
+{
+    otError     error;
+    Ip6::Header ip6header;
+    Child *     child;
+
+    VerifyOrExit(aMacSource.IsShort() && aMacDest.IsShort(), OT_NOOP);
+
+    child = Get<ChildTable>().FindChild(aMacSource.GetShort(), Child::kInStateAnyExceptInvalid);
+    VerifyOrExit((child == nullptr) || child->IsFullThreadDevice(), OT_NOOP);
+
+    aMessage.Read(0, sizeof(ip6header), &ip6header);
+    VerifyOrExit(!ip6header.GetDestination().IsMulticast() &&
+                     Get<NetworkData::Leader>().IsOnMesh(ip6header.GetDestination()),
+                 OT_NOOP);
+
+    error = Get<Mle::MleRouter>().CheckReachability(aMacDest.GetShort(), ip6header);
+
+    if (error == OT_ERROR_NO_ROUTE)
+    {
+        SendDestinationUnreachable(aMacSource.GetShort(), aMessage);
+    }
+
+exit:
+    return;
+}
+
+otError MeshForwarder::CheckReachability(const uint8_t *     aFrame,
                                          uint16_t            aFrameLength,
                                          const Mac::Address &aMeshSource,
                                          const Mac::Address &aMeshDest)
 {
-    otError     error = OT_ERROR_NONE;
-    Ip6::Header ip6Header;
+    otError                error = OT_ERROR_NONE;
+    Ip6::Header            ip6Header;
+    Message *              message = nullptr;
+    Lowpan::FragmentHeader fragmentHeader;
+    uint16_t               fragmentHeaderLength;
+    uint16_t               datagramSize = 0;
 
-    SuccessOrExit(error = GetIp6Header(aFrame, aFrameLength, aMeshSource, aMeshDest, ip6Header));
-    error = Get<Mle::MleRouter>().CheckReachability(aMeshSource.GetShort(), aMeshDest.GetShort(), ip6Header);
+    if (fragmentHeader.ParseFrom(aFrame, aFrameLength, fragmentHeaderLength) == OT_ERROR_NONE)
+    {
+        // Only the first fragment header is followed by a LOWPAN_IPHC header
+        VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0, error = OT_ERROR_NOT_FOUND);
+        aFrame += fragmentHeaderLength;
+        aFrameLength -= fragmentHeaderLength;
+
+        datagramSize = fragmentHeader.GetDatagramSize();
+    }
+
+    VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame), error = OT_ERROR_NOT_FOUND);
+
+    error = FrameToMessage(aFrame, aFrameLength, datagramSize, aMeshSource, aMeshDest, message);
+    SuccessOrExit(error);
+
+    message->Read(0, sizeof(ip6Header), &ip6Header);
+    error = Get<Mle::MleRouter>().CheckReachability(aMeshDest.GetShort(), ip6Header);
 
 exit:
-    // the message may not contain an IPv6 header
     if (error == OT_ERROR_NOT_FOUND)
     {
+        // the message may not contain an IPv6 header
         error = OT_ERROR_NONE;
     }
-    else if (error != OT_ERROR_NONE)
+    else if (error == OT_ERROR_NO_ROUTE)
     {
-        error = OT_ERROR_DROP;
+        SendDestinationUnreachable(aMeshSource.GetShort(), *message);
+    }
+
+    if (message != nullptr)
+    {
+        message->Free();
     }
 
     return error;
 }
 
+void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Message &aMessage)
+{
+    Ip6::MessageInfo messageInfo;
+
+    messageInfo.GetPeerAddr() = Get<Mle::MleRouter>().GetMeshLocal16();
+    messageInfo.GetPeerAddr().GetIid().SetLocator(aMeshSource);
+
+    IgnoreError(Get<Ip6::Icmp>().SendError(Ip6::Icmp::Header::kTypeDstUnreach,
+                                           Ip6::Icmp::Header::kCodeDstUnreachNoRoute, messageInfo, aMessage));
+}
+
 void MeshForwarder::HandleMesh(uint8_t *               aFrame,
                                uint16_t                aFrameLength,
                                const Mac::Address &    aMacSource,
                                const otThreadLinkInfo &aLinkInfo)
 {
     otError            error   = OT_ERROR_NONE;
-    Message *          message = NULL;
+    Message *          message = nullptr;
     Mac::Address       meshDest;
     Mac::Address       meshSource;
     Lowpan::MeshHeader meshHeader;
@@ -539,8 +643,8 @@
     }
     else if (meshHeader.GetHopsLeft() > 0)
     {
-        uint8_t  priority = kDefaultMsgPriority;
-        uint16_t offset   = 0;
+        Message::Priority priority = Message::kPriorityNormal;
+        uint16_t          offset   = 0;
 
         Get<Mle::MleRouter>().ResolveRoutingLoops(aMacSource.GetShort(), meshDest.GetShort());
 
@@ -550,7 +654,7 @@
 
         GetForwardFramePriority(aFrame, aFrameLength, meshSource, meshDest, priority);
         message = Get<MessagePool>().New(Message::kType6lowpan, priority);
-        VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+        VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
         SuccessOrExit(error = message->SetLength(meshHeader.GetHeaderLength() + aFrameLength));
         offset += meshHeader.WriteTo(*message, offset);
@@ -561,7 +665,7 @@
 
         LogMessage(kMessageReceive, *message, &aMacSource, OT_ERROR_NONE);
 
-        SendMessage(*message);
+        IgnoreError(SendMessage(*message));
     }
 
 exit:
@@ -571,14 +675,14 @@
         otLogInfoMac("Dropping rx mesh frame, error:%s, len:%d, src:%s, sec:%s", otThreadErrorToString(error),
                      aFrameLength, aMacSource.ToString().AsCString(), aLinkInfo.mLinkSecurity ? "yes" : "no");
 
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
     }
 }
 
-void MeshForwarder::UpdateRoutes(uint8_t *           aFrame,
+void MeshForwarder::UpdateRoutes(const uint8_t *     aFrame,
                                  uint16_t            aFrameLength,
                                  const Mac::Address &aMeshSource,
                                  const Mac::Address &aMeshDest)
@@ -586,10 +690,10 @@
     Ip6::Header ip6Header;
     Neighbor *  neighbor;
 
-    VerifyOrExit(!aMeshDest.IsBroadcast() && aMeshSource.IsShort());
+    VerifyOrExit(!aMeshDest.IsBroadcast() && aMeshSource.IsShort(), OT_NOOP);
     SuccessOrExit(GetIp6Header(aFrame, aFrameLength, aMeshSource, aMeshDest, ip6Header));
 
-    if (!ip6Header.GetSource().IsRoutingLocator() && !ip6Header.GetSource().IsAnycastRoutingLocator() &&
+    if (!ip6Header.GetSource().GetIid().IsLocator() &&
         Get<NetworkData::Leader>().IsOnMesh(ip6Header.GetSource()) /* only for on mesh address which may require AQ */)
     {
         if (Get<AddressResolver>().UpdateCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort()) ==
@@ -606,13 +710,13 @@
                 (aMeshDest.GetShort() == Get<Mac::Mac>().GetShortAddress() ||
                  Get<Mle::MleRouter>().IsMinimalChild(aMeshDest.GetShort())))
             {
-                Get<AddressResolver>().AddCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort());
+                Get<AddressResolver>().AddSnoopedCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort());
             }
         }
     }
 
     neighbor = Get<Mle::MleRouter>().GetNeighbor(ip6Header.GetSource());
-    VerifyOrExit(neighbor != NULL && !neighbor->IsFullThreadDevice());
+    VerifyOrExit(neighbor != nullptr && !neighbor->IsFullThreadDevice(), OT_NOOP);
 
     if (!Mle::Mle::RouterIdMatch(aMeshSource.GetShort(), Get<Mac::Mac>().GetShortAddress()))
     {
@@ -646,13 +750,13 @@
 void MeshForwarder::UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader,
                                            uint16_t                aFragmentLength,
                                            uint16_t                aSrcRloc16,
-                                           uint8_t                 aPriority)
+                                           Message::Priority       aPriority)
 {
     FragmentPriorityEntry *entry;
 
     if (aFragmentHeader.GetDatagramOffset() == 0)
     {
-        VerifyOrExit((entry = GetUnusedFragmentPriorityEntry()) != NULL);
+        VerifyOrExit((entry = GetUnusedFragmentPriorityEntry()) != nullptr, OT_NOOP);
 
         entry->SetDatagramTag(aFragmentHeader.GetDatagramTag());
         entry->SetSrcRloc16(aSrcRloc16);
@@ -666,7 +770,8 @@
     }
     else
     {
-        VerifyOrExit((entry = FindFragmentPriorityEntry(aFragmentHeader.GetDatagramTag(), aSrcRloc16)) != NULL);
+        VerifyOrExit((entry = FindFragmentPriorityEntry(aFragmentHeader.GetDatagramTag(), aSrcRloc16)) != nullptr,
+                     OT_NOOP);
 
         entry->SetLifetime(kReassemblyTimeout);
 
@@ -692,7 +797,7 @@
         }
     }
 
-    entry = NULL;
+    entry = nullptr;
 
 exit:
     return entry;
@@ -710,7 +815,7 @@
         }
     }
 
-    entry = NULL;
+    entry = nullptr;
 
 exit:
     return entry;
@@ -718,24 +823,24 @@
 
 otError MeshForwarder::GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader,
                                            uint16_t                aSrcRloc16,
-                                           uint8_t &               aPriority)
+                                           Message::Priority &     aPriority)
 {
     otError                error = OT_ERROR_NONE;
     FragmentPriorityEntry *entry;
 
     entry = FindFragmentPriorityEntry(aFragmentHeader.GetDatagramTag(), aSrcRloc16);
-    VerifyOrExit(entry != NULL, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(entry != nullptr, error = OT_ERROR_NOT_FOUND);
     aPriority = entry->GetPriority();
 
 exit:
     return error;
 }
 
-otError MeshForwarder::GetForwardFramePriority(const uint8_t *     aFrame,
-                                               uint16_t            aFrameLength,
-                                               const Mac::Address &aMeshSource,
-                                               const Mac::Address &aMeshDest,
-                                               uint8_t &           aPriority)
+void MeshForwarder::GetForwardFramePriority(const uint8_t *     aFrame,
+                                            uint16_t            aFrameLength,
+                                            const Mac::Address &aMeshSource,
+                                            const Mac::Address &aMeshDest,
+                                            Message::Priority & aPriority)
 {
     otError                error      = OT_ERROR_NONE;
     bool                   isFragment = false;
@@ -770,35 +875,69 @@
         UpdateFragmentPriority(fragmentHeader, aFrameLength, aMeshSource.GetShort(), aPriority);
     }
 
-    return error;
+    return;
 }
 
 otError MeshForwarder::GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest)
 {
-    otError                  error      = OT_ERROR_NONE;
-    uint8_t                  serviceId  = Mle::Mle::ServiceIdFromAloc(aServiceAloc);
-    NetworkData::ServiceTlv *serviceTlv = Get<NetworkData::Leader>().FindServiceById(serviceId);
+    otError                        error      = OT_ERROR_NONE;
+    uint8_t                        serviceId  = Mle::Mle::ServiceIdFromAloc(aServiceAloc);
+    const NetworkData::ServiceTlv *serviceTlv = Get<NetworkData::Leader>().FindServiceById(serviceId);
 
-    if (serviceTlv != NULL)
+    if (serviceTlv != nullptr)
     {
-        NetworkData::NetworkDataTlv *cur = serviceTlv->GetSubTlvs();
-        NetworkData::NetworkDataTlv *end = serviceTlv->GetNext();
-        NetworkData::ServerTlv *     server;
-        uint8_t                      bestCost = Mle::kMaxRouteCost;
-        uint8_t                      curCost  = 0x00;
-        uint16_t                     bestDest = Mac::kShortAddrInvalid;
+        const NetworkData::NetworkDataTlv *cur = serviceTlv->GetSubTlvs();
+        const NetworkData::NetworkDataTlv *end = serviceTlv->GetNext();
+        Neighbor *                         neighbor;
+        uint16_t                           server16;
+        uint8_t                            bestCost = Mle::kMaxRouteCost;
+        uint8_t                            curCost  = 0x00;
+        uint16_t                           bestDest = Mac::kShortAddrInvalid;
 
         while (cur < end)
         {
             switch (cur->GetType())
             {
             case NetworkData::NetworkDataTlv::kTypeServer:
-                server  = static_cast<NetworkData::ServerTlv *>(cur);
-                curCost = Get<Mle::MleRouter>().GetCost(server->GetServer16());
+                server16 = static_cast<const NetworkData::ServerTlv *>(cur)->GetServer16();
+
+                // Path cost
+                curCost = Get<Mle::MleRouter>().GetCost(server16);
+
+                if (!Get<Mle::MleRouter>().IsActiveRouter(server16))
+                {
+                    // Assume best link between remote child server and its parent.
+                    curCost += 1;
+                }
+
+                // Cost if the server is direct neighbor.
+                neighbor = Get<Mle::MleRouter>().GetNeighbor(server16);
+
+                if (neighbor != nullptr && neighbor->IsStateValid())
+                {
+                    uint8_t cost;
+
+                    if (!Get<Mle::MleRouter>().IsActiveRouter(server16))
+                    {
+                        // Cost calculated only from Link Quality In as the parent only maintains
+                        // one-direction link info.
+                        cost = Mle::MleRouter::LinkQualityToCost(neighbor->GetLinkInfo().GetLinkQuality());
+                    }
+                    else
+                    {
+                        cost = Get<Mle::MleRouter>().GetLinkCost(Mle::Mle::RouterIdFromRloc16(server16));
+                    }
+
+                    // Choose the minimum cost
+                    if (cost < curCost)
+                    {
+                        curCost = cost;
+                    }
+                }
 
                 if ((bestDest == Mac::kShortAddrInvalid) || (curCost < bestCost))
                 {
-                    bestDest = server->GetServer16();
+                    bestDest = server16;
                     bestCost = curCost;
                 }
 
@@ -869,8 +1008,8 @@
     otLogMac(
         aLogLevel, "%s mesh frame, len:%d%s%s, msrc:%s, mdst:%s, hops:%d, frag:%s, sec:%s%s%s%s%s",
         MessageActionToString(aAction, aError), aMessage.GetLength(),
-        (aMacAddress == NULL) ? "" : ((aAction == kMessageReceive) ? ", from:" : ", to:"),
-        (aMacAddress == NULL) ? "" : aMacAddress->ToString().AsCString(), aMeshSource.ToString().AsCString(),
+        (aMacAddress == nullptr) ? "" : ((aAction == kMessageReceive) ? ", from:" : ", to:"),
+        (aMacAddress == nullptr) ? "" : aMacAddress->ToString().AsCString(), aMeshSource.ToString().AsCString(),
         aMeshDest.ToString().AsCString(), meshHeader.GetHopsLeft() + ((aAction == kMessageReceive) ? 1 : 0),
         hasFragmentHeader ? "yes" : "no", aMessage.IsLinkSecurityEnabled() ? "yes" : "no",
         (aError == OT_ERROR_NONE) ? "" : ", error:", (aError == OT_ERROR_NONE) ? "" : otThreadErrorToString(aError),
@@ -881,7 +1020,7 @@
         otLogMac(aLogLevel, "    Frag tag:%04x, offset:%d, size:%d", fragmentHeader.GetDatagramTag(),
                  fragmentHeader.GetDatagramOffset(), fragmentHeader.GetDatagramSize());
 
-        VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0);
+        VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0, OT_NOOP);
     }
 
     error = OT_ERROR_NONE;
@@ -906,8 +1045,8 @@
     uint16_t frameLength;
     union
     {
-        Ip6::UdpHeader udp;
-        Ip6::TcpHeader tcp;
+        Ip6::Udp::Header udp;
+        Ip6::Tcp::Header tcp;
     } header;
 
     aChecksum   = 0;
@@ -920,7 +1059,7 @@
 
     headerLength = Get<Lowpan::Lowpan>().DecompressBaseHeader(aIp6Header, nextHeaderCompressed, aMeshSource, aMeshDest,
                                                               frameBuffer, frameLength);
-    VerifyOrExit(headerLength >= 0);
+    VerifyOrExit(headerLength >= 0, OT_NOOP);
 
     aOffset += headerLength;
 
@@ -931,13 +1070,14 @@
     case Ip6::kProtoUdp:
         if (nextHeaderCompressed)
         {
-            frameLength  = aMessage.Read(aOffset, sizeof(Ip6::UdpHeader), frameBuffer);
+            frameLength  = aMessage.Read(aOffset, sizeof(Ip6::Udp::Header), frameBuffer);
             headerLength = Get<Lowpan::Lowpan>().DecompressUdpHeader(header.udp, frameBuffer, frameLength);
-            VerifyOrExit(headerLength >= 0);
+            VerifyOrExit(headerLength >= 0, OT_NOOP);
         }
         else
         {
-            VerifyOrExit(sizeof(Ip6::UdpHeader) == aMessage.Read(aOffset, sizeof(Ip6::UdpHeader), &header.udp));
+            VerifyOrExit(sizeof(Ip6::Udp::Header) == aMessage.Read(aOffset, sizeof(Ip6::Udp::Header), &header.udp),
+                         OT_NOOP);
         }
 
         aChecksum   = header.udp.GetChecksum();
@@ -946,7 +1086,8 @@
         break;
 
     case Ip6::kProtoTcp:
-        VerifyOrExit(sizeof(Ip6::TcpHeader) == aMessage.Read(aOffset, sizeof(Ip6::TcpHeader), &header.tcp));
+        VerifyOrExit(sizeof(Ip6::Tcp::Header) == aMessage.Read(aOffset, sizeof(Ip6::Tcp::Header), &header.tcp),
+                     OT_NOOP);
         aChecksum   = header.tcp.GetChecksum();
         aSourcePort = header.tcp.GetSourcePort();
         aDestPort   = header.tcp.GetDestinationPort();
@@ -1003,7 +1144,7 @@
     // logged when the same Mesh Header message was received
     // and info about it was logged.
 
-    VerifyOrExit(aAction != kMessageTransmit);
+    VerifyOrExit(aAction != kMessageTransmit, OT_NOOP);
 
     LogMeshIpHeader(aMessage, offset, meshSource, meshDest, aLogLevel);
 
diff --git a/src/core/thread/mesh_forwarder_mtd.cpp b/src/core/thread/mesh_forwarder_mtd.cpp
index c6099d0..d637a54 100644
--- a/src/core/thread/mesh_forwarder_mtd.cpp
+++ b/src/core/thread/mesh_forwarder_mtd.cpp
@@ -39,27 +39,24 @@
 
 otError MeshForwarder::SendMessage(Message &aMessage)
 {
-    otError error;
-
     aMessage.SetDirectTransmission();
     aMessage.SetOffset(0);
     aMessage.SetDatagramTag(0);
 
-    SuccessOrExit(error = mSendQueue.Enqueue(aMessage));
+    mSendQueue.Enqueue(aMessage);
     mScheduleTransmissionTask.Post();
 
-exit:
-    return error;
+    return OT_ERROR_NONE;
 }
 
-otError MeshForwarder::EvictMessage(uint8_t aPriority)
+otError MeshForwarder::EvictMessage(Message::Priority aPriority)
 {
     otError  error = OT_ERROR_NOT_FOUND;
     Message *message;
 
-    VerifyOrExit((message = mSendQueue.GetTail()) != NULL);
+    VerifyOrExit((message = mSendQueue.GetTail()) != nullptr, OT_NOOP);
 
-    if (message->GetPriority() < aPriority)
+    if (message->GetPriority() < static_cast<uint8_t>(aPriority))
     {
         RemoveMessage(*message);
         ExitNow(error = OT_ERROR_NONE);
diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp
index 715cf77..31ce1a2 100644
--- a/src/core/thread/mle.cpp
+++ b/src/core/thread/mle.cpp
@@ -62,22 +62,25 @@
 
 Mle::Mle(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , Notifier::Receiver(aInstance, Mle::HandleNotifierEvents)
     , mRetrieveNewNetworkData(false)
-    , mRole(OT_DEVICE_ROLE_DISABLED)
+    , mRole(kRoleDisabled)
     , mDeviceMode(DeviceMode::kModeRxOnWhenIdle | DeviceMode::kModeSecureDataRequest)
     , mAttachState(kAttachStateIdle)
     , mReattachState(kReattachStop)
     , mAttachCounter(0)
     , mAnnounceDelay(kAnnounceTimeout)
-    , mAttachTimer(aInstance, &Mle::HandleAttachTimer, this)
-    , mDelayedResponseTimer(aInstance, &Mle::HandleDelayedResponseTimer, this)
-    , mMessageTransmissionTimer(aInstance, &Mle::HandleMessageTransmissionTimer, this)
+    , mAttachTimer(aInstance, Mle::HandleAttachTimer, this)
+    , mDelayedResponseTimer(aInstance, Mle::HandleDelayedResponseTimer, this)
+    , mMessageTransmissionTimer(aInstance, Mle::HandleMessageTransmissionTimer, this)
     , mParentLeaderCost(0)
     , mParentRequestMode(kAttachAny)
     , mParentPriority(0)
     , mParentLinkQuality3(0)
     , mParentLinkQuality2(0)
     , mParentLinkQuality1(0)
+    , mParentSedBufferSize(0)
+    , mParentSedDatagramCount(0)
     , mChildUpdateAttempts(0)
     , mChildUpdateRequestState(kChildUpdateRequestNone)
     , mDataRequestAttempts(0)
@@ -86,14 +89,8 @@
     , mParentLinkMargin(0)
     , mParentIsSingleton(false)
     , mReceivedResponseFromParent(false)
-    , mSocket(aInstance.Get<Ip6::Udp>())
+    , mSocket(aInstance)
     , mTimeout(kMleEndDeviceTimeout)
-    , mDiscoverHandler(NULL)
-    , mDiscoverContext(NULL)
-    , mDiscoverCcittIndex(0)
-    , mDiscoverAnsiIndex(0)
-    , mDiscoverInProgress(false)
-    , mDiscoverEnableFiltering(false)
 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
     , mPreviousParentRloc(Mac::kShortAddrInvalid)
 #endif
@@ -102,36 +99,38 @@
     , mParentSearchBackoffWasCanceled(false)
     , mParentSearchRecentlyDetached(false)
     , mParentSearchBackoffCancelTime(0)
-    , mParentSearchTimer(aInstance, &Mle::HandleParentSearchTimer, this)
+    , mParentSearchTimer(aInstance, Mle::HandleParentSearchTimer, this)
 #endif
     , mAnnounceChannel(0)
     , mAlternateChannel(0)
     , mAlternatePanId(Mac::kPanIdBroadcast)
     , mAlternateTimestamp(0)
-    , mNotifierCallback(aInstance, &Mle::HandleStateChanged, this)
-    , mParentResponseCb(NULL)
-    , mParentResponseCbContext(NULL)
+    , mParentResponseCb(nullptr)
+    , mParentResponseCbContext(nullptr)
 {
-    otMeshLocalPrefix meshLocalPrefix;
+    MeshLocalPrefix meshLocalPrefix;
+
+    mParent.Init(aInstance);
+    mParentCandidate.Init(aInstance);
 
     mLeaderData.Clear();
     mParentLeaderData.Clear();
     mParent.Clear();
-    memset(&mChildIdRequest, 0, sizeof(mChildIdRequest));
     mParentCandidate.Clear();
     ResetCounters();
 
     // link-local 64
     mLinkLocal64.Clear();
-    mLinkLocal64.GetAddress().mFields.m16[0] = HostSwap16(0xfe80);
-    mLinkLocal64.GetAddress().SetIid(Get<Mac::Mac>().GetExtAddress());
-    mLinkLocal64.mPrefixLength = 64;
-    mLinkLocal64.mPreferred    = true;
-    mLinkLocal64.mValid        = true;
+    mLinkLocal64.GetAddress().SetToLinkLocalAddress(Get<Mac::Mac>().GetExtAddress());
+    mLinkLocal64.mPrefixLength  = 64;
+    mLinkLocal64.mAddressOrigin = OT_ADDRESS_ORIGIN_THREAD;
+    mLinkLocal64.mPreferred     = true;
+    mLinkLocal64.mValid         = true;
 
     // Leader Aloc
     mLeaderAloc.Clear();
-    mLeaderAloc.mPrefixLength       = 64;
+    mLeaderAloc.mPrefixLength       = MeshLocalPrefix::kLength;
+    mLeaderAloc.mAddressOrigin      = OT_ADDRESS_ORIGIN_THREAD;
     mLeaderAloc.mPreferred          = true;
     mLeaderAloc.mValid              = true;
     mLeaderAloc.mScopeOverride      = Ip6::Address::kRealmLocalScope;
@@ -143,28 +142,26 @@
     for (size_t i = 0; i < OT_ARRAY_LENGTH(mServiceAlocs); i++)
     {
         mServiceAlocs[i].Clear();
-        mServiceAlocs[i].mPrefixLength               = 64;
-        mServiceAlocs[i].mPreferred                  = true;
-        mServiceAlocs[i].mValid                      = true;
-        mServiceAlocs[i].mScopeOverride              = Ip6::Address::kRealmLocalScope;
-        mServiceAlocs[i].mScopeOverrideValid         = true;
-        mServiceAlocs[i].GetAddress().mFields.m16[7] = HostSwap16(Mac::kShortAddrInvalid);
+        mServiceAlocs[i].mPrefixLength       = MeshLocalPrefix::kLength;
+        mServiceAlocs[i].mAddressOrigin      = OT_ADDRESS_ORIGIN_THREAD;
+        mServiceAlocs[i].mPreferred          = true;
+        mServiceAlocs[i].mValid              = true;
+        mServiceAlocs[i].mScopeOverride      = Ip6::Address::kRealmLocalScope;
+        mServiceAlocs[i].mScopeOverrideValid = true;
+        mServiceAlocs[i].GetAddress().GetIid().SetLocator(Mac::kShortAddrInvalid);
     }
 
 #endif
 
     // initialize Mesh Local Prefix
-    meshLocalPrefix.m8[0] = 0xfd;
-    memcpy(&meshLocalPrefix.m8[1], Get<Mac::Mac>().GetExtendedPanId().m8, 5);
-    meshLocalPrefix.m8[6] = 0x00;
-    meshLocalPrefix.m8[7] = 0x00;
+    meshLocalPrefix.SetFromExtendedPanId(Get<Mac::Mac>().GetExtendedPanId());
 
     // mesh-local 64
     mMeshLocal64.Clear();
-    Random::NonCrypto::FillBuffer(mMeshLocal64.GetAddress().mFields.m8 + OT_IP6_PREFIX_SIZE,
-                                  OT_IP6_ADDRESS_SIZE - OT_IP6_PREFIX_SIZE);
+    mMeshLocal64.GetAddress().GetIid().GenerateRandom();
 
-    mMeshLocal64.mPrefixLength       = 64;
+    mMeshLocal64.mPrefixLength       = MeshLocalPrefix::kLength;
+    mMeshLocal64.mAddressOrigin      = OT_ADDRESS_ORIGIN_THREAD;
     mMeshLocal64.mPreferred          = true;
     mMeshLocal64.mValid              = true;
     mMeshLocal64.mScopeOverride      = Ip6::Address::kRealmLocalScope;
@@ -172,15 +169,14 @@
 
     // mesh-local 16
     mMeshLocal16.Clear();
-    mMeshLocal16.GetAddress().mFields.m16[4] = HostSwap16(0x0000);
-    mMeshLocal16.GetAddress().mFields.m16[5] = HostSwap16(0x00ff);
-    mMeshLocal16.GetAddress().mFields.m16[6] = HostSwap16(0xfe00);
-    mMeshLocal16.mPrefixLength               = 64;
-    mMeshLocal16.mPreferred                  = true;
-    mMeshLocal16.mValid                      = true;
-    mMeshLocal16.mScopeOverride              = Ip6::Address::kRealmLocalScope;
-    mMeshLocal16.mScopeOverrideValid         = true;
-    mMeshLocal16.mRloc                       = true;
+    mMeshLocal16.GetAddress().GetIid().SetToLocator(0);
+    mMeshLocal16.mPrefixLength       = MeshLocalPrefix::kLength;
+    mMeshLocal16.mAddressOrigin      = OT_ADDRESS_ORIGIN_THREAD;
+    mMeshLocal16.mPreferred          = true;
+    mMeshLocal16.mValid              = true;
+    mMeshLocal16.mScopeOverride      = Ip6::Address::kRealmLocalScope;
+    mMeshLocal16.mScopeOverrideValid = true;
+    mMeshLocal16.mRloc               = true;
 
     // Store RLOC address reference in MPL module.
     Get<Ip6::Mpl>().SetMatchingAddress(mMeshLocal16.GetAddress());
@@ -226,7 +222,7 @@
 
     Stop(false);
     SuccessOrExit(error = mSocket.Close());
-    SuccessOrExit(error = Get<ThreadNetif>().RemoveUnicastAddress(mLinkLocal64));
+    Get<ThreadNetif>().RemoveUnicastAddress(mLinkLocal64);
 
 exit:
     return error;
@@ -270,19 +266,21 @@
 
     if (aAnnounceAttach || (GetRloc16() == Mac::kShortAddrInvalid))
     {
-        BecomeChild(kAttachAny);
+        IgnoreError(BecomeChild(kAttachAny));
     }
+#if OPENTHREAD_FTD
     else if (IsActiveRouter(GetRloc16()))
     {
         if (Get<MleRouter>().BecomeRouter(ThreadStatusTlv::kTooFewRouters) != OT_ERROR_NONE)
         {
-            BecomeChild(kAttachAny);
+            IgnoreError(BecomeChild(kAttachAny));
         }
     }
+#endif
     else
     {
         mChildUpdateAttempts = 0;
-        SendChildUpdateRequest();
+        IgnoreError(SendChildUpdateRequest());
     }
 
 exit:
@@ -297,7 +295,7 @@
         Get<MeshCoP::PendingDataset>().HandleDetach();
     }
 
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED);
+    VerifyOrExit(!IsDisabled(), OT_NOOP);
 
     Get<KeyManager>().Stop();
     SetStateDetached();
@@ -306,49 +304,44 @@
     Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal16);
     Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal64);
 
-    SetRole(OT_DEVICE_ROLE_DISABLED);
+    SetRole(kRoleDisabled);
 
 exit:
     return;
 }
 
-void Mle::SetRole(otDeviceRole aRole)
+void Mle::SetRole(DeviceRole aRole)
 {
-    otDeviceRole oldRole = mRole;
+    DeviceRole oldRole = mRole;
 
-    SuccessOrExit(Get<Notifier>().Update(mRole, aRole, OT_CHANGED_THREAD_ROLE));
+    SuccessOrExit(Get<Notifier>().Update(mRole, aRole, kEventThreadRoleChanged));
 
     otLogNoteMle("Role %s -> %s", RoleToString(oldRole), RoleToString(mRole));
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
+    case kRoleDisabled:
         mCounters.mDisabledRole++;
         break;
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDetached:
         mCounters.mDetachedRole++;
         break;
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         mCounters.mChildRole++;
         break;
-    case OT_DEVICE_ROLE_ROUTER:
+    case kRoleRouter:
         mCounters.mRouterRole++;
         break;
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleLeader:
         mCounters.mLeaderRole++;
         break;
     }
 
-#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
-    if (IsAttached())
+    // If the previous state is disabled, the parent can be in kStateRestored.
+    if (!IsChild() && oldRole != kRoleDisabled)
     {
-        SuccessOrExit(Get<MeshCoP::BorderAgent>().Start());
+        mParent.SetState(Neighbor::kStateInvalid);
     }
-    else
-    {
-        SuccessOrExit(Get<MeshCoP::BorderAgent>().Stop());
-    }
-#endif
 
 exit:
     OT_UNUSED_VARIABLE(oldRole);
@@ -356,7 +349,7 @@
 
 void Mle::SetAttachState(AttachState aState)
 {
-    VerifyOrExit(aState != mAttachState);
+    VerifyOrExit(aState != mAttachState, OT_NOOP);
     otLogInfoMle("AttachState %s -> %s", AttachStateToString(mAttachState), AttachStateToString(aState));
     mAttachState = aState;
 
@@ -370,39 +363,45 @@
     Settings::NetworkInfo networkInfo;
     Settings::ParentInfo  parentInfo;
 
-    Get<MeshCoP::ActiveDataset>().Restore();
-    Get<MeshCoP::PendingDataset>().Restore();
+    IgnoreError(Get<MeshCoP::ActiveDataset>().Restore());
+    IgnoreError(Get<MeshCoP::PendingDataset>().Restore());
+
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    Get<DuaManager>().Restore();
+#endif
 
     SuccessOrExit(error = Get<Settings>().ReadNetworkInfo(networkInfo));
 
-    Get<KeyManager>().SetCurrentKeySequence(networkInfo.mKeySequence);
-    Get<KeyManager>().SetMleFrameCounter(networkInfo.mMleFrameCounter);
-    Get<KeyManager>().SetMacFrameCounter(networkInfo.mMacFrameCounter);
-    mDeviceMode.Set(networkInfo.mDeviceMode);
+    Get<KeyManager>().SetCurrentKeySequence(networkInfo.GetKeySequence());
+    Get<KeyManager>().SetMleFrameCounter(networkInfo.GetMleFrameCounter());
+    Get<KeyManager>().SetMacFrameCounter(networkInfo.GetMacFrameCounter());
+    mDeviceMode.Set(networkInfo.GetDeviceMode());
 
-    switch (networkInfo.mRole)
+    // force re-attach when version mismatch.
+    VerifyOrExit(networkInfo.GetVersion() == kThreadVersion, OT_NOOP);
+
+    switch (networkInfo.GetRole())
     {
-    case OT_DEVICE_ROLE_CHILD:
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleChild:
+    case kRoleRouter:
+    case kRoleLeader:
         break;
 
     default:
         ExitNow();
     }
 
-    Get<Mac::Mac>().SetShortAddress(networkInfo.mRloc16);
-    Get<Mac::Mac>().SetExtAddress(networkInfo.mExtAddress);
+    Get<Mac::Mac>().SetShortAddress(networkInfo.GetRloc16());
+    Get<Mac::Mac>().SetExtAddress(networkInfo.GetExtAddress());
 
-    memcpy(&mMeshLocal64.GetAddress().mFields.m8[OT_IP6_PREFIX_SIZE], networkInfo.mMlIid,
-           OT_IP6_ADDRESS_SIZE - OT_IP6_PREFIX_SIZE);
+    mMeshLocal64.GetAddress().SetIid(networkInfo.GetMeshLocalIid());
 
-    if (networkInfo.mRloc16 == Mac::kShortAddrInvalid)
+    if (networkInfo.GetRloc16() == Mac::kShortAddrInvalid)
     {
         ExitNow();
     }
 
-    if (!IsActiveRouter(networkInfo.mRloc16))
+    if (!IsActiveRouter(networkInfo.GetRloc16()))
     {
         error = Get<Settings>().ReadParentInfo(parentInfo);
 
@@ -415,27 +414,30 @@
             // exchange) and going through the full attach process.
 
             otLogWarnMle("Invalid settings - no saved parent info with valid end-device RLOC16 0x%04x",
-                         networkInfo.mRloc16);
+                         networkInfo.GetRloc16());
             ExitNow();
         }
 
         mParent.Clear();
-        mParent.SetExtAddress(*static_cast<Mac::ExtAddress *>(&parentInfo.mExtAddress));
+        mParent.SetExtAddress(parentInfo.GetExtAddress());
+        mParent.SetVersion(static_cast<uint8_t>(parentInfo.GetVersion()));
         mParent.SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle |
                                          DeviceMode::kModeFullNetworkData | DeviceMode::kModeSecureDataRequest));
-        mParent.SetRloc16(Rloc16FromRouterId(RouterIdFromRloc16(networkInfo.mRloc16)));
+        mParent.SetRloc16(Rloc16FromRouterId(RouterIdFromRloc16(networkInfo.GetRloc16())));
         mParent.SetState(Neighbor::kStateRestored);
 
 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
         mPreviousParentRloc = mParent.GetRloc16();
 #endif
     }
+#if OPENTHREAD_FTD
     else
     {
         Get<MleRouter>().SetRouterId(RouterIdFromRloc16(GetRloc16()));
-        Get<MleRouter>().SetPreviousPartitionId(networkInfo.mPreviousPartitionId);
+        Get<MleRouter>().SetPreviousPartitionId(networkInfo.GetPreviousPartitionId());
         Get<MleRouter>().RestoreChildren();
     }
+#endif
 
 exit:
     return error;
@@ -446,7 +448,7 @@
     otError               error = OT_ERROR_NONE;
     Settings::NetworkInfo networkInfo;
 
-    networkInfo.Clear();
+    networkInfo.Init();
 
     if (IsAttached())
     {
@@ -454,18 +456,20 @@
         // avoid losing/overwriting previous information when a reboot
         // occurs after a message is sent but before attaching.
 
-        networkInfo.mRole                = mRole;
-        networkInfo.mRloc16              = GetRloc16();
-        networkInfo.mPreviousPartitionId = mLeaderData.GetPartitionId();
-        networkInfo.mExtAddress          = Get<Mac::Mac>().GetExtAddress();
-        memcpy(networkInfo.mMlIid, &mMeshLocal64.GetAddress().mFields.m8[OT_IP6_PREFIX_SIZE], OT_IP6_IID_SIZE);
+        networkInfo.SetRole(mRole);
+        networkInfo.SetRloc16(GetRloc16());
+        networkInfo.SetPreviousPartitionId(mLeaderData.GetPartitionId());
+        networkInfo.SetExtAddress(Get<Mac::Mac>().GetExtAddress());
+        networkInfo.SetMeshLocalIid(mMeshLocal64.GetAddress().GetIid());
+        networkInfo.SetVersion(kThreadVersion);
 
-        if (mRole == OT_DEVICE_ROLE_CHILD)
+        if (IsChild())
         {
             Settings::ParentInfo parentInfo;
 
-            parentInfo.Clear();
-            parentInfo.mExtAddress = mParent.GetExtAddress();
+            parentInfo.Init();
+            parentInfo.SetExtAddress(mParent.GetExtAddress());
+            parentInfo.SetVersion(mParent.GetVersion());
 
             SuccessOrExit(error = Get<Settings>().SaveParentInfo(parentInfo));
         }
@@ -483,15 +487,17 @@
         SuccessOrExit(Get<Settings>().ReadNetworkInfo(networkInfo));
     }
 
-    networkInfo.mKeySequence     = Get<KeyManager>().GetCurrentKeySequence();
-    networkInfo.mMleFrameCounter = Get<KeyManager>().GetMleFrameCounter() + OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
-    networkInfo.mMacFrameCounter = Get<KeyManager>().GetMacFrameCounter() + OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
-    networkInfo.mDeviceMode      = mDeviceMode.Get();
+    networkInfo.SetKeySequence(Get<KeyManager>().GetCurrentKeySequence());
+    networkInfo.SetMleFrameCounter(Get<KeyManager>().GetMleFrameCounter() +
+                                   OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD);
+    networkInfo.SetMacFrameCounter(Get<KeyManager>().GetMacFrameCounter() +
+                                   OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD);
+    networkInfo.SetDeviceMode(mDeviceMode.Get());
 
     SuccessOrExit(error = Get<Settings>().SaveNetworkInfo(networkInfo));
 
-    Get<KeyManager>().SetStoredMleFrameCounter(networkInfo.mMleFrameCounter);
-    Get<KeyManager>().SetStoredMacFrameCounter(networkInfo.mMacFrameCounter);
+    Get<KeyManager>().SetStoredMleFrameCounter(networkInfo.GetMleFrameCounter());
+    Get<KeyManager>().SetStoredMacFrameCounter(networkInfo.GetMacFrameCounter());
 
     otLogDebgMle("Store Network Information");
 
@@ -499,105 +505,17 @@
     return error;
 }
 
-otError Mle::Discover(const Mac::ChannelMask &aScanChannels,
-                      uint16_t                aPanId,
-                      bool                    aJoiner,
-                      bool                    aEnableFiltering,
-                      DiscoverHandler         aCallback,
-                      void *                  aContext)
-{
-    otError                      error   = OT_ERROR_NONE;
-    Message *                    message = NULL;
-    Ip6::Address                 destination;
-    Tlv                          tlv;
-    MeshCoP::DiscoveryRequestTlv discoveryRequest;
-    uint16_t                     startOffset;
-
-    VerifyOrExit(!mDiscoverInProgress, error = OT_ERROR_BUSY);
-
-    mDiscoverEnableFiltering = aEnableFiltering;
-
-    if (mDiscoverEnableFiltering)
-    {
-        Mac::ExtAddress extAddress;
-        Crc16           ccitt(Crc16::kCcitt);
-        Crc16           ansi(Crc16::kAnsi);
-
-        Get<Radio>().GetIeeeEui64(extAddress);
-        MeshCoP::ComputeJoinerId(extAddress, extAddress);
-
-        // Compute bloom filter (for steering data)
-        for (size_t i = 0; i < sizeof(extAddress.m8); i++)
-        {
-            ccitt.Update(extAddress.m8[i]);
-            ansi.Update(extAddress.m8[i]);
-        }
-
-        mDiscoverCcittIndex = ccitt.Get();
-        mDiscoverAnsiIndex  = ansi.Get();
-    }
-
-    mDiscoverHandler = aCallback;
-    mDiscoverContext = aContext;
-    Get<MeshForwarder>().SetDiscoverParameters(aScanChannels);
-
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
-    message->SetSubType(Message::kSubTypeMleDiscoverRequest);
-    message->SetPanId(aPanId);
-    SuccessOrExit(error = AppendHeader(*message, Header::kCommandDiscoveryRequest));
-
-    // Discovery TLV
-    tlv.SetType(Tlv::kDiscovery);
-    SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
-
-    startOffset = message->GetLength();
-
-    // Discovery Request TLV
-    discoveryRequest.Init();
-    discoveryRequest.SetVersion(kThreadVersion);
-    discoveryRequest.SetJoiner(aJoiner);
-    SuccessOrExit(error = discoveryRequest.AppendTo(*message));
-
-    tlv.SetLength(static_cast<uint8_t>(message->GetLength() - startOffset));
-    message->Write(startOffset - sizeof(tlv), sizeof(tlv), &tlv);
-
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xff02);
-    destination.mFields.m16[7] = HostSwap16(0x0002);
-    SuccessOrExit(error = SendMessage(*message, destination));
-
-    mDiscoverInProgress = true;
-
-    LogMleMessage("Send Discovery Request", destination);
-
-exit:
-
-    if (error != OT_ERROR_NONE && message != NULL)
-    {
-        message->Free();
-    }
-
-    return error;
-}
-
-void Mle::HandleDiscoverComplete(void)
-{
-    mDiscoverInProgress      = false;
-    mDiscoverEnableFiltering = false;
-    mDiscoverHandler(NULL, mDiscoverContext);
-}
-
 otError Mle::BecomeDetached(void)
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(!IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     // In case role is already detached and attach state is `kAttachStateStart`
     // (i.e., waiting to start an attach attempt), there is no need to make any
     // changes.
 
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DETACHED || mAttachState != kAttachStateStart);
+    VerifyOrExit(!IsDetached() || mAttachState != kAttachStateStart, OT_NOOP);
 
     // not in reattach stage after reset
     if (mReattachState == kReattachStop)
@@ -612,7 +530,7 @@
     SetStateDetached();
     mParent.SetState(Neighbor::kStateInvalid);
     SetRloc16(Mac::kShortAddrInvalid);
-    BecomeChild(kAttachAny);
+    IgnoreError(BecomeChild(kAttachAny));
 
 exit:
     return error;
@@ -622,7 +540,7 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(!IsDisabled(), error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(!IsAttaching(), error = OT_ERROR_BUSY);
 
     if (mReattachState == kReattachStart)
@@ -643,10 +561,12 @@
 
     if (aMode != kAttachBetter)
     {
+#if OPENTHREAD_FTD
         if (IsFullThreadDevice())
         {
             Get<MleRouter>().StopAdvertiseTimer();
         }
+#endif
     }
     else
     {
@@ -655,7 +575,7 @@
 
     mAttachTimer.Start(GetAttachStartDelay());
 
-    if (mRole == OT_DEVICE_ROLE_DETACHED)
+    if (IsDetached())
     {
         mAttachCounter++;
 
@@ -681,7 +601,7 @@
     uint32_t delay = 1;
     uint32_t jitter;
 
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_DETACHED);
+    VerifyOrExit(IsDetached(), OT_NOOP);
 
     if (mAttachCounter == 0)
     {
@@ -722,17 +642,29 @@
 
 bool Mle::IsAttached(void) const
 {
-    return (mRole == OT_DEVICE_ROLE_CHILD || mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER);
+    return (IsChild() || IsRouter() || IsLeader());
+}
+
+bool Mle::IsRouterOrLeader(void) const
+{
+    return (IsRouter() || IsLeader());
 }
 
 void Mle::SetStateDetached(void)
 {
-    if (mRole == OT_DEVICE_ROLE_LEADER)
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    Get<BackboneRouter::Local>().Reset();
+#endif
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+    Get<BackboneRouter::Leader>().Reset();
+#endif
+
+    if (IsLeader())
     {
         Get<ThreadNetif>().RemoveUnicastAddress(mLeaderAloc);
     }
 
-    SetRole(OT_DEVICE_ROLE_DETACHED);
+    SetRole(kRoleDetached);
     SetAttachState(kAttachStateIdle);
     mAttachTimer.Stop();
     mMessageTransmissionTimer.Stop();
@@ -742,20 +674,24 @@
     mDataRequestAttempts     = 0;
     Get<MeshForwarder>().SetRxOnWhenIdle(true);
     Get<Mac::Mac>().SetBeaconEnabled(false);
+#if OPENTHREAD_FTD
     Get<MleRouter>().HandleDetachStart();
+#endif
     Get<Ip6::Ip6>().SetForwardingEnabled(false);
+#if OPENTHREAD_FTD
     Get<Ip6::Mpl>().SetTimerExpirations(0);
+#endif
 }
 
 void Mle::SetStateChild(uint16_t aRloc16)
 {
-    if (mRole == OT_DEVICE_ROLE_LEADER)
+    if (IsLeader())
     {
         Get<ThreadNetif>().RemoveUnicastAddress(mLeaderAloc);
     }
 
     SetRloc16(aRloc16);
-    SetRole(OT_DEVICE_ROLE_CHILD);
+    SetRole(kRoleChild);
     SetAttachState(kAttachStateIdle);
     mAttachTimer.Stop();
     mAttachCounter       = 0;
@@ -765,16 +701,17 @@
     Get<Mac::Mac>().SetBeaconEnabled(false);
     ScheduleMessageTransmissionTimer();
 
+#if OPENTHREAD_FTD
     if (IsFullThreadDevice())
     {
         Get<MleRouter>().HandleChildStart(mParentRequestMode);
     }
-
-#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
-    Get<NetworkData::Local>().ClearResubmitDelayTimer();
 #endif
+
     Get<Ip6::Ip6>().SetForwardingEnabled(false);
+#if OPENTHREAD_FTD
     Get<Ip6::Mpl>().SetTimerExpirations(kMplChildDataMessageTimerExpirations);
+#endif
 
     // send announce after attached if needed
     InformPreviousChannel();
@@ -791,15 +728,16 @@
 
 void Mle::InformPreviousChannel(void)
 {
-    VerifyOrExit(mAlternatePanId != Mac::kPanIdBroadcast);
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_CHILD || mRole == OT_DEVICE_ROLE_ROUTER);
+    VerifyOrExit(mAlternatePanId != Mac::kPanIdBroadcast, OT_NOOP);
+    VerifyOrExit(IsChild() || IsRouter(), OT_NOOP);
 
-    if (!IsFullThreadDevice() || mRole == OT_DEVICE_ROLE_ROUTER ||
-        Get<MleRouter>().GetRouterSelectionJitterTimeout() == 0)
-    {
-        mAlternatePanId = Mac::kPanIdBroadcast;
-        Get<AnnounceBeginServer>().SendAnnounce(1 << mAlternateChannel);
-    }
+#if OPENTHREAD_FTD
+    VerifyOrExit(!IsFullThreadDevice() || IsRouter() || Get<MleRouter>().GetRouterSelectionJitterTimeout() == 0,
+                 OT_NOOP);
+#endif
+
+    mAlternatePanId = Mac::kPanIdBroadcast;
+    Get<AnnounceBeginServer>().SendAnnounce(1 << mAlternateChannel);
 
 exit:
     return;
@@ -807,7 +745,7 @@
 
 void Mle::SetTimeout(uint32_t aTimeout)
 {
-    VerifyOrExit(mTimeout != aTimeout);
+    VerifyOrExit(mTimeout != aTimeout, OT_NOOP);
 
     if (aTimeout < kMinTimeout)
     {
@@ -818,9 +756,9 @@
 
     Get<DataPollSender>().RecalculatePollPeriod();
 
-    if (mRole == OT_DEVICE_ROLE_CHILD)
+    if (IsChild())
     {
-        SendChildUpdateRequest();
+        IgnoreError(SendChildUpdateRequest());
     }
 
 exit:
@@ -833,34 +771,34 @@
     DeviceMode oldMode = mDeviceMode;
 
     VerifyOrExit(aDeviceMode.IsValid(), error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit(mDeviceMode != aDeviceMode);
+    VerifyOrExit(mDeviceMode != aDeviceMode, OT_NOOP);
     mDeviceMode = aDeviceMode;
 
     otLogNoteMle("Mode 0x%02x -> 0x%02x [%s]", oldMode.Get(), mDeviceMode.Get(), mDeviceMode.ToString().AsCString());
 
-    Store();
+    IgnoreError(Store());
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
+    case kRoleDisabled:
         break;
 
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDetached:
         mAttachCounter = 0;
         SetStateDetached();
-        BecomeChild(kAttachAny);
+        IgnoreError(BecomeChild(kAttachAny));
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         SetStateChild(GetRloc16());
-        SendChildUpdateRequest();
+        IgnoreError(SendChildUpdateRequest());
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleRouter:
+    case kRoleLeader:
         if (oldMode.IsFullThreadDevice() && !mDeviceMode.IsFullThreadDevice())
         {
-            BecomeDetached();
+            IgnoreError(BecomeDetached());
         }
 
         break;
@@ -873,23 +811,21 @@
 void Mle::UpdateLinkLocalAddress(void)
 {
     Get<ThreadNetif>().RemoveUnicastAddress(mLinkLocal64);
-    mLinkLocal64.GetAddress().SetIid(Get<Mac::Mac>().GetExtAddress());
+    mLinkLocal64.GetAddress().GetIid().SetFromExtAddress(Get<Mac::Mac>().GetExtAddress());
     Get<ThreadNetif>().AddUnicastAddress(mLinkLocal64);
 
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_LL_ADDR);
+    Get<Notifier>().Signal(kEventThreadLinkLocalAddrChanged);
 }
 
-void Mle::SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix)
+void Mle::SetMeshLocalPrefix(const MeshLocalPrefix &aMeshLocalPrefix)
 {
-    if (memcmp(mMeshLocal64.GetAddress().mFields.m8, aMeshLocalPrefix.m8, sizeof(aMeshLocalPrefix)) == 0)
-    {
-        Get<Notifier>().SignalIfFirst(OT_CHANGED_THREAD_ML_ADDR);
-        ExitNow();
-    }
+    VerifyOrExit(GetMeshLocalPrefix() != aMeshLocalPrefix,
+                 Get<Notifier>().SignalIfFirst(kEventThreadMeshLocalAddrChanged));
 
     if (Get<ThreadNetif>().IsUp())
     {
         Get<ThreadNetif>().RemoveUnicastAddress(mLeaderAloc);
+
         // We must remove the old addresses before adding the new ones.
         Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal64);
         Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal16);
@@ -897,12 +833,12 @@
         Get<ThreadNetif>().UnsubscribeMulticast(mRealmLocalAllThreadNodes);
     }
 
-    memcpy(mMeshLocal64.GetAddress().mFields.m8, aMeshLocalPrefix.m8, sizeof(aMeshLocalPrefix));
-    memcpy(mMeshLocal16.GetAddress().mFields.m8, aMeshLocalPrefix.m8, sizeof(aMeshLocalPrefix));
-    memcpy(mLeaderAloc.GetAddress().mFields.m8, aMeshLocalPrefix.m8, sizeof(aMeshLocalPrefix));
+    mMeshLocal64.GetAddress().SetPrefix(aMeshLocalPrefix);
+    mMeshLocal16.GetAddress().SetPrefix(aMeshLocalPrefix);
+    mLeaderAloc.GetAddress().SetPrefix(aMeshLocalPrefix);
 
     // Just keep mesh local prefix if network interface is down
-    VerifyOrExit(Get<ThreadNetif>().IsUp());
+    VerifyOrExit(Get<ThreadNetif>().IsUp(), OT_NOOP);
 
     ApplyMeshLocalPrefix();
 
@@ -912,27 +848,10 @@
 
 void Mle::ApplyMeshLocalPrefix(void)
 {
-#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+    mLinkLocalAllThreadNodes.GetAddress().SetMulticastNetworkPrefix(GetMeshLocalPrefix());
+    mRealmLocalAllThreadNodes.GetAddress().SetMulticastNetworkPrefix(GetMeshLocalPrefix());
 
-    for (uint8_t i = 0; i < OT_ARRAY_LENGTH(mServiceAlocs); i++)
-    {
-        if (HostSwap16(mServiceAlocs[i].GetAddress().mFields.m16[7]) != Mac::kShortAddrInvalid)
-        {
-            Get<ThreadNetif>().RemoveUnicastAddress(mServiceAlocs[i]);
-            memcpy(mServiceAlocs[i].GetAddress().mFields.m8, mMeshLocal64.GetAddress().mFields.m8, 8);
-            Get<ThreadNetif>().AddUnicastAddress(mServiceAlocs[i]);
-        }
-    }
-
-#endif
-
-    mLinkLocalAllThreadNodes.GetAddress().mFields.m8[3] = 64;
-    memcpy(mLinkLocalAllThreadNodes.GetAddress().mFields.m8 + 4, mMeshLocal64.GetAddress().mFields.m8, 8);
-
-    mRealmLocalAllThreadNodes.GetAddress().mFields.m8[3] = 64;
-    memcpy(mRealmLocalAllThreadNodes.GetAddress().mFields.m8 + 4, mMeshLocal64.GetAddress().mFields.m8, 8);
-
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED);
+    VerifyOrExit(!IsDisabled(), OT_NOOP);
 
     // Add the addresses back into the table.
     Get<ThreadNetif>().AddUnicastAddress(mMeshLocal64);
@@ -945,14 +864,44 @@
     }
 
     // update Leader ALOC
-    if (mRole == OT_DEVICE_ROLE_LEADER)
+    if (IsLeader())
     {
         Get<ThreadNetif>().AddUnicastAddress(mLeaderAloc);
     }
 
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
+    Get<MeshCoP::Commissioner>().ApplyMeshLocalPrefix();
+#endif
+
+#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
+    Get<MeshCoP::BorderAgent>().ApplyMeshLocalPrefix();
+#endif
+
+#if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
+    Get<Dhcp6::Dhcp6Server>().ApplyMeshLocalPrefix();
+#endif
+
+#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(mServiceAlocs); i++)
+    {
+        if (mServiceAlocs[i].GetAddress().GetIid().GetLocator() != Mac::kShortAddrInvalid)
+        {
+            Get<ThreadNetif>().RemoveUnicastAddress(mServiceAlocs[i]);
+            mServiceAlocs[i].GetAddress().SetPrefix(GetMeshLocalPrefix());
+            Get<ThreadNetif>().AddUnicastAddress(mServiceAlocs[i]);
+        }
+    }
+
+#endif
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    Get<BackboneRouter::Local>().ApplyMeshLocalPrefix();
+#endif
+
 exit:
     // Changing the prefix also causes the mesh local address to be different.
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_ML_ADDR);
+    Get<Notifier>().Signal(kEventThreadMeshLocalAddrChanged);
 }
 
 uint16_t Mle::GetRloc16(void) const
@@ -967,6 +916,12 @@
     if (aRloc16 != oldRloc16)
     {
         otLogNoteMle("RLOC16 %04x -> %04x", oldRloc16, aRloc16);
+
+        // Clear cached CoAP with old RLOC source
+        if (oldRloc16 != Mac::kShortAddrInvalid)
+        {
+            Get<Coap::Coap>().ClearRequests(mMeshLocal16.GetAddress());
+        }
     }
 
     Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal16);
@@ -977,7 +932,7 @@
     if (aRloc16 != Mac::kShortAddrInvalid)
     {
         // mesh-local 16
-        mMeshLocal16.GetAddress().mFields.m16[7] = HostSwap16(aRloc16);
+        mMeshLocal16.GetAddress().GetIid().SetLocator(aRloc16);
         Get<ThreadNetif>().AddUnicastAddress(mMeshLocal16);
 #if OPENTHREAD_FTD
         Get<AddressResolver>().RestartAddressQueries();
@@ -989,13 +944,15 @@
 {
     if (mLeaderData.GetPartitionId() != aPartitionId)
     {
+#if OPENTHREAD_FTD
         Get<MleRouter>().HandlePartitionChange();
-        Get<Notifier>().Signal(OT_CHANGED_THREAD_PARTITION_ID);
+#endif
+        Get<Notifier>().Signal(kEventThreadPartitionIdChanged);
         mCounters.mPartitionIdChanges++;
     }
     else
     {
-        Get<Notifier>().SignalIfFirst(OT_CHANGED_THREAD_PARTITION_ID);
+        Get<Notifier>().SignalIfFirst(kEventThreadPartitionIdChanged);
     }
 
     mLeaderData.SetPartitionId(aPartitionId);
@@ -1009,24 +966,20 @@
 
     VerifyOrExit(GetRloc16() != Mac::kShortAddrInvalid, error = OT_ERROR_DETACHED);
 
-    memcpy(&aAddress, &mMeshLocal16.GetAddress(), 8);
-    aAddress.mFields.m16[4] = HostSwap16(0x0000);
-    aAddress.mFields.m16[5] = HostSwap16(0x00ff);
-    aAddress.mFields.m16[6] = HostSwap16(0xfe00);
-    aAddress.mFields.m16[7] = HostSwap16(Rloc16FromRouterId(mLeaderData.GetLeaderRouterId()));
+    aAddress.SetToRoutingLocator(GetMeshLocalPrefix(), Rloc16FromRouterId(mLeaderData.GetLeaderRouterId()));
 
 exit:
     return error;
 }
 
-otError Mle::GetAlocAddress(Ip6::Address &aAddress, uint16_t aAloc16) const
+otError Mle::GetLocatorAddress(Ip6::Address &aAddress, uint16_t aLocator) const
 {
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(GetRloc16() != Mac::kShortAddrInvalid, error = OT_ERROR_DETACHED);
 
     memcpy(&aAddress, &mMeshLocal16.GetAddress(), 14);
-    aAddress.mFields.m16[7] = HostSwap16(aAloc16);
+    aAddress.GetIid().SetLocator(aLocator);
 
 exit:
     return error;
@@ -1037,32 +990,13 @@
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(GetRloc16() != Mac::kShortAddrInvalid, error = OT_ERROR_DETACHED);
-
-    memcpy(&aAddress, &mMeshLocal16.GetAddress(), 8);
-    aAddress.mFields.m16[4] = HostSwap16(0x0000);
-    aAddress.mFields.m16[5] = HostSwap16(0x00ff);
-    aAddress.mFields.m16[6] = HostSwap16(0xfe00);
-    aAddress.mFields.m16[7] = HostSwap16(ServiceAlocFromId(aServiceId));
+    aAddress.SetToAnycastLocator(GetMeshLocalPrefix(), ServiceAlocFromId(aServiceId));
 
 exit:
     return error;
 }
 
-otError Mle::AddLeaderAloc(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_LEADER, error = OT_ERROR_INVALID_STATE);
-
-    SuccessOrExit(error = GetLeaderAloc(mLeaderAloc.GetAddress()));
-
-    error = Get<ThreadNetif>().AddUnicastAddress(mLeaderAloc);
-
-exit:
-    return error;
-}
-
-const LeaderDataTlv &Mle::GetLeaderDataTlv(void)
+const LeaderData &Mle::GetLeaderData(void)
 {
     mLeaderData.SetDataVersion(Get<NetworkData::Leader>().GetVersion());
     mLeaderData.SetStableDataVersion(Get<NetworkData::Leader>().GetStableVersion());
@@ -1070,30 +1004,13 @@
     return mLeaderData;
 }
 
-otError Mle::GetLeaderData(otLeaderData &aLeaderData)
-{
-    const LeaderDataTlv &leaderData(GetLeaderDataTlv());
-    otError              error = OT_ERROR_NONE;
-
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED && mRole != OT_DEVICE_ROLE_DETACHED, error = OT_ERROR_DETACHED);
-
-    aLeaderData.mPartitionId       = leaderData.GetPartitionId();
-    aLeaderData.mWeighting         = leaderData.GetWeighting();
-    aLeaderData.mDataVersion       = leaderData.GetDataVersion();
-    aLeaderData.mStableDataVersion = leaderData.GetStableDataVersion();
-    aLeaderData.mLeaderRouterId    = leaderData.GetLeaderRouterId();
-
-exit:
-    return error;
-}
-
 Message *Mle::NewMleMessage(void)
 {
     Message *         message;
-    otMessageSettings settings = {false, static_cast<otMessagePriority>(kMleMessagePriority)};
+    Message::Settings settings(Message::kNoLinkSecurity, Message::kPriorityNet);
 
-    message = mSocket.NewMessage(0, &settings);
-    VerifyOrExit(message != NULL);
+    message = mSocket.NewMessage(0, settings);
+    VerifyOrExit(message != nullptr, OT_NOOP);
 
     message->SetSubType(Message::kSubTypeMleGeneral);
 
@@ -1127,132 +1044,123 @@
 
 otError Mle::AppendSourceAddress(Message &aMessage)
 {
-    SourceAddressTlv tlv;
-
-    tlv.Init();
-    tlv.SetRloc16(GetRloc16());
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint16Tlv(aMessage, Tlv::kSourceAddress, GetRloc16());
 }
 
 otError Mle::AppendStatus(Message &aMessage, StatusTlv::Status aStatus)
 {
-    StatusTlv tlv;
-
-    tlv.Init();
-    tlv.SetStatus(aStatus);
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint8Tlv(aMessage, Tlv::kStatus, static_cast<uint8_t>(aStatus));
 }
 
 otError Mle::AppendMode(Message &aMessage, DeviceMode aMode)
 {
-    ModeTlv tlv;
-
-    tlv.Init();
-    tlv.SetMode(aMode);
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint8Tlv(aMessage, Tlv::kMode, aMode.Get());
 }
 
 otError Mle::AppendTimeout(Message &aMessage, uint32_t aTimeout)
 {
-    TimeoutTlv tlv;
+    return Tlv::AppendUint32Tlv(aMessage, Tlv::kTimeout, aTimeout);
+}
 
-    tlv.Init();
-    tlv.SetTimeout(aTimeout);
-
-    return tlv.AppendTo(aMessage);
+otError Mle::AppendChallenge(Message &aMessage, const Challenge &aChallenge)
+{
+    return Tlv::AppendTlv(aMessage, Tlv::kChallenge, aChallenge.mBuffer, aChallenge.mLength);
 }
 
 otError Mle::AppendChallenge(Message &aMessage, const uint8_t *aChallenge, uint8_t aChallengeLength)
 {
-    otError error;
-    Tlv     tlv;
+    return Tlv::AppendTlv(aMessage, Tlv::kChallenge, aChallenge, aChallengeLength);
+}
 
-    tlv.SetType(Tlv::kChallenge);
-    tlv.SetLength(aChallengeLength);
+otError Mle::AppendResponse(Message &aMessage, const Challenge &aResponse)
+{
+    return Tlv::AppendTlv(aMessage, Tlv::kResponse, aResponse.mBuffer, aResponse.mLength);
+}
 
-    SuccessOrExit(error = aMessage.Append(&tlv, sizeof(tlv)));
-    SuccessOrExit(error = aMessage.Append(aChallenge, aChallengeLength));
+otError Mle::ReadChallengeOrResponse(const Message &aMessage, uint8_t aTlvType, Challenge &aBuffer)
+{
+    otError  error;
+    uint16_t offset;
+    uint16_t length;
+
+    SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, aTlvType, offset, length));
+    VerifyOrExit(length >= kMinChallengeSize, error = OT_ERROR_PARSE);
+
+    if (length > kMaxChallengeSize)
+    {
+        length = kMaxChallengeSize;
+    }
+
+    aMessage.Read(offset, length, aBuffer.mBuffer);
+    aBuffer.mLength = static_cast<uint8_t>(length);
+
 exit:
     return error;
 }
 
-otError Mle::AppendResponse(Message &aMessage, const uint8_t *aResponse, uint8_t aResponseLength)
+otError Mle::ReadChallenge(const Message &aMessage, Challenge &aChallenge)
 {
-    otError error;
-    Tlv     tlv;
+    return ReadChallengeOrResponse(aMessage, Tlv::kChallenge, aChallenge);
+}
 
-    tlv.SetType(Tlv::kResponse);
-    tlv.SetLength(aResponseLength);
-
-    SuccessOrExit(error = aMessage.Append(&tlv, sizeof(tlv)));
-    SuccessOrExit(error = aMessage.Append(aResponse, aResponseLength));
-
-exit:
-    return error;
+otError Mle::ReadResponse(const Message &aMessage, Challenge &aResponse)
+{
+    return ReadChallengeOrResponse(aMessage, Tlv::kResponse, aResponse);
 }
 
 otError Mle::AppendLinkFrameCounter(Message &aMessage)
 {
-    LinkFrameCounterTlv tlv;
-
-    tlv.Init();
-    tlv.SetFrameCounter(Get<KeyManager>().GetMacFrameCounter());
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint32Tlv(aMessage, Tlv::kLinkFrameCounter, Get<KeyManager>().GetMacFrameCounter());
 }
 
 otError Mle::AppendMleFrameCounter(Message &aMessage)
 {
-    MleFrameCounterTlv tlv;
-
-    tlv.Init();
-    tlv.SetFrameCounter(Get<KeyManager>().GetMleFrameCounter());
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint32Tlv(aMessage, Tlv::kMleFrameCounter, Get<KeyManager>().GetMleFrameCounter());
 }
 
 otError Mle::AppendAddress16(Message &aMessage, uint16_t aRloc16)
 {
-    Address16Tlv tlv;
-
-    tlv.Init();
-    tlv.SetRloc16(aRloc16);
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint16Tlv(aMessage, Tlv::kAddress16, aRloc16);
 }
 
 otError Mle::AppendLeaderData(Message &aMessage)
 {
-    mLeaderData.Init();
+    LeaderDataTlv leaderDataTlv;
+
     mLeaderData.SetDataVersion(Get<NetworkData::Leader>().GetVersion());
     mLeaderData.SetStableDataVersion(Get<NetworkData::Leader>().GetStableVersion());
 
-    return mLeaderData.AppendTo(aMessage);
+    leaderDataTlv.Init();
+    leaderDataTlv.Set(mLeaderData);
+
+    return leaderDataTlv.AppendTo(aMessage);
 }
 
-void Mle::FillNetworkDataTlv(NetworkDataTlv &aTlv, bool aStableOnly)
+otError Mle::ReadLeaderData(const Message &aMessage, LeaderData &aLeaderData)
 {
-    uint8_t length = sizeof(NetworkDataTlv) - sizeof(Tlv); // sizeof( NetworkDataTlv::mNetworkData )
+    otError       error;
+    LeaderDataTlv leaderDataTlv;
 
-    // Ignore result code, provided buffer must be enough
-    Get<NetworkData::Leader>().GetNetworkData(aStableOnly, aTlv.GetNetworkData(), length);
-    aTlv.SetLength(length);
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, Tlv::kLeaderData, sizeof(leaderDataTlv), leaderDataTlv));
+    VerifyOrExit(leaderDataTlv.IsValid(), error = OT_ERROR_PARSE);
+    leaderDataTlv.Get(aLeaderData);
+
+exit:
+    return error;
 }
 
 otError Mle::AppendNetworkData(Message &aMessage, bool aStableOnly)
 {
-    otError        error = OT_ERROR_NONE;
-    NetworkDataTlv tlv;
+    otError error = OT_ERROR_NONE;
+    uint8_t networkData[NetworkData::NetworkData::kMaxSize];
+    uint8_t length;
 
     VerifyOrExit(!mRetrieveNewNetworkData, error = OT_ERROR_INVALID_STATE);
 
-    tlv.Init();
-    FillNetworkDataTlv(tlv, aStableOnly);
+    length = sizeof(networkData);
+    IgnoreError(Get<NetworkData::Leader>().GetNetworkData(aStableOnly, networkData, length));
 
-    error = tlv.AppendTo(aMessage);
+    error = Tlv::AppendTlv(aMessage, Tlv::kNetworkData, networkData, length);
 
 exit:
     return error;
@@ -1260,14 +1168,24 @@
 
 otError Mle::AppendTlvRequest(Message &aMessage, const uint8_t *aTlvs, uint8_t aTlvsLength)
 {
-    otError error;
-    Tlv     tlv;
+    return Tlv::AppendTlv(aMessage, Tlv::kTlvRequest, aTlvs, aTlvsLength);
+}
 
-    tlv.SetType(Tlv::kTlvRequest);
-    tlv.SetLength(aTlvsLength);
+otError Mle::FindTlvRequest(const Message &aMessage, RequestedTlvs &aRequestedTlvs)
+{
+    otError  error;
+    uint16_t offset;
+    uint16_t length;
 
-    SuccessOrExit(error = aMessage.Append(&tlv, sizeof(tlv)));
-    SuccessOrExit(error = aMessage.Append(aTlvs, aTlvsLength));
+    SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Tlv::kTlvRequest, offset, length));
+
+    if (length > sizeof(aRequestedTlvs.mTlvs))
+    {
+        length = sizeof(aRequestedTlvs.mTlvs);
+    }
+
+    aMessage.Read(offset, length, aRequestedTlvs.mTlvs);
+    aRequestedTlvs.mNumTlvs = static_cast<uint8_t>(length);
 
 exit:
     return error;
@@ -1275,32 +1193,17 @@
 
 otError Mle::AppendScanMask(Message &aMessage, uint8_t aScanMask)
 {
-    ScanMaskTlv tlv;
-
-    tlv.Init();
-    tlv.SetMask(aScanMask);
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint8Tlv(aMessage, Tlv::kScanMask, aScanMask);
 }
 
 otError Mle::AppendLinkMargin(Message &aMessage, uint8_t aLinkMargin)
 {
-    LinkMarginTlv tlv;
-
-    tlv.Init();
-    tlv.SetLinkMargin(aLinkMargin);
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint8Tlv(aMessage, Tlv::kLinkMargin, aLinkMargin);
 }
 
 otError Mle::AppendVersion(Message &aMessage)
 {
-    VersionTlv tlv;
-
-    tlv.Init();
-    tlv.SetVersion(kThreadVersion);
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint16Tlv(aMessage, Tlv::kVersion, kThreadVersion);
 }
 
 bool Mle::HasUnregisteredAddress(void)
@@ -1321,13 +1224,17 @@
 
     if (!IsRxOnWhenIdle())
     {
-        uint8_t      iterator = 0;
-        Ip6::Address address;
-
         // For sleepy end-device, we register any external multicast
         // addresses.
 
-        retval = (Get<ThreadNetif>().GetNextExternalMulticast(iterator, address) == OT_ERROR_NONE);
+        for (const Ip6::NetifMulticastAddress *address = Get<ThreadNetif>().GetMulticastAddresses(); address != nullptr;
+             address                                   = address->GetNext())
+        {
+            if (Get<ThreadNetif>().IsMulticastAddressExternal(*address))
+            {
+                ExitNow(retval = true);
+            }
+        }
     }
 
 exit:
@@ -1343,6 +1250,9 @@
     uint8_t                  length      = 0;
     uint8_t                  counter     = 0;
     uint16_t                 startOffset = aMessage.GetLength();
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    Ip6::Address domainUnicastAddress;
+#endif
 
     tlv.SetType(Tlv::kAddressRegistration);
     SuccessOrExit(error = aMessage.Append(&tlv, sizeof(tlv)));
@@ -1354,9 +1264,28 @@
     length += entry.GetLength();
 
     // Continue to append the other addresses if not `kAppendMeshLocalOnly` mode
-    VerifyOrExit(aMode != kAppendMeshLocalOnly);
+    VerifyOrExit(aMode != kAppendMeshLocalOnly, OT_NOOP);
     counter++;
 
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    // Cache Domain Unicast Address.
+    domainUnicastAddress = Get<DuaManager>().GetDomainUnicastAddress();
+
+    if (Get<ThreadNetif>().HasUnicastAddress(domainUnicastAddress))
+    {
+        error = Get<NetworkData::Leader>().GetContext(domainUnicastAddress, context);
+
+        OT_ASSERT(error == OT_ERROR_NONE);
+
+        // Prioritize DUA, compressed entry
+        entry.SetContextId(context.mContextId);
+        entry.SetIid(domainUnicastAddress.GetIid());
+        SuccessOrExit(error = aMessage.Append(&entry, entry.GetLength()));
+        length += entry.GetLength();
+        counter++;
+    }
+#endif // OPENTHREAD_CONFIG_DUA_ENABLE
+
     for (const Ip6::NetifUnicastAddress *addr = Get<ThreadNetif>().GetUnicastAddresses(); addr; addr = addr->GetNext())
     {
         if (addr->GetAddress().IsLinkLocal() || IsRoutingLocator(addr->GetAddress()) ||
@@ -1365,6 +1294,14 @@
             continue;
         }
 
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+        // Skip DUA that was already appended above.
+        if (addr->GetAddress() == domainUnicastAddress)
+        {
+            continue;
+        }
+#endif
+
         if (Get<NetworkData::Leader>().GetContext(addr->GetAddress(), context) == OT_ERROR_NONE)
         {
             // compressed entry
@@ -1382,26 +1319,45 @@
         length += entry.GetLength();
         counter++;
         // only continue to append if there is available entry.
-        VerifyOrExit(counter < OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER);
+        VerifyOrExit(counter < OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER, OT_NOOP);
     }
 
-    // For sleepy end device, register external multicast addresses to the parent for indirect transmission
-    if (!IsRxOnWhenIdle())
+    // Append external multicast addresses.  For sleepy end device,
+    // register all external multicast addresses with the parent for
+    // indirect transmission. Since Thread 1.2, non-sleepy MED should
+    // also register external multicast addresses of scope larger than
+    // realm with a 1.2 or higher parent.
+    if (!IsRxOnWhenIdle()
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+        || !GetParent().IsThreadVersion1p1()
+#endif
+    )
     {
-        uint8_t      iterator = 0;
-        Ip6::Address address;
-
-        // append external multicast address
-        while (Get<ThreadNetif>().GetNextExternalMulticast(iterator, address) == OT_ERROR_NONE)
+        for (const Ip6::NetifMulticastAddress *addr = Get<ThreadNetif>().GetMulticastAddresses(); addr != nullptr;
+             addr                                   = addr->GetNext())
         {
+            if (!Get<ThreadNetif>().IsMulticastAddressExternal(*addr))
+            {
+                continue;
+            }
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+            // For Thread 1.2 MED, skip multicast address with scope not
+            // larger than realm local when registering.
+            if (IsRxOnWhenIdle() && !addr->GetAddress().IsMulticastLargerThanRealmLocal())
+            {
+                continue;
+            }
+#endif
+
             entry.SetUncompressed();
-            entry.SetIp6Address(address);
+            entry.SetIp6Address(addr->GetAddress());
             SuccessOrExit(error = aMessage.Append(&entry, entry.GetLength()));
             length += entry.GetLength();
 
             counter++;
             // only continue to append if there is available entry.
-            VerifyOrExit(counter < OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER);
+            VerifyOrExit(counter < OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER, OT_NOOP);
         }
     }
 
@@ -1439,12 +1395,7 @@
 
 otError Mle::AppendXtalAccuracy(Message &aMessage)
 {
-    XtalAccuracyTlv tlv;
-
-    tlv.Init();
-    tlv.SetXtalAccuracy(otPlatTimeGetXtalAccuracy());
-
-    return tlv.AppendTo(aMessage);
+    return Tlv::AppendUint16Tlv(aMessage, Tlv::kXtalAccuracy, otPlatTimeGetXtalAccuracy());
 }
 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 
@@ -1482,18 +1433,18 @@
     return error;
 }
 
-void Mle::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags)
+void Mle::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<Mle>().HandleStateChanged(aFlags);
+    static_cast<Mle &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
-void Mle::HandleStateChanged(otChangedFlags aFlags)
+void Mle::HandleNotifierEvents(Events aEvents)
 {
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED);
+    VerifyOrExit(!IsDisabled(), OT_NOOP);
 
-    if (aFlags & OT_CHANGED_THREAD_ROLE)
+    if (aEvents.Contains(kEventThreadRoleChanged))
     {
-        if (mRole == OT_DEVICE_ROLE_CHILD && !IsFullThreadDevice() && mAddressRegistrationMode == kAppendMeshLocalOnly)
+        if (IsChild() && !IsFullThreadDevice() && mAddressRegistrationMode == kAppendMeshLocalOnly)
         {
             // If only mesh-local address was registered in the "Child
             // ID Request" message, after device is attached, trigger a
@@ -1506,55 +1457,68 @@
         }
     }
 
-    if ((aFlags & (OT_CHANGED_IP6_ADDRESS_ADDED | OT_CHANGED_IP6_ADDRESS_REMOVED)) != 0)
+    if (aEvents.ContainsAny(kEventIp6AddressAdded | kEventIp6AddressRemoved))
     {
-        if (!Get<ThreadNetif>().IsUnicastAddress(mMeshLocal64.GetAddress()))
+        if (!Get<ThreadNetif>().HasUnicastAddress(mMeshLocal64.GetAddress()))
         {
             // Mesh Local EID was removed, choose a new one and add it back
-            Random::NonCrypto::FillBuffer(mMeshLocal64.GetAddress().mFields.m8 + OT_IP6_PREFIX_SIZE,
-                                          OT_IP6_ADDRESS_SIZE - OT_IP6_PREFIX_SIZE);
+            mMeshLocal64.GetAddress().GetIid().GenerateRandom();
 
             Get<ThreadNetif>().AddUnicastAddress(mMeshLocal64);
-            Get<Notifier>().Signal(OT_CHANGED_THREAD_ML_ADDR);
+            Get<Notifier>().Signal(kEventThreadMeshLocalAddrChanged);
         }
 
-        if (mRole == OT_DEVICE_ROLE_CHILD && !IsFullThreadDevice())
+        if (IsChild() && !IsFullThreadDevice())
         {
             mChildUpdateRequestState = kChildUpdateRequestPending;
             ScheduleMessageTransmissionTimer();
         }
     }
 
-    if ((aFlags & (OT_CHANGED_IP6_MULTICAST_SUBSCRIBED | OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED)) != 0)
+    if (aEvents.ContainsAny(kEventIp6MulticastSubscribed | kEventIp6MulticastUnsubscribed))
     {
-        if (mRole == OT_DEVICE_ROLE_CHILD && !IsFullThreadDevice() && !IsRxOnWhenIdle())
+        // When multicast subscription changes, SED always notifies its parent as it depends on its
+        // parent for indirect transmission. Since Thread 1.2, MED MAY also notify its parent of 1.2
+        // or higher version as it could depend on its parent to perform Multicast Listener Report.
+        if (IsChild() && !IsFullThreadDevice() &&
+            (!IsRxOnWhenIdle()
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+             || !GetParent().IsThreadVersion1p1()
+#endif
+                 ))
+
         {
             mChildUpdateRequestState = kChildUpdateRequestPending;
             ScheduleMessageTransmissionTimer();
         }
     }
 
-    if ((aFlags & OT_CHANGED_THREAD_NETDATA) != 0)
+    if (aEvents.Contains(kEventThreadNetdataChanged))
     {
+#if OPENTHREAD_FTD
         if (IsFullThreadDevice())
         {
             Get<MleRouter>().HandleNetworkDataUpdateRouter();
         }
-        else if ((aFlags & OT_CHANGED_THREAD_ROLE) == 0)
+        else
+#endif
         {
-            mChildUpdateRequestState = kChildUpdateRequestPending;
-            ScheduleMessageTransmissionTimer();
+            if (!aEvents.Contains(kEventThreadRoleChanged))
+            {
+                mChildUpdateRequestState = kChildUpdateRequestPending;
+                ScheduleMessageTransmissionTimer();
+            }
         }
 
-#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
-        Get<NetworkData::Local>().SendServerDataNotification();
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+        Get<BackboneRouter::Leader>().Update();
+#endif
 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
         this->UpdateServiceAlocs();
 #endif
-#endif
 
 #if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
-        Get<Dhcp6::Dhcp6Server>().UpdateService();
+        IgnoreError(Get<Dhcp6::Dhcp6Server>().UpdateService());
 #endif // OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
 
 #if OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
@@ -1562,21 +1526,20 @@
 #endif // OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
     }
 
-    if (aFlags & (OT_CHANGED_THREAD_ROLE | OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER))
+    if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadKeySeqCounterChanged))
     {
         // Store the settings on a key seq change, or when role changes and device
         // is attached (i.e., skip `Store()` on role change to detached).
 
-        if ((aFlags & OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER) || IsAttached())
+        if (aEvents.Contains(kEventThreadKeySeqCounterChanged) || IsAttached())
         {
-            Store();
+            IgnoreError(Store());
         }
     }
 
-    if (aFlags & OT_CHANGED_SECURITY_POLICY)
+    if (aEvents.Contains(kEventSecurityPolicyChanged))
     {
-        Get<Ip6::Filter>().AllowNativeCommissioner(
-            (Get<KeyManager>().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_NATIVE_COMMISSIONING) != 0);
+        Get<Ip6::Filter>().AllowNativeCommissioner(Get<KeyManager>().IsNativeCommissioningAllowed());
     }
 
 exit:
@@ -1589,22 +1552,22 @@
     uint16_t              rloc               = GetRloc16();
     uint16_t              serviceAloc        = 0;
     uint8_t               serviceId          = 0;
-    int                   i                  = 0;
     NetworkData::Iterator serviceIterator    = NetworkData::kIteratorInit;
-    int                   serviceAlocsLength = OT_ARRAY_LENGTH(mServiceAlocs);
+    size_t                serviceAlocsLength = OT_ARRAY_LENGTH(mServiceAlocs);
+    size_t                i                  = 0;
 
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED);
+    VerifyOrExit(!IsDisabled(), OT_NOOP);
 
     // First remove all alocs which are no longer necessary, to free up space in mServiceAlocs
     for (i = 0; i < serviceAlocsLength; i++)
     {
-        serviceAloc = HostSwap16(mServiceAlocs[i].GetAddress().mFields.m16[7]);
+        serviceAloc = mServiceAlocs[i].GetAddress().GetIid().GetLocator();
 
         if ((serviceAloc != Mac::kShortAddrInvalid) &&
             (!Get<NetworkData::Leader>().ContainsService(Mle::ServiceIdFromAloc(serviceAloc), rloc)))
         {
             Get<ThreadNetif>().RemoveUnicastAddress(mServiceAlocs[i]);
-            mServiceAlocs[i].GetAddress().mFields.m16[7] = HostSwap16(Mac::kShortAddrInvalid);
+            mServiceAlocs[i].GetAddress().GetIid().SetLocator(Mac::kShortAddrInvalid);
         }
     }
 
@@ -1613,7 +1576,7 @@
     {
         for (i = 0; i < serviceAlocsLength; i++)
         {
-            serviceAloc = HostSwap16(mServiceAlocs[i].GetAddress().mFields.m16[7]);
+            serviceAloc = mServiceAlocs[i].GetAddress().GetIid().GetLocator();
 
             if ((serviceAloc != Mac::kShortAddrInvalid) && (Mle::ServiceIdFromAloc(serviceAloc) == serviceId))
             {
@@ -1626,7 +1589,7 @@
             // Service Aloc is not there, but it should be. Lets add it into first empty space
             for (i = 0; i < serviceAlocsLength; i++)
             {
-                serviceAloc = HostSwap16(mServiceAlocs[i].GetAddress().mFields.m16[7]);
+                serviceAloc = mServiceAlocs[i].GetAddress().GetIid().GetLocator();
 
                 if (serviceAloc == Mac::kShortAddrInvalid)
                 {
@@ -1678,7 +1641,7 @@
 
         if ((linkQuality == 3 || mAttachState != kAttachStateParentRequestRouter) &&
             mParentCandidate.IsStateParentResponse() &&
-            (mRole != OT_DEVICE_ROLE_CHILD || mReceivedResponseFromParent || mParentRequestMode == kAttachBetter) &&
+            (!IsChild() || mReceivedResponseFromParent || mParentRequestMode == kAttachBetter) &&
             SendChildIdRequest() == OT_ERROR_NONE)
         {
             SetAttachState(kAttachStateChildIdRequest);
@@ -1690,8 +1653,8 @@
     switch (mAttachState)
     {
     case kAttachStateIdle:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
 
     case kAttachStateProcessAnnounce:
         ProcessAnnounce();
@@ -1718,14 +1681,14 @@
         // during reattach when losing connectivity.
         if (mParentRequestMode == kAttachSame1 || mParentRequestMode == kAttachSame2)
         {
-            SendParentRequest(kParentRequestTypeRoutersAndReeds);
+            IgnoreError(SendParentRequest(kParentRequestTypeRoutersAndReeds));
             delay = kParentRequestReedTimeout;
         }
         // initial MLE Parent Request has only R flag set in Scan Mask TLV for
         // during initial attach or downgrade process
         else
         {
-            SendParentRequest(kParentRequestTypeRouters);
+            IgnoreError(SendParentRequest(kParentRequestTypeRouters));
             delay = kParentRequestRouterTimeout;
         }
 
@@ -1733,7 +1696,7 @@
 
     case kAttachStateParentRequestRouter:
         SetAttachState(kAttachStateParentRequestReed);
-        SendParentRequest(kParentRequestTypeRoutersAndReeds);
+        IgnoreError(SendParentRequest(kParentRequestTypeRoutersAndReeds));
         delay = kParentRequestReedTimeout;
         break;
 
@@ -1743,7 +1706,7 @@
         if (shouldAnnounce)
         {
             SetAttachState(kAttachStateAnnounce);
-            SendParentRequest(kParentRequestTypeRoutersAndReeds);
+            IgnoreError(SendParentRequest(kParentRequestTypeRoutersAndReeds));
             mAnnounceChannel = Mac::ChannelMask::kChannelIteratorFirst;
             delay            = mAnnounceDelay;
             break;
@@ -1783,8 +1746,9 @@
     bool             shouldAnnounce = false;
     Mac::ChannelMask channelMask;
 
-    VerifyOrExit((mRole != OT_DEVICE_ROLE_CHILD) && (mReattachState == kReattachStop) &&
-                 (Get<MeshCoP::ActiveDataset>().IsPartiallyComplete() || !IsFullThreadDevice()));
+    VerifyOrExit(!IsChild() && (mReattachState == kReattachStop) &&
+                     (Get<MeshCoP::ActiveDataset>().IsPartiallyComplete() || !IsFullThreadDevice()),
+                 OT_NOOP);
 
     if (Get<MeshCoP::ActiveDataset>().GetChannelMask(channelMask) != OT_ERROR_NONE)
     {
@@ -1812,7 +1776,7 @@
     {
         if (Get<MeshCoP::PendingDataset>().Restore() == OT_ERROR_NONE)
         {
-            Get<MeshCoP::PendingDataset>().ApplyConfiguration();
+            IgnoreError(Get<MeshCoP::PendingDataset>().ApplyConfiguration());
             mReattachState = kReattachPending;
             SetAttachState(kAttachStateStart);
             delay = 1 + Random::NonCrypto::GetUint32InRange(0, kAttachStartJitter);
@@ -1825,30 +1789,32 @@
     else if (mReattachState == kReattachPending)
     {
         mReattachState = kReattachStop;
-        Get<MeshCoP::ActiveDataset>().Restore();
+        IgnoreError(Get<MeshCoP::ActiveDataset>().Restore());
     }
 
-    VerifyOrExit(mReattachState == kReattachStop);
+    VerifyOrExit(mReattachState == kReattachStop, OT_NOOP);
 
     switch (mParentRequestMode)
     {
     case kAttachAny:
-        if (mRole != OT_DEVICE_ROLE_CHILD)
+        if (!IsChild())
         {
             if (mAlternatePanId != Mac::kPanIdBroadcast)
             {
-                Get<Mac::Mac>().SetPanChannel(mAlternateChannel);
+                IgnoreError(Get<Mac::Mac>().SetPanChannel(mAlternateChannel));
                 Get<Mac::Mac>().SetPanId(mAlternatePanId);
                 mAlternatePanId = Mac::kPanIdBroadcast;
-                BecomeDetached();
+                IgnoreError(BecomeDetached());
             }
-            else if (!IsFullThreadDevice())
+#if OPENTHREAD_FTD
+            else if (IsFullThreadDevice() && Get<MleRouter>().BecomeLeader() == OT_ERROR_NONE)
             {
-                BecomeDetached();
+                // do nothing
             }
-            else if (Get<MleRouter>().BecomeLeader() != OT_ERROR_NONE)
+#endif
+            else
             {
-                BecomeDetached();
+                IgnoreError(BecomeDetached());
             }
         }
         else if (!IsRxOnWhenIdle())
@@ -1861,12 +1827,12 @@
         break;
 
     case kAttachSame1:
-        BecomeChild(kAttachSame2);
+        IgnoreError(BecomeChild(kAttachSame2));
         break;
 
     case kAttachSame2:
     case kAttachSameDowngrade:
-        BecomeChild(kAttachAny);
+        IgnoreError(BecomeChild(kAttachAny));
         break;
 
     case kAttachBetter:
@@ -1884,36 +1850,33 @@
 
 void Mle::HandleDelayedResponseTimer(void)
 {
-    DelayedResponseHeader delayedResponse;
-    TimeMilli             now          = TimerMilli::GetNow();
-    TimeMilli             nextSendTime = now.GetDistantFuture();
-    Message *             message;
-    Message *             nextMessage;
+    DelayedResponseMetadata metadata;
+    TimeMilli               now          = TimerMilli::GetNow();
+    TimeMilli               nextSendTime = now.GetDistantFuture();
+    Message *               message;
+    Message *               nextMessage;
 
-    for (message = mDelayedResponses.GetHead(); message != NULL; message = nextMessage)
+    for (message = mDelayedResponses.GetHead(); message != nullptr; message = nextMessage)
     {
         nextMessage = message->GetNext();
 
-        delayedResponse.ReadFrom(*message);
+        metadata.ReadFrom(*message);
 
-        if (now < delayedResponse.GetSendTime())
+        if (now < metadata.mSendTime)
         {
-            if (nextSendTime > delayedResponse.GetSendTime())
+            if (nextSendTime > metadata.mSendTime)
             {
-                nextSendTime = delayedResponse.GetSendTime();
+                nextSendTime = metadata.mSendTime;
             }
         }
         else
         {
             mDelayedResponses.Dequeue(*message);
+            metadata.RemoveFrom(*message);
 
-            // Remove the DelayedResponseHeader from the message.
-            DelayedResponseHeader::RemoveFrom(*message);
-
-            // Send the message.
-            if (SendMessage(*message, delayedResponse.GetDestination()) == OT_ERROR_NONE)
+            if (SendMessage(*message, metadata.mDestination) == OT_ERROR_NONE)
             {
-                LogMleMessage("Send delayed message", delayedResponse.GetDestination());
+                LogMleMessage("Send delayed message", metadata.mDestination);
 
                 // Here enters fast poll mode, as for Rx-Off-when-idle device, the enqueued msg should
                 // be Mle Data Request.
@@ -1940,18 +1903,18 @@
 
 void Mle::RemoveDelayedDataResponseMessage(void)
 {
-    Message *             message = mDelayedResponses.GetHead();
-    DelayedResponseHeader delayedResponse;
+    Message *               message = mDelayedResponses.GetHead();
+    DelayedResponseMetadata metadata;
 
-    while (message != NULL)
+    while (message != nullptr)
     {
-        delayedResponse.ReadFrom(*message);
+        metadata.ReadFrom(*message);
 
         if (message->GetSubType() == Message::kSubTypeMleDataResponse)
         {
             mDelayedResponses.Dequeue(*message);
             message->Free();
-            LogMleMessage("Remove Delayed Data Response", delayedResponse.GetDestination());
+            LogMleMessage("Remove Delayed Data Response", metadata.mDestination);
 
             // no more than one multicast MLE Data Response in Delayed Message Queue.
             break;
@@ -1968,7 +1931,7 @@
     uint8_t      scanMask = 0;
     Ip6::Address destination;
 
-    Random::Crypto::FillBuffer(mParentRequest.mChallenge, sizeof(mParentRequest.mChallenge));
+    mParentRequestChallenge.GenerateRandom();
 
     switch (aType)
     {
@@ -1981,19 +1944,17 @@
         break;
     }
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandParentRequest));
     SuccessOrExit(error = AppendMode(*message, mDeviceMode));
-    SuccessOrExit(error = AppendChallenge(*message, mParentRequest.mChallenge, sizeof(mParentRequest.mChallenge)));
+    SuccessOrExit(error = AppendChallenge(*message, mParentRequestChallenge));
     SuccessOrExit(error = AppendScanMask(*message, scanMask));
     SuccessOrExit(error = AppendVersion(*message));
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     SuccessOrExit(error = AppendTimeRequest(*message));
 #endif
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xff02);
-    destination.mFields.m16[7] = HostSwap16(0x0002);
+    destination.SetToLinkLocalAllRoutersMulticast();
     SuccessOrExit(error = SendMessage(*message, destination));
 
     switch (aType)
@@ -2009,7 +1970,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -2022,7 +1983,7 @@
     if (mAttachState == kAttachStateChildIdRequest)
     {
         mAddressRegistrationMode = kAppendMeshLocalOnly;
-        SendChildIdRequest();
+        IgnoreError(SendChildIdRequest());
     }
 }
 
@@ -2031,12 +1992,12 @@
     otError      error   = OT_ERROR_NONE;
     uint8_t      tlvs[]  = {Tlv::kAddress16, Tlv::kNetworkData, Tlv::kRoute};
     uint8_t      tlvsLen = sizeof(tlvs);
-    Message *    message = NULL;
+    Message *    message = nullptr;
     Ip6::Address destination;
 
     if (mParent.GetExtAddress() == mParentCandidate.GetExtAddress())
     {
-        if (mRole == OT_DEVICE_ROLE_CHILD)
+        if (IsChild())
         {
             otLogInfoMle("Already attached to candidate parent");
             ExitNow(error = OT_ERROR_ALREADY);
@@ -2052,10 +2013,10 @@
         }
     }
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     message->SetSubType(Message::kSubTypeMleChildIdRequest);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildIdRequest));
-    SuccessOrExit(error = AppendResponse(*message, mChildIdRequest.mChallenge, mChildIdRequest.mChallengeLength));
+    SuccessOrExit(error = AppendResponse(*message, mParentCandidateChallenge));
     SuccessOrExit(error = AppendLinkFrameCounter(*message));
     SuccessOrExit(error = AppendMleFrameCounter(*message));
     SuccessOrExit(error = AppendMode(*message, mDeviceMode));
@@ -2076,9 +2037,7 @@
 
     mParentCandidate.SetState(Neighbor::kStateValid);
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xfe80);
-    destination.SetIid(mParentCandidate.GetExtAddress());
+    destination.SetToLinkLocalAddress(mParentCandidate.GetExtAddress());
     SuccessOrExit(error = SendMessage(*message, destination));
 
     if (mAddressRegistrationMode == kAppendMeshLocalOnly)
@@ -2098,7 +2057,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -2114,7 +2073,7 @@
     otError  error = OT_ERROR_NONE;
     Message *message;
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandDataRequest));
     SuccessOrExit(error = AppendTlvRequest(*message, aTlvs, aTlvsLength));
     SuccessOrExit(error = AppendActiveTimestamp(*message));
@@ -2138,12 +2097,12 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
 
-    if ((mRole == OT_DEVICE_ROLE_CHILD) && !IsRxOnWhenIdle())
+    if (IsChild() && !IsRxOnWhenIdle())
     {
         mDataRequestState = kDataRequestActive;
 
@@ -2181,7 +2140,7 @@
         ExitNow(interval = kUnicastRetransmissionDelay);
     }
 
-    if ((mRole == OT_DEVICE_ROLE_CHILD) && IsRxOnWhenIdle())
+    if (IsChild() && IsRxOnWhenIdle())
     {
         interval =
             Time::SecToMsec(mTimeout) - static_cast<uint32_t>(kUnicastRetransmissionDelay) * kMaxChildKeepAliveAttempts;
@@ -2207,7 +2166,7 @@
 {
     // The `mMessageTransmissionTimer` is used for:
     //
-    //  - Delaying OT_CHANGED notification triggered "Child Update Request" transmission (to allow aggregation),
+    //  - Delaying kEvent notification triggered "Child Update Request" transmission (to allow aggregation),
     //  - Retransmission of "Child Update Request",
     //  - Retransmission of "Data Request" on a child,
     //  - Sending periodic keep-alive "Child Update Request" messages on a non-sleepy (rx-on) child.
@@ -2220,11 +2179,9 @@
             static const uint8_t tlvs[] = {Tlv::kNetworkData};
             Ip6::Address         destination;
 
-            VerifyOrExit(mDataRequestAttempts < kMaxChildKeepAliveAttempts, BecomeDetached());
+            VerifyOrExit(mDataRequestAttempts < kMaxChildKeepAliveAttempts, IgnoreError(BecomeDetached()));
 
-            destination.Clear();
-            destination.mFields.m16[0] = HostSwap16(0xfe80);
-            destination.SetIid(mParent.GetExtAddress());
+            destination.SetToLinkLocalAddress(mParent.GetExtAddress());
 
             if (SendDataRequest(destination, tlvs, sizeof(tlvs), 0) == OT_ERROR_NONE)
             {
@@ -2235,7 +2192,7 @@
         }
 
         // Keep-alive "Child Update Request" only on a non-sleepy child
-        VerifyOrExit((mRole == OT_DEVICE_ROLE_CHILD) && IsRxOnWhenIdle());
+        VerifyOrExit(IsChild() && IsRxOnWhenIdle(), OT_NOOP);
         break;
 
     case kChildUpdateRequestPending:
@@ -2255,7 +2212,7 @@
         break;
     }
 
-    VerifyOrExit(mChildUpdateAttempts < kMaxChildKeepAliveAttempts, BecomeDetached());
+    VerifyOrExit(mChildUpdateAttempts < kMaxChildKeepAliveAttempts, IgnoreError(BecomeDetached()));
 
     if (SendChildUpdateRequest() == OT_ERROR_NONE)
     {
@@ -2270,19 +2227,19 @@
 {
     otError      error = OT_ERROR_NONE;
     Ip6::Address destination;
-    Message *    message = NULL;
+    Message *    message = nullptr;
 
     if (!mParent.IsStateValidOrRestoring())
     {
         otLogWarnMle("No valid parent when sending Child Update Request");
-        BecomeDetached();
+        IgnoreError(BecomeDetached());
         ExitNow();
     }
 
     mChildUpdateRequestState = kChildUpdateRequestActive;
     ScheduleMessageTransmissionTimer();
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     message->SetSubType(Message::kSubTypeMleChildUpdateRequest);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateRequest));
     SuccessOrExit(error = AppendMode(*message, mDeviceMode));
@@ -2294,27 +2251,25 @@
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DETACHED:
-        Random::Crypto::FillBuffer(mParentRequest.mChallenge, sizeof(mParentRequest.mChallenge));
-        SuccessOrExit(error = AppendChallenge(*message, mParentRequest.mChallenge, sizeof(mParentRequest.mChallenge)));
+    case kRoleDetached:
+        mParentRequestChallenge.GenerateRandom();
+        SuccessOrExit(error = AppendChallenge(*message, mParentRequestChallenge));
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         SuccessOrExit(error = AppendSourceAddress(*message));
         SuccessOrExit(error = AppendLeaderData(*message));
         SuccessOrExit(error = AppendTimeout(*message, mTimeout));
         break;
 
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
-        assert(false);
-        break;
+    case kRoleDisabled:
+    case kRoleRouter:
+    case kRoleLeader:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xfe80);
-    destination.SetIid(mParent.GetExtAddress());
+    destination.SetToLinkLocalAddress(mParent.GetExtAddress());
     SuccessOrExit(error = SendMessage(*message, destination));
 
     LogMleMessage("Send Child Update Request to parent", destination);
@@ -2331,7 +2286,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -2339,14 +2294,14 @@
     return error;
 }
 
-otError Mle::SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const ChallengeTlv &aChallenge)
+otError Mle::SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const Challenge &aChallenge)
 {
     otError      error = OT_ERROR_NONE;
     Ip6::Address destination;
     Message *    message;
     bool         checkAddress = false;
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateResponse));
     SuccessOrExit(error = AppendSourceAddress(*message));
     SuccessOrExit(error = AppendLeaderData(*message));
@@ -2378,7 +2333,7 @@
             break;
 
         case Tlv::kResponse:
-            SuccessOrExit(error = AppendResponse(*message, aChallenge.GetChallenge(), aChallenge.GetChallengeLength()));
+            SuccessOrExit(error = AppendResponse(*message, aChallenge));
             break;
 
         case Tlv::kLinkFrameCounter:
@@ -2391,21 +2346,19 @@
         }
     }
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xfe80);
-    destination.SetIid(mParent.GetExtAddress());
+    destination.SetToLinkLocalAddress(mParent.GetExtAddress());
     SuccessOrExit(error = SendMessage(*message, destination));
 
     LogMleMessage("Send Child Update Response to parent", destination);
 
     if (checkAddress && HasUnregisteredAddress())
     {
-        SendChildUpdateRequest();
+        IgnoreError(SendChildUpdateRequest());
     }
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -2413,27 +2366,24 @@
     return error;
 }
 
-otError Mle::SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce)
+void Mle::SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce)
 {
     Ip6::Address destination;
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xff02);
-    destination.mFields.m16[7] = HostSwap16(0x0001);
+    destination.SetToLinkLocalAllNodesMulticast();
 
-    return SendAnnounce(aChannel, aOrphanAnnounce, destination);
+    SendAnnounce(aChannel, aOrphanAnnounce, destination);
 }
 
-otError Mle::SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination)
+void Mle::SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination)
 {
     otError            error = OT_ERROR_NONE;
     ChannelTlv         channel;
-    PanIdTlv           panid;
     ActiveTimestampTlv activeTimestamp;
-    Message *          message = NULL;
+    Message *          message = nullptr;
 
     VerifyOrExit(Get<Mac::Mac>().GetSupportedChannelMask().ContainsChannel(aChannel), error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     message->SetLinkSecurityEnabled(true);
     message->SetSubType(Message::kSubTypeMleAnnounce);
     message->SetChannel(aChannel);
@@ -2457,21 +2407,18 @@
         SuccessOrExit(error = AppendActiveTimestamp(*message));
     }
 
-    panid.Init();
-    panid.SetPanId(Get<Mac::Mac>().GetPanId());
-    SuccessOrExit(error = panid.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, Tlv::kPanId, Get<Mac::Mac>().GetPanId()));
+
     SuccessOrExit(error = SendMessage(*message, aDestination));
 
     otLogInfoMle("Send Announce on channel %d", aChannel);
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
-
-    return error;
 }
 
 otError Mle::SendOrphanAnnounce(void)
@@ -2497,9 +2444,8 @@
     otError          error = OT_ERROR_NONE;
     Header           header;
     uint32_t         keySequence;
-    uint8_t          nonce[KeyManager::kNonceSize];
-    uint8_t          tag[4];
-    uint8_t          tagLength;
+    uint8_t          nonce[Crypto::AesCcm::kNonceSize];
+    uint8_t          tag[kMleSecurityTagSize];
     Crypto::AesCcm   aesCcm;
     uint8_t          buf[64];
     uint16_t         length;
@@ -2516,13 +2462,12 @@
 
         aMessage.Write(0, header.GetLength(), &header);
 
-        KeyManager::GenerateNonce(Get<Mac::Mac>().GetExtAddress(), Get<KeyManager>().GetMleFrameCounter(),
-                                  Mac::Frame::kSecEncMic32, nonce);
+        Crypto::AesCcm::GenerateNonce(Get<Mac::Mac>().GetExtAddress(), Get<KeyManager>().GetMleFrameCounter(),
+                                      Mac::Frame::kSecEncMic32, nonce);
 
-        aesCcm.SetKey(Get<KeyManager>().GetCurrentMleKey(), 16);
-        error = aesCcm.Init(16 + 16 + header.GetHeaderLength(), aMessage.GetLength() - (header.GetLength() - 1),
-                            sizeof(tag), nonce, sizeof(nonce));
-        assert(error == OT_ERROR_NONE);
+        aesCcm.SetKey(Get<KeyManager>().GetCurrentMleKey());
+        aesCcm.Init(16 + 16 + header.GetHeaderLength(), aMessage.GetLength() - (header.GetLength() - 1), sizeof(tag),
+                    nonce, sizeof(nonce));
 
         aesCcm.Header(&mLinkLocal64.GetAddress(), sizeof(mLinkLocal64.GetAddress()));
         aesCcm.Header(&aDestination, sizeof(aDestination));
@@ -2533,14 +2478,13 @@
         while (aMessage.GetOffset() < aMessage.GetLength())
         {
             length = aMessage.Read(aMessage.GetOffset(), sizeof(buf), buf);
-            aesCcm.Payload(buf, buf, length, true);
+            aesCcm.Payload(buf, buf, length, Crypto::AesCcm::kEncrypt);
             aMessage.Write(aMessage.GetOffset(), length, buf);
             aMessage.MoveOffset(length);
         }
 
-        tagLength = sizeof(tag);
-        aesCcm.Finalize(tag, &tagLength);
-        SuccessOrExit(error = aMessage.Append(tag, tagLength));
+        aesCcm.Finalize(tag);
+        SuccessOrExit(error = aMessage.Append(tag, sizeof(tag)));
 
         Get<KeyManager>().IncrementMleFrameCounter();
     }
@@ -2558,13 +2502,16 @@
 
 otError Mle::AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay)
 {
-    otError               error = OT_ERROR_NONE;
-    DelayedResponseHeader delayedResponse(TimerMilli::GetNow() + aDelay, aDestination);
+    otError                 error = OT_ERROR_NONE;
+    DelayedResponseMetadata metadata;
 
-    SuccessOrExit(error = delayedResponse.AppendTo(aMessage));
+    metadata.mSendTime    = TimerMilli::GetNow() + aDelay;
+    metadata.mDestination = aDestination;
+
+    SuccessOrExit(error = metadata.AppendTo(aMessage));
     mDelayedResponses.Enqueue(aMessage);
 
-    mDelayedResponseTimer.FireAtIfEarlier(delayedResponse.GetSendTime());
+    mDelayedResponseTimer.FireAtIfEarlier(metadata.mSendTime);
 
 exit:
     return error;
@@ -2581,23 +2528,22 @@
     otError         error = OT_ERROR_NONE;
     Header          header;
     uint32_t        keySequence;
-    const uint8_t * mleKey;
+    const Key *     mleKey;
     uint32_t        frameCounter;
-    uint8_t         messageTag[4];
-    uint8_t         nonce[KeyManager::kNonceSize];
-    Mac::ExtAddress macAddr;
+    uint8_t         messageTag[kMleSecurityTagSize];
+    uint8_t         nonce[Crypto::AesCcm::kNonceSize];
+    Mac::ExtAddress extAddr;
     Crypto::AesCcm  aesCcm;
     uint16_t        mleOffset;
     uint8_t         buf[64];
     uint16_t        length;
-    uint8_t         tag[4];
-    uint8_t         tagLength;
+    uint8_t         tag[kMleSecurityTagSize];
     uint8_t         command;
     Neighbor *      neighbor;
 
     otLogDebgMle("Receive UDP message");
 
-    VerifyOrExit(aMessageInfo.GetLinkInfo() != NULL);
+    VerifyOrExit(aMessageInfo.GetLinkInfo() != nullptr, OT_NOOP);
     VerifyOrExit(aMessageInfo.GetHopLimit() == kMleHopLimit, error = OT_ERROR_PARSE);
 
     length = aMessage.Read(aMessage.GetOffset(), sizeof(header), &header);
@@ -2609,12 +2555,14 @@
 
         switch (header.GetCommand())
         {
+#if OPENTHREAD_FTD
         case Header::kCommandDiscoveryRequest:
             Get<MleRouter>().HandleDiscoveryRequest(aMessage, aMessageInfo);
             break;
+#endif
 
         case Header::kCommandDiscoveryResponse:
-            HandleDiscoveryResponse(aMessage, aMessageInfo);
+            Get<DiscoverScanner>().HandleDiscoveryResponse(aMessage, aMessageInfo);
             break;
 
         default:
@@ -2624,18 +2572,18 @@
         ExitNow();
     }
 
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(!IsDisabled(), error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(header.GetSecuritySuite() == Header::k154Security, error = OT_ERROR_PARSE);
 
     keySequence = header.GetKeyId();
 
     if (keySequence == Get<KeyManager>().GetCurrentKeySequence())
     {
-        mleKey = Get<KeyManager>().GetCurrentMleKey();
+        mleKey = &Get<KeyManager>().GetCurrentMleKey();
     }
     else
     {
-        mleKey = Get<KeyManager>().GetTemporaryMleKey(keySequence);
+        mleKey = &Get<KeyManager>().GetTemporaryMleKey(keySequence);
     }
 
     VerifyOrExit(aMessage.GetOffset() + header.GetLength() + sizeof(messageTag) <= aMessage.GetLength(),
@@ -2645,15 +2593,14 @@
     aMessage.Read(aMessage.GetLength() - sizeof(messageTag), sizeof(messageTag), messageTag);
     SuccessOrExit(error = aMessage.SetLength(aMessage.GetLength() - sizeof(messageTag)));
 
-    aMessageInfo.GetPeerAddr().ToExtAddress(macAddr);
-    frameCounter = header.GetFrameCounter();
-    KeyManager::GenerateNonce(macAddr, frameCounter, Mac::Frame::kSecEncMic32, nonce);
+    aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr);
 
-    aesCcm.SetKey(mleKey, 16);
-    SuccessOrExit(error = aesCcm.Init(sizeof(aMessageInfo.GetPeerAddr()) + sizeof(aMessageInfo.GetSockAddr()) +
-                                          header.GetHeaderLength(),
-                                      aMessage.GetLength() - aMessage.GetOffset(), sizeof(messageTag), nonce,
-                                      sizeof(nonce)));
+    frameCounter = header.GetFrameCounter();
+    Crypto::AesCcm::GenerateNonce(extAddr, frameCounter, Mac::Frame::kSecEncMic32, nonce);
+
+    aesCcm.SetKey(*mleKey);
+    aesCcm.Init(sizeof(aMessageInfo.GetPeerAddr()) + sizeof(aMessageInfo.GetSockAddr()) + header.GetHeaderLength(),
+                aMessage.GetLength() - aMessage.GetOffset(), sizeof(messageTag), nonce, sizeof(nonce));
 
     aesCcm.Header(&aMessageInfo.GetPeerAddr(), sizeof(aMessageInfo.GetPeerAddr()));
     aesCcm.Header(&aMessageInfo.GetSockAddr(), sizeof(aMessageInfo.GetSockAddr()));
@@ -2664,15 +2611,14 @@
     while (aMessage.GetOffset() < aMessage.GetLength())
     {
         length = aMessage.Read(aMessage.GetOffset(), sizeof(buf), buf);
-        aesCcm.Payload(buf, buf, length, false);
+        aesCcm.Payload(buf, buf, length, Crypto::AesCcm::kDecrypt);
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
         aMessage.Write(aMessage.GetOffset(), length, buf);
 #endif
         aMessage.MoveOffset(length);
     }
 
-    tagLength = sizeof(tag);
-    aesCcm.Finalize(tag, &tagLength);
+    aesCcm.Finalize(tag);
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     VerifyOrExit(memcmp(messageTag, tag, sizeof(tag)) == 0, error = OT_ERROR_SECURITY);
 #endif
@@ -2689,30 +2635,30 @@
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DETACHED:
-    case OT_DEVICE_ROLE_CHILD:
-        neighbor = GetNeighbor(macAddr);
+    case kRoleDetached:
+    case kRoleChild:
+        neighbor = GetNeighbor(extAddr);
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleRouter:
+    case kRoleLeader:
         if (command == Header::kCommandChildIdResponse)
         {
-            neighbor = GetNeighbor(macAddr);
+            neighbor = GetNeighbor(extAddr);
         }
         else
         {
-            neighbor = Get<MleRouter>().GetNeighbor(macAddr);
+            neighbor = Get<MleRouter>().GetNeighbor(extAddr);
         }
 
         break;
 
     default:
-        neighbor = NULL;
+        neighbor = nullptr;
         break;
     }
 
-    if (neighbor != NULL && neighbor->IsStateValid())
+    if (neighbor != nullptr && neighbor->IsStateValid())
     {
         if (keySequence == neighbor->GetKeySequence())
         {
@@ -2730,6 +2676,55 @@
 
     switch (command)
     {
+    case Header::kCommandAdvertisement:
+        HandleAdvertisement(aMessage, aMessageInfo, neighbor);
+        break;
+
+    case Header::kCommandDataResponse:
+        HandleDataResponse(aMessage, aMessageInfo, neighbor);
+        break;
+
+    case Header::kCommandParentResponse:
+        HandleParentResponse(aMessage, aMessageInfo, keySequence);
+        break;
+
+    case Header::kCommandChildIdResponse:
+        HandleChildIdResponse(aMessage, aMessageInfo, neighbor);
+        break;
+
+    case Header::kCommandAnnounce:
+        HandleAnnounce(aMessage, aMessageInfo);
+        break;
+
+    case Header::kCommandChildUpdateRequest:
+#if OPENTHREAD_FTD
+        if (IsRouterOrLeader())
+        {
+            Get<MleRouter>().HandleChildUpdateRequest(aMessage, aMessageInfo, keySequence);
+        }
+        else
+#endif
+        {
+            HandleChildUpdateRequest(aMessage, aMessageInfo, neighbor);
+        }
+
+        break;
+
+    case Header::kCommandChildUpdateResponse:
+#if OPENTHREAD_FTD
+        if (IsRouterOrLeader())
+        {
+            Get<MleRouter>().HandleChildUpdateResponse(aMessage, aMessageInfo, keySequence, neighbor);
+        }
+        else
+#endif
+        {
+            HandleChildUpdateResponse(aMessage, aMessageInfo, neighbor);
+        }
+
+        break;
+
+#if OPENTHREAD_FTD
     case Header::kCommandLinkRequest:
         Get<MleRouter>().HandleLinkRequest(aMessage, aMessageInfo, neighbor);
         break;
@@ -2742,67 +2737,27 @@
         Get<MleRouter>().HandleLinkAcceptAndRequest(aMessage, aMessageInfo, keySequence, neighbor);
         break;
 
-    case Header::kCommandAdvertisement:
-        HandleAdvertisement(aMessage, aMessageInfo, neighbor);
-        break;
-
     case Header::kCommandDataRequest:
         Get<MleRouter>().HandleDataRequest(aMessage, aMessageInfo, neighbor);
         break;
 
-    case Header::kCommandDataResponse:
-        HandleDataResponse(aMessage, aMessageInfo, neighbor);
-        break;
-
     case Header::kCommandParentRequest:
         Get<MleRouter>().HandleParentRequest(aMessage, aMessageInfo);
         break;
 
-    case Header::kCommandParentResponse:
-        HandleParentResponse(aMessage, aMessageInfo, keySequence);
-        break;
-
     case Header::kCommandChildIdRequest:
         Get<MleRouter>().HandleChildIdRequest(aMessage, aMessageInfo, keySequence);
         break;
 
-    case Header::kCommandChildIdResponse:
-        HandleChildIdResponse(aMessage, aMessageInfo, neighbor);
-        break;
-
-    case Header::kCommandChildUpdateRequest:
-        if (mRole == OT_DEVICE_ROLE_LEADER || mRole == OT_DEVICE_ROLE_ROUTER)
-        {
-            Get<MleRouter>().HandleChildUpdateRequest(aMessage, aMessageInfo, keySequence);
-        }
-        else
-        {
-            HandleChildUpdateRequest(aMessage, aMessageInfo, neighbor);
-        }
-
-        break;
-
-    case Header::kCommandChildUpdateResponse:
-        if (mRole == OT_DEVICE_ROLE_LEADER || mRole == OT_DEVICE_ROLE_ROUTER)
-        {
-            Get<MleRouter>().HandleChildUpdateResponse(aMessage, aMessageInfo, keySequence, neighbor);
-        }
-        else
-        {
-            HandleChildUpdateResponse(aMessage, aMessageInfo, neighbor);
-        }
-
-        break;
-
-    case Header::kCommandAnnounce:
-        HandleAnnounce(aMessage, aMessageInfo);
-        break;
-
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     case Header::kCommandTimeSync:
         Get<MleRouter>().HandleTimeSync(aMessage, aMessageInfo, neighbor);
         break;
 #endif
+#endif // OPENTHREAD_FTD
+
+    default:
+        ExitNow(error = OT_ERROR_DROP);
     }
 
 exit:
@@ -2815,59 +2770,66 @@
     return;
 }
 
-otError Mle::HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor)
+void Mle::HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor)
 {
-    otError          error = OT_ERROR_NONE;
-    SourceAddressTlv sourceAddress;
-    LeaderDataTlv    leaderData;
-    RouteTlv         route;
-    uint8_t          tlvs[] = {Tlv::kNetworkData};
-    uint16_t         delay;
+    otError    error = OT_ERROR_NONE;
+    uint16_t   sourceAddress;
+    LeaderData leaderData;
+    uint8_t    tlvs[] = {Tlv::kNetworkData};
+    uint16_t   delay;
 
     // Source Address
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
-    VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress));
 
-    LogMleMessage("Receive Advertisement", aMessageInfo.GetPeerAddr(), sourceAddress.GetRloc16());
+    LogMleMessage("Receive Advertisement", aMessageInfo.GetPeerAddr(), sourceAddress);
 
     // Leader Data
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
-    VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadLeaderData(aMessage, leaderData));
 
-    if (mRole != OT_DEVICE_ROLE_DETACHED)
+    if (!IsDetached())
     {
+#if OPENTHREAD_FTD
         if (IsFullThreadDevice())
         {
             SuccessOrExit(error = Get<MleRouter>().HandleAdvertisement(aMessage, aMessageInfo, aNeighbor));
         }
-        else if ((aNeighbor == &mParent) && (mParent.GetRloc16() != sourceAddress.GetRloc16()))
+        else
+#endif
         {
-            // Remove stale parent.
-            BecomeDetached();
+            if ((aNeighbor == &mParent) && (mParent.GetRloc16() != sourceAddress))
+            {
+                // Remove stale parent.
+                IgnoreError(BecomeDetached());
+            }
         }
     }
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDisabled:
+    case kRoleDetached:
         ExitNow();
 
-    case OT_DEVICE_ROLE_CHILD:
-        VerifyOrExit(aNeighbor == &mParent);
+    case kRoleChild:
+        VerifyOrExit(aNeighbor == &mParent, OT_NOOP);
 
-        if ((mParent.GetRloc16() == sourceAddress.GetRloc16()) &&
-            (leaderData.GetPartitionId() != mLeaderData.GetPartitionId() ||
-             leaderData.GetLeaderRouterId() != GetLeaderId()))
+        if ((mParent.GetRloc16() == sourceAddress) && (leaderData.GetPartitionId() != mLeaderData.GetPartitionId() ||
+                                                       leaderData.GetLeaderRouterId() != GetLeaderId()))
         {
             SetLeaderData(leaderData.GetPartitionId(), leaderData.GetWeighting(), leaderData.GetLeaderRouterId());
 
-            if (IsFullThreadDevice() && (Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE) &&
-                route.IsValid())
+#if OPENTHREAD_FTD
+            if (IsFullThreadDevice())
             {
-                // Overwrite Route Data
-                Get<MleRouter>().ProcessRouteTlv(route);
+                RouteTlv route;
+
+                if ((Tlv::FindTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE) && route.IsValid())
+                {
+                    // Overwrite Route Data
+                    IgnoreError(Get<MleRouter>().ProcessRouteTlv(route));
+                }
             }
+#endif
 
             mRetrieveNewNetworkData = true;
         }
@@ -2875,23 +2837,17 @@
         mParent.SetLastHeard(TimerMilli::GetNow());
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
-        VerifyOrExit(aNeighbor && aNeighbor->IsStateValid());
+    case kRoleRouter:
+    case kRoleLeader:
+        VerifyOrExit(aNeighbor && aNeighbor->IsStateValid(), OT_NOOP);
         break;
     }
 
     if (mRetrieveNewNetworkData || IsNetworkDataNewer(leaderData))
     {
         delay = Random::NonCrypto::GetUint16InRange(0, kMleMaxResponseDelay);
-        SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs), delay);
+        IgnoreError(SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs), delay));
     }
-#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
-    else
-    {
-        Get<NetworkData::Local>().SendServerDataNotification();
-    }
-#endif
 
 exit:
 
@@ -2899,13 +2855,9 @@
     {
         otLogWarnMle("Failed to process Advertisement: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError Mle::HandleDataResponse(const Message &         aMessage,
-                                const Ip6::MessageInfo &aMessageInfo,
-                                const Neighbor *        aNeighbor)
+void Mle::HandleDataResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor)
 {
     otError error;
 
@@ -2922,7 +2874,7 @@
         // running out the specified number. E.g. other component also trigger fast poll, and
         // is waiting for response; or the corner case where multiple Mle Data Request attempts
         // happened due to the retransmission mechanism.
-        IgnoreReturnValue(Get<DataPollSender>().StopFastPolls());
+        Get<DataPollSender>().StopFastPolls();
     }
 
 exit:
@@ -2931,11 +2883,9 @@
     {
         otLogWarnMle("Failed to process Data Response: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-bool Mle::IsNetworkDataNewer(const LeaderDataTlv &aLeaderData)
+bool Mle::IsNetworkDataNewer(const LeaderData &aLeaderData)
 {
     int8_t diff;
 
@@ -2954,7 +2904,7 @@
 otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError             error = OT_ERROR_NONE;
-    LeaderDataTlv       leaderData;
+    LeaderData          leaderData;
     ActiveTimestampTlv  activeTimestamp;
     PendingTimestampTlv pendingTimestamp;
     uint16_t            networkDataOffset    = 0;
@@ -2964,14 +2914,19 @@
     Tlv                 tlv;
 
     // Leader Data
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
-    VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadLeaderData(aMessage, leaderData));
 
     if ((leaderData.GetPartitionId() != mLeaderData.GetPartitionId()) ||
         (leaderData.GetWeighting() != mLeaderData.GetWeighting()) || (leaderData.GetLeaderRouterId() != GetLeaderId()))
     {
-        if (mRole == OT_DEVICE_ROLE_CHILD)
+        if (IsChild())
         {
+#if OPENTHREAD_FTD
+            // An FTD skips handling LeaderData of a different partition.
+            VerifyOrExit(!IsFullThreadDevice() || (leaderData.GetPartitionId() == mLeaderData.GetPartitionId() &&
+                                                   leaderData.GetLeaderRouterId() == GetLeaderId()),
+                         error = OT_ERROR_DROP);
+#endif
             SetLeaderData(leaderData.GetPartitionId(), leaderData.GetWeighting(), leaderData.GetLeaderRouterId());
             mRetrieveNewNetworkData = true;
         }
@@ -2982,11 +2937,11 @@
     }
     else if (!mRetrieveNewNetworkData)
     {
-        VerifyOrExit(IsNetworkDataNewer(leaderData));
+        VerifyOrExit(IsNetworkDataNewer(leaderData), OT_NOOP);
     }
 
     // Active Timestamp
-    if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
     {
         const MeshCoP::Timestamp *timestamp;
 
@@ -2995,8 +2950,8 @@
 
         // if received timestamp does not match the local value and message does not contain the dataset,
         // send MLE Data Request
-        if ((timestamp == NULL || timestamp->Compare(activeTimestamp) != 0) &&
-            (Tlv::GetOffset(aMessage, Tlv::kActiveDataset, activeDatasetOffset) != OT_ERROR_NONE))
+        if (!IsLeader() && ((timestamp == nullptr) || (timestamp->Compare(activeTimestamp) != 0)) &&
+            (Tlv::FindTlvOffset(aMessage, Tlv::kActiveDataset, activeDatasetOffset) != OT_ERROR_NONE))
         {
             ExitNow(dataRequest = true);
         }
@@ -3007,7 +2962,7 @@
     }
 
     // Pending Timestamp
-    if (Tlv::GetTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
     {
         const MeshCoP::Timestamp *timestamp;
 
@@ -3016,8 +2971,8 @@
 
         // if received timestamp does not match the local value and message does not contain the dataset,
         // send MLE Data Request
-        if ((timestamp == NULL || timestamp->Compare(pendingTimestamp) != 0) &&
-            (Tlv::GetOffset(aMessage, Tlv::kPendingDataset, pendingDatasetOffset) != OT_ERROR_NONE))
+        if (!IsLeader() && ((timestamp == nullptr) || (timestamp->Compare(pendingTimestamp) != 0)) &&
+            (Tlv::FindTlvOffset(aMessage, Tlv::kPendingDataset, pendingDatasetOffset) != OT_ERROR_NONE))
         {
             ExitNow(dataRequest = true);
         }
@@ -3027,7 +2982,7 @@
         pendingTimestamp.SetLength(0);
     }
 
-    if (Tlv::GetOffset(aMessage, Tlv::kNetworkData, networkDataOffset) == OT_ERROR_NONE)
+    if (Tlv::FindTlvOffset(aMessage, Tlv::kNetworkData, networkDataOffset) == OT_ERROR_NONE)
     {
         error =
             Get<NetworkData::Leader>().SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
@@ -3039,25 +2994,34 @@
         ExitNow(dataRequest = true);
     }
 
-    // Active Dataset
-    if (activeTimestamp.GetLength() > 0)
+#if OPENTHREAD_FTD
+    if (IsLeader())
     {
-        if (activeDatasetOffset > 0)
-        {
-            aMessage.Read(activeDatasetOffset, sizeof(tlv), &tlv);
-            Get<MeshCoP::ActiveDataset>().Save(activeTimestamp, aMessage, activeDatasetOffset + sizeof(tlv),
-                                               tlv.GetLength());
-        }
+        Get<NetworkData::Leader>().IncrementVersionAndStableVersion();
     }
-
-    // Pending Dataset
-    if (pendingTimestamp.GetLength() > 0)
+    else
+#endif
     {
-        if (pendingDatasetOffset > 0)
+        // Active Dataset
+        if (activeTimestamp.GetLength() > 0)
         {
-            aMessage.Read(pendingDatasetOffset, sizeof(tlv), &tlv);
-            Get<MeshCoP::PendingDataset>().Save(pendingTimestamp, aMessage, pendingDatasetOffset + sizeof(tlv),
-                                                tlv.GetLength());
+            if (activeDatasetOffset > 0)
+            {
+                aMessage.Read(activeDatasetOffset, sizeof(tlv), &tlv);
+                IgnoreError(Get<MeshCoP::ActiveDataset>().Save(activeTimestamp, aMessage,
+                                                               activeDatasetOffset + sizeof(tlv), tlv.GetLength()));
+            }
+        }
+
+        // Pending Dataset
+        if (pendingTimestamp.GetLength() > 0)
+        {
+            if (pendingDatasetOffset > 0)
+            {
+                aMessage.Read(pendingDatasetOffset, sizeof(tlv), &tlv);
+                IgnoreError(Get<MeshCoP::PendingDataset>().Save(pendingTimestamp, aMessage,
+                                                                pendingDatasetOffset + sizeof(tlv), tlv.GetLength()));
+            }
         }
     }
 
@@ -3082,7 +3046,7 @@
             delay = 10;
         }
 
-        SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs), delay);
+        IgnoreError(SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs), delay));
     }
     else if (error == OT_ERROR_NONE)
     {
@@ -3100,7 +3064,11 @@
     return error;
 }
 
-bool Mle::IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, uint8_t aLinkMargin, ConnectivityTlv &aConnectivityTlv)
+bool Mle::IsBetterParent(uint16_t               aRloc16,
+                         uint8_t                aLinkQuality,
+                         uint8_t                aLinkMargin,
+                         const ConnectivityTlv &aConnectivityTlv,
+                         uint8_t                aVersion)
 {
     bool rval = false;
 
@@ -3109,6 +3077,7 @@
                                              ? candidateLinkQualityIn
                                              : mParentCandidate.GetLinkQualityOut();
 
+    // Mesh Impacting Criteria
     if (aLinkQuality != candidateTwoWayLinkQuality)
     {
         ExitNow(rval = (aLinkQuality > candidateTwoWayLinkQuality));
@@ -3124,11 +3093,29 @@
         ExitNow(rval = (aConnectivityTlv.GetParentPriority() > mParentPriority));
     }
 
+    // Prefer the parent with highest quality links (Link Quality 3 field in Connectivity TLV) to neighbors
     if (aConnectivityTlv.GetLinkQuality3() != mParentLinkQuality3)
     {
         ExitNow(rval = (aConnectivityTlv.GetLinkQuality3() > mParentLinkQuality3));
     }
 
+    // Thread 1.2 Specification 4.5.2.1.2 Child Impacting Criteria
+    if (aVersion != mParentCandidate.GetVersion())
+    {
+        ExitNow(rval = (aVersion > mParentCandidate.GetVersion()));
+    }
+
+    if (aConnectivityTlv.GetSedBufferSize() != mParentSedBufferSize)
+    {
+        ExitNow(rval = (aConnectivityTlv.GetSedBufferSize() > mParentSedBufferSize));
+    }
+
+    if (aConnectivityTlv.GetSedDatagramCount() != mParentSedDatagramCount)
+    {
+        ExitNow(rval = (aConnectivityTlv.GetSedDatagramCount() > mParentSedDatagramCount));
+    }
+
+    // Extra rules
     if (aConnectivityTlv.GetLinkQuality2() != mParentLinkQuality2)
     {
         ExitNow(rval = (aConnectivityTlv.GetLinkQuality2() > mParentLinkQuality2));
@@ -3145,63 +3132,62 @@
     return rval;
 }
 
-otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence)
+void Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence)
 {
     otError                 error    = OT_ERROR_NONE;
     const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
-    ResponseTlv             response;
-    SourceAddressTlv        sourceAddress;
-    LeaderDataTlv           leaderData;
-    LinkMarginTlv           linkMarginTlv;
+    Challenge               response;
+    uint16_t                version;
+    uint16_t                sourceAddress;
+    LeaderData              leaderData;
+    uint8_t                 linkMarginFromTlv;
     uint8_t                 linkMargin;
     uint8_t                 linkQuality;
     ConnectivityTlv         connectivity;
-    LinkFrameCounterTlv     linkFrameCounter;
-    MleFrameCounterTlv      mleFrameCounter;
-    ChallengeTlv            challenge;
+    uint32_t                linkFrameCounter;
+    uint32_t                mleFrameCounter;
     Mac::ExtAddress         extAddress;
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     TimeParameterTlv timeParameter;
 #endif
 
     // Source Address
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
-    VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress));
 
-    LogMleMessage("Receive Parent Response", aMessageInfo.GetPeerAddr(), sourceAddress.GetRloc16());
+    LogMleMessage("Receive Parent Response", aMessageInfo.GetPeerAddr(), sourceAddress);
+
+    // Version
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kVersion, version));
+    VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = OT_ERROR_PARSE);
 
     // Response
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kResponse, sizeof(response), response));
-    VerifyOrExit(response.IsValid() &&
-                     memcmp(response.GetResponse(), mParentRequest.mChallenge, response.GetResponseLength()) == 0,
-                 error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadResponse(aMessage, response));
+    VerifyOrExit(response == mParentRequestChallenge, error = OT_ERROR_PARSE);
 
-    aMessageInfo.GetPeerAddr().ToExtAddress(extAddress);
+    aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddress);
 
-    if (mRole == OT_DEVICE_ROLE_CHILD && mParent.GetExtAddress() == extAddress)
+    if (IsChild() && mParent.GetExtAddress() == extAddress)
     {
         mReceivedResponseFromParent = true;
     }
 
     // Leader Data
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
-    VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadLeaderData(aMessage, leaderData));
 
-    // Link Quality
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLinkMargin, sizeof(linkMarginTlv), linkMarginTlv));
-    VerifyOrExit(linkMarginTlv.IsValid(), error = OT_ERROR_PARSE);
+    // Link Margin
+    SuccessOrExit(error = Tlv::FindUint8Tlv(aMessage, Tlv::kLinkMargin, linkMarginFromTlv));
 
     linkMargin = LinkQualityInfo::ConvertRssToLinkMargin(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
 
-    if (linkMargin > linkMarginTlv.GetLinkMargin())
+    if (linkMargin > linkMarginFromTlv)
     {
-        linkMargin = linkMarginTlv.GetLinkMargin();
+        linkMargin = linkMarginFromTlv;
     }
 
     linkQuality = LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin);
 
     // Connectivity
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kConnectivity, sizeof(connectivity), connectivity));
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, Tlv::kConnectivity, sizeof(connectivity), connectivity));
     VerifyOrExit(connectivity.IsValid(), error = OT_ERROR_PARSE);
 
     // Share data with application, if requested.
@@ -3210,7 +3196,7 @@
         otThreadParentResponseInfo parentinfo;
 
         parentinfo.mExtAddr      = extAddress;
-        parentinfo.mRloc16       = sourceAddress.GetRloc16();
+        parentinfo.mRloc16       = sourceAddress;
         parentinfo.mRssi         = linkInfo->mRss;
         parentinfo.mPriority     = connectivity.GetParentPriority();
         parentinfo.mLinkQuality3 = connectivity.GetLinkQuality3();
@@ -3222,32 +3208,33 @@
     }
 
 #if OPENTHREAD_FTD
-    if (IsFullThreadDevice() && (mRole != OT_DEVICE_ROLE_DETACHED))
+    if (IsFullThreadDevice() && !IsDetached())
     {
         int8_t diff = static_cast<int8_t>(connectivity.GetIdSequence() - Get<RouterTable>().GetRouterIdSequence());
 
         switch (mParentRequestMode)
         {
         case kAttachAny:
-            VerifyOrExit(leaderData.GetPartitionId() != mLeaderData.GetPartitionId() || diff > 0);
+            VerifyOrExit(leaderData.GetPartitionId() != mLeaderData.GetPartitionId() || diff > 0, OT_NOOP);
             break;
 
         case kAttachSame1:
         case kAttachSame2:
-            VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId());
-            VerifyOrExit(diff > 0);
+            VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId(), OT_NOOP);
+            VerifyOrExit(diff > 0, OT_NOOP);
             break;
 
         case kAttachSameDowngrade:
-            VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId());
-            VerifyOrExit(diff >= 0);
+            VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId(), OT_NOOP);
+            VerifyOrExit(diff >= 0, OT_NOOP);
             break;
 
         case kAttachBetter:
-            VerifyOrExit(leaderData.GetPartitionId() != mLeaderData.GetPartitionId());
+            VerifyOrExit(leaderData.GetPartitionId() != mLeaderData.GetPartitionId(), OT_NOOP);
 
             VerifyOrExit(MleRouter::ComparePartitions(connectivity.GetActiveRouters() <= 1, leaderData,
-                                                      Get<MleRouter>().IsSingleton(), mLeaderData) > 0);
+                                                      Get<MleRouter>().IsSingleton(), mLeaderData) > 0,
+                         OT_NOOP);
             break;
         }
     }
@@ -3262,6 +3249,7 @@
 
         int compare = 0;
 
+#if OPENTHREAD_FTD
         if (IsFullThreadDevice())
         {
             compare = MleRouter::ComparePartitions(connectivity.GetActiveRouters() <= 1, leaderData, mParentIsSingleton,
@@ -3269,32 +3257,36 @@
         }
 
         // only consider partitions that are the same or better
-        VerifyOrExit(compare >= 0);
+        VerifyOrExit(compare >= 0, OT_NOOP);
+#endif
 
         // only consider better parents if the partitions are the same
-        VerifyOrExit(compare != 0 || IsBetterParent(sourceAddress.GetRloc16(), linkQuality, linkMargin, connectivity));
+        VerifyOrExit(compare != 0 || IsBetterParent(sourceAddress, linkQuality, linkMargin, connectivity,
+                                                    static_cast<uint8_t>(version)),
+                     OT_NOOP);
     }
 
     // Link Frame Counter
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLinkFrameCounter, sizeof(linkFrameCounter), linkFrameCounter));
-    VerifyOrExit(linkFrameCounter.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint32Tlv(aMessage, Tlv::kLinkFrameCounter, linkFrameCounter));
 
     // Mle Frame Counter
-    if (Tlv::GetTlv(aMessage, Tlv::kMleFrameCounter, sizeof(mleFrameCounter), mleFrameCounter) == OT_ERROR_NONE)
+    switch (Tlv::FindUint32Tlv(aMessage, Tlv::kMleFrameCounter, mleFrameCounter))
     {
-        VerifyOrExit(mleFrameCounter.IsValid());
-    }
-    else
-    {
-        mleFrameCounter.SetFrameCounter(linkFrameCounter.GetFrameCounter());
+    case OT_ERROR_NONE:
+        break;
+    case OT_ERROR_NOT_FOUND:
+        mleFrameCounter = linkFrameCounter;
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 
     // Time Parameter
-    if (Tlv::GetTlv(aMessage, Tlv::kTimeParameter, sizeof(timeParameter), timeParameter) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kTimeParameter, sizeof(timeParameter), timeParameter) == OT_ERROR_NONE)
     {
-        VerifyOrExit(timeParameter.IsValid());
+        VerifyOrExit(timeParameter.IsValid(), OT_NOOP);
 
         Get<TimeSync>().SetTimeSyncPeriod(timeParameter.GetTimeSyncPeriod());
         Get<TimeSync>().SetXtalThreshold(timeParameter.GetXtalThreshold());
@@ -3311,32 +3303,32 @@
 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 
     // Challenge
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kChallenge, sizeof(challenge), challenge));
-    VerifyOrExit(challenge.IsValid(), error = OT_ERROR_PARSE);
-    mChildIdRequest.mChallengeLength = challenge.GetChallengeLength();
-    memcpy(mChildIdRequest.mChallenge, challenge.GetChallenge(), mChildIdRequest.mChallengeLength);
+    SuccessOrExit(error = ReadChallenge(aMessage, mParentCandidateChallenge));
 
     mParentCandidate.SetExtAddress(extAddress);
-    mParentCandidate.SetRloc16(sourceAddress.GetRloc16());
-    mParentCandidate.SetLinkFrameCounter(linkFrameCounter.GetFrameCounter());
-    mParentCandidate.SetMleFrameCounter(mleFrameCounter.GetFrameCounter());
+    mParentCandidate.SetRloc16(sourceAddress);
+    mParentCandidate.SetLinkFrameCounter(linkFrameCounter);
+    mParentCandidate.SetMleFrameCounter(mleFrameCounter);
+    mParentCandidate.SetVersion(static_cast<uint8_t>(version));
     mParentCandidate.SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle |
                                               DeviceMode::kModeFullNetworkData | DeviceMode::kModeSecureDataRequest));
     mParentCandidate.GetLinkInfo().Clear();
-    mParentCandidate.GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
+    mParentCandidate.GetLinkInfo().AddRss(linkInfo->mRss);
     mParentCandidate.ResetLinkFailures();
-    mParentCandidate.SetLinkQualityOut(LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMarginTlv.GetLinkMargin()));
+    mParentCandidate.SetLinkQualityOut(LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMarginFromTlv));
     mParentCandidate.SetState(Neighbor::kStateParentResponse);
     mParentCandidate.SetKeySequence(aKeySequence);
 
-    mParentPriority     = connectivity.GetParentPriority();
-    mParentLinkQuality3 = connectivity.GetLinkQuality3();
-    mParentLinkQuality2 = connectivity.GetLinkQuality2();
-    mParentLinkQuality1 = connectivity.GetLinkQuality1();
-    mParentLeaderCost   = connectivity.GetLeaderCost();
-    mParentLeaderData   = leaderData;
-    mParentIsSingleton  = connectivity.GetActiveRouters() <= 1;
-    mParentLinkMargin   = linkMargin;
+    mParentPriority         = connectivity.GetParentPriority();
+    mParentLinkQuality3     = connectivity.GetLinkQuality3();
+    mParentLinkQuality2     = connectivity.GetLinkQuality2();
+    mParentLinkQuality1     = connectivity.GetLinkQuality1();
+    mParentLeaderCost       = connectivity.GetLeaderCost();
+    mParentSedBufferSize    = connectivity.GetSedBufferSize();
+    mParentSedDatagramCount = connectivity.GetSedDatagramCount();
+    mParentLeaderData       = leaderData;
+    mParentIsSingleton      = connectivity.GetActiveRouters() <= 1;
+    mParentLinkMargin       = linkMargin;
 
 exit:
 
@@ -3344,21 +3336,18 @@
     {
         otLogWarnMle("Failed to process Parent Response: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError Mle::HandleChildIdResponse(const Message &         aMessage,
-                                   const Ip6::MessageInfo &aMessageInfo,
-                                   const Neighbor *        aNeighbor)
+void Mle::HandleChildIdResponse(const Message &         aMessage,
+                                const Ip6::MessageInfo &aMessageInfo,
+                                const Neighbor *        aNeighbor)
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
     otError             error = OT_ERROR_NONE;
-    LeaderDataTlv       leaderData;
-    SourceAddressTlv    sourceAddress;
-    Address16Tlv        shortAddress;
-    RouteTlv            route;
+    LeaderData          leaderData;
+    uint16_t            sourceAddress;
+    uint16_t            shortAddress;
     ActiveTimestampTlv  activeTimestamp;
     PendingTimestampTlv pendingTimestamp;
     Tlv                 tlv;
@@ -3366,37 +3355,35 @@
     uint16_t            offset;
 
     // Source Address
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
-    VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress));
 
-    LogMleMessage("Receive Child ID Response", aMessageInfo.GetPeerAddr(), sourceAddress.GetRloc16());
+    LogMleMessage("Receive Child ID Response", aMessageInfo.GetPeerAddr(), sourceAddress);
 
     VerifyOrExit(aNeighbor && aNeighbor->IsStateValid(), error = OT_ERROR_SECURITY);
 
-    VerifyOrExit(mAttachState == kAttachStateChildIdRequest);
+    VerifyOrExit(mAttachState == kAttachStateChildIdRequest, OT_NOOP);
 
     // Leader Data
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
-    VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadLeaderData(aMessage, leaderData));
 
     // ShortAddress
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kAddress16, sizeof(shortAddress), shortAddress));
-    VerifyOrExit(shortAddress.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kAddress16, shortAddress));
 
     // Network Data
-    error = Tlv::GetOffset(aMessage, Tlv::kNetworkData, networkDataOffset);
+    error = Tlv::FindTlvOffset(aMessage, Tlv::kNetworkData, networkDataOffset);
     SuccessOrExit(error);
 
     // Active Timestamp
-    if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
     {
         VerifyOrExit(activeTimestamp.IsValid(), error = OT_ERROR_PARSE);
 
         // Active Dataset
-        if (Tlv::GetOffset(aMessage, Tlv::kActiveDataset, offset) == OT_ERROR_NONE)
+        if (Tlv::FindTlvOffset(aMessage, Tlv::kActiveDataset, offset) == OT_ERROR_NONE)
         {
             aMessage.Read(offset, sizeof(tlv), &tlv);
-            Get<MeshCoP::ActiveDataset>().Save(activeTimestamp, aMessage, offset + sizeof(tlv), tlv.GetLength());
+            IgnoreError(
+                Get<MeshCoP::ActiveDataset>().Save(activeTimestamp, aMessage, offset + sizeof(tlv), tlv.GetLength()));
         }
     }
 
@@ -3407,15 +3394,16 @@
     }
 
     // Pending Timestamp
-    if (Tlv::GetTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
     {
         VerifyOrExit(pendingTimestamp.IsValid(), error = OT_ERROR_PARSE);
 
         // Pending Dataset
-        if (Tlv::GetOffset(aMessage, Tlv::kPendingDataset, offset) == OT_ERROR_NONE)
+        if (Tlv::FindTlvOffset(aMessage, Tlv::kPendingDataset, offset) == OT_ERROR_NONE)
         {
             aMessage.Read(offset, sizeof(tlv), &tlv);
-            Get<MeshCoP::PendingDataset>().Save(pendingTimestamp, aMessage, offset + sizeof(tlv), tlv.GetLength());
+            IgnoreError(
+                Get<MeshCoP::PendingDataset>().Save(pendingTimestamp, aMessage, offset + sizeof(tlv), tlv.GetLength()));
         }
     }
     else
@@ -3447,21 +3435,28 @@
         Get<MeshForwarder>().SetRxOnWhenIdle(true);
     }
 
-    // Route
-    if ((Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE) && IsFullThreadDevice())
+#if OPENTHREAD_FTD
+    if (IsFullThreadDevice())
     {
-        SuccessOrExit(error = Get<MleRouter>().ProcessRouteTlv(route));
+        RouteTlv route;
+
+        if (Tlv::FindTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE)
+        {
+            SuccessOrExit(error = Get<MleRouter>().ProcessRouteTlv(route));
+        }
     }
+#endif
 
     mParent = mParentCandidate;
     mParentCandidate.Clear();
 
-    mParent.SetRloc16(sourceAddress.GetRloc16());
+    mParent.SetRloc16(sourceAddress);
 
-    Get<NetworkData::Leader>().SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
-                                              !IsFullNetworkData(), aMessage, networkDataOffset);
+    IgnoreError(Get<NetworkData::Leader>().SetNetworkData(leaderData.GetDataVersion(),
+                                                          leaderData.GetStableDataVersion(), !IsFullNetworkData(),
+                                                          aMessage, networkDataOffset));
 
-    SetStateChild(shortAddress.GetRloc16());
+    SetStateChild(shortAddress);
 
 exit:
 
@@ -3469,56 +3464,56 @@
     {
         otLogWarnMle("Failed to process Child ID Response: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError Mle::HandleChildUpdateRequest(const Message &         aMessage,
-                                      const Ip6::MessageInfo &aMessageInfo,
-                                      Neighbor *              aNeighbor)
+void Mle::HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor)
 {
     static const uint8_t kMaxResponseTlvs = 6;
 
-    otError          error = OT_ERROR_NONE;
-    SourceAddressTlv sourceAddress;
-    ChallengeTlv     challenge;
-    TlvRequestTlv    tlvRequest;
-    uint8_t          tlvs[kMaxResponseTlvs] = {};
-    uint8_t          numTlvs                = 0;
+    otError       error = OT_ERROR_NONE;
+    uint16_t      sourceAddress;
+    Challenge     challenge;
+    RequestedTlvs requestedTlvs;
+    uint8_t       tlvs[kMaxResponseTlvs] = {};
+    uint8_t       numTlvs                = 0;
 
     // Source Address
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
-    VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress));
 
-    LogMleMessage("Receive Child Update Request from parent", aMessageInfo.GetPeerAddr(), sourceAddress.GetRloc16());
+    LogMleMessage("Receive Child Update Request from parent", aMessageInfo.GetPeerAddr(), sourceAddress);
 
     // Challenge
-    if (Tlv::GetTlv(aMessage, Tlv::kChallenge, sizeof(challenge), challenge) == OT_ERROR_NONE)
+    switch (ReadChallenge(aMessage, challenge))
     {
-        VerifyOrExit(challenge.IsValid(), error = OT_ERROR_PARSE);
+    case OT_ERROR_NONE:
         tlvs[numTlvs++] = Tlv::kResponse;
         tlvs[numTlvs++] = Tlv::kMleFrameCounter;
         tlvs[numTlvs++] = Tlv::kLinkFrameCounter;
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     if (aNeighbor == &mParent)
     {
-        StatusTlv status;
+        uint8_t status;
 
-        if (Tlv::GetTlv(aMessage, Tlv::kStatus, sizeof(status), status) == OT_ERROR_NONE)
+        switch (Tlv::FindUint8Tlv(aMessage, Tlv::kStatus, status))
         {
-            VerifyOrExit(status.IsValid(), error = OT_ERROR_PARSE);
-
-            if (status.GetStatus() == StatusTlv::kError)
-            {
-                BecomeDetached();
-                ExitNow();
-            }
+        case OT_ERROR_NONE:
+            VerifyOrExit(status != StatusTlv::kError, IgnoreError(BecomeDetached()));
+            break;
+        case OT_ERROR_NOT_FOUND:
+            break;
+        default:
+            ExitNow(error = OT_ERROR_PARSE);
         }
 
-        if (mParent.GetRloc16() != sourceAddress.GetRloc16())
+        if (mParent.GetRloc16() != sourceAddress)
         {
-            BecomeDetached();
+            IgnoreError(BecomeDetached());
             ExitNow();
         }
 
@@ -3532,20 +3527,24 @@
     }
 
     // TLV Request
-    if (Tlv::GetTlv(aMessage, Tlv::kTlvRequest, sizeof(tlvRequest), tlvRequest) == OT_ERROR_NONE)
+    switch (FindTlvRequest(aMessage, requestedTlvs))
     {
-        VerifyOrExit(tlvRequest.IsValid(), error = OT_ERROR_PARSE);
-
-        for (uint8_t i = 0; i < tlvRequest.GetLength(); i++)
+    case OT_ERROR_NONE:
+        for (uint8_t i = 0; i < requestedTlvs.mNumTlvs; i++)
         {
             if (numTlvs >= sizeof(tlvs))
             {
-                otLogWarnMle("Failed to respond with TLVs: %d of %d", i, tlvRequest.GetLength());
+                otLogWarnMle("Failed to respond with TLVs: %d of %d", i, requestedTlvs.mNumTlvs);
                 break;
             }
 
-            tlvs[numTlvs++] = tlvRequest.GetTlvs()[i];
+            tlvs[numTlvs++] = requestedTlvs.mTlvs[i];
         }
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     SuccessOrExit(error = SendChildUpdateResponse(tlvs, numTlvs, challenge));
@@ -3556,74 +3555,68 @@
     {
         otLogWarnMle("Failed to process Child Update Request from parent: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError Mle::HandleChildUpdateResponse(const Message &         aMessage,
-                                       const Ip6::MessageInfo &aMessageInfo,
-                                       const Neighbor *        aNeighbor)
+void Mle::HandleChildUpdateResponse(const Message &         aMessage,
+                                    const Ip6::MessageInfo &aMessageInfo,
+                                    const Neighbor *        aNeighbor)
 {
-    otError             error = OT_ERROR_NONE;
-    StatusTlv           status;
-    ModeTlv             mode;
-    ResponseTlv         response;
-    LinkFrameCounterTlv linkFrameCounter;
-    MleFrameCounterTlv  mleFrameCounter;
-    SourceAddressTlv    sourceAddress;
-    TimeoutTlv          timeout;
+    otError   error = OT_ERROR_NONE;
+    uint8_t   status;
+    uint8_t   mode;
+    Challenge response;
+    uint32_t  linkFrameCounter;
+    uint32_t  mleFrameCounter;
+    uint16_t  sourceAddress;
+    uint32_t  timeout;
 
     LogMleMessage("Receive Child Update Response from parent", aMessageInfo.GetPeerAddr());
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DETACHED:
-        VerifyOrExit(
-            (Tlv::GetTlv(aMessage, Tlv::kResponse, sizeof(response), response) == OT_ERROR_NONE) &&
-                (response.IsValid()) &&
-                (!memcmp(response.GetResponse(), mParentRequest.mChallenge, sizeof(mParentRequest.mChallenge))),
-            error = OT_ERROR_SECURITY);
+    case kRoleDetached:
+        SuccessOrExit(error = ReadResponse(aMessage, response));
+        VerifyOrExit(response == mParentRequestChallenge, error = OT_ERROR_SECURITY);
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         VerifyOrExit((aNeighbor == &mParent) && mParent.IsStateValid(), error = OT_ERROR_SECURITY);
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
     // Status
-    if (Tlv::GetTlv(aMessage, Tlv::kStatus, sizeof(status), status) == OT_ERROR_NONE)
+    if (Tlv::FindUint8Tlv(aMessage, Tlv::kStatus, status) == OT_ERROR_NONE)
     {
-        BecomeDetached();
+        IgnoreError(BecomeDetached());
         ExitNow();
     }
 
     // Mode
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kMode, sizeof(mode), mode));
-    VerifyOrExit(mode.IsValid(), error = OT_ERROR_PARSE);
-    VerifyOrExit(mode.GetMode() == mDeviceMode, error = OT_ERROR_DROP);
+    SuccessOrExit(error = Tlv::FindUint8Tlv(aMessage, Tlv::kMode, mode));
+    VerifyOrExit(DeviceMode(mode) == mDeviceMode, error = OT_ERROR_DROP);
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DETACHED:
-        SuccessOrExit(error =
-                          Tlv::GetTlv(aMessage, Tlv::kLinkFrameCounter, sizeof(linkFrameCounter), linkFrameCounter));
-        VerifyOrExit(linkFrameCounter.IsValid(), error = OT_ERROR_PARSE);
+    case kRoleDetached:
+        SuccessOrExit(error = Tlv::FindUint32Tlv(aMessage, Tlv::kLinkFrameCounter, linkFrameCounter));
 
-        if (Tlv::GetTlv(aMessage, Tlv::kMleFrameCounter, sizeof(mleFrameCounter), mleFrameCounter) == OT_ERROR_NONE)
+        switch (Tlv::FindUint32Tlv(aMessage, Tlv::kMleFrameCounter, mleFrameCounter))
         {
-            VerifyOrExit(mleFrameCounter.IsValid(), error = OT_ERROR_PARSE);
-        }
-        else
-        {
-            mleFrameCounter.SetFrameCounter(linkFrameCounter.GetFrameCounter());
+        case OT_ERROR_NONE:
+            break;
+        case OT_ERROR_NOT_FOUND:
+            mleFrameCounter = linkFrameCounter;
+            break;
+        default:
+            ExitNow(error = OT_ERROR_PARSE);
         }
 
-        mParent.SetLinkFrameCounter(linkFrameCounter.GetFrameCounter());
-        mParent.SetMleFrameCounter(mleFrameCounter.GetFrameCounter());
+        mParent.SetLinkFrameCounter(linkFrameCounter);
+        mParent.SetMleFrameCounter(mleFrameCounter);
 
         mParent.SetState(Neighbor::kStateValid);
         SetStateChild(GetRloc16());
@@ -3632,14 +3625,13 @@
 
         // fall through
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         // Source Address
-        SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
-        VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
+        SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress));
 
-        if (RouterIdFromRloc16(sourceAddress.GetRloc16()) != RouterIdFromRloc16(GetRloc16()))
+        if (RouterIdFromRloc16(sourceAddress) != RouterIdFromRloc16(GetRloc16()))
         {
-            BecomeDetached();
+            IgnoreError(BecomeDetached());
             ExitNow();
         }
 
@@ -3647,10 +3639,15 @@
         SuccessOrExit(error = HandleLeaderData(aMessage, aMessageInfo));
 
         // Timeout optional
-        if (Tlv::GetTlv(aMessage, Tlv::kTimeout, sizeof(timeout), timeout) == OT_ERROR_NONE)
+        switch (Tlv::FindUint32Tlv(aMessage, Tlv::kTimeout, timeout))
         {
-            VerifyOrExit(timeout.IsValid(), error = OT_ERROR_PARSE);
-            mTimeout = timeout.GetTimeout();
+        case OT_ERROR_NONE:
+            mTimeout = timeout;
+            break;
+        case OT_ERROR_NOT_FOUND:
+            break;
+        default:
+            ExitNow(error = OT_ERROR_PARSE);
         }
 
         if (!IsRxOnWhenIdle())
@@ -3666,8 +3663,8 @@
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
 exit:
@@ -3685,11 +3682,9 @@
     {
         otLogWarnMle("Failed to process Child Update Response: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError Mle::HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+void Mle::HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
@@ -3697,38 +3692,36 @@
     ChannelTlv                channelTlv;
     ActiveTimestampTlv        timestamp;
     const MeshCoP::Timestamp *localTimestamp;
-    PanIdTlv                  panIdTlv;
     uint8_t                   channel;
     uint16_t                  panId;
 
     LogMleMessage("Receive Announce", aMessageInfo.GetPeerAddr());
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kChannel, sizeof(channelTlv), channelTlv));
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, Tlv::kChannel, sizeof(channelTlv), channelTlv));
     VerifyOrExit(channelTlv.IsValid(), error = OT_ERROR_PARSE);
 
     channel = static_cast<uint8_t>(channelTlv.GetChannel());
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(timestamp), timestamp));
+    SuccessOrExit(error = Tlv::FindTlv(aMessage, Tlv::kActiveTimestamp, sizeof(timestamp), timestamp));
     VerifyOrExit(timestamp.IsValid(), error = OT_ERROR_PARSE);
 
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kPanId, sizeof(panIdTlv), panIdTlv));
-    VerifyOrExit(panIdTlv.IsValid(), error = OT_ERROR_PARSE);
-    panId = panIdTlv.GetPanId();
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kPanId, panId));
 
     localTimestamp = Get<MeshCoP::ActiveDataset>().GetTimestamp();
 
-    if (localTimestamp == NULL || localTimestamp->Compare(timestamp) > 0)
+    if (localTimestamp == nullptr || localTimestamp->Compare(timestamp) > 0)
     {
         // No action is required if device is detached, and current
         // channel and pan-id match the values from the received MLE
         // Announce message.
 
-        VerifyOrExit((mRole != OT_DEVICE_ROLE_DETACHED) || (Get<Mac::Mac>().GetPanChannel() != channel) ||
-                     (Get<Mac::Mac>().GetPanId() != panId));
+        VerifyOrExit(!IsDetached() || (Get<Mac::Mac>().GetPanChannel() != channel) ||
+                         (Get<Mac::Mac>().GetPanId() != panId),
+                     OT_NOOP);
 
         if (mAttachState == kAttachStateProcessAnnounce)
         {
-            VerifyOrExit(mAlternateTimestamp < timestamp.GetSeconds());
+            VerifyOrExit(mAlternateTimestamp < timestamp.GetSeconds(), OT_NOOP);
         }
 
         mAlternateTimestamp = timestamp.GetSeconds();
@@ -3761,8 +3754,6 @@
     {
         otLogWarnMle("Failed to process Announce: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
 void Mle::ProcessAnnounce(void)
@@ -3770,7 +3761,7 @@
     uint8_t  newChannel = mAlternateChannel;
     uint16_t newPanId   = mAlternatePanId;
 
-    assert(mAttachState == kAttachStateProcessAnnounce);
+    OT_ASSERT(mAttachState == kAttachStateProcessAnnounce);
 
     otLogNoteMle("Processing Announce - channel %d, panid 0x%02x", newChannel, newPanId);
 
@@ -3781,117 +3772,15 @@
     mAlternatePanId     = Get<Mac::Mac>().GetPanId();
     mAlternateTimestamp = 0;
 
-    Get<Mac::Mac>().SetPanChannel(newChannel);
+    IgnoreError(Get<Mac::Mac>().SetPanChannel(newChannel));
     Get<Mac::Mac>().SetPanId(newPanId);
 
-    Start(/* aAnnounceAttach */ true);
-}
-
-otError Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
-    otError                       error    = OT_ERROR_NONE;
-    const otThreadLinkInfo *      linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
-    Tlv                           tlv;
-    MeshCoP::Tlv                  meshcopTlv;
-    MeshCoP::DiscoveryResponseTlv discoveryResponse;
-    MeshCoP::ExtendedPanIdTlv     extPanId;
-    MeshCoP::NetworkNameTlv       networkName;
-    MeshCoP::SteeringDataTlv      steeringData;
-    MeshCoP::JoinerUdpPortTlv     JoinerUdpPort;
-    otActiveScanResult            result;
-    uint16_t                      offset;
-    uint16_t                      end;
-    bool                          didCheckSteeringData = false;
-
-    LogMleMessage("Receive Discovery Response", aMessageInfo.GetPeerAddr());
-
-    VerifyOrExit(mDiscoverInProgress, error = OT_ERROR_DROP);
-
-    // find MLE Discovery TLV
-    VerifyOrExit(Tlv::GetOffset(aMessage, Tlv::kDiscovery, offset) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
-    aMessage.Read(offset, sizeof(tlv), &tlv);
-
-    offset += sizeof(tlv);
-    end = offset + tlv.GetLength();
-
-    memset(&result, 0, sizeof(result));
-    result.mPanId   = linkInfo->mPanId;
-    result.mChannel = linkInfo->mChannel;
-    result.mRssi    = linkInfo->mRss;
-    result.mLqi     = linkInfo->mLqi;
-    aMessageInfo.GetPeerAddr().ToExtAddress(*static_cast<Mac::ExtAddress *>(&result.mExtAddress));
-
-    // process MeshCoP TLVs
-    while (offset < end)
-    {
-        aMessage.Read(offset, sizeof(meshcopTlv), &meshcopTlv);
-
-        switch (meshcopTlv.GetType())
-        {
-        case MeshCoP::Tlv::kDiscoveryResponse:
-            aMessage.Read(offset, sizeof(discoveryResponse), &discoveryResponse);
-            VerifyOrExit(discoveryResponse.IsValid(), error = OT_ERROR_PARSE);
-            result.mVersion  = discoveryResponse.GetVersion();
-            result.mIsNative = discoveryResponse.IsNativeCommissioner();
-            break;
-
-        case MeshCoP::Tlv::kExtendedPanId:
-            aMessage.Read(offset, sizeof(extPanId), &extPanId);
-            VerifyOrExit(extPanId.IsValid(), error = OT_ERROR_PARSE);
-            result.mExtendedPanId = extPanId.GetExtendedPanId();
-            break;
-
-        case MeshCoP::Tlv::kNetworkName:
-            aMessage.Read(offset, sizeof(networkName), &networkName);
-            static_cast<Mac::NetworkName &>(result.mNetworkName).Set(networkName.GetNetworkName());
-            break;
-
-        case MeshCoP::Tlv::kSteeringData:
-            aMessage.Read(offset, sizeof(steeringData), &steeringData);
-            VerifyOrExit(steeringData.IsValid(), error = OT_ERROR_PARSE);
-
-            if (mDiscoverEnableFiltering)
-            {
-                VerifyOrExit((steeringData.GetBit(mDiscoverCcittIndex % steeringData.GetNumBits()) &&
-                              steeringData.GetBit(mDiscoverAnsiIndex % steeringData.GetNumBits())));
-            }
-
-            didCheckSteeringData         = true;
-            result.mSteeringData.mLength = steeringData.GetSteeringDataLength();
-            memcpy(result.mSteeringData.m8, steeringData.GetValue(), result.mSteeringData.mLength);
-
-            break;
-
-        case MeshCoP::Tlv::kJoinerUdpPort:
-            aMessage.Read(offset, sizeof(JoinerUdpPort), &JoinerUdpPort);
-            VerifyOrExit(JoinerUdpPort.IsValid(), error = OT_ERROR_PARSE);
-            result.mJoinerUdpPort = JoinerUdpPort.GetUdpPort();
-            break;
-
-        default:
-            break;
-        }
-
-        offset += sizeof(meshcopTlv) + meshcopTlv.GetLength();
-    }
-
-    VerifyOrExit(!mDiscoverEnableFiltering || didCheckSteeringData);
-
-    mDiscoverHandler(&result, mDiscoverContext);
-
-exit:
-
-    if (error != OT_ERROR_NONE)
-    {
-        otLogWarnMle("Failed to process Discovery Response: %s", otThreadErrorToString(error));
-    }
-
-    return error;
+    IgnoreError(Start(/* aAnnounceAttach */ true));
 }
 
 Neighbor *Mle::GetNeighbor(uint16_t aAddress)
 {
-    Neighbor *rval = NULL;
+    Neighbor *rval = nullptr;
 
     if (mParent.IsStateValidOrRestoring() && (mParent.GetRloc16() == aAddress))
     {
@@ -3907,7 +3796,7 @@
 
 Neighbor *Mle::GetNeighbor(const Mac::ExtAddress &aAddress)
 {
-    Neighbor *rval = NULL;
+    Neighbor *rval = nullptr;
 
     if (mParent.IsStateValidOrRestoring() && (mParent.GetExtAddress() == aAddress))
     {
@@ -3923,7 +3812,7 @@
 
 Neighbor *Mle::GetNeighbor(const Mac::Address &aAddress)
 {
-    Neighbor *neighbor = NULL;
+    Neighbor *neighbor = nullptr;
 
     switch (aAddress.GetType())
     {
@@ -3950,64 +3839,53 @@
 
 bool Mle::IsRoutingLocator(const Ip6::Address &aAddress) const
 {
-    return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0 &&
-           aAddress.mFields.m8[14] < Ip6::Address::kAloc16Mask &&
-           (aAddress.mFields.m8[14] & Ip6::Address::kRloc16ReservedBitMask) == 0;
+    return IsMeshLocalAddress(aAddress) && aAddress.GetIid().IsRoutingLocator();
 }
 
 bool Mle::IsAnycastLocator(const Ip6::Address &aAddress) const
 {
-    return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0 &&
-           aAddress.mFields.m8[14] == Ip6::Address::kAloc16Mask;
+    return IsMeshLocalAddress(aAddress) && aAddress.GetIid().IsAnycastLocator();
 }
 
 bool Mle::IsMeshLocalAddress(const Ip6::Address &aAddress) const
 {
-    return aAddress.PrefixMatch(GetMeshLocal16()) >= Ip6::Address::kMeshLocalPrefixLength;
+    return (aAddress.GetPrefix() == GetMeshLocalPrefix());
 }
 
-otError Mle::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header)
+otError Mle::CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header)
 {
-    otError          error = OT_ERROR_DROP;
-    Ip6::MessageInfo messageInfo;
+    otError error;
 
-    if (aMeshDest != GetRloc16())
+    if ((aMeshDest != GetRloc16()) || Get<ThreadNetif>().HasUnicastAddress(aIp6Header.GetDestination()))
     {
-        ExitNow(error = OT_ERROR_NONE);
+        error = OT_ERROR_NONE;
+    }
+    else
+    {
+        error = OT_ERROR_NO_ROUTE;
     }
 
-    if (Get<ThreadNetif>().IsUnicastAddress(aIp6Header.GetDestination()))
-    {
-        ExitNow(error = OT_ERROR_NONE);
-    }
-
-    messageInfo.GetPeerAddr()                = GetMeshLocal16();
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aMeshSource);
-
-    Get<Ip6::Icmp>().SendError(Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo,
-                               aIp6Header);
-
-exit:
     return error;
 }
 
 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
-otError Mle::InformPreviousParent(void)
+void Mle::InformPreviousParent(void)
 {
     otError          error   = OT_ERROR_NONE;
-    Message *        message = NULL;
+    Message *        message = nullptr;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((mPreviousParentRloc != Mac::kShortAddrInvalid) && (mPreviousParentRloc != mParent.GetRloc16()));
+    VerifyOrExit((mPreviousParentRloc != Mac::kShortAddrInvalid) && (mPreviousParentRloc != mParent.GetRloc16()),
+                 OT_NOOP);
 
     mCounters.mParentChanges++;
 
-    VerifyOrExit((message = Get<Ip6::Ip6>().NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Ip6::Ip6>().NewMessage(0)) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = message->SetLength(0));
 
     messageInfo.SetSockAddr(GetMeshLocal64());
     messageInfo.SetPeerAddr(GetMeshLocal16());
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(mPreviousParentRloc);
+    messageInfo.GetPeerAddr().GetIid().SetLocator(mPreviousParentRloc);
 
     SuccessOrExit(error = Get<Ip6::Ip6>().SendDatagram(*message, messageInfo, Ip6::kProtoNone));
 
@@ -4019,13 +3897,11 @@
     {
         otLogWarnMle("Failed to inform previous parent: %s", otThreadErrorToString(error));
 
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
     }
-
-    return error;
 }
 #endif // OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
 
@@ -4056,18 +3932,18 @@
 
     mParentSearchIsInBackoff = false;
 
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_CHILD);
+    VerifyOrExit(IsChild(), OT_NOOP);
 
     parentRss = GetParent().GetLinkInfo().GetAverageRss();
     otLogInfoMle("PeriodicParentSearch: Parent RSS %d", parentRss);
-    VerifyOrExit(parentRss != OT_RADIO_RSSI_INVALID);
+    VerifyOrExit(parentRss != OT_RADIO_RSSI_INVALID, OT_NOOP);
 
     if (parentRss < kParentSearchRssThreadhold)
     {
         otLogInfoMle("PeriodicParentSearch: Parent RSS less than %d, searching for new parents",
                      kParentSearchRssThreadhold);
         mParentSearchIsInBackoff = true;
-        BecomeChild(kAttachAny);
+        IgnoreError(BecomeChild(kAttachAny));
     }
 
 exit:
@@ -4153,29 +4029,29 @@
     otLogInfoMle("%s (%s,0x%04x)", aLogString, aAddress.ToString().AsCString(), aRloc);
 }
 
-const char *Mle::RoleToString(otDeviceRole aRole)
+const char *Mle::RoleToString(DeviceRole aRole)
 {
     const char *roleString = "Unknown";
 
     switch (aRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
+    case kRoleDisabled:
         roleString = "Disabled";
         break;
 
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDetached:
         roleString = "Detached";
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         roleString = "Child";
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
+    case kRoleRouter:
         roleString = "Router";
         break;
 
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleLeader:
         roleString = "Leader";
         break;
     }
@@ -4291,5 +4167,31 @@
     mParentResponseCbContext = aContext;
 }
 
+void Mle::Challenge::GenerateRandom(void)
+{
+    mLength = kMaxChallengeSize;
+    IgnoreError(Random::Crypto::FillBuffer(mBuffer, mLength));
+}
+
+bool Mle::Challenge::Matches(const uint8_t *aBuffer, uint8_t aLength) const
+{
+    return (mLength == aLength) && (memcmp(mBuffer, aBuffer, aLength) == 0);
+}
+
+void Mle::DelayedResponseMetadata::ReadFrom(const Message &aMessage)
+{
+    uint16_t length = aMessage.GetLength();
+
+    OT_ASSERT(length >= sizeof(*this));
+    aMessage.Read(length - sizeof(*this), sizeof(*this), this);
+}
+
+void Mle::DelayedResponseMetadata::RemoveFrom(Message &aMessage) const
+{
+    otError error = aMessage.SetLength(aMessage.GetLength() - sizeof(*this));
+    OT_ASSERT(error == OT_ERROR_NONE);
+    OT_UNUSED_VARIABLE(error);
+}
+
 } // namespace Mle
 } // namespace ot
diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp
index 5dc4323..efa4bb1 100644
--- a/src/core/thread/mle.hpp
+++ b/src/core/thread/mle.hpp
@@ -41,10 +41,10 @@
 #include "common/timer.hpp"
 #include "mac/mac.hpp"
 #include "meshcop/joiner_router.hpp"
+#include "meshcop/meshcop.hpp"
 #include "net/udp6.hpp"
-#include "thread/device_mode.hpp"
-#include "thread/mle_constants.hpp"
 #include "thread/mle_tlvs.hpp"
+#include "thread/mle_types.hpp"
 #include "thread/topology.hpp"
 
 namespace ot {
@@ -84,48 +84,6 @@
  */
 
 /**
- * MLE Attach modes
- *
- */
-enum AttachMode
-{
-    kAttachAny           = 0, ///< Attach to any Thread partition.
-    kAttachSame1         = 1, ///< Attach to the same Thread partition (attempt 1 when losing connectivity).
-    kAttachSame2         = 2, ///< Attach to the same Thread partition (attempt 2 when losing connectivity).
-    kAttachBetter        = 3, ///< Attach to a better (i.e. higher weight/partition id) Thread partition.
-    kAttachSameDowngrade = 4, ///< Attach to the same Thread partition during downgrade process.
-};
-
-/**
- * This enumeration represents the allocation of the ALOC Space
- *
- */
-enum AlocAllocation
-{
-    kAloc16Leader                      = 0xfc00,
-    kAloc16DhcpAgentStart              = 0xfc01,
-    kAloc16DhcpAgentEnd                = 0xfc0f,
-    kAloc16DhcpAgentMask               = 0x000f,
-    kAloc16ServiceStart                = 0xfc10,
-    kAloc16ServiceEnd                  = 0xfc2f,
-    kAloc16CommissionerStart           = 0xfc30,
-    kAloc16CommissionerEnd             = 0xfc37,
-    kAloc16CommissionerMask            = 0x0007,
-    kAloc16NeighborDiscoveryAgentStart = 0xfc40,
-    kAloc16NeighborDiscoveryAgentEnd   = 0xfc4e,
-};
-
-/**
- * Service IDs
- *
- */
-enum ServiceID
-{
-    kServiceMinId = 0x00, ///< Minimal Service ID.
-    kServiceMaxId = 0x0f, ///< Maximal Service ID.
-};
-
-/**
  * This class implements MLE Header generation and parsing.
  *
  */
@@ -134,6 +92,43 @@
 {
 public:
     /**
+     * MLE Command Types.
+     *
+     */
+    enum Command
+    {
+        kCommandLinkRequest          = 0,  ///< Link Request
+        kCommandLinkAccept           = 1,  ///< Link Accept
+        kCommandLinkAcceptAndRequest = 2,  ///< Link Accept and Reject
+        kCommandLinkReject           = 3,  ///< Link Reject
+        kCommandAdvertisement        = 4,  ///< Advertisement
+        kCommandUpdate               = 5,  ///< Update
+        kCommandUpdateRequest        = 6,  ///< Update Request
+        kCommandDataRequest          = 7,  ///< Data Request
+        kCommandDataResponse         = 8,  ///< Data Response
+        kCommandParentRequest        = 9,  ///< Parent Request
+        kCommandParentResponse       = 10, ///< Parent Response
+        kCommandChildIdRequest       = 11, ///< Child ID Request
+        kCommandChildIdResponse      = 12, ///< Child ID Response
+        kCommandChildUpdateRequest   = 13, ///< Child Update Request
+        kCommandChildUpdateResponse  = 14, ///< Child Update Response
+        kCommandAnnounce             = 15, ///< Announce
+        kCommandDiscoveryRequest     = 16, ///< Discovery Request
+        kCommandDiscoveryResponse    = 17, ///< Discovery Response
+        kCommandTimeSync             = 99, ///< Time Sync (applicable when OPENTHREAD_CONFIG_TIME_SYNC_ENABLE enabled)
+    };
+
+    /**
+     * MLE Security Suite
+     *
+     */
+    enum SecuritySuite
+    {
+        k154Security = 0,   ///< IEEE 802.15.4-2006 security.
+        kNoSecurity  = 255, ///< No security enabled.
+    };
+
+    /**
      * This method initializes the MLE header.
      *
      */
@@ -165,22 +160,12 @@
      */
     uint8_t GetLength(void) const
     {
-        uint8_t rval = sizeof(mSecuritySuite) + sizeof(mCommand);
-
-        if (mSecuritySuite == k154Security)
-        {
-            rval += sizeof(mSecurityControl) + sizeof(mFrameCounter) + sizeof(mKeySource) + sizeof(mKeyIndex);
-        }
-
-        return rval;
+        return sizeof(mSecuritySuite) + sizeof(mCommand) +
+               ((mSecuritySuite == k154Security)
+                    ? sizeof(mSecurityControl) + sizeof(mFrameCounter) + sizeof(mKeySource) + sizeof(mKeyIndex)
+                    : 0);
     }
 
-    enum SecuritySuite
-    {
-        k154Security = 0,   ///< IEEE 802.15.4-2006 security.
-        kNoSecurity  = 255, ///< No security enabled.
-    };
-
     /**
      * This method returns the Security Suite value.
      *
@@ -279,39 +264,6 @@
     void SetFrameCounter(uint32_t aFrameCounter) { mFrameCounter = Encoding::LittleEndian::HostSwap32(aFrameCounter); }
 
     /**
-     * MLE Command Types.
-     *
-     */
-    enum Command
-    {
-        kCommandLinkRequest          = 0,  ///< Link Reject
-        kCommandLinkAccept           = 1,  ///< Link Accept
-        kCommandLinkAcceptAndRequest = 2,  ///< Link Accept and Reject
-        kCommandLinkReject           = 3,  ///< Link Reject
-        kCommandAdvertisement        = 4,  ///< Advertisement
-        kCommandUpdate               = 5,  ///< Update
-        kCommandUpdateRequest        = 6,  ///< Update Request
-        kCommandDataRequest          = 7,  ///< Data Request
-        kCommandDataResponse         = 8,  ///< Data Response
-        kCommandParentRequest        = 9,  ///< Parent Request
-        kCommandParentResponse       = 10, ///< Parent Response
-        kCommandChildIdRequest       = 11, ///< Child ID Request
-        kCommandChildIdResponse      = 12, ///< Child ID Response
-        kCommandChildUpdateRequest   = 13, ///< Child Update Request
-        kCommandChildUpdateResponse  = 14, ///< Child Update Response
-        kCommandAnnounce             = 15, ///< Announce
-        kCommandDiscoveryRequest     = 16, ///< Discovery Request
-        kCommandDiscoveryResponse    = 17, ///< Discovery Response
-
-        /**
-         * Applicable/Required only when time synchronization service
-         * (`OPENTHREAD_CONFIG_TIME_SYNC_ENABLE`) is enabled.
-         *
-         */
-        kCommandTimeSync = 99, ///< Time Synchronization
-    };
-
-    /**
      * This method returns the Command Type value.
      *
      * @returns The Command Type value.
@@ -319,14 +271,7 @@
      */
     Command GetCommand(void) const
     {
-        if (mSecuritySuite == kNoSecurity)
-        {
-            return static_cast<Command>(mSecurityControl);
-        }
-        else
-        {
-            return static_cast<Command>(mCommand);
-        }
+        return static_cast<Command>((mSecuritySuite == kNoSecurity) ? mSecurityControl : mCommand);
     }
 
     /**
@@ -357,100 +302,13 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements functionality required for delaying MLE responses.
- *
- */
-class DelayedResponseHeader
-{
-public:
-    /**
-     * Default constructor for the object.
-     *
-     */
-    DelayedResponseHeader(void)
-        : mDestination()
-        , mSendTime(0)
-    {
-        mDestination.Clear();
-    }
-
-    /**
-     * This constructor initializes the object with specific values.
-     *
-     * @param[in]  aSendTime     Time when the message shall be sent.
-     * @param[in]  aDestination  IPv6 address of the message destination.
-     *
-     */
-    DelayedResponseHeader(TimeMilli aSendTime, const Ip6::Address &aDestination)
-        : mDestination(aDestination)
-        , mSendTime(aSendTime)
-    {
-    }
-
-    /**
-     * This method appends delayed response header to the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     * @retval OT_ERROR_NONE     Successfully appended the bytes.
-     * @retval OT_ERROR_NO_BUFS  Insufficient available buffers to grow the message.
-     *
-     */
-    otError AppendTo(Message &aMessage) { return aMessage.Append(this, sizeof(*this)); }
-
-    /**
-     * This method reads delayed response header from the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     */
-    void ReadFrom(const Message &aMessage)
-    {
-        uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
-        assert(length == sizeof(*this));
-        OT_UNUSED_VARIABLE(length);
-    }
-
-    /**
-     * This method removes delayed response header from the message.
-     *
-     * @param[in]  aMessage  A reference to the message.
-     *
-     */
-    static void RemoveFrom(Message &aMessage)
-    {
-        otError error = aMessage.SetLength(aMessage.GetLength() - sizeof(DelayedResponseHeader));
-        assert(error == OT_ERROR_NONE);
-        OT_UNUSED_VARIABLE(error);
-    }
-
-    /**
-     * This method returns a time when the message shall be sent.
-     *
-     * @returns  A time when the message shall be sent.
-     *
-     */
-    TimeMilli GetSendTime(void) const { return mSendTime; }
-
-    /**
-     * This method returns a destination of the delayed message.
-     *
-     * @returns  A destination of the delayed message.
-     *
-     */
-    const Ip6::Address &GetDestination(void) const { return mDestination; }
-
-private:
-    Ip6::Address mDestination; ///< IPv6 address of the message destination.
-    TimeMilli    mSendTime;    ///< Time when the message shall be sent.
-};
-
-/**
  * This class implements MLE functionality required by the Thread EndDevices, Router, and Leader roles.
  *
  */
-class Mle : public InstanceLocator
+class Mle : public InstanceLocator, public Notifier::Receiver
 {
+    friend class DiscoverScanner;
+
 public:
     /**
      * This constructor initializes the MLE object.
@@ -516,61 +374,13 @@
     otError Store(void);
 
     /**
-     * This function pointer is called on receiving an MLE Discovery Response message.
-     *
-     * @param[in]  aResult   A valid pointer to the Discovery Response information or NULL when the Discovery completes.
-     * @param[in]  aContext  A pointer to application-specific context.
-     *
-     */
-    typedef void (*DiscoverHandler)(otActiveScanResult *aResult, void *aContext);
-
-    /**
-     * This method initiates a Thread Discovery.
-     *
-     * @param[in]  aScanChannels          A bit vector indicating which channels to scan.
-     * @param[in]  aPanId                 The PAN ID filter (set to Broadcast PAN to disable filter).
-     * @param[in]  aJoiner                Value of the Joiner Flag in the Discovery Request TLV.
-     * @param[in]  aEnableFiltering       Enable filtering out MLE discovery responses that don't match our factory
-     *                                    assigned EUI64.
-     * @param[in]  aHandler               A pointer to a function that is called on receiving an MLE Discovery Response.
-     * @param[in]  aContext               A pointer to arbitrary context information.
-     *
-     * @retval OT_ERROR_NONE  Successfully started a Thread Discovery.
-     * @retval OT_ERROR_BUSY  Thread Discovery is already in progress.
-     *
-     */
-    otError Discover(const Mac::ChannelMask &aScanChannels,
-                     uint16_t                aPanId,
-                     bool                    aJoiner,
-                     bool                    aEnableFiltering,
-                     DiscoverHandler         aCallback,
-                     void *                  aContext);
-
-    /**
-     * This method indicates whether or not an MLE Thread Discovery is currently in progress.
-     *
-     * @returns true if an MLE Thread Discovery is in progress, false otherwise.
-     *
-     */
-    bool IsDiscoverInProgress(void) const { return mDiscoverInProgress; }
-
-    /**
-     * This method is called by the MeshForwarder to indicate that discovery is complete.
-     *
-     */
-    void HandleDiscoverComplete(void);
-
-    /**
      * This method generates an MLE Announce message.
      *
      * @param[in]  aChannel        The channel to use when transmitting.
      * @param[in]  aOrphanAnnounce To indicate if MLE Announce is sent from an orphan end device.
      *
-     * @retval OT_ERROR_NONE     Successfully generated an MLE Announce message.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffers to generate the MLE Announce message.
-     *
      */
-    otError SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce);
+    void SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce);
 
     /**
      * This method causes the Thread interface to detach from the Thread network.
@@ -616,12 +426,66 @@
     bool IsAttaching(void) const { return (mAttachState != kAttachStateIdle); }
 
     /**
-     * This method returns the current Thread interface state.
+     * This method returns the current Thread device role.
      *
-     * @returns The current Thread interface state.
+     * @returns The current Thread device role.
      *
      */
-    otDeviceRole GetRole(void) const { return mRole; }
+    DeviceRole GetRole(void) const { return mRole; }
+
+    /**
+     * This method indicates whether device role is disabled.
+     *
+     * @retval TRUE   Device role is disabled.
+     * @retval FALSE  Device role is not disabled.
+     *
+     */
+    bool IsDisabled(void) const { return (mRole == kRoleDisabled); }
+
+    /**
+     * This method indicates whether device role is detached.
+     *
+     * @retval TRUE   Device role is detached.
+     * @retval FALSE  Device role is not detached.
+     *
+     */
+    bool IsDetached(void) const { return (mRole == kRoleDetached); }
+
+    /**
+     * This method indicates whether device role is child.
+     *
+     * @retval TRUE   Device role is child.
+     * @retval FALSE  Device role is not child.
+     *
+     */
+    bool IsChild(void) const { return (mRole == kRoleChild); }
+
+    /**
+     * This method indicates whether device role is router.
+     *
+     * @retval TRUE   Device role is router.
+     * @retval FALSE  Device role is not router.
+     *
+     */
+    bool IsRouter(void) const { return (mRole == kRoleRouter); }
+
+    /**
+     * This method indicates whether device role is leader.
+     *
+     * @retval TRUE   Device role is leader.
+     * @retval FALSE  Device role is not leader.
+     *
+     */
+    bool IsLeader(void) const { return (mRole == kRoleLeader); }
+
+    /**
+     * This method indicates whether device role is either router or leader.
+     *
+     * @retval TRUE   Device role is either router or leader.
+     * @retval FALSE  Device role is neither router nor leader.
+     *
+     */
+    bool IsRouterOrLeader(void) const;
 
     /**
      * This method returns the Device Mode as reported in the Mode TLV.
@@ -688,9 +552,9 @@
      * @returns A reference to the Mesh Local Prefix.
      *
      */
-    const otMeshLocalPrefix &GetMeshLocalPrefix(void) const
+    const MeshLocalPrefix &GetMeshLocalPrefix(void) const
     {
-        return reinterpret_cast<const otMeshLocalPrefix &>(mMeshLocal16.GetAddress());
+        return static_cast<const MeshLocalPrefix &>(mMeshLocal16.GetAddress().GetPrefix());
     }
 
     /**
@@ -699,13 +563,11 @@
      * @param[in]  aMeshLocalPrefix  A reference to the Mesh Local Prefix.
      *
      */
-    void SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix);
+    void SetMeshLocalPrefix(const MeshLocalPrefix &aMeshLocalPrefix);
 
     /**
      * This method applies the Mesh Local Prefix.
      *
-     * @param[in]  aPrefix  A reference to the Mesh Local Prefix.
-     *
      */
     void ApplyMeshLocalPrefix(void);
 
@@ -857,7 +719,7 @@
      * @retval OT_ERROR_DETACHED  The Thread interface is not currently attached to a Thread Partition.
      *
      */
-    otError GetLeaderAloc(Ip6::Address &aAddress) const { return GetAlocAddress(aAddress, kAloc16Leader); }
+    otError GetLeaderAloc(Ip6::Address &aAddress) const { return GetLocatorAddress(aAddress, kAloc16Leader); }
 
     /**
      * This method computes the Commissioner's ALOC.
@@ -871,13 +733,13 @@
      */
     otError GetCommissionerAloc(Ip6::Address &aAddress, uint16_t aSessionId) const
     {
-        return GetAlocAddress(aAddress, CommissionerAloc16FromId(aSessionId));
+        return GetLocatorAddress(aAddress, CommissionerAloc16FromId(aSessionId));
     }
 
     /**
      * This method retrieves the Service ALOC for given Service ID.
      *
-     * @param[in]   aServiceID Service ID to get ALOC for.
+     * @param[in]   aServiceId Service ID to get ALOC for.
      * @param[out]  aAddress   A reference to the Service ALOC.
      *
      * @retval OT_ERROR_NONE      Successfully retrieved the Service ALOC.
@@ -887,33 +749,12 @@
     otError GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const;
 
     /**
-     * This method adds Leader's ALOC to its Thread interface.
+     * This method returns the most recently received Leader Data.
      *
-     * @retval OT_ERROR_NONE            Successfully added the Leader's ALOC.
-     * @retval OT_ERROR_BUSY            The Leader's ALOC address was already added.
-     * @retval OT_ERROR_INVALID_STATE   The device's role is not Leader.
+     * @returns  A reference to the most recently received Leader Data.
      *
      */
-    otError AddLeaderAloc(void);
-
-    /**
-     * This method returns the most recently received Leader Data TLV.
-     *
-     * @returns  A reference to the most recently received Leader Data TLV.
-     *
-     */
-    const LeaderDataTlv &GetLeaderDataTlv(void);
-
-    /**
-     * This method gets the Leader Data.
-     *
-     * @param[out]  aLeaderData  A reference to where the leader data is placed.
-     *
-     * @retval OT_ERROR_NONE         Successfully retrieved the leader data.
-     * @retval OT_ERROR_DETACHED     Not currently attached.
-     *
-     */
-    otError GetLeaderData(otLeaderData &aLeaderData);
+    const LeaderData &GetLeaderData(void);
 
     /**
      * This method derives the Child ID from a given RLOC16.
@@ -1010,15 +851,6 @@
     static bool IsActiveRouter(uint16_t aRloc16) { return ChildIdFromRloc16(aRloc16) == 0; }
 
     /**
-     * This method fills the NetworkDataTlv.
-     *
-     * @param[out] aTlv         The NetworkDataTlv.
-     * @param[in]  aStableOnly  TRUE to append stable data, FALSE otherwise.
-     *
-     */
-    void FillNetworkDataTlv(NetworkDataTlv &aTlv, bool aStableOnly);
-
-    /**
      * This method returns a reference to the send queue.
      *
      * @returns A reference to the send queue.
@@ -1036,7 +868,7 @@
      * This method converts a device role into a human-readable string.
      *
      */
-    static const char *RoleToString(otDeviceRole aRole);
+    static const char *RoleToString(DeviceRole aRole);
 
     /**
      * This method gets the MLE counters.
@@ -1071,6 +903,18 @@
      */
     void RequestShorterChildIdRequest(void);
 
+    /**
+     * This method gets the RLOC or ALOC of a given RLOC16 or ALOC16.
+     *
+     * @param[out]  aAddress  A reference to the RLOC or ALOC.
+     * @param[in]   aLocator  RLOC16 or ALOC16.
+     *
+     * @retval OT_ERROR_NONE      If got the RLOC or ALOC successfully.
+     * @retval OT_ERROR_DETACHED  If device is detached.
+     *
+     */
+    otError GetLocatorAddress(Ip6::Address &aAddress, uint16_t aLocator) const;
+
 protected:
     /**
      * States during attach (when searching for a parent).
@@ -1116,9 +960,63 @@
     };
 
     /**
+     * This type represents a Challenge (or Response) data.
+     *
+     */
+    struct Challenge
+    {
+        uint8_t mBuffer[kMaxChallengeSize]; ///< Buffer containing the challenge/response byte sequence.
+        uint8_t mLength;                    ///< Challenge length (in bytes).
+
+        /**
+         * This method generates a cryptographically secure random sequence to populate the challenge data.
+         *
+         */
+        void GenerateRandom(void);
+
+        /**
+         * This method indicates whether the Challenge matches a given buffer.
+         *
+         * @param[in] aBuffer   A pointer to a buffer to compare with the Challenge.
+         * @param[in] aLength   Length of @p aBuffer (in bytes).
+         *
+         * @retval TRUE  If the Challenge matches the given buffer.
+         * @retval FALSE If the Challenge does not match the given buffer.
+         *
+         */
+        bool Matches(const uint8_t *aBuffer, uint8_t aLength) const;
+
+        /**
+         * This method indicates whether two Challenge data byte sequences are equal or not.
+         *
+         * @param[in] aOther   Another Challenge data to compare.
+         *
+         * @retval TRUE  If the two Challenges match.
+         * @retval FALSE If the two Challenges do not match.
+         *
+         */
+        bool operator==(const Challenge &aOther) const { return Matches(aOther.mBuffer, aOther.mLength); }
+    };
+
+    /**
+     * This type represents list of requested TLVs in a TLV Request TLV.
+     *
+     */
+    struct RequestedTlvs
+    {
+        enum
+        {
+            kMaxNumTlvs = 16, ///< Maximum number of TLVs in request array.
+        };
+
+        uint8_t mTlvs[kMaxNumTlvs]; ///< Array of requested TLVs.
+        uint8_t mNumTlvs;           ///< Number of TLVs in the array.
+    };
+
+    /**
      * This method allocates a new message buffer for preparing an MLE message.
      *
-     * @returns A pointer to the message or NULL if insufficient message buffers are available.
+     * @returns A pointer to the message or nullptr if insufficient message buffers are available.
      *
      */
     Message *NewMleMessage(void);
@@ -1129,7 +1027,7 @@
      * @param[in] aRole A device role.
      *
      */
-    void SetRole(otDeviceRole aRole);
+    void SetRole(DeviceRole aRole);
 
     /**
      * This method sets the attach state
@@ -1200,17 +1098,54 @@
     otError AppendChallenge(Message &aMessage, const uint8_t *aChallenge, uint8_t aChallengeLength);
 
     /**
+     * This method appends a Challenge TLV to a message.
+     *
+     * @param[in]  aMessage          A reference to the message.
+     * @param[in]  aChallenge        A reference to the Challenge data.
+     *
+     * @retval OT_ERROR_NONE     Successfully appended the Challenge TLV.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffers available to append the Challenge TLV.
+     *
+     */
+    otError AppendChallenge(Message &aMessage, const Challenge &aChallenge);
+
+    /**
+     * This method reads Challenge TLV from a message.
+     *
+     * @param[in]  aMessage          A reference to the message.
+     * @param[out] aChallenge        A reference to the Challenge data where to output the read value.
+     *
+     * @retval OT_ERROR_NONE       Successfully read the Challenge TLV.
+     * @retval OT_ERROR_NOT_FOUND  Challenge TLV was not found in the message.
+     * @retval OT_ERROR_PARSE      Challenge TLV was found but could not be parsed.
+     *
+     */
+    otError ReadChallenge(const Message &aMessage, Challenge &aChallenge);
+
+    /**
      * This method appends a Response TLV to a message.
      *
      * @param[in]  aMessage         A reference to the message.
-     * @param[in]  aResponse        A pointer to the Response value.
-     * @param[in]  aResponseLength  The length of the Response value in bytes.
+     * @param[in]  aResponse        A reference to the Response data.
      *
      * @retval OT_ERROR_NONE     Successfully appended the Response TLV.
      * @retval OT_ERROR_NO_BUFS  Insufficient buffers available to append the Response TLV.
      *
      */
-    otError AppendResponse(Message &aMessage, const uint8_t *aResponse, uint8_t aResponseLength);
+    otError AppendResponse(Message &aMessage, const Challenge &aResponse);
+
+    /**
+     * This method reads Response TLV from a message.
+     *
+     * @param[in]  aMessage         A reference to the message.
+     * @param[out] aResponse        A reference to the Response data where to output the read value.
+     *
+     * @retval OT_ERROR_NONE       Successfully read the Response TLV.
+     * @retval OT_ERROR_NOT_FOUND  Response TLV was not found in the message.
+     * @retval OT_ERROR_PARSE      Response TLV was found but could not be parsed.
+     *
+     */
+    otError ReadResponse(const Message &aMessage, Challenge &aResponse);
 
     /**
      * This method appends a Link Frame Counter TLV to a message.
@@ -1272,6 +1207,19 @@
     otError AppendTlvRequest(Message &aMessage, const uint8_t *aTlvs, uint8_t aTlvsLength);
 
     /**
+     * This method reads TLV Request TLV from a message.
+     *
+     * @param[in]  aMessage         A reference to the message.
+     * @param[out] aRequestedTlvs   A reference to output the read list of requested TLVs.
+     *
+     * @retval OT_ERROR_NONE       Successfully read the TLV.
+     * @retval OT_ERROR_NOT_FOUND  TLV was not found in the message.
+     * @retval OT_ERROR_PARSE      TLV was found but could not be parsed.
+     *
+     */
+    otError FindTlvRequest(const Message &aMessage, RequestedTlvs &aRequestedTlvs);
+
+    /**
      * This method appends a Leader Data TLV to a message.
      *
      * @param[in]  aMessage  A reference to the message.
@@ -1283,6 +1231,19 @@
     otError AppendLeaderData(Message &aMessage);
 
     /**
+     * This method reads Leader Data TLV from a message.
+     *
+     * @param[in]  aMessage        A reference to the message.
+     * @param[out] aLeaderData     A reference to output the Leader Data.
+     *
+     * @retval OT_ERROR_NONE       Successfully read the TLV.
+     * @retval OT_ERROR_NOT_FOUND  TLV was not found in the message.
+     * @retval OT_ERROR_PARSE      TLV was found but could not be parsed.
+     *
+     */
+    otError ReadLeaderData(const Message &aMessage, LeaderData &aLeaderData);
+
+    /**
      * This method appends a Scan Mask TLV to a message.
      *
      * @param[in]  aMessage   A reference to the message.
@@ -1401,15 +1362,14 @@
     /**
      * This method checks if the destination is reachable.
      *
-     * @param[in]  aMeshSource  The RLOC16 of the source.
-     * @param[in]  aMeshDest    The RLOC16 of the destination.
-     * @param[in]  aIp6Header   The IPv6 header of the message.
+     * @param[in]  aMeshDest   The RLOC16 of the destination.
+     * @param[in]  aIp6Header  The IPv6 header of the message.
      *
-     * @retval OT_ERROR_NONE  The destination is reachable.
-     * @retval OT_ERROR_DROP  The destination is not reachable and the message should be dropped.
+     * @retval OT_ERROR_NONE      The destination is reachable.
+     * @retval OT_ERROR_NO_ROUTE  The destination is not reachable and the message should be dropped.
      *
      */
-    otError CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header);
+    otError CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header);
 
     /**
      * This method returns a pointer to the neighbor object.
@@ -1452,7 +1412,7 @@
     Neighbor *GetNeighbor(const Ip6::Address &aAddress)
     {
         OT_UNUSED_VARIABLE(aAddress);
-        return NULL;
+        return nullptr;
     }
 
     /**
@@ -1496,13 +1456,13 @@
      *
      * @param[in]  aTlvs         A pointer to requested TLV types.
      * @param[in]  aNumTlvs      The number of TLV types in @p aTlvs.
-     * @param[in]  aChallenge    The Challenge TLV for the response.
+     * @param[in]  aChallenge    The Challenge for the response.
      *
      * @retval OT_ERROR_NONE     Successfully generated an MLE Child Update Response message.
      * @retval OT_ERROR_NO_BUFS  Insufficient buffers to generate the MLE Child Update Response message.
      *
      */
-    otError SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const ChallengeTlv &aChallenge);
+    otError SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const Challenge &aChallenge);
 
     /**
      * This method submits an MLE message to the UDP socket.
@@ -1628,10 +1588,13 @@
     static const char *ReattachStateToString(ReattachState aState);
 #endif
 
-    LeaderDataTlv mLeaderData;               ///< Last received Leader Data TLV.
+    Ip6::NetifUnicastAddress mLeaderAloc; ///< Leader anycast locator
+
+    LeaderData    mLeaderData;               ///< Last received Leader Data TLV.
     bool          mRetrieveNewNetworkData;   ///< Indicating new Network Data is needed if set.
-    otDeviceRole  mRole;                     ///< Current Thread role.
+    DeviceRole    mRole;                     ///< Current Thread role.
     Router        mParent;                   ///< Parent information.
+    Router        mParentCandidate;          ///< Parent candidate information.
     DeviceMode    mDeviceMode;               ///< Device mode setting.
     AttachState   mAttachState;              ///< The parent request state.
     ReattachState mReattachState;            ///< Reattach state
@@ -1645,8 +1608,8 @@
 private:
     enum
     {
-        kMleMessagePriority = Message::kPriorityNet,
         kMleHopLimit        = 255,
+        kMleSecurityTagSize = 4, // Security tag size in bytes.
 
         // Parameters related to "periodic parent search" feature (CONFIG_ENABLE_PERIODIC_PARENT_SEARCH).
         // All timer intervals are converted to milliseconds.
@@ -1680,8 +1643,18 @@
         kDataRequestActive, ///< Data Request has been sent, Data Response is expected.
     };
 
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags);
-    void        HandleStateChanged(otChangedFlags aFlags);
+    struct DelayedResponseMetadata
+    {
+        otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
+        void    ReadFrom(const Message &aMessage);
+        void    RemoveFrom(Message &aMessage) const;
+
+        Ip6::Address mDestination; // IPv6 address of the message destination.
+        TimeMilli    mSendTime;    // Time when the message shall be sent.
+    };
+
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
     static void HandleAttachTimer(Timer &aTimer);
     void        HandleAttachTimer(void);
     static void HandleDelayedResponseTimer(Timer &aTimer);
@@ -1691,23 +1664,19 @@
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
     void        ScheduleMessageTransmissionTimer(void);
+    otError     ReadChallengeOrResponse(const Message &aMessage, uint8_t aTlvType, Challenge &aBuffer);
 
-    otError HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor);
-    otError HandleChildIdResponse(const Message &         aMessage,
-                                  const Ip6::MessageInfo &aMessageInfo,
-                                  const Neighbor *        aNeighbor);
-    otError HandleChildUpdateRequest(const Message &         aMessage,
-                                     const Ip6::MessageInfo &aMessageInfo,
-                                     Neighbor *              aNeighbor);
-    otError HandleChildUpdateResponse(const Message &         aMessage,
-                                      const Ip6::MessageInfo &aMessageInfo,
-                                      const Neighbor *        aNeighbor);
-    otError HandleDataResponse(const Message &         aMessage,
+    void HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor);
+    void HandleChildIdResponse(const Message &         aMessage,
                                const Ip6::MessageInfo &aMessageInfo,
                                const Neighbor *        aNeighbor);
-    otError HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence);
-    otError HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-    otError HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    void HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor);
+    void HandleChildUpdateResponse(const Message &         aMessage,
+                                   const Ip6::MessageInfo &aMessageInfo,
+                                   const Neighbor *        aNeighbor);
+    void HandleDataResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor);
+    void HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence);
+    void HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
     otError HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
     void    ProcessAnnounce(void);
     bool    HasUnregisteredAddress(void);
@@ -1717,13 +1686,16 @@
     otError  SendChildIdRequest(void);
     otError  SendOrphanAnnounce(void);
     bool     PrepareAnnounceState(void);
-    otError  SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination);
+    void     SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination);
     uint32_t Reattach(void);
 
-    bool IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, uint8_t aLinkMargin, ConnectivityTlv &aConnectivityTlv);
-    bool IsNetworkDataNewer(const LeaderDataTlv &aLeaderData);
+    bool IsBetterParent(uint16_t               aRloc16,
+                        uint8_t                aLinkQuality,
+                        uint8_t                aLinkMargin,
+                        const ConnectivityTlv &aConnectivityTlv,
+                        uint8_t                aVersion);
+    bool IsNetworkDataNewer(const LeaderData &aLeaderData);
 
-    otError GetAlocAddress(Ip6::Address &aAddress, uint16_t aAloc16) const;
 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
     /**
      * This method scans for network data from the leader and updates IP addresses assigned to this
@@ -1733,7 +1705,7 @@
 #endif
 
 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
-    otError InformPreviousParent(void);
+    void InformPreviousParent(void);
 #endif
 
 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
@@ -1745,22 +1717,15 @@
 
     MessageQueue mDelayedResponses;
 
-    struct
-    {
-        uint8_t mChallenge[ChallengeTlv::kMaxSize];
-        uint8_t mChallengeLength;
-    } mChildIdRequest;
-
-    struct
-    {
-        uint8_t mChallenge[ChallengeTlv::kMaxSize];
-    } mParentRequest;
+    Challenge mParentRequestChallenge;
 
     AttachMode mParentRequestMode;
     int8_t     mParentPriority;
     uint8_t    mParentLinkQuality3;
     uint8_t    mParentLinkQuality2;
     uint8_t    mParentLinkQuality1;
+    uint16_t   mParentSedBufferSize;
+    uint8_t    mParentSedDatagramCount;
 
     uint8_t                 mChildUpdateAttempts;
     ChildUpdateRequestState mChildUpdateRequestState;
@@ -1769,22 +1734,15 @@
 
     AddressRegistrationMode mAddressRegistrationMode;
 
-    uint8_t       mParentLinkMargin;
-    bool          mParentIsSingleton;
-    bool          mReceivedResponseFromParent;
-    LeaderDataTlv mParentLeaderData;
+    uint8_t    mParentLinkMargin;
+    bool       mParentIsSingleton;
+    bool       mReceivedResponseFromParent;
+    LeaderData mParentLeaderData;
 
-    Router mParentCandidate;
+    Challenge mParentCandidateChallenge;
 
-    Ip6::UdpSocket mSocket;
-    uint32_t       mTimeout;
-
-    DiscoverHandler mDiscoverHandler;
-    void *          mDiscoverContext;
-    uint16_t        mDiscoverCcittIndex;
-    uint16_t        mDiscoverAnsiIndex;
-    bool            mDiscoverInProgress;
-    bool            mDiscoverEnableFiltering;
+    Ip6::Udp::Socket mSocket;
+    uint32_t         mTimeout;
 
 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
     uint16_t mPreviousParentRloc;
@@ -1803,10 +1761,8 @@
     uint16_t mAlternatePanId;
     uint64_t mAlternateTimestamp;
 
-    Ip6::NetifUnicastAddress mLeaderAloc;
-
 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
-    Ip6::NetifUnicastAddress mServiceAlocs[OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS];
+    Ip6::NetifUnicastAddress mServiceAlocs[kMaxServiceAlocs];
 #endif
 
     otMleCounters mCounters;
@@ -1817,8 +1773,6 @@
     Ip6::NetifMulticastAddress mLinkLocalAllThreadNodes;
     Ip6::NetifMulticastAddress mRealmLocalAllThreadNodes;
 
-    Notifier::Callback mNotifierCallback;
-
     otThreadParentResponseCallback mParentResponseCb;
     void *                         mParentResponseCbContext;
 };
diff --git a/src/core/thread/mle_constants.hpp b/src/core/thread/mle_constants.hpp
deleted file mode 100644
index 50a389c..0000000
--- a/src/core/thread/mle_constants.hpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes definitions for MLE functionality required by the Thread Child, Router, and Leader roles.
- */
-
-#ifndef MLE_CONSTANTS_HPP_
-#define MLE_CONSTANTS_HPP_
-
-#include "openthread-core-config.h"
-
-namespace ot {
-namespace Mle {
-
-/**
- * @addtogroup core-mle-core
- *
- */
-
-enum
-{
-    kMaxChildren               = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN,
-    kMaxChildKeepAliveAttempts = 4, ///< Maximum keep alive attempts before attempting to reattach to a new Parent
-    kFailedChildTransmissions  = OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS, ///< FAILED_CHILD_TRANSMISSIONS
-};
-
-/**
- * MLE Protocol Constants
- *
- */
-enum
-{
-    kThreadVersion                  = OPENTHREAD_THREAD_VERSION, ///< Thread Version
-    kUdpPort                        = 19788,                     ///< MLE UDP Port
-    kParentRequestRouterTimeout     = 750,                       ///< Router Parent Request timeout
-    kParentRequestDuplicateMargin   = 50,                        ///< Margin for duplicate parent request
-    kParentRequestReedTimeout       = 1250,                      ///< Router and REEDs Parent Request timeout
-    kAttachStartJitter              = 50,                        ///< Maximum jitter time added to start of attach.
-    kAnnounceProcessTimeout         = 250,  ///< Timeout after receiving Announcement before channel/pan-id change
-    kAnnounceTimeout                = 1400, ///< Total timeout used for sending Announcement messages
-    kMinAnnounceDelay               = 80,   ///< Minimum delay between Announcement messages
-    kParentResponseMaxDelayRouters  = 500,  ///< Maximum delay for response for Parent Request sent to routers only
-    kParentResponseMaxDelayAll      = 1000, ///< Maximum delay for response for Parent Request sent to all devices
-    kUnicastRetransmissionDelay     = 1000, ///< Base delay before retransmitting an MLE unicast.
-    kChildUpdateRequestPendingDelay = 100,  ///< Delay (in ms) for aggregating Child Update Request.
-    kMaxTransmissionCount           = 3,    ///< Maximum number of times an MLE message may be transmitted.
-    kMaxResponseDelay               = 1000, ///< Maximum delay before responding to a multicast request
-    kMaxChildIdRequestTimeout       = 5000, ///< Maximum delay for receiving a Child ID Request
-    kMaxChildUpdateResponseTimeout  = 2000, ///< Maximum delay for receiving a Child Update Response
-    kMaxLinkRequestTimeout          = 2000, ///< Maximum delay for receiving a Link Accept
-    kMinTimeoutKeepAlive            = (((kMaxChildKeepAliveAttempts + 1) * kUnicastRetransmissionDelay) /
-                            1000), ///< Minimum timeout(s) for keep alive
-    kMinTimeoutDataPoll             = (OPENTHREAD_CONFIG_MAC_MINIMUM_POLL_PERIOD +
-                           OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS * OPENTHREAD_CONFIG_MAC_RETX_POLL_PERIOD) /
-                          1000, ///< Minimum timeout(s) for data poll
-    kMinTimeout = (kMinTimeoutKeepAlive >= kMinTimeoutDataPoll ? kMinTimeoutKeepAlive
-                                                               : kMinTimeoutDataPoll), ///< Minimum timeout(s)
-};
-
-enum
-{
-    kMinChildId       = 1,   ///< Minimum Child ID
-    kMaxChildId       = 511, ///< Maximum Child ID
-    kRouterIdOffset   = 10,  ///< Bit offset of Router ID in RLOC16
-    kRlocPrefixLength = 14,  ///< Prefix length of RLOC in bytes
-};
-
-/**
- * Routing Protocol Constants
- *
- */
-enum
-{
-    kAdvertiseIntervalMin = 1, ///< ADVERTISEMENT_I_MIN (sec)
-#if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
-    kAdvertiseIntervalMax = 5, ///< ADVERTISEMENT_I_MAX (sec) proposal
-#else
-    kAdvertiseIntervalMax = 32, ///< ADVERTISEMENT_I_MAX (sec)
-#endif
-    kFailedRouterTransmissions = 4,   ///< FAILED_ROUTER_TRANSMISSIONS
-    kRouterIdReuseDelay        = 100, ///< ID_REUSE_DELAY (sec)
-    kRouterIdSequencePeriod    = 10,  ///< ID_SEQUENCE_PERIOD (sec)
-    kMaxNeighborAge            = 100, ///< MAX_NEIGHBOR_AGE (sec)
-#if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
-    kMaxRouteCost = 127, ///< MAX_ROUTE_COST proposal
-#else
-    kMaxRouteCost         = 16, ///< MAX_ROUTE_COST
-#endif
-    kMaxRouterId                = 62,                                          ///< MAX_ROUTER_ID
-    kInvalidRouterId            = kMaxRouterId + 1,                            ///< Value indicating incorrect Router Id
-    kMaxRouters                 = OPENTHREAD_CONFIG_MLE_MAX_ROUTERS,           ///< MAX_ROUTERS
-    kMinDowngradeNeighbors      = 7,                                           ///< MIN_DOWNGRADE_NEIGHBORS
-    kNetworkIdTimeout           = 120,                                         ///< NETWORK_ID_TIMEOUT (sec)
-    kParentRouteToLeaderTimeout = 20,                                          ///< PARENT_ROUTE_TO_LEADER_TIMEOUT (sec)
-    kRouterSelectionJitter      = 120,                                         ///< ROUTER_SELECTION_JITTER (sec)
-    kRouterDowngradeThreshold   = 23,                                          ///< ROUTER_DOWNGRADE_THRESHOLD (routers)
-    kRouterUpgradeThreshold     = 16,                                          ///< ROUTER_UPGRADE_THRESHOLD (routers)
-    kMaxLeaderToRouterTimeout   = 90,                                          ///< INFINITE_COST_TIMEOUT (sec)
-    kReedAdvertiseInterval      = 570,                                         ///< REED_ADVERTISEMENT_INTERVAL (sec)
-    kReedAdvertiseJitter        = 60,                                          ///< REED_ADVERTISEMENT_JITTER (sec)
-    kLeaderWeight               = 64,                                          ///< Default leader weight
-    kMleEndDeviceTimeout        = OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT, ///< MLE_END_DEVICE_TIMEOUT (sec)
-    kMeshLocalPrefixContextId   = 0,                                           ///< 0 is reserved for Mesh Local Prefix
-};
-
-/**
- * Parent Priority values
- *
- */
-enum
-{
-    kParentPriorityHigh        = 1,  // Parent Priority High
-    kParentPriorityMedium      = 0,  // Parent Priority Medium (default)
-    kParentPriorityLow         = -1, // Parent Priority Low
-    kParentPriorityUnspecified = -2, // Parent Priority Unspecified
-};
-
-enum
-{
-    kLinkQuality3LinkCost = 1,             ///< Link Cost for Link Quality 3
-    kLinkQuality2LinkCost = 2,             ///< Link Cost for Link Quality 2
-    kLinkQuality1LinkCost = 4,             ///< Link Cost for Link Quality 1
-    kLinkQuality0LinkCost = kMaxRouteCost, ///< Link Cost for Link Quality 0
-};
-
-/**
- * Multicast Forwarding Constants
- *
- */
-enum
-{
-    kMplChildDataMessageTimerExpirations  = 0, ///< Number of MPL retransmissions for Children.
-    kMplRouterDataMessageTimerExpirations = 2, ///< Number of MPL retransmissions for Routers.
-};
-
-} // namespace Mle
-
-/**
- * @}
- *
- */
-
-} // namespace ot
-
-#endif // MLE_CONSTANTS_HPP_
diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp
index f3cccb4..d87896b 100644
--- a/src/core/thread/mle_router.cpp
+++ b/src/core/thread/mle_router.cpp
@@ -49,6 +49,7 @@
 #include "thread/thread_tlvs.hpp"
 #include "thread/thread_uri_paths.hpp"
 #include "thread/time_sync_service.hpp"
+#include "utils/otns.hpp"
 
 using ot::Encoding::BigEndian::HostSwap16;
 
@@ -57,13 +58,13 @@
 
 MleRouter::MleRouter(Instance &aInstance)
     : Mle(aInstance)
-    , mAdvertiseTimer(aInstance, &MleRouter::HandleAdvertiseTimer, NULL, this)
-    , mStateUpdateTimer(aInstance, &MleRouter::HandleStateUpdateTimer, this)
+    , mAdvertiseTimer(aInstance, MleRouter::HandleAdvertiseTimer, nullptr, this)
+    , mStateUpdateTimer(aInstance, MleRouter::HandleStateUpdateTimer, this)
     , mAddressSolicit(OT_URI_PATH_ADDRESS_SOLICIT, &MleRouter::HandleAddressSolicit, this)
     , mAddressRelease(OT_URI_PATH_ADDRESS_RELEASE, &MleRouter::HandleAddressRelease, this)
     , mChildTable(aInstance)
     , mRouterTable(aInstance)
-    , mNeighborTableChangedCallback(NULL)
+    , mNeighborTableChangedCallback(nullptr)
     , mChallengeTimeout(0)
     , mNextChildId(kMaxChildId)
     , mNetworkIdTimeout(kNetworkIdTimeout)
@@ -73,6 +74,7 @@
     , mFixedLeaderPartitionId(0)
     , mRouterEligible(true)
     , mAddressSolicitPending(false)
+    , mAddressSolicitRejected(false)
     , mPreviousPartitionIdRouter(0)
     , mPreviousPartitionId(0)
     , mPreviousPartitionRouterIdSequence(0)
@@ -80,10 +82,20 @@
     , mRouterSelectionJitter(kRouterSelectionJitter)
     , mRouterSelectionJitterTimeout(0)
     , mParentPriority(kParentPriorityUnspecified)
+#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    , mBackboneRouterRegistrationDelay(0)
+#endif
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
+    , mMaxChildIpAddresses(0)
+#endif
 {
     mDeviceMode.Set(mDeviceMode.Get() | DeviceMode::kModeFullThreadDevice | DeviceMode::kModeFullNetworkData);
 
     SetRouterId(kInvalidRouterId);
+
+#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
+    mSteeringData.Clear();
+#endif
 }
 
 void MleRouter::HandlePartitionChange(void)
@@ -93,7 +105,7 @@
     mPreviousPartitionIdTimeout        = GetNetworkIdTimeout();
 
     Get<AddressResolver>().Clear();
-    Get<Coap::Coap>().AbortTransaction(&MleRouter::HandleAddressSolicitResponse, this);
+    IgnoreError(Get<Coap::Coap>().AbortTransaction(&MleRouter::HandleAddressSolicitResponse, this));
     mRouterTable.Clear();
 }
 
@@ -112,19 +124,19 @@
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDisabled:
+    case kRoleDetached:
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         Get<Mac::Mac>().SetBeaconEnabled(mRouterEligible);
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleRouter:
+    case kRoleLeader:
         if (!mRouterEligible)
         {
-            BecomeDetached();
+            IgnoreError(BecomeDetached());
         }
 
         break;
@@ -138,8 +150,8 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_ROUTER, error = OT_ERROR_NONE);
+    VerifyOrExit(!IsDisabled(), error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(!IsRouter(), error = OT_ERROR_NONE);
     VerifyOrExit(IsRouterEligible(), error = OT_ERROR_NOT_CAPABLE);
 
     otLogInfoMle("Attempt to become router");
@@ -149,18 +161,18 @@
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DETACHED:
-        SuccessOrExit(error = SendLinkRequest(NULL));
+    case kRoleDetached:
+        SuccessOrExit(error = SendLinkRequest(nullptr));
         mStateUpdateTimer.Start(kStateUpdatePeriod);
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         SuccessOrExit(error = SendAddressSolicit(aStatus));
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
 exit:
@@ -175,8 +187,8 @@
     uint8_t  leaderId;
 
     VerifyOrExit(!Get<MeshCoP::ActiveDataset>().IsPartiallyComplete(), error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(mRole != OT_DEVICE_ROLE_LEADER, error = OT_ERROR_NONE);
+    VerifyOrExit(!IsDisabled(), error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(!IsLeader(), error = OT_ERROR_NONE);
     VerifyOrExit(IsRouterEligible(), error = OT_ERROR_NOT_CAPABLE);
 
     mRouterTable.Clear();
@@ -189,7 +201,7 @@
     SetLeaderData(partitionId, mLeaderWeight, leaderId);
 
     router = mRouterTable.Allocate(leaderId);
-    assert(router != NULL);
+    OT_ASSERT(router != nullptr);
 
     SetRouterId(leaderId);
     router->SetExtAddress(Get<Mac::Mac>().GetExtAddress());
@@ -209,7 +221,7 @@
     Get<Coap::Coap>().RemoveResource(mAddressRelease);
     Get<MeshCoP::ActiveDataset>().StopLeader();
     Get<MeshCoP::PendingDataset>().StopLeader();
-    mAdvertiseTimer.Stop();
+    StopAdvertiseTimer();
     Get<NetworkData::Leader>().Stop();
     Get<ThreadNetif>().UnsubscribeAllRoutersMulticast();
 }
@@ -221,9 +233,10 @@
     mStateUpdateTimer.Stop();
 }
 
-otError MleRouter::HandleChildStart(AttachMode aMode)
+void MleRouter::HandleChildStart(AttachMode aMode)
 {
-    otError error = OT_ERROR_NONE;
+    // reset `rejected` flag whenever REED becomes child.
+    mAddressSolicitRejected = false;
 
     mRouterSelectionJitterTimeout = 1 + Random::NonCrypto::GetUint8InRange(0, mRouterSelectionJitter);
 
@@ -237,7 +250,7 @@
 
     Get<ThreadNetif>().SubscribeAllRoutersMulticast();
 
-    VerifyOrExit(IsRouterIdValid(mPreviousRouterId), error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(IsRouterIdValid(mPreviousRouterId), OT_NOOP);
 
     switch (aMode)
     {
@@ -258,7 +271,7 @@
     case kAttachSame2:
         if (HasChildren())
         {
-            BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest);
+            IgnoreError(BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest));
         }
 
         break;
@@ -282,7 +295,7 @@
     case kAttachBetter:
         if (HasChildren() && mPreviousPartitionIdRouter != mLeaderData.GetPartitionId())
         {
-            BecomeRouter(ThreadStatusTlv::kParentPartitionChange);
+            IgnoreError(BecomeRouter(ThreadStatusTlv::kParentPartitionChange));
         }
 
         break;
@@ -295,20 +308,18 @@
     {
         SetRouterId(kInvalidRouterId);
     }
-
-    return error;
 }
 
 void MleRouter::SetStateRouter(uint16_t aRloc16)
 {
     SetRloc16(aRloc16);
 
-    SetRole(OT_DEVICE_ROLE_ROUTER);
+    SetRole(kRoleRouter);
     SetAttachState(kAttachStateIdle);
     mAttachCounter = 0;
     mAttachTimer.Stop();
     mMessageTransmissionTimer.Stop();
-    mAdvertiseTimer.Stop();
+    StopAdvertiseTimer();
     ResetAdvertiseInterval();
 
     Get<ThreadNetif>().SubscribeAllRoutersMulticast();
@@ -319,27 +330,30 @@
     Get<Mac::Mac>().SetBeaconEnabled(true);
 
     // remove children that do not have matching RLOC16
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
     {
-        if (RouterIdFromRloc16(iter.GetChild()->GetRloc16()) != mRouterId)
+        if (RouterIdFromRloc16(child.GetRloc16()) != mRouterId)
         {
-            RemoveNeighbor(*iter.GetChild());
+            RemoveNeighbor(child);
         }
     }
 }
 
 void MleRouter::SetStateLeader(uint16_t aRloc16)
 {
+    IgnoreError(Get<MeshCoP::ActiveDataset>().Restore());
+    IgnoreError(Get<MeshCoP::PendingDataset>().Restore());
     SetRloc16(aRloc16);
 
-    SetRole(OT_DEVICE_ROLE_LEADER);
+    SetRole(kRoleLeader);
     SetAttachState(kAttachStateIdle);
     mAttachCounter = 0;
     mAttachTimer.Stop();
     mMessageTransmissionTimer.Stop();
-    mAdvertiseTimer.Stop();
+    StopAdvertiseTimer();
     ResetAdvertiseInterval();
-    AddLeaderAloc();
+    IgnoreError(GetLeaderAloc(mLeaderAloc.GetAddress()));
+    Get<ThreadNetif>().AddUnicastAddress(mLeaderAloc);
 
     Get<ThreadNetif>().SubscribeAllRoutersMulticast();
     mPreviousPartitionIdRouter = mLeaderData.GetPartitionId();
@@ -356,11 +370,11 @@
     Get<AddressResolver>().Clear();
 
     // remove children that do not have matching RLOC16
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
     {
-        if (RouterIdFromRloc16(iter.GetChild()->GetRloc16()) != mRouterId)
+        if (RouterIdFromRloc16(child.GetRloc16()) != mRouterId)
         {
-            RemoveNeighbor(*iter.GetChild());
+            RemoveNeighbor(child);
         }
     }
 
@@ -391,7 +405,7 @@
 
 void MleRouter::ResetAdvertiseInterval(void)
 {
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER);
+    VerifyOrExit(IsRouterOrLeader(), OT_NOOP);
 
     if (!mAdvertiseTimer.IsRunning())
     {
@@ -405,61 +419,62 @@
     return;
 }
 
-otError MleRouter::SendAdvertisement(void)
+void MleRouter::SendAdvertisement(void)
 {
     otError      error = OT_ERROR_NONE;
     Ip6::Address destination;
-    Message *    message = NULL;
+    Message *    message = nullptr;
 
     // Suppress MLE Advertisements when trying to attach to a better partition.
     //
     // Without this suppression, a device may send an MLE Advertisement before receiving the MLE Child ID Response.
     // The candidate parent then removes the attaching device because the Source Address TLV includes an RLOC16 that
     // indicates a Router role (i.e. a Child ID equal to zero).
-    VerifyOrExit(!IsAttaching());
+    VerifyOrExit(!IsAttaching(), OT_NOOP);
 
     // Suppress MLE Advertisements when transitioning to the router role.
     //
     // When trying to attach to a new partition, sending out advertisements as a REED can cause already-attached
     // children to detach.
-    VerifyOrExit(!mAddressSolicitPending);
+    VerifyOrExit(!mAddressSolicitPending, OT_NOOP);
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandAdvertisement));
     SuccessOrExit(error = AppendSourceAddress(*message));
     SuccessOrExit(error = AppendLeaderData(*message));
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
-        assert(false);
+    case kRoleDisabled:
+    case kRoleDetached:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
+
+    case kRoleChild:
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
-        break;
-
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleRouter:
+    case kRoleLeader:
         SuccessOrExit(error = AppendRoute(*message));
         break;
     }
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xff02);
-    destination.mFields.m16[7] = HostSwap16(0x0001);
+    destination.SetToLinkLocalAllNodesMulticast();
     SuccessOrExit(error = SendMessage(*message, destination));
 
     LogMleMessage("Send Advertisement", destination);
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        message->Free();
-    }
+        otLogWarnMle("Failed to send Advertisement: %s", otThreadErrorToString(error));
 
-    return error;
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
 }
 
 otError MleRouter::SendLinkRequest(Neighbor *aNeighbor)
@@ -473,28 +488,28 @@
 
     destination.Clear();
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandLinkRequest));
     SuccessOrExit(error = AppendVersion(*message));
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-        assert(false);
-        break;
+    case kRoleDisabled:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
 
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDetached:
         SuccessOrExit(error = AppendTlvRequest(*message, detachedTlvs, sizeof(detachedTlvs)));
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         SuccessOrExit(error = AppendSourceAddress(*message));
         SuccessOrExit(error = AppendLeaderData(*message));
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
-        if (aNeighbor == NULL || !aNeighbor->IsStateValid())
+    case kRoleRouter:
+    case kRoleLeader:
+        if (aNeighbor == nullptr || !aNeighbor->IsStateValid())
         {
             SuccessOrExit(error = AppendTlvRequest(*message, routerTlvs, sizeof(routerTlvs)));
         }
@@ -512,16 +527,13 @@
     SuccessOrExit(error = AppendTimeRequest(*message));
 #endif
 
-    if (aNeighbor == NULL)
+    if (aNeighbor == nullptr)
     {
-        Random::Crypto::FillBuffer(mChallenge, sizeof(mChallenge));
-
+        mChallenge.GenerateRandom();
         mChallengeTimeout = (((2 * kMaxResponseDelay) + kStateUpdatePeriod - 1) / kStateUpdatePeriod);
 
-        SuccessOrExit(error = AppendChallenge(*message, mChallenge, sizeof(mChallenge)));
-        destination.mFields.m8[0]  = 0xff;
-        destination.mFields.m8[1]  = 0x02;
-        destination.mFields.m8[15] = 2;
+        SuccessOrExit(error = AppendChallenge(*message, mChallenge));
+        destination.SetToLinkLocalAllRoutersMulticast();
     }
     else
     {
@@ -532,14 +544,13 @@
         }
         else
         {
-            uint8_t challenge[ChallengeTlv::kMaxSize];
+            Challenge challenge;
 
-            Random::Crypto::FillBuffer(challenge, sizeof(challenge));
-            SuccessOrExit(error = AppendChallenge(*message, challenge, sizeof(challenge)));
+            challenge.GenerateRandom();
+            SuccessOrExit(error = AppendChallenge(*message, challenge));
         }
 
-        destination.mFields.m16[0] = HostSwap16(0xfe80);
-        destination.SetIid(aNeighbor->GetExtAddress());
+        destination.SetToLinkLocalAddress(aNeighbor->GetExtAddress());
     }
 
     SuccessOrExit(error = SendMessage(*message, destination));
@@ -548,7 +559,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -556,98 +567,104 @@
     return error;
 }
 
-otError MleRouter::HandleLinkRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor)
+void MleRouter::HandleLinkRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor)
 {
-    otError          error    = OT_ERROR_NONE;
-    Neighbor *       neighbor = NULL;
-    ChallengeTlv     challenge;
-    VersionTlv       version;
-    LeaderDataTlv    leaderData;
-    SourceAddressTlv sourceAddress;
-    TlvRequestTlv    tlvRequest;
+    otError       error    = OT_ERROR_NONE;
+    Neighbor *    neighbor = nullptr;
+    Challenge     challenge;
+    uint16_t      version;
+    LeaderData    leaderData;
+    uint16_t      sourceAddress;
+    RequestedTlvs requestedTlvs;
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     TimeRequestTlv timeRequest;
 #endif
 
     LogMleMessage("Receive Link Request", aMessageInfo.GetPeerAddr());
 
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(IsRouterOrLeader(), error = OT_ERROR_INVALID_STATE);
 
     VerifyOrExit(!IsAttaching(), error = OT_ERROR_INVALID_STATE);
 
     // Challenge
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kChallenge, sizeof(challenge), challenge));
-    VerifyOrExit(challenge.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadChallenge(aMessage, challenge));
 
     // Version
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kVersion, sizeof(version), version));
-    VerifyOrExit(version.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kVersion, version));
+    VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = OT_ERROR_PARSE);
 
     // Leader Data
-    if (Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData) == OT_ERROR_NONE)
+    switch (ReadLeaderData(aMessage, leaderData))
     {
-        VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+    case OT_ERROR_NONE:
         VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId(), error = OT_ERROR_INVALID_STATE);
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // Source Address
-    if (Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress) == OT_ERROR_NONE)
+    switch (Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress))
     {
-        uint16_t rloc16;
-
-        VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
-
-        rloc16 = sourceAddress.GetRloc16();
-
-        if (IsActiveRouter(rloc16))
+    case OT_ERROR_NONE:
+        if (IsActiveRouter(sourceAddress))
         {
-            Mac::ExtAddress macAddr;
+            Mac::ExtAddress extAddr;
 
-            aMessageInfo.GetPeerAddr().ToExtAddress(macAddr);
+            aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr);
 
-            neighbor = mRouterTable.GetRouter(RouterIdFromRloc16(rloc16));
-            VerifyOrExit(neighbor != NULL, error = OT_ERROR_PARSE);
+            neighbor = mRouterTable.GetRouter(RouterIdFromRloc16(sourceAddress));
+            VerifyOrExit(neighbor != nullptr, error = OT_ERROR_PARSE);
             VerifyOrExit(!neighbor->IsStateLinkRequest(), error = OT_ERROR_ALREADY);
 
             if (!neighbor->IsStateValid())
             {
                 const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
 
-                neighbor->SetExtAddress(macAddr);
+                neighbor->SetExtAddress(extAddr);
                 neighbor->GetLinkInfo().Clear();
-                neighbor->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
+                neighbor->GetLinkInfo().AddRss(linkInfo->mRss);
                 neighbor->ResetLinkFailures();
                 neighbor->SetLastHeard(TimerMilli::GetNow());
                 neighbor->SetState(Neighbor::kStateLinkRequest);
             }
             else
             {
-                VerifyOrExit(neighbor->GetExtAddress() == macAddr);
+                VerifyOrExit(neighbor->GetExtAddress() == extAddr, OT_NOOP);
             }
         }
-    }
-    else
-    {
+
+        break;
+
+    case OT_ERROR_NOT_FOUND:
         // lack of source address indicates router coming out of reset
         VerifyOrExit(aNeighbor && aNeighbor->IsStateValid() && IsActiveRouter(aNeighbor->GetRloc16()),
                      error = OT_ERROR_DROP);
         neighbor = aNeighbor;
+        break;
+
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // TLV Request
-    if (Tlv::GetTlv(aMessage, Tlv::kTlvRequest, sizeof(tlvRequest), tlvRequest) == OT_ERROR_NONE)
+    switch (FindTlvRequest(aMessage, requestedTlvs))
     {
-        VerifyOrExit(tlvRequest.IsValid(), error = OT_ERROR_PARSE);
-    }
-    else
-    {
-        tlvRequest.SetLength(0);
+    case OT_ERROR_NONE:
+        break;
+    case OT_ERROR_NOT_FOUND:
+        requestedTlvs.mNumTlvs = 0;
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    if (neighbor != NULL)
+    if (neighbor != nullptr)
     {
-        if (Tlv::GetTlv(aMessage, Tlv::kTimeRequest, sizeof(timeRequest), timeRequest) == OT_ERROR_NONE)
+        if (Tlv::FindTlv(aMessage, Tlv::kTimeRequest, sizeof(timeRequest), timeRequest) == OT_ERROR_NONE)
         {
             neighbor->SetTimeSyncEnabled(true);
         }
@@ -658,16 +675,20 @@
     }
 #endif
 
-    SuccessOrExit(error = SendLinkAccept(aMessageInfo, neighbor, tlvRequest, challenge));
+    SuccessOrExit(error = SendLinkAccept(aMessageInfo, neighbor, requestedTlvs, challenge));
 
 exit:
-    return error;
+
+    if (error != OT_ERROR_NONE)
+    {
+        otLogNoteMle("Failed to process Link Request: %s", otThreadErrorToString(error));
+    }
 }
 
 otError MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
                                   Neighbor *              aNeighbor,
-                                  const TlvRequestTlv &   aTlvRequest,
-                                  const ChallengeTlv &    aChallenge)
+                                  const RequestedTlvs &   aRequestedTlvs,
+                                  const Challenge &       aChallenge)
 {
     otError                 error        = OT_ERROR_NONE;
     const otThreadLinkInfo *linkInfo     = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
@@ -676,14 +697,14 @@
     Header::Command         command;
     uint8_t                 linkMargin;
 
-    command = (aNeighbor == NULL || aNeighbor->IsStateValid()) ? Header::kCommandLinkAccept
-                                                               : Header::kCommandLinkAcceptAndRequest;
+    command = (aNeighbor == nullptr || aNeighbor->IsStateValid()) ? Header::kCommandLinkAccept
+                                                                  : Header::kCommandLinkAcceptAndRequest;
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, command));
     SuccessOrExit(error = AppendVersion(*message));
     SuccessOrExit(error = AppendSourceAddress(*message));
-    SuccessOrExit(error = AppendResponse(*message, aChallenge.GetChallenge(), aChallenge.GetChallengeLength()));
+    SuccessOrExit(error = AppendResponse(*message, aChallenge));
     SuccessOrExit(error = AppendLinkFrameCounter(*message));
     SuccessOrExit(error = AppendMleFrameCounter(*message));
 
@@ -692,21 +713,21 @@
 
     SuccessOrExit(error = AppendLinkMargin(*message, linkMargin));
 
-    if (aNeighbor != NULL && IsActiveRouter(aNeighbor->GetRloc16()))
+    if (aNeighbor != nullptr && IsActiveRouter(aNeighbor->GetRloc16()))
     {
         SuccessOrExit(error = AppendLeaderData(*message));
     }
 
-    for (uint8_t i = 0; i < aTlvRequest.GetLength(); i++)
+    for (uint8_t i = 0; i < aRequestedTlvs.mNumTlvs; i++)
     {
-        switch (aTlvRequest.GetTlvs()[i])
+        switch (aRequestedTlvs.mTlvs[i])
         {
         case Tlv::kRoute:
             SuccessOrExit(error = AppendRoute(*message));
             break;
 
         case Tlv::kAddress16:
-            VerifyOrExit(aNeighbor != NULL, error = OT_ERROR_DROP);
+            VerifyOrExit(aNeighbor != nullptr, error = OT_ERROR_DROP);
             SuccessOrExit(error = AppendAddress16(*message, aNeighbor->GetRloc16()));
             break;
 
@@ -718,7 +739,7 @@
         }
     }
 
-    if (aNeighbor != NULL && !aNeighbor->IsStateValid())
+    if (aNeighbor != nullptr && !aNeighbor->IsStateValid())
     {
         aNeighbor->GenerateChallenge();
 
@@ -729,7 +750,7 @@
     }
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    if (aNeighbor != NULL && aNeighbor->IsTimeSyncEnabled())
+    if (aNeighbor != nullptr && aNeighbor->IsTimeSyncEnabled())
     {
         message->SetTimeSync(true);
     }
@@ -751,7 +772,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -759,10 +780,10 @@
     return error;
 }
 
-otError MleRouter::HandleLinkAccept(const Message &         aMessage,
-                                    const Ip6::MessageInfo &aMessageInfo,
-                                    uint32_t                aKeySequence,
-                                    Neighbor *              aNeighbor)
+void MleRouter::HandleLinkAccept(const Message &         aMessage,
+                                 const Ip6::MessageInfo &aMessageInfo,
+                                 uint32_t                aKeySequence,
+                                 Neighbor *              aNeighbor)
 {
     otError error = HandleLinkAccept(aMessage, aMessageInfo, aKeySequence, aNeighbor, false);
 
@@ -770,14 +791,12 @@
     {
         otLogWarnMle("Failed to process Link Accept: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError MleRouter::HandleLinkAcceptAndRequest(const Message &         aMessage,
-                                              const Ip6::MessageInfo &aMessageInfo,
-                                              uint32_t                aKeySequence,
-                                              Neighbor *              aNeighbor)
+void MleRouter::HandleLinkAcceptAndRequest(const Message &         aMessage,
+                                           const Ip6::MessageInfo &aMessageInfo,
+                                           uint32_t                aKeySequence,
+                                           Neighbor *              aNeighbor)
 {
     otError error = HandleLinkAccept(aMessage, aMessageInfo, aKeySequence, aNeighbor, true);
 
@@ -785,8 +804,6 @@
     {
         otLogWarnMle("Failed to process Link Accept and Request: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
 otError MleRouter::HandleLinkAccept(const Message &         aMessage,
@@ -801,52 +818,48 @@
     const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
     Router *                router;
     Neighbor::State         neighborState;
-    Mac::ExtAddress         macAddr;
-    VersionTlv              version;
-    ResponseTlv             response;
-    SourceAddressTlv        sourceAddress;
-    LinkFrameCounterTlv     linkFrameCounter;
-    MleFrameCounterTlv      mleFrameCounter;
+    Mac::ExtAddress         extAddr;
+    uint16_t                version;
+    Challenge               response;
+    uint16_t                sourceAddress;
+    uint32_t                linkFrameCounter;
+    uint32_t                mleFrameCounter;
     uint8_t                 routerId;
-    Address16Tlv            address16;
+    uint16_t                address16;
     RouteTlv                route;
-    LeaderDataTlv           leaderData;
-    LinkMarginTlv           linkMargin;
+    LeaderData              leaderData;
+    uint8_t                 linkMargin;
 
     // Source Address
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
-    VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress));
 
     if (aRequest)
     {
-        LogMleMessage("Receive Link Accept and Request", aMessageInfo.GetPeerAddr(), sourceAddress.GetRloc16());
+        LogMleMessage("Receive Link Accept and Request", aMessageInfo.GetPeerAddr(), sourceAddress);
     }
     else
     {
-        LogMleMessage("Receive Link Accept", aMessageInfo.GetPeerAddr(), sourceAddress.GetRloc16());
+        LogMleMessage("Receive Link Accept", aMessageInfo.GetPeerAddr(), sourceAddress);
     }
 
-    VerifyOrExit(IsActiveRouter(sourceAddress.GetRloc16()), error = OT_ERROR_PARSE);
+    VerifyOrExit(IsActiveRouter(sourceAddress), error = OT_ERROR_PARSE);
 
-    routerId      = RouterIdFromRloc16(sourceAddress.GetRloc16());
+    routerId      = RouterIdFromRloc16(sourceAddress);
     router        = mRouterTable.GetRouter(routerId);
-    neighborState = (router != NULL) ? router->GetState() : Neighbor::kStateInvalid;
+    neighborState = (router != nullptr) ? router->GetState() : Neighbor::kStateInvalid;
 
     // Response
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kResponse, sizeof(response), response));
-    VerifyOrExit(response.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadResponse(aMessage, response));
 
     // verify response
     switch (neighborState)
     {
     case Neighbor::kStateLinkRequest:
-        VerifyOrExit(memcmp(router->GetChallenge(), response.GetResponse(), router->GetChallengeSize()) == 0,
-                     error = OT_ERROR_SECURITY);
+        VerifyOrExit(response.Matches(router->GetChallenge(), router->GetChallengeSize()), error = OT_ERROR_SECURITY);
         break;
 
     case Neighbor::kStateInvalid:
-        VerifyOrExit((mChallengeTimeout > 0) && (memcmp(mChallenge, response.GetResponse(), sizeof(mChallenge)) == 0),
-                     error = OT_ERROR_SECURITY);
+        VerifyOrExit((mChallengeTimeout > 0) && (response == mChallenge), error = OT_ERROR_SECURITY);
 
     case Neighbor::kStateValid:
         break;
@@ -856,67 +869,67 @@
     }
 
     // Remove stale neighbors
-    if (aNeighbor && aNeighbor->GetRloc16() != sourceAddress.GetRloc16())
+    if (aNeighbor && aNeighbor->GetRloc16() != sourceAddress)
     {
         RemoveNeighbor(*aNeighbor);
     }
 
     // Version
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kVersion, sizeof(version), version));
-    VerifyOrExit(version.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kVersion, version));
+    VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = OT_ERROR_PARSE);
 
     // Link-Layer Frame Counter
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLinkFrameCounter, sizeof(linkFrameCounter), linkFrameCounter));
-    VerifyOrExit(linkFrameCounter.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint32Tlv(aMessage, Tlv::kLinkFrameCounter, linkFrameCounter));
 
     // MLE Frame Counter
-    if (Tlv::GetTlv(aMessage, Tlv::kMleFrameCounter, sizeof(mleFrameCounter), mleFrameCounter) == OT_ERROR_NONE)
+    switch (Tlv::FindUint32Tlv(aMessage, Tlv::kMleFrameCounter, mleFrameCounter))
     {
-        VerifyOrExit(mleFrameCounter.IsValid(), error = OT_ERROR_PARSE);
-    }
-    else
-    {
-        mleFrameCounter.SetFrameCounter(linkFrameCounter.GetFrameCounter());
+    case OT_ERROR_NONE:
+        break;
+    case OT_ERROR_NOT_FOUND:
+        mleFrameCounter = linkFrameCounter;
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // Link Margin
-    if (Tlv::GetTlv(aMessage, Tlv::kLinkMargin, sizeof(linkMargin), linkMargin) == OT_ERROR_NONE)
+    switch (Tlv::FindUint8Tlv(aMessage, Tlv::kLinkMargin, linkMargin))
     {
-        VerifyOrExit(linkMargin.IsValid(), error = OT_ERROR_PARSE);
-    }
-    else
-    {
+    case OT_ERROR_NONE:
+        break;
+    case OT_ERROR_NOT_FOUND:
         // Link Margin TLV may be skipped in Router Synchronization process after Reset
-        VerifyOrExit(mRole == OT_DEVICE_ROLE_DETACHED, error = OT_ERROR_NOT_FOUND);
-
+        VerifyOrExit(IsDetached(), error = OT_ERROR_NOT_FOUND);
         // Wait for an MLE Advertisement to establish a routing cost to the neighbor
-        linkMargin.SetLinkMargin(0);
+        linkMargin = 0;
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-        assert(false);
-        break;
+    case kRoleDisabled:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
 
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDetached:
         // Address16
-        SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kAddress16, sizeof(address16), address16));
-        VerifyOrExit(address16.IsValid(), error = OT_ERROR_PARSE);
-        VerifyOrExit(GetRloc16() == address16.GetRloc16(), error = OT_ERROR_DROP);
+        SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kAddress16, address16));
+        VerifyOrExit(GetRloc16() == address16, error = OT_ERROR_DROP);
 
         // Leader Data
-        SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
-        VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+        SuccessOrExit(error = ReadLeaderData(aMessage, leaderData));
         SetLeaderData(leaderData.GetPartitionId(), leaderData.GetWeighting(), leaderData.GetLeaderRouterId());
 
         // Route
-        SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route));
+        SuccessOrExit(error = Tlv::FindTlv(aMessage, Tlv::kRoute, sizeof(route), route));
         VerifyOrExit(route.IsValid(), error = OT_ERROR_PARSE);
         mRouterTable.Clear();
         SuccessOrExit(error = ProcessRouteTlv(route));
         router = mRouterTable.GetRouter(routerId);
-        VerifyOrExit(router != NULL);
+        VerifyOrExit(router != nullptr, OT_NOOP);
 
         if (mLeaderData.GetLeaderRouterId() == RouterIdFromRloc16(GetRloc16()))
         {
@@ -928,38 +941,40 @@
         }
 
         mRetrieveNewNetworkData = true;
-        SendDataRequest(aMessageInfo.GetPeerAddr(), dataRequestTlvs, sizeof(dataRequestTlvs), 0);
+        IgnoreError(SendDataRequest(aMessageInfo.GetPeerAddr(), dataRequestTlvs, sizeof(dataRequestTlvs), 0));
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
         Get<TimeSync>().HandleTimeSyncMessage(aMessage);
 #endif
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
-        VerifyOrExit(router != NULL);
+    case kRoleChild:
+        VerifyOrExit(router != nullptr, OT_NOOP);
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
-        VerifyOrExit(router != NULL);
+    case kRoleRouter:
+    case kRoleLeader:
+        VerifyOrExit(router != nullptr, OT_NOOP);
 
         // Leader Data
-        SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
-        VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
-        VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId());
+        SuccessOrExit(error = ReadLeaderData(aMessage, leaderData));
+        VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId(), OT_NOOP);
 
         if (mRetrieveNewNetworkData ||
             (static_cast<int8_t>(leaderData.GetDataVersion() - Get<NetworkData::Leader>().GetVersion()) > 0))
         {
-            SendDataRequest(aMessageInfo.GetPeerAddr(), dataRequestTlvs, sizeof(dataRequestTlvs), 0);
+            IgnoreError(SendDataRequest(aMessageInfo.GetPeerAddr(), dataRequestTlvs, sizeof(dataRequestTlvs), 0));
         }
 
         // Route (optional)
-        if (Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE)
+        if (Tlv::FindTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE)
         {
             VerifyOrExit(route.IsValid(), error = OT_ERROR_PARSE);
             SuccessOrExit(error = ProcessRouteTlv(route));
             UpdateRoutes(route, routerId);
+            // need to update router after ProcessRouteTlv
+            router = mRouterTable.GetRouter(routerId);
+            OT_ASSERT(router != nullptr);
         }
 
         // update routing table
@@ -972,17 +987,17 @@
     }
 
     // finish link synchronization
-    aMessageInfo.GetPeerAddr().ToExtAddress(macAddr);
-    router->SetExtAddress(macAddr);
-    router->SetRloc16(sourceAddress.GetRloc16());
-    router->SetLinkFrameCounter(linkFrameCounter.GetFrameCounter());
-    router->SetMleFrameCounter(mleFrameCounter.GetFrameCounter());
+    aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr);
+    router->SetExtAddress(extAddr);
+    router->SetRloc16(sourceAddress);
+    router->SetLinkFrameCounter(linkFrameCounter);
+    router->SetMleFrameCounter(mleFrameCounter);
     router->SetLastHeard(TimerMilli::GetNow());
     router->SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle |
                                      DeviceMode::kModeFullNetworkData));
     router->GetLinkInfo().Clear();
-    router->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
-    router->SetLinkQualityOut(LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin.GetLinkMargin()));
+    router->GetLinkInfo().AddRss(linkInfo->mRss);
+    router->SetLinkQualityOut(LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin));
     router->ResetLinkFailures();
     router->SetState(Neighbor::kStateValid);
     router->SetKeySequence(aKeySequence);
@@ -991,24 +1006,25 @@
 
     if (aRequest)
     {
-        ChallengeTlv  challenge;
-        TlvRequestTlv tlvRequest;
+        Challenge     challenge;
+        RequestedTlvs requestedTlvs;
 
         // Challenge
-        SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kChallenge, sizeof(challenge), challenge));
-        VerifyOrExit(challenge.IsValid(), error = OT_ERROR_PARSE);
+        SuccessOrExit(error = ReadChallenge(aMessage, challenge));
 
         // TLV Request
-        if (Tlv::GetTlv(aMessage, Tlv::kTlvRequest, sizeof(tlvRequest), tlvRequest) == OT_ERROR_NONE)
+        switch (FindTlvRequest(aMessage, requestedTlvs))
         {
-            VerifyOrExit(tlvRequest.IsValid(), error = OT_ERROR_PARSE);
-        }
-        else
-        {
-            tlvRequest.SetLength(0);
+        case OT_ERROR_NONE:
+            break;
+        case OT_ERROR_NOT_FOUND:
+            requestedTlvs.mNumTlvs = 0;
+            break;
+        default:
+            ExitNow(error = OT_ERROR_PARSE);
         }
 
-        SuccessOrExit(error = SendLinkAccept(aMessageInfo, router, tlvRequest, challenge));
+        SuccessOrExit(error = SendLinkAccept(aMessageInfo, router, requestedTlvs, challenge));
     }
 
 exit:
@@ -1048,8 +1064,8 @@
 
     router = mRouterTable.GetRouter(aRouterId);
 
-    // NULL aRouterId indicates non-existing next hop, hence return kMaxRouteCost for it.
-    VerifyOrExit(router != NULL);
+    // nullptr aRouterId indicates non-existing next hop, hence return kMaxRouteCost for it.
+    VerifyOrExit(router != nullptr, OT_NOOP);
 
     rval = mRouterTable.GetLinkCost(*router);
 
@@ -1073,11 +1089,11 @@
 {
     otError error = OT_ERROR_NONE;
 
-    mRouterTable.ProcessTlv(aRoute);
+    mRouterTable.UpdateRouterIdSet(aRoute.GetRouterIdSequence(), aRoute.GetRouterIdMask());
 
-    if (mRole == OT_DEVICE_ROLE_ROUTER && !mRouterTable.IsAllocated(mRouterId))
+    if (IsRouter() && !mRouterTable.IsAllocated(mRouterId))
     {
-        BecomeDetached();
+        IgnoreError(BecomeDetached());
         error = OT_ERROR_NO_ROUTE;
     }
 
@@ -1101,10 +1117,10 @@
     return rval;
 }
 
-int MleRouter::ComparePartitions(bool                 aSingletonA,
-                                 const LeaderDataTlv &aLeaderDataA,
-                                 bool                 aSingletonB,
-                                 const LeaderDataTlv &aLeaderDataB)
+int MleRouter::ComparePartitions(bool              aSingletonA,
+                                 const LeaderData &aLeaderDataA,
+                                 bool              aSingletonB,
+                                 const LeaderData &aLeaderDataB)
 {
     int rval = 0;
 
@@ -1158,27 +1174,25 @@
     otError                 error    = OT_ERROR_NONE;
     const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
     uint8_t linkMargin = LinkQualityInfo::ConvertRssToLinkMargin(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
-    Mac::ExtAddress  macAddr;
-    SourceAddressTlv sourceAddress;
-    LeaderDataTlv    leaderData;
-    RouteTlv         route;
-    uint32_t         partitionId;
-    Router *         router;
-    uint8_t          routerId;
-    uint8_t          routerCount;
+    Mac::ExtAddress extAddr;
+    uint16_t        sourceAddress = Mac::kShortAddrInvalid;
+    LeaderData      leaderData;
+    RouteTlv        route;
+    uint32_t        partitionId;
+    Router *        router;
+    uint8_t         routerId;
+    uint8_t         routerCount;
 
-    aMessageInfo.GetPeerAddr().ToExtAddress(macAddr);
+    aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr);
 
     // Source Address
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
-    VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress));
 
     // Leader Data
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
-    VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadLeaderData(aMessage, leaderData));
 
     // Route Data (optional)
-    if (Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE)
     {
         VerifyOrExit(route.IsValid(), error = OT_ERROR_PARSE);
     }
@@ -1192,8 +1206,7 @@
 
     if (partitionId != mLeaderData.GetPartitionId())
     {
-        otLogNoteMle("Different partition (peer:%u, local:%u)", leaderData.GetPartitionId(),
-                     mLeaderData.GetPartitionId());
+        otLogNoteMle("Different partition (peer:%u, local:%u)", partitionId, mLeaderData.GetPartitionId());
 
         VerifyOrExit(linkMargin >= OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN, error = OT_ERROR_LINK_MARGIN_LOW);
 
@@ -1204,7 +1217,7 @@
                          error = OT_ERROR_DROP);
         }
 
-        if (mRole == OT_DEVICE_ROLE_CHILD && (aNeighbor == &mParent || !IsFullThreadDevice()))
+        if (IsChild() && (aNeighbor == &mParent || !IsFullThreadDevice()))
         {
             ExitNow();
         }
@@ -1216,27 +1229,27 @@
 #endif
         )
         {
-            BecomeChild(kAttachBetter);
+            IgnoreError(BecomeChild(kAttachBetter));
         }
 
         ExitNow(error = OT_ERROR_DROP);
     }
     else if (leaderData.GetLeaderRouterId() != GetLeaderId())
     {
-        VerifyOrExit(aNeighbor && aNeighbor->IsStateValid());
+        VerifyOrExit(aNeighbor && aNeighbor->IsStateValid(), OT_NOOP);
 
-        if (mRole != OT_DEVICE_ROLE_CHILD)
+        if (!IsChild())
         {
             otLogInfoMle("Leader ID mismatch");
-            BecomeDetached();
+            IgnoreError(BecomeDetached());
             error = OT_ERROR_DROP;
         }
 
         ExitNow();
     }
 
-    VerifyOrExit(IsActiveRouter(sourceAddress.GetRloc16()) && route.IsValid());
-    routerId = RouterIdFromRloc16(sourceAddress.GetRloc16());
+    VerifyOrExit(IsActiveRouter(sourceAddress) && route.IsValid(), OT_NOOP);
+    routerId = RouterIdFromRloc16(sourceAddress);
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     Get<TimeSync>().HandleTimeSyncMessage(aMessage);
@@ -1250,12 +1263,12 @@
 
         switch (mRole)
         {
-        case OT_DEVICE_ROLE_DISABLED:
-        case OT_DEVICE_ROLE_DETACHED:
+        case kRoleDisabled:
+        case kRoleDetached:
             break;
 
-        case OT_DEVICE_ROLE_CHILD:
-            if (sourceAddress.GetRloc16() == mParent.GetRloc16())
+        case kRoleChild:
+            if (sourceAddress == mParent.GetRloc16())
             {
                 processRouteTlv = true;
             }
@@ -1263,7 +1276,7 @@
             {
                 router = mRouterTable.GetRouter(routerId);
 
-                if (router != NULL && router->IsStateValid())
+                if (router != nullptr && router->IsStateValid())
                 {
                     processRouteTlv = true;
                 }
@@ -1271,8 +1284,8 @@
 
             break;
 
-        case OT_DEVICE_ROLE_ROUTER:
-        case OT_DEVICE_ROLE_LEADER:
+        case kRoleRouter:
+        case kRoleLeader:
             processRouteTlv = true;
             break;
         }
@@ -1280,24 +1293,28 @@
         if (processRouteTlv)
         {
             SuccessOrExit(error = ProcessRouteTlv(route));
+            if (Get<RouterTable>().Contains(*aNeighbor))
+            {
+                aNeighbor = nullptr; // aNeighbor is no longer valid after `ProcessRouteTlv`
+            }
         }
     }
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDisabled:
+    case kRoleDetached:
         ExitNow();
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         if (aNeighbor == &mParent)
         {
             // MLE Advertisement from parent
             router = &mParent;
 
-            if (mParent.GetRloc16() != sourceAddress.GetRloc16())
+            if (mParent.GetRloc16() != sourceAddress)
             {
-                BecomeDetached();
+                IgnoreError(BecomeDetached());
                 ExitNow(error = OT_ERROR_NO_ROUTE);
             }
 
@@ -1314,7 +1331,7 @@
 
                 leader = mRouterTable.GetLeader();
 
-                if (leader != NULL)
+                if (leader != nullptr)
                 {
                     for (uint8_t id = 0, routeCount = 0; id <= kMaxRouterId; id++)
                     {
@@ -1349,18 +1366,18 @@
         {
             // MLE Advertisement not from parent, but from some other neighboring router
             router = mRouterTable.GetRouter(routerId);
-            VerifyOrExit(router != NULL);
+            VerifyOrExit(router != nullptr, OT_NOOP);
 
             if (IsFullThreadDevice() && !router->IsStateValid() && !router->IsStateLinkRequest() &&
                 (mRouterTable.GetActiveLinkCount() < OPENTHREAD_CONFIG_MLE_CHILD_ROUTER_LINKS))
             {
-                router->SetExtAddress(macAddr);
+                router->SetExtAddress(extAddr);
                 router->GetLinkInfo().Clear();
-                router->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
+                router->GetLinkInfo().AddRss(linkInfo->mRss);
                 router->ResetLinkFailures();
                 router->SetLastHeard(TimerMilli::GetNow());
                 router->SetState(Neighbor::kStateLinkRequest);
-                SendLinkRequest(router);
+                IgnoreError(SendLinkRequest(router));
                 ExitNow(error = OT_ERROR_NO_ROUTE);
             }
         }
@@ -1369,9 +1386,9 @@
 
         ExitNow();
 
-    case OT_DEVICE_ROLE_ROUTER:
+    case kRoleRouter:
         router = mRouterTable.GetRouter(routerId);
-        VerifyOrExit(router != NULL);
+        VerifyOrExit(router != nullptr, OT_NOOP);
 
         // check current active router number
         routerCount = 0;
@@ -1393,21 +1410,21 @@
 
         // fall through
 
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleLeader:
         router = mRouterTable.GetRouter(routerId);
-        VerifyOrExit(router != NULL);
+        VerifyOrExit(router != nullptr, OT_NOOP);
 
         // Send unicast link request if no link to router and no unicast/multicast link request in progress
         if (!router->IsStateValid() && !router->IsStateLinkRequest() && (mChallengeTimeout == 0) &&
             (linkMargin >= OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN))
         {
-            router->SetExtAddress(macAddr);
+            router->SetExtAddress(extAddr);
             router->GetLinkInfo().Clear();
-            router->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
+            router->GetLinkInfo().AddRss(linkInfo->mRss);
             router->ResetLinkFailures();
             router->SetLastHeard(TimerMilli::GetNow());
             router->SetState(Neighbor::kStateLinkRequest);
-            SendLinkRequest(router);
+            IgnoreError(SendLinkRequest(router));
             ExitNow(error = OT_ERROR_NO_ROUTE);
         }
 
@@ -1418,7 +1435,7 @@
     UpdateRoutes(route, routerId);
 
 exit:
-    if (aNeighbor && aNeighbor->GetRloc16() != sourceAddress.GetRloc16())
+    if (aNeighbor && aNeighbor->GetRloc16() != sourceAddress)
     {
         // Remove stale neighbors
         RemoveNeighbor(*aNeighbor);
@@ -1434,7 +1451,7 @@
     bool    changed          = false;
 
     neighbor = mRouterTable.GetRouter(aRouterId);
-    VerifyOrExit(neighbor != NULL);
+    VerifyOrExit(neighbor != nullptr, OT_NOOP);
 
     // update link quality out to neighbor
     changed = UpdateLinkQualityOut(aRoute, *neighbor, resetAdvInterval);
@@ -1454,7 +1471,7 @@
 
         router = mRouterTable.GetRouter(routerId);
 
-        if (router == NULL || router->GetRloc16() == GetRloc16() || router == neighbor)
+        if (router == nullptr || router->GetRloc16() == GetRloc16() || router == neighbor)
         {
             routeCount++;
             continue;
@@ -1470,13 +1487,13 @@
             cost = kMaxRouteCost;
         }
 
-        if (nextHop == NULL || nextHop == neighbor)
+        if (nextHop == nullptr || nextHop == neighbor)
         {
             // route has no next hop or next hop is neighbor (sender)
 
             if (cost + mRouterTable.GetLinkCost(*neighbor) < kMaxRouteCost)
             {
-                if (nextHop == NULL && mRouterTable.GetLinkCost(*router) >= kMaxRouteCost)
+                if (nextHop == nullptr && mRouterTable.GetLinkCost(*router) >= kMaxRouteCost)
                 {
                     resetAdvInterval = true;
                 }
@@ -1521,7 +1538,7 @@
 
 #if (OPENTHREAD_CONFIG_LOG_MLE && (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO))
 
-    VerifyOrExit(changed);
+    VerifyOrExit(changed, OT_NOOP);
     otLogInfoMle("Route table updated");
 
     for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++)
@@ -1553,7 +1570,7 @@
     Router *nextHop;
 
     myRouterId = RouterIdFromRloc16(GetRloc16());
-    VerifyOrExit(aRoute.IsRouterIdSet(myRouterId));
+    VerifyOrExit(aRoute.IsRouterIdSet(myRouterId), OT_NOOP);
 
     myRouteCount = 0;
     for (uint8_t routerId = 0; routerId < myRouterId; routerId++)
@@ -1562,7 +1579,7 @@
     }
 
     linkQuality = aRoute.GetLinkQualityIn(myRouteCount);
-    VerifyOrExit(aNeighbor.GetLinkQualityOut() != linkQuality);
+    VerifyOrExit(aNeighbor.GetLinkQualityOut() != linkQuality, OT_NOOP);
 
     oldLinkCost = mRouterTable.GetLinkCost(aNeighbor);
 
@@ -1570,7 +1587,7 @@
     nextHop = mRouterTable.GetRouter(aNeighbor.GetNextHop());
 
     // reset MLE advertisement timer if neighbor route cost changed to or from infinite
-    if (nextHop == NULL && (oldLinkCost >= kMaxRouteCost) != (mRouterTable.GetLinkCost(aNeighbor) >= kMaxRouteCost))
+    if (nextHop == nullptr && (oldLinkCost >= kMaxRouteCost) != (mRouterTable.GetLinkCost(aNeighbor) >= kMaxRouteCost))
     {
         aResetAdvInterval = true;
     }
@@ -1580,14 +1597,14 @@
     return changed;
 }
 
-otError MleRouter::HandleParentRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+void MleRouter::HandleParentRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError                 error    = OT_ERROR_NONE;
     const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
-    Mac::ExtAddress         macAddr;
-    VersionTlv              version;
-    ScanMaskTlv             scanMask;
-    ChallengeTlv            challenge;
+    Mac::ExtAddress         extAddr;
+    uint16_t                version;
+    uint8_t                 scanMask;
+    Challenge               challenge;
     Router *                leader;
     Child *                 child;
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
@@ -1598,10 +1615,10 @@
 
     VerifyOrExit(IsRouterEligible(), error = OT_ERROR_INVALID_STATE);
 
-    // A Router MUST NOT send an MLE Parent Response if:
+    // A Router/REED MUST NOT send an MLE Parent Response if:
 
     // 0. It is detached or attempting to another partition
-    VerifyOrExit((mRole != OT_DEVICE_ROLE_DETACHED) && !IsAttaching(), error = OT_ERROR_DROP);
+    VerifyOrExit(!IsDetached() && !IsAttaching(), error = OT_ERROR_DROP);
 
     // 1. It has no available Child capacity (if Max Child Count minus
     // Child Count would be equal to zero)
@@ -1614,57 +1631,60 @@
 
     // 3. Its current routing path cost to the Leader is infinite.
     leader = mRouterTable.GetLeader();
-    assert(leader != NULL);
+    OT_ASSERT(leader != nullptr);
 
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_LEADER || GetLinkCost(GetLeaderId()) < kMaxRouteCost ||
-                     (mRole == OT_DEVICE_ROLE_CHILD && leader->GetCost() + 1 < kMaxRouteCost) ||
+    VerifyOrExit(IsLeader() || GetLinkCost(GetLeaderId()) < kMaxRouteCost ||
+                     (IsChild() && leader->GetCost() + 1 < kMaxRouteCost) ||
                      (leader->GetCost() + GetLinkCost(leader->GetNextHop()) < kMaxRouteCost),
                  error = OT_ERROR_DROP);
 
-    aMessageInfo.GetPeerAddr().ToExtAddress(macAddr);
+    // 4. It is a REED and there are already `kMaxRouters` active routers in
+    // the network (because Leader would reject any further address solicit).
+    // ==> Verified below when checking the scan mask.
+
+    aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr);
 
     // Version
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kVersion, sizeof(version), version));
-    VerifyOrExit(version.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kVersion, version));
+    VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = OT_ERROR_PARSE);
 
     // Scan Mask
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kScanMask, sizeof(scanMask), scanMask));
-    VerifyOrExit(scanMask.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint8Tlv(aMessage, Tlv::kScanMask, scanMask));
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDisabled:
+    case kRoleDetached:
         ExitNow();
 
-    case OT_DEVICE_ROLE_CHILD:
-        VerifyOrExit(scanMask.IsEndDeviceFlagSet());
+    case kRoleChild:
+        VerifyOrExit(ScanMaskTlv::IsEndDeviceFlagSet(scanMask), OT_NOOP);
+        VerifyOrExit(mRouterTable.GetActiveRouterCount() < kMaxRouters, error = OT_ERROR_DROP);
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
-        VerifyOrExit(scanMask.IsRouterFlagSet());
+    case kRoleRouter:
+    case kRoleLeader:
+        VerifyOrExit(ScanMaskTlv::IsRouterFlagSet(scanMask), OT_NOOP);
         break;
     }
 
     // Challenge
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kChallenge, sizeof(challenge), challenge));
-    VerifyOrExit(challenge.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ReadChallenge(aMessage, challenge));
 
-    child = mChildTable.FindChild(macAddr, Child::kInStateAnyExceptInvalid);
+    child = mChildTable.FindChild(extAddr, Child::kInStateAnyExceptInvalid);
 
-    if (child == NULL)
+    if (child == nullptr)
     {
-        VerifyOrExit((child = mChildTable.GetNewChild()) != NULL);
+        VerifyOrExit((child = mChildTable.GetNewChild()) != nullptr, OT_NOOP);
 
         // MAC Address
-        child->SetExtAddress(macAddr);
+        child->SetExtAddress(extAddr);
         child->GetLinkInfo().Clear();
-        child->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
+        child->GetLinkInfo().AddRss(linkInfo->mRss);
         child->ResetLinkFailures();
         child->SetState(Neighbor::kStateParentRequest);
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-        if (Tlv::GetTlv(aMessage, Tlv::kTimeRequest, sizeof(timeRequest), timeRequest) == OT_ERROR_NONE)
+        if (Tlv::FindTlv(aMessage, Tlv::kTimeRequest, sizeof(timeRequest), timeRequest) == OT_ERROR_NONE)
         {
             child->SetTimeSyncEnabled(true);
         }
@@ -1685,7 +1705,7 @@
         child->SetTimeout(Time::MsecToSec(kMaxChildIdRequestTimeout));
     }
 
-    SendParentResponse(child, challenge, !scanMask.IsEndDeviceFlagSet());
+    SendParentResponse(child, challenge, !ScanMaskTlv::IsEndDeviceFlagSet(scanMask));
 
 exit:
 
@@ -1693,8 +1713,6 @@
     {
         otLogWarnMle("Failed to process Parent Request: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
 void MleRouter::HandleStateUpdateTimer(Timer &aTimer)
@@ -1706,7 +1724,7 @@
 {
     bool routerStateUpdate = false;
 
-    VerifyOrExit(IsFullThreadDevice());
+    VerifyOrExit(IsFullThreadDevice(), OT_NOOP);
 
     mStateUpdateTimer.Start(kStateUpdatePeriod);
 
@@ -1729,29 +1747,49 @@
             routerStateUpdate = true;
         }
     }
+#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    // Delay register only when `mRouterSelectionJitterTimeout` is 0,
+    // that is, when the device has decided to stay as REED or Router.
+    else if (mBackboneRouterRegistrationDelay > 0)
+    {
+        mBackboneRouterRegistrationDelay--;
+
+        if (mBackboneRouterRegistrationDelay == 0)
+        {
+            // If no Backbone Router service after jitter, try to register its own Backbone Router Service.
+            if (!Get<BackboneRouter::Leader>().HasPrimary())
+            {
+                if (Get<BackboneRouter::Local>().AddService() == OT_ERROR_NONE)
+                {
+                    Get<NetworkData::Notifier>().HandleServerDataUpdated();
+                }
+            }
+        }
+    }
+#endif
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-        assert(false);
-        break;
+    case kRoleDisabled:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
 
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDetached:
         if (mChallengeTimeout == 0)
         {
-            BecomeDetached();
+            IgnoreError(BecomeDetached());
             ExitNow();
         }
 
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         if (routerStateUpdate)
         {
             if (mRouterTable.GetActiveRouterCount() < mRouterUpgradeThreshold)
             {
                 // upgrade to Router
-                BecomeRouter(ThreadStatusTlv::kTooFewRouters);
+                IgnoreError(BecomeRouter(ThreadStatusTlv::kTooFewRouters));
             }
             else
             {
@@ -1773,33 +1811,32 @@
 
         // fall through
 
-    case OT_DEVICE_ROLE_ROUTER:
+    case kRoleRouter:
         // verify path to leader
         otLogDebgMle("network id timeout = %d", mRouterTable.GetLeaderAge());
 
         if ((mRouterTable.GetActiveRouterCount() > 0) && (mRouterTable.GetLeaderAge() >= mNetworkIdTimeout))
         {
             otLogInfoMle("Router ID Sequence timeout");
-            BecomeChild(kAttachSame1);
+            IgnoreError(BecomeChild(kAttachSame1));
         }
 
         if (routerStateUpdate && mRouterTable.GetActiveRouterCount() > mRouterDowngradeThreshold)
         {
             // downgrade to REED
             otLogNoteMle("Downgrade to REED");
-            BecomeChild(kAttachSameDowngrade);
+            IgnoreError(BecomeChild(kAttachSameDowngrade));
         }
 
         break;
 
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleLeader:
         break;
     }
 
     // update children state
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateAnyExceptInvalid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
     {
-        Child &  child   = *iter.GetChild();
         uint32_t timeout = 0;
 
         switch (child.GetState())
@@ -1817,8 +1854,8 @@
 
         case Neighbor::kStateParentResponse:
         case Neighbor::kStateLinkRequest:
-            assert(false);
-            break;
+            OT_ASSERT(false);
+            OT_UNREACHABLE_CODE(break);
         }
 
         if (TimerMilli::GetNow() - child.GetLastHeard() >= timeout)
@@ -1826,9 +1863,9 @@
             otLogInfoMle("Child timeout expired");
             RemoveNeighbor(child);
         }
-        else if ((mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER) && child.IsStateRestored())
+        else if (IsRouterOrLeader() && child.IsStateRestored())
         {
-            SendChildUpdateRequest(child);
+            IgnoreError(SendChildUpdateRequest(child));
         }
     }
 
@@ -1864,7 +1901,7 @@
                 if (age < Time::SecToMsec(kMaxNeighborAge) + kMaxTransmissionCount * kUnicastRetransmissionDelay)
                 {
                     otLogInfoMle("Router timeout expired");
-                    SendLinkRequest(&router);
+                    IgnoreError(SendLinkRequest(&router));
                 }
                 else
                 {
@@ -1885,13 +1922,13 @@
             }
         }
 
-        if (GetRole() == OT_DEVICE_ROLE_LEADER)
+        if (IsLeader())
         {
-            if (mRouterTable.GetRouter(router.GetNextHop()) == NULL &&
+            if (mRouterTable.GetRouter(router.GetNextHop()) == nullptr &&
                 mRouterTable.GetLinkCost(router) >= kMaxRouteCost && age >= Time::SecToMsec(kMaxLeaderToRouterTimeout))
             {
                 otLogInfoMle("Router ID timeout expired (no route)");
-                mRouterTable.Release(router.GetRouterId());
+                IgnoreError(mRouterTable.Release(router.GetRouterId()));
             }
         }
     }
@@ -1901,7 +1938,7 @@
     SynchronizeChildNetworkData();
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    if (mRole == OT_DEVICE_ROLE_LEADER || mRole == OT_DEVICE_ROLE_ROUTER)
+    if (IsRouterOrLeader())
     {
         Get<TimeSync>().ProcessTimeSync();
     }
@@ -1911,14 +1948,14 @@
     return;
 }
 
-void MleRouter::SendParentResponse(Child *aChild, const ChallengeTlv &aChallenge, bool aRoutersOnlyRequest)
+void MleRouter::SendParentResponse(Child *aChild, const Challenge &aChallenge, bool aRoutersOnlyRequest)
 {
     otError      error = OT_ERROR_NONE;
     Ip6::Address destination;
     Message *    message;
     uint16_t     delay;
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     message->SetDirectTransmission();
 
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandParentResponse));
@@ -1926,7 +1963,7 @@
     SuccessOrExit(error = AppendLeaderData(*message));
     SuccessOrExit(error = AppendLinkFrameCounter(*message));
     SuccessOrExit(error = AppendMleFrameCounter(*message));
-    SuccessOrExit(error = AppendResponse(*message, aChallenge.GetChallenge(), aChallenge.GetChallengeLength()));
+    SuccessOrExit(error = AppendResponse(*message, aChallenge));
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     if (aChild->IsTimeSyncEnabled())
     {
@@ -1937,15 +1974,13 @@
     aChild->GenerateChallenge();
 
     SuccessOrExit(error = AppendChallenge(*message, aChild->GetChallenge(), aChild->GetChallengeSize()));
-    error = AppendLinkMargin(*message, aChild->GetLinkInfo().GetLinkMargin(Get<Mac::Mac>().GetNoiseFloor()));
+    error = AppendLinkMargin(*message, aChild->GetLinkInfo().GetLinkMargin());
     SuccessOrExit(error);
 
     SuccessOrExit(error = AppendConnectivity(*message));
     SuccessOrExit(error = AppendVersion(*message));
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xfe80);
-    destination.SetIid(aChild->GetExtAddress());
+    destination.SetToLinkLocalAddress(aChild->GetExtAddress());
 
     if (aRoutersOnlyRequest)
     {
@@ -1962,12 +1997,40 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
 }
 
+uint8_t MleRouter::GetMaxChildIpAddresses(void) const
+{
+    uint8_t num = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD;
+
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
+    if (mMaxChildIpAddresses != 0)
+    {
+        num = mMaxChildIpAddresses;
+    }
+#endif
+
+    return num;
+}
+
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
+otError MleRouter::SetMaxChildIpAddresses(uint8_t aMaxIpAddresses)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(aMaxIpAddresses <= OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD, error = OT_ERROR_INVALID_ARGS);
+
+    mMaxChildIpAddresses = aMaxIpAddresses;
+
+exit:
+    return error;
+}
+#endif
+
 otError MleRouter::UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, Child &aChild)
 {
     otError                  error = OT_ERROR_NONE;
@@ -2015,13 +2078,23 @@
         }
         else
         {
-            address = *entry.GetIp6Address();
+            address = entry.GetIp6Address();
         }
 
-        // We try to accept/add as many IPv6 addresses as possible.
-        // "Child ID/Update Response" will indicate the accepted
-        // addresses.
-        error = aChild.AddIp6Address(GetInstance(), address);
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
+        if (mMaxChildIpAddresses > 0 && storedCount >= mMaxChildIpAddresses)
+        {
+            // Skip remaining address registration entries but keep logging skipped addresses.
+            error = OT_ERROR_NO_BUFS;
+        }
+        else
+#endif
+        {
+            // We try to accept/add as many IPv6 addresses as possible.
+            // "Child ID/Update Response" will indicate the accepted
+            // addresses.
+            error = aChild.AddIp6Address(address);
+        }
 
         if (error == OT_ERROR_NONE)
         {
@@ -2050,14 +2123,14 @@
         // table is timed out and then trying to register its globally unique
         // IPv6 address as the new child.
 
-        for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone(); iter++)
+        for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
         {
-            if (iter.GetChild() == &aChild)
+            if (&child == &aChild)
             {
                 continue;
             }
 
-            IgnoreReturnValue(iter.GetChild()->RemoveIp6Address(GetInstance(), address));
+            IgnoreError(child.RemoveIp6Address(address));
         }
 
         // Clear EID-to-RLOC cache for the unicast address registered by the child.
@@ -2080,19 +2153,21 @@
     return error;
 }
 
-otError MleRouter::HandleChildIdRequest(const Message &         aMessage,
-                                        const Ip6::MessageInfo &aMessageInfo,
-                                        uint32_t                aKeySequence)
+void MleRouter::HandleChildIdRequest(const Message &         aMessage,
+                                     const Ip6::MessageInfo &aMessageInfo,
+                                     uint32_t                aKeySequence)
 {
     otError                 error    = OT_ERROR_NONE;
     const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
-    Mac::ExtAddress         macAddr;
-    ResponseTlv             response;
-    LinkFrameCounterTlv     linkFrameCounter;
-    MleFrameCounterTlv      mleFrameCounter;
-    ModeTlv                 mode;
-    TimeoutTlv              timeout;
-    TlvRequestTlv           tlvRequest;
+    Mac::ExtAddress         extAddr;
+    uint16_t                version;
+    Challenge               response;
+    uint32_t                linkFrameCounter;
+    uint32_t                mleFrameCounter;
+    uint8_t                 modeBitmask;
+    DeviceMode              mode;
+    uint32_t                timeout;
+    RequestedTlvs           requestedTlvs;
     ActiveTimestampTlv      activeTimestamp;
     PendingTimestampTlv     pendingTimestamp;
     Child *                 child;
@@ -2108,16 +2183,18 @@
     VerifyOrExit(IsAttached(), error = OT_ERROR_INVALID_STATE);
 
     // Find Child
-    aMessageInfo.GetPeerAddr().ToExtAddress(macAddr);
+    aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr);
 
-    child = mChildTable.FindChild(macAddr, Child::kInStateAnyExceptInvalid);
-    VerifyOrExit(child != NULL, error = OT_ERROR_ALREADY);
+    child = mChildTable.FindChild(extAddr, Child::kInStateAnyExceptInvalid);
+    VerifyOrExit(child != nullptr, error = OT_ERROR_ALREADY);
+
+    // Version
+    SuccessOrExit(error = Tlv::FindUint16Tlv(aMessage, Tlv::kVersion, version));
+    VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = OT_ERROR_PARSE);
 
     // Response
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kResponse, sizeof(response), response));
-    VerifyOrExit(response.IsValid() &&
-                     memcmp(response.GetResponse(), child->GetChallenge(), child->GetChallengeSize()) == 0,
-                 error = OT_ERROR_SECURITY);
+    SuccessOrExit(error = ReadResponse(aMessage, response));
+    VerifyOrExit(response.Matches(child->GetChallenge(), child->GetChallengeSize()), error = OT_ERROR_SECURITY);
 
     // Remove existing MLE messages
     Get<MeshForwarder>().RemoveMessages(*child, Message::kSubTypeMleGeneral);
@@ -2126,35 +2203,35 @@
     Get<MeshForwarder>().RemoveMessages(*child, Message::kSubTypeMleDataResponse);
 
     // Link-Layer Frame Counter
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLinkFrameCounter, sizeof(linkFrameCounter), linkFrameCounter));
-    VerifyOrExit(linkFrameCounter.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint32Tlv(aMessage, Tlv::kLinkFrameCounter, linkFrameCounter));
 
     // MLE Frame Counter
-    if (Tlv::GetTlv(aMessage, Tlv::kMleFrameCounter, sizeof(mleFrameCounter), mleFrameCounter) == OT_ERROR_NONE)
+    switch (Tlv::FindUint32Tlv(aMessage, Tlv::kMleFrameCounter, mleFrameCounter))
     {
-        VerifyOrExit(mleFrameCounter.IsValid(), error = OT_ERROR_PARSE);
-    }
-    else
-    {
-        mleFrameCounter.SetFrameCounter(linkFrameCounter.GetFrameCounter());
+    case OT_ERROR_NONE:
+        break;
+    case OT_ERROR_NOT_FOUND:
+        mleFrameCounter = linkFrameCounter;
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // Mode
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kMode, sizeof(mode), mode));
-    VerifyOrExit(mode.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint8Tlv(aMessage, Tlv::kMode, modeBitmask));
+    mode.Set(modeBitmask);
 
     // Timeout
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kTimeout, sizeof(timeout), timeout));
-    VerifyOrExit(timeout.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint32Tlv(aMessage, Tlv::kTimeout, timeout));
 
     // TLV Request
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kTlvRequest, sizeof(tlvRequest), tlvRequest));
-    VerifyOrExit(tlvRequest.IsValid() && tlvRequest.GetLength() <= Child::kMaxRequestTlvs, error = OT_ERROR_PARSE);
+    SuccessOrExit(error = FindTlvRequest(aMessage, requestedTlvs));
+    VerifyOrExit(requestedTlvs.mNumTlvs <= Child::kMaxRequestTlvs, error = OT_ERROR_PARSE);
 
     // Active Timestamp
     activeTimestamp.SetLength(0);
 
-    if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
     {
         VerifyOrExit(activeTimestamp.IsValid(), error = OT_ERROR_PARSE);
     }
@@ -2162,21 +2239,22 @@
     // Pending Timestamp
     pendingTimestamp.SetLength(0);
 
-    if (Tlv::GetTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
     {
         VerifyOrExit(pendingTimestamp.IsValid(), error = OT_ERROR_PARSE);
     }
 
-    if (!mode.GetMode().IsFullThreadDevice())
+    if (!mode.IsFullThreadDevice())
     {
-        SuccessOrExit(error = Tlv::GetOffset(aMessage, Tlv::kAddressRegistration, addressRegistrationOffset));
+        SuccessOrExit(error = Tlv::FindTlvOffset(aMessage, Tlv::kAddressRegistration, addressRegistrationOffset));
         SuccessOrExit(error = UpdateChildAddresses(aMessage, addressRegistrationOffset, *child));
     }
 
     // Remove from router table
-    router = mRouterTable.GetRouter(macAddr);
-    if (router != NULL)
+    router = mRouterTable.GetRouter(extAddr);
+    if (router != nullptr)
     {
+        // The `router` here can be invalid
         RemoveNeighbor(*router);
     }
 
@@ -2190,14 +2268,15 @@
     }
 
     child->SetLastHeard(TimerMilli::GetNow());
-    child->SetLinkFrameCounter(linkFrameCounter.GetFrameCounter());
-    child->SetMleFrameCounter(mleFrameCounter.GetFrameCounter());
+    child->SetLinkFrameCounter(linkFrameCounter);
+    child->SetMleFrameCounter(mleFrameCounter);
     child->SetKeySequence(aKeySequence);
-    child->SetDeviceMode(mode.GetMode());
-    child->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
-    child->SetTimeout(timeout.GetTimeout());
+    child->SetDeviceMode(mode);
+    child->SetVersion(static_cast<uint8_t>(version));
+    child->GetLinkInfo().AddRss(linkInfo->mRss);
+    child->SetTimeout(timeout);
 
-    if (mode.GetMode().IsFullNetworkData())
+    if (mode.IsFullNetworkData())
     {
         child->SetNetworkDataVersion(mLeaderData.GetDataVersion());
     }
@@ -2208,9 +2287,9 @@
 
     child->ClearRequestTlvs();
 
-    for (numTlvs = 0; numTlvs < tlvRequest.GetLength(); numTlvs++)
+    for (numTlvs = 0; numTlvs < requestedTlvs.mNumTlvs; numTlvs++)
     {
-        child->SetRequestTlv(numTlvs, tlvRequest.GetTlvs()[numTlvs]);
+        child->SetRequestTlv(numTlvs, requestedTlvs.mTlvs[numTlvs]);
     }
 
     if (activeTimestamp.GetLength() == 0 || Get<MeshCoP::ActiveDataset>().Compare(activeTimestamp) != 0)
@@ -2225,18 +2304,18 @@
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
-        assert(false);
-        break;
+    case kRoleDisabled:
+    case kRoleDetached:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         child->SetState(Neighbor::kStateChildIdRequest);
-        BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest);
+        IgnoreError(BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest));
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleRouter:
+    case kRoleLeader:
         SuccessOrExit(error = SendChildIdResponse(*child));
         break;
     }
@@ -2247,25 +2326,24 @@
     {
         otLogWarnMle("Failed to process Child ID Request: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError MleRouter::HandleChildUpdateRequest(const Message &         aMessage,
-                                            const Ip6::MessageInfo &aMessageInfo,
-                                            uint32_t                aKeySequence)
+void MleRouter::HandleChildUpdateRequest(const Message &         aMessage,
+                                         const Ip6::MessageInfo &aMessageInfo,
+                                         uint32_t                aKeySequence)
 {
     static const uint8_t kMaxResponseTlvs = 10;
 
     otError         error = OT_ERROR_NONE;
-    Mac::ExtAddress macAddr;
-    ModeTlv         mode;
-    ChallengeTlv    challenge;
-    LeaderDataTlv   leaderData;
-    TimeoutTlv      timeout;
+    Mac::ExtAddress extAddr;
+    uint8_t         modeBitmask;
+    DeviceMode      mode;
+    Challenge       challenge;
+    LeaderData      leaderData;
+    uint32_t        timeout;
     Child *         child;
     DeviceMode      oldMode;
-    TlvRequestTlv   tlvRequest;
+    RequestedTlvs   requestedTlvs;
     uint8_t         tlvs[kMaxResponseTlvs];
     uint8_t         tlvslength                = 0;
     uint16_t        addressRegistrationOffset = 0;
@@ -2274,95 +2352,111 @@
     LogMleMessage("Receive Child Update Request from child", aMessageInfo.GetPeerAddr());
 
     // Mode
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kMode, sizeof(mode), mode));
-    VerifyOrExit(mode.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint8Tlv(aMessage, Tlv::kMode, modeBitmask));
+    mode.Set(modeBitmask);
 
     // Challenge
-    challenge.SetLength(0);
-    if (Tlv::GetTlv(aMessage, Tlv::kChallenge, sizeof(challenge), challenge) == OT_ERROR_NONE)
+    switch (ReadChallenge(aMessage, challenge))
     {
-        VerifyOrExit(challenge.IsValid(), error = OT_ERROR_PARSE);
+    case OT_ERROR_NONE:
         tlvs[tlvslength++] = Tlv::kResponse;
+        break;
+    case OT_ERROR_NOT_FOUND:
+        challenge.mLength = 0;
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // Find Child
-    aMessageInfo.GetPeerAddr().ToExtAddress(macAddr);
-    child = mChildTable.FindChild(macAddr, Child::kInStateAnyExceptInvalid);
+    aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddr);
+    child = mChildTable.FindChild(extAddr, Child::kInStateAnyExceptInvalid);
 
     tlvs[tlvslength++] = Tlv::kSourceAddress;
 
     // Not proceed if the Child Update Request is from the peer which is not the device's child or
     // which was the device's child but becomes invalid.
-    if (child == NULL || child->IsStateInvalid())
+    if (child == nullptr || child->IsStateInvalid())
     {
         // For invalid non-sleepy child, Send Child Update Response with status TLV (error)
-        if (mode.GetMode().IsRxOnWhenIdle())
+        if (mode.IsRxOnWhenIdle())
         {
             tlvs[tlvslength++] = Tlv::kStatus;
-            SendChildUpdateResponse(NULL, aMessageInfo, tlvs, tlvslength, challenge);
+            SendChildUpdateResponse(nullptr, aMessageInfo, tlvs, tlvslength, challenge);
         }
 
         ExitNow();
     }
 
     oldMode = child->GetDeviceMode();
-    child->SetDeviceMode(mode.GetMode());
+    child->SetDeviceMode(mode);
 
     tlvs[tlvslength++] = Tlv::kMode;
 
     // Parent MUST include Leader Data TLV in Child Update Response
     tlvs[tlvslength++] = Tlv::kLeaderData;
 
-    if (challenge.IsValid())
+    if (challenge.mLength != 0)
     {
         tlvs[tlvslength++] = Tlv::kMleFrameCounter;
         tlvs[tlvslength++] = Tlv::kLinkFrameCounter;
     }
 
     // Ip6 Address TLV
-    if (Tlv::GetOffset(aMessage, Tlv::kAddressRegistration, addressRegistrationOffset) == OT_ERROR_NONE)
+    if (Tlv::FindTlvOffset(aMessage, Tlv::kAddressRegistration, addressRegistrationOffset) == OT_ERROR_NONE)
     {
         SuccessOrExit(error = UpdateChildAddresses(aMessage, addressRegistrationOffset, *child));
         tlvs[tlvslength++] = Tlv::kAddressRegistration;
     }
 
     // Leader Data
-    if (Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData) == OT_ERROR_NONE)
+    switch (ReadLeaderData(aMessage, leaderData))
     {
-        VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+    case OT_ERROR_NONE:
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // Timeout
-    if (Tlv::GetTlv(aMessage, Tlv::kTimeout, sizeof(timeout), timeout) == OT_ERROR_NONE)
+    switch (Tlv::FindUint32Tlv(aMessage, Tlv::kTimeout, timeout))
     {
-        VerifyOrExit(timeout.IsValid(), error = OT_ERROR_PARSE);
-
-        if (child->GetTimeout() != timeout.GetTimeout())
+    case OT_ERROR_NONE:
+        if (child->GetTimeout() != timeout)
         {
-            child->SetTimeout(timeout.GetTimeout());
+            child->SetTimeout(timeout);
             childDidChange = true;
         }
 
         tlvs[tlvslength++] = Tlv::kTimeout;
+        break;
+
+    case OT_ERROR_NOT_FOUND:
+        break;
+
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // TLV Request
-    if (Tlv::GetTlv(aMessage, Tlv::kTlvRequest, sizeof(tlvRequest), tlvRequest) == OT_ERROR_NONE)
+    switch (FindTlvRequest(aMessage, requestedTlvs))
     {
-        uint8_t            tlv;
-        TlvRequestIterator iterator = TLVREQUESTTLV_ITERATOR_INIT;
-
-        VerifyOrExit(tlvRequest.IsValid() && tlvRequest.GetLength() <= (kMaxResponseTlvs - tlvslength),
-                     error = OT_ERROR_PARSE);
-
-        while (tlvRequest.GetNextTlv(iterator, tlv) == OT_ERROR_NONE)
+    case OT_ERROR_NONE:
+        VerifyOrExit(requestedTlvs.mNumTlvs <= (kMaxResponseTlvs - tlvslength), error = OT_ERROR_PARSE);
+        for (uint8_t i = 0; i < requestedTlvs.mNumTlvs; i++)
         {
-            // Here skips Tlv::kLeaderData because it has already been included by default
-            if (tlv != Tlv::kLeaderData)
+            // Skip LeaderDataTlv since it is already included by default.
+            if (requestedTlvs.mTlvs[i] != Tlv::kLeaderData)
             {
-                tlvs[tlvslength++] = tlv;
+                tlvs[tlvslength++] = requestedTlvs.mTlvs[i];
             }
         }
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     child->SetLastHeard(TimerMilli::GetNow());
@@ -2391,7 +2485,7 @@
     {
         if (childDidChange)
         {
-            StoreChild(*child);
+            IgnoreError(StoreChild(*child));
         }
     }
 
@@ -2403,28 +2497,26 @@
     {
         otLogWarnMle("Failed to process Child Update Request from child: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError MleRouter::HandleChildUpdateResponse(const Message &         aMessage,
-                                             const Ip6::MessageInfo &aMessageInfo,
-                                             uint32_t                aKeySequence,
-                                             Neighbor *              aNeighbor)
+void MleRouter::HandleChildUpdateResponse(const Message &         aMessage,
+                                          const Ip6::MessageInfo &aMessageInfo,
+                                          uint32_t                aKeySequence,
+                                          Neighbor *              aNeighbor)
 {
     otError                 error    = OT_ERROR_NONE;
     const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
-    SourceAddressTlv        sourceAddress;
-    TimeoutTlv              timeout;
-    ResponseTlv             response;
-    StatusTlv               status;
-    LinkFrameCounterTlv     linkFrameCounter;
-    MleFrameCounterTlv      mleFrameCounter;
-    LeaderDataTlv           leaderData;
+    uint16_t                sourceAddress;
+    uint32_t                timeout;
+    Challenge               response;
+    uint8_t                 status;
+    uint32_t                linkFrameCounter;
+    uint32_t                mleFrameCounter;
+    LeaderData              leaderData;
     Child *                 child;
     uint16_t                addressRegistrationOffset = 0;
 
-    if ((aNeighbor == NULL) || IsActiveRouter(aNeighbor->GetRloc16()))
+    if ((aNeighbor == nullptr) || IsActiveRouter(aNeighbor->GetRloc16()))
     {
         LogMleMessage("Receive Child Update Response from unknown child", aMessageInfo.GetPeerAddr());
         ExitNow(error = OT_ERROR_NOT_FOUND);
@@ -2433,75 +2525,98 @@
     child = static_cast<Child *>(aNeighbor);
 
     // Response
-    if (Tlv::GetTlv(aMessage, Tlv::kResponse, sizeof(response), response) == OT_ERROR_NONE)
+    switch (ReadResponse(aMessage, response))
     {
-        VerifyOrExit(response.IsValid() &&
-                         memcmp(response.GetResponse(), child->GetChallenge(), child->GetChallengeSize()) == 0,
-                     error = OT_ERROR_SECURITY);
-    }
-    else
-    {
+    case OT_ERROR_NONE:
+        VerifyOrExit(response.Matches(child->GetChallenge(), child->GetChallengeSize()), error = OT_ERROR_SECURITY);
+        break;
+    case OT_ERROR_NOT_FOUND:
         VerifyOrExit(child->IsStateValid(), error = OT_ERROR_SECURITY);
+        break;
+    default:
+        ExitNow(error = OT_ERROR_NONE);
     }
 
     LogMleMessage("Receive Child Update Response from child", aMessageInfo.GetPeerAddr(), child->GetRloc16());
 
     // Source Address
-    if (Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress) == OT_ERROR_NONE)
+    switch (Tlv::FindUint16Tlv(aMessage, Tlv::kSourceAddress, sourceAddress))
     {
-        VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
-
-        if (child->GetRloc16() != sourceAddress.GetRloc16())
+    case OT_ERROR_NONE:
+        if (child->GetRloc16() != sourceAddress)
         {
             RemoveNeighbor(*child);
             ExitNow();
         }
+
+        break;
+
+    case OT_ERROR_NOT_FOUND:
+        break;
+
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // Status
-    if (Tlv::GetTlv(aMessage, Tlv::kStatus, sizeof(status), status) == OT_ERROR_NONE)
+    switch (Tlv::FindUint8Tlv(aMessage, Tlv::kStatus, status))
     {
-        VerifyOrExit(status.IsValid(), error = OT_ERROR_PARSE);
-
-        if (status.GetStatus() == StatusTlv::kError)
-        {
-            RemoveNeighbor(*child);
-            ExitNow();
-        }
+    case OT_ERROR_NONE:
+        VerifyOrExit(status != StatusTlv::kError, RemoveNeighbor(*child));
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // Link-Layer Frame Counter
-    if (Tlv::GetTlv(aMessage, Tlv::kLinkFrameCounter, sizeof(linkFrameCounter), linkFrameCounter) == OT_ERROR_NONE)
+
+    switch (Tlv::FindUint32Tlv(aMessage, Tlv::kLinkFrameCounter, linkFrameCounter))
     {
-        VerifyOrExit(linkFrameCounter.IsValid(), error = OT_ERROR_PARSE);
-        child->SetLinkFrameCounter(linkFrameCounter.GetFrameCounter());
+    case OT_ERROR_NONE:
+        child->SetLinkFrameCounter(linkFrameCounter);
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // MLE Frame Counter
-    if (Tlv::GetTlv(aMessage, Tlv::kMleFrameCounter, sizeof(mleFrameCounter), mleFrameCounter) == OT_ERROR_NONE)
+    switch (Tlv::FindUint32Tlv(aMessage, Tlv::kMleFrameCounter, mleFrameCounter))
     {
-        VerifyOrExit(mleFrameCounter.IsValid(), error = OT_ERROR_PARSE);
-        child->SetMleFrameCounter(mleFrameCounter.GetFrameCounter());
+    case OT_ERROR_NONE:
+        child->SetMleFrameCounter(mleFrameCounter);
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_NONE);
     }
 
     // Timeout
-    if (Tlv::GetTlv(aMessage, Tlv::kTimeout, sizeof(timeout), timeout) == OT_ERROR_NONE)
+    switch (Tlv::FindUint32Tlv(aMessage, Tlv::kTimeout, timeout))
     {
-        VerifyOrExit(timeout.IsValid(), error = OT_ERROR_PARSE);
-        child->SetTimeout(timeout.GetTimeout());
+    case OT_ERROR_NONE:
+        child->SetTimeout(timeout);
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // Ip6 Address
-    if (Tlv::GetOffset(aMessage, Tlv::kAddressRegistration, addressRegistrationOffset) == OT_ERROR_NONE)
+    if (Tlv::FindTlvOffset(aMessage, Tlv::kAddressRegistration, addressRegistrationOffset) == OT_ERROR_NONE)
     {
         SuccessOrExit(error = UpdateChildAddresses(aMessage, addressRegistrationOffset, *child));
     }
 
     // Leader Data
-    if (Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData) == OT_ERROR_NONE)
+    switch (ReadLeaderData(aMessage, leaderData))
     {
-        VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
-
+    case OT_ERROR_NONE:
         if (child->IsFullNetworkData())
         {
             child->SetNetworkDataVersion(leaderData.GetDataVersion());
@@ -2510,12 +2625,17 @@
         {
             child->SetNetworkDataVersion(leaderData.GetStableDataVersion());
         }
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     SetChildStateToValid(*child);
     child->SetLastHeard(TimerMilli::GetNow());
     child->SetKeySequence(aKeySequence);
-    child->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
+    child->GetLinkInfo().AddRss(linkInfo->mRss);
 
 exit:
 
@@ -2523,16 +2643,14 @@
     {
         otLogWarnMle("Failed to process Child Update Response from child: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
-otError MleRouter::HandleDataRequest(const Message &         aMessage,
-                                     const Ip6::MessageInfo &aMessageInfo,
-                                     const Neighbor *        aNeighbor)
+void MleRouter::HandleDataRequest(const Message &         aMessage,
+                                  const Ip6::MessageInfo &aMessageInfo,
+                                  const Neighbor *        aNeighbor)
 {
     otError             error = OT_ERROR_NONE;
-    TlvRequestTlv       tlvRequest;
+    RequestedTlvs       requestedTlvs;
     ActiveTimestampTlv  activeTimestamp;
     PendingTimestampTlv pendingTimestamp;
     uint8_t             tlvs[4];
@@ -2543,13 +2661,13 @@
     VerifyOrExit(aNeighbor && aNeighbor->IsStateValid(), error = OT_ERROR_SECURITY);
 
     // TLV Request
-    SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kTlvRequest, sizeof(tlvRequest), tlvRequest));
-    VerifyOrExit(tlvRequest.IsValid() && tlvRequest.GetLength() <= sizeof(tlvs), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = FindTlvRequest(aMessage, requestedTlvs));
+    VerifyOrExit(requestedTlvs.mNumTlvs <= sizeof(tlvs), error = OT_ERROR_PARSE);
 
     // Active Timestamp
     activeTimestamp.SetLength(0);
 
-    if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
     {
         VerifyOrExit(activeTimestamp.IsValid(), error = OT_ERROR_PARSE);
     }
@@ -2557,14 +2675,14 @@
     // Pending Timestamp
     pendingTimestamp.SetLength(0);
 
-    if (Tlv::GetTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
+    if (Tlv::FindTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp) == OT_ERROR_NONE)
     {
         VerifyOrExit(pendingTimestamp.IsValid(), error = OT_ERROR_PARSE);
     }
 
     memset(tlvs, Tlv::kInvalid, sizeof(tlvs));
-    memcpy(tlvs, tlvRequest.GetTlvs(), tlvRequest.GetLength());
-    numTlvs = tlvRequest.GetLength();
+    memcpy(tlvs, requestedTlvs.mTlvs, requestedTlvs.mNumTlvs);
+    numTlvs = requestedTlvs.mNumTlvs;
 
     if (activeTimestamp.GetLength() == 0 || Get<MeshCoP::ActiveDataset>().Compare(activeTimestamp))
     {
@@ -2584,8 +2702,6 @@
     {
         otLogWarnMle("Failed to process Data Request: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
 void MleRouter::HandleNetworkDataUpdateRouter(void)
@@ -2594,14 +2710,11 @@
     Ip6::Address         destination;
     uint16_t             delay;
 
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER);
+    VerifyOrExit(IsRouterOrLeader(), OT_NOOP);
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xff02);
-    destination.mFields.m16[7] = HostSwap16(0x0001);
+    destination.SetToLinkLocalAllNodesMulticast();
 
-    delay =
-        (mRole == OT_DEVICE_ROLE_LEADER) ? 0 : Random::NonCrypto::GetUint16InRange(0, kUnsolicitedDataResponseJitter);
+    delay = IsLeader() ? 0 : Random::NonCrypto::GetUint16InRange(0, kUnsolicitedDataResponseJitter);
     SendDataResponse(destination, tlvs, sizeof(tlvs), delay);
 
     SynchronizeChildNetworkData();
@@ -2612,11 +2725,10 @@
 
 void MleRouter::SynchronizeChildNetworkData(void)
 {
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER);
+    VerifyOrExit(IsRouterOrLeader(), OT_NOOP);
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
     {
-        Child & child = *iter.GetChild();
         uint8_t version;
 
         if (child.IsRxOnWhenIdle())
@@ -2654,38 +2766,32 @@
     nullExtAddr.Clear();
     allowAnyExtAddr.Fill(0xff);
 
-    mSteeringData.Init();
-
-    if ((aExtAddress == NULL) || (*aExtAddress == nullExtAddr))
+    if ((aExtAddress == nullptr) || (*aExtAddress == nullExtAddr))
     {
-        // Clear steering data
         mSteeringData.Clear();
     }
     else if (*aExtAddress == allowAnyExtAddr)
     {
-        // Set steering data to 0xFF
-        mSteeringData.SetLength(1);
-        mSteeringData.Set();
+        mSteeringData.SetToPermitAllJoiners();
     }
     else
     {
         Mac::ExtAddress joinerId;
 
-        // compute Joiner ID
+        mSteeringData.Init();
         MeshCoP::ComputeJoinerId(*aExtAddress, joinerId);
-        // compute Bloom Filter
-        mSteeringData.ComputeBloomFilter(joinerId);
+        mSteeringData.UpdateBloomFilter(joinerId);
     }
 }
 #endif // OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
 
-otError MleRouter::HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+void MleRouter::HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError                      error = OT_ERROR_NONE;
     Tlv                          tlv;
     MeshCoP::Tlv                 meshcopTlv;
     MeshCoP::DiscoveryRequestTlv discoveryRequest;
-    MeshCoP::ExtendedPanIdTlv    extPanId;
+    Mac::ExtendedPanId           extPanId;
     uint16_t                     offset;
     uint16_t                     end;
 
@@ -2695,7 +2801,7 @@
     VerifyOrExit(IsRouterEligible(), error = OT_ERROR_INVALID_STATE);
 
     // find MLE Discovery TLV
-    VerifyOrExit(Tlv::GetOffset(aMessage, Tlv::kDiscovery, offset) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
+    VerifyOrExit(Tlv::FindTlvOffset(aMessage, Tlv::kDiscovery, offset) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
     aMessage.Read(offset, sizeof(tlv), &tlv);
 
     offset += sizeof(tlv);
@@ -2714,24 +2820,22 @@
             if (discoveryRequest.IsJoiner())
             {
 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
-
-                if (!mSteeringData.IsCleared())
+                if (!mSteeringData.IsEmpty())
                 {
                     break;
                 }
                 else // if steering data is not set out of band, fall back to network data
-#endif               // OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
+#endif
                 {
-                    VerifyOrExit(Get<NetworkData::Leader>().IsJoiningEnabled());
+                    VerifyOrExit(Get<NetworkData::Leader>().IsJoiningEnabled(), error = OT_ERROR_SECURITY);
                 }
             }
 
             break;
 
         case MeshCoP::Tlv::kExtendedPanId:
-            aMessage.Read(offset, sizeof(extPanId), &extPanId);
-            VerifyOrExit(extPanId.IsValid(), error = OT_ERROR_PARSE);
-            VerifyOrExit(memcmp(&Get<Mac::Mac>().GetExtendedPanId(), &extPanId.GetExtendedPanId(), OT_EXT_PAN_ID_SIZE));
+            SuccessOrExit(error = Tlv::ReadTlv(aMessage, offset, &extPanId, sizeof(extPanId)));
+            VerifyOrExit(Get<Mac::Mac>().GetExtendedPanId() != extPanId, error = OT_ERROR_DROP);
 
             break;
 
@@ -2750,8 +2854,6 @@
     {
         otLogWarnMle("Failed to process Discovery Request: %s", otThreadErrorToString(error));
     }
-
-    return error;
 }
 
 otError MleRouter::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId)
@@ -2761,13 +2863,10 @@
     uint16_t                      startOffset;
     Tlv                           tlv;
     MeshCoP::DiscoveryResponseTlv discoveryResponse;
-    MeshCoP::ExtendedPanIdTlv     extPanId;
     MeshCoP::NetworkNameTlv       networkName;
-    MeshCoP::JoinerUdpPortTlv     joinerUdpPort;
-    MeshCoP::Tlv *                steeringData;
     uint16_t                      delay;
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     message->SetSubType(Message::kSubTypeMleDiscoverResponse);
     message->SetPanId(aPanId);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandDiscoveryResponse));
@@ -2782,13 +2881,10 @@
     discoveryResponse.Init();
     discoveryResponse.SetVersion(kThreadVersion);
 
-    if (Get<KeyManager>().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_NATIVE_COMMISSIONING)
+    if (Get<KeyManager>().IsNativeCommissioningAllowed())
     {
-        MeshCoP::CommissionerUdpPortTlv commissionerUdpPort;
-
-        commissionerUdpPort.Init();
-        commissionerUdpPort.SetUdpPort(MeshCoP::kBorderAgentUdpPort);
-        SuccessOrExit(error = commissionerUdpPort.AppendTo(*message));
+        SuccessOrExit(
+            error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kCommissionerUdpPort, MeshCoP::kBorderAgentUdpPort));
 
         discoveryResponse.SetNativeCommissioner(true);
     }
@@ -2800,9 +2896,8 @@
     SuccessOrExit(error = discoveryResponse.AppendTo(*message));
 
     // Extended PAN ID TLV
-    extPanId.Init();
-    extPanId.SetExtendedPanId(Get<Mac::Mac>().GetExtendedPanId());
-    SuccessOrExit(error = extPanId.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, MeshCoP::Tlv::kExtendedPanId, Get<Mac::Mac>().GetExtendedPanId().m8,
+                                         sizeof(Mac::ExtendedPanId)));
 
     // Network Name TLV
     networkName.Init();
@@ -2810,29 +2905,29 @@
     SuccessOrExit(error = networkName.AppendTo(*message));
 
 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
-
     // If steering data is set out of band, use that value.
     // Otherwise use the one from commissioning data.
-    if (!mSteeringData.IsCleared())
+    if (!mSteeringData.IsEmpty())
     {
-        SuccessOrExit(error = mSteeringData.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendTlv(*message, MeshCoP::Tlv::kSteeringData, mSteeringData.GetData(),
+                                             mSteeringData.GetLength()));
     }
     else
-#endif // OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
+#endif
     {
-        // Steering Data TLV
+        const MeshCoP::Tlv *steeringData;
+
         steeringData = Get<NetworkData::Leader>().GetCommissioningDataSubTlv(MeshCoP::Tlv::kSteeringData);
 
-        if (steeringData != NULL)
+        if (steeringData != nullptr)
         {
             SuccessOrExit(error = steeringData->AppendTo(*message));
         }
     }
 
     // Joiner UDP Port TLV
-    joinerUdpPort.Init();
-    joinerUdpPort.SetUdpPort(Get<MeshCoP::JoinerRouter>().GetJoinerUdpPort());
-    SuccessOrExit(error = joinerUdpPort.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kJoinerUdpPort,
+                                               Get<MeshCoP::JoinerRouter>().GetJoinerUdpPort()));
 
     tlv.SetLength(static_cast<uint8_t>(message->GetLength() - startOffset));
     message->Write(startOffset - sizeof(tlv), sizeof(tlv), &tlv);
@@ -2849,7 +2944,7 @@
     {
         otLogWarnMle("Failed to process Discovery Response: %s", otThreadErrorToString(error));
 
-        if (message != NULL)
+        if (message != nullptr)
         {
             message->Free();
         }
@@ -2864,7 +2959,7 @@
     Ip6::Address destination;
     Message *    message;
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildIdResponse));
     SuccessOrExit(error = AppendSourceAddress(*message));
     SuccessOrExit(error = AppendLeaderData(*message));
@@ -2887,7 +2982,7 @@
 
             rloc16 = Get<Mac::Mac>().GetShortAddress() | mNextChildId;
 
-        } while (mChildTable.FindChild(rloc16, Child::kInStateAnyExceptInvalid) != NULL);
+        } while (mChildTable.FindChild(rloc16, Child::kInStateAnyExceptInvalid) != nullptr);
 
         // allocate Child ID
         aChild.SetRloc16(rloc16);
@@ -2939,16 +3034,14 @@
     }
 #endif
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xfe80);
-    destination.SetIid(aChild.GetExtAddress());
+    destination.SetToLinkLocalAddress(aChild.GetExtAddress());
     SuccessOrExit(error = SendMessage(*message, destination));
 
     LogMleMessage("Send Child ID Response", destination, aChild.GetRloc16());
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -2985,7 +3078,7 @@
         }
     }
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     message->SetSubType(Message::kSubTypeMleChildUpdateRequest);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateRequest));
     SuccessOrExit(error = AppendSourceAddress(*message));
@@ -3001,9 +3094,7 @@
         SuccessOrExit(error = AppendChallenge(*message, aChild.GetChallenge(), aChild.GetChallengeSize()));
     }
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xfe80);
-    destination.SetIid(aChild.GetExtAddress());
+    destination.SetToLinkLocalAddress(aChild.GetExtAddress());
     SuccessOrExit(error = SendMessage(*message, destination));
 
     if (aChild.IsRxOnWhenIdle())
@@ -3016,7 +3107,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -3028,12 +3119,12 @@
                                         const Ip6::MessageInfo &aMessageInfo,
                                         const uint8_t *         aTlvs,
                                         uint8_t                 aTlvsLength,
-                                        const ChallengeTlv &    aChallenge)
+                                        const Challenge &       aChallenge)
 {
     otError  error = OT_ERROR_NONE;
     Message *message;
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateResponse));
 
     for (int i = 0; i < aTlvsLength; i++)
@@ -3063,7 +3154,7 @@
             break;
 
         case Tlv::kResponse:
-            SuccessOrExit(error = AppendResponse(*message, aChallenge.GetChallenge(), aChallenge.GetChallengeLength()));
+            SuccessOrExit(error = AppendResponse(*message, aChallenge));
             break;
 
         case Tlv::kSourceAddress:
@@ -3086,7 +3177,7 @@
 
     SuccessOrExit(error = SendMessage(*message, aMessageInfo.GetPeerAddr()));
 
-    if (aChild == NULL)
+    if (aChild == nullptr)
     {
         LogMleMessage("Send Child Update Response to child", aMessageInfo.GetPeerAddr());
     }
@@ -3097,19 +3188,19 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
 }
 
-otError MleRouter::SendDataResponse(const Ip6::Address &aDestination,
-                                    const uint8_t *     aTlvs,
-                                    uint8_t             aTlvsLength,
-                                    uint16_t            aDelay)
+void MleRouter::SendDataResponse(const Ip6::Address &aDestination,
+                                 const uint8_t *     aTlvs,
+                                 uint8_t             aTlvsLength,
+                                 uint16_t            aDelay)
 {
     otError   error   = OT_ERROR_NONE;
-    Message * message = NULL;
+    Message * message = nullptr;
     Neighbor *neighbor;
     bool      stableOnly;
 
@@ -3119,7 +3210,7 @@
         ExitNow();
     }
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     message->SetSubType(Message::kSubTypeMleDataResponse);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandDataResponse));
     SuccessOrExit(error = AppendSourceAddress(*message));
@@ -3133,7 +3224,7 @@
         {
         case Tlv::kNetworkData:
             neighbor   = GetNeighbor(aDestination);
-            stableOnly = neighbor != NULL ? !neighbor->IsFullNetworkData() : false;
+            stableOnly = neighbor != nullptr ? !neighbor->IsFullNetworkData() : false;
             SuccessOrExit(error = AppendNetworkData(*message, stableOnly));
             break;
 
@@ -3166,12 +3257,15 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        message->Free();
-    }
+        otLogWarnMle("Failed to send Data Response: %s", otThreadErrorToString(error));
 
-    return error;
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
 }
 
 bool MleRouter::IsMinimalChild(uint16_t aRloc16)
@@ -3184,30 +3278,60 @@
 
         neighbor = GetNeighbor(aRloc16);
 
-        rval = (neighbor != NULL) && (!neighbor->IsFullThreadDevice());
+        rval = (neighbor != nullptr) && (!neighbor->IsFullThreadDevice());
     }
 
     return rval;
 }
 
+void MleRouter::RemoveRouterLink(Router &aRouter)
+{
+    switch (mRole)
+    {
+    case kRoleChild:
+        if (&aRouter == &mParent)
+        {
+            IgnoreError(BecomeDetached());
+        }
+        break;
+
+#if OPENTHREAD_FTD
+    case kRoleRouter:
+    case kRoleLeader:
+        mRouterTable.RemoveRouterLink(aRouter);
+        break;
+#endif
+
+    default:
+        break;
+    }
+}
+
 void MleRouter::RemoveNeighbor(Neighbor &aNeighbor)
 {
+    VerifyOrExit(!aNeighbor.IsStateInvalid(), OT_NOOP);
+
     if (&aNeighbor == &mParent)
     {
-        if (mRole == OT_DEVICE_ROLE_CHILD)
+        if (IsChild())
         {
-            BecomeDetached();
+            IgnoreError(BecomeDetached());
         }
     }
+    else if (&aNeighbor == &mParentCandidate)
+    {
+        mParentCandidate.Clear();
+    }
     else if (!IsActiveRouter(aNeighbor.GetRloc16()))
     {
+        OT_ASSERT(mChildTable.GetChildIndex(static_cast<Child &>(aNeighbor)) < kMaxChildren);
+
         if (aNeighbor.IsStateValidOrRestoring())
         {
             Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED, aNeighbor);
         }
 
         Get<IndirectSender>().ClearAllMessagesForSleepyChild(static_cast<Child &>(aNeighbor));
-        Get<NetworkData::Leader>().SendServerDataNotification(aNeighbor.GetRloc16());
 
         if (aNeighbor.IsFullThreadDevice())
         {
@@ -3215,21 +3339,26 @@
             Get<AddressResolver>().Remove(aNeighbor.GetRloc16());
         }
 
-        RemoveStoredChild(aNeighbor.GetRloc16());
+        IgnoreError(RemoveStoredChild(aNeighbor.GetRloc16()));
     }
     else if (aNeighbor.IsStateValid())
     {
+        OT_ASSERT(mRouterTable.Contains(aNeighbor));
+
         Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, aNeighbor);
-        mRouterTable.RemoveNeighbor(static_cast<Router &>(aNeighbor));
+        mRouterTable.RemoveRouterLink(static_cast<Router &>(aNeighbor));
     }
 
     aNeighbor.GetLinkInfo().Clear();
     aNeighbor.SetState(Neighbor::kStateInvalid);
+
+exit:
+    return;
 }
 
 Neighbor *MleRouter::GetNeighbor(uint16_t aAddress)
 {
-    Neighbor *rval = NULL;
+    Neighbor *rval = nullptr;
 
     if (aAddress == Mac::kShortAddrBroadcast || aAddress == Mac::kShortAddrInvalid)
     {
@@ -3238,18 +3367,18 @@
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
+    case kRoleDisabled:
         break;
 
-    case OT_DEVICE_ROLE_DETACHED:
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleDetached:
+    case kRoleChild:
         rval = Mle::GetNeighbor(aAddress);
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleRouter:
+    case kRoleLeader:
         rval = mChildTable.FindChild(aAddress, Child::kInStateValidOrRestoring);
-        VerifyOrExit(rval == NULL);
+        VerifyOrExit(rval == nullptr, OT_NOOP);
 
         rval = mRouterTable.GetNeighbor(aAddress);
         break;
@@ -3261,26 +3390,26 @@
 
 Neighbor *MleRouter::GetNeighbor(const Mac::ExtAddress &aAddress)
 {
-    Neighbor *rval = NULL;
+    Neighbor *rval = nullptr;
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
+    case kRoleDisabled:
         break;
 
-    case OT_DEVICE_ROLE_DETACHED:
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleDetached:
+    case kRoleChild:
         rval = Mle::GetNeighbor(aAddress);
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleRouter:
+    case kRoleLeader:
         rval = mChildTable.FindChild(aAddress, Child::kInStateValidOrRestoring);
-        VerifyOrExit(rval == NULL);
+        VerifyOrExit(rval == nullptr, OT_NOOP);
 
         rval = mRouterTable.GetNeighbor(aAddress);
 
-        if (rval != NULL)
+        if (rval != nullptr)
         {
             ExitNow();
         }
@@ -3299,7 +3428,7 @@
 
 Neighbor *MleRouter::GetNeighbor(const Mac::Address &aAddress)
 {
-    Neighbor *rval = NULL;
+    Neighbor *rval = nullptr;
 
     switch (aAddress.GetType())
     {
@@ -3320,23 +3449,14 @@
 
 Neighbor *MleRouter::GetNeighbor(const Ip6::Address &aAddress)
 {
-    Mac::Address    macAddr;
     Lowpan::Context context;
-    Child *         child;
-    Neighbor *      rval = NULL;
+    Neighbor *      rval = nullptr;
 
     if (aAddress.IsLinkLocal())
     {
-        if (aAddress.mFields.m16[4] == HostSwap16(0x0000) && aAddress.mFields.m16[5] == HostSwap16(0x00ff) &&
-            aAddress.mFields.m16[6] == HostSwap16(0xfe00))
-        {
-            macAddr.SetShort(HostSwap16(aAddress.mFields.m16[7]));
-        }
-        else
-        {
-            aAddress.ToExtAddress(macAddr);
-        }
+        Mac::Address macAddr;
 
+        aAddress.GetIid().ConvertToMacAddress(macAddr);
         ExitNow(rval = GetNeighbor(macAddr));
     }
 
@@ -3345,29 +3465,25 @@
         context.mContextId = 0xff;
     }
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
     {
-        child = iter.GetChild();
-
-        if (context.mContextId == kMeshLocalPrefixContextId && aAddress.mFields.m16[4] == HostSwap16(0x0000) &&
-            aAddress.mFields.m16[5] == HostSwap16(0x00ff) && aAddress.mFields.m16[6] == HostSwap16(0xfe00) &&
-            aAddress.mFields.m16[7] == HostSwap16(child->GetRloc16()))
+        if ((context.mContextId == kMeshLocalPrefixContextId) && aAddress.GetIid().IsLocator() &&
+            (aAddress.GetIid().GetLocator() == child.GetRloc16()))
         {
-            ExitNow(rval = child);
+            ExitNow(rval = &child);
         }
 
-        if (child->HasIp6Address(GetInstance(), aAddress))
+        if (child.HasIp6Address(aAddress))
         {
-            ExitNow(rval = child);
+            ExitNow(rval = &child);
         }
     }
 
-    VerifyOrExit(context.mContextId == kMeshLocalPrefixContextId, rval = NULL);
+    VerifyOrExit(context.mContextId == kMeshLocalPrefixContextId, rval = nullptr);
 
-    if (aAddress.mFields.m16[4] == HostSwap16(0x0000) && aAddress.mFields.m16[5] == HostSwap16(0x00ff) &&
-        aAddress.mFields.m16[6] == HostSwap16(0xfe00))
+    if (aAddress.GetIid().IsLocator())
     {
-        rval = mRouterTable.GetNeighbor(HostSwap16(aAddress.mFields.m16[7]));
+        rval = mRouterTable.GetNeighbor(aAddress.GetIid().GetLocator());
     }
 
 exit:
@@ -3376,9 +3492,9 @@
 
 Neighbor *MleRouter::GetRxOnlyNeighborRouter(const Mac::Address &aAddress)
 {
-    Neighbor *rval = NULL;
+    Neighbor *rval = nullptr;
 
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_CHILD, rval = NULL);
+    VerifyOrExit(IsChild(), rval = nullptr);
 
     switch (aAddress.GetType())
     {
@@ -3407,7 +3523,7 @@
     const Router *router;
     const Router *nextHop;
 
-    if (mRole == OT_DEVICE_ROLE_CHILD)
+    if (IsChild())
     {
         ExitNow(rval = Mle::GetNextHop(aDestination));
     }
@@ -3419,7 +3535,7 @@
     }
 
     router = mRouterTable.GetRouter(destinationId);
-    VerifyOrExit(router != NULL);
+    VerifyOrExit(router != nullptr, OT_NOOP);
 
     linkCost  = GetLinkCost(destinationId);
     routeCost = GetRouteCost(aDestination);
@@ -3427,7 +3543,7 @@
     if ((routeCost + GetLinkCost(router->GetNextHop())) < linkCost)
     {
         nextHop = mRouterTable.GetRouter(router->GetNextHop());
-        VerifyOrExit(nextHop != NULL && !nextHop->IsStateInvalid());
+        VerifyOrExit(nextHop != nullptr && !nextHop->IsStateInvalid(), OT_NOOP);
 
         rval = Rloc16FromRouterId(router->GetNextHop());
     }
@@ -3447,7 +3563,7 @@
     Router *router   = mRouterTable.GetRouter(routerId);
     uint8_t routeCost;
 
-    VerifyOrExit(router != NULL && mRouterTable.GetRouter(router->GetNextHop()) != NULL);
+    VerifyOrExit(router != nullptr && mRouterTable.GetRouter(router->GetNextHop()) != nullptr, OT_NOOP);
 
     routeCost = GetRouteCost(aRloc16) + GetLinkCost(router->GetNextHop());
 
@@ -3466,7 +3582,7 @@
     const Router *router;
 
     router = mRouterTable.GetRouter(RouterIdFromRloc16(aRloc16));
-    VerifyOrExit(router != NULL && mRouterTable.GetRouter(router->GetNextHop()) != NULL);
+    VerifyOrExit(router != nullptr && mRouterTable.GetRouter(router->GetNextHop()) != nullptr, OT_NOOP);
 
     rval = router->GetCost();
 
@@ -3478,8 +3594,7 @@
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit((mRole == OT_DEVICE_ROLE_DETACHED) || (mRole == OT_DEVICE_ROLE_DISABLED),
-                 error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(IsDetached() || IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
     mPreviousRouterId = aRouterId;
 
@@ -3506,7 +3621,7 @@
 
     rloc16 = Get<Mac::Mac>().GetShortAddress() | aChildId;
     child  = mChildTable.FindChild(rloc16, Child::kInStateAnyExceptInvalid);
-    VerifyOrExit(child != NULL, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(child != nullptr, error = OT_ERROR_NOT_FOUND);
 
     error = GetChildInfo(*child, aChildInfo);
 
@@ -3517,10 +3632,10 @@
 otError MleRouter::GetChildInfoByIndex(uint16_t aChildIndex, otChildInfo &aChildInfo)
 {
     otError error = OT_ERROR_NONE;
-    Child * child = NULL;
+    Child * child = nullptr;
 
     child = mChildTable.GetChildAtIndex(aChildIndex);
-    VerifyOrExit(child != NULL, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(child != nullptr, error = OT_ERROR_NOT_FOUND);
 
     error = GetChildInfo(*child, aChildInfo);
 
@@ -3533,13 +3648,13 @@
                                           Ip6::Address &             aAddress)
 {
     otError error = OT_ERROR_NONE;
-    Child * child = NULL;
+    Child * child = nullptr;
 
     child = mChildTable.GetChildAtIndex(aChildIndex);
-    VerifyOrExit(child != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(child != nullptr, error = OT_ERROR_INVALID_ARGS);
     VerifyOrExit(child->IsStateValidOrRestoring(), error = OT_ERROR_INVALID_ARGS);
 
-    error = child->GetNextIp6Address(GetInstance(), aIterator, aAddress);
+    error = child->GetNextIp6Address(aIterator, aAddress);
 
 exit:
     return error;
@@ -3556,12 +3671,11 @@
         Child *                    child;
         const Settings::ChildInfo &childInfo = iter.GetChildInfo();
 
-        child = mChildTable.FindChild(*static_cast<const Mac::ExtAddress *>(&childInfo.mExtAddress),
-                                      Child::kInStateAnyExceptInvalid);
+        child = mChildTable.FindChild(childInfo.GetExtAddress(), Child::kInStateAnyExceptInvalid);
 
-        if (child == NULL)
+        if (child == nullptr)
         {
-            VerifyOrExit((child = mChildTable.GetNewChild()) != NULL, error = OT_ERROR_NO_BUFS);
+            VerifyOrExit((child = mChildTable.GetNewChild()) != nullptr, error = OT_ERROR_NO_BUFS);
         }
         else
         {
@@ -3570,13 +3684,14 @@
 
         child->Clear();
 
-        child->SetExtAddress(*static_cast<const Mac::ExtAddress *>(&childInfo.mExtAddress));
+        child->SetExtAddress(childInfo.GetExtAddress());
         child->GetLinkInfo().Clear();
-        child->SetRloc16(childInfo.mRloc16);
-        child->SetTimeout(childInfo.mTimeout);
-        child->SetDeviceMode(DeviceMode(childInfo.mMode));
+        child->SetRloc16(childInfo.GetRloc16());
+        child->SetTimeout(childInfo.GetTimeout());
+        child->SetDeviceMode(DeviceMode(childInfo.GetMode()));
         child->SetState(Neighbor::kStateRestored);
         child->SetLastHeard(TimerMilli::GetNow());
+        child->SetVersion(static_cast<uint8_t>(childInfo.GetVersion()));
         Get<IndirectSender>().SetChildUseShortAddress(*child, true);
         numChildren++;
     }
@@ -3601,7 +3716,7 @@
 
     for (Settings::ChildInfoIterator iter(GetInstance()); !iter.IsDone(); iter++)
     {
-        if (iter.GetChildInfo().mRloc16 == aChildRloc16)
+        if (iter.GetChildInfo().GetRloc16() == aChildRloc16)
         {
             error = iter.Delete();
             ExitNow();
@@ -3616,30 +3731,29 @@
 {
     Settings::ChildInfo childInfo;
 
-    IgnoreReturnValue(RemoveStoredChild(aChild.GetRloc16()));
+    IgnoreError(RemoveStoredChild(aChild.GetRloc16()));
 
-    childInfo.Clear();
-    childInfo.mExtAddress = aChild.GetExtAddress();
-    childInfo.mTimeout    = aChild.GetTimeout();
-    childInfo.mRloc16     = aChild.GetRloc16();
-    childInfo.mMode       = aChild.GetDeviceMode().Get();
+    childInfo.Init();
+    childInfo.SetExtAddress(aChild.GetExtAddress());
+    childInfo.SetTimeout(aChild.GetTimeout());
+    childInfo.SetRloc16(aChild.GetRloc16());
+    childInfo.SetMode(aChild.GetDeviceMode().Get());
+    childInfo.SetVersion(aChild.GetVersion());
 
     return Get<Settings>().AddChildInfo(childInfo);
 }
 
-otError MleRouter::RefreshStoredChildren(void)
+void MleRouter::RefreshStoredChildren(void)
 {
-    otError error = OT_ERROR_NONE;
+    SuccessOrExit(Get<Settings>().DeleteChildInfo());
 
-    SuccessOrExit(error = Get<Settings>().DeleteChildInfo());
-
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateAnyExceptInvalid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateAnyExceptInvalid))
     {
-        SuccessOrExit(error = StoreChild(*iter.GetChild()));
+        SuccessOrExit(StoreChild(child));
     }
 
 exit:
-    return error;
+    return;
 }
 
 otError MleRouter::GetChildInfo(Child &aChild, otChildInfo &aChildInfo)
@@ -3691,7 +3805,7 @@
 otError MleRouter::GetNextNeighborInfo(otNeighborInfoIterator &aIterator, otNeighborInfo &aNeighInfo)
 {
     otError   error    = OT_ERROR_NONE;
-    Neighbor *neighbor = NULL;
+    Neighbor *neighbor = nullptr;
     int16_t   index;
 
     memset(&aNeighInfo, 0, sizeof(aNeighInfo));
@@ -3704,7 +3818,7 @@
         {
             Child *child = mChildTable.GetChildAtIndex(static_cast<uint16_t>(index));
 
-            if (child == NULL)
+            if (child == nullptr)
             {
                 break;
             }
@@ -3728,7 +3842,7 @@
     {
         Router *router = mRouterTable.GetRouter(static_cast<uint8_t>(index));
 
-        if (router != NULL && router->IsStateValid())
+        if (router != nullptr && router->IsStateValid())
         {
             neighbor            = router;
             aNeighInfo.mIsChild = false;
@@ -3743,7 +3857,7 @@
 
 exit:
 
-    if (neighbor != NULL)
+    if (neighbor != nullptr)
     {
         GetNeighborInfo(*neighbor, aNeighInfo);
     }
@@ -3762,7 +3876,7 @@
 
     // loop exists
     router = mRouterTable.GetRouter(RouterIdFromRloc16(aDestRloc16));
-    VerifyOrExit(router != NULL);
+    VerifyOrExit(router != nullptr, OT_NOOP);
 
     // invalidate next hop
     router->SetNextHop(kInvalidRouterId);
@@ -3772,26 +3886,25 @@
     return;
 }
 
-otError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header)
+otError MleRouter::CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header)
 {
-    Ip6::MessageInfo messageInfo;
-    otError          error = OT_ERROR_NONE;
+    otError error = OT_ERROR_NONE;
 
-    if (mRole == OT_DEVICE_ROLE_CHILD)
+    if (IsChild())
     {
-        error = Mle::CheckReachability(aMeshSource, aMeshDest, aIp6Header);
+        error = Mle::CheckReachability(aMeshDest, aIp6Header);
         ExitNow();
     }
 
     if (aMeshDest == Get<Mac::Mac>().GetShortAddress())
     {
         // mesh destination is this device
-        if (Get<ThreadNetif>().IsUnicastAddress(aIp6Header.GetDestination()))
+        if (Get<ThreadNetif>().HasUnicastAddress(aIp6Header.GetDestination()))
         {
             // IPv6 destination is this device
             ExitNow();
         }
-        else if (GetNeighbor(aIp6Header.GetDestination()) != NULL)
+        else if (GetNeighbor(aIp6Header.GetDestination()) != nullptr)
         {
             // IPv6 destination is an RFD child
             ExitNow();
@@ -3811,13 +3924,7 @@
         ExitNow();
     }
 
-    messageInfo.GetPeerAddr()                = GetMeshLocal16();
-    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aMeshSource);
-
-    Get<Ip6::Icmp>().SendError(Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo,
-                               aIp6Header);
-
-    error = OT_ERROR_DROP;
+    error = OT_ERROR_NO_ROUTE;
 
 exit:
     return error;
@@ -3825,34 +3932,27 @@
 
 otError MleRouter::SendAddressSolicit(ThreadStatusTlv::Status aStatus)
 {
-    otError                error = OT_ERROR_NONE;
-    ThreadExtMacAddressTlv macAddr64Tlv;
-    ThreadRloc16Tlv        rlocTlv;
-    ThreadStatusTlv        statusTlv;
-    Ip6::MessageInfo       messageInfo;
-    Coap::Message *        message = NULL;
+    otError          error = OT_ERROR_NONE;
+    Ip6::MessageInfo messageInfo;
+    Coap::Message *  message = nullptr;
 
-    VerifyOrExit(!mAddressSolicitPending);
+    VerifyOrExit(!mAddressSolicitPending, OT_NOOP);
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewPriorityMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_ADDRESS_SOLICIT));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    macAddr64Tlv.Init();
-    macAddr64Tlv.SetMacAddr(Get<Mac::Mac>().GetExtAddress());
-    SuccessOrExit(error = macAddr64Tlv.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, ThreadTlv::kExtMacAddress, Get<Mac::Mac>().GetExtAddress().m8,
+                                         sizeof(Mac::ExtAddress)));
 
     if (IsRouterIdValid(mPreviousRouterId))
     {
-        rlocTlv.Init();
-        rlocTlv.SetRloc16(Rloc16FromRouterId(mPreviousRouterId));
-        SuccessOrExit(error = rlocTlv.AppendTo(*message));
+        SuccessOrExit(error =
+                          Tlv::AppendUint16Tlv(*message, ThreadTlv::kRloc16, Rloc16FromRouterId(mPreviousRouterId)));
     }
 
-    statusTlv.Init();
-    statusTlv.SetStatus(aStatus);
-    SuccessOrExit(error = statusTlv.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, ThreadTlv::kStatus, static_cast<uint8_t>(aStatus)));
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     SuccessOrExit(error = AppendXtalAccuracy(*message));
@@ -3870,7 +3970,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -3878,26 +3978,21 @@
     return error;
 }
 
-otError MleRouter::SendAddressRelease(void)
+void MleRouter::SendAddressRelease(void)
 {
-    otError                error = OT_ERROR_NONE;
-    ThreadRloc16Tlv        rlocTlv;
-    ThreadExtMacAddressTlv macAddr64Tlv;
-    Ip6::MessageInfo       messageInfo;
-    Coap::Message *        message;
+    otError          error = OT_ERROR_NONE;
+    Ip6::MessageInfo messageInfo;
+    Coap::Message *  message;
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_ADDRESS_RELEASE));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    rlocTlv.Init();
-    rlocTlv.SetRloc16(Rloc16FromRouterId(mRouterId));
-    SuccessOrExit(error = rlocTlv.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, ThreadTlv::kRloc16, Rloc16FromRouterId(mRouterId)));
 
-    macAddr64Tlv.Init();
-    macAddr64Tlv.SetMacAddr(Get<Mac::Mac>().GetExtAddress());
-    SuccessOrExit(error = macAddr64Tlv.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendTlv(*message, ThreadTlv::kExtMacAddress, Get<Mac::Mac>().GetExtAddress().m8,
+                                         sizeof(Mac::ExtAddress)));
 
     messageInfo.SetSockAddr(GetMeshLocal16());
     SuccessOrExit(error = GetLeaderAddress(messageInfo.GetPeerAddr()));
@@ -3908,12 +4003,15 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        message->Free();
-    }
+        otLogWarnMle("Failed to send Address Release: %s", otThreadErrorToString(error));
 
-    return error;
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
 }
 
 void MleRouter::HandleAddressSolicitResponse(void *               aContext,
@@ -3931,8 +4029,8 @@
 {
     OT_UNUSED_VARIABLE(aMessageInfo);
 
-    ThreadStatusTlv     statusTlv;
-    ThreadRloc16Tlv     rlocTlv;
+    uint8_t             status;
+    uint16_t            rloc16;
     ThreadRouterMaskTlv routerMaskTlv;
     uint8_t             routerId;
     Router *            router;
@@ -3940,17 +4038,18 @@
 
     mAddressSolicitPending = false;
 
-    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage != NULL && aMessage != NULL);
+    VerifyOrExit(aResult == OT_ERROR_NONE && aMessage != nullptr && aMessage != nullptr, OT_NOOP);
 
-    VerifyOrExit(aMessage->GetCode() == OT_COAP_CODE_CHANGED);
+    VerifyOrExit(aMessage->GetCode() == OT_COAP_CODE_CHANGED, OT_NOOP);
 
     LogMleMessage("Receive Address Reply", aMessageInfo->GetPeerAddr());
 
-    SuccessOrExit(ThreadTlv::GetTlv(*aMessage, ThreadTlv::kStatus, sizeof(statusTlv), statusTlv));
-    VerifyOrExit(statusTlv.IsValid());
+    SuccessOrExit(Tlv::FindUint8Tlv(*aMessage, ThreadTlv::kStatus, status));
 
-    if (statusTlv.GetStatus() != statusTlv.kSuccess)
+    if (status != ThreadStatusTlv::kSuccess)
     {
+        mAddressSolicitRejected = true;
+
         if (IsRouterIdValid(mPreviousRouterId))
         {
             if (HasChildren())
@@ -3964,36 +4063,36 @@
         ExitNow();
     }
 
-    SuccessOrExit(ThreadTlv::GetTlv(*aMessage, ThreadTlv::kRloc16, sizeof(rlocTlv), rlocTlv));
-    VerifyOrExit(rlocTlv.IsValid());
-    routerId = RouterIdFromRloc16(rlocTlv.GetRloc16());
+    SuccessOrExit(Tlv::FindUint16Tlv(*aMessage, ThreadTlv::kRloc16, rloc16));
+    routerId = RouterIdFromRloc16(rloc16);
 
-    SuccessOrExit(ThreadTlv::GetTlv(*aMessage, ThreadTlv::kRouterMask, sizeof(routerMaskTlv), routerMaskTlv));
-    VerifyOrExit(routerMaskTlv.IsValid());
+    SuccessOrExit(ThreadTlv::FindTlv(*aMessage, ThreadTlv::kRouterMask, sizeof(routerMaskTlv), routerMaskTlv));
+    VerifyOrExit(routerMaskTlv.IsValid(), OT_NOOP);
 
     // assign short address
     SetRouterId(routerId);
 
     SetStateRouter(Rloc16FromRouterId(mRouterId));
     mRouterTable.Clear();
-    mRouterTable.ProcessTlv(routerMaskTlv);
+    mRouterTable.UpdateRouterIdSet(routerMaskTlv.GetIdSequence(), routerMaskTlv.GetAssignedRouterIdMask());
 
     router = mRouterTable.GetRouter(routerId);
-    VerifyOrExit(router != NULL);
+    VerifyOrExit(router != nullptr, OT_NOOP);
 
     router->SetExtAddress(Get<Mac::Mac>().GetExtAddress());
     router->SetCost(0);
 
     router = mRouterTable.GetRouter(mParent.GetRouterId());
-    VerifyOrExit(router != NULL);
+    VerifyOrExit(router != nullptr, OT_NOOP);
 
     // Keep link to the parent in order to respond to Parent Requests before new link is established.
     *router = mParent;
+    router->SetState(Neighbor::kStateValid);
     router->SetNextHop(kInvalidRouterId);
     router->SetCost(0);
 
     leader = mRouterTable.GetLeader();
-    assert(leader != NULL);
+    OT_ASSERT(leader != nullptr);
 
     if (leader != router)
     {
@@ -4003,12 +4102,12 @@
     }
 
     // send link request
-    SendLinkRequest(NULL);
+    IgnoreError(SendLinkRequest(nullptr));
 
     // send child id responses
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateChildIdRequest); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateChildIdRequest))
     {
-        SendChildIdResponse(*iter.GetChild());
+        IgnoreError(SendChildIdResponse(child));
     }
 
 exit:
@@ -4017,6 +4116,12 @@
     InformPreviousChannel();
 }
 
+bool MleRouter::IsExpectedToBecomeRouter(void) const
+{
+    return IsRouterEligible() && !IsRouterOrLeader() &&
+           (Get<RouterTable>().GetActiveRouterCount() < GetRouterUpgradeThreshold()) && !mAddressSolicitRejected;
+}
+
 void MleRouter::HandleAddressSolicit(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
 {
     static_cast<MleRouter *>(aContext)->HandleAddressSolicit(*static_cast<Coap::Message *>(aMessage),
@@ -4025,48 +4130,42 @@
 
 void MleRouter::HandleAddressSolicit(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    otError                error = OT_ERROR_NONE;
-    ThreadExtMacAddressTlv macAddr64Tlv;
-    ThreadRloc16Tlv        rlocTlv;
-    ThreadStatusTlv        statusTlv;
-    Router *               router = NULL;
+    otError         error = OT_ERROR_NONE;
+    Mac::ExtAddress extAddress;
+    uint16_t        rloc16;
+    uint8_t         status;
+    Router *        router = nullptr;
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    XtalAccuracyTlv xtalAccuracyTlv;
+    uint16_t xtalAccuracy;
 #endif
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST,
-                 error = OT_ERROR_PARSE);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, error = OT_ERROR_PARSE);
 
     LogMleMessage("Receive Address Solicit", aMessageInfo.GetPeerAddr());
 
-    SuccessOrExit(error = ThreadTlv::GetTlv(aMessage, ThreadTlv::kExtMacAddress, sizeof(macAddr64Tlv), macAddr64Tlv));
-    VerifyOrExit(macAddr64Tlv.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = ThreadTlv::FindTlv(aMessage, ThreadTlv::kExtMacAddress, &extAddress, sizeof(extAddress)));
 
-    SuccessOrExit(error = ThreadTlv::GetTlv(aMessage, ThreadTlv::kStatus, sizeof(statusTlv), statusTlv));
-    VerifyOrExit(statusTlv.IsValid(), error = OT_ERROR_PARSE);
+    SuccessOrExit(error = Tlv::FindUint8Tlv(aMessage, ThreadTlv::kStatus, status));
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
     // In a time sync enabled network, all routers' xtal accuracy must be less than the threshold.
-    if (Tlv::GetTlv(aMessage, Tlv::kXtalAccuracy, sizeof(xtalAccuracyTlv), xtalAccuracyTlv) != OT_ERROR_NONE ||
-        xtalAccuracyTlv.GetXtalAccuracy() > Get<TimeSync>().GetXtalThreshold())
-    {
-        ExitNow(router = NULL);
-    }
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, Tlv::kXtalAccuracy, xtalAccuracy));
+    VerifyOrExit(xtalAccuracy <= Get<TimeSync>().GetXtalThreshold(), OT_NOOP);
 #endif
 
     // see if allocation already exists
-    router = mRouterTable.GetRouter(macAddr64Tlv.GetMacAddr());
+    router = mRouterTable.GetRouter(extAddress);
 
-    if (router != NULL)
+    if (router != nullptr)
     {
         ExitNow();
     }
 
     // check the request reason
-    switch (statusTlv.GetStatus())
+    switch (status)
     {
     case ThreadStatusTlv::kTooFewRouters:
-        VerifyOrExit(mRouterTable.GetActiveRouterCount() < mRouterUpgradeThreshold);
+        VerifyOrExit(mRouterTable.GetActiveRouterCount() < mRouterUpgradeThreshold, OT_NOOP);
         break;
 
     case ThreadStatusTlv::kHaveChildIdRequest:
@@ -4075,17 +4174,22 @@
 
     default:
         ExitNow(error = OT_ERROR_PARSE);
-        break;
+        OT_UNREACHABLE_CODE(break);
     }
 
-    if (ThreadTlv::GetTlv(aMessage, ThreadTlv::kRloc16, sizeof(rlocTlv), rlocTlv) == OT_ERROR_NONE)
+    switch (Tlv::FindUint16Tlv(aMessage, ThreadTlv::kRloc16, rloc16))
     {
-        VerifyOrExit(rlocTlv.IsValid(), error = OT_ERROR_PARSE);
-        router = mRouterTable.Allocate(RouterIdFromRloc16(rlocTlv.GetRloc16()));
+    case OT_ERROR_NONE:
+        router = mRouterTable.Allocate(RouterIdFromRloc16(rloc16));
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
     }
 
     // allocate new router id
-    if (router == NULL)
+    if (router == nullptr)
     {
         router = mRouterTable.Allocate();
     }
@@ -4094,9 +4198,9 @@
         otLogInfoMle("router id requested and provided!");
     }
 
-    if (router != NULL)
+    if (router != nullptr)
     {
-        router->SetExtAddress(macAddr64Tlv.GetMacAddr());
+        router->SetExtAddress(extAddress);
     }
     else
     {
@@ -4116,37 +4220,25 @@
                                            const Ip6::MessageInfo &aMessageInfo)
 {
     otError             error = OT_ERROR_NONE;
-    ThreadStatusTlv     statusTlv;
     ThreadRouterMaskTlv routerMaskTlv;
-    ThreadRloc16Tlv     rlocTlv;
     Coap::Message *     message;
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewPriorityMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    statusTlv.Init();
-    statusTlv.SetStatus(aRouter == NULL ? statusTlv.kNoAddressAvailable : statusTlv.kSuccess);
-    SuccessOrExit(error = statusTlv.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, ThreadTlv::kStatus,
+                                              aRouter == nullptr ? ThreadStatusTlv::kNoAddressAvailable
+                                                                 : ThreadStatusTlv::kSuccess));
 
-    if (aRouter != NULL)
+    if (aRouter != nullptr)
     {
-        rlocTlv.Init();
-        rlocTlv.SetRloc16(aRouter->GetRloc16());
-        SuccessOrExit(error = rlocTlv.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, ThreadTlv::kRloc16, aRouter->GetRloc16()));
 
         routerMaskTlv.Init();
         routerMaskTlv.SetIdSequence(mRouterTable.GetRouterIdSequence());
-        routerMaskTlv.ClearAssignedRouterIdMask();
-
-        for (uint8_t routerId = 0; routerId <= kMaxRouterId; routerId++)
-        {
-            if (mRouterTable.IsAllocated(routerId))
-            {
-                routerMaskTlv.SetAssignedRouterId(routerId);
-            }
-        }
+        routerMaskTlv.SetAssignedRouterIdMask(mRouterTable.GetRouterIdSet());
 
         SuccessOrExit(error = routerMaskTlv.AppendTo(*message));
     }
@@ -4157,7 +4249,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -4171,27 +4263,25 @@
 
 void MleRouter::HandleAddressRelease(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    ThreadRloc16Tlv        rlocTlv;
-    ThreadExtMacAddressTlv macAddr64Tlv;
-    uint8_t                routerId;
-    Router *               router;
+    uint16_t        rloc16;
+    Mac::ExtAddress extAddress;
+    uint8_t         routerId;
+    Router *        router;
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
     LogMleMessage("Receive Address Release", aMessageInfo.GetPeerAddr());
 
-    SuccessOrExit(ThreadTlv::GetTlv(aMessage, ThreadTlv::kRloc16, sizeof(rlocTlv), rlocTlv));
-    VerifyOrExit(rlocTlv.IsValid());
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, ThreadTlv::kRloc16, rloc16));
 
-    SuccessOrExit(ThreadTlv::GetTlv(aMessage, ThreadTlv::kExtMacAddress, sizeof(macAddr64Tlv), macAddr64Tlv));
-    VerifyOrExit(macAddr64Tlv.IsValid());
+    SuccessOrExit(Tlv::FindTlv(aMessage, ThreadTlv::kExtMacAddress, &extAddress, sizeof(extAddress)));
 
-    routerId = RouterIdFromRloc16(rlocTlv.GetRloc16());
+    routerId = RouterIdFromRloc16(rloc16);
     router   = mRouterTable.GetRouter(routerId);
 
-    VerifyOrExit(router != NULL && router->GetExtAddress() == macAddr64Tlv.GetMacAddr());
+    VerifyOrExit((router != nullptr) && (router->GetExtAddress() == extAddress), OT_NOOP);
 
-    mRouterTable.Release(routerId);
+    IgnoreError(mRouterTable.Release(routerId));
 
     SuccessOrExit(Get<Coap::Coap>().SendEmptyAck(aMessage, aMessageInfo));
 
@@ -4234,16 +4324,16 @@
     aTlv.SetLinkQuality3(0);
 
     leader = mRouterTable.GetLeader();
-    cost   = (leader != NULL) ? leader->GetCost() : static_cast<uint8_t>(kMaxRouteCost);
+    cost   = (leader != nullptr) ? leader->GetCost() : static_cast<uint8_t>(kMaxRouteCost);
 
     switch (mRole)
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
+    case kRoleDisabled:
+    case kRoleDetached:
         cost = static_cast<uint8_t>(kMaxRouteCost);
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
+    case kRoleChild:
         switch (mParent.GetLinkInfo().GetLinkQuality())
         {
         case 1:
@@ -4262,8 +4352,8 @@
         cost += LinkQualityToCost(mParent.GetLinkInfo().GetLinkQuality());
         break;
 
-    case OT_DEVICE_ROLE_ROUTER:
-        if (leader != NULL)
+    case kRoleRouter:
+        if (leader != nullptr)
         {
             cost += GetLinkCost(leader->GetNextHop());
 
@@ -4275,7 +4365,7 @@
 
         break;
 
-    case OT_DEVICE_ROLE_LEADER:
+    case kRoleLeader:
         cost = 0;
         break;
     }
@@ -4352,7 +4442,7 @@
     tlv.SetType(Tlv::kAddressRegistration);
     SuccessOrExit(error = aMessage.Append(&tlv, sizeof(tlv)));
 
-    while (aChild.GetNextIp6Address(GetInstance(), iterator, address) == OT_ERROR_NONE)
+    while (aChild.GetNextIp6Address(iterator, address) == OT_ERROR_NONE)
     {
         if (address.IsMulticast() || Get<NetworkData::Leader>().GetContext(address, context) != OT_ERROR_NONE)
         {
@@ -4387,14 +4477,12 @@
     uint8_t routerCount = 0;
 
     aTlv.SetRouterIdSequence(mRouterTable.GetRouterIdSequence());
-    aTlv.ClearRouterIdMask();
+    aTlv.SetRouterIdMask(mRouterTable.GetRouterIdSet());
 
     for (RouterTable::Iterator iter(GetInstance()); !iter.IsDone(); iter++, routerCount++)
     {
         Router &router = *iter.GetRouter();
 
-        aTlv.SetRouterId(router.GetRouterId());
-
         if (router.GetRloc16() == GetRloc16())
         {
             aTlv.SetLinkQualityIn(routerCount, 0);
@@ -4410,7 +4498,7 @@
             linkCost = mRouterTable.GetLinkCost(router);
             nextHop  = mRouterTable.GetRouter(router.GetNextHop());
 
-            if (nextHop == NULL)
+            if (nextHop == nullptr)
             {
                 routeCost = linkCost;
             }
@@ -4561,10 +4649,10 @@
 
 void MleRouter::SetChildStateToValid(Child &aChild)
 {
-    VerifyOrExit(!aChild.IsStateValid());
+    VerifyOrExit(!aChild.IsStateValid(), OT_NOOP);
 
     aChild.SetState(Neighbor::kStateValid);
-    StoreChild(aChild);
+    IgnoreError(StoreChild(aChild));
     Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED, aChild);
 
 exit:
@@ -4578,9 +4666,9 @@
 
 void MleRouter::RemoveChildren(void)
 {
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
     {
-        RemoveNeighbor(*iter.GetChild());
+        RemoveNeighbor(child);
     }
 }
 
@@ -4589,7 +4677,7 @@
     uint16_t numChildren = 0;
     uint8_t  routerCount = mRouterTable.GetActiveRouterCount();
 
-    VerifyOrExit(routerCount > mRouterDowngradeThreshold);
+    VerifyOrExit(routerCount > mRouterDowngradeThreshold, OT_NOOP);
 
     numChildren = mChildTable.GetNumChildren(Child::kInStateValid);
 
@@ -4616,12 +4704,10 @@
 {
     otError error = OT_ERROR_NOT_FOUND;
 
-    VerifyOrExit(mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(IsRouterOrLeader(), error = OT_ERROR_INVALID_STATE);
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
     {
-        Child &child = *iter.GetChild();
-
         if (child.IsFullThreadDevice())
         {
             continue;
@@ -4641,11 +4727,13 @@
 
 void MleRouter::Signal(otNeighborTableEvent aEvent, Neighbor &aNeighbor)
 {
-    if (mNeighborTableChangedCallback != NULL)
+    if (mNeighborTableChangedCallback != nullptr)
     {
         otNeighborTableEntryInfo info;
         otError                  error;
 
+        OT_UNUSED_VARIABLE(error);
+
         info.mInstance = &GetInstance();
 
         switch (aEvent)
@@ -4653,7 +4741,7 @@
         case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED:
         case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED:
             error = GetChildInfo(static_cast<Child &>(aNeighbor), info.mInfo.mChild);
-            assert(error == OT_ERROR_NONE);
+            OT_ASSERT(error == OT_ERROR_NONE);
             break;
 
         case OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED:
@@ -4665,14 +4753,18 @@
         mNeighborTableChangedCallback(aEvent, &info);
     }
 
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+    Get<Utils::Otns>().EmitNeighborChange(aEvent, aNeighbor);
+#endif
+
     switch (aEvent)
     {
     case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED:
-        Get<Notifier>().Signal(OT_CHANGED_THREAD_CHILD_ADDED);
+        Get<Notifier>().Signal(kEventThreadChildAdded);
         break;
 
     case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED:
-        Get<Notifier>().Signal(OT_CHANGED_THREAD_CHILD_REMOVED);
+        Get<Notifier>().Signal(kEventThreadChildRemoved);
         break;
 
     default:
@@ -4684,10 +4776,8 @@
 {
     bool rval = false;
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
     {
-        Child &child = *iter.GetChild();
-
         if (child.IsRxOnWhenIdle())
         {
             continue;
@@ -4705,8 +4795,7 @@
 
 bool MleRouter::IsSleepyChildSubscribed(const Ip6::Address &aAddress, Child &aChild)
 {
-    return aChild.IsStateValidOrRestoring() && !aChild.IsRxOnWhenIdle() &&
-           aChild.HasIp6Address(GetInstance(), aAddress);
+    return aChild.IsStateValidOrRestoring() && !aChild.IsRxOnWhenIdle() && aChild.HasIp6Address(aAddress);
 }
 
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
@@ -4714,7 +4803,7 @@
 {
     LogMleMessage("Receive Time Sync", aMessageInfo.GetPeerAddr());
 
-    VerifyOrExit(aNeighbor && aNeighbor->IsStateValid());
+    VerifyOrExit(aNeighbor && aNeighbor->IsStateValid(), OT_NOOP);
 
     Get<TimeSync>().HandleTimeSyncMessage(aMessage);
 
@@ -4726,23 +4815,21 @@
 {
     otError      error = OT_ERROR_NONE;
     Ip6::Address destination;
-    Message *    message = NULL;
+    Message *    message = nullptr;
 
-    VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = NewMleMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
     SuccessOrExit(error = AppendHeader(*message, Header::kCommandTimeSync));
 
     message->SetTimeSync(true);
 
-    destination.Clear();
-    destination.mFields.m16[0] = HostSwap16(0xff02);
-    destination.mFields.m16[7] = HostSwap16(0x0001);
+    destination.SetToLinkLocalAllNodesMulticast();
     SuccessOrExit(error = SendMessage(*message, destination));
 
     LogMleMessage("Send Time Sync", destination);
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp
index a70638e..12379f3 100644
--- a/src/core/thread/mle_router.hpp
+++ b/src/core/thread/mle_router.hpp
@@ -26,15 +26,887 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
+/**
+ * @file
+ *   This file includes definitions for MLE functionality required by the Thread Router and Leader roles.
+ */
+
 #ifndef MLE_ROUTER_HPP_
 #define MLE_ROUTER_HPP_
 
-#if OPENTHREAD_MTD
-#include "mle_router_mtd.hpp"
-#elif OPENTHREAD_FTD
-#include "mle_router_ftd.hpp"
-#else
-#error "Please define OPENTHREAD_MTD=1 or OPENTHREAD_FTD=1"
+#include "openthread-core-config.h"
+
+#include <openthread/thread_ftd.h>
+
+#include "coap/coap.hpp"
+#include "coap/coap_message.hpp"
+#include "common/timer.hpp"
+#include "common/trickle_timer.hpp"
+#include "mac/mac_types.hpp"
+#include "meshcop/meshcop_tlvs.hpp"
+#include "net/icmp6.hpp"
+#include "net/udp6.hpp"
+#include "thread/child_table.hpp"
+#include "thread/mle.hpp"
+#include "thread/mle_tlvs.hpp"
+#include "thread/router_table.hpp"
+#include "thread/thread_tlvs.hpp"
+#include "thread/topology.hpp"
+
+namespace ot {
+namespace Mle {
+
+/**
+ * @addtogroup core-mle-router
+ *
+ * @brief
+ *   This module includes definitions for MLE functionality required by the Thread Router and Leader roles.
+ *
+ * @{
+ */
+
+#if OPENTHREAD_FTD
+
+/**
+ * This class implements MLE functionality required by the Thread Router and Leader roles.
+ *
+ */
+class MleRouter : public Mle
+{
+    friend class Mle;
+    friend class ot::Instance;
+
+public:
+    /**
+     * This constructor initializes the object.
+     *
+     * @param[in]  aInstance     A reference to the OpenThread instance.
+     *
+     */
+    explicit MleRouter(Instance &aInstance);
+
+    /**
+     * This method indicates whether or not the device is router-eligible.
+     *
+     * @retval true   If device is router-eligible.
+     * @retval false  If device is not router-eligible.
+     *
+     */
+    bool IsRouterEligible(void) const;
+
+    /**
+     * This method sets whether or not the device is router-eligible.
+     *
+     * If @p aEligible is false and the device is currently operating as a router, this call will cause the device to
+     * detach and attempt to reattach as a child.
+     *
+     * @param[in]  aEligible  TRUE to configure device router-eligible, FALSE otherwise.
+     *
+     * @retval OT_ERROR_NONE         Successfully set the router-eligible configuration.
+     * @retval OT_ERROR_NOT_CAPABLE  The device is not capable of becoming a router.
+     *
+     */
+    otError SetRouterEligible(bool aEligible);
+
+    /**
+     * This method indicates whether a node is the only router on the network.
+     *
+     * @retval TRUE   It is the only router in the network.
+     * @retval FALSE  It is a child or is not a single router in the network.
+     *
+     */
+    bool IsSingleton(void);
+
+    /**
+     * This method generates an Address Solicit request for a Router ID.
+     *
+     * @param[in]  aStatus  The reason for requesting a Router ID.
+     *
+     * @retval OT_ERROR_NONE           Successfully generated an Address Solicit message.
+     * @retval OT_ERROR_NOT_CAPABLE    Device is not capable of becoming a router
+     * @retval OT_ERROR_INVALID_STATE  Thread is not enabled
+     *
+     */
+    otError BecomeRouter(ThreadStatusTlv::Status aStatus);
+
+    /**
+     * This method causes the Thread interface to become a Leader and start a new partition.
+     *
+     * @retval OT_ERROR_NONE           Successfully become a Leader and started a new partition.
+     * @retval OT_ERROR_NOT_CAPABLE    Device is not capable of becoming a leader
+     * @retval OT_ERROR_INVALID_STATE  Thread is not enabled
+     *
+     */
+    otError BecomeLeader(void);
+
+    /**
+     * This method returns the Leader Weighting value for this Thread interface.
+     *
+     * @returns The Leader Weighting value for this Thread interface.
+     *
+     */
+    uint8_t GetLeaderWeight(void) const { return mLeaderWeight; }
+
+    /**
+     * This method sets the Leader Weighting value for this Thread interface.
+     *
+     * @param[in]  aWeight  The Leader Weighting value.
+     *
+     */
+    void SetLeaderWeight(uint8_t aWeight) { mLeaderWeight = aWeight; }
+
+    /**
+     * This method returns the fixed Partition Id of Thread network partition for certification testing.
+     *
+     * @returns The Partition Id for this Thread network partition.
+     *
+     */
+    uint32_t GetLeaderPartitionId(void) const { return mFixedLeaderPartitionId; }
+
+    /**
+     * This method sets the fixed Partition Id for Thread network partition for certification testing.
+     *
+     * @param[in]  aPartitionId  The Leader Partition Id.
+     *
+     */
+    void SetLeaderPartitionId(uint32_t aPartitionId) { mFixedLeaderPartitionId = aPartitionId; }
+
+    /**
+     * This method sets the preferred Router Id. Upon becoming a router/leader the node
+     * attempts to use this Router Id. If the preferred Router Id is not set or if it
+     * can not be used, a randomly generated router Id is picked.
+     * This property can be set when he device role is detached or disabled.
+     *
+     * @param[in]  aRouterId             The preferred Router Id.
+     *
+     * @retval OT_ERROR_NONE          Successfully set the preferred Router Id.
+     * @retval OT_ERROR_INVALID_STATE Could not set (role is other than detached and disabled)
+     *
+     */
+    otError SetPreferredRouterId(uint8_t aRouterId);
+
+    /**
+     * This method gets the Partition Id which the device joined successfully once.
+     *
+     */
+    uint32_t GetPreviousPartitionId(void) const { return mPreviousPartitionId; }
+
+    /**
+     * This method sets the Partition Id which the device joins successfully.
+     *
+     * @param[in]  aPartitionId   The Partition Id.
+     *
+     */
+    void SetPreviousPartitionId(uint32_t aPartitionId) { mPreviousPartitionId = aPartitionId; }
+
+    /**
+     * This method sets the Router Id.
+     *
+     * @param[in]  aRouterId   The Router Id.
+     *
+     */
+    void SetRouterId(uint8_t aRouterId);
+
+    /**
+     * This method returns the next hop towards an RLOC16 destination.
+     *
+     * @param[in]  aDestination  The RLOC16 of the destination.
+     *
+     * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise.
+     *
+     */
+    uint16_t GetNextHop(uint16_t aDestination);
+
+    /**
+     * This method returns the NETWORK_ID_TIMEOUT value.
+     *
+     * @returns The NETWORK_ID_TIMEOUT value.
+     *
+     */
+    uint8_t GetNetworkIdTimeout(void) const { return mNetworkIdTimeout; }
+
+    /**
+     * This method sets the NETWORK_ID_TIMEOUT value.
+     *
+     * @param[in]  aTimeout  The NETWORK_ID_TIMEOUT value.
+     *
+     */
+    void SetNetworkIdTimeout(uint8_t aTimeout) { mNetworkIdTimeout = aTimeout; }
+
+    /**
+     * This method returns the route cost to a RLOC16.
+     *
+     * @param[in]  aRloc16  The RLOC16 of the destination.
+     *
+     * @returns The route cost to a RLOC16.
+     *
+     */
+    uint8_t GetRouteCost(uint16_t aRloc16) const;
+
+    /**
+     * This method returns the link cost to the given Router.
+     *
+     * @param[in]  aRouterId  The Router ID.
+     *
+     * @returns The link cost to the Router.
+     *
+     */
+    uint8_t GetLinkCost(uint8_t aRouterId);
+
+    /**
+     * This method returns the minimum cost to the given router.
+     *
+     * @param[in]  aRloc16  The short address of the given router.
+     *
+     * @returns The minimum cost to the given router (via direct link or forwarding).
+     *
+     */
+    uint8_t GetCost(uint16_t aRloc16);
+
+    /**
+     * This method returns the ROUTER_SELECTION_JITTER value.
+     *
+     * @returns The ROUTER_SELECTION_JITTER value.
+     *
+     */
+    uint8_t GetRouterSelectionJitter(void) const { return mRouterSelectionJitter; }
+
+    /**
+     * This method sets the ROUTER_SELECTION_JITTER value.
+     *
+     * @returns The ROUTER_SELECTION_JITTER value.
+     *
+     */
+    otError SetRouterSelectionJitter(uint8_t aRouterJitter);
+
+    /**
+     * This method returns the current router selection jitter timeout value.
+     *
+     * @returns The current router selection jitter timeout value.
+     *
+     */
+    uint8_t GetRouterSelectionJitterTimeout(void) const { return mRouterSelectionJitterTimeout; }
+
+    /**
+     * This method returns the ROUTER_UPGRADE_THRESHOLD value.
+     *
+     * @returns The ROUTER_UPGRADE_THRESHOLD value.
+     *
+     */
+    uint8_t GetRouterUpgradeThreshold(void) const { return mRouterUpgradeThreshold; }
+
+    /**
+     * This method sets the ROUTER_UPGRADE_THRESHOLD value.
+     *
+     * @returns The ROUTER_UPGRADE_THRESHOLD value.
+     *
+     */
+    void SetRouterUpgradeThreshold(uint8_t aThreshold) { mRouterUpgradeThreshold = aThreshold; }
+
+    /**
+     * This method returns the ROUTER_DOWNGRADE_THRESHOLD value.
+     *
+     * @returns The ROUTER_DOWNGRADE_THRESHOLD value.
+     *
+     */
+    uint8_t GetRouterDowngradeThreshold(void) const { return mRouterDowngradeThreshold; }
+
+    /**
+     * This method sets the ROUTER_DOWNGRADE_THRESHOLD value.
+     *
+     * @returns The ROUTER_DOWNGRADE_THRESHOLD value.
+     *
+     */
+    void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; }
+
+    /**
+     * This method returns if the REED is expected to become Router soon.
+     *
+     * @retval TRUE   If the REED is going to become Router.
+     * @retval FALSE  Otherwise.
+     *
+     */
+    bool IsExpectedToBecomeRouter(void) const;
+
+    /**
+     * This method removes a link to a neighbor.
+     *
+     * @param[in]  aNeighbor  A reference to the neighbor object.
+     *
+     */
+    void RemoveNeighbor(Neighbor &aNeighbor);
+
+    /**
+     * This method invalidates a direct link to a neighboring router (due to failed link-layer acks).
+     *
+     * @param[in]  aRouter  A reference to the router object.
+     *
+     */
+    void RemoveRouterLink(Router &aRouter);
+
+    /**
+     * This method restores children information from non-volatile memory.
+     *
+     */
+    void RestoreChildren(void);
+
+    /**
+     * This method remove a stored child information from non-volatile memory.
+     *
+     * @param[in]  aChildRloc16   The child RLOC16 to remove.
+     *
+     * @retval  OT_ERROR_NONE        Successfully remove child.
+     * @retval  OT_ERROR_NOT_FOUND   There is no specified child stored in non-volatile memory.
+     *
+     */
+    otError RemoveStoredChild(uint16_t aChildRloc16);
+
+    /**
+     * This method store a child information into non-volatile memory.
+     *
+     * @param[in]  aChild          A reference to the child to store.
+     *
+     * @retval  OT_ERROR_NONE      Successfully store child.
+     * @retval  OT_ERROR_NO_BUFS   Insufficient available buffers to store child.
+     *
+     */
+    otError StoreChild(const Child &aChild);
+
+    /**
+     * This method returns a pointer to a Neighbor object.
+     *
+     * @param[in]  aAddress  The address of the Neighbor.
+     *
+     * @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
+     *
+     */
+    Neighbor *GetNeighbor(uint16_t aAddress);
+
+    /**
+     * This method returns a pointer to a Neighbor object.
+     *
+     * @param[in]  aAddress  The address of the Neighbor.
+     *
+     * @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
+     *
+     */
+    Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress);
+
+    /**
+     * This method returns a pointer to a Neighbor object.
+     *
+     * @param[in]  aAddress  The address of the Neighbor.
+     *
+     * @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
+     *
+     */
+    Neighbor *GetNeighbor(const Mac::Address &aAddress);
+
+    /**
+     * This method returns a pointer to a Neighbor object.
+     *
+     * @param[in]  aAddress  The address of the Neighbor.
+     *
+     * @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
+     *
+     */
+    Neighbor *GetNeighbor(const Ip6::Address &aAddress);
+
+    /**
+     * This method returns a pointer to a Neighbor object if a one-way link is maintained
+     * as in the instance of an FTD child with neighbor routers.
+     *
+     * @param[in]  aAddress  The address of the Neighbor.
+     *
+     * @returns A pointer to the Neighbor corresponding to @p aAddress, nullptr otherwise.
+     *
+     */
+    Neighbor *GetRxOnlyNeighborRouter(const Mac::Address &aAddress);
+
+    /**
+     * This method retains diagnostic information for an attached child by Child ID or RLOC16.
+     *
+     * @param[in]   aChildId    The Child ID or RLOC16 for an attached child.
+     * @param[out]  aChildInfo  The child information.
+     *
+     */
+    otError GetChildInfoById(uint16_t aChildId, otChildInfo &aChildInfo);
+
+    /**
+     * This method retains diagnostic information for an attached child by the internal table index.
+     *
+     * @param[in]   aChildIndex  The table index.
+     * @param[out]  aChildInfo   The child information.
+     *
+     */
+    otError GetChildInfoByIndex(uint16_t aChildIndex, otChildInfo &aChildInfo);
+
+    /**
+     * This methods gets the next IPv6 address (using an iterator) for a given child.
+     *
+     * @param[in]     aChildIndex  The child index.
+     * @param[inout]  aIterator    A reference to iterator. On success the iterator will be updated to point to next
+     *                             entry in the list.
+     * @param[out]    aAddress     A reference to an IPv6 address where the child's next address is placed (on success).
+     *
+     * @retval OT_ERROR_NONE          Successfully found the next address (@p aAddress and @ aIterator are updated).
+     * @retval OT_ERROR_NOT_FOUND     The child has no subsequent IPv6 address entry.
+     * @retval OT_ERROR_INVALID_ARGS  Child at @p aChildIndex is not valid.
+     *
+     */
+    otError GetChildNextIp6Address(uint16_t aChildIndex, Child::Ip6AddressIterator &aIterator, Ip6::Address &aAddress);
+
+    /**
+     * This method indicates whether or not the RLOC16 is an MTD child of this device.
+     *
+     * @param[in]  aRloc16  The RLOC16.
+     *
+     * @retval TRUE if @p aRloc16 is an MTD child of this device.
+     * @retval FALSE if @p aRloc16 is not an MTD child of this device.
+     *
+     */
+    bool IsMinimalChild(uint16_t aRloc16);
+
+    /**
+     * This method gets the next neighbor information. It is used to iterate through the entries of
+     * the neighbor table.
+     *
+     * @param[inout]  aIterator  A reference to the iterator context. To get the first neighbor entry
+                                 it should be set to OT_NEIGHBOR_INFO_ITERATOR_INIT.
+     * @param[out]    aNeighInfo The neighbor information.
+     *
+     * @retval OT_ERROR_NONE          Successfully found the next neighbor entry in table.
+     * @retval OT_ERROR_NOT_FOUND     No subsequent neighbor entry exists in the table.
+     *
+     */
+    otError GetNextNeighborInfo(otNeighborInfoIterator &aIterator, otNeighborInfo &aNeighInfo);
+
+    /**
+     * This method indicates whether or not the given Thread partition attributes are preferred.
+     *
+     * @param[in]  aSingletonA   Whether or not the Thread Partition A has a single router.
+     * @param[in]  aLeaderDataA  A reference to Thread Partition A's Leader Data.
+     * @param[in]  aSingletonB   Whether or not the Thread Partition B has a single router.
+     * @param[in]  aLeaderDataB  A reference to Thread Partition B's Leader Data.
+     *
+     * @retval 1   If partition A is preferred.
+     * @retval 0   If partition A and B have equal preference.
+     * @retval -1  If partition B is preferred.
+     *
+     */
+    static int ComparePartitions(bool              aSingletonA,
+                                 const LeaderData &aLeaderDataA,
+                                 bool              aSingletonB,
+                                 const LeaderData &aLeaderDataB);
+
+    /**
+     * This method checks if the destination is reachable.
+     *
+     * @param[in]  aMeshDest   The RLOC16 of the destination.
+     * @param[in]  aIp6Header  A reference to the IPv6 header of the message.
+     *
+     * @retval OT_ERROR_NONE      The destination is reachable.
+     * @retval OT_ERROR_NO_ROUTE  The destination is not reachable and the message should be dropped.
+     *
+     */
+    otError CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header);
+
+    /**
+     * This method resolves 2-hop routing loops.
+     *
+     * @param[in]  aSourceMac   The RLOC16 of the previous hop.
+     * @param[in]  aDestRloc16  The RLOC16 of the final destination.
+     *
+     */
+    void ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16);
+
+    /**
+     * This method checks if a given Router ID has correct value.
+     *
+     * @param[in]  aRouterId  The Router ID value.
+     *
+     * @retval TRUE   If @p aRouterId is in correct range [0..62].
+     * @retval FALSE  If @p aRouterId is not a valid Router ID.
+     *
+     */
+    static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
+
+    /**
+     * This method fills an ConnectivityTlv.
+     *
+     * @param[out]  aTlv  A reference to the tlv to be filled.
+     *
+     */
+    void FillConnectivityTlv(ConnectivityTlv &aTlv);
+
+    /**
+     * This method fills an RouteTlv.
+     *
+     * @param[out]  aTlv  A reference to the tlv to be filled.
+     *
+     */
+    void FillRouteTlv(RouteTlv &aTlv);
+
+    /**
+     * This method generates an MLE Child Update Request message to be sent to the parent.
+     *
+     * @retval OT_ERROR_NONE     Successfully generated an MLE Child Update Request message.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffers to generate the MLE Child Update Request message.
+     *
+     */
+    otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
+
+    otError SendLinkRequest(Neighbor *aNeighbor);
+
+#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
+    /**
+     * This method sets steering data out of band
+     *
+     * @param[in]  aExtAddress  Value used to set steering data
+     *                          All zeros clears steering data
+     *                          All 0xFFs sets steering data to 0xFF
+     *                          Anything else is used to compute the bloom filter
+     *
+     */
+    void SetSteeringData(const Mac::ExtAddress *aExtAddress);
 #endif
 
+    /**
+     * This method gets the assigned parent priority.
+     *
+     * @returns The assigned parent priority value, -2 means not assigned.
+     *
+     */
+    int8_t GetAssignParentPriority(void) const { return mParentPriority; }
+
+    /**
+     * This method sets the parent priority.
+     *
+     * @param[in]  aParentPriority  The parent priority value.
+     *
+     * @retval OT_ERROR_NONE           Successfully set the parent priority.
+     * @retval OT_ERROR_INVALID_ARGS   If the parent priority value is not among 1, 0, -1 and -2.
+     *
+     */
+    otError SetAssignParentPriority(int8_t aParentPriority);
+
+    /**
+     * This method gets the longest MLE Timeout TLV for all active MTD children.
+     *
+     * @param[out]  aTimeout  A reference to where the information is placed.
+     *
+     * @retval OT_ERROR_NONE           Successfully get the max child timeout
+     * @retval OT_ERROR_INVALID_STATE  Not an active router
+     * @retval OT_ERROR_NOT_FOUND      NO MTD child
+     *
+     */
+    otError GetMaxChildTimeout(uint32_t &aTimeout) const;
+
+    /**
+     * This method register the "neighbor table changed" callback function.
+     *
+     * The provided callback (if non-nullptr) will be invoked when a child/router entry is being added/remove to/from
+     * the neighbor table. Subsequent calls to this method will overwrite the previous callback.
+     *
+     * @param[in] aCallback    A pointer to callback handler function.
+     *
+     */
+    void RegisterNeighborTableChangedCallback(otNeighborTableCallback aCallback)
+    {
+        mNeighborTableChangedCallback = aCallback;
+    }
+
+    /**
+     * This method signals a "neighbor table changed" events (invoking the registered callback function).
+     *
+     * @param[in] aEvent     The event to emit (child/router added/removed).
+     * @param[in] aNeighbor  The neighbor that is being added/removed.
+     *
+     */
+    void Signal(otNeighborTableEvent aEvent, Neighbor &aNeighbor);
+
+    /**
+     * This method returns whether the device has any sleepy children subscribed the address.
+     *
+     * @param[in]  aAddress  The reference of the address.
+     *
+     * @retval TRUE   If the device has any sleepy children subscribed the address @p aAddress.
+     * @retval FALSE  If the device doesn't have any sleepy children subscribed the address @p aAddress.
+     *
+     */
+    bool HasSleepyChildrenSubscribed(const Ip6::Address &aAddress);
+
+    /**
+     * This method returns whether the specific child subscribed the address.
+     *
+     * @param[in]  aAddress  The reference of the address.
+     * @param[in]  aChild    The reference of the child.
+     *
+     * @retval TRUE   If the sleepy child @p aChild subscribed the address @p aAddress.
+     * @retval FALSE  If the sleepy child @p aChild did not subscribe the address @p aAddress.
+     *
+     */
+    bool IsSleepyChildSubscribed(const Ip6::Address &aAddress, Child &aChild);
+
+    /**
+     * This method resets the MLE Advertisement Trickle timer interval.
+     *
+     */
+    void ResetAdvertiseInterval(void);
+
+    /**
+     * This static method converts link quality to route cost.
+     *
+     * @param[in]  aLinkQuality  The link quality.
+     *
+     * @returns The link cost corresponding to @p aLinkQuality.
+     *
+     */
+    static uint8_t LinkQualityToCost(uint8_t aLinkQuality);
+
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    /**
+     * This method generates an MLE Time Synchronization message.
+     *
+     * @retval OT_ERROR_NONE     Successfully sent an MLE Time Synchronization message.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffers to generate the MLE Time Synchronization message.
+     *
+     */
+    otError SendTimeSync(void);
+#endif
+
+#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    /**
+     * This method sets the delay before registering Backbone Router service.
+     *
+     * @param[in]  aDelay  The delay before registering Backbone Router service.
+     *
+     */
+    void SetBackboneRouterRegistrationDelay(uint8_t aDelay) { mBackboneRouterRegistrationDelay = aDelay; }
+#endif
+
+    /**
+     * This method gets the maximum number of IP addresses that each MTD child may register with this device as parent.
+     *
+     * @returns The maximum number of IP addresses that each MTD child may register with this device as parent.
+     *
+     */
+    uint8_t GetMaxChildIpAddresses(void) const;
+
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
+    /**
+     * This method sets/restores the maximum number of IP addresses that each MTD child may register with this
+     * device as parent.
+     *
+     * @param[in]  aMaxIpAddresses  The maximum number of IP addresses that each MTD child may register with this
+     *                              device as parent. 0 to clear the setting and restore the default.
+     *
+     * @retval OT_ERROR_NONE           Successfully set/cleared the number.
+     * @retval OT_ERROR_INVALID_ARGS   If exceeds the allowed maximum number.
+     *
+     */
+    otError SetMaxChildIpAddresses(uint8_t aMaxIpAddresses);
+#endif
+
+private:
+    enum
+    {
+        kDiscoveryMaxJitter = 250u,  ///< Maximum jitter time used to delay Discovery Responses in milliseconds.
+        kStateUpdatePeriod  = 1000u, ///< State update period in milliseconds.
+        kUnsolicitedDataResponseJitter = 500u, ///< Maximum delay before unsolicited Data Response in milliseconds.
+    };
+
+    otError AppendConnectivity(Message &aMessage);
+    otError AppendChildAddresses(Message &aMessage, Child &aChild);
+    otError AppendRoute(Message &aMessage);
+    otError AppendActiveDataset(Message &aMessage);
+    otError AppendPendingDataset(Message &aMessage);
+    otError GetChildInfo(Child &aChild, otChildInfo &aChildInfo);
+    void    GetNeighborInfo(Neighbor &aNeighbor, otNeighborInfo &aNeighInfo);
+    void    RefreshStoredChildren(void);
+    void    HandleDetachStart(void);
+    void    HandleChildStart(AttachMode aMode);
+    void    HandleLinkRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor);
+    void    HandleLinkAccept(const Message &         aMessage,
+                             const Ip6::MessageInfo &aMessageInfo,
+                             uint32_t                aKeySequence,
+                             Neighbor *              aNeighbor);
+    otError HandleLinkAccept(const Message &         aMessage,
+                             const Ip6::MessageInfo &aMessageInfo,
+                             uint32_t                aKeySequence,
+                             Neighbor *              aNeighbor,
+                             bool                    aRequest);
+    void    HandleLinkAcceptAndRequest(const Message &         aMessage,
+                                       const Ip6::MessageInfo &aMessageInfo,
+                                       uint32_t                aKeySequence,
+                                       Neighbor *              aNeighbor);
+    otError HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *);
+    void    HandleParentRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    void    HandleChildIdRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence);
+    void HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence);
+    void HandleChildUpdateResponse(const Message &         aMessage,
+                                   const Ip6::MessageInfo &aMessageInfo,
+                                   uint32_t                aKeySequence,
+                                   Neighbor *              aNeighbor);
+    void HandleDataRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor);
+    void HandleNetworkDataUpdateRouter(void);
+    void HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
+    void HandleTimeSync(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor);
+#endif
+
+    otError ProcessRouteTlv(const RouteTlv &aRoute);
+    void    StopAdvertiseTimer(void);
+    otError SendAddressSolicit(ThreadStatusTlv::Status aStatus);
+    void    SendAddressRelease(void);
+    void    SendAddressSolicitResponse(const Coap::Message &   aRequest,
+                                       const Router *          aRouter,
+                                       const Ip6::MessageInfo &aMessageInfo);
+    void    SendAdvertisement(void);
+    otError SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
+                           Neighbor *              aNeighbor,
+                           const RequestedTlvs &   aRequestedTlvs,
+                           const Challenge &       aChallenge);
+    void    SendParentResponse(Child *aChild, const Challenge &aChallenge, bool aRoutersOnlyRequest);
+    otError SendChildIdResponse(Child &aChild);
+    otError SendChildUpdateRequest(Child &aChild);
+    void    SendChildUpdateResponse(Child *                 aChild,
+                                    const Ip6::MessageInfo &aMessageInfo,
+                                    const uint8_t *         aTlvs,
+                                    uint8_t                 aTlvsLength,
+                                    const Challenge &       aChallenge);
+    void SendDataResponse(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aDelay);
+    otError SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId);
+
+    void    SetStateRouter(uint16_t aRloc16);
+    void    SetStateLeader(uint16_t aRloc16);
+    void    StopLeader(void);
+    void    SynchronizeChildNetworkData(void);
+    otError UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, Child &aChild);
+    void    UpdateRoutes(const RouteTlv &aRoute, uint8_t aRouterId);
+    bool    UpdateLinkQualityOut(const RouteTlv &aRoute, Router &aNeighbor, bool &aResetAdvInterval);
+
+    static void HandleAddressSolicitResponse(void *               aContext,
+                                             otMessage *          aMessage,
+                                             const otMessageInfo *aMessageInfo,
+                                             otError              aResult);
+    void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, otError aResult);
+    static void HandleAddressRelease(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+    void        HandleAddressRelease(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+    static void HandleAddressSolicit(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+    void        HandleAddressSolicit(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
+    static bool IsSingleton(const RouteTlv &aRouteTlv);
+
+    void HandlePartitionChange(void);
+
+    void SetChildStateToValid(Child &aChild);
+    bool HasChildren(void);
+    void RemoveChildren(void);
+    bool HasMinDowngradeNeighborRouters(void);
+    bool HasOneNeighborWithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId);
+    bool HasSmallNumberOfChildren(void);
+
+    static bool HandleAdvertiseTimer(TrickleTimer &aTimer);
+    bool        HandleAdvertiseTimer(void);
+    static void HandleStateUpdateTimer(Timer &aTimer);
+    void        HandleStateUpdateTimer(void);
+
+    TrickleTimer mAdvertiseTimer;
+    TimerMilli   mStateUpdateTimer;
+
+    Coap::Resource mAddressSolicit;
+    Coap::Resource mAddressRelease;
+
+    ChildTable  mChildTable;
+    RouterTable mRouterTable;
+
+    otNeighborTableCallback mNeighborTableChangedCallback;
+
+    uint8_t   mChallengeTimeout;
+    Challenge mChallenge;
+
+    uint16_t mNextChildId;
+    uint8_t  mNetworkIdTimeout;
+    uint8_t  mRouterUpgradeThreshold;
+    uint8_t  mRouterDowngradeThreshold;
+    uint8_t  mLeaderWeight;
+    uint32_t mFixedLeaderPartitionId; ///< only for certification testing
+    bool     mRouterEligible : 1;
+    bool     mAddressSolicitPending : 1;
+    bool     mAddressSolicitRejected : 1;
+
+    uint8_t mRouterId;
+    uint8_t mPreviousRouterId;
+
+    uint32_t mPreviousPartitionIdRouter;         ///< The partition ID when last operating as a router
+    uint32_t mPreviousPartitionId;               ///< The partition ID when last attached
+    uint8_t  mPreviousPartitionRouterIdSequence; ///< The router ID sequence when last attached
+    uint8_t  mPreviousPartitionIdTimeout;        ///< The partition ID timeout when last attached
+
+    uint8_t mRouterSelectionJitter;        ///< The variable to save the assigned jitter value.
+    uint8_t mRouterSelectionJitterTimeout; ///< The Timeout prior to request/release Router ID.
+
+    int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned.
+#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    uint8_t mBackboneRouterRegistrationDelay; ///< Delay before registering Backbone Router service.
+#endif
+#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
+    uint8_t mMaxChildIpAddresses;
+#endif
+
+#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
+    MeshCoP::SteeringData mSteeringData;
+#endif
+};
+
+#endif // OPENTHREAD_FTD
+
+#if OPENTHREAD_MTD
+
+class MleRouter : public Mle
+{
+    friend class Mle;
+    friend class ot::Instance;
+
+public:
+    explicit MleRouter(Instance &aInstance)
+        : Mle(aInstance)
+    {
+    }
+
+    bool IsSingleton(void) const { return false; }
+
+    uint16_t GetNextHop(uint16_t aDestination) const { return Mle::GetNextHop(aDestination); }
+
+    uint8_t GetCost(uint16_t) { return 0; }
+
+    otError RemoveNeighbor(Neighbor &) { return BecomeDetached(); }
+    void    RemoveRouterLink(Router &) { IgnoreError(BecomeDetached()); }
+
+    Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress) { return Mle::GetNeighbor(aAddress); }
+    Neighbor *GetNeighbor(const Mac::Address &aAddress) { return Mle::GetNeighbor(aAddress); }
+
+    otError GetNextNeighborInfo(otNeighborInfoIterator &, otNeighborInfo &) { return OT_ERROR_NOT_IMPLEMENTED; }
+
+    static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
+
+    otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
+
+    otError CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header)
+    {
+        return Mle::CheckReachability(aMeshDest, aIp6Header);
+    }
+};
+
+#endif // OPENTHREAD_MTD
+
+} // namespace Mle
+
+/**
+ * @}
+ */
+
+} // namespace ot
+
 #endif // MLE_ROUTER_HPP_
diff --git a/src/core/thread/mle_router_ftd.hpp b/src/core/thread/mle_router_ftd.hpp
deleted file mode 100644
index bc10717..0000000
--- a/src/core/thread/mle_router_ftd.hpp
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes definitions for MLE functionality required by the Thread Router and Leader roles.
- */
-
-#ifndef MLE_ROUTER_FTD_HPP_
-#define MLE_ROUTER_FTD_HPP_
-
-#include "openthread-core-config.h"
-
-#include <openthread/thread_ftd.h>
-
-#include "coap/coap.hpp"
-#include "coap/coap_message.hpp"
-#include "common/timer.hpp"
-#include "common/trickle_timer.hpp"
-#include "mac/mac_types.hpp"
-#include "meshcop/meshcop_tlvs.hpp"
-#include "net/icmp6.hpp"
-#include "net/udp6.hpp"
-#include "thread/child_table.hpp"
-#include "thread/mle.hpp"
-#include "thread/mle_tlvs.hpp"
-#include "thread/router_table.hpp"
-#include "thread/thread_tlvs.hpp"
-#include "thread/topology.hpp"
-
-namespace ot {
-namespace Mle {
-
-/**
- * @addtogroup core-mle-router
- *
- * @brief
- *   This module includes definitions for MLE functionality required by the Thread Router and Leader roles.
- *
- * @{
- */
-
-/**
- * This class implements MLE functionality required by the Thread Router and Leader roles.
- *
- */
-class MleRouter : public Mle
-{
-    friend class Mle;
-    friend class ot::Instance;
-
-public:
-    /**
-     * This constructor initializes the object.
-     *
-     * @param[in]  aInstance     A reference to the OpenThread instance.
-     *
-     */
-    explicit MleRouter(Instance &aInstance);
-
-    /**
-     * This method indicates whether or not the device is router-eligible.
-     *
-     * @retval true   If device is router-eligible.
-     * @retval false  If device is not router-eligible.
-     *
-     */
-    bool IsRouterEligible(void) const;
-
-    /**
-     * This method sets whether or not the device is router-eligible.
-     *
-     * If @p aEligible is false and the device is currently operating as a router, this call will cause the device to
-     * detach and attempt to reattach as a child.
-     *
-     * @param[in]  aEligible  TRUE to configure device router-eligible, FALSE otherwise.
-     *
-     * @retval OT_ERROR_NONE         Successfully set the router-eligible configuration.
-     * @retval OT_ERROR_NOT_CAPABLE  The device is not capable of becoming a router.
-     *
-     */
-    otError SetRouterEligible(bool aEligible);
-
-    /**
-     * This method indicates whether a node is the only router on the network.
-     *
-     * @retval TRUE   It is the only router in the network.
-     * @retval FALSE  It is a child or is not a single router in the network.
-     *
-     */
-    bool IsSingleton(void);
-
-    /**
-     * This method generates an Address Solicit request for a Router ID.
-     *
-     * @param[in]  aStatus  The reason for requesting a Router ID.
-     *
-     * @retval OT_ERROR_NONE           Successfully generated an Address Solicit message.
-     * @retval OT_ERROR_NOT_CAPABLE    Device is not capable of becoming a router
-     * @retval OT_ERROR_INVALID_STATE  Thread is not enabled
-     *
-     */
-    otError BecomeRouter(ThreadStatusTlv::Status aStatus);
-
-    /**
-     * This method causes the Thread interface to become a Leader and start a new partition.
-     *
-     * @retval OT_ERROR_NONE           Successfully become a Leader and started a new partition.
-     * @retval OT_ERROR_NOT_CAPABLE    Device is not capable of becoming a leader
-     * @retval OT_ERROR_INVALID_STATE  Thread is not enabled
-     *
-     */
-    otError BecomeLeader(void);
-
-    /**
-     * This method returns the Leader Weighting value for this Thread interface.
-     *
-     * @returns The Leader Weighting value for this Thread interface.
-     *
-     */
-    uint8_t GetLeaderWeight(void) const { return mLeaderWeight; }
-
-    /**
-     * This method sets the Leader Weighting value for this Thread interface.
-     *
-     * @param[in]  aWeight  The Leader Weighting value.
-     *
-     */
-    void SetLeaderWeight(uint8_t aWeight) { mLeaderWeight = aWeight; }
-
-    /**
-     * This method returns the fixed Partition Id of Thread network partition for certification testing.
-     *
-     * @returns The Partition Id for this Thread network partition.
-     *
-     */
-    uint32_t GetLeaderPartitionId(void) const { return mFixedLeaderPartitionId; }
-
-    /**
-     * This method sets the fixed Partition Id for Thread network partition for certification testing.
-     *
-     * @param[in]  aPartitionId  The Leader Partition Id.
-     *
-     */
-    void SetLeaderPartitionId(uint32_t aPartitionId) { mFixedLeaderPartitionId = aPartitionId; }
-
-    /**
-     * This method sets the preferred Router Id. Upon becoming a router/leader the node
-     * attempts to use this Router Id. If the preferred Router Id is not set or if it
-     * can not be used, a randomly generated router Id is picked.
-     * This property can be set when he device role is detached or disabled.
-     *
-     * @param[in]  aRouterId             The preferred Router Id.
-     *
-     * @retval OT_ERROR_NONE          Successfully set the preferred Router Id.
-     * @retval OT_ERROR_INVALID_STATE Could not set (role is other than detached and disabled)
-     *
-     */
-    otError SetPreferredRouterId(uint8_t aRouterId);
-
-    /**
-     * This method gets the Partition Id which the device joined successfully once.
-     *
-     */
-    uint32_t GetPreviousPartitionId(void) const { return mPreviousPartitionId; }
-
-    /**
-     * This method sets the Partition Id which the device joins successfully.
-     *
-     * @param[in]  aPartitionId   The Partition Id.
-     *
-     */
-    void SetPreviousPartitionId(uint32_t aPartitionId) { mPreviousPartitionId = aPartitionId; }
-
-    /**
-     * This method sets the Router Id.
-     *
-     * @param[in]  aRouterId   The Router Id.
-     *
-     */
-    void SetRouterId(uint8_t aRouterId);
-
-    /**
-     * This method returns the next hop towards an RLOC16 destination.
-     *
-     * @param[in]  aDestination  The RLOC16 of the destination.
-     *
-     * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise.
-     *
-     */
-    uint16_t GetNextHop(uint16_t aDestination);
-
-    /**
-     * This method returns the NETWORK_ID_TIMEOUT value.
-     *
-     * @returns The NETWORK_ID_TIMEOUT value.
-     *
-     */
-    uint8_t GetNetworkIdTimeout(void) const { return mNetworkIdTimeout; }
-
-    /**
-     * This method sets the NETWORK_ID_TIMEOUT value.
-     *
-     * @param[in]  aTimeout  The NETWORK_ID_TIMEOUT value.
-     *
-     */
-    void SetNetworkIdTimeout(uint8_t aTimeout) { mNetworkIdTimeout = aTimeout; }
-
-    /**
-     * This method returns the route cost to a RLOC16.
-     *
-     * @param[in]  aRloc16  The RLOC16 of the destination.
-     *
-     * @returns The route cost to a RLOC16.
-     *
-     */
-    uint8_t GetRouteCost(uint16_t aRloc16) const;
-
-    /**
-     * This method returns the link cost to the given Router.
-     *
-     * @param[in]  aRouterId  The Router ID.
-     *
-     * @returns The link cost to the Router.
-     *
-     */
-    uint8_t GetLinkCost(uint8_t aRouterId);
-
-    /**
-     * This method returns the minimum cost to the given router.
-     *
-     * @param[in]  aRloc16  The short address of the given router.
-     *
-     * @returns The minimum cost to the given router (via direct link or forwarding).
-     *
-     */
-    uint8_t GetCost(uint16_t aRloc16);
-
-    /**
-     * This method returns the ROUTER_SELECTION_JITTER value.
-     *
-     * @returns The ROUTER_SELECTION_JITTER value.
-     *
-     */
-    uint8_t GetRouterSelectionJitter(void) const { return mRouterSelectionJitter; }
-
-    /**
-     * This method sets the ROUTER_SELECTION_JITTER value.
-     *
-     * @returns The ROUTER_SELECTION_JITTER value.
-     *
-     */
-    otError SetRouterSelectionJitter(uint8_t aRouterJitter);
-
-    /**
-     * This method returns the current router selection jitter timeout value.
-     *
-     * @returns The current router selection jitter timeout value.
-     *
-     */
-    uint8_t GetRouterSelectionJitterTimeout(void) const { return mRouterSelectionJitterTimeout; }
-
-    /**
-     * This method returns the ROUTER_UPGRADE_THRESHOLD value.
-     *
-     * @returns The ROUTER_UPGRADE_THRESHOLD value.
-     *
-     */
-    uint8_t GetRouterUpgradeThreshold(void) const { return mRouterUpgradeThreshold; }
-
-    /**
-     * This method sets the ROUTER_UPGRADE_THRESHOLD value.
-     *
-     * @returns The ROUTER_UPGRADE_THRESHOLD value.
-     *
-     */
-    void SetRouterUpgradeThreshold(uint8_t aThreshold) { mRouterUpgradeThreshold = aThreshold; }
-
-    /**
-     * This method returns the ROUTER_DOWNGRADE_THRESHOLD value.
-     *
-     * @returns The ROUTER_DOWNGRADE_THRESHOLD value.
-     *
-     */
-    uint8_t GetRouterDowngradeThreshold(void) const { return mRouterDowngradeThreshold; }
-
-    /**
-     * This method sets the ROUTER_DOWNGRADE_THRESHOLD value.
-     *
-     * @returns The ROUTER_DOWNGRADE_THRESHOLD value.
-     *
-     */
-    void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; }
-
-    /**
-     * This method removes a link to a neighbor.
-     *
-     * @param[in]  aNeighbor  A reference to the neighbor object.
-     *
-     */
-    void RemoveNeighbor(Neighbor &aNeighbor);
-
-    /**
-     * This method restores children information from non-volatile memory.
-     *
-     */
-    void RestoreChildren(void);
-
-    /**
-     * This method remove a stored child information from non-volatile memory.
-     *
-     * @param[in]  aChildRloc16   The child RLOC16 to remove.
-     *
-     * @retval  OT_ERROR_NONE        Successfully remove child.
-     * @retval  OT_ERROR_NOT_FOUND   There is no specified child stored in non-volatile memory.
-     *
-     */
-    otError RemoveStoredChild(uint16_t aChildRloc16);
-
-    /**
-     * This method store a child information into non-volatile memory.
-     *
-     * @param[in]  aChild          A reference to the child to store.
-     *
-     * @retval  OT_ERROR_NONE      Successfully store child.
-     * @retval  OT_ERROR_NO_BUFS   Insufficient available buffers to store child.
-     *
-     */
-    otError StoreChild(const Child &aChild);
-
-    /**
-     * This method returns a pointer to a Neighbor object.
-     *
-     * @param[in]  aAddress  The address of the Neighbor.
-     *
-     * @returns A pointer to the Neighbor corresponding to @p aAddress, NULL otherwise.
-     *
-     */
-    Neighbor *GetNeighbor(uint16_t aAddress);
-
-    /**
-     * This method returns a pointer to a Neighbor object.
-     *
-     * @param[in]  aAddress  The address of the Neighbor.
-     *
-     * @returns A pointer to the Neighbor corresponding to @p aAddress, NULL otherwise.
-     *
-     */
-    Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress);
-
-    /**
-     * This method returns a pointer to a Neighbor object.
-     *
-     * @param[in]  aAddress  The address of the Neighbor.
-     *
-     * @returns A pointer to the Neighbor corresponding to @p aAddress, NULL otherwise.
-     *
-     */
-    Neighbor *GetNeighbor(const Mac::Address &aAddress);
-
-    /**
-     * This method returns a pointer to a Neighbor object.
-     *
-     * @param[in]  aAddress  The address of the Neighbor.
-     *
-     * @returns A pointer to the Neighbor corresponding to @p aAddress, NULL otherwise.
-     *
-     */
-    Neighbor *GetNeighbor(const Ip6::Address &aAddress);
-
-    /**
-     * This method returns a pointer to a Neighbor object if a one-way link is maintained
-     * as in the instance of an FTD child with neighbor routers.
-     *
-     * @param[in]  aAddress  The address of the Neighbor.
-     *
-     * @returns A pointer to the Neighbor corresponding to @p aAddress, NULL otherwise.
-     *
-     */
-    Neighbor *GetRxOnlyNeighborRouter(const Mac::Address &aAddress);
-
-    /**
-     * This method retains diagnostic information for an attached child by Child ID or RLOC16.
-     *
-     * @param[in]   aChildId    The Child ID or RLOC16 for an attached child.
-     * @param[out]  aChildInfo  The child information.
-     *
-     */
-    otError GetChildInfoById(uint16_t aChildId, otChildInfo &aChildInfo);
-
-    /**
-     * This method retains diagnostic information for an attached child by the internal table index.
-     *
-     * @param[in]   aChildIndex  The table index.
-     * @param[out]  aChildInfo   The child information.
-     *
-     */
-    otError GetChildInfoByIndex(uint16_t aChildIndex, otChildInfo &aChildInfo);
-
-    /**
-     * This methods gets the next IPv6 address (using an iterator) for a given child.
-     *
-     * @param[in]     aChildIndex  The child index.
-     * @param[inout]  aIterator    A reference to iterator. On success the iterator will be updated to point to next
-     *                             entry in the list.
-     * @param[out]    aAddress     A reference to an IPv6 address where the child's next address is placed (on success).
-     *
-     * @retval OT_ERROR_NONE          Successfully found the next address (@p aAddress and @ aIterator are updated).
-     * @retval OT_ERROR_NOT_FOUND     The child has no subsequent IPv6 address entry.
-     * @retval OT_ERROR_INVALID_ARGS  Child at @p aChildIndex is not valid.
-     *
-     */
-    otError GetChildNextIp6Address(uint16_t aChildIndex, Child::Ip6AddressIterator &aIterator, Ip6::Address &aAddress);
-
-    /**
-     * This method indicates whether or not the RLOC16 is an MTD child of this device.
-     *
-     * @param[in]  aRloc16  The RLOC16.
-     *
-     * @retval TRUE if @p aRloc16 is an MTD child of this device.
-     * @retval FALSE if @p aRloc16 is not an MTD child of this device.
-     *
-     */
-    bool IsMinimalChild(uint16_t aRloc16);
-
-    /**
-     * This method gets the next neighbor information. It is used to iterate through the entries of
-     * the neighbor table.
-     *
-     * @param[inout]  aIterator  A reference to the iterator context. To get the first neighbor entry
-                                 it should be set to OT_NEIGHBOR_INFO_ITERATOR_INIT.
-     * @param[out]    aNeighInfo The neighbor information.
-     *
-     * @retval OT_ERROR_NONE          Successfully found the next neighbor entry in table.
-     * @retval OT_ERROR_NOT_FOUND     No subsequent neighbor entry exists in the table.
-     *
-     */
-    otError GetNextNeighborInfo(otNeighborInfoIterator &aIterator, otNeighborInfo &aNeighInfo);
-
-    /**
-     * This method indicates whether or not the given Thread partition attributes are preferred.
-     *
-     * @param[in]  aSingletonA   Whether or not the Thread Partition A has a single router.
-     * @param[in]  aLeaderDataA  A reference to Thread Partition A's Leader Data.
-     * @param[in]  aSingletonB   Whether or not the Thread Partition B has a single router.
-     * @param[in]  aLeaderDataB  A reference to Thread Partition B's Leader Data.
-     *
-     * @retval 1   If partition A is preferred.
-     * @retval 0   If partition A and B have equal preference.
-     * @retval -1  If partition B is preferred.
-     *
-     */
-    static int ComparePartitions(bool                 aSingletonA,
-                                 const LeaderDataTlv &aLeaderDataA,
-                                 bool                 aSingletonB,
-                                 const LeaderDataTlv &aLeaderDataB);
-
-    /**
-     * This method checks if the destination is reachable.
-     *
-     * @param[in]  aMeshSource  The RLOC16 of the source.
-     * @param[in]  aMeshDest    The RLOC16 of the destination.
-     * @param[in]  aIp6Header   A reference to the IPv6 header of the message.
-     *
-     * @retval OT_ERROR_NONE  The destination is reachable.
-     * @retval OT_ERROR_DROP  The destination is not reachable and the message should be dropped.
-     *
-     */
-    otError CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header);
-
-    /**
-     * This method resolves 2-hop routing loops.
-     *
-     * @param[in]  aSourceMac   The RLOC16 of the previous hop.
-     * @param[in]  aDestRloc16  The RLOC16 of the final destination.
-     *
-     */
-    void ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16);
-
-    /**
-     * This method checks if a given Router ID has correct value.
-     *
-     * @param[in]  aRouterId  The Router ID value.
-     *
-     * @retval TRUE   If @p aRouterId is in correct range [0..62].
-     * @retval FALSE  If @p aRouterId is not a valid Router ID.
-     *
-     */
-    static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
-
-    /**
-     * This method fills an ConnectivityTlv.
-     *
-     * @param[out]  aTlv  A reference to the tlv to be filled.
-     *
-     */
-    void FillConnectivityTlv(ConnectivityTlv &aTlv);
-
-    /**
-     * This method fills an RouteTlv.
-     *
-     * @param[out]  aTlv  A reference to the tlv to be filled.
-     *
-     */
-    void FillRouteTlv(RouteTlv &aTlv);
-
-    /**
-     * This method generates an MLE Child Update Request message to be sent to the parent.
-     *
-     * @retval OT_ERROR_NONE     Successfully generated an MLE Child Update Request message.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffers to generate the MLE Child Update Request message.
-     *
-     */
-    otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
-
-    otError SendLinkRequest(Neighbor *aNeighbor);
-
-#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
-    /**
-     * This method sets steering data out of band
-     *
-     * @param[in]  aExtAddress  Value used to set steering data
-     *                          All zeros clears steering data
-     *                          All 0xFFs sets steering data to 0xFF
-     *                          Anything else is used to compute the bloom filter
-     *
-     */
-    void SetSteeringData(const Mac::ExtAddress *aExtAddress);
-#endif // OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
-
-    /**
-     * This method gets the assigned parent priority.
-     *
-     * @returns The assigned parent priority value, -2 means not assigned.
-     *
-     */
-    int8_t GetAssignParentPriority(void) const { return mParentPriority; }
-
-    /**
-     * This method sets the parent priority.
-     *
-     * @param[in]  aParentPriority  The parent priority value.
-     *
-     * @retval OT_ERROR_NONE           Successfully set the parent priority.
-     * @retval OT_ERROR_INVALID_ARGS   If the parent priority value is not among 1, 0, -1 and -2.
-     *
-     */
-    otError SetAssignParentPriority(int8_t aParentPriority);
-
-    /**
-     * This method gets the longest MLE Timeout TLV for all active MTD children.
-     *
-     * @param[out]  aTimeout  A reference to where the information is placed.
-     *
-     * @retval OT_ERROR_NONE           Successfully get the max child timeout
-     * @retval OT_ERROR_INVALID_STATE  Not an active router
-     * @retval OT_ERROR_NOT_FOUND      NO MTD child
-     *
-     */
-    otError GetMaxChildTimeout(uint32_t &aTimeout) const;
-
-    /**
-     * This method register the "neighbor table changed" callback function.
-     *
-     * The provided callback (if non-NULL) will be invoked when a child/router entry is being added/remove to/from the
-     * neighbor table. Subsequent calls to this method will overwrite the previous callback.
-     *
-     * @param[in] aCallback    A pointer to callback handler function.
-     *
-     */
-    void RegisterNeighborTableChangedCallback(otNeighborTableCallback aCallback)
-    {
-        mNeighborTableChangedCallback = aCallback;
-    }
-
-    /**
-     * This method signals a "neighbor table changed" events (invoking the registered callback function).
-     *
-     * @param[in] aEvent     The event to emit (child/router added/removed).
-     * @param[in] aNeighbor  The neighbor that is being added/removed.
-     *
-     */
-    void Signal(otNeighborTableEvent aEvent, Neighbor &aNeighbor);
-
-    /**
-     * This method returns whether the device has any sleepy children subscribed the address.
-     *
-     * @param[in]  aAddress  The reference of the address.
-     *
-     * @retval TRUE   If the device has any sleepy children subscribed the address @p aAddress.
-     * @retval FALSE  If the device doesn't have any sleepy children subscribed the address @p aAddress.
-     *
-     */
-    bool HasSleepyChildrenSubscribed(const Ip6::Address &aAddress);
-
-    /**
-     * This method returns whether the specific child subscribed the address.
-     *
-     * @param[in]  aAddress  The reference of the address.
-     * @param[in]  aChild    The reference of the child.
-     *
-     * @retval TRUE   If the sleepy child @p aChild subscribed the address @p aAddress.
-     * @retval FALSE  If the sleepy child @p aChild did not subscribe the address @p aAddress.
-     *
-     */
-    bool IsSleepyChildSubscribed(const Ip6::Address &aAddress, Child &aChild);
-
-    /**
-     * This method resets the MLE Advertisement Trickle timer interval.
-     *
-     */
-    void ResetAdvertiseInterval(void);
-
-    /**
-     * This static method converts link quality to route cost.
-     *
-     * @param[in]  aLinkQuality  The link quality.
-     *
-     * @returns The link cost corresponding to @p aLinkQuality.
-     *
-     */
-    static uint8_t LinkQualityToCost(uint8_t aLinkQuality);
-
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    /**
-     * This method generates an MLE Time Synchronization message.
-     *
-     * @retval OT_ERROR_NONE     Successfully sent an MLE Time Synchronization message.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffers to generate the MLE Time Synchronization message.
-     *
-     */
-    otError SendTimeSync(void);
-#endif
-
-private:
-    enum
-    {
-        kDiscoveryMaxJitter = 250u,  ///< Maximum jitter time used to delay Discovery Responses in milliseconds.
-        kStateUpdatePeriod  = 1000u, ///< State update period in milliseconds.
-        kUnsolicitedDataResponseJitter = 500u, ///< Maximum delay before unsolicited Data Response in milliseconds.
-    };
-
-    otError AppendConnectivity(Message &aMessage);
-    otError AppendChildAddresses(Message &aMessage, Child &aChild);
-    otError AppendRoute(Message &aMessage);
-    otError AppendActiveDataset(Message &aMessage);
-    otError AppendPendingDataset(Message &aMessage);
-    otError GetChildInfo(Child &aChild, otChildInfo &aChildInfo);
-    void    GetNeighborInfo(Neighbor &aNeighbor, otNeighborInfo &aNeighInfo);
-    otError RefreshStoredChildren(void);
-    void    HandleDetachStart(void);
-    otError HandleChildStart(AttachMode aMode);
-    otError HandleLinkRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor);
-    otError HandleLinkAccept(const Message &         aMessage,
-                             const Ip6::MessageInfo &aMessageInfo,
-                             uint32_t                aKeySequence,
-                             Neighbor *              aNeighbor);
-    otError HandleLinkAccept(const Message &         aMessage,
-                             const Ip6::MessageInfo &aMessageInfo,
-                             uint32_t                aKeySequence,
-                             Neighbor *              aNeighbor,
-                             bool                    aRequest);
-    otError HandleLinkAcceptAndRequest(const Message &         aMessage,
-                                       const Ip6::MessageInfo &aMessageInfo,
-                                       uint32_t                aKeySequence,
-                                       Neighbor *              aNeighbor);
-    otError HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *);
-    otError HandleParentRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-    otError HandleChildIdRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence);
-    otError HandleChildUpdateRequest(const Message &         aMessage,
-                                     const Ip6::MessageInfo &aMessageInfo,
-                                     uint32_t                aKeySequence);
-    otError HandleChildUpdateResponse(const Message &         aMessage,
-                                      const Ip6::MessageInfo &aMessageInfo,
-                                      uint32_t                aKeySequence,
-                                      Neighbor *              aNeighbor);
-    otError HandleDataRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor);
-    void    HandleNetworkDataUpdateRouter(void);
-    otError HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    void HandleTimeSync(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor);
-#endif
-
-    otError ProcessRouteTlv(const RouteTlv &aRoute);
-    void    StopAdvertiseTimer(void);
-    otError SendAddressSolicit(ThreadStatusTlv::Status aStatus);
-    otError SendAddressRelease(void);
-    void    SendAddressSolicitResponse(const Coap::Message &   aRequest,
-                                       const Router *          aRouter,
-                                       const Ip6::MessageInfo &aMessageInfo);
-    otError SendAdvertisement(void);
-    otError SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
-                           Neighbor *              aNeighbor,
-                           const TlvRequestTlv &   aTlvRequest,
-                           const ChallengeTlv &    aChallenge);
-    void    SendParentResponse(Child *aChild, const ChallengeTlv &aChallenge, bool aRoutersOnlyRequest);
-    otError SendChildIdResponse(Child &aChild);
-    otError SendChildUpdateRequest(Child &aChild);
-    void    SendChildUpdateResponse(Child *                 aChild,
-                                    const Ip6::MessageInfo &aMessageInfo,
-                                    const uint8_t *         aTlvs,
-                                    uint8_t                 aTlvsLength,
-                                    const ChallengeTlv &    aChallenge);
-    otError SendDataResponse(const Ip6::Address &aDestination,
-                             const uint8_t *     aTlvs,
-                             uint8_t             aTlvsLength,
-                             uint16_t            aDelay);
-    otError SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId);
-
-    void    SetStateRouter(uint16_t aRloc16);
-    void    SetStateLeader(uint16_t aRloc16);
-    void    StopLeader(void);
-    void    SynchronizeChildNetworkData(void);
-    otError UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, Child &aChild);
-    void    UpdateRoutes(const RouteTlv &aRoute, uint8_t aRouterId);
-    bool    UpdateLinkQualityOut(const RouteTlv &aRoute, Router &aNeighbor, bool &aResetAdvInterval);
-
-    static void HandleAddressSolicitResponse(void *               aContext,
-                                             otMessage *          aMessage,
-                                             const otMessageInfo *aMessageInfo,
-                                             otError              aResult);
-    void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, otError aResult);
-    static void HandleAddressRelease(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
-    void        HandleAddressRelease(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-    static void HandleAddressSolicit(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
-    void        HandleAddressSolicit(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
-    static bool IsSingleton(const RouteTlv &aRouteTlv);
-
-    void HandlePartitionChange(void);
-
-    void SetChildStateToValid(Child &aChild);
-    bool HasChildren(void);
-    void RemoveChildren(void);
-    bool HasMinDowngradeNeighborRouters(void);
-    bool HasOneNeighborWithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId);
-    bool HasSmallNumberOfChildren(void);
-
-    static bool HandleAdvertiseTimer(TrickleTimer &aTimer);
-    bool        HandleAdvertiseTimer(void);
-    static void HandleStateUpdateTimer(Timer &aTimer);
-    void        HandleStateUpdateTimer(void);
-
-    TrickleTimer mAdvertiseTimer;
-    TimerMilli   mStateUpdateTimer;
-
-    Coap::Resource mAddressSolicit;
-    Coap::Resource mAddressRelease;
-
-    ChildTable  mChildTable;
-    RouterTable mRouterTable;
-
-    otNeighborTableCallback mNeighborTableChangedCallback;
-
-    uint8_t  mChallengeTimeout;
-    uint8_t  mChallenge[8];
-    uint16_t mNextChildId;
-    uint8_t  mNetworkIdTimeout;
-    uint8_t  mRouterUpgradeThreshold;
-    uint8_t  mRouterDowngradeThreshold;
-    uint8_t  mLeaderWeight;
-    uint32_t mFixedLeaderPartitionId; ///< only for certification testing
-    bool     mRouterEligible : 1;
-    bool     mAddressSolicitPending : 1;
-
-    uint8_t mRouterId;
-    uint8_t mPreviousRouterId;
-
-    uint32_t mPreviousPartitionIdRouter;         ///< The partition ID when last operating as a router
-    uint32_t mPreviousPartitionId;               ///< The partition ID when last attached
-    uint8_t  mPreviousPartitionRouterIdSequence; ///< The router ID sequence when last attached
-    uint8_t  mPreviousPartitionIdTimeout;        ///< The partition ID timeout when last attached
-
-    uint8_t mRouterSelectionJitter;        ///< The variable to save the assigned jitter value.
-    uint8_t mRouterSelectionJitterTimeout; ///< The Timeout prior to request/release Router ID.
-
-    int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned.
-
-#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
-    MeshCoP::SteeringDataTlv mSteeringData;
-#endif // OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
-};
-
-} // namespace Mle
-
-/**
- * @}
- */
-
-} // namespace ot
-
-#endif // MLE_ROUTER_FTD_HPP_
diff --git a/src/core/thread/mle_router_mtd.hpp b/src/core/thread/mle_router_mtd.hpp
deleted file mode 100644
index d0df826..0000000
--- a/src/core/thread/mle_router_mtd.hpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes definitions for MLE functionality required by the Thread Router and Leader roles.
- */
-
-#ifndef MLE_ROUTER_MTD_HPP_
-#define MLE_ROUTER_MTD_HPP_
-
-#include "openthread-core-config.h"
-
-#include "thread/child_table.hpp"
-#include "thread/mle.hpp"
-#include "thread/mle_tlvs.hpp"
-#include "thread/router_table.hpp"
-#include "thread/thread_tlvs.hpp"
-
-namespace ot {
-namespace Mle {
-
-class MleRouter : public Mle
-{
-    friend class Mle;
-    friend class ot::Instance;
-
-public:
-    explicit MleRouter(Instance &aInstance)
-        : Mle(aInstance)
-        , mChildTable(aInstance)
-        , mRouterTable(aInstance)
-    {
-    }
-
-    bool IsRouterEligible(void) const { return false; }
-
-    bool IsSingleton(void) const { return false; }
-
-    otError BecomeRouter(ThreadStatusTlv::Status) { return OT_ERROR_NOT_CAPABLE; }
-    otError BecomeLeader(void) { return OT_ERROR_NOT_CAPABLE; }
-
-    uint8_t GetRouterSelectionJitterTimeout(void) const { return 0; }
-
-    uint32_t GetPreviousPartitionId(void) const { return 0; }
-    void     SetPreviousPartitionId(uint32_t) {}
-    void     SetRouterId(uint8_t) {}
-
-    uint16_t GetNextHop(uint16_t aDestination) const { return Mle::GetNextHop(aDestination); }
-
-    uint8_t GetNetworkIdTimeout(void) const { return 0; }
-
-    uint8_t GetRouteCost(uint16_t) const { return 0; }
-    uint8_t GetLinkCost(uint16_t) { return 0; }
-    uint8_t GetCost(uint16_t) { return 0; }
-
-    otError RemoveNeighbor(Neighbor &) { return BecomeDetached(); }
-
-    bool IsMinimalChild(uint16_t) const { return false; }
-
-    void    RestoreChildren(void) {}
-    otError RemoveStoredChild(uint16_t) { return OT_ERROR_NOT_IMPLEMENTED; }
-    otError StoreChild(const Child &) { return OT_ERROR_NOT_IMPLEMENTED; }
-
-    Neighbor *GetNeighbor(uint16_t aAddress) { return Mle::GetNeighbor(aAddress); }
-    Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress) { return Mle::GetNeighbor(aAddress); }
-    Neighbor *GetNeighbor(const Mac::Address &aAddress) { return Mle::GetNeighbor(aAddress); }
-    Neighbor *GetNeighbor(const Ip6::Address &aAddress) { return Mle::GetNeighbor(aAddress); }
-    Neighbor *GetRxOnlyNeighborRouter(const Mac::Address &aAddress)
-    {
-        OT_UNUSED_VARIABLE(aAddress);
-        return NULL;
-    }
-
-    otError GetNextNeighborInfo(otNeighborInfoIterator &, otNeighborInfo &) { return OT_ERROR_NOT_IMPLEMENTED; }
-
-    static int ComparePartitions(bool, const LeaderDataTlv &, bool, const LeaderDataTlv &) { return 0; }
-
-    void ResolveRoutingLoops(uint16_t, uint16_t) {}
-
-    otError CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header)
-    {
-        return Mle::CheckReachability(aMeshSource, aMeshDest, aIp6Header);
-    }
-
-    static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
-
-    void FillConnectivityTlv(ConnectivityTlv &) {}
-
-    otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
-
-#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
-    otError SetSteeringData(const otExtAddress *) { return OT_ERROR_NOT_IMPLEMENTED; }
-#endif // OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
-
-    otError GetMaxChildTimeout(uint32_t &) { return OT_ERROR_NOT_IMPLEMENTED; }
-
-    bool HasSleepyChildrenSubscribed(const Ip6::Address &) { return false; }
-
-    bool IsSleepyChildSubscribed(const Ip6::Address &, Child &) { return false; }
-
-private:
-    void    HandleDetachStart(void) {}
-    otError HandleChildStart(AttachMode) { return OT_ERROR_NONE; }
-    otError HandleLinkRequest(const Message &, const Ip6::MessageInfo &, Neighbor *) { return OT_ERROR_DROP; }
-    otError HandleLinkAccept(const Message &, const Ip6::MessageInfo &, uint32_t, Neighbor *) { return OT_ERROR_DROP; }
-    otError HandleLinkAccept(const Message &, const Ip6::MessageInfo &, uint32_t, Neighbor *, bool)
-    {
-        return OT_ERROR_DROP;
-    }
-    otError HandleLinkAcceptAndRequest(const Message &, const Ip6::MessageInfo &, uint32_t, Neighbor *)
-    {
-        return OT_ERROR_DROP;
-    }
-    otError HandleAdvertisement(const Message &, const Ip6::MessageInfo &, Neighbor *) { return OT_ERROR_DROP; }
-    otError HandleParentRequest(const Message &, const Ip6::MessageInfo &) { return OT_ERROR_DROP; }
-    otError HandleChildIdRequest(const Message &, const Ip6::MessageInfo &, uint32_t) { return OT_ERROR_DROP; }
-    otError HandleChildUpdateRequest(const Message &, const Ip6::MessageInfo &, uint32_t) { return OT_ERROR_DROP; }
-    otError HandleChildUpdateResponse(const Message &, const Ip6::MessageInfo &, uint32_t, Neighbor *)
-    {
-        return OT_ERROR_DROP;
-    }
-    otError HandleDataRequest(const Message &, const Ip6::MessageInfo &, const Neighbor *) { return OT_ERROR_DROP; }
-    void    HandleNetworkDataUpdateRouter(void) {}
-    otError HandleDiscoveryRequest(const Message &, const Ip6::MessageInfo &) { return OT_ERROR_DROP; }
-    void    HandlePartitionChange(void) {}
-    void    StopAdvertiseTimer(void) {}
-    otError ProcessRouteTlv(const RouteTlv &) { return OT_ERROR_NONE; }
-#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
-    otError HandleTimeSync(const Message &, const Ip6::MessageInfo &, const Neighbor *) { return OT_ERROR_DROP; }
-#endif
-
-    ChildTable  mChildTable;
-    RouterTable mRouterTable;
-};
-
-} // namespace Mle
-} // namespace ot
-
-#endif // MLE_ROUTER_MTD_HPP_
diff --git a/src/core/thread/mle_tlvs.hpp b/src/core/thread/mle_tlvs.hpp
index 102657e..bae885d 100644
--- a/src/core/thread/mle_tlvs.hpp
+++ b/src/core/thread/mle_tlvs.hpp
@@ -41,8 +41,7 @@
 #include "common/tlvs.hpp"
 #include "meshcop/timestamp.hpp"
 #include "net/ip6_address.hpp"
-#include "thread/device_mode.hpp"
-#include "thread/mle_constants.hpp"
+#include "thread/mle_types.hpp"
 
 namespace ot {
 
@@ -51,10 +50,6 @@
 using ot::Encoding::BigEndian::HostSwap16;
 using ot::Encoding::BigEndian::HostSwap32;
 
-#define TLVREQUESTTLV_ITERATOR_INIT 0 ///< Initializer for TlvRequestTlvIterator.
-
-typedef uint8_t TlvRequestIterator; ///< Used to iterate through TlvRequestTlv.
-
 /**
  * @addtogroup core-mle-tlvs
  *
@@ -135,361 +130,12 @@
      */
     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
 
-    /**
-     * This static method reads the requested TLV out of @p aMessage.
-     *
-     * @param[in]   aMessage    A reference to the message.
-     * @param[in]   aType       The Type value to search for.
-     * @param[in]   aMaxLength  Maximum number of bytes to read.
-     * @param[out]  aTlv        A reference to the TLV that will be copied to.
-     *
-     * @retval OT_ERROR_NONE       Successfully copied the TLV.
-     * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
-     *
-     */
-    static otError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv)
-    {
-        return ot::Tlv::Get(aMessage, static_cast<uint8_t>(aType), aMaxLength, aTlv);
-    }
-
-    /**
-     * This static method obtains the offset of a TLV within @p aMessage.
-     *
-     * @param[in]   aMessage    A reference to the message.
-     * @param[in]   aType       The Type value to search for.
-     * @param[out]  aOffset     A reference to the offset of the TLV.
-     *
-     * @retval OT_ERROR_NONE       Successfully copied the TLV.
-     * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
-     *
-     */
-    static otError GetOffset(const Message &aMessage, Type aType, uint16_t &aOffset)
-    {
-        return ot::Tlv::GetOffset(aMessage, static_cast<uint8_t>(aType), aOffset);
-    }
-
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class SourceAddressTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kSourceAddress);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the RLOC16 value.
-     *
-     * @returns The RLOC16 value.
-     *
-     */
-    uint16_t GetRloc16(void) const { return HostSwap16(mRloc16); }
-
-    /**
-     * This method sets the RLOC16 value.
-     *
-     * @param[in]  aRloc16  The RLOC16 value.
-     *
-     */
-    void SetRloc16(uint16_t aRloc16) { mRloc16 = HostSwap16(aRloc16); }
-
-private:
-    uint16_t mRloc16;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ModeTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kMode);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Mode value.
-     *
-     * @returns The Mode value.
-     *
-     */
-    DeviceMode GetMode(void) const { return DeviceMode(mMode); }
-
-    /**
-     * This method sets the Mode value.
-     *
-     * @param[in]  aMode  The Mode value.
-     *
-     */
-    void SetMode(DeviceMode aMode) { mMode = aMode.Get(); }
-
-private:
-    uint8_t mMode;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class TimeoutTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kTimeout);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Timeout value.
-     *
-     * @returns The Timeout value.
-     *
-     */
-    uint32_t GetTimeout(void) const { return HostSwap32(mTimeout); }
-
-    /**
-     * This method sets the Timeout value.
-     *
-     * @param[in]  aTimeout  The Timeout value.
-     *
-     */
-    void SetTimeout(uint32_t aTimeout) { mTimeout = HostSwap32(aTimeout); }
-
-private:
-    uint32_t mTimeout;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ChallengeTlv : public Tlv
-{
-public:
-    enum
-    {
-        kMinSize = 4, ///< Minimum size in bytes (Thread Specification).
-        kMaxSize = 8, ///< Maximum size in bytes (Thread Specification).
-    };
-
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kChallenge);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= kMinSize; }
-
-    /**
-     * This method returns the Challenge length.
-     *
-     * @returns The Challenge length.
-     *
-     */
-    uint8_t GetChallengeLength(void) const
-    {
-        return GetLength() <= sizeof(mChallenge) ? GetLength() : sizeof(mChallenge);
-    }
-
-    /**
-     * This method returns a pointer to the Challenge value.
-     *
-     * @returns A pointer to the Challenge value.
-     *
-     */
-    const uint8_t *GetChallenge(void) const { return mChallenge; }
-
-    /**
-     * This method sets the Challenge value.
-     *
-     * @param[in]  aChallenge  A pointer to the Challenge value.
-     *
-     */
-    void SetChallenge(const uint8_t *aChallenge) { memcpy(mChallenge, aChallenge, GetChallengeLength()); }
-
-private:
-    uint8_t mChallenge[kMaxSize];
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ResponseTlv : public Tlv
-{
-public:
-    enum
-    {
-        kMinSize = 4, ///< Minimum size in bytes (Thread Specification).
-        kMaxSize = 8, ///< Maximum size in bytes (Thread Specification).
-    };
-
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kResponse);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * OpenThread only generates Challenge values with 8-byte length. As a result, Response value lengths must also
-     * have 8-byte length.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Response length.
-     *
-     * @returns The Response length.
-     *
-     */
-    uint8_t GetResponseLength(void) const { return GetLength() <= sizeof(mResponse) ? GetLength() : sizeof(mResponse); }
-
-    /**
-     * This method returns a pointer to the Response value.
-     *
-     * @returns A pointer to the Response value.
-     *
-     */
-    const uint8_t *GetResponse(void) const { return mResponse; }
-
-    /**
-     * This method sets the Response value.
-     *
-     * @param[in]  aResponse  A pointer to the Response value.
-     *
-     */
-    void SetResponse(const uint8_t *aResponse) { memcpy(mResponse, aResponse, GetResponseLength()); }
-
-private:
-    uint8_t mResponse[kMaxSize];
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class LinkFrameCounterTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kLinkFrameCounter);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Frame Counter value.
-     *
-     * @returns The Frame Counter value.
-     *
-     */
-    uint32_t GetFrameCounter(void) const { return HostSwap32(mFrameCounter); }
-
-    /**
-     * This method sets the Frame Counter value.
-     *
-     * @param[in]  aFrameCounter  The Frame Counter value.
-     *
-     */
-    void SetFrameCounter(uint32_t aFrameCounter) { mFrameCounter = HostSwap32(aFrameCounter); }
-
-private:
-    uint32_t mFrameCounter;
 } OT_TOOL_PACKED_END;
 
 #if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
 
 /**
- * This class implements Source Address TLV generation and parsing.
+ * This class implements Route TLV generation and parsing.
  *
  */
 OT_TOOL_PACKED_BEGIN
@@ -504,7 +150,7 @@
     {
         SetType(kRoute);
         SetLength(sizeof(*this) - sizeof(Tlv));
-        memset(mRouterIdMask, 0, sizeof(mRouterIdMask));
+        mRouterIdMask.Clear();
         memset(mRouteData, 0, sizeof(mRouteData));
     }
 
@@ -534,32 +180,29 @@
     void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; }
 
     /**
-     * This method clears the Router ID Mask.
+     * This method gets the Router ID Mask.
      *
      */
-    void ClearRouterIdMask(void) { memset(mRouterIdMask, 0, sizeof(mRouterIdMask)); }
+    const RouterIdSet &GetRouterIdMask(void) const { return mRouterIdMask; }
+
+    /**
+     * This method sets the Router ID Mask.
+     *
+     * @param[in]  aRouterIdSet The Router ID Mask to set.
+     *
+     */
+    void SetRouterIdMask(const RouterIdSet &aRouterIdSet) { mRouterIdMask = aRouterIdSet; }
 
     /**
      * This method indicates whether or not a Router ID bit is set.
      *
-     * @param[in]  aRouterId  The Router ID.
+     * @param[in]  aRouterId  The Router ID bit.
      *
      * @retval TRUE   If the Router ID bit is set.
      * @retval FALSE  If the Router ID bit is not set.
      *
      */
-    bool IsRouterIdSet(uint8_t aRouterId) const
-    {
-        return (mRouterIdMask[aRouterId / 8] & (0x80 >> (aRouterId % 8))) != 0;
-    }
-
-    /**
-     * This method sets the Router ID bit.
-     *
-     * @param[in]  aRouterId  The Router ID bit to set.
-     *
-     */
-    void SetRouterId(uint8_t aRouterId) { mRouterIdMask[aRouterId / 8] |= 0x80 >> (aRouterId % 8); }
+    bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); }
 
     /**
      * This method returns the Route Data Length value.
@@ -578,71 +221,77 @@
     void SetRouteDataLength(uint8_t aLength) { SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength); }
 
     /**
-     * This method returns the Route Cost value for a given Router ID.
+     * This method returns the Route Cost value for a given Router index.
      *
-     * @returns The Route Cost value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Route Cost value for a given Router index.
      *
      */
-    uint8_t GetRouteCost(uint8_t aRouterId) const { return mRouteData[aRouterId] & kRouteCostMask; }
+    uint8_t GetRouteCost(uint8_t aRouterIndex) const { return mRouteData[aRouterIndex] & kRouteCostMask; }
 
     /**
-     * This method sets the Route Cost value for a given Router ID.
+     * This method sets the Route Cost value for a given Router index.
      *
-     * @param[in]  aRouterId   The Router ID.
-     * @param[in]  aRouteCost  The Route Cost value.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aRouteCost    The Route Cost value.
      *
      */
-    void SetRouteCost(uint8_t aRouterId, uint8_t aRouteCost)
+    void SetRouteCost(uint8_t aRouterIndex, uint8_t aRouteCost)
     {
-        mRouteData[aRouterId] = (mRouteData[aRouterId] & ~kRouteCostMask) | aRouteCost;
+        mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kRouteCostMask) | aRouteCost;
     }
 
     /**
-     * This method returns the Link Quality In value for a given Router ID.
+     * This method returns the Link Quality In value for a given Router index.
      *
-     * @returns The Link Quality In value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Link Quality In value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityIn(uint8_t aRouterId) const
+    uint8_t GetLinkQualityIn(uint8_t aRouterIndex) const
     {
-        return (mRouteData[aRouterId] & kLinkQualityInMask) >> kLinkQualityInOffset;
+        return (mRouteData[aRouterIndex] & kLinkQualityInMask) >> kLinkQualityInOffset;
     }
 
     /**
-     * This method sets the Link Quality In value for a given Router ID.
+     * This method sets the Link Quality In value for a given Router index.
      *
-     * @param[in]  aRouterId     The Router ID.
-     * @param[in]  aLinkQuality  The Link Quality In value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aLinkQuality  The Link Quality In value for a given Router index.
      *
      */
-    void SetLinkQualityIn(uint8_t aRouterId, uint8_t aLinkQuality)
+    void SetLinkQualityIn(uint8_t aRouterIndex, uint8_t aLinkQuality)
     {
-        mRouteData[aRouterId] = (mRouteData[aRouterId] & ~kLinkQualityInMask) |
-                                ((aLinkQuality << kLinkQualityInOffset) & kLinkQualityInMask);
+        mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityInMask) |
+                                   ((aLinkQuality << kLinkQualityInOffset) & kLinkQualityInMask);
     }
 
     /**
-     * This method returns the Link Quality Out value for a given Router ID.
+     * This method returns the Link Quality Out value for a given Router index.
      *
-     * @returns The Link Quality Out value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Link Quality Out value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityOut(uint8_t aRouterId) const
+    uint8_t GetLinkQualityOut(uint8_t aRouterIndex) const
     {
-        return (mRouteData[aRouterId] & kLinkQualityOutMask) >> kLinkQualityOutOffset;
+        return (mRouteData[aRouterIndex] & kLinkQualityOutMask) >> kLinkQualityOutOffset;
     }
 
     /**
-     * This method sets the Link Quality Out value for a given Router ID.
+     * This method sets the Link Quality Out value for a given Router index.
      *
-     * @param[in]  aRouterId     The Router ID.
-     * @param[in]  aLinkQuality  The Link Quality Out value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aLinkQuality  The Link Quality Out value for a given Router index.
      *
      */
-    void SetLinkQualityOut(uint8_t aRouterId, uint8_t aLinkQuality)
+    void SetLinkQualityOut(uint8_t aRouterIndex, uint8_t aLinkQuality)
     {
-        mRouteData[aRouterId] = (mRouteData[aRouterId] & ~kLinkQualityOutMask) |
-                                ((aLinkQuality << kLinkQualityOutOffset) & kLinkQualityOutMask);
+        mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityOutMask) |
+                                   ((aLinkQuality << kLinkQualityOutOffset) & kLinkQualityOutMask);
     }
 
 private:
@@ -655,15 +304,15 @@
         kRouteCostOffset      = 0,
         kRouteCostMask        = 0xf << kRouteCostOffset,
     };
-    uint8_t mRouterIdSequence;
-    uint8_t mRouterIdMask[BitVectorBytes(kMaxRouterId + 1)];
-    uint8_t mRouteData[kMaxRouterId + 1];
+    uint8_t     mRouterIdSequence;
+    RouterIdSet mRouterIdMask;
+    uint8_t     mRouteData[kMaxRouterId + 1];
 } OT_TOOL_PACKED_END;
 
 #else // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
 
 /**
- * This class implements Source Address TLV generation and parsing.
+ * This class implements Route TLV generation and parsing.
  *
  */
 OT_TOOL_PACKED_BEGIN
@@ -706,10 +355,18 @@
     void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; }
 
     /**
-     * This method clears the Router ID Mask.
+     * This method gets the Router ID Mask.
      *
      */
-    void ClearRouterIdMask(void) { memset(mRouterIdMask, 0, sizeof(mRouterIdMask)); }
+    const RouterIdSet &GetRouterIdMask(void) const { return mRouterIdMask; }
+
+    /**
+     * This method sets the Router ID Mask.
+     *
+     * @param[in]  aRouterIdSet The Router ID Mask to set.
+     *
+     */
+    void SetRouterIdMask(const RouterIdSet &aRouterIdSet) { mRouterIdMask = aRouterIdSet; }
 
     /**
      * This method indicates whether or not a Router ID bit is set.
@@ -720,10 +377,7 @@
      * @retval FALSE  If the Router ID bit is not set.
      *
      */
-    bool IsRouterIdSet(uint8_t aRouterId) const
-    {
-        return (mRouterIdMask[aRouterId / 8] & (0x80 >> (aRouterId % 8))) != 0;
-    }
+    bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); }
 
     /**
      * This method sets the Router ID bit.
@@ -731,7 +385,7 @@
      * @param[in]  aRouterId  The Router ID bit to set.
      *
      */
-    void SetRouterId(uint8_t aRouterId) { mRouterIdMask[aRouterId / 8] |= 0x80 >> (aRouterId % 8); }
+    void SetRouterId(uint8_t aRouterId) { mRouterIdMask.Add(aRouterId); }
 
     /**
      * This method returns the Route Data Length value.
@@ -753,102 +407,110 @@
     }
 
     /**
-     * This method returns the Route Cost value for a given Router ID.
+     * This method returns the Route Cost value for a given Router index.
      *
-     * @returns The Route Cost value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Route Cost value for a given Router index.
      *
      */
-    uint8_t GetRouteCost(uint8_t aRouterId) const
+    uint8_t GetRouteCost(uint8_t aRouterIndex) const
     {
-        if (aRouterId & 1)
+        if (aRouterIndex & 1)
         {
-            return mRouteData[aRouterId + aRouterId / 2 + 1];
+            return mRouteData[aRouterIndex + aRouterIndex / 2 + 1];
         }
         else
         {
-            return static_cast<uint8_t>((mRouteData[aRouterId + aRouterId / 2] & kRouteCostMask) << kOddEntryOffset) |
-                   ((mRouteData[aRouterId + aRouterId / 2 + 1] &
+            return static_cast<uint8_t>((mRouteData[aRouterIndex + aRouterIndex / 2] & kRouteCostMask)
+                                        << kOddEntryOffset) |
+                   ((mRouteData[aRouterIndex + aRouterIndex / 2 + 1] &
                      static_cast<uint8_t>(kRouteCostMask << kOddEntryOffset)) >>
                     kOddEntryOffset);
         }
     }
 
     /**
-     * This method sets the Route Cost value for a given Router ID.
+     * This method sets the Route Cost value for a given Router index.
      *
-     * @param[in]  aRouterId   The Router ID.
-     * @param[in]  aRouteCost  The Route Cost value.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aRouteCost    The Route Cost value.
      *
      */
-    void SetRouteCost(uint8_t aRouterId, uint8_t aRouteCost)
+    void SetRouteCost(uint8_t aRouterIndex, uint8_t aRouteCost)
     {
-        if (aRouterId & 1)
+        if (aRouterIndex & 1)
         {
-            mRouteData[aRouterId + aRouterId / 2 + 1] = aRouteCost;
+            mRouteData[aRouterIndex + aRouterIndex / 2 + 1] = aRouteCost;
         }
         else
         {
-            mRouteData[aRouterId + aRouterId / 2] = (mRouteData[aRouterId + aRouterId / 2] & ~kRouteCostMask) |
-                                                    ((aRouteCost >> kOddEntryOffset) & kRouteCostMask);
-            mRouteData[aRouterId + aRouterId / 2 + 1] = static_cast<uint8_t>(
-                (mRouteData[aRouterId + aRouterId / 2 + 1] & ~(kRouteCostMask << kOddEntryOffset)) |
+            mRouteData[aRouterIndex + aRouterIndex / 2] =
+                (mRouteData[aRouterIndex + aRouterIndex / 2] & ~kRouteCostMask) |
+                ((aRouteCost >> kOddEntryOffset) & kRouteCostMask);
+            mRouteData[aRouterIndex + aRouterIndex / 2 + 1] = static_cast<uint8_t>(
+                (mRouteData[aRouterIndex + aRouterIndex / 2 + 1] & ~(kRouteCostMask << kOddEntryOffset)) |
                 ((aRouteCost & kRouteCostMask) << kOddEntryOffset));
         }
     }
 
     /**
-     * This method returns the Link Quality In value for a given Router ID.
+     * This method returns the Link Quality In value for a given Router index.
      *
-     * @returns The Link Quality In value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Link Quality In value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityIn(uint8_t aRouterId) const
+    uint8_t GetLinkQualityIn(uint8_t aRouterIndex) const
     {
-        int offset = ((aRouterId & 1) ? kOddEntryOffset : 0);
-        return (mRouteData[aRouterId + aRouterId / 2] & (kLinkQualityInMask >> offset)) >>
+        int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
+        return (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityInMask >> offset)) >>
                (kLinkQualityInOffset - offset);
     }
 
     /**
-     * This method sets the Link Quality In value for a given Router ID.
+     * This method sets the Link Quality In value for a given Router index.
      *
-     * @param[in]  aRouterId     The Router ID.
-     * @param[in]  aLinkQuality  The Link Quality In value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aLinkQuality  The Link Quality In value for a given Router index.
      *
      */
-    void SetLinkQualityIn(uint8_t aRouterId, uint8_t aLinkQuality)
+    void SetLinkQualityIn(uint8_t aRouterIndex, uint8_t aLinkQuality)
     {
-        int offset = ((aRouterId & 1) ? kOddEntryOffset : 0);
-        mRouteData[aRouterId + aRouterId / 2] =
-            (mRouteData[aRouterId + aRouterId / 2] & ~(kLinkQualityInMask >> offset)) |
+        int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
+        mRouteData[aRouterIndex + aRouterIndex / 2] =
+            (mRouteData[aRouterIndex + aRouterIndex / 2] & ~(kLinkQualityInMask >> offset)) |
             ((aLinkQuality << (kLinkQualityInOffset - offset)) & (kLinkQualityInMask >> offset));
     }
 
     /**
-     * This method returns the Link Quality Out value for a given Router ID.
+     * This method returns the Link Quality Out value for a given Router index.
      *
-     * @returns The Link Quality Out value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Link Quality Out value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityOut(uint8_t aRouterId) const
+    uint8_t GetLinkQualityOut(uint8_t aRouterIndex) const
     {
-        int offset = ((aRouterId & 1) ? kOddEntryOffset : 0);
-        return (mRouteData[aRouterId + aRouterId / 2] & (kLinkQualityOutMask >> offset)) >>
+        int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
+        return (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityOutMask >> offset)) >>
                (kLinkQualityOutOffset - offset);
     }
 
     /**
-     * This method sets the Link Quality Out value for a given Router ID.
+     * This method sets the Link Quality Out value for a given Router index.
      *
-     * @param[in]  aRouterId     The Router ID.
-     * @param[in]  aLinkQuality  The Link Quality Out value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aLinkQuality  The Link Quality Out value for a given Router index.
      *
      */
-    void SetLinkQualityOut(uint8_t aRouterId, uint8_t aLinkQuality)
+    void SetLinkQualityOut(uint8_t aRouterIndex, uint8_t aLinkQuality)
     {
-        int offset = ((aRouterId & 1) ? kOddEntryOffset : 0);
-        mRouteData[aRouterId + aRouterId / 2] =
-            (mRouteData[aRouterId + aRouterId / 2] & ~(kLinkQualityOutMask >> offset)) |
+        int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
+        mRouteData[aRouterIndex + aRouterIndex / 2] =
+            (mRouteData[aRouterIndex + aRouterIndex / 2] & ~(kLinkQualityOutMask >> offset)) |
             ((aLinkQuality << (kLinkQualityOutOffset - offset)) & (kLinkQualityOutMask >> offset));
     }
 
@@ -863,111 +525,17 @@
         kRouteCostMask        = 0xf << kRouteCostOffset,
         kOddEntryOffset       = 4,
     };
-    uint8_t mRouterIdSequence;
-    uint8_t mRouterIdMask[BitVectorBytes(kMaxRouterId + 1)];
-    // Since we do hold 12 (compressible to 11) bits of data per router, each entry occupies 1.5 bytes, consecutively.
-    // First 4 bits are link qualities, remaining 8 bits are route cost.
+    uint8_t     mRouterIdSequence;
+    RouterIdSet mRouterIdMask;
+    // Since we do hold 12 (compressible to 11) bits of data per router, each entry occupies 1.5 bytes,
+    // consecutively. First 4 bits are link qualities, remaining 8 bits are route cost.
     uint8_t mRouteData[kMaxRouterId + 1 + kMaxRouterId / 2 + 1];
 } OT_TOOL_PACKED_END;
 
 #endif // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
 
 /**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class MleFrameCounterTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kMleFrameCounter);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Frame Counter value.
-     *
-     * @returns The Frame Counter value.
-     *
-     */
-    uint32_t GetFrameCounter(void) const { return HostSwap32(mFrameCounter); }
-
-    /**
-     * This method sets the Frame Counter value.
-     *
-     * @param[in]  aFrameCounter  The Frame Counter value.
-     *
-     */
-    void SetFrameCounter(uint32_t aFrameCounter) { mFrameCounter = HostSwap32(aFrameCounter); }
-
-private:
-    uint32_t mFrameCounter;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class Address16Tlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kAddress16);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the RLOC16 value.
-     *
-     * @returns The RLOC16 value.
-     *
-     */
-    uint16_t GetRloc16(void) const { return HostSwap16(mRloc16); }
-
-    /**
-     * This method sets the RLOC16 value.
-     *
-     * @param[in]  aRloc16  The RLOC16 value.
-     *
-     */
-    void SetRloc16(uint16_t aRloc16) { mRloc16 = HostSwap16(aRloc16); }
-
-private:
-    uint16_t mRloc16;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
+ * This class implements Leader Data TLV generation and parsing.
  *
  */
 OT_TOOL_PACKED_BEGIN
@@ -975,12 +543,6 @@
 {
 public:
     /**
-     * This method clears the object (setting all fields to zero).
-     *
-     */
-    void Clear(void) { memset(this, 0, sizeof(*this)); }
-
-    /**
      * This method initializes the TLV.
      *
      */
@@ -1000,84 +562,34 @@
     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
 
     /**
-     * This method returns the Partition ID value.
+     * This method gets the Leader Data info from TLV.
      *
-     * @returns The Partition ID value.
+     * @param[out] aLeaderData   A reference to output Leader Data info.
      *
      */
-    uint32_t GetPartitionId(void) const { return HostSwap32(mPartitionId); }
+    void Get(LeaderData &aLeaderData) const
+    {
+        aLeaderData.SetPartitionId(HostSwap32(mPartitionId));
+        aLeaderData.SetWeighting(mWeighting);
+        aLeaderData.SetDataVersion(mDataVersion);
+        aLeaderData.SetStableDataVersion(mStableDataVersion);
+        aLeaderData.SetLeaderRouterId(mLeaderRouterId);
+    }
 
     /**
-     * This method sets the Partition ID value.
+     * This method sets the Leader Data.
      *
-     * @param[in]  aPartitionId  The Partition ID value.
+     * @param[in] aLeaderData   A Leader Data.
      *
      */
-    void SetPartitionId(uint32_t aPartitionId) { mPartitionId = HostSwap32(aPartitionId); }
-
-    /**
-     * This method returns the Weighting value.
-     *
-     * @returns The Weighting value.
-     *
-     */
-    uint8_t GetWeighting(void) const { return mWeighting; }
-
-    /**
-     * This method sets the Weighting value.
-     *
-     * @param[in]  aWeighting  The Weighting value.
-     *
-     */
-    void SetWeighting(uint8_t aWeighting) { mWeighting = aWeighting; }
-
-    /**
-     * This method returns the Data Version value.
-     *
-     * @returns The Data Version value.
-     *
-     */
-    uint8_t GetDataVersion(void) const { return mDataVersion; }
-
-    /**
-     * This method sets the Data Version value.
-     *
-     * @param[in]  aVersion  The Data Version value.
-     *
-     */
-    void SetDataVersion(uint8_t aVersion) { mDataVersion = aVersion; }
-
-    /**
-     * This method returns the Stable Data Version value.
-     *
-     * @returns The Stable Data Version value.
-     *
-     */
-    uint8_t GetStableDataVersion(void) const { return mStableDataVersion; }
-
-    /**
-     * This method sets the Stable Data Version value.
-     *
-     * @param[in]  aVersion  The Stable Data Version value.
-     *
-     */
-    void SetStableDataVersion(uint8_t aVersion) { mStableDataVersion = aVersion; }
-
-    /**
-     * This method returns the Leader Router ID value.
-     *
-     * @returns The Leader Router ID value.
-     *
-     */
-    uint8_t GetLeaderRouterId(void) const { return mLeaderRouterId; }
-
-    /**
-     * This method sets the Leader Router ID value.
-     *
-     * @param[in]  aRouterId  The Leader Router ID value.
-     *
-     */
-    void SetLeaderRouterId(uint8_t aRouterId) { mLeaderRouterId = aRouterId; }
+    void Set(const LeaderData &aLeaderData)
+    {
+        mPartitionId       = HostSwap32(aLeaderData.GetPartitionId());
+        mWeighting         = aLeaderData.GetWeighting();
+        mDataVersion       = aLeaderData.GetDataVersion();
+        mStableDataVersion = aLeaderData.GetStableDataVersion();
+        mLeaderRouterId    = aLeaderData.GetLeaderRouterId();
+    }
 
 private:
     uint32_t mPartitionId;
@@ -1088,202 +600,41 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements Source Address TLV generation and parsing.
+ * This class implements Scan Mask TLV generation and parsing.
  *
  */
-OT_TOOL_PACKED_BEGIN
-class NetworkDataTlv : public Tlv
+class ScanMaskTlv
 {
 public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kNetworkData);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method returns a pointer to the Network Data.
-     *
-     * @returns A pointer to the Network Data.
-     *
-     */
-    uint8_t *GetNetworkData(void) { return mNetworkData; }
-
-    /**
-     * This method sets the Network Data.
-     *
-     * @param[in]  aNetworkData  A pointer to the Network Data.
-     *
-     */
-    void SetNetworkData(const uint8_t *aNetworkData) { memcpy(mNetworkData, aNetworkData, GetLength()); }
-
-private:
-    uint8_t mNetworkData[255];
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class TlvRequestTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kTlvRequest);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() <= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns a pointer to the TLV list.
-     *
-     * @returns A pointer to the TLV list.
-     *
-     */
-    const uint8_t *GetTlvs(void) const { return mTlvs; }
-
-    /**
-     * This method provides the next Tlv in the TlvRequestTlv.
-     *
-     * @retval OT_ERROR_NONE        Successfully found the next Tlv.
-     * @retval OT_ERROR_NOT_FOUND   No subsequent Tlv exists in TlvRequestTlv.
-     *
-     */
-    otError GetNextTlv(TlvRequestIterator &aIterator, uint8_t &aTlv) const
-    {
-        otError error = OT_ERROR_NOT_FOUND;
-
-        if (aIterator < GetLength())
-        {
-            aTlv      = mTlvs[aIterator];
-            aIterator = static_cast<TlvRequestIterator>(aIterator + sizeof(uint8_t));
-            error     = OT_ERROR_NONE;
-        }
-
-        return error;
-    }
-
-    /**
-     * This method sets the list of TLVs.
-     *
-     * @param[in]  aTlvs  A pointer to the TLV list.
-     *
-     */
-    void SetTlvs(const uint8_t *aTlvs) { memcpy(mTlvs, aTlvs, GetLength()); }
-
-private:
     enum
     {
-        kMaxTlvs = 8,
+        kRouterFlag    = 1 << 7, ///< Scan Mask Router Flag.
+        kEndDeviceFlag = 1 << 6, ///< Scan Mask End Device Flag.
     };
-    uint8_t mTlvs[kMaxTlvs];
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ScanMaskTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kScanMask);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    enum
-    {
-        kRouterFlag    = 1 << 7,
-        kEndDeviceFlag = 1 << 6,
-    };
-
-    /**
-     * This method clears Router flag.
-     *
-     */
-    void ClearRouterFlag(void) { mMask &= ~kRouterFlag; }
-
-    /**
-     * This method sets the Router flag.
-     *
-     */
-    void SetRouterFlag(void) { mMask |= kRouterFlag; }
 
     /**
      * This method indicates whether or not the Router flag is set.
      *
+     * @param[in] aMask   A scan mask value.
+     *
      * @retval TRUE   If the Router flag is set.
      * @retval FALSE  If the Router flag is not set.
      */
-    bool IsRouterFlagSet(void) const { return (mMask & kRouterFlag) != 0; }
-
-    /**
-     * This method clears the End Device flag.
-     *
-     */
-    void ClearEndDeviceFlag(void) { mMask &= ~kEndDeviceFlag; }
-
-    /**
-     * This method sets the End Device flag.
-     *
-     */
-    void SetEndDeviceFlag(void) { mMask |= kEndDeviceFlag; }
+    static bool IsRouterFlagSet(uint8_t aMask) { return (aMask & kRouterFlag) != 0; }
 
     /**
      * This method indicates whether or not the End Device flag is set.
      *
+     * @param[in] aMask   A scan mask value.
+     *
      * @retval TRUE   If the End Device flag is set.
      * @retval FALSE  If the End Device flag is not set.
      */
-    bool IsEndDeviceFlagSet(void) const { return (mMask & kEndDeviceFlag) != 0; }
-
-    /**
-     * This method sets the Mask byte value.
-     *
-     * @param[in]  aMask  The Mask byte value.
-     *
-     */
-    void SetMask(uint8_t aMask) { mMask = aMask; }
-
-private:
-    uint8_t mMask;
-} OT_TOOL_PACKED_END;
+    static bool IsEndDeviceFlagSet(uint8_t aMask) { return (aMask & kEndDeviceFlag) != 0; }
+};
 
 /**
- * This class implements Source Address TLV generation and parsing.
+ * This class implements Connectivity TLV generation and parsing.
  *
  */
 OT_TOOL_PACKED_BEGIN
@@ -1509,79 +860,11 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements Source Address TLV generation and parsing.
+ * This class specifies Status TLV status values.
  *
  */
-OT_TOOL_PACKED_BEGIN
-class LinkMarginTlv : public Tlv
+struct StatusTlv
 {
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kLinkMargin);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Link Margin value.
-     *
-     * @returns The Link Margin value.
-     *
-     */
-    uint8_t GetLinkMargin(void) const { return mLinkMargin; }
-
-    /**
-     * This method sets the Link Margin value.
-     *
-     * @param[in]  aLinkMargin  The Link Margin value.
-     *
-     */
-    void SetLinkMargin(uint8_t aLinkMargin) { mLinkMargin = aLinkMargin; }
-
-private:
-    uint8_t mLinkMargin;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class StatusTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kStatus);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
     /**
      * Status values.
      */
@@ -1589,73 +872,7 @@
     {
         kError = 1, ///< Error.
     };
-
-    /**
-     * This method returns the Status value.
-     *
-     * @returns The Status value.
-     *
-     */
-    Status GetStatus(void) const { return static_cast<Status>(mStatus); }
-
-    /**
-     * This method sets the Status value.
-     *
-     * @param[in]  aStatus  The Status value.
-     *
-     */
-    void SetStatus(Status aStatus) { mStatus = static_cast<uint8_t>(aStatus); }
-
-private:
-    uint8_t mStatus;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class VersionTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kVersion);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the Version value.
-     *
-     * @returns The Version value.
-     *
-     */
-    uint16_t GetVersion(void) const { return HostSwap16(mVersion); }
-
-    /**
-     * This method sets the Version value.
-     *
-     * @param[in]  aVersion  The Version value.
-     *
-     */
-    void SetVersion(uint16_t aVersion) { mVersion = HostSwap16(aVersion); }
-
-private:
-    uint16_t mVersion;
-} OT_TOOL_PACKED_END;
+};
 
 /**
  * This class implements Source Address TLV generation and parsing.
@@ -1706,28 +923,28 @@
     void SetContextId(uint8_t aContextId) { mControl = kCompressed | aContextId; }
 
     /**
-     * This method returns a pointer to the IID value.
+     * This method returns the IID value.
      *
-     * @returns A pointer to the IID value.
+     * @returns The IID value.
      *
      */
-    const uint8_t *GetIid(void) const { return mIid; }
+    const Ip6::InterfaceIdentifier &GetIid(void) const { return mIid; }
 
     /**
      * This method sets the IID value.
      *
-     * @param[in]  aIid  A pointer to the IID value.
+     * @param[in]  aIid  The IID value.
      *
      */
-    void SetIid(const uint8_t *aIid) { memcpy(mIid, aIid, sizeof(mIid)); }
+    void SetIid(const Ip6::InterfaceIdentifier &aIid) { mIid = aIid; }
 
     /**
-     * This method returns a pointer to the IPv6 Address value.
+     * This method returns the IPv6 Address value.
      *
-     * @returns A pointer to the IPv6 Address value.
+     * @returns The IPv6 Address value.
      *
      */
-    const Ip6::Address *GetIp6Address(void) const { return &mIp6Address; }
+    const Ip6::Address &GetIp6Address(void) const { return mIp6Address; }
 
     /**
      * This method sets the IPv6 Address value.
@@ -1747,8 +964,8 @@
     uint8_t mControl;
     union
     {
-        uint8_t      mIid[Ip6::Address::kInterfaceIdentifierSize];
-        Ip6::Address mIp6Address;
+        Ip6::InterfaceIdentifier mIid;
+        Ip6::Address             mIp6Address;
     } OT_TOOL_PACKED_FIELD;
 } OT_TOOL_PACKED_END;
 
@@ -1816,53 +1033,6 @@
     uint16_t mChannel;
 } OT_TOOL_PACKED_END;
 
-/**
- * This class implements PAN ID TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class PanIdTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kPanId);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the PAN ID value.
-     *
-     * @returns The PAN ID value.
-     *
-     */
-    uint16_t GetPanId(void) const { return HostSwap16(mPanId); }
-
-    /**
-     * This method sets the PAN ID value.
-     *
-     * @param[in]  aPanId  The PAN ID value.
-     *
-     */
-    void SetPanId(uint16_t aPanId) { mPanId = HostSwap16(aPanId); }
-
-private:
-    uint16_t mPanId;
-} OT_TOOL_PACKED_END;
-
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 /**
  * This class implements Time Request TLV generation and parsing.
@@ -1956,52 +1126,6 @@
     uint16_t mXtalThreshold;
 } OT_TOOL_PACKED_END;
 
-/**
- * This class implements XTAL Accuracy TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class XtalAccuracyTlv : public Tlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kXtalAccuracy);
-        SetLength(sizeof(*this) - sizeof(Tlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
-
-    /**
-     * This method returns the XTAL accuracy.
-     *
-     * @returns The XTAL accuracy.
-     *
-     */
-    uint16_t GetXtalAccuracy(void) const { return HostSwap16(mXtalAccuracy); }
-
-    /**
-     * This method sets the XTAL accuracy.
-     *
-     * @param[in]  aXTALAccuracy  The XTAL accuracy.
-     *
-     */
-    void SetXtalAccuracy(uint16_t aXtalAccuracy) { mXtalAccuracy = HostSwap16(aXtalAccuracy); }
-
-private:
-    uint16_t mXtalAccuracy;
-} OT_TOOL_PACKED_END;
 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 
 /**
diff --git a/src/core/thread/mle_types.cpp b/src/core/thread/mle_types.cpp
new file mode 100644
index 0000000..29a0767
--- /dev/null
+++ b/src/core/thread/mle_types.cpp
@@ -0,0 +1,74 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements of MLE types and constants.
+ */
+
+#include "mle_types.hpp"
+
+#include "common/code_utils.hpp"
+
+namespace ot {
+namespace Mle {
+
+void DeviceMode::Get(ModeConfig &aModeConfig) const
+{
+    aModeConfig.mRxOnWhenIdle       = IsRxOnWhenIdle();
+    aModeConfig.mSecureDataRequests = IsSecureDataRequest();
+    aModeConfig.mDeviceType         = IsFullThreadDevice();
+    aModeConfig.mNetworkData        = IsFullNetworkData();
+}
+
+void DeviceMode::Set(const ModeConfig &aModeConfig)
+{
+    mMode = 0;
+    mMode |= aModeConfig.mRxOnWhenIdle ? kModeRxOnWhenIdle : 0;
+    mMode |= aModeConfig.mSecureDataRequests ? kModeSecureDataRequest : 0;
+    mMode |= aModeConfig.mDeviceType ? kModeFullThreadDevice : 0;
+    mMode |= aModeConfig.mNetworkData ? kModeFullNetworkData : 0;
+}
+
+DeviceMode::InfoString DeviceMode::ToString(void) const
+{
+    return InfoString("rx-on:%s sec-poll:%s ftd:%s full-net:%s", IsRxOnWhenIdle() ? "yes" : "no",
+                      IsSecureDataRequest() ? "yes" : "no", IsFullThreadDevice() ? "yes" : "no",
+                      IsFullNetworkData() ? "yes" : "no");
+}
+
+void MeshLocalPrefix::SetFromExtendedPanId(const Mac::ExtendedPanId &aExtendedPanId)
+{
+    m8[0] = 0xfd;
+    memcpy(&m8[1], aExtendedPanId.m8, 5);
+    m8[6] = 0x00;
+    m8[7] = 0x00;
+}
+
+} // namespace Mle
+} // namespace ot
diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp
new file mode 100644
index 0000000..ce865f8
--- /dev/null
+++ b/src/core/thread/mle_types.hpp
@@ -0,0 +1,590 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for MLE types and constants.
+ */
+
+#ifndef MLE_TYPES_HPP_
+#define MLE_TYPES_HPP_
+
+#include "openthread-core-config.h"
+
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <openthread/thread.h>
+
+#include "common/clearable.hpp"
+#include "common/encoding.hpp"
+#include "common/equatable.hpp"
+#include "common/string.hpp"
+#include "mac/mac_types.hpp"
+#include "net/ip6_address.hpp"
+
+namespace ot {
+namespace Mle {
+
+/**
+ * @addtogroup core-mle-core
+ *
+ * @brief
+ *   This module includes definition for MLE types and constants.
+ *
+ * @{
+ *
+ */
+
+enum
+{
+    kMaxChildren               = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN,
+    kMaxChildKeepAliveAttempts = 4, ///< Maximum keep alive attempts before attempting to reattach to a new Parent
+    kFailedChildTransmissions  = OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS, ///< FAILED_CHILD_TRANSMISSIONS
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    // Extra one for core Backbone Router Service.
+    kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS + 1,
+#else
+    kMaxServiceAlocs      = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS,
+#endif
+};
+
+/**
+ * MLE Protocol Constants
+ *
+ */
+enum
+{
+    kThreadVersion                  = OPENTHREAD_CONFIG_THREAD_VERSION, ///< Thread Version
+    kUdpPort                        = 19788,                            ///< MLE UDP Port
+    kParentRequestRouterTimeout     = 750,                              ///< Router Parent Request timeout
+    kParentRequestDuplicateMargin   = 50,                               ///< Margin for duplicate parent request
+    kParentRequestReedTimeout       = 1250,                             ///< Router and REEDs Parent Request timeout
+    kAttachStartJitter              = 50,   ///< Maximum jitter time added to start of attach.
+    kAnnounceProcessTimeout         = 250,  ///< Timeout after receiving Announcement before channel/pan-id change
+    kAnnounceTimeout                = 1400, ///< Total timeout used for sending Announcement messages
+    kMinAnnounceDelay               = 80,   ///< Minimum delay between Announcement messages
+    kParentResponseMaxDelayRouters  = 500,  ///< Maximum delay for response for Parent Request sent to routers only
+    kParentResponseMaxDelayAll      = 1000, ///< Maximum delay for response for Parent Request sent to all devices
+    kUnicastRetransmissionDelay     = 1000, ///< Base delay before retransmitting an MLE unicast.
+    kChildUpdateRequestPendingDelay = 100,  ///< Delay (in ms) for aggregating Child Update Request.
+    kMaxTransmissionCount           = 3,    ///< Maximum number of times an MLE message may be transmitted.
+    kMaxResponseDelay               = 1000, ///< Maximum delay before responding to a multicast request
+    kMaxChildIdRequestTimeout       = 5000, ///< Maximum delay for receiving a Child ID Request
+    kMaxChildUpdateResponseTimeout  = 2000, ///< Maximum delay for receiving a Child Update Response
+    kMaxLinkRequestTimeout          = 2000, ///< Maximum delay for receiving a Link Accept
+    kMinTimeoutKeepAlive            = (((kMaxChildKeepAliveAttempts + 1) * kUnicastRetransmissionDelay) /
+                            1000), ///< Minimum timeout(in seconds) for keep alive
+    kMinTimeoutDataPoll             = (OPENTHREAD_CONFIG_MAC_MINIMUM_POLL_PERIOD +
+                           OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS * OPENTHREAD_CONFIG_MAC_RETX_POLL_PERIOD) /
+                          1000, ///< Minimum timeout(in seconds) for data poll
+    kMinTimeout = (kMinTimeoutKeepAlive >= kMinTimeoutDataPoll ? kMinTimeoutKeepAlive
+                                                               : kMinTimeoutDataPoll), ///< Minimum timeout(in seconds)
+};
+
+enum
+{
+    kMinChildId       = 1,   ///< Minimum Child ID
+    kMaxChildId       = 511, ///< Maximum Child ID
+    kRouterIdOffset   = 10,  ///< Bit offset of Router ID in RLOC16
+    kRlocPrefixLength = 14,  ///< Prefix length of RLOC in bytes
+};
+
+/**
+ *  MLE TLV Constants
+ */
+enum
+{
+    kMinChallengeSize = 4, ///< Minimum Challenge size in bytes.
+    kMaxChallengeSize = 8, ///< Maximum Challenge size in bytes.
+};
+
+/**
+ * Routing Protocol Constants
+ *
+ */
+enum
+{
+    kAdvertiseIntervalMin = 1, ///< ADVERTISEMENT_I_MIN (sec)
+#if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
+    kAdvertiseIntervalMax = 5, ///< ADVERTISEMENT_I_MAX (sec) proposal
+#else
+    kAdvertiseIntervalMax = 32, ///< ADVERTISEMENT_I_MAX (sec)
+#endif
+    kFailedRouterTransmissions = 4,   ///< FAILED_ROUTER_TRANSMISSIONS
+    kRouterIdReuseDelay        = 100, ///< ID_REUSE_DELAY (sec)
+    kRouterIdSequencePeriod    = 10,  ///< ID_SEQUENCE_PERIOD (sec)
+    kMaxNeighborAge            = 100, ///< MAX_NEIGHBOR_AGE (sec)
+#if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
+    kMaxRouteCost = 127, ///< MAX_ROUTE_COST proposal
+#else
+    kMaxRouteCost         = 16, ///< MAX_ROUTE_COST
+#endif
+    kMaxRouterId                = OT_NETWORK_MAX_ROUTER_ID,                    ///< MAX_ROUTER_ID
+    kInvalidRouterId            = kMaxRouterId + 1,                            ///< Value indicating incorrect Router Id
+    kMaxRouters                 = OPENTHREAD_CONFIG_MLE_MAX_ROUTERS,           ///< MAX_ROUTERS
+    kMinDowngradeNeighbors      = 7,                                           ///< MIN_DOWNGRADE_NEIGHBORS
+    kNetworkIdTimeout           = 120,                                         ///< NETWORK_ID_TIMEOUT (sec)
+    kParentRouteToLeaderTimeout = 20,                                          ///< PARENT_ROUTE_TO_LEADER_TIMEOUT (sec)
+    kRouterSelectionJitter      = 120,                                         ///< ROUTER_SELECTION_JITTER (sec)
+    kRouterDowngradeThreshold   = 23,                                          ///< ROUTER_DOWNGRADE_THRESHOLD (routers)
+    kRouterUpgradeThreshold     = 16,                                          ///< ROUTER_UPGRADE_THRESHOLD (routers)
+    kMaxLeaderToRouterTimeout   = 90,                                          ///< INFINITE_COST_TIMEOUT (sec)
+    kReedAdvertiseInterval      = 570,                                         ///< REED_ADVERTISEMENT_INTERVAL (sec)
+    kReedAdvertiseJitter        = 60,                                          ///< REED_ADVERTISEMENT_JITTER (sec)
+    kLeaderWeight               = 64,                                          ///< Default leader weight
+    kMleEndDeviceTimeout        = OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT, ///< MLE_END_DEVICE_TIMEOUT (sec)
+    kMeshLocalPrefixContextId   = 0,                                           ///< 0 is reserved for Mesh Local Prefix
+};
+
+/**
+ * Parent Priority values
+ *
+ */
+enum
+{
+    kParentPriorityHigh        = 1,  // Parent Priority High
+    kParentPriorityMedium      = 0,  // Parent Priority Medium (default)
+    kParentPriorityLow         = -1, // Parent Priority Low
+    kParentPriorityUnspecified = -2, // Parent Priority Unspecified
+};
+
+enum
+{
+    kLinkQuality3LinkCost = 1,             ///< Link Cost for Link Quality 3
+    kLinkQuality2LinkCost = 2,             ///< Link Cost for Link Quality 2
+    kLinkQuality1LinkCost = 4,             ///< Link Cost for Link Quality 1
+    kLinkQuality0LinkCost = kMaxRouteCost, ///< Link Cost for Link Quality 0
+};
+
+/**
+ * Multicast Forwarding Constants
+ *
+ */
+enum
+{
+    kMplChildDataMessageTimerExpirations  = 0, ///< Number of MPL retransmissions for Children.
+    kMplRouterDataMessageTimerExpirations = 2, ///< Number of MPL retransmissions for Routers.
+};
+
+/**
+ * This type represents a Thread device role.
+ *
+ */
+enum DeviceRole
+{
+    kRoleDisabled = OT_DEVICE_ROLE_DISABLED, ///< The Thread stack is disabled.
+    kRoleDetached = OT_DEVICE_ROLE_DETACHED, ///< Not currently participating in a Thread network/partition.
+    kRoleChild    = OT_DEVICE_ROLE_CHILD,    ///< The Thread Child role.
+    kRoleRouter   = OT_DEVICE_ROLE_ROUTER,   ///< The Thread Router role.
+    kRoleLeader   = OT_DEVICE_ROLE_LEADER,   ///< The Thread Leader role.
+};
+
+/**
+ * MLE Attach modes
+ *
+ */
+enum AttachMode
+{
+    kAttachAny           = 0, ///< Attach to any Thread partition.
+    kAttachSame1         = 1, ///< Attach to the same Thread partition (attempt 1 when losing connectivity).
+    kAttachSame2         = 2, ///< Attach to the same Thread partition (attempt 2 when losing connectivity).
+    kAttachBetter        = 3, ///< Attach to a better (i.e. higher weight/partition id) Thread partition.
+    kAttachSameDowngrade = 4, ///< Attach to the same Thread partition during downgrade process.
+};
+
+/**
+ * This enumeration represents the allocation of the ALOC Space
+ *
+ */
+enum AlocAllocation
+{
+    kAloc16Leader                      = 0xfc00,
+    kAloc16DhcpAgentStart              = 0xfc01,
+    kAloc16DhcpAgentEnd                = 0xfc0f,
+    kAloc16DhcpAgentMask               = 0x000f,
+    kAloc16ServiceStart                = 0xfc10,
+    kAloc16ServiceEnd                  = 0xfc2f,
+    kAloc16CommissionerStart           = 0xfc30,
+    kAloc16CommissionerEnd             = 0xfc37,
+    kAloc16BackboneRouterPrimary       = 0xfc38,
+    kAloc16CommissionerMask            = 0x0007,
+    kAloc16NeighborDiscoveryAgentStart = 0xfc40,
+    kAloc16NeighborDiscoveryAgentEnd   = 0xfc4e,
+};
+
+/**
+ * Service IDs
+ *
+ */
+enum
+{
+    kServiceMinId = 0x00, ///< Minimal Service ID.
+    kServiceMaxId = 0x0f, ///< Maximal Service ID.
+};
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+
+/**
+ * Backbone Router constants
+ *
+ */
+enum
+{
+    kRegistrationDelayDefault         = 1200, //< In seconds.
+    kMlrTimeoutDefault                = 3600, //< In seconds.
+    kMlrTimeoutMin                    = 300,  //< In seconds.
+    kBackboneRouterRegistrationJitter = 5,    //< In seconds.
+};
+
+static_assert(kMlrTimeoutDefault >= kMlrTimeoutMin,
+              "kMlrTimeoutDefault must be larger than or equal to kMlrTimeoutMin");
+
+#endif
+
+/**
+ * This type represents a MLE device mode.
+ *
+ */
+class DeviceMode : public Equatable<DeviceMode>
+{
+public:
+    enum
+    {
+        kModeRxOnWhenIdle      = 1 << 3, ///< If the device has its receiver on when not transmitting.
+        kModeSecureDataRequest = 1 << 2, ///< If the device uses link layer security for all data requests.
+        kModeFullThreadDevice  = 1 << 1, ///< If the device is an FTD.
+        kModeFullNetworkData   = 1 << 0, ///< If the device requires the full Network Data.
+
+        kInfoStringSize = 45, ///< String buffer size used for `ToString()`.
+    };
+
+    /**
+     * This type defines the fixed-length `String` object returned from `ToString()`.
+     *
+     */
+    typedef String<kInfoStringSize> InfoString;
+
+    /**
+     *  This structure represents an MLE Mode configuration.
+     *
+     */
+    typedef otLinkModeConfig ModeConfig;
+
+    /**
+     * This is the default constructor for `DeviceMode` object.
+     *
+     */
+    DeviceMode(void) {}
+
+    /**
+     * This constructor initializes a `DeviceMode` object from a given mode TLV bitmask.
+     *
+     * @param[in] aMode   A mode TLV bitmask to initialize the `DeviceMode` object.
+     *
+     */
+    explicit DeviceMode(uint8_t aMode)
+        : mMode(aMode)
+    {
+    }
+
+    /**
+     * This constructor initializes a `DeviceMode` object from a given mode configuration structure.
+     *
+     * @param[in] aModeConfig   A mode configuration to initialize the `DeviceMode` object.
+     *
+     */
+    explicit DeviceMode(ModeConfig aModeConfig) { Set(aModeConfig); }
+
+    /**
+     * This method gets the device mode as a mode TLV bitmask.
+     *
+     * @returns The device mode as a mode TLV bitmask.
+     *
+     */
+    uint8_t Get(void) const { return mMode; }
+
+    /**
+     * This method sets the device mode from a given mode TLV bitmask.
+     *
+     * @param[in] aMode   A mode TLV bitmask.
+     *
+     */
+    void Set(uint8_t aMode) { mMode = aMode; }
+
+    /**
+     * This method gets the device mode as a mode configuration structure.
+     *
+     * @param[out] aModeConfig   A reference to a mode configuration structure to output the device mode.
+     *
+     */
+    void Get(ModeConfig &aModeConfig) const;
+
+    /**
+     * this method sets the device mode from a given mode configuration structure.
+     *
+     * @param[in] aModeConfig   A mode configuration structure.
+     *
+     */
+    void Set(const ModeConfig &aModeConfig);
+
+    /**
+     * This method indicates whether or not the device is rx-on-when-idle.
+     *
+     * @retval TRUE   If the device is rx-on-when-idle (non-sleepy).
+     * @retval FALSE  If the device is not rx-on-when-idle (sleepy).
+     *
+     */
+    bool IsRxOnWhenIdle(void) const { return (mMode & kModeRxOnWhenIdle) != 0; }
+
+    /**
+     * This method indicates whether or not the device uses secure IEEE 802.15.4 Data Request messages.
+     *
+     * @retval TRUE   If the device uses secure IEEE 802.15.4 Data Request (data poll) messages.
+     * @retval FALSE  If the device uses any IEEE 802.15.4 Data Request (data poll) messages.
+     *
+     */
+    bool IsSecureDataRequest(void) const { return (mMode & kModeSecureDataRequest) != 0; }
+
+    /**
+     * This method indicates whether or not the device is a Full Thread Device.
+     *
+     * @retval TRUE   If the device is Full Thread Device.
+     * @retval FALSE  If the device if not Full Thread Device.
+     *
+     */
+    bool IsFullThreadDevice(void) const { return (mMode & kModeFullThreadDevice) != 0; }
+
+    /**
+     * This method indicates whether or not the device requests Full Network Data.
+     *
+     * @retval TRUE   If the device requests Full Network Data.
+     * @retval FALSE  If the device does not request Full Network Data (only stable Network Data).
+     *
+     */
+    bool IsFullNetworkData(void) const { return (mMode & kModeFullNetworkData) != 0; }
+
+    /**
+     * This method indicates whether or not the device is a Minimal End Device.
+     *
+     * @retval TRUE   If the device is a Minimal End Device.
+     * @retval FALSE  If the device is not a Minimal End Device.
+     *
+     */
+    bool IsMinimalEndDevice(void) const
+    {
+        return (mMode & (kModeFullThreadDevice | kModeRxOnWhenIdle)) != (kModeFullThreadDevice | kModeRxOnWhenIdle);
+    }
+
+    /**
+     * This method indicates whether or not the device mode flags are valid.
+     *
+     * An FTD which is not rx-on-when-idle (is sleepy) is considered invalid.
+     *
+     * @returns TRUE if , FALSE otherwise.
+     * @retval TRUE   If the device mode flags are valid.
+     * @retval FALSE  If the device mode flags are not valid.
+     *
+     */
+    bool IsValid(void) const { return !IsFullThreadDevice() || IsRxOnWhenIdle(); }
+
+    /**
+     * This method converts the device mode into a human-readable string.
+     *
+     * @returns An `InfoString` object representing the device mode.
+     *
+     */
+    InfoString ToString(void) const;
+
+private:
+    uint8_t mMode;
+};
+
+/**
+ * This class represents a Mesh Local Prefix.
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+class MeshLocalPrefix : public Ip6::NetworkPrefix
+{
+public:
+    /**
+     * This method derives and sets the Mesh Local Prefix from an Extended PAN ID.
+     *
+     * @param[in] aExtendedPanId   An Extended PAN ID.
+     *
+     */
+    void SetFromExtendedPanId(const Mac::ExtendedPanId &aExtendedPanId);
+
+} OT_TOOL_PACKED_END;
+
+/**
+ * This class represents the Thread Leader Data.
+ *
+ */
+class LeaderData : public otLeaderData, public Clearable<LeaderData>
+{
+public:
+    /**
+     * This method returns the Partition ID value.
+     *
+     * @returns The Partition ID value.
+     *
+     */
+    uint32_t GetPartitionId(void) const { return mPartitionId; }
+
+    /**
+     * This method sets the Partition ID value.
+     *
+     * @param[in]  aPartitionId  The Partition ID value.
+     *
+     */
+    void SetPartitionId(uint32_t aPartitionId) { mPartitionId = aPartitionId; }
+
+    /**
+     * This method returns the Weighting value.
+     *
+     * @returns The Weighting value.
+     *
+     */
+    uint8_t GetWeighting(void) const { return mWeighting; }
+
+    /**
+     * This method sets the Weighting value.
+     *
+     * @param[in]  aWeighting  The Weighting value.
+     *
+     */
+    void SetWeighting(uint8_t aWeighting) { mWeighting = aWeighting; }
+
+    /**
+     * This method returns the Data Version value.
+     *
+     * @returns The Data Version value.
+     *
+     */
+    uint8_t GetDataVersion(void) const { return mDataVersion; }
+
+    /**
+     * This method sets the Data Version value.
+     *
+     * @param[in]  aVersion  The Data Version value.
+     *
+     */
+    void SetDataVersion(uint8_t aVersion) { mDataVersion = aVersion; }
+
+    /**
+     * This method returns the Stable Data Version value.
+     *
+     * @returns The Stable Data Version value.
+     *
+     */
+    uint8_t GetStableDataVersion(void) const { return mStableDataVersion; }
+
+    /**
+     * This method sets the Stable Data Version value.
+     *
+     * @param[in]  aVersion  The Stable Data Version value.
+     *
+     */
+    void SetStableDataVersion(uint8_t aVersion) { mStableDataVersion = aVersion; }
+
+    /**
+     * This method returns the Leader Router ID value.
+     *
+     * @returns The Leader Router ID value.
+     *
+     */
+    uint8_t GetLeaderRouterId(void) const { return mLeaderRouterId; }
+
+    /**
+     * This method sets the Leader Router ID value.
+     *
+     * @param[in]  aRouterId  The Leader Router ID value.
+     *
+     */
+    void SetLeaderRouterId(uint8_t aRouterId) { mLeaderRouterId = aRouterId; }
+};
+
+OT_TOOL_PACKED_BEGIN
+class RouterIdSet : public Equatable<RouterIdSet>
+{
+public:
+    /**
+     * This method clears the Router Id Set.
+     *
+     */
+    void Clear(void) { memset(mRouterIdSet, 0, sizeof(mRouterIdSet)); }
+
+    /**
+     * This method indicates whether or not a Router ID bit is set.
+     *
+     * @param[in]  aRouterId  The Router ID.
+     *
+     * @retval TRUE   If the Router ID bit is set.
+     * @retval FALSE  If the Router ID bit is not set.
+     *
+     */
+    bool Contains(uint8_t aRouterId) const { return (mRouterIdSet[aRouterId / 8] & (0x80 >> (aRouterId % 8))) != 0; }
+
+    /**
+     * This method sets a given Router ID.
+     *
+     * @param[in]  aRouterId  The Router ID to set.
+     *
+     */
+    void Add(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] |= 0x80 >> (aRouterId % 8); }
+
+    /**
+     * This method removes a given Router ID.
+     *
+     * @param[in]  aRouterId  The Router ID to remove.
+     *
+     */
+    void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~(0x80 >> (aRouterId % 8)); }
+
+private:
+    uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
+} OT_TOOL_PACKED_END;
+
+/**
+ * This class represents a MLE key.
+ *
+ */
+typedef Mac::Key Key;
+
+/**
+ * @}
+ *
+ */
+
+} // namespace Mle
+} // namespace ot
+
+#endif // MLE_TYPES_HPP_
diff --git a/src/core/thread/network_data.cpp b/src/core/thread/network_data.cpp
index 851e84b..2cbc95d 100644
--- a/src/core/thread/network_data.cpp
+++ b/src/core/thread/network_data.cpp
@@ -50,8 +50,6 @@
 NetworkData::NetworkData(Instance &aInstance, Type aType)
     : InstanceLocator(aInstance)
     , mType(aType)
-    , mLastAttemptWait(false)
-    , mLastAttempt(0)
 {
     mLength = 0;
 }
@@ -61,11 +59,56 @@
     mLength = 0;
 }
 
-otError NetworkData::GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength)
+const NetworkDataTlv *NetworkData::FindTlv(const NetworkDataTlv *aStart,
+                                           const NetworkDataTlv *aEnd,
+                                           NetworkDataTlv::Type  aType)
+{
+    const NetworkDataTlv *tlv;
+
+    for (tlv = aStart; tlv < aEnd; tlv = tlv->GetNext())
+    {
+        VerifyOrExit((tlv + 1) <= aEnd && tlv->GetNext() <= aEnd, tlv = nullptr);
+
+        if (tlv->GetType() == aType)
+        {
+            ExitNow();
+        }
+    }
+
+    tlv = nullptr;
+
+exit:
+    return tlv;
+}
+
+const NetworkDataTlv *NetworkData::FindTlv(const NetworkDataTlv *aStart,
+                                           const NetworkDataTlv *aEnd,
+                                           NetworkDataTlv::Type  aType,
+                                           bool                  aStable)
+{
+    const NetworkDataTlv *tlv;
+
+    for (tlv = aStart; tlv < aEnd; tlv = tlv->GetNext())
+    {
+        VerifyOrExit((tlv + 1) <= aEnd && tlv->GetNext() <= aEnd, tlv = nullptr);
+
+        if ((tlv->GetType() == aType) && (tlv->IsStable() == aStable))
+        {
+            ExitNow();
+        }
+    }
+
+    tlv = nullptr;
+
+exit:
+    return tlv;
+}
+
+otError NetworkData::GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const
 {
     otError error = OT_ERROR_NONE;
 
-    assert(aData != NULL);
+    OT_ASSERT(aData != nullptr);
     VerifyOrExit(aDataLength >= mLength, error = OT_ERROR_NO_BUFS);
 
     memcpy(aData, mTlvs, mLength);
@@ -80,225 +123,222 @@
     return error;
 }
 
-otError NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig &aConfig)
+otError NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig &aConfig) const
 {
     return GetNextOnMeshPrefix(aIterator, Mac::kShortAddrBroadcast, aConfig);
 }
 
-otError NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig)
+otError NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig) const
 {
-    otError             error = OT_ERROR_NOT_FOUND;
-    NetworkDataIterator iterator(aIterator);
-    NetworkDataTlv *    cur = reinterpret_cast<NetworkDataTlv *>(mTlvs + iterator.GetTlvOffset());
-    NetworkDataTlv *    end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
+    Config config;
 
-    for (; cur < end; cur = cur->GetNext(), iterator.SetSubTlvOffset(0), iterator.SetEntryIndex(0))
-    {
-        PrefixTlv *     prefix;
-        NetworkDataTlv *subCur;
-        NetworkDataTlv *subEnd;
+    config.mOnMeshPrefix  = &aConfig;
+    config.mExternalRoute = nullptr;
+    config.mService       = nullptr;
 
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
-
-        if (cur->GetType() != NetworkDataTlv::kTypePrefix)
-        {
-            continue;
-        }
-
-        prefix = static_cast<PrefixTlv *>(cur);
-        subCur = reinterpret_cast<NetworkDataTlv *>(reinterpret_cast<uint8_t *>(prefix->GetSubTlvs()) +
-                                                    iterator.GetSubTlvOffset());
-        subEnd = cur->GetNext();
-
-        for (; subCur < subEnd; subCur = subCur->GetNext(), iterator.SetEntryIndex(0))
-        {
-            BorderRouterTlv *borderRouter;
-
-            VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
-
-            if (subCur->GetType() != NetworkDataTlv::kTypeBorderRouter)
-            {
-                continue;
-            }
-
-            borderRouter = static_cast<BorderRouterTlv *>(subCur);
-
-            for (uint8_t index = iterator.GetEntryIndex(); index < borderRouter->GetNumEntries(); index++)
-            {
-                if (aRloc16 == Mac::kShortAddrBroadcast || borderRouter->GetEntry(index)->GetRloc() == aRloc16)
-                {
-                    BorderRouterEntry *borderRouterEntry = borderRouter->GetEntry(index);
-
-                    memset(&aConfig, 0, sizeof(aConfig));
-                    memcpy(&aConfig.mPrefix.mPrefix, prefix->GetPrefix(), BitVectorBytes(prefix->GetPrefixLength()));
-                    aConfig.mPrefix.mLength = prefix->GetPrefixLength();
-                    aConfig.mPreference     = borderRouterEntry->GetPreference();
-                    aConfig.mPreferred      = borderRouterEntry->IsPreferred();
-                    aConfig.mSlaac          = borderRouterEntry->IsSlaac();
-                    aConfig.mDhcp           = borderRouterEntry->IsDhcp();
-                    aConfig.mConfigure      = borderRouterEntry->IsConfigure();
-                    aConfig.mDefaultRoute   = borderRouterEntry->IsDefaultRoute();
-                    aConfig.mOnMesh         = borderRouterEntry->IsOnMesh();
-                    aConfig.mStable         = borderRouter->IsStable();
-                    aConfig.mRloc16         = borderRouterEntry->GetRloc();
-
-                    iterator.SaveTlvOffset(cur, mTlvs);
-                    iterator.SaveSubTlvOffset(subCur, prefix->GetSubTlvs());
-                    iterator.SetEntryIndex(index + 1);
-
-                    ExitNow(error = OT_ERROR_NONE);
-                }
-            }
-        }
-    }
-
-exit:
-    return error;
+    return Iterate(aIterator, aRloc16, config);
 }
 
-otError NetworkData::GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig)
+otError NetworkData::GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig) const
 {
     return GetNextExternalRoute(aIterator, Mac::kShortAddrBroadcast, aConfig);
 }
 
-otError NetworkData::GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig)
+otError NetworkData::GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig) const
 {
-    otError             error = OT_ERROR_NOT_FOUND;
-    NetworkDataIterator iterator(aIterator);
-    NetworkDataTlv *    cur = reinterpret_cast<NetworkDataTlv *>(mTlvs + iterator.GetTlvOffset());
-    NetworkDataTlv *    end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
+    Config config;
 
-    for (; cur < end; cur = cur->GetNext(), iterator.SetSubTlvOffset(0), iterator.SetEntryIndex(0))
-    {
-        PrefixTlv *     prefix;
-        NetworkDataTlv *subCur;
-        NetworkDataTlv *subEnd;
+    config.mOnMeshPrefix  = nullptr;
+    config.mExternalRoute = &aConfig;
+    config.mService       = nullptr;
 
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
-
-        if (cur->GetType() != NetworkDataTlv::kTypePrefix)
-        {
-            continue;
-        }
-
-        prefix = static_cast<PrefixTlv *>(cur);
-
-        subCur = reinterpret_cast<NetworkDataTlv *>(reinterpret_cast<uint8_t *>(prefix->GetSubTlvs()) +
-                                                    iterator.GetSubTlvOffset());
-        subEnd = cur->GetNext();
-
-        for (; subCur < subEnd; subCur = subCur->GetNext(), iterator.SetEntryIndex(0))
-        {
-            HasRouteTlv *hasRoute;
-
-            VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
-
-            if (subCur->GetType() != NetworkDataTlv::kTypeHasRoute)
-            {
-                continue;
-            }
-
-            hasRoute = static_cast<HasRouteTlv *>(subCur);
-
-            for (uint8_t index = iterator.GetEntryIndex(); index < hasRoute->GetNumEntries(); index++)
-            {
-                if (aRloc16 == Mac::kShortAddrBroadcast || hasRoute->GetEntry(index)->GetRloc() == aRloc16)
-                {
-                    HasRouteEntry *hasRouteEntry = hasRoute->GetEntry(index);
-
-                    memset(&aConfig, 0, sizeof(aConfig));
-                    memcpy(&aConfig.mPrefix.mPrefix, prefix->GetPrefix(), BitVectorBytes(prefix->GetPrefixLength()));
-                    aConfig.mPrefix.mLength      = prefix->GetPrefixLength();
-                    aConfig.mPreference          = hasRouteEntry->GetPreference();
-                    aConfig.mStable              = hasRoute->IsStable();
-                    aConfig.mRloc16              = hasRouteEntry->GetRloc();
-                    aConfig.mNextHopIsThisDevice = (hasRouteEntry->GetRloc() == Get<Mle::MleRouter>().GetRloc16());
-
-                    iterator.SaveTlvOffset(cur, mTlvs);
-                    iterator.SaveSubTlvOffset(subCur, prefix->GetSubTlvs());
-                    iterator.SetEntryIndex(index + 1);
-
-                    ExitNow(error = OT_ERROR_NONE);
-                }
-            }
-        }
-    }
-
-exit:
-    return error;
+    return Iterate(aIterator, aRloc16, config);
 }
 
-otError NetworkData::GetNextService(Iterator &aIterator, ServiceConfig &aConfig)
+otError NetworkData::GetNextService(Iterator &aIterator, ServiceConfig &aConfig) const
 {
     return GetNextService(aIterator, Mac::kShortAddrBroadcast, aConfig);
 }
 
-otError NetworkData::GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig)
+otError NetworkData::GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const
 {
+    Config config;
+
+    config.mOnMeshPrefix  = nullptr;
+    config.mExternalRoute = nullptr;
+    config.mService       = &aConfig;
+
+    return Iterate(aIterator, aRloc16, config);
+}
+
+otError NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const
+{
+    // Iterate to the next entry in Network Data matching `aRloc16`
+    // (can be set to `Mac::kShortAddrBroadcast` to allow any RLOC).
+    // The `aIterator` is used to track and save the current position.
+    // On input, the non-nullptr pointer members in `aConfig` specify the
+    // Network Data entry types (`mOnMeshPrefix`, `mExternalRoute`,
+    // `mService`) to iterate over. On successful exit, the `aConfig`
+    // is updated such that only one member pointer is not nullptr
+    // indicating the type of entry and the non-nullptr config is updated
+    // with the entry info.
+
     otError             error = OT_ERROR_NOT_FOUND;
     NetworkDataIterator iterator(aIterator);
-    NetworkDataTlv *    cur = reinterpret_cast<NetworkDataTlv *>(mTlvs + iterator.GetTlvOffset());
-    NetworkDataTlv *    end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
 
-    for (; cur < end; cur = cur->GetNext(), iterator.SetSubTlvOffset(0))
+    for (const NetworkDataTlv *cur; (cur = iterator.GetTlv(mTlvs)) < GetTlvsEnd(); iterator.AdvanceTlv(mTlvs))
     {
-        ServiceTlv *    service;
-        NetworkDataTlv *subCur;
-        NetworkDataTlv *subEnd;
+        const NetworkDataTlv *subTlvs = nullptr;
 
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
+        switch (cur->GetType())
+        {
+        case NetworkDataTlv::kTypePrefix:
+            if ((aConfig.mOnMeshPrefix != nullptr) || (aConfig.mExternalRoute != nullptr))
+            {
+                subTlvs = static_cast<const PrefixTlv *>(cur)->GetSubTlvs();
+            }
+            break;
+        case NetworkDataTlv::kTypeService:
+            if (aConfig.mService != nullptr)
+            {
+                subTlvs = static_cast<const ServiceTlv *>(cur)->GetSubTlvs();
+            }
+            break;
+        default:
+            break;
+        }
 
-        if (cur->GetType() != NetworkDataTlv::kTypeService)
+        if (subTlvs == nullptr)
         {
             continue;
         }
 
-        service = static_cast<ServiceTlv *>(cur);
-
-        subCur = reinterpret_cast<NetworkDataTlv *>(reinterpret_cast<uint8_t *>(service->GetSubTlvs()) +
-                                                    iterator.GetSubTlvOffset());
-        subEnd = cur->GetNext();
-
-        for (; subCur < subEnd; subCur = subCur->GetNext())
+        for (const NetworkDataTlv *subCur; (subCur = iterator.GetSubTlv(subTlvs)) < cur->GetNext();
+             iterator.AdvaceSubTlv(subTlvs))
         {
-            ServerTlv *server;
-
-            VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
-
-            if (subCur->GetType() != NetworkDataTlv::kTypeServer)
+            if (cur->GetType() == NetworkDataTlv::kTypePrefix)
             {
-                continue;
+                const PrefixTlv *prefix = static_cast<const PrefixTlv *>(cur);
+
+                switch (subCur->GetType())
+                {
+                case NetworkDataTlv::kTypeBorderRouter:
+                {
+                    const BorderRouterTlv *borderRouter = static_cast<const BorderRouterTlv *>(subCur);
+
+                    if (aConfig.mOnMeshPrefix == nullptr)
+                    {
+                        continue;
+                    }
+
+                    for (uint8_t index; (index = iterator.GetAndAdvanceIndex()) < borderRouter->GetNumEntries();)
+                    {
+                        if (aRloc16 == Mac::kShortAddrBroadcast || borderRouter->GetEntry(index)->GetRloc() == aRloc16)
+                        {
+                            const BorderRouterEntry *borderRouterEntry = borderRouter->GetEntry(index);
+
+                            aConfig.mExternalRoute = nullptr;
+                            aConfig.mService       = nullptr;
+                            memset(aConfig.mOnMeshPrefix, 0, sizeof(OnMeshPrefixConfig));
+
+                            memcpy(&aConfig.mOnMeshPrefix->mPrefix.mPrefix, prefix->GetPrefix(),
+                                   BitVectorBytes(prefix->GetPrefixLength()));
+                            aConfig.mOnMeshPrefix->mPrefix.mLength = prefix->GetPrefixLength();
+                            aConfig.mOnMeshPrefix->mPreference     = borderRouterEntry->GetPreference();
+                            aConfig.mOnMeshPrefix->mPreferred      = borderRouterEntry->IsPreferred();
+                            aConfig.mOnMeshPrefix->mSlaac          = borderRouterEntry->IsSlaac();
+                            aConfig.mOnMeshPrefix->mDhcp           = borderRouterEntry->IsDhcp();
+                            aConfig.mOnMeshPrefix->mConfigure      = borderRouterEntry->IsConfigure();
+                            aConfig.mOnMeshPrefix->mDefaultRoute   = borderRouterEntry->IsDefaultRoute();
+                            aConfig.mOnMeshPrefix->mOnMesh         = borderRouterEntry->IsOnMesh();
+                            aConfig.mOnMeshPrefix->mStable         = borderRouter->IsStable();
+                            aConfig.mOnMeshPrefix->mRloc16         = borderRouterEntry->GetRloc();
+                            aConfig.mOnMeshPrefix->mNdDns          = borderRouterEntry->IsNdDns();
+                            aConfig.mOnMeshPrefix->mDp             = borderRouterEntry->IsDp();
+
+                            ExitNow(error = OT_ERROR_NONE);
+                        }
+                    }
+
+                    break;
+                }
+
+                case NetworkDataTlv::kTypeHasRoute:
+                {
+                    const HasRouteTlv *hasRoute = static_cast<const HasRouteTlv *>(subCur);
+
+                    if (aConfig.mExternalRoute == nullptr)
+                    {
+                        continue;
+                    }
+
+                    for (uint8_t index; (index = iterator.GetAndAdvanceIndex()) < hasRoute->GetNumEntries();)
+                    {
+                        if (aRloc16 == Mac::kShortAddrBroadcast || hasRoute->GetEntry(index)->GetRloc() == aRloc16)
+                        {
+                            const HasRouteEntry *hasRouteEntry = hasRoute->GetEntry(index);
+
+                            aConfig.mOnMeshPrefix = nullptr;
+                            aConfig.mService      = nullptr;
+                            memset(aConfig.mExternalRoute, 0, sizeof(ExternalRouteConfig));
+
+                            memcpy(&aConfig.mExternalRoute->mPrefix.mPrefix, prefix->GetPrefix(),
+                                   BitVectorBytes(prefix->GetPrefixLength()));
+                            aConfig.mExternalRoute->mPrefix.mLength = prefix->GetPrefixLength();
+                            aConfig.mExternalRoute->mPreference     = hasRouteEntry->GetPreference();
+                            aConfig.mExternalRoute->mStable         = hasRoute->IsStable();
+                            aConfig.mExternalRoute->mRloc16         = hasRouteEntry->GetRloc();
+                            aConfig.mExternalRoute->mNextHopIsThisDevice =
+                                (hasRouteEntry->GetRloc() == Get<Mle::MleRouter>().GetRloc16());
+
+                            ExitNow(error = OT_ERROR_NONE);
+                        }
+                    }
+
+                    break;
+                }
+
+                default:
+                    break;
+                }
             }
-
-            server = static_cast<ServerTlv *>(subCur);
-
-            if ((aRloc16 == Mac::kShortAddrBroadcast) || (server->GetServer16() == aRloc16))
+            else // cur is `ServiceTLv`
             {
-                memset(&aConfig, 0, sizeof(aConfig));
+                const ServiceTlv *service = static_cast<const ServiceTlv *>(cur);
 
-                aConfig.mServiceID         = service->GetServiceID();
-                aConfig.mEnterpriseNumber  = service->GetEnterpriseNumber();
-                aConfig.mServiceDataLength = service->GetServiceDataLength();
-
-                memcpy(&aConfig.mServiceData, service->GetServiceData(), service->GetServiceDataLength());
-
-                aConfig.mServerConfig.mStable           = server->IsStable();
-                aConfig.mServerConfig.mServerDataLength = server->GetServerDataLength();
-                memcpy(&aConfig.mServerConfig.mServerData, server->GetServerData(), server->GetServerDataLength());
-                aConfig.mServerConfig.mRloc16 = server->GetServer16();
-
-                if (subCur->GetNext() >= cur->GetNext())
+                if (subCur->GetType() == NetworkDataTlv::kTypeServer)
                 {
-                    iterator.SaveTlvOffset(cur->GetNext(), mTlvs);
-                    iterator.SetSubTlvOffset(0);
-                }
-                else
-                {
-                    iterator.SaveTlvOffset(cur, mTlvs);
-                    iterator.SaveSubTlvOffset(subCur->GetNext(), service->GetSubTlvs());
-                }
+                    const ServerTlv *server = static_cast<const ServerTlv *>(subCur);
 
-                ExitNow(error = OT_ERROR_NONE);
+                    if (!iterator.IsNewEntry())
+                    {
+                        continue;
+                    }
+
+                    if ((aRloc16 == Mac::kShortAddrBroadcast) || (server->GetServer16() == aRloc16))
+                    {
+                        aConfig.mOnMeshPrefix  = nullptr;
+                        aConfig.mExternalRoute = nullptr;
+                        memset(aConfig.mService, 0, sizeof(ServiceConfig));
+
+                        aConfig.mService->mServiceId         = service->GetServiceId();
+                        aConfig.mService->mEnterpriseNumber  = service->GetEnterpriseNumber();
+                        aConfig.mService->mServiceDataLength = service->GetServiceDataLength();
+
+                        memcpy(&aConfig.mService->mServiceData, service->GetServiceData(),
+                               service->GetServiceDataLength());
+
+                        aConfig.mService->mServerConfig.mStable           = server->IsStable();
+                        aConfig.mService->mServerConfig.mServerDataLength = server->GetServerDataLength();
+                        memcpy(&aConfig.mService->mServerConfig.mServerData, server->GetServerData(),
+                               server->GetServerDataLength());
+                        aConfig.mService->mServerConfig.mRloc16 = server->GetServer16();
+
+                        iterator.MarkEntryAsNotNew();
+
+                        ExitNow(error = OT_ERROR_NONE);
+                    }
+                }
             }
         }
     }
@@ -307,70 +347,19 @@
     return error;
 }
 
-otError NetworkData::GetNextServiceId(Iterator &aIterator, uint16_t aRloc16, uint8_t &aServiceId)
+otError NetworkData::GetNextServiceId(Iterator &aIterator, uint16_t aRloc16, uint8_t &aServiceId) const
 {
-    otError             error = OT_ERROR_NOT_FOUND;
-    NetworkDataIterator iterator(aIterator);
-    NetworkDataTlv *    cur = reinterpret_cast<NetworkDataTlv *>(mTlvs + iterator.GetTlvOffset());
-    NetworkDataTlv *    end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
+    otError       error;
+    ServiceConfig config;
 
-    for (; cur < end; cur = cur->GetNext(), iterator.SetSubTlvOffset(0))
-    {
-        ServiceTlv *    service;
-        NetworkDataTlv *subCur;
-        NetworkDataTlv *subEnd;
-
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
-
-        if (cur->GetType() != NetworkDataTlv::kTypeService)
-        {
-            continue;
-        }
-
-        service = static_cast<ServiceTlv *>(cur);
-
-        subCur = reinterpret_cast<NetworkDataTlv *>(reinterpret_cast<uint8_t *>(service->GetSubTlvs()) +
-                                                    iterator.GetSubTlvOffset());
-        subEnd = cur->GetNext();
-
-        for (; subCur < subEnd; subCur = subCur->GetNext())
-        {
-            ServerTlv *server;
-
-            VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
-
-            if (subCur->GetType() != NetworkDataTlv::kTypeServer)
-            {
-                continue;
-            }
-
-            server = static_cast<ServerTlv *>(subCur);
-
-            if ((aRloc16 == Mac::kShortAddrBroadcast) || (server->GetServer16() == aRloc16))
-            {
-                aServiceId = service->GetServiceID();
-
-                if (subCur->GetNext() >= cur->GetNext())
-                {
-                    iterator.SaveTlvOffset(cur->GetNext(), mTlvs);
-                    iterator.SetSubTlvOffset(0);
-                }
-                else
-                {
-                    iterator.SaveTlvOffset(cur, mTlvs);
-                    iterator.SaveSubTlvOffset(subCur->GetNext(), service->GetSubTlvs());
-                }
-
-                ExitNow(error = OT_ERROR_NONE);
-            }
-        }
-    }
+    SuccessOrExit(error = GetNextService(aIterator, aRloc16, config));
+    aServiceId = config.mServiceId;
 
 exit:
     return error;
 }
 
-bool NetworkData::ContainsOnMeshPrefixes(NetworkData &aCompare, uint16_t aRloc16)
+bool NetworkData::ContainsOnMeshPrefixes(const NetworkData &aCompare, uint16_t aRloc16) const
 {
     Iterator           outerIterator = kIteratorInit;
     OnMeshPrefixConfig outerConfig;
@@ -400,7 +389,7 @@
     return rval;
 }
 
-bool NetworkData::ContainsExternalRoutes(NetworkData &aCompare, uint16_t aRloc16)
+bool NetworkData::ContainsExternalRoutes(const NetworkData &aCompare, uint16_t aRloc16) const
 {
     Iterator            outerIterator = kIteratorInit;
     ExternalRouteConfig outerConfig;
@@ -430,7 +419,7 @@
     return rval;
 }
 
-bool NetworkData::ContainsServices(NetworkData &aCompare, uint16_t aRloc16)
+bool NetworkData::ContainsServices(const NetworkData &aCompare, uint16_t aRloc16) const
 {
     Iterator      outerIterator = kIteratorInit;
     ServiceConfig outerConfig;
@@ -466,50 +455,17 @@
     return rval;
 }
 
-bool NetworkData::ContainsService(uint8_t aServiceId, uint16_t aRloc16)
+bool NetworkData::ContainsService(uint8_t aServiceId, uint16_t aRloc16) const
 {
-    bool            rval = false;
-    NetworkDataTlv *cur  = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-    NetworkDataTlv *end  = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
+    Iterator iterator = kIteratorInit;
+    uint8_t  serviceId;
+    bool     rval = false;
 
-    for (; cur < end; cur = cur->GetNext())
+    while (GetNextServiceId(iterator, aRloc16, serviceId) == OT_ERROR_NONE)
     {
-        ServiceTlv *    service;
-        NetworkDataTlv *subCur;
-        NetworkDataTlv *subEnd;
-
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
-
-        if (cur->GetType() != NetworkDataTlv::kTypeService)
+        if (serviceId == aServiceId)
         {
-            continue;
-        }
-
-        service = static_cast<ServiceTlv *>(cur);
-
-        if (service->GetServiceID() == aServiceId)
-        {
-            subCur = service->GetSubTlvs();
-            subEnd = cur->GetNext();
-
-            for (; subCur < subEnd; subCur = subCur->GetNext())
-            {
-                ServerTlv *server;
-
-                VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd);
-
-                if (subCur->GetType() != NetworkDataTlv::kTypeServer)
-                {
-                    continue;
-                }
-
-                server = static_cast<ServerTlv *>(subCur);
-
-                if (server->GetServer16() == aRloc16)
-                {
-                    ExitNow(rval = true);
-                }
-            }
+            ExitNow(rval = true);
         }
     }
 
@@ -520,78 +476,52 @@
 void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength)
 {
     NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aData);
-    NetworkDataTlv *end;
-    PrefixTlv *     prefix;
-    ServiceTlv *    service;
-    uint8_t         length;
-    uint8_t *       dst;
-    uint8_t *       src;
 
-    while (1)
+    while (cur < reinterpret_cast<NetworkDataTlv *>(aData + aDataLength))
     {
-        end = reinterpret_cast<NetworkDataTlv *>(aData + aDataLength);
-
-        if (cur >= end)
-        {
-            break;
-        }
-
         switch (cur->GetType())
         {
         case NetworkDataTlv::kTypePrefix:
         {
-            prefix = static_cast<PrefixTlv *>(cur);
+            PrefixTlv *prefix = static_cast<PrefixTlv *>(cur);
+
             RemoveTemporaryData(aData, aDataLength, *prefix);
 
             if (prefix->GetSubTlvsLength() == 0)
             {
-                length = sizeof(NetworkDataTlv) + cur->GetLength();
-                dst    = reinterpret_cast<uint8_t *>(cur);
-                src    = reinterpret_cast<uint8_t *>(cur->GetNext());
-                memmove(dst, src, aDataLength - static_cast<size_t>(src - aData));
-                aDataLength -= length;
+                RemoveTlv(aData, aDataLength, cur);
                 continue;
             }
 
-            otDumpDebgNetData("remove prefix done", mTlvs, mLength);
+            otDumpDebgNetData("remove prefix done", aData, aDataLength);
             break;
         }
 
         case NetworkDataTlv::kTypeService:
         {
-            service = static_cast<ServiceTlv *>(cur);
+            ServiceTlv *service = static_cast<ServiceTlv *>(cur);
             RemoveTemporaryData(aData, aDataLength, *service);
 
             if (service->GetSubTlvsLength() == 0)
             {
-                length = sizeof(NetworkDataTlv) + cur->GetLength();
-                dst    = reinterpret_cast<uint8_t *>(cur);
-                src    = reinterpret_cast<uint8_t *>(cur->GetNext());
-                memmove(dst, src, aDataLength - static_cast<size_t>(src - aData));
-                aDataLength -= length;
+                RemoveTlv(aData, aDataLength, cur);
                 continue;
             }
 
-            otDumpDebgNetData("remove service done", mTlvs, mLength);
+            otDumpDebgNetData("remove service done", aData, aDataLength);
             break;
         }
 
         default:
-        {
             // remove temporary tlv
             if (!cur->IsStable())
             {
-                length = sizeof(NetworkDataTlv) + cur->GetLength();
-                dst    = reinterpret_cast<uint8_t *>(cur);
-                src    = reinterpret_cast<uint8_t *>(cur->GetNext());
-                memmove(dst, src, aDataLength - static_cast<size_t>(src - aData));
-                aDataLength -= length;
+                RemoveTlv(aData, aDataLength, cur);
                 continue;
             }
 
             break;
         }
-        }
 
         cur = cur->GetNext();
     }
@@ -601,54 +531,30 @@
 
 void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix)
 {
-    NetworkDataTlv *   cur = aPrefix.GetSubTlvs();
-    NetworkDataTlv *   end;
-    BorderRouterTlv *  borderRouter;
-    HasRouteTlv *      hasRoute;
-    ContextTlv *       context;
-    BorderRouterEntry *borderRouterEntry;
-    HasRouteEntry *    hasRouteEntry;
-    uint8_t            length;
-    uint8_t            contextId;
-    uint8_t *          dst;
-    uint8_t *          src;
+    NetworkDataTlv *cur = aPrefix.GetSubTlvs();
 
-    while (1)
+    while (cur < aPrefix.GetNext())
     {
-        end = aPrefix.GetNext();
-
-        if (cur >= end)
-        {
-            break;
-        }
-
         if (cur->IsStable())
         {
             switch (cur->GetType())
             {
             case NetworkDataTlv::kTypeBorderRouter:
             {
-                borderRouter = FindBorderRouter(aPrefix);
+                BorderRouterTlv *borderRouter = static_cast<BorderRouterTlv *>(cur);
+                ContextTlv *     context      = FindContext(aPrefix);
 
-                if ((context = FindContext(aPrefix)) == NULL)
+                // Replace p_border_router_16
+                for (BorderRouterEntry *entry = borderRouter->GetFirstEntry(); entry <= borderRouter->GetLastEntry();
+                     entry                    = entry->GetNext())
                 {
-                    break;
-                }
-
-                contextId = context->GetContextId();
-
-                // replace p_border_router_16
-                for (uint8_t i = 0; i < borderRouter->GetNumEntries(); i++)
-                {
-                    borderRouterEntry = borderRouter->GetEntry(i);
-
-                    if (borderRouterEntry->IsDhcp() || borderRouterEntry->IsConfigure())
+                    if ((entry->IsDhcp() || entry->IsConfigure()) && (context != nullptr))
                     {
-                        borderRouterEntry->SetRloc(0xfc00 | contextId);
+                        entry->SetRloc(0xfc00 | context->GetContextId());
                     }
                     else
                     {
-                        borderRouterEntry->SetRloc(0xfffe);
+                        entry->SetRloc(0xfffe);
                     }
                 }
 
@@ -657,23 +563,21 @@
 
             case NetworkDataTlv::kTypeHasRoute:
             {
-                hasRoute = FindHasRoute(aPrefix);
+                HasRouteTlv *hasRoute = static_cast<HasRouteTlv *>(cur);
 
-                // replace r_border_router_16
-                for (uint8_t j = 0; j < hasRoute->GetNumEntries(); j++)
+                // Replace r_border_router_16
+                for (HasRouteEntry *entry = hasRoute->GetFirstEntry(); entry <= hasRoute->GetLastEntry();
+                     entry                = entry->GetNext())
                 {
-                    hasRouteEntry = hasRoute->GetEntry(j);
-                    hasRouteEntry->SetRloc(0xfffe);
+                    entry->SetRloc(0xfffe);
                 }
 
                 break;
             }
 
             default:
-            {
                 break;
             }
-            }
 
             // keep stable tlv
             cur = cur->GetNext();
@@ -681,12 +585,9 @@
         else
         {
             // remove temporary tlv
-            length = sizeof(NetworkDataTlv) + cur->GetLength();
-            dst    = reinterpret_cast<uint8_t *>(cur);
-            src    = reinterpret_cast<uint8_t *>(cur->GetNext());
-            memmove(dst, src, aDataLength - static_cast<size_t>(src - aData));
-            aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - length);
-            aDataLength -= length;
+            uint8_t subTlvSize = cur->GetSize();
+            RemoveTlv(aData, aDataLength, cur);
+            aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - subTlvSize);
         }
     }
 }
@@ -694,37 +595,23 @@
 void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, ServiceTlv &aService)
 {
     NetworkDataTlv *cur = aService.GetSubTlvs();
-    NetworkDataTlv *end;
-    ServerTlv *     server;
-    uint8_t         length;
-    uint8_t *       dst;
-    uint8_t *       src;
 
-    while (1)
+    while (cur < aService.GetNext())
     {
-        end = aService.GetNext();
-
-        if (cur >= end)
-        {
-            break;
-        }
-
         if (cur->IsStable())
         {
             switch (cur->GetType())
             {
             case NetworkDataTlv::kTypeServer:
             {
-                server = static_cast<ServerTlv *>(cur);
-                server->SetServer16(Mle::Mle::ServiceAlocFromId(aService.GetServiceID()));
+                ServerTlv *server = static_cast<ServerTlv *>(cur);
+                server->SetServer16(Mle::Mle::ServiceAlocFromId(aService.GetServiceId()));
                 break;
             }
 
             default:
-            {
                 break;
             }
-            }
 
             // keep stable tlv
             cur = cur->GetNext();
@@ -732,256 +619,179 @@
         else
         {
             // remove temporary tlv
-            length = sizeof(NetworkDataTlv) + cur->GetLength();
-            dst    = reinterpret_cast<uint8_t *>(cur);
-            src    = reinterpret_cast<uint8_t *>(cur->GetNext());
-            memmove(dst, src, aDataLength - static_cast<size_t>(src - aData));
-            aService.SetSubTlvsLength(aService.GetSubTlvsLength() - length);
-            aDataLength -= length;
+            uint8_t subTlvSize = cur->GetSize();
+            RemoveTlv(aData, aDataLength, cur);
+            aService.SetSubTlvsLength(aService.GetSubTlvsLength() - subTlvSize);
         }
     }
 }
 
-BorderRouterTlv *NetworkData::FindBorderRouter(PrefixTlv &aPrefix)
+const BorderRouterTlv *NetworkData::FindBorderRouter(const PrefixTlv &aPrefix)
 {
-    BorderRouterTlv *rval = NULL;
-    NetworkDataTlv * cur  = aPrefix.GetSubTlvs();
-    NetworkDataTlv * end  = aPrefix.GetNext();
-
-    while (cur < end)
-    {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
-
-        if (cur->GetType() == NetworkDataTlv::kTypeBorderRouter)
-        {
-            ExitNow(rval = static_cast<BorderRouterTlv *>(cur));
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return rval;
+    return FindTlv<BorderRouterTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext());
 }
 
-BorderRouterTlv *NetworkData::FindBorderRouter(PrefixTlv &aPrefix, bool aStable)
+const BorderRouterTlv *NetworkData::FindBorderRouter(const PrefixTlv &aPrefix, bool aStable)
 {
-    BorderRouterTlv *rval = NULL;
-    NetworkDataTlv * cur  = aPrefix.GetSubTlvs();
-    NetworkDataTlv * end  = aPrefix.GetNext();
-
-    while (cur < end)
-    {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
-
-        if (cur->GetType() == NetworkDataTlv::kTypeBorderRouter && cur->IsStable() == aStable)
-        {
-            ExitNow(rval = static_cast<BorderRouterTlv *>(cur));
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return rval;
+    return FindTlv<BorderRouterTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext(), aStable);
 }
 
-HasRouteTlv *NetworkData::FindHasRoute(PrefixTlv &aPrefix)
+const HasRouteTlv *NetworkData::FindHasRoute(const PrefixTlv &aPrefix)
 {
-    HasRouteTlv *   rval = NULL;
-    NetworkDataTlv *cur  = aPrefix.GetSubTlvs();
-    NetworkDataTlv *end  = aPrefix.GetNext();
-
-    while (cur < end)
-    {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
-
-        if (cur->GetType() == NetworkDataTlv::kTypeHasRoute)
-        {
-            ExitNow(rval = static_cast<HasRouteTlv *>(cur));
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return rval;
+    return FindTlv<HasRouteTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext());
 }
 
-HasRouteTlv *NetworkData::FindHasRoute(PrefixTlv &aPrefix, bool aStable)
+const HasRouteTlv *NetworkData::FindHasRoute(const PrefixTlv &aPrefix, bool aStable)
 {
-    HasRouteTlv *   rval = NULL;
-    NetworkDataTlv *cur  = aPrefix.GetSubTlvs();
-    NetworkDataTlv *end  = aPrefix.GetNext();
-
-    while (cur < end)
-    {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
-
-        if (cur->GetType() == NetworkDataTlv::kTypeHasRoute && cur->IsStable() == aStable)
-        {
-            ExitNow(rval = static_cast<HasRouteTlv *>(cur));
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return rval;
+    return FindTlv<HasRouteTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext(), aStable);
 }
 
-ContextTlv *NetworkData::FindContext(PrefixTlv &aPrefix)
+const ContextTlv *NetworkData::FindContext(const PrefixTlv &aPrefix)
 {
-    ContextTlv *    rval = NULL;
-    NetworkDataTlv *cur  = aPrefix.GetSubTlvs();
-    NetworkDataTlv *end  = aPrefix.GetNext();
-
-    while (cur < end)
-    {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
-
-        if (cur->GetType() == NetworkDataTlv::kTypeContext)
-        {
-            ExitNow(rval = static_cast<ContextTlv *>(cur));
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return rval;
+    return FindTlv<ContextTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext());
 }
 
-PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
+const PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const
 {
     return FindPrefix(aPrefix, aPrefixLength, mTlvs, mLength);
 }
 
-PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, uint8_t *aTlvs, uint8_t aTlvsLength)
+const PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix,
+                                         uint8_t        aPrefixLength,
+                                         const uint8_t *aTlvs,
+                                         uint8_t        aTlvsLength)
 {
-    NetworkDataTlv *cur     = reinterpret_cast<NetworkDataTlv *>(aTlvs);
-    NetworkDataTlv *end     = reinterpret_cast<NetworkDataTlv *>(aTlvs + aTlvsLength);
-    PrefixTlv *     compare = NULL;
+    const NetworkDataTlv *start = reinterpret_cast<const NetworkDataTlv *>(aTlvs);
+    const NetworkDataTlv *end   = reinterpret_cast<const NetworkDataTlv *>(aTlvs + aTlvsLength);
+    const PrefixTlv *     prefixTlv;
 
-    while (cur < end)
+    while (start < end)
     {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
+        prefixTlv = FindTlv<PrefixTlv>(start, end);
 
-        if (cur->GetType() == NetworkDataTlv::kTypePrefix)
+        VerifyOrExit(prefixTlv != nullptr, OT_NOOP);
+
+        if (prefixTlv->GetPrefixLength() == aPrefixLength &&
+            PrefixMatch(prefixTlv->GetPrefix(), aPrefix, aPrefixLength) >= aPrefixLength)
         {
-            compare = static_cast<PrefixTlv *>(cur);
-
-            if (compare->GetPrefixLength() == aPrefixLength &&
-                PrefixMatch(compare->GetPrefix(), aPrefix, aPrefixLength) >= aPrefixLength)
-            {
-                ExitNow();
-            }
+            ExitNow();
         }
 
-        cur = cur->GetNext();
+        start = prefixTlv->GetNext();
     }
 
-    compare = NULL;
+    prefixTlv = nullptr;
 
 exit:
-    return compare;
+    return prefixTlv;
 }
 
 int8_t NetworkData::PrefixMatch(const uint8_t *a, const uint8_t *b, uint8_t aLength)
 {
-    int8_t  rval  = 0;
-    uint8_t bytes = BitVectorBytes(aLength);
-    uint8_t diff;
+    uint8_t matchedLength;
 
-    for (uint8_t i = 0; i < bytes; i++)
-    {
-        diff = a[i] ^ b[i];
+    // Note that he `Ip6::Address::PrefixMatch` expects the prefix
+    // length to be in bytes unit.
 
-        if (diff == 0)
-        {
-            rval += 8;
-        }
-        else
-        {
-            while ((diff & 0x80) == 0)
-            {
-                rval++;
-                diff <<= 1;
-            }
+    matchedLength = Ip6::Address::PrefixMatch(a, b, BitVectorBytes(aLength));
 
-            break;
-        }
-    }
-
-    return (rval >= aLength) ? rval : -1;
+    return (matchedLength >= aLength) ? static_cast<int8_t>(matchedLength) : -1;
 }
 
-ServiceTlv *NetworkData::FindService(uint32_t       aEnterpriseNumber,
-                                     const uint8_t *aServiceData,
-                                     uint8_t        aServiceDataLength)
+const ServiceTlv *NetworkData::FindService(uint32_t       aEnterpriseNumber,
+                                           const uint8_t *aServiceData,
+                                           uint8_t        aServiceDataLength) const
 {
     return FindService(aEnterpriseNumber, aServiceData, aServiceDataLength, mTlvs, mLength);
 }
 
-ServiceTlv *NetworkData::FindService(uint32_t       aEnterpriseNumber,
-                                     const uint8_t *aServiceData,
-                                     uint8_t        aServiceDataLength,
-                                     uint8_t *      aTlvs,
-                                     uint8_t        aTlvsLength)
+const ServiceTlv *NetworkData::FindService(uint32_t       aEnterpriseNumber,
+                                           const uint8_t *aServiceData,
+                                           uint8_t        aServiceDataLength,
+                                           const uint8_t *aTlvs,
+                                           uint8_t        aTlvsLength)
 {
-    NetworkDataTlv *cur     = reinterpret_cast<NetworkDataTlv *>(aTlvs);
-    NetworkDataTlv *end     = reinterpret_cast<NetworkDataTlv *>(aTlvs + aTlvsLength);
-    ServiceTlv *    compare = NULL;
+    const NetworkDataTlv *start = reinterpret_cast<const NetworkDataTlv *>(aTlvs);
+    const NetworkDataTlv *end   = reinterpret_cast<const NetworkDataTlv *>(aTlvs + aTlvsLength);
+    const ServiceTlv *    serviceTlv;
 
-    while (cur < end)
+    while (start < end)
     {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
+        serviceTlv = FindTlv<ServiceTlv>(start, end);
 
-        if (cur->GetType() == NetworkDataTlv::kTypeService)
+        VerifyOrExit(serviceTlv != nullptr, OT_NOOP);
+
+        if ((serviceTlv->GetEnterpriseNumber() == aEnterpriseNumber) &&
+            (serviceTlv->GetServiceDataLength() == aServiceDataLength) &&
+            (memcmp(serviceTlv->GetServiceData(), aServiceData, aServiceDataLength) == 0))
         {
-            compare = static_cast<ServiceTlv *>(cur);
-
-            if ((compare->GetEnterpriseNumber() == aEnterpriseNumber) &&
-                (compare->GetServiceDataLength() == aServiceDataLength) &&
-                (memcmp(compare->GetServiceData(), aServiceData, aServiceDataLength) == 0))
-            {
-                ExitNow();
-            }
+            ExitNow();
         }
 
-        cur = cur->GetNext();
+        start = serviceTlv->GetNext();
     }
 
-    compare = NULL;
+    serviceTlv = nullptr;
 
 exit:
-    return compare;
+    return serviceTlv;
 }
 
-void NetworkData::Insert(uint8_t *aStart, uint8_t aLength)
+NetworkDataTlv *NetworkData::AppendTlv(uint16_t aTlvSize)
 {
-    assert(aLength + mLength <= sizeof(mTlvs) && mTlvs <= aStart && aStart <= mTlvs + mLength);
-    memmove(aStart + aLength, aStart, mLength - static_cast<size_t>(aStart - mTlvs));
+    NetworkDataTlv *tlv;
+
+    VerifyOrExit(CanInsert(aTlvSize), tlv = nullptr);
+
+    tlv = GetTlvsEnd();
+    mLength += static_cast<uint8_t>(aTlvSize);
+
+exit:
+    return tlv;
+}
+
+void NetworkData::Insert(void *aStart, uint8_t aLength)
+{
+    uint8_t *start = reinterpret_cast<uint8_t *>(aStart);
+
+    OT_ASSERT(CanInsert(aLength) && mTlvs <= start && start <= mTlvs + mLength);
+    memmove(start + aLength, start, mLength - static_cast<size_t>(start - mTlvs));
     mLength += aLength;
 }
 
-void NetworkData::Remove(uint8_t *aStart, uint8_t aLength)
+void NetworkData::Remove(uint8_t *aData, uint8_t &aDataLength, uint8_t *aRemoveStart, uint8_t aRemoveLength)
 {
-    assert(aLength <= mLength && mTlvs <= aStart && (aStart - mTlvs) + aLength <= mLength);
-    memmove(aStart, aStart + aLength, mLength - (static_cast<size_t>(aStart - mTlvs) + aLength));
-    mLength -= aLength;
+    uint8_t *dataEnd   = aData + aDataLength;
+    uint8_t *removeEnd = aRemoveStart + aRemoveLength;
+
+    OT_ASSERT((aRemoveLength <= aDataLength) && (aData <= aRemoveStart) && (removeEnd <= dataEnd));
+
+    memmove(aRemoveStart, removeEnd, static_cast<uint8_t>(dataEnd - removeEnd));
+    aDataLength -= aRemoveLength;
 }
 
-otError NetworkData::SendServerDataNotification(uint16_t aRloc16)
+void NetworkData::RemoveTlv(uint8_t *aData, uint8_t &aDataLength, NetworkDataTlv *aTlv)
+{
+    Remove(aData, aDataLength, reinterpret_cast<uint8_t *>(aTlv), aTlv->GetSize());
+}
+
+void NetworkData::Remove(void *aRemoveStart, uint8_t aRemoveLength)
+{
+    NetworkData::Remove(mTlvs, mLength, reinterpret_cast<uint8_t *>(aRemoveStart), aRemoveLength);
+}
+
+void NetworkData::RemoveTlv(NetworkDataTlv *aTlv)
+{
+    NetworkData::RemoveTlv(mTlvs, mLength, aTlv);
+}
+
+otError NetworkData::SendServerDataNotification(uint16_t aRloc16, Coap::ResponseHandler aHandler, void *aContext)
 {
     otError          error   = OT_ERROR_NONE;
-    Coap::Message *  message = NULL;
+    Coap::Message *  message = nullptr;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit(!mLastAttemptWait || (TimerMilli::GetNow() - mLastAttempt < kDataResubmitDelay),
-                 error = OT_ERROR_ALREADY);
-
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_SERVER_DATA));
     SuccessOrExit(error = message->SetPayloadMarker());
@@ -997,28 +807,19 @@
 
     if (aRloc16 != Mac::kShortAddrInvalid)
     {
-        ThreadRloc16Tlv rloc16Tlv;
-        rloc16Tlv.Init();
-        rloc16Tlv.SetRloc16(aRloc16);
-        SuccessOrExit(error = rloc16Tlv.AppendTo(*message));
+        SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, ThreadTlv::kRloc16, aRloc16));
     }
 
-    Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr());
+    IgnoreError(Get<Mle::MleRouter>().GetLeaderAloc(messageInfo.GetPeerAddr()));
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetPeerPort(kCoapUdpPort);
-    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
-
-    if (mType == kTypeLocal)
-    {
-        mLastAttempt     = TimerMilli::GetNow();
-        mLastAttemptWait = true;
-    }
+    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo, aHandler, aContext));
 
     otLogInfoNetData("Sent server data notification");
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -1026,9 +827,39 @@
     return error;
 }
 
-void NetworkData::ClearResubmitDelayTimer(void)
+otError NetworkData::GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const
 {
-    mLastAttemptWait = false;
+    otError             error;
+    OnMeshPrefixConfig  prefixConfig;
+    ExternalRouteConfig routeConfig;
+    ServiceConfig       serviceConfig;
+    Config              config;
+
+    config.mOnMeshPrefix  = &prefixConfig;
+    config.mExternalRoute = &routeConfig;
+    config.mService       = &serviceConfig;
+
+    SuccessOrExit(error = Iterate(aIterator, Mac::kShortAddrBroadcast, config));
+
+    if (config.mOnMeshPrefix != nullptr)
+    {
+        aRloc16 = config.mOnMeshPrefix->mRloc16;
+    }
+    else if (config.mExternalRoute != nullptr)
+    {
+        aRloc16 = config.mExternalRoute->mRloc16;
+    }
+    else if (config.mService != nullptr)
+    {
+        aRloc16 = config.mService->mServerConfig.mRloc16;
+    }
+    else
+    {
+        OT_ASSERT(false);
+    }
+
+exit:
+    return error;
 }
 
 } // namespace NetworkData
diff --git a/src/core/thread/network_data.hpp b/src/core/thread/network_data.hpp
index f49fe5d..179c23b 100644
--- a/src/core/thread/network_data.hpp
+++ b/src/core/thread/network_data.hpp
@@ -162,7 +162,7 @@
      * @retval OT_ERROR_NO_BUFS    Not enough space to fully copy Thread Network Data.
      *
      */
-    otError GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength);
+    otError GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const;
 
     /**
      * This method provides the next On Mesh prefix in the Thread Network Data.
@@ -174,7 +174,7 @@
      * @retval OT_ERROR_NOT_FOUND  No subsequent On Mesh prefix exists in the Thread Network Data.
      *
      */
-    otError GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig &aConfig);
+    otError GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig &aConfig) const;
 
     /**
      * This method provides the next On Mesh prefix in the Thread Network Data for a given RLOC16.
@@ -187,7 +187,7 @@
      * @retval OT_ERROR_NOT_FOUND  No subsequent On Mesh prefix exists in the Thread Network Data.
      *
      */
-    otError GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig);
+    otError GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig) const;
 
     /**
      * This method provides the next external route in the Thread Network Data.
@@ -199,7 +199,7 @@
      * @retval OT_ERROR_NOT_FOUND  No subsequent external route exists in the Thread Network Data.
      *
      */
-    otError GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig);
+    otError GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig) const;
 
     /**
      * This method provides the next external route in the Thread Network Data for a given RLOC16.
@@ -212,7 +212,7 @@
      * @retval OT_ERROR_NOT_FOUND  No subsequent external route exists in the Thread Network Data.
      *
      */
-    otError GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig);
+    otError GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig) const;
 
     /**
      * This method provides the next service in the Thread Network Data.
@@ -224,7 +224,7 @@
      * @retval OT_ERROR_NOT_FOUND  No subsequent service exists in the Thread Network Data.
      *
      */
-    otError GetNextService(Iterator &aIterator, ServiceConfig &aConfig);
+    otError GetNextService(Iterator &aIterator, ServiceConfig &aConfig) const;
 
     /**
      * This method provides the next service in the Thread Network Data for a given RLOC16.
@@ -237,20 +237,20 @@
      * @retval OT_ERROR_NOT_FOUND  No subsequent service exists in the Thread Network Data.
      *
      */
-    otError GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig);
+    otError GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const;
 
     /**
-     * This method provides the next service ID in the Thread Network Data for a given RLOC16.
+     * This method provides the next Service ID in the Thread Network Data for a given RLOC16.
      *
      * @param[inout]  aIterator  A reference to the Network Data iterator.
      * @param[in]     aRloc16    The RLOC16 value.
-     * @param[out]    aServiceID A reference to variable where the service ID will be placed.
+     * @param[out]    aServiceId A reference to variable where the Service ID will be placed.
      *
      * @retval OT_ERROR_NONE       Successfully found the next service.
      * @retval OT_ERROR_NOT_FOUND  No subsequent service exists in the Thread Network Data.
      *
      */
-    otError GetNextServiceId(Iterator &aIterator, uint16_t aRloc16, uint8_t &aServiceId);
+    otError GetNextServiceId(Iterator &aIterator, uint16_t aRloc16, uint8_t &aServiceId) const;
 
     /**
      * This method indicates whether or not the Thread Network Data contains all of the on mesh prefix information
@@ -263,7 +263,7 @@
      *          FALSE otherwise.
      *
      */
-    bool ContainsOnMeshPrefixes(NetworkData &aCompare, uint16_t aRloc16);
+    bool ContainsOnMeshPrefixes(const NetworkData &aCompare, uint16_t aRloc16) const;
 
     /**
      * This method indicates whether or not the Thread Network Data contains all of the external route information
@@ -276,7 +276,7 @@
      *          FALSE otherwise.
      *
      */
-    bool ContainsExternalRoutes(NetworkData &aCompare, uint16_t aRloc16);
+    bool ContainsExternalRoutes(const NetworkData &aCompare, uint16_t aRloc16) const;
 
     /**
      * This method indicates whether or not the Thread Network Data contains all of the service information
@@ -289,79 +289,184 @@
      *          FALSE otherwise.
      *
      */
-    bool ContainsServices(NetworkData &aCompare, uint16_t aRloc16);
+    bool ContainsServices(const NetworkData &aCompare, uint16_t aRloc16) const;
 
     /**
      * This method indicates whether or not the Thread Network Data contains the service with given Service ID
      * associated with @p aRloc16.
      *
-     * @param[in]  aServiceID The Service ID to search for.
+     * @param[in]  aServiceId The Service ID to search for.
      * @param[in]  aRloc16    The RLOC16 to consider.
      *
      * @returns TRUE if this object contains the service with given ID associated with @p aRloc16,
      *          FALSE otherwise.
      *
      */
-    bool ContainsService(uint8_t aServiceId, uint16_t aRloc16);
+    bool ContainsService(uint8_t aServiceId, uint16_t aRloc16) const;
 
     /**
-     * This method cancels the data resubmit delay timer.
+     * This method provides the next server RLOC16 in the Thread Network Data.
+     *
+     * @param[inout]  aIterator  A reference to the Network Data iterator.
+     * @param[out]    aRloc16    The RLOC16 value.
+     *
+     * @retval OT_ERROR_NONE       Successfully found the next server.
+     * @retval OT_ERROR_NOT_FOUND  No subsequent server exists in the Thread Network Data.
      *
      */
-    void ClearResubmitDelayTimer(void);
+    otError GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const;
 
 protected:
     /**
+     * This method returns a pointer to the start of Network Data TLV sequence.
+     *
+     * @returns A pointer to the start of Network Data TLV sequence.
+     *
+     */
+    NetworkDataTlv *GetTlvsStart(void) { return reinterpret_cast<NetworkDataTlv *>(mTlvs); }
+
+    /**
+     * This method returns a pointer to the start of Network Data TLV sequence.
+     *
+     * @returns A pointer to the start of Network Data TLV sequence.
+     *
+     */
+    const NetworkDataTlv *GetTlvsStart(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs); }
+
+    /**
+     * This method returns a pointer to the end of Network Data TLV sequence.
+     *
+     * @returns A pointer to the end of Network Data TLV sequence.
+     *
+     */
+    NetworkDataTlv *GetTlvsEnd(void) { return reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); }
+
+    /**
+     * This method returns a pointer to the end of Network Data TLV sequence.
+     *
+     * @returns A pointer to the end of Network Data TLV sequence.
+     *
+     */
+    const NetworkDataTlv *GetTlvsEnd(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs + mLength); }
+
+    /**
      * This method returns a pointer to the Border Router TLV within a given Prefix TLV.
      *
      * @param[in]  aPrefix  A reference to the Prefix TLV.
      *
-     * @returns A pointer to the Border Router TLV if one is found or NULL if no Border Router TLV exists.
+     * @returns A pointer to the Border Router TLV if one is found or nullptr if no Border Router TLV exists.
      *
      */
-    BorderRouterTlv *FindBorderRouter(PrefixTlv &aPrefix);
+    static BorderRouterTlv *FindBorderRouter(PrefixTlv &aPrefix)
+    {
+        return const_cast<BorderRouterTlv *>(FindBorderRouter(const_cast<const PrefixTlv &>(aPrefix)));
+    }
+
+    /**
+     * This method returns a pointer to the Border Router TLV within a given Prefix TLV.
+     *
+     * @param[in]  aPrefix  A reference to the Prefix TLV.
+     *
+     * @returns A pointer to the Border Router TLV if one is found or nullptr if no Border Router TLV exists.
+     *
+     */
+    static const BorderRouterTlv *FindBorderRouter(const PrefixTlv &aPrefix);
 
     /**
      * This method returns a pointer to the stable or non-stable Border Router TLV within a given Prefix TLV.
      *
      * @param[in]  aPrefix  A reference to the Prefix TLV.
-     * @param[in]  aStable  TRUE if requesting a stable Border Router TLV, FALSE otherwise.
+     * @param[in]  aStable  TRUE to find a stable TLV, FALSE to find a TLV not marked as stable..
      *
-     * @returns A pointer to the Border Router TLV if one is found or NULL if no Border Router TLV exists.
+     * @returns A pointer to the Border Router TLV if one is found or nullptr if no Border Router TLV exists.
      *
      */
-    BorderRouterTlv *FindBorderRouter(PrefixTlv &aPrefix, bool aStable);
+    static BorderRouterTlv *FindBorderRouter(PrefixTlv &aPrefix, bool aStable)
+    {
+        return const_cast<BorderRouterTlv *>(FindBorderRouter(const_cast<const PrefixTlv &>(aPrefix), aStable));
+    }
+
+    /**
+     * This method returns a pointer to the stable or non-stable Border Router TLV within a given Prefix TLV.
+     *
+     * @param[in]  aPrefix  A reference to the Prefix TLV.
+     * @param[in]  aStable  TRUE to find a stable TLV, FALSE to find a TLV not marked as stable..
+     *
+     * @returns A pointer to the Border Router TLV if one is found or nullptr if no Border Router TLV exists.
+     *
+     */
+    static const BorderRouterTlv *FindBorderRouter(const PrefixTlv &aPrefix, bool aStable);
 
     /**
      * This method returns a pointer to the Has Route TLV within a given Prefix TLV.
      *
      * @param[in]  aPrefix  A reference to the Prefix TLV.
      *
-     * @returns A pointer to the Has Route TLV if one is found or NULL if no Has Route TLV exists.
+     * @returns A pointer to the Has Route TLV if one is found or nullptr if no Has Route TLV exists.
      *
      */
-    HasRouteTlv *FindHasRoute(PrefixTlv &aPrefix);
+    static HasRouteTlv *FindHasRoute(PrefixTlv &aPrefix)
+    {
+        return const_cast<HasRouteTlv *>(FindHasRoute(const_cast<const PrefixTlv &>(aPrefix)));
+    }
+
+    /**
+     * This method returns a pointer to the Has Route TLV within a given Prefix TLV.
+     *
+     * @param[in]  aPrefix  A reference to the Prefix TLV.
+     *
+     * @returns A pointer to the Has Route TLV if one is found or nullptr if no Has Route TLV exists.
+     *
+     */
+    static const HasRouteTlv *FindHasRoute(const PrefixTlv &aPrefix);
 
     /**
      * This method returns a pointer to the stable or non-stable Has Route TLV within a given Prefix TLV.
      *
      * @param[in]  aPrefix  A reference to the Prefix TLV.
-     * @param[in]  aStable  TRUE if requesting a stable Has Route TLV, FALSE otherwise.
+     * @param[in]  aStable  TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
      *
-     * @returns A pointer to the Has Route TLV if one is found or NULL if no Has Route TLV exists.
+     * @returns A pointer to the Has Route TLV if one is found or nullptr if no Has Route TLV exists.
      *
      */
-    HasRouteTlv *FindHasRoute(PrefixTlv &aPrefix, bool aStable);
+    static HasRouteTlv *FindHasRoute(PrefixTlv &aPrefix, bool aStable)
+    {
+        return const_cast<HasRouteTlv *>(FindHasRoute(const_cast<const PrefixTlv &>(aPrefix), aStable));
+    }
+
+    /**
+     * This method returns a pointer to the stable or non-stable Has Route TLV within a given Prefix TLV.
+     *
+     * @param[in]  aPrefix  A reference to the Prefix TLV.
+     * @param[in]  aStable  TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
+     *
+     * @returns A pointer to the Has Route TLV if one is found or nullptr if no Has Route TLV exists.
+     *
+     */
+    static const HasRouteTlv *FindHasRoute(const PrefixTlv &aPrefix, bool aStable);
 
     /**
      * This method returns a pointer to the Context TLV within a given Prefix TLV.
      *
      * @param[in]  aPrefix  A reference to the Prefix TLV.
      *
-     * @returns A pointer to the Context TLV is one is found or NULL if no Context TLV exists.
+     * @returns A pointer to the Context TLV is one is found or nullptr if no Context TLV exists.
      *
      */
-    ContextTlv *FindContext(PrefixTlv &aPrefix);
+    static ContextTlv *FindContext(PrefixTlv &aPrefix)
+    {
+        return const_cast<ContextTlv *>(FindContext(const_cast<const PrefixTlv &>(aPrefix)));
+    }
+
+    /**
+     * This method returns a pointer to the Context TLV within a given Prefix TLV.
+     *
+     * @param[in]  aPrefix  A reference to the Prefix TLV.
+     *
+     * @returns A pointer to the Context TLV is one is found or nullptr if no Context TLV exists.
+     *
+     */
+    static const ContextTlv *FindContext(const PrefixTlv &aPrefix);
 
     /**
      * This method returns a pointer to a Prefix TLV.
@@ -369,23 +474,57 @@
      * @param[in]  aPrefix        A pointer to an IPv6 prefix.
      * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix.
      *
-     * @returns A pointer to the Prefix TLV is one is found or NULL if no matching Prefix TLV exists.
+     * @returns A pointer to the Prefix TLV is one is found or nullptr if no matching Prefix TLV exists.
      *
      */
-    PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength);
+    PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
+    {
+        return const_cast<PrefixTlv *>(const_cast<const NetworkData *>(this)->FindPrefix(aPrefix, aPrefixLength));
+    }
+
+    /**
+     * This method returns a pointer to a Prefix TLV.
+     *
+     * @param[in]  aPrefix        A pointer to an IPv6 prefix.
+     * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix.
+     *
+     * @returns A pointer to the Prefix TLV is one is found or nullptr if no matching Prefix TLV exists.
+     *
+     */
+    const PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const;
 
     /**
      * This method returns a pointer to a Prefix TLV in a specified tlvs buffer.
      *
      * @param[in]  aPrefix        A pointer to an IPv6 prefix.
-     * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix.
+     * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix (in bits).
      * @param[in]  aTlvs          A pointer to a specified tlvs buffer.
      * @param[in]  aTlvsLength    The specified tlvs buffer length pointed to by @p aTlvs.
      *
-     * @returns A pointer to the Prefix TLV is one is found or NULL if no matching Prefix TLV exists.
+     * @returns A pointer to the Prefix TLV is one is found or nullptr if no matching Prefix TLV exists.
      *
      */
-    PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, uint8_t *aTlvs, uint8_t aTlvsLength);
+    static PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, uint8_t *aTlvs, uint8_t aTlvsLength)
+    {
+        return const_cast<PrefixTlv *>(
+            FindPrefix(aPrefix, aPrefixLength, const_cast<const uint8_t *>(aTlvs), aTlvsLength));
+    }
+
+    /**
+     * This method returns a pointer to a Prefix TLV in a specified tlvs buffer.
+     *
+     * @param[in]  aPrefix        A pointer to an IPv6 prefix.
+     * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix (in bits).
+     * @param[in]  aTlvs          A pointer to a specified tlvs buffer.
+     * @param[in]  aTlvsLength    The specified tlvs buffer length pointed to by @p aTlvs.
+     *
+     * @returns A pointer to the Prefix TLV is one is found or nullptr if no matching Prefix TLV exists.
+     *
+     */
+    static const PrefixTlv *FindPrefix(const uint8_t *aPrefix,
+                                       uint8_t        aPrefixLength,
+                                       const uint8_t *aTlvs,
+                                       uint8_t        aTlvsLength);
 
     /**
      * This method returns a pointer to a matching Service TLV.
@@ -394,10 +533,28 @@
      * @param[in]  aServiceData       A pointer to a Service Data.
      * @param[in]  aServiceDataLength The Service Data length pointed to by @p aServiceData.
      *
-     * @returns A pointer to the Service TLV is one is found or NULL if no matching Service TLV exists.
+     * @returns A pointer to the Service TLV is one is found or nullptr if no matching Service TLV exists.
      *
      */
-    ServiceTlv *FindService(uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength);
+    ServiceTlv *FindService(uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength)
+    {
+        return const_cast<ServiceTlv *>(
+            const_cast<const NetworkData *>(this)->FindService(aEnterpriseNumber, aServiceData, aServiceDataLength));
+    }
+
+    /**
+     * This method returns a pointer to a matching Service TLV.
+     *
+     * @param[in]  aEnterpriseNumber  Enterprise Number.
+     * @param[in]  aServiceData       A pointer to a Service Data.
+     * @param[in]  aServiceDataLength The Service Data length pointed to by @p aServiceData.
+     *
+     * @returns A pointer to the Service TLV is one is found or nullptr if no matching Service TLV exists.
+     *
+     */
+    const ServiceTlv *FindService(uint32_t       aEnterpriseNumber,
+                                  const uint8_t *aServiceData,
+                                  uint8_t        aServiceDataLength) const;
 
     /**
      * This method returns a pointer to a Service TLV in a specified tlvs buffer.
@@ -408,14 +565,62 @@
      * @param[in]  aTlvs              A pointer to a specified tlvs buffer.
      * @param[in]  aTlvsLength        The specified tlvs buffer length pointed to by @p aTlvs.
      *
-     * @returns A pointer to the Service TLV is one is found or NULL if no matching Service TLV exists.
+     * @returns A pointer to the Service TLV is one is found or nullptr if no matching Service TLV exists.
      *
      */
-    ServiceTlv *FindService(uint32_t       aEnterpriseNumber,
-                            const uint8_t *aServiceData,
-                            uint8_t        aServiceDataLength,
-                            uint8_t *      aTlvs,
-                            uint8_t        aTlvsLength);
+    static ServiceTlv *FindService(uint32_t       aEnterpriseNumber,
+                                   const uint8_t *aServiceData,
+                                   uint8_t        aServiceDataLength,
+                                   uint8_t *      aTlvs,
+                                   uint8_t        aTlvsLength)
+    {
+        return const_cast<ServiceTlv *>(FindService(aEnterpriseNumber, aServiceData, aServiceDataLength,
+                                                    const_cast<const uint8_t *>(aTlvs), aTlvsLength));
+    }
+
+    /**
+     * This method returns a pointer to a Service TLV in a specified tlvs buffer.
+     *
+     * @param[in]  aEnterpriseNumber  Enterprise Number.
+     * @param[in]  aServiceData       A pointer to an Service Data.
+     * @param[in]  aServiceDataLength The Service Data length pointed to by @p aServiceData.
+     * @param[in]  aTlvs              A pointer to a specified tlvs buffer.
+     * @param[in]  aTlvsLength        The specified tlvs buffer length pointed to by @p aTlvs.
+     *
+     * @returns A pointer to the Service TLV is one is found or nullptr if no matching Service TLV exists.
+     *
+     */
+    static const ServiceTlv *FindService(uint32_t       aEnterpriseNumber,
+                                         const uint8_t *aServiceData,
+                                         uint8_t        aServiceDataLength,
+                                         const uint8_t *aTlvs,
+                                         uint8_t        aTlvsLength);
+
+    /**
+     * This method indicates whether there is space in Network Data to insert/append new info and grow it by a given
+     * number of bytes.
+     *
+     * @param[in]  aSize  The number of bytes to grow the Network Data.
+     *
+     * @retval TRUE   There is space to grow Network Data by @p aSize bytes.
+     * @retval FALSE  There is no space left to grow Network Data by @p aSize bytes.
+     *
+     */
+    bool CanInsert(uint16_t aSize) const { return (mLength + aSize <= kMaxSize); }
+
+    /**
+     * This method grows the Network Data to append a TLV with a requested size.
+     *
+     * On success, the returned TLV is not initialized (i.e., the TLV Length field is not set) but the requested
+     * size for it (@p aTlvSize number of bytes) is reserved in the Network Data.
+     *
+     * @param[in]  aTlvSize  The size of TLV (total number of bytes including Type, Length, and Value fields)
+     *
+     * @returns A pointer to the TLV if there is space to grow Network Data, or nullptr if no space to grow the Network
+     *          Data with requested @p aTlvSize number of bytes.
+     *
+     */
+    NetworkDataTlv *AppendTlv(uint16_t aTlvSize);
 
     /**
      * This method inserts bytes into the Network Data.
@@ -424,16 +629,24 @@
      * @param[in]  aLength  The number of bytes to insert.
      *
      */
-    void Insert(uint8_t *aStart, uint8_t aLength);
+    void Insert(void *aStart, uint8_t aLength);
 
     /**
      * This method removes bytes from the Network Data.
      *
-     * @param[in]  aStart   A pointer to the beginning of the removal.
-     * @param[in]  aLength  The number of bytes to remove.
+     * @param[in]  aRemoveStart   A pointer to the beginning of the removal.
+     * @param[in]  aRemoveLength  The number of bytes to remove.
      *
      */
-    void Remove(uint8_t *aStart, uint8_t aLength);
+    void Remove(void *aRemoveStart, uint8_t aRemoveLength);
+
+    /**
+     * This method removes a TLV from the Network Data.
+     *
+     * @param[in]  aTlv   The TLV to remove.
+     *
+     */
+    void RemoveTlv(NetworkDataTlv *aTlv);
 
     /**
      * This method strips non-stable data from the Thread Network Data.
@@ -443,29 +656,7 @@
      *                             resulting Network Data in bytes.
      *
      */
-    void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength);
-
-    /**
-     * This method strips non-stable Sub-TLVs from a Prefix TLV.
-     *
-     * @param[inout]  aData        A pointer to the Network Data to modify.
-     * @param[inout]  aDataLength  On entry, the size of the Network Data in bytes.  On exit, the size of the
-     *                             resulting Network Data in bytes.
-     * @param[inout]  aPrefix      A reference to the Prefix TLV to modify.
-     *
-     */
-    void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix);
-
-    /**
-     * This method strips non-stable Sub-TLVs from a Service TLV.
-     *
-     * @param[inout]  aData        A pointer to the Network Data to modify.
-     * @param[inout]  aDataLength  On entry, the size of the Network Data in bytes.  On exit, the size of the
-     *                             resulting Network Data in bytes.
-     * @param[inout]  aService     A reference to the Service TLV to modify.
-     *
-     */
-    void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, ServiceTlv &aService);
+    static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength);
 
     /**
      * This method computes the number of IPv6 Prefix bits that match.
@@ -477,18 +668,153 @@
      * @returns The number of matching bits.
      *
      */
-    int8_t PrefixMatch(const uint8_t *a, const uint8_t *b, uint8_t aLength);
+    static int8_t PrefixMatch(const uint8_t *a, const uint8_t *b, uint8_t aLength);
 
     /**
      * This method sends a Server Data Notification message to the Leader.
      *
-     * @param[in]  aRloc16  The old RLOC16 value that was previously registered.
+     * @param[in]  aRloc16   The old RLOC16 value that was previously registered.
+     * @param[in]  aHandler  A function pointer that is called when the transaction ends.
+     * @param[in]  aContext  A pointer to arbitrary context information.
      *
      * @retval OT_ERROR_NONE     Successfully enqueued the notification message.
      * @retval OT_ERROR_NO_BUFS  Insufficient message buffers to generate the notification message.
      *
      */
-    otError SendServerDataNotification(uint16_t aRloc16);
+    otError SendServerDataNotification(uint16_t aRloc16, Coap::ResponseHandler aHandler, void *aContext);
+
+    /**
+     * This static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type.
+     *
+     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
+     * @param[in]  aType   The TLV type to find.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    static NetworkDataTlv *FindTlv(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, NetworkDataTlv::Type aType)
+    {
+        return const_cast<NetworkDataTlv *>(
+            FindTlv(const_cast<const NetworkDataTlv *>(aStart), const_cast<const NetworkDataTlv *>(aEnd), aType));
+    }
+
+    /**
+     * This static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type.
+     *
+     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
+     * @param[in]  aType   The TLV type to find.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    static const NetworkDataTlv *FindTlv(const NetworkDataTlv *aStart,
+                                         const NetworkDataTlv *aEnd,
+                                         NetworkDataTlv::Type  aType);
+
+    /**
+     * This static template method searches in a given sequence of TLVs to find the first TLV with a give template
+     * `TlvType`.
+     *
+     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    template <typename TlvType> static TlvType *FindTlv(NetworkDataTlv *aStart, NetworkDataTlv *aEnd)
+    {
+        return static_cast<TlvType *>(FindTlv(aStart, aEnd, static_cast<NetworkDataTlv::Type>(TlvType::kType)));
+    }
+
+    /**
+     * This static template method searches in a given sequence of TLVs to find the first TLV with a give template
+     * `TlvType`.
+     *
+     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    template <typename TlvType> static const TlvType *FindTlv(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd)
+    {
+        return static_cast<const TlvType *>(FindTlv(aStart, aEnd, static_cast<NetworkDataTlv::Type>(TlvType::kType)));
+    }
+
+    /**
+     * This static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type and stable
+     * flag.
+     *
+     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param [in] aEnd    A pointer to the end of the sequence of TLVs.
+     * @param[in]  aType   The TLV type to find.
+     * @param[in]  aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    static NetworkDataTlv *FindTlv(NetworkDataTlv *     aStart,
+                                   NetworkDataTlv *     aEnd,
+                                   NetworkDataTlv::Type aType,
+                                   bool                 aStable)
+    {
+        return const_cast<NetworkDataTlv *>(FindTlv(const_cast<const NetworkDataTlv *>(aStart),
+                                                    const_cast<const NetworkDataTlv *>(aEnd), aType, aStable));
+    }
+
+    /**
+     * This static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type and stable
+     * flag.
+     *
+     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param [in] aEnd    A pointer to the end of the sequence of TLVs.
+     * @param[in]  aType   The TLV type to find.
+     * @param[in]  aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    static const NetworkDataTlv *FindTlv(const NetworkDataTlv *aStart,
+                                         const NetworkDataTlv *aEnd,
+                                         NetworkDataTlv::Type  aType,
+                                         bool                  aStable);
+
+    /**
+     * This template static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type and
+     * stable flag.
+     *
+     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param [in] aEnd    A pointer to the end of the sequence of TLVs.
+     * @param[in]  aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    template <typename TlvType> static TlvType *FindTlv(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, bool aStable)
+    {
+        return static_cast<TlvType *>(
+            FindTlv(aStart, aEnd, static_cast<NetworkDataTlv::Type>(TlvType::kType), aStable));
+    }
+
+    /**
+     * This template static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type and
+     * stable flag.
+     *
+     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
+     * @param [in] aEnd    A pointer to the end of the sequence of TLVs.
+     * @param[in]  aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
+     *
+     * @returns A pointer to the TLV if found, or nullptr if not found.
+     *
+     */
+    template <typename TlvType>
+    static const TlvType *FindTlv(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd, bool aStable)
+    {
+        return static_cast<const TlvType *>(
+            FindTlv(aStart, aEnd, static_cast<NetworkDataTlv::Type>(TlvType::kType), aStable));
+    }
 
     uint8_t mTlvs[kMaxSize]; ///< The Network Data buffer.
     uint8_t mLength;         ///< The number of valid bytes in @var mTlvs.
@@ -496,7 +822,9 @@
 private:
     enum
     {
-        kDataResubmitDelay = 300000, ///< DATA_RESUBMIT_DELAY (milliseconds)
+        kDataResubmitDelay  = 300000, ///< DATA_RESUBMIT_DELAY (milliseconds) if the device itself is the server.
+        kProxyResubmitDelay = 5000,   ///< Resubmit delay (milliseconds) if deregister as the child server proxy.
+
     };
 
     class NetworkDataIterator
@@ -507,11 +835,48 @@
         {
         }
 
+        const NetworkDataTlv *GetTlv(const uint8_t *aTlvs) const
+        {
+            return reinterpret_cast<const NetworkDataTlv *>(aTlvs + GetTlvOffset());
+        }
+
+        void AdvanceTlv(const uint8_t *aTlvs)
+        {
+            SaveTlvOffset(GetTlv(aTlvs)->GetNext(), aTlvs);
+            SetSubTlvOffset(0);
+            SetEntryIndex(0);
+        }
+
+        const NetworkDataTlv *GetSubTlv(const NetworkDataTlv *aSubTlvs) const
+        {
+            return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(aSubTlvs) +
+                                                            GetSubTlvOffset());
+        }
+
+        void AdvaceSubTlv(const NetworkDataTlv *aSubTlvs)
+        {
+            SaveSubTlvOffset(GetSubTlv(aSubTlvs)->GetNext(), aSubTlvs);
+            SetEntryIndex(0);
+        }
+
+        uint8_t GetAndAdvanceIndex(void) { return mIteratorBuffer[kEntryPosition]++; }
+
+        bool IsNewEntry(void) const { return GetEntryIndex() == 0; }
+        void MarkEntryAsNotNew(void) { SetEntryIndex(1); }
+
+    private:
+        enum
+        {
+            kTlvPosition    = 0,
+            kSubTlvPosition = 1,
+            kEntryPosition  = 2,
+        };
+
         uint8_t GetTlvOffset(void) const { return mIteratorBuffer[kTlvPosition]; }
         uint8_t GetSubTlvOffset(void) const { return mIteratorBuffer[kSubTlvPosition]; }
-        uint8_t GetEntryIndex(void) const { return mIteratorBuffer[kEntryPosition]; }
-        void    SetTlvOffset(uint8_t aOffset) { mIteratorBuffer[kTlvPosition] = aOffset; }
         void    SetSubTlvOffset(uint8_t aOffset) { mIteratorBuffer[kSubTlvPosition] = aOffset; }
+        void    SetTlvOffset(uint8_t aOffset) { mIteratorBuffer[kTlvPosition] = aOffset; }
+        uint8_t GetEntryIndex(void) const { return mIteratorBuffer[kEntryPosition]; }
         void    SetEntryIndex(uint8_t aIndex) { mIteratorBuffer[kEntryPosition] = aIndex; }
 
         void SaveTlvOffset(const NetworkDataTlv *aTlv, const uint8_t *aTlvs)
@@ -525,20 +890,25 @@
                                                  reinterpret_cast<const uint8_t *>(aSubTlvs)));
         }
 
-    private:
-        enum
-        {
-            kTlvPosition    = 0,
-            kSubTlvPosition = 1,
-            kEntryPosition  = 2,
-        };
-
         uint8_t *mIteratorBuffer;
     };
 
+    struct Config
+    {
+        OnMeshPrefixConfig * mOnMeshPrefix;
+        ExternalRouteConfig *mExternalRoute;
+        ServiceConfig *      mService;
+    };
+
+    otError Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const;
+
+    static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix);
+    static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, ServiceTlv &aService);
+
+    static void Remove(uint8_t *aData, uint8_t &aDataLength, uint8_t *aRemoveStart, uint8_t aRemoveLength);
+    static void RemoveTlv(uint8_t *aData, uint8_t &aDataLength, NetworkDataTlv *aTlv);
+
     const Type mType;
-    bool       mLastAttemptWait;
-    TimeMilli  mLastAttempt;
 };
 
 } // namespace NetworkData
diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp
index f3c5fde..4497f37 100644
--- a/src/core/thread/network_data_leader.cpp
+++ b/src/core/thread/network_data_leader.cpp
@@ -64,42 +64,117 @@
     mVersion       = Random::NonCrypto::GetUint8();
     mStableVersion = Random::NonCrypto::GetUint8();
     mLength        = 0;
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETDATA);
+    Get<ot::Notifier>().Signal(kEventThreadNetdataChanged);
 }
 
-otError LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext)
+otError LeaderBase::GetServiceId(uint32_t       aEnterpriseNumber,
+                                 const uint8_t *aServiceData,
+                                 uint8_t        aServiceDataLength,
+                                 bool           aServerStable,
+                                 uint8_t &      aServiceId) const
 {
-    PrefixTlv * prefix;
-    ContextTlv *contextTlv;
+    otError         error    = OT_ERROR_NOT_FOUND;
+    Iterator        iterator = kIteratorInit;
+    otServiceConfig serviceConfig;
+
+    while (GetNextService(iterator, serviceConfig) == OT_ERROR_NONE)
+    {
+        if (aEnterpriseNumber == serviceConfig.mEnterpriseNumber &&
+            aServiceDataLength == serviceConfig.mServiceDataLength &&
+            memcmp(aServiceData, serviceConfig.mServiceData, aServiceDataLength) == 0 &&
+            aServerStable == serviceConfig.mServerConfig.mStable)
+        {
+            aServiceId = serviceConfig.mServiceId;
+            ExitNow(error = OT_ERROR_NONE);
+        }
+    }
+
+exit:
+    return error;
+}
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+otError LeaderBase::GetBackboneRouterPrimary(BackboneRouter::BackboneRouterConfig &aConfig) const
+{
+    otError                         error          = OT_ERROR_NOT_FOUND;
+    uint8_t                         serviceData    = ServiceTlv::kServiceDataBackboneRouter;
+    const ServerTlv *               rvalServerTlv  = nullptr;
+    const BackboneRouterServerData *rvalServerData = nullptr;
+    const ServiceTlv *              serviceTlv;
+    const ServerTlv *               serverTlv;
+
+    serviceTlv = Get<Leader>().FindService(ServiceTlv::kThreadEnterpriseNumber, &serviceData, sizeof(serviceData));
+
+    VerifyOrExit(serviceTlv != nullptr, aConfig.mServer16 = Mac::kShortAddrInvalid);
+
+    for (const NetworkDataTlv *start                                                      = serviceTlv->GetSubTlvs();
+         (serverTlv = FindTlv<ServerTlv>(start, serviceTlv->GetNext())) != nullptr; start = serverTlv->GetNext())
+    {
+        const BackboneRouterServerData *serverData =
+            reinterpret_cast<const BackboneRouterServerData *>(serverTlv->GetServerData());
+
+        if (rvalServerTlv == nullptr ||
+            (serverTlv->GetServer16() == Mle::Mle::Rloc16FromRouterId(Get<Mle::MleRouter>().GetLeaderId())) ||
+            serverData->GetSequenceNumber() > rvalServerData->GetSequenceNumber() ||
+            (serverData->GetSequenceNumber() == rvalServerData->GetSequenceNumber() &&
+             serverTlv->GetServer16() > rvalServerTlv->GetServer16()))
+        {
+            rvalServerTlv  = serverTlv;
+            rvalServerData = serverData;
+        }
+    }
+
+    VerifyOrExit(rvalServerTlv != nullptr, OT_NOOP);
+
+    aConfig.mServer16            = rvalServerTlv->GetServer16();
+    aConfig.mSequenceNumber      = rvalServerData->GetSequenceNumber();
+    aConfig.mReregistrationDelay = rvalServerData->GetReregistrationDelay();
+    aConfig.mMlrTimeout          = rvalServerData->GetMlrTimeout();
+
+    error = OT_ERROR_NONE;
+
+exit:
+    return error;
+}
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+
+const PrefixTlv *LeaderBase::FindNextMatchingPrefix(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const
+{
+    const PrefixTlv *prefix;
+
+    for (const NetworkDataTlv *start = (aPrevTlv == nullptr) ? GetTlvsStart() : aPrevTlv->GetNext();
+         (prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr; start = prefix->GetNext())
+    {
+        if (PrefixMatch(prefix->GetPrefix(), aAddress.mFields.m8, prefix->GetPrefixLength()) >= 0)
+        {
+            ExitNow();
+        }
+    }
+
+exit:
+    return prefix;
+}
+
+otError LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const
+{
+    const PrefixTlv * prefix = nullptr;
+    const ContextTlv *contextTlv;
 
     aContext.mPrefixLength = 0;
 
-    if (PrefixMatch(Get<Mle::MleRouter>().GetMeshLocalPrefix().m8, aAddress.mFields.m8, 64) >= 0)
+    if (Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
     {
         aContext.mPrefix       = Get<Mle::MleRouter>().GetMeshLocalPrefix().m8;
-        aContext.mPrefixLength = 64;
+        aContext.mPrefixLength = Mle::MeshLocalPrefix::kLength;
         aContext.mContextId    = Mle::kMeshLocalPrefixContextId;
         aContext.mCompressFlag = true;
     }
 
-    for (NetworkDataTlv *cur                                            = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
+    while ((prefix = FindNextMatchingPrefix(aAddress, prefix)) != nullptr)
     {
-        if (cur->GetType() != NetworkDataTlv::kTypePrefix)
-        {
-            continue;
-        }
-
-        prefix = static_cast<PrefixTlv *>(cur);
-
-        if (PrefixMatch(prefix->GetPrefix(), aAddress.mFields.m8, prefix->GetPrefixLength()) < 0)
-        {
-            continue;
-        }
-
         contextTlv = FindContext(*prefix);
 
-        if (contextTlv == NULL)
+        if (contextTlv == nullptr)
         {
             continue;
         }
@@ -116,38 +191,26 @@
     return (aContext.mPrefixLength > 0) ? OT_ERROR_NONE : OT_ERROR_NOT_FOUND;
 }
 
-otError LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext)
+otError LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) const
 {
-    otError     error = OT_ERROR_NOT_FOUND;
-    PrefixTlv * prefix;
-    ContextTlv *contextTlv;
+    otError          error = OT_ERROR_NOT_FOUND;
+    const PrefixTlv *prefix;
 
     if (aContextId == Mle::kMeshLocalPrefixContextId)
     {
         aContext.mPrefix       = Get<Mle::MleRouter>().GetMeshLocalPrefix().m8;
-        aContext.mPrefixLength = 64;
+        aContext.mPrefixLength = Mle::MeshLocalPrefix::kLength;
         aContext.mContextId    = Mle::kMeshLocalPrefixContextId;
         aContext.mCompressFlag = true;
         ExitNow(error = OT_ERROR_NONE);
     }
 
-    for (NetworkDataTlv *cur                                            = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
+    for (const NetworkDataTlv *start = GetTlvsStart(); (prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr;
+         start                       = prefix->GetNext())
     {
-        if (cur->GetType() != NetworkDataTlv::kTypePrefix)
-        {
-            continue;
-        }
+        const ContextTlv *contextTlv = FindContext(*prefix);
 
-        prefix     = static_cast<PrefixTlv *>(cur);
-        contextTlv = FindContext(*prefix);
-
-        if (contextTlv == NULL)
-        {
-            continue;
-        }
-
-        if (contextTlv->GetContextId() != aContextId)
+        if ((contextTlv == nullptr) || (contextTlv->GetContextId() != aContextId))
         {
             continue;
         }
@@ -163,7 +226,7 @@
     return error;
 }
 
-otError LeaderBase::GetRlocByContextId(uint8_t aContextId, uint16_t &aRloc16)
+otError LeaderBase::GetRlocByContextId(uint8_t aContextId, uint16_t &aRloc16) const
 {
     otError         error = OT_ERROR_NOT_FOUND;
     Lowpan::Context lowpanContext;
@@ -188,37 +251,34 @@
     return error;
 }
 
-bool LeaderBase::IsOnMesh(const Ip6::Address &aAddress)
+bool LeaderBase::IsOnMesh(const Ip6::Address &aAddress) const
 {
-    PrefixTlv *prefix;
-    bool       rval = false;
+    const PrefixTlv *prefix = nullptr;
+    bool             rval   = false;
 
-    if (memcmp(aAddress.mFields.m8, Get<Mle::MleRouter>().GetMeshLocalPrefix().m8, sizeof(otMeshLocalPrefix)) == 0)
+    VerifyOrExit(!Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress), rval = true);
+
+    while ((prefix = FindNextMatchingPrefix(aAddress, prefix)) != nullptr)
     {
-        ExitNow(rval = true);
-    }
-
-    for (NetworkDataTlv *cur                                            = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
-    {
-        if (cur->GetType() != NetworkDataTlv::kTypePrefix)
+        // check both stable and temporary Border Router TLVs
+        for (int i = 0; i < 2; i++)
         {
-            continue;
+            const BorderRouterTlv *borderRouter = FindBorderRouter(*prefix, /* aStable */ (i == 0));
+
+            if (borderRouter == nullptr)
+            {
+                continue;
+            }
+
+            for (const BorderRouterEntry *entry = borderRouter->GetFirstEntry(); entry <= borderRouter->GetLastEntry();
+                 entry                          = entry->GetNext())
+            {
+                if (entry->IsOnMesh())
+                {
+                    ExitNow(rval = true);
+                }
+            }
         }
-
-        prefix = static_cast<PrefixTlv *>(cur);
-
-        if (PrefixMatch(prefix->GetPrefix(), aAddress.mFields.m8, prefix->GetPrefixLength()) < 0)
-        {
-            continue;
-        }
-
-        if (FindBorderRouter(*prefix) == NULL)
-        {
-            continue;
-        }
-
-        ExitNow(rval = true);
     }
 
 exit:
@@ -228,37 +288,26 @@
 otError LeaderBase::RouteLookup(const Ip6::Address &aSource,
                                 const Ip6::Address &aDestination,
                                 uint8_t *           aPrefixMatch,
-                                uint16_t *          aRloc16)
+                                uint16_t *          aRloc16) const
 {
-    otError    error = OT_ERROR_NO_ROUTE;
-    PrefixTlv *prefix;
+    otError          error  = OT_ERROR_NO_ROUTE;
+    const PrefixTlv *prefix = nullptr;
 
-    for (NetworkDataTlv *cur                                            = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
+    while ((prefix = FindNextMatchingPrefix(aSource, prefix)) != nullptr)
     {
-        if (cur->GetType() != NetworkDataTlv::kTypePrefix)
+        if (ExternalRouteLookup(prefix->GetDomainId(), aDestination, aPrefixMatch, aRloc16) == OT_ERROR_NONE)
         {
-            continue;
+            ExitNow(error = OT_ERROR_NONE);
         }
 
-        prefix = static_cast<PrefixTlv *>(cur);
-
-        if (PrefixMatch(prefix->GetPrefix(), aSource.mFields.m8, prefix->GetPrefixLength()) >= 0)
+        if (DefaultRouteLookup(*prefix, aRloc16) == OT_ERROR_NONE)
         {
-            if (ExternalRouteLookup(prefix->GetDomainId(), aDestination, aPrefixMatch, aRloc16) == OT_ERROR_NONE)
+            if (aPrefixMatch)
             {
-                ExitNow(error = OT_ERROR_NONE);
+                *aPrefixMatch = 0;
             }
 
-            if (DefaultRouteLookup(*prefix, aRloc16) == OT_ERROR_NONE)
-            {
-                if (aPrefixMatch)
-                {
-                    *aPrefixMatch = 0;
-                }
-
-                ExitNow(error = OT_ERROR_NONE);
-            }
+            ExitNow(error = OT_ERROR_NONE);
         }
     }
 
@@ -269,27 +318,18 @@
 otError LeaderBase::ExternalRouteLookup(uint8_t             aDomainId,
                                         const Ip6::Address &aDestination,
                                         uint8_t *           aPrefixMatch,
-                                        uint16_t *          aRloc16)
+                                        uint16_t *          aRloc16) const
 {
-    otError         error = OT_ERROR_NO_ROUTE;
-    PrefixTlv *     prefix;
-    HasRouteTlv *   hasRoute;
-    HasRouteEntry * entry;
-    HasRouteEntry * rvalRoute = NULL;
-    uint8_t         rval_plen = 0;
-    int8_t          plen;
-    NetworkDataTlv *cur;
-    NetworkDataTlv *subCur;
+    otError              error = OT_ERROR_NO_ROUTE;
+    const PrefixTlv *    prefix;
+    const HasRouteEntry *rvalRoute = nullptr;
+    uint8_t              rval_plen = 0;
 
-    for (cur = reinterpret_cast<NetworkDataTlv *>(mTlvs); cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
-         cur = cur->GetNext())
+    for (const NetworkDataTlv *start = GetTlvsStart(); (prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr;
+         start                       = prefix->GetNext())
     {
-        if (cur->GetType() != NetworkDataTlv::kTypePrefix)
-        {
-            continue;
-        }
-
-        prefix = static_cast<PrefixTlv *>(cur);
+        const HasRouteTlv *hasRoute;
+        int8_t             plen;
 
         if (prefix->GetDomainId() != aDomainId)
         {
@@ -298,45 +338,39 @@
 
         plen = PrefixMatch(prefix->GetPrefix(), aDestination.mFields.m8, prefix->GetPrefixLength());
 
-        if (plen > rval_plen)
+        if (plen <= rval_plen)
         {
-            // select border router
-            for (subCur = prefix->GetSubTlvs(); subCur < prefix->GetNext(); subCur = subCur->GetNext())
+            continue;
+        }
+
+        for (const NetworkDataTlv *subStart                                                      = prefix->GetSubTlvs();
+             (hasRoute = FindTlv<HasRouteTlv>(subStart, prefix->GetNext())) != nullptr; subStart = hasRoute->GetNext())
+        {
+            for (const HasRouteEntry *entry = hasRoute->GetFirstEntry(); entry <= hasRoute->GetLastEntry();
+                 entry                      = entry->GetNext())
             {
-                if (subCur->GetType() != NetworkDataTlv::kTypeHasRoute)
+                if (rvalRoute == nullptr || entry->GetPreference() > rvalRoute->GetPreference() ||
+                    (entry->GetPreference() == rvalRoute->GetPreference() &&
+                     (entry->GetRloc() == Get<Mle::MleRouter>().GetRloc16() ||
+                      (rvalRoute->GetRloc() != Get<Mle::MleRouter>().GetRloc16() &&
+                       Get<Mle::MleRouter>().GetCost(entry->GetRloc()) <
+                           Get<Mle::MleRouter>().GetCost(rvalRoute->GetRloc())))))
                 {
-                    continue;
-                }
-
-                hasRoute = static_cast<HasRouteTlv *>(subCur);
-
-                for (uint8_t i = 0; i < hasRoute->GetNumEntries(); i++)
-                {
-                    entry = hasRoute->GetEntry(i);
-
-                    if (rvalRoute == NULL || entry->GetPreference() > rvalRoute->GetPreference() ||
-                        (entry->GetPreference() == rvalRoute->GetPreference() &&
-                         (entry->GetRloc() == Get<Mle::MleRouter>().GetRloc16() ||
-                          (rvalRoute->GetRloc() != Get<Mle::MleRouter>().GetRloc16() &&
-                           Get<Mle::MleRouter>().GetCost(entry->GetRloc()) <
-                               Get<Mle::MleRouter>().GetCost(rvalRoute->GetRloc())))))
-                    {
-                        rvalRoute = entry;
-                        rval_plen = static_cast<uint8_t>(plen);
-                    }
+                    rvalRoute = entry;
+                    rval_plen = static_cast<uint8_t>(plen);
                 }
             }
         }
     }
 
-    if (rvalRoute != NULL)
+    if (rvalRoute != nullptr)
     {
-        if (aRloc16 != NULL)
+        if (aRloc16 != nullptr)
         {
             *aRloc16 = rvalRoute->GetRloc();
         }
 
-        if (aPrefixMatch != NULL)
+        if (aPrefixMatch != nullptr)
         {
             *aPrefixMatch = rval_plen;
         }
@@ -347,32 +381,25 @@
     return error;
 }
 
-otError LeaderBase::DefaultRouteLookup(PrefixTlv &aPrefix, uint16_t *aRloc16)
+otError LeaderBase::DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t *aRloc16) const
 {
-    otError            error = OT_ERROR_NO_ROUTE;
-    BorderRouterTlv *  borderRouter;
-    BorderRouterEntry *entry;
-    BorderRouterEntry *route = NULL;
+    otError                  error = OT_ERROR_NO_ROUTE;
+    const BorderRouterTlv *  borderRouter;
+    const BorderRouterEntry *route = nullptr;
 
-    for (NetworkDataTlv *cur = aPrefix.GetSubTlvs(); cur < aPrefix.GetNext(); cur = cur->GetNext())
+    for (const NetworkDataTlv *start = aPrefix.GetSubTlvs();
+         (borderRouter = FindTlv<BorderRouterTlv>(start, aPrefix.GetNext())) != nullptr;
+         start = borderRouter->GetNext())
     {
-        if (cur->GetType() != NetworkDataTlv::kTypeBorderRouter)
+        for (const BorderRouterEntry *entry = borderRouter->GetFirstEntry(); entry <= borderRouter->GetLastEntry();
+             entry                          = entry->GetNext())
         {
-            continue;
-        }
-
-        borderRouter = static_cast<BorderRouterTlv *>(cur);
-
-        for (uint8_t i = 0; i < borderRouter->GetNumEntries(); i++)
-        {
-            entry = borderRouter->GetEntry(i);
-
             if (!entry->IsDefaultRoute())
             {
                 continue;
             }
 
-            if (route == NULL || entry->GetPreference() > route->GetPreference() ||
+            if (route == nullptr || entry->GetPreference() > route->GetPreference() ||
                 (entry->GetPreference() == route->GetPreference() &&
                  (entry->GetRloc() == Get<Mle::MleRouter>().GetRloc16() ||
                   (route->GetRloc() != Get<Mle::MleRouter>().GetRloc16() &&
@@ -383,9 +410,9 @@
         }
     }
 
-    if (route != NULL)
+    if (route != nullptr)
     {
-        if (aRloc16 != NULL)
+        if (aRloc16 != nullptr)
         {
             *aRloc16 = route->GetRloc();
         }
@@ -423,7 +450,7 @@
 
 #if OPENTHREAD_FTD
     // Synchronize internal 6LoWPAN Context ID Set with recently obtained Network Data.
-    if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER)
+    if (Get<Mle::MleRouter>().IsLeader())
     {
         Get<Leader>().UpdateContextsAfterReset();
     }
@@ -431,7 +458,7 @@
 
     otDumpDebgNetData("set network data", mTlvs, mLength);
 
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETDATA);
+    Get<ot::Notifier>().Signal(kEventThreadNetdataChanged);
 
 exit:
     return error;
@@ -439,83 +466,58 @@
 
 otError LeaderBase::SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength)
 {
-    otError               error     = OT_ERROR_NONE;
-    uint8_t               remaining = kMaxSize - mLength;
+    otError               error = OT_ERROR_NONE;
     CommissioningDataTlv *commissioningDataTlv;
 
-    VerifyOrExit(sizeof(NetworkDataTlv) + aValueLength < remaining, error = OT_ERROR_NO_BUFS);
-
     RemoveCommissioningData();
 
     if (aValueLength > 0)
     {
-        commissioningDataTlv = reinterpret_cast<CommissioningDataTlv *>(mTlvs + mLength);
-        Insert(reinterpret_cast<uint8_t *>(commissioningDataTlv), sizeof(CommissioningDataTlv) + aValueLength);
+        VerifyOrExit(aValueLength <= kMaxSize - sizeof(CommissioningDataTlv), error = OT_ERROR_NO_BUFS);
+        commissioningDataTlv =
+            static_cast<CommissioningDataTlv *>(AppendTlv(sizeof(CommissioningDataTlv) + aValueLength));
+        VerifyOrExit(commissioningDataTlv != nullptr, error = OT_ERROR_NO_BUFS);
+
         commissioningDataTlv->Init();
         commissioningDataTlv->SetLength(aValueLength);
         memcpy(commissioningDataTlv->GetValue(), aValue, aValueLength);
     }
 
     mVersion++;
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETDATA);
+    Get<ot::Notifier>().Signal(kEventThreadNetdataChanged);
 
 exit:
     return error;
 }
 
-NetworkDataTlv *LeaderBase::GetCommissioningData(void)
+const CommissioningDataTlv *LeaderBase::GetCommissioningData(void) const
 {
-    NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-    NetworkDataTlv *end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
-
-    for (; cur < end; cur = cur->GetNext())
-    {
-        if (cur->GetType() == NetworkDataTlv::kTypeCommissioningData)
-        {
-            ExitNow();
-        }
-    }
-
-    cur = NULL;
-
-exit:
-    return cur;
+    return FindTlv<CommissioningDataTlv>(GetTlvsStart(), GetTlvsEnd());
 }
 
-MeshCoP::Tlv *LeaderBase::GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType)
+const MeshCoP::Tlv *LeaderBase::GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType) const
 {
-    MeshCoP::Tlv *  rval = NULL;
-    NetworkDataTlv *commissioningDataTlv;
-    MeshCoP::Tlv *  cur;
-    MeshCoP::Tlv *  end;
+    const MeshCoP::Tlv *  rval = nullptr;
+    const NetworkDataTlv *commissioningDataTlv;
 
     commissioningDataTlv = GetCommissioningData();
-    VerifyOrExit(commissioningDataTlv != NULL);
+    VerifyOrExit(commissioningDataTlv != nullptr, OT_NOOP);
 
-    cur = reinterpret_cast<MeshCoP::Tlv *>(commissioningDataTlv->GetValue());
-    end = reinterpret_cast<MeshCoP::Tlv *>(commissioningDataTlv->GetValue() + commissioningDataTlv->GetLength());
-
-    for (; cur < end; cur = cur->GetNext())
-    {
-        if (cur->GetType() == aType)
-        {
-            ExitNow(rval = cur);
-        }
-    }
+    rval = MeshCoP::Tlv::FindTlv(commissioningDataTlv->GetValue(), commissioningDataTlv->GetLength(), aType);
 
 exit:
     return rval;
 }
 
-bool LeaderBase::IsJoiningEnabled(void)
+bool LeaderBase::IsJoiningEnabled(void) const
 {
-    MeshCoP::Tlv *steeringData;
-    bool          rval = false;
+    const MeshCoP::Tlv *steeringData;
+    bool                rval = false;
 
-    VerifyOrExit(GetCommissioningDataSubTlv(MeshCoP::Tlv::kBorderAgentLocator) != NULL);
+    VerifyOrExit(GetCommissioningDataSubTlv(MeshCoP::Tlv::kBorderAgentLocator) != nullptr, OT_NOOP);
 
     steeringData = GetCommissioningDataSubTlv(MeshCoP::Tlv::kSteeringData);
-    VerifyOrExit(steeringData != NULL);
+    VerifyOrExit(steeringData != nullptr, OT_NOOP);
 
     for (int i = 0; i < steeringData->GetLength(); i++)
     {
@@ -529,22 +531,15 @@
     return rval;
 }
 
-otError LeaderBase::RemoveCommissioningData(void)
+void LeaderBase::RemoveCommissioningData(void)
 {
-    otError error = OT_ERROR_NOT_FOUND;
+    CommissioningDataTlv *tlv = GetCommissioningData();
 
-    for (NetworkDataTlv *cur                                            = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
-    {
-        if (cur->GetType() == NetworkDataTlv::kTypeCommissioningData)
-        {
-            Remove(reinterpret_cast<uint8_t *>(cur), sizeof(NetworkDataTlv) + cur->GetLength());
-            ExitNow(error = OT_ERROR_NONE);
-        }
-    }
+    VerifyOrExit(tlv != nullptr, OT_NOOP);
+    RemoveTlv(tlv);
 
 exit:
-    return error;
+    return;
 }
 
 } // namespace NetworkData
diff --git a/src/core/thread/network_data_leader.hpp b/src/core/thread/network_data_leader.hpp
index 2d0b99a..2120ccb 100644
--- a/src/core/thread/network_data_leader.hpp
+++ b/src/core/thread/network_data_leader.hpp
@@ -38,6 +38,10 @@
 
 #include <stdint.h>
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+#include "backbone_router/bbr_leader.hpp"
+#endif
+
 #include "coap/coap.hpp"
 #include "common/timer.hpp"
 #include "net/ip6_address.hpp"
@@ -105,7 +109,7 @@
      * @retval OT_ERROR_NOT_FOUND  Could not find the 6LoWPAN Context information.
      *
      */
-    otError GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext);
+    otError GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const;
 
     /**
      * This method retrieves the 6LoWPAN Context information based on a given Context ID.
@@ -117,7 +121,7 @@
      * @retval OT_ERROR_NOT_FOUND  Could not find the 6LoWPAN Context information.
      *
      */
-    otError GetContext(uint8_t aContextId, Lowpan::Context &aContext);
+    otError GetContext(uint8_t aContextId, Lowpan::Context &aContext) const;
 
     /**
      * This method indicates whether or not the given IPv6 address is on-mesh.
@@ -128,7 +132,7 @@
      * @retval FALSE  If @p aAddress if not on-link.
      *
      */
-    bool IsOnMesh(const Ip6::Address &aAddress);
+    bool IsOnMesh(const Ip6::Address &aAddress) const;
 
     /**
      * This method performs a route lookup using the Network Data.
@@ -145,7 +149,7 @@
     otError RouteLookup(const Ip6::Address &aSource,
                         const Ip6::Address &aDestination,
                         uint8_t *           aPrefixMatch,
-                        uint16_t *          aRloc16);
+                        uint16_t *          aRloc16) const;
 
     /**
      * This method is used by non-Leader devices to set newly received Network Data from the Leader.
@@ -180,20 +184,44 @@
     /**
      * This method returns a pointer to the Commissioning Data.
      *
-     * @returns A pointer to the Commissioning Data or NULL if no Commissioning Data exists.
+     * @returns A pointer to the Commissioning Data or nullptr if no Commissioning Data exists.
      *
      */
-    NetworkDataTlv *GetCommissioningData(void);
+    CommissioningDataTlv *GetCommissioningData(void)
+    {
+        return const_cast<CommissioningDataTlv *>(const_cast<const LeaderBase *>(this)->GetCommissioningData());
+    }
+
+    /**
+     * This method returns a pointer to the Commissioning Data.
+     *
+     * @returns A pointer to the Commissioning Data or nullptr if no Commissioning Data exists.
+     *
+     */
+    const CommissioningDataTlv *GetCommissioningData(void) const;
 
     /**
      * This method returns a pointer to the Commissioning Data Sub-TLV.
      *
      * @param[in]  aType  The TLV type value.
      *
-     * @returns A pointer to the Commissioning Data Sub-TLV or NULL if no Sub-TLV exists.
+     * @returns A pointer to the Commissioning Data Sub-TLV or nullptr if no Sub-TLV exists.
      *
      */
-    MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType);
+    MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType)
+    {
+        return const_cast<MeshCoP::Tlv *>(const_cast<const LeaderBase *>(this)->GetCommissioningDataSubTlv(aType));
+    }
+
+    /**
+     * This method returns a pointer to the Commissioning Data Sub-TLV.
+     *
+     * @param[in]  aType  The TLV type value.
+     *
+     * @returns A pointer to the Commissioning Data Sub-TLV or nullptr if no Sub-TLV exists.
+     *
+     */
+    const MeshCoP::Tlv *GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType) const;
 
     /**
      * This method indicates whether or not the Commissioning Data TLV indicates Joining is enabled.
@@ -203,7 +231,7 @@
      * @returns TRUE if the Commissioning Data TLV says Joining is enabled, FALSE otherwise.
      *
      */
-    bool IsJoiningEnabled(void);
+    bool IsJoiningEnabled(void) const;
 
     /**
      * This method adds Commissioning Data to the Thread Network Data.
@@ -227,20 +255,54 @@
      * @retval OT_ERROR_NOT_FOUND  The specified @p aContextId could not be found.
      *
      */
-    otError GetRlocByContextId(uint8_t aContextId, uint16_t &aRloc16);
+    otError GetRlocByContextId(uint8_t aContextId, uint16_t &aRloc16) const;
+
+    /**
+     * This method gets the Service ID for the specified service.
+     *
+     * @param[in]  aEnterpriseNumber  Enterprise Number (IANA-assigned) for Service TLV
+     * @param[in]  aServiceData       A pointer to the Service Data
+     * @param[in]  aServiceDataLength The length of @p aServiceData in bytes.
+     * @param[in]  aServerStable      The Stable flag value for Server TLV
+     * @param[out] aServiceId         A reference where to put the Service ID.
+     *
+     * @retval OT_ERROR_NONE       Successfully got the Service ID.
+     * @retval OT_ERROR_NOT_FOUND  The specified service was not found.
+     *
+     */
+    otError GetServiceId(uint32_t       aEnterpriseNumber,
+                         const uint8_t *aServiceData,
+                         uint8_t        aServiceDataLength,
+                         bool           aServerStable,
+                         uint8_t &      aServiceId) const;
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    /**
+     * This method gets the Primary Backbone Router (PBBR) in the Thread Network.
+     *
+     * @param[out]  aConfig      The Primary Backbone Router configuration.
+     *
+     * @retval OT_ERROR_NONE       Successfully got the Primary Backbone Router configuration.
+     * @retval OT_ERROR_NOT_FOUND  No Backbone Router Service in the Thread Network.
+     *
+     */
+    otError GetBackboneRouterPrimary(BackboneRouter::BackboneRouterConfig &aConfig) const;
+#endif
 
 protected:
     uint8_t mStableVersion;
     uint8_t mVersion;
 
 private:
-    otError RemoveCommissioningData(void);
+    const PrefixTlv *FindNextMatchingPrefix(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const;
+
+    void RemoveCommissioningData(void);
 
     otError ExternalRouteLookup(uint8_t             aDomainId,
                                 const Ip6::Address &aDestination,
                                 uint8_t *           aPrefixMatch,
-                                uint16_t *          aRloc16);
-    otError DefaultRouteLookup(PrefixTlv &aPrefix, uint16_t *aRloc16);
+                                uint16_t *          aRloc16) const;
+    otError DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t *aRloc16) const;
 };
 
 /**
diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp
index 77dc727..de07466 100644
--- a/src/core/thread/network_data_leader_ftd.cpp
+++ b/src/core/thread/network_data_leader_ftd.cpp
@@ -52,14 +52,12 @@
 #include "thread/thread_tlvs.hpp"
 #include "thread/thread_uri_paths.hpp"
 
-using ot::Encoding::BigEndian::HostSwap16;
-
 namespace ot {
 namespace NetworkData {
 
 Leader::Leader(Instance &aInstance)
     : LeaderBase(aInstance)
-    , mTimer(aInstance, &Leader::HandleTimer, this)
+    , mTimer(aInstance, Leader::HandleTimer, this)
     , mServerData(OT_URI_PATH_SERVER_DATA, &Leader::HandleServerData, this)
     , mCommissioningDataGet(OT_URI_PATH_COMMISSIONER_GET, &Leader::HandleCommissioningGet, this)
     , mCommissioningDataSet(OT_URI_PATH_COMMISSIONER_SET, &Leader::HandleCommissioningSet, this)
@@ -92,51 +90,45 @@
 
 void Leader::IncrementVersion(void)
 {
-    if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER)
+    if (Get<Mle::MleRouter>().IsLeader())
     {
-        mVersion++;
-        Get<Notifier>().Signal(OT_CHANGED_THREAD_NETDATA);
+        IncrementVersions(/* aIncludeStable */ false);
     }
 }
 
-void Leader::IncrementStableVersion(void)
+void Leader::IncrementVersionAndStableVersion(void)
 {
-    if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER)
+    if (Get<Mle::MleRouter>().IsLeader())
+    {
+        IncrementVersions(/* aIncludeStable */ true);
+    }
+}
+
+void Leader::IncrementVersions(const ChangedFlags &aFlags)
+{
+    if (aFlags.DidChange())
+    {
+        IncrementVersions(aFlags.DidStableChange());
+    }
+}
+
+void Leader::IncrementVersions(bool aIncludeStable)
+{
+    if (aIncludeStable)
     {
         mStableVersion++;
     }
-}
 
-uint32_t Leader::GetContextIdReuseDelay(void) const
-{
-    return mContextIdReuseDelay;
-}
-
-void Leader::SetContextIdReuseDelay(uint32_t aDelay)
-{
-    mContextIdReuseDelay = aDelay;
+    mVersion++;
+    Get<ot::Notifier>().Signal(kEventThreadNetdataChanged);
 }
 
 void Leader::RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode)
 {
-    bool rlocIn     = false;
-    bool rlocStable = false;
+    ChangedFlags flags;
 
-    RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength, aMatchMode);
-    VerifyOrExit(rlocIn);
-    RemoveRloc(aRloc16, aMatchMode);
-
-    mVersion++;
-
-    if (rlocStable)
-    {
-        mStableVersion++;
-    }
-
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETDATA);
-
-exit:
-    return;
+    RemoveRloc(aRloc16, aMatchMode, flags);
+    IncrementVersions(flags);
 }
 
 void Leader::HandleServerData(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -148,20 +140,27 @@
 void Leader::HandleServerData(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     ThreadNetworkDataTlv networkData;
-    ThreadRloc16Tlv      rloc16;
+    uint16_t             rloc16;
 
     otLogInfoNetData("Received network data registration");
 
-    if (ThreadTlv::GetTlv(aMessage, ThreadTlv::kRloc16, sizeof(rloc16), rloc16) == OT_ERROR_NONE)
+    VerifyOrExit(aMessageInfo.GetPeerAddr().GetIid().IsRoutingLocator(), OT_NOOP);
+
+    switch (Tlv::FindUint16Tlv(aMessage, ThreadTlv::kRloc16, rloc16))
     {
-        VerifyOrExit(rloc16.IsValid());
-        RemoveBorderRouter(rloc16.GetRloc16(), kMatchModeRloc16);
+    case OT_ERROR_NONE:
+        RemoveBorderRouter(rloc16, kMatchModeRloc16);
+        break;
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        ExitNow();
     }
 
-    if (ThreadTlv::GetTlv(aMessage, ThreadTlv::kThreadNetworkData, sizeof(networkData), networkData) == OT_ERROR_NONE)
+    if (ThreadTlv::FindTlv(aMessage, ThreadTlv::kThreadNetworkData, sizeof(networkData), networkData) == OT_ERROR_NONE)
     {
-        VerifyOrExit(networkData.IsValid());
-        RegisterNetworkData(HostSwap16(aMessageInfo.mPeerAddr.mFields.m16[7]), networkData.GetTlvs(),
+        VerifyOrExit(networkData.IsValid(), OT_NOOP);
+        RegisterNetworkData(aMessageInfo.GetPeerAddr().GetIid().GetLocator(), networkData.GetTlvs(),
                             networkData.GetLength());
     }
 
@@ -188,12 +187,13 @@
     bool                     hasSessionId = false;
     bool                     hasValidTlv  = false;
     uint16_t                 sessionId    = 0;
+    CommissioningDataTlv *   commDataTlv;
 
     MeshCoP::Tlv *cur;
     MeshCoP::Tlv *end;
 
-    VerifyOrExit(length <= sizeof(tlvs));
-    VerifyOrExit(Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER);
+    VerifyOrExit(length <= sizeof(tlvs), OT_NOOP);
+    VerifyOrExit(Get<Mle::MleRouter>().IsLeader(), OT_NOOP);
 
     aMessage.Read(offset, length, tlvs);
 
@@ -206,7 +206,7 @@
     {
         MeshCoP::Tlv::Type type;
 
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
+        VerifyOrExit(((cur + 1) <= end) && !cur->IsExtended() && (cur->GetNext() <= end), OT_NOOP);
 
         type = cur->GetType();
 
@@ -222,7 +222,7 @@
         {
             MeshCoP::CommissionerSessionIdTlv *tlv = static_cast<MeshCoP::CommissionerSessionIdTlv *>(cur);
 
-            VerifyOrExit(tlv->IsValid());
+            VerifyOrExit(tlv->IsValid(), OT_NOOP);
             sessionId    = tlv->GetCommissionerSessionId();
             hasSessionId = true;
         }
@@ -235,44 +235,43 @@
     }
 
     // verify whether or not commissioner session id TLV is included
-    VerifyOrExit(hasSessionId);
+    VerifyOrExit(hasSessionId, OT_NOOP);
 
     // verify whether or not MGMT_COMM_SET.req includes at least one valid TLV
-    VerifyOrExit(hasValidTlv);
+    VerifyOrExit(hasValidTlv, OT_NOOP);
 
     // Find Commissioning Data TLV
-    for (NetworkDataTlv *netDataTlv = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         netDataTlv < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); netDataTlv = netDataTlv->GetNext())
+    commDataTlv = GetCommissioningData();
+
+    if (commDataTlv != nullptr)
     {
-        if (netDataTlv->GetType() == NetworkDataTlv::kTypeCommissioningData)
+        // Iterate over MeshCoP TLVs and extract desired data
+        for (cur = reinterpret_cast<MeshCoP::Tlv *>(commDataTlv->GetValue());
+             cur < reinterpret_cast<MeshCoP::Tlv *>(commDataTlv->GetValue() + commDataTlv->GetLength());
+             cur = cur->GetNext())
         {
-            // Iterate over MeshCoP TLVs and extract desired data
-            for (cur = reinterpret_cast<MeshCoP::Tlv *>(netDataTlv->GetValue());
-                 cur < reinterpret_cast<MeshCoP::Tlv *>(netDataTlv->GetValue() + netDataTlv->GetLength());
-                 cur = cur->GetNext())
+            if (cur->GetType() == MeshCoP::Tlv::kCommissionerSessionId)
             {
-                if (cur->GetType() == MeshCoP::Tlv::kCommissionerSessionId)
-                {
-                    VerifyOrExit(sessionId ==
-                                 static_cast<MeshCoP::CommissionerSessionIdTlv *>(cur)->GetCommissionerSessionId());
-                }
-                else if (cur->GetType() == MeshCoP::Tlv::kBorderAgentLocator)
-                {
-                    VerifyOrExit(length + cur->GetSize() <= sizeof(tlvs));
-                    memcpy(tlvs + length, reinterpret_cast<uint8_t *>(cur), cur->GetSize());
-                    length += cur->GetSize();
-                }
+                VerifyOrExit(sessionId ==
+                                 static_cast<MeshCoP::CommissionerSessionIdTlv *>(cur)->GetCommissionerSessionId(),
+                             OT_NOOP);
+            }
+            else if (cur->GetType() == MeshCoP::Tlv::kBorderAgentLocator)
+            {
+                VerifyOrExit(length + cur->GetSize() <= sizeof(tlvs), OT_NOOP);
+                memcpy(tlvs + length, reinterpret_cast<uint8_t *>(cur), cur->GetSize());
+                length += cur->GetSize();
             }
         }
     }
 
-    SetCommissioningData(tlvs, static_cast<uint8_t>(length));
+    IgnoreError(SetCommissioningData(tlvs, static_cast<uint8_t>(length)));
 
     state = MeshCoP::StateTlv::kAccept;
 
 exit:
 
-    if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER)
+    if (Get<Mle::MleRouter>().IsLeader())
     {
         SendCommissioningSetResponse(aMessage, aMessageInfo, state);
     }
@@ -289,7 +288,7 @@
     uint16_t length = 0;
     uint16_t offset;
 
-    SuccessOrExit(Tlv::GetValueOffset(aMessage, MeshCoP::Tlv::kGet, offset, length));
+    SuccessOrExit(Tlv::FindTlvValueOffset(aMessage, MeshCoP::Tlv::kGet, offset, length));
     aMessage.SetOffset(offset);
 
 exit:
@@ -300,26 +299,23 @@
                                           uint16_t                aLength,
                                           const Ip6::MessageInfo &aMessageInfo)
 {
-    otError        error = OT_ERROR_NONE;
-    Coap::Message *message;
-    uint8_t        index;
-    uint8_t *      data   = NULL;
-    uint8_t        length = 0;
+    otError               error = OT_ERROR_NONE;
+    Coap::Message *       message;
+    CommissioningDataTlv *commDataTlv;
+    uint8_t *             data   = nullptr;
+    uint8_t               length = 0;
 
-    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    for (NetworkDataTlv *cur                                            = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
+    commDataTlv = GetCommissioningData();
+
+    if (commDataTlv != nullptr)
     {
-        if (cur->GetType() == NetworkDataTlv::kTypeCommissioningData)
-        {
-            data   = cur->GetValue();
-            length = cur->GetLength();
-            break;
-        }
+        data   = commDataTlv->GetValue();
+        length = commDataTlv->GetLength();
     }
 
     VerifyOrExit(data && length, error = OT_ERROR_DROP);
@@ -330,7 +326,7 @@
     }
     else
     {
-        for (index = 0; index < aLength; index++)
+        for (uint16_t index = 0; index < aLength; index++)
         {
             uint8_t type;
 
@@ -351,7 +347,7 @@
     if (message->GetLength() == message->GetOffset())
     {
         // no payload, remove coap payload marker
-        message->SetLength(message->GetLength() - 1);
+        IgnoreError(message->SetLength(message->GetLength() - 1));
     }
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo));
@@ -360,7 +356,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -370,18 +366,15 @@
                                           const Ip6::MessageInfo & aMessageInfo,
                                           MeshCoP::StateTlv::State aState)
 {
-    otError           error = OT_ERROR_NONE;
-    Coap::Message *   message;
-    MeshCoP::StateTlv state;
+    otError        error = OT_ERROR_NONE;
+    Coap::Message *message;
 
-    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->SetDefaultResponseHeader(aRequest));
     SuccessOrExit(error = message->SetPayloadMarker());
 
-    state.Init();
-    state.SetState(aState);
-    SuccessOrExit(error = state.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint8Tlv(*message, MeshCoP::Tlv::kState, static_cast<uint8_t>(aState)));
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, aMessageInfo));
 
@@ -389,7 +382,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -413,511 +406,453 @@
     return matched;
 }
 
-otError Leader::RlocLookup(uint16_t  aRloc16,
-                           bool &    aIn,
-                           bool &    aStable,
-                           uint8_t * aTlvs,
-                           uint8_t   aTlvsLength,
-                           MatchMode aMatchMode,
-                           bool      aAllowOtherEntries)
+otError Leader::Validate(const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aRloc16)
 {
-    otError            error = OT_ERROR_NONE;
-    NetworkDataTlv *   cur   = reinterpret_cast<NetworkDataTlv *>(aTlvs);
-    NetworkDataTlv *   end   = reinterpret_cast<NetworkDataTlv *>(aTlvs + aTlvsLength);
-    NetworkDataTlv *   subCur;
-    NetworkDataTlv *   subEnd;
-    PrefixTlv *        prefix;
-    BorderRouterTlv *  borderRouter;
-    HasRouteTlv *      hasRoute;
-    BorderRouterEntry *borderRouterEntry;
-    HasRouteEntry *    hasRouteEntry;
-    ServiceTlv *       service;
-    ServerTlv *        server;
+    // Validate that the `aTlvs` contains well-formed TLVs, sub-TLVs,
+    // and entries all matching `aRloc16` (no other entry for other
+    // RLOCs and no duplicates TLVs).
 
-    while (cur < end)
+    otError               error = OT_ERROR_NONE;
+    const NetworkDataTlv *end   = reinterpret_cast<const NetworkDataTlv *>(aTlvs + aTlvsLength);
+
+    for (const NetworkDataTlv *cur = reinterpret_cast<const NetworkDataTlv *>(aTlvs); cur < end; cur = cur->GetNext())
     {
+        uint8_t offset;
+
         VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
 
+        offset = static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(cur) - aTlvs);
+
         switch (cur->GetType())
         {
         case NetworkDataTlv::kTypePrefix:
         {
-            prefix = static_cast<PrefixTlv *>(cur);
+            const PrefixTlv *prefix = static_cast<const PrefixTlv *>(cur);
+
             VerifyOrExit(prefix->IsValid(), error = OT_ERROR_PARSE);
 
-            subCur = prefix->GetSubTlvs();
-            subEnd = prefix->GetNext();
+            // Ensure there is no duplicate Prefix TLVs with same prefix.
+            VerifyOrExit(FindPrefix(prefix->GetPrefix(), prefix->GetPrefixLength(), aTlvs, offset) == nullptr,
+                         error = OT_ERROR_PARSE);
 
-            VerifyOrExit(subEnd <= end, error = OT_ERROR_PARSE);
-
-            while (subCur < subEnd)
-            {
-                VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
-
-                switch (subCur->GetType())
-                {
-                case NetworkDataTlv::kTypeBorderRouter:
-                    borderRouter = static_cast<BorderRouterTlv *>(subCur);
-
-                    for (uint8_t i = 0; i < borderRouter->GetNumEntries(); i++)
-                    {
-                        borderRouterEntry = borderRouter->GetEntry(i);
-
-                        if (RlocMatch(borderRouterEntry->GetRloc(), aRloc16, aMatchMode))
-                        {
-                            aIn = true;
-
-                            if (borderRouter->IsStable())
-                            {
-                                aStable = true;
-                            }
-                        }
-                        else
-                        {
-                            VerifyOrExit(aAllowOtherEntries, error = OT_ERROR_FAILED);
-                        }
-                    }
-
-                    break;
-
-                case NetworkDataTlv::kTypeHasRoute:
-                    hasRoute = static_cast<HasRouteTlv *>(subCur);
-
-                    for (uint8_t i = 0; i < hasRoute->GetNumEntries(); i++)
-                    {
-                        hasRouteEntry = hasRoute->GetEntry(i);
-
-                        if (RlocMatch(hasRouteEntry->GetRloc(), aRloc16, aMatchMode))
-                        {
-                            aIn = true;
-
-                            if (hasRoute->IsStable())
-                            {
-                                aStable = true;
-                            }
-                        }
-                        else
-                        {
-                            VerifyOrExit(aAllowOtherEntries, error = OT_ERROR_FAILED);
-                        }
-                    }
-
-                    break;
-
-                default:
-                    break;
-                }
-
-                if (aIn && aStable && aAllowOtherEntries)
-                {
-                    ExitNow();
-                }
-
-                subCur = subCur->GetNext();
-            }
+            SuccessOrExit(error = ValidatePrefix(*prefix, aRloc16));
+            break;
         }
-        break;
 
         case NetworkDataTlv::kTypeService:
         {
-            service = static_cast<ServiceTlv *>(cur);
+            const ServiceTlv *service = static_cast<const ServiceTlv *>(cur);
+
             VerifyOrExit(service->IsValid(), error = OT_ERROR_PARSE);
 
-            subCur = service->GetSubTlvs();
-            subEnd = service->GetNext();
+            // Ensure there is no duplicate Service TLV with same
+            // Enterprise Number and Service Data.
+            VerifyOrExit(FindService(service->GetEnterpriseNumber(), service->GetServiceData(),
+                                     service->GetServiceDataLength(), aTlvs, offset) == nullptr,
+                         error = OT_ERROR_PARSE);
 
-            VerifyOrExit(subEnd <= end, error = OT_ERROR_PARSE);
-
-            while (subCur < subEnd)
-            {
-                VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
-
-                switch (subCur->GetType())
-                {
-                case NetworkDataTlv::kTypeServer:
-                    server = static_cast<ServerTlv *>(subCur);
-                    VerifyOrExit(server->IsValid(), error = OT_ERROR_PARSE);
-
-                    if (RlocMatch(server->GetServer16(), aRloc16, aMatchMode))
-                    {
-                        aIn = true;
-
-                        if (server->IsStable())
-                        {
-                            aStable = true;
-                        }
-                    }
-                    else
-                    {
-                        VerifyOrExit(aAllowOtherEntries, error = OT_ERROR_FAILED);
-                    }
-
-                    break;
-
-                default:
-                    break;
-                }
-
-                if (aIn && aStable && aAllowOtherEntries)
-                {
-                    ExitNow();
-                }
-
-                subCur = subCur->GetNext();
-            }
-
+            SuccessOrExit(error = ValidateService(*service, aRloc16));
             break;
         }
 
         default:
             break;
         }
-
-        cur = cur->GetNext();
     }
 
 exit:
     return error;
 }
 
-bool Leader::IsStableUpdated(uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aTlvsBase, uint8_t aTlvsBaseLength)
+otError Leader::ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16)
 {
-    bool            rval = false;
-    NetworkDataTlv *cur  = reinterpret_cast<NetworkDataTlv *>(aTlvs);
-    NetworkDataTlv *end  = reinterpret_cast<NetworkDataTlv *>(aTlvs + aTlvsLength);
-    ServiceTlv *    service;
+    // Validate that `aPrefix` TLV contains well-formed sub-TLVs and
+    // and entries all matching `aRloc16` (no other entry for other
+    // RLOCs).
 
-    while (cur < end)
+    otError               error                   = OT_ERROR_PARSE;
+    const NetworkDataTlv *subEnd                  = aPrefix.GetNext();
+    bool                  foundTempHasRoute       = false;
+    bool                  foundStableHasRoute     = false;
+    bool                  foundTempBorderRouter   = false;
+    bool                  foundStableBorderRouter = false;
+
+    for (const NetworkDataTlv *subCur = aPrefix.GetSubTlvs(); subCur < subEnd; subCur = subCur->GetNext())
     {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
+        VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, OT_NOOP);
 
-        switch (cur->GetType())
+        switch (subCur->GetType())
         {
-        case NetworkDataTlv::kTypePrefix:
+        case NetworkDataTlv::kTypeBorderRouter:
         {
-            PrefixTlv *      prefix       = static_cast<PrefixTlv *>(cur);
-            ContextTlv *     context      = FindContext(*prefix);
-            BorderRouterTlv *borderRouter = FindBorderRouter(*prefix, true);
-            HasRouteTlv *    hasRoute     = FindHasRoute(*prefix, true);
+            const BorderRouterTlv *borderRouter = static_cast<const BorderRouterTlv *>(subCur);
 
-            if (cur->IsStable() && (!context || borderRouter))
+            // Ensure Prefix TLV contains at most one stable and one
+            // temporary Border Router sub-TLV and the sub-TLVs have
+            // a single entry.
+
+            if (borderRouter->IsStable())
             {
-                PrefixTlv *prefixBase =
-                    FindPrefix(prefix->GetPrefix(), prefix->GetPrefixLength(), aTlvsBase, aTlvsBaseLength);
-
-                if (!prefixBase)
-                {
-                    ExitNow(rval = true);
-                }
-
-                if (borderRouter)
-                {
-                    BorderRouterTlv *borderRouterBase = FindBorderRouter(*prefixBase, true);
-
-                    if (!borderRouterBase || (borderRouter->GetLength() != borderRouterBase->GetLength()) ||
-                        (memcmp(borderRouter, borderRouterBase, borderRouter->GetLength()) != 0))
-                    {
-                        ExitNow(rval = true);
-                    }
-                }
-
-                if (hasRoute)
-                {
-                    HasRouteTlv *hasRouteBase = FindHasRoute(*prefixBase, true);
-
-                    if (!hasRouteBase || (hasRoute->GetLength() != hasRouteBase->GetLength()) ||
-                        (memcmp(hasRoute, hasRouteBase, hasRoute->GetLength()) != 0))
-                    {
-                        ExitNow(rval = true);
-                    }
-                }
+                VerifyOrExit(!foundStableBorderRouter, OT_NOOP);
+                foundStableBorderRouter = true;
+            }
+            else
+            {
+                VerifyOrExit(!foundTempBorderRouter, OT_NOOP);
+                foundTempBorderRouter = true;
             }
 
+            VerifyOrExit(borderRouter->GetFirstEntry() == borderRouter->GetLastEntry(), OT_NOOP);
+            VerifyOrExit(borderRouter->GetFirstEntry()->GetRloc() == aRloc16, OT_NOOP);
             break;
         }
 
-        case NetworkDataTlv::kTypeService:
-            service = static_cast<ServiceTlv *>(cur);
+        case NetworkDataTlv::kTypeHasRoute:
+        {
+            const HasRouteTlv *hasRoute = static_cast<const HasRouteTlv *>(subCur);
 
-            if (cur->IsStable())
+            // Ensure Prefix TLV contains at most one stable and one
+            // temporary Has Route sub-TLV and the sub-TLVs have a
+            // single entry.
+
+            if (hasRoute->IsStable())
             {
-                NetworkDataTlv *curInner;
-                NetworkDataTlv *endInner;
-
-                ServiceTlv *serviceBase = FindService(service->GetEnterpriseNumber(), service->GetServiceData(),
-                                                      service->GetServiceDataLength(), aTlvsBase, aTlvsBaseLength);
-
-                if (!serviceBase || !serviceBase->IsStable())
-                {
-                    ExitNow(rval = true);
-                }
-
-                curInner = service->GetSubTlvs();
-                endInner = service->GetNext();
-
-                while (curInner < endInner)
-                {
-                    if (curInner->IsStable())
-                    {
-                        switch (curInner->GetType())
-                        {
-                        case NetworkDataTlv::kTypeServer:
-                        {
-                            bool       foundInBase = false;
-                            ServerTlv *server      = static_cast<ServerTlv *>(curInner);
-
-                            NetworkDataTlv *curServerBase = serviceBase->GetSubTlvs();
-                            NetworkDataTlv *endServerBase = serviceBase->GetNext();
-
-                            while (curServerBase <= endServerBase)
-                            {
-                                ServerTlv *serverBase = static_cast<ServerTlv *>(curServerBase);
-
-                                VerifyOrExit((curServerBase + 1) <= endServerBase && curServerBase->GetNext() <= end);
-
-                                if (curServerBase->IsStable() && (server->GetServer16() == serverBase->GetServer16()) &&
-                                    (server->GetServerDataLength() == serverBase->GetServerDataLength()) &&
-                                    (memcmp(server->GetServerData(), serverBase->GetServerData(),
-                                            server->GetServerDataLength()) == 0))
-                                {
-                                    foundInBase = true;
-                                    break;
-                                }
-
-                                curServerBase = curServerBase->GetNext();
-                            }
-
-                            if (!foundInBase)
-                            {
-                                ExitNow(rval = true);
-                            }
-
-                            break;
-                        }
-
-                        default:
-                            break;
-                        }
-                    }
-
-                    curInner = curInner->GetNext();
-                }
+                VerifyOrExit(!foundStableHasRoute, OT_NOOP);
+                foundStableHasRoute = true;
+            }
+            else
+            {
+                VerifyOrExit(!foundTempHasRoute, OT_NOOP);
+                foundTempHasRoute = true;
             }
 
+            VerifyOrExit(hasRoute->GetFirstEntry() == hasRoute->GetLastEntry(), OT_NOOP);
+            VerifyOrExit(hasRoute->GetFirstEntry()->GetRloc() == aRloc16, OT_NOOP);
             break;
+        }
 
         default:
             break;
         }
-
-        cur = cur->GetNext();
     }
 
-exit:
-    return rval;
-}
-
-otError Leader::RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aTlvsLength)
-{
-    otError error         = OT_ERROR_NONE;
-    bool    rlocIn        = false;
-    bool    rlocStable    = false;
-    bool    stableUpdated = false;
-    bool    unused;
-    uint8_t oldTlvs[NetworkData::kMaxSize];
-    uint8_t oldTlvsLength = NetworkData::kMaxSize;
-
-    // Verify that `aTlvs` only contains entries matching `aRloc16`.
-    SuccessOrExit(error = RlocLookup(aRloc16, rlocIn, rlocStable, aTlvs, aTlvsLength, kMatchModeRloc16,
-                                     /* aAllowOtherEntries */ false));
-
-    RlocLookup(aRloc16, rlocIn, unused, mTlvs, mLength, kMatchModeRloc16);
-
-    if (rlocIn)
+    if (foundStableBorderRouter || foundTempBorderRouter || foundStableHasRoute || foundTempHasRoute)
     {
-        if (IsStableUpdated(aTlvs, aTlvsLength, mTlvs, mLength) || IsStableUpdated(mTlvs, mLength, aTlvs, aTlvsLength))
-        {
-            stableUpdated = true;
-        }
-
-        // Store old Service IDs for given rloc16, so updates to server will reuse the same Service ID
-        SuccessOrExit(error = GetNetworkData(false, oldTlvs, oldTlvsLength));
-
-        RemoveRloc(aRloc16, kMatchModeRloc16);
-        SuccessOrExit(error = AddNetworkData(aTlvs, aTlvsLength, oldTlvs, oldTlvsLength));
-
-        mVersion++;
-
-        if (stableUpdated)
-        {
-            mStableVersion++;
-        }
+        error = OT_ERROR_NONE;
     }
-    else
-    {
-        // No old data to be preserved, lets avoid memcpy() & FindService calls.
-        SuccessOrExit(error = AddNetworkData(aTlvs, aTlvsLength, oldTlvs, 0));
-
-        mVersion++;
-
-        if (rlocStable)
-        {
-            mStableVersion++;
-        }
-    }
-
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETDATA);
 
 exit:
     return error;
 }
 
-otError Leader::AddNetworkData(uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aOldTlvs, uint8_t aOldTlvsLength)
+otError Leader::ValidateService(const ServiceTlv &aService, uint16_t aRloc16)
 {
-    otError         error = OT_ERROR_NONE;
-    NetworkDataTlv *cur   = reinterpret_cast<NetworkDataTlv *>(aTlvs);
-    NetworkDataTlv *end   = reinterpret_cast<NetworkDataTlv *>(aTlvs + aTlvsLength);
+    // Validate that `aService` TLV contains a single well-formed
+    // Server sub-TLV associated with `aRloc16`.
 
-    while (cur < end)
+    otError               error       = OT_ERROR_PARSE;
+    const NetworkDataTlv *subEnd      = aService.GetNext();
+    bool                  foundServer = false;
+
+    for (const NetworkDataTlv *subCur = aService.GetSubTlvs(); subCur < subEnd; subCur = subCur->GetNext())
     {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
+        VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, OT_NOOP);
 
+        switch (subCur->GetType())
+        {
+        case NetworkDataTlv::kTypeServer:
+        {
+            const ServerTlv *server = static_cast<const ServerTlv *>(subCur);
+
+            VerifyOrExit(!foundServer, OT_NOOP);
+            foundServer = true;
+
+            VerifyOrExit(server->IsValid() && server->GetServer16() == aRloc16, OT_NOOP);
+            break;
+        }
+
+        default:
+            break;
+        }
+    }
+
+    if (foundServer)
+    {
+        error = OT_ERROR_NONE;
+    }
+
+exit:
+    return error;
+}
+
+bool Leader::ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry)
+{
+    // Check whether `aPrefix` has a Has Route sub-TLV with stable
+    // flag `aStable` containing a matching entry to `aEntry`.
+
+    return (aPrefix == nullptr) ? false : ContainsMatchingEntry(FindHasRoute(*aPrefix, aStable), aEntry);
+}
+
+bool Leader::ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry)
+{
+    // Check whether `aHasRoute` has a matching entry to `aEntry`.
+
+    bool contains = false;
+
+    VerifyOrExit(aHasRoute != nullptr, OT_NOOP);
+
+    for (const HasRouteEntry *entry = aHasRoute->GetFirstEntry(); entry <= aHasRoute->GetLastEntry(); entry++)
+    {
+        if (*entry == aEntry)
+        {
+            contains = true;
+            break;
+        }
+    }
+
+exit:
+    return contains;
+}
+
+bool Leader::ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry)
+{
+    // Check whether `aPrefix` has a Border Router sub-TLV with stable
+    // flag `aStable` containing a matching entry to `aEntry`.
+
+    return (aPrefix == nullptr) ? false : ContainsMatchingEntry(FindBorderRouter(*aPrefix, aStable), aEntry);
+}
+
+bool Leader::ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry)
+{
+    // Check whether `aBorderRouter` has a matching entry to `aEntry`.
+
+    bool contains = false;
+
+    VerifyOrExit(aBorderRouter != nullptr, OT_NOOP);
+
+    for (const BorderRouterEntry *entry = aBorderRouter->GetFirstEntry(); entry <= aBorderRouter->GetLastEntry();
+         entry++)
+    {
+        if (*entry == aEntry)
+        {
+            contains = true;
+            break;
+        }
+    }
+
+exit:
+    return contains;
+}
+
+bool Leader::ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer)
+{
+    // Check whether the `aService` has a matching Server sub-TLV
+    // same as `aServer`.
+
+    bool             contains = false;
+    const ServerTlv *server;
+
+    VerifyOrExit(aService != nullptr, OT_NOOP);
+
+    for (const NetworkDataTlv *start = aService->GetSubTlvs();
+         (server = FindTlv<ServerTlv>(start, aService->GetNext(), aServer.IsStable())) != nullptr;
+         start = server->GetNext())
+    {
+        if (*server == aServer)
+        {
+            ExitNow(contains = true);
+        }
+    }
+
+exit:
+    return contains;
+}
+
+Leader::UpdateStatus Leader::UpdatePrefix(PrefixTlv &aPrefix)
+{
+    return UpdateTlv(aPrefix, aPrefix.GetSubTlvs());
+}
+
+Leader::UpdateStatus Leader::UpdateService(ServiceTlv &aService)
+{
+    return UpdateTlv(aService, aService.GetSubTlvs());
+}
+
+Leader::UpdateStatus Leader::UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs)
+{
+    // If `aTlv` contains no sub-TLVs, remove it from Network Data,
+    // otherwise update its stable flag based on its sub-TLVs.
+
+    UpdateStatus status = kTlvUpdated;
+
+    if (aSubTlvs == aTlv.GetNext())
+    {
+        RemoveTlv(&aTlv);
+        ExitNow(status = kTlvRemoved);
+    }
+
+    for (const NetworkDataTlv *subCur = aSubTlvs; subCur < aTlv.GetNext(); subCur = subCur->GetNext())
+    {
+        if (subCur->IsStable())
+        {
+            aTlv.SetStable();
+            ExitNow();
+        }
+    }
+
+    aTlv.ClearStable();
+
+exit:
+    return status;
+}
+
+void Leader::RegisterNetworkData(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t aTlvsLength)
+{
+    otError               error = OT_ERROR_NONE;
+    const NetworkDataTlv *end   = reinterpret_cast<const NetworkDataTlv *>(aTlvs + aTlvsLength);
+    ChangedFlags          flags;
+
+    VerifyOrExit(Get<RouterTable>().IsAllocated(Mle::Mle::RouterIdFromRloc16(aRloc16)), error = OT_ERROR_NO_ROUTE);
+
+    // Validate that the `aTlvs` contains well-formed TLVs, sub-TLVs,
+    // and entries all matching `aRloc16` (no other RLOCs).
+    SuccessOrExit(error = Validate(aTlvs, aTlvsLength, aRloc16));
+
+    // Remove all entries matching `aRloc16` excluding entries that are
+    // present in `aTlvs`
+    RemoveRloc(aRloc16, kMatchModeRloc16, aTlvs, aTlvsLength, flags);
+
+    // Now add all new entries in `aTlvs` to Network Data.
+    for (const NetworkDataTlv *cur = reinterpret_cast<const NetworkDataTlv *>(aTlvs); cur < end; cur = cur->GetNext())
+    {
         switch (cur->GetType())
         {
         case NetworkDataTlv::kTypePrefix:
-            SuccessOrExit(error = AddPrefix(*static_cast<PrefixTlv *>(cur)));
-            otDumpDebgNetData("add prefix done", mTlvs, mLength);
+            SuccessOrExit(error = AddPrefix(*static_cast<const PrefixTlv *>(cur), flags));
             break;
 
         case NetworkDataTlv::kTypeService:
-            SuccessOrExit(error = AddService(*static_cast<ServiceTlv *>(cur), aOldTlvs, aOldTlvsLength));
-            otDumpDebgNetData("add service done", mTlvs, mLength);
+            SuccessOrExit(error = AddService(*static_cast<const ServiceTlv *>(cur), flags));
             break;
 
         default:
             break;
         }
-
-        cur = cur->GetNext();
     }
 
+    IncrementVersions(flags);
+
     otDumpDebgNetData("add done", mTlvs, mLength);
 
 exit:
-    return error;
+
+    if (error != OT_ERROR_NONE)
+    {
+        otLogNoteNetData("Failed to register network data: %s", otThreadErrorToString(error));
+    }
 }
 
-otError Leader::AddPrefix(PrefixTlv &aPrefix)
+otError Leader::AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags)
 {
-    otError         error = OT_ERROR_NONE;
-    NetworkDataTlv *cur;
-    NetworkDataTlv *end;
+    otError    error     = OT_ERROR_NONE;
+    PrefixTlv *dstPrefix = FindPrefix(aPrefix.GetPrefix(), aPrefix.GetPrefixLength());
 
-    VerifyOrExit(aPrefix.IsValid(), error = OT_ERROR_PARSE);
-    cur = aPrefix.GetSubTlvs();
-    end = aPrefix.GetNext();
-
-    while (cur < end)
+    if (dstPrefix == nullptr)
     {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
+        dstPrefix = static_cast<PrefixTlv *>(AppendTlv(PrefixTlv::CalculateSize(aPrefix.GetPrefixLength())));
+        VerifyOrExit(dstPrefix != nullptr, error = OT_ERROR_NO_BUFS);
 
-        switch (cur->GetType())
-        {
-        case NetworkDataTlv::kTypeHasRoute:
-            SuccessOrExit(error = AddHasRoute(aPrefix, *static_cast<HasRouteTlv *>(cur)));
-            break;
-
-        case NetworkDataTlv::kTypeBorderRouter:
-            SuccessOrExit(error = AddBorderRouter(aPrefix, *static_cast<BorderRouterTlv *>(cur)));
-            break;
-
-        default:
-            break;
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return error;
-}
-
-otError Leader::AddService(ServiceTlv &aService, uint8_t *aOldTlvs, uint8_t aOldTlvsLength)
-{
-    otError         error = OT_ERROR_NONE;
-    NetworkDataTlv *cur;
-    NetworkDataTlv *end;
-
-    VerifyOrExit(aService.IsValid(), error = OT_ERROR_PARSE);
-    cur = aService.GetSubTlvs();
-    end = aService.GetNext();
-
-    while (cur < end)
-    {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
-
-        switch (cur->GetType())
-        {
-        case NetworkDataTlv::kTypeServer:
-            SuccessOrExit(error = AddServer(aService, *static_cast<ServerTlv *>(cur), aOldTlvs, aOldTlvsLength));
-            break;
-
-        default:
-            break;
-        }
-
-        cur = cur->GetNext();
-    }
-
-exit:
-    return error;
-}
-
-otError Leader::AddHasRoute(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute)
-{
-    otError      error        = OT_ERROR_NONE;
-    PrefixTlv *  dstPrefix    = NULL;
-    HasRouteTlv *dstHasRoute  = NULL;
-    uint16_t     appendLength = 0;
-
-    VerifyOrExit(aHasRoute.GetNumEntries() > 0, error = OT_ERROR_PARSE);
-
-    if ((dstPrefix = FindPrefix(aPrefix.GetPrefix(), aPrefix.GetPrefixLength())) != NULL)
-    {
-        dstHasRoute = FindHasRoute(*dstPrefix, aHasRoute.IsStable());
-    }
-
-    if (dstPrefix == NULL)
-    {
-        appendLength += sizeof(PrefixTlv) + BitVectorBytes(aPrefix.GetPrefixLength());
-    }
-
-    if (dstHasRoute == NULL)
-    {
-        appendLength += sizeof(HasRouteTlv);
-    }
-
-    appendLength += sizeof(HasRouteEntry);
-
-    VerifyOrExit(mLength + appendLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS);
-
-    if (dstPrefix == NULL)
-    {
-        dstPrefix = reinterpret_cast<PrefixTlv *>(mTlvs + mLength);
-        Insert(reinterpret_cast<uint8_t *>(dstPrefix), sizeof(PrefixTlv) + BitVectorBytes(aPrefix.GetPrefixLength()));
         dstPrefix->Init(aPrefix.GetDomainId(), aPrefix.GetPrefixLength(), aPrefix.GetPrefix());
     }
 
-    if (aHasRoute.IsStable())
+    for (const NetworkDataTlv *subCur = aPrefix.GetSubTlvs(); subCur < aPrefix.GetNext(); subCur = subCur->GetNext())
     {
-        dstPrefix->SetStable();
+        switch (subCur->GetType())
+        {
+        case NetworkDataTlv::kTypeHasRoute:
+            SuccessOrExit(error = AddHasRoute(*static_cast<const HasRouteTlv *>(subCur), *dstPrefix, aChangedFlags));
+            break;
+
+        case NetworkDataTlv::kTypeBorderRouter:
+            SuccessOrExit(
+                error = AddBorderRouter(*static_cast<const BorderRouterTlv *>(subCur), *dstPrefix, aChangedFlags));
+            break;
+
+        default:
+            break;
+        }
     }
 
-    if (dstHasRoute == NULL)
+exit:
+    if (dstPrefix != nullptr)
     {
-        dstHasRoute = static_cast<HasRouteTlv *>(dstPrefix->GetNext());
-        Insert(reinterpret_cast<uint8_t *>(dstHasRoute), sizeof(HasRouteTlv));
-        dstPrefix->SetLength(dstPrefix->GetLength() + sizeof(HasRouteTlv));
+        // `UpdatePrefix()` updates the TLV's stable flag based on
+        // its sub-TLVs, or removes the TLV if it contains no sub-TLV.
+        // This is called at `exit` to ensure that if appending
+        // sub-TLVs fail (e.g., out of space in network data), we
+        // remove an empty Prefix TLV.
+
+        IgnoreReturnValue(UpdatePrefix(*dstPrefix));
+    }
+
+    return error;
+}
+
+otError Leader::AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags)
+{
+    otError     error = OT_ERROR_NONE;
+    ServiceTlv *dstService =
+        FindService(aService.GetEnterpriseNumber(), aService.GetServiceData(), aService.GetServiceDataLength());
+    const ServerTlv *server;
+
+    if (dstService == nullptr)
+    {
+        uint8_t serviceId;
+
+        SuccessOrExit(error = AllocateServiceId(serviceId));
+
+        dstService = static_cast<ServiceTlv *>(
+            AppendTlv(ServiceTlv::CalculateSize(aService.GetEnterpriseNumber(), aService.GetServiceDataLength())));
+        VerifyOrExit(dstService != nullptr, error = OT_ERROR_NO_BUFS);
+
+        dstService->Init(serviceId, aService.GetEnterpriseNumber(), aService.GetServiceData(),
+                         aService.GetServiceDataLength());
+    }
+
+    server = FindTlv<ServerTlv>(aService.GetSubTlvs(), aService.GetNext());
+    OT_ASSERT(server != nullptr);
+
+    SuccessOrExit(error = AddServer(*server, *dstService, aChangedFlags));
+
+exit:
+    if (dstService != nullptr)
+    {
+        // `UpdateService()` updates the TLV's stable flag based on
+        // its sub-TLVs, or removes the TLV if it contains no sub-TLV.
+        // This is called at `exit` to ensure that if appending
+        // sub-TLVs fail (e.g., out of space in network data), we
+        // remove an empty Service TLV.
+
+        IgnoreReturnValue(UpdateService(*dstService));
+    }
+
+    return error;
+}
+
+otError Leader::AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags)
+{
+    otError              error       = OT_ERROR_NONE;
+    HasRouteTlv *        dstHasRoute = FindHasRoute(aDstPrefix, aHasRoute.IsStable());
+    const HasRouteEntry *entry       = aHasRoute.GetFirstEntry();
+
+    if (dstHasRoute == nullptr)
+    {
+        // Ensure there is space for `HasRouteTlv` and a single entry.
+        VerifyOrExit(CanInsert(sizeof(HasRouteTlv) + sizeof(HasRouteEntry)), error = OT_ERROR_NO_BUFS);
+
+        dstHasRoute = static_cast<HasRouteTlv *>(aDstPrefix.GetNext());
+        Insert(dstHasRoute, sizeof(HasRouteTlv));
+        aDstPrefix.IncreaseLength(sizeof(HasRouteTlv));
         dstHasRoute->Init();
 
         if (aHasRoute.IsStable())
@@ -926,244 +861,180 @@
         }
     }
 
-    Insert(reinterpret_cast<uint8_t *>(dstHasRoute->GetNext()), sizeof(HasRouteEntry));
-    dstHasRoute->SetLength(dstHasRoute->GetLength() + sizeof(HasRouteEntry));
-    dstPrefix->SetLength(dstPrefix->GetLength() + sizeof(HasRouteEntry));
-    memcpy(dstHasRoute->GetEntry(dstHasRoute->GetNumEntries() - 1), aHasRoute.GetEntry(0), sizeof(HasRouteEntry));
+    VerifyOrExit(!ContainsMatchingEntry(dstHasRoute, *entry), OT_NOOP);
+
+    VerifyOrExit(CanInsert(sizeof(HasRouteEntry)), error = OT_ERROR_NO_BUFS);
+
+    Insert(dstHasRoute->GetNext(), sizeof(HasRouteEntry));
+    dstHasRoute->IncreaseLength(sizeof(HasRouteEntry));
+    aDstPrefix.IncreaseLength(sizeof(HasRouteEntry));
+
+    *dstHasRoute->GetLastEntry() = *entry;
+    aChangedFlags.Update(*dstHasRoute);
 
 exit:
     return error;
 }
 
-otError Leader::AddServer(ServiceTlv &aService, ServerTlv &aServer, uint8_t *aOldTlvs, uint8_t aOldTlvsLength)
+otError Leader::AddBorderRouter(const BorderRouterTlv &aBorderRouter,
+                                PrefixTlv &            aDstPrefix,
+                                ChangedFlags &         aChangedFlags)
 {
-    otError     error               = OT_ERROR_NONE;
-    ServiceTlv *dstService          = NULL;
-    ServiceTlv *oldService          = NULL;
-    ServerTlv * dstServer           = NULL;
-    uint16_t    appendLength        = 0;
-    uint8_t     serviceID           = 0;
-    uint8_t     serviceInsertLength = sizeof(ServiceTlv) + sizeof(uint8_t) /*mServiceDataLength*/ +
-                                  ServiceTlv::GetEnterpriseNumberFieldLength(aService.GetEnterpriseNumber()) +
-                                  aService.GetServiceDataLength();
+    otError                  error           = OT_ERROR_NONE;
+    BorderRouterTlv *        dstBorderRouter = FindBorderRouter(aDstPrefix, aBorderRouter.IsStable());
+    ContextTlv *             dstContext      = FindContext(aDstPrefix);
+    uint8_t                  contextId       = 0;
+    const BorderRouterEntry *entry           = aBorderRouter.GetFirstEntry();
 
-    dstService =
-        FindService(aService.GetEnterpriseNumber(), aService.GetServiceData(), aService.GetServiceDataLength());
-
-    if (dstService == NULL)
+    if (dstContext == nullptr)
     {
-        appendLength += serviceInsertLength;
+        // Allocate a Context ID first. This ensure that if we cannot
+        // allocate, we fail and exit before potentially inserting a
+        // Border Router sub-TLV.
+        SuccessOrExit(error = AllocateContextId(contextId));
     }
 
-    appendLength += sizeof(ServerTlv) + aServer.GetServerDataLength();
-
-    VerifyOrExit(mLength + appendLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS);
-
-    if (dstService == NULL)
+    if (dstBorderRouter == nullptr)
     {
-        // Try to preserve old Service ID, if existing
-        oldService = FindService(aService.GetEnterpriseNumber(), aService.GetServiceData(),
-                                 aService.GetServiceDataLength(), aOldTlvs, aOldTlvsLength);
+        // Ensure there is space for `BorderRouterTlv` with a single entry
+        // and a `ContextTlv` (if not already present).
+        VerifyOrExit(CanInsert(sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry) +
+                               ((dstContext == nullptr) ? sizeof(ContextTlv) : 0)),
+                     error = OT_ERROR_NO_BUFS);
 
-        if (oldService != NULL)
+        dstBorderRouter = static_cast<BorderRouterTlv *>(aDstPrefix.GetNext());
+        Insert(dstBorderRouter, sizeof(BorderRouterTlv));
+        aDstPrefix.IncreaseLength(sizeof(BorderRouterTlv));
+        dstBorderRouter->Init();
+
+        if (aBorderRouter.IsStable())
         {
-            // The same service is not found in current data, but was in old data. So, it had to be just removed by
-            // RemoveRloc() Lets use the same ServiceID
-            serviceID = oldService->GetServiceID();
+            dstBorderRouter->SetStable();
         }
-        else
-        {
-            uint8_t i;
-
-            // This seems like completely new service. Lets try to find new ServiceID for it. If all are taken, error
-            // out. Since we call FindServiceById() on mTlv, we need to execute this before Insert() call, otherwise
-            // we'll find uninitialized service as well.
-            for (i = Mle::kServiceMinId; i <= Mle::kServiceMaxId; i++)
-            {
-                if (FindServiceById(i) == NULL)
-                {
-                    serviceID = i;
-                    break;
-                }
-            }
-
-            otLogInfoNetData("Allocated Service ID = %d", i);
-
-            VerifyOrExit(i <= Mle::kServiceMaxId, error = OT_ERROR_NO_BUFS);
-        }
-
-        dstService = reinterpret_cast<ServiceTlv *>(mTlvs + mLength);
-        Insert(reinterpret_cast<uint8_t *>(dstService), serviceInsertLength);
-        dstService->Init();
-        dstService->SetServiceID(serviceID);
-        dstService->SetEnterpriseNumber(aService.GetEnterpriseNumber());
-        dstService->SetServiceData(aService.GetServiceData(), aService.GetServiceDataLength());
-        dstService->SetLength(serviceInsertLength - sizeof(NetworkDataTlv));
     }
 
-    dstServer = static_cast<ServerTlv *>(dstService->GetNext());
-
-    Insert(reinterpret_cast<uint8_t *>(dstServer), sizeof(ServerTlv) + aServer.GetServerDataLength());
-    dstServer->Init();
-    dstServer->SetServer16(aServer.GetServer16());
-    dstServer->SetServerData(aServer.GetServerData(), aServer.GetServerDataLength());
-
-    if (aServer.IsStable())
+    if (dstContext == nullptr)
     {
-        dstService->SetStable();
-        dstServer->SetStable();
+        // Ensure there is space for a `ContextTlv` and a single entry.
+        VerifyOrExit(CanInsert(sizeof(BorderRouterEntry) + sizeof(ContextTlv)), error = OT_ERROR_NO_BUFS);
+
+        dstContext = static_cast<ContextTlv *>(aDstPrefix.GetNext());
+        Insert(dstContext, sizeof(ContextTlv));
+        aDstPrefix.IncreaseLength(sizeof(ContextTlv));
+        dstContext->Init(static_cast<uint8_t>(contextId), aDstPrefix.GetPrefixLength());
     }
 
-    dstService->SetLength(dstService->GetLength() + sizeof(ServerTlv) + aServer.GetServerDataLength());
-
-exit:
-    return error;
-}
-
-ServiceTlv *Leader::FindServiceById(uint8_t aServiceId)
-{
-    NetworkDataTlv *cur     = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-    NetworkDataTlv *end     = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
-    ServiceTlv *    compare = NULL;
-
-    while (cur < end)
+    if (aBorderRouter.IsStable())
     {
-        VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
-
-        if (cur->GetType() == NetworkDataTlv::kTypeService)
-        {
-            compare = static_cast<ServiceTlv *>(cur);
-
-            if (compare->GetServiceID() == aServiceId)
-            {
-                ExitNow();
-            }
-        }
-
-        cur = cur->GetNext();
-    }
-
-    compare = NULL;
-
-exit:
-    return compare;
-}
-
-otError Leader::AddBorderRouter(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter)
-{
-    otError          error           = OT_ERROR_NONE;
-    PrefixTlv *      dstPrefix       = NULL;
-    ContextTlv *     dstContext      = NULL;
-    BorderRouterTlv *dstBorderRouter = NULL;
-    int              contextId       = -1;
-    uint16_t         appendLength    = 0;
-
-    VerifyOrExit(aBorderRouter.GetNumEntries() > 0, error = OT_ERROR_PARSE);
-
-    if ((dstPrefix = FindPrefix(aPrefix.GetPrefix(), aPrefix.GetPrefixLength())) != NULL)
-    {
-        dstContext      = FindContext(*dstPrefix);
-        dstBorderRouter = FindBorderRouter(*dstPrefix, aBorderRouter.IsStable());
-    }
-
-    if (dstPrefix == NULL)
-    {
-        appendLength += sizeof(PrefixTlv) + BitVectorBytes(aPrefix.GetPrefixLength());
-    }
-
-    if (dstContext == NULL)
-    {
-        appendLength += sizeof(ContextTlv);
-    }
-
-    if (dstBorderRouter == NULL)
-    {
-        appendLength += sizeof(BorderRouterTlv);
-    }
-
-    appendLength += sizeof(BorderRouterEntry);
-
-    VerifyOrExit(mLength + appendLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS);
-
-    if (dstContext == NULL)
-    {
-        contextId = AllocateContext();
-        VerifyOrExit(contextId >= 0, error = OT_ERROR_NO_BUFS);
-    }
-
-    if (dstPrefix == NULL)
-    {
-        dstPrefix = reinterpret_cast<PrefixTlv *>(mTlvs + mLength);
-        Insert(reinterpret_cast<uint8_t *>(dstPrefix), sizeof(PrefixTlv) + BitVectorBytes(aPrefix.GetPrefixLength()));
-        dstPrefix->Init(aPrefix.GetDomainId(), aPrefix.GetPrefixLength(), aPrefix.GetPrefix());
-    }
-
-    if (dstContext == NULL)
-    {
-        dstContext = static_cast<ContextTlv *>(dstPrefix->GetNext());
-        Insert(reinterpret_cast<uint8_t *>(dstContext), sizeof(ContextTlv));
-        dstPrefix->SetLength(dstPrefix->GetLength() + sizeof(ContextTlv));
-        dstContext->Init();
-        dstContext->SetCompress();
-        dstContext->SetContextId(static_cast<uint8_t>(contextId));
-        dstContext->SetContextLength(aPrefix.GetPrefixLength());
+        dstContext->SetStable();
     }
 
     dstContext->SetCompress();
     StopContextReuseTimer(dstContext->GetContextId());
 
-    if (dstBorderRouter == NULL)
-    {
-        dstBorderRouter = static_cast<BorderRouterTlv *>(dstPrefix->GetNext());
-        Insert(reinterpret_cast<uint8_t *>(dstBorderRouter), sizeof(BorderRouterTlv));
-        dstPrefix->SetLength(dstPrefix->GetLength() + sizeof(BorderRouterTlv));
-        dstBorderRouter->Init();
-    }
+    VerifyOrExit(!ContainsMatchingEntry(dstBorderRouter, *entry), OT_NOOP);
 
-    Insert(reinterpret_cast<uint8_t *>(dstBorderRouter->GetNext()), sizeof(BorderRouterEntry));
-    dstBorderRouter->SetLength(dstBorderRouter->GetLength() + sizeof(BorderRouterEntry));
-    dstPrefix->SetLength(dstPrefix->GetLength() + sizeof(BorderRouterEntry));
-    memcpy(dstBorderRouter->GetEntry(dstBorderRouter->GetNumEntries() - 1), aBorderRouter.GetEntry(0),
-           sizeof(BorderRouterEntry));
+    VerifyOrExit(CanInsert(sizeof(BorderRouterEntry)), error = OT_ERROR_NO_BUFS);
 
-    if (aBorderRouter.IsStable())
-    {
-        dstPrefix->SetStable();
-        dstContext->SetStable();
-        dstBorderRouter->SetStable();
-    }
+    Insert(dstBorderRouter->GetNext(), sizeof(BorderRouterEntry));
+    dstBorderRouter->IncreaseLength(sizeof(BorderRouterEntry));
+    aDstPrefix.IncreaseLength(sizeof(BorderRouterEntry));
+    *dstBorderRouter->GetLastEntry() = *entry;
+    aChangedFlags.Update(*dstBorderRouter);
 
 exit:
     return error;
 }
 
-int Leader::AllocateContext(void)
+otError Leader::AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags)
 {
-    int rval = -1;
+    otError    error = OT_ERROR_NONE;
+    ServerTlv *dstServer;
+    uint8_t    tlvSize = aServer.GetSize();
 
-    for (int i = kMinContextId; i < kMinContextId + kNumContextIds; i++)
+    VerifyOrExit(!ContainsMatchingServer(&aDstService, aServer), OT_NOOP);
+
+    VerifyOrExit(CanInsert(tlvSize), error = OT_ERROR_NO_BUFS);
+
+    dstServer = static_cast<ServerTlv *>(aDstService.GetNext());
+    Insert(dstServer, tlvSize);
+    dstServer->Init(aServer.GetServer16(), aServer.GetServerData(), aServer.GetServerDataLength());
+
+    if (aServer.IsStable())
     {
-        if ((mContextUsed & (1 << i)) == 0)
+        dstServer->SetStable();
+    }
+
+    aDstService.IncreaseLength(tlvSize);
+    aChangedFlags.Update(*dstServer);
+
+exit:
+    return error;
+}
+
+otError Leader::AllocateServiceId(uint8_t &aServiceId)
+{
+    otError error = OT_ERROR_NOT_FOUND;
+    uint8_t serviceId;
+
+    for (serviceId = Mle::kServiceMinId; serviceId <= Mle::kServiceMaxId; serviceId++)
+    {
+        if (FindServiceById(serviceId) == nullptr)
         {
-            mContextUsed |= 1 << i;
-            rval = i;
-            otLogInfoNetData("Allocated Context ID = %d", rval);
-            ExitNow();
+            aServiceId = serviceId;
+            error      = OT_ERROR_NONE;
+            otLogInfoNetData("Allocated Service ID = %d", serviceId);
+            break;
         }
     }
 
-exit:
-    return rval;
+    return error;
 }
 
-void Leader::FreeContext(uint8_t aContextId)
+const ServiceTlv *Leader::FindServiceById(uint8_t aServiceId) const
+{
+    const NetworkDataTlv *start = GetTlvsStart();
+    const ServiceTlv *    service;
+
+    while ((service = FindTlv<ServiceTlv>(start, GetTlvsEnd())) != nullptr)
+    {
+        if (service->GetServiceId() == aServiceId)
+        {
+            ExitNow();
+        }
+
+        start = service->GetNext();
+    }
+
+exit:
+    return service;
+}
+
+otError Leader::AllocateContextId(uint8_t &aContextId)
+{
+    otError error = OT_ERROR_NOT_FOUND;
+
+    for (uint8_t contextId = kMinContextId; contextId < kMinContextId + kNumContextIds; contextId++)
+    {
+        if ((mContextUsed & (1 << contextId)) == 0)
+        {
+            mContextUsed |= (1 << contextId);
+            aContextId = contextId;
+            error      = OT_ERROR_NONE;
+            otLogInfoNetData("Allocated Context ID = %d", contextId);
+            break;
+        }
+    }
+
+    return error;
+}
+
+void Leader::FreeContextId(uint8_t aContextId)
 {
     otLogInfoNetData("Free Context Id = %d", aContextId);
     RemoveContext(aContextId);
     mContextUsed &= ~(1 << aContextId);
-    mVersion++;
-    mStableVersion++;
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETDATA);
+    IncrementVersions(/* aIncludeStable */ true);
 }
 
 void Leader::StartContextReuseTimer(uint8_t aContextId)
@@ -1183,68 +1054,61 @@
     mContextLastUsed[aContextId - kMinContextId].SetValue(0);
 }
 
-otError Leader::SendServerDataNotification(uint16_t aRloc16)
+void Leader::RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags)
 {
-    otError error      = OT_ERROR_NONE;
-    bool    rlocIn     = false;
-    bool    rlocStable = false;
-
-    RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength, kMatchModeRloc16);
-
-    VerifyOrExit(rlocIn, error = OT_ERROR_NOT_FOUND);
-
-    SuccessOrExit(error = NetworkData::SendServerDataNotification(aRloc16));
-
-exit:
-    return error;
+    RemoveRloc(aRloc16, aMatchMode, nullptr, 0, aChangedFlags);
 }
 
-void Leader::RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode)
+void Leader::RemoveRloc(uint16_t       aRloc16,
+                        MatchMode      aMatchMode,
+                        const uint8_t *aExcludeTlvs,
+                        uint8_t        aExcludeTlvsLength,
+                        ChangedFlags & aChangedFlags)
 {
-    NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-    NetworkDataTlv *end;
-    PrefixTlv *     prefix;
-    ServiceTlv *    service;
+    // Remove entries from Network Data matching `aRloc16` (using
+    // `aMatchMode` to determine the match) but exclude any entries
+    // that are present in `aExcludeTlvs`. As entries are removed
+    // update `aChangedFlags` to indicate if Network Data (stable or
+    // not) got changed.
 
-    while (1)
+    NetworkDataTlv *cur = GetTlvsStart();
+
+    while (cur < GetTlvsEnd())
     {
-        end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
-
-        if (cur >= end)
-        {
-            break;
-        }
-
         switch (cur->GetType())
         {
         case NetworkDataTlv::kTypePrefix:
         {
-            prefix = static_cast<PrefixTlv *>(cur);
-            RemoveRloc(*prefix, aRloc16, aMatchMode);
+            PrefixTlv *      prefix = static_cast<PrefixTlv *>(cur);
+            const PrefixTlv *excludePrefix =
+                FindPrefix(prefix->GetPrefix(), prefix->GetPrefixLength(), aExcludeTlvs, aExcludeTlvsLength);
 
-            if (prefix->GetSubTlvsLength() == 0)
+            RemoveRlocInPrefix(*prefix, aRloc16, aMatchMode, excludePrefix, aChangedFlags);
+
+            if (UpdatePrefix(*prefix) == kTlvRemoved)
             {
-                Remove(reinterpret_cast<uint8_t *>(prefix), sizeof(NetworkDataTlv) + prefix->GetLength());
+                // Do not update `cur` when TLV is removed.
                 continue;
             }
 
-            otDumpDebgNetData("remove prefix done", mTlvs, mLength);
             break;
         }
 
         case NetworkDataTlv::kTypeService:
         {
-            service = static_cast<ServiceTlv *>(cur);
-            RemoveRloc(*service, aRloc16, aMatchMode);
+            ServiceTlv *      service = static_cast<ServiceTlv *>(cur);
+            const ServiceTlv *excludeService =
+                FindService(service->GetEnterpriseNumber(), service->GetServiceData(), service->GetServiceDataLength(),
+                            aExcludeTlvs, aExcludeTlvsLength);
 
-            if (service->GetSubTlvsLength() == 0)
+            RemoveRlocInService(*service, aRloc16, aMatchMode, excludeService, aChangedFlags);
+
+            if (UpdateService(*service) == kTlvRemoved)
             {
-                Remove(reinterpret_cast<uint8_t *>(service), sizeof(NetworkDataTlv) + service->GetLength());
+                // Do not update `cur` when TLV is removed.
                 continue;
             }
 
-            otDumpDebgNetData("remove service done", mTlvs, mLength);
-
             break;
         }
 
@@ -1258,44 +1122,43 @@
     otDumpDebgNetData("remove done", mTlvs, mLength);
 }
 
-void Leader::RemoveRloc(PrefixTlv &aPrefix, uint16_t aRloc16, MatchMode aMatchMode)
+void Leader::RemoveRlocInPrefix(PrefixTlv &      aPrefix,
+                                uint16_t         aRloc16,
+                                MatchMode        aMatchMode,
+                                const PrefixTlv *aExcludePrefix,
+                                ChangedFlags &   aChangedFlags)
 {
+    // Remove entries in `aPrefix` TLV matching the given `aRloc16`
+    // excluding any entries that are present in `aExcludePrefix`.
+
     NetworkDataTlv *cur = aPrefix.GetSubTlvs();
-    NetworkDataTlv *end;
     ContextTlv *    context;
 
-    while (1)
+    while (cur < aPrefix.GetNext())
     {
-        end = aPrefix.GetNext();
-
-        if (cur >= end)
-        {
-            break;
-        }
-
         switch (cur->GetType())
         {
         case NetworkDataTlv::kTypeHasRoute:
-            RemoveRloc(aPrefix, *static_cast<HasRouteTlv *>(cur), aRloc16, aMatchMode);
+            RemoveRlocInHasRoute(aPrefix, *static_cast<HasRouteTlv *>(cur), aRloc16, aMatchMode, aExcludePrefix,
+                                 aChangedFlags);
 
-            // remove has route tlv if empty
             if (cur->GetLength() == 0)
             {
-                aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - sizeof(HasRouteTlv));
-                Remove(reinterpret_cast<uint8_t *>(cur), sizeof(HasRouteTlv));
+                aPrefix.DecreaseLength(sizeof(HasRouteTlv));
+                RemoveTlv(cur);
                 continue;
             }
 
             break;
 
         case NetworkDataTlv::kTypeBorderRouter:
-            RemoveRloc(aPrefix, *static_cast<BorderRouterTlv *>(cur), aRloc16, aMatchMode);
+            RemoveRlocInBorderRouter(aPrefix, *static_cast<BorderRouterTlv *>(cur), aRloc16, aMatchMode, aExcludePrefix,
+                                     aChangedFlags);
 
-            // remove border router tlv if empty
             if (cur->GetLength() == 0)
             {
-                aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - sizeof(BorderRouterTlv));
-                Remove(reinterpret_cast<uint8_t *>(cur), sizeof(BorderRouterTlv));
+                aPrefix.DecreaseLength(sizeof(BorderRouterTlv));
+                RemoveTlv(cur);
                 continue;
             }
 
@@ -1308,7 +1171,7 @@
         cur = cur->GetNext();
     }
 
-    if ((context = FindContext(aPrefix)) != NULL)
+    if ((context = FindContext(aPrefix)) != nullptr)
     {
         if (aPrefix.GetSubTlvsLength() == sizeof(ContextTlv))
         {
@@ -1323,56 +1186,56 @@
     }
 }
 
-void Leader::RemoveRloc(ServiceTlv &aService, uint16_t aRloc16, MatchMode aMatchMode)
+void Leader::RemoveRlocInService(ServiceTlv &      aService,
+                                 uint16_t          aRloc16,
+                                 MatchMode         aMatchMode,
+                                 const ServiceTlv *aExcludeService,
+                                 ChangedFlags &    aChangedFlags)
 {
-    NetworkDataTlv *cur = aService.GetSubTlvs();
-    NetworkDataTlv *end;
+    // Remove entries in `aService` TLV matching the given `aRloc16`
+    // excluding any entries that are present in `aExcludeService`.
+
+    NetworkDataTlv *start = aService.GetSubTlvs();
     ServerTlv *     server;
-    uint8_t         removeLength;
 
-    while (1)
+    while ((server = FindTlv<ServerTlv>(start, aService.GetNext())) != nullptr)
     {
-        end = aService.GetNext();
-
-        if (cur >= end)
+        if (RlocMatch(server->GetServer16(), aRloc16, aMatchMode) && !ContainsMatchingServer(aExcludeService, *server))
         {
-            break;
+            uint8_t subTlvSize = server->GetSize();
+
+            aChangedFlags.Update(*server);
+            RemoveTlv(server);
+            aService.DecreaseLength(subTlvSize);
+            continue;
         }
 
-        switch (cur->GetType())
-        {
-        case NetworkDataTlv::kTypeServer:
-            server = static_cast<ServerTlv *>(cur);
-
-            if (RlocMatch(server->GetServer16(), aRloc16, aMatchMode))
-            {
-                removeLength = sizeof(ServerTlv) + server->GetServerDataLength();
-                aService.SetSubTlvsLength(aService.GetSubTlvsLength() - removeLength);
-                Remove(reinterpret_cast<uint8_t *>(cur), removeLength);
-                continue;
-            }
-
-            break;
-
-        default:
-            break;
-        }
-
-        cur = cur->GetNext();
+        start = server->GetNext();
     }
 }
 
-void Leader::RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16, MatchMode aMatchMode)
+void Leader::RemoveRlocInHasRoute(PrefixTlv &      aPrefix,
+                                  HasRouteTlv &    aHasRoute,
+                                  uint16_t         aRloc16,
+                                  MatchMode        aMatchMode,
+                                  const PrefixTlv *aExcludePrefix,
+                                  ChangedFlags &   aChangedFlags)
 {
+    // Remove entries in `aHasRoute` (a sub-TLV of `aPrefix` TLV)
+    // matching the given `aRloc16` excluding entries that are present
+    // in `aExcludePrefix`.
+
     HasRouteEntry *entry = aHasRoute.GetFirstEntry();
 
     while (entry <= aHasRoute.GetLastEntry())
     {
-        if (RlocMatch(entry->GetRloc(), aRloc16, aMatchMode))
+        if (RlocMatch(entry->GetRloc(), aRloc16, aMatchMode) &&
+            !ContainsMatchingEntry(aExcludePrefix, aHasRoute.IsStable(), *entry))
         {
-            aHasRoute.SetLength(aHasRoute.GetLength() - sizeof(HasRouteEntry));
-            aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - sizeof(HasRouteEntry));
-            Remove(reinterpret_cast<uint8_t *>(entry), sizeof(HasRouteEntry));
+            aChangedFlags.Update(aHasRoute);
+            aHasRoute.DecreaseLength(sizeof(HasRouteEntry));
+            aPrefix.DecreaseLength(sizeof(HasRouteEntry));
+            Remove(entry, sizeof(HasRouteEntry));
             continue;
         }
 
@@ -1380,17 +1243,28 @@
     }
 }
 
-void Leader::RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, uint16_t aRloc16, MatchMode aMatchMode)
+void Leader::RemoveRlocInBorderRouter(PrefixTlv &      aPrefix,
+                                      BorderRouterTlv &aBorderRouter,
+                                      uint16_t         aRloc16,
+                                      MatchMode        aMatchMode,
+                                      const PrefixTlv *aExcludePrefix,
+                                      ChangedFlags &   aChangedFlags)
 {
+    // Remove entries in `aBorderRouter` (a sub-TLV of `aPrefix` TLV)
+    // matching the given `aRloc16` excluding entries that are present
+    // in `aExcludePrefix`.
+
     BorderRouterEntry *entry = aBorderRouter.GetFirstEntry();
 
     while (entry <= aBorderRouter.GetLastEntry())
     {
-        if (RlocMatch(entry->GetRloc(), aRloc16, aMatchMode))
+        if (RlocMatch(entry->GetRloc(), aRloc16, aMatchMode) &&
+            !ContainsMatchingEntry(aExcludePrefix, aBorderRouter.IsStable(), *entry))
         {
-            aBorderRouter.SetLength(aBorderRouter.GetLength() - sizeof(BorderRouterEntry));
-            aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - sizeof(BorderRouterEntry));
-            Remove(reinterpret_cast<uint8_t *>(entry), sizeof(*entry));
+            aChangedFlags.Update(aBorderRouter);
+            aBorderRouter.DecreaseLength(sizeof(BorderRouterEntry));
+            aPrefix.DecreaseLength(sizeof(BorderRouterEntry));
+            Remove(entry, sizeof(*entry));
             continue;
         }
 
@@ -1400,119 +1274,66 @@
 
 void Leader::RemoveContext(uint8_t aContextId)
 {
-    NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-    NetworkDataTlv *end;
+    NetworkDataTlv *start = GetTlvsStart();
     PrefixTlv *     prefix;
 
-    while (1)
+    while ((prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr)
     {
-        end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
+        RemoveContext(*prefix, aContextId);
 
-        if (cur >= end)
+        if (UpdatePrefix(*prefix) == kTlvRemoved)
         {
-            break;
+            // Do not update `start` when TLV is removed.
+            continue;
         }
 
-        switch (cur->GetType())
-        {
-        case NetworkDataTlv::kTypePrefix:
-        {
-            prefix = static_cast<PrefixTlv *>(cur);
-            RemoveContext(*prefix, aContextId);
-
-            if (prefix->GetSubTlvsLength() == 0)
-            {
-                Remove(reinterpret_cast<uint8_t *>(prefix), sizeof(NetworkDataTlv) + prefix->GetLength());
-                continue;
-            }
-
-            otDumpDebgNetData("remove prefix done", mTlvs, mLength);
-            break;
-        }
-
-        default:
-            break;
-        }
-
-        cur = cur->GetNext();
+        start = prefix->GetNext();
     }
-
-    otDumpDebgNetData("remove done", mTlvs, mLength);
 }
 
 void Leader::RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId)
 {
-    NetworkDataTlv *cur = aPrefix.GetSubTlvs();
-    NetworkDataTlv *end;
+    NetworkDataTlv *start = aPrefix.GetSubTlvs();
     ContextTlv *    context;
-    uint8_t         length;
 
-    while (1)
+    while ((context = FindTlv<ContextTlv>(start, aPrefix.GetNext())) != nullptr)
     {
-        end = aPrefix.GetNext();
-
-        if (cur >= end)
+        if (context->GetContextId() == aContextId)
         {
-            break;
+            uint8_t subTlvSize = context->GetSize();
+            RemoveTlv(context);
+            aPrefix.DecreaseLength(subTlvSize);
+            continue;
         }
 
-        switch (cur->GetType())
-        {
-        case NetworkDataTlv::kTypeContext:
-        {
-            // remove context tlv
-            context = static_cast<ContextTlv *>(cur);
-
-            if (context->GetContextId() == aContextId)
-            {
-                length = sizeof(NetworkDataTlv) + context->GetLength();
-                aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - length);
-                Remove(reinterpret_cast<uint8_t *>(context), length);
-                continue;
-            }
-
-            break;
-        }
-
-        default:
-            break;
-        }
-
-        cur = cur->GetNext();
+        start = context->GetNext();
     }
 }
 
 void Leader::UpdateContextsAfterReset(void)
 {
-    PrefixTlv * prefix;
-    ContextTlv *contextTlv;
+    NetworkDataTlv *start;
+    PrefixTlv *     prefix;
 
-    // Iterate through Network Data and synchronize missing contexts.
-    for (NetworkDataTlv *cur                                            = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
+    for (start = GetTlvsStart(); (prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr;
+         start = prefix->GetNext())
     {
-        if (cur->GetType() != NetworkDataTlv::kTypePrefix)
+        ContextTlv *context = FindContext(*prefix);
+
+        if (context == nullptr)
         {
             continue;
         }
 
-        prefix     = static_cast<PrefixTlv *>(cur);
-        contextTlv = FindContext(*prefix);
+        mContextUsed |= 1 << context->GetContextId();
 
-        if (contextTlv == NULL)
+        if (context->IsCompress())
         {
-            continue;
-        }
-
-        mContextUsed |= 1 << contextTlv->GetContextId();
-
-        if (contextTlv->IsCompress())
-        {
-            StopContextReuseTimer(contextTlv->GetContextId());
+            StopContextReuseTimer(context->GetContextId());
         }
         else
         {
-            StartContextReuseTimer(contextTlv->GetContextId());
+            StartContextReuseTimer(context->GetContextId());
         }
     }
 }
@@ -1535,7 +1356,7 @@
 
         if (TimerMilli::GetNow() - mContextLastUsed[i] >= Time::SecToMsec(mContextIdReuseDelay))
         {
-            FreeContext(kMinContextId + i);
+            FreeContextId(kMinContextId + i);
         }
         else
         {
@@ -1549,6 +1370,29 @@
     }
 }
 
+otError Leader::RemoveStaleChildEntries(Coap::ResponseHandler aHandler, void *aContext)
+{
+    otError  error    = OT_ERROR_NOT_FOUND;
+    Iterator iterator = kIteratorInit;
+    uint16_t rloc16;
+
+    VerifyOrExit(Get<Mle::MleRouter>().IsRouterOrLeader(), OT_NOOP);
+
+    while (GetNextServer(iterator, rloc16) == OT_ERROR_NONE)
+    {
+        if (!Mle::Mle::IsActiveRouter(rloc16) && Mle::Mle::RouterIdMatch(Get<Mle::MleRouter>().GetRloc16(), rloc16) &&
+            Get<ChildTable>().FindChild(rloc16, Child::kInStateValid) == nullptr)
+        {
+            // In Thread 1.1 Specification 5.15.6.1, only one RLOC16 TLV entry may appear in SRV_DATA.ntf.
+            error = NetworkData::SendServerDataNotification(rloc16, aHandler, aContext);
+            ExitNow();
+        }
+    }
+
+exit:
+    return error;
+}
+
 } // namespace NetworkData
 } // namespace ot
 
diff --git a/src/core/thread/network_data_leader_ftd.hpp b/src/core/thread/network_data_leader_ftd.hpp
index e86b46c..fabafaa 100644
--- a/src/core/thread/network_data_leader_ftd.hpp
+++ b/src/core/thread/network_data_leader_ftd.hpp
@@ -108,10 +108,10 @@
     void IncrementVersion(void);
 
     /**
-     * This method increments the Thread Network Data stable version.
+     * This method increments both the Thread Network Data version and stable version.
      *
      */
-    void IncrementStableVersion(void);
+    void IncrementVersionAndStableVersion(void);
 
     /**
      * This method returns CONTEXT_ID_RESUSE_DELAY value.
@@ -119,7 +119,7 @@
      * @returns The CONTEXT_ID_REUSE_DELAY value.
      *
      */
-    uint32_t GetContextIdReuseDelay(void) const;
+    uint32_t GetContextIdReuseDelay(void) const { return mContextIdReuseDelay; }
 
     /**
      * This method sets CONTEXT_ID_RESUSE_DELAY value.
@@ -129,7 +129,7 @@
      * @param[in]  aDelay  The CONTEXT_ID_REUSE_DELAY value.
      *
      */
-    void SetContextIdReuseDelay(uint32_t aDelay);
+    void SetContextIdReuseDelay(uint32_t aDelay) { mContextIdReuseDelay = aDelay; }
 
     /**
      * This method removes Network Data entries matching with a given RLOC16.
@@ -141,17 +141,6 @@
     void RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode);
 
     /**
-     * This method sends a Server Data Notification message to the Leader indicating an invalid RLOC16.
-     *
-     * @param[in]  aRloc16  The invalid RLOC16 to notify.
-     *
-     * @retval OT_ERROR_NONE     Successfully enqueued the notification message.
-     * @retval OT_ERROR_NO_BUFS  Insufficient message buffers to generate the notification message.
-     *
-     */
-    otError SendServerDataNotification(uint16_t aRloc16);
-
-    /**
      * This method synchronizes internal 6LoWPAN Context ID Set with recently obtained Thread Network Data.
      *
      * Note that this method should be called only by the Leader once after reset.
@@ -160,57 +149,127 @@
     void UpdateContextsAfterReset(void);
 
     /**
-     * This method scans network data for given service ID and returns pointer to the respective TLV, if present.
+     * This method scans network data for given Service ID and returns pointer to the respective TLV, if present.
      *
      * @param aServiceId Service ID to look for.
-     * @return Pointer to the Service TLV for given Service ID, or NULL if not present.
+     * @return Pointer to the Service TLV for given Service ID, or nullptr if not present.
      *
      */
-    ServiceTlv *FindServiceById(uint8_t aServiceId);
+    const ServiceTlv *FindServiceById(uint8_t aServiceId) const;
+
+    /**
+     * This method sends SVR_DATA.ntf message for any stale child entries that exist in the network data.
+     *
+     * @param[in]  aHandler  A function pointer that is called when the transaction ends.
+     * @param[in]  aContext  A pointer to arbitrary context information.
+     *
+     * @retval OT_ERROR_NONE       A stale child entry was found and successfully enqueued a SVR_DATA.ntf message.
+     * @retval OT_ERROR_NO_BUFS    A stale child entry was found, but insufficient message buffers were available.
+     * @retval OT_ERROR_NOT_FOUND  No stale child entries were found.
+     *
+     */
+    otError RemoveStaleChildEntries(Coap::ResponseHandler aHandler, void *aContext);
 
 private:
+    class ChangedFlags
+    {
+    public:
+        ChangedFlags(void)
+            : mChanged(false)
+            , mStableChanged(false)
+        {
+        }
+
+        void Update(const NetworkDataTlv &aTlv)
+        {
+            mChanged       = true;
+            mStableChanged = (mStableChanged || aTlv.IsStable());
+        }
+
+        bool DidChange(void) const { return mChanged; }
+        bool DidStableChange(void) const { return mStableChanged; }
+
+    private:
+        bool mChanged;       // Any (stable or not) network data change (add/remove).
+        bool mStableChanged; // Stable network data change (add/remove).
+    };
+
+    enum UpdateStatus
+    {
+        kTlvRemoved, // TLV contained no sub TLVs and therefore is removed.
+        kTlvUpdated, // TLV stable flag is updated based on its sub TLVs.
+    };
+
     static void HandleServerData(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleServerData(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
 
     static void HandleTimer(Timer &aTimer);
     void        HandleTimer(void);
 
-    otError RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aTlvsLength);
+    void RegisterNetworkData(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t aTlvsLength);
 
-    otError AddHasRoute(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute);
-    otError AddBorderRouter(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter);
-    otError AddNetworkData(uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aOldTlvs, uint8_t aOldTlvsLength);
-    otError AddPrefix(PrefixTlv &aPrefix);
-    otError AddServer(ServiceTlv &aService, ServerTlv &aServer, uint8_t *aOldTlvs, uint8_t aOldTlvsLength);
-    otError AddService(ServiceTlv &aService, uint8_t *aOldTlvs, uint8_t aOldTlvsLength);
+    otError AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags);
+    otError AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
+    otError AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aFlags);
+    otError AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags);
+    otError AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags);
 
-    int  AllocateContext(void);
-    void FreeContext(uint8_t aContextId);
-    void StartContextReuseTimer(uint8_t aContextId);
-    void StopContextReuseTimer(uint8_t aContextId);
+    otError AllocateServiceId(uint8_t &aServiceId);
+
+    otError AllocateContextId(uint8_t &aConextId);
+    void    FreeContextId(uint8_t aContextId);
+    void    StartContextReuseTimer(uint8_t aContextId);
+    void    StopContextReuseTimer(uint8_t aContextId);
 
     void RemoveContext(uint8_t aContextId);
     void RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId);
 
     void RemoveCommissioningData(void);
 
-    void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode);
-    void RemoveRloc(PrefixTlv &aPrefix, uint16_t aRloc16, MatchMode aMatchMode);
-    void RemoveRloc(ServiceTlv &aService, uint16_t aRloc16, MatchMode aMatchMode);
-    void RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16, MatchMode aMatchMode);
-    void RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, uint16_t aRloc16, MatchMode aMatchMode);
+    void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags);
+    void RemoveRloc(uint16_t       aRloc16,
+                    MatchMode      aMatchMode,
+                    const uint8_t *aExcludeTlvs,
+                    uint8_t        aExcludeTlvsLength,
+                    ChangedFlags & aChangedFlags);
+    void RemoveRlocInPrefix(PrefixTlv &      aPrefix,
+                            uint16_t         aRloc16,
+                            MatchMode        aMatchMode,
+                            const PrefixTlv *aExcludePrefix,
+                            ChangedFlags &   aChangedFlags);
+    void RemoveRlocInService(ServiceTlv &      aService,
+                             uint16_t          aRloc16,
+                             MatchMode         aMatchMode,
+                             const ServiceTlv *aExcludeService,
+                             ChangedFlags &    aChangedFlags);
+    void RemoveRlocInHasRoute(PrefixTlv &      aPrefix,
+                              HasRouteTlv &    aHasRoute,
+                              uint16_t         aRloc16,
+                              MatchMode        aMatchMode,
+                              const PrefixTlv *aExcludePrefix,
+                              ChangedFlags &   aChangedFlags);
+    void RemoveRlocInBorderRouter(PrefixTlv &      aPrefix,
+                                  BorderRouterTlv &aBorderRouter,
+                                  uint16_t         aRloc16,
+                                  MatchMode        aMatchMode,
+                                  const PrefixTlv *aExcludePrefix,
+                                  ChangedFlags &   aChangedFlags);
 
     static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode);
 
-    otError RlocLookup(uint16_t  aRloc16,
-                       bool &    aIn,
-                       bool &    aStable,
-                       uint8_t * aTlvs,
-                       uint8_t   aTlvsLength,
-                       MatchMode aMatchMode,
-                       bool      aAllowOtherEntries = true);
+    static otError Validate(const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aRloc16);
+    static otError ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16);
+    static otError ValidateService(const ServiceTlv &aService, uint16_t aRloc16);
 
-    bool IsStableUpdated(uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aTlvsBase, uint8_t aTlvsBaseLength);
+    static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry);
+    static bool ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry);
+    static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry);
+    static bool ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry);
+    static bool ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer);
+
+    UpdateStatus UpdatePrefix(PrefixTlv &aPrefix);
+    UpdateStatus UpdateService(ServiceTlv &aService);
+    UpdateStatus UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs);
 
     static void HandleCommissioningSet(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleCommissioningSet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
@@ -224,6 +283,8 @@
     void SendCommissioningSetResponse(const Coap::Message &    aRequest,
                                       const Ip6::MessageInfo & aMessageInfo,
                                       MeshCoP::StateTlv::State aState);
+    void IncrementVersions(bool aIncludeStable);
+    void IncrementVersions(const ChangedFlags &aFlags);
 
     /**
      * Thread Specification Constants.
diff --git a/src/core/thread/network_data_local.cpp b/src/core/thread/network_data_local.cpp
index 852a4ab..a65ad8a 100644
--- a/src/core/thread/network_data_local.cpp
+++ b/src/core/thread/network_data_local.cpp
@@ -39,6 +39,7 @@
 #include "common/locator-getters.hpp"
 #include "common/logging.hpp"
 #include "mac/mac_types.hpp"
+#include "thread/mle_types.hpp"
 #include "thread/thread_netif.hpp"
 
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
@@ -53,123 +54,149 @@
 }
 
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
-otError Local::AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, uint8_t aFlags, bool aStable)
+otError Local::AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig)
 {
-    otError          error             = OT_ERROR_NONE;
-    uint8_t          prefixLengthBytes = BitVectorBytes(aPrefixLength);
-    uint8_t          appendLength;
-    PrefixTlv *      prefixTlv;
-    BorderRouterTlv *brTlv;
+    uint16_t flags = 0;
 
-    VerifyOrExit(prefixLengthBytes <= sizeof(Ip6::Address), error = OT_ERROR_INVALID_ARGS);
+    if (aConfig.mPreferred)
+    {
+        flags |= BorderRouterEntry::kPreferredFlag;
+    }
 
-    VerifyOrExit((aPrf == OT_ROUTE_PREFERENCE_LOW) || (aPrf == OT_ROUTE_PREFERENCE_MED) ||
-                     (aPrf == OT_ROUTE_PREFERENCE_HIGH),
-                 error = OT_ERROR_INVALID_ARGS);
+    if (aConfig.mSlaac)
+    {
+        flags |= BorderRouterEntry::kSlaacFlag;
+    }
+
+    if (aConfig.mDhcp)
+    {
+        flags |= BorderRouterEntry::kDhcpFlag;
+    }
+
+    if (aConfig.mConfigure)
+    {
+        flags |= BorderRouterEntry::kConfigureFlag;
+    }
+
+    if (aConfig.mDefaultRoute)
+    {
+        flags |= BorderRouterEntry::kDefaultRouteFlag;
+    }
+
+    if (aConfig.mOnMesh)
+    {
+        flags |= BorderRouterEntry::kOnMeshFlag;
+    }
+
+    if (aConfig.mNdDns)
+    {
+        flags |= BorderRouterEntry::kNdDnsFlag;
+    }
+
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    if (aConfig.mDp)
+    {
+        flags |= BorderRouterEntry::kDpFlag;
+    }
+#endif
+
+    return AddPrefix(aConfig.mPrefix.mPrefix.mFields.m8, aConfig.mPrefix.mLength, NetworkDataTlv::kTypeBorderRouter,
+                     aConfig.mPreference, flags, aConfig.mStable);
+}
+
+otError Local::RemoveOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
+{
+    return RemovePrefix(aPrefix, aPrefixLength, NetworkDataTlv::kTypeBorderRouter);
+}
+
+otError Local::AddHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, bool aStable)
+{
+    return AddPrefix(aPrefix, aPrefixLength, NetworkDataTlv::kTypeHasRoute, aPrf, /* aFlags */ 0, aStable);
+}
+
+otError Local::RemoveHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
+{
+    return RemovePrefix(aPrefix, aPrefixLength, NetworkDataTlv::kTypeHasRoute);
+}
+
+otError Local::AddPrefix(const uint8_t *      aPrefix,
+                         uint8_t              aPrefixLength,
+                         NetworkDataTlv::Type aSubTlvType,
+                         int8_t               aPrf,
+                         uint16_t             aFlags,
+                         bool                 aStable)
+{
+    otError    error             = OT_ERROR_NONE;
+    uint8_t    prefixLengthBytes = BitVectorBytes(aPrefixLength);
+    uint8_t    subTlvLength;
+    PrefixTlv *prefixTlv;
+
+    VerifyOrExit(aPrefixLength > 0 && prefixLengthBytes <= sizeof(Ip6::Address), error = OT_ERROR_INVALID_ARGS);
+
+    switch (aPrf)
+    {
+    case OT_ROUTE_PREFERENCE_LOW:
+    case OT_ROUTE_PREFERENCE_MED:
+    case OT_ROUTE_PREFERENCE_HIGH:
+        break;
+    default:
+        ExitNow(error = OT_ERROR_INVALID_ARGS);
+    }
 
     VerifyOrExit(Ip6::Address::PrefixMatch(aPrefix, Get<Mle::MleRouter>().GetMeshLocalPrefix().m8, prefixLengthBytes) <
-                     Ip6::Address::kMeshLocalPrefixLength,
+                     Mle::MeshLocalPrefix::kLength,
                  error = OT_ERROR_INVALID_ARGS);
 
-    RemoveOnMeshPrefix(aPrefix, aPrefixLength);
+    IgnoreError(RemovePrefix(aPrefix, aPrefixLength, aSubTlvType));
 
-    appendLength = sizeof(PrefixTlv) + prefixLengthBytes + sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry);
-    VerifyOrExit(mLength + appendLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS);
+    subTlvLength = (aSubTlvType == NetworkDataTlv::kTypeBorderRouter)
+                       ? sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry)
+                       : sizeof(HasRouteTlv) + sizeof(HasRouteEntry);
 
-    prefixTlv = reinterpret_cast<PrefixTlv *>(mTlvs + mLength);
-    Insert(reinterpret_cast<uint8_t *>(prefixTlv), appendLength);
+    prefixTlv = static_cast<PrefixTlv *>(AppendTlv(sizeof(PrefixTlv) + prefixLengthBytes + subTlvLength));
+    VerifyOrExit(prefixTlv != nullptr, error = OT_ERROR_NO_BUFS);
+
     prefixTlv->Init(0, aPrefixLength, aPrefix);
-    prefixTlv->SetSubTlvsLength(sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry));
+    prefixTlv->SetSubTlvsLength(subTlvLength);
 
-    brTlv = static_cast<BorderRouterTlv *>(prefixTlv->GetSubTlvs());
-    brTlv->Init();
-    brTlv->SetLength(brTlv->GetLength() + sizeof(BorderRouterEntry));
-    brTlv->GetEntry(0)->Init();
-    brTlv->GetEntry(0)->SetPreference(aPrf);
-    brTlv->GetEntry(0)->SetFlags(aFlags);
+    if (aSubTlvType == NetworkDataTlv::kTypeBorderRouter)
+    {
+        BorderRouterTlv *brTlv = static_cast<BorderRouterTlv *>(prefixTlv->GetSubTlvs());
+        brTlv->Init();
+        brTlv->SetLength(brTlv->GetLength() + sizeof(BorderRouterEntry));
+        brTlv->GetEntry(0)->Init();
+        brTlv->GetEntry(0)->SetPreference(aPrf);
+        brTlv->GetEntry(0)->SetFlags(aFlags);
+    }
+    else // aSubTlvType is NetworkDataTlv::kTypeHasRoute
+    {
+        HasRouteTlv *hasRouteTlv = static_cast<HasRouteTlv *>(prefixTlv->GetSubTlvs());
+        hasRouteTlv->Init();
+        hasRouteTlv->SetLength(hasRouteTlv->GetLength() + sizeof(HasRouteEntry));
+        hasRouteTlv->GetEntry(0)->Init();
+        hasRouteTlv->GetEntry(0)->SetPreference(aPrf);
+    }
 
     if (aStable)
     {
         prefixTlv->SetStable();
-        brTlv->SetStable();
+        prefixTlv->GetSubTlvs()->SetStable();
     }
 
-    ClearResubmitDelayTimer();
-
     otDumpDebgNetData("add prefix done", mTlvs, mLength);
 
 exit:
     return error;
 }
 
-otError Local::RemoveOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
+otError Local::RemovePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, NetworkDataTlv::Type aSubTlvType)
 {
     otError    error = OT_ERROR_NONE;
     PrefixTlv *tlv;
 
-    VerifyOrExit((tlv = FindPrefix(aPrefix, aPrefixLength)) != NULL, error = OT_ERROR_NOT_FOUND);
-    VerifyOrExit(FindBorderRouter(*tlv) != NULL, error = OT_ERROR_NOT_FOUND);
-    Remove(reinterpret_cast<uint8_t *>(tlv), sizeof(NetworkDataTlv) + tlv->GetLength());
-    ClearResubmitDelayTimer();
-
-exit:
-    otDumpDebgNetData("remove done", mTlvs, mLength);
-    return error;
-}
-
-otError Local::AddHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, bool aStable)
-{
-    otError      error             = OT_ERROR_NONE;
-    uint8_t      prefixLengthBytes = BitVectorBytes(aPrefixLength);
-    PrefixTlv *  prefixTlv;
-    HasRouteTlv *hasRouteTlv;
-    uint8_t      appendLength;
-
-    VerifyOrExit(prefixLengthBytes <= sizeof(Ip6::Address), error = OT_ERROR_INVALID_ARGS);
-
-    VerifyOrExit((aPrf == OT_ROUTE_PREFERENCE_LOW) || (aPrf == OT_ROUTE_PREFERENCE_MED) ||
-                     (aPrf == OT_ROUTE_PREFERENCE_HIGH),
-                 error = OT_ERROR_INVALID_ARGS);
-
-    RemoveHasRoutePrefix(aPrefix, aPrefixLength);
-
-    appendLength = sizeof(PrefixTlv) + prefixLengthBytes + sizeof(HasRouteTlv) + sizeof(HasRouteEntry);
-    VerifyOrExit(mLength + appendLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS);
-
-    prefixTlv = reinterpret_cast<PrefixTlv *>(mTlvs + mLength);
-    Insert(reinterpret_cast<uint8_t *>(prefixTlv), appendLength);
-    prefixTlv->Init(0, aPrefixLength, aPrefix);
-    prefixTlv->SetSubTlvsLength(sizeof(HasRouteTlv) + sizeof(HasRouteEntry));
-
-    hasRouteTlv = static_cast<HasRouteTlv *>(prefixTlv->GetSubTlvs());
-    hasRouteTlv->Init();
-    hasRouteTlv->SetLength(hasRouteTlv->GetLength() + sizeof(HasRouteEntry));
-    hasRouteTlv->GetEntry(0)->Init();
-    hasRouteTlv->GetEntry(0)->SetPreference(aPrf);
-
-    if (aStable)
-    {
-        prefixTlv->SetStable();
-        hasRouteTlv->SetStable();
-    }
-
-    ClearResubmitDelayTimer();
-
-    otDumpDebgNetData("add route done", mTlvs, mLength);
-
-exit:
-    return error;
-}
-
-otError Local::RemoveHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
-{
-    otError    error = OT_ERROR_NONE;
-    PrefixTlv *tlv;
-
-    VerifyOrExit((tlv = FindPrefix(aPrefix, aPrefixLength)) != NULL, error = OT_ERROR_NOT_FOUND);
-    VerifyOrExit(FindHasRoute(*tlv) != NULL, error = OT_ERROR_NOT_FOUND);
-    Remove(reinterpret_cast<uint8_t *>(tlv), sizeof(NetworkDataTlv) + tlv->GetLength());
-    ClearResubmitDelayTimer();
+    VerifyOrExit((tlv = FindPrefix(aPrefix, aPrefixLength)) != nullptr, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(FindTlv(tlv->GetSubTlvs(), tlv->GetNext(), aSubTlvType) != nullptr, error = OT_ERROR_NOT_FOUND);
+    RemoveTlv(tlv);
 
 exit:
     otDumpDebgNetData("remove done", mTlvs, mLength);
@@ -178,44 +205,34 @@
 
 void Local::UpdateRloc(PrefixTlv &aPrefix)
 {
+    uint16_t rloc16 = Get<Mle::MleRouter>().GetRloc16();
+
     for (NetworkDataTlv *cur = aPrefix.GetSubTlvs(); cur < aPrefix.GetNext(); cur = cur->GetNext())
     {
         switch (cur->GetType())
         {
         case NetworkDataTlv::kTypeHasRoute:
-            UpdateRloc(*static_cast<HasRouteTlv *>(cur));
+            static_cast<HasRouteTlv *>(cur)->GetEntry(0)->SetRloc(rloc16);
             break;
 
         case NetworkDataTlv::kTypeBorderRouter:
-            UpdateRloc(*static_cast<BorderRouterTlv *>(cur));
+            static_cast<BorderRouterTlv *>(cur)->GetEntry(0)->SetRloc(rloc16);
             break;
 
         default:
-            assert(false);
-            break;
+            OT_ASSERT(false);
+            OT_UNREACHABLE_CODE(break);
         }
     }
 }
 
-void Local::UpdateRloc(HasRouteTlv &aHasRoute)
-{
-    HasRouteEntry *entry = aHasRoute.GetEntry(0);
-    entry->SetRloc(Get<Mle::MleRouter>().GetRloc16());
-}
-
-void Local::UpdateRloc(BorderRouterTlv &aBorderRouter)
-{
-    BorderRouterEntry *entry = aBorderRouter.GetEntry(0);
-    entry->SetRloc(Get<Mle::MleRouter>().GetRloc16());
-}
-
-bool Local::IsOnMeshPrefixConsistent(void)
+bool Local::IsOnMeshPrefixConsistent(void) const
 {
     return (Get<Leader>().ContainsOnMeshPrefixes(*this, Get<Mle::MleRouter>().GetRloc16()) &&
             ContainsOnMeshPrefixes(Get<Leader>(), Get<Mle::MleRouter>().GetRloc16()));
 }
 
-bool Local::IsExternalRouteConsistent(void)
+bool Local::IsExternalRouteConsistent(void) const
 {
     return (Get<Leader>().ContainsExternalRoutes(*this, Get<Mle::MleRouter>().GetRloc16()) &&
             ContainsExternalRoutes(Get<Leader>(), Get<Mle::MleRouter>().GetRloc16()));
@@ -234,25 +251,22 @@
     otError     error = OT_ERROR_NONE;
     ServiceTlv *serviceTlv;
     ServerTlv * serverTlv;
-    size_t      serviceTlvLength =
-        (sizeof(ServiceTlv) - sizeof(NetworkDataTlv)) + aServiceDataLength + sizeof(uint8_t) /*mServiceDataLength*/ +
-        ServiceTlv::GetEnterpriseNumberFieldLength(aEnterpriseNumber) + aServerDataLength + sizeof(ServerTlv);
+    uint16_t    serviceTlvSize =
+        ServiceTlv::CalculateSize(aEnterpriseNumber, aServiceDataLength) + sizeof(ServerTlv) + aServerDataLength;
 
-    RemoveService(aEnterpriseNumber, aServiceData, aServiceDataLength);
+    IgnoreError(RemoveService(aEnterpriseNumber, aServiceData, aServiceDataLength));
 
-    VerifyOrExit(mLength + sizeof(NetworkDataTlv) + serviceTlvLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(serviceTlvSize <= kMaxSize, error = OT_ERROR_NO_BUFS);
 
-    serviceTlv = reinterpret_cast<ServiceTlv *>(mTlvs + mLength);
-    Insert(reinterpret_cast<uint8_t *>(serviceTlv), static_cast<uint8_t>(serviceTlvLength) + sizeof(NetworkDataTlv));
+    serviceTlv = static_cast<ServiceTlv *>(AppendTlv(serviceTlvSize));
+    VerifyOrExit(serviceTlv != nullptr, error = OT_ERROR_NO_BUFS);
 
-    serviceTlv->Init();
-    serviceTlv->SetEnterpriseNumber(aEnterpriseNumber);
-    serviceTlv->SetServiceID(0);
-    serviceTlv->SetServiceData(aServiceData, aServiceDataLength);
-    serviceTlv->SetLength(static_cast<uint8_t>(serviceTlvLength));
+    serviceTlv->Init(/* aServiceId */ 0, aEnterpriseNumber, aServiceData, aServiceDataLength);
+    serviceTlv->SetSubTlvsLength(sizeof(ServerTlv) + aServerDataLength);
 
     serverTlv = static_cast<ServerTlv *>(serviceTlv->GetSubTlvs());
-    serverTlv->Init();
+
+    serverTlv->Init(Get<Mle::MleRouter>().GetRloc16(), aServerData, aServerDataLength);
 
     // According to Thread spec 1.1.1, section 5.18.6 Service TLV:
     // "The Stable flag is set if any of the included sub-TLVs have their Stable flag set."
@@ -263,11 +277,6 @@
         serverTlv->SetStable();
     }
 
-    serverTlv->SetServer16(Get<Mle::MleRouter>().GetRloc16());
-    serverTlv->SetServerData(aServerData, aServerDataLength);
-
-    ClearResubmitDelayTimer();
-
     otDumpDebgNetData("add service done", mTlvs, mLength);
 
 exit:
@@ -279,10 +288,9 @@
     otError     error = OT_ERROR_NONE;
     ServiceTlv *tlv;
 
-    VerifyOrExit((tlv = FindService(aEnterpriseNumber, aServiceData, aServiceDataLength)) != NULL,
+    VerifyOrExit((tlv = FindService(aEnterpriseNumber, aServiceData, aServiceDataLength)) != nullptr,
                  error = OT_ERROR_NOT_FOUND);
-    Remove(reinterpret_cast<uint8_t *>(tlv), sizeof(NetworkDataTlv) + tlv->GetLength());
-    ClearResubmitDelayTimer();
+    RemoveTlv(tlv);
 
 exit:
     otDumpDebgNetData("remove service done", mTlvs, mLength);
@@ -291,27 +299,24 @@
 
 void Local::UpdateRloc(ServiceTlv &aService)
 {
+    uint16_t rloc16 = Get<Mle::MleRouter>().GetRloc16();
+
     for (NetworkDataTlv *cur = aService.GetSubTlvs(); cur < aService.GetNext(); cur = cur->GetNext())
     {
         switch (cur->GetType())
         {
         case NetworkDataTlv::kTypeServer:
-            UpdateRloc(*static_cast<ServerTlv *>(cur));
+            static_cast<ServerTlv *>(cur)->SetServer16(rloc16);
             break;
 
         default:
-            assert(false);
-            break;
+            OT_ASSERT(false);
+            OT_UNREACHABLE_CODE(break);
         }
     }
 }
 
-void Local::UpdateRloc(ServerTlv &aServer)
-{
-    aServer.SetServer16(Get<Mle::MleRouter>().GetRloc16());
-}
-
-bool Local::IsServiceConsistent(void)
+bool Local::IsServiceConsistent(void) const
 {
     return (Get<Leader>().ContainsServices(*this, Get<Mle::MleRouter>().GetRloc16()) &&
             ContainsServices(Get<Leader>(), Get<Mle::MleRouter>().GetRloc16()));
@@ -321,8 +326,7 @@
 
 void Local::UpdateRloc(void)
 {
-    for (NetworkDataTlv *cur                                            = reinterpret_cast<NetworkDataTlv *>(mTlvs);
-         cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
+    for (NetworkDataTlv *cur = GetTlvsStart(); cur < GetTlvsEnd(); cur = cur->GetNext())
     {
         switch (cur->GetType())
         {
@@ -340,15 +344,13 @@
 #endif
 
         default:
-            assert(false);
-            break;
+            OT_ASSERT(false);
+            OT_UNREACHABLE_CODE(break);
         }
     }
-
-    ClearResubmitDelayTimer();
 }
 
-otError Local::SendServerDataNotification(void)
+otError Local::UpdateInconsistentServerData(Coap::ResponseHandler aHandler, void *aContext)
 {
     otError  error        = OT_ERROR_NONE;
     uint16_t rloc         = Get<Mle::MleRouter>().GetRloc16();
@@ -357,8 +359,7 @@
 #if OPENTHREAD_FTD
 
     // Don't send this Server Data Notification if the device is going to upgrade to Router
-    if (Get<Mle::MleRouter>().IsRouterEligible() && (Get<Mle::MleRouter>().GetRole() < OT_DEVICE_ROLE_ROUTER) &&
-        (Get<RouterTable>().GetActiveRouterCount() < Get<Mle::MleRouter>().GetRouterUpgradeThreshold()))
+    if (Get<Mle::MleRouter>().IsExpectedToBecomeRouter())
     {
         ExitNow(error = OT_ERROR_INVALID_STATE);
     }
@@ -374,14 +375,14 @@
     isConsistent = isConsistent && IsServiceConsistent();
 #endif
 
-    VerifyOrExit(!isConsistent, ClearResubmitDelayTimer());
+    VerifyOrExit(!isConsistent, error = OT_ERROR_NOT_FOUND);
 
     if (mOldRloc == rloc)
     {
         mOldRloc = Mac::kShortAddrInvalid;
     }
 
-    SuccessOrExit(error = NetworkData::SendServerDataNotification(mOldRloc));
+    SuccessOrExit(error = NetworkData::SendServerDataNotification(mOldRloc, aHandler, aContext));
     mOldRloc = rloc;
 
 exit:
diff --git a/src/core/thread/network_data_local.hpp b/src/core/thread/network_data_local.hpp
index 08039c9..025bee5 100644
--- a/src/core/thread/network_data_local.hpp
+++ b/src/core/thread/network_data_local.hpp
@@ -1,3 +1,4 @@
+
 /*
  *  Copyright (c) 2016, The OpenThread Authors.
  *  All rights reserved.
@@ -72,24 +73,20 @@
     /**
      * This method adds a Border Router entry to the Thread Network Data.
      *
-     * @param[in]  aPrefix        A pointer to the prefix.
-     * @param[in]  aPrefixLength  The length of @p aPrefix in bytes.
-     * @param[in]  aPrf           The preference value.
-     * @param[in]  aFlags         The Border Router Flags value.
-     * @param[in]  aStable        The Stable value.
+     * @param[in]  aConfig  A reference to the on mesh perfix configuration.
      *
      * @retval OT_ERROR_NONE         Successfully added the Border Router entry.
      * @retval OT_ERROR_NO_BUFS      Insufficient space to add the Border Router entry.
      * @retval OT_ERROR_INVALID_ARGS The prefix is mesh local prefix.
      *
      */
-    otError AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, uint8_t aFlags, bool aStable);
+    otError AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig);
 
     /**
      * This method removes a Border Router entry from the Thread Network Data.
      *
      * @param[in]  aPrefix        A pointer to the prefix.
-     * @param[in]  aPrefixLength  The length of @p aPrefix in bytes.
+     * @param[in]  aPrefixLength  The prefix length in bits.
      *
      * @retval OT_ERROR_NONE       Successfully removed the Border Router entry.
      * @retval OT_ERROR_NOT_FOUND  Could not find the Border Router entry.
@@ -101,7 +98,7 @@
      * This method adds a Has Route entry to the Thread Network data.
      *
      * @param[in]  aPrefix        A pointer to the prefix.
-     * @param[in]  aPrefixLength  The length of @p aPrefix in bytes.
+     * @param[in]  aPrefixLength  The prefix length in bits.
      * @param[in]  aPrf           The preference value.
      * @param[in]  aStable        The Stable value.
      *
@@ -115,7 +112,7 @@
      * This method removes a Border Router entry from the Thread Network Data.
      *
      * @param[in]  aPrefix        A pointer to the prefix.
-     * @param[in]  aPrefixLength  The length of @p aPrefix in bytes.
+     * @param[in]  aPrefixLength  The prefix length in bits.
      *
      * @retval OT_ERROR_NONE       Successfully removed the Border Router entry.
      * @retval OT_ERROR_NOT_FOUND  Could not find the Border Router entry.
@@ -163,26 +160,35 @@
     /**
      * This method sends a Server Data Notification message to the Leader.
      *
-     * @retval OT_ERROR_NONE     Successfully enqueued the notification message.
-     * @retval OT_ERROR_NO_BUFS  Insufficient message buffers to generate the notification message.
+     * @param[in]  aHandler  A function pointer that is called when the transaction ends.
+     * @param[in]  aContext  A pointer to arbitrary context information.
+     *
+     * @retval OT_ERROR_NONE           Successfully enqueued the notification message.
+     * @retval OT_ERROR_NO_BUFS        Insufficient message buffers to generate the notification message.
+     * @retval OT_ERROR_INVALID_STATE  Device is a REED and is in the process of becoming a Router.
+     * @retval OT_ERROR_NOT_FOUND      Server Data is already consistent with network data.
      *
      */
-    otError SendServerDataNotification(void);
+    otError UpdateInconsistentServerData(Coap::ResponseHandler aHandler, void *aContext);
 
 private:
     void UpdateRloc(void);
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
-    void UpdateRloc(PrefixTlv &aPrefix);
-    void UpdateRloc(HasRouteTlv &aHasRoute);
-    void UpdateRloc(BorderRouterTlv &aBorderRouter);
-    bool IsOnMeshPrefixConsistent(void);
-    bool IsExternalRouteConsistent(void);
+    otError AddPrefix(const uint8_t *      aPrefix,
+                      uint8_t              aPrefixLength,
+                      NetworkDataTlv::Type aSubTlvType,
+                      int8_t               aPrf,
+                      uint16_t             aFlags,
+                      bool                 aStable);
+    otError RemovePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, NetworkDataTlv::Type aSubTlvType);
+    void    UpdateRloc(PrefixTlv &aPrefix);
+    bool    IsOnMeshPrefixConsistent(void) const;
+    bool    IsExternalRouteConsistent(void) const;
 #endif
 
 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
     void UpdateRloc(ServiceTlv &aService);
-    void UpdateRloc(ServerTlv &aServer);
-    bool IsServiceConsistent(void);
+    bool IsServiceConsistent(void) const;
 #endif
 
     uint16_t mOldRloc;
diff --git a/src/core/thread/network_data_notifier.cpp b/src/core/thread/network_data_notifier.cpp
new file mode 100644
index 0000000..261789c
--- /dev/null
+++ b/src/core/thread/network_data_notifier.cpp
@@ -0,0 +1,167 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements transmissions of SVR_DATA.ntf messages to the Leader.
+ */
+
+#include "network_data_notifier.hpp"
+
+#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+
+#include "common/code_utils.hpp"
+#include "common/instance.hpp"
+#include "common/locator-getters.hpp"
+#include "thread/network_data_leader.hpp"
+#include "thread/network_data_local.hpp"
+
+namespace ot {
+namespace NetworkData {
+
+Notifier::Notifier(Instance &aInstance)
+    : InstanceLocator(aInstance)
+    , ot::Notifier::Receiver(aInstance, Notifier::HandleNotifierEvents)
+    , mTimer(aInstance, Notifier::HandleTimer, this)
+    , mNextDelay(0)
+    , mWaitingForResponse(false)
+{
+}
+
+void Notifier::HandleServerDataUpdated(void)
+{
+    mNextDelay = 0;
+    SynchronizeServerData();
+}
+
+void Notifier::SynchronizeServerData(void)
+{
+    otError error = OT_ERROR_NOT_FOUND;
+
+    VerifyOrExit(Get<Mle::MleRouter>().IsAttached() && !mWaitingForResponse, OT_NOOP);
+
+    VerifyOrExit((mNextDelay == 0) || !mTimer.IsRunning(), OT_NOOP);
+
+#if OPENTHREAD_FTD
+    mNextDelay = kDelayRemoveStaleChildren;
+    error      = Get<Leader>().RemoveStaleChildEntries(&Notifier::HandleCoapResponse, this);
+    VerifyOrExit(error == OT_ERROR_NOT_FOUND, OT_NOOP);
+#endif
+
+#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+    mNextDelay = kDelaySynchronizeServerData;
+    error      = Get<Local>().UpdateInconsistentServerData(&Notifier::HandleCoapResponse, this);
+    VerifyOrExit(error == OT_ERROR_NOT_FOUND, OT_NOOP);
+#endif
+
+exit:
+    switch (error)
+    {
+    case OT_ERROR_NONE:
+        mWaitingForResponse = true;
+        break;
+    case OT_ERROR_NO_BUFS:
+        mTimer.Start(kDelayNoBufs);
+        break;
+#if OPENTHREAD_FTD
+    case OT_ERROR_INVALID_STATE:
+        mTimer.Start(Time::SecToMsec(Get<Mle::MleRouter>().GetRouterSelectionJitterTimeout() + 1));
+        break;
+#endif
+    case OT_ERROR_NOT_FOUND:
+        break;
+    default:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
+    }
+}
+
+void Notifier::HandleNotifierEvents(ot::Notifier::Receiver &aReceiver, Events aEvents)
+{
+    static_cast<Notifier &>(aReceiver).HandleNotifierEvents(aEvents);
+}
+
+void Notifier::HandleNotifierEvents(Events aEvents)
+{
+    if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadChildRemoved))
+    {
+        mNextDelay = 0;
+    }
+
+    if (aEvents.ContainsAny(kEventThreadNetdataChanged | kEventThreadRoleChanged | kEventThreadChildRemoved))
+    {
+        SynchronizeServerData();
+    }
+}
+
+void Notifier::HandleTimer(Timer &aTimer)
+{
+    aTimer.GetOwner<Notifier>().HandleTimer();
+}
+
+void Notifier::HandleTimer(void)
+{
+    SynchronizeServerData();
+}
+
+void Notifier::HandleCoapResponse(void *               aContext,
+                                  otMessage *          aMessage,
+                                  const otMessageInfo *aMessageInfo,
+                                  otError              aResult)
+{
+    OT_UNUSED_VARIABLE(aMessage);
+    OT_UNUSED_VARIABLE(aMessageInfo);
+
+    static_cast<Notifier *>(aContext)->HandleCoapResponse(aResult);
+}
+
+void Notifier::HandleCoapResponse(otError aResult)
+{
+    mWaitingForResponse = false;
+
+    switch (aResult)
+    {
+    case OT_ERROR_NONE:
+        mTimer.Start(mNextDelay + 1);
+        break;
+
+    case OT_ERROR_RESPONSE_TIMEOUT:
+    case OT_ERROR_ABORT:
+        SynchronizeServerData();
+        break;
+
+    default:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
+    }
+}
+
+} // namespace NetworkData
+} // namespace ot
+
+#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
diff --git a/src/core/thread/network_data_notifier.hpp b/src/core/thread/network_data_notifier.hpp
new file mode 100644
index 0000000..0d64959
--- /dev/null
+++ b/src/core/thread/network_data_notifier.hpp
@@ -0,0 +1,101 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for transmitting SVR_DATA.ntf messages.
+ */
+
+#ifndef NETWORK_DATA_NOTIFIER_HPP_
+#define NETWORK_DATA_NOTIFIER_HPP_
+
+#include "openthread-core-config.h"
+
+#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+
+#include "coap/coap.hpp"
+#include "common/message.hpp"
+#include "common/notifier.hpp"
+
+namespace ot {
+namespace NetworkData {
+
+/**
+ * This class implements the SVR_DATA.ntf transmission logic.
+ *
+ */
+class Notifier : public InstanceLocator, public ot::Notifier::Receiver
+{
+public:
+    /**
+     * Constructor.
+     *
+     * @param[in] aInstance  The OpenThread instance.
+     *
+     */
+    Notifier(Instance &aInstance);
+
+    /**
+     * Call this method to inform the notifier that new server data is available.
+     *
+     */
+    void HandleServerDataUpdated(void);
+
+private:
+    enum
+    {
+        kDelayNoBufs                = 1000,   ///< milliseconds
+        kDelayRemoveStaleChildren   = 5000,   ///< milliseconds
+        kDelaySynchronizeServerData = 300000, ///< milliseconds
+    };
+
+    static void HandleNotifierEvents(ot::Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
+
+    static void HandleTimer(Timer &aTimer);
+    void        HandleTimer(void);
+
+    static void HandleCoapResponse(void *               aContext,
+                                   otMessage *          aMessage,
+                                   const otMessageInfo *aMessageInfo,
+                                   otError              aResult);
+    void        HandleCoapResponse(otError aResult);
+
+    void SynchronizeServerData(void);
+
+    TimerMilli mTimer;
+    uint32_t   mNextDelay;
+    bool       mWaitingForResponse;
+};
+
+} // namespace NetworkData
+} // namespace ot
+
+#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+
+#endif // NETWORK_DATA_NOTIFIER_HPP_
diff --git a/src/core/thread/network_data_tlvs.hpp b/src/core/thread/network_data_tlvs.hpp
index 7df17a6..a93ffd6 100644
--- a/src/core/thread/network_data_tlvs.hpp
+++ b/src/core/thread/network_data_tlvs.hpp
@@ -36,15 +36,18 @@
 
 #include "openthread-core-config.h"
 
-#include "common/encoding.hpp"
-#include "net/ip6_address.hpp"
+#include <openthread/netdata.h>
 
-#define THREAD_ENTERPRISE_NUMBER 44970
+#include "common/debug.hpp"
+#include "common/encoding.hpp"
+#include "common/equatable.hpp"
+#include "net/ip6_address.hpp"
 
 namespace ot {
 namespace NetworkData {
 
 using ot::Encoding::BigEndian::HostSwap16;
+using ot::Encoding::BigEndian::HostSwap32;
 
 /**
  * @addtogroup core-netdata-tlvs
@@ -122,6 +125,30 @@
     void SetLength(uint8_t aLength) { mLength = aLength; }
 
     /**
+     * This methods increases the Length value by a given amount.
+     *
+     * @param[in]  aIncrement  The increment amount to increase the length.
+     *
+     */
+    void IncreaseLength(uint8_t aIncrement) { mLength += aIncrement; }
+
+    /**
+     * This methods decreases the Length value by a given amount.
+     *
+     * @param[in]  aDecrement  The decrement amount to decrease the length.
+     *
+     */
+    void DecreaseLength(uint8_t aDecrement) { mLength -= aDecrement; }
+
+    /**
+     * This method returns the TLV's total size (number of bytes) including Type, Length, and Value fields.
+     *
+     * @returns The total size include Type, Length, and Value fields.
+     *
+     */
+    uint8_t GetSize(void) const { return sizeof(NetworkDataTlv) + mLength; }
+
+    /**
      * This method returns a pointer to the Value.
      *
      * @returns A pointer to the value.
@@ -130,6 +157,14 @@
     uint8_t *GetValue(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(NetworkDataTlv); }
 
     /**
+     * This method returns a pointer to the Value.
+     *
+     * @returns A pointer to the value.
+     *
+     */
+    const uint8_t *GetValue(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(NetworkDataTlv); }
+
+    /**
      * This method returns a pointer to the next Network Data TLV.
      *
      * @returns A pointer to the next Network Data TLV.
@@ -141,6 +176,18 @@
     }
 
     /**
+     * This method returns a pointer to the next Network Data TLV.
+     *
+     * @returns A pointer to the next Network Data TLV.
+     *
+     */
+    const NetworkDataTlv *GetNext(void) const
+    {
+        return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(this) + sizeof(*this) +
+                                                        mLength);
+    }
+
+    /**
      * This method clears the Stable bit.
      *
      */
@@ -177,7 +224,7 @@
  *
  */
 OT_TOOL_PACKED_BEGIN
-class HasRouteEntry
+class HasRouteEntry : public Equatable<HasRouteEntry>
 {
 public:
     /**
@@ -221,8 +268,8 @@
      */
     void SetPreference(int8_t aPrf)
     {
-        assert((aPrf == OT_ROUTE_PREFERENCE_LOW) || (aPrf == OT_ROUTE_PREFERENCE_MED) ||
-               (aPrf == OT_ROUTE_PREFERENCE_HIGH));
+        OT_ASSERT((aPrf == OT_ROUTE_PREFERENCE_LOW) || (aPrf == OT_ROUTE_PREFERENCE_MED) ||
+                  (aPrf == OT_ROUTE_PREFERENCE_HIGH));
         mFlags = (mFlags & ~kPreferenceMask) | ((static_cast<uint8_t>(aPrf) << kPreferenceOffset) & kPreferenceMask);
     }
 
@@ -234,6 +281,14 @@
      */
     HasRouteEntry *GetNext(void) { return (this + 1); }
 
+    /**
+     * This method returns a pointer to the next HasRouteEntry.
+     *
+     * @returns A pointer to the next HasRouteEntry.
+     *
+     */
+    const HasRouteEntry *GetNext(void) const { return (this + 1); }
+
 private:
     enum
     {
@@ -253,6 +308,11 @@
 class HasRouteTlv : public NetworkDataTlv
 {
 public:
+    enum
+    {
+        kType = kTypeHasRoute, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -273,16 +333,29 @@
     uint8_t GetNumEntries(void) const { return GetLength() / sizeof(HasRouteEntry); }
 
     /**
-     * This method returns a pointer to the i'th HasRoute entry.
+     * This method returns a pointer to the HasRoute entry at a given index.
      *
-     * @param[in]  i  An index.
+     * @param[in]  aIndex  An index.
      *
-     * @returns A pointer to the i'th HasRoute entry.
+     * @returns A pointer to the HasRoute entry at @p aIndex.
      *
      */
-    HasRouteEntry *GetEntry(uint8_t i)
+    HasRouteEntry *GetEntry(uint8_t aIndex)
     {
-        return reinterpret_cast<HasRouteEntry *>(GetValue() + (i * sizeof(HasRouteEntry)));
+        return reinterpret_cast<HasRouteEntry *>(GetValue() + (aIndex * sizeof(HasRouteEntry)));
+    }
+
+    /**
+     * This method returns a pointer to the HasRoute entry at a given index.
+     *
+     * @param[in]  aIndex  An index.
+     *
+     * @returns A pointer to the HasRoute entry at @p aIndex.
+     *
+     */
+    const HasRouteEntry *GetEntry(uint8_t aIndex) const
+    {
+        return reinterpret_cast<const HasRouteEntry *>(GetValue() + (aIndex * sizeof(HasRouteEntry)));
     }
 
     /**
@@ -294,6 +367,14 @@
     HasRouteEntry *GetFirstEntry(void) { return reinterpret_cast<HasRouteEntry *>(GetValue()); }
 
     /**
+     * This method returns a pointer to the first HasRouteEntry (at index 0'th).
+     *
+     * @returns A pointer to the first HasRouteEntry.
+     *
+     */
+    const HasRouteEntry *GetFirstEntry(void) const { return reinterpret_cast<const HasRouteEntry *>(GetValue()); }
+
+    /**
      * This method returns a pointer to the last HasRouteEntry.
      *
      * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer.
@@ -305,6 +386,20 @@
     {
         return reinterpret_cast<HasRouteEntry *>(GetValue() + GetLength() - sizeof(HasRouteEntry));
     }
+
+    /**
+     * This method returns a pointer to the last HasRouteEntry.
+     *
+     * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer.
+     *
+     * @returns A pointer to the last HasRouteEntry.
+     *
+     */
+    const HasRouteEntry *GetLastEntry(void) const
+    {
+        return reinterpret_cast<const HasRouteEntry *>(GetValue() + GetLength() - sizeof(HasRouteEntry));
+    }
+
 } OT_TOOL_PACKED_END;
 
 /**
@@ -315,11 +410,16 @@
 class PrefixTlv : public NetworkDataTlv
 {
 public:
+    enum
+    {
+        kType = kTypePrefix, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
      * @param[in]  aDomainId      The Domain ID.
-     * @param[in]  aPrefixLength  The Prefix Length
+     * @param[in]  aPrefixLength  The Prefix Length in bits.
      * @param[in]  aPrefix        A pointer to the prefix.
      *
      */
@@ -358,7 +458,7 @@
     /**
      * This method returns the Prefix Length value.
      *
-     * @returns The Prefix Length value.
+     * @returns The Prefix Length value (in bits).
      *
      */
     uint8_t GetPrefixLength(void) const { return mPrefixLength; }
@@ -372,6 +472,14 @@
     uint8_t *GetPrefix(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); }
 
     /**
+     * This method returns a pointer to the Prefix.
+     *
+     * @returns A pointer to the Prefix.
+     *
+     */
+    const uint8_t *GetPrefix(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
+
+    /**
      * This method returns a pointer to the Sub-TLVs.
      *
      * @returns A pointer to the Sub-TLVs.
@@ -383,6 +491,17 @@
     }
 
     /**
+     * This method returns a pointer to the Sub-TLVs.
+     *
+     * @returns A pointer to the Sub-TLVs.
+     *
+     */
+    const NetworkDataTlv *GetSubTlvs(void) const
+    {
+        return reinterpret_cast<const NetworkDataTlv *>(GetPrefix() + BitVectorBytes(mPrefixLength));
+    }
+
+    /**
      * This method returns the Sub-TLVs length in bytes.
      *
      * @returns The Sub-TLVs length in bytes.
@@ -404,6 +523,19 @@
         SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + BitVectorBytes(mPrefixLength) + aLength);
     }
 
+    /**
+     * This static method calculates the total size (number of bytes) of a Prefix TLV with a given Prefix Length value.
+     *
+     * Note that the returned size does include the Type and Length fields in the TLV, but does not account for any
+     * sub TLVs of the Prefix TLV.
+     *
+     * @param[in]  aPrefixLength     A Prefix Length in bits.
+
+     * @returns    The size (number of bytes) of the Prefix TLV.
+     *
+     */
+    static uint16_t CalculateSize(uint8_t aPrefixLength) { return sizeof(PrefixTlv) + BitVectorBytes(aPrefixLength); }
+
 private:
     uint8_t mDomainId;
     uint8_t mPrefixLength;
@@ -414,19 +546,21 @@
  *
  */
 OT_TOOL_PACKED_BEGIN
-class BorderRouterEntry
+class BorderRouterEntry : public Equatable<BorderRouterEntry>
 {
 public:
     enum
     {
-        kPreferenceOffset = 6,
+        kPreferenceOffset = 14,
         kPreferenceMask   = 3 << kPreferenceOffset,
-        kPreferredFlag    = 1 << 5,
-        kSlaacFlag        = 1 << 4,
-        kDhcpFlag         = 1 << 3,
-        kConfigureFlag    = 1 << 2,
-        kDefaultRouteFlag = 1 << 1,
-        kOnMeshFlag       = 1 << 0,
+        kPreferredFlag    = 1 << 13,
+        kSlaacFlag        = 1 << 12,
+        kDhcpFlag         = 1 << 11,
+        kConfigureFlag    = 1 << 10,
+        kDefaultRouteFlag = 1 << 9,
+        kOnMeshFlag       = 1 << 8,
+        kNdDnsFlag        = 1 << 7,
+        kDpFlag           = 1 << 6,
     };
 
     /**
@@ -436,8 +570,7 @@
     void Init(void)
     {
         SetRloc(Mac::kShortAddrInvalid);
-        mFlags    = 0;
-        mReserved = 0;
+        mFlags = 0;
     }
 
     /**
@@ -456,20 +589,23 @@
     void SetRloc(uint16_t aRloc16) { mRloc = HostSwap16(aRloc16); }
 
     /**
-     * This method returns the Flags byte value.
+     * This method returns the Flags value.
      *
-     * @returns The Flags byte value.
+     * @returns The Flags value.
      *
      */
-    uint8_t GetFlags(void) const { return mFlags & ~kPreferenceMask; }
+    uint16_t GetFlags(void) const { return HostSwap16(mFlags) & ~kPreferenceMask; }
 
     /**
-     * This method sets the Flags byte value.
+     * This method sets the Flags value.
      *
-     * @param[in]  aFlags  The Flags byte value.
+     * @param[in]  aFlags  The Flags value.
      *
      */
-    void SetFlags(uint8_t aFlags) { mFlags = (mFlags & kPreferenceMask) | (aFlags & ~kPreferenceMask); }
+    void SetFlags(uint16_t aFlags)
+    {
+        mFlags = HostSwap16((HostSwap16(mFlags) & kPreferenceMask) | (aFlags & ~kPreferenceMask));
+    }
 
     /**
      * This method returns the Preference value.
@@ -477,7 +613,10 @@
      * @returns the Preference value.
      *
      */
-    int8_t GetPreference(void) const { return static_cast<int8_t>(mFlags) >> kPreferenceOffset; }
+    int8_t GetPreference(void) const
+    {
+        return static_cast<int8_t>(static_cast<int16_t>(HostSwap16(mFlags)) >> kPreferenceOffset);
+    }
 
     /**
      * This method sets the Preference value.
@@ -487,7 +626,7 @@
      */
     void SetPreference(int8_t aPrf)
     {
-        mFlags = (mFlags & ~kPreferenceMask) | ((static_cast<uint8_t>(aPrf) << kPreferenceOffset) & kPreferenceMask);
+        mFlags = HostSwap16(GetFlags() | ((static_cast<uint16_t>(aPrf) << kPreferenceOffset) & kPreferenceMask));
     }
 
     /**
@@ -497,19 +636,7 @@
      * @retval FALSE  If the Preferred flag is not set.
      *
      */
-    bool IsPreferred(void) const { return (mFlags & kPreferredFlag) != 0; }
-
-    /**
-     * This method clears the Preferred flag.
-     *
-     */
-    void ClearPreferred(void) { mFlags &= ~kPreferredFlag; }
-
-    /**
-     * This method sets the Preferred flag.
-     *
-     */
-    void SetPreferred(void) { mFlags |= kPreferredFlag; }
+    bool IsPreferred(void) const { return (HostSwap16(mFlags) & kPreferredFlag) != 0; }
 
     /**
      * This method indicates whether or not the SLAAC flag is set.
@@ -518,19 +645,7 @@
      * @retval FALSE  If the SLAAC flag is not set.
      *
      */
-    bool IsSlaac(void) const { return (mFlags & kSlaacFlag) != 0; }
-
-    /**
-     * This method clears the SLAAC flag.
-     *
-     */
-    void ClearSlaac(void) { mFlags &= ~kSlaacFlag; }
-
-    /**
-     * This method sets the SLAAC flag.
-     *
-     */
-    void SetSlaac(void) { mFlags |= kSlaacFlag; }
+    bool IsSlaac(void) const { return (HostSwap16(mFlags) & kSlaacFlag) != 0; }
 
     /**
      * This method indicates whether or not the DHCP flag is set.
@@ -539,19 +654,7 @@
      * @retval FALSE  If the DHCP flag is not set.
      *
      */
-    bool IsDhcp(void) const { return (mFlags & kDhcpFlag) != 0; }
-
-    /**
-     * This method clears the DHCP flag.
-     *
-     */
-    void ClearDhcp(void) { mFlags &= ~kDhcpFlag; }
-
-    /**
-     * This method sets the DHCP flag.
-     *
-     */
-    void SetDhcp(void) { mFlags |= kDhcpFlag; }
+    bool IsDhcp(void) const { return (HostSwap16(mFlags) & kDhcpFlag) != 0; }
 
     /**
      * This method indicates whether or not the Configure flag is set.
@@ -560,19 +663,7 @@
      * @retval FALSE  If the Configure flag is not set.
      *
      */
-    bool IsConfigure(void) const { return (mFlags & kConfigureFlag) != 0; }
-
-    /**
-     * This method clears the Configure flag.
-     *
-     */
-    void ClearConfigure(void) { mFlags &= ~kConfigureFlag; }
-
-    /**
-     * This method sets the Configure flag.
-     *
-     */
-    void SetConfigure(void) { mFlags |= kConfigureFlag; }
+    bool IsConfigure(void) const { return (HostSwap16(mFlags) & kConfigureFlag) != 0; }
 
     /**
      * This method indicates whether or not the Default Route flag is set.
@@ -581,19 +672,7 @@
      * @retval FALSE  If the Default Route flag is not set.
      *
      */
-    bool IsDefaultRoute(void) const { return (mFlags & kDefaultRouteFlag) != 0; }
-
-    /**
-     * This method clears the Default Route flag.
-     *
-     */
-    void ClearDefaultRoute(void) { mFlags &= ~kDefaultRouteFlag; }
-
-    /**
-     * This method sets the Default Route flag.
-     *
-     */
-    void SetDefaultRoute(void) { mFlags |= kDefaultRouteFlag; }
+    bool IsDefaultRoute(void) const { return (HostSwap16(mFlags) & kDefaultRouteFlag) != 0; }
 
     /**
      * This method indicates whether or not the On-Mesh flag is set.
@@ -602,19 +681,25 @@
      * @retval FALSE  If the On-Mesh flag is not set.
      *
      */
-    bool IsOnMesh(void) const { return (mFlags & kOnMeshFlag) != 0; }
+    bool IsOnMesh(void) const { return (HostSwap16(mFlags) & kOnMeshFlag) != 0; }
 
     /**
-     * This method clears the On-Mesh flag.
+     * This method indicates whether or not the Nd-Dns flag is set.
+     *
+     * @retval TRUE   If the Nd-Dns flag is set.
+     * @retval FALSE  If the Nd-Dns flag is not set.
      *
      */
-    void ClearOnMesh(void) { mFlags &= ~kOnMeshFlag; }
+    bool IsNdDns(void) const { return (HostSwap16(mFlags) & kNdDnsFlag) != 0; }
 
     /**
-     * This method sets the On-Mesh flag.
+     * This method indicates whether or not the Domain Prefix flag is set.
+     *
+     * @retval TRUE   If the Domain Prefix flag is set.
+     * @retval FALSE  If the Domain Prefix flag is not set.
      *
      */
-    void SetOnMesh(void) { mFlags |= kOnMeshFlag; }
+    bool IsDp(void) const { return (HostSwap16(mFlags) & kDpFlag) != 0; }
 
     /**
      * This method returns a pointer to the next BorderRouterEntry
@@ -624,10 +709,17 @@
      */
     BorderRouterEntry *GetNext(void) { return (this + 1); }
 
+    /**
+     * This method returns a pointer to the next BorderRouterEntry
+     *
+     * @returns A pointer to the next BorderRouterEntry.
+     *
+     */
+    const BorderRouterEntry *GetNext(void) const { return (this + 1); }
+
 private:
     uint16_t mRloc;
-    uint8_t  mFlags;
-    uint8_t  mReserved;
+    uint16_t mFlags;
 } OT_TOOL_PACKED_END;
 
 /**
@@ -638,6 +730,11 @@
 class BorderRouterTlv : public NetworkDataTlv
 {
 public:
+    enum
+    {
+        kType = kTypeBorderRouter, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -658,16 +755,29 @@
     uint8_t GetNumEntries(void) const { return GetLength() / sizeof(BorderRouterEntry); }
 
     /**
-     * This method returns a pointer to the i'th Border Router entry.
+     * This method returns a pointer to the Border Router entry at a given index
      *
-     * @param[in]  i  The index.
+     * @param[in]  aIndex  The index.
      *
-     * @returns A pointer to the i'th Border Router entry.
+     * @returns A pointer to the Border Router entry at @p aIndex.
      *
      */
-    BorderRouterEntry *GetEntry(uint8_t i)
+    BorderRouterEntry *GetEntry(uint8_t aIndex)
     {
-        return reinterpret_cast<BorderRouterEntry *>(GetValue() + (i * sizeof(BorderRouterEntry)));
+        return reinterpret_cast<BorderRouterEntry *>(GetValue() + (aIndex * sizeof(BorderRouterEntry)));
+    }
+
+    /**
+     * This method returns a pointer to the Border Router entry at a given index.
+     *
+     * @param[in]  aIndex  The index.
+     *
+     * @returns A pointer to the Border Router entry at @p aIndex
+     *
+     */
+    const BorderRouterEntry *GetEntry(uint8_t aIndex) const
+    {
+        return reinterpret_cast<const BorderRouterEntry *>(GetValue() + (aIndex * sizeof(BorderRouterEntry)));
     }
 
     /**
@@ -679,6 +789,17 @@
     BorderRouterEntry *GetFirstEntry(void) { return reinterpret_cast<BorderRouterEntry *>(GetValue()); }
 
     /**
+     * This method returns a pointer to the first BorderRouterEntry (at index 0'th).
+     *
+     * @returns A pointer to the first BorderRouterEntry.
+     *
+     */
+    const BorderRouterEntry *GetFirstEntry(void) const
+    {
+        return reinterpret_cast<const BorderRouterEntry *>(GetValue());
+    }
+
+    /**
      * This method returns a pointer to the last BorderRouterEntry.
      *
      * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer.
@@ -690,6 +811,20 @@
     {
         return reinterpret_cast<BorderRouterEntry *>(GetValue() + GetLength() - sizeof(BorderRouterEntry));
     }
+
+    /**
+     * This method returns a pointer to the last BorderRouterEntry.
+     *
+     * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer.
+     *
+     * @returns A pointer to the last BorderRouterEntry.
+     *
+     */
+    const BorderRouterEntry *GetLastEntry(void) const
+    {
+        return reinterpret_cast<const BorderRouterEntry *>(GetValue() + GetLength() - sizeof(BorderRouterEntry));
+    }
+
 } OT_TOOL_PACKED_END;
 
 /**
@@ -700,17 +835,25 @@
 class ContextTlv : public NetworkDataTlv
 {
 public:
+    enum
+    {
+        kType = kTypeContext, ///< The TLV Type.
+    };
+
     /**
-     * This method initializes the TLV.
+     * This method initializes the Context TLV.
+     *
+     * @param[in]  aConextId   The Context ID value.
+     * @param[in]  aLength     The Context Length value.
      *
      */
-    void Init(void)
+    void Init(uint8_t aContextId, uint8_t aConextLength)
     {
         NetworkDataTlv::Init();
         SetType(kTypeContext);
-        SetLength(2);
-        mFlags         = 0;
-        mContextLength = 0;
+        SetLength(sizeof(ContextTlv) - sizeof(NetworkDataTlv));
+        mFlags         = ((aContextId << kContextIdOffset) & kContextIdMask);
+        mContextLength = aConextLength;
     }
 
     /**
@@ -743,17 +886,6 @@
     uint8_t GetContextId(void) const { return mFlags & kContextIdMask; }
 
     /**
-     * This method sets the Context ID value.
-     *
-     * @param[in]  aContextId  The Context ID value.
-     *
-     */
-    void SetContextId(uint8_t aContextId)
-    {
-        mFlags = (mFlags & ~kContextIdMask) | ((aContextId << kContextIdOffset) & kContextIdMask);
-    }
-
-    /**
      * This method returns the Context Length value.
      *
      * @returns The Context Length value.
@@ -761,14 +893,6 @@
      */
     uint8_t GetContextLength(void) const { return mContextLength; }
 
-    /**
-     * This method sets the Context Length value.
-     *
-     * @param[in]  aLength  The Context Length value.
-     *
-     */
-    void SetContextLength(uint8_t aLength) { mContextLength = aLength; }
-
 private:
     enum
     {
@@ -788,6 +912,11 @@
 class CommissioningDataTlv : public NetworkDataTlv
 {
 public:
+    enum
+    {
+        kType = kTypeCommissioningData, ///< The TLV Type.
+    };
+
     /**
      * This method initializes the TLV.
      *
@@ -808,17 +937,43 @@
 class ServiceTlv : public NetworkDataTlv
 {
 public:
+    enum
+    {
+        kType                      = kTypeService, ///< The TLV Type.
+        kThreadEnterpriseNumber    = 44970,        ///< Thread enterprise number.
+        kServiceDataBackboneRouter = 0x01,         ///< const THREAD_SERVICE_DATA_BBR
+    };
+
     /**
      * This method initializes the TLV.
-     * Initial length is set to 2, to hold S_service_data_length field.
+     *
+     * @param[in]  aServiceId          The Service Id value.
+     * @param[in]  aEnterpriseNumber   The Enterprise Number.
+     * @param[in]  aServiceData        The Service Data.
+     * @param[in]  aServiceDataLength  The Service Data length (number of bytes).
+     *
      */
-    void Init(void)
+    void Init(uint8_t aServiceId, uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength)
     {
         NetworkDataTlv::Init();
         SetType(kTypeService);
-        SetLength(2);
-        mTResSId = kTMask;
-        SetServiceDataLength(0);
+
+        mFlagsServiceId = (aEnterpriseNumber == kThreadEnterpriseNumber) ? kThreadEnterpriseFlag : 0;
+        mFlagsServiceId |= (aServiceId & kServiceIdMask);
+
+        if (aEnterpriseNumber != kThreadEnterpriseNumber)
+        {
+            mShared.mEnterpriseNumber = HostSwap32(aEnterpriseNumber);
+            mServiceDataLength        = aServiceDataLength;
+            memcpy(&mServiceDataLength + sizeof(uint8_t), aServiceData, aServiceDataLength);
+        }
+        else
+        {
+            mShared.mServiceDataLengthThreadEnterprise = aServiceDataLength;
+            memcpy(&mShared.mServiceDataLengthThreadEnterprise + sizeof(uint8_t), aServiceData, aServiceDataLength);
+        }
+
+        SetLength(GetFieldsLength());
     }
 
     /**
@@ -828,133 +983,69 @@
      * @retval FALSE  If the TLV does not appear to be well-formed.
      *
      */
-    bool IsValid(void)
+    bool IsValid(void) const
     {
         uint8_t length = GetLength();
-        return ((length >= (sizeof(*this) - sizeof(NetworkDataTlv))) &&
-                (length >= ((sizeof(*this) - sizeof(NetworkDataTlv)) + (IsThreadEnterprise() ? 0 : sizeof(uint32_t)) +
-                            sizeof(uint8_t))) &&
-                (length >= ((sizeof(*this) - sizeof(NetworkDataTlv)) + (IsThreadEnterprise() ? 0 : sizeof(uint32_t)) +
-                            sizeof(uint8_t) + GetServiceDataLength())));
+
+        return (length >= sizeof(mFlagsServiceId)) &&
+               (length >= kMinLength + (IsThreadEnterprise() ? 0 : sizeof(uint32_t))) &&
+               (static_cast<uint16_t>(length) + sizeof(NetworkDataTlv) >=
+                CalculateSize(GetEnterpriseNumber(), GetServiceDataLength()));
+    }
+
+    /**
+     * This method returns the Service ID. It is in range 0x00-0x0f.
+     *
+     * @returns the Service ID.
+     *
+     */
+    uint8_t GetServiceId(void) const { return (mFlagsServiceId & kServiceIdMask); }
+
+    /**
+     * This method returns Enterprise Number field.
+     *
+     * @returns The Enterprise Number.
+     *
+     */
+    uint32_t GetEnterpriseNumber(void) const
+    {
+        return IsThreadEnterprise() ? static_cast<uint32_t>(kThreadEnterpriseNumber)
+                                    : HostSwap32(mShared.mEnterpriseNumber);
     }
 
     /**
      * This method gets Service Data length.
      *
      * @returns length of the Service Data field in bytes.
-     */
-    uint8_t GetServiceDataLength(void) { return *GetServiceDataLengthLocation(); }
-
-    /**
-     * This method sets Service Data length.
      *
-     * @param aServiceDataLength desired length of the Service Data field in bytes.
      */
-    void SetServiceDataLength(uint8_t aServiceDataLength) { *GetServiceDataLengthLocation() = aServiceDataLength; }
+    uint8_t GetServiceDataLength(void) const
+    {
+        return IsThreadEnterprise() ? mShared.mServiceDataLengthThreadEnterprise : mServiceDataLength;
+    }
 
     /**
      * This method returns a pointer to the Service Data.
      *
      * @returns A pointer to the Service Data.
-     */
-    uint8_t *GetServiceData(void) { return GetServiceDataLengthLocation() + sizeof(uint8_t); }
-
-    /**
-     * This method sets Service Data to the given values.
      *
-     * Caller must ensure that there is enough memory allocated.
-     *
-     * @param aServiceData       pointer to the service data to use
-     * @param aServiceDataLength length of the provided service data in bytes
      */
-    void SetServiceData(const uint8_t *aServiceData, uint8_t aServiceDataLength)
+    uint8_t *GetServiceData(void)
     {
-        SetServiceDataLength(aServiceDataLength);
-
-        memcpy(GetServiceData(), aServiceData, aServiceDataLength);
+        return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) +
+               sizeof(uint8_t);
     }
 
     /**
-     * This method returns Enterprise Number field.
+     * This method returns a pointer to the Service Data.
      *
-     * @returns Enterprise Number
+     * @returns A pointer to the Service Data.
+     *
      */
-    uint32_t GetEnterpriseNumber(void)
+    const uint8_t *GetServiceData(void) const
     {
-        if (IsThreadEnterprise())
-        {
-            return THREAD_ENTERPRISE_NUMBER;
-        }
-        else
-        {
-            // This memory access most likely will not be aligned to 4 bytes
-            return HostSwap32(*reinterpret_cast<uint32_t *>(GetEnterpriseNumberLocation()));
-        }
-    }
-
-    /**
-     * This method returns the T flag. It is set when Enterprise Number is equal to THREAD_ENTERPRISE_NUMBER.
-     *
-     * @returns Flag whether Enterprise Number is equal to THREAD_ENTERPRISE_NUMBER
-     */
-    bool IsThreadEnterprise(void) const { return (mTResSId & kTMask) != 0; }
-
-    /**
-     * This method sets Enterprise Number and updates the T flag.
-     *
-     * Note: this method does not preserve service data / sub-TLV fields. Changing the T flag and inserting
-     * few bytes in the middle of this TLV effectively destroys rest of the content of this TLV (and might lead to
-     * memory corruption) so modification of Enterprise Number must be done before adding any content to the TLV.
-     *
-     * @param [in] aEnterpriseNumber Enterprise Number
-     */
-    void SetEnterpriseNumber(uint32_t aEnterpriseNumber)
-    {
-        if (aEnterpriseNumber == THREAD_ENTERPRISE_NUMBER)
-        {
-            mTResSId |= kTMask;
-        }
-        else
-        {
-            mTResSId &= ~kTMask;
-
-            // This memory access most likely will not be aligned to 4 bytes
-            *reinterpret_cast<uint32_t *>(GetEnterpriseNumberLocation()) = HostSwap32(aEnterpriseNumber);
-        }
-    }
-
-    /**
-     * This method returns length of the S_enterprise_number TLV field in bytes, for given Enterprise Number.
-     *
-     * @returns length of the S_enterprise_number field in bytes
-     */
-    static uint8_t GetEnterpriseNumberFieldLength(uint32_t aEnterpriseNumber)
-    {
-        if (aEnterpriseNumber == THREAD_ENTERPRISE_NUMBER)
-        {
-            return 0;
-        }
-        else
-        {
-            return (sizeof(aEnterpriseNumber));
-        }
-    }
-
-    /**
-     * This method returns Service ID. It is in range 0x00-0x0f.
-     *
-     * @returns Service ID
-     */
-    uint8_t GetServiceID(void) const { return (mTResSId & kSIdMask) >> kSIdOffset; }
-
-    /**
-     * This method sets Service ID.
-     *
-     * @param [in] aServiceID Service ID to be set. Expected range: 0x00-0x0f.
-     */
-    void SetServiceID(uint8_t aServiceID)
-    {
-        mTResSId = static_cast<uint8_t>((mTResSId & ~kSIdMask) | (aServiceID << kSIdOffset));
+        return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) +
+               sizeof(uint8_t);
     }
 
     /**
@@ -963,11 +1054,7 @@
      * @returns The Sub-TLVs length in bytes.
      *
      */
-    uint8_t GetSubTlvsLength(void)
-    {
-        return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv)) - (IsThreadEnterprise() ? 0 : sizeof(uint32_t)) -
-               sizeof(uint8_t) /* mServiceDataLength */ - GetServiceDataLength();
-    }
+    uint8_t GetSubTlvsLength(void) { return GetLength() - GetFieldsLength(); }
 
     /**
      * This method sets the Sub-TLVs length in bytes.
@@ -975,11 +1062,7 @@
      * @param[in]  aLength  The Sub-TLVs length in bytes.
      *
      */
-    void SetSubTlvsLength(uint8_t aLength)
-    {
-        SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + (IsThreadEnterprise() ? 0 : sizeof(uint32_t)) +
-                  sizeof(uint8_t) /* mServiceDataLength */ + GetServiceDataLength() + aLength);
-    }
+    void SetSubTlvsLength(uint8_t aLength) { SetLength(GetFieldsLength() + aLength); }
 
     /**
      * This method returns a pointer to the Sub-TLVs.
@@ -987,41 +1070,69 @@
      * @returns A pointer to the Sub-TLVs.
      *
      */
-    NetworkDataTlv *GetSubTlvs(void)
+    NetworkDataTlv *GetSubTlvs(void) { return reinterpret_cast<NetworkDataTlv *>(GetValue() + GetFieldsLength()); }
+
+    /**
+     * This method returns a pointer to the Sub-TLVs.
+     *
+     * @returns A pointer to the Sub-TLVs.
+     *
+     */
+    const NetworkDataTlv *GetSubTlvs(void) const
     {
-        return reinterpret_cast<NetworkDataTlv *>(GetServiceDataLengthLocation() + sizeof(uint8_t) +
-                                                  GetServiceDataLength());
+        return reinterpret_cast<const NetworkDataTlv *>(GetValue() + GetFieldsLength());
+    }
+
+    /**
+     * This static method calculates the total size (number of bytes) of a Service TLV with a given Enterprise Number
+     * and Service Data length.
+     *
+     * Note that the returned size does include the Type and Length fields in the TLV, but does not account for any
+     * sub-TLVs of the Service TLV.
+     *
+     * @param[in]  aEnterpriseNumber   A Enterprise Number.
+     * @param[in]  aServiceDataLength  A Service Data length.
+     *
+     * @returns    The size (number of bytes) of the Service TLV.
+     *
+     */
+    static uint16_t CalculateSize(uint32_t aEnterpriseNumber, uint8_t aServiceDataLength)
+    {
+        return sizeof(NetworkDataTlv) + kMinLength + aServiceDataLength +
+               ((aEnterpriseNumber == kThreadEnterpriseNumber) ? 0 : sizeof(uint32_t) /* mEnterpriseNumber  */);
     }
 
 private:
-    /**
-     * This method returns pointer to where mServiceDataLength would be.
-     *
-     * @returns pointer to service data length location
-     */
-    uint8_t *GetServiceDataLengthLocation(void)
-    {
-        return GetEnterpriseNumberLocation() + (IsThreadEnterprise() ? 0 : sizeof(uint32_t));
-    }
+    bool IsThreadEnterprise(void) const { return (mFlagsServiceId & kThreadEnterpriseFlag) != 0; }
 
-    /**
-     * This method returns pointer to where mEnterpriseNumber would be.
-     *
-     * Note: this method returns uint8_t*, not uint32_t*.
-     *
-     * @returns pointer to enterprise number location
-     */
-    uint8_t *GetEnterpriseNumberLocation(void) { return &mTResSId + sizeof(mTResSId); }
+    uint8_t GetFieldsLength(void) const
+    {
+        // Returns the length of TLV value's common fields (flags, enterprise
+        // number and service data) excluding any sub-TLVs.
+
+        return kMinLength + (IsThreadEnterprise() ? 0 : sizeof(uint32_t)) + GetServiceDataLength();
+    }
 
     enum
     {
-        kTOffset   = 7,
-        kTMask     = 0x1 << kTOffset,
-        kSIdOffset = 0,
-        kSIdMask   = 0xf << kSIdOffset,
+        kThreadEnterpriseFlag = (1 << 7),
+        kServiceIdMask        = 0xf,
+        kMinLength            = sizeof(uint8_t) + sizeof(uint8_t), // Flags and Service Data length.
     };
 
-    uint8_t mTResSId;
+    // When `kThreadEnterpriseFlag is set in the `mFlagsServiceId`, the
+    // `mEnterpriseNumber` field is elided and `mFlagsServiceId` is
+    // immediately followed by the Service Data length field (which is
+    // represented by `mServiceDataLengthThreadEnterprise`)
+
+    uint8_t mFlagsServiceId;
+    union OT_TOOL_PACKED_FIELD
+    {
+        uint32_t mEnterpriseNumber;
+        uint8_t  mServiceDataLengthThreadEnterprise;
+    } mShared;
+    uint8_t mServiceDataLength;
+
 } OT_TOOL_PACKED_END;
 
 /**
@@ -1032,15 +1143,26 @@
 class ServerTlv : public NetworkDataTlv
 {
 public:
+    enum
+    {
+        kType = kTypeServer, ///< The TLV Type.
+    };
+
     /**
-     * This method initializes the TLV.
+     * This method initializes the Server TLV.
+     *
+     * @param[in] aServer16          The Server16 value.
+     * @param[in] aServerData        The Server Data.
+     * @param[in] aServerDataLength  Server Data length in bytes.
      *
      */
-    void Init(void)
+    void Init(uint16_t aServer16, const uint8_t *aServerData, uint8_t aServerDataLength)
     {
         NetworkDataTlv::Init();
         SetType(kTypeServer);
-        SetLength(sizeof(*this) - sizeof(NetworkDataTlv));
+        SetServer16(aServer16);
+        memcpy(reinterpret_cast<uint8_t *>(this) + sizeof(*this), aServerData, aServerDataLength);
+        SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + aServerDataLength);
     }
 
     /**
@@ -1053,40 +1175,28 @@
     bool IsValid(void) const { return GetLength() >= (sizeof(*this) - sizeof(NetworkDataTlv)); }
 
     /**
-     * This method returns the S_server_16 value.
+     * This method returns the Server16 value.
      *
-     * @returns The S_server_16 value.
+     * @returns The Server16 value.
+     *
      */
     uint16_t GetServer16(void) const { return HostSwap16(mServer16); }
 
-    /**
-     * This method sets the S_server_16 value.
+    /*
+     * This method sets the Server16 value.
      *
-     * @param[in]  aServer16  The S_server_16 value.
+     * @param[in]  aServer16  The Server16 value.
      *
      */
     void SetServer16(uint16_t aServer16) { mServer16 = HostSwap16(aServer16); }
 
     /**
-     * This method returns a pointer to the Server Data.
+     * This method returns the Server Data.
      *
      * @returns A pointer to the Server Data.
-     */
-    const uint8_t *GetServerData(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); }
-
-    /**
-     * This method sets Server Data to the given values.
      *
-     * Caller must ensure that there is enough memory allocated.
-     *
-     * @param aServerData       pointer to the server data to use
-     * @param aServerDataLength length of the provided server data in bytes
      */
-    void SetServerData(const uint8_t *aServerData, uint8_t aServerDataLength)
-    {
-        SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + aServerDataLength);
-        memcpy(reinterpret_cast<uint8_t *>(this) + sizeof(*this), aServerData, aServerDataLength);
-    }
+    const uint8_t *GetServerData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
 
     /**
      * This method returns the Server Data length in bytes.
@@ -1096,10 +1206,97 @@
      */
     uint8_t GetServerDataLength(void) const { return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv)); }
 
+    /**
+     * This method indicates whether two Server TLVs fully match.
+     *
+     * @param[in]  aOther  Another Server TLV to compare with it.
+     *
+     * @retval TRUE  The two TLVs are equal.
+     * @retval FALSE The two TLVs are not equal.
+     *
+     */
+    bool operator==(const ServerTlv &aOther) const
+    {
+        return (GetLength() == aOther.GetLength()) && (memcmp(GetValue(), aOther.GetValue(), GetLength()) == 0);
+    }
+
+    /**
+     * This static method calculates the total size (number of bytes) of a Service TLV with a given Server Data length.
+     *
+     * Note that the returned size does include the Type and Length fields in the TLV.
+     *
+     * @param[in]  aServerDataLength    Server Data length in bytes.
+     *
+     * @returns    The size (number of bytes) of the Server TLV.
+     *
+     */
+    static uint16_t CalculateSize(uint8_t aServerDataLength) { return sizeof(ServerTlv) + aServerDataLength; }
+
 private:
     uint16_t mServer16;
 } OT_TOOL_PACKED_END;
 
+OT_TOOL_PACKED_BEGIN
+class BackboneRouterServerData
+{
+public:
+    /**
+     * This method returns the sequence number of Backbone Router.
+     *
+     * @returns  The sequence number of the Backbone Router.
+     *
+     */
+    uint8_t GetSequenceNumber(void) const { return mSequenceNumber; }
+
+    /**
+     * This method sets the sequence number of Backbone Router.
+     *
+     * @param[in]  aSequenceNumber  The sequence number of Backbone Router.
+     *
+     */
+    void SetSequenceNumber(uint8_t aSequenceNumber) { mSequenceNumber = aSequenceNumber; }
+
+    /**
+     * This method returns the Registration Delay (in seconds) of Backbone Router.
+     *
+     * @returns The BBR Registration Delay (in seconds) of Backbone Router.
+     *
+     */
+    uint16_t GetReregistrationDelay(void) const { return HostSwap16(mReregistrationDelay); }
+
+    /**
+     * This method sets the Registration Delay (in seconds) of Backbone Router.
+     *
+     * @param[in]  aReregistrationDelay  The Registration Delay (in seconds) of Backbone Router.
+     *
+     */
+    void SetReregistrationDelay(uint16_t aReregistrationDelay)
+    {
+        mReregistrationDelay = HostSwap16(aReregistrationDelay);
+    }
+
+    /**
+     * This method returns the multicast listener report timeout (in seconds) of Backbone Router.
+     *
+     * @returns The multicast listener report timeout (in seconds) of Backbone Router.
+     *
+     */
+    uint32_t GetMlrTimeout(void) const { return HostSwap32(mMlrTimeout); }
+
+    /**
+     * This method sets multicast listener report timeout (in seconds) of Backbone Router.
+     *
+     * @param[in]  aMlrTimeout  The multicast listener report timeout (in seconds) of Backbone Router.
+     *
+     */
+    void SetMlrTimeout(uint32_t aMlrTimeout) { mMlrTimeout = HostSwap32(aMlrTimeout); }
+
+private:
+    uint8_t  mSequenceNumber;
+    uint16_t mReregistrationDelay;
+    uint32_t mMlrTimeout;
+} OT_TOOL_PACKED_END;
+
 /**
  * @}
  *
diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp
index 99afd38..7c7fd49 100644
--- a/src/core/thread/network_diagnostic.cpp
+++ b/src/core/thread/network_diagnostic.cpp
@@ -60,8 +60,8 @@
     , mDiagnosticGetQuery(OT_URI_PATH_DIAGNOSTIC_GET_QUERY, &NetworkDiagnostic::HandleDiagnosticGetQuery, this)
     , mDiagnosticGetAnswer(OT_URI_PATH_DIAGNOSTIC_GET_ANSWER, &NetworkDiagnostic::HandleDiagnosticGetAnswer, this)
     , mDiagnosticReset(OT_URI_PATH_DIAGNOSTIC_RESET, &NetworkDiagnostic::HandleDiagnosticReset, this)
-    , mReceiveDiagnosticGetCallback(NULL)
-    , mReceiveDiagnosticGetCallbackContext(NULL)
+    , mReceiveDiagnosticGetCallback(nullptr)
+    , mReceiveDiagnosticGetCallbackContext(nullptr)
 {
     Get<Coap::Coap>().AddResource(mDiagnosticGetRequest);
     Get<Coap::Coap>().AddResource(mDiagnosticGetQuery);
@@ -81,11 +81,11 @@
                                              uint8_t             aCount)
 {
     otError               error;
-    Coap::Message *       message = NULL;
+    Coap::Message *       message = nullptr;
     Ip6::MessageInfo      messageInfo;
-    otCoapResponseHandler handler = NULL;
+    otCoapResponseHandler handler = nullptr;
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     if (aDestination.IsMulticast())
     {
@@ -106,12 +106,7 @@
 
     if (aCount > 0)
     {
-        TypeListTlv tlv;
-        tlv.Init();
-        tlv.SetLength(aCount);
-
-        SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
-        SuccessOrExit(error = message->Append(aTlvTypes, aCount));
+        SuccessOrExit(error = Tlv::AppendTlv(*message, NetworkDataTlv::kTypeList, aTlvTypes, aCount));
     }
 
     if (aDestination.IsLinkLocal() || aDestination.IsLinkLocalMulticast())
@@ -132,7 +127,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -153,8 +148,8 @@
                                                     const Ip6::MessageInfo *aMessageInfo,
                                                     otError                 aResult)
 {
-    VerifyOrExit(aResult == OT_ERROR_NONE);
-    VerifyOrExit(aMessage && aMessage->GetCode() == OT_COAP_CODE_CHANGED);
+    VerifyOrExit(aResult == OT_ERROR_NONE, OT_NOOP);
+    VerifyOrExit(aMessage && aMessage->GetCode() == OT_COAP_CODE_CHANGED, OT_NOOP);
 
     otLogInfoNetDiag("Received diagnostic get response");
 
@@ -177,7 +172,7 @@
 
 void NetworkDiagnostic::HandleDiagnosticGetAnswer(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
     otLogInfoNetDiag("Diagnostic get answer received");
 
@@ -220,6 +215,7 @@
     return error;
 }
 
+#if OPENTHREAD_FTD
 otError NetworkDiagnostic::AppendChildTable(Message &aMessage)
 {
     otError         error   = OT_ERROR_NONE;
@@ -245,11 +241,9 @@
 
     SuccessOrExit(error = aMessage.Append(&tlv, sizeof(ChildTableTlv)));
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
     {
-        VerifyOrExit(count--);
-
-        Child &child = *iter.GetChild();
+        VerifyOrExit(count--, OT_NOOP);
 
         timeout = 0;
 
@@ -271,6 +265,7 @@
 
     return error;
 }
+#endif // OPENTHREAD_FTD
 
 void NetworkDiagnostic::FillMacCountersTlv(MacCountersTlv &aMacCountersTlv)
 {
@@ -290,7 +285,7 @@
     aMacCountersTlv.SetIfOutDiscards(macCounters.mTxErrBusyChannel);
 }
 
-otError NetworkDiagnostic::FillRequestedTlvs(Message &             aRequest,
+otError NetworkDiagnostic::FillRequestedTlvs(const Message &       aRequest,
                                              Message &             aResponse,
                                              NetworkDiagnosticTlv &aNetworkDiagnosticTlv)
 {
@@ -309,45 +304,27 @@
         switch (type)
         {
         case NetworkDiagnosticTlv::kExtMacAddress:
-        {
-            ExtMacAddressTlv tlv;
-            tlv.Init();
-            tlv.SetMacAddr(Get<Mac::Mac>().GetExtAddress());
-            SuccessOrExit(error = tlv.AppendTo(aResponse));
+            SuccessOrExit(
+                error = Tlv::AppendTlv(aResponse, type, &Get<Mac::Mac>().GetExtAddress(), sizeof(Mac::ExtAddress)));
             break;
-        }
 
         case NetworkDiagnosticTlv::kAddress16:
-        {
-            Address16Tlv tlv;
-            tlv.Init();
-            tlv.SetRloc16(Get<Mle::MleRouter>().GetRloc16());
-            SuccessOrExit(error = tlv.AppendTo(aResponse));
+            SuccessOrExit(error = Tlv::AppendUint16Tlv(aResponse, type, Get<Mle::MleRouter>().GetRloc16()));
             break;
-        }
 
         case NetworkDiagnosticTlv::kMode:
-        {
-            ModeTlv tlv;
-            tlv.Init();
-            tlv.SetMode(Get<Mle::MleRouter>().GetDeviceMode());
-            SuccessOrExit(error = tlv.AppendTo(aResponse));
+            SuccessOrExit(error = Tlv::AppendUint8Tlv(aResponse, type, Get<Mle::MleRouter>().GetDeviceMode().Get()));
             break;
-        }
 
         case NetworkDiagnosticTlv::kTimeout:
-        {
             if (!Get<Mle::MleRouter>().IsRxOnWhenIdle())
             {
-                TimeoutTlv tlv;
-                tlv.Init();
-                tlv.SetTimeout(Get<Mle::MleRouter>().GetTimeout());
-                SuccessOrExit(error = tlv.AppendTo(aResponse));
+                SuccessOrExit(error = Tlv::AppendUint32Tlv(aResponse, type, Get<Mle::MleRouter>().GetTimeout()));
             }
 
             break;
-        }
 
+#if OPENTHREAD_FTD
         case NetworkDiagnosticTlv::kConnectivity:
         {
             ConnectivityTlv tlv;
@@ -357,7 +334,6 @@
             break;
         }
 
-#if OPENTHREAD_FTD
         case NetworkDiagnosticTlv::kRoute:
         {
             RouteTlv tlv;
@@ -370,19 +346,27 @@
 
         case NetworkDiagnosticTlv::kLeaderData:
         {
-            LeaderDataTlv tlv(reinterpret_cast<const LeaderDataTlv &>(Get<Mle::MleRouter>().GetLeaderDataTlv()));
+            LeaderDataTlv          tlv;
+            const Mle::LeaderData &leaderData = Get<Mle::MleRouter>().GetLeaderData();
+
             tlv.Init();
+            tlv.SetPartitionId(leaderData.GetPartitionId());
+            tlv.SetWeighting(leaderData.GetWeighting());
+            tlv.SetDataVersion(leaderData.GetDataVersion());
+            tlv.SetStableDataVersion(leaderData.GetStableDataVersion());
+            tlv.SetLeaderRouterId(leaderData.GetLeaderRouterId());
+
             SuccessOrExit(error = tlv.AppendTo(aResponse));
             break;
         }
 
         case NetworkDiagnosticTlv::kNetworkData:
         {
-            NetworkDataTlv tlv;
-            tlv.Init();
+            uint8_t netData[NetworkData::NetworkData::kMaxSize];
+            uint8_t length = sizeof(netData);
 
-            Get<Mle::MleRouter>().FillNetworkDataTlv((reinterpret_cast<Mle::NetworkDataTlv &>(tlv)), false);
-            SuccessOrExit(error = tlv.AppendTo(aResponse));
+            IgnoreError(Get<NetworkData::Leader>().GetNetworkData(/* aStableOnly */ false, netData, length));
+            SuccessOrExit(error = Tlv::AppendTlv(aResponse, type, netData, length));
             break;
         }
 
@@ -417,18 +401,19 @@
             break;
         }
 
+#if OPENTHREAD_FTD
         case NetworkDiagnosticTlv::kChildTable:
         {
             // Thread 1.1.1 Specification Section 10.11.2.2:
             // If a Thread device is unable to supply a specific Diagnostic TLV, that TLV is omitted.
             // Here only Leader or Router may have children.
-            if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER ||
-                Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_ROUTER)
+            if (Get<Mle::MleRouter>().IsRouterOrLeader())
             {
                 SuccessOrExit(error = AppendChildTable(aResponse));
             }
             break;
         }
+#endif
 
         case NetworkDiagnosticTlv::kChannelPages:
         {
@@ -450,23 +435,23 @@
             break;
         }
 
+#if OPENTHREAD_FTD
         case NetworkDiagnosticTlv::kMaxChildTimeout:
         {
-            uint32_t maxTimeout = 0;
+            uint32_t maxTimeout;
 
             if (Get<Mle::MleRouter>().GetMaxChildTimeout(maxTimeout) == OT_ERROR_NONE)
             {
-                MaxChildTimeoutTlv tlv;
-                tlv.Init();
-                tlv.SetTimeout(maxTimeout);
-                SuccessOrExit(error = tlv.AppendTo(aResponse));
+                SuccessOrExit(error = Tlv::AppendUint32Tlv(aResponse, type, maxTimeout));
             }
 
             break;
         }
+#endif
 
         default:
-            ExitNow(error = OT_ERROR_PARSE);
+            // Skip unrecognized TLV type.
+            break;
         }
 
         offset += sizeof(type);
@@ -485,7 +470,7 @@
 void NetworkDiagnostic::HandleDiagnosticGetQuery(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError              error   = OT_ERROR_NONE;
-    Coap::Message *      message = NULL;
+    Coap::Message *      message = nullptr;
     NetworkDiagnosticTlv networkDiagnosticTlv;
     Ip6::MessageInfo     messageInfo;
 
@@ -500,7 +485,7 @@
     VerifyOrExit(networkDiagnosticTlv.GetType() == NetworkDiagnosticTlv::kTypeList, error = OT_ERROR_PARSE);
 
     // DIAG_GET.qry may be sent as a confirmable message.
-    if (aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE)
+    if (aMessage.IsConfirmable())
     {
         if (Get<Coap::Coap>().SendEmptyAck(aMessage, aMessageInfo) == OT_ERROR_NONE)
         {
@@ -508,7 +493,7 @@
         }
     }
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error =
                       message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_DIAGNOSTIC_GET_ANSWER));
@@ -535,16 +520,16 @@
     if (message->GetLength() == message->GetOffset())
     {
         // Remove Payload Marker if payload is actually empty.
-        message->SetLength(message->GetLength() - 1);
+        IgnoreError(message->SetLength(message->GetLength() - 1));
     }
 
-    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo, NULL, this));
+    SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo, nullptr, this));
 
     otLogInfoNetDiag("Sent diagnostic get answer");
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -561,12 +546,11 @@
 void NetworkDiagnostic::HandleDiagnosticGetRequest(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
     otError              error   = OT_ERROR_NONE;
-    Coap::Message *      message = NULL;
+    Coap::Message *      message = nullptr;
     NetworkDiagnosticTlv networkDiagnosticTlv;
     Ip6::MessageInfo     messageInfo(aMessageInfo);
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST,
-                 error = OT_ERROR_DROP);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, error = OT_ERROR_DROP);
 
     otLogInfoNetDiag("Received diagnostic get request");
 
@@ -576,7 +560,7 @@
 
     VerifyOrExit(networkDiagnosticTlv.GetType() == NetworkDiagnosticTlv::kTypeList, error = OT_ERROR_PARSE);
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->SetDefaultResponseHeader(aMessage));
     SuccessOrExit(error = message->SetPayloadMarker());
@@ -586,7 +570,7 @@
     if (message->GetLength() == message->GetOffset())
     {
         // Remove Payload Marker if payload is actually empty.
-        message->SetLength(message->GetOffset() - 1);
+        IgnoreError(message->SetLength(message->GetOffset() - 1));
     }
 
     SuccessOrExit(error = Get<Coap::Coap>().SendMessage(*message, messageInfo));
@@ -595,7 +579,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -606,10 +590,10 @@
                                                uint8_t             aCount)
 {
     otError          error;
-    Coap::Message *  message = NULL;
+    Coap::Message *  message = nullptr;
     Ip6::MessageInfo messageInfo;
 
-    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_DIAGNOSTIC_RESET));
 
@@ -620,12 +604,7 @@
 
     if (aCount > 0)
     {
-        TypeListTlv tlv;
-        tlv.Init();
-        tlv.SetLength(aCount);
-
-        SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
-        SuccessOrExit(error = message->Append(aTlvTypes, aCount));
+        SuccessOrExit(error = Tlv::AppendTlv(*message, NetworkDataTlv::kTypeList, aTlvTypes, aCount));
     }
 
     if (aDestination.IsLinkLocal() || aDestination.IsLinkLocalMulticast())
@@ -646,7 +625,7 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE && message != nullptr)
     {
         message->Free();
     }
@@ -664,22 +643,21 @@
 {
     uint16_t             offset = 0;
     uint8_t              type;
-    NetworkDiagnosticTlv networkDiagnosticTlv;
+    NetworkDiagnosticTlv tlv;
 
     otLogInfoNetDiag("Received diagnostic reset request");
 
-    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
+    VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
 
-    VerifyOrExit((aMessage.Read(aMessage.GetOffset(), sizeof(NetworkDiagnosticTlv), &networkDiagnosticTlv) ==
-                  sizeof(NetworkDiagnosticTlv)));
+    VerifyOrExit((aMessage.Read(aMessage.GetOffset(), sizeof(tlv), &tlv) == sizeof(tlv)), OT_NOOP);
 
-    VerifyOrExit(networkDiagnosticTlv.GetType() == NetworkDiagnosticTlv::kTypeList);
+    VerifyOrExit(tlv.GetType() == NetworkDiagnosticTlv::kTypeList, OT_NOOP);
 
     offset = aMessage.GetOffset() + sizeof(NetworkDiagnosticTlv);
 
-    for (uint8_t i = 0; i < networkDiagnosticTlv.GetLength(); i++)
+    for (uint8_t i = 0; i < tlv.GetLength(); i++)
     {
-        VerifyOrExit(aMessage.Read(offset, sizeof(type), &type) == sizeof(type));
+        VerifyOrExit(aMessage.Read(offset + i, sizeof(type), &type) == sizeof(type), OT_NOOP);
 
         switch (type)
         {
@@ -702,6 +680,255 @@
     return;
 }
 
+static inline void ParseMode(const Mle::DeviceMode &aMode, otLinkModeConfig &aLinkModeConfig)
+{
+    aLinkModeConfig.mRxOnWhenIdle       = aMode.IsRxOnWhenIdle();
+    aLinkModeConfig.mSecureDataRequests = aMode.IsSecureDataRequest();
+    aLinkModeConfig.mDeviceType         = aMode.IsFullThreadDevice();
+    aLinkModeConfig.mNetworkData        = aMode.IsFullNetworkData();
+}
+
+static inline void ParseConnectivity(const ConnectivityTlv &    aConnectivityTlv,
+                                     otNetworkDiagConnectivity &aNetworkDiagConnectivity)
+{
+    aNetworkDiagConnectivity.mParentPriority   = aConnectivityTlv.GetParentPriority();
+    aNetworkDiagConnectivity.mLinkQuality3     = aConnectivityTlv.GetLinkQuality3();
+    aNetworkDiagConnectivity.mLinkQuality2     = aConnectivityTlv.GetLinkQuality2();
+    aNetworkDiagConnectivity.mLinkQuality1     = aConnectivityTlv.GetLinkQuality1();
+    aNetworkDiagConnectivity.mLeaderCost       = aConnectivityTlv.GetLeaderCost();
+    aNetworkDiagConnectivity.mIdSequence       = aConnectivityTlv.GetIdSequence();
+    aNetworkDiagConnectivity.mActiveRouters    = aConnectivityTlv.GetActiveRouters();
+    aNetworkDiagConnectivity.mSedBufferSize    = aConnectivityTlv.GetSedBufferSize();
+    aNetworkDiagConnectivity.mSedDatagramCount = aConnectivityTlv.GetSedDatagramCount();
+}
+
+static void ParseRoute(const RouteTlv &aRouteTlv, otNetworkDiagRoute &aNetworkDiagRoute)
+{
+    uint8_t routeCount = 0;
+
+    for (uint8_t i = 0; i <= Mle::kMaxRouterId; ++i)
+    {
+        if (!aRouteTlv.IsRouterIdSet(i))
+        {
+            continue;
+        }
+        aNetworkDiagRoute.mRouteData[routeCount].mRouterId       = i;
+        aNetworkDiagRoute.mRouteData[routeCount].mRouteCost      = aRouteTlv.GetRouteCost(routeCount);
+        aNetworkDiagRoute.mRouteData[routeCount].mLinkQualityIn  = aRouteTlv.GetLinkQualityIn(routeCount);
+        aNetworkDiagRoute.mRouteData[routeCount].mLinkQualityOut = aRouteTlv.GetLinkQualityOut(routeCount);
+        ++routeCount;
+    }
+    aNetworkDiagRoute.mRouteCount = routeCount;
+    aNetworkDiagRoute.mIdSequence = aRouteTlv.GetRouterIdSequence();
+}
+
+static inline void ParseLeaderData(const LeaderDataTlv &aLeaderDataTlv, otLeaderData &aLeaderData)
+{
+    aLeaderData.mPartitionId       = aLeaderDataTlv.GetPartitionId();
+    aLeaderData.mWeighting         = aLeaderDataTlv.GetWeighting();
+    aLeaderData.mDataVersion       = aLeaderDataTlv.GetDataVersion();
+    aLeaderData.mStableDataVersion = aLeaderDataTlv.GetStableDataVersion();
+    aLeaderData.mLeaderRouterId    = aLeaderDataTlv.GetLeaderRouterId();
+}
+
+static inline void ParseMacCounters(const MacCountersTlv &aMacCountersTlv, otNetworkDiagMacCounters &aMacCounters)
+{
+    aMacCounters.mIfInUnknownProtos  = aMacCountersTlv.GetIfInUnknownProtos();
+    aMacCounters.mIfInErrors         = aMacCountersTlv.GetIfInErrors();
+    aMacCounters.mIfOutErrors        = aMacCountersTlv.GetIfOutErrors();
+    aMacCounters.mIfInUcastPkts      = aMacCountersTlv.GetIfInUcastPkts();
+    aMacCounters.mIfInBroadcastPkts  = aMacCountersTlv.GetIfInBroadcastPkts();
+    aMacCounters.mIfInDiscards       = aMacCountersTlv.GetIfInDiscards();
+    aMacCounters.mIfOutUcastPkts     = aMacCountersTlv.GetIfOutUcastPkts();
+    aMacCounters.mIfOutBroadcastPkts = aMacCountersTlv.GetIfOutBroadcastPkts();
+    aMacCounters.mIfOutDiscards      = aMacCountersTlv.GetIfOutDiscards();
+}
+
+static inline void ParseChildEntry(const ChildTableEntry &aChildTableTlvEntry, otNetworkDiagChildEntry &aChildEntry)
+{
+    aChildEntry.mTimeout = aChildTableTlvEntry.GetTimeout();
+    aChildEntry.mChildId = aChildTableTlvEntry.GetChildId();
+    ParseMode(aChildTableTlvEntry.GetMode(), aChildEntry.mMode);
+}
+
+otError NetworkDiagnostic::GetNextDiagTlv(const Coap::Message &aMessage,
+                                          Iterator &           aIterator,
+                                          otNetworkDiagTlv &   aNetworkDiagTlv)
+{
+    otError              error  = OT_ERROR_NONE;
+    uint16_t             offset = aMessage.GetOffset() + aIterator;
+    NetworkDiagnosticTlv tlv;
+
+    while (true)
+    {
+        uint16_t tlvTotalLength;
+
+        VerifyOrExit(aMessage.Read(offset, sizeof(tlv), &tlv) == sizeof(tlv), error = OT_ERROR_NOT_FOUND);
+
+        switch (tlv.GetType())
+        {
+        case NetworkDiagnosticTlv::kExtMacAddress:
+            SuccessOrExit(
+                error = Tlv::ReadTlv(aMessage, offset, &aNetworkDiagTlv.mData.mExtAddress, sizeof(Mac::ExtAddress)));
+            break;
+
+        case NetworkDiagnosticTlv::kAddress16:
+            SuccessOrExit(error = Tlv::ReadUint16Tlv(aMessage, offset, aNetworkDiagTlv.mData.mAddr16));
+            break;
+
+        case NetworkDiagnosticTlv::kMode:
+        {
+            uint8_t mode;
+
+            SuccessOrExit(error = Tlv::ReadUint8Tlv(aMessage, offset, mode));
+            ParseMode(Mle::DeviceMode(mode), aNetworkDiagTlv.mData.mMode);
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kTimeout:
+            SuccessOrExit(error = Tlv::ReadUint32Tlv(aMessage, offset, aNetworkDiagTlv.mData.mTimeout));
+            break;
+
+        case NetworkDiagnosticTlv::kConnectivity:
+        {
+            ConnectivityTlv connectivity;
+
+            tlvTotalLength = sizeof(connectivity);
+            VerifyOrExit(aMessage.Read(offset, tlvTotalLength, &connectivity) == tlvTotalLength,
+                         error = OT_ERROR_PARSE);
+            VerifyOrExit(connectivity.IsValid(), error = OT_ERROR_PARSE);
+
+            ParseConnectivity(connectivity, aNetworkDiagTlv.mData.mConnectivity);
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kRoute:
+        {
+            RouteTlv route;
+
+            tlvTotalLength = sizeof(tlv) + tlv.GetLength();
+            VerifyOrExit(tlvTotalLength <= sizeof(route), error = OT_ERROR_PARSE);
+            VerifyOrExit(aMessage.Read(offset, tlvTotalLength, &route) == tlvTotalLength, error = OT_ERROR_PARSE);
+            VerifyOrExit(route.IsValid(), error = OT_ERROR_PARSE);
+
+            ParseRoute(route, aNetworkDiagTlv.mData.mRoute);
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kLeaderData:
+        {
+            LeaderDataTlv leaderData;
+
+            tlvTotalLength = sizeof(leaderData);
+            VerifyOrExit(aMessage.Read(offset, tlvTotalLength, &leaderData) == tlvTotalLength, error = OT_ERROR_PARSE);
+            VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
+
+            ParseLeaderData(leaderData, aNetworkDiagTlv.mData.mLeaderData);
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kNetworkData:
+        {
+            NetworkDataTlv networkData;
+
+            tlvTotalLength = sizeof(tlv) + tlv.GetLength();
+            VerifyOrExit(tlvTotalLength <= sizeof(networkData), error = OT_ERROR_PARSE);
+            VerifyOrExit(aMessage.Read(offset, tlvTotalLength, &networkData) == tlvTotalLength, error = OT_ERROR_PARSE);
+            VerifyOrExit(networkData.IsValid(), error = OT_ERROR_PARSE);
+            VerifyOrExit(sizeof(aNetworkDiagTlv.mData.mNetworkData.m8) >= networkData.GetLength(),
+                         error = OT_ERROR_PARSE);
+
+            memcpy(aNetworkDiagTlv.mData.mNetworkData.m8, networkData.GetNetworkData(), networkData.GetLength());
+            aNetworkDiagTlv.mData.mNetworkData.mCount = networkData.GetLength();
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kIp6AddressList:
+        {
+            Ip6AddressListTlv &ip6AddrList = static_cast<Ip6AddressListTlv &>(tlv);
+
+            VerifyOrExit(ip6AddrList.IsValid(), error = OT_ERROR_PARSE);
+            VerifyOrExit(sizeof(aNetworkDiagTlv.mData.mIp6AddrList.mList) >= ip6AddrList.GetLength(),
+                         error = OT_ERROR_PARSE);
+            VerifyOrExit(aMessage.Read(offset + sizeof(ip6AddrList), ip6AddrList.GetLength(),
+                                       aNetworkDiagTlv.mData.mIp6AddrList.mList) == ip6AddrList.GetLength(),
+                         error = OT_ERROR_PARSE);
+
+            aNetworkDiagTlv.mData.mIp6AddrList.mCount = ip6AddrList.GetLength() / OT_IP6_ADDRESS_SIZE;
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kMacCounters:
+        {
+            MacCountersTlv macCounters;
+
+            tlvTotalLength = sizeof(MacCountersTlv);
+            VerifyOrExit(aMessage.Read(offset, tlvTotalLength, &macCounters) == tlvTotalLength, error = OT_ERROR_PARSE);
+            VerifyOrExit(macCounters.IsValid(), error = OT_ERROR_PARSE);
+
+            ParseMacCounters(macCounters, aNetworkDiagTlv.mData.mMacCounters);
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kBatteryLevel:
+            SuccessOrExit(error = Tlv::ReadUint8Tlv(aMessage, offset, aNetworkDiagTlv.mData.mBatteryLevel));
+            break;
+
+        case NetworkDiagnosticTlv::kSupplyVoltage:
+            SuccessOrExit(error = Tlv::ReadUint16Tlv(aMessage, offset, aNetworkDiagTlv.mData.mSupplyVoltage));
+            break;
+
+        case NetworkDiagnosticTlv::kChildTable:
+        {
+            ChildTableTlv &childTable = static_cast<ChildTableTlv &>(tlv);
+
+            VerifyOrExit(childTable.IsValid(), error = OT_ERROR_PARSE);
+            VerifyOrExit(childTable.GetNumEntries() <= OT_ARRAY_LENGTH(aNetworkDiagTlv.mData.mChildTable.mTable),
+                         error = OT_ERROR_PARSE);
+
+            for (uint8_t i = 0; i < childTable.GetNumEntries(); ++i)
+            {
+                ChildTableEntry childEntry;
+                VerifyOrExit(childTable.ReadEntry(childEntry, aMessage, offset, i) == OT_ERROR_NONE,
+                             error = OT_ERROR_PARSE);
+                ParseChildEntry(childEntry, aNetworkDiagTlv.mData.mChildTable.mTable[i]);
+            }
+            aNetworkDiagTlv.mData.mChildTable.mCount = childTable.GetNumEntries();
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kChannelPages:
+        {
+            VerifyOrExit(sizeof(aNetworkDiagTlv.mData.mChannelPages.m8) >= tlv.GetLength(), error = OT_ERROR_PARSE);
+            VerifyOrExit(aMessage.Read(offset + sizeof(tlv), tlv.GetLength(), aNetworkDiagTlv.mData.mChannelPages.m8) ==
+                             tlv.GetLength(),
+                         error = OT_ERROR_PARSE);
+
+            aNetworkDiagTlv.mData.mChannelPages.mCount = tlv.GetLength();
+            break;
+        }
+
+        case NetworkDiagnosticTlv::kMaxChildTimeout:
+            SuccessOrExit(error = Tlv::ReadUint32Tlv(aMessage, offset, aNetworkDiagTlv.mData.mMaxChildTimeout));
+            break;
+
+        default:
+            // Ignore unrecognized Network Diagnostic TLV silently and
+            // continue to top of the `while(true)` loop.
+            offset += tlv.GetSize();
+            continue;
+        }
+
+        // Exit if a TLV is recognized and parsed successfully.
+        aNetworkDiagTlv.mType = tlv.GetType();
+        aIterator             = static_cast<uint16_t>(offset - aMessage.GetOffset() + tlv.GetSize());
+        ExitNow();
+    }
+
+exit:
+    return error;
+}
+
 } // namespace NetworkDiagnostic
 
 } // namespace ot
diff --git a/src/core/thread/network_diagnostic.hpp b/src/core/thread/network_diagnostic.hpp
index 4d0500c..553ef67 100644
--- a/src/core/thread/network_diagnostic.hpp
+++ b/src/core/thread/network_diagnostic.hpp
@@ -36,6 +36,8 @@
 
 #include "openthread-core-config.h"
 
+#include <openthread/netdiag.h>
+
 #include "coap/coap.hpp"
 #include "common/locator.hpp"
 #include "net/udp6.hpp"
@@ -61,6 +63,17 @@
 class NetworkDiagnostic : public InstanceLocator
 {
 public:
+    enum
+    {
+        kIteratorInit = OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT, ///< Initializer value for Iterator.
+    };
+
+    /**
+     * This type represents an iterator used to iterate through Network Diagnostic TLVs from `GetNextDiagTlv()`.
+     *
+     */
+    typedef otNetworkDiagIterator Iterator;
+
     /**
      * This constructor initializes the object.
      *
@@ -71,7 +84,7 @@
      * This method registers a callback to provide received raw DIAG_GET.rsp or an DIAG_GET.ans payload.
      *
      * @param[in]  aCallback         A pointer to a function that is called when an DIAG_GET.rsp or an DIAG_GET.ans
-     *                               is received or NULL to disable the callback.
+     *                               is received or nullptr to disable the callback.
      * @param[in]  aCallbackContext  A pointer to application-specific context.
      *
      */
@@ -98,11 +111,27 @@
      */
     otError SendDiagnosticReset(const Ip6::Address &aDestination, const uint8_t aTlvTypes[], uint8_t aCount);
 
+    /**
+     * This static method gets the next Network Diagnostic TLV in a given message.
+     *
+     * @param[in]     aMessage         A message.
+     * @param[inout]  aIterator        The Network Diagnostic iterator. To get the first TLV set it to `kIteratorInit`.
+     * @param[out]    aNetworkDiagTlv  A reference to a Network Diagnostic TLV to output the next TLV.
+     *
+     * @retval OT_ERROR_NONE       Successfully found the next Network Diagnostic TLV.
+     * @retval OT_ERROR_NOT_FOUND  No subsequent Network Diagnostic TLV exists in the message.
+     * @retval OT_ERROR_PARSE      Parsing the next Network Diagnostic failed.
+     *
+     */
+    static otError GetNextDiagTlv(const Coap::Message &aMessage,
+                                  Iterator &           aIterator,
+                                  otNetworkDiagTlv &   aNetworkDiagTlv);
+
 private:
     otError AppendIp6AddressList(Message &aMessage);
     otError AppendChildTable(Message &aMessage);
     void    FillMacCountersTlv(MacCountersTlv &aMacCountersTlv);
-    otError FillRequestedTlvs(Message &aRequest, Message &aResponse, NetworkDiagnosticTlv &aNetworkDiagnosticTlv);
+    otError FillRequestedTlvs(const Message &aRequest, Message &aResponse, NetworkDiagnosticTlv &aNetworkDiagnosticTlv);
 
     static void HandleDiagnosticGetRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
     void        HandleDiagnosticGetRequest(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
diff --git a/src/core/thread/network_diagnostic_tlvs.hpp b/src/core/thread/network_diagnostic_tlvs.hpp
index 1dc0bcc..ed46eeb 100644
--- a/src/core/thread/network_diagnostic_tlvs.hpp
+++ b/src/core/thread/network_diagnostic_tlvs.hpp
@@ -43,8 +43,7 @@
 #include "common/tlvs.hpp"
 #include "net/ip6_address.hpp"
 #include "radio/radio.hpp"
-#include "thread/device_mode.hpp"
-#include "thread/mle_constants.hpp"
+#include "thread/mle_types.hpp"
 
 namespace ot {
 
@@ -83,23 +82,22 @@
      */
     enum Type
     {
-        kExtMacAddress   = 0,  ///< Source Address TLV
-        kAddress16       = 1,  ///< Address16 TLV
-        kMode            = 2,  ///< Mode TLV
-        kTimeout         = 3,  ///< Timeout TLV
-        kConnectivity    = 4,  ///< Connectivity TLV
-        kRoute           = 5,  ///< Routing-Table TLV
-        kLeaderData      = 6,  ///< Leader Data TLV
-        kNetworkData     = 7,  ///< Network Data TLV
-        kIp6AddressList  = 8,  ///< Ip6 Address List TLV
-        kMacCounters     = 9,  ///< Mac Counters TLV
-        kBatteryLevel    = 14, ///< Battery Level TLV
-        kSupplyVoltage   = 15, ///< Supply Voltage TLV
-        kChildTable      = 16, ///< Child Table TLV
-        kChannelPages    = 17, ///< Channel Pages TLV
-        kTypeList        = 18, ///< Type List TLV
-        kMaxChildTimeout = 19, ///< Max Child Timeout TLV
-        kInvalid         = 255,
+        kExtMacAddress   = OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS,
+        kAddress16       = OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS,
+        kMode            = OT_NETWORK_DIAGNOSTIC_TLV_MODE,
+        kTimeout         = OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT,
+        kConnectivity    = OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY,
+        kRoute           = OT_NETWORK_DIAGNOSTIC_TLV_ROUTE,
+        kLeaderData      = OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA,
+        kNetworkData     = OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA,
+        kIp6AddressList  = OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST,
+        kMacCounters     = OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS,
+        kBatteryLevel    = OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL,
+        kSupplyVoltage   = OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE,
+        kChildTable      = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE,
+        kChannelPages    = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES,
+        kTypeList        = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST,
+        kMaxChildTimeout = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT,
     };
 
     /**
@@ -118,226 +116,6 @@
      */
     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
 
-    /**
-     * This static method reads the requested TLV out of @p aMessage.
-     *
-     * @param[in]   aMessage    A reference to the message.
-     * @param[in]   aType       The Type value to search for.
-     * @param[in]   aMaxLength  Maximum number of bytes to read.
-     * @param[out]  aTlv        A reference to the TLV that will be copied to.
-     *
-     * @retval OT_ERROR_NONE       Successfully copied the TLV.
-     * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
-     *
-     */
-    static otError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv)
-    {
-        return ot::Tlv::Get(aMessage, static_cast<uint8_t>(aType), aMaxLength, aTlv);
-    }
-
-    /**
-     * This static method obtains the offset of a TLV within @p aMessage.
-     *
-     * @param[in]   aMessage    A reference to the message.
-     * @param[in]   aType       The Type value to search for.
-     * @param[out]  aOffset     A reference to the offset of the TLV.
-     *
-     * @retval OT_ERROR_NONE       Successfully copied the TLV.
-     * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
-     *
-     */
-    static otError GetOffset(const Message &aMessage, Type aType, uint16_t &aOffset)
-    {
-        return ot::Tlv::GetOffset(aMessage, static_cast<uint8_t>(aType), aOffset);
-    }
-
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Extended Address TLV generation and parsing.
- *
- */
-class ExtMacAddressTlv : public NetworkDiagnosticTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kExtMacAddress);
-        SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); }
-
-    /**
-     * This method returns a pointer to the Extended MAC Address.
-     *
-     * @returns A pointer to the Extended MAC Address.
-     *
-     */
-    const Mac::ExtAddress *GetMacAddr(void) const { return &mMacAddr; }
-
-    /**
-     * This method sets the Extended MAC Address.
-     *
-     * @param[in]  aAddress  A reference to the Extended MAC Address.
-     *
-     */
-    void SetMacAddr(const Mac::ExtAddress &aAddress) { mMacAddr = aAddress; }
-
-private:
-    Mac::ExtAddress mMacAddr;
-};
-
-/**
- * This class implements Source Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class Address16Tlv : public NetworkDiagnosticTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kAddress16);
-        SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); }
-
-    /**
-     * This method returns the RLOC16 value.
-     *
-     * @returns The RLOC16 value.
-     *
-     */
-    uint16_t GetRloc16(void) const { return HostSwap16(mRloc16); }
-
-    /**
-     * This method sets the RLOC16 value.
-     *
-     * @param[in]  aRloc16  The RLOC16 value.
-     *
-     */
-    void SetRloc16(uint16_t aRloc16) { mRloc16 = HostSwap16(aRloc16); }
-
-private:
-    uint16_t mRloc16;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Mode TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ModeTlv : public NetworkDiagnosticTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kMode);
-        SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); }
-
-    /**
-     * This method returns the Device Mode.
-     *
-     * @returns The Device Mode.
-     *
-     */
-    Mle::DeviceMode GetMode(void) const { return Mle::DeviceMode(mMode); }
-
-    /**
-     * This method sets the Device Mode
-     *
-     * @param[in]  aMode  The Device Mode
-     *
-     */
-    void SetMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); }
-
-private:
-    uint8_t mMode;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Timeout TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class TimeoutTlv : public NetworkDiagnosticTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kTimeout);
-        SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); }
-
-    /**
-     * This method returns the Timeout value.
-     *
-     * @returns The Timeout value.
-     *
-     */
-    uint32_t GetTimeout(void) const { return HostSwap32(mTimeout); }
-
-    /**
-     * This method sets the Timeout value.
-     *
-     * @param[in]  aTimeout  The Timeout value.
-     *
-     */
-    void SetTimeout(uint32_t aTimeout) { mTimeout = HostSwap32(aTimeout); }
-
-private:
-    uint32_t mTimeout;
 } OT_TOOL_PACKED_END;
 
 /**
@@ -367,12 +145,20 @@
      */
     bool IsValid(void) const
     {
-        return ((GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv)) ||
-                (GetLength() ==
-                 sizeof(*this) - sizeof(NetworkDiagnosticTlv) - sizeof(mSedBufferSize) - sizeof(mSedDatagramCount)));
+        return IsSedBufferingIncluded() || (GetLength() == sizeof(*this) - sizeof(NetworkDiagnosticTlv) -
+                                                               sizeof(mSedBufferSize) - sizeof(mSedDatagramCount));
     }
 
     /**
+     * This method indicates whether or not the sed buffer size and datagram count are included.
+     *
+     * @retval TRUE   If the sed buffer size and datagram count are included.
+     * @retval FALSE  If the sed buffer size and datagram count are not included.
+     *
+     */
+    bool IsSedBufferingIncluded(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
+
+    /**
      * This method returns the Parent Priority value.
      *
      * @returns The Parent Priority value.
@@ -493,7 +279,16 @@
      * @returns The SED Buffer Size value.
      *
      */
-    uint16_t GetSedBufferSize(void) const { return HostSwap16(mSedBufferSize); }
+    uint16_t GetSedBufferSize(void) const
+    {
+        uint16_t buffersize = OPENTHREAD_CONFIG_DEFAULT_SED_BUFFER_SIZE;
+
+        if (IsSedBufferingIncluded())
+        {
+            buffersize = HostSwap16(mSedBufferSize);
+        }
+        return buffersize;
+    }
 
     /**
      * This method sets the SED Buffer Size value.
@@ -509,7 +304,16 @@
      * @returns The SED Datagram Count value.
      *
      */
-    uint8_t GetSedDatagramCount(void) const { return mSedDatagramCount; }
+    uint8_t GetSedDatagramCount(void) const
+    {
+        uint8_t count = OPENTHREAD_CONFIG_DEFAULT_SED_DATAGRAM_COUNT;
+
+        if (IsSedBufferingIncluded())
+        {
+            count = mSedDatagramCount;
+        }
+        return count;
+    }
 
     /**
      * This method sets the SED Datagram Count value.
@@ -553,6 +357,7 @@
     {
         SetType(kRoute);
         SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv));
+        mRouterIdMask.Clear();
     }
 
     /**
@@ -581,12 +386,6 @@
     void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; }
 
     /**
-     * This method clears the Router ID Mask.
-     *
-     */
-    void ClearRouterIdMask(void) { memset(mRouterIdMask, 0, sizeof(mRouterIdMask)); }
-
-    /**
      * This method indicates whether or not a Router ID bit is set.
      *
      * @param[in]  aRouterId  The Router ID.
@@ -595,10 +394,7 @@
      * @retval FALSE  If the Router ID bit is not set.
      *
      */
-    bool IsRouterIdSet(uint8_t aRouterId) const
-    {
-        return (mRouterIdMask[aRouterId / 8] & (0x80 >> (aRouterId % 8))) != 0;
-    }
+    bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); }
 
     /**
      * This method sets the Router ID bit.
@@ -606,7 +402,7 @@
      * @param[in]  aRouterId  The Router ID bit to set.
      *
      */
-    void SetRouterId(uint8_t aRouterId) { mRouterIdMask[aRouterId / 8] |= 0x80 >> (aRouterId % 8); }
+    void SetRouterId(uint8_t aRouterId) { mRouterIdMask.Add(aRouterId); }
 
     /**
      * This method returns the Route Data Length value.
@@ -625,71 +421,77 @@
     void SetRouteDataLength(uint8_t aLength) { SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength); }
 
     /**
-     * This method returns the Route Cost value for a given Router ID.
+     * This method returns the Route Cost value for a given Router index.
      *
-     * @returns The Route Cost value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Route Cost value for a given Router index.
      *
      */
-    uint8_t GetRouteCost(uint8_t aRouterId) const { return mRouteData[aRouterId] & kRouteCostMask; }
+    uint8_t GetRouteCost(uint8_t aRouterIndex) const { return mRouteData[aRouterIndex] & kRouteCostMask; }
 
     /**
-     * This method sets the Route Cost value for a given Router ID.
+     * This method sets the Route Cost value for a given Router index.
      *
-     * @param[in]  aRouterId   The Router ID.
-     * @param[in]  aRouteCost  The Route Cost value.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aRouteCost    The Route Cost value.
      *
      */
-    void SetRouteCost(uint8_t aRouterId, uint8_t aRouteCost)
+    void SetRouteCost(uint8_t aRouterIndex, uint8_t aRouteCost)
     {
-        mRouteData[aRouterId] = (mRouteData[aRouterId] & ~kRouteCostMask) | aRouteCost;
+        mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kRouteCostMask) | aRouteCost;
     }
 
     /**
-     * This method returns the Link Quality In value for a given Router ID.
+     * This method returns the Link Quality In value for a given Router index.
      *
-     * @returns The Link Quality In value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Link Quality In value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityIn(uint8_t aRouterId) const
+    uint8_t GetLinkQualityIn(uint8_t aRouterIndex) const
     {
-        return (mRouteData[aRouterId] & kLinkQualityInMask) >> kLinkQualityInOffset;
+        return (mRouteData[aRouterIndex] & kLinkQualityInMask) >> kLinkQualityInOffset;
     }
 
     /**
-     * This method sets the Link Quality In value for a given Router ID.
+     * This method sets the Link Quality In value for a given Router index.
      *
-     * @param[in]  aRouterId     The Router ID.
-     * @param[in]  aLinkQuality  The Link Quality In value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aLinkQuality  The Link Quality In value for a given Router index.
      *
      */
-    void SetLinkQualityIn(uint8_t aRouterId, uint8_t aLinkQuality)
+    void SetLinkQualityIn(uint8_t aRouterIndex, uint8_t aLinkQuality)
     {
-        mRouteData[aRouterId] = (mRouteData[aRouterId] & ~kLinkQualityInMask) |
-                                ((aLinkQuality << kLinkQualityInOffset) & kLinkQualityInMask);
+        mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityInMask) |
+                                   ((aLinkQuality << kLinkQualityInOffset) & kLinkQualityInMask);
     }
 
     /**
-     * This method returns the Link Quality Out value for a given Router ID.
+     * This method returns the Link Quality Out value for a given Router index.
      *
-     * @returns The Link Quality Out value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     *
+     * @returns The Link Quality Out value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityOut(uint8_t aRouterId) const
+    uint8_t GetLinkQualityOut(uint8_t aRouterIndex) const
     {
-        return (mRouteData[aRouterId] & kLinkQualityOutMask) >> kLinkQualityOutOffset;
+        return (mRouteData[aRouterIndex] & kLinkQualityOutMask) >> kLinkQualityOutOffset;
     }
 
     /**
-     * This method sets the Link Quality Out value for a given Router ID.
+     * This method sets the Link Quality Out value for a given Router index.
      *
-     * @param[in]  aRouterId     The Router ID.
-     * @param[in]  aLinkQuality  The Link Quality Out value for a given Router ID.
+     * @param[in]  aRouterIndex  The Router index.
+     * @param[in]  aLinkQuality  The Link Quality Out value for a given Router index.
      *
      */
-    void SetLinkQualityOut(uint8_t aRouterId, uint8_t aLinkQuality)
+    void SetLinkQualityOut(uint8_t aRouterIndex, uint8_t aLinkQuality)
     {
-        mRouteData[aRouterId] = (mRouteData[aRouterId] & ~kLinkQualityOutMask) |
-                                ((aLinkQuality << kLinkQualityOutOffset) & kLinkQualityOutMask);
+        mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityOutMask) |
+                                   ((aLinkQuality << kLinkQualityOutOffset) & kLinkQualityOutMask);
     }
 
 private:
@@ -702,9 +504,9 @@
         kRouteCostOffset      = 0,
         kRouteCostMask        = 0xf << kRouteCostOffset,
     };
-    uint8_t mRouterIdSequence;
-    uint8_t mRouterIdMask[BitVectorBytes(Mle::kMaxRouterId + 1)];
-    uint8_t mRouteData[Mle::kMaxRouterId + 1];
+    uint8_t          mRouterIdSequence;
+    Mle::RouterIdSet mRouterIdMask;
+    uint8_t          mRouteData[Mle::kMaxRouterId + 1];
 } OT_TOOL_PACKED_END;
 
 /**
@@ -888,6 +690,15 @@
     }
 
     /**
+     * This method indicates whether or not the TLV appears to be well-formed.
+     *
+     * @retval TRUE   If the TLV appears to be well-formed.
+     * @retval FALSE  If the TLV does not appear to be well-formed.
+     *
+     */
+    bool IsValid(void) const { return !IsExtended() && (GetLength() % sizeof(Ip6::Address) == 0); }
+
+    /**
      * This method returns a pointer to the IPv6 address entry.
      *
      * @param[in]  aIndex  The index into the IPv6 address list.
@@ -1094,100 +905,6 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements Battery Level TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class BatteryLevelTlv : public NetworkDiagnosticTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kBatteryLevel);
-        SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); }
-
-    /**
-     * This method returns the Status value.
-     *
-     * @returns The Status value.
-     *
-     */
-    uint8_t GetBatteryLevel(void) const { return mBatteryLevel; }
-
-    /**
-     * This method sets the Status value.
-     *
-     * @param[in]  aStatus  The Status value.
-     *
-     */
-    void SetBatteryLevel(uint8_t aBatteryLevel) { mBatteryLevel = aBatteryLevel; }
-
-private:
-    uint8_t mBatteryLevel;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Supply Voltage TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class SupplyVoltageTlv : public NetworkDiagnosticTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kSupplyVoltage);
-        SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); }
-
-    /**
-     * This method returns the Status value.
-     *
-     * @returns The Status value.
-     *
-     */
-    uint16_t GetSupplyVoltage(void) const { return mSupplyVoltage; }
-
-    /**
-     * This method sets the SupplyVoltage value.
-     *
-     * @param[in]  aSupplyVoltage  The SupplyVoltage value.
-     *
-     */
-    void SetSupplyVoltage(uint16_t aSupplyVoltage) { mSupplyVoltage = aSupplyVoltage; }
-
-private:
-    uint16_t mSupplyVoltage;
-} OT_TOOL_PACKED_END;
-
-/**
  * This class implements Child Table Entry generation and parsing.
  *
  */
@@ -1356,7 +1073,7 @@
      * @retval  OT_ERROR_NOT_FOUND  No such entry is found.
      * @retval  OT_ERROR_NONE       Successfully read the entry.
      */
-    otError ReadEntry(ChildTableEntry &aEntry, Message &aMessage, uint16_t aOffset, uint8_t aIndex) const
+    otError ReadEntry(ChildTableEntry &aEntry, const Message &aMessage, uint16_t aOffset, uint8_t aIndex) const
     {
         return (aIndex < GetNumEntries() &&
                 aMessage.Read(aOffset + sizeof(ChildTableTlv) + (aIndex * sizeof(ChildTableEntry)),
@@ -1386,6 +1103,19 @@
     }
 
     /**
+     * This method indicates whether or not the TLV appears to be well-formed.
+     *
+     * @retval TRUE   If the TLV appears to be well-formed.
+     * @retval FALSE  If the TLV does not appear to be well-formed.
+     *
+     */
+    bool IsValid(void) const
+    {
+        // At least one channel page must be included.
+        return GetLength() >= 1;
+    }
+
+    /**
      * This method returns a pointer to the list of Channel Pages.
      *
      * @returns A pointer to the list of Channel Pages.
@@ -1417,53 +1147,6 @@
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements Max Child Timeout TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class MaxChildTimeoutTlv : public NetworkDiagnosticTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kMaxChildTimeout);
-        SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); }
-
-    /**
-     * This method returns the Timeout value.
-     *
-     * @returns The Timeout value.
-     *
-     */
-    uint32_t GetTimeout(void) const { return HostSwap32(mTimeout); }
-
-    /**
-     * This method sets the Timeout value.
-     *
-     * @param[in]  aTimeout  The Timeout value.
-     *
-     */
-    void SetTimeout(uint32_t aTimeout) { mTimeout = HostSwap32(aTimeout); }
-
-private:
-    uint32_t mTimeout;
-} OT_TOOL_PACKED_END;
-
-/**
  * @}
  *
  */
diff --git a/src/core/thread/panid_query_server.cpp b/src/core/thread/panid_query_server.cpp
index 15165ec..a45e5eb 100644
--- a/src/core/thread/panid_query_server.cpp
+++ b/src/core/thread/panid_query_server.cpp
@@ -50,7 +50,7 @@
     : InstanceLocator(aInstance)
     , mChannelMask(0)
     , mPanId(Mac::kPanIdBroadcast)
-    , mTimer(aInstance, &PanIdQueryServer::HandleTimer, this)
+    , mTimer(aInstance, PanIdQueryServer::HandleTimer, this)
     , mPanIdQuery(OT_URI_PATH_PANID_QUERY, &PanIdQueryServer::HandleQuery, this)
 {
     Get<Coap::Coap>().AddResource(mPanIdQuery);
@@ -64,19 +64,18 @@
 
 void PanIdQueryServer::HandleQuery(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
 {
-    MeshCoP::PanIdTlv panId;
-    Ip6::MessageInfo  responseInfo(aMessageInfo);
-    uint32_t          mask;
+    uint16_t         panId;
+    Ip6::MessageInfo responseInfo(aMessageInfo);
+    uint32_t         mask;
 
-    VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST);
-    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
+    VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST, OT_NOOP);
+    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0, OT_NOOP);
 
-    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPanId, sizeof(panId), panId));
-    VerifyOrExit(panId.IsValid());
+    SuccessOrExit(Tlv::FindUint16Tlv(aMessage, MeshCoP::Tlv::kPanId, panId));
 
     mChannelMask  = mask;
     mCommissioner = aMessageInfo.GetPeerAddr();
-    mPanId        = panId.GetPanId();
+    mPanId        = panId;
     mTimer.Start(kScanDelay);
 
     if (aMessage.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast())
@@ -96,7 +95,7 @@
 
 void PanIdQueryServer::HandleScanResult(Mac::ActiveScanResult *aScanResult)
 {
-    if (aScanResult != NULL)
+    if (aScanResult != nullptr)
     {
         if (aScanResult->mPanId == mPanId)
         {
@@ -109,15 +108,14 @@
     }
 }
 
-otError PanIdQueryServer::SendConflict(void)
+void PanIdQueryServer::SendConflict(void)
 {
     otError                 error = OT_ERROR_NONE;
     MeshCoP::ChannelMaskTlv channelMask;
-    MeshCoP::PanIdTlv       panId;
     Ip6::MessageInfo        messageInfo;
     Coap::Message *         message;
 
-    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(Get<Coap::Coap>())) != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST, OT_URI_PATH_PANID_CONFLICT));
     SuccessOrExit(error = message->SetPayloadMarker());
@@ -126,9 +124,7 @@
     channelMask.SetChannelMask(mChannelMask);
     SuccessOrExit(error = channelMask.AppendTo(*message));
 
-    panId.Init();
-    panId.SetPanId(mPanId);
-    SuccessOrExit(error = panId.AppendTo(*message));
+    SuccessOrExit(error = Tlv::AppendUint16Tlv(*message, MeshCoP::Tlv::kPanId, mPanId));
 
     messageInfo.SetSockAddr(Get<Mle::MleRouter>().GetMeshLocal16());
     messageInfo.SetPeerAddr(mCommissioner);
@@ -139,12 +135,15 @@
 
 exit:
 
-    if (error != OT_ERROR_NONE && message != NULL)
+    if (error != OT_ERROR_NONE)
     {
-        message->Free();
-    }
+        otLogWarnMeshCoP("Failed to send panid conflict: %s", otThreadErrorToString(error));
 
-    return error;
+        if (message != nullptr)
+        {
+            message->Free();
+        }
+    }
 }
 
 void PanIdQueryServer::HandleTimer(Timer &aTimer)
@@ -154,7 +153,7 @@
 
 void PanIdQueryServer::HandleTimer(void)
 {
-    Get<Mac::Mac>().ActiveScan(mChannelMask, 0, HandleScanResult, this);
+    IgnoreError(Get<Mac::Mac>().ActiveScan(mChannelMask, 0, HandleScanResult, this));
     mChannelMask = 0;
 }
 
diff --git a/src/core/thread/panid_query_server.hpp b/src/core/thread/panid_query_server.hpp
index 01b93a1..7805038 100644
--- a/src/core/thread/panid_query_server.hpp
+++ b/src/core/thread/panid_query_server.hpp
@@ -75,7 +75,7 @@
 
     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
 
-    otError SendConflict(void);
+    void SendConflict(void);
 
     Ip6::Address mCommissioner;
     uint32_t     mChannelMask;
diff --git a/src/core/thread/router_table.cpp b/src/core/thread/router_table.cpp
index c4955d3..3eecdcf 100644
--- a/src/core/thread/router_table.cpp
+++ b/src/core/thread/router_table.cpp
@@ -44,7 +44,7 @@
 
 RouterTable::Iterator::Iterator(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mRouter(NULL)
+    , mRouter(nullptr)
 {
     Reset();
 }
@@ -65,13 +65,18 @@
     , mRouterIdSequence(Random::NonCrypto::GetUint8())
     , mActiveRouterCount(0)
 {
+    for (uint8_t index = 0; index < Mle::kMaxRouters; index++)
+    {
+        mRouters[index].Init(aInstance);
+    }
+
     Clear();
 }
 
 const Router *RouterTable::GetFirstEntry(void) const
 {
     const Router *router = &mRouters[0];
-    VerifyOrExit(router->GetRloc16() != 0xffff, router = NULL);
+    VerifyOrExit(router->GetRloc16() != 0xffff, router = nullptr);
 
 exit:
     return router;
@@ -79,10 +84,10 @@
 
 const Router *RouterTable::GetNextEntry(const Router *aRouter) const
 {
-    VerifyOrExit(aRouter != NULL);
+    VerifyOrExit(aRouter != nullptr, OT_NOOP);
     aRouter++;
-    VerifyOrExit(aRouter < &mRouters[Mle::kMaxRouters], aRouter = NULL);
-    VerifyOrExit(aRouter->GetRloc16() != 0xffff, aRouter = NULL);
+    VerifyOrExit(aRouter < &mRouters[Mle::kMaxRouters], aRouter = nullptr);
+    VerifyOrExit(aRouter->GetRloc16() != 0xffff, aRouter = nullptr);
 
 exit:
     return aRouter;
@@ -201,7 +206,7 @@
 
 Router *RouterTable::Allocate(void)
 {
-    Router *rval         = NULL;
+    Router *rval         = nullptr;
     uint8_t numAvailable = 0;
     uint8_t freeBit;
 
@@ -214,7 +219,7 @@
         }
     }
 
-    VerifyOrExit(mActiveRouterCount < Mle::kMaxRouters && numAvailable > 0);
+    VerifyOrExit(mActiveRouterCount < Mle::kMaxRouters && numAvailable > 0, OT_NOOP);
 
     // choose available router id at random
     freeBit = Random::NonCrypto::GetUint8InRange(0, numAvailable);
@@ -230,7 +235,7 @@
         if (freeBit == 0)
         {
             rval = Allocate(routerId);
-            assert(rval != NULL);
+            OT_ASSERT(rval != nullptr);
             ExitNow();
         }
 
@@ -243,10 +248,11 @@
 
 Router *RouterTable::Allocate(uint8_t aRouterId)
 {
-    Router *rval = NULL;
+    Router *rval = nullptr;
 
     VerifyOrExit(aRouterId <= Mle::kMaxRouterId && mActiveRouterCount < Mle::kMaxRouters && !IsAllocated(aRouterId) &&
-                 mRouterIdReuseDelay[aRouterId] == 0);
+                     mRouterIdReuseDelay[aRouterId] == 0,
+                 OT_NOOP);
 
     mAllocatedRouterIds.Add(aRouterId);
     UpdateAllocation();
@@ -269,9 +275,9 @@
     otError  error  = OT_ERROR_NONE;
     uint16_t rloc16 = Mle::Mle::Rloc16FromRouterId(aRouterId);
 
-    assert(aRouterId <= Mle::kMaxRouterId);
+    OT_ASSERT(aRouterId <= Mle::kMaxRouterId);
 
-    VerifyOrExit(Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(Get<Mle::MleRouter>().IsLeader(), error = OT_ERROR_INVALID_STATE);
     VerifyOrExit(IsAllocated(aRouterId), error = OT_ERROR_NOT_FOUND);
 
     mAllocatedRouterIds.Remove(aRouterId);
@@ -279,7 +285,7 @@
 
     mRouterIdReuseDelay[aRouterId] = Mle::kRouterIdReuseDelay;
 
-    for (Router *router = GetFirstEntry(); router != NULL; router = GetNextEntry(router))
+    for (Router *router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
     {
         if (router->GetNextHop() == rloc16)
         {
@@ -301,12 +307,12 @@
     return error;
 }
 
-void RouterTable::RemoveNeighbor(Router &aRouter)
+void RouterTable::RemoveRouterLink(Router &aRouter)
 {
     aRouter.SetLinkQualityOut(0);
     aRouter.SetLastHeard(TimerMilli::GetNow());
 
-    for (Router *cur = GetFirstEntry(); cur != NULL; cur = GetNextEntry(cur))
+    for (Router *cur = GetFirstEntry(); cur != nullptr; cur = GetNextEntry(cur))
     {
         if (cur->GetNextHop() == aRouter.GetRouterId())
         {
@@ -333,7 +339,7 @@
 {
     uint8_t activeLinks = 0;
 
-    for (const Router *router = GetFirstEntry(); router != NULL; router = GetNextEntry(router))
+    for (const Router *router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
     {
         if (router->IsStateValid())
         {
@@ -346,11 +352,11 @@
 
 Router *RouterTable::GetNeighbor(uint16_t aRloc16)
 {
-    Router *router = NULL;
+    Router *router = nullptr;
 
-    VerifyOrExit(aRloc16 != Get<Mle::MleRouter>().GetRloc16());
+    VerifyOrExit(aRloc16 != Get<Mle::MleRouter>().GetRloc16(), OT_NOOP);
 
-    for (router = GetFirstEntry(); router != NULL; router = GetNextEntry(router))
+    for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
     {
         if (router->IsStateValid() && router->GetRloc16() == aRloc16)
         {
@@ -364,11 +370,11 @@
 
 Router *RouterTable::GetNeighbor(const Mac::ExtAddress &aExtAddress)
 {
-    Router *router = NULL;
+    Router *router = nullptr;
 
-    VerifyOrExit(aExtAddress != Get<Mac::Mac>().GetExtAddress());
+    VerifyOrExit(aExtAddress != Get<Mac::Mac>().GetExtAddress(), OT_NOOP);
 
-    for (router = GetFirstEntry(); router != NULL; router = GetNextEntry(router))
+    for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
     {
         if (router->IsStateValid() && router->GetExtAddress() == aExtAddress)
         {
@@ -382,10 +388,15 @@
 
 const Router *RouterTable::GetRouter(uint8_t aRouterId) const
 {
-    const Router *router = NULL;
-    uint16_t      rloc16 = Mle::Mle::Rloc16FromRouterId(aRouterId);
+    const Router *router = nullptr;
+    uint16_t      rloc16;
 
-    for (router = GetFirstEntry(); router != NULL; router = GetNextEntry(router))
+    // Skip if invalid router id is passed.
+    VerifyOrExit(aRouterId < Mle::kInvalidRouterId, OT_NOOP);
+
+    rloc16 = Mle::Mle::Rloc16FromRouterId(aRouterId);
+
+    for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
     {
         if (router->GetRloc16() == rloc16)
         {
@@ -393,14 +404,15 @@
         }
     }
 
+exit:
     return router;
 }
 
 Router *RouterTable::GetRouter(const Mac::ExtAddress &aExtAddress)
 {
-    Router *router = NULL;
+    Router *router = nullptr;
 
-    for (router = GetFirstEntry(); router != NULL; router = GetNextEntry(router))
+    for (router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
     {
         if (router->GetExtAddress() == aExtAddress)
         {
@@ -429,7 +441,7 @@
     }
 
     router = GetRouter(routerId);
-    VerifyOrExit(router != NULL, error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(router != nullptr, error = OT_ERROR_NOT_FOUND);
 
     memset(&aRouterInfo, 0, sizeof(aRouterInfo));
     aRouterInfo.mRouterId        = routerId;
@@ -461,7 +473,7 @@
 {
     uint8_t count = 0;
 
-    for (const Router *router = GetFirstEntry(); router != NULL; router = GetNextEntry(router))
+    for (const Router *router = GetFirstEntry(); router != nullptr; router = GetNextEntry(router))
     {
         if (router->IsStateValid())
         {
@@ -476,7 +488,7 @@
 {
     uint8_t rval = Mle::kMaxRouteCost;
 
-    VerifyOrExit(aRouter.GetRloc16() != Get<Mle::MleRouter>().GetRloc16() && aRouter.IsStateValid());
+    VerifyOrExit(aRouter.GetRloc16() != Get<Mle::MleRouter>().GetRloc16() && aRouter.IsStateValid(), OT_NOOP);
 
     rval = aRouter.GetLinkInfo().GetLinkQuality();
 
@@ -491,83 +503,41 @@
     return rval;
 }
 
-void RouterTable::ProcessTlv(const Mle::RouteTlv &aTlv)
+void RouterTable::UpdateRouterIdSet(uint8_t aRouterIdSequence, const Mle::RouterIdSet &aRouterIdSet)
 {
-    bool allocationChanged = false;
-
-    mRouterIdSequence            = aTlv.GetRouterIdSequence();
+    mRouterIdSequence            = aRouterIdSequence;
     mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
 
+    VerifyOrExit(mAllocatedRouterIds != aRouterIdSet, OT_NOOP);
+
     for (uint8_t routerId = 0; routerId <= Mle::kMaxRouterId; routerId++)
     {
-        if (aTlv.IsRouterIdSet(routerId) == IsAllocated(routerId))
-        {
-            continue;
-        }
-
-        allocationChanged = true;
-
-        if (aTlv.IsRouterIdSet(routerId))
-        {
-            mAllocatedRouterIds.Add(routerId);
-        }
-        else
+        // If was allocated but removed in new Router Id Set
+        if (IsAllocated(routerId) && !aRouterIdSet.Contains(routerId))
         {
             Router *router = GetRouter(routerId);
 
-            assert(router != NULL);
+            OT_ASSERT(router != nullptr);
             router->SetNextHop(Mle::kInvalidRouterId);
-            RemoveNeighbor(*router);
+            RemoveRouterLink(*router);
 
             mAllocatedRouterIds.Remove(routerId);
         }
     }
 
-    if (allocationChanged)
-    {
-        UpdateAllocation();
-        Get<Mle::MleRouter>().ResetAdvertiseInterval();
-    }
-}
+    mAllocatedRouterIds = aRouterIdSet;
+    UpdateAllocation();
+    Get<Mle::MleRouter>().ResetAdvertiseInterval();
 
-void RouterTable::ProcessTlv(const ThreadRouterMaskTlv &aTlv)
-{
-    bool allocationChanged = false;
-
-    mRouterIdSequence            = aTlv.GetIdSequence();
-    mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
-
-    for (uint8_t routerId = 0; routerId <= Mle::kMaxRouterId; routerId++)
-    {
-        if (aTlv.IsAssignedRouterIdSet(routerId) == IsAllocated(routerId))
-        {
-            continue;
-        }
-
-        allocationChanged = true;
-
-        if (aTlv.IsAssignedRouterIdSet(routerId))
-        {
-            mAllocatedRouterIds.Add(routerId);
-        }
-        else
-        {
-            mAllocatedRouterIds.Remove(routerId);
-        }
-    }
-
-    if (allocationChanged)
-    {
-        UpdateAllocation();
-        Get<Mle::MleRouter>().ResetAdvertiseInterval();
-    }
+exit:
+    return;
 }
 
 void RouterTable::ProcessTimerTick(void)
 {
     Mle::MleRouter &mle = Get<Mle::MleRouter>();
 
-    if (mle.GetRole() == OT_DEVICE_ROLE_LEADER)
+    if (mle.IsLeader())
     {
         // update router id sequence
         if (GetLeaderAge() >= Mle::kRouterIdSequencePeriod)
diff --git a/src/core/thread/router_table.hpp b/src/core/thread/router_table.hpp
index d7bd251..1709f99 100644
--- a/src/core/thread/router_table.hpp
+++ b/src/core/thread/router_table.hpp
@@ -29,17 +29,19 @@
 #ifndef ROUTER_TABLE_HPP_
 #define ROUTER_TABLE_HPP_
 
+#include "openthread-core-config.h"
+
+#if OPENTHREAD_FTD
+
 #include "common/encoding.hpp"
 #include "common/locator.hpp"
 #include "mac/mac_types.hpp"
-#include "thread/mle_constants.hpp"
+#include "thread/mle_types.hpp"
 #include "thread/thread_tlvs.hpp"
 #include "thread/topology.hpp"
 
 namespace ot {
 
-#if OPENTHREAD_FTD
-
 class RouterTable : public InstanceLocator
 {
 public:
@@ -71,13 +73,13 @@
          * @retval FALSE  The iterator currently points to a valid entry.
          *
          */
-        bool IsDone(void) const { return (mRouter == NULL); }
+        bool IsDone(void) const { return (mRouter == nullptr); }
 
         /**
          * This method advances the iterator.
          *
          * The iterator is moved to point to the next entry.  If there are no more entries matching the iterator
-         * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`).
+         * becomes empty (i.e., `GetRouter()` returns `nullptr` and `IsDone()` returns `true`).
          *
          */
         void Advance(void);
@@ -86,7 +88,7 @@
          * This method overloads `++` operator (pre-increment) to advance the iterator.
          *
          * The iterator is moved to point to the next entry.  If there are no more entries matching the iterator
-         * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`).
+         * becomes empty (i.e., `GetRouter()` returns `nullptr` and `IsDone()` returns `true`).
          *
          */
         void operator++(void) { Advance(); }
@@ -95,7 +97,7 @@
          * This method overloads `++` operator (post-increment) to advance the iterator.
          *
          * The iterator is moved to point to the next entry.  If there are no more entries matching the iterator
-         * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`).
+         * becomes empty (i.e., `GetRouter()` returns `nullptr` and `IsDone()` returns `true`).
          *
          */
         void operator++(int) { Advance(); }
@@ -103,7 +105,7 @@
         /**
          * This method gets the entry to which the iterator is currently pointing.
          *
-         * @returns A pointer to the current entry, or `NULL` if the iterator is done/empty.
+         * @returns A pointer to the current entry, or `nullptr` if the iterator is done/empty.
          *
          */
         Router *GetRouter(void) { return mRouter; }
@@ -135,7 +137,7 @@
     /**
      * This method allocates a router with a random router id.
      *
-     * @returns A pointer to the allocated router or NULL if a router ID is not available.
+     * @returns A pointer to the allocated router or nullptr if a router ID is not available.
      *
      */
     Router *Allocate(void);
@@ -143,7 +145,7 @@
     /**
      * This method allocates a router with a specified router id.
      *
-     * @returns A pointer to the allocated router or NULL if the router id could not be allocated.
+     * @returns A pointer to the allocated router or nullptr if the router id could not be allocated.
      *
      */
     Router *Allocate(uint8_t aRouterId);
@@ -161,12 +163,12 @@
     otError Release(uint8_t aRouterId);
 
     /**
-     * This method removes a neighboring router link.
+     * This method removes a router link.
      *
      * @param[in]  aRouter  A reference to the router.
      *
      */
-    void RemoveNeighbor(Router &aRouter);
+    void RemoveRouterLink(Router &aRouter);
 
     /**
      * This method returns the number of active routers in the Thread network.
@@ -215,7 +217,7 @@
      *
      * @param[in]  aRloc16  The RLOC16 value.
      *
-     * @returns A pointer to the router or NULL if the router could not be found.
+     * @returns A pointer to the router or nullptr if the router could not be found.
      *
      */
     Router *GetNeighbor(uint16_t aRloc16);
@@ -225,7 +227,7 @@
      *
      * @param[in]  aExtAddress  A reference to the IEEE Extended Address.
      *
-     * @returns A pointer to the router or NULL if the router could not be found.
+     * @returns A pointer to the router or nullptr if the router could not be found.
      *
      */
     Router *GetNeighbor(const Mac::ExtAddress &aExtAddress);
@@ -235,7 +237,7 @@
      *
      * @param[in]  aRouterId  The router id.
      *
-     * @returns A pointer to the router or NULL if the router could not be found.
+     * @returns A pointer to the router or nullptr if the router could not be found.
      *
      */
     Router *GetRouter(uint8_t aRouterId)
@@ -248,7 +250,7 @@
      *
      * @param[in]  aRouterId  The router id.
      *
-     * @returns A pointer to the router or NULL if the router could not be found.
+     * @returns A pointer to the router or nullptr if the router could not be found.
      *
      */
     const Router *GetRouter(uint8_t aRouterId) const;
@@ -258,12 +260,28 @@
      *
      * @param[in]  aExtAddress  A reference to the IEEE Extended Address.
      *
-     * @returns A pointer to the router or NULL if the router could not be found.
+     * @returns A pointer to the router or nullptr if the router could not be found.
      *
      */
     Router *GetRouter(const Mac::ExtAddress &aExtAddress);
 
     /**
+     * This method returns if the router table contains a given `Neighbor` instance.
+     *
+     * @param[in]  aNeighbor  A reference to a `Neighbor`.
+     *
+     * @retval TRUE  if @p aNeighbor is a `Router` in the router table.
+     * @retval FALSE if @p aNeighbor is not a `Router` in the router table
+     *               (i.e. mParent, mParentCandidate, a `Child` of the child table).
+     *
+     */
+    bool Contains(const Neighbor &aNeighbor) const
+    {
+        return mRouters <= &static_cast<const Router &>(aNeighbor) &&
+               &static_cast<const Router &>(aNeighbor) < mRouters + Mle::kMaxRouters;
+    }
+
+    /**
      * This method retains diagnostic information for a given router.
      *
      * @param[in]   aRouterId    The router ID or RLOC16 for a given router.
@@ -310,20 +328,21 @@
     bool IsAllocated(uint8_t aRouterId) const;
 
     /**
-     * This method updates the router table with a received Route TLV.
+     * This method updates the Router ID allocation.
      *
-     * @param[in]  aTlv  A reference to the Route TLV.
+     * @param[in]  aRouterIdSequence  The Router Id Sequence.
+     * @param[in]  aRouterIdSet       A reference to the Router Id Set.
      *
      */
-    void ProcessTlv(const Mle::RouteTlv &aTlv);
+    void UpdateRouterIdSet(uint8_t aRouterIdSequence, const Mle::RouterIdSet &aRouterIdSet);
 
     /**
-     * This method updates the router table with a received Router Mask TLV.
+     * This method gets the allocated Router ID set.
      *
-     * @param[in]  aTlv  A reference to the Router Mask TLV.
+     * @returns The allocated Router ID set.
      *
      */
-    void ProcessTlv(const ThreadRouterMaskTlv &aTlv);
+    const Mle::RouterIdSet &GetRouterIdSet(void) const { return mAllocatedRouterIds; }
 
     /**
      * This method updates the router table and must be called with a one second period.
@@ -332,18 +351,6 @@
     void ProcessTimerTick(void);
 
 private:
-    class RouterIdSet
-    {
-    public:
-        void Clear(void) { memset(mRouterIdSet, 0, sizeof(mRouterIdSet)); }
-        bool Contains(uint8_t aRouterId) const { return (mRouterIdSet[aRouterId / 8] & (1 << (aRouterId % 8))) != 0; }
-        void Add(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] |= 1 << (aRouterId % 8); }
-        void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~(1 << (aRouterId % 8)); }
-
-    private:
-        uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
-    };
-
     void          UpdateAllocation(void);
     const Router *GetFirstEntry(void) const;
     const Router *GetNextEntry(const Router *aRouter) const;
@@ -353,40 +360,16 @@
         return const_cast<Router *>(const_cast<const RouterTable *>(this)->GetNextEntry(aRouter));
     }
 
-    Router      mRouters[Mle::kMaxRouters];
-    RouterIdSet mAllocatedRouterIds;
-    uint8_t     mRouterIdReuseDelay[Mle::kMaxRouterId + 1];
-    TimeMilli   mRouterIdSequenceLastUpdated;
-    uint8_t     mRouterIdSequence;
-    uint8_t     mActiveRouterCount;
+    Router           mRouters[Mle::kMaxRouters];
+    Mle::RouterIdSet mAllocatedRouterIds;
+    uint8_t          mRouterIdReuseDelay[Mle::kMaxRouterId + 1];
+    TimeMilli        mRouterIdSequenceLastUpdated;
+    uint8_t          mRouterIdSequence;
+    uint8_t          mActiveRouterCount;
 };
 
-#endif // OPENTHREAD_FTD
-
-#if OPENTHREAD_MTD
-
-class RouterTable
-{
-public:
-    class Iterator
-    {
-    public:
-        explicit Iterator(Instance &) {}
-        void    Reset(void) {}
-        bool    IsDone(void) const { return true; }
-        void    Advance(void) {}
-        void    operator++(void) {}
-        void    operator++(int) {}
-        Router *GetRouter(void) { return NULL; }
-    };
-
-    explicit RouterTable(Instance &) {}
-
-    uint8_t GetNeighborCount(void) const { return 0; }
-};
-
-#endif // OPENTHREAD_MTD
-
 } // namespace ot
 
+#endif // OPENTHREAD_FTD
+
 #endif // ROUTER_TABLE_HPP_
diff --git a/src/core/thread/src_match_controller.cpp b/src/core/thread/src_match_controller.cpp
index c0226e4..0dcc91c 100644
--- a/src/core/thread/src_match_controller.cpp
+++ b/src/core/thread/src_match_controller.cpp
@@ -33,6 +33,8 @@
 
 #include "src_match_controller.hpp"
 
+#if OPENTHREAD_FTD
+
 #include "common/code_utils.hpp"
 #include "common/debug.hpp"
 #include "common/instance.hpp"
@@ -90,7 +92,7 @@
 
 void SourceMatchController::SetSrcMatchAsShort(Child &aChild, bool aUseShortAddress)
 {
-    VerifyOrExit(aChild.IsIndirectSourceMatchShort() != aUseShortAddress);
+    VerifyOrExit(aChild.IsIndirectSourceMatchShort() != aUseShortAddress, OT_NOOP);
 
     if (aChild.GetIndirectMessageCount() > 0)
     {
@@ -210,12 +212,12 @@
 {
     otError error = OT_ERROR_NONE;
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValidOrRestoring); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
     {
-        if (iter.GetChild()->IsIndirectSourceMatchPending())
+        if (child.IsIndirectSourceMatchPending())
         {
-            SuccessOrExit(error = AddAddress(*iter.GetChild()));
-            iter.GetChild()->SetIndirectSourceMatchPending(false);
+            SuccessOrExit(error = AddAddress(child));
+            child.SetIndirectSourceMatchPending(false);
         }
     }
 
@@ -224,3 +226,5 @@
 }
 
 } // namespace ot
+
+#endif // OPENTHREAD_FTD
diff --git a/src/core/thread/thread_netif.cpp b/src/core/thread/thread_netif.cpp
index 0bd3768..1bb64ac 100644
--- a/src/core/thread/thread_netif.cpp
+++ b/src/core/thread/thread_netif.cpp
@@ -52,19 +52,19 @@
     , mCoap(aInstance)
 #if OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
     , mDhcp6Client(aInstance)
-#endif // OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
+#endif
 #if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
     , mDhcp6Server(aInstance)
-#endif // OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
+#endif
 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
     , mSlaac(aInstance)
 #endif
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
-    , mDnsClient(Get<ThreadNetif>())
-#endif // OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
+    , mDnsClient(aInstance)
+#endif
 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
-    , mSntpClient(Get<ThreadNetif>())
-#endif // OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
+    , mSntpClient(aInstance)
+#endif
     , mActiveDataset(aInstance)
     , mPendingDataset(aInstance)
     , mKeyManager(aInstance)
@@ -72,10 +72,14 @@
     , mMac(aInstance)
     , mMeshForwarder(aInstance)
     , mMleRouter(aInstance)
+    , mDiscoverScanner(aInstance)
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
     , mNetworkDataLocal(aInstance)
 #endif
     , mNetworkDataLeader(aInstance)
+#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+    , mNetworkDataNotifier(aInstance)
+#endif
 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
     , mNetworkDiagnostic(aInstance)
 #endif
@@ -85,21 +89,30 @@
 #endif
 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
     , mCommissioner(aInstance)
-#endif // OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
+#endif
 #if OPENTHREAD_CONFIG_DTLS_ENABLE
     , mCoapSecure(aInstance)
 #endif
 #if OPENTHREAD_CONFIG_JOINER_ENABLE
     , mJoiner(aInstance)
-#endif // OPENTHREAD_CONFIG_JOINER_ENABLE
+#endif
 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
     , mJamDetector(aInstance)
-#endif // OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
+#endif
 #if OPENTHREAD_FTD
     , mJoinerRouter(aInstance)
     , mLeader(aInstance)
     , mAddressResolver(aInstance)
-#endif // OPENTHREAD_FTD
+#endif
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    , mBackboneRouterLeader(aInstance)
+#endif
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    , mBackboneRouterLocal(aInstance)
+#endif
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    , mDuaManager(aInstance)
+#endif
     , mChildSupervisor(aInstance)
     , mSupervisionListener(aInstance)
     , mAnnounceBegin(aInstance)
@@ -114,27 +127,27 @@
 
 void ThreadNetif::Up(void)
 {
-    VerifyOrExit(!mIsUp);
+    VerifyOrExit(!mIsUp, OT_NOOP);
 
     // Enable the MAC just in case it was disabled while the Interface was down.
     Get<Mac::Mac>().SetEnabled(true);
 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
-    Get<Utils::ChannelMonitor>().Start();
+    IgnoreError(Get<Utils::ChannelMonitor>().Start());
 #endif
     Get<MeshForwarder>().Start();
 
     mIsUp = true;
 
     SubscribeAllNodesMulticast();
-    Get<Mle::MleRouter>().Enable();
-    Get<Coap::Coap>().Start(kCoapUdpPort);
+    IgnoreError(Get<Mle::MleRouter>().Enable());
+    IgnoreError(Get<Coap::Coap>().Start(kCoapUdpPort));
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
-    Get<Dns::Client>().Start();
+    IgnoreError(Get<Dns::Client>().Start());
 #endif
 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
-    Get<Sntp::Client>().Start();
+    IgnoreError(Get<Sntp::Client>().Start());
 #endif
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETIF_STATE);
+    Get<Notifier>().Signal(kEventThreadNetifStateChanged);
 
 exit:
     return;
@@ -142,19 +155,19 @@
 
 void ThreadNetif::Down(void)
 {
-    VerifyOrExit(mIsUp);
+    VerifyOrExit(mIsUp, OT_NOOP);
 
 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
-    Get<Dns::Client>().Stop();
+    IgnoreError(Get<Dns::Client>().Stop());
 #endif
 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
-    Get<Sntp::Client>().Stop();
+    IgnoreError(Get<Sntp::Client>().Stop());
 #endif
 #if OPENTHREAD_CONFIG_DTLS_ENABLE
     Get<Coap::CoapSecure>().Stop();
 #endif
-    Get<Coap::Coap>().Stop();
-    Get<Mle::MleRouter>().Disable();
+    IgnoreError(Get<Coap::Coap>().Stop());
+    IgnoreError(Get<Mle::MleRouter>().Disable());
     RemoveAllExternalUnicastAddresses();
     UnsubscribeAllExternalMulticastAddresses();
     UnsubscribeAllRoutersMulticast();
@@ -163,9 +176,9 @@
     mIsUp = false;
     Get<MeshForwarder>().Stop();
 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
-    Get<Utils::ChannelMonitor>().Stop();
+    IgnoreError(Get<Utils::ChannelMonitor>().Stop());
 #endif
-    Get<Notifier>().Signal(OT_CHANGED_THREAD_NETIF_STATE);
+    Get<Notifier>().Signal(kEventThreadNetifStateChanged);
 
 exit:
     return;
@@ -194,6 +207,11 @@
     return static_cast<ThreadNetif *>(aContext)->IsTmfMessage(aMessageInfo) ? OT_ERROR_NONE : OT_ERROR_NOT_TMF;
 }
 
+bool ThreadNetif::IsOnMesh(const Ip6::Address &aAddress) const
+{
+    return Get<NetworkData::Leader>().IsOnMesh(aAddress);
+}
+
 bool ThreadNetif::IsTmfMessage(const Ip6::MessageInfo &aMessageInfo)
 {
     bool rval = true;
diff --git a/src/core/thread/thread_netif.hpp b/src/core/thread/thread_netif.hpp
index 46aa3d0..55843b1 100644
--- a/src/core/thread/thread_netif.hpp
+++ b/src/core/thread/thread_netif.hpp
@@ -47,6 +47,17 @@
 #include "meshcop/commissioner.hpp"
 #endif // OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+#include "backbone_router/bbr_leader.hpp"
+#endif
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+#include "backbone_router/bbr_local.hpp"
+#endif
+
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+#include "thread/dua_manager.hpp"
+#endif
+
 #include "meshcop/dataset_manager.hpp"
 
 #if OPENTHREAD_CONFIG_JOINER_ENABLE
@@ -54,7 +65,7 @@
 #endif // OPENTHREAD_CONFIG_JOINER_ENABLE
 
 #include "meshcop/joiner_router.hpp"
-#include "meshcop/leader.hpp"
+#include "meshcop/meshcop_leader.hpp"
 #include "net/dhcp6.hpp"
 #include "net/dhcp6_client.hpp"
 #include "net/dhcp6_server.hpp"
@@ -64,12 +75,14 @@
 #include "net/sntp_client.hpp"
 #include "thread/address_resolver.hpp"
 #include "thread/announce_begin_server.hpp"
+#include "thread/discover_scanner.hpp"
 #include "thread/energy_scan_server.hpp"
 #include "thread/key_manager.hpp"
 #include "thread/mesh_forwarder.hpp"
 #include "thread/mle.hpp"
 #include "thread/mle_router.hpp"
 #include "thread/network_data_local.hpp"
+#include "thread/network_data_notifier.hpp"
 #include "thread/network_diagnostic.hpp"
 #include "thread/panid_query_server.hpp"
 #include "thread/time_sync_service.hpp"
@@ -152,6 +165,17 @@
     otError RouteLookup(const Ip6::Address &aSource, const Ip6::Address &aDestination, uint8_t *aPrefixMatch);
 
     /**
+     * This method indicates whether @p aAddress matches an on-mesh prefix.
+     *
+     * @param[in]  aAddress  The IPv6 address.
+     *
+     * @retval TRUE   If @p aAddress matches an on-mesh prefix.
+     * @retval FALSE  If @p aAddress does not match an on-mesh prefix.
+     *
+     */
+    bool IsOnMesh(const Ip6::Address &aAddress) const;
+
+    /**
      * This method returns whether Thread Management Framework Addressing Rules are met.
      *
      * @retval TRUE   if Thread Management Framework Addressing Rules are met.
@@ -187,10 +211,14 @@
     Mac::Mac                mMac;
     MeshForwarder           mMeshForwarder;
     Mle::MleRouter          mMleRouter;
+    Mle::DiscoverScanner    mDiscoverScanner;
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
     NetworkData::Local mNetworkDataLocal;
 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
     NetworkData::Leader mNetworkDataLeader;
+#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+    NetworkData::Notifier mNetworkDataNotifier;
+#endif
 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
     NetworkDiagnostic::NetworkDiagnostic mNetworkDiagnostic;
 #endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
@@ -221,6 +249,15 @@
     AddressResolver       mAddressResolver;
 #endif // OPENTHREAD_FTD
 
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    BackboneRouter::Leader mBackboneRouterLeader;
+#endif
+#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+    BackboneRouter::Local mBackboneRouterLocal;
+#endif
+#if OPENTHREAD_CONFIG_DUA_ENABLE
+    DuaManager mDuaManager;
+#endif
     Utils::ChildSupervisor     mChildSupervisor;
     Utils::SupervisionListener mSupervisionListener;
     AnnounceBeginServer        mAnnounceBegin;
diff --git a/src/core/thread/thread_tlvs.hpp b/src/core/thread/thread_tlvs.hpp
index 196677b..e3de8ed 100644
--- a/src/core/thread/thread_tlvs.hpp
+++ b/src/core/thread/thread_tlvs.hpp
@@ -41,6 +41,7 @@
 #include "common/tlvs.hpp"
 #include "net/ip6_address.hpp"
 #include "thread/mle.hpp"
+#include "thread/mle_types.hpp"
 
 namespace ot {
 
@@ -94,256 +95,16 @@
      */
     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
 
-    /**
-     * This static method reads the requested TLV out of @p aMessage.
-     *
-     * @param[in]   aMessage    A reference to the message.
-     * @param[in]   aType       The Type value to search for.
-     * @param[in]   aMaxLength  Maximum number of bytes to read.
-     * @param[out]  aTlv        A reference to the TLV that will be copied to.
-     *
-     * @retval OT_ERROR_NONE       Successfully copied the TLV.
-     * @retval OT_ERROR_NOT_FOUND  Could not find the TLV with Type @p aType.
-     *
-     */
-    static otError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv)
-    {
-        return ot::Tlv::Get(aMessage, static_cast<uint8_t>(aType), aMaxLength, aTlv);
-    }
-
 } OT_TOOL_PACKED_END;
 
 /**
- * This class implements Target EID TLV generation and parsing.
+ * This class defines Status TLV constants.
  *
  */
-OT_TOOL_PACKED_BEGIN
-class ThreadTargetTlv : public ThreadTlv
+class ThreadStatusTlv
 {
 public:
     /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kTarget);
-        SetLength(sizeof(*this) - sizeof(ThreadTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); }
-
-    /**
-     * This method returns a reference to the Target EID.
-     *
-     * @returns A pointer to the Target EID.
-     *
-     */
-    const Ip6::Address &GetTarget(void) const { return mTarget; }
-
-    /**
-     * This method sets the Target EID.
-     *
-     * @param[in]  aTarget  A reference to the Target EID.
-     *
-     */
-    void SetTarget(const Ip6::Address &aTarget) { mTarget = aTarget; }
-
-private:
-    Ip6::Address mTarget;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Extended MAC Address TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ThreadExtMacAddressTlv : public ThreadTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kExtMacAddress);
-        SetLength(sizeof(*this) - sizeof(ThreadTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); }
-
-    /**
-     * This method returns a reference to the Extended MAC Address.
-     *
-     * @returns A pointer to the Extended MAC Address.
-     *
-     */
-    const Mac::ExtAddress &GetMacAddr(void) const { return mMacAddr; }
-
-    /**
-     * This method sets the Extended MAC Address.
-     *
-     * @param[in]  aAddress  A reference to the Extended MAC Address.
-     *
-     */
-    void SetMacAddr(const Mac::ExtAddress &aAddress) { mMacAddr = aAddress; }
-
-private:
-    Mac::ExtAddress mMacAddr;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements RLOC16 TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ThreadRloc16Tlv : public ThreadTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kRloc16);
-        SetLength(sizeof(*this) - sizeof(ThreadTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); }
-
-    /**
-     * This method returns the RLOC16 value.
-     *
-     * @returns The RLOC16 value.
-     *
-     */
-    uint16_t GetRloc16(void) const { return HostSwap16(mRloc16); }
-
-    /**
-     * This method sets the RLOC16 value.
-     *
-     * @param[in]  aRloc16  The RLOC16 value.
-     *
-     */
-    void SetRloc16(uint16_t aRloc16) { mRloc16 = HostSwap16(aRloc16); }
-
-private:
-    uint16_t mRloc16;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements ML-EID TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ThreadMeshLocalEidTlv : public ThreadTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kMeshLocalEid);
-        SetLength(sizeof(*this) - sizeof(ThreadTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); }
-
-    /**
-     * This method returns a pointer to the ML-EID IID.
-     *
-     * @returns A pointer to the Extended MAC Address.
-     *
-     */
-    const uint8_t *GetIid(void) const { return mIid; }
-
-    /**
-     * This method sets the ML-EID IID.
-     *
-     * @param[in]  aIid  A pointer to the ML-EID IID.
-     *
-     */
-    void SetIid(const uint8_t *aIid) { memcpy(mIid, aIid, sizeof(mIid)); }
-
-    /**
-     * This method sets the ML-EID IID.
-     *
-     * @param[in]  aExtAddress  A reference to the MAC Extended Address.
-     *
-     */
-    void SetIid(const Mac::ExtAddress &aExtAddress)
-    {
-        Mac::ExtAddress addr;
-
-        addr = aExtAddress;
-        addr.ToggleLocal();
-        addr.CopyTo(mIid);
-    }
-
-private:
-    uint8_t mIid[8];
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Status TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ThreadStatusTlv : public ThreadTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kStatus);
-        SetLength(sizeof(*this) - sizeof(ThreadTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); }
-
-    /**
      * Status values.
      *
      */
@@ -355,73 +116,7 @@
         kHaveChildIdRequest    = 3, ///< Address Solicit due to child ID request.
         kParentPartitionChange = 4, ///< Address Solicit due to parent partition change
     };
-
-    /**
-     * This method returns the Status value.
-     *
-     * @returns The Status value.
-     *
-     */
-    Status GetStatus(void) const { return static_cast<Status>(mStatus); }
-
-    /**
-     * This method sets the Status value.
-     *
-     * @param[in]  aStatus  The Status value.
-     *
-     */
-    void SetStatus(Status aStatus) { mStatus = static_cast<uint8_t>(aStatus); }
-
-private:
-    uint8_t mStatus;
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements Time Since Last Transaction TLV generation and parsing.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class ThreadLastTransactionTimeTlv : public ThreadTlv
-{
-public:
-    /**
-     * This method initializes the TLV.
-     *
-     */
-    void Init(void)
-    {
-        SetType(kLastTransactionTime);
-        SetLength(sizeof(*this) - sizeof(ThreadTlv));
-    }
-
-    /**
-     * This method indicates whether or not the TLV appears to be well-formed.
-     *
-     * @retval TRUE   If the TLV appears to be well-formed.
-     * @retval FALSE  If the TLV does not appear to be well-formed.
-     *
-     */
-    bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); }
-
-    /**
-     * This method returns the Last Transaction Time value.
-     *
-     * @returns The Last Transaction Time value.
-     *
-     */
-    uint32_t GetTime(void) const { return HostSwap32(mTime); }
-
-    /**
-     * This method sets the Last Transaction Time value.
-     *
-     * @param[in]  aTime  The Last Transaction Time value.
-     *
-     */
-    void SetTime(uint32_t aTime) { mTime = HostSwap32(aTime); }
-
-private:
-    uint32_t mTime;
-} OT_TOOL_PACKED_END;
+};
 
 /**
  * This class implements Router Mask TLV generation and parsing.
@@ -438,6 +133,7 @@
     {
         SetType(kRouterMask);
         SetLength(sizeof(*this) - sizeof(ThreadTlv));
+        mAssignedRouterIdMask.Clear();
     }
 
     /**
@@ -466,36 +162,24 @@
     void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; }
 
     /**
-     * This method clears the Assigned Router ID Mask.
+     * This method gets the Assigned Router ID Mask.
+     *
+     * @returns The Assigned Router ID Mask.
      *
      */
-    void ClearAssignedRouterIdMask(void) { memset(mAssignedRouterIdMask, 0, sizeof(mAssignedRouterIdMask)); }
+    const Mle::RouterIdSet &GetAssignedRouterIdMask(void) const { return mAssignedRouterIdMask; }
 
     /**
-     * This method indicates whether or not a given Router ID is set in the Assigned Router ID Mask.
+     * This method sets the Assigned Router ID Mask.
      *
-     * @param[in]  aRouterId  The Router ID.
-     *
-     * @retval TRUE   If the given Router ID is set in the Assigned Router ID Mask.
-     * @retval FALSE  If the given Router ID is not set in the Assigned Router ID Mask.
+     * @param[in]  aRouterIdSet A reference to the Assigned Router ID Mask.
      *
      */
-    bool IsAssignedRouterIdSet(uint8_t aRouterId) const
-    {
-        return (mAssignedRouterIdMask[aRouterId / 8] & (0x80 >> (aRouterId % 8))) != 0;
-    }
-
-    /**
-     * This method clears the Assigned Router ID Mask.
-     *
-     * @param[in]  aRouterId  The Router ID.
-     *
-     */
-    void SetAssignedRouterId(uint8_t aRouterId) { mAssignedRouterIdMask[aRouterId / 8] |= 0x80 >> (aRouterId % 8); }
+    void SetAssignedRouterIdMask(const Mle::RouterIdSet &aRouterIdSet) { mAssignedRouterIdMask = aRouterIdSet; }
 
 private:
-    uint8_t mIdSequence;
-    uint8_t mAssignedRouterIdMask[BitVectorBytes(Mle::kMaxRouterId + 1)];
+    uint8_t          mIdSequence;
+    Mle::RouterIdSet mAssignedRouterIdMask;
 };
 
 /**
diff --git a/src/core/thread/time_sync_service.cpp b/src/core/thread/time_sync_service.cpp
index 18b88b6..0bf5d4a 100644
--- a/src/core/thread/time_sync_service.cpp
+++ b/src/core/thread/time_sync_service.cpp
@@ -51,6 +51,7 @@
 
 TimeSync::TimeSync(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , Notifier::Receiver(aInstance, TimeSync::HandleNotifierEvents)
     , mTimeSyncRequired(false)
     , mTimeSyncSeq(OT_TIME_SYNC_INVALID_SEQ)
     , mTimeSyncPeriod(OPENTHREAD_CONFIG_TIME_SYNC_PERIOD)
@@ -60,9 +61,8 @@
 #endif
     , mLastTimeSyncReceived(0)
     , mNetworkTimeOffset(0)
-    , mTimeSyncCallback(NULL)
-    , mTimeSyncCallbackContext(NULL)
-    , mNotifierCallback(aInstance, &TimeSync::HandleStateChanged, this)
+    , mTimeSyncCallback(nullptr)
+    , mTimeSyncCallbackContext(nullptr)
     , mTimer(aInstance, HandleTimeout, this)
     , mCurrentStatus(OT_NETWORK_TIME_UNSYNCHRONIZED)
 {
@@ -81,23 +81,23 @@
     const int64_t origNetworkTimeOffset = mNetworkTimeOffset;
     int8_t        timeSyncSeqDelta;
 
-    VerifyOrExit(aMessage.GetTimeSyncSeq() != OT_TIME_SYNC_INVALID_SEQ);
+    VerifyOrExit(aMessage.GetTimeSyncSeq() != OT_TIME_SYNC_INVALID_SEQ, OT_NOOP);
 
     timeSyncSeqDelta = static_cast<int8_t>(aMessage.GetTimeSyncSeq() - mTimeSyncSeq);
 
     if (mTimeSyncSeq != OT_TIME_SYNC_INVALID_SEQ && timeSyncSeqDelta < 0)
     {
         // An older time sync sequence was received. This indicates that there is a device that still needs to be
-        // synchronised with the current sequence, so forward it.
+        // synchronized with the current sequence, so forward it.
         mTimeSyncRequired = true;
 
         otLogInfoCore("Older time sync seq received:%u. Forwarding current seq:%u", aMessage.GetTimeSyncSeq(),
                       mTimeSyncSeq);
     }
-    else if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER && timeSyncSeqDelta > 0)
+    else if (Get<Mle::MleRouter>().IsLeader() && timeSyncSeqDelta > 0)
     {
         // Another device is forwarding a later time sync sequence, perhaps because it merged from a different
-        // partition. The leader is authoritative, so ensure all devices synchronise to the time being seeded by this
+        // partition. The leader is authoritative, so ensure all devices synchronize to the time being seeded by this
         // leader instead.
         mTimeSyncSeq      = aMessage.GetTimeSyncSeq() + 1;
         mTimeSyncRequired = true;
@@ -105,14 +105,13 @@
         otLogInfoCore("Newer time sync seq:%u received by leader. Setting current seq to:%u and forwarding",
                       aMessage.GetTimeSyncSeq(), mTimeSyncSeq);
     }
-    else if (Get<Mle::MleRouter>().GetRole() != OT_DEVICE_ROLE_LEADER)
+    else if (!Get<Mle::MleRouter>().IsLeader())
     {
         // For all devices aside from the leader, update network time in following three cases:
         //  1. During first attach.
         //  2. Already attached, and a newer time sync sequence was received.
         //  3. During reattach or migration process.
-        if (mTimeSyncSeq == OT_TIME_SYNC_INVALID_SEQ || timeSyncSeqDelta > 0 ||
-            Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_DETACHED)
+        if (mTimeSyncSeq == OT_TIME_SYNC_INVALID_SEQ || timeSyncSeqDelta > 0 || Get<Mle::MleRouter>().IsDetached())
         {
             // Update network time and forward it.
             mLastTimeSyncReceived = TimerMilli::GetNow();
@@ -143,7 +142,7 @@
 
 void TimeSync::NotifyTimeSyncCallback(void)
 {
-    if (mTimeSyncCallback != NULL)
+    if (mTimeSyncCallback != nullptr)
     {
         mTimeSyncCallback(mTimeSyncCallbackContext);
     }
@@ -152,7 +151,7 @@
 #if OPENTHREAD_FTD
 void TimeSync::ProcessTimeSync(void)
 {
-    if (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_LEADER &&
+    if (Get<Mle::MleRouter>().IsLeader() &&
         (TimerMilli::GetNow() - mLastTimeSyncSent > Time::SecToMsec(mTimeSyncPeriod)))
     {
         IncrementTimeSyncSeq();
@@ -163,7 +162,7 @@
 
     if (mTimeSyncRequired)
     {
-        VerifyOrExit(Get<Mle::MleRouter>().SendTimeSync() == OT_ERROR_NONE);
+        VerifyOrExit(Get<Mle::MleRouter>().SendTimeSync() == OT_ERROR_NONE, OT_NOOP);
 
         mLastTimeSyncSent = TimerMilli::GetNow();
         mTimeSyncRequired = false;
@@ -174,16 +173,16 @@
 }
 #endif // OPENTHREAD_FTD
 
-void TimeSync::HandleStateChanged(otChangedFlags aFlags)
+void TimeSync::HandleNotifierEvents(Events aEvents)
 {
     bool stateChanged = false;
 
-    if ((aFlags & OT_CHANGED_THREAD_ROLE) != 0)
+    if (aEvents.Contains(kEventThreadRoleChanged))
     {
         stateChanged = true;
     }
 
-    if ((aFlags & OT_CHANGED_THREAD_PARTITION_ID) != 0 && Get<Mle::MleRouter>().GetRole() != OT_DEVICE_ROLE_LEADER)
+    if (aEvents.Contains(kEventThreadPartitionIdChanged) && !Get<Mle::MleRouter>().IsLeader())
     {
         // Partition has changed. Accept any network time currently being seeded on the new partition
         // and don't attempt to forward the currently held network time from the previous partition.
@@ -210,9 +209,9 @@
     CheckAndHandleChanges(false);
 }
 
-void TimeSync::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags)
+void TimeSync::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<TimeSync>().HandleStateChanged(aFlags);
+    static_cast<TimeSync &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
 void TimeSync::HandleTimeout(Timer &aTimer)
@@ -230,14 +229,14 @@
 
     switch (Get<Mle::MleRouter>().GetRole())
     {
-    case OT_DEVICE_ROLE_DISABLED:
-    case OT_DEVICE_ROLE_DETACHED:
+    case Mle::kRoleDisabled:
+    case Mle::kRoleDetached:
         networkTimeStatus = OT_NETWORK_TIME_UNSYNCHRONIZED;
         otLogInfoCore("Time sync status UNSYNCHRONIZED as role:DISABLED/DETACHED");
         break;
 
-    case OT_DEVICE_ROLE_CHILD:
-    case OT_DEVICE_ROLE_ROUTER:
+    case Mle::kRoleChild:
+    case Mle::kRoleRouter:
         if (mLastTimeSyncReceived.GetValue() == 0)
         {
             // Haven't yet received any time sync
@@ -254,13 +253,13 @@
         else
         {
             // Schedule a check 1 millisecond after two periods of time
-            assert(resyncNeededThresholdMs >= timeSyncLastSyncMs);
+            OT_ASSERT(resyncNeededThresholdMs >= timeSyncLastSyncMs);
             mTimer.Start(resyncNeededThresholdMs - timeSyncLastSyncMs + 1);
             otLogInfoCore("Time sync status SYNCHRONIZED");
         }
         break;
 
-    case OT_DEVICE_ROLE_LEADER:
+    case Mle::kRoleLeader:
         otLogInfoCore("Time sync status SYNCHRONIZED as role:LEADER");
         break;
     }
diff --git a/src/core/thread/time_sync_service.hpp b/src/core/thread/time_sync_service.hpp
index 8563b34..fad0f96 100644
--- a/src/core/thread/time_sync_service.hpp
+++ b/src/core/thread/time_sync_service.hpp
@@ -50,7 +50,7 @@
  * This class implements OpenThread Time Synchronization Service.
  *
  */
-class TimeSync : public InstanceLocator
+class TimeSync : public InstanceLocator, public Notifier::Receiver
 {
 public:
     /**
@@ -157,7 +157,7 @@
      * @param[in] aFlags Flags that denote the state change events.
      *
      */
-    void HandleStateChanged(otChangedFlags aFlags);
+    void HandleNotifierEvents(Events aEvents);
 
     /**
      * Callback to be called when timer expires.
@@ -173,7 +173,7 @@
      * @param[in] aFlags Flags that denote the state change events.
      *
      */
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags);
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
 
     /**
      * Callback to be called when timer expires.
@@ -216,7 +216,6 @@
     otNetworkTimeSyncCallbackFn
                         mTimeSyncCallback; ///< The callback to be called when time sync is handled or status updated.
     void *              mTimeSyncCallbackContext; ///< The context to be passed to callback.
-    Notifier::Callback  mNotifierCallback;        ///< Callback for thread state changes.
     TimerMilli          mTimer;                   ///< Timer for checking if a resync is required.
     otNetworkTimeStatus mCurrentStatus;           ///< Current network time status.
 };
diff --git a/src/core/thread/topology.cpp b/src/core/thread/topology.cpp
index fc7f6b1..b49256f 100644
--- a/src/core/thread/topology.cpp
+++ b/src/core/thread/topology.cpp
@@ -41,6 +41,13 @@
 
 namespace ot {
 
+void Neighbor::Init(Instance &aInstance)
+{
+    InstanceLocatorInit::Init(aInstance);
+    mLinkInfo.Init(aInstance);
+    SetState(kStateInvalid);
+}
+
 bool Neighbor::IsStateValidOrAttaching(void) const
 {
     bool rval = false;
@@ -100,59 +107,38 @@
 
 void Neighbor::GenerateChallenge(void)
 {
-    Random::Crypto::FillBuffer(mValidPending.mPending.mChallenge, sizeof(mValidPending.mPending.mChallenge));
+    IgnoreError(
+        Random::Crypto::FillBuffer(mValidPending.mPending.mChallenge, sizeof(mValidPending.mPending.mChallenge)));
 }
 
 void Child::Clear(void)
 {
+    Instance &instance = GetInstance();
+
     memset(reinterpret_cast<void *>(this), 0, sizeof(Child));
-    SetState(kStateInvalid);
+    Init(instance);
 }
 
 void Child::ClearIp6Addresses(void)
 {
-    memset(mMeshLocalIid, 0, sizeof(mMeshLocalIid));
+    mMeshLocalIid.Clear();
     memset(mIp6Address, 0, sizeof(mIp6Address));
 }
 
-/**
- * Determines if all elements in an array are zero.
- *
- * @param[in]  aArray   A pointer to an array of bytes.
- * @param[in]  aLength  Array length (number of bytes).
- *
- * @returns TRUE if all bytes in the array are zero, FALSE otherwise.
- *
- */
-static bool IsAllZero(const uint8_t *aArray, uint8_t aLength)
-{
-    bool retval = true;
-
-    for (; aLength != 0; aArray++, aLength--)
-    {
-        VerifyOrExit(*aArray == 0, retval = false);
-    }
-
-exit:
-    return retval;
-}
-
-otError Child::GetMeshLocalIp6Address(Instance &aInstance, Ip6::Address &aAddress) const
+otError Child::GetMeshLocalIp6Address(Ip6::Address &aAddress) const
 {
     otError error = OT_ERROR_NONE;
 
-    VerifyOrExit(!IsAllZero(mMeshLocalIid, sizeof(mMeshLocalIid)), error = OT_ERROR_NOT_FOUND);
+    VerifyOrExit(!mMeshLocalIid.IsUnspecified(), error = OT_ERROR_NOT_FOUND);
 
-    memcpy(aAddress.mFields.m8, aInstance.Get<Mle::MleRouter>().GetMeshLocalPrefix().m8,
-           Ip6::Address::kMeshLocalPrefixSize);
-
+    aAddress.SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
     aAddress.SetIid(mMeshLocalIid);
 
 exit:
     return error;
 }
 
-otError Child::GetNextIp6Address(Instance &aInstance, Ip6AddressIterator &aIterator, Ip6::Address &aAddress) const
+otError Child::GetNextIp6Address(Ip6AddressIterator &aIterator, Ip6::Address &aAddress) const
 {
     otError                   error = OT_ERROR_NONE;
     otChildIp6AddressIterator index;
@@ -162,7 +148,7 @@
     if (aIterator.Get() == 0)
     {
         aIterator.Increment();
-        VerifyOrExit(GetMeshLocalIp6Address(aInstance, aAddress) == OT_ERROR_NOT_FOUND);
+        VerifyOrExit(GetMeshLocalIp6Address(aAddress) == OT_ERROR_NOT_FOUND, OT_NOOP);
     }
 
     index = aIterator.Get() - 1;
@@ -177,16 +163,16 @@
     return error;
 }
 
-otError Child::AddIp6Address(Instance &aInstance, const Ip6::Address &aAddress)
+otError Child::AddIp6Address(const Ip6::Address &aAddress)
 {
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(!aAddress.IsUnspecified(), error = OT_ERROR_INVALID_ARGS);
 
-    if (aInstance.Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
+    if (Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
     {
-        VerifyOrExit(IsAllZero(mMeshLocalIid, sizeof(mMeshLocalIid)), error = OT_ERROR_ALREADY);
-        memcpy(mMeshLocalIid, aAddress.GetIid(), Ip6::Address::kInterfaceIdentifierSize);
+        VerifyOrExit(mMeshLocalIid.IsUnspecified(), error = OT_ERROR_ALREADY);
+        mMeshLocalIid = aAddress.GetIid();
         ExitNow();
     }
 
@@ -207,18 +193,18 @@
     return error;
 }
 
-otError Child::RemoveIp6Address(Instance &aInstance, const Ip6::Address &aAddress)
+otError Child::RemoveIp6Address(const Ip6::Address &aAddress)
 {
     otError  error = OT_ERROR_NOT_FOUND;
     uint16_t index;
 
     VerifyOrExit(!aAddress.IsUnspecified(), error = OT_ERROR_INVALID_ARGS);
 
-    if (aInstance.Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
+    if (Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
     {
-        if (memcmp(aAddress.GetIid(), mMeshLocalIid, Ip6::Address::kInterfaceIdentifierSize) == 0)
+        if (aAddress.GetIid() == mMeshLocalIid)
         {
-            memset(mMeshLocalIid, 0, sizeof(mMeshLocalIid));
+            mMeshLocalIid.Clear();
             error = OT_ERROR_NONE;
         }
 
@@ -227,7 +213,7 @@
 
     for (index = 0; index < kNumIp6Addresses; index++)
     {
-        VerifyOrExit(!mIp6Address[index].IsUnspecified());
+        VerifyOrExit(!mIp6Address[index].IsUnspecified(), OT_NOOP);
 
         if (mIp6Address[index] == aAddress)
         {
@@ -249,21 +235,21 @@
     return error;
 }
 
-bool Child::HasIp6Address(Instance &aInstance, const Ip6::Address &aAddress) const
+bool Child::HasIp6Address(const Ip6::Address &aAddress) const
 {
     bool retval = false;
 
-    VerifyOrExit(!aAddress.IsUnspecified());
+    VerifyOrExit(!aAddress.IsUnspecified(), OT_NOOP);
 
-    if (aInstance.Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
+    if (Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
     {
-        retval = (memcmp(aAddress.GetIid(), mMeshLocalIid, Ip6::Address::kInterfaceIdentifierSize) == 0);
+        retval = (aAddress.GetIid() == mMeshLocalIid);
         ExitNow();
     }
 
     for (uint16_t index = 0; index < kNumIp6Addresses; index++)
     {
-        VerifyOrExit(!mIp6Address[index].IsUnspecified());
+        VerifyOrExit(!mIp6Address[index].IsUnspecified(), OT_NOOP);
 
         if (mIp6Address[index] == aAddress)
         {
@@ -277,13 +263,15 @@
 
 void Child::GenerateChallenge(void)
 {
-    Random::Crypto::FillBuffer(mAttachChallenge, sizeof(mAttachChallenge));
+    IgnoreError(Random::Crypto::FillBuffer(mAttachChallenge, sizeof(mAttachChallenge)));
 }
 
 void Router::Clear(void)
 {
+    Instance &instance = GetInstance();
+
     memset(reinterpret_cast<void *>(this), 0, sizeof(Router));
-    SetState(kStateInvalid);
+    Init(instance);
 }
 
 } // namespace ot
diff --git a/src/core/thread/topology.hpp b/src/core/thread/topology.hpp
index 3512ec6..7599ffd 100644
--- a/src/core/thread/topology.hpp
+++ b/src/core/thread/topology.hpp
@@ -38,25 +38,24 @@
 
 #include <openthread/thread_ftd.h>
 
+#include "common/locator.hpp"
 #include "common/message.hpp"
 #include "common/random.hpp"
 #include "common/timer.hpp"
 #include "mac/mac_types.hpp"
 #include "net/ip6.hpp"
-#include "thread/device_mode.hpp"
 #include "thread/indirect_sender.hpp"
 #include "thread/link_quality.hpp"
 #include "thread/mle_tlvs.hpp"
+#include "thread/mle_types.hpp"
 
 namespace ot {
 
-class Instance;
-
 /**
  * This class represents a Thread neighbor.
  *
  */
-class Neighbor
+class Neighbor : public InstanceLocatorInit
 {
 public:
     /**
@@ -353,6 +352,39 @@
     void SetRloc16(uint16_t aRloc16) { mRloc16 = aRloc16; }
 
     /**
+     * This method indicates whether or not it is a valid Thread 1.1 neighbor.
+     *
+     * @returns TRUE if it is a valid Thread 1.1 neighbor, FALSE otherwise.
+     *
+     */
+    bool IsThreadVersion1p1(void) const { return mState != kStateInvalid && mVersion == OT_THREAD_VERSION_1_1; }
+
+    /**
+     * This method indicates whether Enhanced Keep-Alive is supported or not.
+     *
+     * @returns TRUE if Enhanced Keep-Alive is supported, FALSE otherwise.
+     *
+     */
+    bool IsEnhancedKeepAliveSupported(void) const
+    {
+        return mState != kStateInvalid && mVersion >= OT_THREAD_VERSION_1_2;
+    }
+
+    /**
+     * This method gets the device MLE version.
+     *
+     */
+    uint8_t GetVersion(void) const { return mVersion; }
+
+    /**
+     * This method sets the device MLE version.
+     *
+     * @param[in]  aVersion  The device MLE version.
+     *
+     */
+    void SetVersion(uint8_t aVersion) { mVersion = aVersion; }
+
+    /**
      * This method gets the number of consecutive link failures.
      *
      * @returns The number of consecutive link failures.
@@ -420,6 +452,15 @@
     void SetTimeSyncEnabled(bool aEnabled) { mTimeSyncEnabled = aEnabled; }
 #endif
 
+protected:
+    /**
+     * This method initializes the `Neighbor` object.
+     *
+     * @param[in] aInstance  A reference to OpenThread instance.
+     *
+     */
+    void Init(Instance &aInstance);
+
 private:
     Mac::ExtAddress mMacAddr;   ///< The IEEE 802.15.4 Extended Address
     TimeMilli       mLastHeard; ///< Time when last heard.
@@ -432,7 +473,7 @@
         } mValid;
         struct
         {
-            uint8_t mChallenge[Mle::ChallengeTlv::kMaxSize]; ///< The challenge value
+            uint8_t mChallenge[Mle::kMaxChallengeSize]; ///< The challenge value
         } mPending;
     } mValidPending;
 
@@ -446,6 +487,7 @@
 #else
     uint8_t mLinkFailures; ///< Consecutive link failure count
 #endif
+    uint8_t         mVersion;  ///< The MLE version
     LinkQualityInfo mLinkInfo; ///< Link quality info (contains average RSS, link margin and link quality)
 };
 
@@ -512,6 +554,14 @@
     };
 
     /**
+     * This method initializes the `Child` object.
+     *
+     * @param[in] aInstance  A reference to OpenThread instance.
+     *
+     */
+    void Init(Instance &aInstance) { Neighbor::Init(aInstance); }
+
+    /**
      * This method clears the child entry.
      *
      */
@@ -526,19 +576,25 @@
     /**
      * This method gets the mesh-local IPv6 address.
      *
-     * @param[in]    aInstance           A reference to the OpenThread instance.
      * @param[out]   aAddress            A reference to an IPv6 address to provide address (if any).
      *
      * @retval       OT_ERROR_NONE       Successfully found the mesh-local address and updated @p aAddress.
      * @retval       OT_ERROR_NOT_FOUND  No mesh-local IPv6 address in the IPv6 address list.
      *
      */
-    otError GetMeshLocalIp6Address(Instance &aInstance, Ip6::Address &aAddress) const;
+    otError GetMeshLocalIp6Address(Ip6::Address &aAddress) const;
+
+    /**
+     * This method returns the Mesh Local Interface Identifier.
+     *
+     * @returns The Mesh Local Interface Identifier.
+     *
+     */
+    const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMeshLocalIid; }
 
     /**
      * This method gets the next IPv6 address in the list.
      *
-     * @param[in]    aInstance           A reference to the OpenThread instance.
      * @param[inout] aIterator           A reference to an IPv6 address iterator.
      * @param[out]   aAddress            A reference to an IPv6 address to provide the next address (if any).
      *
@@ -546,12 +602,11 @@
      * @retval       OT_ERROR_NOT_FOUND  No subsequent IPv6 address exists in the IPv6 address list.
      *
      */
-    otError GetNextIp6Address(Instance &aInstance, Ip6AddressIterator &aIterator, Ip6::Address &aAddress) const;
+    otError GetNextIp6Address(Ip6AddressIterator &aIterator, Ip6::Address &aAddress) const;
 
     /**
      * This method adds an IPv6 address to the list.
      *
-     * @param[in]  aInstance          A reference to the OpenThread instance.
      * @param[in]  aAddress           A reference to IPv6 address to be added.
      *
      * @retval OT_ERROR_NONE          Successfully added the new address.
@@ -560,12 +615,11 @@
      * @retval OT_ERROR_INVALID_ARGS  Address is invalid (it is the Unspecified Address).
      *
      */
-    otError AddIp6Address(Instance &aInstance, const Ip6::Address &aAddress);
+    otError AddIp6Address(const Ip6::Address &aAddress);
 
     /**
      * This method removes an IPv6 address from the list.
      *
-     * @param[in]  aInstance              A reference to the OpenThread instance.
      * @param[in]  aAddress               A reference to IPv6 address to be removed.
      *
      * @retval OT_ERROR_NONE              Successfully removed the address.
@@ -573,19 +627,18 @@
      * @retval OT_ERROR_INVALID_ARGS      Address is invalid (it is the Unspecified Address).
      *
      */
-    otError RemoveIp6Address(Instance &aInstance, const Ip6::Address &aAddress);
+    otError RemoveIp6Address(const Ip6::Address &aAddress);
 
     /**
      * This method indicates whether an IPv6 address is in the list of IPv6 addresses of the child.
      *
-     * @param[in]  aInstance  A reference to the OpenThread instance.
      * @param[in]  aAddress   A reference to IPv6 address.
      *
      * @retval TRUE           The address exists on the list.
      * @retval FALSE          Address was not found in the list.
      *
      */
-    bool HasIp6Address(Instance &aInstance, const Ip6::Address &aAddress) const;
+    bool HasIp6Address(const Ip6::Address &aAddress) const;
 
     /**
      * This method gets the child timeout.
@@ -700,23 +753,23 @@
         kNumIp6Addresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1,
     };
 
-    uint8_t      mNetworkDataVersion;                                   ///< Current Network Data version
-    uint8_t      mMeshLocalIid[Ip6::Address::kInterfaceIdentifierSize]; ///< IPv6 address IID for mesh-local address
-    Ip6::Address mIp6Address[kNumIp6Addresses];                         ///< Registered IPv6 addresses
+    uint8_t                  mNetworkDataVersion;           ///< Current Network Data version
+    Ip6::InterfaceIdentifier mMeshLocalIid;                 ///< IPv6 address IID for mesh-local address
+    Ip6::Address             mIp6Address[kNumIp6Addresses]; ///< Registered IPv6 addresses
 
     uint32_t mTimeout; ///< Child timeout
 
     union
     {
-        uint8_t mRequestTlvs[kMaxRequestTlvs];                 ///< Requested MLE TLVs
-        uint8_t mAttachChallenge[Mle::ChallengeTlv::kMaxSize]; ///< The challenge value
+        uint8_t mRequestTlvs[kMaxRequestTlvs];            ///< Requested MLE TLVs
+        uint8_t mAttachChallenge[Mle::kMaxChallengeSize]; ///< The challenge value
     };
 
 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
     uint16_t mSecondsSinceSupervision; ///< Number of seconds since last supervision of the child.
 #endif
 
-    OT_STATIC_ASSERT(OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS < 8192, "mQueuedMessageCount cannot fit max required!");
+    static_assert(OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS < 8192, "mQueuedMessageCount cannot fit max required!");
 };
 
 /**
@@ -727,6 +780,14 @@
 {
 public:
     /**
+     * This method initializes the `Router` object.
+     *
+     * @param[in] aInstance  A reference to OpenThread instance.
+     *
+     */
+    void Init(Instance &aInstance) { Neighbor::Init(aInstance); }
+
+    /**
      * This method clears the router entry.
      *
      */
diff --git a/src/core/utils/channel_manager.cpp b/src/core/utils/channel_manager.cpp
index e543221..977ee6f 100644
--- a/src/core/utils/channel_manager.cpp
+++ b/src/core/utils/channel_manager.cpp
@@ -48,14 +48,14 @@
 
 ChannelManager::ChannelManager(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , Notifier::Receiver(aInstance, ChannelManager::HandleNotifierEvents)
     , mSupportedChannelMask(0)
     , mFavoredChannelMask(0)
     , mActiveTimestamp(0)
-    , mNotifierCallback(aInstance, &ChannelManager::HandleStateChanged, this)
     , mDelay(kMinimumDelay)
     , mChannel(0)
     , mState(kStateIdle)
-    , mTimer(aInstance, &ChannelManager::HandleTimer, this)
+    , mTimer(aInstance, ChannelManager::HandleTimer, this)
     , mAutoSelectInterval(kDefaultAutoSelectInterval)
     , mAutoSelectEnabled(false)
 {
@@ -77,7 +77,7 @@
 
     mTimer.Start(1 + Random::NonCrypto::GetUint32InRange(0, kRequestStartJitterInterval));
 
-    Get<Notifier>().Signal(OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL);
+    Get<Notifier>().Signal(kEventChannelManagerNewChannelChanged);
 
 exit:
     return;
@@ -102,9 +102,9 @@
     otOperationalDataset dataset;
     otError              error;
 
-    VerifyOrExit(mState == kStateChangeRequested);
+    VerifyOrExit(mState == kStateChangeRequested, OT_NOOP);
 
-    VerifyOrExit(mChannel != Get<Mac::Mac>().GetPanChannel());
+    VerifyOrExit(mChannel != Get<Mac::Mac>().GetPanChannel(), OT_NOOP);
 
     if (Get<MeshCoP::PendingDataset>().Read(dataset) == OT_ERROR_NONE)
     {
@@ -140,7 +140,7 @@
         // situation where a channel change request comes right after the
         // network is formed but before the active dataset is created.
 
-        if (Get<Mle::Mle>().GetRole() != OT_DEVICE_ROLE_DISABLED)
+        if (!Get<Mle::Mle>().IsDisabled())
         {
             mTimer.Start(kPendingDatasetTxRetryInterval);
         }
@@ -204,7 +204,7 @@
     dataset.mDelay                                 = delayInMs;
     dataset.mComponents.mIsDelayPresent            = true;
 
-    error = Get<MeshCoP::PendingDataset>().SendSetRequest(dataset, NULL, 0);
+    error = Get<MeshCoP::PendingDataset>().SendSetRequest(dataset, nullptr, 0);
 
     if (error == OT_ERROR_NONE)
     {
@@ -236,7 +236,7 @@
     {
     case kStateIdle:
         otLogInfoUtil("ChannelManager: Auto-triggered channel select");
-        IgnoreReturnValue(RequestChannelSelect(false));
+        IgnoreError(RequestChannelSelect(false));
         StartAutoSelectTimer();
         break;
 
@@ -252,15 +252,15 @@
     }
 }
 
-void ChannelManager::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aChangedFlags)
+void ChannelManager::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<ChannelManager>().HandleStateChanged(aChangedFlags);
+    static_cast<ChannelManager &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
-void ChannelManager::HandleStateChanged(otChangedFlags aChangedFlags)
+void ChannelManager::HandleNotifierEvents(Events aEvents)
 {
-    VerifyOrExit((aChangedFlags & OT_CHANGED_THREAD_CHANNEL) != 0);
-    VerifyOrExit(mChannel == Get<Mac::Mac>().GetPanChannel());
+    VerifyOrExit(aEvents.Contains(kEventThreadChannelChanged), OT_NOOP);
+    VerifyOrExit(mChannel == Get<Mac::Mac>().GetPanChannel(), OT_NOOP);
 
     mState = kStateIdle;
     StartAutoSelectTimer();
@@ -345,9 +345,9 @@
     otLogInfoUtil("ChannelManager: Request to select channel (skip quality check: %s)",
                   aSkipQualityCheck ? "yes" : "no");
 
-    VerifyOrExit(Get<Mle::Mle>().GetRole() != OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(!Get<Mle::Mle>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
 
-    VerifyOrExit(aSkipQualityCheck || ShouldAttemptChannelChange());
+    VerifyOrExit(aSkipQualityCheck || ShouldAttemptChannelChange(), OT_NOOP);
 
     SuccessOrExit(error = FindBetterChannel(newChannel, newOccupancy));
 
@@ -389,7 +389,7 @@
 
 void ChannelManager::StartAutoSelectTimer(void)
 {
-    VerifyOrExit(mState == kStateIdle);
+    VerifyOrExit(mState == kStateIdle, OT_NOOP);
 
     if (mAutoSelectEnabled)
     {
@@ -409,7 +409,7 @@
     if (aEnabled != mAutoSelectEnabled)
     {
         mAutoSelectEnabled = aEnabled;
-        IgnoreReturnValue(RequestChannelSelect(false));
+        IgnoreError(RequestChannelSelect(false));
         StartAutoSelectTimer();
     }
 }
diff --git a/src/core/utils/channel_manager.hpp b/src/core/utils/channel_manager.hpp
index 534d485..4d65a84 100644
--- a/src/core/utils/channel_manager.hpp
+++ b/src/core/utils/channel_manager.hpp
@@ -39,6 +39,7 @@
 #include <openthread/platform/radio.h>
 
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 #include "common/notifier.hpp"
 #include "common/timer.hpp"
 #include "mac/mac.hpp"
@@ -63,7 +64,7 @@
  * This class implements the Channel Manager.
  *
  */
-class ChannelManager : public InstanceLocator
+class ChannelManager : public InstanceLocator, public Notifier::Receiver, private NonCopyable
 {
 public:
     enum
@@ -91,7 +92,7 @@
      *
      * A subsequent call to this method will cancel an ongoing previously requested channel change.
      *
-     * If the requested channel changes, it will trigger a `Notifier` event `OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL`.
+     * If the requested channel changes, it will trigger a `Notifier` event `kEventChannelManagerNewChannelChanged`.
      *
      * @param[in] aChannel             The new channel for the Thread network.
      *
@@ -271,8 +272,8 @@
 
     static void HandleTimer(Timer &aTimer);
     void        HandleTimer(void);
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aChangedFlags);
-    void        HandleStateChanged(otChangedFlags aChangedFlags);
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
     void        PreparePendingDataset(void);
     void        StartAutoSelectTimer(void);
 
@@ -281,21 +282,20 @@
     bool    ShouldAttemptChannelChange(void);
 #endif
 
-    Mac::ChannelMask   mSupportedChannelMask;
-    Mac::ChannelMask   mFavoredChannelMask;
-    uint64_t           mActiveTimestamp;
-    Notifier::Callback mNotifierCallback;
-    uint16_t           mDelay;
-    uint8_t            mChannel;
-    State              mState;
-    TimerMilli         mTimer;
-    uint32_t           mAutoSelectInterval;
-    bool               mAutoSelectEnabled;
+    Mac::ChannelMask mSupportedChannelMask;
+    Mac::ChannelMask mFavoredChannelMask;
+    uint64_t         mActiveTimestamp;
+    uint16_t         mDelay;
+    uint8_t          mChannel;
+    State            mState;
+    TimerMilli       mTimer;
+    uint32_t         mAutoSelectInterval;
+    bool             mAutoSelectEnabled;
 };
 
 #else // OPENTHREAD_FTD
 
-class ChannelManager
+class ChannelManager : private NonCopyable
 {
 public:
     explicit ChannelManager(Instance &) {}
diff --git a/src/core/utils/channel_monitor.cpp b/src/core/utils/channel_monitor.cpp
index d769c02..901a6e6 100644
--- a/src/core/utils/channel_monitor.cpp
+++ b/src/core/utils/channel_monitor.cpp
@@ -62,7 +62,7 @@
     : InstanceLocator(aInstance)
     , mChannelMaskIndex(0)
     , mSampleCount(0)
-    , mTimer(aInstance, &ChannelMonitor::HandleTimer, this)
+    , mTimer(aInstance, ChannelMonitor::HandleTimer, this)
 {
     memset(mChannelOccupancy, 0, sizeof(mChannelOccupancy));
 }
@@ -105,7 +105,7 @@
 {
     uint16_t occupancy = 0;
 
-    VerifyOrExit((Radio::kChannelMin <= aChannel) && (aChannel <= Radio::kChannelMax));
+    VerifyOrExit((Radio::kChannelMin <= aChannel) && (aChannel <= Radio::kChannelMax), OT_NOOP);
     occupancy = mChannelOccupancy[aChannel - Radio::kChannelMin];
 
 exit:
@@ -119,7 +119,8 @@
 
 void ChannelMonitor::HandleTimer(void)
 {
-    Get<Mac::Mac>().EnergyScan(mScanChannelMasks[mChannelMaskIndex], 0, &ChannelMonitor::HandleEnergyScanResult, this);
+    IgnoreError(Get<Mac::Mac>().EnergyScan(mScanChannelMasks[mChannelMaskIndex], 0,
+                                           &ChannelMonitor::HandleEnergyScanResult, this));
 
     mTimer.StartAt(mTimer.GetFireTime(), Random::NonCrypto::AddJitter(kTimerInterval, kMaxJitterInterval));
 }
@@ -131,7 +132,7 @@
 
 void ChannelMonitor::HandleEnergyScanResult(Mac::EnergyScanResult *aResult)
 {
-    if (aResult == NULL)
+    if (aResult == nullptr)
     {
         if (mChannelMaskIndex == kNumChannelMasks - 1)
         {
@@ -151,7 +152,7 @@
         uint32_t newValue     = 0;
         uint32_t weight;
 
-        assert(channelIndex < kNumChannels);
+        OT_ASSERT(channelIndex < kNumChannels);
 
         otLogDebgUtil("ChannelMonitor: channel: %d, rssi:%d", aResult->mChannel, aResult->mMaxRssi);
 
@@ -194,7 +195,7 @@
 
     for (size_t i = 0; i < kNumChannels; i++)
     {
-        logString.Append("%02x ", mChannelOccupancy[i] >> 8);
+        IgnoreError(logString.Append("%02x ", mChannelOccupancy[i] >> 8));
     }
 
     otLogInfoUtil("ChannelMonitor: %u [%s]", mSampleCount, logString.AsCString());
diff --git a/src/core/utils/channel_monitor.hpp b/src/core/utils/channel_monitor.hpp
index 750c2d4..26899be 100644
--- a/src/core/utils/channel_monitor.hpp
+++ b/src/core/utils/channel_monitor.hpp
@@ -39,6 +39,7 @@
 #include <openthread/platform/radio.h>
 
 #include "common/locator.hpp"
+#include "common/non_copyable.hpp"
 #include "common/timer.hpp"
 #include "mac/mac.hpp"
 #include "radio/radio.hpp"
@@ -70,7 +71,7 @@
  * window (referred to as "channel occupancy").
  *
  */
-class ChannelMonitor : public InstanceLocator
+class ChannelMonitor : public InstanceLocator, private NonCopyable
 {
 public:
     enum
diff --git a/src/core/utils/child_supervision.cpp b/src/core/utils/child_supervision.cpp
index 5800a02..16c35d9 100644
--- a/src/core/utils/child_supervision.cpp
+++ b/src/core/utils/child_supervision.cpp
@@ -49,9 +49,9 @@
 
 ChildSupervisor::ChildSupervisor(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , Notifier::Receiver(aInstance, ChildSupervisor::HandleNotifierEvents)
     , mSupervisionInterval(kDefaultSupervisionInterval)
-    , mTimer(aInstance, &ChildSupervisor::HandleTimer, this)
-    , mNotifierCallback(aInstance, &ChildSupervisor::HandleStateChanged, this)
+    , mTimer(aInstance, ChildSupervisor::HandleTimer, this)
 {
 }
 
@@ -63,10 +63,10 @@
 
 Child *ChildSupervisor::GetDestination(const Message &aMessage) const
 {
-    Child *  child = NULL;
+    Child *  child = nullptr;
     uint16_t childIndex;
 
-    VerifyOrExit(aMessage.GetType() == Message::kTypeSupervision);
+    VerifyOrExit(aMessage.GetType() == Message::kTypeSupervision, OT_NOOP);
 
     aMessage.Read(0, sizeof(childIndex), &childIndex);
     child = Get<ChildTable>().GetChildAtIndex(childIndex);
@@ -77,13 +77,13 @@
 
 void ChildSupervisor::SendMessage(Child &aChild)
 {
-    Message *message = NULL;
+    Message *message = nullptr;
     uint16_t childIndex;
 
-    VerifyOrExit(aChild.GetIndirectMessageCount() == 0);
+    VerifyOrExit(aChild.GetIndirectMessageCount() == 0, OT_NOOP);
 
     message = Get<MessagePool>().New(Message::kTypeSupervision, sizeof(uint8_t));
-    VerifyOrExit(message != NULL);
+    VerifyOrExit(message != nullptr, OT_NOOP);
 
     // Supervision message is an empty payload 15.4 data frame.
     // The child index is stored here in the message content to allow
@@ -94,13 +94,13 @@
     SuccessOrExit(message->Append(&childIndex, sizeof(childIndex)));
 
     SuccessOrExit(Get<ThreadNetif>().SendMessage(*message));
-    message = NULL;
+    message = nullptr;
 
     otLogInfoUtil("Sending supervision message to child 0x%04x", aChild.GetRloc16());
 
 exit:
 
-    if (message != NULL)
+    if (message != nullptr)
     {
         message->Free();
     }
@@ -118,12 +118,10 @@
 
 void ChildSupervisor::HandleTimer(void)
 {
-    VerifyOrExit(mSupervisionInterval != 0);
+    VerifyOrExit(mSupervisionInterval != 0, OT_NOOP);
 
-    for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValid); !iter.IsDone(); iter++)
+    for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
     {
-        Child &child = *iter.GetChild();
-
         child.IncrementSecondsSinceLastSupervision();
 
         if ((child.GetSecondsSinceLastSupervision() >= mSupervisionInterval) && !child.IsRxOnWhenIdle())
@@ -146,7 +144,7 @@
     // zero, Thread MLE operation is enabled, and there is at least one
     // "valid" child in the child table.
 
-    shouldRun = ((mSupervisionInterval != 0) && (Get<Mle::MleRouter>().GetRole() != OT_DEVICE_ROLE_DISABLED) &&
+    shouldRun = ((mSupervisionInterval != 0) && !Get<Mle::MleRouter>().IsDisabled() &&
                  Get<ChildTable>().HasChildren(Child::kInStateValid));
 
     if (shouldRun && !mTimer.IsRunning())
@@ -162,14 +160,14 @@
     }
 }
 
-void ChildSupervisor::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags)
+void ChildSupervisor::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<ChildSupervisor>().HandleStateChanged(aFlags);
+    static_cast<ChildSupervisor &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
-void ChildSupervisor::HandleStateChanged(otChangedFlags aFlags)
+void ChildSupervisor::HandleNotifierEvents(Events aEvents)
 {
-    if ((aFlags & (OT_CHANGED_THREAD_ROLE | OT_CHANGED_THREAD_CHILD_ADDED | OT_CHANGED_THREAD_CHILD_REMOVED)) != 0)
+    if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadChildAdded | kEventThreadChildRemoved))
     {
         CheckState();
     }
@@ -180,7 +178,7 @@
 SupervisionListener::SupervisionListener(Instance &aInstance)
     : InstanceLocator(aInstance)
     , mTimeout(0)
-    , mTimer(aInstance, &SupervisionListener::HandleTimer, this)
+    , mTimer(aInstance, SupervisionListener::HandleTimer, this)
 {
     SetTimeout(kDefaultTimeout);
 }
@@ -208,8 +206,9 @@
 {
     // If listener is enabled and device is a child and it received a secure frame from its parent, restart the timer.
 
-    VerifyOrExit(mTimer.IsRunning() && aIsSecure && (Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_CHILD) &&
-                 (Get<Mle::MleRouter>().GetNeighbor(aSourceAddress) == &Get<Mle::MleRouter>().GetParent()));
+    VerifyOrExit(mTimer.IsRunning() && aIsSecure && Get<Mle::MleRouter>().IsChild() &&
+                     (Get<Mle::MleRouter>().GetNeighbor(aSourceAddress) == &Get<Mle::MleRouter>().GetParent()),
+                 OT_NOOP);
 
     RestartTimer();
 
@@ -219,8 +218,7 @@
 
 void SupervisionListener::RestartTimer(void)
 {
-    if ((mTimeout != 0) && (Get<Mle::MleRouter>().GetRole() != OT_DEVICE_ROLE_DISABLED) &&
-        !Get<MeshForwarder>().GetRxOnWhenIdle())
+    if ((mTimeout != 0) && !Get<Mle::MleRouter>().IsDisabled() && !Get<MeshForwarder>().GetRxOnWhenIdle())
     {
         mTimer.Start(Time::SecToMsec(mTimeout));
     }
@@ -237,11 +235,11 @@
 
 void SupervisionListener::HandleTimer(void)
 {
-    VerifyOrExit((Get<Mle::MleRouter>().GetRole() == OT_DEVICE_ROLE_CHILD) && !Get<MeshForwarder>().GetRxOnWhenIdle());
+    VerifyOrExit(Get<Mle::MleRouter>().IsChild() && !Get<MeshForwarder>().GetRxOnWhenIdle(), OT_NOOP);
 
     otLogWarnUtil("Supervision timeout. No frame from parent in %d sec", mTimeout);
 
-    Get<Mle::MleRouter>().SendChildUpdateRequest();
+    IgnoreError(Get<Mle::MleRouter>().SendChildUpdateRequest());
 
 exit:
     RestartTimer();
diff --git a/src/core/utils/child_supervision.hpp b/src/core/utils/child_supervision.hpp
index 9c6666b..619e715 100644
--- a/src/core/utils/child_supervision.hpp
+++ b/src/core/utils/child_supervision.hpp
@@ -88,7 +88,7 @@
  * This class implements a child supervisor.
  *
  */
-class ChildSupervisor : public InstanceLocator
+class ChildSupervisor : public InstanceLocator, public Notifier::Receiver
 {
 public:
     /**
@@ -135,7 +135,8 @@
      *
      * @param[in] aMessage The message for which to get the destination.
      *
-     * @returns  A pointer to the destination child of the message, or NULL if @p aMessage is not of supervision type.
+     * @returns  A pointer to the destination child of the message, or nullptr if @p aMessage is not of supervision
+     * type.
      *
      */
     Child *GetDestination(const Message &aMessage) const;
@@ -160,12 +161,11 @@
     void        CheckState(void);
     static void HandleTimer(Timer &aTimer);
     void        HandleTimer(void);
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags);
-    void        HandleStateChanged(otChangedFlags aFlags);
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
 
-    uint16_t           mSupervisionInterval;
-    TimerMilli         mTimer;
-    Notifier::Callback mNotifierCallback;
+    uint16_t   mSupervisionInterval;
+    TimerMilli mTimer;
 };
 
 #else // #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE && OPENTHREAD_FTD
@@ -178,7 +178,7 @@
     void     Stop(void) {}
     void     SetSupervisionInterval(uint16_t) {}
     uint16_t GetSupervisionInterval(void) const { return 0; }
-    Child *  GetDestination(const Message &) const { return NULL; }
+    Child *  GetDestination(const Message &) const { return nullptr; }
     void     UpdateOnSend(Child &) {}
 };
 
diff --git a/src/core/utils/flash.cpp b/src/core/utils/flash.cpp
new file mode 100644
index 0000000..aa53371
--- /dev/null
+++ b/src/core/utils/flash.cpp
@@ -0,0 +1,312 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "flash.hpp"
+
+#include <stdio.h>
+
+#include <openthread/platform/flash.h>
+
+#include "common/code_utils.hpp"
+#include "common/instance.hpp"
+
+#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+
+namespace ot {
+
+const uint32_t ot::Flash::sSwapActive;
+const uint32_t ot::Flash::sSwapInactive;
+
+void Flash::Init(void)
+{
+    RecordHeader record;
+
+    otPlatFlashInit(&GetInstance());
+
+    mSwapSize = otPlatFlashGetSwapSize(&GetInstance());
+
+    for (mSwapIndex = 0;; mSwapIndex++)
+    {
+        uint32_t swapMarker;
+
+        if (mSwapIndex >= 2)
+        {
+            Wipe();
+            ExitNow();
+        }
+
+        otPlatFlashRead(&GetInstance(), mSwapIndex, 0, &swapMarker, sizeof(swapMarker));
+
+        if (swapMarker == sSwapActive)
+        {
+            break;
+        }
+    }
+
+    for (mSwapUsed = kSwapMarkerSize; mSwapUsed <= mSwapSize - sizeof(record); mSwapUsed += record.GetSize())
+    {
+        otPlatFlashRead(&GetInstance(), mSwapIndex, mSwapUsed, &record, sizeof(record));
+        if (!record.IsAddBeginSet())
+        {
+            break;
+        }
+
+        if (!record.IsAddCompleteSet())
+        {
+            break;
+        }
+    }
+
+    SanitizeFreeSpace();
+
+exit:
+    return;
+}
+
+void Flash::SanitizeFreeSpace(void)
+{
+    uint32_t temp;
+    bool     sanitizeNeeded = false;
+
+    if (mSwapUsed & 3)
+    {
+        ExitNow(sanitizeNeeded = true);
+    }
+
+    for (uint32_t offset = mSwapUsed; offset < mSwapSize; offset += sizeof(temp))
+    {
+        otPlatFlashRead(&GetInstance(), mSwapIndex, offset, &temp, sizeof(temp));
+        if (temp != ~0U)
+        {
+            ExitNow(sanitizeNeeded = true);
+        }
+    }
+
+exit:
+    if (sanitizeNeeded)
+    {
+        Swap();
+    }
+}
+
+otError Flash::Get(uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) const
+{
+    otError      error       = OT_ERROR_NOT_FOUND;
+    uint16_t     valueLength = 0;
+    int          index       = 0; // This must be initalized to 0. See [Note] in Delete().
+    uint32_t     offset;
+    RecordHeader record;
+
+    for (offset = kSwapMarkerSize; offset < mSwapUsed; offset += record.GetSize())
+    {
+        otPlatFlashRead(&GetInstance(), mSwapIndex, offset, &record, sizeof(record));
+
+        if ((record.GetKey() != aKey) || !record.IsValid())
+        {
+            continue;
+        }
+
+        if (record.IsFirst())
+        {
+            index = 0;
+        }
+
+        if (index == aIndex)
+        {
+            if (aValue && aValueLength)
+            {
+                uint16_t readLength = *aValueLength;
+
+                if (readLength > record.GetLength())
+                {
+                    readLength = record.GetLength();
+                }
+
+                otPlatFlashRead(&GetInstance(), mSwapIndex, offset + sizeof(record), aValue, readLength);
+            }
+
+            valueLength = record.GetLength();
+            error       = OT_ERROR_NONE;
+        }
+
+        index++;
+    }
+
+    if (aValueLength)
+    {
+        *aValueLength = valueLength;
+    }
+
+    return error;
+}
+
+otError Flash::Set(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    return Add(aKey, true, aValue, aValueLength);
+}
+
+otError Flash::Add(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    bool first = (Get(aKey, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND);
+
+    return Add(aKey, first, aValue, aValueLength);
+}
+
+otError Flash::Add(uint16_t aKey, bool aFirst, const uint8_t *aValue, uint16_t aValueLength)
+{
+    otError error = OT_ERROR_NONE;
+    Record  record;
+
+    record.Init(aKey, aFirst);
+    record.SetData(aValue, aValueLength);
+
+    OT_ASSERT((mSwapSize - record.GetSize()) >= kSwapMarkerSize);
+
+    if ((mSwapSize - record.GetSize()) < mSwapUsed)
+    {
+        Swap();
+        VerifyOrExit((mSwapSize - record.GetSize()) >= mSwapUsed, error = OT_ERROR_NO_BUFS);
+    }
+
+    otPlatFlashWrite(&GetInstance(), mSwapIndex, mSwapUsed, &record, record.GetSize());
+
+    record.SetAddCompleteFlag();
+    otPlatFlashWrite(&GetInstance(), mSwapIndex, mSwapUsed, &record, sizeof(RecordHeader));
+
+    mSwapUsed += record.GetSize();
+
+exit:
+    return error;
+}
+
+bool Flash::DoesValidRecordExist(uint32_t aOffset, uint16_t aKey) const
+{
+    RecordHeader record;
+    bool         rval = false;
+
+    for (; aOffset < mSwapUsed; aOffset += record.GetSize())
+    {
+        otPlatFlashRead(&GetInstance(), mSwapIndex, aOffset, &record, sizeof(record));
+
+        if (record.IsValid() && record.IsFirst() && (record.GetKey() == aKey))
+        {
+            ExitNow(rval = true);
+        }
+    }
+
+exit:
+    return rval;
+}
+
+void Flash::Swap(void)
+{
+    uint8_t  dstIndex  = !mSwapIndex;
+    uint32_t dstOffset = kSwapMarkerSize;
+    Record   record;
+
+    otPlatFlashErase(&GetInstance(), dstIndex);
+
+    for (uint32_t srcOffset = kSwapMarkerSize; srcOffset < mSwapUsed; srcOffset += record.GetSize())
+    {
+        otPlatFlashRead(&GetInstance(), mSwapIndex, srcOffset, &record, sizeof(RecordHeader));
+
+        VerifyOrExit(record.IsAddBeginSet(), OT_NOOP);
+
+        if (!record.IsValid() || DoesValidRecordExist(srcOffset + record.GetSize(), record.GetKey()))
+        {
+            continue;
+        }
+
+        otPlatFlashRead(&GetInstance(), mSwapIndex, srcOffset, &record, record.GetSize());
+        otPlatFlashWrite(&GetInstance(), dstIndex, dstOffset, &record, record.GetSize());
+        dstOffset += record.GetSize();
+    }
+
+exit:
+    otPlatFlashWrite(&GetInstance(), dstIndex, 0, &sSwapActive, sizeof(sSwapActive));
+    otPlatFlashWrite(&GetInstance(), mSwapIndex, 0, &sSwapInactive, sizeof(sSwapInactive));
+
+    mSwapIndex = dstIndex;
+    mSwapUsed  = dstOffset;
+}
+
+otError Flash::Delete(uint16_t aKey, int aIndex)
+{
+    otError      error = OT_ERROR_NOT_FOUND;
+    int          index = 0; // This must be initalized to 0. See [Note] below.
+    RecordHeader record;
+
+    for (uint32_t offset = kSwapMarkerSize; offset < mSwapUsed; offset += record.GetSize())
+    {
+        otPlatFlashRead(&GetInstance(), mSwapIndex, offset, &record, sizeof(record));
+
+        if ((record.GetKey() != aKey) || !record.IsValid())
+        {
+            continue;
+        }
+
+        if (record.IsFirst())
+        {
+            index = 0;
+        }
+
+        if ((aIndex == index) || (aIndex == -1))
+        {
+            record.SetDeleted();
+            otPlatFlashWrite(&GetInstance(), mSwapIndex, offset, &record, sizeof(record));
+            error = OT_ERROR_NONE;
+        }
+
+        /* [Note] If the operation gets interrupted here and aIndex is 0, the next record (index == 1) will never get
+         * marked as first. However, this is not actually an issue because all the methods that iterate over the
+         * settings area initialize the index to 0, without expecting any record to be effectively marked as first. */
+
+        if ((index == 1) && (aIndex == 0))
+        {
+            record.SetFirst();
+            otPlatFlashWrite(&GetInstance(), mSwapIndex, offset, &record, sizeof(record));
+        }
+
+        index++;
+    }
+
+    return error;
+}
+
+void Flash::Wipe(void)
+{
+    otPlatFlashErase(&GetInstance(), 0);
+    otPlatFlashWrite(&GetInstance(), 0, 0, &sSwapActive, sizeof(sSwapActive));
+
+    mSwapIndex = 0;
+    mSwapUsed  = sizeof(sSwapActive);
+}
+
+} // namespace ot
+
+#endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
diff --git a/src/core/utils/flash.hpp b/src/core/utils/flash.hpp
new file mode 100644
index 0000000..3ff665b
--- /dev/null
+++ b/src/core/utils/flash.hpp
@@ -0,0 +1,235 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLASH_HPP_
+#define FLASH_HPP_
+
+#include "openthread-core-config.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include <openthread/error.h>
+#include <openthread/platform/toolchain.h>
+
+#include "common/debug.hpp"
+#include "common/locator.hpp"
+
+namespace ot {
+
+/**
+ * This class implements the flash storage driver.
+ *
+ */
+class Flash : public InstanceLocator
+{
+public:
+    /**
+     * Constructor.
+     *
+     */
+    Flash(Instance &aInstance)
+        : InstanceLocator(aInstance)
+    {
+    }
+
+    /**
+     * This method initializes the flash storage driver.
+     *
+     */
+    void Init(void);
+
+    /**
+     * This method fetches the value identified by @p aKey.
+     *
+     * @param[in]     aKey          The key associated with the requested value.
+     * @param[in]     aIndex        The index of the specific item to get.
+     * @param[out]    aValue        A pointer to where the value of the setting should be written.
+     *                              May be nullptr if just testing for the presence or length of a key.
+     * @param[inout]  aValueLength  A pointer to the length of the value.
+     *                              When called, this should point to an integer containing the maximum bytes that
+     *                              can be written to @p aValue.
+     *                              At return, the actual length of the setting is written.
+     *                              May be nullptr if performing a presence check.
+     *
+     * @retval OT_ERROR_NONE        The value was fetched successfully.
+     * @retval OT_ERROR_NOT_FOUND   The key was not found.
+     *
+     */
+    otError Get(uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) const;
+
+    /**
+     * This method sets or replaces the value identified by @p aKey.
+     *
+     * If there was more than one value previously associated with @p aKey, then they are all deleted and replaced with
+     * this single entry.
+     *
+     * @param[in]  aKey          The key associated with the value.
+     * @param[in]  aValue        A pointer to where the new value of the setting should be read from.
+     *                           MUST NOT be nullptr if @p aValueLength is non-zero.
+     * @param[in]  aValueLength  The length of the data pointed to by @p aValue. May be zero.
+     *
+     * @retval OT_ERROR_NONE     The value was changed.
+     * @retval OT_ERROR_NO_BUFS  Not enough space to store the value.
+     *
+     */
+    otError Set(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
+
+    /**
+     * This method adds a value to @p aKey.
+     *
+     * @param[in]  aKey          The key associated with the value.
+     * @param[in]  aValue        A pointer to where the new value of the setting should be read from.
+     *                           MUST NOT be nullptr if @p aValueLength is non-zero.
+     * @param[in]  aValueLength  The length of the data pointed to by @p aValue. May be zero.
+     *
+     * @retval OT_ERROR_NONE     The value was added.
+     * @retval OT_ERROR_NO_BUFS  Not enough space to store the value.
+     *
+     */
+    otError Add(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
+
+    /**
+     * This method removes a value from @p aKey.
+     *
+     *
+     * @param[in] aKey    The key associated with the value.
+     * @param[in] aIndex  The index of the value to be removed.
+     *                    If set to -1, all values for @p aKey will be removed.
+     *
+     * @retval OT_ERROR_NONE       The given key and index was found and removed successfully.
+     * @retval OT_ERROR_NOT_FOUND  The given key or index was not found.
+     *
+     */
+    otError Delete(uint16_t aKey, int aIndex);
+
+    /**
+     * This method removes all values.
+     *
+     */
+    void Wipe(void);
+
+private:
+    enum
+    {
+        kSwapMarkerSize = 4, // in bytes
+    };
+
+    static const uint32_t sSwapActive   = 0xbe5cc5ee;
+    static const uint32_t sSwapInactive = 0xbe5cc5ec;
+
+    OT_TOOL_PACKED_BEGIN
+    class RecordHeader
+    {
+    public:
+        void Init(uint16_t aKey, bool aFirst)
+        {
+            mKey   = aKey;
+            mFlags = kFlagsInit & ~kFlagAddBegin;
+
+            if (aFirst)
+            {
+                mFlags &= ~kFlagFirst;
+            }
+
+            mLength   = 0;
+            mReserved = 0xffff;
+        };
+
+        uint16_t GetKey(void) const { return mKey; }
+        void     SetKey(uint16_t aKey) { mKey = aKey; }
+
+        uint16_t GetLength(void) const { return mLength; }
+        void     SetLength(uint16_t aLength) { mLength = aLength; }
+
+        uint16_t GetSize(void) const { return sizeof(*this) + ((mLength + 3) & 0xfffc); }
+
+        bool IsValid(void) const { return ((mFlags & (kFlagAddComplete | kFlagDelete)) == kFlagDelete); }
+
+        bool IsAddBeginSet(void) const { return (mFlags & kFlagAddBegin) == 0; }
+        void SetAddBeginFlag(void) { mFlags &= ~kFlagAddBegin; }
+
+        bool IsAddCompleteSet(void) const { return (mFlags & kFlagAddComplete) == 0; }
+        void SetAddCompleteFlag(void) { mFlags &= ~kFlagAddComplete; }
+
+        bool IsDeleted(void) const { return (mFlags & kFlagDelete) == 0; }
+        void SetDeleted(void) { mFlags &= ~kFlagDelete; }
+
+        bool IsFirst(void) const { return (mFlags & kFlagFirst) == 0; }
+        void SetFirst(void) { mFlags &= ~kFlagFirst; }
+
+    private:
+        enum
+        {
+            kFlagsInit       = 0xffff, ///< Flags initialize to all-ones.
+            kFlagAddBegin    = 1 << 0, ///< 0 indicates record write has started, 1 otherwise.
+            kFlagAddComplete = 1 << 1, ///< 0 indicates record write has completed, 1 otherwise.
+            kFlagDelete      = 1 << 2, ///< 0 indicates record was deleted, 1 otherwise.
+            kFlagFirst       = 1 << 3, ///< 0 indicates first record for key, 1 otherwise.
+        };
+
+        uint16_t mKey;
+        uint16_t mFlags;
+        uint16_t mLength;
+        uint16_t mReserved;
+    } OT_TOOL_PACKED_END;
+
+    OT_TOOL_PACKED_BEGIN
+    class Record : public RecordHeader
+    {
+    public:
+        const uint8_t *GetData(void) const { return mData; }
+        void           SetData(const uint8_t *aData, uint16_t aDataLength)
+        {
+            OT_ASSERT(aDataLength <= kMaxDataSize);
+            memcpy(mData, aData, aDataLength);
+            SetLength(aDataLength);
+        }
+
+    private:
+        enum
+        {
+            kMaxDataSize = 255,
+        };
+
+        uint8_t mData[kMaxDataSize];
+    } OT_TOOL_PACKED_END;
+
+    otError Add(uint16_t aKey, bool aFirst, const uint8_t *aValue, uint16_t aValueLength);
+    bool    DoesValidRecordExist(uint32_t aOffset, uint16_t aKey) const;
+    void    SanitizeFreeSpace(void);
+    void    Swap(void);
+
+    uint32_t mSwapSize;
+    uint32_t mSwapUsed;
+    uint8_t  mSwapIndex;
+};
+
+} // namespace ot
+
+#endif // FLASH_HPP_
diff --git a/src/core/utils/heap.cpp b/src/core/utils/heap.cpp
index e3bd201..36b13d8 100644
--- a/src/core/utils/heap.cpp
+++ b/src/core/utils/heap.cpp
@@ -61,12 +61,12 @@
 
 void *Heap::CAlloc(size_t aCount, size_t aSize)
 {
-    void *   ret  = NULL;
-    Block *  prev = NULL;
-    Block *  curr = NULL;
+    void *   ret  = nullptr;
+    Block *  prev = nullptr;
+    Block *  curr = nullptr;
     uint16_t size = static_cast<uint16_t>(aCount * aSize);
 
-    VerifyOrExit(size);
+    VerifyOrExit(size, OT_NOOP);
 
     size += kAlignSize - 1 - kBlockRemainderSize;
     size &= ~(kAlignSize - 1);
@@ -81,7 +81,7 @@
         curr = &BlockNext(*curr);
     }
 
-    VerifyOrExit(curr->IsFree());
+    VerifyOrExit(curr->IsFree(), OT_NOOP);
 
     prev->SetNext(curr->GetNext());
 
@@ -144,7 +144,7 @@
 
 void Heap::Free(void *aPointer)
 {
-    if (aPointer == NULL)
+    if (aPointer == nullptr)
     {
         return;
     }
diff --git a/src/core/utils/heap.hpp b/src/core/utils/heap.hpp
index 41f8edb..60f2244 100644
--- a/src/core/utils/heap.hpp
+++ b/src/core/utils/heap.hpp
@@ -40,7 +40,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "utils/static_assert.hpp"
+#include "common/non_copyable.hpp"
 
 namespace ot {
 namespace Utils {
@@ -93,7 +93,8 @@
      */
     uint16_t GetNext(void) const
     {
-        return *reinterpret_cast<const uint16_t *>(reinterpret_cast<const uint8_t *>(this) + sizeof(mSize) + mSize);
+        return *reinterpret_cast<const uint16_t *>(
+            reinterpret_cast<const void *>(reinterpret_cast<const uint8_t *>(this) + sizeof(mSize) + mSize));
     }
 
     /**
@@ -106,7 +107,8 @@
      */
     void SetNext(uint16_t aNext)
     {
-        *reinterpret_cast<uint16_t *>(reinterpret_cast<uint8_t *>(this) + sizeof(mSize) + mSize) = aNext;
+        *reinterpret_cast<uint16_t *>(
+            reinterpret_cast<void *>(reinterpret_cast<uint8_t *>(this) + sizeof(mSize) + mSize)) = aNext;
     }
 
     /**
@@ -173,7 +175,7 @@
  *     +--------------------------------------------------------------------------+
  *
  */
-class Heap
+class Heap : private NonCopyable
 {
 public:
     /**
@@ -190,7 +192,7 @@
      *
      * @returns A pointer to the allocated memory.
      *
-     * @retval  NULL    Indicates not enough memory.
+     * @retval  nullptr    Indicates not enough memory.
      *
      */
     void *CAlloc(size_t aCount, size_t aSize);
@@ -243,7 +245,7 @@
         kGuardBlockOffset   = kMemorySize - sizeof(uint16_t),                     ///< Offset of the guard block.
     };
 
-    OT_STATIC_ASSERT(kMemorySize % kAlignSize == 0, "The heap memory size is not aligned to kAlignSize!");
+    static_assert(kMemorySize % kAlignSize == 0, "The heap memory size is not aligned to kAlignSize!");
 
     /**
      * This method returns the block at offset @p aOffset.
diff --git a/src/core/utils/jam_detector.cpp b/src/core/utils/jam_detector.cpp
index 7b31619..2d2064f 100644
--- a/src/core/utils/jam_detector.cpp
+++ b/src/core/utils/jam_detector.cpp
@@ -47,10 +47,10 @@
 
 JamDetector::JamDetector(Instance &aInstance)
     : InstanceLocator(aInstance)
-    , mHandler(NULL)
-    , mContext(NULL)
-    , mNotifierCallback(aInstance, HandleStateChanged, this)
-    , mTimer(aInstance, &JamDetector::HandleTimer, this)
+    , Notifier::Receiver(aInstance, JamDetector::HandleNotifierEvents)
+    , mHandler(nullptr)
+    , mContext(nullptr)
+    , mTimer(aInstance, JamDetector::HandleTimer, this)
     , mHistoryBitmap(0)
     , mCurSecondStartTime(0)
     , mSampleInterval(0)
@@ -68,7 +68,7 @@
     otError error = OT_ERROR_NONE;
 
     VerifyOrExit(!mEnabled, error = OT_ERROR_ALREADY);
-    VerifyOrExit(aHandler != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aHandler != nullptr, error = OT_ERROR_INVALID_ARGS);
 
     mHandler = aHandler;
     mContext = aContext;
@@ -101,18 +101,18 @@
 
 void JamDetector::CheckState(void)
 {
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     switch (Get<Mle::MleRouter>().GetRole())
     {
-    case OT_DEVICE_ROLE_DISABLED:
-        VerifyOrExit(mTimer.IsRunning());
+    case Mle::kRoleDisabled:
+        VerifyOrExit(mTimer.IsRunning(), OT_NOOP);
         mTimer.Stop();
         SetJamState(false);
         break;
 
     default:
-        VerifyOrExit(!mTimer.IsRunning());
+        VerifyOrExit(!mTimer.IsRunning(), OT_NOOP);
         mCurSecondStartTime   = TimerMilli::GetNow();
         mAlwaysAboveThreshold = true;
         mHistoryBitmap        = 0;
@@ -170,7 +170,7 @@
     int8_t rssi;
     bool   didExceedThreshold = true;
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     rssi = Get<Radio>().GetRssi();
 
@@ -271,14 +271,14 @@
     }
 }
 
-void JamDetector::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags)
+void JamDetector::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<JamDetector>().HandleStateChanged(aFlags);
+    static_cast<JamDetector &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
-void JamDetector::HandleStateChanged(otChangedFlags aFlags)
+void JamDetector::HandleNotifierEvents(Events aEvents)
 {
-    if (aFlags & OT_CHANGED_THREAD_ROLE)
+    if (aEvents.Contains(kEventThreadRoleChanged))
     {
         CheckState();
     }
diff --git a/src/core/utils/jam_detector.hpp b/src/core/utils/jam_detector.hpp
index a0ce15d..5162cea 100644
--- a/src/core/utils/jam_detector.hpp
+++ b/src/core/utils/jam_detector.hpp
@@ -48,7 +48,7 @@
 
 namespace Utils {
 
-class JamDetector : public InstanceLocator
+class JamDetector : public InstanceLocator, public Notifier::Receiver
 {
 public:
     /**
@@ -190,22 +190,21 @@
     void        HandleTimer(void);
     void        UpdateHistory(bool aDidExceedThreshold);
     void        UpdateJamState(void);
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags);
-    void        HandleStateChanged(otChangedFlags aFlags);
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
 
-    Handler            mHandler;                  // Handler/callback to inform about jamming state
-    void *             mContext;                  // Context for handler/callback
-    Notifier::Callback mNotifierCallback;         // Notifier callback
-    TimerMilli         mTimer;                    // RSSI sample timer
-    uint64_t           mHistoryBitmap;            // History bitmap, each bit correspond to 1 sec interval
-    TimeMilli          mCurSecondStartTime;       // Start time for current 1 sec interval
-    uint16_t           mSampleInterval;           // Current sample interval
-    uint8_t            mWindow : 6;               // Window (in sec) to monitor jamming
-    uint8_t            mBusyPeriod : 6;           // BusyPeriod (in sec) with mWindow to alert jamming
-    bool               mEnabled : 1;              // If jam detection is enabled
-    bool               mAlwaysAboveThreshold : 1; // State for current 1 sec interval
-    bool               mJamState : 1;             // Current jam state
-    int8_t             mRssiThreshold;            // RSSI threshold for jam detection
+    Handler    mHandler;                  // Handler/callback to inform about jamming state
+    void *     mContext;                  // Context for handler/callback
+    TimerMilli mTimer;                    // RSSI sample timer
+    uint64_t   mHistoryBitmap;            // History bitmap, each bit correspond to 1 sec interval
+    TimeMilli  mCurSecondStartTime;       // Start time for current 1 sec interval
+    uint16_t   mSampleInterval;           // Current sample interval
+    uint8_t    mWindow : 6;               // Window (in sec) to monitor jamming
+    uint8_t    mBusyPeriod : 6;           // BusyPeriod (in sec) with mWindow to alert jamming
+    bool       mEnabled : 1;              // If jam detection is enabled
+    bool       mAlwaysAboveThreshold : 1; // State for current 1 sec interval
+    bool       mJamState : 1;             // Current jam state
+    int8_t     mRssiThreshold;            // RSSI threshold for jam detection
 };
 
 /**
diff --git a/src/core/utils/otns.cpp b/src/core/utils/otns.cpp
new file mode 100644
index 0000000..1d7a595
--- /dev/null
+++ b/src/core/utils/otns.cpp
@@ -0,0 +1,159 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements OTNS utilities.
+ *
+ */
+
+#include "otns.hpp"
+
+#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
+
+#include "common/debug.hpp"
+#include "common/locator-getters.hpp"
+
+namespace ot {
+namespace Utils {
+
+const int kMaxStatusStringLength = 128;
+
+void Otns::EmitShortAddress(uint16_t aShortAddress)
+{
+    EmitStatus("rloc16=%d", aShortAddress);
+}
+
+void Otns::EmitExtendedAddress(const Mac::ExtAddress &aExtAddress)
+{
+    Mac::ExtAddress revExtAddress;
+    revExtAddress.Set(aExtAddress.m8, Mac::ExtAddress::kReverseByteOrder);
+    EmitStatus("extaddr=%s", revExtAddress.ToString().AsCString());
+}
+
+void Otns::EmitPingRequest(const Ip6::Address &aPeerAddress,
+                           uint16_t            aPingLength,
+                           uint32_t            aTimestamp,
+                           uint8_t             aHopLimit)
+{
+    OT_UNUSED_VARIABLE(aHopLimit);
+    EmitStatus("ping_request=%s,%d,%lu", aPeerAddress.ToString().AsCString(), aPingLength, aTimestamp);
+}
+
+void Otns::EmitPingReply(const Ip6::Address &aPeerAddress, uint16_t aPingLength, uint32_t aTimestamp, uint8_t aHopLimit)
+{
+    EmitStatus("ping_reply=%s,%u,%lu,%d", aPeerAddress.ToString().AsCString(), aPingLength, aTimestamp, aHopLimit);
+}
+
+void Otns::EmitStatus(const char *aFmt, ...)
+{
+    char statusStr[kMaxStatusStringLength + 1];
+    int  n;
+
+    va_list ap;
+    va_start(ap, aFmt);
+
+    n = vsnprintf(statusStr, sizeof(statusStr), aFmt, ap);
+    OT_ASSERT(n >= 0);
+
+    va_end(ap);
+
+    otPlatOtnsStatus(statusStr);
+}
+
+void Otns::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
+{
+    static_cast<Otns &>(aReceiver).HandleNotifierEvents(aEvents);
+}
+
+void Otns::HandleNotifierEvents(Events aEvents)
+{
+    if (aEvents.Contains(kEventThreadRoleChanged))
+    {
+        EmitStatus("role=%d", Get<Mle::Mle>().GetRole());
+    }
+
+    if (aEvents.Contains(kEventThreadPartitionIdChanged))
+    {
+        EmitStatus("parid=%x", Get<Mle::Mle>().GetLeaderData().GetPartitionId());
+    }
+
+#if OPENTHREAD_CONFIG_JOINER_ENABLE
+    if (aEvents.Contains(kEventJoinerStateChanged))
+    {
+        EmitStatus("joiner_state=%d", Get<MeshCoP::Joiner>().GetState());
+    }
+#endif
+}
+
+void Otns::EmitNeighborChange(otNeighborTableEvent aEvent, Neighbor &aNeighbor)
+{
+    switch (aEvent)
+    {
+    case OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED:
+        EmitStatus("router_added=%s", aNeighbor.GetExtAddress().ToString().AsCString());
+        break;
+    case OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED:
+        EmitStatus("router_removed=%s", aNeighbor.GetExtAddress().ToString().AsCString());
+        break;
+    case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED:
+        EmitStatus("child_added=%s", aNeighbor.GetExtAddress().ToString().AsCString());
+        break;
+    case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED:
+        EmitStatus("child_removed=%s", aNeighbor.GetExtAddress().ToString().AsCString());
+        break;
+    }
+}
+
+void Otns::EmitTransmit(const Mac::TxFrame &aFrame)
+{
+    Mac::Address dst;
+    uint16_t     frameControlField = aFrame.GetFrameControlField();
+    uint8_t      channel           = aFrame.GetChannel();
+    uint8_t      sequence          = aFrame.GetSequence();
+
+    IgnoreError(aFrame.GetDstAddr(dst));
+
+    if (dst.IsShort())
+    {
+        EmitStatus("transmit=%d,%04x,%d,%04x", channel, frameControlField, sequence, dst.GetShort());
+    }
+    else if (dst.IsExtended())
+    {
+        EmitStatus("transmit=%d,%04x,%d,%s", channel, frameControlField, sequence, dst.ToString().AsCString());
+    }
+    else
+    {
+        EmitStatus("transmit=%d,%04x,%d", channel, frameControlField, sequence);
+    }
+}
+
+} // namespace Utils
+} // namespace ot
+
+#endif // (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
diff --git a/src/core/utils/otns.hpp b/src/core/utils/otns.hpp
new file mode 100644
index 0000000..bb74794
--- /dev/null
+++ b/src/core/utils/otns.hpp
@@ -0,0 +1,147 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file wraps the calls to platform OTNS abstrations.
+ */
+
+#ifndef UTILS_OTNS_HPP_
+#define UTILS_OTNS_HPP_
+
+#include "openthread-core-config.h"
+
+#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
+
+#include <openthread/thread.h>
+#include <openthread/thread_ftd.h>
+#include <openthread/platform/otns.h>
+
+#include "common/locator.hpp"
+#include "common/non_copyable.hpp"
+#include "common/notifier.hpp"
+#include "mac/mac_types.hpp"
+#include "net/ip6_address.hpp"
+#include "thread/topology.hpp"
+
+namespace ot {
+namespace Utils {
+
+/**
+ * This class implements the OTNS Stub that interacts with OTNS.
+ *
+ */
+class Otns : public InstanceLocator, public Notifier::Receiver, private NonCopyable
+{
+public:
+    /**
+     * This constructor initializes the object.
+     *
+     * @param[in]  aInstance     A reference to the OpenThread instance.
+     *
+     */
+    explicit Otns(Instance &aInstance)
+        : InstanceLocator(aInstance)
+        , Notifier::Receiver(aInstance, Otns::HandleNotifierEvents)
+    {
+    }
+
+    /**
+     * This function emits radio short address to OTNS when changed.
+     *
+     * @param[in]  aShortAddress  The new short address.
+     *
+     */
+    static void EmitShortAddress(uint16_t aShortAddress);
+
+    /**
+     * This function emits radio extended address to OTNS when changed.
+     *
+     * @param[in]  aExtAddress  The new extended address.
+     *
+     */
+    static void EmitExtendedAddress(const Mac::ExtAddress &aExtAddress);
+
+    /**
+     * This function emits ping request information to OTNS when sending.
+     *
+     * @param[in]  aPeerAddress  The peer address of the ping request.
+     * @param[in]  aPingLength   The data length of the ping request.
+     * @param[in]  aTimestamp    The timestamp of the ping request.
+     * @param[in]  aHopLimit     The hop limit of the ping request.
+     *
+     */
+    static void EmitPingRequest(const Ip6::Address &aPeerAddress,
+                                uint16_t            aPingLength,
+                                uint32_t            aTimestamp,
+                                uint8_t             aHopLimit);
+
+    /**
+     * This function emits ping reply information to OTNS when received.
+     *
+     * @param[in]  aPeerAddress  The peer address of the ping request.
+     * @param[in]  aPingLength   The data length of the ping reply.
+     * @param[in]  aTimestamp    The timestamp of the ping reply.
+     * @param[in]  aHopLimit     The hop limit of the ping reply.
+     *
+     */
+    static void EmitPingReply(const Ip6::Address &aPeerAddress,
+                              uint16_t            aPingLength,
+                              uint32_t            aTimestamp,
+                              uint8_t             aHopLimit);
+
+    /**
+     * This function emits a neighbor table event to OTNS when a neighbor is added or removed.
+     *
+     * @param[in]  aEvent     The event type.
+     * @param[in]  aNeighbor  The neighbor that is added or removed.
+     *
+     */
+    static void EmitNeighborChange(otNeighborTableEvent aEvent, Neighbor &aNeighbor);
+
+    /**
+     * This function emits a transmit event to OTNS.
+     *
+     * @param[in]  aFrame  The frame of the transmission.
+     *
+     */
+    static void EmitTransmit(const Mac::TxFrame &aFrame);
+
+private:
+    static void EmitStatus(const char *aFmt, ...);
+
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
+};
+
+} // namespace Utils
+} // namespace ot
+
+#endif //(OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
+
+#endif // UTILS_OTNS_HPP_
diff --git a/src/core/utils/parse_cmdline.cpp b/src/core/utils/parse_cmdline.cpp
index 9da77ee..d65bc47 100644
--- a/src/core/utils/parse_cmdline.cpp
+++ b/src/core/utils/parse_cmdline.cpp
@@ -31,6 +31,8 @@
  *   This file implements the command line parser.
  */
 
+#include <string.h>
+
 #include "parse_cmdline.hpp"
 
 #include "common/code_utils.hpp"
@@ -38,36 +40,39 @@
 namespace ot {
 namespace Utils {
 
-static bool IsSpaceOrNewLine(char aChar)
+static bool IsSeparator(char aChar)
 {
     return (aChar == ' ') || (aChar == '\t') || (aChar == '\r') || (aChar == '\n');
 }
 
-otError CmdLineParser::ParseCmd(char *aString, uint8_t &aArgc, char *aArgv[], uint8_t aArgcMax)
+static bool IsEscapable(char aChar)
+{
+    return IsSeparator(aChar) || (aChar == '\\');
+}
+
+otError CmdLineParser::ParseCmd(char *aString, uint8_t &aArgsLength, char *aArgs[], uint8_t aArgsLengthMax)
 {
     otError error = OT_ERROR_NONE;
     char *  cmd;
 
-    aArgc = 0;
+    aArgsLength = 0;
 
-    for (cmd = aString; IsSpaceOrNewLine(*cmd) && *cmd; cmd++)
-        ;
-
-    if (*cmd)
+    for (cmd = aString; *cmd; cmd++)
     {
-        aArgv[aArgc++] = cmd++; // the first argument
-    }
-
-    for (; *cmd; cmd++)
-    {
-        if (IsSpaceOrNewLine(*cmd))
+        if ((*cmd == '\\') && IsEscapable(*(cmd + 1)))
+        {
+            // include the null terminator: strlen(cmd) = strlen(cmd + 1) + 1
+            memmove(cmd, cmd + 1, strlen(cmd));
+        }
+        else if (IsSeparator(*cmd))
         {
             *cmd = '\0';
         }
-        else if (*(cmd - 1) == '\0')
+
+        if ((*cmd != '\0') && ((aArgsLength == 0) || (*(cmd - 1) == '\0')))
         {
-            VerifyOrExit(aArgc < aArgcMax, error = OT_ERROR_INVALID_ARGS);
-            aArgv[aArgc++] = cmd;
+            VerifyOrExit(aArgsLength < aArgsLengthMax, error = OT_ERROR_INVALID_ARGS);
+            aArgs[aArgsLength++] = cmd;
         }
     }
 
diff --git a/src/core/utils/parse_cmdline.hpp b/src/core/utils/parse_cmdline.hpp
index f2ec002..670ccd9 100644
--- a/src/core/utils/parse_cmdline.hpp
+++ b/src/core/utils/parse_cmdline.hpp
@@ -60,15 +60,16 @@
      * This function parses the command line.
      *
      * Note: this method may change the input @p aString, it will put a '\0' by the end of each argument,
-     *       and @p aArgv will point to the arguments in the input @p aString.
+     *       and @p aArgs will point to the arguments in the input @p aString. Backslash ('\') can be used
+     *       to escape separators (' ', '\t', '\r', '\n') and the backslash itself.
      *
-     * @param[in]   aString   A NULL-terminated input string.
-     * @param[out]  aArgc     The argument counter of the command line.
-     * @param[out]  aArgv     The argument vector of the command line.
-     * @param[in]   aArgcMax  The maximum argument counter.
+     * @param[in]   aString         A null-terminated input string.
+     * @param[out]  aArgsLength     The argument counter of the command line.
+     * @param[out]  aArgs           The argument vector of the command line.
+     * @param[in]   aArgsLengthMax  The maximum argument counter.
      *
      */
-    static otError ParseCmd(char *aString, uint8_t &aArgc, char *aArgv[], uint8_t aArgcMax);
+    static otError ParseCmd(char *aString, uint8_t &aArgsLength, char *aArgs[], uint8_t aArgsLengthMax);
 };
 
 /**
diff --git a/src/core/utils/slaac_address.cpp b/src/core/utils/slaac_address.cpp
index e86a115..4971f38 100644
--- a/src/core/utils/slaac_address.cpp
+++ b/src/core/utils/slaac_address.cpp
@@ -49,16 +49,16 @@
 
 Slaac::Slaac(Instance &aInstance)
     : InstanceLocator(aInstance)
+    , Notifier::Receiver(aInstance, Slaac::HandleNotifierEvents)
     , mEnabled(true)
-    , mFilter(NULL)
-    , mNotifierCallback(aInstance, &Slaac::HandleStateChanged, this)
+    , mFilter(nullptr)
 {
     memset(mAddresses, 0, sizeof(mAddresses));
 }
 
 void Slaac::Enable(void)
 {
-    VerifyOrExit(!mEnabled);
+    VerifyOrExit(!mEnabled, OT_NOOP);
 
     otLogInfoUtil("SLAAC:: Enabling");
     mEnabled = true;
@@ -70,7 +70,7 @@
 
 void Slaac::Disable(void)
 {
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
     otLogInfoUtil("SLAAC:: Disabling");
     mEnabled = false;
@@ -82,12 +82,12 @@
 
 void Slaac::SetFilter(otIp6SlaacPrefixFilter aFilter)
 {
-    VerifyOrExit(aFilter != mFilter);
+    VerifyOrExit(aFilter != mFilter, OT_NOOP);
 
     mFilter = aFilter;
-    otLogInfoUtil("SLAAC: Filter %s", (mFilter != NULL) ? "updated" : "disabled");
+    otLogInfoUtil("SLAAC: Filter %s", (mFilter != nullptr) ? "updated" : "disabled");
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
     Update(kModeAdd | kModeRemove);
 
 exit:
@@ -96,26 +96,26 @@
 
 bool Slaac::ShouldFilter(const otIp6Prefix &aPrefix) const
 {
-    return (mFilter != NULL) && mFilter(&GetInstance(), &aPrefix);
+    return (mFilter != nullptr) && mFilter(&GetInstance(), &aPrefix);
 }
 
-void Slaac::HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags)
+void Slaac::HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents)
 {
-    aCallback.GetOwner<Slaac>().HandleStateChanged(aFlags);
+    static_cast<Slaac &>(aReceiver).HandleNotifierEvents(aEvents);
 }
 
-void Slaac::HandleStateChanged(otChangedFlags aFlags)
+void Slaac::HandleNotifierEvents(Events aEvents)
 {
     UpdateMode mode = kModeNone;
 
-    VerifyOrExit(mEnabled);
+    VerifyOrExit(mEnabled, OT_NOOP);
 
-    if (aFlags & OT_CHANGED_THREAD_NETDATA)
+    if (aEvents.Contains(kEventThreadNetdataChanged))
     {
         mode |= kModeAdd | kModeRemove;
     }
 
-    if (aFlags & OT_CHANGED_IP6_ADDRESS_REMOVED)
+    if (aEvents.Contains(kEventIp6AddressRemoved))
     {
         // When an IPv6 address is removed, we ensure to check if a SLAAC address
         // needs to be added (replacing the removed address).
@@ -138,6 +138,14 @@
     return;
 }
 
+bool Slaac::DoesConfigMatchNetifAddr(const NetworkData::OnMeshPrefixConfig &aConfig,
+                                     const Ip6::NetifUnicastAddress &       aAddr)
+{
+    return (((aConfig.mOnMesh && (aAddr.mPrefixLength == aConfig.mPrefix.mLength)) ||
+             (!aConfig.mOnMesh && (aAddr.mPrefixLength == 128))) &&
+            (aAddr.GetAddress().PrefixMatch(aConfig.mPrefix.mPrefix) >= aConfig.mPrefix.mLength));
+}
+
 void Slaac::Update(UpdateMode aMode)
 {
     NetworkData::Iterator           iterator;
@@ -165,10 +173,13 @@
 
                 while (Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, config) == OT_ERROR_NONE)
                 {
-                    otIp6Prefix &prefix = config.mPrefix;
+                    if (config.mDp)
+                    {
+                        // Skip domain prefix which is processed in MLE.
+                        continue;
+                    }
 
-                    if (config.mSlaac && !ShouldFilter(prefix) && (prefix.mLength == slaacAddr->mPrefixLength) &&
-                        (slaacAddr->GetAddress().PrefixMatch(prefix.mPrefix) >= prefix.mLength))
+                    if (config.mSlaac && !ShouldFilter(config.mPrefix) && DoesConfigMatchNetifAddr(config, *slaacAddr))
                     {
                         found = true;
                         break;
@@ -196,7 +207,7 @@
         {
             otIp6Prefix &prefix = config.mPrefix;
 
-            if (!config.mSlaac || ShouldFilter(prefix))
+            if (config.mDp || !config.mSlaac || ShouldFilter(prefix))
             {
                 continue;
             }
@@ -204,10 +215,9 @@
             found = false;
 
             for (const Ip6::NetifUnicastAddress *netifAddr = Get<ThreadNetif>().GetUnicastAddresses();
-                 netifAddr != NULL; netifAddr              = netifAddr->GetNext())
+                 netifAddr != nullptr; netifAddr           = netifAddr->GetNext())
             {
-                if ((netifAddr->mPrefixLength == prefix.mLength) &&
-                    (netifAddr->GetAddress().PrefixMatch(prefix.mPrefix) >= prefix.mLength))
+                if (DoesConfigMatchNetifAddr(config, *netifAddr))
                 {
                     found = true;
                     break;
@@ -228,11 +238,12 @@
                     slaacAddr->Clear();
                     memcpy(&slaacAddr->mAddress, &prefix.mPrefix, BitVectorBytes(prefix.mLength));
 
-                    slaacAddr->mPrefixLength = prefix.mLength;
-                    slaacAddr->mPreferred    = config.mPreferred;
-                    slaacAddr->mValid        = true;
+                    slaacAddr->mPrefixLength  = config.mOnMesh ? prefix.mLength : 128;
+                    slaacAddr->mAddressOrigin = OT_ADDRESS_ORIGIN_SLAAC;
+                    slaacAddr->mPreferred     = config.mPreferred;
+                    slaacAddr->mValid         = true;
 
-                    GenerateIid(*slaacAddr);
+                    IgnoreError(GenerateIid(*slaacAddr));
 
                     otLogInfoUtil("SLAAC: Adding address %s", slaacAddr->GetAddress().ToString().AsCString());
 
@@ -252,7 +263,10 @@
     }
 }
 
-void Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress) const
+otError Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress,
+                           uint8_t *                 aNetworkId,
+                           uint8_t                   aNetworkIdLength,
+                           uint8_t *                 aDadCounter) const
 {
     /*
      *  This method generates a semantically opaque IID per RFC 7217.
@@ -262,47 +276,61 @@
      *  - RID is random (but stable) Identifier.
      *  - For pseudo-random function `F()` SHA-256 is used in this method.
      *  - `Net_Iface` is set to constant string "wpan".
-     *  - `Network_ID` is not used (optional per RF-7217).
+     *  - `Network_ID` is not used if `aNetworkId` is nullptr (optional per RF-7217).
      *  - The `secret_key` is randomly generated on first use (using true
      *    random number generator) and saved in non-volatile settings for
      *    future use.
      *
      */
 
+    otError        error      = OT_ERROR_FAILED;
     const uint8_t  netIface[] = {'w', 'p', 'a', 'n'};
-    uint16_t       dadCounter;
+    uint8_t        dadCounter = aDadCounter ? *aDadCounter : 0;
     IidSecretKey   secretKey;
     Crypto::Sha256 sha256;
     uint8_t        hash[Crypto::Sha256::kHashSize];
 
-    OT_STATIC_ASSERT(sizeof(hash) >= Ip6::Address::kInterfaceIdentifierSize,
-                     "SHA-256 hash size is too small to use as IPv6 address IID");
+    static_assert(sizeof(hash) >= Ip6::InterfaceIdentifier::kSize,
+                  "SHA-256 hash size is too small to use as IPv6 address IID");
 
     GetIidSecretKey(secretKey);
 
-    for (dadCounter = 0; dadCounter < kMaxIidCreationAttempts; dadCounter++)
+    for (uint16_t count = 0; count < kMaxIidCreationAttempts; count++, dadCounter++)
     {
         sha256.Start();
         sha256.Update(aAddress.mAddress.mFields.m8, BitVectorBytes(aAddress.mPrefixLength));
+
+        if (aNetworkId)
+        {
+            sha256.Update(aNetworkId, aNetworkIdLength);
+        }
+
         sha256.Update(netIface, sizeof(netIface));
         sha256.Update(reinterpret_cast<uint8_t *>(&dadCounter), sizeof(dadCounter));
         sha256.Update(secretKey.m8, sizeof(IidSecretKey));
         sha256.Finish(hash);
 
-        aAddress.GetAddress().SetIid(&hash[0]);
+        aAddress.GetAddress().GetIid().SetBytes(&hash[0]);
+
+        // If the IID is reserved, try again with a new dadCounter
+        if (aAddress.GetAddress().GetIid().IsReserved())
+        {
+            continue;
+        }
+
+        if (aDadCounter)
+        {
+            *aDadCounter = dadCounter;
+        }
 
         // Exit and return the address if the IID is not reserved,
-        // otherwise, try again with a new dadCounter
-
-        VerifyOrExit(aAddress.GetAddress().IsIidReserved());
+        ExitNow(error = OT_ERROR_NONE);
     }
 
-    otLogWarnUtil("SLAAC: Failed to generate a non-reserved IID after %d attempts", dadCounter);
-    Random::NonCrypto::FillBuffer(hash, Ip6::Address::kInterfaceIdentifierSize);
-    aAddress.GetAddress().SetIid(&hash[0]);
+    otLogWarnUtil("SLAAC: Failed to generate a non-reserved IID after %d attempts", kMaxIidCreationAttempts);
 
 exit:
-    return;
+    return error;
 }
 
 void Slaac::GetIidSecretKey(IidSecretKey &aKey) const
@@ -310,7 +338,7 @@
     otError error;
 
     error = Get<Settings>().ReadSlaacIidSecretKey(aKey);
-    VerifyOrExit(error != OT_ERROR_NONE);
+    VerifyOrExit(error != OT_ERROR_NONE, OT_NOOP);
 
     // If there is no previously saved secret key, generate
     // a random one and save it.
@@ -319,10 +347,10 @@
 
     if (error != OT_ERROR_NONE)
     {
-        Random::NonCrypto::FillBuffer(aKey.m8, sizeof(IidSecretKey));
+        IgnoreError(Random::Crypto::FillBuffer(aKey.m8, sizeof(IidSecretKey)));
     }
 
-    Get<Settings>().SaveSlaacIidSecretKey(aKey);
+    IgnoreError(Get<Settings>().SaveSlaacIidSecretKey(aKey));
 
     otLogInfoUtil("SLAAC: Generated and saved secret key");
 
diff --git a/src/core/utils/slaac_address.hpp b/src/core/utils/slaac_address.hpp
index 90fd9f8..3c035ce 100644
--- a/src/core/utils/slaac_address.hpp
+++ b/src/core/utils/slaac_address.hpp
@@ -39,6 +39,7 @@
 #include "common/locator.hpp"
 #include "common/notifier.hpp"
 #include "net/netif.hpp"
+#include "thread/network_data.hpp"
 
 namespace ot {
 namespace Utils {
@@ -56,7 +57,7 @@
  * This class implements the SLAAC utility for Thread protocol.
  *
  */
-class Slaac : public InstanceLocator
+class Slaac : public InstanceLocator, public Notifier::Receiver
 {
 public:
     enum
@@ -109,21 +110,41 @@
     bool IsEnabled(void) const { return mEnabled; }
 
     /**
-     * This methods sets a SLAAC prefix filter handler.
+     * This method sets a SLAAC prefix filter handler.
      *
      * The handler is invoked by SLAAC module when it is about to add a SLAAC address based on a prefix. The return
      * boolean value from handler determines whether the address is filtered or added (TRUE to filter the address,
      * FALSE to add address).
      *
-     * The filter can be set to `NULL` to disable filtering (i.e., allow SLAAC addresses for all prefixes).
+     * The filter can be set to `nullptr` to disable filtering (i.e., allow SLAAC addresses for all prefixes).
      *
      */
     void SetFilter(otIp6SlaacPrefixFilter aFilter);
 
+    /**
+     * This method generates the IID of an IPv6 address.
+     *
+     * @param[inout]  aAddress             A reference to the address that will be filled with the IID generated.
+     *                                     Note the prefix of the address must already be filled and will be used
+     *                                     to generate the IID.
+     * @param[in]     aNetworkId           A pointer to a byte array of Network_ID to generate IID.
+     * @param[in]     aNetworkIdLength     The size of array @p aNetworkId.
+     * @param[inout]  aDadCounter          A pointer to the DAD_Counter that is employed to resolve Duplicate
+     *                                     Address Detection connflicts.
+     *
+     * @retval OT_ERROR_NONE   If successfully generated the IID.
+     * @retval OT_ERROR_FAILED If no valid IID was generated.
+     *
+     */
+    otError GenerateIid(Ip6::NetifUnicastAddress &aAddress,
+                        uint8_t *                 aNetworkId       = nullptr,
+                        uint8_t                   aNetworkIdLength = 0,
+                        uint8_t *                 aDadCounter      = nullptr) const;
+
 private:
     enum
     {
-        kMaxIidCreationAttempts = 1024, // Maximum number of attempts when generating IID.
+        kMaxIidCreationAttempts = 256, // Maximum number of attempts when generating IID.
     };
 
     // Values for `UpdateMode` input parameter in `Update()`.
@@ -140,14 +161,14 @@
 
     bool        ShouldFilter(const otIp6Prefix &aPrefix) const;
     void        Update(UpdateMode aMode);
-    void        GenerateIid(Ip6::NetifUnicastAddress &aAddress) const;
     void        GetIidSecretKey(IidSecretKey &aKey) const;
-    static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags);
-    void        HandleStateChanged(otChangedFlags aFlags);
+    static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+    void        HandleNotifierEvents(Events aEvents);
+    static bool DoesConfigMatchNetifAddr(const NetworkData::OnMeshPrefixConfig &aConfig,
+                                         const Ip6::NetifUnicastAddress &       aAddr);
 
     bool                     mEnabled;
     otIp6SlaacPrefixFilter   mFilter;
-    Notifier::Callback       mNotifierCallback;
     Ip6::NetifUnicastAddress mAddresses[OPENTHREAD_CONFIG_IP6_SLAAC_NUM_ADDRESSES];
 };
 
diff --git a/src/core/utils/static_assert.hpp b/src/core/utils/static_assert.hpp
deleted file mode 100644
index de25c70..0000000
--- a/src/core/utils/static_assert.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes macros for static assert for C++03.
- */
-
-#ifndef OPENTHREAD_STATIC_ASSERT_HPP_
-#define OPENTHREAD_STATIC_ASSERT_HPP_
-
-#ifdef __cplusplus
-
-/**
- * Some compilers such as Keil MDK-ARM does not support __COUNTER__ macro.
- */
-#ifndef __COUNTER__
-#define __COUNTER__ __LINE__
-#endif
-
-namespace ot {
-
-template <int> struct StaticAssertError;
-template <> struct StaticAssertError<true>
-{
-    StaticAssertError(...);
-};
-
-} // namespace ot
-
-#define __OT_STATIC_ASSERT_ERROR(aError, aLine) aError##aLine
-#define _OT_STATIC_ASSERT_ERROR(aLine) __OT_STATIC_ASSERT_ERROR(StaticAssertError, aLine)
-
-/**
- * This macro does static assert.
- *
- * @param[in]   aExpression An expression to assert.
- * @param[in]   aMessage    A message to describe what is wrong when @p aExpression is false.
- *
- */
-#define OT_STATIC_ASSERT(aExpression, aMessage)                                                             \
-    enum                                                                                                    \
-    {                                                                                                       \
-        _OT_STATIC_ASSERT_ERROR(__COUNTER__) = sizeof(ot::StaticAssertError<(aExpression) != 0>(aMessage)), \
-    }
-
-#endif // __cplusplus
-
-#endif // OPENTHREAD_STATIC_ASSERT_HPP_
diff --git a/src/core/utils/wrap_string.h b/src/core/utils/wrap_string.h
deleted file mode 100644
index 915b618..0000000
--- a/src/core/utils/wrap_string.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *    Copyright (c) 2017, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file is a wrapper for the standard "string.h" file
- *   Some platforms provide all required functions, some do not.
- *   This solves the missing functions in #include <string.h>
- */
-
-#if !defined(WRAP_STRING_H)
-#define WRAP_STRING_H
-
-#include "openthread-core-config.h"
-
-/* system provided string.h */
-#include <string.h>
-
-/* These are C functions */
-#if defined(__cplusplus)
-#define WRAP_EXTERN_C extern "C"
-#else
-#define WRAP_EXTERN_C extern
-#endif
-
-/* Prototypes for our missing function replacements */
-
-#undef WRAP_EXTERN_C
-
-#endif // WRAP_STRING_H
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
new file mode 100644
index 0000000..31e6c01
--- /dev/null
+++ b/src/lib/CMakeLists.txt
@@ -0,0 +1,32 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_subdirectory(hdlc)
+add_subdirectory(platform)
+add_subdirectory(spinel)
+add_subdirectory(url)
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644
index 0000000..1bb226c
--- /dev/null
+++ b/src/lib/Makefile.am
@@ -0,0 +1,38 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+
+SUBDIRS                                 = \
+    hdlc                                  \
+    platform                              \
+    spinel                                \
+    url                                   \
+    $(NULL)
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/src/lib/common.am b/src/lib/common.am
new file mode 100644
index 0000000..94c34de
--- /dev/null
+++ b/src/lib/common.am
@@ -0,0 +1,29 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+ot_list_objects = $(addprefix $(dir $(1)),$(filter %.o,$(shell $(AR) t $(1))))
diff --git a/src/lib/hdlc/CMakeLists.txt b/src/lib/hdlc/CMakeLists.txt
new file mode 100644
index 0000000..dc84588
--- /dev/null
+++ b/src/lib/hdlc/CMakeLists.txt
@@ -0,0 +1,51 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_library(openthread-hdlc
+    hdlc.cpp
+)
+
+set_target_properties(
+    openthread-hdlc
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_include_directories(openthread-hdlc
+    PUBLIC
+        ${OT_PUBLIC_INCLUDES}
+    PRIVATE
+        ${PROJECT_SOURCE_DIR}/src/core
+)
+
+target_link_libraries(openthread-hdlc PRIVATE ot-config)
+
+target_compile_options(openthread-hdlc PRIVATE
+    ${OT_CFLAGS}
+)
diff --git a/src/lib/hdlc/Makefile.am b/src/lib/hdlc/Makefile.am
new file mode 100644
index 0000000..c410f14
--- /dev/null
+++ b/src/lib/hdlc/Makefile.am
@@ -0,0 +1,43 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+
+noinst_LIBRARIES = libopenthread-hdlc.a
+
+libopenthread_hdlc_a_CPPFLAGS               = \
+    -I$(top_srcdir)/include                   \
+    -I$(top_srcdir)/src/core                  \
+    $(NULL)
+
+libopenthread_hdlc_a_SOURCES                = \
+    hdlc.cpp                                  \
+    hdlc.hpp                                  \
+    $(NULL)
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/src/lib/hdlc/hdlc.cpp b/src/lib/hdlc/hdlc.cpp
new file mode 100644
index 0000000..11c9fe9
--- /dev/null
+++ b/src/lib/hdlc/hdlc.cpp
@@ -0,0 +1,300 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements an HDLC-lite encoder and decoder.
+ */
+
+#include "hdlc.hpp"
+
+#include <stdlib.h>
+
+#include "common/code_utils.hpp"
+
+namespace ot {
+namespace Hdlc {
+
+/**
+ * This method updates an FCS.
+ *
+ * @param[in]  aFcs   The FCS to update.
+ * @param[in]  aByte  The input byte value.
+ *
+ * @returns The updated FCS.
+ *
+ */
+static uint16_t UpdateFcs(uint16_t aFcs, uint8_t aByte);
+
+enum
+{
+    kFlagXOn        = 0x11,
+    kFlagXOff       = 0x13,
+    kFlagSequence   = 0x7e, ///< HDLC Flag value
+    kEscapeSequence = 0x7d, ///< HDLC Escape value
+    kFlagSpecial    = 0xf8,
+};
+
+/**
+ * FCS lookup table
+ *
+ */
+enum
+{
+    kInitFcs = 0xffff, ///< Initial FCS value.
+    kGoodFcs = 0xf0b8, ///< Good FCS value.
+    kFcsSize = 2,      ///< FCS size (number of bytes).
+};
+
+uint16_t UpdateFcs(uint16_t aFcs, uint8_t aByte)
+{
+    static const uint16_t sFcsTable[256] = {
+        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5,
+        0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52,
+        0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3,
+        0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9,
+        0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e,
+        0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f,
+        0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862,
+        0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb,
+        0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948,
+        0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226,
+        0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497,
+        0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704,
+        0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb,
+        0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c,
+        0x3de3, 0x2c6a, 0x1ef1, 0x0f78};
+    return (aFcs >> 8) ^ sFcsTable[(aFcs ^ aByte) & 0xff];
+}
+
+static bool HdlcByteNeedsEscape(uint8_t aByte)
+{
+    bool rval;
+
+    switch (aByte)
+    {
+    case kFlagXOn:
+    case kFlagXOff:
+    case kEscapeSequence:
+    case kFlagSequence:
+    case kFlagSpecial:
+        rval = true;
+        break;
+
+    default:
+        rval = false;
+        break;
+    }
+
+    return rval;
+}
+
+Encoder::Encoder(FrameWritePointer &aWritePointer)
+    : mWritePointer(aWritePointer)
+    , mFcs(0)
+{
+}
+
+otError Encoder::BeginFrame(void)
+{
+    mFcs = kInitFcs;
+
+    return mWritePointer.WriteByte(kFlagSequence);
+}
+
+otError Encoder::Encode(uint8_t aByte)
+{
+    otError error = OT_ERROR_NONE;
+
+    if (HdlcByteNeedsEscape(aByte))
+    {
+        VerifyOrExit(mWritePointer.CanWrite(2), error = OT_ERROR_NO_BUFS);
+
+        IgnoreError(mWritePointer.WriteByte(kEscapeSequence));
+        IgnoreError(mWritePointer.WriteByte(aByte ^ 0x20));
+    }
+    else
+    {
+        SuccessOrExit(error = mWritePointer.WriteByte(aByte));
+    }
+
+    mFcs = UpdateFcs(mFcs, aByte);
+
+exit:
+    return error;
+}
+
+otError Encoder::Encode(const uint8_t *aData, uint16_t aLength)
+{
+    otError           error      = OT_ERROR_NONE;
+    uint16_t          oldFcs     = mFcs;
+    FrameWritePointer oldPointer = mWritePointer;
+
+    while (aLength--)
+    {
+        SuccessOrExit(error = Encode(*aData++));
+    }
+
+exit:
+
+    if (error != OT_ERROR_NONE)
+    {
+        mWritePointer = oldPointer;
+        mFcs          = oldFcs;
+    }
+
+    return error;
+}
+
+otError Encoder::EndFrame(void)
+{
+    otError           error      = OT_ERROR_NONE;
+    FrameWritePointer oldPointer = mWritePointer;
+    uint16_t          oldFcs     = mFcs;
+    uint16_t          fcs        = mFcs;
+
+    fcs ^= 0xffff;
+
+    SuccessOrExit(error = Encode(fcs & 0xff));
+    SuccessOrExit(error = Encode(fcs >> 8));
+
+    SuccessOrExit(error = mWritePointer.WriteByte(kFlagSequence));
+
+exit:
+
+    if (error != OT_ERROR_NONE)
+    {
+        mWritePointer = oldPointer;
+        mFcs          = oldFcs;
+    }
+
+    return error;
+}
+
+Decoder::Decoder(FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext)
+    : mState(kStateNoSync)
+    , mWritePointer(aFrameWritePointer)
+    , mFrameHandler(aFrameHandler)
+    , mContext(aContext)
+    , mFcs(0)
+    , mDecodedLength(0)
+{
+}
+
+void Decoder::Decode(const uint8_t *aData, uint16_t aLength)
+{
+    while (aLength--)
+    {
+        uint8_t byte = *aData++;
+
+        switch (mState)
+        {
+        case kStateNoSync:
+            if (byte == kFlagSequence)
+            {
+                mState         = kStateSync;
+                mDecodedLength = 0;
+                mFcs           = kInitFcs;
+            }
+
+            break;
+
+        case kStateSync:
+            switch (byte)
+            {
+            case kEscapeSequence:
+                mState = kStateEscaped;
+                break;
+
+            case kFlagSequence:
+
+                if (mDecodedLength > 0)
+                {
+                    otError error = OT_ERROR_PARSE;
+
+                    if ((mDecodedLength >= kFcsSize)
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+                        && (mFcs == kGoodFcs)
+#endif
+                    )
+                    {
+                        // Remove the FCS from the frame.
+                        mWritePointer.UndoLastWrites(kFcsSize);
+                        error = OT_ERROR_NONE;
+                    }
+
+                    mFrameHandler(mContext, error);
+                }
+
+                mDecodedLength = 0;
+                mFcs           = kInitFcs;
+                break;
+
+            default:
+                if (mWritePointer.CanWrite(sizeof(uint8_t)))
+                {
+                    mFcs = UpdateFcs(mFcs, byte);
+                    IgnoreError(mWritePointer.WriteByte(byte));
+                    mDecodedLength++;
+                }
+                else
+                {
+                    mFrameHandler(mContext, OT_ERROR_NO_BUFS);
+                    mState = kStateNoSync;
+                }
+
+                break;
+            }
+
+            break;
+
+        case kStateEscaped:
+            if (mWritePointer.CanWrite(sizeof(uint8_t)))
+            {
+                byte ^= 0x20;
+                mFcs = UpdateFcs(mFcs, byte);
+                IgnoreError(mWritePointer.WriteByte(byte));
+                mDecodedLength++;
+                mState = kStateSync;
+            }
+            else
+            {
+                mFrameHandler(mContext, OT_ERROR_NO_BUFS);
+                mState = kStateNoSync;
+            }
+
+            break;
+        }
+    }
+}
+
+} // namespace Hdlc
+} // namespace ot
diff --git a/src/lib/hdlc/hdlc.hpp b/src/lib/hdlc/hdlc.hpp
new file mode 100644
index 0000000..4092f43
--- /dev/null
+++ b/src/lib/hdlc/hdlc.hpp
@@ -0,0 +1,588 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for an HDLC-lite encoder and decoder.
+ */
+
+#ifndef HDLC_HPP_
+#define HDLC_HPP_
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openthread/error.h>
+
+#include "common/code_utils.hpp"
+#include "common/debug.hpp"
+#include "common/encoding.hpp"
+
+namespace ot {
+
+/**
+ * @namespace ot::Hdlc
+ *
+ * @brief
+ *   This namespace includes definitions for the HDLC-lite encoder and decoder.
+ *
+ */
+namespace Hdlc {
+
+/**
+ * This class defines a frame write pointer used by `Hdlc::Encoder` or `Hdlc::Decoder`.
+ *
+ * This class defines the minimum set of APIs used by `Encoder/Decoder` for writing an encoded/decoded frame. It is
+ * simply a wrapper over a pointer into a buffer indicating where next byte should be written. Along with a write
+ * pointer, this class stores a remaining length variable indicating number of remaining bytes that can be written into
+ * the buffer.
+ *
+ * @note This class does NOT define the underlying buffer space or how it is being managed.
+ *
+ * `Encoder` or `Decoder` users are expected to use sub-classes of this class adding the buffer space and implementing
+ * the frame buffer management scheme.
+ *
+ * Two template sub-class `FrameBuffer` and `MultiFrameBuffer` are defined which respectively allow storing a single
+ * frame or multiple frames (FIFO queue of frame) in a buffer of a given size.
+ *
+ */
+class FrameWritePointer
+{
+public:
+    /**
+     * This method indicates whether there is buffer space available to write @p aWriteLength bytes.
+     *
+     * param[in] aWriteLength       Number of bytes to write.
+     *
+     * @retval TRUE                 Enough buffer space is available to write the requested number of bytes.
+     * @retval FALSE                Insufficient buffer space to write the requested number of bytes.
+     *
+     */
+    bool CanWrite(uint16_t aWriteLength) const { return (mRemainingLength >= aWriteLength); }
+
+    /**
+     * This method writes a byte into the buffer and updates the write pointer (if space is available).
+     *
+     * @retval OT_ERROR_NONE     Successfully wrote the byte and updated the pointer.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space to write the byte.
+     *
+     */
+    otError WriteByte(uint8_t aByte)
+    {
+        return CanWrite(sizeof(uint8_t)) ? (*mWritePointer++ = aByte, mRemainingLength--, OT_ERROR_NONE)
+                                         : OT_ERROR_NO_BUFS;
+    }
+
+    /**
+     * This method undoes the last @p aUndoLength writes, removing them from frame.
+     *
+     * @note Caller should ensure that @p aUndoLength is less than or equal to the number of previously written bytes
+     * into the frame. This method does not perform any checks and its behavior is undefined if @p aUndoLength is
+     * larger than the number of bytes previously written into the frame.
+     *
+     * @param[in]  aUndoLength   Number of bytes to remove (number of last `WriteByte()` calls to undo).
+     *
+     */
+    void UndoLastWrites(uint16_t aUndoLength)
+    {
+        mWritePointer -= aUndoLength;
+        mRemainingLength += aUndoLength;
+    }
+
+protected:
+    FrameWritePointer(void)
+        : mWritePointer(nullptr)
+        , mRemainingLength(0)
+    {
+    }
+
+    uint8_t *mWritePointer;    ///< A pointer to current write position in the buffer.
+    uint16_t mRemainingLength; ///< Number of remaining bytes available to write.
+};
+
+/**
+ * This class defines a template frame buffer of a given size for storing a single frame.
+ *
+ * The template parameter `kSize` specifies the size of the buffer.
+ *
+ */
+template <uint16_t kSize> class FrameBuffer : public FrameWritePointer
+{
+public:
+    /**
+     * This constructor initializes the `FrameBuffer` object.
+     *
+     */
+    FrameBuffer(void)
+        : FrameWritePointer()
+    {
+        Clear();
+    }
+
+    /**
+     * This method clears the buffer, moving the write pointer to the beginning of the buffer.
+     *
+     */
+    void Clear(void)
+    {
+        mWritePointer    = mBuffer;
+        mRemainingLength = sizeof(mBuffer);
+    }
+
+    /**
+     * This method indicates whether the buffer is empty or contains a frame.
+     *
+     * @retval TRUE  Buffer is empty
+     * @retval FALSE Buffer contains a frame
+     *
+     */
+    bool IsEmpty(void) const { return (mWritePointer == mBuffer); }
+
+    /**
+     * This method gets the length (number of bytes) in the frame.
+     *
+     * @returns The length (number of bytes) in the frame.
+     *
+     */
+    uint16_t GetLength(void) const { return static_cast<uint16_t>(mWritePointer - mBuffer); }
+
+    /**
+     * This method gets a pointer to start of the frame.
+     *
+     * @returns A pointer to start of the frame.
+     *
+     */
+    uint8_t *GetFrame(void) { return mBuffer; }
+
+private:
+    uint8_t mBuffer[kSize];
+};
+
+/**
+ * This class defines a template frame buffer of a given size for storing multiple frames.
+ *
+ * The template parameter `kSize` specifies the total size of the buffer.
+ *
+ * Unlike `FrameBuffer` class where a single frame can be stored, this class is capable of saving multiple frames
+ * in a FIFO queue format.
+ *
+ */
+template <uint16_t kSize> class MultiFrameBuffer : public FrameWritePointer
+{
+public:
+    /**
+     * This constructor initializes the `MultiFrameBuffer` object.
+     *
+     */
+    MultiFrameBuffer(void)
+        : FrameWritePointer()
+    {
+        Clear();
+    }
+
+    /**
+     * This method clears the buffer, removing current frame and all previously saved frames.
+     *
+     * It moves the write pointer to the beginning of the buffer.
+     *
+     */
+    void Clear(void)
+    {
+        mWriteFrameStart = mBuffer;
+        mWritePointer    = mBuffer + kHeaderSize;
+        mRemainingLength = kSize - kHeaderSize;
+
+        IgnoreError(SetSkipLength(0));
+    }
+
+    /**
+     * This method indicates whether the current frame (being written) is empty or not.
+     *
+     * @retval TRUE  Current frame is empty.
+     * @retval FALSE Current frame is not empty.
+     *
+     */
+    bool HasFrame(void) const { return (mWritePointer != GetFrame()); }
+
+    /**
+     * This method sets the length (number of bytes) of the current frame being written.
+     *
+     * param[in] aLength  The length of current frame.
+     *
+     * @retval OT_ERROR_NONE     Successfully set the length of the current frame.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space to hold a frame of length @p aLength.
+     *
+     */
+    otError SetLength(uint16_t aLength)
+    {
+        otError error = OT_ERROR_NO_BUFS;
+
+        if (GetFrame() + aLength <= OT_ARRAY_END(mBuffer))
+        {
+            mWritePointer    = GetFrame() + aLength;
+            mRemainingLength = static_cast<uint16_t>(mBuffer + kSize - mWritePointer);
+            error            = OT_ERROR_NONE;
+        }
+
+        return error;
+    }
+
+    /**
+     * This method gets the length (number of bytes) in the current frame being written into the buffer.
+     *
+     * @returns The length (number of bytes) in the frame.
+     *
+     */
+    uint16_t GetLength(void) const { return static_cast<uint16_t>(mWritePointer - GetFrame()); }
+
+    /**
+     * This method sets the length (number of bytes) of reserved buffer in front of the current frame being written.
+     *
+     * param[in] aSkipLength  The length of reserved buffer.
+     *
+     * @retval OT_ERROR_NONE     Successfully set the length of reserved buffer.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space to hold a reserved buffer of length @p aLength.
+     *
+     */
+    otError SetSkipLength(uint16_t aSkipLength)
+    {
+        otError error = OT_ERROR_NO_BUFS;
+
+        if (mWriteFrameStart + kHeaderSize + aSkipLength <= OT_ARRAY_END(mBuffer))
+        {
+            Encoding::LittleEndian::WriteUint16(aSkipLength, mWriteFrameStart + kHeaderSkipLengthOffset);
+            mWritePointer    = GetFrame();
+            mRemainingLength = static_cast<uint16_t>(mBuffer + kSize - mWritePointer);
+            error            = OT_ERROR_NONE;
+        }
+
+        return error;
+    }
+
+    /**
+     * This method gets the length (number of bytes) of reserved buffer in front of the current frame being written.
+     *
+     * @returns The length (number of bytes) of the reserved buffer.
+     *
+     */
+    uint16_t GetSkipLength(void) const
+    {
+        return Encoding::LittleEndian::ReadUint16(mWriteFrameStart + kHeaderSkipLengthOffset);
+    }
+
+    /**
+     * This method gets a pointer to the start of the current frame.
+     *
+     * @returns A pointer to the start of the frame.
+     *
+     */
+    uint8_t *GetFrame(void) const { return mWriteFrameStart + kHeaderSize + GetSkipLength(); }
+
+    /**
+     * This method gets the maximum length of the current frame.
+     *
+     * @returns The maximum length of the current frame.
+     *
+     */
+    uint16_t GetFrameMaxLength(void) const { return static_cast<uint16_t>(mBuffer + kSize - GetFrame()); }
+
+    /**
+     * This method saves the current frame and prepares the write pointer for a next frame to be written into the
+     * buffer.
+     *
+     * Saved frame can be retrieved later using `GetNextSavedFrame()`.
+     *
+     */
+    void SaveFrame(void)
+    {
+        Encoding::LittleEndian::WriteUint16(GetSkipLength() + GetLength(), mWriteFrameStart + kHeaderTotalLengthOffset);
+        mWriteFrameStart = mWritePointer;
+        IgnoreError(SetSkipLength(0));
+        mWritePointer    = GetFrame();
+        mRemainingLength = static_cast<uint16_t>(mBuffer + kSize - mWritePointer);
+    }
+
+    /**
+     * This method discards the current frame and prepares the write pointer for a next frame to be written into the
+     * buffer.
+     *
+     */
+    void DiscardFrame(void)
+    {
+        IgnoreError(SetSkipLength(0));
+
+        mWritePointer    = GetFrame();
+        mRemainingLength = static_cast<uint16_t>(mBuffer + kSize - mWritePointer);
+    }
+
+    /**
+     * This method indicates whether there are any saved frames in the buffer.
+     *
+     * @retval TRUE  There is at least one saved frame in the buffer.
+     * @retval FALSE There is no saved frame in the buffer.
+     *
+     */
+    bool HasSavedFrame(void) const { return (mWriteFrameStart != mBuffer); }
+
+    /**
+     * This method iterates through previously saved frames in the buffer, getting a next frame in the queue.
+     *
+     * @param[inout] aFrame   On entry, should point to a previous saved frame or nullptr to get the first frame.
+     *                        On exit, the pointer variable is updated to next frame or set to nullptr if there are
+     * none.
+     * @param[inout] aLength  On entry, should be a reference to the frame length of the previous saved frame.
+     *                        On exit, the reference is updated to the frame length (number of bytes) of next frame.
+     *
+     * @retval OT_ERROR_NONE       Updated @aFrame and @aLength successfully with the next saved frame.
+     * @retval OT_ERROR_NOT_FOUND  No more saved frame in the buffer.
+     *
+     */
+    otError GetNextSavedFrame(uint8_t *&aFrame, uint16_t &aLength)
+    {
+        otError error = OT_ERROR_NONE;
+
+        OT_ASSERT(aFrame == nullptr || (mBuffer <= aFrame && aFrame < OT_ARRAY_END(mBuffer)));
+
+        aFrame = (aFrame == nullptr) ? mBuffer : aFrame + aLength;
+
+        if (aFrame != mWriteFrameStart)
+        {
+            uint16_t totalLength = Encoding::LittleEndian::ReadUint16(aFrame + kHeaderTotalLengthOffset);
+            uint16_t skipLength  = Encoding::LittleEndian::ReadUint16(aFrame + kHeaderSkipLengthOffset);
+
+            aLength = totalLength - skipLength;
+            aFrame += kHeaderSize + skipLength;
+        }
+        else
+        {
+            aLength = 0;
+            aFrame  = nullptr;
+            error   = OT_ERROR_NOT_FOUND;
+        }
+
+        return error;
+    }
+
+    /**
+     * This method clears all saved frames from the buffer and adjusts all the pointers.
+     *
+     * @note This method moves the pointers into the buffer and also copies the content. Any previously retrieved
+     * pointer to buffer (from `GetFrame()` or `GetNextSavedFrame()`) should be considered invalid after calling this
+     * method.
+     *
+     */
+    void ClearSavedFrames(void)
+    {
+        uint16_t len = static_cast<uint16_t>(mWriteFrameStart - mBuffer);
+
+        if (len > 0)
+        {
+            memmove(mBuffer, mWriteFrameStart, static_cast<uint16_t>(mWritePointer - mWriteFrameStart));
+            mWritePointer -= len;
+            mWriteFrameStart -= len;
+            mRemainingLength += len;
+        }
+    }
+
+private:
+    /*
+     * The diagram below illustrates the format of a saved frame.
+     *
+     *  +---------+-------------+------------+----------------+----------------------------+
+     *  | Octets: |      2      |      2     |   SkipLength   |  TotalLength - SkipLength  |
+     *  +---------+-------------+------------+----------------+----------------------------+
+     *  | Fields: | TotalLength | SkipLength | ReservedBuffer |         FrameBuffer        |
+     *  +---------+-------------+------------+----------------+----------------------------+
+     *
+     *   -  "TotalLength"   : The total length of the `ReservedBuffer` and `FrameBuffer`. It is stored in header bytes
+     *                        as a `uint16_t` value using little-endian encoding.
+     *   -  "SkipLength"    : The length of the `ReservedBuffer`. It is stored in header bytes as a `uint16_t` value
+     *                        using little-endian encoding.
+     *   -  "ReservedBuffer": A reserved buffer in front of `FrameBuffer`. User can use it to store extra header, etc.
+     *   -  "FrameBuffer"   : Frame buffer.
+     *
+     * The diagram below illustrates how the frames are saved in the buffer.
+     *
+     * The diagram shows `mBuffer` and different pointers into the buffer. It represents buffer state when there are
+     * two saved frames in the buffer.
+     *
+     *          Saved frame #1           Saved frame #2       Current frame being written
+     *   /                        \ /                      \ /                           \
+     *   +-----------+-------------+-----------+------------+---------+--------------------------------------------+
+     *   | header #1 |   ...       | header #2 |  ...       | header  |  ...             | ...                     |
+     *   +-----------+-------------+-----------+------------+---------+--------------------------------------------+
+     *   ^                                                  ^                            ^\                       /^
+     *   |                                                  |                            |   mRemainingLength      |
+     *  mBuffer[0]                                          mWriteFrameStart             |                         |
+     *                                                                                   |              mBuffer[kSize]
+     *                                                                                 mWritePointer
+     */
+
+    enum
+    {
+        kHeaderTotalLengthOffset = 0,
+        kHeaderSkipLengthOffset  = sizeof(uint16_t),
+        kHeaderSize              = sizeof(uint16_t) + sizeof(uint16_t),
+    };
+
+    uint8_t  mBuffer[kSize];
+    uint8_t *mWriteFrameStart; // Pointer to start of current frame being written.
+};
+
+/**
+ * This class implements the HDLC-lite encoder.
+ *
+ */
+class Encoder
+{
+public:
+    /**
+     * This constructor initializes the object.
+     *
+     * @param[in] aWritePointer   The `FrameWritePointer` used by `Encoder` to write the encoded frames.
+     *
+     */
+    explicit Encoder(FrameWritePointer &aWritePointer);
+
+    /**
+     * This method begins an HDLC frame.
+     *
+     * @retval OT_ERROR_NONE     Successfully started the HDLC frame.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to start the HDLC frame.
+     *
+     */
+    otError BeginFrame(void);
+
+    /**
+     * This method encodes a single byte into current frame.
+     *
+     * If there is no space to add the byte, the write pointer in frame buffer remains the same.
+     *
+     * @param[in]    aByte       A byte value to encode and add to frame.
+     *
+     * @retval OT_ERROR_NONE     Successfully encoded and added the byte to frame buffer.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to encode and add the byte.
+     *
+     */
+    otError Encode(uint8_t aByte);
+
+    /**
+     * This method encodes a given block of data into current frame.
+     *
+     * This method returns success only if there is space in buffer to encode the entire block of data. If there is no
+     * space to encode the entire block of data, the write pointer in frame buffer remains the same.
+     *
+     * @param[in]    aData       A pointer to a buffer containing the data to encode.
+     * @param[in]    aLength     The number of bytes in @p aData.
+     *
+     * @retval OT_ERROR_NONE     Successfully encoded and added the data to frame.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to add the frame.
+     *
+     */
+    otError Encode(const uint8_t *aData, uint16_t aLength);
+
+    /**
+     * This method ends/finalizes the HDLC frame.
+     *
+     * @retval OT_ERROR_NONE     Successfully ended the HDLC frame.
+     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to end the HDLC frame.
+     *
+     */
+    otError EndFrame(void);
+
+private:
+    FrameWritePointer &mWritePointer;
+    uint16_t           mFcs;
+};
+
+/**
+ * This class implements the HDLC-lite decoder.
+ *
+ */
+class Decoder
+{
+public:
+    /**
+     * This function pointer is called when either a complete frame has been decoded or an error occurs during
+     * decoding.
+     *
+     * The decoded frame (or the partially decoded frame in case of an error) is available in `aFrameWritePointer`
+     * buffer given in `Decoder` constructor.
+     *
+     * @param[in] aContext A pointer to arbitrary context information.
+     * @param[in] aError   OT_ERROR_NONE    if the frame was decoded successfully,
+     *                     OT_ERROR_PARSE   if the Frame Check Sequence (FCS) was incorrect in decoded frame,
+     *                     OT_ERROR_NO_BUFS insufficient buffer space available to save the decoded frame.
+     *
+     */
+    typedef void (*FrameHandler)(void *aContext, otError aError);
+
+    /**
+     * This constructor initializes the decoder.
+     *
+     * @param[in] aFrameWritePointer   The `FrameWritePointer` used by `Decoder` to write the decoded frames.
+     * @param[in] aFrameHandler        The frame handler callback function pointer.
+     * @param[in] aContext             A pointer to arbitrary context information.
+     *
+     */
+    Decoder(FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext);
+
+    /**
+     * This method feeds a block of data into the decoder.
+     *
+     * If during decoding, a full HDLC frame is successfully decoded or an error occurs, the `FrameHandler` callback
+     * is called. The decoded frame (or the partially decoded frame in case of an error) is available in
+     * `aFrameWritePointer` buffer from the constructor. The `Decoder` user (if required) must update/reset the write
+     * pointer from this callback for the next frame to be decoded.
+     *
+     * @param[in]  aData    A pointer to a buffer containing data to be fed to decoder.
+     * @param[in]  aLength  The number of bytes in @p aData.
+     *
+     */
+    void Decode(const uint8_t *aData, uint16_t aLength);
+
+private:
+    enum State
+    {
+        kStateNoSync,
+        kStateSync,
+        kStateEscaped,
+    };
+
+    State              mState;
+    FrameWritePointer &mWritePointer;
+    FrameHandler       mFrameHandler;
+    void *             mContext;
+    uint16_t           mFcs;
+    uint16_t           mDecodedLength;
+};
+
+} // namespace Hdlc
+} // namespace ot
+
+#endif // HDLC_HPP_
diff --git a/src/lib/platform/CMakeLists.txt b/src/lib/platform/CMakeLists.txt
new file mode 100644
index 0000000..198140a
--- /dev/null
+++ b/src/lib/platform/CMakeLists.txt
@@ -0,0 +1,44 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_library(openthread-platform
+    exit_code.c
+    exit_code.h
+)
+
+target_include_directories(openthread-platform
+    PUBLIC
+        ${OT_PUBLIC_INCLUDES}
+        ${PROJECT_SOURCE_DIR}/src/
+)
+
+target_link_libraries(openthread-platform PRIVATE ot-config)
+
+target_compile_options(openthread-platform PRIVATE
+    ${OT_CFLAGS}
+)
diff --git a/src/lib/platform/Makefile.am b/src/lib/platform/Makefile.am
new file mode 100644
index 0000000..70f8611
--- /dev/null
+++ b/src/lib/platform/Makefile.am
@@ -0,0 +1,43 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+
+noinst_LIBRARIES = libopenthread-platform.a
+
+libopenthread_platform_a_CPPFLAGS           = \
+    -I$(top_srcdir)/include                   \
+    -I$(top_srcdir)/src/core                  \
+    $(NULL)
+
+libopenthread_platform_a_SOURCES            = \
+    exit_code.c                               \
+    exit_code.h                               \
+    $(NULL)
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/src/lib/platform/exit_code.c b/src/lib/platform/exit_code.c
new file mode 100644
index 0000000..370b3b6
--- /dev/null
+++ b/src/lib/platform/exit_code.c
@@ -0,0 +1,85 @@
+/*
+ *    Copyright (c) 2020, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements exit code utilities.
+ */
+
+#include "exit_code.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+const char *otExitCodeToString(uint8_t aExitCode)
+{
+    const char *retval = NULL;
+
+    switch (aExitCode)
+    {
+    case OT_EXIT_SUCCESS:
+        retval = "Success";
+        break;
+
+    case OT_EXIT_FAILURE:
+        retval = "Failure";
+        break;
+
+    case OT_EXIT_INVALID_ARGUMENTS:
+        retval = "InvalidArgument";
+        break;
+
+    case OT_EXIT_RADIO_SPINEL_INCOMPATIBLE:
+        retval = "RadioSpinelIncompatible";
+        break;
+
+    case OT_EXIT_RADIO_SPINEL_RESET:
+        retval = "RadioSpinelReset";
+        break;
+
+    case OT_EXIT_RADIO_SPINEL_NO_RESPONSE:
+        retval = "RadioSpinelNoResponse";
+        break;
+
+    case OT_EXIT_ERROR_ERRNO:
+#ifdef errno
+        retval = strerror(errno);
+#else
+        retval = "ErrorNo";
+#endif
+        break;
+
+    default:
+        assert(false);
+        retval = "UnknownExitCode";
+        break;
+    }
+
+    return retval;
+}
diff --git a/src/lib/platform/exit_code.h b/src/lib/platform/exit_code.h
new file mode 100644
index 0000000..81a3321
--- /dev/null
+++ b/src/lib/platform/exit_code.h
@@ -0,0 +1,152 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file contains header for exit code utilities.
+ */
+
+#ifndef PLATFORM_EXIT_CODE_H_
+#define PLATFORM_EXIT_CODE_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This enumeration represents exit codes used when OpenThread exits.
+ *
+ */
+enum
+{
+    /**
+     * Success.
+     */
+    OT_EXIT_SUCCESS = 0,
+
+    /**
+     * Generic failure.
+     */
+    OT_EXIT_FAILURE = 1,
+
+    /**
+     * Invalid arguments.
+     */
+    OT_EXIT_INVALID_ARGUMENTS = 2,
+
+    /**
+     * Incompatible radio spinel.
+     */
+    OT_EXIT_RADIO_SPINEL_INCOMPATIBLE = 3,
+
+    /**
+     * Unexpected radio spinel reset.
+     */
+    OT_EXIT_RADIO_SPINEL_RESET = 4,
+
+    /**
+     * System call or library function error.
+     */
+    OT_EXIT_ERROR_ERRNO = 5,
+
+    /**
+     * No response from radio spinel.
+     */
+    OT_EXIT_RADIO_SPINEL_NO_RESPONSE = 6,
+};
+
+/**
+ * This function converts an exit code into a string.
+ *
+ * @param[in]  aExitCode  An exit code.
+ *
+ * @returns  A string representation of an exit code.
+ *
+ */
+const char *otExitCodeToString(uint8_t aExitCode);
+
+/**
+ * This macro checks for the specified condition, which is expected to commonly be true,
+ * and both records exit status and terminates the program if the condition is false.
+ *
+ * @param[in]   aCondition  The condition to verify
+ * @param[in]   aExitCode   The exit code.
+ *
+ */
+#define VerifyOrDie(aCondition, aExitCode)                                                                   \
+    do                                                                                                       \
+    {                                                                                                        \
+        if (!(aCondition))                                                                                   \
+        {                                                                                                    \
+            otLogCritPlat("%s() at %s:%d: %s", __func__, __FILE__, __LINE__, otExitCodeToString(aExitCode)); \
+            exit(aExitCode);                                                                                 \
+        }                                                                                                    \
+    } while (false)
+
+/**
+ * This macro checks for the specified error code, which is expected to commonly be successful,
+ * and both records exit status and terminates the program if the error code is unsuccessful.
+ *
+ * @param[in]  aError  An error code to be evaluated against OT_ERROR_NONE.
+ *
+ */
+#define SuccessOrDie(aError)             \
+    VerifyOrDie(aError == OT_ERROR_NONE, \
+                (aError == OT_ERROR_INVALID_ARGS ? OT_EXIT_INVALID_ARGUMENTS : OT_EXIT_FAILURE))
+
+/**
+ * This macro unconditionally both records exit status and terminates the program.
+ *
+ * @param[in]   aExitCode   The exit code.
+ *
+ */
+#define DieNow(aExitCode) VerifyOrDie(false, aExitCode)
+
+/**
+ * This macro unconditionally both records exit status and exit message and terminates the program.
+ *
+ * @param[in]   aMessage    The exit message.
+ * @param[in]   aExitCode   The exit code.
+ *
+ */
+#define DieNowWithMessage(aMessage, aExitCode)                                                 \
+    do                                                                                         \
+    {                                                                                          \
+        otLogCritPlat("exit(%d): %s line %d, %s, %s", aExitCode, __func__, __LINE__, aMessage, \
+                      otExitCodeToString(aExitCode));                                          \
+        exit(aExitCode);                                                                       \
+    } while (false)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PLATFORM_EXIT_CODE_H_
diff --git a/src/lib/spinel/CMakeLists.txt b/src/lib/spinel/CMakeLists.txt
new file mode 100644
index 0000000..f7b24ba
--- /dev/null
+++ b/src/lib/spinel/CMakeLists.txt
@@ -0,0 +1,78 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_library(openthread-spinel-ncp)
+add_library(openthread-spinel-rcp)
+
+set_target_properties(
+    openthread-spinel-ncp openthread-spinel-rcp
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_compile_definitions(openthread-spinel-ncp PRIVATE
+    OPENTHREAD_FTD=1
+    OPENTHREAD_CONFIG_NCP_UART_ENABLE=1
+    PUBLIC OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1
+)
+
+target_compile_definitions(openthread-spinel-rcp PRIVATE
+    OPENTHREAD_RADIO=1
+    OPENTHREAD_CONFIG_NCP_UART_ENABLE=1
+    PUBLIC OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=0
+)
+
+target_compile_options(openthread-spinel-ncp PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_compile_options(openthread-spinel-rcp PRIVATE
+    ${OT_CFLAGS}
+)
+
+set(COMMON_INCLUDES
+    ${PROJECT_SOURCE_DIR}/src
+    ${PROJECT_SOURCE_DIR}/src/core
+)
+
+set(COMMON_SOURCES
+    spinel.c
+    spinel_buffer.cpp
+    spinel_decoder.cpp
+    spinel_encoder.cpp
+)
+
+target_include_directories(openthread-spinel-ncp PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
+target_include_directories(openthread-spinel-rcp PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
+
+target_sources(openthread-spinel-ncp PRIVATE ${COMMON_SOURCES})
+target_sources(openthread-spinel-rcp PRIVATE ${COMMON_SOURCES})
+
+target_link_libraries(openthread-spinel-ncp PRIVATE ot-config)
+target_link_libraries(openthread-spinel-rcp PRIVATE ot-config)
diff --git a/src/lib/spinel/Makefile.am b/src/lib/spinel/Makefile.am
new file mode 100644
index 0000000..af1fa20
--- /dev/null
+++ b/src/lib/spinel/Makefile.am
@@ -0,0 +1,121 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+
+noinst_LIBRARIES                                  =
+
+if OPENTHREAD_ENABLE_FTD
+noinst_LIBRARIES                                 += libopenthread-spinel-ncp.a
+endif
+
+if OPENTHREAD_ENABLE_MTD
+noinst_LIBRARIES                                 += libopenthread-spinel-ncp.a
+endif
+
+if OPENTHREAD_ENABLE_RADIO_ONLY
+noinst_LIBRARIES                                 += libopenthread-spinel-rcp.a
+endif
+
+COMMON_CPPFLAGS                                   = \
+    -I$(top_srcdir)/include                         \
+    -I$(top_srcdir)/src                             \
+    -I$(top_srcdir)/src/core                        \
+    -I$(top_srcdir)/third_party                     \
+    -D_GNU_SOURCE                                   \
+    -DSPINEL_PLATFORM_HEADER=\"spinel_platform.h\"  \
+    $(OPENTHREAD_TARGET_DEFINES)                    \
+    $(NULL)
+
+COMMON_SOURCES                                    = \
+    spinel.c                                        \
+    spinel_buffer.cpp                               \
+    spinel_decoder.cpp                              \
+    spinel_encoder.cpp                              \
+    $(NULL)
+
+ot_spinel_headers                                 = \
+    spinel.h                                        \
+    $(NULL)
+
+ot_spineldir = $(includedir)/spinel
+dist_ot_spinel_HEADERS = $(ot_spinel_headers)
+
+include_HEADERS                                   = \
+    $(NULL)
+
+noinst_HEADERS                                    = \
+    radio_spinel.hpp                                \
+    radio_spinel_impl.hpp                           \
+    spinel_buffer.hpp                               \
+    spinel_decoder.hpp                              \
+    spinel_encoder.hpp                              \
+    spinel_platform.h                               \
+    openthread-spinel-config.h                      \
+    $(NULL)
+
+libopenthread_spinel_ncp_a_CPPFLAGS                      = \
+    -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1 \
+    $(COMMON_CPPFLAGS)                                     \
+    $(NULL)
+
+libopenthread_spinel_ncp_a_SOURCES                = \
+    $(COMMON_SOURCES)                               \
+    $(NULL)
+
+libopenthread_spinel_rcp_a_CPPFLAGS                      = \
+    -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=0 \
+    $(COMMON_CPPFLAGS)                                     \
+    $(NULL)
+
+libopenthread_spinel_rcp_a_SOURCES                = \
+    $(COMMON_SOURCES)                               \
+    $(NULL)
+
+if OPENTHREAD_BUILD_TESTS
+
+check_PROGRAMS                                    = spinel-test
+spinel_test_SOURCES                               = spinel.c
+spinel_test_CFLAGS                                = \
+    $(COMMON_CPPFLAGS)                              \
+    -DSPINEL_SELF_TEST=1                            \
+    -D_GNU_SOURCE                                   \
+    -I$(top_srcdir)/src/core                        \
+    -I$(top_srcdir)/include                         \
+    $(NULL)
+
+TESTS                                             = spinel-test
+
+install-headers: install-includeHEADERS
+
+if OPENTHREAD_BUILD_COVERAGE
+CLEANFILES                                        = $(wildcard *.gcda *.gcno)
+endif # OPENTHREAD_BUILD_COVERAGE
+endif # OPENTHREAD_BUILD_TESTS
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/src/lib/spinel/openthread-spinel-config.h b/src/lib/spinel/openthread-spinel-config.h
new file mode 100644
index 0000000..390e3e3
--- /dev/null
+++ b/src/lib/spinel/openthread-spinel-config.h
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes compile-time configuration constants for OpenThread.
+ */
+
+#ifndef OPENTHREAD_SPINEL_CONFIG_H_
+#define OPENTHREAD_SPINEL_CONFIG_H_
+
+/**
+ * @def OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+ *
+ * Define 1 to enable feeding an OpenThread message to encoder/decoder.
+ *
+ */
+#ifndef OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+#define OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE 0
+#endif
+
+#endif // OPENTHREAD_SPINEL_CONFIG_H_
diff --git a/src/lib/spinel/radio_spinel.hpp b/src/lib/spinel/radio_spinel.hpp
new file mode 100644
index 0000000..c228a5a
--- /dev/null
+++ b/src/lib/spinel/radio_spinel.hpp
@@ -0,0 +1,887 @@
+/*
+ *  Copyright (c) 2018, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for the spinel based radio transceiver.
+ */
+
+#ifndef RADIO_SPINEL_HPP_
+#define RADIO_SPINEL_HPP_
+
+#include <openthread/platform/radio.h>
+
+#include "spinel.h"
+#include "spinel_interface.hpp"
+#include "ncp/ncp_config.h"
+
+namespace ot {
+namespace Spinel {
+
+/**
+ * The class for providing a OpenThread radio interface by talking with a radio-only
+ * co-procesor(RCP). The InterfaceType template parameter should provide the following
+ * methods:
+ *
+ * class InterfaceType {
+ *
+ *    // This constructor initializes the object.
+ *
+ *    // @param[in] aCallback         Callback on frame received
+ *    // @param[in] aCallbackContext  Callback context
+ *    // @param[in] aFrameBuffer      A reference to a `RxFrameBuffer` object.
+ *
+ *    InterFaceType(Spinel::SpinelInterface::ReceiveFrameCallback aCallback,
+ *                  void *                                        aCallbackContext,
+ *                  Spinel::SpinelInterface::RxFrameBuffer &      aFrameBuffer);
+ *
+ *
+ *    // This method encodes and sends a spinel frame to Radio Co-processor (RCP) over the socket.
+ *
+ *    // This is blocking call, i.e., if the socket is not writable, this method waits for it to become writable for
+ *    // up to `kMaxWaitTime` interval.
+ *
+ *    // @param[in] aFrame     A pointer to buffer containing the spinel frame to send.
+ *    // @param[in] aLength    The length (number of bytes) in the frame.
+ *
+ *    // @retval OT_ERROR_NONE     Successfully encoded and sent the spinel frame.
+ *    // @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to encode the frame.
+ *    // @retval OT_ERROR_FAILED   Failed to send due to socket not becoming writable within `kMaxWaitTime`.
+ *
+ *    otError SendFrame(const uint8_t *aFrame, uint16_t aLength);
+ *
+ *
+ *    // This method waits for receiving part or all of spinel frame within specified interval.
+ *
+ *    // @param[in]  aTimeout  The timeout value in micrsoseconds.
+ *
+ *    // @retval OT_ERROR_NONE             Part or all of spinel frame is received.
+ *    // @retval OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p aTimeout.
+ *
+ *    otError WaitForFrame(uint64_t& aTimeoutUs);
+ *
+ *
+ *    // This method performs radio driver processing.
+ *
+ *    // @param[in]   aContext        The context containing fd_sets.
+ *    //                              The type is specified by the user in template parameters.
+ *
+ *    void Process(const ProcessContextType &aContext);
+ *
+ *
+ *    // This method deinitializes the interface to the RCP.
+ *
+ *    void Deinit(void);
+ * };
+ */
+template <typename InterfaceType, typename ProcessContextType> class RadioSpinel
+{
+public:
+    /**
+     * This constructor initializes the spinel based OpenThread transceiver.
+     *
+     */
+    RadioSpinel(void);
+
+    /**
+     * Initialize this radio transceiver.
+     *
+     * @param[in]  aResetRadio            TRUE to reset on init, FALSE to not reset on init.
+     * @param[in]  aRestoreDatasetFromNcp TRUE to restore dataset to host from non-volatile memory
+     *                                    (only used when attempts to upgrade from NCP to RCP mode),
+     *                                    FALSE otherwise.
+     *
+     */
+    void Init(bool aResetRadio, bool aRestoreDataSetFromNcp);
+
+    /**
+     * Deinitialize this radio transceiver.
+     *
+     */
+    void Deinit(void);
+
+    /**
+     * This method gets the status of promiscuous mode.
+     *
+     * @retval true   Promiscuous mode is enabled.
+     * @retval false  Promiscuous mode is disabled.
+     *
+     */
+    bool IsPromiscuous(void) const { return mIsPromiscuous; }
+
+    /**
+     * This method sets the status of promiscuous mode.
+     *
+     * @param[in]   aEnable     Whether to enable or disable promiscuous mode.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError SetPromiscuous(bool aEnable);
+
+    /**
+     * This method sets the Short Address for address filtering.
+     *
+     * @param[in] aShortAddress  The IEEE 802.15.4 Short Address.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError SetShortAddress(uint16_t aAddress);
+
+    /**
+     * This method gets the factory-assigned IEEE EUI-64 for this transceiver.
+     *
+     * @param[in]  aInstance   The OpenThread instance structure.
+     * @param[out] aIeeeEui64  A pointer to the factory-assigned IEEE EUI-64.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError GetIeeeEui64(uint8_t *aIeeeEui64);
+
+    /**
+     * This method sets the Extended Address for address filtering.
+     *
+     * @param[in] aExtAddress  A pointer to the IEEE 802.15.4 Extended Address stored in little-endian byte order.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError SetExtendedAddress(const otExtAddress &aAddress);
+
+    /**
+     * This method sets the PAN ID for address filtering.
+     *
+     * @param[in]   aPanId  The IEEE 802.15.4 PAN ID.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError SetPanId(uint16_t aPanId);
+
+    /**
+     * This method gets the radio's transmit power in dBm.
+     *
+     * @param[out]  aPower    The transmit power in dBm.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError GetTransmitPower(int8_t &aPower);
+
+    /**
+     * This method sets the radio's transmit power in dBm.
+     *
+     * @param[in]   aPower     The transmit power in dBm.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError SetTransmitPower(int8_t aPower);
+
+    /**
+     * This method gets the radio's CCA ED threshold in dBm.
+     *
+     * @param[out]  aThreshold    The CCA ED threshold in dBm.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError GetCcaEnergyDetectThreshold(int8_t &aThreshold);
+
+    /**
+     * This method sets the radio's CCA ED threshold in dBm.
+     *
+     * @param[in]   aThreshold     The CCA ED threshold in dBm.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError SetCcaEnergyDetectThreshold(int8_t aThreshold);
+
+    /**
+     * This method returns the radio sw version string.
+     *
+     * @returns A pointer to the radio version string.
+     *
+     */
+    const char *GetVersion(void) const { return mVersion; }
+
+    /**
+     * This method returns the radio capabilities.
+     *
+     * @returns The radio capability bit vector.
+     *
+     */
+    otRadioCaps GetRadioCaps(void) const { return mRadioCaps; }
+
+    /**
+     * This method gets the most recent RSSI measurement.
+     *
+     * @returns The RSSI in dBm when it is valid.  127 when RSSI is invalid.
+     */
+    int8_t GetRssi(void);
+
+    /**
+     * This method returns the radio receive sensitivity value.
+     *
+     * @returns The radio receive sensitivity value in dBm.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    int8_t GetReceiveSensitivity(void) const { return mRxSensitivity; }
+
+    /**
+     * This method gets current state of the radio.
+     *
+     * @return  Current state of the radio.
+     *
+     */
+    otRadioState GetState(void) const;
+
+    /**
+     * This method gets the current receiving channel.
+     *
+     * @returns Current receiving channel.
+     *
+     */
+    uint8_t GetChannel(void) const { return mChannel; }
+
+#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
+    /**
+     * Enable the radio coex.
+     *
+     * @param[in] aInstance  The OpenThread instance structure.
+     * @param[in] aEnabled   TRUE to enable the radio coex, FALSE otherwise.
+     *
+     * @retval OT_ERROR_NONE     Successfully enabled.
+     * @retval OT_ERROR_FAILED   The radio coex could not be enabled.
+     *
+     */
+    otError SetCoexEnabled(bool aEnabled);
+
+    /**
+     * Check whether radio coex is enabled or not.
+     *
+     * @param[in] aInstance  The OpenThread instance structure.
+     *
+     * @returns TRUE if the radio coex is enabled, FALSE otherwise.
+     *
+     */
+    bool IsCoexEnabled(void);
+
+    /**
+     * This method retrieves the radio coexistence metrics.
+     *
+     * @param[out] aCoexMetrics  A reference to the coexistence metrics structure.
+     *
+     * @retval OT_ERROR_NONE          Successfully retrieved the coex metrics.
+     * @retval OT_ERROR_INVALID_ARGS  @p aCoexMetrics was nullptr.
+     *
+     */
+    otError GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics);
+#endif
+
+    /**
+     * This method returns a reference to the transmit buffer.
+     *
+     * The caller forms the IEEE 802.15.4 frame in this buffer then calls otPlatRadioTransmit() to request transmission.
+     *
+     * @returns A reference to the transmit buffer.
+     *
+     */
+    otRadioFrame &GetTransmitFrame(void) { return mTxRadioFrame; }
+
+    /**
+     * This method enables or disables source address match feature.
+     *
+     * @param[in]  aEnable     Enable/disable source address match feature.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError EnableSrcMatch(bool aEnable);
+
+    /**
+     * This method adds a short address to the source address match table.
+     *
+     * @param[in]  aInstance      The OpenThread instance structure.
+     * @param[in]  aShortAddress  The short address to be added.
+     *
+     * @retval  OT_ERROR_NONE               Successfully added short address to the source match table.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     * @retval  OT_ERROR_NO_BUFS            No available entry in the source match table.
+     */
+    otError AddSrcMatchShortEntry(uint16_t aShortAddress);
+
+    /**
+     * This method removes a short address from the source address match table.
+     *
+     * @param[in]  aInstance      The OpenThread instance structure.
+     * @param[in]  aShortAddress  The short address to be removed.
+     *
+     * @retval  OT_ERROR_NONE               Successfully removed short address from the source match table.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     * @retval  OT_ERROR_NO_ADDRESS         The short address is not in source address match table.
+     */
+    otError ClearSrcMatchShortEntry(uint16_t aShortAddress);
+
+    /**
+     * Clear all short addresses from the source address match table.
+     *
+     * @param[in]  aInstance   The OpenThread instance structure.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError ClearSrcMatchShortEntries(void);
+
+    /**
+     * Add an extended address to the source address match table.
+     *
+     * @param[in]  aInstance    The OpenThread instance structure.
+     * @param[in]  aExtAddress  The extended address to be added stored in little-endian byte order.
+     *
+     * @retval  OT_ERROR_NONE               Successfully added extended address to the source match table.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     * @retval  OT_ERROR_NO_BUFS            No available entry in the source match table.
+     */
+    otError AddSrcMatchExtEntry(const otExtAddress &aExtAddress);
+
+    /**
+     * Remove an extended address from the source address match table.
+     *
+     * @param[in]  aInstance    The OpenThread instance structure.
+     * @param[in]  aExtAddress  The extended address to be removed stored in little-endian byte order.
+     *
+     * @retval  OT_ERROR_NONE               Successfully removed the extended address from the source match table.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     * @retval  OT_ERROR_NO_ADDRESS         The extended address is not in source address match table.
+     */
+    otError ClearSrcMatchExtEntry(const otExtAddress &aExtAddress);
+
+    /**
+     * Clear all the extended/long addresses from source address match table.
+     *
+     * @param[in]  aInstance   The OpenThread instance structure.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError ClearSrcMatchExtEntries(void);
+
+    /**
+     * This method begins the energy scan sequence on the radio.
+     *
+     * @param[in]  aScanChannel     The channel to perform the energy scan on.
+     * @param[in]  aScanDuration    The duration, in milliseconds, for the channel to be scanned.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration);
+
+    /**
+     * This method switches the radio state from Receive to Transmit.
+     *
+     * @param[in] aFrame     A reference to the transmitted frame.
+     *
+     * @retval  OT_ERROR_NONE               Successfully transitioned to Transmit.
+     * @retval  OT_ERROR_BUSY               Failed due to another transmission is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     * @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state.
+     */
+    otError Transmit(otRadioFrame &aFrame);
+
+    /**
+     * This method switches the radio state from Sleep to Receive.
+     *
+     * @param[in]  aChannel   The channel to use for receiving.
+     *
+     * @retval OT_ERROR_NONE          Successfully transitioned to Receive.
+     * @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting.
+     *
+     */
+    otError Receive(uint8_t aChannel);
+
+    /**
+     * This method switches the radio state from Receive to Sleep.
+     *
+     * @retval OT_ERROR_NONE          Successfully transitioned to Sleep.
+     * @retval OT_ERROR_BUSY          The radio was transmitting
+     * @retval OT_ERROR_INVALID_STATE The radio was disabled
+     *
+     */
+    otError Sleep(void);
+
+    /**
+     * Enable the radio.
+     *
+     * @param[in]   aInstance   A pointer to the OpenThread instance.
+     *
+     * @retval OT_ERROR_NONE     Successfully enabled.
+     * @retval OT_ERROR_FAILED   The radio could not be enabled.
+     *
+     */
+    otError Enable(otInstance *aInstance);
+
+    /**
+     * Disable the radio.
+     *
+     * @retval  OT_ERROR_NONE               Successfully transitioned to Disabled.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError Disable(void);
+
+    /**
+     * This method checks whether radio is enabled or not.
+     *
+     * @returns TRUE if the radio is enabled, FALSE otherwise.
+     *
+     */
+    bool IsEnabled(void) const { return mState != kStateDisabled; }
+
+    /**
+     * This method indicates whether there is a pending transmission.
+     *
+     * @retval TRUE  There is a pending transmission.
+     * @retval FALSE There is no pending transmission.
+     *
+     */
+    bool IsTransmitting(void) const { return mState == kStateTransmitting; }
+
+    /**
+     * This method indicates whether a transmit has just finished.
+     *
+     * @retval TRUE  The trasmission is done.
+     * @retval FALSE The trasmission is not done.
+     *
+     */
+    bool IsTransmitDone(void) const { return mState == kStateTransmitDone; }
+
+    /**
+     * This method returns the timeout timepoint for the pending transmission.
+     *
+     * @returns The timeout timepoint for the pending transmission.
+     *
+     */
+    uint64_t GetTxRadioEndUs(void) const { return mTxRadioEndUs; }
+
+    /**
+     * This method processes any pending the I/O data.
+     *
+     * @param[in]  aContext   The process context.
+     *
+     */
+    void Process(const ProcessContextType &aContext);
+
+    /**
+     * This method returns the underlying spinel interface.
+     *
+     * @returns The underlying spinel interface.
+     *
+     */
+    InterfaceType &GetSpinelInterface(void) { return mSpinelInterface; }
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+    /**
+     * This method enables/disables the factory diagnostics mode.
+     *
+     * @param[in]  aMode  TRUE to enable diagnostics mode, FALSE otherwise.
+     *
+     */
+    void SetDiagEnabled(bool aMode) { mDiagMode = aMode; }
+
+    /**
+     * This method indicates whether or not factory diagnostics mode is enabled.
+     *
+     * @returns TRUE if factory diagnostics mode is enabled, FALSE otherwise.
+     *
+     */
+    bool IsDiagEnabled(void) const { return mDiagMode; }
+
+    /**
+     * This method processes platform diagnostics commands.
+     *
+     * @param[in]   aString         A null-terminated input string.
+     * @param[out]  aOutput         The diagnostics execution result.
+     * @param[in]   aOutputMaxLen   The output buffer size.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError PlatDiagProcess(const char *aString, char *aOutput, size_t aOutputMaxLen);
+#endif
+
+    /**
+     * This method returns the radio channel mask.
+     *
+     * @param[in]   aPreferred  TRUE to get preferred channel mask, FALSE to get supported channel mask.
+     *
+     * @returns The radio channel mask according to @aPreferred:
+     *   The radio supported channel mask that the device is allowed to be on.
+     *   The radio preferred channel mask that the device prefers to form on.
+     *
+     */
+    uint32_t GetRadioChannelMask(bool aPreferred);
+
+    /**
+     * This method processes a received Spinel frame.
+     *
+     * The newly received frame is available in `RxFrameBuffer` from `SpinelInterface::GetRxFrameBuffer()`.
+     *
+     */
+    void HandleReceivedFrame(void);
+
+    /**
+     * This method sets MAC key and key index to RCP.
+     *
+     * @param[in] aKeyIdMode  The key ID mode.
+     * @param[in] aKeyId      The key index.
+     * @param[in] aPrevKey    The previous MAC key.
+     * @param[in] aCurrKey    The current MAC key.
+     * @param[in] aNextKey    The next MAC key.
+     *
+     * @retval  OT_ERROR_NONE               Succeeded.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError SetMacKey(uint8_t         aKeyIdMode,
+                      uint8_t         aKeyId,
+                      const otMacKey &aPrevKey,
+                      const otMacKey &aCurrKey,
+                      const otMacKey &aNextKey);
+
+    /**
+     * This method sets the current MAC Frame Counter value.
+     *
+     * @param[in]   aMacFrameCounter  The MAC Frame Counter value.
+     *
+     */
+    otError SetMacFrameCounter(uint32_t aMacFrameCounter);
+
+    /**
+     * This method checks whether the spinel interface is radio-only
+     *
+     * @retval  TRUE    The radio chip is in radio-only mode.
+     * @retval  FALSE   Otherwise.
+     *
+     */
+    bool IsRcp(void);
+
+    /**
+     * This method checks whether there is pending frame in the buffer.
+     *
+     * @returns Whether there is pending frame in the buffer.
+     *
+     */
+    bool HasPendingFrame(void) const { return mRxFrameBuffer.HasSavedFrame(); }
+
+    /**
+     * This method gets dataset from NCP radio and saves it.
+     *
+     * @retval  OT_ERROR_NONE               Successfully restore dataset.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the radio.
+     * @retval  OT_ERROR_NOT_FOUND          Failed due to spinel property not supported in radio.
+     * @retval  OT_ERROR_FAILED             Failed due to other reasons.
+     */
+    otError RestoreDatasetFromNcp(void);
+
+    /**
+     * This method returns the next timepoint to recalculate RCP time offset.
+     *
+     * @returns The timepoint to start the recalculation of RCP time offset.
+     *
+     */
+    uint64_t GetNextRadioTimeRecalcStart(void) const { return mRadioTimeRecalcStart; }
+
+    /**
+     * This method gets the current estimated time on RCP.
+     *
+     * @returns The current estimated RCP time in microseconds.
+     *
+     */
+    uint64_t GetNow(void);
+
+private:
+    enum
+    {
+        kMaxSpinelFrame        = SpinelInterface::kMaxFrameSize,
+        kMaxWaitTime           = 2000, ///< Max time to wait for response in milliseconds.
+        kVersionStringSize     = 128,  ///< Max size of version string.
+        kCapsBufferSize        = 100,  ///< Max buffer size used to store `SPINEL_PROP_CAPS` value.
+        kChannelMaskBufferSize = 32,   ///< Max buffer size used to store `SPINEL_PROP_PHY_CHAN_SUPPORTED` value.
+    };
+
+    enum State
+    {
+        kStateDisabled,     ///< Radio is disabled.
+        kStateSleep,        ///< Radio is sleep.
+        kStateReceive,      ///< Radio is in receive mode.
+        kStateTransmitting, ///< Frame passed to radio for transmission, waiting for done event from radio.
+        kStateTransmitDone, ///< Radio indicated frame transmission is done.
+    };
+
+    typedef otError (RadioSpinel::*ResponseHandler)(const uint8_t *aBuffer, uint16_t aLength);
+
+    static void HandleReceivedFrame(void *aContext);
+
+    otError CheckSpinelVersion(void);
+    otError CheckRadioCapabilities(void);
+
+    /**
+     * This method triggers a state transfer of the state machine.
+     *
+     */
+    void ProcessRadioStateMachine(void);
+
+    /**
+     * This method processes the frame queue.
+     *
+     */
+    void ProcessFrameQueue(void);
+
+    /**
+     * This method tries to retrieve a spinel property from OpenThread transceiver.
+     *
+     * @param[in]   aKey        Spinel property key.
+     * @param[in]   aFormat     Spinel formatter to unpack property value.
+     * @param[out]  ...         Variable arguments list.
+     *
+     * @retval  OT_ERROR_NONE               Successfully got the property.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError Get(spinel_prop_key_t aKey, const char *aFormat, ...);
+
+    /**
+     * This method tries to retrieve a spinel property from OpenThread transceiver with parameter appended.
+     *
+     * @param[in]   aKey        Spinel property key.
+     * @param[in]   aParam      Parameter appended to spinel command.
+     * @param[in]   aParamSize  Size of parameter appended to spinel command
+     * @param[in]   aFormat     Spinel formatter to unpack property value.
+     * @param[out]  ...         Variable arguments list.
+     *
+     * @retval  OT_ERROR_NONE               Successfully got the property.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError GetWithParam(spinel_prop_key_t aKey,
+                         const uint8_t *   aParam,
+                         spinel_size_t     aParamSize,
+                         const char *      aFormat,
+                         ...);
+
+    /**
+     * This method tries to update a spinel property of OpenThread transceiver.
+     *
+     * @param[in]   aKey        Spinel property key.
+     * @param[in]   aFormat     Spinel formatter to pack property value.
+     * @param[in]   ...         Variable arguments list.
+     *
+     * @retval  OT_ERROR_NONE               Successfully set the property.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError Set(spinel_prop_key_t aKey, const char *aFormat, ...);
+
+    /**
+     * This method tries to insert a item into a spinel list property of OpenThread transceiver.
+     *
+     * @param[in]   aKey        Spinel property key.
+     * @param[in]   aFormat     Spinel formatter to pack the item.
+     * @param[in]   ...         Variable arguments list.
+     *
+     * @retval  OT_ERROR_NONE               Successfully insert item into the property.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError Insert(spinel_prop_key_t aKey, const char *aFormat, ...);
+
+    /**
+     * This method tries to remove a item from a spinel list property of OpenThread transceiver.
+     *
+     * @param[in]   aKey        Spinel property key.
+     * @param[in]   aFormat     Spinel formatter to pack the item.
+     * @param[in]   ...         Variable arguments list.
+     *
+     * @retval  OT_ERROR_NONE               Successfully removed item from the property.
+     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
+     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
+     *
+     */
+    otError Remove(spinel_prop_key_t aKey, const char *aFormat, ...);
+
+    spinel_tid_t GetNextTid(void);
+    void         FreeTid(spinel_tid_t tid) { mCmdTidsInUse &= ~(1 << tid); }
+
+    otError RequestV(bool aWait, uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, va_list aArgs);
+    otError Request(bool aWait, uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, ...);
+    otError WaitResponse(void);
+    otError SendReset(void);
+    otError SendCommand(uint32_t          command,
+                        spinel_prop_key_t key,
+                        spinel_tid_t      tid,
+                        const char *      pack_format,
+                        va_list           args);
+    otError ParseRadioFrame(otRadioFrame &aFrame, const uint8_t *aBuffer, uint16_t aLength, spinel_ssize_t &aUnpacked);
+    otError ThreadDatasetHandler(const uint8_t *aBuffer, uint16_t aLength);
+
+    /**
+     * This method returns if the property changed event is safe to be handled now.
+     *
+     * If a property handler will go up to core stack, it may cause reentrant issue of `Hdlc::Decode()` and
+     * `WaitResponse()`.
+     *
+     * @param[in] aKey The identifier of the property.
+     *
+     * @returns Whether this property is safe to be handled now.
+     *
+     */
+    bool IsSafeToHandleNow(spinel_prop_key_t aKey) const
+    {
+        return !(aKey == SPINEL_PROP_STREAM_RAW || aKey == SPINEL_PROP_MAC_ENERGY_SCAN_RESULT);
+    }
+
+    void HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer);
+    void HandleNotification(const uint8_t *aBuffer, uint16_t aLength);
+    void HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
+
+    void HandleResponse(const uint8_t *aBuffer, uint16_t aLength);
+    void HandleTransmitDone(uint32_t aCommand, spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
+    void HandleWaitingResponse(uint32_t aCommand, spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
+
+    void RadioReceive(void);
+
+    void TransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError);
+
+    void CalcRcpTimeOffset(void);
+
+    otInstance *mInstance;
+
+    SpinelInterface::RxFrameBuffer mRxFrameBuffer;
+
+    InterfaceType mSpinelInterface;
+
+    uint16_t          mCmdTidsInUse;    ///< Used transaction ids.
+    spinel_tid_t      mCmdNextTid;      ///< Next available transaction id.
+    spinel_tid_t      mTxRadioTid;      ///< The transaction id used to send a radio frame.
+    spinel_tid_t      mWaitingTid;      ///< The transaction id of current transaction.
+    spinel_prop_key_t mWaitingKey;      ///< The property key of current transaction.
+    const char *      mPropertyFormat;  ///< The spinel property format of current transaction.
+    va_list           mPropertyArgs;    ///< The arguments pack or unpack spinel property of current transaction.
+    uint32_t          mExpectedCommand; ///< Expected response command of current transaction.
+    otError           mError;           ///< The result of current transaction.
+
+    uint8_t       mRxPsdu[OT_RADIO_FRAME_MAX_SIZE];
+    uint8_t       mTxPsdu[OT_RADIO_FRAME_MAX_SIZE];
+    uint8_t       mAckPsdu[OT_RADIO_FRAME_MAX_SIZE];
+    otRadioFrame  mRxRadioFrame;
+    otRadioFrame  mTxRadioFrame;
+    otRadioFrame  mAckRadioFrame;
+    otRadioFrame *mTransmitFrame; ///< Points to the frame to send
+
+    otExtAddress mExtendedAddress;
+    uint16_t     mShortAddress;
+    uint16_t     mPanId;
+    otRadioCaps  mRadioCaps;
+    uint8_t      mChannel;
+    int8_t       mRxSensitivity;
+    otError      mTxError;
+    char         mVersion[kVersionStringSize];
+    otExtAddress mIeeeEui64;
+
+    State mState;
+    bool  mIsPromiscuous : 1;     ///< Promiscuous mode.
+    bool  mIsReady : 1;           ///< NCP ready.
+    bool  mSupportsLogStream : 1; ///< RCP supports `LOG_STREAM` property with OpenThread log meta-data format.
+    bool  mIsTimeSynced : 1;      ///< Host has calculated the time difference between host and RCP.
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+    bool   mDiagMode;
+    char * mDiagOutput;
+    size_t mDiagOutputMaxLen;
+#endif
+
+    uint64_t mTxRadioEndUs;
+    uint64_t mRadioTimeRecalcStart; ///< When to recalculate RCP time offset.
+    int64_t  mRadioTimeOffset;      ///< Time difference with estimated RCP time minus host time.
+};
+
+} // namespace Spinel
+} // namespace ot
+
+#include "radio_spinel_impl.hpp"
+
+#endif // RADIO_SPINEL_HPP_
diff --git a/src/lib/spinel/radio_spinel_impl.hpp b/src/lib/spinel/radio_spinel_impl.hpp
new file mode 100644
index 0000000..b8f7956
--- /dev/null
+++ b/src/lib/spinel/radio_spinel_impl.hpp
@@ -0,0 +1,1810 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the spinel based radio transceiver.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include <openthread/dataset.h>
+#include <openthread/platform/diag.h>
+#include <openthread/platform/settings.h>
+#include <openthread/platform/time.h>
+
+#include "common/code_utils.hpp"
+#include "common/encoding.hpp"
+#include "common/logging.hpp"
+#include "common/new.hpp"
+#include "common/settings.hpp"
+#include "lib/platform/exit_code.h"
+#include "lib/spinel/spinel_decoder.hpp"
+#include "meshcop/dataset.hpp"
+#include "meshcop/meshcop_tlvs.hpp"
+
+#ifndef MS_PER_S
+#define MS_PER_S 1000
+#endif
+#ifndef US_PER_MS
+#define US_PER_MS 1000
+#endif
+#ifndef US_PER_S
+#define US_PER_S (MS_PER_S * US_PER_MS)
+#endif
+#ifndef NS_PER_US
+#define NS_PER_US 1000
+#endif
+
+#ifndef TX_WAIT_US
+#define TX_WAIT_US (5 * US_PER_S)
+#endif
+
+#ifndef RCP_TIME_OFFSET_CHECK_INTERVAL
+#define RCP_TIME_OFFSET_CHECK_INTERVAL (60 * US_PER_S)
+#endif
+
+using ot::Spinel::Decoder;
+
+namespace ot {
+namespace Spinel {
+
+static otError SpinelStatusToOtError(spinel_status_t aError)
+{
+    otError ret;
+
+    switch (aError)
+    {
+    case SPINEL_STATUS_OK:
+        ret = OT_ERROR_NONE;
+        break;
+
+    case SPINEL_STATUS_FAILURE:
+        ret = OT_ERROR_FAILED;
+        break;
+
+    case SPINEL_STATUS_DROPPED:
+        ret = OT_ERROR_DROP;
+        break;
+
+    case SPINEL_STATUS_NOMEM:
+        ret = OT_ERROR_NO_BUFS;
+        break;
+
+    case SPINEL_STATUS_BUSY:
+        ret = OT_ERROR_BUSY;
+        break;
+
+    case SPINEL_STATUS_PARSE_ERROR:
+        ret = OT_ERROR_PARSE;
+        break;
+
+    case SPINEL_STATUS_INVALID_ARGUMENT:
+        ret = OT_ERROR_INVALID_ARGS;
+        break;
+
+    case SPINEL_STATUS_UNIMPLEMENTED:
+        ret = OT_ERROR_NOT_IMPLEMENTED;
+        break;
+
+    case SPINEL_STATUS_INVALID_STATE:
+        ret = OT_ERROR_INVALID_STATE;
+        break;
+
+    case SPINEL_STATUS_NO_ACK:
+        ret = OT_ERROR_NO_ACK;
+        break;
+
+    case SPINEL_STATUS_CCA_FAILURE:
+        ret = OT_ERROR_CHANNEL_ACCESS_FAILURE;
+        break;
+
+    case SPINEL_STATUS_ALREADY:
+        ret = OT_ERROR_ALREADY;
+        break;
+
+    case SPINEL_STATUS_PROP_NOT_FOUND:
+    case SPINEL_STATUS_ITEM_NOT_FOUND:
+        ret = OT_ERROR_NOT_FOUND;
+        break;
+
+    default:
+        if (aError >= SPINEL_STATUS_STACK_NATIVE__BEGIN && aError <= SPINEL_STATUS_STACK_NATIVE__END)
+        {
+            ret = static_cast<otError>(aError - SPINEL_STATUS_STACK_NATIVE__BEGIN);
+        }
+        else
+        {
+            ret = OT_ERROR_FAILED;
+        }
+        break;
+    }
+
+    return ret;
+}
+
+static void LogIfFail(const char *aText, otError aError)
+{
+    OT_UNUSED_VARIABLE(aText);
+    OT_UNUSED_VARIABLE(aError);
+
+    if (aError != OT_ERROR_NONE)
+    {
+        otLogWarnPlat("%s: %s", aText, otThreadErrorToString(aError));
+    }
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::HandleReceivedFrame(void *aContext)
+{
+    static_cast<RadioSpinel *>(aContext)->HandleReceivedFrame();
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+RadioSpinel<InterfaceType, ProcessContextType>::RadioSpinel(void)
+    : mInstance(nullptr)
+    , mRxFrameBuffer()
+    , mSpinelInterface(HandleReceivedFrame, this, mRxFrameBuffer)
+    , mCmdTidsInUse(0)
+    , mCmdNextTid(1)
+    , mTxRadioTid(0)
+    , mWaitingTid(0)
+    , mWaitingKey(SPINEL_PROP_LAST_STATUS)
+    , mPropertyFormat(nullptr)
+    , mExpectedCommand(0)
+    , mError(OT_ERROR_NONE)
+    , mTransmitFrame(nullptr)
+    , mShortAddress(0)
+    , mPanId(0xffff)
+    , mRadioCaps(0)
+    , mChannel(0)
+    , mRxSensitivity(0)
+    , mState(kStateDisabled)
+    , mIsPromiscuous(false)
+    , mIsReady(false)
+    , mSupportsLogStream(false)
+    , mIsTimeSynced(false)
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+    , mDiagMode(false)
+    , mDiagOutput(nullptr)
+    , mDiagOutputMaxLen(0)
+#endif
+    , mTxRadioEndUs(UINT64_MAX)
+    , mRadioTimeRecalcStart(UINT64_MAX)
+    , mRadioTimeOffset(0)
+{
+    mVersion[0] = '\0';
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::Init(bool aResetRadio, bool aRestoreDatasetFromNcp)
+{
+    otError error = OT_ERROR_NONE;
+
+    if (aResetRadio)
+    {
+        SuccessOrExit(error = SendReset());
+    }
+
+    SuccessOrExit(error = WaitResponse());
+    VerifyOrExit(mIsReady, error = OT_ERROR_FAILED);
+
+    SuccessOrExit(error = CheckSpinelVersion());
+    SuccessOrExit(error = Get(SPINEL_PROP_NCP_VERSION, SPINEL_DATATYPE_UTF8_S, mVersion, sizeof(mVersion)));
+    SuccessOrExit(error = Get(SPINEL_PROP_HWADDR, SPINEL_DATATYPE_EUI64_S, mIeeeEui64.m8));
+
+    if (!IsRcp() && aRestoreDatasetFromNcp)
+    {
+        DieNow((RestoreDatasetFromNcp() == OT_ERROR_NONE) ? OT_EXIT_SUCCESS : OT_EXIT_FAILURE);
+    }
+    SuccessOrDie(CheckRadioCapabilities());
+
+    mRxRadioFrame.mPsdu  = mRxPsdu;
+    mTxRadioFrame.mPsdu  = mTxPsdu;
+    mAckRadioFrame.mPsdu = mAckPsdu;
+
+exit:
+    SuccessOrDie(error);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::CheckSpinelVersion(void)
+{
+    otError      error = OT_ERROR_NONE;
+    unsigned int versionMajor;
+    unsigned int versionMinor;
+
+    SuccessOrExit(error =
+                      Get(SPINEL_PROP_PROTOCOL_VERSION, (SPINEL_DATATYPE_UINT_PACKED_S SPINEL_DATATYPE_UINT_PACKED_S),
+                          &versionMajor, &versionMinor));
+
+    if ((versionMajor != SPINEL_PROTOCOL_VERSION_THREAD_MAJOR) ||
+        (versionMinor != SPINEL_PROTOCOL_VERSION_THREAD_MINOR))
+    {
+        otLogCritPlat("Spinel version mismatch - Posix:%d.%d, RCP:%d.%d", SPINEL_PROTOCOL_VERSION_THREAD_MAJOR,
+                      SPINEL_PROTOCOL_VERSION_THREAD_MINOR, versionMajor, versionMinor);
+        DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
+    }
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+bool RadioSpinel<InterfaceType, ProcessContextType>::IsRcp(void)
+{
+    uint8_t        capsBuffer[kCapsBufferSize];
+    const uint8_t *capsData         = capsBuffer;
+    spinel_size_t  capsLength       = sizeof(capsBuffer);
+    bool           supportsRawRadio = false;
+    bool           isRcp            = false;
+
+    SuccessOrDie(Get(SPINEL_PROP_CAPS, SPINEL_DATATYPE_DATA_S, capsBuffer, &capsLength));
+
+    while (capsLength > 0)
+    {
+        unsigned int   capability;
+        spinel_ssize_t unpacked;
+
+        unpacked = spinel_datatype_unpack(capsData, capsLength, SPINEL_DATATYPE_UINT_PACKED_S, &capability);
+        VerifyOrDie(unpacked > 0, OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
+
+        if (capability == SPINEL_CAP_MAC_RAW)
+        {
+            supportsRawRadio = true;
+        }
+
+        if (capability == SPINEL_CAP_CONFIG_RADIO)
+        {
+            isRcp = true;
+        }
+
+        capsData += unpacked;
+        capsLength -= static_cast<spinel_size_t>(unpacked);
+    }
+
+    if (!supportsRawRadio && isRcp)
+    {
+        otLogCritPlat("RCP capability list does not include support for radio/raw mode");
+        DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
+    }
+
+    return isRcp;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::CheckRadioCapabilities(void)
+{
+    const otRadioCaps kRequiredRadioCaps =
+        OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_CSMA_BACKOFF;
+
+    otError        error = OT_ERROR_NONE;
+    unsigned int   radioCaps;
+    uint8_t        capsBuffer[kCapsBufferSize];
+    const uint8_t *capsData   = capsBuffer;
+    spinel_size_t  capsLength = sizeof(capsBuffer);
+
+    SuccessOrExit(error = Get(SPINEL_PROP_RADIO_CAPS, SPINEL_DATATYPE_UINT_PACKED_S, &radioCaps));
+    mRadioCaps = static_cast<otRadioCaps>(radioCaps);
+
+    if ((mRadioCaps & kRequiredRadioCaps) != kRequiredRadioCaps)
+    {
+        otLogCritPlat("RCP does not support required capabilities: ack-timeout:%s, tx-retries:%s, CSMA-backoff:%s",
+                      (mRadioCaps & OT_RADIO_CAPS_ACK_TIMEOUT) ? "yes" : "no",
+                      (mRadioCaps & OT_RADIO_CAPS_TRANSMIT_RETRIES) ? "yes" : "no",
+                      (mRadioCaps & OT_RADIO_CAPS_CSMA_BACKOFF) ? "yes" : "no");
+
+        DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
+    }
+
+    SuccessOrExit(error = Get(SPINEL_PROP_CAPS, SPINEL_DATATYPE_DATA_S, capsBuffer, &capsLength));
+    while (capsLength > 0)
+    {
+        unsigned int   capability;
+        spinel_ssize_t unpacked =
+            spinel_datatype_unpack(capsData, capsLength, SPINEL_DATATYPE_UINT_PACKED_S, &capability);
+
+        VerifyOrDie(unpacked > 0, OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
+
+        if (capability == SPINEL_CAP_OPENTHREAD_LOG_METADATA)
+        {
+            mSupportsLogStream = true;
+        }
+
+        capsData += unpacked;
+        capsLength -= static_cast<spinel_size_t>(unpacked);
+    }
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::RestoreDatasetFromNcp(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    otPlatSettingsInit(mInstance);
+
+    otLogInfoPlat("Trying to get saved dataset from NCP");
+    SuccessOrExit(
+        error = Get(SPINEL_PROP_THREAD_ACTIVE_DATASET, SPINEL_DATATYPE_VOID_S, &RadioSpinel::ThreadDatasetHandler));
+    SuccessOrExit(
+        error = Get(SPINEL_PROP_THREAD_PENDING_DATASET, SPINEL_DATATYPE_VOID_S, &RadioSpinel::ThreadDatasetHandler));
+
+exit:
+    otPlatSettingsDeinit(mInstance);
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::Deinit(void)
+{
+    mSpinelInterface.Deinit();
+    // This allows implementing pseudo reset.
+    new (this) RadioSpinel();
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::HandleReceivedFrame(void)
+{
+    otError        error = OT_ERROR_NONE;
+    uint8_t        header;
+    spinel_ssize_t unpacked;
+
+    unpacked = spinel_datatype_unpack(mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetLength(), "C", &header);
+
+    VerifyOrExit(unpacked > 0 && (header & SPINEL_HEADER_FLAG) == SPINEL_HEADER_FLAG &&
+                     SPINEL_HEADER_GET_IID(header) == 0,
+                 error = OT_ERROR_PARSE);
+
+    if (SPINEL_HEADER_GET_TID(header) == 0)
+    {
+        HandleNotification(mRxFrameBuffer);
+    }
+    else
+    {
+        HandleResponse(mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetLength());
+        mRxFrameBuffer.DiscardFrame();
+    }
+
+exit:
+    if (error != OT_ERROR_NONE)
+    {
+        mRxFrameBuffer.DiscardFrame();
+        otLogWarnPlat("Error handling hdlc frame: %s", otThreadErrorToString(error));
+    }
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer)
+{
+    spinel_prop_key_t key;
+    spinel_size_t     len = 0;
+    spinel_ssize_t    unpacked;
+    uint8_t *         data = nullptr;
+    uint32_t          cmd;
+    uint8_t           header;
+    otError           error           = OT_ERROR_NONE;
+    bool              shouldSaveFrame = false;
+
+    unpacked = spinel_datatype_unpack(aFrameBuffer.GetFrame(), aFrameBuffer.GetLength(), "CiiD", &header, &cmd, &key,
+                                      &data, &len);
+    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+    VerifyOrExit(SPINEL_HEADER_GET_TID(header) == 0, error = OT_ERROR_PARSE);
+
+    switch (cmd)
+    {
+    case SPINEL_CMD_PROP_VALUE_IS:
+        // Some spinel properties cannot be handled during `WaitResponse()`, we must cache these events.
+        // `mWaitingTid` is released immediately after received the response. And `mWaitingKey` is be set
+        // to `SPINEL_PROP_LAST_STATUS` at the end of `WaitResponse()`.
+
+        if (!IsSafeToHandleNow(key))
+        {
+            ExitNow(shouldSaveFrame = true);
+        }
+
+        HandleValueIs(key, data, static_cast<uint16_t>(len));
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_INSERTED:
+    case SPINEL_CMD_PROP_VALUE_REMOVED:
+        otLogInfoPlat("Ignored command %d", cmd);
+        break;
+
+    default:
+        ExitNow(error = OT_ERROR_PARSE);
+    }
+
+exit:
+    if (shouldSaveFrame)
+    {
+        aFrameBuffer.SaveFrame();
+    }
+    else
+    {
+        aFrameBuffer.DiscardFrame();
+    }
+
+    LogIfFail("Error processing notification", error);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::HandleNotification(const uint8_t *aFrame, uint16_t aLength)
+{
+    spinel_prop_key_t key;
+    spinel_size_t     len = 0;
+    spinel_ssize_t    unpacked;
+    uint8_t *         data = nullptr;
+    uint32_t          cmd;
+    uint8_t           header;
+    otError           error = OT_ERROR_NONE;
+
+    unpacked = spinel_datatype_unpack(aFrame, aLength, "CiiD", &header, &cmd, &key, &data, &len);
+    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+    VerifyOrExit(SPINEL_HEADER_GET_TID(header) == 0, error = OT_ERROR_PARSE);
+    VerifyOrExit(cmd == SPINEL_CMD_PROP_VALUE_IS, OT_NOOP);
+    HandleValueIs(key, data, static_cast<uint16_t>(len));
+
+exit:
+    LogIfFail("Error processing saved notification", error);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::HandleResponse(const uint8_t *aBuffer, uint16_t aLength)
+{
+    spinel_prop_key_t key;
+    uint8_t *         data   = nullptr;
+    spinel_size_t     len    = 0;
+    uint8_t           header = 0;
+    uint32_t          cmd    = 0;
+    spinel_ssize_t    rval   = 0;
+    otError           error  = OT_ERROR_NONE;
+
+    rval = spinel_datatype_unpack(aBuffer, aLength, "CiiD", &header, &cmd, &key, &data, &len);
+    VerifyOrExit(rval > 0 && cmd >= SPINEL_CMD_PROP_VALUE_IS && cmd <= SPINEL_CMD_PROP_VALUE_REMOVED,
+                 error = OT_ERROR_PARSE);
+
+    if (mWaitingTid == SPINEL_HEADER_GET_TID(header))
+    {
+        HandleWaitingResponse(cmd, key, data, static_cast<uint16_t>(len));
+        FreeTid(mWaitingTid);
+        mWaitingTid = 0;
+    }
+    else if (mTxRadioTid == SPINEL_HEADER_GET_TID(header))
+    {
+        if (mState == kStateTransmitting)
+        {
+            HandleTransmitDone(cmd, key, data, static_cast<uint16_t>(len));
+        }
+
+        FreeTid(mTxRadioTid);
+        mTxRadioTid = 0;
+    }
+    else
+    {
+        otLogWarnPlat("Unexpected Spinel transaction message: %u", SPINEL_HEADER_GET_TID(header));
+        error = OT_ERROR_DROP;
+    }
+
+exit:
+    LogIfFail("Error processing response", error);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::ThreadDatasetHandler(const uint8_t *aBuffer, uint16_t aLength)
+{
+    otError              error = OT_ERROR_NONE;
+    otOperationalDataset opDataset;
+    bool                 isActive = ((mWaitingKey == SPINEL_PROP_THREAD_ACTIVE_DATASET) ? true : false);
+    Spinel::Decoder      decoder;
+    MeshCoP::Dataset     dataset(isActive ? MeshCoP::Dataset::kActive : MeshCoP::Dataset::kPending);
+
+    memset(&opDataset, 0, sizeof(otOperationalDataset));
+    decoder.Init(aBuffer, aLength);
+
+    while (!decoder.IsAllReadInStruct())
+    {
+        unsigned int propKey;
+
+        SuccessOrExit(error = decoder.OpenStruct());
+        SuccessOrExit(error = decoder.ReadUintPacked(propKey));
+
+        switch (static_cast<spinel_prop_key_t>(propKey))
+        {
+        case SPINEL_PROP_NET_MASTER_KEY:
+        {
+            const uint8_t *key;
+            uint16_t       len;
+
+            SuccessOrExit(error = decoder.ReadData(key, len));
+            VerifyOrExit(len == OT_MASTER_KEY_SIZE, error = OT_ERROR_INVALID_ARGS);
+            memcpy(opDataset.mMasterKey.m8, key, len);
+            opDataset.mComponents.mIsMasterKeyPresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_NET_NETWORK_NAME:
+        {
+            const char *name;
+            size_t      len;
+
+            SuccessOrExit(error = decoder.ReadUtf8(name));
+            len = StringLength(name, OT_NETWORK_NAME_MAX_SIZE);
+            memcpy(opDataset.mNetworkName.m8, name, len);
+            opDataset.mNetworkName.m8[len]              = '\0';
+            opDataset.mComponents.mIsNetworkNamePresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_NET_XPANID:
+        {
+            const uint8_t *xpanid;
+            uint16_t       len;
+
+            SuccessOrExit(error = decoder.ReadData(xpanid, len));
+            VerifyOrExit(len == OT_EXT_PAN_ID_SIZE, error = OT_ERROR_INVALID_ARGS);
+            memcpy(opDataset.mExtendedPanId.m8, xpanid, len);
+            opDataset.mComponents.mIsExtendedPanIdPresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_IPV6_ML_PREFIX:
+        {
+            const otIp6Address *addr;
+            uint8_t             prefixLen;
+
+            SuccessOrExit(error = decoder.ReadIp6Address(addr));
+            SuccessOrExit(error = decoder.ReadUint8(prefixLen));
+            VerifyOrExit(prefixLen == OT_IP6_PREFIX_BITSIZE, error = OT_ERROR_INVALID_ARGS);
+            memcpy(opDataset.mMeshLocalPrefix.m8, addr, OT_MESH_LOCAL_PREFIX_SIZE);
+            opDataset.mComponents.mIsMeshLocalPrefixPresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_DATASET_DELAY_TIMER:
+        {
+            SuccessOrExit(error = decoder.ReadUint32(opDataset.mDelay));
+            opDataset.mComponents.mIsDelayPresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_MAC_15_4_PANID:
+        {
+            SuccessOrExit(error = decoder.ReadUint16(opDataset.mPanId));
+            opDataset.mComponents.mIsPanIdPresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_PHY_CHAN:
+        {
+            uint8_t channel;
+
+            SuccessOrExit(error = decoder.ReadUint8(channel));
+            opDataset.mChannel                      = channel;
+            opDataset.mComponents.mIsChannelPresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_NET_PSKC:
+        {
+            const uint8_t *psk;
+            uint16_t       len;
+
+            SuccessOrExit(error = decoder.ReadData(psk, len));
+            VerifyOrExit(len == OT_PSKC_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
+            memcpy(opDataset.mPskc.m8, psk, OT_PSKC_MAX_SIZE);
+            opDataset.mComponents.mIsPskcPresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_DATASET_SECURITY_POLICY:
+        {
+            SuccessOrExit(error = decoder.ReadUint16(opDataset.mSecurityPolicy.mRotationTime));
+            SuccessOrExit(error = decoder.ReadUint8(opDataset.mSecurityPolicy.mFlags));
+            opDataset.mComponents.mIsSecurityPolicyPresent = true;
+            break;
+        }
+
+        case SPINEL_PROP_PHY_CHAN_SUPPORTED:
+        {
+            uint8_t channel;
+
+            opDataset.mChannelMask = 0;
+
+            while (!decoder.IsAllReadInStruct())
+            {
+                SuccessOrExit(error = decoder.ReadUint8(channel));
+                VerifyOrExit(channel <= 31, error = OT_ERROR_INVALID_ARGS);
+                opDataset.mChannelMask |= (1UL << channel);
+            }
+            opDataset.mComponents.mIsChannelMaskPresent = true;
+            break;
+        }
+
+        default:
+            break;
+        }
+
+        SuccessOrExit(error = decoder.CloseStruct());
+    }
+
+    /*
+     * Initially set Active Timestamp to 0. This is to allow the node to join the network
+     * yet retrieve the full Active Dataset from a neighboring device if one exists.
+     */
+    opDataset.mActiveTimestamp                      = 0;
+    opDataset.mComponents.mIsActiveTimestampPresent = true;
+
+    SuccessOrExit(error = dataset.SetFrom(opDataset));
+    SuccessOrExit(error = otPlatSettingsSet(
+                      mInstance, isActive ? SettingsBase::kKeyActiveDataset : SettingsBase::kKeyPendingDataset,
+                      dataset.GetBytes(), dataset.GetSize()));
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::HandleWaitingResponse(uint32_t          aCommand,
+                                                                           spinel_prop_key_t aKey,
+                                                                           const uint8_t *   aBuffer,
+                                                                           uint16_t          aLength)
+{
+    if (aKey == SPINEL_PROP_LAST_STATUS)
+    {
+        spinel_status_t status;
+        spinel_ssize_t  unpacked = spinel_datatype_unpack(aBuffer, aLength, "i", &status);
+
+        VerifyOrExit(unpacked > 0, mError = OT_ERROR_PARSE);
+        mError = SpinelStatusToOtError(status);
+    }
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+    else if (aKey == SPINEL_PROP_NEST_STREAM_MFG)
+    {
+        spinel_ssize_t unpacked;
+
+        VerifyOrExit(mDiagOutput != nullptr, OT_NOOP);
+        unpacked =
+            spinel_datatype_unpack_in_place(aBuffer, aLength, SPINEL_DATATYPE_UTF8_S, mDiagOutput, &mDiagOutputMaxLen);
+        VerifyOrExit(unpacked > 0, mError = OT_ERROR_PARSE);
+    }
+#endif
+    else if (aKey == mWaitingKey)
+    {
+        if (mPropertyFormat)
+        {
+            if (static_cast<spinel_datatype_t>(mPropertyFormat[0]) == SPINEL_DATATYPE_VOID_C)
+            {
+                // reserved SPINEL_DATATYPE_VOID_C indicate caller want to parse the spinel response itself
+                ResponseHandler handler = va_arg(mPropertyArgs, ResponseHandler);
+
+                assert(handler != nullptr);
+                mError = (this->*handler)(aBuffer, aLength);
+            }
+            else
+            {
+                spinel_ssize_t unpacked =
+                    spinel_datatype_vunpack_in_place(aBuffer, aLength, mPropertyFormat, mPropertyArgs);
+
+                VerifyOrExit(unpacked > 0, mError = OT_ERROR_PARSE);
+                mError = OT_ERROR_NONE;
+            }
+        }
+        else
+        {
+            if (aCommand == mExpectedCommand)
+            {
+                mError = OT_ERROR_NONE;
+            }
+            else
+            {
+                mError = OT_ERROR_DROP;
+            }
+        }
+    }
+    else
+    {
+        mError = OT_ERROR_DROP;
+    }
+
+exit:
+    LogIfFail("Error processing result", mError);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::HandleValueIs(spinel_prop_key_t aKey,
+                                                                   const uint8_t *   aBuffer,
+                                                                   uint16_t          aLength)
+{
+    otError        error = OT_ERROR_NONE;
+    spinel_ssize_t unpacked;
+
+    if (aKey == SPINEL_PROP_STREAM_RAW)
+    {
+        SuccessOrExit(error = ParseRadioFrame(mRxRadioFrame, aBuffer, aLength, unpacked));
+        RadioReceive();
+    }
+    else if (aKey == SPINEL_PROP_LAST_STATUS)
+    {
+        spinel_status_t status = SPINEL_STATUS_OK;
+
+        unpacked = spinel_datatype_unpack(aBuffer, aLength, "i", &status);
+        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+
+        if (status >= SPINEL_STATUS_RESET__BEGIN && status <= SPINEL_STATUS_RESET__END)
+        {
+            // If RCP crashes/resets while radio was enabled, posix app exits.
+            VerifyOrDie(!IsEnabled(), OT_EXIT_RADIO_SPINEL_RESET);
+
+            otLogInfoPlat("RCP reset: %s", spinel_status_to_cstr(status));
+            mIsReady = true;
+        }
+        else
+        {
+            otLogInfoPlat("RCP last status: %s", spinel_status_to_cstr(status));
+        }
+    }
+    else if (aKey == SPINEL_PROP_MAC_ENERGY_SCAN_RESULT)
+    {
+        uint8_t scanChannel;
+        int8_t  maxRssi;
+
+        unpacked = spinel_datatype_unpack(aBuffer, aLength, "Cc", &scanChannel, &maxRssi);
+
+        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+        otPlatRadioEnergyScanDone(mInstance, maxRssi);
+    }
+    else if (aKey == SPINEL_PROP_STREAM_DEBUG)
+    {
+        char         logStream[OPENTHREAD_CONFIG_NCP_SPINEL_LOG_MAX_SIZE + 1];
+        unsigned int len = sizeof(logStream);
+
+        unpacked = spinel_datatype_unpack_in_place(aBuffer, aLength, SPINEL_DATATYPE_DATA_S, logStream, &len);
+        assert(len < sizeof(logStream));
+        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+        logStream[len] = '\0';
+        otLogDebgPlat("RCP => %s", logStream);
+    }
+    else if ((aKey == SPINEL_PROP_STREAM_LOG) && mSupportsLogStream)
+    {
+        const char *logString;
+        uint8_t     logLevel;
+
+        unpacked = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_UTF8_S, &logString);
+        VerifyOrExit(unpacked >= 0, error = OT_ERROR_PARSE);
+        aBuffer += unpacked;
+        aLength -= unpacked;
+
+        unpacked = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_UINT8_S, &logLevel);
+        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+
+        switch (logLevel)
+        {
+        case SPINEL_NCP_LOG_LEVEL_EMERG:
+        case SPINEL_NCP_LOG_LEVEL_ALERT:
+        case SPINEL_NCP_LOG_LEVEL_CRIT:
+            otLogCritPlat("RCP => %s", logString);
+            break;
+
+        case SPINEL_NCP_LOG_LEVEL_ERR:
+        case SPINEL_NCP_LOG_LEVEL_WARN:
+            otLogWarnPlat("RCP => %s", logString);
+            break;
+
+        case SPINEL_NCP_LOG_LEVEL_NOTICE:
+            otLogNotePlat("RCP => %s", logString);
+            break;
+
+        case SPINEL_NCP_LOG_LEVEL_INFO:
+            otLogInfoPlat("RCP => %s", logString);
+            break;
+
+        case SPINEL_NCP_LOG_LEVEL_DEBUG:
+        default:
+            otLogDebgPlat("RCP => %s", logString);
+            break;
+        }
+    }
+
+exit:
+    LogIfFail("Failed to handle ValueIs", error);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::ParseRadioFrame(otRadioFrame &  aFrame,
+                                                                        const uint8_t * aBuffer,
+                                                                        uint16_t        aLength,
+                                                                        spinel_ssize_t &aUnpacked)
+{
+    otError        error        = OT_ERROR_NONE;
+    uint16_t       flags        = 0;
+    int8_t         noiseFloor   = -128;
+    spinel_size_t  size         = OT_RADIO_FRAME_MAX_SIZE;
+    unsigned int   receiveError = 0;
+    spinel_ssize_t unpacked;
+
+    VerifyOrExit(aLength > 0, aFrame.mLength = 0);
+
+    unpacked = spinel_datatype_unpack_in_place(aBuffer, aLength,
+                                               SPINEL_DATATYPE_DATA_WLEN_S                          // Frame
+                                                               SPINEL_DATATYPE_INT8_S               // RSSI
+                                                               SPINEL_DATATYPE_INT8_S               // Noise Floor
+                                                               SPINEL_DATATYPE_UINT16_S             // Flags
+                                                               SPINEL_DATATYPE_STRUCT_S(            // PHY-data
+                                                                   SPINEL_DATATYPE_UINT8_S          // 802.15.4 channel
+                                                                           SPINEL_DATATYPE_UINT8_S  // 802.15.4 LQI
+                                                                           SPINEL_DATATYPE_UINT64_S // Timestamp (us).
+                                                                   ) SPINEL_DATATYPE_STRUCT_S(      // Vendor-data
+                                                                   SPINEL_DATATYPE_UINT_PACKED_S    // Receive error
+                                                                   ),
+                                               aFrame.mPsdu, &size, &aFrame.mInfo.mRxInfo.mRssi, &noiseFloor, &flags,
+                                               &aFrame.mChannel, &aFrame.mInfo.mRxInfo.mLqi,
+                                               &aFrame.mInfo.mRxInfo.mTimestamp, &receiveError);
+
+    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+    aUnpacked = unpacked;
+
+    aBuffer += unpacked;
+    aLength -= static_cast<uint16_t>(unpacked);
+
+    if (mRadioCaps & OT_RADIO_CAPS_TRANSMIT_SEC)
+    {
+        unpacked =
+            spinel_datatype_unpack_in_place(aBuffer, aLength,
+                                            SPINEL_DATATYPE_STRUCT_S(        // MAC-data
+                                                SPINEL_DATATYPE_UINT8_S      // Security key index
+                                                    SPINEL_DATATYPE_UINT32_S // Security frame counter
+                                                ),
+                                            &aFrame.mInfo.mRxInfo.mAckKeyId, &aFrame.mInfo.mRxInfo.mAckFrameCounter);
+
+        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+        aUnpacked += unpacked;
+    }
+
+    if (receiveError == OT_ERROR_NONE)
+    {
+        aFrame.mLength = static_cast<uint8_t>(size);
+
+        aFrame.mInfo.mRxInfo.mAckedWithFramePending = ((flags & SPINEL_MD_FLAG_ACKED_FP) != 0);
+        aFrame.mInfo.mRxInfo.mAckedWithSecEnhAck    = ((flags & SPINEL_MD_FLAG_ACKED_SEC) != 0);
+    }
+    else if (receiveError < OT_NUM_ERRORS)
+    {
+        error = static_cast<otError>(receiveError);
+    }
+    else
+    {
+        error = OT_ERROR_PARSE;
+    }
+
+exit:
+    LogIfFail("Handle radio frame failed", error);
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::ProcessFrameQueue(void)
+{
+    uint8_t *frame = nullptr;
+    uint16_t length;
+
+    while (mRxFrameBuffer.GetNextSavedFrame(frame, length) == OT_ERROR_NONE)
+    {
+        HandleNotification(frame, length);
+    }
+
+    mRxFrameBuffer.ClearSavedFrames();
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::RadioReceive(void)
+{
+    if (!mIsPromiscuous)
+    {
+        switch (mState)
+        {
+        case kStateDisabled:
+        case kStateSleep:
+            ExitNow();
+
+        case kStateReceive:
+        case kStateTransmitting:
+        case kStateTransmitDone:
+            break;
+        }
+    }
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+    if (otPlatDiagModeGet())
+    {
+        otPlatDiagRadioReceiveDone(mInstance, &mRxRadioFrame, OT_ERROR_NONE);
+    }
+    else
+#endif
+    {
+        otPlatRadioReceiveDone(mInstance, &mRxRadioFrame, OT_ERROR_NONE);
+    }
+
+exit:
+    return;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::TransmitDone(otRadioFrame *aFrame,
+                                                                  otRadioFrame *aAckFrame,
+                                                                  otError       aError)
+{
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+    if (otPlatDiagModeGet())
+    {
+        otPlatDiagRadioTransmitDone(mInstance, aFrame, aError);
+    }
+    else
+#endif
+    {
+        otPlatRadioTxDone(mInstance, aFrame, aAckFrame, aError);
+    }
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::ProcessRadioStateMachine(void)
+{
+    if (mState == kStateTransmitDone)
+    {
+        mState        = kStateReceive;
+        mTxRadioEndUs = UINT64_MAX;
+
+        TransmitDone(mTransmitFrame, (mAckRadioFrame.mLength != 0) ? &mAckRadioFrame : nullptr, mTxError);
+    }
+    else if (mState == kStateTransmitting && otPlatTimeGet() >= mTxRadioEndUs)
+    {
+        // Frame has been successfully passed to radio, but no `TransmitDone` event received within TX_WAIT_US.
+        DieNowWithMessage("radio tx timeout", OT_EXIT_FAILURE);
+    }
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::Process(const ProcessContextType &aContext)
+{
+    if (mRxFrameBuffer.HasSavedFrame())
+    {
+        ProcessFrameQueue();
+    }
+
+    GetSpinelInterface().Process(aContext);
+
+    if (mRxFrameBuffer.HasSavedFrame())
+    {
+        ProcessFrameQueue();
+    }
+
+    ProcessRadioStateMachine();
+    CalcRcpTimeOffset();
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetPromiscuous(bool aEnable)
+{
+    otError error;
+
+    uint8_t mode = (aEnable ? SPINEL_MAC_PROMISCUOUS_MODE_NETWORK : SPINEL_MAC_PROMISCUOUS_MODE_OFF);
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_PROMISCUOUS_MODE, SPINEL_DATATYPE_UINT8_S, mode));
+    mIsPromiscuous = aEnable;
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetShortAddress(uint16_t aAddress)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mShortAddress != aAddress, OT_NOOP);
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_SADDR, SPINEL_DATATYPE_UINT16_S, aAddress));
+    mShortAddress = aAddress;
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetMacKey(uint8_t         aKeyIdMode,
+                                                                  uint8_t         aKeyId,
+                                                                  const otMacKey &aPrevKey,
+                                                                  const otMacKey &aCurrKey,
+                                                                  const otMacKey &aNextKey)
+{
+    otError error;
+
+    SuccessOrExit(error = Set(SPINEL_PROP_RCP_MAC_KEY,
+                              SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_DATA_WLEN_S
+                                  SPINEL_DATATYPE_DATA_WLEN_S SPINEL_DATATYPE_DATA_WLEN_S,
+                              aKeyIdMode, aKeyId, aPrevKey.m8, sizeof(otMacKey), aCurrKey.m8, sizeof(otMacKey),
+                              aNextKey.m8, sizeof(otMacKey)));
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetMacFrameCounter(uint32_t aMacFrameCounter)
+{
+    otError error;
+
+    SuccessOrExit(error = Set(SPINEL_PROP_RCP_MAC_FRAME_COUNTER, SPINEL_DATATYPE_UINT32_S, aMacFrameCounter));
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::GetIeeeEui64(uint8_t *aIeeeEui64)
+{
+    memcpy(aIeeeEui64, mIeeeEui64.m8, sizeof(mIeeeEui64.m8));
+
+    return OT_ERROR_NONE;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetExtendedAddress(const otExtAddress &aExtAddress)
+{
+    otError error;
+
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_LADDR, SPINEL_DATATYPE_EUI64_S, aExtAddress.m8));
+    mExtendedAddress = aExtAddress;
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetPanId(uint16_t aPanId)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mPanId != aPanId, OT_NOOP);
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_PANID, SPINEL_DATATYPE_UINT16_S, aPanId));
+    mPanId = aPanId;
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::EnableSrcMatch(bool aEnable)
+{
+    return Set(SPINEL_PROP_MAC_SRC_MATCH_ENABLED, SPINEL_DATATYPE_BOOL_S, aEnable);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::AddSrcMatchShortEntry(uint16_t aShortAddress)
+{
+    return Insert(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, SPINEL_DATATYPE_UINT16_S, aShortAddress);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::AddSrcMatchExtEntry(const otExtAddress &aExtAddress)
+{
+    return Insert(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, SPINEL_DATATYPE_EUI64_S, aExtAddress.m8);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::ClearSrcMatchShortEntry(uint16_t aShortAddress)
+{
+    return Remove(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, SPINEL_DATATYPE_UINT16_S, aShortAddress);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::ClearSrcMatchExtEntry(const otExtAddress &aExtAddress)
+{
+    return Remove(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, SPINEL_DATATYPE_EUI64_S, aExtAddress.m8);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::ClearSrcMatchShortEntries(void)
+{
+    return Set(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, nullptr);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::ClearSrcMatchExtEntries(void)
+{
+    return Set(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, nullptr);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::GetTransmitPower(int8_t &aPower)
+{
+    otError error = Get(SPINEL_PROP_PHY_TX_POWER, SPINEL_DATATYPE_INT8_S, &aPower);
+
+    LogIfFail("Get transmit power failed", error);
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::GetCcaEnergyDetectThreshold(int8_t &aThreshold)
+{
+    otError error = Get(SPINEL_PROP_PHY_CCA_THRESHOLD, SPINEL_DATATYPE_INT8_S, &aThreshold);
+
+    LogIfFail("Get CCA ED threshold failed", error);
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+int8_t RadioSpinel<InterfaceType, ProcessContextType>::GetRssi(void)
+{
+    int8_t  rssi  = OT_RADIO_RSSI_INVALID;
+    otError error = Get(SPINEL_PROP_PHY_RSSI, SPINEL_DATATYPE_INT8_S, &rssi);
+
+    LogIfFail("Get RSSI failed", error);
+    return rssi;
+}
+
+#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetCoexEnabled(bool aEnabled)
+{
+    return Set(SPINEL_PROP_RADIO_COEX_ENABLE, SPINEL_DATATYPE_BOOL_S, aEnabled);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+bool RadioSpinel<InterfaceType, ProcessContextType>::IsCoexEnabled(void)
+{
+    bool    enabled;
+    otError error = Get(SPINEL_PROP_RADIO_COEX_ENABLE, SPINEL_DATATYPE_BOOL_S, &enabled);
+
+    LogIfFail("Get Coex State failed", error);
+    return enabled;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics)
+{
+    otError error;
+
+    error = Get(SPINEL_PROP_RADIO_COEX_METRICS,
+                SPINEL_DATATYPE_STRUCT_S(                                    // Tx Coex Metrics Structure
+                    SPINEL_DATATYPE_UINT32_S                                 // NumTxRequest
+                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantImmediate
+                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantWait
+                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantWaitActivated
+                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantWaitTimeout
+                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantDeactivatedDuringRequest
+                                                SPINEL_DATATYPE_UINT32_S     // NumTxDelayedGrant
+                                                SPINEL_DATATYPE_UINT32_S     // AvgTxRequestToGrantTime
+                    ) SPINEL_DATATYPE_STRUCT_S(                              // Rx Coex Metrics Structure
+                    SPINEL_DATATYPE_UINT32_S                                 // NumRxRequest
+                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantImmediate
+                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantWait
+                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantWaitActivated
+                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantWaitTimeout
+                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantDeactivatedDuringRequest
+                                                    SPINEL_DATATYPE_UINT32_S // NumRxDelayedGrant
+                                                    SPINEL_DATATYPE_UINT32_S // AvgRxRequestToGrantTime
+                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantNone
+                    ) SPINEL_DATATYPE_BOOL_S                                 // Stopped
+                    SPINEL_DATATYPE_UINT32_S,                                // NumGrantGlitch
+                &aCoexMetrics.mNumTxRequest, &aCoexMetrics.mNumTxGrantImmediate, &aCoexMetrics.mNumTxGrantWait,
+                &aCoexMetrics.mNumTxGrantWaitActivated, &aCoexMetrics.mNumTxGrantWaitTimeout,
+                &aCoexMetrics.mNumTxGrantDeactivatedDuringRequest, &aCoexMetrics.mNumTxDelayedGrant,
+                &aCoexMetrics.mAvgTxRequestToGrantTime, &aCoexMetrics.mNumRxRequest, &aCoexMetrics.mNumRxGrantImmediate,
+                &aCoexMetrics.mNumRxGrantWait, &aCoexMetrics.mNumRxGrantWaitActivated,
+                &aCoexMetrics.mNumRxGrantWaitTimeout, &aCoexMetrics.mNumRxGrantDeactivatedDuringRequest,
+                &aCoexMetrics.mNumRxDelayedGrant, &aCoexMetrics.mAvgRxRequestToGrantTime, &aCoexMetrics.mNumRxGrantNone,
+                &aCoexMetrics.mStopped, &aCoexMetrics.mNumGrantGlitch);
+
+    LogIfFail("Get Coex Metrics failed", error);
+    return error;
+}
+#endif
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetTransmitPower(int8_t aPower)
+{
+    otError error = Set(SPINEL_PROP_PHY_TX_POWER, SPINEL_DATATYPE_INT8_S, aPower);
+    LogIfFail("Set transmit power failed", error);
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SetCcaEnergyDetectThreshold(int8_t aThreshold)
+{
+    otError error = Set(SPINEL_PROP_PHY_CCA_THRESHOLD, SPINEL_DATATYPE_INT8_S, aThreshold);
+    LogIfFail("Set CCA ED threshold failed", error);
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration)
+{
+    otError error;
+
+    VerifyOrExit(mRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN, error = OT_ERROR_NOT_CAPABLE);
+
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_SCAN_MASK, SPINEL_DATATYPE_DATA_S, &aScanChannel, sizeof(uint8_t)));
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_SCAN_PERIOD, SPINEL_DATATYPE_UINT16_S, aScanDuration));
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_SCAN_STATE, SPINEL_DATATYPE_UINT8_S, SPINEL_SCAN_STATE_ENERGY));
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Get(spinel_prop_key_t aKey, const char *aFormat, ...)
+{
+    otError error;
+
+    assert(mWaitingTid == 0);
+
+    mPropertyFormat = aFormat;
+    va_start(mPropertyArgs, aFormat);
+    error = RequestV(true, SPINEL_CMD_PROP_VALUE_GET, aKey, nullptr, mPropertyArgs);
+    va_end(mPropertyArgs);
+    mPropertyFormat = nullptr;
+
+    return error;
+}
+
+// This is not a normal use case for VALUE_GET command and should be only used to get RCP timestamp with dummy payload
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::GetWithParam(spinel_prop_key_t aKey,
+                                                                     const uint8_t *   aParam,
+                                                                     spinel_size_t     aParamSize,
+                                                                     const char *      aFormat,
+                                                                     ...)
+{
+    otError error;
+
+    assert(mWaitingTid == 0);
+
+    mPropertyFormat = aFormat;
+    va_start(mPropertyArgs, aFormat);
+    error = Request(true, SPINEL_CMD_PROP_VALUE_GET, aKey, SPINEL_DATATYPE_DATA_S, aParam, aParamSize);
+    va_end(mPropertyArgs);
+    mPropertyFormat = nullptr;
+
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Set(spinel_prop_key_t aKey, const char *aFormat, ...)
+{
+    otError error;
+
+    assert(mWaitingTid == 0);
+
+    mExpectedCommand = SPINEL_CMD_PROP_VALUE_IS;
+    va_start(mPropertyArgs, aFormat);
+    error = RequestV(true, SPINEL_CMD_PROP_VALUE_SET, aKey, aFormat, mPropertyArgs);
+    va_end(mPropertyArgs);
+    mExpectedCommand = SPINEL_CMD_NOOP;
+
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Insert(spinel_prop_key_t aKey, const char *aFormat, ...)
+{
+    otError error;
+
+    assert(mWaitingTid == 0);
+
+    mExpectedCommand = SPINEL_CMD_PROP_VALUE_INSERTED;
+    va_start(mPropertyArgs, aFormat);
+    error = RequestV(true, SPINEL_CMD_PROP_VALUE_INSERT, aKey, aFormat, mPropertyArgs);
+    va_end(mPropertyArgs);
+    mExpectedCommand = SPINEL_CMD_NOOP;
+
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Remove(spinel_prop_key_t aKey, const char *aFormat, ...)
+{
+    otError error;
+
+    assert(mWaitingTid == 0);
+
+    mExpectedCommand = SPINEL_CMD_PROP_VALUE_REMOVED;
+    va_start(mPropertyArgs, aFormat);
+    error = RequestV(true, SPINEL_CMD_PROP_VALUE_REMOVE, aKey, aFormat, mPropertyArgs);
+    va_end(mPropertyArgs);
+    mExpectedCommand = SPINEL_CMD_NOOP;
+
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::WaitResponse(void)
+{
+    uint64_t end = otPlatTimeGet() + kMaxWaitTime * US_PER_MS;
+
+    otLogDebgPlat("Wait response: tid=%u key=%u", mWaitingTid, mWaitingKey);
+
+    do
+    {
+        uint64_t now;
+        uint64_t remain;
+
+        now = otPlatTimeGet();
+        VerifyOrDie(end > now, OT_EXIT_RADIO_SPINEL_NO_RESPONSE);
+        remain = end - now;
+
+        VerifyOrDie(mSpinelInterface.WaitForFrame(remain) == OT_ERROR_NONE, OT_EXIT_RADIO_SPINEL_NO_RESPONSE);
+    } while (mWaitingTid || !mIsReady);
+
+    LogIfFail("Error waiting response", mError);
+    // This indicates end of waiting response.
+    mWaitingKey = SPINEL_PROP_LAST_STATUS;
+    return mError;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+spinel_tid_t RadioSpinel<InterfaceType, ProcessContextType>::GetNextTid(void)
+{
+    spinel_tid_t tid = 0;
+
+    if (((1 << mCmdNextTid) & mCmdTidsInUse) == 0)
+    {
+        tid         = mCmdNextTid;
+        mCmdNextTid = SPINEL_GET_NEXT_TID(mCmdNextTid);
+        mCmdTidsInUse |= (1 << tid);
+    }
+
+    return tid;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SendReset(void)
+{
+    otError        error = OT_ERROR_NONE;
+    uint8_t        buffer[kMaxSpinelFrame];
+    spinel_ssize_t packed;
+
+    // Pack the header, command and key
+    packed =
+        spinel_datatype_pack(buffer, sizeof(buffer), "Ci", SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_RESET);
+
+    VerifyOrExit(packed > 0 && static_cast<size_t>(packed) <= sizeof(buffer), error = OT_ERROR_NO_BUFS);
+
+    SuccessOrExit(error = mSpinelInterface.SendFrame(buffer, static_cast<uint16_t>(packed)));
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::SendCommand(uint32_t          aCommand,
+                                                                    spinel_prop_key_t aKey,
+                                                                    spinel_tid_t      tid,
+                                                                    const char *      aFormat,
+                                                                    va_list           args)
+{
+    otError        error = OT_ERROR_NONE;
+    uint8_t        buffer[kMaxSpinelFrame];
+    spinel_ssize_t packed;
+    uint16_t       offset;
+
+    // Pack the header, command and key
+    packed = spinel_datatype_pack(buffer, sizeof(buffer), "Cii", SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0 | tid,
+                                  aCommand, aKey);
+
+    VerifyOrExit(packed > 0 && static_cast<size_t>(packed) <= sizeof(buffer), error = OT_ERROR_NO_BUFS);
+
+    offset = static_cast<uint16_t>(packed);
+
+    // Pack the data (if any)
+    if (aFormat)
+    {
+        packed = spinel_datatype_vpack(buffer + offset, sizeof(buffer) - offset, aFormat, args);
+        VerifyOrExit(packed > 0 && static_cast<size_t>(packed + offset) <= sizeof(buffer), error = OT_ERROR_NO_BUFS);
+
+        offset += static_cast<uint16_t>(packed);
+    }
+
+    error = mSpinelInterface.SendFrame(buffer, offset);
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::RequestV(bool              aWait,
+                                                                 uint32_t          command,
+                                                                 spinel_prop_key_t aKey,
+                                                                 const char *      aFormat,
+                                                                 va_list           aArgs)
+{
+    otError      error = OT_ERROR_NONE;
+    spinel_tid_t tid   = (aWait ? GetNextTid() : 0);
+
+    VerifyOrExit(!aWait || tid > 0, error = OT_ERROR_BUSY);
+
+    error = SendCommand(command, aKey, tid, aFormat, aArgs);
+    SuccessOrExit(error);
+
+    if (aKey == SPINEL_PROP_STREAM_RAW)
+    {
+        // not allowed to send another frame before the last frame is done.
+        assert(mTxRadioTid == 0);
+        VerifyOrExit(mTxRadioTid == 0, error = OT_ERROR_BUSY);
+        mTxRadioTid = tid;
+    }
+    else if (aWait)
+    {
+        mWaitingKey = aKey;
+        mWaitingTid = tid;
+        error       = WaitResponse();
+    }
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Request(bool              aWait,
+                                                                uint32_t          aCommand,
+                                                                spinel_prop_key_t aKey,
+                                                                const char *      aFormat,
+                                                                ...)
+{
+    va_list args;
+    va_start(args, aFormat);
+    otError status = RequestV(aWait, aCommand, aKey, aFormat, args);
+    va_end(args);
+    return status;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::HandleTransmitDone(uint32_t          aCommand,
+                                                                        spinel_prop_key_t aKey,
+                                                                        const uint8_t *   aBuffer,
+                                                                        uint16_t          aLength)
+{
+    otError         error        = OT_ERROR_NONE;
+    spinel_status_t status       = SPINEL_STATUS_OK;
+    bool            framePending = false;
+    spinel_ssize_t  unpacked;
+
+    VerifyOrExit(aCommand == SPINEL_CMD_PROP_VALUE_IS && aKey == SPINEL_PROP_LAST_STATUS, error = OT_ERROR_FAILED);
+
+    unpacked = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_UINT_PACKED_S, &status);
+    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+
+    aBuffer += unpacked;
+    aLength -= static_cast<uint16_t>(unpacked);
+
+    unpacked = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_BOOL_S, &framePending);
+    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+
+    aBuffer += unpacked;
+    aLength -= static_cast<uint16_t>(unpacked);
+
+    if (status == SPINEL_STATUS_OK)
+    {
+        SuccessOrExit(error = ParseRadioFrame(mAckRadioFrame, aBuffer, aLength, unpacked));
+        aBuffer += unpacked;
+        aLength -= static_cast<uint16_t>(unpacked);
+    }
+    else
+    {
+        error = SpinelStatusToOtError(status);
+    }
+
+    if ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_SEC) && static_cast<Mac::TxFrame *>(mTransmitFrame)->GetSecurityEnabled())
+    {
+        uint8_t  keyId;
+        uint32_t frameCounter;
+
+        // Replace transmit frame security key index and frame counter with the one filled by RCP
+        unpacked = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_UINT32_S, &keyId,
+                                          &frameCounter);
+        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
+        static_cast<Mac::TxFrame *>(mTransmitFrame)->SetKeyId(keyId);
+        static_cast<Mac::TxFrame *>(mTransmitFrame)->SetFrameCounter(frameCounter);
+    }
+
+exit:
+    mState   = kStateTransmitDone;
+    mTxError = error;
+    LogIfFail("Handle transmit done failed", error);
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Transmit(otRadioFrame &aFrame)
+{
+    otError error = OT_ERROR_INVALID_STATE;
+
+    VerifyOrExit(mState == kStateReceive || (mState == kStateSleep && (mRadioCaps & OT_RADIO_CAPS_SLEEP_TO_TX)),
+                 OT_NOOP);
+
+    mTransmitFrame = &aFrame;
+
+    // `otPlatRadioTxStarted()` is triggered immediately for now, which may be earlier than real started time.
+    otPlatRadioTxStarted(mInstance, mTransmitFrame);
+
+    error = Request(true, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_STREAM_RAW,
+                    SPINEL_DATATYPE_DATA_WLEN_S                     // Frame data
+                                            SPINEL_DATATYPE_UINT8_S // Channel
+                                            SPINEL_DATATYPE_UINT8_S // MaxCsmaBackoffs
+                                            SPINEL_DATATYPE_UINT8_S // MaxFrameRetries
+                                            SPINEL_DATATYPE_BOOL_S  // CsmaCaEnabled
+                                            SPINEL_DATATYPE_BOOL_S  // IsARetx
+                                            SPINEL_DATATYPE_BOOL_S, // SkipAes
+                    mTransmitFrame->mPsdu, mTransmitFrame->mLength, mTransmitFrame->mChannel,
+                    mTransmitFrame->mInfo.mTxInfo.mMaxCsmaBackoffs, mTransmitFrame->mInfo.mTxInfo.mMaxFrameRetries,
+                    mTransmitFrame->mInfo.mTxInfo.mCsmaCaEnabled, mTransmitFrame->mInfo.mTxInfo.mIsARetx,
+                    mTransmitFrame->mInfo.mTxInfo.mIsSecurityProcessed);
+
+    if (error == OT_ERROR_NONE)
+    {
+        // Waiting for `TransmitDone` event.
+        mState        = kStateTransmitting;
+        mTxRadioEndUs = otPlatTimeGet() + TX_WAIT_US;
+    }
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Receive(uint8_t aChannel)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mState != kStateDisabled, error = OT_ERROR_INVALID_STATE);
+
+    if (mChannel != aChannel)
+    {
+        error = Set(SPINEL_PROP_PHY_CHAN, SPINEL_DATATYPE_UINT8_S, aChannel);
+        SuccessOrExit(error);
+        mChannel = aChannel;
+    }
+
+    if (mState == kStateSleep)
+    {
+        error = Set(SPINEL_PROP_MAC_RAW_STREAM_ENABLED, SPINEL_DATATYPE_BOOL_S, true);
+        SuccessOrExit(error);
+    }
+
+    if (mTxRadioTid != 0)
+    {
+        FreeTid(mTxRadioTid);
+        mTxRadioTid = 0;
+    }
+
+    mState = kStateReceive;
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Sleep(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    switch (mState)
+    {
+    case kStateReceive:
+        error = Set(SPINEL_PROP_MAC_RAW_STREAM_ENABLED, SPINEL_DATATYPE_BOOL_S, false);
+        SuccessOrExit(error);
+
+        mState = kStateSleep;
+        break;
+
+    case kStateSleep:
+        break;
+
+    default:
+        error = OT_ERROR_INVALID_STATE;
+        break;
+    }
+
+exit:
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Enable(otInstance *aInstance)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(!IsEnabled(), OT_NOOP);
+
+    mInstance = aInstance;
+
+    SuccessOrExit(error = Set(SPINEL_PROP_PHY_ENABLED, SPINEL_DATATYPE_BOOL_S, true));
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_PANID, SPINEL_DATATYPE_UINT16_S, mPanId));
+    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_SADDR, SPINEL_DATATYPE_UINT16_S, mShortAddress));
+    SuccessOrExit(error = Get(SPINEL_PROP_PHY_RX_SENSITIVITY, SPINEL_DATATYPE_INT8_S, &mRxSensitivity));
+
+    mState = kStateSleep;
+
+exit:
+    if (error != OT_ERROR_NONE)
+    {
+        otLogWarnPlat("RadioSpinel enable: %s", otThreadErrorToString(error));
+        error = OT_ERROR_FAILED;
+    }
+
+    return error;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::Disable(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(IsEnabled(), OT_NOOP);
+    VerifyOrExit(mState == kStateSleep, error = OT_ERROR_INVALID_STATE);
+
+    SuccessOrDie(Set(SPINEL_PROP_PHY_ENABLED, SPINEL_DATATYPE_BOOL_S, false));
+    mState    = kStateDisabled;
+    mInstance = nullptr;
+
+exit:
+    return error;
+}
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+template <typename InterfaceType, typename ProcessContextType>
+otError RadioSpinel<InterfaceType, ProcessContextType>::PlatDiagProcess(const char *aString,
+                                                                        char *      aOutput,
+                                                                        size_t      aOutputMaxLen)
+{
+    otError error;
+
+    mDiagOutput       = aOutput;
+    mDiagOutputMaxLen = aOutputMaxLen;
+
+    error = Set(SPINEL_PROP_NEST_STREAM_MFG, SPINEL_DATATYPE_UTF8_S, aString);
+
+    mDiagOutput       = nullptr;
+    mDiagOutputMaxLen = 0;
+
+    return error;
+}
+#endif
+
+template <typename InterfaceType, typename ProcessContextType>
+uint32_t RadioSpinel<InterfaceType, ProcessContextType>::GetRadioChannelMask(bool aPreferred)
+{
+    uint8_t        maskBuffer[kChannelMaskBufferSize];
+    otError        error       = OT_ERROR_NONE;
+    uint32_t       channelMask = 0;
+    const uint8_t *maskData    = maskBuffer;
+    spinel_size_t  maskLength  = sizeof(maskBuffer);
+
+    SuccessOrDie(Get(aPreferred ? SPINEL_PROP_PHY_CHAN_PREFERRED : SPINEL_PROP_PHY_CHAN_SUPPORTED,
+                     SPINEL_DATATYPE_DATA_S, maskBuffer, &maskLength));
+
+    while (maskLength > 0)
+    {
+        uint8_t        channel;
+        spinel_ssize_t unpacked;
+
+        unpacked = spinel_datatype_unpack(maskData, maskLength, SPINEL_DATATYPE_UINT8_S, &channel);
+        VerifyOrExit(unpacked > 0, error = OT_ERROR_FAILED);
+        VerifyOrExit(channel < kChannelMaskBufferSize, error = OT_ERROR_PARSE);
+        channelMask |= (1UL << channel);
+
+        maskData += unpacked;
+        maskLength -= static_cast<spinel_size_t>(unpacked);
+    }
+
+exit:
+    LogIfFail("Get radio channel mask failed", error);
+    return channelMask;
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+otRadioState RadioSpinel<InterfaceType, ProcessContextType>::GetState(void) const
+{
+    static const otRadioState sOtRadioStateMap[] = {
+        OT_RADIO_STATE_DISABLED, OT_RADIO_STATE_SLEEP,    OT_RADIO_STATE_RECEIVE,
+        OT_RADIO_STATE_TRANSMIT, OT_RADIO_STATE_TRANSMIT,
+    };
+
+    return sOtRadioStateMap[mState];
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+void RadioSpinel<InterfaceType, ProcessContextType>::CalcRcpTimeOffset(void)
+{
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
+    otError        error = OT_ERROR_NONE;
+    uint64_t       localTxTimestamp;
+    uint64_t       localRxTimestamp;
+    uint64_t       remoteTimestamp = 0;
+    uint8_t        buffer[sizeof(remoteTimestamp)];
+    spinel_ssize_t packed;
+
+    otLogInfoPlat("Trying to get RCP time offset");
+
+    /*
+     * Use a modified Network Time Protocol(NTP) to calculate the time offset
+     * Assume the time offset is D so that local can calculate remote time with,
+     *         T' = T + D
+     * Where T is the local time and T' is the remote time.
+     * The time offset is calculated using timestamp measured at local and remote.
+     *
+     *              T0  P    P T2
+     *  local time --+----+----+--->
+     *                \   |   ^
+     *              get\  |  /is
+     *                  v | /
+     * remote time -------+--------->
+     *                    T1'
+     *
+     * Based on the assumptions,
+     * 1. If the propagation time(P) from local to remote and from remote to local are same.
+     * 2. Both the host and RCP can accurately measure the time they send or receive a message.
+     * The degree to which these assumptions hold true determines the accuracy of the offset.
+     * Then,
+     *         T1' = T0 + P + D and T1' = T2 - P + D
+     * Time offset can be calculated with,
+     *         D = T1' - ((T0 + T2)/ 2)
+     */
+
+    VerifyOrExit(!mIsTimeSynced || (otPlatTimeGet() >= GetNextRadioTimeRecalcStart()), OT_NOOP);
+    packed = spinel_datatype_pack(buffer, sizeof(buffer), SPINEL_DATATYPE_UINT64_S, remoteTimestamp);
+    VerifyOrExit(packed > 0 && static_cast<size_t>(packed) <= sizeof(buffer), error = OT_ERROR_NO_BUFS);
+
+    localTxTimestamp = otPlatTimeGet();
+
+    // Dummy timestamp payload to make request length same as response
+    error = GetWithParam(SPINEL_PROP_RCP_TIMESTAMP, buffer, packed, SPINEL_DATATYPE_UINT64_S, &remoteTimestamp);
+
+    localRxTimestamp = otPlatTimeGet();
+
+    VerifyOrExit(error == OT_ERROR_NONE, mRadioTimeRecalcStart = localRxTimestamp);
+
+    mRadioTimeOffset      = remoteTimestamp - ((localRxTimestamp / 2) + (localTxTimestamp / 2));
+    mIsTimeSynced         = true;
+    mRadioTimeRecalcStart = localRxTimestamp + RCP_TIME_OFFSET_CHECK_INTERVAL;
+
+exit:
+    LogIfFail("Error calculating RCP time offset: %s", error);
+#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
+}
+
+template <typename InterfaceType, typename ProcessContextType>
+uint64_t RadioSpinel<InterfaceType, ProcessContextType>::GetNow(void)
+{
+    return mIsTimeSynced ? (otPlatTimeGet() + static_cast<uint64_t>(mRadioTimeOffset)) : UINT64_MAX;
+}
+
+} // namespace Spinel
+} // namespace ot
diff --git a/src/lib/spinel/spinel.c b/src/lib/spinel/spinel.c
new file mode 100644
index 0000000..ae0753f
--- /dev/null
+++ b/src/lib/spinel/spinel.c
@@ -0,0 +1,3047 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  -------------------------------------------------------------------
+ *
+ *  ## Unit Test ##
+ *
+ *  This file includes its own unit test. To compile the unit test,
+ *  simply compile this file with the macro SPINEL_SELF_TEST set to 1.
+ *  For example:
+ *
+ *      cc spinel.c -Wall -DSPINEL_SELF_TEST=1 -o spinel
+ *
+ *  -------------------------------------------------------------------
+ */
+
+// ----------------------------------------------------------------------------
+// MARK: -
+// MARK: Headers
+
+#include "spinel.h"
+
+#include <errno.h>
+#include <limits.h>
+
+#ifndef SPINEL_PLATFORM_HEADER
+/* These are all already included in the spinel platform header
+ * if SPINEL_PLATFORM_HEADER was defined.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif // #ifndef SPINEL_PLATFORM_HEADER
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+// IAR's errno.h apparently doesn't define EOVERFLOW.
+#ifndef EOVERFLOW
+// There is no real good choice for what to set
+// errno to in this case, so we just pick the
+// value '1' somewhat arbitrarily.
+#define EOVERFLOW 1
+#endif
+
+// IAR's errno.h apparently doesn't define EINVAL.
+#ifndef EINVAL
+// There is no real good choice for what to set
+// errno to in this case, so we just pick the
+// value '1' somewhat arbitrarily.
+#define EINVAL 1
+#endif
+
+// IAR's errno.h apparently doesn't define ENOMEM.
+#ifndef ENOMEM
+// There is no real good choice for what to set
+// errno to in this case, so we just pick the
+// value '1' somewhat arbitrarily.
+#define ENOMEM 1
+#endif
+
+#ifndef SPINEL_PLATFORM_SHOULD_LOG_ASSERTS
+#define SPINEL_PLATFORM_SHOULD_LOG_ASSERTS 0
+#endif
+
+#ifndef SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
+#define SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR 0
+#endif
+
+#ifndef SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
+#define SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF 0
+#endif
+
+#ifndef SPINEL_SELF_TEST
+#define SPINEL_SELF_TEST 0
+#endif
+
+#if defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
+#error "SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR is set but errno is already defined."
+#endif
+
+// Work-around for platforms that don't implement the `errno` variable.
+#if !defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
+static int spinel_errno_workaround_;
+#define errno spinel_errno_workaround_
+#endif // SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
+
+#ifndef assert_printf
+#if SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
+#define assert_printf(fmt, ...) printf(__FILE__ ":%d: " fmt "\n", __LINE__, __VA_ARGS__)
+#else // if SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
+#define assert_printf(fmt, ...) fprintf(stderr, __FILE__ ":%d: " fmt "\n", __LINE__, __VA_ARGS__)
+#endif // else SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
+#endif
+
+#ifndef require_action
+#if SPINEL_PLATFORM_SHOULD_LOG_ASSERTS
+#define require_action(c, l, a)                           \
+    do                                                    \
+    {                                                     \
+        if (!(c))                                         \
+        {                                                 \
+            assert_printf("Requirement Failed (%s)", #c); \
+            a;                                            \
+            goto l;                                       \
+        }                                                 \
+    } while (0)
+#else // if DEBUG
+#define require_action(c, l, a) \
+    do                          \
+    {                           \
+        if (!(c))               \
+        {                       \
+            a;                  \
+            goto l;             \
+        }                       \
+    } while (0)
+#endif // else DEBUG
+#endif // ifndef require_action
+
+#ifndef require
+#define require(c, l) require_action(c, l, {})
+#endif
+
+#ifndef strnlen
+static size_t spinel_strnlen(const char *s, size_t maxlen)
+{
+    size_t ret;
+
+    for (ret = 0; (ret < maxlen) && (s[ret] != 0); ret++)
+    {
+        // Empty loop.
+    }
+
+    return ret;
+}
+#else
+#define spinel_strnlen strnlen
+#endif
+
+typedef struct
+{
+    va_list obj;
+} va_list_obj;
+
+#define SPINEL_MAX_PACK_LENGTH 32767
+
+// ----------------------------------------------------------------------------
+
+// This function validates whether a given byte sequence (string) follows UTF8 encoding.
+static bool spinel_validate_utf8(const uint8_t *string)
+{
+    bool    ret = true;
+    uint8_t byte;
+    uint8_t continuation_bytes = 0;
+
+    while ((byte = *string++) != 0)
+    {
+        if ((byte & 0x80) == 0)
+        {
+            continue;
+        }
+
+        // This is a leading byte 1xxx-xxxx.
+
+        if ((byte & 0x40) == 0) // 10xx-xxxx
+        {
+            // We got a continuation byte pattern without seeing a leading byte earlier.
+            ret = false;
+            goto bail;
+        }
+        else if ((byte & 0x20) == 0) // 110x-xxxx
+        {
+            continuation_bytes = 1;
+        }
+        else if ((byte & 0x10) == 0) // 1110-xxxx
+        {
+            continuation_bytes = 2;
+        }
+        else if ((byte & 0x08) == 0) // 1111-0xxx
+        {
+            continuation_bytes = 3;
+        }
+        else // 1111-1xxx  (invalid pattern).
+        {
+            ret = false;
+            goto bail;
+        }
+
+        while (continuation_bytes-- != 0)
+        {
+            byte = *string++;
+
+            // Verify the continuation byte pattern 10xx-xxxx
+            if ((byte & 0xc0) != 0x80)
+            {
+                ret = false;
+                goto bail;
+            }
+        }
+    }
+
+bail:
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+spinel_ssize_t spinel_packed_uint_decode(const uint8_t *bytes, spinel_size_t len, unsigned int *value_ptr)
+{
+    spinel_ssize_t ret   = 0;
+    unsigned int   value = 0;
+
+    unsigned int i = 0;
+
+    do
+    {
+        if ((len < sizeof(uint8_t)) || (i >= sizeof(unsigned int) * CHAR_BIT))
+        {
+            ret = -1;
+            break;
+        }
+
+        value |= (unsigned int)(bytes[0] & 0x7F) << i;
+        i += 7;
+        ret += sizeof(uint8_t);
+        bytes += sizeof(uint8_t);
+        len -= sizeof(uint8_t);
+    } while ((bytes[-1] & 0x80) == 0x80);
+
+    if ((ret > 0) && (value_ptr != NULL))
+    {
+        *value_ptr = value;
+    }
+
+    return ret;
+}
+
+spinel_ssize_t spinel_packed_uint_size(unsigned int value)
+{
+    spinel_ssize_t ret;
+
+    if (value < (1 << 7))
+    {
+        ret = 1;
+    }
+    else if (value < (1 << 14))
+    {
+        ret = 2;
+    }
+    else if (value < (1 << 21))
+    {
+        ret = 3;
+    }
+    else if (value < (1 << 28))
+    {
+        ret = 4;
+    }
+    else
+    {
+        ret = 5;
+    }
+
+    return ret;
+}
+
+spinel_ssize_t spinel_packed_uint_encode(uint8_t *bytes, spinel_size_t len, unsigned int value)
+{
+    const spinel_ssize_t encoded_size = spinel_packed_uint_size(value);
+
+    if ((spinel_ssize_t)len >= encoded_size)
+    {
+        spinel_ssize_t i;
+
+        for (i = 0; i != encoded_size - 1; ++i)
+        {
+            *bytes++ = (value & 0x7F) | 0x80;
+            value    = (value >> 7);
+        }
+
+        *bytes++ = (value & 0x7F);
+    }
+
+    return encoded_size;
+}
+
+const char *spinel_next_packed_datatype(const char *pack_format)
+{
+    int depth = 0;
+
+    do
+    {
+        switch (*++pack_format)
+        {
+        case '(':
+            depth++;
+            break;
+
+        case ')':
+            depth--;
+
+            if (depth == 0)
+            {
+                pack_format++;
+            }
+
+            break;
+        }
+    } while ((depth > 0) && *pack_format != 0);
+
+    return pack_format;
+}
+
+static spinel_ssize_t spinel_datatype_vunpack_(bool           in_place,
+                                               const uint8_t *data_in,
+                                               spinel_size_t  data_len,
+                                               const char *   pack_format,
+                                               va_list_obj *  args)
+{
+    spinel_ssize_t ret = 0;
+
+    // Buffer length sanity check
+    require_action(data_len <= SPINEL_MAX_PACK_LENGTH, bail, (ret = -1, errno = EINVAL));
+
+    for (; *pack_format != 0; pack_format = spinel_next_packed_datatype(pack_format))
+    {
+        if (*pack_format == ')')
+        {
+            // Don't go past the end of a struct.
+            break;
+        }
+
+        switch ((spinel_datatype_t)pack_format[0])
+        {
+        case SPINEL_DATATYPE_BOOL_C:
+        {
+            bool *arg_ptr = va_arg(args->obj, bool *);
+            require_action(data_len >= sizeof(uint8_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = data_in[0] != 0;
+            }
+
+            ret += sizeof(uint8_t);
+            data_in += sizeof(uint8_t);
+            data_len -= sizeof(uint8_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT8_C:
+        case SPINEL_DATATYPE_UINT8_C:
+        {
+            uint8_t *arg_ptr = va_arg(args->obj, uint8_t *);
+            require_action(data_len >= sizeof(uint8_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = data_in[0];
+            }
+
+            ret += sizeof(uint8_t);
+            data_in += sizeof(uint8_t);
+            data_len -= sizeof(uint8_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT16_C:
+        case SPINEL_DATATYPE_UINT16_C:
+        {
+            uint16_t *arg_ptr = va_arg(args->obj, uint16_t *);
+            require_action(data_len >= sizeof(uint16_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = (uint16_t)((data_in[1] << 8) | data_in[0]);
+            }
+
+            ret += sizeof(uint16_t);
+            data_in += sizeof(uint16_t);
+            data_len -= sizeof(uint16_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT32_C:
+        case SPINEL_DATATYPE_UINT32_C:
+        {
+            uint32_t *arg_ptr = va_arg(args->obj, uint32_t *);
+            require_action(data_len >= sizeof(uint32_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = (uint32_t)((data_in[3] << 24) | (data_in[2] << 16) | (data_in[1] << 8) | data_in[0]);
+            }
+
+            ret += sizeof(uint32_t);
+            data_in += sizeof(uint32_t);
+            data_len -= sizeof(uint32_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT64_C:
+        case SPINEL_DATATYPE_UINT64_C:
+        {
+            uint64_t *arg_ptr = va_arg(args->obj, uint64_t *);
+            require_action(data_len >= sizeof(uint64_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                uint32_t l32 = (uint32_t)((data_in[3] << 24) | (data_in[2] << 16) | (data_in[1] << 8) | data_in[0]);
+                uint32_t h32 = (uint32_t)((data_in[7] << 24) | (data_in[6] << 16) | (data_in[5] << 8) | data_in[4]);
+
+                *arg_ptr = ((uint64_t)l32) | (((uint64_t)h32) << 32);
+            }
+
+            ret += sizeof(uint64_t);
+            data_in += sizeof(uint64_t);
+            data_len -= sizeof(uint64_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_IPv6ADDR_C:
+        {
+            require_action(data_len >= sizeof(spinel_ipv6addr_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (in_place)
+            {
+                spinel_ipv6addr_t *arg = va_arg(args->obj, spinel_ipv6addr_t *);
+                if (arg)
+                {
+                    memcpy(arg, data_in, sizeof(spinel_ipv6addr_t));
+                }
+            }
+            else
+            {
+                const spinel_ipv6addr_t **arg_ptr = va_arg(args->obj, const spinel_ipv6addr_t **);
+                if (arg_ptr)
+                {
+                    *arg_ptr = (const spinel_ipv6addr_t *)data_in;
+                }
+            }
+
+            ret += sizeof(spinel_ipv6addr_t);
+            data_in += sizeof(spinel_ipv6addr_t);
+            data_len -= sizeof(spinel_ipv6addr_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_EUI64_C:
+        {
+            require_action(data_len >= sizeof(spinel_eui64_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (in_place)
+            {
+                spinel_eui64_t *arg = va_arg(args->obj, spinel_eui64_t *);
+                if (arg)
+                {
+                    memcpy(arg, data_in, sizeof(spinel_eui64_t));
+                }
+            }
+            else
+            {
+                const spinel_eui64_t **arg_ptr = va_arg(args->obj, const spinel_eui64_t **);
+                if (arg_ptr)
+                {
+                    *arg_ptr = (const spinel_eui64_t *)data_in;
+                }
+            }
+
+            ret += sizeof(spinel_eui64_t);
+            data_in += sizeof(spinel_eui64_t);
+            data_len -= sizeof(spinel_eui64_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_EUI48_C:
+        {
+            require_action(data_len >= sizeof(spinel_eui48_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (in_place)
+            {
+                spinel_eui48_t *arg = va_arg(args->obj, spinel_eui48_t *);
+                if (arg)
+                {
+                    memcpy(arg, data_in, sizeof(spinel_eui48_t));
+                }
+            }
+            else
+            {
+                const spinel_eui48_t **arg_ptr = va_arg(args->obj, const spinel_eui48_t **);
+                if (arg_ptr)
+                {
+                    *arg_ptr = (const spinel_eui48_t *)data_in;
+                }
+            }
+
+            ret += sizeof(spinel_eui48_t);
+            data_in += sizeof(spinel_eui48_t);
+            data_len -= sizeof(spinel_eui48_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_UINT_PACKED_C:
+        {
+            unsigned int * arg_ptr = va_arg(args->obj, unsigned int *);
+            spinel_ssize_t pui_len = spinel_packed_uint_decode(data_in, data_len, arg_ptr);
+
+            // Range check
+            require_action(NULL == arg_ptr || (*arg_ptr < SPINEL_MAX_UINT_PACKED), bail, (ret = -1, errno = ERANGE));
+
+            require(pui_len > 0, bail);
+
+            require(pui_len <= (spinel_ssize_t)data_len, bail);
+
+            ret += pui_len;
+            data_in += pui_len;
+            data_len -= (spinel_size_t)pui_len;
+            break;
+        }
+
+        case SPINEL_DATATYPE_UTF8_C:
+        {
+            size_t len;
+
+            // Make sure we have at least one byte.
+            require_action(data_len > 0, bail, (ret = -1, errno = EOVERFLOW));
+
+            // Add 1 for zero termination. If not zero terminated,
+            // len will then be data_len+1, which we will detect
+            // in the next check.
+            len = spinel_strnlen((const char *)data_in, data_len) + 1;
+
+            // Verify that the string is zero terminated.
+            require_action(len <= data_len, bail, (ret = -1, errno = EOVERFLOW));
+
+            // Verify the string follows valid UTF8 encoding.
+            require_action(spinel_validate_utf8(data_in), bail, (ret = -1, errno = EINVAL));
+
+            if (in_place)
+            {
+                char * arg     = va_arg(args->obj, char *);
+                size_t len_arg = va_arg(args->obj, size_t);
+                if (arg)
+                {
+                    require_action(len_arg >= len, bail, (ret = -1, errno = ENOMEM));
+                    memcpy(arg, data_in, len);
+                }
+            }
+            else
+            {
+                const char **arg_ptr = va_arg(args->obj, const char **);
+                if (arg_ptr)
+                {
+                    *arg_ptr = (const char *)data_in;
+                }
+            }
+
+            ret += (spinel_size_t)len;
+            data_in += len;
+            data_len -= (spinel_size_t)len;
+            break;
+        }
+
+        case SPINEL_DATATYPE_DATA_C:
+        case SPINEL_DATATYPE_DATA_WLEN_C:
+        {
+            spinel_ssize_t pui_len       = 0;
+            uint16_t       block_len     = 0;
+            const uint8_t *block_ptr     = data_in;
+            void *         arg_ptr       = va_arg(args->obj, void *);
+            unsigned int * block_len_ptr = va_arg(args->obj, unsigned int *);
+            char           nextformat    = *spinel_next_packed_datatype(pack_format);
+
+            if ((pack_format[0] == SPINEL_DATATYPE_DATA_WLEN_C) || ((nextformat != 0) && (nextformat != ')')))
+            {
+                pui_len = spinel_datatype_unpack(data_in, data_len, SPINEL_DATATYPE_UINT16_S, &block_len);
+                block_ptr += pui_len;
+
+                require(pui_len > 0, bail);
+                require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
+            }
+            else
+            {
+                block_len = (uint16_t)data_len;
+                pui_len   = 0;
+            }
+
+            require_action((spinel_ssize_t)data_len >= (block_len + pui_len), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (in_place)
+            {
+                require_action(NULL != block_len_ptr && *block_len_ptr >= block_len, bail, (ret = -1, errno = EINVAL));
+                memcpy(arg_ptr, block_ptr, block_len);
+            }
+            else
+            {
+                const uint8_t **block_ptr_ptr = (const uint8_t **)arg_ptr;
+                if (NULL != block_ptr_ptr)
+                {
+                    *block_ptr_ptr = block_ptr;
+                }
+            }
+
+            if (NULL != block_len_ptr)
+            {
+                *block_len_ptr = block_len;
+            }
+
+            block_len += (uint16_t)pui_len;
+            ret += block_len;
+            data_in += block_len;
+            data_len -= block_len;
+            break;
+        }
+
+        case 'T':
+        case SPINEL_DATATYPE_STRUCT_C:
+        {
+            spinel_ssize_t pui_len    = 0;
+            uint16_t       block_len  = 0;
+            spinel_ssize_t actual_len = 0;
+            const uint8_t *block_ptr  = data_in;
+            char           nextformat = *spinel_next_packed_datatype(pack_format);
+
+            if ((pack_format[0] == SPINEL_DATATYPE_STRUCT_C) || ((nextformat != 0) && (nextformat != ')')))
+            {
+                pui_len = spinel_datatype_unpack(data_in, data_len, SPINEL_DATATYPE_UINT16_S, &block_len);
+                block_ptr += pui_len;
+
+                require(pui_len > 0, bail);
+                require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
+            }
+            else
+            {
+                block_len = (uint16_t)data_len;
+                pui_len   = 0;
+            }
+
+            require_action((spinel_ssize_t)data_len >= (block_len + pui_len), bail, (ret = -1, errno = EOVERFLOW));
+
+            actual_len = spinel_datatype_vunpack_(false, block_ptr, block_len, pack_format + 2, args);
+
+            require_action(actual_len > -1, bail, (ret = -1, errno = EOVERFLOW));
+
+            if (pui_len)
+            {
+                block_len += (uint16_t)pui_len;
+            }
+            else
+            {
+                block_len = (uint16_t)actual_len;
+            }
+
+            ret += block_len;
+            data_in += block_len;
+            data_len -= block_len;
+            break;
+        }
+
+        case '.':
+            // Skip.
+            break;
+
+        case SPINEL_DATATYPE_ARRAY_C:
+        default:
+            // Unsupported Type!
+            ret   = -1;
+            errno = EINVAL;
+            goto bail;
+        }
+    }
+
+    return ret;
+
+bail:
+    return ret;
+}
+
+spinel_ssize_t spinel_datatype_unpack_in_place(const uint8_t *data_in,
+                                               spinel_size_t  data_len,
+                                               const char *   pack_format,
+                                               ...)
+{
+    spinel_ssize_t ret;
+    va_list_obj    args;
+    va_start(args.obj, pack_format);
+
+    ret = spinel_datatype_vunpack_(true, data_in, data_len, pack_format, &args);
+
+    va_end(args.obj);
+    return ret;
+}
+
+spinel_ssize_t spinel_datatype_unpack(const uint8_t *data_in, spinel_size_t data_len, const char *pack_format, ...)
+{
+    spinel_ssize_t ret;
+    va_list_obj    args;
+    va_start(args.obj, pack_format);
+
+    ret = spinel_datatype_vunpack_(false, data_in, data_len, pack_format, &args);
+
+    va_end(args.obj);
+    return ret;
+}
+
+spinel_ssize_t spinel_datatype_vunpack_in_place(const uint8_t *data_in,
+                                                spinel_size_t  data_len,
+                                                const char *   pack_format,
+                                                va_list        args)
+{
+    spinel_ssize_t ret;
+    va_list_obj    args_obj;
+    va_copy(args_obj.obj, args);
+
+    ret = spinel_datatype_vunpack_(true, data_in, data_len, pack_format, &args_obj);
+
+    va_end(args_obj.obj);
+    return ret;
+}
+
+spinel_ssize_t spinel_datatype_vunpack(const uint8_t *data_in,
+                                       spinel_size_t  data_len,
+                                       const char *   pack_format,
+                                       va_list        args)
+{
+    spinel_ssize_t ret;
+    va_list_obj    args_obj;
+    va_copy(args_obj.obj, args);
+
+    ret = spinel_datatype_vunpack_(false, data_in, data_len, pack_format, &args_obj);
+
+    va_end(args_obj.obj);
+    return ret;
+}
+
+static spinel_ssize_t spinel_datatype_vpack_(uint8_t *     data_out,
+                                             spinel_size_t data_len_max,
+                                             const char *  pack_format,
+                                             va_list_obj * args)
+{
+    spinel_ssize_t ret = 0;
+
+    // Buffer length sanity check
+    require_action(data_len_max <= SPINEL_MAX_PACK_LENGTH, bail, (ret = -1, errno = EINVAL));
+
+    if (data_out == NULL)
+    {
+        data_len_max = 0;
+    }
+
+    for (; *pack_format != 0; pack_format = spinel_next_packed_datatype(pack_format))
+    {
+        if (*pack_format == ')')
+        {
+            // Don't go past the end of a struct.
+            break;
+        }
+
+        switch ((spinel_datatype_t)*pack_format)
+        {
+        case SPINEL_DATATYPE_BOOL_C:
+        {
+            bool arg = (bool)va_arg(args->obj, int);
+            ret += sizeof(uint8_t);
+
+            if (data_len_max >= sizeof(uint8_t))
+            {
+                data_out[0] = (arg != false);
+                data_out += sizeof(uint8_t);
+                data_len_max -= sizeof(uint8_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT8_C:
+        case SPINEL_DATATYPE_UINT8_C:
+        {
+            uint8_t arg = (uint8_t)va_arg(args->obj, int);
+            ret += sizeof(uint8_t);
+
+            if (data_len_max >= sizeof(uint8_t))
+            {
+                data_out[0] = arg;
+                data_out += sizeof(uint8_t);
+                data_len_max -= sizeof(uint8_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT16_C:
+        case SPINEL_DATATYPE_UINT16_C:
+        {
+            uint16_t arg = (uint16_t)va_arg(args->obj, int);
+            ret += sizeof(uint16_t);
+
+            if (data_len_max >= sizeof(uint16_t))
+            {
+                data_out[1] = (arg >> 8) & 0xff;
+                data_out[0] = (arg >> 0) & 0xff;
+                data_out += sizeof(uint16_t);
+                data_len_max -= sizeof(uint16_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT32_C:
+        case SPINEL_DATATYPE_UINT32_C:
+        {
+            uint32_t arg = (uint32_t)va_arg(args->obj, int);
+            ret += sizeof(uint32_t);
+
+            if (data_len_max >= sizeof(uint32_t))
+            {
+                data_out[3] = (arg >> 24) & 0xff;
+                data_out[2] = (arg >> 16) & 0xff;
+                data_out[1] = (arg >> 8) & 0xff;
+                data_out[0] = (arg >> 0) & 0xff;
+                data_out += sizeof(uint32_t);
+                data_len_max -= sizeof(uint32_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT64_C:
+        case SPINEL_DATATYPE_UINT64_C:
+        {
+            uint64_t arg = va_arg(args->obj, uint64_t);
+
+            ret += sizeof(uint64_t);
+
+            if (data_len_max >= sizeof(uint64_t))
+            {
+                data_out[7] = (arg >> 56) & 0xff;
+                data_out[6] = (arg >> 48) & 0xff;
+                data_out[5] = (arg >> 40) & 0xff;
+                data_out[4] = (arg >> 32) & 0xff;
+                data_out[3] = (arg >> 24) & 0xff;
+                data_out[2] = (arg >> 16) & 0xff;
+                data_out[1] = (arg >> 8) & 0xff;
+                data_out[0] = (arg >> 0) & 0xff;
+                data_out += sizeof(uint64_t);
+                data_len_max -= sizeof(uint64_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_IPv6ADDR_C:
+        {
+            spinel_ipv6addr_t *arg = va_arg(args->obj, spinel_ipv6addr_t *);
+            ret += sizeof(spinel_ipv6addr_t);
+
+            if (data_len_max >= sizeof(spinel_ipv6addr_t))
+            {
+                *(spinel_ipv6addr_t *)data_out = *arg;
+                data_out += sizeof(spinel_ipv6addr_t);
+                data_len_max -= sizeof(spinel_ipv6addr_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_EUI48_C:
+        {
+            spinel_eui48_t *arg = va_arg(args->obj, spinel_eui48_t *);
+            ret += sizeof(spinel_eui48_t);
+
+            if (data_len_max >= sizeof(spinel_eui48_t))
+            {
+                *(spinel_eui48_t *)data_out = *arg;
+                data_out += sizeof(spinel_eui48_t);
+                data_len_max -= sizeof(spinel_eui48_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_EUI64_C:
+        {
+            spinel_eui64_t *arg = va_arg(args->obj, spinel_eui64_t *);
+            ret += sizeof(spinel_eui64_t);
+
+            if (data_len_max >= sizeof(spinel_eui64_t))
+            {
+                *(spinel_eui64_t *)data_out = *arg;
+                data_out += sizeof(spinel_eui64_t);
+                data_len_max -= sizeof(spinel_eui64_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_UINT_PACKED_C:
+        {
+            uint32_t       arg = va_arg(args->obj, uint32_t);
+            spinel_ssize_t encoded_size;
+
+            // Range Check
+            require_action(arg < SPINEL_MAX_UINT_PACKED, bail, {
+                ret   = -1;
+                errno = EINVAL;
+            });
+
+            encoded_size = spinel_packed_uint_encode(data_out, data_len_max, arg);
+            ret += encoded_size;
+
+            if ((spinel_ssize_t)data_len_max >= encoded_size)
+            {
+                data_out += encoded_size;
+                data_len_max -= (spinel_size_t)encoded_size;
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_UTF8_C:
+        {
+            const char *string_arg     = va_arg(args->obj, const char *);
+            size_t      string_arg_len = 0;
+
+            if (string_arg)
+            {
+                string_arg_len = strlen(string_arg) + 1;
+            }
+            else
+            {
+                string_arg     = "";
+                string_arg_len = 1;
+            }
+
+            ret += (spinel_size_t)string_arg_len;
+
+            if (data_len_max >= string_arg_len)
+            {
+                memcpy(data_out, string_arg, string_arg_len);
+
+                data_out += string_arg_len;
+                data_len_max -= (spinel_size_t)string_arg_len;
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_DATA_WLEN_C:
+        case SPINEL_DATATYPE_DATA_C:
+        {
+            const uint8_t *arg           = va_arg(args->obj, const uint8_t *);
+            uint32_t       data_size_arg = va_arg(args->obj, uint32_t);
+            spinel_ssize_t size_len      = 0;
+            char           nextformat    = *spinel_next_packed_datatype(pack_format);
+
+            if ((pack_format[0] == SPINEL_DATATYPE_DATA_WLEN_C) || ((nextformat != 0) && (nextformat != ')')))
+            {
+                size_len = spinel_datatype_pack(data_out, data_len_max, SPINEL_DATATYPE_UINT16_S, data_size_arg);
+                require_action(size_len > 0, bail, {
+                    ret   = -1;
+                    errno = EINVAL;
+                });
+            }
+
+            ret += (spinel_size_t)size_len + data_size_arg;
+
+            if (data_len_max >= (spinel_size_t)size_len + data_size_arg)
+            {
+                data_out += size_len;
+                data_len_max -= (spinel_size_t)size_len;
+
+                if (data_out && arg)
+                {
+                    memcpy(data_out, arg, data_size_arg);
+                }
+
+                data_out += data_size_arg;
+                data_len_max -= data_size_arg;
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case 'T':
+        case SPINEL_DATATYPE_STRUCT_C:
+        {
+            spinel_ssize_t struct_len = 0;
+            spinel_ssize_t size_len   = 0;
+            char           nextformat = *spinel_next_packed_datatype(pack_format);
+
+            require_action(pack_format[1] == '(', bail, {
+                ret   = -1;
+                errno = EINVAL;
+            });
+
+            // First we figure out the size of the struct
+            {
+                va_list_obj subargs;
+                va_copy(subargs.obj, args->obj);
+                struct_len = spinel_datatype_vpack_(NULL, 0, pack_format + 2, &subargs);
+                va_end(subargs.obj);
+            }
+
+            if ((pack_format[0] == SPINEL_DATATYPE_STRUCT_C) || ((nextformat != 0) && (nextformat != ')')))
+            {
+                size_len = spinel_datatype_pack(data_out, data_len_max, SPINEL_DATATYPE_UINT16_S, struct_len);
+                require_action(size_len > 0, bail, {
+                    ret   = -1;
+                    errno = EINVAL;
+                });
+            }
+
+            ret += size_len + struct_len;
+
+            if (struct_len + size_len <= (spinel_ssize_t)data_len_max)
+            {
+                data_out += size_len;
+                data_len_max -= (spinel_size_t)size_len;
+
+                struct_len = spinel_datatype_vpack_(data_out, data_len_max, pack_format + 2, args);
+
+                data_out += struct_len;
+                data_len_max -= (spinel_size_t)struct_len;
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case '.':
+            // Skip.
+            break;
+
+        default:
+            // Unsupported Type!
+            ret   = -1;
+            errno = EINVAL;
+            goto bail;
+        }
+    }
+
+bail:
+    return ret;
+}
+
+spinel_ssize_t spinel_datatype_pack(uint8_t *data_out, spinel_size_t data_len_max, const char *pack_format, ...)
+{
+    int         ret;
+    va_list_obj args;
+    va_start(args.obj, pack_format);
+
+    ret = spinel_datatype_vpack_(data_out, data_len_max, pack_format, &args);
+
+    va_end(args.obj);
+    return ret;
+}
+
+spinel_ssize_t spinel_datatype_vpack(uint8_t *     data_out,
+                                     spinel_size_t data_len_max,
+                                     const char *  pack_format,
+                                     va_list       args)
+{
+    int         ret;
+    va_list_obj args_obj;
+    va_copy(args_obj.obj, args);
+
+    ret = spinel_datatype_vpack_(data_out, data_len_max, pack_format, &args_obj);
+
+    va_end(args_obj.obj);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+// LCOV_EXCL_START
+
+const char *spinel_command_to_cstr(spinel_command_t command)
+{
+    const char *ret = "UNKNOWN";
+
+    switch (command)
+    {
+    case SPINEL_CMD_NOOP:
+        ret = "NOOP";
+        break;
+
+    case SPINEL_CMD_RESET:
+        ret = "RESET";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_GET:
+        ret = "PROP_VALUE_GET";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_SET:
+        ret = "PROP_VALUE_SET";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_INSERT:
+        ret = "PROP_VALUE_INSERT";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_REMOVE:
+        ret = "PROP_VALUE_REMOVE";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_IS:
+        ret = "PROP_VALUE_IS";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_INSERTED:
+        ret = "PROP_VALUE_INSERTED";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_REMOVED:
+        ret = "PROP_VALUE_REMOVED";
+        break;
+
+    case SPINEL_CMD_NET_SAVE:
+        ret = "NET_SAVE";
+        break;
+
+    case SPINEL_CMD_NET_CLEAR:
+        ret = "NET_CLEAR";
+        break;
+
+    case SPINEL_CMD_NET_RECALL:
+        ret = "NET_RECALL";
+        break;
+
+    case SPINEL_CMD_HBO_OFFLOAD:
+        ret = "HBO_OFFLOAD";
+        break;
+
+    case SPINEL_CMD_HBO_RECLAIM:
+        ret = "HBO_RECLAIM";
+        break;
+
+    case SPINEL_CMD_HBO_DROP:
+        ret = "HBO_DROP";
+        break;
+
+    case SPINEL_CMD_HBO_OFFLOADED:
+        ret = "HBO_OFFLOADED";
+        break;
+
+    case SPINEL_CMD_HBO_RECLAIMED:
+        ret = "HBO_RECLAIMED";
+        break;
+
+    case SPINEL_CMD_HBO_DROPPED:
+        ret = "HBO_DROPPED";
+        break;
+
+    case SPINEL_CMD_PEEK:
+        ret = "PEEK";
+        break;
+
+    case SPINEL_CMD_PEEK_RET:
+        ret = "PEEK_RET";
+        break;
+
+    case SPINEL_CMD_POKE:
+        ret = "POKE";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_MULTI_GET:
+        ret = "PROP_VALUE_MULTI_GET";
+        break;
+
+    case SPINEL_CMD_PROP_VALUE_MULTI_SET:
+        ret = "PROP_VALUE_MULTI_SET";
+        break;
+
+    case SPINEL_CMD_PROP_VALUES_ARE:
+        ret = "PROP_VALUES_ARE";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
+{
+    const char *ret = "UNKNOWN";
+
+    switch (prop_key)
+    {
+    case SPINEL_PROP_LAST_STATUS:
+        ret = "LAST_STATUS";
+        break;
+
+    case SPINEL_PROP_PROTOCOL_VERSION:
+        ret = "PROTOCOL_VERSION";
+        break;
+
+    case SPINEL_PROP_NCP_VERSION:
+        ret = "NCP_VERSION";
+        break;
+
+    case SPINEL_PROP_INTERFACE_TYPE:
+        ret = "INTERFACE_TYPE";
+        break;
+
+    case SPINEL_PROP_VENDOR_ID:
+        ret = "VENDOR_ID";
+        break;
+
+    case SPINEL_PROP_CAPS:
+        ret = "CAPS";
+        break;
+
+    case SPINEL_PROP_INTERFACE_COUNT:
+        ret = "INTERFACE_COUNT";
+        break;
+
+    case SPINEL_PROP_POWER_STATE:
+        ret = "POWER_STATE";
+        break;
+
+    case SPINEL_PROP_HWADDR:
+        ret = "HWADDR";
+        break;
+
+    case SPINEL_PROP_LOCK:
+        ret = "LOCK";
+        break;
+
+    case SPINEL_PROP_HBO_MEM_MAX:
+        ret = "HBO_MEM_MAX";
+        break;
+
+    case SPINEL_PROP_HBO_BLOCK_MAX:
+        ret = "HBO_BLOCK_MAX";
+        break;
+
+    case SPINEL_PROP_HOST_POWER_STATE:
+        ret = "HOST_POWER_STATE";
+        break;
+
+    case SPINEL_PROP_MCU_POWER_STATE:
+        ret = "MCU_POWER_STATE";
+        break;
+
+    case SPINEL_PROP_GPIO_CONFIG:
+        ret = "GPIO_CONFIG";
+        break;
+
+    case SPINEL_PROP_GPIO_STATE:
+        ret = "GPIO_STATE";
+        break;
+
+    case SPINEL_PROP_GPIO_STATE_SET:
+        ret = "GPIO_STATE_SET";
+        break;
+
+    case SPINEL_PROP_GPIO_STATE_CLEAR:
+        ret = "GPIO_STATE_CLEAR";
+        break;
+
+    case SPINEL_PROP_TRNG_32:
+        ret = "TRNG_32";
+        break;
+
+    case SPINEL_PROP_TRNG_128:
+        ret = "TRNG_128";
+        break;
+
+    case SPINEL_PROP_TRNG_RAW_32:
+        ret = "TRNG_RAW_32";
+        break;
+
+    case SPINEL_PROP_UNSOL_UPDATE_FILTER:
+        ret = "UNSOL_UPDATE_FILTER";
+        break;
+
+    case SPINEL_PROP_UNSOL_UPDATE_LIST:
+        ret = "UNSOL_UPDATE_LIST";
+        break;
+
+    case SPINEL_PROP_PHY_ENABLED:
+        ret = "PHY_ENABLED";
+        break;
+
+    case SPINEL_PROP_PHY_CHAN:
+        ret = "PHY_CHAN";
+        break;
+
+    case SPINEL_PROP_PHY_CHAN_SUPPORTED:
+        ret = "PHY_CHAN_SUPPORTED";
+        break;
+
+    case SPINEL_PROP_PHY_FREQ:
+        ret = "PHY_FREQ";
+        break;
+
+    case SPINEL_PROP_PHY_CCA_THRESHOLD:
+        ret = "PHY_CCA_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_PHY_TX_POWER:
+        ret = "PHY_TX_POWER";
+        break;
+
+    case SPINEL_PROP_PHY_RSSI:
+        ret = "PHY_RSSI";
+        break;
+
+    case SPINEL_PROP_PHY_RX_SENSITIVITY:
+        ret = "PHY_RX_SENSITIVITY";
+        break;
+
+    case SPINEL_PROP_PHY_PCAP_ENABLED:
+        ret = "PHY_PCAP_ENABLED";
+        break;
+
+    case SPINEL_PROP_PHY_CHAN_PREFERRED:
+        ret = "PHY_CHAN_PREFERRED";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_ENABLE:
+        ret = "JAM_DETECT_ENABLE";
+        break;
+
+    case SPINEL_PROP_JAM_DETECTED:
+        ret = "JAM_DETECTED";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD:
+        ret = "JAM_DETECT_RSSI_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_WINDOW:
+        ret = "JAM_DETECT_WINDOW";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_BUSY:
+        ret = "JAM_DETECT_BUSY";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP:
+        ret = "JAM_DETECT_HISTORY_BITMAP";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL:
+        ret = "CHANNEL_MONITOR_SAMPLE_INTERVAL";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD:
+        ret = "CHANNEL_MONITOR_RSSI_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW:
+        ret = "CHANNEL_MONITOR_SAMPLE_WINDOW";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT:
+        ret = "CHANNEL_MONITOR_SAMPLE_COUNT";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_OCCUPANCY:
+        ret = "CHANNEL_MONITOR_CHANNEL_OCCUPANCY";
+        break;
+
+    case SPINEL_PROP_RADIO_CAPS:
+        ret = "RADIO_CAPS";
+        break;
+
+    case SPINEL_PROP_RADIO_COEX_METRICS:
+        ret = "RADIO_COEX_METRICS";
+        break;
+
+    case SPINEL_PROP_RADIO_COEX_ENABLE:
+        ret = "RADIO_COEX_ENABLE";
+        break;
+
+    case SPINEL_PROP_MAC_SCAN_STATE:
+        ret = "MAC_SCAN_STATE";
+        break;
+
+    case SPINEL_PROP_MAC_SCAN_MASK:
+        ret = "MAC_SCAN_MASK";
+        break;
+
+    case SPINEL_PROP_MAC_SCAN_PERIOD:
+        ret = "MAC_SCAN_PERIOD";
+        break;
+
+    case SPINEL_PROP_MAC_SCAN_BEACON:
+        ret = "MAC_SCAN_BEACON";
+        break;
+
+    case SPINEL_PROP_MAC_15_4_LADDR:
+        ret = "MAC_15_4_LADDR";
+        break;
+
+    case SPINEL_PROP_MAC_15_4_SADDR:
+        ret = "MAC_15_4_SADDR";
+        break;
+
+    case SPINEL_PROP_MAC_15_4_PANID:
+        ret = "MAC_15_4_PANID";
+        break;
+
+    case SPINEL_PROP_MAC_RAW_STREAM_ENABLED:
+        ret = "MAC_RAW_STREAM_ENABLED";
+        break;
+
+    case SPINEL_PROP_MAC_PROMISCUOUS_MODE:
+        ret = "MAC_PROMISCUOUS_MODE";
+        break;
+
+    case SPINEL_PROP_MAC_ENERGY_SCAN_RESULT:
+        ret = "MAC_ENERGY_SCAN_RESULT";
+        break;
+
+    case SPINEL_PROP_MAC_DATA_POLL_PERIOD:
+        ret = "MAC_DATA_POLL_PERIOD";
+        break;
+
+    case SPINEL_PROP_MAC_WHITELIST:
+        ret = "MAC_WHITELIST";
+        break;
+
+    case SPINEL_PROP_MAC_WHITELIST_ENABLED:
+        ret = "MAC_WHITELIST_ENABLED";
+        break;
+
+    case SPINEL_PROP_MAC_EXTENDED_ADDR:
+        ret = "MAC_EXTENDED_ADDR";
+        break;
+
+    case SPINEL_PROP_MAC_SRC_MATCH_ENABLED:
+        ret = "MAC_SRC_MATCH_ENABLED";
+        break;
+
+    case SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES:
+        ret = "MAC_SRC_MATCH_SHORT_ADDRESSES";
+        break;
+
+    case SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES:
+        ret = "MAC_SRC_MATCH_EXTENDED_ADDRESSES";
+        break;
+
+    case SPINEL_PROP_MAC_BLACKLIST:
+        ret = "MAC_BLACKLIST";
+        break;
+
+    case SPINEL_PROP_MAC_BLACKLIST_ENABLED:
+        ret = "MAC_BLACKLIST_ENABLED";
+        break;
+
+    case SPINEL_PROP_MAC_FIXED_RSS:
+        ret = "MAC_FIXED_RSS";
+        break;
+
+    case SPINEL_PROP_MAC_CCA_FAILURE_RATE:
+        ret = "MAC_CCA_FAILURE_RATE";
+        break;
+
+    case SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT:
+        ret = "MAC_MAX_RETRY_NUMBER_DIRECT";
+        break;
+
+    case SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT:
+        ret = "MAC_MAX_RETRY_NUMBER_INDIRECT";
+        break;
+
+    case SPINEL_PROP_NET_SAVED:
+        ret = "NET_SAVED";
+        break;
+
+    case SPINEL_PROP_NET_IF_UP:
+        ret = "NET_IF_UP";
+        break;
+
+    case SPINEL_PROP_NET_STACK_UP:
+        ret = "NET_STACK_UP";
+        break;
+
+    case SPINEL_PROP_NET_ROLE:
+        ret = "NET_ROLE";
+        break;
+
+    case SPINEL_PROP_NET_NETWORK_NAME:
+        ret = "NET_NETWORK_NAME";
+        break;
+
+    case SPINEL_PROP_NET_XPANID:
+        ret = "NET_XPANID";
+        break;
+
+    case SPINEL_PROP_NET_MASTER_KEY:
+        ret = "NET_MASTER_KEY";
+        break;
+
+    case SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER:
+        ret = "NET_KEY_SEQUENCE_COUNTER";
+        break;
+
+    case SPINEL_PROP_NET_PARTITION_ID:
+        ret = "NET_PARTITION_ID";
+        break;
+
+    case SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING:
+        ret = "NET_REQUIRE_JOIN_EXISTING";
+        break;
+
+    case SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME:
+        ret = "NET_KEY_SWITCH_GUARDTIME";
+        break;
+
+    case SPINEL_PROP_NET_PSKC:
+        ret = "NET_PSKC";
+        break;
+
+    case SPINEL_PROP_THREAD_LEADER_ADDR:
+        ret = "THREAD_LEADER_ADDR";
+        break;
+
+    case SPINEL_PROP_THREAD_PARENT:
+        ret = "THREAD_PARENT";
+        break;
+
+    case SPINEL_PROP_THREAD_CHILD_TABLE:
+        ret = "THREAD_CHILD_TABLE";
+        break;
+
+    case SPINEL_PROP_THREAD_LEADER_RID:
+        ret = "THREAD_LEADER_RID";
+        break;
+
+    case SPINEL_PROP_THREAD_LEADER_WEIGHT:
+        ret = "THREAD_LEADER_WEIGHT";
+        break;
+
+    case SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT:
+        ret = "THREAD_LOCAL_LEADER_WEIGHT";
+        break;
+
+    case SPINEL_PROP_THREAD_NETWORK_DATA:
+        ret = "THREAD_NETWORK_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_NETWORK_DATA_VERSION:
+        ret = "THREAD_NETWORK_DATA_VERSION";
+        break;
+
+    case SPINEL_PROP_THREAD_STABLE_NETWORK_DATA:
+        ret = "THREAD_STABLE_NETWORK_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION:
+        ret = "THREAD_STABLE_NETWORK_DATA_VERSION";
+        break;
+
+    case SPINEL_PROP_THREAD_ON_MESH_NETS:
+        ret = "THREAD_ON_MESH_NETS";
+        break;
+
+    case SPINEL_PROP_THREAD_OFF_MESH_ROUTES:
+        ret = "THREAD_OFF_MESH_ROUTES";
+        break;
+
+    case SPINEL_PROP_THREAD_ASSISTING_PORTS:
+        ret = "THREAD_ASSISTING_PORTS";
+        break;
+
+    case SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE:
+        ret = "THREAD_ALLOW_LOCAL_NET_DATA_CHANGE";
+        break;
+
+    case SPINEL_PROP_THREAD_MODE:
+        ret = "THREAD_MODE";
+        break;
+
+    case SPINEL_PROP_THREAD_CHILD_TIMEOUT:
+        ret = "THREAD_CHILD_TIMEOUT";
+        break;
+
+    case SPINEL_PROP_THREAD_RLOC16:
+        ret = "THREAD_RLOC16";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD:
+        ret = "THREAD_ROUTER_UPGRADE_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY:
+        ret = "THREAD_CONTEXT_REUSE_DELAY";
+        break;
+
+    case SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT:
+        ret = "THREAD_NETWORK_ID_TIMEOUT";
+        break;
+
+    case SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS:
+        ret = "THREAD_ACTIVE_ROUTER_IDS";
+        break;
+
+    case SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU:
+        ret = "THREAD_RLOC16_DEBUG_PASSTHRU";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED:
+        ret = "THREAD_ROUTER_ROLE_ENABLED";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD:
+        ret = "THREAD_ROUTER_DOWNGRADE_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER:
+        ret = "THREAD_ROUTER_SELECTION_JITTER";
+        break;
+
+    case SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID:
+        ret = "THREAD_PREFERRED_ROUTER_ID";
+        break;
+
+    case SPINEL_PROP_THREAD_NEIGHBOR_TABLE:
+        ret = "THREAD_NEIGHBOR_TABLE";
+        break;
+
+    case SPINEL_PROP_THREAD_CHILD_COUNT_MAX:
+        ret = "THREAD_CHILD_COUNT_MAX";
+        break;
+
+    case SPINEL_PROP_THREAD_LEADER_NETWORK_DATA:
+        ret = "THREAD_LEADER_NETWORK_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA:
+        ret = "THREAD_STABLE_LEADER_NETWORK_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_JOINERS:
+        ret = "THREAD_JOINERS";
+        break;
+
+    case SPINEL_PROP_THREAD_COMMISSIONER_ENABLED:
+        ret = "THREAD_COMMISSIONER_ENABLED";
+        break;
+
+    case SPINEL_PROP_THREAD_TMF_PROXY_ENABLED:
+        ret = "THREAD_TMF_PROXY_ENABLED";
+        break;
+
+    case SPINEL_PROP_THREAD_TMF_PROXY_STREAM:
+        ret = "THREAD_TMF_PROXY_STREAM";
+        break;
+
+    case SPINEL_PROP_THREAD_UDP_FORWARD_STREAM:
+        ret = "THREAD_UDP_FORWARD_STREAM";
+        break;
+
+    case SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG:
+        ret = "THREAD_DISCOVERY_SCAN_JOINER_FLAG";
+        break;
+
+    case SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING:
+        ret = "THREAD_DISCOVERY_SCAN_ENABLE_FILTERING";
+        break;
+
+    case SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID:
+        ret = "THREAD_DISCOVERY_SCAN_PANID";
+        break;
+
+    case SPINEL_PROP_THREAD_STEERING_DATA:
+        ret = "THREAD_STEERING_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_TABLE:
+        ret = "THREAD_ROUTER_TABLE";
+        break;
+
+    case SPINEL_PROP_THREAD_ACTIVE_DATASET:
+        ret = "THREAD_ACTIVE_DATASET";
+        break;
+
+    case SPINEL_PROP_THREAD_PENDING_DATASET:
+        ret = "THREAD_PENDING_DATASET";
+        break;
+
+    case SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET:
+        ret = "THREAD_MGMT_SET_ACTIVE_DATASET";
+        break;
+
+    case SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET:
+        ret = "THREAD_MGMT_SET_PENDING_DATASET";
+        break;
+
+    case SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP:
+        ret = "DATASET_ACTIVE_TIMESTAMP";
+        break;
+
+    case SPINEL_PROP_DATASET_PENDING_TIMESTAMP:
+        ret = "DATASET_PENDING_TIMESTAMP";
+        break;
+
+    case SPINEL_PROP_DATASET_DELAY_TIMER:
+        ret = "DATASET_DELAY_TIMER";
+        break;
+
+    case SPINEL_PROP_DATASET_SECURITY_POLICY:
+        ret = "DATASET_SECURITY_POLICY";
+        break;
+
+    case SPINEL_PROP_DATASET_RAW_TLVS:
+        ret = "DATASET_RAW_TLVS";
+        break;
+
+    case SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES:
+        ret = "THREAD_CHILD_TABLE_ADDRESSES";
+        break;
+
+    case SPINEL_PROP_THREAD_NEIGHBOR_TABLE_ERROR_RATES:
+        ret = "THREAD_NEIGHBOR_TABLE_ERROR_RATES";
+        break;
+
+    case SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE:
+        ret = "THREAD_ADDRESS_CACHE_TABLE";
+        break;
+
+    case SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET:
+        ret = "THREAD_MGMT_GET_ACTIVE_DATASET";
+        break;
+
+    case SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET:
+        ret = "THREAD_MGMT_GET_PENDING_DATASET";
+        break;
+
+    case SPINEL_PROP_DATASET_DEST_ADDRESS:
+        ret = "DATASET_DEST_ADDRESS";
+        break;
+
+    case SPINEL_PROP_THREAD_NEW_DATASET:
+        ret = "THREAD_NEW_DATASET";
+        break;
+
+    case SPINEL_PROP_MESHCOP_JOINER_STATE:
+        ret = "MESHCOP_JOINER_STATE";
+        break;
+
+    case SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING:
+        ret = "MESHCOP_JOINER_COMMISSIONING";
+        break;
+
+    case SPINEL_PROP_IPV6_LL_ADDR:
+        ret = "IPV6_LL_ADDR";
+        break;
+
+    case SPINEL_PROP_IPV6_ML_ADDR:
+        ret = "IPV6_ML_ADDR";
+        break;
+
+    case SPINEL_PROP_IPV6_ML_PREFIX:
+        ret = "IPV6_ML_PREFIX";
+        break;
+
+    case SPINEL_PROP_IPV6_ADDRESS_TABLE:
+        ret = "IPV6_ADDRESS_TABLE";
+        break;
+
+    case SPINEL_PROP_IPV6_ROUTE_TABLE:
+        ret = "IPV6_ROUTE_TABLE";
+        break;
+
+    case SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD:
+        ret = "IPV6_ICMP_PING_OFFLOAD";
+        break;
+
+    case SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE:
+        ret = "IPV6_MULTICAST_ADDRESS_TABLE";
+        break;
+
+    case SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE:
+        ret = "IPV6_ICMP_PING_OFFLOAD_MODE";
+        break;
+
+    case SPINEL_PROP_STREAM_DEBUG:
+        ret = "STREAM_DEBUG";
+        break;
+
+    case SPINEL_PROP_STREAM_RAW:
+        ret = "STREAM_RAW";
+        break;
+
+    case SPINEL_PROP_STREAM_NET:
+        ret = "STREAM_NET";
+        break;
+
+    case SPINEL_PROP_STREAM_NET_INSECURE:
+        ret = "STREAM_NET_INSECURE";
+        break;
+
+    case SPINEL_PROP_STREAM_LOG:
+        ret = "STREAM_LOG";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_STATE:
+        ret = "MESHCOP_COMMISSIONER_STATE";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS:
+        ret = "MESHCOP_COMMISSIONER_JOINERS";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL:
+        ret = "MESHCOP_COMMISSIONER_PROVISIONING_URL";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID:
+        ret = "MESHCOP_COMMISSIONER_SESSION_ID";
+        break;
+
+    case SPINEL_PROP_MESHCOP_JOINER_DISCERNER:
+        ret = "MESHCOP_JOINER_DISCERNER";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN:
+        ret = "MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN:
+        ret = "MESHCOP_COMMISSIONER_ENERGY_SCAN";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT:
+        ret = "MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY:
+        ret = "MESHCOP_COMMISSIONER_PAN_ID_QUERY";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT:
+        ret = "MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_GET:
+        ret = "MESHCOP_COMMISSIONER_MGMT_GET";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_SET:
+        ret = "MESHCOP_COMMISSIONER_MGMT_SET";
+        break;
+
+    case SPINEL_PROP_MESHCOP_COMMISSIONER_GENERATE_PSKC:
+        ret = "MESHCOP_COMMISSIONER_GENERATE_PSKC";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL:
+        ret = "CHANNEL_MANAGER_NEW_CHANNEL";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MANAGER_DELAY:
+        ret = "CHANNEL_MANAGER_DELAY";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS:
+        ret = "CHANNEL_MANAGER_SUPPORTED_CHANNELS";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS:
+        ret = "CHANNEL_MANAGER_FAVORED_CHANNELS";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT:
+        ret = "CHANNEL_MANAGER_CHANNEL_SELECT";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED:
+        ret = "CHANNEL_MANAGER_AUTO_SELECT_ENABLED";
+        break;
+
+    case SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL:
+        ret = "CHANNEL_MANAGER_AUTO_SELECT_INTERVAL";
+        break;
+
+    case SPINEL_PROP_THREAD_NETWORK_TIME:
+        ret = "THREAD_NETWORK_TIME";
+        break;
+
+    case SPINEL_PROP_TIME_SYNC_PERIOD:
+        ret = "TIME_SYNC_PERIOD";
+        break;
+
+    case SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD:
+        ret = "TIME_SYNC_XTAL_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_CHILD_SUPERVISION_INTERVAL:
+        ret = "CHILD_SUPERVISION_INTERVAL";
+        break;
+
+    case SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT:
+        ret = "CHILD_SUPERVISION_CHECK_TIMEOUT";
+        break;
+
+    case SPINEL_PROP_RCP_VERSION:
+        ret = "RCP_VERSION";
+        break;
+
+    case SPINEL_PROP_PARENT_RESPONSE_INFO:
+        ret = "PARENT_RESPONSE_INFO";
+        break;
+
+    case SPINEL_PROP_SLAAC_ENABLED:
+        ret = "SLAAC_ENABLED";
+        break;
+
+    case SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE:
+        ret = "SERVER_ALLOW_LOCAL_DATA_CHANGE";
+        break;
+
+    case SPINEL_PROP_SERVER_SERVICES:
+        ret = "SERVER_SERVICES";
+        break;
+
+    case SPINEL_PROP_SERVER_LEADER_SERVICES:
+        ret = "SERVER_LEADER_SERVICES";
+        break;
+
+    case SPINEL_PROP_UART_BITRATE:
+        ret = "UART_BITRATE";
+        break;
+
+    case SPINEL_PROP_UART_XON_XOFF:
+        ret = "UART_XON_XOFF";
+        break;
+
+    case SPINEL_PROP_15_4_PIB_PHY_CHANNELS_SUPPORTED:
+        ret = "15_4_PIB_PHY_CHANNELS_SUPPORTED";
+        break;
+
+    case SPINEL_PROP_15_4_PIB_MAC_PROMISCUOUS_MODE:
+        ret = "15_4_PIB_MAC_PROMISCUOUS_MODE";
+        break;
+
+    case SPINEL_PROP_15_4_PIB_MAC_SECURITY_ENABLED:
+        ret = "15_4_PIB_MAC_SECURITY_ENABLED";
+        break;
+
+    case SPINEL_PROP_CNTR_RESET:
+        ret = "CNTR_RESET";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_TOTAL:
+        ret = "CNTR_TX_PKT_TOTAL";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_ACK_REQ:
+        ret = "CNTR_TX_PKT_ACK_REQ";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_ACKED:
+        ret = "CNTR_TX_PKT_ACKED";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_NO_ACK_REQ:
+        ret = "CNTR_TX_PKT_NO_ACK_REQ";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_DATA:
+        ret = "CNTR_TX_PKT_DATA";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_DATA_POLL:
+        ret = "CNTR_TX_PKT_DATA_POLL";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_BEACON:
+        ret = "CNTR_TX_PKT_BEACON";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_BEACON_REQ:
+        ret = "CNTR_TX_PKT_BEACON_REQ";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_OTHER:
+        ret = "CNTR_TX_PKT_OTHER";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_RETRY:
+        ret = "CNTR_TX_PKT_RETRY";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_ERR_CCA:
+        ret = "CNTR_TX_ERR_CCA";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_UNICAST:
+        ret = "CNTR_TX_PKT_UNICAST";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_PKT_BROADCAST:
+        ret = "CNTR_TX_PKT_BROADCAST";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_ERR_ABORT:
+        ret = "CNTR_TX_ERR_ABORT";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_TOTAL:
+        ret = "CNTR_RX_PKT_TOTAL";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_DATA:
+        ret = "CNTR_RX_PKT_DATA";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_DATA_POLL:
+        ret = "CNTR_RX_PKT_DATA_POLL";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_BEACON:
+        ret = "CNTR_RX_PKT_BEACON";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_BEACON_REQ:
+        ret = "CNTR_RX_PKT_BEACON_REQ";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_OTHER:
+        ret = "CNTR_RX_PKT_OTHER";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_FILT_WL:
+        ret = "CNTR_RX_PKT_FILT_WL";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_FILT_DA:
+        ret = "CNTR_RX_PKT_FILT_DA";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_ERR_EMPTY:
+        ret = "CNTR_RX_ERR_EMPTY";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_ERR_UKWN_NBR:
+        ret = "CNTR_RX_ERR_UKWN_NBR";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_ERR_NVLD_SADDR:
+        ret = "CNTR_RX_ERR_NVLD_SADDR";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_ERR_SECURITY:
+        ret = "CNTR_RX_ERR_SECURITY";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_ERR_BAD_FCS:
+        ret = "CNTR_RX_ERR_BAD_FCS";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_ERR_OTHER:
+        ret = "CNTR_RX_ERR_OTHER";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_DUP:
+        ret = "CNTR_RX_PKT_DUP";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_UNICAST:
+        ret = "CNTR_RX_PKT_UNICAST";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_PKT_BROADCAST:
+        ret = "CNTR_RX_PKT_BROADCAST";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL:
+        ret = "CNTR_TX_IP_SEC_TOTAL";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL:
+        ret = "CNTR_TX_IP_INSEC_TOTAL";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_IP_DROPPED:
+        ret = "CNTR_TX_IP_DROPPED";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_IP_SEC_TOTAL:
+        ret = "CNTR_RX_IP_SEC_TOTAL";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_IP_INSEC_TOTAL:
+        ret = "CNTR_RX_IP_INSEC_TOTAL";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_IP_DROPPED:
+        ret = "CNTR_RX_IP_DROPPED";
+        break;
+
+    case SPINEL_PROP_CNTR_TX_SPINEL_TOTAL:
+        ret = "CNTR_TX_SPINEL_TOTAL";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_SPINEL_TOTAL:
+        ret = "CNTR_RX_SPINEL_TOTAL";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_SPINEL_ERR:
+        ret = "CNTR_RX_SPINEL_ERR";
+        break;
+
+    case SPINEL_PROP_CNTR_RX_SPINEL_OUT_OF_ORDER_TID:
+        ret = "CNTR_RX_SPINEL_OUT_OF_ORDER_TID";
+        break;
+
+    case SPINEL_PROP_CNTR_IP_TX_SUCCESS:
+        ret = "CNTR_IP_TX_SUCCESS";
+        break;
+
+    case SPINEL_PROP_CNTR_IP_RX_SUCCESS:
+        ret = "CNTR_IP_RX_SUCCESS";
+        break;
+
+    case SPINEL_PROP_CNTR_IP_TX_FAILURE:
+        ret = "CNTR_IP_TX_FAILURE";
+        break;
+
+    case SPINEL_PROP_CNTR_IP_RX_FAILURE:
+        ret = "CNTR_IP_RX_FAILURE";
+        break;
+
+    case SPINEL_PROP_MSG_BUFFER_COUNTERS:
+        ret = "MSG_BUFFER_COUNTERS";
+        break;
+
+    case SPINEL_PROP_CNTR_ALL_MAC_COUNTERS:
+        ret = "CNTR_ALL_MAC_COUNTERS";
+        break;
+
+    case SPINEL_PROP_CNTR_MLE_COUNTERS:
+        ret = "CNTR_MLE_COUNTERS";
+        break;
+
+    case SPINEL_PROP_CNTR_ALL_IP_COUNTERS:
+        ret = "CNTR_ALL_IP_COUNTERS";
+        break;
+
+    case SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM:
+        ret = "CNTR_MAC_RETRY_HISTOGRAM";
+        break;
+
+    case SPINEL_PROP_NEST_STREAM_MFG:
+        ret = "NEST_STREAM_MFG";
+        break;
+
+    case SPINEL_PROP_NEST_LEGACY_ULA_PREFIX:
+        ret = "NEST_LEGACY_ULA_PREFIX";
+        break;
+
+    case SPINEL_PROP_NEST_LEGACY_LAST_NODE_JOINED:
+        ret = "NEST_LEGACY_LAST_NODE_JOINED";
+        break;
+
+    case SPINEL_PROP_DEBUG_TEST_ASSERT:
+        ret = "DEBUG_TEST_ASSERT";
+        break;
+
+    case SPINEL_PROP_DEBUG_NCP_LOG_LEVEL:
+        ret = "DEBUG_NCP_LOG_LEVEL";
+        break;
+
+    case SPINEL_PROP_DEBUG_TEST_WATCHDOG:
+        ret = "DEBUG_TEST_WATCHDOG";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+const char *spinel_net_role_to_cstr(uint8_t net_role)
+{
+    const char *ret = "NET_ROLE_UNKNOWN";
+
+    switch (net_role)
+    {
+    case SPINEL_NET_ROLE_DETACHED:
+        ret = "NET_ROLE_DETACHED";
+        break;
+
+    case SPINEL_NET_ROLE_CHILD:
+        ret = "NET_ROLE_CHILD";
+        break;
+
+    case SPINEL_NET_ROLE_ROUTER:
+        ret = "NET_ROLE_ROUTER";
+        break;
+
+    case SPINEL_NET_ROLE_LEADER:
+        ret = "NET_ROLE_LEADER";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+const char *spinel_mcu_power_state_to_cstr(uint8_t mcu_power_state)
+{
+    const char *ret = "MCU_POWER_STATE_UNKNOWN";
+
+    switch (mcu_power_state)
+    {
+    case SPINEL_MCU_POWER_STATE_ON:
+        ret = "MCU_POWER_STATE_ON";
+        break;
+
+    case SPINEL_MCU_POWER_STATE_LOW_POWER:
+        ret = "MCU_POWER_STATE_LOW_POWER";
+        break;
+
+    case SPINEL_MCU_POWER_STATE_OFF:
+        ret = "MCU_POWER_STATE_OFF";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+const char *spinel_status_to_cstr(spinel_status_t status)
+{
+    const char *ret = "UNKNOWN";
+
+    switch (status)
+    {
+    case SPINEL_STATUS_OK:
+        ret = "OK";
+        break;
+
+    case SPINEL_STATUS_FAILURE:
+        ret = "FAILURE";
+        break;
+
+    case SPINEL_STATUS_UNIMPLEMENTED:
+        ret = "UNIMPLEMENTED";
+        break;
+
+    case SPINEL_STATUS_INVALID_ARGUMENT:
+        ret = "INVALID_ARGUMENT";
+        break;
+
+    case SPINEL_STATUS_INVALID_STATE:
+        ret = "INVALID_STATE";
+        break;
+
+    case SPINEL_STATUS_INVALID_COMMAND:
+        ret = "INVALID_COMMAND";
+        break;
+
+    case SPINEL_STATUS_INVALID_INTERFACE:
+        ret = "INVALID_INTERFACE";
+        break;
+
+    case SPINEL_STATUS_INTERNAL_ERROR:
+        ret = "INTERNAL_ERROR";
+        break;
+
+    case SPINEL_STATUS_SECURITY_ERROR:
+        ret = "SECURITY_ERROR";
+        break;
+
+    case SPINEL_STATUS_PARSE_ERROR:
+        ret = "PARSE_ERROR";
+        break;
+
+    case SPINEL_STATUS_IN_PROGRESS:
+        ret = "IN_PROGRESS";
+        break;
+
+    case SPINEL_STATUS_NOMEM:
+        ret = "NOMEM";
+        break;
+
+    case SPINEL_STATUS_BUSY:
+        ret = "BUSY";
+        break;
+
+    case SPINEL_STATUS_PROP_NOT_FOUND:
+        ret = "PROP_NOT_FOUND";
+        break;
+
+    case SPINEL_STATUS_DROPPED:
+        ret = "DROPPED";
+        break;
+
+    case SPINEL_STATUS_EMPTY:
+        ret = "EMPTY";
+        break;
+
+    case SPINEL_STATUS_CMD_TOO_BIG:
+        ret = "CMD_TOO_BIG";
+        break;
+
+    case SPINEL_STATUS_NO_ACK:
+        ret = "NO_ACK";
+        break;
+
+    case SPINEL_STATUS_CCA_FAILURE:
+        ret = "CCA_FAILURE";
+        break;
+
+    case SPINEL_STATUS_ALREADY:
+        ret = "ALREADY";
+        break;
+
+    case SPINEL_STATUS_ITEM_NOT_FOUND:
+        ret = "ITEM_NOT_FOUND";
+        break;
+
+    case SPINEL_STATUS_INVALID_COMMAND_FOR_PROP:
+        ret = "INVALID_COMMAND_FOR_PROP";
+        break;
+
+    case SPINEL_STATUS_JOIN_FAILURE:
+        ret = "JOIN_FAILURE";
+        break;
+
+    case SPINEL_STATUS_JOIN_SECURITY:
+        ret = "JOIN_SECURITY";
+        break;
+
+    case SPINEL_STATUS_JOIN_NO_PEERS:
+        ret = "JOIN_NO_PEERS";
+        break;
+
+    case SPINEL_STATUS_JOIN_INCOMPATIBLE:
+        ret = "JOIN_INCOMPATIBLE";
+        break;
+
+    case SPINEL_STATUS_JOIN_RSP_TIMEOUT:
+        ret = "JOIN_RSP_TIMEOUT";
+        break;
+
+    case SPINEL_STATUS_JOIN_SUCCESS:
+        ret = "JOIN_SUCCESS";
+        break;
+
+    case SPINEL_STATUS_RESET_POWER_ON:
+        ret = "RESET_POWER_ON";
+        break;
+
+    case SPINEL_STATUS_RESET_EXTERNAL:
+        ret = "RESET_EXTERNAL";
+        break;
+
+    case SPINEL_STATUS_RESET_SOFTWARE:
+        ret = "RESET_SOFTWARE";
+        break;
+
+    case SPINEL_STATUS_RESET_FAULT:
+        ret = "RESET_FAULT";
+        break;
+
+    case SPINEL_STATUS_RESET_CRASH:
+        ret = "RESET_CRASH";
+        break;
+
+    case SPINEL_STATUS_RESET_ASSERT:
+        ret = "RESET_ASSERT";
+        break;
+
+    case SPINEL_STATUS_RESET_OTHER:
+        ret = "RESET_OTHER";
+        break;
+
+    case SPINEL_STATUS_RESET_UNKNOWN:
+        ret = "RESET_UNKNOWN";
+        break;
+
+    case SPINEL_STATUS_RESET_WATCHDOG:
+        ret = "RESET_WATCHDOG";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+const char *spinel_capability_to_cstr(spinel_capability_t capability)
+{
+    const char *ret = "UNKNOWN";
+
+    switch (capability)
+    {
+    case SPINEL_CAP_LOCK:
+        ret = "LOCK";
+        break;
+
+    case SPINEL_CAP_NET_SAVE:
+        ret = "NET_SAVE";
+        break;
+
+    case SPINEL_CAP_HBO:
+        ret = "HBO";
+        break;
+
+    case SPINEL_CAP_POWER_SAVE:
+        ret = "POWER_SAVE";
+        break;
+
+    case SPINEL_CAP_COUNTERS:
+        ret = "COUNTERS";
+        break;
+
+    case SPINEL_CAP_JAM_DETECT:
+        ret = "JAM_DETECT";
+        break;
+
+    case SPINEL_CAP_PEEK_POKE:
+        ret = "PEEK_POKE";
+        break;
+
+    case SPINEL_CAP_WRITABLE_RAW_STREAM:
+        ret = "WRITABLE_RAW_STREAM";
+        break;
+
+    case SPINEL_CAP_GPIO:
+        ret = "GPIO";
+        break;
+
+    case SPINEL_CAP_TRNG:
+        ret = "TRNG";
+        break;
+
+    case SPINEL_CAP_CMD_MULTI:
+        ret = "CMD_MULTI";
+        break;
+
+    case SPINEL_CAP_UNSOL_UPDATE_FILTER:
+        ret = "UNSOL_UPDATE_FILTER";
+        break;
+
+    case SPINEL_CAP_MCU_POWER_STATE:
+        ret = "MCU_POWER_STATE";
+        break;
+
+    case SPINEL_CAP_PCAP:
+        ret = "PCAP";
+        break;
+
+    case SPINEL_CAP_802_15_4_2003:
+        ret = "802_15_4_2003";
+        break;
+
+    case SPINEL_CAP_802_15_4_2006:
+        ret = "802_15_4_2006";
+        break;
+
+    case SPINEL_CAP_802_15_4_2011:
+        ret = "802_15_4_2011";
+        break;
+
+    case SPINEL_CAP_802_15_4_PIB:
+        ret = "802_15_4_PIB";
+        break;
+
+    case SPINEL_CAP_802_15_4_2450MHZ_OQPSK:
+        ret = "802_15_4_2450MHZ_OQPSK";
+        break;
+
+    case SPINEL_CAP_802_15_4_915MHZ_OQPSK:
+        ret = "802_15_4_915MHZ_OQPSK";
+        break;
+
+    case SPINEL_CAP_802_15_4_868MHZ_OQPSK:
+        ret = "802_15_4_868MHZ_OQPSK";
+        break;
+
+    case SPINEL_CAP_802_15_4_915MHZ_BPSK:
+        ret = "802_15_4_915MHZ_BPSK";
+        break;
+
+    case SPINEL_CAP_802_15_4_868MHZ_BPSK:
+        ret = "802_15_4_868MHZ_BPSK";
+        break;
+
+    case SPINEL_CAP_802_15_4_915MHZ_ASK:
+        ret = "802_15_4_915MHZ_ASK";
+        break;
+
+    case SPINEL_CAP_802_15_4_868MHZ_ASK:
+        ret = "802_15_4_868MHZ_ASK";
+        break;
+
+    case SPINEL_CAP_CONFIG_FTD:
+        ret = "CONFIG_FTD";
+        break;
+
+    case SPINEL_CAP_CONFIG_MTD:
+        ret = "CONFIG_MTD";
+        break;
+
+    case SPINEL_CAP_CONFIG_RADIO:
+        ret = "CONFIG_RADIO";
+        break;
+
+    case SPINEL_CAP_ROLE_ROUTER:
+        ret = "ROLE_ROUTER";
+        break;
+
+    case SPINEL_CAP_ROLE_SLEEPY:
+        ret = "ROLE_SLEEPY";
+        break;
+
+    case SPINEL_CAP_NET_THREAD_1_0:
+        ret = "NET_THREAD_1_0";
+        break;
+
+    case SPINEL_CAP_NET_THREAD_1_1:
+        ret = "NET_THREAD_1_1";
+        break;
+
+    case SPINEL_CAP_MAC_WHITELIST:
+        ret = "MAC_WHITELIST";
+        break;
+
+    case SPINEL_CAP_MAC_RAW:
+        ret = "MAC_RAW";
+        break;
+
+    case SPINEL_CAP_OOB_STEERING_DATA:
+        ret = "OOB_STEERING_DATA";
+        break;
+
+    case SPINEL_CAP_CHANNEL_MONITOR:
+        ret = "CHANNEL_MONITOR";
+        break;
+
+    case SPINEL_CAP_CHANNEL_MANAGER:
+        ret = "CHANNEL_MANAGER";
+        break;
+
+    case SPINEL_CAP_OPENTHREAD_LOG_METADATA:
+        ret = "OPENTHREAD_LOG_METADATA";
+        break;
+
+    case SPINEL_CAP_TIME_SYNC:
+        ret = "TIME_SYNC";
+        break;
+
+    case SPINEL_CAP_CHILD_SUPERVISION:
+        ret = "CHILD_SUPERVISION";
+        break;
+
+    case SPINEL_CAP_POSIX:
+        ret = "POSIX";
+        break;
+
+    case SPINEL_CAP_SLAAC:
+        ret = "SLAAC";
+        break;
+
+    case SPINEL_CAP_RADIO_COEX:
+        ret = "RADIO_COEX";
+        break;
+
+    case SPINEL_CAP_MAC_RETRY_HISTOGRAM:
+        ret = "MAC_RETRY_HISTOGRAM";
+        break;
+
+    case SPINEL_CAP_ERROR_RATE_TRACKING:
+        ret = "ERROR_RATE_TRACKING";
+        break;
+
+    case SPINEL_CAP_THREAD_COMMISSIONER:
+        ret = "THREAD_COMMISSIONER";
+        break;
+
+    case SPINEL_CAP_THREAD_TMF_PROXY:
+        ret = "THREAD_TMF_PROXY";
+        break;
+
+    case SPINEL_CAP_THREAD_UDP_FORWARD:
+        ret = "THREAD_UDP_FORWARD";
+        break;
+
+    case SPINEL_CAP_THREAD_JOINER:
+        ret = "THREAD_JOINER";
+        break;
+
+    case SPINEL_CAP_THREAD_BORDER_ROUTER:
+        ret = "THREAD_BORDER_ROUTER";
+        break;
+
+    case SPINEL_CAP_THREAD_SERVICE:
+        ret = "THREAD_SERVICE";
+        break;
+
+    case SPINEL_CAP_NEST_LEGACY_INTERFACE:
+        ret = "NEST_LEGACY_INTERFACE";
+        break;
+
+    case SPINEL_CAP_NEST_LEGACY_NET_WAKE:
+        ret = "NEST_LEGACY_NET_WAKE";
+        break;
+
+    case SPINEL_CAP_NEST_TRANSMIT_HOOK:
+        ret = "NEST_TRANSMIT_HOOK";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+// LCOV_EXCL_STOP
+
+/* -------------------------------------------------------------------------- */
+
+#if SPINEL_SELF_TEST
+
+int main(void)
+{
+    int                  ret             = -1;
+    const spinel_eui64_t static_eui64    = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}};
+    const char           static_string[] = "static_string";
+    uint8_t              buffer[1024];
+    ssize_t              len;
+
+    len =
+        spinel_datatype_pack(buffer, sizeof(buffer), "CiiLUE", 0x88, 9, 0xA3, 0xDEADBEEF, static_string, &static_eui64);
+
+    if (len != 30)
+    {
+        printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
+        goto bail;
+    }
+
+    {
+        const char *str = NULL;
+
+        // Length ends right before the string.
+        len = spinel_datatype_unpack(buffer, 8, "CiiLU", NULL, NULL, NULL, NULL, &str);
+
+        if (len != -1)
+        {
+            printf("error:%d: len != -1; (%d)\n", __LINE__, (int)len);
+            goto bail;
+        }
+
+        if (str != NULL)
+        {
+            printf("error:%d: str != NULL\n", __LINE__);
+            goto bail;
+        }
+    }
+
+    len = 30;
+
+    {
+        uint8_t               c     = 0;
+        unsigned int          i1    = 0;
+        unsigned int          i2    = 0;
+        uint32_t              l     = 0;
+        const char *          str   = NULL;
+        const spinel_eui64_t *eui64 = NULL;
+
+        len = spinel_datatype_unpack(buffer, (spinel_size_t)len, "CiiLUE", &c, &i1, &i2, &l, &str, &eui64);
+
+        if (len != 30)
+        {
+            printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
+            goto bail;
+        }
+
+        if (c != 0x88)
+        {
+            printf("error: x != 0x88; (%d)\n", c);
+            goto bail;
+        }
+
+        if (i1 != 9)
+        {
+            printf("error: i1 != 9; (%d)\n", i1);
+            goto bail;
+        }
+
+        if (i2 != 0xA3)
+        {
+            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
+            goto bail;
+        }
+
+        if (l != 0xDEADBEEF)
+        {
+            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
+            goto bail;
+        }
+
+        if (strcmp(str, static_string) != 0)
+        {
+            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
+            goto bail;
+        }
+
+        if (memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
+        {
+            printf("error:%d: memcmp(eui64, &eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
+            goto bail;
+        }
+    }
+
+    {
+        uint8_t        c  = 0;
+        unsigned int   i1 = 0;
+        unsigned int   i2 = 0;
+        uint32_t       l  = 0;
+        char           str[sizeof(static_string)];
+        spinel_eui64_t eui64 = {{0}};
+
+        len = spinel_datatype_unpack_in_place(buffer, (spinel_size_t)len, "CiiLUE", &c, &i1, &i2, &l, &str, sizeof(str),
+                                              &eui64);
+
+        if (len != 30)
+        {
+            printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
+            goto bail;
+        }
+
+        if (c != 0x88)
+        {
+            printf("error: x != 0x88; (%d)\n", c);
+            goto bail;
+        }
+
+        if (i1 != 9)
+        {
+            printf("error: i1 != 9; (%d)\n", i1);
+            goto bail;
+        }
+
+        if (i2 != 0xA3)
+        {
+            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
+            goto bail;
+        }
+
+        if (l != 0xDEADBEEF)
+        {
+            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
+            goto bail;
+        }
+
+        if (strcmp(str, static_string) != 0)
+        {
+            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
+            goto bail;
+        }
+
+        if (memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
+        {
+            printf("error:%d: memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
+            goto bail;
+        }
+    }
+
+    // -----------------------------------
+
+    memset(buffer, 0xAA, sizeof(buffer));
+
+    len = spinel_datatype_pack(buffer, sizeof(buffer), "Cit(iL)UE", 0x88, 9, 0xA3, 0xDEADBEEF, static_string,
+                               &static_eui64);
+
+    if (len != 32)
+    {
+        printf("error:%d: len != 32; (%d)\n", __LINE__, (int)len);
+        goto bail;
+    }
+
+    {
+        uint8_t         c     = 0;
+        unsigned int    i1    = 0;
+        unsigned int    i2    = 0;
+        uint32_t        l     = 0;
+        const char *    str   = NULL;
+        spinel_eui64_t *eui64 = NULL;
+
+        len = spinel_datatype_unpack(buffer, (spinel_size_t)len, "Cit(iL)UE", &c, &i1, &i2, &l, &str, &eui64);
+
+        if (len != 32)
+        {
+            printf("error:%d: len != 24; (%d)\n", __LINE__, (int)len);
+            goto bail;
+        }
+
+        if (c != 0x88)
+        {
+            printf("error: x != 0x88; (%d)\n", c);
+            goto bail;
+        }
+
+        if (i1 != 9)
+        {
+            printf("error: i1 != 9; (%d)\n", i1);
+            goto bail;
+        }
+
+        if (i2 != 0xA3)
+        {
+            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
+            goto bail;
+        }
+
+        if (l != 0xDEADBEEF)
+        {
+            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
+            goto bail;
+        }
+
+        if (strcmp(str, static_string) != 0)
+        {
+            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
+            goto bail;
+        }
+
+        if (memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
+        {
+            printf("error:%d: memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
+            goto bail;
+        }
+    }
+
+    {
+        uint8_t        c  = 0;
+        unsigned int   i1 = 0;
+        unsigned int   i2 = 0;
+        uint32_t       l  = 0;
+        char           str[sizeof(static_string)];
+        spinel_eui64_t eui64 = {{0}};
+
+        len = spinel_datatype_unpack_in_place(buffer, (spinel_size_t)len, "Cit(iL)UE", &c, &i1, &i2, &l, &str,
+                                              sizeof(str), &eui64);
+
+        if (len != 32)
+        {
+            printf("error:%d: len != 24; (%d)\n", __LINE__, (int)len);
+            goto bail;
+        }
+
+        if (c != 0x88)
+        {
+            printf("error: x != 0x88; (%d)\n", c);
+            goto bail;
+        }
+
+        if (i1 != 9)
+        {
+            printf("error: i1 != 9; (%d)\n", i1);
+            goto bail;
+        }
+
+        if (i2 != 0xA3)
+        {
+            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
+            goto bail;
+        }
+
+        if (l != 0xDEADBEEF)
+        {
+            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
+            goto bail;
+        }
+
+        if (strcmp(str, static_string) != 0)
+        {
+            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
+            goto bail;
+        }
+
+        if (memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
+        {
+            printf("error:%d: memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
+            goto bail;
+        }
+    }
+
+    {
+        // Test UTF8 validation - Good/Valid strings
+
+        // Single symbols
+        const uint8_t single1[] = {0};                            // 0000
+        const uint8_t single2[] = {0x7F, 0x00};                   // 007F
+        const uint8_t single3[] = {0xC2, 0x80, 0x00};             // 080
+        const uint8_t single4[] = {0xDF, 0xBF, 0x00};             // 07FF
+        const uint8_t single5[] = {0xE0, 0xA0, 0x80, 0x00};       // 0800
+        const uint8_t single6[] = {0xEF, 0xBF, 0xBF, 0x00};       // FFFF
+        const uint8_t single7[] = {0xF0, 0x90, 0x80, 0x80, 0x00}; // 010000
+        const uint8_t single8[] = {0xF4, 0x8F, 0xBF, 0xBF, 0x00}; // 10FFFF
+
+        // Strings
+        const uint8_t str1[] = "spinel";
+        const uint8_t str2[] = "OpenThread";
+        const uint8_t str3[] = {0x41, 0x7F, 0xEF, 0xBF, 0xBF, 0xC2, 0x80, 0x21, 0x33, 0x00};
+        const uint8_t str4[] = {0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xB5, 0x00}; // κόσμε
+        const uint8_t str5[] = {0x3D, 0xF4, 0x8F, 0xBF, 0xBF, 0x01, 0xE0, 0xA0, 0x83, 0x22, 0xEF, 0xBF, 0xBF, 0x00};
+        const uint8_t str6[] = {0xE5, 0xA2, 0x82, 0xE0, 0xA0, 0x80, 0xC2, 0x83, 0xC2, 0x80, 0xF4,
+                                0x8F, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 0xBF, 0xDF, 0xBF, 0x21, 0x00};
+
+        const uint8_t * good_strings[] = {single1, single2, single3, single4, single5, single6, single7, single8,
+                                         str1,    str2,    str3,    str4,    str5,    str6,    NULL};
+        const uint8_t **str_ptr;
+
+        for (str_ptr = &good_strings[0]; *str_ptr != NULL; str_ptr++)
+        {
+            if (!spinel_validate_utf8(*str_ptr))
+            {
+                printf("error: spinel_validate_utf8() did not correctly detect a valid UTF8 sequence!\n");
+                goto bail;
+            }
+        }
+    }
+
+    {
+        // Test UTF8 validation - Bad/Invalid strings
+
+        // Single symbols (invalid)
+        const uint8_t single1[] = {0xF8, 0x00};
+        const uint8_t single2[] = {0xF9, 0x00};
+        const uint8_t single3[] = {0xFA, 0x00};
+        const uint8_t single4[] = {0xFF, 0x00};
+
+        // Bad continuations
+        const uint8_t bad1[] = {0xDF, 0x0F, 0x00};
+        const uint8_t bad2[] = {0xE0, 0xA0, 0x10, 0x00};
+        const uint8_t bad3[] = {0xF0, 0x90, 0x80, 0x60, 0x00};
+        const uint8_t bad4[] = {0xF4, 0x8F, 0xBF, 0x0F, 0x00};
+        const uint8_t bad5[] = {0x21, 0xA0, 0x00};
+        const uint8_t bad6[] = {0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0x00};
+
+        const uint8_t * bad_strings[] = {single1, single2, single3, single4, bad1, bad2, bad3, bad4, bad5, bad6, NULL};
+        const uint8_t **str_ptr;
+
+        for (str_ptr = &bad_strings[0]; *str_ptr != NULL; str_ptr++)
+        {
+            if (spinel_validate_utf8(*str_ptr))
+            {
+                printf("error: spinel_validate_utf8() did not correctly detect an invalid UTF8 sequence\n");
+                goto bail;
+            }
+        }
+    }
+
+    printf("OK\n");
+    ret = 0;
+    return ret;
+
+bail:
+    printf("FAILURE\n");
+    return ret;
+}
+
+#endif // #if SPINEL_SELF_TEST
diff --git a/src/lib/spinel/spinel.h b/src/lib/spinel/spinel.h
new file mode 100644
index 0000000..915751f
--- /dev/null
+++ b/src/lib/spinel/spinel.h
@@ -0,0 +1,4260 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file contains definitions of spinel.
+ */
+
+#ifndef SPINEL_HEADER_INCLUDED
+#define SPINEL_HEADER_INCLUDED 1
+
+/*
+ *   Spinel is a host-controller protocol designed to enable
+ *   inter-operation over simple serial connections between general purpose
+ *   device operating systems (OS) host and network co-processors (NCP) for
+ *   the purpose of controlling and managing the NCP.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ *   Frame Format
+ *
+ *   A frame is defined simply as the concatenation of
+ *
+ *   -  A header byte
+ *   -  A command (up to three bytes)
+ *   -  An optional command payload
+ *
+ *              +---------+--------+-----+-------------+
+ *              | Octets: |   1    | 1-3 |      n      |
+ *              +---------+--------+-----+-------------+
+ *              | Fields: | HEADER | CMD | CMD_PAYLOAD |
+ *              +---------+--------+-----+-------------+
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ *   Header Format
+ *
+ *   The header byte is broken down as follows:
+ *
+ *                    0   1   2   3   4   5   6   7
+ *                  +---+---+---+---+---+---+---+---+
+ *                  |  FLG  |  IID  |      TID      |
+ *                  +---+---+---+---+---+---+---+---+
+ *
+ *
+ *   The flag field of the header byte ("FLG") is always set to the value
+ *   two (or "10" in binary).  Any frame received with these bits set to
+ *   any other value else MUST NOT be considered a Spinel frame.
+ *
+ *   This convention allows Spinel to be line compatible with BTLE HCI.
+ *   By defining the first two bit in this way we can disambiguate between
+ *   Spinel frames and HCI frames (which always start with either "0x01"
+ *   or "0x04") without any additional framing overhead.
+ *
+ *   The Interface Identifier (IID) is a number between 0 and 3, which
+ *   is associated by the OS with a specific NCP. This allows the protocol
+ *   to support up to 4 NCPs under same connection.
+ *
+ *   The least significant bits of the header represent the Transaction
+ *   Identifier (TID). The TID is used for correlating responses to the
+ *   commands which generated them.
+ *
+ *   When a command is sent from the host, any reply to that command sent
+ *   by the NCP will use the same value for the TID.  When the host
+ *   receives a frame that matches the TID of the command it sent, it can
+ *   easily recognize that frame as the actual response to that command.
+ *
+ *   The TID value of zero (0) is used for commands to which a correlated
+ *   response is not expected or needed, such as for unsolicited update
+ *   commands sent to the host from the NCP.
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ *   The command identifier is a 21-bit unsigned integer encoded in up to
+ *   three bytes using the packed unsigned integer format described below.
+ *   Depending on the semantics of the command in question, a payload MAY
+ *   be included in the frame.  The exact composition and length of the
+ *   payload is defined by the command identifier.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ *   Data Packing
+ *
+ *   Data serialization for properties is performed using a light-weight
+ *   data packing format which was loosely inspired by D-Bus.  The format
+ *   of a serialization is defined by a specially formatted string.
+ *
+ *   This packing format is used for notational convenience.  While this
+ *   string-based data-type format has been designed so that the strings
+ *   may be directly used by a structured data parser, such a thing is not
+ *   required to implement Spinel.
+ *
+ *   Goals:
+ *
+ *   -  Be lightweight and favor direct representation of values.
+ *   -  Use an easily readable and memorable format string.
+ *   -  Support lists and structures.
+ *   -  Allow properties to be appended to structures while maintaining
+ *      backward compatibility.
+ *
+ *   Each primitive data-type has an ASCII character associated with it.
+ *   Structures can be represented as strings of these characters.  For
+ *   example:
+ *
+ *   -  "C": A single unsigned byte.
+ *   -  "C6U": A single unsigned byte, followed by a 128-bit IPv6 address,
+ *      followed by a zero-terminated UTF8 string.
+ *   -  "A(6)": An array of concatenated IPv6 addresses
+ *
+ *   In each case, the data is represented exactly as described.  For
+ *   example, an array of 10 IPv6 address is stored as 160 bytes.
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ *   Primitive Types
+ *
+ *   +----------+----------------------+---------------------------------+
+ *   |   Char   | Name                 | Description                     |
+ *   +----------+----------------------+---------------------------------+
+ *   |   "."    | DATATYPE_VOID        | Empty data type. Used           |
+ *   |          |                      | internally.                     |
+ *   |   "b"    | DATATYPE_BOOL        | Boolean value. Encoded in       |
+ *   |          |                      | 8-bits as either 0x00 or 0x01.  |
+ *   |          |                      | All other values are illegal.   |
+ *   |   "C"    | DATATYPE_UINT8       | Unsigned 8-bit integer.         |
+ *   |   "c"    | DATATYPE_INT8        | Signed 8-bit integer.           |
+ *   |   "S"    | DATATYPE_UINT16      | Unsigned 16-bit integer.        |
+ *   |   "s"    | DATATYPE_INT16       | Signed 16-bit integer.          |
+ *   |   "L"    | DATATYPE_UINT32      | Unsigned 32-bit integer.        |
+ *   |   "l"    | DATATYPE_INT32       | Signed 32-bit integer.          |
+ *   |   "i"    | DATATYPE_UINT_PACKED | Packed Unsigned Integer. See    |
+ *   |          |                      | description below               |
+ *   |   "6"    | DATATYPE_IPv6ADDR    | IPv6 Address. (Big-endian)      |
+ *   |   "E"    | DATATYPE_EUI64       | EUI-64 Address. (Big-endian)    |
+ *   |   "e"    | DATATYPE_EUI48       | EUI-48 Address. (Big-endian)    |
+ *   |   "D"    | DATATYPE_DATA        | Arbitrary data. See related     |
+ *   |          |                      | section below for details.      |
+ *   |   "d"    | DATATYPE_DATA_WLEN   | Arbitrary data with prepended   |
+ *   |          |                      | length. See below for details   |
+ *   |   "U"    | DATATYPE_UTF8        | Zero-terminated UTF8-encoded    |
+ *   |          |                      | string.                         |
+ *   | "t(...)" | DATATYPE_STRUCT      | Structured datatype with        |
+ *   |          |                      | prepended length.               |
+ *   | "A(...)" | DATATYPE_ARRAY       | Array of datatypes. Compound    |
+ *   |          |                      | type.                           |
+ *   +----------+----------------------+---------------------------------+
+ *
+ *   All multi-byte values are little-endian unless explicitly stated
+ *   otherwise.
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ *   Packed Unsigned Integer
+ *
+ *   For certain types of integers, such command or property identifiers,
+ *   usually have a value on the wire that is less than 127.  However, in
+ *   order to not preclude the use of values larger than 255, we would
+ *   need to add an extra byte.  Doing this would add an extra byte to the
+ *   majority of instances, which can add up in terms of bandwidth.
+ *
+ *   The packed unsigned integer format is based on the unsigned integer
+ *   format in EXI, except that we limit the maximum value to the
+ *   largest value that can be encoded into three bytes (2,097,151).
+ *
+ *   For all values less than 127, the packed form of the number is simply
+ *   a single byte which directly represents the number.  For values
+ *   larger than 127, the following process is used to encode the value:
+ *
+ *   1.  The unsigned integer is broken up into _n_ 7-bit chunks and
+ *       placed into _n_ octets, leaving the most significant bit of each
+ *       octet unused.
+ *   2.  Order the octets from least-significant to most-significant.
+ *       (Little-endian)
+ *   3.  Clear the most significant bit of the most significant octet.
+ *       Set the least significant bit on all other octets.
+ *
+ *   Where `n` is the smallest number of 7-bit chunks you can use to
+ *   represent the given value.
+ *
+ *   Take the value 1337, for example:
+ *
+ *                              1337 => 0x0539
+ *                                   => [39 0A]
+ *                                   => [B9 0A]
+ *
+ *   To decode the value, you collect the 7-bit chunks until you find an
+ *   octet with the most significant bit clear.
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ *   Data Blobs
+ *
+ *   There are two types for data blobs: "d" and "D".
+ *
+ *   -  "d" has the length of the data (in bytes) prepended to the data
+ *      (with the length encoded as type "S").  The size of the length
+ *      field is not included in the length.
+ *   -  "D" does not have a prepended length: the length of the data is
+ *      implied by the bytes remaining to be parsed.  It is an error for
+ *      "D" to not be the last type in a type in a type signature.
+ *
+ *   This dichotomy allows for more efficient encoding by eliminating
+ *   redundancy.  If the rest of the buffer is a data blob, encoding the
+ *   length would be redundant because we already know how many bytes are
+ *   in the rest of the buffer.
+ *
+ *   In some cases we use "d" even if it is the last field in a type
+ *   signature.  We do this to allow for us to be able to append
+ *   additional fields to the type signature if necessary in the future.
+ *   This is usually the case with embedded structs, like in the scan
+ *   results.
+ *
+ *   For example, let's say we have a buffer that is encoded with the
+ *   datatype signature of "CLLD".  In this case, it is pretty easy to
+ *   tell where the start and end of the data blob is: the start is 9
+ *   bytes from the start of the buffer, and its length is the length of
+ *   the buffer minus 9. (9 is the number of bytes taken up by a byte and
+ *   two longs)
+ *
+ *   The datatype signature "CLLDU" is illegal because we can't determine
+ *   where the last field (a zero-terminated UTF8 string) starts.  But the
+ *   datatype "CLLdU" is legal, because the parser can determine the
+ *   exact length of the data blob-- allowing it to know where the start
+ *   of the next field would be.
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ *   Structured Data
+ *
+ *   The structure data type ("t(...)") is a way of bundling together
+ *   several fields into a single structure.  It can be thought of as a
+ *   "d" type except that instead of being opaque, the fields in the
+ *   content are known.  This is useful for things like scan results where
+ *   you have substructures which are defined by different layers.
+ *
+ *   For example, consider the type signature "Lt(ES)t(6C)".  In this
+ *   hypothetical case, the first struct is defined by the MAC layer, and
+ *   the second struct is defined by the PHY layer.  Because of the use of
+ *   structures, we know exactly what part comes from that layer.
+ *   Additionally, we can add fields to each structure without introducing
+ *   backward compatability problems: Data encoded as "Lt(ESU)t(6C)"
+ *   (Notice the extra "U") will decode just fine as "Lt(ES)t(6C)".
+ *   Additionally, if we don't care about the MAC layer and only care
+ *   about the network layer, we could parse as "Lt()t(6C)".
+ *
+ *   Note that data encoded as "Lt(ES)t(6C)" will also parse as "Ldd",
+ *   with the structures from both layers now being opaque data blobs.
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ *   Arrays
+ *
+ *   An array is simply a concatenated set of _n_ data encodings.  For
+ *   example, the type "A(6)" is simply a list of IPv6 addresses---one
+ *   after the other.  The type "A(6E)" likewise a concatenation of IPv6-
+ *   address/EUI-64 pairs.
+ *
+ *   If an array contains many fields, the fields will often be surrounded
+ *   by a structure ("t(...)").  This effectively prepends each item in
+ *   the array with its length.  This is useful for improving parsing
+ *   performance or to allow additional fields to be added in the future
+ *   in a backward compatible way.  If there is a high certainty that
+ *   additional fields will never be added, the struct may be omitted
+ *   (saving two bytes per item).
+ *
+ *   This specification does not define a way to embed an array as a field
+ *   alongside other fields.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ *   Spinel definition guideline:
+ *
+ *   New NCP firmware should work with an older host driver, i.e., NCP
+ *   implementation should remain backward compatible.
+ *
+ *    - Existing fields in the format of an already implemented spinel
+ *      property or command cannot change.
+ *
+ *    - New fields may be appended at the end of the format (or the end of
+ *      a struct) as long as the NCP implementation treats the new fields as
+ *      optional (i.e., a driver not aware of and therefore not using the
+ *      new fields should continue to function as before).
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#ifdef SPINEL_PLATFORM_HEADER
+#include SPINEL_PLATFORM_HEADER
+#else // ifdef SPINEL_PLATFORM_HEADER
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#endif // else SPINEL_PLATFORM_HEADER
+
+// ----------------------------------------------------------------------------
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#if defined(__GNUC__)
+#define SPINEL_API_EXTERN extern __attribute__((visibility("default")))
+#define SPINEL_API_NONNULL_ALL __attribute__((nonnull))
+#define SPINEL_API_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#endif // ifdef __GNUC__
+
+#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#ifndef SPINEL_API_EXTERN
+#define SPINEL_API_EXTERN extern
+#endif
+
+#ifndef SPINEL_API_NONNULL_ALL
+#define SPINEL_API_NONNULL_ALL
+#endif
+
+#ifndef SPINEL_API_WARN_UNUSED_RESULT
+#define SPINEL_API_WARN_UNUSED_RESULT
+#endif
+
+// ----------------------------------------------------------------------------
+
+#define SPINEL_PROTOCOL_VERSION_THREAD_MAJOR 4
+#define SPINEL_PROTOCOL_VERSION_THREAD_MINOR 3
+
+/**
+ * @def SPINEL_FRAME_MAX_SIZE
+ *
+ *  The maximum size of SPINEL frame.
+ *
+ */
+#define SPINEL_FRAME_MAX_SIZE 1300
+
+/**
+ * @def SPINEL_FRAME_MAX_COMMAND_HEADER_SIZE
+ *
+ *  The maximum size of SPINEL command header.
+ *
+ */
+#define SPINEL_FRAME_MAX_COMMAND_HEADER_SIZE 4
+
+/**
+ * @def SPINEL_FRAME_MAX_PAYLOAD_SIZE
+ *
+ *  The maximum size of SPINEL command payload.
+ *
+ */
+#define SPINEL_FRAME_MAX_COMMAND_PAYLOAD_SIZE (SPINEL_FRAME_MAX_SIZE - SPINEL_FRAME_MAX_COMMAND_HEADER_SIZE)
+
+/**
+ * @def SPINEL_ENCRYPTER_EXTRA_DATA_SIZE
+ *
+ *  The size of extra data to be allocated for spinel frame buffer,
+ *  needed by Spinel Encrypter.
+ *
+ */
+#define SPINEL_ENCRYPTER_EXTRA_DATA_SIZE 0
+
+/**
+ * @def SPINEL_FRAME_BUFFER_SIZE
+ *
+ *  The size of buffer large enough to fit one whole spinel frame with extra data
+ *  needed by Spinel Encrypter.
+ *
+ */
+#define SPINEL_FRAME_BUFFER_SIZE (SPINEL_FRAME_MAX_SIZE + SPINEL_ENCRYPTER_EXTRA_DATA_SIZE)
+
+/// Macro for generating bit masks using bit index from the spec
+#define SPINEL_BIT_MASK(bit_index, field_bit_count) ((1 << ((field_bit_count)-1)) >> (bit_index))
+
+// ----------------------------------------------------------------------------
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+enum
+{
+    SPINEL_STATUS_OK                       = 0,  ///< Operation has completed successfully.
+    SPINEL_STATUS_FAILURE                  = 1,  ///< Operation has failed for some undefined reason.
+    SPINEL_STATUS_UNIMPLEMENTED            = 2,  ///< Given operation has not been implemented.
+    SPINEL_STATUS_INVALID_ARGUMENT         = 3,  ///< An argument to the operation is invalid.
+    SPINEL_STATUS_INVALID_STATE            = 4,  ///< This operation is invalid for the current device state.
+    SPINEL_STATUS_INVALID_COMMAND          = 5,  ///< This command is not recognized.
+    SPINEL_STATUS_INVALID_INTERFACE        = 6,  ///< This interface is not supported.
+    SPINEL_STATUS_INTERNAL_ERROR           = 7,  ///< An internal runtime error has occurred.
+    SPINEL_STATUS_SECURITY_ERROR           = 8,  ///< A security/authentication error has occurred.
+    SPINEL_STATUS_PARSE_ERROR              = 9,  ///< A error has occurred while parsing the command.
+    SPINEL_STATUS_IN_PROGRESS              = 10, ///< This operation is in progress.
+    SPINEL_STATUS_NOMEM                    = 11, ///< Operation prevented due to memory pressure.
+    SPINEL_STATUS_BUSY                     = 12, ///< The device is currently performing a mutually exclusive operation
+    SPINEL_STATUS_PROP_NOT_FOUND           = 13, ///< The given property is not recognized.
+    SPINEL_STATUS_DROPPED                  = 14, ///< A/The packet was dropped.
+    SPINEL_STATUS_EMPTY                    = 15, ///< The result of the operation is empty.
+    SPINEL_STATUS_CMD_TOO_BIG              = 16, ///< The command was too large to fit in the internal buffer.
+    SPINEL_STATUS_NO_ACK                   = 17, ///< The packet was not acknowledged.
+    SPINEL_STATUS_CCA_FAILURE              = 18, ///< The packet was not sent due to a CCA failure.
+    SPINEL_STATUS_ALREADY                  = 19, ///< The operation is already in progress.
+    SPINEL_STATUS_ITEM_NOT_FOUND           = 20, ///< The given item could not be found.
+    SPINEL_STATUS_INVALID_COMMAND_FOR_PROP = 21, ///< The given command cannot be performed on this property.
+
+    SPINEL_STATUS_JOIN__BEGIN = 104,
+
+    /// Generic failure to associate with other peers.
+    /**
+     *  This status error should not be used by implementors if
+     *  enough information is available to determine that one of the
+     *  later join failure status codes would be more accurate.
+     *
+     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
+     */
+    SPINEL_STATUS_JOIN_FAILURE = SPINEL_STATUS_JOIN__BEGIN + 0,
+
+    /// The node found other peers but was unable to decode their packets.
+    /**
+     *  Typically this error code indicates that the network
+     *  key has been set incorrectly.
+     *
+     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
+     */
+    SPINEL_STATUS_JOIN_SECURITY = SPINEL_STATUS_JOIN__BEGIN + 1,
+
+    /// The node was unable to find any other peers on the network.
+    /**
+     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
+     */
+    SPINEL_STATUS_JOIN_NO_PEERS = SPINEL_STATUS_JOIN__BEGIN + 2,
+
+    /// The only potential peer nodes found are incompatible.
+    /**
+     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+     */
+    SPINEL_STATUS_JOIN_INCOMPATIBLE = SPINEL_STATUS_JOIN__BEGIN + 3,
+
+    /// No response in expecting time.
+    /**
+     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
+     */
+    SPINEL_STATUS_JOIN_RSP_TIMEOUT = SPINEL_STATUS_JOIN__BEGIN + 4,
+
+    /// The node succeeds in commissioning and get the network credentials.
+    /**
+     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
+     */
+    SPINEL_STATUS_JOIN_SUCCESS = SPINEL_STATUS_JOIN__BEGIN + 5,
+
+    SPINEL_STATUS_JOIN__END = 112,
+
+    SPINEL_STATUS_RESET__BEGIN   = 112,
+    SPINEL_STATUS_RESET_POWER_ON = SPINEL_STATUS_RESET__BEGIN + 0,
+    SPINEL_STATUS_RESET_EXTERNAL = SPINEL_STATUS_RESET__BEGIN + 1,
+    SPINEL_STATUS_RESET_SOFTWARE = SPINEL_STATUS_RESET__BEGIN + 2,
+    SPINEL_STATUS_RESET_FAULT    = SPINEL_STATUS_RESET__BEGIN + 3,
+    SPINEL_STATUS_RESET_CRASH    = SPINEL_STATUS_RESET__BEGIN + 4,
+    SPINEL_STATUS_RESET_ASSERT   = SPINEL_STATUS_RESET__BEGIN + 5,
+    SPINEL_STATUS_RESET_OTHER    = SPINEL_STATUS_RESET__BEGIN + 6,
+    SPINEL_STATUS_RESET_UNKNOWN  = SPINEL_STATUS_RESET__BEGIN + 7,
+    SPINEL_STATUS_RESET_WATCHDOG = SPINEL_STATUS_RESET__BEGIN + 8,
+    SPINEL_STATUS_RESET__END     = 128,
+
+    SPINEL_STATUS_VENDOR__BEGIN = 15360,
+    SPINEL_STATUS_VENDOR__END   = 16384,
+
+    SPINEL_STATUS_STACK_NATIVE__BEGIN = 16384,
+    SPINEL_STATUS_STACK_NATIVE__END   = 81920,
+
+    SPINEL_STATUS_EXPERIMENTAL__BEGIN = 2000000,
+    SPINEL_STATUS_EXPERIMENTAL__END   = 2097152,
+};
+
+typedef uint32_t spinel_status_t;
+
+typedef enum
+{
+    SPINEL_NET_ROLE_DETACHED = 0,
+    SPINEL_NET_ROLE_CHILD    = 1,
+    SPINEL_NET_ROLE_ROUTER   = 2,
+    SPINEL_NET_ROLE_LEADER   = 3,
+} spinel_net_role_t;
+
+typedef enum
+{
+    SPINEL_IPV6_ICMP_PING_OFFLOAD_DISABLED       = 0,
+    SPINEL_IPV6_ICMP_PING_OFFLOAD_UNICAST_ONLY   = 1,
+    SPINEL_IPV6_ICMP_PING_OFFLOAD_MULTICAST_ONLY = 2,
+    SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL            = 3,
+} spinel_ipv6_icmp_ping_offload_mode_t;
+
+typedef enum
+{
+    SPINEL_SCAN_STATE_IDLE     = 0,
+    SPINEL_SCAN_STATE_BEACON   = 1,
+    SPINEL_SCAN_STATE_ENERGY   = 2,
+    SPINEL_SCAN_STATE_DISCOVER = 3,
+} spinel_scan_state_t;
+
+typedef enum
+{
+    SPINEL_MCU_POWER_STATE_ON        = 0,
+    SPINEL_MCU_POWER_STATE_LOW_POWER = 1,
+    SPINEL_MCU_POWER_STATE_OFF       = 2,
+} spinel_mcu_power_state_t;
+
+// The `spinel_power_state_t` enumeration and `POWER_STATE`
+// property are deprecated. Please use `MCU_POWER_STATE`
+// instead.
+typedef enum
+{
+    SPINEL_POWER_STATE_OFFLINE    = 0,
+    SPINEL_POWER_STATE_DEEP_SLEEP = 1,
+    SPINEL_POWER_STATE_STANDBY    = 2,
+    SPINEL_POWER_STATE_LOW_POWER  = 3,
+    SPINEL_POWER_STATE_ONLINE     = 4,
+} spinel_power_state_t;
+
+typedef enum
+{
+    SPINEL_HOST_POWER_STATE_OFFLINE    = 0,
+    SPINEL_HOST_POWER_STATE_DEEP_SLEEP = 1,
+    SPINEL_HOST_POWER_STATE_RESERVED   = 2,
+    SPINEL_HOST_POWER_STATE_LOW_POWER  = 3,
+    SPINEL_HOST_POWER_STATE_ONLINE     = 4,
+} spinel_host_power_state_t;
+
+typedef enum
+{
+    SPINEL_MESHCOP_JOINER_STATE_IDLE       = 0,
+    SPINEL_MESHCOP_JOINER_STATE_DISCOVER   = 1,
+    SPINEL_MESHCOP_JOINER_STATE_CONNECTING = 2,
+    SPINEL_MESHCOP_JOINER_STATE_CONNECTED  = 3,
+    SPINEL_MESHCOP_JOINER_STATE_ENTRUST    = 4,
+    SPINEL_MESHCOP_JOINER_STATE_JOINED     = 5,
+} spinel_meshcop_joiner_state_t;
+
+enum
+{
+    SPINEL_NET_FLAG_ON_MESH       = (1 << 0),
+    SPINEL_NET_FLAG_DEFAULT_ROUTE = (1 << 1),
+    SPINEL_NET_FLAG_CONFIGURE     = (1 << 2),
+    SPINEL_NET_FLAG_DHCP          = (1 << 3),
+    SPINEL_NET_FLAG_SLAAC         = (1 << 4),
+    SPINEL_NET_FLAG_PREFERRED     = (1 << 5),
+
+    SPINEL_NET_FLAG_PREFERENCE_OFFSET = 6,
+    SPINEL_NET_FLAG_PREFERENCE_MASK   = (3 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
+};
+
+enum
+{
+    SPINEL_ROUTE_PREFERENCE_HIGH   = (1 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
+    SPINEL_ROUTE_PREFERENCE_MEDIUM = (0 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
+    SPINEL_ROUTE_PREFERENCE_LOW    = (3 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
+};
+
+enum
+{
+    SPINEL_THREAD_MODE_FULL_NETWORK_DATA   = (1 << 0),
+    SPINEL_THREAD_MODE_FULL_THREAD_DEV     = (1 << 1),
+    SPINEL_THREAD_MODE_SECURE_DATA_REQUEST = (1 << 2),
+    SPINEL_THREAD_MODE_RX_ON_WHEN_IDLE     = (1 << 3),
+};
+
+enum
+{
+    SPINEL_GPIO_FLAG_DIR_INPUT       = 0,
+    SPINEL_GPIO_FLAG_DIR_OUTPUT      = SPINEL_BIT_MASK(0, 8),
+    SPINEL_GPIO_FLAG_PULL_UP         = SPINEL_BIT_MASK(1, 8),
+    SPINEL_GPIO_FLAG_PULL_DOWN       = SPINEL_BIT_MASK(2, 8),
+    SPINEL_GPIO_FLAG_OPEN_DRAIN      = SPINEL_BIT_MASK(2, 8),
+    SPINEL_GPIO_FLAG_TRIGGER_NONE    = 0,
+    SPINEL_GPIO_FLAG_TRIGGER_RISING  = SPINEL_BIT_MASK(3, 8),
+    SPINEL_GPIO_FLAG_TRIGGER_FALLING = SPINEL_BIT_MASK(4, 8),
+    SPINEL_GPIO_FLAG_TRIGGER_ANY     = SPINEL_GPIO_FLAG_TRIGGER_RISING | SPINEL_GPIO_FLAG_TRIGGER_FALLING,
+};
+
+enum
+{
+    SPINEL_PROTOCOL_TYPE_BOOTLOADER = 0,
+    SPINEL_PROTOCOL_TYPE_ZIGBEE_IP  = 2,
+    SPINEL_PROTOCOL_TYPE_THREAD     = 3,
+};
+
+enum
+{
+    SPINEL_MAC_PROMISCUOUS_MODE_OFF     = 0, ///< Normal MAC filtering is in place.
+    SPINEL_MAC_PROMISCUOUS_MODE_NETWORK = 1, ///< All MAC packets matching network are passed up the stack.
+    SPINEL_MAC_PROMISCUOUS_MODE_FULL    = 2, ///< All decoded MAC packets are passed up the stack.
+};
+
+enum
+{
+    SPINEL_NCP_LOG_LEVEL_EMERG  = 0,
+    SPINEL_NCP_LOG_LEVEL_ALERT  = 1,
+    SPINEL_NCP_LOG_LEVEL_CRIT   = 2,
+    SPINEL_NCP_LOG_LEVEL_ERR    = 3,
+    SPINEL_NCP_LOG_LEVEL_WARN   = 4,
+    SPINEL_NCP_LOG_LEVEL_NOTICE = 5,
+    SPINEL_NCP_LOG_LEVEL_INFO   = 6,
+    SPINEL_NCP_LOG_LEVEL_DEBUG  = 7,
+};
+
+enum
+{
+    SPINEL_NCP_LOG_REGION_NONE        = 0,
+    SPINEL_NCP_LOG_REGION_OT_API      = 1,
+    SPINEL_NCP_LOG_REGION_OT_MLE      = 2,
+    SPINEL_NCP_LOG_REGION_OT_ARP      = 3,
+    SPINEL_NCP_LOG_REGION_OT_NET_DATA = 4,
+    SPINEL_NCP_LOG_REGION_OT_ICMP     = 5,
+    SPINEL_NCP_LOG_REGION_OT_IP6      = 6,
+    SPINEL_NCP_LOG_REGION_OT_MAC      = 7,
+    SPINEL_NCP_LOG_REGION_OT_MEM      = 8,
+    SPINEL_NCP_LOG_REGION_OT_NCP      = 9,
+    SPINEL_NCP_LOG_REGION_OT_MESH_COP = 10,
+    SPINEL_NCP_LOG_REGION_OT_NET_DIAG = 11,
+    SPINEL_NCP_LOG_REGION_OT_PLATFORM = 12,
+    SPINEL_NCP_LOG_REGION_OT_COAP     = 13,
+    SPINEL_NCP_LOG_REGION_OT_CLI      = 14,
+    SPINEL_NCP_LOG_REGION_OT_CORE     = 15,
+    SPINEL_NCP_LOG_REGION_OT_UTIL     = 16,
+    SPINEL_NCP_LOG_REGION_OT_BBR      = 17,
+    SPINEL_NCP_LOG_REGION_OT_MLR      = 18,
+};
+
+enum
+{
+    SPINEL_MESHCOP_COMMISSIONER_STATE_DISABLED = 0,
+    SPINEL_MESHCOP_COMMISSIONER_STATE_PETITION = 1,
+    SPINEL_MESHCOP_COMMISSIONER_STATE_ACTIVE   = 2,
+};
+
+enum
+{
+    SPINEL_ADDRESS_CACHE_ENTRY_STATE_CACHED      = 0, // Entry is cached and in-use.
+    SPINEL_ADDRESS_CACHE_ENTRY_STATE_SNOOPED     = 1, // Entry is created by snoop optimization.
+    SPINEL_ADDRESS_CACHE_ENTRY_STATE_QUERY       = 2, // Entry represents an ongoing query for the EID.
+    SPINEL_ADDRESS_CACHE_ENTRY_STATE_RETRY_QUERY = 3, // Entry is in retry mode (a prior query did not  a response).
+};
+
+typedef struct
+{
+    uint8_t bytes[8];
+} spinel_eui64_t;
+
+typedef struct
+{
+    uint8_t bytes[8];
+} spinel_net_xpanid_t;
+
+typedef struct
+{
+    uint8_t bytes[16];
+} spinel_net_pskc_t;
+
+typedef struct
+{
+    uint8_t bytes[6];
+} spinel_eui48_t;
+
+typedef struct
+{
+    uint8_t bytes[16];
+} spinel_ipv6addr_t;
+
+typedef int          spinel_ssize_t;
+typedef unsigned int spinel_size_t;
+typedef uint8_t      spinel_tid_t;
+
+enum
+{
+    SPINEL_MD_FLAG_TX        = 0x0001, //!< Packet was transmitted, not received.
+    SPINEL_MD_FLAG_BAD_FCS   = 0x0004, //!< Packet was received with bad FCS
+    SPINEL_MD_FLAG_DUPE      = 0x0008, //!< Packet seems to be a duplicate
+    SPINEL_MD_FLAG_ACKED_FP  = 0x0010, //!< Packet was acknowledged with frame pending set
+    SPINEL_MD_FLAG_ACKED_SEC = 0x0020, //!< Packet was acknowledged with secure enhance ACK
+    SPINEL_MD_FLAG_RESERVED  = 0xFFC2, //!< Flags reserved for future use.
+};
+
+enum
+{
+    /**
+     * No-Operation command (Host -> NCP)
+     *
+     * Encoding: Empty
+     *
+     * Induces the NCP to send a success status back to the host. This is
+     * primarily used for liveliness checks. The command payload for this
+     * command SHOULD be empty.
+     *
+     * There is no error condition for this command.
+     *
+     */
+    SPINEL_CMD_NOOP = 0,
+
+    /**
+     * Reset NCP command (Host -> NCP)
+     *
+     * Encoding: Empty
+     *
+     * Causes the NCP to perform a software reset. Due to the nature of
+     * this command, the TID is ignored. The host should instead wait
+     * for a `CMD_PROP_VALUE_IS` command from the NCP indicating
+     * `PROP_LAST_STATUS` has been set to `STATUS_RESET_SOFTWARE`.
+     *
+     * The command payload for this command SHOULD be empty.
+     *
+     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
+     * instead with the value set to the generated status code for the error.
+     *
+     */
+    SPINEL_CMD_RESET = 1,
+
+    /**
+     * Get property value command (Host -> NCP)
+     *
+     * Encoding: `i`
+     *   `i` : Property Id
+     *
+     * Causes the NCP to emit a `CMD_PROP_VALUE_IS` command for the
+     * given property identifier.
+     *
+     * The payload for this command is the property identifier encoded
+     * in the packed unsigned integer format `i`.
+     *
+     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
+     * instead with the value set to the generated status code for the error.
+     *
+     */
+    SPINEL_CMD_PROP_VALUE_GET = 2,
+
+    /**
+     * Set property value command (Host -> NCP)
+     *
+     * Encoding: `iD`
+     *   `i` : Property Id
+     *   `D` : Value (encoding depends on the property)
+     *
+     * Instructs the NCP to set the given property to the specific given
+     * value, replacing any previous value.
+     *
+     * The payload for this command is the property identifier encoded in the
+     * packed unsigned integer format, followed by the property value. The
+     * exact format of the property value is defined by the property.
+     *
+     * On success a `CMD_PROP_VALUE_IS` command is emitted either for the
+     * given property identifier with the set value, or for `PROP_LAST_STATUS`
+     * with value `LAST_STATUS_OK`.
+     *
+     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
+     * with the value set to the generated status code for the error.
+     *
+     */
+    SPINEL_CMD_PROP_VALUE_SET = 3,
+
+    /**
+     * Insert value into property command (Host -> NCP)
+     *
+     * Encoding: `iD`
+     *   `i` : Property Id
+     *   `D` : Value (encoding depends on the property)
+     *
+     * Instructs the NCP to insert the given value into a list-oriented
+     * property without removing other items in the list. The resulting order
+     * of items in the list is defined by the individual property being
+     * operated on.
+     *
+     * The payload for this command is the property identifier encoded in the
+     * packed unsigned integer format, followed by the value to be inserted.
+     * The exact format of the value is defined by the property.
+     *
+     * If the type signature of the property consists of a single structure
+     * enclosed by an array `A(t(...))`, then the contents of value MUST
+     * contain the contents of the structure (`...`) rather than the
+     * serialization of the whole item (`t(...)`).  Specifically, the length
+     * of the structure MUST NOT be prepended to value. This helps to
+     * eliminate redundant data.
+     *
+     * On success, either a `CMD_PROP_VALUE_INSERTED` command is emitted for
+     * the given property, or a `CMD_PROP_VALUE_IS` command is emitted of
+     * property `PROP_LAST_STATUS` with value `LAST_STATUS_OK`.
+     *
+     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
+     * with the value set to the generated status code for the error.
+     *
+     */
+    SPINEL_CMD_PROP_VALUE_INSERT = 4,
+
+    /**
+     * Remove value from property command (Host -> NCP)
+     *
+     * Encoding: `iD`
+     *   `i` : Property Id
+     *   `D` : Value (encoding depends on the property)
+
+     * Instructs the NCP to remove the given value from a list-oriented property,
+     * without affecting other items in the list. The resulting order of items
+     * in the list is defined by the individual property being operated on.
+     *
+     * Note that this command operates by value, not by index!
+     *
+     * The payload for this command is the property identifier encoded in the
+     * packed unsigned integer format, followed by the value to be removed. The
+     * exact format of the value is defined by the property.
+     *
+     * If the type signature of the property consists of a single structure
+     * enclosed by an array `A(t(...))`, then the contents of value MUST contain
+     * the contents of the structure (`...`) rather than the serialization of the
+     * whole item (`t(...)`).  Specifically, the length of the structure MUST NOT
+     * be prepended to `VALUE`. This helps to eliminate redundant data.
+     *
+     * On success, either a `CMD_PROP_VALUE_REMOVED` command is emitted for the
+     * given property, or a `CMD_PROP_VALUE_IS` command is emitted of property
+     * `PROP_LAST_STATUS` with value `LAST_STATUS_OK`.
+     *
+     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
+     * with the value set to the generated status code for the error.
+     *
+     */
+    SPINEL_CMD_PROP_VALUE_REMOVE = 5,
+
+    /**
+     * Property value notification command (NCP -> Host)
+     *
+     * Encoding: `iD`
+     *   `i` : Property Id
+     *   `D` : Value (encoding depends on the property)
+     *
+     * This command can be sent by the NCP in response to a previous command
+     * from the host, or it can be sent by the NCP in an unsolicited fashion
+     * to notify the host of various state changes asynchronously.
+     *
+     * The payload for this command is the property identifier encoded in the
+     * packed unsigned integer format, followed by the current value of the
+     * given property.
+     *
+     */
+    SPINEL_CMD_PROP_VALUE_IS = 6,
+
+    /**
+     * Property value insertion notification command (NCP -> Host)
+     *
+     * Encoding:`iD`
+     *   `i` : Property Id
+     *   `D` : Value (encoding depends on the property)
+     *
+     * This command can be sent by the NCP in response to the
+     * `CMD_PROP_VALUE_INSERT` command, or it can be sent by the NCP in an
+     * unsolicited fashion to notify the host of various state changes
+     * asynchronously.
+     *
+     * The payload for this command is the property identifier encoded in the
+     * packed unsigned integer format, followed by the value that was inserted
+     * into the given property.
+     *
+     * If the type signature of the property specified by property id consists
+     * of a single structure enclosed by an array (`A(t(...))`), then the
+     * contents of value MUST contain the contents of the structure (`...`)
+     * rather than the serialization of the whole item (`t(...)`). Specifically,
+     * the length of the structure MUST NOT be prepended to `VALUE`. This
+     * helps to eliminate redundant data.
+     *
+     * The resulting order of items in the list is defined by the given
+     * property.
+     *
+     */
+    SPINEL_CMD_PROP_VALUE_INSERTED = 7,
+
+    /**
+     * Property value removal notification command (NCP -> Host)
+     *
+     * Encoding: `iD`
+     *   `i` : Property Id
+     *   `D` : Value (encoding depends on the property)
+     *
+     * This command can be sent by the NCP in response to the
+     * `CMD_PROP_VALUE_REMOVE` command, or it can be sent by the NCP in an
+     * unsolicited fashion to notify the host of various state changes
+     * asynchronously.
+     *
+     * Note that this command operates by value, not by index!
+     *
+     * The payload for this command is the property identifier encoded in the
+     * packed unsigned integer format described in followed by the value that
+     * was removed from the given property.
+     *
+     * If the type signature of the property specified by property id consists
+     * of a single structure enclosed by an array (`A(t(...))`), then the
+     * contents of value MUST contain the contents of the structure (`...`)
+     * rather than the serialization of the whole item (`t(...)`).  Specifically,
+     * the length of the structure MUST NOT be prepended to `VALUE`. This
+     * helps to eliminate redundant data.
+     *
+     * The resulting order of items in the list is defined by the given
+     * property.
+     *
+     */
+    SPINEL_CMD_PROP_VALUE_REMOVED = 8,
+
+    SPINEL_CMD_NET_SAVE = 9, // Deprecated
+
+    /**
+     * Clear saved network settings command (Host -> NCP)
+     *
+     * Encoding: Empty
+     *
+     * Erases all network credentials and state from non-volatile memory.
+     *
+     * This operation affects non-volatile memory only. The current network
+     * information stored in volatile memory is unaffected.
+     *
+     * The response to this command is always a `CMD_PROP_VALUE_IS` for
+     * `PROP_LAST_STATUS`, indicating the result of the operation.
+     *
+     */
+    SPINEL_CMD_NET_CLEAR = 10,
+
+    SPINEL_CMD_NET_RECALL = 11, // Deprecated
+
+    /**
+     * Host buffer offload is an optional NCP capability that, when
+     * present, allows the NCP to store data buffers on the host processor
+     * that can be recalled at a later time.
+     *
+     * The presence of this feature can be detected by the host by
+     * checking for the presence of the `CAP_HBO`
+     * capability in `PROP_CAPS`.
+     *
+     * This feature is not currently supported on OpenThread.
+     *
+     */
+
+    SPINEL_CMD_HBO_OFFLOAD   = 12,
+    SPINEL_CMD_HBO_RECLAIM   = 13,
+    SPINEL_CMD_HBO_DROP      = 14,
+    SPINEL_CMD_HBO_OFFLOADED = 15,
+    SPINEL_CMD_HBO_RECLAIMED = 16,
+    SPINEL_CMD_HBO_DROPPED   = 17,
+
+    /**
+     * Peek command (Host -> NCP)
+     *
+     * Encoding: `LU`
+     *   `L` : The address to peek
+     *   `U` : Number of bytes to read
+     *
+     * This command allows the NCP to fetch values from the RAM of the NCP
+     * for debugging purposes. Upon success, `CMD_PEEK_RET` is sent from the
+     * NCP to the host. Upon failure, `PROP_LAST_STATUS` is emitted with
+     * the appropriate error indication.
+     *
+     * The NCP MAY prevent certain regions of memory from being accessed.
+     *
+     * This command requires the capability `CAP_PEEK_POKE` to be present.
+     *
+     */
+    SPINEL_CMD_PEEK = 18,
+
+    /**
+     * Peek return command (NCP -> Host)
+     *
+     * Encoding: `LUD`
+     *   `L` : The address peeked
+     *   `U` : Number of bytes read
+     *   `D` : Memory content
+     *
+     * This command contains the contents of memory that was requested by
+     * a previous call to `CMD_PEEK`.
+     *
+     * This command requires the capability `CAP_PEEK_POKE` to be present.
+     *
+     */
+    SPINEL_CMD_PEEK_RET = 19,
+
+    /**
+     * Poke command (Host -> NCP)
+     *
+     * Encoding: `LUD`
+     *   `L` : The address to be poked
+     *   `U` : Number of bytes to write
+     *   `D` : Content to write
+     *
+     * This command writes the bytes to the specified memory address
+     * for debugging purposes.
+     *
+     * This command requires the capability `CAP_PEEK_POKE` to be present.
+     *
+     */
+    SPINEL_CMD_POKE = 20,
+
+    SPINEL_CMD_PROP_VALUE_MULTI_GET = 21,
+    SPINEL_CMD_PROP_VALUE_MULTI_SET = 22,
+    SPINEL_CMD_PROP_VALUES_ARE      = 23,
+
+    SPINEL_CMD_NEST__BEGIN = 15296,
+    SPINEL_CMD_NEST__END   = 15360,
+
+    SPINEL_CMD_VENDOR__BEGIN = 15360,
+    SPINEL_CMD_VENDOR__END   = 16384,
+
+    SPINEL_CMD_EXPERIMENTAL__BEGIN = 2000000,
+    SPINEL_CMD_EXPERIMENTAL__END   = 2097152,
+};
+
+typedef uint32_t spinel_command_t;
+
+enum
+{
+    SPINEL_CAP_LOCK       = 1,
+    SPINEL_CAP_NET_SAVE   = 2,
+    SPINEL_CAP_HBO        = 3,
+    SPINEL_CAP_POWER_SAVE = 4,
+
+    SPINEL_CAP_COUNTERS   = 5,
+    SPINEL_CAP_JAM_DETECT = 6,
+
+    SPINEL_CAP_PEEK_POKE = 7,
+
+    SPINEL_CAP_WRITABLE_RAW_STREAM = 8,
+    SPINEL_CAP_GPIO                = 9,
+    SPINEL_CAP_TRNG                = 10,
+    SPINEL_CAP_CMD_MULTI           = 11,
+    SPINEL_CAP_UNSOL_UPDATE_FILTER = 12,
+    SPINEL_CAP_MCU_POWER_STATE     = 13,
+    SPINEL_CAP_PCAP                = 14,
+
+    SPINEL_CAP_802_15_4__BEGIN        = 16,
+    SPINEL_CAP_802_15_4_2003          = (SPINEL_CAP_802_15_4__BEGIN + 0),
+    SPINEL_CAP_802_15_4_2006          = (SPINEL_CAP_802_15_4__BEGIN + 1),
+    SPINEL_CAP_802_15_4_2011          = (SPINEL_CAP_802_15_4__BEGIN + 2),
+    SPINEL_CAP_802_15_4_PIB           = (SPINEL_CAP_802_15_4__BEGIN + 5),
+    SPINEL_CAP_802_15_4_2450MHZ_OQPSK = (SPINEL_CAP_802_15_4__BEGIN + 8),
+    SPINEL_CAP_802_15_4_915MHZ_OQPSK  = (SPINEL_CAP_802_15_4__BEGIN + 9),
+    SPINEL_CAP_802_15_4_868MHZ_OQPSK  = (SPINEL_CAP_802_15_4__BEGIN + 10),
+    SPINEL_CAP_802_15_4_915MHZ_BPSK   = (SPINEL_CAP_802_15_4__BEGIN + 11),
+    SPINEL_CAP_802_15_4_868MHZ_BPSK   = (SPINEL_CAP_802_15_4__BEGIN + 12),
+    SPINEL_CAP_802_15_4_915MHZ_ASK    = (SPINEL_CAP_802_15_4__BEGIN + 13),
+    SPINEL_CAP_802_15_4_868MHZ_ASK    = (SPINEL_CAP_802_15_4__BEGIN + 14),
+    SPINEL_CAP_802_15_4__END          = 32,
+
+    SPINEL_CAP_CONFIG__BEGIN = 32,
+    SPINEL_CAP_CONFIG_FTD    = (SPINEL_CAP_CONFIG__BEGIN + 0),
+    SPINEL_CAP_CONFIG_MTD    = (SPINEL_CAP_CONFIG__BEGIN + 1),
+    SPINEL_CAP_CONFIG_RADIO  = (SPINEL_CAP_CONFIG__BEGIN + 2),
+    SPINEL_CAP_CONFIG__END   = 40,
+
+    SPINEL_CAP_ROLE__BEGIN = 48,
+    SPINEL_CAP_ROLE_ROUTER = (SPINEL_CAP_ROLE__BEGIN + 0),
+    SPINEL_CAP_ROLE_SLEEPY = (SPINEL_CAP_ROLE__BEGIN + 1),
+    SPINEL_CAP_ROLE__END   = 52,
+
+    SPINEL_CAP_NET__BEGIN     = 52,
+    SPINEL_CAP_NET_THREAD_1_0 = (SPINEL_CAP_NET__BEGIN + 0),
+    SPINEL_CAP_NET_THREAD_1_1 = (SPINEL_CAP_NET__BEGIN + 1),
+    SPINEL_CAP_NET__END       = 64,
+
+    SPINEL_CAP_OPENTHREAD__BEGIN       = 512,
+    SPINEL_CAP_MAC_WHITELIST           = (SPINEL_CAP_OPENTHREAD__BEGIN + 0),
+    SPINEL_CAP_MAC_RAW                 = (SPINEL_CAP_OPENTHREAD__BEGIN + 1),
+    SPINEL_CAP_OOB_STEERING_DATA       = (SPINEL_CAP_OPENTHREAD__BEGIN + 2),
+    SPINEL_CAP_CHANNEL_MONITOR         = (SPINEL_CAP_OPENTHREAD__BEGIN + 3),
+    SPINEL_CAP_ERROR_RATE_TRACKING     = (SPINEL_CAP_OPENTHREAD__BEGIN + 4),
+    SPINEL_CAP_CHANNEL_MANAGER         = (SPINEL_CAP_OPENTHREAD__BEGIN + 5),
+    SPINEL_CAP_OPENTHREAD_LOG_METADATA = (SPINEL_CAP_OPENTHREAD__BEGIN + 6),
+    SPINEL_CAP_TIME_SYNC               = (SPINEL_CAP_OPENTHREAD__BEGIN + 7),
+    SPINEL_CAP_CHILD_SUPERVISION       = (SPINEL_CAP_OPENTHREAD__BEGIN + 8),
+    SPINEL_CAP_POSIX                   = (SPINEL_CAP_OPENTHREAD__BEGIN + 9),
+    SPINEL_CAP_SLAAC                   = (SPINEL_CAP_OPENTHREAD__BEGIN + 10),
+    SPINEL_CAP_RADIO_COEX              = (SPINEL_CAP_OPENTHREAD__BEGIN + 11),
+    SPINEL_CAP_MAC_RETRY_HISTOGRAM     = (SPINEL_CAP_OPENTHREAD__BEGIN + 12),
+    SPINEL_CAP_OPENTHREAD__END         = 640,
+
+    SPINEL_CAP_THREAD__BEGIN        = 1024,
+    SPINEL_CAP_THREAD_COMMISSIONER  = (SPINEL_CAP_THREAD__BEGIN + 0),
+    SPINEL_CAP_THREAD_TMF_PROXY     = (SPINEL_CAP_THREAD__BEGIN + 1),
+    SPINEL_CAP_THREAD_UDP_FORWARD   = (SPINEL_CAP_THREAD__BEGIN + 2),
+    SPINEL_CAP_THREAD_JOINER        = (SPINEL_CAP_THREAD__BEGIN + 3),
+    SPINEL_CAP_THREAD_BORDER_ROUTER = (SPINEL_CAP_THREAD__BEGIN + 4),
+    SPINEL_CAP_THREAD_SERVICE       = (SPINEL_CAP_THREAD__BEGIN + 5),
+    SPINEL_CAP_THREAD__END          = 1152,
+
+    SPINEL_CAP_NEST__BEGIN           = 15296,
+    SPINEL_CAP_NEST_LEGACY_INTERFACE = (SPINEL_CAP_NEST__BEGIN + 0),
+    SPINEL_CAP_NEST_LEGACY_NET_WAKE  = (SPINEL_CAP_NEST__BEGIN + 1),
+    SPINEL_CAP_NEST_TRANSMIT_HOOK    = (SPINEL_CAP_NEST__BEGIN + 2),
+    SPINEL_CAP_NEST__END             = 15360,
+
+    SPINEL_CAP_VENDOR__BEGIN = 15360,
+    SPINEL_CAP_VENDOR__END   = 16384,
+
+    SPINEL_CAP_EXPERIMENTAL__BEGIN = 2000000,
+    SPINEL_CAP_EXPERIMENTAL__END   = 2097152,
+};
+
+typedef uint32_t spinel_capability_t;
+
+/**
+ * Property Keys
+ *
+ * The properties are broken up into several sections, each with a
+ * reserved ranges of property identifiers:
+ *
+ *    Name         | Range (Inclusive)              | Description
+ *    -------------|--------------------------------|------------------------
+ *    Core         | 0x000 - 0x01F, 0x1000 - 0x11FF | Spinel core
+ *    PHY          | 0x020 - 0x02F, 0x1200 - 0x12FF | Radio PHY layer
+ *    MAC          | 0x030 - 0x03F, 0x1300 - 0x13FF | MAC layer
+ *    NET          | 0x040 - 0x04F, 0x1400 - 0x14FF | Network
+ *    Thread       | 0x050 - 0x05F, 0x1500 - 0x15FF | Thread
+ *    IPv6         | 0x060 - 0x06F, 0x1600 - 0x16FF | IPv6
+ *    Stream       | 0x070 - 0x07F, 0x1700 - 0x17FF | Stream
+ *    MeshCop      | 0x080 - 0x08F, 0x1800 - 0x18FF | Thread Mesh Commissioning
+ *    OpenThread   |                0x1900 - 0x19FF | OpenThread specific
+ *    Server       | 0x0A0 - 0x0AF                  | ALOC Service Server
+ *    Interface    | 0x100 - 0x1FF                  | Interface (e.g., UART)
+ *    PIB          | 0x400 - 0x4FF                  | 802.15.4 PIB
+ *    Counter      | 0x500 - 0x7FF                  | Counters (MAC, IP, etc).
+ *    RCP          | 0x800 - 0x8FF                  | RCP specific property
+ *    Nest         |                0x3BC0 - 0x3BFF | Nest (legacy)
+ *    Vendor       |                0x3C00 - 0x3FFF | Vendor specific
+ *    Debug        |                0x4000 - 0x43FF | Debug related
+ *    Experimental |          2,000,000 - 2,097,151 | Experimental use only
+ *
+ */
+enum
+{
+    /// Last Operation Status
+    /** Format: `i` - Read-only
+     *
+     * Describes the status of the last operation. Encoded as a packed
+     * unsigned integer (see `SPINEL_STATUS_*` for list of values).
+     *
+     * This property is emitted often to indicate the result status of
+     * pretty much any Host-to-NCP operation.
+     *
+     * It is emitted automatically at NCP startup with a value indicating
+     * the reset reason. It is also emitted asynchronously on an error (
+     * e.g., NCP running out of buffer).
+     *
+     */
+    SPINEL_PROP_LAST_STATUS = 0,
+
+    /// Protocol Version
+    /** Format: `ii` - Read-only
+     *
+     * Describes the protocol version information. This property contains
+     * two fields, each encoded as a packed unsigned integer:
+     *   `i`: Major Version Number
+     *   `i`: Minor Version Number
+     *
+     * The version number is defined by `SPINEL_PROTOCOL_VERSION_THREAD_MAJOR`
+     * and `SPINEL_PROTOCOL_VERSION_THREAD_MINOR`.
+     *
+     * This specification describes major version 4, minor version 3.
+     *
+     */
+    SPINEL_PROP_PROTOCOL_VERSION = 1,
+
+    /// NCP Version
+    /** Format: `U` - Read-only
+     *
+     * Contains a string which describes the firmware currently running on
+     * the NCP. Encoded as a zero-terminated UTF-8 string.
+     *
+     */
+    SPINEL_PROP_NCP_VERSION = 2,
+
+    /// NCP Network Protocol Type
+    /** Format: 'i' - Read-only
+     *
+     * This value identifies what the network protocol for this NCP.
+     * The valid protocol type values are defined by enumeration
+     * `SPINEL_PROTOCOL_TYPE_*`:
+     *
+     *   `SPINEL_PROTOCOL_TYPE_BOOTLOADER` = 0
+     *   `SPINEL_PROTOCOL_TYPE_ZIGBEE_IP`  = 2,
+     *   `SPINEL_PROTOCOL_TYPE_THREAD`     = 3,
+     *
+     * OpenThread NCP supports only `SPINEL_PROTOCOL_TYPE_THREAD`
+     *
+     */
+    SPINEL_PROP_INTERFACE_TYPE = 3,
+
+    /// NCP Vendor ID
+    /** Format: 'i` - Read-only
+     *
+     * Vendor ID. Zero for unknown.
+     *
+     */
+    SPINEL_PROP_VENDOR_ID = 4,
+
+    /// NCP Capability List
+    /** Format: 'A(i)` - Read-only
+     *
+     * Describes the supported capabilities of this NCP. Encoded as a list of
+     * packed unsigned integers.
+     *
+     * The capability values are specified by SPINEL_CAP_* enumeration.
+     *
+     */
+    SPINEL_PROP_CAPS = 5,
+
+    /// NCP Interface Count
+    /** Format: 'C` - Read-only
+     *
+     * Provides number of interfaces.
+     *
+     * Currently always reads as 1.
+     *
+     */
+    SPINEL_PROP_INTERFACE_COUNT = 6,
+
+    SPINEL_PROP_POWER_STATE = 7, ///< PowerState [C] (deprecated, use `MCU_POWER_STATE` instead).
+
+    /// NCP Hardware Address
+    /** Format: 'E` - Read-only
+     *
+     * The static EUI64 address of the device, used as a serial number.
+     *
+     */
+    SPINEL_PROP_HWADDR = 8,
+
+    SPINEL_PROP_LOCK          = 9,  ///< PropLock [b] (not supported)
+    SPINEL_PROP_HBO_MEM_MAX   = 10, ///< Max offload mem [S] (not supported)
+    SPINEL_PROP_HBO_BLOCK_MAX = 11, ///< Max offload block [S] (not supported)
+
+    /// Host Power State
+    /** Format: 'C`
+     *
+     * Describes the current power state of the host. This property is used
+     * by the host to inform the NCP when it has changed power states. The
+     * NCP can then use this state to determine which properties need
+     * asynchronous updates. Enumeration `spinel_host_power_state_t` defines
+     * the valid values (`SPINEL_HOST_POWER_STATE_*`):
+     *
+     *   `HOST_POWER_STATE_OFFLINE`: Host is physically powered off and
+     *   cannot be woken by the NCP. All asynchronous commands are
+     *   squelched.
+     *
+     *   `HOST_POWER_STATE_DEEP_SLEEP`: The host is in a low power state
+     *   where it can be woken by the NCP but will potentially require more
+     *   than two seconds to become fully responsive. The NCP MUST
+     *   avoid sending unnecessary property updates, such as child table
+     *   updates or non-critical messages on the debug stream. If the NCP
+     *   needs to wake the host for traffic, the NCP MUST first take
+     *   action to wake the host. Once the NCP signals to the host that it
+     *   should wake up, the NCP MUST wait for some activity from the
+     *   host (indicating that it is fully awake) before sending frames.
+     *
+     *   `HOST_POWER_STATE_RESERVED`:  This value MUST NOT be set by the host. If
+     *   received by the NCP, the NCP SHOULD consider this as a synonym
+     *   of `HOST_POWER_STATE_DEEP_SLEEP`.
+     *
+     *   `HOST_POWER_STATE_LOW_POWER`: The host is in a low power state
+     *   where it can be immediately woken by the NCP. The NCP SHOULD
+     *   avoid sending unnecessary property updates, such as child table
+     *   updates or non-critical messages on the debug stream.
+     *
+     *   `HOST_POWER_STATE_ONLINE`: The host is awake and responsive. No
+     *   special filtering is performed by the NCP on asynchronous updates.
+     *
+     *   All other values are RESERVED. They MUST NOT be set by the
+     *   host. If received by the NCP, the NCP SHOULD consider the value as
+     *   a synonym of `HOST_POWER_STATE_LOW_POWER`.
+     *
+     * After setting this power state, any further commands from the host to
+     * the NCP will cause `HOST_POWER_STATE` to automatically revert to
+     * `HOST_POWER_STATE_ONLINE`.
+     *
+     * When the host is entering a low-power state, it should wait for the
+     * response from the NCP acknowledging the command (with `CMD_VALUE_IS`).
+     * Once that acknowledgment is received the host may enter the low-power
+     * state.
+     *
+     * If the NCP has the `CAP_UNSOL_UPDATE_FILTER` capability, any unsolicited
+     * property updates masked by `PROP_UNSOL_UPDATE_FILTER` should be honored
+     * while the host indicates it is in a low-power state. After resuming to the
+     * `HOST_POWER_STATE_ONLINE` state, the value of `PROP_UNSOL_UPDATE_FILTER`
+     * MUST be unchanged from the value assigned prior to the host indicating
+     * it was entering a low-power state.
+     *
+     */
+    SPINEL_PROP_HOST_POWER_STATE = 12,
+
+    /// NCP's MCU Power State
+    /** Format: 'C`
+     *  Required capability: CAP_MCU_POWER_SAVE
+     *
+     * This property specifies the desired power state of NCP's micro-controller
+     * (MCU) when the underlying platform's operating system enters idle mode (i.e.,
+     * all active tasks/events are processed and the MCU can potentially enter a
+     * energy-saving power state).
+     *
+     * The power state primarily determines how the host should interact with the NCP
+     * and whether the host needs an external trigger (a "poke") to NCP before it can
+     * communicate with the NCP or not. After a reset, the MCU power state MUST be
+     * SPINEL_MCU_POWER_STATE_ON.
+     *
+     * Enumeration `spinel_mcu_power_state_t` defines the valid values
+     * (`SPINEL_MCU_POWER_STATE_*` constants):
+     *
+     *   `SPINEL_MCU_POWER_STATE_ON`: NCP's MCU stays on and active all the time.
+     *   When the NCP's desired power state is set to this value, host can send
+     *   messages to NCP without requiring any "poke" or external triggers. MCU is
+     *   expected to stay on and active. Note that the `ON` power state only
+     *   determines the MCU's power mode and is not related to radio's state.
+     *
+     *   `SPINEL_MCU_POWER_STATE_LOW_POWER`: NCP's MCU can enter low-power
+     *   (energy-saving) state. When the NCP's desired power state is set to
+     *   `LOW_POWER`, host is expected to "poke" the NCP (e.g., an external trigger
+     *   like an interrupt) before it can communicate with the NCP (send a message
+     *   to the NCP). The "poke" mechanism is determined by the platform code (based
+     *   on NCP's interface to the host).
+     *   While power state is set to `LOW_POWER`, NCP can still (at any time) send
+     *   messages to host. Note that receiving a message from the NCP does NOT
+     *   indicate that the NCP's power state has changed, i.e., host is expected to
+     *   continue to "poke" NCP when it wants to talk to the NCP until the power
+     *   state is explicitly changed (by setting this property to `ON`).
+     *   Note that the `LOW_POWER` power state only determines the MCU's power mode
+     *   and is not related to radio's state.
+     *
+     *   `SPINEL_MCU_POWER_STATE_OFF`: NCP is fully powered off.
+     *   An NCP hardware reset (via a RESET pin) is required to bring the NCP back
+     *   to `SPINEL_MCU_POWER_STATE_ON`. RAM is not retained after reset.
+     *
+     */
+    SPINEL_PROP_MCU_POWER_STATE = 13,
+
+    SPINEL_PROP_BASE_EXT__BEGIN = 0x1000,
+
+    /// GPIO Configuration
+    /** Format: `A(CCU)`
+     *  Type: Read-Only (Optionally Read-write using `CMD_PROP_VALUE_INSERT`)
+     *
+     * An array of structures which contain the following fields:
+     *
+     * *   `C`: GPIO Number
+     * *   `C`: GPIO Configuration Flags
+     * *   `U`: Human-readable GPIO name
+     *
+     * GPIOs which do not have a corresponding entry are not supported.
+     *
+     * The configuration parameter contains the configuration flags for the
+     * GPIO:
+     *
+     *       0   1   2   3   4   5   6   7
+     *     +---+---+---+---+---+---+---+---+
+     *     |DIR|PUP|PDN|TRIGGER|  RESERVED |
+     *     +---+---+---+---+---+---+---+---+
+     *             |O/D|
+     *             +---+
+     *
+     * *   `DIR`: Pin direction. Clear (0) for input, set (1) for output.
+     * *   `PUP`: Pull-up enabled flag.
+     * *   `PDN`/`O/D`: Flag meaning depends on pin direction:
+     *     *   Input: Pull-down enabled.
+     *     *   Output: Output is an open-drain.
+     * *   `TRIGGER`: Enumeration describing how pin changes generate
+     *     asynchronous notification commands (TBD) from the NCP to the host.
+     *     *   0: Feature disabled for this pin
+     *     *   1: Trigger on falling edge
+     *     *   2: Trigger on rising edge
+     *     *   3: Trigger on level change
+     * *   `RESERVED`: Bits reserved for future use. Always cleared to zero
+     *     and ignored when read.
+     *
+     * As an optional feature, the configuration of individual pins may be
+     * modified using the `CMD_PROP_VALUE_INSERT` command. Only the GPIO
+     * number and flags fields MUST be present, the GPIO name (if present)
+     * would be ignored. This command can only be used to modify the
+     * configuration of GPIOs which are already exposed---it cannot be used
+     * by the host to add additional GPIOs.
+     */
+    SPINEL_PROP_GPIO_CONFIG = SPINEL_PROP_BASE_EXT__BEGIN + 0,
+
+    /// GPIO State Bitmask
+    /** Format: `D`
+     *  Type: Read-Write
+     *
+     * Contains a bit field identifying the state of the GPIOs. The length of
+     * the data associated with these properties depends on the number of
+     * GPIOs. If you have 10 GPIOs, you'd have two bytes. GPIOs are numbered
+     * from most significant bit to least significant bit, so 0x80 is GPIO 0,
+     * 0x40 is GPIO 1, etc.
+     *
+     * For GPIOs configured as inputs:
+     *
+     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit describes the
+     *     logic level read from the pin.
+     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit is ignored
+     *     for these pins.
+     *
+     * For GPIOs configured as outputs:
+     *
+     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit is
+     *     implementation specific.
+     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit determines
+     *     the new logic level of the output. If this pin is configured as an
+     *     open-drain, setting the associated bit to 1 will cause the pin to
+     *     enter a Hi-Z state.
+     *
+     * For GPIOs which are not specified in `PROP_GPIO_CONFIG`:
+     *
+     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit is
+     *     implementation specific.
+     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit MUST be
+     *     ignored by the NCP.
+     *
+     * When writing, unspecified bits are assumed to be zero.
+     */
+    SPINEL_PROP_GPIO_STATE = SPINEL_PROP_BASE_EXT__BEGIN + 2,
+
+    /// GPIO State Set-Only Bitmask
+    /** Format: `D`
+     *  Type: Write-Only
+     *
+     * Allows for the state of various output GPIOs to be set without affecting
+     * other GPIO states. Contains a bit field identifying the output GPIOs that
+     * should have their state set to 1.
+     *
+     * When writing, unspecified bits are assumed to be zero. The value of
+     * any bits for GPIOs which are not specified in `PROP_GPIO_CONFIG` MUST
+     * be ignored.
+     */
+    SPINEL_PROP_GPIO_STATE_SET = SPINEL_PROP_BASE_EXT__BEGIN + 3,
+
+    /// GPIO State Clear-Only Bitmask
+    /** Format: `D`
+     *  Type: Write-Only
+     *
+     * Allows for the state of various output GPIOs to be cleared without affecting
+     * other GPIO states. Contains a bit field identifying the output GPIOs that
+     * should have their state cleared to 0.
+     *
+     * When writing, unspecified bits are assumed to be zero. The value of
+     * any bits for GPIOs which are not specified in `PROP_GPIO_CONFIG` MUST
+     * be ignored.
+     */
+    SPINEL_PROP_GPIO_STATE_CLEAR = SPINEL_PROP_BASE_EXT__BEGIN + 4,
+
+    /// 32-bit random number from TRNG, ready-to-use.
+    SPINEL_PROP_TRNG_32 = SPINEL_PROP_BASE_EXT__BEGIN + 5,
+
+    /// 16 random bytes from TRNG, ready-to-use.
+    SPINEL_PROP_TRNG_128 = SPINEL_PROP_BASE_EXT__BEGIN + 6,
+
+    /// Raw samples from TRNG entropy source representing 32 bits of entropy.
+    SPINEL_PROP_TRNG_RAW_32 = SPINEL_PROP_BASE_EXT__BEGIN + 7,
+
+    /// NCP Unsolicited update filter
+    /** Format: `A(I)`
+     *  Type: Read-Write (optional Insert-Remove)
+     *  Required capability: `CAP_UNSOL_UPDATE_FILTER`
+     *
+     * Contains a list of properties which are excluded from generating
+     * unsolicited value updates. This property is empty after reset.
+     * In other words, the host may opt-out of unsolicited property updates
+     * for a specific property by adding that property id to this list.
+     * Hosts SHOULD NOT add properties to this list which are not
+     * present in `PROP_UNSOL_UPDATE_LIST`. If such properties are added,
+     * the NCP ignores the unsupported properties.
+     *
+     */
+    SPINEL_PROP_UNSOL_UPDATE_FILTER = SPINEL_PROP_BASE_EXT__BEGIN + 8,
+
+    /// List of properties capable of generating unsolicited value update.
+    /** Format: `A(I)`
+     *  Type: Read-Only
+     *  Required capability: `CAP_UNSOL_UPDATE_FILTER`
+     *
+     * Contains a list of properties which are capable of generating
+     * unsolicited value updates. This list can be used when populating
+     * `PROP_UNSOL_UPDATE_FILTER` to disable all unsolicited property
+     * updates.
+     *
+     * This property is intended to effectively behave as a constant
+     * for a given NCP firmware.
+     */
+    SPINEL_PROP_UNSOL_UPDATE_LIST = SPINEL_PROP_BASE_EXT__BEGIN + 9,
+
+    SPINEL_PROP_BASE_EXT__END = 0x1100,
+
+    SPINEL_PROP_PHY__BEGIN         = 0x20,
+    SPINEL_PROP_PHY_ENABLED        = SPINEL_PROP_PHY__BEGIN + 0, ///< [b]
+    SPINEL_PROP_PHY_CHAN           = SPINEL_PROP_PHY__BEGIN + 1, ///< [C]
+    SPINEL_PROP_PHY_CHAN_SUPPORTED = SPINEL_PROP_PHY__BEGIN + 2, ///< [A(C)]
+    SPINEL_PROP_PHY_FREQ           = SPINEL_PROP_PHY__BEGIN + 3, ///< kHz [L]
+    SPINEL_PROP_PHY_CCA_THRESHOLD  = SPINEL_PROP_PHY__BEGIN + 4, ///< dBm [c]
+    SPINEL_PROP_PHY_TX_POWER       = SPINEL_PROP_PHY__BEGIN + 5, ///< [c]
+    SPINEL_PROP_PHY_RSSI           = SPINEL_PROP_PHY__BEGIN + 6, ///< dBm [c]
+    SPINEL_PROP_PHY_RX_SENSITIVITY = SPINEL_PROP_PHY__BEGIN + 7, ///< dBm [c]
+    SPINEL_PROP_PHY_PCAP_ENABLED   = SPINEL_PROP_PHY__BEGIN + 8, ///< [b]
+    SPINEL_PROP_PHY_CHAN_PREFERRED = SPINEL_PROP_PHY__BEGIN + 9, ///< [A(C)]
+    SPINEL_PROP_PHY__END           = 0x30,
+
+    SPINEL_PROP_PHY_EXT__BEGIN = 0x1200,
+
+    /// Signal Jamming Detection Enable
+    /** Format: `b`
+     *
+     * Indicates if jamming detection is enabled or disabled. Set to true
+     * to enable jamming detection.
+     */
+    SPINEL_PROP_JAM_DETECT_ENABLE = SPINEL_PROP_PHY_EXT__BEGIN + 0,
+
+    /// Signal Jamming Detected Indicator
+    /** Format: `b` (Read-Only)
+     *
+     * Set to true if radio jamming is detected. Set to false otherwise.
+     *
+     * When jamming detection is enabled, changes to the value of this
+     * property are emitted asynchronously via `CMD_PROP_VALUE_IS`.
+     */
+    SPINEL_PROP_JAM_DETECTED = SPINEL_PROP_PHY_EXT__BEGIN + 1,
+
+    /// Jamming detection RSSI threshold
+    /** Format: `c`
+     *  Units: dBm
+     *
+     * This parameter describes the threshold RSSI level (measured in
+     * dBm) above which the jamming detection will consider the
+     * channel blocked.
+     */
+    SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD = SPINEL_PROP_PHY_EXT__BEGIN + 2,
+
+    /// Jamming detection window size
+    /** Format: `C`
+     *  Units: Seconds (1-63)
+     *
+     * This parameter describes the window period for signal jamming
+     * detection.
+     */
+    SPINEL_PROP_JAM_DETECT_WINDOW = SPINEL_PROP_PHY_EXT__BEGIN + 3,
+
+    /// Jamming detection busy period
+    /** Format: `C`
+     *  Units: Seconds (1-63)
+     *
+     * This parameter describes the number of aggregate seconds within
+     * the detection window where the RSSI must be above
+     * `PROP_JAM_DETECT_RSSI_THRESHOLD` to trigger detection.
+     *
+     * The behavior of the jamming detection feature when `PROP_JAM_DETECT_BUSY`
+     * is larger than `PROP_JAM_DETECT_WINDOW` is undefined.
+     */
+    SPINEL_PROP_JAM_DETECT_BUSY = SPINEL_PROP_PHY_EXT__BEGIN + 4,
+
+    /// Jamming detection history bitmap (for debugging)
+    /** Format: `X` (read-only)
+     *
+     * This value provides information about current state of jamming detection
+     * module for monitoring/debugging purpose. It returns a 64-bit value where
+     * each bit corresponds to one second interval starting with bit 0 for the
+     * most recent interval and bit 63 for the oldest intervals (63 sec earlier).
+     * The bit is set to 1 if the jamming detection module observed/detected
+     * high signal level during the corresponding one second interval.
+     *
+     */
+    SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP = SPINEL_PROP_PHY_EXT__BEGIN + 5,
+
+    /// Channel monitoring sample interval
+    /** Format: `L` (read-only)
+     *  Units: Milliseconds
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
+     *
+     * If channel monitoring is enabled and active, every sample interval, a
+     * zero-duration Energy Scan is performed, collecting a single RSSI sample
+     * per channel. The RSSI samples are compared with a pre-specified RSSI
+     * threshold.
+     *
+     */
+    SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL = SPINEL_PROP_PHY_EXT__BEGIN + 6,
+
+    /// Channel monitoring RSSI threshold
+    /** Format: `c` (read-only)
+     *  Units: dBm
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
+     *
+     * This value specifies the threshold used by channel monitoring module.
+     * Channel monitoring maintains the average rate of RSSI samples that
+     * are above the threshold within (approximately) a pre-specified number
+     * of samples (sample window).
+     *
+     */
+    SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD = SPINEL_PROP_PHY_EXT__BEGIN + 7,
+
+    /// Channel monitoring sample window
+    /** Format: `L` (read-only)
+     *  Units: Number of samples
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
+     *
+     * The averaging sample window length (in units of number of channel
+     * samples) used by channel monitoring module. Channel monitoring will
+     * sample all channels every sample interval. It maintains the average rate
+     * of RSSI samples that are above the RSSI threshold within (approximately)
+     * the sample window.
+     *
+     */
+    SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW = SPINEL_PROP_PHY_EXT__BEGIN + 8,
+
+    /// Channel monitoring sample count
+    /** Format: `L` (read-only)
+     *  Units: Number of samples
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
+     *
+     * Total number of RSSI samples (per channel) taken by the channel
+     * monitoring module since its start (since Thread network interface
+     * was enabled).
+     *
+     */
+    SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT = SPINEL_PROP_PHY_EXT__BEGIN + 9,
+
+    /// Channel monitoring channel occupancy
+    /** Format: `A(t(CU))` (read-only)
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
+     *
+     * Data per item is:
+     *
+     *  `C`: Channel
+     *  `U`: Channel occupancy indicator
+     *
+     * The channel occupancy value represents the average rate/percentage of
+     * RSSI samples that were above RSSI threshold ("bad" RSSI samples) within
+     * (approximately) sample window latest RSSI samples.
+     *
+     * Max value of `0xffff` indicates all RSSI samples were above RSSI
+     * threshold (i.e. 100% of samples were "bad").
+     *
+     */
+    SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_OCCUPANCY = SPINEL_PROP_PHY_EXT__BEGIN + 10,
+
+    /// Radio caps
+    /** Format: `i` (read-only)
+     *
+     * Data per item is:
+     *
+     *  `i`: Radio Capabilities.
+     *
+     */
+    SPINEL_PROP_RADIO_CAPS = SPINEL_PROP_PHY_EXT__BEGIN + 11,
+
+    /// All coex metrics related counters.
+    /** Format: t(LLLLLLLL)t(LLLLLLLLL)bL  (Read-only)
+     *
+     * Required capability: SPINEL_CAP_RADIO_COEX
+     *
+     * The contents include two structures and two common variables, first structure corresponds to
+     * all transmit related coex counters, second structure provides the receive related counters.
+     *
+     * The transmit structure includes:
+     *   'L': NumTxRequest                       (The number of tx requests).
+     *   'L': NumTxGrantImmediate                (The number of tx requests while grant was active).
+     *   'L': NumTxGrantWait                     (The number of tx requests while grant was inactive).
+     *   'L': NumTxGrantWaitActivated            (The number of tx requests while grant was inactive that were
+     *                                            ultimately granted).
+     *   'L': NumTxGrantWaitTimeout              (The number of tx requests while grant was inactive that timed out).
+     *   'L': NumTxGrantDeactivatedDuringRequest (The number of tx requests that were in progress when grant was
+     *                                            deactivated).
+     *   'L': NumTxDelayedGrant                  (The number of tx requests that were not granted within 50us).
+     *   'L': AvgTxRequestToGrantTime            (The average time in usec from tx request to grant).
+     *
+     * The receive structure includes:
+     *   'L': NumRxRequest                       (The number of rx requests).
+     *   'L': NumRxGrantImmediate                (The number of rx requests while grant was active).
+     *   'L': NumRxGrantWait                     (The number of rx requests while grant was inactive).
+     *   'L': NumRxGrantWaitActivated            (The number of rx requests while grant was inactive that were
+     *                                            ultimately granted).
+     *   'L': NumRxGrantWaitTimeout              (The number of rx requests while grant was inactive that timed out).
+     *   'L': NumRxGrantDeactivatedDuringRequest (The number of rx requests that were in progress when grant was
+     *                                            deactivated).
+     *   'L': NumRxDelayedGrant                  (The number of rx requests that were not granted within 50us).
+     *   'L': AvgRxRequestToGrantTime            (The average time in usec from rx request to grant).
+     *   'L': NumRxGrantNone                     (The number of rx requests that completed without receiving grant).
+     *
+     * Two common variables:
+     *   'b': Stopped        (Stats collection stopped due to saturation).
+     *   'L': NumGrantGlitch (The number of of grant glitches).
+     */
+    SPINEL_PROP_RADIO_COEX_METRICS = SPINEL_PROP_PHY_EXT__BEGIN + 12,
+
+    /// Radio Coex Enable
+    /** Format: `b`
+     *
+     * Required capability: SPINEL_CAP_RADIO_COEX
+     *
+     * Indicates if radio coex is enabled or disabled. Set to true to enable radio coex.
+     */
+    SPINEL_PROP_RADIO_COEX_ENABLE = SPINEL_PROP_PHY_EXT__BEGIN + 13,
+
+    SPINEL_PROP_PHY_EXT__END = 0x1300,
+
+    SPINEL_PROP_MAC__BEGIN = 0x30,
+
+    /// MAC Scan State
+    /** Format: `C`
+     *
+     * Possible values are from enumeration `spinel_scan_state_t`.
+     *
+     *   SCAN_STATE_IDLE
+     *   SCAN_STATE_BEACON
+     *   SCAN_STATE_ENERGY
+     *   SCAN_STATE_DISCOVER
+     *
+     * Set to `SCAN_STATE_BEACON` to start an active scan.
+     * Beacons will be emitted from `PROP_MAC_SCAN_BEACON`.
+     *
+     * Set to `SCAN_STATE_ENERGY` to start an energy scan.
+     * Channel energy result will be reported by emissions
+     * of `PROP_MAC_ENERGY_SCAN_RESULT` (per channel).
+     *
+     * Set to `SCAN_STATE_DISOVER` to start a Thread MLE discovery
+     * scan operation. Discovery scan result will be emitted from
+     * `PROP_MAC_SCAN_BEACON`.
+     *
+     * Value switches to `SCAN_STATE_IDLE` when scan is complete.
+     *
+     */
+    SPINEL_PROP_MAC_SCAN_STATE = SPINEL_PROP_MAC__BEGIN + 0,
+
+    /// MAC Scan Channel Mask
+    /** Format: `A(C)`
+     *
+     * List of channels to scan.
+     *
+     */
+    SPINEL_PROP_MAC_SCAN_MASK = SPINEL_PROP_MAC__BEGIN + 1,
+
+    /// MAC Scan Channel Period
+    /** Format: `S`
+     *  Unit: milliseconds per channel
+     *
+     */
+    SPINEL_PROP_MAC_SCAN_PERIOD = SPINEL_PROP_MAC__BEGIN + 2,
+
+    /// MAC Scan Beacon
+    /** Format `Cct(ESSc)t(iCUdd)` - Asynchronous event only
+     *
+     * Scan beacons have two embedded structures which contain
+     * information about the MAC layer and the NET layer. Their
+     * format depends on the MAC and NET layer currently in use.
+     * The format below is for an 802.15.4 MAC with Thread:
+     *
+     *  `C`: Channel
+     *  `c`: RSSI of the beacon
+     *  `t`: MAC layer properties (802.15.4 layer)
+     *    `E`: Long address
+     *    `S`: Short address
+     *    `S`: PAN-ID
+     *    `c`: LQI
+     *  NET layer properties
+     *    `i`: Protocol Number (SPINEL_PROTOCOL_TYPE_* values)
+     *    `C`: Flags (SPINEL_BEACON_THREAD_FLAG_* values)
+     *    `U`: Network Name
+     *    `d`: XPANID
+     *    `d`: Steering data
+     *
+     * Extra parameters may be added to each of the structures
+     * in the future, so care should be taken to read the length
+     * that prepends each structure.
+     *
+     */
+    SPINEL_PROP_MAC_SCAN_BEACON = SPINEL_PROP_MAC__BEGIN + 3,
+
+    /// MAC Long Address
+    /** Format: `E`
+     *
+     * The 802.15.4 long address of this node.
+     *
+     */
+    SPINEL_PROP_MAC_15_4_LADDR = SPINEL_PROP_MAC__BEGIN + 4,
+
+    /// MAC Short Address
+    /** Format: `S`
+     *
+     * The 802.15.4 short address of this node.
+     *
+     */
+    SPINEL_PROP_MAC_15_4_SADDR = SPINEL_PROP_MAC__BEGIN + 5,
+
+    /// MAC PAN ID
+    /** Format: `S`
+     *
+     * The 802.15.4 PANID this node is associated with.
+     *
+     */
+    SPINEL_PROP_MAC_15_4_PANID = SPINEL_PROP_MAC__BEGIN + 6,
+
+    /// MAC Stream Raw Enabled
+    /** Format: `b`
+     *
+     * Set to true to enable raw MAC frames to be emitted from
+     * `PROP_STREAM_RAW`.
+     *
+     */
+    SPINEL_PROP_MAC_RAW_STREAM_ENABLED = SPINEL_PROP_MAC__BEGIN + 7,
+
+    /// MAC Promiscuous Mode
+    /** Format: `C`
+     *
+     * Possible values are from enumeration
+     * `SPINEL_MAC_PROMISCUOUS_MODE_*`:
+     *
+     *   `SPINEL_MAC_PROMISCUOUS_MODE_OFF`
+     *        Normal MAC filtering is in place.
+     *
+     *   `SPINEL_MAC_PROMISCUOUS_MODE_NETWORK`
+     *        All MAC packets matching network are passed up
+     *        the stack.
+     *
+     *   `SPINEL_MAC_PROMISCUOUS_MODE_FULL`
+     *        All decoded MAC packets are passed up the stack.
+     *
+     */
+    SPINEL_PROP_MAC_PROMISCUOUS_MODE = SPINEL_PROP_MAC__BEGIN + 8,
+
+    /// MAC Energy Scan Result
+    /** Format: `Cc` - Asynchronous event only
+     *
+     * This property is emitted during energy scan operation
+     * per scanned channel with following format:
+     *
+     *   `C`: Channel
+     *   `c`: RSSI (in dBm)
+     *
+     */
+    SPINEL_PROP_MAC_ENERGY_SCAN_RESULT = SPINEL_PROP_MAC__BEGIN + 9,
+
+    /// MAC Data Poll Period
+    /** Format: `L`
+     *  Unit: millisecond
+     * The (user-specified) data poll (802.15.4 MAC Data Request) period
+     * in milliseconds. Value zero means there is no user-specified
+     * poll period, and the network stack determines the maximum period
+     * based on the MLE Child Timeout.
+     *
+     * If the value is non-zero, it specifies the maximum period between
+     * data poll transmissions. Note that the network stack may send data
+     * request transmissions more frequently when expecting a control-message
+     * (e.g., when waiting for an MLE Child ID Response).
+     *
+     */
+    SPINEL_PROP_MAC_DATA_POLL_PERIOD = SPINEL_PROP_MAC__BEGIN + 10,
+
+    SPINEL_PROP_MAC__END = 0x40,
+
+    SPINEL_PROP_MAC_EXT__BEGIN = 0x1300,
+
+    /// MAC Whitelist
+    /** Format: `A(t(Ec))`
+     * Required capability: `CAP_MAC_WHITELIST`
+     *
+     * Structure Parameters:
+     *
+     *  `E`: EUI64 address of node
+     *  `c`: Optional RSSI-override value. The value 127 indicates
+     *       that the RSSI-override feature is not enabled for this
+     *       address. If this value is omitted when setting or
+     *       inserting, it is assumed to be 127. This parameter is
+     *       ignored when removing.
+     */
+    SPINEL_PROP_MAC_WHITELIST = SPINEL_PROP_MAC_EXT__BEGIN + 0,
+
+    /// MAC Whitelist Enabled Flag
+    /** Format: `b`
+     * Required capability: `CAP_MAC_WHITELIST`
+     *
+     */
+    SPINEL_PROP_MAC_WHITELIST_ENABLED = SPINEL_PROP_MAC_EXT__BEGIN + 1,
+
+    /// MAC Extended Address
+    /** Format: `E`
+     *
+     *  Specified by Thread. Randomly-chosen, but non-volatile EUI-64.
+     */
+    SPINEL_PROP_MAC_EXTENDED_ADDR = SPINEL_PROP_MAC_EXT__BEGIN + 2,
+
+    /// MAC Source Match Enabled Flag
+    /** Format: `b`
+     * Required Capability: SPINEL_CAP_MAC_RAW or SPINEL_CAP_CONFIG_RADIO
+     *
+     * Set to true to enable radio source matching or false to disable it.
+     * The source match functionality is used by radios when generating
+     * ACKs. The short and extended address lists are used for setting
+     * the Frame Pending bit in the ACKs.
+     *
+     */
+    SPINEL_PROP_MAC_SRC_MATCH_ENABLED = SPINEL_PROP_MAC_EXT__BEGIN + 3,
+
+    /// MAC Source Match Short Address List
+    /** Format: `A(S)`
+     * Required Capability: SPINEL_CAP_MAC_RAW or SPINEL_CAP_CONFIG_RADIO
+     *
+     */
+    SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES = SPINEL_PROP_MAC_EXT__BEGIN + 4,
+
+    /// MAC Source Match Extended Address List
+    /** Format: `A(E)`
+     *  Required Capability: SPINEL_CAP_MAC_RAW or SPINEL_CAP_CONFIG_RADIO
+     *
+     */
+    SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES = SPINEL_PROP_MAC_EXT__BEGIN + 5,
+
+    /// MAC Blacklist
+    /** Format: `A(t(E))`
+     * Required capability: `CAP_MAC_WHITELIST`
+     *
+     * Structure Parameters:
+     *
+     *  `E`: EUI64 address of node
+     *
+     */
+    SPINEL_PROP_MAC_BLACKLIST = SPINEL_PROP_MAC_EXT__BEGIN + 6,
+
+    /// MAC Blacklist Enabled Flag
+    /** Format: `b`
+     *  Required capability: `CAP_MAC_WHITELIST`
+     */
+    SPINEL_PROP_MAC_BLACKLIST_ENABLED = SPINEL_PROP_MAC_EXT__BEGIN + 7,
+
+    /// MAC Received Signal Strength Filter
+    /** Format: `A(t(Ec))`
+     * Required capability: `CAP_MAC_WHITELIST`
+     *
+     * Structure Parameters:
+     *
+     * * `E`: Optional EUI64 address of node. Set default RSS if not included.
+     * * `c`: Fixed RSS. 127 means not set.
+     */
+    SPINEL_PROP_MAC_FIXED_RSS = SPINEL_PROP_MAC_EXT__BEGIN + 8,
+
+    /// The CCA failure rate
+    /** Format: `S`
+     *
+     * This property provides the current CCA (Clear Channel Assessment) failure rate.
+     *
+     * Maximum value `0xffff` corresponding to 100% failure rate.
+     *
+     */
+    SPINEL_PROP_MAC_CCA_FAILURE_RATE = SPINEL_PROP_MAC_EXT__BEGIN + 9,
+
+    /// MAC Max direct retry number
+    /** Format: `C`
+     *
+     * The maximum (user-specified) number of direct frame transmission retries.
+     *
+     */
+    SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT = SPINEL_PROP_MAC_EXT__BEGIN + 10,
+
+    /// MAC Max indirect retry number
+    /** Format: `C`
+     * Required capability: `SPINEL_CAP_CONFIG_FTD`
+     *
+     * The maximum (user-specified) number of indirect frame transmission retries.
+     *
+     */
+    SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT = SPINEL_PROP_MAC_EXT__BEGIN + 11,
+
+    SPINEL_PROP_MAC_EXT__END = 0x1400,
+
+    SPINEL_PROP_NET__BEGIN = 0x40,
+
+    /// Network Is Saved (Is Commissioned)
+    /** Format: `b` - Read only
+     *
+     * Returns true if there is a network state stored/saved.
+     *
+     */
+    SPINEL_PROP_NET_SAVED = SPINEL_PROP_NET__BEGIN + 0,
+
+    /// Network Interface Status
+    /** Format `b` - Read-write
+     *
+     * Network interface up/down status. Write true to bring
+     * interface up and false to bring interface down.
+     *
+     */
+    SPINEL_PROP_NET_IF_UP = SPINEL_PROP_NET__BEGIN + 1,
+
+    /// Thread Stack Operational Status
+    /** Format `b` - Read-write
+     *
+     * Thread stack operational status. Write true to start
+     * Thread stack and false to stop it.
+     *
+     */
+    SPINEL_PROP_NET_STACK_UP = SPINEL_PROP_NET__BEGIN + 2,
+
+    /// Thread Device Role
+    /** Format `C` - Read-write
+     *
+     * Possible values are from enumeration `spinel_net_role_t`
+     *
+     *  SPINEL_NET_ROLE_DETACHED = 0,
+     *  SPINEL_NET_ROLE_CHILD    = 1,
+     *  SPINEL_NET_ROLE_ROUTER   = 2,
+     *  SPINEL_NET_ROLE_LEADER   = 3,
+     *
+     */
+    SPINEL_PROP_NET_ROLE = SPINEL_PROP_NET__BEGIN + 3,
+
+    /// Thread Network Name
+    /** Format `U` - Read-write
+     *
+     */
+    SPINEL_PROP_NET_NETWORK_NAME = SPINEL_PROP_NET__BEGIN + 4,
+
+    /// Thread Network Extended PAN ID
+    /** Format `D` - Read-write
+     *
+     */
+    SPINEL_PROP_NET_XPANID = SPINEL_PROP_NET__BEGIN + 5,
+
+    /// Thread Network Master Key
+    /** Format `D` - Read-write
+     *
+     */
+    SPINEL_PROP_NET_MASTER_KEY = SPINEL_PROP_NET__BEGIN + 6,
+
+    /// Thread Network Key Sequence Counter
+    /** Format `L` - Read-write
+     *
+     */
+    SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER = SPINEL_PROP_NET__BEGIN + 7,
+
+    /// Thread Network Partition Id
+    /** Format `L` - Read-write
+     *
+     * The partition ID of the partition that this node is a
+     * member of.
+     *
+     */
+    SPINEL_PROP_NET_PARTITION_ID = SPINEL_PROP_NET__BEGIN + 8,
+
+    /// Require Join Existing
+    /** Format: `b`
+     *  Default Value: `false`
+     *
+     * This flag is typically used for nodes that are associating with an
+     * existing network for the first time. If this is set to `true` before
+     * `PROP_NET_STACK_UP` is set to `true`, the
+     * creation of a new partition at association is prevented. If the node
+     * cannot associate with an existing partition, `PROP_LAST_STATUS` will
+     * emit a status that indicates why the association failed and
+     * `PROP_NET_STACK_UP` will automatically revert to `false`.
+     *
+     * Once associated with an existing partition, this flag automatically
+     * reverts to `false`.
+     *
+     * The behavior of this property being set to `true` when
+     * `PROP_NET_STACK_UP` is already set to `true` is undefined.
+     *
+     */
+    SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING = SPINEL_PROP_NET__BEGIN + 9,
+
+    /// Thread Network Key Switch Guard Time
+    /** Format `L` - Read-write
+     *
+     */
+    SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME = SPINEL_PROP_NET__BEGIN + 10,
+
+    /// Thread Network PSKc
+    /** Format `D` - Read-write
+     *
+     */
+    SPINEL_PROP_NET_PSKC = SPINEL_PROP_NET__BEGIN + 11,
+
+    SPINEL_PROP_NET__END = 0x50,
+
+    SPINEL_PROP_NET_EXT__BEGIN = 0x1400,
+    SPINEL_PROP_NET_EXT__END   = 0x1500,
+
+    SPINEL_PROP_THREAD__BEGIN = 0x50,
+
+    /// Thread Leader IPv6 Address
+    /** Format `6` - Read only
+     *
+     */
+    SPINEL_PROP_THREAD_LEADER_ADDR = SPINEL_PROP_THREAD__BEGIN + 0,
+
+    /// Thread Parent Info
+    /** Format: `ESLccCC` - Read only
+     *
+     *  `E`: Extended address
+     *  `S`: RLOC16
+     *  `L`: Age (seconds since last heard from)
+     *  `c`: Average RSS (in dBm)
+     *  `c`: Last RSSI (in dBm)
+     *  `C`: Link Quality In
+     *  `C`: Link Quality Out
+     *
+     */
+    SPINEL_PROP_THREAD_PARENT = SPINEL_PROP_THREAD__BEGIN + 1,
+
+    /// Thread Child Table
+    /** Format: [A(t(ESLLCCcCc)] - Read only
+     *
+     * Data per item is:
+     *
+     *  `E`: Extended address
+     *  `S`: RLOC16
+     *  `L`: Timeout (in seconds)
+     *  `L`: Age (in seconds)
+     *  `L`: Network Data version
+     *  `C`: Link Quality In
+     *  `c`: Average RSS (in dBm)
+     *  `C`: Mode (bit-flags)
+     *  `c`: Last RSSI (in dBm)
+     *
+     */
+    SPINEL_PROP_THREAD_CHILD_TABLE = SPINEL_PROP_THREAD__BEGIN + 2,
+
+    /// Thread Leader Router Id
+    /** Format `C` - Read only
+     *
+     * The router-id of the current leader.
+     *
+     */
+    SPINEL_PROP_THREAD_LEADER_RID = SPINEL_PROP_THREAD__BEGIN + 3,
+
+    /// Thread Leader Weight
+    /** Format `C` - Read only
+     *
+     * The leader weight of the current leader.
+     *
+     */
+    SPINEL_PROP_THREAD_LEADER_WEIGHT = SPINEL_PROP_THREAD__BEGIN + 4,
+
+    /// Thread Local Leader Weight
+    /** Format `C` - Read only
+     *
+     * The leader weight of this node.
+     *
+     */
+    SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT = SPINEL_PROP_THREAD__BEGIN + 5,
+
+    /// Thread Local Network Data
+    /** Format `D` - Read only
+     *
+     */
+    SPINEL_PROP_THREAD_NETWORK_DATA = SPINEL_PROP_THREAD__BEGIN + 6,
+
+    /// Thread Local Network Data Version
+    /** Format `C` - Read only
+     *
+     */
+    SPINEL_PROP_THREAD_NETWORK_DATA_VERSION = SPINEL_PROP_THREAD__BEGIN + 7,
+
+    /// Thread Local Stable Network Data
+    /** Format `D` - Read only
+     *
+     */
+    SPINEL_PROP_THREAD_STABLE_NETWORK_DATA = SPINEL_PROP_THREAD__BEGIN + 8,
+
+    /// Thread Local Stable Network Data Version
+    /** Format `C` - Read only
+     *
+     */
+    SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION = SPINEL_PROP_THREAD__BEGIN + 9,
+
+    /// On-Mesh Prefixes
+    /** Format: `A(t(6CbCbS))`
+     *
+     * Data per item is:
+     *
+     *  `6`: IPv6 Prefix
+     *  `C`: Prefix length in bits
+     *  `b`: Stable flag
+     *  `C`: TLV flags
+     *  `b`: "Is defined locally" flag. Set if this network was locally
+     *       defined. Assumed to be true for set, insert and replace. Clear if
+     *       the on mesh network was defined by another node.
+     *  `S`: The RLOC16 of the device that registered this on-mesh prefix entry.
+     *       This value is not used and ignored when adding an on-mesh prefix.
+     *
+     */
+    SPINEL_PROP_THREAD_ON_MESH_NETS = SPINEL_PROP_THREAD__BEGIN + 10,
+
+    /// Off-mesh routes
+    /** Format: [A(t(6CbCbb))]
+     *
+     * Data per item is:
+     *
+     *  `6`: Route Prefix
+     *  `C`: Prefix length in bits
+     *  `b`: Stable flag
+     *  `C`: Route preference flags
+     *  `b`: "Is defined locally" flag. Set if this route info was locally
+     *       defined as part of local network data. Assumed to be true for set,
+     *       insert and replace. Clear if the route is part of partition's network
+     *       data.
+     *  `b`: "Next hop is this device" flag. Set if the next hop for the
+     *       route is this device itself (i.e., route was added by this device)
+     *       This value is ignored when adding an external route. For any added
+     *       route the next hop is this device.
+     *  `S`: The RLOC16 of the device that registered this route entry.
+     *       This value is not used and ignored when adding a route.
+     *
+     */
+    SPINEL_PROP_THREAD_OFF_MESH_ROUTES = SPINEL_PROP_THREAD__BEGIN + 11,
+
+    /// Thread Assisting Ports
+    /** Format `A(S)`
+     *
+     * Array of port numbers.
+     */
+    SPINEL_PROP_THREAD_ASSISTING_PORTS = SPINEL_PROP_THREAD__BEGIN + 12,
+
+    /// Thread Allow Local Network Data Change
+    /** Format `b` - Read-write
+     *
+     * Set to true before changing local net data. Set to false when finished.
+     * This allows changes to be aggregated into a single event.
+     *
+     */
+    SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE = SPINEL_PROP_THREAD__BEGIN + 13,
+
+    /// Thread Mode
+    /** Format: `C`
+     *
+     *  This property contains the value of the mode
+     *  TLV for this node. The meaning of the bits in this
+     *  bit-field are defined by section 4.5.2 of the Thread
+     *  specification.
+     *
+     * The values `SPINEL_THREAD_MODE_*` defines the bit-fields
+     *
+     */
+    SPINEL_PROP_THREAD_MODE = SPINEL_PROP_THREAD__BEGIN + 14,
+
+    SPINEL_PROP_THREAD__END = 0x60,
+
+    SPINEL_PROP_THREAD_EXT__BEGIN = 0x1500,
+
+    /// Thread Child Timeout
+    /** Format: `L`
+     *  Unit: Seconds
+     *
+     *  Used when operating in the Child role.
+     */
+    SPINEL_PROP_THREAD_CHILD_TIMEOUT = SPINEL_PROP_THREAD_EXT__BEGIN + 0,
+
+    /// Thread RLOC16
+    /** Format: `S`
+     *
+     */
+    SPINEL_PROP_THREAD_RLOC16 = SPINEL_PROP_THREAD_EXT__BEGIN + 1,
+
+    /// Thread Router Upgrade Threshold
+    /** Format: `C`
+     *
+     */
+    SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD = SPINEL_PROP_THREAD_EXT__BEGIN + 2,
+
+    /// Thread Context Reuse Delay
+    /** Format: `L`
+     *
+     */
+    SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY = SPINEL_PROP_THREAD_EXT__BEGIN + 3,
+
+    /// Thread Network ID Timeout
+    /** Format: `C`
+     *
+     */
+    SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT = SPINEL_PROP_THREAD_EXT__BEGIN + 4,
+
+    /// List of active thread router ids
+    /** Format: `A(C)`
+     *
+     * Note that some implementations may not support CMD_GET_VALUE
+     * router ids, but may support CMD_REMOVE_VALUE when the node is
+     * a leader.
+     *
+     */
+    SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS = SPINEL_PROP_THREAD_EXT__BEGIN + 5,
+
+    /// Forward IPv6 packets that use RLOC16 addresses to HOST.
+    /** Format: `b`
+     *
+     * Allow host to directly observe all IPv6 packets received by the NCP,
+     * including ones sent to the RLOC16 address.
+     *
+     * Default is false.
+     *
+     */
+    SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU = SPINEL_PROP_THREAD_EXT__BEGIN + 6,
+
+    /// Router Role Enabled
+    /** Format `b`
+     *
+     * Allows host to indicate whether or not the router role is enabled.
+     * If current role is a router, setting this property to `false` starts
+     * a re-attach process as an end-device.
+     *
+     */
+    SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 7,
+
+    /// Thread Router Downgrade Threshold
+    /** Format: `C`
+     *
+     */
+    SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD = SPINEL_PROP_THREAD_EXT__BEGIN + 8,
+
+    /// Thread Router Selection Jitter
+    /** Format: `C`
+     *
+     */
+    SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER = SPINEL_PROP_THREAD_EXT__BEGIN + 9,
+
+    /// Thread Preferred Router Id
+    /** Format: `C` - Write only
+     *
+     * Specifies the preferred Router Id. Upon becoming a router/leader the node
+     * attempts to use this Router Id. If the preferred Router Id is not set or
+     * if it can not be used, a randomly generated router id is picked. This
+     * property can be set only when the device role is either detached or
+     * disabled.
+     *
+     */
+    SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID = SPINEL_PROP_THREAD_EXT__BEGIN + 10,
+
+    /// Thread Neighbor Table
+    /** Format: `A(t(ESLCcCbLLc))` - Read only
+     *
+     * Data per item is:
+     *
+     *  `E`: Extended address
+     *  `S`: RLOC16
+     *  `L`: Age (in seconds)
+     *  `C`: Link Quality In
+     *  `c`: Average RSS (in dBm)
+     *  `C`: Mode (bit-flags)
+     *  `b`: `true` if neighbor is a child, `false` otherwise.
+     *  `L`: Link Frame Counter
+     *  `L`: MLE Frame Counter
+     *  `c`: The last RSSI (in dBm)
+     *
+     */
+    SPINEL_PROP_THREAD_NEIGHBOR_TABLE = SPINEL_PROP_THREAD_EXT__BEGIN + 11,
+
+    /// Thread Max Child Count
+    /** Format: `C`
+     *
+     * Specifies the maximum number of children currently allowed.
+     * This parameter can only be set when Thread protocol operation
+     * has been stopped.
+     *
+     */
+    SPINEL_PROP_THREAD_CHILD_COUNT_MAX = SPINEL_PROP_THREAD_EXT__BEGIN + 12,
+
+    /// Leader Network Data
+    /** Format: `D` - Read only
+     *
+     */
+    SPINEL_PROP_THREAD_LEADER_NETWORK_DATA = SPINEL_PROP_THREAD_EXT__BEGIN + 13,
+
+    /// Stable Leader Network Data
+    /** Format: `D` - Read only
+     *
+     */
+    SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA = SPINEL_PROP_THREAD_EXT__BEGIN + 14,
+
+    /// Thread Joiner Data
+    /** Format `A(T(ULE))`
+     *  PSKd, joiner timeout, eui64 (optional)
+     *
+     * This property is being deprecated by SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS.
+     *
+     */
+    SPINEL_PROP_THREAD_JOINERS = SPINEL_PROP_THREAD_EXT__BEGIN + 15,
+
+    /// Thread Commissioner Enable
+    /** Format `b`
+     *
+     * Default value is `false`.
+     *
+     * This property is being deprecated by SPINEL_PROP_MESHCOP_COMMISSIONER_STATE.
+     *
+     */
+    SPINEL_PROP_THREAD_COMMISSIONER_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 16,
+
+    /// Thread TMF proxy enable
+    /** Format `b`
+     * Required capability: `SPINEL_CAP_THREAD_TMF_PROXY`
+     *
+     * This property is deprecated.
+     *
+     */
+    SPINEL_PROP_THREAD_TMF_PROXY_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 17,
+
+    /// Thread TMF proxy stream
+    /** Format `dSS`
+     * Required capability: `SPINEL_CAP_THREAD_TMF_PROXY`
+     *
+     * This property is deprecated. Please see `SPINEL_PROP_THREAD_UDP_FORWARD_STREAM`.
+     *
+     */
+    SPINEL_PROP_THREAD_TMF_PROXY_STREAM = SPINEL_PROP_THREAD_EXT__BEGIN + 18,
+
+    /// Thread "joiner" flag used during discovery scan operation
+    /** Format `b`
+     *
+     * This property defines the Joiner Flag value in the Discovery Request TLV.
+     *
+     * Default value is `false`.
+     *
+     */
+    SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG = SPINEL_PROP_THREAD_EXT__BEGIN + 19,
+
+    /// Enable EUI64 filtering for discovery scan operation.
+    /** Format `b`
+     *
+     * Default value is `false`
+     *
+     */
+    SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING = SPINEL_PROP_THREAD_EXT__BEGIN + 20,
+
+    /// PANID used for Discovery scan operation (used for PANID filtering).
+    /** Format: `S`
+     *
+     * Default value is 0xffff (Broadcast PAN) to disable PANID filtering
+     *
+     */
+    SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID = SPINEL_PROP_THREAD_EXT__BEGIN + 21,
+
+    /// Thread (out of band) steering data for MLE Discovery Response.
+    /** Format `E` - Write only
+     *
+     * Required capability: SPINEL_CAP_OOB_STEERING_DATA.
+     *
+     * Writing to this property allows to set/update the MLE
+     * Discovery Response steering data out of band.
+     *
+     *  - All zeros to clear the steering data (indicating that
+     *    there is no steering data).
+     *  - All 0xFFs to set steering data/bloom filter to
+     *    accept/allow all.
+     *  - A specific EUI64 which is then added to current steering
+     *    data/bloom filter.
+     *
+     */
+    SPINEL_PROP_THREAD_STEERING_DATA = SPINEL_PROP_THREAD_EXT__BEGIN + 22,
+
+    /// Thread Router Table.
+    /** Format: `A(t(ESCCCCCCb)` - Read only
+     *
+     * Data per item is:
+     *
+     *  `E`: IEEE 802.15.4 Extended Address
+     *  `S`: RLOC16
+     *  `C`: Router ID
+     *  `C`: Next hop to router
+     *  `C`: Path cost to router
+     *  `C`: Link Quality In
+     *  `C`: Link Quality Out
+     *  `C`: Age (seconds since last heard)
+     *  `b`: Link established with Router ID or not.
+     *
+     */
+    SPINEL_PROP_THREAD_ROUTER_TABLE = SPINEL_PROP_THREAD_EXT__BEGIN + 23,
+
+    /// Thread Active Operational Dataset
+    /** Format: `A(t(iD))` - Read-Write
+     *
+     * This property provides access to current Thread Active Operational Dataset. A Thread device maintains the
+     * Operational Dataset that it has stored locally and the one currently in use by the partition to which it is
+     * attached. This property corresponds to the locally stored Dataset on the device.
+     *
+     * Operational Dataset consists of a set of supported properties (e.g., channel, master key, network name, PAN id,
+     * etc). Note that not all supported properties may be present (have a value) in a Dataset.
+     *
+     * The Dataset value is encoded as an array of structs containing pairs of property key (as `i`) followed by the
+     * property value (as `D`). The property value must follow the format associated with the corresponding property.
+     *
+     * On write, any unknown/unsupported property keys must be ignored.
+     *
+     * The following properties can be included in a Dataset list:
+     *
+     *   SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP
+     *   SPINEL_PROP_PHY_CHAN
+     *   SPINEL_PROP_PHY_CHAN_SUPPORTED (Channel Mask Page 0)
+     *   SPINEL_PROP_NET_MASTER_KEY
+     *   SPINEL_PROP_NET_NETWORK_NAME
+     *   SPINEL_PROP_NET_XPANID
+     *   SPINEL_PROP_MAC_15_4_PANID
+     *   SPINEL_PROP_IPV6_ML_PREFIX
+     *   SPINEL_PROP_NET_PSKC
+     *   SPINEL_PROP_DATASET_SECURITY_POLICY
+     *
+     */
+    SPINEL_PROP_THREAD_ACTIVE_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 24,
+
+    /// Thread Pending Operational Dataset
+    /** Format: `A(t(iD))` - Read-Write
+     *
+     * This property provide access to current locally stored Pending Operational Dataset.
+     *
+     * The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_ACTIVE_DATASET.
+     *
+     * In addition supported properties in SPINEL_PROP_THREAD_ACTIVE_DATASET, the following properties can also
+     * be included in the Pending Dataset:
+     *
+     *   SPINEL_PROP_DATASET_PENDING_TIMESTAMP
+     *   SPINEL_PROP_DATASET_DELAY_TIMER
+     *
+     */
+    SPINEL_PROP_THREAD_PENDING_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 25,
+
+    /// Send MGMT_SET Thread Active Operational Dataset
+    /** Format: `A(t(iD))` - Write only
+     *
+     * The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_ACTIVE_DATASET.
+     *
+     * This is write-only property. When written, it triggers a MGMT_ACTIVE_SET meshcop command to be sent to leader
+     * with the given Dataset. The spinel frame response should be a `LAST_STATUS` with the status of the transmission
+     * of MGMT_ACTIVE_SET command.
+     *
+     * In addition to supported properties in SPINEL_PROP_THREAD_ACTIVE_DATASET, the following property can be
+     * included in the Dataset (to allow for custom raw TLVs):
+     *
+     *    SPINEL_PROP_DATASET_RAW_TLVS
+     *
+     */
+    SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 26,
+
+    /// Send MGMT_SET Thread Pending Operational Dataset
+    /** Format: `A(t(iD))` - Write only
+     *
+     * This property is similar to SPINEL_PROP_THREAD_PENDING_DATASET and follows the same format and rules.
+     *
+     * In addition to supported properties in SPINEL_PROP_THREAD_PENDING_DATASET, the following property can be
+     * included the Dataset (to allow for custom raw TLVs to be provided).
+     *
+     *    SPINEL_PROP_DATASET_RAW_TLVS
+     *
+     */
+    SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 27,
+
+    /// Operational Dataset Active Timestamp
+    /** Format: `X` - No direct read or write
+     *
+     * It can only be included in one of the Dataset related properties below:
+     *
+     *   SPINEL_PROP_THREAD_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
+     *
+     */
+    SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP = SPINEL_PROP_THREAD_EXT__BEGIN + 28,
+
+    /// Operational Dataset Pending Timestamp
+    /** Format: `X` - No direct read or write
+     *
+     * It can only be included in one of the Pending Dataset properties:
+     *
+     *   SPINEL_PROP_THREAD_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
+     *
+     */
+    SPINEL_PROP_DATASET_PENDING_TIMESTAMP = SPINEL_PROP_THREAD_EXT__BEGIN + 29,
+
+    /// Operational Dataset Delay Timer
+    /** Format: `L` - No direct read or write
+     *
+     * Delay timer (in ms) specifies the time renaming until Thread devices overwrite the value in the Active
+     * Operational Dataset with the corresponding values in the Pending Operational Dataset.
+     *
+     * It can only be included in one of the Pending Dataset properties:
+     *
+     *   SPINEL_PROP_THREAD_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
+     *
+     */
+    SPINEL_PROP_DATASET_DELAY_TIMER = SPINEL_PROP_THREAD_EXT__BEGIN + 30,
+
+    /// Operational Dataset Security Policy
+    /** Format: `SC` - No direct read or write
+     *
+     * It can only be included in one of the Dataset related properties below:
+     *
+     *   SPINEL_PROP_THREAD_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
+     *
+     * Content is
+     *   `S` : Key Rotation Time (in units of hour)
+     *   `C` : Security Policy Flags (as specified in Thread 1.1 Section 8.10.1.15)
+     *
+     */
+    SPINEL_PROP_DATASET_SECURITY_POLICY = SPINEL_PROP_THREAD_EXT__BEGIN + 31,
+
+    /// Operational Dataset Additional Raw TLVs
+    /** Format: `D` - No direct read or write
+     *
+     * This property defines extra raw TLVs that can be added to an Operational DataSet.
+     *
+     * It can only be included in one of the following Dataset properties:
+     *
+     *   SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
+     *
+     */
+    SPINEL_PROP_DATASET_RAW_TLVS = SPINEL_PROP_THREAD_EXT__BEGIN + 32,
+
+    /// Child table addresses
+    /** Format: `A(t(ESA(6)))` - Read only
+     *
+     * This property provides the list of all addresses associated with every child
+     * including any registered IPv6 addresses.
+     *
+     * Data per item is:
+     *
+     *  `E`: Extended address of the child
+     *  `S`: RLOC16 of the child
+     *  `A(6)`: List of IPv6 addresses registered by the child (if any)
+     *
+     */
+    SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES = SPINEL_PROP_THREAD_EXT__BEGIN + 33,
+
+    /// Neighbor Table Frame and Message Error Rates
+    /** Format: `A(t(ESSScc))`
+     *  Required capability: `CAP_ERROR_RATE_TRACKING`
+     *
+     * This property provides link quality related info including
+     * frame and (IPv6) message error rates for all neighbors.
+     *
+     * With regards to message error rate, note that a larger (IPv6)
+     * message can be fragmented and sent as multiple MAC frames. The
+     * message transmission is considered a failure, if any of its
+     * fragments fail after all MAC retry attempts.
+     *
+     * Data per item is:
+     *
+     *  `E`: Extended address of the neighbor
+     *  `S`: RLOC16 of the neighbor
+     *  `S`: Frame error rate (0 -> 0%, 0xffff -> 100%)
+     *  `S`: Message error rate (0 -> 0%, 0xffff -> 100%)
+     *  `c`: Average RSSI (in dBm)
+     *  `c`: Last RSSI (in dBm)
+     *
+     */
+    SPINEL_PROP_THREAD_NEIGHBOR_TABLE_ERROR_RATES = SPINEL_PROP_THREAD_EXT__BEGIN + 34,
+
+    /// EID (Endpoint Identifier) IPv6 Address Cache Table
+    /** Format `A(t(6SCCt(bL6)t(bSS)))
+     *
+     * This property provides Thread EID address cache table.
+     *
+     * Data per item is:
+     *
+     *  `6` : Target IPv6 address
+     *  `S` : RLOC16 of target
+     *  `C` : Age (order of use, 0 indicates most recently used entry)
+     *  `C` : Entry state (values are defined by enumeration `SPINEL_ADDRESS_CACHE_ENTRY_STATE_*`).
+     *
+     *  `t` : Info when state is `SPINEL_ADDRESS_CACHE_ENTRY_STATE_CACHED`
+     *    `b` : Indicates whether last transaction time and ML-EID are valid.
+     *    `L` : Last transaction time
+     *    `6` : Mesh-local EID
+     *
+     *  `t` : Info when state is other than `SPINEL_ADDRESS_CACHE_ENTRY_STATE_CACHED`
+     *    `b` : Indicates whether the entry can be evicted.
+     *    `S` : Timeout in seconds
+     *    `S` : Retry delay (applicable if in query-retry state).
+     *
+     */
+    SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE = SPINEL_PROP_THREAD_EXT__BEGIN + 35,
+
+    /// Thread UDP forward stream
+    /** Format `dS6S`
+     * Required capability: `SPINEL_CAP_THREAD_UDP_FORWARD`
+     *
+     * This property helps exchange UDP packets with host.
+     *
+     *  `d`: UDP payload
+     *  `S`: Remote UDP port
+     *  `6`: Remote IPv6 address
+     *  `S`: Local UDP port
+     *
+     */
+    SPINEL_PROP_THREAD_UDP_FORWARD_STREAM = SPINEL_PROP_THREAD_EXT__BEGIN + 36,
+
+    /// Send MGMT_GET Thread Active Operational Dataset
+    /** Format: `A(t(iD))` - Write only
+     *
+     * The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET. This
+     * property further allows the sender to not include a value associated with properties in formating of `t(iD)`,
+     * i.e., it should accept either a `t(iD)` or a `t(i)` encoding (in both cases indicating that the associated
+     * Dataset property should be requested as part of MGMT_GET command).
+     *
+     * This is write-only property. When written, it triggers a MGMT_ACTIVE_GET meshcop command to be sent to leader
+     * requesting the Dataset related properties from the format. The spinel frame response should be a `LAST_STATUS`
+     * with the status of the transmission of MGMT_ACTIVE_GET command.
+     *
+     * In addition to supported properties in SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET, the following property can be
+     * optionally included in the Dataset:
+     *
+     *    SPINEL_PROP_DATASET_DEST_ADDRESS
+     *
+     */
+    SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 37,
+
+    /// Send MGMT_GET Thread Pending Operational Dataset
+    /** Format: `A(t(iD))` - Write only
+     *
+     * The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET.
+     *
+     * This is write-only property. When written, it triggers a MGMT_PENDING_GET meshcop command to be sent to leader
+     * with the given Dataset. The spinel frame response should be a `LAST_STATUS` with the status of the transmission
+     * of MGMT_PENDING_GET command.
+     *
+     */
+    SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 38,
+
+    /// Operational Dataset (MGMT_GET) Destination IPv6 Address
+    /** Format: `6` - No direct read or write
+     *
+     * This property specifies the IPv6 destination when sending MGMT_GET command for either Active or Pending Dataset
+     * if not provided, Leader ALOC address is used as default.
+     *
+     * It can only be included in one of the MGMT_GET Dataset properties:
+     *
+     *   SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET
+     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
+     *
+     */
+    SPINEL_PROP_DATASET_DEST_ADDRESS = SPINEL_PROP_THREAD_EXT__BEGIN + 39,
+
+    /// Thread New Operational Dataset
+    /** Format: `A(t(iD))` - Read only - FTD build only
+     *
+     * This property allows host to request NCP to create and return a new Operation Dataset to use when forming a new
+     * network.
+     *
+     * Operational Dataset consists of a set of supported properties (e.g., channel, master key, network name, PAN id,
+     * etc). Note that not all supported properties may be present (have a value) in a Dataset.
+     *
+     * The Dataset value is encoded as an array of structs containing pairs of property key (as `i`) followed by the
+     * property value (as `D`). The property value must follow the format associated with the corresponding property.
+     *
+     * The following properties can be included in a Dataset list:
+     *
+     *   SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP
+     *   SPINEL_PROP_PHY_CHAN
+     *   SPINEL_PROP_PHY_CHAN_SUPPORTED (Channel Mask Page 0)
+     *   SPINEL_PROP_NET_MASTER_KEY
+     *   SPINEL_PROP_NET_NETWORK_NAME
+     *   SPINEL_PROP_NET_XPANID
+     *   SPINEL_PROP_MAC_15_4_PANID
+     *   SPINEL_PROP_IPV6_ML_PREFIX
+     *   SPINEL_PROP_NET_PSKC
+     *   SPINEL_PROP_DATASET_SECURITY_POLICY
+     *
+     */
+    SPINEL_PROP_THREAD_NEW_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 40,
+
+    SPINEL_PROP_THREAD_EXT__END = 0x1600,
+
+    SPINEL_PROP_IPV6__BEGIN = 0x60,
+
+    /// Link-Local IPv6 Address
+    /** Format: `6` - Read only
+     *
+     */
+    SPINEL_PROP_IPV6_LL_ADDR = SPINEL_PROP_IPV6__BEGIN + 0, ///< [6]
+
+    /// Mesh Local IPv6 Address
+    /** Format: `6` - Read only
+     *
+     */
+    SPINEL_PROP_IPV6_ML_ADDR = SPINEL_PROP_IPV6__BEGIN + 1,
+
+    /// Mesh Local Prefix
+    /** Format: `6C` - Read-write
+     *
+     * Provides Mesh Local Prefix
+     *
+     *   `6`: Mesh local prefix
+     *   `C` : Prefix length (64 bit for Thread).
+     *
+     */
+    SPINEL_PROP_IPV6_ML_PREFIX = SPINEL_PROP_IPV6__BEGIN + 2,
+
+    /// IPv6 (Unicast) Address Table
+    /** Format: `A(t(6CLLC))`
+     *
+     * This property provides all unicast addresses.
+     *
+     * Array of structures containing:
+     *
+     *  `6`: IPv6 Address
+     *  `C`: Network Prefix Length (in bits)
+     *  `L`: Valid Lifetime
+     *  `L`: Preferred Lifetime
+     *
+     */
+    SPINEL_PROP_IPV6_ADDRESS_TABLE = SPINEL_PROP_IPV6__BEGIN + 3,
+
+    /// IPv6 Route Table - Deprecated
+    SPINEL_PROP_IPV6_ROUTE_TABLE = SPINEL_PROP_IPV6__BEGIN + 4,
+
+    /// IPv6 ICMP Ping Offload
+    /** Format: `b`
+     *
+     * Allow the NCP to directly respond to ICMP ping requests. If this is
+     * turned on, ping request ICMP packets will not be passed to the host.
+     *
+     * Default value is `false`.
+     */
+    SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD = SPINEL_PROP_IPV6__BEGIN + 5,
+
+    /// IPv6 Multicast Address Table
+    /** Format: `A(t(6))`
+     *
+     * This property provides all multicast addresses.
+     *
+     */
+    SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE = SPINEL_PROP_IPV6__BEGIN + 6,
+
+    /// IPv6 ICMP Ping Offload
+    /** Format: `C`
+     *
+     * Allow the NCP to directly respond to ICMP ping requests. If this is
+     * turned on, ping request ICMP packets will not be passed to the host.
+     *
+     * This property allows enabling responses sent to unicast only, multicast
+     * only, or both. The valid value are defined by enumeration
+     * `spinel_ipv6_icmp_ping_offload_mode_t`.
+     *
+     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_DISABLED       = 0
+     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_UNICAST_ONLY   = 1
+     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_MULTICAST_ONLY = 2
+     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL            = 3
+     *
+     * Default value is `NET_IPV6_ICMP_PING_OFFLOAD_DISABLED`.
+     *
+     */
+    SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE = SPINEL_PROP_IPV6__BEGIN + 7, ///< [b]
+
+    SPINEL_PROP_IPV6__END = 0x70,
+
+    SPINEL_PROP_IPV6_EXT__BEGIN = 0x1600,
+    SPINEL_PROP_IPV6_EXT__END   = 0x1700,
+
+    SPINEL_PROP_STREAM__BEGIN = 0x70,
+
+    /// Debug Stream
+    /** Format: `U` (stream, read only)
+     *
+     * This property is a streaming property, meaning that you cannot explicitly
+     * fetch the value of this property. The stream provides human-readable debugging
+     * output which may be displayed in the host logs.
+     *
+     * The location of newline characters is not assumed by the host: it is
+     * the NCP's responsibility to insert newline characters where needed,
+     * just like with any other text stream.
+     *
+     * To receive the debugging stream, you wait for `CMD_PROP_VALUE_IS`
+     * commands for this property from the NCP.
+     *
+     */
+    SPINEL_PROP_STREAM_DEBUG = SPINEL_PROP_STREAM__BEGIN + 0,
+
+    /// Raw Stream
+    /** Format: `dD` (stream, read only)
+     *  Required Capability: SPINEL_CAP_MAC_RAW or SPINEL_CAP_CONFIG_RADIO
+     *
+     * This stream provides the capability of sending and receiving raw 15.4 frames
+     * to and from the radio. The exact format of the frame metadata and data is
+     * dependent on the MAC and PHY being used.
+     *
+     * This property is a streaming property, meaning that you cannot explicitly
+     * fetch the value of this property. To receive traffic, you wait for
+     * `CMD_PROP_VALUE_IS` commands with this property id from the NCP.
+     *
+     * The general format of this property is:
+     *
+     *    `d` : frame data
+     *    `D` : frame meta data
+     *
+     * The frame meta data is optional. Frame metadata MAY be empty or partially
+     * specified. Partially specified metadata MUST be accepted. Default values
+     * are used for all unspecified fields.
+     *
+     * The frame metadata field consists of the following fields:
+     *
+     *   `c` : Received Signal Strength (RSSI) in dBm - default is -128
+     *   `c` : Noise floor in dBm - default is -128
+     *   `S` : Flags (see below).
+     *   `d` : PHY-specific data/struct
+     *   `d` : Vendor-specific data/struct
+     *
+     * Flags fields are defined by the following enumeration bitfields:
+     *
+     *   SPINEL_MD_FLAG_TX       = 0x0001 :  Packet was transmitted, not received.
+     *   SPINEL_MD_FLAG_BAD_FCS  = 0x0004 :  Packet was received with bad FCS
+     *   SPINEL_MD_FLAG_DUPE     = 0x0008 :  Packet seems to be a duplicate
+     *   SPINEL_MD_FLAG_RESERVED = 0xFFF2 :  Flags reserved for future use.
+     *
+     * The format of PHY-specific data for a Thread device contains the following
+     * optional fields:
+
+     *   `C` : 802.15.4 channel (Receive channel)
+     *   `C` : IEEE 802.15.4 LQI
+     *   `L` : The timestamp milliseconds
+     *   `S` : The timestamp microseconds, offset to mMsec
+     *
+     * Frames written to this stream with `CMD_PROP_VALUE_SET` will be sent out
+     * over the radio. This allows the caller to use the radio directly.
+     *
+     * The frame meta data for the `CMD_PROP_VALUE_SET` contains the following
+     * optional fields.  Default values are used for all unspecified fields.
+     *
+     *  `C` : Channel (for frame tx)
+     *  `C` : Maximum number of backoffs attempts before declaring CCA failure
+     *        (use Thread stack default if not specified)
+     *  `C` : Maximum number of retries allowed after a transmission failure
+     *        (use Thread stack default if not specified)
+     *  `b` : Set to true to enable CSMA-CA for this packet, false otherwise.
+     *        (default true).
+     *  `b` : Set to true to indicate it is a retransmission packet, false otherwise.
+     *        (default false).
+     *  `b` : Set to true to indicate that SubMac should skip AES processing, false otherwise.
+     *        (default false).
+     *
+     */
+    SPINEL_PROP_STREAM_RAW = SPINEL_PROP_STREAM__BEGIN + 1,
+
+    /// (IPv6) Network Stream
+    /** Format: `dD` (stream, read only)
+     *
+     * This stream provides the capability of sending and receiving (IPv6)
+     * data packets to and from the currently attached network. The packets
+     * are sent or received securely (encryption and authentication).
+     *
+     * This property is a streaming property, meaning that you cannot explicitly
+     * fetch the value of this property. To receive traffic, you wait for
+     * `CMD_PROP_VALUE_IS` commands with this property id from the NCP.
+     *
+     * To send network packets, you call `CMD_PROP_VALUE_SET` on this property with
+     * the value of the packet.
+     *
+     * The general format of this property is:
+     *
+     *    `d` : packet data
+     *    `D` : packet meta data
+     *
+     * The packet metadata is optional. Packet meta data MAY be empty or partially
+     * specified. Partially specified metadata MUST be accepted. Default values
+     * are used for all unspecified fields.
+     *
+     * For OpenThread the meta data is currently empty.
+     *
+     */
+    SPINEL_PROP_STREAM_NET = SPINEL_PROP_STREAM__BEGIN + 2,
+
+    /// (IPv6) Network Stream Insecure
+    /** Format: `dD` (stream, read only)
+     *
+     * This stream provides the capability of sending and receiving unencrypted
+     * and unauthenticated data packets to and from nearby devices for the
+     * purposes of device commissioning.
+     *
+     * This property is a streaming property, meaning that you cannot explicitly
+     * fetch the value of this property. To receive traffic, you wait for
+     * `CMD_PROP_VALUE_IS` commands with this property id from the NCP.
+     *
+     * To send network packets, you call `CMD_PROP_VALUE_SET` on this property with
+     * the value of the packet.
+     *
+     * The general format of this property is:
+     *
+     *    `d` : packet data
+     *    `D` : packet meta data
+     *
+     * The packet metadata is optional. Packet meta data MAY be empty or partially
+     * specified. Partially specified metadata MUST be accepted. Default values
+     * are used for all unspecified fields.
+     *
+     * For OpenThread the meta data is currently empty.
+     *
+     */
+    SPINEL_PROP_STREAM_NET_INSECURE = SPINEL_PROP_STREAM__BEGIN + 3,
+
+    /// Log Stream
+    /** Format: `UD` (stream, read only)
+     *
+     * This property is a read-only streaming property which provides
+     * formatted log string from NCP. This property provides asynchronous
+     * `CMD_PROP_VALUE_IS` updates with a new log string and includes
+     * optional meta data.
+     *
+     *   `U`: The log string
+     *   `D`: Log metadata (optional).
+     *
+     * Any data after the log string is considered metadata and is OPTIONAL.
+     * Presence of `SPINEL_CAP_OPENTHREAD_LOG_METADATA` capability
+     * indicates that OpenThread log metadata format is used as defined
+     * below:
+     *
+     *    `C`: Log level (as per definition in enumeration
+     *         `SPINEL_NCP_LOG_LEVEL_<level>`)
+     *    `i`: OpenThread Log region (as per definition in enumeration
+     *         `SPINEL_NCP_LOG_REGION_<region>).
+     *    `X`: Log timestamp = <timestamp_base> + <current_time_ms>
+     *
+     */
+    SPINEL_PROP_STREAM_LOG = SPINEL_PROP_STREAM__BEGIN + 4,
+
+    SPINEL_PROP_STREAM__END = 0x80,
+
+    SPINEL_PROP_STREAM_EXT__BEGIN = 0x1700,
+    SPINEL_PROP_STREAM_EXT__END   = 0x1800,
+
+    SPINEL_PROP_MESHCOP__BEGIN = 0x80,
+
+    // Thread Joiner State
+    /** Format `C` - Read Only
+     *
+     * Required capability: SPINEL_CAP_THREAD_JOINER
+     *
+     * The valid values are specified by `spinel_meshcop_joiner_state_t` (`SPINEL_MESHCOP_JOINER_STATE_<state>`)
+     * enumeration.
+     *
+     */
+    SPINEL_PROP_MESHCOP_JOINER_STATE = SPINEL_PROP_MESHCOP__BEGIN + 0, ///<[C]
+
+    /// Thread Joiner Commissioning command and the parameters
+    /** Format `b` or `bU(UUUUU)` (fields in parenthesis are optional) - Write Only
+     *
+     * This property starts or stops Joiner's commissioning process
+     *
+     * Required capability: SPINEL_CAP_THREAD_JOINER
+     *
+     * Writing to this property starts/stops the Joiner commissioning process.
+     * The immediate `VALUE_IS` response indicates success/failure of the starting/stopping
+     * the Joiner commissioning process.
+     *
+     * After a successful start operation, the join process outcome is reported through an
+     * asynchronous `VALUE_IS(LAST_STATUS)` update with one of the following error status values:
+     *
+     *     - SPINEL_STATUS_JOIN_SUCCESS     the join process succeeded.
+     *     - SPINEL_STATUS_JOIN_SECURITY    the join process failed due to security credentials.
+     *     - SPINEL_STATUS_JOIN_NO_PEERS    no joinable network was discovered.
+     *     - SPINEL_STATUS_JOIN_RSP_TIMEOUT if a response timed out.
+     *     - SPINEL_STATUS_JOIN_FAILURE     join failure.
+     *
+     * Frame format:
+     *
+     *  `b` : Start or stop commissioning process (true to start).
+     *
+     * Only if the start commissioning.
+     *
+     *  `U` : Joiner's PSKd.
+     *
+     * The next fields are all optional. If not provided, OpenThread default values would be used.
+     *
+     *  `U` : Provisioning URL (use empty string if not required).
+     *  `U` : Vendor Name. If not specified or empty string, use OpenThread default (PACKAGE_NAME).
+     *  `U` : Vendor Model. If not specified or empty string, use OpenThread default (OPENTHREAD_CONFIG_PLATFORM_INFO).
+     *  `U` : Vendor Sw Version. If not specified or empty string, use OpenThread default (PACKAGE_VERSION).
+     *  `U` : Vendor Data String. Will not be appended if not specified.
+     *
+     */
+    SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING = SPINEL_PROP_MESHCOP__BEGIN + 1,
+
+    // Thread Commissioner State
+    /** Format `C`
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * The valid values are specified by SPINEL_MESHCOP_COMMISSIONER_STATE_<state> enumeration.
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_STATE = SPINEL_PROP_MESHCOP__BEGIN + 2,
+
+    // Thread Commissioner Joiners
+    /** Format `A(t(t(E|CX)UL))` - get, insert or remove.
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * Data per array entry is:
+     *
+     *  `t()` | `t(E)` | `t(CX)` : Joiner info struct (formatting varies).
+     *
+     *   -  `t()` or empty struct indicates any joiner.
+     *   -  `t(E)` specifies the Joiner EUI-64.
+     *   -  `t(CX) specifies Joiner Discerner, `C` is Discerner length (in bits), and `X` is Discerner value.
+     *
+     * The struct is followed by:
+     *
+     *  `L` : Timeout after which to remove Joiner (when written should be in seconds, when read is in milliseconds)
+     *  `U` : PSKd
+     *
+     * For CMD_PROP_VALUE_REMOVE the timeout and PSKd are optional.
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS = SPINEL_PROP_MESHCOP__BEGIN + 3,
+
+    // Thread Commissioner Provisioning URL
+    /** Format `U`
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL = SPINEL_PROP_MESHCOP__BEGIN + 4,
+
+    // Thread Commissioner Session ID
+    /** Format `S` - Read only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID = SPINEL_PROP_MESHCOP__BEGIN + 5,
+
+    /// Thread Joiner Discerner
+    /** Format `CX`  - Read-write
+     *
+     * Required capability: SPINEL_CAP_THREAD_JOINER
+     *
+     * This property represents a Joiner Discerner.
+     *
+     * The Joiner Discerner is used to calculate the Joiner ID used during commissioning/joining process.
+     *
+     * By default (when a discerner is not provided or cleared), Joiner ID is derived as first 64 bits of the result
+     * of computing SHA-256 over factory-assigned IEEE EUI-64. Note that this is the main behavior expected by Thread
+     * specification.
+     *
+     * Format:
+     *
+     *   'C' : The Joiner Discerner bit length (number of bits).
+     *   `X` : The Joiner Discerner value (64-bit unsigned)  - Only present/applicable when length is non-zero.
+     *
+     * When writing to this property, the length can be set to zero to clear any previously set Joiner Discerner value.
+     *
+     * When reading this property if there is no currently set Joiner Discerner, zero is returned as the length (with
+     * no value field).
+     *
+     */
+    SPINEL_PROP_MESHCOP_JOINER_DISCERNER = SPINEL_PROP_MESHCOP__BEGIN + 6,
+
+    SPINEL_PROP_MESHCOP__END = 0x90,
+
+    SPINEL_PROP_MESHCOP_EXT__BEGIN = 0x1800,
+
+    // Thread Commissioner Announce Begin
+    /** Format `LCS6` - Write only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * Writing to this property sends an Announce Begin message with the specified parameters. Response is a
+     * `LAST_STATUS` update with status of operation.
+     *
+     *   `L` : Channel mask
+     *   `C` : Number of messages per channel
+     *   `S` : The time between two successive MLE Announce transmissions (milliseconds)
+     *   `6` : IPv6 destination
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN = SPINEL_PROP_MESHCOP_EXT__BEGIN + 0,
+
+    // Thread Commissioner Energy Scan Query
+    /** Format `LCSS6` - Write only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * Writing to this property sends an Energy Scan Query message with the specified parameters. Response is a
+     * `LAST_STATUS` with status of operation. The energy scan results are emitted asynchronously through
+     * `SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT` updates.
+     *
+     * Format is:
+     *
+     *   `L` : Channel mask
+     *   `C` : The number of energy measurements per channel
+     *   `S` : The time between energy measurements (milliseconds)
+     *   `S` : The scan duration for each energy measurement (milliseconds)
+     *   `6` : IPv6 destination.
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN = SPINEL_PROP_MESHCOP_EXT__BEGIN + 1,
+
+    // Thread Commissioner Energy Scan Result
+    /** Format `Ld` - Asynchronous event only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * This property provides asynchronous `CMD_PROP_VALUE_INSERTED` updates to report energy scan results for a
+     * previously sent Energy Scan Query message (please see `SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN`).
+     *
+     * Format is:
+     *
+     *   `L` : Channel mask
+     *   `d` : Energy measurement data (note that `d` encoding includes the length)
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT = SPINEL_PROP_MESHCOP_EXT__BEGIN + 2,
+
+    // Thread Commissioner PAN ID Query
+    /** Format `SL6` - Write only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * Writing to this property sends a PAN ID Query message with the specified parameters. Response is a
+     * `LAST_STATUS` with status of operation. The PAN ID Conflict results are emitted asynchronously through
+     * `SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT` updates.
+     *
+     * Format is:
+     *
+     *   `S` : PAN ID to query
+     *   `L` : Channel mask
+     *   `6` : IPv6 destination
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY = SPINEL_PROP_MESHCOP_EXT__BEGIN + 3,
+
+    // Thread Commissioner PAN ID Conflict Result
+    /** Format `SL` - Asynchronous event only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * This property provides asynchronous `CMD_PROP_VALUE_INSERTED` updates to report PAN ID conflict results for a
+     * previously sent PAN ID Query message (please see `SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY`).
+     *
+     * Format is:
+     *
+     *   `S` : The PAN ID
+     *   `L` : Channel mask
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT = SPINEL_PROP_MESHCOP_EXT__BEGIN + 4,
+
+    // Thread Commissioner Send MGMT_COMMISSIONER_GET
+    /** Format `d` - Write only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * Writing to this property sends a MGMT_COMMISSIONER_GET message with the specified parameters. Response is a
+     * `LAST_STATUS` with status of operation.
+     *
+     * Format is:
+     *
+     *   `d` : List of TLV types to get
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_GET = SPINEL_PROP_MESHCOP_EXT__BEGIN + 5,
+
+    // Thread Commissioner Send MGMT_COMMISSIONER_SET
+    /** Format `d` - Write only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * Writing to this property sends a MGMT_COMMISSIONER_SET message with the specified parameters. Response is a
+     * `LAST_STATUS` with status of operation.
+     *
+     * Format is:
+     *
+     *   `d` : TLV encoded data
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_SET = SPINEL_PROP_MESHCOP_EXT__BEGIN + 6,
+
+    // Thread Commissioner Generate PSKc
+    /** Format: `UUd` - Write only
+     *
+     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
+     *
+     * Writing to this property allows user to generate PSKc from a given commissioning pass-phrase, network name,
+     * extended PAN Id.
+     *
+     * Written value format is:
+     *
+     *   `U` : The commissioning pass-phrase.
+     *   `U` : Network Name.
+     *   `d` : Extended PAN ID.
+     *
+     * The response on success would be a `VALUE_IS` command with the PSKc with format below:
+     *
+     *   `D` : The PSKc
+     *
+     * On a failure a `LAST_STATUS` is emitted with the error status.
+     *
+     */
+    SPINEL_PROP_MESHCOP_COMMISSIONER_GENERATE_PSKC = SPINEL_PROP_MESHCOP_EXT__BEGIN + 7,
+
+    SPINEL_PROP_MESHCOP_EXT__END = 0x1900,
+
+    SPINEL_PROP_OPENTHREAD__BEGIN = 0x1900,
+
+    /// Channel Manager - Channel Change New Channel
+    /** Format: `C` (read-write)
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
+     *
+     * Setting this property triggers the Channel Manager to start
+     * a channel change process. The network switches to the given
+     * channel after the specified delay (see `CHANNEL_MANAGER_DELAY`).
+     *
+     * A subsequent write to this property will cancel an ongoing
+     * (previously requested) channel change.
+     *
+     */
+    SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL = SPINEL_PROP_OPENTHREAD__BEGIN + 0,
+
+    /// Channel Manager - Channel Change Delay
+    /** Format 'S'
+     *  Units: seconds
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
+     *
+     * This property specifies the delay (in seconds) to be used for
+     * a channel change request.
+     *
+     * The delay should preferably be longer than maximum data poll
+     * interval used by all sleepy-end-devices within the Thread
+     * network.
+     *
+     */
+    SPINEL_PROP_CHANNEL_MANAGER_DELAY = SPINEL_PROP_OPENTHREAD__BEGIN + 1,
+
+    /// Channel Manager Supported Channels
+    /** Format 'A(C)'
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
+     *
+     * This property specifies the list of supported channels.
+     *
+     */
+    SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS = SPINEL_PROP_OPENTHREAD__BEGIN + 2,
+
+    /// Channel Manager Favored Channels
+    /** Format 'A(C)'
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
+     *
+     * This property specifies the list of favored channels (when `ChannelManager` is asked to select channel)
+     *
+     */
+    SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS = SPINEL_PROP_OPENTHREAD__BEGIN + 3,
+
+    /// Channel Manager Channel Select Trigger
+    /** Format 'b'
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
+     *
+     * Writing to this property triggers a request on `ChannelManager` to select a new channel.
+     *
+     * Once a Channel Select is triggered, the Channel Manager will perform the following 3 steps:
+     *
+     * 1) `ChannelManager` decides if the channel change would be helpful. This check can be skipped if in the input
+     *    boolean to this property is set to `true` (skipping the quality check).
+     *    This step uses the collected link quality metrics on the device such as CCA failure rate, frame and message
+     *    error rates per neighbor, etc. to determine if the current channel quality is at the level that justifies
+     *    a channel change.
+     *
+     * 2) If first step passes, then `ChannelManager` selects a potentially better channel. It uses the collected
+     *    channel quality data by `ChannelMonitor` module. The supported and favored channels are used at this step.
+     *
+     * 3) If the newly selected channel is different from the current channel, `ChannelManager` requests/starts the
+     *    channel change process.
+     *
+     * Reading this property always yields `false`.
+     *
+     */
+    SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT = SPINEL_PROP_OPENTHREAD__BEGIN + 4,
+
+    /// Channel Manager Auto Channel Selection Enabled
+    /** Format 'b'
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
+     *
+     * This property indicates if auto-channel-selection functionality is enabled/disabled on `ChannelManager`.
+     *
+     * When enabled, `ChannelManager` will periodically checks and attempts to select a new channel. The period interval
+     * is specified by `SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL`.
+     *
+     */
+    SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED = SPINEL_PROP_OPENTHREAD__BEGIN + 5,
+
+    /// Channel Manager Auto Channel Selection Interval
+    /** Format 'L'
+     *  units: seconds
+     *
+     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
+     *
+     * This property specifies the auto-channel-selection check interval (in seconds).
+     *
+     */
+    SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL = SPINEL_PROP_OPENTHREAD__BEGIN + 6,
+
+    /// Thread network time.
+    /** Format: `Xc` - Read only
+     *
+     * Data per item is:
+     *
+     *  `X`: The Thread network time, in microseconds.
+     *  `c`: Time synchronization status.
+     *
+     */
+    SPINEL_PROP_THREAD_NETWORK_TIME = SPINEL_PROP_OPENTHREAD__BEGIN + 7,
+
+    /// Thread time synchronization period
+    /** Format: `S` - Read-Write
+     *
+     * Data per item is:
+     *
+     *  `S`: Time synchronization period, in seconds.
+     *
+     */
+    SPINEL_PROP_TIME_SYNC_PERIOD = SPINEL_PROP_OPENTHREAD__BEGIN + 8,
+
+    /// Thread Time synchronization XTAL accuracy threshold for Router
+    /** Format: `S` - Read-Write
+     *
+     * Data per item is:
+     *
+     *  `S`: The XTAL accuracy threshold for Router, in PPM.
+     *
+     */
+    SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD = SPINEL_PROP_OPENTHREAD__BEGIN + 9,
+
+    /// Child Supervision Interval
+    /** Format: `S` - Read-Write
+     *  Units: Seconds
+     *
+     * Required capability: `SPINEL_CAP_CHILD_SUPERVISION`
+     *
+     * The child supervision interval (in seconds). Zero indicates that child supervision is disabled.
+     *
+     * When enabled, Child supervision feature ensures that at least one message is sent to every sleepy child within
+     * the given supervision interval. If there is no other message, a supervision message (a data message with empty
+     * payload) is enqueued and sent to the child.
+     *
+     * This property is available for FTD build only.
+     *
+     */
+    SPINEL_PROP_CHILD_SUPERVISION_INTERVAL = SPINEL_PROP_OPENTHREAD__BEGIN + 10,
+
+    /// Child Supervision Check Timeout
+    /** Format: `S` - Read-Write
+     *  Units: Seconds
+     *
+     * Required capability: `SPINEL_CAP_CHILD_SUPERVISION`
+     *
+     * The child supervision check timeout interval (in seconds). Zero indicates supervision check on the child is
+     * disabled.
+     *
+     * Supervision check is only applicable on a sleepy child. When enabled, if the child does not hear from its parent
+     * within the specified check timeout, it initiates a re-attach process by starting an MLE Child Update
+     * Request/Response exchange with the parent.
+     *
+     * This property is available for FTD and MTD builds.
+     *
+     */
+    SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT = SPINEL_PROP_OPENTHREAD__BEGIN + 11,
+
+    // RCP (NCP in radio only mode) version
+    /** Format `U` - Read only
+     *
+     * Required capability: SPINEL_CAP_POSIX
+     *
+     * This property gives the version string of RCP (NCP in radio mode) which is being controlled by a POSIX
+     * application. It is available only in "POSIX" platform (i.e., `OPENTHREAD_PLATFORM_POSIX` is enabled).
+     *
+     */
+    SPINEL_PROP_RCP_VERSION = SPINEL_PROP_OPENTHREAD__BEGIN + 12,
+
+    /// Thread Parent Response info
+    /** Format: `ESccCCCb` - Asynchronous event only
+     *
+     *  `E`: Extended address
+     *  `S`: RLOC16
+     *  `c`: Instant RSSI
+     *  'c': Parent Priority
+     *  `C`: Link Quality3
+     *  `C`: Link Quality2
+     *  `C`: Link Quality1
+     *  'b': Is the node receiving parent response frame attached
+     *
+     * This property sends Parent Response frame information to the Host.
+     * This property is available for FTD build only.
+     *
+     */
+    SPINEL_PROP_PARENT_RESPONSE_INFO = SPINEL_PROP_OPENTHREAD__BEGIN + 13,
+
+    /// SLAAC enabled
+    /** Format `b` - Read-Write
+     *  Required capability: `SPINEL_CAP_SLAAC`
+     *
+     * This property allows the host to enable/disable SLAAC module on NCP at run-time. When SLAAC module is enabled,
+     * SLAAC addresses (based on on-mesh prefixes in Network Data) are added to the interface. When SLAAC module is
+     * disabled any previously added SLAAC address is removed.
+     *
+     */
+    SPINEL_PROP_SLAAC_ENABLED = SPINEL_PROP_OPENTHREAD__BEGIN + 14,
+
+    SPINEL_PROP_OPENTHREAD__END = 0x2000,
+
+    SPINEL_PROP_SERVER__BEGIN = 0xA0,
+
+    /// Server Allow Local Network Data Change
+    /** Format `b` - Read-write
+     *
+     * Required capability: SPINEL_CAP_THREAD_SERVICE
+     *
+     * Set to true before changing local server net data. Set to false when finished.
+     * This allows changes to be aggregated into a single event.
+     *
+     */
+    SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE = SPINEL_PROP_SERVER__BEGIN + 0,
+
+    // Server Services
+    /** Format: `A(t(LdbdS))`
+     *
+     * This property provides all services registered on the device
+     *
+     * Required capability: SPINEL_CAP_THREAD_SERVICE
+     *
+     * Array of structures containing:
+     *
+     *  `L`: Enterprise Number
+     *  `d`: Service Data
+     *  `b`: Stable
+     *  `d`: Server Data
+     *  `S`: RLOC
+     *
+     */
+    SPINEL_PROP_SERVER_SERVICES = SPINEL_PROP_SERVER__BEGIN + 1,
+
+    // Server Leader Services
+    /** Format: `A(t(CLdbdS))`
+     *
+     * This property provides all services registered on the leader
+     *
+     * Array of structures containing:
+     *
+     *  `C`: Service ID
+     *  `L`: Enterprise Number
+     *  `d`: Service Data
+     *  `b`: Stable
+     *  `d`: Server Data
+     *  `S`: RLOC
+     *
+     */
+    SPINEL_PROP_SERVER_LEADER_SERVICES = SPINEL_PROP_SERVER__BEGIN + 2,
+
+    SPINEL_PROP_SERVER__END = 0xB0,
+
+    SPINEL_PROP_INTERFACE__BEGIN = 0x100,
+
+    /// UART Bitrate
+    /** Format: `L`
+     *
+     *  If the NCP is using a UART to communicate with the host,
+     *  this property allows the host to change the bitrate
+     *  of the serial connection. The value encoding is `L`,
+     *  which is a little-endian 32-bit unsigned integer.
+     *  The host should not assume that all possible numeric values
+     *  are supported.
+     *
+     *  If implemented by the NCP, this property should be persistent
+     *  across software resets and forgotten upon hardware resets.
+     *
+     *  This property is only implemented when a UART is being
+     *  used for Spinel. This property is optional.
+     *
+     *  When changing the bitrate, all frames will be received
+     *  at the previous bitrate until the response frame to this command
+     *  is received. Once a successful response frame is received by
+     *  the host, all further frames will be transmitted at the new
+     *  bitrate.
+     */
+    SPINEL_PROP_UART_BITRATE = SPINEL_PROP_INTERFACE__BEGIN + 0,
+
+    /// UART Software Flow Control
+    /** Format: `b`
+     *
+     *  If the NCP is using a UART to communicate with the host,
+     *  this property allows the host to determine if software flow
+     *  control (XON/XOFF style) should be used and (optionally) to
+     *  turn it on or off.
+     *
+     *  This property is only implemented when a UART is being
+     *  used for Spinel. This property is optional.
+     */
+    SPINEL_PROP_UART_XON_XOFF = SPINEL_PROP_INTERFACE__BEGIN + 1,
+
+    SPINEL_PROP_INTERFACE__END = 0x200,
+
+    SPINEL_PROP_15_4_PIB__BEGIN = 0x400,
+    // For direct access to the 802.15.4 PID.
+    // Individual registers are fetched using
+    // `SPINEL_PROP_15_4_PIB__BEGIN+[PIB_IDENTIFIER]`
+    // Only supported if SPINEL_CAP_15_4_PIB is set.
+    //
+    // For brevity, the entire 802.15.4 PIB space is
+    // not defined here, but a few choice attributes
+    // are defined for illustration and convenience.
+    SPINEL_PROP_15_4_PIB_PHY_CHANNELS_SUPPORTED = SPINEL_PROP_15_4_PIB__BEGIN + 0x01, ///< [A(L)]
+    SPINEL_PROP_15_4_PIB_MAC_PROMISCUOUS_MODE   = SPINEL_PROP_15_4_PIB__BEGIN + 0x51, ///< [b]
+    SPINEL_PROP_15_4_PIB_MAC_SECURITY_ENABLED   = SPINEL_PROP_15_4_PIB__BEGIN + 0x5d, ///< [b]
+    SPINEL_PROP_15_4_PIB__END                   = 0x500,
+
+    SPINEL_PROP_CNTR__BEGIN = 0x500,
+
+    /// Counter reset
+    /** Format: Empty (Write only).
+     *
+     * Writing to this property (with any value) will reset all MAC, MLE, IP, and NCP counters to zero.
+     *
+     */
+    SPINEL_PROP_CNTR_RESET = SPINEL_PROP_CNTR__BEGIN + 0,
+
+    /// The total number of transmissions.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_TOTAL = SPINEL_PROP_CNTR__BEGIN + 1,
+
+    /// The number of transmissions with ack request.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_ACK_REQ = SPINEL_PROP_CNTR__BEGIN + 2,
+
+    /// The number of transmissions that were acked.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_ACKED = SPINEL_PROP_CNTR__BEGIN + 3,
+
+    /// The number of transmissions without ack request.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_NO_ACK_REQ = SPINEL_PROP_CNTR__BEGIN + 4,
+
+    /// The number of transmitted data.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_DATA = SPINEL_PROP_CNTR__BEGIN + 5,
+
+    /// The number of transmitted data poll.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_DATA_POLL = SPINEL_PROP_CNTR__BEGIN + 6,
+
+    /// The number of transmitted beacon.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_BEACON = SPINEL_PROP_CNTR__BEGIN + 7,
+
+    /// The number of transmitted beacon request.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_BEACON_REQ = SPINEL_PROP_CNTR__BEGIN + 8,
+
+    /// The number of transmitted other types of frames.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_OTHER = SPINEL_PROP_CNTR__BEGIN + 9,
+
+    /// The number of retransmission times.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_RETRY = SPINEL_PROP_CNTR__BEGIN + 10,
+
+    /// The number of CCA failure times.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_ERR_CCA = SPINEL_PROP_CNTR__BEGIN + 11,
+
+    /// The number of unicast packets transmitted.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_UNICAST = SPINEL_PROP_CNTR__BEGIN + 12,
+
+    /// The number of broadcast packets transmitted.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_BROADCAST = SPINEL_PROP_CNTR__BEGIN + 13,
+
+    /// The number of frame transmission failures due to abort error.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_ERR_ABORT = SPINEL_PROP_CNTR__BEGIN + 14,
+
+    /// The total number of received packets.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_TOTAL = SPINEL_PROP_CNTR__BEGIN + 100,
+
+    /// The number of received data.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_DATA = SPINEL_PROP_CNTR__BEGIN + 101,
+
+    /// The number of received data poll.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_DATA_POLL = SPINEL_PROP_CNTR__BEGIN + 102,
+
+    /// The number of received beacon.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_BEACON = SPINEL_PROP_CNTR__BEGIN + 103,
+
+    /// The number of received beacon request.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_BEACON_REQ = SPINEL_PROP_CNTR__BEGIN + 104,
+
+    /// The number of received other types of frames.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_OTHER = SPINEL_PROP_CNTR__BEGIN + 105,
+
+    /// The number of received packets filtered by whitelist.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_FILT_WL = SPINEL_PROP_CNTR__BEGIN + 106,
+
+    /// The number of received packets filtered by destination check.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_FILT_DA = SPINEL_PROP_CNTR__BEGIN + 107,
+
+    /// The number of received packets that are empty.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_EMPTY = SPINEL_PROP_CNTR__BEGIN + 108,
+
+    /// The number of received packets from an unknown neighbor.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_UKWN_NBR = SPINEL_PROP_CNTR__BEGIN + 109,
+
+    /// The number of received packets whose source address is invalid.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_NVLD_SADDR = SPINEL_PROP_CNTR__BEGIN + 110,
+
+    /// The number of received packets with a security error.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_SECURITY = SPINEL_PROP_CNTR__BEGIN + 111,
+
+    /// The number of received packets with a checksum error.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_BAD_FCS = SPINEL_PROP_CNTR__BEGIN + 112,
+
+    /// The number of received packets with other errors.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_OTHER = SPINEL_PROP_CNTR__BEGIN + 113,
+
+    /// The number of received duplicated.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_DUP = SPINEL_PROP_CNTR__BEGIN + 114,
+
+    /// The number of unicast packets received.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_UNICAST = SPINEL_PROP_CNTR__BEGIN + 115,
+
+    /// The number of broadcast packets received.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_BROADCAST = SPINEL_PROP_CNTR__BEGIN + 116,
+
+    /// The total number of secure transmitted IP messages.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 200,
+
+    /// The total number of insecure transmitted IP messages.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 201,
+
+    /// The number of dropped (not transmitted) IP messages.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_IP_DROPPED = SPINEL_PROP_CNTR__BEGIN + 202,
+
+    /// The total number of secure received IP message.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_IP_SEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 203,
+
+    /// The total number of insecure received IP message.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_IP_INSEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 204,
+
+    /// The number of dropped received IP messages.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_IP_DROPPED = SPINEL_PROP_CNTR__BEGIN + 205,
+
+    /// The number of transmitted spinel frames.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_SPINEL_TOTAL = SPINEL_PROP_CNTR__BEGIN + 300,
+
+    /// The number of received spinel frames.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_SPINEL_TOTAL = SPINEL_PROP_CNTR__BEGIN + 301,
+
+    /// The number of received spinel frames with error.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_SPINEL_ERR = SPINEL_PROP_CNTR__BEGIN + 302,
+
+    /// Number of out of order received spinel frames (tid increase by more than 1).
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_SPINEL_OUT_OF_ORDER_TID = SPINEL_PROP_CNTR__BEGIN + 303,
+
+    /// The number of successful Tx IP packets
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_IP_TX_SUCCESS = SPINEL_PROP_CNTR__BEGIN + 304,
+
+    /// The number of successful Rx IP packets
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_IP_RX_SUCCESS = SPINEL_PROP_CNTR__BEGIN + 305,
+
+    /// The number of failed Tx IP packets
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_IP_TX_FAILURE = SPINEL_PROP_CNTR__BEGIN + 306,
+
+    /// The number of failed Rx IP packets
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_IP_RX_FAILURE = SPINEL_PROP_CNTR__BEGIN + 307,
+
+    /// The message buffer counter info
+    /** Format: `SSSSSSSSSSSSSSSS` (Read-only)
+     *      `S`, (TotalBuffers)           The number of buffers in the pool.
+     *      `S`, (FreeBuffers)            The number of free message buffers.
+     *      `S`, (6loSendMessages)        The number of messages in the 6lo send queue.
+     *      `S`, (6loSendBuffers)         The number of buffers in the 6lo send queue.
+     *      `S`, (6loReassemblyMessages)  The number of messages in the 6LoWPAN reassembly queue.
+     *      `S`, (6loReassemblyBuffers)   The number of buffers in the 6LoWPAN reassembly queue.
+     *      `S`, (Ip6Messages)            The number of messages in the IPv6 send queue.
+     *      `S`, (Ip6Buffers)             The number of buffers in the IPv6 send queue.
+     *      `S`, (MplMessages)            The number of messages in the MPL send queue.
+     *      `S`, (MplBuffers)             The number of buffers in the MPL send queue.
+     *      `S`, (MleMessages)            The number of messages in the MLE send queue.
+     *      `S`, (MleBuffers)             The number of buffers in the MLE send queue.
+     *      `S`, (ArpMessages)            The number of messages in the ARP send queue.
+     *      `S`, (ArpBuffers)             The number of buffers in the ARP send queue.
+     *      `S`, (CoapMessages)           The number of messages in the CoAP send queue.
+     *      `S`, (CoapBuffers)            The number of buffers in the CoAP send queue.
+     */
+    SPINEL_PROP_MSG_BUFFER_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 400,
+
+    /// All MAC related counters.
+    /** Format: t(A(L))t(A(L))
+     *
+     * The contents include two structs, first one corresponds to
+     * all transmit related MAC counters, second one provides the
+     * receive related counters.
+     *
+     * The transmit structure includes:
+     *
+     *   'L': TxTotal                  (The total number of transmissions).
+     *   'L': TxUnicast                (The total number of unicast transmissions).
+     *   'L': TxBroadcast              (The total number of broadcast transmissions).
+     *   'L': TxAckRequested           (The number of transmissions with ack request).
+     *   'L': TxAcked                  (The number of transmissions that were acked).
+     *   'L': TxNoAckRequested         (The number of transmissions without ack request).
+     *   'L': TxData                   (The number of transmitted data).
+     *   'L': TxDataPoll               (The number of transmitted data poll).
+     *   'L': TxBeacon                 (The number of transmitted beacon).
+     *   'L': TxBeaconRequest          (The number of transmitted beacon request).
+     *   'L': TxOther                  (The number of transmitted other types of frames).
+     *   'L': TxRetry                  (The number of retransmission times).
+     *   'L': TxErrCca                 (The number of CCA failure times).
+     *   'L': TxErrAbort               (The number of frame transmission failures due to abort error).
+     *   'L': TxErrBusyChannel         (The number of frames that were dropped due to a busy channel).
+     *   'L': TxDirectMaxRetryExpiry   (The number of expired retransmission retries for direct message).
+     *   'L': TxIndirectMaxRetryExpiry (The number of expired retransmission retries for indirect message).
+     *
+     * The receive structure includes:
+     *
+     *   'L': RxTotal                  (The total number of received packets).
+     *   'L': RxUnicast                (The total number of unicast packets received).
+     *   'L': RxBroadcast              (The total number of broadcast packets received).
+     *   'L': RxData                   (The number of received data).
+     *   'L': RxDataPoll               (The number of received data poll).
+     *   'L': RxBeacon                 (The number of received beacon).
+     *   'L': RxBeaconRequest          (The number of received beacon request).
+     *   'L': RxOther                  (The number of received other types of frames).
+     *   'L': RxAddressFiltered        (The number of received packets filtered by address filter
+     *                                  (whitelist or blacklist)).
+     *   'L': RxDestAddrFiltered       (The number of received packets filtered by destination check).
+     *   'L': RxDuplicated             (The number of received duplicated packets).
+     *   'L': RxErrNoFrame             (The number of received packets with no or malformed content).
+     *   'L': RxErrUnknownNeighbor     (The number of received packets from unknown neighbor).
+     *   'L': RxErrInvalidSrcAddr      (The number of received packets whose source address is invalid).
+     *   'L': RxErrSec                 (The number of received packets with security error).
+     *   'L': RxErrFcs                 (The number of received packets with FCS error).
+     *   'L': RxErrOther               (The number of received packets with other error).
+     *
+     * Writing to this property with any value would reset all MAC counters to zero.
+     *
+     */
+    SPINEL_PROP_CNTR_ALL_MAC_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 401,
+
+    /// Thread MLE counters.
+    /** Format: `SSSSSSSSS`
+     *
+     *   'S': DisabledRole                  (The number of times device entered OT_DEVICE_ROLE_DISABLED role).
+     *   'S': DetachedRole                  (The number of times device entered OT_DEVICE_ROLE_DETACHED role).
+     *   'S': ChildRole                     (The number of times device entered OT_DEVICE_ROLE_CHILD role).
+     *   'S': RouterRole                    (The number of times device entered OT_DEVICE_ROLE_ROUTER role).
+     *   'S': LeaderRole                    (The number of times device entered OT_DEVICE_ROLE_LEADER role).
+     *   'S': AttachAttempts                (The number of attach attempts while device was detached).
+     *   'S': PartitionIdChanges            (The number of changes to partition ID).
+     *   'S': BetterPartitionAttachAttempts (The number of attempts to attach to a better partition).
+     *   'S': ParentChanges                 (The number of times device changed its parents).
+     *
+     * Writing to this property with any value would reset all MLE counters to zero.
+     *
+     */
+    SPINEL_PROP_CNTR_MLE_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 402,
+
+    /// Thread IPv6 counters.
+    /** Format: `t(LL)t(LL)`
+     *
+     * The contents include two structs, first one corresponds to
+     * all transmit related MAC counters, second one provides the
+     * receive related counters.
+     *
+     * The transmit structure includes:
+     *   'L': TxSuccess (The number of IPv6 packets successfully transmitted).
+     *   'L': TxFailure (The number of IPv6 packets failed to transmit).
+     *
+     * The receive structure includes:
+     *   'L': RxSuccess (The number of IPv6 packets successfully received).
+     *   'L': RxFailure (The number of IPv6 packets failed to receive).
+     *
+     * Writing to this property with any value would reset all IPv6 counters to zero.
+     *
+     */
+    SPINEL_PROP_CNTR_ALL_IP_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 403,
+
+    /// MAC retry histogram.
+    /** Format: t(A(L))t(A(L))
+     *
+     * Required capability: SPINEL_CAP_MAC_RETRY_HISTOGRAM
+     *
+     * The contents include two structs, first one is histogram which corresponds to retransmissions number of direct
+     * messages, second one provides the histogram of retransmissions for indirect messages.
+     *
+     * The first structure includes:
+     *   'L': DirectRetry[0]                   (The number of packets after 0 retry).
+     *   'L': DirectRetry[1]                   (The number of packets after 1 retry).
+     *    ...
+     *   'L': DirectRetry[n]                   (The number of packets after n retry).
+     *
+     * The size of the array is OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_MAX_SIZE_COUNT_DIRECT.
+     *
+     * The second structure includes:
+     *   'L': IndirectRetry[0]                   (The number of packets after 0 retry).
+     *   'L': IndirectRetry[1]                   (The number of packets after 1 retry).
+     *    ...
+     *   'L': IndirectRetry[m]                   (The number of packets after m retry).
+     *
+     * The size of the array is OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_MAX_SIZE_COUNT_INDIRECT.
+     *
+     * Writing to this property with any value would reset MAC retry histogram.
+     *
+     */
+    SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM = SPINEL_PROP_CNTR__BEGIN + 404,
+
+    SPINEL_PROP_CNTR__END = 0x800,
+
+    SPINEL_PROP_RCP__BEGIN = 0x800,
+
+    /// MAC Key
+    /** Format: `CCddd`.
+     *
+     *  `C`: MAC key ID mode
+     *  `C`: MAC key ID
+     *  `d`: previous MAC key material data
+     *  `d`: current MAC key material data
+     *  `d`: next MAC key material data
+     *
+     * The Spinel property is used to set/get MAC key materials to and from RCP.
+     *
+     */
+    SPINEL_PROP_RCP_MAC_KEY = SPINEL_PROP_RCP__BEGIN + 0,
+
+    /// MAC Frame Counter
+    /** Format: `L`.
+     *
+     *  `L`: MAC frame counter
+     *
+     * The Spinel property is used to set MAC frame counter to RCP.
+     *
+     */
+    SPINEL_PROP_RCP_MAC_FRAME_COUNTER = SPINEL_PROP_RCP__BEGIN + 1,
+
+    /// Timestamps when Spinel frame is received and transmitted
+    /** Format: `X`.
+     *
+     *  `X`: Spinel frame transmit timestamp
+     *
+     * The Spinel property is used to get timestamp from RCP to calculate host and RCP timer difference.
+     *
+     */
+    SPINEL_PROP_RCP_TIMESTAMP = SPINEL_PROP_RCP__BEGIN + 2,
+
+    SPINEL_PROP_RCP__END = 0x900,
+
+    SPINEL_PROP_NEST__BEGIN = 0x3BC0,
+
+    SPINEL_PROP_NEST_STREAM_MFG = SPINEL_PROP_NEST__BEGIN + 0,
+
+    /// The legacy network ULA prefix (8 bytes)
+    /** Format: 'D' */
+    SPINEL_PROP_NEST_LEGACY_ULA_PREFIX = SPINEL_PROP_NEST__BEGIN + 1,
+
+    /// The EUI64 of last node joined using legacy protocol (if none, all zero EUI64 is returned).
+    /** Format: 'E' */
+    SPINEL_PROP_NEST_LEGACY_LAST_NODE_JOINED = SPINEL_PROP_NEST__BEGIN + 2,
+
+    SPINEL_PROP_NEST__END = 0x3C00,
+
+    SPINEL_PROP_VENDOR__BEGIN = 0x3C00,
+    SPINEL_PROP_VENDOR__END   = 0x4000,
+
+    SPINEL_PROP_DEBUG__BEGIN = 0x4000,
+
+    /// Testing platform assert
+    /** Format: 'b' (read-only)
+     *
+     * Reading this property will cause an assert on the NCP. This is intended for testing the assert functionality of
+     * underlying platform/NCP. Assert should ideally cause the NCP to reset, but if this is not supported a `false`
+     * boolean is returned in response.
+     *
+     */
+    SPINEL_PROP_DEBUG_TEST_ASSERT = SPINEL_PROP_DEBUG__BEGIN + 0,
+
+    /// The NCP log level.
+    /** Format: `C` */
+    SPINEL_PROP_DEBUG_NCP_LOG_LEVEL = SPINEL_PROP_DEBUG__BEGIN + 1,
+
+    /// Testing platform watchdog
+    /** Format: Empty  (read-only)
+     *
+     * Reading this property will causes NCP to start a `while(true) ;` loop and thus triggering a watchdog.
+     *
+     * This is intended for testing the watchdog functionality on the underlying platform/NCP.
+     *
+     */
+    SPINEL_PROP_DEBUG_TEST_WATCHDOG = SPINEL_PROP_DEBUG__BEGIN + 2,
+
+    /// The NCP timestamp base
+    /** Format: X (write-only)
+     *
+     * This property controls the time base value that is used for logs timestamp field calculation.
+     *
+     */
+    SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE = SPINEL_PROP_DEBUG__BEGIN + 3,
+
+    SPINEL_PROP_DEBUG__END = 0x4400,
+
+    SPINEL_PROP_EXPERIMENTAL__BEGIN = 2000000,
+    SPINEL_PROP_EXPERIMENTAL__END   = 2097152,
+};
+
+typedef uint32_t spinel_prop_key_t;
+
+// ----------------------------------------------------------------------------
+
+#define SPINEL_HEADER_FLAG 0x80
+
+#define SPINEL_HEADER_TID_SHIFT 0
+#define SPINEL_HEADER_TID_MASK (15 << SPINEL_HEADER_TID_SHIFT)
+
+#define SPINEL_HEADER_IID_SHIFT 4
+#define SPINEL_HEADER_IID_MASK (3 << SPINEL_HEADER_IID_SHIFT)
+
+#define SPINEL_HEADER_IID_0 (0 << SPINEL_HEADER_IID_SHIFT)
+#define SPINEL_HEADER_IID_1 (1 << SPINEL_HEADER_IID_SHIFT)
+#define SPINEL_HEADER_IID_2 (2 << SPINEL_HEADER_IID_SHIFT)
+#define SPINEL_HEADER_IID_3 (3 << SPINEL_HEADER_IID_SHIFT)
+
+#define SPINEL_HEADER_GET_IID(x) (((x)&SPINEL_HEADER_IID_MASK) >> SPINEL_HEADER_IID_SHIFT)
+#define SPINEL_HEADER_GET_TID(x) (spinel_tid_t)(((x)&SPINEL_HEADER_TID_MASK) >> SPINEL_HEADER_TID_SHIFT)
+
+#define SPINEL_GET_NEXT_TID(x) (spinel_tid_t)((x) >= 0xF ? 1 : (x) + 1)
+
+#define SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT 4
+
+#define SPINEL_BEACON_THREAD_FLAG_VERSION_MASK (0xf << SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT)
+
+#define SPINEL_BEACON_THREAD_FLAG_JOINABLE (1 << 0)
+
+#define SPINEL_BEACON_THREAD_FLAG_NATIVE (1 << 3)
+
+// ----------------------------------------------------------------------------
+
+enum
+{
+    SPINEL_DATATYPE_NULL_C        = 0,
+    SPINEL_DATATYPE_VOID_C        = '.',
+    SPINEL_DATATYPE_BOOL_C        = 'b',
+    SPINEL_DATATYPE_UINT8_C       = 'C',
+    SPINEL_DATATYPE_INT8_C        = 'c',
+    SPINEL_DATATYPE_UINT16_C      = 'S',
+    SPINEL_DATATYPE_INT16_C       = 's',
+    SPINEL_DATATYPE_UINT32_C      = 'L',
+    SPINEL_DATATYPE_INT32_C       = 'l',
+    SPINEL_DATATYPE_UINT64_C      = 'X',
+    SPINEL_DATATYPE_INT64_C       = 'x',
+    SPINEL_DATATYPE_UINT_PACKED_C = 'i',
+    SPINEL_DATATYPE_IPv6ADDR_C    = '6',
+    SPINEL_DATATYPE_EUI64_C       = 'E',
+    SPINEL_DATATYPE_EUI48_C       = 'e',
+    SPINEL_DATATYPE_DATA_WLEN_C   = 'd',
+    SPINEL_DATATYPE_DATA_C        = 'D',
+    SPINEL_DATATYPE_UTF8_C        = 'U', //!< Zero-Terminated UTF8-Encoded String
+    SPINEL_DATATYPE_STRUCT_C      = 't',
+    SPINEL_DATATYPE_ARRAY_C       = 'A',
+};
+
+typedef char spinel_datatype_t;
+
+#define SPINEL_DATATYPE_NULL_S ""
+#define SPINEL_DATATYPE_VOID_S "."
+#define SPINEL_DATATYPE_BOOL_S "b"
+#define SPINEL_DATATYPE_UINT8_S "C"
+#define SPINEL_DATATYPE_INT8_S "c"
+#define SPINEL_DATATYPE_UINT16_S "S"
+#define SPINEL_DATATYPE_INT16_S "s"
+#define SPINEL_DATATYPE_UINT32_S "L"
+#define SPINEL_DATATYPE_INT32_S "l"
+#define SPINEL_DATATYPE_UINT64_S "X"
+#define SPINEL_DATATYPE_INT64_S "x"
+#define SPINEL_DATATYPE_UINT_PACKED_S "i"
+#define SPINEL_DATATYPE_IPv6ADDR_S "6"
+#define SPINEL_DATATYPE_EUI64_S "E"
+#define SPINEL_DATATYPE_EUI48_S "e"
+#define SPINEL_DATATYPE_DATA_WLEN_S "d"
+#define SPINEL_DATATYPE_DATA_S "D"
+#define SPINEL_DATATYPE_UTF8_S "U" //!< Zero-Terminated UTF8-Encoded String
+
+#define SPINEL_DATATYPE_ARRAY_S(x) "A(" x ")"
+#define SPINEL_DATATYPE_STRUCT_S(x) "t(" x ")"
+
+#define SPINEL_DATATYPE_ARRAY_STRUCT_S(x) SPINEL_DATATYPE_ARRAY_S(SPINEL_DATATYPE_STRUCT_WLEN_S(x))
+
+#define SPINEL_DATATYPE_COMMAND_S                   \
+    SPINEL_DATATYPE_UINT8_S           /* header  */ \
+        SPINEL_DATATYPE_UINT_PACKED_S /* command */
+
+#define SPINEL_DATATYPE_COMMAND_PROP_S                    \
+    SPINEL_DATATYPE_COMMAND_S         /* prop command  */ \
+        SPINEL_DATATYPE_UINT_PACKED_S /* property id */
+
+#define SPINEL_MAX_UINT_PACKED 2097151
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_pack(uint8_t *     data_out,
+                                                      spinel_size_t data_len_max,
+                                                      const char *  pack_format,
+                                                      ...);
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_vpack(uint8_t *     data_out,
+                                                       spinel_size_t data_len_max,
+                                                       const char *  pack_format,
+                                                       va_list       args);
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_unpack(const uint8_t *data_in,
+                                                        spinel_size_t  data_len,
+                                                        const char *   pack_format,
+                                                        ...);
+/**
+ * This function parses spinel data similar to sscanf().
+ *
+ * This function actually calls spinel_datatype_vunpack_in_place() to parse data.
+ *
+ * @param[in]   data_in     A pointer to the data to parse.
+ * @param[in]   data_len    The length of @p data_in in bytes.
+ * @param[in]   pack_format C string that contains a format string follows the same specification of spinel.
+ * @param[in]   ...         Additional arguments depending on the format string @p pack_format.
+ *
+ * @returns The parsed length in bytes.
+ *
+ * @note This function behaves different from `spinel_datatype_unpack()`:
+ *       - This function expects composite data arguments of pointer to data type, while `spinel_datatype_unpack()`
+ *         expects them of pointer to data type pointer. For example, if `SPINEL_DATATYPE_EUI64_C` is present in
+ *         @p pack_format, this function expects a `spinel_eui64_t *` is included in variable arguments, while
+ *         `spinel_datatype_unpack()` expects a `spinel_eui64_t **` is included.
+ *       - For `SPINEL_DATATYPE_UTF8_C`, this function expects two arguments, the first of type `char *` and the
+ *         second is of type `size_t` to indicate length of the provided buffer in the first argument just like
+ *         `strncpy()`, while `spinel_datatype_unpack()` only expects a `const char **`.
+ *
+ * @sa spinel_datatype_vunpack_in_place()
+ *
+ */
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_unpack_in_place(const uint8_t *data_in,
+                                                                 spinel_size_t  data_len,
+                                                                 const char *   pack_format,
+                                                                 ...);
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_vunpack(const uint8_t *data_in,
+                                                         spinel_size_t  data_len,
+                                                         const char *   pack_format,
+                                                         va_list        args);
+/**
+ * This function parses spinel data similar to vsscanf().
+ *
+ * @param[in]   data_in     A pointer to the data to parse.
+ * @param[in]   data_len    The length of @p data_in in bytes.
+ * @param[in]   pack_format C string that contains a format string follows the same specification of spinel.
+ * @param[in]   args        A value identifying a variable arguments list.
+ *
+ * @returns The parsed length in bytes.
+ *
+ * @note This function behaves different from `spinel_datatype_vunpack()`:
+ *       - This function expects composite data arguments of pointer to data type, while `spinel_datatype_vunpack()`
+ *         expects them of pointer to data type pointer. For example, if `SPINEL_DATATYPE_EUI64_C` is present in
+ *         @p pack_format, this function expects a `spinel_eui64_t *` is included in variable arguments, while
+ *         `spinel_datatype_vunpack()` expects a `spinel_eui64_t **` is included.
+ *       - For `SPINEL_DATATYPE_UTF8_C`, this function expects two arguments, the first of type `char *` and the
+ *         second is of type `size_t` to indicate length of the provided buffer in the first argument just like
+ *         `strncpy()`, while `spinel_datatype_vunpack()` only expects a `const char **`.
+ *
+ * @sa spinel_datatype_unpack_in_place()
+ *
+ */
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_vunpack_in_place(const uint8_t *data_in,
+                                                                  spinel_size_t  data_len,
+                                                                  const char *   pack_format,
+                                                                  va_list        args);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_decode(const uint8_t *bytes,
+                                                           spinel_size_t  len,
+                                                           unsigned int * value_ptr);
+SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_encode(uint8_t *bytes, spinel_size_t len, unsigned int value);
+SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_size(unsigned int value);
+
+SPINEL_API_EXTERN const char *spinel_next_packed_datatype(const char *pack_format);
+
+// ----------------------------------------------------------------------------
+
+SPINEL_API_EXTERN const char *spinel_command_to_cstr(spinel_command_t command);
+
+SPINEL_API_EXTERN const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key);
+
+SPINEL_API_EXTERN const char *spinel_net_role_to_cstr(uint8_t net_role);
+
+SPINEL_API_EXTERN const char *spinel_mcu_power_state_to_cstr(uint8_t mcu_power_state);
+
+SPINEL_API_EXTERN const char *spinel_status_to_cstr(spinel_status_t status);
+
+SPINEL_API_EXTERN const char *spinel_capability_to_cstr(spinel_capability_t capability);
+
+// ----------------------------------------------------------------------------
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* defined(SPINEL_HEADER_INCLUDED) */
diff --git a/src/lib/spinel/spinel_buffer.cpp b/src/lib/spinel/spinel_buffer.cpp
new file mode 100644
index 0000000..c6869f2
--- /dev/null
+++ b/src/lib/spinel/spinel_buffer.cpp
@@ -0,0 +1,974 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements NCP frame buffer class.
+ */
+
+#include "spinel_buffer.hpp"
+
+#include "common/code_utils.hpp"
+#include "common/debug.hpp"
+
+namespace ot {
+namespace Spinel {
+
+const Buffer::FrameTag Buffer::kInvalidTag = nullptr;
+
+Buffer::Buffer(uint8_t *aBuffer, uint16_t aBufferLength)
+    : mBuffer(aBuffer)
+    , mBufferEnd(aBuffer + aBufferLength)
+    , mBufferLength(aBufferLength)
+{
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    for (uint8_t priority = 0; priority < kNumPrios; priority++)
+    {
+        otMessageQueueInit(&mMessageQueue[priority]);
+    }
+
+    otMessageQueueInit(&mWriteFrameMessageQueue);
+#endif
+
+    SetFrameAddedCallback(nullptr, nullptr);
+    SetFrameRemovedCallback(nullptr, nullptr);
+    Clear();
+}
+
+void Buffer::Clear(void)
+{
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    otMessage *message;
+#endif
+
+    // Write (InFrame) related variables
+    mWriteFrameStart[kPriorityLow]  = mBuffer;
+    mWriteFrameStart[kPriorityHigh] = GetUpdatedBufPtr(mBuffer, 1, kBackward);
+    mWriteDirection                 = kUnknown;
+    mWriteSegmentHead               = mBuffer;
+    mWriteSegmentTail               = mBuffer;
+    mWriteFrameTag                  = kInvalidTag;
+
+    // Read (OutFrame) related variables
+    mReadDirection   = kForward;
+    mReadState       = kReadStateNotActive;
+    mReadFrameLength = kUnknownFrameLength;
+
+    mReadFrameStart[kPriorityLow]  = mBuffer;
+    mReadFrameStart[kPriorityHigh] = GetUpdatedBufPtr(mBuffer, 1, kBackward);
+    mReadSegmentHead               = mBuffer;
+    mReadSegmentTail               = mBuffer;
+    mReadPointer                   = mBuffer;
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    mReadMessage       = nullptr;
+    mReadMessageOffset = 0;
+    mReadMessageTail   = mMessageBuffer;
+
+    // Free all messages in the queues.
+
+    while ((message = otMessageQueueGetHead(&mWriteFrameMessageQueue)) != nullptr)
+    {
+        otMessageQueueDequeue(&mWriteFrameMessageQueue, message);
+
+        // Note that messages associated with current (unfinished) input frame
+        // are not yet owned by the `Buffer` and therefore should not
+        // be freed.
+    }
+
+    for (uint8_t priority = 0; priority < kNumPrios; priority++)
+    {
+        while ((message = otMessageQueueGetHead(&mMessageQueue[priority])) != nullptr)
+        {
+            otMessageQueueDequeue(&mMessageQueue[priority], message);
+            otMessageFree(message);
+        }
+    }
+#endif
+}
+
+void Buffer::SetFrameAddedCallback(BufferCallback aFrameAddedCallback, void *aFrameAddedContext)
+{
+    mFrameAddedCallback = aFrameAddedCallback;
+    mFrameAddedContext  = aFrameAddedContext;
+}
+
+void Buffer::SetFrameRemovedCallback(BufferCallback aFrameRemovedCallback, void *aFrameRemovedContext)
+{
+    mFrameRemovedCallback = aFrameRemovedCallback;
+    mFrameRemovedContext  = aFrameRemovedContext;
+}
+
+// Returns an updated buffer pointer by moving forward/backward (based on `aDirection`) from `aBufPtr` by a given
+// offset. The resulting buffer pointer is ensured to stay within the `mBuffer` boundaries.
+uint8_t *Buffer::GetUpdatedBufPtr(uint8_t *aBufPtr, uint16_t aOffset, Direction aDirection) const
+{
+    uint8_t *ptr = aBufPtr;
+
+    switch (aDirection)
+    {
+    case kForward:
+        ptr += aOffset;
+
+        while (ptr >= mBufferEnd)
+        {
+            ptr -= mBufferLength;
+        }
+
+        break;
+
+    case kBackward:
+        ptr -= aOffset;
+
+        while (ptr < mBuffer)
+        {
+            ptr += mBufferLength;
+        }
+
+        break;
+
+    case kUnknown:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
+    }
+
+    return ptr;
+}
+
+// Gets the distance between two buffer pointers (adjusts for the wrap-around) given a direction (forward or backward).
+uint16_t Buffer::GetDistance(const uint8_t *aStartPtr, const uint8_t *aEndPtr, Direction aDirection) const
+{
+    size_t distance = 0;
+
+    switch (aDirection)
+    {
+    case kForward:
+
+        if (aEndPtr >= aStartPtr)
+        {
+            distance = static_cast<size_t>(aEndPtr - aStartPtr);
+        }
+        else
+        {
+            distance = static_cast<size_t>(mBufferEnd - aStartPtr);
+            distance += static_cast<size_t>(aEndPtr - mBuffer);
+        }
+
+        break;
+
+    case kBackward:
+
+        if (aEndPtr <= aStartPtr)
+        {
+            distance = static_cast<size_t>(aStartPtr - aEndPtr);
+        }
+        else
+        {
+            distance = static_cast<size_t>(mBufferEnd - aEndPtr);
+            distance += static_cast<size_t>(aStartPtr - mBuffer);
+        }
+
+        break;
+
+    case kUnknown:
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
+    }
+
+    return static_cast<uint16_t>(distance);
+}
+
+// Writes a uint16 value at the given buffer pointer (big-endian style).
+void Buffer::WriteUint16At(uint8_t *aBufPtr, uint16_t aValue, Direction aDirection)
+{
+    *aBufPtr                                  = (aValue >> 8);
+    *GetUpdatedBufPtr(aBufPtr, 1, aDirection) = (aValue & 0xff);
+}
+
+// Reads a uint16 value at the given buffer pointer (big-endian style).
+uint16_t Buffer::ReadUint16At(uint8_t *aBufPtr, Direction aDirection)
+{
+    uint16_t value;
+
+    value = static_cast<uint16_t>((*aBufPtr) << 8);
+    value += *GetUpdatedBufPtr(aBufPtr, 1, aDirection);
+
+    return value;
+}
+
+// Appends a byte at the write tail and updates the tail, discards the frame if buffer gets full.
+otError Buffer::InFrameAppend(uint8_t aByte)
+{
+    otError  error = OT_ERROR_NONE;
+    uint8_t *newTail;
+
+    OT_ASSERT(mWriteDirection != kUnknown);
+
+    newTail = GetUpdatedBufPtr(mWriteSegmentTail, 1, mWriteDirection);
+
+    // Ensure the `newTail` has not reached the `mWriteFrameStart` for other direction (other priority level).
+    if (newTail != mWriteFrameStart[(mWriteDirection == kForward) ? kBackward : kForward])
+    {
+        *mWriteSegmentTail = aByte;
+        mWriteSegmentTail  = newTail;
+    }
+    else
+    {
+        error = OT_ERROR_NO_BUFS;
+        InFrameDiscard();
+    }
+
+    return error;
+}
+
+// This method begins a new segment (if one is not already open).
+otError Buffer::InFrameBeginSegment(void)
+{
+    otError  error       = OT_ERROR_NONE;
+    uint16_t headerFlags = kSegmentHeaderNoFlag;
+
+    // Verify that segment is not yet started (i.e., head and tail are the same).
+    VerifyOrExit(mWriteSegmentHead == mWriteSegmentTail, OT_NOOP);
+
+    // Check if this is the start of a new frame (i.e., frame start is same as segment head).
+    if (mWriteFrameStart[mWriteDirection] == mWriteSegmentHead)
+    {
+        headerFlags |= kSegmentHeaderNewFrameFlag;
+    }
+
+    // Reserve space for the segment header.
+    for (uint16_t i = kSegmentHeaderSize; i; i--)
+    {
+        SuccessOrExit(error = InFrameAppend(0));
+    }
+
+    // Write the flags at the segment head.
+    WriteUint16At(mWriteSegmentHead, headerFlags, mWriteDirection);
+
+exit:
+    return error;
+}
+
+// This function closes/ends the current segment.
+void Buffer::InFrameEndSegment(uint16_t aSegmentHeaderFlags)
+{
+    uint16_t segmentLength;
+    uint16_t header;
+
+    segmentLength = GetDistance(mWriteSegmentHead, mWriteSegmentTail, mWriteDirection);
+
+    if (segmentLength >= kSegmentHeaderSize)
+    {
+        // Reduce the header size.
+        segmentLength -= kSegmentHeaderSize;
+
+        // Update the length and the flags in segment header (at segment head pointer).
+        header = ReadUint16At(mWriteSegmentHead, mWriteDirection);
+        header |= (segmentLength & kSegmentHeaderLengthMask);
+        header |= aSegmentHeaderFlags;
+        WriteUint16At(mWriteSegmentHead, header, mWriteDirection);
+
+        // Move the segment head to current tail (to be ready for a possible next segment).
+        mWriteSegmentHead = mWriteSegmentTail;
+    }
+    else
+    {
+        // Remove the current segment (move the tail back to head).
+        mWriteSegmentTail = mWriteSegmentHead;
+    }
+}
+
+// This method discards the current frame being written.
+void Buffer::InFrameDiscard(void)
+{
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    otMessage *message;
+#endif
+
+    VerifyOrExit(mWriteDirection != kUnknown, OT_NOOP);
+
+    // Move the write segment head and tail pointers back to frame start.
+    mWriteSegmentHead = mWriteSegmentTail = mWriteFrameStart[mWriteDirection];
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    while ((message = otMessageQueueGetHead(&mWriteFrameMessageQueue)) != nullptr)
+    {
+        otMessageQueueDequeue(&mWriteFrameMessageQueue, message);
+
+        // Note that messages associated with current (unfinished) input frame
+        // being discarded, are not yet owned by the `Buffer` and
+        // therefore should not be freed.
+    }
+#endif
+
+    mWriteDirection = kUnknown;
+
+exit:
+    UpdateReadWriteStartPointers();
+}
+
+// Returns `true` if in middle of writing a frame with given priority.
+bool Buffer::InFrameIsWriting(Priority aPriority) const
+{
+    return (mWriteDirection == static_cast<Direction>(aPriority));
+}
+
+void Buffer::InFrameBegin(Priority aPriority)
+{
+    // Discard any previous unfinished frame.
+    InFrameDiscard();
+
+    switch (aPriority)
+    {
+    case kPriorityHigh:
+        mWriteDirection = kBackward;
+        break;
+
+    case kPriorityLow:
+        mWriteDirection = kForward;
+        break;
+    }
+
+    // Set up the segment head and tail
+    mWriteSegmentHead = mWriteSegmentTail = mWriteFrameStart[mWriteDirection];
+}
+
+otError Buffer::InFrameFeedByte(uint8_t aByte)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
+
+    // Begin a new segment (if we are not in middle of segment already).
+    SuccessOrExit(error = InFrameBeginSegment());
+
+    error = InFrameAppend(aByte);
+
+exit:
+    return error;
+}
+
+otError Buffer::InFrameFeedData(const uint8_t *aDataBuffer, uint16_t aDataBufferLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
+
+    // Begin a new segment (if we are not in middle of segment already).
+    SuccessOrExit(error = InFrameBeginSegment());
+
+    // Write the data buffer
+    while (aDataBufferLength--)
+    {
+        SuccessOrExit(error = InFrameAppend(*aDataBuffer++));
+    }
+
+exit:
+    return error;
+}
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+otError Buffer::InFrameFeedMessage(otMessage *aMessage)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(aMessage != nullptr, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
+
+    // Begin a new segment (if we are not in middle of segment already).
+    SuccessOrExit(error = InFrameBeginSegment());
+
+    // Enqueue the message in the current write frame queue.
+    otMessageQueueEnqueue(&mWriteFrameMessageQueue, aMessage);
+
+    // End/Close the current segment marking the flag that it contains an associated message.
+    InFrameEndSegment(kSegmentHeaderMessageIndicatorFlag);
+
+exit:
+    return error;
+}
+#endif
+
+otError Buffer::InFrameGetPosition(WritePosition &aPosition)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
+
+    // Begin a new segment (if we are not in middle of segment already).
+    SuccessOrExit(error = InFrameBeginSegment());
+
+    aPosition.mPosition    = mWriteSegmentTail;
+    aPosition.mSegmentHead = mWriteSegmentHead;
+
+exit:
+    return error;
+}
+
+otError Buffer::InFrameOverwrite(const WritePosition &aPosition, const uint8_t *aDataBuffer, uint16_t aDataBufferLength)
+{
+    otError  error = OT_ERROR_NONE;
+    uint8_t *bufPtr;
+    uint16_t segmentLength;
+    uint16_t distance;
+
+    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
+
+    VerifyOrExit(aPosition.mSegmentHead == mWriteSegmentHead, error = OT_ERROR_INVALID_ARGS);
+
+    // Ensure the overwrite does not go beyond current segment tail.
+    segmentLength = GetDistance(mWriteSegmentHead, mWriteSegmentTail, mWriteDirection);
+    distance      = GetDistance(mWriteSegmentHead, aPosition.mPosition, mWriteDirection);
+    VerifyOrExit(distance + aDataBufferLength <= segmentLength, error = OT_ERROR_INVALID_ARGS);
+
+    bufPtr = aPosition.mPosition;
+    while (aDataBufferLength > 0)
+    {
+        *bufPtr = *aDataBuffer;
+
+        aDataBuffer++;
+        aDataBufferLength--;
+
+        bufPtr = GetUpdatedBufPtr(bufPtr, 1, mWriteDirection);
+    }
+
+exit:
+    return error;
+}
+
+uint16_t Buffer::InFrameGetDistance(const WritePosition &aPosition) const
+{
+    uint16_t distance = 0;
+    uint16_t segmentLength;
+    uint16_t offset;
+
+    VerifyOrExit(mWriteDirection != kUnknown, OT_NOOP);
+    VerifyOrExit(aPosition.mSegmentHead == mWriteSegmentHead, OT_NOOP);
+
+    segmentLength = GetDistance(mWriteSegmentHead, mWriteSegmentTail, mWriteDirection);
+    offset        = GetDistance(mWriteSegmentHead, aPosition.mPosition, mWriteDirection);
+    VerifyOrExit(offset < segmentLength, OT_NOOP);
+
+    distance = GetDistance(aPosition.mPosition, mWriteSegmentTail, mWriteDirection);
+
+exit:
+    return distance;
+}
+
+otError Buffer::InFrameReset(const WritePosition &aPosition)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t segmentLength;
+    uint16_t offset;
+
+    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(aPosition.mSegmentHead == mWriteSegmentHead, error = OT_ERROR_INVALID_ARGS);
+
+    segmentLength = GetDistance(mWriteSegmentHead, mWriteSegmentTail, mWriteDirection);
+    offset        = GetDistance(mWriteSegmentHead, aPosition.mPosition, mWriteDirection);
+    VerifyOrExit(offset < segmentLength, error = OT_ERROR_INVALID_ARGS);
+
+    mWriteSegmentTail = aPosition.mPosition;
+
+exit:
+    return error;
+}
+
+otError Buffer::InFrameEnd(void)
+{
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    otMessage *message;
+#endif
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
+
+    // End/Close the current segment (if any).
+    InFrameEndSegment(kSegmentHeaderNoFlag);
+
+    // Save and use the frame start pointer as the tag associated with the frame.
+    mWriteFrameTag = mWriteFrameStart[mWriteDirection];
+
+    // Update the frame start pointer to current segment head to be ready for next frame.
+    mWriteFrameStart[mWriteDirection] = mWriteSegmentHead;
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    // Move all the messages from the frame queue to the main queue.
+    while ((message = otMessageQueueGetHead(&mWriteFrameMessageQueue)) != nullptr)
+    {
+        otMessageQueueDequeue(&mWriteFrameMessageQueue, message);
+        otMessageQueueEnqueue(&mMessageQueue[mWriteDirection], message);
+    }
+#endif
+
+    if (mFrameAddedCallback != nullptr)
+    {
+        mFrameAddedCallback(mFrameAddedContext, mWriteFrameTag, static_cast<Priority>(mWriteDirection), this);
+    }
+
+    mWriteDirection = kUnknown;
+
+exit:
+    return error;
+}
+
+Buffer::FrameTag Buffer::InFrameGetLastTag(void) const
+{
+    return mWriteFrameTag;
+}
+
+bool Buffer::HasFrame(Priority aPriority) const
+{
+    return mReadFrameStart[aPriority] != mWriteFrameStart[aPriority];
+}
+
+bool Buffer::IsEmpty(void) const
+{
+    return !HasFrame(kPriorityHigh) && !HasFrame(kPriorityLow);
+}
+
+void Buffer::OutFrameSelectReadDirection(void)
+{
+    if (mReadState == kReadStateNotActive)
+    {
+        mReadDirection = HasFrame(kPriorityHigh) ? kBackward : kForward;
+    }
+}
+
+// Start/Prepare a new segment for reading.
+otError Buffer::OutFramePrepareSegment(void)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t header;
+
+    while (true)
+    {
+        // Go to the next segment (set the segment head to current segment's end/tail).
+        mReadSegmentHead = mReadSegmentTail;
+
+        // Ensure there is something to read (i.e. segment head is not at start of frame being written).
+        VerifyOrExit(mReadSegmentHead != mWriteFrameStart[mReadDirection], error = OT_ERROR_NOT_FOUND);
+
+        // Read the segment header.
+        header = ReadUint16At(mReadSegmentHead, mReadDirection);
+
+        // Check if this segment is the start of a frame.
+        if (header & kSegmentHeaderNewFrameFlag)
+        {
+            // Ensure that this segment is start of current frame, otherwise the current frame is finished.
+            VerifyOrExit(mReadSegmentHead == mReadFrameStart[mReadDirection], error = OT_ERROR_NOT_FOUND);
+        }
+
+        // Find tail/end of current segment.
+        mReadSegmentTail = GetUpdatedBufPtr(mReadSegmentHead, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask),
+                                            mReadDirection);
+
+        // Update the current read pointer to skip the segment header.
+        mReadPointer = GetUpdatedBufPtr(mReadSegmentHead, kSegmentHeaderSize, mReadDirection);
+
+        // Check if there are data bytes to be read in this segment (i.e. read pointer not at the tail).
+        if (mReadPointer != mReadSegmentTail)
+        {
+            // Update the state to `InSegment` and return.
+            mReadState = kReadStateInSegment;
+
+            ExitNow();
+        }
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+        // No data in this segment,  prepare any appended/associated message of this segment.
+        if (OutFramePrepareMessage() == OT_ERROR_NONE)
+        {
+            ExitNow();
+        }
+
+        // If there is no message (`PrepareMessage()` returned an error), loop back to prepare the next segment.
+#endif
+    }
+
+exit:
+
+    if (error != OT_ERROR_NONE)
+    {
+        mReadState = kReadStateDone;
+    }
+
+    return error;
+}
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+// This method prepares an associated message in current segment and fills the message buffer. It returns
+// ThreadError_NotFound if there is no message or if the message has no content.
+otError Buffer::OutFramePrepareMessage(void)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t header;
+
+    // Read the segment header
+    header = ReadUint16At(mReadSegmentHead, mReadDirection);
+
+    // Ensure that the segment header indicates that there is an associated message or return `NotFound` error.
+    VerifyOrExit((header & kSegmentHeaderMessageIndicatorFlag) != 0, error = OT_ERROR_NOT_FOUND);
+
+    // Update the current message from the queue.
+    mReadMessage = (mReadMessage == nullptr) ? otMessageQueueGetHead(&mMessageQueue[mReadDirection])
+                                             : otMessageQueueGetNext(&mMessageQueue[mReadDirection], mReadMessage);
+
+    VerifyOrExit(mReadMessage != nullptr, error = OT_ERROR_NOT_FOUND);
+
+    // Reset the offset for reading the message.
+    mReadMessageOffset = 0;
+
+    // Fill the content from current message into the message buffer.
+    SuccessOrExit(error = OutFrameFillMessageBuffer());
+
+    // If all successful, set the state to `InMessage`.
+    mReadState = kReadStateInMessage;
+
+exit:
+    return error;
+}
+
+// This method fills content from current message into the message buffer. It returns OT_ERROR_NOT_FOUND if no more
+// content in the current message.
+otError Buffer::OutFrameFillMessageBuffer(void)
+{
+    otError error = OT_ERROR_NONE;
+    int     readLength;
+
+    VerifyOrExit(mReadMessage != nullptr, error = OT_ERROR_NOT_FOUND);
+
+    VerifyOrExit(mReadMessageOffset < otMessageGetLength(mReadMessage), error = OT_ERROR_NOT_FOUND);
+
+    // Read portion of current message from the offset into message buffer.
+    readLength = otMessageRead(mReadMessage, mReadMessageOffset, mMessageBuffer, sizeof(mMessageBuffer));
+
+    VerifyOrExit(readLength > 0, error = OT_ERROR_NOT_FOUND);
+
+    // Update the message offset, set up the message tail, and set read pointer to start of message buffer.
+
+    mReadMessageOffset += readLength;
+
+    mReadMessageTail = mMessageBuffer + readLength;
+
+    mReadPointer = mMessageBuffer;
+
+exit:
+    return error;
+}
+#endif // #if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+
+otError Buffer::OutFrameBegin(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(!IsEmpty(), error = OT_ERROR_NOT_FOUND);
+
+    OutFrameSelectReadDirection();
+
+    // Move the segment head and tail to start of frame.
+    mReadSegmentHead = mReadSegmentTail = mReadFrameStart[mReadDirection];
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    mReadMessage = nullptr;
+#endif
+
+    // Prepare the current segment for reading.
+    error = OutFramePrepareSegment();
+
+exit:
+    return error;
+}
+
+bool Buffer::OutFrameHasEnded(void)
+{
+    return (mReadState == kReadStateDone) || (mReadState == kReadStateNotActive);
+}
+
+uint8_t Buffer::OutFrameReadByte(void)
+{
+    otError error;
+    uint8_t retval = kReadByteAfterFrameHasEnded;
+
+    switch (mReadState)
+    {
+    case kReadStateNotActive:
+
+        // Fall through
+
+    case kReadStateDone:
+
+        retval = kReadByteAfterFrameHasEnded;
+
+        break;
+
+    case kReadStateInSegment:
+
+        // Read a byte from current read pointer and move the read pointer by 1 byte in the read direction.
+        retval       = *mReadPointer;
+        mReadPointer = GetUpdatedBufPtr(mReadPointer, 1, mReadDirection);
+
+        // Check if at end of current segment.
+        if (mReadPointer == mReadSegmentTail)
+        {
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+            // Prepare any message associated with this segment.
+            error = OutFramePrepareMessage();
+#else
+            error = OT_ERROR_NOT_FOUND;
+#endif
+
+            // If there is no message, move to next segment (if any).
+            if (error != OT_ERROR_NONE)
+            {
+                IgnoreError(OutFramePrepareSegment());
+            }
+        }
+
+        break;
+
+    case kReadStateInMessage:
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+        // Read a byte from current read pointer and move the read pointer by 1 byte.
+        retval = *mReadPointer;
+        mReadPointer++;
+
+        // Check if at the end of content in message buffer.
+        if (mReadPointer == mReadMessageTail)
+        {
+            // Fill more bytes from current message into message buffer.
+            error = OutFrameFillMessageBuffer();
+
+            // If no more bytes in the message, move to next segment (if any).
+            if (error != OT_ERROR_NONE)
+            {
+                IgnoreError(OutFramePrepareSegment());
+            }
+        }
+#endif
+        break;
+    }
+
+    return retval;
+}
+
+uint16_t Buffer::OutFrameRead(uint16_t aReadLength, uint8_t *aDataBuffer)
+{
+    uint16_t bytesRead = 0;
+
+    for (bytesRead = 0; (bytesRead < aReadLength) && !OutFrameHasEnded(); bytesRead++)
+    {
+        *aDataBuffer++ = OutFrameReadByte();
+    }
+
+    return bytesRead;
+}
+
+otError Buffer::OutFrameRemove(void)
+{
+    otError  error = OT_ERROR_NONE;
+    uint8_t *bufPtr;
+    uint16_t header;
+    uint8_t  numSegments;
+    FrameTag tag;
+
+    VerifyOrExit(!IsEmpty(), error = OT_ERROR_NOT_FOUND);
+
+    OutFrameSelectReadDirection();
+
+    // Save the frame start pointer as the tag associated with the frame being removed.
+    tag = mReadFrameStart[mReadDirection];
+
+    // Begin at the start of current frame and move through all segments.
+
+    bufPtr      = mReadFrameStart[mReadDirection];
+    numSegments = 0;
+
+    while (bufPtr != mWriteFrameStart[mReadDirection])
+    {
+        // Read the segment header
+        header = ReadUint16At(bufPtr, mReadDirection);
+
+        // If the current segment defines a new frame, and it is not the start of current frame, then we have reached
+        // end of current frame.
+        if (header & kSegmentHeaderNewFrameFlag)
+        {
+            if (bufPtr != mReadFrameStart[mReadDirection])
+            {
+                break;
+            }
+        }
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+        // If current segment has an appended message, remove it from message queue and free it.
+        if (header & kSegmentHeaderMessageIndicatorFlag)
+        {
+            otMessage *message;
+
+            if ((message = otMessageQueueGetHead(&mMessageQueue[mReadDirection])) != nullptr)
+            {
+                otMessageQueueDequeue(&mMessageQueue[mReadDirection], message);
+                otMessageFree(message);
+            }
+        }
+#endif
+
+        // Move the pointer to next segment.
+        bufPtr = GetUpdatedBufPtr(bufPtr, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask), mReadDirection);
+
+        numSegments++;
+
+        // If this assert fails, it is a likely indicator that the internal structure of the NCP buffer has been
+        // corrupted.
+        OT_ASSERT(numSegments <= kMaxSegments);
+    }
+
+    mReadFrameStart[mReadDirection] = bufPtr;
+
+    UpdateReadWriteStartPointers();
+
+    mReadState       = kReadStateNotActive;
+    mReadFrameLength = kUnknownFrameLength;
+
+    if (mFrameRemovedCallback != nullptr)
+    {
+        mFrameRemovedCallback(mFrameRemovedContext, tag, static_cast<Priority>(mReadDirection), this);
+    }
+
+exit:
+    return error;
+}
+
+void Buffer::UpdateReadWriteStartPointers(void)
+{
+    // If there is no fully written high priority frame, and not in middle of writing a new frame either.
+    if (!HasFrame(kPriorityHigh) && !InFrameIsWriting(kPriorityHigh))
+    {
+        // Move the high priority pointers to be right behind the low priority start.
+        mWriteFrameStart[kPriorityHigh] = GetUpdatedBufPtr(mReadFrameStart[kPriorityLow], 1, kBackward);
+        mReadFrameStart[kPriorityHigh]  = mWriteFrameStart[kPriorityHigh];
+        ExitNow();
+    }
+
+    // If there is no fully written low priority frame, and not in middle of writing a new frame either.
+    if (!HasFrame(kPriorityLow) && !InFrameIsWriting(kPriorityLow))
+    {
+        // Move the low priority pointers to be 1 byte after the high priority start.
+        mWriteFrameStart[kPriorityLow] = GetUpdatedBufPtr(mReadFrameStart[kPriorityHigh], 1, kForward);
+        mReadFrameStart[kPriorityLow]  = mWriteFrameStart[kPriorityLow];
+    }
+
+exit:
+    return;
+}
+
+uint16_t Buffer::OutFrameGetLength(void)
+{
+    uint16_t frameLength = 0;
+    uint16_t header;
+    uint8_t *bufPtr;
+    uint8_t  numSegments;
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    otMessage *message = nullptr;
+#endif
+
+    // If the frame length was calculated before, return the previously calculated length.
+    VerifyOrExit(mReadFrameLength == kUnknownFrameLength, frameLength = mReadFrameLength);
+
+    VerifyOrExit(!IsEmpty(), frameLength = 0);
+
+    OutFrameSelectReadDirection();
+
+    // Calculate frame length by adding length of all segments and messages within the current frame.
+
+    bufPtr      = mReadFrameStart[mReadDirection];
+    numSegments = 0;
+
+    while (bufPtr != mWriteFrameStart[mReadDirection])
+    {
+        // Read the segment header
+        header = ReadUint16At(bufPtr, mReadDirection);
+
+        // If the current segment defines a new frame, and it is not the start of current frame, then we have reached
+        // end of current frame.
+        if (header & kSegmentHeaderNewFrameFlag)
+        {
+            if (bufPtr != mReadFrameStart[mReadDirection])
+            {
+                break;
+            }
+        }
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+        // If current segment has an associated message, add its length to frame length.
+        if (header & kSegmentHeaderMessageIndicatorFlag)
+        {
+            message = (message == nullptr) ? otMessageQueueGetHead(&mMessageQueue[mReadDirection])
+                                           : otMessageQueueGetNext(&mMessageQueue[mReadDirection], message);
+
+            if (message != nullptr)
+            {
+                frameLength += otMessageGetLength(message);
+            }
+        }
+#endif
+
+        // Add the length of current segment to the frame length.
+        frameLength += (header & kSegmentHeaderLengthMask);
+
+        // Move the pointer to next segment.
+        bufPtr = GetUpdatedBufPtr(bufPtr, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask), mReadDirection);
+
+        numSegments++;
+
+        // If this assert fails, it is a likely indicator that the internal structure of the NCP buffer has been
+        // corrupted.
+        OT_ASSERT(numSegments <= kMaxSegments);
+    }
+
+    // Remember the calculated frame length for current active frame.
+    if (mReadState != kReadStateNotActive)
+    {
+        mReadFrameLength = frameLength;
+    }
+
+exit:
+    return frameLength;
+}
+
+Buffer::FrameTag Buffer::OutFrameGetTag(void)
+{
+    OutFrameSelectReadDirection();
+
+    // If buffer is empty use `kInvalidTag`, otherwise use the frame start pointer as the tag associated with
+    // current out frame being read
+
+    return IsEmpty() ? kInvalidTag : mReadFrameStart[mReadDirection];
+}
+
+} // namespace Spinel
+} // namespace ot
diff --git a/src/lib/spinel/spinel_buffer.hpp b/src/lib/spinel/spinel_buffer.hpp
new file mode 100644
index 0000000..2c216ce
--- /dev/null
+++ b/src/lib/spinel/spinel_buffer.hpp
@@ -0,0 +1,660 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file contains definitions for the NCP frame buffer class.
+ */
+
+#ifndef NCP_FRAME_BUFFER_HPP_
+#define NCP_FRAME_BUFFER_HPP_
+
+#include "openthread-spinel-config.h"
+
+#include <openthread/message.h>
+
+namespace ot {
+namespace Spinel {
+
+/**
+ * This class implements a buffer/queue for storing Ncp frames.
+ *
+ * A frame can consist of a sequence of data bytes and/or the content of an `otMessage` or a combination of the two.
+ * `Buffer` implements priority FIFO logic for storing and reading frames. Two priority levels of high and low
+ * are supported. Within same priority level first-in-first-out order is preserved. High priority frames are read
+ * ahead of any low priority ones.
+ *
+ */
+class Buffer
+{
+    friend class Encoder;
+
+public:
+    /**
+     * Defines the priority of a frame. High priority frames are read before low priority frames. Within same priority
+     * level FIFO order is preserved.
+     *
+     */
+    enum Priority
+    {
+        kPriorityLow  = 0, //< Indicates low/normal priority for a frame.
+        kPriorityHigh = 1, //< Indicates high priority for a frame.
+    };
+
+    /**
+     * Defines the (abstract) frame tag type. The tag is a unique value (within currently queued frames) associated
+     * with a frame in the `Buffer`. Frame tags can be compared with one another using operator `==`.
+     *
+     */
+    typedef const void *FrameTag;
+
+    /**
+     * Defines the tag value indicating an invalid tag (e.g., when there is no frame).
+     *
+     */
+    static const FrameTag kInvalidTag;
+
+    /**
+     * Defines the structure to hold a write position for an input frame (frame being written).
+     *
+     * It should be considered as an opaque data structure to users of `Buffer`.
+     *
+     */
+    struct WritePosition
+    {
+    public:
+        /**
+         * The constructor for a `WritePosition` object.
+         *
+         */
+        WritePosition(void)
+            : mPosition(0)
+            , mSegmentHead(0)
+        {
+        }
+
+    private:
+        uint8_t *mPosition;    //< Pointer into buffer corresponding to saved write position.
+        uint8_t *mSegmentHead; //< Pointer to segment head.
+
+        friend class Buffer;
+    };
+
+    /**
+     * Defines a function pointer callback which is invoked to inform a change in `Buffer` either when a new
+     * frame is added/written to `Buffer` or when a frame is removed from `Buffer`.
+     *
+     * @param[in] aContext              A pointer to arbitrary context information.
+     * @param[in] aTag                  The tag associated with the frame which is added or removed.
+     * @param[in] aPriority             The priority of frame.
+     * @param[in] aBuffer               A pointer to the `Buffer`.
+     *
+     */
+    typedef void (*BufferCallback)(void *aContext, FrameTag aTag, Priority aPriority, Buffer *aBuffer);
+
+    /**
+     * This constructor initializes an NCP frame buffer.
+     *
+     * @param[in] aBuffer               A pointer to a buffer which will be used by NCP frame buffer.
+     * @param[in] aBufferLength         The buffer size (in bytes).
+     *
+     */
+    Buffer(uint8_t *aBuffer, uint16_t aBufferLength);
+
+    /**
+     * This method clears the NCP frame buffer. All the frames are cleared/removed.
+     *
+     */
+    void Clear(void);
+
+    /**
+     * This method sets the FrameAdded callback and its context.
+     *
+     * Subsequent calls to this method will overwrite the previous callback and its context.
+     *
+     * @param[in] aFrameAddedCallback   Callback invoked when a new frame is successfully added to buffer.
+     * @param[in] aFrameAddedContext    A pointer to arbitrary context used with frame added callback.
+     *
+     */
+    void SetFrameAddedCallback(BufferCallback aFrameAddedCallback, void *aFrameAddedContext);
+
+    /**
+     * This method sets the FrameRemoved callback and its context.
+     *
+     * Subsequent calls to this method will overwrite the previous callback and its context.
+     *
+     * @param[in] aFrameRemovedCallback Callback invoked when a frame is removed from buffer.
+     * @param[in] aFrameRemovedContext  A pointer to arbitrary context used with frame removed callback.
+     *
+     */
+    void SetFrameRemovedCallback(BufferCallback aFrameRemovedCallback, void *aFrameRemovedContext);
+
+    /**
+     * This method begins a new input frame (InFrame) to be added/written to the frame buffer.
+
+     * If there is a previous frame being written (for which `InFrameEnd()` has not yet been called), calling
+     * `InFrameBegin()` will discard and clear the previous unfinished frame.
+     *
+     * @param[in] aPriority             Priority level of the new input frame.
+     *
+     */
+    void InFrameBegin(Priority aPriority);
+
+    /**
+     * This method adds a single byte to current input frame.
+     *
+     * Before using this method `InFrameBegin()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aByte                The byte value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given byte to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
+     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
+     *
+     */
+    otError InFrameFeedByte(uint8_t aByte);
+
+    /**
+     * This method adds data to the current input frame.
+     *
+     * Before using this method `InFrameBegin()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aDataBuffer          A pointer to data buffer.
+     * @param[in]  aDataBufferLength    The length of the data buffer.
+     *
+     * @retval OT_ERROR_NONE            Successfully added new data to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add data.
+     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
+     *
+     */
+    otError InFrameFeedData(const uint8_t *aDataBuffer, uint16_t aDataBufferLength);
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    /**
+     * This method adds a message to the current input frame.
+     *
+     * Before using this method `InFrameBegin()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the frame and return error status
+     * `OT_ERROR_NO_BUFS`.
+     *
+     * The ownership of the passed-in message @p aMessage changes to `Buffer` ONLY when the entire frame is
+     * successfully finished (i.e., with a successful call to `InFrameEnd()` for the current input frame), and in this
+     * case the `otMessage` instance will be freed once the frame is removed (using `OutFrameRemove()`) from NCP buffer.
+     * However, if the input frame gets discarded before it is finished (e.g., running out of buffer space), the
+     * `otMessage` instance remains unchanged.
+     *
+     * @param[in] aMessage              A message to be added to current frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added the message to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the message.
+     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
+     * @retval OT_ERROR_INVALID_ARGS    If @p aMessage is nullptr.
+     *
+     */
+    otError InFrameFeedMessage(otMessage *aMessage);
+#endif
+
+    /**
+     * This method gets the current write position in the input frame.
+     *
+     * The write position is returned in @p aPosition. The saved position can later be used to overwrite the frame
+     * content (using `InFrameOverwrite()`) or discard a portion of written frame and move the write pointer back to
+     * the saved position (using `InFrameReset()`).
+     *
+     * @param[out] aPosition            A reference to a `WritePosition` to save the current write position.
+     *
+     * @retval OT_ERROR_NONE            Successfully saved current write position in @p aPosition.
+     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
+     *
+     */
+    otError InFrameGetPosition(WritePosition &aPosition);
+
+    /**
+     * This method overwrites the previously written content in the current input frame at a given write position.
+     *
+     * The write position @p aPostion must belong to the same input frame saved earlier with `InFrameGetPosition()`.
+     * This method does not allow writing beyond the current end of the input frame (i.e., it can only write over
+     * previously added content). If writing @p aDataBufferLength bytes from write position @p aPosition goes beyond
+     * the end, this method does not change the input frame and returns error status `OT_ERROR_INVALID_ARGS`.
+     * This method cannot be used if the input frame has an added `otMessage` (i.e., a previous call to
+     * `InFrameFeedMessage()`).
+     *
+     * @param[in] aPosition             A reference to the write position.
+     * @param[in] aDataBuffer           A pointer to data buffer.
+     * @param[in] aDataBufferLength     The length of the data buffer.
+     *
+     * @retval OT_ERROR_NONE            Successfully overwrote the data at the given write position.
+     * @retval OT_ERROR_INVALID_STATE   No input frame (`InFrameBegin()` has not been called).
+     * @retval OT_ERROR_INVALID_ARGS    The given write position is not valid (i.e., if it does not belong to same
+     *                                  input frame), or the input frame has an added `otMessage`, or the write
+     *                                  operation will go beyond the current end of the input frame.
+     *
+     */
+    otError InFrameOverwrite(const WritePosition &aPosition, const uint8_t *aDataBuffer, uint16_t aDataBufferLength);
+
+    /**
+     * This method resets the write position of input frame back to a previously saved position. Any previously
+     * added content after the write position is discarded.
+     *
+     * The write position @p aPosition must belong to the same input frame saved earlier with `InFrameGetPosition()`.
+     * This method cannot be used if the input frame has an added `otMessage` (i.e., a previous call to
+     * `InFrameFeedMessage()`).
+     *
+     * @param[in] aPosition             A reference to write position
+     *
+     * @retval OT_ERROR_NONE            Successfully reset the write position of current input frame..
+     * @retval OT_ERROR_INVALID_STATE   No input frame (`InFrameBegin()` has not been called).
+     * @retval OT_ERROR_INVALID_ARGS    The given write position is not valid (does not belong to same input frame), or
+     *                                  the input frame has an added `otMessage`.
+     *
+     */
+    otError InFrameReset(const WritePosition &aPosition);
+
+    /**
+     * This method gets the distance (number of bytes) from a given saved position to current end of frame.
+     *
+     * The write position @p aPosition must belong to the same input frame saved earlier with `InFrameGetPosition()`.
+     * This method cannot be used if the input frame has an added `otMessage` (i.e., a previous call to
+     * `InFrameFeedMessage()`). In case of invalid argument, this method returns zero.
+     *
+     * @param[in] aPosition             A reference to write position
+     *
+     * @returns The distance (number of bytes) from a write position to current end of frame, or zero for invalid
+     *          arguments.
+     *
+     */
+    uint16_t InFrameGetDistance(const WritePosition &aPosition) const;
+
+    /**
+     * This method finalizes/ends the current input frame being written to the buffer.
+     *
+     * Before using this method `InFrameBegin()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the frame and return error status
+     * `OT_ERROR_NO_BUFS`.
+     *
+     * @retval OT_ERROR_NONE            Successfully ended the input frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add message.
+     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
+     *
+     */
+    otError InFrameEnd(void);
+
+    /**
+     * This method returns the tag assigned to last successfully written/added frame to NcpBuffer (i.e., last input
+     * frame for which `InFrameEnd()` was called and returned success status). The tag is a unique value (within
+     * currently queued frames) associated with a frame in the `Buffer`. The tag can be used to identify the
+     * same frame when it is read and removed from the NcpBuffer. Tags can be compared using operator `==`.
+     *
+     * @returns The tag of the last successfully written frame, or `kInvalidTag` if no frame is written so far.
+     */
+    FrameTag InFrameGetLastTag(void) const;
+
+    /**
+     * This method checks if the buffer is empty. A non-empty buffer contains at least one full frame for reading.
+     *
+     * @retval TRUE                     Buffer is not empty and contains at least one full frame for reading.
+     * @retval FALSE                    Buffer is empty and contains no frame for reading.
+     *
+     */
+    bool IsEmpty(void) const;
+
+    /**
+     * This method begins/prepares an output frame to be read from the frame buffer if there is no current active output
+     * frame, or resets the read offset if there is a current active output frame.
+     *
+     * The NCP buffer maintains a read offset for the current frame being read. Before reading any bytes from the frame
+     * this method should be called to prepare the frame and set the read offset.
+     *
+     * If part or even all of current frame has been read, a sub-sequent call to this method  will reset the read
+     * offset back to beginning of current output frame (note that the current output frame will remain unchanged even
+     * in case where a higher priority frame was written to buffer while reading current output frame). A prepared
+     * output frame will stay active as current output frame until it is explicitly removed using `OutFrameRemove()`.
+     *
+     * @retval OT_ERROR_NONE            Successfully started/prepared a new output frame for reading.
+     * @retval OT_ERROR_NOT_FOUND       No frame available in buffer for reading.
+     *
+     */
+    otError OutFrameBegin(void);
+
+    /**
+     * This method checks if the current output frame (being read) has ended.
+     *
+     * The NCP buffer maintains a read offset for the current output frame being read. This method returns `true` if
+     * the read offset has reached the end of the frame and there are no more bytes available to read, or if there is
+     * no currently active output frame.
+     *
+     * @retval TRUE                     Frame has ended (no more bytes available to read from current output frame), or
+     *                                  there is currently no prepared/active output frame.
+     * @retval FALSE                    Frame still has more data to read.
+     *
+     */
+    bool OutFrameHasEnded(void);
+
+    /**
+     * This method reads and returns the next byte from the current output frame.
+     *
+     * The NCP buffer maintains a read offset for the current output frame being read. This method reads and returns
+     * the next byte from the current frame and moves the read offset forward. If read offset is already at the end
+     * current output frame, this method returns zero.
+     *
+     * @returns The next byte from the current output frame or zero if current output frame has ended or there is
+     * prepared/active output from.
+     *
+     */
+    uint8_t OutFrameReadByte(void);
+
+    /**
+     * This method reads and copies bytes from the current output frame into a given buffer.
+     *
+     * The NCP buffer maintains a read offset for the current output frame being read. This method attempts to read
+     * the given number of bytes (@p aDataBufferLength) from the current frame and copies the bytes into the given
+     * data buffer (@p aDataBuffer). It also moves the read offset forward accordingly. If there are fewer bytes
+     * remaining in current frame than the requested @p aReadLength, the available bytes are read/copied. This methods
+     * returns the number of bytes read from frame and copied into @p aDataBuffer.
+     *
+     * @param[in]  aDataBuffer          A pointer to a data buffer.
+     * @param[in]  aReadLength          Number of bytes to read.
+     *
+     * @returns The number of bytes read and copied into data buffer.
+     *
+     */
+    uint16_t OutFrameRead(uint16_t aReadLength, uint8_t *aDataBuffer);
+
+    /**
+     * This method removes the current or front output frame from the buffer.
+     *
+     * If there is an active output from being read (an output frame was prepared earlier with a successful call to
+     * `OutFrameBegin()`), this method removes the current active output frame. If there is no current active frame,
+     * the front frame in the queue (the next frame which would have been read) will be removed.
+     *
+     * When a frame is removed all its associated messages will be freed.
+     *
+     * If the remove operation is successful, this method will invoke the `FrameRemovedCallback` (if not nullptr) before
+     * returning the success state.
+     *
+     * @retval OT_ERROR_NONE            Successfully removed the front frame.
+     * @retval OT_ERROR_NOT_FOUND       No frame available in NCP frame buffer to remove.
+     *
+     */
+    otError OutFrameRemove(void);
+
+    /**
+     * This method returns the number of bytes (length) of current or front frame in the NCP frame buffer.
+     *
+     * If there is an active output from being read (an output frame was prepared earlier with successful call to
+     * `OutFrameBegin()`), this method returns the length of the current output frame. If there is no current active
+     * frame, the length of the front frame in the queue (the next frame which would have been read) will be returned.
+     *
+     * If there is no frame in buffer, this method returns zero.
+     *
+     * @returns The number of bytes (length) of current/front frame, or zero if no frame in buffer.
+     *
+     */
+    uint16_t OutFrameGetLength(void);
+
+    /**
+     * This method returns the tag value associated to current or front frame in the NCP frame buffer.
+     *
+     * If there is an active output from being read (an output frame was prepared earlier with successful call to
+     * `OutFrameBegin()`), this method returns the tag associated with current output frame. If there is no current
+     * active frame, the tag associated with the front frame in the queue (the next frame which would have been read)
+     * will be returned.
+     *
+     * If there is no frame in buffer, this method returns `kInvalidTag`.
+     *
+     * @returns The tag assigned to the current/from output frame, or `kInvalidTag` if no frame in buffer.
+     *
+     */
+    FrameTag OutFrameGetTag(void);
+
+private:
+    /*
+     * `Buffer` Implementation
+     * -------------------------------
+     *
+     * `Buffer` internally stores a frame as a sequence of data segments. Each segment stores a portion of
+     * frame. The data segments are stored in the main buffer `mBuffer`. `mBuffer` is utilized as a circular buffer.
+
+     * The content of messages (which are added using `InFrameFeedMessage()`) are not directly copied in the `mBuffer`
+     * but instead they are enqueued in a message queue `mMessageQueue`.
+     *
+     * Every data segments starts with a header before the data portion. The header is 2 bytes long with the following
+     * format:
+     *
+     *    Bit 0-13: Give the length of the data segment (max segment len is 2^14 = 16,384 bytes).
+     *    Bit 14:   Flag bit set to indicate that this segment has an associated `Message` (appended to its end).
+     *    Bit 15:   Flag bit set to indicate that this segment defines the start of a new frame.
+     *
+     *        Bit  15         Bit 14                     Bits: 0 - 13
+     *    +--------------+--------------+--------------------------------------------------------+
+     *    |   New Frame  |  Has Message |  Length of segment (excluding the header)              |
+     *    +--------------+--------------+--------------------------------------------------------+
+     *
+     * The header is encoded in big-endian (msb first) style.
+
+     * Consider the following calls to create a frame:
+     *
+     *    ncpBuffer.InFrameBegin();
+     *    ncpBuffer.InFrameFeedData("Hello", 5);
+     *    ncpBuffer.InFrameFeedData("There", 5);
+     *    ncpBuffer.InFrameFeedMessage(*someMessage);
+     *    ncpBuffer.InFrameFeedData("Bye", 3);
+     *    ncpBuffer.InFrameEnd();
+     *
+     * This frame is stored as two segments:
+     *
+     *    - Segment #1 contains "HelloThere" with a header value `0xC00A` which shows that this segment contains 10
+     *      data bytes, and it starts a new frame, and also includes an appended message from the message queue.
+     *
+     *    - Segment #2 contains "Bye" with a header value of `0x0003` showing length of 3 and no appended message.
+     *
+     *    +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+     *    | C0  | 0A  | 'H' | 'e' | 'l' | 'l' | 'o' | 'T' | 'h' | 'e' | 'r' | 'e' | 00  | 03  | 'B' | 'y' | 'e' |
+     *    +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+     *     \         /                                                             \         /
+     *   Segment #1 Header                                                      Segment #2 Header
+     *
+     *
+     * `Buffer` uses the `mBuffer` as a circular/ring buffer. To support two frame priorities the buffer is
+     * divided into two high-priority and low-priority regions. The high priority frames are stored in buffer in
+     * backward direction while the low-priority frames use the buffer in forward direction. This model ensures the
+     * available buffer space is utilized efficiently between all frame types.
+     *
+     *                                       mReadFrameStart[kPriorityLow]
+     *                                                 |
+     *                                                 |                   mWriteFrameStart[kPriorityLow]
+     *                                                 |                              |
+     *                                                 V    Low Priority Frames       V
+     *   --------------+------------------------------+------------------------------+------------------
+     *             ... |        <--------             |         -------->            | ...
+     *   --------------+------------------------------+------------------------------+------------------
+     *                ^       High Priority Frames   ^
+     *                |                              |
+     *                |                    mReadFrameStart[kPriorityHigh]
+     *                |
+     *          mWriteFrameStart[kPriorityHigh]
+     *
+     *
+     *
+     * When frames are removed, if possible, the `mReadFrameStart` and `mWriteFrameStart` pointers of the two priority
+     * levels are moved closer to avoid gaps.
+     *
+     * For an output frame (frame being read), Buffer maintains a `ReadState` along with a set of pointers
+     * into the buffer:
+     *
+     *             mReadFrameStart[priority]: Start of the current/front frame.
+     *             |
+     *             |            mReadSegmentHead: Start of the current segment.
+     *             |            |
+     *             |            |              mReadPointer: Pointer to the next byte to read.
+     *             |            |              |
+     *             |            |              |           mReadSegmentTail: End of the current segment.
+     *             |            |              |           |
+     *             V            V              V           V
+     *   ---------+------------+--------------------------+------+----------------+-----------------------------------
+     *       ...  | Segment 1  | Segment  2               | ...  | Last Segment   | ... (possible) next frame
+     *   ---------+------------+--------------------------+------+----------------+-----------------------------------
+     *             \           |                         |                       /
+     *              |          \------------v-----------/                       |
+     *              |                   Current Segment                         |
+     *              |                                                           |
+     *               \---------------------------V-----------------------------/
+     *                              Current OutFrame (being read)
+     *
+     * Note that the diagram above shows the pointers for a low-priority frame (with pointers increasing in forward
+     * direction).
+     *
+     * The `ReadState` indicates the state of current output frame and its read offset (e.g., if read offset is in
+     * middle of a segment or if it is is middle of an appended message, or if we are done with entire frame).
+     *
+     * For an input frame (frame being written), the following pointers are maintained:
+     *
+     *            mWriteFrameWrite[priority]: Start of the current/next frame being written.
+     *                       |
+     *                       |      mWriteSegmentHead: Start of the current segment of the active input frame.
+     *                       |                 |
+     *                       |                 |   mWriteSegmentTail: Pointer to the next byte to write.
+     *                       |                 |                       |
+     *                       |                 |                       |
+     *                       |                 |                       |
+     *                       V                 V                       V
+     *    ------------------+------------------+-------------------------------------------------------------------
+     *    Previous Frames   | Segment 1        | Segment  2            : . . .
+     *    ------------------+------------------+-------------------------------------------------------------------
+     *                       \                                        /
+     *                        |                                      |
+     *                         \------------------V-----------------/
+     *                             Current InFrame (being written)
+     *
+     *
+     */
+
+    enum
+    {
+        kReadByteAfterFrameHasEnded = 0,      // Value returned by ReadByte() when frame has ended.
+        kMessageReadBufferSize      = 16,     // Size of message buffer array `mMessageBuffer`.
+        kUnknownFrameLength         = 0xffff, // Value used when frame length is unknown.
+        kSegmentHeaderSize          = 2,      // Length of the segment header.
+        kSegmentHeaderLengthMask    = 0x3fff, // Bit mask to get the length from the segment header
+        kMaxSegments                = 10,     // Max number of segments allowed in a frame
+
+        kSegmentHeaderNoFlag               = 0,         // No flags are set.
+        kSegmentHeaderNewFrameFlag         = (1 << 15), // Indicates that this segment starts a new frame.
+        kSegmentHeaderMessageIndicatorFlag = (1 << 14), // Indicates this segment ends with a Message.
+
+        kNumPrios = (kPriorityHigh + 1), // Number of priorities.
+    };
+
+    enum ReadState
+    {
+        kReadStateNotActive, // No current prepared output frame.
+        kReadStateInSegment, // In middle of a data segment while reading current frame.
+        kReadStateInMessage, // In middle of a message while reading current frame.
+        kReadStateDone,      // Current output frame is read fully.
+    };
+
+    enum Direction
+    {
+        kForward  = kPriorityLow,
+        kBackward = kPriorityHigh,
+        kUnknown,
+    };
+
+    uint8_t *GetUpdatedBufPtr(uint8_t *aBufPtr, uint16_t aOffset, Direction aDirection) const;
+    uint16_t GetDistance(const uint8_t *aStartPtr, const uint8_t *aEndPtr, Direction aDirection) const;
+
+    uint16_t ReadUint16At(uint8_t *aBufPtr, Direction aDirection);
+    void     WriteUint16At(uint8_t *aBufPtr, uint16_t aValue, Direction aDirection);
+
+    bool HasFrame(Priority aPriority) const;
+    void UpdateReadWriteStartPointers(void);
+
+    otError InFrameAppend(uint8_t aByte);
+    otError InFrameBeginSegment(void);
+    void    InFrameEndSegment(uint16_t aSegmentHeaderFlags);
+    void    InFrameDiscard(void);
+    bool    InFrameIsWriting(Priority aPriority) const;
+
+    void    OutFrameSelectReadDirection(void);
+    otError OutFramePrepareSegment(void);
+    void    OutFrameMoveToNextSegment(void);
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    otError OutFramePrepareMessage(void);
+    otError OutFrameFillMessageBuffer(void);
+#endif
+
+    uint8_t *const mBuffer;       // Pointer to the buffer used to store the data.
+    uint8_t *const mBufferEnd;    // Points to after the end of buffer.
+    const uint16_t mBufferLength; // Length of the buffer.
+
+    BufferCallback mFrameAddedCallback;   // Callback to signal when a new frame is added
+    void *         mFrameAddedContext;    // Context passed to `mFrameAddedCallback`.
+    BufferCallback mFrameRemovedCallback; // Callback to signal when a frame is removed.
+    void *         mFrameRemovedContext;  // Context passed to `mFrameRemovedCallback`.
+
+    Direction mWriteDirection;             // Direction (priority) for current frame being read.
+    uint8_t * mWriteFrameStart[kNumPrios]; // Pointer to start of current frame being written.
+    uint8_t * mWriteSegmentHead;           // Pointer to start of current segment in the frame being written.
+    uint8_t * mWriteSegmentTail;           // Pointer to end of current segment in the frame being written.
+    FrameTag  mWriteFrameTag;              // Tag associated with last successfully written frame.
+
+    Direction mReadDirection;   // Direction (priority) for current frame being read.
+    ReadState mReadState;       // Read state.
+    uint16_t  mReadFrameLength; // Length of current frame being read.
+
+    uint8_t *mReadFrameStart[kNumPrios]; // Pointer to start of current frame being read.
+    uint8_t *mReadSegmentHead;           // Pointer to start of current segment in the frame being read.
+    uint8_t *mReadSegmentTail;           // Pointer to end of current segment in the frame being read.
+    uint8_t *mReadPointer;               // Pointer to next byte to read (either in segment or in msg buffer).
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    otMessageQueue mWriteFrameMessageQueue;                // Message queue for the current frame being written.
+    otMessageQueue mMessageQueue[kNumPrios];               // Main message queues.
+    otMessage *    mReadMessage;                           // Current Message in the frame being read.
+    uint16_t       mReadMessageOffset;                     // Offset within current message being read.
+    uint8_t        mMessageBuffer[kMessageReadBufferSize]; // Buffer to hold part of current message being read.
+    uint8_t *      mReadMessageTail;                       // Pointer to end of current part in mMessageBuffer.
+#endif
+};
+
+} // namespace Spinel
+} // namespace ot
+
+#endif // NCP_FRAME_BUFFER_HPP_
diff --git a/src/lib/spinel/spinel_decoder.cpp b/src/lib/spinel/spinel_decoder.cpp
new file mode 100644
index 0000000..1d36c38
--- /dev/null
+++ b/src/lib/spinel/spinel_decoder.cpp
@@ -0,0 +1,396 @@
+/*
+ *    Copyright (c) 2017, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements a spinel decoder.
+ */
+
+#include "spinel_decoder.hpp"
+
+#include "common/code_utils.hpp"
+#include "common/string.hpp"
+
+namespace ot {
+namespace Spinel {
+
+Decoder::Decoder(void)
+    : mFrame(nullptr)
+    , mLength(0)
+    , mIndex(0)
+    , mEnd(0)
+    , mNumOpenStructs(0)
+    , mSavedNumOpenStructs(0)
+    , mSavedIndex(0)
+    , mSavedEnd(0)
+{
+}
+
+void Decoder::Init(const uint8_t *aFrame, uint16_t aLength)
+{
+    mFrame  = aFrame;
+    mLength = (mFrame != nullptr) ? aLength : 0;
+
+    Reset();
+    ClearSavedPosition();
+}
+
+void Decoder::Reset(void)
+{
+    mIndex          = 0;
+    mEnd            = mLength;
+    mNumOpenStructs = 0;
+    ClearSavedPosition();
+}
+
+otError Decoder::ReadBool(bool &aBool)
+{
+    otError error = OT_ERROR_NONE;
+    uint8_t byte;
+
+    SuccessOrExit(error = ReadUint8(byte));
+
+    // Boolean value are encoded in 8-bits as either 0x00 or 0x01. All other values are illegal.
+    if (byte == 0x00)
+    {
+        aBool = false;
+    }
+    else if (byte == 0x01)
+    {
+        aBool = true;
+    }
+    else
+    {
+        error = OT_ERROR_PARSE;
+    }
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadUint8(uint8_t &aUint8)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mIndex + sizeof(uint8_t) <= mEnd, error = OT_ERROR_PARSE);
+    aUint8 = mFrame[mIndex];
+    mIndex += sizeof(uint8_t);
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadInt8(int8_t &aInt8)
+{
+    otError error = OT_ERROR_NONE;
+    uint8_t byte;
+
+    SuccessOrExit(error = ReadUint8(byte));
+    aInt8 = static_cast<int8_t>(byte);
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadUint16(uint16_t &aUint16)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mIndex + sizeof(uint16_t) <= mEnd, error = OT_ERROR_PARSE);
+
+    aUint16 = static_cast<uint16_t>(mFrame[mIndex] | (mFrame[mIndex + 1] << 8));
+
+    mIndex += sizeof(uint16_t);
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadInt16(int16_t &aInt16)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t u16;
+
+    SuccessOrExit(error = ReadUint16(u16));
+    aInt16 = static_cast<int16_t>(u16);
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadUint32(uint32_t &aUint32)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mIndex + sizeof(uint32_t) <= mEnd, error = OT_ERROR_PARSE);
+
+    aUint32 = ((static_cast<uint32_t>(mFrame[mIndex + 0]) << 0) | (static_cast<uint32_t>(mFrame[mIndex + 1]) << 8) |
+               (static_cast<uint32_t>(mFrame[mIndex + 2]) << 16) | (static_cast<uint32_t>(mFrame[mIndex + 3]) << 24));
+
+    mIndex += sizeof(uint32_t);
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadInt32(int32_t &aInt32)
+{
+    otError  error = OT_ERROR_NONE;
+    uint32_t u32;
+
+    SuccessOrExit(error = ReadUint32(u32));
+    aInt32 = static_cast<int32_t>(u32);
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadUint64(uint64_t &aUint64)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mIndex + sizeof(uint64_t) <= mEnd, error = OT_ERROR_PARSE);
+
+    aUint64 = ((static_cast<uint64_t>(mFrame[mIndex + 0]) << 0) | (static_cast<uint64_t>(mFrame[mIndex + 1]) << 8) |
+               (static_cast<uint64_t>(mFrame[mIndex + 2]) << 16) | (static_cast<uint64_t>(mFrame[mIndex + 3]) << 24) |
+               (static_cast<uint64_t>(mFrame[mIndex + 4]) << 32) | (static_cast<uint64_t>(mFrame[mIndex + 5]) << 40) |
+               (static_cast<uint64_t>(mFrame[mIndex + 6]) << 48) | (static_cast<uint64_t>(mFrame[mIndex + 7]) << 56));
+
+    mIndex += sizeof(uint64_t);
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadInt64(int64_t &aInt64)
+{
+    otError  error = OT_ERROR_NONE;
+    uint64_t u64;
+
+    SuccessOrExit(error = ReadUint64(u64));
+    aInt64 = static_cast<int64_t>(u64);
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadUintPacked(unsigned int &aUint)
+{
+    otError        error = OT_ERROR_NONE;
+    spinel_ssize_t parsedLen;
+    unsigned int   uint;
+
+    parsedLen = spinel_packed_uint_decode(&mFrame[mIndex], mEnd - mIndex, &uint);
+    VerifyOrExit(parsedLen > 0, error = OT_ERROR_PARSE);
+
+    mIndex += parsedLen;
+    aUint = uint;
+
+exit:
+    return error;
+}
+
+// Reads an item of given size and updates the pointer `aPtr`.
+otError Decoder::ReadItem(const uint8_t **aPtr, uint16_t aSize)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mIndex + aSize <= mEnd, error = OT_ERROR_PARSE);
+
+    *aPtr = &mFrame[mIndex];
+
+    mIndex += aSize;
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadIp6Address(spinel_ipv6addr_t &aIp6Addr)
+{
+    otError                  error = OT_ERROR_NONE;
+    const spinel_ipv6addr_t *ipv6AddrPtr;
+
+    SuccessOrExit(error = ReadIp6Address(ipv6AddrPtr));
+    aIp6Addr = *ipv6AddrPtr;
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadIp6Address(otIp6Address &aIp6Addr)
+{
+    otError             error = OT_ERROR_NONE;
+    const otIp6Address *ipv6AddrPtr;
+
+    SuccessOrExit(error = ReadIp6Address(ipv6AddrPtr));
+    aIp6Addr = *ipv6AddrPtr;
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadEui64(spinel_eui64_t &aEui64)
+{
+    otError               error = OT_ERROR_NONE;
+    const spinel_eui64_t *eui64Ptr;
+
+    SuccessOrExit(error = ReadEui64(eui64Ptr));
+    aEui64 = *eui64Ptr;
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadEui64(otExtAddress &aEui64)
+{
+    otError             error = OT_ERROR_NONE;
+    const otExtAddress *eui64Ptr;
+
+    SuccessOrExit(error = ReadEui64(eui64Ptr));
+    aEui64 = *eui64Ptr;
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadEui48(spinel_eui48_t &aEui48)
+{
+    otError               error = OT_ERROR_NONE;
+    const spinel_eui48_t *eui48Ptr;
+
+    SuccessOrExit(error = ReadEui48(eui48Ptr));
+    aEui48 = *eui48Ptr;
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadUtf8(const char *&aUtf8)
+{
+    otError error = OT_ERROR_NONE;
+    size_t  len;
+
+    // Ensure there is at least one byte (for null character).
+    VerifyOrExit(mIndex + sizeof(uint8_t) <= mEnd, error = OT_ERROR_PARSE);
+
+    len = StringLength(reinterpret_cast<const char *>(&mFrame[mIndex]), mEnd - mIndex);
+    VerifyOrExit(len < static_cast<uint16_t>(mEnd - mIndex), error = OT_ERROR_PARSE);
+
+    aUtf8 = reinterpret_cast<const char *>(&mFrame[mIndex]);
+
+    // `sizeof(uint8_t)` is added for the terminating null character.
+    mIndex += static_cast<uint16_t>(len + sizeof(uint8_t));
+
+exit:
+    return error;
+}
+
+otError Decoder::ReadData(const uint8_t *&aData, uint16_t &aDataLen)
+{
+    aDataLen = mEnd - mIndex;
+
+    return ReadItem(&aData, aDataLen);
+}
+
+otError Decoder::ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t len;
+
+    SuccessOrExit(error = ReadUint16(len));
+    SuccessOrExit(error = ReadItem(&aData, len));
+    aDataLen = len;
+
+exit:
+    return error;
+}
+
+otError Decoder::OpenStruct(void)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t structLen;
+
+    VerifyOrExit(mNumOpenStructs < kMaxNestedStructs, error = OT_ERROR_INVALID_STATE);
+
+    SuccessOrExit(error = ReadUint16(structLen));
+    VerifyOrExit(structLen <= mEnd - mIndex, error = OT_ERROR_PARSE);
+
+    mPrevEnd[mNumOpenStructs] = mEnd;
+    mEnd                      = (mIndex + structLen);
+    mNumOpenStructs++;
+
+exit:
+    return error;
+}
+
+otError Decoder::CloseStruct(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mNumOpenStructs > 0, error = OT_ERROR_INVALID_STATE);
+
+    // If there is a saved position and it is contained
+    // within the current struct being closed, the saved
+    // position is cleared to ensure user cannot go back
+    // to middle of an already closed struct.
+
+    if (IsSavedPositionValid() && (mNumOpenStructs == mSavedNumOpenStructs))
+    {
+        ClearSavedPosition();
+    }
+
+    mNumOpenStructs--;
+    mIndex = mEnd;
+    mEnd   = mPrevEnd[mNumOpenStructs];
+
+exit:
+    return error;
+}
+
+void Decoder::SavePosition(void)
+{
+    mSavedIndex          = mIndex;
+    mSavedEnd            = mEnd;
+    mSavedNumOpenStructs = mNumOpenStructs;
+}
+
+otError Decoder::ResetToSaved(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(IsSavedPositionValid(), error = OT_ERROR_INVALID_STATE);
+
+    mIndex          = mSavedIndex;
+    mEnd            = mSavedEnd;
+    mNumOpenStructs = mSavedNumOpenStructs;
+
+exit:
+    return error;
+}
+
+} // namespace Spinel
+} // namespace ot
diff --git a/src/lib/spinel/spinel_decoder.hpp b/src/lib/spinel/spinel_decoder.hpp
new file mode 100644
index 0000000..77328d7
--- /dev/null
+++ b/src/lib/spinel/spinel_decoder.hpp
@@ -0,0 +1,591 @@
+/*
+ *    Copyright (c) 2017, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file contains the definitions of a spinel decoder.
+ */
+
+#ifndef SPINEL_DECODER_HPP_
+#define SPINEL_DECODER_HPP_
+
+#include "openthread-spinel-config.h"
+
+#include <openthread/ip6.h>
+#include <openthread/ncp.h>
+
+#include "spinel.h"
+
+namespace ot {
+namespace Spinel {
+
+/**
+ * This class defines a spinel decoder.
+ *
+ */
+class Decoder
+{
+public:
+    enum
+    {
+        kMaxNestedStructs = 4, ///< Maximum number of nested structs.
+    };
+
+    /**
+     * This constructor initializes a `Decoder` object.
+     *
+     */
+    Decoder(void);
+
+    /**
+     * This method initializes the decoder to start decoding a new frame.
+     *
+     * It sets the read position to the start of the frame and also erases/voids any saved positions (see
+     * `SavePosition()` and `ResetToSaved()` methods).
+     *
+     * @param[in] aFrame                Pointer to the buffer containing the frame to be decoded.
+     * @param[in] aLength               Length (number of bytes) of the frame.
+     *
+     */
+    void Init(const uint8_t *aFrame, uint16_t aLength);
+
+    /**
+     * This method returns the pointer to the start of the frame.
+     *
+     * @returns A pointer to buffer containing current frame being decoded.
+     *
+     */
+    const uint8_t *GetFrame(void) const { return mFrame; }
+
+    /**
+     * This method returns the total length of current frame being decoded.
+     *
+     * @returns The length of current frame being decoded.
+     *
+     */
+    uint16_t GetLength(void) const { return mLength; }
+
+    /**
+     * This method returns the number of bytes that are already read/decoded from the frame.
+     *
+     * @returns The number of bytes already read from frame.
+     *
+     */
+    uint16_t GetReadLength(void) const { return mIndex; }
+
+    /**
+     * This method returns the number of remaining (not yet read/decoded) bytes in the frame.
+     *
+     * @returns The number of remaining unread bytes in the frame.
+     *
+     */
+    uint16_t GetRemainingLength(void) const { return mLength - mIndex; }
+
+    /**
+     * This method indicates whether or not all the bytes in the frame are read.
+     *
+     * @returns TRUE if all the bytes in the buffer are read, FALSE otherwise.
+     *
+     */
+    bool IsAllRead(void) const { return (mIndex == mLength); }
+
+    /**
+     * This method resets the read position to beginning of frame. It will also void/erase any previously saved
+     * position using `SavePosition()` method.
+     *
+     */
+    void Reset(void);
+
+    /**
+     * This method decodes and reads a boolean value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aBool                Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadBool(bool &aBool);
+
+    /**
+     * This method decodes and reads an `int8_t` value form the frame.
+     *
+     * On success, the read position get updated.
+     *
+     * @param[out] aInt8                Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadInt8(int8_t &aInt8);
+
+    /**
+     * This method decodes and reads an `uint8_t` value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aUint8               Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadUint8(uint8_t &aUint8);
+
+    /**
+     * This method decodes and reads an `int16_t` value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aInt16               Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadInt16(int16_t &aInt16);
+
+    /**
+     * This method decodes and reads an `uint16_t` value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aUint16              Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadUint16(uint16_t &aUint16);
+
+    /**
+     * This method decodes and reads an `int32_t` value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aInt32               Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadInt32(int32_t &aInt32);
+
+    /**
+     * This method decodes and reads an `uint32_t` value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aUint32              Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadUint32(uint32_t &aUint32);
+
+    /**
+     * This method decodes and reads an `int64_t` value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aInt64               Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadInt64(int64_t &aInt64);
+
+    /**
+     * This method decodes and reads an `uint64_t` value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aUint64              Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadUint64(uint64_t &aUint64);
+
+    /**
+     * This method decodes (using spinel packed integer format) and reads an unsigned integer value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aUint                Reference to variable to output the read value.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadUintPacked(unsigned int &aUint);
+
+    /**
+     * This method decodes and reads an IPv6 address form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aIp6AddrPtr          Reference to IPv6 address pointer to output the value (as `spinel_ipv6addr_t`).
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadIp6Address(const spinel_ipv6addr_t *&aIp6AddrPtr)
+    {
+        return ReadItem(reinterpret_cast<const uint8_t **>(&aIp6AddrPtr), sizeof(spinel_ipv6addr_t));
+    }
+
+    /**
+     * This method decodes and reads an IPv6 address form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aIp6AddrPtr          Reference to IPv6 address pointer to output the value (as `otIp6Address`).
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadIp6Address(const otIp6Address *&aIp6AddrPtr)
+    {
+        return ReadItem(reinterpret_cast<const uint8_t **>(&aIp6AddrPtr), sizeof(spinel_ipv6addr_t));
+    }
+
+    /**
+     * This method decodes and reads an IPv6 address form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aIp6AddrBufPtr       Reference to a buffer pointer to output the value.
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadIp6Address(const uint8_t *&aIp6AddrBufPtr)
+    {
+        return ReadItem(&aIp6AddrBufPtr, sizeof(spinel_ipv6addr_t));
+    }
+
+    /**
+     * This method decodes and reads an IPv6 address form the frame.
+     *
+     * On success, the read position gets updated and the IP address is copied into the given output variable.
+     *
+     * @param[out] aIp6Addr             Reference to IPv6 address variable to output the value (as `spinel_ipv6addr_t`).
+     *                                  On success, the address is copied into the output variable.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadIp6Address(spinel_ipv6addr_t &aIp6Addr);
+
+    /**
+     * This method decodes and reads an IPv6 address form the frame.
+     *
+     * On success, the read position gets updated and the IP address is copied into the given output variable.
+     *
+     * @param[out] aIp6Addr             Reference to IPv6 address variable to output the value (as `otIp6Address`).
+     *                                  On success, the address is copied into the output variable.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadIp6Address(otIp6Address &aIp6Addr);
+
+    /**
+     * This method decodes and reads an EUI64 value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aEui64Ptr            Reference to an EUI64 pointer to output the value (as `spinel_eui64_t`).
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadEui64(const spinel_eui64_t *&aEui64Ptr)
+    {
+        return ReadItem(reinterpret_cast<const uint8_t **>(&aEui64Ptr), sizeof(spinel_eui64_t));
+    }
+
+    /**
+     * This method decodes and reads an EUI64 value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aEui64Ptr            Reference to an EUI64 pointer to output the value (as `otExtAddress`).
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadEui64(const otExtAddress *&aEui64Ptr)
+    {
+        return ReadItem(reinterpret_cast<const uint8_t **>(&aEui64Ptr), sizeof(spinel_eui64_t));
+    }
+
+    /**
+     * This method decodes and reads an EUI64 value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aEui64BufPtr         Reference to a buffer pointer to output the value.
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadEui64(const uint8_t *&aEui64BufPtr) { return ReadItem(&aEui64BufPtr, sizeof(spinel_eui64_t)); }
+
+    /**
+     * This method decodes and reads an EUI64 value form the frame.
+     *
+     * On success, the read position gets updated and the EUI64 value is copied into the given output variable.
+     *
+     * @param[out] aEui64               Reference to EUI64 variable to output the value (as `spinel_eui64_t`).
+     *                                  On success, the address is copied into the output variable.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadEui64(spinel_eui64_t &aEui64);
+
+    /**
+     * This method decodes and reads an EUI64 value form the frame.
+     *
+     * On success, the read position gets updated and the EUI64 value is copied into the given output variable.
+     *
+     * @param[out] aEui64               Reference to EUI64 variable to output the value (as `otExtAddress`).
+     *                                  On success, the address is copied into the output variable.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadEui64(otExtAddress &aEui64);
+
+    /**
+     * This method decodes and reads an EUI48 value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aEui48Ptr            Reference to an EUI48 pointer to output the value (as `spinel_eui48_t`).
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadEui48(const spinel_eui48_t *&aEui48Ptr)
+    {
+        return ReadItem(reinterpret_cast<const uint8_t **>(&aEui48Ptr), sizeof(spinel_eui48_t));
+    }
+
+    /**
+     * This method decodes and reads an EUI48 value form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aEui48BufPtr         Reference to a buffer pointer to output the value.
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadEui48(const uint8_t *&aEui48BufPtr) { return ReadItem(&aEui48BufPtr, sizeof(spinel_eui48_t)); }
+
+    /**
+     * This method decodes and reads an EUI48 value form the frame.
+     *
+     * On success, the read position gets updated and the EUI48 value is copied into the given output variable.
+     *
+     * @param[out] aEui48               Reference to EUI48 variable to output the value (as `spinel_eui48_t`).
+     *                                  On success, value is copied into the output variable.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadEui48(spinel_eui48_t &aEui48);
+
+    /**
+     * This method decodes and reads a UTF8 string form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aUtf8                Reference to a `char` pointer to output the string.
+     *                                  On success, the pointer variable is updated.
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadUtf8(const char *&aUtf8);
+
+    /**
+     * This method decodes and reads a data blob (sequence of bytes) form the frame.
+     *
+     * On success, the read position gets updated.
+     *
+     * @param[out] aData                Reference to pointer variable to output the data.
+     *                                  On success, the pointer variable is updated.
+     * @param[out] aDataLength          Reference to variable to output the data length (number of bytes).
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadData(const uint8_t *&aData, uint16_t &aDataLen);
+
+    /**
+     * This method decodes and reads a data blob (sequence of bytes) with data length.
+     *
+     * The data length is assumed to be prepended before the data content (encoded as a `uint16_t`). The size of the
+     * length field should not be included in the length value. This method corresponds to `SPINEL_DATATYPE_DATA_WLEN`
+     * type.
+     *
+     * @param[out] aData                Reference to pointer variable to output the data.
+     *                                  On success, the pointer variable is updated.
+     * @param[out] aDataLength          Reference to variable to out the data length (number of bytes).
+     *
+     * @retval OT_ERROR_NONE            Successfully read the value.
+     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
+     *
+     */
+    otError ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen);
+
+    /**
+     * This method opens a struct in the frame.
+     *
+     * After a successful call to this method, all the subsequent `Read{SomeType}()` methods decode and read the
+     * field/value from the current open struct until the struct is closed using `CloseStruct()` method. Structures can
+     * be nested. Up to `kMaxNestedStructs` nested structs can be opened at the same time.
+     *
+     * @retval OT_ERROR_NONE            Successfully opened a struct.
+     * @retval OT_ERROR_PARSE           Failed to parse/open a struct.
+     * @retval OT_ERROR_INVALID_STATE   Already at the maximum number of nested open structures.
+     *
+     */
+    otError OpenStruct(void);
+
+    /**
+     * This method closes the most recently opened struct (using `OpenStruct()`) in the frame.
+     *
+     * On success, the read position is moved to end of the struct skipping any unread bytes within the struct.
+     *
+     * @retval OT_ERROR_NONE            Successfully closed the struct.
+     * @retval OT_ERROR_INVALID_STATE   There is no current open struct to close.
+     *
+     */
+    otError CloseStruct(void);
+
+    /**
+     * This method returns the number of remaining/unread bytes in the current inner-most open structure.
+     *
+     * If there is no currently open structure the number of remaining bytes in whole frame is returned instead.
+     *
+     * @returns The number of remaining unread bytes in the inner-most open structure.
+     *
+     */
+    uint16_t GetRemainingLengthInStruct(void) const { return mEnd - mIndex; }
+
+    /**
+     * This method indicates whether or not all the bytes in inner-most open structure are read.
+     *
+     * If there is no currently open structure, the whole frame is considered instead.
+     *
+     * @returns TRUE if all the bytes are read, FALSE otherwise.
+     *
+     */
+    bool IsAllReadInStruct(void) const { return (mIndex == mEnd); }
+
+    /**
+     * This method saves the current read position in the frame.
+     *
+     * A subsequent call to `SavePosition()` will overwrite the previously saved position. The saved position can be
+     * used to move the read position back (using `ResetToSaved()`) and re-read the same content.
+     *
+     * Saved position can be within an open struct, and it remembers its enclosing struct. When the enclosing struct is
+     * closed, the saved position will be voided and can no longer be used. This ensures that we cannot jump back to
+     * middle an already fully decoded/read and closed struct.
+     *
+     */
+    void SavePosition(void);
+
+    /**
+     * This method resets/moves the read position to a previously saved position.
+     *
+     * The saved position remembers its enclosing structure. When `ResetToSaved()` is called, the current open
+     * structure will be the same as when position was saved.
+     *
+     * @retval OT_ERROR_NONE            Successfully reset the read position.
+     * @retval OT_ERROR_INVALID_STATE   The saved position is not valid (there is no saved position or the saved
+     *                                  position was voided since its enclosing struct was closed).
+     *
+     */
+    otError ResetToSaved(void);
+
+private:
+    otError ReadItem(const uint8_t **aPtr, uint16_t aSize);
+    void    ClearSavedPosition(void) { mSavedIndex = mLength; }
+    bool    IsSavedPositionValid(void) const { return (mSavedIndex < mLength); }
+
+    const uint8_t *mFrame;          // Frame buffer.
+    uint16_t       mLength;         // Frame length (number of bytes).
+    uint16_t       mIndex;          // Current read index.
+    uint16_t       mEnd;            // Current end index (end of struct if in a struct, or end of buffer otherwise).
+    uint8_t        mNumOpenStructs; // Number of open structs.
+
+    uint8_t  mSavedNumOpenStructs; // Number of open structs when read position was saved.
+    uint16_t mSavedIndex;          // Read index when position was saved.
+    uint16_t mSavedEnd;            // End index when position was saved.
+
+    uint16_t mPrevEnd[kMaxNestedStructs];
+};
+
+} // namespace Spinel
+} // namespace ot
+
+#endif // SPINEL_DECODER_HPP_
diff --git a/src/lib/spinel/spinel_encoder.cpp b/src/lib/spinel/spinel_encoder.cpp
new file mode 100644
index 0000000..91a9ec3
--- /dev/null
+++ b/src/lib/spinel/spinel_encoder.cpp
@@ -0,0 +1,295 @@
+/*
+ *    Copyright (c) 2017, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements a spinel encoder.
+ */
+
+#include "spinel_encoder.hpp"
+
+#include <string.h>
+
+#include "common/code_utils.hpp"
+
+namespace ot {
+namespace Spinel {
+
+otError Encoder::BeginFrame(Spinel::Buffer::Priority aPriority)
+{
+    mNumOpenStructs = 0;
+    mNcpBuffer.InFrameBegin(aPriority);
+    return OT_ERROR_NONE;
+}
+
+otError Encoder::BeginFrame(uint8_t aHeader, unsigned int aCommand)
+{
+    otError error = OT_ERROR_NONE;
+
+    // Non-zero TID indicates this is a response to a spinel command.
+
+    if (SPINEL_HEADER_GET_TID(aHeader) != 0)
+    {
+        SuccessOrExit(error = BeginFrame(Spinel::Buffer::kPriorityHigh));
+    }
+    else
+    {
+        SuccessOrExit(error = BeginFrame(Spinel::Buffer::kPriorityLow));
+    }
+
+    SuccessOrExit(error = WriteUint8(aHeader));
+    SuccessOrExit(error = WriteUintPacked(aCommand));
+
+exit:
+    return error;
+}
+
+otError Encoder::BeginFrame(uint8_t aHeader, unsigned int aCommand, spinel_prop_key_t aKey)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = BeginFrame(aHeader, aCommand));
+
+    // The write position is saved before writing the property key,
+    // so that if fetching the property fails and we need to
+    // reply with a `LAST_STATUS` error we can get back to
+    // this saved write position and update the property key.
+    // (Also see `OverwriteWithLastStatusError()`).
+
+    SuccessOrExit(error = SavePosition());
+    SuccessOrExit(error = WriteUintPacked(aKey));
+
+exit:
+    return error;
+}
+
+otError Encoder::OverwriteWithLastStatusError(spinel_status_t aStatus)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = ResetToSaved());
+    SuccessOrExit(error = WriteUintPacked(SPINEL_PROP_LAST_STATUS));
+    SuccessOrExit(error = WriteUintPacked(aStatus));
+
+exit:
+    return error;
+}
+
+otError Encoder::EndFrame(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    while (mNumOpenStructs > 0)
+    {
+        SuccessOrExit(error = CloseStruct());
+    }
+
+    error = mNcpBuffer.InFrameEnd();
+
+exit:
+    return error;
+}
+
+otError Encoder::WriteUint16(uint16_t aUint16)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint16 >> 0) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint16 >> 8) & 0xff));
+
+exit:
+    return error;
+}
+
+otError Encoder::WriteUint32(uint32_t aUint32)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 0) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 8) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 16) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 24) & 0xff));
+
+exit:
+    return error;
+}
+
+otError Encoder::WriteUint64(uint64_t aUint64)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 0) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 8) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 16) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 24) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 32) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 40) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 48) & 0xff));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 56) & 0xff));
+
+exit:
+    return error;
+}
+
+otError Encoder::WriteUintPacked(unsigned int aUint)
+{
+    uint8_t        buffer[6];
+    spinel_ssize_t len;
+
+    len = spinel_packed_uint_encode(buffer, sizeof(buffer), aUint);
+
+    return WriteData(buffer, static_cast<uint16_t>(len));
+}
+
+otError Encoder::WriteDataWithLen(const uint8_t *aData, uint16_t aDataLen)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = WriteUint16(aDataLen));
+    SuccessOrExit(error = WriteData(aData, aDataLen));
+
+exit:
+    return error;
+}
+
+otError Encoder::WriteUtf8(const char *aUtf8)
+{
+    otError error;
+    size_t  len = strlen(aUtf8);
+
+    if (len >= 0xffff)
+    {
+        len = 0xffff;
+    }
+
+    SuccessOrExit(error = WriteData(reinterpret_cast<const uint8_t *>(aUtf8), static_cast<uint16_t>(len)));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte(0));
+
+exit:
+    return error;
+}
+
+otError Encoder::OpenStruct(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(mNumOpenStructs < kMaxNestedStructs, error = OT_ERROR_INVALID_STATE);
+    SuccessOrExit(error = mNcpBuffer.InFrameGetPosition(mStructPosition[mNumOpenStructs]));
+
+    // Reserve bytes for the length to be filled when the struct gets closed.
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte(0));
+    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte(0));
+
+    mNumOpenStructs++;
+
+exit:
+    return error;
+}
+
+otError Encoder::CloseStruct(void)
+{
+    otError  error = OT_ERROR_NONE;
+    uint16_t len;
+    uint8_t  buffer[sizeof(uint16_t)];
+
+    VerifyOrExit(mNumOpenStructs > 0, error = OT_ERROR_INVALID_STATE);
+
+    mNumOpenStructs--;
+
+    len = mNcpBuffer.InFrameGetDistance(mStructPosition[mNumOpenStructs]);
+    VerifyOrExit(len >= sizeof(uint16_t), error = OT_ERROR_INVALID_STATE);
+
+    len -= sizeof(uint16_t);
+
+    buffer[0] = (len >> 0 & 0xff);
+    buffer[1] = (len >> 8 & 0xff);
+
+    SuccessOrExit(error = mNcpBuffer.InFrameOverwrite(mStructPosition[mNumOpenStructs], buffer, sizeof(buffer)));
+
+exit:
+    return error;
+}
+
+otError Encoder::SavePosition(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = mNcpBuffer.InFrameGetPosition(mSavedPosition));
+    mSavedNumOpenStructs = mNumOpenStructs;
+
+exit:
+    return error;
+}
+
+otError Encoder::ResetToSaved(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = mNcpBuffer.InFrameReset(mSavedPosition));
+    mNumOpenStructs = mSavedNumOpenStructs;
+
+exit:
+    return error;
+}
+
+otError Encoder::WritePacked(const char *aPackFormat, ...)
+{
+    uint8_t        buf[kPackFormatBufferSize];
+    otError        error = OT_ERROR_NONE;
+    spinel_ssize_t packedLen;
+    va_list        args;
+
+    va_start(args, aPackFormat);
+
+    packedLen = spinel_datatype_vpack(buf, sizeof(buf), aPackFormat, args);
+    VerifyOrExit((packedLen > 0) && (packedLen <= static_cast<spinel_ssize_t>(sizeof(buf))), error = OT_ERROR_NO_BUFS);
+
+    error = mNcpBuffer.InFrameFeedData(buf, static_cast<uint16_t>(packedLen));
+
+exit:
+    va_end(args);
+
+    return error;
+}
+
+otError Encoder::WriteVPacked(const char *aPackFormat, va_list aArgs)
+{
+    uint8_t        buf[kPackFormatBufferSize];
+    otError        error = OT_ERROR_NONE;
+    spinel_ssize_t packedLen;
+
+    packedLen = spinel_datatype_vpack(buf, sizeof(buf), aPackFormat, aArgs);
+    VerifyOrExit((packedLen > 0) && (packedLen <= static_cast<spinel_ssize_t>(sizeof(buf))), error = OT_ERROR_NO_BUFS);
+
+    error = mNcpBuffer.InFrameFeedData(buf, static_cast<uint16_t>(packedLen));
+
+exit:
+    return error;
+}
+
+} // namespace Spinel
+} // namespace ot
diff --git a/src/lib/spinel/spinel_encoder.hpp b/src/lib/spinel/spinel_encoder.hpp
new file mode 100644
index 0000000..84f2df6
--- /dev/null
+++ b/src/lib/spinel/spinel_encoder.hpp
@@ -0,0 +1,698 @@
+/*
+ *    Copyright (c) 2017, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file contains the definitions of a spinel encoder.
+ */
+
+#ifndef SPINEL_ENCODER_HPP_
+#define SPINEL_ENCODER_HPP_
+
+#include "openthread-spinel-config.h"
+
+#include <openthread/ip6.h>
+#include <openthread/message.h>
+#include <openthread/ncp.h>
+
+#include "spinel.h"
+#include "spinel_buffer.hpp"
+
+namespace ot {
+namespace Spinel {
+
+/**
+ * This class defines a spinel encoder.
+ *
+ */
+class Encoder
+{
+public:
+    /**
+     * This constructor initializes a `Encoder` object.
+     *
+     * @param[in] aNcpBuffer   A reference to a `Spinel::Buffer` where the frames are written.
+     *
+     */
+    explicit Encoder(Spinel::Buffer &aNcpBuffer)
+        : mNcpBuffer(aNcpBuffer)
+        , mNumOpenStructs(0)
+        , mSavedNumOpenStructs(0)
+        , mSavedPosition()
+    {
+    }
+
+    /**
+     * This method begins a new frame to be added/written to the frame buffer.
+     *
+     * If there is a previous frame being written (for which `EndFrame()` has not yet been called), calling
+     * `BeginFrame()` will discard and clear the previous unfinished frame.
+     *
+     * @param[in] aPriority             Priority level of the new input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully started a new frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to start a new frame.
+     *
+     */
+    otError BeginFrame(Spinel::Buffer::Priority aPriority);
+
+    /**
+     * This method begins a new spinel command frame to be added/written to the frame buffer.
+     *
+     * If there is a previous frame being written (for which `EndFrame()` has not yet been called), calling
+     * `BeginFrame()` will discard and clear the previous unfinished frame.
+     *
+     * The spinel transaction ID (TID) in the given spinel header is used to determine the priority level of the new
+     * frame. Non-zero TID value indicates that the frame is a response and therefore it uses higher priority level.
+     *
+     * @param[in] aHeader               Spinel header for new the command frame.
+     * @param[in] aCommand              Spinel command.
+     *
+     * @retval OT_ERROR_NONE            Successfully started a new frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to start a new frame.
+     *
+     */
+    otError BeginFrame(uint8_t aHeader, unsigned int aCommand);
+
+    /**
+     * This method begins a new spinel property update command frame to be added/written to the frame buffer.
+     *
+     * If there is a previous frame being written (for which `EndFrame()` has not yet been called), calling
+     * `BeginFrame()` will discard and clear the previous unfinished frame.
+     *
+     * The spinel transaction ID (TID) in the given spinel header is used to determine the priority level of the new
+     * frame. Non-zero TID value indicates that the frame is a response and therefore it uses higher priority level.
+     *
+     * This method saves the write position before the property key (see also `SavePosition()`) so that if fetching the
+     * property fails and the property key should be switched to `LAST_STATUS` with an error status, the saved
+     * position can be used to update the property key in the frame (see also `OverwriteWithLastStatusError()`)
+     *
+     * @param[in] aHeader               Spinel header for new the command frame.
+     * @param[in] aCommand              Spinel command.
+     * @param[in] aKey                  Spinel property key
+     *
+     * @retval OT_ERROR_NONE            Successfully started a new frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to start a new frame.
+     *
+     */
+    otError BeginFrame(uint8_t aHeader, unsigned int aCommand, spinel_prop_key_t aKey);
+
+    /**
+     * This method overwrites the property key with `LAST_STATUS` in a property update command frame.
+     *
+     * This method should be only used after a successful `BeginFrame(aHeader, aCommand, aPropertKey)`, otherwise, its
+     * behavior is undefined.
+     *
+     * This method moves the write position back to saved position by `BeginFrame()` and replaces the property key
+     * `SPINEL_PROP_LAST_STATUS` and writes the given spinel status error.
+     *
+     * @param[in] aStatus               Spinel error status
+     *
+     * @retval OT_ERROR_NONE            Successfully updated the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to update the frame.
+     *
+     */
+    otError OverwriteWithLastStatusError(spinel_status_t aStatus);
+
+    /**
+     * This method finalizes/ends the current frame being written to the buffer.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new frame. Otherwise, this method
+     * does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the frame and return error status
+     * `OT_ERROR_NO_BUFS`.
+     *
+     * This method ensures to close any open structure (previously opened using `OpenStruct()` but not closed using
+     * `CloseStruct()`).
+     *
+     * @retval OT_ERROR_NONE            Successfully ended the input frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add message.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError EndFrame(void);
+
+    /**
+     * This method encodes and writes a boolean value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aBool                The boolean value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given byte to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteBool(bool aBool) { return mNcpBuffer.InFrameFeedByte(aBool ? 0x01 : 0x00); }
+
+    /**
+     * This method encodes and writes a `uint8_t` value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aUint8               The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteUint8(uint8_t aUint8) { return mNcpBuffer.InFrameFeedByte(aUint8); }
+
+    /**
+     * This method encodes and writes an `int8_t` value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aInt8                The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteInt8(int8_t aInt8) { return WriteUint8(static_cast<uint8_t>(aInt8)); }
+
+    /**
+     * This method encodes and writes a `uint16_t` value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aUint16              The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteUint16(uint16_t aUint16);
+
+    /**
+     * This method encodes and writes an `int16_t` value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aInt16              The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteInt16(int16_t aInt16) { return WriteUint16(static_cast<uint16_t>(aInt16)); }
+
+    /**
+     * This method encodes and writes a `uint32_t` value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aUint32              The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteUint32(uint32_t aUint32);
+
+    /**
+     * This method encodes and writes an `int32_t` value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aInt32               The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteInt32(int32_t aInt32) { return WriteUint32(static_cast<uint32_t>(aInt32)); }
+
+    /**
+     * This method encodes and writes a `uint64_t` value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aUint64              The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteUint64(uint64_t aUint64);
+
+    /**
+     * This method encodes and writes an `int64_t` value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aInt64               The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteInt64(int64_t aInt64) { return WriteUint64(static_cast<uint64_t>(aInt64)); }
+
+    /**
+     * This method encodes (using spinel packed integer format) and writes a value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aUint                The value to add to input frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteUintPacked(unsigned int aUint);
+
+    /**
+     * This method encodes and writes an IPv6 address to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aIp6Addr             A reference to the IPv6 address to be added (as `spinel_ipv6addr_t`)
+     *
+     * @retval OT_ERROR_NONE            Successfully added given address to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the IP address.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteIp6Address(const spinel_ipv6addr_t &aIp6Addr) { return WriteIp6Address(aIp6Addr.bytes); }
+
+    /**
+     * This method encodes and writes an IPv6 address to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aIp6Addr             A reference to the IPv6 address to be added (as `otIp6Address`)
+     *
+     * @retval OT_ERROR_NONE            Successfully added given address to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the IP address.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteIp6Address(const otIp6Address &aIp6Addr) { return WriteIp6Address(aIp6Addr.mFields.m8); }
+
+    /**
+     * This method encodes and writes an IPv6 address to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aIp6AddrBuf          A pointer to a buffer containing the IPv6 address.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given address to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the IP address.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteIp6Address(const uint8_t *aIp6AddrBuf) { return WriteData(aIp6AddrBuf, sizeof(spinel_ipv6addr_t)); }
+
+    /**
+     * This method encodes and writes an EUI64 value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aEui64               A reference to the EUI64 value as a `spinel_eui64_t` type.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI64 value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteEui64(const spinel_eui64_t &aEui64) { return WriteEui64(aEui64.bytes); }
+
+    /**
+     * This method encodes and writes an EUI64 value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aExtAddress          A reference to an `otExtAddress`
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI64 value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteEui64(const otExtAddress &aExtAddress) { return WriteEui64(aExtAddress.m8); }
+
+    /**
+     * This method encodes and writes an EUI64 value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aExtAddress          A pointer to a buffer containing the EUI64 value.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI64 value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteEui64(const uint8_t *aEui64) { return WriteData(aEui64, sizeof(spinel_eui64_t)); }
+
+    /**
+     * This method encodes and writes an EUI48 value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aEui48               A reference to the EUI48 value.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI48 value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteEui48(const spinel_eui48_t &aEui48) { return WriteEui48(aEui48.bytes); }
+
+    /**
+     * This method encodes and writes an EUI48 value to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aEui48               A pointer to a buffer containing the EUI64 value.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI48 value.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteEui48(const uint8_t *aEui48) { return WriteData(aEui48, sizeof(spinel_eui48_t)); }
+
+    /**
+     * This method encodes and writes a UTF8 string to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aUtf8                A const character pointer (C string).
+     *
+     * @retval OT_ERROR_NONE            Successfully added given string to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the string.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteUtf8(const char *aUtf8);
+
+    /**
+     * This method encodes and writes a sequence of bytes to current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aData                A pointer to data buffer.
+     * @param[in]  aDataLen             The length (number of bytes) in the data buffer.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given data to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteData(const uint8_t *aData, uint16_t aDataLen) { return mNcpBuffer.InFrameFeedData(aData, aDataLen); }
+
+    /**
+     * This method encodes and writes a data blob (sequence of bytes) with its length prepended before the data.
+     *
+     * The length of the data (in bytes) is prepended (with the length encoded as a `uint16`). The size of the length
+     * field is not included in the length. This is similar to `SPINEL_DATATYPE_DATA_WLEN` type.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * @param[in]  aData                A pointer to data buffer.
+     * @param[in]  aDataLen             The length (number of bytes) in the data buffer.
+     *
+     * @retval OT_ERROR_NONE            Successfully added given data to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteDataWithLen(const uint8_t *aData, uint16_t aDataLen);
+
+#if OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE
+    /**
+     * This method adds a message to the current input frame.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the frame and return error status
+     * `OT_ERROR_NO_BUFS`.
+     *
+     * The ownership of the passed-in message @p aMessage changes to underlying `Spinel::Buffer` ONLY when the entire
+     * frame is successfully finished (i.e., with a successful call to `EndFrame()` for the current frame being
+     * written), and in this case the `otMessage` instance will be freed once the frame is removed from the
+     * `Spinel::Buffer`. However, if the frame gets discarded before it is finished (e.g., running out of buffer space),
+     * the  `otMessage` instance remains unchanged.
+     *
+     * @param[in] aMessage              A message to be added to current frame.
+     *
+     * @retval OT_ERROR_NONE            Successfully added the message to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the message.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     * @retval OT_ERROR_INVALID_ARGS    If @p aMessage is nullptr.
+     *
+     */
+    otError WriteMessage(otMessage *aMessage) { return mNcpBuffer.InFrameFeedMessage(aMessage); }
+#endif
+
+    /**
+     * This method encodes and writes a set of variables to the current input frame using a given spinel packing format
+     * string.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * Note that the encoded buffer should fit in `kPackFormatBufferSize` bytes.
+     *
+     * @param[in]  aPackFormat          A string giving the spinel packing format.
+     * @param[in]  ...                  Variable arguments corresponding to the types given in @p aPackFormat (see
+     *                                  `spinel_datatype_pack()`).
+     *
+     * @retval OT_ERROR_NONE            Successfully added given data to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WritePacked(const char *aPackFormat, ...);
+
+    /**
+     * This method encodes and writes a set of variables to the current input frame using a given spinel packing format
+     * string.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the current input frame and return the
+     * error status `OT_ERROR_NO_BUFS`.
+     *
+     * Note that the encoded buffer should fit in `kPackFormatBufferSize` bytes.
+     *
+     * @param[in]  aPackFormat          A string giving the spinel packing format.
+     * @param[in]  aArgs                Variable arguments corresponding to the types given in @p aPackFormat (see
+     *                                  `spinel_datatype_pack()`).
+     *
+     * @retval OT_ERROR_NONE            Successfully added given data to the frame.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError WriteVPacked(const char *aPackFormat, va_list aArgs);
+
+    /**
+     * This method opens a struct in the current input frame.
+     *
+     * After a successful call to this method, all the subsequent `Write<SomeType>()` methods add the field/value to
+     * the current open struct until the struct is closed using `CloseStruct()` method. Structures can be nested. Up to
+     * `kMaxNestedStructs` nested structs can be opened at the same time.
+     *
+     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
+     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
+     *
+     * If no buffer space is available, this method will discard and clear the frame and return error status
+     * `OT_ERROR_NO_BUFS`.
+     *
+     * @retval OT_ERROR_NONE            Successfully opened the struct.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to open the struct.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame or if we reached
+     *                                  the maximum number of nested open structures.
+     *
+     */
+    otError OpenStruct(void);
+
+    /**
+     * This method closes the most recently opened struct (using `OpenStruct()`) in the current input frame.
+     *
+     * Each call to `CloseStruct()` must correspond to an earlier successfully opened struct. If a frame is ended using
+     * `EndFrame()` with remaining open structs, the `EndFrame()` method will close all the remaining structs.
+     *
+     * If no buffer space is available, this method will discard and clear the frame and return error status
+     * `OT_ERROR_NO_BUFS`.
+     *
+     * @retval OT_ERROR_NONE            Successfully closed the most recently opened struct.
+     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to open the struct.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame or if there is no
+     *                                  open struct to close
+     */
+    otError CloseStruct(void);
+
+    /**
+     * This method saves the current write position in the input frame.
+     *
+     * The saved position can later be used to discard a portion of written/encoded frame and move the write pointer
+     * back to the saved position (using `ResetToSaved()`).
+     *
+     * @retval OT_ERROR_NONE            Successfully saved current write position in @p aPosition.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     *
+     */
+    otError SavePosition(void);
+
+    /**
+     * This method resets the write position of input frame back to a previously saved position. Any added content
+     * after the write position is discarded.
+     *
+     * The saved position must belong to the same input frame saved earlier with `SavePosition()`. This method cannot
+     * be used if the input frame has an added `otMessage`.
+     *
+     * @retval OT_ERROR_NONE            Successfully reset the write position of current input frame.
+     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
+     * @retval OT_ERROR_INVALID_ARGS    The saved position is not valid (does not belong to same input frame), or
+     *                                  the input frame has an added `otMessage`.
+     *
+     */
+    otError ResetToSaved(void);
+
+private:
+    enum
+    {
+        kPackFormatBufferSize = 96, ///< Size of buffer used when encoding using `WritePacked()` or `WriteVPacked()`.
+        kMaxNestedStructs     = 4,  ///< Maximum number of nested structs.
+    };
+
+    Spinel::Buffer &              mNcpBuffer;
+    Spinel::Buffer::WritePosition mStructPosition[kMaxNestedStructs];
+    uint8_t                       mNumOpenStructs;
+
+    uint8_t                       mSavedNumOpenStructs;
+    Spinel::Buffer::WritePosition mSavedPosition;
+};
+
+} // namespace Spinel
+} // namespace ot
+
+#endif // SPINEL_ENCODER_HPP_
diff --git a/src/lib/spinel/spinel_encrypter.hpp b/src/lib/spinel/spinel_encrypter.hpp
new file mode 100644
index 0000000..989bbc5
--- /dev/null
+++ b/src/lib/spinel/spinel_encrypter.hpp
@@ -0,0 +1,62 @@
+/*
+ *    Copyright (c) 2018, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Allows to encrypt spinel frames sent between Application Processor (AP) and Network Co-Processor (NCP).
+ */
+
+namespace SpinelEncrypter {
+
+/**
+ * Encrypts spinel frames before sending to AP/NCP.
+ *
+ * This method encrypts outbound frames in both directions, i.e. from AP to NCP and from NCP to AP.
+ *
+ * @param[in,out] aFrameBuf Pointer to buffer containing the frame, also where the encrypted frame will be placed.
+ * @param[in] aFrameSize Max number of bytes in frame buffer (max length of spinel frame + additional data for
+ * encryption).
+ * @param[in,out] aFrameLength Pointer to store frame length, on input value is set to frame length,
+ * on output changed to show the frame length after encryption.
+ * @return \c true on success, \c false otherwise.
+ */
+bool EncryptOutbound(unsigned char *aFrameBuf, size_t aFrameSize, size_t *aFrameLength);
+
+/**
+ * Decrypts spinel frames received from AP/NCP.
+ *
+ * This method decrypts inbound frames in both directions, i.e. from AP to NCP and from NCP to AP.
+ *
+ * @param[in,out] aFrameBuf Pointer to buffer containing encrypted frame, also where the decrypted frame will be placed.
+ * @param[in] aFrameSize Max number of bytes in frame buffer (max length of spinel frame + additional data for
+ * encryption).
+ * @param[in,out] aFrameLength Pointer to store frame length, on input value is set to encrypted frame length,
+ * on output changed to show the frame length after decryption.
+ * @return \c true on success, \c false otherwise.
+ */
+bool DecryptInbound(unsigned char *aFrameBuf, size_t aFrameSize, size_t *aFrameLength);
+
+} // namespace SpinelEncrypter
diff --git a/src/lib/spinel/spinel_interface.hpp b/src/lib/spinel/spinel_interface.hpp
new file mode 100644
index 0000000..950f09f
--- /dev/null
+++ b/src/lib/spinel/spinel_interface.hpp
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file includes definitions for the spinel interface to Radio Co-processor (RCP)
+ *
+ */
+
+#ifndef POSIX_APP_SPINEL_INTERFACE_HPP_
+#define POSIX_APP_SPINEL_INTERFACE_HPP_
+
+#include "lib/hdlc/hdlc.hpp"
+
+namespace ot {
+namespace Spinel {
+
+class SpinelInterface
+{
+public:
+    enum
+    {
+        kMaxFrameSize = 2048, ///< Maximum frame size (number of bytes).
+    };
+
+    /**
+     * This type defines a receive frame buffer to store received spinel frame(s).
+     *
+     * @note The receive frame buffer is an `Hdlc::MultiFrameBuffer` and therefore it is capable of storing multiple
+     * frames in a FIFO queue manner.
+     *
+     */
+    typedef Hdlc::MultiFrameBuffer<kMaxFrameSize> RxFrameBuffer;
+
+    typedef void (*ReceiveFrameCallback)(void *aContext);
+};
+} // namespace Spinel
+} // namespace ot
+
+#endif // POSIX_APP_SPINEL_INTERFACE_HPP_
diff --git a/src/lib/spinel/spinel_platform.h b/src/lib/spinel/spinel_platform.h
new file mode 100644
index 0000000..744feff
--- /dev/null
+++ b/src/lib/spinel/spinel_platform.h
@@ -0,0 +1,59 @@
+/*
+ *    Copyright (c) 2017, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SPINEL_PLATFORM_OPENTHREAD_H_
+#define SPINEL_PLATFORM_OPENTHREAD_H_
+
+/**
+ * This is the platform header file used for spinel on
+ * OpenThread.
+ *
+ * To make spinel code more portable, all header file
+ * `#include`s are defined in a platform specific header
+ * file "spinel_platform.h" which is then included from
+ * "spinel.h".
+ *
+ * This file should include the following header files (or
+ * their equivalent on the platform):
+ *
+ *   #include <stdarg.h>
+ *   #include <stdbool.h>
+ *   #include <stdint.h>
+ *   #include <stdio.h>
+ *   #include <stdlib.h>
+ *   #include <string.h>
+ *
+ */
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#endif // SPINEL_PLATFORM_OPENTHREAD_H_
diff --git a/src/lib/url/CMakeLists.txt b/src/lib/url/CMakeLists.txt
new file mode 100644
index 0000000..79c8629
--- /dev/null
+++ b/src/lib/url/CMakeLists.txt
@@ -0,0 +1,40 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_library(openthread-url
+    url.cpp
+)
+
+set_target_properties(
+    openthread-url
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_link_libraries(openthread-url PRIVATE ot-config)
diff --git a/src/lib/url/Makefile.am b/src/lib/url/Makefile.am
new file mode 100644
index 0000000..099921b
--- /dev/null
+++ b/src/lib/url/Makefile.am
@@ -0,0 +1,59 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+
+noinst_LIBRARIES = libopenthread-url.a
+
+libopenthread_url_a_CPPFLAGS                = \
+    -I$(top_srcdir)/include                   \
+    -I$(top_srcdir)/src                       \
+    $(NULL)
+
+libopenthread_url_a_SOURCES                 = \
+    url.cpp                                   \
+    url.hpp                                   \
+    $(NULL)
+
+check_PROGRAMS = test-url
+
+test_url_CPPFLAGS                                             = \
+    -I$(top_srcdir)/include                                     \
+    -I$(top_srcdir)/src                                         \
+    -DSELF_TEST                                                 \
+    $(NULL)
+
+test_url_SOURCES                    = \
+    url.cpp                           \
+    $(NULL)
+
+TESTS                               = \
+    test-url                          \
+    $(NULL)
+
+include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/src/lib/url/url.cpp b/src/lib/url/url.cpp
new file mode 100644
index 0000000..a07e145
--- /dev/null
+++ b/src/lib/url/url.cpp
@@ -0,0 +1,205 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "lib/url/url.hpp"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core/common/code_utils.hpp"
+
+namespace ot {
+namespace Url {
+
+otError Url::Init(char *aUrl)
+{
+    otError error = OT_ERROR_NONE;
+    char *  url   = aUrl;
+
+    mEnd      = aUrl + strlen(aUrl);
+    mProtocol = aUrl;
+
+    url = strstr(aUrl, "://");
+    VerifyOrExit(url != nullptr, error = OT_ERROR_PARSE);
+    url += sizeof("://") - 1;
+    mPath = url;
+
+    url = strstr(url, "?");
+
+    if (url != nullptr)
+    {
+        mQuery = ++url;
+
+        for (char *cur = strtok(url, "&"); cur != nullptr; cur = strtok(nullptr, "&"))
+        {
+            cur[-1] = '\0';
+        }
+    }
+    else
+    {
+        mQuery = mEnd;
+    }
+
+exit:
+    return error;
+}
+
+const char *Url::GetValue(const char *aName, const char *aLastValue) const
+{
+    const char * rval = nullptr;
+    const size_t len  = strlen(aName);
+    const char * start;
+
+    if (aLastValue == nullptr)
+    {
+        start = mQuery;
+    }
+    else
+    {
+        VerifyOrExit(aLastValue > mQuery && aLastValue < mEnd, OT_NOOP);
+        start = aLastValue + strlen(aLastValue) + 1;
+    }
+
+    while (start < mEnd)
+    {
+        const char *last = nullptr;
+
+        if (!strncmp(aName, start, len))
+        {
+            if (start[len] == '=')
+            {
+                ExitNow(rval = &start[len + 1]);
+            }
+            else if (start[len] == '\0')
+            {
+                ExitNow(rval = "");
+            }
+        }
+        last  = start;
+        start = last + strlen(last) + 1;
+    }
+
+exit:
+    return rval;
+}
+
+} // namespace Url
+} // namespace ot
+
+#ifndef SELF_TEST
+#define SELF_TEST 0
+#endif
+
+#if SELF_TEST
+#include <assert.h>
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+
+void TestSimple(void)
+{
+    char         url[] = "spinel:///dev/ttyUSB0?baudrate=115200";
+    ot::Url::Url args;
+
+    assert(!args.Init(url));
+
+    assert(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
+    assert(!strcmp(args.GetValue("baudrate"), "115200"));
+    assert(args.GetValue("not-exists") == nullptr);
+    assert(args.GetValue("last-value-wrong-position", url) == nullptr);
+    assert(args.GetValue("last-value-before-url", url - 1) == nullptr);
+    assert(args.GetValue("last-value-after-url", url + sizeof(url)) == nullptr);
+
+    printf("PASS %s\r\n", __func__);
+}
+
+void TestSimpleNoQueryString(void)
+{
+    char         url[] = "spinel:///dev/ttyUSB0";
+    ot::Url::Url args;
+
+    assert(!args.Init(url));
+    assert(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
+    assert(args.GetValue("last-value-wrong-position", url) == nullptr);
+    assert(args.GetValue("last-value-before-url", url - 1) == nullptr);
+    assert(args.GetValue("last-value-after-url", url + sizeof(url)) == nullptr);
+
+    printf("PASS %s\r\n", __func__);
+}
+
+void TestMultipleProtocols(void)
+{
+    char         url[] = "spinel+spi:///dev/ttyUSB0?baudrate=115200";
+    ot::Url::Url args;
+
+    assert(!args.Init(url));
+    assert(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
+    assert(!strcmp(args.GetValue("baudrate"), "115200"));
+
+    printf("PASS %s\r\n", __func__);
+}
+
+void TestMultipleProtocolsAndDuplicateParameters(void)
+{
+    char         url[] = "spinel+exec:///path/to/ot-rcp?arg=1&arg=arg2&arg=3";
+    ot::Url::Url args;
+    const char * arg = nullptr;
+
+    assert(!args.Init(url));
+    assert(!strcmp(args.GetPath(), "/path/to/ot-rcp"));
+
+    arg = args.GetValue("arg");
+    assert(!strcmp(arg, "1"));
+
+    arg = args.GetValue("arg", arg);
+    assert(!strcmp(arg, "arg2"));
+
+    arg = args.GetValue("arg", arg);
+    assert(!strcmp(arg, "3"));
+
+    assert(args.GetValue("arg", url) == nullptr);
+    assert(args.GetValue("arg", url - 1) == nullptr);
+    assert(args.GetValue("arg", url + sizeof(url)) == nullptr);
+
+    printf("PASS %s\r\n", __func__);
+}
+
+#pragma GCC diagnostic pop
+
+int main(void)
+{
+    TestSimple();
+    TestSimpleNoQueryString();
+    TestMultipleProtocols();
+    TestMultipleProtocolsAndDuplicateParameters();
+
+    return 0;
+}
+
+#endif // SELF_TEST
diff --git a/src/lib/url/url.hpp b/src/lib/url/url.hpp
new file mode 100644
index 0000000..64dce12
--- /dev/null
+++ b/src/lib/url/url.hpp
@@ -0,0 +1,100 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OT_LIB_URL_URL_HPP_
+#define OT_LIB_URL_URL_HPP_
+
+#include <openthread/error.h>
+
+/**
+ * @struct otUrl
+ *
+ * This structure represents a URL.
+ *
+ */
+struct otUrl
+{
+    const char *mProtocol; ///< The URL protocol.
+    const char *mPath;     ///< The path.
+    const char *mQuery;    ///< The start of the URL query string.
+    const char *mEnd;      ///< The end of the URL buffer.
+};
+
+namespace ot {
+namespace Url {
+
+/**
+ * This class implements the URL processing.
+ *
+ */
+class Url : public otUrl
+{
+public:
+    /**
+     * This method initializes the URL.
+     *
+     * @param[in]   aUrl    A buffer stores the null-terminated URL string.
+     *
+     * @retval  OT_ERROR_NONE   Successfully parsed the URL.
+     * @retval  OT_ERROR_PARSE  Failed to parse the string as a URL.
+     *
+     */
+    otError Init(char *aUrl);
+
+    /**
+     * This method gets the path in URL.
+     *
+     * @returns The path in url.
+     *
+     */
+    const char *GetPath(void) const { return mPath; }
+
+    /**
+     * This method gets the value of parameter @p aName.
+     *
+     * @param[in] aName       The parameter name.
+     * @param[in] aLastValue  The last iterated parameter value, nullptr for the first value.
+     *
+     * @returns The parameter value.
+     *
+     */
+    const char *GetValue(const char *aName, const char *aLastValue = nullptr) const;
+
+    /**
+     * This method returns the URL protocol.
+     *
+     * @returns The URL protocol.
+     *
+     */
+    const char *GetProtocol(void) const { return mProtocol; }
+};
+
+} // namespace Url
+} // namespace ot
+
+#endif // OT_LIB_URL_URL_HPP_
diff --git a/src/ncp/CMakeLists.txt b/src/ncp/CMakeLists.txt
index e45ffb0..96928e8 100644
--- a/src/ncp/CMakeLists.txt
+++ b/src/ncp/CMakeLists.txt
@@ -30,50 +30,105 @@
 add_library(openthread-ncp-mtd)
 add_library(openthread-rcp)
 
+# We depend on C++11 to validate that NCP handlers are sorted.
+set_target_properties(
+    openthread-ncp-ftd openthread-ncp-mtd openthread-rcp
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
 target_compile_definitions(openthread-ncp-ftd PRIVATE
-    ${OT_PRIVATE_DEFINES}
     OPENTHREAD_FTD=1
     OPENTHREAD_CONFIG_NCP_UART_ENABLE=1
 )
 
 target_compile_definitions(openthread-ncp-mtd PRIVATE
-    ${OT_PRIVATE_DEFINES}
     OPENTHREAD_MTD=1
     OPENTHREAD_CONFIG_NCP_UART_ENABLE=1
 )
 
 target_compile_definitions(openthread-rcp PRIVATE
-    ${OT_PRIVATE_DEFINES}
     OPENTHREAD_RADIO=1
     OPENTHREAD_CONFIG_NCP_UART_ENABLE=1
 )
 
+target_compile_options(openthread-ncp-ftd PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_compile_options(openthread-ncp-mtd PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_compile_options(openthread-rcp PRIVATE
+    ${OT_CFLAGS}
+)
+
 set(COMMON_INCLUDES
-    ${OT_PRIVATE_INCLUDES}
     ${PROJECT_SOURCE_DIR}/src
     ${PROJECT_SOURCE_DIR}/src/core
 )
 
 set(COMMON_SOURCES
     changed_props_set.cpp
-    hdlc.cpp
     ncp_base.cpp
+    ncp_base_dispatcher.cpp
     ncp_base_ftd.cpp
     ncp_base_mtd.cpp
     ncp_base_radio.cpp
-    ncp_base_dispatcher.cpp
-    ncp_buffer.cpp
     ncp_spi.cpp
     ncp_uart.cpp
-    spinel.c
-    spinel_decoder.cpp
-    spinel_encoder.cpp
 )
 
+set(OT_NCP_VENDOR_HOOK_SOURCE "" CACHE STRING "set vendor hook source file for NCP")
+if(OT_NCP_VENDOR_HOOK_SOURCE)
+    target_compile_definitions(ot-config INTERFACE "OPENTHREAD_ENABLE_NCP_VENDOR_HOOK=1")
+    list(APPEND COMMON_SOURCES ${OT_NCP_VENDOR_HOOK_SOURCE})
+endif()
+
 target_include_directories(openthread-ncp-ftd PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
 target_include_directories(openthread-ncp-mtd PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
 target_include_directories(openthread-rcp PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
 
 target_sources(openthread-ncp-ftd PRIVATE ${COMMON_SOURCES})
 target_sources(openthread-ncp-mtd PRIVATE ${COMMON_SOURCES})
-target_sources(openthread-rcp PRIVATE ${COMMON_SOURCES})
+
+target_sources(openthread-rcp PRIVATE
+    changed_props_set.cpp
+    ncp_base.cpp
+    ncp_base_dispatcher.cpp
+    ncp_base_radio.cpp
+    ncp_spi.cpp
+    ncp_uart.cpp
+)
+
+target_link_libraries(openthread-ncp-ftd
+    PUBLIC
+        openthread-ftd
+    PRIVATE
+        ${OT_PLATFORM_LIB}
+        ${OT_MBEDTLS}
+        openthread-hdlc
+        openthread-spinel-ncp
+        ot-config
+)
+
+target_link_libraries(openthread-ncp-mtd
+    PUBLIC
+        openthread-mtd
+    PRIVATE
+        ${OT_MBEDTLS}
+        openthread-hdlc
+        openthread-spinel-ncp
+        ot-config
+)
+
+target_link_libraries(openthread-rcp
+    PUBLIC
+        openthread-radio
+    PRIVATE
+        openthread-hdlc
+        openthread-spinel-rcp
+        ot-config
+)
diff --git a/src/ncp/Makefile.am b/src/ncp/Makefile.am
index 24e301b..7733e9f 100644
--- a/src/ncp/Makefile.am
+++ b/src/ncp/Makefile.am
@@ -27,6 +27,7 @@
 #
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+include $(top_srcdir)/src/lib/common.am
 
 EXTRA_DIST                                        = \
     example_vendor_hook.cpp                         \
@@ -58,52 +59,59 @@
     $(OPENTHREAD_TARGET_DEFINES)                    \
     $(NULL)
 
-libopenthread_ncp_mtd_a_CPPFLAGS                  = \
-    -DOPENTHREAD_RADIO=0                            \
-    -DOPENTHREAD_FTD=0                              \
-    -DOPENTHREAD_MTD=1                              \
-    $(COMMON_CPPFLAGS)                              \
+libopenthread_ncp_mtd_a_CPPFLAGS                         = \
+    -DOPENTHREAD_RADIO=0                                   \
+    -DOPENTHREAD_FTD=0                                     \
+    -DOPENTHREAD_MTD=1                                     \
+    -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1 \
+    $(COMMON_CPPFLAGS)                                     \
     $(NULL)
 
-libopenthread_ncp_ftd_a_CPPFLAGS                  = \
-    -DOPENTHREAD_RADIO=0                            \
-    -DOPENTHREAD_FTD=1                              \
-    -DOPENTHREAD_MTD=0                              \
-    $(COMMON_CPPFLAGS)                              \
+libopenthread_ncp_ftd_a_CPPFLAGS                         = \
+    -DOPENTHREAD_RADIO=0                                   \
+    -DOPENTHREAD_FTD=1                                     \
+    -DOPENTHREAD_MTD=0                                     \
+    -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1 \
+    $(COMMON_CPPFLAGS)                                     \
     $(NULL)
 
-libopenthread_rcp_a_CPPFLAGS                      = \
-    -DOPENTHREAD_RADIO=1                            \
-    -DOPENTHREAD_FTD=0                              \
-    -DOPENTHREAD_MTD=0                              \
-    $(COMMON_CPPFLAGS)                              \
+libopenthread_rcp_a_CPPFLAGS                             = \
+    -DOPENTHREAD_RADIO=1                                   \
+    -DOPENTHREAD_FTD=0                                     \
+    -DOPENTHREAD_MTD=0                                     \
+    -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=0 \
+    $(COMMON_CPPFLAGS)                                     \
+    $(NULL)
+
+libopenthread_ncp_mtd_a_LIBADD                                                      = \
+    $(call ot_list_objects,$(top_builddir)/src/lib/hdlc/libopenthread-hdlc.a)         \
+    $(call ot_list_objects,$(top_builddir)/src/lib/spinel/libopenthread-spinel-ncp.a) \
+    $(NULL)
+
+libopenthread_ncp_ftd_a_LIBADD                                                      = \
+    $(call ot_list_objects,$(top_builddir)/src/lib/hdlc/libopenthread-hdlc.a  )       \
+    $(call ot_list_objects,$(top_builddir)/src/lib/spinel/libopenthread-spinel-ncp.a) \
+    $(NULL)
+
+libopenthread_rcp_a_LIBADD                                                          = \
+    $(call ot_list_objects,$(top_builddir)/src/lib/hdlc/libopenthread-hdlc.a)         \
+    $(call ot_list_objects,$(top_builddir)/src/lib/spinel/libopenthread-spinel-rcp.a) \
     $(NULL)
 
 COMMON_SOURCES                                    = \
     changed_props_set.cpp                           \
     changed_props_set.hpp                           \
-    hdlc.cpp                                        \
-    hdlc.hpp                                        \
     ncp_base.cpp                                    \
     ncp_base.hpp                                    \
     ncp_base_ftd.cpp                                \
     ncp_base_mtd.cpp                                \
     ncp_base_radio.cpp                              \
     ncp_base_dispatcher.cpp                         \
-    ncp_buffer.cpp                                  \
-    ncp_buffer.hpp                                  \
     ncp_config.h                                    \
     ncp_spi.cpp                                     \
     ncp_spi.hpp                                     \
     ncp_uart.cpp                                    \
     ncp_uart.hpp                                    \
-    spinel.c                                        \
-    spinel.h                                        \
-    spinel_decoder.cpp                              \
-    spinel_decoder.hpp                              \
-    spinel_encoder.cpp                              \
-    spinel_encoder.hpp                              \
-    spinel_platform.h                               \
     $(NULL)
 
 if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
@@ -139,25 +147,4 @@
 include_HEADERS                                   = \
     $(NULL)
 
-if OPENTHREAD_BUILD_TESTS
-
-check_PROGRAMS                                    = spinel-test
-spinel_test_SOURCES                               = spinel.c
-spinel_test_CFLAGS                                = \
-    $(COMMON_CPPFLAGS)                              \
-    -DSPINEL_SELF_TEST=1                            \
-    -D_GNU_SOURCE                                   \
-    -I$(top_srcdir)/src/core                        \
-    -I$(top_srcdir)/include                         \
-    $(NULL)
-
-TESTS                                             = spinel-test
-
-install-headers: install-includeHEADERS
-
-if OPENTHREAD_BUILD_COVERAGE
-CLEANFILES                                        = $(wildcard *.gcda *.gcno)
-endif # OPENTHREAD_BUILD_COVERAGE
-endif # OPENTHREAD_BUILD_TESTS
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/src/ncp/changed_props_set.cpp b/src/ncp/changed_props_set.cpp
index c266053..8a167e3 100644
--- a/src/ncp/changed_props_set.cpp
+++ b/src/ncp/changed_props_set.cpp
@@ -99,8 +99,8 @@
 
 uint8_t ChangedPropsSet::GetNumEntries(void) const
 {
-    OT_STATIC_ASSERT(OT_ARRAY_LENGTH(mSupportedProps) <= sizeof(mChangedSet) * CHAR_BIT,
-                     "Changed set size is smaller than number of entries in `mSupportedProps[]` array");
+    static_assert(OT_ARRAY_LENGTH(mSupportedProps) <= sizeof(mChangedSet) * CHAR_BIT,
+                  "Changed set size is smaller than number of entries in `mSupportedProps[]` array");
 
     return OT_ARRAY_LENGTH(mSupportedProps);
 }
diff --git a/src/ncp/changed_props_set.hpp b/src/ncp/changed_props_set.hpp
index c92db15..0b7040c 100644
--- a/src/ncp/changed_props_set.hpp
+++ b/src/ncp/changed_props_set.hpp
@@ -39,7 +39,7 @@
 
 #include <openthread/error.h>
 
-#include "spinel.h"
+#include "lib/spinel/spinel.h"
 
 namespace ot {
 namespace Ncp {
@@ -127,10 +127,13 @@
      *
      * @param[in] aIndex     The index to an entry.
      *
-     * @returns A pointer to the entry associated with @p aIndex, or NULL if the index is beyond end of array.
+     * @returns A pointer to the entry associated with @p aIndex, or nullptr if the index is beyond end of array.
      *
      */
-    const Entry *GetEntry(uint8_t aIndex) const { return (aIndex < GetNumEntries()) ? &mSupportedProps[aIndex] : NULL; }
+    const Entry *GetEntry(uint8_t aIndex) const
+    {
+        return (aIndex < GetNumEntries()) ? &mSupportedProps[aIndex] : nullptr;
+    }
 
     /**
      * This method indicates if the entry associated with an index is in the set (i.e., it has been changed and
diff --git a/src/ncp/example_vendor_hook.cpp b/src/ncp/example_vendor_hook.cpp
index 948c8f1..195e084 100644
--- a/src/ncp/example_vendor_hook.cpp
+++ b/src/ncp/example_vendor_hook.cpp
@@ -43,8 +43,7 @@
 
     switch (aCommand)
     {
-
-    // TODO: Implement your command handlers here.
+        // TODO: Implement your command handlers here.
 
     default:
         error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_INVALID_COMMAND);
@@ -53,7 +52,7 @@
     return error;
 }
 
-void NcpBase::VendorHandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag)
+void NcpBase::VendorHandleFrameRemovedFromNcpBuffer(Spinel::Buffer::FrameTag aFrameTag)
 {
     // This method is a callback which mirrors `NcpBase::HandleFrameRemovedFromNcpBuffer()`.
     // It is called when a spinel frame is sent and removed from NCP buffer.
@@ -75,13 +74,12 @@
 
     switch (aPropKey)
     {
-
-    // TODO: Implement your property get handlers here.
-    //
-    // Get handler should retrieve the property value and then encode and write the
-    // value into the NCP buffer. If the "get" operation itself fails, handler should
-    // write a `LAST_STATUS` with the error status into the NCP buffer. `OT_ERROR_NO_BUFS`
-    // should be returned if NCP buffer is full and response cannot be written.
+        // TODO: Implement your property get handlers here.
+        //
+        // Get handler should retrieve the property value and then encode and write the
+        // value into the NCP buffer. If the "get" operation itself fails, handler should
+        // write a `LAST_STATUS` with the error status into the NCP buffer. `OT_ERROR_NO_BUFS`
+        // should be returned if NCP buffer is full and response cannot be written.
 
     default:
         error = OT_ERROR_NOT_FOUND;
@@ -97,16 +95,15 @@
 
     switch (aPropKey)
     {
-
-    // TODO: Implement your property set handlers here.
-    //
-    // Set handler should first decode the value from the input Spinel frame and then
-    // perform the corresponding set operation. The handler should not prepare the
-    // spinel response and therefore should not write anything to the NCP buffer.
-    // The error returned from handler (other than `OT_ERROR_NOT_FOUND`) indicates the
-    // error in either parsing of the input or the error of the set operation. In case
-    // of a successful "set", `NcpBase` set command handler will invoke the
-    // `VendorGetPropertyHandler()` for the same property key to prepare the response.
+        // TODO: Implement your property set handlers here.
+        //
+        // Set handler should first decode the value from the input Spinel frame and then
+        // perform the corresponding set operation. The handler should not prepare the
+        // spinel response and therefore should not write anything to the NCP buffer.
+        // The error returned from handler (other than `OT_ERROR_NOT_FOUND`) indicates the
+        // error in either parsing of the input or the error of the set operation. In case
+        // of a successful "set", `NcpBase` set command handler will invoke the
+        // `VendorGetPropertyHandler()` for the same property key to prepare the response.
 
     default:
         error = OT_ERROR_NOT_FOUND;
@@ -116,8 +113,8 @@
     return error;
 }
 
-}  // namespace Ncp
-}  // namespace ot
+} // namespace Ncp
+} // namespace ot
 
 //-------------------------------------------------------------------------------------------------------------------
 // When OPENTHREAD_ENABLE_NCP_VENDOR_HOOK is enabled, vendor code is
@@ -135,7 +132,8 @@
 public:
     NcpVendorUart(ot::Instance *aInstance)
         : ot::Ncp::NcpUart(aInstance)
-    {}
+    {
+    }
 
     // Add public/private methods or member variables
 };
@@ -144,14 +142,14 @@
 
 extern "C" void otNcpInit(otInstance *aInstance)
 {
-    NcpVendorUart *ncpVendor = NULL;
+    NcpVendorUart *ncpVendor = nullptr;
     ot::Instance * instance  = static_cast<ot::Instance *>(aInstance);
 
     ncpVendor = new (&sNcpVendorRaw) NcpVendorUart(instance);
 
-    if (ncpVendor == NULL || ncpVendor != ot::Ncp::NcpBase::GetNcpInstance())
+    if (ncpVendor == nullptr || ncpVendor != ot::Ncp::NcpBase::GetNcpInstance())
     {
-        assert(false);
+        // assert(false);
     }
 }
 
diff --git a/src/ncp/hdlc.cpp b/src/ncp/hdlc.cpp
deleted file mode 100644
index 754365d..0000000
--- a/src/ncp/hdlc.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- *    Copyright (c) 2016, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements an HDLC-lite encoder and decoder.
- */
-
-#include "hdlc.hpp"
-
-#include <stdlib.h>
-
-#include "common/code_utils.hpp"
-
-#if OPENTHREAD_CONFIG_NCP_UART_ENABLE || OPENTHREAD_PLATFORM_POSIX_APP
-
-namespace ot {
-namespace Hdlc {
-
-/**
- * This method updates an FCS.
- *
- * @param[in]  aFcs   The FCS to update.
- * @param[in]  aByte  The input byte value.
- *
- * @returns The updated FCS.
- *
- */
-static uint16_t UpdateFcs(uint16_t aFcs, uint8_t aByte);
-
-enum
-{
-    kFlagXOn        = 0x11,
-    kFlagXOff       = 0x13,
-    kFlagSequence   = 0x7e, ///< HDLC Flag value
-    kEscapeSequence = 0x7d, ///< HDLC Escape value
-    kFlagSpecial    = 0xf8,
-};
-
-/**
- * FCS lookup table
- *
- */
-enum
-{
-    kInitFcs = 0xffff, ///< Initial FCS value.
-    kGoodFcs = 0xf0b8, ///< Good FCS value.
-    kFcsSize = 2,      ///< FCS size (number of bytes).
-};
-
-uint16_t UpdateFcs(uint16_t aFcs, uint8_t aByte)
-{
-    static const uint16_t sFcsTable[256] = {
-        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5,
-        0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52,
-        0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3,
-        0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9,
-        0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e,
-        0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f,
-        0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862,
-        0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb,
-        0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948,
-        0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226,
-        0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497,
-        0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704,
-        0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb,
-        0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c,
-        0x3de3, 0x2c6a, 0x1ef1, 0x0f78};
-    return (aFcs >> 8) ^ sFcsTable[(aFcs ^ aByte) & 0xff];
-}
-
-static bool HdlcByteNeedsEscape(uint8_t aByte)
-{
-    bool rval;
-
-    switch (aByte)
-    {
-    case kFlagXOn:
-    case kFlagXOff:
-    case kEscapeSequence:
-    case kFlagSequence:
-    case kFlagSpecial:
-        rval = true;
-        break;
-
-    default:
-        rval = false;
-        break;
-    }
-
-    return rval;
-}
-
-Encoder::Encoder(FrameWritePointer &aWritePointer)
-    : mWritePointer(aWritePointer)
-    , mFcs(0)
-{
-}
-
-otError Encoder::BeginFrame(void)
-{
-    mFcs = kInitFcs;
-
-    return mWritePointer.WriteByte(kFlagSequence);
-}
-
-otError Encoder::Encode(uint8_t aByte)
-{
-    otError error = OT_ERROR_NONE;
-
-    if (HdlcByteNeedsEscape(aByte))
-    {
-        VerifyOrExit(mWritePointer.CanWrite(2), error = OT_ERROR_NO_BUFS);
-
-        mWritePointer.WriteByte(kEscapeSequence);
-        mWritePointer.WriteByte(aByte ^ 0x20);
-    }
-    else
-    {
-        SuccessOrExit(error = mWritePointer.WriteByte(aByte));
-    }
-
-    mFcs = UpdateFcs(mFcs, aByte);
-
-exit:
-    return error;
-}
-
-otError Encoder::Encode(const uint8_t *aData, uint16_t aLength)
-{
-    otError           error      = OT_ERROR_NONE;
-    uint16_t          oldFcs     = mFcs;
-    FrameWritePointer oldPointer = mWritePointer;
-
-    while (aLength--)
-    {
-        SuccessOrExit(error = Encode(*aData++));
-    }
-
-exit:
-
-    if (error != OT_ERROR_NONE)
-    {
-        mWritePointer = oldPointer;
-        mFcs          = oldFcs;
-    }
-
-    return error;
-}
-
-otError Encoder::EndFrame(void)
-{
-    otError           error      = OT_ERROR_NONE;
-    FrameWritePointer oldPointer = mWritePointer;
-    uint16_t          oldFcs     = mFcs;
-    uint16_t          fcs        = mFcs;
-
-    fcs ^= 0xffff;
-
-    SuccessOrExit(error = Encode(fcs & 0xff));
-    SuccessOrExit(error = Encode(fcs >> 8));
-
-    SuccessOrExit(error = mWritePointer.WriteByte(kFlagSequence));
-
-exit:
-
-    if (error != OT_ERROR_NONE)
-    {
-        mWritePointer = oldPointer;
-        mFcs          = oldFcs;
-    }
-
-    return error;
-}
-
-Decoder::Decoder(FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext)
-    : mState(kStateNoSync)
-    , mWritePointer(aFrameWritePointer)
-    , mFrameHandler(aFrameHandler)
-    , mContext(aContext)
-    , mFcs(0)
-    , mDecodedLength(0)
-{
-}
-
-void Decoder::Decode(const uint8_t *aData, uint16_t aLength)
-{
-    while (aLength--)
-    {
-        uint8_t byte = *aData++;
-
-        switch (mState)
-        {
-        case kStateNoSync:
-            if (byte == kFlagSequence)
-            {
-                mState         = kStateSync;
-                mDecodedLength = 0;
-                mFcs           = kInitFcs;
-            }
-
-            break;
-
-        case kStateSync:
-            switch (byte)
-            {
-            case kEscapeSequence:
-                mState = kStateEscaped;
-                break;
-
-            case kFlagSequence:
-
-                if (mDecodedLength > 0)
-                {
-                    otError error = OT_ERROR_PARSE;
-
-                    if ((mDecodedLength >= kFcsSize)
-#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-                        && (mFcs == kGoodFcs)
-#endif
-                    )
-                    {
-                        // Remove the FCS from the frame.
-                        mWritePointer.UndoLastWrites(kFcsSize);
-                        error = OT_ERROR_NONE;
-                    }
-
-                    mFrameHandler(mContext, error);
-                }
-
-                mDecodedLength = 0;
-                mFcs           = kInitFcs;
-                break;
-
-            default:
-                if (mWritePointer.CanWrite(sizeof(uint8_t)))
-                {
-                    mFcs = UpdateFcs(mFcs, byte);
-                    mWritePointer.WriteByte(byte);
-                    mDecodedLength++;
-                }
-                else
-                {
-                    mFrameHandler(mContext, OT_ERROR_NO_BUFS);
-                    mState = kStateNoSync;
-                }
-
-                break;
-            }
-
-            break;
-
-        case kStateEscaped:
-            if (mWritePointer.CanWrite(sizeof(uint8_t)))
-            {
-                byte ^= 0x20;
-                mFcs = UpdateFcs(mFcs, byte);
-                mWritePointer.WriteByte(byte);
-                mDecodedLength++;
-                mState = kStateSync;
-            }
-            else
-            {
-                mFrameHandler(mContext, OT_ERROR_NO_BUFS);
-                mState = kStateNoSync;
-            }
-
-            break;
-        }
-    }
-}
-
-} // namespace Hdlc
-} // namespace ot
-
-#endif // OPENTHREAD_CONFIG_NCP_UART_ENABLE || OPENTHREAD_PLATFORM_POSIX_APP
diff --git a/src/ncp/hdlc.hpp b/src/ncp/hdlc.hpp
deleted file mode 100644
index 9e88af2..0000000
--- a/src/ncp/hdlc.hpp
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- *    Copyright (c) 2016, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes definitions for an HDLC-lite encoder and decoder.
- */
-
-#ifndef HDLC_HPP_
-#define HDLC_HPP_
-
-#include "openthread-core-config.h"
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <openthread/error.h>
-#include "common/code_utils.hpp"
-#include "common/debug.hpp"
-#include "common/encoding.hpp"
-
-namespace ot {
-
-/**
- * @namespace ot::Hdlc
- *
- * @brief
- *   This namespace includes definitions for the HDLC-lite encoder and decoder.
- *
- */
-namespace Hdlc {
-
-/**
- * This class defines a frame write pointer used by `Hdlc::Encoder` or `Hdlc::Decoder`.
- *
- * This class defines the minimum set of APIs used by `Encoder/Decoder` for writing an encoded/decoded frame. It is
- * simply a wrapper over a pointer into a buffer indicating where next byte should be written. Along with a write
- * pointer, this class stores a remaining length variable indicating number of remaining bytes that can be written into
- * the buffer.
- *
- * @note This class does NOT define the underlying buffer space or how it is being managed.
- *
- * `Encoder` or `Decoder` users are expected to use sub-classes of this class adding the buffer space and implementing
- * the frame buffer management scheme.
- *
- * Two template sub-class `FrameBuffer` and `MultiFrameBuffer` are defined which respectively allow storing a single
- * frame or multiple frames (FIFO queue of frame) in a buffer of a given size.
- *
- */
-class FrameWritePointer
-{
-public:
-    /**
-     * This method indicates whether there is buffer space available to write @p aWriteLength bytes.
-     *
-     * param[in] aWriteLength       Number of bytes to write.
-     *
-     * @retval TRUE                 Enough buffer space is available to write the requested number of bytes.
-     * @retval FALSE                Insufficient buffer space to write the requested number of bytes.
-     *
-     */
-    bool CanWrite(uint16_t aWriteLength) const { return (mRemainingLength >= aWriteLength); }
-
-    /**
-     * This method writes a byte into the buffer and updates the write pointer (if space is available).
-     *
-     * @retval OT_ERROR_NONE     Successfully wrote the byte and updated the pointer.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space to write the byte.
-     *
-     */
-    otError WriteByte(uint8_t aByte)
-    {
-        return CanWrite(sizeof(uint8_t)) ? (*mWritePointer++ = aByte, mRemainingLength--, OT_ERROR_NONE)
-                                         : OT_ERROR_NO_BUFS;
-    }
-
-    /**
-     * This method undoes the last @p aUndoLength writes, removing them from frame.
-     *
-     * @note Caller should ensure that @p aUndoLength is less than or equal to the number of previously written bytes
-     * into the frame. This method does not perform any checks and its behavior is undefined if @p aUndoLength is
-     * larger than the number of bytes previously written into the frame.
-     *
-     * @param[in]  aUndoLength   Number of bytes to remove (number of last `WriteByte()` calls to undo).
-     *
-     */
-    void UndoLastWrites(uint16_t aUndoLength)
-    {
-        mWritePointer -= aUndoLength;
-        mRemainingLength += aUndoLength;
-    }
-
-protected:
-    FrameWritePointer(void)
-        : mWritePointer(NULL)
-        , mRemainingLength(0)
-    {
-    }
-
-    uint8_t *mWritePointer;    ///< A pointer to current write position in the buffer.
-    uint16_t mRemainingLength; ///< Number of remaining bytes available to write.
-};
-
-/**
- * This class defines a template frame buffer of a given size for storing a single frame.
- *
- * The template parameter `kSize` specifies the size of the buffer.
- *
- */
-template <uint16_t kSize> class FrameBuffer : public FrameWritePointer
-{
-public:
-    /**
-     * This constructor initializes the `FrameBuffer` object.
-     *
-     */
-    FrameBuffer(void)
-        : FrameWritePointer()
-    {
-        Clear();
-    }
-
-    /**
-     * This method clears the buffer, moving the write pointer to the beginning of the buffer.
-     *
-     */
-    void Clear(void)
-    {
-        mWritePointer    = mBuffer;
-        mRemainingLength = sizeof(mBuffer);
-    }
-
-    /**
-     * This method indicates whether the buffer is empty or contains a frame.
-     *
-     * @retval TRUE  Buffer is empty
-     * @retval FALSE Buffer contains a frame
-     *
-     */
-    bool IsEmpty(void) const { return (mWritePointer == mBuffer); }
-
-    /**
-     * This method gets the length (number of bytes) in the frame.
-     *
-     * @returns The length (number of bytes) in the frame.
-     *
-     */
-    uint16_t GetLength(void) const { return static_cast<uint16_t>(mWritePointer - mBuffer); }
-
-    /**
-     * This method gets a pointer to start of the frame.
-     *
-     * @returns A pointer to start of the frame.
-     *
-     */
-    uint8_t *GetFrame(void) { return mBuffer; }
-
-private:
-    uint8_t mBuffer[kSize];
-};
-
-/**
- * This class defines a template frame buffer of a given size for storing multiple frames.
- *
- * The template parameter `kSize` specifies the total size of the buffer.
- *
- * Unlike `FrameBuffer` class where a single frame can be stored, this class is capable of saving multiple frames
- * in a FIFO queue format.
- *
- */
-template <uint16_t kSize> class MultiFrameBuffer : public FrameWritePointer
-{
-public:
-    /**
-     * This constructor initializes the `MultiFrameBuffer` object.
-     *
-     */
-    MultiFrameBuffer(void)
-        : FrameWritePointer()
-    {
-        Clear();
-    }
-
-    /**
-     * This method clears the buffer, removing current frame and all previously saved frames.
-     *
-     * It moves the write pointer to the beginning of the buffer.
-     *
-     */
-    void Clear(void)
-    {
-        mWriteFrameStart = mBuffer;
-        mWritePointer    = mBuffer + kHeaderSize;
-        mRemainingLength = kSize - kHeaderSize;
-    }
-
-    /**
-     * This method indicates whether the current frame (being written) is empty or not.
-     *
-     * @retval TRUE  Current frame is empty.
-     * @retval FALSE Current frame is not empty.
-     *
-     */
-    bool HasFrame(void) const { return (mWritePointer != mWriteFrameStart + kHeaderSize); }
-
-    /**
-     * This method gets the length (number of bytes) in the current frame being written into the buffer.
-     *
-     * @returns The length (number of bytes) in the frame.
-     *
-     */
-    uint16_t GetLength(void) const { return static_cast<uint16_t>(mWritePointer - mWriteFrameStart - kHeaderSize); }
-
-    /**
-     * This method gets a pointer to the start of the current frame.
-     *
-     * @returns A pointer to the start of the frame.
-     *
-     */
-    uint8_t *GetFrame(void) { return mWriteFrameStart + kHeaderSize; }
-
-    /**
-     * This method saves the current frame and prepares the write pointer for a next frame to be written into the
-     * buffer.
-     *
-     * Saved frame can be retrieved later using `GetNextSavedFrame()`.
-     *
-     */
-    void SaveFrame(void)
-    {
-        Encoding::LittleEndian::WriteUint16(GetLength(), mWriteFrameStart);
-        mWriteFrameStart = mWritePointer;
-        mWritePointer += kHeaderSize;
-        mRemainingLength = static_cast<uint16_t>(mBuffer + kSize - mWritePointer);
-    }
-
-    /**
-     * This method discards the current frame and prepares the write pointer for a next frame to be written into the
-     * buffer.
-     *
-     */
-    void DiscardFrame(void)
-    {
-        mWritePointer    = mWriteFrameStart + kHeaderSize;
-        mRemainingLength = static_cast<uint16_t>(mBuffer + kSize - mWritePointer);
-    }
-
-    /**
-     * This method indicates whether there are any saved frames in the buffer.
-     *
-     * @retval TRUE  There is at least one saved frame in the buffer.
-     * @retval FALSE There is no saved frame in the buffer.
-     *
-     */
-    bool HasSavedFrame(void) const { return (mWriteFrameStart != mBuffer); }
-
-    /**
-     * This method iterates through previously saved frames in the buffer, getting a next frame in the queue.
-     *
-     * @param[inout] aFrame   On entry, should point to a previous saved frame or NULL to get the first frame.
-     *                        On exit, the pointer variable is updated to next frame or set to NULL if there are none.
-     * @param[out]   aLength  A reference to a variable to return the frame length (number of bytes).
-     *
-     * @retval OT_ERROR_NONE       Updated @aFrame and @aLength successfully with the next saved frame.
-     * @retval OT_ERROR_NOT_FOUND  No more saved frame in the buffer.
-     *
-     */
-    otError GetNextSavedFrame(uint8_t *&aFrame, uint16_t &aLength)
-    {
-        otError error = OT_ERROR_NONE;
-
-        assert(aFrame == NULL || (mBuffer <= aFrame && aFrame < OT_ARRAY_END(mBuffer)));
-
-        aFrame = (aFrame == NULL) ? mBuffer : aFrame + Encoding::LittleEndian::ReadUint16(aFrame - kHeaderSize);
-
-        if (aFrame != mWriteFrameStart)
-        {
-            aLength = Encoding::LittleEndian::ReadUint16(aFrame);
-            aFrame += kHeaderSize;
-        }
-        else
-        {
-            aLength = 0;
-            aFrame  = NULL;
-            error   = OT_ERROR_NOT_FOUND;
-        }
-
-        return error;
-    }
-
-    /**
-     * This method clears all saved frames from the buffer and adjusts all the pointers.
-     *
-     * @note This method moves the pointers into the buffer and also copies the content. Any previously retrieved
-     * pointer to buffer (from `GetFrame()` or `GetNextSavedFrame()`) should be considered invalid after calling this
-     * method.
-     *
-     */
-    void ClearSavedFrames(void)
-    {
-        uint16_t len = static_cast<uint16_t>(mWriteFrameStart - mBuffer);
-
-        if (len > 0)
-        {
-            memmove(mBuffer, mWriteFrameStart, static_cast<uint16_t>(mWritePointer - mWriteFrameStart));
-            mWritePointer -= len;
-            mWriteFrameStart -= len;
-            mRemainingLength += len;
-        }
-    }
-
-private:
-    /*
-     * The diagram below illustrates how the frames are saved in the buffer.
-     *
-     * Each saved frame contains a header which is 2 bytes long and specifies the frame length (the length does not
-     * include the header itself). The frame length is stored in header bytes as a `uint16_t` value using little-endian
-     * encoding.
-     *
-     * The diagram shows `mBuffer` and different pointers into the buffer. It represents buffer state when there are
-     * two saved frames in the buffer.
-     *
-     *          Saved frame #1           Saved frame #2       Current frame being written
-     *   /                        \ /                      \ /                           \
-     *   +-----------+-------------+-----------+------------+---------+--------------------------------------------+
-     *   | header #1 |   ...       | header #2 |  ...       | header  |  ...             | ...                     |
-     *   +-----------+-------------+-----------+------------+---------+--------------------------------------------+
-     *   ^                                                  ^                            ^\                       /^
-     *   |                                                  |                            |   mRemainingLength      |
-     *  mBuffer[0]                                          mWriteFrameStart             |                         |
-     *                                                                                   |              mBuffer[kSize]
-     *                                                                                 mWritePointer
-     */
-
-    enum
-    {
-        kHeaderSize = sizeof(uint16_t),
-    };
-
-    uint8_t  mBuffer[kSize];
-    uint8_t *mWriteFrameStart; // Pointer to start of current frame being written.
-};
-
-/**
- * This class implements the HDLC-lite encoder.
- *
- */
-class Encoder
-{
-public:
-    /**
-     * This constructor initializes the object.
-     *
-     * @param[in] aWritePointer   The `FrameWritePointer` used by `Encoder` to write the encoded frames.
-     *
-     */
-    explicit Encoder(FrameWritePointer &aWritePointer);
-
-    /**
-     * This method begins an HDLC frame.
-     *
-     * @retval OT_ERROR_NONE     Successfully started the HDLC frame.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to start the HDLC frame.
-     *
-     */
-    otError BeginFrame(void);
-
-    /**
-     * This method encodes a single byte into current frame.
-     *
-     * If there is no space to add the byte, the write pointer in frame buffer remains the same.
-     *
-     * @param[in]    aByte       A byte value to encode and add to frame.
-     *
-     * @retval OT_ERROR_NONE     Successfully encoded and added the byte to frame buffer.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to encode and add the byte.
-     *
-     */
-    otError Encode(uint8_t aByte);
-
-    /**
-     * This method encodes a given block of data into current frame.
-     *
-     * This method returns success only if there is space in buffer to encode the entire block of data. If there is no
-     * space to encode the entire block of data, the write pointer in frame buffer remains the same.
-     *
-     * @param[in]    aData       A pointer to a buffer containing the data to encode.
-     * @param[in]    aLength     The number of bytes in @p aData.
-     *
-     * @retval OT_ERROR_NONE     Successfully encoded and added the data to frame.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to add the frame.
-     *
-     */
-    otError Encode(const uint8_t *aData, uint16_t aLength);
-
-    /**
-     * This method ends/finalizes the HDLC frame.
-     *
-     * @retval OT_ERROR_NONE     Successfully ended the HDLC frame.
-     * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to end the HDLC frame.
-     *
-     */
-    otError EndFrame(void);
-
-private:
-    FrameWritePointer &mWritePointer;
-    uint16_t           mFcs;
-};
-
-/**
- * This class implements the HDLC-lite decoder.
- *
- */
-class Decoder
-{
-public:
-    /**
-     * This function pointer is called when either a complete frame has been decoded or an error occurs during
-     * decoding.
-     *
-     * The decoded frame (or the partially decoded frame in case of an error) is available in `aFrameWritePointer`
-     * buffer given in `Decoder` constructor.
-     *
-     * @param[in] aContext A pointer to arbitrary context information.
-     * @param[in] aError   OT_ERROR_NONE    if the frame was decoded successfully,
-     *                     OT_ERROR_PARSE   if the Frame Check Sequence (FCS) was incorrect in decoded frame,
-     *                     OT_ERROR_NO_BUFS insufficient buffer space available to save the decoded frame.
-     *
-     */
-    typedef void (*FrameHandler)(void *aContext, otError aError);
-
-    /**
-     * This constructor initializes the decoder.
-     *
-     * @param[in] aFrameWritePointer   The `FrameWritePointer` used by `Decoder` to write the decoded frames.
-     * @param[in] aFrameHandler        The frame handler callback function pointer.
-     * @param[in] aContext             A pointer to arbitrary context information.
-     *
-     */
-    Decoder(FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext);
-
-    /**
-     * This method feeds a block of data into the decoder.
-     *
-     * If during decoding, a full HDLC frame is successfully decoded or an error occurs, the `FrameHandler` callback
-     * is called. The decoded frame (or the partially decoded frame in case of an error) is available in
-     * `aFrameWritePointer` buffer from the constructor. The `Decoder` user (if required) must update/reset the write
-     * pointer from this callback for the next frame to be decoded.
-     *
-     * @param[in]  aData    A pointer to a buffer containing data to be fed to decoder.
-     * @param[in]  aLength  The number of bytes in @p aData.
-     *
-     */
-    void Decode(const uint8_t *aData, uint16_t aLength);
-
-private:
-    enum State
-    {
-        kStateNoSync,
-        kStateSync,
-        kStateEscaped,
-    };
-
-    State              mState;
-    FrameWritePointer &mWritePointer;
-    FrameHandler       mFrameHandler;
-    void *             mContext;
-    uint16_t           mFcs;
-    uint16_t           mDecodedLength;
-};
-
-} // namespace Hdlc
-} // namespace ot
-
-#endif // HDLC_HPP_
diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp
index bb91b56..bd17952 100644
--- a/src/ncp/ncp_base.cpp
+++ b/src/ncp/ncp_base.cpp
@@ -191,7 +191,7 @@
 // MARK: Class Boilerplate
 // ----------------------------------------------------------------------------
 
-NcpBase *NcpBase::sNcpInstance = NULL;
+NcpBase *NcpBase::sNcpInstance = nullptr;
 
 NcpBase::NcpBase(Instance *aInstance)
     : mInstance(aInstance)
@@ -205,15 +205,15 @@
     , mDiscoveryScanJoinerFlag(false)
     , mDiscoveryScanEnableFiltering(false)
     , mDiscoveryScanPanId(0xffff)
-    , mUpdateChangedPropsTask(*aInstance, &NcpBase::UpdateChangedProps, this)
+    , mUpdateChangedPropsTask(*aInstance, NcpBase::UpdateChangedProps, this)
     , mThreadChangedFlags(0)
     , mChangedPropsSet()
     , mHostPowerState(SPINEL_HOST_POWER_STATE_ONLINE)
-    , mHostPowerReplyFrameTag(NcpFrameBuffer::kInvalidTag)
+    , mHostPowerReplyFrameTag(Spinel::Buffer::kInvalidTag)
     , mHostPowerStateHeader(0)
 #if OPENTHREAD_CONFIG_NCP_ENABLE_PEEK_POKE
-    , mAllowPeekDelegate(NULL)
-    , mAllowPokeDelegate(NULL)
+    , mAllowPeekDelegate(nullptr)
+    , mAllowPokeDelegate(nullptr)
 #endif
     , mNextExpectedTid(0)
     , mResponseQueueHead(0)
@@ -250,7 +250,7 @@
     , mDidInitialUpdates(false)
     , mLogTimestampBase(0)
 {
-    assert(mInstance != NULL);
+    OT_ASSERT(mInstance != nullptr);
 
     sNcpInstance = this;
 
@@ -260,7 +260,7 @@
 
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
     otMessageQueueInit(&mMessageQueue);
-    otSetStateChangedCallback(mInstance, &NcpBase::HandleStateChanged, this);
+    IgnoreError(otSetStateChangedCallback(mInstance, &NcpBase::HandleStateChanged, this));
     otIp6SetReceiveCallback(mInstance, &NcpBase::HandleDatagramFromStack, this);
     otIp6SetReceiveFilterEnabled(mInstance, true);
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
@@ -279,7 +279,7 @@
 #endif // OPENTHREAD_FTD
 #if OPENTHREAD_CONFIG_LEGACY_ENABLE
     mLegacyNodeDidJoin = false;
-    mLegacyHandlers    = NULL;
+    mLegacyHandlers    = nullptr;
     memset(mLegacyUlaPrefix, 0, sizeof(mLegacyUlaPrefix));
     memset(&mLegacyLastJoinedNode, 0, sizeof(mLegacyLastJoinedNode));
 #endif
@@ -318,7 +318,7 @@
 // MARK: Serial Traffic Glue
 // ----------------------------------------------------------------------------
 
-NcpFrameBuffer::FrameTag NcpBase::GetLastOutboundFrameTag(void)
+Spinel::Buffer::FrameTag NcpBase::GetLastOutboundFrameTag(void)
 {
     return mTxFrameBuffer.InFrameGetLastTag();
 }
@@ -341,14 +341,14 @@
     // Skip if there is no header byte to read or this isn't a spinel frame.
 
     SuccessOrExit(mDecoder.ReadUint8(header));
-    VerifyOrExit((SPINEL_HEADER_FLAG & header) == SPINEL_HEADER_FLAG);
+    VerifyOrExit((SPINEL_HEADER_FLAG & header) == SPINEL_HEADER_FLAG, OT_NOOP);
 
     mRxSpinelFrameCounter++;
 
     // We only support IID zero for now.
     if (SPINEL_HEADER_GET_IID(header) != 0)
     {
-        WriteLastStatusFrame(header, SPINEL_STATUS_INVALID_INTERFACE);
+        IgnoreError(WriteLastStatusFrame(header, SPINEL_STATUS_INVALID_INTERFACE));
         ExitNow();
     }
 
@@ -356,7 +356,7 @@
 
     if (error != OT_ERROR_NONE)
     {
-        PrepareLastStatusResponse(header, ThreadErrorToSpinelStatus(error));
+        IgnoreError(PrepareLastStatusResponse(header, ThreadErrorToSpinelStatus(error)));
     }
 
     if (!IsResponseQueueEmpty())
@@ -368,7 +368,7 @@
         // from `HandleFrameRemovedFromNcpBuffer()` when buffer space
         // becomes available.
 
-        IgnoreReturnValue(SendQueuedResponses());
+        IgnoreError(SendQueuedResponses());
     }
 
     // Check for out of sequence TIDs and update `mNextExpectedTid`,
@@ -387,9 +387,9 @@
 }
 
 void NcpBase::HandleFrameRemovedFromNcpBuffer(void *                   aContext,
-                                              NcpFrameBuffer::FrameTag aFrameTag,
-                                              NcpFrameBuffer::Priority aPriority,
-                                              NcpFrameBuffer *         aNcpBuffer)
+                                              Spinel::Buffer::FrameTag aFrameTag,
+                                              Spinel::Buffer::Priority aPriority,
+                                              Spinel::Buffer *         aNcpBuffer)
 {
     OT_UNUSED_VARIABLE(aNcpBuffer);
     OT_UNUSED_VARIABLE(aPriority);
@@ -397,7 +397,7 @@
     static_cast<NcpBase *>(aContext)->HandleFrameRemovedFromNcpBuffer(aFrameTag);
 }
 
-void NcpBase::HandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag)
+void NcpBase::HandleFrameRemovedFromNcpBuffer(Spinel::Buffer::FrameTag aFrameTag)
 {
     if (mHostPowerStateInProgress)
     {
@@ -608,6 +608,13 @@
     case OT_LOG_REGION_UTIL:
         spinelLogRegion = SPINEL_NCP_LOG_REGION_OT_UTIL;
         break;
+
+    case OT_LOG_REGION_BBR:
+        spinelLogRegion = SPINEL_NCP_LOG_REGION_OT_BBR;
+        break;
+    case OT_LOG_REGION_MLR:
+        spinelLogRegion = SPINEL_NCP_LOG_REGION_OT_MLR;
+        break;
     }
 
     return spinelLogRegion;
@@ -619,7 +626,7 @@
     uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
 
     VerifyOrExit(!mDisableStreamWrite, error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(SPINEL_PROP_STREAM_LOG));
+    VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(SPINEL_PROP_STREAM_LOG), OT_NOOP);
 
     // If there is a pending queued response we do not allow any new log
     // stream writes. This is to ensure that log messages can not continue
@@ -807,7 +814,7 @@
     ProcessThreadChangedFlags();
 #endif
 
-    VerifyOrExit(!mChangedPropsSet.IsEmpty());
+    VerifyOrExit(!mChangedPropsSet.IsEmpty(), OT_NOOP);
 
     entry = mChangedPropsSet.GetSupportedEntries(numEntries);
 
@@ -837,7 +844,7 @@
         }
 
         mChangedPropsSet.RemoveEntry(index);
-        VerifyOrExit(!mChangedPropsSet.IsEmpty());
+        VerifyOrExit(!mChangedPropsSet.IsEmpty(), OT_NOOP);
     }
 
 exit:
@@ -961,7 +968,7 @@
     otError         error   = OT_ERROR_NONE;
     PropertyHandler handler = FindSetPropertyHandler(aKey);
 
-    if (handler != NULL)
+    if (handler != nullptr)
     {
         mDisableStreamWrite = false;
         error               = (this->*handler)();
@@ -974,7 +981,7 @@
 
         bool didHandle = HandlePropertySetForSpecialProperties(aHeader, aKey, error);
 
-        VerifyOrExit(!didHandle);
+        VerifyOrExit(!didHandle, OT_NOOP);
 
 #if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
         if (aKey >= SPINEL_PROP_VENDOR__BEGIN && aKey < SPINEL_PROP_VENDOR__END)
@@ -1012,7 +1019,7 @@
 otError NcpBase::HandleCommandPropertyInsertRemove(uint8_t aHeader, spinel_prop_key_t aKey, unsigned int aCommand)
 {
     otError         error           = OT_ERROR_NONE;
-    PropertyHandler handler         = NULL;
+    PropertyHandler handler         = nullptr;
     unsigned int    responseCommand = 0;
     const uint8_t * valuePtr;
     uint16_t        valueLen;
@@ -1030,11 +1037,11 @@
         break;
 
     default:
-        assert(false);
-        break;
+        OT_ASSERT(false);
+        OT_UNREACHABLE_CODE(break);
     }
 
-    VerifyOrExit(handler != NULL, error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_PROP_NOT_FOUND));
+    VerifyOrExit(handler != nullptr, error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_PROP_NOT_FOUND));
 
     // Save current read position in the decoder. Read the entire
     // content as a data blob (which is used in forming the response
@@ -1042,8 +1049,8 @@
     // that the `PropertyHandler` method can parse the content.
 
     mDecoder.SavePosition();
-    mDecoder.ReadData(valuePtr, valueLen);
-    mDecoder.ResetToSaved();
+    IgnoreError(mDecoder.ReadData(valuePtr, valueLen));
+    IgnoreError(mDecoder.ResetToSaved());
 
     mDisableStreamWrite = false;
 
@@ -1093,7 +1100,7 @@
     otError         error   = OT_ERROR_NONE;
     PropertyHandler handler = FindGetPropertyHandler(aPropKey);
 
-    if (handler != NULL)
+    if (handler != nullptr)
     {
         SuccessOrExit(error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, aPropKey));
         SuccessOrExit(error = (this->*handler)());
@@ -1175,8 +1182,8 @@
     // platform doesn't support resetting.
     // In such a case we fake it.
 
-    otThreadSetEnabled(mInstance, false);
-    otIp6SetEnabled(mInstance, false);
+    IgnoreError(otThreadSetEnabled(mInstance, false));
+    IgnoreError(otIp6SetEnabled(mInstance, false));
 #endif
 
     error = WriteLastStatusFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_STATUS_RESET_SOFTWARE);
@@ -1187,7 +1194,7 @@
         mUpdateChangedPropsTask.Post();
     }
 
-    sNcpInstance = NULL;
+    sNcpInstance = nullptr;
 
     return error;
 }
@@ -1238,7 +1245,7 @@
 
     VerifyOrExit(count != 0, parseError = OT_ERROR_INVALID_ARGS);
 
-    if (mAllowPeekDelegate != NULL)
+    if (mAllowPeekDelegate != nullptr)
     {
         VerifyOrExit(mAllowPeekDelegate(address, count), parseError = OT_ERROR_INVALID_ARGS);
     }
@@ -1263,7 +1270,7 @@
     otError        parseError = OT_ERROR_NONE;
     uint32_t       address;
     uint16_t       count;
-    const uint8_t *dataPtr = NULL;
+    const uint8_t *dataPtr = nullptr;
     uint16_t       dataLen;
 
     SuccessOrExit(parseError = mDecoder.ReadUint32(address));
@@ -1273,7 +1280,7 @@
     VerifyOrExit(count != 0, parseError = OT_ERROR_INVALID_ARGS);
     VerifyOrExit(count <= dataLen, parseError = OT_ERROR_INVALID_ARGS);
 
-    if (mAllowPokeDelegate != NULL)
+    if (mAllowPokeDelegate != nullptr)
     {
         VerifyOrExit(mAllowPokeDelegate(address, count), parseError = OT_ERROR_INVALID_ARGS);
     }
@@ -1294,7 +1301,7 @@
 
 otError NcpBase::HandlePropertySet_SPINEL_PROP_NEST_STREAM_MFG(uint8_t aHeader)
 {
-    const char *string = NULL;
+    const char *string = nullptr;
     char        output[OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE];
     otError     error = OT_ERROR_NONE;
 
@@ -1357,7 +1364,7 @@
     // stream enabled already
     if (otLinkRawIsEnabled(mInstance) && mIsRawStreamEnabled)
     {
-        error = otLinkRawReceive(mInstance, &NcpBase::LinkRawReceiveDone);
+        error = otLinkRawReceive(mInstance);
     }
 
 #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
@@ -1368,8 +1375,15 @@
 
 template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_PROMISCUOUS_MODE>(void)
 {
-    return mEncoder.WriteUint8(otPlatRadioGetPromiscuous(mInstance) ? SPINEL_MAC_PROMISCUOUS_MODE_FULL
-                                                                    : SPINEL_MAC_PROMISCUOUS_MODE_OFF);
+    bool isPromiscuous;
+
+#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
+    isPromiscuous = otLinkRawGetPromiscuous(mInstance);
+#else
+    isPromiscuous = otLinkIsPromiscuous(mInstance);
+#endif
+
+    return mEncoder.WriteUint8(isPromiscuous ? SPINEL_MAC_PROMISCUOUS_MODE_FULL : SPINEL_MAC_PROMISCUOUS_MODE_OFF);
 }
 
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_PROMISCUOUS_MODE>(void)
@@ -1382,12 +1396,20 @@
     switch (mode)
     {
     case SPINEL_MAC_PROMISCUOUS_MODE_OFF:
-        otPlatRadioSetPromiscuous(mInstance, false);
+#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
+        error = otLinkRawSetPromiscuous(mInstance, false);
+#else
+        error = otLinkSetPromiscuous(mInstance, false);
+#endif
         break;
 
     case SPINEL_MAC_PROMISCUOUS_MODE_NETWORK:
     case SPINEL_MAC_PROMISCUOUS_MODE_FULL:
-        otPlatRadioSetPromiscuous(mInstance, true);
+#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
+        error = otLinkRawSetPromiscuous(mInstance, true);
+#else
+        error = otLinkSetPromiscuous(mInstance, true);
+#endif
         break;
 
     default:
@@ -1458,7 +1480,7 @@
     {
         if (enabled)
         {
-            error = otLinkRawReceive(mInstance, &NcpBase::LinkRawReceiveDone);
+            error = otLinkRawReceive(mInstance);
         }
         else
         {
@@ -1670,7 +1692,7 @@
     {
         SuccessOrExit(error = mDecoder.ReadUintPacked(propKey));
 
-        IgnoreReturnValue(mChangedPropsSet.EnablePropertyFilter(static_cast<spinel_prop_key_t>(propKey), true));
+        IgnoreError(mChangedPropsSet.EnablePropertyFilter(static_cast<spinel_prop_key_t>(propKey), true));
     }
 
 exit:
@@ -1681,7 +1703,7 @@
 
     if (error != OT_ERROR_NONE)
     {
-        IgnoreReturnValue(
+        IgnoreError(
             WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_UNSOL_UPDATE_FILTER));
     }
 
@@ -1771,11 +1793,11 @@
     SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_MAC_RAW));
 #endif
 
-#if OPENTHREAD_PLATFORM_POSIX_APP
-    SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_POSIX_APP));
+#if OPENTHREAD_PLATFORM_POSIX
+    SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_POSIX));
 #endif
 
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP)
     SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_OPENTHREAD_LOG_METADATA));
 #endif
 
@@ -1938,13 +1960,13 @@
     {
         if (otThreadGetDeviceRole(mInstance) != OT_DEVICE_ROLE_DISABLED)
         {
-            otThreadSetEnabled(mInstance, false);
+            IgnoreError(otThreadSetEnabled(mInstance, false));
             StopLegacy();
         }
 
         if (otIp6IsEnabled(mInstance))
         {
-            otIp6SetEnabled(mInstance, false);
+            IgnoreError(otIp6SetEnabled(mInstance, false));
         }
     }
 #endif // #if OPENTHREAD_FTD || OPENTHREAD_MTD
@@ -2040,7 +2062,7 @@
             }
             else
             {
-                mHostPowerReplyFrameTag = NcpFrameBuffer::kInvalidTag;
+                mHostPowerReplyFrameTag = Spinel::Buffer::kInvalidTag;
             }
 
             mHostPowerStateInProgress = true;
@@ -2181,10 +2203,10 @@
 template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_DEBUG_TEST_ASSERT>(void)
 {
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-    assert(false);
+    OT_ASSERT(false);
 #endif
 
-    // We only get to this point if `assert(false)`
+    // We only get to this point if `OT_ASSERT(false)`
     // does not cause an NCP reset on the platform.
     // In such a case we return `false` as the
     // property value to indicate this.
@@ -2246,10 +2268,10 @@
 
     default:
         ExitNow(error = OT_ERROR_INVALID_ARGS);
-        break;
+        OT_UNREACHABLE_CODE(break);
     }
 
-    otLoggingSetLevel(logLevel);
+    IgnoreError(otLoggingSetLevel(logLevel));
 
 exit:
     return error;
@@ -2366,7 +2388,7 @@
 {
     ot::Ncp::NcpBase *ncp = ot::Ncp::NcpBase::GetNcpInstance();
 
-    if (ncp != NULL)
+    if (ncp != nullptr)
     {
         ncp->RegisterPeekPokeDelagates(aAllowPeekDelegate, aAllowPokeDelegate);
     }
@@ -2382,7 +2404,7 @@
     otError           error = OT_ERROR_INVALID_STATE;
     ot::Ncp::NcpBase *ncp   = ot::Ncp::NcpBase::GetNcpInstance();
 
-    if (ncp != NULL)
+    if (ncp != nullptr)
     {
         error = ncp->StreamWrite(aStreamId, aDataPtr, aDataLen);
     }
@@ -2390,26 +2412,7 @@
     return error;
 }
 
-extern "C" void otNcpPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list aArgs)
-{
-    OT_UNUSED_VARIABLE(aLogLevel);
-    OT_UNUSED_VARIABLE(aLogRegion);
-
-    char logString[OPENTHREAD_CONFIG_NCP_SPINEL_LOG_MAX_SIZE];
-    int  charsWritten;
-
-    if ((charsWritten = vsnprintf(logString, sizeof(logString), aFormat, aArgs)) > 0)
-    {
-        if (charsWritten > static_cast<int>(sizeof(logString) - 1))
-        {
-            charsWritten = static_cast<int>(sizeof(logString) - 1);
-        }
-
-        otNcpStreamWrite(0, reinterpret_cast<uint8_t *>(logString), charsWritten);
-    }
-}
-
-#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
+#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP)
 
 extern "C" void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
 {
@@ -2421,7 +2424,7 @@
 
     if (vsnprintf(logString, sizeof(logString), aFormat, args) > 0)
     {
-        if (ncp != NULL)
+        if (ncp != nullptr)
         {
             ncp->Log(aLogLevel, aLogRegion, logString);
         }
diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp
index b6bd875..ceeb45b 100644
--- a/src/ncp/ncp_base.hpp
+++ b/src/ncp/ncp_base.hpp
@@ -51,12 +51,10 @@
 #include "changed_props_set.hpp"
 #include "common/instance.hpp"
 #include "common/tasklet.hpp"
-#include "ncp/ncp_buffer.hpp"
-#include "ncp/spinel_decoder.hpp"
-#include "ncp/spinel_encoder.hpp"
-#include "utils/static_assert.hpp"
-
-#include "spinel.h"
+#include "lib/spinel/spinel.h"
+#include "lib/spinel/spinel_buffer.hpp"
+#include "lib/spinel/spinel_decoder.hpp"
+#include "lib/spinel/spinel_encoder.hpp"
 
 namespace ot {
 namespace Ncp {
@@ -93,7 +91,7 @@
      * @param[in]  aStreamId  A numeric identifier for the stream to write to.
      *                        If set to '0', will default to the debug stream.
      * @param[in]  aDataPtr   A pointer to the data to send on the stream.
-     *                        If aDataLen is non-zero, this param MUST NOT be NULL.
+     *                        If aDataLen is non-zero, this param MUST NOT be nullptr.
      * @param[in]  aDataLen   The number of bytes of data from aDataPtr to send.
      *
      * @retval OT_ERROR_NONE         The data was queued for delivery to the host.
@@ -208,7 +206,7 @@
         NcpBase::PropertyHandler mHandler;
     };
 
-    NcpFrameBuffer::FrameTag GetLastOutboundFrameTag(void);
+    Spinel::Buffer::FrameTag GetLastOutboundFrameTag(void);
 
     otError HandleCommand(uint8_t aHeader);
 
@@ -259,15 +257,16 @@
     void        UpdateChangedProps(void);
 
     static void HandleFrameRemovedFromNcpBuffer(void *                   aContext,
-                                                NcpFrameBuffer::FrameTag aFrameTag,
-                                                NcpFrameBuffer::Priority aPriority,
-                                                NcpFrameBuffer *         aNcpBuffer);
-    void        HandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag);
+                                                Spinel::Buffer::FrameTag aFrameTag,
+                                                Spinel::Buffer::Priority aPriority,
+                                                Spinel::Buffer *         aNcpBuffer);
+    void        HandleFrameRemovedFromNcpBuffer(Spinel::Buffer::FrameTag aFrameTag);
 
     otError EncodeChannelMask(uint32_t aChannelMask);
     otError DecodeChannelMask(uint32_t &aChannelMask);
 
 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
+    otError PackRadioFrame(otRadioFrame *aFrame, otError aError);
 
     static void LinkRawReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
     void        LinkRawReceiveDone(otRadioFrame *aFrame, otError aError);
@@ -335,9 +334,9 @@
     otError EncodeOperationalDataset(const otOperationalDataset &aDataset);
 
     otError DecodeOperationalDataset(otOperationalDataset &aDataset,
-                                     const uint8_t **      aTlvs             = NULL,
-                                     uint8_t *             aTlvsLength       = NULL,
-                                     const otIp6Address ** aDestIpAddress    = NULL,
+                                     const uint8_t **      aTlvs             = nullptr,
+                                     uint8_t *             aTlvsLength       = nullptr,
+                                     const otIp6Address ** aDestIpAddress    = nullptr,
                                      bool                  aAllowEmptyValues = false);
 
     otError EncodeNeighborInfo(const otNeighborInfo &aNeighborInfo);
@@ -416,9 +415,9 @@
     otError HandlePropertySet_SPINEL_PROP_HOST_POWER_STATE(uint8_t aHeader);
 
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
-    OT_STATIC_ASSERT(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <=
-                         OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE - kSpinelCmdHeaderSize - kSpinelPropIdSize,
-                     "diag output buffer should be smaller than NCP UART tx buffer");
+    static_assert(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <=
+                      OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE - kSpinelCmdHeaderSize - kSpinelPropIdSize,
+                  "diag output buffer should be smaller than NCP UART tx buffer");
 
     otError HandlePropertySet_SPINEL_PROP_NEST_STREAM_MFG(uint8_t aHeader);
 #endif
@@ -472,7 +471,7 @@
      * @param[in] aFrameTag    The tag of the frame removed from NCP buffer.
      *
      */
-    void VendorHandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag);
+    void VendorHandleFrameRemovedFromNcpBuffer(Spinel::Buffer::FrameTag aFrameTag);
 
     /**
      * This method defines a vendor "get property handler" hook to process vendor spinel properties.
@@ -520,9 +519,9 @@
                                                bool aDeviceType,
                                                bool aNetworkData);
     Instance *             mInstance;
-    NcpFrameBuffer         mTxFrameBuffer;
-    SpinelEncoder          mEncoder;
-    SpinelDecoder          mDecoder;
+    Spinel::Buffer         mTxFrameBuffer;
+    Spinel::Encoder        mEncoder;
+    Spinel::Decoder        mDecoder;
     bool                   mHostPowerStateInProgress;
 
     enum
@@ -544,7 +543,7 @@
     ChangedPropsSet mChangedPropsSet;
 
     spinel_host_power_state_t mHostPowerState;
-    NcpFrameBuffer::FrameTag  mHostPowerReplyFrameTag;
+    Spinel::Buffer::FrameTag  mHostPowerReplyFrameTag;
     uint8_t                   mHostPowerStateHeader;
 
 #if OPENTHREAD_CONFIG_NCP_ENABLE_PEEK_POKE
diff --git a/src/ncp/ncp_base_dispatcher.cpp b/src/ncp/ncp_base_dispatcher.cpp
index b5ccb44..7eadb8c 100644
--- a/src/ncp/ncp_base_dispatcher.cpp
+++ b/src/ncp/ncp_base_dispatcher.cpp
@@ -35,7 +35,6 @@
 namespace ot {
 namespace Ncp {
 
-#if __cplusplus >= 201103L
 constexpr bool NcpBase::AreHandlerEntriesSorted(const HandlerEntry *aHandlerEntries, size_t aSize)
 {
     return aSize < 2 ? true
@@ -43,16 +42,14 @@
                         AreHandlerEntriesSorted(aHandlerEntries, aSize - 1));
 }
 
-#define OT_NCP_CONST constexpr
-#else
-#define OT_NCP_CONST const
-#endif
-
 NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey)
 {
-#define OT_NCP_GET_HANDLER_ENTRY(aPropertyName) {aPropertyName, &NcpBase::HandlePropertyGet<aPropertyName>}
+#define OT_NCP_GET_HANDLER_ENTRY(aPropertyName)                   \
+    {                                                             \
+        aPropertyName, &NcpBase::HandlePropertyGet<aPropertyName> \
+    }
 
-    OT_NCP_CONST static HandlerEntry sHandlerEntries[] = {
+    constexpr static HandlerEntry sHandlerEntries[] = {
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_LAST_STATUS),
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PROTOCOL_VERSION),
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NCP_VERSION),
@@ -132,16 +129,20 @@
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD),
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE),
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE),
-#if OPENTHREAD_FTD
 #if OPENTHREAD_CONFIG_JOINER_ENABLE
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_STATE),
 #endif
+#if OPENTHREAD_FTD
 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_STATE),
+        OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS),
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL),
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID),
 #endif
 #endif // OPENTHREAD_FTD
+#if OPENTHREAD_CONFIG_JOINER_ENABLE
+        OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_DISCERNER),
+#endif
 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE),
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_SERVICES),
@@ -198,6 +199,11 @@
 #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM),
 #endif
+#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
+#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
+        OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_TIMESTAMP),
+#endif
+#if OPENTHREAD_MTD || OPENTHREAD_FTD
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER),
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_LIST),
 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
@@ -306,7 +312,7 @@
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT),
 #endif
 #endif // OPENTHREAD_FTD
-#if OPENTHREAD_PLATFORM_POSIX_APP
+#if OPENTHREAD_PLATFORM_POSIX
         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_VERSION),
 #endif
 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
@@ -325,19 +331,20 @@
 
 #undef OT_NCP_GET_HANDLER_ENTRY
 
-#if __cplusplus >= 201103L
     static_assert(AreHandlerEntriesSorted(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries)),
                   "NCP property getter entries not sorted!");
-#endif
 
     return FindPropertyHandler(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries), aKey);
 }
 
 NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
 {
-#define OT_NCP_SET_HANDLER_ENTRY(aPropertyName) {aPropertyName, &NcpBase::HandlePropertySet<aPropertyName>}
+#define OT_NCP_SET_HANDLER_ENTRY(aPropertyName)                   \
+    {                                                             \
+        aPropertyName, &NcpBase::HandlePropertySet<aPropertyName> \
+    }
 
-    OT_NCP_CONST static HandlerEntry sHandlerEntries[] = {
+    constexpr static HandlerEntry sHandlerEntries[] = {
         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_POWER_STATE),
 #if OPENTHREAD_CONFIG_NCP_ENABLE_MCU_POWER_STATE_CONTROL
         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MCU_POWER_STATE),
@@ -401,6 +408,9 @@
         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL),
 #endif
 #endif // OPENTHREAD_FTD
+#if OPENTHREAD_CONFIG_JOINER_ENABLE
+        OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_DISCERNER),
+#endif
 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE),
 #endif
@@ -411,6 +421,12 @@
 #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM),
 #endif
+#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
+#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
+        OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_KEY),
+        OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_FRAME_COUNTER),
+#endif
+#if OPENTHREAD_MTD || OPENTHREAD_FTD
         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER),
 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_ENABLE),
@@ -521,19 +537,20 @@
 
 #undef OT_NCP_SET_HANDLER_ENTRY
 
-#if __cplusplus >= 201103L
     static_assert(AreHandlerEntriesSorted(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries)),
                   "NCP property setter entries not sorted!");
-#endif
 
     return FindPropertyHandler(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries), aKey);
 }
 
 NcpBase::PropertyHandler NcpBase::FindInsertPropertyHandler(spinel_prop_key_t aKey)
 {
-#define OT_NCP_INSERT_HANDLER_ENTRY(aPropertyName) {aPropertyName, &NcpBase::HandlePropertyInsert<aPropertyName>}
+#define OT_NCP_INSERT_HANDLER_ENTRY(aPropertyName)                   \
+    {                                                                \
+        aPropertyName, &NcpBase::HandlePropertyInsert<aPropertyName> \
+    }
 
-    OT_NCP_CONST static HandlerEntry sHandlerEntries[] = {
+    constexpr static HandlerEntry sHandlerEntries[] = {
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_THREAD_ON_MESH_NETS),
@@ -568,19 +585,20 @@
 
 #undef OT_NCP_INSERT_HANDLER_ENTRY
 
-#if __cplusplus >= 201103L
     static_assert(AreHandlerEntriesSorted(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries)),
                   "NCP property setter entries not sorted!");
-#endif
 
     return FindPropertyHandler(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries), aKey);
 }
 
 NcpBase::PropertyHandler NcpBase::FindRemovePropertyHandler(spinel_prop_key_t aKey)
 {
-#define OT_NCP_REMOVE_HANDLER_ENTRY(aPropertyName) {aPropertyName, &NcpBase::HandlePropertyRemove<aPropertyName>}
+#define OT_NCP_REMOVE_HANDLER_ENTRY(aPropertyName)                   \
+    {                                                                \
+        aPropertyName, &NcpBase::HandlePropertyRemove<aPropertyName> \
+    }
 
-    OT_NCP_CONST static HandlerEntry sHandlerEntries[] = {
+    constexpr static HandlerEntry sHandlerEntries[] = {
 #if OPENTHREAD_MTD || OPENTHREAD_FTD
 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_THREAD_ON_MESH_NETS),
@@ -615,10 +633,8 @@
 
 #undef OT_NCP_REMOVE_HANDLER_ENTRY
 
-#if __cplusplus >= 201103L
     static_assert(AreHandlerEntriesSorted(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries)),
                   "NCP property setter entries not sorted!");
-#endif
 
     return FindPropertyHandler(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries), aKey);
 }
@@ -629,7 +645,7 @@
 {
     size_t l = 0;
 
-    assert(aSize > 0);
+    OT_ASSERT(aSize > 0);
 
     for (size_t r = aSize - 1; l < r;)
     {
@@ -645,7 +661,7 @@
         }
     }
 
-    return aHandlerEntries[l].mKey == aKey ? aHandlerEntries[l].mHandler : NULL;
+    return aHandlerEntries[l].mKey == aKey ? aHandlerEntries[l].mHandler : nullptr;
 }
 
 } // namespace Ncp
diff --git a/src/ncp/ncp_base_ftd.cpp b/src/ncp/ncp_base_ftd.cpp
index dde5c9d..38df0d7 100644
--- a/src/ncp/ncp_base_ftd.cpp
+++ b/src/ncp/ncp_base_ftd.cpp
@@ -86,7 +86,7 @@
 
 void NcpBase::HandleParentResponseInfo(otThreadParentResponseInfo *aInfo, void *aContext)
 {
-    VerifyOrExit(aInfo && aContext);
+    VerifyOrExit(aInfo && aContext, OT_NOOP);
 
     static_cast<NcpBase *>(aContext)->HandleParentResponseInfo(*aInfo);
 
@@ -96,7 +96,7 @@
 
 void NcpBase::HandleParentResponseInfo(const otThreadParentResponseInfo &aInfo)
 {
-    VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(SPINEL_PROP_PARENT_RESPONSE_INFO));
+    VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(SPINEL_PROP_PARENT_RESPONSE_INFO), OT_NOOP);
 
     SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
                                       SPINEL_PROP_PARENT_RESPONSE_INFO));
@@ -134,7 +134,7 @@
         // Fall through
     case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED:
         property = SPINEL_PROP_THREAD_CHILD_TABLE;
-        VerifyOrExit(!aEntry.mInfo.mChild.mIsStateRestoring);
+        VerifyOrExit(!aEntry.mInfo.mChild.mIsStateRestoring, OT_NOOP);
         break;
 
     case OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED:
@@ -148,7 +148,7 @@
         ExitNow();
     }
 
-    VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(property));
+    VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(property), OT_NOOP);
 
     SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, command, property));
 
@@ -334,7 +334,7 @@
 
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_PSKC>(void)
 {
-    const uint8_t *ptr = NULL;
+    const uint8_t *ptr = nullptr;
     uint16_t       len;
     otError        error = OT_ERROR_NONE;
 
@@ -526,7 +526,7 @@
         break;
 
     case SPINEL_MESHCOP_COMMISSIONER_STATE_ACTIVE:
-        error = otCommissionerStart(mInstance, NULL, NULL, NULL);
+        error = otCommissionerStart(mInstance, nullptr, nullptr, nullptr);
         break;
 
     default:
@@ -538,23 +538,72 @@
     return error;
 }
 
+template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
+{
+    otError      error = OT_ERROR_NONE;
+    uint16_t     iter  = 0;
+    otJoinerInfo joinerInfo;
+
+    while (otCommissionerGetNextJoinerInfo(mInstance, &iter, &joinerInfo) == OT_ERROR_NONE)
+    {
+        SuccessOrExit(error = mEncoder.OpenStruct());
+
+        SuccessOrExit(error = mEncoder.OpenStruct()); // Joiner Id (any, EUI64 or a Joiner Discerner) struct
+
+        switch (joinerInfo.mType)
+        {
+        case OT_JOINER_INFO_TYPE_ANY:
+            break;
+
+        case OT_JOINER_INFO_TYPE_EUI64:
+            SuccessOrExit(error = mEncoder.WriteEui64(joinerInfo.mSharedId.mEui64));
+            break;
+
+        case OT_JOINER_INFO_TYPE_DISCERNER:
+            SuccessOrExit(error = mEncoder.WriteUint8(joinerInfo.mSharedId.mDiscerner.mLength));
+            SuccessOrExit(error = mEncoder.WriteUint64(joinerInfo.mSharedId.mDiscerner.mValue));
+            break;
+        }
+
+        SuccessOrExit(error = mEncoder.CloseStruct());
+
+        SuccessOrExit(error = mEncoder.WriteUint32(joinerInfo.mExpirationTime));
+        SuccessOrExit(error = mEncoder.WriteUtf8(joinerInfo.mPskd.m8));
+
+        SuccessOrExit(error = mEncoder.CloseStruct());
+    }
+
+exit:
+    return error;
+}
+
 template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
 {
     otError             error = OT_ERROR_NONE;
+    otJoinerDiscerner   discerner;
+    bool                withDiscerner = false;
     const otExtAddress *eui64;
     uint32_t            timeout;
     const char *        psk;
 
     SuccessOrExit(error = mDecoder.OpenStruct());
 
-    if (!mDecoder.IsAllReadInStruct())
+    switch (mDecoder.GetRemainingLengthInStruct())
     {
+    case 0:
+        // Empty struct indicates any joiner
+        eui64 = nullptr;
+        break;
+
+    case sizeof(spinel_eui64_t):
         SuccessOrExit(error = mDecoder.ReadEui64(eui64));
-    }
-    else
-    {
-        // Empty struct indicates any Joiner (no EUI64 is given so NULL is used.).
-        eui64 = NULL;
+        break;
+
+    default:
+        SuccessOrExit(error = mDecoder.ReadUint8(discerner.mLength));
+        SuccessOrExit(error = mDecoder.ReadUint64(discerner.mValue));
+        withDiscerner = true;
+        break;
     }
 
     SuccessOrExit(error = mDecoder.CloseStruct());
@@ -562,7 +611,14 @@
     SuccessOrExit(error = mDecoder.ReadUint32(timeout));
     SuccessOrExit(error = mDecoder.ReadUtf8(psk));
 
-    error = otCommissionerAddJoiner(mInstance, eui64, psk, timeout);
+    if (withDiscerner)
+    {
+        error = otCommissionerAddJoinerWithDiscerner(mInstance, &discerner, psk, timeout);
+    }
+    else
+    {
+        error = otCommissionerAddJoiner(mInstance, eui64, psk, timeout);
+    }
 
 exit:
     return error;
@@ -571,23 +627,40 @@
 template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
 {
     otError             error = OT_ERROR_NONE;
+    otJoinerDiscerner   discerner;
+    bool                withDiscerner = false;
     const otExtAddress *eui64;
 
     SuccessOrExit(error = mDecoder.OpenStruct());
 
-    if (!mDecoder.IsAllReadInStruct())
+    switch (mDecoder.GetRemainingLengthInStruct())
     {
+    case 0:
+        // Empty struct indicates any joiner
+        eui64 = nullptr;
+        break;
+
+    case sizeof(spinel_eui64_t):
         SuccessOrExit(error = mDecoder.ReadEui64(eui64));
-    }
-    else
-    {
-        // Empty struct indicates any Joiner (no EUI64 is given so NULL is used.).
-        eui64 = NULL;
+        break;
+
+    default:
+        SuccessOrExit(error = mDecoder.ReadUint8(discerner.mLength));
+        SuccessOrExit(error = mDecoder.ReadUint64(discerner.mValue));
+        withDiscerner = true;
+        break;
     }
 
     SuccessOrExit(error = mDecoder.CloseStruct());
 
-    error = otCommissionerRemoveJoiner(mInstance, eui64);
+    if (withDiscerner)
+    {
+        error = otCommissionerRemoveJoinerWithDiscerner(mInstance, &discerner);
+    }
+    else
+    {
+        error = otCommissionerRemoveJoiner(mInstance, eui64);
+    }
 
 exit:
     return error;
@@ -773,8 +846,8 @@
     SuccessOrExit(error = mDecoder.ReadDataWithLen(extPanIdData, length));
     VerifyOrExit(length == sizeof(spinel_net_xpanid_t), error = OT_ERROR_PARSE);
 
-    SuccessOrExit(error = otCommissionerGeneratePskc(passPhrase, networkName,
-                                                     reinterpret_cast<const otExtendedPanId *>(extPanIdData), &pskc));
+    SuccessOrExit(error = otDatasetGeneratePskc(passPhrase, reinterpret_cast<const otNetworkName *>(networkName),
+                                                reinterpret_cast<const otExtendedPanId *>(extPanIdData), &pskc));
 
     SuccessOrExit(
         error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_MESHCOP_COMMISSIONER_GENERATE_PSKC));
@@ -806,7 +879,7 @@
     }
     else
     {
-        error = otCommissionerStart(mInstance, NULL, NULL, NULL);
+        error = otCommissionerStart(mInstance, nullptr, nullptr, nullptr);
     }
 
 exit:
@@ -819,8 +892,8 @@
 template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_THREAD_JOINERS>(void)
 {
     otError             error         = OT_ERROR_NONE;
-    const otExtAddress *eui64         = NULL;
-    const char *        pskd          = NULL;
+    const otExtAddress *eui64         = nullptr;
+    const char *        pskd          = nullptr;
     uint32_t            joinerTimeout = 0;
 
     SuccessOrExit(error = mDecoder.ReadUtf8(pskd));
@@ -828,7 +901,7 @@
 
     if (mDecoder.ReadEui64(eui64) != OT_ERROR_NONE)
     {
-        eui64 = NULL;
+        eui64 = nullptr;
     }
 
     error = otCommissionerAddJoiner(mInstance, eui64, pskd, joinerTimeout);
@@ -911,22 +984,59 @@
 
 template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE>(void)
 {
-    otError         error = OT_ERROR_NONE;
-    otEidCacheEntry entry;
+    otError              error = OT_ERROR_NONE;
+    otCacheEntryIterator iterator;
+    otCacheEntryInfo     entry;
+
+    memset(&iterator, 0, sizeof(iterator));
 
     for (uint8_t index = 0;; index++)
     {
-        SuccessOrExit(otThreadGetEidCacheEntry(mInstance, index, &entry));
-
-        if (!entry.mValid)
-        {
-            continue;
-        }
+        SuccessOrExit(otThreadGetNextCacheEntry(mInstance, &entry, &iterator));
 
         SuccessOrExit(error = mEncoder.OpenStruct());
         SuccessOrExit(error = mEncoder.WriteIp6Address(entry.mTarget));
         SuccessOrExit(error = mEncoder.WriteUint16(entry.mRloc16));
-        SuccessOrExit(error = mEncoder.WriteUint8(entry.mAge));
+        SuccessOrExit(error = mEncoder.WriteUint8(index));
+
+        switch (entry.mState)
+        {
+        case OT_CACHE_ENTRY_STATE_CACHED:
+            SuccessOrExit(error = mEncoder.WriteUint8(SPINEL_ADDRESS_CACHE_ENTRY_STATE_CACHED));
+            break;
+        case OT_CACHE_ENTRY_STATE_SNOOPED:
+            SuccessOrExit(error = mEncoder.WriteUint8(SPINEL_ADDRESS_CACHE_ENTRY_STATE_SNOOPED));
+            break;
+        case OT_CACHE_ENTRY_STATE_QUERY:
+            SuccessOrExit(error = mEncoder.WriteUint8(SPINEL_ADDRESS_CACHE_ENTRY_STATE_QUERY));
+            break;
+        case OT_CACHE_ENTRY_STATE_RETRY_QUERY:
+            SuccessOrExit(error = mEncoder.WriteUint8(SPINEL_ADDRESS_CACHE_ENTRY_STATE_RETRY_QUERY));
+            break;
+        }
+
+        SuccessOrExit(error = mEncoder.OpenStruct());
+
+        if (entry.mState == OT_CACHE_ENTRY_STATE_CACHED)
+        {
+            SuccessOrExit(error = mEncoder.WriteBool(entry.mValidLastTrans));
+            SuccessOrExit(error = mEncoder.WriteUint32(entry.mLastTransTime));
+            SuccessOrExit(error = mEncoder.WriteIp6Address(entry.mMeshLocalEid));
+        }
+
+        SuccessOrExit(error = mEncoder.CloseStruct());
+
+        SuccessOrExit(error = mEncoder.OpenStruct());
+
+        if (entry.mState != OT_CACHE_ENTRY_STATE_CACHED)
+        {
+            SuccessOrExit(error = mEncoder.WriteBool(entry.mCanEvict));
+            SuccessOrExit(error = mEncoder.WriteUint16(entry.mTimeout));
+            SuccessOrExit(error = mEncoder.WriteUint16(entry.mRetryDelay));
+        }
+
+        SuccessOrExit(error = mEncoder.CloseStruct());
+
         SuccessOrExit(error = mEncoder.CloseStruct());
     }
 
diff --git a/src/ncp/ncp_base_mtd.cpp b/src/ncp/ncp_base_mtd.cpp
index 293dfc9..f4b88fd 100644
--- a/src/ncp/ncp_base_mtd.cpp
+++ b/src/ncp/ncp_base_mtd.cpp
@@ -366,7 +366,7 @@
 
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_NETWORK_NAME>(void)
 {
-    const char *string = NULL;
+    const char *string = nullptr;
     otError     error  = OT_ERROR_NONE;
 
     SuccessOrExit(mDecoder.ReadUtf8(string));
@@ -384,7 +384,7 @@
 
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_XPANID>(void)
 {
-    const uint8_t *ptr = NULL;
+    const uint8_t *ptr = nullptr;
     uint16_t       len;
     otError        error = OT_ERROR_NONE;
 
@@ -405,7 +405,7 @@
 
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_MASTER_KEY>(void)
 {
-    const uint8_t *ptr = NULL;
+    const uint8_t *ptr = nullptr;
     uint16_t       len;
     otError        error = OT_ERROR_NONE;
 
@@ -476,9 +476,9 @@
     uint8_t networkData[255];
     uint8_t networkDataLen = 255;
 
-    otBorderRouterGetNetData(mInstance,
-                             false, // Stable?
-                             networkData, &networkDataLen);
+    IgnoreError(otBorderRouterGetNetData(mInstance,
+                                         false, // Stable?
+                                         networkData, &networkDataLen));
 
     return mEncoder.WriteData(networkData, networkDataLen);
 }
@@ -488,9 +488,9 @@
     uint8_t networkData[255];
     uint8_t networkDataLen = 255;
 
-    otBorderRouterGetNetData(mInstance,
-                             true, // Stable?
-                             networkData, &networkDataLen);
+    IgnoreError(otBorderRouterGetNetData(mInstance,
+                                         true, // Stable?
+                                         networkData, &networkDataLen));
 
     return mEncoder.WriteData(networkData, networkDataLen);
 }
@@ -501,9 +501,9 @@
     uint8_t networkData[255];
     uint8_t networkDataLen = 255;
 
-    otNetDataGet(mInstance,
-                 false, // Stable?
-                 networkData, &networkDataLen);
+    IgnoreError(otNetDataGet(mInstance,
+                             false, // Stable?
+                             networkData, &networkDataLen));
 
     return mEncoder.WriteData(networkData, networkDataLen);
 }
@@ -513,9 +513,9 @@
     uint8_t networkData[255];
     uint8_t networkDataLen = 255;
 
-    otNetDataGet(mInstance,
-                 true, // Stable?
-                 networkData, &networkDataLen);
+    IgnoreError(otNetDataGet(mInstance,
+                             true, // Stable?
+                             networkData, &networkDataLen));
 
     return mEncoder.WriteData(networkData, networkDataLen);
 }
@@ -559,8 +559,8 @@
             int8_t averageRssi;
             int8_t lastRssi;
 
-            otThreadGetParentAverageRssi(mInstance, &averageRssi);
-            otThreadGetParentLastRssi(mInstance, &lastRssi);
+            IgnoreError(otThreadGetParentAverageRssi(mInstance, &averageRssi));
+            IgnoreError(otThreadGetParentLastRssi(mInstance, &lastRssi));
 
             SuccessOrExit(error = mEncoder.WriteEui64(parentInfo.mExtAddress));
             SuccessOrExit(error = mEncoder.WriteUint16(parentInfo.mRloc16));
@@ -662,7 +662,8 @@
         // the state of these ports, so we need to report
         // those incomplete changes via an asynchronous
         // change event.
-        WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_THREAD_ASSISTING_PORTS);
+        IgnoreError(
+            WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_THREAD_ASSISTING_PORTS));
     }
 
     return error;
@@ -691,7 +692,7 @@
 
     if (shouldRegisterWithLeader)
     {
-        otBorderRouterRegister(mInstance);
+        IgnoreError(otBorderRouterRegister(mInstance));
     }
 
     return error;
@@ -831,7 +832,7 @@
 
     if (shouldRegisterWithLeader)
     {
-        otServerRegister(mInstance);
+        IgnoreError(otServerRegister(mInstance));
     }
 
     return error;
@@ -853,7 +854,7 @@
     VerifyOrExit((dataLen <= sizeof(cfg.mServiceData)), error = OT_ERROR_INVALID_ARGS);
     memcpy(cfg.mServiceData, data, dataLen);
 
-    OT_STATIC_ASSERT((sizeof(cfg.mServiceData) <= UINT8_MAX), "Cannot handle full range of buffer length");
+    static_assert((sizeof(cfg.mServiceData) <= UINT8_MAX), "Cannot handle full range of buffer length");
     cfg.mServiceDataLength = static_cast<uint8_t>(dataLen);
 
     SuccessOrExit(error = mDecoder.ReadBool(stable));
@@ -863,7 +864,7 @@
     VerifyOrExit((dataLen <= sizeof(cfg.mServerConfig.mServerData)), error = OT_ERROR_INVALID_ARGS);
     memcpy(cfg.mServerConfig.mServerData, data, dataLen);
 
-    OT_STATIC_ASSERT((sizeof(cfg.mServerConfig.mServerData) <= UINT8_MAX), "Cannot handle full range of buffer length");
+    static_assert((sizeof(cfg.mServerConfig.mServerData) <= UINT8_MAX), "Cannot handle full range of buffer length");
     cfg.mServerConfig.mServerDataLength = static_cast<uint8_t>(dataLen);
 
     SuccessOrExit(error = otServerAddService(mInstance, &cfg));
@@ -926,7 +927,7 @@
     {
         SuccessOrExit(error = mEncoder.OpenStruct());
 
-        SuccessOrExit(error = mEncoder.WriteUint8(cfg.mServiceID));
+        SuccessOrExit(error = mEncoder.WriteUint8(cfg.mServiceId));
         SuccessOrExit(error = mEncoder.WriteUint32(cfg.mEnterpriseNumber));
         SuccessOrExit(error = mEncoder.WriteDataWithLen(cfg.mServiceData, cfg.mServiceDataLength));
         SuccessOrExit(error = mEncoder.WriteBool(cfg.mServerConfig.mStable));
@@ -1091,7 +1092,7 @@
 {
     otOperationalDataset dataset;
 
-    IgnoreReturnValue(otDatasetGetActive(mInstance, &dataset));
+    IgnoreError(otDatasetGetActive(mInstance, &dataset));
     return EncodeOperationalDataset(dataset);
 }
 
@@ -1099,7 +1100,7 @@
 {
     otOperationalDataset dataset;
 
-    IgnoreReturnValue(otDatasetGetPending(mInstance, &dataset));
+    IgnoreError(otDatasetGetPending(mInstance, &dataset));
     return EncodeOperationalDataset(dataset);
 }
 
@@ -1113,19 +1114,19 @@
 
     memset(&aDataset, 0, sizeof(otOperationalDataset));
 
-    if (aTlvs != NULL)
+    if (aTlvs != nullptr)
     {
-        *aTlvs = NULL;
+        *aTlvs = nullptr;
     }
 
-    if (aTlvsLength != NULL)
+    if (aTlvsLength != nullptr)
     {
         *aTlvsLength = 0;
     }
 
-    if (aDestIpAddress != NULL)
+    if (aDestIpAddress != nullptr)
     {
-        *aDestIpAddress = NULL;
+        *aDestIpAddress = nullptr;
     }
 
     while (!mDecoder.IsAllReadInStruct())
@@ -1307,12 +1308,12 @@
                 SuccessOrExit(error = mDecoder.ReadData(tlvs, len));
                 VerifyOrExit(len <= 255, error = OT_ERROR_INVALID_ARGS);
 
-                if (aTlvs != NULL)
+                if (aTlvs != nullptr)
                 {
                     *aTlvs = tlvs;
                 }
 
-                if (aTlvsLength != NULL)
+                if (aTlvsLength != nullptr)
                 {
                     *aTlvsLength = static_cast<uint8_t>(len);
                 }
@@ -1328,7 +1329,7 @@
 
                 SuccessOrExit(error = mDecoder.ReadIp6Address(addr));
 
-                if (aDestIpAddress != NULL)
+                if (aDestIpAddress != nullptr)
                 {
                     *aDestIpAddress = addr;
                 }
@@ -1462,12 +1463,12 @@
 {
     otError     error           = OT_ERROR_NONE;
     bool        action          = false;
-    const char *psk             = NULL;
-    const char *provisioningUrl = NULL;
-    const char *vendorName      = NULL;
-    const char *vendorModel     = NULL;
-    const char *vendorSwVersion = NULL;
-    const char *vendorData      = NULL;
+    const char *psk             = nullptr;
+    const char *provisioningUrl = nullptr;
+    const char *vendorName      = nullptr;
+    const char *vendorModel     = nullptr;
+    const char *vendorSwVersion = nullptr;
+    const char *vendorData      = nullptr;
 
     SuccessOrExit(error = mDecoder.ReadBool(action));
 
@@ -1509,17 +1510,17 @@
     // Use OpenThread default values for vendor name, mode, sw version if
     // not specified or an empty string is given.
 
-    if ((vendorName == NULL) || (vendorName[0] == 0))
+    if ((vendorName == nullptr) || (vendorName[0] == 0))
     {
         vendorName = PACKAGE_NAME;
     }
 
-    if ((vendorModel == NULL) || (vendorModel[0] == 0))
+    if ((vendorModel == nullptr) || (vendorModel[0] == 0))
     {
         vendorModel = OPENTHREAD_CONFIG_PLATFORM_INFO;
     }
 
-    if ((vendorSwVersion == NULL) || (vendorSwVersion[0] == 0))
+    if ((vendorSwVersion == nullptr) || (vendorSwVersion[0] == 0))
     {
         vendorSwVersion = PACKAGE_VERSION;
     }
@@ -1531,7 +1532,47 @@
     return error;
 }
 
-#endif
+template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_JOINER_DISCERNER>(void)
+{
+    otError                  error;
+    const otJoinerDiscerner *discerner = otJoinerGetDiscerner(mInstance);
+
+    if (discerner == nullptr)
+    {
+        SuccessOrExit(error = mEncoder.WriteUint8(0));
+    }
+    else
+    {
+        SuccessOrExit(error = mEncoder.WriteUint8(discerner->mLength));
+        SuccessOrExit(error = mEncoder.WriteUint64(discerner->mValue));
+    }
+
+exit:
+    return error;
+}
+
+template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_JOINER_DISCERNER>(void)
+{
+    otError           error = OT_ERROR_NONE;
+    otJoinerDiscerner discerner;
+
+    SuccessOrExit(error = mDecoder.ReadUint8(discerner.mLength));
+
+    if (discerner.mLength == 0)
+    {
+        // Clearing any previously set Joiner Discerner
+        error = otJoinerSetDiscerner(mInstance, nullptr);
+        ExitNow();
+    }
+
+    SuccessOrExit(error = mDecoder.ReadUint64(discerner.mValue));
+    error = otJoinerSetDiscerner(mInstance, &discerner);
+
+exit:
+    return error;
+}
+
+#endif // OPENTHREAD_CONFIG_JOINER_ENABLE
 
 template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_ML_PREFIX>(void)
 {
@@ -1539,7 +1580,7 @@
     const otMeshLocalPrefix *mlPrefix = otThreadGetMeshLocalPrefix(mInstance);
     otIp6Address             addr;
 
-    VerifyOrExit(mlPrefix != NULL); // If `mlPrefix` is NULL send empty response.
+    VerifyOrExit(mlPrefix != nullptr, OT_NOOP); // If `mlPrefix` is nullptr send empty response.
 
     memcpy(addr.mFields.m8, mlPrefix->m8, 8);
 
@@ -1574,7 +1615,7 @@
     otError             error = OT_ERROR_NONE;
     const otIp6Address *ml64  = otThreadGetMeshLocalEid(mInstance);
 
-    VerifyOrExit(ml64 != NULL);
+    VerifyOrExit(ml64 != nullptr, OT_NOOP);
     SuccessOrExit(error = mEncoder.WriteIp6Address(*ml64));
 
 exit:
@@ -1586,7 +1627,7 @@
     otError             error   = OT_ERROR_NONE;
     const otIp6Address *address = otThreadGetLinkLocalIp6Address(mInstance);
 
-    VerifyOrExit(address != NULL);
+    VerifyOrExit(address != nullptr, OT_NOOP);
     SuccessOrExit(error = mEncoder.WriteIp6Address(*address));
 
 exit:
@@ -1625,8 +1666,9 @@
     SuccessOrExit(error = mDecoder.ReadUint32(preferredLifetime));
     SuccessOrExit(error = mDecoder.ReadUint32(validLifetime));
 
-    netifAddr.mPreferred = (preferredLifetime != 0);
-    netifAddr.mValid     = (validLifetime != 0);
+    netifAddr.mAddressOrigin = OT_ADDRESS_ORIGIN_MANUAL;
+    netifAddr.mPreferred     = (preferredLifetime != 0);
+    netifAddr.mValid         = (validLifetime != 0);
 
     error = otIp6AddUnicastAddress(mInstance, &netifAddr);
 
@@ -1929,11 +1971,11 @@
 
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_STREAM_NET>(void)
 {
-    const uint8_t *framePtr = NULL;
+    const uint8_t *framePtr = nullptr;
     uint16_t       frameLen = 0;
-    const uint8_t *metaPtr  = NULL;
+    const uint8_t *metaPtr  = nullptr;
     uint16_t       metaLen  = 0;
-    otMessage *    message  = NULL;
+    otMessage *    message  = nullptr;
     otError        error    = OT_ERROR_NONE;
 
     SuccessOrExit(error = mDecoder.ReadDataWithLen(framePtr, frameLen));
@@ -1943,8 +1985,8 @@
     // May later include TX power, allow retransmits, etc...
 
     // STREAM_NET requires layer 2 security.
-    message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, NULL);
-    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+    message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, nullptr);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
     error = otIp6Send(mInstance, message);
 
@@ -2003,11 +2045,11 @@
 
     if (enabled)
     {
-        otJamDetectionStart(mInstance, &NcpBase::HandleJamStateChange_Jump, this);
+        IgnoreError(otJamDetectionStart(mInstance, &NcpBase::HandleJamStateChange_Jump, this));
     }
     else
     {
-        otJamDetectionStop(mInstance);
+        IgnoreError(otJamDetectionStop(mInstance));
     }
 
 exit:
@@ -2401,8 +2443,6 @@
     otError              error    = OT_ERROR_NONE;
     const otMacCounters *counters = otLinkGetCounters(mInstance);
 
-    assert(counters != NULL);
-
     // Encode Tx related counters
     SuccessOrExit(error = mEncoder.OpenStruct());
     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxTotal));
@@ -2461,7 +2501,7 @@
     otError              error    = OT_ERROR_NONE;
     const otMleCounters *counters = otThreadGetMleCounters(mInstance);
 
-    assert(counters != NULL);
+    OT_ASSERT(counters != nullptr);
 
     SuccessOrExit(error = mEncoder.WriteUint16(counters->mDisabledRole));
     SuccessOrExit(error = mEncoder.WriteUint16(counters->mDetachedRole));
@@ -2489,7 +2529,7 @@
     otError             error    = OT_ERROR_NONE;
     const otIpCounters *counters = otThreadGetIp6Counters(mInstance);
 
-    assert(counters != NULL);
+    OT_ASSERT(counters != nullptr);
 
     // Encode Tx related counters
     SuccessOrExit(error = mEncoder.OpenStruct());
@@ -2519,8 +2559,8 @@
     histogramDirect   = otLinkGetTxDirectRetrySuccessHistogram(mInstance, &histogramDirectEntries);
     histogramIndirect = otLinkGetTxIndirectRetrySuccessHistogram(mInstance, &histogramIndirectEntries);
 
-    assert((histogramDirectEntries == 0) || (histogramDirect != NULL));
-    assert((histogramIndirectEntries == 0) || (histogramIndirect != NULL));
+    OT_ASSERT((histogramDirectEntries == 0) || (histogramDirect != nullptr));
+    OT_ASSERT((histogramIndirectEntries == 0) || (histogramIndirect != nullptr));
 
     // Encode direct message retries histogram
     SuccessOrExit(error = mEncoder.OpenStruct());
@@ -2635,7 +2675,7 @@
 
     while (mDecoder.GetRemainingLengthInStruct() > 0)
     {
-        const otExtAddress *extAddress = NULL;
+        const otExtAddress *extAddress = nullptr;
         int8_t              rss;
 
         SuccessOrExit(error = mDecoder.OpenStruct());
@@ -2675,7 +2715,7 @@
 
     if (error != OT_ERROR_NONE)
     {
-        WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_WHITELIST);
+        IgnoreError(WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_WHITELIST));
     }
 
     return error;
@@ -2694,7 +2734,7 @@
         mode = OT_MAC_FILTER_ADDRESS_MODE_WHITELIST;
     }
 
-    error = otLinkFilterSetAddressMode(mInstance, mode);
+    otLinkFilterSetAddressMode(mInstance, mode);
 
 exit:
     return error;
@@ -2709,20 +2749,13 @@
 
     while (mDecoder.GetRemainingLengthInStruct() > 0)
     {
-        const otExtAddress *extAddress = NULL;
+        const otExtAddress *extAddress = nullptr;
 
         SuccessOrExit(error = mDecoder.OpenStruct());
         SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
         SuccessOrExit(error = mDecoder.CloseStruct());
 
-        error = otLinkFilterRemoveAddress(mInstance, extAddress);
-
-        if (error == OT_ERROR_ALREADY)
-        {
-            error = OT_ERROR_NONE;
-        }
-
-        SuccessOrExit(error);
+        otLinkFilterRemoveAddress(mInstance, extAddress);
     }
 
 exit:
@@ -2733,7 +2766,7 @@
 
     if (error != OT_ERROR_NONE)
     {
-        WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_BLACKLIST);
+        IgnoreError(WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_BLACKLIST));
     }
 
     return error;
@@ -2752,7 +2785,7 @@
         mode = OT_MAC_FILTER_ADDRESS_MODE_BLACKLIST;
     }
 
-    error = otLinkFilterSetAddressMode(mInstance, mode);
+    otLinkFilterSetAddressMode(mInstance, mode);
 
 exit:
     return error;
@@ -2763,7 +2796,7 @@
     otError error = OT_ERROR_NONE;
 
     // First, clear the address filter entries.
-    otLinkFilterClearRssIn(mInstance);
+    otLinkFilterClearAllRssIn(mInstance);
 
     while (mDecoder.GetRemainingLengthInStruct() > 0)
     {
@@ -2778,14 +2811,21 @@
         }
         else
         {
-            extAddress = NULL;
+            extAddress = nullptr;
         }
 
         SuccessOrExit(error = mDecoder.ReadInt8(rss));
 
         SuccessOrExit(error = mDecoder.CloseStruct());
 
-        SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, extAddress, rss));
+        if (extAddress != nullptr)
+        {
+            SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, extAddress, rss));
+        }
+        else
+        {
+            otLinkFilterSetDefaultRssIn(mInstance, rss);
+        }
     }
 
 exit:
@@ -2796,7 +2836,7 @@
 
     if (error != OT_ERROR_NONE)
     {
-        WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_FIXED_RSS);
+        IgnoreError(WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_FIXED_RSS));
     }
 
     return error;
@@ -2871,11 +2911,11 @@
 
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_STREAM_NET_INSECURE>(void)
 {
-    const uint8_t *   framePtr    = NULL;
+    const uint8_t *   framePtr    = nullptr;
     uint16_t          frameLen    = 0;
-    const uint8_t *   metaPtr     = NULL;
+    const uint8_t *   metaPtr     = nullptr;
     uint16_t          metaLen     = 0;
-    otMessage *       message     = NULL;
+    otMessage *       message     = nullptr;
     otError           error       = OT_ERROR_NONE;
     otMessageSettings msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL};
 
@@ -2887,7 +2927,7 @@
 
     // STREAM_NET_INSECURE packets are not secured at layer 2.
     message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, &msgSettings);
-    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
     // Ensure the insecure message is forwarded using direct transmission.
     otMessageSetDirectTransmission(message, true);
@@ -2936,9 +2976,9 @@
 
 template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_WHITELIST>(void)
 {
-    otError             error      = OT_ERROR_NONE;
-    const otExtAddress *extAddress = NULL;
-    int8_t              rss        = OT_MAC_FILTER_FIXED_RSS_DISABLED;
+    otError             error = OT_ERROR_NONE;
+    const otExtAddress *extAddress;
+    int8_t              rss = OT_MAC_FILTER_FIXED_RSS_DISABLED;
 
     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
 
@@ -2967,8 +3007,8 @@
 
 template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_BLACKLIST>(void)
 {
-    otError             error      = OT_ERROR_NONE;
-    const otExtAddress *extAddress = NULL;
+    otError             error = OT_ERROR_NONE;
+    const otExtAddress *extAddress;
 
     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
 
@@ -2986,7 +3026,7 @@
 template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_FIXED_RSS>(void)
 {
     otError             error      = OT_ERROR_NONE;
-    const otExtAddress *extAddress = NULL;
+    const otExtAddress *extAddress = nullptr;
     int8_t              rss        = OT_MAC_FILTER_FIXED_RSS_DISABLED;
 
     if (mDecoder.GetRemainingLength() > sizeof(int8_t))
@@ -2996,7 +3036,14 @@
 
     SuccessOrExit(mDecoder.ReadInt8(rss));
 
-    error = otLinkFilterAddRssIn(mInstance, extAddress, rss);
+    if (extAddress != nullptr)
+    {
+        error = otLinkFilterAddRssIn(mInstance, extAddress, rss);
+    }
+    else
+    {
+        otLinkFilterSetDefaultRssIn(mInstance, rss);
+    }
 
 exit:
     return error;
@@ -3028,16 +3075,11 @@
 template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MAC_WHITELIST>(void)
 {
     otError             error      = OT_ERROR_NONE;
-    const otExtAddress *extAddress = NULL;
+    const otExtAddress *extAddress = nullptr;
 
     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
 
-    error = otLinkFilterRemoveAddress(mInstance, extAddress);
-
-    if (error == OT_ERROR_NOT_FOUND)
-    {
-        error = OT_ERROR_NONE;
-    }
+    otLinkFilterRemoveAddress(mInstance, extAddress);
 
 exit:
     return error;
@@ -3046,16 +3088,11 @@
 template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MAC_BLACKLIST>(void)
 {
     otError             error      = OT_ERROR_NONE;
-    const otExtAddress *extAddress = NULL;
+    const otExtAddress *extAddress = nullptr;
 
     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
 
-    error = otLinkFilterRemoveAddress(mInstance, extAddress);
-
-    if (error == OT_ERROR_NOT_FOUND)
-    {
-        error = OT_ERROR_NONE;
-    }
+    otLinkFilterRemoveAddress(mInstance, extAddress);
 
 exit:
     return error;
@@ -3064,18 +3101,20 @@
 template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MAC_FIXED_RSS>(void)
 {
     otError             error      = OT_ERROR_NONE;
-    const otExtAddress *extAddress = NULL;
+    const otExtAddress *extAddress = nullptr;
 
     if (mDecoder.GetRemainingLength() > 0)
     {
         SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
     }
 
-    error = otLinkFilterRemoveRssIn(mInstance, extAddress);
-
-    if (error == OT_ERROR_NOT_FOUND)
+    if (extAddress != nullptr)
     {
-        error = OT_ERROR_NONE;
+        otLinkFilterRemoveRssIn(mInstance, extAddress);
+    }
+    else
+    {
+        otLinkFilterClearDefaultRssIn(mInstance);
     }
 
 exit:
@@ -3084,7 +3123,7 @@
 
 #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
 
-#if OPENTHREAD_PLATFORM_POSIX_APP
+#if OPENTHREAD_PLATFORM_POSIX
 
 template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_RCP_VERSION>(void)
 {
@@ -3121,7 +3160,7 @@
     mLegacyHandlers = aHandlers;
     bool isEnabled;
 
-    VerifyOrExit(mLegacyHandlers != NULL);
+    VerifyOrExit(mLegacyHandlers != nullptr, OT_NOOP);
 
     isEnabled = (otThreadGetDeviceRole(mInstance) != OT_DEVICE_ROLE_DISABLED);
 
@@ -3171,7 +3210,7 @@
 
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NEST_LEGACY_ULA_PREFIX>(void)
 {
-    const uint8_t *ptr = NULL;
+    const uint8_t *ptr = nullptr;
     uint16_t       len;
     otError        error = OT_ERROR_NONE;
 
@@ -3182,7 +3221,7 @@
     memset(mLegacyUlaPrefix, 0, sizeof(mLegacyUlaPrefix));
     memcpy(mLegacyUlaPrefix, ptr, len);
 
-    if ((mLegacyHandlers != NULL) && (mLegacyHandlers->mSetLegacyUlaPrefix != NULL))
+    if ((mLegacyHandlers != nullptr) && (mLegacyHandlers->mSetLegacyUlaPrefix != nullptr))
     {
         mLegacyHandlers->mSetLegacyUlaPrefix(mLegacyUlaPrefix);
     }
@@ -3205,7 +3244,7 @@
 {
     mLegacyNodeDidJoin = false;
 
-    if ((mLegacyHandlers != NULL) && (mLegacyHandlers->mStartLegacy != NULL))
+    if ((mLegacyHandlers != nullptr) && (mLegacyHandlers->mStartLegacy != nullptr))
     {
         mLegacyHandlers->mStartLegacy();
     }
@@ -3215,7 +3254,7 @@
 {
     mLegacyNodeDidJoin = false;
 
-    if ((mLegacyHandlers != NULL) && (mLegacyHandlers->mStopLegacy != NULL))
+    if ((mLegacyHandlers != nullptr) && (mLegacyHandlers->mStopLegacy != nullptr))
     {
         mLegacyHandlers->mStopLegacy();
     }
@@ -3396,9 +3435,12 @@
 
 void NcpBase::HandleDatagramFromStack(otMessage *aMessage)
 {
-    VerifyOrExit(aMessage != NULL);
+    VerifyOrExit(aMessage != nullptr, OT_NOOP);
 
-    SuccessOrExit(otMessageQueueEnqueue(&mMessageQueue, aMessage));
+    // Do not forward frames larger than SPINEL payload size.
+    VerifyOrExit(otMessageGetLength(aMessage) <= SPINEL_FRAME_MAX_COMMAND_PAYLOAD_SIZE, otMessageFree(aMessage));
+
+    otMessageQueueEnqueue(&mMessageQueue, aMessage);
 
     // If there is no queued spinel command response, try to write/send
     // the datagram message immediately. If there is a queued response
@@ -3409,7 +3451,7 @@
 
     if (IsResponseQueueEmpty())
     {
-        IgnoreReturnValue(SendQueuedDatagramMessages());
+        IgnoreError(SendQueuedDatagramMessages());
     }
 
 exit:
@@ -3449,7 +3491,7 @@
     otError    error = OT_ERROR_NONE;
     otMessage *message;
 
-    while ((message = otMessageQueueGetHead(&mMessageQueue)) != NULL)
+    while ((message = otMessageQueueGetHead(&mMessageQueue)) != nullptr)
     {
         // Since an `otMessage` instance can be in one queue at a time,
         // it is first dequeued from `mMessageQueue` before attempting
@@ -3476,7 +3518,7 @@
 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_UDP_FORWARD_STREAM>(void)
 {
-    const uint8_t *     framePtr = NULL;
+    const uint8_t *     framePtr = nullptr;
     uint16_t            frameLen = 0;
     const otIp6Address *peerAddr;
     uint16_t            peerPort;
@@ -3486,7 +3528,7 @@
     otMessageSettings   msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL};
 
     message = otIp6NewMessage(mInstance, &msgSettings);
-    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = mDecoder.ReadDataWithLen(framePtr, frameLen));
     SuccessOrExit(error = mDecoder.ReadUint16(peerPort));
@@ -3498,12 +3540,12 @@
     otUdpForwardReceive(mInstance, message, peerPort, peerAddr, sockPort);
 
     // `otUdpForwardReceive()` takes ownership of `message` (in both success
-    // or failure cases). `message` is set to NULL so it is not freed at
+    // or failure cases). `message` is set to nullptr so it is not freed at
     // exit.
-    message = NULL;
+    message = nullptr;
 
 exit:
-    if (message != NULL)
+    if (message != nullptr)
     {
         otMessageFree(message);
     }
@@ -3538,11 +3580,11 @@
     // after frame was finished/ended successfully. It will be freed
     // when the frame is successfully sent and removed.
 
-    aMessage = NULL;
+    aMessage = nullptr;
 
 exit:
 
-    if (aMessage != NULL)
+    if (aMessage != nullptr)
     {
         otMessageFree(aMessage);
     }
@@ -3563,7 +3605,7 @@
     uint16_t flags  = 0;
     uint8_t  header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
 
-    VerifyOrExit(mPcapEnabled);
+    VerifyOrExit(mPcapEnabled, OT_NOOP);
 
     if (aIsTx)
     {
@@ -3605,7 +3647,7 @@
     bool    enabled;
 
     SuccessOrExit(error = mDecoder.ReadBool(enabled));
-    VerifyOrExit(enabled != mPcapEnabled);
+    VerifyOrExit(enabled != mPcapEnabled, OT_NOOP);
 
     mPcapEnabled = enabled;
 
@@ -3615,7 +3657,7 @@
     }
     else
     {
-        otLinkSetPcapCallback(mInstance, NULL, NULL);
+        otLinkSetPcapCallback(mInstance, nullptr, nullptr);
     }
 
 exit:
@@ -3657,13 +3699,15 @@
         {OT_CHANGED_THREAD_PANID, SPINEL_PROP_MAC_15_4_PANID},
         {OT_CHANGED_THREAD_NETWORK_NAME, SPINEL_PROP_NET_NETWORK_NAME},
         {OT_CHANGED_THREAD_EXT_PANID, SPINEL_PROP_NET_XPANID},
+        {OT_CHANGED_THREAD_RLOC_ADDED, SPINEL_PROP_IPV6_ADDRESS_TABLE},
+        {OT_CHANGED_THREAD_RLOC_REMOVED, SPINEL_PROP_IPV6_ADDRESS_TABLE},
         {OT_CHANGED_MASTER_KEY, SPINEL_PROP_NET_MASTER_KEY},
         {OT_CHANGED_PSKC, SPINEL_PROP_NET_PSKC},
         {OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL, SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL},
         {OT_CHANGED_SUPPORTED_CHANNEL_MASK, SPINEL_PROP_PHY_CHAN_SUPPORTED},
     };
 
-    VerifyOrExit(mThreadChangedFlags != 0);
+    VerifyOrExit(mThreadChangedFlags != 0, OT_NOOP);
 
     // If thread role has changed, check for possible "join" error.
 
@@ -3690,7 +3734,7 @@
             )
             {
                 mThreadChangedFlags &= ~static_cast<uint32_t>(OT_CHANGED_THREAD_PARTITION_ID);
-                otThreadSetEnabled(mInstance, false);
+                IgnoreError(otThreadSetEnabled(mInstance, false));
 
                 mChangedPropsSet.AddProperty(SPINEL_PROP_NET_STACK_UP);
                 mChangedPropsSet.AddLastStatus(SPINEL_STATUS_JOIN_FAILURE);
@@ -3700,7 +3744,7 @@
 
     // Convert OT_CHANGED flags to corresponding NCP property update.
 
-    for (unsigned i = 0; i < OT_ARRAY_LENGTH(kFlags); i++)
+    for (size_t i = 0; i < OT_ARRAY_LENGTH(kFlags); i++)
     {
         uint32_t threadFlag = kFlags[i].mThreadFlag;
 
@@ -3734,12 +3778,12 @@
             }
 
             mThreadChangedFlags &= ~threadFlag;
-            VerifyOrExit(mThreadChangedFlags != 0);
+            VerifyOrExit(mThreadChangedFlags != 0, OT_NOOP);
         }
     }
 
     // Clear any remaining ThreadFlag that has no matching
-    // NCP property update (e.g., OT_CHANGED_THREAD_RLOC_ADDED)
+    // NCP property update (e.g., OT_CHANGED_SECURITY_POLICY)
 
     mThreadChangedFlags = 0;
 
@@ -3759,7 +3803,7 @@
 #if OPENTHREAD_CONFIG_LEGACY_ENABLE
     ot::Ncp::NcpBase *ncp = ot::Ncp::NcpBase::GetNcpInstance();
 
-    if (ncp != NULL)
+    if (ncp != nullptr)
     {
         ncp->RegisterLegacyHandlers(aHandlers);
     }
@@ -3774,7 +3818,7 @@
 #if OPENTHREAD_CONFIG_LEGACY_ENABLE
     ot::Ncp::NcpBase *ncp = ot::Ncp::NcpBase::GetNcpInstance();
 
-    if (ncp != NULL)
+    if (ncp != nullptr)
     {
         ncp->HandleDidReceiveNewLegacyUlaPrefix(aUlaPrefix);
     }
@@ -3789,7 +3833,7 @@
 #if OPENTHREAD_CONFIG_LEGACY_ENABLE
     ot::Ncp::NcpBase *ncp = ot::Ncp::NcpBase::GetNcpInstance();
 
-    if (ncp != NULL)
+    if (ncp != nullptr)
     {
         ncp->HandleLegacyNodeDidJoin(aExtAddr);
     }
diff --git a/src/ncp/ncp_base_radio.cpp b/src/ncp/ncp_base_radio.cpp
index 25d9120..0d23a69 100644
--- a/src/ncp/ncp_base_radio.cpp
+++ b/src/ncp/ncp_base_radio.cpp
@@ -36,6 +36,7 @@
 #include <openthread/link_raw.h>
 #include <openthread/ncp.h>
 #include <openthread/platform/radio.h>
+#include <openthread/platform/time.h>
 
 #include "common/code_utils.hpp"
 #include "common/debug.hpp"
@@ -51,20 +52,12 @@
 // MARK: Raw Link-Layer Datapath Glue
 // ----------------------------------------------------------------------------
 
-void NcpBase::LinkRawReceiveDone(otInstance *, otRadioFrame *aFrame, otError aError)
+otError NcpBase::PackRadioFrame(otRadioFrame *aFrame, otError aError)
 {
-    sNcpInstance->LinkRawReceiveDone(aFrame, aError);
-}
+    otError  error = OT_ERROR_FAILED;
+    uint16_t flags = 0;
 
-void NcpBase::LinkRawReceiveDone(otRadioFrame *aFrame, otError aError)
-{
-    uint16_t flags  = 0;
-    uint8_t  header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
-
-    // Append frame header
-    SuccessOrExit(mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_STREAM_RAW));
-
-    if (aError == OT_ERROR_NONE)
+    if (aFrame != nullptr && aError == OT_ERROR_NONE)
     {
         // Append the frame contents
         SuccessOrExit(mEncoder.WriteDataWithLen(aFrame->mPsdu, aFrame->mLength));
@@ -76,28 +69,61 @@
     }
 
     // Append metadata (rssi, etc)
-    SuccessOrExit(mEncoder.WriteInt8(aFrame->mInfo.mRxInfo.mRssi)); // RSSI
-    SuccessOrExit(mEncoder.WriteInt8(-128));                        // Noise Floor (Currently unused)
+    SuccessOrExit(mEncoder.WriteInt8(aFrame ? aFrame->mInfo.mRxInfo.mRssi : 0)); // RSSI
+    SuccessOrExit(mEncoder.WriteInt8(-128));                                     // Noise Floor (Currently unused)
 
-    if (aFrame->mInfo.mRxInfo.mAckedWithFramePending)
+    if (aFrame != nullptr)
     {
-        flags |= SPINEL_MD_FLAG_ACKED_FP;
+        if (aFrame->mInfo.mRxInfo.mAckedWithFramePending)
+        {
+            flags |= SPINEL_MD_FLAG_ACKED_FP;
+        }
+
+        if (aFrame->mInfo.mRxInfo.mAckedWithSecEnhAck)
+        {
+            flags |= SPINEL_MD_FLAG_ACKED_SEC;
+        }
     }
 
     SuccessOrExit(mEncoder.WriteUint16(flags)); // Flags
 
-    SuccessOrExit(mEncoder.OpenStruct());                           // PHY-data
-    SuccessOrExit(mEncoder.WriteUint8(aFrame->mChannel));           // 802.15.4 channel (Receive channel)
-    SuccessOrExit(mEncoder.WriteUint8(aFrame->mInfo.mRxInfo.mLqi)); // 802.15.4 LQI
+    SuccessOrExit(mEncoder.OpenStruct());                              // PHY-data
+    SuccessOrExit(mEncoder.WriteUint8(aFrame ? aFrame->mChannel : 0)); // 802.15.4 channel (Receive channel)
+    SuccessOrExit(mEncoder.WriteUint8(aFrame ? aFrame->mInfo.mRxInfo.mLqi
+                                             : static_cast<uint8_t>(OT_RADIO_LQI_NONE))); // 802.15.4 LQI
 
-    SuccessOrExit(mEncoder.WriteUint64(aFrame->mInfo.mRxInfo.mTimestamp)); // The timestamp in microseconds
-
+    SuccessOrExit(mEncoder.WriteUint64(aFrame ? aFrame->mInfo.mRxInfo.mTimestamp : 0)); // The timestamp in microseconds
     SuccessOrExit(mEncoder.CloseStruct());
 
     SuccessOrExit(mEncoder.OpenStruct());            // Vendor-data
     SuccessOrExit(mEncoder.WriteUintPacked(aError)); // Receive error
     SuccessOrExit(mEncoder.CloseStruct());
 
+    SuccessOrExit(mEncoder.OpenStruct());                                             // MAC-data
+    SuccessOrExit(mEncoder.WriteUint8(aFrame ? aFrame->mInfo.mRxInfo.mAckKeyId : 0)); // The ACK auxiliary key ID
+    SuccessOrExit(
+        mEncoder.WriteUint32(aFrame ? aFrame->mInfo.mRxInfo.mAckFrameCounter : 0)); // The ACK auxiliary frame counter
+    SuccessOrExit(mEncoder.CloseStruct());
+
+    error = OT_ERROR_NONE;
+
+exit:
+    return error;
+}
+
+void NcpBase::LinkRawReceiveDone(otInstance *, otRadioFrame *aFrame, otError aError)
+{
+    sNcpInstance->LinkRawReceiveDone(aFrame, aError);
+}
+
+void NcpBase::LinkRawReceiveDone(otRadioFrame *aFrame, otError aError)
+{
+    uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
+
+    // Append frame header
+    SuccessOrExit(mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_STREAM_RAW));
+
+    SuccessOrExit(PackRadioFrame(aFrame, aError));
     SuccessOrExit(mEncoder.EndFrame());
 
 exit:
@@ -116,7 +142,7 @@
     if (mCurTransmitTID)
     {
         uint8_t header       = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0 | mCurTransmitTID;
-        bool    framePending = (aAckFrame != NULL && static_cast<Mac::RxFrame *>(aAckFrame)->GetFramePending());
+        bool    framePending = (aAckFrame != nullptr && static_cast<Mac::RxFrame *>(aAckFrame)->GetFramePending());
 
         // Clear cached transmit TID
         mCurTransmitTID = 0;
@@ -125,25 +151,22 @@
         SuccessOrExit(mEncoder.WriteUintPacked(ThreadErrorToSpinelStatus(aError)));
         SuccessOrExit(mEncoder.WriteBool(framePending));
 
-        if (aAckFrame && aError == OT_ERROR_NONE)
+        if (aError == OT_ERROR_NONE)
         {
-            SuccessOrExit(mEncoder.WriteUint16(aAckFrame->mLength));
-            SuccessOrExit(mEncoder.WriteData(aAckFrame->mPsdu, aAckFrame->mLength));
+            SuccessOrExit(PackRadioFrame(aAckFrame, aError));
+        }
 
-            SuccessOrExit(mEncoder.WriteInt8(aAckFrame->mInfo.mRxInfo.mRssi)); // RSSI
-            SuccessOrExit(mEncoder.WriteInt8(-128));                           // Noise Floor (Currently unused)
-            SuccessOrExit(mEncoder.WriteUint16(0));                            // Flags
+        if (static_cast<Mac::TxFrame *>(aFrame)->GetSecurityEnabled())
+        {
+            uint8_t  keyId;
+            uint32_t frameCounter;
 
-            SuccessOrExit(mEncoder.OpenStruct());                                     // PHY-data
-            SuccessOrExit(mEncoder.WriteUint8(aAckFrame->mChannel));                  // Receive channel
-            SuccessOrExit(mEncoder.WriteUint8(aAckFrame->mInfo.mRxInfo.mLqi));        // Link Quality Indicator
-            SuccessOrExit(mEncoder.WriteUint64(aAckFrame->mInfo.mRxInfo.mTimestamp)); // The timestamp in microseconds
+            // Transmit frame auxiliary key index and frame counter
+            SuccessOrExit(static_cast<Mac::TxFrame *>(aFrame)->GetKeyId(keyId));
+            SuccessOrExit(static_cast<Mac::TxFrame *>(aFrame)->GetFrameCounter(frameCounter));
 
-            SuccessOrExit(mEncoder.CloseStruct());
-
-            SuccessOrExit(mEncoder.OpenStruct());            // Vendor-data
-            SuccessOrExit(mEncoder.WriteUintPacked(aError)); // Receive error
-            SuccessOrExit(mEncoder.CloseStruct());
+            SuccessOrExit(mEncoder.WriteUint8(keyId));
+            SuccessOrExit(mEncoder.WriteUint32(frameCounter));
         }
 
         SuccessOrExit(mEncoder.EndFrame());
@@ -167,7 +190,7 @@
 
     // Make sure we are back listening on the original receive channel,
     // since the energy scan could have been on a different channel.
-    otLinkRawReceive(mInstance, &NcpBase::LinkRawReceiveDone);
+    IgnoreError(otLinkRawReceive(mInstance));
 
     SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
                                       SPINEL_PROP_MAC_ENERGY_SCAN_RESULT));
@@ -199,6 +222,16 @@
     return mEncoder.WriteBool(mSrcMatchEnabled);
 }
 
+template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_RCP_TIMESTAMP>(void)
+{
+    otError error = OT_ERROR_NONE;
+
+    SuccessOrExit(error = mEncoder.WriteUint64(otLinkRawGetRadioTime(mInstance)));
+
+exit:
+    return error;
+}
+
 template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_SRC_MATCH_ENABLED>(void)
 {
     otError error = OT_ERROR_NONE;
@@ -296,7 +329,7 @@
 template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES>(void)
 {
     otError             error      = OT_ERROR_NONE;
-    const otExtAddress *extAddress = NULL;
+    const otExtAddress *extAddress = nullptr;
 
     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
 
@@ -315,23 +348,11 @@
 
     if (value == false)
     {
-        // If we have raw stream enabled stop receiving
-        if (mIsRawStreamEnabled)
-        {
-            otLinkRawSleep(mInstance);
-        }
-
-        error = otLinkRawSetEnable(mInstance, false);
+        error = otLinkRawSetReceiveDone(mInstance, NULL);
     }
     else
     {
-        error = otLinkRawSetEnable(mInstance, true);
-
-        // If we have raw stream enabled already, start receiving
-        if (error == OT_ERROR_NONE && mIsRawStreamEnabled)
-        {
-            error = otLinkRawReceive(mInstance, &NcpBase::LinkRawReceiveDone);
-        }
+        error = otLinkRawSetReceiveDone(mInstance, &NcpBase::LinkRawReceiveDone);
     }
 
 exit:
@@ -357,6 +378,8 @@
     const uint8_t *payloadPtr;
     uint16_t       payloadLen;
     bool           csmaEnable;
+    bool           isARetx;
+    bool           isSecurityProcessed;
 
     SuccessOrExit(error = mDecoder.ReadDataWithLen(payloadPtr, payloadLen));
     VerifyOrExit(payloadLen <= OT_RADIO_FRAME_MAX_SIZE, error = OT_ERROR_PARSE);
@@ -370,9 +393,11 @@
     SuccessOrExit(error = mDecoder.ReadUint8(aFrame.mChannel));
 
     // Set the default value for all optional parameters.
-    aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs = OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT;
-    aFrame.mInfo.mTxInfo.mMaxFrameRetries = OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT;
-    aFrame.mInfo.mTxInfo.mCsmaCaEnabled   = true;
+    aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs     = OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT;
+    aFrame.mInfo.mTxInfo.mMaxFrameRetries     = OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT;
+    aFrame.mInfo.mTxInfo.mCsmaCaEnabled       = true;
+    aFrame.mInfo.mTxInfo.mIsARetx             = false;
+    aFrame.mInfo.mTxInfo.mIsSecurityProcessed = false;
 
     // All the next parameters are optional. Note that even if the
     // decoder fails to parse any of optional parameters we still want to
@@ -382,7 +407,11 @@
     SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs));
     SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mMaxFrameRetries));
     SuccessOrExit(mDecoder.ReadBool(csmaEnable));
-    aFrame.mInfo.mTxInfo.mCsmaCaEnabled = csmaEnable;
+    SuccessOrExit(mDecoder.ReadBool(isARetx));
+    SuccessOrExit(mDecoder.ReadBool(isSecurityProcessed));
+    aFrame.mInfo.mTxInfo.mCsmaCaEnabled       = csmaEnable;
+    aFrame.mInfo.mTxInfo.mIsARetx             = isARetx;
+    aFrame.mInfo.mTxInfo.mIsSecurityProcessed = isSecurityProcessed;
 
 exit:
     return error;
@@ -396,7 +425,7 @@
     VerifyOrExit(otLinkRawIsEnabled(mInstance), error = OT_ERROR_INVALID_STATE);
 
     frame = otLinkRawGetTransmitBuffer(mInstance);
-    VerifyOrExit(frame != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(frame != nullptr, error = OT_ERROR_NO_BUFS);
 
     SuccessOrExit(error = DecodeStreamRawTxRequest(*frame));
 
@@ -421,6 +450,51 @@
     return error;
 }
 
+template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_MAC_KEY>(void)
+{
+    otError        error = OT_ERROR_NONE;
+    uint8_t        keyIdMode;
+    uint8_t        keyId;
+    uint16_t       keySize;
+    const uint8_t *prevKey;
+    const uint8_t *currKey;
+    const uint8_t *nextKey;
+
+    SuccessOrExit(error = mDecoder.ReadUint8(keyIdMode));
+    VerifyOrExit(keyIdMode == Mac::Frame::kKeyIdMode1, error = OT_ERROR_INVALID_ARGS);
+
+    SuccessOrExit(error = mDecoder.ReadUint8(keyId));
+
+    SuccessOrExit(error = mDecoder.ReadDataWithLen(prevKey, keySize));
+    VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
+
+    SuccessOrExit(error = mDecoder.ReadDataWithLen(currKey, keySize));
+    VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
+
+    SuccessOrExit(error = mDecoder.ReadDataWithLen(nextKey, keySize));
+    VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
+
+    error =
+        otLinkRawSetMacKey(mInstance, keyIdMode, keyId, reinterpret_cast<const otMacKey *>(prevKey),
+                           reinterpret_cast<const otMacKey *>(currKey), reinterpret_cast<const otMacKey *>(nextKey));
+
+exit:
+    return error;
+}
+
+template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_MAC_FRAME_COUNTER>(void)
+{
+    otError  error = OT_ERROR_NONE;
+    uint32_t frameCounter;
+
+    SuccessOrExit(error = mDecoder.ReadUint32(frameCounter));
+
+    error = otLinkRawSetMacFrameCounter(mInstance, frameCounter);
+
+exit:
+    return error;
+}
+
 } // namespace Ncp
 } // namespace ot
 
diff --git a/src/ncp/ncp_buffer.cpp b/src/ncp/ncp_buffer.cpp
deleted file mode 100644
index 2a63f5b..0000000
--- a/src/ncp/ncp_buffer.cpp
+++ /dev/null
@@ -1,976 +0,0 @@
-/*
- *    Copyright (c) 2016, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements NCP frame buffer class.
- */
-
-#include "ncp_buffer.hpp"
-
-#include "common/code_utils.hpp"
-#include "common/debug.hpp"
-
-namespace ot {
-namespace Ncp {
-
-const NcpFrameBuffer::FrameTag NcpFrameBuffer::kInvalidTag = NULL;
-
-NcpFrameBuffer::NcpFrameBuffer(uint8_t *aBuffer, uint16_t aBufferLength)
-    : mBuffer(aBuffer)
-    , mBufferEnd(aBuffer + aBufferLength)
-    , mBufferLength(aBufferLength)
-{
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    for (uint8_t priority = 0; priority < kNumPrios; priority++)
-    {
-        otMessageQueueInit(&mMessageQueue[priority]);
-    }
-
-    otMessageQueueInit(&mWriteFrameMessageQueue);
-#endif
-
-    SetFrameAddedCallback(NULL, NULL);
-    SetFrameRemovedCallback(NULL, NULL);
-    Clear();
-}
-
-void NcpFrameBuffer::Clear(void)
-{
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    otMessage *message;
-#endif
-
-    // Write (InFrame) related variables
-    mWriteFrameStart[kPriorityLow]  = mBuffer;
-    mWriteFrameStart[kPriorityHigh] = GetUpdatedBufPtr(mBuffer, 1, kBackward);
-    mWriteDirection                 = kUnknown;
-    mWriteSegmentHead               = mBuffer;
-    mWriteSegmentTail               = mBuffer;
-    mWriteFrameTag                  = kInvalidTag;
-
-    // Read (OutFrame) related variables
-    mReadDirection   = kForward;
-    mReadState       = kReadStateNotActive;
-    mReadFrameLength = kUnknownFrameLength;
-
-    mReadFrameStart[kPriorityLow]  = mBuffer;
-    mReadFrameStart[kPriorityHigh] = GetUpdatedBufPtr(mBuffer, 1, kBackward);
-    mReadSegmentHead               = mBuffer;
-    mReadSegmentTail               = mBuffer;
-    mReadPointer                   = mBuffer;
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    mReadMessage       = NULL;
-    mReadMessageOffset = 0;
-    mReadMessageTail   = mMessageBuffer;
-
-    // Free all messages in the queues.
-
-    while ((message = otMessageQueueGetHead(&mWriteFrameMessageQueue)) != NULL)
-    {
-        otMessageQueueDequeue(&mWriteFrameMessageQueue, message);
-
-        // Note that messages associated with current (unfinished) input frame
-        // are not yet owned by the `NcpFrameBuffer` and therefore should not
-        // be freed.
-    }
-
-    for (uint8_t priority = 0; priority < kNumPrios; priority++)
-    {
-        while ((message = otMessageQueueGetHead(&mMessageQueue[priority])) != NULL)
-        {
-            otMessageQueueDequeue(&mMessageQueue[priority], message);
-            otMessageFree(message);
-        }
-    }
-#endif
-}
-
-void NcpFrameBuffer::SetFrameAddedCallback(BufferCallback aFrameAddedCallback, void *aFrameAddedContext)
-{
-    mFrameAddedCallback = aFrameAddedCallback;
-    mFrameAddedContext  = aFrameAddedContext;
-}
-
-void NcpFrameBuffer::SetFrameRemovedCallback(BufferCallback aFrameRemovedCallback, void *aFrameRemovedContext)
-{
-    mFrameRemovedCallback = aFrameRemovedCallback;
-    mFrameRemovedContext  = aFrameRemovedContext;
-}
-
-// Returns an updated buffer pointer by moving forward/backward (based on `aDirection`) from `aBufPtr` by a given
-// offset. The resulting buffer pointer is ensured to stay within the `mBuffer` boundaries.
-uint8_t *NcpFrameBuffer::GetUpdatedBufPtr(uint8_t *aBufPtr, uint16_t aOffset, Direction aDirection) const
-{
-    uint8_t *ptr = aBufPtr;
-
-    switch (aDirection)
-    {
-    case kForward:
-        ptr += aOffset;
-
-        while (ptr >= mBufferEnd)
-        {
-            ptr -= mBufferLength;
-        }
-
-        break;
-
-    case kBackward:
-        ptr -= aOffset;
-
-        while (ptr < mBuffer)
-        {
-            ptr += mBufferLength;
-        }
-
-        break;
-
-    case kUnknown:
-        assert(false);
-        break;
-    }
-
-    return ptr;
-}
-
-// Gets the distance between two buffer pointers (adjusts for the wrap-around) given a direction (forward or backward).
-uint16_t NcpFrameBuffer::GetDistance(const uint8_t *aStartPtr, const uint8_t *aEndPtr, Direction aDirection) const
-{
-    size_t distance = 0;
-
-    switch (aDirection)
-    {
-    case kForward:
-
-        if (aEndPtr >= aStartPtr)
-        {
-            distance = static_cast<size_t>(aEndPtr - aStartPtr);
-        }
-        else
-        {
-            distance = static_cast<size_t>(mBufferEnd - aStartPtr);
-            distance += static_cast<size_t>(aEndPtr - mBuffer);
-        }
-
-        break;
-
-    case kBackward:
-
-        if (aEndPtr <= aStartPtr)
-        {
-            distance = static_cast<size_t>(aStartPtr - aEndPtr);
-        }
-        else
-        {
-            distance = static_cast<size_t>(mBufferEnd - aEndPtr);
-            distance += static_cast<size_t>(aStartPtr - mBuffer);
-        }
-
-        break;
-
-    case kUnknown:
-        assert(false);
-        break;
-    }
-
-    return static_cast<uint16_t>(distance);
-}
-
-// Writes a uint16 value at the given buffer pointer (big-endian style).
-void NcpFrameBuffer::WriteUint16At(uint8_t *aBufPtr, uint16_t aValue, Direction aDirection)
-{
-    *aBufPtr                                  = (aValue >> 8);
-    *GetUpdatedBufPtr(aBufPtr, 1, aDirection) = (aValue & 0xff);
-}
-
-// Reads a uint16 value at the given buffer pointer (big-endian style).
-uint16_t NcpFrameBuffer::ReadUint16At(uint8_t *aBufPtr, Direction aDirection)
-{
-    uint16_t value;
-
-    value = static_cast<uint16_t>((*aBufPtr) << 8);
-    value += *GetUpdatedBufPtr(aBufPtr, 1, aDirection);
-
-    return value;
-}
-
-// Appends a byte at the write tail and updates the tail, discards the frame if buffer gets full.
-otError NcpFrameBuffer::InFrameAppend(uint8_t aByte)
-{
-    otError  error = OT_ERROR_NONE;
-    uint8_t *newTail;
-
-    assert(mWriteDirection != kUnknown);
-
-    newTail = GetUpdatedBufPtr(mWriteSegmentTail, 1, mWriteDirection);
-
-    // Ensure the `newTail` has not reached the `mWriteFrameStart` for other direction (other priority level).
-    if (newTail != mWriteFrameStart[(mWriteDirection == kForward) ? kBackward : kForward])
-    {
-        *mWriteSegmentTail = aByte;
-        mWriteSegmentTail  = newTail;
-    }
-    else
-    {
-        error = OT_ERROR_NO_BUFS;
-        InFrameDiscard();
-    }
-
-    return error;
-}
-
-// This method begins a new segment (if one is not already open).
-otError NcpFrameBuffer::InFrameBeginSegment(void)
-{
-    otError  error       = OT_ERROR_NONE;
-    uint16_t headerFlags = kSegmentHeaderNoFlag;
-
-    // Verify that segment is not yet started (i.e., head and tail are the same).
-    VerifyOrExit(mWriteSegmentHead == mWriteSegmentTail);
-
-    // Check if this is the start of a new frame (i.e., frame start is same as segment head).
-    if (mWriteFrameStart[mWriteDirection] == mWriteSegmentHead)
-    {
-        headerFlags |= kSegmentHeaderNewFrameFlag;
-    }
-
-    // Reserve space for the segment header.
-    for (uint16_t i = kSegmentHeaderSize; i; i--)
-    {
-        SuccessOrExit(error = InFrameAppend(0));
-    }
-
-    // Write the flags at the segment head.
-    WriteUint16At(mWriteSegmentHead, headerFlags, mWriteDirection);
-
-exit:
-    return error;
-}
-
-// This function closes/ends the current segment.
-void NcpFrameBuffer::InFrameEndSegment(uint16_t aSegmentHeaderFlags)
-{
-    uint16_t segmentLength;
-    uint16_t header;
-
-    segmentLength = GetDistance(mWriteSegmentHead, mWriteSegmentTail, mWriteDirection);
-
-    if (segmentLength >= kSegmentHeaderSize)
-    {
-        // Reduce the header size.
-        segmentLength -= kSegmentHeaderSize;
-
-        // Update the length and the flags in segment header (at segment head pointer).
-        header = ReadUint16At(mWriteSegmentHead, mWriteDirection);
-        header |= (segmentLength & kSegmentHeaderLengthMask);
-        header |= aSegmentHeaderFlags;
-        WriteUint16At(mWriteSegmentHead, header, mWriteDirection);
-
-        // Move the segment head to current tail (to be ready for a possible next segment).
-        mWriteSegmentHead = mWriteSegmentTail;
-    }
-    else
-    {
-        // Remove the current segment (move the tail back to head).
-        mWriteSegmentTail = mWriteSegmentHead;
-    }
-}
-
-// This method discards the current frame being written.
-void NcpFrameBuffer::InFrameDiscard(void)
-{
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    otMessage *message;
-#endif
-
-    VerifyOrExit(mWriteDirection != kUnknown);
-
-    // Move the write segment head and tail pointers back to frame start.
-    mWriteSegmentHead = mWriteSegmentTail = mWriteFrameStart[mWriteDirection];
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    while ((message = otMessageQueueGetHead(&mWriteFrameMessageQueue)) != NULL)
-    {
-        otMessageQueueDequeue(&mWriteFrameMessageQueue, message);
-
-        // Note that messages associated with current (unfinished) input frame
-        // being discarded, are not yet owned by the `NcpFrameBuffer` and
-        // therefore should not be freed.
-    }
-#endif
-
-    mWriteDirection = kUnknown;
-
-exit:
-    UpdateReadWriteStartPointers();
-}
-
-// Returns `true` if in middle of writing a frame with given priority.
-bool NcpFrameBuffer::InFrameIsWriting(Priority aPriority) const
-{
-    return (mWriteDirection == static_cast<Direction>(aPriority));
-}
-
-void NcpFrameBuffer::InFrameBegin(Priority aPriority)
-{
-    // Discard any previous unfinished frame.
-    InFrameDiscard();
-
-    switch (aPriority)
-    {
-    case kPriorityHigh:
-        mWriteDirection = kBackward;
-        break;
-
-    case kPriorityLow:
-        mWriteDirection = kForward;
-        break;
-    }
-
-    // Set up the segment head and tail
-    mWriteSegmentHead = mWriteSegmentTail = mWriteFrameStart[mWriteDirection];
-}
-
-otError NcpFrameBuffer::InFrameFeedByte(uint8_t aByte)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
-
-    // Begin a new segment (if we are not in middle of segment already).
-    SuccessOrExit(error = InFrameBeginSegment());
-
-    error = InFrameAppend(aByte);
-
-exit:
-    return error;
-}
-
-otError NcpFrameBuffer::InFrameFeedData(const uint8_t *aDataBuffer, uint16_t aDataBufferLength)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
-
-    // Begin a new segment (if we are not in middle of segment already).
-    SuccessOrExit(error = InFrameBeginSegment());
-
-    // Write the data buffer
-    while (aDataBufferLength--)
-    {
-        SuccessOrExit(error = InFrameAppend(*aDataBuffer++));
-    }
-
-exit:
-    return error;
-}
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-otError NcpFrameBuffer::InFrameFeedMessage(otMessage *aMessage)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(aMessage != NULL, error = OT_ERROR_INVALID_ARGS);
-    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
-
-    // Begin a new segment (if we are not in middle of segment already).
-    SuccessOrExit(error = InFrameBeginSegment());
-
-    // Enqueue the message in the current write frame queue.
-    SuccessOrExit(error = otMessageQueueEnqueue(&mWriteFrameMessageQueue, aMessage));
-
-    // End/Close the current segment marking the flag that it contains an associated message.
-    InFrameEndSegment(kSegmentHeaderMessageIndicatorFlag);
-
-exit:
-    return error;
-}
-#endif
-
-otError NcpFrameBuffer::InFrameGetPosition(WritePosition &aPosition)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
-
-    // Begin a new segment (if we are not in middle of segment already).
-    SuccessOrExit(error = InFrameBeginSegment());
-
-    aPosition.mPosition    = mWriteSegmentTail;
-    aPosition.mSegmentHead = mWriteSegmentHead;
-
-exit:
-    return error;
-}
-
-otError NcpFrameBuffer::InFrameOverwrite(const WritePosition &aPosition,
-                                         const uint8_t *      aDataBuffer,
-                                         uint16_t             aDataBufferLength)
-{
-    otError  error = OT_ERROR_NONE;
-    uint8_t *bufPtr;
-    uint16_t segmentLength;
-    uint16_t distance;
-
-    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
-
-    VerifyOrExit(aPosition.mSegmentHead == mWriteSegmentHead, error = OT_ERROR_INVALID_ARGS);
-
-    // Ensure the overwrite does not go beyond current segment tail.
-    segmentLength = GetDistance(mWriteSegmentHead, mWriteSegmentTail, mWriteDirection);
-    distance      = GetDistance(mWriteSegmentHead, aPosition.mPosition, mWriteDirection);
-    VerifyOrExit(distance + aDataBufferLength <= segmentLength, error = OT_ERROR_INVALID_ARGS);
-
-    bufPtr = aPosition.mPosition;
-    while (aDataBufferLength > 0)
-    {
-        *bufPtr = *aDataBuffer;
-
-        aDataBuffer++;
-        aDataBufferLength--;
-
-        bufPtr = GetUpdatedBufPtr(bufPtr, 1, mWriteDirection);
-    }
-
-exit:
-    return error;
-}
-
-uint16_t NcpFrameBuffer::InFrameGetDistance(const WritePosition &aPosition) const
-{
-    uint16_t distance = 0;
-    uint16_t segmentLength;
-    uint16_t offset;
-
-    VerifyOrExit(mWriteDirection != kUnknown);
-    VerifyOrExit(aPosition.mSegmentHead == mWriteSegmentHead);
-
-    segmentLength = GetDistance(mWriteSegmentHead, mWriteSegmentTail, mWriteDirection);
-    offset        = GetDistance(mWriteSegmentHead, aPosition.mPosition, mWriteDirection);
-    VerifyOrExit(offset < segmentLength);
-
-    distance = GetDistance(aPosition.mPosition, mWriteSegmentTail, mWriteDirection);
-
-exit:
-    return distance;
-}
-
-otError NcpFrameBuffer::InFrameReset(const WritePosition &aPosition)
-{
-    otError  error = OT_ERROR_NONE;
-    uint16_t segmentLength;
-    uint16_t offset;
-
-    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(aPosition.mSegmentHead == mWriteSegmentHead, error = OT_ERROR_INVALID_ARGS);
-
-    segmentLength = GetDistance(mWriteSegmentHead, mWriteSegmentTail, mWriteDirection);
-    offset        = GetDistance(mWriteSegmentHead, aPosition.mPosition, mWriteDirection);
-    VerifyOrExit(offset < segmentLength, error = OT_ERROR_INVALID_ARGS);
-
-    mWriteSegmentTail = aPosition.mPosition;
-
-exit:
-    return error;
-}
-
-otError NcpFrameBuffer::InFrameEnd(void)
-{
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    otMessage *message;
-#endif
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mWriteDirection != kUnknown, error = OT_ERROR_INVALID_STATE);
-
-    // End/Close the current segment (if any).
-    InFrameEndSegment(kSegmentHeaderNoFlag);
-
-    // Save and use the frame start pointer as the tag associated with the frame.
-    mWriteFrameTag = mWriteFrameStart[mWriteDirection];
-
-    // Update the frame start pointer to current segment head to be ready for next frame.
-    mWriteFrameStart[mWriteDirection] = mWriteSegmentHead;
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    // Move all the messages from the frame queue to the main queue.
-    while ((message = otMessageQueueGetHead(&mWriteFrameMessageQueue)) != NULL)
-    {
-        otMessageQueueDequeue(&mWriteFrameMessageQueue, message);
-        otMessageQueueEnqueue(&mMessageQueue[mWriteDirection], message);
-    }
-#endif
-
-    if (mFrameAddedCallback != NULL)
-    {
-        mFrameAddedCallback(mFrameAddedContext, mWriteFrameTag, static_cast<Priority>(mWriteDirection), this);
-    }
-
-    mWriteDirection = kUnknown;
-
-exit:
-    return error;
-}
-
-NcpFrameBuffer::FrameTag NcpFrameBuffer::InFrameGetLastTag(void) const
-{
-    return mWriteFrameTag;
-}
-
-bool NcpFrameBuffer::HasFrame(Priority aPriority) const
-{
-    return mReadFrameStart[aPriority] != mWriteFrameStart[aPriority];
-}
-
-bool NcpFrameBuffer::IsEmpty(void) const
-{
-    return !HasFrame(kPriorityHigh) && !HasFrame(kPriorityLow);
-}
-
-void NcpFrameBuffer::OutFrameSelectReadDirection(void)
-{
-    if (mReadState == kReadStateNotActive)
-    {
-        mReadDirection = HasFrame(kPriorityHigh) ? kBackward : kForward;
-    }
-}
-
-// Start/Prepare a new segment for reading.
-otError NcpFrameBuffer::OutFramePrepareSegment(void)
-{
-    otError  error = OT_ERROR_NONE;
-    uint16_t header;
-
-    while (true)
-    {
-        // Go to the next segment (set the segment head to current segment's end/tail).
-        mReadSegmentHead = mReadSegmentTail;
-
-        // Ensure there is something to read (i.e. segment head is not at start of frame being written).
-        VerifyOrExit(mReadSegmentHead != mWriteFrameStart[mReadDirection], error = OT_ERROR_NOT_FOUND);
-
-        // Read the segment header.
-        header = ReadUint16At(mReadSegmentHead, mReadDirection);
-
-        // Check if this segment is the start of a frame.
-        if (header & kSegmentHeaderNewFrameFlag)
-        {
-            // Ensure that this segment is start of current frame, otherwise the current frame is finished.
-            VerifyOrExit(mReadSegmentHead == mReadFrameStart[mReadDirection], error = OT_ERROR_NOT_FOUND);
-        }
-
-        // Find tail/end of current segment.
-        mReadSegmentTail = GetUpdatedBufPtr(mReadSegmentHead, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask),
-                                            mReadDirection);
-
-        // Update the current read pointer to skip the segment header.
-        mReadPointer = GetUpdatedBufPtr(mReadSegmentHead, kSegmentHeaderSize, mReadDirection);
-
-        // Check if there are data bytes to be read in this segment (i.e. read pointer not at the tail).
-        if (mReadPointer != mReadSegmentTail)
-        {
-            // Update the state to `InSegment` and return.
-            mReadState = kReadStateInSegment;
-
-            ExitNow();
-        }
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-        // No data in this segment,  prepare any appended/associated message of this segment.
-        if (OutFramePrepareMessage() == OT_ERROR_NONE)
-        {
-            ExitNow();
-        }
-
-        // If there is no message (`PrepareMessage()` returned an error), loop back to prepare the next segment.
-#endif
-    }
-
-exit:
-
-    if (error != OT_ERROR_NONE)
-    {
-        mReadState = kReadStateDone;
-    }
-
-    return error;
-}
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-// This method prepares an associated message in current segment and fills the message buffer. It returns
-// ThreadError_NotFound if there is no message or if the message has no content.
-otError NcpFrameBuffer::OutFramePrepareMessage(void)
-{
-    otError  error = OT_ERROR_NONE;
-    uint16_t header;
-
-    // Read the segment header
-    header = ReadUint16At(mReadSegmentHead, mReadDirection);
-
-    // Ensure that the segment header indicates that there is an associated message or return `NotFound` error.
-    VerifyOrExit((header & kSegmentHeaderMessageIndicatorFlag) != 0, error = OT_ERROR_NOT_FOUND);
-
-    // Update the current message from the queue.
-    mReadMessage = (mReadMessage == NULL) ? otMessageQueueGetHead(&mMessageQueue[mReadDirection])
-                                          : otMessageQueueGetNext(&mMessageQueue[mReadDirection], mReadMessage);
-
-    VerifyOrExit(mReadMessage != NULL, error = OT_ERROR_NOT_FOUND);
-
-    // Reset the offset for reading the message.
-    mReadMessageOffset = 0;
-
-    // Fill the content from current message into the message buffer.
-    SuccessOrExit(error = OutFrameFillMessageBuffer());
-
-    // If all successful, set the state to `InMessage`.
-    mReadState = kReadStateInMessage;
-
-exit:
-    return error;
-}
-
-// This method fills content from current message into the message buffer. It returns OT_ERROR_NOT_FOUND if no more
-// content in the current message.
-otError NcpFrameBuffer::OutFrameFillMessageBuffer(void)
-{
-    otError error = OT_ERROR_NONE;
-    int     readLength;
-
-    VerifyOrExit(mReadMessage != NULL, error = OT_ERROR_NOT_FOUND);
-
-    VerifyOrExit(mReadMessageOffset < otMessageGetLength(mReadMessage), error = OT_ERROR_NOT_FOUND);
-
-    // Read portion of current message from the offset into message buffer.
-    readLength = otMessageRead(mReadMessage, mReadMessageOffset, mMessageBuffer, sizeof(mMessageBuffer));
-
-    VerifyOrExit(readLength > 0, error = OT_ERROR_NOT_FOUND);
-
-    // Update the message offset, set up the message tail, and set read pointer to start of message buffer.
-
-    mReadMessageOffset += readLength;
-
-    mReadMessageTail = mMessageBuffer + readLength;
-
-    mReadPointer = mMessageBuffer;
-
-exit:
-    return error;
-}
-#endif // #if OPENTHREAD_MTD || OPENTHREAD_FTD
-
-otError NcpFrameBuffer::OutFrameBegin(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(!IsEmpty(), error = OT_ERROR_NOT_FOUND);
-
-    OutFrameSelectReadDirection();
-
-    // Move the segment head and tail to start of frame.
-    mReadSegmentHead = mReadSegmentTail = mReadFrameStart[mReadDirection];
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    mReadMessage = NULL;
-#endif
-
-    // Prepare the current segment for reading.
-    error = OutFramePrepareSegment();
-
-exit:
-    return error;
-}
-
-bool NcpFrameBuffer::OutFrameHasEnded(void)
-{
-    return (mReadState == kReadStateDone) || (mReadState == kReadStateNotActive);
-}
-
-uint8_t NcpFrameBuffer::OutFrameReadByte(void)
-{
-    otError error;
-    uint8_t retval = kReadByteAfterFrameHasEnded;
-
-    switch (mReadState)
-    {
-    case kReadStateNotActive:
-
-        // Fall through
-
-    case kReadStateDone:
-
-        retval = kReadByteAfterFrameHasEnded;
-
-        break;
-
-    case kReadStateInSegment:
-
-        // Read a byte from current read pointer and move the read pointer by 1 byte in the read direction.
-        retval       = *mReadPointer;
-        mReadPointer = GetUpdatedBufPtr(mReadPointer, 1, mReadDirection);
-
-        // Check if at end of current segment.
-        if (mReadPointer == mReadSegmentTail)
-        {
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-            // Prepare any message associated with this segment.
-            error = OutFramePrepareMessage();
-#else
-            error = OT_ERROR_NOT_FOUND;
-#endif
-
-            // If there is no message, move to next segment (if any).
-            if (error != OT_ERROR_NONE)
-            {
-                OutFramePrepareSegment();
-            }
-        }
-
-        break;
-
-    case kReadStateInMessage:
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-        // Read a byte from current read pointer and move the read pointer by 1 byte.
-        retval = *mReadPointer;
-        mReadPointer++;
-
-        // Check if at the end of content in message buffer.
-        if (mReadPointer == mReadMessageTail)
-        {
-            // Fill more bytes from current message into message buffer.
-            error = OutFrameFillMessageBuffer();
-
-            // If no more bytes in the message, move to next segment (if any).
-            if (error != OT_ERROR_NONE)
-            {
-                OutFramePrepareSegment();
-            }
-        }
-#endif
-        break;
-    }
-
-    return retval;
-}
-
-uint16_t NcpFrameBuffer::OutFrameRead(uint16_t aReadLength, uint8_t *aDataBuffer)
-{
-    uint16_t bytesRead = 0;
-
-    for (bytesRead = 0; (bytesRead < aReadLength) && !OutFrameHasEnded(); bytesRead++)
-    {
-        *aDataBuffer++ = OutFrameReadByte();
-    }
-
-    return bytesRead;
-}
-
-otError NcpFrameBuffer::OutFrameRemove(void)
-{
-    otError  error = OT_ERROR_NONE;
-    uint8_t *bufPtr;
-    uint16_t header;
-    uint8_t  numSegments;
-    FrameTag tag;
-
-    VerifyOrExit(!IsEmpty(), error = OT_ERROR_NOT_FOUND);
-
-    OutFrameSelectReadDirection();
-
-    // Save the frame start pointer as the tag associated with the frame being removed.
-    tag = mReadFrameStart[mReadDirection];
-
-    // Begin at the start of current frame and move through all segments.
-
-    bufPtr      = mReadFrameStart[mReadDirection];
-    numSegments = 0;
-
-    while (bufPtr != mWriteFrameStart[mReadDirection])
-    {
-        // Read the segment header
-        header = ReadUint16At(bufPtr, mReadDirection);
-
-        // If the current segment defines a new frame, and it is not the start of current frame, then we have reached
-        // end of current frame.
-        if (header & kSegmentHeaderNewFrameFlag)
-        {
-            if (bufPtr != mReadFrameStart[mReadDirection])
-            {
-                break;
-            }
-        }
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-        // If current segment has an appended message, remove it from message queue and free it.
-        if (header & kSegmentHeaderMessageIndicatorFlag)
-        {
-            otMessage *message;
-
-            if ((message = otMessageQueueGetHead(&mMessageQueue[mReadDirection])) != NULL)
-            {
-                otMessageQueueDequeue(&mMessageQueue[mReadDirection], message);
-                otMessageFree(message);
-            }
-        }
-#endif
-
-        // Move the pointer to next segment.
-        bufPtr = GetUpdatedBufPtr(bufPtr, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask), mReadDirection);
-
-        numSegments++;
-
-        // If this assert fails, it is a likely indicator that the internal structure of the NCP buffer has been
-        // corrupted.
-        assert(numSegments <= kMaxSegments);
-    }
-
-    mReadFrameStart[mReadDirection] = bufPtr;
-
-    UpdateReadWriteStartPointers();
-
-    mReadState       = kReadStateNotActive;
-    mReadFrameLength = kUnknownFrameLength;
-
-    if (mFrameRemovedCallback != NULL)
-    {
-        mFrameRemovedCallback(mFrameRemovedContext, tag, static_cast<Priority>(mReadDirection), this);
-    }
-
-exit:
-    return error;
-}
-
-void NcpFrameBuffer::UpdateReadWriteStartPointers(void)
-{
-    // If there is no fully written high priority frame, and not in middle of writing a new frame either.
-    if (!HasFrame(kPriorityHigh) && !InFrameIsWriting(kPriorityHigh))
-    {
-        // Move the high priority pointers to be right behind the low priority start.
-        mWriteFrameStart[kPriorityHigh] = GetUpdatedBufPtr(mReadFrameStart[kPriorityLow], 1, kBackward);
-        mReadFrameStart[kPriorityHigh]  = mWriteFrameStart[kPriorityHigh];
-        ExitNow();
-    }
-
-    // If there is no fully written low priority frame, and not in middle of writing a new frame either.
-    if (!HasFrame(kPriorityLow) && !InFrameIsWriting(kPriorityLow))
-    {
-        // Move the low priority pointers to be 1 byte after the high priority start.
-        mWriteFrameStart[kPriorityLow] = GetUpdatedBufPtr(mReadFrameStart[kPriorityHigh], 1, kForward);
-        mReadFrameStart[kPriorityLow]  = mWriteFrameStart[kPriorityLow];
-    }
-
-exit:
-    return;
-}
-
-uint16_t NcpFrameBuffer::OutFrameGetLength(void)
-{
-    uint16_t frameLength = 0;
-    uint16_t header;
-    uint8_t *bufPtr;
-    uint8_t  numSegments;
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    otMessage *message = NULL;
-#endif
-
-    // If the frame length was calculated before, return the previously calculated length.
-    VerifyOrExit(mReadFrameLength == kUnknownFrameLength, frameLength = mReadFrameLength);
-
-    VerifyOrExit(!IsEmpty(), frameLength = 0);
-
-    OutFrameSelectReadDirection();
-
-    // Calculate frame length by adding length of all segments and messages within the current frame.
-
-    bufPtr      = mReadFrameStart[mReadDirection];
-    numSegments = 0;
-
-    while (bufPtr != mWriteFrameStart[mReadDirection])
-    {
-        // Read the segment header
-        header = ReadUint16At(bufPtr, mReadDirection);
-
-        // If the current segment defines a new frame, and it is not the start of current frame, then we have reached
-        // end of current frame.
-        if (header & kSegmentHeaderNewFrameFlag)
-        {
-            if (bufPtr != mReadFrameStart[mReadDirection])
-            {
-                break;
-            }
-        }
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-        // If current segment has an associated message, add its length to frame length.
-        if (header & kSegmentHeaderMessageIndicatorFlag)
-        {
-            message = (message == NULL) ? otMessageQueueGetHead(&mMessageQueue[mReadDirection])
-                                        : otMessageQueueGetNext(&mMessageQueue[mReadDirection], message);
-
-            if (message != NULL)
-            {
-                frameLength += otMessageGetLength(message);
-            }
-        }
-#endif
-
-        // Add the length of current segment to the frame length.
-        frameLength += (header & kSegmentHeaderLengthMask);
-
-        // Move the pointer to next segment.
-        bufPtr = GetUpdatedBufPtr(bufPtr, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask), mReadDirection);
-
-        numSegments++;
-
-        // If this assert fails, it is a likely indicator that the internal structure of the NCP buffer has been
-        // corrupted.
-        assert(numSegments <= kMaxSegments);
-    }
-
-    // Remember the calculated frame length for current active frame.
-    if (mReadState != kReadStateNotActive)
-    {
-        mReadFrameLength = frameLength;
-    }
-
-exit:
-    return frameLength;
-}
-
-NcpFrameBuffer::FrameTag NcpFrameBuffer::OutFrameGetTag(void)
-{
-    OutFrameSelectReadDirection();
-
-    // If buffer is empty use `kInvalidTag`, otherwise use the frame start pointer as the tag associated with
-    // current out frame being read
-
-    return IsEmpty() ? kInvalidTag : mReadFrameStart[mReadDirection];
-}
-
-} // namespace Ncp
-} // namespace ot
diff --git a/src/ncp/ncp_buffer.hpp b/src/ncp/ncp_buffer.hpp
deleted file mode 100644
index 8b63fdf..0000000
--- a/src/ncp/ncp_buffer.hpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- *    Copyright (c) 2016, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file contains definitions for the NCP frame buffer class.
- */
-
-#ifndef NCP_FRAME_BUFFER_HPP_
-#define NCP_FRAME_BUFFER_HPP_
-
-#include "openthread-core-config.h"
-
-#include <openthread/message.h>
-
-namespace ot {
-namespace Ncp {
-
-/**
- * This class implements a buffer/queue for storing NCP frames.
- *
- * A frame can consist of a sequence of data bytes and/or the content of an `otMessage` or a combination of the two.
- * `NcpFrameBuffer` implements priority FIFO logic for storing and reading frames. Two priority levels of high and low
- * are supported. Within same priority level first-in-first-out order is preserved. High priority frames are read
- * ahead of any low priority ones.
- *
- */
-class NcpFrameBuffer
-{
-    friend class SpinelEncoder;
-
-public:
-    /**
-     * Defines the priority of a frame. High priority frames are read before low priority frames. Within same priority
-     * level FIFO order is preserved.
-     *
-     */
-    enum Priority
-    {
-        kPriorityLow  = 0, //< Indicates low/normal priority for a frame.
-        kPriorityHigh = 1, //< Indicates high priority for a frame.
-    };
-
-    /**
-     * Defines the (abstract) frame tag type. The tag is a unique value (within currently queued frames) associated
-     * with a frame in the `NcpFrameBuffer`. Frame tags can be compared with one another using operator `==`.
-     *
-     */
-    typedef const void *FrameTag;
-
-    /**
-     * Defines the tag value indicating an invalid tag (e.g., when there is no frame).
-     *
-     */
-    static const FrameTag kInvalidTag;
-
-    /**
-     * Defines the structure to hold a write position for an input frame (frame being written).
-     *
-     * It should be considered as an opaque data structure to users of `NcpFrameBuffer`.
-     *
-     */
-    struct WritePosition
-    {
-    public:
-        /**
-         * The constructor for a `WritePosition` object.
-         *
-         */
-        WritePosition(void)
-            : mPosition(0)
-            , mSegmentHead(0)
-        {
-        }
-
-    private:
-        uint8_t *mPosition;    //< Pointer into buffer corresponding to saved write position.
-        uint8_t *mSegmentHead; //< Pointer to segment head.
-
-        friend class NcpFrameBuffer;
-    };
-
-    /**
-     * Defines a function pointer callback which is invoked to inform a change in `NcpFrameBuffer` either when a new
-     * frame is added/written to `NcpFrameBuffer` or when a frame is removed from `NcpFrameBuffer`.
-     *
-     * @param[in] aContext              A pointer to arbitrary context information.
-     * @param[in] aTag                  The tag associated with the frame which is added or removed.
-     * @param[in] aPriority             The priority of frame.
-     * @param[in] aNcpFrameBuffer       A pointer to the `NcpFrameBuffer`.
-     *
-     */
-    typedef void (*BufferCallback)(void *aContext, FrameTag aTag, Priority aPriority, NcpFrameBuffer *aNcpFrameBuffer);
-
-    /**
-     * This constructor initializes an NCP frame buffer.
-     *
-     * @param[in] aBuffer               A pointer to a buffer which will be used by NCP frame buffer.
-     * @param[in] aBufferLength         The buffer size (in bytes).
-     *
-     */
-    NcpFrameBuffer(uint8_t *aBuffer, uint16_t aBufferLength);
-
-    /**
-     * This method clears the NCP frame buffer. All the frames are cleared/removed.
-     *
-     */
-    void Clear(void);
-
-    /**
-     * This method sets the FrameAdded callback and its context.
-     *
-     * Subsequent calls to this method will overwrite the previous callback and its context.
-     *
-     * @param[in] aFrameAddedCallback   Callback invoked when a new frame is successfully added to buffer.
-     * @param[in] aFrameAddedContext    A pointer to arbitrary context used with frame added callback.
-     *
-     */
-    void SetFrameAddedCallback(BufferCallback aFrameAddedCallback, void *aFrameAddedContext);
-
-    /**
-     * This method sets the FrameRemoved callback and its context.
-     *
-     * Subsequent calls to this method will overwrite the previous callback and its context.
-     *
-     * @param[in] aFrameRemovedCallback Callback invoked when a frame is removed from buffer.
-     * @param[in] aFrameRemovedContext  A pointer to arbitrary context used with frame removed callback.
-     *
-     */
-    void SetFrameRemovedCallback(BufferCallback aFrameRemovedCallback, void *aFrameRemovedContext);
-
-    /**
-     * This method begins a new input frame (InFrame) to be added/written to the frame buffer.
-
-     * If there is a previous frame being written (for which `InFrameEnd()` has not yet been called), calling
-     * `InFrameBegin()` will discard and clear the previous unfinished frame.
-     *
-     * @param[in] aPriority             Priority level of the new input frame.
-     *
-     */
-    void InFrameBegin(Priority aPriority);
-
-    /**
-     * This method adds a single byte to current input frame.
-     *
-     * Before using this method `InFrameBegin()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aByte                The byte value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given byte to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
-     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
-     *
-     */
-    otError InFrameFeedByte(uint8_t aByte);
-
-    /**
-     * This method adds data to the current input frame.
-     *
-     * Before using this method `InFrameBegin()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aDataBuffer          A pointer to data buffer.
-     * @param[in]  aDataBufferLength    The length of the data buffer.
-     *
-     * @retval OT_ERROR_NONE            Successfully added new data to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add data.
-     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
-     *
-     */
-    otError InFrameFeedData(const uint8_t *aDataBuffer, uint16_t aDataBufferLength);
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    /**
-     * This method adds a message to the current input frame.
-     *
-     * Before using this method `InFrameBegin()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the frame and return error status
-     * `OT_ERROR_NO_BUFS`.
-     *
-     * The ownership of the passed-in message @p aMessage changes to `NcpFrameBuffer` ONLY when the entire frame is
-     * successfully finished (i.e., with a successful call to `InFrameEnd()` for the current input frame), and in this
-     * case the `otMessage` instance will be freed once the frame is removed (using `OutFrameRemove()`) from NCP buffer.
-     * However, if the input frame gets discarded before it is finished (e.g., running out of buffer space), the
-     * `otMessage` instance remains unchanged.
-     *
-     * @param[in] aMessage              A message to be added to current frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added the message to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the message.
-     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
-     * @retval OT_ERROR_INVALID_ARGS    If @p aMessage is NULL.
-     *
-     */
-    otError InFrameFeedMessage(otMessage *aMessage);
-#endif
-
-    /**
-     * This method gets the current write position in the input frame.
-     *
-     * The write position is returned in @p aPosition. The saved position can later be used to overwrite the frame
-     * content (using `InFrameOverwrite()`) or discard a portion of written frame and move the write pointer back to
-     * the saved position (using `InFrameReset()`).
-     *
-     * @param[out] aPosition            A reference to a `WritePosition` to save the current write position.
-     *
-     * @retval OT_ERROR_NONE            Successfully saved current write position in @p aPosition.
-     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
-     *
-     */
-    otError InFrameGetPosition(WritePosition &aPosition);
-
-    /**
-     * This method overwrites the previously written content in the current input frame at a given write position.
-     *
-     * The write position @p aPostion must belong to the same input frame saved earlier with `InFrameGetPosition()`.
-     * This method does not allow writing beyond the current end of the input frame (i.e., it can only write over
-     * previously added content). If writing @p aDataBufferLength bytes from write position @p aPosition goes beyond
-     * the end, this method does not change the input frame and returns error status `OT_ERROR_INVALID_ARGS`.
-     * This method cannot be used if the input frame has an added `otMessage` (i.e., a previous call to
-     * `InFrameFeedMessage()`).
-     *
-     * @param[in] aPosition             A reference to the write position.
-     * @param[in] aDataBuffer           A pointer to data buffer.
-     * @param[in] aDataBufferLength     The length of the data buffer.
-     *
-     * @retval OT_ERROR_NONE            Successfully overwrote the data at the given write position.
-     * @retval OT_ERROR_INVALID_STATE   No input frame (`InFrameBegin()` has not been called).
-     * @retval OT_ERROR_INVALID_ARGS    The given write position is not valid (i.e., if it does not belong to same
-     *                                  input frame), or the input frame has an added `otMessage`, or the write
-     *                                  operation will go beyond the current end of the input frame.
-     *
-     */
-    otError InFrameOverwrite(const WritePosition &aPosition, const uint8_t *aDataBuffer, uint16_t aDataBufferLength);
-
-    /**
-     * This method resets the write position of input frame back to a previously saved position. Any previously
-     * added content after the write position is discarded.
-     *
-     * The write position @p aPosition must belong to the same input frame saved earlier with `InFrameGetPosition()`.
-     * This method cannot be used if the input frame has an added `otMessage` (i.e., a previous call to
-     * `InFrameFeedMessage()`).
-     *
-     * @param[in] aPosition             A reference to write position
-     *
-     * @retval OT_ERROR_NONE            Successfully reset the write position of current input frame..
-     * @retval OT_ERROR_INVALID_STATE   No input frame (`InFrameBegin()` has not been called).
-     * @retval OT_ERROR_INVALID_ARGS    The given write position is not valid (does not belong to same input frame), or
-     *                                  the input frame has an added `otMessage`.
-     *
-     */
-    otError InFrameReset(const WritePosition &aPosition);
-
-    /**
-     * This method gets the distance (number of bytes) from a given saved position to current end of frame.
-     *
-     * The write position @p aPosition must belong to the same input frame saved earlier with `InFrameGetPosition()`.
-     * This method cannot be used if the input frame has an added `otMessage` (i.e., a previous call to
-     * `InFrameFeedMessage()`). In case of invalid argument, this method returns zero.
-     *
-     * @param[in] aPosition             A reference to write position
-     *
-     * @returns The distance (number of bytes) from a write position to current end of frame, or zero for invalid
-     *          arguments.
-     *
-     */
-    uint16_t InFrameGetDistance(const WritePosition &aPosition) const;
-
-    /**
-     * This method finalizes/ends the current input frame being written to the buffer.
-     *
-     * Before using this method `InFrameBegin()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the frame and return error status
-     * `OT_ERROR_NO_BUFS`.
-     *
-     * @retval OT_ERROR_NONE            Successfully ended the input frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add message.
-     * @retval OT_ERROR_INVALID_STATE   `InFrameBegin()` has not been called earlier to start the frame.
-     *
-     */
-    otError InFrameEnd(void);
-
-    /**
-     * This method returns the tag assigned to last successfully written/added frame to NcpBuffer (i.e., last input
-     * frame for which `InFrameEnd()` was called and returned success status). The tag is a unique value (within
-     * currently queued frames) associated with a frame in the `NcpFrameBuffer`. The tag can be used to identify the
-     * same frame when it is read and removed from the NcpBuffer. Tags can be compared using operator `==`.
-     *
-     * @returns The tag of the last successfully written frame, or `kInvalidTag` if no frame is written so far.
-     */
-    FrameTag InFrameGetLastTag(void) const;
-
-    /**
-     * This method checks if the buffer is empty. A non-empty buffer contains at least one full frame for reading.
-     *
-     * @retval TRUE                     Buffer is not empty and contains at least one full frame for reading.
-     * @retval FALSE                    Buffer is empty and contains no frame for reading.
-     *
-     */
-    bool IsEmpty(void) const;
-
-    /**
-     * This method begins/prepares an output frame to be read from the frame buffer if there is no current active output
-     * frame, or resets the read offset if there is a current active output frame.
-     *
-     * The NCP buffer maintains a read offset for the current frame being read. Before reading any bytes from the frame
-     * this method should be called to prepare the frame and set the read offset.
-     *
-     * If part or even all of current frame has been read, a sub-sequent call to this method  will reset the read
-     * offset back to beginning of current output frame (note that the current output frame will remain unchanged even
-     * in case where a higher priority frame was written to buffer while reading current output frame). A prepared
-     * output frame will stay active as current output frame until it is explicitly removed using `OutFrameRemove()`.
-     *
-     * @retval OT_ERROR_NONE            Successfully started/prepared a new output frame for reading.
-     * @retval OT_ERROR_NOT_FOUND       No frame available in buffer for reading.
-     *
-     */
-    otError OutFrameBegin(void);
-
-    /**
-     * This method checks if the current output frame (being read) has ended.
-     *
-     * The NCP buffer maintains a read offset for the current output frame being read. This method returns `true` if
-     * the read offset has reached the end of the frame and there are no more bytes available to read, or if there is
-     * no currently active output frame.
-     *
-     * @retval TRUE                     Frame has ended (no more bytes available to read from current output frame), or
-     *                                  there is currently no prepared/active output frame.
-     * @retval FALSE                    Frame still has more data to read.
-     *
-     */
-    bool OutFrameHasEnded(void);
-
-    /**
-     * This method reads and returns the next byte from the current output frame.
-     *
-     * The NCP buffer maintains a read offset for the current output frame being read. This method reads and returns
-     * the next byte from the current frame and moves the read offset forward. If read offset is already at the end
-     * current output frame, this method returns zero.
-     *
-     * @returns The next byte from the current output frame or zero if current output frame has ended or there is
-     * prepared/active output from.
-     *
-     */
-    uint8_t OutFrameReadByte(void);
-
-    /**
-     * This method reads and copies bytes from the current output frame into a given buffer.
-     *
-     * The NCP buffer maintains a read offset for the current output frame being read. This method attempts to read
-     * the given number of bytes (@p aDataBufferLength) from the current frame and copies the bytes into the given
-     * data buffer (@p aDataBuffer). It also moves the read offset forward accordingly. If there are fewer bytes
-     * remaining in current frame than the requested @p aReadLength, the available bytes are read/copied. This methods
-     * returns the number of bytes read from frame and copied into @p aDataBuffer.
-     *
-     * @param[in]  aDataBuffer          A pointer to a data buffer.
-     * @param[in]  aReadLength          Number of bytes to read.
-     *
-     * @returns The number of bytes read and copied into data buffer.
-     *
-     */
-    uint16_t OutFrameRead(uint16_t aReadLength, uint8_t *aDataBuffer);
-
-    /**
-     * This method removes the current or front output frame from the buffer.
-     *
-     * If there is an active output from being read (an output frame was prepared earlier with a successful call to
-     * `OutFrameBegin()`), this method removes the current active output frame. If there is no current active frame,
-     * the front frame in the queue (the next frame which would have been read) will be removed.
-     *
-     * When a frame is removed all its associated messages will be freed.
-     *
-     * If the remove operation is successful, this method will invoke the `FrameRemovedCallback` (if not NULL) before
-     * returning the success state.
-     *
-     * @retval OT_ERROR_NONE            Successfully removed the front frame.
-     * @retval OT_ERROR_NOT_FOUND       No frame available in NCP frame buffer to remove.
-     *
-     */
-    otError OutFrameRemove(void);
-
-    /**
-     * This method returns the number of bytes (length) of current or front frame in the NCP frame buffer.
-     *
-     * If there is an active output from being read (an output frame was prepared earlier with successful call to
-     * `OutFrameBegin()`), this method returns the length of the current output frame. If there is no current active
-     * frame, the length of the front frame in the queue (the next frame which would have been read) will be returned.
-     *
-     * If there is no frame in buffer, this method returns zero.
-     *
-     * @returns The number of bytes (length) of current/front frame, or zero if no frame in buffer.
-     *
-     */
-    uint16_t OutFrameGetLength(void);
-
-    /**
-     * This method returns the tag value associated to current or front frame in the NCP frame buffer.
-     *
-     * If there is an active output from being read (an output frame was prepared earlier with successful call to
-     * `OutFrameBegin()`), this method returns the tag associated with current output frame. If there is no current
-     * active frame, the tag associated with the front frame in the queue (the next frame which would have been read)
-     * will be returned.
-     *
-     * If there is no frame in buffer, this method returns `kInvalidTag`.
-     *
-     * @returns The tag assigned to the current/from output frame, or `kInvalidTag` if no frame in buffer.
-     *
-     */
-    FrameTag OutFrameGetTag(void);
-
-private:
-    /*
-     * `NcpFrameBuffer` Implementation
-     * -------------------------------
-     *
-     * `NcpFrameBuffer` internally stores a frame as a sequence of data segments. Each segment stores a portion of
-     * frame. The data segments are stored in the main buffer `mBuffer`. `mBuffer` is utilized as a circular buffer.
-
-     * The content of messages (which are added using `InFrameFeedMessage()`) are not directly copied in the `mBuffer`
-     * but instead they are enqueued in a message queue `mMessageQueue`.
-     *
-     * Every data segments starts with a header before the data portion. The header is 2 bytes long with the following
-     * format:
-     *
-     *    Bit 0-13: Give the length of the data segment (max segment len is 2^14 = 16,384 bytes).
-     *    Bit 14:   Flag bit set to indicate that this segment has an associated `Message` (appended to its end).
-     *    Bit 15:   Flag bit set to indicate that this segment defines the start of a new frame.
-     *
-     *        Bit  15         Bit 14                     Bits: 0 - 13
-     *    +--------------+--------------+--------------------------------------------------------+
-     *    |   New Frame  |  Has Message |  Length of segment (excluding the header)              |
-     *    +--------------+--------------+--------------------------------------------------------+
-     *
-     * The header is encoded in big-endian (msb first) style.
-
-     * Consider the following calls to create a frame:
-     *
-     *    ncpBuffer.InFrameBegin();
-     *    ncpBuffer.InFrameFeedData("Hello", 5);
-     *    ncpBuffer.InFrameFeedData("There", 5);
-     *    ncpBuffer.InFrameFeedMessage(*someMessage);
-     *    ncpBuffer.InFrameFeedData("Bye", 3);
-     *    ncpBuffer.InFrameEnd();
-     *
-     * This frame is stored as two segments:
-     *
-     *    - Segment #1 contains "HelloThere" with a header value `0xC00A` which shows that this segment contains 10
-     *      data bytes, and it starts a new frame, and also includes an appended message from the message queue.
-     *
-     *    - Segment #2 contains "Bye" with a header value of `0x0003` showing length of 3 and no appended message.
-     *
-     *    +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
-     *    | C0  | 0A  | 'H' | 'e' | 'l' | 'l' | 'o' | 'T' | 'h' | 'e' | 'r' | 'e' | 00  | 03  | 'B' | 'y' | 'e' |
-     *    +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
-     *     \         /                                                             \         /
-     *   Segment #1 Header                                                      Segment #2 Header
-     *
-     *
-     * `NcpFrameBuffer` uses the `mBuffer` as a circular/ring buffer. To support two frame priorities the buffer is
-     * divided into two high-priority and low-priority regions. The high priority frames are stored in buffer in
-     * backward direction while the low-priority frames use the buffer in forward direction. This model ensures the
-     * available buffer space is utilized efficiently between all frame types.
-     *
-     *                                       mReadFrameStart[kPriorityLow]
-     *                                                 |
-     *                                                 |                   mWriteFrameStart[kPriorityLow]
-     *                                                 |                              |
-     *                                                 V    Low Priority Frames       V
-     *   --------------+------------------------------+------------------------------+------------------
-     *             ... |        <--------             |         -------->            | ...
-     *   --------------+------------------------------+------------------------------+------------------
-     *                ^       High Priority Frames   ^
-     *                |                              |
-     *                |                    mReadFrameStart[kPriorityHigh]
-     *                |
-     *          mWriteFrameStart[kPriorityHigh]
-     *
-     *
-     *
-     * When frames are removed, if possible, the `mReadFrameStart` and `mWriteFrameStart` pointers of the two priority
-     * levels are moved closer to avoid gaps.
-     *
-     * For an output frame (frame being read), NcpFrameBuffer maintains a `ReadState` along with a set of pointers
-     * into the buffer:
-     *
-     *             mReadFrameStart[priority]: Start of the current/front frame.
-     *             |
-     *             |            mReadSegmentHead: Start of the current segment.
-     *             |            |
-     *             |            |              mReadPointer: Pointer to the next byte to read.
-     *             |            |              |
-     *             |            |              |           mReadSegmentTail: End of the current segment.
-     *             |            |              |           |
-     *             V            V              V           V
-     *   ---------+------------+--------------------------+------+----------------+-----------------------------------
-     *       ...  | Segment 1  | Segment  2               | ...  | Last Segment   | ... (possible) next frame
-     *   ---------+------------+--------------------------+------+----------------+-----------------------------------
-     *             \           |                         |                       /
-     *              |          \------------v-----------/                       |
-     *              |                   Current Segment                         |
-     *              |                                                           |
-     *               \---------------------------V-----------------------------/
-     *                              Current OutFrame (being read)
-     *
-     * Note that the diagram above shows the pointers for a low-priority frame (with pointers increasing in forward
-     * direction).
-     *
-     * The `ReadState` indicates the state of current output frame and its read offset (e.g., if read offset is in
-     * middle of a segment or if it is is middle of an appended message, or if we are done with entire frame).
-     *
-     * For an input frame (frame being written), the following pointers are maintained:
-     *
-     *            mWriteFrameWrite[priority]: Start of the current/next frame being written.
-     *                       |
-     *                       |      mWriteSegmentHead: Start of the current segment of the active input frame.
-     *                       |                 |
-     *                       |                 |   mWriteSegmentTail: Pointer to the next byte to write.
-     *                       |                 |                       |
-     *                       |                 |                       |
-     *                       |                 |                       |
-     *                       V                 V                       V
-     *    ------------------+------------------+-------------------------------------------------------------------
-     *    Previous Frames   | Segment 1        | Segment  2            : . . .
-     *    ------------------+------------------+-------------------------------------------------------------------
-     *                       \                                        /
-     *                        |                                      |
-     *                         \------------------V-----------------/
-     *                             Current InFrame (being written)
-     *
-     *
-     */
-
-    enum
-    {
-        kReadByteAfterFrameHasEnded = 0,      // Value returned by ReadByte() when frame has ended.
-        kMessageReadBufferSize      = 16,     // Size of message buffer array `mMessageBuffer`.
-        kUnknownFrameLength         = 0xffff, // Value used when frame length is unknown.
-        kSegmentHeaderSize          = 2,      // Length of the segment header.
-        kSegmentHeaderLengthMask    = 0x3fff, // Bit mask to get the length from the segment header
-        kMaxSegments                = 10,     // Max number of segments allowed in a frame
-
-        kSegmentHeaderNoFlag               = 0,         // No flags are set.
-        kSegmentHeaderNewFrameFlag         = (1 << 15), // Indicates that this segment starts a new frame.
-        kSegmentHeaderMessageIndicatorFlag = (1 << 14), // Indicates this segment ends with a Message.
-
-        kNumPrios = (kPriorityHigh + 1), // Number of priorities.
-    };
-
-    enum ReadState
-    {
-        kReadStateNotActive, // No current prepared output frame.
-        kReadStateInSegment, // In middle of a data segment while reading current frame.
-        kReadStateInMessage, // In middle of a message while reading current frame.
-        kReadStateDone,      // Current output frame is read fully.
-    };
-
-    enum Direction
-    {
-        kForward  = kPriorityLow,
-        kBackward = kPriorityHigh,
-        kUnknown,
-    };
-
-    uint8_t *GetUpdatedBufPtr(uint8_t *aBufPtr, uint16_t aOffset, Direction aDirection) const;
-    uint16_t GetDistance(const uint8_t *aStartPtr, const uint8_t *aEndPtr, Direction aDirection) const;
-
-    uint16_t ReadUint16At(uint8_t *aBufPtr, Direction aDirection);
-    void     WriteUint16At(uint8_t *aBufPtr, uint16_t aValue, Direction aDirection);
-
-    bool HasFrame(Priority aPriority) const;
-    void UpdateReadWriteStartPointers(void);
-
-    otError InFrameAppend(uint8_t aByte);
-    otError InFrameBeginSegment(void);
-    void    InFrameEndSegment(uint16_t aSegmentHeaderFlags);
-    void    InFrameDiscard(void);
-    bool    InFrameIsWriting(Priority aPriority) const;
-
-    void    OutFrameSelectReadDirection(void);
-    otError OutFramePrepareSegment(void);
-    void    OutFrameMoveToNextSegment(void);
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    otError OutFramePrepareMessage(void);
-    otError OutFrameFillMessageBuffer(void);
-#endif
-
-    uint8_t *const mBuffer;       // Pointer to the buffer used to store the data.
-    uint8_t *const mBufferEnd;    // Points to after the end of buffer.
-    const uint16_t mBufferLength; // Length of the buffer.
-
-    BufferCallback mFrameAddedCallback;   // Callback to signal when a new frame is added
-    void *         mFrameAddedContext;    // Context passed to `mFrameAddedCallback`.
-    BufferCallback mFrameRemovedCallback; // Callback to signal when a frame is removed.
-    void *         mFrameRemovedContext;  // Context passed to `mFrameRemovedCallback`.
-
-    Direction mWriteDirection;             // Direction (priority) for current frame being read.
-    uint8_t * mWriteFrameStart[kNumPrios]; // Pointer to start of current frame being written.
-    uint8_t * mWriteSegmentHead;           // Pointer to start of current segment in the frame being written.
-    uint8_t * mWriteSegmentTail;           // Pointer to end of current segment in the frame being written.
-    FrameTag  mWriteFrameTag;              // Tag associated with last successfully written frame.
-
-    Direction mReadDirection;   // Direction (priority) for current frame being read.
-    ReadState mReadState;       // Read state.
-    uint16_t  mReadFrameLength; // Length of current frame being read.
-
-    uint8_t *mReadFrameStart[kNumPrios]; // Pointer to start of current frame being read.
-    uint8_t *mReadSegmentHead;           // Pointer to start of current segment in the frame being read.
-    uint8_t *mReadSegmentTail;           // Pointer to end of current segment in the frame being read.
-    uint8_t *mReadPointer;               // Pointer to next byte to read (either in segment or in msg buffer).
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    otMessageQueue mWriteFrameMessageQueue;                // Message queue for the current frame being written.
-    otMessageQueue mMessageQueue[kNumPrios];               // Main message queues.
-    otMessage *    mReadMessage;                           // Current Message in the frame being read.
-    uint16_t       mReadMessageOffset;                     // Offset within current message being read.
-    uint8_t        mMessageBuffer[kMessageReadBufferSize]; // Buffer to hold part of current message being read.
-    uint8_t *      mReadMessageTail;                       // Pointer to end of current part in mMessageBuffer.
-#endif
-};
-
-} // namespace Ncp
-} // namespace ot
-
-#endif // NCP_FRAME_BUFFER_HPP_
diff --git a/src/ncp/ncp_spi.cpp b/src/ncp/ncp_spi.cpp
index d3b7829..f4dc788 100644
--- a/src/ncp/ncp_spi.cpp
+++ b/src/ncp/ncp_spi.cpp
@@ -35,6 +35,7 @@
 #include <openthread/ncp.h>
 #include <openthread/platform/misc.h>
 #include <openthread/platform/spi-slave.h>
+#include <openthread/platform/toolchain.h>
 
 #include "openthread-core-config.h"
 #include "common/code_utils.hpp"
@@ -42,17 +43,16 @@
 #include "common/instance.hpp"
 #include "common/new.hpp"
 #include "net/ip6.hpp"
-#include "utils/static_assert.hpp"
 
 #if OPENTHREAD_CONFIG_NCP_SPI_ENABLE
 
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
-OT_STATIC_ASSERT(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <=
-                     OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE - ot::Ncp::NcpBase::kSpinelCmdHeaderSize -
-                         ot::Ncp::NcpBase::kSpinelPropIdSize - ot::Ncp::SpiFrame::kHeaderSize,
-                 "diag output should be smaller than NCP SPI tx buffer");
-OT_STATIC_ASSERT(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE,
-                 "diag command line should be smaller than NCP SPI rx buffer");
+static_assert(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <=
+                  OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE - ot::Ncp::NcpBase::kSpinelCmdHeaderSize -
+                      ot::Ncp::NcpBase::kSpinelPropIdSize - ot::Ncp::SpiFrame::kHeaderSize,
+              "diag output should be smaller than NCP SPI tx buffer");
+static_assert(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE,
+              "diag command line should be smaller than NCP SPI rx buffer");
 #endif
 
 namespace ot {
@@ -64,14 +64,14 @@
 
 extern "C" void otNcpInit(otInstance *aInstance)
 {
-    NcpSpi *  ncpSpi   = NULL;
+    NcpSpi *  ncpSpi   = nullptr;
     Instance *instance = static_cast<Instance *>(aInstance);
 
     ncpSpi = new (&sNcpRaw) NcpSpi(instance);
 
-    if (ncpSpi == NULL || ncpSpi != NcpBase::GetNcpInstance())
+    if (ncpSpi == nullptr || ncpSpi != NcpBase::GetNcpInstance())
     {
-        assert(false);
+        OT_ASSERT(false);
     }
 }
 
@@ -82,7 +82,7 @@
     , mTxState(kTxStateIdle)
     , mHandlingRxFrame(false)
     , mResetFlag(true)
-    , mPrepareTxFrameTask(*aInstance, &NcpSpi::PrepareTxFrame, this)
+    , mPrepareTxFrameTask(*aInstance, NcpSpi::PrepareTxFrame, this)
     , mSendFrameLength(0)
 {
     SpiFrame sendFrame(mSendFrame);
@@ -103,14 +103,15 @@
 
     mTxFrameBuffer.SetFrameAddedCallback(HandleFrameAddedToTxBuffer, this);
 
-    otPlatSpiSlaveEnable(&NcpSpi::SpiTransactionComplete, &NcpSpi::SpiTransactionProcess, this);
+    IgnoreError(otPlatSpiSlaveEnable(&NcpSpi::SpiTransactionComplete, &NcpSpi::SpiTransactionProcess, this));
 
     // We signal an interrupt on this first transaction to
     // make sure that the host processor knows that our
     // reset flag was set.
 
-    otPlatSpiSlavePrepareTransaction(mEmptySendFrameZeroAccept, kSpiHeaderSize, mEmptyReceiveFrame, kSpiHeaderSize,
-                                     /* aRequestTras */ true);
+    IgnoreError(otPlatSpiSlavePrepareTransaction(mEmptySendFrameZeroAccept, kSpiHeaderSize, mEmptyReceiveFrame,
+                                                 kSpiHeaderSize,
+                                                 /* aRequestTransactionFlag */ true));
 }
 
 bool NcpSpi::SpiTransactionComplete(void *   aContext,
@@ -144,8 +145,9 @@
     SpiFrame inputFrame(aInputBuf);
     SpiFrame sendFrame(mSendFrame);
 
-    VerifyOrExit((aTransLen >= kSpiHeaderSize) && (aInputLen >= kSpiHeaderSize) && (aOutputLen >= kSpiHeaderSize));
-    VerifyOrExit(inputFrame.IsValid() && outputFrame.IsValid());
+    VerifyOrExit((aTransLen >= kSpiHeaderSize) && (aInputLen >= kSpiHeaderSize) && (aOutputLen >= kSpiHeaderSize),
+                 OT_NOOP);
+    VerifyOrExit(inputFrame.IsValid() && outputFrame.IsValid(), OT_NOOP);
 
     transDataLen = aTransLen - kSpiHeaderSize;
 
@@ -217,7 +219,8 @@
 
     sendFrame.SetHeaderAcceptLen(aInputLen - kSpiHeaderSize);
 
-    otPlatSpiSlavePrepareTransaction(aOutputBuf, aOutputLen, aInputBuf, aInputLen, (mTxState == kTxStateSending));
+    IgnoreError(
+        otPlatSpiSlavePrepareTransaction(aOutputBuf, aOutputLen, aInputBuf, aInputLen, (mTxState == kTxStateSending)));
 
     return shouldProcess;
 }
@@ -241,11 +244,11 @@
 }
 
 void NcpSpi::HandleFrameAddedToTxBuffer(void *                   aContext,
-                                        NcpFrameBuffer::FrameTag aTag,
-                                        NcpFrameBuffer::Priority aPriority,
-                                        NcpFrameBuffer *         aNcpFrameBuffer)
+                                        Spinel::Buffer::FrameTag aTag,
+                                        Spinel::Buffer::Priority aPriority,
+                                        Spinel::Buffer *         aBuffer)
 {
-    OT_UNUSED_VARIABLE(aNcpFrameBuffer);
+    OT_UNUSED_VARIABLE(aBuffer);
     OT_UNUSED_VARIABLE(aTag);
     OT_UNUSED_VARIABLE(aPriority);
 
@@ -259,7 +262,7 @@
     uint16_t readLength;
     SpiFrame sendFrame(mSendFrame);
 
-    VerifyOrExit(!mTxFrameBuffer.IsEmpty());
+    VerifyOrExit(!mTxFrameBuffer.IsEmpty(), OT_NOOP);
 
     if (ShouldWakeHost())
     {
@@ -269,14 +272,17 @@
     SuccessOrExit(error = mTxFrameBuffer.OutFrameBegin());
 
     frameLength = mTxFrameBuffer.OutFrameGetLength();
-    assert(frameLength <= kSpiBufferSize - kSpiHeaderSize);
+    OT_ASSERT(frameLength <= kSpiBufferSize - kSpiHeaderSize);
 
     // The "accept length" in `mSendFrame` is already updated based
     // on current state of receive. It is changed either from the
     // `SpiTransactionComplete()` callback or from `HandleRxFrame()`.
 
     readLength = mTxFrameBuffer.OutFrameRead(frameLength, sendFrame.GetData());
-    assert(readLength == frameLength);
+    OT_ASSERT(readLength == frameLength);
+
+    // Suppress the warning when assertions are disabled
+    OT_UNUSED_VARIABLE(readLength);
 
     sendFrame.SetHeaderDataLen(frameLength);
     mSendFrameLength = frameLength + kSpiHeaderSize;
@@ -286,7 +292,7 @@
     // Prepare new transaction by using `mSendFrame` as the output
     // frame while keeping the input frame unchanged.
 
-    error = otPlatSpiSlavePrepareTransaction(mSendFrame, mSendFrameLength, NULL, 0, /* aRequestTrans */ true);
+    error = otPlatSpiSlavePrepareTransaction(mSendFrame, mSendFrameLength, nullptr, 0, /* aRequestTrans */ true);
 
     if (error == OT_ERROR_BUSY)
     {
@@ -302,7 +308,7 @@
         ExitNow();
     }
 
-    mTxFrameBuffer.OutFrameRemove();
+    IgnoreError(mTxFrameBuffer.OutFrameRemove());
 
 exit:
     return;
@@ -367,8 +373,9 @@
     {
         sendFrame.SetHeaderAcceptLen(kSpiBufferSize - kSpiHeaderSize);
 
-        otPlatSpiSlavePrepareTransaction(mEmptySendFrameFullAccept, kSpiHeaderSize, mReceiveFrame, kSpiBufferSize,
-                                         /* aRequestTrans */ false);
+        IgnoreError(otPlatSpiSlavePrepareTransaction(mEmptySendFrameFullAccept, kSpiHeaderSize, mReceiveFrame,
+                                                     kSpiBufferSize,
+                                                     /* aRequestTrans */ false));
 
         // No need to check the error status. Getting `OT_ERROR_BUSY`
         // is OK as everything will be set up properly from callback when
diff --git a/src/ncp/ncp_spi.hpp b/src/ncp/ncp_spi.hpp
index 5018f29..d4a87dd 100644
--- a/src/ncp/ncp_spi.hpp
+++ b/src/ncp/ncp_spi.hpp
@@ -294,9 +294,9 @@
     void        SpiTransactionProcess(void);
 
     static void HandleFrameAddedToTxBuffer(void *                   aContext,
-                                           NcpFrameBuffer::FrameTag aFrameTag,
-                                           NcpFrameBuffer::Priority aPriority,
-                                           NcpFrameBuffer *         aNcpFrameBuffer);
+                                           Spinel::Buffer::FrameTag aFrameTag,
+                                           Spinel::Buffer::Priority aPriority,
+                                           Spinel::Buffer *         aBuffer);
 
     static void PrepareTxFrame(Tasklet &aTasklet);
     void        PrepareTxFrame(void);
diff --git a/src/ncp/ncp_uart.cpp b/src/ncp/ncp_uart.cpp
index 60f27f0..09247b4 100644
--- a/src/ncp/ncp_uart.cpp
+++ b/src/ncp/ncp_uart.cpp
@@ -45,18 +45,17 @@
 #include "common/instance.hpp"
 #include "common/new.hpp"
 #include "net/ip6.hpp"
-#include "utils/static_assert.hpp"
 
 #if OPENTHREAD_CONFIG_NCP_UART_ENABLE
 
 #if OPENTHREAD_CONFIG_DIAG_ENABLE
-OT_STATIC_ASSERT(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE -
-                                                                  ot::Ncp::NcpBase::kSpinelCmdHeaderSize -
-                                                                  ot::Ncp::NcpBase::kSpinelPropIdSize,
-                 "diag output should be smaller than NCP UART rx buffer");
+static_assert(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE -
+                                                               ot::Ncp::NcpBase::kSpinelCmdHeaderSize -
+                                                               ot::Ncp::NcpBase::kSpinelPropIdSize,
+              "diag output should be smaller than NCP UART rx buffer");
 
-OT_STATIC_ASSERT(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE,
-                 "diag command line should be smaller than NCP UART rx buffer");
+static_assert(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE,
+              "diag command line should be smaller than NCP UART rx buffer");
 #endif
 
 namespace ot {
@@ -68,14 +67,14 @@
 
 extern "C" void otNcpInit(otInstance *aInstance)
 {
-    NcpUart * ncpUart  = NULL;
+    NcpUart * ncpUart  = nullptr;
     Instance *instance = static_cast<Instance *>(aInstance);
 
     ncpUart = new (&sNcpRaw) NcpUart(instance);
 
-    if (ncpUart == NULL || ncpUart != NcpBase::GetNcpInstance())
+    if (ncpUart == nullptr || ncpUart != NcpBase::GetNcpInstance())
     {
-        assert(false);
+        OT_ASSERT(false);
     }
 }
 
@@ -97,15 +96,15 @@
 {
     mTxFrameBuffer.SetFrameAddedCallback(HandleFrameAddedToNcpBuffer, this);
 
-    otPlatUartEnable();
+    IgnoreError(otPlatUartEnable());
 }
 
 void NcpUart::HandleFrameAddedToNcpBuffer(void *                   aContext,
-                                          NcpFrameBuffer::FrameTag aTag,
-                                          NcpFrameBuffer::Priority aPriority,
-                                          NcpFrameBuffer *         aNcpFrameBuffer)
+                                          Spinel::Buffer::FrameTag aTag,
+                                          Spinel::Buffer::Priority aPriority,
+                                          Spinel::Buffer *         aBuffer)
 {
-    OT_UNUSED_VARIABLE(aNcpFrameBuffer);
+    OT_UNUSED_VARIABLE(aBuffer);
     OT_UNUSED_VARIABLE(aTag);
     OT_UNUSED_VARIABLE(aPriority);
 
@@ -134,9 +133,9 @@
     uint16_t len;
     bool     prevHostPowerState;
 #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
-    NcpFrameBufferEncrypterReader &txFrameBuffer = mTxFrameBufferEncrypterReader;
+    Spinel::BufferEncrypterReader &txFrameBuffer = mTxFrameBufferEncrypterReader;
 #else
-    NcpFrameBuffer &txFrameBuffer = mTxFrameBuffer;
+    Spinel::Buffer &txFrameBuffer = mTxFrameBuffer;
 #endif // OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
 
     while (!txFrameBuffer.IsEmpty() || (mState == kFinalizingFrame))
@@ -150,10 +149,10 @@
                 otPlatWakeHost();
             }
 
-            VerifyOrExit(!super_t::ShouldDeferHostSend());
+            VerifyOrExit(!super_t::ShouldDeferHostSend(), OT_NOOP);
             SuccessOrExit(mFrameEncoder.BeginFrame());
 
-            txFrameBuffer.OutFrameBegin();
+            IgnoreError(txFrameBuffer.OutFrameBegin());
 
             mState = kEncodingFrame;
 
@@ -170,7 +169,7 @@
             // call to OutFrameRemove.
             prevHostPowerState = mHostPowerStateInProgress;
 
-            txFrameBuffer.OutFrameRemove();
+            IgnoreError(txFrameBuffer.OutFrameRemove());
 
             if (prevHostPowerState && !mHostPowerStateInProgress)
             {
@@ -208,7 +207,7 @@
     {
         if (otPlatUartSend(mUartBuffer.GetFrame(), len) != OT_ERROR_NONE)
         {
-            assert(false);
+            OT_ASSERT(false);
         }
     }
 }
@@ -217,7 +216,7 @@
 {
     NcpUart *ncpUart = static_cast<NcpUart *>(NcpBase::GetNcpInstance());
 
-    if (ncpUart != NULL)
+    if (ncpUart != nullptr)
     {
         ncpUart->HandleUartSendDone();
     }
@@ -226,7 +225,6 @@
 void NcpUart::HandleUartSendDone(void)
 {
     mUartBuffer.Clear();
-
     mUartSendTask.Post();
 }
 
@@ -234,7 +232,7 @@
 {
     NcpUart *ncpUart = static_cast<NcpUart *>(NcpBase::GetNcpInstance());
 
-    if (ncpUart != NULL)
+    if (ncpUart != nullptr)
     {
         ncpUart->HandleUartReceiveDone(aBuf, aBufLength);
     }
@@ -287,7 +285,7 @@
     snprintf(hexbuf, sizeof(hexbuf), "Framing error %d: [", aError);
 
     // Write out the first part of our log message.
-    otNcpStreamWrite(0, reinterpret_cast<uint8_t *>(hexbuf), static_cast<int>(strlen(hexbuf)));
+    IgnoreError(otNcpStreamWrite(0, reinterpret_cast<uint8_t *>(hexbuf), static_cast<int>(strlen(hexbuf))));
 
     // The first '3' comes from the trailing "]\n\000" at the end o the string.
     // The second '3' comes from the length of two hex digits and a space.
@@ -305,24 +303,24 @@
 
     // Write out the second part of our log message.
     // We skip the first byte since it has a space in it.
-    otNcpStreamWrite(0, reinterpret_cast<uint8_t *>(hexbuf + 1), static_cast<int>(strlen(hexbuf) - 1));
+    IgnoreError(otNcpStreamWrite(0, reinterpret_cast<uint8_t *>(hexbuf + 1), static_cast<int>(strlen(hexbuf) - 1)));
 }
 
 #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
 
-NcpUart::NcpFrameBufferEncrypterReader::NcpFrameBufferEncrypterReader(NcpFrameBuffer &aTxFrameBuffer)
+NcpUart::Spinel::BufferEncrypterReader::SpinelBufferEncrypterReader(Spinel::Buffer &aTxFrameBuffer)
     : mTxFrameBuffer(aTxFrameBuffer)
     , mDataBufferReadIndex(0)
     , mOutputDataLength(0)
 {
 }
 
-bool NcpUart::NcpFrameBufferEncrypterReader::IsEmpty(void) const
+bool NcpUart::Spinel::BufferEncrypterReader::IsEmpty(void) const
 {
     return mTxFrameBuffer.IsEmpty() && !mOutputDataLength;
 }
 
-otError NcpUart::NcpFrameBufferEncrypterReader::OutFrameBegin(void)
+otError NcpUart::Spinel::BufferEncrypterReader::OutFrameBegin(void)
 {
     otError status = OT_ERROR_FAILED;
 
@@ -334,7 +332,7 @@
 
         if (mOutputDataLength > 0)
         {
-            assert(mOutputDataLength <= sizeof(mDataBuffer));
+            OT_ASSERT(mOutputDataLength <= sizeof(mDataBuffer));
             mTxFrameBuffer.OutFrameRead(mOutputDataLength, mDataBuffer);
 
             if (!SpinelEncrypter::EncryptOutbound(mDataBuffer, sizeof(mDataBuffer), &mOutputDataLength))
@@ -352,22 +350,22 @@
     return status;
 }
 
-bool NcpUart::NcpFrameBufferEncrypterReader::OutFrameHasEnded(void)
+bool NcpUart::Spinel::BufferEncrypterReader::OutFrameHasEnded(void)
 {
     return (mDataBufferReadIndex >= mOutputDataLength);
 }
 
-uint8_t NcpUart::NcpFrameBufferEncrypterReader::OutFrameReadByte(void)
+uint8_t NcpUart::Spinel::BufferEncrypterReader::OutFrameReadByte(void)
 {
     return mDataBuffer[mDataBufferReadIndex++];
 }
 
-otError NcpUart::NcpFrameBufferEncrypterReader::OutFrameRemove(void)
+otError NcpUart::Spinel::BufferEncrypterReader::OutFrameRemove(void)
 {
     return mTxFrameBuffer.OutFrameRemove();
 }
 
-void NcpUart::NcpFrameBufferEncrypterReader::Reset(void)
+void NcpUart::Spinel::BufferEncrypterReader::Reset(void)
 {
     mOutputDataLength    = 0;
     mDataBufferReadIndex = 0;
diff --git a/src/ncp/ncp_uart.hpp b/src/ncp/ncp_uart.hpp
index 8e61e72..5221403 100644
--- a/src/ncp/ncp_uart.hpp
+++ b/src/ncp/ncp_uart.hpp
@@ -35,7 +35,7 @@
 
 #include "openthread-core-config.h"
 
-#include "ncp/hdlc.hpp"
+#include "lib/hdlc/hdlc.hpp"
 #include "ncp/ncp_base.hpp"
 
 #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
@@ -87,17 +87,17 @@
 
 #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
     /**
-     * Wraps NcpFrameBuffer allowing to read data through spinel encrypter.
+     * Wraps Spinel::Buffer allowing to read data through spinel encrypter.
      * Creates additional buffers to allow transforming of the whole spinel frames.
      */
-    class NcpFrameBufferEncrypterReader
+    class Spinel::BufferEncrypterReader
     {
     public:
         /**
          * C-tor.
-         * Takes a reference to NcpFrameBuffer in order to read spinel frames.
+         * Takes a reference to Spinel::Buffer in order to read spinel frames.
          */
-        explicit NcpFrameBufferEncrypterReader(NcpFrameBuffer &aTxFrameBuffer);
+        explicit Spinel::BufferEncrypterReader(Spinel::Buffer &aTxFrameBuffer);
         bool    IsEmpty(void) const;
         otError OutFrameBegin(void);
         bool    OutFrameHasEnded(void);
@@ -107,7 +107,7 @@
     private:
         void Reset(void);
 
-        NcpFrameBuffer &mTxFrameBuffer;
+        Spinel::Buffer &mTxFrameBuffer;
         uint8_t         mDataBuffer[kRxBufferSize];
         size_t          mDataBufferReadIndex;
         size_t          mOutputDataLength;
@@ -123,9 +123,9 @@
     static void EncodeAndSendToUart(Tasklet &aTasklet);
     static void HandleFrame(void *aContext, otError aError);
     static void HandleFrameAddedToNcpBuffer(void *                   aContext,
-                                            NcpFrameBuffer::FrameTag aTag,
-                                            NcpFrameBuffer::Priority aPriority,
-                                            NcpFrameBuffer *         aNcpFrameBuffer);
+                                            Spinel::Buffer::FrameTag aTag,
+                                            Spinel::Buffer::Priority aPriority,
+                                            Spinel::Buffer *         aBuffer);
 
     Hdlc::Encoder                        mFrameEncoder;
     Hdlc::Decoder                        mFrameDecoder;
@@ -137,7 +137,7 @@
     Tasklet                              mUartSendTask;
 
 #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
-    NcpFrameBufferEncrypterReader mTxFrameBufferEncrypterReader;
+    Spinel::BufferEncrypterReader mTxFrameBufferEncrypterReader;
 #endif // OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER
 };
 
diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c
deleted file mode 100644
index a041c66..0000000
--- a/src/ncp/spinel.c
+++ /dev/null
@@ -1,3041 +0,0 @@
-/*
- *    Copyright (c) 2016, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- *  -------------------------------------------------------------------
- *
- *  ## Unit Test ##
- *
- *  This file includes its own unit test. To compile the unit test,
- *  simply compile this file with the macro SPINEL_SELF_TEST set to 1.
- *  For example:
- *
- *      cc spinel.c -Wall -DSPINEL_SELF_TEST=1 -o spinel
- *
- *  -------------------------------------------------------------------
- */
-
-// ----------------------------------------------------------------------------
-// MARK: -
-// MARK: Headers
-
-#include "spinel.h"
-
-#include <errno.h>
-#include <limits.h>
-
-#ifndef SPINEL_PLATFORM_HEADER
-/* These are all already included in the spinel platform header
- * if SPINEL_PLATFORM_HEADER was defined.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif // #ifndef SPINEL_PLATFORM_HEADER
-
-// ----------------------------------------------------------------------------
-// MARK: -
-
-// IAR's errno.h apparently doesn't define EOVERFLOW.
-#ifndef EOVERFLOW
-// There is no real good choice for what to set
-// errno to in this case, so we just pick the
-// value '1' somewhat arbitrarily.
-#define EOVERFLOW 1
-#endif
-
-// IAR's errno.h apparently doesn't define EINVAL.
-#ifndef EINVAL
-// There is no real good choice for what to set
-// errno to in this case, so we just pick the
-// value '1' somewhat arbitrarily.
-#define EINVAL 1
-#endif
-
-// IAR's errno.h apparently doesn't define ENOMEM.
-#ifndef ENOMEM
-// There is no real good choice for what to set
-// errno to in this case, so we just pick the
-// value '1' somewhat arbitrarily.
-#define ENOMEM 1
-#endif
-
-#ifndef SPINEL_PLATFORM_SHOULD_LOG_ASSERTS
-#define SPINEL_PLATFORM_SHOULD_LOG_ASSERTS 0
-#endif
-
-#ifndef SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
-#define SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR 0
-#endif
-
-#ifndef SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
-#define SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF 0
-#endif
-
-#ifndef SPINEL_SELF_TEST
-#define SPINEL_SELF_TEST 0
-#endif
-
-#if defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
-#error "SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR is set but errno is already defined."
-#endif
-
-// Work-around for platforms that don't implement the `errno` variable.
-#if !defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
-static int spinel_errno_workaround_;
-#define errno spinel_errno_workaround_
-#endif // SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
-
-#ifndef assert_printf
-#if SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
-#define assert_printf(fmt, ...) printf(__FILE__ ":%d: " fmt "\n", __LINE__, __VA_ARGS__)
-#else // if SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
-#define assert_printf(fmt, ...) fprintf(stderr, __FILE__ ":%d: " fmt "\n", __LINE__, __VA_ARGS__)
-#endif // else SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
-#endif
-
-#ifndef require_action
-#if SPINEL_PLATFORM_SHOULD_LOG_ASSERTS
-#define require_action(c, l, a)                           \
-    do                                                    \
-    {                                                     \
-        if (!(c))                                         \
-        {                                                 \
-            assert_printf("Requirement Failed (%s)", #c); \
-            a;                                            \
-            goto l;                                       \
-        }                                                 \
-    } while (0)
-#else // if DEBUG
-#define require_action(c, l, a) \
-    do                          \
-    {                           \
-        if (!(c))               \
-        {                       \
-            a;                  \
-            goto l;             \
-        }                       \
-    } while (0)
-#endif // else DEBUG
-#endif // ifndef require_action
-
-#ifndef require
-#define require(c, l) require_action(c, l, {})
-#endif
-
-#ifndef strnlen
-size_t strnlen(const char *s, size_t maxlen)
-{
-    size_t ret;
-
-    for (ret = 0; (ret < maxlen) && (s[ret] != 0); ret++)
-    {
-        // Empty loop.
-    }
-
-    return ret;
-}
-#endif
-
-typedef struct
-{
-    va_list obj;
-} va_list_obj;
-
-#define SPINEL_MAX_PACK_LENGTH 32767
-
-// ----------------------------------------------------------------------------
-
-// This function validates whether a given byte sequence (string) follows UTF8 encoding.
-static bool spinel_validate_utf8(const uint8_t *string)
-{
-    bool    ret = true;
-    uint8_t byte;
-    uint8_t continuation_bytes = 0;
-
-    while ((byte = *string++) != 0)
-    {
-        if ((byte & 0x80) == 0)
-        {
-            continue;
-        }
-
-        // This is a leading byte 1xxx-xxxx.
-
-        if ((byte & 0x40) == 0) // 10xx-xxxx
-        {
-            // We got a continuation byte pattern without seeing a leading byte earlier.
-            ret = false;
-            goto bail;
-        }
-        else if ((byte & 0x20) == 0) // 110x-xxxx
-        {
-            continuation_bytes = 1;
-        }
-        else if ((byte & 0x10) == 0) // 1110-xxxx
-        {
-            continuation_bytes = 2;
-        }
-        else if ((byte & 0x08) == 0) // 1111-0xxx
-        {
-            continuation_bytes = 3;
-        }
-        else // 1111-1xxx  (invalid pattern).
-        {
-            ret = false;
-            goto bail;
-        }
-
-        while (continuation_bytes-- != 0)
-        {
-            byte = *string++;
-
-            // Verify the continuation byte pattern 10xx-xxxx
-            if ((byte & 0xc0) != 0x80)
-            {
-                ret = false;
-                goto bail;
-            }
-        }
-    }
-
-bail:
-    return ret;
-}
-
-// ----------------------------------------------------------------------------
-// MARK: -
-
-spinel_ssize_t spinel_packed_uint_decode(const uint8_t *bytes, spinel_size_t len, unsigned int *value_ptr)
-{
-    spinel_ssize_t ret   = 0;
-    unsigned int   value = 0;
-
-    unsigned int i = 0;
-
-    do
-    {
-        if ((len < sizeof(uint8_t)) || (i >= sizeof(unsigned int) * CHAR_BIT))
-        {
-            ret = -1;
-            break;
-        }
-
-        value |= (unsigned int)(bytes[0] & 0x7F) << i;
-        i += 7;
-        ret += sizeof(uint8_t);
-        bytes += sizeof(uint8_t);
-        len -= sizeof(uint8_t);
-    } while ((bytes[-1] & 0x80) == 0x80);
-
-    if ((ret > 0) && (value_ptr != NULL))
-    {
-        *value_ptr = value;
-    }
-
-    return ret;
-}
-
-spinel_ssize_t spinel_packed_uint_size(unsigned int value)
-{
-    spinel_ssize_t ret;
-
-    if (value < (1 << 7))
-    {
-        ret = 1;
-    }
-    else if (value < (1 << 14))
-    {
-        ret = 2;
-    }
-    else if (value < (1 << 21))
-    {
-        ret = 3;
-    }
-    else if (value < (1 << 28))
-    {
-        ret = 4;
-    }
-    else
-    {
-        ret = 5;
-    }
-
-    return ret;
-}
-
-spinel_ssize_t spinel_packed_uint_encode(uint8_t *bytes, spinel_size_t len, unsigned int value)
-{
-    const spinel_ssize_t encoded_size = spinel_packed_uint_size(value);
-
-    if ((spinel_ssize_t)len >= encoded_size)
-    {
-        spinel_ssize_t i;
-
-        for (i = 0; i != encoded_size - 1; ++i)
-        {
-            *bytes++ = (value & 0x7F) | 0x80;
-            value    = (value >> 7);
-        }
-
-        *bytes++ = (value & 0x7F);
-    }
-
-    return encoded_size;
-}
-
-const char *spinel_next_packed_datatype(const char *pack_format)
-{
-    int depth = 0;
-
-    do
-    {
-        switch (*++pack_format)
-        {
-        case '(':
-            depth++;
-            break;
-
-        case ')':
-            depth--;
-
-            if (depth == 0)
-            {
-                pack_format++;
-            }
-
-            break;
-        }
-    } while ((depth > 0) && *pack_format != 0);
-
-    return pack_format;
-}
-
-static spinel_ssize_t spinel_datatype_vunpack_(bool           in_place,
-                                               const uint8_t *data_in,
-                                               spinel_size_t  data_len,
-                                               const char *   pack_format,
-                                               va_list_obj *  args)
-{
-    spinel_ssize_t ret = 0;
-
-    // Buffer length sanity check
-    require_action(data_len <= SPINEL_MAX_PACK_LENGTH, bail, (ret = -1, errno = EINVAL));
-
-    for (; *pack_format != 0; pack_format = spinel_next_packed_datatype(pack_format))
-    {
-        if (*pack_format == ')')
-        {
-            // Don't go past the end of a struct.
-            break;
-        }
-
-        switch ((spinel_datatype_t)pack_format[0])
-        {
-        case SPINEL_DATATYPE_BOOL_C:
-        {
-            bool *arg_ptr = va_arg(args->obj, bool *);
-            require_action(data_len >= sizeof(uint8_t), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (arg_ptr)
-            {
-                *arg_ptr = data_in[0] != 0;
-            }
-
-            ret += sizeof(uint8_t);
-            data_in += sizeof(uint8_t);
-            data_len -= sizeof(uint8_t);
-            break;
-        }
-
-        case SPINEL_DATATYPE_INT8_C:
-        case SPINEL_DATATYPE_UINT8_C:
-        {
-            uint8_t *arg_ptr = va_arg(args->obj, uint8_t *);
-            require_action(data_len >= sizeof(uint8_t), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (arg_ptr)
-            {
-                *arg_ptr = data_in[0];
-            }
-
-            ret += sizeof(uint8_t);
-            data_in += sizeof(uint8_t);
-            data_len -= sizeof(uint8_t);
-            break;
-        }
-
-        case SPINEL_DATATYPE_INT16_C:
-        case SPINEL_DATATYPE_UINT16_C:
-        {
-            uint16_t *arg_ptr = va_arg(args->obj, uint16_t *);
-            require_action(data_len >= sizeof(uint16_t), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (arg_ptr)
-            {
-                *arg_ptr = (uint16_t)((data_in[1] << 8) | data_in[0]);
-            }
-
-            ret += sizeof(uint16_t);
-            data_in += sizeof(uint16_t);
-            data_len -= sizeof(uint16_t);
-            break;
-        }
-
-        case SPINEL_DATATYPE_INT32_C:
-        case SPINEL_DATATYPE_UINT32_C:
-        {
-            uint32_t *arg_ptr = va_arg(args->obj, uint32_t *);
-            require_action(data_len >= sizeof(uint32_t), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (arg_ptr)
-            {
-                *arg_ptr = (uint32_t)((data_in[3] << 24) | (data_in[2] << 16) | (data_in[1] << 8) | data_in[0]);
-            }
-
-            ret += sizeof(uint32_t);
-            data_in += sizeof(uint32_t);
-            data_len -= sizeof(uint32_t);
-            break;
-        }
-
-        case SPINEL_DATATYPE_INT64_C:
-        case SPINEL_DATATYPE_UINT64_C:
-        {
-            uint64_t *arg_ptr = va_arg(args->obj, uint64_t *);
-            require_action(data_len >= sizeof(uint64_t), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (arg_ptr)
-            {
-                uint32_t l32 = (uint32_t)((data_in[3] << 24) | (data_in[2] << 16) | (data_in[1] << 8) | data_in[0]);
-                uint32_t h32 = (uint32_t)((data_in[7] << 24) | (data_in[6] << 16) | (data_in[5] << 8) | data_in[4]);
-
-                *arg_ptr = ((uint64_t)l32) | (((uint64_t)h32) << 32);
-            }
-
-            ret += sizeof(uint64_t);
-            data_in += sizeof(uint64_t);
-            data_len -= sizeof(uint64_t);
-            break;
-        }
-
-        case SPINEL_DATATYPE_IPv6ADDR_C:
-        {
-            require_action(data_len >= sizeof(spinel_ipv6addr_t), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (in_place)
-            {
-                spinel_ipv6addr_t *arg = va_arg(args->obj, spinel_ipv6addr_t *);
-                if (arg)
-                {
-                    memcpy(arg, data_in, sizeof(spinel_ipv6addr_t));
-                }
-            }
-            else
-            {
-                const spinel_ipv6addr_t **arg_ptr = va_arg(args->obj, const spinel_ipv6addr_t **);
-                if (arg_ptr)
-                {
-                    *arg_ptr = (const spinel_ipv6addr_t *)data_in;
-                }
-            }
-
-            ret += sizeof(spinel_ipv6addr_t);
-            data_in += sizeof(spinel_ipv6addr_t);
-            data_len -= sizeof(spinel_ipv6addr_t);
-            break;
-        }
-
-        case SPINEL_DATATYPE_EUI64_C:
-        {
-            require_action(data_len >= sizeof(spinel_eui64_t), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (in_place)
-            {
-                spinel_eui64_t *arg = va_arg(args->obj, spinel_eui64_t *);
-                if (arg)
-                {
-                    memcpy(arg, data_in, sizeof(spinel_eui64_t));
-                }
-            }
-            else
-            {
-                const spinel_eui64_t **arg_ptr = va_arg(args->obj, const spinel_eui64_t **);
-                if (arg_ptr)
-                {
-                    *arg_ptr = (const spinel_eui64_t *)data_in;
-                }
-            }
-
-            ret += sizeof(spinel_eui64_t);
-            data_in += sizeof(spinel_eui64_t);
-            data_len -= sizeof(spinel_eui64_t);
-            break;
-        }
-
-        case SPINEL_DATATYPE_EUI48_C:
-        {
-            require_action(data_len >= sizeof(spinel_eui48_t), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (in_place)
-            {
-                spinel_eui48_t *arg = va_arg(args->obj, spinel_eui48_t *);
-                if (arg)
-                {
-                    memcpy(arg, data_in, sizeof(spinel_eui48_t));
-                }
-            }
-            else
-            {
-                const spinel_eui48_t **arg_ptr = va_arg(args->obj, const spinel_eui48_t **);
-                if (arg_ptr)
-                {
-                    *arg_ptr = (const spinel_eui48_t *)data_in;
-                }
-            }
-
-            ret += sizeof(spinel_eui48_t);
-            data_in += sizeof(spinel_eui48_t);
-            data_len -= sizeof(spinel_eui48_t);
-            break;
-        }
-
-        case SPINEL_DATATYPE_UINT_PACKED_C:
-        {
-            unsigned int * arg_ptr = va_arg(args->obj, unsigned int *);
-            spinel_ssize_t pui_len = spinel_packed_uint_decode(data_in, data_len, arg_ptr);
-
-            // Range check
-            require_action(NULL == arg_ptr || (*arg_ptr < SPINEL_MAX_UINT_PACKED), bail, (ret = -1, errno = ERANGE));
-
-            require(pui_len > 0, bail);
-
-            require(pui_len <= (spinel_ssize_t)data_len, bail);
-
-            ret += pui_len;
-            data_in += pui_len;
-            data_len -= (spinel_size_t)pui_len;
-            break;
-        }
-
-        case SPINEL_DATATYPE_UTF8_C:
-        {
-            size_t len;
-
-            // Make sure we have at least one byte.
-            require_action(data_len > 0, bail, (ret = -1, errno = EOVERFLOW));
-
-            // Add 1 for zero termination. If not zero terminated,
-            // len will then be data_len+1, which we will detect
-            // in the next check.
-            len = strnlen((const char *)data_in, data_len) + 1;
-
-            // Verify that the string is zero terminated.
-            require_action(len <= data_len, bail, (ret = -1, errno = EOVERFLOW));
-
-            // Verify the string follows valid UTF8 encoding.
-            require_action(spinel_validate_utf8(data_in), bail, (ret = -1, errno = EINVAL));
-
-            if (in_place)
-            {
-                char * arg     = va_arg(args->obj, char *);
-                size_t len_arg = va_arg(args->obj, size_t);
-                if (arg)
-                {
-                    require_action(len_arg >= len, bail, (ret = -1, errno = ENOMEM));
-                    memcpy(arg, data_in, len);
-                }
-            }
-            else
-            {
-                const char **arg_ptr = va_arg(args->obj, const char **);
-                if (arg_ptr)
-                {
-                    *arg_ptr = (const char *)data_in;
-                }
-            }
-
-            ret += (spinel_size_t)len;
-            data_in += len;
-            data_len -= (spinel_size_t)len;
-            break;
-        }
-
-        case SPINEL_DATATYPE_DATA_C:
-        case SPINEL_DATATYPE_DATA_WLEN_C:
-        {
-            spinel_ssize_t pui_len       = 0;
-            uint16_t       block_len     = 0;
-            const uint8_t *block_ptr     = data_in;
-            void *         arg_ptr       = va_arg(args->obj, void *);
-            unsigned int * block_len_ptr = va_arg(args->obj, unsigned int *);
-            char           nextformat    = *spinel_next_packed_datatype(pack_format);
-
-            if ((pack_format[0] == SPINEL_DATATYPE_DATA_WLEN_C) || ((nextformat != 0) && (nextformat != ')')))
-            {
-                pui_len = spinel_datatype_unpack(data_in, data_len, SPINEL_DATATYPE_UINT16_S, &block_len);
-                block_ptr += pui_len;
-
-                require(pui_len > 0, bail);
-                require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
-            }
-            else
-            {
-                block_len = (uint16_t)data_len;
-                pui_len   = 0;
-            }
-
-            require_action((spinel_ssize_t)data_len >= (block_len + pui_len), bail, (ret = -1, errno = EOVERFLOW));
-
-            if (in_place)
-            {
-                require_action(NULL != block_len_ptr && *block_len_ptr >= block_len, bail, (ret = -1, errno = EINVAL));
-                memcpy(arg_ptr, block_ptr, block_len);
-            }
-            else
-            {
-                const uint8_t **block_ptr_ptr = (const uint8_t **)arg_ptr;
-                if (NULL != block_ptr_ptr)
-                {
-                    *block_ptr_ptr = block_ptr;
-                }
-            }
-
-            if (NULL != block_len_ptr)
-            {
-                *block_len_ptr = block_len;
-            }
-
-            block_len += (uint16_t)pui_len;
-            ret += block_len;
-            data_in += block_len;
-            data_len -= block_len;
-            break;
-        }
-
-        case 'T':
-        case SPINEL_DATATYPE_STRUCT_C:
-        {
-            spinel_ssize_t pui_len    = 0;
-            uint16_t       block_len  = 0;
-            spinel_ssize_t actual_len = 0;
-            const uint8_t *block_ptr  = data_in;
-            char           nextformat = *spinel_next_packed_datatype(pack_format);
-
-            if ((pack_format[0] == SPINEL_DATATYPE_STRUCT_C) || ((nextformat != 0) && (nextformat != ')')))
-            {
-                pui_len = spinel_datatype_unpack(data_in, data_len, SPINEL_DATATYPE_UINT16_S, &block_len);
-                block_ptr += pui_len;
-
-                require(pui_len > 0, bail);
-                require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
-            }
-            else
-            {
-                block_len = (uint16_t)data_len;
-                pui_len   = 0;
-            }
-
-            require_action((spinel_ssize_t)data_len >= (block_len + pui_len), bail, (ret = -1, errno = EOVERFLOW));
-
-            actual_len = spinel_datatype_vunpack_(false, block_ptr, block_len, pack_format + 2, args);
-
-            require_action(actual_len > -1, bail, (ret = -1, errno = EOVERFLOW));
-
-            if (pui_len)
-            {
-                block_len += (uint16_t)pui_len;
-            }
-            else
-            {
-                block_len = (uint16_t)actual_len;
-            }
-
-            ret += block_len;
-            data_in += block_len;
-            data_len -= block_len;
-            break;
-        }
-
-        case '.':
-            // Skip.
-            break;
-
-        case SPINEL_DATATYPE_ARRAY_C:
-        default:
-            // Unsupported Type!
-            ret   = -1;
-            errno = EINVAL;
-            goto bail;
-        }
-    }
-
-    return ret;
-
-bail:
-    return ret;
-}
-
-spinel_ssize_t spinel_datatype_unpack_in_place(const uint8_t *data_in,
-                                               spinel_size_t  data_len,
-                                               const char *   pack_format,
-                                               ...)
-{
-    spinel_ssize_t ret;
-    va_list_obj    args;
-    va_start(args.obj, pack_format);
-
-    ret = spinel_datatype_vunpack_(true, data_in, data_len, pack_format, &args);
-
-    va_end(args.obj);
-    return ret;
-}
-
-spinel_ssize_t spinel_datatype_unpack(const uint8_t *data_in, spinel_size_t data_len, const char *pack_format, ...)
-{
-    spinel_ssize_t ret;
-    va_list_obj    args;
-    va_start(args.obj, pack_format);
-
-    ret = spinel_datatype_vunpack_(false, data_in, data_len, pack_format, &args);
-
-    va_end(args.obj);
-    return ret;
-}
-
-spinel_ssize_t spinel_datatype_vunpack_in_place(const uint8_t *data_in,
-                                                spinel_size_t  data_len,
-                                                const char *   pack_format,
-                                                va_list        args)
-{
-    spinel_ssize_t ret;
-    va_list_obj    args_obj;
-    va_copy(args_obj.obj, args);
-
-    ret = spinel_datatype_vunpack_(true, data_in, data_len, pack_format, &args_obj);
-
-    va_end(args_obj.obj);
-    return ret;
-}
-
-spinel_ssize_t spinel_datatype_vunpack(const uint8_t *data_in,
-                                       spinel_size_t  data_len,
-                                       const char *   pack_format,
-                                       va_list        args)
-{
-    spinel_ssize_t ret;
-    va_list_obj    args_obj;
-    va_copy(args_obj.obj, args);
-
-    ret = spinel_datatype_vunpack_(false, data_in, data_len, pack_format, &args_obj);
-
-    va_end(args_obj.obj);
-    return ret;
-}
-
-static spinel_ssize_t spinel_datatype_vpack_(uint8_t *     data_out,
-                                             spinel_size_t data_len_max,
-                                             const char *  pack_format,
-                                             va_list_obj * args)
-{
-    spinel_ssize_t ret = 0;
-
-    // Buffer length sanity check
-    require_action(data_len_max <= SPINEL_MAX_PACK_LENGTH, bail, (ret = -1, errno = EINVAL));
-
-    if (data_out == NULL)
-    {
-        data_len_max = 0;
-    }
-
-    for (; *pack_format != 0; pack_format = spinel_next_packed_datatype(pack_format))
-    {
-        if (*pack_format == ')')
-        {
-            // Don't go past the end of a struct.
-            break;
-        }
-
-        switch ((spinel_datatype_t)*pack_format)
-        {
-        case SPINEL_DATATYPE_BOOL_C:
-        {
-            bool arg = (bool)va_arg(args->obj, int);
-            ret += sizeof(uint8_t);
-
-            if (data_len_max >= sizeof(uint8_t))
-            {
-                data_out[0] = (arg != false);
-                data_out += sizeof(uint8_t);
-                data_len_max -= sizeof(uint8_t);
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_INT8_C:
-        case SPINEL_DATATYPE_UINT8_C:
-        {
-            uint8_t arg = (uint8_t)va_arg(args->obj, int);
-            ret += sizeof(uint8_t);
-
-            if (data_len_max >= sizeof(uint8_t))
-            {
-                data_out[0] = arg;
-                data_out += sizeof(uint8_t);
-                data_len_max -= sizeof(uint8_t);
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_INT16_C:
-        case SPINEL_DATATYPE_UINT16_C:
-        {
-            uint16_t arg = (uint16_t)va_arg(args->obj, int);
-            ret += sizeof(uint16_t);
-
-            if (data_len_max >= sizeof(uint16_t))
-            {
-                data_out[1] = (arg >> 8) & 0xff;
-                data_out[0] = (arg >> 0) & 0xff;
-                data_out += sizeof(uint16_t);
-                data_len_max -= sizeof(uint16_t);
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_INT32_C:
-        case SPINEL_DATATYPE_UINT32_C:
-        {
-            uint32_t arg = (uint32_t)va_arg(args->obj, int);
-            ret += sizeof(uint32_t);
-
-            if (data_len_max >= sizeof(uint32_t))
-            {
-                data_out[3] = (arg >> 24) & 0xff;
-                data_out[2] = (arg >> 16) & 0xff;
-                data_out[1] = (arg >> 8) & 0xff;
-                data_out[0] = (arg >> 0) & 0xff;
-                data_out += sizeof(uint32_t);
-                data_len_max -= sizeof(uint32_t);
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_INT64_C:
-        case SPINEL_DATATYPE_UINT64_C:
-        {
-            uint64_t arg = va_arg(args->obj, uint64_t);
-
-            ret += sizeof(uint64_t);
-
-            if (data_len_max >= sizeof(uint64_t))
-            {
-                data_out[7] = (arg >> 56) & 0xff;
-                data_out[6] = (arg >> 48) & 0xff;
-                data_out[5] = (arg >> 40) & 0xff;
-                data_out[4] = (arg >> 32) & 0xff;
-                data_out[3] = (arg >> 24) & 0xff;
-                data_out[2] = (arg >> 16) & 0xff;
-                data_out[1] = (arg >> 8) & 0xff;
-                data_out[0] = (arg >> 0) & 0xff;
-                data_out += sizeof(uint64_t);
-                data_len_max -= sizeof(uint64_t);
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_IPv6ADDR_C:
-        {
-            spinel_ipv6addr_t *arg = va_arg(args->obj, spinel_ipv6addr_t *);
-            ret += sizeof(spinel_ipv6addr_t);
-
-            if (data_len_max >= sizeof(spinel_ipv6addr_t))
-            {
-                *(spinel_ipv6addr_t *)data_out = *arg;
-                data_out += sizeof(spinel_ipv6addr_t);
-                data_len_max -= sizeof(spinel_ipv6addr_t);
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_EUI48_C:
-        {
-            spinel_eui48_t *arg = va_arg(args->obj, spinel_eui48_t *);
-            ret += sizeof(spinel_eui48_t);
-
-            if (data_len_max >= sizeof(spinel_eui48_t))
-            {
-                *(spinel_eui48_t *)data_out = *arg;
-                data_out += sizeof(spinel_eui48_t);
-                data_len_max -= sizeof(spinel_eui48_t);
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_EUI64_C:
-        {
-            spinel_eui64_t *arg = va_arg(args->obj, spinel_eui64_t *);
-            ret += sizeof(spinel_eui64_t);
-
-            if (data_len_max >= sizeof(spinel_eui64_t))
-            {
-                *(spinel_eui64_t *)data_out = *arg;
-                data_out += sizeof(spinel_eui64_t);
-                data_len_max -= sizeof(spinel_eui64_t);
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_UINT_PACKED_C:
-        {
-            uint32_t       arg = va_arg(args->obj, uint32_t);
-            spinel_ssize_t encoded_size;
-
-            // Range Check
-            require_action(arg < SPINEL_MAX_UINT_PACKED, bail, {
-                ret   = -1;
-                errno = EINVAL;
-            });
-
-            encoded_size = spinel_packed_uint_encode(data_out, data_len_max, arg);
-            ret += encoded_size;
-
-            if ((spinel_ssize_t)data_len_max >= encoded_size)
-            {
-                data_out += encoded_size;
-                data_len_max -= (spinel_size_t)encoded_size;
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_UTF8_C:
-        {
-            const char *string_arg     = va_arg(args->obj, const char *);
-            size_t      string_arg_len = 0;
-
-            if (string_arg)
-            {
-                string_arg_len = strlen(string_arg) + 1;
-            }
-            else
-            {
-                string_arg     = "";
-                string_arg_len = 1;
-            }
-
-            ret += (spinel_size_t)string_arg_len;
-
-            if (data_len_max >= string_arg_len)
-            {
-                memcpy(data_out, string_arg, string_arg_len);
-
-                data_out += string_arg_len;
-                data_len_max -= (spinel_size_t)string_arg_len;
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case SPINEL_DATATYPE_DATA_WLEN_C:
-        case SPINEL_DATATYPE_DATA_C:
-        {
-            const uint8_t *arg           = va_arg(args->obj, const uint8_t *);
-            uint32_t       data_size_arg = va_arg(args->obj, uint32_t);
-            spinel_ssize_t size_len      = 0;
-            char           nextformat    = *spinel_next_packed_datatype(pack_format);
-
-            if ((pack_format[0] == SPINEL_DATATYPE_DATA_WLEN_C) || ((nextformat != 0) && (nextformat != ')')))
-            {
-                size_len = spinel_datatype_pack(data_out, data_len_max, SPINEL_DATATYPE_UINT16_S, data_size_arg);
-                require_action(size_len > 0, bail, {
-                    ret   = -1;
-                    errno = EINVAL;
-                });
-            }
-
-            ret += (spinel_size_t)size_len + data_size_arg;
-
-            if (data_len_max >= (spinel_size_t)size_len + data_size_arg)
-            {
-                data_out += size_len;
-                data_len_max -= (spinel_size_t)size_len;
-
-                if (data_out && arg)
-                {
-                    memcpy(data_out, arg, data_size_arg);
-                }
-
-                data_out += data_size_arg;
-                data_len_max -= data_size_arg;
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case 'T':
-        case SPINEL_DATATYPE_STRUCT_C:
-        {
-            spinel_ssize_t struct_len = 0;
-            spinel_ssize_t size_len   = 0;
-            char           nextformat = *spinel_next_packed_datatype(pack_format);
-
-            require_action(pack_format[1] == '(', bail, {
-                ret   = -1;
-                errno = EINVAL;
-            });
-
-            // First we figure out the size of the struct
-            {
-                va_list_obj subargs;
-                va_copy(subargs.obj, args->obj);
-                struct_len = spinel_datatype_vpack_(NULL, 0, pack_format + 2, &subargs);
-                va_end(subargs.obj);
-            }
-
-            if ((pack_format[0] == SPINEL_DATATYPE_STRUCT_C) || ((nextformat != 0) && (nextformat != ')')))
-            {
-                size_len = spinel_datatype_pack(data_out, data_len_max, SPINEL_DATATYPE_UINT16_S, struct_len);
-                require_action(size_len > 0, bail, {
-                    ret   = -1;
-                    errno = EINVAL;
-                });
-            }
-
-            ret += size_len + struct_len;
-
-            if (struct_len + size_len <= (spinel_ssize_t)data_len_max)
-            {
-                data_out += size_len;
-                data_len_max -= (spinel_size_t)size_len;
-
-                struct_len = spinel_datatype_vpack_(data_out, data_len_max, pack_format + 2, args);
-
-                data_out += struct_len;
-                data_len_max -= (spinel_size_t)struct_len;
-            }
-            else
-            {
-                data_len_max = 0;
-            }
-
-            break;
-        }
-
-        case '.':
-            // Skip.
-            break;
-
-        default:
-            // Unsupported Type!
-            ret   = -1;
-            errno = EINVAL;
-            goto bail;
-        }
-    }
-
-bail:
-    return ret;
-}
-
-spinel_ssize_t spinel_datatype_pack(uint8_t *data_out, spinel_size_t data_len_max, const char *pack_format, ...)
-{
-    int         ret;
-    va_list_obj args;
-    va_start(args.obj, pack_format);
-
-    ret = spinel_datatype_vpack_(data_out, data_len_max, pack_format, &args);
-
-    va_end(args.obj);
-    return ret;
-}
-
-spinel_ssize_t spinel_datatype_vpack(uint8_t *     data_out,
-                                     spinel_size_t data_len_max,
-                                     const char *  pack_format,
-                                     va_list       args)
-{
-    int         ret;
-    va_list_obj args_obj;
-    va_copy(args_obj.obj, args);
-
-    ret = spinel_datatype_vpack_(data_out, data_len_max, pack_format, &args_obj);
-
-    va_end(args_obj.obj);
-    return ret;
-}
-
-// ----------------------------------------------------------------------------
-// MARK: -
-
-// LCOV_EXCL_START
-
-const char *spinel_command_to_cstr(spinel_command_t command)
-{
-    const char *ret = "UNKNOWN";
-
-    switch (command)
-    {
-    case SPINEL_CMD_NOOP:
-        ret = "NOOP";
-        break;
-
-    case SPINEL_CMD_RESET:
-        ret = "RESET";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_GET:
-        ret = "PROP_VALUE_GET";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_SET:
-        ret = "PROP_VALUE_SET";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_INSERT:
-        ret = "PROP_VALUE_INSERT";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_REMOVE:
-        ret = "PROP_VALUE_REMOVE";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_IS:
-        ret = "PROP_VALUE_IS";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_INSERTED:
-        ret = "PROP_VALUE_INSERTED";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_REMOVED:
-        ret = "PROP_VALUE_REMOVED";
-        break;
-
-    case SPINEL_CMD_NET_SAVE:
-        ret = "NET_SAVE";
-        break;
-
-    case SPINEL_CMD_NET_CLEAR:
-        ret = "NET_CLEAR";
-        break;
-
-    case SPINEL_CMD_NET_RECALL:
-        ret = "NET_RECALL";
-        break;
-
-    case SPINEL_CMD_HBO_OFFLOAD:
-        ret = "HBO_OFFLOAD";
-        break;
-
-    case SPINEL_CMD_HBO_RECLAIM:
-        ret = "HBO_RECLAIM";
-        break;
-
-    case SPINEL_CMD_HBO_DROP:
-        ret = "HBO_DROP";
-        break;
-
-    case SPINEL_CMD_HBO_OFFLOADED:
-        ret = "HBO_OFFLOADED";
-        break;
-
-    case SPINEL_CMD_HBO_RECLAIMED:
-        ret = "HBO_RECLAIMED";
-        break;
-
-    case SPINEL_CMD_HBO_DROPPED:
-        ret = "HBO_DROPPED";
-        break;
-
-    case SPINEL_CMD_PEEK:
-        ret = "PEEK";
-        break;
-
-    case SPINEL_CMD_PEEK_RET:
-        ret = "PEEK_RET";
-        break;
-
-    case SPINEL_CMD_POKE:
-        ret = "POKE";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_MULTI_GET:
-        ret = "PROP_VALUE_MULTI_GET";
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_MULTI_SET:
-        ret = "PROP_VALUE_MULTI_SET";
-        break;
-
-    case SPINEL_CMD_PROP_VALUES_ARE:
-        ret = "PROP_VALUES_ARE";
-        break;
-
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
-{
-    const char *ret = "UNKNOWN";
-
-    switch (prop_key)
-    {
-    case SPINEL_PROP_LAST_STATUS:
-        ret = "LAST_STATUS";
-        break;
-
-    case SPINEL_PROP_PROTOCOL_VERSION:
-        ret = "PROTOCOL_VERSION";
-        break;
-
-    case SPINEL_PROP_NCP_VERSION:
-        ret = "NCP_VERSION";
-        break;
-
-    case SPINEL_PROP_INTERFACE_TYPE:
-        ret = "INTERFACE_TYPE";
-        break;
-
-    case SPINEL_PROP_VENDOR_ID:
-        ret = "VENDOR_ID";
-        break;
-
-    case SPINEL_PROP_CAPS:
-        ret = "CAPS";
-        break;
-
-    case SPINEL_PROP_INTERFACE_COUNT:
-        ret = "INTERFACE_COUNT";
-        break;
-
-    case SPINEL_PROP_POWER_STATE:
-        ret = "POWER_STATE";
-        break;
-
-    case SPINEL_PROP_HWADDR:
-        ret = "HWADDR";
-        break;
-
-    case SPINEL_PROP_LOCK:
-        ret = "LOCK";
-        break;
-
-    case SPINEL_PROP_HBO_MEM_MAX:
-        ret = "HBO_MEM_MAX";
-        break;
-
-    case SPINEL_PROP_HBO_BLOCK_MAX:
-        ret = "HBO_BLOCK_MAX";
-        break;
-
-    case SPINEL_PROP_HOST_POWER_STATE:
-        ret = "HOST_POWER_STATE";
-        break;
-
-    case SPINEL_PROP_MCU_POWER_STATE:
-        ret = "MCU_POWER_STATE";
-        break;
-
-    case SPINEL_PROP_GPIO_CONFIG:
-        ret = "GPIO_CONFIG";
-        break;
-
-    case SPINEL_PROP_GPIO_STATE:
-        ret = "GPIO_STATE";
-        break;
-
-    case SPINEL_PROP_GPIO_STATE_SET:
-        ret = "GPIO_STATE_SET";
-        break;
-
-    case SPINEL_PROP_GPIO_STATE_CLEAR:
-        ret = "GPIO_STATE_CLEAR";
-        break;
-
-    case SPINEL_PROP_TRNG_32:
-        ret = "TRNG_32";
-        break;
-
-    case SPINEL_PROP_TRNG_128:
-        ret = "TRNG_128";
-        break;
-
-    case SPINEL_PROP_TRNG_RAW_32:
-        ret = "TRNG_RAW_32";
-        break;
-
-    case SPINEL_PROP_UNSOL_UPDATE_FILTER:
-        ret = "UNSOL_UPDATE_FILTER";
-        break;
-
-    case SPINEL_PROP_UNSOL_UPDATE_LIST:
-        ret = "UNSOL_UPDATE_LIST";
-        break;
-
-    case SPINEL_PROP_PHY_ENABLED:
-        ret = "PHY_ENABLED";
-        break;
-
-    case SPINEL_PROP_PHY_CHAN:
-        ret = "PHY_CHAN";
-        break;
-
-    case SPINEL_PROP_PHY_CHAN_SUPPORTED:
-        ret = "PHY_CHAN_SUPPORTED";
-        break;
-
-    case SPINEL_PROP_PHY_FREQ:
-        ret = "PHY_FREQ";
-        break;
-
-    case SPINEL_PROP_PHY_CCA_THRESHOLD:
-        ret = "PHY_CCA_THRESHOLD";
-        break;
-
-    case SPINEL_PROP_PHY_TX_POWER:
-        ret = "PHY_TX_POWER";
-        break;
-
-    case SPINEL_PROP_PHY_RSSI:
-        ret = "PHY_RSSI";
-        break;
-
-    case SPINEL_PROP_PHY_RX_SENSITIVITY:
-        ret = "PHY_RX_SENSITIVITY";
-        break;
-
-    case SPINEL_PROP_PHY_PCAP_ENABLED:
-        ret = "PHY_PCAP_ENABLED";
-        break;
-
-    case SPINEL_PROP_PHY_CHAN_PREFERRED:
-        ret = "PHY_CHAN_PREFERRED";
-        break;
-
-    case SPINEL_PROP_JAM_DETECT_ENABLE:
-        ret = "JAM_DETECT_ENABLE";
-        break;
-
-    case SPINEL_PROP_JAM_DETECTED:
-        ret = "JAM_DETECTED";
-        break;
-
-    case SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD:
-        ret = "JAM_DETECT_RSSI_THRESHOLD";
-        break;
-
-    case SPINEL_PROP_JAM_DETECT_WINDOW:
-        ret = "JAM_DETECT_WINDOW";
-        break;
-
-    case SPINEL_PROP_JAM_DETECT_BUSY:
-        ret = "JAM_DETECT_BUSY";
-        break;
-
-    case SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP:
-        ret = "JAM_DETECT_HISTORY_BITMAP";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL:
-        ret = "CHANNEL_MONITOR_SAMPLE_INTERVAL";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD:
-        ret = "CHANNEL_MONITOR_RSSI_THRESHOLD";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW:
-        ret = "CHANNEL_MONITOR_SAMPLE_WINDOW";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT:
-        ret = "CHANNEL_MONITOR_SAMPLE_COUNT";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_OCCUPANCY:
-        ret = "CHANNEL_MONITOR_CHANNEL_OCCUPANCY";
-        break;
-
-    case SPINEL_PROP_RADIO_CAPS:
-        ret = "RADIO_CAPS";
-        break;
-
-    case SPINEL_PROP_RADIO_COEX_METRICS:
-        ret = "RADIO_COEX_METRICS";
-        break;
-
-    case SPINEL_PROP_RADIO_COEX_ENABLE:
-        ret = "RADIO_COEX_ENABLE";
-        break;
-
-    case SPINEL_PROP_MAC_SCAN_STATE:
-        ret = "MAC_SCAN_STATE";
-        break;
-
-    case SPINEL_PROP_MAC_SCAN_MASK:
-        ret = "MAC_SCAN_MASK";
-        break;
-
-    case SPINEL_PROP_MAC_SCAN_PERIOD:
-        ret = "MAC_SCAN_PERIOD";
-        break;
-
-    case SPINEL_PROP_MAC_SCAN_BEACON:
-        ret = "MAC_SCAN_BEACON";
-        break;
-
-    case SPINEL_PROP_MAC_15_4_LADDR:
-        ret = "MAC_15_4_LADDR";
-        break;
-
-    case SPINEL_PROP_MAC_15_4_SADDR:
-        ret = "MAC_15_4_SADDR";
-        break;
-
-    case SPINEL_PROP_MAC_15_4_PANID:
-        ret = "MAC_15_4_PANID";
-        break;
-
-    case SPINEL_PROP_MAC_RAW_STREAM_ENABLED:
-        ret = "MAC_RAW_STREAM_ENABLED";
-        break;
-
-    case SPINEL_PROP_MAC_PROMISCUOUS_MODE:
-        ret = "MAC_PROMISCUOUS_MODE";
-        break;
-
-    case SPINEL_PROP_MAC_ENERGY_SCAN_RESULT:
-        ret = "MAC_ENERGY_SCAN_RESULT";
-        break;
-
-    case SPINEL_PROP_MAC_DATA_POLL_PERIOD:
-        ret = "MAC_DATA_POLL_PERIOD";
-        break;
-
-    case SPINEL_PROP_MAC_WHITELIST:
-        ret = "MAC_WHITELIST";
-        break;
-
-    case SPINEL_PROP_MAC_WHITELIST_ENABLED:
-        ret = "MAC_WHITELIST_ENABLED";
-        break;
-
-    case SPINEL_PROP_MAC_EXTENDED_ADDR:
-        ret = "MAC_EXTENDED_ADDR";
-        break;
-
-    case SPINEL_PROP_MAC_SRC_MATCH_ENABLED:
-        ret = "MAC_SRC_MATCH_ENABLED";
-        break;
-
-    case SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES:
-        ret = "MAC_SRC_MATCH_SHORT_ADDRESSES";
-        break;
-
-    case SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES:
-        ret = "MAC_SRC_MATCH_EXTENDED_ADDRESSES";
-        break;
-
-    case SPINEL_PROP_MAC_BLACKLIST:
-        ret = "MAC_BLACKLIST";
-        break;
-
-    case SPINEL_PROP_MAC_BLACKLIST_ENABLED:
-        ret = "MAC_BLACKLIST_ENABLED";
-        break;
-
-    case SPINEL_PROP_MAC_FIXED_RSS:
-        ret = "MAC_FIXED_RSS";
-        break;
-
-    case SPINEL_PROP_MAC_CCA_FAILURE_RATE:
-        ret = "MAC_CCA_FAILURE_RATE";
-        break;
-
-    case SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT:
-        ret = "MAC_MAX_RETRY_NUMBER_DIRECT";
-        break;
-
-    case SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT:
-        ret = "MAC_MAX_RETRY_NUMBER_INDIRECT";
-        break;
-
-    case SPINEL_PROP_NET_SAVED:
-        ret = "NET_SAVED";
-        break;
-
-    case SPINEL_PROP_NET_IF_UP:
-        ret = "NET_IF_UP";
-        break;
-
-    case SPINEL_PROP_NET_STACK_UP:
-        ret = "NET_STACK_UP";
-        break;
-
-    case SPINEL_PROP_NET_ROLE:
-        ret = "NET_ROLE";
-        break;
-
-    case SPINEL_PROP_NET_NETWORK_NAME:
-        ret = "NET_NETWORK_NAME";
-        break;
-
-    case SPINEL_PROP_NET_XPANID:
-        ret = "NET_XPANID";
-        break;
-
-    case SPINEL_PROP_NET_MASTER_KEY:
-        ret = "NET_MASTER_KEY";
-        break;
-
-    case SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER:
-        ret = "NET_KEY_SEQUENCE_COUNTER";
-        break;
-
-    case SPINEL_PROP_NET_PARTITION_ID:
-        ret = "NET_PARTITION_ID";
-        break;
-
-    case SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING:
-        ret = "NET_REQUIRE_JOIN_EXISTING";
-        break;
-
-    case SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME:
-        ret = "NET_KEY_SWITCH_GUARDTIME";
-        break;
-
-    case SPINEL_PROP_NET_PSKC:
-        ret = "NET_PSKC";
-        break;
-
-    case SPINEL_PROP_THREAD_LEADER_ADDR:
-        ret = "THREAD_LEADER_ADDR";
-        break;
-
-    case SPINEL_PROP_THREAD_PARENT:
-        ret = "THREAD_PARENT";
-        break;
-
-    case SPINEL_PROP_THREAD_CHILD_TABLE:
-        ret = "THREAD_CHILD_TABLE";
-        break;
-
-    case SPINEL_PROP_THREAD_LEADER_RID:
-        ret = "THREAD_LEADER_RID";
-        break;
-
-    case SPINEL_PROP_THREAD_LEADER_WEIGHT:
-        ret = "THREAD_LEADER_WEIGHT";
-        break;
-
-    case SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT:
-        ret = "THREAD_LOCAL_LEADER_WEIGHT";
-        break;
-
-    case SPINEL_PROP_THREAD_NETWORK_DATA:
-        ret = "THREAD_NETWORK_DATA";
-        break;
-
-    case SPINEL_PROP_THREAD_NETWORK_DATA_VERSION:
-        ret = "THREAD_NETWORK_DATA_VERSION";
-        break;
-
-    case SPINEL_PROP_THREAD_STABLE_NETWORK_DATA:
-        ret = "THREAD_STABLE_NETWORK_DATA";
-        break;
-
-    case SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION:
-        ret = "THREAD_STABLE_NETWORK_DATA_VERSION";
-        break;
-
-    case SPINEL_PROP_THREAD_ON_MESH_NETS:
-        ret = "THREAD_ON_MESH_NETS";
-        break;
-
-    case SPINEL_PROP_THREAD_OFF_MESH_ROUTES:
-        ret = "THREAD_OFF_MESH_ROUTES";
-        break;
-
-    case SPINEL_PROP_THREAD_ASSISTING_PORTS:
-        ret = "THREAD_ASSISTING_PORTS";
-        break;
-
-    case SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE:
-        ret = "THREAD_ALLOW_LOCAL_NET_DATA_CHANGE";
-        break;
-
-    case SPINEL_PROP_THREAD_MODE:
-        ret = "THREAD_MODE";
-        break;
-
-    case SPINEL_PROP_THREAD_CHILD_TIMEOUT:
-        ret = "THREAD_CHILD_TIMEOUT";
-        break;
-
-    case SPINEL_PROP_THREAD_RLOC16:
-        ret = "THREAD_RLOC16";
-        break;
-
-    case SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD:
-        ret = "THREAD_ROUTER_UPGRADE_THRESHOLD";
-        break;
-
-    case SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY:
-        ret = "THREAD_CONTEXT_REUSE_DELAY";
-        break;
-
-    case SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT:
-        ret = "THREAD_NETWORK_ID_TIMEOUT";
-        break;
-
-    case SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS:
-        ret = "THREAD_ACTIVE_ROUTER_IDS";
-        break;
-
-    case SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU:
-        ret = "THREAD_RLOC16_DEBUG_PASSTHRU";
-        break;
-
-    case SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED:
-        ret = "THREAD_ROUTER_ROLE_ENABLED";
-        break;
-
-    case SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD:
-        ret = "THREAD_ROUTER_DOWNGRADE_THRESHOLD";
-        break;
-
-    case SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER:
-        ret = "THREAD_ROUTER_SELECTION_JITTER";
-        break;
-
-    case SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID:
-        ret = "THREAD_PREFERRED_ROUTER_ID";
-        break;
-
-    case SPINEL_PROP_THREAD_NEIGHBOR_TABLE:
-        ret = "THREAD_NEIGHBOR_TABLE";
-        break;
-
-    case SPINEL_PROP_THREAD_CHILD_COUNT_MAX:
-        ret = "THREAD_CHILD_COUNT_MAX";
-        break;
-
-    case SPINEL_PROP_THREAD_LEADER_NETWORK_DATA:
-        ret = "THREAD_LEADER_NETWORK_DATA";
-        break;
-
-    case SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA:
-        ret = "THREAD_STABLE_LEADER_NETWORK_DATA";
-        break;
-
-    case SPINEL_PROP_THREAD_JOINERS:
-        ret = "THREAD_JOINERS";
-        break;
-
-    case SPINEL_PROP_THREAD_COMMISSIONER_ENABLED:
-        ret = "THREAD_COMMISSIONER_ENABLED";
-        break;
-
-    case SPINEL_PROP_THREAD_TMF_PROXY_ENABLED:
-        ret = "THREAD_TMF_PROXY_ENABLED";
-        break;
-
-    case SPINEL_PROP_THREAD_TMF_PROXY_STREAM:
-        ret = "THREAD_TMF_PROXY_STREAM";
-        break;
-
-    case SPINEL_PROP_THREAD_UDP_FORWARD_STREAM:
-        ret = "THREAD_UDP_FORWARD_STREAM";
-        break;
-
-    case SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG:
-        ret = "THREAD_DISCOVERY_SCAN_JOINER_FLAG";
-        break;
-
-    case SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING:
-        ret = "THREAD_DISCOVERY_SCAN_ENABLE_FILTERING";
-        break;
-
-    case SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID:
-        ret = "THREAD_DISCOVERY_SCAN_PANID";
-        break;
-
-    case SPINEL_PROP_THREAD_STEERING_DATA:
-        ret = "THREAD_STEERING_DATA";
-        break;
-
-    case SPINEL_PROP_THREAD_ROUTER_TABLE:
-        ret = "THREAD_ROUTER_TABLE";
-        break;
-
-    case SPINEL_PROP_THREAD_ACTIVE_DATASET:
-        ret = "THREAD_ACTIVE_DATASET";
-        break;
-
-    case SPINEL_PROP_THREAD_PENDING_DATASET:
-        ret = "THREAD_PENDING_DATASET";
-        break;
-
-    case SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET:
-        ret = "THREAD_MGMT_SET_ACTIVE_DATASET";
-        break;
-
-    case SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET:
-        ret = "THREAD_MGMT_SET_PENDING_DATASET";
-        break;
-
-    case SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP:
-        ret = "DATASET_ACTIVE_TIMESTAMP";
-        break;
-
-    case SPINEL_PROP_DATASET_PENDING_TIMESTAMP:
-        ret = "DATASET_PENDING_TIMESTAMP";
-        break;
-
-    case SPINEL_PROP_DATASET_DELAY_TIMER:
-        ret = "DATASET_DELAY_TIMER";
-        break;
-
-    case SPINEL_PROP_DATASET_SECURITY_POLICY:
-        ret = "DATASET_SECURITY_POLICY";
-        break;
-
-    case SPINEL_PROP_DATASET_RAW_TLVS:
-        ret = "DATASET_RAW_TLVS";
-        break;
-
-    case SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES:
-        ret = "THREAD_CHILD_TABLE_ADDRESSES";
-        break;
-
-    case SPINEL_PROP_THREAD_NEIGHBOR_TABLE_ERROR_RATES:
-        ret = "THREAD_NEIGHBOR_TABLE_ERROR_RATES";
-        break;
-
-    case SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE:
-        ret = "THREAD_ADDRESS_CACHE_TABLE";
-        break;
-
-    case SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET:
-        ret = "THREAD_MGMT_GET_ACTIVE_DATASET";
-        break;
-
-    case SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET:
-        ret = "THREAD_MGMT_GET_PENDING_DATASET";
-        break;
-
-    case SPINEL_PROP_DATASET_DEST_ADDRESS:
-        ret = "DATASET_DEST_ADDRESS";
-        break;
-
-    case SPINEL_PROP_THREAD_NEW_DATASET:
-        ret = "THREAD_NEW_DATASET";
-        break;
-
-    case SPINEL_PROP_MESHCOP_JOINER_STATE:
-        ret = "MESHCOP_JOINER_STATE";
-        break;
-
-    case SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING:
-        ret = "MESHCOP_JOINER_COMMISSIONING";
-        break;
-
-    case SPINEL_PROP_IPV6_LL_ADDR:
-        ret = "IPV6_LL_ADDR";
-        break;
-
-    case SPINEL_PROP_IPV6_ML_ADDR:
-        ret = "IPV6_ML_ADDR";
-        break;
-
-    case SPINEL_PROP_IPV6_ML_PREFIX:
-        ret = "IPV6_ML_PREFIX";
-        break;
-
-    case SPINEL_PROP_IPV6_ADDRESS_TABLE:
-        ret = "IPV6_ADDRESS_TABLE";
-        break;
-
-    case SPINEL_PROP_IPV6_ROUTE_TABLE:
-        ret = "IPV6_ROUTE_TABLE";
-        break;
-
-    case SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD:
-        ret = "IPV6_ICMP_PING_OFFLOAD";
-        break;
-
-    case SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE:
-        ret = "IPV6_MULTICAST_ADDRESS_TABLE";
-        break;
-
-    case SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE:
-        ret = "IPV6_ICMP_PING_OFFLOAD_MODE";
-        break;
-
-    case SPINEL_PROP_STREAM_DEBUG:
-        ret = "STREAM_DEBUG";
-        break;
-
-    case SPINEL_PROP_STREAM_RAW:
-        ret = "STREAM_RAW";
-        break;
-
-    case SPINEL_PROP_STREAM_NET:
-        ret = "STREAM_NET";
-        break;
-
-    case SPINEL_PROP_STREAM_NET_INSECURE:
-        ret = "STREAM_NET_INSECURE";
-        break;
-
-    case SPINEL_PROP_STREAM_LOG:
-        ret = "STREAM_LOG";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_STATE:
-        ret = "MESHCOP_COMMISSIONER_STATE";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS:
-        ret = "MESHCOP_COMMISSIONER_JOINERS";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL:
-        ret = "MESHCOP_COMMISSIONER_PROVISIONING_URL";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID:
-        ret = "MESHCOP_COMMISSIONER_SESSION_ID";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN:
-        ret = "MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN:
-        ret = "MESHCOP_COMMISSIONER_ENERGY_SCAN";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT:
-        ret = "MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY:
-        ret = "MESHCOP_COMMISSIONER_PAN_ID_QUERY";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT:
-        ret = "MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_GET:
-        ret = "MESHCOP_COMMISSIONER_MGMT_GET";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_SET:
-        ret = "MESHCOP_COMMISSIONER_MGMT_SET";
-        break;
-
-    case SPINEL_PROP_MESHCOP_COMMISSIONER_GENERATE_PSKC:
-        ret = "MESHCOP_COMMISSIONER_GENERATE_PSKC";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL:
-        ret = "CHANNEL_MANAGER_NEW_CHANNEL";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MANAGER_DELAY:
-        ret = "CHANNEL_MANAGER_DELAY";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS:
-        ret = "CHANNEL_MANAGER_SUPPORTED_CHANNELS";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS:
-        ret = "CHANNEL_MANAGER_FAVORED_CHANNELS";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT:
-        ret = "CHANNEL_MANAGER_CHANNEL_SELECT";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED:
-        ret = "CHANNEL_MANAGER_AUTO_SELECT_ENABLED";
-        break;
-
-    case SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL:
-        ret = "CHANNEL_MANAGER_AUTO_SELECT_INTERVAL";
-        break;
-
-    case SPINEL_PROP_THREAD_NETWORK_TIME:
-        ret = "THREAD_NETWORK_TIME";
-        break;
-
-    case SPINEL_PROP_TIME_SYNC_PERIOD:
-        ret = "TIME_SYNC_PERIOD";
-        break;
-
-    case SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD:
-        ret = "TIME_SYNC_XTAL_THRESHOLD";
-        break;
-
-    case SPINEL_PROP_CHILD_SUPERVISION_INTERVAL:
-        ret = "CHILD_SUPERVISION_INTERVAL";
-        break;
-
-    case SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT:
-        ret = "CHILD_SUPERVISION_CHECK_TIMEOUT";
-        break;
-
-    case SPINEL_PROP_RCP_VERSION:
-        ret = "RCP_VERSION";
-        break;
-
-    case SPINEL_PROP_PARENT_RESPONSE_INFO:
-        ret = "PARENT_RESPONSE_INFO";
-        break;
-
-    case SPINEL_PROP_SLAAC_ENABLED:
-        ret = "SLAAC_ENABLED";
-        break;
-
-    case SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE:
-        ret = "SERVER_ALLOW_LOCAL_DATA_CHANGE";
-        break;
-
-    case SPINEL_PROP_SERVER_SERVICES:
-        ret = "SERVER_SERVICES";
-        break;
-
-    case SPINEL_PROP_SERVER_LEADER_SERVICES:
-        ret = "SERVER_LEADER_SERVICES";
-        break;
-
-    case SPINEL_PROP_UART_BITRATE:
-        ret = "UART_BITRATE";
-        break;
-
-    case SPINEL_PROP_UART_XON_XOFF:
-        ret = "UART_XON_XOFF";
-        break;
-
-    case SPINEL_PROP_15_4_PIB_PHY_CHANNELS_SUPPORTED:
-        ret = "15_4_PIB_PHY_CHANNELS_SUPPORTED";
-        break;
-
-    case SPINEL_PROP_15_4_PIB_MAC_PROMISCUOUS_MODE:
-        ret = "15_4_PIB_MAC_PROMISCUOUS_MODE";
-        break;
-
-    case SPINEL_PROP_15_4_PIB_MAC_SECURITY_ENABLED:
-        ret = "15_4_PIB_MAC_SECURITY_ENABLED";
-        break;
-
-    case SPINEL_PROP_CNTR_RESET:
-        ret = "CNTR_RESET";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_TOTAL:
-        ret = "CNTR_TX_PKT_TOTAL";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_ACK_REQ:
-        ret = "CNTR_TX_PKT_ACK_REQ";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_ACKED:
-        ret = "CNTR_TX_PKT_ACKED";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_NO_ACK_REQ:
-        ret = "CNTR_TX_PKT_NO_ACK_REQ";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_DATA:
-        ret = "CNTR_TX_PKT_DATA";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_DATA_POLL:
-        ret = "CNTR_TX_PKT_DATA_POLL";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_BEACON:
-        ret = "CNTR_TX_PKT_BEACON";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_BEACON_REQ:
-        ret = "CNTR_TX_PKT_BEACON_REQ";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_OTHER:
-        ret = "CNTR_TX_PKT_OTHER";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_RETRY:
-        ret = "CNTR_TX_PKT_RETRY";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_ERR_CCA:
-        ret = "CNTR_TX_ERR_CCA";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_UNICAST:
-        ret = "CNTR_TX_PKT_UNICAST";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_PKT_BROADCAST:
-        ret = "CNTR_TX_PKT_BROADCAST";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_ERR_ABORT:
-        ret = "CNTR_TX_ERR_ABORT";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_TOTAL:
-        ret = "CNTR_RX_PKT_TOTAL";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_DATA:
-        ret = "CNTR_RX_PKT_DATA";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_DATA_POLL:
-        ret = "CNTR_RX_PKT_DATA_POLL";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_BEACON:
-        ret = "CNTR_RX_PKT_BEACON";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_BEACON_REQ:
-        ret = "CNTR_RX_PKT_BEACON_REQ";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_OTHER:
-        ret = "CNTR_RX_PKT_OTHER";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_FILT_WL:
-        ret = "CNTR_RX_PKT_FILT_WL";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_FILT_DA:
-        ret = "CNTR_RX_PKT_FILT_DA";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_ERR_EMPTY:
-        ret = "CNTR_RX_ERR_EMPTY";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_ERR_UKWN_NBR:
-        ret = "CNTR_RX_ERR_UKWN_NBR";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_ERR_NVLD_SADDR:
-        ret = "CNTR_RX_ERR_NVLD_SADDR";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_ERR_SECURITY:
-        ret = "CNTR_RX_ERR_SECURITY";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_ERR_BAD_FCS:
-        ret = "CNTR_RX_ERR_BAD_FCS";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_ERR_OTHER:
-        ret = "CNTR_RX_ERR_OTHER";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_DUP:
-        ret = "CNTR_RX_PKT_DUP";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_UNICAST:
-        ret = "CNTR_RX_PKT_UNICAST";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_PKT_BROADCAST:
-        ret = "CNTR_RX_PKT_BROADCAST";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL:
-        ret = "CNTR_TX_IP_SEC_TOTAL";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL:
-        ret = "CNTR_TX_IP_INSEC_TOTAL";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_IP_DROPPED:
-        ret = "CNTR_TX_IP_DROPPED";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_IP_SEC_TOTAL:
-        ret = "CNTR_RX_IP_SEC_TOTAL";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_IP_INSEC_TOTAL:
-        ret = "CNTR_RX_IP_INSEC_TOTAL";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_IP_DROPPED:
-        ret = "CNTR_RX_IP_DROPPED";
-        break;
-
-    case SPINEL_PROP_CNTR_TX_SPINEL_TOTAL:
-        ret = "CNTR_TX_SPINEL_TOTAL";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_SPINEL_TOTAL:
-        ret = "CNTR_RX_SPINEL_TOTAL";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_SPINEL_ERR:
-        ret = "CNTR_RX_SPINEL_ERR";
-        break;
-
-    case SPINEL_PROP_CNTR_RX_SPINEL_OUT_OF_ORDER_TID:
-        ret = "CNTR_RX_SPINEL_OUT_OF_ORDER_TID";
-        break;
-
-    case SPINEL_PROP_CNTR_IP_TX_SUCCESS:
-        ret = "CNTR_IP_TX_SUCCESS";
-        break;
-
-    case SPINEL_PROP_CNTR_IP_RX_SUCCESS:
-        ret = "CNTR_IP_RX_SUCCESS";
-        break;
-
-    case SPINEL_PROP_CNTR_IP_TX_FAILURE:
-        ret = "CNTR_IP_TX_FAILURE";
-        break;
-
-    case SPINEL_PROP_CNTR_IP_RX_FAILURE:
-        ret = "CNTR_IP_RX_FAILURE";
-        break;
-
-    case SPINEL_PROP_MSG_BUFFER_COUNTERS:
-        ret = "MSG_BUFFER_COUNTERS";
-        break;
-
-    case SPINEL_PROP_CNTR_ALL_MAC_COUNTERS:
-        ret = "CNTR_ALL_MAC_COUNTERS";
-        break;
-
-    case SPINEL_PROP_CNTR_MLE_COUNTERS:
-        ret = "CNTR_MLE_COUNTERS";
-        break;
-
-    case SPINEL_PROP_CNTR_ALL_IP_COUNTERS:
-        ret = "CNTR_ALL_IP_COUNTERS";
-        break;
-
-    case SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM:
-        ret = "CNTR_MAC_RETRY_HISTOGRAM";
-        break;
-
-    case SPINEL_PROP_NEST_STREAM_MFG:
-        ret = "NEST_STREAM_MFG";
-        break;
-
-    case SPINEL_PROP_NEST_LEGACY_ULA_PREFIX:
-        ret = "NEST_LEGACY_ULA_PREFIX";
-        break;
-
-    case SPINEL_PROP_NEST_LEGACY_LAST_NODE_JOINED:
-        ret = "NEST_LEGACY_LAST_NODE_JOINED";
-        break;
-
-    case SPINEL_PROP_DEBUG_TEST_ASSERT:
-        ret = "DEBUG_TEST_ASSERT";
-        break;
-
-    case SPINEL_PROP_DEBUG_NCP_LOG_LEVEL:
-        ret = "DEBUG_NCP_LOG_LEVEL";
-        break;
-
-    case SPINEL_PROP_DEBUG_TEST_WATCHDOG:
-        ret = "DEBUG_TEST_WATCHDOG";
-        break;
-
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-const char *spinel_net_role_to_cstr(uint8_t net_role)
-{
-    const char *ret = "NET_ROLE_UNKNONW";
-
-    switch (net_role)
-    {
-    case SPINEL_NET_ROLE_DETACHED:
-        ret = "NET_ROLE_DETACHED";
-        break;
-
-    case SPINEL_NET_ROLE_CHILD:
-        ret = "NET_ROLE_CHILD";
-        break;
-
-    case SPINEL_NET_ROLE_ROUTER:
-        ret = "NET_ROLE_ROUTER";
-        break;
-
-    case SPINEL_NET_ROLE_LEADER:
-        ret = "NET_ROLE_LEADER";
-        break;
-
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-const char *spinel_mcu_power_state_to_cstr(uint8_t mcu_power_state)
-{
-    const char *ret = "MCU_POWER_STATE_UNKNOWN";
-
-    switch (mcu_power_state)
-    {
-    case SPINEL_MCU_POWER_STATE_ON:
-        ret = "MCU_POWER_STATE_ON";
-        break;
-
-    case SPINEL_MCU_POWER_STATE_LOW_POWER:
-        ret = "MCU_POWER_STATE_LOW_POWER";
-        break;
-
-    case SPINEL_MCU_POWER_STATE_OFF:
-        ret = "MCU_POWER_STATE_OFF";
-        break;
-
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-const char *spinel_status_to_cstr(spinel_status_t status)
-{
-    const char *ret = "UNKNOWN";
-
-    switch (status)
-    {
-    case SPINEL_STATUS_OK:
-        ret = "OK";
-        break;
-
-    case SPINEL_STATUS_FAILURE:
-        ret = "FAILURE";
-        break;
-
-    case SPINEL_STATUS_UNIMPLEMENTED:
-        ret = "UNIMPLEMENTED";
-        break;
-
-    case SPINEL_STATUS_INVALID_ARGUMENT:
-        ret = "INVALID_ARGUMENT";
-        break;
-
-    case SPINEL_STATUS_INVALID_STATE:
-        ret = "INVALID_STATE";
-        break;
-
-    case SPINEL_STATUS_INVALID_COMMAND:
-        ret = "INVALID_COMMAND";
-        break;
-
-    case SPINEL_STATUS_INVALID_INTERFACE:
-        ret = "INVALID_INTERFACE";
-        break;
-
-    case SPINEL_STATUS_INTERNAL_ERROR:
-        ret = "INTERNAL_ERROR";
-        break;
-
-    case SPINEL_STATUS_SECURITY_ERROR:
-        ret = "SECURITY_ERROR";
-        break;
-
-    case SPINEL_STATUS_PARSE_ERROR:
-        ret = "PARSE_ERROR";
-        break;
-
-    case SPINEL_STATUS_IN_PROGRESS:
-        ret = "IN_PROGRESS";
-        break;
-
-    case SPINEL_STATUS_NOMEM:
-        ret = "NOMEM";
-        break;
-
-    case SPINEL_STATUS_BUSY:
-        ret = "BUSY";
-        break;
-
-    case SPINEL_STATUS_PROP_NOT_FOUND:
-        ret = "PROP_NOT_FOUND";
-        break;
-
-    case SPINEL_STATUS_DROPPED:
-        ret = "DROPPED";
-        break;
-
-    case SPINEL_STATUS_EMPTY:
-        ret = "EMPTY";
-        break;
-
-    case SPINEL_STATUS_CMD_TOO_BIG:
-        ret = "CMD_TOO_BIG";
-        break;
-
-    case SPINEL_STATUS_NO_ACK:
-        ret = "NO_ACK";
-        break;
-
-    case SPINEL_STATUS_CCA_FAILURE:
-        ret = "CCA_FAILURE";
-        break;
-
-    case SPINEL_STATUS_ALREADY:
-        ret = "ALREADY";
-        break;
-
-    case SPINEL_STATUS_ITEM_NOT_FOUND:
-        ret = "ITEM_NOT_FOUND";
-        break;
-
-    case SPINEL_STATUS_INVALID_COMMAND_FOR_PROP:
-        ret = "INVALID_COMMAND_FOR_PROP";
-        break;
-
-    case SPINEL_STATUS_JOIN_FAILURE:
-        ret = "JOIN_FAILURE";
-        break;
-
-    case SPINEL_STATUS_JOIN_SECURITY:
-        ret = "JOIN_SECURITY";
-        break;
-
-    case SPINEL_STATUS_JOIN_NO_PEERS:
-        ret = "JOIN_NO_PEERS";
-        break;
-
-    case SPINEL_STATUS_JOIN_INCOMPATIBLE:
-        ret = "JOIN_INCOMPATIBLE";
-        break;
-
-    case SPINEL_STATUS_JOIN_RSP_TIMEOUT:
-        ret = "JOIN_RSP_TIMEOUT";
-        break;
-
-    case SPINEL_STATUS_JOIN_SUCCESS:
-        ret = "JOIN_SUCCESS";
-        break;
-
-    case SPINEL_STATUS_RESET_POWER_ON:
-        ret = "RESET_POWER_ON";
-        break;
-
-    case SPINEL_STATUS_RESET_EXTERNAL:
-        ret = "RESET_EXTERNAL";
-        break;
-
-    case SPINEL_STATUS_RESET_SOFTWARE:
-        ret = "RESET_SOFTWARE";
-        break;
-
-    case SPINEL_STATUS_RESET_FAULT:
-        ret = "RESET_FAULT";
-        break;
-
-    case SPINEL_STATUS_RESET_CRASH:
-        ret = "RESET_CRASH";
-        break;
-
-    case SPINEL_STATUS_RESET_ASSERT:
-        ret = "RESET_ASSERT";
-        break;
-
-    case SPINEL_STATUS_RESET_OTHER:
-        ret = "RESET_OTHER";
-        break;
-
-    case SPINEL_STATUS_RESET_UNKNOWN:
-        ret = "RESET_UNKNOWN";
-        break;
-
-    case SPINEL_STATUS_RESET_WATCHDOG:
-        ret = "RESET_WATCHDOG";
-        break;
-
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-const char *spinel_capability_to_cstr(spinel_capability_t capability)
-{
-    const char *ret = "UNKNOWN";
-
-    switch (capability)
-    {
-    case SPINEL_CAP_LOCK:
-        ret = "LOCK";
-        break;
-
-    case SPINEL_CAP_NET_SAVE:
-        ret = "NET_SAVE";
-        break;
-
-    case SPINEL_CAP_HBO:
-        ret = "HBO";
-        break;
-
-    case SPINEL_CAP_POWER_SAVE:
-        ret = "POWER_SAVE";
-        break;
-
-    case SPINEL_CAP_COUNTERS:
-        ret = "COUNTERS";
-        break;
-
-    case SPINEL_CAP_JAM_DETECT:
-        ret = "JAM_DETECT";
-        break;
-
-    case SPINEL_CAP_PEEK_POKE:
-        ret = "PEEK_POKE";
-        break;
-
-    case SPINEL_CAP_WRITABLE_RAW_STREAM:
-        ret = "WRITABLE_RAW_STREAM";
-        break;
-
-    case SPINEL_CAP_GPIO:
-        ret = "GPIO";
-        break;
-
-    case SPINEL_CAP_TRNG:
-        ret = "TRNG";
-        break;
-
-    case SPINEL_CAP_CMD_MULTI:
-        ret = "CMD_MULTI";
-        break;
-
-    case SPINEL_CAP_UNSOL_UPDATE_FILTER:
-        ret = "UNSOL_UPDATE_FILTER";
-        break;
-
-    case SPINEL_CAP_MCU_POWER_STATE:
-        ret = "MCU_POWER_STATE";
-        break;
-
-    case SPINEL_CAP_PCAP:
-        ret = "PCAP";
-        break;
-
-    case SPINEL_CAP_802_15_4_2003:
-        ret = "802_15_4_2003";
-        break;
-
-    case SPINEL_CAP_802_15_4_2006:
-        ret = "802_15_4_2006";
-        break;
-
-    case SPINEL_CAP_802_15_4_2011:
-        ret = "802_15_4_2011";
-        break;
-
-    case SPINEL_CAP_802_15_4_PIB:
-        ret = "802_15_4_PIB";
-        break;
-
-    case SPINEL_CAP_802_15_4_2450MHZ_OQPSK:
-        ret = "802_15_4_2450MHZ_OQPSK";
-        break;
-
-    case SPINEL_CAP_802_15_4_915MHZ_OQPSK:
-        ret = "802_15_4_915MHZ_OQPSK";
-        break;
-
-    case SPINEL_CAP_802_15_4_868MHZ_OQPSK:
-        ret = "802_15_4_868MHZ_OQPSK";
-        break;
-
-    case SPINEL_CAP_802_15_4_915MHZ_BPSK:
-        ret = "802_15_4_915MHZ_BPSK";
-        break;
-
-    case SPINEL_CAP_802_15_4_868MHZ_BPSK:
-        ret = "802_15_4_868MHZ_BPSK";
-        break;
-
-    case SPINEL_CAP_802_15_4_915MHZ_ASK:
-        ret = "802_15_4_915MHZ_ASK";
-        break;
-
-    case SPINEL_CAP_802_15_4_868MHZ_ASK:
-        ret = "802_15_4_868MHZ_ASK";
-        break;
-
-    case SPINEL_CAP_CONFIG_FTD:
-        ret = "CONFIG_FTD";
-        break;
-
-    case SPINEL_CAP_CONFIG_MTD:
-        ret = "CONFIG_MTD";
-        break;
-
-    case SPINEL_CAP_CONFIG_RADIO:
-        ret = "CONFIG_RADIO";
-        break;
-
-    case SPINEL_CAP_ROLE_ROUTER:
-        ret = "ROLE_ROUTER";
-        break;
-
-    case SPINEL_CAP_ROLE_SLEEPY:
-        ret = "ROLE_SLEEPY";
-        break;
-
-    case SPINEL_CAP_NET_THREAD_1_0:
-        ret = "NET_THREAD_1_0";
-        break;
-
-    case SPINEL_CAP_NET_THREAD_1_1:
-        ret = "NET_THREAD_1_1";
-        break;
-
-    case SPINEL_CAP_MAC_WHITELIST:
-        ret = "MAC_WHITELIST";
-        break;
-
-    case SPINEL_CAP_MAC_RAW:
-        ret = "MAC_RAW";
-        break;
-
-    case SPINEL_CAP_OOB_STEERING_DATA:
-        ret = "OOB_STEERING_DATA";
-        break;
-
-    case SPINEL_CAP_CHANNEL_MONITOR:
-        ret = "CHANNEL_MONITOR";
-        break;
-
-    case SPINEL_CAP_CHANNEL_MANAGER:
-        ret = "CHANNEL_MANAGER";
-        break;
-
-    case SPINEL_CAP_OPENTHREAD_LOG_METADATA:
-        ret = "OPENTHREAD_LOG_METADATA";
-        break;
-
-    case SPINEL_CAP_TIME_SYNC:
-        ret = "TIME_SYNC";
-        break;
-
-    case SPINEL_CAP_CHILD_SUPERVISION:
-        ret = "CHILD_SUPERVISION";
-        break;
-
-    case SPINEL_CAP_POSIX_APP:
-        ret = "POSIX_APP";
-        break;
-
-    case SPINEL_CAP_SLAAC:
-        ret = "SLAAC";
-        break;
-
-    case SPINEL_CAP_RADIO_COEX:
-        ret = "RADIO_COEX";
-        break;
-
-    case SPINEL_CAP_MAC_RETRY_HISTOGRAM:
-        ret = "MAC_RETRY_HISTOGRAM";
-        break;
-
-    case SPINEL_CAP_ERROR_RATE_TRACKING:
-        ret = "ERROR_RATE_TRACKING";
-        break;
-
-    case SPINEL_CAP_THREAD_COMMISSIONER:
-        ret = "THREAD_COMMISSIONER";
-        break;
-
-    case SPINEL_CAP_THREAD_TMF_PROXY:
-        ret = "THREAD_TMF_PROXY";
-        break;
-
-    case SPINEL_CAP_THREAD_UDP_FORWARD:
-        ret = "THREAD_UDP_FORWARD";
-        break;
-
-    case SPINEL_CAP_THREAD_JOINER:
-        ret = "THREAD_JOINER";
-        break;
-
-    case SPINEL_CAP_THREAD_BORDER_ROUTER:
-        ret = "THREAD_BORDER_ROUTER";
-        break;
-
-    case SPINEL_CAP_THREAD_SERVICE:
-        ret = "THREAD_SERVICE";
-        break;
-
-    case SPINEL_CAP_NEST_LEGACY_INTERFACE:
-        ret = "NEST_LEGACY_INTERFACE";
-        break;
-
-    case SPINEL_CAP_NEST_LEGACY_NET_WAKE:
-        ret = "NEST_LEGACY_NET_WAKE";
-        break;
-
-    case SPINEL_CAP_NEST_TRANSMIT_HOOK:
-        ret = "NEST_TRANSMIT_HOOK";
-        break;
-
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-// LCOV_EXCL_STOP
-
-/* -------------------------------------------------------------------------- */
-
-#if SPINEL_SELF_TEST
-
-int main(void)
-{
-    int                  ret             = -1;
-    const spinel_eui64_t static_eui64    = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}};
-    const char           static_string[] = "static_string";
-    uint8_t              buffer[1024];
-    ssize_t              len;
-
-    len =
-        spinel_datatype_pack(buffer, sizeof(buffer), "CiiLUE", 0x88, 9, 0xA3, 0xDEADBEEF, static_string, &static_eui64);
-
-    if (len != 30)
-    {
-        printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
-        goto bail;
-    }
-
-    {
-        const char *str = NULL;
-
-        // Length ends right before the string.
-        len = spinel_datatype_unpack(buffer, 8, "CiiLU", NULL, NULL, NULL, NULL, &str);
-
-        if (len != -1)
-        {
-            printf("error:%d: len != -1; (%d)\n", __LINE__, (int)len);
-            goto bail;
-        }
-
-        if (str != NULL)
-        {
-            printf("error:%d: str != NULL\n", __LINE__);
-            goto bail;
-        }
-    }
-
-    len = 30;
-
-    {
-        uint8_t               c     = 0;
-        unsigned int          i1    = 0;
-        unsigned int          i2    = 0;
-        uint32_t              l     = 0;
-        const char *          str   = NULL;
-        const spinel_eui64_t *eui64 = NULL;
-
-        len = spinel_datatype_unpack(buffer, (spinel_size_t)len, "CiiLUE", &c, &i1, &i2, &l, &str, &eui64);
-
-        if (len != 30)
-        {
-            printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
-            goto bail;
-        }
-
-        if (c != 0x88)
-        {
-            printf("error: x != 0x88; (%d)\n", c);
-            goto bail;
-        }
-
-        if (i1 != 9)
-        {
-            printf("error: i1 != 9; (%d)\n", i1);
-            goto bail;
-        }
-
-        if (i2 != 0xA3)
-        {
-            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
-            goto bail;
-        }
-
-        if (l != 0xDEADBEEF)
-        {
-            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
-            goto bail;
-        }
-
-        if (strcmp(str, static_string) != 0)
-        {
-            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
-            goto bail;
-        }
-
-        if (memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
-        {
-            printf("error:%d: memcmp(eui64, &eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
-            goto bail;
-        }
-    }
-
-    {
-        uint8_t        c  = 0;
-        unsigned int   i1 = 0;
-        unsigned int   i2 = 0;
-        uint32_t       l  = 0;
-        char           str[sizeof(static_string)];
-        spinel_eui64_t eui64 = {{0}};
-
-        len = spinel_datatype_unpack_in_place(buffer, (spinel_size_t)len, "CiiLUE", &c, &i1, &i2, &l, &str, sizeof(str),
-                                              &eui64);
-
-        if (len != 30)
-        {
-            printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
-            goto bail;
-        }
-
-        if (c != 0x88)
-        {
-            printf("error: x != 0x88; (%d)\n", c);
-            goto bail;
-        }
-
-        if (i1 != 9)
-        {
-            printf("error: i1 != 9; (%d)\n", i1);
-            goto bail;
-        }
-
-        if (i2 != 0xA3)
-        {
-            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
-            goto bail;
-        }
-
-        if (l != 0xDEADBEEF)
-        {
-            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
-            goto bail;
-        }
-
-        if (strcmp(str, static_string) != 0)
-        {
-            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
-            goto bail;
-        }
-
-        if (memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
-        {
-            printf("error:%d: memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
-            goto bail;
-        }
-    }
-
-    // -----------------------------------
-
-    memset(buffer, 0xAA, sizeof(buffer));
-
-    len = spinel_datatype_pack(buffer, sizeof(buffer), "Cit(iL)UE", 0x88, 9, 0xA3, 0xDEADBEEF, static_string,
-                               &static_eui64);
-
-    if (len != 32)
-    {
-        printf("error:%d: len != 32; (%d)\n", __LINE__, (int)len);
-        goto bail;
-    }
-
-    {
-        uint8_t         c     = 0;
-        unsigned int    i1    = 0;
-        unsigned int    i2    = 0;
-        uint32_t        l     = 0;
-        const char *    str   = NULL;
-        spinel_eui64_t *eui64 = NULL;
-
-        len = spinel_datatype_unpack(buffer, (spinel_size_t)len, "Cit(iL)UE", &c, &i1, &i2, &l, &str, &eui64);
-
-        if (len != 32)
-        {
-            printf("error:%d: len != 24; (%d)\n", __LINE__, (int)len);
-            goto bail;
-        }
-
-        if (c != 0x88)
-        {
-            printf("error: x != 0x88; (%d)\n", c);
-            goto bail;
-        }
-
-        if (i1 != 9)
-        {
-            printf("error: i1 != 9; (%d)\n", i1);
-            goto bail;
-        }
-
-        if (i2 != 0xA3)
-        {
-            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
-            goto bail;
-        }
-
-        if (l != 0xDEADBEEF)
-        {
-            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
-            goto bail;
-        }
-
-        if (strcmp(str, static_string) != 0)
-        {
-            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
-            goto bail;
-        }
-
-        if (memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
-        {
-            printf("error:%d: memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
-            goto bail;
-        }
-    }
-
-    {
-        uint8_t        c  = 0;
-        unsigned int   i1 = 0;
-        unsigned int   i2 = 0;
-        uint32_t       l  = 0;
-        char           str[sizeof(static_string)];
-        spinel_eui64_t eui64 = {{0}};
-
-        len = spinel_datatype_unpack_in_place(buffer, (spinel_size_t)len, "Cit(iL)UE", &c, &i1, &i2, &l, &str,
-                                              sizeof(str), &eui64);
-
-        if (len != 32)
-        {
-            printf("error:%d: len != 24; (%d)\n", __LINE__, (int)len);
-            goto bail;
-        }
-
-        if (c != 0x88)
-        {
-            printf("error: x != 0x88; (%d)\n", c);
-            goto bail;
-        }
-
-        if (i1 != 9)
-        {
-            printf("error: i1 != 9; (%d)\n", i1);
-            goto bail;
-        }
-
-        if (i2 != 0xA3)
-        {
-            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
-            goto bail;
-        }
-
-        if (l != 0xDEADBEEF)
-        {
-            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
-            goto bail;
-        }
-
-        if (strcmp(str, static_string) != 0)
-        {
-            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
-            goto bail;
-        }
-
-        if (memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
-        {
-            printf("error:%d: memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
-            goto bail;
-        }
-    }
-
-    {
-        // Test UTF8 validation - Good/Valid strings
-
-        // Single symbols
-        const uint8_t single1[] = {0};                            // 0000
-        const uint8_t single2[] = {0x7F, 0x00};                   // 007F
-        const uint8_t single3[] = {0xC2, 0x80, 0x00};             // 080
-        const uint8_t single4[] = {0xDF, 0xBF, 0x00};             // 07FF
-        const uint8_t single5[] = {0xE0, 0xA0, 0x80, 0x00};       // 0800
-        const uint8_t single6[] = {0xEF, 0xBF, 0xBF, 0x00};       // FFFF
-        const uint8_t single7[] = {0xF0, 0x90, 0x80, 0x80, 0x00}; // 010000
-        const uint8_t single8[] = {0xF4, 0x8F, 0xBF, 0xBF, 0x00}; // 10FFFF
-
-        // Strings
-        const uint8_t str1[] = "spinel";
-        const uint8_t str2[] = "OpenThread";
-        const uint8_t str3[] = {0x41, 0x7F, 0xEF, 0xBF, 0xBF, 0xC2, 0x80, 0x21, 0x33, 0x00};
-        const uint8_t str4[] = {0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xB5, 0x00}; // κόσμε
-        const uint8_t str5[] = {0x3D, 0xF4, 0x8F, 0xBF, 0xBF, 0x01, 0xE0, 0xA0, 0x83, 0x22, 0xEF, 0xBF, 0xBF, 0x00};
-        const uint8_t str6[] = {0xE5, 0xA2, 0x82, 0xE0, 0xA0, 0x80, 0xC2, 0x83, 0xC2, 0x80, 0xF4,
-                                0x8F, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 0xBF, 0xDF, 0xBF, 0x21, 0x00};
-
-        const uint8_t * good_strings[] = {single1, single2, single3, single4, single5, single6, single7, single8,
-                                         str1,    str2,    str3,    str4,    str5,    str6,    NULL};
-        const uint8_t **str_ptr;
-
-        for (str_ptr = &good_strings[0]; *str_ptr != NULL; str_ptr++)
-        {
-            if (!spinel_validate_utf8(*str_ptr))
-            {
-                printf("error: spinel_validate_utf8() did not correctly detect a valid UTF8 sequence!\n");
-                goto bail;
-            }
-        }
-    }
-
-    {
-        // Test UTF8 validation - Bad/Invalid strings
-
-        // Single symbols (invalid)
-        const uint8_t single1[] = {0xF8, 0x00};
-        const uint8_t single2[] = {0xF9, 0x00};
-        const uint8_t single3[] = {0xFA, 0x00};
-        const uint8_t single4[] = {0xFF, 0x00};
-
-        // Bad continuations
-        const uint8_t bad1[] = {0xDF, 0x0F, 0x00};
-        const uint8_t bad2[] = {0xE0, 0xA0, 0x10, 0x00};
-        const uint8_t bad3[] = {0xF0, 0x90, 0x80, 0x60, 0x00};
-        const uint8_t bad4[] = {0xF4, 0x8F, 0xBF, 0x0F, 0x00};
-        const uint8_t bad5[] = {0x21, 0xA0, 0x00};
-        const uint8_t bad6[] = {0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0x00};
-
-        const uint8_t * bad_strings[] = {single1, single2, single3, single4, bad1, bad2, bad3, bad4, bad5, bad6, NULL};
-        const uint8_t **str_ptr;
-
-        for (str_ptr = &bad_strings[0]; *str_ptr != NULL; str_ptr++)
-        {
-            if (spinel_validate_utf8(*str_ptr))
-            {
-                printf("error: spinel_validate_utf8() did not correctly detect an invalid UTF8 sequence\n");
-                goto bail;
-            }
-        }
-    }
-
-    printf("OK\n");
-    ret = 0;
-    return ret;
-
-bail:
-    printf("FAILURE\n");
-    return ret;
-}
-
-#endif // #if SPINEL_SELF_TEST
diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h
deleted file mode 100644
index c96d792..0000000
--- a/src/ncp/spinel.h
+++ /dev/null
@@ -1,4141 +0,0 @@
-/*
- *    Copyright (c) 2016, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file contains definitions of spinel.
- */
-
-#ifndef SPINEL_HEADER_INCLUDED
-#define SPINEL_HEADER_INCLUDED 1
-
-/*
- *   Spinel is a host-controller protocol designed to enable
- *   inter-operation over simple serial connections between general purpose
- *   device operating systems (OS) host and network co-processors (NCP) for
- *   the purpose of controlling and managing the NCP.
- *
- * ---------------------------------------------------------------------------
- *
- *   Frame Format
- *
- *   A frame is defined simply as the concatenation of
- *
- *   -  A header byte
- *   -  A command (up to three bytes)
- *   -  An optional command payload
- *
- *              +---------+--------+-----+-------------+
- *              | Octets: |   1    | 1-3 |      n      |
- *              +---------+--------+-----+-------------+
- *              | Fields: | HEADER | CMD | CMD_PAYLOAD |
- *              +---------+--------+-----+-------------+
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- *
- *   Header Format
- *
- *   The header byte is broken down as follows:
- *
- *                    0   1   2   3   4   5   6   7
- *                  +---+---+---+---+---+---+---+---+
- *                  |  FLG  |  IID  |      TID      |
- *                  +---+---+---+---+---+---+---+---+
- *
- *
- *   The flag field of the header byte ("FLG") is always set to the value
- *   two (or "10" in binary).  Any frame received with these bits set to
- *   any other value else MUST NOT be considered a Spinel frame.
- *
- *   This convention allows Spinel to be line compatible with BTLE HCI.
- *   By defining the first two bit in this way we can disambiguate between
- *   Spinel frames and HCI frames (which always start with either "0x01"
- *   or "0x04") without any additional framing overhead.
- *
- *   The Interface Identifier (IID) is a number between 0 and 3, which
- *   is associated by the OS with a specific NCP. This allows the protocol
- *   to support up to 4 NCPs under same connection.
- *
- *   The least significant bits of the header represent the Transaction
- *   Identifier (TID). The TID is used for correlating responses to the
- *   commands which generated them.
- *
- *   When a command is sent from the host, any reply to that command sent
- *   by the NCP will use the same value for the TID.  When the host
- *   receives a frame that matches the TID of the command it sent, it can
- *   easily recognize that frame as the actual response to that command.
- *
- *   The TID value of zero (0) is used for commands to which a correlated
- *   response is not expected or needed, such as for unsolicited update
- *   commands sent to the host from the NCP.
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- *
- *   The command identifier is a 21-bit unsigned integer encoded in up to
- *   three bytes using the packed unsigned integer format described below.
- *   Depending on the semantics of the command in question, a payload MAY
- *   be included in the frame.  The exact composition and length of the
- *   payload is defined by the command identifier.
- *
- * ---------------------------------------------------------------------------
- *
- *   Data Packing
- *
- *   Data serialization for properties is performed using a light-weight
- *   data packing format which was loosely inspired by D-Bus.  The format
- *   of a serialization is defined by a specially formatted string.
- *
- *   This packing format is used for notational convenience.  While this
- *   string-based data-type format has been designed so that the strings
- *   may be directly used by a structured data parser, such a thing is not
- *   required to implement Spinel.
- *
- *   Goals:
- *
- *   -  Be lightweight and favor direct representation of values.
- *   -  Use an easily readable and memorable format string.
- *   -  Support lists and structures.
- *   -  Allow properties to be appended to structures while maintaining
- *      backward compatibility.
- *
- *   Each primitive data-type has an ASCII character associated with it.
- *   Structures can be represented as strings of these characters.  For
- *   example:
- *
- *   -  "C": A single unsigned byte.
- *   -  "C6U": A single unsigned byte, followed by a 128-bit IPv6 address,
- *      followed by a zero-terminated UTF8 string.
- *   -  "A(6)": An array of concatenated IPv6 addresses
- *
- *   In each case, the data is represented exactly as described.  For
- *   example, an array of 10 IPv6 address is stored as 160 bytes.
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- *
- *   Primitive Types
- *
- *   +----------+----------------------+---------------------------------+
- *   |   Char   | Name                 | Description                     |
- *   +----------+----------------------+---------------------------------+
- *   |   "."    | DATATYPE_VOID        | Empty data type. Used           |
- *   |          |                      | internally.                     |
- *   |   "b"    | DATATYPE_BOOL        | Boolean value. Encoded in       |
- *   |          |                      | 8-bits as either 0x00 or 0x01.  |
- *   |          |                      | All other values are illegal.   |
- *   |   "C"    | DATATYPE_UINT8       | Unsigned 8-bit integer.         |
- *   |   "c"    | DATATYPE_INT8        | Signed 8-bit integer.           |
- *   |   "S"    | DATATYPE_UINT16      | Unsigned 16-bit integer.        |
- *   |   "s"    | DATATYPE_INT16       | Signed 16-bit integer.          |
- *   |   "L"    | DATATYPE_UINT32      | Unsigned 32-bit integer.        |
- *   |   "l"    | DATATYPE_INT32       | Signed 32-bit integer.          |
- *   |   "i"    | DATATYPE_UINT_PACKED | Packed Unsigned Integer. See    |
- *   |          |                      | description below               |
- *   |   "6"    | DATATYPE_IPv6ADDR    | IPv6 Address. (Big-endian)      |
- *   |   "E"    | DATATYPE_EUI64       | EUI-64 Address. (Big-endian)    |
- *   |   "e"    | DATATYPE_EUI48       | EUI-48 Address. (Big-endian)    |
- *   |   "D"    | DATATYPE_DATA        | Arbitrary data. See related     |
- *   |          |                      | section below for details.      |
- *   |   "d"    | DATATYPE_DATA_WLEN   | Arbitrary data with prepended   |
- *   |          |                      | length. See below for details   |
- *   |   "U"    | DATATYPE_UTF8        | Zero-terminated UTF8-encoded    |
- *   |          |                      | string.                         |
- *   | "t(...)" | DATATYPE_STRUCT      | Structured datatype with        |
- *   |          |                      | prepended length.               |
- *   | "A(...)" | DATATYPE_ARRAY       | Array of datatypes. Compound    |
- *   |          |                      | type.                           |
- *   +----------+----------------------+---------------------------------+
- *
- *   All multi-byte values are little-endian unless explicitly stated
- *   otherwise.
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- *
- *   Packed Unsigned Integer
- *
- *   For certain types of integers, such command or property identifiers,
- *   usually have a value on the wire that is less than 127.  However, in
- *   order to not preclude the use of values larger than 255, we would
- *   need to add an extra byte.  Doing this would add an extra byte to the
- *   majority of instances, which can add up in terms of bandwidth.
- *
- *   The packed unsigned integer format is based on the unsigned integer
- *   format in EXI, except that we limit the maximum value to the
- *   largest value that can be encoded into three bytes (2,097,151).
- *
- *   For all values less than 127, the packed form of the number is simply
- *   a single byte which directly represents the number.  For values
- *   larger than 127, the following process is used to encode the value:
- *
- *   1.  The unsigned integer is broken up into _n_ 7-bit chunks and
- *       placed into _n_ octets, leaving the most significant bit of each
- *       octet unused.
- *   2.  Order the octets from least-significant to most-significant.
- *       (Little-endian)
- *   3.  Clear the most significant bit of the most significant octet.
- *       Set the least significant bit on all other octets.
- *
- *   Where `n` is the smallest number of 7-bit chunks you can use to
- *   represent the given value.
- *
- *   Take the value 1337, for example:
- *
- *                              1337 => 0x0539
- *                                   => [39 0A]
- *                                   => [B9 0A]
- *
- *   To decode the value, you collect the 7-bit chunks until you find an
- *   octet with the most significant bit clear.
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- *
- *   Data Blobs
- *
- *   There are two types for data blobs: "d" and "D".
- *
- *   -  "d" has the length of the data (in bytes) prepended to the data
- *      (with the length encoded as type "S").  The size of the length
- *      field is not included in the length.
- *   -  "D" does not have a prepended length: the length of the data is
- *      implied by the bytes remaining to be parsed.  It is an error for
- *      "D" to not be the last type in a type in a type signature.
- *
- *   This dichotomy allows for more efficient encoding by eliminating
- *   redundancy.  If the rest of the buffer is a data blob, encoding the
- *   length would be redundant because we already know how many bytes are
- *   in the rest of the buffer.
- *
- *   In some cases we use "d" even if it is the last field in a type
- *   signature.  We do this to allow for us to be able to append
- *   additional fields to the type signature if necessary in the future.
- *   This is usually the case with embedded structs, like in the scan
- *   results.
- *
- *   For example, let's say we have a buffer that is encoded with the
- *   datatype signature of "CLLD".  In this case, it is pretty easy to
- *   tell where the start and end of the data blob is: the start is 9
- *   bytes from the start of the buffer, and its length is the length of
- *   the buffer minus 9. (9 is the number of bytes taken up by a byte and
- *   two longs)
- *
- *   The datatype signature "CLLDU" is illegal because we can't determine
- *   where the last field (a zero-terminated UTF8 string) starts.  But the
- *   datatype "CLLdU" is legal, because the parser can determine the
- *   exact length of the data blob-- allowing it to know where the start
- *   of the next field would be.
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- *
- *   Structured Data
- *
- *   The structure data type ("t(...)") is a way of bundling together
- *   several fields into a single structure.  It can be thought of as a
- *   "d" type except that instead of being opaque, the fields in the
- *   content are known.  This is useful for things like scan results where
- *   you have substructures which are defined by different layers.
- *
- *   For example, consider the type signature "Lt(ES)t(6C)".  In this
- *   hypothetical case, the first struct is defined by the MAC layer, and
- *   the second struct is defined by the PHY layer.  Because of the use of
- *   structures, we know exactly what part comes from that layer.
- *   Additionally, we can add fields to each structure without introducing
- *   backward compatability problems: Data encoded as "Lt(ESU)t(6C)"
- *   (Notice the extra "U") will decode just fine as "Lt(ES)t(6C)".
- *   Additionally, if we don't care about the MAC layer and only care
- *   about the network layer, we could parse as "Lt()t(6C)".
- *
- *   Note that data encoded as "Lt(ES)t(6C)" will also parse as "Ldd",
- *   with the structures from both layers now being opaque data blobs.
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- *
- *   Arrays
- *
- *   An array is simply a concatenated set of _n_ data encodings.  For
- *   example, the type "A(6)" is simply a list of IPv6 addresses---one
- *   after the other.  The type "A(6E)" likewise a concatenation of IPv6-
- *   address/EUI-64 pairs.
- *
- *   If an array contains many fields, the fields will often be surrounded
- *   by a structure ("t(...)").  This effectively prepends each item in
- *   the array with its length.  This is useful for improving parsing
- *   performance or to allow additional fields to be added in the future
- *   in a backward compatible way.  If there is a high certainty that
- *   additional fields will never be added, the struct may be omitted
- *   (saving two bytes per item).
- *
- *   This specification does not define a way to embed an array as a field
- *   alongside other fields.
- *
- * ---------------------------------------------------------------------------
- *
- *   Spinel definition guideline:
- *
- *   New NCP firmware should work with an older host driver, i.e., NCP
- *   implementation should remain backward compatible.
- *
- *    - Existing fields in the format of an already implemented spinel
- *      property or command cannot change.
- *
- *    - New fields may be appended at the end of the format (or the end of
- *      a struct) as long as the NCP implementation treats the new fields as
- *      optional (i.e., a driver not aware of and therefore not using the
- *      new fields should continue to function as before).
- *
- * ---------------------------------------------------------------------------
- */
-
-#ifdef SPINEL_PLATFORM_HEADER
-#include SPINEL_PLATFORM_HEADER
-#else // ifdef SPINEL_PLATFORM_HEADER
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#endif // else SPINEL_PLATFORM_HEADER
-
-// ----------------------------------------------------------------------------
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-#if defined(__GNUC__)
-#define SPINEL_API_EXTERN extern __attribute__((visibility("default")))
-#define SPINEL_API_NONNULL_ALL __attribute__((nonnull))
-#define SPINEL_API_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
-#endif // ifdef __GNUC__
-
-#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-#ifndef SPINEL_API_EXTERN
-#define SPINEL_API_EXTERN extern
-#endif
-
-#ifndef SPINEL_API_NONNULL_ALL
-#define SPINEL_API_NONNULL_ALL
-#endif
-
-#ifndef SPINEL_API_WARN_UNUSED_RESULT
-#define SPINEL_API_WARN_UNUSED_RESULT
-#endif
-
-// ----------------------------------------------------------------------------
-
-#define SPINEL_PROTOCOL_VERSION_THREAD_MAJOR 4
-#define SPINEL_PROTOCOL_VERSION_THREAD_MINOR 3
-
-#define SPINEL_FRAME_MAX_SIZE 1300
-
-/**
- * @def SPINEL_ENCRYPTER_EXTRA_DATA_SIZE
- *
- *  The size of extra data to be allocated for spinel frame buffer,
- *  needed by Spinel Encrypter.
- *
- */
-#define SPINEL_ENCRYPTER_EXTRA_DATA_SIZE 0
-
-/**
- * @def SPINEL_FRAME_BUFFER_SIZE
- *
- *  The size of buffer large enough to fit one whole spinel frame with extra data
- *  needed by Spinel Encrypter.
- *
- */
-#define SPINEL_FRAME_BUFFER_SIZE (SPINEL_FRAME_MAX_SIZE + SPINEL_ENCRYPTER_EXTRA_DATA_SIZE)
-
-/// Macro for generating bit masks using bit index from the spec
-#define SPINEL_BIT_MASK(bit_index, field_bit_count) ((1 << ((field_bit_count)-1)) >> (bit_index))
-
-// ----------------------------------------------------------------------------
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-enum
-{
-    SPINEL_STATUS_OK                       = 0,  ///< Operation has completed successfully.
-    SPINEL_STATUS_FAILURE                  = 1,  ///< Operation has failed for some undefined reason.
-    SPINEL_STATUS_UNIMPLEMENTED            = 2,  ///< Given operation has not been implemented.
-    SPINEL_STATUS_INVALID_ARGUMENT         = 3,  ///< An argument to the operation is invalid.
-    SPINEL_STATUS_INVALID_STATE            = 4,  ///< This operation is invalid for the current device state.
-    SPINEL_STATUS_INVALID_COMMAND          = 5,  ///< This command is not recognized.
-    SPINEL_STATUS_INVALID_INTERFACE        = 6,  ///< This interface is not supported.
-    SPINEL_STATUS_INTERNAL_ERROR           = 7,  ///< An internal runtime error has occured.
-    SPINEL_STATUS_SECURITY_ERROR           = 8,  ///< A security/authentication error has occured.
-    SPINEL_STATUS_PARSE_ERROR              = 9,  ///< A error has occured while parsing the command.
-    SPINEL_STATUS_IN_PROGRESS              = 10, ///< This operation is in progress.
-    SPINEL_STATUS_NOMEM                    = 11, ///< Operation prevented due to memory pressure.
-    SPINEL_STATUS_BUSY                     = 12, ///< The device is currently performing a mutually exclusive operation
-    SPINEL_STATUS_PROP_NOT_FOUND           = 13, ///< The given property is not recognized.
-    SPINEL_STATUS_DROPPED                  = 14, ///< A/The packet was dropped.
-    SPINEL_STATUS_EMPTY                    = 15, ///< The result of the operation is empty.
-    SPINEL_STATUS_CMD_TOO_BIG              = 16, ///< The command was too large to fit in the internal buffer.
-    SPINEL_STATUS_NO_ACK                   = 17, ///< The packet was not acknowledged.
-    SPINEL_STATUS_CCA_FAILURE              = 18, ///< The packet was not sent due to a CCA failure.
-    SPINEL_STATUS_ALREADY                  = 19, ///< The operation is already in progress.
-    SPINEL_STATUS_ITEM_NOT_FOUND           = 20, ///< The given item could not be found.
-    SPINEL_STATUS_INVALID_COMMAND_FOR_PROP = 21, ///< The given command cannot be performed on this property.
-
-    SPINEL_STATUS_JOIN__BEGIN = 104,
-
-    /// Generic failure to associate with other peers.
-    /**
-     *  This status error should not be used by implementors if
-     *  enough information is available to determine that one of the
-     *  later join failure status codes would be more accurate.
-     *
-     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
-     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
-     */
-    SPINEL_STATUS_JOIN_FAILURE = SPINEL_STATUS_JOIN__BEGIN + 0,
-
-    /// The node found other peers but was unable to decode their packets.
-    /**
-     *  Typically this error code indicates that the network
-     *  key has been set incorrectly.
-     *
-     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
-     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
-     */
-    SPINEL_STATUS_JOIN_SECURITY = SPINEL_STATUS_JOIN__BEGIN + 1,
-
-    /// The node was unable to find any other peers on the network.
-    /**
-     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
-     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
-     */
-    SPINEL_STATUS_JOIN_NO_PEERS = SPINEL_STATUS_JOIN__BEGIN + 2,
-
-    /// The only potential peer nodes found are incompatible.
-    /**
-     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
-     */
-    SPINEL_STATUS_JOIN_INCOMPATIBLE = SPINEL_STATUS_JOIN__BEGIN + 3,
-
-    /// No response in expecting time.
-    /**
-     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
-     */
-    SPINEL_STATUS_JOIN_RSP_TIMEOUT = SPINEL_STATUS_JOIN__BEGIN + 4,
-
-    /// The node succeeds in commissioning and get the network credentials.
-    /**
-     *  \sa SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING
-     */
-    SPINEL_STATUS_JOIN_SUCCESS = SPINEL_STATUS_JOIN__BEGIN + 5,
-
-    SPINEL_STATUS_JOIN__END = 112,
-
-    SPINEL_STATUS_RESET__BEGIN   = 112,
-    SPINEL_STATUS_RESET_POWER_ON = SPINEL_STATUS_RESET__BEGIN + 0,
-    SPINEL_STATUS_RESET_EXTERNAL = SPINEL_STATUS_RESET__BEGIN + 1,
-    SPINEL_STATUS_RESET_SOFTWARE = SPINEL_STATUS_RESET__BEGIN + 2,
-    SPINEL_STATUS_RESET_FAULT    = SPINEL_STATUS_RESET__BEGIN + 3,
-    SPINEL_STATUS_RESET_CRASH    = SPINEL_STATUS_RESET__BEGIN + 4,
-    SPINEL_STATUS_RESET_ASSERT   = SPINEL_STATUS_RESET__BEGIN + 5,
-    SPINEL_STATUS_RESET_OTHER    = SPINEL_STATUS_RESET__BEGIN + 6,
-    SPINEL_STATUS_RESET_UNKNOWN  = SPINEL_STATUS_RESET__BEGIN + 7,
-    SPINEL_STATUS_RESET_WATCHDOG = SPINEL_STATUS_RESET__BEGIN + 8,
-    SPINEL_STATUS_RESET__END     = 128,
-
-    SPINEL_STATUS_VENDOR__BEGIN = 15360,
-    SPINEL_STATUS_VENDOR__END   = 16384,
-
-    SPINEL_STATUS_STACK_NATIVE__BEGIN = 16384,
-    SPINEL_STATUS_STACK_NATIVE__END   = 81920,
-
-    SPINEL_STATUS_EXPERIMENTAL__BEGIN = 2000000,
-    SPINEL_STATUS_EXPERIMENTAL__END   = 2097152,
-};
-
-typedef uint32_t spinel_status_t;
-
-typedef enum
-{
-    SPINEL_NET_ROLE_DETACHED = 0,
-    SPINEL_NET_ROLE_CHILD    = 1,
-    SPINEL_NET_ROLE_ROUTER   = 2,
-    SPINEL_NET_ROLE_LEADER   = 3,
-} spinel_net_role_t;
-
-typedef enum
-{
-    SPINEL_IPV6_ICMP_PING_OFFLOAD_DISABLED       = 0,
-    SPINEL_IPV6_ICMP_PING_OFFLOAD_UNICAST_ONLY   = 1,
-    SPINEL_IPV6_ICMP_PING_OFFLOAD_MULTICAST_ONLY = 2,
-    SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL            = 3,
-} spinel_ipv6_icmp_ping_offload_mode_t;
-
-typedef enum
-{
-    SPINEL_SCAN_STATE_IDLE     = 0,
-    SPINEL_SCAN_STATE_BEACON   = 1,
-    SPINEL_SCAN_STATE_ENERGY   = 2,
-    SPINEL_SCAN_STATE_DISCOVER = 3,
-} spinel_scan_state_t;
-
-typedef enum
-{
-    SPINEL_MCU_POWER_STATE_ON        = 0,
-    SPINEL_MCU_POWER_STATE_LOW_POWER = 1,
-    SPINEL_MCU_POWER_STATE_OFF       = 2,
-} spinel_mcu_power_state_t;
-
-// The `spinel_power_state_t` enumeration and `POWER_STATE`
-// property are deprecated. Please use `MCU_POWER_STATE`
-// instead.
-typedef enum
-{
-    SPINEL_POWER_STATE_OFFLINE    = 0,
-    SPINEL_POWER_STATE_DEEP_SLEEP = 1,
-    SPINEL_POWER_STATE_STANDBY    = 2,
-    SPINEL_POWER_STATE_LOW_POWER  = 3,
-    SPINEL_POWER_STATE_ONLINE     = 4,
-} spinel_power_state_t;
-
-typedef enum
-{
-    SPINEL_HOST_POWER_STATE_OFFLINE    = 0,
-    SPINEL_HOST_POWER_STATE_DEEP_SLEEP = 1,
-    SPINEL_HOST_POWER_STATE_RESERVED   = 2,
-    SPINEL_HOST_POWER_STATE_LOW_POWER  = 3,
-    SPINEL_HOST_POWER_STATE_ONLINE     = 4,
-} spinel_host_power_state_t;
-
-typedef enum
-{
-    SPINEL_MESHCOP_JOINER_STATE_IDLE       = 0,
-    SPINEL_MESHCOP_JOINER_STATE_DISCOVER   = 1,
-    SPINEL_MESHCOP_JOINER_STATE_CONNECTING = 2,
-    SPINEL_MESHCOP_JOINER_STATE_CONNECTED  = 3,
-    SPINEL_MESHCOP_JOINER_STATE_ENTRUST    = 4,
-    SPINEL_MESHCOP_JOINER_STATE_JOINED     = 5,
-} spinel_meshcop_joiner_state_t;
-
-enum
-{
-    SPINEL_NET_FLAG_ON_MESH       = (1 << 0),
-    SPINEL_NET_FLAG_DEFAULT_ROUTE = (1 << 1),
-    SPINEL_NET_FLAG_CONFIGURE     = (1 << 2),
-    SPINEL_NET_FLAG_DHCP          = (1 << 3),
-    SPINEL_NET_FLAG_SLAAC         = (1 << 4),
-    SPINEL_NET_FLAG_PREFERRED     = (1 << 5),
-
-    SPINEL_NET_FLAG_PREFERENCE_OFFSET = 6,
-    SPINEL_NET_FLAG_PREFERENCE_MASK   = (3 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
-};
-
-enum
-{
-    SPINEL_ROUTE_PREFERENCE_HIGH   = (1 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
-    SPINEL_ROUTE_PREFERENCE_MEDIUM = (0 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
-    SPINEL_ROUTE_PREFERENCE_LOW    = (3 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
-};
-
-enum
-{
-    SPINEL_THREAD_MODE_FULL_NETWORK_DATA   = (1 << 0),
-    SPINEL_THREAD_MODE_FULL_THREAD_DEV     = (1 << 1),
-    SPINEL_THREAD_MODE_SECURE_DATA_REQUEST = (1 << 2),
-    SPINEL_THREAD_MODE_RX_ON_WHEN_IDLE     = (1 << 3),
-};
-
-enum
-{
-    SPINEL_GPIO_FLAG_DIR_INPUT       = 0,
-    SPINEL_GPIO_FLAG_DIR_OUTPUT      = SPINEL_BIT_MASK(0, 8),
-    SPINEL_GPIO_FLAG_PULL_UP         = SPINEL_BIT_MASK(1, 8),
-    SPINEL_GPIO_FLAG_PULL_DOWN       = SPINEL_BIT_MASK(2, 8),
-    SPINEL_GPIO_FLAG_OPEN_DRAIN      = SPINEL_BIT_MASK(2, 8),
-    SPINEL_GPIO_FLAG_TRIGGER_NONE    = 0,
-    SPINEL_GPIO_FLAG_TRIGGER_RISING  = SPINEL_BIT_MASK(3, 8),
-    SPINEL_GPIO_FLAG_TRIGGER_FALLING = SPINEL_BIT_MASK(4, 8),
-    SPINEL_GPIO_FLAG_TRIGGER_ANY     = SPINEL_GPIO_FLAG_TRIGGER_RISING | SPINEL_GPIO_FLAG_TRIGGER_FALLING,
-};
-
-enum
-{
-    SPINEL_PROTOCOL_TYPE_BOOTLOADER = 0,
-    SPINEL_PROTOCOL_TYPE_ZIGBEE_IP  = 2,
-    SPINEL_PROTOCOL_TYPE_THREAD     = 3,
-};
-
-enum
-{
-    SPINEL_MAC_PROMISCUOUS_MODE_OFF     = 0, ///< Normal MAC filtering is in place.
-    SPINEL_MAC_PROMISCUOUS_MODE_NETWORK = 1, ///< All MAC packets matching network are passed up the stack.
-    SPINEL_MAC_PROMISCUOUS_MODE_FULL    = 2, ///< All decoded MAC packets are passed up the stack.
-};
-
-enum
-{
-    SPINEL_NCP_LOG_LEVEL_EMERG  = 0,
-    SPINEL_NCP_LOG_LEVEL_ALERT  = 1,
-    SPINEL_NCP_LOG_LEVEL_CRIT   = 2,
-    SPINEL_NCP_LOG_LEVEL_ERR    = 3,
-    SPINEL_NCP_LOG_LEVEL_WARN   = 4,
-    SPINEL_NCP_LOG_LEVEL_NOTICE = 5,
-    SPINEL_NCP_LOG_LEVEL_INFO   = 6,
-    SPINEL_NCP_LOG_LEVEL_DEBUG  = 7,
-};
-
-enum
-{
-    SPINEL_NCP_LOG_REGION_NONE        = 0,
-    SPINEL_NCP_LOG_REGION_OT_API      = 1,
-    SPINEL_NCP_LOG_REGION_OT_MLE      = 2,
-    SPINEL_NCP_LOG_REGION_OT_ARP      = 3,
-    SPINEL_NCP_LOG_REGION_OT_NET_DATA = 4,
-    SPINEL_NCP_LOG_REGION_OT_ICMP     = 5,
-    SPINEL_NCP_LOG_REGION_OT_IP6      = 6,
-    SPINEL_NCP_LOG_REGION_OT_MAC      = 7,
-    SPINEL_NCP_LOG_REGION_OT_MEM      = 8,
-    SPINEL_NCP_LOG_REGION_OT_NCP      = 9,
-    SPINEL_NCP_LOG_REGION_OT_MESH_COP = 10,
-    SPINEL_NCP_LOG_REGION_OT_NET_DIAG = 11,
-    SPINEL_NCP_LOG_REGION_OT_PLATFORM = 12,
-    SPINEL_NCP_LOG_REGION_OT_COAP     = 13,
-    SPINEL_NCP_LOG_REGION_OT_CLI      = 14,
-    SPINEL_NCP_LOG_REGION_OT_CORE     = 15,
-    SPINEL_NCP_LOG_REGION_OT_UTIL     = 16,
-};
-
-enum
-{
-    SPINEL_MESHCOP_COMMISSIONER_STATE_DISABLED = 0,
-    SPINEL_MESHCOP_COMMISSIONER_STATE_PETITION = 1,
-    SPINEL_MESHCOP_COMMISSIONER_STATE_ACTIVE   = 2,
-};
-
-typedef struct
-{
-    uint8_t bytes[8];
-} spinel_eui64_t;
-
-typedef struct
-{
-    uint8_t bytes[8];
-} spinel_net_xpanid_t;
-
-typedef struct
-{
-    uint8_t bytes[16];
-} spinel_net_pskc_t;
-
-typedef struct
-{
-    uint8_t bytes[6];
-} spinel_eui48_t;
-
-typedef struct
-{
-    uint8_t bytes[16];
-} spinel_ipv6addr_t;
-
-typedef int          spinel_ssize_t;
-typedef unsigned int spinel_size_t;
-typedef uint8_t      spinel_tid_t;
-
-enum
-{
-    SPINEL_MD_FLAG_TX       = 0x0001, //!< Packet was transmitted, not received.
-    SPINEL_MD_FLAG_BAD_FCS  = 0x0004, //!< Packet was received with bad FCS
-    SPINEL_MD_FLAG_DUPE     = 0x0008, //!< Packet seems to be a duplicate
-    SPINEL_MD_FLAG_ACKED_FP = 0x0010, //!< Packet was acknowledged with frame pending set
-    SPINEL_MD_FLAG_RESERVED = 0xFFE2, //!< Flags reserved for future use.
-};
-
-enum
-{
-    /**
-     * No-Operation command (Host -> NCP)
-     *
-     * Encoding: Empty
-     *
-     * Induces the NCP to send a success status back to the host. This is
-     * primarily used for liveliness checks. The command payload for this
-     * command SHOULD be empty.
-     *
-     * There is no error condition for this command.
-     *
-     */
-    SPINEL_CMD_NOOP = 0,
-
-    /**
-     * Reset NCP command (Host -> NCP)
-     *
-     * Encoding: Empty
-     *
-     * Causes the NCP to perform a software reset. Due to the nature of
-     * this command, the TID is ignored. The host should instead wait
-     * for a `CMD_PROP_VALUE_IS` command from the NCP indicating
-     * `PROP_LAST_STATUS` has been set to `STATUS_RESET_SOFTWARE`.
-     *
-     * The command payload for this command SHOULD be empty.
-     *
-     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
-     * instead with the value set to the generated status code for the error.
-     *
-     */
-    SPINEL_CMD_RESET = 1,
-
-    /**
-     * Get property value command (Host -> NCP)
-     *
-     * Encoding: `i`
-     *   `i` : Property Id
-     *
-     * Causes the NCP to emit a `CMD_PROP_VALUE_IS` command for the
-     * given property identifier.
-     *
-     * The payload for this command is the property identifier encoded
-     * in the packed unsigned integer format `i`.
-     *
-     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
-     * instead with the value set to the generated status code for the error.
-     *
-     */
-    SPINEL_CMD_PROP_VALUE_GET = 2,
-
-    /**
-     * Set property value command (Host -> NCP)
-     *
-     * Encoding: `iD`
-     *   `i` : Property Id
-     *   `D` : Value (encoding depends on the property)
-     *
-     * Instructs the NCP to set the given property to the specific given
-     * value, replacing any previous value.
-     *
-     * The payload for this command is the property identifier encoded in the
-     * packed unsigned integer format, followed by the property value. The
-     * exact format of the property value is defined by the property.
-     *
-     * On success a `CMD_PROP_VALUE_IS` command is emitted either for the
-     * given property identifier with the set value, or for `PROP_LAST_STATUS`
-     * with value `LAST_STATUS_OK`.
-     *
-     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
-     * with the value set to the generated status code for the error.
-     *
-     */
-    SPINEL_CMD_PROP_VALUE_SET = 3,
-
-    /**
-     * Insert value into property command (Host -> NCP)
-     *
-     * Encoding: `iD`
-     *   `i` : Property Id
-     *   `D` : Value (encoding depends on the property)
-     *
-     * Instructs the NCP to insert the given value into a list-oriented
-     * property without removing other items in the list. The resulting order
-     * of items in the list is defined by the individual property being
-     * operated on.
-     *
-     * The payload for this command is the property identifier encoded in the
-     * packed unsigned integer format, followed by the value to be inserted.
-     * The exact format of the value is defined by the property.
-     *
-     * If the type signature of the property consists of a single structure
-     * enclosed by an array `A(t(...))`, then the contents of value MUST
-     * contain the contents of the structure (`...`) rather than the
-     * serialization of the whole item (`t(...)`).  Specifically, the length
-     * of the structure MUST NOT be prepended to value. This helps to
-     * eliminate redundant data.
-     *
-     * On success, either a `CMD_PROP_VALUE_INSERTED` command is emitted for
-     * the given property, or a `CMD_PROP_VALUE_IS` command is emitted of
-     * property `PROP_LAST_STATUS` with value `LAST_STATUS_OK`.
-     *
-     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
-     * with the value set to the generated status code for the error.
-     *
-     */
-    SPINEL_CMD_PROP_VALUE_INSERT = 4,
-
-    /**
-     * Remove value from property command (Host -> NCP)
-     *
-     * Encoding: `iD`
-     *   `i` : Property Id
-     *   `D` : Value (encoding depends on the property)
-
-     * Instructs the NCP to remove the given value from a list-oriented property,
-     * without affecting other items in the list. The resulting order of items
-     * in the list is defined by the individual property being operated on.
-     *
-     * Note that this command operates by value, not by index!
-     *
-     * The payload for this command is the property identifier encoded in the
-     * packed unsigned integer format, followed by the value to be removed. The
-     * exact format of the value is defined by the property.
-     *
-     * If the type signature of the property consists of a single structure
-     * enclosed by an array `A(t(...))`, then the contents of value MUST contain
-     * the contents of the structure (`...`) rather than the serialization of the
-     * whole item (`t(...)`).  Specifically, the length of the structure MUST NOT
-     * be prepended to `VALUE`. This helps to eliminate redundant data.
-     *
-     * On success, either a `CMD_PROP_VALUE_REMOVED` command is emitted for the
-     * given property, or a `CMD_PROP_VALUE_IS` command is emitted of property
-     * `PROP_LAST_STATUS` with value `LAST_STATUS_OK`.
-     *
-     * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
-     * with the value set to the generated status code for the error.
-     *
-     */
-    SPINEL_CMD_PROP_VALUE_REMOVE = 5,
-
-    /**
-     * Property value notification command (NCP -> Host)
-     *
-     * Encoding: `iD`
-     *   `i` : Property Id
-     *   `D` : Value (encoding depends on the property)
-     *
-     * This command can be sent by the NCP in response to a previous command
-     * from the host, or it can be sent by the NCP in an unsolicited fashion
-     * to notify the host of various state changes asynchronously.
-     *
-     * The payload for this command is the property identifier encoded in the
-     * packed unsigned integer format, followed by the current value of the
-     * given property.
-     *
-     */
-    SPINEL_CMD_PROP_VALUE_IS = 6,
-
-    /**
-     * Property value insertion notification command (NCP -> Host)
-     *
-     * Encoding:`iD`
-     *   `i` : Property Id
-     *   `D` : Value (encoding depends on the property)
-     *
-     * This command can be sent by the NCP in response to the
-     * `CMD_PROP_VALUE_INSERT` command, or it can be sent by the NCP in an
-     * unsolicited fashion to notify the host of various state changes
-     * asynchronously.
-     *
-     * The payload for this command is the property identifier encoded in the
-     * packed unsigned integer format, followed by the value that was inserted
-     * into the given property.
-     *
-     * If the type signature of the property specified by property id consists
-     * of a single structure enclosed by an array (`A(t(...))`), then the
-     * contents of value MUST contain the contents of the structure (`...`)
-     * rather than the serialization of the whole item (`t(...)`). Specifically,
-     * the length of the structure MUST NOT be prepended to `VALUE`. This
-     * helps to eliminate redundant data.
-     *
-     * The resulting order of items in the list is defined by the given
-     * property.
-     *
-     */
-    SPINEL_CMD_PROP_VALUE_INSERTED = 7,
-
-    /**
-     * Property value removal notification command (NCP -> Host)
-     *
-     * Encoding: `iD`
-     *   `i` : Property Id
-     *   `D` : Value (encoding depends on the property)
-     *
-     * This command can be sent by the NCP in response to the
-     * `CMD_PROP_VALUE_REMOVE` command, or it can be sent by the NCP in an
-     * unsolicited fashion to notify the host of various state changes
-     * asynchronously.
-     *
-     * Note that this command operates by value, not by index!
-     *
-     * The payload for this command is the property identifier encoded in the
-     * packed unsigned integer format described in followed by the value that
-     * was removed from the given property.
-     *
-     * If the type signature of the property specified by property id consists
-     * of a single structure enclosed by an array (`A(t(...))`), then the
-     * contents of value MUST contain the contents of the structure (`...`)
-     * rather than the serialization of the whole item (`t(...)`).  Specifically,
-     * the length of the structure MUST NOT be prepended to `VALUE`. This
-     * helps to eliminate redundant data.
-     *
-     * The resulting order of items in the list is defined by the given
-     * property.
-     *
-     */
-    SPINEL_CMD_PROP_VALUE_REMOVED = 8,
-
-    SPINEL_CMD_NET_SAVE = 9, // Deprecated
-
-    /**
-     * Clear saved network settings command (Host -> NCP)
-     *
-     * Encoding: Empty
-     *
-     * Erases all network credentials and state from non-volatile memory.
-     *
-     * This operation affects non-volatile memory only. The current network
-     * information stored in volatile memory is unaffected.
-     *
-     * The response to this command is always a `CMD_PROP_VALUE_IS` for
-     * `PROP_LAST_STATUS`, indicating the result of the operation.
-     *
-     */
-    SPINEL_CMD_NET_CLEAR = 10,
-
-    SPINEL_CMD_NET_RECALL = 11, // Deprecated
-
-    /**
-     * Host buffer offload is an optional NCP capability that, when
-     * present, allows the NCP to store data buffers on the host processor
-     * that can be recalled at a later time.
-     *
-     * The presence of this feature can be detected by the host by
-     * checking for the presence of the `CAP_HBO`
-     * capability in `PROP_CAPS`.
-     *
-     * This feature is not currently supported on OpenThread.
-     *
-     */
-
-    SPINEL_CMD_HBO_OFFLOAD   = 12,
-    SPINEL_CMD_HBO_RECLAIM   = 13,
-    SPINEL_CMD_HBO_DROP      = 14,
-    SPINEL_CMD_HBO_OFFLOADED = 15,
-    SPINEL_CMD_HBO_RECLAIMED = 16,
-    SPINEL_CMD_HBO_DROPPED   = 17,
-
-    /**
-     * Peek command (Host -> NCP)
-     *
-     * Encoding: `LU`
-     *   `L` : The address to peek
-     *   `U` : Number of bytes to read
-     *
-     * This command allows the NCP to fetch values from the RAM of the NCP
-     * for debugging purposes. Upon success, `CMD_PEEK_RET` is sent from the
-     * NCP to the host. Upon failure, `PROP_LAST_STATUS` is emitted with
-     * the appropriate error indication.
-     *
-     * The NCP MAY prevent certain regions of memory from being accessed.
-     *
-     * This command requires the capability `CAP_PEEK_POKE` to be present.
-     *
-     */
-    SPINEL_CMD_PEEK = 18,
-
-    /**
-     * Peek return command (NCP -> Host)
-     *
-     * Encoding: `LUD`
-     *   `L` : The address peeked
-     *   `U` : Number of bytes read
-     *   `D` : Memory content
-     *
-     * This command contains the contents of memory that was requested by
-     * a previous call to `CMD_PEEK`.
-     *
-     * This command requires the capability `CAP_PEEK_POKE` to be present.
-     *
-     */
-    SPINEL_CMD_PEEK_RET = 19,
-
-    /**
-     * Poke command (Host -> NCP)
-     *
-     * Encoding: `LUD`
-     *   `L` : The address to be poked
-     *   `U` : Number of bytes to write
-     *   `D` : Content to write
-     *
-     * This command writes the bytes to the specified memory address
-     * for debugging purposes.
-     *
-     * This command requires the capability `CAP_PEEK_POKE` to be present.
-     *
-     */
-    SPINEL_CMD_POKE = 20,
-
-    SPINEL_CMD_PROP_VALUE_MULTI_GET = 21,
-    SPINEL_CMD_PROP_VALUE_MULTI_SET = 22,
-    SPINEL_CMD_PROP_VALUES_ARE      = 23,
-
-    SPINEL_CMD_NEST__BEGIN = 15296,
-    SPINEL_CMD_NEST__END   = 15360,
-
-    SPINEL_CMD_VENDOR__BEGIN = 15360,
-    SPINEL_CMD_VENDOR__END   = 16384,
-
-    SPINEL_CMD_EXPERIMENTAL__BEGIN = 2000000,
-    SPINEL_CMD_EXPERIMENTAL__END   = 2097152,
-};
-
-typedef uint32_t spinel_command_t;
-
-enum
-{
-    SPINEL_CAP_LOCK       = 1,
-    SPINEL_CAP_NET_SAVE   = 2,
-    SPINEL_CAP_HBO        = 3,
-    SPINEL_CAP_POWER_SAVE = 4,
-
-    SPINEL_CAP_COUNTERS   = 5,
-    SPINEL_CAP_JAM_DETECT = 6,
-
-    SPINEL_CAP_PEEK_POKE = 7,
-
-    SPINEL_CAP_WRITABLE_RAW_STREAM = 8,
-    SPINEL_CAP_GPIO                = 9,
-    SPINEL_CAP_TRNG                = 10,
-    SPINEL_CAP_CMD_MULTI           = 11,
-    SPINEL_CAP_UNSOL_UPDATE_FILTER = 12,
-    SPINEL_CAP_MCU_POWER_STATE     = 13,
-    SPINEL_CAP_PCAP                = 14,
-
-    SPINEL_CAP_802_15_4__BEGIN        = 16,
-    SPINEL_CAP_802_15_4_2003          = (SPINEL_CAP_802_15_4__BEGIN + 0),
-    SPINEL_CAP_802_15_4_2006          = (SPINEL_CAP_802_15_4__BEGIN + 1),
-    SPINEL_CAP_802_15_4_2011          = (SPINEL_CAP_802_15_4__BEGIN + 2),
-    SPINEL_CAP_802_15_4_PIB           = (SPINEL_CAP_802_15_4__BEGIN + 5),
-    SPINEL_CAP_802_15_4_2450MHZ_OQPSK = (SPINEL_CAP_802_15_4__BEGIN + 8),
-    SPINEL_CAP_802_15_4_915MHZ_OQPSK  = (SPINEL_CAP_802_15_4__BEGIN + 9),
-    SPINEL_CAP_802_15_4_868MHZ_OQPSK  = (SPINEL_CAP_802_15_4__BEGIN + 10),
-    SPINEL_CAP_802_15_4_915MHZ_BPSK   = (SPINEL_CAP_802_15_4__BEGIN + 11),
-    SPINEL_CAP_802_15_4_868MHZ_BPSK   = (SPINEL_CAP_802_15_4__BEGIN + 12),
-    SPINEL_CAP_802_15_4_915MHZ_ASK    = (SPINEL_CAP_802_15_4__BEGIN + 13),
-    SPINEL_CAP_802_15_4_868MHZ_ASK    = (SPINEL_CAP_802_15_4__BEGIN + 14),
-    SPINEL_CAP_802_15_4__END          = 32,
-
-    SPINEL_CAP_CONFIG__BEGIN = 32,
-    SPINEL_CAP_CONFIG_FTD    = (SPINEL_CAP_CONFIG__BEGIN + 0),
-    SPINEL_CAP_CONFIG_MTD    = (SPINEL_CAP_CONFIG__BEGIN + 1),
-    SPINEL_CAP_CONFIG_RADIO  = (SPINEL_CAP_CONFIG__BEGIN + 2),
-    SPINEL_CAP_CONFIG__END   = 40,
-
-    SPINEL_CAP_ROLE__BEGIN = 48,
-    SPINEL_CAP_ROLE_ROUTER = (SPINEL_CAP_ROLE__BEGIN + 0),
-    SPINEL_CAP_ROLE_SLEEPY = (SPINEL_CAP_ROLE__BEGIN + 1),
-    SPINEL_CAP_ROLE__END   = 52,
-
-    SPINEL_CAP_NET__BEGIN     = 52,
-    SPINEL_CAP_NET_THREAD_1_0 = (SPINEL_CAP_NET__BEGIN + 0),
-    SPINEL_CAP_NET_THREAD_1_1 = (SPINEL_CAP_NET__BEGIN + 1),
-    SPINEL_CAP_NET__END       = 64,
-
-    SPINEL_CAP_OPENTHREAD__BEGIN       = 512,
-    SPINEL_CAP_MAC_WHITELIST           = (SPINEL_CAP_OPENTHREAD__BEGIN + 0),
-    SPINEL_CAP_MAC_RAW                 = (SPINEL_CAP_OPENTHREAD__BEGIN + 1),
-    SPINEL_CAP_OOB_STEERING_DATA       = (SPINEL_CAP_OPENTHREAD__BEGIN + 2),
-    SPINEL_CAP_CHANNEL_MONITOR         = (SPINEL_CAP_OPENTHREAD__BEGIN + 3),
-    SPINEL_CAP_ERROR_RATE_TRACKING     = (SPINEL_CAP_OPENTHREAD__BEGIN + 4),
-    SPINEL_CAP_CHANNEL_MANAGER         = (SPINEL_CAP_OPENTHREAD__BEGIN + 5),
-    SPINEL_CAP_OPENTHREAD_LOG_METADATA = (SPINEL_CAP_OPENTHREAD__BEGIN + 6),
-    SPINEL_CAP_TIME_SYNC               = (SPINEL_CAP_OPENTHREAD__BEGIN + 7),
-    SPINEL_CAP_CHILD_SUPERVISION       = (SPINEL_CAP_OPENTHREAD__BEGIN + 8),
-    SPINEL_CAP_POSIX_APP               = (SPINEL_CAP_OPENTHREAD__BEGIN + 9),
-    SPINEL_CAP_SLAAC                   = (SPINEL_CAP_OPENTHREAD__BEGIN + 10),
-    SPINEL_CAP_RADIO_COEX              = (SPINEL_CAP_OPENTHREAD__BEGIN + 11),
-    SPINEL_CAP_MAC_RETRY_HISTOGRAM     = (SPINEL_CAP_OPENTHREAD__BEGIN + 12),
-    SPINEL_CAP_OPENTHREAD__END         = 640,
-
-    SPINEL_CAP_THREAD__BEGIN        = 1024,
-    SPINEL_CAP_THREAD_COMMISSIONER  = (SPINEL_CAP_THREAD__BEGIN + 0),
-    SPINEL_CAP_THREAD_TMF_PROXY     = (SPINEL_CAP_THREAD__BEGIN + 1),
-    SPINEL_CAP_THREAD_UDP_FORWARD   = (SPINEL_CAP_THREAD__BEGIN + 2),
-    SPINEL_CAP_THREAD_JOINER        = (SPINEL_CAP_THREAD__BEGIN + 3),
-    SPINEL_CAP_THREAD_BORDER_ROUTER = (SPINEL_CAP_THREAD__BEGIN + 4),
-    SPINEL_CAP_THREAD_SERVICE       = (SPINEL_CAP_THREAD__BEGIN + 5),
-    SPINEL_CAP_THREAD__END          = 1152,
-
-    SPINEL_CAP_NEST__BEGIN           = 15296,
-    SPINEL_CAP_NEST_LEGACY_INTERFACE = (SPINEL_CAP_NEST__BEGIN + 0),
-    SPINEL_CAP_NEST_LEGACY_NET_WAKE  = (SPINEL_CAP_NEST__BEGIN + 1),
-    SPINEL_CAP_NEST_TRANSMIT_HOOK    = (SPINEL_CAP_NEST__BEGIN + 2),
-    SPINEL_CAP_NEST__END             = 15360,
-
-    SPINEL_CAP_VENDOR__BEGIN = 15360,
-    SPINEL_CAP_VENDOR__END   = 16384,
-
-    SPINEL_CAP_EXPERIMENTAL__BEGIN = 2000000,
-    SPINEL_CAP_EXPERIMENTAL__END   = 2097152,
-};
-
-typedef uint32_t spinel_capability_t;
-
-/**
- * Property Keys
- *
- * The properties are broken up into several sections, each with a
- * reserved ranges of property identifiers:
- *
- *    Name         | Range (Inclusive)              | Description
- *    -------------|--------------------------------|------------------------
- *    Core         | 0x000 - 0x01F, 0x1000 - 0x11FF | Spinel core
- *    PHY          | 0x020 - 0x02F, 0x1200 - 0x12FF | Radio PHY layer
- *    MAC          | 0x030 - 0x03F, 0x1300 - 0x13FF | MAC layer
- *    NET          | 0x040 - 0x04F, 0x1400 - 0x14FF | Network
- *    Thread       | 0x050 - 0x05F, 0x1500 - 0x15FF | Thread
- *    IPv6         | 0x060 - 0x06F, 0x1600 - 0x16FF | IPv6
- *    Stream       | 0x070 - 0x07F, 0x1700 - 0x17FF | Stream
- *    MeshCop      | 0x080 - 0x08F, 0x1800 - 0x18FF | Thread Mesh Commissioning
- *    OpenThread   |                0x1900 - 0x19FF | OpenThread specific
- *    Server       | 0x0A0 - 0x0AF                  | ALOC Service Server
- *    Interface    | 0x100 - 0x1FF                  | Interface (e.g., UART)
- *    PIB          | 0x400 - 0x4FF                  | 802.15.4 PIB
- *    Counter      | 0x500 - 0x7FF                  | Counters (MAC, IP, etc).
- *    Nest         |                0x3BC0 - 0x3BFF | Nest (legacy)
- *    Vendor       |                0x3C00 - 0x3FFF | Vendor specific
- *    Debug        |                0x4000 - 0x43FF | Debug related
- *    Experimental |          2,000,000 - 2,097,151 | Experimental use only
- *
- */
-enum
-{
-    /// Last Operation Status
-    /** Format: `i` - Read-only
-     *
-     * Describes the status of the last operation. Encoded as a packed
-     * unsigned integer (see `SPINEL_STATUS_*` for list of values).
-     *
-     * This property is emitted often to indicate the result status of
-     * pretty much any Host-to-NCP operation.
-     *
-     * It is emitted automatically at NCP startup with a value indicating
-     * the reset reason. It is also emitted asynchronously on an error (
-     * e.g., NCP running out of buffer).
-     *
-     */
-    SPINEL_PROP_LAST_STATUS = 0,
-
-    /// Protocol Version
-    /** Format: `ii` - Read-only
-     *
-     * Describes the protocol version information. This property contains
-     * two fields, each encoded as a packed unsigned integer:
-     *   `i`: Major Version Number
-     *   `i`: Minor Version Number
-     *
-     * The version number is defined by `SPINEL_PROTOCOL_VERSION_THREAD_MAJOR`
-     * and `SPINEL_PROTOCOL_VERSION_THREAD_MINOR`.
-     *
-     * This specification describes major version 4, minor version 3.
-     *
-     */
-    SPINEL_PROP_PROTOCOL_VERSION = 1,
-
-    /// NCP Version
-    /** Format: `U` - Read-only
-     *
-     * Contains a string which describes the firmware currently running on
-     * the NCP. Encoded as a zero-terminated UTF-8 string.
-     *
-     */
-    SPINEL_PROP_NCP_VERSION = 2,
-
-    /// NCP Network Protocol Type
-    /** Format: 'i' - Read-only
-     *
-     * This value identifies what the network protocol for this NCP.
-     * The valid protocol type values are defined by enumeration
-     * `SPINEL_PROTOCOL_TYPE_*`:
-     *
-     *   `SPINEL_PROTOCOL_TYPE_BOOTLOADER` = 0
-     *   `SPINEL_PROTOCOL_TYPE_ZIGBEE_IP`  = 2,
-     *   `SPINEL_PROTOCOL_TYPE_THREAD`     = 3,
-     *
-     * OpenThread NCP supports only `SPINEL_PROTOCOL_TYPE_THREAD`
-     *
-     */
-    SPINEL_PROP_INTERFACE_TYPE = 3,
-
-    /// NCP Vendor ID
-    /** Format: 'i` - Read-only
-     *
-     * Vendor ID. Zero for unknown.
-     *
-     */
-    SPINEL_PROP_VENDOR_ID = 4,
-
-    /// NCP Capability List
-    /** Format: 'A(i)` - Read-only
-     *
-     * Describes the supported capabilities of this NCP. Encoded as a list of
-     * packed unsigned integers.
-     *
-     * The capability values are specified by SPINEL_CAP_* enumeration.
-     *
-     */
-    SPINEL_PROP_CAPS = 5,
-
-    /// NCP Interface Count
-    /** Format: 'C` - Read-only
-     *
-     * Provides number of interfaces.
-     *
-     * Currently always reads as 1.
-     *
-     */
-    SPINEL_PROP_INTERFACE_COUNT = 6,
-
-    SPINEL_PROP_POWER_STATE = 7, ///< PowerState [C] (deprecated, use `MCU_POWER_STATE` instead).
-
-    /// NCP Hardware Address
-    /** Format: 'E` - Read-only
-     *
-     * The static EUI64 address of the device, used as a serial number.
-     *
-     */
-    SPINEL_PROP_HWADDR = 8,
-
-    SPINEL_PROP_LOCK          = 9,  ///< PropLock [b] (not supported)
-    SPINEL_PROP_HBO_MEM_MAX   = 10, ///< Max offload mem [S] (not supported)
-    SPINEL_PROP_HBO_BLOCK_MAX = 11, ///< Max offload block [S] (not supported)
-
-    /// Host Power State
-    /** Format: 'C`
-     *
-     * Describes the current power state of the host. This property is used
-     * by the host to inform the NCP when it has changed power states. The
-     * NCP can then use this state to determine which properties need
-     * asynchronous updates. Enumeration `spinel_host_power_state_t` defines
-     * the valid values (`SPINEL_HOST_POWER_STATE_*`):
-     *
-     *   `HOST_POWER_STATE_OFFLINE`: Host is physically powered off and
-     *   cannot be woken by the NCP. All asynchronous commands are
-     *   squelched.
-     *
-     *   `HOST_POWER_STATE_DEEP_SLEEP`: The host is in a low power state
-     *   where it can be woken by the NCP but will potentially require more
-     *   than two seconds to become fully responsive. The NCP MUST
-     *   avoid sending unnecessary property updates, such as child table
-     *   updates or non-critical messages on the debug stream. If the NCP
-     *   needs to wake the host for traffic, the NCP MUST first take
-     *   action to wake the host. Once the NCP signals to the host that it
-     *   should wake up, the NCP MUST wait for some activity from the
-     *   host (indicating that it is fully awake) before sending frames.
-     *
-     *   `HOST_POWER_STATE_RESERVED`:  This value MUST NOT be set by the host. If
-     *   received by the NCP, the NCP SHOULD consider this as a synonym
-     *   of `HOST_POWER_STATE_DEEP_SLEEP`.
-     *
-     *   `HOST_POWER_STATE_LOW_POWER`: The host is in a low power state
-     *   where it can be immediately woken by the NCP. The NCP SHOULD
-     *   avoid sending unnecessary property updates, such as child table
-     *   updates or non-critical messages on the debug stream.
-     *
-     *   `HOST_POWER_STATE_ONLINE`: The host is awake and responsive. No
-     *   special filtering is performed by the NCP on asynchronous updates.
-     *
-     *   All other values are RESERVED. They MUST NOT be set by the
-     *   host. If received by the NCP, the NCP SHOULD consider the value as
-     *   a synonym of `HOST_POWER_STATE_LOW_POWER`.
-     *
-     * After setting this power state, any further commands from the host to
-     * the NCP will cause `HOST_POWER_STATE` to automatically revert to
-     * `HOST_POWER_STATE_ONLINE`.
-     *
-     * When the host is entering a low-power state, it should wait for the
-     * response from the NCP acknowledging the command (with `CMD_VALUE_IS`).
-     * Once that acknowledgment is received the host may enter the low-power
-     * state.
-     *
-     * If the NCP has the `CAP_UNSOL_UPDATE_FILTER` capability, any unsolicited
-     * property updates masked by `PROP_UNSOL_UPDATE_FILTER` should be honored
-     * while the host indicates it is in a low-power state. After resuming to the
-     * `HOST_POWER_STATE_ONLINE` state, the value of `PROP_UNSOL_UPDATE_FILTER`
-     * MUST be unchanged from the value assigned prior to the host indicating
-     * it was entering a low-power state.
-     *
-     */
-    SPINEL_PROP_HOST_POWER_STATE = 12,
-
-    /// NCP's MCU Power State
-    /** Format: 'C`
-     *  Required capability: CAP_MCU_POWER_SAVE
-     *
-     * This property specifies the desired power state of NCP's micro-controller
-     * (MCU) when the underlying platform's operating system enters idle mode (i.e.,
-     * all active tasks/events are processed and the MCU can potentially enter a
-     * energy-saving power state).
-     *
-     * The power state primarily determines how the host should interact with the NCP
-     * and whether the host needs an external trigger (a "poke") to NCP before it can
-     * communicate with the NCP or not. After a reset, the MCU power state MUST be
-     * SPINEL_MCU_POWER_STATE_ON.
-     *
-     * Enumeration `spinel_mcu_power_state_t` defines the valid values
-     * (`SPINEL_MCU_POWER_STATE_*` constants):
-     *
-     *   `SPINEL_MCU_POWER_STATE_ON`: NCP's MCU stays on and active all the time.
-     *   When the NCP's desired power state is set to this value, host can send
-     *   messages to NCP without requiring any "poke" or external triggers. MCU is
-     *   expected to stay on and active. Note that the `ON` power state only
-     *   determines the MCU's power mode and is not related to radio's state.
-     *
-     *   `SPINEL_MCU_POWER_STATE_LOW_POWER`: NCP's MCU can enter low-power
-     *   (energy-saving) state. When the NCP's desired power state is set to
-     *   `LOW_POWER`, host is expected to "poke" the NCP (e.g., an external trigger
-     *   like an interrupt) before it can communicate with the NCP (send a message
-     *   to the NCP). The "poke" mechanism is determined by the platform code (based
-     *   on NCP's interface to the host).
-     *   While power state is set to `LOW_POWER`, NCP can still (at any time) send
-     *   messages to host. Note that receiving a message from the NCP does NOT
-     *   indicate that the NCP's power state has changed, i.e., host is expected to
-     *   continue to "poke" NCP when it wants to talk to the NCP until the power
-     *   state is explicitly changed (by setting this property to `ON`).
-     *   Note that the `LOW_POWER` power state only determines the MCU's power mode
-     *   and is not related to radio's state.
-     *
-     *   `SPINEL_MCU_POWER_STATE_OFF`: NCP is fully powered off.
-     *   An NCP hardware reset (via a RESET pin) is required to bring the NCP back
-     *   to `SPINEL_MCU_POWER_STATE_ON`. RAM is not retained after reset.
-     *
-     */
-    SPINEL_PROP_MCU_POWER_STATE = 13,
-
-    SPINEL_PROP_BASE_EXT__BEGIN = 0x1000,
-
-    /// GPIO Configuration
-    /** Format: `A(CCU)`
-     *  Type: Read-Only (Optionally Read-write using `CMD_PROP_VALUE_INSERT`)
-     *
-     * An array of structures which contain the following fields:
-     *
-     * *   `C`: GPIO Number
-     * *   `C`: GPIO Configuration Flags
-     * *   `U`: Human-readable GPIO name
-     *
-     * GPIOs which do not have a corresponding entry are not supported.
-     *
-     * The configuration parameter contains the configuration flags for the
-     * GPIO:
-     *
-     *       0   1   2   3   4   5   6   7
-     *     +---+---+---+---+---+---+---+---+
-     *     |DIR|PUP|PDN|TRIGGER|  RESERVED |
-     *     +---+---+---+---+---+---+---+---+
-     *             |O/D|
-     *             +---+
-     *
-     * *   `DIR`: Pin direction. Clear (0) for input, set (1) for output.
-     * *   `PUP`: Pull-up enabled flag.
-     * *   `PDN`/`O/D`: Flag meaning depends on pin direction:
-     *     *   Input: Pull-down enabled.
-     *     *   Output: Output is an open-drain.
-     * *   `TRIGGER`: Enumeration describing how pin changes generate
-     *     asynchronous notification commands (TBD) from the NCP to the host.
-     *     *   0: Feature disabled for this pin
-     *     *   1: Trigger on falling edge
-     *     *   2: Trigger on rising edge
-     *     *   3: Trigger on level change
-     * *   `RESERVED`: Bits reserved for future use. Always cleared to zero
-     *     and ignored when read.
-     *
-     * As an optional feature, the configuration of individual pins may be
-     * modified using the `CMD_PROP_VALUE_INSERT` command. Only the GPIO
-     * number and flags fields MUST be present, the GPIO name (if present)
-     * would be ignored. This command can only be used to modify the
-     * configuration of GPIOs which are already exposed---it cannot be used
-     * by the host to add additional GPIOs.
-     */
-    SPINEL_PROP_GPIO_CONFIG = SPINEL_PROP_BASE_EXT__BEGIN + 0,
-
-    /// GPIO State Bitmask
-    /** Format: `D`
-     *  Type: Read-Write
-     *
-     * Contains a bit field identifying the state of the GPIOs. The length of
-     * the data associated with these properties depends on the number of
-     * GPIOs. If you have 10 GPIOs, you'd have two bytes. GPIOs are numbered
-     * from most significant bit to least significant bit, so 0x80 is GPIO 0,
-     * 0x40 is GPIO 1, etc.
-     *
-     * For GPIOs configured as inputs:
-     *
-     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit describes the
-     *     logic level read from the pin.
-     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit is ignored
-     *     for these pins.
-     *
-     * For GPIOs configured as outputs:
-     *
-     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit is
-     *     implementation specific.
-     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit determines
-     *     the new logic level of the output. If this pin is configured as an
-     *     open-drain, setting the associated bit to 1 will cause the pin to
-     *     enter a Hi-Z state.
-     *
-     * For GPIOs which are not specified in `PROP_GPIO_CONFIG`:
-     *
-     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit is
-     *     implementation specific.
-     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit MUST be
-     *     ignored by the NCP.
-     *
-     * When writing, unspecified bits are assumed to be zero.
-     */
-    SPINEL_PROP_GPIO_STATE = SPINEL_PROP_BASE_EXT__BEGIN + 2,
-
-    /// GPIO State Set-Only Bitmask
-    /** Format: `D`
-     *  Type: Write-Only
-     *
-     * Allows for the state of various output GPIOs to be set without affecting
-     * other GPIO states. Contains a bit field identifying the output GPIOs that
-     * should have their state set to 1.
-     *
-     * When writing, unspecified bits are assumed to be zero. The value of
-     * any bits for GPIOs which are not specified in `PROP_GPIO_CONFIG` MUST
-     * be ignored.
-     */
-    SPINEL_PROP_GPIO_STATE_SET = SPINEL_PROP_BASE_EXT__BEGIN + 3,
-
-    /// GPIO State Clear-Only Bitmask
-    /** Format: `D`
-     *  Type: Write-Only
-     *
-     * Allows for the state of various output GPIOs to be cleared without affecting
-     * other GPIO states. Contains a bit field identifying the output GPIOs that
-     * should have their state cleared to 0.
-     *
-     * When writing, unspecified bits are assumed to be zero. The value of
-     * any bits for GPIOs which are not specified in `PROP_GPIO_CONFIG` MUST
-     * be ignored.
-     */
-    SPINEL_PROP_GPIO_STATE_CLEAR = SPINEL_PROP_BASE_EXT__BEGIN + 4,
-
-    /// 32-bit random number from TRNG, ready-to-use.
-    SPINEL_PROP_TRNG_32 = SPINEL_PROP_BASE_EXT__BEGIN + 5,
-
-    /// 16 random bytes from TRNG, ready-to-use.
-    SPINEL_PROP_TRNG_128 = SPINEL_PROP_BASE_EXT__BEGIN + 6,
-
-    /// Raw samples from TRNG entropy source representing 32 bits of entropy.
-    SPINEL_PROP_TRNG_RAW_32 = SPINEL_PROP_BASE_EXT__BEGIN + 7,
-
-    /// NCP Unsolicited update filter
-    /** Format: `A(I)`
-     *  Type: Read-Write (optional Insert-Remove)
-     *  Required capability: `CAP_UNSOL_UPDATE_FILTER`
-     *
-     * Contains a list of properties which are excluded from generating
-     * unsolicited value updates. This property is empty after reset.
-     * In other words, the host may opt-out of unsolicited property updates
-     * for a specific property by adding that property id to this list.
-     * Hosts SHOULD NOT add properties to this list which are not
-     * present in `PROP_UNSOL_UPDATE_LIST`. If such properties are added,
-     * the NCP ignores the unsupported properties.
-     *
-     */
-    SPINEL_PROP_UNSOL_UPDATE_FILTER = SPINEL_PROP_BASE_EXT__BEGIN + 8,
-
-    /// List of properties capable of generating unsolicited value update.
-    /** Format: `A(I)`
-     *  Type: Read-Only
-     *  Required capability: `CAP_UNSOL_UPDATE_FILTER`
-     *
-     * Contains a list of properties which are capable of generating
-     * unsolicited value updates. This list can be used when populating
-     * `PROP_UNSOL_UPDATE_FILTER` to disable all unsolicited property
-     * updates.
-     *
-     * This property is intended to effectively behave as a constant
-     * for a given NCP firmware.
-     */
-    SPINEL_PROP_UNSOL_UPDATE_LIST = SPINEL_PROP_BASE_EXT__BEGIN + 9,
-
-    SPINEL_PROP_BASE_EXT__END = 0x1100,
-
-    SPINEL_PROP_PHY__BEGIN         = 0x20,
-    SPINEL_PROP_PHY_ENABLED        = SPINEL_PROP_PHY__BEGIN + 0, ///< [b]
-    SPINEL_PROP_PHY_CHAN           = SPINEL_PROP_PHY__BEGIN + 1, ///< [C]
-    SPINEL_PROP_PHY_CHAN_SUPPORTED = SPINEL_PROP_PHY__BEGIN + 2, ///< [A(C)]
-    SPINEL_PROP_PHY_FREQ           = SPINEL_PROP_PHY__BEGIN + 3, ///< kHz [L]
-    SPINEL_PROP_PHY_CCA_THRESHOLD  = SPINEL_PROP_PHY__BEGIN + 4, ///< dBm [c]
-    SPINEL_PROP_PHY_TX_POWER       = SPINEL_PROP_PHY__BEGIN + 5, ///< [c]
-    SPINEL_PROP_PHY_RSSI           = SPINEL_PROP_PHY__BEGIN + 6, ///< dBm [c]
-    SPINEL_PROP_PHY_RX_SENSITIVITY = SPINEL_PROP_PHY__BEGIN + 7, ///< dBm [c]
-    SPINEL_PROP_PHY_PCAP_ENABLED   = SPINEL_PROP_PHY__BEGIN + 8, ///< [b]
-    SPINEL_PROP_PHY_CHAN_PREFERRED = SPINEL_PROP_PHY__BEGIN + 9, ///< [A(C)]
-    SPINEL_PROP_PHY__END           = 0x30,
-
-    SPINEL_PROP_PHY_EXT__BEGIN = 0x1200,
-
-    /// Signal Jamming Detection Enable
-    /** Format: `b`
-     *
-     * Indicates if jamming detection is enabled or disabled. Set to true
-     * to enable jamming detection.
-     */
-    SPINEL_PROP_JAM_DETECT_ENABLE = SPINEL_PROP_PHY_EXT__BEGIN + 0,
-
-    /// Signal Jamming Detected Indicator
-    /** Format: `b` (Read-Only)
-     *
-     * Set to true if radio jamming is detected. Set to false otherwise.
-     *
-     * When jamming detection is enabled, changes to the value of this
-     * property are emitted asynchronously via `CMD_PROP_VALUE_IS`.
-     */
-    SPINEL_PROP_JAM_DETECTED = SPINEL_PROP_PHY_EXT__BEGIN + 1,
-
-    /// Jamming detection RSSI threshold
-    /** Format: `c`
-     *  Units: dBm
-     *
-     * This parameter describes the threshold RSSI level (measured in
-     * dBm) above which the jamming detection will consider the
-     * channel blocked.
-     */
-    SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD = SPINEL_PROP_PHY_EXT__BEGIN + 2,
-
-    /// Jamming detection window size
-    /** Format: `C`
-     *  Units: Seconds (1-63)
-     *
-     * This parameter describes the window period for signal jamming
-     * detection.
-     */
-    SPINEL_PROP_JAM_DETECT_WINDOW = SPINEL_PROP_PHY_EXT__BEGIN + 3,
-
-    /// Jamming detection busy period
-    /** Format: `C`
-     *  Units: Seconds (1-63)
-     *
-     * This parameter describes the number of aggregate seconds within
-     * the detection window where the RSSI must be above
-     * `PROP_JAM_DETECT_RSSI_THRESHOLD` to trigger detection.
-     *
-     * The behavior of the jamming detection feature when `PROP_JAM_DETECT_BUSY`
-     * is larger than `PROP_JAM_DETECT_WINDOW` is undefined.
-     */
-    SPINEL_PROP_JAM_DETECT_BUSY = SPINEL_PROP_PHY_EXT__BEGIN + 4,
-
-    /// Jamming detection history bitmap (for debugging)
-    /** Format: `X` (read-only)
-     *
-     * This value provides information about current state of jamming detection
-     * module for monitoring/debugging purpose. It returns a 64-bit value where
-     * each bit corresponds to one second interval starting with bit 0 for the
-     * most recent interval and bit 63 for the oldest intervals (63 sec earlier).
-     * The bit is set to 1 if the jamming detection module observed/detected
-     * high signal level during the corresponding one second interval.
-     *
-     */
-    SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP = SPINEL_PROP_PHY_EXT__BEGIN + 5,
-
-    /// Channel monitoring sample interval
-    /** Format: `L` (read-only)
-     *  Units: Milliseconds
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
-     *
-     * If channel monitoring is enabled and active, every sample interval, a
-     * zero-duration Energy Scan is performed, collecting a single RSSI sample
-     * per channel. The RSSI samples are compared with a pre-specified RSSI
-     * threshold.
-     *
-     */
-    SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL = SPINEL_PROP_PHY_EXT__BEGIN + 6,
-
-    /// Channel monitoring RSSI threshold
-    /** Format: `c` (read-only)
-     *  Units: dBm
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
-     *
-     * This value specifies the threshold used by channel monitoring module.
-     * Channel monitoring maintains the average rate of RSSI samples that
-     * are above the threshold within (approximately) a pre-specified number
-     * of samples (sample window).
-     *
-     */
-    SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD = SPINEL_PROP_PHY_EXT__BEGIN + 7,
-
-    /// Channel monitoring sample window
-    /** Format: `L` (read-only)
-     *  Units: Number of samples
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
-     *
-     * The averaging sample window length (in units of number of channel
-     * samples) used by channel monitoring module. Channel monitoring will
-     * sample all channels every sample interval. It maintains the average rate
-     * of RSSI samples that are above the RSSI threshold within (approximately)
-     * the sample window.
-     *
-     */
-    SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW = SPINEL_PROP_PHY_EXT__BEGIN + 8,
-
-    /// Channel monitoring sample count
-    /** Format: `L` (read-only)
-     *  Units: Number of samples
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
-     *
-     * Total number of RSSI samples (per channel) taken by the channel
-     * monitoring module since its start (since Thread network interface
-     * was enabled).
-     *
-     */
-    SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT = SPINEL_PROP_PHY_EXT__BEGIN + 9,
-
-    /// Channel monitoring channel occupancy
-    /** Format: `A(t(CU))` (read-only)
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MONITOR
-     *
-     * Data per item is:
-     *
-     *  `C`: Channel
-     *  `U`: Channel occupancy indicator
-     *
-     * The channel occupancy value represents the average rate/percentage of
-     * RSSI samples that were above RSSI threshold ("bad" RSSI samples) within
-     * (approximately) sample window latest RSSI samples.
-     *
-     * Max value of `0xffff` indicates all RSSI samples were above RSSI
-     * threshold (i.e. 100% of samples were "bad").
-     *
-     */
-    SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_OCCUPANCY = SPINEL_PROP_PHY_EXT__BEGIN + 10,
-
-    /// Radio caps
-    /** Format: `i` (read-only)
-     *
-     * Data per item is:
-     *
-     *  `i`: Radio Capabilities.
-     *
-     */
-    SPINEL_PROP_RADIO_CAPS = SPINEL_PROP_PHY_EXT__BEGIN + 11,
-
-    /// All coex metrics related counters.
-    /** Format: t(LLLLLLLL)t(LLLLLLLLL)bL  (Read-only)
-     *
-     * Required capability: SPINEL_CAP_RADIO_COEX
-     *
-     * The contents include two structures and two common variables, first structure corresponds to
-     * all transmit related coex counters, second structure provides the receive related counters.
-     *
-     * The transmit structure includes:
-     *   'L': NumTxRequest                       (The number of tx requests).
-     *   'L': NumTxGrantImmediate                (The number of tx requests while grant was active).
-     *   'L': NumTxGrantWait                     (The number of tx requests while grant was inactive).
-     *   'L': NumTxGrantWaitActivated            (The number of tx requests while grant was inactive that were
-     *                                            ultimately granted).
-     *   'L': NumTxGrantWaitTimeout              (The number of tx requests while grant was inactive that timed out).
-     *   'L': NumTxGrantDeactivatedDuringRequest (The number of tx requests that were in progress when grant was
-     *                                            deactivated).
-     *   'L': NumTxDelayedGrant                  (The number of tx requests that were not granted within 50us).
-     *   'L': AvgTxRequestToGrantTime            (The average time in usec from tx request to grant).
-     *
-     * The receive structure includes:
-     *   'L': NumRxRequest                       (The number of rx requests).
-     *   'L': NumRxGrantImmediate                (The number of rx requests while grant was active).
-     *   'L': NumRxGrantWait                     (The number of rx requests while grant was inactive).
-     *   'L': NumRxGrantWaitActivated            (The number of rx requests while grant was inactive that were
-     *                                            ultimately granted).
-     *   'L': NumRxGrantWaitTimeout              (The number of rx requests while grant was inactive that timed out).
-     *   'L': NumRxGrantDeactivatedDuringRequest (The number of rx requests that were in progress when grant was
-     *                                            deactivated).
-     *   'L': NumRxDelayedGrant                  (The number of rx requests that were not granted within 50us).
-     *   'L': AvgRxRequestToGrantTime            (The average time in usec from rx request to grant).
-     *   'L': NumRxGrantNone                     (The number of rx requests that completed without receiving grant).
-     *
-     * Two common variables:
-     *   'b': Stopped        (Stats collection stopped due to saturation).
-     *   'L': NumGrantGlitch (The number of of grant glitches).
-     */
-    SPINEL_PROP_RADIO_COEX_METRICS = SPINEL_PROP_PHY_EXT__BEGIN + 12,
-
-    /// Radio Coex Enable
-    /** Format: `b`
-     *
-     * Required capability: SPINEL_CAP_RADIO_COEX
-     *
-     * Indicates if radio coex is enabled or disabled. Set to true to enable radio coex.
-     */
-    SPINEL_PROP_RADIO_COEX_ENABLE = SPINEL_PROP_PHY_EXT__BEGIN + 13,
-
-    SPINEL_PROP_PHY_EXT__END = 0x1300,
-
-    SPINEL_PROP_MAC__BEGIN = 0x30,
-
-    /// MAC Scan State
-    /** Format: `C`
-     *
-     * Possible values are from enumeration `spinel_scan_state_t`.
-     *
-     *   SCAN_STATE_IDLE
-     *   SCAN_STATE_BEACON
-     *   SCAN_STATE_ENERGY
-     *   SCAN_STATE_DISCOVER
-     *
-     * Set to `SCAN_STATE_BEACON` to start an active scan.
-     * Beacons will be emitted from `PROP_MAC_SCAN_BEACON`.
-     *
-     * Set to `SCAN_STATE_ENERGY` to start an energy scan.
-     * Channel energy result will be reported by emissions
-     * of `PROP_MAC_ENERGY_SCAN_RESULT` (per channel).
-     *
-     * Set to `SCAN_STATE_DISOVER` to start a Thread MLE discovery
-     * scan operation. Discovery scan result will be emitted from
-     * `PROP_MAC_SCAN_BEACON`.
-     *
-     * Value switches to `SCAN_STATE_IDLE` when scan is complete.
-     *
-     */
-    SPINEL_PROP_MAC_SCAN_STATE = SPINEL_PROP_MAC__BEGIN + 0,
-
-    /// MAC Scan Channel Mask
-    /** Format: `A(C)`
-     *
-     * List of channels to scan.
-     *
-     */
-    SPINEL_PROP_MAC_SCAN_MASK = SPINEL_PROP_MAC__BEGIN + 1,
-
-    /// MAC Scan Channel Period
-    /** Format: `S`
-     *  Unit: milliseconds per channel
-     *
-     */
-    SPINEL_PROP_MAC_SCAN_PERIOD = SPINEL_PROP_MAC__BEGIN + 2,
-
-    /// MAC Scan Beacon
-    /** Format `Cct(ESSc)t(iCUdd)` - Asynchronous event only
-     *
-     * Scan beacons have two embedded structures which contain
-     * information about the MAC layer and the NET layer. Their
-     * format depends on the MAC and NET layer currently in use.
-     * The format below is for an 802.15.4 MAC with Thread:
-     *
-     *  `C`: Channel
-     *  `c`: RSSI of the beacon
-     *  `t`: MAC layer properties (802.15.4 layer)
-     *    `E`: Long address
-     *    `S`: Short address
-     *    `S`: PAN-ID
-     *    `c`: LQI
-     *  NET layer properties
-     *    `i`: Protocol Number (SPINEL_PROTOCOL_TYPE_* values)
-     *    `C`: Flags (SPINEL_BEACON_THREAD_FLAG_* values)
-     *    `U`: Network Name
-     *    `d`: XPANID
-     *    `d`: Steering data
-     *
-     * Extra parameters may be added to each of the structures
-     * in the future, so care should be taken to read the length
-     * that prepends each structure.
-     *
-     */
-    SPINEL_PROP_MAC_SCAN_BEACON = SPINEL_PROP_MAC__BEGIN + 3,
-
-    /// MAC Long Address
-    /** Format: `E`
-     *
-     * The 802.15.4 long address of this node.
-     *
-     */
-    SPINEL_PROP_MAC_15_4_LADDR = SPINEL_PROP_MAC__BEGIN + 4,
-
-    /// MAC Short Address
-    /** Format: `S`
-     *
-     * The 802.15.4 short address of this node.
-     *
-     */
-    SPINEL_PROP_MAC_15_4_SADDR = SPINEL_PROP_MAC__BEGIN + 5,
-
-    /// MAC PAN ID
-    /** Format: `S`
-     *
-     * The 802.15.4 PANID this node is associated with.
-     *
-     */
-    SPINEL_PROP_MAC_15_4_PANID = SPINEL_PROP_MAC__BEGIN + 6,
-
-    /// MAC Stream Raw Enabled
-    /** Format: `b`
-     *
-     * Set to true to enable raw MAC frames to be emitted from
-     * `PROP_STREAM_RAW`.
-     *
-     */
-    SPINEL_PROP_MAC_RAW_STREAM_ENABLED = SPINEL_PROP_MAC__BEGIN + 7,
-
-    /// MAC Promiscuous Mode
-    /** Format: `C`
-     *
-     * Possible values are from enumeration
-     * `SPINEL_MAC_PROMISCUOUS_MODE_*`:
-     *
-     *   `SPINEL_MAC_PROMISCUOUS_MODE_OFF`
-     *        Normal MAC filtering is in place.
-     *
-     *   `SPINEL_MAC_PROMISCUOUS_MODE_NETWORK`
-     *        All MAC packets matching network are passed up
-     *        the stack.
-     *
-     *   `SPINEL_MAC_PROMISCUOUS_MODE_FULL`
-     *        All decoded MAC packets are passed up the stack.
-     *
-     */
-    SPINEL_PROP_MAC_PROMISCUOUS_MODE = SPINEL_PROP_MAC__BEGIN + 8,
-
-    /// MAC Energy Scan Result
-    /** Format: `Cc` - Asynchronous event only
-     *
-     * This property is emitted during energy scan operation
-     * per scanned channel with following format:
-     *
-     *   `C`: Channel
-     *   `c`: RSSI (in dBm)
-     *
-     */
-    SPINEL_PROP_MAC_ENERGY_SCAN_RESULT = SPINEL_PROP_MAC__BEGIN + 9,
-
-    /// MAC Data Poll Period
-    /** Format: `L`
-     *  Unit: millisecond
-     * The (user-specified) data poll (802.15.4 MAC Data Request) period
-     * in milliseconds. Value zero means there is no user-specified
-     * poll period, and the network stack determines the maximum period
-     * based on the MLE Child Timeout.
-     *
-     * If the value is non-zero, it specifies the maximum period between
-     * data poll transmissions. Note that the network stack may send data
-     * request transmissions more frequently when expecting a control-message
-     * (e.g., when waiting for an MLE Child ID Response).
-     *
-     */
-    SPINEL_PROP_MAC_DATA_POLL_PERIOD = SPINEL_PROP_MAC__BEGIN + 10,
-
-    SPINEL_PROP_MAC__END = 0x40,
-
-    SPINEL_PROP_MAC_EXT__BEGIN = 0x1300,
-
-    /// MAC Whitelist
-    /** Format: `A(t(Ec))`
-     * Required capability: `CAP_MAC_WHITELIST`
-     *
-     * Structure Parameters:
-     *
-     *  `E`: EUI64 address of node
-     *  `c`: Optional RSSI-override value. The value 127 indicates
-     *       that the RSSI-override feature is not enabled for this
-     *       address. If this value is omitted when setting or
-     *       inserting, it is assumed to be 127. This parameter is
-     *       ignored when removing.
-     */
-    SPINEL_PROP_MAC_WHITELIST = SPINEL_PROP_MAC_EXT__BEGIN + 0,
-
-    /// MAC Whitelist Enabled Flag
-    /** Format: `b`
-     * Required capability: `CAP_MAC_WHITELIST`
-     *
-     */
-    SPINEL_PROP_MAC_WHITELIST_ENABLED = SPINEL_PROP_MAC_EXT__BEGIN + 1,
-
-    /// MAC Extended Address
-    /** Format: `E`
-     *
-     *  Specified by Thread. Randomly-chosen, but non-volatile EUI-64.
-     */
-    SPINEL_PROP_MAC_EXTENDED_ADDR = SPINEL_PROP_MAC_EXT__BEGIN + 2,
-
-    /// MAC Source Match Enabled Flag
-    /** Format: `b`
-     * Required Capability: SPINEL_CAP_MAC_RAW or SPINEL_CAP_CONFIG_RADIO
-     *
-     * Set to true to enable radio source matching or false to disable it.
-     * The source match functionality is used by radios when generating
-     * ACKs. The short and extended address lists are used for setting
-     * the Frame Pending bit in the ACKs.
-     *
-     */
-    SPINEL_PROP_MAC_SRC_MATCH_ENABLED = SPINEL_PROP_MAC_EXT__BEGIN + 3,
-
-    /// MAC Source Match Short Address List
-    /** Format: `A(S)`
-     * Required Capability: SPINEL_CAP_MAC_RAW or SPINEL_CAP_CONFIG_RADIO
-     *
-     */
-    SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES = SPINEL_PROP_MAC_EXT__BEGIN + 4,
-
-    /// MAC Source Match Extended Address List
-    /** Format: `A(E)`
-     *  Required Capability: SPINEL_CAP_MAC_RAW or SPINEL_CAP_CONFIG_RADIO
-     *
-     */
-    SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES = SPINEL_PROP_MAC_EXT__BEGIN + 5,
-
-    /// MAC Blacklist
-    /** Format: `A(t(E))`
-     * Required capability: `CAP_MAC_WHITELIST`
-     *
-     * Structure Parameters:
-     *
-     *  `E`: EUI64 address of node
-     *
-     */
-    SPINEL_PROP_MAC_BLACKLIST = SPINEL_PROP_MAC_EXT__BEGIN + 6,
-
-    /// MAC Blacklist Enabled Flag
-    /** Format: `b`
-     *  Required capability: `CAP_MAC_WHITELIST`
-     */
-    SPINEL_PROP_MAC_BLACKLIST_ENABLED = SPINEL_PROP_MAC_EXT__BEGIN + 7,
-
-    /// MAC Received Signal Strength Filter
-    /** Format: `A(t(Ec))`
-     * Required capability: `CAP_MAC_WHITELIST`
-     *
-     * Structure Parameters:
-     *
-     * * `E`: Optional EUI64 address of node. Set default RSS if not included.
-     * * `c`: Fixed RSS. 127 means not set.
-     */
-    SPINEL_PROP_MAC_FIXED_RSS = SPINEL_PROP_MAC_EXT__BEGIN + 8,
-
-    /// The CCA failure rate
-    /** Format: `S`
-     *
-     * This property provides the current CCA (Clear Channel Assessment) failure rate.
-     *
-     * Maximum value `0xffff` corresponding to 100% failure rate.
-     *
-     */
-    SPINEL_PROP_MAC_CCA_FAILURE_RATE = SPINEL_PROP_MAC_EXT__BEGIN + 9,
-
-    /// MAC Max direct retry number
-    /** Format: `C`
-     *
-     * The maximum (user-specified) number of direct frame transmission retries.
-     *
-     */
-    SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT = SPINEL_PROP_MAC_EXT__BEGIN + 10,
-
-    /// MAC Max indirect retry number
-    /** Format: `C`
-     * Required capability: `SPINEL_CAP_CONFIG_FTD`
-     *
-     * The maximum (user-specified) number of indirect frame transmission retries.
-     *
-     */
-    SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT = SPINEL_PROP_MAC_EXT__BEGIN + 11,
-
-    SPINEL_PROP_MAC_EXT__END = 0x1400,
-
-    SPINEL_PROP_NET__BEGIN = 0x40,
-
-    /// Network Is Saved (Is Commissioned)
-    /** Format: `b` - Read only
-     *
-     * Returns true if there is a network state stored/saved.
-     *
-     */
-    SPINEL_PROP_NET_SAVED = SPINEL_PROP_NET__BEGIN + 0,
-
-    /// Network Interface Status
-    /** Format `b` - Read-write
-     *
-     * Network interface up/down status. Write true to bring
-     * interface up and false to bring interface down.
-     *
-     */
-    SPINEL_PROP_NET_IF_UP = SPINEL_PROP_NET__BEGIN + 1,
-
-    /// Thread Stack Operational Status
-    /** Format `b` - Read-write
-     *
-     * Thread stack operational status. Write true to start
-     * Thread stack and false to stop it.
-     *
-     */
-    SPINEL_PROP_NET_STACK_UP = SPINEL_PROP_NET__BEGIN + 2,
-
-    /// Thread Device Role
-    /** Format `C` - Read-write
-     *
-     * Possible values are from enumeration `spinel_net_role_t`
-     *
-     *  SPINEL_NET_ROLE_DETACHED = 0,
-     *  SPINEL_NET_ROLE_CHILD    = 1,
-     *  SPINEL_NET_ROLE_ROUTER   = 2,
-     *  SPINEL_NET_ROLE_LEADER   = 3,
-     *
-     */
-    SPINEL_PROP_NET_ROLE = SPINEL_PROP_NET__BEGIN + 3,
-
-    /// Thread Network Name
-    /** Format `U` - Read-write
-     *
-     */
-    SPINEL_PROP_NET_NETWORK_NAME = SPINEL_PROP_NET__BEGIN + 4,
-
-    /// Thread Network Extended PAN ID
-    /** Format `D` - Read-write
-     *
-     */
-    SPINEL_PROP_NET_XPANID = SPINEL_PROP_NET__BEGIN + 5,
-
-    /// Thread Network Master Key
-    /** Format `D` - Read-write
-     *
-     */
-    SPINEL_PROP_NET_MASTER_KEY = SPINEL_PROP_NET__BEGIN + 6,
-
-    /// Thread Network Key Sequence Counter
-    /** Format `L` - Read-write
-     *
-     */
-    SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER = SPINEL_PROP_NET__BEGIN + 7,
-
-    /// Thread Network Partition Id
-    /** Format `L` - Read-write
-     *
-     * The partition ID of the partition that this node is a
-     * member of.
-     *
-     */
-    SPINEL_PROP_NET_PARTITION_ID = SPINEL_PROP_NET__BEGIN + 8,
-
-    /// Require Join Existing
-    /** Format: `b`
-     *  Default Value: `false`
-     *
-     * This flag is typically used for nodes that are associating with an
-     * existing network for the first time. If this is set to `true` before
-     * `PROP_NET_STACK_UP` is set to `true`, the
-     * creation of a new partition at association is prevented. If the node
-     * cannot associate with an existing partition, `PROP_LAST_STATUS` will
-     * emit a status that indicates why the association failed and
-     * `PROP_NET_STACK_UP` will automatically revert to `false`.
-     *
-     * Once associated with an existing partition, this flag automatically
-     * reverts to `false`.
-     *
-     * The behavior of this property being set to `true` when
-     * `PROP_NET_STACK_UP` is already set to `true` is undefined.
-     *
-     */
-    SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING = SPINEL_PROP_NET__BEGIN + 9,
-
-    /// Thread Network Key Switch Guard Time
-    /** Format `L` - Read-write
-     *
-     */
-    SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME = SPINEL_PROP_NET__BEGIN + 10,
-
-    /// Thread Network PSKc
-    /** Format `D` - Read-write
-     *
-     */
-    SPINEL_PROP_NET_PSKC = SPINEL_PROP_NET__BEGIN + 11,
-
-    SPINEL_PROP_NET__END = 0x50,
-
-    SPINEL_PROP_NET_EXT__BEGIN = 0x1400,
-    SPINEL_PROP_NET_EXT__END   = 0x1500,
-
-    SPINEL_PROP_THREAD__BEGIN = 0x50,
-
-    /// Thread Leader IPv6 Address
-    /** Format `6` - Read only
-     *
-     */
-    SPINEL_PROP_THREAD_LEADER_ADDR = SPINEL_PROP_THREAD__BEGIN + 0,
-
-    /// Thread Parent Info
-    /** Format: `ESLccCC` - Read only
-     *
-     *  `E`: Extended address
-     *  `S`: RLOC16
-     *  `L`: Age (seconds since last heard from)
-     *  `c`: Average RSS (in dBm)
-     *  `c`: Last RSSI (in dBm)
-     *  `C`: Link Quality In
-     *  `C`: Link Quality Out
-     *
-     */
-    SPINEL_PROP_THREAD_PARENT = SPINEL_PROP_THREAD__BEGIN + 1,
-
-    /// Thread Child Table
-    /** Format: [A(t(ESLLCCcCc)] - Read only
-     *
-     * Data per item is:
-     *
-     *  `E`: Extended address
-     *  `S`: RLOC16
-     *  `L`: Timeout (in seconds)
-     *  `L`: Age (in seconds)
-     *  `L`: Network Data version
-     *  `C`: Link Quality In
-     *  `c`: Average RSS (in dBm)
-     *  `C`: Mode (bit-flags)
-     *  `c`: Last RSSI (in dBm)
-     *
-     */
-    SPINEL_PROP_THREAD_CHILD_TABLE = SPINEL_PROP_THREAD__BEGIN + 2,
-
-    /// Thread Leader Router Id
-    /** Format `C` - Read only
-     *
-     * The router-id of the current leader.
-     *
-     */
-    SPINEL_PROP_THREAD_LEADER_RID = SPINEL_PROP_THREAD__BEGIN + 3,
-
-    /// Thread Leader Weight
-    /** Format `C` - Read only
-     *
-     * The leader weight of the current leader.
-     *
-     */
-    SPINEL_PROP_THREAD_LEADER_WEIGHT = SPINEL_PROP_THREAD__BEGIN + 4,
-
-    /// Thread Local Leader Weight
-    /** Format `C` - Read only
-     *
-     * The leader weight of this node.
-     *
-     */
-    SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT = SPINEL_PROP_THREAD__BEGIN + 5,
-
-    /// Thread Local Network Data
-    /** Format `D` - Read only
-     *
-     */
-    SPINEL_PROP_THREAD_NETWORK_DATA = SPINEL_PROP_THREAD__BEGIN + 6,
-
-    /// Thread Local Network Data Version
-    /** Format `C` - Read only
-     *
-     */
-    SPINEL_PROP_THREAD_NETWORK_DATA_VERSION = SPINEL_PROP_THREAD__BEGIN + 7,
-
-    /// Thread Local Stable Network Data
-    /** Format `D` - Read only
-     *
-     */
-    SPINEL_PROP_THREAD_STABLE_NETWORK_DATA = SPINEL_PROP_THREAD__BEGIN + 8,
-
-    /// Thread Local Stable Network Data Version
-    /** Format `C` - Read only
-     *
-     */
-    SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION = SPINEL_PROP_THREAD__BEGIN + 9,
-
-    /// On-Mesh Prefixes
-    /** Format: `A(t(6CbCbS))`
-     *
-     * Data per item is:
-     *
-     *  `6`: IPv6 Prefix
-     *  `C`: Prefix length in bits
-     *  `b`: Stable flag
-     *  `C`: TLV flags
-     *  `b`: "Is defined locally" flag. Set if this network was locally
-     *       defined. Assumed to be true for set, insert and replace. Clear if
-     *       the on mesh network was defined by another node.
-     *  `S`: The RLOC16 of the device that registered this on-mesh prefix entry.
-     *       This value is not used and ignored when adding an on-mesh prefix.
-     *
-     */
-    SPINEL_PROP_THREAD_ON_MESH_NETS = SPINEL_PROP_THREAD__BEGIN + 10,
-
-    /// Off-mesh routes
-    /** Format: [A(t(6CbCbb))]
-     *
-     * Data per item is:
-     *
-     *  `6`: Route Prefix
-     *  `C`: Prefix length in bits
-     *  `b`: Stable flag
-     *  `C`: Route preference flags
-     *  `b`: "Is defined locally" flag. Set if this route info was locally
-     *       defined as part of local network data. Assumed to be true for set,
-     *       insert and replace. Clear if the route is part of partition's network
-     *       data.
-     *  `b`: "Next hop is this device" flag. Set if the next hop for the
-     *       route is this device itself (i.e., route was added by this device)
-     *       This value is ignored when adding an external route. For any added
-     *       route the next hop is this device.
-     *  `S`: The RLOC16 of the device that registered this route entry.
-     *       This value is not used and ignored when adding a route.
-     *
-     */
-    SPINEL_PROP_THREAD_OFF_MESH_ROUTES = SPINEL_PROP_THREAD__BEGIN + 11,
-
-    /// Thread Assisting Ports
-    /** Format `A(S)`
-     *
-     * Array of port numbers.
-     */
-    SPINEL_PROP_THREAD_ASSISTING_PORTS = SPINEL_PROP_THREAD__BEGIN + 12,
-
-    /// Thread Allow Local Network Data Change
-    /** Format `b` - Read-write
-     *
-     * Set to true before changing local net data. Set to false when finished.
-     * This allows changes to be aggregated into a single event.
-     *
-     */
-    SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE = SPINEL_PROP_THREAD__BEGIN + 13,
-
-    /// Thread Mode
-    /** Format: `C`
-     *
-     *  This property contains the value of the mode
-     *  TLV for this node. The meaning of the bits in this
-     *  bit-field are defined by section 4.5.2 of the Thread
-     *  specification.
-     *
-     * The values `SPINEL_THREAD_MODE_*` defines the bit-fields
-     *
-     */
-    SPINEL_PROP_THREAD_MODE = SPINEL_PROP_THREAD__BEGIN + 14,
-
-    SPINEL_PROP_THREAD__END = 0x60,
-
-    SPINEL_PROP_THREAD_EXT__BEGIN = 0x1500,
-
-    /// Thread Child Timeout
-    /** Format: `L`
-     *  Unit: Seconds
-     *
-     *  Used when operating in the Child role.
-     */
-    SPINEL_PROP_THREAD_CHILD_TIMEOUT = SPINEL_PROP_THREAD_EXT__BEGIN + 0,
-
-    /// Thread RLOC16
-    /** Format: `S`
-     *
-     */
-    SPINEL_PROP_THREAD_RLOC16 = SPINEL_PROP_THREAD_EXT__BEGIN + 1,
-
-    /// Thread Router Upgrade Threshold
-    /** Format: `C`
-     *
-     */
-    SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD = SPINEL_PROP_THREAD_EXT__BEGIN + 2,
-
-    /// Thread Context Reuse Delay
-    /** Format: `L`
-     *
-     */
-    SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY = SPINEL_PROP_THREAD_EXT__BEGIN + 3,
-
-    /// Thread Network ID Timeout
-    /** Format: `C`
-     *
-     */
-    SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT = SPINEL_PROP_THREAD_EXT__BEGIN + 4,
-
-    /// List of active thread router ids
-    /** Format: `A(C)`
-     *
-     * Note that some implementations may not support CMD_GET_VALUE
-     * router ids, but may support CMD_REMOVE_VALUE when the node is
-     * a leader.
-     *
-     */
-    SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS = SPINEL_PROP_THREAD_EXT__BEGIN + 5,
-
-    /// Forward IPv6 packets that use RLOC16 addresses to HOST.
-    /** Format: `b`
-     *
-     * Allow host to directly observe all IPv6 packets received by the NCP,
-     * including ones sent to the RLOC16 address.
-     *
-     * Default is false.
-     *
-     */
-    SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU = SPINEL_PROP_THREAD_EXT__BEGIN + 6,
-
-    /// Router Role Enabled
-    /** Format `b`
-     *
-     * Allows host to indicate whether or not the router role is enabled.
-     * If current role is a router, setting this property to `false` starts
-     * a re-attach process as an end-device.
-     *
-     */
-    SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 7,
-
-    /// Thread Router Downgrade Threshold
-    /** Format: `C`
-     *
-     */
-    SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD = SPINEL_PROP_THREAD_EXT__BEGIN + 8,
-
-    /// Thread Router Selection Jitter
-    /** Format: `C`
-     *
-     */
-    SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER = SPINEL_PROP_THREAD_EXT__BEGIN + 9,
-
-    /// Thread Preferred Router Id
-    /** Format: `C` - Write only
-     *
-     * Specifies the preferred Router Id. Upon becoming a router/leader the node
-     * attempts to use this Router Id. If the preferred Router Id is not set or
-     * if it can not be used, a randomly generated router id is picked. This
-     * property can be set only when the device role is either detached or
-     * disabled.
-     *
-     */
-    SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID = SPINEL_PROP_THREAD_EXT__BEGIN + 10,
-
-    /// Thread Neighbor Table
-    /** Format: `A(t(ESLCcCbLLc))` - Read only
-     *
-     * Data per item is:
-     *
-     *  `E`: Extended address
-     *  `S`: RLOC16
-     *  `L`: Age (in seconds)
-     *  `C`: Link Quality In
-     *  `c`: Average RSS (in dBm)
-     *  `C`: Mode (bit-flags)
-     *  `b`: `true` if neighbor is a child, `false` otherwise.
-     *  `L`: Link Frame Counter
-     *  `L`: MLE Frame Counter
-     *  `c`: The last RSSI (in dBm)
-     *
-     */
-    SPINEL_PROP_THREAD_NEIGHBOR_TABLE = SPINEL_PROP_THREAD_EXT__BEGIN + 11,
-
-    /// Thread Max Child Count
-    /** Format: `C`
-     *
-     * Specifies the maximum number of children currently allowed.
-     * This parameter can only be set when Thread protocol operation
-     * has been stopped.
-     *
-     */
-    SPINEL_PROP_THREAD_CHILD_COUNT_MAX = SPINEL_PROP_THREAD_EXT__BEGIN + 12,
-
-    /// Leader Network Data
-    /** Format: `D` - Read only
-     *
-     */
-    SPINEL_PROP_THREAD_LEADER_NETWORK_DATA = SPINEL_PROP_THREAD_EXT__BEGIN + 13,
-
-    /// Stable Leader Network Data
-    /** Format: `D` - Read only
-     *
-     */
-    SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA = SPINEL_PROP_THREAD_EXT__BEGIN + 14,
-
-    /// Thread Joiner Data
-    /** Format `A(T(ULE))`
-     *  PSKd, joiner timeout, eui64 (optional)
-     *
-     * This property is being deprecated by SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS.
-     *
-     */
-    SPINEL_PROP_THREAD_JOINERS = SPINEL_PROP_THREAD_EXT__BEGIN + 15,
-
-    /// Thread Commissioner Enable
-    /** Format `b`
-     *
-     * Default value is `false`.
-     *
-     * This property is being deprecated by SPINEL_PROP_MESHCOP_COMMISSIONER_STATE.
-     *
-     */
-    SPINEL_PROP_THREAD_COMMISSIONER_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 16,
-
-    /// Thread TMF proxy enable
-    /** Format `b`
-     * Required capability: `SPINEL_CAP_THREAD_TMF_PROXY`
-     *
-     * This property is deprecated.
-     *
-     */
-    SPINEL_PROP_THREAD_TMF_PROXY_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 17,
-
-    /// Thread TMF proxy stream
-    /** Format `dSS`
-     * Required capability: `SPINEL_CAP_THREAD_TMF_PROXY`
-     *
-     * This property is deprecated. Please see `SPINEL_PROP_THREAD_UDP_FORWARD_STREAM`.
-     *
-     */
-    SPINEL_PROP_THREAD_TMF_PROXY_STREAM = SPINEL_PROP_THREAD_EXT__BEGIN + 18,
-
-    /// Thread "joiner" flag used during discovery scan operation
-    /** Format `b`
-     *
-     * This property defines the Joiner Flag value in the Discovery Request TLV.
-     *
-     * Default value is `false`.
-     *
-     */
-    SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG = SPINEL_PROP_THREAD_EXT__BEGIN + 19,
-
-    /// Enable EUI64 filtering for discovery scan operation.
-    /** Format `b`
-     *
-     * Default value is `false`
-     *
-     */
-    SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING = SPINEL_PROP_THREAD_EXT__BEGIN + 20,
-
-    /// PANID used for Discovery scan operation (used for PANID filtering).
-    /** Format: `S`
-     *
-     * Default value is 0xffff (Broadcast PAN) to disable PANID filtering
-     *
-     */
-    SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID = SPINEL_PROP_THREAD_EXT__BEGIN + 21,
-
-    /// Thread (out of band) steering data for MLE Discovery Response.
-    /** Format `E` - Write only
-     *
-     * Required capability: SPINEL_CAP_OOB_STEERING_DATA.
-     *
-     * Writing to this property allows to set/update the MLE
-     * Discovery Response steering data out of band.
-     *
-     *  - All zeros to clear the steering data (indicating that
-     *    there is no steering data).
-     *  - All 0xFFs to set steering data/bloom filter to
-     *    accept/allow all.
-     *  - A specific EUI64 which is then added to current steering
-     *    data/bloom filter.
-     *
-     */
-    SPINEL_PROP_THREAD_STEERING_DATA = SPINEL_PROP_THREAD_EXT__BEGIN + 22,
-
-    /// Thread Router Table.
-    /** Format: `A(t(ESCCCCCCb)` - Read only
-     *
-     * Data per item is:
-     *
-     *  `E`: IEEE 802.15.4 Extended Address
-     *  `S`: RLOC16
-     *  `C`: Router ID
-     *  `C`: Next hop to router
-     *  `C`: Path cost to router
-     *  `C`: Link Quality In
-     *  `C`: Link Quality Out
-     *  `C`: Age (seconds since last heard)
-     *  `b`: Link established with Router ID or not.
-     *
-     */
-    SPINEL_PROP_THREAD_ROUTER_TABLE = SPINEL_PROP_THREAD_EXT__BEGIN + 23,
-
-    /// Thread Active Operational Dataset
-    /** Format: `A(t(iD))` - Read-Write
-     *
-     * This property provides access to current Thread Active Operational Dataset. A Thread device maintains the
-     * Operational Dataset that it has stored locally and the one currently in use by the partition to which it is
-     * attached. This property corresponds to the locally stored Dataset on the device.
-     *
-     * Operational Dataset consists of a set of supported properties (e.g., channel, master key, network name, PAN id,
-     * etc). Note that not all supported properties may be present (have a value) in a Dataset.
-     *
-     * The Dataset value is encoded as an array of structs containing pairs of property key (as `i`) followed by the
-     * property value (as `D`). The property value must follow the format associated with the corresponding property.
-     *
-     * On write, any unknown/unsupported property keys must be ignored.
-     *
-     * The following properties can be included in a Dataset list:
-     *
-     *   SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP
-     *   SPINEL_PROP_PHY_CHAN
-     *   SPINEL_PROP_PHY_CHAN_SUPPORTED (Channel Mask Page 0)
-     *   SPINEL_PROP_NET_MASTER_KEY
-     *   SPINEL_PROP_NET_NETWORK_NAME
-     *   SPINEL_PROP_NET_XPANID
-     *   SPINEL_PROP_MAC_15_4_PANID
-     *   SPINEL_PROP_IPV6_ML_PREFIX
-     *   SPINEL_PROP_NET_PSKC
-     *   SPINEL_PROP_DATASET_SECURITY_POLICY
-     *
-     */
-    SPINEL_PROP_THREAD_ACTIVE_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 24,
-
-    /// Thread Pending Operational Dataset
-    /** Format: `A(t(iD))` - Read-Write
-     *
-     * This property provide access to current locally stored Pending Operational Dataset.
-     *
-     * The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_ACTIVE_DATASET.
-     *
-     * In addition supported properties in SPINEL_PROP_THREAD_ACTIVE_DATASET, the following properties can also
-     * be included in the Pending Dataset:
-     *
-     *   SPINEL_PROP_DATASET_PENDING_TIMESTAMP
-     *   SPINEL_PROP_DATASET_DELAY_TIMER
-     *
-     */
-    SPINEL_PROP_THREAD_PENDING_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 25,
-
-    /// Send MGMT_SET Thread Active Operational Dataset
-    /** Format: `A(t(iD))` - Write only
-     *
-     * The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_ACTIVE_DATASET.
-     *
-     * This is write-only property. When written, it triggers a MGMT_ACTIVE_SET meshcop command to be sent to leader
-     * with the given Dataset. The spinel frame response should be a `LAST_STATUS` with the status of the transmission
-     * of MGMT_ACTIVE_SET command.
-     *
-     * In addition to supported properties in SPINEL_PROP_THREAD_ACTIVE_DATASET, the following property can be
-     * included in the Dataset (to allow for custom raw TLVs):
-     *
-     *    SPINEL_PROP_DATASET_RAW_TLVS
-     *
-     */
-    SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 26,
-
-    /// Send MGMT_SET Thread Pending Operational Dataset
-    /** Format: `A(t(iD))` - Write only
-     *
-     * This property is similar to SPINEL_PROP_THREAD_PENDING_DATASET and follows the same format and rules.
-     *
-     * In addition to supported properties in SPINEL_PROP_THREAD_PENDING_DATASET, the following property can be
-     * included the Dataset (to allow for custom raw TLVs to be provided).
-     *
-     *    SPINEL_PROP_DATASET_RAW_TLVS
-     *
-     */
-    SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 27,
-
-    /// Operational Dataset Active Timestamp
-    /** Format: `X` - No direct read or write
-     *
-     * It can only be included in one of the Dataset related properties below:
-     *
-     *   SPINEL_PROP_THREAD_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
-     *
-     */
-    SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP = SPINEL_PROP_THREAD_EXT__BEGIN + 28,
-
-    /// Operational Dataset Pending Timestamp
-    /** Format: `X` - No direct read or write
-     *
-     * It can only be included in one of the Pending Dataset properties:
-     *
-     *   SPINEL_PROP_THREAD_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
-     *
-     */
-    SPINEL_PROP_DATASET_PENDING_TIMESTAMP = SPINEL_PROP_THREAD_EXT__BEGIN + 29,
-
-    /// Operational Dataset Delay Timer
-    /** Format: `L` - No direct read or write
-     *
-     * Delay timer (in ms) specifies the time renaming until Thread devices overwrite the value in the Active
-     * Operational Dataset with the corresponding values in the Pending Operational Dataset.
-     *
-     * It can only be included in one of the Pending Dataset properties:
-     *
-     *   SPINEL_PROP_THREAD_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
-     *
-     */
-    SPINEL_PROP_DATASET_DELAY_TIMER = SPINEL_PROP_THREAD_EXT__BEGIN + 30,
-
-    /// Operational Dataset Security Policy
-    /** Format: `SC` - No direct read or write
-     *
-     * It can only be included in one of the Dataset related properties below:
-     *
-     *   SPINEL_PROP_THREAD_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
-     *
-     * Content is
-     *   `S` : Key Rotation Time (in units of hour)
-     *   `C` : Security Policy Flags (as specified in Thread 1.1 Section 8.10.1.15)
-     *
-     */
-    SPINEL_PROP_DATASET_SECURITY_POLICY = SPINEL_PROP_THREAD_EXT__BEGIN + 31,
-
-    /// Operational Dataset Additional Raw TLVs
-    /** Format: `D` - No direct read or write
-     *
-     * This property defines extra raw TLVs that can be added to an Operational DataSet.
-     *
-     * It can only be included in one of the following Dataset properties:
-     *
-     *   SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
-     *
-     */
-    SPINEL_PROP_DATASET_RAW_TLVS = SPINEL_PROP_THREAD_EXT__BEGIN + 32,
-
-    /// Child table addresses
-    /** Format: `A(t(ESA(6)))` - Read only
-     *
-     * This property provides the list of all addresses associated with every child
-     * including any registered IPv6 addresses.
-     *
-     * Data per item is:
-     *
-     *  `E`: Extended address of the child
-     *  `S`: RLOC16 of the child
-     *  `A(6)`: List of IPv6 addresses registered by the child (if any)
-     *
-     */
-    SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES = SPINEL_PROP_THREAD_EXT__BEGIN + 33,
-
-    /// Neighbor Table Frame and Message Error Rates
-    /** Format: `A(t(ESSScc))`
-     *  Required capability: `CAP_ERROR_RATE_TRACKING`
-     *
-     * This property provides link quality related info including
-     * frame and (IPv6) message error rates for all neighbors.
-     *
-     * With regards to message error rate, note that a larger (IPv6)
-     * message can be fragmented and sent as multiple MAC frames. The
-     * message transmission is considered a failure, if any of its
-     * fragments fail after all MAC retry attempts.
-     *
-     * Data per item is:
-     *
-     *  `E`: Extended address of the neighbor
-     *  `S`: RLOC16 of the neighbor
-     *  `S`: Frame error rate (0 -> 0%, 0xffff -> 100%)
-     *  `S`: Message error rate (0 -> 0%, 0xffff -> 100%)
-     *  `c`: Average RSSI (in dBm)
-     *  `c`: Last RSSI (in dBm)
-     *
-     */
-    SPINEL_PROP_THREAD_NEIGHBOR_TABLE_ERROR_RATES = SPINEL_PROP_THREAD_EXT__BEGIN + 34,
-
-    /// EID (Endpoint Identifier) IPv6 Address Cache Table
-    /** Format `A(t(6SC))`
-     *
-     * This property provides Thread EID address cache table.
-     *
-     * Data per item is:
-     *
-     *  `6` : Target IPv6 address
-     *  `S` : RLOC16 of target
-     *  `C` : Age (order of use, 0 indicates most recently used entry)
-     *
-     */
-    SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE = SPINEL_PROP_THREAD_EXT__BEGIN + 35,
-
-    /// Thread UDP forward stream
-    /** Format `dS6S`
-     * Required capability: `SPINEL_CAP_THREAD_UDP_FORWARD`
-     *
-     * This property helps exchange UDP packets with host.
-     *
-     *  `d`: UDP payload
-     *  `S`: Remote UDP port
-     *  `6`: Remote IPv6 address
-     *  `S`: Local UDP port
-     *
-     */
-    SPINEL_PROP_THREAD_UDP_FORWARD_STREAM = SPINEL_PROP_THREAD_EXT__BEGIN + 36,
-
-    /// Send MGMT_GET Thread Active Operational Dataset
-    /** Format: `A(t(iD))` - Write only
-     *
-     * The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET. This
-     * property further allows the sender to not include a value associated with properties in formating of `t(iD)`,
-     * i.e., it should accept either a `t(iD)` or a `t(i)` encoding (in both cases indicating that the associated
-     * Dataset property should be requested as part of MGMT_GET command).
-     *
-     * This is write-only property. When written, it triggers a MGMT_ACTIVE_GET meshcop command to be sent to leader
-     * requesting the Dataset related properties from the format. The spinel frame response should be a `LAST_STATUS`
-     * with the status of the transmission of MGMT_ACTIVE_GET command.
-     *
-     * In addition to supported properties in SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET, the following property can be
-     * optionally included in the Dataset:
-     *
-     *    SPINEL_PROP_DATASET_DEST_ADDRESS
-     *
-     */
-    SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 37,
-
-    /// Send MGMT_GET Thread Pending Operational Dataset
-    /** Format: `A(t(iD))` - Write only
-     *
-     * The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET.
-     *
-     * This is write-only property. When written, it triggers a MGMT_PENDING_GET meshcop command to be sent to leader
-     * with the given Dataset. The spinel frame response should be a `LAST_STATUS` with the status of the transmission
-     * of MGMT_PENDING_GET command.
-     *
-     */
-    SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 38,
-
-    /// Operational Dataset (MGMT_GET) Destination IPv6 Address
-    /** Format: `6` - No direct read or write
-     *
-     * This property specifies the IPv6 destination when sending MGMT_GET command for either Active or Pending Dataset
-     * if not provided, Leader ALOC address is used as default.
-     *
-     * It can only be included in one of the MGMT_GET Dataset properties:
-     *
-     *   SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET
-     *   SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET
-     *
-     */
-    SPINEL_PROP_DATASET_DEST_ADDRESS = SPINEL_PROP_THREAD_EXT__BEGIN + 39,
-
-    /// Thread New Operational Dataset
-    /** Format: `A(t(iD))` - Read only - FTD build only
-     *
-     * This property allows host to request NCP to create and return a new Operation Dataset to use when forming a new
-     * network.
-     *
-     * Operational Dataset consists of a set of supported properties (e.g., channel, master key, network name, PAN id,
-     * etc). Note that not all supported properties may be present (have a value) in a Dataset.
-     *
-     * The Dataset value is encoded as an array of structs containing pairs of property key (as `i`) followed by the
-     * property value (as `D`). The property value must follow the format associated with the corresponding property.
-     *
-     * The following properties can be included in a Dataset list:
-     *
-     *   SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP
-     *   SPINEL_PROP_PHY_CHAN
-     *   SPINEL_PROP_PHY_CHAN_SUPPORTED (Channel Mask Page 0)
-     *   SPINEL_PROP_NET_MASTER_KEY
-     *   SPINEL_PROP_NET_NETWORK_NAME
-     *   SPINEL_PROP_NET_XPANID
-     *   SPINEL_PROP_MAC_15_4_PANID
-     *   SPINEL_PROP_IPV6_ML_PREFIX
-     *   SPINEL_PROP_NET_PSKC
-     *   SPINEL_PROP_DATASET_SECURITY_POLICY
-     *
-     */
-    SPINEL_PROP_THREAD_NEW_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 40,
-
-    SPINEL_PROP_THREAD_EXT__END = 0x1600,
-
-    SPINEL_PROP_IPV6__BEGIN = 0x60,
-
-    /// Link-Local IPv6 Address
-    /** Format: `6` - Read only
-     *
-     */
-    SPINEL_PROP_IPV6_LL_ADDR = SPINEL_PROP_IPV6__BEGIN + 0, ///< [6]
-
-    /// Mesh Local IPv6 Address
-    /** Format: `6` - Read only
-     *
-     */
-    SPINEL_PROP_IPV6_ML_ADDR = SPINEL_PROP_IPV6__BEGIN + 1,
-
-    /// Mesh Local Prefix
-    /** Format: `6C` - Read-write
-     *
-     * Provides Mesh Local Prefix
-     *
-     *   `6`: Mesh local prefix
-     *   `C` : Prefix length (64 bit for Thread).
-     *
-     */
-    SPINEL_PROP_IPV6_ML_PREFIX = SPINEL_PROP_IPV6__BEGIN + 2,
-
-    /// IPv6 (Unicast) Address Table
-    /** Format: `A(t(6CLLC))`
-     *
-     * This property provides all unicast addresses.
-     *
-     * Array of structures containing:
-     *
-     *  `6`: IPv6 Address
-     *  `C`: Network Prefix Length
-     *  `L`: Valid Lifetime
-     *  `L`: Preferred Lifetime
-     *
-     */
-    SPINEL_PROP_IPV6_ADDRESS_TABLE = SPINEL_PROP_IPV6__BEGIN + 3,
-
-    /// IPv6 Route Table - Deprecated
-    SPINEL_PROP_IPV6_ROUTE_TABLE = SPINEL_PROP_IPV6__BEGIN + 4,
-
-    /// IPv6 ICMP Ping Offload
-    /** Format: `b`
-     *
-     * Allow the NCP to directly respond to ICMP ping requests. If this is
-     * turned on, ping request ICMP packets will not be passed to the host.
-     *
-     * Default value is `false`.
-     */
-    SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD = SPINEL_PROP_IPV6__BEGIN + 5,
-
-    /// IPv6 Multicast Address Table
-    /** Format: `A(t(6))`
-     *
-     * This property provides all multicast addresses.
-     *
-     */
-    SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE = SPINEL_PROP_IPV6__BEGIN + 6,
-
-    /// IPv6 ICMP Ping Offload
-    /** Format: `C`
-     *
-     * Allow the NCP to directly respond to ICMP ping requests. If this is
-     * turned on, ping request ICMP packets will not be passed to the host.
-     *
-     * This property allows enabling responses sent to unicast only, multicast
-     * only, or both. The valid value are defined by enumeration
-     * `spinel_ipv6_icmp_ping_offload_mode_t`.
-     *
-     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_DISABLED       = 0
-     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_UNICAST_ONLY   = 1
-     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_MULTICAST_ONLY = 2
-     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL            = 3
-     *
-     * Default value is `NET_IPV6_ICMP_PING_OFFLOAD_DISABLED`.
-     *
-     */
-    SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE = SPINEL_PROP_IPV6__BEGIN + 7, ///< [b]
-
-    SPINEL_PROP_IPV6__END = 0x70,
-
-    SPINEL_PROP_IPV6_EXT__BEGIN = 0x1600,
-    SPINEL_PROP_IPV6_EXT__END   = 0x1700,
-
-    SPINEL_PROP_STREAM__BEGIN = 0x70,
-
-    /// Debug Stream
-    /** Format: `U` (stream, read only)
-     *
-     * This property is a streaming property, meaning that you cannot explicitly
-     * fetch the value of this property. The stream provides human-readable debugging
-     * output which may be displayed in the host logs.
-     *
-     * The location of newline characters is not assumed by the host: it is
-     * the NCP's responsibility to insert newline characters where needed,
-     * just like with any other text stream.
-     *
-     * To receive the debugging stream, you wait for `CMD_PROP_VALUE_IS`
-     * commands for this property from the NCP.
-     *
-     */
-    SPINEL_PROP_STREAM_DEBUG = SPINEL_PROP_STREAM__BEGIN + 0,
-
-    /// Raw Stream
-    /** Format: `dD` (stream, read only)
-     *  Required Capability: SPINEL_CAP_MAC_RAW or SPINEL_CAP_CONFIG_RADIO
-     *
-     * This stream provides the capability of sending and receiving raw 15.4 frames
-     * to and from the radio. The exact format of the frame metadata and data is
-     * dependent on the MAC and PHY being used.
-     *
-     * This property is a streaming property, meaning that you cannot explicitly
-     * fetch the value of this property. To receive traffic, you wait for
-     * `CMD_PROP_VALUE_IS` commands with this property id from the NCP.
-     *
-     * The general format of this property is:
-     *
-     *    `d` : frame data
-     *    `D` : frame meta data
-     *
-     * The frame meta data is optional. Frame metadata MAY be empty or partially
-     * specified. Partially specified metadata MUST be accepted. Default values
-     * are used for all unspecified fields.
-     *
-     * The frame metadata field consists of the following fields:
-     *
-     *   `c` : Received Signal Strength (RSSI) in dBm - default is -128
-     *   `c` : Noise floor in dBm - default is -128
-     *   `S` : Flags (see below).
-     *   `d` : PHY-specific data/struct
-     *   `d` : Vendor-specific data/struct
-     *
-     * Flags fields are defined by the following enumeration bitfields:
-     *
-     *   SPINEL_MD_FLAG_TX       = 0x0001 :  Packet was transmitted, not received.
-     *   SPINEL_MD_FLAG_BAD_FCS  = 0x0004 :  Packet was received with bad FCS
-     *   SPINEL_MD_FLAG_DUPE     = 0x0008 :  Packet seems to be a duplicate
-     *   SPINEL_MD_FLAG_RESERVED = 0xFFF2 :  Flags reserved for future use.
-     *
-     * The format of PHY-specific data for a Thread device contains the following
-     * optional fields:
-
-     *   `C` : 802.15.4 channel (Receive channel)
-     *   `C` : IEEE 802.15.4 LQI
-     *   `L` : The timestamp milliseconds
-     *   `S` : The timestamp microseconds, offset to mMsec
-     *
-     * Frames written to this stream with `CMD_PROP_VALUE_SET` will be sent out
-     * over the radio. This allows the caller to use the radio directly.
-     *
-     * The frame meta data for the `CMD_PROP_VALUE_SET` contains the following
-     * optional fields.  Default values are used for all unspecified fields.
-     *
-     *  `C` : Channel (for frame tx)
-     *  `C` : Maximum number of backoffs attempts before declaring CCA failure
-     *        (use Thread stack default if not specified)
-     *  `C` : Maximum number of retries allowed after a transmission failure
-     *        (use Thread stack default if not specified)
-     *  `b` : Set to true to enable CSMA-CA for this packet, false otherwise.
-     *        (default true).
-     *
-     */
-    SPINEL_PROP_STREAM_RAW = SPINEL_PROP_STREAM__BEGIN + 1,
-
-    /// (IPv6) Network Stream
-    /** Format: `dD` (stream, read only)
-     *
-     * This stream provides the capability of sending and receiving (IPv6)
-     * data packets to and from the currently attached network. The packets
-     * are sent or received securely (encryption and authentication).
-     *
-     * This property is a streaming property, meaning that you cannot explicitly
-     * fetch the value of this property. To receive traffic, you wait for
-     * `CMD_PROP_VALUE_IS` commands with this property id from the NCP.
-     *
-     * To send network packets, you call `CMD_PROP_VALUE_SET` on this property with
-     * the value of the packet.
-     *
-     * The general format of this property is:
-     *
-     *    `d` : packet data
-     *    `D` : packet meta data
-     *
-     * The packet metadata is optional. Packet meta data MAY be empty or partially
-     * specified. Partially specified metadata MUST be accepted. Default values
-     * are used for all unspecified fields.
-     *
-     * For OpenThread the meta data is currently empty.
-     *
-     */
-    SPINEL_PROP_STREAM_NET = SPINEL_PROP_STREAM__BEGIN + 2,
-
-    /// (IPv6) Network Stream Insecure
-    /** Format: `dD` (stream, read only)
-     *
-     * This stream provides the capability of sending and receiving unencrypted
-     * and unauthenticated data packets to and from nearby devices for the
-     * purposes of device commissioning.
-     *
-     * This property is a streaming property, meaning that you cannot explicitly
-     * fetch the value of this property. To receive traffic, you wait for
-     * `CMD_PROP_VALUE_IS` commands with this property id from the NCP.
-     *
-     * To send network packets, you call `CMD_PROP_VALUE_SET` on this property with
-     * the value of the packet.
-     *
-     * The general format of this property is:
-     *
-     *    `d` : packet data
-     *    `D` : packet meta data
-     *
-     * The packet metadata is optional. Packet meta data MAY be empty or partially
-     * specified. Partially specified metadata MUST be accepted. Default values
-     * are used for all unspecified fields.
-     *
-     * For OpenThread the meta data is currently empty.
-     *
-     */
-    SPINEL_PROP_STREAM_NET_INSECURE = SPINEL_PROP_STREAM__BEGIN + 3,
-
-    /// Log Stream
-    /** Format: `UD` (stream, read only)
-     *
-     * This property is a read-only streaming property which provides
-     * formatted log string from NCP. This property provides asynchronous
-     * `CMD_PROP_VALUE_IS` updates with a new log string and includes
-     * optional meta data.
-     *
-     *   `U`: The log string
-     *   `D`: Log metadata (optional).
-     *
-     * Any data after the log string is considered metadata and is OPTIONAL.
-     * Presence of `SPINEL_CAP_OPENTHREAD_LOG_METADATA` capability
-     * indicates that OpenThread log metadata format is used as defined
-     * below:
-     *
-     *    `C`: Log level (as per definition in enumeration
-     *         `SPINEL_NCP_LOG_LEVEL_<level>`)
-     *    `i`: OpenThread Log region (as per definition in enumeration
-     *         `SPINEL_NCP_LOG_REGION_<region>).
-     *    `X`: Log timestamp = <timestamp_base> + <current_time_ms>
-     *
-     */
-    SPINEL_PROP_STREAM_LOG = SPINEL_PROP_STREAM__BEGIN + 4,
-
-    SPINEL_PROP_STREAM__END = 0x80,
-
-    SPINEL_PROP_STREAM_EXT__BEGIN = 0x1700,
-    SPINEL_PROP_STREAM_EXT__END   = 0x1800,
-
-    SPINEL_PROP_MESHCOP__BEGIN = 0x80,
-
-    // Thread Joiner State
-    /** Format `C` - Read Only
-     *
-     * Required capability: SPINEL_CAP_THREAD_JOINER
-     *
-     * The valid values are specified by `spinel_meshcop_joiner_state_t` (`SPINEL_MESHCOP_JOINER_STATE_<state>`)
-     * enumeration.
-     *
-     */
-    SPINEL_PROP_MESHCOP_JOINER_STATE = SPINEL_PROP_MESHCOP__BEGIN + 0, ///<[C]
-
-    /// Thread Joiner Commissioning command and the parameters
-    /** Format `b` or `bU(UUUUU)` (fields in parenthesis are optional) - Write Only
-     *
-     * This property starts or stops Joiner's commissioning process
-     *
-     * Required capability: SPINEL_CAP_THREAD_JOINER
-     *
-     * Writing to this property starts/stops the Joiner commissioning process.
-     * The immediate `VALUE_IS` response indicates success/failure of the starting/stopping
-     * the Joiner commissioning process.
-     *
-     * After a successful start operation, the join process outcome is reported through an
-     * asynchronous `VALUE_IS(LAST_STATUS)` update with one of the following error status values:
-     *
-     *     - SPINEL_STATUS_JOIN_SUCCESS     the join process succeeded.
-     *     - SPINEL_STATUS_JOIN_SECURITY    the join process failed due to security credentials.
-     *     - SPINEL_STATUS_JOIN_NO_PEERS    no joinable network was discovered.
-     *     - SPINEL_STATUS_JOIN_RSP_TIMEOUT if a response timed out.
-     *     - SPINEL_STATUS_JOIN_FAILURE     join failure.
-     *
-     * Frame format:
-     *
-     *  `b` : Start or stop commissioning process (true to start).
-     *
-     * Only if the start commissioning.
-     *
-     *  `U` : Joiner's PSKd.
-     *
-     * The next fields are all optional. If not provided, OpenThread default values would be used.
-     *
-     *  `U` : Provisioning URL (use empty string if not required).
-     *  `U` : Vendor Name. If not specified or empty string, use OpenThread default (PACKAGE_NAME).
-     *  `U` : Vendor Model. If not specified or empty string, use OpenThread default (OPENTHREAD_CONFIG_PLATFORM_INFO).
-     *  `U` : Vendor Sw Version. If not specified or empty string, use OpenThread default (PACKAGE_VERSION).
-     *  `U` : Vendor Data String. Will not be appended if not specified.
-     *
-     */
-    SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING = SPINEL_PROP_MESHCOP__BEGIN + 1,
-
-    // Thread Commissioner State
-    /** Format `C`
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * The valid values are specified by SPINEL_MESHCOP_COMMISIONER_STATE_<state> enumeration.
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_STATE = SPINEL_PROP_MESHCOP__BEGIN + 2,
-
-    // Thread Commissioner Joiners
-    /** Format `A(t(E)UL)` - insert or remove only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * Data per item is:
-     *
-     *  `t(E)` | `t()`: Joiner EUI64. Empty struct indicates any Joiner
-     *  `L`           : Timeout (in seconds) after which the Joiner is automatically removed
-     *  `U`           : PSKd
-     *
-     * For CMD_PROP_VALUE_REMOVE the timeout and PSKd are optional.
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS = SPINEL_PROP_MESHCOP__BEGIN + 3,
-
-    // Thread Commissioner Provisioning URL
-    /** Format `U`
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL = SPINEL_PROP_MESHCOP__BEGIN + 4,
-
-    // Thread Commissioner Session ID
-    /** Format `S` - Read only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID = SPINEL_PROP_MESHCOP__BEGIN + 5,
-
-    SPINEL_PROP_MESHCOP__END = 0x90,
-
-    SPINEL_PROP_MESHCOP_EXT__BEGIN = 0x1800,
-
-    // Thread Commissioner Announce Begin
-    /** Format `LCS6` - Write only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * Writing to this property sends an Announce Begin message with the specified parameters. Response is a
-     * `LAST_STATUS` update with status of operation.
-     *
-     *   `L` : Channel mask
-     *   `C` : Number of messages per channel
-     *   `S` : The time between two successive MLE Announce transmissions (milliseconds)
-     *   `6` : IPv6 destination
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN = SPINEL_PROP_MESHCOP_EXT__BEGIN + 0,
-
-    // Thread Commissioner Energy Scan Query
-    /** Format `LCSS6` - Write only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * Writing to this property sends an Energy Scan Query message with the specified parameters. Response is a
-     * `LAST_STATUS` with status of operation. The energy scan results are emitted asynchronously through
-     * `SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT` updates.
-     *
-     * Format is:
-     *
-     *   `L` : Channel mask
-     *   `C` : The number of energy measurements per channel
-     *   `S` : The time between energy measurements (milliseconds)
-     *   `S` : The scan duration for each energy measurement (milliseconds)
-     *   `6` : IPv6 destination.
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN = SPINEL_PROP_MESHCOP_EXT__BEGIN + 1,
-
-    // Thread Commissioner Energy Scan Result
-    /** Format `Ld` - Asynchronous event only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * This property provides asynchronous `CMD_PROP_VALUE_INSERTED` updates to report energy scan results for a
-     * previously sent Energy Scan Query message (please see `SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN`).
-     *
-     * Format is:
-     *
-     *   `L` : Channel mask
-     *   `d` : Energy measurement data (note that `d` encoding includes the length)
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT = SPINEL_PROP_MESHCOP_EXT__BEGIN + 2,
-
-    // Thread Commissioner PAN ID Query
-    /** Format `SL6` - Write only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * Writing to this property sends a PAN ID Query message with the specified parameters. Response is a
-     * `LAST_STATUS` with status of operation. The PAN ID Conflict results are emitted asynchronously through
-     * `SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT` updates.
-     *
-     * Format is:
-     *
-     *   `S` : PAN ID to query
-     *   `L` : Channel mask
-     *   `6` : IPv6 destination
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY = SPINEL_PROP_MESHCOP_EXT__BEGIN + 3,
-
-    // Thread Commissioner PAN ID Conflict Result
-    /** Format `SL` - Asynchronous event only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * This property provides asynchronous `CMD_PROP_VALUE_INSERTED` updates to report PAN ID conflict results for a
-     * previously sent PAN ID Query message (please see `SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY`).
-     *
-     * Format is:
-     *
-     *   `S` : The PAN ID
-     *   `L` : Channel mask
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT = SPINEL_PROP_MESHCOP_EXT__BEGIN + 4,
-
-    // Thread Commissioner Send MGMT_COMMISSIONER_GET
-    /** Format `d` - Write only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * Writing to this property sends a MGMT_COMMISSIONER_GET message with the specified parameters. Response is a
-     * `LAST_STATUS` with status of operation.
-     *
-     * Format is:
-     *
-     *   `d` : List of TLV types to get
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_GET = SPINEL_PROP_MESHCOP_EXT__BEGIN + 5,
-
-    // Thread Commissioner Send MGMT_COMMISSIONER_SET
-    /** Format `d` - Write only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * Writing to this property sends a MGMT_COMMISSIONER_SET message with the specified parameters. Response is a
-     * `LAST_STATUS` with status of operation.
-     *
-     * Format is:
-     *
-     *   `d` : TLV encoded data
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_SET = SPINEL_PROP_MESHCOP_EXT__BEGIN + 6,
-
-    // Thread Commissioner Generate PSKc
-    /** Format: `UUd` - Write only
-     *
-     * Required capability: SPINEL_CAP_THREAD_COMMISSIONER
-     *
-     * Writing to this property allows user to generate PSKc from a given commissioning pass-phrase, network name,
-     * extended PAN Id.
-     *
-     * Written value format is:
-     *
-     *   `U` : The commissioning pass-phrase.
-     *   `U` : Network Name.
-     *   `d` : Extended PAN ID.
-     *
-     * The response on success would be a `VALUE_IS` command with the PSKc with format below:
-     *
-     *   `D` : The PSKc
-     *
-     * On a failure a `LAST_STATUS` is emitted with the error status.
-     *
-     */
-    SPINEL_PROP_MESHCOP_COMMISSIONER_GENERATE_PSKC = SPINEL_PROP_MESHCOP_EXT__BEGIN + 7,
-
-    SPINEL_PROP_MESHCOP_EXT__END = 0x1900,
-
-    SPINEL_PROP_OPENTHREAD__BEGIN = 0x1900,
-
-    /// Channel Manager - Channel Change New Channel
-    /** Format: `C` (read-write)
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
-     *
-     * Setting this property triggers the Channel Manager to start
-     * a channel change process. The network switches to the given
-     * channel after the specified delay (see `CHANNEL_MANAGER_DELAY`).
-     *
-     * A subsequent write to this property will cancel an ongoing
-     * (previously requested) channel change.
-     *
-     */
-    SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL = SPINEL_PROP_OPENTHREAD__BEGIN + 0,
-
-    /// Channel Manager - Channel Change Delay
-    /** Format 'S'
-     *  Units: seconds
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
-     *
-     * This property specifies the delay (in seconds) to be used for
-     * a channel change request.
-     *
-     * The delay should preferably be longer than maximum data poll
-     * interval used by all sleepy-end-devices within the Thread
-     * network.
-     *
-     */
-    SPINEL_PROP_CHANNEL_MANAGER_DELAY = SPINEL_PROP_OPENTHREAD__BEGIN + 1,
-
-    /// Channel Manager Supported Channels
-    /** Format 'A(C)'
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
-     *
-     * This property specifies the list of supported channels.
-     *
-     */
-    SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS = SPINEL_PROP_OPENTHREAD__BEGIN + 2,
-
-    /// Channel Manager Favored Channels
-    /** Format 'A(C)'
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
-     *
-     * This property specifies the list of favored channels (when `ChannelManager` is asked to select channel)
-     *
-     */
-    SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS = SPINEL_PROP_OPENTHREAD__BEGIN + 3,
-
-    /// Channel Manager Channel Select Trigger
-    /** Format 'b'
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
-     *
-     * Writing to this property triggers a request on `ChannelManager` to select a new channel.
-     *
-     * Once a Channel Select is triggered, the Channel Manager will perform the following 3 steps:
-     *
-     * 1) `ChannelManager` decides if the channel change would be helpful. This check can be skipped if in the input
-     *    boolean to this property is set to `true` (skipping the quality check).
-     *    This step uses the collected link quality metrics on the device such as CCA failure rate, frame and message
-     *    error rates per neighbor, etc. to determine if the current channel quality is at the level that justifies
-     *    a channel change.
-     *
-     * 2) If first step passes, then `ChannelManager` selects a potentially better channel. It uses the collected
-     *    channel quality data by `ChannelMonitor` module. The supported and favored channels are used at this step.
-     *
-     * 3) If the newly selected channel is different from the current channel, `ChannelManager` requests/starts the
-     *    channel change process.
-     *
-     * Reading this property always yields `false`.
-     *
-     */
-    SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT = SPINEL_PROP_OPENTHREAD__BEGIN + 4,
-
-    /// Channel Manager Auto Channel Selection Enabled
-    /** Format 'b'
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
-     *
-     * This property indicates if auto-channel-selection functionality is enabled/disabled on `ChannelManager`.
-     *
-     * When enabled, `ChannelManager` will periodically checks and attempts to select a new channel. The period interval
-     * is specified by `SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL`.
-     *
-     */
-    SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED = SPINEL_PROP_OPENTHREAD__BEGIN + 5,
-
-    /// Channel Manager Auto Channel Selection Interval
-    /** Format 'L'
-     *  units: seconds
-     *
-     * Required capability: SPINEL_CAP_CHANNEL_MANAGER
-     *
-     * This property specifies the auto-channel-selection check interval (in seconds).
-     *
-     */
-    SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL = SPINEL_PROP_OPENTHREAD__BEGIN + 6,
-
-    /// Thread network time.
-    /** Format: `Xc` - Read only
-     *
-     * Data per item is:
-     *
-     *  `X`: The Thread network time, in microseconds.
-     *  `c`: Time synchronization status.
-     *
-     */
-    SPINEL_PROP_THREAD_NETWORK_TIME = SPINEL_PROP_OPENTHREAD__BEGIN + 7,
-
-    /// Thread time synchronization period
-    /** Format: `S` - Read-Write
-     *
-     * Data per item is:
-     *
-     *  `S`: Time synchronization period, in seconds.
-     *
-     */
-    SPINEL_PROP_TIME_SYNC_PERIOD = SPINEL_PROP_OPENTHREAD__BEGIN + 8,
-
-    /// Thread Time synchronization XTAL accuracy threshold for Router
-    /** Format: `S` - Read-Write
-     *
-     * Data per item is:
-     *
-     *  `S`: The XTAL accuracy threshold for Router, in PPM.
-     *
-     */
-    SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD = SPINEL_PROP_OPENTHREAD__BEGIN + 9,
-
-    /// Child Supervision Interval
-    /** Format: `S` - Read-Write
-     *  Units: Seconds
-     *
-     * Required capability: `SPINEL_CAP_CHILD_SUPERVISION`
-     *
-     * The child supervision interval (in seconds). Zero indicates that child supervision is disabled.
-     *
-     * When enabled, Child supervision feature ensures that at least one message is sent to every sleepy child within
-     * the given supervision interval. If there is no other message, a supervision message (a data message with empty
-     * payload) is enqueued and sent to the child.
-     *
-     * This property is available for FTD build only.
-     *
-     */
-    SPINEL_PROP_CHILD_SUPERVISION_INTERVAL = SPINEL_PROP_OPENTHREAD__BEGIN + 10,
-
-    /// Child Supervision Check Timeout
-    /** Format: `S` - Read-Write
-     *  Units: Seconds
-     *
-     * Required capability: `SPINEL_CAP_CHILD_SUPERVISION`
-     *
-     * The child supervision check timeout interval (in seconds). Zero indicates supervision check on the child is
-     * disabled.
-     *
-     * Supervision check is only applicable on a sleepy child. When enabled, if the child does not hear from its parent
-     * within the specified check timeout, it initiates a re-attach process by starting an MLE Child Update
-     * Request/Response exchange with the parent.
-     *
-     * This property is available for FTD and MTD builds.
-     *
-     */
-    SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT = SPINEL_PROP_OPENTHREAD__BEGIN + 11,
-
-    // RCP (NCP in radio only mode) version
-    /** Format `U` - Read only
-     *
-     * Required capability: SPINEL_CAP_POSIX_APP
-     *
-     * This property gives the version string of RCP (NCP in radio mode) which is being controlled by the POSIX
-     * application. It is available only in "POSIX Application" configuration (i.e., `OPENTHREAD_PLATFORM_POSIX_APP` is
-     * enabled).
-     *
-     */
-    SPINEL_PROP_RCP_VERSION = SPINEL_PROP_OPENTHREAD__BEGIN + 12,
-
-    /// Thread Parent Response info
-    /** Format: `ESccCCCb` - Asynchronous event only
-     *
-     *  `E`: Extended address
-     *  `S`: RLOC16
-     *  `c`: Instant RSSI
-     *  'c': Parent Priority
-     *  `C`: Link Quality3
-     *  `C`: Link Quality2
-     *  `C`: Link Quality1
-     *  'b': Is the node receiving parent response frame attached
-     *
-     * This property sends Parent Response frame information to the Host.
-     * This property is available for FTD build only.
-     *
-     */
-    SPINEL_PROP_PARENT_RESPONSE_INFO = SPINEL_PROP_OPENTHREAD__BEGIN + 13,
-
-    /// SLAAC enabled
-    /** Format `b` - Read-Write
-     *  Required capability: `SPINEL_CAP_SLAAC`
-     *
-     * This property allows the host to enable/disable SLAAC module on NCP at run-time. When SLAAC module is enabled,
-     * SLAAC addresses (based on on-mesh prefixes in Network Data) are added to the interface. When SLAAC module is
-     * disabled any previously added SLAAC address is removed.
-     *
-     */
-    SPINEL_PROP_SLAAC_ENABLED = SPINEL_PROP_OPENTHREAD__BEGIN + 14,
-
-    SPINEL_PROP_OPENTHREAD__END = 0x2000,
-
-    SPINEL_PROP_SERVER__BEGIN = 0xA0,
-
-    /// Server Allow Local Network Data Change
-    /** Format `b` - Read-write
-     *
-     * Required capability: SPINEL_CAP_THREAD_SERVICE
-     *
-     * Set to true before changing local server net data. Set to false when finished.
-     * This allows changes to be aggregated into a single event.
-     *
-     */
-    SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE = SPINEL_PROP_SERVER__BEGIN + 0,
-
-    // Server Services
-    /** Format: `A(t(LdbdS))`
-     *
-     * This property provides all services registered on the device
-     *
-     * Required capability: SPINEL_CAP_THREAD_SERVICE
-     *
-     * Array of structures containing:
-     *
-     *  `L`: Enterprise Number
-     *  `d`: Service Data
-     *  `b`: Stable
-     *  `d`: Server Data
-     *  `S`: RLOC
-     *
-     */
-    SPINEL_PROP_SERVER_SERVICES = SPINEL_PROP_SERVER__BEGIN + 1,
-
-    // Server Leader Services
-    /** Format: `A(t(CLdbdS))`
-     *
-     * This property provides all services registered on the leader
-     *
-     * Array of structures containing:
-     *
-     *  `C`: Service ID
-     *  `L`: Enterprise Number
-     *  `d`: Service Data
-     *  `b`: Stable
-     *  `d`: Server Data
-     *  `S`: RLOC
-     *
-     */
-    SPINEL_PROP_SERVER_LEADER_SERVICES = SPINEL_PROP_SERVER__BEGIN + 2,
-
-    SPINEL_PROP_SERVER__END = 0xB0,
-
-    SPINEL_PROP_INTERFACE__BEGIN = 0x100,
-
-    /// UART Bitrate
-    /** Format: `L`
-     *
-     *  If the NCP is using a UART to communicate with the host,
-     *  this property allows the host to change the bitrate
-     *  of the serial connection. The value encoding is `L`,
-     *  which is a little-endian 32-bit unsigned integer.
-     *  The host should not assume that all possible numeric values
-     *  are supported.
-     *
-     *  If implemented by the NCP, this property should be persistent
-     *  across software resets and forgotten upon hardware resets.
-     *
-     *  This property is only implemented when a UART is being
-     *  used for Spinel. This property is optional.
-     *
-     *  When changing the bitrate, all frames will be received
-     *  at the previous bitrate until the response frame to this command
-     *  is received. Once a successful response frame is received by
-     *  the host, all further frames will be transmitted at the new
-     *  bitrate.
-     */
-    SPINEL_PROP_UART_BITRATE = SPINEL_PROP_INTERFACE__BEGIN + 0,
-
-    /// UART Software Flow Control
-    /** Format: `b`
-     *
-     *  If the NCP is using a UART to communicate with the host,
-     *  this property allows the host to determine if software flow
-     *  control (XON/XOFF style) should be used and (optionally) to
-     *  turn it on or off.
-     *
-     *  This property is only implemented when a UART is being
-     *  used for Spinel. This property is optional.
-     */
-    SPINEL_PROP_UART_XON_XOFF = SPINEL_PROP_INTERFACE__BEGIN + 1,
-
-    SPINEL_PROP_INTERFACE__END = 0x200,
-
-    SPINEL_PROP_15_4_PIB__BEGIN = 0x400,
-    // For direct access to the 802.15.4 PID.
-    // Individual registers are fetched using
-    // `SPINEL_PROP_15_4_PIB__BEGIN+[PIB_IDENTIFIER]`
-    // Only supported if SPINEL_CAP_15_4_PIB is set.
-    //
-    // For brevity, the entire 802.15.4 PIB space is
-    // not defined here, but a few choice attributes
-    // are defined for illustration and convenience.
-    SPINEL_PROP_15_4_PIB_PHY_CHANNELS_SUPPORTED = SPINEL_PROP_15_4_PIB__BEGIN + 0x01, ///< [A(L)]
-    SPINEL_PROP_15_4_PIB_MAC_PROMISCUOUS_MODE   = SPINEL_PROP_15_4_PIB__BEGIN + 0x51, ///< [b]
-    SPINEL_PROP_15_4_PIB_MAC_SECURITY_ENABLED   = SPINEL_PROP_15_4_PIB__BEGIN + 0x5d, ///< [b]
-    SPINEL_PROP_15_4_PIB__END                   = 0x500,
-
-    SPINEL_PROP_CNTR__BEGIN = 0x500,
-
-    /// Counter reset
-    /** Format: Empty (Write only).
-     *
-     * Writing to this property (with any value) will reset all MAC, MLE, IP, and NCP counters to zero.
-     *
-     */
-    SPINEL_PROP_CNTR_RESET = SPINEL_PROP_CNTR__BEGIN + 0,
-
-    /// The total number of transmissions.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_TOTAL = SPINEL_PROP_CNTR__BEGIN + 1,
-
-    /// The number of transmissions with ack request.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_ACK_REQ = SPINEL_PROP_CNTR__BEGIN + 2,
-
-    /// The number of transmissions that were acked.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_ACKED = SPINEL_PROP_CNTR__BEGIN + 3,
-
-    /// The number of transmissions without ack request.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_NO_ACK_REQ = SPINEL_PROP_CNTR__BEGIN + 4,
-
-    /// The number of transmitted data.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_DATA = SPINEL_PROP_CNTR__BEGIN + 5,
-
-    /// The number of transmitted data poll.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_DATA_POLL = SPINEL_PROP_CNTR__BEGIN + 6,
-
-    /// The number of transmitted beacon.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_BEACON = SPINEL_PROP_CNTR__BEGIN + 7,
-
-    /// The number of transmitted beacon request.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_BEACON_REQ = SPINEL_PROP_CNTR__BEGIN + 8,
-
-    /// The number of transmitted other types of frames.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_OTHER = SPINEL_PROP_CNTR__BEGIN + 9,
-
-    /// The number of retransmission times.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_RETRY = SPINEL_PROP_CNTR__BEGIN + 10,
-
-    /// The number of CCA failure times.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_ERR_CCA = SPINEL_PROP_CNTR__BEGIN + 11,
-
-    /// The number of unicast packets transmitted.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_UNICAST = SPINEL_PROP_CNTR__BEGIN + 12,
-
-    /// The number of broadcast packets transmitted.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_PKT_BROADCAST = SPINEL_PROP_CNTR__BEGIN + 13,
-
-    /// The number of frame transmission failures due to abort error.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_ERR_ABORT = SPINEL_PROP_CNTR__BEGIN + 14,
-
-    /// The total number of received packets.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_TOTAL = SPINEL_PROP_CNTR__BEGIN + 100,
-
-    /// The number of received data.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_DATA = SPINEL_PROP_CNTR__BEGIN + 101,
-
-    /// The number of received data poll.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_DATA_POLL = SPINEL_PROP_CNTR__BEGIN + 102,
-
-    /// The number of received beacon.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_BEACON = SPINEL_PROP_CNTR__BEGIN + 103,
-
-    /// The number of received beacon request.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_BEACON_REQ = SPINEL_PROP_CNTR__BEGIN + 104,
-
-    /// The number of received other types of frames.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_OTHER = SPINEL_PROP_CNTR__BEGIN + 105,
-
-    /// The number of received packets filtered by whitelist.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_FILT_WL = SPINEL_PROP_CNTR__BEGIN + 106,
-
-    /// The number of received packets filtered by destination check.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_FILT_DA = SPINEL_PROP_CNTR__BEGIN + 107,
-
-    /// The number of received packets that are empty.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_ERR_EMPTY = SPINEL_PROP_CNTR__BEGIN + 108,
-
-    /// The number of received packets from an unknown neighbor.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_ERR_UKWN_NBR = SPINEL_PROP_CNTR__BEGIN + 109,
-
-    /// The number of received packets whose source address is invalid.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_ERR_NVLD_SADDR = SPINEL_PROP_CNTR__BEGIN + 110,
-
-    /// The number of received packets with a security error.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_ERR_SECURITY = SPINEL_PROP_CNTR__BEGIN + 111,
-
-    /// The number of received packets with a checksum error.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_ERR_BAD_FCS = SPINEL_PROP_CNTR__BEGIN + 112,
-
-    /// The number of received packets with other errors.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_ERR_OTHER = SPINEL_PROP_CNTR__BEGIN + 113,
-
-    /// The number of received duplicated.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_DUP = SPINEL_PROP_CNTR__BEGIN + 114,
-
-    /// The number of unicast packets received.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_UNICAST = SPINEL_PROP_CNTR__BEGIN + 115,
-
-    /// The number of broadcast packets received.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_PKT_BROADCAST = SPINEL_PROP_CNTR__BEGIN + 116,
-
-    /// The total number of secure transmitted IP messages.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 200,
-
-    /// The total number of insecure transmitted IP messages.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 201,
-
-    /// The number of dropped (not transmitted) IP messages.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_IP_DROPPED = SPINEL_PROP_CNTR__BEGIN + 202,
-
-    /// The total number of secure received IP message.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_IP_SEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 203,
-
-    /// The total number of insecure received IP message.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_IP_INSEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 204,
-
-    /// The number of dropped received IP messages.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_IP_DROPPED = SPINEL_PROP_CNTR__BEGIN + 205,
-
-    /// The number of transmitted spinel frames.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_TX_SPINEL_TOTAL = SPINEL_PROP_CNTR__BEGIN + 300,
-
-    /// The number of received spinel frames.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_SPINEL_TOTAL = SPINEL_PROP_CNTR__BEGIN + 301,
-
-    /// The number of received spinel frames with error.
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_SPINEL_ERR = SPINEL_PROP_CNTR__BEGIN + 302,
-
-    /// Number of out of order received spinel frames (tid increase by more than 1).
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_RX_SPINEL_OUT_OF_ORDER_TID = SPINEL_PROP_CNTR__BEGIN + 303,
-
-    /// The number of successful Tx IP packets
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_IP_TX_SUCCESS = SPINEL_PROP_CNTR__BEGIN + 304,
-
-    /// The number of successful Rx IP packets
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_IP_RX_SUCCESS = SPINEL_PROP_CNTR__BEGIN + 305,
-
-    /// The number of failed Tx IP packets
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_IP_TX_FAILURE = SPINEL_PROP_CNTR__BEGIN + 306,
-
-    /// The number of failed Rx IP packets
-    /** Format: `L` (Read-only) */
-    SPINEL_PROP_CNTR_IP_RX_FAILURE = SPINEL_PROP_CNTR__BEGIN + 307,
-
-    /// The message buffer counter info
-    /** Format: `SSSSSSSSSSSSSSSS` (Read-only)
-     *      `S`, (TotalBuffers)           The number of buffers in the pool.
-     *      `S`, (FreeBuffers)            The number of free message buffers.
-     *      `S`, (6loSendMessages)        The number of messages in the 6lo send queue.
-     *      `S`, (6loSendBuffers)         The number of buffers in the 6lo send queue.
-     *      `S`, (6loReassemblyMessages)  The number of messages in the 6LoWPAN reassembly queue.
-     *      `S`, (6loReassemblyBuffers)   The number of buffers in the 6LoWPAN reassembly queue.
-     *      `S`, (Ip6Messages)            The number of messages in the IPv6 send queue.
-     *      `S`, (Ip6Buffers)             The number of buffers in the IPv6 send queue.
-     *      `S`, (MplMessages)            The number of messages in the MPL send queue.
-     *      `S`, (MplBuffers)             The number of buffers in the MPL send queue.
-     *      `S`, (MleMessages)            The number of messages in the MLE send queue.
-     *      `S`, (MleBuffers)             The number of buffers in the MLE send queue.
-     *      `S`, (ArpMessages)            The number of messages in the ARP send queue.
-     *      `S`, (ArpBuffers)             The number of buffers in the ARP send queue.
-     *      `S`, (CoapMessages)           The number of messages in the CoAP send queue.
-     *      `S`, (CoapBuffers)            The number of buffers in the CoAP send queue.
-     */
-    SPINEL_PROP_MSG_BUFFER_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 400,
-
-    /// All MAC related counters.
-    /** Format: t(A(L))t(A(L))
-     *
-     * The contents include two structs, first one corresponds to
-     * all transmit related MAC counters, second one provides the
-     * receive related counters.
-     *
-     * The transmit structure includes:
-     *
-     *   'L': TxTotal                  (The total number of transmissions).
-     *   'L': TxUnicast                (The total number of unicast transmissions).
-     *   'L': TxBroadcast              (The total number of broadcast transmissions).
-     *   'L': TxAckRequested           (The number of transmissions with ack request).
-     *   'L': TxAcked                  (The number of transmissions that were acked).
-     *   'L': TxNoAckRequested         (The number of transmissions without ack request).
-     *   'L': TxData                   (The number of transmitted data).
-     *   'L': TxDataPoll               (The number of transmitted data poll).
-     *   'L': TxBeacon                 (The number of transmitted beacon).
-     *   'L': TxBeaconRequest          (The number of transmitted beacon request).
-     *   'L': TxOther                  (The number of transmitted other types of frames).
-     *   'L': TxRetry                  (The number of retransmission times).
-     *   'L': TxErrCca                 (The number of CCA failure times).
-     *   'L': TxErrAbort               (The number of frame transmission failures due to abort error).
-     *   'L': TxErrBusyChannel         (The number of frames that were dropped due to a busy channel).
-     *   'L': TxDirectMaxRetryExpiry   (The number of expired retransmission retries for direct message).
-     *   'L': TxIndirectMaxRetryExpiry (The number of expired retransmission retries for indirect message).
-     *
-     * The receive structure includes:
-     *
-     *   'L': RxTotal                  (The total number of received packets).
-     *   'L': RxUnicast                (The total number of unicast packets received).
-     *   'L': RxBroadcast              (The total number of broadcast packets received).
-     *   'L': RxData                   (The number of received data).
-     *   'L': RxDataPoll               (The number of received data poll).
-     *   'L': RxBeacon                 (The number of received beacon).
-     *   'L': RxBeaconRequest          (The number of received beacon request).
-     *   'L': RxOther                  (The number of received other types of frames).
-     *   'L': RxAddressFiltered        (The number of received packets filtered by address filter
-     *                                  (whitelist or blacklist)).
-     *   'L': RxDestAddrFiltered       (The number of received packets filtered by destination check).
-     *   'L': RxDuplicated             (The number of received duplicated packets).
-     *   'L': RxErrNoFrame             (The number of received packets with no or malformed content).
-     *   'L': RxErrUnknownNeighbor     (The number of received packets from unknown neighbor).
-     *   'L': RxErrInvalidSrcAddr      (The number of received packets whose source address is invalid).
-     *   'L': RxErrSec                 (The number of received packets with security error).
-     *   'L': RxErrFcs                 (The number of received packets with FCS error).
-     *   'L': RxErrOther               (The number of received packets with other error).
-     *
-     * Writing to this property with any value would reset all MAC counters to zero.
-     *
-     */
-    SPINEL_PROP_CNTR_ALL_MAC_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 401,
-
-    /// Thread MLE counters.
-    /** Format: `SSSSSSSSS`
-     *
-     *   'S': DisabledRole                  (The number of times device entered OT_DEVICE_ROLE_DISABLED role).
-     *   'S': DetachedRole                  (The number of times device entered OT_DEVICE_ROLE_DETACHED role).
-     *   'S': ChildRole                     (The number of times device entered OT_DEVICE_ROLE_CHILD role).
-     *   'S': RouterRole                    (The number of times device entered OT_DEVICE_ROLE_ROUTER role).
-     *   'S': LeaderRole                    (The number of times device entered OT_DEVICE_ROLE_LEADER role).
-     *   'S': AttachAttempts                (The number of attach attempts while device was detached).
-     *   'S': PartitionIdChanges            (The number of changes to partition ID).
-     *   'S': BetterPartitionAttachAttempts (The number of attempts to attach to a better partition).
-     *   'S': ParentChanges                 (The number of times device changed its parents).
-     *
-     * Writing to this property with any value would reset all MLE counters to zero.
-     *
-     */
-    SPINEL_PROP_CNTR_MLE_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 402,
-
-    /// Thread IPv6 counters.
-    /** Format: `t(LL)t(LL)`
-     *
-     * The contents include two structs, first one corresponds to
-     * all transmit related MAC counters, second one provides the
-     * receive related counters.
-     *
-     * The transmit structure includes:
-     *   'L': TxSuccess (The number of IPv6 packets successfully transmitted).
-     *   'L': TxFailure (The number of IPv6 packets failed to transmit).
-     *
-     * The receive structure includes:
-     *   'L': RxSuccess (The number of IPv6 packets successfully received).
-     *   'L': RxFailure (The number of IPv6 packets failed to receive).
-     *
-     * Writing to this property with any value would reset all IPv6 counters to zero.
-     *
-     */
-    SPINEL_PROP_CNTR_ALL_IP_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 403,
-
-    /// MAC retry histogram.
-    /** Format: t(A(L))t(A(L))
-     *
-     * Required capability: SPINEL_CAP_MAC_RETRY_HISTOGRAM
-     *
-     * The contents include two structs, first one is histogram which corresponds to retransmissions number of direct
-     * messages, second one provides the histogram of retransmissions for indirect messages.
-     *
-     * The first structure includes:
-     *   'L': DirectRetry[0]                   (The number of packets after 0 retry).
-     *   'L': DirectRetry[1]                   (The number of packets after 1 retry).
-     *    ...
-     *   'L': DirectRetry[n]                   (The number of packets after n retry).
-     *
-     * The size of the array is OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_MAX_SIZE_COUNT_DIRECT.
-     *
-     * The second structure includes:
-     *   'L': IndirectRetry[0]                   (The number of packets after 0 retry).
-     *   'L': IndirectRetry[1]                   (The number of packets after 1 retry).
-     *    ...
-     *   'L': IndirectRetry[m]                   (The number of packets after m retry).
-     *
-     * The size of the array is OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_MAX_SIZE_COUNT_INDIRECT.
-     *
-     * Writing to this property with any value would reset MAC retry histogram.
-     *
-     */
-    SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM = SPINEL_PROP_CNTR__BEGIN + 404,
-
-    SPINEL_PROP_CNTR__END = 0x800,
-
-    SPINEL_PROP_NEST__BEGIN = 0x3BC0,
-
-    SPINEL_PROP_NEST_STREAM_MFG = SPINEL_PROP_NEST__BEGIN + 0,
-
-    /// The legacy network ULA prefix (8 bytes)
-    /** Format: 'D' */
-    SPINEL_PROP_NEST_LEGACY_ULA_PREFIX = SPINEL_PROP_NEST__BEGIN + 1,
-
-    /// The EUI64 of last node joined using legacy protocol (if none, all zero EUI64 is returned).
-    /** Format: 'E' */
-    SPINEL_PROP_NEST_LEGACY_LAST_NODE_JOINED = SPINEL_PROP_NEST__BEGIN + 2,
-
-    SPINEL_PROP_NEST__END = 0x3C00,
-
-    SPINEL_PROP_VENDOR__BEGIN = 0x3C00,
-    SPINEL_PROP_VENDOR__END   = 0x4000,
-
-    SPINEL_PROP_DEBUG__BEGIN = 0x4000,
-
-    /// Testing platform assert
-    /** Format: 'b' (read-only)
-     *
-     * Reading this property will cause an assert on the NCP. This is intended for testing the assert functionality of
-     * underlying platform/NCP. Assert should ideally cause the NCP to reset, but if this is not supported a `false`
-     * boolean is returned in response.
-     *
-     */
-    SPINEL_PROP_DEBUG_TEST_ASSERT = SPINEL_PROP_DEBUG__BEGIN + 0,
-
-    /// The NCP log level.
-    /** Format: `C` */
-    SPINEL_PROP_DEBUG_NCP_LOG_LEVEL = SPINEL_PROP_DEBUG__BEGIN + 1,
-
-    /// Testing platform watchdog
-    /** Format: Empty  (read-only)
-     *
-     * Reading this property will causes NCP to start a `while(true) ;` loop and thus triggering a watchdog.
-     *
-     * This is intended for testing the watchdog functionality on the underlying platform/NCP.
-     *
-     */
-    SPINEL_PROP_DEBUG_TEST_WATCHDOG = SPINEL_PROP_DEBUG__BEGIN + 2,
-
-    /// The NCP timestamp base
-    /** Format: X (write-only)
-     *
-     * This property controls the time base value that is used for logs timestamp field calulation.
-     *
-     */
-    SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE = SPINEL_PROP_DEBUG__BEGIN + 3,
-
-    SPINEL_PROP_DEBUG__END = 0x4400,
-
-    SPINEL_PROP_EXPERIMENTAL__BEGIN = 2000000,
-    SPINEL_PROP_EXPERIMENTAL__END   = 2097152,
-};
-
-typedef uint32_t spinel_prop_key_t;
-
-// ----------------------------------------------------------------------------
-
-#define SPINEL_HEADER_FLAG 0x80
-
-#define SPINEL_HEADER_TID_SHIFT 0
-#define SPINEL_HEADER_TID_MASK (15 << SPINEL_HEADER_TID_SHIFT)
-
-#define SPINEL_HEADER_IID_SHIFT 4
-#define SPINEL_HEADER_IID_MASK (3 << SPINEL_HEADER_IID_SHIFT)
-
-#define SPINEL_HEADER_IID_0 (0 << SPINEL_HEADER_IID_SHIFT)
-#define SPINEL_HEADER_IID_1 (1 << SPINEL_HEADER_IID_SHIFT)
-#define SPINEL_HEADER_IID_2 (2 << SPINEL_HEADER_IID_SHIFT)
-#define SPINEL_HEADER_IID_3 (3 << SPINEL_HEADER_IID_SHIFT)
-
-#define SPINEL_HEADER_GET_IID(x) (((x)&SPINEL_HEADER_IID_MASK) >> SPINEL_HEADER_IID_SHIFT)
-#define SPINEL_HEADER_GET_TID(x) (spinel_tid_t)(((x)&SPINEL_HEADER_TID_MASK) >> SPINEL_HEADER_TID_SHIFT)
-
-#define SPINEL_GET_NEXT_TID(x) (spinel_tid_t)((x) >= 0xF ? 1 : (x) + 1)
-
-#define SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT 4
-
-#define SPINEL_BEACON_THREAD_FLAG_VERSION_MASK (0xf << SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT)
-
-#define SPINEL_BEACON_THREAD_FLAG_JOINABLE (1 << 0)
-
-#define SPINEL_BEACON_THREAD_FLAG_NATIVE (1 << 3)
-
-// ----------------------------------------------------------------------------
-
-enum
-{
-    SPINEL_DATATYPE_NULL_C        = 0,
-    SPINEL_DATATYPE_VOID_C        = '.',
-    SPINEL_DATATYPE_BOOL_C        = 'b',
-    SPINEL_DATATYPE_UINT8_C       = 'C',
-    SPINEL_DATATYPE_INT8_C        = 'c',
-    SPINEL_DATATYPE_UINT16_C      = 'S',
-    SPINEL_DATATYPE_INT16_C       = 's',
-    SPINEL_DATATYPE_UINT32_C      = 'L',
-    SPINEL_DATATYPE_INT32_C       = 'l',
-    SPINEL_DATATYPE_UINT64_C      = 'X',
-    SPINEL_DATATYPE_INT64_C       = 'x',
-    SPINEL_DATATYPE_UINT_PACKED_C = 'i',
-    SPINEL_DATATYPE_IPv6ADDR_C    = '6',
-    SPINEL_DATATYPE_EUI64_C       = 'E',
-    SPINEL_DATATYPE_EUI48_C       = 'e',
-    SPINEL_DATATYPE_DATA_WLEN_C   = 'd',
-    SPINEL_DATATYPE_DATA_C        = 'D',
-    SPINEL_DATATYPE_UTF8_C        = 'U', //!< Zero-Terminated UTF8-Encoded String
-    SPINEL_DATATYPE_STRUCT_C      = 't',
-    SPINEL_DATATYPE_ARRAY_C       = 'A',
-};
-
-typedef char spinel_datatype_t;
-
-#define SPINEL_DATATYPE_NULL_S ""
-#define SPINEL_DATATYPE_VOID_S "."
-#define SPINEL_DATATYPE_BOOL_S "b"
-#define SPINEL_DATATYPE_UINT8_S "C"
-#define SPINEL_DATATYPE_INT8_S "c"
-#define SPINEL_DATATYPE_UINT16_S "S"
-#define SPINEL_DATATYPE_INT16_S "s"
-#define SPINEL_DATATYPE_UINT32_S "L"
-#define SPINEL_DATATYPE_INT32_S "l"
-#define SPINEL_DATATYPE_UINT64_S "X"
-#define SPINEL_DATATYPE_INT64_S "x"
-#define SPINEL_DATATYPE_UINT_PACKED_S "i"
-#define SPINEL_DATATYPE_IPv6ADDR_S "6"
-#define SPINEL_DATATYPE_EUI64_S "E"
-#define SPINEL_DATATYPE_EUI48_S "e"
-#define SPINEL_DATATYPE_DATA_WLEN_S "d"
-#define SPINEL_DATATYPE_DATA_S "D"
-#define SPINEL_DATATYPE_UTF8_S "U" //!< Zero-Terminated UTF8-Encoded String
-
-#define SPINEL_DATATYPE_ARRAY_S(x) "A(" x ")"
-#define SPINEL_DATATYPE_STRUCT_S(x) "t(" x ")"
-
-#define SPINEL_DATATYPE_ARRAY_STRUCT_S(x) SPINEL_DATATYPE_ARRAY_S(SPINEL_DATATYPE_STRUCT_WLEN_S(x))
-
-#define SPINEL_DATATYPE_COMMAND_S                   \
-    SPINEL_DATATYPE_UINT8_S           /* header  */ \
-        SPINEL_DATATYPE_UINT_PACKED_S /* command */
-
-#define SPINEL_DATATYPE_COMMAND_PROP_S                    \
-    SPINEL_DATATYPE_COMMAND_S         /* prop command  */ \
-        SPINEL_DATATYPE_UINT_PACKED_S /* property id */
-
-#define SPINEL_MAX_UINT_PACKED 2097151
-
-SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_pack(uint8_t *     data_out,
-                                                      spinel_size_t data_len_max,
-                                                      const char *  pack_format,
-                                                      ...);
-SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_vpack(uint8_t *     data_out,
-                                                       spinel_size_t data_len_max,
-                                                       const char *  pack_format,
-                                                       va_list       args);
-SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_unpack(const uint8_t *data_in,
-                                                        spinel_size_t  data_len,
-                                                        const char *   pack_format,
-                                                        ...);
-/**
- * This function parses spinel data similar to sscanf().
- *
- * This function actually calls spinel_datatype_vunpack_in_place() to parse data.
- *
- * @param[in]   data_in     A pointer to the data to parse.
- * @param[in]   data_len    The length of @p data_in in bytes.
- * @param[in]   pack_format C string that contains a format string follows the same specification of spinel.
- * @param[in]   ...         Additional arguments depending on the format string @p pack_format.
- *
- * @returns The parsed length in bytes.
- *
- * @note This function behaves different from `spinel_datatype_unpack()`:
- *       - This function expects composite data arguments of pointer to data type, while `spinel_datatype_unpack()`
- *         expects them of pointer to data type pointer. For example, if `SPINEL_DATATYPE_EUI64_C` is present in
- *         @p pack_format, this function expects a `spinel_eui64_t *` is included in variable arguments, while
- *         `spinel_datatype_unpack()` expects a `spinel_eui64_t **` is included.
- *       - For `SPINEL_DATATYPE_UTF8_C`, this function expects two arguments, the first of type `char *` and the
- *         second is of type `size_t` to indicate length of the provided buffer in the first argument just like
- *         `strncpy()`, while `spinel_datatype_unpack()` only expects a `const char **`.
- *
- * @sa spinel_datatype_vunpack_in_place()
- *
- */
-SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_unpack_in_place(const uint8_t *data_in,
-                                                                 spinel_size_t  data_len,
-                                                                 const char *   pack_format,
-                                                                 ...);
-SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_vunpack(const uint8_t *data_in,
-                                                         spinel_size_t  data_len,
-                                                         const char *   pack_format,
-                                                         va_list        args);
-/**
- * This function parses spinel data similar to vsscanf().
- *
- * @param[in]   data_in     A pointer to the data to parse.
- * @param[in]   data_len    The length of @p data_in in bytes.
- * @param[in]   pack_format C string that contains a format string follows the same specification of spinel.
- * @param[in]   args        A value identifying a variable arguments list.
- *
- * @returns The parsed length in bytes.
- *
- * @note This function behaves different from `spinel_datatype_vunpack()`:
- *       - This function expects composite data arguments of pointer to data type, while `spinel_datatype_vunpack()`
- *         expects them of pointer to data type pointer. For example, if `SPINEL_DATATYPE_EUI64_C` is present in
- *         @p pack_format, this function expects a `spinel_eui64_t *` is included in variable arguments, while
- *         `spinel_datatype_vunpack()` expects a `spinel_eui64_t **` is included.
- *       - For `SPINEL_DATATYPE_UTF8_C`, this function expects two arguments, the first of type `char *` and the
- *         second is of type `size_t` to indicate length of the provided buffer in the first argument just like
- *         `strncpy()`, while `spinel_datatype_vunpack()` only expects a `const char **`.
- *
- * @sa spinel_datatype_unpack_in_place()
- *
- */
-SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_vunpack_in_place(const uint8_t *data_in,
-                                                                  spinel_size_t  data_len,
-                                                                  const char *   pack_format,
-                                                                  va_list        args);
-
-SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_decode(const uint8_t *bytes,
-                                                           spinel_size_t  len,
-                                                           unsigned int * value_ptr);
-SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_encode(uint8_t *bytes, spinel_size_t len, unsigned int value);
-SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_size(unsigned int value);
-
-SPINEL_API_EXTERN const char *spinel_next_packed_datatype(const char *pack_format);
-
-// ----------------------------------------------------------------------------
-
-SPINEL_API_EXTERN const char *spinel_command_to_cstr(spinel_command_t command);
-
-SPINEL_API_EXTERN const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key);
-
-SPINEL_API_EXTERN const char *spinel_net_role_to_cstr(uint8_t net_role);
-
-SPINEL_API_EXTERN const char *spinel_mcu_power_state_to_cstr(uint8_t mcu_power_state);
-
-SPINEL_API_EXTERN const char *spinel_status_to_cstr(spinel_status_t status);
-
-SPINEL_API_EXTERN const char *spinel_capability_to_cstr(spinel_capability_t capability);
-
-// ----------------------------------------------------------------------------
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* defined(SPINEL_HEADER_INCLUDED) */
diff --git a/src/ncp/spinel_decoder.cpp b/src/ncp/spinel_decoder.cpp
deleted file mode 100644
index 43f1618..0000000
--- a/src/ncp/spinel_decoder.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- *    Copyright (c) 2017, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements a spinel decoder.
- */
-
-#include <openthread/config.h>
-
-#include "spinel_decoder.hpp"
-
-#include "common/code_utils.hpp"
-#include "common/string.hpp"
-
-namespace ot {
-namespace Ncp {
-
-SpinelDecoder::SpinelDecoder(void)
-    : mFrame(NULL)
-    , mLength(0)
-    , mIndex(0)
-    , mEnd(0)
-    , mNumOpenStructs(0)
-    , mSavedNumOpenStructs(0)
-    , mSavedIndex(0)
-    , mSavedEnd(0)
-{
-}
-
-void SpinelDecoder::Init(const uint8_t *aFrame, uint16_t aLength)
-{
-    mFrame  = aFrame;
-    mLength = (mFrame != NULL) ? aLength : 0;
-
-    Reset();
-    ClearSavedPosition();
-}
-
-void SpinelDecoder::Reset(void)
-{
-    mIndex          = 0;
-    mEnd            = mLength;
-    mNumOpenStructs = 0;
-    ClearSavedPosition();
-}
-
-otError SpinelDecoder::ReadBool(bool &aBool)
-{
-    otError error = OT_ERROR_NONE;
-    uint8_t byte;
-
-    SuccessOrExit(error = ReadUint8(byte));
-
-    // Boolean value are encoded in 8-bits as either 0x00 or 0x01. All other values are illegal.
-    if (byte == 0x00)
-    {
-        aBool = false;
-    }
-    else if (byte == 0x01)
-    {
-        aBool = true;
-    }
-    else
-    {
-        error = OT_ERROR_PARSE;
-    }
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadUint8(uint8_t &aUint8)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mIndex + sizeof(uint8_t) <= mEnd, error = OT_ERROR_PARSE);
-    aUint8 = mFrame[mIndex];
-    mIndex += sizeof(uint8_t);
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadInt8(int8_t &aInt8)
-{
-    otError error = OT_ERROR_NONE;
-    uint8_t byte;
-
-    SuccessOrExit(error = ReadUint8(byte));
-    aInt8 = static_cast<int8_t>(byte);
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadUint16(uint16_t &aUint16)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mIndex + sizeof(uint16_t) <= mEnd, error = OT_ERROR_PARSE);
-
-    aUint16 = static_cast<uint16_t>(mFrame[mIndex] | (mFrame[mIndex + 1] << 8));
-
-    mIndex += sizeof(uint16_t);
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadInt16(int16_t &aInt16)
-{
-    otError  error = OT_ERROR_NONE;
-    uint16_t u16;
-
-    SuccessOrExit(error = ReadUint16(u16));
-    aInt16 = static_cast<int16_t>(u16);
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadUint32(uint32_t &aUint32)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mIndex + sizeof(uint32_t) <= mEnd, error = OT_ERROR_PARSE);
-
-    aUint32 = ((static_cast<uint32_t>(mFrame[mIndex + 0]) << 0) | (static_cast<uint32_t>(mFrame[mIndex + 1]) << 8) |
-               (static_cast<uint32_t>(mFrame[mIndex + 2]) << 16) | (static_cast<uint32_t>(mFrame[mIndex + 3]) << 24));
-
-    mIndex += sizeof(uint32_t);
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadInt32(int32_t &aInt32)
-{
-    otError  error = OT_ERROR_NONE;
-    uint32_t u32;
-
-    SuccessOrExit(error = ReadUint32(u32));
-    aInt32 = static_cast<int32_t>(u32);
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadUint64(uint64_t &aUint64)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mIndex + sizeof(uint64_t) <= mEnd, error = OT_ERROR_PARSE);
-
-    aUint64 = ((static_cast<uint64_t>(mFrame[mIndex + 0]) << 0) | (static_cast<uint64_t>(mFrame[mIndex + 1]) << 8) |
-               (static_cast<uint64_t>(mFrame[mIndex + 2]) << 16) | (static_cast<uint64_t>(mFrame[mIndex + 3]) << 24) |
-               (static_cast<uint64_t>(mFrame[mIndex + 4]) << 32) | (static_cast<uint64_t>(mFrame[mIndex + 5]) << 40) |
-               (static_cast<uint64_t>(mFrame[mIndex + 6]) << 48) | (static_cast<uint64_t>(mFrame[mIndex + 7]) << 56));
-
-    mIndex += sizeof(uint64_t);
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadInt64(int64_t &aInt64)
-{
-    otError  error = OT_ERROR_NONE;
-    uint64_t u64;
-
-    SuccessOrExit(error = ReadUint64(u64));
-    aInt64 = static_cast<int64_t>(u64);
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadUintPacked(unsigned int &aUint)
-{
-    otError        error = OT_ERROR_NONE;
-    spinel_ssize_t parsedLen;
-    unsigned int   uint;
-
-    parsedLen = spinel_packed_uint_decode(&mFrame[mIndex], mEnd - mIndex, &uint);
-    VerifyOrExit(parsedLen > 0, error = OT_ERROR_PARSE);
-
-    mIndex += parsedLen;
-    aUint = uint;
-
-exit:
-    return error;
-}
-
-// Reads an item of given size and updates the pointer `aPtr`.
-otError SpinelDecoder::ReadItem(const uint8_t **aPtr, uint16_t aSize)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mIndex + aSize <= mEnd, error = OT_ERROR_PARSE);
-
-    *aPtr = &mFrame[mIndex];
-
-    mIndex += aSize;
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadIp6Address(spinel_ipv6addr_t &aIp6Addr)
-{
-    otError                  error = OT_ERROR_NONE;
-    const spinel_ipv6addr_t *ipv6AddrPtr;
-
-    SuccessOrExit(error = ReadIp6Address(ipv6AddrPtr));
-    aIp6Addr = *ipv6AddrPtr;
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadIp6Address(otIp6Address &aIp6Addr)
-{
-    otError             error = OT_ERROR_NONE;
-    const otIp6Address *ipv6AddrPtr;
-
-    SuccessOrExit(error = ReadIp6Address(ipv6AddrPtr));
-    aIp6Addr = *ipv6AddrPtr;
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadEui64(spinel_eui64_t &aEui64)
-{
-    otError               error = OT_ERROR_NONE;
-    const spinel_eui64_t *eui64Ptr;
-
-    SuccessOrExit(error = ReadEui64(eui64Ptr));
-    aEui64 = *eui64Ptr;
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadEui64(otExtAddress &aEui64)
-{
-    otError             error = OT_ERROR_NONE;
-    const otExtAddress *eui64Ptr;
-
-    SuccessOrExit(error = ReadEui64(eui64Ptr));
-    aEui64 = *eui64Ptr;
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadEui48(spinel_eui48_t &aEui48)
-{
-    otError               error = OT_ERROR_NONE;
-    const spinel_eui48_t *eui48Ptr;
-
-    SuccessOrExit(error = ReadEui48(eui48Ptr));
-    aEui48 = *eui48Ptr;
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadUtf8(const char *&aUtf8)
-{
-    otError error = OT_ERROR_NONE;
-    size_t  len;
-
-    // Ensure there is at least one byte (for null character).
-    VerifyOrExit(mIndex + sizeof(uint8_t) <= mEnd, error = OT_ERROR_PARSE);
-
-    len = StringLength(reinterpret_cast<const char *>(&mFrame[mIndex]), mEnd - mIndex);
-    VerifyOrExit(len < static_cast<uint16_t>(mEnd - mIndex), error = OT_ERROR_PARSE);
-
-    aUtf8 = reinterpret_cast<const char *>(&mFrame[mIndex]);
-
-    // `sizeof(uint8_t)` is added for the terminating null character.
-    mIndex += static_cast<uint16_t>(len + sizeof(uint8_t));
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::ReadData(const uint8_t *&aData, uint16_t &aDataLen)
-{
-    aDataLen = mEnd - mIndex;
-
-    return ReadItem(&aData, aDataLen);
-}
-
-otError SpinelDecoder::ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen)
-{
-    otError  error = OT_ERROR_NONE;
-    uint16_t len;
-
-    SuccessOrExit(error = ReadUint16(len));
-    SuccessOrExit(error = ReadItem(&aData, len));
-    aDataLen = len;
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::OpenStruct(void)
-{
-    otError  error = OT_ERROR_NONE;
-    uint16_t structLen;
-
-    VerifyOrExit(mNumOpenStructs < kMaxNestedStructs, error = OT_ERROR_INVALID_STATE);
-
-    SuccessOrExit(error = ReadUint16(structLen));
-    VerifyOrExit(structLen <= mEnd - mIndex, error = OT_ERROR_PARSE);
-
-    mPrevEnd[mNumOpenStructs] = mEnd;
-    mEnd                      = (mIndex + structLen);
-    mNumOpenStructs++;
-
-exit:
-    return error;
-}
-
-otError SpinelDecoder::CloseStruct(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mNumOpenStructs > 0, error = OT_ERROR_INVALID_STATE);
-
-    // If there is a saved position and it is contained
-    // within the current struct being closed, the saved
-    // position is cleared to ensure user cannot go back
-    // to middle of an already closed struct.
-
-    if (IsSavedPositionValid() && (mNumOpenStructs == mSavedNumOpenStructs))
-    {
-        ClearSavedPosition();
-    }
-
-    mNumOpenStructs--;
-    mIndex = mEnd;
-    mEnd   = mPrevEnd[mNumOpenStructs];
-
-exit:
-    return error;
-}
-
-void SpinelDecoder::SavePosition(void)
-{
-    mSavedIndex          = mIndex;
-    mSavedEnd            = mEnd;
-    mSavedNumOpenStructs = mNumOpenStructs;
-}
-
-otError SpinelDecoder::ResetToSaved(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(IsSavedPositionValid(), error = OT_ERROR_INVALID_STATE);
-
-    mIndex          = mSavedIndex;
-    mEnd            = mSavedEnd;
-    mNumOpenStructs = mSavedNumOpenStructs;
-
-exit:
-    return error;
-}
-
-} // namespace Ncp
-} // namespace ot
diff --git a/src/ncp/spinel_decoder.hpp b/src/ncp/spinel_decoder.hpp
deleted file mode 100644
index 8267e77..0000000
--- a/src/ncp/spinel_decoder.hpp
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- *    Copyright (c) 2017, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file contains the definitions of a spinel decoder.
- */
-
-#ifndef SPINEL_DECODER_HPP_
-#define SPINEL_DECODER_HPP_
-
-#include <openthread/config.h>
-
-#include <openthread/ip6.h>
-#include <openthread/ncp.h>
-
-#include "openthread-core-config.h"
-#include "ncp/spinel.h"
-
-namespace ot {
-namespace Ncp {
-
-/**
- * This class defines a spinel decoder.
- *
- */
-class SpinelDecoder
-{
-public:
-    enum
-    {
-        kMaxNestedStructs = 4, ///< Maximum number of nested structs.
-    };
-
-    /**
-     * This constructor initializes a `SpinelDecoder` object.
-     *
-     */
-    SpinelDecoder(void);
-
-    /**
-     * This method initializes the decoder to start decoding a new frame.
-     *
-     * It sets the read position to the start of the frame and also erases/voids any saved positions (see
-     * `SavePosition()` and `ResetToSaved()` methods).
-     *
-     * @param[in] aFrame                Pointer to the buffer containing the frame to be decoded.
-     * @param[in] aLength               Length (number of bytes) of the frame.
-     *
-     */
-    void Init(const uint8_t *aFrame, uint16_t aLength);
-
-    /**
-     * This method returns the pointer to the start of the frame.
-     *
-     * @returns A pointer to buffer containing current frame being decoded.
-     *
-     */
-    const uint8_t *GetFrame(void) const { return mFrame; }
-
-    /**
-     * This method returns the total length of current frame being decoded.
-     *
-     * @returns The length of current frame being decoded.
-     *
-     */
-    uint16_t GetLength(void) const { return mLength; }
-
-    /**
-     * This method returns the number of bytes that are already read/decoded from the frame.
-     *
-     * @returns The number of bytes already read from frame.
-     *
-     */
-    uint16_t GetReadLength(void) const { return mIndex; }
-
-    /**
-     * This method returns the number of remaining (not yet read/decoded) bytes in the frame.
-     *
-     * @returns The number of remaining unread bytes in the frame.
-     *
-     */
-    uint16_t GetRemainingLength(void) const { return mLength - mIndex; }
-
-    /**
-     * This method indicates whether or not all the bytes in the frame are read.
-     *
-     * @returns TRUE if all the bytes in the buffer are read, FALSE otherwise.
-     *
-     */
-    bool IsAllRead(void) const { return (mIndex == mLength); }
-
-    /**
-     * This method resets the read position to beginning of frame. It will also void/erase any previously saved
-     * position using `SavePosition()` method.
-     *
-     */
-    void Reset(void);
-
-    /**
-     * This method decodes and reads a boolean value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aBool                Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadBool(bool &aBool);
-
-    /**
-     * This method decodes and reads an `int8_t` value form the frame.
-     *
-     * On success, the read position get updated.
-     *
-     * @param[out] aInt8                Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadInt8(int8_t &aInt8);
-
-    /**
-     * This method decodes and reads an `uint8_t` value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aUint8               Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadUint8(uint8_t &aUint8);
-
-    /**
-     * This method decodes and reads an `int16_t` value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aInt16               Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadInt16(int16_t &aInt16);
-
-    /**
-     * This method decodes and reads an `uint16_t` value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aUint16              Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadUint16(uint16_t &aUint16);
-
-    /**
-     * This method decodes and reads an `int32_t` value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aInt32               Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadInt32(int32_t &aInt32);
-
-    /**
-     * This method decodes and reads an `uint32_t` value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aUint32              Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadUint32(uint32_t &aUint32);
-
-    /**
-     * This method decodes and reads an `int64_t` value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aInt64               Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadInt64(int64_t &aInt64);
-
-    /**
-     * This method decodes and reads an `uint64_t` value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aUint64              Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadUint64(uint64_t &aUint64);
-
-    /**
-     * This method decodes (using spinel packed integer format) and reads an unsigned integer value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aUint                Reference to variable to output the read value.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadUintPacked(unsigned int &aUint);
-
-    /**
-     * This method decodes and reads an IPv6 address form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aIp6AddrPtr          Reference to IPv6 address pointer to output the value (as `spinel_ipv6addr_t`).
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadIp6Address(const spinel_ipv6addr_t *&aIp6AddrPtr)
-    {
-        return ReadItem(reinterpret_cast<const uint8_t **>(&aIp6AddrPtr), sizeof(spinel_ipv6addr_t));
-    }
-
-    /**
-     * This method decodes and reads an IPv6 address form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aIp6AddrPtr          Reference to IPv6 address pointer to output the value (as `otIp6Address`).
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadIp6Address(const otIp6Address *&aIp6AddrPtr)
-    {
-        return ReadItem(reinterpret_cast<const uint8_t **>(&aIp6AddrPtr), sizeof(spinel_ipv6addr_t));
-    }
-
-    /**
-     * This method decodes and reads an IPv6 address form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aIp6AddrBufPtr       Reference to a buffer pointer to output the value.
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadIp6Address(const uint8_t *&aIp6AddrBufPtr)
-    {
-        return ReadItem(&aIp6AddrBufPtr, sizeof(spinel_ipv6addr_t));
-    }
-
-    /**
-     * This method decodes and reads an IPv6 address form the frame.
-     *
-     * On success, the read position gets updated and the IP address is copied into the given output variable.
-     *
-     * @param[out] aIp6Addr             Reference to IPv6 address variable to output the value (as `spinel_ipv6addr_t`).
-     *                                  On success, the address is copied into the output variable.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadIp6Address(spinel_ipv6addr_t &aIp6Addr);
-
-    /**
-     * This method decodes and reads an IPv6 address form the frame.
-     *
-     * On success, the read position gets updated and the IP address is copied into the given output variable.
-     *
-     * @param[out] aIp6Addr             Reference to IPv6 address variable to output the value (as `otIp6Address`).
-     *                                  On success, the address is copied into the output variable.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadIp6Address(otIp6Address &aIp6Addr);
-
-    /**
-     * This method decodes and reads an EUI64 value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aEui64Ptr            Reference to an EUI64 pointer to output the value (as `spinel_eui64_t`).
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadEui64(const spinel_eui64_t *&aEui64Ptr)
-    {
-        return ReadItem(reinterpret_cast<const uint8_t **>(&aEui64Ptr), sizeof(spinel_eui64_t));
-    }
-
-    /**
-     * This method decodes and reads an EUI64 value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aEui64Ptr            Reference to an EUI64 pointer to output the value (as `otExtAddress`).
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadEui64(const otExtAddress *&aEui64Ptr)
-    {
-        return ReadItem(reinterpret_cast<const uint8_t **>(&aEui64Ptr), sizeof(spinel_eui64_t));
-    }
-
-    /**
-     * This method decodes and reads an EUI64 value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aEui64BufPtr         Reference to a buffer pointer to output the value.
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadEui64(const uint8_t *&aEui64BufPtr) { return ReadItem(&aEui64BufPtr, sizeof(spinel_eui64_t)); }
-
-    /**
-     * This method decodes and reads an EUI64 value form the frame.
-     *
-     * On success, the read position gets updated and the EUI64 value is copied into the given output variable.
-     *
-     * @param[out] aEui64               Reference to EUI64 variable to output the value (as `spinel_eui64_t`).
-     *                                  On success, the address is copied into the output variable.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadEui64(spinel_eui64_t &aEui64);
-
-    /**
-     * This method decodes and reads an EUI64 value form the frame.
-     *
-     * On success, the read position gets updated and the EUI64 value is copied into the given output variable.
-     *
-     * @param[out] aEui64               Reference to EUI64 variable to output the value (as `otExtAddress`).
-     *                                  On success, the address is copied into the output variable.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadEui64(otExtAddress &aEui64);
-
-    /**
-     * This method decodes and reads an EUI48 value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aEui48Ptr            Reference to an EUI48 pointer to output the value (as `spinel_eui48_t`).
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadEui48(const spinel_eui48_t *&aEui48Ptr)
-    {
-        return ReadItem(reinterpret_cast<const uint8_t **>(&aEui48Ptr), sizeof(spinel_eui48_t));
-    }
-
-    /**
-     * This method decodes and reads an EUI48 value form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aEui48BufPtr         Reference to a buffer pointer to output the value.
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadEui48(const uint8_t *&aEui48BufPtr) { return ReadItem(&aEui48BufPtr, sizeof(spinel_eui48_t)); }
-
-    /**
-     * This method decodes and reads an EUI48 value form the frame.
-     *
-     * On success, the read position gets updated and the EUI48 value is copied into the given output variable.
-     *
-     * @param[out] aEui48               Reference to EUI48 variable to output the value (as `spinel_eui48_t`).
-     *                                  On success, value is copied into the output variable.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadEui48(spinel_eui48_t &aEui48);
-
-    /**
-     * This method decodes and reads a UTF8 string form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aUtf8                Reference to a `char` pointer to output the string.
-     *                                  On success, the pointer variable is updated.
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadUtf8(const char *&aUtf8);
-
-    /**
-     * This method decodes and reads a data blob (sequence of bytes) form the frame.
-     *
-     * On success, the read position gets updated.
-     *
-     * @param[out] aData                Reference to pointer variable to output the data.
-     *                                  On success, the pointer variable is updated.
-     * @param[out] aDataLength          Reference to variable to output the data length (number of bytes).
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadData(const uint8_t *&aData, uint16_t &aDataLen);
-
-    /**
-     * This method decodes and reads a data blob (sequence of bytes) with data length.
-     *
-     * The data length is assumed to be prepended before the data content (encoded as a `uint16_t`). The size of the
-     * length field should not be included in the length value. This method corresponds to `SPINEL_DATATYPE_DATA_WLEN`
-     * type.
-     *
-     * @param[out] aData                Reference to pointer variable to output the data.
-     *                                  On success, the pointer variable is updated.
-     * @param[out] aDataLength          Reference to variable to out the data length (number of bytes).
-     *
-     * @retval OT_ERROR_NONE            Successfully read the value.
-     * @retval OT_ERROR_PARSE           Failed to parse/decode the value.
-     *
-     */
-    otError ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen);
-
-    /**
-     * This method opens a struct in the frame.
-     *
-     * After a successful call to this method, all the subsequent `Read{SomeType}()` methods decode and read the
-     * field/value from the current open struct until the struct is closed using `CloseStruct()` method. Structures can
-     * be nested. Up to `kMaxNestedStructs` nested structs can be opened at the same time.
-     *
-     * @retval OT_ERROR_NONE            Successfully opened a struct.
-     * @retval OT_ERROR_PARSE           Failed to parse/open a struct.
-     * @retval OT_ERROR_INVALID_STATE   Already at the maximum number of nested open structures.
-     *
-     */
-    otError OpenStruct(void);
-
-    /**
-     * This method closes the most recently opened struct (using `OpenStruct()`) in the frame.
-     *
-     * On success, the read position is moved to end of the struct skipping any unread bytes within the struct.
-     *
-     * @retval OT_ERROR_NONE            Successfully closed the struct.
-     * @retval OT_ERROR_INVALID_STATE   There is no current open struct to close.
-     *
-     */
-    otError CloseStruct(void);
-
-    /**
-     * This method returns the number of remaining/unread bytes in the current inner-most open structure.
-     *
-     * If there is no currently open structure the number of remaining bytes in whole frame is returned instead.
-     *
-     * @returns The number of remaining unread bytes in the inner-most open structure.
-     *
-     */
-    uint16_t GetRemainingLengthInStruct(void) const { return mEnd - mIndex; }
-
-    /**
-     * This method indicates whether or not all the bytes in inner-most open structure are read.
-     *
-     * If there is no currently open structure, the whole frame is considered instead.
-     *
-     * @returns TRUE if all the bytes are read, FALSE otherwise.
-     *
-     */
-    bool IsAllReadInStruct(void) const { return (mIndex == mEnd); }
-
-    /**
-     * This method saves the current read position in the frame.
-     *
-     * A subsequent call to `SavePosition()` will overwrite the previously saved position. The saved position can be
-     * used to move the read position back (using `ResetToSaved()`) and re-read the same content.
-     *
-     * Saved position can be within an open struct, and it remembers its enclosing struct. When the enclosing struct is
-     * closed, the saved position will be voided and can no longer be used. This ensures that we cannot jump back to
-     * middle an already fully decoded/read and closed struct.
-     *
-     */
-    void SavePosition(void);
-
-    /**
-     * This method resets/moves the read position to a previously saved position.
-     *
-     * The saved position remembers its enclosing structure. When `ResetToSaved()` is called, the current open
-     * structure will be the same as when position was saved.
-     *
-     * @retval OT_ERROR_NONE            Successfully reset the read position.
-     * @retval OT_ERROR_INVALID_STATE   The saved position is not valid (there is no saved position or the saved
-     *                                  position was voided since its enclosing struct was closed).
-     *
-     */
-    otError ResetToSaved(void);
-
-private:
-    otError ReadItem(const uint8_t **aPtr, uint16_t aSize);
-    void    ClearSavedPosition(void) { mSavedIndex = mLength; }
-    bool    IsSavedPositionValid(void) const { return (mSavedIndex < mLength); }
-
-    const uint8_t *mFrame;          // Frame buffer.
-    uint16_t       mLength;         // Frame length (number of bytes).
-    uint16_t       mIndex;          // Current read index.
-    uint16_t       mEnd;            // Current end index (end of struct if in a struct, or end of buffer otherwise).
-    uint8_t        mNumOpenStructs; // Number of open structs.
-
-    uint8_t  mSavedNumOpenStructs; // Number of open structs when read position was saved.
-    uint16_t mSavedIndex;          // Read index when position was saved.
-    uint16_t mSavedEnd;            // End index when position was saved.
-
-    uint16_t mPrevEnd[kMaxNestedStructs];
-};
-
-} // namespace Ncp
-} // namespace ot
-
-#endif // SPINEL_DECODER_HPP_
diff --git a/src/ncp/spinel_encoder.cpp b/src/ncp/spinel_encoder.cpp
deleted file mode 100644
index 332a04b..0000000
--- a/src/ncp/spinel_encoder.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- *    Copyright (c) 2017, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements a spinel encoder.
- */
-
-#include "spinel_encoder.hpp"
-
-#include <string.h>
-
-#include "common/code_utils.hpp"
-
-namespace ot {
-namespace Ncp {
-
-otError SpinelEncoder::BeginFrame(NcpFrameBuffer::Priority aPriority)
-{
-    mNumOpenStructs = 0;
-    mNcpBuffer.InFrameBegin(aPriority);
-    return OT_ERROR_NONE;
-}
-
-otError SpinelEncoder::BeginFrame(uint8_t aHeader, unsigned int aCommand)
-{
-    otError error = OT_ERROR_NONE;
-
-    // Non-zero TID indicates this is a response to a spinel command.
-
-    if (SPINEL_HEADER_GET_TID(aHeader) != 0)
-    {
-        SuccessOrExit(error = BeginFrame(NcpFrameBuffer::kPriorityHigh));
-    }
-    else
-    {
-        SuccessOrExit(error = BeginFrame(NcpFrameBuffer::kPriorityLow));
-    }
-
-    SuccessOrExit(error = WriteUint8(aHeader));
-    SuccessOrExit(error = WriteUintPacked(aCommand));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::BeginFrame(uint8_t aHeader, unsigned int aCommand, spinel_prop_key_t aKey)
-{
-    otError error = OT_ERROR_NONE;
-
-    SuccessOrExit(error = BeginFrame(aHeader, aCommand));
-
-    // The write position is saved before writing the property key,
-    // so that if fetching the property fails and we need to
-    // reply with a `LAST_STATUS` error we can get back to
-    // this saved write position and update the property key.
-    // (Also see `OverwriteWithLastStatusError()`).
-
-    SuccessOrExit(error = SavePosition());
-    SuccessOrExit(error = WriteUintPacked(aKey));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::OverwriteWithLastStatusError(spinel_status_t aStatus)
-{
-    otError error = OT_ERROR_NONE;
-
-    SuccessOrExit(error = ResetToSaved());
-    SuccessOrExit(error = WriteUintPacked(SPINEL_PROP_LAST_STATUS));
-    SuccessOrExit(error = WriteUintPacked(aStatus));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::EndFrame(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    while (mNumOpenStructs > 0)
-    {
-        SuccessOrExit(error = CloseStruct());
-    }
-
-    error = mNcpBuffer.InFrameEnd();
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::WriteUint16(uint16_t aUint16)
-{
-    otError error = OT_ERROR_NONE;
-
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint16 >> 0) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint16 >> 8) & 0xff));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::WriteUint32(uint32_t aUint32)
-{
-    otError error = OT_ERROR_NONE;
-
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 0) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 8) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 16) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 24) & 0xff));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::WriteUint64(uint64_t aUint64)
-{
-    otError error = OT_ERROR_NONE;
-
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 0) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 8) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 16) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 24) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 32) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 40) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 48) & 0xff));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 56) & 0xff));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::WriteUintPacked(unsigned int aUint)
-{
-    uint8_t        buffer[6];
-    spinel_ssize_t len;
-
-    len = spinel_packed_uint_encode(buffer, sizeof(buffer), aUint);
-
-    return WriteData(buffer, static_cast<uint16_t>(len));
-}
-
-otError SpinelEncoder::WriteDataWithLen(const uint8_t *aData, uint16_t aDataLen)
-{
-    otError error = OT_ERROR_NONE;
-
-    SuccessOrExit(error = WriteUint16(aDataLen));
-    SuccessOrExit(error = WriteData(aData, aDataLen));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::WriteUtf8(const char *aUtf8)
-{
-    otError error;
-    size_t  len = strlen(aUtf8);
-
-    if (len >= 0xffff)
-    {
-        len = 0xffff;
-    }
-
-    SuccessOrExit(error = WriteData(reinterpret_cast<const uint8_t *>(aUtf8), static_cast<uint16_t>(len)));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte(0));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::OpenStruct(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mNumOpenStructs < kMaxNestedStructs, error = OT_ERROR_INVALID_STATE);
-    SuccessOrExit(error = mNcpBuffer.InFrameGetPosition(mStructPosition[mNumOpenStructs]));
-
-    // Reserve bytes for the length to be filled when the struct gets closed.
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte(0));
-    SuccessOrExit(error = mNcpBuffer.InFrameFeedByte(0));
-
-    mNumOpenStructs++;
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::CloseStruct(void)
-{
-    otError  error = OT_ERROR_NONE;
-    uint16_t len;
-    uint8_t  buffer[sizeof(uint16_t)];
-
-    VerifyOrExit(mNumOpenStructs > 0, error = OT_ERROR_INVALID_STATE);
-
-    mNumOpenStructs--;
-
-    len = mNcpBuffer.InFrameGetDistance(mStructPosition[mNumOpenStructs]);
-    VerifyOrExit(len >= sizeof(uint16_t), error = OT_ERROR_INVALID_STATE);
-
-    len -= sizeof(uint16_t);
-
-    buffer[0] = (len >> 0 & 0xff);
-    buffer[1] = (len >> 8 & 0xff);
-
-    SuccessOrExit(error = mNcpBuffer.InFrameOverwrite(mStructPosition[mNumOpenStructs], buffer, sizeof(buffer)));
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::SavePosition(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    SuccessOrExit(error = mNcpBuffer.InFrameGetPosition(mSavedPosition));
-    mSavedNumOpenStructs = mNumOpenStructs;
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::ResetToSaved(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    SuccessOrExit(error = mNcpBuffer.InFrameReset(mSavedPosition));
-    mNumOpenStructs = mSavedNumOpenStructs;
-
-exit:
-    return error;
-}
-
-otError SpinelEncoder::WritePacked(const char *aPackFormat, ...)
-{
-    uint8_t        buf[kPackFormatBufferSize];
-    otError        error = OT_ERROR_NONE;
-    spinel_ssize_t packedLen;
-    va_list        args;
-
-    va_start(args, aPackFormat);
-
-    packedLen = spinel_datatype_vpack(buf, sizeof(buf), aPackFormat, args);
-    VerifyOrExit((packedLen > 0) && (packedLen <= static_cast<spinel_ssize_t>(sizeof(buf))), error = OT_ERROR_NO_BUFS);
-
-    error = mNcpBuffer.InFrameFeedData(buf, static_cast<uint16_t>(packedLen));
-
-exit:
-    va_end(args);
-
-    return error;
-}
-
-otError SpinelEncoder::WriteVPacked(const char *aPackFormat, va_list aArgs)
-{
-    uint8_t        buf[kPackFormatBufferSize];
-    otError        error = OT_ERROR_NONE;
-    spinel_ssize_t packedLen;
-
-    packedLen = spinel_datatype_vpack(buf, sizeof(buf), aPackFormat, aArgs);
-    VerifyOrExit((packedLen > 0) && (packedLen <= static_cast<spinel_ssize_t>(sizeof(buf))), error = OT_ERROR_NO_BUFS);
-
-    error = mNcpBuffer.InFrameFeedData(buf, static_cast<uint16_t>(packedLen));
-
-exit:
-    return error;
-}
-
-} // namespace Ncp
-} // namespace ot
diff --git a/src/ncp/spinel_encoder.hpp b/src/ncp/spinel_encoder.hpp
deleted file mode 100644
index 4565496..0000000
--- a/src/ncp/spinel_encoder.hpp
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- *    Copyright (c) 2017, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file contains the definitions of a spinel encoder.
- */
-
-#ifndef SPINEL_ENCODER_HPP_
-#define SPINEL_ENCODER_HPP_
-
-#include "openthread-core-config.h"
-
-#include <openthread/ip6.h>
-#include <openthread/message.h>
-#include <openthread/ncp.h>
-
-#include "openthread-core-config.h"
-#include "ncp/ncp_buffer.hpp"
-#include "ncp/spinel.h"
-
-namespace ot {
-namespace Ncp {
-
-/**
- * This class defines a spinel encoder.
- *
- */
-class SpinelEncoder
-{
-public:
-    /**
-     * This constructor initializes a `SpinelEncoder` object.
-     *
-     * @param[in] aNcpBuffer   A reference to a `NcpFrameBuffer` where the frames are written.
-     *
-     */
-    explicit SpinelEncoder(NcpFrameBuffer &aNcpBuffer)
-        : mNcpBuffer(aNcpBuffer)
-        , mNumOpenStructs(0)
-        , mSavedNumOpenStructs(0)
-        , mSavedPosition()
-    {
-    }
-
-    /**
-     * This method begins a new frame to be added/written to the frame buffer.
-     *
-     * If there is a previous frame being written (for which `EndFrame()` has not yet been called), calling
-     * `BeginFrame()` will discard and clear the previous unfinished frame.
-     *
-     * @param[in] aPriority             Priority level of the new input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully started a new frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to start a new frame.
-     *
-     */
-    otError BeginFrame(NcpFrameBuffer::Priority aPriority);
-
-    /**
-     * This method begins a new spinel command frame to be added/written to the frame buffer.
-     *
-     * If there is a previous frame being written (for which `EndFrame()` has not yet been called), calling
-     * `BeginFrame()` will discard and clear the previous unfinished frame.
-     *
-     * The spinel transaction ID (TID) in the given spinel header is used to determine the priority level of the new
-     * frame. Non-zero TID value indicates that the frame is a response and therefore it uses higher priority level.
-     *
-     * @param[in] aHeader               Spinel header for new the command frame.
-     * @param[in] aCommand              Spinel command.
-     *
-     * @retval OT_ERROR_NONE            Successfully started a new frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to start a new frame.
-     *
-     */
-    otError BeginFrame(uint8_t aHeader, unsigned int aCommand);
-
-    /**
-     * This method begins a new spinel property update command frame to be added/written to the frame buffer.
-     *
-     * If there is a previous frame being written (for which `EndFrame()` has not yet been called), calling
-     * `BeginFrame()` will discard and clear the previous unfinished frame.
-     *
-     * The spinel transaction ID (TID) in the given spinel header is used to determine the priority level of the new
-     * frame. Non-zero TID value indicates that the frame is a response and therefore it uses higher priority level.
-     *
-     * This method saves the write position before the property key (see also `SavePosition()`) so that if fetching the
-     * property fails and the property key should be switched to `LAST_STATUS` with an error status, the saved
-     * position can be used to update the property key in the frame (see also `OverwriteWithLastStatusError()`)
-     *
-     * @param[in] aHeader               Spinel header for new the command frame.
-     * @param[in] aCommand              Spinel command.
-     * @param[in] aKey                  Spinel property key
-     *
-     * @retval OT_ERROR_NONE            Successfully started a new frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to start a new frame.
-     *
-     */
-    otError BeginFrame(uint8_t aHeader, unsigned int aCommand, spinel_prop_key_t aKey);
-
-    /**
-     * This method overwrites the property key with `LAST_STATUS` in a property update command frame.
-     *
-     * This method should be only used after a successful `BeginFrame(aHeader, aCommand, aPropertKey)`, otherwise, its
-     * behavior is undefined.
-     *
-     * This method moves the write position back to saved position by `BeginFrame()` and replaces the property key
-     * `SPINEL_PROP_LAST_STATUS` and writes the given spinel status error.
-     *
-     * @param[in] aStatus               Spinel error status
-     *
-     * @retval OT_ERROR_NONE            Successfully updated the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to update the frame.
-     *
-     */
-    otError OverwriteWithLastStatusError(spinel_status_t aStatus);
-
-    /**
-     * This method finalizes/ends the current frame being written to the buffer.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new frame. Otherwise, this method
-     * does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the frame and return error status
-     * `OT_ERROR_NO_BUFS`.
-     *
-     * This method ensures to close any open structure (previously opened using `OpenStruct()` but not closed using
-     * `CloseStruct()`).
-     *
-     * @retval OT_ERROR_NONE            Successfully ended the input frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add message.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError EndFrame(void);
-
-    /**
-     * This method encodes and writes a boolean value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aBool                The boolean value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given byte to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteBool(bool aBool) { return mNcpBuffer.InFrameFeedByte(aBool ? 0x01 : 0x00); }
-
-    /**
-     * This method encodes and writes a `uint8_t` value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aUint8               The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteUint8(uint8_t aUint8) { return mNcpBuffer.InFrameFeedByte(aUint8); }
-
-    /**
-     * This method encodes and writes an `int8_t` value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aInt8                The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteInt8(int8_t aInt8) { return WriteUint8(static_cast<uint8_t>(aInt8)); }
-
-    /**
-     * This method encodes and writes a `uint16_t` value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aUint16              The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteUint16(uint16_t aUint16);
-
-    /**
-     * This method encodes and writes an `int16_t` value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aInt16              The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteInt16(int16_t aInt16) { return WriteUint16(static_cast<uint16_t>(aInt16)); }
-
-    /**
-     * This method encodes and writes a `uint32_t` value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aUint32              The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteUint32(uint32_t aUint32);
-
-    /**
-     * This method encodes and writes an `int32_t` value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aInt32               The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteInt32(int32_t aInt32) { return WriteUint32(static_cast<uint32_t>(aInt32)); }
-
-    /**
-     * This method encodes and writes a `uint64_t` value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aUint64              The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteUint64(uint64_t aUint64);
-
-    /**
-     * This method encodes and writes an `int64_t` value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aInt64               The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteInt64(int64_t aInt64) { return WriteUint64(static_cast<uint64_t>(aInt64)); }
-
-    /**
-     * This method encodes (using spinel packed integer format) and writes a value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aUint                The value to add to input frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteUintPacked(unsigned int aUint);
-
-    /**
-     * This method encodes and writes an IPv6 address to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aIp6Addr             A reference to the IPv6 address to be added (as `spinel_ipv6addr_t`)
-     *
-     * @retval OT_ERROR_NONE            Successfully added given address to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the IP address.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteIp6Address(const spinel_ipv6addr_t &aIp6Addr) { return WriteIp6Address(aIp6Addr.bytes); }
-
-    /**
-     * This method encodes and writes an IPv6 address to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aIp6Addr             A reference to the IPv6 address to be added (as `otIp6Address`)
-     *
-     * @retval OT_ERROR_NONE            Successfully added given address to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the IP address.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteIp6Address(const otIp6Address &aIp6Addr) { return WriteIp6Address(aIp6Addr.mFields.m8); }
-
-    /**
-     * This method encodes and writes an IPv6 address to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aIp6AddrBuf          A pointer to a buffer containing the IPv6 address.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given address to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the IP address.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteIp6Address(const uint8_t *aIp6AddrBuf) { return WriteData(aIp6AddrBuf, sizeof(spinel_ipv6addr_t)); }
-
-    /**
-     * This method encodes and writes an EUI64 value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aEui64               A reference to the EUI64 value as a `spinel_eui64_t` type.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI64 value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteEui64(const spinel_eui64_t &aEui64) { return WriteEui64(aEui64.bytes); }
-
-    /**
-     * This method encodes and writes an EUI64 value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aExtAddress          A reference to an `otExtAddress`
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI64 value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteEui64(const otExtAddress &aExtAddress) { return WriteEui64(aExtAddress.m8); }
-
-    /**
-     * This method encodes and writes an EUI64 value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aExtAddress          A pointer to a buffer containing the EUI64 value.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI64 value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteEui64(const uint8_t *aEui64) { return WriteData(aEui64, sizeof(spinel_eui64_t)); }
-
-    /**
-     * This method encodes and writes an EUI48 value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aEui48               A reference to the EUI48 value.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI48 value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteEui48(const spinel_eui48_t &aEui48) { return WriteEui48(aEui48.bytes); }
-
-    /**
-     * This method encodes and writes an EUI48 value to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aEui48               A pointer to a buffer containing the EUI64 value.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given value to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the EUI48 value.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteEui48(const uint8_t *aEui48) { return WriteData(aEui48, sizeof(spinel_eui48_t)); }
-
-    /**
-     * This method encodes and writes a UTF8 string to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aUtf8                A const character pointer (C string).
-     *
-     * @retval OT_ERROR_NONE            Successfully added given string to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the string.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteUtf8(const char *aUtf8);
-
-    /**
-     * This method encodes and writes a sequence of bytes to current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aData                A pointer to data buffer.
-     * @param[in]  aDataLen             The length (number of bytes) in the data buffer.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given data to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteData(const uint8_t *aData, uint16_t aDataLen) { return mNcpBuffer.InFrameFeedData(aData, aDataLen); }
-
-    /**
-     * This method encodes and writes a data blob (sequence of bytes) with its length prepended before the data.
-     *
-     * The length of the data (in bytes) is prepended (with the length encoded as a `uint16`). The size of the length
-     * field is not included in the length. This is similar to `SPINEL_DATATYPE_DATA_WLEN` type.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * @param[in]  aData                A pointer to data buffer.
-     * @param[in]  aDataLen             The length (number of bytes) in the data buffer.
-     *
-     * @retval OT_ERROR_NONE            Successfully added given data to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteDataWithLen(const uint8_t *aData, uint16_t aDataLen);
-
-#if OPENTHREAD_MTD || OPENTHREAD_FTD
-    /**
-     * This method adds a message to the current input frame.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the frame and return error status
-     * `OT_ERROR_NO_BUFS`.
-     *
-     * The ownership of the passed-in message @p aMessage changes to underlying `NcpFrameBuffer` ONLY when the entire
-     * frame is successfully finished (i.e., with a successful call to `EndFrame()` for the current frame being
-     * written), and in this case the `otMessage` instance will be freed once the frame is removed from the
-     * `NcpFrameBuffer`. However, if the frame gets discarded before it is finished (e.g., running out of buffer space),
-     * the  `otMessage` instance remains unchanged.
-     *
-     * @param[in] aMessage              A message to be added to current frame.
-     *
-     * @retval OT_ERROR_NONE            Successfully added the message to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the message.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     * @retval OT_ERROR_INVALID_ARGS    If @p aMessage is NULL.
-     *
-     */
-    otError WriteMessage(otMessage *aMessage) { return mNcpBuffer.InFrameFeedMessage(aMessage); }
-#endif
-
-    /**
-     * This method encodes and writes a set of variables to the current input frame using a given spinel packing format
-     * string.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * Note that the encoded buffer should fit in `kPackFormatBufferSize` bytes.
-     *
-     * @param[in]  aPackFormat          A string giving the spinel packing format.
-     * @param[in]  ...                  Variable arguments corresponding to the types given in @p aPackFormat (see
-     *                                  `spinel_datatype_pack()`).
-     *
-     * @retval OT_ERROR_NONE            Successfully added given data to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WritePacked(const char *aPackFormat, ...);
-
-    /**
-     * This method encodes and writes a set of variables to the current input frame using a given spinel packing format
-     * string.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the current input frame and return the
-     * error status `OT_ERROR_NO_BUFS`.
-     *
-     * Note that the encoded buffer should fit in `kPackFormatBufferSize` bytes.
-     *
-     * @param[in]  aPackFormat          A string giving the spinel packing format.
-     * @param[in]  aArgs                Variable arguments corresponding to the types given in @p aPackFormat (see
-     *                                  `spinel_datatype_pack()`).
-     *
-     * @retval OT_ERROR_NONE            Successfully added given data to the frame.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to add the byte.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError WriteVPacked(const char *aPackFormat, va_list aArgs);
-
-    /**
-     * This method opens a struct in the current input frame.
-     *
-     * After a successful call to this method, all the subsequent `Write<SomeType>()` methods add the field/value to
-     * the current open struct until the struct is closed using `CloseStruct()` method. Structures can be nested. Up to
-     * `kMaxNestedStructs` nested structs can be opened at the same time.
-     *
-     * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this
-     * method does nothing and returns error status `OT_ERROR_INVALID_STATE`.
-     *
-     * If no buffer space is available, this method will discard and clear the frame and return error status
-     * `OT_ERROR_NO_BUFS`.
-     *
-     * @retval OT_ERROR_NONE            Successfully opened the struct.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to open the struct.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame or if we reached
-     *                                  the maximum number of nested open structures.
-     *
-     */
-    otError OpenStruct(void);
-
-    /**
-     * This method closes the most recently opened struct (using `OpenStruct()`) in the current input frame.
-     *
-     * Each call to `CloseStruct()` must correspond to an earlier successfully opened struct. If a frame is ended using
-     * `EndFrame()` with remaining open structs, the `EndFrame()` method will close all the remaining structs.
-     *
-     * If no buffer space is available, this method will discard and clear the frame and return error status
-     * `OT_ERROR_NO_BUFS`.
-     *
-     * @retval OT_ERROR_NONE            Successfully closed the most recently opened struct.
-     * @retval OT_ERROR_NO_BUFS         Insufficient buffer space available to open the struct.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame or if there is no
-     *                                  open struct to close
-     */
-    otError CloseStruct(void);
-
-    /**
-     * This method saves the current write position in the input frame.
-     *
-     * The saved position can later be used to discard a portion of written/encoded frame and move the write pointer
-     * back to the saved position (using `ResetToSaved()`).
-     *
-     * @retval OT_ERROR_NONE            Successfully saved current write position in @p aPosition.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     *
-     */
-    otError SavePosition(void);
-
-    /**
-     * This method resets the write position of input frame back to a previously saved position. Any added content
-     * after the write position is discarded.
-     *
-     * The saved position must belong to the same input frame saved earlier with `SavePosition()`. This method cannot
-     * be used if the input frame has an added `otMessage`.
-     *
-     * @retval OT_ERROR_NONE            Successfully reset the write position of current input frame.
-     * @retval OT_ERROR_INVALID_STATE   `BeginFrame()` has not been called earlier to start the frame.
-     * @retval OT_ERROR_INVALID_ARGS    The saved position is not valid (does not belong to same input frame), or
-     *                                  the input frame has an added `otMessage`.
-     *
-     */
-    otError ResetToSaved(void);
-
-private:
-    enum
-    {
-        kPackFormatBufferSize = 96, ///< Size of buffer used when encoding using `WritePacked()` or `WriteVPacked()`.
-        kMaxNestedStructs     = 4,  ///< Maximum number of nested structs.
-    };
-
-    NcpFrameBuffer &              mNcpBuffer;
-    NcpFrameBuffer::WritePosition mStructPosition[kMaxNestedStructs];
-    uint8_t                       mNumOpenStructs;
-
-    uint8_t                       mSavedNumOpenStructs;
-    NcpFrameBuffer::WritePosition mSavedPosition;
-};
-
-} // namespace Ncp
-} // namespace ot
-
-#endif // SPINEL_ENCODER_HPP_
diff --git a/src/ncp/spinel_encrypter.hpp b/src/ncp/spinel_encrypter.hpp
deleted file mode 100644
index 8fe9510..0000000
--- a/src/ncp/spinel_encrypter.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *    Copyright (c) 2018, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Allows to encrypt spinel frames sent between Application Processor (AP) and Network Co-Processor (NCP).
- */
-
-namespace SpinelEncrypter {
-
-/**
- * Encrypts spinel frames before sending to AP/NCP.
- *
- * This method encrypts outbound frames in both directions, i.e. from AP to NCP and from NCP to AP.
- *
- * @param[in,out] aFrameBuf Pointer to buffer containing the frame, also where the encrypted frame will be placed.
- * @param[in] aFrameSize Max number of bytes in frame buffer (max length of spinel frame + additional data for encryption).
- * @param[in,out] aFrameLength Pointer to store frame length, on input value is set to frame length,
- * on output changed to show the frame length after encryption.
- * @return \c true on success, \c false otherwise.
- */
-bool EncryptOutbound(unsigned char *aFrameBuf, size_t aFrameSize, size_t *aFrameLength);
-
-/**
- * Decrypts spinel frames received from AP/NCP.
- *
- * This method decrypts inbound frames in both directions, i.e. from AP to NCP and from NCP to AP.
- *
- * @param[in,out] aFrameBuf Pointer to buffer containing encrypted frame, also where the decrypted frame will be placed.
- * @param[in] aFrameSize Max number of bytes in frame buffer (max length of spinel frame + additional data for encryption).
- * @param[in,out] aFrameLength Pointer to store frame length, on input value is set to encrypted frame length,
- * on output changed to show the frame length after decryption.
- * @return \c true on success, \c false otherwise.
- */
-bool DecryptInbound(unsigned char *aFrameBuf, size_t aFrameSize, size_t *aFrameLength);
-
-} // namespace SpinelEncrypter
diff --git a/src/ncp/spinel_platform.h b/src/ncp/spinel_platform.h
deleted file mode 100644
index d0263cb..0000000
--- a/src/ncp/spinel_platform.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *    Copyright (c) 2017, The OpenThread Authors.
- *    All rights reserved.
- *
- *    Redistribution and use in source and binary forms, with or without
- *    modification, are permitted provided that the following conditions are met:
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *    3. Neither the name of the copyright holder nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SPINEL_PLATFORM_OPENTHREAD_H_
-#define SPINEL_PLATFORM_OPENTHREAD_H_
-
-/**
- * This is the platform header file used for spinel on
- * OpenThread.
- *
- * To make spinel code more portable, all header file
- * `#include`s are defined in a platform specific header
- * file "spinel_platform.h" which is then included from
- * "spinel.h".
- *
- * This file should include the following header files (or
- * their equivalent on the platform):
- *
- *   #include <stdarg.h>
- *   #include <stdbool.h>
- *   #include <stdint.h>
- *   #include <stdio.h>
- *   #include <stdlib.h>
- *   #include <string.h>
- *
- */
-
-#include "openthread-core-config.h"
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#endif // SPINEL_PLATFORM_OPENTHREAD_H_
diff --git a/src/posix/CMakeLists.txt b/src/posix/CMakeLists.txt
index 920584f..907e84c 100644
--- a/src/posix/CMakeLists.txt
+++ b/src/posix/CMakeLists.txt
@@ -28,71 +28,53 @@
 
 set(COMMON_INCLUDES
     ${OT_PUBLIC_INCLUDES}
-    ${OT_PRIVATE_INCLUDES}
+    ${PROJECT_SOURCE_DIR}/src
     ${PROJECT_SOURCE_DIR}/src/core
     ${PROJECT_SOURCE_DIR}/src/posix/platform
+    ${PROJECT_SOURCE_DIR}/src/posix/platform/include
 )
 
+set(OT_READLINE "readline" CACHE STRING "set readline library name")
+set_property(CACHE OT_READLINE PROPERTY STRINGS "readline" "edit")
+
+if(OT_READLINE)
+    find_library(READLINE ${OT_READLINE})
+
+    if (NOT READLINE)
+        message(FATAL_ERROR "Failed to find ${OT_READLINE}")
+    endif()
+
+    find_library(NCURSES ncurses)
+    if (NOT NCURSES)
+        message(FATAL_ERROR "Failed to find ncurses")
+    endif()
+
+    list(APPEND READLINE_LINK_LIBRARIES "${READLINE}" "${NCURSES}")
+endif()
+
 if(OT_DAEMON)
-    add_executable(ot-daemon
-        main.c
-    )
+    include(daemon.cmake)
 
-    target_include_directories(ot-daemon PRIVATE ${COMMON_INCLUDES})
-
-    target_compile_definitions(ot-daemon PRIVATE
-        OPENTHREAD_POSIX_APP_TYPE=2
-    )
-
-    target_link_libraries(ot-daemon PRIVATE
-        openthread-cli-ftd
-        ${OT_PLATFORM_LIB}
-        openthread-ftd
-        ${OT_PLATFORM_LIB}
-        openthread-ncp-ftd
-        mbedcrypto
-    )
-
-    add_executable(ot-ctl
-        client.c
-    )
-
-    target_include_directories(ot-ctl PRIVATE ${COMMON_INCLUDES})
+    if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
+        set(CPACK_PACKAGE_NAME "openthread-daemon")
+    endif()
 else()
-    add_executable(ot-cli
-        main.c
-    )
+    if(OT_APP_CLI)
+        include(cli.cmake)
+    endif()
 
-    target_include_directories(ot-cli PRIVATE ${COMMON_INCLUDES})
+    if(OT_APP_NCP)
+        include(ncp.cmake)
+    endif()
 
-    target_compile_definitions(ot-cli PRIVATE
-        OPENTHREAD_POSIX_APP_TYPE=2
-    )
+    if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
+        set(CPACK_PACKAGE_NAME "openthread-standalone")
+    endif()
+endif()
 
-    target_link_libraries(ot-cli
-        openthread-cli-ftd
-        ${OT_PLATFORM_LIB}
-        openthread-ftd
-        ${OT_PLATFORM_LIB}
-        mbedcrypto
-        openthread-ncp-ftd
-    )
-
-    add_executable(ot-ncp
-        main.c
-    )
-    target_include_directories(ot-ncp PRIVATE ${COMMON_INCLUDES})
-
-    target_compile_definitions(ot-ncp PRIVATE
-        OPENTHREAD_POSIX_APP_TYPE=1
-    )
-
-    target_link_libraries(ot-ncp
-        openthread-ncp-ftd
-        ${OT_PLATFORM_LIB}
-        openthread-ftd
-        ${OT_PLATFORM_LIB}
-        mbedcrypto
-        openthread-ncp-ftd
-    )
+if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
+    set(CPACK_GENERATOR "DEB")
+    set(CPACK_DEBIAN_PACKAGE_MAINTAINER "OpenThread Authors <openthread-users@googlegroups.com")
+    set(CPACK_PACKAGE_CONTACT "OpenThread Authors <openthread-users@googlegroups.com")
+    include(CPack)
 endif()
diff --git a/src/posix/Makefile-posix b/src/posix/Makefile-posix
index 2c9a4d7..5259e0a 100644
--- a/src/posix/Makefile-posix
+++ b/src/posix/Makefile-posix
@@ -38,6 +38,7 @@
 BORDER_AGENT                         ?= 1
 BORDER_ROUTER                        ?= 1
 COAP                                 ?= 1
+COAP_OBSERVE                         ?= 1
 COAPS                                ?= 1
 COMMISSIONER                         ?= 1
 CHANNEL_MANAGER                      ?= 1
@@ -57,12 +58,15 @@
 LINK_RAW                             ?= 0
 LOG_OUTPUT                           ?= PLATFORM_DEFINED
 MAC_FILTER                           ?= 1
+MAX_POWER_TABLE                      ?= 1
 MTD_NETDIAG                          ?= 1
 READLINE                             ?= readline
 REFERENCE_DEVICE                     ?= 1
 SERVICE                              ?= 1
 SNTP_CLIENT                          ?= 1
+ifneq ($(DAEMON),1)
 UDP_FORWARD                          ?= 1
+endif
 
 COMMONCFLAGS                         := \
     -g                                  \
@@ -75,13 +79,13 @@
     --enable-cli                      \
     --enable-ftd                      \
     --enable-ncp                      \
-    --enable-posix-app                \
+    --with-platform=posix             \
     $(NULL)
 
 # Platform specific switches
 
 ifeq ($(DAEMON),1)
-configure_OPTIONS              += --enable-posix-app-daemon
+configure_OPTIONS              += --enable-posix-daemon
 endif
 
 ifneq ($(DEBUG),1)
@@ -94,6 +98,10 @@
 configure_OPTIONS              += --host=$(HOST)
 endif
 
+ifeq ($(MAX_POWER_TABLE),1)
+COMMONCFLAGS                   += -DOPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE=1
+endif
+
 ifeq ($(PLATFORM_NETIF),1)
 COMMONCFLAGS                   += -DOPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1
 endif
@@ -102,10 +110,10 @@
 configure_OPTIONS              += --with-readline=$(READLINE)
 endif
 
-ifeq ($(RCP_SPI),1)
-COMMONCFLAGS                   += -DOPENTHREAD_POSIX_RCP_SPI_ENABLE=1
+ifeq ($(RCP_BUS),spi)
+COMMONCFLAGS                   += -DOPENTHREAD_POSIX_CONFIG_RCP_BUS=OT_POSIX_RCP_BUS_SPI
 else
-COMMONCFLAGS                   += -DOPENTHREAD_POSIX_RCP_UART_ENABLE=1
+COMMONCFLAGS                   += -DOPENTHREAD_POSIX_CONFIG_RCP_BUS=OT_POSIX_RCP_BUS_UART
 endif
 
 ifeq ($(VIRTUAL_TIME),1)
diff --git a/src/posix/Makefile.am b/src/posix/Makefile.am
index 896893e..d9e17d4 100644
--- a/src/posix/Makefile.am
+++ b/src/posix/Makefile.am
@@ -40,16 +40,12 @@
     platform                                                             \
     $(NULL)
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                                                         = \
-    platform                                                             \
-    $(NULL)
-
 CPPFLAGS_COMMON                                                        = \
     -I$(top_srcdir)/include                                              \
+    -I$(top_srcdir)/src/                                                 \
     -I$(top_srcdir)/src/core                                             \
     -I$(top_srcdir)/src/posix/platform                                   \
+    -I$(top_srcdir)/src/posix/platform/include                           \
     -D_GNU_SOURCE                                                        \
     -DOPENTHREAD_FTD=1                                                   \
     -DOPENTHREAD_MTD=0                                                   \
@@ -63,6 +59,12 @@
     -lutil                                                               \
     $(NULL)
 
+if OPENTHREAD_TARGET_LINUX
+LDADD_COMMON                                                          += \
+    -lrt                                                                 \
+    $(NULL)
+endif
+
 if OPENTHREAD_ENABLE_BUILTIN_MBEDTLS
 LDADD_COMMON                                                          += \
     $(top_builddir)/third_party/mbedtls/libmbedcrypto.a                  \
@@ -75,7 +77,7 @@
 if OPENTHREAD_ENABLE_EXECUTABLE
 ot_ncp_CPPFLAGS                                                        = \
     $(CPPFLAGS_COMMON)                                                   \
-    -DOPENTHREAD_POSIX_APP_TYPE=1                                        \
+    -DOPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_NCP                    \
     $(NULL)
 
 ot_ncp_SOURCES                                                         = \
@@ -99,12 +101,12 @@
     $(LIBTOOLFLAGS_COMMON)                                               \
     $(NULL)
 
-if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
+if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
 bin_PROGRAMS                                                          += \
     ot-ctl                                                               \
     ot-daemon                                                            \
     $(NULL)
-else # OPENTHREAD_ENABLE_POSIX_APP_DAEMON
+else # OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
 if OPENTHREAD_ENABLE_CLI
 bin_PROGRAMS                                                          += \
     ot-cli                                                               \
@@ -115,10 +117,10 @@
     ot-ncp                                                               \
     $(NULL)
 endif
-endif # OPENTHREAD_ENABLE_POSIX_APP_DAEMON
+endif # OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
 
 ot_ctl_SOURCES                                                         = \
-    client.c                                                             \
+    client.cpp                                                           \
     $(NULL)
 
 ot_ctl_CPPFLAGS                                                        = \
@@ -127,7 +129,7 @@
 
 ot_daemon_CPPFLAGS                                                     = \
     $(CPPFLAGS_COMMON)                                                   \
-    -DOPENTHREAD_POSIX_APP_TYPE=2                                        \
+    -DOPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_CLI                    \
     $(NULL)
 
 ot_daemon_SOURCES                                                      = \
@@ -155,12 +157,12 @@
 
 ot_cli_CPPFLAGS                                                        = \
     $(CPPFLAGS_COMMON)                                                   \
-    -DOPENTHREAD_POSIX_APP_TYPE=2                                        \
+    -DOPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_CLI                    \
     $(NULL)
 
 ot_cli_SOURCES                                                         = \
     main.c                                                               \
-    console_cli.c                                                        \
+    console_cli.cpp                                                      \
     $(NULL)
 
 ot_cli_LDADD                                                           = \
diff --git a/src/posix/README.md b/src/posix/README.md
index 7f9913b..d5c6828 100644
--- a/src/posix/README.md
+++ b/src/posix/README.md
@@ -1,5 +1,4 @@
-OpenThread POSIX app
-====================
+# OpenThread POSIX app
 
 OpenThread supports running its core on POSIX and transmits radio frames through a radio transceiver.
 
@@ -17,8 +16,7 @@
          POSIX                                          Chip
 ```
 
-Build
------
+## Build
 
 ```sh
 # build core for POSIX
@@ -27,24 +25,22 @@
 make -f examples/Makefile-xxxx
 ```
 
-Test
-----
+## Test
 
-**NOTE** Assuming the build system is 64bit Linux, you can use the normal OpenThread CLI as described in the [command line document](../../src/cli/README.md).
-You can also perform radio diagnostics using the command [diag](../../src/core/diags/README.md).
+**NOTE** Assuming the build system is 64bit Linux, you can use the normal OpenThread CLI as described in the [command line document](../../src/cli/README.md). You can also perform radio diagnostics using the command [diag](../../src/core/diags/README.md).
 
 ### With Simulation
 
 ```sh
-make -f examples/Makefile-posix
-./output/posix/x86_64-unknown-linux-gnu/bin/ot-cli ./output/x86_64-unknown-linux-gnu/bin/ot-rcp 1
+make -f examples/Makefile-simulation
+./output/posix/x86_64-unknown-linux-gnu/bin/ot-cli 'spinel+hdlc+forkpty://output/x86_64-unknown-linux-gnu/bin/ot-rcp?forkpty-arg=1'
 ```
 
 ### With Real Device
 
 #### nRF52840
 
-* USB=0
+- USB=0
 
 ```sh
 make -f examples/Makefile-nrf52840
@@ -62,10 +58,10 @@
 exit
 EOF
 
-./output/posix/x86_64-unknown-linux-gnu/bin/ot-cli /dev/ttyACM0 115200
+./output/posix/x86_64-unknown-linux-gnu/bin/ot-cli 'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200'
 ```
 
-* USB=1
+- USB=1
 
 ```sh
 # without USB=1 may result in failure for serial port issue
@@ -73,7 +69,7 @@
 arm-none-eabi-objcopy -O ihex output/nrf52840/bin/ot-rcp ot-rcp.hex
 nrfjprog -f nrf52 --chiperase --reset --program ot-rcp.hex
 # plug the CDC serial USB port
-./output/posix/x86_64-unknown-linux-gnu/bin/ot-cli /dev/ttyACM0 115200
+./output/posix/x86_64-unknown-linux-gnu/bin/ot-cli 'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200'
 ```
 
 #### CC2538
@@ -83,42 +79,39 @@
 arm-none-eabi-objcopy -O binary output/cc2538/bin/ot-rcp ot-rcp.bin
 # see https://github.com/JelmerT/cc2538-bsl
 python cc2538-bsl/cc2538-bsl.py -b 460800 -e -w -v -p /dev/ttyUSB0 ot-rcp.bin
-./output/posix/x86_64-unknown-linux-gnu/bin/ot-cli /dev/ttyUSB0 115200
+./output/posix/x86_64-unknown-linux-gnu/bin/ot-cli 'spinel+hdlc+uart:///dev/ttyUSB0?uart-baudrate=115200'
 ```
 
-Wpantund Support
-----------------
+## Wpantund Support
 
-**NOTE** Assuming the build system is 64bit Linux and *wpantund* is already installed and **stopped**.
+**NOTE** Assuming the build system is 64bit Linux and _wpantund_ is already installed and **stopped**.
 
 ### With Simulation
 
 ```sh
-sudo wpantund -s 'system:./output/posix/x86_64-unknown-linux-gnu/bin/ot-ncp ./output/x86_64-unknown-linux-gnu/bin/ot-rcp 1'
+sudo wpantund -s 'system:./output/posix/x86_64-unknown-linux-gnu/bin/ot-ncp spinel+hdlc+forkpty://output/x86_64-unknown-linux-gnu/bin/ot-rcp?forkpty-arg=1'
 ```
 
 ### With Real Device
 
 ```sh
 # nRF52840
-sudo wpantund -s 'system:./output/posix/x86_64-unknown-linux-gnu/bin/ot-ncp /dev/ttyACM0 115200'
+sudo wpantund -s 'system:./output/posix/x86_64-unknown-linux-gnu/bin/ot-ncp spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200'
 # CC2538
-sudo wpantund -s 'system:./output/posix/x86_64-unknown-linux-gnu/bin/ot-ncp /dev/ttyUSB0 115200'
+sudo wpantund -s 'system:./output/posix/x86_64-unknown-linux-gnu/bin/ot-ncp spinel+hdlc+uart:///dev/ttyUSB0?uart-baudrate=115200'
 ```
 
-Daemon Mode Support
--------------------
+## Daemon Mode Support
 
-OpenThread Posix Daemon mode uses a unix socket as input and output, so that OpenThread core can run as a service. And a client
-can communicate with it by connecting to the socket. The protocol is OpenThread CLI.
+OpenThread Posix Daemon mode uses a unix socket as input and output, so that OpenThread core can run as a service. And a client can communicate with it by connecting to the socket. The protocol is OpenThread CLI.
 
 ```
 # build daemon mode core stack for POSIX
 make -f src/posix/Makefile-posix DAEMON=1
 # Daemon with simulation
-./output/posix/x86_64-unknown-linux-gnu/bin/ot-daemon ./output/x86_64-unknown-linux-gnu/bin/ot-rcp 1
+./output/posix/x86_64-unknown-linux-gnu/bin/ot-daemon 'spinel+hdlc+forkpty://output/x86_64-unknown-linux-gnu/bin/ot-rcp?forkpty-arg=1'
 # Daemon with real device
-./output/posix/x86_64-unknown-linux-gnu/bin/ot-daemon /dev/ttyACM0 115200
+./output/posix/x86_64-unknown-linux-gnu/bin/ot-daemon 'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200'
 # Built-in controller
 ./output/posix/x86_64-unknown-linux-gnu/bin/ot-ctl
 ```
diff --git a/src/posix/cli.cmake b/src/posix/cli.cmake
new file mode 100644
index 0000000..86d6599
--- /dev/null
+++ b/src/posix/cli.cmake
@@ -0,0 +1,67 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_executable(ot-cli
+    main.c
+    $<$<BOOL:${READLINE}>:console_cli.cpp>
+)
+
+set_target_properties(
+    ot-cli
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_include_directories(ot-cli PRIVATE ${COMMON_INCLUDES})
+
+target_compile_definitions(ot-cli PRIVATE
+    $<$<BOOL:${READLINE}>:HAVE_LIB$<UPPER_CASE:${OT_READLINE}>=1>
+    OPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_CLI
+    ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(ot-cli PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_link_libraries(ot-cli
+    openthread-cli-ftd
+    ${OT_PLATFORM_LIB}
+    openthread-ftd
+    ${OT_PLATFORM_LIB}
+    openthread-cli-ftd
+    openthread-hdlc
+    openthread-spinel-rcp
+    mbedcrypto
+    ${READLINE_LINK_LIBRARIES}
+)
+
+
+install(TARGETS ot-cli DESTINATION bin)
+
diff --git a/src/posix/client.c b/src/posix/client.c
deleted file mode 100644
index a8a37f9..0000000
--- a/src/posix/client.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "openthread-core-config.h"
-
-#include <openthread/platform/toolchain.h>
-
-#ifndef HAVE_LIBEDIT
-#define HAVE_LIBEDIT 0
-#endif
-
-#ifndef HAVE_LIBREADLINE
-#define HAVE_LIBREADLINE 0
-#endif
-
-#define OPENTHREAD_USE_READLINE (HAVE_LIBEDIT || HAVE_LIBREADLINE)
-
-#if HAVE_LIBEDIT
-#include <editline/readline.h>
-#elif HAVE_LIBREADLINE
-#include <readline/history.h>
-#include <readline/readline.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include "code_utils.h"
-#include "common/code_utils.hpp"
-
-#include "platform-posix.h"
-
-static int sSessionFd = -1;
-
-#if OPENTHREAD_USE_READLINE
-static void InputCallback(char *aLine)
-{
-    if (aLine != NULL)
-    {
-        add_history(aLine);
-        dprintf(sSessionFd, "%s\n", aLine);
-        free(aLine);
-    }
-    else
-    {
-        exit(OT_EXIT_SUCCESS);
-    }
-}
-#endif // OPENTHREAD_USE_READLINE
-
-static bool FindDone(int *aDoneState, char aNowCharacter)
-{
-    switch (aNowCharacter)
-    {
-    case 'D':
-        *aDoneState = *aDoneState == 0 ? 1 : -1;
-        break;
-    case 'o':
-        *aDoneState = *aDoneState == 1 ? 2 : -1;
-        break;
-    case 'n':
-        *aDoneState = *aDoneState == 2 ? 3 : -1;
-        break;
-    case 'e':
-        *aDoneState = *aDoneState == 3 ? 4 : -1;
-        break;
-    case '\r':
-    case '\n':
-        if (*aDoneState == 4)
-        {
-            *aDoneState = 5;
-        }
-        else
-        {
-            *aDoneState = 0;
-        }
-        break;
-    default:
-        *aDoneState = -1;
-        break;
-    }
-
-    return *aDoneState == 5;
-}
-
-static bool FindError(int *aErrorState, char aNowCharacter)
-{
-    switch (aNowCharacter)
-    {
-    case 'E':
-        *aErrorState = *aErrorState == 0 ? 1 : -1;
-        break;
-    case 'r':
-        if (*aErrorState == 1 || *aErrorState == 2 || *aErrorState == 4)
-        {
-            (*aErrorState)++;
-        }
-        else
-        {
-            *aErrorState = -1;
-        }
-        break;
-    case 'o':
-        *aErrorState = *aErrorState == 3 ? 4 : -1;
-        break;
-    case ' ':
-        *aErrorState = *aErrorState == 5 ? 6 : -1;
-        break;
-    case '\r':
-    case '\n':
-        *aErrorState = 0;
-        break;
-    default:
-        *aErrorState = -1;
-        break;
-    }
-
-    return *aErrorState == 6;
-}
-
-static void SendBlockingCommand(int aArgc, char *aArgv[])
-{
-    char buffer[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
-    int  doneState  = 0;
-    int  errorState = 0;
-
-    for (int i = 0; i < aArgc; i++)
-    {
-        otEXPECT_ACTION(write(sSessionFd, aArgv[i], strlen(aArgv[i])) >= 0, perror("Failed to send command"));
-        otEXPECT_ACTION(write(sSessionFd, " ", 1) >= 0, perror("Failed to send command"));
-    }
-    otEXPECT_ACTION(write(sSessionFd, "\n", 1) >= 0, perror("Failed to send command"));
-
-    while (true)
-    {
-        ssize_t rval = read(sSessionFd, buffer, sizeof(buffer));
-
-        otEXPECT(rval >= 0);
-        write(STDOUT_FILENO, buffer, rval);
-        for (ssize_t i = 0; i < rval; i++)
-        {
-            if (FindDone(&doneState, buffer[i]) || FindError(&errorState, buffer[i]))
-            {
-                otEXIT_NOW();
-            }
-        }
-    }
-exit:
-    return;
-}
-
-int main(int argc, char *argv[])
-{
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
-
-    int ret;
-
-    sSessionFd = socket(AF_UNIX, SOCK_STREAM, 0);
-    otEXPECT_ACTION(sSessionFd != -1, perror("socket"); ret = OT_EXIT_FAILURE);
-
-    {
-        struct sockaddr_un sockname;
-
-        memset(&sockname, 0, sizeof(struct sockaddr_un));
-        sockname.sun_family = AF_UNIX;
-        strncpy(sockname.sun_path, OPENTHREAD_POSIX_APP_SOCKET_NAME, sizeof(sockname.sun_path) - 1);
-
-        ret = connect(sSessionFd, (const struct sockaddr *)&sockname, sizeof(struct sockaddr_un));
-
-        if (ret == -1)
-        {
-            fprintf(stderr, "OpenThread daemon is not running.\n");
-            otEXIT_NOW(ret = OT_EXIT_FAILURE);
-        }
-
-#if OPENTHREAD_USE_READLINE
-        rl_instream           = stdin;
-        rl_outstream          = stdout;
-        rl_inhibit_completion = true;
-        rl_callback_handler_install("> ", InputCallback);
-        rl_already_prompted = 1;
-#endif
-    }
-
-    if (argc > 1)
-    {
-        SendBlockingCommand(argc - 1, &argv[1]);
-        otEXIT_NOW(ret = 0);
-    }
-
-    while (1)
-    {
-        fd_set  readFdSet;
-        char    buffer[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
-        ssize_t rval;
-        int     maxFd = sSessionFd > STDIN_FILENO ? sSessionFd : STDIN_FILENO;
-
-        FD_ZERO(&readFdSet);
-
-        FD_SET(STDIN_FILENO, &readFdSet);
-        FD_SET(sSessionFd, &readFdSet);
-
-        ret = select(maxFd + 1, &readFdSet, NULL, NULL, NULL);
-
-        otEXPECT_ACTION(ret != -1, perror("select"); ret = OT_EXIT_FAILURE);
-
-        if (ret == 0)
-        {
-            otEXIT_NOW(ret = OT_EXIT_SUCCESS);
-        }
-
-        if (FD_ISSET(STDIN_FILENO, &readFdSet))
-        {
-#if OPENTHREAD_USE_READLINE
-            rl_callback_read_char();
-#else
-            otEXPECT_ACTION(fgets(buffer, sizeof(buffer), stdin) != NULL, ret = OT_EXIT_FAILURE);
-
-            rval = write(sSessionFd, buffer, strlen(buffer));
-            otEXPECT_ACTION(rval != -1, perror("write"); ret = OT_EXIT_FAILURE);
-#endif
-        }
-
-        if (FD_ISSET(sSessionFd, &readFdSet))
-        {
-            rval = read(sSessionFd, buffer, sizeof(buffer));
-            otEXPECT_ACTION(rval != -1, perror("read"); ret = OT_EXIT_FAILURE);
-
-            if (rval == 0)
-            {
-                // daemon closed sSessionFd
-                otEXIT_NOW(ret = OT_EXIT_FAILURE);
-            }
-            else
-            {
-                IgnoreReturnValue(write(STDOUT_FILENO, buffer, rval));
-            }
-        }
-    }
-
-exit:
-    if (sSessionFd != -1)
-    {
-#if OPENTHREAD_USE_READLINE
-        rl_callback_handler_remove();
-#endif
-        close(sSessionFd);
-    }
-
-    return ret;
-}
diff --git a/src/posix/client.cpp b/src/posix/client.cpp
new file mode 100644
index 0000000..8ac5da4
--- /dev/null
+++ b/src/posix/client.cpp
@@ -0,0 +1,354 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "platform/openthread-posix-config.h"
+
+#include <openthread/platform/toolchain.h>
+
+#ifndef HAVE_LIBEDIT
+#define HAVE_LIBEDIT 0
+#endif
+
+#ifndef HAVE_LIBREADLINE
+#define HAVE_LIBREADLINE 0
+#endif
+
+#define OPENTHREAD_USE_READLINE (HAVE_LIBEDIT || HAVE_LIBREADLINE)
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#if HAVE_LIBEDIT
+#include <editline/readline.h>
+#elif HAVE_LIBREADLINE
+#include <readline/history.h>
+#include <readline/readline.h>
+#endif
+
+#include "common/code_utils.hpp"
+
+#include "platform-posix.h"
+
+static int sSessionFd = -1;
+
+#if OPENTHREAD_USE_READLINE
+static void InputCallback(char *aLine)
+{
+    if (aLine != nullptr)
+    {
+        add_history(aLine);
+        dprintf(sSessionFd, "%s\n", aLine);
+        free(aLine);
+    }
+    else
+    {
+        exit(OT_EXIT_SUCCESS);
+    }
+}
+#endif // OPENTHREAD_USE_READLINE
+
+static bool FindPrompt(int &aState, char aChar)
+{
+    switch (aChar)
+    {
+    case '>':
+        aState = aState == 0 ? 1 : -1;
+        break;
+    case ' ':
+        aState = aState == 1 ? 2 : -1;
+        break;
+    case '\r':
+    case '\n':
+        aState = 0;
+        break;
+    default:
+        aState = -1;
+    }
+
+    return aState == 2;
+}
+
+static bool FindDone(int &aDoneState, char aNowCharacter)
+{
+    switch (aNowCharacter)
+    {
+    case 'D':
+        aDoneState = aDoneState == 0 ? 1 : -1;
+        break;
+    case 'o':
+        aDoneState = aDoneState == 1 ? 2 : -1;
+        break;
+    case 'n':
+        aDoneState = aDoneState == 2 ? 3 : -1;
+        break;
+    case 'e':
+        aDoneState = aDoneState == 3 ? 4 : -1;
+        break;
+    case '\r':
+    case '\n':
+        if (aDoneState == 4)
+        {
+            aDoneState = 5;
+        }
+        else
+        {
+            aDoneState = 0;
+        }
+        break;
+    default:
+        aDoneState = -1;
+        break;
+    }
+
+    return aDoneState == 5;
+}
+
+static bool FindError(int &aErrorState, char aNowCharacter)
+{
+    switch (aNowCharacter)
+    {
+    case 'E':
+        aErrorState = aErrorState == 0 ? 1 : -1;
+        break;
+    case 'r':
+        if (aErrorState == 1 || aErrorState == 2 || aErrorState == 4)
+        {
+            (aErrorState)++;
+        }
+        else
+        {
+            aErrorState = -1;
+        }
+        break;
+    case 'o':
+        aErrorState = aErrorState == 3 ? 4 : -1;
+        break;
+    case ' ':
+        aErrorState = aErrorState == 5 ? 6 : -1;
+        break;
+    case '\r':
+    case '\n':
+        aErrorState = 0;
+        break;
+    default:
+        aErrorState = -1;
+        break;
+    }
+
+    return aErrorState == 6;
+}
+
+static bool DoWrite(int aFile, const void *aBuffer, size_t aSize)
+{
+    bool ret = true;
+
+    while (aSize)
+    {
+        ssize_t rval = write(aFile, aBuffer, aSize);
+        if (rval <= 0)
+        {
+            VerifyOrExit((rval == -1) && (errno == EINTR), perror("write"); ret = false);
+        }
+        else
+        {
+            aBuffer = reinterpret_cast<const uint8_t *>(aBuffer) + rval;
+            aSize -= static_cast<size_t>(rval);
+        }
+    }
+
+exit:
+    return ret;
+}
+
+int main(int argc, char *argv[])
+{
+    int  ret;
+    bool isInteractive = true;
+    bool isFinished    = false;
+    int  doneState     = 0;
+    int  errorState    = 0;
+    int  promptState   = 0;
+
+    sSessionFd = socket(AF_UNIX, SOCK_STREAM, 0);
+    VerifyOrExit(sSessionFd != -1, perror("socket"); ret = OT_EXIT_FAILURE);
+
+    {
+        struct sockaddr_un sockname;
+
+        memset(&sockname, 0, sizeof(struct sockaddr_un));
+        sockname.sun_family = AF_UNIX;
+        strncpy(sockname.sun_path, OPENTHREAD_POSIX_DAEMON_SOCKET_NAME, sizeof(sockname.sun_path) - 1);
+
+        ret = connect(sSessionFd, reinterpret_cast<const struct sockaddr *>(&sockname), sizeof(struct sockaddr_un));
+
+        if (ret == -1)
+        {
+            fprintf(stderr, "OpenThread daemon is not running.\n");
+            ExitNow(ret = OT_EXIT_FAILURE);
+        }
+    }
+
+    if (argc > 1)
+    {
+        for (int i = 1; i < argc; i++)
+        {
+            VerifyOrExit(DoWrite(sSessionFd, argv[i], strlen(argv[i])), ret = OT_EXIT_FAILURE);
+            VerifyOrExit(DoWrite(sSessionFd, " ", 1), ret = OT_EXIT_FAILURE);
+        }
+        VerifyOrExit(DoWrite(sSessionFd, "\n", 1), ret = OT_EXIT_FAILURE);
+
+        isInteractive = false;
+    }
+#if OPENTHREAD_USE_READLINE
+    else
+    {
+        rl_instream           = stdin;
+        rl_outstream          = stdout;
+        rl_inhibit_completion = true;
+        rl_callback_handler_install("> ", InputCallback);
+        rl_already_prompted = 1;
+    }
+#endif
+
+    while (!isFinished)
+    {
+        fd_set readFdSet;
+        char   buffer[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
+        int    maxFd = sSessionFd;
+
+        FD_ZERO(&readFdSet);
+
+        FD_SET(sSessionFd, &readFdSet);
+
+        if (isInteractive)
+        {
+            FD_SET(STDIN_FILENO, &readFdSet);
+            if (STDIN_FILENO > maxFd)
+            {
+                maxFd = STDIN_FILENO;
+            }
+        }
+
+        ret = select(maxFd + 1, &readFdSet, nullptr, nullptr, nullptr);
+
+        VerifyOrExit(ret != -1, perror("select"); ret = OT_EXIT_FAILURE);
+
+        if (ret == 0)
+        {
+            ExitNow(ret = OT_EXIT_SUCCESS);
+        }
+
+        if (isInteractive && FD_ISSET(STDIN_FILENO, &readFdSet))
+        {
+#if OPENTHREAD_USE_READLINE
+            rl_callback_read_char();
+#else
+            VerifyOrExit(fgets(buffer, sizeof(buffer), stdin) != nullptr, ret = OT_EXIT_FAILURE);
+
+            VerifyOrExit(DoWrite(sSessionFd, buffer, strlen(buffer)), ret = OT_EXIT_FAILURE);
+#endif
+        }
+
+        if (FD_ISSET(sSessionFd, &readFdSet))
+        {
+            ssize_t rval = read(sSessionFd, buffer, sizeof(buffer));
+            VerifyOrExit(rval != -1, perror("read"); ret = OT_EXIT_FAILURE);
+
+            if (rval == 0)
+            {
+                // daemon closed sSessionFd
+                ExitNow(ret = isInteractive ? OT_EXIT_FAILURE : OT_EXIT_SUCCESS);
+            }
+
+            if (isInteractive)
+            {
+                VerifyOrExit(DoWrite(STDOUT_FILENO, buffer, static_cast<size_t>(rval)), ret = OT_EXIT_FAILURE);
+            }
+            else
+            {
+                ssize_t lineStart = 0;
+
+                for (ssize_t i = 0; i < rval; i++)
+                {
+                    int prevPromptState = promptState;
+
+                    if (FindPrompt(promptState, buffer[i]))
+                    {
+                        doneState  = 0;
+                        errorState = 0;
+                        lineStart  = i + 1;
+                        continue;
+                    }
+                    else if (prevPromptState == 1 && i == 0)
+                    {
+                        VerifyOrExit(DoWrite(STDOUT_FILENO, ">", 1), ret = OT_EXIT_FAILURE);
+                    }
+
+                    if (buffer[i] == '\r' || buffer[i] == '\n')
+                    {
+                        VerifyOrExit(DoWrite(STDOUT_FILENO, buffer + lineStart, static_cast<size_t>(i - lineStart + 1)),
+                                     ret = OT_EXIT_FAILURE);
+                        lineStart = i + 1;
+                    }
+
+                    if (FindDone(doneState, buffer[i]) || FindError(errorState, buffer[i]))
+                    {
+                        isFinished = true;
+                        ret        = OT_EXIT_SUCCESS;
+                    }
+                }
+
+                if (lineStart < rval && promptState != 1)
+                {
+                    assert(promptState != 0 && promptState != 2);
+                    VerifyOrExit(DoWrite(STDOUT_FILENO, buffer + lineStart, static_cast<size_t>(rval - lineStart)),
+                                 ret = OT_EXIT_FAILURE);
+                }
+            }
+        }
+    }
+
+exit:
+    if (sSessionFd != -1)
+    {
+#if OPENTHREAD_USE_READLINE
+        if (isInteractive)
+        {
+            rl_callback_handler_remove();
+        }
+#endif
+        close(sSessionFd);
+    }
+
+    return ret;
+}
diff --git a/src/posix/console_cli.c b/src/posix/console_cli.c
deleted file mode 100644
index 9f7d544..0000000
--- a/src/posix/console_cli.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "console_cli.h"
-
-#include "openthread/config.h"
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifndef HAVE_LIBEDIT
-#define HAVE_LIBEDIT 0
-#endif
-
-#ifndef HAVE_LIBREADLINE
-#define HAVE_LIBREADLINE 0
-#endif
-
-#if HAVE_LIBEDIT || HAVE_LIBREADLINE
-#if HAVE_LIBEDIT
-#include <editline/readline.h>
-#elif HAVE_LIBREADLINE
-#include <readline/history.h>
-#include <readline/readline.h>
-#else
-#error "Missing readline library"
-#endif
-
-#include <openthread/cli.h>
-
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-
-static const char sPrompt[] = "> ";
-
-static int sReadFd;
-
-static void InputCallback(char *aLine)
-{
-    if (aLine != NULL)
-    {
-        size_t len;
-
-        if ((len = strlen(aLine)) > 0)
-        {
-            add_history(aLine);
-            otCliConsoleInputLine(aLine, (uint16_t)len);
-        }
-        free(aLine);
-    }
-    else
-    {
-        exit(OT_EXIT_SUCCESS);
-    }
-}
-
-static int OutputCallback(const char *aBuffer, uint16_t aLength, void *aContext)
-{
-    (void)aContext;
-
-    return (int)write(STDOUT_FILENO, aBuffer, aLength);
-}
-
-void otxConsoleInit(otInstance *aInstance)
-{
-    rl_instream           = stdin;
-    rl_outstream          = stdout;
-    rl_inhibit_completion = true;
-    sReadFd               = fileno(rl_instream);
-    rl_callback_handler_install(sPrompt, InputCallback);
-    otCliConsoleInit(aInstance, OutputCallback, NULL);
-}
-
-void otxConsoleDeinit(void)
-{
-    rl_callback_handler_remove();
-}
-
-void otxConsoleUpdate(otSysMainloopContext *aMainloop)
-{
-    FD_SET(sReadFd, &aMainloop->mReadFdSet);
-    FD_SET(sReadFd, &aMainloop->mErrorFdSet);
-
-    if (aMainloop->mMaxFd < sReadFd)
-    {
-        aMainloop->mMaxFd = sReadFd;
-    }
-}
-
-void otxConsoleProcess(const otSysMainloopContext *aMainloop)
-{
-    if (FD_ISSET(sReadFd, &aMainloop->mErrorFdSet))
-    {
-        perror("console error");
-        exit(OT_EXIT_FAILURE);
-    }
-
-    if (FD_ISSET(sReadFd, &aMainloop->mReadFdSet))
-    {
-        rl_callback_read_char();
-    }
-}
-
-#endif // HAVE_LIBEDIT || HAVE_LIBREADLINE
diff --git a/src/posix/console_cli.cpp b/src/posix/console_cli.cpp
new file mode 100644
index 0000000..91a620f
--- /dev/null
+++ b/src/posix/console_cli.cpp
@@ -0,0 +1,131 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "console_cli.h"
+
+#include "openthread/config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifndef HAVE_LIBEDIT
+#define HAVE_LIBEDIT 0
+#endif
+
+#ifndef HAVE_LIBREADLINE
+#define HAVE_LIBREADLINE 0
+#endif
+
+#if HAVE_LIBEDIT || HAVE_LIBREADLINE
+#if HAVE_LIBEDIT
+#include <editline/readline.h>
+#elif HAVE_LIBREADLINE
+#include <readline/history.h>
+#include <readline/readline.h>
+#else
+#error "Missing readline library"
+#endif
+
+#include <openthread/cli.h>
+
+#include "openthread-core-config.h"
+#include "platform-posix.h"
+
+static const char sPrompt[] = "> ";
+
+static int sReadFd;
+
+static void InputCallback(char *aLine)
+{
+    if (aLine != nullptr)
+    {
+        size_t len;
+
+        if ((len = strlen(aLine)) > 0)
+        {
+            add_history(aLine);
+            otCliConsoleInputLine(aLine, (uint16_t)len);
+        }
+        free(aLine);
+    }
+    else
+    {
+        exit(OT_EXIT_SUCCESS);
+    }
+}
+
+static int OutputCallback(const char *aBuffer, uint16_t aLength, void *aContext)
+{
+    (void)aContext;
+
+    return (int)write(STDOUT_FILENO, aBuffer, aLength);
+}
+
+void otxConsoleInit(otInstance *aInstance)
+{
+    rl_instream           = stdin;
+    rl_outstream          = stdout;
+    rl_inhibit_completion = true;
+    sReadFd               = fileno(rl_instream);
+    rl_callback_handler_install(sPrompt, InputCallback);
+    otCliConsoleInit(aInstance, OutputCallback, nullptr);
+}
+
+void otxConsoleDeinit(void)
+{
+    rl_callback_handler_remove();
+}
+
+void otxConsoleUpdate(otSysMainloopContext *aMainloop)
+{
+    FD_SET(sReadFd, &aMainloop->mReadFdSet);
+    FD_SET(sReadFd, &aMainloop->mErrorFdSet);
+
+    if (aMainloop->mMaxFd < sReadFd)
+    {
+        aMainloop->mMaxFd = sReadFd;
+    }
+}
+
+void otxConsoleProcess(const otSysMainloopContext *aMainloop)
+{
+    if (FD_ISSET(sReadFd, &aMainloop->mErrorFdSet))
+    {
+        perror("console error");
+        exit(OT_EXIT_FAILURE);
+    }
+
+    if (FD_ISSET(sReadFd, &aMainloop->mReadFdSet))
+    {
+        rl_callback_read_char();
+    }
+}
+
+#endif // HAVE_LIBEDIT || HAVE_LIBREADLINE
diff --git a/src/posix/console_cli.h b/src/posix/console_cli.h
index 41b0f98..2728e18 100644
--- a/src/posix/console_cli.h
+++ b/src/posix/console_cli.h
@@ -29,9 +29,15 @@
 #ifndef OPENTHREAD_CONSOLE_CLI_H_
 #define OPENTHREAD_CONSOLE_CLI_H_
 
+#include "platform/openthread-posix-config.h"
+
 #include <stdint.h>
 
-#include "openthread-system.h"
+#include <openthread/openthread-system.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /**
  * This function initializes CLI console.
@@ -63,4 +69,8 @@
  */
 void otxConsoleProcess(const otSysMainloopContext *aMainloop);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif // OPENTHREAD_CONSOLE_CLI_H_
diff --git a/src/posix/daemon.cmake b/src/posix/daemon.cmake
new file mode 100644
index 0000000..3efe922
--- /dev/null
+++ b/src/posix/daemon.cmake
@@ -0,0 +1,90 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_executable(ot-daemon
+    main.c
+)
+
+set_target_properties(
+    ot-daemon
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_include_directories(ot-daemon PRIVATE ${COMMON_INCLUDES})
+
+target_compile_definitions(ot-daemon PRIVATE
+    OPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_CLI
+    ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(ot-daemon PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_link_libraries(ot-daemon PRIVATE
+    openthread-cli-ftd
+    ${OT_PLATFORM_LIB}
+    openthread-ftd
+    ${OT_PLATFORM_LIB}
+    openthread-ncp-ftd
+    mbedcrypto
+)
+
+add_executable(ot-ctl
+    client.cpp
+)
+
+set_target_properties(
+    ot-ctl
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_compile_definitions(ot-ctl PRIVATE
+    $<$<BOOL:${READLINE}>:HAVE_LIB$<UPPER_CASE:${OT_READLINE}>=1>
+    ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(ot-ctl PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_link_libraries(ot-ctl PRIVATE
+    ${READLINE_LINK_LIBRARIES}
+    ot-config
+)
+
+target_include_directories(ot-ctl PRIVATE ${COMMON_INCLUDES})
+
+install(TARGETS ot-daemon
+    DESTINATION sbin)
+install(TARGETS ot-ctl
+    DESTINATION bin)
diff --git a/src/posix/main.c b/src/posix/main.c
index 144de83..d77d114 100644
--- a/src/posix/main.c
+++ b/src/posix/main.c
@@ -26,6 +26,8 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "platform/openthread-posix-config.h"
+
 #include <openthread/config.h>
 
 #include <assert.h>
@@ -35,6 +37,7 @@
 #include <setjmp.h>
 #include <signal.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
 #include <unistd.h>
@@ -50,19 +53,20 @@
 #define HAVE_LIBREADLINE 0
 #endif
 
-#define OPENTHREAD_POSIX_APP_TYPE_NCP 1
-#define OPENTHREAD_POSIX_APP_TYPE_CLI 2
+#define OT_POSIX_APP_TYPE_NCP 1
+#define OT_POSIX_APP_TYPE_CLI 2
 
 #include <openthread/diag.h>
 #include <openthread/logging.h>
 #include <openthread/tasklet.h>
+#include <openthread/thread.h>
 #include <openthread/platform/radio.h>
-#if OPENTHREAD_POSIX_APP_TYPE == OPENTHREAD_POSIX_APP_TYPE_NCP
+#if OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_NCP
 #include <openthread/ncp.h>
 #define OPENTHREAD_USE_CONSOLE 0
-#elif OPENTHREAD_POSIX_APP_TYPE == OPENTHREAD_POSIX_APP_TYPE_CLI
+#elif OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_CLI
 #include <openthread/cli.h>
-#if (HAVE_LIBEDIT || HAVE_LIBREADLINE) && !OPENTHREAD_ENABLE_POSIX_APP_DAEMON
+#if (HAVE_LIBEDIT || HAVE_LIBREADLINE) && !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
 #define OPENTHREAD_USE_CONSOLE 1
 #include "console_cli.h"
 #else
@@ -71,7 +75,10 @@
 #else
 #error "Unknown posix app type!"
 #endif
-#include <openthread-system.h>
+#include <common/code_utils.hpp>
+#include <common/logging.hpp>
+#include <lib/platform/exit_code.h>
+#include <openthread/openthread-system.h>
 
 #ifndef OPENTHREAD_ENABLE_COVERAGE
 #define OPENTHREAD_ENABLE_COVERAGE 0
@@ -96,99 +103,62 @@
  */
 enum
 {
-    ARG_PRINT_RADIO_VERSION = 1001,
-    ARG_NO_RADIO_RESET      = 1002,
-    ARG_RESTORE_NCP_DATASET = 1003,
-    ARG_SPI_GPIO_INT_DEV    = 1011,
-    ARG_SPI_GPIO_INT_LINE   = 1012,
-    ARG_SPI_GPIO_RESET_DEV  = 1013,
-    ARG_SPI_GPIO_RESET_LINE = 1014,
-    ARG_SPI_MODE            = 1015,
-    ARG_SPI_SPEED           = 1016,
-    ARG_SPI_CS_DELAY        = 1017,
-    ARG_SPI_RESET_DELAY     = 1018,
-    ARG_SPI_ALIGN_ALLOWANCE = 1019,
-    ARG_SPI_SMALL_PACKET    = 1020,
+    OT_POSIX_OPT_DEBUG_LEVEL    = 'd',
+    OT_POSIX_OPT_DRY_RUN        = 'n',
+    OT_POSIX_OPT_HELP           = 'h',
+    OT_POSIX_OPT_INTERFACE_NAME = 'I',
+    OT_POSIX_OPT_TIME_SPEED     = 's',
+    OT_POSIX_OPT_VERBOSE        = 'v',
+
+    OT_POSIX_OPT_SHORT_MAX = 128,
+
+    OT_POSIX_OPT_RADIO_VERSION,
+    OT_POSIX_OPT_REAL_TIME_SIGNAL,
 };
 
-static const struct option kOptions[] = {{"debug-level", required_argument, NULL, 'd'},
-                                         {"dry-run", no_argument, NULL, 'n'},
-                                         {"help", no_argument, NULL, 'h'},
-                                         {"interface-name", required_argument, NULL, 'I'},
-                                         {"no-reset", no_argument, NULL, ARG_NO_RADIO_RESET},
-                                         {"radio-version", no_argument, NULL, ARG_PRINT_RADIO_VERSION},
-                                         {"ncp-dataset", no_argument, NULL, ARG_RESTORE_NCP_DATASET},
-                                         {"time-speed", required_argument, NULL, 's'},
-                                         {"verbose", no_argument, NULL, 'v'},
-#if OPENTHREAD_POSIX_RCP_SPI_ENABLE
-                                         {"gpio-int-dev", required_argument, NULL, ARG_SPI_GPIO_INT_DEV},
-                                         {"gpio-int-line", required_argument, NULL, ARG_SPI_GPIO_INT_LINE},
-                                         {"gpio-reset-dev", required_argument, NULL, ARG_SPI_GPIO_RESET_DEV},
-                                         {"gpio-reset-line", required_argument, NULL, ARG_SPI_GPIO_RESET_LINE},
-                                         {"spi-mode", required_argument, NULL, ARG_SPI_MODE},
-                                         {"spi-speed", required_argument, NULL, ARG_SPI_SPEED},
-                                         {"spi-cs-delay", required_argument, NULL, ARG_SPI_CS_DELAY},
-                                         {"spi-reset-delay", required_argument, NULL, ARG_SPI_RESET_DELAY},
-                                         {"spi-align-allowance", required_argument, NULL, ARG_SPI_ALIGN_ALLOWANCE},
-                                         {"spi-small-packet", required_argument, NULL, ARG_SPI_SMALL_PACKET},
-#endif
+static const struct option kOptions[] = {{"debug-level", required_argument, NULL, OT_POSIX_OPT_DEBUG_LEVEL},
+                                         {"dry-run", no_argument, NULL, OT_POSIX_OPT_DRY_RUN},
+                                         {"help", no_argument, NULL, OT_POSIX_OPT_HELP},
+                                         {"interface-name", required_argument, NULL, OT_POSIX_OPT_INTERFACE_NAME},
+                                         {"radio-version", no_argument, NULL, OT_POSIX_OPT_RADIO_VERSION},
+                                         {"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL},
+                                         {"time-speed", required_argument, NULL, OT_POSIX_OPT_TIME_SPEED},
+                                         {"verbose", no_argument, NULL, OT_POSIX_OPT_VERBOSE},
                                          {0, 0, 0, 0}};
 
 static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
 {
     fprintf(aStream,
             "Syntax:\n"
-            "    %s [Options] NodeId|Device|Command [DeviceConfig|CommandArgs]\n"
+            "    %s [Options] RadioURL\n"
             "Options:\n"
-            "    -I  --interface-name name     Thread network interface name.\n"
             "    -d  --debug-level             Debug level of logging.\n"
+            "    -h  --help                    Display this usage information.\n"
+            "    -I  --interface-name name     Thread network interface name.\n"
             "    -n  --dry-run                 Just verify if arguments is valid and radio spinel is compatible.\n"
-            "        --no-reset                Do not send Spinel reset command to RCP on initialization.\n"
             "        --radio-version           Print radio firmware version.\n"
-            "        --ncp-dataset             Retrieve and save NCP dataset to file.\n"
             "    -s  --time-speed factor       Time speed up factor.\n"
-            "    -v  --verbose                 Also log to stderr.\n"
-#if OPENTHREAD_POSIX_RCP_SPI_ENABLE
-            "        --gpio-int-dev[=gpio-device-path]\n"
-            "                                  Specify a path to the Linux sysfs-exported GPIO device for the\n"
-            "                                  `I̅N̅T̅` pin. If not specified, `SPI` interface will fall back to\n"
-            "                                  polling, which is inefficient.\n"
-            "        --gpio-int-line[=line-offset]\n"
-            "                                  The offset index of `I̅N̅T̅` pin for the associated GPIO device.\n"
-            "                                  If not specified, `SPI` interface will fall back to polling,\n"
-            "                                  which is inefficient.\n"
-            "        --gpio-reset-dev[=gpio-device-path]\n"
-            "                                  Specify a path to the Linux sysfs-exported GPIO device for the\n"
-            "                                  `R̅E̅S̅` pin.\n"
-            "        --gpio-reset-line[=line-offset]"
-            "                                  The offset index of `R̅E̅S̅` pin for the associated GPIO device.\n"
-            "        --spi-mode[=mode]         Specify the SPI mode to use (0-3).\n"
-            "        --spi-speed[=hertz]       Specify the SPI speed in hertz.\n"
-            "        --spi-cs-delay[=usec]     Specify the delay after C̅S̅ assertion, in µsec.\n"
-            "        --spi-reset-delay[=ms]    Specify the delay after R̅E̅S̅E̅T̅ assertion, in milliseconds.\n"
-            "        --spi-align-allowance[=n] Specify the maximum number of 0xFF bytes to clip from start of\n"
-            "                                  MISO frame. Max value is 16.\n"
-            "        --spi-small-packet=[n]    Specify the smallest packet we can receive in a single transaction.\n"
-            "                                  (larger packets will require two transactions). Default value is 32.\n"
-#endif
-            "    -h  --help                    Display this usage information.\n",
+            "    -v  --verbose                 Also log to stderr.\n",
             aProgramName);
+#ifdef __linux__
+    fprintf(aStream,
+            "        --real-time-signal        (Linux only) The real-time signal number for microsecond timer.\n"
+            "                                  Use +N for relative value to SIGRTMIN, and use N for absolute value.\n");
+
+#endif
+    fprintf(aStream, "%s", otSysGetRadioUrlHelpString());
     exit(aExitCode);
 }
 
 static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
 {
-    memset(aConfig, 0, sizeof(PosixConfig));
+    memset(aConfig, 0, sizeof(*aConfig));
 
-    aConfig->mPlatformConfig.mSpeedUpFactor      = 1;
-    aConfig->mPlatformConfig.mResetRadio         = true;
-    aConfig->mPlatformConfig.mSpiSpeed           = OT_PLATFORM_CONFIG_SPI_DEFAULT_SPEED_HZ;
-    aConfig->mPlatformConfig.mSpiCsDelay         = OT_PLATFORM_CONFIG_SPI_DEFAULT_CS_DELAY_US;
-    aConfig->mPlatformConfig.mSpiResetDelay      = OT_PLATFORM_CONFIG_SPI_DEFAULT_RESET_DELAY_MS;
-    aConfig->mPlatformConfig.mSpiAlignAllowance  = OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE;
-    aConfig->mPlatformConfig.mSpiSmallPacketSize = OT_PLATFORM_CONFIG_SPI_DEFAULT_SMALL_PACKET_SIZE;
-    aConfig->mPlatformConfig.mSpiMode            = OT_PLATFORM_CONFIG_SPI_DEFAULT_MODE;
-    aConfig->mLogLevel                           = OT_LOG_LEVEL_CRIT;
+    aConfig->mPlatformConfig.mSpeedUpFactor = 1;
+    aConfig->mLogLevel                      = OT_LOG_LEVEL_CRIT;
+#ifdef __linux__
+    aConfig->mPlatformConfig.mRealTimeSignal = SIGRTMIN;
+#endif
 
     optind = 1;
 
@@ -204,19 +174,19 @@
 
         switch (option)
         {
-        case 'd':
+        case OT_POSIX_OPT_DEBUG_LEVEL:
             aConfig->mLogLevel = (otLogLevel)atoi(optarg);
             break;
-        case 'h':
+        case OT_POSIX_OPT_HELP:
             PrintUsage(aArgVector[0], stdout, OT_EXIT_SUCCESS);
             break;
-        case 'I':
+        case OT_POSIX_OPT_INTERFACE_NAME:
             aConfig->mPlatformConfig.mInterfaceName = optarg;
             break;
-        case 'n':
+        case OT_POSIX_OPT_DRY_RUN:
             aConfig->mIsDryRun = true;
             break;
-        case 's':
+        case OT_POSIX_OPT_TIME_SPEED:
         {
             char *endptr = NULL;
 
@@ -229,50 +199,24 @@
             }
             break;
         }
-        case 'v':
+        case OT_POSIX_OPT_VERBOSE:
             aConfig->mIsVerbose = true;
             break;
-        case ARG_PRINT_RADIO_VERSION:
+        case OT_POSIX_OPT_RADIO_VERSION:
             aConfig->mPrintRadioVersion = true;
             break;
-        case ARG_NO_RADIO_RESET:
-            aConfig->mPlatformConfig.mResetRadio = false;
+#ifdef __linux__
+        case OT_POSIX_OPT_REAL_TIME_SIGNAL:
+            if (optarg[0] == '+')
+            {
+                aConfig->mPlatformConfig.mRealTimeSignal = SIGRTMIN + atoi(&optarg[1]);
+            }
+            else
+            {
+                aConfig->mPlatformConfig.mRealTimeSignal = atoi(optarg);
+            }
             break;
-        case ARG_RESTORE_NCP_DATASET:
-            aConfig->mPlatformConfig.mRestoreDatasetFromNcp = true;
-            break;
-#if OPENTHREAD_POSIX_RCP_SPI_ENABLE
-        case ARG_SPI_GPIO_INT_DEV:
-            aConfig->mPlatformConfig.mSpiGpioIntDevice = optarg;
-            break;
-        case ARG_SPI_GPIO_INT_LINE:
-            aConfig->mPlatformConfig.mSpiGpioIntLine = (uint8_t)atoi(optarg);
-            break;
-        case ARG_SPI_GPIO_RESET_DEV:
-            aConfig->mPlatformConfig.mSpiGpioResetDevice = optarg;
-            break;
-        case ARG_SPI_GPIO_RESET_LINE:
-            aConfig->mPlatformConfig.mSpiGpioResetLine = (uint8_t)atoi(optarg);
-            break;
-        case ARG_SPI_MODE:
-            aConfig->mPlatformConfig.mSpiMode = (uint8_t)atoi(optarg);
-            break;
-        case ARG_SPI_SPEED:
-            aConfig->mPlatformConfig.mSpiSpeed = atoi(optarg);
-            break;
-        case ARG_SPI_CS_DELAY:
-            aConfig->mPlatformConfig.mSpiCsDelay = atoi(optarg);
-            break;
-        case ARG_SPI_RESET_DELAY:
-            aConfig->mPlatformConfig.mSpiResetDelay = atoi(optarg);
-            break;
-        case ARG_SPI_ALIGN_ALLOWANCE:
-            aConfig->mPlatformConfig.mSpiAlignAllowance = atoi(optarg);
-            break;
-        case ARG_SPI_SMALL_PACKET:
-            aConfig->mPlatformConfig.mSpiSmallPacketSize = atoi(optarg);
-            break;
-#endif // OPENTHREAD_POSIX_RCP_SPI_ENABLE
+#endif // __linux__
         case '?':
             PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
             break;
@@ -286,13 +230,7 @@
     {
         PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
     }
-
-    aConfig->mPlatformConfig.mRadioFile = aArgVector[optind];
-
-    if (optind + 1 < aArgCount)
-    {
-        aConfig->mPlatformConfig.mRadioConfig = aArgVector[optind + 1];
-    }
+    aConfig->mPlatformConfig.mRadioUrl = aArgVector[optind];
 }
 
 static otInstance *InitInstance(int aArgCount, char *aArgVector[])
@@ -304,7 +242,9 @@
 
     openlog(aArgVector[0], LOG_PID | (config.mIsVerbose ? LOG_PERROR : 0), LOG_DAEMON);
     setlogmask(setlogmask(0) & LOG_UPTO(LOG_DEBUG));
-    otLoggingSetLevel(config.mLogLevel);
+    syslog(LOG_INFO, "Running %s", otGetVersionString());
+    syslog(LOG_INFO, "Thread version: %hu", otThreadGetVersion());
+    IgnoreError(otLoggingSetLevel(config.mLogLevel));
 
     instance = otSysInit(&config.mPlatformConfig);
 
@@ -312,6 +252,10 @@
     {
         printf("%s\n", otPlatRadioGetVersionString(instance));
     }
+    else
+    {
+        syslog(LOG_INFO, "RCP version: %s", otPlatRadioGetVersionString(instance));
+    }
 
     if (config.mIsDryRun)
     {
@@ -356,9 +300,9 @@
 
     instance = InitInstance(argc, argv);
 
-#if OPENTHREAD_POSIX_APP_TYPE == OPENTHREAD_POSIX_APP_TYPE_NCP
+#if OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_NCP
     otNcpInit(instance);
-#elif OPENTHREAD_POSIX_APP_TYPE == OPENTHREAD_POSIX_APP_TYPE_CLI
+#elif OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_CLI
 #if OPENTHREAD_USE_CONSOLE
     otxConsoleInit(instance);
 #else
diff --git a/src/posix/ncp.cmake b/src/posix/ncp.cmake
new file mode 100644
index 0000000..b185631
--- /dev/null
+++ b/src/posix/ncp.cmake
@@ -0,0 +1,60 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_executable(ot-ncp
+    main.c
+)
+
+set_target_properties(
+    ot-ncp
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
+
+target_include_directories(ot-ncp PRIVATE ${COMMON_INCLUDES})
+
+target_compile_definitions(ot-ncp PRIVATE
+    OPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_NCP
+    ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(ot-ncp PRIVATE
+    ${OT_CFLAGS}
+)
+
+target_link_libraries(ot-ncp
+    openthread-ncp-ftd
+    ${OT_PLATFORM_LIB}
+    openthread-ftd
+    ${OT_PLATFORM_LIB}
+    mbedcrypto
+    openthread-ncp-ftd
+)
+
+install(TARGETS ot-ncp DESTINATION bin)
diff --git a/src/posix/platform/CMakeLists.txt b/src/posix/platform/CMakeLists.txt
index 6cdc73e..9d9c14e 100644
--- a/src/posix/platform/CMakeLists.txt
+++ b/src/posix/platform/CMakeLists.txt
@@ -30,45 +30,85 @@
 
 option(OT_DAEMON "Enable daemon mode" OFF)
 if(OT_DAEMON)
-    list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_ENABLE_POSIX_APP_DAEMON=1")
+    list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE=1")
 endif()
 
-list(APPEND OT_PLATFORM_DEFINES
-    "OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1"
-    "OPENTHREAD_CONFIG_NCP_UART_ENABLE=1"
-    "OPENTHREAD_POSIX=1"
-    "OPENTHREAD_POSIX_RCP_UART_ENABLE=1"
-    "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"openthread-core-posix-config.h\""
-)
+option(OT_POSIX_VIRTUAL_TIME "enable virtual time" OFF)
+if(OT_POSIX_VIRTUAL_TIME)
+    list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_POSIX_VIRTUAL_TIME=1")
+endif()
+
+option(OT_POSIX_MAX_POWER_TABLE  "enable max power table" OFF)
+if(OT_POSIX_MAX_POWER_TABLE)
+    list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE=1")
+endif()
+
+set(OT_POSIX_CONFIG_RCP_BUS "" CACHE STRING "RCP bus type")
+if(OT_POSIX_CONFIG_RCP_BUS)
+    list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_POSIX_CONFIG_RCP_BUS=OT_POSIX_RCP_BUS_${OT_POSIX_CONFIG_RCP_BUS}")
+endif()
+
+if(NOT OT_CONFIG)
+    set(OT_CONFIG "openthread-core-posix-config.h")
+    set(OT_CONFIG ${OT_CONFIG} PARENT_SCOPE)
+endif()
+
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_POSIX=1")
+
 set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
 
+list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONFIG}\"")
+
 add_library(openthread-posix
-    alarm.c
-    entropy.c
+    alarm.cpp
+    entropy.cpp
     hdlc_interface.cpp
-    logging.c
-    misc.c
+    logging.cpp
+    misc.cpp
     netif.cpp
-    radio_spinel.cpp
+    radio.cpp
+    radio_url.cpp
     settings.cpp
-    sim.c
     spi_interface.cpp
-    system.c
-    uart.c
+    system.cpp
+    uart.cpp
     udp.cpp
+    virtual_time.cpp
 )
 
-target_link_libraries(openthread-posix PUBLIC
-    util
+set_target_properties(
+    openthread-posix
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
 )
 
-target_compile_definitions(openthread-posix PUBLIC ${OT_PLATFORM_DEFINES})
+target_link_libraries(openthread-posix
+    PUBLIC
+        openthread-platform
+    PRIVATE
+        openthread-url
+        ot-config
+        util
+        $<$<STREQUAL:${CMAKE_SYSTEM_NAME},Linux>:rt>
+)
+
+target_compile_definitions(openthread-posix
+    PUBLIC
+        ${OT_PUBLIC_DEFINES}
+    PRIVATE
+        ${OT_PLATFORM_DEFINES}
+)
+
+target_compile_options(openthread-posix PRIVATE
+    ${OT_CFLAGS}
+)
 
 target_include_directories(openthread-posix PRIVATE
     ${OT_PUBLIC_INCLUDES}
-    ${OT_PRIVATE_INCLUDES}
     ${PROJECT_SOURCE_DIR}/src
     ${PROJECT_SOURCE_DIR}/src/core
-    ${PROJECT_SOURCE_DIR}/src/posix/platform
     ${PROJECT_SOURCE_DIR}/third_party/mbedtls/repo/include
+    PUBLIC
+        ${PROJECT_SOURCE_DIR}/src/posix/platform/include
 )
diff --git a/src/posix/platform/Makefile.am b/src/posix/platform/Makefile.am
index 3d36340..c93bc21 100644
--- a/src/posix/platform/Makefile.am
+++ b/src/posix/platform/Makefile.am
@@ -27,67 +27,71 @@
 #
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
+include $(top_srcdir)/src/lib/common.am
 
 lib_LIBRARIES                             = libopenthread-posix.a
 
-libopenthread_posix_a_CPPFLAGS            = \
-    -I$(top_srcdir)/include                 \
-    -I$(top_srcdir)/src                     \
-    -I$(top_srcdir)/src/core                \
-    -I$(top_srcdir)/src/posix/platform      \
-    -D_GNU_SOURCE                           \
-    -DOPENTHREAD_FTD=1                      \
-    -DOPENTHREAD_MTD=0                      \
-    -DOPENTHREAD_RADIO=0                    \
+libopenthread_posix_a_CPPFLAGS                                = \
+    -I$(top_srcdir)/include                                     \
+    -I$(top_srcdir)/src                                         \
+    -I$(top_srcdir)/src/core                                    \
+    -I$(top_srcdir)/src/posix/platform                          \
+    -I$(top_srcdir)/src/posix/platform/include                  \
+    -D_GNU_SOURCE                                               \
+    -DOPENTHREAD_FTD=1                                          \
+    -DOPENTHREAD_MTD=0                                          \
+    -DOPENTHREAD_RADIO=0                                        \
     $(NULL)
 
 libopenthread_posix_a_SOURCES             = \
-    alarm.c                                 \
-    entropy.c                               \
+    alarm.cpp                               \
+    entropy.cpp                             \
     hdlc_interface.cpp                      \
-    logging.c                               \
-    misc.c                                  \
+    logging.cpp                             \
+    misc.cpp                                \
     netif.cpp                               \
-    radio_spinel.cpp                        \
+    radio.cpp                               \
+    radio_url.cpp                           \
     settings.cpp                            \
-    sim.c                                   \
     spi_interface.cpp                       \
-    system.c                                \
-    uart.c                                  \
+    system.cpp                              \
+    uart.cpp                                \
     udp.cpp                                 \
+    virtual_time.cpp                        \
+    $(NULL)
+
+libopenthread_posix_a_LIBADD                                                        = \
+    $(call ot_list_objects,$(top_builddir)/src/lib/url/libopenthread-url.a)           \
+    $(call ot_list_objects,$(top_builddir)/src/lib/platform/libopenthread-platform.a) \
     $(NULL)
 
 noinst_HEADERS                            = \
-    platform-posix.h                        \
     hdlc_interface.hpp                      \
-    radio_spinel.hpp                        \
-    spinel_interface.hpp                    \
+    openthread-posix-config.h               \
+    platform-posix.h                        \
+    radio_url.hpp                           \
     $(NULL)
 
 openthread_HEADERS                        = \
-    openthread-system.h                     \
+    include/openthread/openthread-system.h  \
     $(NULL)
 
 openthreaddir = $(includedir)/openthread
 dist_openthread_HEADERS = $(openthread_headers)
 
-PRETTY_FILES                              = \
-    $(libopenthread_posix_a_SOURCES)        \
-    $(noinst_HEADERS)                       \
-    $(openthread_HEADERS)                   \
-    $(NULL)
-
 if OPENTHREAD_BUILD_COVERAGE
 CLEANFILES                                = $(wildcard *.gcda *.gcno)
 endif # OPENTHREAD_BUILD_COVERAGE
 
 check_PROGRAMS = test-settings
 
-test_settings_CPPFLAGS                    = \
-    -I$(top_srcdir)/include                 \
-    -I$(top_srcdir)/src/core                \
-    -DOPENTHREAD_CONFIG_LOG_PLATFORM=0      \
-    -DSELF_TEST                             \
+test_settings_CPPFLAGS                                        = \
+    -I$(top_srcdir)/include                                     \
+    -I$(top_srcdir)/src                                         \
+    -I$(top_srcdir)/src/core                                    \
+    -I$(top_srcdir)/src/posix/platform/include                  \
+    -DOPENTHREAD_CONFIG_LOG_PLATFORM=0                          \
+    -DSELF_TEST                                                 \
     $(NULL)
 
 test_settings_SOURCES                     = \
diff --git a/src/posix/platform/README.md b/src/posix/platform/README.md
index 6b5f83a..6a02928 100644
--- a/src/posix/platform/README.md
+++ b/src/posix/platform/README.md
@@ -10,10 +10,9 @@
 $ make -f src/posix/Makefile-posix
 ```
 
-After a successful build, the `elf` files are found in
-`<path-to-openthread>/output/posix/<platform>/bin`.
+After a successful build, the `elf` files are found in `<path-to-openthread>/output/posix/<platform>/bin`.
 
-## 
+##
 
 ## Interact
 
diff --git a/src/posix/platform/alarm.c b/src/posix/platform/alarm.c
deleted file mode 100644
index 778efe9..0000000
--- a/src/posix/platform/alarm.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-#include <openthread/platform/alarm-micro.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/diag.h>
-
-#include "code_utils.h"
-
-static bool     sIsMsRunning = false;
-static uint32_t sMsAlarm     = 0;
-
-#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-static bool     sIsUsRunning = false;
-static uint32_t sUsAlarm     = 0;
-#endif
-
-static uint32_t sSpeedUpFactor = 1;
-
-#if !OPENTHREAD_POSIX_VIRTUAL_TIME
-uint64_t platformGetTime(void)
-{
-    struct timespec now;
-
-#ifdef CLOCK_MONOTONIC_RAW
-    VerifyOrDie(clock_gettime(CLOCK_MONOTONIC_RAW, &now) == 0, OT_EXIT_FAILURE);
-#else
-    VerifyOrDie(clock_gettime(CLOCK_MONOTONIC, &now) == 0, OT_EXIT_FAILURE);
-#endif
-
-    return (uint64_t)now.tv_sec * US_PER_S + (uint64_t)now.tv_nsec / NS_PER_US;
-}
-#endif // !OPENTHREAD_POSIX_VIRTUAL_TIME
-
-static uint64_t platformAlarmGetNow(void)
-{
-    return platformGetTime() * sSpeedUpFactor;
-}
-
-void platformAlarmInit(uint32_t aSpeedUpFactor)
-{
-    sSpeedUpFactor = aSpeedUpFactor;
-}
-
-uint32_t otPlatAlarmMilliGetNow(void)
-{
-    return (uint32_t)(platformAlarmGetNow() / US_PER_MS);
-}
-
-void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sMsAlarm     = aT0 + aDt;
-    sIsMsRunning = true;
-}
-
-void otPlatAlarmMilliStop(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sIsMsRunning = false;
-}
-
-#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-uint32_t otPlatAlarmMicroGetNow(void)
-{
-    return (uint32_t)(platformGetTime());
-}
-
-void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sUsAlarm     = aT0 + aDt;
-    sIsUsRunning = true;
-}
-
-void otPlatAlarmMicroStop(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sIsUsRunning = false;
-}
-#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-
-void platformAlarmUpdateTimeout(struct timeval *aTimeout)
-{
-    int64_t  remaining = INT32_MAX;
-    uint64_t now       = platformAlarmGetNow();
-
-    assert(aTimeout != NULL);
-
-    if (sIsMsRunning)
-    {
-        remaining = (int32_t)(sMsAlarm - (uint32_t)(now / US_PER_MS));
-        otEXPECT(remaining > 0);
-        remaining *= US_PER_MS;
-        remaining -= (now % US_PER_MS);
-    }
-
-#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-    if (sIsUsRunning)
-    {
-        int32_t usRemaining = (int32_t)(sUsAlarm - (uint32_t)now);
-
-        if (usRemaining < remaining)
-        {
-            remaining = usRemaining;
-        }
-    }
-#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-
-exit:
-    if (remaining <= 0)
-    {
-        aTimeout->tv_sec  = 0;
-        aTimeout->tv_usec = 0;
-    }
-    else
-    {
-        remaining /= sSpeedUpFactor;
-
-        if (remaining == 0)
-        {
-            remaining = 1;
-        }
-
-        aTimeout->tv_sec  = (time_t)(remaining / US_PER_S);
-        aTimeout->tv_usec = remaining % US_PER_S;
-    }
-}
-
-void platformAlarmProcess(otInstance *aInstance)
-{
-    int32_t remaining;
-
-    if (sIsMsRunning)
-    {
-        remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
-
-        if (remaining <= 0)
-        {
-            sIsMsRunning = false;
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-
-            if (otPlatDiagModeGet())
-            {
-                otPlatDiagAlarmFired(aInstance);
-            }
-            else
-#endif
-            {
-                otPlatAlarmMilliFired(aInstance);
-            }
-        }
-    }
-
-#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-
-    if (sIsUsRunning)
-    {
-        remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
-
-        if (remaining <= 0)
-        {
-            sIsUsRunning = false;
-
-            otPlatAlarmMicroFired(aInstance);
-        }
-    }
-
-#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-}
diff --git a/src/posix/platform/alarm.cpp b/src/posix/platform/alarm.cpp
new file mode 100644
index 0000000..0dfdddc
--- /dev/null
+++ b/src/posix/platform/alarm.cpp
@@ -0,0 +1,298 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "openthread-posix-config.h"
+#include "platform-posix.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include <openthread/platform/alarm-micro.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+
+#include "common/code_utils.hpp"
+
+static bool     sIsMsRunning = false;
+static uint32_t sMsAlarm     = 0;
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+static bool     sIsUsRunning = false;
+static uint32_t sUsAlarm     = 0;
+#endif
+
+static uint32_t sSpeedUpFactor = 1;
+
+#ifdef __linux__
+
+#include <signal.h>
+#include <time.h>
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE && !OPENTHREAD_POSIX_VIRTUAL_TIME
+static timer_t sMicroTimer;
+static int     sRealTimeSignal = 0;
+
+static void microTimerHandler(int aSignal, siginfo_t *aSignalInfo, void *aUserContext)
+{
+    assert(aSignal == sRealTimeSignal);
+    assert(aSignalInfo->si_value.sival_ptr == &sMicroTimer);
+    OT_UNUSED_VARIABLE(aSignal);
+    OT_UNUSED_VARIABLE(aSignalInfo);
+    OT_UNUSED_VARIABLE(aUserContext);
+}
+#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE && !OPENTHREAD_POSIX_VIRTUAL_TIME
+#endif // __linux__
+
+#ifdef CLOCK_MONOTONIC_RAW
+#define OT_POSIX_CLOCK_ID CLOCK_MONOTONIC_RAW
+#else
+#define OT_POSIX_CLOCK_ID CLOCK_MONOTONIC
+#endif
+
+#if !OPENTHREAD_POSIX_VIRTUAL_TIME
+uint64_t otPlatTimeGet(void)
+{
+    struct timespec now;
+
+    VerifyOrDie(clock_gettime(OT_POSIX_CLOCK_ID, &now) == 0, OT_EXIT_FAILURE);
+
+    return (uint64_t)now.tv_sec * US_PER_S + (uint64_t)now.tv_nsec / NS_PER_US;
+}
+#endif // !OPENTHREAD_POSIX_VIRTUAL_TIME
+
+static uint64_t platformAlarmGetNow(void)
+{
+    return otPlatTimeGet() * sSpeedUpFactor;
+}
+
+void platformAlarmInit(uint32_t aSpeedUpFactor, int aRealTimeSignal)
+{
+    sSpeedUpFactor = aSpeedUpFactor;
+
+    if (aRealTimeSignal == 0)
+    {
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+        otLogWarnPlat("Real time signal not enabled, microsecond timers may be inaccurate!");
+#endif
+    }
+#ifdef __linux__
+    else if (aRealTimeSignal >= SIGRTMIN && aRealTimeSignal <= SIGRTMAX)
+    {
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE && !OPENTHREAD_POSIX_VIRTUAL_TIME
+        struct sigaction sa;
+        struct sigevent  sev;
+
+        sa.sa_flags     = SA_SIGINFO;
+        sa.sa_sigaction = microTimerHandler;
+        sigemptyset(&sa.sa_mask);
+
+        VerifyOrDie(sigaction(aRealTimeSignal, &sa, NULL) != -1, OT_EXIT_ERROR_ERRNO);
+
+        sev.sigev_notify          = SIGEV_SIGNAL;
+        sev.sigev_signo           = aRealTimeSignal;
+        sev.sigev_value.sival_ptr = &sMicroTimer;
+
+        VerifyOrDie(timer_create(CLOCK_MONOTONIC, &sev, &sMicroTimer) != -1, OT_EXIT_ERROR_ERRNO);
+
+        sRealTimeSignal = aRealTimeSignal;
+#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE && !OPENTHREAD_POSIX_VIRTUAL_TIME
+    }
+#endif // __linux__
+    else
+    {
+        DieNow(OT_EXIT_INVALID_ARGUMENTS);
+    }
+}
+
+uint32_t otPlatAlarmMilliGetNow(void)
+{
+    return (uint32_t)(platformAlarmGetNow() / US_PER_MS);
+}
+
+void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sMsAlarm     = aT0 + aDt;
+    sIsMsRunning = true;
+}
+
+void otPlatAlarmMilliStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sIsMsRunning = false;
+}
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+uint32_t otPlatAlarmMicroGetNow(void)
+{
+    return static_cast<uint32_t>(platformAlarmGetNow());
+}
+
+void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sUsAlarm     = aT0 + aDt;
+    sIsUsRunning = true;
+
+#ifdef __linux__
+    if (sRealTimeSignal != 0)
+    {
+        struct itimerspec its;
+        uint32_t          diff = sUsAlarm - otPlatAlarmMicroGetNow();
+
+        its.it_value.tv_sec  = diff / US_PER_S;
+        its.it_value.tv_nsec = (diff % US_PER_S) * NS_PER_US;
+
+        its.it_interval.tv_sec  = 0;
+        its.it_interval.tv_nsec = 0;
+
+        if (-1 == timer_settime(sMicroTimer, 0, &its, NULL))
+        {
+            otLogWarnPlat("Failed to update microsecond timer: %s", strerror(errno));
+        }
+    }
+#endif // __linux__
+}
+
+void otPlatAlarmMicroStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sIsUsRunning = false;
+
+#ifdef __linux__
+    if (sRealTimeSignal != 0)
+    {
+        struct itimerspec its = {{0, 0}, {0, 0}};
+
+        if (-1 == timer_settime(sMicroTimer, 0, &its, NULL))
+        {
+            otLogWarnPlat("Failed to stop microsecond timer: %s", strerror(errno));
+        }
+    }
+#endif // __linux__
+}
+#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+
+void platformAlarmUpdateTimeout(struct timeval *aTimeout)
+{
+    int64_t  remaining = INT32_MAX;
+    uint64_t now       = platformAlarmGetNow();
+
+    assert(aTimeout != nullptr);
+
+    if (sIsMsRunning)
+    {
+        remaining = (int32_t)(sMsAlarm - (uint32_t)(now / US_PER_MS));
+        VerifyOrExit(remaining > 0, OT_NOOP);
+        remaining *= US_PER_MS;
+        remaining -= (now % US_PER_MS);
+    }
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+    if (sIsUsRunning)
+    {
+        int32_t usRemaining = (int32_t)(sUsAlarm - (uint32_t)now);
+
+        if (usRemaining < remaining)
+        {
+            remaining = usRemaining;
+        }
+    }
+#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+
+exit:
+    if (remaining <= 0)
+    {
+        aTimeout->tv_sec  = 0;
+        aTimeout->tv_usec = 0;
+    }
+    else
+    {
+        remaining /= sSpeedUpFactor;
+
+        if (remaining == 0)
+        {
+            remaining = 1;
+        }
+
+        if (remaining < aTimeout->tv_sec * US_PER_S + aTimeout->tv_usec)
+        {
+            aTimeout->tv_sec  = static_cast<time_t>(remaining / US_PER_S);
+            aTimeout->tv_usec = static_cast<suseconds_t>(remaining % US_PER_S);
+        }
+    }
+}
+
+void platformAlarmProcess(otInstance *aInstance)
+{
+    int32_t remaining;
+
+    if (sIsMsRunning)
+    {
+        remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
+
+        if (remaining <= 0)
+        {
+            sIsMsRunning = false;
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+
+            if (otPlatDiagModeGet())
+            {
+                otPlatDiagAlarmFired(aInstance);
+            }
+            else
+#endif
+            {
+                otPlatAlarmMilliFired(aInstance);
+            }
+        }
+    }
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+
+    if (sIsUsRunning)
+    {
+        remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
+
+        if (remaining <= 0)
+        {
+            sIsUsRunning = false;
+
+            otPlatAlarmMicroFired(aInstance);
+        }
+    }
+
+#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+}
diff --git a/src/posix/platform/code_utils.h b/src/posix/platform/code_utils.h
deleted file mode 100644
index 46b0d00..0000000
--- a/src/posix/platform/code_utils.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  Copyright (c) 2017, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes macros for validating runtime conditions.
- */
-
-#ifndef CODE_UTILS_H
-#define CODE_UTILS_H
-
-/**
- *  This checks for the specified condition, which is expected to
- *  commonly be true, and branches to the local label 'exit' if the
- *  condition is false.
- *
- *  @param[in]  aCondition  A Boolean expression to be evaluated.
- *
- */
-#define otEXPECT(aCondition) \
-    do                       \
-    {                        \
-        if (!(aCondition))   \
-        {                    \
-            goto exit;       \
-        }                    \
-    } while (0)
-
-/**
- *  This checks for the specified condition, which is expected to
- *  commonly be true, and both executes @p anAction and branches to
- *  the local label 'exit' if the condition is false.
- *
- *  @param[in]  aCondition  A Boolean expression to be evaluated.
- *  @param[in]  aAction     An expression or block to execute when the
- *                          assertion fails.
- *
- */
-#define otEXPECT_ACTION(aCondition, aAction) \
-    do                                       \
-    {                                        \
-        if (!(aCondition))                   \
-        {                                    \
-            aAction;                         \
-            goto exit;                       \
-        }                                    \
-    } while (0)
-
-/**
- *  This unconditionally executes @aAction and branches to the local
- *  label 'exit'.
- *
- *  @note The use of this interface implies neither success nor
- *        failure for the overall exit status of the enclosing
- *        function body.
- *
- *  @param[in]  aAction     An expression or block to execute.
- *
- */
-#define otEXIT_NOW(aAction) \
-    do                      \
-    {                       \
-        aAction;            \
-        goto exit;          \
-    } while (0)
-
-#endif // CODE_UTILS_H
diff --git a/src/posix/platform/entropy.c b/src/posix/platform/entropy.c
deleted file mode 100644
index b31b78c..0000000
--- a/src/posix/platform/entropy.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements an entropy source based on /dev/urandom or pseudo-random generator.
- *
- */
-
-#include <openthread/platform/entropy.h>
-
-#include "openthread-core-config.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-#include "code_utils.h"
-#include "platform-posix.h"
-
-#include <openthread/error.h>
-
-#ifndef __SANITIZE_ADDRESS__
-#define __SANITIZE_ADDRESS__ 0
-#endif
-
-#if __SANITIZE_ADDRESS__ != 0
-
-static uint32_t sState = 1;
-
-#endif // __SANITIZE_ADDRESS__
-
-void platformRandomInit(void)
-{
-#if __SANITIZE_ADDRESS__ != 0
-
-    // Multiplying gNodeId assures that no two nodes gets the same seed within an hour.
-    sState = (uint32_t)time(NULL) + (3600 * gNodeId);
-
-#endif // __SANITIZE_ADDRESS__
-}
-
-#if __SANITIZE_ADDRESS__ != 0
-
-uint32_t randomUint32Get(void)
-{
-    uint32_t mlcg, p, q;
-    uint64_t tmpstate;
-
-    tmpstate = (uint64_t)33614 * (uint64_t)sState;
-    q        = tmpstate & 0xffffffff;
-    q        = q >> 1;
-    p        = tmpstate >> 32;
-    mlcg     = p + q;
-
-    if (mlcg & 0x80000000)
-    {
-        mlcg &= 0x7fffffff;
-        mlcg++;
-    }
-
-    sState = mlcg;
-
-    return mlcg;
-}
-
-#endif // __SANITIZE_ADDRESS__
-
-otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
-{
-    otError error = OT_ERROR_NONE;
-
-#if __SANITIZE_ADDRESS__ == 0
-
-    FILE * file = NULL;
-    size_t readLength;
-
-    otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
-
-    file = fopen("/dev/urandom", "rb");
-    otEXPECT_ACTION(file != NULL, error = OT_ERROR_FAILED);
-
-    readLength = fread(aOutput, 1, aOutputLength, file);
-    otEXPECT_ACTION(readLength == aOutputLength, error = OT_ERROR_FAILED);
-
-exit:
-
-    if (file != NULL)
-    {
-        fclose(file);
-    }
-
-#else // __SANITIZE_ADDRESS__
-
-    /*
-     * THE IMPLEMENTATION BELOW IS NOT COMPLIANT WITH THE THREAD SPECIFICATION.
-     *
-     * Address Sanitizer triggers test failures when reading random
-     * values from /dev/urandom.  The pseudo-random number generator
-     * implementation below is only used to enable continuous
-     * integration checks with Address Sanitizer enabled.
-     */
-    otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
-
-    for (uint16_t length = 0; length < aOutputLength; length++)
-    {
-        aOutput[length] = (uint8_t)randomUint32Get();
-    }
-
-exit:
-
-#endif // __SANITIZE_ADDRESS__
-
-    return error;
-}
diff --git a/src/posix/platform/entropy.cpp b/src/posix/platform/entropy.cpp
new file mode 100644
index 0000000..561f279
--- /dev/null
+++ b/src/posix/platform/entropy.cpp
@@ -0,0 +1,138 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements an entropy source based on /dev/urandom or pseudo-random generator.
+ *
+ */
+
+#include "openthread-posix-config.h"
+#include "platform-posix.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <openthread/error.h>
+#include <openthread/platform/entropy.h>
+
+#include "common/code_utils.hpp"
+
+#ifndef __SANITIZE_ADDRESS__
+#define __SANITIZE_ADDRESS__ 0
+#endif
+
+#if __SANITIZE_ADDRESS__ != 0
+
+static uint32_t sState = 1;
+
+#endif // __SANITIZE_ADDRESS__
+
+void platformRandomInit(void)
+{
+#if __SANITIZE_ADDRESS__ != 0
+
+    // Multiplying gNodeId assures that no two nodes gets the same seed within an hour.
+    sState = (uint32_t)time(nullptr) + (3600 * gNodeId);
+
+#endif // __SANITIZE_ADDRESS__
+}
+
+#if __SANITIZE_ADDRESS__ != 0
+
+uint32_t randomUint32Get(void)
+{
+    uint32_t mlcg, p, q;
+    uint64_t tmpstate;
+
+    tmpstate = (uint64_t)33614 * (uint64_t)sState;
+    q        = tmpstate & 0xffffffff;
+    q        = q >> 1;
+    p        = tmpstate >> 32;
+    mlcg     = p + q;
+
+    if (mlcg & 0x80000000)
+    {
+        mlcg &= 0x7fffffff;
+        mlcg++;
+    }
+
+    sState = mlcg;
+
+    return mlcg;
+}
+
+#endif // __SANITIZE_ADDRESS__
+
+otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
+{
+    otError error = OT_ERROR_NONE;
+
+#if __SANITIZE_ADDRESS__ == 0
+
+    FILE * file = nullptr;
+    size_t readLength;
+
+    VerifyOrExit(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
+
+    file = fopen("/dev/urandom", "rb");
+    VerifyOrExit(file != nullptr, error = OT_ERROR_FAILED);
+
+    readLength = fread(aOutput, 1, aOutputLength, file);
+    VerifyOrExit(readLength == aOutputLength, error = OT_ERROR_FAILED);
+
+exit:
+
+    if (file != nullptr)
+    {
+        fclose(file);
+    }
+
+#else // __SANITIZE_ADDRESS__
+
+    /*
+     * THE IMPLEMENTATION BELOW IS NOT COMPLIANT WITH THE THREAD SPECIFICATION.
+     *
+     * Address Sanitizer triggers test failures when reading random
+     * values from /dev/urandom.  The pseudo-random number generator
+     * implementation below is only used to enable continuous
+     * integration checks with Address Sanitizer enabled.
+     */
+    VerifyOrExit(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
+
+    for (uint16_t length = 0; length < aOutputLength; length++)
+    {
+        aOutput[length] = (uint8_t)randomUint32Get();
+    }
+
+exit:
+
+#endif // __SANITIZE_ADDRESS__
+
+    return error;
+}
diff --git a/src/posix/platform/hdlc_interface.cpp b/src/posix/platform/hdlc_interface.cpp
index 0b90864..9ae3573 100644
--- a/src/posix/platform/hdlc_interface.cpp
+++ b/src/posix/platform/hdlc_interface.cpp
@@ -31,17 +31,18 @@
  *   This file includes the implementation for the HDLC interface to radio (RCP).
  */
 
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-
 #include "hdlc_interface.hpp"
 
+#include "platform-posix.h"
+
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
-#if OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
-#ifdef __APPLE__
+#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
+#if defined(__APPLE__) || defined(__NetBSD__)
 #include <util.h>
+#elif defined(__FreeBSD__)
+#include <libutil.h>
 #else
 #include <pty.h>
 #endif
@@ -56,8 +57,8 @@
 #include <termios.h>
 #include <unistd.h>
 
-#include <common/code_utils.hpp>
-#include <common/logging.hpp>
+#include "common/code_utils.hpp"
+#include "common/logging.hpp"
 
 #ifndef SOCKET_UTILS_DEFAULT_SHELL
 #define SOCKET_UTILS_DEFAULT_SHELL "/bin/sh"
@@ -119,43 +120,48 @@
 
 #endif // __APPLE__
 
-#if OPENTHREAD_POSIX_RCP_UART_ENABLE
+#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART
+
+using ot::Spinel::SpinelInterface;
 
 namespace ot {
-namespace PosixApp {
+namespace Posix {
 
-HdlcInterface::HdlcInterface(SpinelInterface::Callbacks &aCallback, SpinelInterface::RxFrameBuffer &aFrameBuffer)
-    : mCallbacks(aCallback)
-    , mRxFrameBuffer(aFrameBuffer)
+HdlcInterface::HdlcInterface(SpinelInterface::ReceiveFrameCallback aCallback,
+                             void *                                aCallbackContext,
+                             SpinelInterface::RxFrameBuffer &      aFrameBuffer)
+    : mReceiveFrameCallback(aCallback)
+    , mReceiveFrameContext(aCallbackContext)
+    , mReceiveFrameBuffer(aFrameBuffer)
     , mSockFd(-1)
     , mHdlcDecoder(aFrameBuffer, HandleHdlcFrame, this)
 {
 }
 
-otError HdlcInterface::Init(const otPlatformConfig &aPlatformConfig)
+otError HdlcInterface::Init(const RadioUrl &aRadioUrl)
 {
     otError     error = OT_ERROR_NONE;
     struct stat st;
 
     VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY);
 
-    VerifyOrDie(stat(aPlatformConfig.mRadioFile, &st) == 0, OT_EXIT_INVALID_ARGUMENTS);
+    VerifyOrDie(stat(aRadioUrl.GetPath(), &st) == 0, OT_EXIT_INVALID_ARGUMENTS);
 
     if (S_ISCHR(st.st_mode))
     {
-        mSockFd = OpenFile(aPlatformConfig.mRadioFile, aPlatformConfig.mRadioConfig);
+        mSockFd = OpenFile(aRadioUrl);
         VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS);
     }
-#if OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
+#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
     else if (S_ISREG(st.st_mode))
     {
-        mSockFd = ForkPty(aPlatformConfig.mRadioFile, aPlatformConfig.mRadioConfig);
+        mSockFd = ForkPty(aRadioUrl.GetPath(), aRadioUrl.GetValue("forkpty-arg"));
         VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS);
     }
-#endif // OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
+#endif // OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
     else
     {
-        otLogCritPlat("Radio file '%s' not supported", aPlatformConfig.mRadioFile);
+        otLogCritPlat("Radio file '%s' not supported", aRadioUrl.GetPath());
         ExitNow(error = OT_ERROR_INVALID_ARGS);
     }
 
@@ -170,10 +176,10 @@
 
 void HdlcInterface::Deinit(void)
 {
-    VerifyOrExit(mSockFd != -1);
+    VerifyOrExit(mSockFd != -1, OT_NOOP);
 
     VerifyOrExit(0 == close(mSockFd), perror("close RCP"));
-    VerifyOrExit(-1 != wait(NULL) || errno == ECHILD, perror("wait RCP"));
+    VerifyOrExit(-1 != wait(nullptr) || errno == ECHILD, perror("wait RCP"));
 
     mSockFd = -1;
 
@@ -223,22 +229,24 @@
 {
     otError error = OT_ERROR_NONE;
 #if OPENTHREAD_POSIX_VIRTUAL_TIME
-    platformSimSendRadioSpinelWriteEvent(aFrame, aLength);
+    virtualTimeSendRadioSpinelWriteEvent(aFrame, aLength);
 #else
     while (aLength)
     {
         ssize_t rval = write(mSockFd, aFrame, aLength);
 
-        if (rval > 0)
+        if (rval == aLength)
+        {
+            break;
+        }
+        else if (rval > 0)
         {
             aLength -= static_cast<uint16_t>(rval);
             aFrame += static_cast<uint16_t>(rval);
-            continue;
         }
-
-        if ((rval < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR))
+        else if (rval < 0)
         {
-            DieNow(OT_EXIT_ERROR_ERRNO);
+            VerifyOrDie((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR), OT_EXIT_ERROR_ERRNO);
         }
 
         SuccessOrExit(error = WaitForWritable());
@@ -249,16 +257,18 @@
     return error;
 }
 
-otError HdlcInterface::WaitForFrame(const struct timeval &aTimeout)
+otError HdlcInterface::WaitForFrame(uint64_t aTimeoutUs)
 {
-    otError        error   = OT_ERROR_NONE;
-    struct timeval timeout = aTimeout;
-
+    otError        error = OT_ERROR_NONE;
+    struct timeval timeout;
 #if OPENTHREAD_POSIX_VIRTUAL_TIME
-    struct Event event;
+    struct VirtualTimeEvent event;
 
-    platformSimSendSleepEvent(&timeout);
-    platformSimReceiveEvent(&event);
+    timeout.tv_sec  = static_cast<time_t>(aTimeoutUs / US_PER_S);
+    timeout.tv_usec = static_cast<suseconds_t>(aTimeoutUs % US_PER_S);
+
+    virtualTimeSendSleepEvent(&timeout);
+    virtualTimeReceiveEvent(&event);
 
     switch (event.mEvent)
     {
@@ -267,7 +277,7 @@
         break;
 
     case OT_SIM_EVENT_ALARM_FIRED:
-        ExitNow(error = OT_ERROR_RESPONSE_TIMEOUT);
+        VerifyOrExit(event.mDelay <= aTimeoutUs, error = OT_ERROR_RESPONSE_TIMEOUT);
         break;
 
     default:
@@ -275,6 +285,9 @@
         break;
     }
 #else  // OPENTHREAD_POSIX_VIRTUAL_TIME
+    timeout.tv_sec = static_cast<time_t>(aTimeoutUs / US_PER_S);
+    timeout.tv_usec = static_cast<suseconds_t>(aTimeoutUs % US_PER_S);
+
     fd_set read_fds;
     fd_set error_fds;
     int rval;
@@ -284,7 +297,7 @@
     FD_SET(mSockFd, &read_fds);
     FD_SET(mSockFd, &error_fds);
 
-    rval = select(mSockFd + 1, &read_fds, NULL, &error_fds, &timeout);
+    rval = select(mSockFd + 1, &read_fds, nullptr, &error_fds, &timeout);
 
     if (rval > 0)
     {
@@ -328,11 +341,9 @@
     }
 }
 
-void HdlcInterface::Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet)
+void HdlcInterface::Process(const RadioProcessContext &aContext)
 {
-    OT_UNUSED_VARIABLE(aWriteFdSet);
-
-    if (FD_ISSET(mSockFd, &aReadFdSet))
+    if (FD_ISSET(mSockFd, aContext.mReadFdSet))
     {
         Read();
     }
@@ -342,7 +353,7 @@
 {
     otError        error   = OT_ERROR_NONE;
     struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000};
-    uint64_t       now     = platformGetTime();
+    uint64_t       now     = otPlatTimeGet();
     uint64_t       end     = now + kMaxWaitTime * US_PER_MS;
     fd_set         writeFds;
     fd_set         errorFds;
@@ -355,7 +366,7 @@
         FD_SET(mSockFd, &writeFds);
         FD_SET(mSockFd, &errorFds);
 
-        rval = select(mSockFd + 1, NULL, &writeFds, &errorFds, &timeout);
+        rval = select(mSockFd + 1, nullptr, &writeFds, &errorFds, &timeout);
 
         if (rval > 0)
         {
@@ -377,7 +388,7 @@
             DieNow(OT_EXIT_ERROR_ERRNO);
         }
 
-        now = platformGetTime();
+        now = otPlatTimeGet();
 
         if (end > now)
         {
@@ -398,12 +409,12 @@
     return error;
 }
 
-int HdlcInterface::OpenFile(const char *aFile, const char *aConfig)
+int HdlcInterface::OpenFile(const RadioUrl &aRadioUrl)
 {
     int fd   = -1;
     int rval = 0;
 
-    fd = open(aFile, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC);
+    fd = open(aRadioUrl.GetPath(), O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC);
     if (fd == -1)
     {
         perror("open uart failed");
@@ -413,41 +424,41 @@
     if (isatty(fd))
     {
         struct termios tios;
+        const char *   value;
+        speed_t        speed;
 
-        int  speed  = 115200;
-        int  cstopb = 1;
-        char parity = 'N';
-        char flow   = 'N';
+        int      stopBit  = 1;
+        uint32_t baudrate = 115200;
 
-        VerifyOrExit((rval = tcgetattr(fd, &tios)) == 0);
+        VerifyOrExit((rval = tcgetattr(fd, &tios)) == 0, OT_NOOP);
 
         cfmakeraw(&tios);
 
         tios.c_cflag = CS8 | HUPCL | CREAD | CLOCAL;
 
-        // example: 115200N1H
-        if (aConfig != NULL)
+        if ((value = aRadioUrl.GetValue("uart-parity")) != nullptr)
         {
-            sscanf(aConfig, "%u%c%d%c", &speed, &parity, &cstopb, &flow);
+            if (strncmp(value, "odd", 3) == 0)
+            {
+                tios.c_cflag |= PARENB;
+                tios.c_cflag |= PARODD;
+            }
+            else if (strncmp(value, "even", 4) == 0)
+            {
+                tios.c_cflag |= PARENB;
+            }
+            else
+            {
+                DieNow(OT_EXIT_INVALID_ARGUMENTS);
+            }
         }
 
-        switch (parity)
+        if ((value = aRadioUrl.GetValue("uart-stop")) != nullptr)
         {
-        case 'N':
-            break;
-        case 'E':
-            tios.c_cflag |= PARENB;
-            break;
-        case 'O':
-            tios.c_cflag |= (PARENB | PARODD);
-            break;
-        default:
-            // not supported
-            DieNow(OT_EXIT_INVALID_ARGUMENTS);
-            break;
+            stopBit = atoi(value);
         }
 
-        switch (cstopb)
+        switch (stopBit)
         {
         case 1:
             tios.c_cflag &= static_cast<unsigned long>(~CSTOPB);
@@ -460,7 +471,12 @@
             break;
         }
 
-        switch (speed)
+        if ((value = aRadioUrl.GetValue("uart-baudrate")))
+        {
+            baudrate = static_cast<uint32_t>(atoi(value));
+        }
+
+        switch (baudrate)
         {
         case 9600:
             speed = B9600;
@@ -547,22 +563,14 @@
             break;
         }
 
-        switch (flow)
+        if (aRadioUrl.GetValue("uart-flow-control") != nullptr)
         {
-        case 'N':
-            break;
-        case 'H':
             tios.c_cflag |= CRTSCTS;
-            break;
-        default:
-            // not supported
-            DieNow(OT_EXIT_INVALID_ARGUMENTS);
-            break;
         }
 
         VerifyOrExit((rval = cfsetspeed(&tios, static_cast<speed_t>(speed))) == 0, perror("cfsetspeed"));
         VerifyOrExit((rval = tcsetattr(fd, TCSANOW, &tios)) == 0, perror("tcsetattr"));
-        VerifyOrExit((rval = tcflush(fd, TCIOFLUSH)) == 0);
+        VerifyOrExit((rval = tcflush(fd, TCIOFLUSH)) == 0, OT_NOOP);
     }
 
 exit:
@@ -574,8 +582,8 @@
     return fd;
 }
 
-#if OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
-int HdlcInterface::ForkPty(const char *aCommand, const char *aArguments)
+#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
+int HdlcInterface::ForkPty(const char *aCommand, const char *aRadioUrl)
 {
     int fd   = -1;
     int pid  = -1;
@@ -588,7 +596,7 @@
         cfmakeraw(&tios);
         tios.c_cflag = CS8 | HUPCL | CREAD | CLOCAL;
 
-        VerifyOrExit((pid = forkpty(&fd, NULL, &tios, NULL)) != -1, perror("forkpty()"));
+        VerifyOrExit((pid = forkpty(&fd, nullptr, &tios, nullptr)) != -1, perror("forkpty()"));
     }
 
     if (0 == pid)
@@ -596,13 +604,20 @@
         const int kMaxCommand = 255;
         char      cmd[kMaxCommand];
 
-        rval = snprintf(cmd, sizeof(cmd), "exec %s %s", aCommand, aArguments);
+        if (aRadioUrl == nullptr)
+        {
+            rval = snprintf(cmd, sizeof(cmd), "exec %s", aCommand);
+        }
+        else
+        {
+            rval = snprintf(cmd, sizeof(cmd), "exec %s %s", aCommand, aRadioUrl);
+        }
         VerifyOrExit(rval > 0 && static_cast<size_t>(rval) < sizeof(cmd),
                      fprintf(stderr, "NCP file and configuration is too long!");
                      rval = -1);
 
         VerifyOrExit((rval = execl(SOCKET_UTILS_DEFAULT_SHELL, SOCKET_UTILS_DEFAULT_SHELL, "-c", cmd,
-                                   static_cast<char *>(NULL))) != -1,
+                                   static_cast<char *>(nullptr))) != -1,
                      perror("execl(OT_RCP)"));
     }
     else
@@ -615,7 +630,7 @@
     VerifyOrDie(rval == 0, OT_EXIT_ERROR_ERRNO);
     return fd;
 }
-#endif // OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
+#endif // OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
 
 void HdlcInterface::HandleHdlcFrame(void *aContext, otError aError)
 {
@@ -626,15 +641,15 @@
 {
     if (aError == OT_ERROR_NONE)
     {
-        mCallbacks.HandleReceivedFrame();
+        mReceiveFrameCallback(mReceiveFrameContext);
     }
     else
     {
-        mRxFrameBuffer.DiscardFrame();
+        mReceiveFrameBuffer.DiscardFrame();
         otLogWarnPlat("Error decoding hdlc frame: %s", otThreadErrorToString(aError));
     }
 }
 
-} // namespace PosixApp
+} // namespace Posix
 } // namespace ot
-#endif // OPENTHREAD_POSIX_RCP_UART_ENABLE
+#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART
diff --git a/src/posix/platform/hdlc_interface.hpp b/src/posix/platform/hdlc_interface.hpp
index 14b321a..2db2400 100644
--- a/src/posix/platform/hdlc_interface.hpp
+++ b/src/posix/platform/hdlc_interface.hpp
@@ -34,14 +34,15 @@
 #ifndef POSIX_APP_HDLC_INTERFACE_HPP_
 #define POSIX_APP_HDLC_INTERFACE_HPP_
 
-#include "platform-config.h"
-#include "spinel_interface.hpp"
-#include "ncp/hdlc.hpp"
+#include "openthread-posix-config.h"
+#include "platform-posix.h"
+#include "lib/hdlc/hdlc.hpp"
+#include "lib/spinel/spinel_interface.hpp"
 
-#if OPENTHREAD_POSIX_RCP_UART_ENABLE
+#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART
 
 namespace ot {
-namespace PosixApp {
+namespace Posix {
 
 /**
  * This class defines an HDLC interface to the Radio Co-processor (RCP)
@@ -53,11 +54,14 @@
     /**
      * This constructor initializes the object.
      *
-     * @param[in] aCallback     A reference to a `Callback` object.
-     * @param[in] aFrameBuffer  A reference to a `RxFrameBuffer` object.
+     * @param[in] aCallback         Callback on frame received
+     * @param[in] aCallbackContext  Callback context
+     * @param[in] aFrameBuffer      A reference to a `RxFrameBuffer` object.
      *
      */
-    HdlcInterface(SpinelInterface::Callbacks &aCallback, SpinelInterface::RxFrameBuffer &aFrameBuffer);
+    HdlcInterface(Spinel::SpinelInterface::ReceiveFrameCallback aCallback,
+                  void *                                        aCallbackContext,
+                  Spinel::SpinelInterface::RxFrameBuffer &      aFrameBuffer);
 
     /**
      * This destructor deinitializes the object.
@@ -70,14 +74,14 @@
      *
      * @note This method should be called before reading and sending spinel frames to the interface.
      *
-     * @param[in]  aPlatformConfig  Platform configuration structure.
+     * @param[in]  aRadioUrl          RadioUrl parsed from radio url.
      *
      * @retval OT_ERROR_NONE          The interface is initialized successfully
      * @retval OT_ERROR_ALREADY       The interface is already initialized.
      * @retval OT_ERROR_INVALID_ARGS  The UART device or executable cannot be found or failed to open/run.
      *
      */
-    otError Init(const otPlatformConfig &aPlatformConfig);
+    otError Init(const RadioUrl &aRadioUrl);
 
     /**
      * This method deinitializes the interface to the RCP.
@@ -104,13 +108,13 @@
     /**
      * This method waits for receiving part or all of spinel frame within specified interval.
      *
-     * @param[in]  aTimeout  A reference to the timeout.
+     * @param[in]  aTimeout  The timeout value in microseconds.
      *
      * @retval OT_ERROR_NONE             Part or all of spinel frame is received.
      * @retval OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p aTimeout.
      *
      */
-    otError WaitForFrame(const struct timeval &aTimeout);
+    otError WaitForFrame(uint64_t aTimeoutUs);
 
     /**
      * This method updates the file descriptor sets with file descriptors used by the radio driver.
@@ -126,24 +130,22 @@
     /**
      * This method performs radio driver processing.
      *
-     * @param[in]   aReadFdSet      A reference to the read file descriptors.
-     * @param[in]   aWriteFdSet     A reference to the write file descriptors.
+     * @param[in]   aContext        The context containing fd_sets.
      *
      */
-    void Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet);
+    void Process(const RadioProcessContext &aContext);
 
 #if OPENTHREAD_POSIX_VIRTUAL_TIME
     /**
      * This method process read data (decode the data).
      *
      * This method is intended only for virtual time simulation. Its behavior is similar to `Read()` but instead of
-     * reading the data from the radio socket, it uses the given data in the buffer `aBuffer`.
+     * reading the data from the radio socket, it uses the given data in @p `aEvent`.
      *
-     * @param[in] aBuffer  A pointer to buffer containing data.
-     * @param[in] aLength  The length (number of bytes) in the buffer.
+     * @param[in] aEvent   The data event.
      *
      */
-    void ProcessReadData(const uint8_t *aBuffer, uint16_t aLength) { Decode(aBuffer, aLength); }
+    void Process(const VirtualTimeEvent &aEvent) { Decode(aEvent.mData, aEvent.mDataLength); }
 #endif
 
 private:
@@ -196,26 +198,31 @@
     static void HandleHdlcFrame(void *aContext, otError aError);
     void        HandleHdlcFrame(otError aError);
 
-    static int OpenFile(const char *aFile, const char *aConfig);
-#if OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
-    static int ForkPty(const char *aCommand, const char *aArguments);
+    static int OpenFile(const RadioUrl &aRadioUrl);
+#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
+    static int ForkPty(const char *aCommand, const char *aRadioUrl);
 #endif
 
     enum
     {
-        kMaxFrameSize = SpinelInterface::kMaxFrameSize,
+        kMaxFrameSize = Spinel::SpinelInterface::kMaxFrameSize,
         kMaxWaitTime  = 2000, ///< Maximum wait time in Milliseconds for socket to become writable (see `SendFrame`).
     };
 
-    SpinelInterface::Callbacks &    mCallbacks;
-    SpinelInterface::RxFrameBuffer &mRxFrameBuffer;
+    Spinel::SpinelInterface::ReceiveFrameCallback mReceiveFrameCallback;
+    void *                                        mReceiveFrameContext;
+    Spinel::SpinelInterface::RxFrameBuffer &      mReceiveFrameBuffer;
 
     int           mSockFd;
     Hdlc::Decoder mHdlcDecoder;
+
+    // Non-copyable, intentionally not implemented.
+    HdlcInterface(const HdlcInterface &);
+    HdlcInterface &operator=(const HdlcInterface &);
 };
 
-} // namespace PosixApp
+} // namespace Posix
 } // namespace ot
 
-#endif // OPENTHREAD_POSIX_RCP_UART_ENABLE
+#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART
 #endif // POSIX_APP_HDLC_INTERFACE_HPP_
diff --git a/src/posix/platform/include/openthread/openthread-system.h b/src/posix/platform/include/openthread/openthread-system.h
new file mode 100644
index 0000000..6c63301
--- /dev/null
+++ b/src/posix/platform/include/openthread/openthread-system.h
@@ -0,0 +1,157 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *   This file defines the platform-specific functions needed by OpenThread's example applications.
+ */
+
+#ifndef OPENTHREAD_SYSTEM_H_
+#define OPENTHREAD_SYSTEM_H_
+
+#include <setjmp.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/select.h>
+
+#include <openthread/error.h>
+#include <openthread/instance.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This enumeration represents default parameters for the SPI interface.
+ *
+ */
+enum
+{
+    OT_PLATFORM_CONFIG_SPI_DEFAULT_MODE           = 0,       ///< Default SPI Mode: CPOL=0, CPHA=0.
+    OT_PLATFORM_CONFIG_SPI_DEFAULT_SPEED_HZ       = 1000000, ///< Default SPI speed in hertz.
+    OT_PLATFORM_CONFIG_SPI_DEFAULT_CS_DELAY_US    = 20,      ///< Default delay after SPI C̅S̅ assertion, in µsec.
+    OT_PLATFORM_CONFIG_SPI_DEFAULT_RESET_DELAY_MS = 0, ///< Default delay after R̅E̅S̅E̅T̅ assertion, in miliseconds.
+    OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE =
+        16, ///< Default maximum number of 0xFF bytes to clip from start of MISO frame.
+    OT_PLATFORM_CONFIG_SPI_DEFAULT_SMALL_PACKET_SIZE =
+        32, ///< Default smallest SPI packet size we can receive in a single transaction.
+};
+
+/**
+ * This structure represents platform specific configurations.
+ *
+ */
+typedef struct otPlatformConfig
+{
+    const char *mInterfaceName;  ///< Thread network interface name.
+    const char *mRadioUrl;       ///< Radio url.
+    int         mRealTimeSignal; ///< The real-time signal for microsecond timer.
+    uint32_t    mSpeedUpFactor;  ///< Speed up factor.
+} otPlatformConfig;
+
+/**
+ * This function performs all platform-specific initialization of OpenThread's drivers.
+ *
+ * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
+ *       when initialization of OpenThread's drivers is most appropriate.
+ *
+ * @param[in]  aPlatformConfig  Platform configuration structure.
+ *
+ * @returns A pointer to the OpenThread instance.
+ *
+ */
+otInstance *otSysInit(otPlatformConfig *aPlatformConfig);
+
+/**
+ * This function performs all platform-specific deinitialization for OpenThread's drivers.
+ *
+ * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
+ *       when deinitialization of OpenThread's drivers is most appropriate.
+ *
+ */
+void otSysDeinit(void);
+
+/**
+ * This structure represents a context for a select() based mainloop.
+ *
+ */
+typedef struct otSysMainloopContext
+{
+    fd_set         mReadFdSet;  ///< The read file descriptors.
+    fd_set         mWriteFdSet; ///< The write file descriptors.
+    fd_set         mErrorFdSet; ///< The error file descriptors.
+    int            mMaxFd;      ///< The max file descriptor.
+    struct timeval mTimeout;    ///< The timeout.
+} otSysMainloopContext;
+
+/**
+ * This function updates the file descriptor sets with file descriptors used by OpenThread drivers.
+ *
+ * @param[in]       aInstance   The OpenThread instance structure.
+ * @param[inout]    aMainloop   A pointer to the mainloop context.
+ *
+ */
+void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop);
+
+/**
+ * This function polls OpenThread's mainloop.
+ *
+ * @param[inout]    aMainloop   A pointer to the mainloop context.
+ *
+ * @returns value returned from select().
+ *
+ */
+int otSysMainloopPoll(otSysMainloopContext *aMainloop);
+
+/**
+ * This function performs all platform-specific processing for OpenThread's example applications.
+ *
+ * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
+ *       in the main loop when processing OpenThread's drivers is most appropriate.
+ *
+ * @param[in]   aInstance   The OpenThread instance structure.
+ * @param[in]   aMainloop   A pointer to the mainloop context.
+ *
+ */
+void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop);
+
+/**
+ * This method returns the radio url help string.
+ *
+ * @returns the radio url help string.
+ *
+ */
+const char *otSysGetRadioUrlHelpString(void);
+
+#ifdef __cplusplus
+} // end of extern "C"
+#endif
+
+#endif // OPENTHREAD_SYSTEM_H_
diff --git a/src/posix/platform/logging.c b/src/posix/platform/logging.c
deleted file mode 100644
index 0903bdb..0000000
--- a/src/posix/platform/logging.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <syslog.h>
-
-#include <openthread/platform/logging.h>
-
-#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
-void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
-{
-    OT_UNUSED_VARIABLE(aLogRegion);
-
-    va_list args;
-
-    switch (aLogLevel)
-    {
-    case OT_LOG_LEVEL_NONE:
-        aLogLevel = LOG_ALERT;
-        break;
-    case OT_LOG_LEVEL_CRIT:
-        aLogLevel = LOG_CRIT;
-        break;
-    case OT_LOG_LEVEL_WARN:
-        aLogLevel = LOG_WARNING;
-        break;
-    case OT_LOG_LEVEL_NOTE:
-        aLogLevel = LOG_NOTICE;
-        break;
-    case OT_LOG_LEVEL_INFO:
-        aLogLevel = LOG_INFO;
-        break;
-    case OT_LOG_LEVEL_DEBG:
-        aLogLevel = LOG_DEBUG;
-        break;
-    default:
-        assert(false);
-        aLogLevel = LOG_DEBUG;
-        break;
-    }
-
-    va_start(args, aFormat);
-    vsyslog(aLogLevel, aFormat, args);
-    va_end(args);
-}
-#endif // OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
diff --git a/src/posix/platform/logging.cpp b/src/posix/platform/logging.cpp
new file mode 100644
index 0000000..717156d
--- /dev/null
+++ b/src/posix/platform/logging.cpp
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "openthread-posix-config.h"
+#include "platform-posix.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <syslog.h>
+
+#include <openthread/platform/logging.h>
+
+#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
+void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
+{
+    OT_UNUSED_VARIABLE(aLogRegion);
+
+    va_list args;
+
+    switch (aLogLevel)
+    {
+    case OT_LOG_LEVEL_NONE:
+        aLogLevel = LOG_ALERT;
+        break;
+    case OT_LOG_LEVEL_CRIT:
+        aLogLevel = LOG_CRIT;
+        break;
+    case OT_LOG_LEVEL_WARN:
+        aLogLevel = LOG_WARNING;
+        break;
+    case OT_LOG_LEVEL_NOTE:
+        aLogLevel = LOG_NOTICE;
+        break;
+    case OT_LOG_LEVEL_INFO:
+        aLogLevel = LOG_INFO;
+        break;
+    case OT_LOG_LEVEL_DEBG:
+        aLogLevel = LOG_DEBUG;
+        break;
+    default:
+        assert(false);
+        aLogLevel = LOG_DEBUG;
+        break;
+    }
+
+    va_start(args, aFormat);
+    vsyslog(aLogLevel, aFormat, args);
+    va_end(args);
+}
+#endif // OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
diff --git a/src/posix/platform/max_power_table.hpp b/src/posix/platform/max_power_table.hpp
new file mode 100644
index 0000000..f72cfa5
--- /dev/null
+++ b/src/posix/platform/max_power_table.hpp
@@ -0,0 +1,93 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OT_POSIX_PLATFORM_MAX_POWER_TABLE_HPP_
+#define OT_POSIX_PLATFORM_MAX_POWER_TABLE_HPP_
+
+#include "core/radio/radio.hpp"
+
+namespace ot {
+namespace Posix {
+
+class MaxPowerTable
+{
+public:
+    static const int8_t kPowerDefault = 30; ///< Default power 1 watt (30 dBm).
+
+    MaxPowerTable(void) { memset(mPowerTable, kPowerForbidden, sizeof(mPowerTable)); }
+
+    /**
+     * This method gets the max allowed transmit power of channel @p aChannel.
+     *
+     * @params[in]  aChannel    The radio channel number.
+     *
+     * @returns The max allowed transmit power in dBm.
+     *
+     */
+    int8_t GetTransmitPower(uint8_t aChannel) const { return mPowerTable[aChannel - Radio::kChannelMin]; }
+
+    /**
+     * This method sets the max allowed transmit power of channel @p aChannel.
+     *
+     * @params[in]  aChannel    The radio channel number.
+     * @params[in]  aPower      The max allowed transmit power in dBm.
+     *
+     */
+    void SetTransmitPower(uint8_t aChannel, int8_t aPower) { mPowerTable[aChannel - Radio::kChannelMin] = aPower; }
+
+    /**
+     * This method gets the allowed channel masks.
+     *
+     * All channels of max power value of 0x7f is considered forbidden.
+     *
+     */
+    uint32_t GetAllowedChannelMask(void) const
+    {
+        uint32_t channelMask = 0;
+
+        for (uint8_t i = Radio::kChannelMin; i <= Radio::kChannelMax; ++i)
+        {
+            if (mPowerTable[i - Radio::kChannelMin] != kPowerForbidden)
+            {
+                channelMask |= (1 << i);
+            }
+        }
+
+        return channelMask;
+    }
+
+private:
+    static const int8_t kPowerForbidden = 0x7f;
+
+    int8_t mPowerTable[Radio::kChannelMax - Radio::kChannelMin + 1];
+};
+
+} // namespace Posix
+} // namespace ot
+
+#endif // OT_POSIX_PLATFORM_MAX_POWER_TABLE_HPP_
diff --git a/src/posix/platform/misc.c b/src/posix/platform/misc.c
deleted file mode 100644
index 3c08fa1..0000000
--- a/src/posix/platform/misc.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-
-#include <assert.h>
-#include <fcntl.h>
-#include <setjmp.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include <openthread/platform/misc.h>
-
-#include "code_utils.h"
-#include "common/logging.hpp"
-
-static otPlatResetReason   sPlatResetReason   = OT_PLAT_RESET_REASON_POWER_ON;
-static otPlatMcuPowerState gPlatMcuPowerState = OT_PLAT_MCU_POWER_STATE_ON;
-
-otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    return sPlatResetReason;
-}
-
-void otPlatWakeHost(void)
-{
-    // TODO: implement an operation to wake the host from sleep state.
-}
-
-otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    otError error = OT_ERROR_NONE;
-
-    switch (aState)
-    {
-    case OT_PLAT_MCU_POWER_STATE_ON:
-    case OT_PLAT_MCU_POWER_STATE_LOW_POWER:
-        gPlatMcuPowerState = aState;
-        break;
-
-    default:
-        error = OT_ERROR_FAILED;
-        break;
-    }
-
-    return error;
-}
-
-otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    return gPlatMcuPowerState;
-}
-
-int SocketWithCloseExec(int aDomain, int aType, int aProtocol)
-{
-    int rval = 0;
-    int fd   = -1;
-
-#ifdef __APPLE__
-    otEXPECT_ACTION((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)"));
-
-    otEXPECT_ACTION((rval = fcntl(fd, F_GETFD, 0)) != -1, perror("fcntl(F_GETFD)"));
-    otEXPECT_ACTION((rval = fcntl(fd, F_SETFD, rval | FD_CLOEXEC)) != -1, perror("fcntl(F_SETFD)"));
-#else
-    otEXPECT_ACTION((fd = socket(aDomain, aType | SOCK_CLOEXEC, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)"));
-#endif
-
-exit:
-    if (rval == -1 && fd != -1)
-    {
-        VerifyOrDie(close(fd) == 0, OT_EXIT_ERROR_ERRNO);
-        fd = -1;
-    }
-
-    return fd;
-}
-
-const char *otExitCodeToString(uint8_t aExitCode)
-{
-    const char *retval = NULL;
-
-    switch (aExitCode)
-    {
-    case OT_EXIT_SUCCESS:
-        retval = "Success";
-        break;
-
-    case OT_EXIT_FAILURE:
-        retval = "Failure";
-        break;
-
-    case OT_EXIT_INVALID_ARGUMENTS:
-        retval = "InvalidArgument";
-        break;
-
-    case OT_EXIT_RADIO_SPINEL_INCOMPATIBLE:
-        retval = "RadioSpinelIncompatible";
-        break;
-
-    case OT_EXIT_RADIO_SPINEL_RESET:
-        retval = "RadioSpinelReset";
-        break;
-
-    case OT_EXIT_ERROR_ERRNO:
-        retval = strerror(errno);
-        break;
-
-    default:
-        assert(false);
-        retval = "UnknownExitCode";
-        break;
-    }
-
-    return retval;
-}
diff --git a/src/posix/platform/misc.cpp b/src/posix/platform/misc.cpp
new file mode 100644
index 0000000..0251b7a
--- /dev/null
+++ b/src/posix/platform/misc.cpp
@@ -0,0 +1,110 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "openthread-posix-config.h"
+#include "platform-posix.h"
+
+#include <assert.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <openthread/platform/misc.h>
+
+#include "common/code_utils.hpp"
+#include "common/logging.hpp"
+
+static otPlatResetReason   sPlatResetReason   = OT_PLAT_RESET_REASON_POWER_ON;
+static otPlatMcuPowerState gPlatMcuPowerState = OT_PLAT_MCU_POWER_STATE_ON;
+
+otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return sPlatResetReason;
+}
+
+void otPlatWakeHost(void)
+{
+    // TODO: implement an operation to wake the host from sleep state.
+}
+
+otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NONE;
+
+    switch (aState)
+    {
+    case OT_PLAT_MCU_POWER_STATE_ON:
+    case OT_PLAT_MCU_POWER_STATE_LOW_POWER:
+        gPlatMcuPowerState = aState;
+        break;
+
+    default:
+        error = OT_ERROR_FAILED;
+        break;
+    }
+
+    return error;
+}
+
+otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return gPlatMcuPowerState;
+}
+
+int SocketWithCloseExec(int aDomain, int aType, int aProtocol, SocketBlockOption aBlockOption)
+{
+    int rval = 0;
+    int fd   = -1;
+
+#ifdef __APPLE__
+    VerifyOrExit((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)"));
+
+    VerifyOrExit((rval = fcntl(fd, F_GETFD, 0)) != -1, perror("fcntl(F_GETFD)"));
+    rval |= aBlockOption == kSocketNonBlock ? O_NONBLOCK | FD_CLOEXEC : FD_CLOEXEC;
+    VerifyOrExit((rval = fcntl(fd, F_SETFD, rval)) != -1, perror("fcntl(F_SETFD)"));
+#else
+    aType |= aBlockOption == kSocketNonBlock ? SOCK_CLOEXEC | SOCK_NONBLOCK : SOCK_CLOEXEC;
+    VerifyOrExit((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)"));
+#endif
+
+exit:
+    if (rval == -1)
+    {
+        VerifyOrDie(close(fd) == 0, OT_EXIT_ERROR_ERRNO);
+        fd = -1;
+    }
+
+    return fd;
+}
diff --git a/src/posix/platform/netif.cpp b/src/posix/platform/netif.cpp
index c86a3fd..b394212 100644
--- a/src/posix/platform/netif.cpp
+++ b/src/posix/platform/netif.cpp
@@ -30,21 +30,56 @@
  * @file
  *   This file implements the platform network on Linux.
  */
-#include "openthread-core-config.h"
+
+#include "openthread-posix-config.h"
 #include "platform-posix.h"
 
+#if defined(__APPLE__)
+
+//	NOTE: on mac OS, the utun driver is present on the system and "works" --
+//	but in a limited way.  In particular, the mac OS "utun" driver is marked IFF_POINTTOPOINT,
+//	and you cannot clear that flag with SIOCSIFFLAGS (it's part of the IFF_CANTCHANGE definition
+//	in xnu's net/if.h [but removed from the mac OS SDK net/if.h]).  And unfortuntately, mac OS's
+//	build of mDNSResponder won't allow for mDNS over an interface marked IFF_POINTTOPOINT
+//	(see comments near definition of MulticastInterface in mDNSMacOSX.c for the bogus reasoning).
+//
+//	There is an alternative.  An open-source tuntap kernel extension is available here:
+//
+//		<http://tuntaposx.sourceforge.net>
+//		<https://sourceforge.net/p/tuntaposx/code/ci/master/tree/>
+//
+//	and can be installed via homebrew here:
+//
+//		<https://formulae.brew.sh/cask/tuntap>
+//
+//	Building from source and installing isn't trivial, and it's
+//	not getting easier (https://forums.developer.apple.com/thread/79590).
+//
+//	If you want mDNS support, then you can't use Apple utun.  I use the non-Apple driver
+//	pretty much exclusively, because mDNS is a requirement.
+
+#if !(defined(OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION) &&                         \
+      ((OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_UTUN) || \
+       (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_TUN)))
+#error "Unexpected tunnel driver selection"
+#endif
+
+#endif // defined(__APPLE__)
+
 #include <arpa/inet.h>
 #include <assert.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <ifaddrs.h>
-#if __linux__
+#ifdef __linux__
 #include <linux/if_tun.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
-#endif
+#endif // __linux__
 #include <net/if.h>
 #include <net/if_arp.h>
 #include <stdio.h>
+#include <string.h>
 #include <sys/ioctl.h>
 #include <sys/select.h>
 #include <sys/socket.h>
@@ -52,10 +87,61 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#if defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+#include <netinet/in.h>
+#if defined(__APPLE__) || defined(__FreeBSD__)
+#include <net/if_var.h>
+#endif // defined(__APPLE__) || defined(__FreeBSD__)
+#include <net/route.h>
+#include <netinet6/in6_var.h>
+#if defined(__APPLE__) || defined(__FreeBSD__)
+// the prf_ra structure is defined inside another structure (in6_prflags), and C++
+//   treats that as out of scope if another structure tries to use it -- this (slightly gross)
+//   workaround makes us dependent on our definition remaining in sync (at least the size of it),
+//   so we add a compile-time check that will fail if the SDK ever changes
+//
+// our definition of the struct:
+struct prf_ra
+{
+    u_char onlink : 1;
+    u_char autonomous : 1;
+    u_char reserved : 6;
+} prf_ra;
+// object that contains the SDK's version of the structure:
+struct in6_prflags compile_time_check_prflags;
+// compile time check to make sure they're the same size:
+extern int
+    compile_time_check_struct_prf_ra[(sizeof(struct prf_ra) == sizeof(compile_time_check_prflags.prf_ra)) ? 1 : -1];
+#endif
+#include <net/if_dl.h>    // struct sockaddr_dl
+#include <netinet6/nd6.h> // ND6_INFINITE_LIFETIME
+
+#ifdef __APPLE__
+#if OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_UTUN
+#include <net/if_utun.h>
+#endif
+
+#if OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_TUN
+#include <sys/ioccom.h>
+// FIX ME: include the tun_ioctl.h file (challenging, as it's location depends on where the developer puts it)
+#define TUNSIFHEAD _IOW('t', 96, int)
+#define TUNGIFHEAD _IOR('t', 97, int)
+#endif
+
+#include <sys/kern_control.h>
+#endif // defined(__APPLE__)
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+#include <net/if_tun.h>
+#endif // defined(__NetBSD__) || defined(__FreeBSD__)
+
+#endif // defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+
 #include <openthread/icmp6.h>
 #include <openthread/instance.h>
 #include <openthread/ip6.h>
 #include <openthread/message.h>
+#include <openthread/platform/misc.h>
 
 #include "common/code_utils.hpp"
 #include "common/logging.hpp"
@@ -64,9 +150,26 @@
 #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
 
 #ifndef OPENTHREAD_POSIX_TUN_DEVICE
+
+#ifdef __linux__
 #define OPENTHREAD_POSIX_TUN_DEVICE "/dev/net/tun"
+#elif defined(__NetBSD__) || defined(__FreeBSD__)
+#define OPENTHREAD_POSIX_TUN_DEVICE "/dev/tun0"
+#elif defined(__APPLE__)
+#if OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_UTUN
+#define OPENTHREAD_POSIX_TUN_DEVICE // not used - calculated dynamically
+#elif OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_TUN
+#define OPENTHREAD_POSIX_TUN_DEVICE "/dev/tun0"
+#endif
+#else
+// good luck -- untested platform...
+#define OPENTHREAD_POSIX_TUN_DEVICE "/dev/net/tun"
+#endif
+
 #endif // OPENTHREAD_TUN_DEVICE
 
+// Some platforms will include linux/ipv6.h in netinet/in.h
+#if defined(__linux__) && !defined(_IPV6_H) && !defined(_UAPI_IPV6_H)
 // from linux/ipv6.h
 struct in6_ifreq
 {
@@ -74,38 +177,181 @@
     __u32           ifr6_prefixlen;
     int             ifr6_ifindex;
 };
+#endif // defined(__linux__) && !defined(_IPV6_H) && !defined(_UAPI_IPV6_H)
 
-static otInstance * sInstance  = NULL;
-static int          sTunFd     = -1; ///< Used to exchange IPv6 packets.
-static int          sIpFd      = -1; ///< Used to manage IPv6 stack on Thread interface.
-static int          sNetlinkFd = -1; ///< Used to receive netlink events.
-static unsigned int sTunIndex  = 0;
+#if defined(RTM_NEWMADDR) || defined(__NetBSD__)
+// on some BSDs (mac OS, FreeBSD), we get RTM_NEWMADDR/RTM_DELMADDR messages, so we don't need to monitor using MLD
+// on NetBSD, MLD monitoring simply doesn't work
+#define OPENTHREAD_POSIX_USE_MLD_MONITOR 0
+#else
+// on some platforms (Linux, but others might be made to work), we do not get information about multicast
+// group joining via AF_NETLINK or AF_ROUTE sockets.  on those platform, we must listen for IPv6 ICMP
+// MLDv2 messages to know when mulicast memberships change
+// 		https://stackoverflow.com/questions/37346289/using-netlink-is-it-possible-to-listen-whenever-multicast-group-membership-is-ch
+#define OPENTHREAD_POSIX_USE_MLD_MONITOR 1
+#endif // defined(RTM_NEWMADDR) || defined(__NetBSD__)
+
+// some platforms (like NetBSD) do not have RTM_NEWMADDR/RTM_DELMADDR messages, and they ALSO lack
+// working MLDv2 support.  for those platforms, we must tell the OpenThread interface to
+// pass ALL multicast packets up; the kernel's IPv6 will filter and drop those that have no listeners
+#define OPENTHREAD_POSIX_MULTICAST_PROMISCUOUS_REQUIRED 0
+#if !OPENTHREAD_POSIX_USE_MLD_MONITOR
+#if defined(__NetBSD__)
+#undef OPENTHREAD_POSIX_MULTICAST_PROMISCUOUS_REQUIRED
+#define OPENTHREAD_POSIX_MULTICAST_PROMISCUOUS_REQUIRED 1
+#endif
+#endif
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+static otError destroyTunnel(void);
+#endif
+
+static otInstance *sInstance  = nullptr;
+static int         sTunFd     = -1; ///< Used to exchange IPv6 packets.
+static int         sIpFd      = -1; ///< Used to manage IPv6 stack on Thread interface.
+static int         sNetlinkFd = -1; ///< Used to receive netlink events.
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+static int sMLDMonitorFd = -1; ///< Used to receive MLD events.
+#endif
+static unsigned int sTunIndex = 0;
 static char         sTunName[IFNAMSIZ];
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+// ff02::16
+static const otIp6Address kMLDv2MulticastAddress = {
+    {{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16}}};
+
+OT_TOOL_PACKED_BEGIN
+struct MLDv2Header
+{
+    uint8_t  mType;
+    uint8_t  _rsv0;
+    uint16_t mChecksum;
+    uint16_t _rsv1;
+    uint16_t mNumRecords;
+} OT_TOOL_PACKED_END;
+
+OT_TOOL_PACKED_BEGIN
+struct MLDv2Record
+{
+    uint8_t         mRecordType;
+    uint8_t         mAuxDataLen;
+    uint16_t        mNumSources;
+    struct in6_addr mMulticastAddress;
+} OT_TOOL_PACKED_END;
+
+enum
+{
+    kICMPv6MLDv2Type                      = 143,
+    kICMPv6MLDv2RecordChangeToExcludeType = 3,
+    kICMPv6MLDv2RecordChangeToIncludeType = 4,
+};
+#endif
 
 static const size_t kMaxIp6Size = 1536;
 
+#define OPENTHREAD_POSIX_LOG_TUN_PACKETS 0
+
+#if !defined(__linux__)
+static bool UnicastAddressIsSubscribed(otInstance *aInstance, const otNetifAddress *netAddr)
+{
+    const otNetifAddress *address = otIp6GetUnicastAddresses(aInstance);
+
+    while (address != nullptr)
+    {
+        if (memcmp(address->mAddress.mFields.m8, netAddr->mAddress.mFields.m8, sizeof(address->mAddress.mFields.m8)) ==
+            0)
+        {
+            return true;
+        }
+
+        address = address->mNext;
+    }
+
+    return false;
+}
+#endif
+
+#if defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+static const uint8_t allOnes[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                                  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+static void InitNetaskWithPrefixLength(struct in6_addr *address, uint8_t prefixLen)
+{
+#define MAX_PREFIX_LENGTH (OT_IP6_ADDRESS_SIZE * CHAR_BIT)
+    if (prefixLen > MAX_PREFIX_LENGTH)
+    {
+        prefixLen = MAX_PREFIX_LENGTH;
+    }
+
+    ot::Ip6::Address addr;
+
+    addr.Clear();
+    addr.SetPrefix(allOnes, prefixLen);
+    memcpy(address, addr.mFields.m8, sizeof(addr.mFields.m8));
+}
+
+static uint8_t NetmaskToPrefixLength(const struct sockaddr_in6 *netmask)
+{
+    return ot::Ip6::Address::PrefixMatch(netmask->sin6_addr.s6_addr, allOnes, 128);
+}
+#endif
+
 static void UpdateUnicast(otInstance *aInstance, const otIp6Address &aAddress, uint8_t aPrefixLength, bool aIsAdded)
 {
-    struct in6_ifreq ifr6;
-    otError          error = OT_ERROR_NONE;
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NONE;
 
     assert(sInstance == aInstance);
 
-    VerifyOrExit(sIpFd > 0, error = OT_ERROR_INVALID_STATE);
+    VerifyOrExit(sIpFd >= 0, error = OT_ERROR_INVALID_STATE);
 
-    memcpy(&ifr6.ifr6_addr, &aAddress, sizeof(ifr6.ifr6_addr));
-
-    ifr6.ifr6_ifindex   = static_cast<int>(sTunIndex);
-    ifr6.ifr6_prefixlen = aPrefixLength;
-
-    if (aIsAdded)
+#if defined(__linux__)
     {
-        VerifyOrDie(ioctl(sIpFd, SIOCSIFADDR, &ifr6) == 0, OT_EXIT_ERROR_ERRNO);
+        struct in6_ifreq ifr6;
+        memcpy(&ifr6.ifr6_addr, &aAddress, sizeof(ifr6.ifr6_addr));
+
+        ifr6.ifr6_ifindex   = static_cast<int>(sTunIndex);
+        ifr6.ifr6_prefixlen = aPrefixLength;
+
+        if (aIsAdded)
+        {
+            VerifyOrDie(ioctl(sIpFd, SIOCSIFADDR, &ifr6) == 0, OT_EXIT_ERROR_ERRNO);
+        }
+        else
+        {
+            VerifyOrExit(ioctl(sIpFd, SIOCDIFADDR, &ifr6) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
+        }
     }
-    else
+#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
     {
-        VerifyOrExit(ioctl(sIpFd, SIOCDIFADDR, &ifr6) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
+        int                 err;
+        struct in6_aliasreq ifr6;
+
+        memset(&ifr6, 0, sizeof(ifr6));
+        strlcpy(ifr6.ifra_name, sTunName, sizeof(ifr6.ifra_name));
+        ifr6.ifra_addr.sin6_family = AF_INET6;
+        ifr6.ifra_addr.sin6_len    = sizeof(ifr6.ifra_addr);
+        memcpy(&ifr6.ifra_addr.sin6_addr, &aAddress, sizeof(struct in6_addr));
+        ifr6.ifra_prefixmask.sin6_family = AF_INET6;
+        ifr6.ifra_prefixmask.sin6_len    = sizeof(ifr6.ifra_prefixmask);
+        InitNetaskWithPrefixLength(&ifr6.ifra_prefixmask.sin6_addr, aPrefixLength);
+        ifr6.ifra_lifetime.ia6t_vltime    = ND6_INFINITE_LIFETIME;
+        ifr6.ifra_lifetime.ia6t_pltime    = ND6_INFINITE_LIFETIME;
+
+#if defined(__APPLE__)
+        ifr6.ifra_lifetime.ia6t_expire    = ND6_INFINITE_LIFETIME;
+        ifr6.ifra_lifetime.ia6t_preferred = ND6_INFINITE_LIFETIME;
+#endif
+
+        err = ioctl(sIpFd, aIsAdded ? SIOCAIFADDR_IN6 : SIOCDIFADDR_IN6, &ifr6);
+        if ((err == -1) && (errno == EALREADY))
+        {
+            err = 0;
+        }
+        VerifyOrExit(err == 0, perror("ioctl"); error = OT_ERROR_FAILED);
     }
+#endif
 
 exit:
     if (error != OT_ERROR_NONE)
@@ -120,19 +366,41 @@
 
 static void UpdateMulticast(otInstance *aInstance, const otIp6Address &aAddress, bool aIsAdded)
 {
+    OT_UNUSED_VARIABLE(aInstance);
+
     struct ipv6_mreq mreq;
     otError          error = OT_ERROR_NONE;
 
     assert(sInstance == aInstance);
 
-    VerifyOrExit(sIpFd > 0);
+    VerifyOrExit(sIpFd >= 0, OT_NOOP);
     memcpy(&mreq.ipv6mr_multiaddr, &aAddress, sizeof(mreq.ipv6mr_multiaddr));
     mreq.ipv6mr_interface = sTunIndex;
 
-    VerifyOrExit(
-        setsockopt(sIpFd, IPPROTO_IPV6, (aIsAdded ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP), &mreq, sizeof(mreq)) == 0,
-        perror("setsockopt");
-        error = OT_ERROR_FAILED);
+    int err;
+    err = setsockopt(sIpFd, IPPROTO_IPV6, (aIsAdded ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP), &mreq, sizeof(mreq));
+#if defined(__APPLE__) || defined(__FreeBSD__)
+    if ((err != 0) && (errno == EINVAL) && (IN6_IS_ADDR_MC_LINKLOCAL(&mreq.ipv6mr_multiaddr)))
+    {
+        // FIX ME
+        // on mac OS (and FreeBSD), the first time we run (but not subsequently), we get a failure on this particular
+        // join. do we need to bring up the interface at least once prior to joining?
+        // we need to figure out why so we can get rid of this workaround
+        char addressString[INET6_ADDRSTRLEN + 1];
+
+        inet_ntop(AF_INET6, mreq.ipv6mr_multiaddr.s6_addr, addressString, sizeof(addressString));
+        otLogWarnPlat("ignoring %s failure (EINVAL) for MC LINKLOCAL address (%s)",
+                      aIsAdded ? "IPV6_JOIN_GROUP" : "IPV6_LEAVE_GROUP", addressString);
+        err = 0;
+    }
+#endif
+
+    if (err != 0)
+    {
+        otLogWarnPlat("%s failure (%d)", aIsAdded ? "IPV6_JOIN_GROUP" : "IPV6_LEAVE_GROUP", errno);
+    }
+
+    VerifyOrExit(err == 0, perror("setsockopt"); error = OT_ERROR_FAILED);
 
 exit:
     SuccessOrDie(error);
@@ -143,24 +411,26 @@
 {
     otError      error = OT_ERROR_NONE;
     struct ifreq ifr;
+    bool         ifState = false;
+    bool         otState = false;
 
     assert(sInstance == aInstance);
 
-    VerifyOrExit(sIpFd > 0);
+    VerifyOrExit(sIpFd >= 0, OT_NOOP);
     memset(&ifr, 0, sizeof(ifr));
     strncpy(ifr.ifr_name, sTunName, sizeof(ifr.ifr_name));
     VerifyOrExit(ioctl(sIpFd, SIOCGIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
 
-    if (otIp6IsEnabled(aInstance))
-    {
-        ifr.ifr_flags |= IFF_UP;
-    }
-    else
-    {
-        ifr.ifr_flags &= ~IFF_UP;
-    }
+    ifState = ((ifr.ifr_flags & IFF_UP) == IFF_UP) ? true : false;
+    otState = otIp6IsEnabled(aInstance);
 
-    VerifyOrExit(ioctl(sIpFd, SIOCSIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
+    otLogNotePlat("changing interface state to %s%s.", otState ? "UP" : "DOWN",
+                  (ifState == otState) ? " (already done, ignoring)" : "");
+    if (ifState != otState)
+    {
+        ifr.ifr_flags = otState ? (ifr.ifr_flags | IFF_UP) : (ifr.ifr_flags & ~IFF_UP);
+        VerifyOrExit(ioctl(sIpFd, SIOCSIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
+    }
 
 exit:
     if (error == OT_ERROR_NONE)
@@ -187,7 +457,7 @@
 
 static void processStateChange(otChangedFlags aFlags, void *aContext)
 {
-    if (OT_CHANGED_THREAD_NETIF_STATE | aFlags)
+    if (OT_CHANGED_THREAD_NETIF_STATE & aFlags)
     {
         UpdateLink(static_cast<otInstance *>(aContext));
     }
@@ -195,15 +465,36 @@
 
 static void processReceive(otMessage *aMessage, void *aContext)
 {
-    char     packet[kMaxIp6Size];
-    otError  error  = OT_ERROR_NONE;
-    uint16_t length = otMessageGetLength(aMessage);
+    OT_UNUSED_VARIABLE(aContext);
+
+    char     packet[kMaxIp6Size + 4];
+    otError  error     = OT_ERROR_NONE;
+    uint16_t length    = otMessageGetLength(aMessage);
+    size_t   offset    = 0;
+    uint16_t maxLength = sizeof(packet) - 4;
+#if defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+    // BSD tunnel drivers use (for legacy reasons) a 4-byte header to determine the address family of the packet
+    offset += 4;
+#endif
 
     assert(sInstance == aContext);
 
-    VerifyOrExit(sTunFd > 0);
+    VerifyOrExit(sTunFd > 0, OT_NOOP);
 
-    VerifyOrExit(otMessageRead(aMessage, 0, packet, sizeof(packet)) == length, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(otMessageRead(aMessage, 0, &packet[offset], maxLength) == length, error = OT_ERROR_NO_BUFS);
+
+#if OPENTHREAD_POSIX_LOG_TUN_PACKETS
+    otLogInfoPlat("Packet from NCP (%hu bytes)", static_cast<uint16_t>(length));
+    otDumpInfo(OT_LOG_REGION_PLATFORM, "", &packet[offset], length);
+#endif
+
+#if defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+    packet[0] = 0;
+    packet[1] = 0;
+    packet[2] = (PF_INET6 << 8) & 0xFF;
+    packet[3] = (PF_INET6 << 0) & 0xFF;
+    length += 4;
+#endif
 
     VerifyOrExit(write(sTunFd, packet, length) == length, perror("write"); error = OT_ERROR_FAILED);
 
@@ -222,26 +513,41 @@
 
 static void processTransmit(otInstance *aInstance)
 {
-    otMessage *message = NULL;
+    otMessage *message = nullptr;
     ssize_t    rval;
     char       packet[kMaxIp6Size];
-    otError    error = OT_ERROR_NONE;
+    otError    error  = OT_ERROR_NONE;
+    size_t     offset = 0;
 
     assert(sInstance == aInstance);
 
     rval = read(sTunFd, packet, sizeof(packet));
     VerifyOrExit(rval > 0, error = OT_ERROR_FAILED);
 
-    message = otIp6NewMessage(aInstance, NULL);
-    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+    message = otIp6NewMessage(aInstance, nullptr);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
-    SuccessOrExit(error = otMessageAppend(message, packet, static_cast<uint16_t>(rval)));
+#if defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+    // BSD tunnel drivers have (for legacy reasons), may have a 4-byte header on them
+    if ((rval >= 4) && (packet[0] == 0) && (packet[1] == 0))
+    {
+        rval -= 4;
+        offset = 4;
+    }
+#endif
+
+#if OPENTHREAD_POSIX_LOG_TUN_PACKETS
+    otLogInfoPlat("Packet to NCP (%hu bytes)", static_cast<uint16_t>(rval));
+    otDumpInfo(OT_LOG_REGION_PLATFORM, "", &packet[offset], static_cast<size_t>(rval));
+#endif
+
+    SuccessOrExit(error = otMessageAppend(message, &packet[offset], static_cast<uint16_t>(rval)));
 
     error   = otIp6Send(aInstance, message);
-    message = NULL;
+    message = nullptr;
 
 exit:
-    if (message != NULL)
+    if (message != nullptr)
     {
         otMessageFree(message);
     }
@@ -256,13 +562,45 @@
     }
 }
 
+#define kAddAddress true
+#define kRemoveAddress false
+#define kUnicastAddress true
+#define kMulticastAddress false
+static void logAddrEvent(bool isAdd, bool isUnicast, struct sockaddr_in6 &addr6, otError error)
+{
+    char addressString[INET6_ADDRSTRLEN + 1];
+
+    // these parameters may not be used if logging is disabled at compile time
+    OT_UNUSED_VARIABLE(isUnicast);
+    OT_UNUSED_VARIABLE(addr6);
+    OT_UNUSED_VARIABLE(addressString);
+
+    if ((error == OT_ERROR_NONE) || ((isAdd) && (error == OT_ERROR_ALREADY)) ||
+        ((!isAdd) && (error == OT_ERROR_NOT_FOUND)))
+    {
+        otLogNotePlat("%s [%s] %s%s", isAdd ? "ADD" : "DEL", isUnicast ? "U" : "M",
+                      inet_ntop(AF_INET6, addr6.sin6_addr.s6_addr, addressString, sizeof(addressString)),
+                      error == OT_ERROR_ALREADY ? " (already subscribed, ignored)"
+                                                : error == OT_ERROR_NOT_FOUND ? " (not found, ignored)" : "");
+    }
+    else
+    {
+        otLogWarnPlat("%s [%s] %s failed (%s)", isAdd ? "ADD" : "DEL", isUnicast ? "U" : "M",
+                      inet_ntop(AF_INET6, addr6.sin6_addr.s6_addr, addressString, sizeof(addressString)),
+                      otThreadErrorToString(error));
+    }
+}
+
+#if defined(__linux__)
+
 static void processNetifAddrEvent(otInstance *aInstance, struct nlmsghdr *aNetlinkMessage)
 {
-    struct ifaddrmsg *ifaddr = reinterpret_cast<struct ifaddrmsg *>(NLMSG_DATA(aNetlinkMessage));
-    size_t            rtaLength;
-    otError           error = OT_ERROR_NONE;
+    struct ifaddrmsg *  ifaddr = reinterpret_cast<struct ifaddrmsg *>(NLMSG_DATA(aNetlinkMessage));
+    size_t              rtaLength;
+    otError             error = OT_ERROR_NONE;
+    struct sockaddr_in6 addr6;
 
-    VerifyOrExit(ifaddr->ifa_index == static_cast<unsigned int>(sTunIndex) && ifaddr->ifa_family == AF_INET6);
+    VerifyOrExit(ifaddr->ifa_index == static_cast<unsigned int>(sTunIndex) && ifaddr->ifa_family == AF_INET6, OT_NOOP);
 
     rtaLength = IFA_PAYLOAD(aNetlinkMessage);
 
@@ -275,10 +613,15 @@
         case IFA_LOCAL:
         case IFA_BROADCAST:
         case IFA_ANYCAST:
+        case IFA_MULTICAST:
         {
             ot::Ip6::Address addr;
             memcpy(&addr, RTA_DATA(rta), sizeof(addr));
 
+            memset(&addr6, 0, sizeof(addr6));
+            addr6.sin6_family = AF_INET6;
+            memcpy(&addr6.sin6_addr, RTA_DATA(rta), sizeof(addr6.sin6_addr));
+
             if (aNetlinkMessage->nlmsg_type == RTM_NEWADDR)
             {
                 if (!addr.IsMulticast())
@@ -287,23 +630,44 @@
 
                     netAddr.mAddress      = addr;
                     netAddr.mPrefixLength = ifaddr->ifa_prefixlen;
-                    SuccessOrExit(error = otIp6AddUnicastAddress(aInstance, &netAddr));
+
+                    error = otIp6AddUnicastAddress(aInstance, &netAddr);
                 }
                 else
                 {
-                    SuccessOrExit(error = otIp6SubscribeMulticastAddress(aInstance, &addr));
+                    otNetifMulticastAddress netAddr;
+
+                    netAddr.mAddress = addr;
+
+                    error = otIp6SubscribeMulticastAddress(aInstance, &addr);
                 }
+
+                logAddrEvent(kAddAddress, !addr.IsMulticast(), addr6, error);
+                if (error == OT_ERROR_ALREADY)
+                {
+                    error = OT_ERROR_NONE;
+                }
+
+                SuccessOrExit(error);
             }
             else if (aNetlinkMessage->nlmsg_type == RTM_DELADDR)
             {
                 if (!addr.IsMulticast())
                 {
-                    otIp6RemoveUnicastAddress(aInstance, &addr);
+                    error = otIp6RemoveUnicastAddress(aInstance, &addr);
                 }
                 else
                 {
-                    otIp6UnsubscribeMulticastAddress(aInstance, &addr);
+                    error = otIp6UnsubscribeMulticastAddress(aInstance, &addr);
                 }
+
+                logAddrEvent(kRemoveAddress, !addr.IsMulticast(), addr6, error);
+                if (error == OT_ERROR_NOT_FOUND)
+                {
+                    error = OT_ERROR_NONE;
+                }
+
+                SuccessOrExit(error);
             }
             else
             {
@@ -311,7 +675,9 @@
             }
             break;
         }
+
         default:
+            otLogWarnPlat("unexpected address type (%d).", (int)rta->rta_type);
             break;
         }
     }
@@ -332,7 +698,7 @@
     struct ifinfomsg *ifinfo = reinterpret_cast<struct ifinfomsg *>(NLMSG_DATA(aNetlinkMessage));
     otError           error  = OT_ERROR_NONE;
 
-    VerifyOrExit(ifinfo->ifi_index == static_cast<int>(sTunIndex));
+    VerifyOrExit(ifinfo->ifi_index == static_cast<int>(sTunIndex), OT_NOOP);
     SuccessOrExit(error = otIp6SetEnabled(aInstance, ifinfo->ifi_flags & IFF_UP));
 
 exit:
@@ -345,6 +711,250 @@
         otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
     }
 }
+#endif
+
+#if defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+
+#if defined(__FreeBSD__)
+#define ROUNDUP(a) ((a) > 0 ? (1 + (((a)-1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
+#endif
+
+#if defined(__APPLE__)
+#define ROUNDUP(a) ((a) > 0 ? (1 + (((a)-1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
+#define DARWIN_SA_SIZE(sa) ROUNDUP(sa->sa_len)
+#define SA_SIZE(sa) DARWIN_SA_SIZE(sa)
+#endif
+
+#if defined(__NetBSD__)
+#define RT_ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a)-1U) | ((n)-1))) : (n))
+#define RT_ROUNDUP(a) RT_ROUNDUP2((a), sizeof(uint64_t))
+#define SA_SIZE(sa) RT_ROUNDUP(sa->sa_len)
+#endif
+
+static void processNetifAddrEvent(otInstance *aInstance, struct rt_msghdr *rtm)
+{
+    otError            error;
+    struct ifa_msghdr *ifam;
+#ifdef RTM_NEWMADDR
+    struct ifma_msghdr *ifmam;
+#endif
+    struct sockaddr_in6 addr6;
+    struct sockaddr_in6 netmask;
+    uint8_t *           addrbuf;
+    unsigned int        addrlen;
+    unsigned int        addrmask = 0;
+    unsigned int        i;
+    struct sockaddr *   sa;
+    bool                is_link_local;
+    size_t              buffer_len = rtm->rtm_msglen;
+
+    addr6.sin6_family   = 0;
+    netmask.sin6_family = 0;
+
+    if ((rtm->rtm_type == RTM_NEWADDR) || (rtm->rtm_type == RTM_DELADDR))
+    {
+        ifam = reinterpret_cast<struct ifa_msghdr *>(rtm);
+
+        VerifyOrExit(ifam->ifam_index == static_cast<unsigned int>(sTunIndex), OT_NOOP);
+
+        addrbuf  = (uint8_t *)&ifam[1];
+        addrmask = (unsigned int)ifam->ifam_addrs;
+    }
+#ifdef RTM_NEWMADDR
+    else if ((rtm->rtm_type == RTM_NEWMADDR) || (rtm->rtm_type == RTM_DELMADDR))
+    {
+        ifmam = reinterpret_cast<struct ifma_msghdr *>(rtm);
+
+        VerifyOrExit(ifmam->ifmam_index == static_cast<unsigned int>(sTunIndex), OT_NOOP);
+
+        addrbuf  = (uint8_t *)&ifmam[1];
+        addrmask = (unsigned int)ifmam->ifmam_addrs;
+    }
+#endif
+    addrlen = (unsigned int)buffer_len;
+
+    if (addrmask != 0)
+    {
+        for (i = 0; i < RTAX_MAX; i++)
+        {
+            unsigned int mask = (addrmask & (1 << i));
+            if (mask)
+            {
+                sa = (struct sockaddr *)addrbuf;
+
+                if (sa->sa_family == AF_INET6)
+                {
+                    if (i == RTAX_IFA)
+                        memcpy(&addr6, sa, sizeof(sockaddr_in6));
+                    if (i == RTAX_NETMASK)
+                        memcpy(&netmask, sa, sizeof(sockaddr_in6));
+                }
+                addrlen -= SA_SIZE(sa);
+                addrbuf += SA_SIZE(sa);
+            }
+        }
+    }
+
+    if (addr6.sin6_family == AF_INET6)
+    {
+        is_link_local = false;
+        if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr))
+        {
+            is_link_local = true;
+            // clear the scope -- Mac OS X sends this to us (bozos!)
+            addr6.sin6_addr.s6_addr[3] = 0;
+        }
+        else if (IN6_IS_ADDR_MC_LINKLOCAL(&addr6.sin6_addr))
+        {
+            addr6.sin6_addr.s6_addr[3] = 0;
+        }
+
+        ot::Ip6::Address addr;
+        memcpy(&addr, &addr6.sin6_addr, sizeof(addr));
+
+        if (rtm->rtm_type == RTM_NEWADDR
+#ifdef RTM_NEWMADDR
+            || rtm->rtm_type == RTM_NEWMADDR
+#endif
+        )
+        {
+            if (!addr.IsMulticast())
+            {
+                otNetifAddress netAddr;
+                bool           subscribed;
+
+                netAddr.mAddress      = addr;
+                netAddr.mPrefixLength = NetmaskToPrefixLength(&netmask);
+
+                subscribed = UnicastAddressIsSubscribed(aInstance, &netAddr);
+
+                if (subscribed)
+                {
+                    logAddrEvent(kAddAddress, kUnicastAddress, addr6, OT_ERROR_ALREADY);
+                    error = OT_ERROR_NONE;
+                }
+                else
+                {
+                    if (is_link_local)
+                    {
+                        // remove the stack-added link-local address
+
+                        int                 err;
+                        struct in6_aliasreq ifr6;
+                        char                addressString[INET6_ADDRSTRLEN + 1];
+
+                        OT_UNUSED_VARIABLE(addressString); // if otLog*Plat is disabled, we'll get a warning
+
+                        memset(&ifr6, 0, sizeof(ifr6));
+                        strlcpy(ifr6.ifra_name, sTunName, sizeof(ifr6.ifra_name));
+                        ifr6.ifra_addr.sin6_family = AF_INET6;
+                        ifr6.ifra_addr.sin6_len    = sizeof(ifr6.ifra_addr);
+                        memcpy(&ifr6.ifra_addr.sin6_addr, &addr6.sin6_addr, sizeof(struct in6_addr));
+                        ifr6.ifra_prefixmask.sin6_family = AF_INET6;
+                        ifr6.ifra_prefixmask.sin6_len    = sizeof(ifr6.ifra_prefixmask);
+                        InitNetaskWithPrefixLength(&ifr6.ifra_prefixmask.sin6_addr, netAddr.mPrefixLength);
+                        ifr6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
+                        ifr6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
+
+#if defined(__APPLE__)
+                        ifr6.ifra_lifetime.ia6t_expire    = ND6_INFINITE_LIFETIME;
+                        ifr6.ifra_lifetime.ia6t_preferred = ND6_INFINITE_LIFETIME;
+#endif
+
+                        err = ioctl(sIpFd, SIOCDIFADDR_IN6, &ifr6);
+                        if (err != 0)
+                        {
+                            otLogWarnPlat(
+                                "error (%d) removing stack-addded link-local address %s", errno,
+                                inet_ntop(AF_INET6, addr6.sin6_addr.s6_addr, addressString, sizeof(addressString)));
+                            error = OT_ERROR_FAILED;
+                        }
+                        else
+                        {
+                            otLogNotePlat(
+                                "        %s (removed stack-added link-local)",
+                                inet_ntop(AF_INET6, addr6.sin6_addr.s6_addr, addressString, sizeof(addressString)));
+                            error = OT_ERROR_NONE;
+                        }
+                    }
+                    else
+                    {
+                        error = otIp6AddUnicastAddress(aInstance, &netAddr);
+                        logAddrEvent(kAddAddress, kUnicastAddress, addr6, error);
+                        if (error == OT_ERROR_ALREADY)
+                        {
+                            error = OT_ERROR_NONE;
+                        }
+                    }
+                }
+                SuccessOrExit(error);
+            }
+            else
+            {
+                otNetifMulticastAddress netAddr;
+                netAddr.mAddress = addr;
+
+                error = otIp6SubscribeMulticastAddress(aInstance, &addr);
+                logAddrEvent(kAddAddress, kMulticastAddress, addr6, error);
+                if (error == OT_ERROR_ALREADY)
+                {
+                    error = OT_ERROR_NONE;
+                }
+                SuccessOrExit(error);
+            }
+        }
+        else if (rtm->rtm_type == RTM_DELADDR
+#ifdef RTM_DELMADDR
+                 || rtm->rtm_type == RTM_DELMADDR
+#endif
+        )
+        {
+            if (!addr.IsMulticast())
+            {
+                error = otIp6RemoveUnicastAddress(aInstance, &addr);
+                logAddrEvent(kRemoveAddress, kUnicastAddress, addr6, error);
+                if (error == OT_ERROR_NOT_FOUND)
+                {
+                    error = OT_ERROR_NONE;
+                }
+            }
+            else
+            {
+                error = otIp6UnsubscribeMulticastAddress(aInstance, &addr);
+                logAddrEvent(kRemoveAddress, kMulticastAddress, addr6, error);
+                if (error == OT_ERROR_NOT_FOUND)
+                {
+                    error = OT_ERROR_NONE;
+                }
+            }
+            SuccessOrExit(error);
+        }
+    }
+
+exit:;
+}
+
+static void processNetifInfoEvent(otInstance *aInstance, struct rt_msghdr *rtm)
+{
+    struct if_msghdr *ifm   = reinterpret_cast<struct if_msghdr *>(rtm);
+    otError           error = OT_ERROR_NONE;
+
+    VerifyOrExit(ifm->ifm_index == static_cast<int>(sTunIndex), OT_NOOP);
+
+    UpdateLink(aInstance);
+
+exit:
+    if (error == OT_ERROR_NONE)
+    {
+        otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
+    }
+    else
+    {
+        otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
+    }
+}
+
+#endif
 
 static void processNetifEvent(otInstance *aInstance)
 {
@@ -354,11 +964,22 @@
 
     length = recv(sNetlinkFd, buffer, sizeof(buffer), 0);
 
-    VerifyOrExit(length > 0);
+    VerifyOrExit(length > 0, OT_NOOP);
 
-    for (struct nlmsghdr *msg = reinterpret_cast<struct nlmsghdr *>(buffer); NLMSG_OK(msg, length);
+#if defined(__linux__)
+    for (struct nlmsghdr *msg = reinterpret_cast<struct nlmsghdr *>(buffer); NLMSG_OK(msg, static_cast<size_t>(length));
          msg                  = NLMSG_NEXT(msg, length))
     {
+#else
+    {
+        // BSD sends one message per read to routing socket (see route.c, monitor command)
+        struct rt_msghdr *msg;
+
+        msg = (struct rt_msghdr *)buffer;
+
+#define nlmsg_type rtm_type
+
+#endif
         switch (msg->nlmsg_type)
         {
         case RTM_NEWADDR:
@@ -366,13 +987,33 @@
             processNetifAddrEvent(aInstance, msg);
             break;
 
+#if defined(RTM_NEWLINK) && defined(RTM_DELLINK)
         case RTM_NEWLINK:
         case RTM_DELLINK:
             processNetifLinkEvent(aInstance, msg);
             break;
+#endif
 
-        default:
+#if defined(RTM_NEWMADDR) && defined(RTM_DELMADDR)
+        case RTM_NEWMADDR:
+        case RTM_DELMADDR:
+            processNetifAddrEvent(aInstance, msg);
             break;
+#endif
+
+#if !defined(__linux__)
+        case RTM_IFINFO:
+            processNetifInfoEvent(aInstance, msg);
+            break;
+#endif
+
+#if defined(ROUTE_FILTER) || defined(RO_MSGFILTER) || defined(__linux__)
+        default:
+            otLogWarnPlat("unhandled/unexpected netlink/route message (%d).", (int)msg->nlmsg_type);
+            break;
+#else
+            // this platform doesn't support filtering, so we expect messages of other types...we just ignore them
+#endif
         }
     }
 
@@ -380,91 +1021,380 @@
     return;
 }
 
-void platformNetifInit(otInstance *aInstance)
+void platformNetifDeinit(void)
+{
+    if (sTunFd != -1)
+    {
+        close(sTunFd);
+        sTunFd = -1;
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+        destroyTunnel();
+#endif
+    }
+
+    if (sIpFd != -1)
+    {
+        close(sIpFd);
+        sIpFd = -1;
+    }
+
+    if (sNetlinkFd != -1)
+    {
+        close(sNetlinkFd);
+        sNetlinkFd = -1;
+    }
+
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+    if (sMLDMonitorFd != -1)
+    {
+        close(sMLDMonitorFd);
+        sMLDMonitorFd = -1;
+    }
+#endif
+
+    sTunIndex = 0;
+}
+
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+static void mldListenerInit(void)
+{
+    struct ipv6_mreq mreq6;
+
+    sMLDMonitorFd          = SocketWithCloseExec(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, kSocketNonBlock);
+    mreq6.ipv6mr_interface = sTunIndex;
+    memcpy(&mreq6.ipv6mr_multiaddr, kMLDv2MulticastAddress.mFields.m8, sizeof(kMLDv2MulticastAddress.mFields.m8));
+
+    VerifyOrDie(setsockopt(sMLDMonitorFd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, sizeof(mreq6)) == 0, OT_EXIT_FAILURE);
+#if defined(__linux__)
+    VerifyOrDie(setsockopt(sMLDMonitorFd, SOL_SOCKET, SO_BINDTODEVICE, sTunName,
+                           static_cast<socklen_t>(strnlen(sTunName, IFNAMSIZ))) == 0,
+                OT_EXIT_FAILURE);
+#endif
+}
+
+static void processMLDEvent(otInstance *aInstance)
+{
+    const size_t        kMaxMLDEvent = 8192;
+    uint8_t             buffer[kMaxMLDEvent];
+    ssize_t             bufferLen = -1;
+    struct sockaddr_in6 srcAddr;
+    socklen_t           addrLen  = sizeof(srcAddr);
+    bool                fromSelf = false;
+    MLDv2Header *       hdr      = reinterpret_cast<MLDv2Header *>(buffer);
+    size_t              offset;
+    uint8_t             type;
+    struct ifaddrs *    ifAddrs = nullptr;
+    char                addressString[INET6_ADDRSTRLEN + 1];
+
+    bufferLen = recvfrom(sMLDMonitorFd, buffer, sizeof(buffer), 0, reinterpret_cast<sockaddr *>(&srcAddr), &addrLen);
+    VerifyOrExit(bufferLen > 0, OT_NOOP);
+
+    type = buffer[0];
+    VerifyOrExit(type == kICMPv6MLDv2Type && bufferLen >= static_cast<ssize_t>(sizeof(MLDv2Header)), OT_NOOP);
+
+    // Check whether it is sent by self
+    VerifyOrExit(getifaddrs(&ifAddrs) == 0, OT_NOOP);
+    for (struct ifaddrs *ifAddr = ifAddrs; ifAddr != nullptr; ifAddr = ifAddr->ifa_next)
+    {
+        if (ifAddr->ifa_addr != nullptr && ifAddr->ifa_addr->sa_family == AF_INET6 &&
+            strncmp(sTunName, ifAddr->ifa_name, IFNAMSIZ) == 0)
+        {
+            struct sockaddr_in6 *addr6 = reinterpret_cast<struct sockaddr_in6 *>(ifAddr->ifa_addr);
+
+            if (memcmp(&addr6->sin6_addr, &srcAddr.sin6_addr, sizeof(in6_addr)) == 0)
+            {
+                fromSelf = true;
+                break;
+            }
+        }
+    }
+    VerifyOrExit(fromSelf, OT_NOOP);
+
+    hdr    = reinterpret_cast<MLDv2Header *>(buffer);
+    offset = sizeof(MLDv2Header);
+
+    for (size_t i = 0; i < ntohs(hdr->mNumRecords) && offset < static_cast<size_t>(bufferLen); i++)
+    {
+        if (static_cast<size_t>(bufferLen) >= (sizeof(MLDv2Record) + offset))
+        {
+            MLDv2Record *record = reinterpret_cast<MLDv2Record *>(&buffer[offset]);
+
+            otError      err;
+            otIp6Address address;
+
+            memcpy(&address.mFields.m8, &record->mMulticastAddress, sizeof(address.mFields.m8));
+            inet_ntop(AF_INET6, &record->mMulticastAddress, addressString, sizeof(addressString));
+            if (record->mRecordType == kICMPv6MLDv2RecordChangeToIncludeType)
+            {
+                err = otIp6SubscribeMulticastAddress(aInstance, &address);
+                if (err == OT_ERROR_ALREADY)
+                {
+                    otLogNotePlat(
+                        "Will not subscribe duplicate multicast address %s",
+                        inet_ntop(AF_INET6, &record->mMulticastAddress, addressString, sizeof(addressString)));
+                }
+                else if (err != OT_ERROR_NONE)
+                {
+                    otLogWarnPlat("Failed to subscribe multicast address %s: %s", addressString,
+                                  otThreadErrorToString(err));
+                }
+                else
+                {
+                    otLogDebgPlat("Subscribed multicast address %s", addressString);
+                }
+            }
+            else if (record->mRecordType == kICMPv6MLDv2RecordChangeToExcludeType)
+            {
+                err = otIp6UnsubscribeMulticastAddress(aInstance, &address);
+                if (err != OT_ERROR_NONE)
+                {
+                    otLogWarnPlat("Failed to unsubscribe multicast address %s: %s", addressString,
+                                  otThreadErrorToString(err));
+                }
+                else
+                {
+                    otLogDebgPlat("Unsubscribed multicast address %s", addressString);
+                }
+            }
+
+            offset += sizeof(MLDv2Record) + sizeof(in6_addr) * ntohs(record->mNumSources);
+        }
+    }
+
+exit:
+    if (ifAddrs)
+    {
+        freeifaddrs(ifAddrs);
+    }
+
+    return;
+}
+#endif
+
+#if defined(__linux__)
+// set up the tun device
+static void platformConfigureTunDevice(otInstance *aInstance,
+                                       const char *aInterfaceName,
+                                       char *      deviceName,
+                                       size_t      deviceNameLen)
 {
     struct ifreq ifr;
 
-    sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
-    VerifyOrExit(sIpFd >= 0);
+    (void)aInstance;
 
+    sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC | O_NONBLOCK);
+    VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO);
+
+    memset(&ifr, 0, sizeof(ifr));
+    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+
+    if (aInterfaceName)
+    {
+        VerifyOrDie(strlen(aInterfaceName) < IFNAMSIZ, OT_EXIT_INVALID_ARGUMENTS);
+
+        strncpy(ifr.ifr_name, aInterfaceName, IFNAMSIZ);
+    }
+    else
+    {
+        strncpy(ifr.ifr_name, "wpan%d", IFNAMSIZ);
+    }
+
+    VerifyOrDie(ioctl(sTunFd, TUNSETIFF, static_cast<void *>(&ifr)) == 0, OT_EXIT_ERROR_ERRNO);
+    VerifyOrDie(ioctl(sTunFd, TUNSETLINK, ARPHRD_VOID) == 0, OT_EXIT_ERROR_ERRNO);
+
+    strncpy(deviceName, ifr.ifr_name, deviceNameLen);
+}
+#endif
+
+#if defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_UTUN)
+static void platformConfigureTunDevice(otInstance *aInstance,
+                                       const char *aInterfaceName,
+                                       char *      deviceName,
+                                       size_t      deviceNameLen)
+{
+    (void)aInterfaceName;
+    int                 err = 0;
+    struct sockaddr_ctl addr;
+    struct ctl_info     info;
+
+    (void)aInstance;
+
+    sTunFd = SocketWithCloseExec(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL, kSocketNonBlock);
+    VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO);
+
+    memset(&info, 0, sizeof(info));
+    strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME));
+    err = ioctl(sTunFd, CTLIOCGINFO, &info);
+    VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
+
+    addr.sc_id      = info.ctl_id;
+    addr.sc_len     = sizeof(addr);
+    addr.sc_family  = AF_SYSTEM;
+    addr.ss_sysaddr = AF_SYS_CONTROL;
+
+    addr.sc_unit = 0;
+    err          = connect(sTunFd, (struct sockaddr *)&addr, sizeof(addr));
+    VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
+
+    socklen_t devNameLen;
+    devNameLen = (socklen_t)deviceNameLen;
+    err        = getsockopt(sTunFd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, deviceName, &devNameLen);
+    VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
+
+    otLogInfoPlat("Tunnel device name = '%s'", deviceName);
+}
+#endif
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+static otError destroyTunnel(void)
+{
+    otError      error;
+    struct ifreq ifr;
+
+    memset(&ifr, 0, sizeof(ifr));
+    strncpy(ifr.ifr_name, sTunName, sizeof(ifr.ifr_name));
+    VerifyOrExit(ioctl(sIpFd, SIOCIFDESTROY, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
+    error = OT_ERROR_NONE;
+
+exit:
+    return error;
+}
+#endif
+
+#if defined(__NetBSD__) ||                                                                             \
+    (defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_TUN)) || \
+    defined(__FreeBSD__)
+static void platformConfigureTunDevice(otInstance *aInstance,
+                                       const char *aInterfaceName,
+                                       char *      deviceName,
+                                       size_t      deviceNameLen)
+{
+    int         flags = IFF_BROADCAST | IFF_MULTICAST;
+    int         err;
+    const char *last_slash;
+    const char *path;
+
+    (void)aInterfaceName;
+    (void)aInstance;
+
+    path = OPENTHREAD_POSIX_TUN_DEVICE;
+
+    sTunFd = open(path, O_RDWR | O_NONBLOCK);
+    VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO);
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+    err = ioctl(sTunFd, TUNSIFMODE, &flags);
+    VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
+#endif
+
+    flags = 1;
+    err   = ioctl(sTunFd, TUNSIFHEAD, &flags);
+    VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
+
+    last_slash = strrchr(OPENTHREAD_POSIX_TUN_DEVICE, '/');
+    VerifyOrDie(last_slash != nullptr, OT_EXIT_ERROR_ERRNO);
+    last_slash++;
+
+    strncpy(deviceName, last_slash, deviceNameLen);
+}
+#endif
+
+static void platformConfigureNetLink(void)
+{
+#if defined(__linux__)
     sNetlinkFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
-    VerifyOrExit(sNetlinkFd > 0);
+#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+    sNetlinkFd = socket(PF_ROUTE, SOCK_RAW, 0);
+#else
+#error "!! Unknown platform !!"
+#endif
+    VerifyOrDie(sNetlinkFd >= 0, OT_EXIT_ERROR_ERRNO);
 
-    otIcmp6SetEchoMode(aInstance, OT_ICMP6_ECHO_HANDLER_DISABLED);
-
+#if defined(__linux__)
     {
         struct sockaddr_nl sa;
 
         memset(&sa, 0, sizeof(sa));
         sa.nl_family = AF_NETLINK;
         sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV6_IFADDR;
-        VerifyOrExit(bind(sNetlinkFd, reinterpret_cast<struct sockaddr *>(&sa), sizeof(sa)) == 0);
+        VerifyOrDie(bind(sNetlinkFd, reinterpret_cast<struct sockaddr *>(&sa), sizeof(sa)) == 0, OT_EXIT_ERROR_ERRNO);
     }
+#endif
 
-    sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC);
-    VerifyOrExit(sTunFd > 0, otLogCritPlat("Unable to open tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
+#if defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+    {
+        int status;
+#ifdef ROUTE_FILTER
+        unsigned int msgfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) | ROUTE_FILTER(RTM_DELADDR) |
+                                 ROUTE_FILTER(RTM_NEWMADDR) | ROUTE_FILTER(RTM_DELMADDR);
+#define FILTER_CMD ROUTE_MSGFILTER
+#define FILTER_ARG msgfilter
+#define FILTER_ARG_SZ sizeof(msgfilter)
+#endif
+#ifdef RO_MSGFILTER
+        uint8_t msgfilter[] = {RTM_IFINFO, RTM_NEWADDR, RTM_DELADDR};
+#define FILTER_CMD RO_MSGFILTER
+#define FILTER_ARG msgfilter
+#define FILTER_ARG_SZ sizeof(msgfilter)
+#endif
+#if defined(ROUTE_FILTER) || defined(RO_MSGFILTER)
+        status = setsockopt(sNetlinkFd, AF_ROUTE, FILTER_CMD, FILTER_ARG, FILTER_ARG_SZ);
+        VerifyOrDie(status == 0, OT_EXIT_ERROR_ERRNO);
+#endif
+        status = fcntl(sNetlinkFd, F_SETFL, O_NONBLOCK);
+        VerifyOrDie(status == 0, OT_EXIT_ERROR_ERRNO);
+    }
+#endif // defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+}
 
-    memset(&ifr, 0, sizeof(ifr));
-    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
-    strncpy(ifr.ifr_name, "wpan%d", IFNAMSIZ);
+void platformNetifInit(otInstance *aInstance, const char *aInterfaceName)
+{
+    sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketNonBlock);
+    VerifyOrDie(sIpFd >= 0, OT_EXIT_ERROR_ERRNO);
 
-    VerifyOrExit(ioctl(sTunFd, TUNSETIFF, static_cast<void *>(&ifr)) == 0,
-                 otLogCritPlat("Unable to configure tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
-    VerifyOrExit(ioctl(sTunFd, TUNSETLINK, ARPHRD_VOID) == 0,
-                 otLogCritPlat("Unable to set link type of tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
+    platformConfigureNetLink();
+    platformConfigureTunDevice(aInstance, aInterfaceName, sTunName, sizeof(sTunName));
 
-    sTunIndex = if_nametoindex(ifr.ifr_name);
-    VerifyOrExit(sTunIndex > 0);
+    sTunIndex = if_nametoindex(sTunName);
+    VerifyOrDie(sTunIndex > 0, OT_EXIT_FAILURE);
 
-    strncpy(sTunName, ifr.ifr_name, sizeof(sTunName));
 #if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
     platformUdpInit(sTunName);
 #endif
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+    mldListenerInit();
+#endif
 
+    otIcmp6SetEchoMode(aInstance, OT_ICMP6_ECHO_HANDLER_DISABLED);
     otIp6SetReceiveCallback(aInstance, processReceive, aInstance);
     otIp6SetAddressCallback(aInstance, processAddressChange, aInstance);
-    otSetStateChangedCallback(aInstance, processStateChange, aInstance);
+    SuccessOrDie(otSetStateChangedCallback(aInstance, processStateChange, aInstance));
+#if OPENTHREAD_POSIX_MULTICAST_PROMISCUOUS_REQUIRED
+    otIp6SetMulticastPromiscuousEnabled(aInstance, true);
+#endif
+
     sInstance = aInstance;
-
-exit:
-    if (sTunIndex == 0)
-    {
-        if (sTunFd != -1)
-        {
-            close(sTunFd);
-            sTunFd = -1;
-        }
-
-        if (sIpFd != -1)
-        {
-            close(sIpFd);
-            sIpFd = -1;
-        }
-
-        if (sNetlinkFd != -1)
-        {
-            close(sNetlinkFd);
-            sNetlinkFd = -1;
-        }
-
-        DieNow(OT_EXIT_FAILURE);
-    }
 }
 
 void platformNetifUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
 {
     OT_UNUSED_VARIABLE(aWriteFdSet);
 
-    VerifyOrExit(sTunIndex > 0);
+    VerifyOrExit(sTunIndex > 0, OT_NOOP);
 
-    assert(sTunFd > 0);
-    assert(sNetlinkFd > 0);
-    assert(sIpFd > 0);
+    assert(sTunFd >= 0);
+    assert(sNetlinkFd >= 0);
+    assert(sIpFd >= 0);
 
     FD_SET(sTunFd, aReadFdSet);
     FD_SET(sTunFd, aErrorFdSet);
     FD_SET(sNetlinkFd, aReadFdSet);
     FD_SET(sNetlinkFd, aErrorFdSet);
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+    FD_SET(sMLDMonitorFd, aReadFdSet);
+    FD_SET(sMLDMonitorFd, aErrorFdSet);
+#endif
 
     if (sTunFd > *aMaxFd)
     {
@@ -476,6 +1406,12 @@
         *aMaxFd = sNetlinkFd;
     }
 
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+    if (sMLDMonitorFd > *aMaxFd)
+    {
+        *aMaxFd = sMLDMonitorFd;
+    }
+#endif
 exit:
     return;
 }
@@ -483,7 +1419,7 @@
 void platformNetifProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet)
 {
     OT_UNUSED_VARIABLE(aWriteFdSet);
-    VerifyOrExit(sTunIndex > 0);
+    VerifyOrExit(sTunIndex > 0, OT_NOOP);
 
     if (FD_ISSET(sTunFd, aErrorFdSet))
     {
@@ -497,6 +1433,14 @@
         DieNow(OT_EXIT_FAILURE);
     }
 
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+    if (FD_ISSET(sMLDMonitorFd, aErrorFdSet))
+    {
+        close(sMLDMonitorFd);
+        DieNow(OT_EXIT_FAILURE);
+    }
+#endif
+
     if (FD_ISSET(sTunFd, aReadFdSet))
     {
         processTransmit(sInstance);
@@ -507,8 +1451,31 @@
         processNetifEvent(sInstance);
     }
 
+#if OPENTHREAD_POSIX_USE_MLD_MONITOR
+    if (FD_ISSET(sMLDMonitorFd, aReadFdSet))
+    {
+        processMLDEvent(sInstance);
+    }
+#endif
+
 exit:
     return;
 }
 
+otError otPlatGetNetif(otInstance *aInstance, const char **outNetIfName, unsigned int *outNetIfIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error;
+
+    VerifyOrExit(sTunIndex != 0, error = OT_ERROR_FAILED);
+
+    *outNetIfName  = sTunName;
+    *outNetIfIndex = sTunIndex;
+    error          = OT_ERROR_NONE;
+
+exit:
+
+    return error;
+}
 #endif // OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
diff --git a/src/posix/platform/openthread-core-posix-config.h b/src/posix/platform/openthread-core-posix-config.h
index 9280cb2..9dddb83 100644
--- a/src/posix/platform/openthread-core-posix-config.h
+++ b/src/posix/platform/openthread-core-posix-config.h
@@ -45,12 +45,36 @@
 #endif
 
 /**
+ * @def OPENTHREAD_CONFIG_LOG_OUTPUT
+ *
+ * Select the log output.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT
+#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
+ *
+ * Define as 1 to enable dynamic log level control.
+ *
+ * Note that the OPENTHREAD_CONFIG_LOG_LEVEL determines the log level at
+ * compile time. The dynamic log level control (if enabled) only allows
+ * decreasing the log level from the compile time value.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
+#define OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE 1
+#endif
+
+/**
  * @def OPENTHREAD_CONFIG_PLATFORM_INFO
  *
  * The platform-specific string to insert into the OpenThread version string.
  *
  */
-#define OPENTHREAD_CONFIG_PLATFORM_INFO "POSIX-APP"
+#define OPENTHREAD_CONFIG_PLATFORM_INFO "POSIX"
 
 /**
  * @def OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
@@ -81,4 +105,17 @@
 #ifndef OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
 #define OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE 1
 #endif
+
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+
+#ifndef OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+#define OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE 1
+#endif
+
+#ifndef OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+#define OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE 1
+#endif
+
+#endif
+
 #endif // OPENTHREAD_CORE_POSIX_CONFIG_H_
diff --git a/src/posix/platform/openthread-posix-config.h b/src/posix/platform/openthread-posix-config.h
new file mode 100644
index 0000000..223e8e2
--- /dev/null
+++ b/src/posix/platform/openthread-posix-config.h
@@ -0,0 +1,128 @@
+/*
+ *  Copyright (c) 2019, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OPENTHREAD_PLATFORM_CONFIG_H_
+#define OPENTHREAD_PLATFORM_CONFIG_H_
+
+#include "openthread-core-config.h"
+
+/**
+ * @file
+ * @brief
+ *   This file includes the POSIX platform-specific configurations.
+ */
+
+/**
+ * @def OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
+ *
+ * Define as 1 to enable PTY RCP support.
+ *
+ */
+#ifndef OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
+#define OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE 1
+#endif
+
+/**
+ * @def OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME
+ *
+ * Define socket basename used by POSIX app daemon.
+ *
+ */
+#ifndef OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME
+#define OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME "/tmp/openthread"
+#endif
+
+/**
+ * @def OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+ *
+ * Define to 1 to enable POSIX daemon.
+ *
+ */
+#ifndef OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+#define OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE 0
+#endif
+
+/**
+ * RCP bus UART.
+ *
+ * @note This value is also for simulated UART bus.
+ *
+ */
+#define OT_POSIX_RCP_BUS_UART 1
+
+/**
+ * RCP bus SPI.
+ *
+ */
+#define OT_POSIX_RCP_BUS_SPI 2
+
+/**
+ * @def OPENTHREAD_POSIX_CONFIG_RCP_BUS
+ *
+ * This setting configures what type of RCP bus to use.
+ *
+ */
+#ifndef OPENTHREAD_POSIX_CONFIG_RCP_BUS
+#define OPENTHREAD_POSIX_CONFIG_RCP_BUS OT_POSIX_RCP_BUS_UART
+#endif
+
+/**
+ * @def OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
+ *
+ * Define as 1 to enable max power table support.
+ *
+ */
+#ifndef OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
+#define OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE 0
+#endif
+
+#ifdef __APPLE__
+
+/**
+ * Use built-in utun driver on mac OS
+ */
+#define OT_POSIX_CONFIG_MACOS_UTUN 1
+
+/**
+ * Use open-source tun driver on mac OS
+ */
+#define OT_POSIX_CONFIG_MACOS_TUN 2
+
+/**
+ * @def OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION
+ *
+ * This setting configures which tunnel driver to use.
+ *
+ */
+#ifndef OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION
+#define OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION OT_POSIX_CONFIG_MACOS_UTUN
+#endif
+
+#endif // __APPLE__
+
+#endif // OPENTHREAD_PLATFORM_CONFIG_H_
diff --git a/src/posix/platform/openthread-system.h b/src/posix/platform/openthread-system.h
deleted file mode 100644
index e582cbf..0000000
--- a/src/posix/platform/openthread-system.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- * @brief
- *   This file defines the platform-specific functions needed by OpenThread's example applications.
- */
-
-#ifndef OPENTHREAD_SYSTEM_H_
-#define OPENTHREAD_SYSTEM_H_
-
-#include <setjmp.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <sys/select.h>
-
-#include <openthread/error.h>
-#include <openthread/instance.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * This enumeration represents exit codes used when OpenThread exits.
- *
- */
-enum
-{
-    /**
-     * Success.
-     */
-    OT_EXIT_SUCCESS = 0,
-
-    /**
-     * Generic failure.
-     */
-    OT_EXIT_FAILURE = 1,
-
-    /**
-     * Invalid arguments.
-     */
-    OT_EXIT_INVALID_ARGUMENTS = 2,
-
-    /**
-     * Incompatible radio spinel.
-     */
-    OT_EXIT_RADIO_SPINEL_INCOMPATIBLE = 3,
-
-    /**
-     * Unexpected radio spinel reset.
-     */
-    OT_EXIT_RADIO_SPINEL_RESET = 4,
-
-    /**
-     * System call or library function error.
-     */
-    OT_EXIT_ERROR_ERRNO = 5,
-};
-
-/**
- * This enumeration represents default parameters for the SPI interface.
- *
- */
-enum
-{
-    OT_PLATFORM_CONFIG_SPI_DEFAULT_MODE           = 0,       ///< Default SPI Mode: CPOL=0, CPHA=0.
-    OT_PLATFORM_CONFIG_SPI_DEFAULT_SPEED_HZ       = 1000000, ///< Default SPI speed in hertz.
-    OT_PLATFORM_CONFIG_SPI_DEFAULT_CS_DELAY_US    = 20,      ///< Default delay after SPI C̅S̅ assertion, in µsec.
-    OT_PLATFORM_CONFIG_SPI_DEFAULT_RESET_DELAY_MS = 0, ///< Default delay after R̅E̅S̅E̅T̅ assertion, in miliseconds.
-    OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE =
-        16, ///< Default maximum number of 0xFF bytes to clip from start of MISO frame.
-    OT_PLATFORM_CONFIG_SPI_DEFAULT_SMALL_PACKET_SIZE =
-        32, ///< Default smallest SPI packet size we can receive in a single transaction.
-};
-
-/**
- * This structure represents platform specific configurations.
- *
- */
-typedef struct otPlatformConfig
-{
-    uint64_t    mNodeId;                ///< Unique node ID.
-    uint32_t    mSpeedUpFactor;         ///< Speed up factor.
-    const char *mInterfaceName;         ///< Thread network interface name.
-    const char *mRadioFile;             ///< Radio file path.
-    const char *mRadioConfig;           ///< Radio configurations.
-    bool        mResetRadio;            ///< Whether to reset RCP when initializing.
-    bool        mRestoreDatasetFromNcp; ///< Whether to retrieve dataset from NCP and save to file.
-
-    char *   mSpiGpioIntDevice;   ///< Path to the Linux GPIO character device for the `I̅N̅T̅` pin.
-    char *   mSpiGpioResetDevice; ///< Path to the Linux GPIO character device for the `R̅E̅S̅E̅T̅` pin.
-    uint8_t  mSpiGpioIntLine;     ///< Line index of the `I̅N̅T̅` pin for the associated GPIO character device.
-    uint8_t  mSpiGpioResetLine;   ///< Line index of the `R̅E̅S̅E̅T̅` pin for the associated GPIO character device.
-    uint8_t  mSpiMode;            ///< SPI mode to use (0-3).
-    uint32_t mSpiSpeed;           ///< SPI speed in hertz.
-    uint32_t mSpiResetDelay;      ///< The delay after R̅E̅S̅E̅T̅ assertion, in miliseconds.
-    uint16_t mSpiCsDelay;         ///< The delay after SPI C̅S̅ assertion, in µsec.
-    uint8_t  mSpiAlignAllowance;  ///< Maximum number of 0xFF bytes to clip from start of MISO frame.
-    uint8_t  mSpiSmallPacketSize; ///< Smallest SPI packet size we can receive in a single transaction.
-} otPlatformConfig;
-
-/**
- * This function performs all platform-specific initialization of OpenThread's drivers.
- *
- * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
- *       when initialization of OpenThread's drivers is most appropriate.
- *
- * @param[in]  aPlatformConfig  Platform configuration structure.
- *
- * @returns A pointer to the OpenThread instance.
- *
- */
-otInstance *otSysInit(otPlatformConfig *aPlatformConfig);
-
-/**
- * This function performs all platform-specific deinitialization for OpenThread's drivers.
- *
- * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
- *       when deinitialization of OpenThread's drivers is most appropriate.
- *
- */
-void otSysDeinit(void);
-
-/**
- * This structure represents a context for a select() based mainloop.
- *
- */
-typedef struct otSysMainloopContext
-{
-    fd_set         mReadFdSet;  ///< The read file descriptors.
-    fd_set         mWriteFdSet; ///< The write file descriptors.
-    fd_set         mErrorFdSet; ///< The error file descriptors.
-    int            mMaxFd;      ///< The max file descriptor.
-    struct timeval mTimeout;    ///< The timeout.
-} otSysMainloopContext;
-
-/**
- * This function updates the file descriptor sets with file descriptors used by OpenThread drivers.
- *
- * @param[in]       aInstance   The OpenThread instance structure.
- * @param[inout]    aMainloop   A pointer to the mainloop context.
- *
- */
-void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop);
-
-/**
- * This function polls OpenThread's mainloop.
- *
- * @param[inout]    aMainloop   A pointer to the mainloop context.
- *
- * @returns value returned from select().
- *
- */
-int otSysMainloopPoll(otSysMainloopContext *aMainloop);
-
-/**
- * This function performs all platform-specific processing for OpenThread's example applications.
- *
- * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
- *       in the main loop when processing OpenThread's drivers is most appropriate.
- *
- * @param[in]   aInstance   The OpenThread instance structure.
- * @param[in]   aMainloop   A pointer to the mainloop context.
- *
- */
-void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop);
-
-#ifdef __cplusplus
-} // end of extern "C"
-#endif
-
-#endif // OPENTHREAD_SYSTEM_H_
diff --git a/src/posix/platform/platform-config.h b/src/posix/platform/platform-config.h
deleted file mode 100644
index 1508fc3..0000000
--- a/src/posix/platform/platform-config.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef OPENTHREAD_PLATFORM_CONFIG_H_
-#define OPENTHREAD_PLATFORM_CONFIG_H_
-
-/**
- * @file
- * @brief
- *   This file includes the POSIX platform-specific configurations.
- */
-
-/**
- * @def OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
- *
- * Define as 1 to enable PTY device support in POSIX app.
- *
- */
-#ifndef OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
-#define OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE 1
-#endif
-
-/**
- * @def OPENTHREAD_POSIX_APP_SOCKET_BASENAME
- *
- * Define socket basename used by POSIX app daemon.
- *
- */
-#ifndef OPENTHREAD_POSIX_APP_SOCKET_BASENAME
-#define OPENTHREAD_POSIX_APP_SOCKET_BASENAME "/tmp/openthread"
-#endif
-
-/**
- * @def OPENTHREAD_POSIX_VIRTUAL_TIME
- *
- * This setting configures whether to use virtual time.
- *
- */
-#ifndef OPENTHREAD_POSIX_VIRTUAL_TIME
-#define OPENTHREAD_POSIX_VIRTUAL_TIME 0
-#endif
-
-#endif // OPENTHREAD_PLATFORM_CONFIG_H_
diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h
index d2a19cc..fbebdb6 100644
--- a/src/posix/platform/platform-posix.h
+++ b/src/posix/platform/platform-posix.h
@@ -35,24 +35,39 @@
 #ifndef PLATFORM_POSIX_H_
 #define PLATFORM_POSIX_H_
 
+#include "openthread-posix-config.h"
+
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/select.h>
 #include <sys/time.h>
 
-#include <openthread-system.h>
 #include <openthread/error.h>
 #include <openthread/instance.h>
+#include <openthread/openthread-system.h>
+#include <openthread/platform/time.h>
 
-#include "platform-config.h"
 #include "common/logging.hpp"
 
+#include "radio_url.hpp"
+#include "lib/platform/exit_code.h"
+
+/**
+ * @def OPENTHREAD_POSIX_VIRTUAL_TIME
+ *
+ * This setting configures whether to use virtual time.
+ *
+ */
+#ifndef OPENTHREAD_POSIX_VIRTUAL_TIME
+#define OPENTHREAD_POSIX_VIRTUAL_TIME 0
+#endif
+
 /**
  * This is the socket name used by daemon mode.
  *
  */
-#define OPENTHREAD_POSIX_APP_SOCKET_NAME OPENTHREAD_POSIX_APP_SOCKET_BASENAME ".sock"
+#define OPENTHREAD_POSIX_DAEMON_SOCKET_NAME OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME ".sock"
 
 #ifdef __cplusplus
 extern "C" {
@@ -68,7 +83,7 @@
 };
 
 OT_TOOL_PACKED_BEGIN
-struct Event
+struct VirtualTimeEvent
 {
     uint64_t mDelay;
     uint8_t  mEvent;
@@ -76,69 +91,11 @@
     uint8_t  mData[OT_EVENT_DATA_MAX_SIZE];
 } OT_TOOL_PACKED_END;
 
-/**
- * This function converts an exit code into a string.
- *
- * @param[in]  aExitCode  An exit code.
- *
- * @returns  A string representation of an exit code.
- *
- */
-const char *otExitCodeToString(uint8_t aExitCode);
-
-/**
- * This macro checks for the specified condition, which is expected to commonly be true,
- * and both records exit status and terminates the program if the condition is false.
- *
- * @param[in]   aCondition  The condition to verify
- * @param[in]   aExitCode   The exit code.
- *
- */
-#define VerifyOrDie(aCondition, aExitCode)                                                                   \
-    do                                                                                                       \
-    {                                                                                                        \
-        if (!(aCondition))                                                                                   \
-        {                                                                                                    \
-            otLogCritPlat("%s() at %s:%d: %s", __func__, __FILE__, __LINE__, otExitCodeToString(aExitCode)); \
-            exit(aExitCode);                                                                                 \
-        }                                                                                                    \
-    } while (false)
-
-/**
- * This macro checks for the specified error code, which is expected to commonly be successful,
- * and both records exit status and terminates the program if the error code is unsuccessful.
- *
- * @param[in]  aError  An error code to be evaluated against OT_ERROR_NONE.
- *
- */
-#define SuccessOrDie(aError)             \
-    VerifyOrDie(aError == OT_ERROR_NONE, \
-                (aError == OT_ERROR_INVALID_ARGS ? OT_EXIT_INVALID_ARGUMENTS : OT_EXIT_FAILURE))
-
-/**
- * This macro unconditionally both records exit status and terminates the program.
- *
- * @param[in]   aExitCode   The exit code.
- *
- */
-#define DieNow(aExitCode) VerifyOrDie(false, aExitCode)
-
-/**
- * This macro unconditionally both records exit status and exit message and terminates the program.
- *
- * @param[in]   aMessage    The exit message.
- * @param[in]   aExitCode   The exit code.
- *
- */
-#define DieNowWithMessage(aMessage, aExitCode)                                                       \
-    do                                                                                               \
-    {                                                                                                \
-        fprintf(stderr, "exit(%d): %s line %d, %s, %s\r\n", aExitCode, __func__, __LINE__, aMessage, \
-                otExitCodeToString(aExitCode));                                                      \
-        otLogCritPlat("exit(%d): %s line %d, %s, %s", aExitCode, __func__, __LINE__, aMessage,       \
-                      otExitCodeToString(aExitCode));                                                \
-        exit(aExitCode);                                                                             \
-    } while (false)
+struct RadioProcessContext
+{
+    const fd_set *mReadFdSet;
+    const fd_set *mWriteFdSet;
+};
 
 /**
  * Unique node ID.
@@ -149,8 +106,11 @@
 /**
  * This function initializes the alarm service used by OpenThread.
  *
+ * @param[in]  aSpeedUpFactor   The speed up factor.
+ * @param[in]  aRealTimeSignal  The real time signal for microsecond alarms.
+ *
  */
-void platformAlarmInit(uint32_t aSpeedUpFactor);
+void platformAlarmInit(uint32_t aSpeedUpFactor, int aRealTimeSignal);
 
 /**
  * This function retrieves the time remaining until the alarm fires.
@@ -176,10 +136,18 @@
  */
 int32_t platformAlarmGetNext(void);
 
+#ifndef MS_PER_S
 #define MS_PER_S 1000
+#endif
+#ifndef US_PER_MS
 #define US_PER_MS 1000
-#define US_PER_S 1000000
+#endif
+#ifndef US_PER_S
+#define US_PER_S (MS_PER_S * US_PER_MS)
+#endif
+#ifndef NS_PER_US
 #define NS_PER_US 1000
+#endif
 
 /**
  * This function advances the alarm time by @p aDelta.
@@ -198,7 +166,7 @@
  * @param[in]  aPlatformConfig  Platform configuration structure.
  *
  */
-void platformRadioInit(const otPlatformConfig *aPlatformConfig);
+void platformRadioInit(otUrl *aRadioUrl);
 
 /**
  * This function shuts down the radio service used by OpenThread.
@@ -207,6 +175,12 @@
 void platformRadioDeinit(void);
 
 /**
+ * This function shuts down platform network interface.
+ *
+ */
+void platformNetifDeinit(void);
+
+/**
  * This function inputs a received radio frame.
  *
  * @param[in]  aInstance   A pointer to the OpenThread instance.
@@ -275,9 +249,10 @@
  * This function initializes platform netif.
  *
  * @param[in]   aInstance       A pointer to the OpenThread instance.
+ * @param[in]   aInterfaceName  A pointer to Thread network interface name.
  *
  */
-void platformNetifInit(otInstance *aInstance);
+void platformNetifInit(otInstance *aInstance, const char *aInterfaceName);
 
 /**
  * This function updates the file descriptor sets with file descriptors used by platform netif module.
@@ -303,14 +278,16 @@
 /**
  * This function initialize virtual time simulation.
  *
+ * @params[in]  aNodeId     Node id of this simulated device.
+ *
  */
-void platformSimInit(void);
+void virtualTimeInit(uint16_t aNodeId);
 
 /**
  * This function deinitialize virtual time simulation.
  *
  */
-void platformSimDeinit(void);
+void virtualTimeDeinit(void);
 
 /**
  * This function performs virtual time simulation processing.
@@ -320,7 +297,7 @@
  * @param[in]   aWriteFdSet     A pointer to the write file descriptors.
  *
  */
-void platformSimProcess(otInstance *  aInstance,
+void virtualTimeProcess(otInstance *  aInstance,
                         const fd_set *aReadFdSet,
                         const fd_set *aWriteFdSet,
                         const fd_set *aErrorFdSet);
@@ -336,7 +313,7 @@
  * @param[inout]  aTimeout     A pointer to the timeout.
  *
  */
-void platformSimUpdateFdSet(fd_set *        aReadFdSet,
+void virtualTimeUpdateFdSet(fd_set *        aReadFdSet,
                             fd_set *        aWriteFdSet,
                             fd_set *        aErrorFdSet,
                             int *           aMaxFd,
@@ -349,7 +326,7 @@
  * @param[in] aLength   Length of the spinel frame.
  *
  */
-void platformSimSendRadioSpinelWriteEvent(const uint8_t *aData, uint16_t aLength);
+void virtualTimeSendRadioSpinelWriteEvent(const uint8_t *aData, uint16_t aLength);
 
 /**
  * This function receives an event of virtual time simulation.
@@ -357,7 +334,7 @@
  * @param[out]  aEvent  A pointer to the event receiving the event.
  *
  */
-void platformSimReceiveEvent(struct Event *aEvent);
+void virtualTimeReceiveEvent(struct VirtualTimeEvent *aEvent);
 
 /**
  * This function sends sleep event through virtual time simulation.
@@ -365,7 +342,7 @@
  * @param[in]   aTimeout    A pointer to the time sleeping.
  *
  */
-void platformSimSendSleepEvent(const struct timeval *aTimeout);
+void virtualTimeSendSleepEvent(const struct timeval *aTimeout);
 
 /**
  * This function performs radio spinel processing of virtual time simulation.
@@ -374,15 +351,7 @@
  * @param[in]   aEvent      A pointer to the current event.
  *
  */
-void platformSimRadioSpinelProcess(otInstance *aInstance, const struct Event *aEvent);
-
-/**
- * This function gets system time in microseconds without applying speed up factor.
- *
- * @returns System time in microseconds.
- *
- */
-uint64_t platformGetTime(void);
+void virtualTimeRadioSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
 
 /**
  * This function initializes platform UDP driver.
@@ -410,19 +379,26 @@
  */
 void platformUdpUpdateFdSet(otInstance *aInstance, fd_set *aReadFdSet, int *aMaxFd);
 
+enum SocketBlockOption
+{
+    kSocketBlock,
+    kSocketNonBlock,
+};
+
 /**
  * This function creates a socket with SOCK_CLOEXEC flag set.
  *
- * @param[in]   aDomain     The communication domain.
- * @param[in]   aType       The semantics of communication.
- * @param[in]   aProtocol   The protocol to use.
+ * @param[in]   aDomain       The communication domain.
+ * @param[in]   aType         The semantics of communication.
+ * @param[in]   aProtocol     The protocol to use.
+ * @param[in]   aBlockOption  Whether to add nonblock flags.
  *
  * @returns The file descriptor of the created socket.
  *
  * @retval  -1  Failed to create socket.
  *
  */
-int SocketWithCloseExec(int aDomain, int aType, int aProtocol);
+int SocketWithCloseExec(int aDomain, int aType, int aProtocol, SocketBlockOption aBlockOption);
 
 #ifdef __cplusplus
 }
diff --git a/src/posix/platform/radio.cpp b/src/posix/platform/radio.cpp
new file mode 100644
index 0000000..0f21d64
--- /dev/null
+++ b/src/posix/platform/radio.cpp
@@ -0,0 +1,510 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file implements the radio apis on posix platform.
+ */
+
+#include "platform-posix.h"
+
+#include "lib/spinel/radio_spinel.hpp"
+
+#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART
+#include "hdlc_interface.hpp"
+
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+static ot::Spinel::RadioSpinel<ot::Posix::HdlcInterface, VirtualTimeEvent> sRadioSpinel;
+#else
+static ot::Spinel::RadioSpinel<ot::Posix::HdlcInterface, RadioProcessContext> sRadioSpinel;
+#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
+#elif OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
+#include "spi_interface.hpp"
+
+static ot::Spinel::RadioSpinel<ot::Posix::SpiInterface, RadioProcessContext> sRadioSpinel;
+#else
+#error "OPENTHREAD_POSIX_CONFIG_RCP_BUS only allows OT_POSIX_RCP_BUS_UART and OT_POSIX_RCP_BUS_SPI!"
+#endif
+
+#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
+#include "posix/platform/max_power_table.hpp"
+
+static ot::Posix::MaxPowerTable sMaxPowerTable;
+#endif
+
+void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    SuccessOrDie(sRadioSpinel.GetIeeeEui64(aIeeeEui64));
+}
+
+void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    SuccessOrDie(sRadioSpinel.SetPanId(panid));
+}
+
+void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    otExtAddress addr;
+
+    for (size_t i = 0; i < sizeof(addr); i++)
+    {
+        addr.m8[i] = aAddress->m8[sizeof(addr) - 1 - i];
+    }
+
+    SuccessOrDie(sRadioSpinel.SetExtendedAddress(addr));
+}
+
+void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    SuccessOrDie(sRadioSpinel.SetShortAddress(aAddress));
+}
+
+void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    SuccessOrDie(sRadioSpinel.SetPromiscuous(aEnable));
+}
+
+void platformRadioInit(otUrl *aRadioUrl)
+{
+    ot::Posix::RadioUrl &radioUrl       = *static_cast<ot::Posix::RadioUrl *>(aRadioUrl);
+    bool                 resetRadio     = (radioUrl.GetValue("no-reset") == nullptr);
+    bool                 restoreDataset = (radioUrl.GetValue("ncp-dataset") != nullptr);
+#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
+    uint8_t     channel       = ot::Radio::kChannelMin;
+    int8_t      power         = ot::Posix::MaxPowerTable::kPowerDefault;
+    const char *maxPowerTable = radioUrl.GetValue("max-power-table");
+
+    if (maxPowerTable != nullptr)
+    {
+        const char *str = nullptr;
+
+        for (str = strtok(const_cast<char *>(maxPowerTable), ","); str != nullptr && channel <= ot::Radio::kChannelMax;
+             str = strtok(nullptr, ","))
+        {
+            power = static_cast<int8_t>(strtol(str, nullptr, 0));
+            sMaxPowerTable.SetTransmitPower(channel++, power);
+        }
+
+        VerifyOrDie(str == nullptr, OT_EXIT_INVALID_ARGUMENTS);
+    }
+
+    // Use the last power if omitted.
+    while (channel <= ot::Radio::kChannelMax)
+    {
+        sMaxPowerTable.SetTransmitPower(channel, power);
+        ++channel;
+    }
+#endif
+
+    SuccessOrDie(sRadioSpinel.GetSpinelInterface().Init(radioUrl));
+    sRadioSpinel.Init(resetRadio, restoreDataset);
+}
+
+void platformRadioDeinit(void)
+{
+    sRadioSpinel.Deinit();
+}
+
+bool otPlatRadioIsEnabled(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.IsEnabled();
+}
+
+otError otPlatRadioEnable(otInstance *aInstance)
+{
+    return sRadioSpinel.Enable(aInstance);
+}
+
+otError otPlatRadioDisable(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.Disable();
+}
+
+otError otPlatRadioSleep(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.Sleep();
+}
+
+otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error;
+
+#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
+    if (sRadioSpinel.GetChannel() != aChannel)
+    {
+        SuccessOrExit(error = otPlatRadioSetTransmitPower(aInstance, sMaxPowerTable.GetTransmitPower(aChannel)));
+    }
+#endif
+    SuccessOrExit(error = sRadioSpinel.Receive(aChannel));
+
+exit:
+    return error;
+}
+
+otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.Transmit(*aFrame);
+}
+
+otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return &sRadioSpinel.GetTransmitFrame();
+}
+
+int8_t otPlatRadioGetRssi(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.GetRssi();
+}
+
+otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.GetRadioCaps();
+}
+
+const char *otPlatRadioGetVersionString(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.GetVersion();
+}
+
+bool otPlatRadioGetPromiscuous(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.IsPromiscuous();
+}
+
+void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd, struct timeval *aTimeout)
+{
+    uint64_t now      = otPlatTimeGet();
+    uint64_t deadline = sRadioSpinel.GetNextRadioTimeRecalcStart();
+
+    if (sRadioSpinel.IsTransmitting())
+    {
+        uint64_t txRadioEndUs = sRadioSpinel.GetTxRadioEndUs();
+
+        if (txRadioEndUs < deadline)
+        {
+            deadline = txRadioEndUs;
+        }
+    }
+
+    if (now < deadline)
+    {
+        uint64_t remain = deadline - now;
+
+        if (remain < static_cast<uint64_t>(aTimeout->tv_sec * US_PER_S + aTimeout->tv_usec))
+        {
+            aTimeout->tv_sec  = static_cast<time_t>(remain / US_PER_S);
+            aTimeout->tv_usec = static_cast<suseconds_t>(remain % US_PER_S);
+        }
+    }
+    else
+    {
+        aTimeout->tv_sec  = 0;
+        aTimeout->tv_usec = 0;
+    }
+
+    sRadioSpinel.GetSpinelInterface().UpdateFdSet(*aReadFdSet, *aWriteFdSet, *aMaxFd, *aTimeout);
+
+    if (sRadioSpinel.HasPendingFrame() || sRadioSpinel.IsTransmitDone())
+    {
+        aTimeout->tv_sec  = 0;
+        aTimeout->tv_usec = 0;
+    }
+}
+
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+void virtualTimeRadioSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    sRadioSpinel.Process(*aEvent);
+}
+#else
+void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    RadioProcessContext context = {aReadFdSet, aWriteFdSet};
+
+    sRadioSpinel.Process(context);
+}
+#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
+
+void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    SuccessOrDie(sRadioSpinel.EnableSrcMatch(aEnable));
+}
+
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.AddSrcMatchShortEntry(aShortAddress);
+}
+
+otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    otExtAddress addr;
+
+    for (size_t i = 0; i < sizeof(addr); i++)
+    {
+        addr.m8[i] = aExtAddress->m8[sizeof(addr) - 1 - i];
+    }
+
+    return sRadioSpinel.AddSrcMatchExtEntry(addr);
+}
+
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.ClearSrcMatchShortEntry(aShortAddress);
+}
+
+otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    otExtAddress addr;
+
+    for (size_t i = 0; i < sizeof(addr); i++)
+    {
+        addr.m8[i] = aExtAddress->m8[sizeof(addr) - 1 - i];
+    }
+
+    return sRadioSpinel.ClearSrcMatchExtEntry(addr);
+}
+
+void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    SuccessOrDie(sRadioSpinel.ClearSrcMatchShortEntries());
+}
+
+void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    SuccessOrDie(sRadioSpinel.ClearSrcMatchExtEntries());
+}
+
+otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.EnergyScan(aScanChannel, aScanDuration);
+}
+
+otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    assert(aPower != nullptr);
+    return sRadioSpinel.GetTransmitPower(*aPower);
+}
+
+otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.SetTransmitPower(aPower);
+}
+
+otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    assert(aThreshold != nullptr);
+    return sRadioSpinel.GetCcaEnergyDetectThreshold(*aThreshold);
+}
+
+otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.SetCcaEnergyDetectThreshold(aThreshold);
+}
+
+int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.GetReceiveSensitivity();
+}
+
+#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
+otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.SetCoexEnabled(aEnabled);
+}
+
+bool otPlatRadioIsCoexEnabled(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.IsCoexEnabled();
+}
+
+otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    otError error = OT_ERROR_NONE;
+
+    VerifyOrExit(aCoexMetrics != nullptr, error = OT_ERROR_INVALID_ARGS);
+
+    error = sRadioSpinel.GetCoexMetrics(*aCoexMetrics);
+
+exit:
+    return error;
+}
+#endif
+
+#if OPENTHREAD_CONFIG_DIAG_ENABLE
+otError otPlatDiagProcess(otInstance *aInstance,
+                          uint8_t     aArgsLength,
+                          char *      aArgs[],
+                          char *      aOutput,
+                          size_t      aOutputMaxLen)
+{
+    // deliver the platform specific diags commands to radio only ncp.
+    OT_UNUSED_VARIABLE(aInstance);
+    char  cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE] = {'\0'};
+    char *cur                                              = cmd;
+    char *end                                              = cmd + sizeof(cmd);
+
+    for (uint8_t index = 0; index < aArgsLength; index++)
+    {
+        cur += snprintf(cur, static_cast<size_t>(end - cur), "%s ", aArgs[index]);
+    }
+
+    return sRadioSpinel.PlatDiagProcess(cmd, aOutput, aOutputMaxLen);
+}
+
+void otPlatDiagModeSet(bool aMode)
+{
+    SuccessOrExit(sRadioSpinel.PlatDiagProcess(aMode ? "start" : "stop", nullptr, 0));
+    sRadioSpinel.SetDiagEnabled(aMode);
+
+exit:
+    return;
+}
+
+bool otPlatDiagModeGet(void)
+{
+    return sRadioSpinel.IsDiagEnabled();
+}
+
+void otPlatDiagTxPowerSet(int8_t aTxPower)
+{
+    char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
+
+    snprintf(cmd, sizeof(cmd), "power %d", aTxPower);
+    SuccessOrExit(sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0));
+
+exit:
+    return;
+}
+
+void otPlatDiagChannelSet(uint8_t aChannel)
+{
+    char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
+
+    snprintf(cmd, sizeof(cmd), "channel %d", aChannel);
+    SuccessOrExit(sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0));
+
+exit:
+    return;
+}
+
+void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aFrame);
+    OT_UNUSED_VARIABLE(aError);
+}
+
+void otPlatDiagAlarmCallback(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
+
+uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return
+#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
+        sMaxPowerTable.GetAllowedChannelMask() &
+#endif
+        sRadioSpinel.GetRadioChannelMask(false);
+}
+
+uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return
+#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
+        sMaxPowerTable.GetAllowedChannelMask() &
+#endif
+        sRadioSpinel.GetRadioChannelMask(true);
+}
+
+otRadioState otPlatRadioGetState(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.GetState();
+}
+
+void otPlatRadioSetMacKey(otInstance *    aInstance,
+                          uint8_t         aKeyIdMode,
+                          uint8_t         aKeyId,
+                          const otMacKey *aPrevKey,
+                          const otMacKey *aCurrKey,
+                          const otMacKey *aNextKey)
+{
+    SuccessOrDie(sRadioSpinel.SetMacKey(aKeyIdMode, aKeyId, *aPrevKey, *aCurrKey, *aNextKey));
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
+{
+    SuccessOrDie(sRadioSpinel.SetMacFrameCounter(aMacFrameCounter));
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+uint64_t otPlatRadioGetNow(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return sRadioSpinel.GetNow();
+}
diff --git a/src/posix/platform/radio_spinel.cpp b/src/posix/platform/radio_spinel.cpp
deleted file mode 100644
index 2f8048e..0000000
--- a/src/posix/platform/radio_spinel.cpp
+++ /dev/null
@@ -1,1981 +0,0 @@
-/*
- *  Copyright (c) 2018, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file implements the spinel based radio transceiver.
- */
-
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-#include "ncp/spinel_decoder.hpp"
-
-#include "radio_spinel.hpp"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <syslog.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include <common/code_utils.hpp>
-#include <common/encoding.hpp>
-#include <common/logging.hpp>
-#include <common/new.hpp>
-#include <common/settings.hpp>
-#include <meshcop/dataset.hpp>
-#include <meshcop/meshcop_tlvs.hpp>
-#include <openthread/dataset.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/diag.h>
-#include <openthread/platform/radio.h>
-#include <openthread/platform/settings.h>
-
-#ifndef TX_WAIT_US
-#define TX_WAIT_US (5 * US_PER_S)
-#endif
-
-static ot::PosixApp::RadioSpinel sRadioSpinel;
-
-namespace ot {
-namespace PosixApp {
-
-static otError SpinelStatusToOtError(spinel_status_t aError)
-{
-    otError ret;
-
-    switch (aError)
-    {
-    case SPINEL_STATUS_OK:
-        ret = OT_ERROR_NONE;
-        break;
-
-    case SPINEL_STATUS_FAILURE:
-        ret = OT_ERROR_FAILED;
-        break;
-
-    case SPINEL_STATUS_DROPPED:
-        ret = OT_ERROR_DROP;
-        break;
-
-    case SPINEL_STATUS_NOMEM:
-        ret = OT_ERROR_NO_BUFS;
-        break;
-
-    case SPINEL_STATUS_BUSY:
-        ret = OT_ERROR_BUSY;
-        break;
-
-    case SPINEL_STATUS_PARSE_ERROR:
-        ret = OT_ERROR_PARSE;
-        break;
-
-    case SPINEL_STATUS_INVALID_ARGUMENT:
-        ret = OT_ERROR_INVALID_ARGS;
-        break;
-
-    case SPINEL_STATUS_UNIMPLEMENTED:
-        ret = OT_ERROR_NOT_IMPLEMENTED;
-        break;
-
-    case SPINEL_STATUS_INVALID_STATE:
-        ret = OT_ERROR_INVALID_STATE;
-        break;
-
-    case SPINEL_STATUS_NO_ACK:
-        ret = OT_ERROR_NO_ACK;
-        break;
-
-    case SPINEL_STATUS_CCA_FAILURE:
-        ret = OT_ERROR_CHANNEL_ACCESS_FAILURE;
-        break;
-
-    case SPINEL_STATUS_ALREADY:
-        ret = OT_ERROR_ALREADY;
-        break;
-
-    case SPINEL_STATUS_PROP_NOT_FOUND:
-    case SPINEL_STATUS_ITEM_NOT_FOUND:
-        ret = OT_ERROR_NOT_FOUND;
-        break;
-
-    default:
-        if (aError >= SPINEL_STATUS_STACK_NATIVE__BEGIN && aError <= SPINEL_STATUS_STACK_NATIVE__END)
-        {
-            ret = static_cast<otError>(aError - SPINEL_STATUS_STACK_NATIVE__BEGIN);
-        }
-        else
-        {
-            ret = OT_ERROR_FAILED;
-        }
-        break;
-    }
-
-    return ret;
-}
-
-static void LogIfFail(const char *aText, otError aError)
-{
-    OT_UNUSED_VARIABLE(aText);
-    OT_UNUSED_VARIABLE(aError);
-
-    if (aError != OT_ERROR_NONE)
-    {
-        otLogWarnPlat("%s: %s", aText, otThreadErrorToString(aError));
-    }
-}
-
-void SpinelInterface::Callbacks::HandleReceivedFrame(void)
-{
-    static_cast<RadioSpinel *>(this)->HandleReceivedFrame();
-}
-
-RadioSpinel::RadioSpinel(void)
-    : mInstance(NULL)
-    , mRxFrameBuffer()
-    , mSpinelInterface(*this, mRxFrameBuffer)
-    , mCmdTidsInUse(0)
-    , mCmdNextTid(1)
-    , mTxRadioTid(0)
-    , mWaitingTid(0)
-    , mWaitingKey(SPINEL_PROP_LAST_STATUS)
-    , mPropertyFormat(NULL)
-    , mExpectedCommand(0)
-    , mError(OT_ERROR_NONE)
-    , mTransmitFrame(NULL)
-    , mShortAddress(0)
-    , mPanId(0xffff)
-    , mRadioCaps(0)
-    , mChannel(0)
-    , mRxSensitivity(0)
-    , mState(kStateDisabled)
-    , mIsPromiscuous(false)
-    , mIsReady(false)
-    , mSupportsLogStream(false)
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-    , mDiagMode(false)
-    , mDiagOutput(NULL)
-    , mDiagOutputMaxLen(0)
-#endif
-    , mTxRadioEndUs(UINT64_MAX)
-{
-    mVersion[0] = '\0';
-}
-
-void RadioSpinel::Init(const otPlatformConfig &aPlatformConfig)
-{
-    otError error = OT_ERROR_NONE;
-    bool    isRcp;
-
-    SuccessOrExit(error = mSpinelInterface.Init(aPlatformConfig));
-
-    if (aPlatformConfig.mResetRadio)
-    {
-        SuccessOrExit(error = SendReset());
-    }
-
-    SuccessOrExit(error = WaitResponse());
-    VerifyOrExit(mIsReady, error = OT_ERROR_FAILED);
-
-    SuccessOrExit(error = CheckSpinelVersion());
-    SuccessOrExit(error = CheckCapabilities(isRcp));
-    SuccessOrExit(error = Get(SPINEL_PROP_NCP_VERSION, SPINEL_DATATYPE_UTF8_S, mVersion, sizeof(mVersion)));
-    SuccessOrExit(error = Get(SPINEL_PROP_HWADDR, SPINEL_DATATYPE_UINT64_S, &gNodeId));
-
-    gNodeId = ot::Encoding::BigEndian::HostSwap64(gNodeId);
-
-    if (aPlatformConfig.mRestoreDatasetFromNcp && !isRcp)
-    {
-        DieNow((RestoreDatasetFromNcp() == OT_ERROR_NONE) ? OT_EXIT_SUCCESS : OT_EXIT_FAILURE);
-    }
-
-    SuccessOrExit(error = CheckRadioCapabilities());
-
-    mRxRadioFrame.mPsdu  = mRxPsdu;
-    mTxRadioFrame.mPsdu  = mTxPsdu;
-    mAckRadioFrame.mPsdu = mAckPsdu;
-
-exit:
-    SuccessOrDie(error);
-}
-
-otError RadioSpinel::CheckSpinelVersion(void)
-{
-    otError      error = OT_ERROR_NONE;
-    unsigned int versionMajor;
-    unsigned int versionMinor;
-
-    SuccessOrExit(error =
-                      Get(SPINEL_PROP_PROTOCOL_VERSION, (SPINEL_DATATYPE_UINT_PACKED_S SPINEL_DATATYPE_UINT_PACKED_S),
-                          &versionMajor, &versionMinor));
-
-    if ((versionMajor != SPINEL_PROTOCOL_VERSION_THREAD_MAJOR) ||
-        (versionMinor != SPINEL_PROTOCOL_VERSION_THREAD_MINOR))
-    {
-        otLogCritPlat("Spinel version mismatch - PosixApp:%d.%d, RCP:%d.%d", SPINEL_PROTOCOL_VERSION_THREAD_MAJOR,
-                      SPINEL_PROTOCOL_VERSION_THREAD_MINOR, versionMajor, versionMinor);
-        DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
-    }
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::CheckCapabilities(bool &aIsRcp)
-{
-    otError        error = OT_ERROR_NONE;
-    uint8_t        capsBuffer[kCapsBufferSize];
-    const uint8_t *capsData         = capsBuffer;
-    spinel_size_t  capsLength       = sizeof(capsBuffer);
-    bool           supportsRawRadio = false;
-
-    SuccessOrExit(error = Get(SPINEL_PROP_CAPS, SPINEL_DATATYPE_DATA_S, capsBuffer, &capsLength));
-
-    aIsRcp = false;
-
-    while (capsLength > 0)
-    {
-        unsigned int   capability;
-        spinel_ssize_t unpacked;
-
-        unpacked = spinel_datatype_unpack(capsData, capsLength, SPINEL_DATATYPE_UINT_PACKED_S, &capability);
-        VerifyOrExit(unpacked > 0, error = OT_ERROR_FAILED);
-
-        if (capability == SPINEL_CAP_OPENTHREAD_LOG_METADATA)
-        {
-            mSupportsLogStream = true;
-        }
-
-        if (capability == SPINEL_CAP_MAC_RAW)
-        {
-            supportsRawRadio = true;
-        }
-
-        if (capability == SPINEL_CAP_CONFIG_RADIO)
-        {
-            aIsRcp = true;
-        }
-
-        capsData += unpacked;
-        capsLength -= static_cast<spinel_size_t>(unpacked);
-    }
-
-    if (!supportsRawRadio && aIsRcp)
-    {
-        otLogCritPlat("RCP capability list does not include support for radio/raw mode");
-        DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
-    }
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::CheckRadioCapabilities(void)
-{
-    const otRadioCaps kRequiredRadioCaps =
-        OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_CSMA_BACKOFF;
-
-    otError      error = OT_ERROR_NONE;
-    unsigned int caps;
-
-    SuccessOrExit(error = Get(SPINEL_PROP_RADIO_CAPS, SPINEL_DATATYPE_UINT_PACKED_S, &caps));
-    mRadioCaps = static_cast<otRadioCaps>(caps);
-
-    if ((mRadioCaps & kRequiredRadioCaps) != kRequiredRadioCaps)
-    {
-        otLogCritPlat("RCP does not support required capabilities: ack-timeout:%s, tx-retries:%s, CSMA-backoff:%s",
-                      (mRadioCaps & OT_RADIO_CAPS_ACK_TIMEOUT) ? "yes" : "no",
-                      (mRadioCaps & OT_RADIO_CAPS_TRANSMIT_RETRIES) ? "yes" : "no",
-                      (mRadioCaps & OT_RADIO_CAPS_CSMA_BACKOFF) ? "yes" : "no");
-
-        DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
-    }
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::RestoreDatasetFromNcp(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    otPlatSettingsInit(mInstance);
-
-    otLogInfoPlat("Trying to get saved dataset from NCP");
-    SuccessOrExit(
-        error = Get(SPINEL_PROP_THREAD_ACTIVE_DATASET, SPINEL_DATATYPE_VOID_S, &RadioSpinel::ThreadDatasetHandler));
-    SuccessOrExit(
-        error = Get(SPINEL_PROP_THREAD_PENDING_DATASET, SPINEL_DATATYPE_VOID_S, &RadioSpinel::ThreadDatasetHandler));
-
-exit:
-    otPlatSettingsDeinit(mInstance);
-    return error;
-}
-
-void RadioSpinel::Deinit(void)
-{
-    mSpinelInterface.Deinit();
-    // This allows implementing pseudo reset.
-    new (this) RadioSpinel();
-}
-
-void RadioSpinel::HandleReceivedFrame(void)
-{
-    otError        error = OT_ERROR_NONE;
-    uint8_t        header;
-    spinel_ssize_t unpacked;
-
-    unpacked = spinel_datatype_unpack(mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetLength(), "C", &header);
-
-    VerifyOrExit(unpacked > 0 && (header & SPINEL_HEADER_FLAG) == SPINEL_HEADER_FLAG &&
-                     SPINEL_HEADER_GET_IID(header) == 0,
-                 error = OT_ERROR_PARSE);
-
-    if (SPINEL_HEADER_GET_TID(header) == 0)
-    {
-        HandleNotification(mRxFrameBuffer);
-    }
-    else
-    {
-        HandleResponse(mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetLength());
-        mRxFrameBuffer.DiscardFrame();
-    }
-
-exit:
-    if (error != OT_ERROR_NONE)
-    {
-        mRxFrameBuffer.DiscardFrame();
-        otLogWarnPlat("Error handling hdlc frame: %s", otThreadErrorToString(error));
-    }
-}
-
-void RadioSpinel::HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer)
-{
-    spinel_prop_key_t key;
-    spinel_size_t     len = 0;
-    spinel_ssize_t    unpacked;
-    uint8_t *         data = NULL;
-    uint32_t          cmd;
-    uint8_t           header;
-    otError           error           = OT_ERROR_NONE;
-    bool              shouldSaveFrame = false;
-
-    unpacked = spinel_datatype_unpack(aFrameBuffer.GetFrame(), aFrameBuffer.GetLength(), "CiiD", &header, &cmd, &key,
-                                      &data, &len);
-    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-    VerifyOrExit(SPINEL_HEADER_GET_TID(header) == 0, error = OT_ERROR_PARSE);
-
-    switch (cmd)
-    {
-    case SPINEL_CMD_PROP_VALUE_IS:
-        // Some spinel properties cannot be handled during `WaitResponse()`, we must cache these events.
-        // `mWaitingTid` is released immediately after received the response. And `mWaitingKey` is be set
-        // to `SPINEL_PROP_LAST_STATUS` at the end of `WaitResponse()`.
-
-        if (!IsSafeToHandleNow(key))
-        {
-            ExitNow(shouldSaveFrame = true);
-        }
-
-        HandleValueIs(key, data, static_cast<uint16_t>(len));
-        break;
-
-    case SPINEL_CMD_PROP_VALUE_INSERTED:
-    case SPINEL_CMD_PROP_VALUE_REMOVED:
-        otLogInfoPlat("Ignored command %d", cmd);
-        break;
-
-    default:
-        ExitNow(error = OT_ERROR_PARSE);
-    }
-
-exit:
-    if (shouldSaveFrame)
-    {
-        aFrameBuffer.SaveFrame();
-    }
-    else
-    {
-        aFrameBuffer.DiscardFrame();
-    }
-
-    LogIfFail("Error processing notification", error);
-}
-
-void RadioSpinel::HandleNotification(const uint8_t *aFrame, uint16_t aLength)
-{
-    spinel_prop_key_t key;
-    spinel_size_t     len = 0;
-    spinel_ssize_t    unpacked;
-    uint8_t *         data = NULL;
-    uint32_t          cmd;
-    uint8_t           header;
-    otError           error = OT_ERROR_NONE;
-
-    unpacked = spinel_datatype_unpack(aFrame, aLength, "CiiD", &header, &cmd, &key, &data, &len);
-    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-    VerifyOrExit(SPINEL_HEADER_GET_TID(header) == 0, error = OT_ERROR_PARSE);
-    VerifyOrExit(cmd == SPINEL_CMD_PROP_VALUE_IS);
-    HandleValueIs(key, data, static_cast<uint16_t>(len));
-
-exit:
-    LogIfFail("Error processing saved notification", error);
-}
-
-void RadioSpinel::HandleResponse(const uint8_t *aBuffer, uint16_t aLength)
-{
-    spinel_prop_key_t key;
-    uint8_t *         data   = NULL;
-    spinel_size_t     len    = 0;
-    uint8_t           header = 0;
-    uint32_t          cmd    = 0;
-    spinel_ssize_t    rval   = 0;
-    otError           error  = OT_ERROR_NONE;
-
-    rval = spinel_datatype_unpack(aBuffer, aLength, "CiiD", &header, &cmd, &key, &data, &len);
-    VerifyOrExit(rval > 0 && cmd >= SPINEL_CMD_PROP_VALUE_IS && cmd <= SPINEL_CMD_PROP_VALUE_REMOVED,
-                 error = OT_ERROR_PARSE);
-
-    if (mWaitingTid == SPINEL_HEADER_GET_TID(header))
-    {
-        HandleWaitingResponse(cmd, key, data, static_cast<uint16_t>(len));
-        FreeTid(mWaitingTid);
-        mWaitingTid = 0;
-    }
-    else if (mTxRadioTid == SPINEL_HEADER_GET_TID(header))
-    {
-        if (mState == kStateTransmitting)
-        {
-            HandleTransmitDone(cmd, key, data, static_cast<uint16_t>(len));
-        }
-
-        FreeTid(mTxRadioTid);
-        mTxRadioTid = 0;
-    }
-    else
-    {
-        otLogWarnPlat("Unexpected Spinel transaction message: %u", SPINEL_HEADER_GET_TID(header));
-        error = OT_ERROR_DROP;
-    }
-
-exit:
-    LogIfFail("Error processing response", error);
-}
-
-otError RadioSpinel::ThreadDatasetHandler(const uint8_t *aBuffer, uint16_t aLength)
-{
-    otError              error = OT_ERROR_NONE;
-    otOperationalDataset opDataset;
-    bool                 isActive = ((mWaitingKey == SPINEL_PROP_THREAD_ACTIVE_DATASET) ? true : false);
-    Ncp::SpinelDecoder   decoder;
-    MeshCoP::Dataset     dataset(isActive ? MeshCoP::Tlv::kActiveTimestamp : MeshCoP::Tlv::kPendingTimestamp);
-
-    memset(&opDataset, 0, sizeof(otOperationalDataset));
-    decoder.Init(aBuffer, aLength);
-
-    while (!decoder.IsAllReadInStruct())
-    {
-        unsigned int propKey;
-
-        SuccessOrExit(error = decoder.OpenStruct());
-        SuccessOrExit(error = decoder.ReadUintPacked(propKey));
-
-        switch (static_cast<spinel_prop_key_t>(propKey))
-        {
-        case SPINEL_PROP_NET_MASTER_KEY:
-        {
-            const uint8_t *key;
-            uint16_t       len;
-
-            SuccessOrExit(error = decoder.ReadData(key, len));
-            VerifyOrExit(len == OT_MASTER_KEY_SIZE, error = OT_ERROR_INVALID_ARGS);
-            memcpy(opDataset.mMasterKey.m8, key, len);
-            opDataset.mComponents.mIsMasterKeyPresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_NET_NETWORK_NAME:
-        {
-            const char *name;
-            size_t      len;
-
-            SuccessOrExit(error = decoder.ReadUtf8(name));
-            len = StringLength(name, OT_NETWORK_NAME_MAX_SIZE);
-            memcpy(opDataset.mNetworkName.m8, name, len);
-            opDataset.mNetworkName.m8[len]              = '\0';
-            opDataset.mComponents.mIsNetworkNamePresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_NET_XPANID:
-        {
-            const uint8_t *xpanid;
-            uint16_t       len;
-
-            SuccessOrExit(error = decoder.ReadData(xpanid, len));
-            VerifyOrExit(len == OT_EXT_PAN_ID_SIZE, error = OT_ERROR_INVALID_ARGS);
-            memcpy(opDataset.mExtendedPanId.m8, xpanid, len);
-            opDataset.mComponents.mIsExtendedPanIdPresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_IPV6_ML_PREFIX:
-        {
-            const otIp6Address *addr;
-            uint8_t             prefixLen;
-
-            SuccessOrExit(error = decoder.ReadIp6Address(addr));
-            SuccessOrExit(error = decoder.ReadUint8(prefixLen));
-            VerifyOrExit(prefixLen == OT_IP6_PREFIX_BITSIZE, error = OT_ERROR_INVALID_ARGS);
-            memcpy(opDataset.mMeshLocalPrefix.m8, addr, OT_MESH_LOCAL_PREFIX_SIZE);
-            opDataset.mComponents.mIsMeshLocalPrefixPresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_DATASET_DELAY_TIMER:
-        {
-            SuccessOrExit(error = decoder.ReadUint32(opDataset.mDelay));
-            opDataset.mComponents.mIsDelayPresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_MAC_15_4_PANID:
-        {
-            SuccessOrExit(error = decoder.ReadUint16(opDataset.mPanId));
-            opDataset.mComponents.mIsPanIdPresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_PHY_CHAN:
-        {
-            uint8_t channel;
-
-            SuccessOrExit(error = decoder.ReadUint8(channel));
-            opDataset.mChannel                      = channel;
-            opDataset.mComponents.mIsChannelPresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_NET_PSKC:
-        {
-            const uint8_t *psk;
-            uint16_t       len;
-
-            SuccessOrExit(error = decoder.ReadData(psk, len));
-            VerifyOrExit(len == OT_PSKC_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
-            memcpy(opDataset.mPskc.m8, psk, OT_PSKC_MAX_SIZE);
-            opDataset.mComponents.mIsPskcPresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_DATASET_SECURITY_POLICY:
-        {
-            SuccessOrExit(error = decoder.ReadUint16(opDataset.mSecurityPolicy.mRotationTime));
-            SuccessOrExit(error = decoder.ReadUint8(opDataset.mSecurityPolicy.mFlags));
-            opDataset.mComponents.mIsSecurityPolicyPresent = true;
-            break;
-        }
-
-        case SPINEL_PROP_PHY_CHAN_SUPPORTED:
-        {
-            uint8_t channel;
-
-            opDataset.mChannelMask = 0;
-
-            while (!decoder.IsAllReadInStruct())
-            {
-                SuccessOrExit(error = decoder.ReadUint8(channel));
-                VerifyOrExit(channel <= 31, error = OT_ERROR_INVALID_ARGS);
-                opDataset.mChannelMask |= (1UL << channel);
-            }
-            opDataset.mComponents.mIsChannelMaskPresent = true;
-            break;
-        }
-
-        default:
-            break;
-        }
-
-        SuccessOrExit(error = decoder.CloseStruct());
-    }
-
-    /*
-     * Initially set Active Timestamp to 0. This is to allow the node to join the network
-     * yet retrieve the full Active Dataset from a neighboring device if one exists.
-     */
-    opDataset.mActiveTimestamp                      = 0;
-    opDataset.mComponents.mIsActiveTimestampPresent = true;
-
-    SuccessOrExit(error = dataset.Set(opDataset));
-    SuccessOrExit(error = otPlatSettingsSet(
-                      mInstance, isActive ? SettingsBase::kKeyActiveDataset : SettingsBase::kKeyPendingDataset,
-                      dataset.GetBytes(), dataset.GetSize()));
-
-exit:
-    return error;
-}
-
-void RadioSpinel::HandleWaitingResponse(uint32_t          aCommand,
-                                        spinel_prop_key_t aKey,
-                                        const uint8_t *   aBuffer,
-                                        uint16_t          aLength)
-{
-    if (aKey == SPINEL_PROP_LAST_STATUS)
-    {
-        spinel_status_t status;
-        spinel_ssize_t  unpacked = spinel_datatype_unpack(aBuffer, aLength, "i", &status);
-
-        VerifyOrExit(unpacked > 0, mError = OT_ERROR_PARSE);
-        mError = SpinelStatusToOtError(status);
-    }
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-    else if (aKey == SPINEL_PROP_NEST_STREAM_MFG)
-    {
-        spinel_ssize_t unpacked;
-
-        VerifyOrExit(mDiagOutput != NULL);
-        unpacked =
-            spinel_datatype_unpack_in_place(aBuffer, aLength, SPINEL_DATATYPE_UTF8_S, mDiagOutput, &mDiagOutputMaxLen);
-        VerifyOrExit(unpacked > 0, mError = OT_ERROR_PARSE);
-    }
-#endif
-    else if (aKey == mWaitingKey)
-    {
-        if (mPropertyFormat)
-        {
-            if (static_cast<spinel_datatype_t>(mPropertyFormat[0]) == SPINEL_DATATYPE_VOID_C)
-            {
-                // reserved SPINEL_DATATYPE_VOID_C indicate caller want to parse the spinel response itself
-                ResponseHandler handler = va_arg(mPropertyArgs, ResponseHandler);
-
-                assert(handler != NULL);
-                mError = (this->*handler)(aBuffer, aLength);
-            }
-            else
-            {
-                spinel_ssize_t unpacked =
-                    spinel_datatype_vunpack_in_place(aBuffer, aLength, mPropertyFormat, mPropertyArgs);
-
-                VerifyOrExit(unpacked > 0, mError = OT_ERROR_PARSE);
-                mError = OT_ERROR_NONE;
-            }
-        }
-        else
-        {
-            if (aCommand == mExpectedCommand)
-            {
-                mError = OT_ERROR_NONE;
-            }
-            else
-            {
-                mError = OT_ERROR_DROP;
-            }
-        }
-    }
-    else
-    {
-        mError = OT_ERROR_DROP;
-    }
-
-exit:
-    LogIfFail("Error processing result", mError);
-}
-
-void RadioSpinel::HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength)
-{
-    otError error = OT_ERROR_NONE;
-
-    if (aKey == SPINEL_PROP_STREAM_RAW)
-    {
-        SuccessOrExit(error = ParseRadioFrame(mRxRadioFrame, aBuffer, aLength));
-        RadioReceive();
-    }
-    else if (aKey == SPINEL_PROP_LAST_STATUS)
-    {
-        spinel_status_t status = SPINEL_STATUS_OK;
-        spinel_ssize_t  unpacked;
-
-        unpacked = spinel_datatype_unpack(aBuffer, aLength, "i", &status);
-        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-
-        if (status >= SPINEL_STATUS_RESET__BEGIN && status <= SPINEL_STATUS_RESET__END)
-        {
-            // If RCP crashes/resets while radio was enabled, posix app exits.
-            VerifyOrDie(!IsEnabled(), OT_EXIT_RADIO_SPINEL_RESET);
-
-            otLogInfoPlat("RCP reset: %s", spinel_status_to_cstr(status));
-            mIsReady = true;
-        }
-        else
-        {
-            otLogInfoPlat("RCP last status: %s", spinel_status_to_cstr(status));
-        }
-    }
-    else if (aKey == SPINEL_PROP_MAC_ENERGY_SCAN_RESULT)
-    {
-        uint8_t        scanChannel;
-        int8_t         maxRssi;
-        spinel_ssize_t unpacked;
-
-        unpacked = spinel_datatype_unpack(aBuffer, aLength, "Cc", &scanChannel, &maxRssi);
-
-        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-        otPlatRadioEnergyScanDone(mInstance, maxRssi);
-    }
-    else if (aKey == SPINEL_PROP_STREAM_DEBUG)
-    {
-        char           logStream[OPENTHREAD_CONFIG_NCP_SPINEL_LOG_MAX_SIZE + 1];
-        unsigned int   len = sizeof(logStream);
-        spinel_ssize_t unpacked;
-
-        unpacked = spinel_datatype_unpack_in_place(aBuffer, aLength, SPINEL_DATATYPE_DATA_S, logStream, &len);
-        assert(len < sizeof(logStream));
-        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-        logStream[len] = '\0';
-        otLogDebgPlat("RCP => %s", logStream);
-    }
-    else if ((aKey == SPINEL_PROP_STREAM_LOG) && mSupportsLogStream)
-    {
-        const char *   logString;
-        spinel_ssize_t unpacked;
-        uint8_t        logLevel;
-
-        unpacked = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_UTF8_S, &logString);
-        VerifyOrExit(unpacked >= 0, error = OT_ERROR_PARSE);
-        aBuffer += unpacked;
-        aLength -= unpacked;
-
-        unpacked = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_UINT8_S, &logLevel);
-        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-
-        switch (logLevel)
-        {
-        case SPINEL_NCP_LOG_LEVEL_EMERG:
-        case SPINEL_NCP_LOG_LEVEL_ALERT:
-        case SPINEL_NCP_LOG_LEVEL_CRIT:
-            otLogCritPlat("RCP => %s", logString);
-            break;
-
-        case SPINEL_NCP_LOG_LEVEL_ERR:
-        case SPINEL_NCP_LOG_LEVEL_WARN:
-            otLogWarnPlat("RCP => %s", logString);
-            break;
-
-        case SPINEL_NCP_LOG_LEVEL_NOTICE:
-            otLogNotePlat("RCP => %s", logString);
-            break;
-
-        case SPINEL_NCP_LOG_LEVEL_INFO:
-            otLogInfoPlat("RCP => %s", logString);
-            break;
-
-        case SPINEL_NCP_LOG_LEVEL_DEBUG:
-        default:
-            otLogDebgPlat("RCP => %s", logString);
-            break;
-        }
-    }
-
-exit:
-    LogIfFail("Failed to handle ValueIs", error);
-}
-
-otError RadioSpinel::ParseRadioFrame(otRadioFrame &aFrame, const uint8_t *aBuffer, uint16_t aLength)
-{
-    otError        error        = OT_ERROR_NONE;
-    uint16_t       flags        = 0;
-    int8_t         noiseFloor   = -128;
-    spinel_size_t  size         = OT_RADIO_FRAME_MAX_SIZE;
-    unsigned int   receiveError = 0;
-    spinel_ssize_t unpacked;
-
-    unpacked = spinel_datatype_unpack_in_place(aBuffer, aLength,
-                                               SPINEL_DATATYPE_DATA_WLEN_S                          // Frame
-                                                               SPINEL_DATATYPE_INT8_S               // RSSI
-                                                               SPINEL_DATATYPE_INT8_S               // Noise Floor
-                                                               SPINEL_DATATYPE_UINT16_S             // Flags
-                                                               SPINEL_DATATYPE_STRUCT_S(            // PHY-data
-                                                                   SPINEL_DATATYPE_UINT8_S          // 802.15.4 channel
-                                                                           SPINEL_DATATYPE_UINT8_S  // 802.15.4 LQI
-                                                                           SPINEL_DATATYPE_UINT64_S // Timestamp (us).
-                                                                   ) SPINEL_DATATYPE_STRUCT_S(      // Vendor-data
-                                                                   SPINEL_DATATYPE_UINT_PACKED_S    // Receive error
-                                                                   ),
-                                               aFrame.mPsdu, &size, &aFrame.mInfo.mRxInfo.mRssi, &noiseFloor, &flags,
-                                               &aFrame.mChannel, &aFrame.mInfo.mRxInfo.mLqi,
-                                               &aFrame.mInfo.mRxInfo.mTimestamp, &receiveError);
-
-    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-
-    if (receiveError == OT_ERROR_NONE)
-    {
-        aFrame.mLength = static_cast<uint8_t>(size);
-
-        aFrame.mInfo.mRxInfo.mAckedWithFramePending = ((flags & SPINEL_MD_FLAG_ACKED_FP) != 0);
-    }
-    else if (receiveError < OT_NUM_ERRORS)
-    {
-        error = static_cast<otError>(receiveError);
-    }
-    else
-    {
-        error = OT_ERROR_PARSE;
-    }
-
-exit:
-    LogIfFail("Handle radio frame failed", error);
-    return error;
-}
-
-void RadioSpinel::ProcessFrameQueue(void)
-{
-    uint8_t *frame = NULL;
-    uint16_t length;
-
-    while (mRxFrameBuffer.GetNextSavedFrame(frame, length) == OT_ERROR_NONE)
-    {
-        HandleNotification(frame, length);
-    }
-
-    mRxFrameBuffer.ClearSavedFrames();
-}
-
-void RadioSpinel::RadioReceive(void)
-{
-    if (!mIsPromiscuous)
-    {
-        switch (mState)
-        {
-        case kStateDisabled:
-        case kStateSleep:
-            ExitNow();
-
-        case kStateReceive:
-        case kStateTransmitting:
-        case kStateTransmitDone:
-            break;
-        }
-    }
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-    if (otPlatDiagModeGet())
-    {
-        otPlatDiagRadioReceiveDone(mInstance, &mRxRadioFrame, OT_ERROR_NONE);
-    }
-    else
-#endif
-    {
-        otPlatRadioReceiveDone(mInstance, &mRxRadioFrame, OT_ERROR_NONE);
-    }
-
-exit:
-    return;
-}
-
-void RadioSpinel::TransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError)
-{
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-    if (otPlatDiagModeGet())
-    {
-        otPlatDiagRadioTransmitDone(mInstance, aFrame, aError);
-    }
-    else
-#endif
-    {
-        otPlatRadioTxDone(mInstance, aFrame, aAckFrame, aError);
-    }
-}
-
-void RadioSpinel::UpdateFdSet(fd_set &aReadFdSet, fd_set &aWriteFdSet, int &aMaxFd, struct timeval &aTimeout)
-{
-    mSpinelInterface.UpdateFdSet(aReadFdSet, aWriteFdSet, aMaxFd, aTimeout);
-
-    if (mState == kStateTransmitting)
-    {
-        uint64_t now = platformGetTime();
-
-        if (now < mTxRadioEndUs)
-        {
-            uint64_t remain = mTxRadioEndUs - now;
-
-            if (remain < static_cast<uint64_t>(aTimeout.tv_sec * US_PER_S + aTimeout.tv_usec))
-            {
-                aTimeout.tv_sec  = static_cast<time_t>(remain / US_PER_S);
-                aTimeout.tv_usec = static_cast<suseconds_t>(remain % US_PER_S);
-            }
-        }
-        else
-        {
-            aTimeout.tv_sec  = 0;
-            aTimeout.tv_usec = 0;
-        }
-    }
-
-    if (mRxFrameBuffer.HasSavedFrame() || (mState == kStateTransmitDone))
-    {
-        aTimeout.tv_sec  = 0;
-        aTimeout.tv_usec = 0;
-    }
-}
-
-void RadioSpinel::Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet)
-{
-    if (mRxFrameBuffer.HasSavedFrame())
-    {
-        // Handle frames received and saved during `WaitResponse()`
-        ProcessFrameQueue();
-    }
-
-    mSpinelInterface.Process(aReadFdSet, aWriteFdSet);
-
-    if (mRxFrameBuffer.HasSavedFrame())
-    {
-        ProcessFrameQueue();
-    }
-
-    if (mState == kStateTransmitDone)
-    {
-        mState        = kStateReceive;
-        mTxRadioEndUs = UINT64_MAX;
-
-        TransmitDone(mTransmitFrame, (mAckRadioFrame.mLength != 0) ? &mAckRadioFrame : NULL, mTxError);
-    }
-    else if (mState == kStateTransmitting && platformGetTime() >= mTxRadioEndUs)
-    {
-        // Frame has been successfully passed to radio, but no `TransmitDone` event received within TX_WAIT_US.
-        DieNowWithMessage("radio tx timeout", OT_EXIT_FAILURE);
-    }
-}
-
-otError RadioSpinel::SetPromiscuous(bool aEnable)
-{
-    otError error;
-
-    uint8_t mode = (aEnable ? SPINEL_MAC_PROMISCUOUS_MODE_NETWORK : SPINEL_MAC_PROMISCUOUS_MODE_OFF);
-    SuccessOrExit(error = Set(SPINEL_PROP_MAC_PROMISCUOUS_MODE, SPINEL_DATATYPE_UINT8_S, mode));
-    mIsPromiscuous = aEnable;
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::SetShortAddress(uint16_t aAddress)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mShortAddress != aAddress);
-    SuccessOrExit(error = sRadioSpinel.Set(SPINEL_PROP_MAC_15_4_SADDR, SPINEL_DATATYPE_UINT16_S, aAddress));
-    mShortAddress = aAddress;
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::GetIeeeEui64(uint8_t *aIeeeEui64)
-{
-    return Get(SPINEL_PROP_HWADDR, SPINEL_DATATYPE_EUI64_S, aIeeeEui64);
-}
-
-otError RadioSpinel::SetExtendedAddress(const otExtAddress &aExtAddress)
-{
-    otError error;
-
-    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_LADDR, SPINEL_DATATYPE_EUI64_S, aExtAddress.m8));
-    mExtendedAddress = aExtAddress;
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::SetPanId(uint16_t aPanId)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mPanId != aPanId);
-    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_PANID, SPINEL_DATATYPE_UINT16_S, aPanId));
-    mPanId = aPanId;
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::EnableSrcMatch(bool aEnable)
-{
-    return Set(SPINEL_PROP_MAC_SRC_MATCH_ENABLED, SPINEL_DATATYPE_BOOL_S, aEnable);
-}
-
-otError RadioSpinel::AddSrcMatchShortEntry(const uint16_t aShortAddress)
-{
-    return Insert(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, SPINEL_DATATYPE_UINT16_S, aShortAddress);
-}
-
-otError RadioSpinel::AddSrcMatchExtEntry(const otExtAddress &aExtAddress)
-{
-    return Insert(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, SPINEL_DATATYPE_EUI64_S, aExtAddress.m8);
-}
-
-otError RadioSpinel::ClearSrcMatchShortEntry(const uint16_t aShortAddress)
-{
-    return Remove(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, SPINEL_DATATYPE_UINT16_S, aShortAddress);
-}
-
-otError RadioSpinel::ClearSrcMatchExtEntry(const otExtAddress &aExtAddress)
-{
-    return Remove(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, SPINEL_DATATYPE_EUI64_S, aExtAddress.m8);
-}
-
-otError RadioSpinel::ClearSrcMatchShortEntries(void)
-{
-    return Set(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, NULL);
-}
-
-otError RadioSpinel::ClearSrcMatchExtEntries(void)
-{
-    return Set(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, NULL);
-}
-
-otError RadioSpinel::GetTransmitPower(int8_t &aPower)
-{
-    otError error = Get(SPINEL_PROP_PHY_TX_POWER, SPINEL_DATATYPE_INT8_S, &aPower);
-
-    LogIfFail("Get transmit power failed", error);
-    return error;
-}
-
-otError RadioSpinel::GetCcaEnergyDetectThreshold(int8_t &aThreshold)
-{
-    otError error = Get(SPINEL_PROP_PHY_CCA_THRESHOLD, SPINEL_DATATYPE_INT8_S, &aThreshold);
-
-    LogIfFail("Get CCA ED threshold failed", error);
-    return error;
-}
-
-int8_t RadioSpinel::GetRssi(void)
-{
-    int8_t  rssi  = OT_RADIO_RSSI_INVALID;
-    otError error = Get(SPINEL_PROP_PHY_RSSI, SPINEL_DATATYPE_INT8_S, &rssi);
-
-    LogIfFail("Get RSSI failed", error);
-    return rssi;
-}
-
-#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
-otError RadioSpinel::SetCoexEnabled(bool aEnabled)
-{
-    return Set(SPINEL_PROP_RADIO_COEX_ENABLE, SPINEL_DATATYPE_BOOL_S, aEnabled);
-}
-
-bool RadioSpinel::IsCoexEnabled(void)
-{
-    bool    enabled;
-    otError error = Get(SPINEL_PROP_RADIO_COEX_ENABLE, SPINEL_DATATYPE_BOOL_S, &enabled);
-
-    LogIfFail("Get Coex State failed", error);
-    return enabled;
-}
-
-otError RadioSpinel::GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics)
-{
-    otError error;
-
-    error = Get(SPINEL_PROP_RADIO_COEX_METRICS,
-                SPINEL_DATATYPE_STRUCT_S(                                    // Tx Coex Metrics Structure
-                    SPINEL_DATATYPE_UINT32_S                                 // NumTxRequest
-                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantImmediate
-                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantWait
-                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantWaitActivated
-                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantWaitTimeout
-                                                SPINEL_DATATYPE_UINT32_S     // NumTxGrantDeactivatedDuringRequest
-                                                SPINEL_DATATYPE_UINT32_S     // NumTxDelayedGrant
-                                                SPINEL_DATATYPE_UINT32_S     // AvgTxRequestToGrantTime
-                    ) SPINEL_DATATYPE_STRUCT_S(                              // Rx Coex Metrics Structure
-                    SPINEL_DATATYPE_UINT32_S                                 // NumRxRequest
-                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantImmediate
-                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantWait
-                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantWaitActivated
-                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantWaitTimeout
-                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantDeactivatedDuringRequest
-                                                    SPINEL_DATATYPE_UINT32_S // NumRxDelayedGrant
-                                                    SPINEL_DATATYPE_UINT32_S // AvgRxRequestToGrantTime
-                                                    SPINEL_DATATYPE_UINT32_S // NumRxGrantNone
-                    ) SPINEL_DATATYPE_BOOL_S                                 // Stopped
-                    SPINEL_DATATYPE_UINT32_S,                                // NumGrantGlitch
-                &aCoexMetrics.mNumTxRequest, &aCoexMetrics.mNumTxGrantImmediate, &aCoexMetrics.mNumTxGrantWait,
-                &aCoexMetrics.mNumTxGrantWaitActivated, &aCoexMetrics.mNumTxGrantWaitTimeout,
-                &aCoexMetrics.mNumTxGrantDeactivatedDuringRequest, &aCoexMetrics.mNumTxDelayedGrant,
-                &aCoexMetrics.mAvgTxRequestToGrantTime, &aCoexMetrics.mNumRxRequest, &aCoexMetrics.mNumRxGrantImmediate,
-                &aCoexMetrics.mNumRxGrantWait, &aCoexMetrics.mNumRxGrantWaitActivated,
-                &aCoexMetrics.mNumRxGrantWaitTimeout, &aCoexMetrics.mNumRxGrantDeactivatedDuringRequest,
-                &aCoexMetrics.mNumRxDelayedGrant, &aCoexMetrics.mAvgRxRequestToGrantTime, &aCoexMetrics.mNumRxGrantNone,
-                &aCoexMetrics.mStopped, &aCoexMetrics.mNumGrantGlitch);
-
-    LogIfFail("Get Coex Metrics failed", error);
-    return error;
-}
-#endif
-
-otError RadioSpinel::SetTransmitPower(int8_t aPower)
-{
-    otError error = Set(SPINEL_PROP_PHY_TX_POWER, SPINEL_DATATYPE_INT8_S, aPower);
-    LogIfFail("Set transmit power failed", error);
-    return error;
-}
-
-otError RadioSpinel::SetCcaEnergyDetectThreshold(int8_t aThreshold)
-{
-    otError error = Set(SPINEL_PROP_PHY_CCA_THRESHOLD, SPINEL_DATATYPE_INT8_S, aThreshold);
-    LogIfFail("Set CCA ED threshold failed", error);
-    return error;
-}
-
-otError RadioSpinel::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration)
-{
-    otError error;
-
-    VerifyOrExit(mRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN, error = OT_ERROR_NOT_CAPABLE);
-
-    SuccessOrExit(error = Set(SPINEL_PROP_MAC_SCAN_MASK, SPINEL_DATATYPE_DATA_S, &aScanChannel, sizeof(uint8_t)));
-    SuccessOrExit(error = Set(SPINEL_PROP_MAC_SCAN_PERIOD, SPINEL_DATATYPE_UINT16_S, aScanDuration));
-    SuccessOrExit(error = Set(SPINEL_PROP_MAC_SCAN_STATE, SPINEL_DATATYPE_UINT8_S, SPINEL_SCAN_STATE_ENERGY));
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::Get(spinel_prop_key_t aKey, const char *aFormat, ...)
-{
-    otError error;
-
-    assert(mWaitingTid == 0);
-
-    mPropertyFormat = aFormat;
-    va_start(mPropertyArgs, aFormat);
-    error = RequestV(true, SPINEL_CMD_PROP_VALUE_GET, aKey, NULL, mPropertyArgs);
-    va_end(mPropertyArgs);
-    mPropertyFormat = NULL;
-
-    return error;
-}
-
-otError RadioSpinel::Set(spinel_prop_key_t aKey, const char *aFormat, ...)
-{
-    otError error;
-
-    assert(mWaitingTid == 0);
-
-    mExpectedCommand = SPINEL_CMD_PROP_VALUE_IS;
-    va_start(mPropertyArgs, aFormat);
-    error = RequestV(true, SPINEL_CMD_PROP_VALUE_SET, aKey, aFormat, mPropertyArgs);
-    va_end(mPropertyArgs);
-    mExpectedCommand = SPINEL_CMD_NOOP;
-
-    return error;
-}
-
-otError RadioSpinel::Insert(spinel_prop_key_t aKey, const char *aFormat, ...)
-{
-    otError error;
-
-    assert(mWaitingTid == 0);
-
-    mExpectedCommand = SPINEL_CMD_PROP_VALUE_INSERTED;
-    va_start(mPropertyArgs, aFormat);
-    error = RequestV(true, SPINEL_CMD_PROP_VALUE_INSERT, aKey, aFormat, mPropertyArgs);
-    va_end(mPropertyArgs);
-    mExpectedCommand = SPINEL_CMD_NOOP;
-
-    return error;
-}
-
-otError RadioSpinel::Remove(spinel_prop_key_t aKey, const char *aFormat, ...)
-{
-    otError error;
-
-    assert(mWaitingTid == 0);
-
-    mExpectedCommand = SPINEL_CMD_PROP_VALUE_REMOVED;
-    va_start(mPropertyArgs, aFormat);
-    error = RequestV(true, SPINEL_CMD_PROP_VALUE_REMOVE, aKey, aFormat, mPropertyArgs);
-    va_end(mPropertyArgs);
-    mExpectedCommand = SPINEL_CMD_NOOP;
-
-    return error;
-}
-
-otError RadioSpinel::WaitResponse(void)
-{
-    uint64_t       now     = platformGetTime();
-    uint64_t       end     = now + kMaxWaitTime * US_PER_MS;
-    struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000};
-
-    do
-    {
-        if (mSpinelInterface.WaitForFrame(timeout) == OT_ERROR_RESPONSE_TIMEOUT)
-        {
-            FreeTid(mWaitingTid);
-            mWaitingTid = 0;
-            ExitNow(mError = OT_ERROR_RESPONSE_TIMEOUT);
-        }
-
-        now = platformGetTime();
-
-        if (end > now)
-        {
-            uint64_t remain = end - now;
-
-            timeout.tv_sec  = static_cast<time_t>(remain / US_PER_S);
-            timeout.tv_usec = static_cast<suseconds_t>(remain % US_PER_S);
-        }
-        else
-        {
-            mWaitingTid = 0;
-            mError      = OT_ERROR_RESPONSE_TIMEOUT;
-        }
-    } while (mWaitingTid || !mIsReady);
-
-exit:
-    LogIfFail("Error waiting response", mError);
-    // This indicates end of waiting repsonse.
-    mWaitingKey = SPINEL_PROP_LAST_STATUS;
-    return mError;
-}
-
-spinel_tid_t RadioSpinel::GetNextTid(void)
-{
-    spinel_tid_t tid = 0;
-
-    if (((1 << mCmdNextTid) & mCmdTidsInUse) == 0)
-    {
-        tid         = mCmdNextTid;
-        mCmdNextTid = SPINEL_GET_NEXT_TID(mCmdNextTid);
-        mCmdTidsInUse |= (1 << tid);
-    }
-
-    return tid;
-}
-
-otError RadioSpinel::SendReset(void)
-{
-    otError        error = OT_ERROR_NONE;
-    uint8_t        buffer[kMaxSpinelFrame];
-    spinel_ssize_t packed;
-
-    // Pack the header, command and key
-    packed =
-        spinel_datatype_pack(buffer, sizeof(buffer), "Ci", SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_RESET);
-
-    VerifyOrExit(packed > 0 && static_cast<size_t>(packed) <= sizeof(buffer), error = OT_ERROR_NO_BUFS);
-
-    SuccessOrExit(error = mSpinelInterface.SendFrame(buffer, static_cast<uint16_t>(packed)));
-
-    sleep(0);
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::SendCommand(uint32_t          aCommand,
-                                 spinel_prop_key_t aKey,
-                                 spinel_tid_t      tid,
-                                 const char *      aFormat,
-                                 va_list           args)
-{
-    otError        error = OT_ERROR_NONE;
-    uint8_t        buffer[kMaxSpinelFrame];
-    spinel_ssize_t packed;
-    uint16_t       offset;
-
-    // Pack the header, command and key
-    packed = spinel_datatype_pack(buffer, sizeof(buffer), "Cii", SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0 | tid,
-                                  aCommand, aKey);
-
-    VerifyOrExit(packed > 0 && static_cast<size_t>(packed) <= sizeof(buffer), error = OT_ERROR_NO_BUFS);
-
-    offset = static_cast<uint16_t>(packed);
-
-    // Pack the data (if any)
-    if (aFormat)
-    {
-        packed = spinel_datatype_vpack(buffer + offset, sizeof(buffer) - offset, aFormat, args);
-        VerifyOrExit(packed > 0 && static_cast<size_t>(packed + offset) <= sizeof(buffer), error = OT_ERROR_NO_BUFS);
-
-        offset += static_cast<uint16_t>(packed);
-    }
-
-    error = mSpinelInterface.SendFrame(buffer, offset);
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::RequestV(bool aWait, uint32_t command, spinel_prop_key_t aKey, const char *aFormat, va_list aArgs)
-{
-    otError      error = OT_ERROR_NONE;
-    spinel_tid_t tid   = (aWait ? GetNextTid() : 0);
-
-    VerifyOrExit(!aWait || tid > 0, error = OT_ERROR_BUSY);
-
-    error = SendCommand(command, aKey, tid, aFormat, aArgs);
-    VerifyOrExit(error == OT_ERROR_NONE);
-
-    if (aKey == SPINEL_PROP_STREAM_RAW)
-    {
-        // not allowed to send another frame before the last frame is done.
-        assert(mTxRadioTid == 0);
-        VerifyOrExit(mTxRadioTid == 0, error = OT_ERROR_BUSY);
-        mTxRadioTid = tid;
-    }
-    else if (aWait)
-    {
-        mWaitingKey = aKey;
-        mWaitingTid = tid;
-        error       = WaitResponse();
-    }
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::Request(bool aWait, uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, ...)
-{
-    va_list args;
-    va_start(args, aFormat);
-    otError status = RequestV(aWait, aCommand, aKey, aFormat, args);
-    va_end(args);
-    return status;
-}
-
-void RadioSpinel::HandleTransmitDone(uint32_t          aCommand,
-                                     spinel_prop_key_t aKey,
-                                     const uint8_t *   aBuffer,
-                                     uint16_t          aLength)
-{
-    otError         error  = OT_ERROR_NONE;
-    spinel_status_t status = SPINEL_STATUS_OK;
-    spinel_ssize_t  unpacked;
-
-    VerifyOrExit(aCommand == SPINEL_CMD_PROP_VALUE_IS && aKey == SPINEL_PROP_LAST_STATUS, error = OT_ERROR_FAILED);
-
-    unpacked = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_UINT_PACKED_S, &status);
-    VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-
-    aBuffer += unpacked;
-    aLength -= static_cast<uint16_t>(unpacked);
-
-    if (status == SPINEL_STATUS_OK)
-    {
-        bool framePending = false;
-        unpacked          = spinel_datatype_unpack(aBuffer, aLength, SPINEL_DATATYPE_BOOL_S, &framePending);
-        OT_UNUSED_VARIABLE(framePending);
-        VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
-
-        aBuffer += unpacked;
-        aLength -= static_cast<spinel_size_t>(unpacked);
-
-        if (aLength > 0)
-        {
-            SuccessOrExit(error = ParseRadioFrame(mAckRadioFrame, aBuffer, aLength));
-        }
-        else
-        {
-            mAckRadioFrame.mLength = 0;
-        }
-    }
-    else
-    {
-        error = SpinelStatusToOtError(status);
-    }
-
-exit:
-    mState   = kStateTransmitDone;
-    mTxError = error;
-    LogIfFail("Handle transmit done failed", error);
-}
-
-otError RadioSpinel::Transmit(otRadioFrame &aFrame)
-{
-    otError error = OT_ERROR_INVALID_STATE;
-
-    VerifyOrExit(mState == kStateReceive);
-
-    mTransmitFrame = &aFrame;
-
-    // `otPlatRadioTxStarted()` is triggered immediately for now, which may be earlier than real started time.
-    otPlatRadioTxStarted(mInstance, mTransmitFrame);
-
-    error = Request(true, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_STREAM_RAW,
-                    SPINEL_DATATYPE_DATA_WLEN_S             // Frame data
-                                    SPINEL_DATATYPE_UINT8_S // Channel
-                                    SPINEL_DATATYPE_UINT8_S // MaxCsmaBackoffs
-                                    SPINEL_DATATYPE_UINT8_S // MaxFrameRetries
-                                    SPINEL_DATATYPE_BOOL_S, // CsmaCaEnabled
-                    mTransmitFrame->mPsdu, mTransmitFrame->mLength, mTransmitFrame->mChannel,
-                    mTransmitFrame->mInfo.mTxInfo.mMaxCsmaBackoffs, mTransmitFrame->mInfo.mTxInfo.mMaxFrameRetries,
-                    mTransmitFrame->mInfo.mTxInfo.mCsmaCaEnabled);
-
-    if (error == OT_ERROR_NONE)
-    {
-        // Waiting for `TransmitDone` event.
-        mState        = kStateTransmitting;
-        mTxRadioEndUs = platformGetTime() + TX_WAIT_US;
-    }
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::Receive(uint8_t aChannel)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(mState != kStateDisabled, error = OT_ERROR_INVALID_STATE);
-
-    if (mChannel != aChannel)
-    {
-        error = Set(SPINEL_PROP_PHY_CHAN, SPINEL_DATATYPE_UINT8_S, aChannel);
-        VerifyOrExit(error == OT_ERROR_NONE);
-        mChannel = aChannel;
-    }
-
-    if (mState == kStateSleep)
-    {
-        error = Set(SPINEL_PROP_MAC_RAW_STREAM_ENABLED, SPINEL_DATATYPE_BOOL_S, true);
-        VerifyOrExit(error == OT_ERROR_NONE);
-    }
-
-    if (mTxRadioTid != 0)
-    {
-        FreeTid(mTxRadioTid);
-        mTxRadioTid = 0;
-    }
-
-    mState = kStateReceive;
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::Sleep(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    switch (mState)
-    {
-    case kStateReceive:
-        error = sRadioSpinel.Set(SPINEL_PROP_MAC_RAW_STREAM_ENABLED, SPINEL_DATATYPE_BOOL_S, false);
-        VerifyOrExit(error == OT_ERROR_NONE);
-
-        mState = kStateSleep;
-        break;
-
-    case kStateSleep:
-        break;
-
-    default:
-        error = OT_ERROR_INVALID_STATE;
-        break;
-    }
-
-exit:
-    return error;
-}
-
-otError RadioSpinel::Enable(otInstance *aInstance)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(!IsEnabled());
-
-    mInstance = aInstance;
-
-    SuccessOrExit(error = Set(SPINEL_PROP_PHY_ENABLED, SPINEL_DATATYPE_BOOL_S, true));
-    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_PANID, SPINEL_DATATYPE_UINT16_S, mPanId));
-    SuccessOrExit(error = Set(SPINEL_PROP_MAC_15_4_SADDR, SPINEL_DATATYPE_UINT16_S, mShortAddress));
-    SuccessOrExit(error = Get(SPINEL_PROP_PHY_RX_SENSITIVITY, SPINEL_DATATYPE_INT8_S, &mRxSensitivity));
-
-    mState = kStateSleep;
-
-exit:
-    if (error != OT_ERROR_NONE)
-    {
-        otLogWarnPlat("RadioSpinel enable: %s", otThreadErrorToString(error));
-        error = OT_ERROR_FAILED;
-    }
-
-    return error;
-}
-
-otError RadioSpinel::Disable(void)
-{
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(IsEnabled());
-    VerifyOrExit(mState == kStateSleep, error = OT_ERROR_INVALID_STATE);
-
-    SuccessOrDie(sRadioSpinel.Set(SPINEL_PROP_PHY_ENABLED, SPINEL_DATATYPE_BOOL_S, false));
-    mState    = kStateDisabled;
-    mInstance = NULL;
-
-exit:
-    return error;
-}
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-otError RadioSpinel::PlatDiagProcess(const char *aString, char *aOutput, size_t aOutputMaxLen)
-{
-    otError error;
-
-    mDiagOutput       = aOutput;
-    mDiagOutputMaxLen = aOutputMaxLen;
-
-    error = Set(SPINEL_PROP_NEST_STREAM_MFG, SPINEL_DATATYPE_UTF8_S, aString);
-
-    mDiagOutput       = NULL;
-    mDiagOutputMaxLen = 0;
-
-    return error;
-}
-#endif
-
-uint32_t RadioSpinel::GetRadioChannelMask(bool aPreferred)
-{
-    uint8_t        maskBuffer[kChannelMaskBufferSize];
-    otError        error       = OT_ERROR_NONE;
-    uint32_t       channelMask = 0;
-    const uint8_t *maskData    = maskBuffer;
-    spinel_size_t  maskLength  = sizeof(maskBuffer);
-
-    SuccessOrDie(Get(aPreferred ? SPINEL_PROP_PHY_CHAN_PREFERRED : SPINEL_PROP_PHY_CHAN_SUPPORTED,
-                     SPINEL_DATATYPE_DATA_S, maskBuffer, &maskLength));
-
-    while (maskLength > 0)
-    {
-        uint8_t        channel;
-        spinel_ssize_t unpacked;
-
-        unpacked = spinel_datatype_unpack(maskData, maskLength, SPINEL_DATATYPE_UINT8_S, &channel);
-        VerifyOrExit(unpacked > 0, error = OT_ERROR_FAILED);
-        VerifyOrExit(channel < kChannelMaskBufferSize, error = OT_ERROR_PARSE);
-        channelMask |= (1UL << channel);
-
-        maskData += unpacked;
-        maskLength -= static_cast<spinel_size_t>(unpacked);
-    }
-
-exit:
-    LogIfFail("Get radio channel mask failed", error);
-    return channelMask;
-}
-
-otRadioState RadioSpinel::GetState(void) const
-{
-    static const otRadioState sOtRadioStateMap[] = {
-        OT_RADIO_STATE_DISABLED, OT_RADIO_STATE_SLEEP,    OT_RADIO_STATE_RECEIVE,
-        OT_RADIO_STATE_TRANSMIT, OT_RADIO_STATE_TRANSMIT,
-    };
-
-    return sOtRadioStateMap[mState];
-}
-
-} // namespace PosixApp
-} // namespace ot
-
-void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
-{
-    SuccessOrDie(sRadioSpinel.GetIeeeEui64(aIeeeEui64));
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
-{
-    SuccessOrDie(sRadioSpinel.SetPanId(panid));
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress)
-{
-    otExtAddress addr;
-
-    for (size_t i = 0; i < sizeof(addr); i++)
-    {
-        addr.m8[i] = aAddress->m8[sizeof(addr) - 1 - i];
-    }
-
-    SuccessOrDie(sRadioSpinel.SetExtendedAddress(addr));
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
-{
-    SuccessOrDie(sRadioSpinel.SetShortAddress(aAddress));
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
-{
-    SuccessOrDie(sRadioSpinel.SetPromiscuous(aEnable));
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void platformRadioInit(const otPlatformConfig *aPlatformConfig)
-{
-    sRadioSpinel.Init(*aPlatformConfig);
-}
-
-void platformRadioDeinit(void)
-{
-    sRadioSpinel.Deinit();
-}
-
-bool otPlatRadioIsEnabled(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.IsEnabled();
-}
-
-otError otPlatRadioEnable(otInstance *aInstance)
-{
-    return sRadioSpinel.Enable(aInstance);
-}
-
-otError otPlatRadioDisable(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.Disable();
-}
-
-otError otPlatRadioSleep(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.Sleep();
-}
-
-otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.Receive(aChannel);
-}
-
-otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.Transmit(*aFrame);
-}
-
-otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return &sRadioSpinel.GetTransmitFrame();
-}
-
-int8_t otPlatRadioGetRssi(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetRssi();
-}
-
-otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetRadioCaps();
-}
-
-const char *otPlatRadioGetVersionString(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetVersion();
-}
-
-bool otPlatRadioGetPromiscuous(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.IsPromiscuous();
-}
-
-void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd, struct timeval *aTimeout)
-{
-    sRadioSpinel.UpdateFdSet(*aReadFdSet, *aWriteFdSet, *aMaxFd, *aTimeout);
-}
-
-void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
-{
-    sRadioSpinel.Process(*aReadFdSet, *aWriteFdSet);
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
-{
-    SuccessOrDie(sRadioSpinel.EnableSrcMatch(aEnable));
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.AddSrcMatchShortEntry(aShortAddress);
-}
-
-otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
-{
-    otExtAddress addr;
-
-    for (size_t i = 0; i < sizeof(addr); i++)
-    {
-        addr.m8[i] = aExtAddress->m8[sizeof(addr) - 1 - i];
-    }
-
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.AddSrcMatchExtEntry(addr);
-}
-
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.ClearSrcMatchShortEntry(aShortAddress);
-}
-
-otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
-{
-    otExtAddress addr;
-
-    for (size_t i = 0; i < sizeof(addr); i++)
-    {
-        addr.m8[i] = aExtAddress->m8[sizeof(addr) - 1 - i];
-    }
-
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.ClearSrcMatchExtEntry(addr);
-}
-
-void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
-{
-    SuccessOrDie(sRadioSpinel.ClearSrcMatchShortEntries());
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
-{
-    SuccessOrDie(sRadioSpinel.ClearSrcMatchExtEntries());
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.EnergyScan(aScanChannel, aScanDuration);
-}
-
-otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
-{
-    assert(aPower != NULL);
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetTransmitPower(*aPower);
-}
-
-otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.SetTransmitPower(aPower);
-}
-
-otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
-{
-    assert(aThreshold != NULL);
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetCcaEnergyDetectThreshold(*aThreshold);
-}
-
-otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.SetCcaEnergyDetectThreshold(aThreshold);
-}
-
-int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetReceiveSensitivity();
-}
-
-#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
-otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.SetCoexEnabled(aEnabled);
-}
-
-bool otPlatRadioIsCoexEnabled(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.IsCoexEnabled();
-}
-
-otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    otError error = OT_ERROR_NONE;
-
-    VerifyOrExit(aCoexMetrics != NULL, error = OT_ERROR_INVALID_ARGS);
-
-    error = sRadioSpinel.GetCoexMetrics(*aCoexMetrics);
-
-exit:
-    return error;
-}
-#endif
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-void ot::PosixApp::RadioSpinel::Process(const Event &aEvent)
-{
-    if (mRxFrameBuffer.HasSavedFrame())
-    {
-        ProcessFrameQueue();
-    }
-
-    // The current event can be other event types
-    if (aEvent.mEvent == OT_SIM_EVENT_RADIO_SPINEL_WRITE)
-    {
-        mSpinelInterface.ProcessReadData(aEvent.mData, aEvent.mDataLength);
-    }
-
-    if (mRxFrameBuffer.HasSavedFrame())
-    {
-        ProcessFrameQueue();
-    }
-
-    if (mState == kStateTransmitDone)
-    {
-        mState        = kStateReceive;
-        mTxRadioEndUs = UINT64_MAX;
-
-        TransmitDone(mTransmitFrame, (mAckRadioFrame.mLength != 0) ? &mAckRadioFrame : NULL, mTxError);
-    }
-    else if (mState == kStateTransmitting && platformGetTime() >= mTxRadioEndUs)
-    {
-        // Frame has been successfully passed to radio, but no `TransmitDone` event received within TX_WAIT_US.
-        DieNowWithMessage("radio tx timeout", OT_EXIT_FAILURE);
-    }
-}
-
-void platformSimRadioSpinelProcess(otInstance *aInstance, const struct Event *aEvent)
-{
-    sRadioSpinel.Process(*aEvent);
-    OT_UNUSED_VARIABLE(aInstance);
-}
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    // deliver the platform specific diags commands to radio only ncp.
-    OT_UNUSED_VARIABLE(aInstance);
-    char  cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE] = {'\0'};
-    char *cur                                              = cmd;
-    char *end                                              = cmd + sizeof(cmd);
-
-    for (int index = 0; index < argc; index++)
-    {
-        cur += snprintf(cur, static_cast<size_t>(end - cur), "%s ", argv[index]);
-    }
-
-    sRadioSpinel.PlatDiagProcess(cmd, aOutput, aOutputMaxLen);
-}
-
-void otPlatDiagModeSet(bool aMode)
-{
-    SuccessOrExit(sRadioSpinel.PlatDiagProcess(aMode ? "start" : "stop", NULL, 0));
-    sRadioSpinel.SetDiagEnabled(aMode);
-
-exit:
-    return;
-}
-
-bool otPlatDiagModeGet(void)
-{
-    return sRadioSpinel.IsDiagEnabled();
-}
-
-void otPlatDiagTxPowerSet(int8_t aTxPower)
-{
-    char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
-
-    snprintf(cmd, sizeof(cmd), "power %d", aTxPower);
-    SuccessOrExit(sRadioSpinel.PlatDiagProcess(cmd, NULL, 0));
-
-exit:
-    return;
-}
-
-void otPlatDiagChannelSet(uint8_t aChannel)
-{
-    char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
-
-    snprintf(cmd, sizeof(cmd), "channel %d", aChannel);
-    SuccessOrExit(sRadioSpinel.PlatDiagProcess(cmd, NULL, 0));
-
-exit:
-    return;
-}
-
-void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aFrame);
-    OT_UNUSED_VARIABLE(aError);
-}
-
-void otPlatDiagAlarmCallback(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
-#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
-
-uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetRadioChannelMask(false);
-}
-
-uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetRadioChannelMask(true);
-}
-
-otRadioState otPlatRadioGetState(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return sRadioSpinel.GetState();
-}
diff --git a/src/posix/platform/radio_spinel.hpp b/src/posix/platform/radio_spinel.hpp
deleted file mode 100644
index 76761ae..0000000
--- a/src/posix/platform/radio_spinel.hpp
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- *  Copyright (c) 2018, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes definitions for the spinel based radio transceiver.
- */
-
-#ifndef RADIO_SPINEL_HPP_
-#define RADIO_SPINEL_HPP_
-
-#include <openthread/platform/radio.h>
-
-#if OPENTHREAD_POSIX_RCP_UART_ENABLE
-#include "hdlc_interface.hpp"
-#endif
-
-#if OPENTHREAD_POSIX_RCP_SPI_ENABLE
-#include "spi_interface.hpp"
-#endif
-
-#include "spinel_interface.hpp"
-#include "ncp/ncp_config.h"
-#include "ncp/spinel.h"
-
-namespace ot {
-namespace PosixApp {
-
-class RadioSpinel : public SpinelInterface::Callbacks
-{
-public:
-    /**
-     * This constructor initializes the spinel based OpenThread transceiver.
-     *
-     */
-    RadioSpinel(void);
-
-    /**
-     * Initialize this radio transceiver.
-     *
-     * @param[in]  aPlatformConfig  Platform configuration structure.
-     *
-     */
-    void Init(const otPlatformConfig &aPlatformConfig);
-
-    /**
-     * Deinitialize this radio transceiver.
-     *
-     */
-    void Deinit(void);
-
-    /**
-     * This method gets the status of promiscuous mode.
-     *
-     * @retval true   Promiscuous mode is enabled.
-     * @retval false  Promiscuous mode is disabled.
-     *
-     */
-    bool IsPromiscuous(void) const { return mIsPromiscuous; }
-
-    /**
-     * This method sets the status of promiscuous mode.
-     *
-     * @param[in]   aEnable     Whether to enable or disable promiscuous mode.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError SetPromiscuous(bool aEnable);
-
-    /**
-     * This method sets the Short Address for address filtering.
-     *
-     * @param[in] aShortAddress  The IEEE 802.15.4 Short Address.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError SetShortAddress(uint16_t aAddress);
-
-    /**
-     * This method gets the factory-assigned IEEE EUI-64 for this transceiver.
-     *
-     * @param[in]  aInstance   The OpenThread instance structure.
-     * @param[out] aIeeeEui64  A pointer to the factory-assigned IEEE EUI-64.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError GetIeeeEui64(uint8_t *aIeeeEui64);
-
-    /**
-     * This method sets the Extended Address for address filtering.
-     *
-     * @param[in] aExtAddress  A pointer to the IEEE 802.15.4 Extended Address stored in little-endian byte order.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError SetExtendedAddress(const otExtAddress &aAddress);
-
-    /**
-     * This method sets the PAN ID for address filtering.
-     *
-     * @param[in]   aPanId  The IEEE 802.15.4 PAN ID.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError SetPanId(uint16_t aPanId);
-
-    /**
-     * This method gets the radio's transmit power in dBm.
-     *
-     * @param[out]  aPower    The transmit power in dBm.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError GetTransmitPower(int8_t &aPower);
-
-    /**
-     * This method sets the radio's transmit power in dBm.
-     *
-     * @param[in]   aPower     The transmit power in dBm.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError SetTransmitPower(int8_t aPower);
-
-    /**
-     * This method gets the radio's CCA ED threshold in dBm.
-     *
-     * @param[out]  aThreshold    The CCA ED threshold in dBm.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError GetCcaEnergyDetectThreshold(int8_t &aThreshold);
-
-    /**
-     * This method sets the radio's CCA ED threshold in dBm.
-     *
-     * @param[in]   aThreshold     The CCA ED threshold in dBm.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError SetCcaEnergyDetectThreshold(int8_t aThreshold);
-
-    /**
-     * This method returns the radio sw version string.
-     *
-     * @returns A pointer to the radio version string.
-     *
-     */
-    const char *GetVersion(void) const { return mVersion; }
-
-    /**
-     * This method returns the radio capabilities.
-     *
-     * @returns The radio capability bit vector.
-     *
-     */
-    otRadioCaps GetRadioCaps(void) const { return mRadioCaps; }
-
-    /**
-     * This method gets the most recent RSSI measurement.
-     *
-     * @returns The RSSI in dBm when it is valid.  127 when RSSI is invalid.
-     */
-    int8_t GetRssi(void);
-
-    /**
-     * This method returns the radio receive sensitivity value.
-     *
-     * @returns The radio receive sensitivity value in dBm.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    int8_t GetReceiveSensitivity(void) const { return mRxSensitivity; }
-
-    /**
-     * This method gets current state of the radio.
-     *
-     * @return  Current state of the radio.
-     *
-     */
-    otRadioState GetState(void) const;
-
-#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
-    /**
-     * Enable the radio coex.
-     *
-     * @param[in] aInstance  The OpenThread instance structure.
-     * @param[in] aEnabled   TRUE to enable the radio coex, FALSE otherwise.
-     *
-     * @retval OT_ERROR_NONE     Successfully enabled.
-     * @retval OT_ERROR_FAILED   The radio coex could not be enabled.
-     *
-     */
-    otError SetCoexEnabled(bool aEnabled);
-
-    /**
-     * Check whether radio coex is enabled or not.
-     *
-     * @param[in] aInstance  The OpenThread instance structure.
-     *
-     * @returns TRUE if the radio coex is enabled, FALSE otherwise.
-     *
-     */
-    bool IsCoexEnabled(void);
-
-    /**
-     * This method retrieves the radio coexistence metrics.
-     *
-     * @param[out] aCoexMetrics  A reference to the coexistence metrics structure.
-     *
-     * @retval OT_ERROR_NONE          Successfully retrieved the coex metrics.
-     * @retval OT_ERROR_INVALID_ARGS  @p aCoexMetrics was NULL.
-     *
-     */
-    otError GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics);
-#endif
-
-    /**
-     * This method returns a reference to the transmit buffer.
-     *
-     * The caller forms the IEEE 802.15.4 frame in this buffer then calls otPlatRadioTransmit() to request transmission.
-     *
-     * @returns A reference to the transmit buffer.
-     *
-     */
-    otRadioFrame &GetTransmitFrame(void) { return mTxRadioFrame; }
-
-    /**
-     * This method enables or disables source address match feature.
-     *
-     * @param[in]  aEnable     Enable/disable source address match feature.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError EnableSrcMatch(bool aEnable);
-
-    /**
-     * This method adds a short address to the source address match table.
-     *
-     * @param[in]  aInstance      The OpenThread instance structure.
-     * @param[in]  aShortAddress  The short address to be added.
-     *
-     * @retval  OT_ERROR_NONE               Successfully added short address to the source match table.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     * @retval  OT_ERROR_NO_BUFS            No available entry in the source match table.
-     */
-    otError AddSrcMatchShortEntry(const uint16_t aShortAddress);
-
-    /**
-     * This method removes a short address from the source address match table.
-     *
-     * @param[in]  aInstance      The OpenThread instance structure.
-     * @param[in]  aShortAddress  The short address to be removed.
-     *
-     * @retval  OT_ERROR_NONE               Successfully removed short address from the source match table.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     * @retval  OT_ERROR_NO_ADDRESS         The short address is not in source address match table.
-     */
-    otError ClearSrcMatchShortEntry(const uint16_t aShortAddress);
-
-    /**
-     * Clear all short addresses from the source address match table.
-     *
-     * @param[in]  aInstance   The OpenThread instance structure.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError ClearSrcMatchShortEntries(void);
-
-    /**
-     * Add an extended address to the source address match table.
-     *
-     * @param[in]  aInstance    The OpenThread instance structure.
-     * @param[in]  aExtAddress  The extended address to be added stored in little-endian byte order.
-     *
-     * @retval  OT_ERROR_NONE               Successfully added extended address to the source match table.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     * @retval  OT_ERROR_NO_BUFS            No available entry in the source match table.
-     */
-    otError AddSrcMatchExtEntry(const otExtAddress &aExtAddress);
-
-    /**
-     * Remove an extended address from the source address match table.
-     *
-     * @param[in]  aInstance    The OpenThread instance structure.
-     * @param[in]  aExtAddress  The extended address to be removed stored in little-endian byte order.
-     *
-     * @retval  OT_ERROR_NONE               Successfully removed the extended address from the source match table.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     * @retval  OT_ERROR_NO_ADDRESS         The extended address is not in source address match table.
-     */
-    otError ClearSrcMatchExtEntry(const otExtAddress &aExtAddress);
-
-    /**
-     * Clear all the extended/long addresses from source address match table.
-     *
-     * @param[in]  aInstance   The OpenThread instance structure.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError ClearSrcMatchExtEntries(void);
-
-    /**
-     * This method begins the energy scan sequence on the radio.
-     *
-     * @param[in]  aScanChannel     The channel to perform the energy scan on.
-     * @param[in]  aScanDuration    The duration, in milliseconds, for the channel to be scanned.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration);
-
-    /**
-     * This method switches the radio state from Receive to Transmit.
-     *
-     * @param[in] aFrame     A reference to the transmitted frame.
-     *
-     * @retval  OT_ERROR_NONE               Successfully transitioned to Transmit.
-     * @retval  OT_ERROR_BUSY               Failed due to another transmission is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     * @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state.
-     */
-    otError Transmit(otRadioFrame &aFrame);
-
-    /**
-     * This method switches the radio state from Sleep to Receive.
-     *
-     * @param[in]  aChannel   The channel to use for receiving.
-     *
-     * @retval OT_ERROR_NONE          Successfully transitioned to Receive.
-     * @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting.
-     *
-     */
-    otError Receive(uint8_t aChannel);
-
-    /**
-     * This method switches the radio state from Receive to Sleep.
-     *
-     * @retval OT_ERROR_NONE          Successfully transitioned to Sleep.
-     * @retval OT_ERROR_BUSY          The radio was transmitting
-     * @retval OT_ERROR_INVALID_STATE The radio was disabled
-     *
-     */
-    otError Sleep(void);
-
-    /**
-     * Enable the radio.
-     *
-     * @param[in]   aInstance   A pointer to the OpenThread instance.
-     *
-     * @retval OT_ERROR_NONE     Successfully enabled.
-     * @retval OT_ERROR_FAILED   The radio could not be enabled.
-     *
-     */
-    otError Enable(otInstance *aInstance);
-
-    /**
-     * Disable the radio.
-     *
-     * @retval  OT_ERROR_NONE               Successfully transitioned to Disabled.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError Disable(void);
-
-    /**
-     * This method checks whether radio is enabled or not.
-     *
-     * @returns TRUE if the radio is enabled, FALSE otherwise.
-     *
-     */
-    bool IsEnabled(void) const { return mState != kStateDisabled; }
-
-    /**
-     * This method updates the file descriptor sets with file descriptors used by the radio driver.
-     *
-     * @param[inout]  aReadFdSet   A reference to the read file descriptors.
-     * @param[inout]  aWriteFdSet  A reference to the write file descriptors.
-     * @param[inout]  aMaxFd       A reference to the max file descriptor.
-     * @param[inout]  aTimeout     A reference to the timeout.
-     *
-     */
-    void UpdateFdSet(fd_set &aReadFdSet, fd_set &aWriteFdSet, int &aMaxFd, struct timeval &aTimeout);
-
-    /**
-     * This method performs radio driver processing.
-     *
-     * @param[in]   aReadFdSet      A reference to the read file descriptors.
-     * @param[in]   aWriteFdSet     A reference to the write file descriptors.
-     *
-     */
-    void Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet);
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-    /**
-     * This method performs radio spinel processing in simulation mode.
-     *
-     * @param[in]   aEvent  A reference to the current received simulation event.
-     *
-     */
-    void Process(const struct Event &aEvent);
-
-    /**
-     * This method updates the @p aTimeout for processing radio spinel in simulation mode.
-     *
-     * @param[out]   aTimeout    A reference to the current timeout.
-     *
-     */
-    void Update(struct timeval &aTimeout);
-#endif
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-    /**
-     * This method enables/disables the factory diagnostics mode.
-     *
-     * @param[in]  aMode  TRUE to enable diagnostics mode, FALSE otherwise.
-     *
-     */
-    void SetDiagEnabled(bool aMode) { mDiagMode = aMode; }
-
-    /**
-     * This method indicates whether or not factory diagnostics mode is enabled.
-     *
-     * @returns TRUE if factory diagnostics mode is enabled, FALSE otherwise.
-     *
-     */
-    bool IsDiagEnabled(void) const { return mDiagMode; }
-
-    /**
-     * This method processes platform diagnostics commands.
-     *
-     * @param[in]   aString         A NULL-terminated input string.
-     * @param[out]  aOutput         The diagnostics execution result.
-     * @param[in]   aOutputMaxLen   The output buffer size.
-     *
-     * @retval  OT_ERROR_NONE               Succeeded.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError PlatDiagProcess(const char *aString, char *aOutput, size_t aOutputMaxLen);
-#endif
-
-    /**
-     * This method returns the radio channel mask.
-     *
-     * @param[in]   aPreferred  TRUE to get preferred channel mask, FALSE to get supported channel mask.
-     *
-     * @returns The radio channel mask according to @aPreferred:
-     *   The radio supported channel mask that the device is allowed to be on.
-     *   The radio preferred channel mask that the device prefers to form on.
-     *
-     */
-    uint32_t GetRadioChannelMask(bool aPreferred);
-
-    /**
-     * This method processes a received Spinel frame.
-     *
-     * The newly received frame is available in `RxFrameBuffer` from `SpinelInterface::GetRxFrameBuffer()`.
-     *
-     */
-    void HandleReceivedFrame(void);
-
-private:
-    enum
-    {
-        kMaxSpinelFrame        = SpinelInterface::kMaxFrameSize,
-        kMaxWaitTime           = 2000, ///< Max time to wait for response in milliseconds.
-        kVersionStringSize     = 128,  ///< Max size of version string.
-        kCapsBufferSize        = 100,  ///< Max buffer size used to store `SPINEL_PROP_CAPS` value.
-        kChannelMaskBufferSize = 32,   ///< Max buffer size used to store `SPINEL_PROP_PHY_CHAN_SUPPORTED` value.
-    };
-
-    enum State
-    {
-        kStateDisabled,     ///< Radio is disabled.
-        kStateSleep,        ///< Radio is sleep.
-        kStateReceive,      ///< Radio is in receive mode.
-        kStateTransmitting, ///< Frame passed to radio for transmission, waiting for done event from radio.
-        kStateTransmitDone, ///< Radio indicated frame transmission is done.
-    };
-
-    typedef otError (RadioSpinel::*ResponseHandler)(const uint8_t *aBuffer, uint16_t aLength);
-
-    otError CheckSpinelVersion(void);
-    otError CheckCapabilities(bool &aIsRcp);
-    otError CheckRadioCapabilities(void);
-    void    ProcessFrameQueue(void);
-
-    /**
-     * This method tries to retrieve a spinel property from OpenThread transceiver.
-     *
-     * @param[in]   aKey        Spinel property key.
-     * @param[in]   aFormat     Spinel formatter to unpack property value.
-     * @param[out]  ...         Variable arguments list.
-     *
-     * @retval  OT_ERROR_NONE               Successfully got the property.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError Get(spinel_prop_key_t aKey, const char *aFormat, ...);
-
-    /**
-     * This method tries to update a spinel property of OpenThread transceiver.
-     *
-     * @param[in]   aKey        Spinel property key.
-     * @param[in]   aFormat     Spinel formatter to pack property value.
-     * @param[in]   ...         Variable arguments list.
-     *
-     * @retval  OT_ERROR_NONE               Successfully set the property.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError Set(spinel_prop_key_t aKey, const char *aFormat, ...);
-
-    /**
-     * This method tries to insert a item into a spinel list property of OpenThread transceiver.
-     *
-     * @param[in]   aKey        Spinel property key.
-     * @param[in]   aFormat     Spinel formatter to pack the item.
-     * @param[in]   ...         Variable arguments list.
-     *
-     * @retval  OT_ERROR_NONE               Successfully insert item into the property.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError Insert(spinel_prop_key_t aKey, const char *aFormat, ...);
-
-    /**
-     * This method tries to remove a item from a spinel list property of OpenThread transceiver.
-     *
-     * @param[in]   aKey        Spinel property key.
-     * @param[in]   aFormat     Spinel formatter to pack the item.
-     * @param[in]   ...         Variable arguments list.
-     *
-     * @retval  OT_ERROR_NONE               Successfully removed item from the property.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     *
-     */
-    otError Remove(spinel_prop_key_t aKey, const char *aFormat, ...);
-
-    spinel_tid_t GetNextTid(void);
-    void         FreeTid(spinel_tid_t tid) { mCmdTidsInUse &= ~(1 << tid); }
-
-    otError RequestV(bool aWait, uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, va_list aArgs);
-    otError Request(bool aWait, uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, ...);
-    otError WaitResponse(void);
-    otError SendReset(void);
-    otError SendCommand(uint32_t          command,
-                        spinel_prop_key_t key,
-                        spinel_tid_t      tid,
-                        const char *      pack_format,
-                        va_list           args);
-    otError ParseRadioFrame(otRadioFrame &aFrame, const uint8_t *aBuffer, uint16_t aLength);
-    otError ThreadDatasetHandler(const uint8_t *aBuffer, uint16_t aLength);
-
-    /**
-     * This method returns if the property changed event is safe to be handled now.
-     *
-     * If a property handler will go up to core stack, it may cause reentrant issue of `Hdlc::Decode()` and
-     * `WaitResponse()`.
-     *
-     * @param[in] aKey The identifier of the property.
-     *
-     * @returns Whether this property is safe to be handled now.
-     *
-     */
-    bool IsSafeToHandleNow(spinel_prop_key_t aKey) const
-    {
-        return !(aKey == SPINEL_PROP_STREAM_RAW || aKey == SPINEL_PROP_MAC_ENERGY_SCAN_RESULT);
-    }
-
-    void HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer);
-    void HandleNotification(const uint8_t *aBuffer, uint16_t aLength);
-    void HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
-
-    void HandleResponse(const uint8_t *aBuffer, uint16_t aLength);
-    void HandleTransmitDone(uint32_t aCommand, spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
-    void HandleWaitingResponse(uint32_t aCommand, spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
-
-    void RadioReceive(void);
-
-    void TransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError);
-
-    /**
-     * This method gets dataset from NCP radio and saves it.
-     *
-     * @retval  OT_ERROR_NONE               Successfully restore dataset.
-     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
-     * @retval  OT_ERROR_RESPONSE_TIMEOUT   Failed due to no response received from the transceiver.
-     * @retval  OT_ERROR_NOT_FOUND          Failed due to spinel property not supported in radio.
-     * @retval  OT_ERROR_FAILED             Failed due to other reasons.
-     */
-    otError RestoreDatasetFromNcp(void);
-
-    otInstance *mInstance;
-
-    SpinelInterface::RxFrameBuffer mRxFrameBuffer;
-
-#if OPENTHREAD_POSIX_RCP_UART_ENABLE
-    HdlcInterface mSpinelInterface;
-#endif
-
-#if OPENTHREAD_POSIX_RCP_SPI_ENABLE
-    SpiInterface mSpinelInterface;
-#endif
-
-    uint16_t          mCmdTidsInUse;    ///< Used transaction ids.
-    spinel_tid_t      mCmdNextTid;      ///< Next available transaction id.
-    spinel_tid_t      mTxRadioTid;      ///< The transaction id used to send a radio frame.
-    spinel_tid_t      mWaitingTid;      ///< The transaction id of current transaction.
-    spinel_prop_key_t mWaitingKey;      ///< The property key of current transaction.
-    const char *      mPropertyFormat;  ///< The spinel property format of current transaction.
-    va_list           mPropertyArgs;    ///< The arguments pack or unpack spinel property of current transaction.
-    uint32_t          mExpectedCommand; ///< Expected response command of current transaction.
-    otError           mError;           ///< The result of current transaction.
-
-    uint8_t       mRxPsdu[OT_RADIO_FRAME_MAX_SIZE];
-    uint8_t       mTxPsdu[OT_RADIO_FRAME_MAX_SIZE];
-    uint8_t       mAckPsdu[OT_RADIO_FRAME_MAX_SIZE];
-    otRadioFrame  mRxRadioFrame;
-    otRadioFrame  mTxRadioFrame;
-    otRadioFrame  mAckRadioFrame;
-    otRadioFrame *mTransmitFrame; ///< Points to the frame to send
-
-    otExtAddress mExtendedAddress;
-    uint16_t     mShortAddress;
-    uint16_t     mPanId;
-    otRadioCaps  mRadioCaps;
-    uint8_t      mChannel;
-    int8_t       mRxSensitivity;
-    otError      mTxError;
-    char         mVersion[kVersionStringSize];
-
-    State mState;
-    bool  mIsPromiscuous : 1;     ///< Promiscuous mode.
-    bool  mIsReady : 1;           ///< NCP ready.
-    bool  mSupportsLogStream : 1; ///< RCP supports `LOG_STREAM` property with OpenThread log meta-data format.
-
-#if OPENTHREAD_CONFIG_DIAG_ENABLE
-    bool   mDiagMode;
-    char * mDiagOutput;
-    size_t mDiagOutputMaxLen;
-#endif
-
-    uint64_t mTxRadioEndUs;
-};
-
-} // namespace PosixApp
-} // namespace ot
-
-#endif // RADIO_SPINEL_HPP_
diff --git a/src/posix/platform/radio_url.cpp b/src/posix/platform/radio_url.cpp
new file mode 100644
index 0000000..aa21258
--- /dev/null
+++ b/src/posix/platform/radio_url.cpp
@@ -0,0 +1,106 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "posix/platform/radio_url.hpp"
+
+#include <stdio.h>
+
+#include <openthread/openthread-system.h>
+
+#include "core/common/code_utils.hpp"
+#include "posix/platform/platform-posix.h"
+
+const char *otSysGetRadioUrlHelpString(void)
+{
+#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
+#define OT_RADIO_URL_HELP_BUS                                                                                  \
+    "    spinel+spi://${PATH_TO_SPI_DEVICE}?${Parameters}\n"                                                   \
+    "Parameters:\n"                                                                                            \
+    "    gpio-int-device[=gpio-device-path]\n"                                                                 \
+    "                                  Specify a path to the Linux sysfs-exported GPIO device for the\n"       \
+    "                                  `I̅N̅T̅` pin. If not specified, `SPI` interface will fall back to\n" \
+    "                                  polling, which is inefficient.\n"                                       \
+    "    gpio-int-line[=line-offset]\n"                                                                        \
+    "                                  The offset index of `I̅N̅T̅` pin for the associated GPIO device.\n"  \
+    "                                  If not specified, `SPI` interface will fall back to polling,\n"         \
+    "                                  which is inefficient.\n"                                                \
+    "    gpio-reset-dev[=gpio-device-path]\n"                                                                  \
+    "                                  Specify a path to the Linux sysfs-exported GPIO device for the\n"       \
+    "                                  `R̅E̅S̅` pin.\n"                                                     \
+    "    gpio-reset-line[=line-offset]"                                                                        \
+    "                                  The offset index of `R̅E̅S̅` pin for the associated GPIO device.\n"  \
+    "    spi-mode[=mode]               Specify the SPI mode to use (0-3).\n"                                   \
+    "    spi-speed[=hertz]             Specify the SPI speed in hertz.\n"                                      \
+    "    spi-cs-delay[=usec]           Specify the delay after C̅S̅ assertion, in µsec.\n"                  \
+    "    spi-reset-delay[=ms]          Specify the delay after R̅E̅S̅E̅T̅ assertion, in milliseconds.\n"  \
+    "    spi-align-allowance[=n]       Specify the maximum number of 0xFF bytes to clip from start of\n"       \
+    "                                  MISO frame. Max value is 16.\n"                                         \
+    "    spi-small-packet=[n]          Specify the smallest packet we can receive in a single transaction.\n"  \
+    "                                  (larger packets will require two transactions). Default value is 32.\n"
+
+#else
+
+#define OT_RADIO_URL_HELP_BUS                                                                        \
+    "    spinel+hdlc+uart://${PATH_TO_UART_DEVICE}?${Parameters} for real uart device\n"             \
+    "    spinel+hdlc+fortpty://${PATH_TO_UART_DEVICE}?${Parameters} for forking a pty subprocess.\n" \
+    "Parameters:\n"                                                                                  \
+    "    uart-parity[=even|odd]         Uart parity config, optional.\n"                             \
+    "    uart-stop[=number-of-bits]     Uart stop bit, default is 1.\n"                              \
+    "    uart-baudrate[=baudrate]       Uart baud rate, default is 115200.\n"                        \
+    "    uart-flow-control              Enable flow control, disabled by default.\n"                 \
+    "    forkpty-arg[=argument string]  Command line arguments for subprocess, can be repeated.\n"
+
+#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
+
+#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
+#define OT_RADIO_URL_HELP_MAX_POWER_TABLE                                                                  \
+    "    max-power-table               Max power for channels in ascending order separated by commas,\n"   \
+    "                                  If the number of values is less than that of supported channels,\n" \
+    "                                  the last value will be applied to all remaining channels.\n"        \
+    "                                  Special value 0x7f disables a channel.\n"
+#else
+#define OT_RADIO_URL_HELP_MAX_POWER_TABLE
+#endif
+
+    return "RadioURL:\n" OT_RADIO_URL_HELP_BUS OT_RADIO_URL_HELP_MAX_POWER_TABLE
+           "    no-reset                      Do not send Spinel reset command to RCP on initialization.\n"
+           "    ncp-dataset                   Retrieve dataset from ncp.\n";
+}
+
+namespace ot {
+namespace Posix {
+
+RadioUrl::RadioUrl(const char *aUrl)
+{
+    VerifyOrDie(strnlen(aUrl, sizeof(mUrl)) < sizeof(mUrl), OT_EXIT_INVALID_ARGUMENTS);
+    strncpy(mUrl, aUrl, sizeof(mUrl) - 1);
+    SuccessOrDie(Url::Url::Init(mUrl));
+}
+
+} // namespace Posix
+} // namespace ot
diff --git a/src/posix/platform/radio_url.hpp b/src/posix/platform/radio_url.hpp
new file mode 100644
index 0000000..2445989
--- /dev/null
+++ b/src/posix/platform/radio_url.hpp
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef POSIX_PLATFORM_RADIO_URL_HPP_
+#define POSIX_PLATFORM_RADIO_URL_HPP_
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openthread/openthread-system.h>
+
+#include "lib/url/url.hpp"
+
+namespace ot {
+namespace Posix {
+
+/**
+ * This class implements the radio URL processing.
+ *
+ */
+class RadioUrl : public ot::Url::Url
+{
+public:
+    /**
+     * This constructor initializes the object.
+     *
+     * @param[in]   aUrl    The null-terminated URL string.
+     *
+     */
+    RadioUrl(const char *aUrl);
+
+private:
+    enum
+    {
+        kRadioUrlMaxSize = 512,
+    };
+    char mUrl[kRadioUrlMaxSize];
+};
+
+} // namespace Posix
+} // namespace ot
+
+#endif // POSIX_PLATFORM_RADIO_URL_HPP_
diff --git a/src/posix/platform/settings.cpp b/src/posix/platform/settings.cpp
index 3263af1..ec6aa79 100644
--- a/src/posix/platform/settings.cpp
+++ b/src/posix/platform/settings.cpp
@@ -32,7 +32,7 @@
  *
  */
 
-#include "openthread-core-config.h"
+#include "openthread-posix-config.h"
 #include "platform-posix.h"
 
 #include <assert.h>
@@ -45,9 +45,11 @@
 #include <unistd.h>
 
 #include <openthread/platform/misc.h>
+#include <openthread/platform/radio.h>
 #include <openthread/platform/settings.h>
 
 #include "common/code_utils.hpp"
+#include "common/encoding.hpp"
 
 static const size_t kMaxFileNameSize = sizeof(OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH) + 32;
 
@@ -55,20 +57,23 @@
 
 static otError platformSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex, int *aSwapFd);
 
-static void getSettingsFileName(char aFileName[kMaxFileNameSize], bool aSwap)
+static void getSettingsFileName(otInstance *aInstance, char aFileName[kMaxFileNameSize], bool aSwap)
 {
     const char *offset = getenv("PORT_OFFSET");
+    uint64_t    nodeId;
 
+    otPlatRadioGetIeeeEui64(aInstance, reinterpret_cast<uint8_t *>(&nodeId));
+    nodeId = ot::Encoding::BigEndian::HostSwap64(nodeId);
     snprintf(aFileName, kMaxFileNameSize, OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH "/%s_%" PRIx64 ".%s",
-             offset == NULL ? "0" : offset, gNodeId, (aSwap ? "swap" : "data"));
+             offset == nullptr ? "0" : offset, nodeId, (aSwap ? "swap" : "data"));
 }
 
-static int swapOpen(void)
+static int swapOpen(otInstance *aInstance)
 {
     char fileName[kMaxFileNameSize];
     int  fd;
 
-    getSettingsFileName(fileName, true);
+    getSettingsFileName(aInstance, fileName, true);
 
     fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
     VerifyOrDie(fd != -1, OT_EXIT_ERROR_ERRNO);
@@ -83,8 +88,10 @@
  * @param[in]   aLength Number of bytes to copy.
  *
  */
-static void swapWrite(int aFd, uint16_t aLength)
+static void swapWrite(otInstance *aInstance, int aFd, uint16_t aLength)
 {
+    OT_UNUSED_VARIABLE(aInstance);
+
     const size_t kBlockSize = 512;
     uint8_t      buffer[kBlockSize];
 
@@ -102,13 +109,13 @@
     }
 }
 
-static void swapPersist(int aFd)
+static void swapPersist(otInstance *aInstance, int aFd)
 {
     char swapFile[kMaxFileNameSize];
     char dataFile[kMaxFileNameSize];
 
-    getSettingsFileName(swapFile, true);
-    getSettingsFileName(dataFile, false);
+    getSettingsFileName(aInstance, swapFile, true);
+    getSettingsFileName(aInstance, dataFile, false);
 
     VerifyOrDie(0 == close(sSettingsFd), OT_EXIT_ERROR_ERRNO);
     VerifyOrDie(0 == fsync(aFd), OT_EXIT_ERROR_ERRNO);
@@ -117,19 +124,17 @@
     sSettingsFd = aFd;
 }
 
-static void swapDiscard(int aFd)
+static void swapDiscard(otInstance *aInstance, int aFd)
 {
     char swapFileName[kMaxFileNameSize];
 
     VerifyOrDie(0 == close(aFd), OT_EXIT_ERROR_ERRNO);
-    getSettingsFileName(swapFileName, true);
+    getSettingsFileName(aInstance, swapFileName, true);
     VerifyOrDie(0 == unlink(swapFileName), OT_EXIT_ERROR_ERRNO);
 }
 
 void otPlatSettingsInit(otInstance *aInstance)
 {
-    OT_UNUSED_VARIABLE(aInstance);
-
     otError error = OT_ERROR_NONE;
 
     {
@@ -144,7 +149,7 @@
     {
         char fileName[kMaxFileNameSize];
 
-        getSettingsFileName(fileName, false);
+        getSettingsFileName(aInstance, fileName, false);
         sSettingsFd = open(fileName, O_RDWR | O_CREAT | O_CLOEXEC, 0600);
     }
 
@@ -258,7 +263,7 @@
                     write(swapFd, aValue, aValueLength) == aValueLength,
                 OT_EXIT_FAILURE);
 
-    swapPersist(swapFd);
+    swapPersist(aInstance, swapFd);
 
     return OT_ERROR_NONE;
 }
@@ -268,12 +273,12 @@
     OT_UNUSED_VARIABLE(aInstance);
 
     off_t size   = lseek(sSettingsFd, 0, SEEK_END);
-    int   swapFd = swapOpen();
+    int   swapFd = swapOpen(aInstance);
 
     if (size > 0)
     {
         VerifyOrDie(0 == lseek(sSettingsFd, 0, SEEK_SET), OT_EXIT_ERROR_ERRNO);
-        swapWrite(swapFd, static_cast<uint16_t>(size));
+        swapWrite(aInstance, swapFd, static_cast<uint16_t>(size));
     }
 
     VerifyOrDie(write(swapFd, &aKey, sizeof(aKey)) == sizeof(aKey) &&
@@ -281,14 +286,14 @@
                     write(swapFd, aValue, aValueLength) == aValueLength,
                 OT_EXIT_FAILURE);
 
-    swapPersist(swapFd);
+    swapPersist(aInstance, swapFd);
 
     return OT_ERROR_NONE;
 }
 
 otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
 {
-    return platformSettingsDelete(aInstance, aKey, aIndex, NULL);
+    return platformSettingsDelete(aInstance, aKey, aIndex, nullptr);
 }
 
 /**
@@ -314,7 +319,7 @@
     otError error  = OT_ERROR_NOT_FOUND;
     off_t   size   = lseek(sSettingsFd, 0, SEEK_END);
     off_t   offset = lseek(sSettingsFd, 0, SEEK_SET);
-    int     swapFd = swapOpen();
+    int     swapFd = swapOpen(aInstance);
 
     assert(swapFd != -1);
     assert(offset == 0);
@@ -339,7 +344,7 @@
             if (aIndex == 0)
             {
                 VerifyOrExit(offset == lseek(sSettingsFd, length, SEEK_CUR), error = OT_ERROR_PARSE);
-                swapWrite(swapFd, static_cast<uint16_t>(size - offset));
+                swapWrite(aInstance, swapFd, static_cast<uint16_t>(size - offset));
                 error = OT_ERROR_NONE;
                 break;
             }
@@ -363,23 +368,23 @@
         assert(rval == sizeof(length));
         VerifyOrDie(rval == sizeof(length), OT_EXIT_FAILURE);
 
-        swapWrite(swapFd, length);
+        swapWrite(aInstance, swapFd, length);
     }
 
 exit:
     VerifyOrDie(error != OT_ERROR_PARSE, OT_EXIT_FAILURE);
 
-    if (aSwapFd != NULL)
+    if (aSwapFd != nullptr)
     {
         *aSwapFd = swapFd;
     }
     else if (error == OT_ERROR_NONE)
     {
-        swapPersist(swapFd);
+        swapPersist(aInstance, swapFd);
     }
     else if (error == OT_ERROR_NOT_FOUND)
     {
-        swapDiscard(swapFd);
+        swapDiscard(aInstance, swapFd);
     }
 
     return error;
@@ -397,11 +402,16 @@
 
 #if SELF_TEST
 
-uint64_t gNodeId = 1;
+void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    memset(aIeeeEui64, 0, sizeof(uint64_t));
+}
 
 int main()
 {
-    otInstance *instance = NULL;
+    otInstance *instance = nullptr;
     uint8_t     data[60];
 
     for (uint8_t i = 0; i < sizeof(data); ++i)
@@ -428,8 +438,8 @@
         uint8_t  value[sizeof(data)];
         uint16_t length = sizeof(value);
 
-        assert(otPlatSettingsGet(instance, 0, 0, NULL, NULL) == OT_ERROR_NONE);
-        assert(otPlatSettingsGet(instance, 0, 0, NULL, &length) == OT_ERROR_NONE);
+        assert(otPlatSettingsGet(instance, 0, 0, nullptr, nullptr) == OT_ERROR_NONE);
+        assert(otPlatSettingsGet(instance, 0, 0, nullptr, &length) == OT_ERROR_NONE);
         assert(length == sizeof(data) / 2);
 
         length = sizeof(value);
@@ -447,9 +457,9 @@
         assert(value[length] == 0);
 
         // wrong index
-        assert(otPlatSettingsGet(instance, 0, 1, NULL, NULL) == OT_ERROR_NOT_FOUND);
+        assert(otPlatSettingsGet(instance, 0, 1, nullptr, nullptr) == OT_ERROR_NOT_FOUND);
         // wrong key
-        assert(otPlatSettingsGet(instance, 1, 0, NULL, NULL) == OT_ERROR_NOT_FOUND);
+        assert(otPlatSettingsGet(instance, 1, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND);
     }
     otPlatSettingsWipe(instance);
 
@@ -512,7 +522,7 @@
 
         // delete all records
         assert(otPlatSettingsDelete(instance, 0, -1) == OT_ERROR_NONE);
-        assert(otPlatSettingsGet(instance, 0, 0, NULL, NULL) == OT_ERROR_NOT_FOUND);
+        assert(otPlatSettingsGet(instance, 0, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND);
     }
     otPlatSettingsWipe(instance);
 
@@ -531,7 +541,7 @@
         assert(0 == memcmp(value, data, length));
 
         assert(otPlatSettingsDelete(instance, 0, 0) == OT_ERROR_NOT_FOUND);
-        assert(otPlatSettingsGet(instance, 0, 0, NULL, NULL) == OT_ERROR_NOT_FOUND);
+        assert(otPlatSettingsGet(instance, 0, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND);
     }
     otPlatSettingsWipe(instance);
     otPlatSettingsDeinit(instance);
diff --git a/src/posix/platform/sim.c b/src/posix/platform/sim.c
deleted file mode 100644
index 5ff05d9..0000000
--- a/src/posix/platform/sim.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- *  Copyright (c) 2018, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- * @brief
- *   This file implements the posix simulation.
- */
-
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-
-#include <arpa/inet.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/select.h>
-#include <unistd.h>
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-
-static const int kWellKnownNodeId = 34;      ///< Well-known ID used by a simulated radio supporting promiscuous mode.
-static const int kBasePort        = 18000;   ///< This base port for posix app simulation.
-static const int kUsPerSecond     = 1000000; ///< Number of microseconds per second.
-
-static uint64_t sNow        = 0;  ///< Time of simulation.
-static int      sSockFd     = -1; ///< Socket used to communicating with simulator.
-static uint16_t sPortOffset = 0;  ///< Port offset for simulation.
-static int      sNodeId     = 0;  ///< Node id of this simulated device.
-
-void platformSimInit(void)
-{
-    struct sockaddr_in sockaddr;
-    char *             offset;
-
-    memset(&sockaddr, 0, sizeof(sockaddr));
-    sockaddr.sin_family = AF_INET;
-
-    offset = getenv("PORT_OFFSET");
-
-    if (offset)
-    {
-        char *endptr;
-
-        sPortOffset = (uint16_t)strtol(offset, &endptr, 0);
-
-        if (*endptr != '\0')
-        {
-            const uint8_t kMsgSize = 40;
-            char          msg[kMsgSize];
-
-            snprintf(msg, sizeof(msg), "Invalid PORT_OFFSET: %s", offset);
-            DieNowWithMessage(msg, OT_EXIT_INVALID_ARGUMENTS);
-        }
-
-        sPortOffset *= kWellKnownNodeId;
-    }
-
-    // node id is required for virtual time simulation
-    sNodeId = atoi(getenv("NODE_ID"));
-
-    sockaddr.sin_port        = htons(kBasePort + sPortOffset + sNodeId);
-    sockaddr.sin_addr.s_addr = INADDR_ANY;
-
-    sSockFd = SocketWithCloseExec(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
-    if (sSockFd == -1)
-    {
-        DieNowWithMessage("socket", OT_EXIT_ERROR_ERRNO);
-    }
-
-    if (bind(sSockFd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == -1)
-    {
-        DieNowWithMessage("bind", OT_EXIT_ERROR_ERRNO);
-    }
-}
-
-void platformSimDeinit(void)
-{
-    if (sSockFd != -1)
-    {
-        close(sSockFd);
-        sSockFd = -1;
-    }
-}
-
-static void platformSimSendEvent(struct Event *aEvent, size_t aLength)
-{
-    ssize_t            rval;
-    struct sockaddr_in sockaddr;
-
-    memset(&sockaddr, 0, sizeof(sockaddr));
-    sockaddr.sin_family = AF_INET;
-    inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr);
-    sockaddr.sin_port = htons(9000 + sPortOffset);
-
-    rval = sendto(sSockFd, aEvent, aLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
-
-    if (rval < 0)
-    {
-        DieNowWithMessage("sendto", OT_EXIT_ERROR_ERRNO);
-    }
-}
-
-void platformSimReceiveEvent(struct Event *aEvent)
-{
-    ssize_t rval = recvfrom(sSockFd, aEvent, sizeof(*aEvent), 0, NULL, NULL);
-
-    if (rval < 0 || (uint16_t)rval < offsetof(struct Event, mData))
-    {
-        DieNowWithMessage("recvfrom", (rval < 0) ? OT_EXIT_ERROR_ERRNO : OT_EXIT_FAILURE);
-    }
-
-    sNow += aEvent->mDelay;
-}
-
-void platformSimSendSleepEvent(const struct timeval *aTimeout)
-{
-    struct Event event;
-
-    event.mDelay      = (uint64_t)aTimeout->tv_sec * kUsPerSecond + (uint64_t)aTimeout->tv_usec;
-    event.mEvent      = OT_SIM_EVENT_ALARM_FIRED;
-    event.mDataLength = 0;
-
-    platformSimSendEvent(&event, offsetof(struct Event, mData));
-}
-
-void platformSimSendRadioSpinelWriteEvent(const uint8_t *aData, uint16_t aLength)
-{
-    struct Event event;
-
-    event.mDelay      = 0;
-    event.mEvent      = OT_SIM_EVENT_RADIO_SPINEL_WRITE;
-    event.mDataLength = aLength;
-
-    memcpy(event.mData, aData, aLength);
-
-    platformSimSendEvent(&event, offsetof(struct Event, mData) + event.mDataLength);
-}
-
-void platformSimUpdateFdSet(fd_set *        aReadFdSet,
-                            fd_set *        aWriteFdSet,
-                            fd_set *        aErrorFdSet,
-                            int *           aMaxFd,
-                            struct timeval *aTimeout)
-{
-    OT_UNUSED_VARIABLE(aWriteFdSet);
-    OT_UNUSED_VARIABLE(aErrorFdSet);
-    OT_UNUSED_VARIABLE(aTimeout);
-
-    FD_SET(sSockFd, aReadFdSet);
-    if (*aMaxFd < sSockFd)
-    {
-        *aMaxFd = sSockFd;
-    }
-}
-
-void platformSimProcess(otInstance *  aInstance,
-                        const fd_set *aReadFdSet,
-                        const fd_set *aWriteFdSet,
-                        const fd_set *aErrorFdSet)
-{
-    struct Event event = {0};
-
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aWriteFdSet);
-    OT_UNUSED_VARIABLE(aErrorFdSet);
-
-    if (FD_ISSET(sSockFd, aReadFdSet))
-    {
-        platformSimReceiveEvent(&event);
-    }
-
-    platformSimRadioSpinelProcess(aInstance, &event);
-}
-
-uint64_t platformGetTime(void)
-{
-    return sNow;
-}
-
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
diff --git a/src/posix/platform/spi_interface.cpp b/src/posix/platform/spi_interface.cpp
index eb3c77c..ffff0dc 100644
--- a/src/posix/platform/spi_interface.cpp
+++ b/src/posix/platform/spi_interface.cpp
@@ -31,17 +31,16 @@
  *   This file includes the implementation for the SPI interface to radio (RCP).
  */
 
-#include "openthread-core-config.h"
+#include "spi_interface.hpp"
 
 #include "platform-posix.h"
-#include "spi_interface.hpp"
 
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <inttypes.h>
 #include <signal.h>
-#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -55,16 +54,21 @@
 #include <sys/types.h>
 #include <sys/ucontext.h>
 
-#if OPENTHREAD_POSIX_RCP_SPI_ENABLE
+#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
 #include <linux/gpio.h>
 #include <linux/ioctl.h>
 #include <linux/spi/spidev.h>
 
-namespace ot {
-namespace PosixApp {
+using ot::Spinel::SpinelInterface;
 
-SpiInterface::SpiInterface(SpinelInterface::Callbacks &aCallback, SpinelInterface::RxFrameBuffer &aFrameBuffer)
-    : mCallbacks(aCallback)
+namespace ot {
+namespace Posix {
+
+SpiInterface::SpiInterface(SpinelInterface::ReceiveFrameCallback aCallback,
+                           void *                                aCallbackContext,
+                           SpinelInterface::RxFrameBuffer &      aFrameBuffer)
+    : mReceiveFrameCallback(aCallback)
+    , mReceiveFrameContext(aCallbackContext)
     , mRxFrameBuffer(aFrameBuffer)
     , mSpiDevFd(-1)
     , mResetGpioValueFd(-1)
@@ -87,29 +91,92 @@
 {
 }
 
-otError SpiInterface::Init(const otPlatformConfig &aPlatformConfig)
+otError SpiInterface::Init(const RadioUrl &aRadioUrl)
 {
-    VerifyOrDie(aPlatformConfig.mSpiAlignAllowance <= kSpiAlignAllowanceMax, OT_EXIT_FAILURE);
+    const char *spiGpioIntDevice;
+    const char *spiGpioResetDevice;
+    uint8_t     spiGpioIntLine     = 0;
+    uint8_t     spiGpioResetLine   = 0;
+    uint8_t     spiMode            = OT_PLATFORM_CONFIG_SPI_DEFAULT_MODE;
+    uint32_t    spiSpeed           = SPI_IOC_WR_MAX_SPEED_HZ;
+    uint32_t    spiResetDelay      = OT_PLATFORM_CONFIG_SPI_DEFAULT_RESET_DELAY_MS;
+    uint16_t    spiCsDelay         = OT_PLATFORM_CONFIG_SPI_DEFAULT_CS_DELAY_US;
+    uint8_t     spiAlignAllowance  = OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE;
+    uint8_t     spiSmallPacketSize = OT_PLATFORM_CONFIG_SPI_DEFAULT_SMALL_PACKET_SIZE;
+    const char *value;
 
-    mSpiCsDelayUs       = aPlatformConfig.mSpiCsDelay;
-    mSpiSmallPacketSize = aPlatformConfig.mSpiSmallPacketSize;
-    mSpiAlignAllowance  = aPlatformConfig.mSpiAlignAllowance;
+    spiGpioIntDevice   = aRadioUrl.GetValue("gpio-int-device");
+    spiGpioResetDevice = aRadioUrl.GetValue("gpio-reset-device");
+    if (!spiGpioIntDevice || !spiGpioResetDevice)
+    {
+        DieNow(OT_EXIT_INVALID_ARGUMENTS);
+    }
 
-    if (aPlatformConfig.mSpiGpioIntDevice != NULL)
+    if ((value = aRadioUrl.GetValue("gpio-int-line")))
+    {
+        spiGpioIntLine = static_cast<uint8_t>(atoi(value));
+    }
+    else
+    {
+        DieNow(OT_EXIT_INVALID_ARGUMENTS);
+    }
+    if ((value = aRadioUrl.GetValue("gpio-reset-line")))
+    {
+        spiGpioResetLine = static_cast<uint8_t>(atoi(value));
+    }
+    else
+    {
+        DieNow(OT_EXIT_INVALID_ARGUMENTS);
+    }
+    if ((value = aRadioUrl.GetValue("spi-mode")))
+    {
+        spiMode = static_cast<uint8_t>(atoi(value));
+    }
+    if ((value = aRadioUrl.GetValue("spi-speed")))
+    {
+        spiSpeed = static_cast<uint32_t>(atoi(value));
+    }
+    if ((value = aRadioUrl.GetValue("spi-reset-delay")))
+    {
+        spiResetDelay = static_cast<uint32_t>(atoi(value));
+    }
+    if ((value = aRadioUrl.GetValue("spi-cs-delay")))
+    {
+        spiCsDelay = static_cast<uint16_t>(atoi(value));
+    }
+    if ((value = aRadioUrl.GetValue("spi-align-allowance")))
+    {
+        spiAlignAllowance = static_cast<uint8_t>(atoi(value));
+    }
+    if ((value = aRadioUrl.GetValue("spi-small-packet")))
+    {
+        spiSmallPacketSize = static_cast<uint8_t>(atoi(value));
+    }
+
+    VerifyOrDie(spiAlignAllowance <= kSpiAlignAllowanceMax, OT_EXIT_FAILURE);
+
+    mSpiCsDelayUs       = spiCsDelay;
+    mSpiSmallPacketSize = spiSmallPacketSize;
+    mSpiAlignAllowance  = spiAlignAllowance;
+
+    if (spiGpioIntDevice != nullptr)
     {
         // If the interrupt pin is not set, SPI interface will use polling mode.
-        InitIntPin(aPlatformConfig.mSpiGpioIntDevice, aPlatformConfig.mSpiGpioIntLine);
+        InitIntPin(spiGpioIntDevice, spiGpioIntLine);
+    }
+    else
+    {
         otLogNotePlat("SPI interface enters polling mode.");
     }
 
-    InitResetPin(aPlatformConfig.mSpiGpioResetDevice, aPlatformConfig.mSpiGpioResetLine);
-    InitSpiDev(aPlatformConfig.mRadioFile, aPlatformConfig.mSpiMode, aPlatformConfig.mSpiSpeed);
+    InitResetPin(spiGpioResetDevice, spiGpioResetLine);
+    InitSpiDev(aRadioUrl.GetPath(), spiMode, spiSpeed);
 
     // Reset RCP chip.
     TrigerReset();
 
     // Waiting for the RCP chip starts up.
-    usleep(static_cast<useconds_t>(aPlatformConfig.mSpiResetDelay) * kUsecPerMsec);
+    usleep(static_cast<useconds_t>(spiResetDelay) * kUsecPerMsec);
 
     return OT_ERROR_NONE;
 }
@@ -203,7 +270,7 @@
 
     otLogDebgPlat("InitResetPin: charDev=%s, line=%" PRIu8, aCharDev, aLine);
 
-    VerifyOrDie((aCharDev != NULL) && (aLine < GPIOHANDLES_MAX), OT_EXIT_INVALID_ARGUMENTS);
+    VerifyOrDie((aCharDev != nullptr) && (aLine < GPIOHANDLES_MAX), OT_EXIT_INVALID_ARGUMENTS);
     VerifyOrDie((fd = open(aCharDev, O_RDWR)) != -1, OT_EXIT_ERROR_ERRNO);
     mResetGpioValueFd = SetupGpioHandle(fd, aLine, GPIOHANDLE_REQUEST_OUTPUT, label);
 
@@ -217,7 +284,7 @@
 
     otLogDebgPlat("InitIntPin: charDev=%s, line=%" PRIu8, aCharDev, aLine);
 
-    VerifyOrDie((aCharDev != NULL) && (aLine < GPIOHANDLES_MAX), OT_EXIT_INVALID_ARGUMENTS);
+    VerifyOrDie((aCharDev != nullptr) && (aLine < GPIOHANDLES_MAX), OT_EXIT_INVALID_ARGUMENTS);
     VerifyOrDie((fd = open(aCharDev, O_RDWR)) != -1, OT_EXIT_ERROR_ERRNO);
 
     mIntGpioValueFd = SetupGpioEvent(fd, aLine, GPIOHANDLE_REQUEST_INPUT, GPIOEVENT_REQUEST_FALLING_EDGE, label);
@@ -232,7 +299,7 @@
 
     otLogDebgPlat("InitSpiDev: path=%s, mode=%" PRIu8 ", speed=%" PRIu32, aPath, aMode, aSpeed);
 
-    VerifyOrDie((aPath != NULL) && (aMode <= kSpiModeMax), OT_EXIT_INVALID_ARGUMENTS);
+    VerifyOrDie((aPath != nullptr) && (aMode <= kSpiModeMax), OT_EXIT_INVALID_ARGUMENTS);
     VerifyOrDie((fd = open(aPath, O_RDWR | O_CLOEXEC)) != -1, OT_EXIT_ERROR_ERRNO);
     VerifyOrExit(ioctl(fd, SPI_IOC_WR_MODE, &aMode) != -1, LogError("ioctl(SPI_IOC_WR_MODE)"));
     VerifyOrExit(ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &aSpeed) != -1, LogError("ioctl(SPI_IOC_WR_MAX_SPEED_HZ)"));
@@ -264,18 +331,20 @@
     otLogNotePlat("Triggered hardware reset");
 }
 
-uint8_t *SpiInterface::GetRealRxFrameStart(void)
+uint8_t *SpiInterface::GetRealRxFrameStart(uint8_t *aSpiRxFrameBuffer, uint8_t aAlignAllowance, uint16_t &aSkipLength)
 {
-    uint8_t *      ret = mSpiRxFrameBuffer;
-    const uint8_t *end = mSpiRxFrameBuffer + mSpiAlignAllowance;
+    uint8_t *      start = aSpiRxFrameBuffer;
+    const uint8_t *end   = aSpiRxFrameBuffer + aAlignAllowance;
 
-    for (; ret != end && ret[0] == 0xff; ret++)
+    for (; start != end && start[0] == 0xff; start++)
         ;
 
-    return ret;
+    aSkipLength = static_cast<uint16_t>(start - aSpiRxFrameBuffer);
+
+    return start;
 }
 
-otError SpiInterface::DoSpiTransfer(uint32_t aLength)
+otError SpiInterface::DoSpiTransfer(uint8_t *aSpiRxFrameBuffer, uint32_t aTransferLength)
 {
     int                     ret;
     struct spi_ioc_transfer transfer[2];
@@ -294,8 +363,8 @@
 
     // This part is the actual SPI transfer.
     transfer[1].tx_buf        = reinterpret_cast<uintptr_t>(mSpiTxFrameBuffer);
-    transfer[1].rx_buf        = reinterpret_cast<uintptr_t>(mSpiRxFrameBuffer);
-    transfer[1].len           = aLength + kSpiFrameHeaderSize + mSpiAlignAllowance;
+    transfer[1].rx_buf        = reinterpret_cast<uintptr_t>(aSpiRxFrameBuffer);
+    transfer[1].len           = aTransferLength;
     transfer[1].speed_hz      = mSpiSpeedHz;
     transfer[1].delay_usecs   = 0;
     transfer[1].bits_per_word = kSpiBitsPerWord;
@@ -315,7 +384,7 @@
     if (ret != -1)
     {
         otDumpDebg(OT_LOG_REGION_PLATFORM, "SPI-TX", mSpiTxFrameBuffer, transfer[1].len);
-        otDumpDebg(OT_LOG_REGION_PLATFORM, "SPI-RX", mSpiRxFrameBuffer, transfer[1].len);
+        otDumpDebg(OT_LOG_REGION_PLATFORM, "SPI-RX", aSpiRxFrameBuffer, transfer[1].len);
 
         mSpiFrameCount++;
     }
@@ -325,13 +394,16 @@
 
 otError SpiInterface::PushPullSpi(void)
 {
-    otError       error;
-    uint8_t *     spiRxFrameBuffer    = NULL;
+    otError       error               = OT_ERROR_FAILED;
     uint16_t      spiTransferBytes    = 0;
     uint8_t       successfulExchanges = 0;
+    bool          discardRxFrame      = true;
+    uint8_t *     spiRxFrameBuffer;
+    uint8_t *     spiRxFrame;
     uint8_t       slaveHeader;
     uint16_t      slaveAcceptLen;
     Ncp::SpiFrame txFrame(mSpiTxFrameBuffer);
+    uint16_t      skipAlignAllowanceLength;
 
     if (mSpiValidFrameCount == 0)
     {
@@ -385,8 +457,20 @@
 
     txFrame.SetHeaderAcceptLen(spiTransferBytes);
 
+    // Set skip length to make MultiFrameBuffer to reserve a space in front of the frame buffer.
+    SuccessOrExit(error = mRxFrameBuffer.SetSkipLength(kSpiFrameHeaderSize));
+
+    // Check whether the remaining frame buffer has enough space to store the data to be received.
+    VerifyOrExit(mRxFrameBuffer.GetFrameMaxLength() >= spiTransferBytes + mSpiAlignAllowance, OT_NOOP);
+
+    // Point to the start of the reserved buffer.
+    spiRxFrameBuffer = mRxFrameBuffer.GetFrame() - kSpiFrameHeaderSize;
+
+    // Set the total number of bytes to be transmitted.
+    spiTransferBytes += kSpiFrameHeaderSize + mSpiAlignAllowance;
+
     // Perform the SPI transaction.
-    error = DoSpiTransfer(spiTransferBytes);
+    error = DoSpiTransfer(spiRxFrameBuffer, spiTransferBytes);
 
     if (error != OT_ERROR_NONE)
     {
@@ -403,10 +487,10 @@
     }
 
     // Account for misalignment (0xFF bytes at the start)
-    spiRxFrameBuffer = GetRealRxFrameStart();
+    spiRxFrame = GetRealRxFrameStart(spiRxFrameBuffer, mSpiAlignAllowance, skipAlignAllowanceLength);
 
     {
-        Ncp::SpiFrame rxFrame(spiRxFrameBuffer);
+        Ncp::SpiFrame rxFrame(spiRxFrame);
 
         otLogDebgPlat("spi_transfer TX: H:%02X ACCEPT:%" PRIu16 " DATA:%" PRIu16, txFrame.GetHeaderFlagByte(),
                       txFrame.GetHeaderAcceptLen(), txFrame.GetHeaderDataLen());
@@ -416,8 +500,8 @@
         slaveHeader = rxFrame.GetHeaderFlagByte();
         if ((slaveHeader == 0xFF) || (slaveHeader == 0x00))
         {
-            if ((slaveHeader == spiRxFrameBuffer[1]) && (slaveHeader == spiRxFrameBuffer[2]) &&
-                (slaveHeader == spiRxFrameBuffer[3]) && (slaveHeader == spiRxFrameBuffer[4]))
+            if ((slaveHeader == spiRxFrame[1]) && (slaveHeader == spiRxFrame[2]) && (slaveHeader == spiRxFrame[3]) &&
+                (slaveHeader == spiRxFrame[4]))
             {
                 // Device is off or in a bad state. In some cases may be induced by flow control.
                 if (mSpiSlaveDataLen == 0)
@@ -436,12 +520,10 @@
                 // Header is full of garbage
                 mSpiGarbageFrameCount++;
 
-                otLogWarnPlat("Garbage in header : %02X %02X %02X %02X %02X", spiRxFrameBuffer[0], spiRxFrameBuffer[1],
-                              spiRxFrameBuffer[2], spiRxFrameBuffer[3], spiRxFrameBuffer[4]);
-                otDumpWarn(OT_LOG_REGION_PLATFORM, "SPI-TX", mSpiTxFrameBuffer,
-                           spiTransferBytes + kSpiFrameHeaderSize + mSpiAlignAllowance);
-                otDumpWarn(OT_LOG_REGION_PLATFORM, "SPI-RX", mSpiRxFrameBuffer,
-                           spiTransferBytes + kSpiFrameHeaderSize + mSpiAlignAllowance);
+                otLogWarnPlat("Garbage in header : %02X %02X %02X %02X %02X", spiRxFrame[0], spiRxFrame[1],
+                              spiRxFrame[2], spiRxFrame[3], spiRxFrame[4]);
+                otDumpWarn(OT_LOG_REGION_PLATFORM, "SPI-TX", mSpiTxFrameBuffer, spiTransferBytes);
+                otDumpWarn(OT_LOG_REGION_PLATFORM, "SPI-RX", spiRxFrameBuffer, spiTransferBytes);
             }
 
             mSpiTxRefusedCount++;
@@ -457,12 +539,10 @@
             mSpiTxRefusedCount++;
             mSpiSlaveDataLen = 0;
 
-            otLogWarnPlat("Garbage in header : %02X %02X %02X %02X %02X", spiRxFrameBuffer[0], spiRxFrameBuffer[1],
-                          spiRxFrameBuffer[2], spiRxFrameBuffer[3], spiRxFrameBuffer[4]);
-            otDumpWarn(OT_LOG_REGION_PLATFORM, "SPI-TX", mSpiTxFrameBuffer,
-                       spiTransferBytes + kSpiFrameHeaderSize + mSpiAlignAllowance);
-            otDumpWarn(OT_LOG_REGION_PLATFORM, "SPI-RX", mSpiRxFrameBuffer,
-                       spiTransferBytes + kSpiFrameHeaderSize + mSpiAlignAllowance);
+            otLogWarnPlat("Garbage in header : %02X %02X %02X %02X %02X", spiRxFrame[0], spiRxFrame[1], spiRxFrame[2],
+                          spiRxFrame[3], spiRxFrame[4]);
+            otDumpWarn(OT_LOG_REGION_PLATFORM, "SPI-TX", mSpiTxFrameBuffer, spiTransferBytes);
+            otDumpWarn(OT_LOG_REGION_PLATFORM, "SPI-RX", spiRxFrameBuffer, spiTransferBytes);
 
             ExitNow();
         }
@@ -485,7 +565,15 @@
             mSpiRxFrameCount++;
             successfulExchanges++;
 
-            HandleReceivedFrame(rxFrame);
+            // Set the skip length to skip align bytes and SPI frame header.
+            SuccessOrExit(error = mRxFrameBuffer.SetSkipLength(skipAlignAllowanceLength + kSpiFrameHeaderSize));
+            // Set the received frame length.
+            SuccessOrExit(error = mRxFrameBuffer.SetLength(rxFrame.GetHeaderDataLen()));
+
+            // Upper layer will free the frame buffer.
+            discardRxFrame = false;
+
+            mReceiveFrameCallback(mReceiveFrameContext);
         }
     }
 
@@ -524,6 +612,11 @@
     }
 
 exit:
+    if (discardRxFrame)
+    {
+        mRxFrameBuffer.DiscardFrame();
+    }
+
     return error;
 }
 
@@ -630,11 +723,9 @@
     }
 }
 
-void SpiInterface::Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet)
+void SpiInterface::Process(const RadioProcessContext &aContext)
 {
-    OT_UNUSED_VARIABLE(aWriteFdSet);
-
-    if (FD_ISSET(mIntGpioValueFd, &aReadFdSet))
+    if (FD_ISSET(mIntGpioValueFd, aContext.mReadFdSet))
     {
         struct gpioevent_data event;
 
@@ -648,26 +739,31 @@
     if (mSpiTxIsReady || CheckInterrupt())
     {
         // We guard this with the above check because we don't want to overwrite any previously received frames.
-        PushPullSpi();
+        IgnoreError(PushPullSpi());
     }
 }
 
-otError SpiInterface::WaitForFrame(const struct timeval &aTimeout)
+otError SpiInterface::WaitForFrame(uint64_t aTimeoutUs)
 {
-    otError        error   = OT_ERROR_NONE;
-    struct timeval timeout = {kSecPerDay, 0};
+    otError        error      = OT_ERROR_NONE;
+    struct timeval spiTimeout = {kSecPerDay, 0};
+    struct timeval timeout;
     fd_set         readFdSet;
     int            ret;
+    bool           isDataReady = false;
+
+    timeout.tv_sec  = static_cast<time_t>(aTimeoutUs / US_PER_S);
+    timeout.tv_usec = static_cast<suseconds_t>(aTimeoutUs % US_PER_S);
 
     FD_ZERO(&readFdSet);
 
     if (mIntGpioValueFd >= 0)
     {
-        if (CheckInterrupt())
+        if ((isDataReady = CheckInterrupt()))
         {
             // Interrupt pin is asserted, set the timeout to be 0.
-            timeout.tv_sec  = 0;
-            timeout.tv_usec = 0;
+            spiTimeout.tv_sec  = 0;
+            spiTimeout.tv_usec = 0;
         }
         else
         {
@@ -679,32 +775,29 @@
     else
     {
         // In this case we don't have an interrupt, so we revert to SPI polling.
-        timeout.tv_sec  = 0;
-        timeout.tv_usec = kSpiPollPeriodUs;
+        spiTimeout.tv_sec  = 0;
+        spiTimeout.tv_usec = kSpiPollPeriodUs;
     }
 
-    if (timercmp(&aTimeout, &timeout, <))
+    if (timercmp(&spiTimeout, &timeout, <))
     {
-        timeout = aTimeout;
+        timeout = spiTimeout;
     }
 
-    ret = select(mIntGpioValueFd + 1, &readFdSet, NULL, NULL, &timeout);
-    if (ret > 0)
+    ret = select(mIntGpioValueFd + 1, &readFdSet, nullptr, nullptr, &timeout);
+
+    if (ret > 0 && FD_ISSET(mIntGpioValueFd, &readFdSet))
     {
-        if (FD_ISSET(mIntGpioValueFd, &readFdSet))
-        {
-            struct gpioevent_data event;
+        struct gpioevent_data event;
 
-            // Read event data to clear interrupt.
-            VerifyOrDie(read(mIntGpioValueFd, &event, sizeof(event)) != -1, OT_EXIT_FAILURE);
-        }
+        // Read event data to clear interrupt.
+        VerifyOrDie(read(mIntGpioValueFd, &event, sizeof(event)) != -1, OT_EXIT_FAILURE);
+        isDataReady = true;
+    }
 
-        // If we can receive a packet.
-        if (CheckInterrupt())
-        {
-            otLogDebgPlat("WaitForFrame(): Interrupt.");
-            PushPullSpi();
-        }
+    if (isDataReady)
+    {
+        IgnoreError(PushPullSpi());
     }
     else if (ret == 0)
     {
@@ -731,32 +824,12 @@
     mSpiTxIsReady     = true;
     mSpiTxPayloadSize = aLength;
 
-    PushPullSpi();
+    IgnoreError(PushPullSpi());
 
 exit:
     return error;
 }
 
-void SpiInterface::HandleReceivedFrame(Ncp::SpiFrame &aSpiFrame)
-{
-    const uint8_t *spinelFrame = aSpiFrame.GetData();
-
-    for (uint16_t i = 0; i < aSpiFrame.GetHeaderDataLen(); i++)
-    {
-        if (mRxFrameBuffer.WriteByte(spinelFrame[i]) != OT_ERROR_NONE)
-        {
-            mRxFrameBuffer.DiscardFrame();
-            otLogNotePlat("No enough memory buffers, drop packet");
-            ExitNow();
-        }
-    }
-
-    mCallbacks.HandleReceivedFrame();
-
-exit:
-    return;
-}
-
 void SpiInterface::LogError(const char *aString)
 {
     OT_UNUSED_VARIABLE(aString);
@@ -776,7 +849,7 @@
     otLogInfoPlat("INFO: mSpiTxFrameCount=%" PRIu64, mSpiTxFrameCount);
     otLogInfoPlat("INFO: mSpiTxFrameByteCount=%" PRIu64, mSpiTxFrameByteCount);
 }
-} // namespace PosixApp
+} // namespace Posix
 } // namespace ot
 
-#endif // OPENTHREAD_POSIX_RCP_SPI_ENABLE
+#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
diff --git a/src/posix/platform/spi_interface.hpp b/src/posix/platform/spi_interface.hpp
index 3338d76..de34145 100644
--- a/src/posix/platform/spi_interface.hpp
+++ b/src/posix/platform/spi_interface.hpp
@@ -34,17 +34,20 @@
 #ifndef POSIX_APP_SPI_INTERFACE_HPP_
 #define POSIX_APP_SPI_INTERFACE_HPP_
 
-#include "spinel_interface.hpp"
-#include "ncp/hdlc.hpp"
+#include "openthread-posix-config.h"
 
-#include <openthread-system.h>
+#include "platform-posix.h"
+#include "lib/hdlc/hdlc.hpp"
+#include "lib/spinel/spinel_interface.hpp"
 
-#if OPENTHREAD_POSIX_RCP_SPI_ENABLE
+#include <openthread/openthread-system.h>
+
+#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
 
 #include "ncp/ncp_spi.hpp"
 
 namespace ot {
-namespace PosixApp {
+namespace Posix {
 
 /**
  * This class defines an SPI interface to the Radio Co-processor (RCP).
@@ -56,11 +59,14 @@
     /**
      * This constructor initializes the object.
      *
-     * @param[in] aCallback     A reference to a `Callback` object.
-     * @param[in] aFrameBuffer  A reference to a `RxFrameBuffer` object.
+     * @param[in] aCallback         A reference to a `Callback` object.
+     * @param[in] aCallbackContext  The context pointer passed to the callback.
+     * @param[in] aFrameBuffer      A reference to a `RxFrameBuffer` object.
      *
      */
-    SpiInterface(SpinelInterface::Callbacks &aCallback, SpinelInterface::RxFrameBuffer &aFrameBuffer);
+    SpiInterface(Spinel::SpinelInterface::ReceiveFrameCallback aCallback,
+                 void *                                        aCallbackContext,
+                 Spinel::SpinelInterface::RxFrameBuffer &      aFrameBuffer);
 
     /**
      * This destructor deinitializes the object.
@@ -73,14 +79,14 @@
      *
      * @note This method should be called before reading and sending spinel frames to the interface.
      *
-     * @param[in]  aPlatformConfig  Platform configuration structure.
+     * @param[in]  aRadioUrl          Arguments parsed from radio url.
      *
      * @retval OT_ERROR_NONE          The interface is initialized successfully.
      * @retval OT_ERROR_ALREADY       The interface is already initialized.
      * @retval OT_ERROR_INVALID_ARGS  The UART device or executable cannot be found or failed to open/run.
      *
      */
-    otError Init(const otPlatformConfig &aPlatformConfig);
+    otError Init(const RadioUrl &aRadioUrl);
 
     /**
      * This method deinitializes the interface to the RCP.
@@ -105,13 +111,13 @@
     /**
      * This method waits for receiving part or all of spinel frame within specified interval.
      *
-     * @param[in]  aTimeout  A reference to the timeout.
+     * @param[in]  aTimeout  The timeout value in microseconds.
      *
      * @retval OT_ERROR_NONE             Part or all of spinel frame is received.
      * @retval OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p aTimeout.
      *
      */
-    otError WaitForFrame(const struct timeval &aTimeout);
+    otError WaitForFrame(uint64_t aTimeoutUs);
 
     /**
      * This method updates the file descriptor sets with file descriptors used by the radio driver.
@@ -127,11 +133,10 @@
     /**
      * This method performs radio driver processing.
      *
-     * @param[in]   aReadFdSet      A reference to the read file descriptors.
-     * @param[in]   aWriteFdSet     A reference to the write file descriptors.
+     * @param[in]   aContext        The context containing fd_sets.
      *
      */
-    void Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet);
+    void Process(const RadioProcessContext &aContext);
 
 private:
     int     SetupGpioHandle(int aFd, uint8_t aLine, uint32_t aHandleFlags, const char *aLabel);
@@ -144,29 +149,28 @@
     void InitSpiDev(const char *aPath, uint8_t aMode, uint32_t aSpeed);
     void TrigerReset(void);
 
-    uint8_t *GetRealRxFrameStart(void);
-    otError  DoSpiTransfer(uint32_t aLength);
+    uint8_t *GetRealRxFrameStart(uint8_t *aSpiRxFrameBuffer, uint8_t aAlignAllowance, uint16_t &aSkipLength);
+    otError  DoSpiTransfer(uint8_t *aSpiRxFrameBuffer, uint32_t aTransferLength);
     otError  PushPullSpi(void);
 
     bool CheckInterrupt(void);
-    void HandleReceivedFrame(Ncp::SpiFrame &aSpiFrame);
     void LogStats(void);
-    void LogError(const char * aString);
+    void LogError(const char *aString);
     void LogBuffer(const char *aDesc, const uint8_t *aBuffer, uint16_t aLength, bool aForce);
 
     enum
     {
-        kSpiModeMax              = 3,
-        kSpiAlignAllowanceMax    = 16,
-        kSpiFrameHeaderSize      = 5,
-        kSpiBitsPerWord          = 8,
-        kSpiTxRefuseWarnCount    = 30,
-        kSpiTxRefuseExitCount    = 100,
-        kImmediateRetryCount     = 5,
-        kFastRetryCount          = 15,
-        kDebugBytesPerLine       = 16, 
-        kGpioIntAssertState      = 0,
-        kGpioResetAssertState    = 0,
+        kSpiModeMax           = 3,
+        kSpiAlignAllowanceMax = 16,
+        kSpiFrameHeaderSize   = 5,
+        kSpiBitsPerWord       = 8,
+        kSpiTxRefuseWarnCount = 30,
+        kSpiTxRefuseExitCount = 100,
+        kImmediateRetryCount  = 5,
+        kFastRetryCount       = 15,
+        kDebugBytesPerLine    = 16,
+        kGpioIntAssertState   = 0,
+        kGpioResetAssertState = 0,
     };
 
     enum
@@ -183,11 +187,12 @@
 
     enum
     {
-        kMaxFrameSize = SpinelInterface::kMaxFrameSize,
+        kMaxFrameSize = Spinel::SpinelInterface::kMaxFrameSize,
     };
 
-    SpinelInterface::Callbacks &    mCallbacks;
-    SpinelInterface::RxFrameBuffer &mRxFrameBuffer;
+    Spinel::SpinelInterface::ReceiveFrameCallback mReceiveFrameCallback;
+    void *                                        mReceiveFrameContext;
+    Spinel::SpinelInterface::RxFrameBuffer &      mRxFrameBuffer;
 
     int mSpiDevFd;
     int mResetGpioValueFd;
@@ -210,8 +215,6 @@
     uint64_t mSpiTxFrameCount;
     uint64_t mSpiTxFrameByteCount;
 
-    uint8_t  mSpiRxFrameBuffer[kMaxFrameSize + kSpiAlignAllowanceMax];
-
     bool     mSpiTxIsReady;
     uint16_t mSpiTxRefusedCount;
     uint16_t mSpiTxPayloadSize;
@@ -219,10 +222,14 @@
 
     bool     mDidPrintRateLimitLog;
     uint16_t mSpiSlaveDataLen;
+
+    // Non-copyable, intentionally not implemented.
+    SpiInterface(const SpiInterface &);
+    SpiInterface &operator=(const SpiInterface &);
 };
 
-} // namespace PosixApp
+} // namespace Posix
 } // namespace ot
 
-#endif // OPENTHREAD_POSIX_RCP_SPI_ENABLE
+#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
 #endif // POSIX_APP_SPI_INTERFACE_HPP_
diff --git a/src/posix/platform/spinel_interface.hpp b/src/posix/platform/spinel_interface.hpp
deleted file mode 100644
index 0e016c7..0000000
--- a/src/posix/platform/spinel_interface.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *  Copyright (c) 2019, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- *   This file includes definitions for the spinel interface to Radio Co-processor (RCP)
- *
- */
-
-#ifndef POSIX_APP_SPINEL_INTERFACE_HPP_
-#define POSIX_APP_SPINEL_INTERFACE_HPP_
-
-#include "ncp/hdlc.hpp"
-
-namespace ot {
-namespace PosixApp {
-
-class SpinelInterface
-{
-public:
-    enum
-    {
-        kMaxFrameSize = 2048, ///< Maximum frame size (number of bytes).
-    };
-
-    /**
-     * This type defines a receive frame buffer to store received spinel frame(s).
-     *
-     * @note The receive frame buffer is an `Hdlc::MultiFrameBuffer` and therefore it is capable of storing multiple
-     * frames in a FIFO queue manner.
-     *
-     */
-    typedef Hdlc::MultiFrameBuffer<kMaxFrameSize> RxFrameBuffer;
-
-    /**
-     * This class defines the callbacks provided by `SpinelInterface` to its owner/user.
-     *
-     */
-    class Callbacks
-    {
-    public:
-        /**
-         * This callback is invoked to notify owner/user of `SpinelInterface` of a received spinel frame.
-         *
-         * The newly received frame is available in `RxFrameBuffer` from `SpinelInterface::GetRxFrameBuffer()`.
-         * User can read and process the frame. The callback is expected to either discard the new frame using
-         * `RxFrameBuffer::DiscardFrame()` or save the frame using `RxFrameBuffer::SaveFrame()` to be read and
-         * processed later.
-         *
-         */
-        void HandleReceivedFrame(void);
-    };
-};
-} // namespace PosixApp
-} // namespace ot
-
-#endif // POSIX_APP_SPINEL_INTERFACE_HPP_
diff --git a/src/posix/platform/system.c b/src/posix/platform/system.c
deleted file mode 100644
index 8fbc117..0000000
--- a/src/posix/platform/system.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- * @brief
- *   This file includes the platform-specific initializers.
- */
-
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-
-#include <assert.h>
-
-#include <openthread-core-config.h>
-#include <openthread/tasklet.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/radio.h>
-
-uint64_t gNodeId = 0;
-
-otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
-{
-    otInstance *instance = NULL;
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-    platformSimInit();
-#endif
-    platformAlarmInit(aPlatformConfig->mSpeedUpFactor);
-    platformRadioInit(aPlatformConfig);
-    platformRandomInit();
-
-    instance = otInstanceInitSingle();
-    assert(instance != NULL);
-
-#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
-    platformNetifInit(instance);
-#elif OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    platformUdpInit(aPlatformConfig->mInterfaceName);
-#endif
-
-    return instance;
-}
-
-void otSysDeinit(void)
-{
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-    platformSimDeinit();
-#endif
-    platformRadioDeinit();
-}
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-/**
- * This function try selecting the given file descriptors in nonblocking mode.
- *
- * @param[inout]    aReadFdSet   A pointer to the read file descriptors.
- * @param[inout]    aWriteFdSet  A pointer to the write file descriptors.
- * @param[inout]    aErrorFdSet  A pointer to the error file descriptors.
- * @param[in]       aMaxFd       The max file descriptor.
- *
- * @returns The value returned from select().
- *
- */
-static int trySelect(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int aMaxFd)
-{
-    struct timeval timeout          = {0, 0};
-    fd_set         originReadFdSet  = *aReadFdSet;
-    fd_set         originWriteFdSet = *aWriteFdSet;
-    fd_set         originErrorFdSet = *aErrorFdSet;
-    int            rval;
-
-    rval = select(aMaxFd + 1, aReadFdSet, aWriteFdSet, aErrorFdSet, &timeout);
-
-    if (rval == 0)
-    {
-        *aReadFdSet  = originReadFdSet;
-        *aWriteFdSet = originWriteFdSet;
-        *aErrorFdSet = originErrorFdSet;
-    }
-
-    return rval;
-}
-#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
-
-void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop)
-{
-    platformAlarmUpdateTimeout(&aMainloop->mTimeout);
-    platformUartUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
-                            &aMainloop->mMaxFd);
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    platformUdpUpdateFdSet(aInstance, &aMainloop->mReadFdSet, &aMainloop->mMaxFd);
-#endif
-#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
-    platformNetifUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
-                             &aMainloop->mMaxFd);
-#endif
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-    platformSimUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, &aMainloop->mMaxFd,
-                           &aMainloop->mTimeout);
-#else
-    platformRadioUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mMaxFd, &aMainloop->mTimeout);
-#endif
-
-    if (otTaskletsArePending(aInstance))
-    {
-        aMainloop->mTimeout.tv_sec  = 0;
-        aMainloop->mTimeout.tv_usec = 0;
-    }
-}
-
-int otSysMainloopPoll(otSysMainloopContext *aMainloop)
-{
-    int rval;
-
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-    if (timerisset(&aMainloop->mTimeout))
-    {
-        // Make sure there are no data ready in UART
-        rval = trySelect(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, aMainloop->mMaxFd);
-
-        if (rval == 0)
-        {
-            bool noWrite = true;
-
-            // If there are write requests, the device is supposed to wake soon
-            for (int i = 0; i < aMainloop->mMaxFd + 1; ++i)
-            {
-                if (FD_ISSET(i, &aMainloop->mWriteFdSet))
-                {
-                    noWrite = false;
-                    break;
-                }
-            }
-
-            if (noWrite)
-            {
-                platformSimSendSleepEvent(&aMainloop->mTimeout);
-            }
-
-            rval = select(aMainloop->mMaxFd + 1, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet,
-                          &aMainloop->mErrorFdSet, NULL);
-        }
-    }
-    else
-#endif
-    {
-        rval = select(aMainloop->mMaxFd + 1, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
-                      &aMainloop->mTimeout);
-    }
-
-    return rval;
-}
-
-void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop)
-{
-#if OPENTHREAD_POSIX_VIRTUAL_TIME
-    platformSimProcess(aInstance, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
-#else
-    platformRadioProcess(aInstance, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet);
-#endif
-    platformUartProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
-    platformAlarmProcess(aInstance);
-#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
-    platformNetifProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
-#endif
-#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
-    platformUdpProcess(aInstance, &aMainloop->mReadFdSet);
-#endif
-}
diff --git a/src/posix/platform/system.cpp b/src/posix/platform/system.cpp
new file mode 100644
index 0000000..8c80819
--- /dev/null
+++ b/src/posix/platform/system.cpp
@@ -0,0 +1,205 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *   This file includes the platform-specific initializers.
+ */
+
+#include "openthread-posix-config.h"
+#include "platform-posix.h"
+
+#include <assert.h>
+
+#include <openthread-core-config.h>
+#include <openthread/tasklet.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/radio.h>
+#include <openthread/platform/uart.h>
+
+#include "common/code_utils.hpp"
+
+uint64_t gNodeId = 0;
+
+otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
+{
+    otInstance *        instance = nullptr;
+    ot::Posix::RadioUrl radioUrl(aPlatformConfig->mRadioUrl);
+
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+    virtualTimeInit(static_cast<uint16_t>(atoi(radioUrl.GetValue("forkpty-arg"))));
+#endif
+
+    VerifyOrDie(radioUrl.GetPath() != nullptr, OT_EXIT_INVALID_ARGUMENTS);
+    platformAlarmInit(aPlatformConfig->mSpeedUpFactor, aPlatformConfig->mRealTimeSignal);
+    platformRadioInit(&radioUrl);
+    platformRandomInit();
+
+    instance = otInstanceInitSingle();
+    assert(instance != nullptr);
+
+#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+    platformNetifInit(instance, aPlatformConfig->mInterfaceName);
+#elif OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+    platformUdpInit(aPlatformConfig->mInterfaceName);
+#endif
+
+    return instance;
+}
+
+void otSysDeinit(void)
+{
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+    virtualTimeDeinit();
+#endif
+    platformRadioDeinit();
+#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+    platformNetifDeinit();
+#endif
+    IgnoreError(otPlatUartDisable());
+}
+
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+/**
+ * This function try selecting the given file descriptors in nonblocking mode.
+ *
+ * @param[inout]    aReadFdSet   A pointer to the read file descriptors.
+ * @param[inout]    aWriteFdSet  A pointer to the write file descriptors.
+ * @param[inout]    aErrorFdSet  A pointer to the error file descriptors.
+ * @param[in]       aMaxFd       The max file descriptor.
+ *
+ * @returns The value returned from select().
+ *
+ */
+static int trySelect(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int aMaxFd)
+{
+    struct timeval timeout          = {0, 0};
+    fd_set         originReadFdSet  = *aReadFdSet;
+    fd_set         originWriteFdSet = *aWriteFdSet;
+    fd_set         originErrorFdSet = *aErrorFdSet;
+    int            rval;
+
+    rval = select(aMaxFd + 1, aReadFdSet, aWriteFdSet, aErrorFdSet, &timeout);
+
+    if (rval == 0)
+    {
+        *aReadFdSet  = originReadFdSet;
+        *aWriteFdSet = originWriteFdSet;
+        *aErrorFdSet = originErrorFdSet;
+    }
+
+    return rval;
+}
+#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
+
+void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop)
+{
+    platformAlarmUpdateTimeout(&aMainloop->mTimeout);
+    platformUartUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
+                            &aMainloop->mMaxFd);
+#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+    platformUdpUpdateFdSet(aInstance, &aMainloop->mReadFdSet, &aMainloop->mMaxFd);
+#endif
+#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+    platformNetifUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
+                             &aMainloop->mMaxFd);
+#endif
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+    virtualTimeUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, &aMainloop->mMaxFd,
+                           &aMainloop->mTimeout);
+#else
+    platformRadioUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mMaxFd, &aMainloop->mTimeout);
+#endif
+
+    if (otTaskletsArePending(aInstance))
+    {
+        aMainloop->mTimeout.tv_sec  = 0;
+        aMainloop->mTimeout.tv_usec = 0;
+    }
+}
+
+int otSysMainloopPoll(otSysMainloopContext *aMainloop)
+{
+    int rval;
+
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+    if (timerisset(&aMainloop->mTimeout))
+    {
+        // Make sure there are no data ready in UART
+        rval = trySelect(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, aMainloop->mMaxFd);
+
+        if (rval == 0)
+        {
+            bool noWrite = true;
+
+            // If there are write requests, the device is supposed to wake soon
+            for (int i = 0; i < aMainloop->mMaxFd + 1; ++i)
+            {
+                if (FD_ISSET(i, &aMainloop->mWriteFdSet))
+                {
+                    noWrite = false;
+                    break;
+                }
+            }
+
+            if (noWrite)
+            {
+                virtualTimeSendSleepEvent(&aMainloop->mTimeout);
+            }
+
+            rval = select(aMainloop->mMaxFd + 1, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet,
+                          &aMainloop->mErrorFdSet, nullptr);
+        }
+    }
+    else
+#endif
+    {
+        rval = select(aMainloop->mMaxFd + 1, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
+                      &aMainloop->mTimeout);
+    }
+
+    return rval;
+}
+
+void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop)
+{
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+    virtualTimeProcess(aInstance, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
+#else
+    platformRadioProcess(aInstance, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet);
+#endif
+    platformUartProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
+    platformAlarmProcess(aInstance);
+#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
+    platformNetifProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
+#endif
+#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
+    platformUdpProcess(aInstance, &aMainloop->mReadFdSet);
+#endif
+}
diff --git a/src/posix/platform/uart.c b/src/posix/platform/uart.c
deleted file mode 100644
index b8ffa9a..0000000
--- a/src/posix/platform/uart.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "openthread-core-config.h"
-#include "platform-posix.h"
-
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-#include <fcntl.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#endif
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <openthread/platform/uart.h>
-
-#include "code_utils.h"
-#include "common/code_utils.hpp"
-
-#define OPENTHREAD_POSIX_APP_SOCKET_LOCK OPENTHREAD_POSIX_APP_SOCKET_BASENAME ".lock"
-
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-static int sUartSocket    = -1;
-static int sUartLock      = -1;
-static int sSessionSocket = -1;
-#endif
-
-static bool           sEnabled     = false;
-static const uint8_t *sWriteBuffer = NULL;
-static uint16_t       sWriteLength = 0;
-
-otError otPlatUartEnable(void)
-{
-    otError error = OT_ERROR_NONE;
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-    struct sockaddr_un sockname;
-    int                ret;
-
-    // This allows implementing pseudo reset.
-    otEXPECT(sUartSocket == -1);
-
-    sUartSocket = SocketWithCloseExec(AF_UNIX, SOCK_STREAM, 0);
-
-    if (sUartSocket == -1)
-    {
-        DieNow(OT_EXIT_FAILURE);
-    }
-
-    sUartLock = open(OPENTHREAD_POSIX_APP_SOCKET_LOCK, O_CREAT | O_RDONLY | O_CLOEXEC, 0600);
-
-    if (sUartLock == -1)
-    {
-        DieNowWithMessage("open", OT_EXIT_ERROR_ERRNO);
-    }
-
-    if (flock(sUartLock, LOCK_EX | LOCK_NB) == -1)
-    {
-        DieNowWithMessage("flock", OT_EXIT_ERROR_ERRNO);
-    }
-
-    memset(&sockname, 0, sizeof(struct sockaddr_un));
-
-    (void)unlink(OPENTHREAD_POSIX_APP_SOCKET_NAME);
-
-    sockname.sun_family = AF_UNIX;
-    assert(sizeof(OPENTHREAD_POSIX_APP_SOCKET_NAME) < sizeof(sockname.sun_path));
-    strncpy(sockname.sun_path, OPENTHREAD_POSIX_APP_SOCKET_NAME, sizeof(sockname.sun_path) - 1);
-
-    ret = bind(sUartSocket, (const struct sockaddr *)&sockname, sizeof(struct sockaddr_un));
-
-    if (ret == -1)
-    {
-        DieNowWithMessage("bind", OT_EXIT_ERROR_ERRNO);
-    }
-
-    //
-    // only accept 1 connection.
-    //
-    ret = listen(sUartSocket, 1);
-    if (ret == -1)
-    {
-        DieNowWithMessage("listen", OT_EXIT_ERROR_ERRNO);
-    }
-
-exit:
-#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-
-    sEnabled = true;
-    return error;
-}
-
-otError otPlatUartDisable(void)
-{
-    otError error = OT_ERROR_NONE;
-    sEnabled      = false;
-
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-    if (sSessionSocket != -1)
-    {
-        close(sSessionSocket);
-        sSessionSocket = -1;
-    }
-
-    if (sUartSocket != -1)
-    {
-        close(sUartSocket);
-        sUartSocket = -1;
-    }
-
-    if (sUartLock != -1)
-    {
-        (void)flock(sUartLock, LOCK_UN);
-        close(sUartLock);
-        sUartLock = -1;
-    }
-#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-
-    return error;
-}
-
-otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
-{
-    otError error = OT_ERROR_NONE;
-
-    assert(sEnabled);
-    otEXPECT_ACTION(sWriteLength == 0, error = OT_ERROR_BUSY);
-
-    sWriteBuffer = aBuf;
-    sWriteLength = aBufLength;
-
-exit:
-    return error;
-}
-
-otError otPlatUartFlush(void)
-{
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
-{
-    otEXPECT(sEnabled);
-
-    if (aReadFdSet != NULL)
-    {
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-        int fd = (sSessionSocket == -1 ? sUartSocket : sSessionSocket);
-#else
-        int fd = STDIN_FILENO;
-#endif
-
-        FD_SET(fd, aReadFdSet);
-
-        if (aErrorFdSet != NULL)
-        {
-            FD_SET(fd, aErrorFdSet);
-        }
-
-        if (aMaxFd != NULL && *aMaxFd < fd)
-        {
-            *aMaxFd = fd;
-        }
-    }
-    if ((aWriteFdSet != NULL) && (sWriteLength > 0))
-    {
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-        int fd = (sSessionSocket == -1 ? sUartSocket : sSessionSocket);
-#else
-        int fd = STDOUT_FILENO;
-#endif
-
-        FD_SET(fd, aWriteFdSet);
-
-        if (aErrorFdSet != NULL)
-        {
-            FD_SET(fd, aErrorFdSet);
-        }
-
-        if (aMaxFd != NULL && *aMaxFd < fd)
-        {
-            *aMaxFd = fd;
-        }
-    }
-
-exit:
-    return;
-}
-
-void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet)
-{
-    ssize_t rval;
-    int     fd;
-
-    otEXPECT(sEnabled);
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-    if (FD_ISSET(sUartSocket, aErrorFdSet))
-    {
-        DieNowWithMessage("socket", OT_EXIT_FAILURE);
-    }
-    else if (FD_ISSET(sUartSocket, aReadFdSet))
-    {
-        sSessionSocket = accept(sUartSocket, NULL, NULL);
-    }
-
-    if (sSessionSocket == -1 && sWriteBuffer != NULL)
-    {
-        IgnoreReturnValue(write(STDERR_FILENO, sWriteBuffer, sWriteLength));
-        sWriteBuffer = NULL;
-        sWriteLength = 0;
-        otPlatUartSendDone();
-    }
-
-    otEXPECT(sSessionSocket != -1);
-
-    if (FD_ISSET(sSessionSocket, aErrorFdSet))
-    {
-        close(sSessionSocket);
-        sSessionSocket = -1;
-    }
-
-    otEXPECT(sSessionSocket != -1);
-
-    fd = sSessionSocket;
-#else  // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-    if (FD_ISSET(STDIN_FILENO, aErrorFdSet))
-    {
-        DieNowWithMessage("stdin", OT_EXIT_FAILURE);
-    }
-
-    if (FD_ISSET(STDOUT_FILENO, aErrorFdSet))
-    {
-        DieNowWithMessage("stdout", OT_EXIT_FAILURE);
-    }
-
-    fd = STDIN_FILENO;
-#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-
-    if (FD_ISSET(fd, aReadFdSet))
-    {
-        uint8_t buffer[256];
-
-        rval = read(fd, buffer, sizeof(buffer));
-
-        if (rval > 0)
-        {
-            otPlatUartReceived(buffer, (uint16_t)rval);
-        }
-        else if (rval <= 0)
-        {
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-            if (rval < 0)
-            {
-                perror("UART read");
-            }
-            close(sSessionSocket);
-            sSessionSocket = -1;
-            otEXIT_NOW();
-#else
-            DieNowWithMessage("UART read", (rval < 0) ? OT_EXIT_ERROR_ERRNO : OT_EXIT_FAILURE);
-#endif
-        }
-    }
-
-#if !OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-    fd = STDOUT_FILENO;
-#endif
-
-    if ((sWriteLength > 0) && (FD_ISSET(fd, aWriteFdSet)))
-    {
-        rval = write(fd, sWriteBuffer, sWriteLength);
-
-        if (rval < 0)
-        {
-#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
-            perror("UART write");
-            close(sSessionSocket);
-            sSessionSocket = -1;
-            otEXIT_NOW();
-#else
-            DieNowWithMessage("UART write", OT_EXIT_ERROR_ERRNO);
-#endif
-        }
-
-        otEXPECT(rval > 0);
-
-        sWriteBuffer += (uint16_t)rval;
-        sWriteLength -= (uint16_t)rval;
-
-        if (sWriteLength == 0)
-        {
-            otPlatUartSendDone();
-        }
-    }
-
-exit:
-    return;
-}
diff --git a/src/posix/platform/uart.cpp b/src/posix/platform/uart.cpp
new file mode 100644
index 0000000..42f20dc
--- /dev/null
+++ b/src/posix/platform/uart.cpp
@@ -0,0 +1,382 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "openthread-posix-config.h"
+#include "platform-posix.h"
+
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <openthread/platform/uart.h>
+
+#include "common/code_utils.hpp"
+
+#define OPENTHREAD_POSIX_DAEMON_SOCKET_LOCK OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME ".lock"
+
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+static int sUartSocket    = -1;
+static int sUartLock      = -1;
+static int sSessionSocket = -1;
+#endif
+
+static bool           sEnabled     = false;
+static const uint8_t *sWriteBuffer = nullptr;
+static uint16_t       sWriteLength = 0;
+
+otError otPlatUartEnable(void)
+{
+    otError error = OT_ERROR_NONE;
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+    struct sockaddr_un sockname;
+    int                ret;
+
+    // This allows implementing pseudo reset.
+    VerifyOrExit(sUartSocket == -1, OT_NOOP);
+
+    sUartSocket = SocketWithCloseExec(AF_UNIX, SOCK_STREAM, 0, kSocketNonBlock);
+
+    if (sUartSocket == -1)
+    {
+        DieNow(OT_EXIT_FAILURE);
+    }
+
+    sUartLock = open(OPENTHREAD_POSIX_DAEMON_SOCKET_LOCK, O_CREAT | O_RDONLY | O_CLOEXEC, 0600);
+
+    if (sUartLock == -1)
+    {
+        DieNowWithMessage("open", OT_EXIT_ERROR_ERRNO);
+    }
+
+    if (flock(sUartLock, LOCK_EX | LOCK_NB) == -1)
+    {
+        DieNowWithMessage("flock", OT_EXIT_ERROR_ERRNO);
+    }
+
+    memset(&sockname, 0, sizeof(struct sockaddr_un));
+
+    (void)unlink(OPENTHREAD_POSIX_DAEMON_SOCKET_NAME);
+
+    sockname.sun_family = AF_UNIX;
+    assert(sizeof(OPENTHREAD_POSIX_DAEMON_SOCKET_NAME) < sizeof(sockname.sun_path));
+    strncpy(sockname.sun_path, OPENTHREAD_POSIX_DAEMON_SOCKET_NAME, sizeof(sockname.sun_path) - 1);
+
+    ret = bind(sUartSocket, (const struct sockaddr *)&sockname, sizeof(struct sockaddr_un));
+
+    if (ret == -1)
+    {
+        DieNowWithMessage("bind", OT_EXIT_ERROR_ERRNO);
+    }
+
+    //
+    // only accept 1 connection.
+    //
+    ret = listen(sUartSocket, 1);
+    if (ret == -1)
+    {
+        DieNowWithMessage("listen", OT_EXIT_ERROR_ERRNO);
+    }
+
+exit:
+#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+
+    sEnabled = true;
+    return error;
+}
+
+otError otPlatUartDisable(void)
+{
+    otError error = OT_ERROR_NONE;
+    sEnabled      = false;
+
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+    if (sSessionSocket != -1)
+    {
+        close(sSessionSocket);
+        sSessionSocket = -1;
+    }
+
+    if (sUartSocket != -1)
+    {
+        close(sUartSocket);
+        sUartSocket = -1;
+    }
+
+    if (sUartLock != -1)
+    {
+        (void)flock(sUartLock, LOCK_UN);
+        close(sUartLock);
+        sUartLock = -1;
+    }
+#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+
+    return error;
+}
+
+otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    otError error = OT_ERROR_NONE;
+
+    assert(sEnabled);
+    VerifyOrExit(sWriteLength == 0, error = OT_ERROR_BUSY);
+
+    sWriteBuffer = aBuf;
+    sWriteLength = aBufLength;
+
+exit:
+    return error;
+}
+
+otError otPlatUartFlush(void)
+{
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
+{
+    VerifyOrExit(sEnabled, OT_NOOP);
+
+    if (aReadFdSet != nullptr)
+    {
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+        int fd = (sSessionSocket == -1 ? sUartSocket : sSessionSocket);
+#else
+        int fd = STDIN_FILENO;
+#endif
+
+        FD_SET(fd, aReadFdSet);
+
+        if (aErrorFdSet != nullptr)
+        {
+            FD_SET(fd, aErrorFdSet);
+        }
+
+        if (aMaxFd != nullptr && *aMaxFd < fd)
+        {
+            *aMaxFd = fd;
+        }
+    }
+    if ((aWriteFdSet != nullptr) && (sWriteLength > 0))
+    {
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+        int fd = (sSessionSocket == -1 ? sUartSocket : sSessionSocket);
+#else
+        int fd = STDOUT_FILENO;
+#endif
+
+        FD_SET(fd, aWriteFdSet);
+
+        if (aErrorFdSet != nullptr)
+        {
+            FD_SET(fd, aErrorFdSet);
+        }
+
+        if (aMaxFd != nullptr && *aMaxFd < fd)
+        {
+            *aMaxFd = fd;
+        }
+    }
+
+exit:
+    return;
+}
+
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+static void InitializeSessionSocket(void)
+{
+    int rval;
+
+    VerifyOrExit((rval = accept(sUartSocket, nullptr, nullptr)) != -1, OT_NOOP);
+
+    if (sSessionSocket != -1)
+    {
+        close(sSessionSocket);
+    }
+
+    sSessionSocket = rval;
+
+    VerifyOrExit((rval = fcntl(sSessionSocket, F_GETFD, 0)) != -1, OT_NOOP);
+
+    rval |= FD_CLOEXEC;
+
+    VerifyOrExit((rval = fcntl(sSessionSocket, F_SETFD, rval)) != -1, OT_NOOP);
+
+exit:
+    if (rval == -1)
+    {
+        otLogWarnPlat("Failed to initialize session socket: %s", strerror(errno));
+        sSessionSocket = -1;
+    }
+    else
+    {
+        otLogInfoPlat("Session socket is ready", strerror(errno));
+    }
+}
+#endif
+
+void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet)
+{
+    ssize_t rval;
+    int     fd;
+
+    VerifyOrExit(sEnabled, OT_NOOP);
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+    if (FD_ISSET(sUartSocket, aErrorFdSet))
+    {
+        DieNowWithMessage("socket", OT_EXIT_FAILURE);
+    }
+    else if (FD_ISSET(sUartSocket, aReadFdSet))
+    {
+        InitializeSessionSocket();
+    }
+
+    if (sSessionSocket == -1 && sWriteBuffer != nullptr)
+    {
+        IgnoreReturnValue(write(STDERR_FILENO, sWriteBuffer, sWriteLength));
+        sWriteBuffer = nullptr;
+        sWriteLength = 0;
+        otPlatUartSendDone();
+    }
+
+    VerifyOrExit(sSessionSocket != -1, OT_NOOP);
+
+    if (FD_ISSET(sSessionSocket, aErrorFdSet))
+    {
+        close(sSessionSocket);
+        sSessionSocket = -1;
+    }
+
+    VerifyOrExit(sSessionSocket != -1, OT_NOOP);
+
+    fd = sSessionSocket;
+#else  // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+    if (FD_ISSET(STDIN_FILENO, aErrorFdSet))
+    {
+        DieNowWithMessage("stdin", OT_EXIT_FAILURE);
+    }
+
+    if (FD_ISSET(STDOUT_FILENO, aErrorFdSet))
+    {
+        DieNowWithMessage("stdout", OT_EXIT_FAILURE);
+    }
+
+    fd = STDIN_FILENO;
+#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+
+    if (FD_ISSET(fd, aReadFdSet))
+    {
+        uint8_t buffer[256];
+
+        rval = read(fd, buffer, sizeof(buffer));
+
+        if (rval > 0)
+        {
+            otPlatUartReceived(buffer, (uint16_t)rval);
+        }
+        else if (rval <= 0)
+        {
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+            if (rval < 0)
+            {
+                perror("UART read");
+            }
+            close(sSessionSocket);
+            sSessionSocket = -1;
+            ExitNow();
+#else
+            DieNowWithMessage("UART read", (rval < 0) ? OT_EXIT_ERROR_ERRNO : OT_EXIT_FAILURE);
+#endif
+        }
+    }
+
+#if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+    fd = STDOUT_FILENO;
+#endif
+
+    if ((sWriteLength > 0) && (FD_ISSET(fd, aWriteFdSet)))
+    {
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+        // Don't die on SIGPIPE
+#if !defined(MSG_NOSIGNAL)
+        // some platforms (mac OS, Solaris) don't have MSG_NOSIGNAL
+        // SOME of those (mac OS, but NOT Solaris) support SO_NOSIGPIPE
+        // if we have SO_NOSIGPIPE, then set it.  otherwise, we're going
+        // to simply ignore it.
+#if defined(SO_NOSIGPIPE)
+        int err;
+        int flag;
+
+        flag = 1;
+        err  = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(flag));
+        VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
+#else
+#warning "no support for MSG_NOSIGNAL or SO_NOSIGPIPE"
+#endif
+#define MSG_NOSIGNAL 0
+#endif // !defined(MSG_NOSIGNAL)
+        rval = send(fd, sWriteBuffer, sWriteLength, MSG_NOSIGNAL);
+#else
+        rval = write(fd, sWriteBuffer, sWriteLength);
+#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+
+        if (rval < 0)
+        {
+#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
+            perror("UART write");
+            close(sSessionSocket);
+            sSessionSocket = -1;
+            ExitNow();
+#else
+            DieNowWithMessage("UART write", OT_EXIT_ERROR_ERRNO);
+#endif
+        }
+
+        VerifyOrExit(rval > 0, OT_NOOP);
+
+        sWriteBuffer += (uint16_t)rval;
+        sWriteLength -= (uint16_t)rval;
+
+        if (sWriteLength == 0)
+        {
+            otPlatUartSendDone();
+        }
+    }
+
+exit:
+    return;
+}
diff --git a/src/posix/platform/udp.cpp b/src/posix/platform/udp.cpp
index 46616f8..06bea02 100644
--- a/src/posix/platform/udp.cpp
+++ b/src/posix/platform/udp.cpp
@@ -36,7 +36,7 @@
 #define __APPLE_USE_RFC_3542
 #endif
 
-#include "openthread-core-config.h"
+#include "openthread-posix-config.h"
 #include "platform-posix.h"
 
 #include <arpa/inet.h>
@@ -82,12 +82,14 @@
 static otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, const otMessageInfo &aMessageInfo)
 {
     struct sockaddr_in6 peerAddr;
-    uint8_t             control[CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int))];
-    size_t              controlLength = 0;
-    struct iovec        iov;
-    struct msghdr       msg;
-    struct cmsghdr *    cmsg;
-    ssize_t             rval;
+    uint8_t
+                    control[OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int)))];
+    size_t          controlLength = 0;
+    struct iovec    iov;
+    struct msghdr   msg;
+    struct cmsghdr *cmsg;
+    ssize_t         rval;
+    otError         error = OT_ERROR_NONE;
 
     memset(&peerAddr, 0, sizeof(peerAddr));
     peerAddr.sin6_port   = htons(aMessageInfo.mPeerPort);
@@ -156,7 +158,14 @@
     VerifyOrExit(rval > 0, perror("sendmsg"));
 
 exit:
-    return rval > 0 ? OT_ERROR_NONE : OT_ERROR_FAILED;
+    // EINVAL happens when we shift from child to router and the
+    // interface address changes. Ask callers to try again later.
+    if (rval == -1)
+    {
+        error = (errno == EINVAL) ? OT_ERROR_INVALID_STATE : OT_ERROR_FAILED;
+    }
+
+    return error;
 }
 
 static otError receivePacket(int aFd, uint8_t *aPayload, uint16_t &aLength, otMessageInfo &aMessageInfo)
@@ -182,7 +191,7 @@
     VerifyOrExit(rval > 0, perror("recvmsg"));
     aLength = static_cast<uint16_t>(rval);
 
-    for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
+    for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); cmsg != nullptr; cmsg = CMSG_NXTHDR(&msg, cmsg))
     {
         if (cmsg->cmsg_level == IPPROTO_IPV6)
         {
@@ -217,9 +226,9 @@
     otError error = OT_ERROR_NONE;
     int     fd;
 
-    assert(aUdpSocket->mHandle == NULL);
+    assert(aUdpSocket->mHandle == nullptr);
 
-    fd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+    fd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, kSocketNonBlock);
     VerifyOrExit(fd >= 0, error = OT_ERROR_FAILED);
 
     aUdpSocket->mHandle = FdToHandle(fd);
@@ -233,11 +242,11 @@
     otError error = OT_ERROR_NONE;
     int     fd;
 
-    VerifyOrExit(aUdpSocket->mHandle != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aUdpSocket->mHandle != nullptr, error = OT_ERROR_INVALID_ARGS);
     fd = FdFromHandle(aUdpSocket->mHandle);
     VerifyOrExit(0 == close(fd), error = OT_ERROR_FAILED);
 
-    aUdpSocket->mHandle = NULL;
+    aUdpSocket->mHandle = nullptr;
 
 exit:
     return error;
@@ -249,9 +258,9 @@
     int     fd;
 
     assert(sPlatNetifIndex != 0);
-    assert(aUdpSocket->mHandle != NULL);
+    assert(aUdpSocket->mHandle != nullptr);
     VerifyOrExit(sPlatNetifIndex != 0, error = OT_ERROR_INVALID_STATE);
-    VerifyOrExit(aUdpSocket->mHandle != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aUdpSocket->mHandle != nullptr, error = OT_ERROR_INVALID_ARGS);
     VerifyOrExit(aUdpSocket->mSockName.mPort != 0, error = OT_ERROR_INVALID_ARGS);
     fd = FdFromHandle(aUdpSocket->mHandle);
 
@@ -291,7 +300,7 @@
     bool isDisconnect = memcmp(&aUdpSocket->mPeerName.mAddress, &in6addr_any, sizeof(in6addr_any)) == 0 &&
                         aUdpSocket->mPeerName.mPort == 0;
 
-    VerifyOrExit(aUdpSocket->mHandle != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aUdpSocket->mHandle != nullptr, error = OT_ERROR_INVALID_ARGS);
 
     fd = FdFromHandle(aUdpSocket->mHandle);
 
@@ -340,7 +349,7 @@
     otError error = OT_ERROR_NONE;
     int     fd;
 
-    VerifyOrExit(aUdpSocket->mHandle != NULL, error = OT_ERROR_INVALID_ARGS);
+    VerifyOrExit(aUdpSocket->mHandle != nullptr, error = OT_ERROR_INVALID_ARGS);
     fd = FdFromHandle(aUdpSocket->mHandle);
 
     {
@@ -362,13 +371,13 @@
 
 void platformUdpUpdateFdSet(otInstance *aInstance, fd_set *aReadFdSet, int *aMaxFd)
 {
-    VerifyOrExit(sPlatNetifIndex != 0);
+    VerifyOrExit(sPlatNetifIndex != 0, OT_NOOP);
 
-    for (otUdpSocket *socket = otUdpGetSockets(aInstance); socket != NULL; socket = socket->mNext)
+    for (otUdpSocket *socket = otUdpGetSockets(aInstance); socket != nullptr; socket = socket->mNext)
     {
         int fd;
 
-        if (socket->mHandle == NULL)
+        if (socket->mHandle == nullptr)
         {
             continue;
         }
@@ -376,7 +385,7 @@
         fd = FdFromHandle(socket->mHandle);
         FD_SET(fd, aReadFdSet);
 
-        if (aMaxFd != NULL && *aMaxFd < fd)
+        if (aMaxFd != nullptr && *aMaxFd < fd)
         {
             *aMaxFd = fd;
         }
@@ -388,7 +397,7 @@
 
 void platformUdpInit(const char *aIfName)
 {
-    if (aIfName == NULL)
+    if (aIfName == nullptr)
     {
         DieNow(OT_EXIT_INVALID_ARGUMENTS);
     }
@@ -405,16 +414,16 @@
 {
     otMessageSettings msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL};
 
-    VerifyOrExit(sPlatNetifIndex != 0);
+    VerifyOrExit(sPlatNetifIndex != 0, OT_NOOP);
 
-    for (otUdpSocket *socket = otUdpGetSockets(aInstance); socket != NULL; socket = socket->mNext)
+    for (otUdpSocket *socket = otUdpGetSockets(aInstance); socket != nullptr; socket = socket->mNext)
     {
         int fd = FdFromHandle(socket->mHandle);
 
         if (fd > 0 && FD_ISSET(fd, aReadFdSet))
         {
             otMessageInfo messageInfo;
-            otMessage *   message = NULL;
+            otMessage *   message = nullptr;
             uint8_t       payload[kMaxUdpSize];
             uint16_t      length = sizeof(payload);
 
@@ -428,7 +437,7 @@
 
             message = otUdpNewMessage(aInstance, &msgSettings);
 
-            if (message == NULL)
+            if (message == nullptr)
             {
                 continue;
             }
diff --git a/src/posix/platform/virtual_time.cpp b/src/posix/platform/virtual_time.cpp
new file mode 100644
index 0000000..1e33e1f
--- /dev/null
+++ b/src/posix/platform/virtual_time.cpp
@@ -0,0 +1,205 @@
+/*
+ *  Copyright (c) 2018, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * @brief
+ *   This file implements the posix simulation.
+ */
+
+#include "openthread-posix-config.h"
+#include "platform-posix.h"
+
+#include <arpa/inet.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/select.h>
+#include <unistd.h>
+
+#if OPENTHREAD_POSIX_VIRTUAL_TIME
+
+static const int kWellKnownNodeId = 34;      ///< Well-known ID used by a simulated radio supporting promiscuous mode.
+static const int kBasePort        = 18000;   ///< This base port for posix app simulation.
+static const int kUsPerSecond     = 1000000; ///< Number of microseconds per second.
+
+static uint64_t sNow        = 0;  ///< Time of simulation.
+static int      sSockFd     = -1; ///< Socket used to communicating with simulator.
+static uint16_t sPortOffset = 0;  ///< Port offset for simulation.
+
+void virtualTimeInit(uint16_t aNodeId)
+{
+    struct sockaddr_in sockaddr;
+    char *             offset;
+
+    memset(&sockaddr, 0, sizeof(sockaddr));
+    sockaddr.sin_family = AF_INET;
+
+    offset = getenv("PORT_OFFSET");
+
+    if (offset)
+    {
+        char *endptr;
+
+        sPortOffset = (uint16_t)strtol(offset, &endptr, 0);
+
+        if (*endptr != '\0')
+        {
+            const uint8_t kMsgSize = 40;
+            char          msg[kMsgSize];
+
+            snprintf(msg, sizeof(msg), "Invalid PORT_OFFSET: %s", offset);
+            DieNowWithMessage(msg, OT_EXIT_INVALID_ARGUMENTS);
+        }
+
+        sPortOffset *= kWellKnownNodeId;
+    }
+
+    sockaddr.sin_port        = htons(kBasePort + sPortOffset + aNodeId);
+    sockaddr.sin_addr.s_addr = INADDR_ANY;
+
+    sSockFd = SocketWithCloseExec(AF_INET, SOCK_DGRAM, IPPROTO_UDP, kSocketBlock);
+
+    if (sSockFd == -1)
+    {
+        DieNowWithMessage("socket", OT_EXIT_ERROR_ERRNO);
+    }
+
+    if (bind(sSockFd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == -1)
+    {
+        DieNowWithMessage("bind", OT_EXIT_ERROR_ERRNO);
+    }
+}
+
+void virtualTimeDeinit(void)
+{
+    if (sSockFd != -1)
+    {
+        close(sSockFd);
+        sSockFd = -1;
+    }
+}
+
+static void virtualTimeSendEvent(struct VirtualTimeEvent *aEvent, size_t aLength)
+{
+    ssize_t            rval;
+    struct sockaddr_in sockaddr;
+
+    memset(&sockaddr, 0, sizeof(sockaddr));
+    sockaddr.sin_family = AF_INET;
+    inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr);
+    sockaddr.sin_port = htons(9000 + sPortOffset);
+
+    rval = sendto(sSockFd, aEvent, aLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
+
+    if (rval < 0)
+    {
+        DieNowWithMessage("sendto", OT_EXIT_ERROR_ERRNO);
+    }
+}
+
+void virtualTimeReceiveEvent(struct VirtualTimeEvent *aEvent)
+{
+    ssize_t rval = recvfrom(sSockFd, aEvent, sizeof(*aEvent), 0, nullptr, nullptr);
+
+    if (rval < 0 || (uint16_t)rval < offsetof(struct VirtualTimeEvent, mData))
+    {
+        DieNowWithMessage("recvfrom", (rval < 0) ? OT_EXIT_ERROR_ERRNO : OT_EXIT_FAILURE);
+    }
+
+    sNow += aEvent->mDelay;
+}
+
+void virtualTimeSendSleepEvent(const struct timeval *aTimeout)
+{
+    struct VirtualTimeEvent event;
+
+    event.mDelay      = (uint64_t)aTimeout->tv_sec * kUsPerSecond + (uint64_t)aTimeout->tv_usec;
+    event.mEvent      = OT_SIM_EVENT_ALARM_FIRED;
+    event.mDataLength = 0;
+
+    virtualTimeSendEvent(&event, offsetof(struct VirtualTimeEvent, mData));
+}
+
+void virtualTimeSendRadioSpinelWriteEvent(const uint8_t *aData, uint16_t aLength)
+{
+    struct VirtualTimeEvent event;
+
+    event.mDelay      = 0;
+    event.mEvent      = OT_SIM_EVENT_RADIO_SPINEL_WRITE;
+    event.mDataLength = aLength;
+
+    memcpy(event.mData, aData, aLength);
+
+    virtualTimeSendEvent(&event, offsetof(struct VirtualTimeEvent, mData) + event.mDataLength);
+}
+
+void virtualTimeUpdateFdSet(fd_set *        aReadFdSet,
+                            fd_set *        aWriteFdSet,
+                            fd_set *        aErrorFdSet,
+                            int *           aMaxFd,
+                            struct timeval *aTimeout)
+{
+    OT_UNUSED_VARIABLE(aWriteFdSet);
+    OT_UNUSED_VARIABLE(aErrorFdSet);
+    OT_UNUSED_VARIABLE(aTimeout);
+
+    FD_SET(sSockFd, aReadFdSet);
+    if (*aMaxFd < sSockFd)
+    {
+        *aMaxFd = sSockFd;
+    }
+}
+
+void virtualTimeProcess(otInstance *  aInstance,
+                        const fd_set *aReadFdSet,
+                        const fd_set *aWriteFdSet,
+                        const fd_set *aErrorFdSet)
+{
+    struct VirtualTimeEvent event;
+
+    memset(&event, 0, sizeof(event));
+
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aWriteFdSet);
+    OT_UNUSED_VARIABLE(aErrorFdSet);
+
+    if (FD_ISSET(sSockFd, aReadFdSet))
+    {
+        virtualTimeReceiveEvent(&event);
+    }
+
+    virtualTimeRadioSpinelProcess(aInstance, &event);
+}
+
+uint64_t otPlatTimeGet(void)
+{
+    return sNow;
+}
+
+#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..65feb22
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,29 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_subdirectory(unit)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9c7031d..7d0459c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -41,13 +41,6 @@
 SUBDIRS                                 = \
     $(NULL)
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    fuzz                                  \
-    unit                                  \
-    $(NULL)
-
 SUBDIRS                                += \
     unit                                  \
     $(NULL)
diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am
index eafd198..bce0e31 100644
--- a/tests/fuzz/Makefile.am
+++ b/tests/fuzz/Makefile.am
@@ -47,7 +47,7 @@
     $(NULL)
 
 COMMON_SOURCES                                            = \
-    fuzzer_platform.c                                       \
+    fuzzer_platform.cpp                                     \
     fuzzer_platform.h                                       \
     $(NULL)
 
diff --git a/tests/fuzz/cli_uart_received.cpp b/tests/fuzz/cli_uart_received.cpp
index d96e7e9..591caf8 100644
--- a/tests/fuzz/cli_uart_received.cpp
+++ b/tests/fuzz/cli_uart_received.cpp
@@ -47,19 +47,19 @@
 {
     const otPanId panId = 0xdead;
 
-    otInstance *instance = NULL;
-    uint8_t *   buf      = NULL;
+    otInstance *instance = nullptr;
+    uint8_t *   buf      = nullptr;
 
-    VerifyOrExit(size <= 65536);
+    VerifyOrExit(size <= 65536, OT_NOOP);
 
     FuzzerPlatformInit();
 
     instance = otInstanceInitSingle();
     otCliUartInit(instance);
-    otLinkSetPanId(instance, panId);
-    otIp6SetEnabled(instance, true);
-    otThreadSetEnabled(instance, true);
-    otThreadBecomeLeader(instance);
+    IgnoreError(otLinkSetPanId(instance, panId));
+    IgnoreError(otIp6SetEnabled(instance, true));
+    IgnoreError(otThreadSetEnabled(instance, true));
+    IgnoreError(otThreadBecomeLeader(instance));
 
     buf = static_cast<uint8_t *>(malloc(size));
 
@@ -67,7 +67,7 @@
 
     otPlatUartReceived(buf, (uint16_t)size);
 
-    VerifyOrExit(!FuzzerPlatformResetWasRequested());
+    VerifyOrExit(!FuzzerPlatformResetWasRequested(), OT_NOOP);
 
     for (int i = 0; i < MAX_ITERATIONS; i++)
     {
@@ -81,12 +81,12 @@
 
 exit:
 
-    if (buf != NULL)
+    if (buf != nullptr)
     {
         free(buf);
     }
 
-    if (instance != NULL)
+    if (instance != nullptr)
     {
         otInstanceFinalize(instance);
     }
diff --git a/tests/fuzz/fuzzer_platform.c b/tests/fuzz/fuzzer_platform.c
deleted file mode 100644
index 3dad915..0000000
--- a/tests/fuzz/fuzzer_platform.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- *  Copyright (c) 2017, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-
-#include <openthread/platform/alarm-micro.h>
-#include <openthread/platform/alarm-milli.h>
-#include <openthread/platform/diag.h>
-#include <openthread/platform/logging.h>
-#include <openthread/platform/misc.h>
-#include <openthread/platform/radio.h>
-#include <openthread/platform/settings.h>
-#include <openthread/platform/uart.h>
-
-typedef struct AlarmState
-{
-    uint32_t fire;
-    bool     isRunning;
-} AlarmState;
-
-static uint32_t     sAlarmNow;
-static AlarmState   sAlarmMilli;
-static AlarmState   sAlarmMicro;
-static uint32_t     sRandomState = 1;
-static uint8_t      sRadioTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE];
-static otRadioFrame sRadioTransmitFrame = {.mPsdu = sRadioTransmitPsdu};
-static bool         sResetWasRequested  = false;
-
-void FuzzerPlatformInit(void)
-{
-    sRandomState = 1;
-    sAlarmNow    = 0;
-    memset(&sAlarmMilli, 0, sizeof(sAlarmMilli));
-    memset(&sAlarmMicro, 0, sizeof(sAlarmMicro));
-}
-
-void FuzzerPlatformProcess(otInstance *aInstance)
-{
-    if (sAlarmMilli.isRunning || sAlarmMicro.isRunning)
-    {
-        uint32_t fire = UINT32_MAX;
-
-        if (sAlarmMilli.isRunning && fire > sAlarmMilli.fire)
-        {
-            fire = sAlarmMilli.fire;
-        }
-
-        if (sAlarmMicro.isRunning && fire > sAlarmMicro.fire)
-        {
-            fire = sAlarmMicro.fire;
-        }
-
-        sAlarmNow = fire;
-
-        if (sAlarmMilli.isRunning && sAlarmNow >= sAlarmMilli.fire)
-        {
-            sAlarmMilli.isRunning = false;
-            otPlatAlarmMilliFired(aInstance);
-        }
-
-#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
-        if (sAlarmMicro.isRunning && sAlarmNow >= sAlarmMicro.fire)
-        {
-            sAlarmMicro.isRunning = false;
-            otPlatAlarmMicroFired(aInstance);
-        }
-#endif
-    }
-}
-
-bool FuzzerPlatformResetWasRequested(void)
-{
-    return sResetWasRequested;
-}
-
-uint32_t otPlatAlarmMilliGetNow(void)
-{
-    return sAlarmNow / 1000;
-}
-
-void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sAlarmMilli.fire      = (aT0 + aDt) * 1000;
-    sAlarmMilli.isRunning = true;
-}
-
-void otPlatAlarmMilliStop(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sAlarmMilli.isRunning = false;
-}
-
-uint32_t otPlatAlarmMicroGetNow(void)
-{
-    return sAlarmNow;
-}
-
-void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sAlarmMicro.fire      = aT0 + aDt;
-    sAlarmMicro.isRunning = true;
-}
-
-void otPlatAlarmMicroStop(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sAlarmMicro.isRunning = false;
-}
-
-bool otDiagIsEnabled(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    return false;
-}
-
-void otDiagProcessCmd(otInstance *aInstance, int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aArgCount);
-    OT_UNUSED_VARIABLE(aArgVector);
-    OT_UNUSED_VARIABLE(aOutput);
-    OT_UNUSED_VARIABLE(aOutputMaxLen);
-}
-
-void otDiagProcessCmdLine(otInstance *aInstance, const char *aString, char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aString);
-    OT_UNUSED_VARIABLE(aOutput);
-    OT_UNUSED_VARIABLE(aOutputMaxLen);
-}
-
-void otPlatReset(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-
-    sResetWasRequested = true;
-}
-
-otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return OT_PLAT_RESET_REASON_POWER_ON;
-}
-
-void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
-{
-    OT_UNUSED_VARIABLE(aLogLevel);
-    OT_UNUSED_VARIABLE(aLogRegion);
-    OT_UNUSED_VARIABLE(aFormat);
-}
-
-void otPlatWakeHost(void)
-{
-}
-
-void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aIeeeEui64);
-}
-
-void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aPanId);
-}
-
-void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddr)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aExtAddr);
-}
-
-void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aShortAddr)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aShortAddr);
-}
-
-void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnabled)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aEnabled);
-}
-
-bool otPlatRadioIsEnabled(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return true;
-}
-
-otError otPlatRadioEnable(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioDisable(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioSleep(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aChannel);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aFrame);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aPower);
-    return OT_ERROR_NONE;
-}
-
-otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return &sRadioTransmitFrame;
-}
-
-int8_t otPlatRadioGetRssi(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return 0;
-}
-
-otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return OT_RADIO_CAPS_NONE;
-}
-
-bool otPlatRadioGetPromiscuous(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return false;
-}
-
-void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aEnable);
-}
-
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aShortAddress);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aExtAddress);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aShortAddress);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aExtAddress);
-    return OT_ERROR_NONE;
-}
-
-void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aScanChannel);
-    OT_UNUSED_VARIABLE(aScanDuration);
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aPower);
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aThreshold);
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aThreshold);
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    return 0;
-}
-
-otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
-{
-    for (uint16_t length = 0; length < aOutputLength; length++)
-    {
-        aOutput[length] = (uint8_t)rand();
-    }
-
-    return OT_ERROR_NONE;
-}
-
-void otPlatSettingsInit(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-void otPlatSettingsDeinit(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aKey);
-    OT_UNUSED_VARIABLE(aIndex);
-    OT_UNUSED_VARIABLE(aValue);
-    OT_UNUSED_VARIABLE(aValueLength);
-    return OT_ERROR_NOT_FOUND;
-}
-
-otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aKey);
-    OT_UNUSED_VARIABLE(aValue);
-    OT_UNUSED_VARIABLE(aValueLength);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aKey);
-    OT_UNUSED_VARIABLE(aValue);
-    OT_UNUSED_VARIABLE(aValueLength);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aKey);
-    OT_UNUSED_VARIABLE(aIndex);
-    return OT_ERROR_NONE;
-}
-
-void otPlatSettingsWipe(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
-
-otError otPlatUartEnable(void)
-{
-    return OT_ERROR_NONE;
-}
-
-otError otPlatUartDisable(void)
-{
-    return OT_ERROR_NONE;
-}
-
-otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
-{
-    OT_UNUSED_VARIABLE(aBuf);
-    OT_UNUSED_VARIABLE(aBufLength);
-    return OT_ERROR_NONE;
-}
-
-otError otPlatUartFlush(void)
-{
-    return OT_ERROR_NOT_IMPLEMENTED;
-}
-
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
-    OT_UNUSED_VARIABLE(argv);
-    OT_UNUSED_VARIABLE(aOutput);
-    OT_UNUSED_VARIABLE(aOutputMaxLen);
-}
-
-void otPlatDiagModeSet(bool aMode)
-{
-    OT_UNUSED_VARIABLE(aMode);
-}
-
-bool otPlatDiagModeGet(void)
-{
-    return false;
-}
-
-void otPlatDiagChannelSet(uint8_t aChannel)
-{
-    OT_UNUSED_VARIABLE(aChannel);
-}
-
-void otPlatDiagTxPowerSet(int8_t aTxPower)
-{
-    OT_UNUSED_VARIABLE(aTxPower);
-}
-
-void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(aFrame);
-    OT_UNUSED_VARIABLE(aError);
-}
-
-void otPlatDiagAlarmCallback(otInstance *aInstance)
-{
-    OT_UNUSED_VARIABLE(aInstance);
-}
diff --git a/tests/fuzz/fuzzer_platform.cpp b/tests/fuzz/fuzzer_platform.cpp
new file mode 100644
index 0000000..a262044
--- /dev/null
+++ b/tests/fuzz/fuzzer_platform.cpp
@@ -0,0 +1,563 @@
+/*
+ *  Copyright (c) 2017, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "openthread-core-config.h"
+
+#include "fuzzer_platform.h"
+
+#include <string.h>
+
+#include <openthread/platform/alarm-micro.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/diag.h>
+#include <openthread/platform/entropy.h>
+#include <openthread/platform/logging.h>
+#include <openthread/platform/misc.h>
+#include <openthread/platform/radio.h>
+#include <openthread/platform/settings.h>
+#include <openthread/platform/uart.h>
+
+#include "mac/mac_frame.hpp"
+
+using namespace ot;
+
+typedef struct AlarmState
+{
+    uint32_t fire;
+    bool     isRunning;
+} AlarmState;
+
+enum
+{
+    IEEE802154_ACK_LENGTH = 5,
+
+    IEEE802154_FRAME_TYPE_ACK = 2 << 0,
+};
+
+static uint32_t     sAlarmNow;
+static AlarmState   sAlarmMilli;
+static AlarmState   sAlarmMicro;
+static uint32_t     sRandomState = 1;
+static uint8_t      sRadioTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE];
+static otRadioFrame sRadioTransmitFrame;
+static uint8_t      sRadioAckPsdu[OT_RADIO_FRAME_MAX_SIZE];
+static otRadioFrame sRadioAckFrame;
+static bool         sResetWasRequested = false;
+static otRadioState sRadioState        = OT_RADIO_STATE_DISABLED;
+
+bool otMacFrameIsAckRequested(const otRadioFrame *aFrame)
+{
+    return static_cast<const Mac::Frame *>(aFrame)->GetAckRequest();
+}
+
+uint8_t otMacFrameGetSequence(const otRadioFrame *aFrame)
+{
+    return static_cast<const Mac::Frame *>(aFrame)->GetSequence();
+}
+
+void FuzzerPlatformInit(void)
+{
+    sRandomState = 1;
+    sAlarmNow    = 0;
+    memset(&sAlarmMilli, 0, sizeof(sAlarmMilli));
+    memset(&sAlarmMicro, 0, sizeof(sAlarmMicro));
+
+    sRadioTransmitFrame.mPsdu = sRadioTransmitPsdu;
+    sRadioAckFrame.mPsdu      = sRadioAckPsdu;
+}
+
+void FuzzerPlatformProcess(otInstance *aInstance)
+{
+    if (sRadioState == OT_RADIO_STATE_TRANSMIT)
+    {
+        sRadioState = OT_RADIO_STATE_RECEIVE;
+
+        if (otMacFrameIsAckRequested(&sRadioTransmitFrame))
+        {
+            sRadioAckFrame.mLength  = IEEE802154_ACK_LENGTH;
+            sRadioAckFrame.mPsdu[0] = IEEE802154_FRAME_TYPE_ACK;
+            sRadioAckFrame.mPsdu[1] = 0;
+            sRadioAckFrame.mPsdu[2] = otMacFrameGetSequence(&sRadioTransmitFrame);
+            sRadioAckFrame.mChannel = sRadioTransmitFrame.mChannel;
+
+            otPlatRadioTxDone(aInstance, &sRadioTransmitFrame, &sRadioAckFrame, OT_ERROR_NONE);
+        }
+        else
+        {
+            otPlatRadioTxDone(aInstance, &sRadioTransmitFrame, nullptr, OT_ERROR_NONE);
+        }
+    }
+
+    if (sAlarmMilli.isRunning || sAlarmMicro.isRunning)
+    {
+        uint32_t fire = UINT32_MAX;
+
+        if (sAlarmMilli.isRunning && fire > sAlarmMilli.fire)
+        {
+            fire = sAlarmMilli.fire;
+        }
+
+        if (sAlarmMicro.isRunning && fire > sAlarmMicro.fire)
+        {
+            fire = sAlarmMicro.fire;
+        }
+
+        sAlarmNow = fire;
+
+        if (sAlarmMilli.isRunning && sAlarmNow >= sAlarmMilli.fire)
+        {
+            sAlarmMilli.isRunning = false;
+            otPlatAlarmMilliFired(aInstance);
+        }
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+        if (sAlarmMicro.isRunning && sAlarmNow >= sAlarmMicro.fire)
+        {
+            sAlarmMicro.isRunning = false;
+            otPlatAlarmMicroFired(aInstance);
+        }
+#endif
+    }
+}
+
+bool FuzzerPlatformResetWasRequested(void)
+{
+    return sResetWasRequested;
+}
+
+uint32_t otPlatAlarmMilliGetNow(void)
+{
+    return sAlarmNow / 1000;
+}
+
+void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sAlarmMilli.fire      = (aT0 + aDt) * 1000;
+    sAlarmMilli.isRunning = true;
+}
+
+void otPlatAlarmMilliStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sAlarmMilli.isRunning = false;
+}
+
+uint32_t otPlatAlarmMicroGetNow(void)
+{
+    return sAlarmNow;
+}
+
+void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sAlarmMicro.fire      = aT0 + aDt;
+    sAlarmMicro.isRunning = true;
+}
+
+void otPlatAlarmMicroStop(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sAlarmMicro.isRunning = false;
+}
+
+bool otDiagIsEnabled(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return false;
+}
+
+otError otDiagProcessCmd(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
+    OT_UNUSED_VARIABLE(aOutput);
+    OT_UNUSED_VARIABLE(aOutputMaxLen);
+
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+void otDiagProcessCmdLine(otInstance *aInstance, const char *aString, char *aOutput, size_t aOutputMaxLen)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aString);
+    OT_UNUSED_VARIABLE(aOutput);
+    OT_UNUSED_VARIABLE(aOutputMaxLen);
+}
+
+void otPlatReset(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sResetWasRequested = true;
+}
+
+otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return OT_PLAT_RESET_REASON_POWER_ON;
+}
+
+void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
+{
+    OT_UNUSED_VARIABLE(aLogLevel);
+    OT_UNUSED_VARIABLE(aLogRegion);
+    OT_UNUSED_VARIABLE(aFormat);
+}
+
+void otPlatWakeHost(void)
+{
+}
+
+void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aIeeeEui64);
+}
+
+void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aPanId);
+}
+
+void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddr)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aExtAddr);
+}
+
+void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aShortAddr)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aShortAddr);
+}
+
+void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnabled)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aEnabled);
+}
+
+bool otPlatRadioIsEnabled(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return true;
+}
+
+otError otPlatRadioEnable(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sRadioState = OT_RADIO_STATE_SLEEP;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioDisable(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sRadioState = OT_RADIO_STATE_DISABLED;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioSleep(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    sRadioState = OT_RADIO_STATE_SLEEP;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aChannel);
+
+    sRadioState = OT_RADIO_STATE_RECEIVE;
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
+{
+    sRadioState = OT_RADIO_STATE_TRANSMIT;
+
+    otPlatRadioTxStarted(aInstance, aFrame);
+
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aPower);
+    return OT_ERROR_NONE;
+}
+
+otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return &sRadioTransmitFrame;
+}
+
+int8_t otPlatRadioGetRssi(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return 0;
+}
+
+otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return OT_RADIO_CAPS_NONE;
+}
+
+bool otPlatRadioGetPromiscuous(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return false;
+}
+
+void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aEnable);
+}
+
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aShortAddress);
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aExtAddress);
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aShortAddress);
+    return OT_ERROR_NONE;
+}
+
+otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aExtAddress);
+    return OT_ERROR_NONE;
+}
+
+void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aScanChannel);
+    OT_UNUSED_VARIABLE(aScanDuration);
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aPower);
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aThreshold);
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aThreshold);
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    return 0;
+}
+
+otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
+{
+    for (uint16_t length = 0; length < aOutputLength; length++)
+    {
+        aOutput[length] = (uint8_t)rand();
+    }
+
+    return OT_ERROR_NONE;
+}
+
+void otPlatSettingsInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+void otPlatSettingsDeinit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aKey);
+    OT_UNUSED_VARIABLE(aIndex);
+    OT_UNUSED_VARIABLE(aValue);
+    OT_UNUSED_VARIABLE(aValueLength);
+    return OT_ERROR_NOT_FOUND;
+}
+
+otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aKey);
+    OT_UNUSED_VARIABLE(aValue);
+    OT_UNUSED_VARIABLE(aValueLength);
+    return OT_ERROR_NONE;
+}
+
+otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aKey);
+    OT_UNUSED_VARIABLE(aValue);
+    OT_UNUSED_VARIABLE(aValueLength);
+    return OT_ERROR_NONE;
+}
+
+otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aKey);
+    OT_UNUSED_VARIABLE(aIndex);
+    return OT_ERROR_NONE;
+}
+
+void otPlatSettingsWipe(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
+
+otError otPlatUartEnable(void)
+{
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartDisable(void)
+{
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
+{
+    OT_UNUSED_VARIABLE(aBuf);
+    OT_UNUSED_VARIABLE(aBufLength);
+    return OT_ERROR_NONE;
+}
+
+otError otPlatUartFlush(void)
+{
+    return OT_ERROR_NOT_IMPLEMENTED;
+}
+
+otError otPlatDiagProcess(otInstance *aInstance,
+                          uint8_t     aArgsLength,
+                          char *      aArgs[],
+                          char *      aOutput,
+                          size_t      aOutputMaxLen)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aArgsLength);
+    OT_UNUSED_VARIABLE(aArgs);
+    OT_UNUSED_VARIABLE(aOutput);
+    OT_UNUSED_VARIABLE(aOutputMaxLen);
+
+    return OT_ERROR_INVALID_COMMAND;
+}
+
+void otPlatDiagModeSet(bool aMode)
+{
+    OT_UNUSED_VARIABLE(aMode);
+}
+
+bool otPlatDiagModeGet(void)
+{
+    return false;
+}
+
+void otPlatDiagChannelSet(uint8_t aChannel)
+{
+    OT_UNUSED_VARIABLE(aChannel);
+}
+
+void otPlatDiagTxPowerSet(int8_t aTxPower)
+{
+    OT_UNUSED_VARIABLE(aTxPower);
+}
+
+void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+    OT_UNUSED_VARIABLE(aFrame);
+    OT_UNUSED_VARIABLE(aError);
+}
+
+void otPlatDiagAlarmCallback(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+}
diff --git a/tests/fuzz/fuzzer_platform.h b/tests/fuzz/fuzzer_platform.h
index 2a87efd..343039c 100644
--- a/tests/fuzz/fuzzer_platform.h
+++ b/tests/fuzz/fuzzer_platform.h
@@ -29,6 +29,8 @@
 #ifndef FUZZER_PLATFORM_H_
 #define FUZZER_PLATFORM_H_
 
+#include <openthread/instance.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/tests/fuzz/ip6_send.cpp b/tests/fuzz/ip6_send.cpp
index a28f8fe..b11f03c 100644
--- a/tests/fuzz/ip6_send.cpp
+++ b/tests/fuzz/ip6_send.cpp
@@ -45,35 +45,35 @@
 {
     const otPanId panId = 0xdead;
 
-    otInstance *      instance = NULL;
-    otMessage *       message  = NULL;
+    otInstance *      instance = nullptr;
+    otMessage *       message  = nullptr;
     otError           error    = OT_ERROR_NONE;
     otMessageSettings settings;
 
-    VerifyOrExit(size > 0);
+    VerifyOrExit(size > 0, OT_NOOP);
 
     FuzzerPlatformInit();
 
     instance = otInstanceInitSingle();
-    otLinkSetPanId(instance, panId);
-    otIp6SetEnabled(instance, true);
-    otThreadSetEnabled(instance, true);
-    otThreadBecomeLeader(instance);
+    IgnoreError(otLinkSetPanId(instance, panId));
+    IgnoreError(otIp6SetEnabled(instance, true));
+    IgnoreError(otThreadSetEnabled(instance, true));
+    IgnoreError(otThreadBecomeLeader(instance));
 
     settings.mLinkSecurityEnabled = (data[0] & 0x1) != 0;
     settings.mPriority            = OT_MESSAGE_PRIORITY_NORMAL;
 
     message = otIp6NewMessage(instance, &settings);
-    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
+    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
 
     error = otMessageAppend(message, data + 1, static_cast<uint16_t>(size - 1));
     SuccessOrExit(error);
 
     error = otIp6Send(instance, message);
 
-    message = NULL;
+    message = nullptr;
 
-    VerifyOrExit(!FuzzerPlatformResetWasRequested());
+    VerifyOrExit(!FuzzerPlatformResetWasRequested(), OT_NOOP);
 
     for (int i = 0; i < MAX_ITERATIONS; i++)
     {
@@ -87,12 +87,12 @@
 
 exit:
 
-    if (message != NULL)
+    if (message != nullptr)
     {
         otMessageFree(message);
     }
 
-    if (instance != NULL)
+    if (instance != nullptr)
     {
         otInstanceFinalize(instance);
     }
diff --git a/tests/fuzz/ncp_uart_received.cpp b/tests/fuzz/ncp_uart_received.cpp
index 857dd4e..10f08ec 100644
--- a/tests/fuzz/ncp_uart_received.cpp
+++ b/tests/fuzz/ncp_uart_received.cpp
@@ -47,19 +47,19 @@
 {
     const otPanId panId = 0xdead;
 
-    otInstance *instance = NULL;
-    uint8_t *   buf      = NULL;
+    otInstance *instance = nullptr;
+    uint8_t *   buf      = nullptr;
 
-    VerifyOrExit(size <= 65536);
+    VerifyOrExit(size <= 65536, OT_NOOP);
 
     FuzzerPlatformInit();
 
     instance = otInstanceInitSingle();
     otNcpInit(instance);
-    otLinkSetPanId(instance, panId);
-    otIp6SetEnabled(instance, true);
-    otThreadSetEnabled(instance, true);
-    otThreadBecomeLeader(instance);
+    IgnoreError(otLinkSetPanId(instance, panId));
+    IgnoreError(otIp6SetEnabled(instance, true));
+    IgnoreError(otThreadSetEnabled(instance, true));
+    IgnoreError(otThreadBecomeLeader(instance));
 
     buf = static_cast<uint8_t *>(malloc(size));
 
@@ -67,7 +67,7 @@
 
     otPlatUartReceived(buf, (uint16_t)size);
 
-    VerifyOrExit(!FuzzerPlatformResetWasRequested());
+    VerifyOrExit(!FuzzerPlatformResetWasRequested(), OT_NOOP);
 
     for (int i = 0; i < MAX_ITERATIONS; i++)
     {
@@ -81,12 +81,12 @@
 
 exit:
 
-    if (buf != NULL)
+    if (buf != nullptr)
     {
         free(buf);
     }
 
-    if (instance != NULL)
+    if (instance != nullptr)
     {
         otInstanceFinalize(instance);
     }
diff --git a/tests/fuzz/radio_receive_done.cpp b/tests/fuzz/radio_receive_done.cpp
index cafcf8b..70aba45 100644
--- a/tests/fuzz/radio_receive_done.cpp
+++ b/tests/fuzz/radio_receive_done.cpp
@@ -46,19 +46,19 @@
 {
     const otPanId panId = 0xdead;
 
-    otInstance * instance = NULL;
+    otInstance * instance = nullptr;
     otRadioFrame frame;
-    uint8_t *    buf = NULL;
+    uint8_t *    buf = nullptr;
 
-    VerifyOrExit(size <= OT_RADIO_FRAME_MAX_SIZE);
+    VerifyOrExit(size <= OT_RADIO_FRAME_MAX_SIZE, OT_NOOP);
 
     FuzzerPlatformInit();
 
     instance = otInstanceInitSingle();
-    otLinkSetPanId(instance, panId);
-    otIp6SetEnabled(instance, true);
-    otThreadSetEnabled(instance, true);
-    otThreadBecomeLeader(instance);
+    IgnoreError(otLinkSetPanId(instance, panId));
+    IgnoreError(otIp6SetEnabled(instance, true));
+    IgnoreError(otThreadSetEnabled(instance, true));
+    IgnoreError(otThreadBecomeLeader(instance));
 
     buf = static_cast<uint8_t *>(malloc(size));
 
@@ -71,7 +71,7 @@
 
     otPlatRadioReceiveDone(instance, &frame, OT_ERROR_NONE);
 
-    VerifyOrExit(!FuzzerPlatformResetWasRequested());
+    VerifyOrExit(!FuzzerPlatformResetWasRequested(), OT_NOOP);
 
     for (int i = 0; i < MAX_ITERATIONS; i++)
     {
@@ -85,12 +85,12 @@
 
 exit:
 
-    if (buf != NULL)
+    if (buf != nullptr)
     {
         free(buf);
     }
 
-    if (instance != NULL)
+    if (instance != nullptr)
     {
         otInstanceFinalize(instance);
     }
diff --git a/tests/scripts/Makefile.am b/tests/scripts/Makefile.am
index 4613bab..d1cd8f1 100644
--- a/tests/scripts/Makefile.am
+++ b/tests/scripts/Makefile.am
@@ -47,10 +47,5 @@
 endif
 endif
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
 
diff --git a/tests/scripts/expect/_common.exp b/tests/scripts/expect/_common.exp
new file mode 100644
index 0000000..f3a7cc7
--- /dev/null
+++ b/tests/scripts/expect/_common.exp
@@ -0,0 +1,72 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+proc wait_for {command expected} {
+    set result 0
+    set timeout 1
+    for {set i 0} {$i < 20} {incr i} {
+        if {$command != ""} {
+            send "$command\n"
+        }
+
+        expect {
+            -re $expected {
+                set result 1
+            }
+            timeout {
+                # Do nothing
+            }
+        }
+        if {$result == 1} {
+            break
+        }
+    }
+    if {$result == 0} {
+        exit 1
+    }
+}
+
+proc spawn_node {id} {
+    if {[info exists ::env(RCP_COMMAND)] && $::env(RCP_COMMAND) != ""} {
+        spawn $::env(OT_COMMAND) "spinel+hdlc+uart://$::env(RCP_COMMAND)?forkpty-arg=$id"
+    } else {
+        spawn $::env(OT_COMMAND) $id
+    }
+    expect_after {
+        timeout { exit 1 }
+    }
+    return $spawn_id
+}
+
+proc dispose {} {
+    send "\x04"
+    expect eof
+}
+
+set timeout 10
diff --git a/tests/scripts/expect/_multinode.exp b/tests/scripts/expect/_multinode.exp
new file mode 100644
index 0000000..3844607
--- /dev/null
+++ b/tests/scripts/expect/_multinode.exp
@@ -0,0 +1,95 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+proc setup_nodes {} {
+    # Sets up a Thread network with 2 nodes, spawn_1 as the leader and spawn_2
+    # as a child.
+
+    global spawn_1
+    global spawn_2
+    global spawn_id
+    global env
+
+    set spawn_1 [spawn_node 1]
+    set spawn_2 [spawn_node 2]
+    set psk "J01NME"
+
+    set spawn_id $spawn_2
+    send "eui64\n"
+    expect -re {([0-9a-f]{16})}
+    set eui64 $expect_out(1,string)
+    expect "Done"
+
+    set spawn_id $spawn_1
+    send "dataset init new\n"
+    expect "Done"
+    send "dataset commit active\n"
+    expect "Done"
+    send "ifconfig up\n"
+    expect "Done"
+    send "thread start\n"
+    expect "Done"
+    wait_for "state" "leader"
+    expect "Done"
+    send "commissioner start\n"
+    expect "Done"
+    expect "Commissioner: active"
+    send "commissioner joiner add $eui64 $psk\n"
+    expect "Done"
+    send "channel\n"
+    expect -re {(\d+)}
+    set channel $expect_out(1,string)
+    expect "Done"
+
+    set spawn_id $spawn_2
+    send "mode rs\n"
+    expect "Done"
+    send "ifconfig up\n"
+    expect "Done"
+    send "joiner start $psk\n"
+    expect "Done"
+    wait_for "" "Join success"
+    send "thread start\n"
+    expect "Done"
+    wait_for "state" "child"
+    expect "Done"
+}
+
+proc dispose_nodes {} {
+    global spawn_1
+    global spawn_2
+    global spawn_id
+
+    set spawn_id $spawn_1
+    dispose
+    set spawn_id $spawn_2
+    dispose
+}
diff --git a/tests/scripts/expect/cli-channel.exp b/tests/scripts/expect/cli-channel.exp
new file mode 100755
index 0000000..007f537
--- /dev/null
+++ b/tests/scripts/expect/cli-channel.exp
@@ -0,0 +1,89 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "ifconfig up\n"
+expect "Done"
+send "thread start\n"
+expect "Done"
+
+send "channel monitor stop\n"
+expect "Done"
+send "channel monitor\n"
+expect "enabled: 0"
+expect "Done"
+send "channel monitor start\n"
+expect "Done"
+send "channel monitor\n"
+expect "enabled: 1"
+expect -re {interval: \d+}
+expect -re {threshold: -?\d+}
+expect -re {window: \d+}
+expect -re {count: \d+}
+expect "occupancies:"
+for {set i 11} {$i <= 26} {incr i} {
+    expect -re "ch $i \\(0x\[0-9a-f\]{4}\\) +\\d+\\.\\d+% busy"
+}
+expect "Done"
+send "channel monitor something_invalid\n"
+expect "Error 7: InvalidArgs"
+
+send "channel manager change 15\n"
+expect "Done"
+send "channel manager\n"
+expect "channel: 15"
+expect "auto: 0"
+expect "Done"
+send "channel manager select 1\n"
+expect "Error 13: InvalidState" # Because of insufficient channel monitor samples
+send "channel manager delay 200\n"
+expect "Done"
+send "channel manager interval 20000\n"
+expect "Done"
+send "channel manager supported 0x7fff800\n"
+expect "Done"
+send "channel manager favored 0x7fff800\n"
+expect "Done"
+send "channel manager auto 1\n"
+expect "Done"
+send "channel manager\n"
+expect "channel: 15"
+expect "auto: 1"
+expect "delay: 200"
+expect "interval: 20000"
+expect "supported: { 11-26}"
+expect "favored: { 11-26}"
+expect "Done"
+send "channel manager something_invalid\n"
+expect "Error 7: InvalidArgs"
+
+dispose
diff --git a/tests/scripts/expect/cli-child.exp b/tests/scripts/expect/cli-child.exp
new file mode 100755
index 0000000..a630038
--- /dev/null
+++ b/tests/scripts/expect/cli-child.exp
@@ -0,0 +1,62 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_2
+send "extaddr\n"
+expect "extaddr"
+expect -re {([0-9a-f]{16})}
+set extaddr $expect_out(1,string)
+expect "Done"
+send "rloc16\n"
+expect "rloc16"
+expect -re {([0-9a-f]{4})}
+set rloc $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_1
+send "child table\n"
+expect "| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |"
+expect "+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+"
+expect -re "\\| +(\\d+) \\| 0x$rloc \\| +\\d+ \\| +\\d+ \\| +\\d+ \\| +\\d+ \\|\\d\\|\\d\\|\\d\\|\\d\\| $extaddr \\|"
+set child_id $expect_out(1,string)
+expect "Done"
+send "child list\n"
+expect "child list"
+expect $child_id
+expect "Done"
+send "child $child_id\n"
+expect "Ext Addr: $extaddr"
+expect "Done"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-childip.exp b/tests/scripts/expect/cli-childip.exp
new file mode 100755
index 0000000..1d8581b
--- /dev/null
+++ b/tests/scripts/expect/cli-childip.exp
@@ -0,0 +1,61 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_2
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr $expect_out(1,string)
+expect "Done"
+send "rloc16\n"
+expect "rloc16"
+expect -re {([0-9a-f]{4})}
+set rloc $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_1
+send "childip\n"
+expect "$rloc: $addr"
+expect "Done"
+send "childip max 2\n"
+expect "Done"
+send "childip max\n"
+expect "2"
+expect "Done"
+send "childip max something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "childip something_invalid\n"
+expect "Error 35: InvalidCommand"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-coap.exp b/tests/scripts/expect/cli-coap.exp
new file mode 100755
index 0000000..829d43b
--- /dev/null
+++ b/tests/scripts/expect/cli-coap.exp
@@ -0,0 +1,114 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_1
+send "coap start\n"
+expect "Done"
+send "coap resource test/resource\n"
+expect "Done"
+send "coap set Testing123\n"
+expect "Done"
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr_1 $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_2
+send "coap start\n"
+expect "Done"
+send "coap parameters request 3000 4 3 5\n"
+expect "Transmission parameters for request:"
+expect "ACK_TIMEOUT=3000 ms, ACK_RANDOM_FACTOR=4/3, MAX_RETRANSMIT=5"
+expect "Done"
+send "coap parameters response 2500 4 3 3\n"
+expect "Transmission parameters for response:"
+expect "ACK_TIMEOUT=2500 ms, ACK_RANDOM_FACTOR=4/3, MAX_RETRANSMIT=3"
+expect "Done"
+send "coap get $addr_1 test/resource\n"
+expect "Done"
+expect "coap response from $addr_1 with payload: 54657374696e67313233" # ASCII of "Testing123"
+send "coap post $addr_1 test/resource con Testing123\n"
+expect "Done"
+expect "coap response from $addr_1"
+send "coap put $addr_1 test/resource con Testing123\n"
+expect "Done"
+expect "coap response from $addr_1"
+send "coap delete $addr_1 test/resource con\n"
+expect "Done"
+expect "coap response from $addr_1"
+send "coap post $addr_1 test/resource none Testing123\n"
+expect "Done"
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr_2 $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_1
+expect "coap request from $addr_2 GET"
+expect "coap response sent"
+expect "coap request from $addr_2 POST with payload: 54657374696e67313233"
+expect "coap response sent"
+expect "coap request from $addr_2 PUT with payload: 54657374696e67313233"
+expect "coap response sent"
+expect "coap request from $addr_2 DELETE"
+expect "coap response sent"
+expect "coap request from $addr_2 POST with payload: 54657374696e67313233"
+send "coap resource\n"
+expect "test/resource"
+expect "Done"
+send "coap set\n"
+expect "Testing123"
+expect "Done"
+send "coap parameters request default\n"
+expect "Transmission parameters for request:"
+expect "default"
+expect "Done"
+send "coap parameters response default\n"
+expect "Transmission parameters for response:"
+expect "default"
+expect "Done"
+send "coap help\n"
+expect "Done"
+send "coap parameters something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "coap get\n"
+expect "Error 7: InvalidArgs"
+send "coap get $addr_2\n"
+expect "Error 7: InvalidArgs"
+send "coap\n"
+expect "Error 7: InvalidArgs"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-coaps.exp b/tests/scripts/expect/cli-coaps.exp
new file mode 100755
index 0000000..5502d8f
--- /dev/null
+++ b/tests/scripts/expect/cli-coaps.exp
@@ -0,0 +1,116 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_1
+send "coaps x509\n"
+expect "Done"
+send "coaps start\n"
+expect "Done"
+send "coaps resource test/resource\n"
+expect "Done"
+send "coaps set Testing123\n"
+expect "Done"
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr_1 $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_2
+send "coaps x509\n"
+expect "Done"
+send "coaps start\n"
+expect "Done"
+send "coaps connect $addr_1 5684\n"
+expect "Done"
+expect "coaps connected"
+send "coaps get $addr_1 test/resource\n"
+expect "Done"
+expect "coaps response from $addr_1 with payload: 54657374696e67313233" # ASCII of "Testing123"
+send "coaps post $addr_1 test/resource con Testing123\n"
+expect "Done"
+expect "coaps response from $addr_1"
+send "coaps put $addr_1 test/resource con Testing123\n"
+expect "Done"
+expect "coaps response from $addr_1"
+send "coaps delete $addr_1 test/resource con\n"
+expect "Done"
+expect "coaps response from $addr_1"
+send "coaps post $addr_1 test/resource none Testing123\n"
+expect "Done"
+send "coaps get $addr_1 default\n"
+expect "Done"
+expect "coaps response from $addr_1"
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr_2 $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_1
+expect "coaps request from $addr_2 GET"
+expect "coaps response sent"
+expect "coaps request from $addr_2 POST with payload: 54657374696e67313233"
+expect "coaps response sent"
+expect "coaps request from $addr_2 PUT with payload: 54657374696e67313233"
+expect "coaps response sent"
+expect "coaps request from $addr_2 DELETE"
+expect "coaps response sent"
+expect "coaps request from $addr_2 POST with payload: 54657374696e67313233"
+send "coaps resource\n"
+expect "test/resource"
+expect "Done"
+send "coaps set\n"
+expect "Testing123"
+expect "Done"
+send "coaps help\n"
+expect "Done"
+send "coaps get\n"
+expect "Error 7: InvalidArgs"
+send "coaps\n"
+expect "Error 7: InvalidArgs"
+send "coaps start false\n"
+expect "Error 24: Already"
+send "coaps start something_invalid\n"
+expect "Error 7: InvalidArgs"
+
+set spawn_id $spawn_2
+send "coaps stop\n"
+expect "Done"
+
+set spawn_id $spawn_1
+send "coaps stop\n"
+expect "Done"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-coex.exp b/tests/scripts/expect/cli-coex.exp
new file mode 100755
index 0000000..6355509
--- /dev/null
+++ b/tests/scripts/expect/cli-coex.exp
@@ -0,0 +1,70 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "coex disable\n"
+expect "Done"
+send "coex\n"
+expect "Disabled"
+expect "Done"
+send "coex enable\n"
+expect "Done"
+send "coex\n"
+expect "Enabled"
+expect "Done"
+send "coex metrics\n"
+expect -re {Stopped: (true|false)}
+expect -re {Grant Glitch: \d+}
+expect "Transmit metrics"
+expect -re {    Request: \d+}
+expect -re {    Grant Immediate: \d+}
+expect -re {    Grant Wait: \d+}
+expect -re {    Grant Wait Activated: \d+}
+expect -re {    Grant Wait Timeout: \d+}
+expect -re {    Grant Deactivated During Request: \d+}
+expect -re {    Delayed Grant: \d+}
+expect -re {    Average Request To Grant Time: \d+}
+expect "Receive metrics"
+expect -re {    Request: \d+}
+expect -re {    Grant Immediate: \d+}
+expect -re {    Grant Wait: \d+}
+expect -re {    Grant Wait Activated: \d+}
+expect -re {    Grant Wait Timeout: \d+}
+expect -re {    Grant Deactivated During Request: \d+}
+expect -re {    Delayed Grant: \d+}
+expect -re {    Average Request To Grant Time: \d+}
+expect -re {    Grant None: \d+}
+expect "Done"
+send "coex something_invalid\n"
+expect "Error 7: InvalidArgs"
+
+dispose
diff --git a/tests/scripts/expect/cli-commissioner.exp b/tests/scripts/expect/cli-commissioner.exp
new file mode 100755
index 0000000..d31ce46
--- /dev/null
+++ b/tests/scripts/expect/cli-commissioner.exp
@@ -0,0 +1,69 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_2
+send "commissioner start\n"
+expect "Done"
+expect "Commissioner: active"
+send "commissioner provisioningurl openthread.io\n"
+expect "Done"
+send "commissioner joiner add * J01NME 1\n"
+expect "Done"
+send "commissioner joiner remove *\n"
+expect "Done"
+send "commissioner sessionid\n"
+expect "commissioner sessionid"
+expect -re {(\d+)}
+set sessionid $expect_out(1,string)
+send "commissioner mgmtset sessionid $sessionid steeringdata ffffffff joinerudpport 10001\n"
+expect "Done"
+send "commissioner mgmtset sessionid $sessionid locator 0x0100\n"
+expect "Done"
+send "commissioner mgmtget sessionid steeringdata joinerudpport locator binary 0b081209\n"
+expect "Done"
+send "commissioner stop\n"
+expect "Commissioner: disabled"
+expect "Done"
+send "commissioner help\n"
+expect "Done"
+send "commissioner joiner something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "commissioner mgmtget something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "commissioner mgmtset something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "commissioner\n"
+expect "Error 35: InvalidCommand"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-counters.exp b/tests/scripts/expect/cli-counters.exp
new file mode 100755
index 0000000..06b4105
--- /dev/null
+++ b/tests/scripts/expect/cli-counters.exp
@@ -0,0 +1,53 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "counters\n"
+expect "mac"
+expect "mle"
+expect "Done"
+send "counters mac\n"
+expect "Done"
+send "counters mle\n"
+expect "Done"
+send "counters mac reset\n"
+expect "Done"
+send "counters mle reset\n"
+expect "Done"
+send "counters mac 1\n"
+expect "Error 7: InvalidArgs"
+send "counters mle 1\n"
+expect "Error 7: InvalidArgs"
+send "counters other\n"
+expect "Error 7: InvalidArgs"
+
+dispose
diff --git a/tests/scripts/expect/cli-dataset.exp b/tests/scripts/expect/cli-dataset.exp
new file mode 100755
index 0000000..2afbd56
--- /dev/null
+++ b/tests/scripts/expect/cli-dataset.exp
@@ -0,0 +1,208 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_1
+send "dataset active\n"
+expect -re {Active Timestamp: \d+}
+expect -re {Channel: (\d+)}
+set channel $expect_out(1,string)
+expect -re {Channel Mask: [0-9a-f]{8}}
+expect -re {Ext PAN ID: [0-9a-f]{16}}
+expect -re {Mesh Local Prefix: ([0-9a-f]{1,4}:){3}[0-9a-f]{1,4}\/64}
+expect -re {Master Key: [0-9a-f]{32}}
+expect -re {Network Name: [^\r\n]+}
+expect -re {PAN ID: 0x[0-9a-f]{4}}
+expect -re {PSKc: [0-9a-f]{32}}
+expect -re {Security Policy: \d+, o?n?r?c?b?}
+send "dataset pending\n"
+expect "Error 23: NotFound"
+send "dataset init active\n"
+expect "Done"
+send "dataset activetimestamp 100\n"
+expect "Done"
+if {$channel == 11} {
+    send "dataset channel 18\n"
+} else {
+    send "dataset channel 11\n"
+}
+expect "Done"
+send "dataset channelmask 0x03fff800\n"
+expect "Done"
+send "dataset extpanid aabbccddeeff0011\n"
+expect "Done"
+send "dataset masterkey aabbccddeeff00112233445566778899\n"
+expect "Done"
+send "dataset meshlocalprefix fdde:4860::\n"
+expect "Done"
+send "dataset networkname OT-network\n"
+expect "Done"
+send "dataset panid 0xface\n"
+expect "Done"
+send "dataset pskc 00112233445566778899aabbccddeeff\n"
+expect "Done"
+send "dataset securitypolicy 678 onrcb\n"
+expect "Done"
+send "dataset pendingtimestamp 100\n"
+expect "Done"
+send "dataset delay 30000\n"
+expect "Done"
+send "dataset commit pending\n"
+expect "Done"
+send "dataset pending\n"
+expect "Pending Timestamp: 100"
+expect "Active Timestamp: 100"
+if {$channel == 11} {
+    expect "Channel: 18"
+} else {
+    expect "Channel: 11"
+}
+expect "Channel Mask: 03fff800"
+expect -re {Delay: \d+}
+expect "Ext PAN ID: aabbccddeeff0011"
+expect "Mesh Local Prefix: fdde:4860:0:0/64"
+expect "Master Key: aabbccddeeff00112233445566778899"
+expect "Network Name: OT-network"
+expect "PAN ID: 0xface"
+expect "PSKc: 00112233445566778899aabbccddeeff"
+expect "Security Policy: 678, onrcb"
+expect "Done"
+
+sleep 30
+
+set spawn_id $spawn_2
+wait_for "dataset active" "Active Timestamp: 100"
+expect "Done"
+send "dataset active\n"
+expect "Active Timestamp: 100"
+if {$channel == 11} {
+    expect "Channel: 18"
+} else {
+    expect "Channel: 11"
+}
+expect "Channel Mask: 03fff800"
+expect "Ext PAN ID: aabbccddeeff0011"
+expect "Mesh Local Prefix: fdde:4860:0:0/64"
+expect "Master Key: aabbccddeeff00112233445566778899"
+expect "Network Name: OT-network"
+expect "PAN ID: 0xface"
+expect "PSKc: 00112233445566778899aabbccddeeff"
+expect "Security Policy: 678, onrcb"
+expect "Done"
+send "dataset clear\n"
+expect "Done"
+send "dataset init active\n"
+expect "Done"
+send "dataset\n"
+expect "Active Timestamp: 100"
+if {$channel == 11} {
+    expect "Channel: 18"
+} else {
+    expect "Channel: 11"
+}
+expect "Channel Mask: 03fff800"
+expect "Ext PAN ID: aabbccddeeff0011"
+expect "Mesh Local Prefix: fdde:4860:0:0/64"
+expect "Master Key: aabbccddeeff00112233445566778899"
+expect "Network Name: OT-network"
+expect "PAN ID: 0xface"
+expect "PSKc: 00112233445566778899aabbccddeeff"
+expect "Security Policy: 678, onrcb"
+expect "Done"
+send "dataset init pending\n"
+expect "Error 23: NotFound"
+
+set spawn_id $spawn_1
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_2
+send "dataset mgmtgetcommand active \
+activetimestamp pendingtimestamp masterkey networkname extpanid \
+localprefix delaytimer panid channel \
+binary 000102030405060708090a0b0e0f0c333435 \
+address $addr\n"
+expect "Done"
+send "dataset mgmtgetcommand pending \
+activetimestamp pendingtimestamp masterkey networkname extpanid \
+localprefix delaytimer panid channel \
+binary 000102030405060708090a0b0e0f0c333435 \
+address $addr\n"
+expect "Done"
+
+set spawn_id $spawn_1
+send "dataset active binary\n"
+expect "dataset active binary"
+expect -re {([0-9a-f]+)}
+set binary $expect_out(1,string)
+expect "Done"
+send "dataset set pending $binary\n"
+expect "Done"
+send "dataset pending binary\n"
+expect $binary
+expect "Done"
+send "dataset set active $binary\n"
+expect "Done"
+send "dataset help\n"
+expect "Done"
+send "dataset\n"
+expect "Done"
+send "dataset init something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset active something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset pending something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset commit something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset mgmtsetcommand something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset mgmtsetcommand active something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset mgmtgetcommand something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset mgmtgetcommand active something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset pskc -p 123456\n"
+expect "Done"
+send "dataset pskc\n"
+expect "Error 7: InvalidArgs"
+send "dataset securitypolicy 678 something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "dataset set something_invalid 00\n"
+expect "Error 7: InvalidArgs"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-extaddr.exp b/tests/scripts/expect/cli-extaddr.exp
new file mode 100755
index 0000000..c98cd77
--- /dev/null
+++ b/tests/scripts/expect/cli-extaddr.exp
@@ -0,0 +1,49 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "extaddr 99aabbccddeeff00\n"
+expect "Done"
+send "extaddr 99AABBCCDDEEFF00\n"
+expect "Done"
+send "extaddr\n"
+expect "99aabbccddeeff00"
+send "extaddr 1\n"
+expect "Error 7: InvalidArgs"
+send "extaddr 0123456789abcdef0\n"
+expect "Error 7: InvalidArgs"
+send "extaddr invalid\n"
+expect "Error 7: InvalidArgs"
+send "extaddr\n"
+expect "99aabbccddeeff00"
+
+dispose
diff --git a/tests/scripts/expect/cli-ipmaddr.exp b/tests/scripts/expect/cli-ipmaddr.exp
new file mode 100755
index 0000000..4f74119
--- /dev/null
+++ b/tests/scripts/expect/cli-ipmaddr.exp
@@ -0,0 +1,69 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_1
+send "ipmaddr add ff0e::1\n"
+expect "Done"
+send "ipmaddr\n"
+expect "ff0e:0:0:0:0:0:0:1"
+expect "Done"
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr $expect_out(1,string)
+
+set spawn_id $spawn_2
+send "ping ff0e::1\n"
+expect "Done"
+expect "16 bytes from $addr: icmp_seq=1"
+
+set spawn_id $spawn_1
+send "ipmaddr del ff0e::1\n"
+expect "Done"
+send "ipmaddr del ff0e::1\n"
+expect "Error 23: NotFound"
+send "ipmaddr promiscuous enable\n"
+expect "Done"
+send "ipmaddr promiscuous\n"
+expect "Enabled"
+expect "Done"
+send "ipmaddr promiscuous disable\n"
+expect "Done"
+send "ipmaddr promiscuous\n"
+expect "Disabled"
+expect "Done"
+send "ipmaddr something_invalid\n"
+expect "Error 35: InvalidCommand"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-log-level.exp b/tests/scripts/expect/cli-log-level.exp
new file mode 100755
index 0000000..7391185
--- /dev/null
+++ b/tests/scripts/expect/cli-log-level.exp
@@ -0,0 +1,51 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "log level\n"
+expect "1"
+expect "Done"
+send "log level 5\n"
+expect "Done"
+send "log level\n"
+expect "5"
+expect "Done"
+send "log level -1\n"
+expect "Error 7: InvalidArgs"
+send "log level 6\n"
+expect "Error 7: InvalidArgs"
+send "log a\n"
+expect "Error 7: InvalidArgs"
+send "log level 1 2\n"
+expect "Error 7: InvalidArgs"
+
+dispose
diff --git a/tests/scripts/expect/cli-mac.exp b/tests/scripts/expect/cli-mac.exp
new file mode 100755
index 0000000..ae1df98
--- /dev/null
+++ b/tests/scripts/expect/cli-mac.exp
@@ -0,0 +1,59 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "mac retries direct 5\n"
+expect "Done"
+send "mac retries direct\n"
+expect "5"
+expect "Done"
+
+send "mac retries indirect 2\n"
+expect "Done"
+send "mac retries indirect\n"
+expect "2"
+expect "Done"
+
+send "mac\n"
+expect "Error 7: InvalidArgs"
+send "mac something_invalid\n"
+expect "Error 35: InvalidCommand"
+send "mac retries\n"
+expect "Error 7: InvalidArgs"
+send "mac retries something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "mac retries direct 256\n"
+expect "Error 7: InvalidArgs"
+send "mac retries indirect 256\n"
+expect "Error 7: InvalidArgs"
+
+dispose
diff --git a/tests/scripts/expect/cli-macfilter.exp b/tests/scripts/expect/cli-macfilter.exp
new file mode 100755
index 0000000..579e109
--- /dev/null
+++ b/tests/scripts/expect/cli-macfilter.exp
@@ -0,0 +1,143 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "macfilter\n"
+expect "Address Mode: Disabled"
+expect "RssIn List:"
+expect "Done"
+
+send "macfilter addr add aabbccddeeff0011\n"
+expect "Done"
+
+send "macfilter addr\n"
+expect "Disabled"
+expect "aabbccddeeff0011"
+expect "Done"
+
+send "macfilter addr whitelist\n"
+expect "Done"
+
+send "macfilter addr\n"
+expect "Whitelist"
+expect "aabbccddeeff0011"
+expect "Done"
+
+send "macfilter\n"
+expect "Address Mode: Whitelist"
+expect "aabbccddeeff0011"
+expect "RssIn List:"
+expect "Done"
+
+send "macfilter addr add 2233445566778899\n"
+expect "Done"
+
+send "macfilter addr remove aabbccddeeff0011\n"
+expect "Done"
+
+send "macfilter addr blacklist\n"
+expect "Done"
+
+send "macfilter addr\n"
+expect "Blacklist"
+expect "2233445566778899"
+expect "Done"
+
+send "macfilter\n"
+expect "Address Mode: Blacklist"
+expect "2233445566778899"
+expect "RssIn List:"
+expect "Done"
+
+send "macfilter addr clear\n"
+expect "Done"
+
+send "macfilter addr disable\n"
+expect "Done"
+
+send "macfilter addr\n"
+expect "Disabled"
+expect "Done"
+
+send "macfilter\n"
+expect "Address Mode: Disabled"
+expect "RssIn List:"
+expect "Done"
+
+send "macfilter addr something_invalid\n"
+expect "Error 35: InvalidCommand"
+
+send "macfilter rss\n"
+expect "Done"
+
+send "macfilter rss add-lqi * 2\n"
+expect "Done"
+
+send "macfilter rss add-lqi aabbccddeeff0011 3\n"
+expect "Done"
+
+send "macfilter rss\n"
+expect -re {aabbccddeeff0011 : rss -?\d+ \(lqi 3\)}
+expect -re {Default rss: -?\d+ \(lqi 2\)}
+expect "Done"
+
+send "macfilter\n"
+expect "Address Mode: Disabled"
+expect "RssIn List:"
+expect -re {aabbccddeeff0011 : rss -?\d+ \(lqi 3\)}
+expect -re {Default rss : -?\d+ \(lqi 2\)}
+expect "Done"
+
+send "macfilter rss remove *\n"
+expect "Done"
+
+send "macfilter rss remove aabbccddeeff0011\n"
+expect "Done"
+
+send "macfilter rss add 2233445566778899 -70\n"
+expect "Done"
+
+send "macfilter rss add * -80\n"
+expect "Done"
+
+send "macfilter rss\n"
+expect -re {2233445566778899 : rss -70 \(lqi \d\)}
+expect -re {Default rss: -80 \(lqi \d\)}
+expect "Done"
+
+send "macfilter rss clear\n"
+expect "Done"
+
+send "macfilter rss something_invalid\n"
+expect "Error 35: InvalidCommand"
+
+dispose
diff --git a/tests/scripts/expect/cli-misc.exp b/tests/scripts/expect/cli-misc.exp
new file mode 100755
index 0000000..3d3fb65
--- /dev/null
+++ b/tests/scripts/expect/cli-misc.exp
@@ -0,0 +1,149 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+set spawn_id $spawn_1
+
+send "leaderdata\n"
+expect -re {Partition ID: \d+}
+expect -re {Weighting: \d+}
+expect -re {Data Version: \d+}
+expect -re {Stable Data Version: \d+}
+expect -re {Leader Router ID: \d+}
+expect "Done"
+
+send "help\n"
+expect "Done"
+
+send "bufferinfo\n"
+expect "Done"
+
+send "netdatashow\n"
+expect "Done"
+
+send "parent\n"
+expect "Done"
+
+send "delaytimermin 1\n"
+expect "Done"
+send "delaytimermin\n"
+expect "1"
+expect "Done"
+send "delaytimermin 1 2\n"
+send "counters mac 1\n"
+expect "Error 7: InvalidArgs"
+
+send "ifconfig down\n"
+expect "Done"
+send "ifconfig\n"
+expect "down"
+expect "Done"
+send "ifconfig up\n"
+expect "Done"
+send "ifconfig\n"
+expect "up"
+expect "Done"
+
+send "ipaddr add ::\n"
+expect "Done"
+send "ipaddr del ::\n"
+expect "Done"
+
+send "leaderweight 1\n"
+expect "Done"
+send "leaderweight\n"
+expect "1"
+expect "Done"
+
+send "mode rsdn\n"
+expect "Done"
+send "mode\n"
+expect -re "(?=.*r)(?=.*s)(?=.*d)(?=.*n)"
+
+send "parent\n"
+expect "Done"
+
+send "singleton\n"
+expect -re "true|false"
+expect "Done"
+
+send "state\n"
+expect "disabled"
+expect "Done"
+
+send "txpower -10\n"
+expect "Done"
+send "txpower\n"
+expect -- "-10 dBm"
+expect "Done"
+
+send "thread version\n"
+expect "Done"
+
+send "version\n"
+expect "Done"
+
+send "joinerport 10001\n"
+expect "Done"
+send "joinerport\n"
+expect "10001"
+expect "Done"
+
+send "parentpriority 1\n"
+expect "Done"
+send "parentpriority\n"
+expect "1"
+expect "Done"
+
+send "pollperiod 100000\n"
+expect "Done"
+send "pollperiod\n"
+expect "100000"
+expect "Done"
+
+send "prefix add ::/64 low pdcrosn\n"
+expect "Done"
+send "prefix\n"
+expect "0:0:0:0::/64 pdcrosn low"
+expect "Done"
+
+send "preferrouterid 1\n"
+expect "Done"
+
+send "route add ::/64 s low\n"
+expect "Done"
+send "route\n"
+expect "0:0:0:0::/64 s low"
+send "route remove ::/64\n"
+expect "Done"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-neighbor.exp b/tests/scripts/expect/cli-neighbor.exp
new file mode 100755
index 0000000..b09b832
--- /dev/null
+++ b/tests/scripts/expect/cli-neighbor.exp
@@ -0,0 +1,59 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_2
+send "rloc16\n"
+expect "rloc16"
+expect -re {([0-9a-f]{4})}
+set rloc $expect_out(1,string)
+expect "Done"
+send "extaddr\n"
+expect "extaddr"
+expect -re {([0-9a-f]{16})}
+set extaddr $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_1
+send "neighbor table\n"
+expect "| Role | RLOC16 | Age | Avg RSSI | Last RSSI |R|S|D|N| Extended MAC     |"
+expect "+------+--------+-----+----------+-----------+-+-+-+-+------------------+"
+expect -re "\\| +C +\\| 0x$rloc \\| +\\d+ \\| +-?\\d+ \\| +-?\\d+ \\|1\\|1\\|0\\|0\\| $extaddr \\|"
+expect "Done"
+send "neighbor list\n"
+expect "0x$rloc"
+expect "Done"
+send "neighbor something_invalid\n"
+expect "Error 7: InvalidArgs"
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-ping.exp b/tests/scripts/expect/cli-ping.exp
new file mode 100755
index 0000000..9f07a92
--- /dev/null
+++ b/tests/scripts/expect/cli-ping.exp
@@ -0,0 +1,67 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+
+set spawn_id [spawn_node 1]
+
+send "ping ::1 1 2 1 1\n"
+expect "Done"
+send "ping stop\n"
+expect "Done"
+send "ping ::1 1 2 0.12345 1\n"
+expect "Done"
+send "ping stop\n"
+expect "Done"
+send "ping ::1 1 2 1 1 1\n"
+expect "Error 7: InvalidArgs"
+
+dispose
+
+
+setup_nodes
+
+set spawn_id $spawn_2
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_1
+send "ping $addr\n"
+expect "16 bytes from $addr: icmp_seq=1"
+send "ping $addr 20 10 0.00123456 255\n"
+for {set i 2} {$i <= 11} {incr i} {
+    expect "28 bytes from $addr: icmp_seq=$i"
+}
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-promiscuous.exp b/tests/scripts/expect/cli-promiscuous.exp
new file mode 100755
index 0000000..dc56a5e
--- /dev/null
+++ b/tests/scripts/expect/cli-promiscuous.exp
@@ -0,0 +1,88 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+
+set spawn_id [spawn_node 1]
+
+send "promiscuous\n"
+expect "Disabled"
+expect "Done"
+send "promiscuous enable\n"
+expect "Done"
+send "promiscuous\n"
+expect "Enabled"
+expect "Done"
+send "promiscuous disable\n"
+expect "Done"
+send "promiscuous a\n"
+expect "Error 7: InvalidArgs"
+
+dispose
+
+
+setup_nodes
+
+set spawn_id $spawn_1
+send "channel\n"
+expect "channel"
+expect -re {(\d+)}
+set channel $expect_out(1,string)
+expect "Done"
+
+set spawn_id [spawn_node 3]
+set spawn_3 $spawn_id
+send "channel $channel\n"
+expect "Done"
+send "promiscuous enable\n"
+expect "Done"
+
+set spawn_id $spawn_2
+send "ipaddr\n"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_1
+send "ping $addr\n"
+expect "16 bytes from $addr: icmp_seq=1"
+
+set spawn_id $spawn_3
+expect -re {============================================\[len = +\d+]============================}
+expect -re {\|( ([0-9A-Z]{2}|\.\.)){16}\|( .){16}\|}
+expect -- "-----------------------------------------------------------------------------------"
+send "promiscuous disable\n"
+expect "Done"
+
+set spawn_id $spawn_3
+dispose
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-pskc.exp b/tests/scripts/expect/cli-pskc.exp
new file mode 100755
index 0000000..d751824
--- /dev/null
+++ b/tests/scripts/expect/cli-pskc.exp
@@ -0,0 +1,55 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "pskc 00112233445566778899aabbccddeeff\n"
+expect "Done"
+send "pskc\n"
+expect "00112233445566778899aabbccddeeff"
+expect "Done"
+send "factoryreset\n"
+sleep 0.1
+send "networkname Test\\ Network\n"
+expect "Done"
+send "extpanid 0001020304050607\n"
+expect "Done"
+send "pskc -p 12SECRETPASSWORD34\n"
+expect "Done"
+send "pskc\n"
+expect "c3f59368445a1b6106be420a706d4cc9"
+expect "Done"
+send "factoryreset\n"
+sleep 0.1
+send "pskc -x\n"
+expect "Error 7: InvalidArgs"
+
+dispose
diff --git a/tests/scripts/expect/cli-router.exp b/tests/scripts/expect/cli-router.exp
new file mode 100755
index 0000000..610f1b3
--- /dev/null
+++ b/tests/scripts/expect/cli-router.exp
@@ -0,0 +1,73 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_1
+send "extaddr\n"
+expect "extaddr"
+expect -re {([0-9a-f]{16})}
+set extaddr $expect_out(1,string)
+expect "Done"
+send "router list\n"
+expect "router list"
+expect -re {(\d+)}
+set router_id $expect_out(1,string)
+expect "Done"
+send "router $router_id\n"
+expect -re {Rloc: ([0-9a-f]{4})}
+set rloc $expect_out(1,string)
+expect "Done"
+send "router table\n"
+expect "| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |"
+expect "+----+--------+----------+-----------+-------+--------+-----+------------------+"
+expect -re "\\| +$router_id \\| 0x$rloc \\| +\\d+ \\| +\\d+ \\| +\\d+ \\| +\\d+ \\| +\\d+ \\| $extaddr \\|"
+expect "Done"
+
+set spawn_id $spawn_2
+send "mode rsdn\n"
+expect "Done"
+send "state router\n"
+expect "Done"
+wait_for "router list" $router_id
+send "router $router_id\n"
+expect "Router ID: $router_id"
+expect "Rloc: $rloc"
+expect "Next Hop: fc00"
+expect "Link: 1"
+expect "Ext Addr: $extaddr"
+expect -re {Cost: \d+}
+expect -re {Link Quality In: \d+}
+expect -re {Link Quality Out: \d+}
+expect -re {Age: \d+}
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-routereligible.exp b/tests/scripts/expect/cli-routereligible.exp
new file mode 100755
index 0000000..d979371
--- /dev/null
+++ b/tests/scripts/expect/cli-routereligible.exp
@@ -0,0 +1,54 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "routereligible disable\n"
+expect "Done"
+send "routereligible\n"
+expect "Disabled"
+expect "Done"
+send "routereligible enable\n"
+expect "Done"
+send "routereligible\n"
+expect "Enabled"
+expect "Done"
+send "routereligible something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "mode rs\n"
+expect "Done"
+send "routereligible\n"
+expect "Disabled"
+expect "Done"
+send "routereligible enable\n"
+expect "Error 27: NotCapable"
+
+dispose
diff --git a/tests/scripts/expect/cli-scan-discover.exp b/tests/scripts/expect/cli-scan-discover.exp
new file mode 100755
index 0000000..79482b7
--- /dev/null
+++ b/tests/scripts/expect/cli-scan-discover.exp
@@ -0,0 +1,93 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id [spawn_node 3]
+set spawn_3 $spawn_id
+
+set spawn_id $spawn_1
+send "extaddr\n"
+expect "extaddr"
+expect -re {([0-9a-f]{16})}
+set extaddr $expect_out(1,string)
+expect "Done"
+send "panid\n"
+expect "panid"
+expect -re {([0-9a-f]{4})}
+set pan $expect_out(1,string)
+expect "Done"
+send "extpanid\n"
+expect "extpanid"
+expect -re {([0-9a-f]{16})}
+set extpan $expect_out(1,string)
+expect "Done"
+send "networkname\n"
+expect "networkname"
+expect -re {[\r\n]([^\r\n]+?)[\r\n]}
+set network $expect_out(1,string)
+expect "Done"
+send "channel\n"
+expect "channel"
+expect -re {(\d+)}
+set channel $expect_out(1,string)
+expect "Done"
+
+set spawn_id $spawn_3
+send "scan $channel\n"
+expect "| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |"
+expect "+---+------------------+------------------+------+------------------+----+-----+-----+"
+wait_for "" "\\| \\d \\| $network +\\| $extpan \\| $pan \\| $extaddr \\| +$channel \\| +-?\\d+ \\| +\\d \\|"
+wait_for "" "Done"
+send "scan energy 100\n"
+expect "| Ch | RSSI |"
+expect "+----+------+"
+for {set i 11} {$i <= 26} {incr i} {
+    expect -re "\\| +$i \\| +-?\\d+ \\|"
+}
+expect "Done"
+
+set spawn_id $spawn_3
+send "ifconfig up\n"
+expect "Done"
+send "discover $channel\n"
+expect "| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |"
+expect "+---+------------------+------------------+------+------------------+----+-----+-----+"
+wait_for "" "\\| \\d \\| $network +\\| $extpan \\| $pan \\| $extaddr \\| +$channel \\| +-?\\d+ \\| +\\d \\|"
+wait_for "" "Done"
+send "discover something_invalid\n"
+expect "Error 7: InvalidArgs"
+
+set spawn_id $spawn_3
+dispose
+
+dispose_nodes
diff --git a/tests/scripts/expect/cli-udp.exp b/tests/scripts/expect/cli-udp.exp
new file mode 100755
index 0000000..66607c9
--- /dev/null
+++ b/tests/scripts/expect/cli-udp.exp
@@ -0,0 +1,79 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+source "tests/scripts/expect/_multinode.exp"
+
+setup_nodes
+
+set spawn_id $spawn_2
+send "udp open\n"
+expect "Done"
+send "udp bind :: 11001\n"
+expect "Done"
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr_2 $expect_out(1,string)
+
+set spawn_id $spawn_1
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr_1 $expect_out(1,string)
+send "udp open\n"
+expect "Done"
+send "udp bind :: 11002\n"
+expect "Done"
+send "udp connect $addr_2 11001\n"
+expect "Done"
+send "udp send -s 10\n"
+expect "Done"
+send "udp send -x a68656c6c6f\n"
+expect "Done"
+send "udp send -t there\n"
+expect "Done"
+
+set spawn_id $spawn_2
+expect "10 bytes from $addr_1 11002 0123456789"
+expect "6 bytes from $addr_1 11002"
+expect "hello"
+expect "5 bytes from $addr_1 11002 there"
+
+set spawn_id $spawn_1
+send "udp help\n"
+expect "Done"
+send "udp connect something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "udp send -x something_invalid\n"
+expect "Error 7: InvalidArgs"
+send "udp\n"
+expect "Error 7: InvalidArgs"
+
+dispose_nodes
diff --git a/tests/scripts/expect/posix-diag-rcp.exp b/tests/scripts/expect/posix-diag-rcp.exp
new file mode 100755
index 0000000..8e0be13
--- /dev/null
+++ b/tests/scripts/expect/posix-diag-rcp.exp
@@ -0,0 +1,57 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "diag rcp\n"
+expect "diagnostics mode is disabled"
+expect "Done"
+send "diag start\n"
+expect "start diagnostics mode"
+expect "status 0x00"
+expect "Done"
+send "diag rcp\n"
+expect "diagnostics mode is enabled"
+expect "Done"
+send "diag rcp channel\n"
+expect "failed"
+expect "status 0x7"
+expect "Done"
+send "diag rcp channel 11\n"
+expect "Done"
+send "diag rcp power\n"
+expect "failed"
+expect "status 0x7"
+expect "Done"
+send "diag rcp power 10\n"
+expect "Done"
+
+dispose
diff --git a/tests/scripts/expect/posix-max-power-table.exp b/tests/scripts/expect/posix-max-power-table.exp
new file mode 100755
index 0000000..7f2a515
--- /dev/null
+++ b/tests/scripts/expect/posix-max-power-table.exp
@@ -0,0 +1,57 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+# allows 11-25 and forbidden 26
+spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?max-power-table=11,12,13,14,15,16,17,18,19,20,21,22,23,24,-1,0x7f&forkpty-arg=1"
+expect_after {
+    timeout { exit 1 }
+}
+send "channel supported\n"
+expect "0x3fff800"
+expect "Done"
+send "channel preferred\n"
+expect "0x3fff800"
+expect "Done"
+send "\x04"
+expect eof
+# allows all channels by default
+spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?forkpty-arg=1"
+expect_after {
+    timeout { exit 1 }
+}
+send "channel supported\n"
+expect "0x7fff800"
+expect "Done"
+send "channel preferred\n"
+expect "0x7fff800"
+expect "Done"
+send "\x04"
+expect eof
diff --git a/tests/scripts/expect/posix-rcp.exp b/tests/scripts/expect/posix-rcp.exp
new file mode 100755
index 0000000..4e9b3e8
--- /dev/null
+++ b/tests/scripts/expect/posix-rcp.exp
@@ -0,0 +1,39 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "rcp version\n"
+expect "Done"
+send "rcp something_invalid\n"
+expect "Error 7: InvalidArgs"
+
+dispose
diff --git a/tests/scripts/expect/posix-scan-tx-to-sleep.exp b/tests/scripts/expect/posix-scan-tx-to-sleep.exp
new file mode 100755
index 0000000..b70ef45
--- /dev/null
+++ b/tests/scripts/expect/posix-scan-tx-to-sleep.exp
@@ -0,0 +1,92 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?forkpty-arg=--sleep-to-tx 1"
+set node_1 $spawn_id
+expect_after {
+    timeout { exit 1 }
+}
+
+send "dataset init new\n"
+expect "Done"
+send "dataset panid 0xface\n"
+expect "Done"
+send "dataset commit active\n"
+expect "Done"
+send "ifconfig up\n"
+expect "Done"
+send "thread start\n"
+expect "Done"
+wait_for "state" "leader"
+expect "Done"
+
+send "extaddr\n"
+expect "extaddr"
+expect -re {([0-9a-f]{16})}
+set extaddr $expect_out(1,string)
+expect "Done"
+send "panid\n"
+expect "panid"
+expect -re {([0-9a-f]{4})}
+set pan $expect_out(1,string)
+expect "Done"
+send "extpanid\n"
+expect "extpanid"
+expect -re {([0-9a-f]{16})}
+set extpan $expect_out(1,string)
+expect "Done"
+send "networkname\n"
+expect "networkname"
+expect -re {[\r\n]([^\r\n]+)[\r\n]}
+set network $expect_out(1,string)
+expect "Done"
+send "channel\n"
+expect "channel"
+expect -re {(\d+)}
+set channel $expect_out(1,string)
+expect "Done"
+
+spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?forkpty-arg=--sleep-to-tx 2"
+set node_2 $spawn_id
+expect_after {
+    timeout { exit 1 }
+}
+
+send "scan\n"
+expect "| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |"
+expect "+---+------------------+------------------+------+------------------+----+-----+-----+"
+wait_for "" "\\| \\d \\| $network +\\| $extpan \\| $pan \\| $extaddr \\| +$channel \\| +-?\\d+ \\| +\\d \\|"
+wait_for "" "Done"
+
+dispose
+
+set spawn_id $node_1
+dispose
diff --git a/tests/scripts/expect/simulation-networktime.exp b/tests/scripts/expect/simulation-networktime.exp
new file mode 100755
index 0000000..99af19d
--- /dev/null
+++ b/tests/scripts/expect/simulation-networktime.exp
@@ -0,0 +1,44 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "networktime 20 200\n"
+expect "Done"
+send "networktime\n"
+expect -re {Network Time:     \d+us \((unsynchronized|resync needed|synchronized)\)}
+expect "Time Sync Period: 20s"
+expect "XTAL Threshold:   200ppm"
+expect "Done"
+send "networktime something_invalid\n"
+expect "Error 7: InvalidArgs"
+
+dispose
diff --git a/tests/scripts/expect/tun-dns-client.exp b/tests/scripts/expect/tun-dns-client.exp
new file mode 100755
index 0000000..8e4c71a
--- /dev/null
+++ b/tests/scripts/expect/tun-dns-client.exp
@@ -0,0 +1,47 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "panid 0xface\n"
+expect "Done"
+send "ifconfig up\n"
+expect "Done"
+send "thread start\n"
+expect "Done"
+wait_for "state" "leader"
+expect "Done"
+
+send "dns resolve ipv6.google.com ::1 53\n"
+expect "DNS response for ipv6.google.com"
+expect "Done"
+
+dispose
diff --git a/tests/scripts/expect/tun-netif.exp b/tests/scripts/expect/tun-netif.exp
new file mode 100755
index 0000000..0c96b0b
--- /dev/null
+++ b/tests/scripts/expect/tun-netif.exp
@@ -0,0 +1,38 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "netif\n"
+expect -re {[\r\n][^\r\n:]+?:\d+}
+expect "Done"
+
+dispose
diff --git a/tests/scripts/expect/tun-netstat.exp b/tests/scripts/expect/tun-netstat.exp
new file mode 100755
index 0000000..ba54763
--- /dev/null
+++ b/tests/scripts/expect/tun-netstat.exp
@@ -0,0 +1,62 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "ifconfig up\n"
+expect "Done"
+send "udp open\n"
+expect "Done"
+send "netstat\n"
+expect "|                 Local Address                 |                  Peer Address                 |"
+expect "+-----------------------------------------------+-----------------------------------------------+"
+expect "| 0:0:0:0:0:0:0:0:*                             | 0:0:0:0:0:0:0:0:*                             |"
+expect "Done"
+send "udp bind :: 10001\n"
+expect "Done"
+send "netstat\n"
+expect "|                 Local Address                 |                  Peer Address                 |"
+expect "+-----------------------------------------------+-----------------------------------------------+"
+expect "| 0:0:0:0:0:0:0:0:10001                         | 0:0:0:0:0:0:0:0:*                             |"
+expect "Done"
+send "ipaddr mleid\n"
+expect "ipaddr mleid"
+expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
+set addr $expect_out(1,string)
+send "udp connect $addr 10001\n"
+expect "Done"
+send "netstat\n"
+expect "|                 Local Address                 |                  Peer Address                 |"
+expect "+-----------------------------------------------+-----------------------------------------------+"
+expect -re "\\| 0:0:0:0:0:0:0:0:10001 +\\| $addr:10001 +\\|"
+expect "Done"
+
+dispose
diff --git a/tests/scripts/expect/tun-sntp.exp b/tests/scripts/expect/tun-sntp.exp
new file mode 100755
index 0000000..23f7f89
--- /dev/null
+++ b/tests/scripts/expect/tun-sntp.exp
@@ -0,0 +1,47 @@
+#!/usr/bin/expect -f
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+source "tests/scripts/expect/_common.exp"
+
+set spawn_id [spawn_node 1]
+
+send "panid 0xface\n"
+expect "Done"
+send "ifconfig up\n"
+expect "Done"
+send "thread start\n"
+expect "Done"
+wait_for "state" "leader"
+expect "Done"
+
+send "sntp query ::1 123\n"
+expect -re {SNTP response - Unix time: \d+ \(era: \d+\)}
+expect "Done"
+
+dispose
diff --git a/tests/scripts/misc/test_multicast_join.py b/tests/scripts/misc/test_multicast_join.py
new file mode 100755
index 0000000..9c1ae92
--- /dev/null
+++ b/tests/scripts/misc/test_multicast_join.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import socket
+import struct
+import subprocess
+import sys
+import time
+
+from ipaddress import ip_address
+
+
+def get_maddrs():
+    lines = subprocess.run(['ot-ctl', 'ipmaddr'],
+                           stdout=subprocess.PIPE).stdout.decode().split()
+    return [ip_address(l) for l in lines if l.startswith('ff')]
+
+
+def main():
+    group = 'ff02::158'
+    if_index = int(sys.argv[1])
+
+    with socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) as s:
+        s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, if_index)
+        s.setsockopt(
+            socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP,
+            struct.pack('16si', socket.inet_pton(socket.AF_INET6, group),
+                        if_index))
+        time.sleep(2)
+        maddrs = get_maddrs()
+        print(maddrs)
+        if not any(addr == ip_address(group) for addr in maddrs):
+            return -1
+
+        s.setsockopt(
+            socket.IPPROTO_IPV6, socket.IPV6_LEAVE_GROUP,
+            struct.pack('16si', socket.inet_pton(socket.AF_INET6, group),
+                        if_index))
+
+        time.sleep(2)
+        maddrs = get_maddrs()
+        print(maddrs)
+        if any(addr == ip_address(group) for addr in maddrs):
+            return -1
+    return 0
+
+
+if __name__ == '__main__':
+    exit(main())
diff --git a/tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py b/tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
index 48d0aea..27f046c 100755
--- a/tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
+++ b/tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
@@ -29,39 +29,28 @@
 
 import unittest
 
-import config
 import mle
 import network_layer
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 
 
-class Cert_5_1_01_RouterAttach(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_01_RouterAttach(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -110,9 +99,7 @@
         msg.assertMleMessageContainsTlv(mle.Version)
 
         # 4 - Router
-        msg = router_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST
-        )
+        msg = router_messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
         msg.assertSentToNode(self.nodes[LEADER])
         msg.assertMleMessageContainsTlv(mle.Response)
         msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
@@ -125,8 +112,7 @@
 
         # 5 - Leader
         msg = leader_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        )
+            mle.CommandType.CHILD_ID_RESPONSE)
         msg.assertSentToNode(self.nodes[ROUTER])
         msg.assertMleMessageContainsTlv(mle.SourceAddress)
         msg.assertMleMessageContainsTlv(mle.LeaderData)
@@ -162,8 +148,7 @@
 
         # 9 - Leader
         msg = leader_messages.next_mle_message(
-            mle.CommandType.LINK_ACCEPT_AND_REQUEST
-        )
+            mle.CommandType.LINK_ACCEPT_AND_REQUEST)
         msg.assertMleMessageContainsTlv(mle.SourceAddress)
         msg.assertMleMessageContainsTlv(mle.LeaderData)
         msg.assertMleMessageContainsTlv(mle.Response)
diff --git a/tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py b/tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
index 27adb96..529c344 100755
--- a/tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
+++ b/tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
@@ -31,7 +31,7 @@
 
 import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -41,44 +41,34 @@
 MTDS = [ED, SED]
 
 
-class Cert_5_1_02_ChildAddressTimeout(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-        self.nodes[SED].set_panid(0xface)
-        self.nodes[SED].set_mode('sn')
-        self.nodes[SED].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-        self.nodes[SED].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_02_ChildAddressTimeout(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED, SED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        SED: {
+            'is_mtd': True,
+            'mode': 'sn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_1_03_RouterAddressReallocation.py b/tests/scripts/thread-cert/Cert_5_1_03_RouterAddressReallocation.py
index 8dbb5b5..de010b6 100755
--- a/tests/scripts/thread-cert/Cert_5_1_03_RouterAddressReallocation.py
+++ b/tests/scripts/thread-cert/Cert_5_1_03_RouterAddressReallocation.py
@@ -29,49 +29,35 @@
 
 import unittest
 
-import config
 import mle
 import network_layer
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
 ROUTER2 = 3
 
 
-class Cert_5_1_03_RouterAddressReallocation(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_03_RouterAddressReallocation(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -124,8 +110,7 @@
 
         # Leader or Router1 can be parent of Router2
         if leader_messages.contains_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        ):
+                mle.CommandType.CHILD_ID_RESPONSE):
             leader_messages.next_mle_message(mle.CommandType.CHILD_ID_RESPONSE)
 
             msg = router2_messages.next_coap_message("0.02")
@@ -134,11 +119,8 @@
             msg = leader_messages.next_coap_message("2.04")
 
         elif router1_messages.contains_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        ):
-            router1_messages.next_mle_message(
-                mle.CommandType.CHILD_ID_RESPONSE
-            )
+                mle.CommandType.CHILD_ID_RESPONSE):
+            router1_messages.next_mle_message(mle.CommandType.CHILD_ID_RESPONSE)
 
             msg = router2_messages.next_coap_message("0.02")
             msg.assertCoapMessageRequestUriPath("/a/as")
@@ -154,8 +136,7 @@
         # Router1 make two attempts to reconnect to its current Partition.
         for _ in range(4):
             msg = router1_messages.next_mle_message(
-                mle.CommandType.PARENT_REQUEST
-            )
+                mle.CommandType.PARENT_REQUEST)
             msg.assertSentWithHopLimit(255)
             msg.assertSentToDestinationAddress("ff02::2")
             msg.assertMleMessageContainsTlv(mle.Mode)
@@ -182,8 +163,7 @@
 
         # 7 - Router1
         msg = router1_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST
-        )
+            mle.CommandType.CHILD_ID_REQUEST)
         msg.assertSentToNode(self.nodes[ROUTER2])
         msg.assertMleMessageContainsTlv(mle.Response)
         msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
diff --git a/tests/scripts/thread-cert/Cert_5_1_04_RouterAddressReallocation.py b/tests/scripts/thread-cert/Cert_5_1_04_RouterAddressReallocation.py
index a94b3f2..fb371c4 100755
--- a/tests/scripts/thread-cert/Cert_5_1_04_RouterAddressReallocation.py
+++ b/tests/scripts/thread-cert/Cert_5_1_04_RouterAddressReallocation.py
@@ -29,49 +29,35 @@
 
 import unittest
 
-import config
 import mle
 import network_layer
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
 ROUTER2 = 3
 
 
-class Cert_5_1_04_RouterAddressReallocation(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_04_RouterAddressReallocation(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -123,8 +109,7 @@
 
         # Leader or Router1 can be parent of Router2
         if leader_messages.contains_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        ):
+                mle.CommandType.CHILD_ID_RESPONSE):
             leader_messages.next_mle_message(mle.CommandType.CHILD_ID_RESPONSE)
 
             msg = router2_messages.next_coap_message("0.02")
@@ -133,11 +118,8 @@
             msg = leader_messages.next_coap_message("2.04")
 
         elif router1_messages.contains_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        ):
-            router1_messages.next_mle_message(
-                mle.CommandType.CHILD_ID_RESPONSE
-            )
+                mle.CommandType.CHILD_ID_RESPONSE):
+            router1_messages.next_mle_message(mle.CommandType.CHILD_ID_RESPONSE)
 
             msg = router2_messages.next_coap_message("0.02")
             msg.assertCoapMessageRequestUriPath("/a/as")
@@ -153,8 +135,7 @@
         # Router1 make two attempts to reconnect to its current Partition.
         for _ in range(4):
             msg = router1_messages.next_mle_message(
-                mle.CommandType.PARENT_REQUEST
-            )
+                mle.CommandType.PARENT_REQUEST)
             msg.assertSentWithHopLimit(255)
             msg.assertSentToDestinationAddress("ff02::2")
             msg.assertMleMessageContainsTlv(mle.Mode)
@@ -184,9 +165,7 @@
         router2_messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
 
         # 9 - Router1
-        msg = router1_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router1_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[ROUTER2])
         msg.assertMleMessageContainsTlv(mle.SourceAddress)
         msg.assertMleMessageContainsTlv(mle.LeaderData)
@@ -199,8 +178,7 @@
         msg.assertMleMessageContainsTlv(mle.Version)
 
         msg = router1_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        )
+            mle.CommandType.CHILD_ID_RESPONSE)
         msg.assertSentToNode(self.nodes[ROUTER2])
         msg.assertMleMessageContainsTlv(mle.SourceAddress)
         msg.assertMleMessageContainsTlv(mle.LeaderData)
diff --git a/tests/scripts/thread-cert/Cert_5_1_05_RouterAddressTimeout.py b/tests/scripts/thread-cert/Cert_5_1_05_RouterAddressTimeout.py
index 8d85b4b..318ddc8 100755
--- a/tests/scripts/thread-cert/Cert_5_1_05_RouterAddressTimeout.py
+++ b/tests/scripts/thread-cert/Cert_5_1_05_RouterAddressTimeout.py
@@ -29,43 +29,34 @@
 
 import unittest
 
-import config
 import mle
 import network_layer
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
 
 
-class Cert_5_1_05_RouterAddressTimeout(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self._setUpRouter1()
+class Cert_5_1_05_RouterAddressTimeout(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def _setUpRouter1(self):
         self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
         self.nodes[ROUTER1].enable_whitelist()
         self.nodes[ROUTER1].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_5_1_06_RemoveRouterId.py b/tests/scripts/thread-cert/Cert_5_1_06_RemoveRouterId.py
index afd7b3d..5689e2e 100755
--- a/tests/scripts/thread-cert/Cert_5_1_06_RemoveRouterId.py
+++ b/tests/scripts/thread-cert/Cert_5_1_06_RemoveRouterId.py
@@ -30,39 +30,28 @@
 import unittest
 
 import command
-from command import CheckType
-import config
 import mle
-import node
+import thread_cert
+from command import CheckType
 
 LEADER = 1
 ROUTER1 = 2
 
 
-class Cert_5_1_06_RemoveRouterId(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_06_RemoveRouterId(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -105,8 +94,7 @@
         command.check_parent_request(msg, is_first_request=True)
 
         msg = router1_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST, sent_to_node=self.nodes[LEADER]
-        )
+            mle.CommandType.CHILD_ID_REQUEST, sent_to_node=self.nodes[LEADER])
         command.check_child_id_request(
             msg,
             tlv_request=CheckType.CONTAIN,
diff --git a/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py b/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py
index 20c8e86..ebb8b68 100755
--- a/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py
+++ b/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py
@@ -30,49 +30,98 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 SED1 = 7
 
 
-class Cert_5_1_07_MaxChildCount(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 13):
-            self.nodes[i] = node.Node(i, (i >= 3), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-        self.nodes[ROUTER].set_max_children(10)
-
-        for i in range(3, 13):
-            if i in range(3, 7):
-                self.nodes[i].set_mode('rsn')
-            else:
-                self.nodes[i].set_mode('s')
-            self.nodes[i].set_panid(0xface)
-            self.nodes[i].add_whitelist(self.nodes[ROUTER].get_addr64())
-            self.nodes[ROUTER].add_whitelist(self.nodes[i].get_addr64())
-            self.nodes[i].enable_whitelist()
-            self.nodes[i].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_07_MaxChildCount(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'max_children': 10,
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, 3, 4, 5, 6, SED1, 8, 9, 10, 11, 12]
+        },
+        3: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        4: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        5: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        6: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        8: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        9: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        10: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        11: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+        12: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_1_08_RouterAttachConnectivity.py b/tests/scripts/thread-cert/Cert_5_1_08_RouterAttachConnectivity.py
index 08d8627..cbf47be 100755
--- a/tests/scripts/thread-cert/Cert_5_1_08_RouterAttachConnectivity.py
+++ b/tests/scripts/thread-cert/Cert_5_1_08_RouterAttachConnectivity.py
@@ -31,7 +31,7 @@
 
 import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -40,55 +40,38 @@
 ROUTER4 = 5
 
 
-class Cert_5_1_08_RouterAttachConnectivity(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER4].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER4].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER4].set_panid(0xface)
-        self.nodes[ROUTER4].set_mode('rsdn')
-        self.nodes[ROUTER4].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER4].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER4].enable_whitelist()
-        self.nodes[ROUTER4].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_08_RouterAttachConnectivity(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2, ROUTER3]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER3]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER4]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER1, ROUTER4]
+        },
+        ROUTER4: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER2, ROUTER3]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -135,20 +118,15 @@
         self.assertEqual(0, scan_mask_tlv.end_device)
 
         # 3 - Router2, Router3
-        msg = router2_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router2_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[ROUTER4])
 
-        msg = router3_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router3_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[ROUTER4])
 
         # 4 - Router4
         msg = router4_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST
-        )
+            mle.CommandType.CHILD_ID_REQUEST)
         msg.assertSentToNode(self.nodes[ROUTER3])
         msg.assertMleMessageContainsTlv(mle.Response)
         msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
diff --git a/tests/scripts/thread-cert/Cert_5_1_09_REEDAttachConnectivity.py b/tests/scripts/thread-cert/Cert_5_1_09_REEDAttachConnectivity.py
index 5c1398c..01aaa5d 100755
--- a/tests/scripts/thread-cert/Cert_5_1_09_REEDAttachConnectivity.py
+++ b/tests/scripts/thread-cert/Cert_5_1_09_REEDAttachConnectivity.py
@@ -31,7 +31,7 @@
 
 import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -40,55 +40,38 @@
 ROUTER2 = 5
 
 
-class Cert_5_1_09_REEDAttachConnectivity(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[REED0].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[REED0].set_panid(0xface)
-        self.nodes[REED0].set_mode('rsdn')
-        self.nodes[REED0].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED0].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[REED0].set_router_upgrade_threshold(0)
-        self.nodes[REED0].enable_whitelist()
-
-        self.nodes[REED1].set_panid(0xface)
-        self.nodes[REED1].set_mode('rsdn')
-        self.nodes[REED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[REED1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[REED1].set_router_upgrade_threshold(0)
-        self.nodes[REED1].enable_whitelist()
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[REED0].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_09_REEDAttachConnectivity(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, REED0, REED1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, REED1]
+        },
+        REED0: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        REED1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, ROUTER1, ROUTER2]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [REED0, REED1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -161,8 +144,7 @@
 
         # 6 - Router2
         msg = router2_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST
-        )
+            mle.CommandType.CHILD_ID_REQUEST)
         msg.assertSentToNode(self.nodes[REED1])
         msg.assertMleMessageContainsTlv(mle.Response)
         msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
diff --git a/tests/scripts/thread-cert/Cert_5_1_10_RouterAttachLinkQuality.py b/tests/scripts/thread-cert/Cert_5_1_10_RouterAttachLinkQuality.py
index 5f09e21..dcf15af 100755
--- a/tests/scripts/thread-cert/Cert_5_1_10_RouterAttachLinkQuality.py
+++ b/tests/scripts/thread-cert/Cert_5_1_10_RouterAttachLinkQuality.py
@@ -29,9 +29,8 @@
 
 import unittest
 
-import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -39,48 +38,32 @@
 ROUTER3 = 4
 
 
-class Cert_5_1_10_RouterAttachLinkQuality(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(
-            self.nodes[ROUTER3].get_addr64(), rssi=-85
-        )
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_10_RouterAttachLinkQuality(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER3]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, (ROUTER3, -85)]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -142,20 +125,15 @@
         msg.assertMleMessageContainsTlv(mle.Version)
 
         # 4 - Router1, Router2
-        msg = router1_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router1_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[ROUTER3])
 
-        msg = router2_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router2_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[ROUTER3])
 
         # 5 - Router3
         msg = router3_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST
-        )
+            mle.CommandType.CHILD_ID_REQUEST)
         msg.assertSentToNode(self.nodes[ROUTER1])
         msg.assertMleMessageContainsTlv(mle.Response)
         msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
diff --git a/tests/scripts/thread-cert/Cert_5_1_11_REEDAttachLinkQuality.py b/tests/scripts/thread-cert/Cert_5_1_11_REEDAttachLinkQuality.py
index be6195d..af8f185 100755
--- a/tests/scripts/thread-cert/Cert_5_1_11_REEDAttachLinkQuality.py
+++ b/tests/scripts/thread-cert/Cert_5_1_11_REEDAttachLinkQuality.py
@@ -29,9 +29,8 @@
 
 import unittest
 
-import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 REED = 2
@@ -39,48 +38,32 @@
 ROUTER1 = 4
 
 
-class Cert_5_1_11_REEDAttachLinkQuality(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[REED].set_panid(0xface)
-        self.nodes[REED].set_mode('rsdn')
-        self.nodes[REED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[REED].set_router_upgrade_threshold(0)
-        self.nodes[REED].enable_whitelist()
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(
-            self.nodes[ROUTER1].get_addr64(), rssi=-85
-        )
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_1_11_REEDAttachLinkQuality(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [REED, ROUTER2]
+        },
+        REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, ROUTER1]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, (ROUTER1, -85)]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [REED, ROUTER2]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -141,9 +124,7 @@
         self.assertEqual(0, scan_mask_tlv.end_device)
 
         # 4 - Router2
-        msg = router2_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router2_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[ROUTER1])
 
         # 5 - Router1
@@ -161,8 +142,7 @@
 
         # 6 - Router1
         msg = router1_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST
-        )
+            mle.CommandType.CHILD_ID_REQUEST)
         msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
         msg.assertMleMessageContainsTlv(mle.Mode)
         msg.assertMleMessageContainsTlv(mle.Response)
diff --git a/tests/scripts/thread-cert/Cert_5_1_12_NewRouterNeighborSync.py b/tests/scripts/thread-cert/Cert_5_1_12_NewRouterNeighborSync.py
index 738ebd2..40d16b0 100755
--- a/tests/scripts/thread-cert/Cert_5_1_12_NewRouterNeighborSync.py
+++ b/tests/scripts/thread-cert/Cert_5_1_12_NewRouterNeighborSync.py
@@ -29,62 +29,46 @@
 
 import unittest
 
-import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
 ROUTER2 = 3
 
 
-class Cert_5_1_12_NewRouterSync(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_5_1_12_NewRouterSync(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
-    def verify_step_4(
-        self, router1_messages, router2_messages, req_receiver, accept_receiver
-    ):
+    def verify_step_4(self, router1_messages, router2_messages, req_receiver,
+                      accept_receiver):
         if router2_messages.contains_mle_message(
-            mle.CommandType.LINK_REQUEST
-        ) and (
-            router1_messages.contains_mle_message(mle.CommandType.LINK_ACCEPT)
-            or router1_messages.contains_mle_message(
-                mle.CommandType.LINK_ACCEPT_AND_REQUEST
-            )
-        ):
+                mle.CommandType.LINK_REQUEST) and (
+                    router1_messages.contains_mle_message(
+                        mle.CommandType.LINK_ACCEPT) or
+                    router1_messages.contains_mle_message(
+                        mle.CommandType.LINK_ACCEPT_AND_REQUEST)):
 
             msg = router2_messages.next_mle_message(
-                mle.CommandType.LINK_REQUEST
-            )
+                mle.CommandType.LINK_REQUEST)
 
             msg.assertSentToNode(self.nodes[req_receiver])
             msg.assertMleMessageContainsTlv(mle.SourceAddress)
@@ -154,13 +138,10 @@
 
         # 4 - Router1, Router2
         self.assertTrue(
-            self.verify_step_4(
-                router1_messages, router2_messages, ROUTER1, ROUTER2
-            )
-            or self.verify_step_4(
-                router2_messages, router1_messages, ROUTER2, ROUTER1
-            )
-        )
+            self.verify_step_4(router1_messages, router2_messages, ROUTER1,
+                               ROUTER2) or
+            self.verify_step_4(router2_messages, router1_messages, ROUTER2,
+                               ROUTER1))
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_5_1_13_RouterReset.py b/tests/scripts/thread-cert/Cert_5_1_13_RouterReset.py
index 1c5a7a7..e3d0862 100755
--- a/tests/scripts/thread-cert/Cert_5_1_13_RouterReset.py
+++ b/tests/scripts/thread-cert/Cert_5_1_13_RouterReset.py
@@ -29,42 +29,33 @@
 
 import unittest
 
-import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 
 
-class Cert_5_1_13_RouterReset(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self._setUpRouter()
+class Cert_5_1_13_RouterReset(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def _setUpRouter(self):
         self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
         self.nodes[ROUTER].enable_whitelist()
         self.nodes[ROUTER].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_5_2_01_REEDAttach.py b/tests/scripts/thread-cert/Cert_5_2_01_REEDAttach.py
index 3461095..d7fadc6 100755
--- a/tests/scripts/thread-cert/Cert_5_2_01_REEDAttach.py
+++ b/tests/scripts/thread-cert/Cert_5_2_01_REEDAttach.py
@@ -29,11 +29,10 @@
 
 import unittest
 
-import node
-import mle
-import config
 import command
-
+import config
+import mle
+import thread_cert
 
 LEADER = 1
 DUT_ROUTER1 = 2
@@ -41,44 +40,33 @@
 MED1 = 4
 
 
-class Cert_5_2_01_REEDAttach(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, i == MED1, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[DUT_ROUTER1].set_panid(0xface)
-        self.nodes[DUT_ROUTER1].set_mode('rsdn')
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[DUT_ROUTER1].enable_whitelist()
-        self.nodes[DUT_ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[REED1].set_panid(0xface)
-        self.nodes[REED1].set_mode('rsdn')
-        self.nodes[REED1].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-        self.nodes[REED1].add_whitelist(self.nodes[MED1].get_addr64())
-        self.nodes[REED1].enable_whitelist()
-        self.nodes[REED1].set_router_selection_jitter(1)
-        self.nodes[REED1].set_router_upgrade_threshold(1)
-
-        self.nodes[MED1].set_panid(0xface)
-        self.nodes[MED1].set_mode('rsn')
-        self.nodes[MED1].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[MED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_2_01_REEDAttach(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [DUT_ROUTER1]
+        },
+        DUT_ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, REED1]
+        },
+        REED1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 1,
+            'whitelist': [DUT_ROUTER1, MED1]
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [REED1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -102,16 +90,13 @@
 
         # 3 DUT_ROUTER1: Verify MLE Parent Response
         router1_messages = self.simulator.get_messages_sent_by(DUT_ROUTER1)
-        msg = router1_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router1_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[REED1])
         command.check_parent_response(msg)
 
         # 4 DUT_ROUTER1: Verify MLE Child ID Response
         msg = router1_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        )
+            mle.CommandType.CHILD_ID_RESPONSE)
         msg.assertSentToNode(self.nodes[REED1])
         command.check_child_id_response(msg)
 
@@ -126,8 +111,7 @@
         reed1_messages = self.simulator.get_messages_sent_by(REED1)
         msg = reed1_messages.next_coap_message('0.02')
         reed1_ipv6_address = (
-            msg.ipv6_packet.ipv6_header.source_address.compressed
-        )
+            msg.ipv6_packet.ipv6_header.source_address.compressed)
         msg.assertSentToNode(self.nodes[DUT_ROUTER1])
         msg.assertCoapMessageRequestUriPath('/a/as')
 
diff --git a/tests/scripts/thread-cert/Cert_5_2_03_LeaderReject2Hops.py b/tests/scripts/thread-cert/Cert_5_2_03_LeaderReject2Hops.py
index df084f8..0b8ebc6 100755
--- a/tests/scripts/thread-cert/Cert_5_2_03_LeaderReject2Hops.py
+++ b/tests/scripts/thread-cert/Cert_5_2_03_LeaderReject2Hops.py
@@ -29,10 +29,9 @@
 
 import unittest
 
-import node
 import mle
 import network_layer
-import config
+import thread_cert
 
 DUT_LEADER = 1
 ROUTER_1 = 2
@@ -40,47 +39,280 @@
 ROUTER_32 = 33
 
 
-class Cert_5_2_3_LeaderReject2Hops(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-
-        self.nodes[DUT_LEADER] = node.Node(
-            DUT_LEADER, simulator=self.simulator
-        )
-        self.nodes[DUT_LEADER].set_panid(0xface)
-        self.nodes[DUT_LEADER].set_mode('rsdn')
-        self.nodes[DUT_LEADER].enable_whitelist()
-        self.nodes[DUT_LEADER].set_router_upgrade_threshold(32)
-        self.nodes[DUT_LEADER].set_router_downgrade_threshold(33)
-
-        for i in range(2, 33):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-            self.nodes[i].set_panid(0xface)
-            self.nodes[i].set_mode('rsdn')
-            self.nodes[i].add_whitelist(self.nodes[DUT_LEADER].get_addr64())
-            self.nodes[DUT_LEADER].add_whitelist(self.nodes[i].get_addr64())
-            self.nodes[i].enable_whitelist()
-            self.nodes[i].set_router_upgrade_threshold(33)
-            self.nodes[i].set_router_downgrade_threshold(33)
-            self.nodes[i].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER_32] = node.Node(ROUTER_32, simulator=self.simulator)
-        self.nodes[ROUTER_32].set_panid(0xface)
-        self.nodes[ROUTER_32].set_mode('rsdn')
-        self.nodes[ROUTER_32].add_whitelist(self.nodes[ROUTER_1].get_addr64())
-        self.nodes[ROUTER_1].add_whitelist(self.nodes[ROUTER_32].get_addr64())
-        self.nodes[ROUTER_32].enable_whitelist()
-        self.nodes[ROUTER_32].set_router_upgrade_threshold(33)
-        self.nodes[ROUTER_32].set_router_downgrade_threshold(33)
-        self.nodes[ROUTER_32].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_2_3_LeaderReject2Hops(thread_cert.TestCase):
+    TOPOLOGY = {
+        DUT_LEADER: {
+            'mode':
+                'rsdn',
+            'panid':
+                0xface,
+            'router_downgrade_threshold':
+                33,
+            'router_upgrade_threshold':
+                32,
+            'whitelist': [
+                ROUTER_1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+                18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+                ROUTER_31
+            ]
+        },
+        ROUTER_1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER, ROUTER_32]
+        },
+        3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        4: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        5: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        6: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        7: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        8: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        9: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        10: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        11: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        12: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        13: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        14: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        15: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        16: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        17: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        18: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        19: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        20: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        21: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        22: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        23: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        24: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        25: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        26: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        27: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        28: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        29: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        30: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        31: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        ROUTER_31: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [DUT_LEADER]
+        },
+        ROUTER_32: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 33,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 33,
+            'whitelist': [ROUTER_1]
+        },
+    }
 
     def test(self):
         # 1
@@ -126,9 +358,8 @@
         msg.assertCoapMessageContainsTlv(network_layer.Status)
 
         status_tlv = msg.get_coap_message_tlv(network_layer.Status)
-        self.assertEqual(
-            network_layer.StatusValues.NO_ADDRESS_AVAILABLE, status_tlv.status
-        )
+        self.assertEqual(network_layer.StatusValues.NO_ADDRESS_AVAILABLE,
+                         status_tlv.status)
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_5_2_04_REEDUpgrade.py b/tests/scripts/thread-cert/Cert_5_2_04_REEDUpgrade.py
index 062e977..829cb56 100755
--- a/tests/scripts/thread-cert/Cert_5_2_04_REEDUpgrade.py
+++ b/tests/scripts/thread-cert/Cert_5_2_04_REEDUpgrade.py
@@ -29,60 +29,134 @@
 
 import unittest
 
-import node
 import mle
 import network_layer
-import config
+import thread_cert
 
 LEADER = 1
 ROUTER = 16
 DUT_REED = 17
 ED = 18
-MESH_LOCAL_PREFIX = 'fdde:ad00:beef:0:'
-ROUTING_LACATOR = ':0:ff:fe00'
+MESH_LOCAL_PREFIX = 'fd00:db8:'
+ROUTING_LOCATOR = ':0:ff:fe00'
 REED_ADVERTISEMENT_INTERVAL = 570
 REED_ADVERTISEMENT_MAX_JITTER = 60
 ROUTER_SELECTION_JITTER = 1
 
 
-class Cert_5_2_4_REEDUpgrade(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 19):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].enable_whitelist()
-
-        for i in range(2, 17):
-            self.nodes[i].set_panid(0xface)
-            self.nodes[i].set_mode('rsdn')
-            self.nodes[i].add_whitelist(self.nodes[LEADER].get_addr64())
-            self.nodes[LEADER].add_whitelist(self.nodes[i].get_addr64())
-            self.nodes[i].enable_whitelist()
-            self.nodes[i].set_router_selection_jitter(1)
-
-        self.nodes[DUT_REED].set_panid(0xface)
-        self.nodes[DUT_REED].set_mode('rsdn')
-        self.nodes[DUT_REED].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[DUT_REED].get_addr64())
-        self.nodes[DUT_REED].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[DUT_REED].enable_whitelist()
-        self.nodes[DUT_REED].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsdn')
-        self.nodes[ED].add_whitelist(self.nodes[DUT_REED].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_2_4_REEDUpgrade(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode':
+                'rsdn',
+            'panid':
+                0xface,
+            'whitelist': [
+                2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ROUTER
+            ]
+        },
+        2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        4: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        5: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        6: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        7: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        8: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        9: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        10: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        11: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        12: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        13: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        14: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        15: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, DUT_REED]
+        },
+        DUT_REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER, ED]
+        },
+        ED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [DUT_REED]
+        },
+    }
 
     def test(self):
         # 1 Ensure topology is formed correctly without the DUT_REED.
@@ -115,9 +189,8 @@
         msg.assertMleMessageDoesNotContainTlv(mle.Route64)
 
         # 4 Wait for DUT_REED to send the second packet.
-        self.simulator.go(
-            REED_ADVERTISEMENT_INTERVAL + REED_ADVERTISEMENT_MAX_JITTER
-        )
+        self.simulator.go(REED_ADVERTISEMENT_INTERVAL +
+                          REED_ADVERTISEMENT_MAX_JITTER)
 
         # 5 DUT_REED: Verify the second MLE Advertisement.
         reed_messages = self.simulator.get_messages_sent_by(DUT_REED)
@@ -166,10 +239,8 @@
         # Leader.
         mleid = None
         for addr in self.nodes[LEADER].get_addrs():
-            if (
-                addr.find(MESH_LOCAL_PREFIX) != -1
-                and addr.find(ROUTING_LACATOR) == -1
-            ):
+            if (addr.startswith(MESH_LOCAL_PREFIX) and
+                    addr.find(ROUTING_LOCATOR) == -1):
                 mleid = addr
                 break
 
diff --git a/tests/scripts/thread-cert/Cert_5_2_05_AddressQuery.py b/tests/scripts/thread-cert/Cert_5_2_05_AddressQuery.py
index e4a9e3b..5b7b5ec 100755
--- a/tests/scripts/thread-cert/Cert_5_2_05_AddressQuery.py
+++ b/tests/scripts/thread-cert/Cert_5_2_05_AddressQuery.py
@@ -29,9 +29,9 @@
 
 import unittest
 
-import node
-import config
 import command
+import config
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -41,44 +41,120 @@
 ROUTER_SELECTION_JITTER = 1
 
 
-class Cert_5_2_5_AddressQuery(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 19):
-            self.nodes[i] = node.Node(i, (i == ED1), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid()
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].enable_whitelist()
-
-        for i in range(2, 17):
-            self.nodes[i].set_panid()
-            self.nodes[i].set_mode('rsdn')
-            self.nodes[i].add_whitelist(self.nodes[LEADER].get_addr64())
-            self.nodes[LEADER].add_whitelist(self.nodes[i].get_addr64())
-            self.nodes[i].enable_whitelist()
-            self.nodes[i].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid()
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[DUT_REED].set_panid()
-        self.nodes[DUT_REED].set_mode('rsdn')
-        self.nodes[DUT_REED].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[DUT_REED].get_addr64())
-        self.nodes[DUT_REED].enable_whitelist()
-        self.nodes[DUT_REED].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_2_5_AddressQuery(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode':
+                'rsdn',
+            'panid':
+                0xface,
+            'whitelist': [
+                ROUTER1, BR, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ED1
+            ]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, DUT_REED]
+        },
+        BR: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        4: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        5: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        6: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        7: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        8: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        9: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        10: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        11: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        12: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        13: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        14: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        15: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        16: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+        DUT_REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         # 1. LEADER: DHCPv6 Server for prefix 2001::/64.
@@ -126,9 +202,7 @@
 
         # 6. Verify DUT_REED would send Address Notification when ping to its
         # ML-EID.
-        mleid = self.nodes[DUT_REED].get_ip6_address(
-            config.ADDRESS_TYPE.ML_EID
-        )
+        mleid = self.nodes[DUT_REED].get_ip6_address(config.ADDRESS_TYPE.ML_EID)
         self.assertTrue(self.nodes[ED1].ping(mleid))
 
         # Wait for sniffer collecting packets
@@ -136,17 +210,15 @@
 
         reed_messages = self.simulator.get_messages_sent_by(DUT_REED)
         msg = reed_messages.next_coap_message('0.02', '/a/an')
-        command.check_address_notification(
-            msg, self.nodes[DUT_REED], self.nodes[LEADER]
-        )
+        command.check_address_notification(msg, self.nodes[DUT_REED],
+                                           self.nodes[LEADER])
 
         # 7 & 8. Verify DUT_REED would send Address Notification when ping to
         # its 2001::EID and 2002::EID.
         flag2001 = 0
         flag2002 = 0
         for global_address in self.nodes[DUT_REED].get_ip6_address(
-            config.ADDRESS_TYPE.GLOBAL
-        ):
+                config.ADDRESS_TYPE.GLOBAL):
             if global_address[0:4] == '2001':
                 flag2001 += 1
             elif global_address[0:4] == '2002':
@@ -160,9 +232,8 @@
 
             reed_messages = self.simulator.get_messages_sent_by(DUT_REED)
             msg = reed_messages.next_coap_message('0.02', '/a/an')
-            command.check_address_notification(
-                msg, self.nodes[DUT_REED], self.nodes[LEADER]
-            )
+            command.check_address_notification(msg, self.nodes[DUT_REED],
+                                               self.nodes[LEADER])
 
         assert flag2001 == 1, "Error: Expecting address 2001::EID not appear."
         assert flag2002 == 1, "Error: Expecting address 2002::EID not appear."
diff --git a/tests/scripts/thread-cert/Cert_5_2_06_RouterDowngrade.py b/tests/scripts/thread-cert/Cert_5_2_06_RouterDowngrade.py
index 963ad7f..7929d30 100755
--- a/tests/scripts/thread-cert/Cert_5_2_06_RouterDowngrade.py
+++ b/tests/scripts/thread-cert/Cert_5_2_06_RouterDowngrade.py
@@ -29,10 +29,10 @@
 
 import unittest
 
-import node
-import config
 import command
+import config
 import mle
+import thread_cert
 
 LEADER = 1
 DUT_ROUTER1 = 2
@@ -40,25 +40,175 @@
 ROUTER24 = 24
 
 
-class Cert_5_2_06_RouterDowngrade(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 25):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-            self.nodes[i].set_panid()
-            self.nodes[i].set_mode('rsdn')
-            self.nodes[i].set_router_selection_jitter(1)
-            if i != DUT_ROUTER1:
-                self.nodes[i].set_router_upgrade_threshold(32)
-                self.nodes[i].set_router_downgrade_threshold(32)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_2_06_RouterDowngrade(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        DUT_ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        4: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        5: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        6: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        7: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        8: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        9: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        10: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        11: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        12: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        13: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        14: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        15: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        16: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        17: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        18: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        19: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        20: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        21: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        22: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        23: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+        ROUTER24: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_downgrade_threshold': 32,
+            'router_selection_jitter': 1,
+            'router_upgrade_threshold': 32
+        },
+    }
 
     def test(self):
         # 1 Ensure topology is formed correctly without ROUTER24.
@@ -99,8 +249,7 @@
 
         # 4 & 5
         router1_rloc = self.nodes[DUT_ROUTER1].get_ip6_address(
-            config.ADDRESS_TYPE.RLOC
-        )
+            config.ADDRESS_TYPE.RLOC)
         self.assertTrue(self.nodes[LEADER].ping(router1_rloc))
 
 
diff --git a/tests/scripts/thread-cert/Cert_5_2_07_REEDSynchronization.py b/tests/scripts/thread-cert/Cert_5_2_07_REEDSynchronization.py
index d642e96..474398e 100755
--- a/tests/scripts/thread-cert/Cert_5_2_07_REEDSynchronization.py
+++ b/tests/scripts/thread-cert/Cert_5_2_07_REEDSynchronization.py
@@ -28,12 +28,12 @@
 #
 
 import unittest
-import ipv6
 
-import node
-import mle
-import config
 import command
+import config
+import ipv6
+import mle
+import thread_cert
 
 LEADER = 1
 DUT_ROUTER1 = 2
@@ -42,22 +42,94 @@
 MLE_MIN_LINKS = 3
 
 
-class Cert_5_2_7_REEDSynchronization(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 18):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-            self.nodes[i].set_panid(0xface)
-            self.nodes[i].set_mode('rsdn')
-            self.nodes[i].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_2_7_REEDSynchronization(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        DUT_ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        4: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        5: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        6: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        7: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        8: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        9: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        10: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        11: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        12: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        13: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        14: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        15: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        16: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        DUT_REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+    }
 
     def test(self):
         # 1. Ensure topology is formed correctly without DUT_ROUTER1.
@@ -74,9 +146,8 @@
 
         # 2. DUT_REED: Attach to network. Verify it didn't send an Address Solicit Request.
         # Avoid DUT_REED attach to DUT_ROUTER1.
-        self.nodes[DUT_REED].add_whitelist(
-            self.nodes[DUT_ROUTER1].get_addr64(), config.RSSI['LINK_QULITY_1']
-        )
+        self.nodes[DUT_REED].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64(),
+                                           config.RSSI['LINK_QULITY_1'])
 
         self.nodes[DUT_REED].start()
         self.simulator.go(config.MAX_ADVERTISEMENT_INTERVAL)
@@ -85,9 +156,8 @@
         # The DUT_REED must not send a coap message here.
         reed_messages = self.simulator.get_messages_sent_by(DUT_REED)
         msg = reed_messages.does_not_contain_coap_message()
-        assert (
-            msg is True
-        ), "Error: The DUT_REED sent an Address Solicit Request"
+        assert (msg is
+                True), "Error: The DUT_REED sent an Address Solicit Request"
 
         # 3. DUT_REED: Verify sent a Link Request to at least 3 neighboring
         # Routers.
@@ -104,29 +174,24 @@
 
         link_accept_count = 0
         destination_link_local = self.nodes[DUT_REED].get_ip6_address(
-            config.ADDRESS_TYPE.LINK_LOCAL
-        )
+            config.ADDRESS_TYPE.LINK_LOCAL)
 
         for i in range(1, DUT_REED):
             dut_messages = self.simulator.get_messages_sent_by(i)
 
             while True:
-                msg = dut_messages.next_mle_message(
-                    mle.CommandType.LINK_ACCEPT, False
-                )
+                msg = dut_messages.next_mle_message(mle.CommandType.LINK_ACCEPT,
+                                                    False)
                 if msg is None:
                     break
-                if (
-                    ipv6.ip_address(destination_link_local)
-                    == msg.ipv6_packet.ipv6_header.destination_address
-                ):
+                if (ipv6.ip_address(destination_link_local) ==
+                        msg.ipv6_packet.ipv6_header.destination_address):
                     command.check_link_accept(msg, self.nodes[DUT_REED])
                     link_accept_count += 1
                     break
 
-        assert (
-            link_accept_count >= MLE_MIN_LINKS
-        ) is True, "Error: too few Link Accept sent to DUT_REED"
+        assert (link_accept_count >= MLE_MIN_LINKS
+               ) is True, "Error: too few Link Accept sent to DUT_REED"
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_5_3_01_LinkLocal.py b/tests/scripts/thread-cert/Cert_5_3_01_LinkLocal.py
index e7f9bd7..c6dd979 100755
--- a/tests/scripts/thread-cert/Cert_5_3_01_LinkLocal.py
+++ b/tests/scripts/thread-cert/Cert_5_3_01_LinkLocal.py
@@ -29,33 +29,25 @@
 
 import unittest
 
-import node
 import config
+import thread_cert
 
 LEADER = 1
 DUT_ROUTER1 = 2
 
 
-class Cert_5_3_1_LinkLocal(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-
-        self.nodes[DUT_ROUTER1].set_panid(0xface)
-        self.nodes[DUT_ROUTER1].set_mode('rsdn')
-        self.nodes[DUT_ROUTER1].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_1_LinkLocal(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface
+        },
+        DUT_ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+    }
 
     def test(self):
         # 1
@@ -69,8 +61,7 @@
 
         # 2 & 3
         link_local = self.nodes[DUT_ROUTER1].get_ip6_address(
-            config.ADDRESS_TYPE.LINK_LOCAL
-        )
+            config.ADDRESS_TYPE.LINK_LOCAL)
         self.assertTrue(self.nodes[LEADER].ping(link_local, size=256))
         self.assertTrue(self.nodes[LEADER].ping(link_local))
 
@@ -83,11 +74,8 @@
         self.assertTrue(self.nodes[LEADER].ping('ff02::2'))
 
         # 8
-        self.assertTrue(
-            self.nodes[LEADER].ping(
-                config.LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS
-            )
-        )
+        self.assertTrue(self.nodes[LEADER].ping(
+            config.LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS))
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_5_3_02_RealmLocal.py b/tests/scripts/thread-cert/Cert_5_3_02_RealmLocal.py
index f5fd3a1..ad44a13 100755
--- a/tests/scripts/thread-cert/Cert_5_3_02_RealmLocal.py
+++ b/tests/scripts/thread-cert/Cert_5_3_02_RealmLocal.py
@@ -29,8 +29,8 @@
 
 import unittest
 
-import node
 import config
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -38,44 +38,33 @@
 SED1 = 4
 
 
-class Cert_5_3_2_RealmLocal(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i == SED1), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[DUT_ROUTER2].set_panid(0xface)
-        self.nodes[DUT_ROUTER2].set_mode('rsdn')
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[DUT_ROUTER2].enable_whitelist()
-        self.nodes[DUT_ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('sn')
-        self.nodes[SED1].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_2_RealmLocal(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, DUT_ROUTER2]
+        },
+        DUT_ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1, SED1]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 'sn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [DUT_ROUTER2]
+        },
+    }
 
     def test(self):
         # 1
@@ -97,15 +86,14 @@
 
         # 2 & 3
         mleid = self.nodes[DUT_ROUTER2].get_ip6_address(
-            config.ADDRESS_TYPE.ML_EID
-        )
+            config.ADDRESS_TYPE.ML_EID)
         self.assertTrue(self.nodes[LEADER].ping(mleid, size=256))
         self.assertTrue(self.nodes[LEADER].ping(mleid))
 
         # 4 & 5
-        self.assertTrue(
-            self.nodes[LEADER].ping('ff03::1', num_responses=2, size=256)
-        )
+        self.assertTrue(self.nodes[LEADER].ping('ff03::1',
+                                                num_responses=2,
+                                                size=256))
         sed_messages = self.simulator.get_messages_sent_by(SED1)
         self.assertFalse(sed_messages.contains_icmp_message())
 
@@ -114,9 +102,9 @@
         self.assertFalse(sed_messages.contains_icmp_message())
 
         # 6 & 7
-        self.assertTrue(
-            self.nodes[LEADER].ping('ff03::2', num_responses=2, size=256)
-        )
+        self.assertTrue(self.nodes[LEADER].ping('ff03::2',
+                                                num_responses=2,
+                                                size=256))
         sed_messages = self.simulator.get_messages_sent_by(SED1)
         self.assertFalse(sed_messages.contains_icmp_message())
 
@@ -125,23 +113,19 @@
         self.assertFalse(sed_messages.contains_icmp_message())
 
         # 8
-        self.assertTrue(
-            self.nodes[LEADER].ping(
-                config.REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS,
-                num_responses=3,
-                size=256,
-            )
-        )
+        self.assertTrue(self.nodes[LEADER].ping(
+            config.REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS,
+            num_responses=3,
+            size=256,
+        ))
         self.simulator.go(2)
         sed_messages = self.simulator.get_messages_sent_by(SED1)
         self.assertTrue(sed_messages.contains_icmp_message())
 
-        self.assertTrue(
-            self.nodes[LEADER].ping(
-                config.REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS,
-                num_responses=3,
-            )
-        )
+        self.assertTrue(self.nodes[LEADER].ping(
+            config.REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS,
+            num_responses=3,
+        ))
         self.simulator.go(2)
         sed_messages = self.simulator.get_messages_sent_by(SED1)
         self.assertTrue(sed_messages.contains_icmp_message())
diff --git a/tests/scripts/thread-cert/Cert_5_3_03_AddressQuery.py b/tests/scripts/thread-cert/Cert_5_3_03_AddressQuery.py
index ea6e0f4..127700d 100755
--- a/tests/scripts/thread-cert/Cert_5_3_03_AddressQuery.py
+++ b/tests/scripts/thread-cert/Cert_5_3_03_AddressQuery.py
@@ -29,9 +29,9 @@
 
 import unittest
 
-import node
-import config
 import command
+import config
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -41,53 +41,39 @@
 MED1_TIMEOUT = 3
 
 
-class Cert_5_3_3_AddressQuery(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i == MED1), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid()
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid()
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[DUT_ROUTER2].set_panid()
-        self.nodes[DUT_ROUTER2].set_mode('rsdn')
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[MED1].get_addr64())
-        self.nodes[DUT_ROUTER2].enable_whitelist()
-        self.nodes[DUT_ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid()
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-        self.nodes[MED1].set_panid()
-        self.nodes[MED1].set_mode('rsn')
-        self.nodes[MED1].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[MED1].set_timeout(MED1_TIMEOUT)
-        self.nodes[MED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_3_AddressQuery(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, DUT_ROUTER2, ROUTER3]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        DUT_ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER3, MED1]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, DUT_ROUTER2]
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': 3,
+            'whitelist': [DUT_ROUTER2]
+        },
+    }
 
     def test(self):
         # 1
@@ -112,8 +98,7 @@
         dut_messages = self.simulator.get_messages_sent_by(DUT_ROUTER2)
 
         router3_mleid = self.nodes[ROUTER3].get_ip6_address(
-            config.ADDRESS_TYPE.ML_EID
-        )
+            config.ADDRESS_TYPE.ML_EID)
         self.assertTrue(self.nodes[MED1].ping(router3_mleid))
 
         # Verify DUT_ROUTER2 sent an Address Query Request to the Realm local
@@ -136,16 +121,14 @@
         dut_messages = self.simulator.get_messages_sent_by(DUT_ROUTER2)
 
         med1_mleid = self.nodes[MED1].get_ip6_address(
-            config.ADDRESS_TYPE.ML_EID
-        )
+            config.ADDRESS_TYPE.ML_EID)
         self.assertTrue(self.nodes[ROUTER1].ping(med1_mleid))
 
         # Verify DUT_ROUTER2 responded with an Address Notification.
         dut_messages = self.simulator.get_messages_sent_by(DUT_ROUTER2)
         msg = dut_messages.next_coap_message('0.02', '/a/an')
-        command.check_address_notification(
-            msg, self.nodes[DUT_ROUTER2], self.nodes[ROUTER1]
-        )
+        command.check_address_notification(msg, self.nodes[DUT_ROUTER2],
+                                           self.nodes[ROUTER1])
 
         # 4
         # Wait the finish of address resolution traffic triggerred by previous
diff --git a/tests/scripts/thread-cert/Cert_5_3_04_AddressMapCache.py b/tests/scripts/thread-cert/Cert_5_3_04_AddressMapCache.py
index 722ef64..181f268 100755
--- a/tests/scripts/thread-cert/Cert_5_3_04_AddressMapCache.py
+++ b/tests/scripts/thread-cert/Cert_5_3_04_AddressMapCache.py
@@ -29,9 +29,9 @@
 
 import unittest
 
-import node
-import config
 import command
+import config
+import thread_cert
 
 LEADER = 1
 DUT_ROUTER1 = 2
@@ -44,50 +44,51 @@
 MTDS = [SED1, ED1, ED2, ED3, ED4]
 
 
-class Cert_5_3_4_AddressMapCache(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 8):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED2].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED3].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED4].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[DUT_ROUTER1].set_panid(0xface)
-        self.nodes[DUT_ROUTER1].set_mode('rsdn')
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[DUT_ROUTER1].enable_whitelist()
-        self.nodes[DUT_ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-
-        # Set the SED1's timeout in order to receive the icmp reply when keep
-        # alive with DUT_ROUTER.
-        self.nodes[SED1].set_timeout(5)
-        self.nodes[SED1].enable_whitelist()
-
-        for ED in [ED1, ED2, ED3, ED4]:
-            self.nodes[ED].set_panid(0xface)
-            self.nodes[ED].set_mode('rsn')
-            self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-            self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_4_AddressMapCache(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [DUT_ROUTER1, ED1, ED2, ED3, ED4]
+        },
+        DUT_ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, SED1]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': 5,
+            'whitelist': [DUT_ROUTER1]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+        ED2: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+        ED3: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+        ED4: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         # 1
@@ -112,8 +113,7 @@
         # 2
         for ED in [ED1, ED2, ED3, ED4]:
             ed_mleid = self.nodes[ED].get_ip6_address(
-                config.ADDRESS_TYPE.ML_EID
-            )
+                config.ADDRESS_TYPE.ML_EID)
             self.assertTrue(self.nodes[SED1].ping(ed_mleid))
             self.simulator.go(5)
 
@@ -134,17 +134,15 @@
 
         for ED in [ED1, ED2, ED3, ED4]:
             ed_mleid = self.nodes[ED].get_ip6_address(
-                config.ADDRESS_TYPE.ML_EID
-            )
+                config.ADDRESS_TYPE.ML_EID)
             self.assertTrue(self.nodes[SED1].ping(ed_mleid))
             self.simulator.go(5)
 
             # Verify DUT_ROUTER1 didn't generate an Address Query Request.
             dut_messages = self.simulator.get_messages_sent_by(DUT_ROUTER1)
             msg = dut_messages.next_coap_message('0.02', '/a/aq', False)
-            assert (
-                msg is None
-            ), "Error: The DUT sent an unexpected Address Query Request"
+            assert (msg is None
+                   ), "Error: The DUT sent an unexpected Address Query Request"
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_5_3_05_RoutingLinkQuality.py b/tests/scripts/thread-cert/Cert_5_3_05_RoutingLinkQuality.py
index af6a1dc..f7b85d7 100755
--- a/tests/scripts/thread-cert/Cert_5_3_05_RoutingLinkQuality.py
+++ b/tests/scripts/thread-cert/Cert_5_3_05_RoutingLinkQuality.py
@@ -29,9 +29,9 @@
 
 import unittest
 
-import node
-import config
 import command
+import config
+import thread_cert
 
 LEADER = 1
 DUT_ROUTER1 = 2
@@ -39,46 +39,32 @@
 ROUTER3 = 4
 
 
-class Cert_5_3_5_RoutingLinkQuality(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[DUT_ROUTER1].set_panid(0xface)
-        self.nodes[DUT_ROUTER1].set_mode('rsdn')
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[DUT_ROUTER1].enable_whitelist()
-        self.nodes[DUT_ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_5_RoutingLinkQuality(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [DUT_ROUTER1, ROUTER2]
+        },
+        DUT_ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2, ROUTER3]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, DUT_ROUTER1]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [DUT_ROUTER1]
+        },
+    }
 
     def test(self):
         # 1
@@ -95,8 +81,7 @@
 
         # 2 & 3
         leader_rloc = self.nodes[LEADER].get_ip6_address(
-            config.ADDRESS_TYPE.RLOC
-        )
+            config.ADDRESS_TYPE.RLOC)
 
         # Verify the ICMPv6 Echo Request took the least cost path.
         self.assertTrue(self.nodes[ROUTER3].ping(leader_rloc))
@@ -104,12 +89,10 @@
         command.check_icmp_path(self.simulator, path, self.nodes)
 
         # 4 & 5
-        self.nodes[LEADER].add_whitelist(
-            self.nodes[DUT_ROUTER1].get_addr64(), config.RSSI['LINK_QULITY_1']
-        )
-        self.nodes[DUT_ROUTER1].add_whitelist(
-            self.nodes[LEADER].get_addr64(), config.RSSI['LINK_QULITY_1']
-        )
+        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64(),
+                                         config.RSSI['LINK_QULITY_1'])
+        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64(),
+                                              config.RSSI['LINK_QULITY_1'])
         self.simulator.go(3 * config.MAX_ADVERTISEMENT_INTERVAL)
 
         # Verify the ICMPv6 Echo Request took the longer path because it cost
@@ -119,12 +102,10 @@
         command.check_icmp_path(self.simulator, path, self.nodes)
 
         # 6 & 7
-        self.nodes[LEADER].add_whitelist(
-            self.nodes[DUT_ROUTER1].get_addr64(), config.RSSI['LINK_QULITY_2']
-        )
-        self.nodes[DUT_ROUTER1].add_whitelist(
-            self.nodes[LEADER].get_addr64(), config.RSSI['LINK_QULITY_2']
-        )
+        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64(),
+                                         config.RSSI['LINK_QULITY_2'])
+        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64(),
+                                              config.RSSI['LINK_QULITY_2'])
         self.simulator.go(3 * config.MAX_ADVERTISEMENT_INTERVAL)
 
         # Verify the direct neighbor would be prioritized when there are two
@@ -134,18 +115,15 @@
         command.check_icmp_path(self.simulator, path, self.nodes)
 
         # 8 & 9
-        self.nodes[LEADER].add_whitelist(
-            self.nodes[DUT_ROUTER1].get_addr64(), config.RSSI['LINK_QULITY_0']
-        )
-        self.nodes[DUT_ROUTER1].add_whitelist(
-            self.nodes[LEADER].get_addr64(), config.RSSI['LINK_QULITY_0']
-        )
+        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64(),
+                                         config.RSSI['LINK_QULITY_0'])
+        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64(),
+                                              config.RSSI['LINK_QULITY_0'])
         self.simulator.go(3 * config.MAX_ADVERTISEMENT_INTERVAL)
 
         # Verify the ICMPv6 Echo Request took the longer path.
         leader_rloc = self.nodes[LEADER].get_ip6_address(
-            config.ADDRESS_TYPE.RLOC
-        )
+            config.ADDRESS_TYPE.RLOC)
         self.assertTrue(self.nodes[ROUTER3].ping(leader_rloc))
         path = [ROUTER3, DUT_ROUTER1, ROUTER2, LEADER]
         command.check_icmp_path(self.simulator, path, self.nodes)
diff --git a/tests/scripts/thread-cert/Cert_5_3_06_RouterIdMask.py b/tests/scripts/thread-cert/Cert_5_3_06_RouterIdMask.py
index d20379b..f866f80 100755
--- a/tests/scripts/thread-cert/Cert_5_3_06_RouterIdMask.py
+++ b/tests/scripts/thread-cert/Cert_5_3_06_RouterIdMask.py
@@ -29,51 +29,42 @@
 
 import unittest
 
-import node
-import mle
-import config
 import command
+import config
+import mle
+import thread_cert
 
 DUT_LEADER = 1
 ROUTER1 = 2
 ROUTER2 = 3
 
 
-class Cert_5_3_6_RouterIdMask(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[DUT_LEADER].set_panid(0xface)
-        self.nodes[DUT_LEADER].set_mode('rsdn')
-        self.nodes[DUT_LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[DUT_LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[DUT_LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self._setUpRouter2()
+class Cert_5_3_6_RouterIdMask(thread_cert.TestCase):
+    TOPOLOGY = {
+        DUT_LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [DUT_LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def _setUpRouter2(self):
         self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
         self.nodes[ROUTER2].enable_whitelist()
         self.nodes[ROUTER2].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         # 1
         self.nodes[DUT_LEADER].start()
@@ -111,8 +102,7 @@
 
             leader_messages = self.simulator.get_messages_sent_by(DUT_LEADER)
             msg = leader_messages.last_mle_message(
-                mle.CommandType.ADVERTISEMENT, False
-            )
+                mle.CommandType.ADVERTISEMENT, False)
             if msg is None:
                 continue
 
@@ -123,9 +113,8 @@
                 break
         self.assertTrue(routing_cost == 0)
 
-        self.simulator.go(
-            config.INFINITE_COST_TIMEOUT + config.MAX_ADVERTISEMENT_INTERVAL
-        )
+        self.simulator.go(config.INFINITE_COST_TIMEOUT +
+                          config.MAX_ADVERTISEMENT_INTERVAL)
         leader_messages = self.simulator.get_messages_sent_by(DUT_LEADER)
         msg = leader_messages.last_mle_message(mle.CommandType.ADVERTISEMENT)
         self.assertFalse(command.check_id_set(msg, router2_id))
@@ -150,16 +139,14 @@
         router1_id = self.nodes[ROUTER1].get_router_id()
         router2_id = self.nodes[ROUTER2].get_router_id()
 
-        self.simulator.go(
-            config.MAX_NEIGHBOR_AGE + config.MAX_ADVERTISEMENT_INTERVAL
-        )
+        self.simulator.go(config.MAX_NEIGHBOR_AGE +
+                          config.MAX_ADVERTISEMENT_INTERVAL)
         leader_messages = self.simulator.get_messages_sent_by(DUT_LEADER)
         msg = leader_messages.last_mle_message(mle.CommandType.ADVERTISEMENT)
         self.assertEqual(command.get_routing_cost(msg, router1_id), 0)
 
-        self.simulator.go(
-            config.INFINITE_COST_TIMEOUT + config.MAX_ADVERTISEMENT_INTERVAL
-        )
+        self.simulator.go(config.INFINITE_COST_TIMEOUT +
+                          config.MAX_ADVERTISEMENT_INTERVAL)
         leader_messages = self.simulator.get_messages_sent_by(DUT_LEADER)
         msg = leader_messages.last_mle_message(mle.CommandType.ADVERTISEMENT)
         self.assertFalse(command.check_id_set(msg, router1_id))
diff --git a/tests/scripts/thread-cert/Cert_5_3_06b_RouterIdMask.py b/tests/scripts/thread-cert/Cert_5_3_06b_RouterIdMask.py
index 0403e97..4f86b41 100755
--- a/tests/scripts/thread-cert/Cert_5_3_06b_RouterIdMask.py
+++ b/tests/scripts/thread-cert/Cert_5_3_06b_RouterIdMask.py
@@ -29,45 +29,33 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
 ROUTER2 = 3
 
 
-class Cert_5_3_6_RouterIdMask(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_6_RouterIdMask(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py b/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py
index 3f65a37..81ced37 100755
--- a/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py
+++ b/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py
@@ -29,10 +29,10 @@
 
 import unittest
 
-import node
 import command
 import config
 import mle
+import thread_cert
 
 DUT_LEADER = 1
 ROUTER1 = 2
@@ -44,55 +44,44 @@
 MTDS = [MED1, SED1, MED3]
 
 
-class Cert_5_3_7_DuplicateAddress(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 7):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[DUT_LEADER].set_panid(0xface)
-        self.nodes[DUT_LEADER].set_mode('rsdn')
-        self.nodes[DUT_LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[DUT_LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[DUT_LEADER].add_whitelist(self.nodes[MED3].get_addr64())
-        self.nodes[DUT_LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[DUT_LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[MED1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[DUT_LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[MED1].set_panid(0xface)
-        self.nodes[MED1].set_mode('rsn')
-        self.nodes[MED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[MED1].enable_whitelist()
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-
-        self.nodes[MED3].set_panid(0xface)
-        self.nodes[MED3].set_mode('rsn')
-        self.nodes[MED3].add_whitelist(self.nodes[DUT_LEADER].get_addr64())
-        self.nodes[MED3].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_7_DuplicateAddress(thread_cert.TestCase):
+    TOPOLOGY = {
+        DUT_LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2, MED3]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [DUT_LEADER, MED1]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [DUT_LEADER, SED1]
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'whitelist': [ROUTER2]
+        },
+        MED3: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [DUT_LEADER]
+        },
+    }
 
     def test(self):
         # 1
@@ -139,9 +128,8 @@
         # address.
         dut_messages = self.simulator.get_messages_sent_by(DUT_LEADER)
         msg = dut_messages.next_coap_message('0.02', '/a/aq')
-        command.check_address_query(
-            msg, self.nodes[DUT_LEADER], config.REALM_LOCAL_ALL_ROUTERS_ADDRESS
-        )
+        command.check_address_query(msg, self.nodes[DUT_LEADER],
+                                    config.REALM_LOCAL_ALL_ROUTERS_ADDRESS)
 
         # 5 & 6
         # Verify DUT_LEADER sent an Address Error Notification to the Realm
@@ -150,8 +138,7 @@
         dut_messages = self.simulator.get_messages_sent_by(DUT_LEADER)
         msg = dut_messages.next_coap_message('0.02', '/a/ae')
         command.check_address_error_notification(
-            msg, self.nodes[DUT_LEADER], config.REALM_LOCAL_ALL_ROUTERS_ADDRESS
-        )
+            msg, self.nodes[DUT_LEADER], config.REALM_LOCAL_ALL_ROUTERS_ADDRESS)
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_5_3_08_ChildAddressSet.py b/tests/scripts/thread-cert/Cert_5_3_08_ChildAddressSet.py
index 4e6b7c4..4a74dea 100755
--- a/tests/scripts/thread-cert/Cert_5_3_08_ChildAddressSet.py
+++ b/tests/scripts/thread-cert/Cert_5_3_08_ChildAddressSet.py
@@ -29,11 +29,11 @@
 
 import unittest
 
-import config
 import command
+import config
 import ipv6
 import mle
-import node
+import thread_cert
 
 DUT_LEADER = 1
 BR = 2
@@ -43,38 +43,32 @@
 MTDS = [MED1, MED2]
 
 
-class Cert_5_3_8_ChildAddressSet(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[DUT_LEADER].set_panid(0xface)
-        self.nodes[DUT_LEADER].set_mode('rsdn')
-        self.nodes[DUT_LEADER].add_whitelist(self.nodes[BR].get_addr64())
-        self.nodes[DUT_LEADER].add_whitelist(self.nodes[MED1].get_addr64())
-        self.nodes[DUT_LEADER].add_whitelist(self.nodes[MED2].get_addr64())
-        self.nodes[DUT_LEADER].enable_whitelist()
-
-        self.nodes[BR].set_panid(0xface)
-        self.nodes[BR].set_mode('rsdn')
-        self.nodes[BR].add_whitelist(self.nodes[DUT_LEADER].get_addr64())
-        self.nodes[BR].enable_whitelist()
-        self.nodes[BR].set_router_selection_jitter(1)
-
-        for i in MTDS:
-            self.nodes[i].set_panid(0xface)
-            self.nodes[i].set_mode('rsn')
-            self.nodes[i].add_whitelist(self.nodes[DUT_LEADER].get_addr64())
-            self.nodes[i].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_8_ChildAddressSet(thread_cert.TestCase):
+    TOPOLOGY = {
+        DUT_LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [BR, MED1, MED2]
+        },
+        BR: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [DUT_LEADER]
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [DUT_LEADER]
+        },
+        MED2: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [DUT_LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[DUT_LEADER].start()
@@ -109,8 +103,7 @@
 
         # 4 MED1: MED1 send an ICMPv6 Echo Request to the MED2 ML-EID
         med2_ml_eid = self.nodes[MED2].get_ip6_address(
-            config.ADDRESS_TYPE.ML_EID
-        )
+            config.ADDRESS_TYPE.ML_EID)
         self.assertTrue(med2_ml_eid is not None)
         self.assertTrue(self.nodes[MED1].ping(med2_ml_eid))
 
@@ -127,9 +120,8 @@
         # Verify MED2 sent an ICMPv6 Echo Reply
         med2_messages = self.simulator.get_messages_sent_by(MED2)
         msg = med2_messages.get_icmp_message(ipv6.ICMP_ECHO_RESPONSE)
-        assert (
-            msg is not None
-        ), "Error: The MED2 didn't send ICMPv6 Echo Reply to MED1"
+        assert (msg is not None
+               ), "Error: The MED2 didn't send ICMPv6 Echo Reply to MED1"
 
         # 5 MED1: MED1 send an ICMPv6 Echo Request to the MED2 2001::GUA
         addr = self.nodes[MED2].get_addr("2001::/64")
@@ -149,9 +141,8 @@
         # Verify MED2 sent an ICMPv6 Echo Reply
         med2_messages = self.simulator.get_messages_sent_by(MED2)
         msg = med2_messages.get_icmp_message(ipv6.ICMP_ECHO_RESPONSE)
-        assert (
-            msg is not None
-        ), "Error: The MED2 didn't send ICMPv6 Echo Reply to MED1"
+        assert (msg is not None
+               ), "Error: The MED2 didn't send ICMPv6 Echo Reply to MED1"
 
         # 6 MED1: MED1 send an ICMPv6 Echo Request to the MED2 2002::GUA
         addr = self.nodes[MED2].get_addr("2002::/64")
@@ -171,9 +162,8 @@
         # Verify MED2 sent an ICMPv6 Echo Reply
         med2_messages = self.simulator.get_messages_sent_by(MED2)
         msg = med2_messages.get_icmp_message(ipv6.ICMP_ECHO_RESPONSE)
-        assert (
-            msg is not None
-        ), "Error: The MED2 didn't send ICMPv6 Echo Reply to MED1"
+        assert (msg is not None
+               ), "Error: The MED2 didn't send ICMPv6 Echo Reply to MED1"
 
         # 7 MED1: MED1 send an ICMPv6 Echo Request to the MED2 2003::GUA
         addr = self.nodes[MED2].get_addr("2003::/64")
@@ -193,9 +183,8 @@
         # Verify MED2 sent an ICMPv6 Echo Reply
         med2_messages = self.simulator.get_messages_sent_by(MED2)
         msg = med2_messages.get_icmp_message(ipv6.ICMP_ECHO_RESPONSE)
-        assert (
-            msg is not None
-        ), "Error: The MED2 didn't send ICMPv6 Echo Reply to MED1"
+        assert (msg is not None
+               ), "Error: The MED2 didn't send ICMPv6 Echo Reply to MED1"
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_5_3_09_AddressQuery.py b/tests/scripts/thread-cert/Cert_5_3_09_AddressQuery.py
index d5b856c..225bb52 100755
--- a/tests/scripts/thread-cert/Cert_5_3_09_AddressQuery.py
+++ b/tests/scripts/thread-cert/Cert_5_3_09_AddressQuery.py
@@ -33,7 +33,7 @@
 import command
 import config
 import ipv6
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -42,51 +42,39 @@
 SED1 = 5
 
 
-class Cert_5_3_09_AddressQuery(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i == SED1), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[DUT_ROUTER2].set_panid(0xface)
-        self.nodes[DUT_ROUTER2].set_mode('rsdn')
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[DUT_ROUTER2].enable_whitelist()
-        self.nodes[DUT_ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-        self.nodes[SED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_09_AddressQuery(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, DUT_ROUTER2, ROUTER3]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        DUT_ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, SED1]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [DUT_ROUTER2]
+        },
+    }
 
     def test(self):
         # 1 & 2 ALL: Build and verify the topology
@@ -130,8 +118,7 @@
         dut_router2_messages = self.simulator.get_messages_sent_by(DUT_ROUTER2)
         msg = dut_router2_messages.next_coap_message('0.02', '/a/aq')
         msg.assertSentToDestinationAddress(
-            config.REALM_LOCAL_ALL_ROUTERS_ADDRESS
-        )
+            config.REALM_LOCAL_ALL_ROUTERS_ADDRESS)
         command.check_address_query(
             msg,
             self.nodes[DUT_ROUTER2],
@@ -157,9 +144,8 @@
         # Verify DUT_ROUTER2 sent an Address Notification message
         dut_router2_messages = self.simulator.get_messages_sent_by(DUT_ROUTER2)
         msg = dut_router2_messages.next_coap_message('0.02', '/a/an')
-        command.check_address_notification(
-            msg, self.nodes[DUT_ROUTER2], self.nodes[ROUTER1]
-        )
+        command.check_address_notification(msg, self.nodes[DUT_ROUTER2],
+                                           self.nodes[ROUTER1])
 
         # 5 SED1: SED1 sends an ICMPv6 Echo Request to the ROUTER3 using GUA
         # 2001:: address
@@ -178,8 +164,7 @@
 
         # Verify DUT_ROUTER2 forwarded the ICMPv6 Echo Reply to SED1
         msg = dut_router2_messages_temp.get_icmp_message(
-            ipv6.ICMP_ECHO_RESPONSE
-        )
+            ipv6.ICMP_ECHO_RESPONSE)
         assert (
             msg is not None
         ), "Error: The DUT_ROUTER2 didn't forward ICMPv6 Echo Reply to SED1"
@@ -197,8 +182,7 @@
         dut_router2_messages = self.simulator.get_messages_sent_by(DUT_ROUTER2)
         msg = dut_router2_messages.next_coap_message('0.02', '/a/aq')
         msg.assertSentToDestinationAddress(
-            config.REALM_LOCAL_ALL_ROUTERS_ADDRESS
-        )
+            config.REALM_LOCAL_ALL_ROUTERS_ADDRESS)
 
         # 7 SED1: Power off SED1 and wait to allow DUT_ROUTER2 to timeout the
         # child
diff --git a/tests/scripts/thread-cert/Cert_5_3_10_AddressQuery.py b/tests/scripts/thread-cert/Cert_5_3_10_AddressQuery.py
index de8fa3a..c3b05cf 100755
--- a/tests/scripts/thread-cert/Cert_5_3_10_AddressQuery.py
+++ b/tests/scripts/thread-cert/Cert_5_3_10_AddressQuery.py
@@ -33,7 +33,7 @@
 import command
 import config
 import ipv6
-import node
+import thread_cert
 
 LEADER = 1
 BR = 2
@@ -42,52 +42,40 @@
 MED1 = 5
 
 
-class Cert_5_3_10_AddressQuery(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_5_3_10_AddressQuery(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i == MED1), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[BR].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[BR].set_panid(0xface)
-        self.nodes[BR].set_mode('rsdn')
-        self.nodes[BR].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[BR].enable_whitelist()
-        self.nodes[BR].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[DUT_ROUTER2].set_panid(0xface)
-        self.nodes[DUT_ROUTER2].set_mode('rsdn')
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[DUT_ROUTER2].add_whitelist(self.nodes[MED1].get_addr64())
-        self.nodes[DUT_ROUTER2].enable_whitelist()
-        self.nodes[DUT_ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[MED1].set_panid(0xface)
-        self.nodes[MED1].set_mode('rsn')
-        self.nodes[MED1].add_whitelist(self.nodes[DUT_ROUTER2].get_addr64())
-        self.nodes[MED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [BR, ROUTER1, DUT_ROUTER2]
+        },
+        BR: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, DUT_ROUTER2]
+        },
+        DUT_ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER1, MED1]
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [DUT_ROUTER2]
+        },
+    }
 
     def test(self):
         # 1 & 2
@@ -158,9 +146,8 @@
         # Verify DUT_ROUTER2 sent an Address Notification message
         dut_router2_messages = self.simulator.get_messages_sent_by(DUT_ROUTER2)
         msg = dut_router2_messages.next_coap_message('0.02', '/a/an')
-        command.check_address_notification(
-            msg, self.nodes[DUT_ROUTER2], self.nodes[BR]
-        )
+        command.check_address_notification(msg, self.nodes[DUT_ROUTER2],
+                                           self.nodes[BR])
 
         # 5 MED1: MED1 sends an ICMPv6 Echo Request to ROUTER1 using GUA 2003::
         # address
@@ -181,8 +168,7 @@
 
         # Verify DUT_ROUTER2 forwarded ICMPv6 Echo Reply to MED1
         msg = dut_router2_messages_temp.get_icmp_message(
-            ipv6.ICMP_ECHO_RESPONSE
-        )
+            ipv6.ICMP_ECHO_RESPONSE)
         assert (
             msg is not None
         ), "Error: The DUT_ROUTER2 didn't forward ICMPv6 Echo Reply to MED1"
@@ -199,16 +185,14 @@
 
         # Verify the DUT_ROUTER2 has removed all entries based on ROUTER1's
         # Router ID
-        command.check_router_id_cached(
-            self.nodes[DUT_ROUTER2], router1_id, False
-        )
+        command.check_router_id_cached(self.nodes[DUT_ROUTER2], router1_id,
+                                       False)
 
         # Verify DUT_ROUTER2 sent an Address Query Request
         dut_router2_messages = self.simulator.get_messages_sent_by(DUT_ROUTER2)
         msg = dut_router2_messages.next_coap_message('0.02', '/a/aq')
         msg.assertSentToDestinationAddress(
-            config.REALM_LOCAL_ALL_ROUTERS_ADDRESS
-        )
+            config.REALM_LOCAL_ALL_ROUTERS_ADDRESS)
 
         # 7 MED1: Power off MED1 and wait to allow DUT_ROUTER2 to timeout the
         # child
diff --git a/tests/scripts/thread-cert/Cert_5_3_11_AddressQueryTimeoutIntervals.py b/tests/scripts/thread-cert/Cert_5_3_11_AddressQueryTimeoutIntervals.py
index eb16153..7d35987 100755
--- a/tests/scripts/thread-cert/Cert_5_3_11_AddressQueryTimeoutIntervals.py
+++ b/tests/scripts/thread-cert/Cert_5_3_11_AddressQueryTimeoutIntervals.py
@@ -31,43 +31,33 @@
 
 import command
 import config
-import node
+import thread_cert
 
 LEADER = 1
 DUT_ROUTER1 = 2
 MED1 = 3
 
 
-class Cert_5_3_11_AddressQueryTimeoutIntervals(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, (i == MED1), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[DUT_ROUTER1].set_panid(0xface)
-        self.nodes[DUT_ROUTER1].set_mode('rsdn')
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[DUT_ROUTER1].add_whitelist(self.nodes[MED1].get_addr64())
-        self.nodes[DUT_ROUTER1].enable_whitelist()
-        self.nodes[DUT_ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[MED1].set_panid(0xface)
-        self.nodes[MED1].set_mode('rsn')
-        self.nodes[MED1].add_whitelist(self.nodes[DUT_ROUTER1].get_addr64())
-        self.nodes[MED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_11_AddressQueryTimeoutIntervals(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [DUT_ROUTER1]
+        },
+        DUT_ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, MED1]
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [DUT_ROUTER1]
+        },
+    }
 
     def test(self):
         # 1 ALL: Build and verify the topology
@@ -85,7 +75,7 @@
 
         # 2 MED1: MED1 sends an ICMPv6 Echo Request to a non-existent
         # mesh-local address X
-        X = "fdde:ad00:beef:0000:aa55:aa55:aa55:aa55"
+        X = "fd00:db8:0000:0000:aa55:aa55:aa55:aa55"
         self.assertFalse(self.nodes[MED1].ping(X))
 
         self.simulator.go(config.AQ_TIMEOUT)
diff --git a/tests/scripts/thread-cert/Cert_5_5_01_LeaderReboot.py b/tests/scripts/thread-cert/Cert_5_5_01_LeaderReboot.py
index eddb05d..cc02772 100755
--- a/tests/scripts/thread-cert/Cert_5_5_01_LeaderReboot.py
+++ b/tests/scripts/thread-cert/Cert_5_5_01_LeaderReboot.py
@@ -33,44 +33,32 @@
 import command
 import config
 import mle
-import node
+import thread_cert
 
 DUT_LEADER = 1
 DUT_ROUTER1 = 2
 
 
-class Cert_5_5_1_LeaderReboot(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[DUT_LEADER].set_panid(0xface)
-        self.nodes[DUT_LEADER].set_mode('rsdn')
-        self._setUpLeader()
-
-        self.nodes[DUT_ROUTER1].set_panid(0xface)
-        self.nodes[DUT_ROUTER1].set_mode('rsdn')
-        self.nodes[DUT_ROUTER1].add_whitelist(
-            self.nodes[DUT_LEADER].get_addr64()
-        )
-        self.nodes[DUT_ROUTER1].enable_whitelist()
-        self.nodes[DUT_ROUTER1].set_router_selection_jitter(1)
+class Cert_5_5_1_LeaderReboot(thread_cert.TestCase):
+    TOPOLOGY = {
+        DUT_LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [DUT_ROUTER1]
+        },
+        DUT_ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [DUT_LEADER]
+        },
+    }
 
     def _setUpLeader(self):
         self.nodes[DUT_LEADER].add_whitelist(
-            self.nodes[DUT_ROUTER1].get_addr64()
-        )
+            self.nodes[DUT_ROUTER1].get_addr64())
         self.nodes[DUT_LEADER].enable_whitelist()
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         # 1 ALL: Build and verify the topology
         self.nodes[DUT_LEADER].start()
@@ -93,13 +81,11 @@
 
         # Send a harness helper ping to the DUT
         router1_rloc = self.nodes[DUT_ROUTER1].get_ip6_address(
-            config.ADDRESS_TYPE.RLOC
-        )
+            config.ADDRESS_TYPE.RLOC)
         self.assertTrue(self.nodes[DUT_LEADER].ping(router1_rloc))
 
         leader_rloc = self.nodes[DUT_LEADER].get_ip6_address(
-            config.ADDRESS_TYPE.RLOC
-        )
+            config.ADDRESS_TYPE.RLOC)
         self.assertTrue(self.nodes[DUT_ROUTER1].ping(leader_rloc))
 
         # 3 DUT_LEADER: Reset DUT_LEADER
@@ -116,9 +102,8 @@
 
         # Verify DUT_LEADER didn't send MLE Advertisement messages
         leader_messages = self.simulator.get_messages_sent_by(DUT_LEADER)
-        msg = leader_messages.next_mle_message(
-            mle.CommandType.ADVERTISEMENT, False
-        )
+        msg = leader_messages.next_mle_message(mle.CommandType.ADVERTISEMENT,
+                                               False)
         self.assertTrue(msg is None)
 
         self.nodes[DUT_LEADER].start()
@@ -153,8 +138,7 @@
             )
         else:
             msg = router1_messages_temp.next_mle_message(
-                mle.CommandType.LINK_ACCEPT_AND_REQUEST
-            )
+                mle.CommandType.LINK_ACCEPT_AND_REQUEST)
             self.assertTrue(msg is not None)
             command.check_link_accept(
                 msg,
@@ -167,18 +151,14 @@
 
         # 6 DUT_LEADER: Verify DUT_LEADER didn't send a Parent Request message
         msg = leader_messages_temp.next_mle_message(
-            mle.CommandType.PARENT_REQUEST, False
-        )
+            mle.CommandType.PARENT_REQUEST, False)
         self.assertTrue(msg is None)
 
         # 7 ALL: Verify connectivity by sending an ICMPv6 Echo Request from
         # DUT_LEADER to DUT_ROUTER1 link local address
         router1_link_local_address = self.nodes[DUT_ROUTER1].get_ip6_address(
-            config.ADDRESS_TYPE.LINK_LOCAL
-        )
-        self.assertTrue(
-            self.nodes[DUT_LEADER].ping(router1_link_local_address)
-        )
+            config.ADDRESS_TYPE.LINK_LOCAL)
+        self.assertTrue(self.nodes[DUT_LEADER].ping(router1_link_local_address))
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_5_5_02_LeaderReboot.py b/tests/scripts/thread-cert/Cert_5_5_02_LeaderReboot.py
index c911fc5..31b73fd 100755
--- a/tests/scripts/thread-cert/Cert_5_5_02_LeaderReboot.py
+++ b/tests/scripts/thread-cert/Cert_5_5_02_LeaderReboot.py
@@ -29,49 +29,40 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 ED = 3
 
 
-class Cert_5_5_2_LeaderReboot(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self._setUpLeader()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED].enable_whitelist()
+class Cert_5_5_2_LeaderReboot(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def _setUpLeader(self):
         self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
         self.nodes[LEADER].enable_whitelist()
         self.nodes[LEADER].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_5_5_03_SplitMergeChildren.py b/tests/scripts/thread-cert/Cert_5_5_03_SplitMergeChildren.py
index c5c92f4..3ebc304 100755
--- a/tests/scripts/thread-cert/Cert_5_5_03_SplitMergeChildren.py
+++ b/tests/scripts/thread-cert/Cert_5_5_03_SplitMergeChildren.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -42,46 +41,45 @@
 MTDS = [ED1, ED2, ED3]
 
 
-class Cert_5_5_3_SplitMergeChildren(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 7):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self._setUpLeader()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED2].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED3].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[ED2].set_panid(0xface)
-        self.nodes[ED2].set_mode('rsn')
-        self.nodes[ED2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED2].enable_whitelist()
-
-        self.nodes[ED3].set_panid(0xface)
-        self.nodes[ED3].set_mode('rsn')
-        self.nodes[ED3].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED3].enable_whitelist()
+class Cert_5_5_3_SplitMergeChildren(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1, ROUTER2, ED1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED2, ED3]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+        ED2: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        ED3: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def _setUpLeader(self):
         self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
@@ -90,12 +88,6 @@
         self.nodes[LEADER].enable_whitelist()
         self.nodes[LEADER].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_5_5_04_SplitMergeRouters.py b/tests/scripts/thread-cert/Cert_5_5_04_SplitMergeRouters.py
index a9c8aa3..5fd0919 100755
--- a/tests/scripts/thread-cert/Cert_5_5_04_SplitMergeRouters.py
+++ b/tests/scripts/thread-cert/Cert_5_5_04_SplitMergeRouters.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -39,43 +38,39 @@
 ROUTER4 = 5
 
 
-class Cert_5_5_4_SplitMergeRouters(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self._setUpLeader()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER4].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER4].set_panid(0xface)
-        self.nodes[ROUTER4].set_mode('rsdn')
-        self.nodes[ROUTER4].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER4].enable_whitelist()
-        self.nodes[ROUTER4].set_router_selection_jitter(1)
+class Cert_5_5_4_SplitMergeRouters(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER3]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER4]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+        ROUTER4: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER2]
+        },
+    }
 
     def _setUpLeader(self):
         self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
@@ -83,12 +78,6 @@
         self.nodes[LEADER].enable_whitelist()
         self.nodes[LEADER].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_5_5_05_SplitMergeREED.py b/tests/scripts/thread-cert/Cert_5_5_05_SplitMergeREED.py
index d0930a1..925ea99 100755
--- a/tests/scripts/thread-cert/Cert_5_5_05_SplitMergeREED.py
+++ b/tests/scripts/thread-cert/Cert_5_5_05_SplitMergeREED.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -40,46 +39,114 @@
 REED1 = 17
 
 
-class Cert_5_5_5_SplitMergeREED(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 18):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        for i in range(ROUTER2, ROUTER15 + 1):
-            self.nodes[LEADER].add_whitelist(self.nodes[i].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        for i in range(ROUTER2, ROUTER15 + 1):
-            self.nodes[i].set_panid(0xface)
-            self.nodes[i].set_mode('rsdn')
-            self.nodes[i].add_whitelist(self.nodes[LEADER].get_addr64())
-            self.nodes[i].enable_whitelist()
-            self.nodes[i].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64())
-
-        self.nodes[REED1].set_panid(0xface)
-        self.nodes[REED1].set_mode('rsdn')
-        self.nodes[REED1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[REED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_5_5_SplitMergeREED(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode':
+                'rsdn',
+            'panid':
+                0xface,
+            'whitelist': [
+                ROUTER2, ROUTER3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+                ROUTER15
+            ]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER3]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, REED1]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER1]
+        },
+        5: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        6: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        7: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        8: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        9: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        10: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        11: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        12: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        13: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        14: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        15: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ROUTER15: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        REED1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER2]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_5_07_SplitMergeThreeWay.py b/tests/scripts/thread-cert/Cert_5_5_07_SplitMergeThreeWay.py
index 08ee6a9..a826887 100755
--- a/tests/scripts/thread-cert/Cert_5_5_07_SplitMergeThreeWay.py
+++ b/tests/scripts/thread-cert/Cert_5_5_07_SplitMergeThreeWay.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER1 = 1
 ROUTER1 = 2
@@ -38,35 +37,33 @@
 ROUTER3 = 4
 
 
-class Cert_5_5_7_SplitMergeThreeWay(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER1].set_panid(0xface)
-        self.nodes[LEADER1].set_mode('rsdn')
-        self._setUpLeader1()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[LEADER1].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
+class Cert_5_5_7_SplitMergeThreeWay(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1, ROUTER2, ROUTER3]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER1]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER1]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER1]
+        },
+    }
 
     def _setUpLeader1(self):
         self.nodes[LEADER1].add_whitelist(self.nodes[ROUTER1].get_addr64())
@@ -75,12 +72,6 @@
         self.nodes[LEADER1].enable_whitelist()
         self.nodes[LEADER1].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER1].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_5_5_08_SplitRoutersLostLeader.py b/tests/scripts/thread-cert/Cert_5_5_08_SplitRoutersLostLeader.py
deleted file mode 100755
index 6da034b..0000000
--- a/tests/scripts/thread-cert/Cert_5_5_08_SplitRoutersLostLeader.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python3
-#
-#  Copyright (c) 2016, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-import unittest
-
-import config
-import node
-
-LEADER1 = 1
-ROUTER1 = 2
-ROUTER2 = 3
-ROUTER3 = 4
-ED1 = 5
-
-
-class Cert_5_5_8_SplitRoutersLostLeader(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i == ED1), simulator=self.simulator)
-
-        self.nodes[LEADER1].set_panid(0xface)
-        self.nodes[LEADER1].set_mode('rsdn')
-        self.nodes[LEADER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[LEADER1].enable_whitelist()
-        self.nodes[LEADER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self._setUpRouter3()
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-    def _setUpRouter3(self):
-        self.nodes[ROUTER3].add_whitelist(self.nodes[LEADER1].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-
-    def test(self):
-        self.nodes[LEADER1].start()
-        self.simulator.go(5)
-        self.assertEqual(self.nodes[LEADER1].get_state(), 'leader')
-
-        self.nodes[ROUTER3].start()
-        self.simulator.go(5)
-        self.assertEqual(self.nodes[ROUTER3].get_state(), 'router')
-
-        self.nodes[ROUTER2].start()
-        self.simulator.go(5)
-        self.assertEqual(self.nodes[ROUTER2].get_state(), 'router')
-
-        self.nodes[ROUTER1].start()
-        self.simulator.go(5)
-        self.assertEqual(self.nodes[ROUTER1].get_state(), 'router')
-
-        self.nodes[ED1].start()
-        self.simulator.go(5)
-        self.assertEqual(self.nodes[ED1].get_state(), 'child')
-
-        addrs = self.nodes[ED1].get_addrs()
-        for addr in addrs:
-            if addr[0:4] != 'fe80':
-                self.assertTrue(self.nodes[LEADER1].ping(addr))
-
-        self.nodes[ROUTER3].reset()
-        self._setUpRouter3()
-        self.simulator.go(140)
-
-        self.nodes[ROUTER3].start()
-        self.simulator.go(60)
-
-        addrs = self.nodes[ED1].get_addrs()
-        for addr in addrs:
-            if addr[0:4] != 'fe80':
-                self.assertTrue(self.nodes[LEADER1].ping(addr))
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/tests/scripts/thread-cert/Cert_5_6_01_NetworkDataRegisterBeforeAttachLeader.py b/tests/scripts/thread-cert/Cert_5_6_01_NetworkDataRegisterBeforeAttachLeader.py
index 5e172e7..7319fc9 100755
--- a/tests/scripts/thread-cert/Cert_5_6_01_NetworkDataRegisterBeforeAttachLeader.py
+++ b/tests/scripts/thread-cert/Cert_5_6_01_NetworkDataRegisterBeforeAttachLeader.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_5_6_1_NetworkDataLeaderAsBr(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_6_1_NetworkDataLeaderAsBr(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1, SED1]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_6_02_NetworkDataRegisterBeforeAttachRouter.py b/tests/scripts/thread-cert/Cert_5_6_02_NetworkDataRegisterBeforeAttachRouter.py
index c4eb66e..1663533 100755
--- a/tests/scripts/thread-cert/Cert_5_6_02_NetworkDataRegisterBeforeAttachRouter.py
+++ b/tests/scripts/thread-cert/Cert_5_6_02_NetworkDataRegisterBeforeAttachRouter.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_5_6_2_NetworkDataRouterAsBr(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_6_2_NetworkDataRouterAsBr(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER, ED1, SED1]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_6_03_NetworkDataRegisterAfterAttachLeader.py b/tests/scripts/thread-cert/Cert_5_6_03_NetworkDataRegisterAfterAttachLeader.py
index cbbfe7b..5dab72f 100755
--- a/tests/scripts/thread-cert/Cert_5_6_03_NetworkDataRegisterAfterAttachLeader.py
+++ b/tests/scripts/thread-cert/Cert_5_6_03_NetworkDataRegisterAfterAttachLeader.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_5_6_3_NetworkDataRegisterAfterAttachLeader(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_6_3_NetworkDataRegisterAfterAttachLeader(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1, SED1]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_6_04_NetworkDataRegisterAfterAttachRouter.py b/tests/scripts/thread-cert/Cert_5_6_04_NetworkDataRegisterAfterAttachRouter.py
index d7ad91e..bbef541 100755
--- a/tests/scripts/thread-cert/Cert_5_6_04_NetworkDataRegisterAfterAttachRouter.py
+++ b/tests/scripts/thread-cert/Cert_5_6_04_NetworkDataRegisterAfterAttachRouter.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_5_6_4_NetworkDataRegisterAfterAttachRouter(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_6_4_NetworkDataRegisterAfterAttachRouter(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1, SED1]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_6_05_NetworkDataRegisterAfterAttachRouter.py b/tests/scripts/thread-cert/Cert_5_6_05_NetworkDataRegisterAfterAttachRouter.py
index 18af5ae..9c84f1b 100755
--- a/tests/scripts/thread-cert/Cert_5_6_05_NetworkDataRegisterAfterAttachRouter.py
+++ b/tests/scripts/thread-cert/Cert_5_6_05_NetworkDataRegisterAfterAttachRouter.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_5_6_5_NetworkDataRegisterAfterAttachRouter(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_6_5_NetworkDataRegisterAfterAttachRouter(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1, SED1]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -119,7 +109,7 @@
             if addr[0:3] == '200':
                 self.assertTrue(self.nodes[LEADER].ping(addr))
 
-        self.nodes[ROUTER].add_prefix('2001:2:0:3::/64', 'pacs')
+        self.nodes[ROUTER].add_prefix('2001:2:0:3::/64', 'paos')
         self.nodes[ROUTER].register_netdata()
 
         # Set lowpan context of sniffer
diff --git a/tests/scripts/thread-cert/Cert_5_6_06_NetworkDataExpiration.py b/tests/scripts/thread-cert/Cert_5_6_06_NetworkDataExpiration.py
index 0c4de82..2dd5235 100755
--- a/tests/scripts/thread-cert/Cert_5_6_06_NetworkDataExpiration.py
+++ b/tests/scripts/thread-cert/Cert_5_6_06_NetworkDataExpiration.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_5_6_6_NetworkDataExpiration(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_6_6_NetworkDataExpiration(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1, SED1]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -119,7 +109,7 @@
             if addr[0:3] == '200':
                 self.assertTrue(self.nodes[LEADER].ping(addr))
 
-        self.nodes[ROUTER].add_prefix('2001:2:0:3::/64', 'pacs')
+        self.nodes[ROUTER].add_prefix('2001:2:0:3::/64', 'paos')
         self.nodes[ROUTER].register_netdata()
 
         # Set lowpan context of sniffer
diff --git a/tests/scripts/thread-cert/Cert_5_6_07_NetworkDataRequestREED.py b/tests/scripts/thread-cert/Cert_5_6_07_NetworkDataRequestREED.py
index feb89ad..80b310f 100755
--- a/tests/scripts/thread-cert/Cert_5_6_07_NetworkDataRequestREED.py
+++ b/tests/scripts/thread-cert/Cert_5_6_07_NetworkDataRequestREED.py
@@ -29,45 +29,33 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 REED = 3
 
 
-class Cert_5_6_7_NetworkDataRequestREED(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[REED].set_panid(0xface)
-        self.nodes[REED].set_mode('rsdn')
-        self.nodes[REED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED].enable_whitelist()
-        self.nodes[REED].set_router_upgrade_threshold(0)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_6_7_NetworkDataRequestREED(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER, REED]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_6_08_ContextManagement.py b/tests/scripts/thread-cert/Cert_5_6_08_ContextManagement.py
deleted file mode 100755
index ff82c7c..0000000
--- a/tests/scripts/thread-cert/Cert_5_6_08_ContextManagement.py
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/usr/bin/env python3
-#
-#  Copyright (c) 2016, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-import unittest
-
-import config
-import node
-
-LEADER = 1
-ROUTER = 2
-ED = 3
-
-
-class Cert_5_6_8_ContextManagement(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_context_reuse_delay(10)
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
-    def test(self):
-        self.nodes[LEADER].start()
-        self.simulator.go(4)
-        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
-
-        self.nodes[ROUTER].start()
-        self.simulator.go(5)
-        self.assertEqual(self.nodes[ROUTER].get_state(), 'router')
-
-        self.nodes[ED].start()
-        self.simulator.go(5)
-        self.assertEqual(self.nodes[ED].get_state(), 'child')
-
-        self.nodes[ROUTER].add_prefix('2001:2:0:1::/64', 'paros')
-        self.nodes[ROUTER].register_netdata()
-
-        # Set lowpan context of sniffer
-        self.simulator.set_lowpan_context(1, '2001:2:0:1::/64')
-
-        self.simulator.go(2)
-
-        addrs = self.nodes[LEADER].get_addrs()
-        self.assertTrue(any('2001:2:0:1' in addr[0:10] for addr in addrs))
-        for addr in addrs:
-            if addr[0:3] == '200':
-                self.assertTrue(self.nodes[ED].ping(addr))
-
-        self.nodes[ROUTER].remove_prefix('2001:2:0:1::/64')
-        self.nodes[ROUTER].register_netdata()
-        self.simulator.go(5)
-
-        addrs = self.nodes[LEADER].get_addrs()
-        self.assertFalse(any('2001:2:0:1' in addr[0:10] for addr in addrs))
-        for addr in addrs:
-            if addr[0:3] == '200':
-                self.assertTrue(self.nodes[ED].ping(addr))
-
-        self.nodes[ROUTER].add_prefix('2001:2:0:2::/64', 'paros')
-        self.nodes[ROUTER].register_netdata()
-
-        # Set lowpan context of sniffer
-        self.simulator.set_lowpan_context(2, '2001:2:0:2::/64')
-
-        self.simulator.go(5)
-
-        addrs = self.nodes[LEADER].get_addrs()
-        self.assertFalse(any('2001:2:0:1' in addr[0:10] for addr in addrs))
-        self.assertTrue(any('2001:2:0:2' in addr[0:10] for addr in addrs))
-        for addr in addrs:
-            if addr[0:3] == '200':
-                self.assertTrue(self.nodes[ED].ping(addr))
-
-        self.simulator.go(5)
-        self.nodes[ROUTER].add_prefix('2001:2:0:3::/64', 'paros')
-        self.nodes[ROUTER].register_netdata()
-
-        # Set lowpan context of sniffer
-        self.simulator.set_lowpan_context(3, '2001:2:0:3::/64')
-
-        self.simulator.go(5)
-
-        addrs = self.nodes[LEADER].get_addrs()
-        self.assertFalse(any('2001:2:0:1' in addr[0:10] for addr in addrs))
-        self.assertTrue(any('2001:2:0:2' in addr[0:10] for addr in addrs))
-        self.assertTrue(any('2001:2:0:3' in addr[0:10] for addr in addrs))
-        for addr in addrs:
-            if addr[0:3] == '200':
-                self.assertTrue(self.nodes[ED].ping(addr))
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/tests/scripts/thread-cert/Cert_5_6_09_NetworkDataForwarding.py b/tests/scripts/thread-cert/Cert_5_6_09_NetworkDataForwarding.py
index bf8b491..8e4668e 100755
--- a/tests/scripts/thread-cert/Cert_5_6_09_NetworkDataForwarding.py
+++ b/tests/scripts/thread-cert/Cert_5_6_09_NetworkDataForwarding.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -41,50 +41,39 @@
 MTDS = [ED, SED]
 
 
-class Cert_5_6_9_NetworkDataForwarding(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[SED].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-        self.nodes[SED].set_panid(0xface)
-        self.nodes[SED].set_mode('s')
-        self.nodes[SED].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[SED].enable_whitelist()
-        self.nodes[SED].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_6_9_NetworkDataForwarding(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED, SED]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        SED: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_7_01_CoapDiagCommands_A.py b/tests/scripts/thread-cert/Cert_5_7_01_CoapDiagCommands_A.py
new file mode 100755
index 0000000..9cafce2
--- /dev/null
+++ b/tests/scripts/thread-cert/Cert_5_7_01_CoapDiagCommands_A.py
@@ -0,0 +1,207 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import config
+import mle
+import network_diag
+import network_layer
+import thread_cert
+from network_diag import TlvType
+
+LEADER = 1
+ROUTER1 = 2
+REED1 = 3
+SED1 = 4
+MED1 = 5
+FED1 = 6
+
+DUT = ROUTER1
+MTDS = [MED1, SED1]
+
+
+class Cert_5_7_01_CoapDiagCommands_A(thread_cert.TestCase):
+    SUPPORT_NCP = False
+
+    TOPOLOGY = {
+        LEADER: {
+            'whitelist': [ROUTER1],
+        },
+        ROUTER1: {
+            'whitelist': [LEADER, REED1, SED1, MED1, FED1],
+            'router_selection_jitter': 1
+        },
+        REED1: {
+            'whitelist': [ROUTER1],
+            'router_upgrade_threshold': 0
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'whitelist': [ROUTER1],
+            'timeout': config.DEFAULT_CHILD_TIMEOUT
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'whitelist': [ROUTER1]
+        },
+        FED1: {
+            'whitelist': [ROUTER1],
+            'router_upgrade_threshold': 0
+        },
+    }
+
+    def test(self):
+        # 1 - Form topology
+        self.nodes[LEADER].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[ROUTER1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[ROUTER1].get_state(), 'router')
+
+        self.nodes[REED1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[REED1].get_state(), 'child')
+
+        self.nodes[SED1].start()
+        self.simulator.go(10)
+        self.assertEqual(self.nodes[SED1].get_state(), 'child')
+
+        self.nodes[MED1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[MED1].get_state(), 'child')
+
+        self.nodes[FED1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[FED1].get_state(), 'child')
+
+        dut_rloc = self.nodes[DUT].get_ip6_address(config.ADDRESS_TYPE.RLOC)
+
+        # 2 - Leader sends DIAG_GET.req
+        tlv_types = [
+            TlvType.EXT_ADDRESS, TlvType.ADDRESS16, TlvType.MODE,
+            TlvType.CONNECTIVITY, TlvType.ROUTE64, TlvType.LEADER_DATA,
+            TlvType.NETWORK_DATA, TlvType.IPV6_ADDRESS_LIST,
+            TlvType.CHANNEL_PAGES
+        ]
+        self.nodes[LEADER].send_network_diag_get(dut_rloc, tlv_types)
+        self.simulator.go(2)
+
+        dut_messages = self.simulator.get_messages_sent_by(DUT)
+
+        diag_get_rsp = dut_messages.next_coap_message(code='2.04')
+        diag_get_rsp.assertCoapMessageContainsTlv(
+            network_layer.MacExtendedAddress)
+        diag_get_rsp.assertCoapMessageContainsTlv(mle.Address16)
+        diag_get_rsp.assertCoapMessageContainsTlv(mle.Mode)
+        diag_get_rsp.assertCoapMessageContainsTlv(mle.Connectivity)
+        diag_get_rsp.assertCoapMessageContainsTlv(mle.Route64)
+        diag_get_rsp.assertCoapMessageContainsTlv(mle.LeaderData)
+        diag_get_rsp.assertCoapMessageContainsTlv(mle.NetworkData)
+        diag_get_rsp.assertCoapMessageContainsTlv(network_diag.Ipv6AddressList)
+        diag_get_rsp.assertCoapMessageContainsTlv(network_diag.ChannelPages)
+
+        # 3 - Leader sends DIAG_GET.req (MAC Counters TLV type included)
+        self.nodes[LEADER].send_network_diag_get(dut_rloc,
+                                                 [TlvType.MAC_COUNTERS])
+        self.simulator.go(2)
+
+        dut_messages = self.simulator.get_messages_sent_by(DUT)
+        diag_get_rsp = dut_messages.next_coap_message(code='2.04')
+        diag_get_rsp.assertCoapMessageContainsTlv(network_diag.MacCounters)
+        mac_counters = diag_get_rsp.get_coap_message_tlv(
+            network_diag.MacCounters)
+
+        # 4 - Leader sends DIAG_GET.req (Timeout/Polling Period TLV type included)
+        self.nodes[LEADER].send_network_diag_get(dut_rloc,
+                                                 [TlvType.POLLING_PERIOD])
+        self.simulator.go(2)
+
+        dut_messages = self.simulator.get_messages_sent_by(DUT)
+        diag_get_rsp = dut_messages.next_coap_message(code='2.04')
+        diag_get_rsp.assertCoapMessageDoesNotContainTlv(mle.Timeout)
+
+        # 5 - Leader sends DIAG_GET.req (Battery Level and Supply Voltage TLV types included)
+        self.nodes[LEADER].send_network_diag_get(
+            dut_rloc, [TlvType.BATTERY_LEVEL, TlvType.SUPPLY_VOLTAGE])
+        self.simulator.go(2)
+
+        dut_messages = self.simulator.get_messages_sent_by(DUT)
+        diag_get_rsp = dut_messages.next_coap_message(code='2.04')
+        diag_get_rsp.assertCoapMessageContainsOptionalTlv(
+            network_diag.BatteryLevel)
+        diag_get_rsp.assertCoapMessageContainsOptionalTlv(
+            network_diag.SupplyVoltage)
+
+        # 6 - Leader sends DIAG_GET.req (Child Table TLV types included)
+        self.nodes[LEADER].send_network_diag_get(dut_rloc,
+                                                 [TlvType.CHILD_TABLE])
+        self.simulator.go(2)
+
+        dut_messages = self.simulator.get_messages_sent_by(DUT)
+        diag_get_rsp = dut_messages.next_coap_message(code='2.04')
+        diag_get_rsp.assertCoapMessageContainsTlv(network_diag.ChildTable)
+        child_table = diag_get_rsp.get_coap_message_tlv(network_diag.ChildTable)
+        self.assertEqual(len(child_table.children), 4)
+        # TODO(wgtdkp): more validations
+
+        # 7 - Leader sends DIAG_RST.ntf (MAC Counters TLV type included)
+        self.nodes[LEADER].send_network_diag_reset(dut_rloc,
+                                                   [TlvType.MAC_COUNTERS])
+        self.simulator.go(2)
+
+        dut_messages = self.simulator.get_messages_sent_by(DUT)
+
+        # Make sure the response is there.
+        dut_messages.next_coap_message(code='2.04')
+
+        # 8 - Leader Sends DIAG_GET.req (MAC Counters TLV type included)
+        self.nodes[LEADER].send_network_diag_get(dut_rloc,
+                                                 [TlvType.MAC_COUNTERS])
+        self.simulator.go(2)
+
+        dut_messages = self.simulator.get_messages_sent_by(DUT)
+        diag_get_rsp = dut_messages.next_coap_message(code='2.04')
+        diag_get_rsp.assertCoapMessageContainsTlv(network_diag.MacCounters)
+        reset_mac_counters = diag_get_rsp.get_coap_message_tlv(
+            network_diag.MacCounters)
+
+        self.assertEqual(len(mac_counters.counters),
+                         len(reset_mac_counters.counters))
+        for old_counter, new_counter in zip(mac_counters.counters,
+                                            reset_mac_counters.counters):
+            self.assertTrue(new_counter == 0 or new_counter < old_counter)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/Cert_5_8_01_KeySynchronization.py b/tests/scripts/thread-cert/Cert_5_8_01_KeySynchronization.py
deleted file mode 100755
index 41adbbc..0000000
--- a/tests/scripts/thread-cert/Cert_5_8_01_KeySynchronization.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env python3
-#
-#  Copyright (c) 2016, The OpenThread Authors.
-#  All rights reserved.
-#
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  1. Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-#  2. Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#  3. Neither the name of the copyright holder nor the
-#     names of its contributors may be used to endorse or promote products
-#     derived from this software without specific prior written permission.
-#
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-#  POSSIBILITY OF SUCH DAMAGE.
-#
-
-import unittest
-
-import config
-import node
-
-LEADER = 1
-ED = 2
-
-
-class Cert_5_8_1_KeySynchronization(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_key_switch_guardtime(0)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-        self.nodes[ED].set_key_switch_guardtime(0)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
-    def test(self):
-        self.nodes[LEADER].start()
-        self.simulator.go(4)
-        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
-
-        self.nodes[ED].start()
-        self.simulator.go(5)
-        self.assertEqual(self.nodes[ED].get_state(), 'child')
-
-        addrs = self.nodes[LEADER].get_addrs()
-        for addr in addrs:
-            if 'ff:fe00' not in addr:
-                self.assertTrue(self.nodes[ED].ping(addr))
-
-        key_sequence_counter = self.nodes[ED].get_key_sequence_counter()
-        self.nodes[ED].set_key_sequence_counter(key_sequence_counter + 10)
-
-        addrs = self.nodes[LEADER].get_addrs()
-        for addr in addrs:
-            if 'ff:fe00' not in addr:
-                self.assertFalse(self.nodes[ED].ping(addr))
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py b/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py
index 27a4c52..c413fe3 100755
--- a/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py
+++ b/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py
@@ -29,39 +29,28 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 
 
-class Cert_5_8_2_KeyIncrement(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].set_key_switch_guardtime(0)
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_key_switch_guardtime(0)
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_8_2_KeyIncrement(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'key_switch_guardtime': 0,
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'key_switch_guardtime': 0,
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py b/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py
index b70eeb7..27bbe65 100755
--- a/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py
+++ b/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py
@@ -29,40 +29,29 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 
 
-class Cert_5_8_3_KeyIncrementRollOver(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_key_switch_guardtime(0)
-        self.nodes[LEADER].set_key_sequence_counter(127)
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_key_switch_guardtime(0)
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_8_3_KeyIncrementRollOver(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'key_sequence_counter': 127,
+            'key_switch_guardtime': 0,
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'key_switch_guardtime': 0,
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_1_01_RouterAttach.py b/tests/scripts/thread-cert/Cert_6_1_01_RouterAttach.py
index a812277..333bbba 100755
--- a/tests/scripts/thread-cert/Cert_6_1_01_RouterAttach.py
+++ b/tests/scripts/thread-cert/Cert_6_1_01_RouterAttach.py
@@ -29,37 +29,27 @@
 
 import unittest
 
-import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 ED = 2
 
 
-class Cert_6_1_1_RouterAttach(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_1_RouterAttach(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -109,8 +99,7 @@
 
         # 5 - leader
         msg = leader_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        )
+            mle.CommandType.CHILD_ID_RESPONSE)
         msg.assertSentToNode(self.nodes[ED])
 
         # 6 - leader
diff --git a/tests/scripts/thread-cert/Cert_6_1_02_REEDAttach_MED.py b/tests/scripts/thread-cert/Cert_6_1_02_REEDAttach_MED.py
index 62440f7..b4cf8f0 100755
--- a/tests/scripts/thread-cert/Cert_6_1_02_REEDAttach_MED.py
+++ b/tests/scripts/thread-cert/Cert_6_1_02_REEDAttach_MED.py
@@ -29,50 +29,40 @@
 
 import unittest
 
+import thread_cert
 from command import check_parent_request
 from command import check_child_id_request
 from command import check_child_update_request_from_child
 from command import CheckType
 import config
 import mle
-import node
 
 LEADER = 1
 REED = 2
 MED = 3
 
 
-class Cert_6_1_2_REEDAttach_MED(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, (i == MED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[REED].set_panid(0xface)
-        self.nodes[REED].set_mode('rsdn')
-        self.nodes[REED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED].add_whitelist(self.nodes[MED].get_addr64())
-        self.nodes[REED].enable_whitelist()
-        self.nodes[REED].set_router_upgrade_threshold(0)
-
-        self.nodes[MED].set_panid(0xface)
-        self.nodes[MED].set_mode('rsn')
-        self.nodes[MED].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[MED].enable_whitelist()
-        self.nodes[MED].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_2_REEDAttach_MED(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [REED]
+        },
+        REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, MED]
+        },
+        MED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [REED]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -99,9 +89,8 @@
         check_parent_request(msg, is_first_request=False)
 
         # Step 6 - DUT sends Child ID Request
-        msg = med_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST, sent_to_node=self.nodes[REED]
-        )
+        msg = med_messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST,
+                                            sent_to_node=self.nodes[REED])
         check_child_id_request(
             msg,
             address_registration=CheckType.CONTAIN,
@@ -117,8 +106,7 @@
 
         # Step 8 - DUT sends Child Update messages
         msg = med_messages.next_mle_message(
-            mle.CommandType.CHILD_UPDATE_REQUEST
-        )
+            mle.CommandType.CHILD_UPDATE_REQUEST)
         check_child_update_request_from_child(
             msg,
             source_address=CheckType.CONTAIN,
diff --git a/tests/scripts/thread-cert/Cert_6_1_02_REEDAttach_SED.py b/tests/scripts/thread-cert/Cert_6_1_02_REEDAttach_SED.py
index 41d5882..bd9ec45 100755
--- a/tests/scripts/thread-cert/Cert_6_1_02_REEDAttach_SED.py
+++ b/tests/scripts/thread-cert/Cert_6_1_02_REEDAttach_SED.py
@@ -29,6 +29,7 @@
 
 import unittest
 
+import thread_cert
 from command import check_parent_request
 from command import check_child_id_request
 from command import CheckType
@@ -36,44 +37,33 @@
 import mac802154
 import message
 import mle
-import node
 
 LEADER = 1
 REED = 2
 SED = 3
 
 
-class Cert_6_1_2_REEDAttach_SED(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, (i == SED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[REED].set_panid(0xface)
-        self.nodes[REED].set_mode('rsdn')
-        self.nodes[REED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED].add_whitelist(self.nodes[SED].get_addr64())
-        self.nodes[REED].enable_whitelist()
-        self.nodes[REED].set_router_upgrade_threshold(0)
-
-        self.nodes[SED].set_panid(0xface)
-        self.nodes[SED].set_mode('s')
-        self.nodes[SED].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[SED].enable_whitelist()
-        self.nodes[SED].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_2_REEDAttach_SED(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [REED]
+        },
+        REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, SED]
+        },
+        SED: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [REED]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -100,9 +90,8 @@
         check_parent_request(msg, is_first_request=False)
 
         # Step 6 - DUT sends Child ID Request
-        msg = sed_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_REQUEST, sent_to_node=self.nodes[REED]
-        )
+        msg = sed_messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST,
+                                            sent_to_node=self.nodes[REED])
         check_child_id_request(
             msg,
             address_registration=CheckType.CONTAIN,
@@ -119,9 +108,8 @@
 
         # Step 11 - SED sends periodic 802.15.4 Data Request messages
         msg = sed_messages.next_message()
-        self.assertEqual(
-            False, msg.isMacAddressTypeLong()
-        )  # Extra check, keep-alive messages are of short types of mac address
+        self.assertEqual(False, msg.isMacAddressTypeLong(
+        ))  # Extra check, keep-alive messages are of short types of mac address
         self.assertEqual(msg.type, message.MessageType.COMMAND)
         self.assertEqual(
             msg.mac_header.command_type,
diff --git a/tests/scripts/thread-cert/Cert_6_1_03_RouterAttachConnectivity.py b/tests/scripts/thread-cert/Cert_6_1_03_RouterAttachConnectivity.py
index eebb4e3..678b3f9 100755
--- a/tests/scripts/thread-cert/Cert_6_1_03_RouterAttachConnectivity.py
+++ b/tests/scripts/thread-cert/Cert_6_1_03_RouterAttachConnectivity.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -39,54 +39,38 @@
 ED = 5
 
 
-class Cert_6_1_3_RouterAttachConnectivity(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_3_RouterAttachConnectivity(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2, ROUTER3]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER3]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER1, ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER2, ROUTER3]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_1_04_REEDAttachConnectivity.py b/tests/scripts/thread-cert/Cert_6_1_04_REEDAttachConnectivity.py
index c2ee061..e1d7294 100755
--- a/tests/scripts/thread-cert/Cert_6_1_04_REEDAttachConnectivity.py
+++ b/tests/scripts/thread-cert/Cert_6_1_04_REEDAttachConnectivity.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -39,54 +38,38 @@
 ED = 5
 
 
-class Cert_6_1_4_REEDAttachConnectivity(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[REED0].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[REED0].set_panid(0xface)
-        self.nodes[REED0].set_mode('rsdn')
-        self.nodes[REED0].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED0].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[REED0].set_router_upgrade_threshold(0)
-        self.nodes[REED0].enable_whitelist()
-
-        self.nodes[REED1].set_panid(0xface)
-        self.nodes[REED1].set_mode('rsdn')
-        self.nodes[REED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[REED1].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[REED1].set_router_upgrade_threshold(0)
-        self.nodes[REED1].enable_whitelist()
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[REED0].get_addr64())
-        self.nodes[ED].add_whitelist(self.nodes[REED1].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_4_REEDAttachConnectivity(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, REED0, REED1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, REED1]
+        },
+        REED0: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, ED]
+        },
+        REED1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, ROUTER1, ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [REED0, REED1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_1_05_RouterAttachLinkQuality.py b/tests/scripts/thread-cert/Cert_6_1_05_RouterAttachLinkQuality.py
index 7f33118..778a39b 100755
--- a/tests/scripts/thread-cert/Cert_6_1_05_RouterAttachLinkQuality.py
+++ b/tests/scripts/thread-cert/Cert_6_1_05_RouterAttachLinkQuality.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -38,47 +37,32 @@
 ED = 4
 
 
-class Cert_6_1_5_RouterAttachLinkQuality(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(
-            self.nodes[ED].get_addr64(), rssi=-85
-        )
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_5_RouterAttachLinkQuality(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, (ED, -85)]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_1_06_REEDAttachLinkQuality_ED.py b/tests/scripts/thread-cert/Cert_6_1_06_REEDAttachLinkQuality_ED.py
index 90661e6..6d96b54 100755
--- a/tests/scripts/thread-cert/Cert_6_1_06_REEDAttachLinkQuality_ED.py
+++ b/tests/scripts/thread-cert/Cert_6_1_06_REEDAttachLinkQuality_ED.py
@@ -29,9 +29,8 @@
 
 import unittest
 
-import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 REED = 2
@@ -39,47 +38,32 @@
 ED = 4
 
 
-class Cert_6_1_6_REEDAttachLinkQuality_ED(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[REED].set_panid(0xface)
-        self.nodes[REED].set_mode('rsdn')
-        self.nodes[REED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[REED].set_router_upgrade_threshold(0)
-        self.nodes[REED].enable_whitelist()
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(
-            self.nodes[ED].get_addr64(), rssi=-85
-        )
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_6_REEDAttachLinkQuality_ED(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [REED, ROUTER2]
+        },
+        REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, ED]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, (ED, -85)]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [REED, ROUTER2]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -140,9 +124,7 @@
         self.assertEqual(0, scan_mask_tlv.end_device)
 
         # 4 - Router2
-        msg = router2_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router2_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[ED])
 
         # 5 - ED
@@ -159,9 +141,7 @@
         self.assertEqual(1, scan_mask_tlv.end_device)
 
         # 6 - REED
-        msg = router2_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router2_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[ED])
 
         msg = reed_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
diff --git a/tests/scripts/thread-cert/Cert_6_1_06_REEDAttachLinkQuality_SED.py b/tests/scripts/thread-cert/Cert_6_1_06_REEDAttachLinkQuality_SED.py
index 8ed6533..279e266 100755
--- a/tests/scripts/thread-cert/Cert_6_1_06_REEDAttachLinkQuality_SED.py
+++ b/tests/scripts/thread-cert/Cert_6_1_06_REEDAttachLinkQuality_SED.py
@@ -31,7 +31,7 @@
 
 import config
 import mle
-import node
+import thread_cert
 
 LEADER = 1
 REED = 2
@@ -39,48 +39,33 @@
 SED = 4
 
 
-class Cert_6_1_6_REEDAttachLinkQuality_SED(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i == SED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[REED].set_panid(0xface)
-        self.nodes[REED].set_mode('rsdn')
-        self.nodes[REED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[REED].add_whitelist(self.nodes[SED].get_addr64())
-        self.nodes[REED].set_router_upgrade_threshold(0)
-        self.nodes[REED].enable_whitelist()
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(
-            self.nodes[SED].get_addr64(), rssi=-85
-        )
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[SED].set_panid(0xface)
-        self.nodes[SED].set_mode('s')
-        self.nodes[SED].add_whitelist(self.nodes[REED].get_addr64())
-        self.nodes[SED].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[SED].enable_whitelist()
-        self.nodes[SED].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_6_REEDAttachLinkQuality_SED(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [REED, ROUTER2]
+        },
+        REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_upgrade_threshold': 0,
+            'whitelist': [LEADER, SED]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, (SED, -85)]
+        },
+        SED: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [REED, ROUTER2]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -141,9 +126,7 @@
         self.assertEqual(0, scan_mask_tlv.end_device)
 
         # 4 - Router2
-        msg = router2_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router2_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[SED])
 
         # 5 - SED
@@ -160,9 +143,7 @@
         self.assertEqual(1, scan_mask_tlv.end_device)
 
         # 6 - REED
-        msg = router2_messages.next_mle_message(
-            mle.CommandType.PARENT_RESPONSE
-        )
+        msg = router2_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
         msg.assertSentToNode(self.nodes[SED])
 
         msg = reed_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
diff --git a/tests/scripts/thread-cert/Cert_6_1_07_EDSynchronization.py b/tests/scripts/thread-cert/Cert_6_1_07_EDSynchronization.py
index 6af3b33..e99ced2 100755
--- a/tests/scripts/thread-cert/Cert_6_1_07_EDSynchronization.py
+++ b/tests/scripts/thread-cert/Cert_6_1_07_EDSynchronization.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -39,58 +38,38 @@
 ROUTER3 = 5
 
 
-class Cert_6_1_7_EDSynchronization(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER3].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER3].set_panid(0xface)
-        self.nodes[ROUTER3].set_mode('rsdn')
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER3].enable_whitelist()
-        self.nodes[ROUTER3].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_1_7_EDSynchronization(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ED, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED, ROUTER3]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER, ROUTER1, ROUTER2, ROUTER3]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED, ROUTER3]
+        },
+        ROUTER3: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ED, ROUTER1, ROUTER2]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_2_01_NewPartition.py b/tests/scripts/thread-cert/Cert_6_2_01_NewPartition.py
index 0bfafa6..86ba12f 100755
--- a/tests/scripts/thread-cert/Cert_6_2_01_NewPartition.py
+++ b/tests/scripts/thread-cert/Cert_6_2_01_NewPartition.py
@@ -29,44 +29,33 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
 ED = 3
 
 
-class Cert_6_2_1_NewPartition(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_2_1_NewPartition(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_2_02_NewPartition.py b/tests/scripts/thread-cert/Cert_6_2_02_NewPartition.py
index d2c7cfc..6c1a729 100755
--- a/tests/scripts/thread-cert/Cert_6_2_02_NewPartition.py
+++ b/tests/scripts/thread-cert/Cert_6_2_02_NewPartition.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -38,46 +37,33 @@
 ED = 4
 
 
-class Cert_6_2_2_NewPartition(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_network_id_timeout(110)
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_2_2_NewPartition(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2, ED]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'network_id_timeout': 110,
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER1]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_3_01_OrphanReattach.py b/tests/scripts/thread-cert/Cert_6_3_01_OrphanReattach.py
index 0e7743f..aefd606 100755
--- a/tests/scripts/thread-cert/Cert_6_3_01_OrphanReattach.py
+++ b/tests/scripts/thread-cert/Cert_6_3_01_OrphanReattach.py
@@ -29,45 +29,34 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 ED = 3
 
 
-class Cert_6_3_1_OrphanReattach(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-        self.nodes[ED].set_timeout(10)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_3_1_OrphanReattach(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': 10,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_3_02_NetworkDataUpdate.py b/tests/scripts/thread-cert/Cert_6_3_02_NetworkDataUpdate.py
index 02b34ea..852c2e5 100755
--- a/tests/scripts/thread-cert/Cert_6_3_02_NetworkDataUpdate.py
+++ b/tests/scripts/thread-cert/Cert_6_3_02_NetworkDataUpdate.py
@@ -29,37 +29,27 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ED = 2
 
 
-class Cert_6_3_2_NetworkDataUpdate(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-        self.nodes[ED].set_timeout(10)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_3_2_NetworkDataUpdate(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': 10,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_4_01_LinkLocal.py b/tests/scripts/thread-cert/Cert_6_4_01_LinkLocal.py
index 1448293..b2f7c55 100755
--- a/tests/scripts/thread-cert/Cert_6_4_01_LinkLocal.py
+++ b/tests/scripts/thread-cert/Cert_6_4_01_LinkLocal.py
@@ -29,36 +29,26 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ED = 2
 
 
-class Cert_6_4_1_LinkLocal(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_4_1_LinkLocal(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_4_02_RealmLocal.py b/tests/scripts/thread-cert/Cert_6_4_02_RealmLocal.py
index a8bf7a5..897c772 100755
--- a/tests/scripts/thread-cert/Cert_6_4_02_RealmLocal.py
+++ b/tests/scripts/thread-cert/Cert_6_4_02_RealmLocal.py
@@ -29,44 +29,34 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 ED = 3
 
 
-class Cert_5_3_2_RealmLocal(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_5_3_2_RealmLocal(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        4: {},
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -87,21 +77,16 @@
                 self.assertTrue(self.nodes[LEADER].ping(addr, size=256))
                 self.assertTrue(self.nodes[LEADER].ping(addr))
 
-        self.assertTrue(
-            self.nodes[LEADER].ping('ff03::1', num_responses=2, size=256)
-        )
+        self.assertTrue(self.nodes[LEADER].ping('ff03::1',
+                                                num_responses=2,
+                                                size=256))
         self.assertTrue(self.nodes[LEADER].ping('ff03::1', num_responses=2))
 
-        self.assertTrue(
-            self.nodes[LEADER].ping(
-                'ff33:0040:fdde:ad00:beef:0:0:1', num_responses=2, size=256
-            )
-        )
-        self.assertTrue(
-            self.nodes[LEADER].ping(
-                'ff33:0040:fdde:ad00:beef:0:0:1', num_responses=2
-            )
-        )
+        self.assertTrue(self.nodes[LEADER].ping('ff33:0040:fd00:db8:0:0:0:1',
+                                                num_responses=2,
+                                                size=256))
+        self.assertTrue(self.nodes[LEADER].ping('ff33:0040:fd00:db8:0:0:0:1',
+                                                num_responses=2))
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_6_5_01_ChildResetSynchronize.py b/tests/scripts/thread-cert/Cert_6_5_01_ChildResetSynchronize.py
index fbf9d8a..967c3eb 100755
--- a/tests/scripts/thread-cert/Cert_6_5_01_ChildResetSynchronize.py
+++ b/tests/scripts/thread-cert/Cert_6_5_01_ChildResetSynchronize.py
@@ -30,40 +30,32 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ED = 2
 
 
-class Cert_6_5_1_ChildResetSynchronize(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-        self._setUpEd()
+class Cert_6_5_1_ChildResetSynchronize(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [LEADER]
+        },
+    }
 
     def _setUpEd(self):
         self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
         self.nodes[ED].enable_whitelist()
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_6_5_02_ChildResetReattach.py b/tests/scripts/thread-cert/Cert_6_5_02_ChildResetReattach.py
index 846f6ae..a66c718 100755
--- a/tests/scripts/thread-cert/Cert_6_5_02_ChildResetReattach.py
+++ b/tests/scripts/thread-cert/Cert_6_5_02_ChildResetReattach.py
@@ -29,40 +29,31 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ED = 2
 
 
-class Cert_6_5_2_ChildResetReattach(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self._setUpEd()
+class Cert_6_5_2_ChildResetReattach(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def _setUpEd(self):
         self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
         self.nodes[ED].enable_whitelist()
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_6_6_01_KeyIncrement.py b/tests/scripts/thread-cert/Cert_6_6_01_KeyIncrement.py
index 77967a0..df27239 100755
--- a/tests/scripts/thread-cert/Cert_6_6_01_KeyIncrement.py
+++ b/tests/scripts/thread-cert/Cert_6_6_01_KeyIncrement.py
@@ -29,38 +29,28 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ED = 2
 
 
-class Cert_6_6_1_KeyIncrement(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_key_switch_guardtime(0)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-        self.nodes[ED].set_key_switch_guardtime(0)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_6_1_KeyIncrement(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'key_switch_guardtime': 0,
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'key_switch_guardtime': 0,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_6_6_02_KeyIncrementRollOver.py b/tests/scripts/thread-cert/Cert_6_6_02_KeyIncrementRollOver.py
index 766b42b..6a56755 100755
--- a/tests/scripts/thread-cert/Cert_6_6_02_KeyIncrementRollOver.py
+++ b/tests/scripts/thread-cert/Cert_6_6_02_KeyIncrementRollOver.py
@@ -29,39 +29,29 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER = 1
 ED = 2
 
 
-class Cert_6_6_2_KeyIncrement1(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, (i == ED), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_key_switch_guardtime(0)
-        self.nodes[LEADER].set_key_sequence_counter(127)
-
-        self.nodes[ED].set_panid(0xface)
-        self.nodes[ED].set_mode('rsn')
-        self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ED].enable_whitelist()
-        self.nodes[ED].set_key_switch_guardtime(0)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_6_6_2_KeyIncrement1(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'key_sequence_counter': 127,
+            'key_switch_guardtime': 0,
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'key_switch_guardtime': 0,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_7_1_01_BorderRouterAsLeader.py b/tests/scripts/thread-cert/Cert_7_1_01_BorderRouterAsLeader.py
index 4f02528..7bce176 100755
--- a/tests/scripts/thread-cert/Cert_7_1_01_BorderRouterAsLeader.py
+++ b/tests/scripts/thread-cert/Cert_7_1_01_BorderRouterAsLeader.py
@@ -29,6 +29,8 @@
 
 import unittest
 
+import config
+import thread_cert
 from command import (
     check_child_id_response,
     check_child_update_response,
@@ -38,9 +40,7 @@
 from command import CheckType
 from command import NetworkDataCheck, PrefixesCheck, SinglePrefixCheck
 
-import config
 import mle
-import node
 
 LEADER = 1
 ROUTER = 2
@@ -50,43 +50,33 @@
 MTDS = [SED1, MED1]
 
 
-class Cert_7_1_1_BorderRouterAsLeader(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[MED1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-        self.nodes[MED1].set_panid(0xface)
-        self.nodes[MED1].set_mode('rsn')
-        self.nodes[MED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[MED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_7_1_1_BorderRouterAsLeader(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER, SED1, MED1]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [LEADER]
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -138,68 +128,52 @@
         msg = leader_messages.next_mle_message(mle.CommandType.DATA_RESPONSE)
         check_data_response(
             msg,
-            network_data_check=NetworkDataCheck(
-                prefixes_check=PrefixesCheck(
-                    prefix_check_list=[
-                        SinglePrefixCheck(prefix=b'2001000200000001'),
-                        SinglePrefixCheck(prefix=b'2001000200000002'),
-                    ]
-                )
-            ),
+            network_data_check=NetworkDataCheck(prefixes_check=PrefixesCheck(
+                prefix_check_list=[
+                    SinglePrefixCheck(prefix=b'2001000200000001'),
+                    SinglePrefixCheck(prefix=b'2001000200000002'),
+                ])),
         )
 
         # Step 4 - DUT sends a MLE Child ID Response to Router1
         msg = leader_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        )
+            mle.CommandType.CHILD_ID_RESPONSE)
         check_child_id_response(
             msg,
-            network_data_check=NetworkDataCheck(
-                prefixes_check=PrefixesCheck(prefix_cnt=2)
-            ),
+            network_data_check=NetworkDataCheck(prefixes_check=PrefixesCheck(
+                prefix_cnt=2)),
         )
 
         # Step 6 - DUT sends a MLE Child ID Response to SED1
         msg = leader_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        )
+            mle.CommandType.CHILD_ID_RESPONSE)
         check_child_id_response(
             msg,
-            network_data_check=NetworkDataCheck(
-                prefixes_check=PrefixesCheck(
-                    prefix_check_list=[
-                        SinglePrefixCheck(border_router_16=0xfffe)
-                    ]
-                )
-            ),
+            network_data_check=NetworkDataCheck(prefixes_check=PrefixesCheck(
+                prefix_check_list=[SinglePrefixCheck(
+                    border_router_16=0xfffe)])),
         )
 
         # For Step 10
         msg_chd_upd_res_to_sed = leader_messages.next_mle_message(
-            mle.CommandType.CHILD_UPDATE_RESPONSE
-        )
+            mle.CommandType.CHILD_UPDATE_RESPONSE)
 
         # Step 8 - DUT sends a MLE Child ID Response to MED1
         msg = leader_messages.next_mle_message(
-            mle.CommandType.CHILD_ID_RESPONSE
-        )
+            mle.CommandType.CHILD_ID_RESPONSE)
         check_child_id_response(
             msg,
-            network_data_check=NetworkDataCheck(
-                prefixes_check=PrefixesCheck(prefix_cnt=2)
-            ),
+            network_data_check=NetworkDataCheck(prefixes_check=PrefixesCheck(
+                prefix_cnt=2)),
         )
 
         # Step 10 - DUT sends Child Update Response
         msg_chd_upd_res_to_med = leader_messages.next_mle_message(
-            mle.CommandType.CHILD_UPDATE_RESPONSE
-        )
+            mle.CommandType.CHILD_UPDATE_RESPONSE)
         msg = med1_messages.next_mle_message(
-            mle.CommandType.CHILD_UPDATE_REQUEST
-        )
+            mle.CommandType.CHILD_UPDATE_REQUEST)
         check_child_update_request_from_child(
-            msg, address_registration=CheckType.CONTAIN, CIDs=[0, 1, 2]
-        )
+            msg, address_registration=CheckType.CONTAIN, CIDs=[0, 1, 2])
 
         check_child_update_response(
             msg_chd_upd_res_to_med,
@@ -208,11 +182,9 @@
         )
 
         msg = sed1_messages.next_mle_message(
-            mle.CommandType.CHILD_UPDATE_REQUEST
-        )
+            mle.CommandType.CHILD_UPDATE_REQUEST)
         check_child_update_request_from_child(
-            msg, address_registration=CheckType.CONTAIN, CIDs=[0, 1]
-        )
+            msg, address_registration=CheckType.CONTAIN, CIDs=[0, 1])
         check_child_update_response(
             msg_chd_upd_res_to_sed,
             address_registration=CheckType.CONTAIN,
diff --git a/tests/scripts/thread-cert/Cert_7_1_02_BorderRouterAsRouter.py b/tests/scripts/thread-cert/Cert_7_1_02_BorderRouterAsRouter.py
index 22eb0c8..26ba669 100755
--- a/tests/scripts/thread-cert/Cert_7_1_02_BorderRouterAsRouter.py
+++ b/tests/scripts/thread-cert/Cert_7_1_02_BorderRouterAsRouter.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [ED2, SED2]
 
 
-class Cert_7_1_2_BorderRouterAsRouter(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED2].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED2].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED2].set_panid(0xface)
-        self.nodes[ED2].set_mode('rsn')
-        self.nodes[ED2].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED2].enable_whitelist()
-
-        self.nodes[SED2].set_panid(0xface)
-        self.nodes[SED2].set_mode('s')
-        self.nodes[SED2].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED2].enable_whitelist()
-        self.nodes[SED2].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_7_1_2_BorderRouterAsRouter(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED2, SED2]
+        },
+        ED2: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED2: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_7_1_03_BorderRouterAsLeader.py b/tests/scripts/thread-cert/Cert_7_1_03_BorderRouterAsLeader.py
index 018cb04..7bc03fe 100755
--- a/tests/scripts/thread-cert/Cert_7_1_03_BorderRouterAsLeader.py
+++ b/tests/scripts/thread-cert/Cert_7_1_03_BorderRouterAsLeader.py
@@ -29,6 +29,7 @@
 
 import unittest
 
+import thread_cert
 from command import (
     check_child_update_request_from_child,
     check_child_update_request_from_parent,
@@ -40,7 +41,6 @@
 
 import config
 import mle
-import node
 
 LEADER = 1
 ROUTER = 2
@@ -50,43 +50,33 @@
 MTDS = [SED1, MED1]
 
 
-class Cert_7_1_3_BorderRouterAsLeader(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[MED1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[SED1].set_panid(0xface)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-        self.nodes[MED1].set_panid(0xface)
-        self.nodes[MED1].set_mode('rsn')
-        self.nodes[MED1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[MED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_7_1_3_BorderRouterAsLeader(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER, SED1, MED1]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [LEADER]
+        },
+        MED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         # 1 - All
@@ -143,24 +133,19 @@
         msg = leader_messages.next_mle_message(mle.CommandType.DATA_RESPONSE)
         check_data_response(
             msg,
-            network_data_check=NetworkDataCheck(
-                prefixes_check=PrefixesCheck(
-                    prefix_check_list=[
-                        SinglePrefixCheck(b'2001000200000001'),
-                        SinglePrefixCheck(b'2001000200000002'),
-                    ]
-                )
-            ),
+            network_data_check=NetworkDataCheck(prefixes_check=PrefixesCheck(
+                prefix_check_list=[
+                    SinglePrefixCheck(b'2001000200000001'),
+                    SinglePrefixCheck(b'2001000200000002'),
+                ])),
         )
 
         # 4 - N/A
         # Get addresses registered by MED1
         msg = med1_messages.next_mle_message(
-            mle.CommandType.CHILD_UPDATE_REQUEST
-        )
+            mle.CommandType.CHILD_UPDATE_REQUEST)
         check_child_update_request_from_child(
-            msg, address_registration=CheckType.CONTAIN, CIDs=[0, 1, 2]
-        )
+            msg, address_registration=CheckType.CONTAIN, CIDs=[0, 1, 2])
 
         # 5 - Leader
         # Make a copy of leader's messages to ensure that we don't miss
@@ -170,9 +155,9 @@
             mle.CommandType.CHILD_UPDATE_RESPONSE,
             sent_to_node=self.nodes[MED1],
         )
-        check_child_update_response(
-            msg, address_registration=CheckType.CONTAIN, CIDs=[1, 2]
-        )
+        check_child_update_response(msg,
+                                    address_registration=CheckType.CONTAIN,
+                                    CIDs=[1, 2])
 
         # 6A & 6B - Leader
         if config.LEADER_NOTIFY_SED_BY_CHILD_UPDATE_REQUEST:
@@ -188,27 +173,24 @@
             )
         else:
             msg = leader_messages.next_mle_message(
-                mle.CommandType.DATA_RESPONSE, sent_to_node=self.nodes[SED1]
-            )
+                mle.CommandType.DATA_RESPONSE, sent_to_node=self.nodes[SED1])
             check_data_response(msg, network_data_check=NetworkDataCheck())
 
         # 7 - N/A
         # Get addresses registered by SED1
         msg = sed1_messages.next_mle_message(
-            mle.CommandType.CHILD_UPDATE_REQUEST
-        )
+            mle.CommandType.CHILD_UPDATE_REQUEST)
         check_child_update_request_from_child(
-            msg, address_registration=CheckType.CONTAIN, CIDs=[0, 1]
-        )
+            msg, address_registration=CheckType.CONTAIN, CIDs=[0, 1])
 
         # 8 - Leader
         msg = leader_messages.next_mle_message(
             mle.CommandType.CHILD_UPDATE_RESPONSE,
             sent_to_node=self.nodes[SED1],
         )
-        check_child_update_response(
-            msg, address_registration=CheckType.CONTAIN, CIDs=[1]
-        )
+        check_child_update_response(msg,
+                                    address_registration=CheckType.CONTAIN,
+                                    CIDs=[1])
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/Cert_7_1_04_BorderRouterAsRouter.py b/tests/scripts/thread-cert/Cert_7_1_04_BorderRouterAsRouter.py
index 7ffb393..10e4a7d 100755
--- a/tests/scripts/thread-cert/Cert_7_1_04_BorderRouterAsRouter.py
+++ b/tests/scripts/thread-cert/Cert_7_1_04_BorderRouterAsRouter.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [SED2, ED2]
 
 
-class Cert_7_1_4_BorderRouterAsRouter(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED2].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED2].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED2].set_panid(0xface)
-        self.nodes[ED2].set_mode('rsn')
-        self.nodes[ED2].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED2].enable_whitelist()
-
-        self.nodes[SED2].set_panid(0xface)
-        self.nodes[SED2].set_mode('s')
-        self.nodes[SED2].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED2].enable_whitelist()
-        self.nodes[SED2].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_7_1_4_BorderRouterAsRouter(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED2, SED2]
+        },
+        ED2: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED2: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_7_1_05_BorderRouterAsRouter.py b/tests/scripts/thread-cert/Cert_7_1_05_BorderRouterAsRouter.py
index f048369..bc12f72 100755
--- a/tests/scripts/thread-cert/Cert_7_1_05_BorderRouterAsRouter.py
+++ b/tests/scripts/thread-cert/Cert_7_1_05_BorderRouterAsRouter.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
@@ -40,43 +40,33 @@
 MTDS = [ED2, SED2]
 
 
-class Cert_7_1_5_BorderRouterAsRouter(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[ED2].get_addr64())
-        self.nodes[ROUTER].add_whitelist(self.nodes[SED2].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[ED2].set_panid(0xface)
-        self.nodes[ED2].set_mode('rsn')
-        self.nodes[ED2].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[ED2].enable_whitelist()
-
-        self.nodes[SED2].set_panid(0xface)
-        self.nodes[SED2].set_mode('s')
-        self.nodes[SED2].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[SED2].enable_whitelist()
-        self.nodes[SED2].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class Cert_7_1_5_BorderRouterAsRouter(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED2, SED2]
+        },
+        ED2: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED2: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -127,11 +117,8 @@
         self.assertTrue(any('2001:2:0:2' in addr[0:10] for addr in addrs))
         self.assertTrue(any('2001:2:0:3' in addr[0:10] for addr in addrs))
         for addr in addrs:
-            if (
-                addr[0:10] == '2001:2:0:1'
-                or addr[0:10] == '2001:2:0:2'
-                or addr[0:10] == '2001:2:0:3'
-            ):
+            if (addr[0:10] == '2001:2:0:1' or addr[0:10] == '2001:2:0:2' or
+                    addr[0:10] == '2001:2:0:3'):
                 self.assertTrue(self.nodes[LEADER].ping(addr))
 
         addrs = self.nodes[SED2].get_addrs()
@@ -139,11 +126,8 @@
         self.assertFalse(any('2001:2:0:2' in addr[0:10] for addr in addrs))
         self.assertTrue(any('2001:2:0:3' in addr[0:10] for addr in addrs))
         for addr in addrs:
-            if (
-                addr[0:10] == '2001:2:0:1'
-                or addr[0:10] == '2001:2:0:2'
-                or addr[0:10] == '2001:2:0:3'
-            ):
+            if (addr[0:10] == '2001:2:0:1' or addr[0:10] == '2001:2:0:2' or
+                    addr[0:10] == '2001:2:0:3'):
                 self.assertTrue(self.nodes[LEADER].ping(addr))
 
 
diff --git a/tests/scripts/thread-cert/Cert_8_1_01_Commissioning.py b/tests/scripts/thread-cert/Cert_8_1_01_Commissioning.py
index e5ee374..0a5e214 100755
--- a/tests/scripts/thread-cert/Cert_8_1_01_Commissioning.py
+++ b/tests/scripts/thread-cert/Cert_8_1_01_Commissioning.py
@@ -30,10 +30,9 @@
 import unittest
 
 import command
-import config
 import dtls
 import mle
-import node
+import thread_cert
 
 from command import CheckType
 
@@ -41,29 +40,21 @@
 JOINER = 2
 
 
-class Cert_8_1_01_Commissioning(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_8_1_01_Commissioning(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_panid(0xface)
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].set_masterkey(
-            '00112233445566778899aabbccddeeff'
-        )
-
-        self.nodes[JOINER].set_mode('rsdn')
-        self.nodes[JOINER].set_masterkey('deadbeefdeadbeefdeadbeefdeadbeef')
-        self.nodes[JOINER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'masterkey': '00112233445566778899aabbccddeeff',
+            'mode': 'rsdn',
+            'panid': 0xface
+        },
+        JOINER: {
+            'masterkey': 'deadbeefdeadbeefdeadbeefdeadbeef',
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+    }
 
     def test(self):
         self.nodes[COMMISSIONER].interface_up()
@@ -73,15 +64,13 @@
         self.nodes[COMMISSIONER].commissioner_start()
         self.simulator.go(3)
         self.nodes[COMMISSIONER].commissioner_add_joiner(
-            self.nodes[JOINER].get_eui64(), 'OPENTHREAD'
-        )
+            self.nodes[JOINER].get_eui64(), 'PSKD01')
 
         self.nodes[JOINER].interface_up()
-        self.nodes[JOINER].joiner_start('OPENTHREAD')
+        self.nodes[JOINER].joiner_start('PSKD01')
         self.simulator.go(10)
         self.simulator.read_cert_messages_in_commissioning_log(
-            [COMMISSIONER, JOINER]
-        )
+            [COMMISSIONER, JOINER])
         self.assertEqual(
             self.nodes[JOINER].get_masterkey(),
             self.nodes[COMMISSIONER].get_masterkey(),
@@ -89,66 +78,55 @@
 
         joiner_messages = self.simulator.get_messages_sent_by(JOINER)
         commissioner_messages = self.simulator.get_messages_sent_by(
-            COMMISSIONER
-        )
+            COMMISSIONER)
 
         # 2 - N/A
 
         # 3 - Joiner_1
         msg = joiner_messages.next_mle_message(
-            mle.CommandType.DISCOVERY_REQUEST
-        )
+            mle.CommandType.DISCOVERY_REQUEST)
         command.check_discovery_request(msg)
         request_src_addr = msg.mac_header.src_address
 
         # 4 - Commissioner
         msg = commissioner_messages.next_mle_message(
-            mle.CommandType.DISCOVERY_RESPONSE
-        )
-        command.check_discovery_response(
-            msg, request_src_addr, steering_data=CheckType.CONTAIN
-        )
+            mle.CommandType.DISCOVERY_RESPONSE)
+        command.check_discovery_response(msg,
+                                         request_src_addr,
+                                         steering_data=CheckType.CONTAIN)
         udp_port_set_by_commissioner = command.get_joiner_udp_port_in_discovery_response(
             msg)
 
         # 5.2 - Joiner_1
-        msg = joiner_messages.next_dtls_message(
-            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.CLIENT_HELLO
-        )
+        msg = joiner_messages.next_dtls_message(dtls.ContentType.HANDSHAKE,
+                                                dtls.HandshakeType.CLIENT_HELLO)
         self.assertEqual(msg.get_dst_udp_port(), udp_port_set_by_commissioner)
 
         # 5.3 - Commissioner
         msg = commissioner_messages.next_dtls_message(
-            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.HELLO_VERIFY_REQUEST
-        )
+            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.HELLO_VERIFY_REQUEST)
         commissioner_cookie = msg.dtls.body.cookie
 
         # 5.4 - Joiner_1
-        msg = joiner_messages.next_dtls_message(
-            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.CLIENT_HELLO
-        )
+        msg = joiner_messages.next_dtls_message(dtls.ContentType.HANDSHAKE,
+                                                dtls.HandshakeType.CLIENT_HELLO)
         self.assertEqual(commissioner_cookie, msg.dtls.body.cookie)
         self.assertEqual(msg.get_dst_udp_port(), udp_port_set_by_commissioner)
 
         # 5.5 - Commissioner
+        commissioner_messages.next_dtls_message(dtls.ContentType.HANDSHAKE,
+                                                dtls.HandshakeType.SERVER_HELLO)
         commissioner_messages.next_dtls_message(
-            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.SERVER_HELLO
-        )
+            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.SERVER_KEY_EXCHANGE)
         commissioner_messages.next_dtls_message(
-            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.SERVER_KEY_EXCHANGE
-        )
-        commissioner_messages.next_dtls_message(
-            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.SERVER_HELLO_DONE
-        )
+            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.SERVER_HELLO_DONE)
 
         # 5.6 - Joiner_1
         msg = joiner_messages.next_dtls_message(
-            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.CLIENT_KEY_EXCHANGE
-        )
+            dtls.ContentType.HANDSHAKE, dtls.HandshakeType.CLIENT_KEY_EXCHANGE)
         self.assertEqual(msg.get_dst_udp_port(), udp_port_set_by_commissioner)
         msg = joiner_messages.next_dtls_message(
-            dtls.ContentType.CHANGE_CIPHER_SPEC
-        )
+            dtls.ContentType.CHANGE_CIPHER_SPEC)
         self.assertEqual(msg.get_dst_udp_port(), udp_port_set_by_commissioner)
 
         # TODO(wgtdkp): It's required to verify DTLS FINISHED message here.
@@ -156,8 +134,7 @@
 
         # 5.7 - Commissioner
         commissioner_messages.next_dtls_message(
-            dtls.ContentType.CHANGE_CIPHER_SPEC
-        )
+            dtls.ContentType.CHANGE_CIPHER_SPEC)
 
         # TODO(wgtdkp): It's required to verify DTLS FINISHED message here.
         # Currently not handled as it is encrypted.
@@ -165,16 +142,13 @@
         # 5.8,9,10,11
         # - Joiner_1
         command.check_joiner_commissioning_messages(
-            joiner_messages.commissioning_messages
-        )
+            joiner_messages.commissioning_messages)
         # - Commissioner
         command.check_commissioner_commissioning_messages(
-            commissioner_messages.commissioning_messages
-        )
+            commissioner_messages.commissioning_messages)
         # As commissioner is also joiner router
         command.check_joiner_router_commissioning_messages(
-            commissioner_messages.commissioning_messages
-        )
+            commissioner_messages.commissioning_messages)
 
         self.nodes[JOINER].thread_start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_8_1_02_Commissioning.py b/tests/scripts/thread-cert/Cert_8_1_02_Commissioning.py
index 01c60a2..0d39c48 100755
--- a/tests/scripts/thread-cert/Cert_8_1_02_Commissioning.py
+++ b/tests/scripts/thread-cert/Cert_8_1_02_Commissioning.py
@@ -29,36 +29,27 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 COMMISSIONER = 1
 JOINER = 2
 
 
-class Cert_8_1_02_Commissioning(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_8_1_02_Commissioning(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_panid(0xface)
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].set_masterkey(
-            'deadbeefdeadbeefdeadbeefdeadbeef'
-        )
-
-        self.nodes[JOINER].set_mode('rsdn')
-        self.nodes[JOINER].set_masterkey('00112233445566778899aabbccddeeff')
-        self.nodes[JOINER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'masterkey': 'deadbeefdeadbeefdeadbeefdeadbeef',
+            'mode': 'rsdn',
+            'panid': 0xface
+        },
+        JOINER: {
+            'masterkey': '00112233445566778899aabbccddeeff',
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+    }
 
     def test(self):
         self.nodes[COMMISSIONER].interface_up()
@@ -68,11 +59,10 @@
         self.nodes[COMMISSIONER].commissioner_start()
         self.simulator.go(3)
         self.nodes[COMMISSIONER].commissioner_add_joiner(
-            self.nodes[JOINER].get_eui64(), 'OPENTHREAD'
-        )
+            self.nodes[JOINER].get_eui64(), 'PSKD01')
 
         self.nodes[JOINER].interface_up()
-        self.nodes[JOINER].joiner_start('DAERHTNEPO')
+        self.nodes[JOINER].joiner_start('10DKSP')
         self.simulator.go(10)
         self.assertNotEqual(
             self.nodes[JOINER].get_masterkey(),
diff --git a/tests/scripts/thread-cert/Cert_8_2_01_JoinerRouter.py b/tests/scripts/thread-cert/Cert_8_2_01_JoinerRouter.py
index 0cb54bb..925731d 100755
--- a/tests/scripts/thread-cert/Cert_8_2_01_JoinerRouter.py
+++ b/tests/scripts/thread-cert/Cert_8_2_01_JoinerRouter.py
@@ -29,47 +29,34 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 COMMISSIONER = 1
 JOINER_ROUTER = 2
 JOINER = 3
 
 
-class Cert_8_2_01_JoinerRouter(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_8_2_01_JoinerRouter(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_panid(0xface)
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].set_masterkey(
-            'deadbeefdeadbeefdeadbeefdeadbeef'
-        )
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[JOINER_ROUTER].set_mode('rsdn')
-        self.nodes[JOINER_ROUTER].set_masterkey(
-            '00112233445566778899aabbccddeeff'
-        )
-        self.nodes[JOINER_ROUTER].enable_whitelist()
-        self.nodes[JOINER_ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[JOINER].set_mode('rsdn')
-        self.nodes[JOINER].set_masterkey('00112233445566778899aabbccddeeff')
-        self.nodes[JOINER].enable_whitelist()
-        self.nodes[JOINER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'masterkey': 'deadbeefdeadbeefdeadbeefdeadbeef',
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        JOINER_ROUTER: {
+            'masterkey': '00112233445566778899aabbccddeeff',
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+        JOINER: {
+            'masterkey': '00112233445566778899aabbccddeeff',
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+    }
 
     def test(self):
         self.nodes[COMMISSIONER].interface_up()
@@ -80,55 +67,38 @@
         self.nodes[COMMISSIONER].commissioner_start()
         self.simulator.go(5)
         self.nodes[COMMISSIONER].commissioner_add_joiner(
-            self.nodes[JOINER_ROUTER].get_eui64(), 'OPENTHREAD'
-        )
+            self.nodes[JOINER_ROUTER].get_eui64(), 'PSKD01')
         self.nodes[COMMISSIONER].commissioner_add_joiner(
-            self.nodes[JOINER].get_eui64(), 'OPENTHREAD2'
-        )
+            self.nodes[JOINER].get_eui64(), 'PSKD02')
         self.simulator.go(5)
 
-        self.nodes[COMMISSIONER].add_whitelist(
-            self.nodes[JOINER_ROUTER].get_joiner_id()
-        )
-        self.nodes[JOINER_ROUTER].add_whitelist(
-            self.nodes[COMMISSIONER].get_addr64()
-        )
-
         self.nodes[JOINER_ROUTER].interface_up()
-        self.nodes[JOINER_ROUTER].joiner_start('OPENTHREAD')
+        self.nodes[JOINER_ROUTER].joiner_start('PSKD01')
         self.simulator.go(10)
         self.assertEqual(
             self.nodes[JOINER_ROUTER].get_masterkey(),
             self.nodes[COMMISSIONER].get_masterkey(),
         )
 
-        self.nodes[COMMISSIONER].add_whitelist(
-            self.nodes[JOINER_ROUTER].get_addr64()
-        )
-
         self.nodes[JOINER_ROUTER].thread_start()
         self.simulator.go(5)
         self.assertEqual(self.nodes[JOINER_ROUTER].get_state(), 'router')
 
-        self.nodes[JOINER_ROUTER].add_whitelist(
-            self.nodes[JOINER].get_joiner_id()
-        )
-        self.nodes[JOINER].add_whitelist(
-            self.nodes[JOINER_ROUTER].get_addr64()
-        )
+        self.nodes[COMMISSIONER].enable_whitelist()
+        self.nodes[COMMISSIONER].add_whitelist(
+            self.nodes[JOINER_ROUTER].get_addr64())
+
+        self.nodes[JOINER].enable_whitelist()
+        self.nodes[JOINER].add_whitelist(self.nodes[JOINER_ROUTER].get_addr64())
 
         self.nodes[JOINER].interface_up()
-        self.nodes[JOINER].joiner_start('OPENTHREAD2')
+        self.nodes[JOINER].joiner_start('PSKD02')
         self.simulator.go(10)
         self.assertEqual(
             self.nodes[JOINER].get_masterkey(),
             self.nodes[COMMISSIONER].get_masterkey(),
         )
 
-        self.nodes[JOINER_ROUTER].add_whitelist(
-            self.nodes[JOINER].get_addr64()
-        )
-
         self.nodes[JOINER].thread_start()
         self.simulator.go(5)
         self.assertEqual(self.nodes[JOINER].get_state(), 'router')
diff --git a/tests/scripts/thread-cert/Cert_8_2_02_JoinerRouter.py b/tests/scripts/thread-cert/Cert_8_2_02_JoinerRouter.py
index e3e7354..7efff79 100755
--- a/tests/scripts/thread-cert/Cert_8_2_02_JoinerRouter.py
+++ b/tests/scripts/thread-cert/Cert_8_2_02_JoinerRouter.py
@@ -29,47 +29,34 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 COMMISSIONER = 1
 JOINER_ROUTER = 2
 JOINER = 3
 
 
-class Cert_8_2_02_JoinerRouter(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_8_2_02_JoinerRouter(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_panid(0xface)
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].set_masterkey(
-            'deadbeefdeadbeefdeadbeefdeadbeef'
-        )
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[JOINER_ROUTER].set_mode('rsdn')
-        self.nodes[JOINER_ROUTER].set_masterkey(
-            '00112233445566778899aabbccddeeff'
-        )
-        self.nodes[JOINER_ROUTER].enable_whitelist()
-        self.nodes[JOINER_ROUTER].set_router_selection_jitter(1)
-
-        self.nodes[JOINER].set_mode('rsdn')
-        self.nodes[JOINER].set_masterkey('00112233445566778899aabbccddeeff')
-        self.nodes[JOINER].enable_whitelist()
-        self.nodes[JOINER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'masterkey': 'deadbeefdeadbeefdeadbeefdeadbeef',
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+        JOINER_ROUTER: {
+            'masterkey': '00112233445566778899aabbccddeeff',
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+        JOINER: {
+            'masterkey': '00112233445566778899aabbccddeeff',
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+    }
 
     def test(self):
         self.nodes[COMMISSIONER].interface_up()
@@ -80,45 +67,32 @@
         self.nodes[COMMISSIONER].commissioner_start()
         self.simulator.go(5)
         self.nodes[COMMISSIONER].commissioner_add_joiner(
-            self.nodes[JOINER_ROUTER].get_eui64(), 'OPENTHREAD'
-        )
+            self.nodes[JOINER_ROUTER].get_eui64(), 'PSKD01')
         self.nodes[COMMISSIONER].commissioner_add_joiner(
-            self.nodes[JOINER].get_eui64(), 'OPENTHREAD2'
-        )
+            self.nodes[JOINER].get_eui64(), 'PSKD02')
         self.simulator.go(5)
 
-        self.nodes[COMMISSIONER].add_whitelist(
-            self.nodes[JOINER_ROUTER].get_joiner_id()
-        )
-        self.nodes[JOINER_ROUTER].add_whitelist(
-            self.nodes[COMMISSIONER].get_addr64()
-        )
-
         self.nodes[JOINER_ROUTER].interface_up()
-        self.nodes[JOINER_ROUTER].joiner_start('OPENTHREAD')
+        self.nodes[JOINER_ROUTER].joiner_start('PSKD01')
         self.simulator.go(10)
         self.assertEqual(
             self.nodes[JOINER_ROUTER].get_masterkey(),
             self.nodes[COMMISSIONER].get_masterkey(),
         )
 
-        self.nodes[COMMISSIONER].add_whitelist(
-            self.nodes[JOINER_ROUTER].get_addr64()
-        )
-
         self.nodes[JOINER_ROUTER].thread_start()
         self.simulator.go(5)
         self.assertEqual(self.nodes[JOINER_ROUTER].get_state(), 'router')
 
-        self.nodes[JOINER_ROUTER].add_whitelist(
-            self.nodes[JOINER].get_joiner_id()
-        )
-        self.nodes[JOINER].add_whitelist(
-            self.nodes[JOINER_ROUTER].get_addr64()
-        )
+        self.nodes[COMMISSIONER].enable_whitelist()
+        self.nodes[COMMISSIONER].add_whitelist(
+            self.nodes[JOINER_ROUTER].get_addr64())
+
+        self.nodes[JOINER].enable_whitelist()
+        self.nodes[JOINER].add_whitelist(self.nodes[JOINER_ROUTER].get_addr64())
 
         self.nodes[JOINER].interface_up()
-        self.nodes[JOINER].joiner_start('2DAERHTNEPO')
+        self.nodes[JOINER].joiner_start('20DKSP')
         self.simulator.go(10)
         self.assertNotEqual(
             self.nodes[JOINER].get_masterkey(),
diff --git a/tests/scripts/thread-cert/Cert_9_2_02_MGMTCommissionerSet.py b/tests/scripts/thread-cert/Cert_9_2_02_MGMTCommissionerSet.py
index 1ab4750..9749343 100755
--- a/tests/scripts/thread-cert/Cert_9_2_02_MGMTCommissionerSet.py
+++ b/tests/scripts/thread-cert/Cert_9_2_02_MGMTCommissionerSet.py
@@ -31,40 +31,31 @@
 import unittest
 
 import command
-import config
 import mesh_cop
 import mle
-import node
+import thread_cert
 
 COMMISSIONER = 1
 LEADER = 2
 
 
-class Cert_9_2_02_MGMTCommissionerSet(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_02_MGMTCommissionerSet(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_panid(0xface)
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [COMMISSIONER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -84,19 +75,17 @@
         self.simulator.go(3)
         self.simulator.get_messages_sent_by(COMMISSIONER)  # Skip LEAD_PET.req
 
-        # Get CommissionerSesssionId from LEAD_PET.rsp
+        # Get CommissionerSessionId from LEAD_PET.rsp
         leader_messages = self.simulator.get_messages_sent_by(LEADER)
         msg = leader_messages.next_coap_message('2.04', assert_enabled=True)
         commissioner_session_id_tlv = command.get_sub_tlv(
-            msg.coap.payload, mesh_cop.CommissionerSessionId
-        )
+            msg.coap.payload, mesh_cop.CommissionerSessionId)
 
         # Step 2 - Harness instructs commissioner to send
         # MGMT_COMMISSIONER_SET.req to Leader
         steering_data_tlv = mesh_cop.SteeringData(bytes([0xff]))
         self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs(
-            [steering_data_tlv]
-        )
+            [steering_data_tlv])
         self.simulator.go(5)
 
         # Step 3 - Leader responds to MGMT_COMMISSIONER_SET.req with
@@ -105,19 +94,16 @@
         msg = leader_messages.next_coap_message('2.04')
         # (mesh_cop.State(mesh_cop.MeshCopState.REJECT),) <- this a tuple, don't delete the comma
         command.check_coap_message(
-            msg, [mesh_cop.State(mesh_cop.MeshCopState.REJECT)]
-        )
+            msg, [mesh_cop.State(mesh_cop.MeshCopState.REJECT)])
         self.simulator.get_messages_sent_by(COMMISSIONER)  # Skip LEAD_PET.req
 
         # Step 4 - Harness instructs commissioner to send
         # MGMT_COMMISSIONER_SET.req to Leader
         self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs(
-            [steering_data_tlv, commissioner_session_id_tlv]
-        )
+            [steering_data_tlv, commissioner_session_id_tlv])
         self.simulator.go(5)
         commissioner_messages = self.simulator.get_messages_sent_by(
-            COMMISSIONER
-        )
+            COMMISSIONER)
         msg = commissioner_messages.next_coap_message('0.02', uri_path='/c/cs')
         rloc = ip_address(self.nodes[LEADER].get_rloc())
         leader_aloc = ip_address(self.nodes[LEADER].get_addr_leader_aloc())
@@ -131,8 +117,7 @@
         leader_messages = self.simulator.get_messages_sent_by(LEADER)
         msg = leader_messages.next_coap_message('2.04')
         command.check_coap_message(
-            msg, [mesh_cop.State(mesh_cop.MeshCopState.ACCEPT)]
-        )
+            msg, [mesh_cop.State(mesh_cop.MeshCopState.ACCEPT)])
 
         # Step 6 - Leader sends a multicast MLE Data Response
         msg = leader_messages.next_mle_message(mle.CommandType.DATA_RESPONSE)
@@ -146,16 +131,14 @@
                         mesh_cop.SteeringData,
                         mesh_cop.BorderAgentLocator,
                     ],
-                )
-            ),
+                )),
         )
 
         # Step 7 - Harness instructs commissioner to send
         # MGMT_COMMISSIONER_SET.req to Leader
         border_agent_locator_tlv = mesh_cop.BorderAgentLocator(0x0400)
         self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs(
-            [commissioner_session_id_tlv, border_agent_locator_tlv]
-        )
+            [commissioner_session_id_tlv, border_agent_locator_tlv])
         self.simulator.go(5)
 
         # Step 8 - Leader responds to MGMT_COMMISSIONER_SET.req with
@@ -163,18 +146,15 @@
         leader_messages = self.simulator.get_messages_sent_by(LEADER)
         msg = leader_messages.next_coap_message('2.04')
         command.check_coap_message(
-            msg, [mesh_cop.State(mesh_cop.MeshCopState.REJECT)]
-        )
+            msg, [mesh_cop.State(mesh_cop.MeshCopState.REJECT)])
 
         # Step 9 - Harness instructs commissioner to send
         # MGMT_COMMISSIONER_SET.req to Leader
-        self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs(
-            [
-                steering_data_tlv,
-                commissioner_session_id_tlv,
-                border_agent_locator_tlv,
-            ]
-        )
+        self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs([
+            steering_data_tlv,
+            commissioner_session_id_tlv,
+            border_agent_locator_tlv,
+        ])
         self.simulator.go(5)
 
         # Step 10 - Leader responds to MGMT_COMMISSIONER_SET.req with
@@ -182,14 +162,12 @@
         leader_messages = self.simulator.get_messages_sent_by(LEADER)
         msg = leader_messages.next_coap_message('2.04')
         command.check_coap_message(
-            msg, [mesh_cop.State(mesh_cop.MeshCopState.REJECT)]
-        )
+            msg, [mesh_cop.State(mesh_cop.MeshCopState.REJECT)])
 
         # Step 11 - Harness instructs commissioner to send
         # MGMT_COMMISSIONER_SET.req to Leader
         self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs(
-            [mesh_cop.CommissionerSessionId(0xffff), steering_data_tlv]
-        )
+            [mesh_cop.CommissionerSessionId(0xffff), steering_data_tlv])
         self.simulator.go(5)
 
         # Step 12 - Leader responds to MGMT_COMMISSIONER_SET.req with
@@ -197,18 +175,15 @@
         leader_messages = self.simulator.get_messages_sent_by(LEADER)
         msg = leader_messages.next_coap_message('2.04')
         command.check_coap_message(
-            msg, [mesh_cop.State(mesh_cop.MeshCopState.REJECT)]
-        )
+            msg, [mesh_cop.State(mesh_cop.MeshCopState.REJECT)])
 
         # Step 13 - Harness instructs commissioner to send
         # MGMT_COMMISSIONER_SET.req to Leader
-        self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs(
-            [
-                commissioner_session_id_tlv,
-                steering_data_tlv,
-                mesh_cop.Channel(0x0, 0x0),
-            ]
-        )
+        self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs([
+            commissioner_session_id_tlv,
+            steering_data_tlv,
+            mesh_cop.Channel(0x0, 0x0),
+        ])
         self.simulator.go(5)
 
         # Step 14 - Leader responds to MGMT_COMMISSIONER_SET.req with
@@ -216,8 +191,7 @@
         leader_messages = self.simulator.get_messages_sent_by(LEADER)
         msg = leader_messages.next_coap_message('2.04')
         command.check_coap_message(
-            msg, [mesh_cop.State(mesh_cop.MeshCopState.ACCEPT)]
-        )
+            msg, [mesh_cop.State(mesh_cop.MeshCopState.ACCEPT)])
 
         # Step 15 - Send ICMPv6 Echo Request to Leader
         leader_rloc = self.nodes[LEADER].get_rloc()
diff --git a/tests/scripts/thread-cert/Cert_9_2_04_ActiveDataset.py b/tests/scripts/thread-cert/Cert_9_2_04_ActiveDataset.py
index 1351e53..d831c6d 100755
--- a/tests/scripts/thread-cert/Cert_9_2_04_ActiveDataset.py
+++ b/tests/scripts/thread-cert/Cert_9_2_04_ActiveDataset.py
@@ -29,38 +29,35 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 COMMISSIONER = 1
 LEADER = 2
 
 
-class Cert_9_2_04_ActiveDataset(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_04_ActiveDataset(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(
-            10, panid=0xface, master_key='000102030405060708090a0b0c0d0e0f'
-        )
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_active_dataset(
-            10, panid=0xface, master_key='000102030405060708090a0b0c0d0e0f'
-        )
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': 0xface,
+                'master_key': '000102030405060708090a0b0c0d0e0f'
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+        LEADER: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': 0xface,
+                'master_key': '000102030405060708090a0b0c0d0e0f'
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_9_2_07_DelayTimer.py b/tests/scripts/thread-cert/Cert_9_2_07_DelayTimer.py
index 585d113..8249e9d 100755
--- a/tests/scripts/thread-cert/Cert_9_2_07_DelayTimer.py
+++ b/tests/scripts/thread-cert/Cert_9_2_07_DelayTimer.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 PANID_INIT = 0xface
 
@@ -47,43 +46,40 @@
 COMMISSIONER_PENDING_PANID = 0xafce
 
 
-class Cert_9_2_7_DelayTimer(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_7_DelayTimer(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(LEADER_ACTIVE_TIMESTAMP)
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].set_panid(PANID_INIT)
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].set_panid(PANID_INIT)
-        self.nodes[LEADER].set_partition_id(0xffffffff)
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER].set_active_dataset(ROUTER_ACTIVE_TIMESTAMP)
-        self.nodes[ROUTER].set_pending_dataset(
-            ROUTER_PENDING_TIMESTAMP, ROUTER_PENDING_ACTIVE_TIMESTAMP
-        )
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].set_panid(PANID_INIT)
-        self.nodes[ROUTER].set_partition_id(0x1)
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': LEADER_ACTIVE_TIMESTAMP
+            },
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'partition_id': 0xffffffff,
+            'router_selection_jitter': 1,
+            'whitelist': [COMMISSIONER]
+        },
+        ROUTER: {
+            'active_dataset': {
+                'timestamp': ROUTER_ACTIVE_TIMESTAMP
+            },
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'partition_id': 1,
+            'pending_dataset': {
+                'pendingtimestamp': ROUTER_PENDING_TIMESTAMP,
+                'activetimestamp': ROUTER_PENDING_ACTIVE_TIMESTAMP
+            },
+            'router_selection_jitter': 1
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -122,26 +118,21 @@
             panid=COMMISSIONER_PENDING_PANID,
         )
         self.simulator.go(40)
-        self.assertEqual(
-            self.nodes[LEADER].get_panid(), COMMISSIONER_PENDING_PANID
-        )
-        self.assertEqual(
-            self.nodes[COMMISSIONER].get_panid(), COMMISSIONER_PENDING_PANID
-        )
-        self.assertEqual(
-            self.nodes[ROUTER].get_panid(), COMMISSIONER_PENDING_PANID
-        )
+        self.assertEqual(self.nodes[LEADER].get_panid(),
+                         COMMISSIONER_PENDING_PANID)
+        self.assertEqual(self.nodes[COMMISSIONER].get_panid(),
+                         COMMISSIONER_PENDING_PANID)
+        self.assertEqual(self.nodes[ROUTER].get_panid(),
+                         COMMISSIONER_PENDING_PANID)
 
-        self.assertEqual(
-            self.nodes[LEADER].get_channel(), COMMISSIONER_PENDING_CHANNEL
-        )
+        self.assertEqual(self.nodes[LEADER].get_channel(),
+                         COMMISSIONER_PENDING_CHANNEL)
         self.assertEqual(
             self.nodes[COMMISSIONER].get_channel(),
             COMMISSIONER_PENDING_CHANNEL,
         )
-        self.assertEqual(
-            self.nodes[ROUTER].get_channel(), COMMISSIONER_PENDING_CHANNEL
-        )
+        self.assertEqual(self.nodes[ROUTER].get_channel(),
+                         COMMISSIONER_PENDING_CHANNEL)
 
         ipaddrs = self.nodes[ROUTER].get_addrs()
         for ipaddr in ipaddrs:
diff --git a/tests/scripts/thread-cert/Cert_9_2_08_PersistentDatasets.py b/tests/scripts/thread-cert/Cert_9_2_08_PersistentDatasets.py
index b6b1b2a..a4730fc 100755
--- a/tests/scripts/thread-cert/Cert_9_2_08_PersistentDatasets.py
+++ b/tests/scripts/thread-cert/Cert_9_2_08_PersistentDatasets.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 COMMISSIONER = 1
 LEADER = 2
@@ -48,47 +48,56 @@
 MTDS = [ED, SED]
 
 
-class Cert_9_2_8_PersistentDatasets(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_8_PersistentDatasets(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(
-            LEADER_ACTIVE_TIMESTAMP, panid=PANID_INIT, channel=CHANNEL_INIT
-        )
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_active_dataset(
-            LEADER_ACTIVE_TIMESTAMP, panid=PANID_INIT, channel=CHANNEL_INIT
-        )
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[SED].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_active_dataset(
-            LEADER_ACTIVE_TIMESTAMP, panid=PANID_INIT, channel=CHANNEL_INIT
-        )
-        self.nodes[ROUTER].set_mode('rsdn')
-        self._setUpRouter()
-
-        self.nodes[ED].set_channel(CHANNEL_INIT)
-        self.nodes[ED].set_panid(PANID_INIT)
-        self.nodes[ED].set_mode('rsn')
-        self._setUpEd()
-
-        self.nodes[SED].set_channel(CHANNEL_INIT)
-        self.nodes[SED].set_panid(PANID_INIT)
-        self.nodes[SED].set_mode('s')
-        self._setUpSed()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': LEADER_ACTIVE_TIMESTAMP,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'active_dataset': {
+                'timestamp': LEADER_ACTIVE_TIMESTAMP,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'whitelist': [COMMISSIONER, ROUTER, ED, SED]
+        },
+        ROUTER: {
+            'active_dataset': {
+                'timestamp': LEADER_ACTIVE_TIMESTAMP,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        ED: {
+            'channel': CHANNEL_INIT,
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': PANID_INIT,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [LEADER]
+        },
+        SED: {
+            'channel': CHANNEL_INIT,
+            'is_mtd': True,
+            'mode': 's',
+            'panid': PANID_INIT,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [LEADER]
+        },
+    }
 
     def _setUpRouter(self):
         self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
@@ -105,11 +114,6 @@
         self.nodes[SED].enable_whitelist()
         self.nodes[SED].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
@@ -149,16 +153,13 @@
 
         self.simulator.go(60)
 
-        self.assertEqual(
-            self.nodes[LEADER].get_panid(), COMMISSIONER_PENDING_PANID
-        )
-        self.assertEqual(
-            self.nodes[COMMISSIONER].get_panid(), COMMISSIONER_PENDING_PANID
-        )
+        self.assertEqual(self.nodes[LEADER].get_panid(),
+                         COMMISSIONER_PENDING_PANID)
+        self.assertEqual(self.nodes[COMMISSIONER].get_panid(),
+                         COMMISSIONER_PENDING_PANID)
 
-        self.assertEqual(
-            self.nodes[LEADER].get_channel(), COMMISSIONER_PENDING_CHANNEL
-        )
+        self.assertEqual(self.nodes[LEADER].get_channel(),
+                         COMMISSIONER_PENDING_CHANNEL)
         self.assertEqual(
             self.nodes[COMMISSIONER].get_channel(),
             COMMISSIONER_PENDING_CHANNEL,
@@ -186,25 +187,18 @@
 
         self.simulator.go(10)
 
-        self.assertEqual(
-            self.nodes[ROUTER].get_panid(), COMMISSIONER_PENDING_PANID
-        )
-        self.assertEqual(
-            self.nodes[ED].get_panid(), COMMISSIONER_PENDING_PANID
-        )
-        self.assertEqual(
-            self.nodes[SED].get_panid(), COMMISSIONER_PENDING_PANID
-        )
+        self.assertEqual(self.nodes[ROUTER].get_panid(),
+                         COMMISSIONER_PENDING_PANID)
+        self.assertEqual(self.nodes[ED].get_panid(), COMMISSIONER_PENDING_PANID)
+        self.assertEqual(self.nodes[SED].get_panid(),
+                         COMMISSIONER_PENDING_PANID)
 
-        self.assertEqual(
-            self.nodes[ROUTER].get_channel(), COMMISSIONER_PENDING_CHANNEL
-        )
-        self.assertEqual(
-            self.nodes[ED].get_channel(), COMMISSIONER_PENDING_CHANNEL
-        )
-        self.assertEqual(
-            self.nodes[SED].get_channel(), COMMISSIONER_PENDING_CHANNEL
-        )
+        self.assertEqual(self.nodes[ROUTER].get_channel(),
+                         COMMISSIONER_PENDING_CHANNEL)
+        self.assertEqual(self.nodes[ED].get_channel(),
+                         COMMISSIONER_PENDING_CHANNEL)
+        self.assertEqual(self.nodes[SED].get_channel(),
+                         COMMISSIONER_PENDING_CHANNEL)
 
         self.simulator.go(5)
 
diff --git a/tests/scripts/thread-cert/Cert_9_2_09_PendingPartition.py b/tests/scripts/thread-cert/Cert_9_2_09_PendingPartition.py
index 53db38a..b8706e1 100755
--- a/tests/scripts/thread-cert/Cert_9_2_09_PendingPartition.py
+++ b/tests/scripts/thread-cert/Cert_9_2_09_PendingPartition.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 CHANNEL_INIT = 19
 PANID_INIT = 0xface
@@ -44,55 +43,53 @@
 ROUTER2 = 4
 
 
-class Cert_9_2_09_PendingPartition(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_09_PendingPartition(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(
-            10, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_active_dataset(
-            10, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].set_partition_id(0xffffffff)
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_active_dataset(
-            10, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_active_dataset(
-            10, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-        self.nodes[ROUTER2].set_network_id_timeout(100)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'partition_id': 0xffffffff,
+            'router_selection_jitter': 1,
+            'whitelist': [COMMISSIONER, ROUTER1]
+        },
+        ROUTER1: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'network_id_timeout': 100,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_9_2_10_PendingPartition.py b/tests/scripts/thread-cert/Cert_9_2_10_PendingPartition.py
index 42ed0f7..0ebeebe 100755
--- a/tests/scripts/thread-cert/Cert_9_2_10_PendingPartition.py
+++ b/tests/scripts/thread-cert/Cert_9_2_10_PendingPartition.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 CHANNEL_INIT = 19
 PANID_INIT = 0xface
@@ -47,60 +47,57 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_9_2_10_PendingPartition(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_10_PendingPartition(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(
-            15, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_active_dataset(
-            15, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].set_partition_id(0xffffffff)
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_active_dataset(
-            15, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_channel(CHANNEL_INIT)
-        self.nodes[ED1].set_panid(PANID_INIT)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_channel(CHANNEL_INIT)
-        self.nodes[SED1].set_panid(PANID_INIT)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': 15,
+                'panid': 0xface,
+                'channel': 19
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'active_dataset': {
+                'timestamp': 15,
+                'panid': 0xface,
+                'channel': 19
+            },
+            'mode': 'rsdn',
+            'partition_id': 0xffffffff,
+            'router_selection_jitter': 1,
+            'whitelist': [COMMISSIONER, ROUTER1]
+        },
+        ROUTER1: {
+            'active_dataset': {
+                'timestamp': 15,
+                'panid': 0xface,
+                'channel': 19
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1, SED1]
+        },
+        ED1: {
+            'channel': 19,
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        SED1: {
+            'channel': 19,
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_9_2_11_MasterKey.py b/tests/scripts/thread-cert/Cert_9_2_11_MasterKey.py
index 1947990..13cef03 100755
--- a/tests/scripts/thread-cert/Cert_9_2_11_MasterKey.py
+++ b/tests/scripts/thread-cert/Cert_9_2_11_MasterKey.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 KEY1 = '000102030405060708090a0b0c0d0e0f'
 KEY2 = '0f0e0d0c0b0a09080706050403020100'
@@ -47,61 +47,61 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_9_2_11_MasterKey(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_11_MasterKey(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(
-            10, channel=CHANNEL_INIT, panid=PANID_INIT, master_key=KEY1
-        )
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_active_dataset(
-            10, channel=CHANNEL_INIT, panid=PANID_INIT, master_key=KEY1
-        )
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_active_dataset(
-            10, channel=CHANNEL_INIT, panid=PANID_INIT, master_key=KEY1
-        )
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_channel(CHANNEL_INIT)
-        self.nodes[ED1].set_panid(PANID_INIT)
-        self.nodes[ED1].set_masterkey(KEY1)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_channel(CHANNEL_INIT)
-        self.nodes[SED1].set_panid(PANID_INIT)
-        self.nodes[SED1].set_masterkey(KEY1)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT,
+                'master_key': '000102030405060708090a0b0c0d0e0f'
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT,
+                'master_key': '000102030405060708090a0b0c0d0e0f'
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [COMMISSIONER, ROUTER1]
+        },
+        ROUTER1: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT,
+                'master_key': '000102030405060708090a0b0c0d0e0f'
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1, SED1]
+        },
+        ED1: {
+            'channel': CHANNEL_INIT,
+            'is_mtd': True,
+            'masterkey': '000102030405060708090a0b0c0d0e0f',
+            'mode': 'rsn',
+            'panid': PANID_INIT,
+            'whitelist': [ROUTER1]
+        },
+        SED1: {
+            'channel': CHANNEL_INIT,
+            'is_mtd': True,
+            'masterkey': '000102030405060708090a0b0c0d0e0f',
+            'mode': 's',
+            'panid': PANID_INIT,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/Cert_9_2_12_Announce.py b/tests/scripts/thread-cert/Cert_9_2_12_Announce.py
index 4f6485d..be2e522 100755
--- a/tests/scripts/thread-cert/Cert_9_2_12_Announce.py
+++ b/tests/scripts/thread-cert/Cert_9_2_12_Announce.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 LEADER1 = 1
 ROUTER1 = 2
@@ -47,59 +46,57 @@
 DATASET2_PANID = 0xafce
 
 
-class Cert_9_2_12_Announce(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_12_Announce(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 6):
-            self.nodes[i] = node.Node(i, (i == MED), simulator=self.simulator)
-
-        self.nodes[LEADER1].set_active_dataset(
-            DATASET1_TIMESTAMP, channel=DATASET1_CHANNEL, panid=DATASET1_PANID
-        )
-        self.nodes[LEADER1].set_mode('rsdn')
-        self.nodes[LEADER1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER1].enable_whitelist()
-
-        self.nodes[ROUTER1].set_active_dataset(
-            DATASET1_TIMESTAMP, channel=DATASET1_CHANNEL, panid=DATASET1_PANID
-        )
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER1].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[LEADER2].set_active_dataset(
-            DATASET2_TIMESTAMP, channel=DATASET2_CHANNEL, panid=DATASET2_PANID
-        )
-        self.nodes[LEADER2].set_mode('rsdn')
-        self.nodes[LEADER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER2].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER2].enable_whitelist()
-        self.nodes[LEADER2].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_active_dataset(
-            DATASET2_TIMESTAMP, channel=DATASET2_CHANNEL, panid=DATASET2_PANID
-        )
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER2].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[MED].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[MED].set_channel(DATASET2_CHANNEL)
-        self.nodes[MED].set_panid(DATASET2_PANID)
-        self.nodes[MED].set_mode('rsn')
-        self.nodes[MED].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[MED].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        LEADER1: {
+            'active_dataset': {
+                'timestamp': DATASET1_TIMESTAMP,
+                'panid': DATASET1_PANID,
+                'channel': DATASET1_CHANNEL
+            },
+            'mode': 'rsdn',
+            'whitelist': [ROUTER1]
+        },
+        ROUTER1: {
+            'active_dataset': {
+                'timestamp': DATASET1_TIMESTAMP,
+                'panid': DATASET1_PANID,
+                'channel': DATASET1_CHANNEL
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER1, LEADER2]
+        },
+        LEADER2: {
+            'active_dataset': {
+                'timestamp': DATASET2_TIMESTAMP,
+                'panid': DATASET2_PANID,
+                'channel': DATASET2_CHANNEL
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER2: {
+            'active_dataset': {
+                'timestamp': DATASET2_TIMESTAMP,
+                'panid': DATASET2_PANID,
+                'channel': DATASET2_CHANNEL
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER2, MED]
+        },
+        MED: {
+            'channel': DATASET2_CHANNEL,
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': DATASET2_PANID,
+            'whitelist': [ROUTER2]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER1].start()
diff --git a/tests/scripts/thread-cert/Cert_9_2_13_EnergyScan.py b/tests/scripts/thread-cert/Cert_9_2_13_EnergyScan.py
index 8fe47a8..8c770cb 100755
--- a/tests/scripts/thread-cert/Cert_9_2_13_EnergyScan.py
+++ b/tests/scripts/thread-cert/Cert_9_2_13_EnergyScan.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 COMMISSIONER = 1
 LEADER = 2
@@ -38,43 +37,34 @@
 ED1 = 4
 
 
-class Cert_9_2_13_EnergyScan(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_13_EnergyScan(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, (i == ED1), simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_panid(0xface)
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_panid(0xface)
-        self.nodes[ED1].set_mode('rs')
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [COMMISSIONER, ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rs',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -101,9 +91,7 @@
                 break
 
         self.assertTrue(self.nodes[COMMISSIONER].ping(ipaddr))
-        self.nodes[COMMISSIONER].energy_scan(
-            0x50000, 0x02, 0x20, 0x3E8, ipaddr
-        )
+        self.nodes[COMMISSIONER].energy_scan(0x50000, 0x02, 0x20, 0x3E8, ipaddr)
 
         ipaddrs = self.nodes[ED1].get_addrs()
         for ipaddr in ipaddrs:
@@ -111,13 +99,10 @@
                 break
 
         self.assertTrue(self.nodes[COMMISSIONER].ping(ipaddr))
-        self.nodes[COMMISSIONER].energy_scan(
-            0x50000, 0x02, 0x20, 0x3E8, ipaddr
-        )
+        self.nodes[COMMISSIONER].energy_scan(0x50000, 0x02, 0x20, 0x3E8, ipaddr)
 
-        self.nodes[COMMISSIONER].energy_scan(
-            0x50000, 0x02, 0x20, 0x3E8, 'ff33:0040:fdde:ad00:beef:0:0:1'
-        )
+        self.nodes[COMMISSIONER].energy_scan(0x50000, 0x02, 0x20, 0x3E8,
+                                             'ff33:0040:fd00:db8:0:0:0:1')
 
         self.assertTrue(self.nodes[COMMISSIONER].ping(ipaddr))
 
diff --git a/tests/scripts/thread-cert/Cert_9_2_14_PanIdQuery.py b/tests/scripts/thread-cert/Cert_9_2_14_PanIdQuery.py
index 3cda814..906a606 100755
--- a/tests/scripts/thread-cert/Cert_9_2_14_PanIdQuery.py
+++ b/tests/scripts/thread-cert/Cert_9_2_14_PanIdQuery.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 COMMISSIONER = 1
 LEADER1 = 2
@@ -38,47 +37,33 @@
 LEADER2 = 4
 
 
-class Cert_9_2_14_PanIdQuery(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_14_PanIdQuery(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_panid(0xface)
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(
-            self.nodes[LEADER1].get_addr64()
-        )
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER1].set_panid(0xface)
-        self.nodes[LEADER1].set_mode('rsdn')
-        self.nodes[LEADER1].add_whitelist(
-            self.nodes[COMMISSIONER].get_addr64()
-        )
-        self.nodes[LEADER1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER1].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER1].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[LEADER2].set_panid(0xdead)
-        self.nodes[LEADER2].set_mode('rsdn')
-        self.nodes[LEADER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER2].enable_whitelist()
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER1]
+        },
+        LEADER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [COMMISSIONER, ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER1, LEADER2]
+        },
+        LEADER2: {
+            'mode': 'rsdn',
+            'panid': 0xdead,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER1].start()
@@ -106,9 +91,8 @@
 
         self.nodes[COMMISSIONER].panid_query(0xdead, 0xffffffff, ipaddr)
 
-        self.nodes[COMMISSIONER].panid_query(
-            0xdead, 0xffffffff, 'ff33:0040:fdde:ad00:beef:0:0:1'
-        )
+        self.nodes[COMMISSIONER].panid_query(0xdead, 0xffffffff,
+                                             'ff33:0040:fd00:db8:0:0:0:1')
 
         self.assertTrue(self.nodes[COMMISSIONER].ping(ipaddr))
 
diff --git a/tests/scripts/thread-cert/Cert_9_2_15_PendingPartition.py b/tests/scripts/thread-cert/Cert_9_2_15_PendingPartition.py
index 03c9b99..7be9875 100755
--- a/tests/scripts/thread-cert/Cert_9_2_15_PendingPartition.py
+++ b/tests/scripts/thread-cert/Cert_9_2_15_PendingPartition.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 CHANNEL_INIT = 19
 PANID_INIT = 0xface
@@ -43,58 +42,58 @@
 ROUTER2 = 4
 
 
-class Cert_9_2_15_PendingPartition(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_15_PendingPartition(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(
-            15, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_active_dataset(
-            15, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].set_partition_id(0xffffffff)
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_active_dataset(
-            15, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_active_dataset(
-            15, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self._setUpRouter2()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': 15,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'active_dataset': {
+                'timestamp': 15,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'partition_id': 0xffffffff,
+            'router_selection_jitter': 1,
+            'whitelist': [COMMISSIONER, ROUTER1]
+        },
+        ROUTER1: {
+            'active_dataset': {
+                'timestamp': 15,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'active_dataset': {
+                'timestamp': 15,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def _setUpRouter2(self):
         self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
         self.nodes[ROUTER2].enable_whitelist()
         self.nodes[ROUTER2].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
diff --git a/tests/scripts/thread-cert/Cert_9_2_16_ActivePendingPartition.py b/tests/scripts/thread-cert/Cert_9_2_16_ActivePendingPartition.py
index 725928a..ee3df39 100755
--- a/tests/scripts/thread-cert/Cert_9_2_16_ActivePendingPartition.py
+++ b/tests/scripts/thread-cert/Cert_9_2_16_ActivePendingPartition.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import config
-import node
+import thread_cert
 
 CHANNEL_INIT = 19
 PANID_INIT = 0xface
@@ -44,58 +43,58 @@
 ROUTER2 = 4
 
 
-class Cert_9_2_16_ActivePendingPartition(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_16_ActivePendingPartition(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 5):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(
-            1, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_active_dataset(
-            1, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].set_partition_id(0xffffffff)
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_active_dataset(
-            1, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_active_dataset(
-            1, channel=CHANNEL_INIT, panid=PANID_INIT
-        )
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self._setUpRouter2()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': 1,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'active_dataset': {
+                'timestamp': 1,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'partition_id': 0xffffffff,
+            'router_selection_jitter': 1,
+            'whitelist': [COMMISSIONER, ROUTER1]
+        },
+        ROUTER1: {
+            'active_dataset': {
+                'timestamp': 1,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'active_dataset': {
+                'timestamp': 1,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def _setUpRouter2(self):
         self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
         self.nodes[ROUTER2].enable_whitelist()
         self.nodes[ROUTER2].set_router_selection_jitter(1)
 
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
-
     def test(self):
         self.nodes[LEADER].start()
         self.simulator.go(5)
@@ -135,27 +134,22 @@
         )
         self.simulator.go(5)
 
-        self.nodes[COMMISSIONER].send_mgmt_active_set(
-            active_timestamp=15, network_name='threadCert'
-        )
+        self.nodes[COMMISSIONER].send_mgmt_active_set(active_timestamp=15,
+                                                      network_name='threadCert')
         self.simulator.go(100)
 
         self.nodes[ROUTER2].start()
         self.simulator.go(5)
         self.assertEqual(self.nodes[ROUTER2].get_state(), 'router')
 
-        self.assertEqual(
-            self.nodes[COMMISSIONER].get_network_name(), NETWORK_NAME_FINAL
-        )
-        self.assertEqual(
-            self.nodes[LEADER].get_network_name(), NETWORK_NAME_FINAL
-        )
-        self.assertEqual(
-            self.nodes[ROUTER1].get_network_name(), NETWORK_NAME_FINAL
-        )
-        self.assertEqual(
-            self.nodes[ROUTER2].get_network_name(), NETWORK_NAME_FINAL
-        )
+        self.assertEqual(self.nodes[COMMISSIONER].get_network_name(),
+                         NETWORK_NAME_FINAL)
+        self.assertEqual(self.nodes[LEADER].get_network_name(),
+                         NETWORK_NAME_FINAL)
+        self.assertEqual(self.nodes[ROUTER1].get_network_name(),
+                         NETWORK_NAME_FINAL)
+        self.assertEqual(self.nodes[ROUTER2].get_network_name(),
+                         NETWORK_NAME_FINAL)
 
         self.simulator.go(100)
 
diff --git a/tests/scripts/thread-cert/Cert_9_2_17_Orphan.py b/tests/scripts/thread-cert/Cert_9_2_17_Orphan.py
index 2e9cbed..ac1bd18 100755
--- a/tests/scripts/thread-cert/Cert_9_2_17_Orphan.py
+++ b/tests/scripts/thread-cert/Cert_9_2_17_Orphan.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 CHANNEL1 = 11
 CHANNEL2 = 18
@@ -42,41 +42,40 @@
 ED1 = 3
 
 
-class Cert_9_2_17_Orphan(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_17_Orphan(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, (i == ED1), simulator=self.simulator)
-
-        self.nodes[LEADER1].set_active_dataset(
-            10, channel=CHANNEL1, panid=PANID_INIT, channel_mask=CHANNEL_MASK
-        )
-        self.nodes[LEADER1].set_mode('rsdn')
-        self.nodes[LEADER1].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[LEADER1].enable_whitelist()
-        self.nodes[LEADER1].set_router_selection_jitter(1)
-
-        self.nodes[LEADER2].set_active_dataset(
-            20, channel=CHANNEL2, panid=PANID_INIT, channel_mask=CHANNEL_MASK
-        )
-        self.nodes[LEADER2].set_mode('rsdn')
-        self.nodes[LEADER2].enable_whitelist()
-        self.nodes[LEADER2].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_channel(CHANNEL1)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].set_panid(PANID_INIT)
-        self.nodes[ED1].add_whitelist(self.nodes[LEADER1].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-        self.nodes[ED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        LEADER1: {
+            'active_dataset': {
+                'timestamp': 10,
+                'panid': PANID_INIT,
+                'channel': CHANNEL1,
+                'channel_mask': CHANNEL_MASK
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [ED1]
+        },
+        LEADER2: {
+            'active_dataset': {
+                'timestamp': 20,
+                'panid': PANID_INIT,
+                'channel': CHANNEL2,
+                'channel_mask': CHANNEL_MASK
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1
+        },
+        ED1: {
+            'channel': CHANNEL1,
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': PANID_INIT,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [LEADER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER1].start()
diff --git a/tests/scripts/thread-cert/Cert_9_2_18_RollBackActiveTimestamp.py b/tests/scripts/thread-cert/Cert_9_2_18_RollBackActiveTimestamp.py
index 3a8fc7d..8e97452 100755
--- a/tests/scripts/thread-cert/Cert_9_2_18_RollBackActiveTimestamp.py
+++ b/tests/scripts/thread-cert/Cert_9_2_18_RollBackActiveTimestamp.py
@@ -30,7 +30,7 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 KEY1 = '00112233445566778899aabbccddeeff'
 KEY2 = 'ffeeddccbbaa99887766554433221100'
@@ -48,70 +48,73 @@
 MTDS = [ED1, SED1]
 
 
-class Cert_9_2_18_RollBackActiveTimestamp(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Cert_9_2_18_RollBackActiveTimestamp(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 7):
-            self.nodes[i] = node.Node(i, (i in MTDS), simulator=self.simulator)
-
-        self.nodes[COMMISSIONER].set_active_dataset(
-            1, channel=CHANNEL_INIT, panid=PANID_INIT, master_key=KEY1
-        )
-        self.nodes[COMMISSIONER].set_mode('rsdn')
-        self.nodes[COMMISSIONER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[COMMISSIONER].enable_whitelist()
-        self.nodes[COMMISSIONER].set_router_selection_jitter(1)
-
-        self.nodes[LEADER].set_active_dataset(
-            1, channel=CHANNEL_INIT, panid=PANID_INIT, master_key=KEY1
-        )
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].set_partition_id(0xffffffff)
-        self.nodes[LEADER].add_whitelist(self.nodes[COMMISSIONER].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER1].set_active_dataset(
-            1, channel=CHANNEL_INIT, panid=PANID_INIT, master_key=KEY1
-        )
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ED1].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[SED1].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_active_dataset(
-            1, channel=CHANNEL_INIT, panid=PANID_INIT, master_key=KEY1
-        )
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-        self.nodes[ED1].set_channel(CHANNEL_INIT)
-        self.nodes[ED1].set_masterkey(KEY1)
-        self.nodes[ED1].set_mode('rsn')
-        self.nodes[ED1].set_panid(PANID_INIT)
-        self.nodes[ED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ED1].enable_whitelist()
-
-        self.nodes[SED1].set_channel(CHANNEL_INIT)
-        self.nodes[SED1].set_masterkey(KEY1)
-        self.nodes[SED1].set_mode('s')
-        self.nodes[SED1].set_panid(PANID_INIT)
-        self.nodes[SED1].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[SED1].enable_whitelist()
-        self.nodes[SED1].set_timeout(config.DEFAULT_CHILD_TIMEOUT)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
+    TOPOLOGY = {
+        COMMISSIONER: {
+            'active_dataset': {
+                'timestamp': 1,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT,
+                'master_key': '00112233445566778899aabbccddeeff'
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+        LEADER: {
+            'active_dataset': {
+                'timestamp': 1,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT,
+                'master_key': '00112233445566778899aabbccddeeff'
+            },
+            'mode': 'rsdn',
+            'partition_id': 0xffffffff,
+            'router_selection_jitter': 1,
+            'whitelist': [COMMISSIONER, ROUTER1]
+        },
+        ROUTER1: {
+            'active_dataset': {
+                'timestamp': 1,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT,
+                'master_key': '00112233445566778899aabbccddeeff'
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2, ED1, SED1]
+        },
+        ROUTER2: {
+            'active_dataset': {
+                'timestamp': 1,
+                'panid': PANID_INIT,
+                'channel': CHANNEL_INIT,
+                'master_key': '00112233445566778899aabbccddeeff'
+            },
+            'mode': 'rsdn',
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+        ED1: {
+            'channel': CHANNEL_INIT,
+            'is_mtd': True,
+            'masterkey': '00112233445566778899aabbccddeeff',
+            'mode': 'rsn',
+            'panid': PANID_INIT,
+            'whitelist': [ROUTER1]
+        },
+        SED1: {
+            'channel': CHANNEL_INIT,
+            'is_mtd': True,
+            'masterkey': '00112233445566778899aabbccddeeff',
+            'mode': 's',
+            'panid': PANID_INIT,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -136,9 +139,8 @@
         self.simulator.go(5)
         self.assertEqual(self.nodes[SED1].get_state(), 'child')
 
-        self.nodes[COMMISSIONER].send_mgmt_active_set(
-            active_timestamp=20000, network_name='GRL'
-        )
+        self.nodes[COMMISSIONER].send_mgmt_active_set(active_timestamp=20000,
+                                                      network_name='GRL')
         self.simulator.go(5)
 
         self.nodes[COMMISSIONER].send_mgmt_pending_set(
diff --git a/tests/scripts/thread-cert/Makefile.am b/tests/scripts/thread-cert/Makefile.am
index 72db53f..bf923fd 100644
--- a/tests/scripts/thread-cert/Makefile.am
+++ b/tests/scripts/thread-cert/Makefile.am
@@ -68,7 +68,6 @@
     Cert_5_5_04_SplitMergeRouters.py                                 \
     Cert_5_5_05_SplitMergeREED.py                                    \
     Cert_5_5_07_SplitMergeThreeWay.py                                \
-    Cert_5_5_08_SplitRoutersLostLeader.py                            \
     Cert_5_6_01_NetworkDataRegisterBeforeAttachLeader.py             \
     Cert_5_6_02_NetworkDataRegisterBeforeAttachRouter.py             \
     Cert_5_6_03_NetworkDataRegisterAfterAttachLeader.py              \
@@ -76,9 +75,8 @@
     Cert_5_6_05_NetworkDataRegisterAfterAttachRouter.py              \
     Cert_5_6_06_NetworkDataExpiration.py                             \
     Cert_5_6_07_NetworkDataRequestREED.py                            \
-    Cert_5_6_08_ContextManagement.py                                 \
     Cert_5_6_09_NetworkDataForwarding.py                             \
-    Cert_5_8_01_KeySynchronization.py                                \
+    Cert_5_7_01_CoapDiagCommands_A.py                                \
     Cert_5_8_02_KeyIncrement.py                                      \
     Cert_5_8_03_KeyIncrementRollOver.py                              \
     Cert_6_1_01_RouterAttach.py                                      \
@@ -127,6 +125,7 @@
     command.py                                                       \
     common.py                                                        \
     config.py                                                        \
+    debug.py                                                         \
     dtls.py                                                          \
     ipv6.py                                                          \
     lowpan.py                                                        \
@@ -136,6 +135,7 @@
     mle.py                                                           \
     net_crypto.py                                                    \
     network_data.py                                                  \
+    network_diag.py                                                  \
     network_layer.py                                                 \
     node.py                                                          \
     pcap.py                                                          \
@@ -143,6 +143,7 @@
     sniffer.py                                                       \
     sniffer_transport.py                                             \
     test_coap.py                                                     \
+    test_coap_observe.py                                             \
     test_coaps.py                                                    \
     test_common.py                                                   \
     test_crypto.py                                                   \
@@ -153,9 +154,12 @@
     test_lowpan.py                                                   \
     test_mac802154.py                                                \
     test_mle.py                                                      \
-    test_service.py                                                  \
     test_network_data.py                                             \
     test_network_layer.py                                            \
+    test_reed_address_solicit_rejected.py                            \
+    test_reset.py                                                    \
+    test_service.py                                                  \
+    thread_cert.py                                                   \
     tlvs_parsing.py                                                  \
     $(NULL)
 
@@ -164,6 +168,7 @@
 
 check_SCRIPTS                                                      = \
     test_coap.py                                                     \
+    test_coap_observe.py                                             \
     test_coaps.py                                                    \
     test_common.py                                                   \
     test_crypto.py                                                   \
@@ -174,9 +179,11 @@
     test_lowpan.py                                                   \
     test_mac802154.py                                                \
     test_mle.py                                                      \
-    test_service.py                                                  \
     test_network_data.py                                             \
     test_network_layer.py                                            \
+    test_reed_address_solicit_rejected.py                            \
+    test_reset.py                                                    \
+    test_service.py                                                  \
     Cert_5_1_01_RouterAttach.py                                      \
     Cert_5_1_02_ChildAddressTimeout.py                               \
     Cert_5_1_03_RouterAddressReallocation.py                         \
@@ -213,7 +220,6 @@
     Cert_5_5_04_SplitMergeRouters.py                                 \
     Cert_5_5_05_SplitMergeREED.py                                    \
     Cert_5_5_07_SplitMergeThreeWay.py                                \
-    Cert_5_5_08_SplitRoutersLostLeader.py                            \
     Cert_5_6_01_NetworkDataRegisterBeforeAttachLeader.py             \
     Cert_5_6_02_NetworkDataRegisterBeforeAttachRouter.py             \
     Cert_5_6_03_NetworkDataRegisterAfterAttachLeader.py              \
@@ -221,9 +227,8 @@
     Cert_5_6_05_NetworkDataRegisterAfterAttachRouter.py              \
     Cert_5_6_06_NetworkDataExpiration.py                             \
     Cert_5_6_07_NetworkDataRequestREED.py                            \
-    Cert_5_6_08_ContextManagement.py                                 \
     Cert_5_6_09_NetworkDataForwarding.py                             \
-    Cert_5_8_01_KeySynchronization.py                                \
+    Cert_5_7_01_CoapDiagCommands_A.py                                \
     Cert_5_8_02_KeyIncrement.py                                      \
     Cert_5_8_03_KeyIncrementRollOver.py                              \
     Cert_6_1_01_RouterAttach.py                                      \
@@ -282,33 +287,4 @@
     $(check_SCRIPTS)                                                 \
     $(NULL)
 
-XFAIL_NCP_TESTS                                                    = \
-    test_coaps.py                                                    \
-    test_diag.py                                                     \
-    test_ipv6_fragmentation.py                                       \
-    test_ipv6_source_selection.py                                    \
-    test_service.py                                                  \
-    Cert_5_3_10_AddressQuery.py                                      \
-    Cert_8_1_01_Commissioning.py                                     \
-    Cert_8_1_02_Commissioning.py                                     \
-    Cert_8_2_01_JoinerRouter.py                                      \
-    Cert_8_2_02_JoinerRouter.py                                      \
-    Cert_9_2_02_MGMTCommissionerSet.py                               \
-    Cert_9_2_04_ActiveDataset.py                                     \
-    Cert_9_2_07_DelayTimer.py                                        \
-    Cert_9_2_08_PersistentDatasets.py                                \
-    Cert_9_2_09_PendingPartition.py                                  \
-    Cert_9_2_10_PendingPartition.py                                  \
-    Cert_9_2_11_MasterKey.py                                         \
-    Cert_9_2_12_Announce.py                                          \
-    Cert_9_2_13_EnergyScan.py                                        \
-    Cert_9_2_14_PanIdQuery.py                                        \
-    Cert_9_2_15_PendingPartition.py                                  \
-    Cert_9_2_16_ActivePendingPartition.py                            \
-    Cert_9_2_17_Orphan.py                                            \
-    Cert_9_2_18_RollBackActiveTimestamp.py                           \
-    $(NULL)
-
-XFAIL_TESTS = $(if $(filter $(NODE_TYPE),ncp-sim),$(XFAIL_NCP_TESTS))
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/tests/scripts/thread-cert/README.md b/tests/scripts/thread-cert/README.md
index 2abb66f..69f156b 100644
--- a/tests/scripts/thread-cert/README.md
+++ b/tests/scripts/thread-cert/README.md
@@ -1,8 +1,6 @@
-OpenThread Certification Tests
-==============================
+# OpenThread Certification Tests
 
-Inspector
---------
+## Inspector
 
 Inspect nodes status by the following modification:
 
@@ -37,14 +35,15 @@
 ### CLI reference
 
 #### `#` mode
+
 This is selection mode. You may select the node to inspect here.
 
-- `list`      - list available nodes.
-- `exit`      - end inspecting, continue running test case.
-- \<number\>   - select the node with id \<number\>. This will result in entering `>`  mode.
+- `list` - list available nodes.
+- `exit` - end inspecting, continue running test case.
+- \<number\> - select the node with id \<number\>. This will result in entering `>` mode.
 
 #### `>` mode
+
 This is node mode. You may run OpenThread CLI here.
 
-* `exit`      - go back to `#` mode.
-
+- `exit` - go back to `#` mode.
diff --git a/tests/scripts/thread-cert/Test_Cli.py b/tests/scripts/thread-cert/Test_Cli.py
index cfe688e..9fb45c5 100755
--- a/tests/scripts/thread-cert/Test_Cli.py
+++ b/tests/scripts/thread-cert/Test_Cli.py
@@ -29,20 +29,15 @@
 
 import unittest
 
-import node
+import thread_cert
 
 LEADER = 1
 
 
-class Cert_Cli(unittest.TestCase):
-    def setUp(self):
-        self.nodes = {}
-        self.nodes[LEADER] = node.Node(LEADER)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
+class Cert_Cli(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {},
+    }
 
     def test(self):
         commands = self.nodes[LEADER].get_commands()
diff --git a/tests/scripts/thread-cert/Test_MacScan.py b/tests/scripts/thread-cert/Test_MacScan.py
index 04ccce3..8595d32 100755
--- a/tests/scripts/thread-cert/Test_MacScan.py
+++ b/tests/scripts/thread-cert/Test_MacScan.py
@@ -30,36 +30,29 @@
 import time
 import unittest
 
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 
 
-class Test_MacScan(unittest.TestCase):
-    def setUp(self):
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_channel(12)
-        self.nodes[LEADER].set_network_name('OpenThread')
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_channel(12)
-        self.nodes[ROUTER].set_network_name('OpenThread')
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
+class Test_MacScan(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'channel': 12,
+            'mode': 'rsdn',
+            'network_name': 'OpenThread',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'channel': 12,
+            'mode': 'rsdn',
+            'network_name': 'OpenThread',
+            'panid': 0xface,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/coap.py b/tests/scripts/thread-cert/coap.py
index 68ec871..8e68490 100644
--- a/tests/scripts/thread-cert/coap.py
+++ b/tests/scripts/thread-cert/coap.py
@@ -61,7 +61,6 @@
 
 
 class CoapOptionHeader(object):
-
     """ Class representing CoAP optiona header. """
 
     def __init__(self, delta, length):
@@ -104,7 +103,6 @@
 
 
 class CoapOption(object):
-
     """ Class representing CoAP option. """
 
     def __init__(self, _type, value):
@@ -120,13 +118,11 @@
         return self._value
 
     def __repr__(self):
-        return "CoapOption(type={}, value={})".format(
-            self.type, hexlify(self.value)
-        )
+        return "CoapOption(type={}, value={})".format(self.type,
+                                                      hexlify(self.value))
 
 
 class CoapOptionsFactory(object):
-
     """ Factory that produces CoAP options. """
 
     def parse(self, data, message_info):
@@ -148,7 +144,6 @@
 
 
 class CoapCode(object):
-
     """ Class representing CoAP code. """
 
     def __init__(self, code):
@@ -182,8 +177,7 @@
     @property
     def dotted(self):
         return ".".join(
-            ["{:01d}".format(self._class), "{:02d}".format(self.detail)]
-        )
+            ["{:01d}".format(self._class), "{:02d}".format(self.detail)])
 
     def __eq__(self, other):
         if isinstance(other, int):
@@ -196,16 +190,14 @@
             return self.code == other.code
 
         else:
-            raise TypeError(
-                "Could not compare {} and {}".format(type(self), type(other))
-            )
+            raise TypeError("Could not compare {} and {}".format(
+                type(self), type(other)))
 
     def __repr__(self):
         return self.dotted
 
 
 class CoapMessage(object):
-
     """ Class representing CoAP message. """
 
     def __init__(
@@ -266,21 +258,21 @@
 
     def __repr__(self):
         options_str = ", ".join([repr(opt) for opt in self.options])
-        return ("CoapMessage(version={}, type={}, code={}, message_id={}, token={}, options=[{}], payload={},",
-                "uri-path='{}')").format(
-            self.version,
-            CoapMessageType.name[self.type],
-            self.code,
-            self.message_id,
-            hexlify(self.token),
-            options_str,
-            self.payload,
-            self.uri_path,
-        )
+        return (
+            "CoapMessage(version={}, type={}, code={}, message_id={}, token={}, options=[{}], payload={},",
+            "uri-path='{}')").format(
+                self.version,
+                CoapMessageType.name[self.type],
+                self.code,
+                self.message_id,
+                hexlify(self.token),
+                options_str,
+                self.payload,
+                self.uri_path,
+            )
 
 
 class CoapMessageProxy(object):
-
     """ Proxy class of CoAP message.
 
     The main idea behind this class is to delay parsing payload. Due to architecture of the existing solution
@@ -299,8 +291,7 @@
         self._message_info = message_info
         self._mid_to_uri_path_binder = mid_to_uri_path_binder
         self._uri_path_based_payload_factories = (
-            uri_path_based_payload_factories
-        )
+            uri_path_based_payload_factories)
 
     @property
     def version(self):
@@ -334,14 +325,12 @@
     def payload(self):
         try:
             binded_uri_path = self._mid_to_uri_path_binder.get_uri_path_for(
-                self.message_id, self.token
-            )
+                self.message_id, self.token)
 
             factory = self._uri_path_based_payload_factories[binded_uri_path]
 
-            return factory.parse(
-                io.BytesIO(self._coap_message.payload), self._message_info
-            )
+            return factory.parse(io.BytesIO(self._coap_message.payload),
+                                 self._message_info)
 
         except RuntimeError:
             return self._coap_message.payload
@@ -352,14 +341,21 @@
 
     def __repr__(self):
         options_str = ", ".join([repr(opt) for opt in self.options])
-        return ("CoapMessageProxy(version={}, type={}, code={}, message_id={}, token={}, options=[{}], payload={},",
-                "uri-path='{}')").format(
-            self.version, self.type, self.code, self.message_id, hexlify(self.token), options_str, self.payload,
-            self.uri_path, )
+        return (
+            "CoapMessageProxy(version={}, type={}, code={}, message_id={}, token={}, options=[{}], payload={},",
+            "uri-path='{}')").format(
+                self.version,
+                self.type,
+                self.code,
+                self.message_id,
+                hexlify(self.token),
+                options_str,
+                self.payload,
+                self.uri_path,
+            )
 
 
 class CoapMessageIdToUriPathBinder:
-
     """ Class binds message id and token with URI path. """
 
     def __init__(self):
@@ -373,12 +369,11 @@
             return self._uri_path_binds[message_id][hexlify(token)]
         except KeyError:
             raise RuntimeError(
-                "Could not find URI PATH for message_id: {} and token: {}".format(
-                    message_id, hexlify(token)))
+                "Could not find URI PATH for message_id: {} and token: {}".
+                format(message_id, hexlify(token)))
 
 
 class CoapMessageFactory(object):
-
     """ Factory that produces CoAP messages. """
 
     def __init__(
@@ -389,8 +384,7 @@
     ):
         self._options_factory = options_factory
         self._uri_path_based_payload_factories = (
-            uri_path_based_payload_factories
-        )
+            uri_path_based_payload_factories)
         self._mid_to_uri_path_binder = message_id_to_uri_path_binder
 
     def _uri_path_from(self, options):
@@ -416,8 +410,7 @@
 
     def parse(self, data, message_info):
         version, _type, token_length = self._parse_initial_byte(
-            data, message_info
-        )
+            data, message_info)
 
         code = CoapCode(ord(data.read(1)))
         message_id = struct.unpack(">H", data.read(2))[0]
@@ -428,8 +421,7 @@
         uri_path = self._uri_path_from(options)
         if uri_path is not None:
             self._mid_to_uri_path_binder.add_uri_path_for(
-                message_id, token, uri_path
-            )
+                message_id, token, uri_path)
 
         coap_message = CoapMessage(
             version,
diff --git a/tests/scripts/thread-cert/command.py b/tests/scripts/thread-cert/command.py
index bf32ad5..3d7fa9e 100644
--- a/tests/scripts/thread-cert/command.py
+++ b/tests/scripts/thread-cert/command.py
@@ -29,6 +29,7 @@
 
 import binascii
 
+import ipaddress
 import ipv6
 import network_data
 import network_layer
@@ -58,22 +59,19 @@
 
     source_rloc = source_node.get_ip6_address(config.ADDRESS_TYPE.RLOC)
     assert (
-        ipv6.ip_address(source_rloc)
-        == command_msg.ipv6_packet.ipv6_header.source_address
-    ), (
-        "Error: The IPv6 source address is not the RLOC of the originator. The source node's rloc is: "
-        + str(ipv6.ip_address(source_rloc))
-        + ", but the source_address in command msg is: "
-        + str(command_msg.ipv6_packet.ipv6_header.source_address)
-    )
+        ipv6.ip_address(
+            source_rloc) == command_msg.ipv6_packet.ipv6_header.source_address
+    ), ("Error: The IPv6 source address is not the RLOC of the originator. The source node's rloc is: "
+        + str(ipv6.ip_address(source_rloc)) +
+        ", but the source_address in command msg is: " +
+        str(command_msg.ipv6_packet.ipv6_header.source_address))
 
     if isinstance(destination_address, bytearray):
         destination_address = bytes(destination_address)
 
-    assert (
-        ipv6.ip_address(destination_address)
-        == command_msg.ipv6_packet.ipv6_header.destination_address
-    ), "Error: The IPv6 destination address is not expected."
+    assert (ipv6.ip_address(destination_address) ==
+            command_msg.ipv6_packet.ipv6_header.destination_address
+           ), "Error: The IPv6 destination address is not expected."
 
 
 def check_address_notification(command_msg, source_node, destination_node):
@@ -86,22 +84,20 @@
 
     source_rloc = source_node.get_ip6_address(config.ADDRESS_TYPE.RLOC)
     assert (
-        ipv6.ip_address(source_rloc)
-        == command_msg.ipv6_packet.ipv6_header.source_address
+        ipv6.ip_address(
+            source_rloc) == command_msg.ipv6_packet.ipv6_header.source_address
     ), "Error: The IPv6 source address is not the RLOC of the originator."
 
     destination_rloc = destination_node.get_ip6_address(
-        config.ADDRESS_TYPE.RLOC
-    )
+        config.ADDRESS_TYPE.RLOC)
     assert (
-        ipv6.ip_address(destination_rloc)
-        == command_msg.ipv6_packet.ipv6_header.destination_address
+        ipv6.ip_address(destination_rloc) ==
+        command_msg.ipv6_packet.ipv6_header.destination_address
     ), "Error: The IPv6 destination address is not the RLOC of the destination."
 
 
-def check_address_error_notification(
-    command_msg, source_node, destination_address
-):
+def check_address_error_notification(command_msg, source_node,
+                                     destination_address):
     """Verify source_node sent a properly formatted Address Error Notification command message to destination_address.
     """
     command_msg.assertCoapMessageRequestUriPath('/a/ae')
@@ -110,27 +106,23 @@
 
     source_rloc = source_node.get_ip6_address(config.ADDRESS_TYPE.RLOC)
     assert (
-        ipv6.ip_address(source_rloc)
-        == command_msg.ipv6_packet.ipv6_header.source_address
-    ), (
-        "Error: The IPv6 source address is not the RLOC of the originator. The source node's rloc is: "
-        + str(ipv6.ip_address(source_rloc))
-        + ", but the source_address in command msg is: "
-        + str(command_msg.ipv6_packet.ipv6_header.source_address)
-    )
+        ipv6.ip_address(
+            source_rloc) == command_msg.ipv6_packet.ipv6_header.source_address
+    ), ("Error: The IPv6 source address is not the RLOC of the originator. The source node's rloc is: "
+        + str(ipv6.ip_address(source_rloc)) +
+        ", but the source_address in command msg is: " +
+        str(command_msg.ipv6_packet.ipv6_header.source_address))
 
     if isinstance(destination_address, bytearray):
         destination_address = bytes(destination_address)
 
     assert (
-        ipv6.ip_address(destination_address)
-        == command_msg.ipv6_packet.ipv6_header.destination_address
-    ), (
-        "Error: The IPv6 destination address is not expected. The destination node's rloc is: "
-        + str(ipv6.ip_address(destination_address))
-        + ", but the destination_address in command msg is: "
-        + str(command_msg.ipv6_packet.ipv6_header.destination_address)
-    )
+        ipv6.ip_address(destination_address) ==
+        command_msg.ipv6_packet.ipv6_header.destination_address
+    ), ("Error: The IPv6 destination address is not expected. The destination node's rloc is: "
+        + str(ipv6.ip_address(destination_address)) +
+        ", but the destination_address in command msg is: " +
+        str(command_msg.ipv6_packet.ipv6_header.destination_address))
 
 
 def check_address_solicit(command_msg, was_router):
@@ -151,12 +143,10 @@
     command_msg.assertCoapMessageContainsTlv(network_layer.MacExtendedAddress)
 
     destination_rloc = destination_node.get_ip6_address(
-        config.ADDRESS_TYPE.RLOC
-    )
-    assert (
-        ipv6.ip_address(destination_rloc)
-        == command_msg.ipv6_packet.ipv6_header.destination_address
-    ), "Error: The destination is not RLOC address"
+        config.ADDRESS_TYPE.RLOC)
+    assert (ipv6.ip_address(destination_rloc) ==
+            command_msg.ipv6_packet.ipv6_header.destination_address
+           ), "Error: The destination is not RLOC address"
 
 
 def check_tlv_request_tlv(command_msg, check_type, tlv_id):
@@ -165,14 +155,12 @@
     tlv_request_tlv = command_msg.get_mle_message_tlv(mle.TlvRequest)
 
     if check_type == CheckType.CONTAIN:
-        assert (
-            tlv_request_tlv is not None
-        ), "Error: The msg doesn't contain TLV Request TLV"
+        assert (tlv_request_tlv is
+                not None), "Error: The msg doesn't contain TLV Request TLV"
         assert any(
             tlv_id == tlv for tlv in tlv_request_tlv.tlvs
         ), "Error: The msg doesn't contain TLV Request TLV ID: {}".format(
-            tlv_id
-        )
+            tlv_id)
 
     elif check_type == CheckType.NOT_CONTAIN:
         if tlv_request_tlv is not None:
@@ -186,8 +174,7 @@
                 print("TLV Request TLV contains TLV ID: {}".format(tlv_id))
             else:
                 print(
-                    "TLV Request TLV doesn't contain TLV ID: {}".format(tlv_id)
-                )
+                    "TLV Request TLV doesn't contain TLV ID: {}".format(tlv_id))
         else:
             print("The msg doesn't contain TLV Request TLV")
 
@@ -211,15 +198,11 @@
     check_mle_optional_tlv(command_msg, source_address, mle.SourceAddress)
     check_mle_optional_tlv(command_msg, leader_data, mle.LeaderData)
 
-    check_tlv_request_tlv(
-        command_msg, tlv_request_address16, mle.TlvType.ADDRESS16
-    )
-    check_tlv_request_tlv(
-        command_msg, tlv_request_route64, mle.TlvType.ROUTE64
-    )
-    check_tlv_request_tlv(
-        command_msg, tlv_request_link_margin, mle.TlvType.LINK_MARGIN
-    )
+    check_tlv_request_tlv(command_msg, tlv_request_address16,
+                          mle.TlvType.ADDRESS16)
+    check_tlv_request_tlv(command_msg, tlv_request_route64, mle.TlvType.ROUTE64)
+    check_tlv_request_tlv(command_msg, tlv_request_link_margin,
+                          mle.TlvType.LINK_MARGIN)
 
 
 def check_link_accept(
@@ -247,17 +230,14 @@
     check_mle_optional_tlv(command_msg, address16, mle.Address16)
     check_mle_optional_tlv(command_msg, route64, mle.Route64)
 
-    check_tlv_request_tlv(
-        command_msg, tlv_request_link_margin, mle.TlvType.LINK_MARGIN
-    )
+    check_tlv_request_tlv(command_msg, tlv_request_link_margin,
+                          mle.TlvType.LINK_MARGIN)
 
     destination_link_local = destination_node.get_ip6_address(
-        config.ADDRESS_TYPE.LINK_LOCAL
-    )
+        config.ADDRESS_TYPE.LINK_LOCAL)
     assert (
-        ipv6.ip_address(destination_link_local)
-        == command_msg.ipv6_packet.ipv6_header.destination_address
-    ), "Error: The destination is unexpected"
+        ipv6.ip_address(destination_link_local) == command_msg.ipv6_packet.
+        ipv6_header.destination_address), "Error: The destination is unexpected"
 
 
 def check_icmp_path(sniffer, path, nodes, icmp_type=ipv6.ICMP_ECHO_REQUEST):
@@ -273,9 +253,8 @@
         if i < len_path - 1:
             next_node = nodes[path[i + 1]]
             next_node_rloc16 = next_node.get_addr16()
-            assert (
-                next_node_rloc16 == node_icmp_msg.mac_header.dest_address.rloc
-            ), "Error: The path is unexpected."
+            assert (next_node_rloc16 == node_icmp_msg.mac_header.dest_address.
+                    rloc), "Error: The path is unexpected."
         else:
             return True
 
@@ -327,8 +306,7 @@
 def check_mle_advertisement(command_msg):
     command_msg.assertSentWithHopLimit(255)
     command_msg.assertSentToDestinationAddress(
-        config.LINK_LOCAL_ALL_NODES_ADDRESS
-    )
+        config.LINK_LOCAL_ALL_NODES_ADDRESS)
     command_msg.assertMleMessageContainsTlv(mle.SourceAddress)
     command_msg.assertMleMessageContainsTlv(mle.LeaderData)
     command_msg.assertMleMessageContainsTlv(mle.Route64)
@@ -344,8 +322,7 @@
 
     command_msg.assertSentWithHopLimit(255)
     command_msg.assertSentToDestinationAddress(
-        config.LINK_LOCAL_ALL_ROUTERS_ADDRESS
-    )
+        config.LINK_LOCAL_ALL_ROUTERS_ADDRESS)
     command_msg.assertMleMessageContainsTlv(mle.Mode)
     command_msg.assertMleMessageContainsTlv(mle.Challenge)
     command_msg.assertMleMessageContainsTlv(mle.Version)
@@ -398,21 +375,15 @@
 
     check_mle_optional_tlv(command_msg, tlv_request, mle.TlvRequest)
     check_mle_optional_tlv(command_msg, mle_frame_counter, mle.MleFrameCounter)
-    check_mle_optional_tlv(
-        command_msg, address_registration, mle.AddressRegistration
-    )
+    check_mle_optional_tlv(command_msg, address_registration,
+                           mle.AddressRegistration)
     check_mle_optional_tlv(command_msg, active_timestamp, mle.ActiveTimestamp)
-    check_mle_optional_tlv(
-        command_msg, pending_timestamp, mle.PendingTimestamp
-    )
+    check_mle_optional_tlv(command_msg, pending_timestamp, mle.PendingTimestamp)
     check_mle_optional_tlv(command_msg, route64, mle.Route64)
 
-    check_tlv_request_tlv(
-        command_msg, CheckType.CONTAIN, mle.TlvType.ADDRESS16
-    )
-    check_tlv_request_tlv(
-        command_msg, CheckType.CONTAIN, mle.TlvType.NETWORK_DATA
-    )
+    check_tlv_request_tlv(command_msg, CheckType.CONTAIN, mle.TlvType.ADDRESS16)
+    check_tlv_request_tlv(command_msg, CheckType.CONTAIN,
+                          mle.TlvType.NETWORK_DATA)
 
 
 def check_child_id_response(
@@ -434,36 +405,29 @@
 
     check_mle_optional_tlv(command_msg, route64, mle.Route64)
     check_mle_optional_tlv(command_msg, network_data, mle.NetworkData)
-    check_mle_optional_tlv(
-        command_msg, address_registration, mle.AddressRegistration
-    )
+    check_mle_optional_tlv(command_msg, address_registration,
+                           mle.AddressRegistration)
     check_mle_optional_tlv(command_msg, active_timestamp, mle.ActiveTimestamp)
-    check_mle_optional_tlv(
-        command_msg, pending_timestamp, mle.PendingTimestamp
-    )
-    check_mle_optional_tlv(
-        command_msg, active_operational_dataset, mle.ActiveOperationalDataset
-    )
-    check_mle_optional_tlv(
-        command_msg, pending_operational_dataset, mle.PendingOperationalDataset
-    )
+    check_mle_optional_tlv(command_msg, pending_timestamp, mle.PendingTimestamp)
+    check_mle_optional_tlv(command_msg, active_operational_dataset,
+                           mle.ActiveOperationalDataset)
+    check_mle_optional_tlv(command_msg, pending_operational_dataset,
+                           mle.PendingOperationalDataset)
 
     if network_data_check is not None:
         network_data_tlv = command_msg.assertMleMessageContainsTlv(
-            mle.NetworkData
-        )
+            mle.NetworkData)
         network_data_check.check(network_data_tlv)
 
 
 def check_prefix(prefix):
     """Verify if a prefix contains 6loWPAN sub-TLV and border router sub-TLV
     """
+    assert contains_tlv(prefix.sub_tlvs, network_data.BorderRouter
+                       ), 'Prefix doesn\'t contain a border router sub-TLV!'
     assert contains_tlv(
-        prefix.sub_tlvs, network_data.BorderRouter
-    ), 'Prefix doesn\'t contain a border router sub-TLV!'
-    assert contains_tlv(
-        prefix.sub_tlvs, network_data.LowpanId
-    ), 'Prefix doesn\'t contain a LowpanId sub-TLV!'
+        prefix.sub_tlvs,
+        network_data.LowpanId), 'Prefix doesn\'t contain a LowpanId sub-TLV!'
 
 
 def check_child_update_request_from_child(
@@ -475,7 +439,7 @@
     address_registration=CheckType.OPTIONAL,
     tlv_request_tlv=CheckType.OPTIONAL,
     active_timestamp=CheckType.OPTIONAL,
-    CIDs=[],
+    CIDs=(),
 ):
 
     command_msg.assertMleMessageContainsTlv(mle.Mode)
@@ -483,9 +447,8 @@
     check_mle_optional_tlv(command_msg, leader_data, mle.LeaderData)
     check_mle_optional_tlv(command_msg, challenge, mle.Challenge)
     check_mle_optional_tlv(command_msg, time_out, mle.Timeout)
-    check_mle_optional_tlv(
-        command_msg, address_registration, mle.AddressRegistration
-    )
+    check_mle_optional_tlv(command_msg, address_registration,
+                           mle.AddressRegistration)
     check_mle_optional_tlv(command_msg, tlv_request_tlv, mle.TlvRequest)
     check_mle_optional_tlv(command_msg, active_timestamp, mle.ActiveTimestamp)
 
@@ -510,13 +473,10 @@
     eidcaches = node.get_eidcaches()
     if cached:
         assert any(
-            router_id == (int(rloc, 16) >> 10) for (_, rloc) in eidcaches
-        )
+            router_id == (int(rloc, 16) >> 10) for (_, rloc) in eidcaches)
     else:
-        assert (
-            any(router_id == (int(rloc, 16) >> 10) for (_, rloc) in eidcaches)
-            is False
-        )
+        assert (any(router_id == (int(rloc, 16) >> 10)
+                    for (_, rloc) in eidcaches) is False)
 
 
 def contains_tlv(sub_tlvs, tlv_type):
@@ -528,10 +488,9 @@
 def contains_tlvs(sub_tlvs, tlv_types):
     """Verify if all types of tlv in a list are included in a sub-tlv list.
     """
-    return all(
-        (any(isinstance(sub_tlv, tlv_type) for sub_tlv in sub_tlvs))
-        for tlv_type in tlv_types
-    )
+    return all((any(isinstance(sub_tlv, tlv_type)
+                    for sub_tlv in sub_tlvs))
+               for tlv_type in tlv_types)
 
 
 def check_secure_mle_key_id_mode(command_msg, key_id_mode):
@@ -541,9 +500,9 @@
     assert command_msg.mle.aux_sec_hdr.key_id_mode == key_id_mode
 
 
-def check_data_response(
-    command_msg, network_data_check=None, active_timestamp=CheckType.OPTIONAL
-):
+def check_data_response(command_msg,
+                        network_data_check=None,
+                        active_timestamp=CheckType.OPTIONAL):
     """Verify a properly formatted Data Response command message.
     """
     check_secure_mle_key_id_mode(command_msg, 0x02)
@@ -552,8 +511,7 @@
     check_mle_optional_tlv(command_msg, active_timestamp, mle.ActiveTimestamp)
     if network_data_check is not None:
         network_data_tlv = command_msg.assertMleMessageContainsTlv(
-            mle.NetworkData
-        )
+            mle.NetworkData)
         network_data_check.check(network_data_tlv)
 
 
@@ -587,7 +545,7 @@
     response=CheckType.OPTIONAL,
     link_layer_frame_counter=CheckType.OPTIONAL,
     mle_frame_counter=CheckType.OPTIONAL,
-    CIDs=[],
+    CIDs=(),
 ):
     """Verify a properly formatted Child Update Response from parent
     """
@@ -596,26 +554,23 @@
     command_msg.assertMleMessageContainsTlv(mle.SourceAddress)
     command_msg.assertMleMessageContainsTlv(mle.Mode)
     check_mle_optional_tlv(command_msg, timeout, mle.Timeout)
-    check_mle_optional_tlv(
-        command_msg, address_registration, mle.AddressRegistration
-    )
+    check_mle_optional_tlv(command_msg, address_registration,
+                           mle.AddressRegistration)
     check_mle_optional_tlv(command_msg, address16, mle.Address16)
     check_mle_optional_tlv(command_msg, leader_data, mle.LeaderData)
     check_mle_optional_tlv(command_msg, network_data, mle.NetworkData)
     check_mle_optional_tlv(command_msg, response, mle.Response)
-    check_mle_optional_tlv(
-        command_msg, link_layer_frame_counter, mle.LinkLayerFrameCounter
-    )
+    check_mle_optional_tlv(command_msg, link_layer_frame_counter,
+                           mle.LinkLayerFrameCounter)
     check_mle_optional_tlv(command_msg, mle_frame_counter, mle.MleFrameCounter)
 
     if (address_registration == CheckType.CONTAIN) and len(CIDs) > 0:
         _check_address_registration(command_msg, CIDs)
 
 
-def _check_address_registration(command_msg, CIDs=[]):
+def _check_address_registration(command_msg, CIDs=()):
     addresses = command_msg.assertMleMessageContainsTlv(
-        mle.AddressRegistration
-    ).addresses
+        mle.AddressRegistration).addresses
     for cid in CIDs:
         found = False
         for address in addresses:
@@ -623,9 +578,7 @@
                 if cid == address.cid:
                     found = True
                     break
-        assert found, "AddressRegistration TLV doesn't have CID {} ".format(
-            cid
-        )
+        assert found, "AddressRegistration TLV doesn't have CID {} ".format(cid)
 
 
 def get_sub_tlv(tlvs, tlv_type):
@@ -634,12 +587,59 @@
             return sub_tlv
 
 
-def check_address_registration_tlv(addr_reg_tlv, address_set):
-    """Verify all addresses contained in address_set are contained in add_reg_tlv
+def check_address_registration_tlv(
+    command_msg,
+    full_address,
+):
+    """Check whether or not a full IPv6 address in AddressRegistrationTlv.
     """
-    assert all(
-        addr in addr_reg_tlv.addresses for addr in address_set
-    ), 'Some addresses are not included in AddressRegistration TLV'
+    found = False
+    addr = ipaddress.ip_address(full_address)
+    addresses = command_msg.assertMleMessageContainsTlv(
+        mle.AddressRegistration).addresses
+
+    for item in addresses:
+        if isinstance(item, mle.AddressFull) and ipaddress.ip_address(
+                item.ipv6_address) == addr:
+            found = True
+            break
+
+    return found
+
+
+def check_compressed_address_registration_tlv(command_msg,
+                                              cid,
+                                              iid,
+                                              cid_present_once=False):
+    '''Check whether or not a compressed IPv6 address in AddressRegistrationTlv.
+    note: only compare the iid part of the address.
+
+        Args:
+            command_msg (MleMessage) : The Mle message to check.
+            cid (int): The context id of the domain prefix.
+            iid (string): The Interface Identifier.
+            cid_present_once(boolean): True if cid entry should apprear only once in AR Tlv.
+                                       False otherwise.
+    '''
+    found = False
+    cid_cnt = 0
+
+    addresses = command_msg.assertMleMessageContainsTlv(
+        mle.AddressRegistration).addresses
+
+    for item in addresses:
+        if isinstance(item, mle.AddressCompressed):
+            if cid == item.cid:
+                cid_cnt = cid_cnt + 1
+                if iid == item.iid.hex():
+                    found = True
+                    break
+    assert found, 'Error: Expected (cid, iid):({},{}) Not Found'.format(
+        cid, iid)
+
+    assert cid_present_once == (
+        cid_cnt == 1), 'Error: Expected cid present {} but present {}'.format(
+            'once' if cid_present_once else '', cid_cnt)
 
 
 def assert_contains_tlv(tlvs, check_type, tlv_type):
@@ -663,36 +663,32 @@
     """
     assert not isinstance(command_msg.mle, mle.MleMessageSecured)
     tlvs = command_msg.assertMleMessageContainsTlv(mle.ThreadDiscovery).tlvs
-    request = assert_contains_tlv(
-        tlvs, CheckType.CONTAIN, mesh_cop.DiscoveryRequest
-    )
+    request = assert_contains_tlv(tlvs, CheckType.CONTAIN,
+                                  mesh_cop.DiscoveryRequest)
     assert request.version == config.PROTOCOL_VERSION
 
 
-def check_discovery_response(
-    command_msg, request_src_addr, steering_data=CheckType.OPTIONAL
-):
+def check_discovery_response(command_msg,
+                             request_src_addr,
+                             steering_data=CheckType.OPTIONAL):
     """Verify a properly formatted Thread Discovery Response command message.
     """
     assert not isinstance(command_msg.mle, mle.MleMessageSecured)
     assert (
-        command_msg.mac_header.src_address.type == common.MacAddressType.LONG
-    )
+        command_msg.mac_header.src_address.type == common.MacAddressType.LONG)
     assert command_msg.mac_header.dest_address == request_src_addr
 
     tlvs = command_msg.assertMleMessageContainsTlv(mle.ThreadDiscovery).tlvs
-    response = assert_contains_tlv(
-        tlvs, CheckType.CONTAIN, mesh_cop.DiscoveryResponse
-    )
+    response = assert_contains_tlv(tlvs, CheckType.CONTAIN,
+                                   mesh_cop.DiscoveryResponse)
     assert response.version == config.PROTOCOL_VERSION
     assert_contains_tlv(tlvs, CheckType.CONTAIN, mesh_cop.ExtendedPanid)
     assert_contains_tlv(tlvs, CheckType.CONTAIN, mesh_cop.NetworkName)
     assert_contains_tlv(tlvs, steering_data, mesh_cop.SteeringData)
     assert_contains_tlv(tlvs, steering_data, mesh_cop.JoinerUdpPort)
 
-    check_type = (
-        CheckType.CONTAIN if response.native_flag else CheckType.OPTIONAL
-    )
+    check_type = (CheckType.CONTAIN
+                  if response.native_flag else CheckType.OPTIONAL)
     assert_contains_tlv(tlvs, check_type, mesh_cop.CommissionerUdpPort)
 
 
@@ -700,9 +696,8 @@
     """Get the udp port specified in a DISCOVERY RESPONSE message
     """
     tlvs = command_msg.assertMleMessageContainsTlv(mle.ThreadDiscovery).tlvs
-    udp_port_tlv = assert_contains_tlv(
-        tlvs, CheckType.CONTAIN, mesh_cop.JoinerUdpPort
-    )
+    udp_port_tlv = assert_contains_tlv(tlvs, CheckType.CONTAIN,
+                                       mesh_cop.JoinerUdpPort)
     return udp_port_tlv.udp_port
 
 
@@ -713,9 +708,8 @@
     assert len(commissioning_messages) >= 2
     join_fin_req = commissioning_messages[0]
     assert join_fin_req.type == mesh_cop.MeshCopMessageType.JOIN_FIN_REQ
-    assert_contains_tlv(
-        join_fin_req.tlvs, CheckType.NOT_CONTAIN, mesh_cop.ProvisioningUrl
-    )
+    assert_contains_tlv(join_fin_req.tlvs, CheckType.NOT_CONTAIN,
+                        mesh_cop.ProvisioningUrl)
     join_ent_rsp = commissioning_messages[1]
     assert join_ent_rsp.type == mesh_cop.MeshCopMessageType.JOIN_ENT_RSP
 
@@ -723,19 +717,15 @@
 def check_commissioner_commissioning_messages(commissioning_messages):
     """Verify COAP messages sent by commissioner while commissioning process.
     """
-    assert any(
-        msg.type == mesh_cop.MeshCopMessageType.JOIN_FIN_RSP
-        for msg in commissioning_messages
-    )
+    assert any(msg.type == mesh_cop.MeshCopMessageType.JOIN_FIN_RSP
+               for msg in commissioning_messages)
 
 
 def check_joiner_router_commissioning_messages(commissioning_messages):
     """Verify COAP messages sent by joiner router while commissioning process.
     """
-    assert any(
-        msg.type == mesh_cop.MeshCopMessageType.JOIN_ENT_NTF
-        for msg in commissioning_messages
-    )
+    assert any(msg.type == mesh_cop.MeshCopMessageType.JOIN_ENT_NTF
+               for msg in commissioning_messages)
     return None
 
 
@@ -746,9 +736,9 @@
     assert len(tp1) == len(tp2)
     for tlv in tp2:
         peer_tlv = get_sub_tlv(tp1, type(tlv))
-        assert (
-            peer_tlv is not None and peer_tlv == tlv
-        ), 'peer_tlv:{}, tlv:{} type:{}'.format(peer_tlv, tlv, type(tlv))
+        assert (peer_tlv is not None and
+                peer_tlv == tlv), 'peer_tlv:{}, tlv:{} type:{}'.format(
+                    peer_tlv, tlv, type(tlv))
 
 
 def check_coap_message(msg, payloads, dest_addrs=None):
@@ -763,38 +753,37 @@
 
 
 class SinglePrefixCheck:
+
     def __init__(self, prefix=None, border_router_16=None):
         self._prefix = prefix
         self._border_router_16 = border_router_16
 
     def check(self, prefix_tlv):
-        border_router_tlv = assert_contains_tlv(
-            prefix_tlv.sub_tlvs, CheckType.CONTAIN, network_data.BorderRouter
-        )
-        assert_contains_tlv(
-            prefix_tlv.sub_tlvs, CheckType.CONTAIN, network_data.LowpanId
-        )
+        border_router_tlv = assert_contains_tlv(prefix_tlv.sub_tlvs,
+                                                CheckType.CONTAIN,
+                                                network_data.BorderRouter)
+        assert_contains_tlv(prefix_tlv.sub_tlvs, CheckType.CONTAIN,
+                            network_data.LowpanId)
         result = True
         if self._prefix is not None:
             result &= self._prefix == binascii.hexlify(prefix_tlv.prefix)
         if self._border_router_16 is not None:
             result &= (
-                self._border_router_16 == border_router_tlv.border_router_16
-            )
+                self._border_router_16 == border_router_tlv.border_router_16)
         return result
 
 
 class PrefixesCheck:
-    def __init__(self, prefix_cnt=0, prefix_check_list=[]):
+
+    def __init__(self, prefix_cnt=0, prefix_check_list=()):
         self._prefix_cnt = prefix_cnt
         self._prefix_check_list = prefix_check_list
 
     def check(self, prefix_tlvs):
         # if prefix_cnt is given, then check count only
         if self._prefix_cnt > 0:
-            assert (
-                len(prefix_tlvs) >= self._prefix_cnt
-            ), 'prefix count is less than expected'
+            assert (len(prefix_tlvs) >=
+                    self._prefix_cnt), 'prefix count is less than expected'
         else:
             for prefix_check in self._prefix_check_list:
                 found = False
@@ -806,21 +795,22 @@
 
 
 class CommissioningDataCheck:
-    def __init__(self, stable=None, sub_tlv_type_list=[]):
+
+    def __init__(self, stable=None, sub_tlv_type_list=()):
         self._stable = stable
         self._sub_tlv_type_list = sub_tlv_type_list
 
     def check(self, commissioning_data_tlv):
         if self._stable is not None:
-            assert (
-                self._stable == commissioning_data_tlv.stable
-            ), 'Commissioning Data stable flag is not correct'
-        assert contains_tlvs(
-            commissioning_data_tlv.sub_tlvs, self._sub_tlv_type_list
-        ), 'Some sub tlvs are missing in Commissioning Data'
+            assert (self._stable == commissioning_data_tlv.stable
+                   ), 'Commissioning Data stable flag is not correct'
+        assert contains_tlvs(commissioning_data_tlv.sub_tlvs,
+                             self._sub_tlv_type_list
+                            ), 'Some sub tlvs are missing in Commissioning Data'
 
 
 class NetworkDataCheck:
+
     def __init__(self, prefixes_check=None, commissioning_data_check=None):
         self._prefixes_check = prefixes_check
         self._commissioning_data_check = commissioning_data_check
@@ -828,8 +818,7 @@
     def check(self, network_data_tlv):
         if self._prefixes_check is not None:
             prefix_tlvs = [
-                tlv
-                for tlv in network_data_tlv.tlvs
+                tlv for tlv in network_data_tlv.tlvs
                 if isinstance(tlv, network_data.Prefix)
             ]
             self._prefixes_check.check(prefix_tlvs)
diff --git a/tests/scripts/thread-cert/common.py b/tests/scripts/thread-cert/common.py
index 519b1df..e42a70e 100644
--- a/tests/scripts/thread-cert/common.py
+++ b/tests/scripts/thread-cert/common.py
@@ -34,17 +34,25 @@
 
 import ipaddress
 
+# Map of 2 bits of parent priority.
+pp_map = {1: 1, 0: 0, 3: -1, 2: -2}
+
+UDP_TEST_PORT = 12345
+
+
+# Get the signed parent priority from the byte that parent priority is in.
+def map_pp(pp_byte):
+    return pp_map[((pp_byte & 0xC0) >> 6)]
+
 
 def expect_the_same_class(self, other):
     if not isinstance(other, self.__class__):
-        raise TypeError(
-            "Expected the same class. Got {} and {}".format(
-                type(self), type(other)
-            )
-        )
+        raise TypeError("Expected the same class. Got {} and {}".format(
+            type(self), type(other)))
 
 
 class MessageInfo(object):
+
     def __init__(self):
         self.aux_sec_hdr = None
         self.aux_sec_hdr_bytes = None
@@ -109,6 +117,7 @@
 
 
 class MacAddress(object):
+
     def __init__(self, mac_address, _type, big_endian=True):
         if _type == MacAddressType.SHORT:
             length = 2
@@ -135,15 +144,11 @@
 
     def convert_to_iid(self):
         if self._type == MacAddressType.SHORT:
-            return (
-                bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00])
-                + self._mac_address[:2]
-            )
+            return (bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00]) +
+                    self._mac_address[:2])
         elif self._type == MacAddressType.LONG:
-            return (
-                bytearray([self._mac_address[0] ^ 0x02])
-                + self._mac_address[1:]
-            )
+            return (bytearray([self._mac_address[0] ^ 0x02]) +
+                    self._mac_address[1:])
         else:
             raise RuntimeError(
                 "Could not convert to IID. Invalid MAC address type: {}".format(
@@ -153,8 +158,8 @@
     def from_eui64(cls, eui64, big_endian=True):
         if not isinstance(eui64, bytearray):
             raise RuntimeError(
-                "Could not create MAC address from EUI64. Invalid data type: {}".format(
-                    type(eui64)))
+                "Could not create MAC address from EUI64. Invalid data type: {}"
+                .format(type(eui64)))
 
         return cls(eui64, MacAddressType.LONG)
 
@@ -166,17 +171,15 @@
             mac_address = rloc16[:2]
         else:
             raise RuntimeError(
-                "Could not create MAC address from RLOC16. Invalid data type: {}".format(
-                    type(rloc16)))
+                "Could not create MAC address from RLOC16. Invalid data type: {}"
+                .format(type(rloc16)))
 
         return cls(mac_address, MacAddressType.SHORT)
 
     def __eq__(self, other):
         return (self.type == other.type) and (
-            self.mac_address == other.mac_address
-        )
+            self.mac_address == other.mac_address)
 
     def __repr__(self):
         return "MacAddress(mac_address=b'{}', type={})".format(
-            hexlify(self.mac_address), MacAddressType(self._type)
-        )
+            hexlify(self.mac_address), MacAddressType(self._type))
diff --git a/tests/scripts/thread-cert/config.py b/tests/scripts/thread-cert/config.py
index b95230e..767948a 100644
--- a/tests/scripts/thread-cert/config.py
+++ b/tests/scripts/thread-cert/config.py
@@ -39,47 +39,55 @@
 import mle
 import net_crypto
 import network_data
+import network_diag
 import network_layer
 import simulator
 import sniffer
 
-MESH_LOCAL_PREFIX = 'fdde:ad00:beef::/64'
-MESH_LOCAL_PREFIX_REGEX_PATTERN = '^fdde:ad00:beef:(0){0,4}:'
+# This extended address will generate the MESH_LOCAL_PREFIX
+EXTENDED_PANID = '000db80000000000'
+MESH_LOCAL_PREFIX = 'fd00:db8::/64'
+MESH_LOCAL_PREFIX_REGEX_PATTERN = '^fd00:0?db8:0{0,4}:0{0,4}'
 ROUTING_LOCATOR = '64/:0:ff:fe00:/16'
 ROUTING_LOCATOR_REGEX_PATTERN = r'.*:(0)?:0{0,2}ff:fe00:\w{1,4}$'
 LINK_LOCAL = 'fe80:/112'
 LINK_LOCAL_REGEX_PATTERN = '^fe80:.*'
 ALOC_FLAG_REGEX_PATTERN = '.*:fc..$'
-LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS = 'ff32:40:fdde:ad00:beef:0:0:1'
-REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS = 'ff33:40:fdde:ad00:beef:0:0:1'
+LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS = 'ff32:40:fd00:db8:0:0:0:1'
+REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS = 'ff33:40:fd00:db8:0:0:0:1'
 REALM_LOCAL_ALL_ROUTERS_ADDRESS = 'ff03::2'
 LINK_LOCAL_ALL_NODES_ADDRESS = 'ff02::1'
 LINK_LOCAL_ALL_ROUTERS_ADDRESS = 'ff02::2'
 
-DEFAULT_MASTER_KEY = bytearray(
-    [
-        0x00,
-        0x11,
-        0x22,
-        0x33,
-        0x44,
-        0x55,
-        0x66,
-        0x77,
-        0x88,
-        0x99,
-        0xaa,
-        0xbb,
-        0xcc,
-        0xdd,
-        0xee,
-        0xff,
-    ]
-)
+DOMAIN_PREFIX = 'fd00:7d03:7d03:7d03::/64'
+DOMAIN_PREFIX_ALTER = 'fd00:7d04:7d04:7d04::/64'
 
-ADDRESS_TYPE = Enum(
-    'ADDRESS_TYPE', ('LINK_LOCAL', 'GLOBAL', 'RLOC', 'ALOC', 'ML_EID')
-)
+ALL_NETWORK_BBRS_ADDRESS = 'ff32:40:fd00:db8:0:0:0:3'
+
+ALL_DOMAIN_BBRS_ADDRESS = 'ff32:40:fd00:7d03:7d03:7d03:0:3'
+ALL_DOMAIN_BBRS_ADDRESS_ALTER = 'ff32:40:fd00:7d04:7d04:7d04:0:3'
+
+DEFAULT_MASTER_KEY = bytearray([
+    0x00,
+    0x11,
+    0x22,
+    0x33,
+    0x44,
+    0x55,
+    0x66,
+    0x77,
+    0x88,
+    0x99,
+    0xaa,
+    0xbb,
+    0xcc,
+    0xdd,
+    0xee,
+    0xff,
+])
+
+ADDRESS_TYPE = Enum('ADDRESS_TYPE',
+                    ('LINK_LOCAL', 'GLOBAL', 'RLOC', 'ALOC', 'ML_EID'))
 RSSI = {
     'LINK_QULITY_0': -100,
     'LINK_QULITY_1': -95,
@@ -108,19 +116,21 @@
 
 def create_default_network_data_prefix_sub_tlvs_factories():
     return {
-        network_data.TlvType.HAS_ROUTE: network_data.HasRouteFactory(
-            routes_factory=network_data.RoutesFactory(
-                route_factory=network_data.RouteFactory()
-            )
-        ),
-        network_data.TlvType.BORDER_ROUTER: network_data.BorderRouterFactory(),
-        network_data.TlvType.LOWPAN_ID: network_data.LowpanIdFactory(),
+        network_data.TlvType.HAS_ROUTE:
+            network_data.HasRouteFactory(
+                routes_factory=network_data.RoutesFactory(
+                    route_factory=network_data.RouteFactory())),
+        network_data.TlvType.BORDER_ROUTER:
+            network_data.BorderRouterFactory(),
+        network_data.TlvType.LOWPAN_ID:
+            network_data.LowpanIdFactory(),
     }
 
 
 def create_default_network_data_prefix_sub_tlvs_factory():
     return network_data.PrefixSubTlvsFactory(
-        sub_tlvs_factories=create_default_network_data_prefix_sub_tlvs_factories())
+        sub_tlvs_factories=create_default_network_data_prefix_sub_tlvs_factories(
+        ))
 
 
 def create_default_network_data_service_sub_tlvs_factories():
@@ -129,53 +139,62 @@
 
 def create_default_network_data_service_sub_tlvs_factory():
     return network_data.ServiceSubTlvsFactory(
-        sub_tlvs_factories=create_default_network_data_service_sub_tlvs_factories())
+        sub_tlvs_factories=
+        create_default_network_data_service_sub_tlvs_factories())
 
 
 def create_default_network_data_commissioning_data_sub_tlvs_factories():
     return {
-        mesh_cop.TlvType.CHANNEL: mesh_cop.ChannelFactory(),
-        mesh_cop.TlvType.STEERING_DATA: mesh_cop.SteeringDataFactory(),
-        mesh_cop.TlvType.BORDER_AGENT_LOCATOR: mesh_cop.BorderAgentLocatorFactory(),
-        mesh_cop.TlvType.COMMISSIONER_SESSION_ID: mesh_cop.CommissionerSessionIdFactory(),
-        mesh_cop.TlvType.COMMISSIONER_UDP_PORT: mesh_cop.CommissionerUdpPortFactory(),
+        mesh_cop.TlvType.CHANNEL:
+            mesh_cop.ChannelFactory(),
+        mesh_cop.TlvType.STEERING_DATA:
+            mesh_cop.SteeringDataFactory(),
+        mesh_cop.TlvType.BORDER_AGENT_LOCATOR:
+            mesh_cop.BorderAgentLocatorFactory(),
+        mesh_cop.TlvType.COMMISSIONER_SESSION_ID:
+            mesh_cop.CommissionerSessionIdFactory(),
+        mesh_cop.TlvType.COMMISSIONER_UDP_PORT:
+            mesh_cop.CommissionerUdpPortFactory(),
     }
 
 
 def create_default_network_data_commissioning_data_sub_tlvs_factory():
     return network_data.CommissioningDataSubTlvsFactory(
-        sub_tlvs_factories=create_default_network_data_commissioning_data_sub_tlvs_factories())
+        sub_tlvs_factories=
+        create_default_network_data_commissioning_data_sub_tlvs_factories())
 
 
 def create_default_network_data_tlvs_factories():
     return {
-        network_data.TlvType.PREFIX: network_data.PrefixFactory(
-            sub_tlvs_factory=create_default_network_data_prefix_sub_tlvs_factory()
-        ),
-        network_data.TlvType.SERVICE: network_data.ServiceFactory(
-            sub_tlvs_factory=create_default_network_data_service_sub_tlvs_factory()
-        ),
-        network_data.TlvType.COMMISSIONING: network_data.CommissioningDataFactory(
-            sub_tlvs_factory=create_default_network_data_commissioning_data_sub_tlvs_factory()
-        ),
+        network_data.TlvType.PREFIX:
+            network_data.PrefixFactory(
+                sub_tlvs_factory=
+                create_default_network_data_prefix_sub_tlvs_factory()),
+        network_data.TlvType.SERVICE:
+            network_data.ServiceFactory(
+                sub_tlvs_factory=
+                create_default_network_data_service_sub_tlvs_factory()),
+        network_data.TlvType.COMMISSIONING:
+            network_data.CommissioningDataFactory(
+                sub_tlvs_factory=
+                create_default_network_data_commissioning_data_sub_tlvs_factory(
+                )),
     }
 
 
 def create_default_network_data_tlvs_factory():
     return network_data.NetworkDataTlvsFactory(
-        sub_tlvs_factories=create_default_network_data_tlvs_factories()
-    )
+        sub_tlvs_factories=create_default_network_data_tlvs_factories())
 
 
 def create_default_mle_tlv_route64_factory():
-    return mle.Route64Factory(
-        link_quality_and_route_data_factory=mle.LinkQualityAndRouteDataFactory())
+    return mle.Route64Factory(link_quality_and_route_data_factory=mle.
+                              LinkQualityAndRouteDataFactory())
 
 
 def create_default_mle_tlv_network_data_factory():
     return mle.NetworkDataFactory(
-        network_data_tlvs_factory=create_default_network_data_tlvs_factory()
-    )
+        network_data_tlvs_factory=create_default_network_data_tlvs_factory())
 
 
 def create_default_mle_tlv_address_registration_factory():
@@ -187,169 +206,296 @@
 
 def create_default_mle_tlv_thread_discovery_factory():
     return mle.ThreadDiscoveryFactory(
-        thread_discovery_tlvs_factory=create_default_thread_discovery_tlvs_factory())
+        thread_discovery_tlvs_factory=
+        create_default_thread_discovery_tlvs_factory())
 
 
 def create_default_thread_discovery_tlvs_factory():
     return mesh_cop.ThreadDiscoveryTlvsFactory(
-        sub_tlvs_factories=create_default_thread_discovery_sub_tlvs_factories()
-    )
+        sub_tlvs_factories=create_default_thread_discovery_sub_tlvs_factories())
 
 
 def create_default_thread_discovery_sub_tlvs_factories():
     return {
-        mesh_cop.TlvType.DISCOVERY_REQUEST: mesh_cop.DiscoveryRequestFactory(),
-        mesh_cop.TlvType.DISCOVERY_RESPONSE: mesh_cop.DiscoveryResponseFactory(),
-        mesh_cop.TlvType.EXTENDED_PANID: mesh_cop.ExtendedPanidFactory(),
-        mesh_cop.TlvType.NETWORK_NAME: mesh_cop.NetworkNameFactory(),
-        mesh_cop.TlvType.STEERING_DATA: mesh_cop.SteeringDataFactory(),
-        mesh_cop.TlvType.JOINER_UDP_PORT: mesh_cop.JoinerUdpPortFactory(),
-        mesh_cop.TlvType.COMMISSIONER_UDP_PORT: mesh_cop.CommissionerUdpPortFactory(),
+        mesh_cop.TlvType.DISCOVERY_REQUEST:
+            mesh_cop.DiscoveryRequestFactory(),
+        mesh_cop.TlvType.DISCOVERY_RESPONSE:
+            mesh_cop.DiscoveryResponseFactory(),
+        mesh_cop.TlvType.EXTENDED_PANID:
+            mesh_cop.ExtendedPanidFactory(),
+        mesh_cop.TlvType.NETWORK_NAME:
+            mesh_cop.NetworkNameFactory(),
+        mesh_cop.TlvType.STEERING_DATA:
+            mesh_cop.SteeringDataFactory(),
+        mesh_cop.TlvType.JOINER_UDP_PORT:
+            mesh_cop.JoinerUdpPortFactory(),
+        mesh_cop.TlvType.COMMISSIONER_UDP_PORT:
+            mesh_cop.CommissionerUdpPortFactory(),
     }
 
 
 def create_default_mle_tlvs_factories():
     return {
-        mle.TlvType.SOURCE_ADDRESS: mle.SourceAddressFactory(),
-        mle.TlvType.MODE: mle.ModeFactory(),
-        mle.TlvType.TIMEOUT: mle.TimeoutFactory(),
-        mle.TlvType.CHALLENGE: mle.ChallengeFactory(),
-        mle.TlvType.RESPONSE: mle.ResponseFactory(),
-        mle.TlvType.LINK_LAYER_FRAME_COUNTER: mle.LinkLayerFrameCounterFactory(),
-        mle.TlvType.MLE_FRAME_COUNTER: mle.MleFrameCounterFactory(),
-        mle.TlvType.ROUTE64: create_default_mle_tlv_route64_factory(),
-        mle.TlvType.ADDRESS16: mle.Address16Factory(),
-        mle.TlvType.LEADER_DATA: mle.LeaderDataFactory(),
-        mle.TlvType.NETWORK_DATA: create_default_mle_tlv_network_data_factory(),
-        mle.TlvType.TLV_REQUEST: mle.TlvRequestFactory(),
-        mle.TlvType.SCAN_MASK: mle.ScanMaskFactory(),
-        mle.TlvType.CONNECTIVITY: mle.ConnectivityFactory(),
-        mle.TlvType.LINK_MARGIN: mle.LinkMarginFactory(),
-        mle.TlvType.STATUS: mle.StatusFactory(),
-        mle.TlvType.VERSION: mle.VersionFactory(),
-        mle.TlvType.ADDRESS_REGISTRATION: create_default_mle_tlv_address_registration_factory(),
-        mle.TlvType.CHANNEL: mle.ChannelFactory(),
-        mle.TlvType.PANID: mle.PanIdFactory(),
-        mle.TlvType.ACTIVE_TIMESTAMP: mle.ActiveTimestampFactory(),
-        mle.TlvType.PENDING_TIMESTAMP: mle.PendingTimestampFactory(),
-        mle.TlvType.ACTIVE_OPERATIONAL_DATASET: mle.ActiveOperationalDatasetFactory(),
-        mle.TlvType.PENDING_OPERATIONAL_DATASET: mle.PendingOperationalDatasetFactory(),
-        mle.TlvType.TIME_REQUEST: mle.TimeRequestFactory(),
-        mle.TlvType.TIME_PARAMETER: mle.TimeParameterFactory(),
-        mle.TlvType.THREAD_DISCOVERY: create_default_mle_tlv_thread_discovery_factory(),
+        mle.TlvType.SOURCE_ADDRESS:
+            mle.SourceAddressFactory(),
+        mle.TlvType.MODE:
+            mle.ModeFactory(),
+        mle.TlvType.TIMEOUT:
+            mle.TimeoutFactory(),
+        mle.TlvType.CHALLENGE:
+            mle.ChallengeFactory(),
+        mle.TlvType.RESPONSE:
+            mle.ResponseFactory(),
+        mle.TlvType.LINK_LAYER_FRAME_COUNTER:
+            mle.LinkLayerFrameCounterFactory(),
+        mle.TlvType.MLE_FRAME_COUNTER:
+            mle.MleFrameCounterFactory(),
+        mle.TlvType.ROUTE64:
+            create_default_mle_tlv_route64_factory(),
+        mle.TlvType.ADDRESS16:
+            mle.Address16Factory(),
+        mle.TlvType.LEADER_DATA:
+            mle.LeaderDataFactory(),
+        mle.TlvType.NETWORK_DATA:
+            create_default_mle_tlv_network_data_factory(),
+        mle.TlvType.TLV_REQUEST:
+            mle.TlvRequestFactory(),
+        mle.TlvType.SCAN_MASK:
+            mle.ScanMaskFactory(),
+        mle.TlvType.CONNECTIVITY:
+            mle.ConnectivityFactory(),
+        mle.TlvType.LINK_MARGIN:
+            mle.LinkMarginFactory(),
+        mle.TlvType.STATUS:
+            mle.StatusFactory(),
+        mle.TlvType.VERSION:
+            mle.VersionFactory(),
+        mle.TlvType.ADDRESS_REGISTRATION:
+            create_default_mle_tlv_address_registration_factory(),
+        mle.TlvType.CHANNEL:
+            mle.ChannelFactory(),
+        mle.TlvType.PANID:
+            mle.PanIdFactory(),
+        mle.TlvType.ACTIVE_TIMESTAMP:
+            mle.ActiveTimestampFactory(),
+        mle.TlvType.PENDING_TIMESTAMP:
+            mle.PendingTimestampFactory(),
+        mle.TlvType.ACTIVE_OPERATIONAL_DATASET:
+            mle.ActiveOperationalDatasetFactory(),
+        mle.TlvType.PENDING_OPERATIONAL_DATASET:
+            mle.PendingOperationalDatasetFactory(),
+        mle.TlvType.TIME_REQUEST:
+            mle.TimeRequestFactory(),
+        mle.TlvType.TIME_PARAMETER:
+            mle.TimeParameterFactory(),
+        mle.TlvType.THREAD_DISCOVERY:
+            create_default_mle_tlv_thread_discovery_factory(),
     }
 
 
 def create_default_mle_crypto_engine(master_key):
     return net_crypto.CryptoEngine(
-        crypto_material_creator=net_crypto.MleCryptoMaterialCreator(master_key)
-    )
+        crypto_material_creator=net_crypto.MleCryptoMaterialCreator(master_key))
 
 
 def create_default_mle_message_factory(master_key):
     return mle.MleMessageFactory(
         aux_sec_hdr_factory=net_crypto.AuxiliarySecurityHeaderFactory(),
         mle_command_factory=mle.MleCommandFactory(
-            tlvs_factories=create_default_mle_tlvs_factories()
-        ),
+            tlvs_factories=create_default_mle_tlvs_factories()),
         crypto_engine=create_default_mle_crypto_engine(master_key),
     )
 
 
 def create_deafult_network_tlvs_factories():
     return {
-        network_layer.TlvType.TARGET_EID: network_layer.TargetEidFactory(),
-        network_layer.TlvType.MAC_EXTENDED_ADDRESS: network_layer.MacExtendedAddressFactory(),
-        network_layer.TlvType.RLOC16: network_layer.Rloc16Factory(),
-        network_layer.TlvType.ML_EID: network_layer.MlEidFactory(),
-        network_layer.TlvType.STATUS: network_layer.StatusFactory(),
-        network_layer.TlvType.TIME_SINCE_LAST_TRANSACTION: network_layer.TimeSinceLastTransactionFactory(),
-        network_layer.TlvType.ROUTER_MASK: network_layer.RouterMaskFactory(),
-        network_layer.TlvType.ND_OPTION: network_layer.NdOptionFactory(),
-        network_layer.TlvType.ND_DATA: network_layer.NdDataFactory(),
-        network_layer.TlvType.THREAD_NETWORK_DATA: network_layer.ThreadNetworkDataFactory(
-            create_default_network_data_tlvs_factory()
-        ),
-        network_layer.TlvType.XTAL_ACCURACY: network_layer.XtalAccuracyFactory(),
+        network_layer.TlvType.TARGET_EID:
+            network_layer.TargetEidFactory(),
+        network_layer.TlvType.MAC_EXTENDED_ADDRESS:
+            network_layer.MacExtendedAddressFactory(),
+        network_layer.TlvType.RLOC16:
+            network_layer.Rloc16Factory(),
+        network_layer.TlvType.ML_EID:
+            network_layer.MlEidFactory(),
+        network_layer.TlvType.STATUS:
+            network_layer.StatusFactory(),
+        network_layer.TlvType.TIME_SINCE_LAST_TRANSACTION:
+            network_layer.TimeSinceLastTransactionFactory(),
+        network_layer.TlvType.ROUTER_MASK:
+            network_layer.RouterMaskFactory(),
+        network_layer.TlvType.ND_OPTION:
+            network_layer.NdOptionFactory(),
+        network_layer.TlvType.ND_DATA:
+            network_layer.NdDataFactory(),
+        network_layer.TlvType.THREAD_NETWORK_DATA:
+            network_layer.ThreadNetworkDataFactory(
+                create_default_network_data_tlvs_factory()),
+        network_layer.TlvType.XTAL_ACCURACY:
+            network_layer.XtalAccuracyFactory(),
         # Routing information are distributed in a Thread network by MLE Routing TLV
         # which is in fact MLE Route64 TLV. Thread specificaton v1.1. - Chapter 5.20
-        network_layer.TlvType.MLE_ROUTING: create_default_mle_tlv_route64_factory(),
+        network_layer.TlvType.MLE_ROUTING:
+            create_default_mle_tlv_route64_factory(),
     }
 
 
 def create_default_network_tlvs_factory():
     return SubTlvsFactory(
-        sub_tlvs_factories=create_deafult_network_tlvs_factories()
-    )
+        sub_tlvs_factories=create_deafult_network_tlvs_factories())
 
 
 def create_default_mesh_cop_tlvs_factories():
     return {
-        mesh_cop.TlvType.CHANNEL: mesh_cop.ChannelFactory(),
-        mesh_cop.TlvType.PAN_ID: mesh_cop.PanidFactory(),
-        mesh_cop.TlvType.EXTENDED_PANID: mesh_cop.ExtendedPanidFactory(),
-        mesh_cop.TlvType.NETWORK_NAME: mesh_cop.NetworkNameFactory(),
-        mesh_cop.TlvType.PSKC: mesh_cop.PSKcFactory(),
-        mesh_cop.TlvType.NETWORK_MASTER_KEY: mesh_cop.NetworkMasterKeyFactory(),
-        mesh_cop.TlvType.NETWORK_KEY_SEQUENCE_COUNTER: mesh_cop.NetworkKeySequenceCounterFactory(),
-        mesh_cop.TlvType.NETWORK_MESH_LOCAL_PREFIX: mesh_cop.NetworkMeshLocalPrefixFactory(),
-        mesh_cop.TlvType.STEERING_DATA: mesh_cop.SteeringDataFactory(),
-        mesh_cop.TlvType.BORDER_AGENT_LOCATOR: mesh_cop.BorderAgentLocatorFactory(),
-        mesh_cop.TlvType.COMMISSIONER_ID: mesh_cop.CommissionerIdFactory(),
-        mesh_cop.TlvType.COMMISSIONER_SESSION_ID: mesh_cop.CommissionerSessionIdFactory(),
-        mesh_cop.TlvType.SECURITY_POLICY: mesh_cop.SecurityPolicyFactory(),
-        mesh_cop.TlvType.GET: mesh_cop.GetFactory(),
-        mesh_cop.TlvType.ACTIVE_TIMESTAMP: mesh_cop.ActiveTimestampFactory(),
-        mesh_cop.TlvType.COMMISSIONER_UDP_PORT: mesh_cop.CommissionerUdpPortFactory(),
-        mesh_cop.TlvType.STATE: mesh_cop.StateFactory(),
-        mesh_cop.TlvType.JOINER_DTLS_ENCAPSULATION: mesh_cop.JoinerDtlsEncapsulationFactory(),
-        mesh_cop.TlvType.JOINER_UDP_PORT: mesh_cop.JoinerUdpPortFactory(),
-        mesh_cop.TlvType.JOINER_IID: mesh_cop.JoinerIIDFactory(),
-        mesh_cop.TlvType.JOINER_ROUTER_LOCATOR: mesh_cop.JoinerRouterLocatorFactory(),
-        mesh_cop.TlvType.JOINER_ROUTER_KEK: mesh_cop.JoinerRouterKEKFactory(),
-        mesh_cop.TlvType.PROVISIONING_URL: mesh_cop.ProvisioningUrlFactory(),
-        mesh_cop.TlvType.VENDOR_NAME: mesh_cop.VendorNameFactory(),
-        mesh_cop.TlvType.VENDOR_MODEL: mesh_cop.VendorModelFactory(),
-        mesh_cop.TlvType.VENDOR_SW_VERSION: mesh_cop.VendorSWVersionFactory(),
-        mesh_cop.TlvType.VENDOR_DATA: mesh_cop.VendorDataFactory(),
-        mesh_cop.TlvType.VENDOR_STACK_VERSION: mesh_cop.VendorStackVersionFactory(),
-        mesh_cop.TlvType.UDP_ENCAPSULATION: mesh_cop.UdpEncapsulationFactory(),
-        mesh_cop.TlvType.IPV6_ADDRESS: mesh_cop.Ipv6AddressFactory(),
-        mesh_cop.TlvType.PENDING_TIMESTAMP: mesh_cop.PendingTimestampFactory(),
-        mesh_cop.TlvType.DELAY_TIMER: mesh_cop.DelayTimerFactory(),
-        mesh_cop.TlvType.CHANNEL_MASK: mesh_cop.ChannelMaskFactory(),
-        mesh_cop.TlvType.COUNT: mesh_cop.CountFactory(),
-        mesh_cop.TlvType.PERIOD: mesh_cop.PeriodFactory(),
-        mesh_cop.TlvType.SCAN_DURATION: mesh_cop.ScanDurationFactory(),
-        mesh_cop.TlvType.ENERGY_LIST: mesh_cop.EnergyListFactory(),
+        mesh_cop.TlvType.CHANNEL:
+            mesh_cop.ChannelFactory(),
+        mesh_cop.TlvType.PAN_ID:
+            mesh_cop.PanidFactory(),
+        mesh_cop.TlvType.EXTENDED_PANID:
+            mesh_cop.ExtendedPanidFactory(),
+        mesh_cop.TlvType.NETWORK_NAME:
+            mesh_cop.NetworkNameFactory(),
+        mesh_cop.TlvType.PSKC:
+            mesh_cop.PSKcFactory(),
+        mesh_cop.TlvType.NETWORK_MASTER_KEY:
+            mesh_cop.NetworkMasterKeyFactory(),
+        mesh_cop.TlvType.NETWORK_KEY_SEQUENCE_COUNTER:
+            mesh_cop.NetworkKeySequenceCounterFactory(),
+        mesh_cop.TlvType.NETWORK_MESH_LOCAL_PREFIX:
+            mesh_cop.NetworkMeshLocalPrefixFactory(),
+        mesh_cop.TlvType.STEERING_DATA:
+            mesh_cop.SteeringDataFactory(),
+        mesh_cop.TlvType.BORDER_AGENT_LOCATOR:
+            mesh_cop.BorderAgentLocatorFactory(),
+        mesh_cop.TlvType.COMMISSIONER_ID:
+            mesh_cop.CommissionerIdFactory(),
+        mesh_cop.TlvType.COMMISSIONER_SESSION_ID:
+            mesh_cop.CommissionerSessionIdFactory(),
+        mesh_cop.TlvType.SECURITY_POLICY:
+            mesh_cop.SecurityPolicyFactory(),
+        mesh_cop.TlvType.GET:
+            mesh_cop.GetFactory(),
+        mesh_cop.TlvType.ACTIVE_TIMESTAMP:
+            mesh_cop.ActiveTimestampFactory(),
+        mesh_cop.TlvType.COMMISSIONER_UDP_PORT:
+            mesh_cop.CommissionerUdpPortFactory(),
+        mesh_cop.TlvType.STATE:
+            mesh_cop.StateFactory(),
+        mesh_cop.TlvType.JOINER_DTLS_ENCAPSULATION:
+            mesh_cop.JoinerDtlsEncapsulationFactory(),
+        mesh_cop.TlvType.JOINER_UDP_PORT:
+            mesh_cop.JoinerUdpPortFactory(),
+        mesh_cop.TlvType.JOINER_IID:
+            mesh_cop.JoinerIIDFactory(),
+        mesh_cop.TlvType.JOINER_ROUTER_LOCATOR:
+            mesh_cop.JoinerRouterLocatorFactory(),
+        mesh_cop.TlvType.JOINER_ROUTER_KEK:
+            mesh_cop.JoinerRouterKEKFactory(),
+        mesh_cop.TlvType.PROVISIONING_URL:
+            mesh_cop.ProvisioningUrlFactory(),
+        mesh_cop.TlvType.VENDOR_NAME:
+            mesh_cop.VendorNameFactory(),
+        mesh_cop.TlvType.VENDOR_MODEL:
+            mesh_cop.VendorModelFactory(),
+        mesh_cop.TlvType.VENDOR_SW_VERSION:
+            mesh_cop.VendorSWVersionFactory(),
+        mesh_cop.TlvType.VENDOR_DATA:
+            mesh_cop.VendorDataFactory(),
+        mesh_cop.TlvType.VENDOR_STACK_VERSION:
+            mesh_cop.VendorStackVersionFactory(),
+        mesh_cop.TlvType.UDP_ENCAPSULATION:
+            mesh_cop.UdpEncapsulationFactory(),
+        mesh_cop.TlvType.IPV6_ADDRESS:
+            mesh_cop.Ipv6AddressFactory(),
+        mesh_cop.TlvType.PENDING_TIMESTAMP:
+            mesh_cop.PendingTimestampFactory(),
+        mesh_cop.TlvType.DELAY_TIMER:
+            mesh_cop.DelayTimerFactory(),
+        mesh_cop.TlvType.CHANNEL_MASK:
+            mesh_cop.ChannelMaskFactory(),
+        mesh_cop.TlvType.COUNT:
+            mesh_cop.CountFactory(),
+        mesh_cop.TlvType.PERIOD:
+            mesh_cop.PeriodFactory(),
+        mesh_cop.TlvType.SCAN_DURATION:
+            mesh_cop.ScanDurationFactory(),
+        mesh_cop.TlvType.ENERGY_LIST:
+            mesh_cop.EnergyListFactory(),
     }
 
 
 def create_default_mesh_cop_tlvs_factory():
     return SubTlvsFactory(
-        sub_tlvs_factories=create_default_mesh_cop_tlvs_factories()
-    )
+        sub_tlvs_factories=create_default_mesh_cop_tlvs_factories())
+
+
+def create_default_network_diag_tlv_factories():
+    return {
+        network_diag.TlvType.EXT_ADDRESS:
+            network_layer.MacExtendedAddressFactory(),
+        network_diag.TlvType.ADDRESS16:
+            mle.Address16Factory(),
+        network_diag.TlvType.MODE:
+            mle.ModeFactory(),
+        network_diag.TlvType.POLLING_PERIOD:
+            mle.TimeoutFactory(),
+        network_diag.TlvType.CONNECTIVITY:
+            mle.ConnectivityFactory(),
+        network_diag.TlvType.ROUTE64:
+            create_default_mle_tlv_route64_factory(),
+        network_diag.TlvType.LEADER_DATA:
+            mle.LeaderDataFactory(),
+        network_diag.TlvType.NETWORK_DATA:
+            create_default_mle_tlv_network_data_factory(),
+        network_diag.TlvType.IPV6_ADDRESS_LIST:
+            network_diag.Ipv6AddressListFactory(),
+        network_diag.TlvType.MAC_COUNTERS:
+            network_diag.MacCountersFactory(),
+        network_diag.TlvType.BATTERY_LEVEL:
+            network_diag.BatteryLevelFactory(),
+        network_diag.TlvType.SUPPLY_VOLTAGE:
+            network_diag.SupplyVoltageFactory(),
+        network_diag.TlvType.CHILD_TABLE:
+            network_diag.ChildTableFactory(),
+        network_diag.TlvType.CHANNEL_PAGES:
+            network_diag.ChannelPagesFactory(),
+        network_diag.TlvType.TYPE_LIST:
+            network_diag.TypeListFactory(),
+        network_diag.TlvType.MAX_CHILD_TIMEOUT:
+            network_diag.MaxChildTimeoutFactory()
+    }
+
+
+def create_default_network_diag_tlvs_factory():
+    return SubTlvsFactory(
+        sub_tlvs_factories=create_default_network_diag_tlv_factories())
 
 
 def create_default_uri_path_based_payload_factories():
     network_layer_tlvs_factory = create_default_network_tlvs_factory()
     mesh_cop_tlvs_factory = create_default_mesh_cop_tlvs_factory()
+    network_diag_tlvs_factory = create_default_network_diag_tlvs_factory()
+
     return {
-        "/a/as": network_layer_tlvs_factory,
-        "/a/aq": network_layer_tlvs_factory,
-        "/a/ar": network_layer_tlvs_factory,
-        "/a/ae": network_layer_tlvs_factory,
-        "/a/an": network_layer_tlvs_factory,
-        "/a/sd": network_layer_tlvs_factory,
-        "/c/lp": mesh_cop_tlvs_factory,
-        "/c/cs": mesh_cop_tlvs_factory,
+        '/a/as': network_layer_tlvs_factory,
+        '/a/aq': network_layer_tlvs_factory,
+        '/a/ar': network_layer_tlvs_factory,
+        '/a/ae': network_layer_tlvs_factory,
+        '/a/an': network_layer_tlvs_factory,
+        '/a/sd': network_layer_tlvs_factory,
+        '/c/lp': mesh_cop_tlvs_factory,
+        '/c/cs': mesh_cop_tlvs_factory,
+        '/d/da': network_diag_tlvs_factory,
+        '/d/dg': network_diag_tlvs_factory,
+        '/d/dq': network_diag_tlvs_factory,
+        '/d/dr': network_diag_tlvs_factory,
     }
 
 
 def create_default_coap_message_factory():
     return coap.CoapMessageFactory(
         options_factory=coap.CoapOptionsFactory(),
-        uri_path_based_payload_factories=create_default_uri_path_based_payload_factories(),
+        uri_path_based_payload_factories=
+        create_default_uri_path_based_payload_factories(),
         message_id_to_uri_path_binder=coap.CoapMessageIdToUriPathBinder(),
     )
 
@@ -360,8 +506,7 @@
 
 def create_default_ipv6_hop_by_hop_options_factory():
     return ipv6.HopByHopOptionsFactory(
-        options_factories=create_default_ipv6_hop_by_hop_options_factories()
-    )
+        options_factories=create_default_ipv6_hop_by_hop_options_factories())
 
 
 def create_default_based_on_src_dst_ports_udp_payload_factory(master_key):
@@ -374,9 +519,9 @@
             19788: mle_message_factory,
             61631: coap_message_factory,
             1000: dtls_message_factory,
+            5683: coap_message_factory,
             5684: dtls_message_factory,
-        }
-    )
+        })
 
 
 def create_default_dtls_message_factory():
@@ -385,35 +530,48 @@
 
 def create_default_ipv6_icmp_body_factories():
     return {
-        ipv6.ICMP_DESTINATION_UNREACHABLE: ipv6.ICMPv6DestinationUnreachableFactory(),
-        ipv6.ICMP_ECHO_REQUEST: ipv6.ICMPv6EchoBodyFactory(),
-        ipv6.ICMP_ECHO_RESPONSE: ipv6.ICMPv6EchoBodyFactory(),
-        "default": ipv6.BytesPayloadFactory(),
+        ipv6.ICMP_DESTINATION_UNREACHABLE:
+            ipv6.ICMPv6DestinationUnreachableFactory(),
+        ipv6.ICMP_ECHO_REQUEST:
+            ipv6.ICMPv6EchoBodyFactory(),
+        ipv6.ICMP_ECHO_RESPONSE:
+            ipv6.ICMPv6EchoBodyFactory(),
+        'default':
+            ipv6.BytesPayloadFactory(),
     }
 
 
 def create_default_ipv6_upper_layer_factories(master_key):
     return {
-        ipv6.IPV6_NEXT_HEADER_UDP: ipv6.UDPDatagramFactory(
-            udp_header_factory=ipv6.UDPHeaderFactory(),
-            udp_payload_factory=create_default_based_on_src_dst_ports_udp_payload_factory(
-                master_key
+        ipv6.IPV6_NEXT_HEADER_UDP:
+            ipv6.UDPDatagramFactory(
+                udp_header_factory=ipv6.UDPHeaderFactory(),
+                udp_payload_factory=
+                create_default_based_on_src_dst_ports_udp_payload_factory(
+                    master_key),
             ),
-        ),
-        ipv6.IPV6_NEXT_HEADER_ICMP: ipv6.ICMPv6Factory(
-            body_factories=create_default_ipv6_icmp_body_factories()
-        ),
+        ipv6.IPV6_NEXT_HEADER_ICMP:
+            ipv6.ICMPv6Factory(
+                body_factories=create_default_ipv6_icmp_body_factories()),
     }
 
 
 def create_default_lowpan_extension_headers_factories():
-    return {ipv6.IPV6_NEXT_HEADER_HOP_BY_HOP: lowpan.LowpanHopByHopFactory(
-        hop_by_hop_options_factory=create_default_ipv6_hop_by_hop_options_factory())}
+    return {
+        ipv6.IPV6_NEXT_HEADER_HOP_BY_HOP:
+            lowpan.LowpanHopByHopFactory(
+                hop_by_hop_options_factory=
+                create_default_ipv6_hop_by_hop_options_factory())
+    }
 
 
 def create_default_ipv6_extension_headers_factories():
-    return {ipv6.IPV6_NEXT_HEADER_HOP_BY_HOP: ipv6.HopByHopFactory(
-        hop_by_hop_options_factory=create_default_ipv6_hop_by_hop_options_factory())}
+    return {
+        ipv6.IPV6_NEXT_HEADER_HOP_BY_HOP:
+            ipv6.HopByHopFactory(
+                hop_by_hop_options_factory=
+                create_default_ipv6_hop_by_hop_options_factory())
+    }
 
 
 def create_default_ipv6_packet_factory(master_key):
@@ -426,11 +584,10 @@
 def create_default_lowpan_decompressor(context_manager):
     return lowpan.LowpanDecompressor(
         lowpan_ip_header_factory=lowpan.LowpanIpv6HeaderFactory(
-            context_manager=context_manager
-        ),
+            context_manager=context_manager),
         lowpan_extension_headers_factory=lowpan.LowpanExtensionHeadersFactory(
-            ext_headers_factories=create_default_lowpan_extension_headers_factories()
-        ),
+            ext_headers_factories=
+            create_default_lowpan_extension_headers_factories()),
         lowpan_udp_header_factory=lowpan.LowpanUdpHeaderFactory(),
     )
 
@@ -442,13 +599,13 @@
     return context_manager
 
 
-def create_default_lowpan_parser(
-    context_manager, master_key=DEFAULT_MASTER_KEY
-):
+def create_default_lowpan_parser(context_manager,
+                                 master_key=DEFAULT_MASTER_KEY):
     return lowpan.LowpanParser(
         lowpan_mesh_header_factory=lowpan.LowpanMeshHeaderFactory(),
         lowpan_decompressor=create_default_lowpan_decompressor(context_manager),
-        lowpan_fragements_buffers_manager=lowpan.LowpanFragmentsBuffersManager(),
+        lowpan_fragements_buffers_manager=lowpan.LowpanFragmentsBuffersManager(
+        ),
         ipv6_packet_factory=create_default_ipv6_packet_factory(master_key),
     )
 
diff --git a/tests/scripts/thread-cert/debug.py b/tests/scripts/thread-cert/debug.py
index 4d76097..b3b03b2 100644
--- a/tests/scripts/thread-cert/debug.py
+++ b/tests/scripts/thread-cert/debug.py
@@ -27,7 +27,6 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from builtins import input
 
 
diff --git a/tests/scripts/thread-cert/dtls.py b/tests/scripts/thread-cert/dtls.py
index 33fd914..41fc801 100644
--- a/tests/scripts/thread-cert/dtls.py
+++ b/tests/scripts/thread-cert/dtls.py
@@ -91,9 +91,9 @@
 
 
 class Record(ConvertibleToBytes, BuildableFromBytes):
-    def __init__(
-        self, content_type, version, epoch, sequence_number, length, fragment
-    ):
+
+    def __init__(self, content_type, version, epoch, sequence_number, length,
+                 fragment):
         self.content_type = content_type
         self.version = version
         self.epoch = epoch
@@ -102,14 +102,10 @@
         self.fragment = fragment
 
     def to_bytes(self):
-        return (
-            struct.pack(">B", self.content_type)
-            + self.version.to_bytes()
-            + struct.pack(">H", self.epoch)
-            + self.sequence_number.to_bytes(6, byteorder='big')
-            + struct.pack(">H", self.length)
-            + self.fragment
-        )
+        return (struct.pack(">B", self.content_type) + self.version.to_bytes() +
+                struct.pack(">H", self.epoch) +
+                self.sequence_number.to_bytes(6, byteorder='big') +
+                struct.pack(">H", self.length) + self.fragment)
 
     @classmethod
     def from_bytes(cls, data):
@@ -119,16 +115,21 @@
         sequence_number = struct.unpack(">Q", b'\x00\x00' + data.read(6))[0]
         length = struct.unpack(">H", data.read(2))[0]
         fragment = bytes(data.read(length))
-        return cls(
-            content_type, version, epoch, sequence_number, length, fragment
-        )
+        return cls(content_type, version, epoch, sequence_number, length,
+                   fragment)
 
     def __repr__(self):
         return "Record(content_type={}, version={}, epoch={}, sequence_number={}, length={})".format(
-            str(self.content_type), self.version, self.epoch, self.sequence_number, self.length, )
+            str(self.content_type),
+            self.version,
+            self.epoch,
+            self.sequence_number,
+            self.length,
+        )
 
 
 class Message(ConvertibleToBytes, BuildableFromBytes):
+
     def __init__(self, content_type):
         self.content_type = content_type
 
@@ -141,6 +142,7 @@
 
 
 class HandshakeMessage(Message):
+
     def __init__(
         self,
         handshake_type,
@@ -159,14 +161,12 @@
         self.body = body
 
     def to_bytes(self):
-        return (
-            struct.pack(">B", self.handshake_type)
-            + struct.pack(">I", self.length)[1:]
-            + struct.pack(">H", self.message_seq)
-            + struct.pack(">I", self.fragment_offset)[1:]
-            + struct.pack(">I", self.fragment_length)[1:]
-            + self.body.to_bytes()
-        )
+        return (struct.pack(">B", self.handshake_type) +
+                struct.pack(">I", self.length)[1:] +
+                struct.pack(">H", self.message_seq) +
+                struct.pack(">I", self.fragment_offset)[1:] +
+                struct.pack(">I", self.fragment_length)[1:] +
+                self.body.to_bytes())
 
     @classmethod
     def from_bytes(cls, data):
@@ -196,22 +196,19 @@
         )
 
     def __repr__(self):
-        return "Handshake(type={}, length={})".format(
-            str(self.handshake_type), self.length
-        )
+        return "Handshake(type={}, length={})".format(str(self.handshake_type),
+                                                      self.length)
 
 
 class ProtocolVersion(ConvertibleToBytes, BuildableFromBytes):
+
     def __init__(self, major, minor):
         self.major = major
         self.minor = minor
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other))
-            and self.major == other.major
-            and self.minor == other.minor
-        )
+        return (isinstance(self, type(other)) and self.major == other.major and
+                self.minor == other.minor)
 
     def to_bytes(self):
         return struct.pack(">BB", self.major, self.minor)
@@ -223,8 +220,7 @@
 
     def __repr__(self):
         return "ProtocolVersion(major={}, minor={})".format(
-            self.major, self.minor
-        )
+            self.major, self.minor)
 
 
 class Random(ConvertibleToBytes, BuildableFromBytes):
@@ -237,11 +233,9 @@
         assert len(self.random_bytes) == Random.random_bytes_length
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other))
-            and self.gmt_unix_time == other.gmt_unix_time
-            and self.random_bytes == other.random_bytes
-        )
+        return (isinstance(self, type(other)) and
+                self.gmt_unix_time == other.gmt_unix_time and
+                self.random_bytes == other.random_bytes)
 
     def to_bytes(self):
         return struct.pack(">I", self.gmt_unix_time) + (self.random_bytes)
@@ -254,6 +248,7 @@
 
 
 class VariableVector(ConvertibleToBytes):
+
     def __init__(self, subrange, ele_cls, elements):
         self.subrange = subrange
         self.ele_cls = ele_cls
@@ -264,12 +259,10 @@
         return len(self.elements)
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other))
-            and self.subrange == other.subrange
-            and self.ele_cls == other.ele_cls
-            and self.elements == other.elements
-        )
+        return (isinstance(self, type(other)) and
+                self.subrange == other.subrange and
+                self.ele_cls == other.ele_cls and
+                self.elements == other.elements)
 
     def to_bytes(self):
         data = reduce(lambda ele, acc: acc + ele.to_bytes(), self.elements)
@@ -299,7 +292,7 @@
         ret = bytearray([])
         while length_in_byte > 0:
             ret += bytes(length_in_byte & 0xff)
-            length_in_byte == length_in_byte >> 8
+            length_in_byte = length_in_byte >> 8
         return ret
 
     @classmethod
@@ -308,6 +301,7 @@
 
 
 class Opaque(ConvertibleToBytes, BuildableFromBytes):
+
     def __init__(self, byte):
         self.byte = byte
 
@@ -323,6 +317,7 @@
 
 
 class CipherSuite(ConvertibleToBytes, BuildableFromBytes):
+
     def __init__(self, cipher):
         self.cipher = cipher
 
@@ -361,33 +356,29 @@
 
 
 class Extension(ConvertibleToBytes, BuildableFromBytes):
+
     def __init__(self, extension_type, extension_data):
         self.extension_type = extension_type
         self.extension_data = extension_data
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other))
-            and self.extension_type == other.extension_type
-            and self.extension_data == other.extension_data
-        )
+        return (isinstance(self, type(other)) and
+                self.extension_type == other.extension_type and
+                self.extension_data == other.extension_data)
 
     def to_bytes(self):
-        return (
-            struct.pack(">H", self.extension_type)
-            + self.extension_data.to_bytes()
-        )
+        return (struct.pack(">H", self.extension_type) +
+                self.extension_data.to_bytes())
 
     @classmethod
     def from_bytes(cls, data):
         extension_type = struct.unpack(">H", data.read(2))[0]
-        extension_data = VariableVector.from_bytes(
-            Opaque, (0, 2 ** 16 - 1), data
-        )
+        extension_data = VariableVector.from_bytes(Opaque, (0, 2**16 - 1), data)
         return cls(extension_type, extension_data)
 
 
 class ClientHello(HandshakeMessage):
+
     def __init__(
         self,
         client_version,
@@ -407,33 +398,26 @@
         self.extensions = extensions
 
     def to_bytes(self):
-        return (
-            self.client_version.to_bytes()
-            + self.random.to_bytes()
-            + self.session_id.to_bytes()
-            + self.cookie.to_bytes()
-            + self.cipher_suites.to_bytes()
-            + self.compression_methods.to_bytes()
-            + self.extensions.to_bytes()
-        )
+        return (self.client_version.to_bytes() + self.random.to_bytes() +
+                self.session_id.to_bytes() + self.cookie.to_bytes() +
+                self.cipher_suites.to_bytes() +
+                self.compression_methods.to_bytes() +
+                self.extensions.to_bytes())
 
     @classmethod
     def from_bytes(cls, data):
         client_version = ProtocolVersion.from_bytes(data)
         random = Random.from_bytes(data)
         session_id = VariableVector.from_bytes(Opaque, (0, 32), data)
-        cookie = VariableVector.from_bytes(Opaque, (0, 2 ** 8 - 1), data)
-        cipher_suites = VariableVector.from_bytes(
-            CipherSuite, (2, 2 ** 16 - 1), data
-        )
-        compression_methods = VariableVector.from_bytes(
-            CompressionMethod, (1, 2 ** 8 - 1), data
-        )
+        cookie = VariableVector.from_bytes(Opaque, (0, 2**8 - 1), data)
+        cipher_suites = VariableVector.from_bytes(CipherSuite, (2, 2**16 - 1),
+                                                  data)
+        compression_methods = VariableVector.from_bytes(CompressionMethod,
+                                                        (1, 2**8 - 1), data)
         extensions = None
         if data.tell() < len(data.getvalue()):
-            extensions = VariableVector.from_bytes(
-                Extension, (0, 2 ** 16 - 1), data
-            )
+            extensions = VariableVector.from_bytes(Extension, (0, 2**16 - 1),
+                                                   data)
         return cls(
             client_version,
             random,
@@ -446,6 +430,7 @@
 
 
 class HelloVerifyRequest(HandshakeMessage):
+
     def __init__(self, server_version, cookie):
         self.server_version = server_version
         self.cookie = cookie
@@ -456,11 +441,12 @@
     @classmethod
     def from_bytes(cls, data):
         server_version = ProtocolVersion.from_bytes(data)
-        cookie = VariableVector.from_bytes(Opaque, (0, 2 ** 8 - 1), data)
+        cookie = VariableVector.from_bytes(Opaque, (0, 2**8 - 1), data)
         return cls(server_version, cookie)
 
 
 class ServerHello(HandshakeMessage):
+
     def __init__(
         self,
         server_version,
@@ -478,14 +464,9 @@
         self.extensions = extensions
 
     def to_bytes(self):
-        return (
-            self.server_version.to_bytes()
-            + self.random.to_bytes()
-            + self.session_id.to_bytes()
-            + self.cipher_suite.to_bytes()
-            + self.compression_method.to_bytes()
-            + self.extensions.to_bytes()
-        )
+        return (self.server_version.to_bytes() + self.random.to_bytes() +
+                self.session_id.to_bytes() + self.cipher_suite.to_bytes() +
+                self.compression_method.to_bytes() + self.extensions.to_bytes())
 
     @classmethod
     def from_bytes(cls, data):
@@ -496,9 +477,8 @@
         compression_method = CompressionMethod.from_bytes(data)
         extensions = None
         if data.tell() < len(data.getvalue()):
-            extensions = VariableVector.from_bytes(
-                Extension, (0, 2 ** 16 - 1), data
-            )
+            extensions = VariableVector.from_bytes(Extension, (0, 2**16 - 1),
+                                                   data)
         return cls(
             server_version,
             random,
@@ -510,6 +490,7 @@
 
 
 class ServerHelloDone(HandshakeMessage):
+
     def __init__(self):
         pass
 
@@ -522,41 +503,49 @@
 
 
 class HelloRequest(HandshakeMessage):
+
     def __init__(self):
         raise NotImplementedError
 
 
 class Certificate(HandshakeMessage):
+
     def __init__(self):
         raise NotImplementedError
 
 
 class ServerKeyExchange(HandshakeMessage):
+
     def __init__(self):
         raise NotImplementedError
 
 
 class CertificateRequest(HandshakeMessage):
+
     def __init__(self):
         raise NotImplementedError
 
 
 class CertificateVerify(HandshakeMessage):
+
     def __init__(self):
         raise NotImplementedError
 
 
 class ClientKeyExchange(HandshakeMessage):
+
     def __init__(self):
         raise NotImplementedError
 
 
 class Finished(HandshakeMessage):
+
     def __init__(self, verify_data):
         raise NotImplementedError
 
 
 class AlertMessage(Message):
+
     def __init__(self, level, description):
         super(AlertMessage, self).__init__(ContentType.ALERT)
         self.level = level
@@ -576,16 +565,15 @@
             return cls(None, None)
 
     def __repr__(self):
-        return "Alert(level={}, description={})".format(
-            str(self.level), str(self.description)
-        )
+        return "Alert(level={}, description={})".format(str(self.level),
+                                                        str(self.description))
 
 
 class ChangeCipherSpecMessage(Message):
+
     def __init__(self):
-        super(ChangeCipherSpecMessage, self).__init__(
-            ContentType.CHANGE_CIPHER_SPEC
-        )
+        super(ChangeCipherSpecMessage,
+              self).__init__(ContentType.CHANGE_CIPHER_SPEC)
 
     def to_bytes(self):
         return struct.pack(">B", 1)
@@ -600,10 +588,10 @@
 
 
 class ApplicationDataMessage(Message):
+
     def __init__(self, raw):
-        super(ApplicationDataMessage, self).__init__(
-            ContentType.APPLICATION_DATA
-        )
+        super(ApplicationDataMessage,
+              self).__init__(ContentType.APPLICATION_DATA)
         self.raw = raw
         self.body = None
 
@@ -638,7 +626,6 @@
     HandshakeType.FINISHED: None,  # Finished
 }
 
-
 content_map = {
     ContentType.CHANGE_CIPHER_SPEC: ChangeCipherSpecMessage,
     ContentType.ALERT: AlertMessage,
@@ -665,11 +652,9 @@
                 raise ValueError("DTLS version error, expect DTLSv1.2")
 
             last_msg_is_change_cipher_spec = type(
-                self
-            ).last_msg_is_change_cipher_spec
+                self).last_msg_is_change_cipher_spec
             type(self).last_msg_is_change_cipher_spec = (
-                record.content_type == ContentType.CHANGE_CIPHER_SPEC
-            )
+                record.content_type == ContentType.CHANGE_CIPHER_SPEC)
 
             # FINISHED message immediately follows CHANGE_CIPHER_SPEC message
             # We skip FINISHED message as it is encrypted
diff --git a/tests/scripts/thread-cert/ipv6.py b/tests/scripts/thread-cert/ipv6.py
index 9e285de..fd7bb56 100644
--- a/tests/scripts/thread-cert/ipv6.py
+++ b/tests/scripts/thread-cert/ipv6.py
@@ -34,12 +34,13 @@
 from binascii import hexlify
 from ipaddress import ip_address
 
+import common
+
 try:
     from itertools import izip_longest as zip_longest
 except ImportError:
     from itertools import zip_longest
 
-
 # Next headers for IPv6 protocols
 IPV6_NEXT_HEADER_HOP_BY_HOP = 0
 IPV6_NEXT_HEADER_TCP = 6
@@ -96,7 +97,6 @@
 
 
 class PacketFactory(object):
-
     """ Interface for classes that produce objects from data. """
 
     def parse(self, data, message_info):
@@ -111,7 +111,6 @@
 
 
 class BuildableFromBytes(object):
-
     """ Interface for classes which can be built from bytes. """
 
     @classmethod
@@ -126,7 +125,6 @@
 
 
 class ConvertibleToBytes(object):
-
     """ Interface for classes which can be converted to bytes. """
 
     def to_bytes(self):
@@ -147,7 +145,6 @@
 
 
 class Header(object):
-
     """ Interface for header classes. """
 
     __metaclass__ = abc.ABCMeta
@@ -162,7 +159,6 @@
 
 
 class ExtensionHeader(object):
-
     """ Base for classes representing Extension Headers in IPv6 packets. """
 
     def __init__(self, next_header, hdr_ext_len=0):
@@ -171,7 +167,6 @@
 
 
 class UpperLayerProtocol(Header, ConvertibleToBytes):
-
     """ Base for classes representing upper layer protocol payload in IPv6 packets. """
 
     def __init__(self, header):
@@ -200,7 +195,6 @@
 
 
 class IPv6PseudoHeader(ConvertibleToBytes):
-
     """ Class representing IPv6 pseudo header which is required to calculate
     upper layer protocol (like e.g. UDP or ICMPv6) checksum.
 
@@ -208,13 +202,11 @@
 
     """
 
-    def __init__(
-        self, source_address, destination_address, payload_length, next_header
-    ):
+    def __init__(self, source_address, destination_address, payload_length,
+                 next_header):
         self._source_address = self._convert_to_ipaddress(source_address)
         self._destination_address = self._convert_to_ipaddress(
-            destination_address
-        )
+            destination_address)
         self.payload_length = payload_length
         self.next_header = next_header
 
@@ -251,7 +243,6 @@
 
 
 class IPv6Header(ConvertibleToBytes, BuildableFromBytes):
-
     """ Class representing IPv6 packet header. """
 
     _version = 6
@@ -271,8 +262,7 @@
         self.version = self._version
         self._source_address = self._convert_to_ipaddress(source_address)
         self._destination_address = self._convert_to_ipaddress(
-            destination_address
-        )
+            destination_address)
         self.traffic_class = traffic_class
         self.flow_label = flow_label
         self.hop_limit = hop_limit
@@ -298,16 +288,13 @@
         return self._destination_address
 
     def to_bytes(self):
-        data = bytearray(
-            [
-                ((self.version & 0x0F) << 4)
-                | ((self.traffic_class >> 4) & 0x0F),
-                ((self.traffic_class & 0x0F) << 4)
-                | ((self.flow_label >> 16) & 0x0F),
-                ((self.flow_label >> 8) & 0xff),
-                ((self.flow_label & 0xff)),
-            ]
-        )
+        data = bytearray([
+            ((self.version & 0x0F) << 4) | ((self.traffic_class >> 4) & 0x0F),
+            ((self.traffic_class & 0x0F) << 4) |
+            ((self.flow_label >> 16) & 0x0F),
+            ((self.flow_label >> 8) & 0xff),
+            ((self.flow_label & 0xff)),
+        ])
         data += struct.pack(">H", self.payload_length)
         data += bytearray([self.next_header, self.hop_limit])
         data += self.source_address.packed
@@ -356,7 +343,6 @@
 
 
 class IPv6Packet(ConvertibleToBytes):
-
     """ Class representing IPv6 packet.
 
     IPv6 packet consists of IPv6 header, optional extension header, and upper layer protocol.
@@ -402,16 +388,16 @@
 
     """
 
-    def __init__(
-        self, ipv6_header, upper_layer_protocol, extension_headers=None
-    ):
+    def __init__(self,
+                 ipv6_header,
+                 upper_layer_protocol,
+                 extension_headers=None):
         self.ipv6_header = ipv6_header
 
         self.upper_layer_protocol = upper_layer_protocol
 
-        self.extension_headers = (
-            extension_headers if extension_headers is not None else []
-        )
+        self.extension_headers = (extension_headers
+                                  if extension_headers is not None else [])
 
         self._update_next_header_values_in_headers()
 
@@ -422,22 +408,17 @@
         checksum = self.calculate_checksum()
 
         if self.upper_layer_protocol.checksum != checksum:
-            raise RuntimeError(
-                "Could not create IPv6 packet. "
-                "Invalid checksum: {}!={}".format(
-                    self.upper_layer_protocol.checksum, checksum
-                )
-            )
+            raise RuntimeError("Could not create IPv6 packet. "
+                               "Invalid checksum: {}!={}".format(
+                                   self.upper_layer_protocol.checksum,
+                                   checksum))
 
         self.upper_layer_protocol.checksum = checksum
 
     def _update_payload_length_value_in_ipv6_header(self):
-        self.ipv6_header.payload_length = len(self.upper_layer_protocol) + sum(
-            [
-                len(extension_header)
-                for extension_header in self.extension_headers
-            ]
-        )
+        self.ipv6_header.payload_length = len(self.upper_layer_protocol) + sum([
+            len(extension_header) for extension_header in self.extension_headers
+        ])
 
     def _update_next_header_values_in_headers(self):
         last_header = self.ipv6_header
@@ -464,9 +445,8 @@
             self.upper_layer_protocol.type,
         )
 
-        return calculate_checksum(
-            pseudo_header.to_bytes() + upper_layer_protocol_bytes
-        )
+        return calculate_checksum(pseudo_header.to_bytes() +
+                                  upper_layer_protocol_bytes)
 
     def to_bytes(self):
         self._update_payload_length_value_in_ipv6_header()
@@ -484,12 +464,10 @@
 
     def __repr__(self):
         return "IPv6Packet(header={}, upper_layer_protocol={})".format(
-            self.ipv6_header, self.upper_layer_protocol
-        )
+            self.ipv6_header, self.upper_layer_protocol)
 
 
 class UDPHeader(ConvertibleToBytes, BuildableFromBytes):
-
     """ Class representing UDP datagram header.
 
     This header is required to construct UDP datagram.
@@ -539,7 +517,6 @@
 
 
 class UDPDatagram(UpperLayerProtocol):
-
     """ Class representing UDP datagram.
 
     UDP is an upper layer protocol for IPv6 so it can be passed to IPv6 packet as upper_layer_protocol.
@@ -576,7 +553,6 @@
 
 
 class ICMPv6Header(ConvertibleToBytes, BuildableFromBytes):
-
     """ Class representing ICMPv6 message header.
 
     This header is required to construct ICMPv6 message.
@@ -593,8 +569,7 @@
 
     def to_bytes(self):
         return bytearray([self.type, self.code]) + struct.pack(
-            ">H", self.checksum
-        )
+            ">H", self.checksum)
 
     @classmethod
     def from_bytes(cls, data):
@@ -609,7 +584,6 @@
 
 
 class ICMPv6(UpperLayerProtocol):
-
     """ Class representing ICMPv6 message.
 
     ICMPv6 is an upper layer protocol for IPv6 so it can be passed to IPv6 packet as upper_layer_protocol.
@@ -640,7 +614,6 @@
 
 
 class FragmentHeader(ExtensionHeader):
-
     """ Class representing Fragment extension header.
 
     +-------------+----------+-----------------+-----+---+----------------+
@@ -653,6 +626,7 @@
         - more_flag to indicate further data (1 bit)
         - identification for all associated fragments (32 bit)
     """
+
     @property
     def type(self):
         return 44
@@ -669,7 +643,11 @@
     def offset(self):
         return self._fragm_offset
 
-    def __init__(self, next_header=None, fragm_offset=0, more_flag=False, identification=0):
+    def __init__(self,
+                 next_header=None,
+                 fragm_offset=0,
+                 more_flag=False,
+                 identification=0):
         super(FragmentHeader, self).__init__(next_header, 0)
         self._fragm_offset = fragm_offset
         self._more_flag = more_flag
@@ -680,7 +658,10 @@
 
     def to_bytes(self):
         data = bytearray([self.next_header, 0x00])
-        data += bytearray([self._fragm_offset >> 5, ((self._fragm_offset << 3) | self._more_flag) & 0xff])
+        data += bytearray([
+            self._fragm_offset >> 5,
+            ((self._fragm_offset << 3) | self._more_flag) & 0xff
+        ])
         data += struct.pack(">I", self._identification)
 
         return data
@@ -688,7 +669,7 @@
     @classmethod
     def from_bytes(cls, data):
         next_header = struct.unpack(">B", data.read(1))[0]
-        struct.unpack(">B", data.read(1))[0]    # reserved
+        struct.unpack(">B", data.read(1))[0]  # reserved
         fragment_offset = struct.unpack(">H", data.read(2))[0]
         more_flag = fragment_offset & 0x1
         identificaton = struct.unpack(">I", data.read(4))[0]
@@ -702,7 +683,6 @@
 
 
 class HopByHop(ExtensionHeader):
-
     """ Class representing HopByHop extension header.
 
     HopByHop extension header consists of:
@@ -782,7 +762,6 @@
 
 
 class HopByHopOptionHeader(ConvertibleToBytes, BuildableFromBytes):
-
     """ Class representing HopByHop option header. """
 
     _header_length = 2
@@ -805,12 +784,10 @@
 
     def __repr__(self):
         return "HopByHopOptionHeader(type={}, length={})".format(
-            self.type, self.length
-        )
+            self.type, self.length)
 
 
 class HopByHopOption(ConvertibleToBytes):
-
     """ Class representing HopByHop option.
 
     Class consists of two elements: HopByHopOptionHeader and value (e.g. for MPLOption).
@@ -838,12 +815,10 @@
 
     def __repr__(self):
         return "HopByHopOption(header={}, value={})".format(
-            self.header, self.value
-        )
+            self.header, self.value)
 
 
 class MPLOption(ConvertibleToBytes):
-
     """ Class representing MPL option. """
 
     _header_length = 2
@@ -858,11 +833,8 @@
         self.seed_id = seed_id
 
     def to_bytes(self):
-        smv = (
-            ((self.S & 0x03) << 6)
-            | ((self.M & 0x01) << 5)
-            | ((self.V & 0x01) << 4)
-        )
+        smv = (((self.S & 0x03) << 6) | ((self.M & 0x01) << 5) |
+               ((self.V & 0x01) << 4))
 
         return bytearray([smv, self.sequence]) + self.seed_id
 
@@ -884,12 +856,10 @@
 
     def __repr__(self):
         return "MPLOption(S={}, M={}, V={}, sequence={}, seed_id={})".format(
-            self.S, self.M, self.V, self.sequence, hexlify(self.seed_id)
-        )
+            self.S, self.M, self.V, self.sequence, hexlify(self.seed_id))
 
 
 class IPv6PacketFactory(PacketFactory):
-
     """ Factory that produces IPv6 packets from data.
 
     This factory must be initialized with factories which allow to parse extension headers and upper layer protocols.
@@ -950,20 +920,16 @@
             return self._ehf[next_header]
         except KeyError:
             raise RuntimeError(
-                "Could not get Extension Header factory for next_header={}.".format(
-                    next_header
-                )
-            )
+                "Could not get Extension Header factory for next_header={}.".
+                format(next_header))
 
     def _get_upper_layer_protocol_factory_for(self, next_header):
         try:
             return self._ulpf[next_header]
         except KeyError:
             raise RuntimeError(
-                "Could not get Upper Layer Protocol factory for next_header={}.".format(
-                    next_header
-                )
-            )
+                "Could not get Upper Layer Protocol factory for next_header={}."
+                .format(next_header))
 
     def _parse_extension_headers(self, data, next_header, message_info):
         extension_headers = []
@@ -991,34 +957,31 @@
         message_info.destination_ipv6 = ipv6_header.destination_address
 
         next_header, extension_headers = self._parse_extension_headers(
-            data, ipv6_header.next_header, message_info
-        )
+            data, ipv6_header.next_header, message_info)
 
         upper_layer_protocol = self._parse_upper_layer_protocol(
-            data, next_header, message_info
-        )
+            data, next_header, message_info)
 
         return IPv6Packet(ipv6_header, upper_layer_protocol, extension_headers)
 
 
 class HopByHopOptionsFactory(object):
-
     """ Factory that produces HopByHop options. """
 
     _one_byte_padding = 0x00
     _many_bytes_padding = 0x01
 
     def __init__(self, options_factories=None):
-        self._options_factories = (
-            options_factories if options_factories is not None else {}
-        )
+        self._options_factories = (options_factories
+                                   if options_factories is not None else {})
 
     def _get_HopByHopOption_value_factory(self, _type):
         try:
             return self._options_factories[_type]
         except KeyError:
             raise RuntimeError(
-                "Could not find HopByHopOption value factory for type={}.".format(_type))
+                "Could not find HopByHopOption value factory for type={}.".
+                format(_type))
 
     def parse(self, data, message_info):
         options = []
@@ -1036,8 +999,7 @@
 
             else:
                 factory = self._get_HopByHopOption_value_factory(
-                    option_header.type
-                )
+                    option_header.type)
 
                 option_data = data.read(option_header.length)
 
@@ -1052,7 +1014,6 @@
 
 
 class HopByHopFactory(PacketFactory):
-
     """ Factory that produces HopByHop extension headers from data. """
 
     def __init__(self, hop_by_hop_options_factory):
@@ -1069,14 +1030,12 @@
         # Note! Two bytes were read (next_header and hdr_ext_len) so they must
         # be substracted from header length
         hop_by_hop_length = (
-            self._calculate_extension_header_length(hdr_ext_len) - 2
-        )
+            self._calculate_extension_header_length(hdr_ext_len) - 2)
 
         hop_by_hop_data = data.read(hop_by_hop_length)
 
         options = self._hop_by_hop_options_factory.parse(
-            io.BytesIO(hop_by_hop_data), message_info
-        )
+            io.BytesIO(hop_by_hop_data), message_info)
 
         hop_by_hop = HopByHop(next_header, options, hdr_ext_len)
 
@@ -1086,7 +1045,6 @@
 
 
 class MPLOptionFactory(PacketFactory):
-
     """ Factory that produces MPL options for HopByHop extension header. """
 
     def parse(self, data, message_info):
@@ -1094,7 +1052,6 @@
 
 
 class UDPHeaderFactory:
-
     """ Factory that produces UDP header. """
 
     def parse(self, data, message_info):
@@ -1104,7 +1061,6 @@
 class UdpBasedOnSrcDstPortsPayloadFactory:
 
     # TODO: Unittests
-
     """ Factory that produces UDP payload. """
 
     def __init__(self, src_dst_port_based_payload_factories):
@@ -1125,7 +1081,10 @@
         if message_info.src_port in self._factories:
             factory = self._factories[message_info.src_port]
 
-        if factory is None:
+        if message_info.dst_port == common.UDP_TEST_PORT:
+            # Ignore traffic targeted to test port
+            return None
+        elif factory is None:
             raise RuntimeError("Could not find factory to build UDP payload.")
 
         return factory.parse(data, message_info)
@@ -1134,7 +1093,6 @@
 class UDPDatagramFactory(PacketFactory):
 
     # TODO: Unittests
-
     """ Factory that produces UDP datagrams. """
 
     def __init__(self, udp_header_factory, udp_payload_factory):
@@ -1145,9 +1103,8 @@
         header = self._udp_header_factory.parse(data, message_info)
 
         # Update message payload length: UDP header (8B) + payload length
-        message_info.payload_length += len(header) + (
-            len(data.getvalue()) - data.tell()
-        )
+        message_info.payload_length += len(header) + (len(data.getvalue()) -
+                                                      data.tell())
 
         message_info.src_port = header.src_port
         message_info.dst_port = header.dst_port
@@ -1158,13 +1115,11 @@
 
 
 class ICMPv6Factory(PacketFactory):
-
     """ Factory that produces ICMPv6 messages from data. """
 
     def __init__(self, body_factories=None):
-        self._body_factories = (
-            body_factories if body_factories is not None else {}
-        )
+        self._body_factories = (body_factories
+                                if body_factories is not None else {})
 
     def _get_icmpv6_body_factory(self, _type):
         try:
@@ -1174,15 +1129,12 @@
             if "default" not in self._body_factories:
                 raise RuntimeError(
                     "Could not find specialized factory to parse ICMP body. "
-                    "Unsupported ICMP type: {}".format(_type)
-                )
+                    "Unsupported ICMP type: {}".format(_type))
 
             default_factory = self._body_factories["default"]
 
-            print(
-                "Could not find specialized factory to parse ICMP body. "
-                "Take the default one: {}".format(type(default_factory))
-            )
+            print("Could not find specialized factory to parse ICMP body. "
+                  "Take the default one: {}".format(type(default_factory)))
 
             return default_factory
 
@@ -1191,15 +1143,13 @@
 
         factory = self._get_icmpv6_body_factory(header.type)
 
-        message_info.payload_length += len(header) + (
-            len(data.getvalue()) - data.tell()
-        )
+        message_info.payload_length += len(header) + (len(data.getvalue()) -
+                                                      data.tell())
 
         return ICMPv6(header, factory.parse(data, message_info))
 
 
 class ICMPv6EchoBodyFactory(PacketFactory):
-
     """ Factory that produces ICMPv6 echo message body. """
 
     def parse(self, data, message_info):
@@ -1207,7 +1157,6 @@
 
 
 class BytesPayload(ConvertibleToBytes, BuildableFromBytes):
-
     """ Class representing bytes payload. """
 
     def __init__(self, data):
@@ -1225,7 +1174,6 @@
 
 
 class BytesPayloadFactory(PacketFactory):
-
     """ Factory that produces bytes payload. """
 
     def parse(self, data, message_info):
@@ -1233,7 +1181,6 @@
 
 
 class ICMPv6EchoBody(ConvertibleToBytes, BuildableFromBytes):
-
     """ Class representing body of ICMPv6 echo messages. """
 
     _header_length = 4
@@ -1261,7 +1208,6 @@
 
 
 class ICMPv6DestinationUnreachableFactory(PacketFactory):
-
     """ Factory that produces ICMPv6 echo message body. """
 
     def parse(self, data, message_info):
@@ -1269,7 +1215,6 @@
 
 
 class ICMPv6DestinationUnreachable(ConvertibleToBytes, BuildableFromBytes):
-
     """ Class representing body of ICMPv6 Destination Unreachable messages. """
 
     _header_length = 4
diff --git a/tests/scripts/thread-cert/lowpan.py b/tests/scripts/thread-cert/lowpan.py
index 01fac90..6dac3a9 100644
--- a/tests/scripts/thread-cert/lowpan.py
+++ b/tests/scripts/thread-cert/lowpan.py
@@ -116,7 +116,16 @@
 
     def __repr__(self):
         return "LowpanIPHC(tf={}, nh={}, hlim={}, cid={}, sac={}, sam={}, m={}, dac={}, dam={})".format(
-            self.tf, self.nh, self.hlim, self.cid, self.sac, self.sam, self.m, self.dac, self.dam, )
+            self.tf,
+            self.nh,
+            self.hlim,
+            self.cid,
+            self.sac,
+            self.sam,
+            self.m,
+            self.dac,
+            self.dam,
+        )
 
 
 class LowpanNHC:
@@ -201,7 +210,6 @@
 
 
 class LowpanHopByHopFactory:
-
     """ Factory that produces HopByHop extension header. """
 
     def __init__(self, hop_by_hop_options_factory):
@@ -213,8 +221,7 @@
         ext_header_data = data.read(ext_header_length)
 
         options = self._hop_by_hop_options_factory.parse(
-            io.BytesIO(ext_header_data), message_info
-        )
+            io.BytesIO(ext_header_data), message_info)
 
         ext_header = ipv6.HopByHop(next_header, options)
 
@@ -224,7 +231,6 @@
 
 
 class LowpanExtensionHeadersFactory:
-
     """ Factory that produces extension headers. """
 
     NHC_NH_INLINE = 0
@@ -232,8 +238,7 @@
 
     def __init__(self, ext_headers_factories):
         self._ext_headers_factories = (
-            ext_headers_factories if ext_headers_factories is not None else {}
-        )
+            ext_headers_factories if ext_headers_factories is not None else {})
 
     def _decompress_nh(self, hc, data):
         if hc.nh == self.NHC_NH_INLINE:
@@ -248,10 +253,8 @@
 
         except BaseException:
             raise RuntimeError(
-                "Could not find an extension header factory for the EID type: {}".format(
-                    eid
-                )
-            )
+                "Could not find an extension header factory for the EID type: {}"
+                .format(eid))
 
     def parse(self, data, message_info):
         nhc = LowpanNHC.from_bytes(bytearray(data.read(1)))
@@ -264,7 +267,6 @@
 
 
 class LowpanUdpHeaderFactory:
-
     """ Factory producing UDP header. """
 
     UDP_HC_C_INLINE = 0
@@ -317,6 +319,7 @@
 
 
 class Context:
+
     def __init__(self, prefix, prefix_length=None):
         if isinstance(prefix, str):
             prefix, prefix_length = prefix.split("/")
@@ -329,19 +332,16 @@
 
         elif isinstance(prefix, bytearray):
             self._prefix = prefix
-            self._prefix_length = (
-                prefix_length
-                if prefix_length is not None
-                else len(self._prefix) * 8
-            )
+            self._prefix_length = (prefix_length if prefix_length is not None
+                                   else len(self._prefix) * 8)
 
     @property
     def prefix(self):
-        return self._prefix[: self.prefix_length_all_bytes]
+        return self._prefix[:self.prefix_length_all_bytes]
 
     @property
     def prefix_full_bytes(self):
-        return self._prefix[: self.prefix_length_full_bytes]
+        return self._prefix[:self.prefix_length_full_bytes]
 
     @property
     def prefix_length(self):
@@ -364,16 +364,13 @@
 
 
 class ContextManager(dict):
-
     """ Class representing Context Manager. """
 
     def __check_index(self, index):
         if index < 0 or index > 15:
             raise IndexError(
                 "Invalid index: {}. Valid index is in range [0, 15]".format(
-                    index
-                )
-            )
+                    index))
 
     def __check_type(self, value):
         if not isinstance(value, Context):
@@ -392,12 +389,10 @@
 
 
 class LowpanIpv6HeaderFactory:
-
     """ Factory that produces IPv6 header. """
 
     IPV6_LINKLOCAL_PREFIX = bytearray(
-        [0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
-    )
+        [0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
 
     SHORT_ADDR_PADDING_BYTES = bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00])
 
@@ -551,11 +546,8 @@
             return self.IPV6_LINKLOCAL_PREFIX + bytearray(data.read(8))
 
         elif iphc.sam == self.IPHC_SAM_16B:
-            return (
-                self.IPV6_LINKLOCAL_PREFIX
-                + self.SHORT_ADDR_PADDING_BYTES
-                + bytearray(data.read(2))
-            )
+            return (self.IPV6_LINKLOCAL_PREFIX + self.SHORT_ADDR_PADDING_BYTES +
+                    bytearray(data.read(2)))
 
         elif iphc.sam == self.IPHC_SAM_ELIDED:
             return self.IPV6_LINKLOCAL_PREFIX + src_mac_addr.convert_to_iid()
@@ -596,11 +588,9 @@
                 address_overlapping_byte = address_bytes[-required_bytes]
 
                 overlapping_byte = prefix_overlapping_byte & ~(
-                    0xff >> prefix_length_rest_bits
-                )
+                    0xff >> prefix_length_rest_bits)
                 overlapping_byte |= address_overlapping_byte & (
-                    0xff >> prefix_length_rest_bits
-                )
+                    0xff >> prefix_length_rest_bits)
 
                 src_addr += bytearray([overlapping_byte])
                 required_bytes -= 1
@@ -612,11 +602,8 @@
             required_bytes -= prefix_length_all_bytes
             required_bytes -= len(address_bytes)
 
-            src_addr = (
-                prefix[:prefix_length_all_bytes]
-                + bytearray([0x00] * required_bytes)
-                + address_bytes
-            )
+            src_addr = (prefix[:prefix_length_all_bytes] +
+                        bytearray([0x00] * required_bytes) + address_bytes)
 
         return src_addr
 
@@ -636,8 +623,7 @@
         elif iphc.sam == self.IPHC_SAM_16B:
             context = self._context_manager[sci]
             address_bytes = self.SHORT_ADDR_PADDING_BYTES + bytearray(
-                data.read(2)
-            )
+                data.read(2))
 
             return self._merge_prefix_with_address(
                 prefix=context.prefix,
@@ -656,14 +642,11 @@
 
     def _decompress_src_addr(self, iphc, src_mac_addr, sci, data):
         if iphc.sac == self.IPHC_SAC_STATELESS:
-            return self._decompress_src_addr_stateless(
-                iphc, src_mac_addr, data
-            )
+            return self._decompress_src_addr_stateless(iphc, src_mac_addr, data)
 
         elif iphc.sac == self.IPHC_SAC_STATEFUL:
-            return self._decompress_src_addr_stateful(
-                iphc, src_mac_addr, sci, data
-            )
+            return self._decompress_src_addr_stateful(iphc, src_mac_addr, sci,
+                                                      data)
 
     def _decompress_unicast_dst_addr_stateless(self, iphc, dst_mac_addr, data):
         if iphc.dam == self.IPHC_DAM_128B:
@@ -673,18 +656,14 @@
             return self.IPV6_LINKLOCAL_PREFIX + bytearray(data.read(8))
 
         elif iphc.dam == self.IPHC_DAM_16B:
-            return (
-                self.IPV6_LINKLOCAL_PREFIX
-                + self.SHORT_ADDR_PADDING_BYTES
-                + bytearray(data.read(2))
-            )
+            return (self.IPV6_LINKLOCAL_PREFIX + self.SHORT_ADDR_PADDING_BYTES +
+                    bytearray(data.read(2)))
 
         elif iphc.dam == self.IPHC_DAM_ELIDED:
             return self.IPV6_LINKLOCAL_PREFIX + dst_mac_addr.convert_to_iid()
 
-    def _decompress_unicast_dst_addr_stateful(
-        self, iphc, dst_mac_addr, dci, data
-    ):
+    def _decompress_unicast_dst_addr_stateful(self, iphc, dst_mac_addr, dci,
+                                              data):
         if iphc.dam == self.IPHC_DAM_128B:
             raise RuntimeError("Reserved")
 
@@ -700,8 +679,7 @@
         elif iphc.dam == self.IPHC_DAM_16B:
             context = self._context_manager[dci]
             address_bytes = self.SHORT_ADDR_PADDING_BYTES + bytearray(
-                data.read(2)
-            )
+                data.read(2))
 
             return self._merge_prefix_with_address(
                 prefix=context.prefix,
@@ -721,13 +699,11 @@
     def _decompress_unicast_dst_addr(self, iphc, dst_mac_addr, dci, data):
         if iphc.dac == self.IPHC_DAC_STATELESS:
             return self._decompress_unicast_dst_addr_stateless(
-                iphc, dst_mac_addr, data
-            )
+                iphc, dst_mac_addr, data)
 
         elif iphc.dac == self.IPHC_DAC_STATEFUL:
             return self._decompress_unicast_dst_addr_stateful(
-                iphc, dst_mac_addr, dci, data
-            )
+                iphc, dst_mac_addr, dci, data)
 
     def _decompress_multicast_dst_addr_stateless(self, iphc, data):
         if iphc.dam == self.IPHC_DAM_128B:
@@ -735,24 +711,17 @@
 
         elif iphc.dam == self.IPHC_DAM_48B:
             addr48b = bytearray(data.read(6))
-            return (
-                bytearray([0xff, addr48b[0]])
-                + bytearray([0x00] * 9)
-                + addr48b[1:]
-            )
+            return (bytearray([0xff, addr48b[0]]) + bytearray([0x00] * 9) +
+                    addr48b[1:])
 
         elif iphc.dam == self.IPHC_DAM_32B:
             addr32b = bytearray(data.read(4))
-            return (
-                bytearray([0xff, addr32b[0]])
-                + bytearray([0x00] * 11)
-                + addr32b[1:]
-            )
+            return (bytearray([0xff, addr32b[0]]) + bytearray([0x00] * 11) +
+                    addr32b[1:])
 
         elif iphc.dam == self.IPHC_DAM_8B:
-            return (
-                bytearray([0xff, 0x02]) + bytearray([0x00] * 13) + data.read(1)
-            )
+            return (bytearray([0xff, 0x02]) + bytearray([0x00] * 13) +
+                    data.read(1))
 
     def _decompress_multicast_dst_addr_stateful(self, iphc, dci, data):
         if iphc.dam == self.IPHC_M_DAM_00:
@@ -770,13 +739,8 @@
             if missing_bytes > 0:
                 prefix += bytearray([0x00] * missing_bytes)
 
-            return (
-                bytearray([0xff])
-                + addr48b[:2]
-                + bytearray([prefix_length])
-                + prefix
-                + addr48b[2:]
-            )
+            return (bytearray([0xff]) + addr48b[:2] +
+                    bytearray([prefix_length]) + prefix + addr48b[2:])
 
         elif iphc.dam == self.IPHC_M_DAM_01:
             raise RuntimeError("Reserved")
@@ -792,15 +756,12 @@
             return self._decompress_multicast_dst_addr_stateless(iphc, data)
 
         elif iphc.dac == self.IPHC_DAC_STATEFUL:
-            return self._decompress_multicast_dst_addr_stateful(
-                iphc, dci, data
-            )
+            return self._decompress_multicast_dst_addr_stateful(iphc, dci, data)
 
     def _decompress_dst_addr(self, iphc, dst_mac_addr, dci, data):
         if iphc.m == self.IPHC_M_NO:
-            return self._decompress_unicast_dst_addr(
-                iphc, dst_mac_addr, dci, data
-            )
+            return self._decompress_unicast_dst_addr(iphc, dst_mac_addr, dci,
+                                                     data)
 
         elif iphc.m == self.IPHC_M_YES:
             return self._decompress_multicast_dst_addr(iphc, dci, data)
@@ -819,17 +780,15 @@
 
         hop_limit = self._decompress_hlim(iphc, data)
 
-        src_address = self._decompress_src_addr(
-            iphc, message_info.source_mac_address, sci, data
-        )
+        src_address = self._decompress_src_addr(iphc,
+                                                message_info.source_mac_address,
+                                                sci, data)
 
         dst_address = self._decompress_dst_addr(
-            iphc, message_info.destination_mac_address, dci, data
-        )
+            iphc, message_info.destination_mac_address, dci, data)
 
-        header = ipv6.IPv6Header(
-            src_address, dst_address, traffic_class, flow_label, hop_limit
-        )
+        header = ipv6.IPv6Header(src_address, dst_address, traffic_class,
+                                 flow_label, hop_limit)
 
         header.next_header = next_header
 
@@ -837,7 +796,6 @@
 
 
 class LowpanDecompressor:
-
     """ Class decompressing 6LoWPAN packets. """
 
     def __init__(
@@ -848,8 +806,7 @@
     ):
         self._lowpan_ip_header_factory = lowpan_ip_header_factory
         self._lowpan_extension_headers_factory = (
-            lowpan_extension_headers_factory
-        )
+            lowpan_extension_headers_factory)
         self._lowpan_udp_header_factory = lowpan_udp_header_factory
 
     def _is_ipv6_extension_header(self, header_first_byte):
@@ -897,8 +854,7 @@
 
                 elif self._is_udp_header(header_first_byte):
                     udp_header = self._lowpan_udp_header_factory.parse(
-                        data, message_info
-                    )
+                        data, message_info)
 
                     # Update next header field in the previous header
                     previous_header.next_header = udp_header.type
@@ -910,12 +866,10 @@
 
 
 class LowpanMeshHeader(object):
-
     """ Class representing 6LoWPAN mesh header (RFC 4944 5.2). """
 
-    def __init__(
-        self, hops_left, originator_address, final_destination_address
-    ):
+    def __init__(self, hops_left, originator_address,
+                 final_destination_address):
         self._hops_left = hops_left
         self._originator_address = originator_address
         self._final_destination_address = final_destination_address
@@ -934,6 +888,7 @@
 
 
 class LowpanMeshHeaderFactory:
+
     def _parse_address(self, data, is_short):
         if is_short:
             return common.MacAddress.from_rloc16(bytearray(data.read(2)))
@@ -951,19 +906,17 @@
         else:
             hops_left = ord(data.read(1))
 
-        originator_address = self._parse_address(
-            data, is_short_originator_address
-        )
+        originator_address = self._parse_address(data,
+                                                 is_short_originator_address)
         final_destination_address = self._parse_address(
-            data, is_short_final_destination_address
-        )
+            data, is_short_final_destination_address)
 
-        return LowpanMeshHeader(
-            hops_left, originator_address, final_destination_address
-        )
+        return LowpanMeshHeader(hops_left, originator_address,
+                                final_destination_address)
 
 
 class LowpanFragmentationHeader(object):
+
     def __init__(self, datagram_size, datagram_tag, datagram_offset=0):
         self._datagram_size = datagram_size
         self._datagram_tag = datagram_tag
@@ -1001,6 +954,7 @@
 
 
 class LowpanFragmentsBuffer(object):
+
     def __init__(self, buffer_size):
         self._buffer = [None] * buffer_size
         self._position = 0
@@ -1034,8 +988,7 @@
     def read(self):
         if not self.whole_packet_received():
             raise ValueError(
-                "Only a part of the packet has been stored in the buffer."
-            )
+                "Only a part of the packet has been stored in the buffer.")
 
         return bytearray(self._buffer)
 
@@ -1044,33 +997,31 @@
 
 
 class LowpanFragmentsBuffersManager(object):
+
     def __init__(self):
         self._fragments_buffers = {}
 
     def _create_key(self, message_info, datagram_tag):
-        key = (
-            bytes(message_info.source_mac_address.mac_address)
-            + bytes(message_info.destination_mac_address.mac_address)
-            + bytes(datagram_tag)
-        )
+        key = (bytes(message_info.source_mac_address.mac_address) +
+               bytes(message_info.destination_mac_address.mac_address) +
+               bytes(datagram_tag))
         return key
 
     def _allocate_fragments_buffer(self, key, datagram_size):
         if datagram_size is None or datagram_size < 0:
             raise ValueError(
-                "Could not allocate fragments buffer. Invalid datagram size: {}".format(
-                    datagram_size
-                )
-            )
+                "Could not allocate fragments buffer. Invalid datagram size: {}"
+                .format(datagram_size))
 
         fragments_buffer = LowpanFragmentsBuffer(datagram_size)
 
         self._fragments_buffers[key] = fragments_buffer
         return fragments_buffer
 
-    def get_fragments_buffer(
-        self, message_info, datagram_tag, datagram_size=None
-    ):
+    def get_fragments_buffer(self,
+                             message_info,
+                             datagram_tag,
+                             datagram_size=None):
         key = self._create_key(message_info, datagram_tag)
 
         if key not in self._fragments_buffers:
@@ -1085,6 +1036,7 @@
 
 
 class LowpanParser(object):
+
     def __init__(
         self,
         lowpan_mesh_header_factory,
@@ -1095,8 +1047,7 @@
         self._lowpan_mesh_header_factory = lowpan_mesh_header_factory
         self._lowpan_decompressor = lowpan_decompressor
         self._lowpan_fragments_buffers_manager = (
-            lowpan_fragements_buffers_manager
-        )
+            lowpan_fragements_buffers_manager)
         self._ipv6_packet_factory = ipv6_packet_factory
 
     def _peek_n_bytes(self, data, n):
@@ -1129,15 +1080,13 @@
         )
 
         ipv6_header, extension_headers, udp_header = self._decompress_iphc(
-            data, message_info
-        )
+            data, message_info)
 
         uncompressed_data = data.read()
 
         # Update payload lengths
         ipv6_header.payload_length = fragmentation_header.datagram_size - len(
-            ipv6_header
-        )
+            ipv6_header)
 
         fragments_buffer.seek(0)
         fragments_buffer.write(ipv6_header.to_bytes())
@@ -1154,8 +1103,7 @@
             data = io.BytesIO(fragments_buffer.read())
 
             self._lowpan_fragments_buffers_manager.free_fragments_buffer(
-                message_info, fragmentation_header.datagram_tag
-            )
+                message_info, fragmentation_header.datagram_tag)
 
             return self._ipv6_packet_factory.parse(data, message_info)
 
@@ -1179,8 +1127,7 @@
             data = io.BytesIO(fragments_buffer.read())
 
             self._lowpan_fragments_buffers_manager.free_fragments_buffer(
-                message_info, fragmentation_header.datagram_tag
-            )
+                message_info, fragmentation_header.datagram_tag)
 
             return self._ipv6_packet_factory.parse(data, message_info)
 
@@ -1188,8 +1135,7 @@
 
     def _handle_iphc_header(self, data, message_info):
         ipv6_header, extension_headers, udp_header = self._decompress_iphc(
-            data, message_info
-        )
+            data, message_info)
 
         uncompressed_data = data.read()
 
@@ -1209,9 +1155,8 @@
 
         decompressed_data = ipv6_header.to_bytes() + decompressed_data
 
-        return self._ipv6_packet_factory.parse(
-            io.BytesIO(decompressed_data), message_info
-        )
+        return self._ipv6_packet_factory.parse(io.BytesIO(decompressed_data),
+                                               message_info)
 
     def set_lowpan_context(self, cid, prefix):
         self._lowpan_decompressor.set_lowpan_context(cid, prefix)
@@ -1223,30 +1168,24 @@
 
             if self._is_mesh_header(first_byte):
                 mesh_header = self._lowpan_mesh_header_factory.parse(
-                    data, message_info
-                )
+                    data, message_info)
 
                 message_info.source_mac_address = (
-                    mesh_header.originator_address
-                )
+                    mesh_header.originator_address)
                 message_info.destination_mac_address = (
-                    mesh_header.final_destination_address
-                )
+                    mesh_header.final_destination_address)
 
             elif self._is_first_fragmentation_header(first_byte):
                 return self._handle_first_fragmentation_header(
-                    data, message_info
-                )
+                    data, message_info)
 
             elif self._is_subsequent_fragmentation_header(first_byte):
                 return self._handle_subsequent_fragmentation_header(
-                    data, message_info
-                )
+                    data, message_info)
 
             elif self._is_iphc(first_byte):
                 return self._handle_iphc_header(data, message_info)
 
             else:
                 raise RuntimeError(
-                    "Unsupported header type: 0x{:02x}".format(first_byte)
-                )
+                    "Unsupported header type: 0x{:02x}".format(first_byte))
diff --git a/tests/scripts/thread-cert/mac802154.py b/tests/scripts/thread-cert/mac802154.py
index 7d11760..ac9a8fa 100644
--- a/tests/scripts/thread-cert/mac802154.py
+++ b/tests/scripts/thread-cert/mac802154.py
@@ -26,7 +26,6 @@
 #  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #  POSSIBILITY OF SUCH DAMAGE.
 #
-
 """
     This module provides simple 802.15.4 MAC parser.
 """
@@ -43,8 +42,16 @@
 )
 
 
-class DeviceDescriptors:
+class KeyIdMode0Exception(Exception):
+    """
+    Raised when key id mode of packet is 0.
+    Such packet wouldn't be handled in test scripts,
+    but it's not abnormal behavior.
+    """
+    pass
 
+
+class DeviceDescriptors:
     """Class representing 802.15.4 Device Descriptors."""
 
     device_descriptors = {}
@@ -67,8 +74,8 @@
 
 
 class InformationElement:
-
     """Class representing 802.15.4 MAC Information Element."""
+
     def __init__(self, id, length, content):
         self._id = id
         self._length = length
@@ -88,7 +95,6 @@
 
 
 class MacHeader:
-
     """Class representing 802.15.4 MAC header."""
 
     class FrameType:
@@ -141,7 +147,6 @@
 
 
 class MacPayload:
-
     """Class representing 802.15.4 MAC payload."""
 
     def __init__(self, data):
@@ -149,7 +154,6 @@
 
 
 class MacFrame:
-
     """Class representing 802.15.4 MAC frame."""
 
     IEEE802154_HEADER_IE_TYPE_MASK = 0x8000
@@ -259,9 +263,8 @@
 
         data.seek(fcs_start)
         if aux_sec_header and aux_sec_header.security_level:
-            mic, payload_end = self._parse_mic(
-                data, aux_sec_header.security_level
-            )
+            mic, payload_end = self._parse_mic(data,
+                                               aux_sec_header.security_level)
         else:
             payload_end = fcs_start
             mic = None
@@ -272,22 +275,18 @@
         data.seek(cur_pos)
         while ie_present and cur_pos + 2 < payload_end:
             header_ie = struct.unpack("<H", data.read(2))[0]
-            id = (
-                header_ie & MacFrame.IEEE802154_HEADER_IE_ID_MASK
-            ) >> 7
+            id = (header_ie & MacFrame.IEEE802154_HEADER_IE_ID_MASK) >> 7
             # Currently, payload IE doesn't exist in the code. So only HT2 is required.
             # TODO: support HT1 when there are Payload IEs in our code
             assert id != MacFrame.IEEE802154_HEADER_IE_HT1, \
                 'Currently there should be no HT1!'
-            header_ie_length = (
-                header_ie & MacFrame.IEEE802154_HEADER_IE_LENGTH_MASK
-            )
+            header_ie_length = (header_ie &
+                                MacFrame.IEEE802154_HEADER_IE_LENGTH_MASK)
             assert cur_pos + 2 + header_ie_length <= payload_end, \
                 'Parsing Header IE error, IE id:{} length:{}'.format(id, header_ie_length)
             header_ie_content = data.read(header_ie_length)
             header_ie_list.append(
-                InformationElement(id, header_ie_length, header_ie_content)
-            )
+                InformationElement(id, header_ie_length, header_ie_content))
             cur_pos += 2 + header_ie_length
             if id == MacFrame.IEEE802154_HEADER_IE_HT2:
                 break
@@ -310,9 +309,7 @@
 
             if ie_present:
                 data.seek(header_ie_start)
-                extra_open_fields += data.read(
-                    header_ie_end - header_ie_start
-                )
+                extra_open_fields += data.read(header_ie_end - header_ie_start)
 
             message_info = MessageInfo()
             message_info.aux_sec_hdr = aux_sec_header
@@ -338,12 +335,10 @@
                 message_info.source_mac_address = src_address.mac_address
 
             sec_obj = CryptoEngine(
-                MacCryptoMaterialCreator(config.DEFAULT_MASTER_KEY)
-            )
+                MacCryptoMaterialCreator(config.DEFAULT_MASTER_KEY))
             self.payload = MacPayload(
-                bytearray(open_payload)
-                + sec_obj.decrypt(private_payload, mic, message_info)
-            )
+                bytearray(open_payload) +
+                sec_obj.decrypt(private_payload, mic, message_info))
 
         else:
             self.payload = MacPayload(payload)
@@ -372,14 +367,14 @@
 
     def _parse_address(self, data, mode):
         if mode == MacHeader.AddressMode.SHORT:
-            return MacAddress(
-                data.read(2), MacAddressType.SHORT, big_endian=False
-            )
+            return MacAddress(data.read(2),
+                              MacAddressType.SHORT,
+                              big_endian=False)
 
         if mode == MacHeader.AddressMode.EXTENDED:
-            return MacAddress(
-                data.read(8), MacAddressType.LONG, big_endian=False
-            )
+            return MacAddress(data.read(8),
+                              MacAddressType.LONG,
+                              big_endian=False)
 
         else:
             return None
@@ -391,11 +386,13 @@
         key_id_mode = (security_control & 0x18) >> 3
 
         if key_id_mode == 0:
-            key_id = data.read(9)
+            raise KeyIdMode0Exception
         elif key_id_mode == 1:
             key_id = data.read(1)
         elif key_id_mode == 2:
             key_id = data.read(5)
+        elif key_id_mode == 3:
+            key_id = data.read(9)
         else:
             pass
 
diff --git a/tests/scripts/thread-cert/mesh_cop.py b/tests/scripts/thread-cert/mesh_cop.py
index f5abcb1..3f2d1df 100644
--- a/tests/scripts/thread-cert/mesh_cop.py
+++ b/tests/scripts/thread-cert/mesh_cop.py
@@ -30,9 +30,11 @@
 from binascii import hexlify
 from enum import IntEnum
 import io
+import logging
 import struct
 
 from network_data import SubTlvsFactory
+from tlvs_parsing import UnknownTlvFactory
 import common
 
 
@@ -101,6 +103,7 @@
 
 # Channel TLV (0)
 class Channel(object):
+
     def __init__(self, channel_page, channel):
         self._channel_page = channel_page
         self._channel = channel
@@ -116,23 +119,20 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self._channel_page == other._channel_page
-            and self._channel == other.__channel
-        )
+        return (self._channel_page == other._channel_page and
+                self._channel == other.__channel)
 
     def __repr__(self):
         return 'Channel(channel_page={},channel={})'.format(
-            self._channel_page, self._channel
-        )
+            self._channel_page, self._channel)
 
     def to_hex(self):
-        return struct.pack(
-            '>BBBH', TlvType.CHANNEL, 3, self.channel_page, self.channel
-        )
+        return struct.pack('>BBBH', TlvType.CHANNEL, 3, self.channel_page,
+                           self.channel)
 
 
 class ChannelFactory(object):
+
     def parse(self, data, message_info):
         data_tp = struct.unpack('>BH', data.read(3))
         channel_page = data_tp[0]
@@ -155,6 +155,7 @@
 
 # ExtendedPanid TLV (2)
 class ExtendedPanid(object):
+
     def __init__(self, extended_panid):
         self._extended_panid = extended_panid
 
@@ -163,16 +164,15 @@
         return self._extended_panid
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other))
-            and self.extended_panid == other.extended_panid
-        )
+        return (isinstance(self, type(other)) and
+                self.extended_panid == other.extended_panid)
 
     def __repr__(self):
         return "ExtendedPanid(extended_panid={})".format(self.extended_panid)
 
 
 class ExtendedPanidFactory(object):
+
     def parse(self, data, message_info):
         extended_panid = struct.unpack(">Q", data.read(8))[0]
         return ExtendedPanid(extended_panid)
@@ -180,6 +180,7 @@
 
 # NetworkName TLV (3)
 class NetworkName(object):
+
     def __init__(self, network_name):
         self._network_name = network_name
 
@@ -188,16 +189,15 @@
         return self._network_name
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other))
-            and self.network_name == other.network_name
-        )
+        return (isinstance(self, type(other)) and
+                self.network_name == other.network_name)
 
     def __repr__(self):
         return "NetworkName(network_name={})".format(self.network_name)
 
 
 class NetworkNameFactory(object):
+
     def parse(self, data, message_info):
         len = message_info.length
         network_name = struct.unpack("{}s".format(10), data.read(len))[0]
@@ -258,6 +258,7 @@
 
 # Steering Data TLV (8)
 class SteeringData(object):
+
     def __init__(self, bloom_filter):
         self._bloom_filter = bloom_filter
 
@@ -272,18 +273,16 @@
 
     def __repr__(self):
         return "SteeringData(bloom_filter={})".format(
-            hexlify(self._bloom_filter)
-        )
+            hexlify(self._bloom_filter))
 
     def to_hex(self):
         bloom_filter_len = len(self.bloom_filter)
-        return (
-            struct.pack('>BB', TlvType.STEERING_DATA, bloom_filter_len)
-            + self.bloom_filter
-        )
+        return (struct.pack('>BB', TlvType.STEERING_DATA, bloom_filter_len) +
+                self.bloom_filter)
 
 
 class SteeringDataFactory:
+
     def parse(self, data, message_info):
         bloom_filter = data.read(message_info.length)
         return SteeringData(bloom_filter)
@@ -291,6 +290,7 @@
 
 # Border Agent Locator TLV (9)
 class BorderAgentLocator(object):
+
     def __init__(self, address):
         self._border_agent_locator = address
 
@@ -305,16 +305,15 @@
 
     def __repr__(self):
         return "BorderAgentLocator(rloc16={})".format(
-            hex(self._border_agent_locator)
-        )
+            hex(self._border_agent_locator))
 
     def to_hex(self):
-        return struct.pack(
-            '>BBH', TlvType.BORDER_AGENT_LOCATOR, 2, self.border_agent_locator
-        )
+        return struct.pack('>BBH', TlvType.BORDER_AGENT_LOCATOR, 2,
+                           self.border_agent_locator)
 
 
 class BorderAgentLocatorFactory:
+
     def parse(self, data, message_info):
         border_agent_locator = struct.unpack(">H", data.read(2))[0]
         return BorderAgentLocator(border_agent_locator)
@@ -322,6 +321,7 @@
 
 # CommissionerId TLV (10)
 class CommissionerId(object):
+
     def __init__(self, commissioner_id):
         self._commissioner_id = commissioner_id
 
@@ -333,12 +333,11 @@
         return self.commissioner_id == other.commissioner_id
 
     def __repr__(self):
-        return "CommissionerId(commissioner_id={})".format(
-            self.commissioner_id
-        )
+        return "CommissionerId(commissioner_id={})".format(self.commissioner_id)
 
 
 class CommissionerIdFactory(object):
+
     def parse(self, data, message_info):
         commissioner_id = data.getvalue().decode('utf-8')
         return CommissionerId(commissioner_id)
@@ -346,6 +345,7 @@
 
 # Commissioner Session ID TLV (11)
 class CommissionerSessionId(object):
+
     def __init__(self, commissioner_session_id):
         self._commissioner_session_id = commissioner_session_id
 
@@ -360,8 +360,7 @@
 
     def __repr__(self):
         return "CommissionerSessionId(commissioner_session_id={})".format(
-            self._commissioner_session_id
-        )
+            self._commissioner_session_id)
 
     def to_hex(self):
         return struct.pack(
@@ -373,6 +372,7 @@
 
 
 class CommissionerSessionIdFactory:
+
     def parse(self, data, message_info):
         session_id = struct.unpack(">H", data.read(2))[0]
         return CommissionerSessionId(session_id)
@@ -419,6 +419,7 @@
 
 # Commissioner UDP Port TLV (15)
 class CommissionerUdpPort(object):
+
     def __init__(self, udp_port):
         self._udp_port = udp_port
 
@@ -436,6 +437,7 @@
 
 
 class CommissionerUdpPortFactory:
+
     def parse(self, data, message_info):
         udp_port = struct.unpack(">H", data.read(2))[0]
         return CommissionerUdpPort(udp_port)
@@ -443,6 +445,7 @@
 
 # State TLV (16)
 class State(object):
+
     def __init__(self, state):
         self._state = state
 
@@ -458,6 +461,7 @@
 
 
 class StateFactory:
+
     def parse(self, data, message_info):
         state = ord(data.read(1))
         return State(state)
@@ -478,6 +482,7 @@
 
 # JoinerUdpPort TLV (18)
 class JoinerUdpPort(object):
+
     def __init__(self, udp_port):
         self._udp_port = udp_port
 
@@ -486,15 +491,15 @@
         return self._udp_port
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other)) and self.udp_port == other.udp_port
-        )
+        return (isinstance(self, type(other)) and
+                self.udp_port == other.udp_port)
 
     def __repr__(self):
         return "JoinerUdpPort(udp_port={})".format(self.udp_port)
 
 
 class JoinerUdpPortFactory(object):
+
     def parse(self, data, message_info):
         udp_port = struct.unpack(">H", data.read(2))[0]
         return JoinerUdpPort(udp_port)
@@ -541,6 +546,7 @@
 
 # ProvisioningURL TLV (32)
 class ProvisioningUrl(object):
+
     def __init__(self, url):
         self._url = url
 
@@ -553,6 +559,7 @@
 
 
 class ProvisioningUrlFactory:
+
     def parse(self, data, message_info):
         url = data.decode('utf-8')
         return ProvisioningUrl(url)
@@ -560,6 +567,7 @@
 
 # VendorName TLV (33)
 class VendorName(object):
+
     def __init__(self, vendor_name):
         self._vendor_name = vendor_name
 
@@ -575,6 +583,7 @@
 
 
 class VendorNameFactory:
+
     def parse(self, data, message_info):
         vendor_name = data.getvalue().decode('utf-8')
         return VendorName(vendor_name)
@@ -582,6 +591,7 @@
 
 # VendorModel TLV (34)
 class VendorModel(object):
+
     def __init__(self, vendor_model):
         self._vendor_model = vendor_model
 
@@ -597,6 +607,7 @@
 
 
 class VendorModelFactory:
+
     def parse(self, data, message_info):
         vendor_model = data.getvalue().decode('utf-8')
         return VendorModel(vendor_model)
@@ -604,6 +615,7 @@
 
 # VendorSWVersion TLV (35)
 class VendorSWVersion(object):
+
     def __init__(self, vendor_sw_version):
         self._vendor_sw_version = vendor_sw_version
 
@@ -615,12 +627,11 @@
         return self.vendor_sw_version == other.vendor_sw_version
 
     def __repr__(self):
-        return "VendorName(vendor_sw_version={})".format(
-            self.vendor_sw_version
-        )
+        return "VendorName(vendor_sw_version={})".format(self.vendor_sw_version)
 
 
 class VendorSWVersionFactory:
+
     def parse(self, data, message_info):
         vendor_sw_version = data.getvalue()
         return VendorSWVersion(vendor_sw_version)
@@ -628,6 +639,7 @@
 
 # VendorData TLV (36)
 class VendorData(object):
+
     def __init__(self, data):
         self._vendor_data = data
 
@@ -640,12 +652,14 @@
 
 
 class VendorDataFactory(object):
+
     def parse(self, data, message_info):
         return VendorData(data)
 
 
 # VendorStackVersion TLV (37)
 class VendorStackVersion(object):
+
     def __init__(self, stack_vendor_oui, build, rev, minor, major):
         self._stack_vendor_oui = stack_vendor_oui
         self._build = build
@@ -680,6 +694,7 @@
 
 
 class VendorStackVersionFactory:
+
     def parse(self, data, message_info):
         stack_vendor_oui = struct.unpack(">H", data.read(2))[0]
         rest = struct.unpack(">BBBB", data.read(4))
@@ -809,6 +824,7 @@
 
 # Discovery Request TLV (128)
 class DiscoveryRequest(object):
+
     def __init__(self, version, joiner_flag):
         self._version = version
         self._joiner_flag = joiner_flag
@@ -822,19 +838,17 @@
         return self._joiner_flag
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other))
-            and self.version == other.version
-            and self.joiner_flag == other.joiner_flag
-        )
+        return (isinstance(self, type(other)) and
+                self.version == other.version and
+                self.joiner_flag == other.joiner_flag)
 
     def __repr__(self):
         return "DiscoveryRequest(version={}, joiner_flag={})".format(
-            self.version, self.joiner_flag
-        )
+            self.version, self.joiner_flag)
 
 
 class DiscoveryRequestFactory(object):
+
     def parse(self, data, message_info):
         data_byte = struct.unpack(">B", data.read(1))[0]
         version = (data_byte & 0xf0) >> 4
@@ -845,6 +859,7 @@
 
 # Discovery Response TLV (128)
 class DiscoveryResponse(object):
+
     def __init__(self, version, native_flag):
         self._version = version
         self._native_flag = native_flag
@@ -858,19 +873,17 @@
         return self._native_flag
 
     def __eq__(self, other):
-        return (
-            isinstance(self, type(other))
-            and self.version == other.version
-            and self.native_flag == other.native_flag
-        )
+        return (isinstance(self, type(other)) and
+                self.version == other.version and
+                self.native_flag == other.native_flag)
 
     def __repr__(self):
         return "DiscoveryResponse(version={}, native_flag={})".format(
-            self.version, self.native_flag
-        )
+            self.version, self.native_flag)
 
 
 class DiscoveryResponseFactory(object):
+
     def parse(self, data, message_info):
         data_byte = struct.unpack(">B", data.read(1))[0]
         version = (data_byte & 0xf0) >> 4
@@ -880,6 +893,7 @@
 
 
 class MeshCopCommand(object):
+
     def __init__(self, _type, tlvs):
         self._type = _type
         self._tlvs = tlvs
@@ -907,6 +921,7 @@
 
 
 class MeshCopCommandFactory:
+
     def __init__(self, tlvs_factories):
         self._tlvs_factories = tlvs_factories
         self._mesh_cop_msg_type_map = create_deault_mesh_cop_msg_type_map()
@@ -918,28 +933,25 @@
         try:
             return self._tlvs_factories[_type]
         except KeyError:
-            raise KeyError(
-                "Could not find TLV factory. Unsupported TLV type: {}".format(
-                    _type
-                )
-            )
+            logging.error(
+                'Could not find TLV factory. Unsupported TLV type: {}'.format(
+                    _type))
+            return UnknownTlvFactory(_type)
 
     def _parse_tlv(self, data):
         _type = TlvType(ord(data.read(1)))
         length = self._get_length(data)
         value = data.read(length)
         factory = self._get_tlv_factory(_type)
-        return factory.parse(
-            io.BytesIO(value), None
-        )  # message_info not needed here
+        return factory.parse(io.BytesIO(value),
+                             None)  # message_info not needed here
 
     def _get_mesh_cop_msg_type(self, msg_type_str):
         try:
             return self._mesh_cop_msg_type_map[msg_type_str]
         except KeyError:
             raise KeyError(
-                'Mesh cop message type not found: {}'.format(msg_type_str)
-            )
+                'Mesh cop message type not found: {}'.format(msg_type_str))
 
     def parse(self, cmd_type_str, data):
         cmd_type = self._get_mesh_cop_msg_type(cmd_type_str)
@@ -965,5 +977,6 @@
 
 
 class ThreadDiscoveryTlvsFactory(SubTlvsFactory):
+
     def __init__(self, sub_tlvs_factories):
         super(ThreadDiscoveryTlvsFactory, self).__init__(sub_tlvs_factories)
diff --git a/tests/scripts/thread-cert/message.py b/tests/scripts/thread-cert/message.py
index 1556acc..05ee825 100644
--- a/tests/scripts/thread-cert/message.py
+++ b/tests/scripts/thread-cert/message.py
@@ -41,6 +41,10 @@
 from enum import IntEnum
 
 
+class DropPacketException(Exception):
+    pass
+
+
 class MessageType(IntEnum):
     MLE = 0
     COAP = 1
@@ -53,6 +57,7 @@
 
 
 class Message(object):
+
     def __init__(self):
         self._type = None
         self._channel = None
@@ -68,9 +73,8 @@
             self._type = MessageType.MLE
             self._mle = udp_datagram.payload
 
-        elif isinstance(
-            udp_datagram.payload, (coap.CoapMessage, coap.CoapMessageProxy)
-        ):
+        elif isinstance(udp_datagram.payload,
+                        (coap.CoapMessage, coap.CoapMessageProxy)):
             self._type = MessageType.COAP
             self._coap = udp_datagram.payload
 
@@ -145,15 +149,12 @@
 
         elif self._mac_header.frame_type == mac802154.MacHeader.FrameType.DATA:
             self._type = MessageType.DATA
-        elif (
-            self._mac_header.frame_type
-            == mac802154.MacHeader.FrameType.COMMAND
-        ):
+        elif (self._mac_header.frame_type ==
+              mac802154.MacHeader.FrameType.COMMAND):
             self._type = MessageType.COMMAND
         else:
-            raise ValueError(
-                'Invalid mac frame type %d' % self._mac_header.frame_type
-            )
+            raise ValueError('Invalid mac frame type %d' %
+                             self._mac_header.frame_type)
 
     @property
     def ipv6_packet(self):
@@ -257,15 +258,10 @@
                 break
 
         if contains_tlv:
-            print(
-                "MleMessage contains optional TLV: {}".format(tlv_class_type)
-            )
+            print("MleMessage contains optional TLV: {}".format(tlv_class_type))
         else:
-            print(
-                "MleMessage doesn't contain optional TLV: {}".format(
-                    tlv_class_type
-                )
-            )
+            print("MleMessage doesn't contain optional TLV: {}".format(
+                tlv_class_type))
 
     def get_coap_message_tlv(self, tlv_class_type):
         if self.type != MessageType.COAP:
@@ -307,11 +303,8 @@
             if isinstance(tlv, tlv_class_type):
                 break
 
-        print(
-            "CoapMessage doesn't contain optional TLV: {}".format(
-                tlv_class_type
-            )
-        )
+        print("CoapMessage doesn't contain optional TLV: {}".format(
+            tlv_class_type))
 
     def assertCoapMessageRequestUriPath(self, uri_path):
         if self.type != MessageType.COAP:
@@ -340,24 +333,19 @@
 
         elif self.mac_header.dest_address.type == common.MacAddressType.LONG:
             mac_address = common.MacAddress.from_eui64(
-                bytearray(node.get_addr64(), encoding="utf-8")
-            )
+                bytearray(node.get_addr64(), encoding="utf-8"))
             if self.mac_header.dest_address == mac_address:
                 sent_to_node = True
 
         assert sent_to_node
 
     def assertSentToDestinationAddress(self, ipv6_address):
-        assert (
-            self.ipv6_packet.ipv6_header.destination_address
-            == ipaddress.ip_address(ipv6_address)
-        )
+        assert (self.ipv6_packet.ipv6_header.destination_address ==
+                ipaddress.ip_address(ipv6_address))
 
     def assertSentFromSourceAddress(self, ipv6_address):
-        assert (
-            self.ipv6_packet.ipv6_header.source_address
-            == ipaddress.ip_address(ipv6_address)
-        )
+        assert (self.ipv6_packet.ipv6_header.source_address ==
+                ipaddress.ip_address(ipv6_address))
 
     def assertSentWithHopLimit(self, hop_limit):
         assert self.ipv6_packet.ipv6_header.hop_limit == hop_limit
@@ -366,22 +354,24 @@
         return self.mac_header.dest_address.type == common.MacAddressType.LONG
 
     def get_dst_udp_port(self):
-        assert isinstance(
-            self.ipv6_packet.upper_layer_protocol, ipv6.UDPDatagram
-        )
+        assert isinstance(self.ipv6_packet.upper_layer_protocol,
+                          ipv6.UDPDatagram)
         return self.ipv6_packet.upper_layer_protocol.header.dst_port
 
+    def is_data_poll(self):
+        return self._type == MessageType.COMMAND and \
+            self._mac_header.command_type == mac802154.MacHeader.CommandIdentifier.DATA_REQUEST
+
     def __repr__(self):
-        if (
-            self.type == MessageType.DTLS
-            and self.dtls.content_type == dtls.ContentType.HANDSHAKE
-        ):
+        if (self.type == MessageType.DTLS and
+                self.dtls.content_type == dtls.ContentType.HANDSHAKE):
             return "Message(type={})".format(str(self.dtls.handshake_type))
         return "Message(type={})".format(MessageType(self.type).name)
 
 
 class MessagesSet(object):
-    def __init__(self, messages, commissioning_messages=[]):
+
+    def __init__(self, messages, commissioning_messages=()):
         self._messages = messages
         self._commissioning_messages = commissioning_messages
 
@@ -393,6 +383,14 @@
     def commissioning_messages(self):
         return self._commissioning_messages
 
+    def next_data_poll(self):
+        while True:
+            message = self.next_message_of(MessageType.COMMAND, False)
+            if not message:
+                break
+            elif message.is_data_poll():
+                return message
+
     def next_coap_message(self, code, uri_path=None, assert_enabled=True):
         message = None
 
@@ -413,9 +411,8 @@
             break
 
         if assert_enabled:
-            assert (
-                message is not None
-            ), "Could not find CoapMessage with code: {}".format(code)
+            assert (message is not None
+                   ), "Could not find CoapMessage with code: {}".format(code)
 
         return message
 
@@ -450,9 +447,10 @@
 
         return message
 
-    def next_mle_message(
-        self, command_type, assert_enabled=True, sent_to_node=None
-    ):
+    def next_mle_message(self,
+                         command_type,
+                         assert_enabled=True,
+                         sent_to_node=None):
         message = self.next_mle_message_of_one_of_command_types(command_type)
 
         if assert_enabled:
@@ -524,21 +522,15 @@
                 continue
             if msg.dtls.content_type != content_type:
                 continue
-            if (
-                content_type == dtls.ContentType.HANDSHAKE
-                and msg.dtls.handshake_type != handshake_type
-            ):
+            if (content_type == dtls.ContentType.HANDSHAKE and
+                    msg.dtls.handshake_type != handshake_type):
                 continue
             return msg
 
-        t = (
-            handshake_type
-            if content_type == dtls.ContentType.HANDSHAKE
-            else content_type
-        )
-        raise ValueError(
-            "Could not find DTLS message of type: {}".format(str(t))
-        )
+        t = (handshake_type
+             if content_type == dtls.ContentType.HANDSHAKE else content_type)
+        raise ValueError("Could not find DTLS message of type: {}".format(
+            str(t)))
 
     def contains_icmp_message(self):
         for m in self.messages:
@@ -586,6 +578,7 @@
 
 
 class MessageFactory:
+
     def __init__(self, lowpan_parser):
         self._lowpan_parser = lowpan_parser
 
@@ -593,14 +586,12 @@
         for tlv in message.mle.command.tlvs:
 
             if isinstance(tlv, mle.SourceAddress):
-                mac802154.DeviceDescriptors.add(
-                    tlv.address, message.mac_header.src_address
-                )
+                mac802154.DeviceDescriptors.add(tlv.address,
+                                                message.mac_header.src_address)
 
             if isinstance(tlv, mle.Address16):
-                mac802154.DeviceDescriptors.add(
-                    tlv.address, message.mac_header.dest_address
-                )
+                mac802154.DeviceDescriptors.add(tlv.address,
+                                                message.mac_header.dest_address)
 
     def _parse_mac_frame(self, data):
         mac_frame = mac802154.MacFrame()
@@ -611,30 +602,38 @@
         self._lowpan_parser.set_lowpan_context(cid, prefix)
 
     def create(self, data):
-        message = Message()
-        message.channel = struct.unpack(">B", data.read(1))
+        try:
+            message = Message()
+            message.channel = struct.unpack(">B", data.read(1))
 
-        # Parse MAC header
-        mac_frame = self._parse_mac_frame(data)
-        message.mac_header = mac_frame.header
+            # Parse MAC header
+            mac_frame = self._parse_mac_frame(data)
+            message.mac_header = mac_frame.header
 
-        if message.mac_header.frame_type != mac802154.MacHeader.FrameType.DATA:
-            return [message]
+            if message.mac_header.frame_type != mac802154.MacHeader.FrameType.DATA:
+                return [message]
 
-        message_info = common.MessageInfo()
-        message_info.source_mac_address = message.mac_header.src_address
-        message_info.destination_mac_address = message.mac_header.dest_address
+            message_info = common.MessageInfo()
+            message_info.source_mac_address = message.mac_header.src_address
+            message_info.destination_mac_address = message.mac_header.dest_address
 
-        # Create stream with 6LoWPAN datagram
-        lowpan_payload = io.BytesIO(mac_frame.payload.data)
+            # Create stream with 6LoWPAN datagram
+            lowpan_payload = io.BytesIO(mac_frame.payload.data)
 
-        ipv6_packet = self._lowpan_parser.parse(lowpan_payload, message_info)
-        if ipv6_packet is None:
-            return [message]
+            ipv6_packet = self._lowpan_parser.parse(lowpan_payload,
+                                                    message_info)
+            if ipv6_packet is None:
+                return [message]
 
-        message.ipv6_packet = ipv6_packet
+            message.ipv6_packet = ipv6_packet
 
-        if message.type == MessageType.MLE:
-            self._add_device_descriptors(message)
+            if message.type == MessageType.MLE:
+                self._add_device_descriptors(message)
 
-        return message.try_extract_dtls_messages()
+            return message.try_extract_dtls_messages()
+
+        except mac802154.KeyIdMode0Exception:
+            print(
+                'Received packet with key_id_mode = 0, cannot be handled in test scripts'
+            )
+            raise DropPacketException
diff --git a/tests/scripts/thread-cert/mle.py b/tests/scripts/thread-cert/mle.py
index 0f6e335..c47f190 100644
--- a/tests/scripts/thread-cert/mle.py
+++ b/tests/scripts/thread-cert/mle.py
@@ -28,6 +28,7 @@
 #
 
 import io
+import logging
 import struct
 
 from binascii import hexlify
@@ -35,6 +36,7 @@
 import common
 
 from enum import IntEnum
+from tlvs_parsing import UnknownTlvFactory
 
 
 class CommandType(IntEnum):
@@ -90,6 +92,7 @@
 
 
 class SourceAddress(object):
+
     def __init__(self, address):
         self._address = address
 
@@ -107,12 +110,14 @@
 
 
 class SourceAddressFactory:
+
     def parse(self, data, message_info):
         address = struct.unpack(">H", data.read(2))[0]
         return SourceAddress(address)
 
 
 class Mode(object):
+
     def __init__(self, receiver, secure, device_type, network_data):
         self._receiver = receiver
         self._secure = secure
@@ -138,12 +143,10 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.receiver == other.receiver
-            and self.secure == other.secure
-            and self.device_type == other.device_type
-            and self.network_data == other.network_data
-        )
+        return (self.receiver == other.receiver and
+                self.secure == other.secure and
+                self.device_type == other.device_type and
+                self.network_data == other.network_data)
 
     def __repr__(self):
         return "Mode(receiver={}, secure={}, device_type={}, network_data={})".format(
@@ -151,6 +154,7 @@
 
 
 class ModeFactory:
+
     def parse(self, data, message_info):
         mode = ord(data.read(1))
         receiver = (mode >> 3) & 0x01
@@ -161,6 +165,7 @@
 
 
 class Timeout(object):
+
     def __init__(self, timeout):
         self._timeout = timeout
 
@@ -178,12 +183,14 @@
 
 
 class TimeoutFactory:
+
     def parse(self, data, message_info):
         timeout = struct.unpack(">I", data.read(4))[0]
         return Timeout(timeout)
 
 
 class Challenge(object):
+
     def __init__(self, challenge):
         self._challenge = challenge
 
@@ -201,12 +208,14 @@
 
 
 class ChallengeFactory:
+
     def parse(self, data, message_info):
         challenge = data.read()
         return Challenge(challenge)
 
 
 class Response(object):
+
     def __init__(self, response):
         self._response = response
 
@@ -224,12 +233,14 @@
 
 
 class ResponseFactory:
+
     def parse(self, data, message_info):
         response = data.read()
         return Response(response)
 
 
 class LinkLayerFrameCounter(object):
+
     def __init__(self, frame_counter):
         self._frame_counter = frame_counter
 
@@ -244,17 +255,18 @@
 
     def __repr__(self):
         return "LinkLayerFrameCounter(frame_counter={})".format(
-            self.frame_counter
-        )
+            self.frame_counter)
 
 
 class LinkLayerFrameCounterFactory:
+
     def parse(self, data, message_info):
         frame_counter = struct.unpack(">I", data.read(4))[0]
         return LinkLayerFrameCounter(frame_counter)
 
 
 class MleFrameCounter(object):
+
     def __init__(self, frame_counter):
         self._frame_counter = frame_counter
 
@@ -272,12 +284,14 @@
 
 
 class MleFrameCounterFactory:
+
     def parse(self, data, message_info):
         frame_counter = struct.unpack(">I", data.read(4))[0]
         return MleFrameCounter(frame_counter)
 
 
 class LinkQualityAndRouteData(object):
+
     def __init__(self, output, _input, route):
         self._output = output
         self._input = _input
@@ -298,19 +312,16 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.output == other.output
-            and self.input == other.input
-            and self.route == other.route
-        )
+        return (self.output == other.output and self.input == other.input and
+                self.route == other.route)
 
     def __repr__(self):
         return "LinkQualityAndRouteData(ouput={}, input={}, route={})".format(
-            self.output, self.input, self.route
-        )
+            self.output, self.input, self.route)
 
 
 class LinkQualityAndRouteDataFactory:
+
     def parse(self, data, message_info):
         lqrd = ord(data.read(1))
         output = (lqrd >> 6) & 0x3
@@ -320,9 +331,9 @@
 
 
 class Route64(object):
-    def __init__(
-        self, id_sequence, router_id_mask, link_quality_and_route_data
-    ):
+
+    def __init__(self, id_sequence, router_id_mask,
+                 link_quality_and_route_data):
         self._id_sequence = id_sequence
         self._router_id_mask = router_id_mask
         self._link_quality_and_route_data = link_quality_and_route_data
@@ -342,22 +353,20 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.id_sequence == other.id_sequence
-            and self.router_id_mask == other.router_id_mask
-            and self.link_quality_and_route_data
-            == other.link_quality_and_route_data
-        )
+        return (self.id_sequence == other.id_sequence and
+                self.router_id_mask == other.router_id_mask and
+                self.link_quality_and_route_data ==
+                other.link_quality_and_route_data)
 
     def __repr__(self):
         lqrd_str = ", ".join(
-            ["{}".format(lqrd) for lqrd in self.link_quality_and_route_data]
-        )
+            ["{}".format(lqrd) for lqrd in self.link_quality_and_route_data])
         return "Route64(id_sequence={}, router_id_mask={}, link_quality_and_route_data=[{}])".format(
             self.id_sequence, hex(self.router_id_mask), lqrd_str)
 
 
 class Route64Factory:
+
     def __init__(self, link_quality_and_route_data_factory):
         self._lqrd_factory = link_quality_and_route_data_factory
 
@@ -369,15 +378,13 @@
 
         while data.tell() < len(data.getvalue()):
             link_quality_and_route_data.append(
-                self._lqrd_factory.parse(data, message_info)
-            )
+                self._lqrd_factory.parse(data, message_info))
 
-        return Route64(
-            id_sequence, router_id_mask, link_quality_and_route_data
-        )
+        return Route64(id_sequence, router_id_mask, link_quality_and_route_data)
 
 
 class Address16(object):
+
     def __init__(self, address):
         self._address = address
 
@@ -395,12 +402,14 @@
 
 
 class Address16Factory:
+
     def parse(self, data, message_info):
         address = struct.unpack(">H", data.read(2))[0]
         return Address16(address)
 
 
 class LeaderData(object):
+
     def __init__(
         self,
         partition_id,
@@ -438,21 +447,24 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.partition_id == other.partition_id
-            and self.weighting == other.weighting
-            and self.data_version == other.data_version
-            and self.stable_data_version == other.stable_data_version
-            and self.leader_router_id == other.leader_router_id
-        )
+        return (self.partition_id == other.partition_id and
+                self.weighting == other.weighting and
+                self.data_version == other.data_version and
+                self.stable_data_version == other.stable_data_version and
+                self.leader_router_id == other.leader_router_id)
 
     def __repr__(self):
-        return ("LeaderData(partition_id={}, weighting={}, data_version={}, stable_data_version={},",
-                "leader_router_id={})").format(
-            self.partition_id, self.weighting, self.data_version, self.stable_data_version, self.leader_router_id, )
+        return 'LeaderData(partition_id={}, weighting={}, data_version={}, stable_data_version={},leader_router_id={}'.format(
+            self.partition_id,
+            self.weighting,
+            self.data_version,
+            self.stable_data_version,
+            self.leader_router_id,
+        )
 
 
 class LeaderDataFactory:
+
     def parse(self, data, message_info):
         partition_id = struct.unpack(">I", data.read(4))[0]
         weighting = ord(data.read(1))
@@ -469,6 +481,7 @@
 
 
 class NetworkData(object):
+
     def __init__(self, tlvs):
         self._tlvs = tlvs
 
@@ -487,6 +500,7 @@
 
 
 class NetworkDataFactory:
+
     def __init__(self, network_data_tlvs_factory):
         self._tlvs_factory = network_data_tlvs_factory
 
@@ -496,6 +510,7 @@
 
 
 class TlvRequest(object):
+
     def __init__(self, tlvs):
         self._tlvs = tlvs
 
@@ -514,12 +529,14 @@
 
 
 class TlvRequestFactory:
+
     def parse(self, data, message_info):
         tlvs = [b for b in bytearray(data.read())]
         return TlvRequest(tlvs)
 
 
 class ScanMask(object):
+
     def __init__(self, router, end_device):
         self._router = router
         self._end_device = end_device
@@ -535,17 +552,16 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.router == other.router and self.end_device == other.end_device
-        )
+        return (self.router == other.router and
+                self.end_device == other.end_device)
 
     def __repr__(self):
         return "ScanMask(router={}, end_device={})".format(
-            self.router, self.end_device
-        )
+            self.router, self.end_device)
 
 
 class ScanMaskFactory:
+
     def parse(self, data, message_info):
         scan_mask = ord(data.read(1))
         router = (scan_mask >> 7) & 0x01
@@ -554,9 +570,10 @@
 
 
 class Connectivity(object):
+
     def __init__(
         self,
-        pp,
+        pp_byte,
         link_quality_3,
         link_quality_2,
         link_quality_1,
@@ -566,7 +583,7 @@
         sed_buffer_size=None,
         sed_datagram_count=None,
     ):
-        self._pp = pp
+        self._pp_byte = pp_byte
         self._link_quality_3 = link_quality_3
         self._link_quality_2 = link_quality_2
         self._link_quality_1 = link_quality_1
@@ -577,8 +594,12 @@
         self._sed_datagram_count = sed_datagram_count
 
     @property
+    def pp_byte(self):
+        return self._pp_byte
+
+    @property
     def pp(self):
-        return self._pp
+        return common.map_pp(self._pp_byte)
 
     @property
     def link_quality_3(self):
@@ -615,17 +636,15 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.pp == other.pp
-            and self.link_quality_3 == other.link_quality_3
-            and self.link_quality_2 == other.link_quality_2
-            and self.link_quality_1 == other.link_quality_1
-            and self.leader_cost == other.leader_cost
-            and self.id_sequence == other.id_sequence
-            and self.active_routers == other.active_routers
-            and self.sed_buffer_size == other.sed_buffer_size
-            and self.sed_datagram_count == other.sed_datagram_count
-        )
+        return (self.pp == other.pp and
+                self.link_quality_3 == other.link_quality_3 and
+                self.link_quality_2 == other.link_quality_2 and
+                self.link_quality_1 == other.link_quality_1 and
+                self.leader_cost == other.leader_cost and
+                self.id_sequence == other.id_sequence and
+                self.active_routers == other.active_routers and
+                self.sed_buffer_size == other.sed_buffer_size and
+                self.sed_datagram_count == other.sed_datagram_count)
 
     def __repr__(self):
         return r"Connectivity(pp={}, \
@@ -650,8 +669,9 @@
 
 
 class ConnectivityFactory:
+
     def parse(self, data, message_info):
-        pp = ord(data.read(1)) & 0x03
+        pp_byte = ord(data.read(1))
         link_quality_3 = ord(data.read(1))
         link_quality_2 = ord(data.read(1))
         link_quality_1 = ord(data.read(1))
@@ -669,7 +689,7 @@
             sed_datagram_count = None
 
         return Connectivity(
-            pp,
+            pp_byte,
             link_quality_3,
             link_quality_2,
             link_quality_1,
@@ -682,6 +702,7 @@
 
 
 class LinkMargin(object):
+
     def __init__(self, link_margin):
         self._link_margin = link_margin
 
@@ -699,12 +720,14 @@
 
 
 class LinkMarginFactory:
+
     def parse(self, data, message_info):
         link_margin = ord(data.read(1))
         return LinkMargin(link_margin)
 
 
 class Status(object):
+
     def __init__(self, status):
         self._status = status
 
@@ -722,12 +745,14 @@
 
 
 class StatusFactory:
+
     def parse(self, data, message_info):
         status = ord(data.read(1))
         return Status(status)
 
 
 class Version(object):
+
     def __init__(self, version):
         self._version = version
 
@@ -745,12 +770,14 @@
 
 
 class VersionFactory:
+
     def parse(self, data, message_info):
         version = struct.unpack(">H", data.read(2))[0]
         return Version(version)
 
 
 class AddressFull(object):
+
     def __init__(self, ipv6_address):
         self._ipv6_address = ipv6_address
 
@@ -764,12 +791,12 @@
         return self.ipv6_address == other.ipv6_address
 
     def __repr__(self):
-        return "AddressFull(ipv6_address={}')".format(
-            hexlify(self.ipv6_address)
-        )
+        return "AddressFull(ipv6_address={}')".format(hexlify(
+            self.ipv6_address))
 
 
 class AddressFullFactory:
+
     def parse(self, data, message_info):
         data.read(1)  # first byte is ignored
         ipv6_address = data.read(16)
@@ -777,6 +804,7 @@
 
 
 class AddressCompressed(object):
+
     def __init__(self, cid, iid):
         self._cid = cid
         self._iid = iid
@@ -796,11 +824,11 @@
 
     def __repr__(self):
         return "AddressCompressed(cid={}, iid={}')".format(
-            self.cid, hexlify(self.iid)
-        )
+            self.cid, hexlify(self.iid))
 
 
 class AddressCompressedFactory:
+
     def parse(self, data, message_info):
         cid = ord(data.read(1)) & 0x0F
         iid = bytearray(data.read(8))
@@ -808,6 +836,7 @@
 
 
 class AddressRegistration(object):
+
     def __init__(self, addresses):
         self._addresses = addresses
 
@@ -822,12 +851,12 @@
 
     def __repr__(self):
         addresses_str = ", ".join(
-            ["{}".format(address) for address in self.addresses]
-        )
+            ["{}".format(address) for address in self.addresses])
         return "AddressRegistration(addresses=[{}])".format(addresses_str)
 
 
 class AddressRegistrationFactory:
+
     def __init__(self, addr_compressed_factory, addr_full_factory):
         self._addr_compressed_factory = addr_compressed_factory
         self._addr_full_factory = addr_full_factory
@@ -841,17 +870,16 @@
 
             if compressed:
                 addresses.append(
-                    self._addr_compressed_factory.parse(data, message_info)
-                )
+                    self._addr_compressed_factory.parse(data, message_info))
             else:
                 addresses.append(
-                    self._addr_full_factory.parse(data, message_info)
-                )
+                    self._addr_full_factory.parse(data, message_info))
 
         return AddressRegistration(addresses)
 
 
 class Channel(object):
+
     def __init__(self, channel_page, channel):
         self._channel_page = channel_page
         self._channel = channel
@@ -867,18 +895,16 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.channel_page == other.channel_page
-            and self.channel == other.channel
-        )
+        return (self.channel_page == other.channel_page and
+                self.channel == other.channel)
 
     def __repr__(self):
         return "Channel(channel_page={}, channel={})".format(
-            self.channel_page, self.channel
-        )
+            self.channel_page, self.channel)
 
 
 class ChannelFactory:
+
     def parse(self, data, message_info):
         channel_page = ord(data.read(1))
         channel = struct.unpack(">H", data.read(2))[0]
@@ -886,6 +912,7 @@
 
 
 class PanId:
+
     def __init__(self, pan_id):
         self._pan_id = pan_id
 
@@ -903,12 +930,14 @@
 
 
 class PanIdFactory:
+
     def parse(self, data, message_info):
         pan_id = struct.unpack(">H", data.read(2))[0]
         return PanId(pan_id)
 
 
 class ActiveTimestamp(object):
+
     def __init__(self, timestamp_seconds, timestamp_ticks, u):
         self._timestamp_seconds = timestamp_seconds
         self._timestamp_ticks = timestamp_ticks
@@ -929,11 +958,9 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.timestamp_seconds == other.timestamp_seconds
-            and self.timestamp_ticks == other.timestamp_ticks
-            and self.u == other.u
-        )
+        return (self.timestamp_seconds == other.timestamp_seconds and
+                self.timestamp_ticks == other.timestamp_ticks and
+                self.u == other.u)
 
     def __repr__(self):
         return "ActiveTimestamp(timestamp_seconds={}, timestamp_ticks={}, u={})".format(
@@ -941,6 +968,7 @@
 
 
 class ActiveTimestampFactory:
+
     def parse(self, data, message_info):
         seconds = bytearray([0x00, 0x00]) + bytearray(data.read(6))
         ticks = struct.unpack(">H", data.read(2))[0]
@@ -952,6 +980,7 @@
 
 
 class PendingTimestamp(object):
+
     def __init__(self, timestamp_seconds, timestamp_ticks, u):
         self._timestamp_seconds = timestamp_seconds
         self._timestamp_ticks = timestamp_ticks
@@ -972,11 +1001,9 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.timestamp_seconds == other.timestamp_seconds
-            and self.timestamp_ticks == other.timestamp_ticks
-            and self.u == other.u
-        )
+        return (self.timestamp_seconds == other.timestamp_seconds and
+                self.timestamp_ticks == other.timestamp_ticks and
+                self.u == other.u)
 
     def __repr__(self):
         return "PendingTimestamp(timestamp_seconds={}, timestamp_ticks={}, u={})".format(
@@ -984,6 +1011,7 @@
 
 
 class PendingTimestampFactory:
+
     def parse(self, data, message_info):
         seconds = bytearray([0x00, 0x00]) + bytearray(data.read(6))
         ticks = struct.unpack(">H", data.read(2))[0]
@@ -1002,6 +1030,7 @@
 
 
 class ActiveOperationalDatasetFactory:
+
     def parse(self, data, message_info):
         return ActiveOperationalDataset()
 
@@ -1014,11 +1043,13 @@
 
 
 class PendingOperationalDatasetFactory:
+
     def parse(self, data, message_info):
         return PendingOperationalDataset()
 
 
 class ThreadDiscovery(object):
+
     def __init__(self, tlvs):
         self._tlvs = tlvs
 
@@ -1034,6 +1065,7 @@
 
 
 class ThreadDiscoveryFactory:
+
     def __init__(self, thread_discovery_tlvs_factory):
         self._tlvs_factory = thread_discovery_tlvs_factory
 
@@ -1050,6 +1082,7 @@
 
 
 class TimeRequestFactory:
+
     def parse(self, data, message_info):
         return TimeRequest()
 
@@ -1062,11 +1095,13 @@
 
 
 class TimeParameterFactory:
+
     def parse(self, data, message_info):
         return TimeParameter()
 
 
 class MleCommand(object):
+
     def __init__(self, _type, tlvs):
         self._type = _type
         self._tlvs = tlvs
@@ -1081,9 +1116,7 @@
 
     def __repr__(self):
         tlvs_str = ", ".join(["{}".format(tlv) for tlv in self.tlvs])
-        return "MleCommand(type={}, tlvs=[{}])".format(
-            self.type.name, tlvs_str
-        )
+        return "MleCommand(type={}, tlvs=[{}])".format(self.type.name, tlvs_str)
 
 
 class MleCommandFactory:
@@ -1105,11 +1138,10 @@
         try:
             return self._tlvs_factories[_type]
         except KeyError:
-            raise KeyError(
-                "Could not find TLV factory. Unsupported TLV type: {}".format(
-                    _type
-                )
-            )
+            logging.error(
+                'Could not find TLV factory. Unsupported TLV type: {}'.format(
+                    _type))
+            return UnknownTlvFactory(_type)
 
     def _parse_tlv(self, data, message_info):
         _type = TlvType(ord(data.read(1)))
@@ -1132,6 +1164,7 @@
 
 
 class MleMessage(object):
+
     def __init__(self, command):
         self._command = command
 
@@ -1144,6 +1177,7 @@
 
 
 class MleMessageSecured(MleMessage):
+
     def __init__(self, aux_sec_hdr, command, mic):
         super(MleMessageSecured, self).__init__(command)
         self._aux_sec_hdr = aux_sec_hdr
@@ -1163,9 +1197,8 @@
 
 
 class MleMessageFactory:
-    def __init__(
-        self, aux_sec_hdr_factory, mle_command_factory, crypto_engine
-    ):
+
+    def __init__(self, aux_sec_hdr_factory, mle_command_factory, crypto_engine):
         self._aux_sec_hdr_factory = aux_sec_hdr_factory
         self._mle_command_factory = mle_command_factory
         self._crypto_engine = crypto_engine
@@ -1176,17 +1209,14 @@
         enc_data_length = len(data.getvalue())
 
         enc_data = bytearray(
-            data.read(
-                enc_data_length - data.tell() - self._crypto_engine.mic_length
-            )
-        )
+            data.read(enc_data_length - data.tell() -
+                      self._crypto_engine.mic_length))
         mic = bytearray(data.read())
 
         dec_data = self._crypto_engine.decrypt(enc_data, mic, message_info)
 
-        command = self._mle_command_factory.parse(
-            io.BytesIO(dec_data), message_info
-        )
+        command = self._mle_command_factory.parse(io.BytesIO(dec_data),
+                                                  message_info)
 
         return MleMessageSecured(aux_sec_hdr, command, mic)
 
@@ -1206,7 +1236,5 @@
 
         else:
             raise RuntimeError(
-                "Could not create MLE message. Unknown security indicator value: {}".format(
-                    security_indicator
-                )
-            )
+                "Could not create MLE message. Unknown security indicator value: {}"
+                .format(security_indicator))
diff --git a/tests/scripts/thread-cert/net_crypto.py b/tests/scripts/thread-cert/net_crypto.py
index 191fa00..a144eae 100644
--- a/tests/scripts/thread-cert/net_crypto.py
+++ b/tests/scripts/thread-cert/net_crypto.py
@@ -37,7 +37,6 @@
 
 
 class CryptoEngine:
-
     """ Class responsible for encryption and decryption of data. """
 
     def __init__(self, crypto_material_creator):
@@ -134,6 +133,7 @@
 
 
 class MacCryptoMaterialCreator(CryptoMaterialCreator):
+
     def __init__(self, master_key):
         """
         Args:
@@ -158,9 +158,8 @@
         """
         return bytes(eui64 + struct.pack(">LB", frame_counter, security_level))
 
-    def _create_authenticated_data(
-        self, mhr, auxiliary_security_header, extra_open_fields
-    ):
+    def _create_authenticated_data(self, mhr, auxiliary_security_header,
+                                   extra_open_fields):
         """ Create Authenticated Data
 
         Read more: 7.6.3.3 CCM prerequisites - Std 802.15.4-2006
@@ -178,8 +177,7 @@
 
     def create_key_and_nonce_and_authenticated_data(self, message_info):
         _, mac_key = self._generate_keys(
-            message_info.aux_sec_hdr.sequence_counter
-        )
+            message_info.aux_sec_hdr.sequence_counter)
 
         nonce = self._create_nonce(
             message_info.source_mac_address,
@@ -201,6 +199,7 @@
 
 
 class MleCryptoMaterialCreator(CryptoMaterialCreator):
+
     def __init__(self, master_key):
         """
         Args:
@@ -223,14 +222,11 @@
             bytes: created Nonce
 
         """
-        return bytes(
-            source_eui64[:8]
-            + struct.pack(">LB", frame_counter, security_level)
-        )
+        return bytes(source_eui64[:8] +
+                     struct.pack(">LB", frame_counter, security_level))
 
-    def _create_authenticated_data(
-        self, source_address, destination_address, auxiliary_security_header
-    ):
+    def _create_authenticated_data(self, source_address, destination_address,
+                                   auxiliary_security_header):
         """ Create Authenticated Data
 
         Read more: 4.8 - Thread v1.0 Specification
@@ -244,16 +240,12 @@
             bytes: Authenticated Data
 
         """
-        return bytes(
-            source_address.packed
-            + destination_address.packed
-            + auxiliary_security_header
-        )
+        return bytes(source_address.packed + destination_address.packed +
+                     auxiliary_security_header)
 
     def create_key_and_nonce_and_authenticated_data(self, message_info):
         mle_key, _ = self._generate_keys(
-            message_info.aux_sec_hdr.sequence_counter
-        )
+            message_info.aux_sec_hdr.sequence_counter)
 
         nonce = self._create_nonce(
             message_info.source_mac_address.mac_address,
@@ -275,6 +267,7 @@
 
 
 class AuxiliarySecurityHeader:
+
     def __init__(
         self,
         key_id_mode,
@@ -303,7 +296,7 @@
         if self.key_id_mode == 0:
             key_source = self.key_id[:8]
             format = ">Q" if self._big_endian else "<Q"
-        if self.key_id_mode == 1:
+        elif self.key_id_mode == 1:
             # Try to guess valid Key Sequence Counter based on Key Index. This
             # one should work for now.
             return self.key_index - 1
@@ -313,9 +306,8 @@
             key_source = self.key_id[:4]
             format = ">I" if self._big_endian else "<I"
         else:
-            raise ValueError(
-                "Unsupported Key Index Mode: {}".format(self.key_id_mode)
-            )
+            raise ValueError("Unsupported Key Index Mode: {}".format(
+                self.key_id_mode))
 
         return struct.unpack(format, key_source)[0]
 
@@ -341,7 +333,11 @@
 
     def __repr__(self):
         return "AuxiliarySecurityHeader(key_id_mode={}, security_level={}, frame_counter={}, key_id={})".format(
-            self.key_id_mode, self.security_level, self.frame_counter, hexlify(self.key_id), )
+            self.key_id_mode,
+            self.security_level,
+            self.frame_counter,
+            hexlify(self.key_id),
+        )
 
 
 class AuxiliarySecurityHeaderFactory:
@@ -375,25 +371,21 @@
 
     def parse(self, data, message_info):
         security_control_bytes = bytearray(
-            data.read(self._SECURITY_CONTROL_LENGTH)
-        )
+            data.read(self._SECURITY_CONTROL_LENGTH))
         frame_counter_bytes = bytearray(data.read(self._FRAME_COUNTER_LENGTH))
 
         security_level, key_id_mode = self._parse_security_control(
-            security_control_bytes[0]
-        )
+            security_control_bytes[0])
         frame_counter = self._parse_frame_counter(frame_counter_bytes)
 
         key_id_length = self._key_id_length(key_id_mode)
         key_id_bytes = bytearray(data.read(key_id_length))
 
-        aux_sec_hdr = AuxiliarySecurityHeader(
-            key_id_mode, security_level, frame_counter, key_id_bytes
-        )
+        aux_sec_hdr = AuxiliarySecurityHeader(key_id_mode, security_level,
+                                              frame_counter, key_id_bytes)
 
-        message_info.aux_sec_hdr_bytes = (
-            security_control_bytes + frame_counter_bytes + key_id_bytes
-        )
+        message_info.aux_sec_hdr_bytes = (security_control_bytes +
+                                          frame_counter_bytes + key_id_bytes)
         message_info.aux_sec_hdr = aux_sec_hdr
 
         return aux_sec_hdr
diff --git a/tests/scripts/thread-cert/network_data.py b/tests/scripts/thread-cert/network_data.py
index 72c3ce1..9794c98 100644
--- a/tests/scripts/thread-cert/network_data.py
+++ b/tests/scripts/thread-cert/network_data.py
@@ -49,6 +49,7 @@
 
 
 class NetworkData(object):
+
     def __init__(self, stable):
         self._stable = stable
 
@@ -58,6 +59,7 @@
 
 
 class NetworkDataSubTlvsFactory(SubTlvsFactory):
+
     def parse(self, data, message_info):
         sub_tlvs = []
 
@@ -81,6 +83,7 @@
 
 
 class Route(object):
+
     def __init__(self, border_router_16, prf):
         self._border_router_16 = border_router_16
         self._prf = prf
@@ -96,18 +99,16 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.border_router_16 == other.border_router_16
-            and self.prf == other.prf
-        )
+        return (self.border_router_16 == other.border_router_16 and
+                self.prf == other.prf)
 
     def __repr__(self):
         return "Route(border_router_16={}, prf={})".format(
-            self.border_router_16, self.prf
-        )
+            self.border_router_16, self.prf)
 
 
 class RouteFactory(object):
+
     def parse(self, data, message_info):
         border_router_16 = struct.unpack(">H", data.read(2))[0]
 
@@ -118,6 +119,7 @@
 
 
 class RoutesFactory(object):
+
     def __init__(self, route_factory):
         self._route_factory = route_factory
 
@@ -133,6 +135,7 @@
 
 
 class HasRoute(NetworkData):
+
     def __init__(self, routes, stable):
         super(HasRoute, self).__init__(stable)
         self._routes = routes
@@ -149,11 +152,11 @@
     def __repr__(self):
         routes_str = ", ".join(["{}".format(route) for route in self.routes])
         return "HasRoute(stable={}, routes=[{}])".format(
-            self.stable, routes_str
-        )
+            self.stable, routes_str)
 
 
 class HasRouteFactory(object):
+
     def __init__(self, routes_factory):
         self._routes_factory = routes_factory
 
@@ -164,6 +167,7 @@
 
 
 class Prefix(NetworkData):
+
     def __init__(self, domain_id, prefix_length, prefix, sub_tlvs, stable):
         super(Prefix, self).__init__(stable)
         self._domain_id = domain_id
@@ -190,25 +194,29 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.domain_id == other.domain_id
-            and self.prefix_length == other.prefix_length
-            and self.prefix == other.prefix
-            and self.sub_tlvs == other.sub_tlvs
-        )
+        return (self.domain_id == other.domain_id and
+                self.prefix_length == other.prefix_length and
+                self.prefix == other.prefix and self.sub_tlvs == other.sub_tlvs)
 
     def __repr__(self):
         sub_tlvs_str = ", ".join(["{}".format(tlv) for tlv in self.sub_tlvs])
         return "Prefix(stable={}, domain_id={}, prefix_length={}, prefix={}, sub_tlvs=[{}])".format(
-            self.stable, self.domain_id, self.prefix_length, hexlify(self.prefix), sub_tlvs_str, )
+            self.stable,
+            self.domain_id,
+            self.prefix_length,
+            hexlify(self.prefix),
+            sub_tlvs_str,
+        )
 
 
 class PrefixSubTlvsFactory(NetworkDataSubTlvsFactory):
+
     def __init__(self, sub_tlvs_factories):
         super(PrefixSubTlvsFactory, self).__init__(sub_tlvs_factories)
 
 
 class PrefixFactory(object):
+
     def __init__(self, sub_tlvs_factory):
         self._sub_tlvs_factory = sub_tlvs_factory
 
@@ -222,16 +230,15 @@
 
         prefix = bytearray(data.read(self._bits_to_bytes(prefix_length)))
 
-        sub_tlvs = self._sub_tlvs_factory.parse(
-            io.BytesIO(data.read()), message_info
-        )
+        sub_tlvs = self._sub_tlvs_factory.parse(io.BytesIO(data.read()),
+                                                message_info)
 
-        return Prefix(
-            domain_id, prefix_length, prefix, sub_tlvs, message_info.stable
-        )
+        return Prefix(domain_id, prefix_length, prefix, sub_tlvs,
+                      message_info.stable)
 
 
 class BorderRouter(NetworkData):
+
     def __init__(self, border_router_16, prf, p, s, d, c, r, o, n, stable):
         super(BorderRouter, self).__init__(stable)
         self._border_router_16 = border_router_16
@@ -283,24 +290,29 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.border_router_16 == other.border_router_16
-            and self.prf == other.prf
-            and self.p == other.p
-            and self.s == other.s
-            and self.d == other.d
-            and self.c == other.c
-            and self.r == other.r
-            and self.o == other.o
-            and self.n == other.n
-        )
+        return (self.border_router_16 == other.border_router_16 and
+                self.prf == other.prf and self.p == other.p and
+                self.s == other.s and self.d == other.d and
+                self.c == other.c and self.r == other.r and
+                self.o == other.o and self.n == other.n)
 
     def __repr__(self):
         return "BorderRouter(stable={}, border_router_16={}, prf={}, p={}, s={}, d={}, c={}, r={}, o={}, n={})".format(
-            self.stable, self.border_router_16, self.prf, self.p, self.s, self.d, self.c, self.r, self.o, self.n, )
+            self.stable,
+            self.border_router_16,
+            self.prf,
+            self.p,
+            self.s,
+            self.d,
+            self.c,
+            self.r,
+            self.o,
+            self.n,
+        )
 
 
 class BorderRouterFactory(object):
+
     def parse(self, data, message_info):
         border_router_16 = struct.unpack(">H", data.read(2))[0]
 
@@ -316,12 +328,12 @@
         data_byte = ord(data.read(1))
         n = (data_byte >> 7) & 0x01
 
-        return BorderRouter(
-            border_router_16, prf, p, s, d, c, r, o, n, message_info.stable
-        )
+        return BorderRouter(border_router_16, prf, p, s, d, c, r, o, n,
+                            message_info.stable)
 
 
 class LowpanId(NetworkData):
+
     def __init__(self, c, cid, context_length, stable):
         super(LowpanId, self).__init__(stable)
         self._c = c
@@ -343,19 +355,16 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.c == other.c
-            and self.cid == other.cid
-            and self.context_length == other.context_length
-        )
+        return (self.c == other.c and self.cid == other.cid and
+                self.context_length == other.context_length)
 
     def __repr__(self):
         return "LowpanId(stable={}, c={}, cid={}, context_length={})".format(
-            self.stable, self.c, self.cid, self.context_length
-        )
+            self.stable, self.c, self.cid, self.context_length)
 
 
 class LowpanIdFactory(object):
+
     def parse(self, data, message_info):
         data_byte = ord(data.read(1))
 
@@ -368,6 +377,7 @@
 
 
 class CommissioningData(NetworkData):
+
     def __init__(self, sub_tlvs, stable):
         super(CommissioningData, self).__init__(stable)
         self._sub_tlvs = sub_tlvs
@@ -382,34 +392,32 @@
         return self.sub_tlvs == other.sub_tlvs
 
     def __repr__(self):
-        sub_tlvs_str = ", ".format(
-            ["{}".format(tlv) for tlv in self._sub_tlvs]
-        )
+        sub_tlvs_str = ", ".join(["{}".format(tlv) for tlv in self._sub_tlvs])
         return "CommissioningData(stable={}, sub_tlvs=[{}])".format(
-            self._stable, sub_tlvs_str
-        )
+            self._stable, sub_tlvs_str)
 
 
 class CommissioningDataSubTlvsFactory(SubTlvsFactory):
+
     def __init__(self, sub_tlvs_factories):
-        super(CommissioningDataSubTlvsFactory, self).__init__(
-            sub_tlvs_factories
-        )
+        super(CommissioningDataSubTlvsFactory,
+              self).__init__(sub_tlvs_factories)
 
 
 class CommissioningDataFactory(object):
+
     def __init__(self, sub_tlvs_factory):
         self._sub_tlvs_factory = sub_tlvs_factory
 
     def parse(self, data, message_info):
-        sub_tlvs = self._sub_tlvs_factory.parse(
-            io.BytesIO(data.read()), message_info
-        )
+        sub_tlvs = self._sub_tlvs_factory.parse(io.BytesIO(data.read()),
+                                                message_info)
 
         return CommissioningData(sub_tlvs, message_info.stable)
 
 
 class Service(NetworkData):
+
     def __init__(
         self,
         t,
@@ -455,29 +463,35 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.t == other.t
-            and self.id == other.id
-            and self.enterprise_number == other.enterprise_number
-            and self.service_data_length == other.service_data_length
-            and self.service_data == other.service_data
-            and self.sub_tlvs == other.sub_tlvs
-        )
+        return (self.t == other.t and self.id == other.id and
+                self.enterprise_number == other.enterprise_number and
+                self.service_data_length == other.service_data_length and
+                self.service_data == other.service_data and
+                self.sub_tlvs == other.sub_tlvs)
 
     def __repr__(self):
-        sub_tlvs_str = ", ".format(["{}".format(tlv) for tlv in self.sub_tlvs])
-        return ("LowpanId(stable={}, t={}, id={}, enterprise_number={}, service_data_length={}, service_data={},",
-                "sub_tlvs=[{}])").format(
-            self.stable, self.t, self.id, self.enterprise_number, self.service_data_length, self.service_data,
-            sub_tlvs_str, )
+        sub_tlvs_str = ", ".join(["{}".format(tlv) for tlv in self.sub_tlvs])
+        return (
+            "LowpanId(stable={}, t={}, id={}, enterprise_number={}, service_data_length={}, service_data={}, sub_tlvs=[{}])"
+        ).format(
+            self.stable,
+            self.t,
+            self.id,
+            self.enterprise_number,
+            self.service_data_length,
+            self.service_data,
+            sub_tlvs_str,
+        )
 
 
 class ServiceSubTlvsFactory(NetworkDataSubTlvsFactory):
+
     def __init__(self, sub_tlvs_factories):
         super(ServiceSubTlvsFactory, self).__init__(sub_tlvs_factories)
 
 
 class ServiceFactory(object):
+
     def __init__(self, sub_tlvs_factory):
         self._sub_tlvs_factory = sub_tlvs_factory
 
@@ -490,9 +504,8 @@
         service_data_length = ord(data.read(1))
         service_data = data.read(service_data_length)
 
-        sub_tlvs = self._sub_tlvs_factory.parse(
-            io.BytesIO(data.read()), message_info
-        )
+        sub_tlvs = self._sub_tlvs_factory.parse(io.BytesIO(data.read()),
+                                                message_info)
 
         return Service(
             t,
@@ -506,6 +519,7 @@
 
 
 class Server(NetworkData):
+
     def __init__(self, server_16, server_data, stable):
         super(Server, self).__init__(stable)
         self._server_16 = server_16
@@ -522,18 +536,16 @@
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
 
-        return (
-            self.server_16 == other.server_16
-            and self.server_data == other.server_data
-        )
+        return (self.server_16 == other.server_16 and
+                self.server_data == other.server_data)
 
     def __repr__(self):
         return "LowpanId(stable={}, server_16={}, server_data=b'{}')".format(
-            self.stable, self.server_16, hexlify(self.server_data)
-        )
+            self.stable, self.server_16, hexlify(self.server_data))
 
 
 class ServerFactory(object):
+
     def parse(self, data, message_info):
         server_16 = struct.unpack(">H", data.read(2))[0]
         server_data = bytearray(data.read())
@@ -542,5 +554,6 @@
 
 
 class NetworkDataTlvsFactory(NetworkDataSubTlvsFactory):
+
     def __init__(self, sub_tlvs_factories):
         super(NetworkDataTlvsFactory, self).__init__(sub_tlvs_factories)
diff --git a/tests/scripts/thread-cert/network_diag.py b/tests/scripts/thread-cert/network_diag.py
new file mode 100644
index 0000000..5cdf1e6
--- /dev/null
+++ b/tests/scripts/thread-cert/network_diag.py
@@ -0,0 +1,336 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import struct
+
+from enum import IntEnum
+from typing import List
+
+import common
+import ipaddress
+import mle
+
+
+class TlvType(IntEnum):
+    EXT_ADDRESS = 0
+    ADDRESS16 = 1
+    MODE = 2
+    POLLING_PERIOD = 3
+    CONNECTIVITY = 4
+    ROUTE64 = 5
+    LEADER_DATA = 6
+    NETWORK_DATA = 7
+    IPV6_ADDRESS_LIST = 8
+    MAC_COUNTERS = 9
+    BATTERY_LEVEL = 14
+    SUPPLY_VOLTAGE = 15
+    CHILD_TABLE = 16
+    CHANNEL_PAGES = 17
+    TYPE_LIST = 18
+    MAX_CHILD_TIMEOUT = 19
+
+
+class Ipv6AddressList:
+
+    def __init__(self, addresses: List[ipaddress.IPv6Address]):
+        self._addresses = addresses
+
+    @property
+    def addresses(self):
+        return self._addresses
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+        return self.addresses == other.addresses
+
+    def __repr__(self):
+        return f'Ipv6AddressList({self.addresses})'
+
+
+class Ipv6AddressListFactory:
+
+    def parse(self, data, message_info):
+        addresses = []
+        while data.tell() < message_info.length:
+            addresses.append(ipaddress.IPv6Address(data.read(16)))
+        return Ipv6AddressList(addresses)
+
+
+class MacCounters:
+
+    def __init__(self, counters: List[int]):
+        self._counters = counters
+
+    @property
+    def if_in_unknown_protos(self):
+        return self._counters[0]
+
+    @property
+    def if_in_errors(self):
+        return self._counters[1]
+
+    @property
+    def if_out_errors(self):
+        return self._counters[2]
+
+    @property
+    def if_in_ucast_pkts(self):
+        return self._counters[3]
+
+    @property
+    def if_in_broadcast_pkts(self):
+        return self._counters[4]
+
+    @property
+    def if_in_discards(self):
+        return self._counters[5]
+
+    @property
+    def if_out_ucast_pkts(self):
+        return self._counters[6]
+
+    @property
+    def if_out_broadcast_pkts(self):
+        return self._counters[7]
+
+    @property
+    def if_out_discards(self):
+        return self._counters[8]
+
+    @property
+    def counters(self):
+        return self._counters
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+
+        return self.counters == other.counters
+
+    def __repr__(self):
+        return ('MacCounters(' +
+                f'if_in_unknown_protos={self.if_in_unknown_protos}, ' +
+                f'if_in_errors={self.if_in_errors}, ' +
+                f'if_out_errors={self.if_out_errors}, ' +
+                f'if_in_ucast_pkts={self.if_in_ucast_pkts}, ' +
+                f'if_in_broadcast_pkts={self.if_in_broadcast_pkts}, ' +
+                f'if_in_discards={self.if_in_discards}, ' +
+                f'if_out_ucast_pkts={self.if_out_ucast_pkts}, ' +
+                f'if_out_broadcast_pkts={self.if_out_broadcast_pkts}, ' +
+                f'if_out_discards={self.if_out_discards})')
+
+
+class MacCountersFactory:
+
+    def parse(self, data, message_info):
+        return MacCounters(struct.unpack('>9I', data.read(4 * 9)))
+
+
+class BatteryLevel:
+
+    def __init__(self, battery_level: int):
+        self._battery_level = battery_level
+
+    @property
+    def battery_level(self):
+        return self._battery_level
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+
+        return self.battery_level == other.battery_level
+
+    def __repr__(self):
+        return f'BatteryLevel(battery_level={self.battery_level})'
+
+
+class BatteryLevelFactory:
+
+    def parse(self, data, message_info):
+        return BatteryLevel(struct.unpack('>B', data.read(1))[0])
+
+
+class SupplyVoltage:
+
+    def __init__(self, supply_voltage: int):
+        self._supply_voltage = supply_voltage
+
+    @property
+    def supply_voltage(self):
+        return self._supply_voltage
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+
+        return self.supply_voltage == other.supply_voltage
+
+    def __repr__(self):
+        return f'SupplyVoltage(supply_voltage={self.supply_voltage})'
+
+
+class SupplyVoltageFactory:
+
+    def parse(self, data, message_info):
+        return SupplyVoltage(struct.unpack('>H', data.read(2))[0])
+
+
+class ChildTableEntry:
+
+    def __init__(self, timeout: int, child_id: int, mode: mle.Mode):
+        self._timeout = timeout
+        self._child_id = child_id
+        self._mode = mode
+
+    @property
+    def timeout(self):
+        return self._timeout
+
+    @property
+    def child_id(self):
+        return self._child_id
+
+    @property
+    def mode(self):
+        return self._mode
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+
+        return (self.timeout == other.timeout and
+                self.child_id == other.child_id and self.mode == other.mode)
+
+    def __repr__(self):
+        return f'ChildTableEntry(timeout={self.timeout}, child_id={self.child_id}, mode={self.mode})'
+
+
+class ChildTable:
+
+    def __init__(self, children: List[ChildTableEntry]):
+        self._children = sorted(children, key=lambda child: child.child_id)
+
+    @property
+    def children(self):
+        return self._children
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+
+        return self.children == other.children
+
+    def __repr__(self):
+        return f'ChildTable({self.children})'
+
+
+class ChildTableFactory:
+
+    def parse(self, data, message_info):
+        children = []
+        while message_info.length > 0:
+            timeout_and_id = struct.unpack('>H', data.read(2))[0]
+            message_info.length -= 2
+
+            timeout = (timeout_and_id & 0xf800) >> 11
+            child_id = timeout_and_id & 0x1fff
+
+            mode = mle.ModeFactory().parse(data, message_info)
+            message_info.length -= 1
+
+            children.append(ChildTableEntry(timeout, child_id, mode))
+        return ChildTable(children)
+
+
+class ChannelPages:
+
+    def __init__(self, channel_pages: bytes):
+        self._channel_pages = channel_pages
+
+    @property
+    def channel_pages(self):
+        return self._channel_pages
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+
+        return self.channel_pages == other.channel_pages
+
+    def __repr__(self):
+        return f'ChannelPages(channel_pages={self.channel_pages})'
+
+
+class ChannelPagesFactory:
+
+    def parse(self, data, message_info):
+        return ChannelPages(data.getvalue())
+
+
+class TypeList:
+
+    def __init__(self, tlv_types: List[int]):
+        self._tlv_types = tlv_types
+
+    @property
+    def tlv_types(self):
+        return self._tlv_types
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+
+        return self.tlv_types == other.tlv_types
+
+    def __repr__(self):
+        return f'TypeList(tlv_types={self.tlv_types})'
+
+
+class TypeListFactory:
+
+    def parse(self, data, message_info):
+        return TypeList([ord(t) for t in data.getvalue()])
+
+
+class MaxChildTimeout:
+
+    def __init__(self, max_child_timeout: int):
+        self._max_child_timeout = max_child_timeout
+
+    @property
+    def max_child_timeout(self):
+        return self._max_child_timeout
+
+    def __eq__(self, other):
+        common.expect_the_same_class(self, other)
+
+        return self.max_child_timeout == other.max_child_timeout
+
+    def __repr__(self):
+        return f'MaxChildTimeout(max_child_timeout={self.max_child_timeout})'
+
+
+class MaxChildTimeoutFactory:
+
+    def parse(self, data, message_info):
+        return MaxChildTimeout(struct.unpack('>I', data.read(4))[0])
diff --git a/tests/scripts/thread-cert/network_layer.py b/tests/scripts/thread-cert/network_layer.py
index a84c649..4febac5 100644
--- a/tests/scripts/thread-cert/network_layer.py
+++ b/tests/scripts/thread-cert/network_layer.py
@@ -59,6 +59,7 @@
 
 
 class TargetEid(object):
+
     def __init__(self, eid):
         self._eid = eid
 
@@ -75,6 +76,7 @@
 
 
 class TargetEidFactory(object):
+
     def parse(self, data, message_info):
         eid = bytearray(data.read(16))
 
@@ -82,6 +84,7 @@
 
 
 class MacExtendedAddress(object):
+
     def __init__(self, mac_address):
         self._mac_address = mac_address
 
@@ -95,11 +98,11 @@
 
     def __repr__(self):
         return "MacExtendedAddress(mac_address={})".format(
-            hexlify(self.mac_address)
-        )
+            hexlify(self.mac_address))
 
 
 class MacExtendedAddressFactory(object):
+
     def parse(self, data, message_info):
         mac_address = bytearray(data.read(8))
 
@@ -107,6 +110,7 @@
 
 
 class Rloc16(object):
+
     def __init__(self, rloc16):
         self._rloc16 = rloc16
 
@@ -123,6 +127,7 @@
 
 
 class Rloc16Factory(object):
+
     def parse(self, data, message_info):
         rloc16 = struct.unpack(">H", data.read(2))[0]
 
@@ -130,6 +135,7 @@
 
 
 class MlEid(object):
+
     def __init__(self, ml_eid):
         self._ml_eid = ml_eid
 
@@ -146,6 +152,7 @@
 
 
 class MlEidFactory(object):
+
     def parse(self, data, message_info):
         ml_eid = bytearray(data.read(8))
 
@@ -153,6 +160,7 @@
 
 
 class Status(object):
+
     def __init__(self, status):
         self._status = status
 
@@ -169,6 +177,7 @@
 
 
 class StatusFactory(object):
+
     def parse(self, data, message_info):
         status = StatusValues(ord(data.read(1)))
 
@@ -176,6 +185,7 @@
 
 
 class TimeSinceLastTransaction(object):
+
     def __init__(self, seconds):
         self._seconds = seconds
 
@@ -192,6 +202,7 @@
 
 
 class TimeSinceLastTransactionFactory(object):
+
     def parse(self, data, message_info):
         seconds = struct.unpack(">L", data.read(4))[0]
 
@@ -199,6 +210,7 @@
 
 
 class RouterMask(object):
+
     def __init__(self, id_sequence, router_id_mask):
         self._id_sequence = id_sequence
         self._router_id_mask = router_id_mask
@@ -213,18 +225,16 @@
 
     def __eq__(self, other):
         common.expect_the_same_class(self, other)
-        return (
-            self.id_sequence == other.id_sequence
-            and self.router_id_mask == other.router_id_mask
-        )
+        return (self.id_sequence == other.id_sequence and
+                self.router_id_mask == other.router_id_mask)
 
     def __repr__(self):
         return "RouterMask(id_sequence={}, router_id_mask={})".format(
-            self.id_sequence, hex(self.router_id_mask)
-        )
+            self.id_sequence, hex(self.router_id_mask))
 
 
 class RouterMaskFactory(object):
+
     def parse(self, data, message_info):
         id_sequence = ord(data.read(1))
         router_id_mask = struct.unpack(">Q", data.read(8))[0]
@@ -233,6 +243,7 @@
 
 
 class NdOption(object):
+
     def __init__(self, options):
         self._options = options
 
@@ -245,12 +256,12 @@
         return self.options == other.options
 
     def __repr__(self):
-        return "NdOption(options=[{}])".format(
-            ", ".join([str(opt) for opt in self.options])
-        )
+        return "NdOption(options=[{}])".format(", ".join(
+            [str(opt) for opt in self.options]))
 
 
 class NdOptionFactory(object):
+
     def parse(self, data, message_info):
         options = [opt for opt in bytearray(data.read())]
         return NdOption(options)
@@ -276,11 +287,13 @@
 
 
 class XtalAccuracyFactory:
+
     def parse(self, data, message_info):
         return XtalAccuracy()
 
 
 class ThreadNetworkData(object):
+
     def __init__(self, tlvs):
         self._tlvs = tlvs
 
@@ -293,12 +306,12 @@
         return self.tlvs == other.tlvs
 
     def __repr__(self):
-        return "ThreadNetworkData(tlvs=[{}])".format(
-            ", ".join([str(tlv) for tlv in self.tlvs])
-        )
+        return "ThreadNetworkData(tlvs=[{}])".format(", ".join(
+            [str(tlv) for tlv in self.tlvs]))
 
 
 class ThreadNetworkDataFactory(object):
+
     def __init__(self, network_data_tlvs_factory):
         self._network_data_tlvs_factory = network_data_tlvs_factory
 
diff --git a/tests/scripts/thread-cert/node.py b/tests/scripts/thread-cert/node.py
index 70110ba..8df2b38 100755
--- a/tests/scripts/thread-cert/node.py
+++ b/tests/scripts/thread-cert/node.py
@@ -38,13 +38,29 @@
 import socket
 import time
 import unittest
+import binascii
 
 
 class Node:
-    def __init__(self, nodeid, is_mtd=False, simulator=None):
+
+    def __init__(self,
+                 nodeid,
+                 is_mtd=False,
+                 simulator=None,
+                 version=None,
+                 is_bbr=False):
         self.nodeid = nodeid
         self.verbose = int(float(os.getenv('VERBOSE', 0)))
         self.node_type = os.getenv('NODE_TYPE', 'sim')
+        self.env_version = os.getenv('THREAD_VERSION', '1.1')
+        self.is_bbr = is_bbr
+        self._initialized = False
+
+        if version is not None:
+            self.version = version
+        else:
+            self.version = self.env_version
+
         self.simulator = simulator
         if self.simulator:
             self.simulator.add_node(self)
@@ -64,24 +80,57 @@
 
         self._initialized = True
 
+        self.set_extpanid(config.EXTENDED_PANID)
+
     def __init_sim(self, nodeid, mode):
         """ Initialize a simulation node. """
-        if 'OT_CLI_PATH' in os.environ.keys():
-            cmd = os.environ['OT_CLI_PATH']
-        elif 'top_builddir' in os.environ.keys():
-            srcdir = os.environ['top_builddir']
-            cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
-        else:
-            cmd = './ot-cli-%s' % mode
 
-        if 'RADIO_DEVICE' in os.environ:
-            cmd += ' -v %s' % os.environ['RADIO_DEVICE']
-            os.environ['NODE_ID'] = str(nodeid)
+        # Default command if no match below, will be overridden if below conditions are met.
+        cmd = './ot-cli-%s' % (mode)
 
-        cmd += ' %d' % nodeid
+        # If Thread version of node matches the testing environment version.
+        if self.version == self.env_version:
+            # Load Thread 1.2 BBR device when testing Thread 1.2 scenarios
+            # which requires device with Backbone functionality.
+            if self.version == '1.2' and self.is_bbr:
+                if 'OT_CLI_PATH_1_2_BBR' in os.environ:
+                    cmd = os.environ['OT_CLI_PATH_1_2_BBR']
+                elif 'top_builddir_1_2_bbr' in os.environ:
+                    srcdir = os.environ['top_builddir_1_2_bbr']
+                    cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
+
+            # Load Thread device of the testing environment version (may be 1.1 or 1.2)
+            else:
+                if 'OT_CLI_PATH' in os.environ:
+                    cmd = os.environ['OT_CLI_PATH']
+                elif 'top_builddir' in os.environ:
+                    srcdir = os.environ['top_builddir']
+                    cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
+
+            if 'RADIO_DEVICE' in os.environ:
+                cmd += ' --real-time-signal=+1 -v spinel+hdlc+uart://%s?forkpty-arg=%d' % (
+                    os.environ['RADIO_DEVICE'], nodeid)
+            else:
+                cmd += ' %d' % nodeid
+
+        # Load Thread 1.1 node when testing Thread 1.2 scenarios for interoperability
+        elif self.version == '1.1':
+            # Posix app
+            if 'OT_CLI_PATH_1_1' in os.environ:
+                cmd = os.environ['OT_CLI_PATH_1_1']
+            elif 'top_builddir_1_1' in os.environ:
+                srcdir = os.environ['top_builddir_1_1']
+                cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
+
+            if 'RADIO_DEVICE_1_1' in os.environ:
+                cmd += ' --real-time-signal=+1 -v spinel+hdlc+uart://%s?forkpty-arg=%d' % (
+                    os.environ['RADIO_DEVICE_1_1'], nodeid)
+            else:
+                cmd += ' %d' % nodeid
+
         print("%s" % cmd)
 
-        self.pexpect = pexpect.popen_spawn.PopenSpawn(cmd, timeout=4)
+        self.pexpect = pexpect.popen_spawn.PopenSpawn(cmd, timeout=10)
 
         # Add delay to ensure that the process is ready to receive commands.
         timeout = 0.4
@@ -95,30 +144,74 @@
 
     def __init_ncp_sim(self, nodeid, mode):
         """ Initialize an NCP simulation node. """
-        if 'RADIO_DEVICE' in os.environ:
-            args = ' %s' % os.environ['RADIO_DEVICE']
-            os.environ['NODE_ID'] = str(nodeid)
-        else:
-            args = ''
 
-        if 'OT_NCP_PATH' in os.environ.keys():
-            cmd = 'spinel-cli.py -p "%s%s" -n' % (
-                os.environ['OT_NCP_PATH'],
-                args,
-            )
-        elif "top_builddir" in os.environ.keys():
-            builddir = os.environ['top_builddir']
-            cmd = 'spinel-cli.py -p "%s/examples/apps/ncp/ot-ncp-%s%s" -n' % (
-                builddir,
-                mode,
-                args,
-            )
-        else:
-            cmd = 'spinel-cli.py -p "./ot-ncp-%s%s" -n' % (mode, args)
+        # Default command if no match below, will be overridden if below conditions are met.
+        cmd = 'spinel-cli.py -p ./ot-ncp-%s -n' % mode
+
+        # If Thread version of node matches the testing environment version.
+        if self.version == self.env_version:
+            if 'RADIO_DEVICE' in os.environ:
+                args = ' --real-time-signal=+1 spinel+hdlc+uart://%s?forkpty-arg=%d' % (
+                    os.environ['RADIO_DEVICE'], nodeid)
+            else:
+                args = ''
+
+            # Load Thread 1.2 BBR device when testing Thread 1.2 scenarios
+            # which requires device with Backbone functionality.
+            if self.version == '1.2' and self.is_bbr:
+                if 'OT_NCP_PATH_1_2_BBR' in os.environ:
+                    cmd = 'spinel-cli.py -p "%s%s" -n' % (
+                        os.environ['OT_NCP_PATH_1_2_BBR'],
+                        args,
+                    )
+                elif 'top_builddir_1_2_bbr' in os.environ:
+                    srcdir = os.environ['top_builddir_1_2_bbr']
+                    cmd = '%s/examples/apps/ncp/ot-ncp-%s' % (srcdir, mode)
+                    cmd = 'spinel-cli.py -p "%s%s" -n' % (
+                        cmd,
+                        args,
+                    )
+
+            # Load Thread device of the testing environment version (may be 1.1 or 1.2).
+            else:
+                if 'OT_NCP_PATH' in os.environ:
+                    cmd = 'spinel-cli.py -p "%s%s" -n' % (
+                        os.environ['OT_NCP_PATH'],
+                        args,
+                    )
+                elif 'top_builddir' in os.environ:
+                    srcdir = os.environ['top_builddir']
+                    cmd = '%s/examples/apps/ncp/ot-ncp-%s' % (srcdir, mode)
+                    cmd = 'spinel-cli.py -p "%s%s" -n' % (
+                        cmd,
+                        args,
+                    )
+
+        # Load Thread 1.1 node when testing Thread 1.2 scenarios for interoperability.
+        elif self.version == '1.1':
+            if 'RADIO_DEVICE_1_1' in os.environ:
+                args = ' --real-time-signal=+1 spinel+hdlc+uart://%s?forkpty-arg=%d' % (
+                    os.environ['RADIO_DEVICE_1_1'], nodeid)
+            else:
+                args = ''
+
+            if 'OT_NCP_PATH_1_1' in os.environ:
+                cmd = 'spinel-cli.py -p "%s%s" -n' % (
+                    os.environ['OT_NCP_PATH_1_1'],
+                    args,
+                )
+            elif 'top_builddir_1_1' in os.environ:
+                srcdir = os.environ['top_builddir_1_1']
+                cmd = '%s/examples/apps/ncp/ot-ncp-%s' % (srcdir, mode)
+                cmd = 'spinel-cli.py -p "%s%s" -n' % (
+                    cmd,
+                    args,
+                )
+
         cmd += ' %d' % nodeid
         print("%s" % cmd)
 
-        self.pexpect = pexpect.spawn(cmd, timeout=4)
+        self.pexpect = pexpect.spawn(cmd, timeout=10)
 
         # Add delay to ensure that the process is ready to receive commands.
         time.sleep(0.2)
@@ -141,14 +234,62 @@
                 if timeout <= 0:
                     raise
 
+    def _prepare_pattern(self, pattern):
+        """Build a new pexpect pattern matching line by line.
+
+        Adds lookahead and lookbehind to make each pattern match a whole line,
+        and add 'Done' as the first pattern.
+
+        Args:
+            pattern: a single regex or a list of regex.
+
+        Returns:
+            A list of regex.
+        """
+        EXPECT_LINE_FORMAT = r'(?<=[\r\n])%s(?=[\r\n])'
+
+        if isinstance(pattern, list):
+            pattern = [EXPECT_LINE_FORMAT % p for p in pattern]
+        else:
+            pattern = [EXPECT_LINE_FORMAT % pattern]
+
+        return [EXPECT_LINE_FORMAT % 'Done'] + pattern
+
+    def _expect_result(self, pattern, *args, **kwargs):
+        """Expect a single matching result.
+
+        The arguments are identical to pexpect.expect().
+
+        Returns:
+            The matched line.
+        """
+        results = self._expect_results(pattern, *args, **kwargs)
+        assert len(results) == 1
+        return results[0]
+
+    def _expect_results(self, pattern, *args, **kwargs):
+        """Expect multiple matching results.
+
+        The arguments are identical to pexpect.expect().
+
+        Returns:
+            The matched lines.
+        """
+        results = []
+        pattern = self._prepare_pattern(pattern)
+
+        while self._expect(pattern, *args, **kwargs):
+            results.append(self.pexpect.match.group(0).decode('utf8'))
+
+        return results
+
     def __init_soc(self, nodeid):
         """ Initialize a System-on-a-chip node connected via UART. """
         import fdpexpect
 
         serialPort = '/dev/ttyUSB%d' % ((nodeid - 1) * 2)
         self.pexpect = fdpexpect.fdspawn(
-            os.open(serialPort, os.O_RDWR | os.O_NONBLOCK | os.O_NOCTTY)
-        )
+            os.open(serialPort, os.O_RDWR | os.O_NONBLOCK | os.O_NOCTTY))
 
     def __del__(self):
         self.destroy()
@@ -157,12 +298,9 @@
         if not self._initialized:
             return
 
-        if (
-            hasattr(self.pexpect, 'proc')
-            and self.pexpect.proc.poll() is None
-            or not hasattr(self.pexpect, 'proc')
-            and self.pexpect.isalive()
-        ):
+        if (hasattr(self.pexpect, 'proc') and self.pexpect.proc.poll() is None
+                or
+                not hasattr(self.pexpect, 'proc') and self.pexpect.isalive()):
             print("%d: exit" % self.nodeid)
             self.pexpect.send('exit\n')
             self.pexpect.expect(pexpect.EOF)
@@ -178,17 +316,8 @@
         dummy_format_str = br"\[THCI\].*?type=%s.*?"
         join_ent_ntf = dummy_format_str % br"JOIN_ENT\.ntf"
         join_ent_rsp = dummy_format_str % br"JOIN_ENT\.rsp"
-        pattern = (
-            b"("
-            + join_fin_req
-            + b")|("
-            + join_fin_rsp
-            + b")|("
-            + join_ent_ntf
-            + b")|("
-            + join_ent_rsp
-            + b")"
-        )
+        pattern = (b"(" + join_fin_req + b")|(" + join_fin_rsp + b")|(" +
+                   join_ent_ntf + b")|(" + join_ent_rsp + b")")
 
         messages = []
         # There are at most 4 cert messages both for joiner and commissioner
@@ -243,14 +372,7 @@
     def get_commands(self):
         self.send_command('?')
         self._expect('Commands:')
-        commands = []
-        while True:
-            i = self._expect(['Done', r'(\S+)'])
-            if i != 0:
-                commands.append(self.pexpect.match.groups()[0])
-            else:
-                break
-        return commands
+        return self._expect_results(r'\S+')
 
     def set_mode(self, mode):
         cmd = 'mode %s' % mode
@@ -324,6 +446,97 @@
         self.send_command(cmd)
         self._expect('Done')
 
+    def get_bbr_registration_jitter(self):
+        self.send_command('bbr jitter')
+        return int(self._expect_result(r'\d+'))
+
+    def set_bbr_registration_jitter(self, jitter):
+        cmd = 'bbr jitter %d' % jitter
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def enable_backbone_router(self):
+        cmd = 'bbr enable'
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def disable_backbone_router(self):
+        cmd = 'bbr disable'
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def register_backbone_router(self):
+        cmd = 'bbr register'
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def get_backbone_router_state(self):
+        states = [r'Disabled', r'Primary', r'Secondary']
+        self.send_command('bbr state')
+        return self._expect_result(states)
+
+    def get_backbone_router(self):
+        cmd = 'bbr config'
+        self.send_command(cmd)
+        self._expect(r'(.*)Done')
+        g = self.pexpect.match.groups()
+        output = g[0].decode("utf-8")
+        lines = output.strip().split('\n')
+        lines = [l.strip() for l in lines]
+        ret = {}
+        for l in lines:
+            z = re.search(r'seqno:\s+([0-9]+)', l)
+            if z:
+                ret['seqno'] = int(z.groups()[0])
+
+            z = re.search(r'delay:\s+([0-9]+)', l)
+            if z:
+                ret['delay'] = int(z.groups()[0])
+
+            z = re.search(r'timeout:\s+([0-9]+)', l)
+            if z:
+                ret['timeout'] = int(z.groups()[0])
+
+        return ret
+
+    def set_backbone_router(self, seqno=None, reg_delay=None, mlr_timeout=None):
+        cmd = 'bbr config'
+
+        if seqno is not None:
+            cmd += ' seqno %d' % seqno
+
+        if reg_delay is not None:
+            cmd += ' delay %d' % reg_delay
+
+        if mlr_timeout is not None:
+            cmd += ' timeout %d' % mlr_timeout
+
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def set_domain_prefix(self, prefix, flags='prosD'):
+        self.add_prefix(prefix, flags)
+        self.register_netdata()
+
+    def remove_domain_prefix(self, prefix):
+        self.remove_prefix(prefix)
+        self.register_netdata()
+
+    def set_dua_iid(self, iid):
+        cmd = 'dua iid {}'.format(iid)
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def clear_dua_iid(self):
+        cmd = 'dua iid clear'
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def set_link_quality(self, addr, lqi):
+        cmd = 'macfilter rss add-lqi %s %s' % (addr, lqi)
+        self.send_command(cmd)
+        self._expect('Done')
+
     def remove_whitelist(self, addr):
         cmd = 'macfilter addr remove %s' % addr
         self.send_command(cmd)
@@ -331,11 +544,8 @@
 
     def get_addr16(self):
         self.send_command('rloc16')
-        i = self._expect('([0-9a-fA-F]{4})')
-        if i == 0:
-            addr16 = int(self.pexpect.match.groups()[0], 16)
-        self._expect('Done')
-        return addr16
+        rloc16 = self._expect_result(r'[0-9a-fA-F]{4}')
+        return int(rloc16, 16)
 
     def get_router_id(self):
         rloc16 = self.get_addr16()
@@ -343,37 +553,27 @@
 
     def get_addr64(self):
         self.send_command('extaddr')
-        i = self._expect('([0-9a-fA-F]{16})')
-        if i == 0:
-            addr64 = self.pexpect.match.groups()[0].decode("utf-8")
+        return self._expect_result('[0-9a-fA-F]{16}')
 
+    def set_addr64(self, addr64):
+        self.send_command('extaddr %s' % addr64)
         self._expect('Done')
-        return addr64
 
     def get_eui64(self):
         self.send_command('eui64')
-        i = self._expect('([0-9a-fA-F]{16})')
-        if i == 0:
-            addr64 = self.pexpect.match.groups()[0].decode("utf-8")
+        return self._expect_result('[0-9a-fA-F]{16}')
 
+    def set_extpanid(self, extpanid):
+        self.send_command('extpanid %s' % extpanid)
         self._expect('Done')
-        return addr64
 
     def get_joiner_id(self):
         self.send_command('joiner id')
-        i = self._expect('([0-9a-fA-F]{16})')
-        if i == 0:
-            addr = self.pexpect.match.groups()[0].decode("utf-8")
-        self._expect('Done')
-        return addr
+        return self._expect_result('[0-9a-fA-F]{16}')
 
     def get_channel(self):
         self.send_command('channel')
-        i = self._expect(r'(\d+)\r?\n')
-        if i == 0:
-            channel = int(self.pexpect.match.groups()[0])
-        self._expect('Done')
-        return channel
+        return int(self._expect_result(r'\d+'))
 
     def set_channel(self, channel):
         cmd = 'channel %d' % channel
@@ -382,11 +582,7 @@
 
     def get_masterkey(self):
         self.send_command('masterkey')
-        i = self._expect('([0-9a-fA-F]{32})')
-        if i == 0:
-            masterkey = self.pexpect.match.groups()[0].decode("utf-8")
-        self._expect('Done')
-        return masterkey
+        return self._expect_result('[0-9a-fA-F]{32}')
 
     def set_masterkey(self, masterkey):
         cmd = 'masterkey %s' % masterkey
@@ -395,11 +591,8 @@
 
     def get_key_sequence_counter(self):
         self.send_command('keysequence counter')
-        i = self._expect(r'(\d+)\r?\n')
-        if i == 0:
-            key_sequence_counter = int(self.pexpect.match.groups()[0])
-        self._expect('Done')
-        return key_sequence_counter
+        result = self._expect_result(r'\d+')
+        return int(result)
 
     def set_key_sequence_counter(self, key_sequence_counter):
         cmd = 'keysequence counter %d' % key_sequence_counter
@@ -416,47 +609,61 @@
         self.send_command(cmd)
         self._expect('Done')
 
+    def _escape_escapable(self, string):
+        """Escape CLI escapable characters in the given string.
+
+        Args:
+            string (str): UTF-8 input string.
+
+        Returns:
+            [str]: The modified string with escaped characters.
+        """
+        escapable_chars = '\\ \t\r\n'
+        for char in escapable_chars:
+            string = string.replace(char, '\\%s' % char)
+        return string
+
     def get_network_name(self):
         self.send_command('networkname')
-        while True:
-            i = self._expect(['Done', r'(\S+)'])
-            if i != 0:
-                network_name = self.pexpect.match.groups()[0].decode('utf-8')
-            else:
-                break
-        return network_name
+        return self._expect_result([r'\S+'])
 
     def set_network_name(self, network_name):
-        cmd = 'networkname %s' % network_name
+        cmd = 'networkname %s' % self._escape_escapable(network_name)
         self.send_command(cmd)
         self._expect('Done')
 
     def get_panid(self):
         self.send_command('panid')
-        i = self._expect('([0-9a-fA-F]{4})')
-        if i == 0:
-            panid = int(self.pexpect.match.groups()[0], 16)
-        self._expect('Done')
-        return panid
+        result = self._expect_result('0x[0-9a-fA-F]{4}')
+        return int(result, 16)
 
     def set_panid(self, panid=config.PANID):
         cmd = 'panid %d' % panid
         self.send_command(cmd)
         self._expect('Done')
 
+    def set_parent_priority(self, priority):
+        cmd = 'parentpriority %d' % priority
+        self.send_command(cmd)
+        self._expect('Done')
+
     def get_partition_id(self):
         self.send_command('leaderpartitionid')
-        i = self._expect(r'(\d+)\r?\n')
-        if i == 0:
-            weight = self.pexpect.match.groups()[0]
-        self._expect('Done')
-        return weight
+        return self._expect_result(r'\d+')
 
     def set_partition_id(self, partition_id):
         cmd = 'leaderpartitionid %d' % partition_id
         self.send_command(cmd)
         self._expect('Done')
 
+    def get_pollperiod(self):
+        self.send_command('pollperiod')
+        return self._expect_result(r'\d+')
+
+    def set_pollperiod(self, pollperiod):
+        self.send_command('pollperiod %d' % pollperiod)
+        self._expect('Done')
+
     def set_router_upgrade_threshold(self, threshold):
         cmd = 'routerupgradethreshold %d' % threshold
         self.send_command(cmd)
@@ -467,17 +674,20 @@
         self.send_command(cmd)
         self._expect('Done')
 
+    def prefer_router_id(self, router_id):
+        cmd = 'preferrouterid %d' % router_id
+        self.send_command(cmd)
+        self._expect('Done')
+
     def release_router_id(self, router_id):
         cmd = 'releaserouterid %d' % router_id
         self.send_command(cmd)
         self._expect('Done')
 
     def get_state(self):
-        states = [r'\ndetached', r'\nchild', r'\nrouter', r'\nleader']
+        states = [r'detached', r'child', r'router', r'leader']
         self.send_command('state')
-        match = self._expect(states)
-        self._expect('Done')
-        return states[match].strip(r'\n')
+        return self._expect_result(states)
 
     def set_state(self, state):
         cmd = 'state %s' % state
@@ -486,11 +696,7 @@
 
     def get_timeout(self):
         self.send_command('childtimeout')
-        i = self._expect(r'(\d+)\r?\n')
-        if i == 0:
-            timeout = self.pexpect.match.groups()[0]
-        self._expect('Done')
-        return timeout
+        return self._expect_result(r'\d+')
 
     def set_timeout(self, timeout):
         cmd = 'childtimeout %d' % timeout
@@ -504,11 +710,7 @@
 
     def get_weight(self):
         self.send_command('leaderweight')
-        i = self._expect(r'(\d+)\r?\n')
-        if i == 0:
-            weight = self.pexpect.match.groups()[0]
-        self._expect('Done')
-        return weight
+        return self._expect_result(r'\d+')
 
     def set_weight(self, weight):
         cmd = 'leaderweight %d' % weight
@@ -520,48 +722,27 @@
         self.send_command(cmd)
         self._expect('Done')
 
+    def add_ipmaddr(self, ipmaddr):
+        cmd = 'ipmaddr add %s' % ipmaddr
+        self.send_command(cmd)
+        self._expect('Done')
+
     def get_addrs(self):
-        addrs = []
         self.send_command('ipaddr')
 
-        while True:
-            i = self._expect([r'(\S+(:\S*)+)\r?\n', 'Done'])
-            if i == 0:
-                addrs.append(self.pexpect.match.groups()[0].decode("utf-8"))
-            elif i == 1:
-                break
-
-        return addrs
+        return self._expect_results(r'\S+(:\S*)+')
 
     def get_mleid(self):
-        addr = None
-        cmd = 'ipaddr mleid'
-        self.send_command(cmd)
-        i = self._expect(r'(\S+(:\S*)+)\r?\n')
-        if i == 0:
-            addr = self.pexpect.match.groups()[0].decode("utf-8")
-        self._expect('Done')
-        return addr
+        self.send_command('ipaddr mleid')
+        return self._expect_result(r'\S+(:\S*)+')
 
     def get_linklocal(self):
-        addr = None
-        cmd = 'ipaddr linklocal'
-        self.send_command(cmd)
-        i = self._expect(r'(\S+(:\S*)+)\r?\n')
-        if i == 0:
-            addr = self.pexpect.match.groups()[0].decode("utf-8")
-        self._expect('Done')
-        return addr
+        self.send_command('ipaddr linklocal')
+        return self._expect_result(r'\S+(:\S*)+')
 
     def get_rloc(self):
-        addr = None
-        cmd = 'ipaddr rloc'
-        self.send_command(cmd)
-        i = self._expect(r'(\S+(:\S*)+)\r?\n')
-        if i == 0:
-            addr = self.pexpect.match.groups()[0].decode("utf-8")
-        self._expect('Done')
-        return addr
+        self.send_command('ipaddr rloc')
+        return self._expect_result(r'\S+(:\S*)+')
 
     def get_addr(self, prefix):
         network = ipaddress.ip_network(u'%s' % str(prefix))
@@ -576,16 +757,36 @@
 
         return None
 
+    def has_ipaddr(self, address):
+        ipaddr = ipaddress.ip_address(address)
+        ipaddrs = self.get_addrs()
+        for addr in ipaddrs:
+            if isinstance(addr, bytearray):
+                addr = bytes(addr)
+            if ipaddress.ip_address(addr) == ipaddr:
+                return True
+        return False
+
+    def get_ipmaddrs(self):
+        self.send_command('ipmaddr')
+        return self._expect_results(r'\S+(:\S*)+')
+
+    def has_ipmaddr(self, address):
+        ipmaddr = ipaddress.ip_address(address)
+        ipmaddrs = self.get_ipmaddrs()
+        for addr in ipmaddrs:
+            if isinstance(addr, bytearray):
+                addr = bytes(addr)
+            if ipaddress.ip_address(addr) == ipmaddr:
+                return True
+        return False
+
     def get_addr_leader_aloc(self):
         addrs = self.get_addrs()
         for addr in addrs:
             segs = addr.split(':')
-            if (
-                segs[4] == '0'
-                and segs[5] == 'ff'
-                and segs[6] == 'fe00'
-                and segs[7] == 'fc00'
-            ):
+            if (segs[4] == '0' and segs[5] == 'ff' and segs[6] == 'fe00' and
+                    segs[7] == 'fc00'):
                 return addr
         return None
 
@@ -593,14 +794,11 @@
         eidcaches = []
         self.send_command('eidcache')
 
-        while True:
-            i = self._expect([r'([a-fA-F0-9\:]+) ([a-fA-F0-9]+)\r?\n', 'Done'])
-            if i == 0:
-                eid = self.pexpect.match.groups()[0].decode("utf-8")
-                rloc = self.pexpect.match.groups()[1].decode("utf-8")
-                eidcaches.append((eid, rloc))
-            elif i == 1:
-                break
+        pattern = self._prepare_pattern(r'([a-fA-F0-9\:]+) ([a-fA-F0-9]+)')
+        while self._expect(pattern):
+            eid = self.pexpect.match.groups()[0].decode("utf-8")
+            rloc = self.pexpect.match.groups()[1].decode("utf-8")
+            eidcaches.append((eid, rloc))
 
         return eidcaches
 
@@ -628,47 +826,32 @@
     def __getGlobalAddress(self):
         global_address = []
         for ip6Addr in self.get_addrs():
-            if (
-                (not re.match(config.LINK_LOCAL_REGEX_PATTERN, ip6Addr, re.I))
-                and (
-                    not re.match(
-                        config.MESH_LOCAL_PREFIX_REGEX_PATTERN, ip6Addr, re.I
-                    )
-                )
-                and (
-                    not re.match(
-                        config.ROUTING_LOCATOR_REGEX_PATTERN, ip6Addr, re.I
-                    )
-                )
-            ):
+            if ((not re.match(config.LINK_LOCAL_REGEX_PATTERN, ip6Addr, re.I))
+                    and (not re.match(config.MESH_LOCAL_PREFIX_REGEX_PATTERN,
+                                      ip6Addr, re.I)) and
+                (not re.match(config.ROUTING_LOCATOR_REGEX_PATTERN, ip6Addr,
+                              re.I))):
                 global_address.append(ip6Addr)
 
         return global_address
 
     def __getRloc(self):
         for ip6Addr in self.get_addrs():
-            if (
-                re.match(config.MESH_LOCAL_PREFIX_REGEX_PATTERN, ip6Addr, re.I)
-                and re.match(
-                    config.ROUTING_LOCATOR_REGEX_PATTERN, ip6Addr, re.I
-                )
-                and not (
-                    re.match(config.ALOC_FLAG_REGEX_PATTERN, ip6Addr, re.I)
-                )
-            ):
+            if (re.match(config.MESH_LOCAL_PREFIX_REGEX_PATTERN, ip6Addr, re.I)
+                    and re.match(config.ROUTING_LOCATOR_REGEX_PATTERN, ip6Addr,
+                                 re.I) and
+                    not (re.match(config.ALOC_FLAG_REGEX_PATTERN, ip6Addr,
+                                  re.I))):
                 return ip6Addr
         return None
 
     def __getAloc(self):
         aloc = []
         for ip6Addr in self.get_addrs():
-            if (
-                re.match(config.MESH_LOCAL_PREFIX_REGEX_PATTERN, ip6Addr, re.I)
-                and re.match(
-                    config.ROUTING_LOCATOR_REGEX_PATTERN, ip6Addr, re.I
-                )
-                and re.match(config.ALOC_FLAG_REGEX_PATTERN, ip6Addr, re.I)
-            ):
+            if (re.match(config.MESH_LOCAL_PREFIX_REGEX_PATTERN, ip6Addr, re.I)
+                    and re.match(config.ROUTING_LOCATOR_REGEX_PATTERN, ip6Addr,
+                                 re.I) and
+                    re.match(config.ALOC_FLAG_REGEX_PATTERN, ip6Addr, re.I)):
                 aloc.append(ip6Addr)
 
         return aloc
@@ -676,10 +859,9 @@
     def __getMleid(self):
         for ip6Addr in self.get_addrs():
             if re.match(
-                config.MESH_LOCAL_PREFIX_REGEX_PATTERN, ip6Addr, re.I
-            ) and not (
-                re.match(config.ROUTING_LOCATOR_REGEX_PATTERN, ip6Addr, re.I)
-            ):
+                    config.MESH_LOCAL_PREFIX_REGEX_PATTERN, ip6Addr,
+                    re.I) and not (re.match(
+                        config.ROUTING_LOCATOR_REGEX_PATTERN, ip6Addr, re.I)):
                 return ip6Addr
 
         return None
@@ -710,18 +892,14 @@
 
     def get_context_reuse_delay(self):
         self.send_command('contextreusedelay')
-        i = self._expect(r'(\d+)\r?\n')
-        if i == 0:
-            timeout = self.pexpect.match.groups()[0]
-        self._expect('Done')
-        return timeout
+        return self._expect_result(r'\d+')
 
     def set_context_reuse_delay(self, delay):
         cmd = 'contextreusedelay %d' % delay
         self.send_command(cmd)
         self._expect('Done')
 
-    def add_prefix(self, prefix, flags, prf='med'):
+    def add_prefix(self, prefix, flags='paosr', prf='med'):
         cmd = 'prefix add %s %s %s' % (prefix, flags, prf)
         self.send_command(cmd)
         self._expect('Done')
@@ -745,6 +923,30 @@
         self.send_command('netdataregister')
         self._expect('Done')
 
+    def send_network_diag_get(self, addr, tlv_types):
+        self.send_command('networkdiagnostic get %s %s' %
+                          (addr, ' '.join([str(t.value) for t in tlv_types])))
+
+        if isinstance(self.simulator, simulator.VirtualTime):
+            self.simulator.go(8)
+            timeout = 1
+        else:
+            timeout = 8
+
+        self._expect('Done', timeout=timeout)
+
+    def send_network_diag_reset(self, addr, tlv_types):
+        self.send_command('networkdiagnostic reset %s %s' %
+                          (addr, ' '.join([str(t.value) for t in tlv_types])))
+
+        if isinstance(self.simulator, simulator.VirtualTime):
+            self.simulator.go(8)
+            timeout = 1
+        else:
+            timeout = 8
+
+        self._expect('Done', timeout=timeout)
+
     def energy_scan(self, mask, count, period, scan_duration, ipaddr):
         cmd = 'commissioner energy %d %d %d %d %s' % (
             mask,
@@ -778,20 +980,9 @@
     def scan(self):
         self.send_command('scan')
 
-        results = []
-        while True:
-            i = self._expect(
-                [
-                    r'\|\s(\S+)\s+\|\s(\S+)\s+\|\s([0-9a-fA-F]{4})\s\|\s([0-9a-fA-F]{16})\s\|\s(\d+)\r?\n',
-                    'Done',
-                ]
-            )
-            if i == 0:
-                results.append(self.pexpect.match.groups())
-            else:
-                break
-
-        return results
+        return self._expect_results(
+            r'\|\s(\S+)\s+\|\s(\S+)\s+\|\s([0-9a-fA-F]{4})\s\|\s([0-9a-fA-F]{16})\s\|\s(\d+)'
+        )
 
     def ping(self, ipaddr, num_responses=1, size=None, timeout=5):
         cmd = 'ping %s' % ipaddr
@@ -800,21 +991,29 @@
 
         self.send_command(cmd)
 
-        if isinstance(self.simulator, simulator.VirtualTime):
-            self.simulator.go(timeout)
+        end = self.simulator.now() + timeout
+
+        responders = {}
 
         result = True
-        try:
-            responders = {}
-            while len(responders) < num_responses:
-                i = self._expect([r'from (\S+):'])
+        # ncp-sim doesn't print Done
+        done = (self.node_type == 'ncp-sim')
+        while len(responders) < num_responses or not done:
+            self.simulator.go(1)
+            try:
+                i = self._expect([r'from (\S+):', r'Done'], timeout=0.1)
+            except (pexpect.TIMEOUT, socket.timeout):
+                if self.simulator.now() < end:
+                    continue
+                result = False
+                if isinstance(self.simulator, simulator.VirtualTime):
+                    self.simulator.sync_devices()
+                break
+            else:
                 if i == 0:
                     responders[self.pexpect.match.groups()[0]] = 1
-            self._expect('\n')
-        except (pexpect.TIMEOUT, socket.timeout):
-            result = False
-            if isinstance(self.simulator, simulator.VirtualTime):
-                self.simulator.sync_devices()
+                elif i == 1:
+                    done = True
 
         return result
 
@@ -862,12 +1061,19 @@
             self.send_command(cmd)
             self._expect('Done')
 
+        # Set the meshlocal prefix in config.py
+        self.send_command('dataset meshlocalprefix %s' %
+                          config.MESH_LOCAL_PREFIX.split('/')[0])
+        self._expect('Done')
+
         self.send_command('dataset commit active')
         self._expect('Done')
 
-    def set_pending_dataset(
-        self, pendingtimestamp, activetimestamp, panid=None, channel=None
-    ):
+    def set_pending_dataset(self,
+                            pendingtimestamp,
+                            activetimestamp,
+                            panid=None,
+                            channel=None):
         self.send_command('dataset clear')
         self._expect('Done')
 
@@ -889,6 +1095,11 @@
             self.send_command(cmd)
             self._expect('Done')
 
+        # Set the meshlocal prefix in config.py
+        self.send_command('dataset meshlocalprefix %s' %
+                          config.MESH_LOCAL_PREFIX.split('/')[0])
+        self._expect('Done')
+
         self.send_command('dataset commit pending')
         self._expect('Done')
 
@@ -938,7 +1149,7 @@
             cmd += 'localprefix %s ' % mesh_local
 
         if network_name is not None:
-            cmd += 'networkname %s ' % network_name
+            cmd += 'networkname %s ' % self._escape_escapable(network_name)
 
         if binary is not None:
             cmd += 'binary %s ' % binary
@@ -980,11 +1191,187 @@
             cmd += 'localprefix %s ' % mesh_local
 
         if network_name is not None:
-            cmd += 'networkname %s ' % network_name
+            cmd += 'networkname %s ' % self._escape_escapable(network_name)
 
         self.send_command(cmd)
         self._expect('Done')
 
+    def coap_cancel(self):
+        """
+        Cancel a CoAP subscription.
+        """
+        cmd = 'coap cancel'
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def coap_delete(self, ipaddr, uri, con=False, payload=None):
+        """
+        Send a DELETE request via CoAP.
+        """
+        return self._coap_rq('delete', ipaddr, uri, con, payload)
+
+    def coap_get(self, ipaddr, uri, con=False, payload=None):
+        """
+        Send a GET request via CoAP.
+        """
+        return self._coap_rq('get', ipaddr, uri, con, payload)
+
+    def coap_observe(self, ipaddr, uri, con=False, payload=None):
+        """
+        Send a GET request via CoAP with Observe set.
+        """
+        return self._coap_rq('observe', ipaddr, uri, con, payload)
+
+    def coap_post(self, ipaddr, uri, con=False, payload=None):
+        """
+        Send a POST request via CoAP.
+        """
+        return self._coap_rq('post', ipaddr, uri, con, payload)
+
+    def coap_put(self, ipaddr, uri, con=False, payload=None):
+        """
+        Send a PUT request via CoAP.
+        """
+        return self._coap_rq('put', ipaddr, uri, con, payload)
+
+    def _coap_rq(self, method, ipaddr, uri, con=False, payload=None):
+        """
+        Issue a GET/POST/PUT/DELETE/GET OBSERVE request.
+        """
+        cmd = 'coap %s %s %s' % (method, ipaddr, uri)
+        if con:
+            cmd += ' con'
+        else:
+            cmd += ' non'
+
+        if payload is not None:
+            cmd += ' %s' % payload
+
+        self.send_command(cmd)
+        return self.coap_wait_response()
+
+    def coap_wait_response(self):
+        """
+        Wait for a CoAP response, and return it.
+        """
+        if isinstance(self.simulator, simulator.VirtualTime):
+            self.simulator.go(5)
+            timeout = 1
+        else:
+            timeout = 5
+
+        self._expect(
+            r'coap response from ([\da-f:]+)(?: OBS=(\d+))?'
+            r'(?: with payload: ([\da-f]+))?\b',
+            timeout=timeout)
+        (source, observe, payload) = self.pexpect.match.groups()
+        source = source.decode('UTF-8')
+
+        if observe is not None:
+            observe = int(observe, base=10)
+
+        if payload is not None:
+            payload = binascii.a2b_hex(payload).decode('UTF-8')
+
+        # Return the values received
+        return dict(source=source, observe=observe, payload=payload)
+
+    def coap_wait_request(self):
+        """
+        Wait for a CoAP request to be made.
+        """
+        if isinstance(self.simulator, simulator.VirtualTime):
+            self.simulator.go(5)
+            timeout = 1
+        else:
+            timeout = 5
+
+        self._expect(
+            r'coap request from ([\da-f:]+)(?: OBS=(\d+))?'
+            r'(?: with payload: ([\da-f]+))?\b',
+            timeout=timeout)
+        (source, observe, payload) = self.pexpect.match.groups()
+        source = source.decode('UTF-8')
+
+        if observe is not None:
+            observe = int(observe, base=10)
+
+        if payload is not None:
+            payload = binascii.a2b_hex(payload).decode('UTF-8')
+
+        # Return the values received
+        return dict(source=source, observe=observe, payload=payload)
+
+    def coap_wait_subscribe(self):
+        """
+        Wait for a CoAP client to be subscribed.
+        """
+        if isinstance(self.simulator, simulator.VirtualTime):
+            self.simulator.go(5)
+            timeout = 1
+        else:
+            timeout = 5
+
+        self._expect(r'Subscribing client\b', timeout=timeout)
+
+    def coap_wait_ack(self):
+        """
+        Wait for a CoAP notification ACK.
+        """
+        if isinstance(self.simulator, simulator.VirtualTime):
+            self.simulator.go(5)
+            timeout = 1
+        else:
+            timeout = 5
+
+        self._expect(
+            r'Received ACK in reply to notification '
+            r'from ([\da-f:]+)\b',
+            timeout=timeout)
+        (source,) = self.pexpect.match.groups()
+        source = source.decode('UTF-8')
+
+        return source
+
+    def coap_set_resource_path(self, path):
+        """
+        Set the path for the CoAP resource.
+        """
+        cmd = 'coap resource %s' % path
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def coap_set_content(self, content):
+        """
+        Set the content of the CoAP resource.
+        """
+        cmd = 'coap set %s' % content
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def coap_start(self):
+        """
+        Start the CoAP service.
+        """
+        cmd = 'coap start'
+        self.send_command(cmd)
+        self._expect('Done')
+
+    def coap_stop(self):
+        """
+        Stop the CoAP service.
+        """
+        cmd = 'coap stop'
+        self.send_command(cmd)
+
+        if isinstance(self.simulator, simulator.VirtualTime):
+            self.simulator.go(5)
+            timeout = 1
+        else:
+            timeout = 5
+
+        self._expect('Done', timeout=timeout)
+
     def coaps_start_psk(self, psk, pskIdentity):
         cmd = 'coaps psk %s %s' % (psk, pskIdentity)
         self.send_command(cmd)
diff --git a/tests/scripts/thread-cert/pcap.py b/tests/scripts/thread-cert/pcap.py
index 8887b49..d478811 100644
--- a/tests/scripts/thread-cert/pcap.py
+++ b/tests/scripts/thread-cert/pcap.py
@@ -26,7 +26,6 @@
 #  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #  POSSIBILITY OF SUCH DAMAGE.
 #
-
 """ Module to provide codec utilities for .pcap formatters. """
 
 import struct
diff --git a/tests/scripts/thread-cert/requirements.txt b/tests/scripts/thread-cert/requirements.txt
index 684b969..1d8ca8c 100644
--- a/tests/scripts/thread-cert/requirements.txt
+++ b/tests/scripts/thread-cert/requirements.txt
@@ -1,4 +1,3 @@
-enum34
 ipaddress
 pexpect
 pycryptodome
diff --git a/tests/scripts/thread-cert/simulator.py b/tests/scripts/thread-cert/simulator.py
index fb23ec5..1fc38da 100644
--- a/tests/scripts/thread-cert/simulator.py
+++ b/tests/scripts/thread-cert/simulator.py
@@ -48,12 +48,12 @@
 
 
 class BaseSimulator(object):
+
     def __init__(self):
         self._nodes = {}
         self.commissioning_messages = {}
         self._payload_parse_factory = mesh_cop.MeshCopCommandFactory(
-            mesh_cop.create_default_mesh_cop_tlv_factories()
-        )
+            mesh_cop.create_default_mesh_cop_tlv_factories())
         self._mesh_cop_msg_set = mesh_cop.create_mesh_cop_message_type_set()
 
     def __del__(self):
@@ -81,18 +81,18 @@
             if not node:
                 continue
             for (
-                direction,
-                type,
-                payload,
+                    direction,
+                    type,
+                    payload,
             ) in node.read_cert_messages_in_commissioning_log():
                 if direction == b'send':
                     msg = self._payload_parse_factory.parse(
-                        type.decode("utf-8"), io.BytesIO(payload)
-                    )
+                        type.decode("utf-8"), io.BytesIO(payload))
                     self.commissioning_messages[nodeid].append(msg)
 
 
 class RealTime(BaseSimulator):
+
     def __init__(self):
         super(RealTime, self).__init__()
         self._sniffer = config.create_default_thread_sniffer()
@@ -103,12 +103,13 @@
 
     def get_messages_sent_by(self, nodeid):
         messages = self._sniffer.get_messages_sent_by(nodeid).messages
-        ret = message.MessagesSet(
-            messages, self.commissioning_messages[nodeid]
-        )
+        ret = message.MessagesSet(messages, self.commissioning_messages[nodeid])
         self.commissioning_messages[nodeid] = []
         return ret
 
+    def now(self):
+        return time.time()
+
     def go(self, duration, nodeid=None):
         time.sleep(duration)
 
@@ -137,7 +138,7 @@
     END_OF_TIME = 0x7FFFFFFF
     PORT_OFFSET = int(os.getenv('PORT_OFFSET', '0'))
 
-    BLOCK_TIMEOUT = 4
+    BLOCK_TIMEOUT = 10
 
     RADIO_ONLY = os.getenv('RADIO_DEVICE') is not None
     NCP_SIM = os.getenv('NODE_TYPE', 'sim') == 'ncp-sim'
@@ -174,14 +175,18 @@
         self.sock.close()
         self.sock = None
 
-    def _add_message(self, nodeid, message):
+    def _add_message(self, nodeid, message_obj):
         addr = ('127.0.0.1', self.port + nodeid)
 
         # Ignore any exceptions
         try:
-            messages = self._message_factory.create(io.BytesIO(message))
+            messages = self._message_factory.create(io.BytesIO(message_obj))
             self.devices[addr]['msgs'] += messages
 
+        except message.DropPacketException:
+            print(
+                'Drop current packet because it cannot be handled in test scripts'
+            )
         except Exception as e:
             # Just print the exception to the console
             print("EXCEPTION: %s" % e)
@@ -207,9 +212,7 @@
         messages = self.devices[addr]['msgs']
         self.devices[addr]['msgs'] = []
 
-        ret = message.MessagesSet(
-            messages, self.commissioning_messages[nodeid]
-        )
+        ret = message.MessagesSet(messages, self.commissioning_messages[nodeid])
         self.commissioning_messages[nodeid] = []
         return ret
 
@@ -239,14 +242,9 @@
     def receive_events(self):
         """ Receive events until all devices are asleep. """
         while True:
-            if (
-                self.current_event
-                or len(self.awake_devices)
-                or (
-                    self._next_event_time() > self._pause_time
-                    and self.current_nodeid
-                )
-            ):
+            if (self.current_event or len(self.awake_devices) or
+                (self._next_event_time() > self._pause_time and
+                 self.current_nodeid)):
                 self.sock.settimeout(self.BLOCK_TIMEOUT)
                 try:
                     msg, addr = self.sock.recvfrom(self.MAX_MESSAGE)
@@ -311,10 +309,8 @@
 
                 self.awake_devices.discard(addr)
 
-                if (
-                    self.current_event
-                    and self.current_event[self.EVENT_ADDR] == addr
-                ):
+                if (self.current_event and
+                        self.current_event[self.EVENT_ADDR] == addr):
                     # print "Done\t", self.current_event
                     self.current_event = None
 
@@ -335,9 +331,8 @@
                         # print "-- Enqueue\t", event
                         bisect.insort(self.event_queue, event)
 
-                self._pcap.append(
-                    data, (event_time // 1000000, event_time % 1000000)
-                )
+                self._pcap.append(data,
+                                  (event_time // 1000000, event_time % 1000000))
                 self._add_message(addr[1] - self.port, data)
 
                 # add radio transmit done events to event queue
@@ -461,14 +456,16 @@
                 continue
             dbg_print('syncing', addr, elapsed)
             self.devices[addr]['time'] = self.current_time
-            message = struct.pack(
-                '=QBH', elapsed, self.OT_SIM_EVENT_ALARM_FIRED, 0
-            )
+            message = struct.pack('=QBH', elapsed,
+                                  self.OT_SIM_EVENT_ALARM_FIRED, 0)
             self._send_message(message, addr)
             self.awake_devices.add(addr)
             self.receive_events()
         self.awake_devices.clear()
 
+    def now(self):
+        return self.current_time / 1000000
+
     def go(self, duration, nodeid=None):
         assert self.current_time == self._pause_time
         duration = int(duration) * 1000000
diff --git a/tests/scripts/thread-cert/sniffer.py b/tests/scripts/thread-cert/sniffer.py
index 5bfbb82..d6ad885 100644
--- a/tests/scripts/thread-cert/sniffer.py
+++ b/tests/scripts/thread-cert/sniffer.py
@@ -45,7 +45,6 @@
 
 
 class Sniffer:
-
     """ Class representing the Sniffing node, whose main task is listening
         and logging message exchange performed by other nodes.
     """
diff --git a/tests/scripts/thread-cert/sniffer_transport.py b/tests/scripts/thread-cert/sniffer_transport.py
index 6f443d3..f5d9ca1 100644
--- a/tests/scripts/thread-cert/sniffer_transport.py
+++ b/tests/scripts/thread-cert/sniffer_transport.py
@@ -110,16 +110,14 @@
     def _nodeid_to_address(self, nodeid, ip_address=''):
         return (
             ip_address,
-            self.BASE_PORT
-            + (self.PORT_OFFSET * self.WELLKNOWN_NODE_ID)
-            + nodeid,
+            self.BASE_PORT + (self.PORT_OFFSET * self.WELLKNOWN_NODE_ID) +
+            nodeid,
         )
 
     def _address_to_nodeid(self, address):
         _, port = address
-        return (
-            port - self.BASE_PORT - (self.PORT_OFFSET * self.WELLKNOWN_NODE_ID)
-        )
+        return (port - self.BASE_PORT -
+                (self.PORT_OFFSET * self.WELLKNOWN_NODE_ID))
 
     def open(self):
         if self.is_opened:
@@ -132,8 +130,9 @@
 
         self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
-        self._socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
-                                socket.inet_aton(self.RADIO_GROUP) + socket.inet_aton('127.0.0.1'))
+        self._socket.setsockopt(
+            socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
+            socket.inet_aton(self.RADIO_GROUP) + socket.inet_aton('127.0.0.1'))
         self._socket.bind(self._nodeid_to_address(self.WELLKNOWN_NODE_ID))
 
     def close(self):
@@ -169,5 +168,6 @@
 
 
 class SnifferTransportFactory(object):
+
     def create_transport(self):
         return SnifferSocketTransport()
diff --git a/tests/scripts/thread-cert/test_coap.py b/tests/scripts/thread-cert/test_coap.py
index 35d4bb6..8747f01 100755
--- a/tests/scripts/thread-cert/test_coap.py
+++ b/tests/scripts/thread-cert/test_coap.py
@@ -106,8 +106,9 @@
 
 
 class TestCoapMessageOptionHeader(unittest.TestCase):
+
     def test_should_return_passed_on_value_when_read_extended_value_is_called_with_value_different_than_13_and_14(
-            self):
+        self):
         # GIVEN
         value = any_4bits_value_different_than_13_and_14()
 
@@ -118,7 +119,7 @@
         self.assertEqual(value, actual_value)
 
     def test_should_return_value_stored_in_first_byte_plus_13_when_read_extended_value_is_called_with_value_equal_13(
-            self):
+        self):
         # GIVEN
         value = 13
         extended_value = any_value()
@@ -132,7 +133,7 @@
         self.assertEqual(extended_value + 13, actual_value)
 
     def test_should_return_value_stored_in_first_byte_plus_269_when_read_extended_value_is_called_with_value_equal_14(
-            self):
+        self):
         # GIVEN
         value = 14
         extended_value = any_value()
@@ -146,7 +147,7 @@
         self.assertEqual(extended_value + 269, actual_value)
 
     def test_should_create_CoapOptionHeader_when_from_bytes_classmethod_is_called(
-            self):
+        self):
         # GIVEN
         delta = any_4bits_value_different_than_13_and_14()
         length = any_4bits_value_different_than_13_and_14()
@@ -161,7 +162,7 @@
         self.assertEqual(length, option_header.length)
 
     def test_should_return_True_when_is_payload_marker_property_called_with_delta_and_length_equal_15(
-            self):
+        self):
         # GIVEN
         delta = 15
         length = 15
@@ -176,6 +177,7 @@
 
 
 class TestCoapOption(unittest.TestCase):
+
     def test_should_return_type_value_when_type_property_is_called(self):
         # GIVEN
         _type = any_coap_option_type()
@@ -202,8 +204,9 @@
 
 
 class TestCoapOptionsFactory(unittest.TestCase):
+
     def test_should_create_list_of_CoapOption_from_bytearray_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
         delta = any_4bits_value_lower_or_equal_than_12()
         length = any_4bits_value_lower_or_equal_than_12()
@@ -223,6 +226,7 @@
 
 
 class TestCoapCode(unittest.TestCase):
+
     def test_should_return_code_value_when_code_property_is_called(self):
         # GIVEN
         code = any_code()
@@ -273,7 +277,7 @@
         self.assertEqual(code, (int(_class) << 5) | int(detail))
 
     def test_should_create_CoapCode_when_from_class_and_detail_classmethod_is_called(
-            self):
+        self):
         # GIVEN
         code = any_code()
 
@@ -287,7 +291,7 @@
         self.assertEqual(code, actual_coap_obj.code)
 
     def test_should_create_CoapCode_when_from_dotted_string_classmethod_is_called(
-            self):
+        self):
         # GIVEN
         code = any_code()
 
@@ -301,6 +305,7 @@
 
 
 class TestCoapMessage(unittest.TestCase):
+
     def test_should_return_version_value_when_version_property_is_called(self):
         # GIVEN
         version = any_version()
@@ -362,8 +367,7 @@
         self.assertEqual(code, actual_code)
 
     def test_should_return_message_id_value_when_message_id_property_is_called(
-        self
-    ):
+        self):
         # GIVEN
         message_id = any_message_id()
 
@@ -464,8 +468,7 @@
         self.assertEqual(payload, actual_payload)
 
     def test_should_return_uri_path_value_when_uri_path_property_is_called(
-        self
-    ):
+        self):
         # GIVEN
         uri_path = any_uri_path()
 
@@ -488,8 +491,9 @@
 
 
 class TestCoapMessageIdToUriPathBinder(unittest.TestCase):
+
     def test_should_add_uri_path_to_binds_when_add_uri_path_for_method_is_called(
-            self):
+        self):
         # GIVEN
         message_id = any_message_id()
         token = any_token()
@@ -504,7 +508,7 @@
         self.assertEqual(uri_path, binder.get_uri_path_for(message_id, token))
 
     def test_should_raise_KeyError_when_get_uri_path_for_is_called_but_it_is_not_present_in_database(
-            self):
+        self):
         # GIVEN
         message_id = any_message_id()
         token = any_token()
@@ -513,14 +517,16 @@
         binder = coap.CoapMessageIdToUriPathBinder()
 
         # THEN
-        self.assertRaises(
-            RuntimeError, binder.get_uri_path_for, message_id, token
-        )
+        self.assertRaises(RuntimeError, binder.get_uri_path_for, message_id,
+                          token)
 
 
 class TestCoapMessageFactory(unittest.TestCase):
+
     def _create_dummy_payload_factory(self):
+
         class DummyPayloadFactory:
+
             def parse(self, data, message_info):
                 return data.read()
 
@@ -536,16 +542,35 @@
         )
 
     def test_should_create_CoapMessage_from_solicit_request_data_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
-        data = bytearray(
-            [
-                0x42, 0x02, 0x00, 0xBD, 0x65, 0xee, 0xB1, 0x61,
-                0x02, 0x61, 0x73, 0xff, 0x01, 0x08, 0x16, 0x6E,
-                0x0A, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x01,
-                0x02,
-            ]
-        )
+        data = bytearray([
+            0x42,
+            0x02,
+            0x00,
+            0xBD,
+            0x65,
+            0xee,
+            0xB1,
+            0x61,
+            0x02,
+            0x61,
+            0x73,
+            0xff,
+            0x01,
+            0x08,
+            0x16,
+            0x6E,
+            0x0A,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x02,
+            0x04,
+            0x01,
+            0x02,
+        ])
 
         factory = self._create_coap_message_factory()
 
@@ -563,26 +588,54 @@
         self.assertEqual("as", coap_message.options[1].value.decode("utf-8"))
         self.assertEqual("/a/as", coap_message.uri_path)
         self.assertEqual(
-            bytearray(
-                [
-                    0x01, 0x08, 0x16, 0x6E, 0x0A, 0x00, 0x00, 0x00,
-                    0x00, 0x02, 0x04, 0x01, 0x02,
-                ]
-            ),
+            bytearray([
+                0x01,
+                0x08,
+                0x16,
+                0x6E,
+                0x0A,
+                0x00,
+                0x00,
+                0x00,
+                0x00,
+                0x02,
+                0x04,
+                0x01,
+                0x02,
+            ]),
             coap_message.payload,
         )
 
     def test_should_create_CoapMessage_from_solicit_response_data_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
-        data = bytearray(
-            [
-                0x62, 0x44, 0x00, 0xBD, 0x65, 0xee, 0xff, 0x04,
-                0x01, 0x00, 0x02, 0x02, 0x00, 0x00, 0x07, 0x09,
-                0x76, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
-                0x00,
-            ]
-        )
+        data = bytearray([
+            0x62,
+            0x44,
+            0x00,
+            0xBD,
+            0x65,
+            0xee,
+            0xff,
+            0x04,
+            0x01,
+            0x00,
+            0x02,
+            0x02,
+            0x00,
+            0x00,
+            0x07,
+            0x09,
+            0x76,
+            0x80,
+            0x00,
+            0x01,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+        ])
 
         mid_binder = coap.CoapMessageIdToUriPathBinder()
         mid_binder.add_uri_path_for(189, bytearray([0x65, 0xee]), "/a/as")
@@ -607,13 +660,26 @@
         self.assertEqual(bytearray([0x65, 0xee]), coap_message.token)
         self.assertEqual(None, coap_message.uri_path)
         self.assertEqual(
-            bytearray(
-                [
-                    0x04, 0x01, 0x00, 0x02, 0x02, 0x00, 0x00, 0x07,
-                    0x09, 0x76, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00,
-                    0x00, 0x00,
-                ]
-            ),
+            bytearray([
+                0x04,
+                0x01,
+                0x00,
+                0x02,
+                0x02,
+                0x00,
+                0x00,
+                0x07,
+                0x09,
+                0x76,
+                0x80,
+                0x00,
+                0x01,
+                0x00,
+                0x00,
+                0x00,
+                0x00,
+                0x00,
+            ]),
             coap_message.payload,
         )
 
diff --git a/tests/scripts/thread-cert/test_coap_observe.py b/tests/scripts/thread-cert/test_coap_observe.py
new file mode 100755
index 0000000..ae1161b
--- /dev/null
+++ b/tests/scripts/thread-cert/test_coap_observe.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import pexpect
+import config
+import thread_cert
+
+LEADER = 1
+ROUTER = 2
+
+
+class TestCoapObserve(thread_cert.TestCase):
+    """
+    Test suite for CoAP Observations (RFC7641).
+    """
+
+    SUPPORT_NCP = False
+
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
+
+    def _do_notification_test(self, con):
+        self.nodes[LEADER].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[ROUTER].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[ROUTER].get_state(), 'router')
+
+        mleid = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.ML_EID)
+
+        self.nodes[LEADER].coap_start()
+        self.nodes[LEADER].coap_set_resource_path('test')
+        self.nodes[LEADER].coap_set_content('Test123')
+
+        self.nodes[ROUTER].coap_start()
+        response = self.nodes[ROUTER].coap_observe(mleid, 'test', con=con)
+
+        first_observe = response['observe']
+        self.assertIsNotNone(first_observe)
+        self.assertEqual(response['payload'], 'Test123')
+        self.assertEqual(response['source'], mleid)
+
+        # This should have been emitted already, so should return immediately
+        self.nodes[LEADER].coap_wait_subscribe()
+
+        # Now change the content on the leader and wait for it to show up
+        # on the router.  We will do this a few times with a short delay.
+        for n in range(0, 5):
+            content = 'msg%d' % n
+
+            self.nodes[LEADER].coap_set_content(content)
+
+            response = self.nodes[ROUTER].coap_wait_response()
+            self.assertGreater(response['observe'], first_observe)
+            self.assertEqual(response['payload'], content)
+            self.assertEqual(response['source'], mleid)
+
+        # Stop subscription
+        self.nodes[ROUTER].coap_cancel()
+
+        # We should see the response, but with no Observe option
+        response = self.nodes[ROUTER].coap_wait_response()
+        self.assertIsNone(response['observe'])
+        # Content won't have changed.
+        self.assertEqual(response['payload'], content)
+
+        # Make another change, no notification should be sent
+        self.nodes[LEADER].coap_set_content('LastNote')
+
+        # This should time out!
+        try:
+            self.nodes[ROUTER].coap_wait_response()
+            self.fail('Should not have received notification')
+        except pexpect.exceptions.TIMEOUT:
+            pass
+
+        self.nodes[ROUTER].coap_stop()
+        self.nodes[LEADER].coap_stop()
+
+    def test_con(self):
+        """
+        Test notification using CON messages.
+        """
+        for trial in range(0, 3):
+            try:
+                self._do_notification_test(con=True)
+                break
+            except (AssertionError, pexpect.exceptions.TIMEOUT):
+                continue
+
+    def test_non(self):
+        """
+        Test notification using NON messages.
+        """
+        for trial in range(0, 3):
+            try:
+                self._do_notification_test(con=False)
+                break
+            except (AssertionError, pexpect.exceptions.TIMEOUT):
+                continue
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/test_coaps.py b/tests/scripts/thread-cert/test_coaps.py
index bb46366..98d74d9 100755
--- a/tests/scripts/thread-cert/test_coaps.py
+++ b/tests/scripts/thread-cert/test_coaps.py
@@ -30,36 +30,28 @@
 import unittest
 
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 
 
-class TestCoaps(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class TestCoaps(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xface)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/test_common.py b/tests/scripts/thread-cert/test_common.py
index 42939cd..f7797c3 100755
--- a/tests/scripts/thread-cert/test_common.py
+++ b/tests/scripts/thread-cert/test_common.py
@@ -51,8 +51,9 @@
 
 
 class TestMessageInfo(unittest.TestCase):
+
     def test_should_return_source_ipv6_value_when_source_ipv6_property_is_called(
-            self):
+        self):
         # GIVEN
         source_ipv6 = any_ipv6_address()
 
@@ -63,12 +64,11 @@
         actual_source_ipv6 = message_info.source_ipv6
 
         # THEN
-        self.assertEqual(
-            ipaddress.ip_address(bytes(source_ipv6)), actual_source_ipv6
-        )
+        self.assertEqual(ipaddress.ip_address(bytes(source_ipv6)),
+                         actual_source_ipv6)
 
     def test_should_return_destination_ipv6_value_when_destination_ipv6_property_is_called(
-            self):
+        self):
         # GIVEN
         destination_ipv6 = any_ipv6_address()
 
@@ -85,7 +85,7 @@
         )
 
     def test_should_return_source_eui64_value_when_source_eui64_property_is_called(
-            self):
+        self):
         # GIVEN
         source_mac_address = any_eui64()
 
@@ -99,7 +99,7 @@
         self.assertEqual(source_mac_address, actual_source_mac_address)
 
     def test_should_return_destination_eui64_value_when_destination_eui64_property_is_called(
-            self):
+        self):
         # GIVEN
         destination_mac_address = any_eui64()
 
@@ -110,14 +110,14 @@
         actual_destination_mac_address = message_info.destination_mac_address
 
         # THEN
-        self.assertEqual(
-            destination_mac_address, actual_destination_mac_address
-        )
+        self.assertEqual(destination_mac_address,
+                         actual_destination_mac_address)
 
 
 class TestMacAddress(unittest.TestCase):
+
     def test_should_create_MacAddress_from_eui64_when_from_eui64_classmethod_is_called(
-            self):
+        self):
         # GIVEN
         eui64 = any_eui64()
 
@@ -129,7 +129,7 @@
         self.assertEqual(eui64, mac_address.mac_address)
 
     def test_should_create_MacAddress_from_rloc16_int_when_from_rloc16_classmethod_is_called(
-            self):
+        self):
         # GIVEN
         rloc16 = any_rloc16_int()
 
@@ -141,7 +141,7 @@
         self.assertEqual(struct.pack(">H", rloc16), mac_address.mac_address)
 
     def test_should_create_MacAddress_from_rloc16_bytearray_when_from_rloc16_classmethod_is_called(
-            self):
+        self):
         # GIVEN
         rloc16 = any_rloc16_bytearray()
 
@@ -153,7 +153,7 @@
         self.assertEqual(rloc16, mac_address.mac_address)
 
     def test_should_convert_short_MacAddress_to_iid_when_convert_method_is_called(
-            self):
+        self):
         # GIVEN
         rloc16 = any_rloc16_bytearray()
 
@@ -164,11 +164,10 @@
 
         # THEN
         self.assertEqual(
-            bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00]) + rloc16, iid
-        )
+            bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00]) + rloc16, iid)
 
     def test_should_convert_eui64_MacAddress_to_iid_when_convert_method_is_called(
-            self):
+        self):
         # GIVEN
         eui64 = any_eui64()
 
diff --git a/tests/scripts/thread-cert/test_crypto.py b/tests/scripts/thread-cert/test_crypto.py
index 3e00407..c18b358 100755
--- a/tests/scripts/thread-cert/test_crypto.py
+++ b/tests/scripts/thread-cert/test_crypto.py
@@ -36,12 +36,15 @@
 import common
 import net_crypto
 
-master_key = bytearray([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-                        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff])
+master_key = bytearray([
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
+    0xcc, 0xdd, 0xee, 0xff
+])
 
 
 def convert_aux_sec_hdr_to_bytearray(aux_sec_hdr):
-    data = bytearray([aux_sec_hdr.security_level | ((aux_sec_hdr.key_id_mode & 0x03) << 3)])
+    data = bytearray(
+        [aux_sec_hdr.security_level | ((aux_sec_hdr.key_id_mode & 0x03) << 3)])
     data += struct.pack("<L", aux_sec_hdr.frame_counter)
     data += aux_sec_hdr.key_id
     return data
@@ -73,7 +76,8 @@
     key_id_mode = any_key_id_mode()
     key_id = any_key_id(key_id_mode)
 
-    return net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), any_frame_counter(), key_id)
+    return net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(),
+                                              any_frame_counter(), key_id)
 
 
 def any_frame_counter():
@@ -96,7 +100,8 @@
 
 class TestCryptoEngine(unittest.TestCase):
 
-    def test_should_decrypt_bytearray_to_mle_message_when_decrypt_method_is_called(self):
+    def test_should_decrypt_bytearray_to_mle_message_when_decrypt_method_is_called(
+        self):
         # GIVEN
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -105,32 +110,38 @@
         message_info.source_ipv6 = "fe80::235:cc94:d77a:07e8"
         message_info.destination_ipv6 = "ff02::2"
 
-        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(key_id_mode=2,
-                                                                      security_level=5,
-                                                                      frame_counter=262165,
-                                                                      key_id=bytearray([0x00, 0x00, 0x00, 0x00, 0x01]))
-        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr)
+        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(
+            key_id_mode=2,
+            security_level=5,
+            frame_counter=262165,
+            key_id=bytearray([0x00, 0x00, 0x00, 0x00, 0x01]))
+        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(
+            message_info.aux_sec_hdr)
 
-        data = bytearray([0x9a, 0x5a, 0x9a, 0x5b, 0xba, 0x25, 0x9c, 0x5e,
-                          0x58, 0xa2, 0x7e, 0x75, 0x74, 0xef, 0x79, 0xbc,
-                          0x4f, 0xa3, 0xf9, 0xae, 0xa8, 0x34, 0xf6, 0xf2,
-                          0x37, 0x21, 0x93, 0x60])
+        data = bytearray([
+            0x9a, 0x5a, 0x9a, 0x5b, 0xba, 0x25, 0x9c, 0x5e, 0x58, 0xa2, 0x7e,
+            0x75, 0x74, 0xef, 0x79, 0xbc, 0x4f, 0xa3, 0xf9, 0xae, 0xa8, 0x34,
+            0xf6, 0xf2, 0x37, 0x21, 0x93, 0x60
+        ])
 
         mic = bytearray([0xe1, 0xb5, 0xa2, 0x53])
 
-        net_crypto_engine = net_crypto.CryptoEngine(net_crypto.MleCryptoMaterialCreator(master_key))
+        net_crypto_engine = net_crypto.CryptoEngine(
+            net_crypto.MleCryptoMaterialCreator(master_key))
 
         # WHEN
         mle_msg = net_crypto_engine.decrypt(data, mic, message_info)
 
         # THEN
-        expected_mle_msg = bytearray([0x04, 0x00, 0x02, 0x00, 0x00, 0x09, 0x0b, 0x8f,
-                                      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
-                                      0x01, 0xf1, 0x0b, 0x08, 0x65, 0x5e, 0x0f, 0x83,
-                                      0x40, 0xc7, 0x83, 0x31])
+        expected_mle_msg = bytearray([
+            0x04, 0x00, 0x02, 0x00, 0x00, 0x09, 0x0b, 0x8f, 0x80, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0xf1, 0x0b, 0x08, 0x65, 0x5e,
+            0x0f, 0x83, 0x40, 0xc7, 0x83, 0x31
+        ])
         self.assertEqual(expected_mle_msg, mle_msg)
 
-    def test_should_encrypt_mle_message_to_bytearray_when_encrypt_method_is_called(self):
+    def test_should_encrypt_mle_message_to_bytearray_when_encrypt_method_is_called(
+        self):
         # GIVEN
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -139,31 +150,37 @@
         message_info.source_ipv6 = "fe80::235:cc94:d77a:07e8"
         message_info.destination_ipv6 = "ff02::2"
 
-        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(key_id_mode=2,
-                                                                      security_level=5,
-                                                                      frame_counter=262165,
-                                                                      key_id=bytearray([0x00, 0x00, 0x00, 0x00, 0x01]))
-        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr)
+        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(
+            key_id_mode=2,
+            security_level=5,
+            frame_counter=262165,
+            key_id=bytearray([0x00, 0x00, 0x00, 0x00, 0x01]))
+        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(
+            message_info.aux_sec_hdr)
 
-        mle_msg = bytearray([0x04, 0x00, 0x02, 0x00, 0x00, 0x09, 0x0b, 0x8f,
-                             0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
-                             0x01, 0xf1, 0x0b, 0x08, 0x65, 0x5e, 0x0f, 0x83,
-                             0x40, 0xc7, 0x83, 0x31])
+        mle_msg = bytearray([
+            0x04, 0x00, 0x02, 0x00, 0x00, 0x09, 0x0b, 0x8f, 0x80, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0xf1, 0x0b, 0x08, 0x65, 0x5e,
+            0x0f, 0x83, 0x40, 0xc7, 0x83, 0x31
+        ])
 
-        net_crypto_engine = net_crypto.CryptoEngine(net_crypto.MleCryptoMaterialCreator(master_key))
+        net_crypto_engine = net_crypto.CryptoEngine(
+            net_crypto.MleCryptoMaterialCreator(master_key))
 
         # WHEN
         encrypted_data, mic = net_crypto_engine.encrypt(mle_msg, message_info)
 
         # THEN
-        expected_encrypted_data = bytearray([0x9a, 0x5a, 0x9a, 0x5b, 0xba, 0x25, 0x9c, 0x5e,
-                                             0x58, 0xa2, 0x7e, 0x75, 0x74, 0xef, 0x79, 0xbc,
-                                             0x4f, 0xa3, 0xf9, 0xae, 0xa8, 0x34, 0xf6, 0xf2,
-                                             0x37, 0x21, 0x93, 0x60, 0xe1, 0xb5, 0xa2, 0x53])
+        expected_encrypted_data = bytearray([
+            0x9a, 0x5a, 0x9a, 0x5b, 0xba, 0x25, 0x9c, 0x5e, 0x58, 0xa2, 0x7e,
+            0x75, 0x74, 0xef, 0x79, 0xbc, 0x4f, 0xa3, 0xf9, 0xae, 0xa8, 0x34,
+            0xf6, 0xf2, 0x37, 0x21, 0x93, 0x60, 0xe1, 0xb5, 0xa2, 0x53
+        ])
 
         self.assertEqual(expected_encrypted_data, encrypted_data + mic)
 
-    def test_should_encrypt_and_decrypt_random_data_content_when_proper_methods_are_called(self):
+    def test_should_encrypt_and_decrypt_random_data_content_when_proper_methods_are_called(
+        self):
         # GIVEN
         data = any_data()
 
@@ -173,18 +190,22 @@
         security_level = 5
 
         message_info = common.MessageInfo()
-        message_info.source_mac_address = common.MacAddress.from_eui64(any_eui64())
+        message_info.source_mac_address = common.MacAddress.from_eui64(
+            any_eui64())
 
         message_info.source_ipv6 = any_ip_address()
         message_info.destination_ipv6 = any_ip_address()
 
-        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(key_id_mode=key_id_mode,
-                                                                      security_level=security_level,
-                                                                      frame_counter=any_frame_counter(),
-                                                                      key_id=any_key_id(key_id_mode))
-        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr)
+        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(
+            key_id_mode=key_id_mode,
+            security_level=security_level,
+            frame_counter=any_frame_counter(),
+            key_id=any_key_id(key_id_mode))
+        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(
+            message_info.aux_sec_hdr)
 
-        net_crypto_engine = net_crypto.CryptoEngine(net_crypto.MleCryptoMaterialCreator(master_key))
+        net_crypto_engine = net_crypto.CryptoEngine(
+            net_crypto.MleCryptoMaterialCreator(master_key))
 
         # WHEN
         enc_data, mic = net_crypto_engine.encrypt(data, message_info)
@@ -195,7 +216,6 @@
 
 
 class TestCryptoMaterialCreator(unittest.TestCase):
-
     """ Key generaion was described in Thread specification.
 
     Read more: Thread 1.1.0 Specification Candidate Final - 7.1.4 Key Generation
@@ -203,7 +223,8 @@
     Test vectors was taken from thread specification.
     """
 
-    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_0(self):
+    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_0(
+        self):
         """
         7.1.4.1 Test Vector 1
         """
@@ -217,12 +238,21 @@
         mle_key, mac_key = creator._generate_keys(sequence_counter)
 
         # THEN
-        self.assertEqual(mle_key, bytearray([0x54, 0x45, 0xf4, 0x15, 0x8f, 0xd7, 0x59, 0x12,
-                                             0x17, 0x58, 0x09, 0xf8, 0xb5, 0x7a, 0x66, 0xa4]))
-        self.assertEqual(mac_key, bytearray([0xde, 0x89, 0xc5, 0x3a, 0xf3, 0x82, 0xb4, 0x21,
-                                             0xe0, 0xfd, 0xe5, 0xa9, 0xba, 0xe3, 0xbe, 0xf0]))
+        self.assertEqual(
+            mle_key,
+            bytearray([
+                0x54, 0x45, 0xf4, 0x15, 0x8f, 0xd7, 0x59, 0x12, 0x17, 0x58,
+                0x09, 0xf8, 0xb5, 0x7a, 0x66, 0xa4
+            ]))
+        self.assertEqual(
+            mac_key,
+            bytearray([
+                0xde, 0x89, 0xc5, 0x3a, 0xf3, 0x82, 0xb4, 0x21, 0xe0, 0xfd,
+                0xe5, 0xa9, 0xba, 0xe3, 0xbe, 0xf0
+            ]))
 
-    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_1(self):
+    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_1(
+        self):
         """
         7.1.4.2 Test Vector 2
         """
@@ -236,12 +266,21 @@
         mle_key, mac_key = creator._generate_keys(sequence_counter)
 
         # THEN
-        self.assertEqual(mle_key, bytearray([0x8f, 0x4c, 0xd1, 0xa2, 0x7d, 0x95, 0xc0, 0x7d,
-                                             0x12, 0xdb, 0x89, 0x74, 0xbd, 0x61, 0x5c, 0x13]))
-        self.assertEqual(mac_key, bytearray([0x9b, 0xe0, 0xd1, 0xaf, 0x7b, 0xd8, 0x73, 0x50,
-                                             0xde, 0xab, 0xcd, 0xd0, 0x7f, 0xeb, 0xb9, 0xd5]))
+        self.assertEqual(
+            mle_key,
+            bytearray([
+                0x8f, 0x4c, 0xd1, 0xa2, 0x7d, 0x95, 0xc0, 0x7d, 0x12, 0xdb,
+                0x89, 0x74, 0xbd, 0x61, 0x5c, 0x13
+            ]))
+        self.assertEqual(
+            mac_key,
+            bytearray([
+                0x9b, 0xe0, 0xd1, 0xaf, 0x7b, 0xd8, 0x73, 0x50, 0xde, 0xab,
+                0xcd, 0xd0, 0x7f, 0xeb, 0xb9, 0xd5
+            ]))
 
-    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_2(self):
+    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_2(
+        self):
         """
         7.1.4.3 Test Vector 3
         """
@@ -255,10 +294,18 @@
         mle_key, mac_key = creator._generate_keys(sequence_counter)
 
         # THEN
-        self.assertEqual(mle_key, bytearray([0x01, 0x6e, 0x2a, 0xb8, 0xec, 0x88, 0x87, 0x96,
-                                             0x87, 0xa7, 0x2e, 0x0a, 0x35, 0x7e, 0xcf, 0x2a]))
-        self.assertEqual(mac_key, bytearray([0x56, 0x41, 0x09, 0xe9, 0xd2, 0xaa, 0xd7, 0xf7,
-                                             0x23, 0xec, 0x3b, 0x96, 0x11, 0x0e, 0xef, 0xa3]))
+        self.assertEqual(
+            mle_key,
+            bytearray([
+                0x01, 0x6e, 0x2a, 0xb8, 0xec, 0x88, 0x87, 0x96, 0x87, 0xa7,
+                0x2e, 0x0a, 0x35, 0x7e, 0xcf, 0x2a
+            ]))
+        self.assertEqual(
+            mac_key,
+            bytearray([
+                0x56, 0x41, 0x09, 0xe9, 0xd2, 0xaa, 0xd7, 0xf7, 0x23, 0xec,
+                0x3b, 0x96, 0x11, 0x0e, 0xef, 0xa3
+            ]))
 
 
 class TestMleCryptoMaterialCreator(unittest.TestCase):
@@ -272,7 +319,8 @@
         creator = net_crypto.MleCryptoMaterialCreator(master_key)
 
         # WHEN
-        nonce = creator._create_nonce(source_eui64, frame_counter, security_level)
+        nonce = creator._create_nonce(source_eui64, frame_counter,
+                                      security_level)
 
         # THEN
         nonce_bytes = io.BytesIO(nonce)
@@ -281,7 +329,8 @@
         self.assertEqual(struct.pack(">L", frame_counter), nonce_bytes.read(4))
         self.assertEqual(security_level, ord(nonce_bytes.read(1)))
 
-    def test_should_create_authenticated_data_when_create_authenticated_data_method_is_called(self):
+    def test_should_create_authenticated_data_when_create_authenticated_data_method_is_called(
+        self):
         """
         Only Key id mode 2.
         Length of the Auxiliary Security Header is constantly equal 10.
@@ -290,64 +339,68 @@
         # GIVEN
         source_address = any_ip_address()
         destination_address = any_ip_address()
-        auxiliary_security_header_bytes = convert_aux_sec_hdr_to_bytearray(any_auxiliary_security_header())
+        auxiliary_security_header_bytes = convert_aux_sec_hdr_to_bytearray(
+            any_auxiliary_security_header())
 
         creator = net_crypto.MleCryptoMaterialCreator(master_key)
 
         # WHEN
         authenticated_data = creator._create_authenticated_data(
-            source_address, destination_address, auxiliary_security_header_bytes)
+            source_address, destination_address,
+            auxiliary_security_header_bytes)
 
         # THEN
         authenticated_data_bytes = io.BytesIO(authenticated_data)
 
-        self.assertEqual(source_address.packed, authenticated_data_bytes.read(16))
-        self.assertEqual(destination_address.packed, authenticated_data_bytes.read(16))
-        self.assertEqual(auxiliary_security_header_bytes, authenticated_data_bytes.read(10))
+        self.assertEqual(source_address.packed,
+                         authenticated_data_bytes.read(16))
+        self.assertEqual(destination_address.packed,
+                         authenticated_data_bytes.read(16))
+        self.assertEqual(auxiliary_security_header_bytes,
+                         authenticated_data_bytes.read(10))
 
-    def test_should_create_key_and_nonce_and_auth_data_when_create_key_and_nonce_and_auth_data_is_called(self):
+    def test_should_create_key_and_nonce_and_auth_data_when_create_key_and_nonce_and_auth_data_is_called(
+        self):
         # GIVEN
         message_info = common.MessageInfo()
-        message_info.source_mac_address = common.MacAddress.from_eui64(any_eui64())
+        message_info.source_mac_address = common.MacAddress.from_eui64(
+            any_eui64())
 
         message_info.source_ipv6 = any_ip_address()
         message_info.destination_ipv6 = any_ip_address()
 
         message_info.aux_sec_hdr = any_auxiliary_security_header()
-        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr)
+        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(
+            message_info.aux_sec_hdr)
 
         creator = net_crypto.MleCryptoMaterialCreator(master_key)
 
         # WHEN
-        key, nonce, auth_data = creator.create_key_and_nonce_and_authenticated_data(message_info)
+        key, nonce, auth_data = creator.create_key_and_nonce_and_authenticated_data(
+            message_info)
 
         # THEN
         self.assertEqual(
-            message_info.source_mac_address.mac_address
-            + struct.pack(
-                ">LB",
-                message_info.aux_sec_hdr.frame_counter,
-                message_info.aux_sec_hdr.security_level
-            ),
-            nonce
-        )
+            message_info.source_mac_address.mac_address +
+            struct.pack(">LB", message_info.aux_sec_hdr.frame_counter,
+                        message_info.aux_sec_hdr.security_level), nonce)
 
         self.assertEqual(
-            message_info.source_ipv6.packed
-            + message_info.destination_ipv6.packed
-            + message_info.aux_sec_hdr_bytes,
-            auth_data
-        )
+            message_info.source_ipv6.packed +
+            message_info.destination_ipv6.packed +
+            message_info.aux_sec_hdr_bytes, auth_data)
 
 
 class TestAuxiliarySecurityHeader(unittest.TestCase):
 
-    def test_should_return_key_id_mode_value_when_key_id_mode_property_is_called(self):
+    def test_should_return_key_id_mode_value_when_key_id_mode_property_is_called(
+        self):
         # GIVEN
         key_id_mode = any_key_id_mode()
 
         aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(
-            key_id_mode, any_security_level(), any_frame_counter(), any_key_id(key_id_mode))
+            key_id_mode, any_security_level(), any_frame_counter(),
+            any_key_id(key_id_mode))
 
         # WHEN
         actual_key_id_mode = aux_sec_hdr_obj.key_id_mode
@@ -355,13 +408,15 @@
         # THEN
         self.assertEqual(key_id_mode, actual_key_id_mode)
 
-    def test_should_return_security_level_value_when_security_level_property_is_called(self):
+    def test_should_return_security_level_value_when_security_level_property_is_called(
+        self):
         # GIVEN
         security_level = any_security_level()
         key_id_mode = any_key_id_mode()
 
         aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(
-            key_id_mode, security_level, any_frame_counter(), any_key_id(key_id_mode))
+            key_id_mode, security_level, any_frame_counter(),
+            any_key_id(key_id_mode))
 
         # WHEN
         actual_security_level = aux_sec_hdr_obj.security_level
@@ -369,13 +424,15 @@
         # THEN
         self.assertEqual(security_level, actual_security_level)
 
-    def test_should_return_frame_counter_value_when_frame_counter_property_is_called(self):
+    def test_should_return_frame_counter_value_when_frame_counter_property_is_called(
+        self):
         # GIVEN
         frame_counter = any_frame_counter()
         key_id_mode = any_key_id_mode()
 
         aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(
-            key_id_mode, any_security_level(), frame_counter, any_key_id(key_id_mode))
+            key_id_mode, any_security_level(), frame_counter,
+            any_key_id(key_id_mode))
 
         # WHEN
         actual_frame_counter = aux_sec_hdr_obj.frame_counter
@@ -397,7 +454,8 @@
         # THEN
         self.assertEqual(key_id, actual_key_id)
 
-    def test_should_return_sequence_counter_value_when_sequence_counter_property_is_called(self):
+    def test_should_return_sequence_counter_value_when_sequence_counter_property_is_called(
+        self):
         # GIVEN
         key_id_mode = 2
         key_id = any_key_id(key_id_mode)
@@ -409,12 +467,14 @@
         actual_sequence_counter = aux_sec_hdr_obj.sequence_counter
 
         # THEN
-        self.assertEqual(struct.unpack(">I", key_id[:4])[0], actual_sequence_counter)
+        self.assertEqual(
+            struct.unpack(">I", key_id[:4])[0], actual_sequence_counter)
 
 
 class TestAuxiliarySecurityHeaderFactory(unittest.TestCase):
 
-    def test_should_create_AuxiliarySecurityHeader_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_AuxiliarySecurityHeader_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         key_id_mode = any_key_id_mode()
         sec_lvl = any_security_level()
@@ -423,13 +483,15 @@
 
         factory = net_crypto.AuxiliarySecurityHeaderFactory()
 
-        data = bytearray([sec_lvl | key_id_mode << 3]) + struct.pack("<I", frame_counter) + key_id
+        data = bytearray([sec_lvl | key_id_mode << 3]) + struct.pack(
+            "<I", frame_counter) + key_id
 
         # WHEN
         aux_sec_hdr = factory.parse(io.BytesIO(data), common.MessageInfo())
 
         # THEN
-        self.assertTrue(isinstance(aux_sec_hdr, net_crypto.AuxiliarySecurityHeader))
+        self.assertTrue(
+            isinstance(aux_sec_hdr, net_crypto.AuxiliarySecurityHeader))
         self.assertEqual(key_id_mode, aux_sec_hdr.key_id_mode)
         self.assertEqual(sec_lvl, aux_sec_hdr.security_level)
         self.assertEqual(frame_counter, aux_sec_hdr.frame_counter)
diff --git a/tests/scripts/thread-cert/test_diag.py b/tests/scripts/thread-cert/test_diag.py
index 06a92fd..a1f89d7 100755
--- a/tests/scripts/thread-cert/test_diag.py
+++ b/tests/scripts/thread-cert/test_diag.py
@@ -27,80 +27,74 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-import unittest
 import time
+import unittest
 
-import node
-import config
+import thread_cert
 
 
-class TestDiag(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-        self.node = node.Node(1, False, simulator=self.simulator)
+class TestDiag(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-    def tearDown(self):
-        self.node.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {1: None}
 
     def test(self):
+        node = self.nodes[1]
+
         cases = [
-            ('diag\n',
-             'diagnostics mode is disabled\r\n'),
-            ('diag send 10 100\n',
-             'failed\r\nstatus 0xd\r\n'),
-            ('diag start\n',
-             'start diagnostics mode\r\nstatus 0x00\r\n'),
+            ('diag\n', 'diagnostics mode is disabled\r\n'),
+            ('diag send 10 100\n', 'Error 13: InvalidState\r\n'),
+            ('diag start\n', 'Done\r\n'),
             ('diag invalid test\n',
              'diag feature \'invalid\' is not supported'),
-            ('diag',
-             'diagnostics mode is enabled\r\n'),
-            ('diag channel 10\n',
-             'failed\r\nstatus 0x7\r\n'),
-            ('diag channel 11\n',
-             'set channel to 11\r\nstatus 0x00\r\n'),
-            ('diag channel\n',
-             'channel: 11\r\n'),
-            ('diag power -10\n',
-             'set tx power to -10 dBm\r\nstatus 0x00\r\n'),
-            ('diag power\n',
-             'tx power: -10 dBm\r\n'),
-            ('diag stats\n',
+            ('diag', 'diagnostics mode is enabled\r\n'),
+            ('diag channel 10\n', 'failed\r\nstatus 0x7\r\n'),
+            ('diag channel 11\n', 'set channel to 11\r\nstatus 0x00\r\n'),
+            ('diag channel\n', 'channel: 11\r\n'),
+            ('diag power -10\n', 'set tx power to -10 dBm\r\nstatus 0x00\r\n'),
+            ('diag power\n', 'tx power: -10 dBm\r\n'),
+            (
+                'diag stats\n',
                 'received packets: 0\r\nsent packets: 0\r\n'
                 'first received packet: rssi=0, lqi=0\r\n'
                 'last received packet: rssi=0, lqi=0\r\n',
-             ),
-            ('diag send 20 100\n',
+            ),
+            (
+                'diag send 20 100\n',
                 r'sending 0x14 packet\(s\), length 0x64\r\nstatus 0x00\r\n',
-             ),
-            ('  diag \t send    \t 20\t100',
+            ),
+            (
+                '  diag \t send    \t 20\t100',
                 r'sending 0x14 packet\(s\), length 0x64\r\nstatus 0x00\r\n',
-             ),
-            ('diag repeat 100 100\n',
+            ),
+            (
+                'diag repeat 100 100\n',
                 'sending packets of length 0x64 at the delay of 0x64 ms\r\nstatus 0x00\r\n',
-             ),
-            ('diag repeat stop\n',
+            ),
+            (
+                'diag repeat stop\n',
                 'repeated packet transmission is stopped\r\nstatus 0x00\r\n',
-             ),
-            ('diag stop\n',
+            ),
+            (
+                'diag stop\n',
                 r'received packets: 0\r\nsent packets: ([1-9]\d*)\r\n'
                 'first received packet: rssi=0, lqi=0\r\n'
                 'last received packet: rssi=0, lqi=0\r\n\n'
                 r'stop diagnostics mode\r\nstatus 0x00\r\n',
-             ),
-            ('diag',
-             'diagnostics mode is disabled\r\n'),
-            ('diag 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32',
+            ),
+            ('diag', 'diagnostics mode is disabled\r\n'),
+            (
+                'diag 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32',
                 r'Error: too many args \(max 32\)\r\n',
-             ),
+            ),
         ]
 
         for case in cases:
-            self.node.send_command(case[0])
+            node.send_command(case[0])
             self.simulator.go(1)
             if type(self.simulator).__name__ == 'VirtualTime':
                 time.sleep(0.1)
-            self.node._expect(case[1])
+            node._expect(case[1])
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/test_ipv6.py b/tests/scripts/thread-cert/test_ipv6.py
index 8011e12..f2db0a3 100755
--- a/tests/scripts/thread-cert/test_ipv6.py
+++ b/tests/scripts/thread-cert/test_ipv6.py
@@ -68,7 +68,6 @@
 
 
 class HopByHopOptionBytesValue:
-
     """ Test helper class """
 
     _value = "value"
@@ -90,7 +89,6 @@
 
 
 class ICMPv6BytesBody:
-
     """ Test helper class """
 
     _icmp_body = "icmp_body"
@@ -111,7 +109,6 @@
 
 
 class ICMPv6BytesBodyFactory:
-
     """ Test helper class """
 
     def parse(self, data, context):
@@ -171,7 +168,8 @@
 
 
 def any_icmp_payload(_type, code, checksum, body):
-    return bytearray([_type, code, (checksum >> 8) & 0xff, checksum & 0xff]) + body
+    return bytearray([_type, code,
+                      (checksum >> 8) & 0xff, checksum & 0xff]) + body
 
 
 def any_udp_payload(src_port, dst_port, payload, checksum):
@@ -188,7 +186,10 @@
 
 def any_body():
     length = any_uint(8)
-    body = "".join([random.choice(string.ascii_letters + string.digits + string.hexdigits) for _ in range(length)])
+    body = "".join([
+        random.choice(string.ascii_letters + string.digits + string.hexdigits)
+        for _ in range(length)
+    ])
     return bytearray(body.encode("utf-8"))
 
 
@@ -199,7 +200,8 @@
 
 
 def any_ip_address():
-    return bytearray([0xfe, 0x80]) + bytearray([0x00] * 6) + bytearray([random.getrandbits(8)] * 8)
+    return bytearray([0xfe, 0x80]) + bytearray([0x00] * 6) + bytearray(
+        [random.getrandbits(8)] * 8)
 
 
 def any_port():
@@ -232,7 +234,10 @@
 
 def any_mpl_seed_id(S):
     length = MPLOption._seed_id_length[S]
-    seed_id = "".join([random.choice(string.ascii_letters + string.digits + string.hexdigits) for _ in range(length)])
+    seed_id = "".join([
+        random.choice(string.ascii_letters + string.digits + string.hexdigits)
+        for _ in range(length)
+    ])
     return bytearray(seed_id.encode("utf-8"))
 
 
@@ -309,12 +314,14 @@
 
 def any_hop_by_hop_bytes_option():
     length = any_length()
-    return HopByHopOption(any_hop_by_hop_bytes_option_header(length), any_hop_by_hop_bytes_value(length))
+    return HopByHopOption(any_hop_by_hop_bytes_option_header(length),
+                          any_hop_by_hop_bytes_value(length))
 
 
 def any_hop_by_hop_mpl_option():
     mpl_option = any_mpl_option()
-    return HopByHopOption(any_hop_by_hop_bytes_option_header(len(mpl_option)), mpl_option)
+    return HopByHopOption(any_hop_by_hop_bytes_option_header(len(mpl_option)),
+                          mpl_option)
 
 
 def any_identifier():
@@ -343,7 +350,8 @@
 
 class TestIPv6Header(unittest.TestCase):
 
-    def test_should_convert_IPv6_header_to_bytes_when_to_bytes_method_is_called(self):
+    def test_should_convert_IPv6_header_to_bytes_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         traffic_class = any_traffic_class()
         flow_label = any_flow_label()
@@ -353,7 +361,8 @@
         source_address = any_ip_address()
         destination_address = any_ip_address()
 
-        ipv6_header = IPv6Header(source_address, destination_address, traffic_class, flow_label, hop_limit,
+        ipv6_header = IPv6Header(source_address, destination_address,
+                                 traffic_class, flow_label, hop_limit,
                                  payload_length, next_header)
 
         # WHEN
@@ -362,16 +371,16 @@
         # THEN
         self.assertEqual(6, data[0] >> 4)
         self.assertEqual(traffic_class, ((data[0] << 8 | data[1]) >> 4) & 0xff)
-        self.assertEqual(
-            flow_label, ((data[1] & 0x0F) << 16) | (data[2] << 8) | data[3]
-        )
+        self.assertEqual(flow_label,
+                         ((data[1] & 0x0F) << 16) | (data[2] << 8) | data[3])
         self.assertEqual(payload_length, struct.unpack("!H", data[4:6])[0])
         self.assertEqual(next_header, data[6])
         self.assertEqual(hop_limit, data[7])
         self.assertEqual(source_address, data[8:24])
         self.assertEqual(destination_address, data[24:40])
 
-    def test_should_create_IPv6Header_when_from_bytes_classmethod_is_called(self):
+    def test_should_create_IPv6Header_when_from_bytes_classmethod_is_called(
+        self):
         # GIVEN
         traffic_class = any_traffic_class()
         flow_label = any_flow_label()
@@ -386,7 +395,8 @@
                           (flow_label >> 8) & 0xff, flow_label & 0xff,
                           payload_length >> 8, payload_length & 0xff,
                           next_header, hop_limit])
-        data += ip_address(bytes(source_address)).packed + ip_address(bytes(destination_address)).packed
+        data += ip_address(bytes(source_address)).packed + ip_address(
+            bytes(destination_address)).packed
 
         # WHEN
         ipv6_header = IPv6Header.from_bytes(io.BytesIO(data))
@@ -399,12 +409,16 @@
         self.assertEqual(next_header, ipv6_header.next_header)
         self.assertEqual(hop_limit, ipv6_header.hop_limit)
         self.assertEqual(source_address, ipv6_header.source_address.packed)
-        self.assertEqual(destination_address, ipv6_header.destination_address.packed)
+        self.assertEqual(destination_address,
+                         ipv6_header.destination_address.packed)
 
-    def test_should_return_proper_header_length_when_IPv6Packet_object_is_called_in_len(self):
+    def test_should_return_proper_header_length_when_IPv6Packet_object_is_called_in_len(
+        self):
         # GIVEN
-        ipv6_header = IPv6Header(any_traffic_class(), any_flow_label(), any_payload_length(),
-                                 any_next_header(), any_hop_limit(), any_ip_address(), any_ip_address())
+        ipv6_header = IPv6Header(any_traffic_class(), any_flow_label(),
+                                 any_payload_length(), any_next_header(),
+                                 any_hop_limit(), any_ip_address(),
+                                 any_ip_address())
 
         # WHEN
         ipv6_header_length = len(ipv6_header)
@@ -415,7 +429,8 @@
 
 class TestUDPHeader(unittest.TestCase):
 
-    def test_should_convert_UDP_header_to_bytes_when_to_bytes_method_is_called(self):
+    def test_should_convert_UDP_header_to_bytes_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         src_port = any_port()
         dst_port = any_port()
@@ -433,7 +448,8 @@
         self.assertEqual(payload_length, struct.unpack("!H", data[4:6])[0])
         self.assertEqual(checksum, struct.unpack("!H", data[6:])[0])
 
-    def test_should_create_UDPHeader_when_from_bytes_classmethod_is_called(self):
+    def test_should_create_UDPHeader_when_from_bytes_classmethod_is_called(
+        self):
         # GIVEN
         src_port = any_port()
         dst_port = any_port()
@@ -452,9 +468,11 @@
         self.assertEqual(payload_length, udp_header.payload_length)
         self.assertEqual(checksum, udp_header.checksum)
 
-    def test_should_return_proper_header_length_when_UDPHeader_object_is_called_in_len(self):
+    def test_should_return_proper_header_length_when_UDPHeader_object_is_called_in_len(
+        self):
         # GIVEN
-        udp_header = UDPHeader(any_port(), any_port(), any_payload_length(), any_checksum())
+        udp_header = UDPHeader(any_port(), any_port(), any_payload_length(),
+                               any_checksum())
 
         # WHEN
         udp_header_length = len(udp_header)
@@ -464,7 +482,8 @@
 
     def test_should_return_17_when_type_property_is_called(self):
         # GIVEN
-        udp_header = UDPHeader(any_port(), any_port(), any_payload_length(), any_checksum())
+        udp_header = UDPHeader(any_port(), any_port(), any_payload_length(),
+                               any_checksum())
 
         # THEN
         self.assertEqual(17, udp_header.type)
@@ -472,7 +491,8 @@
 
 class TestICMPv6Header(unittest.TestCase):
 
-    def test_should_convert_icmp_message_header_to_bytes_when_to_bytes_method_is_called(self):
+    def test_should_convert_icmp_message_header_to_bytes_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         _type = any_type()
         code = any_code()
@@ -488,7 +508,8 @@
         self.assertEqual(code, data[1])
         self.assertEqual(checksum, struct.unpack("!H", data[2:])[0])
 
-    def test_should_create_ICMPv6Header_when_to_bytes_classmethod_is_called(self):
+    def test_should_create_ICMPv6Header_when_to_bytes_classmethod_is_called(
+        self):
         # GIVEN
         _type = any_type()
         code = any_code()
@@ -504,7 +525,8 @@
         self.assertEqual(code, icmpv6_header.code)
         self.assertEqual(checksum, icmpv6_header.checksum)
 
-    def test_should_return_proper_header_length_when_ICMPv6Header_object_is_called_in_len(self):
+    def test_should_return_proper_header_length_when_ICMPv6Header_object_is_called_in_len(
+        self):
         # GIVEN
         icmpv6_header = ICMPv6Header(any_type(), any_code(), any_checksum())
 
@@ -517,62 +539,50 @@
 
 class TestIPv6Packet(unittest.TestCase):
 
-    def test_should_build_IPv6Packet_with_ICMP_payload_from_well_know_values_when_to_bytes_method_is_called(self):
+    def test_should_build_IPv6Packet_with_ICMP_payload_from_well_know_values_when_to_bytes_method_is_called(
+        self):
         # GIVEN
 
         ipv6_packet = IPv6Packet(
-            IPv6Header(
-                source_address="fd00:1234:4555::ff:fe00:1800",
-                destination_address="ff03::1"
-            ),
+            IPv6Header(source_address="fd00:1234:4555::ff:fe00:1800",
+                       destination_address="ff03::1"),
             ICMPv6(
                 ICMPv6Header(128, 0),
                 ICMPv6EchoBody(
-                    0,
-                    2,
-                    bytearray(
-                        [
-                            0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01,
-                            0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
-                            0x41, 0x41
-                        ]
-                    )
-                )
-            ),
-            [
-                HopByHop(
-                    options=[
-                        HopByHopOption(
-                            HopByHopOptionHeader(_type=0x6d),
-                            MPLOption(S=1, M=0, V=0, sequence=2, seed_id=bytearray([0x00, 0x18]))
-                        )
-                    ]
-                )
-            ]
-        )
+                    0, 2,
+                    bytearray([
+                        0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41,
+                        0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
+                    ]))), [
+                        HopByHop(options=[
+                            HopByHopOption(
+                                HopByHopOptionHeader(_type=0x6d),
+                                MPLOption(S=1,
+                                          M=0,
+                                          V=0,
+                                          sequence=2,
+                                          seed_id=bytearray([0x00, 0x18])))
+                        ])
+                    ])
 
         # WHEN
         ipv6_packet_bytes = ipv6_packet.to_bytes()
 
         # THEN
-        expected_ipv6_packet_bytes = bytearray(
-            [
-                0x60, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40,
-                0xfd, 0x00, 0x12, 0x34, 0x45, 0x55, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x18, 0x00,
-                0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-                0x3a, 0x00, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18,
-                0x80, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0x02,
-                0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01,
-                0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
-                0x41, 0x41
-            ]
-        )
+        expected_ipv6_packet_bytes = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40, 0xfd, 0x00, 0x12,
+            0x34, 0x45, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00,
+            0x18, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x6d, 0x04,
+            0x40, 0x02, 0x00, 0x18, 0x80, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00,
+            0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x41,
+            0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
+        ])
 
         self.assertEqual(expected_ipv6_packet_bytes, ipv6_packet_bytes)
 
-    def test_should_build_IPv6Packet_with_UDP_payload_from_well_know_values_when_to_bytes_method_is_called(self):
+    def test_should_build_IPv6Packet_with_UDP_payload_from_well_know_values_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         ipv6_header = IPv6Header(source_address="fe80::1",
                                  destination_address="ff02::2",
@@ -581,16 +591,12 @@
         udp_dgram = UDPDatagram(
             UDPHeader(src_port=19788, dst_port=19788),
             BytesPayload(
-                bytearray(
-                    [
-                        0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                        0x00, 0x00, 0x01, 0x09, 0x01, 0x01, 0x0b, 0x03,
-                        0x04, 0xc6, 0x69, 0x73, 0x51, 0x0e, 0x01, 0x80,
-                        0x12, 0x02, 0x00, 0x01, 0xde, 0xad, 0xbe, 0xef
-                    ]
-                )
-            )
-        )
+                bytearray([
+                    0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                    0x01, 0x09, 0x01, 0x01, 0x0b, 0x03, 0x04, 0xc6, 0x69, 0x73,
+                    0x51, 0x0e, 0x01, 0x80, 0x12, 0x02, 0x00, 0x01, 0xde, 0xad,
+                    0xbe, 0xef
+                ])))
 
         ipv6_packet = IPv6Packet(ipv6_header, udp_dgram)
 
@@ -598,57 +604,55 @@
         ipv6_packet_bytes = ipv6_packet.to_bytes()
 
         # THEN
-        expected_ipv6_packet_bytes = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x11, 0xff,
-                                                0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-                                                0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-                                                0x4d, 0x4c, 0x4d, 0x4c, 0x00, 0x28, 0xe9, 0xf4,
-                                                0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                                0x00, 0x00, 0x01, 0x09, 0x01, 0x01, 0x0b, 0x03,
-                                                0x04, 0xc6, 0x69, 0x73, 0x51, 0x0e, 0x01, 0x80,
-                                                0x12, 0x02, 0x00, 0x01, 0xde, 0xad, 0xbe, 0xef])
+        expected_ipv6_packet_bytes = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x11, 0xff, 0xfe, 0x80, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x01, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x4d, 0x4c, 0x4d, 0x4c,
+            0x00, 0x28, 0xe9, 0xf4, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x01, 0x09, 0x01, 0x01, 0x0b, 0x03, 0x04, 0xc6,
+            0x69, 0x73, 0x51, 0x0e, 0x01, 0x80, 0x12, 0x02, 0x00, 0x01, 0xde,
+            0xad, 0xbe, 0xef
+        ])
 
         self.assertEqual(expected_ipv6_packet_bytes, ipv6_packet_bytes)
 
 
 class TestIPv6PacketFactory(unittest.TestCase):
 
-    def test_should_create_IPv6Packet_with_MPL_and_ICMP_when_to_bytes_method_is_called(self):
+    def test_should_create_IPv6Packet_with_MPL_and_ICMP_when_to_bytes_method_is_called(
+        self):
         # GIVEN
-        ipv6_packet_bytes = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40,
-                                       0xfd, 0x00, 0x12, 0x34, 0x45, 0x55, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x18, 0x00,
-                                       0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-                                       0x3a, 0x00, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18,
-                                       0x80, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0x02,
-                                       0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01,
-                                       0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
-                                       0x41, 0x41])
+        ipv6_packet_bytes = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40, 0xfd, 0x00, 0x12,
+            0x34, 0x45, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00,
+            0x18, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x6d, 0x04,
+            0x40, 0x02, 0x00, 0x18, 0x80, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00,
+            0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x41,
+            0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
+        ])
 
         ipv6_factory = IPv6PacketFactory(
             ehf={
-                0: HopByHopFactory(
-                    hop_by_hop_options_factory=HopByHopOptionsFactory(
-                        options_factories={
-                            109: MPLOptionFactory()
-                        }
-                    )
-                )
+                0:
+                    HopByHopFactory(
+                        hop_by_hop_options_factory=HopByHopOptionsFactory(
+                            options_factories={109: MPLOptionFactory()}))
             },
             ulpf={
-                58: ICMPv6Factory(body_factories={
-                    128: ICMPv6EchoBodyFactory()
-                })
+                58: ICMPv6Factory(body_factories={128: ICMPv6EchoBodyFactory()})
             })
 
         # WHEN
-        ipv6_packet = ipv6_factory.parse(io.BytesIO(ipv6_packet_bytes), any_message_info())
+        ipv6_packet = ipv6_factory.parse(io.BytesIO(ipv6_packet_bytes),
+                                         any_message_info())
 
         # THEN
-        self.assertEqual('fd00:1234:4555::ff:fe00:1800', ipv6_packet.ipv6_header.source_address.compressed)
-        self.assertEqual('ff03::1', ipv6_packet.ipv6_header.destination_address.compressed)
+        self.assertEqual('fd00:1234:4555::ff:fe00:1800',
+                         ipv6_packet.ipv6_header.source_address.compressed)
+        self.assertEqual('ff03::1',
+                         ipv6_packet.ipv6_header.destination_address.compressed)
         self.assertEqual(64, ipv6_packet.ipv6_header.hop_limit)
         self.assertEqual(0, ipv6_packet.ipv6_header.next_header)
         self.assertEqual(34, ipv6_packet.ipv6_header.payload_length)
@@ -659,42 +663,48 @@
         self.assertEqual(1, ipv6_packet.extension_headers[0].options[0].value.S)
         self.assertEqual(0, ipv6_packet.extension_headers[0].options[0].value.M)
         self.assertEqual(0, ipv6_packet.extension_headers[0].options[0].value.V)
-        self.assertEqual(2, ipv6_packet.extension_headers[0].options[0].value.sequence)
-        self.assertEqual(bytearray([0x00, 0x18]), ipv6_packet.extension_headers[0].options[0].value.seed_id)
+        self.assertEqual(
+            2, ipv6_packet.extension_headers[0].options[0].value.sequence)
+        self.assertEqual(
+            bytearray([0x00, 0x18]),
+            ipv6_packet.extension_headers[0].options[0].value.seed_id)
 
-        self.assertEqual(34578, ipv6_packet.upper_layer_protocol.header.checksum)
+        self.assertEqual(34578,
+                         ipv6_packet.upper_layer_protocol.header.checksum)
         self.assertEqual(128, ipv6_packet.upper_layer_protocol.header.type)
         self.assertEqual(0, ipv6_packet.upper_layer_protocol.header.code)
         self.assertEqual(0, ipv6_packet.upper_layer_protocol.body.identifier)
-        self.assertEqual(2, ipv6_packet.upper_layer_protocol.body.sequence_number)
-        self.assertEqual(b'\x80\x00\xc7\xbf\x00\x00\x00\x01AAAAAAAAAA', ipv6_packet.upper_layer_protocol.body.data)
+        self.assertEqual(2,
+                         ipv6_packet.upper_layer_protocol.body.sequence_number)
+        self.assertEqual(b'\x80\x00\xc7\xbf\x00\x00\x00\x01AAAAAAAAAA',
+                         ipv6_packet.upper_layer_protocol.body.data)
 
-    def test_should_create_IPv6Packet_without_any_extension_header_with_ICMP_when_to_bytes_method_is_called(self):
+    def test_should_create_IPv6Packet_without_any_extension_header_with_ICMP_when_to_bytes_method_is_called(
+        self):
         # GIVEN
-        ipv6_packet_bytes = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x3A, 0x40,
-                                       0xfd, 0x00, 0x12, 0x34, 0x45, 0x55, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x18, 0x00,
-                                       0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-                                       0x80, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0x02,
-                                       0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01,
-                                       0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
-                                       0x41, 0x41])
+        ipv6_packet_bytes = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x3A, 0x40, 0xfd, 0x00, 0x12,
+            0x34, 0x45, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00,
+            0x18, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x87, 0x12,
+            0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00,
+            0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
+        ])
 
-        ipv6_factory = IPv6PacketFactory(
-            ulpf={
-                58: ICMPv6Factory(body_factories={
-                    128: ICMPv6EchoBodyFactory()
-                })
-            })
+        ipv6_factory = IPv6PacketFactory(ulpf={
+            58: ICMPv6Factory(body_factories={128: ICMPv6EchoBodyFactory()})
+        })
 
         # WHEN
-        ipv6_packet = ipv6_factory.parse(io.BytesIO(ipv6_packet_bytes), any_message_info())
+        ipv6_packet = ipv6_factory.parse(io.BytesIO(ipv6_packet_bytes),
+                                         any_message_info())
         ipv6_packet._validate_checksum()
 
         # THEN
-        self.assertEqual('fd00:1234:4555::ff:fe00:1800', ipv6_packet.ipv6_header.source_address.compressed)
-        self.assertEqual('ff03::1', ipv6_packet.ipv6_header.destination_address.compressed)
+        self.assertEqual('fd00:1234:4555::ff:fe00:1800',
+                         ipv6_packet.ipv6_header.source_address.compressed)
+        self.assertEqual('ff03::1',
+                         ipv6_packet.ipv6_header.destination_address.compressed)
         self.assertEqual(64, ipv6_packet.ipv6_header.hop_limit)
         self.assertEqual(58, ipv6_packet.ipv6_header.next_header)
         self.assertEqual(26, ipv6_packet.ipv6_header.payload_length)
@@ -702,54 +712,57 @@
         self.assertEqual(0, ipv6_packet.ipv6_header.traffic_class)
         self.assertEqual(6, ipv6_packet.ipv6_header.version)
 
-        self.assertEqual(34578, ipv6_packet.upper_layer_protocol.header.checksum)
+        self.assertEqual(34578,
+                         ipv6_packet.upper_layer_protocol.header.checksum)
         self.assertEqual(128, ipv6_packet.upper_layer_protocol.header.type)
         self.assertEqual(0, ipv6_packet.upper_layer_protocol.header.code)
         self.assertEqual(0, ipv6_packet.upper_layer_protocol.body.identifier)
-        self.assertEqual(2, ipv6_packet.upper_layer_protocol.body.sequence_number)
-        self.assertEqual(b'\x80\x00\xc7\xbf\x00\x00\x00\x01AAAAAAAAAA', ipv6_packet.upper_layer_protocol.body.data)
+        self.assertEqual(2,
+                         ipv6_packet.upper_layer_protocol.body.sequence_number)
+        self.assertEqual(b'\x80\x00\xc7\xbf\x00\x00\x00\x01AAAAAAAAAA',
+                         ipv6_packet.upper_layer_protocol.body.data)
 
     def test_should_set_message_info_field_when_to_bytes_method_is_called(self):
         # GIVEN
-        ipv6_packet_data = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x3A, 0x40,
-                                      0xfd, 0x00, 0x12, 0x34, 0x45, 0x55, 0x00, 0x00,
-                                      0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x18, 0x00,
-                                      0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-                                      0x80, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0x02,
-                                      0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01,
-                                      0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
-                                      0x41, 0x41])
+        ipv6_packet_data = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x3A, 0x40, 0xfd, 0x00, 0x12,
+            0x34, 0x45, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00,
+            0x18, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x87, 0x12,
+            0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00,
+            0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
+        ])
 
         message_info = any_message_info()
         message_info.source_ipv6 = "ff::"
         message_info.destination_address = "ff::"
 
-        factory = IPv6PacketFactory(
-            ulpf={
-                58: ICMPv6Factory(body_factories={
-                    128: ICMPv6EchoBodyFactory()
-                })
-            })
+        factory = IPv6PacketFactory(ulpf={
+            58: ICMPv6Factory(body_factories={128: ICMPv6EchoBodyFactory()})
+        })
 
         # WHEN
         factory.parse(io.BytesIO(ipv6_packet_data), message_info)
 
         # THEN
-        self.assertEqual("fd00:1234:4555::ff:fe00:1800", message_info.source_ipv6.compressed)
+        self.assertEqual("fd00:1234:4555::ff:fe00:1800",
+                         message_info.source_ipv6.compressed)
         self.assertEqual("ff03::1", message_info.destination_ipv6.compressed)
 
 
 class TestUDPDatagram(unittest.TestCase):
 
-    def test_should_creates_bytes_from_UDPHeader_and_payload_when_to_bytes_method_is_called(self):
+    def test_should_creates_bytes_from_UDPHeader_and_payload_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         src_port = any_port()
         dst_port = any_port()
         checksum = any_checksum()
 
         payload = any_payload()
-        payload_length = len(payload) + 8  # UDP length consists of UDP header length and payload length
+        payload_length = len(
+            payload
+        ) + 8  # UDP length consists of UDP header length and payload length
 
         udp_header = UDPHeader(src_port, dst_port, payload_length, checksum)
         udp_payload = BytesPayload(payload)
@@ -767,14 +780,16 @@
 
 class TestIPv6FragmentHeader(unittest.TestCase):
 
-    def test_shold_convert_IPv6_fragment_header_to_bytes_when_to_bytes_method_is_called(self):
+    def test_shold_convert_IPv6_fragment_header_to_bytes_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         type = any_type()
         offset = any_fragment_offset()
         more_flag = any_bool()
         identification = any_fragment_identification()
 
-        ipv6_fragment_header = FragmentHeader(type, offset, more_flag, identification)
+        ipv6_fragment_header = FragmentHeader(type, offset, more_flag,
+                                              identification)
 
         # WHEN
         actual = ipv6_fragment_header.to_bytes()
@@ -785,7 +800,8 @@
 
         self.assertEqual(expected, actual)
 
-    def test_should_create_FragmentHeader_when_from_bytes_classmethod_is_called(self):
+    def test_should_create_FragmentHeader_when_from_bytes_classmethod_is_called(
+        self):
         # GIVEN
         type = any_type()
         offset = any_fragment_offset()
@@ -807,7 +823,8 @@
 
 class TestICMPv6(unittest.TestCase):
 
-    def test_should_creates_bytes_from_ICMPv6Header_and_body_when_to_bytes_method_is_called(self):
+    def test_should_creates_bytes_from_ICMPv6Header_and_body_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         _type = any_type()
         code = any_code()
@@ -854,11 +871,13 @@
             return bytearray([0x00])
         elif padding_length > 1:
             padding_length -= 2
-            return bytearray([0x01, padding_length]) + bytearray([0x00 for _ in range(padding_length)])
+            return bytearray([0x01, padding_length]) + bytearray(
+                [0x00 for _ in range(padding_length)])
         else:
             return bytearray()
 
-    def test_should_create_bytes_from_HopByHop_when_to_bytes_method_is_called(self):
+    def test_should_create_bytes_from_HopByHop_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         next_header = any_next_header()
         hop_by_hop_option = any_hop_by_hop_bytes_option()
@@ -870,7 +889,8 @@
         data = hop_by_hop.to_bytes()
 
         # THEN
-        expected_data = bytearray([next_header, hdr_ext_len]) + hop_by_hop_option.to_bytes()
+        expected_data = bytearray([next_header, hdr_ext_len
+                                  ]) + hop_by_hop_option.to_bytes()
         padding_length = self._calculate_required_padding(len(expected_data))
         expected_data += self.create_padding(padding_length)
 
@@ -879,7 +899,8 @@
 
 class TestMPLOption(unittest.TestCase):
 
-    def test_should_convert_MPLOption_to_bytes_when_to_bytes_method_is_called(self):
+    def test_should_convert_MPLOption_to_bytes_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         S = any_mpl_S()
         M = any_mpl_M()
@@ -893,10 +914,12 @@
         data = mpl_option.to_bytes()
 
         # THEN
-        expected_data = bytearray([(S << 6) | (M << 5) | (V << 4), sequence]) + seed_id
+        expected_data = bytearray([(S << 6) | (M << 5) |
+                                   (V << 4), sequence]) + seed_id
         self.assertEqual(expected_data, data)
 
-    def test_should_create_MPLOption_when_to_bytes_method_is_called_with_data(self):
+    def test_should_create_MPLOption_when_to_bytes_method_is_called_with_data(
+        self):
         # GIVEN
         S = any_mpl_S()
         M = any_mpl_M()
@@ -922,7 +945,8 @@
         self.assertEqual(8, MPLOption._seed_id_length[2])
         self.assertEqual(16, MPLOption._seed_id_length[3])
 
-    def test_should_return_proper_length_when_len_is_called_with_mpl_option_object(self):
+    def test_should_return_proper_length_when_len_is_called_with_mpl_option_object(
+        self):
         # GIVEN
         S = any_mpl_S()
         M = any_mpl_M()
@@ -937,12 +961,14 @@
 
         # THEN
         SMV_and_sequence_length = 2
-        self.assertEqual(SMV_and_sequence_length + len(seed_id), mpl_option_length)
+        self.assertEqual(SMV_and_sequence_length + len(seed_id),
+                         mpl_option_length)
 
 
 class TestclassHopByHopOption(unittest.TestCase):
 
-    def test_should_convert_HopByHopOption_to_bytes_when_to_bytes_method_is_called(self):
+    def test_should_convert_HopByHopOption_to_bytes_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         length = any_length()
         header = any_hop_by_hop_bytes_option_header(length)
@@ -957,7 +983,8 @@
         expected_data = header.to_bytes() + value.to_bytes()
         self.assertEqual(expected_data, data)
 
-    def test_should_return_length_of_HopByHopOption_when_len_is_called_with_hop_by_hop_option_object(self):
+    def test_should_return_length_of_HopByHopOption_when_len_is_called_with_hop_by_hop_option_object(
+        self):
         # GIVEN
         length = any_length()
         header = any_hop_by_hop_bytes_option_header(length)
@@ -971,12 +998,14 @@
         # THEN
         header_length = 2
         expected_hop_by_hop_option_length = header_length + length
-        self.assertEqual(expected_hop_by_hop_option_length, hop_by_hop_option_length)
+        self.assertEqual(expected_hop_by_hop_option_length,
+                         hop_by_hop_option_length)
 
 
 class TestHopByHopOptionHeader(unittest.TestCase):
 
-    def test_should_convert_HopByHopOptionHeader_to_bytes_when_to_bytes_method_is_called(self):
+    def test_should_convert_HopByHopOptionHeader_to_bytes_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         _type = any_type()
         length = any_length()
@@ -990,7 +1019,8 @@
         expected_data = bytearray([_type, length])
         self.assertEqual(expected_data, data)
 
-    def test_should_create_HopByHopOptionHeader_when_to_bytes_method_is_called_with_data(self):
+    def test_should_create_HopByHopOptionHeader_when_to_bytes_method_is_called_with_data(
+        self):
         # GIVEN
         _type = any_type()
         length = any_length()
@@ -1004,7 +1034,8 @@
         self.assertEqual(_type, option_header.type)
         self.assertEqual(length, option_header.length)
 
-    def test_should_return_proper_length_when_len_is_called_with_HopByHopOptionHeader_object(self):
+    def test_should_return_proper_length_when_len_is_called_with_HopByHopOptionHeader_object(
+        self):
         # GIVEN
         _type = any_type()
         length = any_length()
@@ -1039,11 +1070,13 @@
                 return bytearray([0x00])
             elif padding_length > 1:
                 padding_length -= 2
-                return bytearray([0x01, padding_length]) + bytearray([0x00 for _ in range(padding_length)])
+                return bytearray([0x01, padding_length]) + bytearray(
+                    [0x00 for _ in range(padding_length)])
 
         return bytearray()
 
-    def test_should_create_HopByHop_object_instance_when_to_bytes_method_is_called_with_data(self):
+    def test_should_create_HopByHop_object_instance_when_to_bytes_method_is_called_with_data(
+        self):
         # GIVEN
         hop_by_hop_option = any_hop_by_hop_mpl_option()
         hop_by_hop_option_type = hop_by_hop_option.header.type
@@ -1053,44 +1086,51 @@
 
         hop_by_hop_factory = HopByHopFactory(
             hop_by_hop_options_factory=HopByHopOptionsFactory(
-                options_factories={
-                    hop_by_hop_option_type: MPLOptionFactory()
-                }
-            )
-        )
+                options_factories={hop_by_hop_option_type: MPLOptionFactory()}))
 
-        data = bytearray([next_header, hdr_ext_len]) + hop_by_hop_option.to_bytes()
+        data = bytearray([next_header, hdr_ext_len
+                         ]) + hop_by_hop_option.to_bytes()
         data += self.padding(len(data))
 
         # WHEN
-        hop_by_hop = hop_by_hop_factory.parse(io.BytesIO(data), any_message_info())
+        hop_by_hop = hop_by_hop_factory.parse(io.BytesIO(data),
+                                              any_message_info())
 
         # THEN
-        self.assertEqual(hop_by_hop_option.value.S, hop_by_hop.options[0].value.S)
-        self.assertEqual(hop_by_hop_option.value.V, hop_by_hop.options[0].value.V)
-        self.assertEqual(hop_by_hop_option.value.M, hop_by_hop.options[0].value.M)
-        self.assertEqual(hop_by_hop_option.value.sequence, hop_by_hop.options[0].value.sequence)
-        self.assertEqual(hop_by_hop_option.value.seed_id, hop_by_hop.options[0].value.seed_id)
+        self.assertEqual(hop_by_hop_option.value.S,
+                         hop_by_hop.options[0].value.S)
+        self.assertEqual(hop_by_hop_option.value.V,
+                         hop_by_hop.options[0].value.V)
+        self.assertEqual(hop_by_hop_option.value.M,
+                         hop_by_hop.options[0].value.M)
+        self.assertEqual(hop_by_hop_option.value.sequence,
+                         hop_by_hop.options[0].value.sequence)
+        self.assertEqual(hop_by_hop_option.value.seed_id,
+                         hop_by_hop.options[0].value.seed_id)
 
-    def test_should_raise_RuntimeError_when_no_option_factory_is_set_and_parse_method_is_called(self):
+    def test_should_raise_RuntimeError_when_no_option_factory_is_set_and_parse_method_is_called(
+        self):
         # GIVEN
         hop_by_hop_option = any_hop_by_hop_mpl_option()
 
         next_header = any_next_header()
         hdr_ext_len = self._calculate_hdr_ext_len(2 + len(hop_by_hop_option))
 
-        hop_by_hop_factory = HopByHopFactory(hop_by_hop_options_factory=HopByHopOptionsFactory())
+        hop_by_hop_factory = HopByHopFactory(
+            hop_by_hop_options_factory=HopByHopOptionsFactory())
 
         data = bytes([next_header, hdr_ext_len]) + hop_by_hop_option.to_bytes()
         data += self.padding(len(data))
 
         # THEN
-        self.assertRaises(RuntimeError, hop_by_hop_factory.parse, io.BytesIO(data), any_message_info())
+        self.assertRaises(RuntimeError, hop_by_hop_factory.parse,
+                          io.BytesIO(data), any_message_info())
 
 
 class TestMPLOptionFactory(unittest.TestCase):
 
-    def test_should_produce_MPLOption_from_bytes_when_to_bytes_method_is_called_with_data(self):
+    def test_should_produce_MPLOption_from_bytes_when_to_bytes_method_is_called_with_data(
+        self):
         # GIVEN
         S = any_mpl_S()
         M = any_mpl_M()
@@ -1116,7 +1156,8 @@
 
 class TestUdpBasedOnSrcDstPortsPayloadFactory(unittest.TestCase):
 
-    def test_should_create_payload_from_data_when_src_port_factory_is_defined_and_parse_method_is_called(self):
+    def test_should_create_payload_from_data_when_src_port_factory_is_defined_and_parse_method_is_called(
+        self):
         # GIVEN
         data = any_data()
 
@@ -1135,7 +1176,8 @@
         # THEN
         self.assertEqual(data, actual_data.data)
 
-    def test_should_create_payload_from_data_when_dst_port_factory_is_defined_and_parse_method_is_called(self):
+    def test_should_create_payload_from_data_when_dst_port_factory_is_defined_and_parse_method_is_called(
+        self):
         # GIVEN
         data = any_data()
 
@@ -1154,7 +1196,8 @@
         # THEN
         self.assertEqual(data, actual_data.data)
 
-    def test_should_raise_RuntimeError_when_parse_method_is_called_but_required_factory_is_not_defined(self):
+    def test_should_raise_RuntimeError_when_parse_method_is_called_but_required_factory_is_not_defined(
+        self):
         # GIVEN
         data = any_data()
 
@@ -1162,15 +1205,18 @@
         message_info.src_port = any_port()
         message_info.dst_port = any_port()
 
-        factory = UdpBasedOnSrcDstPortsPayloadFactory(src_dst_port_based_payload_factories={})
+        factory = UdpBasedOnSrcDstPortsPayloadFactory(
+            src_dst_port_based_payload_factories={})
 
         # THEN
-        self.assertRaises(RuntimeError, factory.parse, io.BytesIO(data), message_info)
+        self.assertRaises(RuntimeError, factory.parse, io.BytesIO(data),
+                          message_info)
 
 
 class TestUDPDatagramFactory(unittest.TestCase):
 
-    def test_should_produce_UDPDatagram_from_bytes_when_to_bytes_method_is_called_with_data(self):
+    def test_should_produce_UDPDatagram_from_bytes_when_to_bytes_method_is_called_with_data(
+        self):
         # GIVEN
         src_port = any_port()
         dst_port = any_port()
@@ -1179,10 +1225,10 @@
         payload = any_payload()
         payload_length = len(payload) + len(UDPHeader(0, 0))
 
-        data = bytearray([(src_port >> 8), (src_port & 0xff),
-                          (dst_port >> 8), (dst_port & 0xff),
-                          (payload_length >> 8), (payload_length & 0xff),
-                          (checksum >> 8), (checksum & 0xff)]) + payload
+        data = bytearray([(src_port >> 8), (src_port & 0xff), (dst_port >> 8),
+                          (dst_port & 0xff), (payload_length >> 8),
+                          (payload_length & 0xff), (checksum >> 8),
+                          (checksum & 0xff)]) + payload
 
         factory = UDPDatagramFactory(UDPHeaderFactory(), BytesPayloadFactory())
 
@@ -1196,7 +1242,8 @@
         self.assertEqual(udp_dgram.header.checksum, checksum)
         self.assertEqual(udp_dgram.payload.data, payload)
 
-    def test_should_set_src_and_dst_port_in_message_info_when_parse_method_is_called(self):
+    def test_should_set_src_and_dst_port_in_message_info_when_parse_method_is_called(
+        self):
         # GIVEN
         message_info = any_message_info()
 
@@ -1207,21 +1254,16 @@
         payload = any_payload()
         payload_length = len(payload) + len(UDPHeader(0, 0))
 
-        data = (
-            bytearray(
-                [
-                    (src_port >> 8),
-                    (src_port & 0xff),
-                    (dst_port >> 8),
-                    (dst_port & 0xff),
-                    (payload_length >> 8),
-                    (payload_length & 0xff),
-                    (checksum >> 8),
-                    (checksum & 0xff),
-                ]
-            )
-            + payload
-        )
+        data = (bytearray([
+            (src_port >> 8),
+            (src_port & 0xff),
+            (dst_port >> 8),
+            (dst_port & 0xff),
+            (payload_length >> 8),
+            (payload_length & 0xff),
+            (checksum >> 8),
+            (checksum & 0xff),
+        ]) + payload)
 
         factory = UDPDatagramFactory(UDPHeaderFactory(), BytesPayloadFactory())
 
@@ -1235,16 +1277,19 @@
 
 class TestICMPv6Factory(unittest.TestCase):
 
-    def test_should_produce_ICMPv6_from_bytes_when_to_bytes_method_is_called_with_data(self):
+    def test_should_produce_ICMPv6_from_bytes_when_to_bytes_method_is_called_with_data(
+        self):
         # GIVEN
         _type = any_type()
         code = any_code()
         checksum = any_checksum()
         body = any_body()
 
-        data = bytearray([_type, code, (checksum >> 8), (checksum & 0xff)]) + body
+        data = bytearray([_type, code, (checksum >> 8),
+                          (checksum & 0xff)]) + body
 
-        factory = ICMPv6Factory(body_factories={_type: ICMPv6BytesBodyFactory()})
+        factory = ICMPv6Factory(
+            body_factories={_type: ICMPv6BytesBodyFactory()})
 
         # WHEN
         icmpv6_msg = factory.parse(io.BytesIO(data), any_message_info())
@@ -1255,7 +1300,8 @@
         self.assertEqual(icmpv6_msg.header.checksum, checksum)
         self.assertEqual(icmpv6_msg.body.bytes, body)
 
-    def test_should_raise_RuntimeError_when_method_parse_is_called_but_body_factory_is_not_present(self):
+    def test_should_raise_RuntimeError_when_method_parse_is_called_but_body_factory_is_not_present(
+        self):
         # GIVEN
         _type = any_type()
         code = any_code()
@@ -1267,12 +1313,14 @@
         factory = ICMPv6Factory()
 
         # WHEN
-        self.assertRaises(RuntimeError, factory.parse, io.BytesIO(data), any_message_info())
+        self.assertRaises(RuntimeError, factory.parse, io.BytesIO(data),
+                          any_message_info())
 
 
 class TestBytesPayload(unittest.TestCase):
 
-    def test_should_create_BytesPayload_when_from_bytes_class_method_is_called(self):
+    def test_should_create_BytesPayload_when_from_bytes_class_method_is_called(
+        self):
         # GIVEN
         data = any_data()
 
@@ -1282,7 +1330,8 @@
         # THEN
         self.assertEqual(data, actual.data)
 
-    def test_should_return_exactly_the_same_data_as_passed_to_constructor_when_to_bytes_method_is_called(self):
+    def test_should_return_exactly_the_same_data_as_passed_to_constructor_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         data = any_data()
         payload = BytesPayload(data)
@@ -1293,7 +1342,8 @@
         # THEN
         self.assertEqual(data, actual)
 
-    def test_should_return_the_same_len_as_data_passed_to_constructor_when_len_is_called_on_BytesPayload_object(self):
+    def test_should_return_the_same_len_as_data_passed_to_constructor_when_len_is_called_on_BytesPayload_object(
+        self):
         # GIVEN
         data = any_data()
         payload = BytesPayload(data)
@@ -1307,7 +1357,8 @@
 
 class TestICMPv6EchoBody(unittest.TestCase):
 
-    def test_convert_ICMPv6_echo_body_to_data_when_to_bytes_method_is_called(self):
+    def test_convert_ICMPv6_echo_body_to_data_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         identifier = any_identifier()
         sequence_number = any_sequence_number()
@@ -1319,19 +1370,21 @@
         actual = body.to_bytes()
 
         # THEN
-        expected = bytearray([identifier >> 8, identifier & 0xff, sequence_number >> 8, sequence_number & 0xff]) + data
+        expected = bytearray([
+            identifier >> 8, identifier & 0xff, sequence_number >> 8,
+            sequence_number & 0xff
+        ]) + data
         self.assertEqual(expected, actual)
 
-    def test_should_create_ICMPv6EchoBody_from_data_when_from_bytes_classmethod_is_called(self):
+    def test_should_create_ICMPv6EchoBody_from_data_when_from_bytes_classmethod_is_called(
+        self):
         # GIVEN
         identifier = any_identifier()
         sequence_number = any_sequence_number()
         body_data = any_data()
 
-        data = bytearray([(identifier >> 8),
-                          (identifier & 0xff),
-                          (sequence_number >> 8),
-                          (sequence_number & 0xff)])
+        data = bytearray([(identifier >> 8), (identifier & 0xff),
+                          (sequence_number >> 8), (sequence_number & 0xff)])
         data += body_data
 
         # WHEN
@@ -1342,19 +1395,24 @@
         self.assertEqual(sequence_number, actual.sequence_number)
         self.assertEqual(body_data, actual.data)
 
-    def test_should_build_ICMPv6EchoBody_from_well_know_values_when_to_bytes_method_is_called(self):
+    def test_should_build_ICMPv6EchoBody_from_well_know_values_when_to_bytes_method_is_called(
+        self):
         # GIVEN
-        body = ICMPv6EchoBody(0, 2, bytearray([0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01,
-                                               0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
-                                               0x41, 0x41]))
+        body = ICMPv6EchoBody(
+            0, 2,
+            bytearray([
+                0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x41,
+                0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
+            ]))
 
         # WHEN
         actual = body.to_bytes()
 
         # THEN
-        expected = bytearray([0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf,
-                              0x00, 0x00, 0x00, 0x01, 0x41, 0x41, 0x41, 0x41,
-                              0x41, 0x41, 0x41, 0x41, 0x41, 0x41])
+        expected = bytearray([
+            0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00,
+            0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
+        ])
 
         self.assertEqual(expected, actual)
 
@@ -1368,7 +1426,8 @@
         body_data = any_data()
 
         data = bytearray([(identifier >> 8) & 0xff, identifier & 0xff,
-                          (sequence_number >> 8) & 0xff, sequence_number & 0xff]) + body_data
+                          (sequence_number >> 8) & 0xff, sequence_number & 0xff
+                         ]) + body_data
 
         factory = ICMPv6EchoBodyFactory()
 
@@ -1385,7 +1444,8 @@
 
 class TestICMPv6DestinationUnreachable(unittest.TestCase):
 
-    def test_should_convert_ICMPv6DestinationUnreachable_to_bytearray_when_to_bytes_method_is_called(self):
+    def test_should_convert_ICMPv6DestinationUnreachable_to_bytearray_when_to_bytes_method_is_called(
+        self):
         # GIVEN
         data = any_data()
 
@@ -1395,9 +1455,11 @@
         actual_data = icmpv6_dest_unreachable.to_bytes()
 
         # THEN
-        self.assertEqual(bytearray([0x00, 0x00, 0x00, 0x00]) + data, actual_data)
+        self.assertEqual(
+            bytearray([0x00, 0x00, 0x00, 0x00]) + data, actual_data)
 
-    def test_should_convert_bytearray_to_ICMPv6DestinationUnreachable_when_from_bytes_method_is_called(self):
+    def test_should_convert_bytearray_to_ICMPv6DestinationUnreachable_when_from_bytes_method_is_called(
+        self):
         # GIVEN
         data = any_data()
 
@@ -1415,13 +1477,15 @@
         unused = random.randint(1, 1 << 32)
 
         # WHEN
-        self.assertRaises(RuntimeError, ICMPv6DestinationUnreachable.from_bytes,
-                          io.BytesIO(bytearray(struct.pack(">I", unused)) + data))
+        self.assertRaises(
+            RuntimeError, ICMPv6DestinationUnreachable.from_bytes,
+            io.BytesIO(bytearray(struct.pack(">I", unused)) + data))
 
 
 class TestICMPv6DestinationUnreachableFactory(unittest.TestCase):
 
-    def test_should_create_ICMPv6DestinationUnreachable_when_parse_method_is_called(self):
+    def test_should_create_ICMPv6DestinationUnreachable_when_parse_method_is_called(
+        self):
         # GIVEN
         icmp_data = any_data()
 
@@ -1430,7 +1494,8 @@
         data = bytearray([0x00, 0x00, 0x00, 0x00]) + icmp_data
 
         # WHEN
-        icmpv6_dest_unreachable = factory.parse(io.BytesIO(data), any_message_info())
+        icmpv6_dest_unreachable = factory.parse(io.BytesIO(data),
+                                                any_message_info())
 
         # THEN
         self.assertEqual(icmp_data, icmpv6_dest_unreachable.data)
@@ -1462,7 +1527,8 @@
 
 class TestHopByHopOptionsFactory(unittest.TestCase):
 
-    def test_should_create_option_from_bytearray_when_to_bytes_method_is_called(self):
+    def test_should_create_option_from_bytearray_when_to_bytes_method_is_called(
+        self):
         # GIVEN
 
         class DummyOptionFactory:
@@ -1470,7 +1536,8 @@
             def parse(self, data, message_info):
                 return data.read()
 
-        factory = HopByHopOptionsFactory(options_factories={2: DummyOptionFactory()})
+        factory = HopByHopOptionsFactory(
+            options_factories={2: DummyOptionFactory()})
 
         data = bytearray([0x02, 0x03, 0x11, 0x22, 0x33, 0x01, 0x00])
 
diff --git a/tests/scripts/thread-cert/test_ipv6_fragmentation.py b/tests/scripts/thread-cert/test_ipv6_fragmentation.py
index 90bb440..65c1349 100755
--- a/tests/scripts/thread-cert/test_ipv6_fragmentation.py
+++ b/tests/scripts/thread-cert/test_ipv6_fragmentation.py
@@ -29,38 +29,30 @@
 
 import unittest
 
+import common
 import config
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 
 
-class TestIPv6Fragmentation(unittest.TestCase):
+class TestIPv6Fragmentation(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xcafe)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xcafe)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xcafe,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xcafe,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -71,22 +63,22 @@
         self.simulator.go(5)
         self.assertEqual(self.nodes[ROUTER].get_state(), 'router')
 
-        mleid_leader = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.ML_EID)
-        mleid_router = self.nodes[ROUTER].get_ip6_address(config.ADDRESS_TYPE.ML_EID)
+        mleid_leader = self.nodes[LEADER].get_ip6_address(
+            config.ADDRESS_TYPE.ML_EID)
+        mleid_router = self.nodes[ROUTER].get_ip6_address(
+            config.ADDRESS_TYPE.ML_EID)
 
-        self.nodes[LEADER].udp_start("::", 12345)
-        self.nodes[ROUTER].udp_start("::", 12345)
+        self.nodes[LEADER].udp_start("::", common.UDP_TEST_PORT)
+        self.nodes[ROUTER].udp_start("::", common.UDP_TEST_PORT)
 
-        self.nodes[LEADER].udp_send(1952, mleid_router, 12345)
+        self.nodes[LEADER].udp_send(1952, mleid_router, common.UDP_TEST_PORT)
         self.simulator.go(5)
         self.nodes[ROUTER].udp_check_rx(1952)
 
-        self.nodes[ROUTER].udp_send(1831, mleid_leader, 12345)
+        self.nodes[ROUTER].udp_send(1831, mleid_leader, common.UDP_TEST_PORT)
         self.simulator.go(5)
         self.nodes[LEADER].udp_check_rx(1831)
 
-        self.nodes[ROUTER].udp_send(1953, mleid_leader, 12345, False)
-
         self.nodes[ROUTER].udp_stop()
         self.nodes[LEADER].udp_stop()
 
diff --git a/tests/scripts/thread-cert/test_ipv6_source_selection.py b/tests/scripts/thread-cert/test_ipv6_source_selection.py
index 0c51f0d..58df28c 100755
--- a/tests/scripts/thread-cert/test_ipv6_source_selection.py
+++ b/tests/scripts/thread-cert/test_ipv6_source_selection.py
@@ -29,39 +29,29 @@
 
 import unittest
 
-import config
 import ipv6
-import node
+import thread_cert
 
 LEADER = 1
 ROUTER = 2
 
 
-class TestIPv6SourceSelection(unittest.TestCase):
+class TestIPv6SourceSelection(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 3):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xcafe)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER].set_panid(0xcafe)
-        self.nodes[ROUTER].set_mode('rsdn')
-        self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER].enable_whitelist()
-        self.nodes[ROUTER].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xcafe,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xcafe,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
diff --git a/tests/scripts/thread-cert/test_lowpan.py b/tests/scripts/thread-cert/test_lowpan.py
index 04ebc1c..4635f88 100755
--- a/tests/scripts/thread-cert/test_lowpan.py
+++ b/tests/scripts/thread-cert/test_lowpan.py
@@ -41,20 +41,22 @@
 def create_default_lowpan_parser(context_manager):
     return lowpan.LowpanParser(
         lowpan_mesh_header_factory=lowpan.LowpanMeshHeaderFactory(),
-        lowpan_decompressor=config.create_default_lowpan_decompressor(context_manager),
-        lowpan_fragements_buffers_manager=lowpan.LowpanFragmentsBuffersManager(),
+        lowpan_decompressor=config.create_default_lowpan_decompressor(
+            context_manager),
+        lowpan_fragements_buffers_manager=lowpan.LowpanFragmentsBuffersManager(
+        ),
         ipv6_packet_factory=ipv6.IPv6PacketFactory(
             ehf=config.create_default_ipv6_extension_headers_factories(),
             ulpf={
-                17: ipv6.UDPDatagramFactory(
-                    udp_header_factory=ipv6.UDPHeaderFactory(),
-                    udp_payload_factory=ipv6.BytesPayloadFactory()),
-                58: ipv6.ICMPv6Factory(
-                    body_factories=config.create_default_ipv6_icmp_body_factories()
-                )
-            }
-        )
-    )
+                17:
+                    ipv6.UDPDatagramFactory(
+                        udp_header_factory=ipv6.UDPHeaderFactory(),
+                        udp_payload_factory=ipv6.BytesPayloadFactory()),
+                58:
+                    ipv6.ICMPv6Factory(
+                        body_factories=config.
+                        create_default_ipv6_icmp_body_factories())
+            }))
 
 
 def any_tf():
@@ -194,7 +196,8 @@
 
 
 def any_context():
-    prefix = bytearray([random.getrandbits(8) for _ in range(random.randint(2, 15))])
+    prefix = bytearray(
+        [random.getrandbits(8) for _ in range(random.randint(2, 15))])
     prefix_length = len(prefix)
     return lowpan.Context(prefix, prefix_length * 8)
 
@@ -202,9 +205,11 @@
 def any_mac_address():
     length = random.choice([2, 8])
     if length == 2:
-        return common.MacAddress.from_rloc16(bytearray([random.getrandbits(8) for _ in range(length)]))
+        return common.MacAddress.from_rloc16(
+            bytearray([random.getrandbits(8) for _ in range(length)]))
     elif length == 8:
-        return common.MacAddress.from_eui64(bytearray([random.getrandbits(8) for _ in range(length)]))
+        return common.MacAddress.from_eui64(
+            bytearray([random.getrandbits(8) for _ in range(length)]))
 
 
 def any_hops_left():
@@ -230,7 +235,8 @@
 
 class TestLowpanIPHC(unittest.TestCase):
 
-    def test_should_create_LowpanIPHC_object_when_from_bytes_classmethod_called(self):
+    def test_should_create_LowpanIPHC_object_when_from_bytes_classmethod_called(
+        self):
         # GIVEN
         tf = any_tf()
         nh = any_nh()
@@ -243,7 +249,8 @@
         dam = any_dam()
 
         byte0 = (3 << 5) | (tf << 3) | (nh << 2) | hlim
-        byte1 = (cid << 7) | (sac << 6) | (sam << 4) | (m << 3) | (dac << 2) | dam
+        byte1 = (cid << 7) | (sac << 6) | (sam << 4) | (m << 3) | (
+            dac << 2) | dam
 
         data_bytes = bytearray([byte0, byte1])
 
@@ -264,24 +271,25 @@
 
 class TestLowpanParser(unittest.TestCase):
 
-    def test_should_parse_6lo_with_mesh_hdr_that_contains_hlim_stored_on_2_bytes_when_decompress_method_called(self):
+    def test_should_parse_6lo_with_mesh_hdr_that_contains_hlim_stored_on_2_bytes_when_decompress_method_called(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0xbf, 0x13, 0x90, 0x00, 0x48, 0x01, 0x7c, 0x77,
-                                   0x3f, 0xf2, 0xbf, 0xc0, 0x00, 0x24, 0xb1, 0x62,
-                                   0x44, 0x02, 0xf0, 0xba, 0x0d, 0xff, 0x04, 0x01,
-                                   0x00, 0x02, 0x02, 0x08, 0x00, 0x07, 0x09, 0x50,
-                                   0x20, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00])
+        lowpan_packet = bytearray([
+            0xbf, 0x13, 0x90, 0x00, 0x48, 0x01, 0x7c, 0x77, 0x3f, 0xf2, 0xbf,
+            0xc0, 0x00, 0x24, 0xb1, 0x62, 0x44, 0x02, 0xf0, 0xba, 0x0d, 0xff,
+            0x04, 0x01, 0x00, 0x02, 0x02, 0x08, 0x00, 0x07, 0x09, 0x50, 0x20,
+            0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x21, 0x11, 0x3f,
-                                 0xfd, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x90, 0x00,
-                                 0xfd, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x48, 0x01,
-                                 0xf0, 0xbf, 0xc0, 0x00, 0x00, 0x21, 0xe2, 0xdd,
-                                 0x62, 0x44, 0x02, 0xf0, 0xba, 0x0d, 0xff, 0x04,
-                                 0x01, 0x00, 0x02, 0x02, 0x08, 0x00, 0x07, 0x09,
-                                 0x50, 0x20, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00,
-                                 0x00])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x21, 0x11, 0x3f, 0xfd, 0x00, 0x0d,
+            0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00,
+            0x90, 0x00, 0xfd, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0xff, 0xfe, 0x00, 0x48, 0x01, 0xf0, 0xbf, 0xc0, 0x00,
+            0x00, 0x21, 0xe2, 0xdd, 0x62, 0x44, 0x02, 0xf0, 0xba, 0x0d, 0xff,
+            0x04, 0x01, 0x00, 0x02, 0x02, 0x08, 0x00, 0x07, 0x09, 0x50, 0x20,
+            0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -295,25 +303,29 @@
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_uncompressed_udp_and_without_hbh_when_decompress_method_called(self):
+    def test_should_parse_6lo_with_uncompressed_udp_and_without_hbh_when_decompress_method_called(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0x33, 0x11, 0x16, 0x33, 0x16, 0x34, 0x00,
-                                   0x14, 0xcf, 0x63, 0x80, 0x00, 0xfa, 0xa5, 0x0b,
-                                   0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0x33, 0x11, 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf, 0x63,
+            0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb,
+            0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x11, 0x40,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17,
-                                 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf, 0x63,
-                                 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x11, 0x40, 0xfe, 0x80, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17, 0x16, 0x33, 0x16, 0x34,
+            0x00, 0x14, 0xcf, 0x63, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00,
+            0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -324,25 +336,28 @@
         parser = create_default_lowpan_parser(context_manager=None)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_udp_and_without_hbh_when_decompress_method_called(self):
+    def test_should_parse_6lo_with_compressed_udp_and_without_hbh_when_decompress_method_called(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7e, 0x33, 0xf0, 0x16, 0x33, 0x16, 0x34, 0x04,
-                                   0xd2, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00,
-                                   0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7e, 0x33, 0xf0, 0x16, 0x33, 0x16, 0x34, 0x04, 0xd2, 0x80, 0x00,
+            0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x11, 0x40,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17,
-                                 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf, 0x63,
-                                 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x11, 0x40, 0xfe, 0x80, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17, 0x16, 0x33, 0x16, 0x34,
+            0x00, 0x14, 0xcf, 0x63, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00,
+            0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -353,27 +368,30 @@
         parser = create_default_lowpan_parser(context_manager=None)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_uncompressed_udp_and_with_uncompressed_hbh_when_decompress_method_called(self):
+    def test_should_parse_6lo_with_uncompressed_udp_and_with_uncompressed_hbh_when_decompress_method_called(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0x33, 0x00, 0x11, 0x00, 0x6d, 0x04, 0x40,
-                                   0x02, 0x00, 0x18, 0x16, 0x33, 0x16, 0x34, 0x00,
-                                   0x0c, 0x04, 0xd2, 0x80, 0x00, 0xfa, 0xa5, 0x0b,
-                                   0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0x33, 0x00, 0x11, 0x00, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18,
+            0x16, 0x33, 0x16, 0x34, 0x00, 0x0c, 0x04, 0xd2, 0x80, 0x00, 0xfa,
+            0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x40,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17,
-                                 0x11, 0x00, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18,
-                                 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf, 0x63,
-                                 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x40, 0xfe, 0x80, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17, 0x11, 0x00, 0x6d, 0x04,
+            0x40, 0x02, 0x00, 0x18, 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf,
+            0x63, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92,
+            0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -384,27 +402,30 @@
         parser = create_default_lowpan_parser(context_manager=None)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_uncompressed_udp_and_with_compressed_hbh_when_decompress_method_called(self):
+    def test_should_parse_6lo_with_uncompressed_udp_and_with_compressed_hbh_when_decompress_method_called(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7e, 0x33, 0xe0, 0x11, 0x06, 0x6d, 0x04, 0x40,
-                                   0x02, 0x00, 0x18, 0x16, 0x33, 0x16, 0x34, 0x00,
-                                   0x0c, 0x04, 0xd2, 0x80, 0x00, 0xfa, 0xa5, 0x0b,
-                                   0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7e, 0x33, 0xe0, 0x11, 0x06, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18,
+            0x16, 0x33, 0x16, 0x34, 0x00, 0x0c, 0x04, 0xd2, 0x80, 0x00, 0xfa,
+            0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x40,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17,
-                                 0x11, 0x00, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18,
-                                 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf, 0x63,
-                                 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x40, 0xfe, 0x80, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17, 0x11, 0x00, 0x6d, 0x04,
+            0x40, 0x02, 0x00, 0x18, 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf,
+            0x63, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92,
+            0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -415,27 +436,30 @@
         parser = create_default_lowpan_parser(context_manager=None)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_udp_and_with_compressed_hbh_when_decompress_method_called(self):
+    def test_should_parse_6lo_with_compressed_udp_and_with_compressed_hbh_when_decompress_method_called(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7e, 0x33, 0xe1, 0x06, 0x6d, 0x04, 0x40, 0x02,
-                                   0x00, 0x18, 0xf0, 0x16, 0x33, 0x16, 0x34, 0x04,
-                                   0xd2, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00,
-                                   0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7e, 0x33, 0xe1, 0x06, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18, 0xf0,
+            0x16, 0x33, 0x16, 0x34, 0x04, 0xd2, 0x80, 0x00, 0xfa, 0xa5, 0x0b,
+            0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x40,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17,
-                                 0x11, 0x00, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18,
-                                 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf, 0x63,
-                                 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x40, 0xfe, 0x80, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17, 0x11, 0x00, 0x6d, 0x04,
+            0x40, 0x02, 0x00, 0x18, 0x16, 0x33, 0x16, 0x34, 0x00, 0x14, 0xcf,
+            0x63, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92,
+            0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -446,25 +470,28 @@
         parser = create_default_lowpan_parser(context_manager=None)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xd5, 0xaa, 0x3a, 0x02, 0x99, 0x99, 0xff,
-                                   0xfe, 0x22, 0x11, 0x01, 0x36, 0x29, 0x96, 0xff,
-                                   0xfe, 0xac, 0xff, 0x18, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xd5, 0xaa, 0x3a, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11,
+            0x01, 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18, 0x80, 0x00,
+            0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x01,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18,
-                                 0x80, 0x00, 0x97, 0xf3, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0x20, 0x00, 0x0d,
+            0xb8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x01, 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18, 0x80, 0x00, 0x97, 0xf3,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -478,25 +505,28 @@
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_1(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_1(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xd5, 0xaa, 0x3a, 0x02, 0x99, 0x99, 0xff,
-                                   0xfe, 0x22, 0x11, 0x01, 0x36, 0x29, 0x96, 0xff,
-                                   0xfe, 0xac, 0xff, 0x18, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xd5, 0xaa, 0x3a, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11,
+            0x01, 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18, 0x80, 0x00,
+            0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x01,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18,
-                                 0x80, 0x00, 0x97, 0xf3, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0x20, 0x00, 0x0d,
+            0xb8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x01, 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18, 0x80, 0x00, 0x97, 0xf3,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -510,25 +540,28 @@
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_2(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_2(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xf0, 0xa0, 0x3a, 0x20, 0x0d, 0x14, 0x56,
-                                   0x12, 0x55, 0x00, 0x00, 0x25, 0x14, 0x46, 0xff,
-                                   0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xf0, 0xa0, 0x3a, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00,
+            0x00, 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00,
+            0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00,
-                                 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe,
-                                 0x80, 0x00, 0xb3, 0xf3, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0x20, 0x00, 0x0d,
+            0xb8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00, 0x25,
+            0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xb3, 0xf3,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -542,25 +575,28 @@
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_3(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_3(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xd5, 0xaa, 0x3a, 0x02, 0x99, 0x99, 0xff,
-                                   0xfe, 0x22, 0x11, 0x01, 0x36, 0x29, 0x96, 0xff,
-                                   0xfe, 0xac, 0xff, 0x18, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xd5, 0xaa, 0x3a, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11,
+            0x01, 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18, 0x80, 0x00,
+            0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x01,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18,
-                                 0x80, 0x00, 0x97, 0xf3, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0x20, 0x00, 0x0d,
+            0xb8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x01, 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18, 0x80, 0x00, 0x97, 0xf3,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -574,24 +610,28 @@
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_4(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_4(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xf5, 0xaa, 0x3a, 0x36, 0x29, 0x96, 0xff,
-                                   0xfe, 0xac, 0xff, 0x18, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xf5, 0xaa, 0x3a, 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff,
+            0x18, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92,
+            0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x36, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18,
-                                 0x80, 0x00, 0x97, 0xf4, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0x20, 0x00, 0x0d,
+            0xb8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x36,
+            0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x18, 0x80, 0x00, 0x97, 0xf4,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -605,23 +645,27 @@
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_5(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_5(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xf7, 0xac, 0x3a, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xf7, 0xac, 0x3a, 0x80, 0x00, 0xfa, 0xa5, 0x0b, 0xc0, 0x00,
+            0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00,
-                                 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe,
-                                 0x80, 0x00, 0xb3, 0xf3, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0x20, 0x00, 0x0d,
+            0xb8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00, 0x25,
+            0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xb3, 0xf3,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -631,30 +675,34 @@
 
         context_manager = lowpan.ContextManager()
         context_manager[10] = lowpan.Context(prefix="2000:0db8::/64")
-        context_manager[12] = lowpan.Context(prefix="200d:1456:1255:0000:2514:46ff:fedd:2afe/128")
+        context_manager[12] = lowpan.Context(
+            prefix="200d:1456:1255:0000:2514:46ff:fedd:2afe/128")
 
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_6(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_6(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xf0, 0xc0, 0x3a, 0x20, 0x0d, 0x14, 0x56,
-                                   0x12, 0x54, 0x00, 0x00, 0x12, 0x54, 0x11, 0xff,
-                                   0xfe, 0x1c, 0x7e, 0xff, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xf0, 0xc0, 0x3a, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x54, 0x00,
+            0x00, 0x12, 0x54, 0x11, 0xff, 0xfe, 0x1c, 0x7e, 0xff, 0x80, 0x00,
+            0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00,
-                                 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe,
-                                 0x20, 0x0d, 0x14, 0x56, 0x12, 0x54, 0x00, 0x00,
-                                 0x12, 0x54, 0x11, 0xff, 0xfe, 0x1c, 0x7e, 0xff,
-                                 0x80, 0x00, 0xa5, 0x40, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0x20, 0x0d, 0x14,
+            0x56, 0x12, 0x55, 0x00, 0x00, 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd,
+            0x2a, 0xfe, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x54, 0x00, 0x00, 0x12,
+            0x54, 0x11, 0xff, 0xfe, 0x1c, 0x7e, 0xff, 0x80, 0x00, 0xa5, 0x40,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -663,31 +711,35 @@
             bytearray([0x34, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17]))
 
         context_manager = lowpan.ContextManager()
-        context_manager[12] = lowpan.Context(prefix="200d:1456:1255:0000:2514:46ff:fedd:2afe/128")
+        context_manager[12] = lowpan.Context(
+            prefix="200d:1456:1255:0000:2514:46ff:fedd:2afe/128")
 
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_7(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_7(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xd0, 0xd0, 0x3a, 0x00, 0x02, 0x98, 0xff,
-                                   0xfe, 0x22, 0x12, 0x00, 0x20, 0x0d, 0x14, 0x56,
-                                   0x12, 0x55, 0x00, 0x00, 0x25, 0x14, 0x46, 0xff,
-                                   0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xd0, 0xd0, 0x3a, 0x00, 0x02, 0x98, 0xff, 0xfe, 0x22, 0x12,
+            0x00, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00, 0x25, 0x14,
+            0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xfa, 0xa5, 0x0b,
+            0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0xaa, 0xbb, 0xcc, 0xdd, 0x00, 0x00, 0x00, 0x00,
-                                 0x77, 0x82, 0x98, 0xff, 0xfe, 0x22, 0x12, 0x00,
-                                 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00,
-                                 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe,
-                                 0x80, 0x00, 0xf5, 0x28, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0xaa, 0xbb, 0xcc,
+            0xdd, 0x00, 0x00, 0x00, 0x00, 0x77, 0x82, 0x98, 0xff, 0xfe, 0x22,
+            0x12, 0x00, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00, 0x25,
+            0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xf5, 0x28,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -696,30 +748,34 @@
             bytearray([0x34, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17]))
 
         context_manager = lowpan.ContextManager()
-        context_manager[13] = lowpan.Context(prefix="AABB:CCDD:0000:0000:7796::/75")
+        context_manager[13] = lowpan.Context(
+            prefix="AABB:CCDD:0000:0000:7796::/75")
 
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_8(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_8(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xf0, 0xd0, 0x3a, 0x20, 0x0d, 0x14, 0x56,
-                                   0x12, 0x55, 0x00, 0x00, 0x25, 0x14, 0x46, 0xff,
-                                   0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xf0, 0xd0, 0x3a, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00,
+            0x00, 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00,
+            0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0xaa, 0xbb, 0xcc, 0xdd, 0x00, 0x00, 0x00, 0x00,
-                                 0x77, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00,
-                                 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe,
-                                 0x80, 0x00, 0xf5, 0x11, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0xaa, 0xbb, 0xcc,
+            0xdd, 0x00, 0x00, 0x00, 0x00, 0x77, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00, 0x25,
+            0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xf5, 0x11,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -728,30 +784,34 @@
             bytearray([0x34, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17]))
 
         context_manager = lowpan.ContextManager()
-        context_manager[13] = lowpan.Context(prefix="AABB:CCDD:0000:0000:7796::/75")
+        context_manager[13] = lowpan.Context(
+            prefix="AABB:CCDD:0000:0000:7796::/75")
 
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_9(self):
+    def test_should_parse_6lo_with_compressed_icmp_and_without_compressed_hbh_when_decompress_method_called_9(
+        self):
         # GIVEN
-        lowpan_packet = bytearray([0x7a, 0xf0, 0xd0, 0x3a, 0x20, 0x0d, 0x14, 0x56,
-                                   0x12, 0x55, 0x00, 0x00, 0x25, 0x14, 0x46, 0xff,
-                                   0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xfa, 0xa5,
-                                   0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53])
+        lowpan_packet = bytearray([
+            0x7a, 0xf0, 0xd0, 0x3a, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00,
+            0x00, 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00,
+            0xfa, 0xa5, 0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
-                                 0xaa, 0xbb, 0xcc, 0xdd, 0x00, 0x00, 0x00, 0x00,
-                                 0x77, 0x99, 0x99, 0xff, 0xfe, 0x22, 0x11, 0x00,
-                                 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00,
-                                 0x25, 0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe,
-                                 0x80, 0x00, 0xf5, 0x11, 0x0b, 0xc0, 0x00, 0x04,
-                                 0x4e, 0x92, 0xbb, 0x53])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40, 0xaa, 0xbb, 0xcc,
+            0xdd, 0x00, 0x00, 0x00, 0x00, 0x77, 0x99, 0x99, 0xff, 0xfe, 0x22,
+            0x11, 0x00, 0x20, 0x0d, 0x14, 0x56, 0x12, 0x55, 0x00, 0x00, 0x25,
+            0x14, 0x46, 0xff, 0xfe, 0xdd, 0x2a, 0xfe, 0x80, 0x00, 0xf5, 0x11,
+            0x0b, 0xc0, 0x00, 0x04, 0x4e, 0x92, 0xbb, 0x53
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -759,198 +819,188 @@
         message_info.destination_mac_address = common.MacAddress.from_eui64(
             bytearray([0x34, 0x29, 0x96, 0xff, 0xfe, 0xac, 0xff, 0x17]))
         context_manager = lowpan.ContextManager()
-        context_manager[13] = lowpan.Context(prefix="AABB:CCDD:0000:0000:7796::/75")
+        context_manager[13] = lowpan.Context(
+            prefix="AABB:CCDD:0000:0000:7796::/75")
 
         parser = create_default_lowpan_parser(context_manager)
 
         # WHEN
-        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet), message_info)
+        actual_ipv6_packet = parser.parse(io.BytesIO(lowpan_packet),
+                                          message_info)
 
         # THEN
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_defragment_big_IPv6_packet_when_parse_method_called_with_fragments_in_random_order(self):
+    def test_should_defragment_big_IPv6_packet_when_parse_method_called_with_fragments_in_random_order(
+        self):
         # GIVEN
-        fragment_1 = bytearray([0xC5, 0x00, 0x31, 0x9F, 0x7A, 0x33, 0x3A,
-                                0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E])
+        fragment_1 = bytearray([
+            0xC5, 0x00, 0x31, 0x9F, 0x7A, 0x33, 0x3A, 0x80, 0x00, 0xFA, 0xA5,
+            0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
+            0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3,
+            0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44, 0x54, 0x12, 0x43, 0x53,
+            0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
+            0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x92, 0xBB, 0x53,
+            0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54,
+            0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x80,
+            0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53,
+            0x11, 0x4C, 0x66, 0x4E
+        ])
 
-        fragment_2 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x11,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
-                                0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                0x22, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA])
+        fragment_2 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x11, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66,
+            0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44,
+            0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66, 0xFE, 0x92, 0xBB, 0x53,
+            0x1A, 0x44, 0x66, 0x77, 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44,
+            0x66, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3,
+            0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92,
+            0xBB, 0x53, 0x1A, 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
+            0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E, 0x22, 0xBB, 0x53,
+            0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54,
+            0x01, 0xAA
+        ])
 
-        fragment_3 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x1D,
-                                0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44, 0x66,
-                                0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                0xC0, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0xCC, 0x4E,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77])
+        fragment_3 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x1D, 0x44, 0x54, 0x12, 0xD3, 0x53, 0x11,
+            0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
+            0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x92, 0xBB, 0x53, 0x1A,
+            0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01,
+            0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0xC0, 0x00,
+            0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11,
+            0x44, 0xCC, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
+            0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44, 0x54, 0x12,
+            0x43, 0x53, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44,
+            0x66, 0x77
+        ])
 
-        fragment_4 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x29,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99])
+        fragment_4 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x29, 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11,
+            0x44, 0x66, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15,
+            0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E,
+            0x92, 0xBB, 0x53, 0x1A, 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00,
+            0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB,
+            0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC,
+            0x54, 0x01, 0xAA, 0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
+            0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x1A, 0x92,
+            0xBB, 0x53, 0x11, 0x44, 0x66, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66,
+            0x77, 0x99
+        ])
 
-        fragment_5 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x35,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
-                                0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A])
+        fragment_5 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x35, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54,
+            0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x80,
+            0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53,
+            0x11, 0x4C, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
+            0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44, 0x54,
+            0x12, 0xa3, 0x53, 0x11, 0x44, 0x66, 0xFE, 0x92, 0xBB, 0x53, 0x1A,
+            0x44, 0x66, 0x77, 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
+            0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00,
+            0x54, 0xCC, 0x54, 0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB,
+            0x53, 0x1A
+        ])
 
-        fragment_6 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x41,
-                                0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                0x22, 0xBB, 0x53, 0x1A, 0x44, 0x67, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44, 0x66,
-                                0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                0xC0, 0x00, 0xFA, 0x15, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0xCC, 0x4E])
+        fragment_6 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x41, 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0,
+            0x00, 0x04, 0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E, 0x22,
+            0xBB, 0x53, 0x1A, 0x44, 0x67, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54,
+            0xCC, 0x54, 0x01, 0xAA, 0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44,
+            0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x1A,
+            0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x92, 0xBB, 0x53, 0x1A, 0x44,
+            0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
+            0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0xC0, 0x00, 0xFA,
+            0x15, 0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44,
+            0xCC, 0x4E
+        ])
 
-        fragment_7 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x4D,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBA, 0x53, 0x1A,
-                                0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3A, 0x64,
-                                0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                0x02, 0x00, 0x00, 0x11, 0x12, 0x13, 0x14, 0x15,
-                                0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
+        fragment_7 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x4D, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66,
+            0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44,
+            0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBC, 0x53,
+            0x1A, 0x44, 0x66, 0x77, 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44,
+            0x66, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3,
+            0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92,
+            0xBA, 0x53, 0x1A, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3A, 0x64,
+            0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+            0x11, 0x12, 0x13, 0x14, 0x15, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00
+        ])
 
-        fragment_8 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x59,
-                                0x02, 0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43,
-                                0x60, 0x00, 0xF0, 0x00, 0x00, 0x10, 0x3A, 0x64,
-                                0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                0x02, 0x00, 0x00, 0x11, 0x12, 0x13, 0x14, 0x15,
-                                0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                0x02, 0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43,
-                                0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77])
+        fragment_8 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x59, 0x02, 0x00, 0x1A, 0x2A, 0x3F, 0x09,
+            0xAB, 0x43, 0x60, 0x00, 0xF0, 0x00, 0x00, 0x10, 0x3A, 0x64, 0xfe,
+            0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11,
+            0x12, 0x13, 0x14, 0x15, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x02, 0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43, 0x80, 0x00,
+            0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11,
+            0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
+            0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44, 0x54, 0x12,
+            0x43, 0x53, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44,
+            0x66, 0x77
+        ])
 
-        fragment_9 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x65,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E,
-                                0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
-                                0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                0x92, 0xBB, 0x53, 0x1A, 0x4D, 0x66, 0x77, 0x99])
+        fragment_9 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x65, 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11,
+            0x44, 0x66, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15,
+            0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E,
+            0x92, 0xBB, 0x53, 0x1A, 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00,
+            0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E, 0x92, 0xBB,
+            0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC,
+            0x54, 0x01, 0xAA, 0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
+            0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x1A, 0x92,
+            0xBB, 0x53, 0x11, 0x44, 0x66, 0x92, 0xBB, 0x53, 0x1A, 0x4D, 0x66,
+            0x77, 0x99
+        ])
 
-        fragment_10 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x71,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x22, 0xBB, 0x51, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A])
+        fragment_10 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x71, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54,
+            0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x80,
+            0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0x1B, 0x53,
+            0x11, 0x44, 0x66, 0x4E, 0x22, 0xBB, 0x51, 0x1A, 0x44, 0x66, 0x77,
+            0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44, 0x54,
+            0x12, 0xD3, 0x53, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
+            0x44, 0x66, 0x77, 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
+            0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00,
+            0x54, 0xCC, 0x54, 0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB,
+            0x53, 0x1A
+        ])
 
-        fragment_11 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x7D,
-                                 0xC0, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0xCC, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x4A, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E])
+        fragment_11 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x7D, 0xC0, 0x00, 0xFA, 0xA5, 0x0B, 0xC0,
+            0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0xCC, 0x4E, 0x92,
+            0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54,
+            0xCC, 0x54, 0x01, 0xAA, 0x44, 0x54, 0x12, 0x4A, 0x53, 0x11, 0x44,
+            0x66, 0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x1A,
+            0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x92, 0xBB, 0x53, 0x1A, 0x44,
+            0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
+            0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x80, 0x00, 0xFA,
+            0xA5, 0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44,
+            0x66, 0x4E
+        ])
 
-        fragment_12 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x89,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x3A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA])
+        fragment_12 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x89, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66,
+            0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44,
+            0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53,
+            0x3A, 0x44, 0x66, 0x77, 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44,
+            0x66, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3,
+            0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92,
+            0xBB, 0x53, 0x1A, 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
+            0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E, 0x92, 0xBB, 0x53,
+            0x1A, 0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54,
+            0x01, 0xAA
+        ])
 
-        fragment_13 = bytearray([0xE5, 0x00, 0x31, 0x9F, 0x95,
-                                 0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
-                                 0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x1B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x22, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44, 0x66])
+        fragment_13 = bytearray([
+            0xE5, 0x00, 0x31, 0x9F, 0x95, 0x44, 0x54, 0x12, 0xa3, 0x53, 0x11,
+            0x44, 0x66, 0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
+            0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x92, 0xBB, 0x53, 0x1A,
+            0x44, 0x66, 0x77, 0x99, 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01,
+            0xAA, 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x80, 0x00,
+            0xFA, 0xA5, 0x1B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0x1B, 0x53, 0x11,
+            0x44, 0x66, 0x4E, 0x22, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
+            0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA, 0x44, 0x54, 0x12,
+            0xD3, 0x53, 0x11, 0x44, 0x66
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -976,169 +1026,1292 @@
         actual_ipv6_packet = parser.parse(io.BytesIO(fragment_1), message_info)
 
         # THEN
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x04, 0xD8, 0x3A, 0x40,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x00, 0x00, 0x11, 0x12, 0x13, 0x14, 0x15,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43,  # / * 40 * /
-                                 0x80, 0x00, 0xAB, 0x64, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,  # / * 120 * /
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
-                                 0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,  # / * 200 * /
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x22, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,  # / * 280 * /
-                                 0xC0, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0xCC, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,  # / * 360 * /
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
-                                 0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x22, 0xBB, 0x53, 0x1A, 0x44, 0x67, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0xC0, 0x00, 0xFA, 0x15, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0xCC, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBA, 0x53, 0x1A,
-                                 0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3A, 0x64,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x00, 0x00, 0x11, 0x12, 0x13, 0x14, 0x15,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43,  # / * 720 * /
-                                 0x60, 0x00, 0xF0, 0x00, 0x00, 0x10, 0x3A, 0x64,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x00, 0x00, 0x11, 0x12, 0x13, 0x14, 0x15,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
-                                 0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x4D, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x22, 0xBB, 0x51, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0xC0, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0xCC, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x4A, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBC, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,  # / * 1080 * /
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0x43, 0x53, 0x11, 0x44, 0x66,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x3A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x4C, 0x66, 0x4E,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xa3, 0x53, 0x11, 0x44, 0x66,
-                                 0xFE, 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77,
-                                 0x99, 0x1A, 0x92, 0xBB, 0x53, 0x11, 0x44, 0x66,
-                                 0x92, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x11, 0x44, 0x66, 0x4E, 0x92, 0xBB, 0x53, 0x1A,
-                                 0x80, 0x00, 0xFA, 0xA5, 0x1B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0x1B, 0x53, 0x11, 0x44, 0x66, 0x4E,
-                                 0x22, 0xBB, 0x53, 0x1A, 0x44, 0x66, 0x77, 0x99,
-                                 0x15, 0xB3, 0x00, 0x54, 0xCC, 0x54, 0x01, 0xAA,
-                                 0x44, 0x54, 0x12, 0xD3, 0x53, 0x11, 0x44, 0x66])
+        ipv6_packet = bytearray([
+            0x60,
+            0x00,
+            0x00,
+            0x00,
+            0x04,
+            0xD8,
+            0x3A,
+            0x40,
+            0xfe,
+            0x80,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x02,
+            0x00,
+            0x00,
+            0x11,
+            0x12,
+            0x13,
+            0x14,
+            0x15,
+            0xfe,
+            0x80,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x02,
+            0x00,
+            0x1A,
+            0x2A,
+            0x3F,
+            0x09,
+            0xAB,
+            0x43,  # / * 40 * /
+            0x80,
+            0x00,
+            0xAB,
+            0x64,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0x43,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,  # / * 120 * /
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x4C,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0xa3,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0xFE,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,  # / * 200 * /
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0x1B,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x22,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0xD3,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,  # / * 280 * /
+            0xC0,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0xCC,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0x43,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBC,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,  # / * 360 * /
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0x43,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x4C,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0xa3,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0xFE,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0x1B,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x22,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x67,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0xD3,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0xC0,
+            0x00,
+            0xFA,
+            0x15,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0xCC,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0x43,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBC,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBA,
+            0x53,
+            0x1A,
+            0x60,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x10,
+            0x3A,
+            0x64,
+            0xfe,
+            0x80,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x02,
+            0x00,
+            0x00,
+            0x11,
+            0x12,
+            0x13,
+            0x14,
+            0x15,
+            0xfe,
+            0x80,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x02,
+            0x00,
+            0x1A,
+            0x2A,
+            0x3F,
+            0x09,
+            0xAB,
+            0x43,  # / * 720 * /
+            0x60,
+            0x00,
+            0xF0,
+            0x00,
+            0x00,
+            0x10,
+            0x3A,
+            0x64,
+            0xfe,
+            0x80,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x02,
+            0x00,
+            0x00,
+            0x11,
+            0x12,
+            0x13,
+            0x14,
+            0x15,
+            0xfe,
+            0x80,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x00,
+            0x02,
+            0x00,
+            0x1A,
+            0x2A,
+            0x3F,
+            0x09,
+            0xAB,
+            0x43,
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0x43,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBC,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x4C,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0xa3,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0xFE,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x4D,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0x1B,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x22,
+            0xBB,
+            0x51,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0xD3,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0xC0,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0xCC,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0x4A,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBC,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,  # / * 1080 * /
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0x43,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x3A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x0B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x4C,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0xa3,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0xFE,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x1A,
+            0x92,
+            0xBB,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x92,
+            0xBB,
+            0x53,
+            0x1A,
+            0x80,
+            0x00,
+            0xFA,
+            0xA5,
+            0x1B,
+            0xC0,
+            0x00,
+            0x04,
+            0x4E,
+            0x92,
+            0x1B,
+            0x53,
+            0x11,
+            0x44,
+            0x66,
+            0x4E,
+            0x22,
+            0xBB,
+            0x53,
+            0x1A,
+            0x44,
+            0x66,
+            0x77,
+            0x99,
+            0x15,
+            0xB3,
+            0x00,
+            0x54,
+            0xCC,
+            0x54,
+            0x01,
+            0xAA,
+            0x44,
+            0x54,
+            0x12,
+            0xD3,
+            0x53,
+            0x11,
+            0x44,
+            0x66
+        ])
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
-    def test_should_defragment_IPv6_packet_when_parse_method_called_with_fragments(self):
+    def test_should_defragment_IPv6_packet_when_parse_method_called_with_fragments(
+        self):
         # GIVEN
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -1146,32 +2319,40 @@
         message_info.destination_mac_address = common.MacAddress.from_eui64(
             bytearray([0x00, 0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43]))
 
-        fragment_1 = bytearray([0xC0, 0x38, 0x12, 0x34, 0x7A, 0x33, 0x3A, 0x80,
-                                0x00, 0x1A, 0x33, 0x0B, 0xC0, 0x00, 0x04])
+        fragment_1 = bytearray([
+            0xC0, 0x38, 0x12, 0x34, 0x7A, 0x33, 0x3A, 0x80, 0x00, 0x1A, 0x33,
+            0x0B, 0xC0, 0x00, 0x04
+        ])
 
-        fragment_2 = bytearray([0xE0, 0x38, 0x12, 0x34, 0x06, 0x4E, 0x92, 0xBB,
-                                0x53, 0x11, 0x12, 0x13, 0x14])
+        fragment_2 = bytearray([
+            0xE0, 0x38, 0x12, 0x34, 0x06, 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x12,
+            0x13, 0x14
+        ])
 
         parser = create_default_lowpan_parser(None)
 
         # WHEN
-        self.assertIsNone(parser.parse(io.BytesIO(fragment_1), message_info=message_info))
-        actual_ipv6_packet = parser.parse(io.BytesIO(fragment_2), message_info=message_info)
+        self.assertIsNone(
+            parser.parse(io.BytesIO(fragment_1), message_info=message_info))
+        actual_ipv6_packet = parser.parse(io.BytesIO(fragment_2),
+                                          message_info=message_info)
 
         # THEN
-        ipv6_packet = bytearray([0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3A, 0x40,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x00, 0x00, 0x11, 0x12, 0x13, 0x14, 0x15,
-                                 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                 0x02, 0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43,
-                                 0x80, 0x00, 0x1A, 0x33, 0x0B, 0xC0, 0x00, 0x04,
-                                 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x12, 0x13, 0x14])
+        ipv6_packet = bytearray([
+            0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3A, 0x40, 0xfe, 0x80, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x12, 0x13,
+            0x14, 0x15, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+            0x00, 0x1A, 0x2A, 0x3F, 0x09, 0xAB, 0x43, 0x80, 0x00, 0x1A, 0x33,
+            0x0B, 0xC0, 0x00, 0x04, 0x4E, 0x92, 0xBB, 0x53, 0x11, 0x12, 0x13,
+            0x14
+        ])
         self.assertEqual(ipv6_packet, actual_ipv6_packet.to_bytes())
 
 
 class TestLowpanUdpHeaderFactory(unittest.TestCase):
 
-    def test_should_parse_udp_datagram_ports_when_decompress_udp_ports_method_called_with_udphc_p_eq_0(self):
+    def test_should_parse_udp_datagram_ports_when_decompress_udp_ports_method_called_with_udphc_p_eq_0(
+        self):
         # GIVEN
         factory = lowpan.LowpanUdpHeaderFactory()
 
@@ -1185,14 +2366,16 @@
         data_bytes = struct.pack(">H", src_port) + struct.pack(">H", dst_port)
 
         # WHEN
-        actual_src_port, actual_dst_port = factory._decompress_udp_ports(udphc, io.BytesIO(data_bytes))
+        actual_src_port, actual_dst_port = factory._decompress_udp_ports(
+            udphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(src_port, actual_src_port)
         self.assertEqual(dst_port, actual_dst_port)
         self.assertEqual(0, p)
 
-    def test_should_parse_udp_datagram_ports_when_decompress_udp_ports_method_called_with_udphc_p_eq_1(self):
+    def test_should_parse_udp_datagram_ports_when_decompress_udp_ports_method_called_with_udphc_p_eq_1(
+        self):
         # GIVEN
         factory = lowpan.LowpanUdpHeaderFactory()
 
@@ -1203,17 +2386,20 @@
         src_port = any_src_port()
         dst_port = any_compressable_dst_port()
 
-        data_bytes = struct.pack(">H", src_port) + bytearray([struct.pack(">H", dst_port)[1]])
+        data_bytes = struct.pack(">H", src_port) + bytearray(
+            [struct.pack(">H", dst_port)[1]])
 
         # WHEN
-        actual_src_port, actual_dst_port = factory._decompress_udp_ports(udphc, io.BytesIO(data_bytes))
+        actual_src_port, actual_dst_port = factory._decompress_udp_ports(
+            udphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(1, p)
         self.assertEqual(src_port, actual_src_port)
         self.assertEqual(dst_port, actual_dst_port)
 
-    def test_should_parse_udp_datagram_ports_when_decompress_udp_ports_method_called_with_udphc_p_eq_2(self):
+    def test_should_parse_udp_datagram_ports_when_decompress_udp_ports_method_called_with_udphc_p_eq_2(
+        self):
         # GIVEN
         factory = lowpan.LowpanUdpHeaderFactory()
 
@@ -1224,17 +2410,20 @@
         src_port = any_compressable_src_port()
         dst_port = any_dst_port()
 
-        data_bytes = bytearray([struct.pack(">H", src_port)[1]]) + struct.pack(">H", dst_port)
+        data_bytes = bytearray([struct.pack(">H", src_port)[1]]) + struct.pack(
+            ">H", dst_port)
 
         # WHEN
-        actual_src_port, actual_dst_port = factory._decompress_udp_ports(udphc, io.BytesIO(data_bytes))
+        actual_src_port, actual_dst_port = factory._decompress_udp_ports(
+            udphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(2, p)
         self.assertEqual(src_port, actual_src_port)
         self.assertEqual(dst_port, actual_dst_port)
 
-    def test_should_parse_udp_datagram_ports_when_decompress_udp_ports_method_called_with_udphc_p_eq_3(self):
+    def test_should_parse_udp_datagram_ports_when_decompress_udp_ports_method_called_with_udphc_p_eq_3(
+        self):
         # GIVEN
         factory = lowpan.LowpanUdpHeaderFactory()
 
@@ -1248,14 +2437,16 @@
         data_bytes = bytearray([((src_port & 0x0F) << 4) | (dst_port & 0x0F)])
 
         # WHEN
-        actual_src_port, actual_dst_port = factory._decompress_udp_ports(udphc, io.BytesIO(data_bytes))
+        actual_src_port, actual_dst_port = factory._decompress_udp_ports(
+            udphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(3, p)
         self.assertEqual(src_port, actual_src_port)
         self.assertEqual(dst_port, actual_dst_port)
 
-    def test_should_parse_udp_datagram_checksum_when_decompress_udp_checksum_called_with_udphc_c_eq_0(self):
+    def test_should_parse_udp_datagram_checksum_when_decompress_udp_checksum_called_with_udphc_c_eq_0(
+        self):
         # GIVEN
         factory = lowpan.LowpanUdpHeaderFactory()
 
@@ -1268,13 +2459,15 @@
         data_bytes = struct.pack(">H", checksum)
 
         # WHEN
-        actual_checksum = factory._decompress_udp_checksum(udphc, io.BytesIO(data_bytes))
+        actual_checksum = factory._decompress_udp_checksum(
+            udphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(0, c)
         self.assertEqual(checksum, actual_checksum)
 
-    def test_should_parse_udp_datagram_checksum_when_decompress_udp_checksum_called_with_udphc_c_eq_1(self):
+    def test_should_parse_udp_datagram_checksum_when_decompress_udp_checksum_called_with_udphc_c_eq_1(
+        self):
         # GIVEN
         factory = lowpan.LowpanUdpHeaderFactory()
 
@@ -1285,7 +2478,8 @@
         data_bytes = bytearray()
 
         # WHEN
-        actual_checksum = factory._decompress_udp_checksum(udphc, io.BytesIO(data_bytes))
+        actual_checksum = factory._decompress_udp_checksum(
+            udphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(1, c)
@@ -1294,9 +2488,11 @@
 
 class TestLowpanIpv6HeaderFactory(unittest.TestCase):
 
-    IPV6_LINKLOCAL_PREFIX = bytearray([0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
+    IPV6_LINKLOCAL_PREFIX = bytearray(
+        [0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
 
-    def test_should_parse_traffic_class_and_flow_label_when_decompress_tf_method_called_with_iphc_tf_eq_0(self):
+    def test_should_parse_traffic_class_and_flow_label_when_decompress_tf_method_called_with_iphc_tf_eq_0(
+        self):
         # GIVEN
         ecn = any_ecn()
         dscp = any_dscp()
@@ -1315,14 +2511,16 @@
                                  any_sam(), any_m(), any_dac(), any_dam())
 
         # WHEN
-        actual_traffic_class, actual_flow_label = factory._decompress_tf(iphc, io.BytesIO(data_bytes))
+        actual_traffic_class, actual_flow_label = factory._decompress_tf(
+            iphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(0, tf)
         self.assertEqual((dscp << 2) | ecn, actual_traffic_class)
         self.assertEqual(flow_label, actual_flow_label)
 
-    def test_should_parse_traffic_class_and_flow_label_when_decompress_tf_method_called_with_iphc_tf_eq_1(self):
+    def test_should_parse_traffic_class_and_flow_label_when_decompress_tf_method_called_with_iphc_tf_eq_1(
+        self):
         # GIVEN
         ecn = any_ecn()
         flow_label = any_flow_label()
@@ -1339,14 +2537,16 @@
                                  any_sam(), any_m(), any_dac(), any_dam())
 
         # WHEN
-        actual_traffic_class, actual_flow_label = factory._decompress_tf(iphc, io.BytesIO(data_bytes))
+        actual_traffic_class, actual_flow_label = factory._decompress_tf(
+            iphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(1, tf)
         self.assertEqual(ecn, actual_traffic_class)
         self.assertEqual(flow_label, actual_flow_label)
 
-    def test_should_parse_traffic_class_and_flow_label_when_decompress_tf_method_called_with_iphc_tf_eq_2(self):
+    def test_should_parse_traffic_class_and_flow_label_when_decompress_tf_method_called_with_iphc_tf_eq_2(
+        self):
         # GIVEN
         ecn = any_ecn()
         dscp = any_dscp()
@@ -1360,14 +2560,16 @@
                                  any_sam(), any_m(), any_dac(), any_dam())
 
         # WHEN
-        actual_traffic_class, actual_flow_label = factory._decompress_tf(iphc, io.BytesIO(data_bytes))
+        actual_traffic_class, actual_flow_label = factory._decompress_tf(
+            iphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(2, tf)
         self.assertEqual((dscp << 2) | ecn, actual_traffic_class)
         self.assertEqual(0, actual_flow_label)
 
-    def test_should_parse_traffic_class_and_flow_label_when_decompress_tf_method_called_with_iphc_tf_eq_3(self):
+    def test_should_parse_traffic_class_and_flow_label_when_decompress_tf_method_called_with_iphc_tf_eq_3(
+        self):
         data_bytes = bytearray()
 
         factory = lowpan.LowpanIpv6HeaderFactory()
@@ -1377,14 +2579,16 @@
                                  any_sam(), any_m(), any_dac(), any_dam())
 
         # WHEN
-        actual_traffic_class, actual_flow_label = factory._decompress_tf(iphc, io.BytesIO(data_bytes))
+        actual_traffic_class, actual_flow_label = factory._decompress_tf(
+            iphc, io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(3, tf)
         self.assertEqual(0, actual_traffic_class)
         self.assertEqual(0, actual_flow_label)
 
-    def test_should_parse_traffic_class_and_flow_label_when_decompress_nh_method_called_with_iphc_nh_eq_0(self):
+    def test_should_parse_traffic_class_and_flow_label_when_decompress_nh_method_called_with_iphc_nh_eq_0(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1397,13 +2601,15 @@
         data_bytes = bytearray([next_header])
 
         # WHEN
-        actual_next_header = factory._decompress_nh(iphc, io.BytesIO(data_bytes))
+        actual_next_header = factory._decompress_nh(iphc,
+                                                    io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(0, nh)
         self.assertEqual(next_header, actual_next_header)
 
-    def test_should_parse_traffic_class_and_flow_label_when_decompress_nh_method_called_with_iphc_nh_eq_1(self):
+    def test_should_parse_traffic_class_and_flow_label_when_decompress_nh_method_called_with_iphc_nh_eq_1(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1414,13 +2620,15 @@
         data_bytes = bytearray()
 
         # WHEN
-        actual_next_header = factory._decompress_nh(iphc, io.BytesIO(data_bytes))
+        actual_next_header = factory._decompress_nh(iphc,
+                                                    io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(1, nh)
         self.assertEqual(None, actual_next_header)
 
-    def test_should_parse_hop_limit_when_decompress_hlim_called_with_iphc_hlim_eq_0(self):
+    def test_should_parse_hop_limit_when_decompress_hlim_called_with_iphc_hlim_eq_0(
+        self):
         # GIVEN
         hop_limit = any_hop_limit()
 
@@ -1433,13 +2641,15 @@
         data_bytes = bytearray([hop_limit])
 
         # WHEN
-        actual_hop_limit = factory._decompress_hlim(iphc, io.BytesIO(data_bytes))
+        actual_hop_limit = factory._decompress_hlim(iphc,
+                                                    io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(0, hlim)
         self.assertEqual(hop_limit, actual_hop_limit)
 
-    def test_should_parse_hop_limit_when_decompress_hlim_called_with_iphc_hlim_eq_1(self):
+    def test_should_parse_hop_limit_when_decompress_hlim_called_with_iphc_hlim_eq_1(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1450,13 +2660,15 @@
         data_bytes = bytearray()
 
         # WHEN
-        actual_hop_limit = factory._decompress_hlim(iphc, io.BytesIO(data_bytes))
+        actual_hop_limit = factory._decompress_hlim(iphc,
+                                                    io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(1, hlim)
         self.assertEqual(1, actual_hop_limit)
 
-    def test_should_parse_hop_limit_when_decompress_hlim_called_with_iphc_hlim_eq_2(self):
+    def test_should_parse_hop_limit_when_decompress_hlim_called_with_iphc_hlim_eq_2(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1467,13 +2679,15 @@
         data_bytes = bytearray()
 
         # WHEN
-        actual_hop_limit = factory._decompress_hlim(iphc, io.BytesIO(data_bytes))
+        actual_hop_limit = factory._decompress_hlim(iphc,
+                                                    io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(2, hlim)
         self.assertEqual(64, actual_hop_limit)
 
-    def test_should_parse_hop_limit_when_decompress_hlim_called_with_iphc_hlim_eq_3(self):
+    def test_should_parse_hop_limit_when_decompress_hlim_called_with_iphc_hlim_eq_3(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1484,13 +2698,15 @@
         data_bytes = bytearray()
 
         # WHEN
-        actual_hop_limit = factory._decompress_hlim(iphc, io.BytesIO(data_bytes))
+        actual_hop_limit = factory._decompress_hlim(iphc,
+                                                    io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(3, hlim)
         self.assertEqual(255, actual_hop_limit)
 
-    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_0_and_sam_eq_0(self):
+    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_0_and_sam_eq_0(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1503,14 +2719,17 @@
                                  sam, any_m(), any_dac(), any_dam())
 
         # WHEN
-        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(), any_sci(), io.BytesIO(src_addr))
+        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(),
+                                                       any_sci(),
+                                                       io.BytesIO(src_addr))
 
         # THEN
         self.assertEqual(0, sac)
         self.assertEqual(0, sam)
         self.assertEqual(bytes(src_addr), actual_src_addr)
 
-    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_0_and_sam_eq_1(self):
+    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_0_and_sam_eq_1(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1523,14 +2742,17 @@
                                  sam, any_m(), any_dac(), any_dam())
 
         # WHEN
-        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(), any_sci(), io.BytesIO(eui64))
+        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(),
+                                                       any_sci(),
+                                                       io.BytesIO(eui64))
 
         # THEN
         self.assertEqual(0, sac)
         self.assertEqual(1, sam)
         self.assertEqual(self.IPV6_LINKLOCAL_PREFIX + eui64, actual_src_addr)
 
-    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_0_and_sam_eq_2(self):
+    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_0_and_sam_eq_2(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1543,19 +2765,20 @@
                                  sam, any_m(), any_dac(), any_dam())
 
         # WHEN
-        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(), any_sci(), io.BytesIO(rloc16))
+        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(),
+                                                       any_sci(),
+                                                       io.BytesIO(rloc16))
 
         # THEN
         self.assertEqual(0, sac)
         self.assertEqual(2, sam)
         self.assertEqual(
-            self.IPV6_LINKLOCAL_PREFIX
-            + bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00])
-            + rloc16,
-            actual_src_addr
-        )
+            self.IPV6_LINKLOCAL_PREFIX +
+            bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00]) + rloc16,
+            actual_src_addr)
 
-    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_0_and_sam_eq_3(self):
+    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_0_and_sam_eq_3(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1570,17 +2793,17 @@
         data_bytes = bytearray([])
 
         # WHEN
-        actual_src_addr = factory._decompress_src_addr(iphc, src_mac_addr, any_sci(), io.BytesIO(data_bytes))
+        actual_src_addr = factory._decompress_src_addr(iphc, src_mac_addr,
+                                                       any_sci(),
+                                                       io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(0, sac)
         self.assertEqual(3, sam)
         self.assertEqual(
-            self.IPV6_LINKLOCAL_PREFIX
-            + bytearray([src_mac_addr.mac_address[0] ^ 0x02])
-            + src_mac_addr.mac_address[1:],
-            actual_src_addr
-        )
+            self.IPV6_LINKLOCAL_PREFIX +
+            bytearray([src_mac_addr.mac_address[0] ^ 0x02]) +
+            src_mac_addr.mac_address[1:], actual_src_addr)
 
     def _merge_prefix_and_address(self, prefix, prefix_length, address):
         total_bytes = 16
@@ -1596,9 +2819,11 @@
             total_bytes -= prefix_length_in_bytes
             total_bytes -= len(address)
 
-            return prefix[:prefix_length_in_bytes] + bytearray([0x00] * total_bytes) + address
+            return prefix[:prefix_length_in_bytes] + bytearray(
+                [0x00] * total_bytes) + address
 
-    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_1_and_sam_eq_0(self):
+    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_1_and_sam_eq_0(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory(None)
 
@@ -1611,14 +2836,17 @@
                                  sam, any_m(), any_dac(), any_dam())
 
         # WHEN
-        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(), any_sci(), io.BytesIO(src_addr))
+        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(),
+                                                       any_sci(),
+                                                       io.BytesIO(src_addr))
 
         # THEN
         self.assertEqual(1, sac)
         self.assertEqual(0, sam)
         self.assertEqual(bytearray([0x00] * 16), actual_src_addr)
 
-    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_1_and_sam_eq_1(self):
+    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_1_and_sam_eq_1(
+        self):
         # GIVEN
         sci = any_sci()
 
@@ -1637,17 +2865,20 @@
         iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), sac,
                                  sam, any_m(), any_dac(), any_dam())
 
-        src_addr = self._merge_prefix_and_address(context.prefix, context.prefix_length, eui64)
+        src_addr = self._merge_prefix_and_address(context.prefix,
+                                                  context.prefix_length, eui64)
 
         # WHEN
-        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(), sci, io.BytesIO(eui64))
+        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(),
+                                                       sci, io.BytesIO(eui64))
 
         # THEN
         self.assertEqual(1, sac)
         self.assertEqual(1, sam)
         self.assertEqual(src_addr, actual_src_addr)
 
-    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_1_and_sam_eq_2(self):
+    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_1_and_sam_eq_2(
+        self):
         # GIVEN
         sci = any_sci()
 
@@ -1668,17 +2899,20 @@
 
         iid = bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00]) + rloc16
 
-        src_addr = self._merge_prefix_and_address(context.prefix, context.prefix_length, iid)
+        src_addr = self._merge_prefix_and_address(context.prefix,
+                                                  context.prefix_length, iid)
 
         # WHEN
-        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(), sci, io.BytesIO(rloc16))
+        actual_src_addr = factory._decompress_src_addr(iphc, any_src_mac_addr(),
+                                                       sci, io.BytesIO(rloc16))
 
         # THEN
         self.assertEqual(1, sac)
         self.assertEqual(2, sam)
         self.assertEqual(src_addr, actual_src_addr)
 
-    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_1_and_sam_eq_3(self):
+    def test_should_parse_source_address_when_decompress_src_addr_called_with_sac_eq_1_and_sam_eq_3(
+        self):
         # GIVEN
         sci = any_sci()
 
@@ -1697,21 +2931,25 @@
         iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), sac,
                                  sam, any_m(), any_dac(), any_dam())
 
-        iid = bytearray([src_mac_addr.mac_address[0] ^ 0x02]) + src_mac_addr.mac_address[1:]
+        iid = bytearray([src_mac_addr.mac_address[0] ^ 0x02
+                        ]) + src_mac_addr.mac_address[1:]
 
-        src_addr = self._merge_prefix_and_address(context.prefix, context.prefix_length, iid)
+        src_addr = self._merge_prefix_and_address(context.prefix,
+                                                  context.prefix_length, iid)
 
         data_bytes = bytearray([])
 
         # WHEN
-        actual_src_addr = factory._decompress_src_addr(iphc, src_mac_addr, sci, io.BytesIO(data_bytes))
+        actual_src_addr = factory._decompress_src_addr(iphc, src_mac_addr, sci,
+                                                       io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(1, sac)
         self.assertEqual(3, sam)
         self.assertEqual(src_addr, actual_src_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_0_and_dam_eq_0(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_0_and_dam_eq_0(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1721,13 +2959,15 @@
         dac = factory.IPHC_DAC_STATELESS
         dam = factory.IPHC_DAM_128B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         dst_mac_addr = bytearray([0x00] * 8)
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, dst_mac_addr, any_dci(), io.BytesIO(ipv6_addr))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, dst_mac_addr,
+                                                       any_dci(),
+                                                       io.BytesIO(ipv6_addr))
 
         # THEN
         self.assertEqual(0, m)
@@ -1735,7 +2975,8 @@
         self.assertEqual(0, dam)
         self.assertEqual(ipv6_addr, actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_0_and_dam_eq_1(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_0_and_dam_eq_1(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1745,11 +2986,13 @@
         dac = factory.IPHC_DAC_STATELESS
         dam = factory.IPHC_DAM_64B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), any_dci(), io.BytesIO(eui64))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       any_dci(),
+                                                       io.BytesIO(eui64))
 
         # THEN
         self.assertEqual(0, m)
@@ -1757,7 +3000,8 @@
         self.assertEqual(1, dam)
         self.assertEqual(self.IPV6_LINKLOCAL_PREFIX + eui64, actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_0_and_dam_eq_2(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_0_and_dam_eq_2(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1767,24 +3011,25 @@
         dac = factory.IPHC_DAC_STATELESS
         dam = factory.IPHC_DAM_16B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), any_dci(), io.BytesIO(rloc16))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       any_dci(),
+                                                       io.BytesIO(rloc16))
 
         # THEN
         self.assertEqual(0, m)
         self.assertEqual(0, dac)
         self.assertEqual(2, dam)
         self.assertEqual(
-            self.IPV6_LINKLOCAL_PREFIX
-            + bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00])
-            + rloc16,
-            actual_dst_addr
-        )
+            self.IPV6_LINKLOCAL_PREFIX +
+            bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00]) + rloc16,
+            actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_0_and_dam_eq_3(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_0_and_dam_eq_3(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1794,26 +3039,27 @@
         dac = factory.IPHC_DAC_STATELESS
         dam = factory.IPHC_DAM_ELIDED
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         data_bytes = bytearray([])
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, dst_mac_addr, any_dci(), io.BytesIO(data_bytes))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, dst_mac_addr,
+                                                       any_dci(),
+                                                       io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(0, m)
         self.assertEqual(0, dac)
         self.assertEqual(3, dam)
         self.assertEqual(
-            self.IPV6_LINKLOCAL_PREFIX
-            + bytearray([dst_mac_addr.mac_address[0] ^ 0x02])
-            + dst_mac_addr.mac_address[1:],
-            actual_dst_addr
-        )
+            self.IPV6_LINKLOCAL_PREFIX +
+            bytearray([dst_mac_addr.mac_address[0] ^ 0x02]) +
+            dst_mac_addr.mac_address[1:], actual_dst_addr)
 
-    def test_should_raise_RuntimeError_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_1_and_dam_eq_0(self):
+    def test_should_raise_RuntimeError_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_1_and_dam_eq_0(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1823,14 +3069,15 @@
         dac = factory.IPHC_DAC_STATEFUL
         dam = factory.IPHC_DAM_128B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         # WHEN
         self.assertRaises(RuntimeError, factory._decompress_dst_addr, iphc,
                           any_dst_mac_addr(), any_dci(), io.BytesIO(ipv6_addr))
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_1_and_dam_eq_1(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_1_and_dam_eq_1(
+        self):
         # GIVEN
         dci = any_dci()
 
@@ -1847,13 +3094,15 @@
         dac = factory.IPHC_DAC_STATEFUL
         dam = factory.IPHC_DAM_64B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
-        dst_addr = self._merge_prefix_and_address(context.prefix, context.prefix_length, eui64)
+        dst_addr = self._merge_prefix_and_address(context.prefix,
+                                                  context.prefix_length, eui64)
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), dci, io.BytesIO(eui64))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       dci, io.BytesIO(eui64))
 
         # THEN
         self.assertEqual(0, m)
@@ -1861,7 +3110,8 @@
         self.assertEqual(1, dam)
         self.assertEqual(dst_addr, actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_1_and_dam_eq_2(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_1_and_dam_eq_2(
+        self):
         # GIVEN
         dci = any_dci()
 
@@ -1878,15 +3128,17 @@
         dac = factory.IPHC_DAC_STATEFUL
         dam = factory.IPHC_DAM_16B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         iid = bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00]) + rloc16
 
-        dst_addr = self._merge_prefix_and_address(context.prefix, context.prefix_length, iid)
+        dst_addr = self._merge_prefix_and_address(context.prefix,
+                                                  context.prefix_length, iid)
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), dci, io.BytesIO(rloc16))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       dci, io.BytesIO(rloc16))
 
         # THEN
         self.assertEqual(0, m)
@@ -1894,7 +3146,8 @@
         self.assertEqual(2, dam)
         self.assertEqual(dst_addr, actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_1_and_dam_eq_3(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_0_and_dac_eq_1_and_dam_eq_3(
+        self):
         # GIVEN
         dci = any_dci()
 
@@ -1911,17 +3164,20 @@
         dac = factory.IPHC_DAC_STATEFUL
         dam = factory.IPHC_DAM_0B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
-        iid = bytearray([dst_mac_addr.mac_address[0] ^ 0x02]) + dst_mac_addr.mac_address[1:]
+        iid = bytearray([dst_mac_addr.mac_address[0] ^ 0x02
+                        ]) + dst_mac_addr.mac_address[1:]
 
-        dst_addr = self._merge_prefix_and_address(context.prefix, context.prefix_length, iid)
+        dst_addr = self._merge_prefix_and_address(context.prefix,
+                                                  context.prefix_length, iid)
 
         data_bytes = bytearray([])
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, dst_mac_addr, dci, io.BytesIO(data_bytes))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, dst_mac_addr, dci,
+                                                       io.BytesIO(data_bytes))
 
         # THEN
         self.assertEqual(0, m)
@@ -1929,7 +3185,8 @@
         self.assertEqual(3, dam)
         self.assertEqual(dst_addr, actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_0_and_dam_eq_0(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_0_and_dam_eq_0(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1939,11 +3196,13 @@
         dac = factory.IPHC_DAC_STATELESS
         dam = factory.IPHC_DAM_128B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), any_dci(), io.BytesIO(ipv6_addr))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       any_dci(),
+                                                       io.BytesIO(ipv6_addr))
 
         # THEN
         self.assertEqual(1, m)
@@ -1951,7 +3210,8 @@
         self.assertEqual(0, dam)
         self.assertEqual(ipv6_addr, actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_0_and_dam_eq_1(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_0_and_dam_eq_1(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1961,14 +3221,18 @@
         dac = factory.IPHC_DAC_STATELESS
         dam = factory.IPHC_DAM_48B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
-        expected_dst_addr = bytearray([0xff, addr48b[0], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, addr48b[1], addr48b[2], addr48b[3], addr48b[4], addr48b[5]])
+        expected_dst_addr = bytearray([
+            0xff, addr48b[0], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, addr48b[1], addr48b[2], addr48b[3], addr48b[4], addr48b[5]
+        ])
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), any_dci(), io.BytesIO(addr48b))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       any_dci(),
+                                                       io.BytesIO(addr48b))
 
         # THEN
         self.assertEqual(1, m)
@@ -1976,7 +3240,8 @@
         self.assertEqual(1, dam)
         self.assertEqual(expected_dst_addr, actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_0_and_dam_eq_2(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_0_and_dam_eq_2(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -1986,14 +3251,18 @@
         dac = factory.IPHC_DAC_STATELESS
         dam = factory.IPHC_DAM_32B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
-        expected_dst_addr = bytearray([0xff, addr32b[0], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00, 0x00, addr32b[1], addr32b[2], addr32b[3]])
+        expected_dst_addr = bytearray([
+            0xff, addr32b[0], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, addr32b[1], addr32b[2], addr32b[3]
+        ])
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), any_dci(), io.BytesIO(addr32b))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       any_dci(),
+                                                       io.BytesIO(addr32b))
 
         # THEN
         self.assertEqual(1, m)
@@ -2001,7 +3270,8 @@
         self.assertEqual(2, dam)
         self.assertEqual(expected_dst_addr, actual_dst_addr)
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_0_and_dam_eq_3(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_0_and_dam_eq_3(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -2011,14 +3281,18 @@
         dac = factory.IPHC_DAC_STATELESS
         dam = factory.IPHC_DAM_8B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
-        expected_dst_addr = bytearray([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, addr8b[0]])
+        expected_dst_addr = bytearray([
+            0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, addr8b[0]
+        ])
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), any_dci(), io.BytesIO(addr8b))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       any_dci(),
+                                                       io.BytesIO(addr8b))
 
         # THEN
         self.assertEqual(1, m)
@@ -2026,7 +3300,8 @@
         self.assertEqual(3, dam)
         self.assertEqual(expected_dst_addr, actual_dst_addr)
 
-    def test_should_raise_RuntimeError_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_1_and_dam_eq_0(self):
+    def test_should_raise_RuntimeError_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_1_and_dam_eq_0(
+        self):
         # GIVEN
         dci = any_dci()
 
@@ -2043,8 +3318,8 @@
         dac = factory.IPHC_DAC_STATEFUL
         dam = factory.IPHC_DAM_128B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         prefix = context.prefix[:8]
 
@@ -2054,10 +3329,12 @@
 
         prefix_length = context.prefix_length
 
-        dst_addr = bytearray([0xff]) + addr48b[:2] + bytearray([prefix_length]) + prefix + addr48b[2:]
+        dst_addr = bytearray([0xff]) + addr48b[:2] + bytearray(
+            [prefix_length]) + prefix + addr48b[2:]
 
         # WHEN
-        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(), dci, io.BytesIO(addr48b))
+        actual_dst_addr = factory._decompress_dst_addr(iphc, any_dst_mac_addr(),
+                                                       dci, io.BytesIO(addr48b))
 
         # THEN
         self.assertEqual(1, m)
@@ -2065,7 +3342,8 @@
         self.assertEqual(0, dam)
         self.assertEqual(dst_addr, actual_dst_addr)
 
-    def test_should_raise_RuntimeError_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_1_and_dam_eq_1(self):
+    def test_should_raise_RuntimeError_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_1_and_dam_eq_1(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -2075,14 +3353,15 @@
         dac = factory.IPHC_DAC_STATEFUL
         dam = factory.IPHC_DAM_48B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         # WHEN
         self.assertRaises(RuntimeError, factory._decompress_dst_addr, iphc,
                           any_dst_mac_addr(), any_dci(), io.BytesIO(addr48b))
 
-    def test_should_raise_RuntimeError_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_1_and_dam_eq_2(self):
+    def test_should_raise_RuntimeError_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_1_and_dam_eq_2(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -2092,14 +3371,15 @@
         dac = factory.IPHC_DAC_STATEFUL
         dam = factory.IPHC_DAM_32B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         # WHEN
         self.assertRaises(RuntimeError, factory._decompress_dst_addr, iphc,
                           any_dst_mac_addr(), any_dci(), io.BytesIO(addr32b))
 
-    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_1_and_dam_eq_3(self):
+    def test_should_parse_dst_addr_when_decompress_dst_addr_called_with_m_eq_1_and_dac_eq_1_and_dam_eq_3(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
@@ -2109,61 +3389,73 @@
         dac = factory.IPHC_DAC_STATEFUL
         dam = factory.IPHC_DAM_8B
 
-        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(), any_sac(),
-                                 any_sam(), m, dac, dam)
+        iphc = lowpan.LowpanIPHC(any_tf(), any_nh(), any_hlim(), any_cid(),
+                                 any_sac(), any_sam(), m, dac, dam)
 
         # WHEN
         self.assertRaises(RuntimeError, factory._decompress_dst_addr, iphc,
                           any_dst_mac_addr(), any_dci(), io.BytesIO(addr8b))
 
-    def test_should_merge_pfx_with_addr_bytes_when_merge_method_called_with_pfx_shorter_than_missing_bits(self):
+    def test_should_merge_pfx_with_addr_bytes_when_merge_method_called_with_pfx_shorter_than_missing_bits(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
         prefix = bytearray([0x20, 0x00, 0x0d, 0xb8])
         prefix_length = 32
 
-        address_bytes = bytearray([0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81])
+        address_bytes = bytearray(
+            [0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81])
 
         addr = prefix + bytearray([0x00] * 4) + address_bytes
 
         # WHEN
-        actual_addr = factory._merge_prefix_with_address(prefix, prefix_length, address_bytes)
+        actual_addr = factory._merge_prefix_with_address(
+            prefix, prefix_length, address_bytes)
 
         # THEN
         self.assertEqual(addr, actual_addr)
 
-    def test_should_merge_pfx_with_addr_bytes_when_merge_method_called_with_pfx_longer_than_missing_bits_overlap(self):
+    def test_should_merge_pfx_with_addr_bytes_when_merge_method_called_with_pfx_longer_than_missing_bits_overlap(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
-        prefix = bytearray([0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x22])
+        prefix = bytearray(
+            [0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x22])
         prefix_length = 68
 
-        address_bytes = bytearray([0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81])
+        address_bytes = bytearray(
+            [0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81])
 
         addr = prefix[:-1] + bytearray([0x2a]) + address_bytes[1:]
 
         # WHEN
-        actual_addr = factory._merge_prefix_with_address(prefix, prefix_length, address_bytes)
+        actual_addr = factory._merge_prefix_with_address(
+            prefix, prefix_length, address_bytes)
 
         # THEN
         self.assertEqual(addr, actual_addr)
 
-    def test_should_merge_pfx_with_address_bytes_when_merge_method_called_with_pfx_longer_than_missing_bits(self):
+    def test_should_merge_pfx_with_address_bytes_when_merge_method_called_with_pfx_longer_than_missing_bits(
+        self):
         # GIVEN
         factory = lowpan.LowpanIpv6HeaderFactory()
 
-        prefix = bytearray([0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-                            0x22, 0x00, 0x00, 0x11, 0x01, 0x11, 0x01, 0x22])
+        prefix = bytearray([
+            0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
+            0x11, 0x01, 0x11, 0x01, 0x22
+        ])
         prefix_length = 128
 
-        address_bytes = bytearray([0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81])
+        address_bytes = bytearray(
+            [0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81])
 
         addr = prefix
 
         # WHEN
-        actual_addr = factory._merge_prefix_with_address(prefix, prefix_length, address_bytes)
+        actual_addr = factory._merge_prefix_with_address(
+            prefix, prefix_length, address_bytes)
 
         # THEN
         self.assertEqual(addr, actual_addr)
@@ -2171,7 +3463,8 @@
 
 class TestContext(unittest.TestCase):
 
-    def test_should_extract_context_from_str_representation_when_constructor_called(self):
+    def test_should_extract_context_from_str_representation_when_constructor_called(
+        self):
         # GIVEN
         prefix = "2000:db8::/64"
 
@@ -2179,7 +3472,9 @@
         c = lowpan.Context(prefix)
 
         # THEN
-        self.assertEqual(bytearray([0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00]), c.prefix)
+        self.assertEqual(
+            bytearray([0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00]),
+            c.prefix)
         self.assertEqual(64, c.prefix_length)
         self.assertEqual(8, c.prefix_length_full_bytes)
 
@@ -2191,7 +3486,9 @@
         c = lowpan.Context(prefix)
 
         # THEN
-        self.assertEqual(bytearray([0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00]), c.prefix)
+        self.assertEqual(
+            bytearray([0x20, 0x00, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00]),
+            c.prefix)
         self.assertEqual(8, c.prefix_length_full_bytes)
         self.assertEqual(64, c.prefix_length)
 
@@ -2233,7 +3530,8 @@
         # GIVEN
         hops_left = any_hops_left()
 
-        mesh_header = lowpan.LowpanMeshHeader(hops_left, any_mac_address(), any_mac_address())
+        mesh_header = lowpan.LowpanMeshHeader(hops_left, any_mac_address(),
+                                              any_mac_address())
 
         # WHEN
         actual_hops_left = mesh_header.hops_left
@@ -2241,11 +3539,14 @@
         # THEN
         self.assertEqual(hops_left, actual_hops_left)
 
-    def test_should_return_originator_address_value_when_originator_address_property_called(self):
+    def test_should_return_originator_address_value_when_originator_address_property_called(
+        self):
         # GIVEN
         originator_address = any_mac_address()
 
-        mesh_header = lowpan.LowpanMeshHeader(any_hops_left(), originator_address, any_mac_address())
+        mesh_header = lowpan.LowpanMeshHeader(any_hops_left(),
+                                              originator_address,
+                                              any_mac_address())
 
         # WHEN
         actual_originator_address = mesh_header.originator_address
@@ -2253,17 +3554,21 @@
         # THEN
         self.assertEqual(originator_address, actual_originator_address)
 
-    def test_should_return_final_destination_address_value_when_final_destination_address_property_called(self):
+    def test_should_return_final_destination_address_value_when_final_destination_address_property_called(
+        self):
         # GIVEN
         final_destination_address = any_mac_address()
 
-        mesh_header = lowpan.LowpanMeshHeader(any_hops_left(), any_mac_address(), final_destination_address)
+        mesh_header = lowpan.LowpanMeshHeader(any_hops_left(),
+                                              any_mac_address(),
+                                              final_destination_address)
 
         # WHEN
         actual_final_destination_address = mesh_header.final_destination_address
 
         # THEN
-        self.assertEqual(final_destination_address, actual_final_destination_address)
+        self.assertEqual(final_destination_address,
+                         actual_final_destination_address)
 
 
 class TestLowpanMeshHeaderFactory(unittest.TestCase):
@@ -2281,7 +3586,8 @@
         mesh_header_first_byte = (2 << 6) | (v << 5) | (f << 4)
 
         if hops_left >= 0x0f:
-            mesh_header_data = bytearray([mesh_header_first_byte | 0x0f, hops_left])
+            mesh_header_data = bytearray(
+                [mesh_header_first_byte | 0x0f, hops_left])
         else:
             mesh_header_data = bytearray([mesh_header_first_byte | hops_left])
 
@@ -2290,17 +3596,20 @@
         mesh_header_factory = lowpan.LowpanMeshHeaderFactory()
 
         # WHEN
-        mesh_header = mesh_header_factory.parse(io.BytesIO(mesh_header_data), None)
+        mesh_header = mesh_header_factory.parse(io.BytesIO(mesh_header_data),
+                                                None)
 
         # THEN
         self.assertEqual(hops_left, mesh_header.hops_left)
         self.assertEqual(originator_address, mesh_header.originator_address)
-        self.assertEqual(final_destination_address, mesh_header.final_destination_address)
+        self.assertEqual(final_destination_address,
+                         mesh_header.final_destination_address)
 
 
 class TestLowpanFragmentationHeader(unittest.TestCase):
 
-    def test_should_return_datagram_size_value_when_datagram_size_property_called(self):
+    def test_should_return_datagram_size_value_when_datagram_size_property_called(
+        self):
         # GIVEN
         datagram_size = any_datagram_size()
 
@@ -2313,7 +3622,8 @@
         # THEN
         self.assertEqual(datagram_size, actual_datagram_size)
 
-    def test_should_return_datagram_tag_value_when_datagram_tag_property_called(self):
+    def test_should_return_datagram_tag_value_when_datagram_tag_property_called(
+        self):
         # GIVEN
         datagram_tag = any_datagram_tag()
 
@@ -2326,7 +3636,8 @@
         # THEN
         self.assertEqual(datagram_tag, actual_datagram_tag)
 
-    def test_should_return_datagram_offset_value_when_datagram_offset_property_called(self):
+    def test_should_return_datagram_offset_value_when_datagram_offset_property_called(
+        self):
         # GIVEN
         datagram_offset = any_datagram_offset()
 
@@ -2339,7 +3650,8 @@
         # THEN
         self.assertEqual(datagram_offset, actual_datagram_offset)
 
-    def test_should_return_False_when_is_first_property_called_and_datagram_offset_is_not_eq_0(self):
+    def test_should_return_False_when_is_first_property_called_and_datagram_offset_is_not_eq_0(
+        self):
         # GIVEN
         datagram_offset = random.randint(1, (1 << 8) - 1)
 
@@ -2352,17 +3664,21 @@
         # THEN
         self.assertFalse(is_first)
 
-    def test_should_to_bytes_LowpanFragmentationHeader_from_bytes_when_from_bytes_class_method_called(self):
+    def test_should_to_bytes_LowpanFragmentationHeader_from_bytes_when_from_bytes_class_method_called(
+        self):
         # GIVEN
         datagram_size = any_datagram_size()
         datagram_tag = any_datagram_tag()
         datagram_offset = any_datagram_offset()
 
-        data = struct.pack(">HHB", ((3 << 14) | (int(datagram_offset != 0) << 13) | datagram_size),
+        data = struct.pack(">HHB",
+                           ((3 << 14) |
+                            (int(datagram_offset != 0) << 13) | datagram_size),
                            datagram_tag, datagram_offset)
 
         # WHEN
-        fragmentation_header = lowpan.LowpanFragmentationHeader.from_bytes(io.BytesIO(data))
+        fragmentation_header = lowpan.LowpanFragmentationHeader.from_bytes(
+            io.BytesIO(data))
 
         # THEN
         self.assertEqual(datagram_size, fragmentation_header.datagram_size)
@@ -2374,24 +3690,28 @@
 
     def test_should_parse_parent_request_when_decompress_method_called(self):
         # GIVEN
-        data = bytearray([0x7f, 0x3b, 0x02, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c,
-                          0x5e, 0xaf, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00,
-                          0x00, 0x00, 0x00, 0x00, 0x01, 0x3b, 0xfb, 0x0e,
-                          0x3b, 0x15, 0xa1, 0xf9, 0xf5, 0x64, 0xf4, 0x99,
-                          0xef, 0x70, 0x78, 0x6c, 0x3c, 0x0f, 0x54, 0x4e,
-                          0x95, 0xe8, 0xf5, 0x27, 0x4c, 0xfc])
+        data = bytearray([
+            0x7f, 0x3b, 0x02, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c, 0x5e, 0xaf, 0x00,
+            0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3b,
+            0xfb, 0x0e, 0x3b, 0x15, 0xa1, 0xf9, 0xf5, 0x64, 0xf4, 0x99, 0xef,
+            0x70, 0x78, 0x6c, 0x3c, 0x0f, 0x54, 0x4e, 0x95, 0xe8, 0xf5, 0x27,
+            0x4c, 0xfc
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
             bytearray([0x12, 0xcf, 0xd3, 0x8b, 0x3b, 0x61, 0x55, 0x58]))
 
-        decompressor = config.create_default_lowpan_decompressor(context_manager=None)
+        decompressor = config.create_default_lowpan_decompressor(
+            context_manager=None)
 
         # WHEN
-        ipv6_header, extension_headers, udp_header = decompressor.decompress(io.BytesIO(data), message_info)
+        ipv6_header, extension_headers, udp_header = decompressor.decompress(
+            io.BytesIO(data), message_info)
 
         # THEN
-        self.assertEqual("fe80::10cf:d38b:3b61:5558", ipv6_header.source_address.compressed)
+        self.assertEqual("fe80::10cf:d38b:3b61:5558",
+                         ipv6_header.source_address.compressed)
         self.assertEqual("ff02::2", ipv6_header.destination_address.compressed)
         self.assertEqual(17, ipv6_header.next_header)
         self.assertEqual(255, ipv6_header.hop_limit)
@@ -2400,18 +3720,17 @@
 
     def test_should_parse_parent_response_when_decompress_method_called(self):
         # GIVEN
-        data = bytearray([0x7f, 0x33, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c, 0x0f,
-                          0xe8, 0x00, 0x15, 0x04, 0x00, 0x00, 0x00, 0x00,
-                          0x00, 0x00, 0x00, 0x01, 0x31, 0xb8, 0x16, 0x02,
-                          0x61, 0xcc, 0x98, 0x90, 0xd6, 0xfd, 0x69, 0xd3,
-                          0x89, 0xa0, 0x30, 0x49, 0x83, 0x7c, 0xf7, 0xb5,
-                          0x7f, 0x83, 0x2a, 0x04, 0xf6, 0x3b, 0x8c, 0xe8,
-                          0xb6, 0x37, 0x51, 0x5b, 0x28, 0x9a, 0x3b, 0xbe,
-                          0x0d, 0xb3, 0x4e, 0x9f, 0xd8, 0x14, 0xc8, 0xc9,
-                          0xf4, 0x28, 0xf6, 0x8d, 0xb7, 0xf0, 0x7d, 0x46,
-                          0x13, 0xc2, 0xb1, 0x69, 0x4d, 0xae, 0xc1, 0x23,
-                          0x16, 0x62, 0x90, 0xea, 0xff, 0x1b, 0xb7, 0xd7,
-                          0x1e, 0x5c])
+        data = bytearray([
+            0x7f, 0x33, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c, 0x0f, 0xe8, 0x00, 0x15,
+            0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31, 0xb8,
+            0x16, 0x02, 0x61, 0xcc, 0x98, 0x90, 0xd6, 0xfd, 0x69, 0xd3, 0x89,
+            0xa0, 0x30, 0x49, 0x83, 0x7c, 0xf7, 0xb5, 0x7f, 0x83, 0x2a, 0x04,
+            0xf6, 0x3b, 0x8c, 0xe8, 0xb6, 0x37, 0x51, 0x5b, 0x28, 0x9a, 0x3b,
+            0xbe, 0x0d, 0xb3, 0x4e, 0x9f, 0xd8, 0x14, 0xc8, 0xc9, 0xf4, 0x28,
+            0xf6, 0x8d, 0xb7, 0xf0, 0x7d, 0x46, 0x13, 0xc2, 0xb1, 0x69, 0x4d,
+            0xae, 0xc1, 0x23, 0x16, 0x62, 0x90, 0xea, 0xff, 0x1b, 0xb7, 0xd7,
+            0x1e, 0x5c
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -2419,14 +3738,18 @@
         message_info.destination_mac_address = common.MacAddress.from_eui64(
             bytearray([0x12, 0xcf, 0xd3, 0x8b, 0x3b, 0x61, 0x55, 0x58]))
 
-        decompressor = config.create_default_lowpan_decompressor(context_manager=None)
+        decompressor = config.create_default_lowpan_decompressor(
+            context_manager=None)
 
         # WHEN
-        ipv6_header, extension_headers, udp_header = decompressor.decompress(io.BytesIO(data), message_info)
+        ipv6_header, extension_headers, udp_header = decompressor.decompress(
+            io.BytesIO(data), message_info)
 
         # THEN
-        self.assertEqual("fe80::383e:9eed:7a01:36a5", ipv6_header.source_address.compressed)
-        self.assertEqual("fe80::10cf:d38b:3b61:5558", ipv6_header.destination_address.compressed)
+        self.assertEqual("fe80::383e:9eed:7a01:36a5",
+                         ipv6_header.source_address.compressed)
+        self.assertEqual("fe80::10cf:d38b:3b61:5558",
+                         ipv6_header.destination_address.compressed)
         self.assertEqual(17, ipv6_header.next_header)
         self.assertEqual(255, ipv6_header.hop_limit)
 
@@ -2437,16 +3760,15 @@
 
     def test_should_parse_child_id_request_when_decompress_method_called(self):
         # GIVEN
-        data = bytearray([0x7f, 0x33, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c, 0x9a,
-                          0x62, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00,
-                          0x00, 0x00, 0x00, 0x01, 0x14, 0x03, 0xe3, 0x72,
-                          0x50, 0x4f, 0x8c, 0x5c, 0x42, 0x81, 0x68, 0xe2,
-                          0x11, 0xfc, 0xf5, 0x8c, 0x62, 0x8e, 0x83, 0x99,
-                          0xe7, 0x26, 0x86, 0x34, 0x3b, 0xa7, 0x68, 0xc7,
-                          0x93, 0xfb, 0x72, 0xd9, 0xcc, 0x13, 0x5e, 0x5b,
-                          0x96, 0x0e, 0xf1, 0x80, 0x03, 0x55, 0x4f, 0x27,
-                          0xc2, 0x96, 0xf4, 0x9c, 0x65, 0x82, 0x97, 0xcf,
-                          0x97, 0x35, 0x89, 0xc2])
+        data = bytearray([
+            0x7f, 0x33, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c, 0x9a, 0x62, 0x00, 0x15,
+            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, 0x03,
+            0xe3, 0x72, 0x50, 0x4f, 0x8c, 0x5c, 0x42, 0x81, 0x68, 0xe2, 0x11,
+            0xfc, 0xf5, 0x8c, 0x62, 0x8e, 0x83, 0x99, 0xe7, 0x26, 0x86, 0x34,
+            0x3b, 0xa7, 0x68, 0xc7, 0x93, 0xfb, 0x72, 0xd9, 0xcc, 0x13, 0x5e,
+            0x5b, 0x96, 0x0e, 0xf1, 0x80, 0x03, 0x55, 0x4f, 0x27, 0xc2, 0x96,
+            0xf4, 0x9c, 0x65, 0x82, 0x97, 0xcf, 0x97, 0x35, 0x89, 0xc2
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -2454,14 +3776,18 @@
         message_info.destination_mac_address = common.MacAddress.from_eui64(
             bytearray([0x3a, 0x3e, 0x9e, 0xed, 0x7a, 0x01, 0x36, 0xa5]))
 
-        decompressor = config.create_default_lowpan_decompressor(context_manager=None)
+        decompressor = config.create_default_lowpan_decompressor(
+            context_manager=None)
 
         # WHEN
-        ipv6_header, extension_headers, udp_header = decompressor.decompress(io.BytesIO(data), message_info)
+        ipv6_header, extension_headers, udp_header = decompressor.decompress(
+            io.BytesIO(data), message_info)
 
         # THEN
-        self.assertEqual("fe80::10cf:d38b:3b61:5558", ipv6_header.source_address.compressed)
-        self.assertEqual("fe80::383e:9eed:7a01:36a5", ipv6_header.destination_address.compressed)
+        self.assertEqual("fe80::10cf:d38b:3b61:5558",
+                         ipv6_header.source_address.compressed)
+        self.assertEqual("fe80::383e:9eed:7a01:36a5",
+                         ipv6_header.destination_address.compressed)
         self.assertEqual(17, ipv6_header.next_header)
         self.assertEqual(255, ipv6_header.hop_limit)
 
@@ -2472,15 +3798,15 @@
 
     def test_should_parse_child_id_response_when_decompress_method_called(self):
         # GIVEN
-        data = bytearray([0x7f, 0x33, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c, 0x7b,
-                          0xe3, 0x00, 0x15, 0x05, 0x00, 0x00, 0x00, 0x00,
-                          0x00, 0x00, 0x00, 0x01, 0xe0, 0x57, 0xbf, 0x2f,
-                          0xc0, 0x4b, 0x1d, 0xac, 0x3c, 0x24, 0x16, 0xdf,
-                          0xeb, 0x96, 0xeb, 0xda, 0x42, 0xeb, 0x00, 0x89,
-                          0x5f, 0x39, 0xc9, 0x2b, 0x7d, 0x31, 0xd5, 0x83,
-                          0x9d, 0xdb, 0xb7, 0xc8, 0xe6, 0x25, 0xd3, 0x7a,
-                          0x1e, 0x5f, 0x66, 0x9e, 0x63, 0x2d, 0x42, 0x27,
-                          0x19, 0x41, 0xdc, 0xc4, 0xc4, 0xc0, 0x8c, 0x07])
+        data = bytearray([
+            0x7f, 0x33, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c, 0x7b, 0xe3, 0x00, 0x15,
+            0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x57,
+            0xbf, 0x2f, 0xc0, 0x4b, 0x1d, 0xac, 0x3c, 0x24, 0x16, 0xdf, 0xeb,
+            0x96, 0xeb, 0xda, 0x42, 0xeb, 0x00, 0x89, 0x5f, 0x39, 0xc9, 0x2b,
+            0x7d, 0x31, 0xd5, 0x83, 0x9d, 0xdb, 0xb7, 0xc8, 0xe6, 0x25, 0xd3,
+            0x7a, 0x1e, 0x5f, 0x66, 0x9e, 0x63, 0x2d, 0x42, 0x27, 0x19, 0x41,
+            0xdc, 0xc4, 0xc4, 0xc0, 0x8c, 0x07
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
@@ -2488,14 +3814,18 @@
         message_info.destination_mac_address = common.MacAddress.from_eui64(
             bytearray([0x12, 0xcf, 0xd3, 0x8b, 0x3b, 0x61, 0x55, 0x58]))
 
-        decompressor = config.create_default_lowpan_decompressor(context_manager=None)
+        decompressor = config.create_default_lowpan_decompressor(
+            context_manager=None)
 
         # WHEN
-        ipv6_header, extension_headers, udp_header = decompressor.decompress(io.BytesIO(data), message_info)
+        ipv6_header, extension_headers, udp_header = decompressor.decompress(
+            io.BytesIO(data), message_info)
 
         # THEN
-        self.assertEqual("fe80::383e:9eed:7a01:36a5", ipv6_header.source_address.compressed)
-        self.assertEqual("fe80::10cf:d38b:3b61:5558", ipv6_header.destination_address.compressed)
+        self.assertEqual("fe80::383e:9eed:7a01:36a5",
+                         ipv6_header.source_address.compressed)
+        self.assertEqual("fe80::10cf:d38b:3b61:5558",
+                         ipv6_header.destination_address.compressed)
         self.assertEqual(17, ipv6_header.next_header)
         self.assertEqual(255, ipv6_header.hop_limit)
 
@@ -2506,25 +3836,28 @@
 
     def test_should_parse_advertisement_when_decompress_method_called(self):
         # GIVEN
-        data = bytearray([0x7f, 0x3b, 0x01, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c,
-                          0x35, 0x9f, 0x00, 0x15, 0x07, 0x00, 0x00, 0x00,
-                          0x00, 0x00, 0x00, 0x00, 0x01, 0x9e, 0xb8, 0xd0,
-                          0x2f, 0x2a, 0xe0, 0x00, 0x5d, 0x66, 0x63, 0x05,
-                          0xa0, 0x59, 0xb0, 0xd4, 0x95, 0x7f, 0xe6, 0x79,
-                          0x17, 0x87, 0x2c, 0x1d, 0x83, 0xad, 0xc2, 0x64,
-                          0x47, 0x20, 0x7a, 0xe2])
+        data = bytearray([
+            0x7f, 0x3b, 0x01, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c, 0x35, 0x9f, 0x00,
+            0x15, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9e,
+            0xb8, 0xd0, 0x2f, 0x2a, 0xe0, 0x00, 0x5d, 0x66, 0x63, 0x05, 0xa0,
+            0x59, 0xb0, 0xd4, 0x95, 0x7f, 0xe6, 0x79, 0x17, 0x87, 0x2c, 0x1d,
+            0x83, 0xad, 0xc2, 0x64, 0x47, 0x20, 0x7a, 0xe2
+        ])
 
         message_info = common.MessageInfo()
         message_info.source_mac_address = common.MacAddress.from_eui64(
             bytearray([0x3a, 0x3e, 0x9e, 0xed, 0x7a, 0x01, 0x36, 0xa5]))
 
-        decompressor = config.create_default_lowpan_decompressor(context_manager=None)
+        decompressor = config.create_default_lowpan_decompressor(
+            context_manager=None)
 
         # WHEN
-        ipv6_header, extension_headers, udp_header = decompressor.decompress(io.BytesIO(data), message_info)
+        ipv6_header, extension_headers, udp_header = decompressor.decompress(
+            io.BytesIO(data), message_info)
 
         # THEN
-        self.assertEqual("fe80::383e:9eed:7a01:36a5", ipv6_header.source_address.compressed)
+        self.assertEqual("fe80::383e:9eed:7a01:36a5",
+                         ipv6_header.source_address.compressed)
         self.assertEqual("ff02::1", ipv6_header.destination_address.compressed)
         self.assertEqual(17, ipv6_header.next_header)
         self.assertEqual(255, ipv6_header.hop_limit)
@@ -2537,16 +3870,19 @@
 
 class TestLowpanFragmentsBuffer(unittest.TestCase):
 
-    def test_should_raise_ValueError_when_write_method_called_with_data_length_bigger_than_buffer_length(self):
+    def test_should_raise_ValueError_when_write_method_called_with_data_length_bigger_than_buffer_length(
+        self):
         # GIVEN
         length = random.randint(1, 1280)
 
-        fragments_buffer = lowpan.LowpanFragmentsBuffer(buffer_size=(length - 1))
+        fragments_buffer = lowpan.LowpanFragmentsBuffer(buffer_size=(length -
+                                                                     1))
 
         # THEN
         self.assertRaises(ValueError, fragments_buffer.write, any_data(length))
 
-    def test_should_move_write_position_by_the_data_length_when_write_method_called(self):
+    def test_should_move_write_position_by_the_data_length_when_write_method_called(
+        self):
         # GIVEN
         length = random.randint(1, 1280)
 
@@ -2562,17 +3898,20 @@
         # THEN
         self.assertEqual(fragments_buffer.tell() - start_position, len(data))
 
-    def test_should_raise_ValueError_when_read_method_called_but_not_whole_packet_has_been_stored_in_buffer(self):
+    def test_should_raise_ValueError_when_read_method_called_but_not_whole_packet_has_been_stored_in_buffer(
+        self):
         # GIVEN
         data = any_data(length=3)
 
-        fragments_buffer = lowpan.LowpanFragmentsBuffer(buffer_size=random.randint(4, 1280))
+        fragments_buffer = lowpan.LowpanFragmentsBuffer(
+            buffer_size=random.randint(4, 1280))
         fragments_buffer.write(data)
 
         # WHEN
         self.assertRaises(ValueError, fragments_buffer.read)
 
-    def test_should_raise_ValueError_when_seek_method_called_with_offset_bigger_than_buffer_length(self):
+    def test_should_raise_ValueError_when_seek_method_called_with_offset_bigger_than_buffer_length(
+        self):
         # GIVEN
         offset = random.randint(1281, 2500)
 
@@ -2606,7 +3945,8 @@
         # THEN
         self.assertEqual(data, fragments_buffer.read())
 
-    def test_should_write_many_frags_to_the_buffer_and_return_whole_message_when_write_method_called_many_times(self):
+    def test_should_write_many_frags_to_the_buffer_and_return_whole_message_when_write_method_called_many_times(
+        self):
         # GIVEN
         buffer_size = 42
         fragments_buffer = lowpan.LowpanFragmentsBuffer(buffer_size=buffer_size)
@@ -2649,18 +3989,20 @@
         fragments_buffer.write(fragment_6)
 
         # THEN
-        self.assertEqual(bytearray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-                                    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-                                    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
-                                    0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
-                                    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
-                                    0x29, 0x2a]),
-                         fragments_buffer.read())
+        self.assertEqual(
+            bytearray([
+                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+                0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+                0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
+                0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+                0x29, 0x2a
+            ]), fragments_buffer.read())
 
 
 class TestLowpanFragmentsBuffersManager(unittest.TestCase):
 
-    def test_should_raise_ValueError_when_get_fragments_buffer_method_called_with_invalid_dgram_size(self):
+    def test_should_raise_ValueError_when_get_fragments_buffer_method_called_with_invalid_dgram_size(
+        self):
         # GIVEN
         message_info = common.MessageInfo()
         message_info.source_mac_address = any_mac_address()
@@ -2671,10 +4013,13 @@
         manager = lowpan.LowpanFragmentsBuffersManager()
 
         # THEN
-        self.assertRaises(ValueError, manager.get_fragments_buffer, message_info, any_datagram_tag(), None)
-        self.assertRaises(ValueError, manager.get_fragments_buffer, message_info, any_datagram_tag(), negative_int)
+        self.assertRaises(ValueError, manager.get_fragments_buffer,
+                          message_info, any_datagram_tag(), None)
+        self.assertRaises(ValueError, manager.get_fragments_buffer,
+                          message_info, any_datagram_tag(), negative_int)
 
-    def test_should_return_LowpanFragmentsBuffer_when_get_fragments_buffer_method_called_with_valid_dgram_size(self):
+    def test_should_return_LowpanFragmentsBuffer_when_get_fragments_buffer_method_called_with_valid_dgram_size(
+        self):
         # GIVEN
         message_info = common.MessageInfo()
         message_info.source_mac_address = any_mac_address()
@@ -2685,7 +4030,9 @@
         manager = lowpan.LowpanFragmentsBuffersManager()
 
         # WHEN
-        fragments_buffer = manager.get_fragments_buffer(message_info, any_datagram_tag(), datagram_size)
+        fragments_buffer = manager.get_fragments_buffer(message_info,
+                                                        any_datagram_tag(),
+                                                        datagram_size)
 
         # THEN
         self.assertIsInstance(fragments_buffer, lowpan.LowpanFragmentsBuffer)
diff --git a/tests/scripts/thread-cert/test_mac802154.py b/tests/scripts/thread-cert/test_mac802154.py
index 449c7ad..bd289c4 100755
--- a/tests/scripts/thread-cert/test_mac802154.py
+++ b/tests/scripts/thread-cert/test_mac802154.py
@@ -45,9 +45,8 @@
         frame = mac802154.MacFrame()
         frame.parse(io.BytesIO(bytearray([0x12, 0x00, 0x12, 0x34, 0x56])))
 
-        self.assertEqual(
-            mac802154.MacHeader.FrameType.ACK,
-            frame.header.frame_type)
+        self.assertEqual(mac802154.MacHeader.FrameType.ACK,
+                         frame.header.frame_type)
         self.assertEqual(True, frame.header.frame_pending)
         self.assertEqual(False, frame.header.ack_request)
         self.assertEqual(0, frame.header.frame_version)
@@ -57,12 +56,15 @@
 
     def test_should_parse_data_frame_with_short_addresses(self):
         frame = mac802154.MacFrame()
-        frame.parse(io.BytesIO(bytearray([0x61, 0x88, 0x34, 0xce, 0xfa,
-                                          0xad, 0xde, 0xef, 0xbe, 0x12, 0x34, 0xfe, 0xdc])))
+        frame.parse(
+            io.BytesIO(
+                bytearray([
+                    0x61, 0x88, 0x34, 0xce, 0xfa, 0xad, 0xde, 0xef, 0xbe, 0x12,
+                    0x34, 0xfe, 0xdc
+                ])))
 
-        self.assertEqual(
-            mac802154.MacHeader.FrameType.DATA,
-            frame.header.frame_type)
+        self.assertEqual(mac802154.MacHeader.FrameType.DATA,
+                         frame.header.frame_type)
         self.assertEqual(False, frame.header.frame_pending)
         self.assertEqual(True, frame.header.ack_request)
         self.assertEqual(0, frame.header.frame_version)
@@ -77,17 +79,16 @@
 
     def test_should_parse_data_frame_with_extended_addresses(self):
         frame = mac802154.MacFrame()
-        frame.parse(io.BytesIO(bytearray([0x61, 0xcc,
-                                          0x56,
-                                          0xce, 0xfa,
-                                          0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
-                                          0x0b, 0xad, 0xf0, 0x0d, 0xba, 0xd0, 0xd0, 0x0d,
-                                          0x12, 0x34,
-                                          0xfe, 0xdc])))
+        frame.parse(
+            io.BytesIO(
+                bytearray([
+                    0x61, 0xcc, 0x56, 0xce, 0xfa, 0xde, 0xad, 0xbe, 0xef, 0xde,
+                    0xad, 0xbe, 0xef, 0x0b, 0xad, 0xf0, 0x0d, 0xba, 0xd0, 0xd0,
+                    0x0d, 0x12, 0x34, 0xfe, 0xdc
+                ])))
 
-        self.assertEqual(
-            mac802154.MacHeader.FrameType.DATA,
-            frame.header.frame_type)
+        self.assertEqual(mac802154.MacHeader.FrameType.DATA,
+                         frame.header.frame_type)
         self.assertEqual(False, frame.header.frame_pending)
         self.assertEqual(True, frame.header.ack_request)
         self.assertEqual(0, frame.header.frame_version)
@@ -95,36 +96,26 @@
         self.assertEqual(bytearray([0xfe, 0xdc]), frame.header.fcs)
         self.assertEqual(0xface, frame.header.dest_pan_id)
         self.assertEqual(
-            bytearray(
-                reversed(
-                    [
-                        0xde, 0xad, 0xbe, 0xef,
-                        0xde, 0xad, 0xbe, 0xef])),
-            frame.header.dest_address.mac_address)
+            bytearray(reversed([0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
+                                0xef])), frame.header.dest_address.mac_address)
         self.assertEqual(0xface, frame.header.src_pan_id)
         self.assertEqual(
-            bytearray(
-                reversed(
-                    [
-                        0x0b, 0xad, 0xf0, 0x0d,
-                        0xba, 0xd0, 0xd0, 0x0d])),
-            frame.header.src_address.mac_address)
+            bytearray(reversed([0x0b, 0xad, 0xf0, 0x0d, 0xba, 0xd0, 0xd0,
+                                0x0d])), frame.header.src_address.mac_address)
 
         self.assertEqual(bytearray([0x12, 0x34]), frame.payload.data)
 
     def test_should_parse_data_frame_with_short_and_extended_addresses(self):
         frame = mac802154.MacFrame()
-        frame.parse(io.BytesIO(bytearray([0x61, 0xc8,
-                                          0x56,
-                                          0xce, 0xfa,
-                                          0xad, 0xde,
-                                          0x0b, 0xad, 0xf0, 0x0d, 0xba, 0xd0, 0xd0, 0x0d,
-                                          0x12, 0x34,
-                                          0xfe, 0xdc])))
+        frame.parse(
+            io.BytesIO(
+                bytearray([
+                    0x61, 0xc8, 0x56, 0xce, 0xfa, 0xad, 0xde, 0x0b, 0xad, 0xf0,
+                    0x0d, 0xba, 0xd0, 0xd0, 0x0d, 0x12, 0x34, 0xfe, 0xdc
+                ])))
 
-        self.assertEqual(
-            mac802154.MacHeader.FrameType.DATA,
-            frame.header.frame_type)
+        self.assertEqual(mac802154.MacHeader.FrameType.DATA,
+                         frame.header.frame_type)
         self.assertEqual(False, frame.header.frame_pending)
         self.assertEqual(True, frame.header.ack_request)
         self.assertEqual(0, frame.header.frame_version)
@@ -134,29 +125,22 @@
         self.assertEqual(0xdead, frame.header.dest_address.rloc)
         self.assertEqual(0xface, frame.header.src_pan_id)
         self.assertEqual(
-            bytearray(
-                reversed(
-                    [
-                        0x0b, 0xad, 0xf0, 0x0d,
-                        0xba, 0xd0, 0xd0, 0x0d])),
-            frame.header.src_address.mac_address)
+            bytearray(reversed([0x0b, 0xad, 0xf0, 0x0d, 0xba, 0xd0, 0xd0,
+                                0x0d])), frame.header.src_address.mac_address)
 
         self.assertEqual(bytearray([0x12, 0x34]), frame.payload.data)
 
     def test_should_parse_data_frame_with_extended_and_short_addresses(self):
         frame = mac802154.MacFrame()
-        frame.parse(io.BytesIO(bytearray([0x61, 0x8c,
-                                          0x56,
-                                          0xce, 0xfa,
-                                          0xde, 0xad, 0xbe, 0xef,
-                                          0xde, 0xad, 0xbe, 0xef,
-                                          0x0d, 0xf0,
-                                          0x12, 0x34,
-                                          0xfe, 0xdc])))
+        frame.parse(
+            io.BytesIO(
+                bytearray([
+                    0x61, 0x8c, 0x56, 0xce, 0xfa, 0xde, 0xad, 0xbe, 0xef, 0xde,
+                    0xad, 0xbe, 0xef, 0x0d, 0xf0, 0x12, 0x34, 0xfe, 0xdc
+                ])))
 
-        self.assertEqual(
-            mac802154.MacHeader.FrameType.DATA,
-            frame.header.frame_type)
+        self.assertEqual(mac802154.MacHeader.FrameType.DATA,
+                         frame.header.frame_type)
         self.assertEqual(False, frame.header.frame_pending)
         self.assertEqual(True, frame.header.ack_request)
         self.assertEqual(0, frame.header.frame_version)
@@ -164,12 +148,8 @@
         self.assertEqual(bytearray([0xfe, 0xdc]), frame.header.fcs)
         self.assertEqual(0xface, frame.header.dest_pan_id)
         self.assertEqual(
-            bytearray(
-                reversed(
-                    [
-                        0xde, 0xad, 0xbe, 0xef,
-                        0xde, 0xad, 0xbe, 0xef])),
-            frame.header.dest_address.mac_address)
+            bytearray(reversed([0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
+                                0xef])), frame.header.dest_address.mac_address)
         self.assertEqual(0xface, frame.header.src_pan_id)
         self.assertEqual(0xf00d, frame.header.src_address.rloc)
 
@@ -177,17 +157,15 @@
 
     def test_should_parse_data_request_command(self):
         frame = mac802154.MacFrame()
-        frame.parse(io.BytesIO(bytearray([0x63, 0x88,
-                                          0x78,
-                                          0xce, 0xfa,
-                                          0xad, 0xde,
-                                          0x0d, 0xf0,
-                                          0x04,
-                                          0xfe, 0xdc])))
+        frame.parse(
+            io.BytesIO(
+                bytearray([
+                    0x63, 0x88, 0x78, 0xce, 0xfa, 0xad, 0xde, 0x0d, 0xf0, 0x04,
+                    0xfe, 0xdc
+                ])))
 
-        self.assertEqual(
-            mac802154.MacHeader.FrameType.COMMAND,
-            frame.header.frame_type)
+        self.assertEqual(mac802154.MacHeader.FrameType.COMMAND,
+                         frame.header.frame_type)
         self.assertEqual(False, frame.header.frame_pending)
         self.assertEqual(True, frame.header.ack_request)
         self.assertEqual(0, frame.header.frame_version)
@@ -202,26 +180,77 @@
 
     def test_should_decrypt_data_frame(self):
 
-        mac802154.DeviceDescriptors.add(0x2001, MacAddress(bytearray(
-            [0x16, 0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x07]), MacAddressType.LONG))
+        mac802154.DeviceDescriptors.add(
+            0x2001,
+            MacAddress(
+                bytearray([0x16, 0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x07]),
+                MacAddressType.LONG))
 
         frame = mac802154.MacFrame()
-        frame.parse(io.BytesIO(bytearray([0x69, 0x98, 0x68,  # FC, seq
-                                          0xce, 0xfa,       # Pan Id
-                                          0x00, 0x20,       # Dst addr
-                                          0x01, 0x20,       # Src addr
-                                          0x0d, 0x00, 0x00, 0x00, 0x00, 0x01,             # Aux Security Header
-                                          0xb5, 0x5a, 0x0d, 0x8e, 0x18, 0x5c, 0xb1, 0x06,  # Payload
-                                          0xc4, 0x6f, 0x7d, 0x6b, 0xb5, 0x4a, 0x87, 0x14,
-                                          0xae, 0xdd, 0x8e, 0xb7, 0x37, 0x62, 0x27, 0x48,
-                                          0xc9, 0x53, 0x0c, 0x44, 0x31, 0x59, 0x8b, 0xa2,
-                                          0x83, 0x59, 0xa1, 0x43,  # MIC (valid)
-                                          0x74, 0xe0, 0x2a, 0xf6,
-                                          0x99, 0xfc])))           # FCS (valid)
+        frame.parse(
+            io.BytesIO(
+                bytearray([
+                    0x69,
+                    0x98,
+                    0x68,  # FC, seq
+                    0xce,
+                    0xfa,  # Pan Id
+                    0x00,
+                    0x20,  # Dst addr
+                    0x01,
+                    0x20,  # Src addr
+                    0x0d,
+                    0x00,
+                    0x00,
+                    0x00,
+                    0x00,
+                    0x01,  # Aux Security Header
+                    0xb5,
+                    0x5a,
+                    0x0d,
+                    0x8e,
+                    0x18,
+                    0x5c,
+                    0xb1,
+                    0x06,  # Payload
+                    0xc4,
+                    0x6f,
+                    0x7d,
+                    0x6b,
+                    0xb5,
+                    0x4a,
+                    0x87,
+                    0x14,
+                    0xae,
+                    0xdd,
+                    0x8e,
+                    0xb7,
+                    0x37,
+                    0x62,
+                    0x27,
+                    0x48,
+                    0xc9,
+                    0x53,
+                    0x0c,
+                    0x44,
+                    0x31,
+                    0x59,
+                    0x8b,
+                    0xa2,
+                    0x83,
+                    0x59,
+                    0xa1,
+                    0x43,  # MIC (valid)
+                    0x74,
+                    0xe0,
+                    0x2a,
+                    0xf6,
+                    0x99,
+                    0xfc
+                ])))  # FCS (valid)
 
-        self.assertEqual(
-            mac802154.MacHeader.FrameType.DATA,
-            frame.header.frame_type)
+        self.assertEqual(mac802154.MacHeader.FrameType.DATA,
+                         frame.header.frame_type)
         self.assertEqual(False, frame.header.frame_pending)
         self.assertEqual(True, frame.header.ack_request)
         self.assertEqual(1, frame.header.frame_version)
@@ -235,45 +264,41 @@
         self.assertEqual(0, frame.header.aux_sec_header.frame_counter)
         self.assertEqual(5, frame.header.aux_sec_header.security_level)
 
-        self.assertEqual(bytes(bytearray([0x7c, 0x77, 0x80, 0xf0,
-                                          0x4d, 0x4d, 0x4d, 0x4d,
-                                          0xe0, 0x04, 0x44, 0x02,
-                                          0x44, 0x66, 0x13, 0x5f,
-                                          0x22, 0x80, 0xb1, 0x61,
-                                          0x02, 0x61, 0x73, 0x11,
-                                          0x2a, 0xff, 0x01, 0x08,
-                                          0x16, 0x6e, 0x0a, 0x00,
-                                          0x00, 0x00, 0x00, 0x07])),
-                         frame.payload.data)
+        self.assertEqual(
+            bytes(
+                bytearray([
+                    0x7c, 0x77, 0x80, 0xf0, 0x4d, 0x4d, 0x4d, 0x4d, 0xe0, 0x04,
+                    0x44, 0x02, 0x44, 0x66, 0x13, 0x5f, 0x22, 0x80, 0xb1, 0x61,
+                    0x02, 0x61, 0x73, 0x11, 0x2a, 0xff, 0x01, 0x08, 0x16, 0x6e,
+                    0x0a, 0x00, 0x00, 0x00, 0x00, 0x07
+                ])), frame.payload.data)
 
     def test_should_decrypt_command_frame(self):
         frame = mac802154.MacFrame()
-        frame.parse(io.BytesIO(bytearray([0x6b, 0xdc, 0xce, 0xce,
-                                          0xfa, 0x02, 0x00, 0x00,
-                                          0x00, 0x00, 0x0a, 0x6e,
-                                          0x16, 0x03, 0x00, 0x00,
-                                          0x00, 0x00, 0x0a, 0x6e,
-                                          0x16, 0x0d, 0x00, 0x00,
-                                          0x00, 0x00, 0x01, 0x04,
-                                          0x2d, 0xbc, 0x12, 0xbe,
-                                          0x0a, 0x4f])))
+        frame.parse(
+            io.BytesIO(
+                bytearray([
+                    0x6b, 0xdc, 0xce, 0xce, 0xfa, 0x02, 0x00, 0x00, 0x00, 0x00,
+                    0x0a, 0x6e, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x6e,
+                    0x16, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x2d, 0xbc,
+                    0x12, 0xbe, 0x0a, 0x4f
+                ])))
 
-        self.assertEqual(
-            mac802154.MacHeader.FrameType.COMMAND,
-            frame.header.frame_type)
+        self.assertEqual(mac802154.MacHeader.FrameType.COMMAND,
+                         frame.header.frame_type)
         self.assertEqual(False, frame.header.frame_pending)
         self.assertEqual(True, frame.header.ack_request)
         self.assertEqual(1, frame.header.frame_version)
         self.assertEqual(206, frame.header.seq)
         self.assertEqual(bytearray([0x0a, 0x4f]), frame.header.fcs)
         self.assertEqual(0xface, frame.header.dest_pan_id)
-        self.assertEqual(bytearray([0x16, 0x6e, 0x0a, 0x00,
-                                    0x00, 0x00, 0x00, 0x02]),
-                         frame.header.dest_address.mac_address)
+        self.assertEqual(
+            bytearray([0x16, 0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02]),
+            frame.header.dest_address.mac_address)
         self.assertEqual(0xface, frame.header.src_pan_id)
-        self.assertEqual(bytearray([0x16, 0x6e, 0x0a, 0x00,
-                                    0x00, 0x00, 0x00, 0x03]),
-                         frame.header.src_address.mac_address)
+        self.assertEqual(
+            bytearray([0x16, 0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x03]),
+            frame.header.src_address.mac_address)
 
         self.assertEqual(0, frame.header.aux_sec_header.frame_counter)
         self.assertEqual(5, frame.header.aux_sec_header.security_level)
diff --git a/tests/scripts/thread-cert/test_mle.py b/tests/scripts/thread-cert/test_mle.py
index 01526ee..59afd7d 100755
--- a/tests/scripts/thread-cert/test_mle.py
+++ b/tests/scripts/thread-cert/test_mle.py
@@ -59,22 +59,102 @@
 
 
 mode_map = {
-    0x00: {"receiver": 0, "secure": 0, "device_type": 0, "network_data": 0},
-    0x08: {"receiver": 1, "secure": 0, "device_type": 0, "network_data": 0},
-    0x04: {"receiver": 0, "secure": 1, "device_type": 0, "network_data": 0},
-    0x0C: {"receiver": 1, "secure": 1, "device_type": 0, "network_data": 0},
-    0x02: {"receiver": 0, "secure": 0, "device_type": 1, "network_data": 0},
-    0x0A: {"receiver": 1, "secure": 0, "device_type": 1, "network_data": 0},
-    0x06: {"receiver": 0, "secure": 1, "device_type": 1, "network_data": 0},
-    0x0E: {"receiver": 1, "secure": 1, "device_type": 1, "network_data": 0},
-    0x01: {"receiver": 0, "secure": 0, "device_type": 0, "network_data": 1},
-    0x09: {"receiver": 1, "secure": 0, "device_type": 0, "network_data": 1},
-    0x05: {"receiver": 0, "secure": 1, "device_type": 0, "network_data": 1},
-    0x0D: {"receiver": 1, "secure": 1, "device_type": 0, "network_data": 1},
-    0x03: {"receiver": 0, "secure": 0, "device_type": 1, "network_data": 1},
-    0x0B: {"receiver": 1, "secure": 0, "device_type": 1, "network_data": 1},
-    0x07: {"receiver": 0, "secure": 1, "device_type": 1, "network_data": 1},
-    0x0F: {"receiver": 1, "secure": 1, "device_type": 1, "network_data": 1}
+    0x00: {
+        "receiver": 0,
+        "secure": 0,
+        "device_type": 0,
+        "network_data": 0
+    },
+    0x08: {
+        "receiver": 1,
+        "secure": 0,
+        "device_type": 0,
+        "network_data": 0
+    },
+    0x04: {
+        "receiver": 0,
+        "secure": 1,
+        "device_type": 0,
+        "network_data": 0
+    },
+    0x0C: {
+        "receiver": 1,
+        "secure": 1,
+        "device_type": 0,
+        "network_data": 0
+    },
+    0x02: {
+        "receiver": 0,
+        "secure": 0,
+        "device_type": 1,
+        "network_data": 0
+    },
+    0x0A: {
+        "receiver": 1,
+        "secure": 0,
+        "device_type": 1,
+        "network_data": 0
+    },
+    0x06: {
+        "receiver": 0,
+        "secure": 1,
+        "device_type": 1,
+        "network_data": 0
+    },
+    0x0E: {
+        "receiver": 1,
+        "secure": 1,
+        "device_type": 1,
+        "network_data": 0
+    },
+    0x01: {
+        "receiver": 0,
+        "secure": 0,
+        "device_type": 0,
+        "network_data": 1
+    },
+    0x09: {
+        "receiver": 1,
+        "secure": 0,
+        "device_type": 0,
+        "network_data": 1
+    },
+    0x05: {
+        "receiver": 0,
+        "secure": 1,
+        "device_type": 0,
+        "network_data": 1
+    },
+    0x0D: {
+        "receiver": 1,
+        "secure": 1,
+        "device_type": 0,
+        "network_data": 1
+    },
+    0x03: {
+        "receiver": 0,
+        "secure": 0,
+        "device_type": 1,
+        "network_data": 1
+    },
+    0x0B: {
+        "receiver": 1,
+        "secure": 0,
+        "device_type": 1,
+        "network_data": 1
+    },
+    0x07: {
+        "receiver": 0,
+        "secure": 1,
+        "device_type": 1,
+        "network_data": 1
+    },
+    0x0F: {
+        "receiver": 1,
+        "secure": 1,
+        "device_type": 1,
+        "network_data": 1
+    }
 }
 
 
@@ -146,10 +226,22 @@
 
 
 scan_mask_map = {
-    0x00: {"router": 0, "end_device": 0},
-    0x40: {"router": 0, "end_device": 1},
-    0x80: {"router": 1, "end_device": 0},
-    0xC0: {"router": 1, "end_device": 1},
+    0x00: {
+        "router": 0,
+        "end_device": 0
+    },
+    0x40: {
+        "router": 0,
+        "end_device": 1
+    },
+    0x80: {
+        "router": 1,
+        "end_device": 0
+    },
+    0xC0: {
+        "router": 1,
+        "end_device": 1
+    },
 }
 
 
@@ -202,7 +294,7 @@
 
 
 def any_pp():
-    return random.getrandbits(2)
+    return (random.getrandbits(2) << 6)
 
 
 def any_link_quality_3():
@@ -311,7 +403,8 @@
 
 class TestSourceAddressFactory(unittest.TestCase):
 
-    def test_should_create_SourceAddress_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_SourceAddress_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         address = any_address()
 
@@ -329,11 +422,13 @@
 
 class TestMode(unittest.TestCase):
 
-    def test_should_return_receiver_value_when_receiver_property_is_called(self):
+    def test_should_return_receiver_value_when_receiver_property_is_called(
+        self):
         # GIVEN
         receiver = any_receiver()
 
-        mode = mle.Mode(receiver, any_secure(), any_device_type(), any_network_data())
+        mode = mle.Mode(receiver, any_secure(), any_device_type(),
+                        any_network_data())
 
         # WHEN
         actual_receiver = mode.receiver
@@ -345,7 +440,8 @@
         # GIVEN
         secure = any_secure()
 
-        mode = mle.Mode(any_receiver(), secure, any_device_type(), any_network_data())
+        mode = mle.Mode(any_receiver(), secure, any_device_type(),
+                        any_network_data())
 
         # WHEN
         actual_secure = mode.secure
@@ -353,11 +449,13 @@
         # THEN
         self.assertEqual(secure, actual_secure)
 
-    def test_should_return_device_type_value_when_device_type_property_is_called(self):
+    def test_should_return_device_type_value_when_device_type_property_is_called(
+        self):
         # GIVEN
         device_type = any_device_type()
 
-        mode = mle.Mode(any_receiver(), any_secure(), device_type, any_network_data())
+        mode = mle.Mode(any_receiver(), any_secure(), device_type,
+                        any_network_data())
 
         # WHEN
         actual_device_type = mode.device_type
@@ -365,11 +463,13 @@
         # THEN
         self.assertEqual(device_type, actual_device_type)
 
-    def test_should_return_network_data_value_when_network_data_property_is_called(self):
+    def test_should_return_network_data_value_when_network_data_property_is_called(
+        self):
         # GIVEN
         network_data = any_network_data()
 
-        mode = mle.Mode(any_receiver(), any_secure(), any_device_type(), network_data)
+        mode = mle.Mode(any_receiver(), any_secure(), any_device_type(),
+                        network_data)
 
         # WHEN
         actual_network_data = mode.network_data
@@ -380,7 +480,8 @@
 
 class TestModeFactory(unittest.TestCase):
 
-    def test_should_create_Mode_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Mode_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         mode = any_mode()
 
@@ -396,7 +497,8 @@
         self.assertEqual(mode_map[mode]["receiver"], actual_mode.receiver)
         self.assertEqual(mode_map[mode]["secure"], actual_mode.secure)
         self.assertEqual(mode_map[mode]["device_type"], actual_mode.device_type)
-        self.assertEqual(mode_map[mode]["network_data"], actual_mode.network_data)
+        self.assertEqual(mode_map[mode]["network_data"],
+                         actual_mode.network_data)
 
 
 class TestTimeout(unittest.TestCase):
@@ -416,7 +518,8 @@
 
 class TestTimeoutFactory(unittest.TestCase):
 
-    def test_should_create_Timeout_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Timeout_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         timeout = any_timeout()
 
@@ -434,7 +537,8 @@
 
 class TestChallenge(unittest.TestCase):
 
-    def test_should_return_challenge_value_when_challenge_property_is_called(self):
+    def test_should_return_challenge_value_when_challenge_property_is_called(
+        self):
         # GIVEN
         challenge = any_challenge()
 
@@ -449,7 +553,8 @@
 
 class TestChallengeFactory(unittest.TestCase):
 
-    def test_should_create_Challenge_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Challenge_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         challenge = any_challenge()
 
@@ -467,7 +572,8 @@
 
 class TestResponse(unittest.TestCase):
 
-    def test_should_return_response_value_when_response_property_is_called(self):
+    def test_should_return_response_value_when_response_property_is_called(
+        self):
         # GIVEN
         response = any_response()
 
@@ -482,7 +588,8 @@
 
 class TestResponseFactory(unittest.TestCase):
 
-    def test_should_create_Challenge_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Challenge_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         response = any_response()
 
@@ -500,22 +607,26 @@
 
 class TestLinkLayerFrameCounter(unittest.TestCase):
 
-    def test_should_return_frame_counter_value_when_frame_counter_property_is_called(self):
+    def test_should_return_frame_counter_value_when_frame_counter_property_is_called(
+        self):
         # GIVEN
         link_layer_frame_counter = any_link_layer_frame_counter()
 
-        link_layer_frame_counter_obj = mle.LinkLayerFrameCounter(link_layer_frame_counter)
+        link_layer_frame_counter_obj = mle.LinkLayerFrameCounter(
+            link_layer_frame_counter)
 
         # WHEN
         actual_link_layer_frame_counter = link_layer_frame_counter_obj.frame_counter
 
         # THEN
-        self.assertEqual(link_layer_frame_counter, actual_link_layer_frame_counter)
+        self.assertEqual(link_layer_frame_counter,
+                         actual_link_layer_frame_counter)
 
 
 class TestLinkLayerFrameCounterFactory(unittest.TestCase):
 
-    def test_should_create_LinkLayerFrameCounter_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_LinkLayerFrameCounter_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         link_layer_frame_counter = any_link_layer_frame_counter()
 
@@ -524,16 +635,21 @@
         data = struct.pack(">I", link_layer_frame_counter)
 
         # WHEN
-        actual_link_layer_frame_counter = factory.parse(io.BytesIO(data), dict())
+        actual_link_layer_frame_counter = factory.parse(io.BytesIO(data),
+                                                        dict())
 
         # THEN
-        self.assertTrue(isinstance(actual_link_layer_frame_counter, mle.LinkLayerFrameCounter))
-        self.assertEqual(link_layer_frame_counter, actual_link_layer_frame_counter.frame_counter)
+        self.assertTrue(
+            isinstance(actual_link_layer_frame_counter,
+                       mle.LinkLayerFrameCounter))
+        self.assertEqual(link_layer_frame_counter,
+                         actual_link_layer_frame_counter.frame_counter)
 
 
 class TestMleFrameCounter(unittest.TestCase):
 
-    def test_should_return_frame_counter_value_when_frame_counter_property_is_called(self):
+    def test_should_return_frame_counter_value_when_frame_counter_property_is_called(
+        self):
         # GIVEN
         mle_frame_counter = any_mle_frame_counter()
 
@@ -548,7 +664,8 @@
 
 class TestMleFrameCounterFactory(unittest.TestCase):
 
-    def test_should_create_MleFrameCounter_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_MleFrameCounter_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         mle_frame_counter = any_mle_frame_counter()
 
@@ -560,8 +677,10 @@
         actual_mle_frame_counter = factory.parse(io.BytesIO(data), dict())
 
         # THEN
-        self.assertTrue(isinstance(actual_mle_frame_counter, mle.MleFrameCounter))
-        self.assertEqual(mle_frame_counter, actual_mle_frame_counter.frame_counter)
+        self.assertTrue(
+            isinstance(actual_mle_frame_counter, mle.MleFrameCounter))
+        self.assertEqual(mle_frame_counter,
+                         actual_mle_frame_counter.frame_counter)
 
 
 class TestLinkQualityAndRouteData(unittest.TestCase):
@@ -605,7 +724,8 @@
 
 class TestLinkQualityAndRouteDataFactory(unittest.TestCase):
 
-    def test_should_create_LinkQualityAndRouteData_from_well_known_byte_when_parse_method_is_called(self):
+    def test_should_create_LinkQualityAndRouteData_from_well_known_byte_when_parse_method_is_called(
+        self):
         # GIVEN
         factory = mle.LinkQualityAndRouteDataFactory()
 
@@ -619,7 +739,8 @@
         self.assertEqual(2, actual_lqrd.input)
         self.assertEqual(6, actual_lqrd.route)
 
-    def test_should_create_LinkQualityAndRouteData_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_LinkQualityAndRouteData_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         output = any_output()
         _input = any_input()
@@ -643,11 +764,13 @@
 
 class TestRoute64(unittest.TestCase):
 
-    def test_should_return_id_sequence_value_when_id_sequence_property_is_called(self):
+    def test_should_return_id_sequence_value_when_id_sequence_property_is_called(
+        self):
         # GIVEN
         id_sequence = any_id_sequence()
 
-        route64_obj = mle.Route64(id_sequence, any_router_id_mask(), any_link_quality_and_route_data())
+        route64_obj = mle.Route64(id_sequence, any_router_id_mask(),
+                                  any_link_quality_and_route_data())
 
         # WHEN
         actual_id_sequence = route64_obj.id_sequence
@@ -655,11 +778,13 @@
         # THEN
         self.assertEqual(id_sequence, actual_id_sequence)
 
-    def test_should_return_router_id_mask_value_when_router_id_mask_property_is_called(self):
+    def test_should_return_router_id_mask_value_when_router_id_mask_property_is_called(
+        self):
         # GIVEN
         router_id_mask = any_router_id_mask()
 
-        route64_obj = mle.Route64(any_id_sequence(), router_id_mask, any_link_quality_and_route_data())
+        route64_obj = mle.Route64(any_id_sequence(), router_id_mask,
+                                  any_link_quality_and_route_data())
 
         # WHEN
         actual_router_id_mask = route64_obj.router_id_mask
@@ -667,22 +792,26 @@
         # THEN
         self.assertEqual(router_id_mask, actual_router_id_mask)
 
-    def test_should_return_link_quality_and_route_data_value_when_link_quality_and_route_data_property_is_called(self):
+    def test_should_return_link_quality_and_route_data_value_when_link_quality_and_route_data_property_is_called(
+        self):
         # GIVEN
         link_quality_and_route_data = any_link_quality_and_route_data()
 
-        route64_obj = mle.Route64(any_id_sequence(), any_router_id_mask(), link_quality_and_route_data)
+        route64_obj = mle.Route64(any_id_sequence(), any_router_id_mask(),
+                                  link_quality_and_route_data)
 
         # WHEN
         actual_link_quality_and_route_data = route64_obj.link_quality_and_route_data
 
         # THEN
-        self.assertEqual(link_quality_and_route_data, actual_link_quality_and_route_data)
+        self.assertEqual(link_quality_and_route_data,
+                         actual_link_quality_and_route_data)
 
 
 class TestRoute64Factory(unittest.TestCase):
 
-    def test_should_create_Route64_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Route64_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         class DummyLQRDFactory:
 
@@ -696,11 +825,13 @@
         for i in range(64):
             router_count += (router_id_mask >> i) & 0x01
 
-        link_quality_and_route_data = any_link_quality_and_route_data(router_count)
+        link_quality_and_route_data = any_link_quality_and_route_data(
+            router_count)
 
         factory = mle.Route64Factory(DummyLQRDFactory())
 
-        data = bytearray([id_sequence]) + struct.pack(">Q", router_id_mask) + bytearray(link_quality_and_route_data)
+        data = bytearray([id_sequence]) + struct.pack(
+            ">Q", router_id_mask) + bytearray(link_quality_and_route_data)
 
         # WHEN
         actual_route64 = factory.parse(io.BytesIO(data), dict())
@@ -709,7 +840,8 @@
         self.assertTrue(isinstance(actual_route64, mle.Route64))
         self.assertEqual(id_sequence, actual_route64.id_sequence)
         self.assertEqual(router_id_mask, actual_route64.router_id_mask)
-        self.assertEqual([b for b in link_quality_and_route_data], actual_route64.link_quality_and_route_data)
+        self.assertEqual([b for b in link_quality_and_route_data],
+                         actual_route64.link_quality_and_route_data)
 
 
 class TestAddress16(unittest.TestCase):
@@ -729,7 +861,8 @@
 
 class TestAddress16Factory(unittest.TestCase):
 
-    def test_should_create_Address16_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Address16_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         address = any_address()
 
@@ -747,12 +880,15 @@
 
 class TestLeaderData(unittest.TestCase):
 
-    def test_should_return_partition_id_value_when_partition_id_property_is_called(self):
+    def test_should_return_partition_id_value_when_partition_id_property_is_called(
+        self):
         # GIVEN
         partition_id = any_partition_id()
 
-        leader_data = mle.LeaderData(partition_id, any_weighting(), any_data_version(),
-                                     any_stable_data_version(), any_leader_router_id())
+        leader_data = mle.LeaderData(partition_id, any_weighting(),
+                                     any_data_version(),
+                                     any_stable_data_version(),
+                                     any_leader_router_id())
 
         # WHEN
         actual_partition_id = leader_data.partition_id
@@ -760,12 +896,15 @@
         # THEN
         self.assertEqual(partition_id, actual_partition_id)
 
-    def test_should_return_weighting_value_when_weighting_property_is_called(self):
+    def test_should_return_weighting_value_when_weighting_property_is_called(
+        self):
         # GIVEN
         weighting = any_weighting()
 
-        leader_data = mle.LeaderData(any_partition_id(), weighting, any_data_version(),
-                                     any_stable_data_version(), any_leader_router_id())
+        leader_data = mle.LeaderData(any_partition_id(), weighting,
+                                     any_data_version(),
+                                     any_stable_data_version(),
+                                     any_leader_router_id())
 
         # WHEN
         actual_weighting = leader_data.weighting
@@ -773,12 +912,14 @@
         # THEN
         self.assertEqual(weighting, actual_weighting)
 
-    def test_should_return_data_version_value_when_data_version_property_is_called(self):
+    def test_should_return_data_version_value_when_data_version_property_is_called(
+        self):
         # GIVEN
         data_version = any_data_version()
 
-        leader_data = mle.LeaderData(any_partition_id(), any_weighting(), data_version,
-                                     any_stable_data_version(), any_leader_router_id())
+        leader_data = mle.LeaderData(any_partition_id(), any_weighting(),
+                                     data_version, any_stable_data_version(),
+                                     any_leader_router_id())
 
         # WHEN
         actual_data_version = leader_data.data_version
@@ -786,12 +927,14 @@
         # THEN
         self.assertEqual(data_version, actual_data_version)
 
-    def test_should_return_stable_data_version_value_when_stable_data_version_property_is_called(self):
+    def test_should_return_stable_data_version_value_when_stable_data_version_property_is_called(
+        self):
         # GIVEN
         stable_data_version = any_stable_data_version()
 
-        leader_data = mle.LeaderData(any_partition_id(), any_weighting(), any_data_version(),
-                                     stable_data_version, any_leader_router_id())
+        leader_data = mle.LeaderData(any_partition_id(), any_weighting(),
+                                     any_data_version(), stable_data_version,
+                                     any_leader_router_id())
 
         # WHEN
         actual_stable_data_version = leader_data.stable_data_version
@@ -799,12 +942,15 @@
         # THEN
         self.assertEqual(stable_data_version, actual_stable_data_version)
 
-    def test_should_return_leader_router_id_value_when_leader_router_id_property_is_called(self):
+    def test_should_return_leader_router_id_value_when_leader_router_id_property_is_called(
+        self):
         # GIVEN
         leader_router_id = any_leader_router_id()
 
-        leader_data = mle.LeaderData(any_partition_id(), any_weighting(), any_data_version(),
-                                     any_stable_data_version(), leader_router_id)
+        leader_data = mle.LeaderData(any_partition_id(), any_weighting(),
+                                     any_data_version(),
+                                     any_stable_data_version(),
+                                     leader_router_id)
 
         # WHEN
         actual_leader_router_id = leader_data.leader_router_id
@@ -815,7 +961,8 @@
 
 class TestLeaderDataFactory(unittest.TestCase):
 
-    def test_should_create_Address16_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Address16_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         partition_id = any_partition_id()
         weighting = any_weighting()
@@ -836,7 +983,8 @@
         self.assertEqual(partition_id, actual_leader_data.partition_id)
         self.assertEqual(weighting, actual_leader_data.weighting)
         self.assertEqual(data_version, actual_leader_data.data_version)
-        self.assertEqual(stable_data_version, actual_leader_data.stable_data_version)
+        self.assertEqual(stable_data_version,
+                         actual_leader_data.stable_data_version)
         self.assertEqual(leader_router_id, actual_leader_data.leader_router_id)
 
 
@@ -857,7 +1005,8 @@
 
 class TestNetworkDataFactory(unittest.TestCase):
 
-    def test_should_create_TlvRequest_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_TlvRequest_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         class DummyNetworkTlvsFactory:
 
@@ -895,7 +1044,8 @@
 
 class TestTlvRequestFactory(unittest.TestCase):
 
-    def test_should_create_TlvRequest_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_TlvRequest_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         tlvs = any_tlvs()
 
@@ -925,7 +1075,8 @@
         # THEN
         self.assertEqual(router, actual_router)
 
-    def test_should_return_end_device_value_when_end_device_property_is_called(self):
+    def test_should_return_end_device_value_when_end_device_property_is_called(
+        self):
         # GIVEN
         end_device = any_scan_mask_end_device()
 
@@ -940,7 +1091,8 @@
 
 class TestScanMaskFactory(unittest.TestCase):
 
-    def test_should_create_ScanMask_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_ScanMask_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         scan_mask = any_scan_mask()
 
@@ -953,18 +1105,19 @@
 
         # THEN
         self.assertTrue(isinstance(actual_scan_mask, mle.ScanMask))
-        self.assertEqual(scan_mask_map[scan_mask]["router"], actual_scan_mask.router)
-        self.assertEqual(scan_mask_map[scan_mask]["end_device"], actual_scan_mask.end_device)
+        self.assertEqual(scan_mask_map[scan_mask]["router"],
+                         actual_scan_mask.router)
+        self.assertEqual(scan_mask_map[scan_mask]["end_device"],
+                         actual_scan_mask.end_device)
 
 
 class TestConnectivity(unittest.TestCase):
 
     def test_should_return_pp_value_when_pp_property_is_called(self):
         # GIVEN
-        pp = any_pp()
+        pp_byte = any_pp()
 
-        connectivity_obj = mle.Connectivity(pp,
-                                            any_link_quality_3(),
+        connectivity_obj = mle.Connectivity(pp_byte, any_link_quality_3(),
                                             any_link_quality_2(),
                                             any_link_quality_1(),
                                             any_leader_cost(),
@@ -977,14 +1130,14 @@
         actual_pp = connectivity_obj.pp
 
         # THEN
-        self.assertEqual(pp, actual_pp)
+        self.assertEqual(common.map_pp(pp_byte), actual_pp)
 
-    def test_should_return_link_quality_3_value_when_link_quality_3_property_is_called(self):
+    def test_should_return_link_quality_3_value_when_link_quality_3_property_is_called(
+        self):
         # GIVEN
         link_quality_3 = any_link_quality_3()
 
-        connectivity_obj = mle.Connectivity(any_pp(),
-                                            link_quality_3,
+        connectivity_obj = mle.Connectivity(any_pp(), link_quality_3,
                                             any_link_quality_2(),
                                             any_link_quality_1(),
                                             any_leader_cost(),
@@ -999,12 +1152,12 @@
         # THEN
         self.assertEqual(link_quality_3, actual_link_quality_3)
 
-    def test_should_return_link_quality_2_value_when_link_quality_2_property_is_called(self):
+    def test_should_return_link_quality_2_value_when_link_quality_2_property_is_called(
+        self):
         # GIVEN
         link_quality_2 = any_link_quality_2()
 
-        connectivity_obj = mle.Connectivity(any_pp(),
-                                            any_link_quality_3(),
+        connectivity_obj = mle.Connectivity(any_pp(), any_link_quality_3(),
                                             link_quality_2,
                                             any_link_quality_1(),
                                             any_leader_cost(),
@@ -1019,15 +1172,14 @@
         # THEN
         self.assertEqual(link_quality_2, actual_link_quality_2)
 
-    def test_should_return_link_quality_1_value_when_link_quality_1_property_is_called(self):
+    def test_should_return_link_quality_1_value_when_link_quality_1_property_is_called(
+        self):
         # GIVEN
         link_quality_1 = any_link_quality_1()
 
-        connectivity_obj = mle.Connectivity(any_pp(),
-                                            any_link_quality_3(),
+        connectivity_obj = mle.Connectivity(any_pp(), any_link_quality_3(),
                                             any_link_quality_2(),
-                                            link_quality_1,
-                                            any_leader_cost(),
+                                            link_quality_1, any_leader_cost(),
                                             any_id_sequence(),
                                             any_active_routers(),
                                             any_sed_buffer_size(),
@@ -1039,15 +1191,14 @@
         # THEN
         self.assertEqual(link_quality_1, actual_link_quality_1)
 
-    def test_should_return_leader_cost_value_when_leader_cost_property_is_called(self):
+    def test_should_return_leader_cost_value_when_leader_cost_property_is_called(
+        self):
         # GIVEN
         leader_cost = any_leader_cost()
 
-        connectivity_obj = mle.Connectivity(any_pp(),
-                                            any_link_quality_3(),
+        connectivity_obj = mle.Connectivity(any_pp(), any_link_quality_3(),
                                             any_link_quality_2(),
-                                            any_link_quality_1(),
-                                            leader_cost,
+                                            any_link_quality_1(), leader_cost,
                                             any_id_sequence(),
                                             any_active_routers(),
                                             any_sed_buffer_size(),
@@ -1059,16 +1210,15 @@
         # THEN
         self.assertEqual(leader_cost, actual_leader_cost)
 
-    def test_should_return_id_sequence_value_when_id_sequence_property_is_called(self):
+    def test_should_return_id_sequence_value_when_id_sequence_property_is_called(
+        self):
         # GIVEN
         id_sequence = any_id_sequence()
 
-        connectivity_obj = mle.Connectivity(any_pp(),
-                                            any_link_quality_3(),
+        connectivity_obj = mle.Connectivity(any_pp(), any_link_quality_3(),
                                             any_link_quality_2(),
                                             any_link_quality_1(),
-                                            any_leader_cost(),
-                                            id_sequence,
+                                            any_leader_cost(), id_sequence,
                                             any_active_routers(),
                                             any_sed_buffer_size(),
                                             any_sed_datagram_count())
@@ -1079,17 +1229,16 @@
         # THEN
         self.assertEqual(id_sequence, actual_id_sequence)
 
-    def test_should_return_active_routers_value_when_active_routers_property_is_called(self):
+    def test_should_return_active_routers_value_when_active_routers_property_is_called(
+        self):
         # GIVEN
         active_routers = any_active_routers()
 
-        connectivity_obj = mle.Connectivity(any_pp(),
-                                            any_link_quality_3(),
+        connectivity_obj = mle.Connectivity(any_pp(), any_link_quality_3(),
                                             any_link_quality_2(),
                                             any_link_quality_1(),
                                             any_leader_cost(),
-                                            any_id_sequence(),
-                                            active_routers,
+                                            any_id_sequence(), active_routers,
                                             any_sed_buffer_size(),
                                             any_sed_datagram_count())
 
@@ -1099,12 +1248,12 @@
         # THEN
         self.assertEqual(active_routers, actual_active_routers)
 
-    def test_should_return_sed_buffer_size_value_when_sed_buffer_size_property_is_called(self):
+    def test_should_return_sed_buffer_size_value_when_sed_buffer_size_property_is_called(
+        self):
         # GIVEN
         sed_buffer_size = any_sed_buffer_size()
 
-        connectivity_obj = mle.Connectivity(any_pp(),
-                                            any_link_quality_3(),
+        connectivity_obj = mle.Connectivity(any_pp(), any_link_quality_3(),
                                             any_link_quality_2(),
                                             any_link_quality_1(),
                                             any_leader_cost(),
@@ -1119,12 +1268,12 @@
         # THEN
         self.assertEqual(sed_buffer_size, actual_sed_buffer_size)
 
-    def test_should_return_sed_datagram_count_value_when_sed_datagram_count_property_is_called(self):
+    def test_should_return_sed_datagram_count_value_when_sed_datagram_count_property_is_called(
+        self):
         # GIVEN
         sed_datagram_count = any_sed_datagram_count()
 
-        connectivity_obj = mle.Connectivity(any_pp(),
-                                            any_link_quality_3(),
+        connectivity_obj = mle.Connectivity(any_pp(), any_link_quality_3(),
                                             any_link_quality_2(),
                                             any_link_quality_1(),
                                             any_leader_cost(),
@@ -1142,9 +1291,10 @@
 
 class TestConnectivityFactory(unittest.TestCase):
 
-    def test_should_create_Connectivity_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Connectivity_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
-        pp = any_pp()
+        pp_byte = any_pp()
         link_quality_3 = any_link_quality_3()
         link_quality_2 = any_link_quality_2()
         link_quality_1 = any_link_quality_1()
@@ -1156,15 +1306,18 @@
 
         factory = mle.ConnectivityFactory()
 
-        data = bytearray([pp, link_quality_3, link_quality_2, link_quality_1, leader_cost, id_sequence,
-                          active_routers]) + struct.pack(">H", sed_buffer_size) + bytearray([sed_datagram_count])
+        data = bytearray([
+            pp_byte, link_quality_3, link_quality_2, link_quality_1,
+            leader_cost, id_sequence, active_routers
+        ]) + struct.pack(">H", sed_buffer_size) + bytearray(
+            [sed_datagram_count])
 
         # WHEN
         actual_connectivity = factory.parse(io.BytesIO(data), dict())
 
         # THEN
         self.assertTrue(isinstance(actual_connectivity, mle.Connectivity))
-        self.assertEqual(pp, actual_connectivity.pp)
+        self.assertEqual(common.map_pp(pp_byte), actual_connectivity.pp)
         self.assertEqual(link_quality_3, actual_connectivity.link_quality_3)
         self.assertEqual(link_quality_2, actual_connectivity.link_quality_2)
         self.assertEqual(link_quality_1, actual_connectivity.link_quality_1)
@@ -1172,11 +1325,13 @@
         self.assertEqual(id_sequence, actual_connectivity.id_sequence)
         self.assertEqual(active_routers, actual_connectivity.active_routers)
         self.assertEqual(sed_buffer_size, actual_connectivity.sed_buffer_size)
-        self.assertEqual(sed_datagram_count, actual_connectivity.sed_datagram_count)
+        self.assertEqual(sed_datagram_count,
+                         actual_connectivity.sed_datagram_count)
 
-    def test_should_create_Connectivity_without_sed_data_when_parse_method_is_called(self):
+    def test_should_create_Connectivity_without_sed_data_when_parse_method_is_called(
+        self):
         # GIVEN
-        pp = any_pp()
+        pp_byte = any_pp()
         link_quality_3 = any_link_quality_3()
         link_quality_2 = any_link_quality_2()
         link_quality_1 = any_link_quality_1()
@@ -1188,15 +1343,17 @@
 
         factory = mle.ConnectivityFactory()
 
-        data = bytearray([pp, link_quality_3, link_quality_2, link_quality_1, leader_cost, id_sequence,
-                          active_routers])
+        data = bytearray([
+            pp_byte, link_quality_3, link_quality_2, link_quality_1,
+            leader_cost, id_sequence, active_routers
+        ])
 
         # WHEN
         actual_connectivity = factory.parse(io.BytesIO(data), dict())
 
         # THEN
         self.assertTrue(isinstance(actual_connectivity, mle.Connectivity))
-        self.assertEqual(pp, actual_connectivity.pp)
+        self.assertEqual(common.map_pp(pp_byte), actual_connectivity.pp)
         self.assertEqual(link_quality_3, actual_connectivity.link_quality_3)
         self.assertEqual(link_quality_2, actual_connectivity.link_quality_2)
         self.assertEqual(link_quality_1, actual_connectivity.link_quality_1)
@@ -1209,7 +1366,8 @@
 
 class TestLinkMargin(unittest.TestCase):
 
-    def test_should_return_link_margin_value_when_link_margin_property_is_called(self):
+    def test_should_return_link_margin_value_when_link_margin_property_is_called(
+        self):
         # GIVEN
         link_margin = any_link_margin()
 
@@ -1224,7 +1382,8 @@
 
 class TestLinkMarginFactory(unittest.TestCase):
 
-    def test_should_create_LinkMargin_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_LinkMargin_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         link_margin = any_link_margin()
 
@@ -1257,7 +1416,8 @@
 
 class TestStatusFactory(unittest.TestCase):
 
-    def test_should_create_Status_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Status_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         status = any_status()
 
@@ -1290,7 +1450,8 @@
 
 class TestVersionFactory(unittest.TestCase):
 
-    def test_should_create_Version_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Version_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         version = any_version()
 
@@ -1308,7 +1469,8 @@
 
 class TestAddressRegistrationFull(unittest.TestCase):
 
-    def test_should_return_ipv6_address_value_when_ipv6_address_property_is_called(self):
+    def test_should_return_ipv6_address_value_when_ipv6_address_property_is_called(
+        self):
         # GIVEN
         ipv6_address = any_ipv6_address()
 
@@ -1323,7 +1485,8 @@
 
 class TestAddressRegistrationFullFactory(unittest.TestCase):
 
-    def test_should_create_AddressFull_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_AddressFull_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         ipv6_address = any_ipv6_address()
 
@@ -1368,7 +1531,8 @@
 
 class TestAddressRegistrationCompressedFactory(unittest.TestCase):
 
-    def test_should_create_AddressRegistrationCompressed_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_AddressRegistrationCompressed_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         cid = any_cid()
         iid = any_iid()
@@ -1381,14 +1545,16 @@
         actual_addr_reg_compressed = factory.parse(io.BytesIO(data), dict())
 
         # THEN
-        self.assertTrue(isinstance(actual_addr_reg_compressed, mle.AddressCompressed))
+        self.assertTrue(
+            isinstance(actual_addr_reg_compressed, mle.AddressCompressed))
         self.assertEqual(cid, actual_addr_reg_compressed.cid)
         self.assertEqual(iid, actual_addr_reg_compressed.iid)
 
 
 class TestAddressRegistration(unittest.TestCase):
 
-    def test_should_return_addresses_value_when_addresses_property_is_called(self):
+    def test_should_return_addresses_value_when_addresses_property_is_called(
+        self):
         # GIVEN
         addresses = any_addresses()
 
@@ -1403,7 +1569,8 @@
 
 class TestAddressRegistrationFactory(unittest.TestCase):
 
-    def test_should_create_AddressRegistration_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_AddressRegistration_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         cid = any_cid()
         iid = any_iid()
@@ -1426,12 +1593,14 @@
         self.assertTrue(isinstance(actual_addr_reg, mle.AddressRegistration))
         self.assertEqual(addresses[0].cid, actual_addr_reg.addresses[0].cid)
         self.assertEqual(addresses[0].iid, actual_addr_reg.addresses[0].iid)
-        self.assertEqual(addresses[1].ipv6_address, actual_addr_reg.addresses[1].ipv6_address)
+        self.assertEqual(addresses[1].ipv6_address,
+                         actual_addr_reg.addresses[1].ipv6_address)
 
 
 class TestChannel(unittest.TestCase):
 
-    def test_should_return_channel_page_value_when_channel_page_property_is_called(self):
+    def test_should_return_channel_page_value_when_channel_page_property_is_called(
+        self):
         # GIVEN
         channel_page = any_channel_page()
 
@@ -1458,7 +1627,8 @@
 
 class TestChannelFactory(unittest.TestCase):
 
-    def test_should_create_Channel_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_Channel_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         channel_page = any_channel_page()
         channel = any_channel()
@@ -1493,7 +1663,8 @@
 
 class TestPanIdFactory(unittest.TestCase):
 
-    def test_should_create_PanId_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_PanId_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         pan_id = any_pan_id()
 
@@ -1511,11 +1682,14 @@
 
 class TestActiveTimestamp(unittest.TestCase):
 
-    def test_should_return_timestamp_seconds_value_when_timestamp_seconds_property_is_called(self):
+    def test_should_return_timestamp_seconds_value_when_timestamp_seconds_property_is_called(
+        self):
         # GIVEN
         timestamp_seconds = any_timestamp_seconds()
 
-        active_timestamp_obj = mle.ActiveTimestamp(timestamp_seconds, any_timestamp_ticks(), any_u())
+        active_timestamp_obj = mle.ActiveTimestamp(timestamp_seconds,
+                                                   any_timestamp_ticks(),
+                                                   any_u())
 
         # WHEN
         actual_timestamp_seconds = active_timestamp_obj.timestamp_seconds
@@ -1523,11 +1697,13 @@
         # THEN
         self.assertEqual(timestamp_seconds, actual_timestamp_seconds)
 
-    def test_should_return_timestamp_ticks_value_when_timestamp_ticks_property_is_called(self):
+    def test_should_return_timestamp_ticks_value_when_timestamp_ticks_property_is_called(
+        self):
         # GIVEN
         timestamp_ticks = any_timestamp_ticks()
 
-        active_timestamp_obj = mle.ActiveTimestamp(any_timestamp_seconds(), timestamp_ticks, any_u())
+        active_timestamp_obj = mle.ActiveTimestamp(any_timestamp_seconds(),
+                                                   timestamp_ticks, any_u())
 
         # WHEN
         actual_timestamp_ticks = active_timestamp_obj.timestamp_ticks
@@ -1539,7 +1715,8 @@
         # GIVEN
         u = any_u()
 
-        active_timestamp_obj = mle.ActiveTimestamp(any_timestamp_seconds(), any_timestamp_ticks(), u)
+        active_timestamp_obj = mle.ActiveTimestamp(any_timestamp_seconds(),
+                                                   any_timestamp_ticks(), u)
 
         # WHEN
         actual_u = active_timestamp_obj.u
@@ -1550,7 +1727,8 @@
 
 class TestActiveTimestampFactory(unittest.TestCase):
 
-    def test_should_create_ActiveTimestamp_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_ActiveTimestamp_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         timestamp_seconds = any_timestamp_seconds()
         timestamp_ticks = any_timestamp_ticks()
@@ -1558,7 +1736,8 @@
 
         factory = mle.ActiveTimestampFactory()
 
-        data = struct.pack(">Q", timestamp_seconds)[2:] + struct.pack(">H", (timestamp_ticks << 1) | u)
+        data = struct.pack(">Q", timestamp_seconds)[2:] + struct.pack(
+            ">H", (timestamp_ticks << 1) | u)
 
         # WHEN
         active_timestamp = factory.parse(io.BytesIO(data), dict())
@@ -1572,11 +1751,14 @@
 
 class TestPendingTimestamp(unittest.TestCase):
 
-    def test_should_return_timestamp_seconds_value_when_timestamp_seconds_property_is_called(self):
+    def test_should_return_timestamp_seconds_value_when_timestamp_seconds_property_is_called(
+        self):
         # GIVEN
         timestamp_seconds = any_timestamp_seconds()
 
-        pending_timestamp_obj = mle.PendingTimestamp(timestamp_seconds, any_timestamp_ticks(), any_u())
+        pending_timestamp_obj = mle.PendingTimestamp(timestamp_seconds,
+                                                     any_timestamp_ticks(),
+                                                     any_u())
 
         # WHEN
         actual_timestamp_seconds = pending_timestamp_obj.timestamp_seconds
@@ -1584,11 +1766,13 @@
         # THEN
         self.assertEqual(timestamp_seconds, actual_timestamp_seconds)
 
-    def test_should_return_timestamp_ticks_value_when_timestamp_ticks_property_is_called(self):
+    def test_should_return_timestamp_ticks_value_when_timestamp_ticks_property_is_called(
+        self):
         # GIVEN
         timestamp_ticks = any_timestamp_ticks()
 
-        pending_timestamp_obj = mle.PendingTimestamp(any_timestamp_seconds(), timestamp_ticks, any_u())
+        pending_timestamp_obj = mle.PendingTimestamp(any_timestamp_seconds(),
+                                                     timestamp_ticks, any_u())
 
         # WHEN
         actual_timestamp_ticks = pending_timestamp_obj.timestamp_ticks
@@ -1600,7 +1784,8 @@
         # GIVEN
         u = any_u()
 
-        pending_timestamp_obj = mle.PendingTimestamp(any_timestamp_seconds(), any_timestamp_ticks(), u)
+        pending_timestamp_obj = mle.PendingTimestamp(any_timestamp_seconds(),
+                                                     any_timestamp_ticks(), u)
 
         # WHEN
         actual_u = pending_timestamp_obj.u
@@ -1611,7 +1796,8 @@
 
 class TestPendingTimestampFactory(unittest.TestCase):
 
-    def test_should_create_PendingTimestamp_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_PendingTimestamp_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         timestamp_seconds = any_timestamp_seconds()
         timestamp_ticks = any_timestamp_ticks()
@@ -1619,7 +1805,8 @@
 
         factory = mle.PendingTimestampFactory()
 
-        data = struct.pack(">Q", timestamp_seconds)[2:] + struct.pack(">H", (timestamp_ticks << 1) | u)
+        data = struct.pack(">Q", timestamp_seconds)[2:] + struct.pack(
+            ">H", (timestamp_ticks << 1) | u)
 
         # WHEN
         pending_timestamp = factory.parse(io.BytesIO(data), dict())
@@ -1633,16 +1820,18 @@
 
 class TestMleCommandFactory(unittest.TestCase):
 
-    def test_should_create_MleCommand_from_bytearray_when_parse_method_is_called(self):
-        data = bytearray([0x0b, 0x04, 0x08, 0xa5, 0xf2, 0x9b, 0xde, 0xe3,
-                          0xd8, 0xbe, 0xb9, 0x05, 0x04, 0x00, 0x00, 0x00,
-                          0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
-                          0x01, 0x0d, 0x02, 0x04, 0x00, 0x00, 0x00, 0xf0,
-                          0x12, 0x02, 0x00, 0x02, 0x13, 0x09, 0x80, 0x86,
-                          0xa2, 0x1b, 0x81, 0x6d, 0xb8, 0xb5, 0xe8, 0x0d,
-                          0x03, 0x0a, 0x0c, 0x09])
+    def test_should_create_MleCommand_from_bytearray_when_parse_method_is_called(
+        self):
+        data = bytearray([
+            0x0b, 0x04, 0x08, 0xa5, 0xf2, 0x9b, 0xde, 0xe3, 0xd8, 0xbe, 0xb9,
+            0x05, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00,
+            0x01, 0x01, 0x01, 0x0d, 0x02, 0x04, 0x00, 0x00, 0x00, 0xf0, 0x12,
+            0x02, 0x00, 0x02, 0x13, 0x09, 0x80, 0x86, 0xa2, 0x1b, 0x81, 0x6d,
+            0xb8, 0xb5, 0xe8, 0x0d, 0x03, 0x0a, 0x0c, 0x09
+        ])
 
-        factory = mle.MleCommandFactory(config.create_default_mle_tlvs_factories())
+        factory = mle.MleCommandFactory(
+            config.create_default_mle_tlvs_factories())
 
         # WHEN
         actual_mle_command = factory.parse(io.BytesIO(data), None)
@@ -1652,30 +1841,40 @@
 
         self.assertEqual(11, actual_mle_command.type)
 
-        self.assertEqual(mle.Response(bytearray([0xa5, 0xf2, 0x9b, 0xde, 0xe3, 0xd8, 0xbe, 0xb9])),
-                         actual_mle_command.tlvs[0])
+        self.assertEqual(
+            mle.Response(
+                bytearray([0xa5, 0xf2, 0x9b, 0xde, 0xe3, 0xd8, 0xbe, 0xb9])),
+            actual_mle_command.tlvs[0])
 
-        self.assertEqual(mle.LinkLayerFrameCounter(0), actual_mle_command.tlvs[1])
+        self.assertEqual(mle.LinkLayerFrameCounter(0),
+                         actual_mle_command.tlvs[1])
 
         self.assertEqual(mle.MleFrameCounter(1), actual_mle_command.tlvs[2])
 
-        self.assertEqual(mle.Mode(receiver=1, secure=1, device_type=0, network_data=1),
-                         actual_mle_command.tlvs[3])
+        self.assertEqual(
+            mle.Mode(receiver=1, secure=1, device_type=0, network_data=1),
+            actual_mle_command.tlvs[3])
 
         self.assertEqual(mle.Timeout(240), actual_mle_command.tlvs[4])
 
         self.assertEqual(mle.Version(2), actual_mle_command.tlvs[5])
 
-        self.assertEqual(mle.AddressRegistration(addresses=[
-            mle.AddressCompressed(cid=0, iid=bytearray([0x86, 0xa2, 0x1b, 0x81, 0x6d, 0xb8, 0xb5, 0xe8]))]),
-            actual_mle_command.tlvs[6])
+        self.assertEqual(
+            mle.AddressRegistration(addresses=[
+                mle.AddressCompressed(
+                    cid=0,
+                    iid=bytearray(
+                        [0x86, 0xa2, 0x1b, 0x81, 0x6d, 0xb8, 0xb5, 0xe8]))
+            ]), actual_mle_command.tlvs[6])
 
-        self.assertEqual(mle.TlvRequest(tlvs=[10, 12, 9]), actual_mle_command.tlvs[7])
+        self.assertEqual(mle.TlvRequest(tlvs=[10, 12, 9]),
+                         actual_mle_command.tlvs[7])
 
 
 class TestMleMessageFactory(unittest.TestCase):
 
-    def test_should_create_MleMessageSecured_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_MleMessageSecured_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         message_info = common.MessageInfo()
         message_info.source_ipv6 = "fe80::10cf:d38b:3b61:5558"
@@ -1686,17 +1885,18 @@
         message_info.destination_mac_address = common.MacAddress.from_eui64(
             bytearray([0x3a, 0x3e, 0x9e, 0xed, 0x7a, 0x01, 0x36, 0xa5]))
 
-        data = bytearray([0x00, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                          0x00, 0x01, 0x14, 0x03, 0xe3, 0x72, 0x50, 0x4f,
-                          0x8c, 0x5c, 0x42, 0x81, 0x68, 0xe2, 0x11, 0xfc,
-                          0xf5, 0x8c, 0x62, 0x8e, 0x83, 0x99, 0xe7, 0x26,
-                          0x86, 0x34, 0x3b, 0xa7, 0x68, 0xc7, 0x93, 0xfb,
-                          0x72, 0xd9, 0xcc, 0x13, 0x5e, 0x5b, 0x96, 0x0e,
-                          0xf1, 0x80, 0x03, 0x55, 0x4f, 0x27, 0xc2, 0x96,
-                          0xf4, 0x9c, 0x65, 0x82, 0x97, 0xcf, 0x97, 0x35,
-                          0x89, 0xc2])
+        data = bytearray([
+            0x00, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+            0x14, 0x03, 0xe3, 0x72, 0x50, 0x4f, 0x8c, 0x5c, 0x42, 0x81, 0x68,
+            0xe2, 0x11, 0xfc, 0xf5, 0x8c, 0x62, 0x8e, 0x83, 0x99, 0xe7, 0x26,
+            0x86, 0x34, 0x3b, 0xa7, 0x68, 0xc7, 0x93, 0xfb, 0x72, 0xd9, 0xcc,
+            0x13, 0x5e, 0x5b, 0x96, 0x0e, 0xf1, 0x80, 0x03, 0x55, 0x4f, 0x27,
+            0xc2, 0x96, 0xf4, 0x9c, 0x65, 0x82, 0x97, 0xcf, 0x97, 0x35, 0x89,
+            0xc2
+        ])
 
-        factory = config.create_default_mle_message_factory(master_key=config.DEFAULT_MASTER_KEY)
+        factory = config.create_default_mle_message_factory(
+            master_key=config.DEFAULT_MASTER_KEY)
 
         # WHEN
         actual_mle_message = factory.parse(io.BytesIO(data), message_info)
@@ -1706,29 +1906,40 @@
 
         self.assertEqual(11, actual_mle_message.command.type)
 
-        self.assertEqual(mle.Response(bytearray([0xa5, 0xf2, 0x9b, 0xde, 0xe3, 0xd8, 0xbe, 0xb9])),
-                         actual_mle_message.command.tlvs[0])
+        self.assertEqual(
+            mle.Response(
+                bytearray([0xa5, 0xf2, 0x9b, 0xde, 0xe3, 0xd8, 0xbe, 0xb9])),
+            actual_mle_message.command.tlvs[0])
 
-        self.assertEqual(mle.LinkLayerFrameCounter(0), actual_mle_message.command.tlvs[1])
+        self.assertEqual(mle.LinkLayerFrameCounter(0),
+                         actual_mle_message.command.tlvs[1])
 
-        self.assertEqual(mle.MleFrameCounter(1), actual_mle_message.command.tlvs[2])
+        self.assertEqual(mle.MleFrameCounter(1),
+                         actual_mle_message.command.tlvs[2])
 
-        self.assertEqual(mle.Mode(receiver=1, secure=1, device_type=0, network_data=1),
-                         actual_mle_message.command.tlvs[3])
+        self.assertEqual(
+            mle.Mode(receiver=1, secure=1, device_type=0, network_data=1),
+            actual_mle_message.command.tlvs[3])
 
         self.assertEqual(mle.Timeout(240), actual_mle_message.command.tlvs[4])
 
         self.assertEqual(mle.Version(2), actual_mle_message.command.tlvs[5])
 
-        self.assertEqual(mle.AddressRegistration(addresses=[
-            mle.AddressCompressed(cid=0, iid=bytearray([0x86, 0xa2, 0x1b, 0x81, 0x6d, 0xb8, 0xb5, 0xe8]))]),
-            actual_mle_message.command.tlvs[6])
+        self.assertEqual(
+            mle.AddressRegistration(addresses=[
+                mle.AddressCompressed(
+                    cid=0,
+                    iid=bytearray(
+                        [0x86, 0xa2, 0x1b, 0x81, 0x6d, 0xb8, 0xb5, 0xe8]))
+            ]), actual_mle_message.command.tlvs[6])
 
-        self.assertEqual(mle.TlvRequest(tlvs=[10, 12, 9]), actual_mle_message.command.tlvs[7])
+        self.assertEqual(mle.TlvRequest(tlvs=[10, 12, 9]),
+                         actual_mle_message.command.tlvs[7])
 
         self.assertEqual(bytearray(data[-4:]), actual_mle_message.mic)
 
-    def test_should_create_MleMessageSecured_with_MLE_Data_Response_from_bytearray_when_parse_method_is_called(self):
+    def test_should_create_MleMessageSecured_with_MLE_Data_Response_from_bytearray_when_parse_method_is_called(
+        self):
         # GIVEN
         message_info = common.MessageInfo()
         message_info.source_ipv6 = "fe80::241c:b11b:7b62:caf1"
@@ -1739,15 +1950,16 @@
         message_info.destination_mac_address = common.MacAddress.from_eui64(
             bytearray([0x3a, 0xba, 0xad, 0xca, 0xfe, 0xde, 0xff, 0xa5]))
 
-        data = bytearray([0x00, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
-                          0x00, 0x00, 0x01, 0xca, 0xd3, 0x45, 0xe2, 0x35,
-                          0x1d, 0x00, 0x2d, 0x72, 0x71, 0xb1, 0x19, 0xaf,
-                          0x8b, 0x05, 0xd9, 0x52, 0x74, 0xce, 0xe6, 0x36,
-                          0x53, 0xeb, 0xc6, 0x25, 0x94, 0x01, 0x6d, 0x20,
-                          0xdf, 0x30, 0x82, 0xf8, 0xbb, 0x34, 0x47, 0x42,
-                          0x50, 0xe9, 0x41, 0xa7, 0x33, 0xa5])
+        data = bytearray([
+            0x00, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+            0xca, 0xd3, 0x45, 0xe2, 0x35, 0x1d, 0x00, 0x2d, 0x72, 0x71, 0xb1,
+            0x19, 0xaf, 0x8b, 0x05, 0xd9, 0x52, 0x74, 0xce, 0xe6, 0x36, 0x53,
+            0xeb, 0xc6, 0x25, 0x94, 0x01, 0x6d, 0x20, 0xdf, 0x30, 0x82, 0xf8,
+            0xbb, 0x34, 0x47, 0x42, 0x50, 0xe9, 0x41, 0xa7, 0x33, 0xa5
+        ])
 
-        factory = config.create_default_mle_message_factory(master_key=config.DEFAULT_MASTER_KEY)
+        factory = config.create_default_mle_message_factory(
+            master_key=config.DEFAULT_MASTER_KEY)
 
         # WHEN
         actual_mle_message = factory.parse(io.BytesIO(data), message_info)
@@ -1757,29 +1969,40 @@
 
         self.assertEqual(8, actual_mle_message.command.type)
 
-        self.assertEqual(mle.SourceAddress(address=0x9400), actual_mle_message.command.tlvs[0])
+        self.assertEqual(mle.SourceAddress(address=0x9400),
+                         actual_mle_message.command.tlvs[0])
 
-        self.assertEqual(mle.LeaderData(
-            partition_id=0x06d014ca,
-            weighting=64,
-            data_version=131,
-            stable_data_version=168,
-            leader_router_id=37
-        ), actual_mle_message.command.tlvs[1])
+        self.assertEqual(
+            mle.LeaderData(partition_id=0x06d014ca,
+                           weighting=64,
+                           data_version=131,
+                           stable_data_version=168,
+                           leader_router_id=37),
+            actual_mle_message.command.tlvs[1])
 
-        self.assertEqual(mle.NetworkData(tlvs=[
-            network_data.Prefix(
-                domain_id=0,
-                prefix_length=64,
-                prefix=bytearray([0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34]),
-                sub_tlvs=[
-                    network_data.LowpanId(c=1, cid=1, context_length=64, stable=1),
-                    network_data.BorderRouter(border_router_16=37888, prf=0, p=1,
-                                              s=1, d=0, c=0, r=1, o=1, n=0, stable=1)
-                ],
-                stable=1
-            )
-        ]), actual_mle_message.command.tlvs[2])
+        self.assertEqual(
+            mle.NetworkData(tlvs=[
+                network_data.Prefix(
+                    domain_id=0,
+                    prefix_length=64,
+                    prefix=bytearray(
+                        [0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34]),
+                    sub_tlvs=[
+                        network_data.LowpanId(
+                            c=1, cid=1, context_length=64, stable=1),
+                        network_data.BorderRouter(border_router_16=37888,
+                                                  prf=0,
+                                                  p=1,
+                                                  s=1,
+                                                  d=0,
+                                                  c=0,
+                                                  r=1,
+                                                  o=1,
+                                                  n=0,
+                                                  stable=1)
+                    ],
+                    stable=1)
+            ]), actual_mle_message.command.tlvs[2])
 
         self.assertEqual(bytearray(data[-4:]), actual_mle_message.mic)
 
diff --git a/tests/scripts/thread-cert/test_network_data.py b/tests/scripts/thread-cert/test_network_data.py
index 552cc04..e3e8e3f 100755
--- a/tests/scripts/thread-cert/test_network_data.py
+++ b/tests/scripts/thread-cert/test_network_data.py
@@ -39,9 +39,7 @@
 
 
 def convert_route_to_bytearray(route):
-    return struct.pack(
-        ">HB", route.border_router_16, ((route.prf & 0x03) << 6)
-    )
+    return struct.pack(">HB", route.border_router_16, ((route.prf & 0x03) << 6))
 
 
 def convert_routes_to_bytearray(routes):
@@ -60,13 +58,10 @@
     data = struct.pack(
         ">HBB",
         border_router.border_router_16,
-        (border_router.o & 0x01)
-        | ((border_router.r & 0x01) << 1)
-        | ((border_router.c & 0x01) << 2)
-        | ((border_router.d & 0x01) << 3)
-        | ((border_router.s & 0x01) << 4)
-        | ((border_router.p & 0x01) << 5)
-        | ((border_router.prf & 0x03) << 6),
+        (border_router.o & 0x01) | ((border_router.r & 0x01) << 1) |
+        ((border_router.c & 0x01) << 2) | ((border_router.d & 0x01) << 3) |
+        ((border_router.s & 0x01) << 4) | ((border_router.p & 0x01) << 5) |
+        ((border_router.prf & 0x03) << 6),
         ((border_router.n & 0x01) << 7),
     )
 
@@ -75,8 +70,7 @@
 
 def convert_lowpan_id_to_bytearray(lowpan_id):
     return bytearray(
-        [lowpan_id.cid | (lowpan_id.c << 4), lowpan_id.context_length]
-    )
+        [lowpan_id.cid | (lowpan_id.c << 4), lowpan_id.context_length])
 
 
 def convert_prefix_sub_tlvs_to_bytearray(sub_tlvs):
@@ -124,16 +118,13 @@
 
 
 def convert_service_to_bytearray(service):
-    return (
-        struct.pack(
-            ">BLB",
-            ((service.t & 0x01) << 7) | ((service.id) & 0x0F),
-            service.enterprise_number,
-            service.service_data_length,
-        )
-        + service.service_data
-        + convert_service_sub_tlvs_to_bytearray(service.sub_tlvs)
-    )
+    return (struct.pack(
+        ">BLB",
+        ((service.t & 0x01) << 7) | ((service.id) & 0x0F),
+        service.enterprise_number,
+        service.service_data_length,
+    ) + service.service_data +
+            convert_service_sub_tlvs_to_bytearray(service.sub_tlvs))
 
 
 def any_border_router_16():
@@ -171,12 +162,9 @@
     if prefix_length is None:
         prefix_length = any_prefix_length()
 
-    return bytearray(
-        [
-            random.getrandbits(8)
-            for _ in range(int(math.ceil(prefix_length / 8)))
-        ]
-    )
+    return bytearray([
+        random.getrandbits(8) for _ in range(int(math.ceil(prefix_length / 8)))
+    ])
 
 
 def any_p():
@@ -231,9 +219,8 @@
 
 
 def any_lowpan_id():
-    return network_data.LowpanId(
-        any_c(), any_cid(), any_context_length(), any_stable()
-    )
+    return network_data.LowpanId(any_c(), any_cid(), any_context_length(),
+                                 any_stable())
 
 
 def any_prefix_sub_tlvs():
@@ -283,9 +270,7 @@
 
 
 def any_server():
-    return network_data.Server(
-        any_server_16(), any_server_data(), any_stable()
-    )
+    return network_data.Server(any_server_16(), any_server_data(), any_stable())
 
 
 def any_service_sub_tlvs():
@@ -305,8 +290,9 @@
 
 
 class TestRoute(unittest.TestCase):
+
     def test_should_return_border_router_16_value_when_border_router_16_property_is_called(
-            self):
+        self):
         # GIVEN
         border_router_16 = any_border_router_16()
 
@@ -332,9 +318,9 @@
 
 
 class TestRouteFactory(unittest.TestCase):
+
     def test_should_create_Route_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         border_router_16 = any_border_router_16()
         prf = any_prf()
@@ -342,8 +328,7 @@
         factory = network_data.RouteFactory()
 
         data = convert_route_to_bytearray(
-            network_data.Route(border_router_16, prf)
-        )
+            network_data.Route(border_router_16, prf))
 
         # WHEN
         actual_route = factory.parse(io.BytesIO(data), None)
@@ -355,8 +340,9 @@
 
 
 class TestRoutesFactory(unittest.TestCase):
+
     def test_should_create_Route_list_from_bytearray_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
         routes = any_routes()
 
@@ -372,6 +358,7 @@
 
 
 class TestHasRoute(unittest.TestCase):
+
     def test_should_return_routes_value_when_routes_property_is_called(self):
         # GIVEN
         routes = any_routes()
@@ -398,16 +385,15 @@
 
 
 class TestHasRouteFactory(unittest.TestCase):
+
     def test_should_create_HasRoute_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         routes = any_routes()
         stable = any_stable()
 
         factory = network_data.HasRouteFactory(
-            network_data.RoutesFactory(network_data.RouteFactory())
-        )
+            network_data.RoutesFactory(network_data.RouteFactory()))
 
         data = convert_routes_to_bytearray(routes)
 
@@ -424,9 +410,9 @@
 
 
 class TestPrefix(unittest.TestCase):
+
     def test_should_return_domain_id_value_when_domain_id_property_is_called(
-        self
-    ):
+        self):
         # GIVEN
         domain_id = any_domain_id()
 
@@ -445,7 +431,7 @@
         self.assertEqual(domain_id, actual_domain_id)
 
     def test_should_return_prefix_length_value_when_prefix_length_property_is_called(
-            self):
+        self):
         # GIVEN
         prefix_length = any_prefix_length()
 
@@ -482,8 +468,7 @@
         self.assertEqual(prefix, actual_prefix)
 
     def test_should_return_sub_tlvs_value_when_sub_tlvs_property_is_called(
-        self
-    ):
+        self):
         # GIVEN
         sub_tlvs = any_prefix_sub_tlvs()
 
@@ -521,15 +506,14 @@
 
 
 class TestPrefixSubTlvsFactory(unittest.TestCase):
+
     def test_should_create_SubTlvs_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         sub_tlvs = any_prefix_sub_tlvs()
 
         factory = network_data.PrefixSubTlvsFactory(
-            config.create_default_network_data_prefix_sub_tlvs_factories()
-        )
+            config.create_default_network_data_prefix_sub_tlvs_factories())
 
         data = convert_prefix_sub_tlvs_to_bytearray(sub_tlvs)
 
@@ -542,9 +526,9 @@
 
 
 class TestPrefixFactory(unittest.TestCase):
+
     def test_should_create_Prefix_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         domain_id = any_domain_id()
         prefix_length = any_prefix_length()
@@ -552,14 +536,10 @@
         sub_tlvs = any_prefix_sub_tlvs()
 
         factory = network_data.PrefixFactory(
-            config.create_default_network_data_prefix_sub_tlvs_factory()
-        )
+            config.create_default_network_data_prefix_sub_tlvs_factory())
 
-        data = (
-            bytearray([domain_id, prefix_length])
-            + prefix
-            + convert_prefix_sub_tlvs_to_bytearray(sub_tlvs)
-        )
+        data = (bytearray([domain_id, prefix_length]) + prefix +
+                convert_prefix_sub_tlvs_to_bytearray(sub_tlvs))
 
         message_info = common.MessageInfo()
 
@@ -575,8 +555,9 @@
 
 
 class TestBorderRouter(unittest.TestCase):
+
     def test_should_return_border_router_16_value_when_border_router_16_property_is_called(
-            self):
+        self):
         # GIVEN
         border_router_16 = any_border_router_16()
 
@@ -808,8 +789,9 @@
 
 
 class TestBorderRouterFactory(unittest.TestCase):
+
     def test_should_create_BorderRouter_from_bytearray_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
         border_router_16 = any_border_router_16()
         prf = any_prf()
@@ -825,10 +807,8 @@
         factory = network_data.BorderRouterFactory()
 
         data = convert_border_router_to_bytearray(
-            network_data.BorderRouter(
-                border_router_16, prf, p, s, d, c, r, o, n, stable
-            )
-        )
+            network_data.BorderRouter(border_router_16, prf, p, s, d, c, r, o,
+                                      n, stable))
 
         message_info = common.MessageInfo()
         message_info.stable = stable
@@ -838,11 +818,9 @@
 
         # THEN
         self.assertTrue(
-            isinstance(actual_border_router, network_data.BorderRouter)
-        )
-        self.assertEqual(
-            border_router_16, actual_border_router.border_router_16
-        )
+            isinstance(actual_border_router, network_data.BorderRouter))
+        self.assertEqual(border_router_16,
+                         actual_border_router.border_router_16)
         self.assertEqual(prf, actual_border_router.prf)
         self.assertEqual(p, actual_border_router.p)
         self.assertEqual(s, actual_border_router.s)
@@ -855,13 +833,13 @@
 
 
 class TestLowpanId(unittest.TestCase):
+
     def test_should_return_c_value_when_c_property_is_called(self):
         # GIVEN
         c = any_c()
 
-        lowpan_id = network_data.LowpanId(
-            c, any_cid(), any_context_length(), any_stable()
-        )
+        lowpan_id = network_data.LowpanId(c, any_cid(), any_context_length(),
+                                          any_stable())
 
         # WHEN
         actual_c = lowpan_id.c
@@ -873,9 +851,8 @@
         # GIVEN
         cid = any_cid()
 
-        lowpan_id = network_data.LowpanId(
-            any_c(), cid, any_context_length(), any_stable()
-        )
+        lowpan_id = network_data.LowpanId(any_c(), cid, any_context_length(),
+                                          any_stable())
 
         # WHEN
         actual_cid = lowpan_id.cid
@@ -884,13 +861,12 @@
         self.assertEqual(cid, actual_cid)
 
     def test_should_return_context_length_value_when_context_length_property_is_called(
-            self):
+        self):
         # GIVEN
         context_length = any_context_length()
 
-        lowpan_id = network_data.LowpanId(
-            any_c(), any_cid(), context_length, any_stable()
-        )
+        lowpan_id = network_data.LowpanId(any_c(), any_cid(), context_length,
+                                          any_stable())
 
         # WHEN
         actual_context_length = lowpan_id.context_length
@@ -902,9 +878,8 @@
         # GIVEN
         stable = any_stable()
 
-        lowpan_id = network_data.LowpanId(
-            any_c(), any_cid(), any_context_length(), stable
-        )
+        lowpan_id = network_data.LowpanId(any_c(), any_cid(),
+                                          any_context_length(), stable)
 
         # WHEN
         actual_stable = lowpan_id.stable
@@ -914,9 +889,9 @@
 
 
 class TestLowpanIdFactory(unittest.TestCase):
+
     def test_should_create_LowpanId_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         c = any_c()
         cid = any_cid()
@@ -926,8 +901,7 @@
         factory = network_data.LowpanIdFactory()
 
         data = convert_lowpan_id_to_bytearray(
-            network_data.LowpanId(c, cid, context_length, stable)
-        )
+            network_data.LowpanId(c, cid, context_length, stable))
 
         message_info = common.MessageInfo()
         message_info.stable = stable
@@ -943,6 +917,7 @@
 
 
 class TestService(unittest.TestCase):
+
     def test_should_return_t_value_when_t_property_is_called(self):
         # GIVEN
         t = any_t()
@@ -984,7 +959,7 @@
         self.assertEqual(_id, actual_id)
 
     def test_should_return_enterprise_number_value_when_enterprise_number_property_is_called(
-            self):
+        self):
         # GIVEN
         enterprise_number = any_enterprise_number()
 
@@ -1005,7 +980,7 @@
         self.assertEqual(enterprise_number, actual_enterprise_number)
 
     def test_should_return_service_data_length_value_when_service_data_length_property_is_called(
-            self):
+        self):
         # GIVEN
         service_data_length = any_service_data_length()
 
@@ -1026,7 +1001,7 @@
         self.assertEqual(service_data_length, actual_service_data_length)
 
     def test_should_return_service_data_value_when_service_data_property_is_called(
-            self):
+        self):
         # GIVEN
         service_data = any_service_data()
 
@@ -1047,8 +1022,7 @@
         self.assertEqual(service_data, actual_service_data)
 
     def test_should_return_sub_tlvs_value_when_sub_tlvs_property_is_called(
-        self
-    ):
+        self):
         # GIVEN
         sub_tlvs = any_service_sub_tlvs()
 
@@ -1090,15 +1064,14 @@
 
 
 class TestServiceSubTlvsFactory(unittest.TestCase):
+
     def test_should_create_SubTlvs_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         sub_tlvs = any_service_sub_tlvs()
 
         factory = network_data.ServiceSubTlvsFactory(
-            config.create_default_network_data_service_sub_tlvs_factories()
-        )
+            config.create_default_network_data_service_sub_tlvs_factories())
 
         data = convert_service_sub_tlvs_to_bytearray(sub_tlvs)
 
@@ -1111,9 +1084,9 @@
 
 
 class TestServiceFactory(unittest.TestCase):
+
     def test_should_create_Service_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         t = any_t()
         _id = any_id()
@@ -1124,8 +1097,7 @@
         stable = any_stable()
 
         factory = network_data.ServiceFactory(
-            config.create_default_network_data_service_sub_tlvs_factory()
-        )
+            config.create_default_network_data_service_sub_tlvs_factory())
 
         data = convert_service_to_bytearray(
             network_data.Service(
@@ -1136,8 +1108,7 @@
                 service_data,
                 sub_tlvs,
                 stable,
-            )
-        )
+            ))
 
         message_info = common.MessageInfo()
         message_info.stable = stable
@@ -1150,23 +1121,20 @@
         self.assertEqual(t, actual_service.t)
         self.assertEqual(_id, actual_service.id)
         self.assertEqual(enterprise_number, actual_service.enterprise_number)
-        self.assertEqual(
-            service_data_length, actual_service.service_data_length
-        )
+        self.assertEqual(service_data_length,
+                         actual_service.service_data_length)
         self.assertEqual(service_data, actual_service.service_data)
         self.assertEqual(sub_tlvs, actual_service.sub_tlvs)
 
 
 class TestServer(unittest.TestCase):
+
     def test_should_return_server_16_value_when_server_16_property_is_called(
-        self
-    ):
+        self):
         # GIVEN
         server_16 = any_server_16()
 
-        server = network_data.Server(
-            server_16, any_server_data(), any_stable()
-        )
+        server = network_data.Server(server_16, any_server_data(), any_stable())
 
         # WHEN
         actual_server_16 = server.server_16
@@ -1175,13 +1143,11 @@
         self.assertEqual(server_16, actual_server_16)
 
     def test_should_return_server_data_value_when_server_data_property_is_called(
-            self):
+        self):
         # GIVEN
         server_data = any_server_data()
 
-        server = network_data.Server(
-            any_server_16(), server_data, any_stable()
-        )
+        server = network_data.Server(any_server_16(), server_data, any_stable())
 
         # WHEN
         actual_server_data = server.server_data
@@ -1193,9 +1159,7 @@
         # GIVEN
         stable = any_stable()
 
-        server = network_data.Server(
-            any_server_16(), any_server_data(), stable
-        )
+        server = network_data.Server(any_server_16(), any_server_data(), stable)
 
         # WHEN
         actual_stable = server.stable
@@ -1205,9 +1169,9 @@
 
 
 class TestServerFactory(unittest.TestCase):
+
     def test_should_create_Server_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         server_16 = any_server_16()
         server_data = any_server_data()
@@ -1216,8 +1180,7 @@
         factory = network_data.ServerFactory()
 
         data = convert_server_to_bytearray(
-            network_data.Server(server_16, server_data, stable)
-        )
+            network_data.Server(server_16, server_data, stable))
 
         message_info = common.MessageInfo()
         message_info.stable = stable
diff --git a/tests/scripts/thread-cert/test_network_layer.py b/tests/scripts/thread-cert/test_network_layer.py
index 93cae84..95c6861 100755
--- a/tests/scripts/thread-cert/test_network_layer.py
+++ b/tests/scripts/thread-cert/test_network_layer.py
@@ -92,6 +92,7 @@
 
 
 class TestTargetEid(unittest.TestCase):
+
     def test_should_return_eid_value_when_eid_property_is_called(self):
         # GIVEN
         eid = any_eid()
@@ -105,7 +106,7 @@
         self.assertEqual(eid, actual_eid)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         eid = any_eid()
 
@@ -116,8 +117,9 @@
 
 
 class TestTargetEidFactory(unittest.TestCase):
+
     def test_should_create_TargetEid_from_bytearray_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
         eid = any_eid()
 
@@ -132,8 +134,9 @@
 
 
 class TestMacExtendedAddress(unittest.TestCase):
+
     def test_should_return_mac_address_value_when_mac_address_property_is_called(
-            self):
+        self):
         # GIVEN
         mac_address = any_mac_extended_address()
 
@@ -146,39 +149,38 @@
         self.assertEqual(mac_address, actual_mac_address)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         mac_address = any_mac_extended_address()
 
         mac_extended_address = network_layer.MacExtendedAddress(mac_address)
 
         # THEN
-        self.assertEqual(
-            mac_extended_address, network_layer.MacExtendedAddress(mac_address)
-        )
+        self.assertEqual(mac_extended_address,
+                         network_layer.MacExtendedAddress(mac_address))
 
 
 class TestMacExtendedAddressFactory(unittest.TestCase):
+
     def test_should_create_MacExtendedAddress_from_bytearray_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
         mac_address = any_mac_extended_address()
 
         factory = network_layer.MacExtendedAddressFactory()
 
         # WHEN
-        mac_extended_address = factory.parse(
-            io.BytesIO(mac_address), common.MessageInfo()
-        )
+        mac_extended_address = factory.parse(io.BytesIO(mac_address),
+                                             common.MessageInfo())
 
         # THEN
         self.assertTrue(
-            isinstance(mac_extended_address, network_layer.MacExtendedAddress)
-        )
+            isinstance(mac_extended_address, network_layer.MacExtendedAddress))
         self.assertEqual(mac_address, mac_extended_address.mac_address)
 
 
 class TestRloc16(unittest.TestCase):
+
     def test_should_return_rloc16_value_when_rloc16_property_is_called(self):
         # GIVEN
         rloc16 = any_rloc16()
@@ -192,7 +194,7 @@
         self.assertEqual(rloc16, actual_rloc16)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         rloc16 = any_rloc16()
 
@@ -203,9 +205,9 @@
 
 
 class TestRloc16Factory(unittest.TestCase):
+
     def test_should_create_Rloc16_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         rloc16 = any_rloc16()
 
@@ -222,6 +224,7 @@
 
 
 class TestMlEid(unittest.TestCase):
+
     def test_should_return_ml_eid_value_when_ml_eid_property_is_called(self):
         # GIVEN
         ml_eid = any_ml_eid()
@@ -235,7 +238,7 @@
         self.assertEqual(ml_eid, actual_ml_eid)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         ml_eid = any_ml_eid()
 
@@ -246,9 +249,9 @@
 
 
 class TestMlEidFactory(unittest.TestCase):
+
     def test_should_create_MlEid_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         ml_eid = any_ml_eid()
 
@@ -263,6 +266,7 @@
 
 
 class TestStatus(unittest.TestCase):
+
     def test_should_return_status_value_when_status_property_is_called(self):
         # GIVEN
         status = any_status()
@@ -276,7 +280,7 @@
         self.assertEqual(status, actual_status)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         status = any_status()
 
@@ -287,9 +291,9 @@
 
 
 class TestStatusFactory(unittest.TestCase):
+
     def test_should_create_Status_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         status = any_status()
 
@@ -306,13 +310,13 @@
 
 
 class TestTimeSinceLastTransaction(unittest.TestCase):
+
     def test_should_return_seconds_value_when_seconds_property_is_called(self):
         # GIVEN
         seconds = any_seconds()
 
         time_since_last_transaction = network_layer.TimeSinceLastTransaction(
-            seconds
-        )
+            seconds)
 
         # WHEN
         actual_seconds = time_since_last_transaction.seconds
@@ -321,13 +325,12 @@
         self.assertEqual(seconds, actual_seconds)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         seconds = any_seconds()
 
         time_since_last_transaction = network_layer.TimeSinceLastTransaction(
-            seconds
-        )
+            seconds)
 
         # THEN
         self.assertEqual(
@@ -337,8 +340,9 @@
 
 
 class TestTimeSinceLastTransactionFactory(unittest.TestCase):
+
     def test_should_create_TimeSinceLastTransaction_from_bytearray_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
         seconds = any_seconds()
 
@@ -347,29 +351,27 @@
         data = bytearray(struct.pack(">L", seconds))
 
         # WHEN
-        time_since_last_transaction = factory.parse(
-            io.BytesIO(data), common.MessageInfo()
-        )
+        time_since_last_transaction = factory.parse(io.BytesIO(data),
+                                                    common.MessageInfo())
 
         # THEN
         self.assertTrue(
             isinstance(
                 time_since_last_transaction,
                 network_layer.TimeSinceLastTransaction,
-            )
-        )
+            ))
         self.assertEqual(seconds, time_since_last_transaction.seconds)
 
 
 class TestRouterMask(unittest.TestCase):
+
     def test_should_return_id_sequence_value_when_id_sequence_property_is_called(
-            self):
+        self):
         # GIVEN
         id_sequence = any_id_sequence()
 
-        router_mask = network_layer.RouterMask(
-            id_sequence, any_router_id_mask()
-        )
+        router_mask = network_layer.RouterMask(id_sequence,
+                                               any_router_id_mask())
 
         # WHEN
         actual_id_sequence = router_mask.id_sequence
@@ -378,13 +380,12 @@
         self.assertEqual(id_sequence, actual_id_sequence)
 
     def test_should_return_router_id_mask_value_when_router_id_mask_property_is_called(
-            self):
+        self):
         # GIVEN
         router_id_mask = any_router_id_mask()
 
-        router_mask = network_layer.RouterMask(
-            any_id_sequence(), router_id_mask
-        )
+        router_mask = network_layer.RouterMask(any_id_sequence(),
+                                               router_id_mask)
 
         # WHEN
         actual_router_id_mask = router_mask.router_id_mask
@@ -393,7 +394,7 @@
         self.assertEqual(router_id_mask, actual_router_id_mask)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         id_sequence = any_id_sequence()
         router_id_mask = any_router_id_mask()
@@ -401,14 +402,14 @@
         router_mask = network_layer.RouterMask(id_sequence, router_id_mask)
 
         # THEN
-        self.assertEqual(
-            router_mask, network_layer.RouterMask(id_sequence, router_id_mask)
-        )
+        self.assertEqual(router_mask,
+                         network_layer.RouterMask(id_sequence, router_id_mask))
 
 
 class TestRouterMaskFactory(unittest.TestCase):
+
     def test_should_create_RouterMask_from_bytearray_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
         id_sequence = any_id_sequence()
         router_id_mask = any_router_id_mask()
@@ -427,6 +428,7 @@
 
 
 class TestNdOption(unittest.TestCase):
+
     def test_should_return_options_value_when_options_property_is_called(self):
         # GIVEN
         options = any_options()
@@ -440,7 +442,7 @@
         self.assertEqual(options, actual_options)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         options = any_options()
 
@@ -451,9 +453,9 @@
 
 
 class TestNdOptionFactory(unittest.TestCase):
+
     def test_should_create_NdOption_from_bytearray_when_parse_method_is_called(
-        self
-    ):
+        self):
         # GIVEN
         options = any_options()
 
@@ -470,6 +472,7 @@
 
 
 class TestThreadNetworkData(unittest.TestCase):
+
     def test_should_return_options_value_when_options_property_is_called(self):
         # GIVEN
         tlvs = any_tlvs_data()
@@ -483,41 +486,39 @@
         self.assertEqual(tlvs, actual_tlvs)
 
     def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(
-            self):
+        self):
         # GIVEN
         tlvs = any_tlvs_data()
 
         thread_network_data = network_layer.ThreadNetworkData(tlvs)
 
         # THEN
-        self.assertEqual(
-            thread_network_data, network_layer.ThreadNetworkData(tlvs)
-        )
+        self.assertEqual(thread_network_data,
+                         network_layer.ThreadNetworkData(tlvs))
 
 
 class TestThreadNetworkDataFactory(unittest.TestCase):
+
     def test_should_create_ThreadNetworkData_from_bytearray_when_parse_method_is_called(
-            self):
+        self):
         # GIVEN
         tlvs = any_tlvs_data()
 
         class DummyNetworkDataTlvsFactory:
+
             def parse(self, data, message_info):
                 return bytearray(data.read())
 
         factory = network_layer.ThreadNetworkDataFactory(
-            DummyNetworkDataTlvsFactory()
-        )
+            DummyNetworkDataTlvsFactory())
 
         # WHEN
-        thread_network_data = factory.parse(
-            io.BytesIO(tlvs), common.MessageInfo()
-        )
+        thread_network_data = factory.parse(io.BytesIO(tlvs),
+                                            common.MessageInfo())
 
         # THEN
         self.assertTrue(
-            isinstance(thread_network_data, network_layer.ThreadNetworkData)
-        )
+            isinstance(thread_network_data, network_layer.ThreadNetworkData))
         self.assertEqual(tlvs, thread_network_data.tlvs)
 
 
diff --git a/tests/scripts/thread-cert/test_on_mesh_prefix.py b/tests/scripts/thread-cert/test_on_mesh_prefix.py
new file mode 100755
index 0000000..c2d0fd2
--- /dev/null
+++ b/tests/scripts/thread-cert/test_on_mesh_prefix.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import config
+import thread_cert
+
+LEADER = 1
+ROUTER = 2
+ED1 = 3
+SED1 = 4
+
+MTDS = [ED1, SED1]
+
+
+class Test_OnMeshPrefix(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED1, SED1]
+        },
+        ED1: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        SED1: {
+            'is_mtd': True,
+            'mode': 's',
+            'panid': 0xface,
+            'timeout': config.DEFAULT_CHILD_TIMEOUT,
+            'whitelist': [ROUTER]
+        },
+    }
+
+    def test(self):
+        self.nodes[LEADER].start()
+        self.simulator.go(4)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[ROUTER].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[ROUTER].get_state(), 'router')
+
+        self.nodes[ED1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[ED1].get_state(), 'child')
+
+        self.nodes[SED1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[SED1].get_state(), 'child')
+
+        self.nodes[ROUTER].add_prefix('2001:2:0:1::/64', 'paros')
+        self.nodes[ROUTER].add_prefix('2001:2:0:2::/64', 'paro')
+        self.nodes[ROUTER].register_netdata()
+
+        # Set lowpan context of sniffer
+        self.simulator.set_lowpan_context(1, '2001:2:0:1::/64')
+        self.simulator.set_lowpan_context(2, '2001:2:0:2::/64')
+
+        self.simulator.go(10)
+
+        addrs = self.nodes[ED1].get_addrs()
+        self.assertTrue(any('2001:2:0:1' in addr[0:10] for addr in addrs))
+        self.assertTrue(any('2001:2:0:2' in addr[0:10] for addr in addrs))
+        for addr in addrs:
+            if addr[0:3] == '200':
+                self.assertTrue(self.nodes[LEADER].ping(addr))
+
+        addrs = self.nodes[SED1].get_addrs()
+        self.assertTrue(any('2001:2:0:1' in addr[0:10] for addr in addrs))
+        self.assertFalse(any('2001:2:0:2' in addr[0:10] for addr in addrs))
+        for addr in addrs:
+            if addr[0:3] == '200':
+                self.assertTrue(self.nodes[LEADER].ping(addr))
+
+        self.nodes[ROUTER].add_prefix('2002:2:0:3::/64', 'pars')
+        self.nodes[ROUTER].register_netdata()
+
+        # Set lowpan context of sniffer
+        self.simulator.set_lowpan_context(3, '2002:2:0:3::/64')
+
+        self.simulator.go(10)
+
+        addrs = self.nodes[ED1].get_addrs()
+        self.assertTrue(any('2001:2:0:1' in addr[0:10] for addr in addrs))
+        self.assertTrue(any('2001:2:0:2' in addr[0:10] for addr in addrs))
+        self.assertTrue(any('2002:2:0:3' in addr[0:10] for addr in addrs))
+        for addr in addrs:
+            if addr[0:4] == '2001':
+                self.assertTrue(self.nodes[LEADER].ping(addr))
+            elif addr[0:4] == '2002':
+                self.assertFalse(self.nodes[LEADER].ping(addr))
+
+        addrs = self.nodes[SED1].get_addrs()
+        self.assertTrue(any('2001:2:0:1' in addr[0:10] for addr in addrs))
+        self.assertFalse(any('2001:2:0:2' in addr[0:10] for addr in addrs))
+        self.assertTrue(any('2002:2:0:3' in addr[0:10] for addr in addrs))
+        for addr in addrs:
+            if addr[0:4] == '2001':
+                self.assertTrue(self.nodes[LEADER].ping(addr))
+            elif addr[0:4] == '2002':
+                self.assertFalse(self.nodes[LEADER].ping(addr))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/test_reed_address_solicit_rejected.py b/tests/scripts/thread-cert/test_reed_address_solicit_rejected.py
new file mode 100755
index 0000000..9c18a78
--- /dev/null
+++ b/tests/scripts/thread-cert/test_reed_address_solicit_rejected.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import config
+import re
+import unittest
+
+import thread_cert
+
+LEADER = 1
+REED = 2
+
+SRV_0_ID = 0
+SRV_0_ENT_NUMBER = '123'
+SRV_0_SERVICE_DATA = 'foo'
+SRV_0_SERVER_DATA = 'bar'
+
+# Topology:
+# LEADER -- REED
+#
+
+
+class TestREEDAddressSolicitRejected(thread_cert.TestCase):
+    SUPPORT_NCP = False
+
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface
+        },
+        REED: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1
+        },
+    }
+
+    def testAddressSolicitRejectedBeforeSvrData(self):
+        self.nodes[LEADER].start()
+        self.nodes[LEADER].set_router_upgrade_threshold(1)
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[REED].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[REED].get_state(), 'child')
+
+        self.nodes[REED].add_service(SRV_0_ENT_NUMBER, SRV_0_SERVICE_DATA,
+                                     SRV_0_SERVER_DATA)
+        self.nodes[REED].register_netdata()
+        self.simulator.go(2)
+
+        self.assertEqual(self.hasAloc(REED, SRV_0_ID), True)
+
+    def testAddressSolicitRejectedAfterSvrData(self):
+        self.nodes[LEADER].start()
+        self.nodes[LEADER].set_router_upgrade_threshold(1)
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[REED].set_router_selection_jitter(120)
+        self.nodes[REED].start()
+        # set routerupgradethreshold=1 on REED so that it won't send ADDR_SOL.req
+        self.nodes[REED].set_router_upgrade_threshold(1)
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[REED].get_state(), 'child')
+
+        # restore routerupgradethreshold to 16 and add service
+        self.nodes[REED].set_router_upgrade_threshold(16)
+        self.nodes[REED].add_service(SRV_0_ENT_NUMBER, SRV_0_SERVICE_DATA,
+                                     SRV_0_SERVER_DATA)
+        self.nodes[REED].register_netdata()
+        self.simulator.go(130)
+        self.assertEqual(self.hasAloc(REED, SRV_0_ID), True)
+
+    def hasAloc(self, node_id, service_id):
+        for addr in self.nodes[node_id].get_ip6_address(
+                config.ADDRESS_TYPE.ALOC):
+            m = re.match('.*:fc(..)$', addr, re.I)
+            if m is not None:
+                if m.group(
+                        1) == str(service_id +
+                                  10):  # for service_id=3 look for '...:fc13'
+                    return True
+
+        return False
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/test_reset.py b/tests/scripts/thread-cert/test_reset.py
new file mode 100755
index 0000000..a87ddee
--- /dev/null
+++ b/tests/scripts/thread-cert/test_reset.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+import thread_cert
+
+LEADER = 1
+ROUTER = 2
+ED = 3
+SED = 4
+
+
+class TestReset(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+        ROUTER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ED]
+        },
+        ED: {
+            'is_mtd': True,
+            'mode': 'rsn',
+            'panid': 0xface,
+            'whitelist': [ROUTER]
+        },
+    }
+
+    def test(self):
+        self.nodes[LEADER].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[ROUTER].start()
+        self.simulator.go(7)
+        self.assertEqual(self.nodes[ROUTER].get_state(), 'router')
+
+        self.nodes[ED].start()
+        self.simulator.go(7)
+        self.assertEqual(self.nodes[ED].get_state(), 'child')
+
+        leader_addrs = self.nodes[LEADER].get_addrs()
+        router_addrs = self.nodes[ROUTER].get_addrs()
+
+        for i in range(0, 1010):
+            self.assertTrue(self.nodes[ED].ping(leader_addrs[0]))
+        self.simulator.go(1)
+
+        # 1 - Leader
+        self.nodes[LEADER].reset()
+        self.nodes[LEADER].start()
+        self.simulator.go(7)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        for addr in router_addrs:
+            self.assertTrue(self.nodes[LEADER].ping(addr))
+
+        # 2 - Router
+        self.nodes[ROUTER].reset()
+        self.nodes[ROUTER].start()
+        self.simulator.go(7)
+        self.assertEqual(self.nodes[ROUTER].get_state(), 'router')
+
+        for addr in leader_addrs:
+            self.assertTrue(self.nodes[ROUTER].ping(addr))
+
+        # 3 - Child
+        self.nodes[ED].reset()
+        self.nodes[ED].start()
+        self.simulator.go(7)
+        self.assertEqual(self.nodes[ED].get_state(), 'child')
+
+        for addr in router_addrs:
+            self.assertTrue(self.nodes[ED].ping(addr))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/test_route_table.py b/tests/scripts/thread-cert/test_route_table.py
index 18fecdc..42bf9ee 100755
--- a/tests/scripts/thread-cert/test_route_table.py
+++ b/tests/scripts/thread-cert/test_route_table.py
@@ -29,8 +29,7 @@
 
 import unittest
 
-import node
-import config
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -41,37 +40,26 @@
 #
 
 
-class TestRouteTable(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
-
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+class TestRouteTable(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'whitelist': [ROUTER1]
+        },
+        ROUTER1: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'mode': 'rsdn',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [ROUTER1]
+        },
+    }
 
     def test(self):
         self.nodes[LEADER].start()
@@ -92,7 +80,7 @@
 
         for _node in self.nodes.values():
             router_table = _node.router_table()
-            self.assertEqual(set(router_table.keys()), router_ids)
+            self.assertEqual(set(router_table), router_ids)
 
 
 if __name__ == '__main__':
diff --git a/tests/scripts/thread-cert/test_service.py b/tests/scripts/thread-cert/test_service.py
index b4dc97c..e7f91ec 100755
--- a/tests/scripts/thread-cert/test_service.py
+++ b/tests/scripts/thread-cert/test_service.py
@@ -30,8 +30,8 @@
 import re
 import unittest
 
-import node
 import config
+import thread_cert
 
 LEADER = 1
 ROUTER1 = 2
@@ -48,55 +48,43 @@
 SRV_1_SERVER_DATA = 'qux'
 
 
-class Test_Service(unittest.TestCase):
-    def setUp(self):
-        self.simulator = config.create_default_simulator()
+class Test_Service(thread_cert.TestCase):
+    SUPPORT_NCP = False
 
-        self.nodes = {}
-        for i in range(1, 4):
-            self.nodes[i] = node.Node(i, simulator=self.simulator)
-
-        self.nodes[LEADER].set_panid(0xface)
-        self.nodes[LEADER].set_mode('rsdn')
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[LEADER].enable_whitelist()
-        self.nodes[LEADER].set_channel(12)
-        self.nodes[LEADER].set_network_name('OpenThread')
-
-        self.nodes[ROUTER1].set_panid(0xface)
-        self.nodes[ROUTER1].set_mode('rsdn')
-        self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER2].get_addr64())
-        self.nodes[ROUTER1].enable_whitelist()
-        self.nodes[ROUTER1].set_channel(12)
-        self.nodes[ROUTER1].set_network_name('OpenThread')
-        self.nodes[ROUTER1].set_router_selection_jitter(1)
-
-        self.nodes[ROUTER2].set_panid(0xface)
-        self.nodes[ROUTER2].set_mode('rsdn')
-        self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64())
-        self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER1].get_addr64())
-        self.nodes[ROUTER2].enable_whitelist()
-        self.nodes[ROUTER2].set_channel(12)
-        self.nodes[ROUTER2].set_network_name('OpenThread')
-        self.nodes[ROUTER2].set_router_selection_jitter(1)
-
-    def tearDown(self):
-        for n in list(self.nodes.values()):
-            n.stop()
-            n.destroy()
-        self.simulator.stop()
+    TOPOLOGY = {
+        LEADER: {
+            'channel': 12,
+            'mode': 'rsdn',
+            'network_name': 'OpenThread',
+            'panid': 0xface,
+            'whitelist': [ROUTER1, ROUTER2]
+        },
+        ROUTER1: {
+            'channel': 12,
+            'mode': 'rsdn',
+            'network_name': 'OpenThread',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER2]
+        },
+        ROUTER2: {
+            'channel': 12,
+            'mode': 'rsdn',
+            'network_name': 'OpenThread',
+            'panid': 0xface,
+            'router_selection_jitter': 1,
+            'whitelist': [LEADER, ROUTER1]
+        },
+    }
 
     def hasAloc(self, node_id, service_id):
         for addr in self.nodes[node_id].get_ip6_address(
-            config.ADDRESS_TYPE.ALOC
-        ):
+                config.ADDRESS_TYPE.ALOC):
             m = re.match('.*:fc(..)$', addr, re.I)
             if m is not None:
-                if m.group(1) == str(
-                    service_id + 10
-                ):  # for service_id=3 look for '...:fc13'
+                if m.group(
+                        1) == str(service_id +
+                                  10):  # for service_id=3 look for '...:fc13'
                     return True
 
         return False
@@ -127,9 +115,8 @@
         self.assertEqual(self.hasAloc(ROUTER2, SRV_0_ID), False)
         self.assertEqual(self.hasAloc(ROUTER2, SRV_1_ID), False)
 
-        self.nodes[ROUTER1].add_service(
-            SRV_0_ENT_NUMBER, SRV_0_SERVICE_DATA, SRV_0_SERVER_DATA
-        )
+        self.nodes[ROUTER1].add_service(SRV_0_ENT_NUMBER, SRV_0_SERVICE_DATA,
+                                        SRV_0_SERVER_DATA)
         self.nodes[ROUTER1].register_netdata()
         self.simulator.go(2)
 
@@ -140,14 +127,11 @@
         self.assertEqual(self.hasAloc(ROUTER2, SRV_0_ID), False)
         self.assertEqual(self.hasAloc(ROUTER2, SRV_1_ID), False)
 
-        aloc0 = self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.ALOC)[
-            0
-        ]
+        aloc0 = self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.ALOC)[0]
         self.pingFromAll(aloc0)
 
-        self.nodes[LEADER].add_service(
-            SRV_0_ENT_NUMBER, SRV_0_SERVICE_DATA, SRV_0_SERVER_DATA
-        )
+        self.nodes[LEADER].add_service(SRV_0_ENT_NUMBER, SRV_0_SERVICE_DATA,
+                                       SRV_0_SERVER_DATA)
         self.nodes[LEADER].register_netdata()
         self.simulator.go(2)
 
@@ -160,9 +144,8 @@
 
         self.pingFromAll(aloc0)
 
-        self.nodes[ROUTER2].add_service(
-            SRV_1_ENT_NUMBER, SRV_1_SERVICE_DATA, SRV_1_SERVER_DATA
-        )
+        self.nodes[ROUTER2].add_service(SRV_1_ENT_NUMBER, SRV_1_SERVICE_DATA,
+                                        SRV_1_SERVER_DATA)
         self.nodes[ROUTER2].register_netdata()
         self.simulator.go(2)
 
@@ -173,15 +156,11 @@
         self.assertEqual(self.hasAloc(ROUTER2, SRV_0_ID), False)
         self.assertEqual(self.hasAloc(ROUTER2, SRV_1_ID), True)
 
-        aloc1 = self.nodes[ROUTER2].get_ip6_address(config.ADDRESS_TYPE.ALOC)[
-            0
-        ]
+        aloc1 = self.nodes[ROUTER2].get_ip6_address(config.ADDRESS_TYPE.ALOC)[0]
         self.pingFromAll(aloc0)
         self.pingFromAll(aloc1)
 
-        self.nodes[ROUTER1].remove_service(
-            SRV_0_ENT_NUMBER, SRV_0_SERVICE_DATA
-        )
+        self.nodes[ROUTER1].remove_service(SRV_0_ENT_NUMBER, SRV_0_SERVICE_DATA)
         self.nodes[ROUTER1].register_netdata()
         self.simulator.go(2)
 
@@ -209,9 +188,7 @@
         self.failToPingFromAll(aloc0)
         self.pingFromAll(aloc1)
 
-        self.nodes[ROUTER2].remove_service(
-            SRV_1_ENT_NUMBER, SRV_1_SERVICE_DATA
-        )
+        self.nodes[ROUTER2].remove_service(SRV_1_ENT_NUMBER, SRV_1_SERVICE_DATA)
         self.nodes[ROUTER2].register_netdata()
         self.simulator.go(2)
 
diff --git a/tests/scripts/thread-cert/thread_cert.py b/tests/scripts/thread-cert/thread_cert.py
new file mode 100644
index 0000000..8ebe8f5
--- /dev/null
+++ b/tests/scripts/thread-cert/thread_cert.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import os
+import sys
+import unittest
+
+import config
+import debug
+from node import Node
+
+PORT_OFFSET = int(os.getenv('PORT_OFFSET', "0"))
+
+DEFAULT_PARAMS = {
+    'is_mtd': False,
+    'is_bbr': False,
+    'mode': 'rsdn',
+    'panid': 0xface,
+    'whitelist': None,
+    'version': '1.1',
+}
+"""Default configurations when creating nodes."""
+
+EXTENDED_ADDRESS_BASE = 0x166e0a0000000000
+"""Extended address base to keep U/L bit 1. The value is borrowed from Thread Test Harness."""
+
+
+class NcpSupportMixin():
+    """ The mixin to check whether a test case supports NCP.
+    """
+
+    SUPPORT_NCP = True
+
+    def __init__(self, *args, **kwargs):
+        if os.getenv('NODE_TYPE', 'sim') == 'ncp-sim' and not self.SUPPORT_NCP:
+            # 77 means skip this test case in automake tests
+            sys.exit(77)
+
+        super().__init__(*args, **kwargs)
+
+
+class TestCase(NcpSupportMixin, unittest.TestCase):
+    """The base class for all thread certification test cases.
+
+    The `topology` member of sub-class is used to create test topology.
+    """
+
+    TOPOLOGY = None
+
+    def setUp(self):
+        """Create simulator, nodes and apply configurations.
+        """
+        self._clean_up_tmp()
+
+        self.simulator = config.create_default_simulator()
+        self.nodes = {}
+
+        initial_topology = {}
+        for i, params in self.TOPOLOGY.items():
+            if params:
+                params = dict(DEFAULT_PARAMS, **params)
+            else:
+                params = DEFAULT_PARAMS.copy()
+            initial_topology[i] = params
+
+            self.nodes[i] = Node(
+                i,
+                params['is_mtd'],
+                simulator=self.simulator,
+                version=params['version'],
+                is_bbr=params['is_bbr'],
+            )
+            self.nodes[i].set_panid(params['panid'])
+            self.nodes[i].set_mode(params['mode'])
+
+            if 'partition_id' in params:
+                self.nodes[i].set_partition_id(params['partition_id'])
+            if 'channel' in params:
+                self.nodes[i].set_channel(params['channel'])
+            if 'masterkey' in params:
+                self.nodes[i].set_masterkey(params['masterkey'])
+            if 'network_name' in params:
+                self.nodes[i].set_network_name(params['network_name'])
+
+            if 'router_selection_jitter' in params:
+                self.nodes[i].set_router_selection_jitter(
+                    params['router_selection_jitter'])
+            if 'router_upgrade_threshold' in params:
+                self.nodes[i].set_router_upgrade_threshold(
+                    params['router_upgrade_threshold'])
+            if 'router_downgrade_threshold' in params:
+                self.nodes[i].set_router_downgrade_threshold(
+                    params['router_downgrade_threshold'])
+
+            if 'timeout' in params:
+                self.nodes[i].set_timeout(params['timeout'])
+
+            if 'active_dataset' in params:
+                self.nodes[i].set_active_dataset(
+                    params['active_dataset']['timestamp'],
+                    panid=params['active_dataset'].get('panid'),
+                    channel=params['active_dataset'].get('channel'),
+                    channel_mask=params['active_dataset'].get('channel_mask'),
+                    master_key=params['active_dataset'].get('master_key'))
+
+            if 'pending_dataset' in params:
+                self.nodes[i].set_pending_dataset(
+                    params['pending_dataset']['pendingtimestamp'],
+                    params['pending_dataset']['activetimestamp'],
+                    panid=params['pending_dataset'].get('panid'),
+                    channel=params['pending_dataset'].get('channel'))
+
+            if 'key_switch_guardtime' in params:
+                self.nodes[i].set_key_switch_guardtime(
+                    params['key_switch_guardtime'])
+            if 'key_sequence_counter' in params:
+                self.nodes[i].set_key_sequence_counter(
+                    params['key_sequence_counter'])
+
+            if 'network_id_timeout' in params:
+                self.nodes[i].set_network_id_timeout(
+                    params['network_id_timeout'])
+
+            if 'context_reuse_delay' in params:
+                self.nodes[i].set_context_reuse_delay(
+                    params['context_reuse_delay'])
+
+            if 'max_children' in params:
+                self.nodes[i].set_max_children(params['max_children'])
+
+        # we have to add whitelist after nodes are all created
+        for i, params in initial_topology.items():
+            whitelist = params['whitelist']
+            if not whitelist:
+                continue
+
+            for j in whitelist:
+                rssi = None
+                if isinstance(j, tuple):
+                    j, rssi = j
+                self.nodes[i].add_whitelist(self.nodes[j].get_addr64(),
+                                            rssi=rssi)
+            self.nodes[i].enable_whitelist()
+
+        self._inspector = debug.Inspector(self)
+
+    def inspect(self):
+        self._inspector.inspect()
+
+    def tearDown(self):
+        """Destroy nodes and simulator.
+        """
+        for node in list(self.nodes.values()):
+            node.stop()
+            node.destroy()
+
+        self.simulator.stop()
+        del self.nodes
+        del self.simulator
+
+    def flush_all(self):
+        """Flush away all captured messages of all nodes.
+        """
+        for i in list(self.nodes.keys()):
+            self.simulator.get_messages_sent_by(i)
+
+    def flush_nodes(self, nodes):
+        """Flush away all captured messages of specified nodes.
+
+        Args:
+            nodes (list): nodes whose messages to flush.
+
+        """
+        for i in nodes:
+            if i in list(self.nodes.keys()):
+                self.simulator.get_messages_sent_by(i)
+
+    def _clean_up_tmp(self):
+        """
+        Clean up node files in tmp directory
+        """
+        os.system(
+            f"rm -f tmp/{PORT_OFFSET}_*.flash tmp/{PORT_OFFSET}_*.data tmp/{PORT_OFFSET}_*.swap"
+        )
diff --git a/tests/scripts/thread-cert/tlvs_parsing.py b/tests/scripts/thread-cert/tlvs_parsing.py
index 63195ff..5ca8f7c 100644
--- a/tests/scripts/thread-cert/tlvs_parsing.py
+++ b/tests/scripts/thread-cert/tlvs_parsing.py
@@ -27,9 +27,30 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 
 import io
+import logging
+
+
+class UnknownTlv(object):
+
+    def __init__(self, type, data):
+        self.type = type
+        self.data = data
+
+    def __repr__(self):
+        return 'UnknownTlv(%d, %s)' % (self.type, self.data)
+
+
+class UnknownTlvFactory(object):
+
+    def __init__(self, type):
+        self._type = type
+
+    def parse(self, data, message_info):
+        return UnknownTlv(self._type, data)
 
 
 class SubTlvsFactory(object):
+
     def __init__(self, sub_tlvs_factories):
         self._sub_tlvs_factories = sub_tlvs_factories
 
@@ -37,9 +58,10 @@
         try:
             return self._sub_tlvs_factories[_type]
         except KeyError:
-            raise RuntimeError(
-                "Could not find factory. Factory type = {}.".format(_type)
-            )
+            logging.error(
+                'Could not find TLV factory. Unsupported TLV type: {}'.format(
+                    _type))
+            return UnknownTlvFactory(_type)
 
     def parse(self, data, message_info):
         sub_tlvs = []
diff --git a/tests/scripts/thread-cert/v1_2_router_5_1_1.py b/tests/scripts/thread-cert/v1_2_router_5_1_1.py
new file mode 100755
index 0000000..c7908ad
--- /dev/null
+++ b/tests/scripts/thread-cert/v1_2_router_5_1_1.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import thread_cert
+import mle
+import network_layer
+
+LEADER = 1
+ROUTER_1 = 2
+
+
+class Router_5_1_01(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'version': '1.2'
+        },
+        ROUTER_1: {
+            'version': '1.2'
+        },
+    }
+    """All nodes are created with default configurations"""
+
+    def test(self):
+        self.nodes[ROUTER_1].set_router_selection_jitter(1)
+
+        self.nodes[LEADER].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[ROUTER_1].start()
+        self.simulator.go(7)
+        self.assertEqual(self.nodes[ROUTER_1].get_state(), 'router')
+
+        leader_messages = self.simulator.get_messages_sent_by(LEADER)
+        router_messages = self.simulator.get_messages_sent_by(ROUTER_1)
+
+        # 1 - Leader transmits MLE advertisements
+        msg = leader_messages.next_mle_message(mle.CommandType.ADVERTISEMENT)
+        msg.assertSentWithHopLimit(255)
+        msg.assertSentToDestinationAddress('ff02::1')
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.Route64)
+
+        # 2 - Router_1 begins attach process by sending a multicast MLE Parent Request
+        msg = router_messages.next_mle_message(mle.CommandType.PARENT_REQUEST)
+        msg.assertSentWithHopLimit(255)
+        msg.assertSentToDestinationAddress('ff02::2')
+        msg.assertMleMessageContainsTlv(mle.Mode)
+        msg.assertMleMessageContainsTlv(mle.Challenge)
+        msg.assertMleMessageContainsTlv(mle.ScanMask)
+        msg.assertMleMessageContainsTlv(mle.Version)
+        assert msg.get_mle_message_tlv(mle.Version).version == 3
+
+        scan_mask_tlv = msg.get_mle_message_tlv(mle.ScanMask)
+        self.assertEqual(1, scan_mask_tlv.router)
+        self.assertEqual(0, scan_mask_tlv.end_device)
+
+        # 3 - Leader sends a MLE Parent Response
+        msg = leader_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
+        msg.assertSentToNode(self.nodes[ROUTER_1])
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
+        msg.assertMleMessageContainsOptionalTlv(mle.MleFrameCounter)
+        msg.assertMleMessageContainsTlv(mle.Response)
+        msg.assertMleMessageContainsTlv(mle.Challenge)
+        msg.assertMleMessageContainsTlv(mle.LinkMargin)
+        msg.assertMleMessageContainsTlv(mle.Connectivity)
+        msg.assertMleMessageContainsTlv(mle.Version)
+        assert msg.get_mle_message_tlv(mle.Version).version == 3
+
+        # 4 - Router_1 receives the MLE Parent Response and sends a Child ID Request
+        msg = router_messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
+        msg.assertSentToNode(self.nodes[LEADER])
+        msg.assertMleMessageContainsTlv(mle.Response)
+        msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
+        msg.assertMleMessageContainsOptionalTlv(mle.MleFrameCounter)
+        msg.assertMleMessageContainsTlv(mle.Mode)
+        msg.assertMleMessageContainsTlv(mle.Timeout)
+        msg.assertMleMessageContainsTlv(mle.Version)
+        msg.assertMleMessageContainsTlv(mle.TlvRequest)
+        msg.assertMleMessageDoesNotContainTlv(mle.AddressRegistration)
+        assert msg.get_mle_message_tlv(mle.Version).version == 3
+
+        # 5 - Leader responds with a Child ID Response
+        msg = leader_messages.next_mle_message(
+            mle.CommandType.CHILD_ID_RESPONSE)
+        msg.assertSentToNode(self.nodes[ROUTER_1])
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.Address16)
+        msg.assertMleMessageContainsOptionalTlv(mle.NetworkData)
+        msg.assertMleMessageContainsOptionalTlv(mle.Route64)
+        msg.assertMleMessageContainsOptionalTlv(mle.AddressRegistration)
+
+        # 6 - Router_1 sends an Address Solicit Request
+        msg = router_messages.next_coap_message('0.02')
+        msg.assertCoapMessageRequestUriPath('/a/as')
+        msg.assertCoapMessageContainsTlv(network_layer.MacExtendedAddress)
+        msg.assertCoapMessageContainsTlv(network_layer.Status)
+
+        # 7 - Leader sends an Address Solicit Response
+        msg = leader_messages.next_coap_message('2.04')
+        msg.assertCoapMessageContainsTlv(network_layer.Status)
+        msg.assertCoapMessageContainsOptionalTlv(network_layer.RouterMask)
+
+        status_tlv = msg.get_coap_message_tlv(network_layer.Status)
+        self.assertEqual(network_layer.StatusValues.SUCCESS, status_tlv.status)
+
+        # 8 - Router_1 sends a multicast Link Request Message
+        msg = router_messages.next_mle_message(mle.CommandType.LINK_REQUEST)
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.Challenge)
+        msg.assertMleMessageContainsTlv(mle.Version)
+        msg.assertMleMessageContainsTlv(mle.TlvRequest)
+        assert msg.get_mle_message_tlv(mle.Version).version >= 3
+
+        tlv_request = msg.get_mle_message_tlv(mle.TlvRequest)
+        self.assertIn(mle.TlvType.LINK_MARGIN, tlv_request.tlvs)
+
+        # 9 - Leader sends a Unicast Link Accept
+        msg = leader_messages.next_mle_message(
+            mle.CommandType.LINK_ACCEPT_AND_REQUEST)
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.Response)
+        msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
+        msg.assertMleMessageContainsTlv(mle.Version)
+        msg.assertMleMessageContainsTlv(mle.LinkMargin)
+        msg.assertMleMessageContainsOptionalTlv(mle.MleFrameCounter)
+        msg.assertMleMessageContainsOptionalTlv(mle.Challenge)
+        assert msg.get_mle_message_tlv(mle.Version).version >= 3
+
+        # 10 - Router_1 Transmit MLE advertisements
+        msg = router_messages.next_mle_message(mle.CommandType.ADVERTISEMENT)
+        msg.assertSentWithHopLimit(255)
+        msg.assertSentToDestinationAddress('ff02::1')
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.Route64)
+
+        # 11 - Verify connectivity by sending an ICMPv6 Echo Request to the DUT link local address
+        self.assertTrue(self.nodes[LEADER].ping(
+            self.nodes[ROUTER_1].get_linklocal()))
+        self.assertTrue(self.nodes[ROUTER_1].ping(
+            self.nodes[LEADER].get_linklocal()))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/v1_2_test_backbone_router_service.py b/tests/scripts/thread-cert/v1_2_test_backbone_router_service.py
new file mode 100755
index 0000000..56d26a4
--- /dev/null
+++ b/tests/scripts/thread-cert/v1_2_test_backbone_router_service.py
@@ -0,0 +1,274 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import thread_cert
+import config
+
+LEADER_1_1 = 1
+BBR_1 = 2
+BBR_2 = 3
+
+WAIT_ATTACH = 5
+WAIT_REDUNDANCE = 3
+ROUTER_SELECTION_JITTER = 1
+BBR_REGISTRATION_JITTER = 5
+"""
+ Topology
+
+ LEADER_1_1 --- BBR_1
+          \        |
+            \      |
+              \    |
+                BBR_2
+
+ 1) Bring up Leader_1_1 and then BBR_1, BBR_1 becomes Primary Backbone Router.
+ 2) Reset BBR_1, if bring back soon, it could restore the Backbone Router Service
+    from the network, after increasing sequence number, it will reregister its
+    Backbone Router Service to the Leader and become Primary.
+ 3) Reset BBR_1, if bring back after it is released in the network, BBR_1 will
+    choose a random sequence number, register its Backbone Router Service to
+    Leader and become Primary.
+ 4) Configure BBR_2 with highest sequence number and explicitly trigger SRV_DATA.ntf.
+    BBR_2 would become Primary and BBR_1 would change to Secondary with sequence
+    number increased by 1.
+    a) Check communication via DUA.
+ 5) Stop BBR_2, BBR_1 would become Primary after detecting there is no available
+    Backbone Router Service in Thread Network.
+ 6) Bring back BBR_2, and it would become Secondary.
+    a) Check the uniqueness of DUA by comparing the one in above 4a).
+    b) Check communication via DUA.
+
+"""
+
+
+class TestBackboneRouterService(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER_1_1: {
+            'version': '1.1',
+            'whitelist': [BBR_1, BBR_2],
+        },
+        BBR_1: {
+            'version': '1.2',
+            'whitelist': [LEADER_1_1, BBR_2],
+            'is_bbr': True
+        },
+        BBR_2: {
+            'version': '1.2',
+            'whitelist': [LEADER_1_1, BBR_1],
+            'is_bbr': True
+        },
+    }
+    """All nodes are created with default configurations"""
+
+    def test(self):
+
+        self.nodes[LEADER_1_1].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[LEADER_1_1].get_state(), 'leader')
+        self.simulator.set_lowpan_context(1, config.DOMAIN_PREFIX)
+
+        # 1) First Backbone Router would become the Primary.
+        self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
+        self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
+        self.nodes[BBR_1].set_backbone_router(seqno=1)
+        self.nodes[BBR_1].start()
+        WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_1].get_state(), 'router')
+        self.nodes[BBR_1].enable_backbone_router()
+        WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
+                         'Primary')
+        assert self.nodes[BBR_1].has_ipmaddr(config.ALL_NETWORK_BBRS_ADDRESS)
+        assert not self.nodes[BBR_1].has_ipmaddr(config.ALL_DOMAIN_BBRS_ADDRESS)
+
+        self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        assert self.nodes[BBR_1].has_ipmaddr(config.ALL_DOMAIN_BBRS_ADDRESS)
+
+        # 2) Reset BBR_1 and bring it back soon.
+        # Verify that it restores Primary State with sequence number
+        # increased by 1.
+        self.nodes[BBR_1].reset()
+        self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
+        self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
+        self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
+        self.nodes[BBR_1].enable_backbone_router()
+        self.nodes[BBR_1].start()
+        WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_1].get_state(), 'router')
+        WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
+                         'Primary')
+        assert self.nodes[BBR_1].get_backbone_router()['seqno'] == 2
+
+        # 3) Reset BBR_1 and bring it back after its original router id is released
+        # 200s (100s MaxNeighborAge + 90s InfiniteCost + 10s redundance)
+        # Verify it becomes Primary again.
+        # Note: To ensure test in next step, here Step 3) will repeat until
+        # the random sequence number is not the highest value 255.
+        while True:
+            self.nodes[BBR_1].reset()
+            WAIT_TIME = 200
+            self.simulator.go(WAIT_TIME)
+            self.nodes[BBR_1].set_router_selection_jitter(
+                ROUTER_SELECTION_JITTER)
+            self.nodes[BBR_1].set_bbr_registration_jitter(
+                BBR_REGISTRATION_JITTER)
+            self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
+            self.nodes[BBR_1].enable_backbone_router()
+            self.nodes[BBR_1].start()
+            WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+            self.simulator.go(WAIT_TIME)
+            self.assertEqual(self.nodes[BBR_1].get_state(), 'router')
+            WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
+            self.simulator.go(WAIT_TIME)
+            self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
+                             'Primary')
+            BBR_1_SEQNO = self.nodes[BBR_1].get_backbone_router()['seqno']
+            if (BBR_1_SEQNO != 255):
+                break
+
+        #4) Configure BBR_2 with highest sequence number (255) and
+        #   explicitly trigger SRV_DATA.ntf.
+        #   Verify BBR_2 would become Primary and BBR_1 would change to
+        #   Secondary with sequence number increased by 1.
+
+        # Bring up BBR_2, it becomes Router with backbone function disabled
+        # by default.
+        self.nodes[BBR_2].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
+        self.nodes[BBR_2].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
+        self.nodes[BBR_2].set_domain_prefix(config.DOMAIN_PREFIX)
+        self.nodes[BBR_2].start()
+        WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_2].get_state(), 'router')
+        WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
+                         'Disabled')
+
+        assert not self.nodes[BBR_2].has_ipmaddr(
+            config.ALL_NETWORK_BBRS_ADDRESS)
+        assert not self.nodes[BBR_2].has_ipmaddr(config.ALL_DOMAIN_BBRS_ADDRESS)
+
+        # Enable Backbone function, it will stay at Secondary state as
+        # there is Primary Backbone Router already.
+        # Here removes the Domain Prefix before enabling backbone function
+        # intentionally to avoid SRV_DATA.ntf due to prefix inconsistency.
+        self.nodes[BBR_2].remove_domain_prefix(config.DOMAIN_PREFIX)
+        self.nodes[BBR_2].enable_backbone_router()
+        self.nodes[BBR_2].set_backbone_router(seqno=255)
+        WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
+                         'Secondary')
+
+        # Check no SRV_DATA.ntf.
+        messages = self.simulator.get_messages_sent_by(BBR_2)
+        msg = messages.next_coap_message('0.02', '/a/sd', False)
+        assert (
+            msg is None
+        ), "Error: %d sent unexpected SRV_DATA.ntf when there is PBbr already"
+
+        # Flush relative message queue.
+        self.flush_nodes([BBR_1])
+
+        # BBR_2 registers SRV_DATA.ntf explicitly.
+        self.nodes[BBR_2].register_backbone_router()
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
+                         'Primary')
+
+        # Verify BBR_1 becomes Secondary and sends SRV_DATA.ntf to deregister
+        # its service.
+        messages = self.simulator.get_messages_sent_by(BBR_1)
+        messages.next_coap_message('0.02', '/a/sd', True)
+        self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
+                         'Secondary')
+        # Verify Sequence number increases when become Secondary from Primary.
+        assert self.nodes[BBR_1].get_backbone_router()['seqno'] == (
+            BBR_1_SEQNO + 1)
+
+        # 4a) Check communication via DUA.
+        bbr2_dua = self.nodes[BBR_2].get_addr(config.DOMAIN_PREFIX)
+        self.assertTrue(self.nodes[BBR_1].ping(bbr2_dua))
+
+        # 5) Stop BBR_2, BBR_1 becomes Primary after detecting there is no
+        #    available Backbone Router Service.
+        self.nodes[BBR_2].reset()
+        self.nodes[LEADER_1_1].release_router_id(
+            self.nodes[BBR_2].get_router_id())
+        # Wait for the dissemination of Network Data without Backbone Router service
+        self.simulator.go(10)
+
+        # BBR_1 becomes Primary.
+        self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
+                         'Primary')
+        messages = self.simulator.get_messages_sent_by(BBR_1)
+        messages.next_coap_message('0.02', '/a/sd', True)
+
+        # 6) Bring back BBR_2.
+        #    Verify that BBR_2 stays at Secondary.
+        self.nodes[BBR_2].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
+        self.nodes[BBR_2].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
+        self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
+        self.nodes[BBR_2].enable_backbone_router()
+        self.nodes[BBR_2].interface_up()
+        self.nodes[BBR_2].thread_start()
+        WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_2].get_state(), 'router')
+        WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
+                         'Secondary')
+
+        assert self.nodes[BBR_1].has_ipmaddr(config.ALL_NETWORK_BBRS_ADDRESS)
+        assert self.nodes[BBR_1].has_ipmaddr(config.ALL_DOMAIN_BBRS_ADDRESS)
+
+        # 6a) Check the uniqueness of DUA by comparing the one in above 4a).
+        bbr2_dua2 = self.nodes[BBR_2].get_addr(config.DOMAIN_PREFIX)
+        assert bbr2_dua == bbr2_dua2, 'Error: Unexpected different DUA ({} v.s. {})'.format(
+            bbr2_dua, bbr2_dua2)
+
+        # 6b) Check communication via DUA
+        self.assertTrue(self.nodes[BBR_1].ping(bbr2_dua))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/v1_2_test_domain_unicast_address.py b/tests/scripts/thread-cert/v1_2_test_domain_unicast_address.py
new file mode 100755
index 0000000..85eba96
--- /dev/null
+++ b/tests/scripts/thread-cert/v1_2_test_domain_unicast_address.py
@@ -0,0 +1,339 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import command
+import config
+import ipaddress
+import mle
+import thread_cert
+
+BBR_1 = 1  # Collapsed with Leader Role
+ROUTER_1_1 = 2
+ROUTER_1_2 = 3
+MED_1_2 = 4
+SED_1_2 = 5
+
+WAIT_ATTACH = 5
+WAIT_REDUNDANCE = 3
+ROUTER_SELECTION_JITTER = 1
+BBR_REGISTRATION_JITTER = 5
+SED_POLL_PERIOD = 2000  # 2s
+MED_TIMEOUT = 20  # 20s
+
+DUA_IID_MANUAL1 = '4444333322221111'
+DUA_IID_MANUAL2 = '5555444433332222'
+
+TEST_PREFIX1 = '2001:0:0:1::/64'
+TEST_PREFIX2 = '2001:0:0:2::/64'
+TEST_PREFIX3 = '2001:0:0:3::/64'
+"""
+ Topology
+
+
+   SED_1_2
+     |
+     |
+ ROUTER_1_1         MED_1_2
+     |                 |
+     |                 |
+ BBR_1 (LEADER) --- ROUTER_1_2
+
+
+ 1) Bring up BBR_1, BBR_1 becomes Leader and Primary Backbone Router, with Domain
+    Prefix without `P_slaac`.
+
+ 2) Bring up ROUTER_1_1, no DUA was added due to that `P_slaac` flag is not set.
+
+ 3) Bring up ROUTER_1_2, verify that it has DUA generated.
+
+ 4) Bring up MED_1_2 with DUA_IID_MANUAL1 set in advance, verify
+    a) DUA_IID_MANUAL1 is registered in Address Registration TLV via Child Update Request.
+    b) Remove DUA_IID_MANUAL1, a new DUA generated via SLAAC would be registered in Address
+       Registration TLV via Child Update Request.
+    c) Set DUA_IID_MANUAL2 which should override the generated one and be registered in Address
+       Registration TLV via Child Update Request.
+    d) Remove DUA_IID_MANUAL2, a new DUA generated via SLAAC, the same as in above b) would
+       be registered in Address Registration TLV via  Child Update Request.
+
+ 5) Change BBR_1 from config.DOMAIN_PREFIX to config.DOMAIN_PRFIX_ALTER. Verify that MED_1_2
+    generate a new Interface Identifier different from the one generated in 4d) due to the
+    Domain Prefix change.
+
+ 6) Recover config.Domain_Prefix on BBR_1. Verify that MED_1_2 generates and registers the same
+    DUA as in step 4b).
+
+ 7) Configure ROUTER_1_1 as Border Router with 3 SLAAC prefixes, verify MED_1_2 would register
+    its DUA in Address Registration TLV.
+
+ 8) Bring up SED_1_2, verify it generates one DUA, and registers it to its parent, though the parent
+    is a Thread 1.1 device.
+
+"""
+
+
+class TestDomainUnicastAddress(thread_cert.TestCase):
+    TOPOLOGY = {
+        BBR_1: {
+            'version': '1.2',
+            'whitelist': [ROUTER_1_1, ROUTER_1_2],
+            'is_bbr': True
+        },
+        ROUTER_1_1: {
+            'version': '1.1',
+            'whitelist': [BBR_1, SED_1_2]
+        },
+        ROUTER_1_2: {
+            'version': '1.2',
+            'whitelist': [BBR_1, MED_1_2]
+        },
+        MED_1_2: {
+            'mode': 'rsn',
+            'version': '1.2',
+            'whitelist': [ROUTER_1_2],
+        },
+        SED_1_2: {
+            'mode': 'sn',
+            'version': '1.2',
+            'whitelist': [ROUTER_1_1],
+        },
+    }
+    """All nodes are created with default configurations"""
+
+    def __get_iid(self, address):
+        ''' Get the interface identifier of an IPv6 address.
+
+        Args:
+            address (string): An IPv6 address;
+        '''
+        return ''.join(ipaddress.ip_address(address).exploded.split(':')[4:])
+
+    def __check_dua_registration(self, node, iid, dp_cid):
+        ''' Check whether or not the specified domain unicast address is registered in Address
+        Registraion TLV.
+
+        Args:
+            node (int) : The device id
+            iid (string): The Interface Identifier
+            dp_cid (int): The context id of the domain prefix.
+        '''
+
+        messages = self.simulator.get_messages_sent_by(node)
+        msg = messages.next_mle_message(mle.CommandType.CHILD_UPDATE_REQUEST)
+        command.check_compressed_address_registration_tlv(msg,
+                                                          dp_cid,
+                                                          iid,
+                                                          cid_present_once=True)
+
+    def test(self):
+        # starting context id
+        context_id = 1
+
+        # 1) Bring up BBR_1, BBR_1 becomes Leader and Primary Backbone Router, with Domain
+        #    Prefix without `P_slaac`.
+        self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
+        self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
+        self.nodes[BBR_1].set_backbone_router(seqno=1)
+        self.nodes[BBR_1].start()
+        WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_1].get_state(), 'leader')
+        self.nodes[BBR_1].enable_backbone_router()
+        WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
+                         'Primary')
+        assert self.nodes[BBR_1].has_ipmaddr(config.ALL_NETWORK_BBRS_ADDRESS)
+        assert not self.nodes[BBR_1].has_ipmaddr(config.ALL_DOMAIN_BBRS_ADDRESS)
+
+        self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX, 'prosD')
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        assert self.nodes[BBR_1].has_ipmaddr(config.ALL_DOMAIN_BBRS_ADDRESS)
+
+        self.simulator.set_lowpan_context(context_id, config.DOMAIN_PREFIX)
+        domain_prefix_cid = context_id
+
+        # 2) Bring up ROUTER_1_1, no DUA was added due to that `P_slaac` flag is not set.
+        self.nodes[ROUTER_1_1].set_router_selection_jitter(
+            ROUTER_SELECTION_JITTER)
+        WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+        self.nodes[ROUTER_1_1].start()
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[ROUTER_1_1].get_state(), 'router')
+        dua = self.nodes[ROUTER_1_1].get_addr(config.DOMAIN_PREFIX)
+        assert not dua, 'Error: Unexpected DUA ({})'.format(dua)
+
+        # 3) Bring up ROUTER_1_2, verify that it has DUA generated.
+        self.nodes[ROUTER_1_2].set_router_selection_jitter(
+            ROUTER_SELECTION_JITTER)
+        self.nodes[ROUTER_1_2].start()
+        WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[ROUTER_1_2].get_state(), 'router')
+        dua = self.nodes[ROUTER_1_2].get_addr(config.DOMAIN_PREFIX)
+        assert dua, 'Error: Expected DUA not found'
+        self.assertTrue(self.nodes[BBR_1].ping(dua))
+
+        # 4) Bring up MED_1_2 with DUA_IID_MANUAL1 set in advance
+        self.nodes[MED_1_2].set_dua_iid(DUA_IID_MANUAL1)
+        self.nodes[MED_1_2].set_timeout(MED_TIMEOUT)
+        self.nodes[MED_1_2].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[MED_1_2].get_state(), 'child')
+
+        # 4a) DUA_IID_MANUAL1 is registered in Address Registration TLV via Child Update Request.
+        self.__check_dua_registration(MED_1_2, DUA_IID_MANUAL1,
+                                      domain_prefix_cid)
+
+        # 4b) Remove DUA_IID_MANUAL1, a new DUA generated via SLAAC would be registered in Address
+        #   Registration TLV via Child Update Request.
+
+        # Flush relative message queues.
+        messages = self.simulator.get_messages_sent_by(MED_1_2)
+
+        self.nodes[MED_1_2].clear_dua_iid()
+        WAIT_TIME = MED_TIMEOUT + WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+
+        med_1_2_dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
+        assert med_1_2_dua, 'Error: Expected DUA not found'
+
+        med_1_2_dua_iid = self.__get_iid(med_1_2_dua)
+        self.__check_dua_registration(MED_1_2, med_1_2_dua_iid,
+                                      domain_prefix_cid)
+
+        # 4c) Set DUA_IID_MANUAL2 which should override the generated one and be registered in Address
+        #   Registration TLV via Child Update Request.
+
+        # Flush relative message queues.
+        messages = self.simulator.get_messages_sent_by(MED_1_2)
+        self.nodes[MED_1_2].set_dua_iid(DUA_IID_MANUAL2)
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+
+        dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
+
+        self.__check_dua_registration(MED_1_2, DUA_IID_MANUAL2,
+                                      domain_prefix_cid)
+
+        # 4d) Remove DUA_IID_MANUAL2, a new DUA generated via SLAAC, the same as in above b) would
+        #     be registered in Address Registration TLV via  Child Update Request.
+
+        # Flush relative message queues.
+        messages = self.simulator.get_messages_sent_by(MED_1_2)
+        self.nodes[MED_1_2].clear_dua_iid()
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
+        assert ipaddress.ip_address(dua) == ipaddress.ip_address(
+            med_1_2_dua), 'Error: Expected SLAAC DUA not generated'
+        assert ipaddress.ip_address(med_1_2_dua) == ipaddress.ip_address(
+            dua), 'Error: Expected same SLAAC DUA not generated'
+
+        self.__check_dua_registration(MED_1_2, med_1_2_dua_iid,
+                                      domain_prefix_cid)
+
+        # 5) Change BBR_1 from config.DOMAIN_PREFIX to config.DOMAIN_PRFIX_ALTER. Verify that MED_1_2
+        #   generates a new Interface Identifier different from the one generated in 4d) due to the
+        #   Domain Prefix change.
+        context_id += 1
+        self.simulator.set_lowpan_context(context_id,
+                                          config.DOMAIN_PREFIX_ALTER)
+        self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX_ALTER)
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+
+        med_1_2_dua2 = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX_ALTER)
+        med_1_2_dua2_iid = self.__get_iid(med_1_2_dua2)
+        self.__check_dua_registration(MED_1_2, med_1_2_dua2_iid, context_id)
+
+        #6) Recover config.Domain_Prefix on BBR_1. Verify that MED_1_2 generates and registers the same
+        #   DUA as in step 4b).
+        self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+        dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
+        assert dua, 'Error: Expected DUA not found'
+        assert ipaddress.ip_address(med_1_2_dua) == ipaddress.ip_address(
+            dua), 'Error: Expected same SLAAC DUA not generated'
+
+        self.__check_dua_registration(MED_1_2, med_1_2_dua_iid,
+                                      domain_prefix_cid)
+
+        #7) Configure ROUTER_1_1 as Border Router with 3 SLAAC prefixes, verify MED_1_2 would register
+        #   its DUA in Address Registration TLV.
+
+        # Flush relative message queues.
+        messages = self.simulator.get_messages_sent_by(MED_1_2)
+
+        context_id += 1
+        self.simulator.set_lowpan_context(context_id, TEST_PREFIX1)
+        self.nodes[ROUTER_1_1].add_prefix(TEST_PREFIX1)
+
+        context_id += 1
+        self.simulator.set_lowpan_context(context_id, TEST_PREFIX2)
+        self.nodes[ROUTER_1_1].add_prefix(TEST_PREFIX2)
+        context_id += 1
+        self.simulator.set_lowpan_context(context_id, TEST_PREFIX3)
+        self.nodes[ROUTER_1_1].add_prefix(TEST_PREFIX3)
+        self.nodes[ROUTER_1_1].register_netdata()
+
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+
+        WAIT_TIME = MED_TIMEOUT
+        dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
+        assert dua, 'Error: Expected DUA not found'
+        assert ipaddress.ip_address(med_1_2_dua) == ipaddress.ip_address(
+            dua), 'Error: Expected same SLAAC DUA not generated'
+
+        self.__check_dua_registration(MED_1_2, med_1_2_dua_iid,
+                                      domain_prefix_cid)
+
+        #8) Bring up SED_1_2, verify that it generates one DUA, and registers it to its parent, though the parent
+        #   is a Thread 1.1 device.
+        self.nodes[SED_1_2].set_pollperiod(SED_POLL_PERIOD)
+        self.nodes[SED_1_2].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+
+        dua = self.nodes[SED_1_2].get_addr(config.DOMAIN_PREFIX)
+        assert dua, 'Error: Expected DUA not found'
+
+        dua_iid = self.__get_iid(dua)
+        self.__check_dua_registration(SED_1_2, dua_iid, domain_prefix_cid)
+
+        self.assertTrue(self.nodes[BBR_1].ping(dua))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/v1_2_test_enhanced_frame_pending.py b/tests/scripts/thread-cert/v1_2_test_enhanced_frame_pending.py
new file mode 100755
index 0000000..a1a9dfe
--- /dev/null
+++ b/tests/scripts/thread-cert/v1_2_test_enhanced_frame_pending.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+"""This test case verifies Thread 1.2 enhanced frame pending feature.
+
+Topology
+
+    Leader ----- SED_1
+
+1. Set up topology a Leader and a SED.
+2. SED pings leader so a data poll is just sent.
+3. Leader sends a UDP packet to SED to put a pending frame in queue.
+4. Wait for half polling period, verify no packet received by SED.
+5. SED sends a UDP packet to Leader to solicit an ACK with frame pending set.
+   * Verify Leader receives a UDP packet
+   * Verify SED sends a data poll
+   * Verify SED receives a UDP packet
+"""
+
+import unittest
+import pexpect
+
+import thread_cert
+import common
+
+LEADER = 1
+SED_1 = 2
+
+CHILD_TIMEOUT = 30
+UDP_BYTES_COUNT = 73
+
+DEFAULT_POLL_PERIOD = CHILD_TIMEOUT - 4
+"""The default poll period calculated from child timeout."""
+
+
+class SED_EnhancedFramePending(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'version': '1.2'
+        },
+        SED_1: {
+            'mode': 's',
+            'version': '1.2',
+        },
+    }
+
+    def test(self):
+        self.nodes[SED_1].set_timeout(CHILD_TIMEOUT)
+
+        # 1 - Set up topology
+        self.nodes[LEADER].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[SED_1].start()
+        self.simulator.go(7)
+        self.assertEqual(self.nodes[SED_1].get_state(), 'child')
+
+        self.nodes[LEADER].udp_start('::', common.UDP_TEST_PORT)
+        self.nodes[SED_1].udp_start('::', common.UDP_TEST_PORT)
+
+        # 2 - Ping Leader
+        self.assertTrue(self.nodes[SED_1].ping(self.nodes[LEADER].get_rloc(),
+                                               timeout=CHILD_TIMEOUT))
+
+        self.flush_all()
+
+        # 3 - Send to SED
+        self.nodes[LEADER].udp_send(UDP_BYTES_COUNT,
+                                    self.nodes[SED_1].get_rloc(),
+                                    common.UDP_TEST_PORT)
+
+        # 4 - Wait for half polling period
+        self.simulator.go(DEFAULT_POLL_PERIOD // 2)
+        with self.assertRaises(pexpect.TIMEOUT):
+            self.nodes[SED_1].udp_check_rx(UDP_BYTES_COUNT)
+
+        # 5 - Send to Leader
+        self.nodes[SED_1].udp_send(UDP_BYTES_COUNT,
+                                   self.nodes[LEADER].get_rloc(),
+                                   common.UDP_TEST_PORT)
+        self.simulator.go(1)
+        self.nodes[LEADER].udp_check_rx(UDP_BYTES_COUNT)
+        sed_messages = self.simulator.get_messages_sent_by(SED_1)
+        self.assertNotEqual(sed_messages.next_data_poll(), None)
+        self.nodes[SED_1].udp_check_rx(UDP_BYTES_COUNT)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py b/tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py
new file mode 100755
index 0000000..d22ceb2
--- /dev/null
+++ b/tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import thread_cert
+import mle
+
+LEADER = 1
+SED_1 = 2
+
+CHILD_TIMEOUT = 30
+
+DEFAULT_POLL_PERIOD = CHILD_TIMEOUT - 4
+"""The default poll period calculated by ot::Mac::DataPollSender::GetDefaultPollPeriod()."""
+
+USER_POLL_PERIOD = CHILD_TIMEOUT // 3
+"""The poll period explicitly set by this test for verifying enhanced keep-alive."""
+
+
+class SED_EnhancedKeepAlive(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER: {
+            'version': '1.2'
+        },
+        SED_1: {
+            'mode': 's',
+            'version': '1.2',
+        },
+    }
+    """All nodes are created with default configurations"""
+
+    def test(self):
+        self.nodes[SED_1].set_timeout(CHILD_TIMEOUT)
+        self.nodes[SED_1].set_pollperiod(USER_POLL_PERIOD * 1000)
+
+        self.nodes[LEADER].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
+
+        self.nodes[SED_1].start()
+        self.simulator.go(7)
+        self.assertEqual(self.nodes[SED_1].get_state(), 'child')
+
+        leader_messages = self.simulator.get_messages_sent_by(LEADER)
+        sed_messages = self.simulator.get_messages_sent_by(SED_1)
+
+        # 1 - Leader transmits MLE advertisements
+        msg = leader_messages.next_mle_message(mle.CommandType.ADVERTISEMENT)
+        msg.assertSentWithHopLimit(255)
+        msg.assertSentToDestinationAddress('ff02::1')
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.Route64)
+
+        # 2 - SED_1 begins attach process by sending a multicast MLE Parent Request
+        msg = sed_messages.next_mle_message(mle.CommandType.PARENT_REQUEST)
+        msg.assertSentWithHopLimit(255)
+        msg.assertSentToDestinationAddress('ff02::2')
+        msg.assertMleMessageContainsTlv(mle.Mode)
+        msg.assertMleMessageContainsTlv(mle.Challenge)
+        msg.assertMleMessageContainsTlv(mle.ScanMask)
+        msg.assertMleMessageContainsTlv(mle.Version)
+        self.assertEqual(msg.get_mle_message_tlv(mle.Version).version, 3)
+
+        scan_mask_tlv = msg.get_mle_message_tlv(mle.ScanMask)
+        self.assertEqual(1, scan_mask_tlv.router)
+        self.assertEqual(0, scan_mask_tlv.end_device)
+
+        # 3 - Leader sends a MLE Parent Response
+        msg = leader_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
+        msg.assertSentToNode(self.nodes[SED_1])
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
+        msg.assertMleMessageContainsOptionalTlv(mle.MleFrameCounter)
+        msg.assertMleMessageContainsTlv(mle.Response)
+        msg.assertMleMessageContainsTlv(mle.Challenge)
+        msg.assertMleMessageContainsTlv(mle.LinkMargin)
+        msg.assertMleMessageContainsTlv(mle.Connectivity)
+        msg.assertMleMessageContainsTlv(mle.Version)
+        self.assertEqual(msg.get_mle_message_tlv(mle.Version).version, 3)
+
+        # 4 - SED_1 receives the MLE Parent Response and sends a Child ID Request
+        msg = sed_messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
+        msg.assertSentToNode(self.nodes[LEADER])
+        msg.assertMleMessageContainsTlv(mle.Response)
+        msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter)
+        msg.assertMleMessageContainsOptionalTlv(mle.MleFrameCounter)
+        msg.assertMleMessageContainsTlv(mle.Mode)
+        msg.assertMleMessageContainsTlv(mle.Timeout)
+        msg.assertMleMessageContainsTlv(mle.Version)
+        msg.assertMleMessageContainsTlv(mle.TlvRequest)
+        self.assertEqual(msg.get_mle_message_tlv(mle.Version).version, 3)
+
+        # 5 - Leader responds with a Child ID Response
+        msg = leader_messages.next_mle_message(
+            mle.CommandType.CHILD_ID_RESPONSE)
+        msg.assertSentToNode(self.nodes[SED_1])
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.Address16)
+        msg.assertMleMessageContainsOptionalTlv(mle.NetworkData)
+        msg.assertMleMessageContainsOptionalTlv(mle.Route64)
+        msg.assertMleMessageContainsOptionalTlv(mle.AddressRegistration)
+
+        leader_aloc = self.nodes[LEADER].get_addr_leader_aloc()
+        self.assertTrue(self.nodes[SED_1].ping(leader_aloc,
+                                               timeout=USER_POLL_PERIOD * 2))
+
+        # 6 - Timeout Child
+        self.nodes[LEADER].enable_whitelist()
+        self.nodes[SED_1].enable_whitelist()
+        self.nodes[SED_1].set_pollperiod(CHILD_TIMEOUT * 1000 * 2)
+        self.simulator.go(CHILD_TIMEOUT + 1)
+        self.assertEqual(self.nodes[SED_1].get_state(), 'child')
+        self.nodes[SED_1].set_pollperiod(USER_POLL_PERIOD * 1000)
+        self.nodes[LEADER].disable_whitelist()
+        self.nodes[SED_1].disable_whitelist()
+        self.assertFalse(self.nodes[SED_1].ping(leader_aloc,
+                                                timeout=USER_POLL_PERIOD * 2))
+        self.flush_all()
+
+        # 7 - Wait SED_1 to re-attach
+        self.simulator.go(240)
+        leader_messages = self.simulator.get_messages_sent_by(LEADER)
+        msg = leader_messages.next_mle_message(
+            mle.CommandType.CHILD_ID_RESPONSE)
+        msg.assertSentToNode(self.nodes[SED_1])
+        msg.assertMleMessageContainsTlv(mle.SourceAddress)
+        msg.assertMleMessageContainsTlv(mle.LeaderData)
+        msg.assertMleMessageContainsTlv(mle.Address16)
+        msg.assertMleMessageContainsOptionalTlv(mle.NetworkData)
+        msg.assertMleMessageContainsOptionalTlv(mle.Route64)
+        msg.assertMleMessageContainsOptionalTlv(mle.AddressRegistration)
+        self.assertTrue(self.nodes[SED_1].ping(leader_aloc,
+                                               timeout=USER_POLL_PERIOD * 2))
+        self.flush_all()
+
+        # 8 - Verify enhanced keep-alive works
+        self.nodes[LEADER].enable_whitelist()
+        self.nodes[SED_1].enable_whitelist()
+        self.nodes[SED_1].set_pollperiod(CHILD_TIMEOUT * 1000 * 2)
+        self.simulator.go(CHILD_TIMEOUT // 2)
+        self.assertEqual(self.nodes[SED_1].get_state(), 'child')
+        self.nodes[LEADER].disable_whitelist()
+        self.nodes[SED_1].disable_whitelist()
+        non_exist_addr = leader_aloc.replace('fc00', 'fc12')
+        self.assertFalse(self.nodes[SED_1].ping(non_exist_addr))
+        self.nodes[LEADER].enable_whitelist()
+        self.nodes[SED_1].enable_whitelist()
+        self.simulator.go(CHILD_TIMEOUT // 2)
+        self.nodes[LEADER].disable_whitelist()
+        self.nodes[SED_1].disable_whitelist()
+        self.nodes[SED_1].set_pollperiod(USER_POLL_PERIOD * 1000)
+        self.assertTrue(self.nodes[SED_1].ping(leader_aloc,
+                                               timeout=USER_POLL_PERIOD * 2))
+
+        # 9 - Verify child resets keep-alive timer
+        self.nodes[SED_1].set_pollperiod(DEFAULT_POLL_PERIOD * 1000)
+        self.simulator.go(DEFAULT_POLL_PERIOD // 3 * 2)
+        self.flush_all()
+        self.nodes[SED_1].ping(leader_aloc, timeout=1)
+        self.simulator.go(DEFAULT_POLL_PERIOD // 3 * 2)
+        sed_messages = self.simulator.get_messages_sent_by(SED_1)
+        self.assertEqual(sed_messages.next_data_poll(), None)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/v1_2_test_multicast_registration.py b/tests/scripts/thread-cert/v1_2_test_multicast_registration.py
new file mode 100755
index 0000000..b4aeff0
--- /dev/null
+++ b/tests/scripts/thread-cert/v1_2_test_multicast_registration.py
@@ -0,0 +1,305 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import command
+import config
+import mle
+import thread_cert
+
+LEADER_1_2 = 1
+MED_1_2 = 2
+SED_1_2 = 3
+MED_1_1 = 4
+SED_1_1 = 5
+ROUTER_1_1 = 6
+MED_1_2_2 = 7
+SED_1_2_2 = 8
+
+WAIT_ATTACH = 5
+WAIT_REDUNDANCE = 3
+ROUTER_SELECTION_JITTER = 1
+
+MA1_LINKLOCAL = 'ff02::1:2:3:4'
+MA2_ADMINSCOPE = 'ff04::1:2:3:4'
+"""
+ Topology
+
+             SED_1_2
+                |
+                |
+MED_1_2 --- LEADER_1_2 --- MED_1_1
+                |     \
+                |       \
+             SED_1_1     ROUTER_1_1 --- MED_1_2_2
+                            |
+                            |
+                         SED_1_2_2
+
+ 1) Bring up Leader_1_2.
+
+ 2) Bring up MED_1_2, which attaches to Thread 1.2 parent, only register MA with scope larger than realm local.
+    a) add MA1_LINKLOCAL which would NOT be registered in AddressRegistrationTLV of Child Update Request.
+    b) add MA2_ADMINSCOPE which would be registered in AddressRegistrationTLV of Child Update Request.
+
+ 3) Bring up SED_1_2, which attaches to Thread 1.2 parent, register any external MA for indirect transmission.
+    a) add MA1_LINKLOCAL which would be registered in AddressRegistrationTLV of Child Update Request
+    b) add MA2_ADMINSCOPE which would be registered in AddressRegistrationTLV of Child Update Request.
+
+ 4) Bring up MED_1_1, which attaches to Thread 1.2 parent, not register any external MA.
+    a) add MA1_LINKLOCAL which would NOT be registered in AddressRegistrationTLV of Child Update Request.
+    b) add MA2_ADMINSCOPE which would NOT be registered in AddressRegistrationTLV of Child Update Request.
+
+ 5) Bring up SED_1_1, which attaches to Thread 1.2 parent, register any external MA for indirect transmission.
+    a) add MA1_LINKLOCAL which would be registered in AddressRegistrationTLV of Child Update Request
+    b) add MA2_ADMINSCOPE which would be registered in AddressRegistrationTLV of Child Update Request.
+
+ 6) Bring up ROUTER_1_1.
+
+ 7) Bring up MED_1_2_2 which attaches to Thread 1.1 parent, not register any external MA.
+    a) add MA1_LINKLOCAL which would NOT be registered in AddressRegistrationTLV of Child Update Request
+    b) add MA2_ADMINSCOPE which would NOT be registered in AddressRegistrationTLV of Child Update Request.
+
+ 8) Bring up SED_1_2_2 which attaches to Thread 1.1 parent, register any external MA for indirect transmission.
+    a) add MA1_LINKLOCAL which would be registered in AddressRegistrationTLV of Child Update Request
+    b) add MA2_ADMINSCOPE which would be registered in AddressRegistrationTLV of Child Update Request.
+
+"""
+
+
+class TestMulticastRegistration(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER_1_2: {
+            'version': '1.2',
+            'whitelist': [MED_1_2, SED_1_2, MED_1_1, SED_1_1, ROUTER_1_1],
+        },
+        MED_1_2: {
+            'mode': 'rsn',
+            'version': '1.2',
+            'whitelist': [LEADER_1_2],
+        },
+        SED_1_2: {
+            'mode': 'sn',
+            'version': '1.2',
+            'whitelist': [LEADER_1_2],
+        },
+        MED_1_1: {
+            'mode': 'rsn',
+            'version': '1.1',
+            'whitelist': [LEADER_1_2],
+        },
+        SED_1_1: {
+            'mode': 'sn',
+            'version': '1.1',
+            'whitelist': [LEADER_1_2],
+        },
+        ROUTER_1_1: {
+            'version': '1.1',
+            'whitelist': [LEADER_1_2, MED_1_2_2, SED_1_2_2],
+        },
+        MED_1_2_2: {
+            'mode': 'rsn',
+            'version': '1.2',
+            'whitelist': [ROUTER_1_1],
+        },
+        SED_1_2_2: {
+            'mode': 'sn',
+            'version': '1.2',
+            'whitelist': [ROUTER_1_1],
+        },
+    }
+    """All nodes are created with default configurations"""
+
+    def __check_multicast_registration(self,
+                                       node,
+                                       multicast_address,
+                                       child_update_request_assert=True,
+                                       in_address_registration=True):
+        ''' Check whether or not the addition of the multicast address on the specific node
+        would trigger Child Update Request for multicast address registration via Address
+        Registraion TLV.
+
+        Args:
+            node (int) : The device id
+            multicast_address (string): The multicast address
+            child_update_request_assert (bool): whether or not the addition should trigger Child Update Request
+            in_address_registration (bool): Whether or not the multicast_address should be registered
+        '''
+        # Flush relative message queues.
+        self.flush_nodes([node])
+
+        self.nodes[node].add_ipmaddr(multicast_address)
+        WAIT_TIME = WAIT_REDUNDANCE
+        self.simulator.go(WAIT_TIME)
+
+        messages = self.simulator.get_messages_sent_by(node)
+
+        msg = messages.next_mle_message(
+            mle.CommandType.CHILD_UPDATE_REQUEST,
+            assert_enabled=child_update_request_assert)
+
+        if msg:
+            is_in = command.check_address_registration_tlv(
+                msg, multicast_address)
+
+            if in_address_registration:
+                assert is_in, 'Error: Expected {} in AddressRegistrationTLV not found'.format(
+                    multicast_address)
+            else:
+                assert not is_in, 'Error: Unexpected {} in AddressRegistrationTLV'.format(
+                    multicast_address)
+
+    def test(self):
+
+        # 1) Bring up Leader_1_2.
+        self.nodes[LEADER_1_2].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[LEADER_1_2].get_state(), 'leader')
+
+        # 2) Bring up MED_1_2, which attaches to Thread 1.2 parent, only register MA with scope larger than realm local.
+        self.nodes[MED_1_2].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[MED_1_2].get_state(), 'child')
+
+        # 2a) add MA1_LINKLOCAL which would NOT be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(MED_1_2,
+                                            MA1_LINKLOCAL,
+                                            child_update_request_assert=False,
+                                            in_address_registration=False)
+
+        # 2b) add MA2_ADMINSCOPE which would be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(MED_1_2,
+                                            MA2_ADMINSCOPE,
+                                            child_update_request_assert=True,
+                                            in_address_registration=True)
+
+        # 3) Bring up SED_1_2, which attaches to Thread 1.2 parent, register any external MA for indirect transmission.
+        self.nodes[SED_1_2].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[SED_1_2].get_state(), 'child')
+
+        # 3a) add MA1_LINKLOCAL which would be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(SED_1_2,
+                                            MA1_LINKLOCAL,
+                                            child_update_request_assert=True,
+                                            in_address_registration=True)
+
+        # 3b) add MA2_ADMINSCOPE which would be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(SED_1_2,
+                                            MA2_ADMINSCOPE,
+                                            child_update_request_assert=True,
+                                            in_address_registration=True)
+
+        # 4) Bring up MED_1_1, which attaches to Thread 1.2 parent, not register any external MA.
+        self.nodes[MED_1_1].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[MED_1_1].get_state(), 'child')
+
+        # 4a) add MA1_LINKLOCAL which would NOT be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(MED_1_1,
+                                            MA1_LINKLOCAL,
+                                            child_update_request_assert=False,
+                                            in_address_registration=False)
+
+        # 4b) add MA2_ADMINSCOPE which would NOT be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(MED_1_1,
+                                            MA2_ADMINSCOPE,
+                                            child_update_request_assert=False,
+                                            in_address_registration=False)
+
+        # 5) Bring up SED_1_1, which attaches to Thread 1.2 parent, register any external MA for indirect transmission.
+        self.nodes[SED_1_1].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[SED_1_1].get_state(), 'child')
+
+        # 5a) add MA1_LINKLOCAL which would be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(SED_1_1,
+                                            MA1_LINKLOCAL,
+                                            child_update_request_assert=True,
+                                            in_address_registration=True)
+
+        # 5b) add MA2_ADMINSCOPE which would be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(SED_1_1,
+                                            MA2_ADMINSCOPE,
+                                            child_update_request_assert=True,
+                                            in_address_registration=True)
+
+        #6) Bring up ROUTER_1_1.
+        self.nodes[ROUTER_1_1].set_router_selection_jitter(
+            ROUTER_SELECTION_JITTER)
+        self.nodes[ROUTER_1_1].start()
+        WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[ROUTER_1_1].get_state(), 'router')
+
+        # 7) Bring up MED_1_2_2 which attaches to Thread 1.1 parent, not register any external MA.
+        self.nodes[MED_1_2_2].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[MED_1_2_2].get_state(), 'child')
+
+        # 7a) add MA1_LINKLOCAL which would NOT be registered in AddressRegistrationTLV of Child Update Request
+        self.__check_multicast_registration(MED_1_2_2,
+                                            MA1_LINKLOCAL,
+                                            child_update_request_assert=False,
+                                            in_address_registration=False)
+
+        # 7b) add MA2_ADMINSCOPE which would NOT be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(MED_1_2_2,
+                                            MA2_ADMINSCOPE,
+                                            child_update_request_assert=False,
+                                            in_address_registration=False)
+
+        # 8) Bring up SED_1_2_2 which attaches to Thread 1.1 parent, register any external MA for indirect transmission.
+        self.nodes[SED_1_2_2].start()
+        WAIT_TIME = WAIT_ATTACH
+        self.simulator.go(WAIT_TIME)
+        self.assertEqual(self.nodes[SED_1_2_2].get_state(), 'child')
+
+        # 8a) add MA1_LINKLOCAL which would be registered in AddressRegistrationTLV of Child Update Request
+        self.__check_multicast_registration(SED_1_2_2,
+                                            MA1_LINKLOCAL,
+                                            child_update_request_assert=True,
+                                            in_address_registration=True)
+
+        # 8b) add MA2_ADMINSCOPE which would be registered in AddressRegistrationTLV of Child Update Request.
+        self.__check_multicast_registration(SED_1_2_2,
+                                            MA2_ADMINSCOPE,
+                                            child_update_request_assert=True,
+                                            in_address_registration=True)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/scripts/thread-cert/v1_2_test_parent_selection.py b/tests/scripts/thread-cert/v1_2_test_parent_selection.py
new file mode 100755
index 0000000..2df27fa
--- /dev/null
+++ b/tests/scripts/thread-cert/v1_2_test_parent_selection.py
@@ -0,0 +1,307 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2019, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+import unittest
+
+import thread_cert
+import mle
+
+LEADER_1_2 = 1
+ROUTER_1_1 = 2
+REED_1_2 = 3
+ROUTER_1_2 = 4
+REED_1_1 = 5
+MED_1_1 = 6
+MED_1_2 = 7
+
+# Topology
+#               (lq:2)  (pp:1)
+#     REED_1_2  ----- ROUTER_1_2
+#        |     \    /     |      \
+#        |       \/    REED_1_1    \
+# (lq:2) |      /  \  /  `router`    \
+#        | (lq:2)    \                 \
+#        |  /      /   \                 \
+#       LEADER_1_2 --- ROUTER_1_1 -- MED_1_2
+#                \        |
+#                  \      |
+#                    \    |
+#                       MED_1_1
+#
+# 1) Bring up LEADER_1_2 and ROUTER_1_1,
+# 2) Config link quality (LEADER_1_2->REED_1_2) as 2, bring up REED_1_2 which would attach to ROUTER_1_1
+#    due to higher two-way link quality,
+# 3) Config link quality(LEADER_1_2->ROUTER_1_2) and link quality(REED_1_2->ROUTER_1_2) as 2, bring up
+#    ROUTER_1_2 which would attach to LEADER_1_2 due to active router is preferred,
+# 4) Config parent priority as 1 on ROUTER_1_2, bring up REED_1_1 which would attach to ROUTER_1_2 due to
+#    higher parent priority,
+# 5) Upgrade REED_1_1 to `router` role, bring up MED_1_1 which would attach to LEADER_1_2 which has higher
+#    link quality of 3,
+# 6) Config parent priority as 1 on ROUTER_1_1, bring up MED_1_2 which would attach to ROUTER_1_2 due to
+#    higher version
+#
+
+
+class TestParentSelection(thread_cert.TestCase):
+    TOPOLOGY = {
+        LEADER_1_2: {
+            'version': '1.2',
+            'whitelist': [REED_1_2, ROUTER_1_2, REED_1_1, ROUTER_1_1, MED_1_1],
+        },
+        ROUTER_1_1: {
+            'version': '1.1',
+            'whitelist': [LEADER_1_2, REED_1_2, MED_1_2, MED_1_1],
+        },
+        REED_1_2: {
+            'version': '1.2',
+            'whitelist': [ROUTER_1_2, ROUTER_1_1, LEADER_1_2],
+        },
+        ROUTER_1_2: {
+            'version': '1.2',
+            'whitelist': [REED_1_2, MED_1_2, REED_1_1, LEADER_1_2],
+        },
+        REED_1_1: {
+            'version': '1.1',
+            'whitelist': [ROUTER_1_2, LEADER_1_2]
+        },
+        MED_1_1: {
+            'mode': 'rs',
+            'version': '1.1',
+            'whitelist': [LEADER_1_2, ROUTER_1_1],
+        },
+        MED_1_2: {
+            'mode': 'rs',
+            'version': '1.2',
+            'whitelist': [ROUTER_1_1, ROUTER_1_2],
+        },
+    }
+    """All nodes are created with default configurations"""
+
+    def test(self):
+
+        self.nodes[LEADER_1_2].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[LEADER_1_2].get_state(), 'leader')
+
+        self.nodes[ROUTER_1_1].set_router_selection_jitter(1)
+        self.nodes[ROUTER_1_1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[ROUTER_1_1].get_state(), 'router')
+
+        # Mesh Impacting Criteria - Highest Two-way link quality
+        # REED_1_2 would attach to ROUTER_1_1
+        # Attach to ROUTER_1_1 which has highest two-way link quality
+
+        # Flush relative message queues
+        self.flush_nodes([LEADER_1_2, ROUTER_1_1])
+
+        self.nodes[LEADER_1_2].set_link_quality(
+            self.nodes[REED_1_2].get_addr64(), 2)
+        self.nodes[REED_1_2].set_router_selection_jitter(1)
+        self.nodes[REED_1_2].set_router_upgrade_threshold(1)
+        self.nodes[REED_1_2].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[REED_1_2].get_state(), 'child')
+
+        # Check Parent Response
+        messages = self.simulator.get_messages_sent_by(ROUTER_1_1)
+        parent_prefer = messages.next_mle_message(
+            mle.CommandType.PARENT_RESPONSE)
+        assert (parent_prefer), "Error: Expected parent response not found"
+
+        messages = self.simulator.get_messages_sent_by(LEADER_1_2)
+        parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
+        assert (parent_cmp), "Error: Expected parent response not found"
+
+        # Known that link margin for link quality 3 is 80 and link quality 2 is 15
+        assert ((parent_prefer.get_mle_message_tlv(mle.LinkMargin).link_margin -
+                 parent_cmp.get_mle_message_tlv(mle.LinkMargin).link_margin) >
+                20)
+
+        # Check Child Id Request
+        messages = self.simulator.get_messages_sent_by(REED_1_2)
+        msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
+        msg.assertSentToNode(self.nodes[ROUTER_1_1])
+
+        # Mesh Impacting Criteria - Active Routers over REEDs
+        # ROUTER_1_2 would attach to LEADER_1_2
+        # Link quality configuration, so that REED_1_2 has the chance to respond
+
+        # Flush relative message queues
+        self.flush_nodes([LEADER_1_2, REED_1_2])
+
+        self.nodes[LEADER_1_2].set_link_quality(
+            self.nodes[ROUTER_1_2].get_addr64(), 2)
+        self.nodes[REED_1_2].set_link_quality(
+            self.nodes[ROUTER_1_2].get_addr64(), 2)
+        self.nodes[ROUTER_1_2].set_router_selection_jitter(1)
+        self.nodes[ROUTER_1_2].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[ROUTER_1_2].get_state(), 'router')
+
+        # Check Parent Response
+        messages = self.simulator.get_messages_sent_by(LEADER_1_2)
+
+        # Skip first response for first parent request
+        assert messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
+
+        parent_prefer = messages.next_mle_message(
+            mle.CommandType.PARENT_RESPONSE)
+        assert (parent_prefer), "Error: Expected parent response not found"
+
+        messages = self.simulator.get_messages_sent_by(REED_1_2)
+        parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
+        assert (parent_cmp), "Error: Expected parent response not found"
+
+        assert (parent_prefer.get_mle_message_tlv(
+            mle.LinkMargin).link_margin == parent_cmp.get_mle_message_tlv(
+                mle.LinkMargin).link_margin)
+
+        # Check Child Id Request
+        messages = self.simulator.get_messages_sent_by(ROUTER_1_2)
+        msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
+        msg.assertSentToNode(self.nodes[LEADER_1_2])
+
+        # Mesh Impacting Criteria - Highest Parent Priority value in the Connectivity TLV
+        # REED_1_1 would attach to ROUTER_1_2
+
+        # Flush relative message queues
+        self.flush_nodes([LEADER_1_2, ROUTER_1_2])
+
+        self.nodes[ROUTER_1_2].set_parent_priority(1)
+        self.nodes[REED_1_1].set_router_selection_jitter(1)
+        self.nodes[REED_1_1].set_router_upgrade_threshold(1)
+        self.nodes[REED_1_1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[REED_1_1].get_state(), 'child')
+
+        # Check Parent Response
+        messages = self.simulator.get_messages_sent_by(ROUTER_1_2)
+        parent_prefer = messages.next_mle_message(
+            mle.CommandType.PARENT_RESPONSE)
+        assert (parent_prefer), "Error: Expected parent response not found"
+
+        messages = self.simulator.get_messages_sent_by(LEADER_1_2)
+        parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
+        assert (parent_cmp), "Error: Expected parent response not found"
+
+        assert (parent_prefer.get_mle_message_tlv(
+            mle.LinkMargin).link_margin == parent_cmp.get_mle_message_tlv(
+                mle.LinkMargin).link_margin)
+
+        assert (parent_prefer.get_mle_message_tlv(mle.Connectivity).pp >
+                parent_cmp.get_mle_message_tlv(mle.Connectivity).pp)
+
+        # Check Child Id Request
+        messages = self.simulator.get_messages_sent_by(REED_1_1)
+        msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
+        msg.assertSentToNode(self.nodes[ROUTER_1_2])
+
+        # Mesh Impacting Criteria - Router with the most high-quality neighbors
+        # (Link Quality 3 field in the Connectivity TLV)
+        # MED_1_1 would attach to LEADER_1_2
+
+        self.nodes[REED_1_1].set_state('router')
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[REED_1_1].get_state(), 'router')
+
+        # Flush relative message queues
+        self.flush_nodes([LEADER_1_2, ROUTER_1_1])
+
+        self.nodes[MED_1_1].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[MED_1_1].get_state(), 'child')
+
+        # Check Parent Response
+        messages = self.simulator.get_messages_sent_by(LEADER_1_2)
+        parent_prefer = messages.next_mle_message(
+            mle.CommandType.PARENT_RESPONSE)
+        assert (parent_prefer), "Error: Expected parent response not found"
+
+        messages = self.simulator.get_messages_sent_by(ROUTER_1_1)
+        parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
+        assert (parent_cmp), "Error: Expected parent response not found"
+
+        assert (parent_prefer.get_mle_message_tlv(
+            mle.LinkMargin).link_margin == parent_cmp.get_mle_message_tlv(
+                mle.LinkMargin).link_margin)
+        assert (parent_prefer.get_mle_message_tlv(
+            mle.Connectivity).pp == parent_cmp.get_mle_message_tlv(
+                mle.Connectivity).pp)
+        assert (parent_prefer.get_mle_message_tlv(
+            mle.Connectivity).link_quality_3 > parent_cmp.get_mle_message_tlv(
+                mle.Connectivity).link_quality_3)
+
+        # Check Child Id Request
+        messages = self.simulator.get_messages_sent_by(MED_1_1)
+        msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
+        msg.assertSentToNode(self.nodes[LEADER_1_2])
+
+        # Child Impacting Criteria - A Version number in the Version TLV
+        # equal to or higher than the version that implements features
+        # desirable to the Child MED_1_2 would attach to ROUTER_1_2
+
+        # Flush relative message queues
+        self.flush_nodes([ROUTER_1_2, ROUTER_1_1])
+
+        self.nodes[ROUTER_1_1].set_parent_priority(1)
+        self.nodes[MED_1_2].start()
+        self.simulator.go(5)
+        self.assertEqual(self.nodes[MED_1_2].get_state(), 'child')
+
+        # Check Parent Response
+        messages = self.simulator.get_messages_sent_by(ROUTER_1_2)
+        parent_prefer = messages.next_mle_message(
+            mle.CommandType.PARENT_RESPONSE)
+        assert (parent_prefer), "Error: Expected parent response not found"
+
+        messages = self.simulator.get_messages_sent_by(ROUTER_1_1)
+        parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE)
+        assert (parent_cmp), "Error: Expected parent response not found"
+
+        assert (parent_prefer.get_mle_message_tlv(
+            mle.LinkMargin).link_margin == parent_cmp.get_mle_message_tlv(
+                mle.LinkMargin).link_margin)
+        assert (parent_prefer.get_mle_message_tlv(
+            mle.Connectivity).pp == parent_cmp.get_mle_message_tlv(
+                mle.Connectivity).pp)
+        assert (parent_prefer.get_mle_message_tlv(
+            mle.Connectivity).link_quality_3 == parent_cmp.get_mle_message_tlv(
+                mle.Connectivity).link_quality_3)
+        assert (parent_prefer.get_mle_message_tlv(mle.Version).version >
+                parent_cmp.get_mle_message_tlv(mle.Version).version)
+
+        # Check Child Id Request
+        messages = self.simulator.get_messages_sent_by(MED_1_2)
+        msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST)
+        msg.assertSentToNode(self.nodes[ROUTER_1_2])
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/toranj/README.md b/tests/toranj/README.md
index 6bf819a..4a33519 100644
--- a/tests/toranj/README.md
+++ b/tests/toranj/README.md
@@ -6,15 +6,14 @@
 - It can be used to simulate multiple nodes forming complex network topologies.
 - It allows testing of network interactions between many nodes (IPv6 traffic exchanges).
 
-`toranj` is developed in Python. `toranj` runs wpantund natively with OpenThread in NCP mode on POSIX simulation platform.
-`toranj` tests will run as part of travis pull request validation in OpenThread and/or `wpantund` GitHub projects.
-
+`toranj` is developed in Python. `toranj` runs wpantund natively with OpenThread in NCP mode on POSIX simulation platform. `toranj` tests will run as part of GitHub Actions pull request validation in OpenThread and/or `wpantund` GitHub projects.
 
 ## Setup
 
 `toranj` requires `wpantund` to be installed.
+
 - Please follow [`wpantund` installation guide](https://github.com/openthread/wpantund/blob/master/INSTALL.md#wpantund-installation-guide). Note that `toranj` expects `wpantund` installed from latest master branch.
-- Alternative way to install `wpantund` is to use the same commands from travis `before_install` [script](https://github.com/openthread/openthread/blob/ef940b06594b370176b724733dbd7ad09617a693/.travis/before_install.sh#L110-L127) for build target `toranj-test-framework`.
+- Alternative way to install `wpantund` is to use the same commands from git workflow [Simulation](https://github.com/openthread/openthread/blob/4b55284bd20f99a88e8e2c617ba358a0a5547f5d/.github/workflows/simulation.yml#L336-L341) for build target `toranj-test-framework`.
 
 To run all tests, `start` script can be used. This script will build OpenThread with proper configuration options and starts running all test.
 
@@ -39,7 +38,6 @@
 
 `wpan.Node()` class creates a Thread node instance. It creates a sub-process to run `wpantund` and OpenThread, and provides methods to control the node.
 
-
 ```python
 >>> import wpan
 >>> node1 = wpan.Node()
@@ -49,6 +47,7 @@
 >>> node2
 Node (index=2, interface_name=wpan2)
 ```
+
 Note: You may need to run as `sudo` to allow `wpantund` to create tunnel interface (i.e., use `sudo python`).
 
 ### `wpan.Node` methods providing `wpanctl` commands
@@ -65,6 +64,7 @@
 ```
 
 Example:
+
 ```python
 >>> node.get(wpan.WPAN_NAME)
 '"test-network"'
@@ -77,6 +77,7 @@
 ```
 
 - Common network operations:
+
 ```python
     node.reset()            # Reset the NCP
     node.status()           # Get current status
@@ -91,6 +92,7 @@
 ```
 
 Example:
+
 ```python
 >>> result = node.status()
 >>> print result
@@ -126,6 +128,7 @@
 ```
 
 - Scan:
+
 ```python
     node.active_scan(channel=None)
     node.energy_scan(channel=None)
@@ -133,7 +136,8 @@
     node.permit_join(duration_sec=None, port=None, udp=True, tcp=True)
 ```
 
--  On-mesh prefixes and off-mesh routes:
+- On-mesh prefixes and off-mesh routes:
+
 ```python
     node.config_gateway(prefix, default_route=False)
     node.add_route(route_prefix, prefix_len_in_bytes=None, priority=None)
@@ -144,22 +148,15 @@
 
 `wpan` module provides variables for different `wpantund` properties. Some commonly used are:
 
-- Network/NCP properties:
-        WPAN_STATE, WPAN_NAME, WPAN_PANID, WPAN_XPANID, WPAN_KEY, WPAN_CHANNEL, WPAN_HW_ADDRESS,
-        WPAN_EXT_ADDRESS, WPAN_POLL_INTERVAL, WPAN_NODE_TYPE, WPAN_ROLE, WPAN_PARTITION_ID
+- Network/NCP properties: WPAN_STATE, WPAN_NAME, WPAN_PANID, WPAN_XPANID, WPAN_KEY, WPAN_CHANNEL, WPAN_HW_ADDRESS, WPAN_EXT_ADDRESS, WPAN_POLL_INTERVAL, WPAN_NODE_TYPE, WPAN_ROLE, WPAN_PARTITION_ID
 
-- IPv6 Addresses:
-        WPAN_IP6_LINK_LOCAL_ADDRESS, WPAN_IP6_MESH_LOCAL_ADDRESS, WPAN_IP6_MESH_LOCAL_PREFIX,
-        WPAN_IP6_ALL_ADDRESSES, WPAN_IP6_MULTICAST_ADDRESSES
+- IPv6 Addresses: WPAN_IP6_LINK_LOCAL_ADDRESS, WPAN_IP6_MESH_LOCAL_ADDRESS, WPAN_IP6_MESH_LOCAL_PREFIX, WPAN_IP6_ALL_ADDRESSES, WPAN_IP6_MULTICAST_ADDRESSES
 
-- Thread Properties:
-        WPAN_THREAD_RLOC16, WPAN_THREAD_ROUTER_ID, WPAN_THREAD_LEADER_ADDRESS,
-        WPAN_THREAD_LEADER_ROUTER_ID, WPAN_THREAD_LEADER_WEIGHT, WPAN_THREAD_LEADER_NETWORK_DATA,
+- Thread Properties: WPAN_THREAD_RLOC16, WPAN_THREAD_ROUTER_ID, WPAN_THREAD_LEADER_ADDRESS, WPAN_THREAD_LEADER_ROUTER_ID, WPAN_THREAD_LEADER_WEIGHT, WPAN_THREAD_LEADER_NETWORK_DATA,
 
         WPAN_THREAD_CHILD_TABLE, WPAN_THREAD_CHILD_TABLE_ADDRESSES, WPAN_THREAD_NEIGHBOR_TABLE,
         WPAN_THREAD_ROUTER_TABLE
 
-
 Method `join_node()` can be used by a node to join another node:
 
 ```python
@@ -177,6 +174,7 @@
 #### Example (simple 3-node topology)
 
 Script below shows how to create a 3-node network topology with `node1` and `node2` being routers, and `node3` an end-device connected to `node2`:
+
 ```python
 >>> import wpan
 >>> node1 = wpan.Node()
@@ -223,12 +221,14 @@
 ```
 
 - `src` and `dst` can be
-   - either a string containing an IPv6 address
-   - or a tuple (ipv6 address as string, port). if no port is given, a random port number is used.
+
+  - either a string containing an IPv6 address
+  - or a tuple (ipv6 address as string, port). if no port is given, a random port number is used.
 
 - `data` can be
-   - either a string containing the message to be sent,
-   - or an int indicating size of the message (a random message with the given length will be generated).
+
+  - either a string containing the message to be sent,
+  - or an int indicating size of the message (a random message with the given length will be generated).
 
 - `count` gives number of times the message will be sent (default is 1).
 
@@ -256,6 +256,7 @@
 #### Example
 
 Sending 10 messages containing `"Hello there!"` from `node1` to `node2` using their mesh-local addresses:
+
 ```python
 # `node1` and `node2` are already joined and are part of the same Thread network.
 
@@ -301,17 +302,17 @@
 
 ### Logs and Verbose mode
 
-Every `wpan.Node()` instance will save its corresponding `wpantund` logs. By default the logs are saved in a file
-`wpantun-log<node_index>.log`. By setting `wpan.Node__TUND_LOG_TO_FILE` to `False` the logs are written to `stdout` as the test-cases are executed.
+Every `wpan.Node()` instance will save its corresponding `wpantund` logs. By default the logs are saved in a file `wpantun-log<node_index>.log`. By setting `wpan.Node__TUND_LOG_TO_FILE` to `False` the logs are written to `stdout` as the test-cases are executed.
 
 When `start.sh` script is used to run all test-cases, if any test fails, to help with debugging of the issue, the last 30 lines of `wpantund` logs of every node involved in the test-case is dumped to `stdout`.
 
-A `wpan.Node()` instance can also provide additional logs and info as the test-cases are run (verbose mode). By default this is disabled. It can be enabled for a node instance when it is created:
+A `wpan.Node()` instance can also provide additional logs and info as the test-cases are run (verbose mode). It can be enabled for a node instance when it is created:
+
 ```python
     node = wpan.Node(verbose=True)     # `node` instance will provide extra logs.
 ```
 
-Alternatively, `wpan.Node._VERBOSE` settings can be changed to enable verbose logging for all nodes.
+Alternatively, `wpan.Node._VERBOSE` settings can be changed to enable verbose logging for all nodes. The default value of `wpan.Node._VERBOSE` is determined from environment variable `TORANJ_VERBOSE` (verbose mode is enabled when env variable is set to any of `1`, `True`, `Yes`, `Y`, `On` (case-insensitive)), otherwise it is disabled. When `TORANJ_VERBOSE` is enabled, the OpenThread logging is also enabled (and collected in `wpantund-log<node_index>.log`files) on all nodes.
 
 Here is example of small test script and its corresponding log output with `verbose` mode enabled:
 
@@ -336,6 +337,7 @@
 wpan.Node.perform_async_tx_rx()
 
 ```
+
 ```
 $ Node1.__init__() cmd: /usr/local/sbin/wpantund -o Config:NCP:SocketPath "system:../../examples/apps/ncp/ot-ncp-ftd 1" -o Config:TUN:InterfaceName wpan1 -o Config:NCP:DriverName spinel -o Daemon:SyslogMask "all -debug"
 $ Node2.__init__() cmd: /usr/local/sbin/wpantund -o Config:NCP:SocketPath "system:../../examples/apps/ncp/ot-ncp-ftd 2" -o Config:TUN:InterfaceName wpan2 -o Config:NCP:DriverName spinel -o Daemon:SyslogMask "all -debug"
@@ -366,6 +368,6 @@
 
 ```
 
-------
+---
 
 What does `"toranj"` mean? it's the name of a common symmetric weaving [pattern](https://en.wikipedia.org/wiki/Persian_carpet#/media/File:Toranj_-_special_circular_design_of_Iranian_carpets.JPG) used in Persian carpets.
diff --git a/tests/toranj/build.sh b/tests/toranj/build.sh
index f16fcc0..c498afa 100755
--- a/tests/toranj/build.sh
+++ b/tests/toranj/build.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 #  Copyright (c) 2018, The OpenThread Authors.
 #  All rights reserved.
@@ -27,19 +27,18 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-cd $(dirname $0)
-cd ../..
-
-display_usage() {
+display_usage()
+{
     echo ""
     echo "Toranj Build script "
     echo ""
-    echo "Usage: $(basename $0) [options] <config>"
+    echo "Usage: $(basename "$0") [options] <config>"
     echo "    <config> can be:"
-    echo "        ncp        : Build OpenThread NCP FTD mode with POSIX platform"
-    echo "        rcp        : Build OpenThread RCP (NCP in radio mode) with POSIX platform"
-    echo "        posix-app  : Build OpenThread POSIX App NCP"
+    echo "        ncp        : Build OpenThread NCP FTD mode with simulation platform"
+    echo "        rcp        : Build OpenThread RCP (NCP in radio mode) with simulation platform"
+    echo "        posix      : Build OpenThread POSIX App NCP"
     echo "        cmake      : Configure and build OpenThread using cmake/ninja (RCP and NCP) only"
+    echo "        cmake-posix: Configure and build OpenThread POSIX host using cmake/ninja"
     echo ""
     echo "Options:"
     echo "        -c/--enable-coverage  Enable code coverage"
@@ -47,22 +46,25 @@
     echo ""
 }
 
-die() {
-    echo " *** ERROR: " $*
+die()
+{
+    echo " *** ERROR: " "$*"
     exit 1
 }
 
+cd "$(dirname "$0")" || die "cd failed"
+cd ../.. || die "cd failed"
+
 coverage=no
 tests=no
 
-while [ $# -ge 2 ]
-do
+while [ $# -ge 2 ]; do
     case $1 in
-        -c|--enable-coverage)
+        -c | --enable-coverage)
             coverage=yes
             shift
             ;;
-        -t|--enable-tests)
+        -t | --enable-tests)
             tests=yes
             shift
             ;;
@@ -81,15 +83,13 @@
 
 build_config=$1
 
-configure_options="                \
-    --disable-docs                 \
-    --enable-tests=$tests          \
-    --enable-coverage=$coverage    \
-    --enable-ftd                   \
-    --enable-ncp                   \
-    "
-
-cppflags_config='-DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"../tests/toranj/openthread-core-toranj-config.h\"'
+configure_options=(
+    "--disable-docs"
+    "--enable-tests=$tests"
+    "--enable-coverage=$coverage"
+    "--enable-ftd"
+    "--enable-ncp"
+)
 
 if [ -n "${top_builddir}" ]; then
     top_srcdir=$(pwd)
@@ -104,12 +104,13 @@
         echo "==================================================================================================="
         echo "Building OpenThread NCP FTD mode with POSIX platform"
         echo "==================================================================================================="
-        ./bootstrap || die
-        cd "${top_builddir}"
-        ${top_srcdir}/configure                 \
-            CPPFLAGS="$cppflags_config"         \
-            --with-examples=posix               \
-            $configure_options || die
+        ./bootstrap || die "bootstrap failed"
+        cd "${top_builddir}" || die "cd failed"
+        cppflags_config='-DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"../tests/toranj/openthread-core-toranj-config-simulation.h\"'
+        ${top_srcdir}/configure \
+            CPPFLAGS="$cppflags_config" \
+            --with-examples=simulation \
+            "${configure_options[@]}" || die
         make -j 8 || die
         ;;
 
@@ -117,45 +118,61 @@
         echo "===================================================================================================="
         echo "Building OpenThread RCP (NCP in radio mode) with POSIX platform"
         echo "===================================================================================================="
-        ./bootstrap || die
-        cd "${top_builddir}"
-        ${top_srcdir}/configure                 \
-            CPPFLAGS="$cppflags_config"         \
-            --enable-coverage=${coverage}       \
-            --enable-ncp                        \
-            --enable-radio-only                 \
-            --with-examples=posix               \
-            --disable-docs                      \
+        ./bootstrap || die "bootstrap failed"
+        cd "${top_builddir}" || die "cd failed"
+        cppflags_config='-DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"../tests/toranj/openthread-core-toranj-config-simulation.h\"'
+        ${top_srcdir}/configure \
+            CPPFLAGS="$cppflags_config " \
+            --enable-coverage=${coverage} \
+            --enable-ncp \
+            --enable-radio-only \
+            --with-examples=simulation \
+            --disable-docs \
             --enable-tests=$tests || die
         make -j 8 || die
         ;;
 
-    posix-app|posixapp)
+    posix | posix-app | posixapp)
         echo "===================================================================================================="
         echo "Building OpenThread POSIX App NCP"
         echo "===================================================================================================="
-        ./bootstrap || die
-        cd "${top_builddir}"
-        ${top_srcdir}/configure                 \
-            CPPFLAGS="$cppflags_config -DOPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE=1 -DOPENTHREAD_POSIX_RCP_UART_ENABLE=1" \
-            --enable-posix-app                  \
-            $configure_options || die
+        ./bootstrap || die "bootstrap failed"
+        cd "${top_builddir}" || die "cd failed"
+        cppflags_config='-DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"../tests/toranj/openthread-core-toranj-config-posix.h\"'
+        ${top_srcdir}/configure \
+            CPPFLAGS="$cppflags_config" \
+            --with-platform=posix \
+            "${configure_options[@]}" || die
         make -j 8 || die
         ;;
 
     cmake)
         echo "===================================================================================================="
-        echo "Building OpenThread (NCP/CLI for FTD/MTD/RCP mode) with POSIX platform using cmake"
+        echo "Building OpenThread (NCP/CLI for FTD/MTD/RCP mode) with simulation platform using cmake"
         echo "===================================================================================================="
-        cmake -GNinja -DOT_PLATFORM=posix -DOT_CONFIG=../tests/toranj/openthread-core-toranj-config.h . || die
+        cd "${top_builddir}" || die "cd failed"
+        cmake -GNinja -DOT_PLATFORM=simulation -DOT_COMPILE_WARNING_AS_ERROR=on -DOT_APP_CLI=off \
+            -DOT_CONFIG=../tests/toranj/openthread-core-toranj-config-simulation.h \
+            "${top_srcdir}" || die
+        ninja || die
+        ;;
+
+    cmake-posix-host | cmake-posix | cmake-p)
+        echo "===================================================================================================="
+        echo "Building OpenThread POSIX host platform using cmake"
+        echo "===================================================================================================="
+        cd "${top_builddir}" || die "cd failed"
+        cmake -GNinja -DOT_PLATFORM=posix -DOT_COMPILE_WARNING_AS_ERROR=on -DOT_APP_CLI=off \
+            -DOT_CONFIG=../tests/toranj/openthread-core-toranj-config-posix.h \
+            "${top_srcdir}" || die
         ninja || die
         ;;
 
     *)
-      echo "Error: Unknown configuration \"$1\""
-      display_usage
-      exit 1
-      ;;
+        echo "Error: Unknown configuration \"$1\""
+        display_usage
+        exit 1
+        ;;
 esac
 
 exit 0
diff --git a/tests/toranj/openthread-core-toranj-config-posix.h b/tests/toranj/openthread-core-toranj-config-posix.h
new file mode 100644
index 0000000..67e65fa
--- /dev/null
+++ b/tests/toranj/openthread-core-toranj-config-posix.h
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OPENTHREAD_CORE_TORANJ_CONFIG_POSIX_H_
+#define OPENTHREAD_CORE_TORANJ_CONFIG_POSIX_H_
+
+/**
+ * This header file defines the OpenThread core configuration options for toranj with POSIX platform.
+ *
+ */
+
+// Include the common configuration for all platforms.
+#include "openthread-core-toranj-config.h"
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_INFO
+ *
+ * The platform-specific string to insert into the OpenThread version string.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_INFO "POSIX-toranj"
+
+/**
+ * @def OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
+ *
+ * Define to 1 to enable Border Router support.
+ *
+ */
+#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
+ *
+ * Define as 1 to enable PTY device support in POSIX app.
+ *
+ */
+#define OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE 1
+
+#define OPENTHREAD_POSIX_CONFIG_RCP_BUS OT_POSIX_RCP_BUS_UART
+
+#endif /* OPENTHREAD_CORE_TORANJ_CONFIG_POSIX_H_ */
diff --git a/tests/toranj/openthread-core-toranj-config-simulation.h b/tests/toranj/openthread-core-toranj-config-simulation.h
new file mode 100644
index 0000000..7b68873
--- /dev/null
+++ b/tests/toranj/openthread-core-toranj-config-simulation.h
@@ -0,0 +1,62 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OPENTHREAD_CORE_TORANJ_CONFIG_SIMULATION_H_
+#define OPENTHREAD_CORE_TORANJ_CONFIG_SIMULATION_H_
+
+/**
+ * This header file defines the OpenThread core configuration for toranj with simulation platform.
+ *
+ */
+
+// Include the common configuration for all platforms.
+#include "openthread-core-toranj-config.h"
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_INFO
+ *
+ * The platform-specific string to insert into the OpenThread version string.
+ *
+ */
+#if OPENTHREAD_RADIO
+#define OPENTHREAD_CONFIG_PLATFORM_INFO "SIMULATION-RCP-toranj"
+#else
+#define OPENTHREAD_CONFIG_PLATFORM_INFO "SIMULATION-toranj"
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+ *
+ * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
+ *
+ * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
+ *
+ */
+#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
+
+#endif /* OPENTHREAD_CORE_TORANJ_CONFIG_SIMULATION_H_ */
diff --git a/tests/toranj/openthread-core-toranj-config.h b/tests/toranj/openthread-core-toranj-config.h
index 3b84958..15c6ff3 100644
--- a/tests/toranj/openthread-core-toranj-config.h
+++ b/tests/toranj/openthread-core-toranj-config.h
@@ -26,30 +26,17 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef OPENTHREAD_CORE_TORANJ_CONFIG_H_
-#define OPENTHREAD_CORE_TORANJ_CONFIG_H_
-
 /**
  * This header file defines the OpenThread core configuration options used in NCP build for `toranj` test framework.
  *
  */
 
-#ifndef OPENTHREAD_RADIO
-#define OPENTHREAD_RADIO 0
+#if !defined(OPENTHREAD_CORE_TORANJ_CONFIG_SIMULATION_H_) && !defined(OPENTHREAD_CORE_TORANJ_CONFIG_POSIX_H_)
+#error "This header file should only be included through the platform-specific one"
 #endif
 
-/**
- * @def OPENTHREAD_CONFIG_PLATFORM_INFO
- *
- * The platform-specific string to insert into the OpenThread version string.
- *
- */
-#if OPENTHREAD_RADIO
-#define OPENTHREAD_CONFIG_PLATFORM_INFO                         "POSIX-RCP-toranj"
-#elif OPENTHREAD_PLATFORM_POSIX_APP
-#define OPENTHREAD_CONFIG_PLATFORM_INFO                         "POSIX-App-toranj"
-#else
-#define OPENTHREAD_CONFIG_PLATFORM_INFO                         "POSIX-toranj"
+#ifndef OPENTHREAD_RADIO
+#define OPENTHREAD_RADIO 0
 #endif
 
 /**
@@ -58,7 +45,7 @@
  * Define to 1 to enable Border Router support.
  *
  */
-#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE                  1
+#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
@@ -66,7 +53,15 @@
  * Define to 1 to enable Commissioner support.
  *
  */
-#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE                   1
+#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_COMMISSIONER_MAX_JOINER_ENTRIES
+ *
+ * The maximum number of Joiner entries maintained by the Commissioner.
+ *
+ */
+#define OPENTHREAD_CONFIG_COMMISSIONER_MAX_JOINER_ENTRIES 4
 
 /**
  * @def OPENTHREAD_CONFIG_DIAG_ENABLE
@@ -74,7 +69,7 @@
  * Define to 1 to enable Factory Diagnostics support.
  *
  */
-#define OPENTHREAD_CONFIG_DIAG_ENABLE                           1
+#define OPENTHREAD_CONFIG_DIAG_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_JOINER_ENABLE
@@ -82,7 +77,7 @@
  * Define to 1 to enable Joiner support.
  *
  */
-#define OPENTHREAD_CONFIG_JOINER_ENABLE                         1
+#define OPENTHREAD_CONFIG_JOINER_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
@@ -90,7 +85,7 @@
  * Define to 1 to support injecting Service entries into the Thread Network Data.
  *
  */
-#define OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE                1
+#define OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_LEGACY_ENABLE
@@ -98,7 +93,7 @@
  * Define to 1 to enable legacy network support.
  *
  */
-#define OPENTHREAD_CONFIG_LEGACY_ENABLE                         1
+#define OPENTHREAD_CONFIG_LEGACY_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
@@ -106,7 +101,7 @@
  * Define to 1 to enable the Jam Detection service.
  *
  */
-#define OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE                  1
+#define OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS
@@ -114,7 +109,7 @@
  * The number of message buffers in the buffer pool.
  *
  */
-#define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS                   256
+#define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 256
 
 /**
  * @def OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_ENTRIES
@@ -122,7 +117,25 @@
  * The number of EID-to-RLOC cache entries.
  *
  */
-#define OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_ENTRIES                 32
+#define OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_ENTRIES 16
+
+/**
+ * @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT
+ *
+ * The timeout value (in seconds) waiting for a address notification response after sending an address query.
+ *
+ * Default: 3 seconds
+ *
+ */
+#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_TIMEOUT 6
+
+/**
+ * @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY
+ *
+ * Initial retry delay for address query (in seconds).
+ *
+ */
+#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_INITIAL_RETRY_DELAY 4
 
 /**
  * @def OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY
@@ -132,7 +145,28 @@
  * Default: 28800 seconds (480 minutes or 8 hours)
  *
  */
-#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY         120
+#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY 120
+
+/**
+ * @def OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES
+ *
+ * The maximum number of EID-to-RLOC cache entries that can be uses for "snoop optimization" where an entry is created
+ * by inspecting a received message.
+ *
+ */
+#define OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_MAX_SNOOP_ENTRIES 2
+
+/**
+ * @def OPENTHREAD_CONFIG_TMF_SNOOP_CACHE_ENTRY_TIMEOUT
+ *
+ * The timeout value (in seconds) blocking eviction of an address cache entry created through snoop optimization (i.e.,
+ * inspection of a received message). After the timeout expires the entry can be reclaimed again. This timeout allows
+ * a longer response delay for a received message giving more chance that a snooped entry will be used (avoiding
+ * sending Address Query when a response message is sent to same destination from which the message was received
+ * earlier).
+ *
+ */
+#define OPENTHREAD_CONFIG_TMF_SNOOP_CACHE_ENTRY_TIMEOUT 3
 
 /**
  * @def OPENTHREAD_CONFIG_MLE_MAX_CHILDREN
@@ -140,7 +174,7 @@
  * The maximum number of children.
  *
  */
-#define OPENTHREAD_CONFIG_MLE_MAX_CHILDREN                          32
+#define OPENTHREAD_CONFIG_MLE_MAX_CHILDREN 32
 
 /**
  * @def OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT
@@ -148,7 +182,7 @@
  * The default child timeout value (in seconds).
  *
  */
-#define OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT                 120
+#define OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT 120
 
 /**
  * @def OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD
@@ -156,7 +190,7 @@
  * The maximum number of supported IPv6 address registrations per child.
  *
  */
-#define OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD                    10
+#define OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD 10
 
 /**
  * @def OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS
@@ -164,7 +198,7 @@
  * The maximum number of supported IPv6 addresses allows to be externally added.
  *
  */
-#define OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS                      8
+#define OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS 8
 
 /**
  * @def OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS
@@ -172,7 +206,7 @@
  * The maximum number of supported IPv6 multicast addresses allows to be externally added.
  *
  */
-#define OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS            4
+#define OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS 4
 
 /**
  * @def OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
@@ -188,7 +222,7 @@
  * The number of MAC Filter entries.
  *
  */
-#define OPENTHREAD_CONFIG_MAC_FILTER_SIZE                       80
+#define OPENTHREAD_CONFIG_MAC_FILTER_SIZE 80
 
 /**
  * @def OPENTHREAD_CONFIG_LOG_OUTPUT
@@ -196,7 +230,7 @@
  * Selects if, and where the LOG output goes to.
  *
  */
-#define OPENTHREAD_CONFIG_LOG_OUTPUT                            OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL
+#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_APP
 
 /**
  * @def OPENTHREAD_CONFIG_LOG_LEVEL
@@ -204,7 +238,7 @@
  * The log level (used at compile time).
  *
  */
-#define OPENTHREAD_CONFIG_LOG_LEVEL                             OT_LOG_LEVEL_INFO
+#define OPENTHREAD_CONFIG_LOG_LEVEL OT_LOG_LEVEL_INFO
 
 /**
  * @def OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
@@ -212,7 +246,7 @@
  * Define as 1 to enable dynamic log level control.
  *
  */
-#define OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE              1
+#define OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL
@@ -220,7 +254,7 @@
  * Define to prepend the log level to all log messages
  *
  */
-#define OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL                     0
+#define OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL 0
 
 /**
  * @def OPENTHREAD_CONFIG_LOG_PREPEND_REGION
@@ -228,7 +262,7 @@
  * Define to prepend the log region to all log messages
  *
  */
-#define OPENTHREAD_CONFIG_LOG_PREPEND_REGION                    0
+#define OPENTHREAD_CONFIG_LOG_PREPEND_REGION 0
 
 /**
  * @def OPENTHREAD_CONFIG_LOG_SUFFIX
@@ -236,7 +270,7 @@
  * Define suffix to append at the end of logs.
  *
  */
-#define OPENTHREAD_CONFIG_LOG_SUFFIX                            ""
+#define OPENTHREAD_CONFIG_LOG_SUFFIX ""
 
 /**
  * @def OPENTHREAD_CONFIG_LOG_PLATFORM
@@ -244,7 +278,7 @@
  * Define to enable platform region logging.
  *
  */
-#define OPENTHREAD_CONFIG_LOG_PLATFORM                          1
+#define OPENTHREAD_CONFIG_LOG_PLATFORM 1
 
 /**
  * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE
@@ -260,7 +294,7 @@
  *  The size of NCP message buffer in bytes
  *
  */
-#define OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE                    4096
+#define OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE 4096
 
 /**
  * @def OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
@@ -268,7 +302,7 @@
  * Enable setting steering data out of band.
  *
  */
-#define OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE          1
+#define OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
@@ -279,7 +313,7 @@
  * and mesh-local IP address as the source address) to its previous parent.
  *
  */
-#define OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH    1
+#define OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH 1
 
 /**
  * @def OPENTHREAD_CONFIG_MLE_SEND_LINK_REQUEST_ON_ADV_TIMEOUT
@@ -287,7 +321,7 @@
  * Define to 1 to send an MLE Link Request when MAX_NEIGHBOR_AGE is reached for a neighboring router.
  *
  */
-#define OPENTHREAD_CONFIG_MLE_SEND_LINK_REQUEST_ON_ADV_TIMEOUT  1
+#define OPENTHREAD_CONFIG_MLE_SEND_LINK_REQUEST_ON_ADV_TIMEOUT 1
 
 /**
  * @def OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE
@@ -295,7 +329,7 @@
  * Define as 1 to enable Channel Manager support.
  *
  */
-#define OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE                1
+#define OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
@@ -303,7 +337,7 @@
  * Define as 1 to enable Channel Monitor support.
  *
  */
-#define OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE                1
+#define OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE 1
 
 /**
  * @def OPENTHREAD_CONFIG_CHANNEL_MANAGER_MINIMUM_DELAY
@@ -316,7 +350,7 @@
  * Applicable only if Channel Manager feature is enabled (i.e., `OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE` is set).
  *
  */
-#define OPENTHREAD_CONFIG_CHANNEL_MANAGER_MINIMUM_DELAY         2
+#define OPENTHREAD_CONFIG_CHANNEL_MANAGER_MINIMUM_DELAY 2
 
 /**
  * @def OPENTHREAD_CONFIG_CHANNEL_MANAGER_THRESHOLD_TO_SKIP_FAVORED
@@ -394,33 +428,38 @@
  * Define as 1 to enable support for adding of auto-configured SLAAC addresses by OpenThread.
  *
  */
-#define OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE    1
+#define OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 1
 
 #if OPENTHREAD_RADIO
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE
  *
  * Define to 1 if you want to enable software ACK timeout logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
  *
  * Define to 1 if you want to enable software retransmission logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1
 
 /**
- * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
  *
  * Define to 1 if you want to enable software CSMA-CA backoff logic.
  *
  */
-#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE          1
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1
+
+/**
+ * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
+ *
+ * Define to 1 if you want to enable software transmission security logic.
+ *
+ */
+#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 1
 #endif // OPENTHREAD_RADIO
-
-#endif /* OPENTHREAD_CORE_TORANJ_CONFIG_H_ */
-
diff --git a/tests/toranj/start.sh b/tests/toranj/start.sh
index 39cbebd..ba8abda 100755
--- a/tests/toranj/start.sh
+++ b/tests/toranj/start.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 #  Copyright (c) 2018, The OpenThread Authors.
 #  All rights reserved.
@@ -27,46 +27,45 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-die() {
-    echo " *** ERROR: " $*
+die()
+{
+    echo " *** ERROR: " "$*"
     exit 1
 }
 
-cleanup() {
+cleanup()
+{
     # Clear logs and flash files
-    sudo rm tmp/*.flash tmp/*.data tmp/*.swap > /dev/null 2>&1
-    sudo rm *.log > /dev/null 2>&1
+    sudo rm tmp/*.flash tmp/*.data tmp/*.swap >/dev/null 2>&1
+    sudo rm ./*.log >/dev/null 2>&1
 
     # Clear any wpantund instances
-    sudo killall wpantund > /dev/null 2>&1
+    sudo killall wpantund >/dev/null 2>&1
 
-    wpan_interfaces=$(ifconfig 2>/dev/null | grep -o wpan[0-9]*)
-
-    for interface in $wpan_interfaces; do
-        sudo ip link delete $interface > /dev/null 2>&1
-    done
+    while read -r interface; do
+        sudo ip link delete "$interface" >/dev/null 2>&1
+    done < <(ifconfig 2>/dev/null | grep -o "wpan[0-9]*")
 
     sleep 0.3
 }
 
-run() {
+run()
+{
     counter=0
     while true; do
 
-        if sudo -E python $1; then
+        if sudo -E python "$1"; then
             cleanup
             return
         fi
 
-        # On Travis, we allow a failed test to be retried up to 3 attempts.
-        if [ "$BUILD_TARGET" = "toranj-test-framework" ]; then
-            if [ "$counter" -lt 2 ]; then
-                counter=$((counter+1))
-                echo Attempt $counter running "$1" failed. Trying again.
-                cleanup
-                sleep 10
-                continue
-            fi
+        # We allow a failed test to be retried up to 3 attempts.
+        if [ "$counter" -lt 2 ]; then
+            counter=$((counter + 1))
+            echo Attempt $counter running "$1" failed. Trying again.
+            cleanup
+            sleep 10
+            continue
         fi
 
         echo " *** TEST FAILED"
@@ -75,7 +74,7 @@
     done
 }
 
-cd $(dirname $0)
+cd "$(dirname "$0")" || die "cd failed"
 
 if [ "$COVERAGE" = 1 ]; then
     coverage_option="--enable-coverage"
@@ -83,21 +82,21 @@
     coverage_option=""
 fi
 
-case $TORANJ_POSIX_APP_RCP_MODEL in
-    1|yes)
-        use_posix_app_with_rcp=yes
+case $TORANJ_POSIX_RCP_MODEL in
+    1 | yes)
+        use_posix_with_rcp=yes
         ;;
     *)
-        use_posix_app_with_rcp=no
+        use_posix_with_rcp=no
         ;;
 esac
 
-if [ "$use_posix_app_with_rcp" = "no" ]; then
-    ./build.sh ${coverage_option} ncp || die
+if [ "$use_posix_with_rcp" = "no" ]; then
+    ./build.sh ${coverage_option} ncp || die "ncp build failed"
 
 else
-    ./build.sh ${coverage_option} rcp || die
-    ./build.sh ${coverage_option} posix-app || die
+    ./build.sh ${coverage_option} rcp || die "rcp build failed"
+    ./build.sh ${coverage_option} posix || die "posix build failed"
 fi
 
 cleanup
@@ -140,6 +139,10 @@
 run test-036-wpantund-host-route-management.py
 run test-037-wpantund-auto-add-route-for-on-mesh-prefix.py
 run test-038-clear-address-cache-for-sed.py
+run test-039-address-cache-table-snoop.py
+run test-040-network-data-stable-full.py
+run test-041-lowpan-fragmentation.py
+run test-042-meshcop-joiner-discerner.py
 run test-100-mcu-power-state.py
 run test-600-channel-manager-properties.py
 run test-601-channel-manager-channel-change.py
diff --git a/tests/toranj/test-001-get-set.py b/tests/toranj/test-001-get-set.py
index c8a841d..cdc7b80 100644
--- a/tests/toranj/test-001-get-set.py
+++ b/tests/toranj/test-001-get-set.py
@@ -174,21 +174,21 @@
     wpan.WPAN_THREAD_STABLE_LEADER_NETWORK_DATA,
 ]
 
-all_posix_app_gettable_props = [wpan.WPAN_RCP_VERSION]
+all_posix_gettable_props = [wpan.WPAN_RCP_VERSION]
 
-# note: partitionid only takes effect after forming one Thread network.
+# note: Partition Id only takes effect after forming one Thread network.
 node.set(wpan.WPAN_PARTITION_ID, '12345678')
 
 node.form('get-set')
 
-# verify that partitionid property is indeed changed.
+# verify that Partition Id property is indeed changed.
 verify(int(node.get(wpan.WPAN_PARTITION_ID), 0) == 12345678)
 
 for prop in all_gettable_props:
     node.get(prop)
 
-if node.using_posix_app_with_rcp:
-    for prop in all_posix_app_gettable_props:
+if node.using_posix_with_rcp:
+    for prop in all_posix_gettable_props:
         node.get(prop)
 
 # -----------------------------------------------------------------------------------------------------------------------
diff --git a/tests/toranj/test-002-form.py b/tests/toranj/test-002-form.py
index f74b809..969d9ae 100644
--- a/tests/toranj/test-002-form.py
+++ b/tests/toranj/test-002-form.py
@@ -74,7 +74,6 @@
 verify(node.get(wpan.WPAN_PANID) != DEFAULT_PANID)
 verify(node.get(wpan.WPAN_XPANID) != DEFAULT_XPANID)
 
-
 node.leave()
 verify(node.get(wpan.WPAN_STATE) == wpan.STATE_OFFLINE)
 
diff --git a/tests/toranj/test-004-scan.py b/tests/toranj/test-004-scan.py
index ff4603e..a28c8e9 100644
--- a/tests/toranj/test-004-scan.py
+++ b/tests/toranj/test-004-scan.py
@@ -30,7 +30,7 @@
 import wpan
 
 # -----------------------------------------------------------------------------------------------------------------------
-# Test desciption: Active scan and permit-join
+# Test description: Active scan and permit-join
 
 test_name = __file__[:-3] if __file__.endswith('.py') else __file__
 print('-' * 120)
diff --git a/tests/toranj/test-005-discover-scan.py b/tests/toranj/test-005-discover-scan.py
index e7074e6..2bdfbce 100644
--- a/tests/toranj/test-005-discover-scan.py
+++ b/tests/toranj/test-005-discover-scan.py
@@ -39,11 +39,14 @@
 # -----------------------------------------------------------------------------------------------------------------------
 # Creating `wpan.Nodes` instances
 
-NUM_NODES = 5
+speedup = 2
+wpan.Node.set_time_speedup_factor(speedup)
 
-nodes = []
-for i in range(NUM_NODES):
-    nodes.append(wpan.Node())
+node1 = wpan.Node()
+node2 = wpan.Node()
+node3 = wpan.Node()
+node4 = wpan.Node()
+node5 = wpan.Node()
 
 scanner = wpan.Node()
 
@@ -55,8 +58,11 @@
 # -----------------------------------------------------------------------------------------------------------------------
 # Build network topology
 
-for node in nodes:
-    node.form(node.interface_name)
+node1.form("net1", channel='11', panid='0x0001')
+node2.form("net2", channel='12', panid='0x0002')
+node3.form("net3", channel='13', panid='0x0002')
+node4.form("net4", channel='13', panid='0x0004')
+node5.form("net5", channel='14', panid='0x0005')
 
 # -----------------------------------------------------------------------------------------------------------------------
 # Test implementation
@@ -65,17 +71,57 @@
 
 scan_result = wpan.parse_scan_result(scanner.discover_scan())
 
-for node in nodes:
+verify(len(scan_result) == 5)
+for node in [node1, node2, node3, node4, node5]:
     verify(node.is_in_scan_result(scan_result))
 
 # Scan from an already associated node.
 
-scan_result = wpan.parse_scan_result(nodes[0].discover_scan())
+scan_result = wpan.parse_scan_result(node1.discover_scan())
 
-for node in nodes[1:]:
+verify(len(scan_result) == 4)
+for node in [node2, node3, node4, node5]:
     verify(node.is_in_scan_result(scan_result))
 
-# TODO: add tests for the joiner only and filtering
+# Scan on specific subset of channels
+
+scan_result = wpan.parse_scan_result(scanner.discover_scan(channel="11-13"))
+
+verify(len(scan_result) == 4)
+for node in [node1, node2, node3, node4]:
+    verify(node.is_in_scan_result(scan_result))
+
+# Filter on specific PAN ID.
+
+scan_result = wpan.parse_scan_result(
+    scanner.discover_scan(panid_filter="0x0002"))
+
+verify(len(scan_result) == 2)
+for node in [node2, node3]:
+    verify(node.is_in_scan_result(scan_result))
+
+# Scan joinable only.
+
+scanner_hw_addr = scanner.get(wpan.WPAN_HW_ADDRESS)[1:-1]  # Remove the `[]`
+
+node1.commissioner_start()
+node1.commissioner_add_joiner(scanner_hw_addr, '123456')
+node2.commissioner_start()
+node2.commissioner_add_joiner('1122334455667788', '123456')
+
+scan_result = wpan.parse_scan_result(scanner.discover_scan(joiner_only=True))
+
+verify(len(scan_result) == 2)
+for node in [node1, node2]:
+    verify(node.is_in_scan_result(scan_result))
+
+# Scan with filter enabled
+
+scan_result = wpan.parse_scan_result(
+    scanner.discover_scan(enable_filtering=True))
+
+verify(len(scan_result) == 1)
+verify(node1.is_in_scan_result(scan_result))
 
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
diff --git a/tests/toranj/test-006-traffic-router-end-device.py b/tests/toranj/test-006-traffic-router-end-device.py
index 314e6a5..99e5bf2 100644
--- a/tests/toranj/test-006-traffic-router-end-device.py
+++ b/tests/toranj/test-006-traffic-router-end-device.py
@@ -92,9 +92,8 @@
 
     s1 = node1.prepare_tx((src, PORT), (dst, PORT), 'Hi there!', NUM_MSGS)
     r1 = node2.prepare_rx(s1)
-    s2 = node2.prepare_tx(
-        (dst, PORT), (src, PORT), 'Hello back to you!', NUM_MSGS
-    )
+    s2 = node2.prepare_tx((dst, PORT), (src, PORT), 'Hello back to you!',
+                          NUM_MSGS)
     r2 = node1.prepare_rx(s2)
 
     wpan.Node.perform_async_tx_rx()
diff --git a/tests/toranj/test-007-traffic-router-sleepy.py b/tests/toranj/test-007-traffic-router-sleepy.py
index 241e291..a8e5253 100644
--- a/tests/toranj/test-007-traffic-router-sleepy.py
+++ b/tests/toranj/test-007-traffic-router-sleepy.py
@@ -97,9 +97,8 @@
 
         s1 = node1.prepare_tx((src, PORT), (dst, PORT), 'Hi there!', NUM_MSGS)
         r1 = node2.prepare_rx(s1)
-        s2 = node2.prepare_tx(
-            (dst, PORT), (src, PORT), 'Hello back to you!', NUM_MSGS
-        )
+        s2 = node2.prepare_tx((dst, PORT), (src, PORT), 'Hello back to you!',
+                              NUM_MSGS)
         r2 = node1.prepare_rx(s2)
 
         wpan.Node.perform_async_tx_rx()
diff --git a/tests/toranj/test-009-insecure-traffic-join.py b/tests/toranj/test-009-insecure-traffic-join.py
index d8268c4..f024806 100644
--- a/tests/toranj/test-009-insecure-traffic-join.py
+++ b/tests/toranj/test-009-insecure-traffic-join.py
@@ -90,9 +90,8 @@
 
 # Send insecure reply from node1 to node2
 
-sender2 = node1.prepare_tx(
-    (ll1, insecure_port), (ll2, rx_port), "Hi back! (insecure)", NUM_MSGS
-)
+sender2 = node1.prepare_tx((ll1, insecure_port), (ll2, rx_port),
+                           "Hi back! (insecure)", NUM_MSGS)
 recver2 = node2.prepare_rx(sender2)
 wpan.Node.perform_async_tx_rx()
 verify(sender2.was_successful)
@@ -106,9 +105,8 @@
 
 node1.permit_join('0')
 
-sender = node2.prepare_tx(
-    ll2, (ll1, insecure_port), "Hi (now secure)", NUM_MSGS
-)
+sender = node2.prepare_tx(ll2, (ll1, insecure_port), "Hi (now secure)",
+                          NUM_MSGS)
 recver = node1.prepare_rx(sender)
 wpan.Node.perform_async_tx_rx()
 verify(sender.was_successful)
@@ -116,9 +114,8 @@
 
 node2.permit_join('0')
 
-sender2 = node1.prepare_tx(
-    (ll1, insecure_port), (ll2, rx_port), "Hi back! (secure now)", NUM_MSGS
-)
+sender2 = node1.prepare_tx((ll1, insecure_port), (ll2, rx_port),
+                           "Hi back! (secure now)", NUM_MSGS)
 recver2 = node2.prepare_rx(sender2)
 wpan.Node.perform_async_tx_rx()
 verify(sender2.was_successful)
diff --git a/tests/toranj/test-010-on-mesh-prefix-config-gateway.py b/tests/toranj/test-010-on-mesh-prefix-config-gateway.py
index c096b1a..c111323 100644
--- a/tests/toranj/test-010-on-mesh-prefix-config-gateway.py
+++ b/tests/toranj/test-010-on-mesh-prefix-config-gateway.py
@@ -75,8 +75,7 @@
     """
     for node in node_list:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
             if p.prefix == prefix:
                 verify(int(p.prefix_len) == prefix_len)
@@ -90,9 +89,8 @@
                 verify(p.priority == priority)
                 break
         else:
-            raise wpan.VerifyError(
-                'Did not find prefix {} on node {}'.format(prefix, node)
-            )
+            raise wpan.VerifyError('Did not find prefix {} on node {}'.format(
+                prefix, node))
 
 
 # -----------------------------------------------------------------------------------------------------------------------
diff --git a/tests/toranj/test-011-child-table.py b/tests/toranj/test-011-child-table.py
index 27e8d24..813f074 100644
--- a/tests/toranj/test-011-child-table.py
+++ b/tests/toranj/test-011-child-table.py
@@ -72,8 +72,7 @@
 # Get the child table and verify all children are in the table.
 
 child_table = wpan.parse_child_table_result(
-    router.get(wpan.WPAN_THREAD_CHILD_TABLE)
-)
+    router.get(wpan.WPAN_THREAD_CHILD_TABLE))
 
 verify(len(child_table) == len(children))
 
@@ -83,21 +82,15 @@
         if entry.ext_address == ext_addr:
             break
     else:
-        print(
-            'Failed to find a child entry for extended address {} in table'.format(
-                ext_addr
-            )
-        )
+        print('Failed to find a child entry for extended address {} in table'.
+              format(ext_addr))
         exit(1)
 
-    verify(
-        int(entry.rloc16, 16) == int(child.get(wpan.WPAN_THREAD_RLOC16), 16)
-    )
+    verify(int(entry.rloc16, 16) == int(child.get(wpan.WPAN_THREAD_RLOC16), 16))
     verify(int(entry.timeout, 0) == 120)
     verify(entry.is_rx_on_when_idle() is False)
     verify(entry.is_ftd() is False)
 
-
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
 
diff --git a/tests/toranj/test-012-multi-hop-traffic.py b/tests/toranj/test-012-multi-hop-traffic.py
index 9d8b0ba..74a8799 100644
--- a/tests/toranj/test-012-multi-hop-traffic.py
+++ b/tests/toranj/test-012-multi-hop-traffic.py
@@ -50,7 +50,6 @@
 # - Verifies Mesh Header frame forwarding over multiple routers.
 # - Verifies forwarding of large IPv6 messages (1000 bytes) requiring lowpan fragmentation.
 
-
 test_name = __file__[:-3] if __file__.endswith('.py') else __file__
 print('-' * 120)
 print('Starting \'{}\''.format(test_name))
@@ -115,15 +114,13 @@
 
 for index in range(1, NUM_ROUTERS):
     routers[index].join_node(routers[index - 1], wpan.JOIN_TYPE_ROUTER)
-    sed_children[index].join_node(
-        routers[index], wpan.JOIN_TYPE_SLEEPY_END_DEVICE
-    )
+    sed_children[index].join_node(routers[index],
+                                  wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
     sed_children[index].set(wpan.WPAN_POLL_INTERVAL, '500')
 
 fed_children[0].join_node(routers[0], wpan.JOIN_TYPE_END_DEVICE)
 fed_children[-1].join_node(routers[-1], wpan.JOIN_TYPE_END_DEVICE)
 
-
 # -----------------------------------------------------------------------------------------------------------------------
 # Test implementation
 
@@ -140,12 +137,12 @@
 
 
 def check_r1_router_table():
-    router_table = wpan.parse_router_table_result(
-        routers[0].get(wpan.WPAN_THREAD_ROUTER_TABLE)
-    )
+    router_table = wpan.parse_router_table_result(routers[0].get(
+        wpan.WPAN_THREAD_ROUTER_TABLE))
     verify(len(router_table) == NUM_ROUTERS)
     for entry in router_table:
-        verify(entry.rloc16 == r1_rloc or entry.is_link_established or entry.next_hop != INVALID_ROUTER_ID)
+        verify(entry.rloc16 == r1_rloc or entry.is_link_established() or
+               entry.next_hop != INVALID_ROUTER_ID)
 
 
 wpan.verify_within(check_r1_router_table, ROUTER_TABLE_WAIT_TIME)
diff --git a/tests/toranj/test-013-off-mesh-route-traffic.py b/tests/toranj/test-013-off-mesh-route-traffic.py
index 3009c20..164da52 100644
--- a/tests/toranj/test-013-off-mesh-route-traffic.py
+++ b/tests/toranj/test-013-off-mesh-route-traffic.py
@@ -87,7 +87,6 @@
 #   |       |
 #  fed1    sed2
 
-
 r1.whitelist_node(r2)
 r2.whitelist_node(r1)
 
@@ -108,6 +107,9 @@
 # -----------------------------------------------------------------------------------------------------------------------
 # Test implementation
 
+WAIT_TIME = 10
+NUM_ROUTES = 3
+NUM_ROUTES_LOCAL = 1
 ON_MESH_PREFIX = "fd00:1234::"
 OFF_MESH_ROUTE_1 = "fd00:abba::"
 OFF_MESH_ROUTE_2 = "fd00:cafe::"
@@ -133,7 +135,27 @@
 fed1.add_route(OFF_MESH_ROUTE_3)
 fed1.add_ip6_address_on_interface(OFF_MESH_ADDR_3)
 
-time.sleep(0.5)
+# Wait till network data is updated on r1, r2, and sed2 and they all see all
+# the added off-mesh routes.
+
+
+def check_off_mesh_routes():
+    # If a node itself adds a route, the route entry will be seen twice in
+    # its WPAN_THREAD_OFF_MESH_ROUTES list (one time as part of network-wide
+    # network data and again as part of the local network data). Note that
+    # `r1 and `r2` each add a route, while `sed2` does not.
+    verify(
+        len(wpan.parse_list(r1.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
+        NUM_ROUTES + NUM_ROUTES_LOCAL)
+    verify(
+        len(wpan.parse_list(r2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
+        NUM_ROUTES + NUM_ROUTES_LOCAL)
+    verify(
+        len(wpan.parse_list(sed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
+        NUM_ROUTES)
+
+
+wpan.verify_within(check_off_mesh_routes, WAIT_TIME)
 
 # Traffic from `sed2` to `OFF_MESH_ADDR_1` (verify that it is received on
 # `r1`).
diff --git a/tests/toranj/test-014-ip6-address-add.py b/tests/toranj/test-014-ip6-address-add.py
index c9822d0..6602b3b 100644
--- a/tests/toranj/test-014-ip6-address-add.py
+++ b/tests/toranj/test-014-ip6-address-add.py
@@ -82,7 +82,6 @@
 #   |       |
 #  fed1    sed2
 
-
 r1.whitelist_node(r2)
 r2.whitelist_node(r1)
 
@@ -132,8 +131,7 @@
     for prefix in [IP6_PREFIX_1, IP6_PREFIX_2, IP6_PREFIX_3]:
         for node in all_nodes:
             prefixes = wpan.parse_on_mesh_prefix_result(
-                node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-            )
+                node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
             for p in prefixes:
                 if p.prefix == prefix:
                     verify(p.prefix_len == '64')
@@ -148,8 +146,7 @@
                     break
             else:  # `for` loop finished without finding the prefix.
                 raise wpan.VerifyError(
-                    'Did not find prefix {} on node {}'.format(prefix, node)
-                )
+                    'Did not find prefix {} on node {}'.format(prefix, node))
 
     # Verify that IPv6 address of `sed2` is present on `r2` (its parent)
     # "Thread:ChildTable:Addresses".
@@ -177,8 +174,7 @@
     # Verify that the related prefix is also removed on all nodes
     for node in all_nodes:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
             verify(p.prefix != IP6_PREFIX_1)
 
diff --git a/tests/toranj/test-015-same-prefix-on-multiple-nodes.py b/tests/toranj/test-015-same-prefix-on-multiple-nodes.py
index fcb07a4..1d9bdfb 100644
--- a/tests/toranj/test-015-same-prefix-on-multiple-nodes.py
+++ b/tests/toranj/test-015-same-prefix-on-multiple-nodes.py
@@ -93,27 +93,18 @@
 def check_prefix():
     for node in [r1, r2]:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
             if p.prefix == IP6_PREFIX:
-                if (
-                    p.origin == 'ncp'
-                    and p.prefix_len == '64'
-                    and p.is_stable()
-                    and p.is_on_mesh()
-                    and p.is_preferred()
-                    and not p.is_def_route()
-                    and not p.is_slaac()
-                    and not p.is_dhcp()
-                    and not p.is_config()
-                    and p.priority == "med"
-                ):
+                if (p.origin == 'ncp' and p.prefix_len == '64' and
+                        p.is_stable() and p.is_on_mesh() and
+                        p.is_preferred() and not p.is_def_route() and
+                        not p.is_slaac() and not p.is_dhcp() and
+                        not p.is_config() and p.priority == "med"):
                     break
         else:  # `for` loop finished without finding the prefix.
-            raise wpan.VerifyError(
-                'Did not find prefix {} on node {}'.format(IP6_PREFIX, r1)
-            )
+            raise wpan.VerifyError('Did not find prefix {} on node {}'.format(
+                IP6_PREFIX, r1))
 
 
 wpan.verify_within(check_prefix, 5)
@@ -141,8 +132,7 @@
 def check_empty_prefix_list():
     for node in [r1, r2]:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         verify(len(prefixes) == 0)
 
 
diff --git a/tests/toranj/test-016-neighbor-table.py b/tests/toranj/test-016-neighbor-table.py
index c8bac84..9086f9f 100644
--- a/tests/toranj/test-016-neighbor-table.py
+++ b/tests/toranj/test-016-neighbor-table.py
@@ -85,7 +85,7 @@
     children[num].whitelist_node(routers[0])
     routers[0].whitelist_node(children[num])
 
-# whiltelist the end-device ed with its corresponding router
+# whitelist the end-device ed with its corresponding router
 for num in range(1, NUM_ROUTERS):
     ed[num].whitelist_node(routers[num])
     routers[num].whitelist_node(ed[num])
@@ -109,9 +109,8 @@
     verify(router.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER)
 
 # Get and parse the neighbor table on routers[0].
-neighbor_table = wpan.parse_neighbor_table_result(
-    routers[0].get(wpan.WPAN_THREAD_NEIGHBOR_TABLE)
-)
+neighbor_table = wpan.parse_neighbor_table_result(routers[0].get(
+    wpan.WPAN_THREAD_NEIGHBOR_TABLE))
 
 verify(len(neighbor_table) == NUM_ROUTERS - 1 + NUM_CHILDREN)
 
@@ -123,14 +122,10 @@
             break
     else:
         raise wpan.VerifyError(
-            'Failed to find a child entry for extended address {} in table'.format(
-                ext_addr
-            )
-        )
+            'Failed to find a child entry for extended address {} in table'.
+            format(ext_addr))
 
-    verify(
-        int(entry.rloc16, 16) == int(child.get(wpan.WPAN_THREAD_RLOC16), 16)
-    )
+    verify(int(entry.rloc16, 16) == int(child.get(wpan.WPAN_THREAD_RLOC16), 16))
     verify(entry.is_rx_on_when_idle() is False)
     verify(entry.is_ftd() is False)
     verify(entry.is_child())
@@ -143,19 +138,15 @@
             break
     else:
         raise wpan.VerifyError(
-            'Failed to find a router entry for extended address {} in table'.format(
-                ext_addr
-            )
-        )
+            'Failed to find a router entry for extended address {} in table'.
+            format(ext_addr))
 
     verify(
-        int(entry.rloc16, 16) == int(router.get(wpan.WPAN_THREAD_RLOC16), 16)
-    )
+        int(entry.rloc16, 16) == int(router.get(wpan.WPAN_THREAD_RLOC16), 16))
     verify(entry.is_rx_on_when_idle())
     verify(entry.is_ftd())
     verify(entry.is_child() is False)
 
-
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
 
diff --git a/tests/toranj/test-017-parent-reset-child-recovery.py b/tests/toranj/test-017-parent-reset-child-recovery.py
index b7fec12..2b8ca01 100644
--- a/tests/toranj/test-017-parent-reset-child-recovery.py
+++ b/tests/toranj/test-017-parent-reset-child-recovery.py
@@ -157,10 +157,8 @@
 # Verify that number of state changes on all children stays as before
 # (indicating they did not get detached).
 for i in range(len(all_children)):
-    verify(
-        child_num_state_changes[i]
-        == len(wpan.parse_list(all_children[i].get("stat:ncp")))
-    )
+    verify(child_num_state_changes[i] == len(
+        wpan.parse_list(all_children[i].get("stat:ncp"))))
 
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
diff --git a/tests/toranj/test-018-child-supervision.py b/tests/toranj/test-018-child-supervision.py
index 5c02bb6..75219dc 100644
--- a/tests/toranj/test-018-child-supervision.py
+++ b/tests/toranj/test-018-child-supervision.py
@@ -95,8 +95,7 @@
 
 # Verify the child table on parent contains the child with correct timeout
 child_table = wpan.parse_child_table_result(
-    parent.get(wpan.WPAN_THREAD_CHILD_TABLE)
-)
+    parent.get(wpan.WPAN_THREAD_CHILD_TABLE))
 verify(len(child_table) == 1)
 verify(int(child_table[0].timeout, 0) == CHILD_TIMEOUT)
 
@@ -113,16 +112,14 @@
 
 def check_child_is_removed_from_parent_child_table():
     child_table = wpan.parse_child_table_result(
-        parent.get(wpan.WPAN_THREAD_CHILD_TABLE)
-    )
+        parent.get(wpan.WPAN_THREAD_CHILD_TABLE))
     verify(len(child_table) == 0)
 
 
 # wait till child is removed from parent's child table
 # after this child should still be associated
-wpan.verify_within(
-    check_child_is_removed_from_parent_child_table, CHILD_TIMEOUT / speedup + 2
-)
+wpan.verify_within(check_child_is_removed_from_parent_child_table,
+                   CHILD_TIMEOUT / speedup + 2)
 verify(child.is_associated())
 
 # Enable supervision check on child and expect the child to
@@ -138,17 +135,15 @@
     verify(not child.is_associated())
 
 
-wpan.verify_within(
-    check_child_is_detached, CHILD_SUPERVISION_CHECK_TIMEOUT / speedup + 8
-)
+wpan.verify_within(check_child_is_detached,
+                   CHILD_SUPERVISION_CHECK_TIMEOUT / speedup + 8)
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 # Enable child supervision on parent and disable white-listing
 
-parent.set(
-    wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL)
-)
+parent.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL,
+           str(PARENT_SUPERVISION_INTERVAL))
 parent.set(wpan.WPAN_MAC_WHITELIST_ENABLED, '0')
 
 # Wait for the child to attach back
@@ -171,9 +166,8 @@
 # used. Note that supervision interval on parent is set to 1 sec.
 
 verify(
-    int(parent.get("NCP:Counter:TX_PKT_UNICAST"), 0)
-    >= parent_unicast_tx_count + 1
-)
+    int(parent.get("NCP:Counter:TX_PKT_UNICAST"), 0) >=
+    parent_unicast_tx_count + 1)
 
 verify(child.is_associated())
 
diff --git a/tests/toranj/test-019-inform-previous-parent.py b/tests/toranj/test-019-inform-previous-parent.py
index d88451c..d82d995 100644
--- a/tests/toranj/test-019-inform-previous-parent.py
+++ b/tests/toranj/test-019-inform-previous-parent.py
@@ -119,9 +119,8 @@
     wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT,
     str(CHILD_SUPERVISION_CHECK_TIMEOUT),
 )
-parent1.set(
-    wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL)
-)
+parent1.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL,
+            str(PARENT_SUPERVISION_INTERVAL))
 
 # Since child supervision is not enabled on `parent2` and the `child` is
 # removed from whitelist on `parent2`, after the supervision check timeout
@@ -138,14 +137,12 @@
 
 def check_child_is_reattached():
     verify(
-        len(wpan.parse_list(child.get("stat:ncp"))) > child_num_state_changes
-    )
+        len(wpan.parse_list(child.get("stat:ncp"))) > child_num_state_changes)
     verify(child.is_associated())
 
 
-wpan.verify_within(
-    check_child_is_reattached, CHILD_SUPERVISION_CHECK_TIMEOUT / speedup + 5
-)
+wpan.verify_within(check_child_is_reattached,
+                   CHILD_SUPERVISION_CHECK_TIMEOUT / speedup + 5)
 
 # Verify that the `child` is now attached to `parent1`
 child_table = wpan.parse_list(parent1.get(wpan.WPAN_THREAD_CHILD_TABLE))
diff --git a/tests/toranj/test-020-router-table.py b/tests/toranj/test-020-router-table.py
index 0c9ac3c..41b98f5 100644
--- a/tests/toranj/test-020-router-table.py
+++ b/tests/toranj/test-020-router-table.py
@@ -123,8 +123,7 @@
 
 def check_r1_router_table():
     router_table = wpan.parse_router_table_result(
-        r1.get(wpan.WPAN_THREAD_ROUTER_TABLE)
-    )
+        r1.get(wpan.WPAN_THREAD_ROUTER_TABLE))
     verify(len(router_table) == 4)
     for entry in router_table:
         if entry.rloc16 == r1_rloc:
@@ -150,8 +149,7 @@
 
 def check_r3_router_table():
     router_table = wpan.parse_router_table_result(
-        r3.get(wpan.WPAN_THREAD_ROUTER_TABLE)
-    )
+        r3.get(wpan.WPAN_THREAD_ROUTER_TABLE))
     verify(len(router_table) == 4)
     for entry in router_table:
         if entry.rloc16 == r1_rloc:
@@ -177,8 +175,7 @@
 
 def check_r4_router_table():
     router_table = wpan.parse_router_table_result(
-        r4.get(wpan.WPAN_THREAD_ROUTER_TABLE)
-    )
+        r4.get(wpan.WPAN_THREAD_ROUTER_TABLE))
     verify(len(router_table) == 4)
     for entry in router_table:
         if entry.rloc16 == r1_rloc:
diff --git a/tests/toranj/test-021-address-cache-table.py b/tests/toranj/test-021-address-cache-table.py
index 84b611d..2a44284 100644
--- a/tests/toranj/test-021-address-cache-table.py
+++ b/tests/toranj/test-021-address-cache-table.py
@@ -125,8 +125,7 @@
 
 def check_r1_router_table():
     router_table = wpan.parse_router_table_result(
-        r1.get(wpan.WPAN_THREAD_ROUTER_TABLE)
-    )
+        r1.get(wpan.WPAN_THREAD_ROUTER_TABLE))
     verify(len(router_table) == 3)
     for entry in router_table:
         if entry.rloc16 == r3_rloc:
@@ -158,8 +157,7 @@
 # c2 and c3 addresses.
 
 addr_cache_table = wpan.parse_address_cache_table_result(
-    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE)
-)
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
 verify(len(addr_cache_table) == 2)
 
 for entry in addr_cache_table:
@@ -228,23 +226,79 @@
 wpan.Node.perform_async_tx_rx()
 verify(sender.was_successful and recver.was_successful)
 
-# The address cache table on r1 should still be the same as before.
+# The address cache table on r1 should have c2's address removed.
 
 addr_cache_table = wpan.parse_address_cache_table_result(
-    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE)
-)
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+verify(len(addr_cache_table) == 1)
+
+for entry in addr_cache_table:
+    if entry.address == c3_address:
+        # Entry for c3 should still point towards c3
+        verify(entry.rloc16 == c3_rloc)
+    else:
+        raise (wpan.VerifyError("Unknown entry in the address cache table"))
+
+# Send a UDP message from r1 to c2.
+
+sender = r1.prepare_tx(r1_address, c2_address, "Hi again c2")
+recver = c2.prepare_rx(sender)
+wpan.Node.perform_async_tx_rx()
+verify(sender.was_successful and recver.was_successful)
+
+# The address cache table on r1 should have both c1 and c2.
+
+addr_cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
 verify(len(addr_cache_table) == 2)
 
 for entry in addr_cache_table:
     if entry.address == c2_address:
-        # Entry for c2 should still point towards r2
-        verify(entry.rloc16 == r2_rloc)
+        # Entry for c2 should point towards r3
+        verify(entry.rloc16 == r3_rloc)
     elif entry.address == c3_address:
         # Entry for c3 should still point towards c3
         verify(entry.rloc16 == c3_rloc)
     else:
         raise (wpan.VerifyError("Unknown entry in the address cache table"))
 
+# Force c2 to switch its parent from r3 to r2
+
+c2.set(
+    wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT,
+    str(CHILD_SUPERVISION_CHECK_TIMEOUT),
+)
+r2.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL))
+
+r3.un_whitelist_node(c2)
+r2.whitelist_node(c2)
+c2.whitelist_node(r2)
+
+# Wait for c2 to detach from r3 and attach to r2.
+#
+# Upon re-attach, previous parent r3 is notified and should remove c2 from
+# its child table.
+
+
+def check_c2_is_removed_from_r3_child_table():
+    child_table = wpan.parse_list(r3.get(wpan.WPAN_THREAD_CHILD_TABLE))
+    verify(len(child_table) == 1)
+
+
+wpan.verify_within(check_c2_is_removed_from_r3_child_table, REATTACH_WAIT_TIME)
+
+# Verify that both c2 is a child of r2
+
+child_table = wpan.parse_list(r2.get(wpan.WPAN_THREAD_CHILD_TABLE))
+verify(len(child_table) == 1)
+
+# New network topology
+#
+#     r1 ---- r2 ---- r3
+#     |       |       |
+#     |       |       |
+#     c1      c2(s)   c3
+
 # Send a UDP message from c2 to c1.
 # This message will be forwarded by r1 to its FED child c1.
 
@@ -253,14 +307,82 @@
 wpan.Node.perform_async_tx_rx()
 verify(sender.was_successful and recver.was_successful)
 
-# r1 upon receiving and forwarding the message from c2 (through r3 now) should
+# r1 upon receiving and forwarding the message from c2 (through r2 now) should
 # update its address cache table for c2 (address cache update through snooping).
 #
 # verify that the address cache table is updated correctly.
 
 addr_cache_table = wpan.parse_address_cache_table_result(
-    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE)
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+verify(len(addr_cache_table) == 2)
+
+for entry in addr_cache_table:
+    if entry.address == c2_address:
+        # Entry for c2's address should now point to r2
+        verify(entry.rloc16 == r2_rloc)
+    elif entry.address == c3_address:
+        # Entry for c3's address should still point to c3
+        verify(entry.rloc16 == c3_rloc)
+    else:
+        raise (wpan.VerifyError("Unknown entry in the address cache table"))
+
+# Force c2 to switch its parent from r2 to r3
+
+CHILD_SUPERVISION_CHECK_TIMEOUT = 2
+PARENT_SUPERVISION_INTERVAL = 1
+
+REATTACH_WAIT_TIME = CHILD_SUPERVISION_CHECK_TIMEOUT / speedup + 6
+
+c2.set(
+    wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT,
+    str(CHILD_SUPERVISION_CHECK_TIMEOUT),
 )
+r3.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL))
+
+r2.un_whitelist_node(c2)
+r3.whitelist_node(c2)
+c2.whitelist_node(r3)
+
+# Wait for c2 to detach from r2 and attach to r3.
+#
+# Upon re-attach, previous parent r2 is notified and should remove c2 from
+# its child table.
+
+
+def check_c2_is_removed_from_r2_child_table():
+    child_table = wpan.parse_list(r2.get(wpan.WPAN_THREAD_CHILD_TABLE))
+    verify(len(child_table) == 0)
+
+
+wpan.verify_within(check_c2_is_removed_from_r2_child_table, REATTACH_WAIT_TIME)
+
+# Verify that both c2, c3 are children of r3
+
+child_table = wpan.parse_list(r3.get(wpan.WPAN_THREAD_CHILD_TABLE))
+verify(len(child_table) == 2)
+
+# New network topology
+#
+#     r1 ---- r2 ---- r3
+#     |               /\
+#     |              /  \
+#     c1           c2(s) c3
+
+# Send a UDP message from c2 to c1.
+# This message will be forwarded by r1 to its FED child c1.
+
+sender = c2.prepare_tx(c2_address, c1_address, "Hi c1 child of r1")
+recver = c1.prepare_rx(sender)
+wpan.Node.perform_async_tx_rx()
+verify(sender.was_successful and recver.was_successful)
+
+# r1 upon receiving and forwarding the message from c2 (through r2 now) should
+# update its address cache table for c2 (address cache update through snooping).
+#
+# verify that the address cache table is updated correctly.
+
+addr_cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
 verify(len(addr_cache_table) == 2)
 
 for entry in addr_cache_table:
diff --git a/tests/toranj/test-022-multicast-ip6-address.py b/tests/toranj/test-022-multicast-ip6-address.py
index 3db89de..77becad 100644
--- a/tests/toranj/test-022-multicast-ip6-address.py
+++ b/tests/toranj/test-022-multicast-ip6-address.py
@@ -98,7 +98,6 @@
 ll_all_thread_nodes_addr = 'ff32:40:' + ml_prefix + '1'
 rl_all_thread_nodes_addr = 'ff33:40:' + ml_prefix + '1'
 
-
 # List of multicast addresses subscribed by all nodes
 mcast_addrs = [
     "ff02::1",  # All nodes link-local
diff --git a/tests/toranj/test-023-multicast-traffic.py b/tests/toranj/test-023-multicast-traffic.py
index 1467423..0580535 100644
--- a/tests/toranj/test-023-multicast-traffic.py
+++ b/tests/toranj/test-023-multicast-traffic.py
@@ -74,9 +74,10 @@
     Verify that the message is received on all nodes in `recving_nodes` list and that it is not received on all
     nodes in `non_recving_nodes` list.
     """
-    sender = src_node.prepare_tx(
-        src_addr, mcast_addr, msg_len, mcast_hops=mcast_hops
-    )
+    sender = src_node.prepare_tx(src_addr,
+                                 mcast_addr,
+                                 msg_len,
+                                 mcast_hops=mcast_hops)
     recvers = [node.prepare_rx(sender) for node in recving_nodes]
     listeners = [
         node.prepare_listener(sender.dst_port, timeout=0.5)
@@ -91,15 +92,10 @@
     for lsnr in listeners:
         # `all_rx_msg` contains a list of (msg_content, (src_addr, src_port)).
         verify(
-            len(lsnr.all_rx_msg) == 0
-            or all(
-                [
-                    msg[1][0] != sender.src_addr
-                    and msg[1][1] != sender.src_port
-                    for msg in lsnr.all_rx_msg
-                ]
-            )
-        )
+            len(lsnr.all_rx_msg) == 0 or all([
+                msg[1][0] != sender.src_addr and msg[1][1] != sender.src_port
+                for msg in lsnr.all_rx_msg
+            ]))
 
 
 # -----------------------------------------------------------------------------------------------------------------------
@@ -252,9 +248,10 @@
 )
 
 # r1 =>> mesh-local all-thread (four hops)
-send_mcast(
-    r1, ml1, ml_all_thread_nodes_addr, [r1, r2, fed, r3, r4, sed], mcast_hops=4
-)
+send_mcast(r1,
+           ml1,
+           ml_all_thread_nodes_addr, [r1, r2, fed, r3, r4, sed],
+           mcast_hops=4)
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # Subscribe to a specific multicast address on r2 and sed
diff --git a/tests/toranj/test-024-partition-merge.py b/tests/toranj/test-024-partition-merge.py
index 55899f0..ab2724b 100644
--- a/tests/toranj/test-024-partition-merge.py
+++ b/tests/toranj/test-024-partition-merge.py
@@ -49,7 +49,6 @@
 #   merge the info in combined.
 #
 
-
 test_name = __file__[:-3] if __file__.endswith('.py') else __file__
 print('-' * 120)
 print('Starting \'{}\''.format(test_name))
@@ -76,8 +75,7 @@
     """
     for node in node_list:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
             if p.prefix == prefix:
                 verify(int(p.prefix_len) == prefix_len)
@@ -91,9 +89,8 @@
                 verify(p.priority == priority)
                 break
         else:
-            raise wpan.VerifyError(
-                "Did not find prefix {} on node {}".format(prefix, node)
-            )
+            raise wpan.VerifyError("Did not find prefix {} on node {}".format(
+                prefix, node))
 
 
 # -----------------------------------------------------------------------------------------------------------------------
@@ -149,7 +146,7 @@
 r1.un_whitelist_node(r2)
 r2.un_whitelist_node(r1)
 
-# Add a prefix before r2 releaizes it can not longer talk
+# Add a prefix before r2 realizes it can not longer talk
 # to leader (r1).
 r2.add_prefix(prefix2)
 
@@ -170,11 +167,11 @@
 r2.whitelist_node(r1)
 
 
-def check_paritition_id_macth():
+def check_partition_id_match():
     verify(r1.get(wpan.WPAN_PARTITION_ID) == r2.get(wpan.WPAN_PARTITION_ID))
 
 
-wpan.verify_within(check_paritition_id_macth, long_wait)
+wpan.verify_within(check_partition_id_match, long_wait)
 
 # Check that partitions merged successfully
 
@@ -183,12 +180,9 @@
     r1_type = r1.get(wpan.WPAN_NODE_TYPE)
     r2_type = r2.get(wpan.WPAN_NODE_TYPE)
     verify(
-        (r1_type == wpan.NODE_TYPE_LEADER and r2_type == wpan.NODE_TYPE_ROUTER)
-        or (
-            r2_type == wpan.NODE_TYPE_LEADER
-            and r1_type == wpan.NODE_TYPE_ROUTER
-        )
-    )
+        (r1_type == wpan.NODE_TYPE_LEADER and
+         r2_type == wpan.NODE_TYPE_ROUTER) or
+        (r2_type == wpan.NODE_TYPE_LEADER and r1_type == wpan.NODE_TYPE_ROUTER))
 
 
 wpan.verify_within(check_r1_r2_roles, short_wait)
diff --git a/tests/toranj/test-025-network-data-timeout.py b/tests/toranj/test-025-network-data-timeout.py
index 2cab044..c255512 100644
--- a/tests/toranj/test-025-network-data-timeout.py
+++ b/tests/toranj/test-025-network-data-timeout.py
@@ -74,14 +74,10 @@
     """
     for node in node_list:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
-            if (
-                p.prefix == prefix
-                and p.origin == "ncp"
-                and int(p.rloc16(), 0) == rloc16
-            ):
+            if (p.prefix == prefix and p.origin == "ncp" and
+                    int(p.rloc16(), 0) == rloc16):
                 verify(int(p.prefix_len) == prefix_len)
                 verify(p.is_stable() == stable)
                 verify(p.is_on_mesh() == on_mesh)
@@ -93,9 +89,8 @@
                 verify(p.priority == priority)
                 break
         else:
-            raise wpan.VerifyError(
-                "Did not find prefix {} on node {}".format(prefix, node)
-            )
+            raise wpan.VerifyError("Did not find prefix {} on node {}".format(
+                prefix, node))
 
 
 def verify_no_prefix(node_list, prefix, rloc16):
@@ -105,19 +100,13 @@
     """
     for node in node_list:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
-            if (
-                p.prefix == prefix
-                and p.origin == "ncp"
-                and int(p.rloc16(), 0) == rloc16
-            ):
+            if (p.prefix == prefix and p.origin == "ncp" and
+                    int(p.rloc16(), 0) == rloc16):
                 raise wpan.VerifyError(
                     "Did find prefix {} with rloc {} on node {}".format(
-                        prefix, hex(rloc16), node
-                    )
-                )
+                        prefix, hex(rloc16), node))
 
 
 # -----------------------------------------------------------------------------------------------------------------------
@@ -246,9 +235,12 @@
 
 def check_prefixes_on_r1_after_r2_leave():
     # Verify that entries added by r1 are still present
-    verify_prefix(
-        [r1], prefix1, r1_rloc, on_mesh=True, preferred=True, stable=True
-    )
+    verify_prefix([r1],
+                  prefix1,
+                  r1_rloc,
+                  on_mesh=True,
+                  preferred=True,
+                  stable=True)
     verify_prefix(
         [r1],
         common_prefix,
diff --git a/tests/toranj/test-026-slaac-address-wpantund.py b/tests/toranj/test-026-slaac-address-wpantund.py
index ab435a7..c9b218e 100644
--- a/tests/toranj/test-026-slaac-address-wpantund.py
+++ b/tests/toranj/test-026-slaac-address-wpantund.py
@@ -80,26 +80,21 @@
     """
     for node in node_list:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
             if p.prefix == prefix:
-                if (
-                    int(p.prefix_len) == prefix_len
-                    and p.is_stable() == stable
-                    and p.is_on_mesh() == on_mesh
-                    and p.is_def_route() == default_route
-                    and p.is_slaac() == slaac
-                    and p.is_dhcp() == dhcp
-                    and p.is_config() == configure
-                    and p.is_preferred() == preferred
-                    and p.priority == priority
-                ):
+                if (int(p.prefix_len) == prefix_len and
+                        p.is_stable() == stable and
+                        p.is_on_mesh() == on_mesh and
+                        p.is_def_route() == default_route and
+                        p.is_slaac() == slaac and p.is_dhcp() == dhcp and
+                        p.is_config() == configure and
+                        p.is_preferred() == preferred and
+                        p.priority == priority):
                     break
         else:
-            raise wpan.VerifyError(
-                "Did not find prefix {} on node {}".format(prefix, node)
-            )
+            raise wpan.VerifyError("Did not find prefix {} on node {}".format(
+                prefix, node))
 
 
 def verify_no_prefix(node_list, prefix):
@@ -108,8 +103,7 @@
     """
     for node in node_list:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
             verify(not p.prefix == prefix)
 
diff --git a/tests/toranj/test-027-child-mode-change.py b/tests/toranj/test-027-child-mode-change.py
index 447e1f4..720463d 100644
--- a/tests/toranj/test-027-child-mode-change.py
+++ b/tests/toranj/test-027-child-mode-change.py
@@ -47,8 +47,7 @@
     table entry's mode value matches the children Thread mode.
     """
     child_table = wpan.parse_child_table_result(
-        parent.get(wpan.WPAN_THREAD_CHILD_TABLE)
-    )
+        parent.get(wpan.WPAN_THREAD_CHILD_TABLE))
     verify(len(child_table) == len(children))
     for child in children:
         ext_addr = child.get(wpan.WPAN_EXT_ADDRESS)[1:-1]
@@ -57,33 +56,22 @@
                 break
         else:
             raise wpan.VerifyError(
-                'Failed to find a child entry for extended address {} in table'.format(
-                    ext_addr
-                )
-            )
+                'Failed to find a child entry for extended address {} in table'.
+                format(ext_addr))
             exit(1)
 
         verify(
-            int(entry.rloc16, 16)
-            == int(child.get(wpan.WPAN_THREAD_RLOC16), 16)
-        )
+            int(entry.rloc16, 16) == int(child.get(wpan.WPAN_THREAD_RLOC16),
+                                         16))
         mode = int(child.get(wpan.WPAN_THREAD_DEVICE_MODE), 0)
-        verify(
-            entry.is_rx_on_when_idle()
-            == (mode & wpan.THREAD_MODE_FLAG_RX_ON_WHEN_IDLE != 0)
-        )
-        verify(
-            entry.is_ftd()
-            == (mode & wpan.THREAD_MODE_FLAG_FULL_THREAD_DEV != 0)
-        )
-        verify(
-            entry.is_full_net_data()
-            == (mode & wpan.THREAD_MODE_FLAG_FULL_NETWORK_DATA != 0)
-        )
-        verify(
-            entry.is_sec_data_req()
-            == (mode & wpan.THREAD_MODE_FLAG_SECURE_DATA_REQUEST != 0)
-        )
+        verify(entry.is_rx_on_when_idle() == (
+            mode & wpan.THREAD_MODE_FLAG_RX_ON_WHEN_IDLE != 0))
+        verify(entry.is_ftd() == (
+            mode & wpan.THREAD_MODE_FLAG_FULL_THREAD_DEV != 0))
+        verify(entry.is_full_net_data() == (
+            mode & wpan.THREAD_MODE_FLAG_FULL_NETWORK_DATA != 0))
+        verify(entry.is_sec_data_req() == (
+            mode & wpan.THREAD_MODE_FLAG_SECURE_DATA_REQUEST != 0))
 
 
 # -----------------------------------------------------------------------------------------------------------------------
@@ -121,16 +109,12 @@
 WAIT_INTERVAL = 6
 
 # Thread Mode for end-device and sleepy end-device
-DEVICE_MODE_SLEEPY_END_DEVICE = (
-    wpan.THREAD_MODE_FLAG_FULL_NETWORK_DATA
-    | wpan.THREAD_MODE_FLAG_SECURE_DATA_REQUEST
-)
-DEVICE_MODE_END_DEVICE = (
-    wpan.THREAD_MODE_FLAG_FULL_NETWORK_DATA
-    | wpan.THREAD_MODE_FLAG_FULL_THREAD_DEV
-    | wpan.THREAD_MODE_FLAG_SECURE_DATA_REQUEST
-    | wpan.THREAD_MODE_FLAG_RX_ON_WHEN_IDLE
-)
+DEVICE_MODE_SLEEPY_END_DEVICE = (wpan.THREAD_MODE_FLAG_FULL_NETWORK_DATA |
+                                 wpan.THREAD_MODE_FLAG_SECURE_DATA_REQUEST)
+DEVICE_MODE_END_DEVICE = (wpan.THREAD_MODE_FLAG_FULL_NETWORK_DATA |
+                          wpan.THREAD_MODE_FLAG_FULL_THREAD_DEV |
+                          wpan.THREAD_MODE_FLAG_SECURE_DATA_REQUEST |
+                          wpan.THREAD_MODE_FLAG_RX_ON_WHEN_IDLE)
 
 # Disable child supervision on all devices
 parent.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, '0')
@@ -139,12 +123,10 @@
 
 # Verify Thread Device Mode on both children
 verify(
-    int(child1.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_END_DEVICE
-)
+    int(child1.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_END_DEVICE)
 verify(
-    int(child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0)
-    == DEVICE_MODE_SLEEPY_END_DEVICE
-)
+    int(child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) ==
+    DEVICE_MODE_SLEEPY_END_DEVICE)
 
 
 def check_child_table():
@@ -171,14 +153,12 @@
 
 child1.set(wpan.WPAN_THREAD_DEVICE_MODE, str(DEVICE_MODE_SLEEPY_END_DEVICE))
 verify(
-    int(child1.get(wpan.WPAN_THREAD_DEVICE_MODE), 0)
-    == DEVICE_MODE_SLEEPY_END_DEVICE
-)
+    int(child1.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) ==
+    DEVICE_MODE_SLEEPY_END_DEVICE)
 
 child2.set(wpan.WPAN_THREAD_DEVICE_MODE, str(DEVICE_MODE_END_DEVICE))
 verify(
-    int(child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_END_DEVICE
-)
+    int(child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_END_DEVICE)
 
 # Verify that the child table on parent is also updated
 wpan.verify_within(check_child_table, WAIT_INTERVAL)
@@ -186,9 +166,8 @@
 
 def check_child2_received_msg():
     verify(
-        int(child2.get(wpan.WPAN_NCP_COUNTER_RX_IP_SEC_TOTAL), 0)
-        >= child2_rx_ip_counter + NUM_MSGS
-    )
+        int(child2.get(wpan.WPAN_NCP_COUNTER_RX_IP_SEC_TOTAL), 0) >=
+        child2_rx_ip_counter + NUM_MSGS)
 
 
 wpan.verify_within(check_child2_received_msg, WAIT_INTERVAL)
diff --git a/tests/toranj/test-028-router-leader-reset-recovery.py b/tests/toranj/test-028-router-leader-reset-recovery.py
index c07738e..a159a73 100644
--- a/tests/toranj/test-028-router-leader-reset-recovery.py
+++ b/tests/toranj/test-028-router-leader-reset-recovery.py
@@ -46,8 +46,7 @@
     This function verifies that the neighbor table of a given `node` contains the node in the `neighbors` list.
     """
     neighbor_table = wpan.parse_neighbor_table_result(
-        node.get(wpan.WPAN_THREAD_NEIGHBOR_TABLE)
-    )
+        node.get(wpan.WPAN_THREAD_NEIGHBOR_TABLE))
     for neighbor in neighbors:
         ext_addr = neighbor.get(wpan.WPAN_EXT_ADDRESS)[1:-1]
         for entry in neighbor_table:
@@ -55,10 +54,8 @@
                 break
         else:
             raise wpan.VerifyError(
-                'Failed to find a neighbor entry for extended address {} in table'.format(
-                    ext_addr
-                )
-            )
+                'Failed to find a neighbor entry for extended address {} in table'
+                .format(ext_addr))
 
 
 # -----------------------------------------------------------------------------------------------------------------------
@@ -123,7 +120,6 @@
 verify(r1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER)
 verify(r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER)
 
-
 # Now reset r1 and check that everything recover correctly.
 r1.reset()
 
diff --git a/tests/toranj/test-029-data-poll-interval.py b/tests/toranj/test-029-data-poll-interval.py
index b4213e3..b8b64a8 100644
--- a/tests/toranj/test-029-data-poll-interval.py
+++ b/tests/toranj/test-029-data-poll-interval.py
@@ -74,26 +74,20 @@
 
 for poll_interval in [100, 200, 500, 50]:  # in milliseconds
 
-    poll_count_before = int(
-        child.get(wpan.WPAN_NCP_COUNTER_TX_PKT_DATA_POLL), 0
-    )
+    poll_count_before = int(child.get(wpan.WPAN_NCP_COUNTER_TX_PKT_DATA_POLL),
+                            0)
 
     child.set(wpan.WPAN_POLL_INTERVAL, str(poll_interval))
     verify(int(child.get(wpan.WPAN_POLL_INTERVAL), 0) == poll_interval)
 
     time.sleep(WAIT_TIME)
-    poll_count_after = int(
-        child.get(wpan.WPAN_NCP_COUNTER_TX_PKT_DATA_POLL), 0
-    )
+    poll_count_after = int(child.get(wpan.WPAN_NCP_COUNTER_TX_PKT_DATA_POLL), 0)
     actual_polls = poll_count_after - poll_count_before
 
     expected_polls = WAIT_TIME * 1000 * speedup / poll_interval
 
-    print(
-        "poll interval {} ms, polls -> actual {}, expected {}".format(
-            poll_interval, actual_polls, expected_polls
-        )
-    )
+    print("poll interval {} ms, polls -> actual {}, expected {}".format(
+        poll_interval, actual_polls, expected_polls))
 
     verify(actual_polls >= int(expected_polls))
 
@@ -129,7 +123,6 @@
 child.set(wpan.WPAN_THREAD_CHILD_TIMEOUT, str(child_timeout / 1000))
 verify(int(child.get(wpan.WPAN_POLL_INTERVAL), 0) == default_poll_interval)
 
-
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
 
diff --git a/tests/toranj/test-030-slaac-address-ncp.py b/tests/toranj/test-030-slaac-address-ncp.py
index c6edda1..3b53208 100644
--- a/tests/toranj/test-030-slaac-address-ncp.py
+++ b/tests/toranj/test-030-slaac-address-ncp.py
@@ -88,26 +88,21 @@
     """
     for node in node_list:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
             if p.prefix == prefix:
-                if (
-                    int(p.prefix_len) == prefix_len
-                    and p.is_stable() == stable
-                    and p.is_on_mesh() == on_mesh
-                    and p.is_def_route() == default_route
-                    and p.is_slaac() == slaac
-                    and p.is_dhcp() == dhcp
-                    and p.is_config() == configure
-                    and p.is_preferred() == preferred
-                    and p.priority == priority
-                ):
+                if (int(p.prefix_len) == prefix_len and
+                        p.is_stable() == stable and
+                        p.is_on_mesh() == on_mesh and
+                        p.is_def_route() == default_route and
+                        p.is_slaac() == slaac and p.is_dhcp() == dhcp and
+                        p.is_config() == configure and
+                        p.is_preferred() == preferred and
+                        p.priority == priority):
                     break
         else:
-            raise wpan.VerifyError(
-                "Did not find prefix {} on node {}".format(prefix, node)
-            )
+            raise wpan.VerifyError("Did not find prefix {} on node {}".format(
+                prefix, node))
 
 
 def verify_no_prefix(node_list, prefix):
@@ -116,8 +111,7 @@
     """
     for node in node_list:
         prefixes = wpan.parse_on_mesh_prefix_result(
-            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)
-        )
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
         for p in prefixes:
             verify(not p.prefix == prefix)
 
@@ -191,10 +185,8 @@
 
 r1.reset()
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # Remove the prefix on r1 and verify that the address and prefix are
@@ -217,28 +209,22 @@
 # Add prefix on r2
 r2.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True)
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 # Add same prefix on r1 and verify prefix and addresses stay as before
 r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True)
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 # Remove on r1, addresses and prefixes should stay as before (r2 still has
 # the same prefix)
 r1.remove_prefix(PREFIX)
 time.sleep(0.5)
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 # Remove the prefix on r2 and verify that the address and prefix are now
 # removed on all nodes.
@@ -252,10 +238,8 @@
 r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=False)
 r2.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True)
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 # Now remove the prefix on r2 and verify that SLAAC address is removed
 r2.remove_prefix(PREFIX)
@@ -297,10 +281,8 @@
 
 r1.remove_ip6_address_on_interface(IP_ADDRESS)
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 # Re-add the address
 r1.add_ip6_address_on_interface(IP_ADDRESS)
@@ -329,10 +311,8 @@
 
 r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True)
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 for node in all_nodes:
     node.set(wpan.WPAN_OT_SLAAC_ENABLED, 'false')
@@ -342,10 +322,8 @@
 for node in all_nodes:
     node.set(wpan.WPAN_OT_SLAAC_ENABLED, 'true')
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 r1.remove_prefix(PREFIX)
 wpan.verify_within(check_prefix_and_slaac_address_are_removed, WAIT_INTERVAL)
@@ -364,10 +342,8 @@
 for node in all_nodes:
     node.set(wpan.WPAN_OT_SLAAC_ENABLED, 'true')
 wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
-verify(
-    [node.find_ip6_address_with_prefix(PREFIX) for node in all_nodes]
-    == slaac_addrs
-)
+verify([node.find_ip6_address_with_prefix(PREFIX)
+        for node in all_nodes] == slaac_addrs)
 
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
diff --git a/tests/toranj/test-031-meshcop-joiner-commissioner.py b/tests/toranj/test-031-meshcop-joiner-commissioner.py
index f06e560..eaee3fa 100644
--- a/tests/toranj/test-031-meshcop-joiner-commissioner.py
+++ b/tests/toranj/test-031-meshcop-joiner-commissioner.py
@@ -39,7 +39,6 @@
 print('-' * 120)
 print('Starting \'{}\''.format(test_name))
 
-
 # -----------------------------------------------------------------------------------------------------------------------
 # Creating `wpan.Nodes` instances
 
@@ -81,11 +80,11 @@
 j.joiner_attach()
 
 
-def joiner_is_asscoated():
+def joiner_is_associated():
     verify(j.is_associated())
 
 
-wpan.verify_within(joiner_is_asscoated, WAIT_TIME)
+wpan.verify_within(joiner_is_associated, WAIT_TIME)
 
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
diff --git a/tests/toranj/test-032-child-attach-with-multiple-ip-addresses.py b/tests/toranj/test-032-child-attach-with-multiple-ip-addresses.py
index 3992b98..c0e9ba6 100644
--- a/tests/toranj/test-032-child-attach-with-multiple-ip-addresses.py
+++ b/tests/toranj/test-032-child-attach-with-multiple-ip-addresses.py
@@ -121,9 +121,8 @@
 wpan.verify_within(check_addresses_on_child, WAIT_TIME)
 
 # Remove child from parent's white-list
-parent.remove(
-    wpan.WPAN_MAC_WHITELIST_ENTRIES, child.get(wpan.WPAN_EXT_ADDRESS)[1:-1]
-)
+parent.remove(wpan.WPAN_MAC_WHITELIST_ENTRIES,
+              child.get(wpan.WPAN_EXT_ADDRESS)[1:-1])
 
 # Enable supervision check on child, this ensures that child is detached soon.
 child.set(
@@ -163,7 +162,7 @@
 # child table.
 
 
-def check_child_addressses_on_parent():
+def check_child_addresses_on_parent():
     child_addrs = parent.get(wpan.WPAN_THREAD_CHILD_TABLE_ADDRESSES)
     verify(child_addrs.find(prefix1) > 0)
     verify(child_addrs.find(prefix2) > 0)
@@ -171,7 +170,7 @@
     verify(child_addrs.find(prefix4) > 0)
 
 
-wpan.verify_within(check_child_addressses_on_parent, WAIT_TIME)
+wpan.verify_within(check_child_addresses_on_parent, WAIT_TIME)
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # Check the child recovery after a parent reset using quick re-attach
@@ -195,7 +194,7 @@
 # Verify that we again see all the child addresses in the parent's child table.
 # Note that child should register its addresses using "Child Update
 # Request" exchange.
-wpan.verify_within(check_child_addressses_on_parent, WAIT_TIME)
+wpan.verify_within(check_child_addresses_on_parent, WAIT_TIME)
 
 # Verify that there was no state change on child.
 verify(child_num_state_changes == len(wpan.parse_list(child.get("stat:ncp"))))
diff --git a/tests/toranj/test-033-mesh-local-prefix-change.py b/tests/toranj/test-033-mesh-local-prefix-change.py
index cbf7f76..792ac6c 100644
--- a/tests/toranj/test-033-mesh-local-prefix-change.py
+++ b/tests/toranj/test-033-mesh-local-prefix-change.py
@@ -92,9 +92,8 @@
 
 verify(node2.is_associated())
 verify(
-    node2.get(wpan.WPAN_IP6_MESH_LOCAL_PREFIX)
-    == node1.get(wpan.WPAN_IP6_MESH_LOCAL_PREFIX)
-)
+    node2.get(wpan.WPAN_IP6_MESH_LOCAL_PREFIX) == node1.get(
+        wpan.WPAN_IP6_MESH_LOCAL_PREFIX))
 
 # Ensure that there are only two addresses on the node2 (link-local and mesh-local address) and that RLOC
 # address is correctly filtered (by wpantund).
diff --git a/tests/toranj/test-034-poor-link-parent-child-attach.py b/tests/toranj/test-034-poor-link-parent-child-attach.py
index 2bcf93c..784598c 100644
--- a/tests/toranj/test-034-poor-link-parent-child-attach.py
+++ b/tests/toranj/test-034-poor-link-parent-child-attach.py
@@ -31,7 +31,7 @@
 # -----------------------------------------------------------------------------------------------------------------------
 # Test description:
 #
-# This test covers a situation where a single parent exists in network with poor link quality ensuding the child
+# This test covers a situation where a single parent exists in network with poor link quality ensuring the child
 # can attach the parent.
 
 test_name = __file__[:-3] if __file__.endswith('.py') else __file__
diff --git a/tests/toranj/test-035-child-timeout-large-data-poll.py b/tests/toranj/test-035-child-timeout-large-data-poll.py
index 6753a94..02ec362 100644
--- a/tests/toranj/test-035-child-timeout-large-data-poll.py
+++ b/tests/toranj/test-035-child-timeout-large-data-poll.py
@@ -59,7 +59,7 @@
 
 parent.form("poll-timeout")
 
-TIMEOUT = 5   # Child timeout in seconds
+TIMEOUT = 5  # Child timeout in seconds
 
 child.set(wpan.WPAN_THREAD_CHILD_TIMEOUT, str(TIMEOUT))
 
diff --git a/tests/toranj/test-036-wpantund-host-route-management.py b/tests/toranj/test-036-wpantund-host-route-management.py
index 9049835..cd46876 100644
--- a/tests/toranj/test-036-wpantund-host-route-management.py
+++ b/tests/toranj/test-036-wpantund-host-route-management.py
@@ -43,7 +43,6 @@
 #        - filtering of self added routes is not enabled, and
 #        - it is added at lower preference level.
 
-
 test_name = __file__[:-3] if __file__.endswith('.py') else __file__
 print('-' * 120)
 print('Starting \'{}\''.format(test_name))
@@ -57,18 +56,19 @@
     This function verifies that node has the same interface routes as given by `route_list` which is an array of
     tuples of (route, prefix_len, metric).
     """
-    node_routes = wpan.parse_interface_routes_result(node.get(wpan.WPAN_IP6_INTERFACE_ROUTES))
+    node_routes = wpan.parse_interface_routes_result(
+        node.get(wpan.WPAN_IP6_INTERFACE_ROUTES))
 
     verify(len(route_list) == len(node_routes))
 
     for route in route_list:
         for node_route in node_routes:
-            if (node_route.route_prefix, node_route.prefix_len, node_route.metric) == route:
+            if (node_route.route_prefix, node_route.prefix_len,
+                    node_route.metric) == route:
                 break
         else:
-            raise wpan.VerifyError(
-                'Did not find route {} on node {}'.format(route, node)
-            )
+            raise wpan.VerifyError('Did not find route {} on node {}'.format(
+                route, node))
 
 
 # -----------------------------------------------------------------------------------------------------------------------
@@ -100,7 +100,6 @@
 #
 # 3 routers, c3 is added to ensure r3 is promoted to a router quickly!
 
-
 r1.form("route-test")
 
 r1.whitelist_node(r2)
@@ -163,8 +162,9 @@
 
 # We expect to see all 3 routes added on r1 host interface with same priority levels as r2.
 def check_routes_on_r1_1():
-    verify_interface_routes(r1,
-                            [(ROUTE1, LEN1, LOW_METRIC), (ROUTE2, LEN2, MEDIUM_METRIC), (ROUTE3, LEN3, HIGH_METRIC)])
+    verify_interface_routes(r1, [(ROUTE1, LEN1, LOW_METRIC),
+                                 (ROUTE2, LEN2, MEDIUM_METRIC),
+                                 (ROUTE3, LEN3, HIGH_METRIC)])
 
 
 wpan.verify_within(check_routes_on_r1_1, WAIT_TIME)
@@ -178,7 +178,8 @@
 
 # We expect the host interface routes on r1 to change accordingly
 def check_routes_on_r1_2():
-    route_list = [(ROUTE1, LEN1, MEDIUM_METRIC), (ROUTE2, LEN2, MEDIUM_METRIC), (ROUTE3, LEN3, HIGH_METRIC)]
+    route_list = [(ROUTE1, LEN1, MEDIUM_METRIC), (ROUTE2, LEN2, MEDIUM_METRIC),
+                  (ROUTE3, LEN3, HIGH_METRIC)]
     verify_interface_routes(r1, route_list)
 
 
@@ -195,7 +196,8 @@
 
 # We expect the host interface routes on r1 to again change accordingly:
 def check_routes_on_r1_3():
-    verify_interface_routes(r1, [(ROUTE1, LEN1, MEDIUM_METRIC), (ROUTE2, LEN2, LOW_METRIC)])
+    verify_interface_routes(r1, [(ROUTE1, LEN1, MEDIUM_METRIC),
+                                 (ROUTE2, LEN2, LOW_METRIC)])
 
 
 wpan.verify_within(check_routes_on_r1_3, WAIT_TIME)
@@ -213,14 +215,16 @@
 #      - it is added at lower preference level.
 
 r1.set(wpan.WPAN_DAEMON_OFF_MESH_ROUTE_FILTER_SELF_AUTO_ADDED, 'false')
-verify(r1.get(wpan.WPAN_DAEMON_OFF_MESH_ROUTE_FILTER_SELF_AUTO_ADDED) == 'false')
+verify(
+    r1.get(wpan.WPAN_DAEMON_OFF_MESH_ROUTE_FILTER_SELF_AUTO_ADDED) == 'false')
 
 # Add ROUTE1 on r1 with low-priority. Since it's also present on r3 with
 # medium priority, we should still see the route on host (as medium).
 
 r1.add_route(ROUTE1, prefix_len=LEN1, priority=LOW_PRIORITY)
 
-verify_interface_routes(r1, [(ROUTE1, LEN1, MEDIUM_METRIC), (ROUTE2, LEN2, LOW_METRIC)])
+verify_interface_routes(r1, [(ROUTE1, LEN1, MEDIUM_METRIC),
+                             (ROUTE2, LEN2, LOW_METRIC)])
 
 # Now change ROUTE1 on r1 to be same priority as on r2, now the route should
 # no longer be present on host interface routes.
@@ -244,7 +248,8 @@
 r1.remove_route(ROUTE1, prefix_len=LEN1)
 r1.remove_route(ROUTE2, prefix_len=LEN2)
 
-verify_interface_routes(r1, [(ROUTE1, LEN1, MEDIUM_METRIC), (ROUTE2, LEN2, LOW_METRIC)])
+verify_interface_routes(r1, [(ROUTE1, LEN1, MEDIUM_METRIC),
+                             (ROUTE2, LEN2, LOW_METRIC)])
 
 verify_interface_routes(r2, [])
 
@@ -261,7 +266,8 @@
 
 r1.remove_route(ROUTE1, prefix_len=LEN1)
 
-verify_interface_routes(r1, [(ROUTE1, LEN1, MEDIUM_METRIC), (ROUTE2, LEN2, LOW_METRIC)])
+verify_interface_routes(r1, [(ROUTE1, LEN1, MEDIUM_METRIC),
+                             (ROUTE2, LEN2, LOW_METRIC)])
 
 verify_interface_routes(r2, [])
 
diff --git a/tests/toranj/test-037-wpantund-auto-add-route-for-on-mesh-prefix.py b/tests/toranj/test-037-wpantund-auto-add-route-for-on-mesh-prefix.py
index 5cc259e..acb84f7 100644
--- a/tests/toranj/test-037-wpantund-auto-add-route-for-on-mesh-prefix.py
+++ b/tests/toranj/test-037-wpantund-auto-add-route-for-on-mesh-prefix.py
@@ -52,18 +52,19 @@
     This function verifies that node has the same interface routes as given by `route_list` which is an array of
     tuples of (route, prefix_len, metric).
     """
-    node_routes = wpan.parse_interface_routes_result(node.get(wpan.WPAN_IP6_INTERFACE_ROUTES))
+    node_routes = wpan.parse_interface_routes_result(
+        node.get(wpan.WPAN_IP6_INTERFACE_ROUTES))
 
     verify(len(route_list) == len(node_routes))
 
     for route in route_list:
         for node_route in node_routes:
-            if (node_route.route_prefix, node_route.prefix_len, node_route.metric) == route:
+            if (node_route.route_prefix, node_route.prefix_len,
+                    node_route.metric) == route:
                 break
         else:
-            raise wpan.VerifyError(
-                'Did not find route {} on node {}'.format(route, node)
-            )
+            raise wpan.VerifyError('Did not find route {} on node {}'.format(
+                route, node))
 
 
 # -----------------------------------------------------------------------------------------------------------------------
@@ -120,7 +121,9 @@
 WAIT_TIME = 10
 
 # Verify the default daemon configuration
-verify(r1.get(wpan.WPAN_DAEMON_ON_MESH_PREFIX_AUTO_ADD_AS_INTERFACE_ROUTE) == 'true')
+verify(
+    r1.get(wpan.WPAN_DAEMON_ON_MESH_PREFIX_AUTO_ADD_AS_INTERFACE_ROUTE) ==
+    'true')
 
 r1.set(wpan.WPAN_DAEMON_OFF_MESH_ROUTE_AUTO_ADD_ON_INTERFACE, 'false')
 verify(r1.get(wpan.WPAN_DAEMON_OFF_MESH_ROUTE_AUTO_ADD_ON_INTERFACE) == 'false')
@@ -134,7 +137,8 @@
 
 # We expect to only see routes associated the first two (which are on-mesh) on r1.
 def check_routes_on_r1_is_prefix1_and_prefix2():
-    verify_interface_routes(r1, [(PREFIX1, LEN1, MEDIUM_METRIC), (PREFIX2, LEN2, MEDIUM_METRIC)])
+    verify_interface_routes(r1, [(PREFIX1, LEN1, MEDIUM_METRIC),
+                                 (PREFIX2, LEN2, MEDIUM_METRIC)])
 
 
 wpan.verify_within(check_routes_on_r1_is_prefix1_and_prefix2, WAIT_TIME)
@@ -179,14 +183,14 @@
 r1.set(wpan.WPAN_DAEMON_OFF_MESH_ROUTE_AUTO_ADD_ON_INTERFACE, 'true')
 verify(r1.get(wpan.WPAN_DAEMON_OFF_MESH_ROUTE_AUTO_ADD_ON_INTERFACE) == 'true')
 
-
 r2.add_route(ROUTE5, prefix_len=LEN5, priority=MEDIUM_PRIORITY)
 r2.add_route(ROUTE4, prefix_len=LEN4, priority=MEDIUM_PRIORITY)
 r1.add_prefix(PREFIX3, prefix_len=LEN3, on_mesh=True, slaac=False)
 
 
 def check_routes_on_r1_is_prefix3_route4_and_route5():
-    route_list = [(PREFIX3, LEN3, MEDIUM_METRIC), (ROUTE4, LEN4, MEDIUM_METRIC), (ROUTE5, LEN5, MEDIUM_METRIC)]
+    route_list = [(PREFIX3, LEN3, MEDIUM_METRIC), (ROUTE4, LEN4, MEDIUM_METRIC),
+                  (ROUTE5, LEN5, MEDIUM_METRIC)]
     verify_interface_routes(r1, route_list)
 
 
@@ -206,7 +210,9 @@
 # Test behavior when feature is disabled
 
 r1.set(wpan.WPAN_DAEMON_ON_MESH_PREFIX_AUTO_ADD_AS_INTERFACE_ROUTE, 'false')
-verify(r1.get(wpan.WPAN_DAEMON_ON_MESH_PREFIX_AUTO_ADD_AS_INTERFACE_ROUTE) == 'false')
+verify(
+    r1.get(wpan.WPAN_DAEMON_ON_MESH_PREFIX_AUTO_ADD_AS_INTERFACE_ROUTE) ==
+    'false')
 
 r1.add_prefix(PREFIX3, prefix_len=LEN3, on_mesh=True, slaac=False)
 wpan.verify_within(check_routes_on_r1_is_only_route4, WAIT_TIME)
diff --git a/tests/toranj/test-038-clear-address-cache-for-sed.py b/tests/toranj/test-038-clear-address-cache-for-sed.py
index 706a4ed..76f613a 100644
--- a/tests/toranj/test-038-clear-address-cache-for-sed.py
+++ b/tests/toranj/test-038-clear-address-cache-for-sed.py
@@ -119,7 +119,6 @@
 wpan.Node.perform_async_tx_rx()
 verify(sender.was_successful and recver.was_successful)
 
-
 # Force c to switch its parent from r2 to r1
 #
 #   r3 ---- r1 ---- r2
@@ -132,7 +131,8 @@
 
 REATTACH_WAIT_TIME = CHILD_SUPERVISION_CHECK_TIMEOUT / speedup + 6
 
-c.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, str(CHILD_SUPERVISION_CHECK_TIMEOUT))
+c.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT,
+      str(CHILD_SUPERVISION_CHECK_TIMEOUT))
 r2.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL))
 r1.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL))
 r3.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL))
@@ -164,7 +164,6 @@
 wpan.Node.perform_async_tx_rx()
 verify(sender.was_successful and recver.was_successful)
 
-
 # Force c to switch its parent from r1 to r3
 #
 #   r3 ---- r1 ---- r2
@@ -186,7 +185,6 @@
 
 wpan.verify_within(check_c_is_removed_from_r1_child_table, REATTACH_WAIT_TIME)
 
-
 # check that c is now a child of r3 (r3 should have two child, c and c3)
 child_table = wpan.parse_list(r3.get(wpan.WPAN_THREAD_CHILD_TABLE))
 verify(len(child_table) == 2)
@@ -197,13 +195,11 @@
 # r1 will still have an entry pointing to r2, and r2 will have an entry
 # pointing to r1, thus creating a loop (the msg will not be delivered to r3)
 
-
 sender = r1.prepare_tx(r1_address, c_address, "Hi from r1 to c")
 recver = c.prepare_rx(sender)
 wpan.Node.perform_async_tx_rx()
 verify(sender.was_successful and recver.was_successful)
 
-
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
 
diff --git a/tests/toranj/test-039-address-cache-table-snoop.py b/tests/toranj/test-039-address-cache-table-snoop.py
new file mode 100644
index 0000000..846496f
--- /dev/null
+++ b/tests/toranj/test-039-address-cache-table-snoop.py
@@ -0,0 +1,421 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+
+import time
+import wpan
+from wpan import verify
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test description: Address Cache Table
+#
+# This test verifies the behavior of `AddressResolver` and how the cache
+# table is managed. In particular it verifies behavior query timeout and
+# query retry and snoop optimization.
+
+test_name = __file__[:-3] if __file__.endswith('.py') else __file__
+print('-' * 120)
+print('Starting \'{}\''.format(test_name))
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Creating `wpan.Nodes` instances
+
+speedup = 4
+wpan.Node.set_time_speedup_factor(speedup)
+
+r1 = wpan.Node()
+r2 = wpan.Node()
+r3 = wpan.Node()
+
+c2 = wpan.Node()
+c3 = wpan.Node()
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Init all nodes
+
+wpan.Node.init_all_nodes()
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Build network topology
+#
+#  r3 ---- r1 ---- r2
+#  |               |
+#  |               |
+#  c3              c2
+#
+
+PREFIX = "fd00:1234::"
+POLL_INTERVAL = 200
+
+MAX_SNOOPED_NON_EVICTABLE = 2
+INITIAL_RETRY_DELAY = 4
+MAX_CACHE_ENTRIES = 16
+
+r1.form("sekiro")  # shadows die twice!
+
+r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=False, preferred=True)
+
+r1.whitelist_node(r2)
+r2.whitelist_node(r1)
+r2.join_node(r1, wpan.JOIN_TYPE_ROUTER)
+
+c2.whitelist_node(r2)
+r2.whitelist_node(c2)
+c2.join_node(r2, wpan.JOIN_TYPE_END_DEVICE)
+
+r1.whitelist_node(r3)
+r3.whitelist_node(r1)
+r3.join_node(r1, wpan.JOIN_TYPE_ROUTER)
+
+c3.whitelist_node(r3)
+r3.whitelist_node(c3)
+c3.join_node(r3, wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
+c3.set(wpan.WPAN_POLL_INTERVAL, str(POLL_INTERVAL))
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test implementation
+#
+
+# Add IPv6 addresses on different nodes.
+
+r1_address = PREFIX + "1"
+r1.add_ip6_address_on_interface(r1_address)
+
+WAIT_TIME = 10
+PORT = 1234
+
+NUM_ADDRESSES = 4  # Number of addresses to add on r2, r3, c2, and c3
+
+for num in range(NUM_ADDRESSES):
+    r2.add_ip6_address_on_interface(PREFIX + "2:" + str(num))
+    r3.add_ip6_address_on_interface(PREFIX + "3:" + str(num))
+    c2.add_ip6_address_on_interface(PREFIX + "c2:" + str(num))
+    c3.add_ip6_address_on_interface(PREFIX + "c3:" + str(num))
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+# From r1 send msg to a group of addresses (not provided by any nodes in network).
+
+NUM_QUERY_ADDRS = 5
+MAX_STAGGER_INTERVAL = 2.5
+
+for num in range(NUM_QUERY_ADDRS):
+    sender = r1.prepare_tx((r1_address, PORT),
+                           (PREFIX + "800:" + str(num), PORT), "hi nobody!", 1)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+    # Wait before next tx to stagger the address queries
+    # request ensuring different timeouts
+    time.sleep(MAX_STAGGER_INTERVAL / (NUM_QUERY_ADDRS * speedup))
+
+r2_rloc = int(r2.get(wpan.WPAN_THREAD_RLOC16), 16)
+c2_rloc = int(c2.get(wpan.WPAN_THREAD_RLOC16), 16)
+r3_rloc = int(r3.get(wpan.WPAN_THREAD_RLOC16), 16)
+
+# Verify that we do see entries in cache table for all the addresses and all are in "query" state
+
+addr_cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+verify(len(addr_cache_table) == NUM_QUERY_ADDRS)
+for entry in addr_cache_table:
+    verify(entry.state == wpan.ADDRESS_CACHE_ENTRY_STATE_QUERY)
+    verify(not entry.can_evict())
+    verify(entry.timeout > 0)
+    verify(entry.retry_delay == INITIAL_RETRY_DELAY)
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+# Check the retry-query behavior
+
+# Wait till all the address queries time out and verify they enter "retry-query" state.
+
+
+def check_cache_entry_switch_to_retry_state():
+    cache_table = wpan.parse_address_cache_table_result(
+        r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+    for index in range(NUM_QUERY_ADDRS):
+        verify(cache_table[index].state ==
+               wpan.ADDRESS_CACHE_ENTRY_STATE_RETRY_QUERY)
+        verify(cache_table[index].retry_delay == 2 * INITIAL_RETRY_DELAY)
+
+
+wpan.verify_within(check_cache_entry_switch_to_retry_state, WAIT_TIME)
+
+# Try sending again to same addresses which are in "retry-delay" state.
+
+for num in range(NUM_QUERY_ADDRS):
+    sender = r1.prepare_tx((r1_address, PORT),
+                           (PREFIX + "800:" + str(num), PORT), "hi nobody!", 1)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+
+# Make sure the entries stayed in retry-delay as before.
+
+wpan.verify_within(check_cache_entry_switch_to_retry_state, WAIT_TIME)
+
+# Now wait for them to get to zero timeout.
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+
+def check_cache_entry_in_retry_state_to_get_to_zero_timeout():
+    cache_table = wpan.parse_address_cache_table_result(
+        r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+    for index in range(NUM_QUERY_ADDRS):
+        verify(cache_table[index].state ==
+               wpan.ADDRESS_CACHE_ENTRY_STATE_RETRY_QUERY)
+        verify(cache_table[index].timeout == 0)
+
+
+wpan.verify_within(check_cache_entry_in_retry_state_to_get_to_zero_timeout,
+                   WAIT_TIME)
+
+# Now try again using the same addresses.
+
+for num in range(NUM_QUERY_ADDRS):
+    sender = r1.prepare_tx((r1_address, PORT),
+                           (PREFIX + "800:" + str(num), PORT),
+                           "hi again nobody!", 1)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+
+# We expect now after the delay to see retries for same addresses.
+
+
+def check_cache_entry_switch_to_query_state():
+    cache_table = wpan.parse_address_cache_table_result(
+        r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+    for index in range(NUM_QUERY_ADDRS):
+        verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_QUERY)
+        verify(cache_table[index].can_evict() == True)
+
+
+wpan.verify_within(check_cache_entry_switch_to_query_state, WAIT_TIME)
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+# Verify snoop optimization.
+
+for num in range(NUM_ADDRESSES):
+    sender = r2.prepare_tx((PREFIX + "2:" + str(num), PORT), (r1_address, PORT),
+                           "hi r1 from r2 (snoop me)", 1)
+    recver = r1.prepare_rx(sender)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+    verify(recver.was_successful)
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+# We expect to see new "snooped" entries at the top of list.
+# Also verify that only MAX_SNOOPED_NON_EVICTABLE of snooped entries are non-evictable.
+
+verify(len(cache_table) >= NUM_ADDRESSES)
+
+for index in range(NUM_ADDRESSES):
+    verify(cache_table[index].address == PREFIX + "2:" +
+           str(NUM_ADDRESSES - index - 1))
+    verify(cache_table[index].rloc16 == r2_rloc)
+    verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_SNOOPED)
+    if index < NUM_ADDRESSES - MAX_SNOOPED_NON_EVICTABLE:
+        verify(cache_table[index].can_evict() == True)
+        verify(cache_table[index].timeout == 0)
+    else:
+        verify(cache_table[index].can_evict() == False)
+        verify(cache_table[index].timeout > 0)
+
+# From r1 send to r2 using the addresses from snooped entries:
+
+for num in range(NUM_ADDRESSES):
+    sender = r1.prepare_tx((r1_address, PORT), (PREFIX + "2:" + str(num), PORT),
+                           "hi back r2 from r1", 1)
+    recver = r2.prepare_rx(sender)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+    verify(recver.was_successful)
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+# We expect to see the entries to be in "cached" state now.
+
+verify(len(cache_table) >= NUM_ADDRESSES)
+
+for index in range(NUM_ADDRESSES):
+    verify(cache_table[index].address == PREFIX + "2:" +
+           str(NUM_ADDRESSES - index - 1))
+    verify(cache_table[index].rloc16 == r2_rloc)
+    verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_CACHED)
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+# Check query requests, last transaction time
+
+# Send from r1 to all addresses on r3.
+
+for num in range(NUM_ADDRESSES):
+    sender = r1.prepare_tx((r1_address, PORT), (PREFIX + "3:" + str(num), PORT),
+                           "hi r3 from r1", 1)
+    recver = r3.prepare_rx(sender)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+    verify(recver.was_successful)
+    cache_table = wpan.parse_address_cache_table_result(
+        r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+# We expect to see the cache entries for the addresses pointing to r3.
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+for index in range(NUM_ADDRESSES):
+    verify(cache_table[index].address == PREFIX + "3:" +
+           str(NUM_ADDRESSES - index - 1))
+    verify(cache_table[index].rloc16 == r3_rloc)
+    verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_CACHED)
+    verify(cache_table[index].last_trans == 0)
+
+# Send from r1 to all addresses on c3 (sleepy child of r3)
+
+for num in range(NUM_ADDRESSES):
+    sender = r1.prepare_tx((r1_address, PORT),
+                           (PREFIX + "c3:" + str(num), PORT), "hi c3 from r1",
+                           1)
+    recver = c3.prepare_rx(sender)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+    verify(recver.was_successful)
+
+# We expect to see the cache entries for c3 addresses pointing to r3.
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+for index in range(NUM_ADDRESSES):
+    verify(cache_table[index].address == PREFIX + "c3:" +
+           str(NUM_ADDRESSES - index - 1))
+    verify(cache_table[index].rloc16 == r3_rloc)
+    verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_CACHED)
+    verify(cache_table[index].last_trans > 0)
+
+# Send again to r2. This should cause the related cache entries to be moved to top of the list:
+
+for num in range(NUM_ADDRESSES):
+    sender = r1.prepare_tx((r1_address, PORT), (PREFIX + "2:" + str(num), PORT),
+                           "hi again r2 from r1", 1)
+    recver = r2.prepare_rx(sender)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+    verify(recver.was_successful)
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+for index in range(NUM_ADDRESSES):
+    verify(cache_table[index].address == PREFIX + "2:" +
+           str(NUM_ADDRESSES - index - 1))
+    verify(cache_table[index].rloc16 == r2_rloc)
+    verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_CACHED)
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+# Check behavior when cache table is full.
+
+verify(len(cache_table) == MAX_CACHE_ENTRIES)
+
+for num in range(NUM_QUERY_ADDRS):
+    sender = r1.prepare_tx((r1_address, PORT),
+                           (PREFIX + "900:" + str(num), PORT), "hi nobody!", 1)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+verify(len(cache_table) == MAX_CACHE_ENTRIES)
+
+# Send from c2 to r1 and verify that snoop optimization uses at most
+# `MAX_SNOOPED_NON_EVICTABLE` entries.
+
+for num in range(NUM_ADDRESSES):
+    sender = c2.prepare_tx((PREFIX + "c2:" + str(num), PORT),
+                           (r1_address, PORT), "hi r1 from c2 (snoop me)", 1)
+    recver = r1.prepare_rx(sender)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+    verify(recver.was_successful)
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+verify(len(cache_table) == MAX_CACHE_ENTRIES)
+
+snooped_entries = [
+    entry for entry in cache_table
+    if entry.state == wpan.ADDRESS_CACHE_ENTRY_STATE_SNOOPED
+]
+verify(len(snooped_entries) == MAX_SNOOPED_NON_EVICTABLE)
+
+for entry in snooped_entries:
+    verify(entry.rloc16 == c2_rloc)
+    verify(entry.state == wpan.ADDRESS_CACHE_ENTRY_STATE_SNOOPED)
+    verify(entry.can_evict() == False)
+    verify(entry.timeout > 0)
+
+# Now send from r1 to c2, some of the snooped entries would be used,
+# others would  go through full address query.
+
+for num in range(NUM_ADDRESSES):
+    sender = r1.prepare_tx((r1_address, PORT),
+                           (PREFIX + "c2:" + str(num), PORT), "hi c2 from r1",
+                           1)
+    recver = c2.prepare_rx(sender)
+    wpan.Node.perform_async_tx_rx()
+    verify(sender.was_successful)
+    verify(recver.was_successful)
+
+cache_table = wpan.parse_address_cache_table_result(
+    r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE))
+
+verify(len(cache_table) == MAX_CACHE_ENTRIES)
+
+# Verify that c2 entries are now at the top of cache list.
+
+for index in range(NUM_ADDRESSES):
+    verify(cache_table[index].address == PREFIX + "c2:" +
+           str(NUM_ADDRESSES - index - 1))
+    verify(cache_table[index].rloc16 == c2_rloc)
+    verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_CACHED)
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test finished
+
+wpan.Node.finalize_all_nodes()
+
+print('\'{}\' passed.'.format(test_name))
diff --git a/tests/toranj/test-040-network-data-stable-full.py b/tests/toranj/test-040-network-data-stable-full.py
new file mode 100644
index 0000000..04605f7
--- /dev/null
+++ b/tests/toranj/test-040-network-data-stable-full.py
@@ -0,0 +1,328 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+
+import wpan
+from wpan import verify
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test description: Network Data update and version changes (stable only vs. full version).
+#
+# Network topology
+#
+#      leader
+#      /  |  \
+#     /   |   \
+#    /    |    \
+#   c1    c2    c3
+#
+#
+# c3 is sleepy-end node and also configured to request stable Network Data only
+#
+# Test covers the following steps:
+# - Adding/removing prefixes (stable or temporary) on c1
+# - Verifying that Network Data is updated on all nodes
+# - Ensuring correct update to version and stable version
+
+# The above steps are repeated over many different situations:
+# - Where the same prefixes are also added by other nodes
+# - Or the same prefixes are added as off-mesh routes by other nodes
+#
+
+test_name = __file__[:-3] if __file__.endswith('.py') else __file__
+print('-' * 120)
+print('Starting \'{}\''.format(test_name))
+
+
+def verify_prefix(
+    node_list,
+    prefix,
+    rloc16,
+    prefix_len=64,
+    stable=True,
+    priority='med',
+    on_mesh=False,
+    slaac=False,
+    dhcp=False,
+    configure=False,
+    default_route=False,
+    preferred=False,
+):
+    """
+    This function verifies that the `prefix` is present on all the nodes in the `node_list`. It also verifies that the
+    `prefix` is associated with the given `rloc16` (as an integer).
+    """
+    for node in node_list:
+        prefixes = wpan.parse_on_mesh_prefix_result(
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
+        for p in prefixes:
+            if (p.prefix == prefix and p.origin == "ncp" and
+                    int(p.rloc16(), 0) == rloc16):
+                verify(int(p.prefix_len) == prefix_len)
+                verify(p.is_stable() == stable)
+                verify(p.is_on_mesh() == on_mesh)
+                verify(p.is_def_route() == default_route)
+                verify(p.is_slaac() == slaac)
+                verify(p.is_dhcp() == dhcp)
+                verify(p.is_config() == configure)
+                verify(p.is_preferred() == preferred)
+                verify(p.priority == priority)
+                break
+        else:
+            raise wpan.VerifyError("Did not find prefix {} on node {}".format(
+                prefix, node))
+
+
+def verify_no_prefix(node_list, prefix, rloc16):
+    """
+    This function verifies that none of the nodes in `node_list` contains the on-mesh `prefix` associated with the
+    given `rloc16`.
+    """
+    for node in node_list:
+        prefixes = wpan.parse_on_mesh_prefix_result(
+            node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
+        for p in prefixes:
+            if (p.prefix == prefix and p.origin == "ncp" and
+                    int(p.rloc16(), 0) == rloc16):
+                raise wpan.VerifyError(
+                    "Did find prefix {} with rloc {} on node {}".format(
+                        prefix, hex(rloc16), node))
+
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Creating `wpan.Nodes` instances
+
+speedup = 25
+wpan.Node.set_time_speedup_factor(speedup)
+
+leader = wpan.Node()
+c1 = wpan.Node()
+c2 = wpan.Node()
+c3 = wpan.Node()
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Init all nodes
+
+wpan.Node.init_all_nodes()
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Build network topology
+#
+
+leader.form("bloodborne")  # "fear the old blood"
+
+c1.join_node(leader, wpan.JOIN_TYPE_END_DEVICE)
+c2.join_node(leader, wpan.JOIN_TYPE_END_DEVICE)
+c3.join_node(leader, wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
+c3.set(wpan.WPAN_POLL_INTERVAL, '400')
+
+# Clear the "full network data" flag on c3.
+c3.set(wpan.WPAN_THREAD_DEVICE_MODE,
+       str(wpan.THREAD_MODE_FLAG_SECURE_DATA_REQUEST))
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test implementation
+
+WAIT_TIME = 15
+
+prefix1 = "fd00:1::"
+prefix2 = "fd00:2::"
+prefix3 = "fd00:3::"
+
+leader_rloc = int(leader.get(wpan.WPAN_THREAD_RLOC16), 0)
+c1_rloc = int(c1.get(wpan.WPAN_THREAD_RLOC16), 0)
+c2_rloc = int(c2.get(wpan.WPAN_THREAD_RLOC16), 0)
+no_rloc = 0xfffe
+
+
+def test_prefix_add_remove():
+    # Tests adding and removing stable and temporary prefixes on r1
+    # Verifies that all nodes in network do see the updates and that
+    # Network Data version and stable version are updated correctly.
+
+    old_version = int(leader.get(wpan.WPAN_THREAD_NETWORK_DATA_VERSION), 0)
+    old_stable_version = int(
+        leader.get(wpan.WPAN_THREAD_STABLE_NETWORK_DATA_VERSION), 0)
+
+    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    # Add a stable prefix and check all nodes see the prefix
+    c1.add_prefix(prefix1, stable=True)
+
+    def check_prefix1():
+        verify_prefix(
+            [leader, c1, c2],
+            prefix1,
+            c1_rloc,
+            stable=True,
+        )
+
+        verify_prefix(
+            [c3],
+            prefix1,
+            no_rloc,
+            stable=True,
+        )
+
+    wpan.verify_within(check_prefix1, WAIT_TIME)
+
+    new_version = int(leader.get(wpan.WPAN_THREAD_NETWORK_DATA_VERSION), 0)
+    new_stable_version = int(
+        leader.get(wpan.WPAN_THREAD_STABLE_NETWORK_DATA_VERSION), 0)
+
+    verify(new_version == ((old_version + 1) % 256))
+    verify(new_stable_version == ((old_stable_version + 1) % 256))
+
+    old_version = new_version
+    old_stable_version = new_stable_version
+
+    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    # Add prefix 2 as temp (not stable)
+
+    c1.add_prefix(prefix2, stable=False)
+
+    def check_prefix2():
+        verify_prefix(
+            [leader, c1, c2],
+            prefix2,
+            c1_rloc,
+            stable=False,
+        )
+
+    wpan.verify_within(check_prefix1, WAIT_TIME)
+    wpan.verify_within(check_prefix2, WAIT_TIME)
+
+    new_version = int(leader.get(wpan.WPAN_THREAD_NETWORK_DATA_VERSION), 0)
+    new_stable_version = int(
+        leader.get(wpan.WPAN_THREAD_STABLE_NETWORK_DATA_VERSION), 0)
+
+    verify(new_version == ((old_version + 1) % 256))
+    verify(new_stable_version == old_stable_version)
+
+    old_version = new_version
+    old_stable_version = new_stable_version
+
+    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    # Remove prefix 1
+
+    c1.remove_prefix(prefix1)
+
+    def check_no_prefix1():
+        verify_no_prefix([leader, c1, c2], prefix1, c1_rloc)
+
+    wpan.verify_within(check_no_prefix1, WAIT_TIME)
+    wpan.verify_within(check_prefix2, WAIT_TIME)
+
+    new_version = int(leader.get(wpan.WPAN_THREAD_NETWORK_DATA_VERSION), 0)
+    new_stable_version = int(
+        leader.get(wpan.WPAN_THREAD_STABLE_NETWORK_DATA_VERSION), 0)
+
+    verify(new_version == ((old_version + 1) % 256))
+    verify(new_stable_version == ((old_stable_version + 1) % 256))
+
+    old_version = new_version
+    old_stable_version = new_stable_version
+
+    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    # Remove prefix 2
+
+    c1.remove_prefix(prefix2)
+
+    def check_no_prefix2():
+        verify_no_prefix([leader, c1, c2], prefix2, c1_rloc)
+
+    wpan.verify_within(check_no_prefix1, WAIT_TIME)
+    wpan.verify_within(check_no_prefix2, WAIT_TIME)
+
+    new_version = int(leader.get(wpan.WPAN_THREAD_NETWORK_DATA_VERSION), 0)
+    new_stable_version = int(
+        leader.get(wpan.WPAN_THREAD_STABLE_NETWORK_DATA_VERSION), 0)
+
+    verify(new_version == ((old_version + 1) % 256))
+    verify(new_stable_version == old_stable_version)
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Repeat the `test_prefix_add_remove()` under different situations
+# where same prefix is added/removed by other nodes in the network
+# or added as an off-mesh route.
+
+num_routes = 0
+
+test_prefix_add_remove()
+
+leader.add_prefix(prefix1, stable=False)
+test_prefix_add_remove()
+
+leader.add_prefix(prefix2, stable=True)
+test_prefix_add_remove()
+
+leader.remove_prefix(prefix1)
+test_prefix_add_remove()
+
+leader.remove_prefix(prefix2)
+test_prefix_add_remove()
+
+leader.add_route(prefix1, stable=False)
+num_routes = num_routes + 1
+test_prefix_add_remove()
+verify(
+    len(wpan.parse_list(c2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
+    num_routes)
+
+leader.add_route(prefix2, stable=True)
+num_routes = num_routes + 1
+test_prefix_add_remove()
+verify(
+    len(wpan.parse_list(c2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
+    num_routes)
+
+leader.add_prefix(prefix3, stable=True)
+test_prefix_add_remove()
+verify(
+    len(wpan.parse_list(c2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
+    num_routes)
+
+leader.remove_route(prefix2)
+num_routes = num_routes - 1
+test_prefix_add_remove()
+verify(
+    len(wpan.parse_list(c2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
+    num_routes)
+
+leader.remove_route(prefix1)
+num_routes = num_routes - 1
+test_prefix_add_remove()
+verify(
+    len(wpan.parse_list(c2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
+    num_routes)
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test finished
+
+wpan.Node.finalize_all_nodes()
+
+print('\'{}\' passed.'.format(test_name))
diff --git a/tests/toranj/test-041-lowpan-fragmentation.py b/tests/toranj/test-041-lowpan-fragmentation.py
new file mode 100644
index 0000000..b807152
--- /dev/null
+++ b/tests/toranj/test-041-lowpan-fragmentation.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+
+import wpan
+from wpan import verify
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test description: This test verifies 6LoWPAN fragmentation code by exchanging IPv6 messages with
+# many different lengths between two nodes.
+
+test_name = __file__[:-3] if __file__.endswith('.py') else __file__
+print('-' * 120)
+print('Starting \'{}\''.format(test_name))
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Creating `wpan.Nodes` instances
+
+speedup = 4
+wpan.Node.set_time_speedup_factor(speedup)
+
+node1 = wpan.Node()
+node2 = wpan.Node()
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Init all nodes
+
+wpan.Node.init_all_nodes()
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Build network topology
+
+# Two-node network (node1 leader/router, node2 end-device)
+
+node1.form('horizon')  # "zero dawn"
+node2.join_node(node1, node_type=wpan.JOIN_TYPE_END_DEVICE)
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test implementation
+
+# Get the link local addresses
+ll1 = node1.get(wpan.WPAN_IP6_LINK_LOCAL_ADDRESS)[1:-1]
+ll2 = node2.get(wpan.WPAN_IP6_LINK_LOCAL_ADDRESS)[1:-1]
+
+PORT = 1234
+MSG_LEN_START = 100
+MSG_LEN_END = 500
+
+for msg_length in range(MSG_LEN_START, MSG_LEN_END):
+    sender = node1.prepare_tx((ll1, PORT), (ll2, PORT), msg_length)
+    recver = node2.prepare_rx(sender)
+
+    wpan.Node.perform_async_tx_rx()
+
+    verify(sender.was_successful)
+    verify(recver.was_successful)
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test finished
+
+wpan.Node.finalize_all_nodes()
+
+print('\'{}\' passed.'.format(test_name))
diff --git a/tests/toranj/test-042-meshcop-joiner-discerner.py b/tests/toranj/test-042-meshcop-joiner-discerner.py
new file mode 100644
index 0000000..abd2d85
--- /dev/null
+++ b/tests/toranj/test-042-meshcop-joiner-discerner.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+
+import wpan
+from wpan import verify
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test description: Test use of Joiner Discerner for commissioning
+#
+
+test_name = __file__[:-3] if __file__.endswith('.py') else __file__
+print('-' * 120)
+print('Starting \'{}\''.format(test_name))
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Creating `wpan.Nodes` instances
+
+speedup = 4
+wpan.Node.set_time_speedup_factor(speedup)
+
+commr = wpan.Node()
+joiner1 = wpan.Node()
+joiner2 = wpan.Node()
+joiner3 = wpan.Node()
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Init all nodes
+
+wpan.Node.init_all_nodes()
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Build network topology
+
+commr.form('discerner')
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test implementation
+
+WAIT_TIME = 2  # seconds
+
+PSK1 = 'UNCHARTEDTHEL0STLEGACY'
+PSK2 = 'UNCHARTED4ATH1EFSEND'
+PSK3 = 'THELAST0FUS'
+
+DISCERNER1 = '0x777'
+D_LEN1 = 12
+
+DISCERNER2 = '0x7777777'
+D_LEN2 = 32
+
+EUI64_3 = joiner3.get(wpan.WPAN_HW_ADDRESS)[1:-1]  # Remove the "[]"
+
+JOINER_TIMOUT = '500'  # in seconds
+
+# Verify Discerner value after device reset on Joiner
+
+verify(int(joiner1.get(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH), 0) == 0)
+verify(int(joiner1.get(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE), 0) == 0)
+
+# Set Joiner Discerner on `joiner1` and `joiner2`
+
+joiner1.set(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH, str(D_LEN1))
+joiner1.set(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE, DISCERNER1)
+verify(
+    int(joiner1.get(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH), 0) == D_LEN1)
+verify(
+    int(joiner1.get(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE), 0) == int(
+        DISCERNER1, 0))
+
+joiner2.set(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH, str(D_LEN2))
+joiner2.set(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE, DISCERNER2)
+verify(
+    int(joiner2.get(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH), 0) == D_LEN2)
+verify(
+    int(joiner2.get(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE), 0) == int(
+        DISCERNER2, 0))
+
+# Check clearing of a previously set Joiner Discerner
+
+joiner3.set(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH, str(D_LEN2))
+joiner3.set(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE, DISCERNER2)
+verify(
+    int(joiner3.get(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH), 0) == D_LEN2)
+verify(
+    int(joiner3.get(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE), 0) == int(
+        DISCERNER2, 0))
+
+joiner3.set(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH, '0')
+verify(int(joiner3.get(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH), 0) == 0)
+verify(int(joiner3.get(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE), 0) == 0)
+
+# Adding Joiners on Commissioner
+
+commr.commissioner_start()
+
+commr.commissioner_add_joiner_with_discerner(DISCERNER1, D_LEN1, PSK1,
+                                             JOINER_TIMOUT)
+commr.commissioner_add_joiner_with_discerner(DISCERNER2, D_LEN2, PSK2,
+                                             JOINER_TIMOUT)
+commr.commissioner_add_joiner(EUI64_3, PSK3, JOINER_TIMOUT)
+
+verify(
+    len(wpan.parse_list(commr.get(wpan.WPAN_THREAD_COMMISSIONER_JOINERS))) == 3)
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Start `joiner2` first
+
+# Starting with `joiner2` verifies the behavior of Commissioner to
+# prefer the Joiner entry with the longest matching discriminator. Note
+# that `joiner2` uses a longer discriminator compared to `joiner1` with
+# similar value.
+
+joiner2.joiner_join(PSK2)
+verify(joiner2.get(wpan.WPAN_STATE) == wpan.STATE_COMMISSIONED)
+joiner2.joiner_attach()
+
+
+def joiner2_is_associated():
+    verify(joiner2.is_associated())
+
+
+wpan.verify_within(joiner2_is_associated, WAIT_TIME)
+
+# Start `joiner1`
+
+joiner1.joiner_join(PSK1)
+verify(joiner1.get(wpan.WPAN_STATE) == wpan.STATE_COMMISSIONED)
+joiner1.joiner_attach()
+
+
+def joiner1_is_associated():
+    verify(joiner1.is_associated())
+
+
+wpan.verify_within(joiner1_is_associated, WAIT_TIME)
+
+# Start `joiner3`
+
+joiner3.joiner_join(PSK3)
+verify(joiner3.get(wpan.WPAN_STATE) == wpan.STATE_COMMISSIONED)
+joiner3.joiner_attach()
+
+
+def joiner3_is_associated():
+    verify(joiner3.is_associated())
+
+
+wpan.verify_within(joiner3_is_associated, WAIT_TIME)
+
+# -----------------------------------------------------------------------------------------------------------------------
+# Test finished
+
+wpan.Node.finalize_all_nodes()
+
+print('\'{}\' passed.'.format(test_name))
diff --git a/tests/toranj/test-100-mcu-power-state.py b/tests/toranj/test-100-mcu-power-state.py
index db5aa62..c430b9d 100644
--- a/tests/toranj/test-100-mcu-power-state.py
+++ b/tests/toranj/test-100-mcu-power-state.py
@@ -84,27 +84,23 @@
 
 node.set(wpan.WPAN_NCP_MCU_POWER_STATE, 'low-power')
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 verify(node.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED)
 
 node.set(wpan.WPAN_NCP_MCU_POWER_STATE, 'on')
 verify(node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_ON)
 
-node.set(
-    wpan.WPAN_NCP_MCU_POWER_STATE, 'lp'
-)  # special short-form string for low-power
+node.set(wpan.WPAN_NCP_MCU_POWER_STATE,
+         'lp')  # special short-form string for low-power
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 
 node.set(wpan.WPAN_NCP_MCU_POWER_STATE, wpan.MCU_POWER_STATE_ON)
 verify(node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_ON)
 
 node.set(wpan.WPAN_NCP_MCU_POWER_STATE, wpan.MCU_POWER_STATE_LOW_POWER)
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 verify(node.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED)
 
 # Verify that `wpantund` will restore the user-set value after NCP reset
@@ -112,8 +108,7 @@
 node.reset()
 time.sleep(1)
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 node.set(wpan.WPAN_NCP_MCU_POWER_STATE, wpan.MCU_POWER_STATE_ON)
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -135,8 +130,7 @@
 
 node.get(wpan.WPAN_THREAD_RLOC16)
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 verify(node.get(wpan.WPAN_STATE) == wpan.STATE_DEEP_SLEEP)
 
 # Setting the power state to `on` should change wpantund state to `OFFLINE`
@@ -150,8 +144,7 @@
 node.wpanctl('begin-low-power')
 wpan.verify_within(check_wpan_is_in_deep_sleep_state, WAIT_TIME)
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 
 node.set(wpan.WPAN_NCP_MCU_POWER_STATE, wpan.MCU_POWER_STATE_ON)
 wpan.verify_within(check_wpan_is_in_offline_state, WAIT_TIME)
@@ -166,8 +159,7 @@
 # does not change the state.
 node.wpanctl('begin-low-power')
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 verify(node.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED)
 
 # After reset, power state should remain `LOW_POWER` (wpantund would restore the value
@@ -199,8 +191,7 @@
 verify(node.get('Daemon:Enabled') == 'false')
 wpan.verify_within(check_wpan_is_in_deep_sleep_state, WAIT_TIME)
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 
 # Enabling `wpantund` should update the `MCU_POWER_STATE` back to `ON`.
 node.set('Daemon:Enabled', 'true')
@@ -219,8 +210,7 @@
 verify(node.get('Daemon:Enabled') == 'false')
 wpan.verify_within(check_wpan_is_in_deep_sleep_state, WAIT_TIME)
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 
 node.set('Daemon:Enabled', 'true')
 wpan.verify_within(check_wpan_is_in_commissioned_state, WAIT_TIME)
@@ -236,14 +226,12 @@
 
 node.set(wpan.WPAN_NCP_MCU_POWER_STATE, wpan.MCU_POWER_STATE_LOW_POWER)
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 
 node.form("resume-test")
 verify(node.is_associated())
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 
 node.reset()
 
@@ -253,8 +241,7 @@
 
 wpan.verify_within(check_wpan_is_in_associating_state, WAIT_TIME)
 verify(
-    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER
-)
+    node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER)
 
 # -----------------------------------------------------------------------------------------------------------------------
 # Test finished
diff --git a/tests/toranj/test-600-channel-manager-properties.py b/tests/toranj/test-600-channel-manager-properties.py
index 8e9f72d..01d5485 100644
--- a/tests/toranj/test-600-channel-manager-properties.py
+++ b/tests/toranj/test-600-channel-manager-properties.py
@@ -75,41 +75,33 @@
 verify(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED) == 'false')
 
 node.set(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL, '1000')
-verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL), 0) == 1000
-)
+verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL), 0) == 1000)
 
-all_channls_mask = int('0x7fff800', 0)
+all_channels_mask = int('0x7fff800', 0)
 chan_11_mask = int('0x800', 0)
 chan_11_to_13_mask = int('0x3800', 0)
 
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK, str(all_channls_mask)
-)
+node.set(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK,
+         str(all_channels_mask))
 verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0)
-    == all_channls_mask
-)
+    int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0) ==
+    all_channels_mask)
 
 node.set(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK, str(chan_11_mask))
 verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK), 0)
-    == chan_11_mask
-)
+    int(node.get(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK), 0) ==
+    chan_11_mask)
 
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK, str(chan_11_to_13_mask)
-)
+node.set(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK,
+         str(chan_11_to_13_mask))
 verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0)
-    == chan_11_to_13_mask
-)
+    int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0) ==
+    chan_11_to_13_mask)
 
-node.set(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK, str(all_channls_mask))
+node.set(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK, str(all_channels_mask))
 verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK), 0)
-    == all_channls_mask
-)
+    int(node.get(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK), 0) ==
+    all_channels_mask)
 
 node.set(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED, '1')
 verify(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED) == 'true')
@@ -123,26 +115,19 @@
 
 while node.get(wpan.WPAN_STATE) != wpan.STATE_ASSOCIATED:
     if time.time() - start_time > wait_time:
-        print(
-            'Took too long to restore after reset ({}>{} sec)'.format(
-                time.time() - start_time, wait_time
-            )
-        )
+        print('Took too long to restore after reset ({}>{} sec)'.format(
+            time.time() - start_time, wait_time))
         exit(1)
     time.sleep(2)
 
 verify(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED) == 'true')
 verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK), 0)
-    == all_channls_mask
-)
+    int(node.get(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK), 0) ==
+    all_channels_mask)
 verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0)
-    == chan_11_to_13_mask
-)
-verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL), 0) == 1000
-)
+    int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0) ==
+    chan_11_to_13_mask)
+verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL), 0) == 1000)
 verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_DELAY), 0) == 180)
 
 # -----------------------------------------------------------------------------------------------------------------------
diff --git a/tests/toranj/test-601-channel-manager-channel-change.py b/tests/toranj/test-601-channel-manager-channel-change.py
index 561aa30..3635ab4 100644
--- a/tests/toranj/test-601-channel-manager-channel-change.py
+++ b/tests/toranj/test-601-channel-manager-channel-change.py
@@ -45,18 +45,13 @@
     """
     start_time = time.time()
 
-    while not all(
-        [
-            (new_channel == int(node.get(wpan.WPAN_CHANNEL), 0))
-            for node in nodes
-        ]
-    ):
+    while not all([
+        (new_channel == int(node.get(wpan.WPAN_CHANNEL), 0)) for node in nodes
+    ]):
         if time.time() - start_time > wait_time:
-            print(
-                'Took too long to switch to channel {} ({}>{} sec)'.format(
-                    new_channel, time.time() - start_time, wait_time
-                )
-            )
+            print('Took too long to switch to channel {} ({}>{} sec)'.format(
+                new_channel,
+                time.time() - start_time, wait_time))
             exit(1)
         time.sleep(0.1)
 
@@ -142,9 +137,8 @@
 
 # Request different channels from two routers (r1 and r2)
 
-r1.set(
-    wpan.WPAN_CHANNEL_MANAGER_DELAY, '20'
-)  # increase the time to ensure r1 change is in process
+r1.set(wpan.WPAN_CHANNEL_MANAGER_DELAY,
+       '20')  # increase the time to ensure r1 change is in process
 r1.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '17')
 time.sleep(10.5 / speedup)
 verify_channel(all_nodes, 16)
diff --git a/tests/toranj/test-602-channel-manager-channel-select.py b/tests/toranj/test-602-channel-manager-channel-select.py
index 253ce03..b2a02d2 100644
--- a/tests/toranj/test-602-channel-manager-channel-select.py
+++ b/tests/toranj/test-602-channel-manager-channel-select.py
@@ -45,18 +45,13 @@
     """
     start_time = time.time()
 
-    while not all(
-        [
-            (new_channel == int(node.get(wpan.WPAN_CHANNEL), 0))
-            for node in nodes
-        ]
-    ):
+    while not all([
+        (new_channel == int(node.get(wpan.WPAN_CHANNEL), 0)) for node in nodes
+    ]):
         if time.time() - start_time > wait_time:
-            print(
-                'Took too long to switch to channel {} ({}>{} sec)'.format(
-                    new_channel, time.time() - start_time, wait_time
-                )
-            )
+            print('Took too long to switch to channel {} ({}>{} sec)'.format(
+                new_channel,
+                time.time() - start_time, wait_time))
             exit(1)
         time.sleep(0.1)
 
@@ -82,24 +77,34 @@
 # -----------------------------------------------------------------------------------------------------------------------
 # Test implementation
 
-all_channls_mask = int('0x7fff800', 0)
+all_channels_mask = int('0x7fff800', 0)
 chan_12_to_15_mask = int('0x000f000', 0)
 chan_15_to_17_mask = int('0x0038000', 0)
 
 # Set supported channel mask to be all channels
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK, str(all_channls_mask)
-)
+node.set(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK,
+         str(all_channels_mask))
 verify(
-    int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0)
-    == all_channls_mask
-)
+    int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0) ==
+    all_channels_mask)
+
+WAIT_TIME = 15
+EXPECTED_SAMEPLE_COUNT = 970
 
 # Sleep for 4.5 second with speedup factor of 10,000 this is more than 12
-# hours.
+# hours. We sleep instead of immediately checking the sample counter in
+# order to not add more actions/events into simulation (specially since
+# we are running at very high speedup).
 time.sleep(4.5)
 
-verify(int(node.get(wpan.WPAN_CHANNEL_MONITOR_SAMPLE_COUNT), 0) > 970)
+
+def check_sample_count():
+    verify(
+        int(node.get(wpan.WPAN_CHANNEL_MONITOR_SAMPLE_COUNT), 0) >
+        EXPECTED_SAMEPLE_COUNT)
+
+
+wpan.verify_within(check_sample_count, WAIT_TIME)
 
 # Verify the initial value of `NEW_CHANNEL` (should be zero if there has
 # been no channel change so far).
@@ -124,12 +129,10 @@
 # Even though 11 would be best, quality difference between 11 and 12 is not high enough for selection
 # algorithm to pick an unfavored channel.
 
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK, str(chan_12_to_15_mask)
-)
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '25'
-)  # request a channel change to 25
+node.set(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK,
+         str(chan_12_to_15_mask))
+node.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL,
+         '25')  # request a channel change to 25
 verify_channel([node], 25)
 node.set(wpan.WPAN_CHANNEL_MANAGER_CHANNEL_SELECT, 'true')
 verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 12)
@@ -140,13 +143,11 @@
 # This time the quality difference between 11 and 15 should be high enough for selection
 # algorithm to pick the best though unfavored channel (i.e., channel 11).
 
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '25'
-)  # request a channel change to 25
+node.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL,
+         '25')  # request a channel change to 25
 verify_channel([node], 25)
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK, str(chan_15_to_17_mask)
-)
+node.set(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK,
+         str(chan_15_to_17_mask))
 node.set(wpan.WPAN_CHANNEL_MANAGER_CHANNEL_SELECT, 'true')
 verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 11)
 verify_channel([node], 11)
@@ -154,9 +155,8 @@
 # Set channels 12-15 as favorable and request a channel select, verify
 # that channel is not switched.
 
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK, str(chan_12_to_15_mask)
-)
+node.set(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK,
+         str(chan_12_to_15_mask))
 node.set(wpan.WPAN_CHANNEL_MANAGER_CHANNEL_SELECT, 'true')
 verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 11)
 verify_channel([node], 11)
@@ -165,12 +165,11 @@
 # However, since quality difference between current channel 12 and new best channel 11 is not large
 # enough, no action should be taken.
 
-node.set(
-    wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '12'
-)  # request a channel change to 12
+node.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL,
+         '12')  # request a channel change to 12
 verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 12)
 verify_channel([node], 12)
-node.set(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK, str(all_channls_mask))
+node.set(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK, str(all_channels_mask))
 node.set(wpan.WPAN_CHANNEL_MANAGER_CHANNEL_SELECT, 'true')
 verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 12)
 verify_channel([node], 12)
diff --git a/tests/toranj/test-603-channel-manager-announce-recovery.py b/tests/toranj/test-603-channel-manager-announce-recovery.py
index 381f68f..ce0f62b 100644
--- a/tests/toranj/test-603-channel-manager-announce-recovery.py
+++ b/tests/toranj/test-603-channel-manager-announce-recovery.py
@@ -45,18 +45,13 @@
     """
     start_time = time.time()
 
-    while not all(
-        [
-            (new_channel == int(node.get(wpan.WPAN_CHANNEL), 0))
-            for node in nodes
-        ]
-    ):
+    while not all([
+        (new_channel == int(node.get(wpan.WPAN_CHANNEL), 0)) for node in nodes
+    ]):
         if time.time() - start_time > wait_time:
-            print(
-                'Took too long to switch to channel {} ({}>{} sec)'.format(
-                    new_channel, time.time() - start_time, wait_time
-                )
-            )
+            print('Took too long to switch to channel {} ({}>{} sec)'.format(
+                new_channel,
+                time.time() - start_time, wait_time))
             exit(1)
         time.sleep(0.1)
 
diff --git a/tests/toranj/wpan.py b/tests/toranj/wpan.py
index 3eee1ec..244cbb0 100644
--- a/tests/toranj/wpan.py
+++ b/tests/toranj/wpan.py
@@ -110,6 +110,9 @@
 WPAN_THREAD_PENDING_DATASET_ASVALMAP = "Thread:PendingDataset:AsValMap"
 WPAN_THREAD_ADDRESS_CACHE_TABLE = "Thread:AddressCacheTable"
 WPAN_THREAD_ADDRESS_CACHE_TABLE_ASVALMAP = "Thread:AddressCacheTable:AsValMap"
+WPAN_THREAD_JOINER_DISCERNER_VALUE = "Joiner:Discerner:Value"
+WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH = "Joiner:Discerner:BitLength"
+WPAN_THREAD_COMMISSIONER_JOINERS = "Commissioner:Joiners"
 
 WPAN_OT_LOG_LEVEL = "OpenThread:LogLevel"
 WPAN_OT_SLAAC_ENABLED = "OpenThread:SLAAC:Enabled"
@@ -244,6 +247,14 @@
 JOIN_TYPE_SLEEPY_END_DEVICE = 's'
 
 # -----------------------------------------------------------------------------------------------------------------------
+# Address Cache Table Entry States
+
+ADDRESS_CACHE_ENTRY_STATE_CACHED = "cached"
+ADDRESS_CACHE_ENTRY_STATE_SNOOPED = "snooped"
+ADDRESS_CACHE_ENTRY_STATE_QUERY = "query"
+ADDRESS_CACHE_ENTRY_STATE_RETRY_QUERY = "retry-query"
+
+# -----------------------------------------------------------------------------------------------------------------------
 # Bit Flags for Thread Device Mode `WPAN_THREAD_DEVICE_MODE`
 
 THREAD_MODE_FLAG_FULL_NETWORK_DATA = (1 << 0)
@@ -264,6 +275,7 @@
     if flush:
         sys.stdout.flush()
 
+
 # -----------------------------------------------------------------------------------------------------------------------
 # Node class
 
@@ -272,21 +284,22 @@
     """ A wpantund OT NCP instance """
 
     # defines the default verbosity setting (can be changed per `Node`)
-    _VERBOSE = False
-    _SPEED_UP_FACTOR = 1    # defines the default time speed up factor
+    _VERBOSE = os.getenv('TORANJ_VERBOSE',
+                         'no').lower() in ['true', '1', 't', 'y', 'yes', 'on']
+    _SPEED_UP_FACTOR = 1  # defines the default time speed up factor
 
     # path to `wpantund`, `wpanctl`, `ot-ncp-ftd`,`ot-ncp` and `ot-rcp`
     _WPANTUND = '%s/sbin/wpantund' % _WPANTUND_PREFIX
     _WPANCTL = '%s/bin/wpanctl' % _WPANTUND_PREFIX
 
     _OT_NCP_FTD = '%s/examples/apps/ncp/ot-ncp-ftd' % _OT_BUILDDIR
-    _OT_NCP_FTD_POSIX_APP = '%s/src/posix/ot-ncp' % _OT_BUILDDIR
+    _OT_NCP_FTD_POSIX = '%s/src/posix/ot-ncp' % _OT_BUILDDIR
     _OT_RCP = '%s/examples/apps/ncp/ot-rcp' % _OT_BUILDDIR
 
     # Environment variable used to determine how to run OpenThread
-    # If set to 1, then posix-app (`ot-ncp`) is used along with a posix RCP `ot-rcp`.
+    # If set to 1, then posix NCP (`ot-ncp`) is used along with a posix RCP `ot-rcp`.
     # Otherwise, the posix NCP `ot-ncp-ftd` is used
-    _POSIX_APP_ENV_VAR = 'TORANJ_POSIX_APP_RCP_MODEL'
+    _POSIX_ENV_VAR = 'TORANJ_POSIX_RCP_MODEL'
 
     # determines if the wpantund logs are saved in file or sent to stdout
     _TUND_LOG_TO_FILE = True
@@ -311,20 +324,22 @@
         self._interface_name = self._INTFC_NAME_PREFIX + str(index)
         self._verbose = verbose
 
-        # Check if env variable `TORANJ_POSIX_APP_RCP_MODEL` is defined
+        # Check if env variable `TORANJ_POSIX_RCP_MODEL` is defined
         # and use it to determine if to use operate in "posix-ncp-app".
-        if self._POSIX_APP_ENV_VAR in os.environ:
-            self._use_posix_app_with_rcp = (
-                os.environ[self._POSIX_APP_ENV_VAR] in ['1', 'yes'])
+        if self._POSIX_ENV_VAR in os.environ:
+            self._use_posix_with_rcp = (os.environ[self._POSIX_ENV_VAR] in [
+                '1', 'yes'
+            ])
         else:
-            self._use_posix_app_with_rcp = False
+            self._use_posix_with_rcp = False
 
-        if self._use_posix_app_with_rcp:
-            ncp_socket_path = 'system:{} -s {} {} {}'.format(
-                self._OT_NCP_FTD_POSIX_APP, self._SPEED_UP_FACTOR, self._OT_RCP, index)
+        if self._use_posix_with_rcp:
+            ncp_socket_path = 'system:{} -s {} spinel+hdlc+uart://{}?forkpty-arg={}'.format(
+                self._OT_NCP_FTD_POSIX, self._SPEED_UP_FACTOR, self._OT_RCP,
+                index)
         else:
-            ncp_socket_path = 'system:{} {} {}'.format(
-                self._OT_NCP_FTD, index, self._SPEED_UP_FACTOR)
+            ncp_socket_path = 'system:{} {} {}'.format(self._OT_NCP_FTD, index,
+                                                       self._SPEED_UP_FACTOR)
 
         cmd = self._WPANTUND + \
             ' -o Config:NCP:SocketPath \"{}\"'.format(ncp_socket_path) + \
@@ -341,8 +356,9 @@
         if self._verbose:
             _log('$ Node{}.__init__() cmd: {}'.format(index, cmd))
 
-        self._wpantund_process = subprocess.Popen(
-            cmd, shell=True, stderr=self._tund_log_file)
+        self._wpantund_process = subprocess.Popen(cmd,
+                                                  shell=True,
+                                                  stderr=self._tund_log_file)
 
         self._wpanctl_cmd = self._WPANCTL + ' -I ' + self._interface_name + ' '
 
@@ -373,8 +389,8 @@
         return self._tund_log_file
 
     @property
-    def using_posix_app_with_rcp(self):
-        return self._use_posix_app_with_rcp
+    def using_posix_with_rcp(self):
+        return self._use_posix_with_rcp
 
     # ------------------------------------------------------------------------------------------------------------------
     # Executing a `wpanctl` command
@@ -383,19 +399,15 @@
         """ Runs a wpanctl command on the given wpantund/OT-NCP instance and returns the output """
 
         if self._verbose:
-            _log(
-                '$ Node{}.wpanctl(\'{}\')'.format(
-                    self._index,
-                    cmd),
-                new_line=False)
+            _log('$ Node{}.wpanctl(\'{}\')'.format(self._index, cmd),
+                 new_line=False)
 
-        result = subprocess.check_output(
-            self._wpanctl_cmd + cmd,
-            shell=True,
-            stderr=subprocess.STDOUT)
+        result = subprocess.check_output(self._wpanctl_cmd + cmd,
+                                         shell=True,
+                                         stderr=subprocess.STDOUT)
 
-        if len(
-                result) >= 1 and result[-1] == '\n':  # remove the last char if it is '\n',
+        if len(result) >= 1 and result[
+                -1] == '\n':  # remove the last char if it is '\n',
             result = result[:-1]
 
         if self._verbose:
@@ -424,8 +436,9 @@
         return self._update_prop('remove', prop_name, value, binary_data)
 
     def _update_prop(self, action, prop_name, value, binary_data):
-        return self.wpanctl(action + ' ' + prop_name + ' ' + ('-d ' if binary_data else '')
-                            + '-v ' + value)  # use -v to handle values starting with `-`.
+        return self.wpanctl(action + ' ' + prop_name + ' ' +
+                            ('-d ' if binary_data else '') + '-v ' +
+                            value)  # use -v to handle values starting with `-`.
 
     def reset(self):
         return self.wpanctl('reset')
@@ -436,64 +449,65 @@
     def leave(self):
         return self.wpanctl('leave')
 
-    def form(
-            self,
-            name,
-            channel=None,
-            channel_mask=None,
-            panid=None,
-            xpanid=None,
-            key=None,
-            key_index=None,
-            node_type=None,
-            mesh_local_prefix=None,
-            legacy_prefix=None):
-        return self.wpanctl('form \"' + name + '\"'
-                            + (' -c {}'.format(channel) if channel is not None else '')
-                            + (' -m {}'.format(channel_mask) if channel_mask is not None else '')
-                            + (' -p {}'.format(panid) if panid is not None else '')
-                            + (' -x {}'.format(xpanid) if xpanid is not None else '')
-                            + (' -k {}'.format(key) if key is not None else '')
-                            + (' -i {}'.format(key_index) if key_index is not None else '')
-                            + (' -T {}'.format(node_type) if node_type is not None else '')
-                            + (' -M {}'.format(mesh_local_prefix) if mesh_local_prefix is not None else '')
-                            + (' -L {}'.format(legacy_prefix) if legacy_prefix is not None else ''))
+    def form(self,
+             name,
+             channel=None,
+             channel_mask=None,
+             panid=None,
+             xpanid=None,
+             key=None,
+             key_index=None,
+             node_type=None,
+             mesh_local_prefix=None,
+             legacy_prefix=None):
+        return self.wpanctl(
+            'form \"' + name + '\"' +
+            (' -c {}'.format(channel) if channel is not None else '') +
+            (' -m {}'.format(channel_mask) if channel_mask is not None else ''
+            ) + (' -p {}'.format(panid) if panid is not None else '') +
+            (' -x {}'.format(xpanid) if xpanid is not None else '') +
+            (' -k {}'.format(key) if key is not None else '') +
+            (' -i {}'.format(key_index) if key_index is not None else '') +
+            (' -T {}'.format(node_type) if node_type is not None else '') +
+            (' -M {}'.format(mesh_local_prefix
+                            ) if mesh_local_prefix is not None else '') +
+            (' -L {}'.format(legacy_prefix) if legacy_prefix is not None else ''
+            ))
 
-    def join(
-            self,
-            name,
-            channel=None,
-            node_type=None,
-            panid=None,
-            xpanid=None,
-            key=None):
-        return self.wpanctl('join \"' + name + '\"'
-                            + (' -c {}'.format(channel) if channel is not None else '')
-                            + (' -T {}'.format(node_type) if node_type is not None else '')
-                            + (' -p {}'.format(panid) if panid is not None else '')
-                            + (' -x {}'.format(xpanid) if xpanid is not None else '')
-                            + (' -k {}'.format(key) if key is not None else '')
-                            + (' -n'))
+    def join(self,
+             name,
+             channel=None,
+             node_type=None,
+             panid=None,
+             xpanid=None,
+             key=None):
+        return self.wpanctl(
+            'join \"' + name + '\"' +
+            (' -c {}'.format(channel) if channel is not None else '') +
+            (' -T {}'.format(node_type) if node_type is not None else '') +
+            (' -p {}'.format(panid) if panid is not None else '') +
+            (' -x {}'.format(xpanid) if xpanid is not None else '') +
+            (' -k {}'.format(key) if key is not None else '') + (' -n'))
 
     def active_scan(self, channel=None):
         return self.wpanctl(
             'scan' + (' -c {}'.format(channel) if channel is not None else ''))
 
     def energy_scan(self, channel=None):
-        return self.wpanctl(
-            'scan -e' + (' -c {}'.format(channel) if channel is not None else ''))
+        return self.wpanctl('scan -e' + (
+            ' -c {}'.format(channel) if channel is not None else ''))
 
-    def discover_scan(
-            self,
-            channel=None,
-            joiner_only=False,
-            enable_filtering=False,
-            panid_filter=None):
-        return self.wpanctl('scan -d'
-                            + (' -c {}'.format(channel) if channel is not None else '')
-                            + (' -j' if joiner_only else '')
-                            + (' -e' if enable_filtering else '')
-                            + (' -p {}'.format(panid_filter) if panid_filter is not None else ''))
+    def discover_scan(self,
+                      channel=None,
+                      joiner_only=False,
+                      enable_filtering=False,
+                      panid_filter=None):
+        return self.wpanctl(
+            'scan -d' +
+            (' -c {}'.format(channel) if channel is not None else '') +
+            (' -j' if joiner_only else '') +
+            (' -f' if enable_filtering else '') +
+            (' -p {}'.format(panid_filter) if panid_filter is not None else ''))
 
     def permit_join(self, duration_sec=None, port=None, udp=True, tcp=True):
         if not udp and not tcp:  # incorrect use!
@@ -506,72 +520,78 @@
         if port is not None and duration_sec is None:
             duration_sec = '240'
 
-        return self.wpanctl('permit-join'
-                            + (' {}'.format(duration_sec) if duration_sec is not None else '')
-                            + (' {}'.format(port) if port is not None else '')
-                            + traffic_type)
+        return self.wpanctl(
+            'permit-join' +
+            (' {}'.format(duration_sec) if duration_sec is not None else '') +
+            (' {}'.format(port) if port is not None else '') + traffic_type)
 
     def config_gateway(self, prefix, default_route=False, priority=None):
-        return self.wpanctl('config-gateway ' + prefix
-                            + (' -d' if default_route else '')
-                            + (' -P {}'.format(priority) if priority is not None else ''))
+        return self.wpanctl(
+            'config-gateway ' + prefix + (' -d' if default_route else '') +
+            (' -P {}'.format(priority) if priority is not None else ''))
 
-    def add_prefix(
-            self,
-            prefix,
-            prefix_len=None,
-            priority=None,
-            stable=True,
-            on_mesh=False,
-            slaac=False,
-            dhcp=False,
-            configure=False,
-            default_route=False,
-            preferred=False):
-        return self.wpanctl('add-prefix ' + prefix
-                            + (' -l {}'.format(prefix_len) if prefix_len is not None else '')
-                            + (' -P {}'.format(priority) if priority is not None else '')
-                            + (' -s' if stable else '')
-                            + (' -f' if preferred else '')
-                            + (' -a' if slaac else '')
-                            + (' -d' if dhcp else '')
-                            + (' -c' if configure else '')
-                            + (' -r' if default_route else '')
-                            + (' -o' if on_mesh else ''))
+    def add_prefix(self,
+                   prefix,
+                   prefix_len=None,
+                   priority=None,
+                   stable=True,
+                   on_mesh=False,
+                   slaac=False,
+                   dhcp=False,
+                   configure=False,
+                   default_route=False,
+                   preferred=False):
+        return self.wpanctl(
+            'add-prefix ' + prefix +
+            (' -l {}'.format(prefix_len) if prefix_len is not None else '') +
+            (' -P {}'.format(priority) if priority is not None else '') +
+            (' -s' if stable else '') + (' -f' if preferred else '') +
+            (' -a' if slaac else '') + (' -d' if dhcp else '') +
+            (' -c' if configure else '') + (' -r' if default_route else '') +
+            (' -o' if on_mesh else ''))
 
     def remove_prefix(self, prefix, prefix_len=None):
-        return self.wpanctl('remove-prefix ' + prefix
-                            + (' -l {}'.format(prefix_len) if prefix_len is not None else ''))
+        return self.wpanctl('remove-prefix ' + prefix + (
+            ' -l {}'.format(prefix_len) if prefix_len is not None else ''))
 
-    def add_route(
-            self,
-            route_prefix,
-            prefix_len=None,
-            priority=None,
-            stable=True):
+    def add_route(self,
+                  route_prefix,
+                  prefix_len=None,
+                  priority=None,
+                  stable=True):
         """route priority [(>0 for high, 0 for medium, <0 for low)]"""
-        return self.wpanctl('add-route ' + route_prefix
-                            + (' -l {}'.format(prefix_len) if prefix_len is not None else '')
-                            + (' -p {}'.format(priority) if priority is not None else '')
-                            + ('' if stable else '-n'))
+        return self.wpanctl(
+            'add-route ' + route_prefix +
+            (' -l {}'.format(prefix_len) if prefix_len is not None else '') +
+            (' -p {}'.format(priority) if priority is not None else '') +
+            ('' if stable else ' -n'))
 
-    def remove_route(
-            self,
-            route_prefix,
-            prefix_len=None,
-            priority=None,
-            stable=True):
+    def remove_route(self,
+                     route_prefix,
+                     prefix_len=None,
+                     priority=None,
+                     stable=True):
         """route priority [(>0 for high, 0 for medium, <0 for low)]"""
-        return self.wpanctl('remove-route ' + route_prefix
-                            + (' -l {}'.format(prefix_len) if prefix_len is not None else '')
-                            + (' -p {}'.format(priority) if priority is not None else ''))
+        return self.wpanctl(
+            'remove-route ' + route_prefix +
+            (' -l {}'.format(prefix_len) if prefix_len is not None else '') +
+            (' -p {}'.format(priority) if priority is not None else ''))
 
     def commissioner_start(self):
         return self.wpanctl('commissioner start')
 
     def commissioner_add_joiner(self, eui64, pskd, timeout='100'):
+        return self.wpanctl('commissioner joiner-add {} {} {}'.format(
+            eui64, timeout, pskd))
+
+    def commissioner_add_joiner_with_discerner(self,
+                                               discerner_value,
+                                               discerner_bit_len,
+                                               pskd,
+                                               timeout='100'):
         return self.wpanctl(
-            'commissioner joiner-add {} {} {}'.format(eui64, timeout, pskd))
+            'commissioner joiner-add-discerner {} {} {} {}'.format(
+                discerner_value, discerner_bit_len, timeout, pskd))
 
     def joiner_join(self, pskd):
         return self.wpanctl('joiner --join {}'.format(pskd))
@@ -607,10 +627,8 @@
 
     def un_whitelist_node(self, node):
         """Removes a given node (of node `Node) from the whitelist"""
-        self.remove(
-            WPAN_MAC_WHITELIST_ENTRIES,
-            node.get(WPAN_EXT_ADDRESS)[
-                1:-1])
+        self.remove(WPAN_MAC_WHITELIST_ENTRIES,
+                    node.get(WPAN_EXT_ADDRESS)[1:-1])
 
     def is_in_scan_result(self, scan_result):
         """Checks if node is in the scan results
@@ -624,15 +642,13 @@
         ext_address = self.get(WPAN_EXT_ADDRESS)[1:-1]
 
         for item in scan_result:
-            if all(
-                [
-                    item.network_name == name,
-                    item.panid == panid,
-                    item.xpanid == xpanid,
-                    item.channel == channel,
+            if all([
+                    item.network_name == name, item.panid == panid,
+                    item.xpanid == xpanid, item.channel == channel,
                     item.ext_address == ext_address,
-                    (item.type == ScanResult.TYPE_DISCOVERY_SCAN) or (
-                        item.joinable == joinable)]):
+                (item.type == ScanResult.TYPE_DISCOVERY_SCAN) or
+                (item.joinable == joinable)
+            ]):
                 return True
 
         return False
@@ -659,8 +675,9 @@
         if self._verbose:
             _log('$ Node{} \'{}\')'.format(self._index, cmd))
 
-        result = subprocess.check_output(
-            cmd, shell=True, stderr=subprocess.STDOUT)
+        result = subprocess.check_output(cmd,
+                                         shell=True,
+                                         stderr=subprocess.STDOUT)
         return result
 
     def remove_ip6_address_on_interface(self, address, prefix_len=64):
@@ -674,15 +691,16 @@
         if self._verbose:
             _log('$ Node{} \'{}\')'.format(self._index, cmd))
 
-        result = subprocess.check_output(
-            cmd, shell=True, stderr=subprocess.STDOUT)
+        result = subprocess.check_output(cmd,
+                                         shell=True,
+                                         stderr=subprocess.STDOUT)
         return result
 
     # ------------------------------------------------------------------------------------------------------------------
     # class methods
 
     @classmethod
-    def init_all_nodes(cls, disable_logs=True, wait_time=15):
+    def init_all_nodes(cls, disable_logs=not _VERBOSE, wait_time=15):
         """Issues a `wpanctl.leave` on all `Node` objects and waits for them to be ready"""
         random.seed(123456)
         time.sleep(0.5)
@@ -692,16 +710,21 @@
                 try:
                     node._wpantund_process.poll()
                     if node._wpantund_process.returncode is not None:
-                        print('Node {} wpantund instance has terminated unexpectedly'.format(node))
+                        print(
+                            'Node {} wpantund instance has terminated unexpectedly'
+                            .format(node))
                     if disable_logs:
                         node.set(WPAN_OT_LOG_LEVEL, '0')
                     node.leave()
                 except subprocess.CalledProcessError as e:
                     if (node._verbose):
-                        _log(' -> \'{}\' exit code: {}'.format(e.output, e.returncode))
+                        _log(' -> \'{}\' exit code: {}'.format(
+                            e.output, e.returncode))
                     interval = time.time() - start_time
                     if interval > wait_time:
-                        print('Took too long to init node {} ({}>{} sec)'.format(node, interval, wait_time))
+                        print(
+                            'Took too long to init node {} ({}>{} sec)'.format(
+                                node, interval, wait_time))
                         raise
                 except BaseException:
                     raise
@@ -721,7 +744,8 @@
         """Sets up the time speed up factor - should be set before creating any `Node` objects"""
         if len(Node._all_nodes) != 0:
             raise Node._NodeError(
-                'set_time_speedup_factor() cannot be called after creating a `Node`')
+                'set_time_speedup_factor() cannot be called after creating a `Node`'
+            )
         Node._SPEED_UP_FACTOR = factor
 
     # ------------------------------------------------------------------------------------------------------------------
@@ -764,15 +788,8 @@
         else:
             msg = data
 
-        return AsyncSender(
-            self,
-            src_addr,
-            src_port,
-            dst_addr,
-            dst_port,
-            msg,
-            count,
-            mcast_hops)
+        return AsyncSender(self, src_addr, src_port, dst_addr, dst_port, msg,
+                           count, mcast_hops)
 
     def _get_receiver(self, local_port):
         # Gets or creates a receiver (an `AsyncReceiver`) tied to given port
@@ -794,11 +811,8 @@
     def prepare_rx(self, sender):
         """Prepare to receive messages from a sender (an `AsyncSender`)"""
         receiver = self._get_receiver(sender.dst_port)
-        receiver._add_sender(
-            sender.src_addr,
-            sender.src_port,
-            sender.msg,
-            sender.count)
+        receiver._add_sender(sender.src_addr, sender.src_port, sender.msg,
+                             sender.count)
         return receiver
 
     def prepare_listener(self, local_port, timeout=1):
@@ -815,7 +829,8 @@
             while asyncore.socket_map:
                 elapsed_time = time.time() - start_time
                 if elapsed_time > timeout:
-                    print('Performing aysnc tx/tx took too long ({}>{} sec)'.format(elapsed_time, timeout))
+                    print('Performing aysnc tx/tx took too long ({}>{} sec)'.
+                          format(elapsed_time, timeout))
                     raise Node._NodeError(
                         'perform_tx_rx timed out ({}>{} sec)'.format(
                             elapsed_time, timeout))
@@ -825,10 +840,10 @@
             print('Failed to perform async rx/tx')
             raise
 
+
 # -----------------------------------------------------------------------------------------------------------------------
 # `AsyncSender` and `AsyncReceiver classes
 
-
 _SO_BINDTODEVICE = 25
 
 
@@ -847,16 +862,15 @@
 class AsyncSender(asyncore.dispatcher):
     """ An IPv6 async message sender - use `Node.prepare_tx()` to create one"""
 
-    def __init__(
-            self,
-            node,
-            src_addr,
-            src_port,
-            dst_addr,
-            dst_port,
-            msg,
-            count,
-            mcast_hops=None):
+    def __init__(self,
+                 node,
+                 src_addr,
+                 src_port,
+                 dst_addr,
+                 dst_port,
+                 msg,
+                 count,
+                 mcast_hops=None):
         self._node = node
         self._src_addr = src_addr
         self._src_port = src_port
@@ -870,18 +884,14 @@
 
         # Create a socket, bind it to the node's interface
         sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
-        sock.setsockopt(
-            socket.SOL_SOCKET,
-            _SO_BINDTODEVICE,
-            node.interface_name + '\0')
+        sock.setsockopt(socket.SOL_SOCKET, _SO_BINDTODEVICE,
+                        node.interface_name + '\0')
         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
 
         # Set the IPV6_MULTICAST_HOPS
         if mcast_hops is not None:
-            sock.setsockopt(
-                socket.IPPROTO_IPV6,
-                socket.IPV6_MULTICAST_HOPS,
-                mcast_hops)
+            sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS,
+                            mcast_hops)
 
         # Bind the socket to the given src address
         if _is_ipv6_addr_link_local(src_addr):
@@ -943,18 +953,13 @@
 
         if self._node._verbose:
             if sent_len < 30:
-                info_text = '{} bytes ("{}")'.format(
-                    sent_len, self._tx_buffer[:sent_len])
+                info_text = '{} bytes ("{}")'.format(sent_len,
+                                                     self._tx_buffer[:sent_len])
             else:
                 info_text = '{} bytes'.format(sent_len)
-            _log(
-                '- Node{} sent {} to [{}]:{} from [{}]:{}'.format(
-                    self._node._index,
-                    info_text,
-                    self._dst_addr,
-                    self._dst_port,
-                    self._src_addr,
-                    self._src_port))
+            _log('- Node{} sent {} to [{}]:{} from [{}]:{}'.format(
+                self._node._index, info_text, self._dst_addr, self._dst_port,
+                self._src_addr, self._src_port))
 
         self._tx_buffer = self._tx_buffer[sent_len:]
 
@@ -968,6 +973,7 @@
     def handle_close(self):
         self.close()
 
+
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 
@@ -977,6 +983,7 @@
     _MAX_RECV_SIZE = 2048
 
     class _SenderInfo(object):
+
         def __init__(self, sender_addr, sender_port, msg, count):
             self._sender_addr = sender_addr
             self._sender_port = sender_port
@@ -995,20 +1002,18 @@
     def __init__(self, node, local_port):
         self._node = node
         self._local_port = local_port
-        self._senders = []        # list of `_SenderInfo` objects
+        self._senders = []  # list of `_SenderInfo` objects
         # contains all received messages as a list of (pkt, (src_addr,
         # src_port))
         self._all_rx = []
-        self._timeout = 0         # listen timeout (zero means forever)
+        self._timeout = 0  # listen timeout (zero means forever)
         self._started = False
         self._start_time = 0
 
         # Create a socket, bind it to the node's interface
         sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
-        sock.setsockopt(
-            socket.SOL_SOCKET,
-            _SO_BINDTODEVICE,
-            node.interface_name + '\0')
+        sock.setsockopt(socket.SOL_SOCKET, _SO_BINDTODEVICE,
+                        node.interface_name + '\0')
         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
 
         # Bind the socket to any IPv6 address with the given local port
@@ -1019,8 +1024,7 @@
 
     def _add_sender(self, sender_addr, sender_port, msg, count):
         self._senders.append(
-            AsyncReceiver._SenderInfo(
-                sender_addr, sender_port, msg, count))
+            AsyncReceiver._SenderInfo(sender_addr, sender_port, msg, count))
 
     def _set_listen_timeout(self, timeout):
         self._timeout = timeout
@@ -1052,11 +1056,14 @@
         if not self._started:
             self._start_time = time.time()
             self._started = True
-        if self._timeout != 0 and time.time() - self._start_time >= self._timeout:
+        if self._timeout != 0 and time.time(
+        ) - self._start_time >= self._timeout:
             self.handle_close()
             if self._node._verbose:
-                _log('- Node{} finished listening on port {} for {} sec, received {} msg(s)'.format(
-                    self._node._index, self._local_port, self._timeout, len(self._all_rx)))
+                _log(
+                    '- Node{} finished listening on port {} for {} sec, received {} msg(s)'
+                    .format(self._node._index, self._local_port, self._timeout,
+                            len(self._all_rx)))
             return False
         return True
 
@@ -1078,18 +1085,16 @@
                 info_text = '{} bytes ("{}")'.format(len(msg), msg)
             else:
                 info_text = '{} bytes'.format(len(msg))
-            _log(
-                '- Node{} received {} on port {} from [{}]:{}'.format(
-                    self._node._index,
-                    info_text,
-                    self._local_port,
-                    src_addr,
-                    src_port))
+            _log('- Node{} received {} on port {} from [{}]:{}'.format(
+                self._node._index, info_text, self._local_port, src_addr,
+                src_port))
 
         self._all_rx.append((msg, (src_addr, src_port)))
 
-        if all([sender._check_received(msg, src_addr, src_port)
-                for sender in self._senders]):
+        if all([
+                sender._check_received(msg, src_addr, src_port)
+                for sender in self._senders
+        ]):
             self.handle_close()
 
     def handle_close(self):
@@ -1097,6 +1102,7 @@
         # remove the receiver from the node once the socket is closed
         self._node._remove_recver(self)
 
+
 # -----------------------------------------------------------------------------------------------------------------------
 
 
@@ -1133,7 +1139,8 @@
             condition_checker_func()
         except VerifyError as e:
             if time.time() - start_time > wait_time:
-                print('Took too long to pass the condition ({}>{} sec)'.format(time.time() - start_time, wait_time))
+                print('Took too long to pass the condition ({}>{} sec)'.format(
+                    time.time() - start_time, wait_time))
                 print(e.message)
                 raise e
         except BaseException:
@@ -1144,6 +1151,7 @@
             time.sleep(delay_time)
     _is_in_verify_within = old_is_in_verify_within
 
+
 # -----------------------------------------------------------------------------------------------------------------------
 # Parsing `wpanctl` output
 
@@ -1186,7 +1194,8 @@
             self._rssi = items[1]
         else:
             raise ValueError(
-                '"{}" does not seem to be a valid scan result string'.result_text)
+                '"{}" does not seem to be a valid scan result string'.
+                result_text)
 
     @property
     def type(self):
@@ -1226,8 +1235,8 @@
 
 def parse_scan_result(scan_result):
     """ Parses scan result string and returns an array of `ScanResult` objects"""
-    return [ScanResult(item) for item in scan_result.split(
-        '\n')[2:]]  # skip first two lines which are table headers
+    return [ScanResult(item) for item in scan_result.split('\n')[2:]
+           ]  # skip first two lines which are table headers
 
 
 def parse_list(list_string):
@@ -1249,6 +1258,7 @@
     #
     return [line[2:-1].split()[0] for line in list_string.split('\n')[1:-1]]
 
+
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 
@@ -1264,9 +1274,9 @@
 
         m = re.match(
             r'\t"([0-9a-fA-F:]+)\s*prefix_len:(\d+)\s+origin:(\w*)\s+stable:(\w*).* \['
-            + r'on-mesh:(\d)\s+def-route:(\d)\s+config:(\d)\s+dhcp:(\d)\s+slaac:(\d)\s+pref:(\d)\s+prio:(\w*)\]'
-            + r'\s+rloc:(0x[0-9a-fA-F]+)',
-            text)
+            +
+            r'on-mesh:(\d)\s+def-route:(\d)\s+config:(\d)\s+dhcp:(\d)\s+slaac:(\d)\s+pref:(\d)\s+prio:(\w*)\]'
+            + r'\s+rloc:(0x[0-9a-fA-F]+)', text)
         verify(m is not None)
         data = m.groups()
 
@@ -1329,8 +1339,10 @@
 
 def parse_on_mesh_prefix_result(on_mesh_prefix_list):
     """ Parses on-mesh prefix list string and returns an array of `OnMeshPrefix` objects"""
-    return [OnMeshPrefix(item)
-            for item in on_mesh_prefix_list.split('\n')[1:-1]]
+    return [
+        OnMeshPrefix(item) for item in on_mesh_prefix_list.split('\n')[1:-1]
+    ]
+
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
@@ -1399,6 +1411,7 @@
     """ Parses child table list string and returns an array of `ChildEntry` objects"""
     return [ChildEntry(item) for item in child_table_list.split('\n')[1:-1]]
 
+
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 
@@ -1455,8 +1468,10 @@
 
 def parse_neighbor_table_result(neighbor_table_list):
     """ Parses neighbor table list string and returns an array of `NeighborEntry` objects"""
-    return [NeighborEntry(item)
-            for item in neighbor_table_list.split('\n')[1:-1]]
+    return [
+        NeighborEntry(item) for item in neighbor_table_list.split('\n')[1:-1]
+    ]
+
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
@@ -1521,8 +1536,10 @@
 
 def parse_router_table_result(router_table_list):
     """ Parses router table list string and returns an array of `RouterTableEntry` objects"""
-    return [RouterTableEntry(item)
-            for item in router_table_list.split('\n')[1:-1]]
+    return [
+        RouterTableEntry(item) for item in router_table_list.split('\n')[1:-1]
+    ]
+
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
@@ -1534,8 +1551,8 @@
 
         # Example of expected text:
         #
-        # '\t"fd00:1234::d427:a1d9:6204:dbae -> 0x9c00, age:0"'
-        #
+        # '\t"fd00:1234::100:8 -> 0xfffe, Age:1, State:query, CanEvict:no, Timeout:3, RetryDelay:15"`
+        # '\t"fd00:1234::3:2 -> 0x2000, Age:0, State:cached, LastTrans:0, ML-EID:fd40:ea58:a88c:0:b7ab:4919:aa7b:11a3"`
 
         # We get rid of the first two chars `\t"' and last char '"', split the rest using whitespace as separator.
         # Then remove any ',' at end of items in the list.
@@ -1552,7 +1569,16 @@
         # separator
         dict = {item.split(':')[0]: item.split(':')[1] for item in items[3:]}
 
-        self._age = int(dict['age'], 0)
+        self._age = int(dict['Age'], 0)
+
+        self._state = dict['State']
+
+        if self._state == ADDRESS_CACHE_ENTRY_STATE_CACHED:
+            self._last_trans = int(dict.get("LastTrans", "-1"), 0)
+        else:
+            self._can_evict = (dict['CanEvict'] == 'yes')
+            self._timeout = int(dict['Timeout'])
+            self._retry_delay = int(dict['RetryDelay'])
 
     @property
     def address(self):
@@ -1566,14 +1592,36 @@
     def age(self):
         return self._age
 
+    @property
+    def state(self):
+        return self._state
+
+    def can_evict(self):
+        return self._can_evict
+
+    @property
+    def timeout(self):
+        return self._timeout
+
+    @property
+    def retry_delay(self):
+        return self._retry_delay
+
+    @property
+    def last_trans(self):
+        return self._last_trans
+
     def __repr__(self):
         return 'AddressCacheEntry({})'.format(self.__dict__)
 
 
 def parse_address_cache_table_result(addr_cache_table_list):
     """ Parses address cache table list string and returns an array of `AddressCacheEntry` objects"""
-    return [AddressCacheEntry(item)
-            for item in addr_cache_table_list.split('\n')[1:-1]]
+    return [
+        AddressCacheEntry(item)
+        for item in addr_cache_table_list.split('\n')[1:-1]
+    ]
+
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
@@ -1618,5 +1666,6 @@
 
 def parse_interface_routes_result(interface_routes_list):
     """ Parses interface routes list string and returns an array of `InterfaceRoute` objects"""
-    return [InterfaceRoute(item)
-            for item in interface_routes_list.split('\n')[1:-1]]
+    return [
+        InterfaceRoute(item) for item in interface_routes_list.split('\n')[1:-1]
+    ]
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
new file mode 100644
index 0000000..d10f0ae
--- /dev/null
+++ b/tests/unit/CMakeLists.txt
@@ -0,0 +1,521 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+set(COMMON_SOURCES
+    test_platform.cpp
+    test_util.cpp
+)
+
+set(COMMON_LIBS
+    openthread-ftd
+    openthread-ncp-ftd
+    ot-config
+    ${OT_MBEDTLS}
+    util
+)
+
+set(COMMON_INCLUDES
+    ${PROJECT_SOURCE_DIR}/include
+    ${PROJECT_SOURCE_DIR}/src
+    ${PROJECT_SOURCE_DIR}/src/core
+    ${PROJECT_SOURCE_DIR}/examples/platforms/simulation
+)
+
+set(COMMON_COMPILE_OPTIONS
+    -DOPENTHREAD_FTD=1
+    -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1
+)
+
+add_executable(test-aes
+    ${COMMON_SOURCES}
+    test_aes.cpp
+)
+
+target_include_directories(test-aes
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-aes
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-aes
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-aes COMMAND test-aes)
+
+add_executable(test-child
+    ${COMMON_SOURCES}
+    test_child.cpp
+)
+
+target_include_directories(test-child
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-child
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-child
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-child COMMAND test-child)
+
+add_executable(test-child-table
+    ${COMMON_SOURCES}
+    test_child_table.cpp
+)
+
+target_include_directories(test-child-table
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-child-table
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-child-table
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-child-table COMMAND test-child-table)
+
+add_executable(test-flash
+    ${COMMON_SOURCES}
+    test_flash.cpp
+)
+
+target_include_directories(test-flash
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-flash
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-flash
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-flash COMMAND test-flash)
+
+add_executable(test-heap
+    ${COMMON_SOURCES}
+    test_heap.cpp
+)
+
+target_include_directories(test-heap
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-heap
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-heap
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-heap COMMAND test-heap)
+
+add_executable(test-hmac-sha256
+    ${COMMON_SOURCES}
+    test_hmac_sha256.cpp
+)
+
+target_include_directories(test-hmac-sha256
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-hmac-sha256
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-hmac-sha256
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-hmac-sha256 COMMAND test-hmac-sha256)
+
+add_executable(test-ip6-address
+    ${COMMON_SOURCES}
+    test_ip6_address.cpp
+)
+
+target_include_directories(test-ip6-address
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-ip6-address
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-ip6-address
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-ip6-address COMMAND test-ip6-address)
+
+add_executable(test-link-quality
+    ${COMMON_SOURCES}
+    test_link_quality.cpp
+)
+
+target_include_directories(test-link-quality
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-link-quality
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-link-quality
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-link-quality COMMAND test-link-quality)
+
+add_executable(test-linked-list
+    ${COMMON_SOURCES}
+    test_linked_list.cpp
+)
+
+target_include_directories(test-linked-list
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-linked-list
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-linked-list
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-linked-list COMMAND test-linked-list)
+
+add_executable(test-lowpan
+    ${COMMON_SOURCES}
+    test_lowpan.cpp
+)
+
+target_include_directories(test-lowpan
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-lowpan
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-lowpan
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-lowpan COMMAND test-lowpan)
+
+add_executable(test-mac-frame
+    ${COMMON_SOURCES}
+    test_mac_frame.cpp
+)
+
+target_include_directories(test-mac-frame
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-mac-frame
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-mac-frame
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-mac-frame COMMAND test-mac-frame)
+
+add_executable(test-message
+    ${COMMON_SOURCES}
+    test_message.cpp
+)
+
+target_include_directories(test-message
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-message
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-message
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-message COMMAND test-message)
+
+add_executable(test-message-queue
+    ${COMMON_SOURCES}
+    test_message_queue.cpp
+)
+
+target_include_directories(test-message-queue
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-message-queue
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-message-queue
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-message-queue COMMAND test-message-queue)
+
+add_executable(test-netif
+    ${COMMON_SOURCES}
+    test_netif.cpp
+)
+
+target_include_directories(test-netif
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-netif
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-netif
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-netif COMMAND test-netif)
+
+add_executable(test-network-data
+    ${COMMON_SOURCES}
+    test_network_data.cpp
+)
+
+target_include_directories(test-network-data
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-network-data
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-network-data
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-network-data COMMAND test-network-data)
+
+add_executable(test-pool
+    ${COMMON_SOURCES}
+    test_pool.cpp
+)
+
+target_include_directories(test-pool
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-pool
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-pool
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-pool COMMAND test-pool)
+
+add_executable(test-priority-queue
+    ${COMMON_SOURCES}
+    test_priority_queue.cpp
+)
+
+target_include_directories(test-priority-queue
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-priority-queue
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-priority-queue
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-priority-queue COMMAND test-priority-queue)
+
+add_executable(test-pskc
+    ${COMMON_SOURCES}
+    test_pskc.cpp
+)
+
+target_include_directories(test-pskc
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-pskc
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-pskc
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-pskc COMMAND test-pskc)
+
+add_executable(test-steering-data
+    ${COMMON_SOURCES}
+    test_steering_data.cpp
+)
+
+target_include_directories(test-steering-data
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-steering-data
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-steering-data
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-steering-data COMMAND test-steering-data)
+
+add_executable(test-string
+    ${COMMON_SOURCES}
+    test_string.cpp
+)
+
+target_include_directories(test-string
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-string
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-string
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-string COMMAND test-string)
+
+add_executable(test-timer
+    ${COMMON_SOURCES}
+    test_timer.cpp
+)
+
+target_include_directories(test-timer
+    PRIVATE
+        ${COMMON_INCLUDES}
+)
+
+target_compile_options(test-timer
+    PRIVATE
+        ${COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(test-timer
+    PRIVATE
+        ${COMMON_LIBS}
+)
+
+add_test(NAME test-timer COMMAND test-timer)
+
+set_target_properties(
+    test-aes test-child test-child-table test-flash test-heap test-hmac-sha256 test-ip6-address test-link-quality test-linked-list test-lowpan test-mac-frame test-message test-message-queue test-netif test-network-data test-pool test-priority-queue test-pskc test-steering-data test-string test-timer
+    PROPERTIES
+        C_STANDARD 99
+        CXX_STANDARD 11
+)
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 2e18605..7aac4bf 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -53,20 +53,21 @@
     -DOPENTHREAD_FTD=1                                                \
     -DOPENTHREAD_MTD=0                                                \
     -DOPENTHREAD_RADIO=0                                              \
+    -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1            \
     -I$(top_srcdir)/include                                           \
     -I$(top_srcdir)/src                                               \
     -I$(top_srcdir)/src/core                                          \
     $(NULL)
 
-if OPENTHREAD_EXAMPLES_POSIX
+if OPENTHREAD_EXAMPLES_SIMULATION
 AM_CPPFLAGS                                                        += \
     -I$(top_srcdir)/examples/platforms                                \
     $(NULL)
 endif
 
-if OPENTHREAD_PLATFORM_POSIX_APP
+if OPENTHREAD_PLATFORM_POSIX
 AM_CPPFLAGS                                                        += \
-    -DOPENTHREAD_PLATFORM_POSIX_APP=1                                 \
+    -DOPENTHREAD_PLATFORM_POSIX=1                                     \
     -I$(top_srcdir)/src/posix/platform                                \
     $(NULL)
 endif
@@ -91,7 +92,7 @@
     $(NULL)
 endif
 
-if OPENTHREAD_PLATFORM_POSIX_APP
+if OPENTHREAD_PLATFORM_POSIX
 COMMON_LDADD                                                       += \
     -lutil
     $(NULL)
@@ -108,6 +109,7 @@
     test-aes                                                          \
     test-child                                                        \
     test-child-table                                                  \
+    test-flash                                                        \
     test-heap                                                         \
     test-hmac-sha256                                                  \
     test-ip6-address                                                  \
@@ -119,8 +121,10 @@
     test-message-queue                                                \
     test-netif                                                        \
     test-network-data                                                 \
+    test-pool                                                         \
     test-priority-queue                                               \
     test-pskc                                                         \
+    test-steering-data                                                \
     test-string                                                       \
     test-timer                                                        \
     $(NULL)
@@ -128,7 +132,7 @@
 if OPENTHREAD_ENABLE_NCP
 check_PROGRAMS                                                     += \
     test-hdlc                                                         \
-    test-ncp-buffer                                                   \
+    test-spinel-buffer                                                \
     test-spinel-decoder                                               \
     test-spinel-encoder                                               \
     $(NULL)
@@ -172,6 +176,9 @@
 test_child_table_LDADD       = $(COMMON_LDADD)
 test_child_table_SOURCES     = $(COMMON_SOURCES) test_child_table.cpp
 
+test_flash_LDADD             = $(COMMON_LDADD)
+test_flash_SOURCES           = $(COMMON_SOURCES) test_flash.cpp
+
 test_hdlc_LDADD              = $(COMMON_LDADD)
 test_hdlc_SOURCES            = $(COMMON_SOURCES) test_hdlc.cpp
 
@@ -202,8 +209,8 @@
 test_message_queue_LDADD     = $(COMMON_LDADD)
 test_message_queue_SOURCES   = $(COMMON_SOURCES) test_message_queue.cpp
 
-test_ncp_buffer_LDADD        = $(COMMON_LDADD)
-test_ncp_buffer_SOURCES      = $(COMMON_SOURCES) test_ncp_buffer.cpp
+test_spinel_buffer_LDADD        = $(COMMON_LDADD)
+test_spinel_buffer_SOURCES      = $(COMMON_SOURCES) test_spinel_buffer.cpp
 
 test_netif_LDADD             = $(COMMON_LDADD)
 test_netif_SOURCES           = $(COMMON_SOURCES) test_netif.cpp
@@ -211,12 +218,18 @@
 test_network_data_LDADD      = $(COMMON_LDADD)
 test_network_data_SOURCES    = $(COMMON_SOURCES) test_network_data.cpp
 
+test_pool_LDADD              = $(COMMON_LDADD)
+test_pool_SOURCES            = $(COMMON_SOURCES) test_pool.cpp
+
 test_priority_queue_LDADD    = $(COMMON_LDADD)
 test_priority_queue_SOURCES  = $(COMMON_SOURCES) test_priority_queue.cpp
 
 test_pskc_LDADD              = $(COMMON_LDADD)
 test_pskc_SOURCES            = $(COMMON_SOURCES) test_pskc.cpp
 
+test_steering_data_LDADD     = $(COMMON_LDADD)
+test_steering_data_SOURCES   = $(COMMON_SOURCES) test_steering_data.cpp
+
 test_string_LDADD            = $(COMMON_LDADD)
 test_string_SOURCES          = $(COMMON_SOURCES) test_string.cpp
 
@@ -232,33 +245,6 @@
 test_toolchain_LDADD         = $(NULL)
 test_toolchain_SOURCES       = test_toolchain.cpp test_toolchain_c.c
 
-PRETTY_FILES                                                        = \
-    $(noinst_HEADERS)                                                 \
-    $(test_address_sanitizer_SOURCES)                                 \
-    $(test_aes_SOURCES)                                               \
-    $(test_child_SOURCES)                                             \
-    $(test_child_table_SOURCES)                                       \
-    $(test_hdlc_SOURCES)                                              \
-    $(test_heap_SOURCES)                                              \
-    $(test_hmac_sha256_SOURCES)                                       \
-    $(test_link_quality_SOURCES)                                      \
-    $(test_linked_list_SOURCES)                                       \
-    $(test_lowpan_SOURCES)                                            \
-    $(test_mac_frame_SOURCES)                                         \
-    $(test_message_queue_SOURCES)                                     \
-    $(test_message_SOURCES)                                           \
-    $(test_ncp_buffer_SOURCES)                                        \
-    $(test_netif_SOURCES)                                             \
-    $(test_network_data_SOURCES)                                      \
-    $(test_priority_queue_SOURCES)                                    \
-    $(test_pskc_SOURCES)                                              \
-    $(test_spinel_decoder_SOURCES)                                    \
-    $(test_spinel_encoder_SOURCES)                                    \
-    $(test_string_SOURCES)                                            \
-    $(test_timer_SOURCES)                                             \
-    $(test_toolchain_SOURCES)                                         \
-    $(NULL)
-
 if OPENTHREAD_BUILD_COVERAGE
 CLEANFILES                   = $(wildcard *.gcda *.gcno)
 endif # OPENTHREAD_BUILD_COVERAGE
diff --git a/tests/unit/test_aes.cpp b/tests/unit/test_aes.cpp
index b8027af..362c96b 100644
--- a/tests/unit/test_aes.cpp
+++ b/tests/unit/test_aes.cpp
@@ -65,18 +65,20 @@
         0xAC, 0xDE, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x02,
     };
 
-    VerifyOrQuit(instance != NULL, "Null OpenThread instance");
+    VerifyOrQuit(instance != nullptr, "Null OpenThread instance");
 
     aesCcm.SetKey(key, sizeof(key));
     aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
     aesCcm.Header(test, headerLength);
-    aesCcm.Finalize(test + headerLength, &tagLength);
+    VerifyOrQuit(aesCcm.GetTagLength() == tagLength, "AesCcm::GetTagLength() failed");
+    aesCcm.Finalize(test + headerLength);
 
     VerifyOrQuit(memcmp(test, encrypted, sizeof(encrypted)) == 0, "TestMacBeaconFrame encrypt failed");
 
     aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
     aesCcm.Header(test, headerLength);
-    aesCcm.Finalize(test + headerLength, &tagLength);
+    VerifyOrQuit(aesCcm.GetTagLength() == tagLength, "AesCcm::GetTagLength() failed");
+    aesCcm.Finalize(test + headerLength);
 
     VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0, "TestMacBeaconFrame decrypt failed");
 
@@ -121,16 +123,18 @@
     aesCcm.SetKey(key, sizeof(key));
     aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
     aesCcm.Header(test, headerLength);
-    aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, true);
-    aesCcm.Finalize(test + headerLength + payloadLength, &tagLength);
-    VerifyOrQuit(memcmp(test, encrypted, sizeof(encrypted)) == 0, "TestMacCommandFrame encrypt failed\n");
+    aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, ot::Crypto::AesCcm::kEncrypt);
+    VerifyOrQuit(aesCcm.GetTagLength() == tagLength, "AesCcm::GetTagLength() failed");
+    aesCcm.Finalize(test + headerLength + payloadLength);
+    VerifyOrQuit(memcmp(test, encrypted, sizeof(encrypted)) == 0, "TestMacCommandFrame encrypt failed");
 
     aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
     aesCcm.Header(test, headerLength);
-    aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, false);
-    aesCcm.Finalize(test + headerLength + payloadLength, &tagLength);
+    aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, ot::Crypto::AesCcm::kDecrypt);
+    VerifyOrQuit(aesCcm.GetTagLength() == tagLength, "AesCcm::GetTagLength() failed");
+    aesCcm.Finalize(test + headerLength + payloadLength);
 
-    VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0, "TestMacCommandFrame decrypt failed\n");
+    VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0, "TestMacCommandFrame decrypt failed");
 }
 
 int main(void)
diff --git a/tests/unit/test_child.cpp b/tests/unit/test_child.cpp
index 06ac801..3a14a3c 100644
--- a/tests/unit/test_child.cpp
+++ b/tests/unit/test_child.cpp
@@ -54,7 +54,7 @@
 
     for (uint8_t index = 0; index < aAddressListLength; index++)
     {
-        VerifyOrQuit(aChild.HasIp6Address(*sInstance, aAddressList[index]), "HasIp6Address() failed");
+        VerifyOrQuit(aChild.HasIp6Address(aAddressList[index]), "HasIp6Address() failed");
     }
 
     memset(addressObserved, 0, sizeof(addressObserved));
@@ -67,7 +67,7 @@
         }
     }
 
-    while (aChild.GetNextIp6Address(*sInstance, iterator, address) == OT_ERROR_NONE)
+    while (aChild.GetNextIp6Address(iterator, address) == OT_ERROR_NONE)
     {
         bool addressIsInList = false;
 
@@ -90,8 +90,7 @@
 
         if (sInstance->Get<Mle::MleRouter>().IsMeshLocalAddress(aAddressList[index]))
         {
-            SuccessOrQuit(aChild.GetMeshLocalIp6Address(*sInstance, address),
-                          "Child::GetMeshLocalIp6Address() failed\n");
+            SuccessOrQuit(aChild.GetMeshLocalIp6Address(address), "Child::GetMeshLocalIp6Address() failed\n");
             VerifyOrQuit(address == aAddressList[index], "GetMeshLocalIp6Address() did not return expected address");
             hasMeshLocal = true;
         }
@@ -99,7 +98,7 @@
 
     if (!hasMeshLocal)
     {
-        VerifyOrQuit(aChild.GetMeshLocalIp6Address(*sInstance, address) == OT_ERROR_NOT_FOUND,
+        VerifyOrQuit(aChild.GetMeshLocalIp6Address(address) == OT_ERROR_NOT_FOUND,
                      "Child::GetMeshLocalIp6Address() returned an address not in the expected list");
     }
 }
@@ -115,10 +114,15 @@
         "fd00:1234::204c:3d7c:98f6:9a1b",
     };
 
-    const uint8_t meshLocalIid[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
+    const uint8_t            meshLocalIidArray[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
+    Ip6::InterfaceIdentifier meshLocalIid;
+
+    meshLocalIid.SetBytes(meshLocalIidArray);
 
     sInstance = testInitInstance();
-    VerifyOrQuit(sInstance != NULL, "Null instance");
+    VerifyOrQuit(sInstance != nullptr, "Null instance");
+
+    child.Init(*sInstance);
 
     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
@@ -144,7 +148,7 @@
     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     printf("Child state after init");
     child.Clear();
-    VerifyChildIp6Addresses(child, 0, NULL);
+    VerifyChildIp6Addresses(child, 0, nullptr);
     printf(" -- PASS\n");
 
     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -152,11 +156,11 @@
 
     for (uint8_t index = 0; index < numAddresses; index++)
     {
-        SuccessOrQuit(child.AddIp6Address(*sInstance, addresses[index]), "AddIp6Address() failed");
+        SuccessOrQuit(child.AddIp6Address(addresses[index]), "AddIp6Address() failed");
         VerifyChildIp6Addresses(child, 1, &addresses[index]);
 
         child.ClearIp6Addresses();
-        VerifyChildIp6Addresses(child, 0, NULL);
+        VerifyChildIp6Addresses(child, 0, nullptr);
     }
 
     printf(" -- PASS\n");
@@ -166,7 +170,7 @@
 
     for (uint8_t index = 0; index < numAddresses; index++)
     {
-        SuccessOrQuit(child.AddIp6Address(*sInstance, addresses[index]), "AddIp6Address() failed");
+        SuccessOrQuit(child.AddIp6Address(addresses[index]), "AddIp6Address() failed");
         VerifyChildIp6Addresses(child, index + 1, addresses);
     }
 
@@ -177,7 +181,7 @@
 
     for (uint8_t index = 0; index < numAddresses; index++)
     {
-        VerifyOrQuit(child.AddIp6Address(*sInstance, addresses[index]) == OT_ERROR_ALREADY,
+        VerifyOrQuit(child.AddIp6Address(addresses[index]) == OT_ERROR_ALREADY,
                      "AddIp6Address() did not fail when adding same address");
         VerifyChildIp6Addresses(child, numAddresses, addresses);
     }
@@ -189,14 +193,14 @@
 
     for (uint8_t index = 0; index < numAddresses; index++)
     {
-        SuccessOrQuit(child.RemoveIp6Address(*sInstance, addresses[index]), "RemoveIp6Address() failed");
+        SuccessOrQuit(child.RemoveIp6Address(addresses[index]), "RemoveIp6Address() failed");
         VerifyChildIp6Addresses(child, numAddresses - 1 - index, &addresses[index + 1]);
 
-        VerifyOrQuit(child.RemoveIp6Address(*sInstance, addresses[index]) == OT_ERROR_NOT_FOUND,
+        VerifyOrQuit(child.RemoveIp6Address(addresses[index]) == OT_ERROR_NOT_FOUND,
                      "RemoveIp6Address() did not fail when removing an address not on the list");
     }
 
-    VerifyChildIp6Addresses(child, 0, NULL);
+    VerifyChildIp6Addresses(child, 0, nullptr);
     printf(" -- PASS\n");
 
     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -204,15 +208,15 @@
 
     for (uint8_t index = 0; index < numAddresses; index++)
     {
-        SuccessOrQuit(child.AddIp6Address(*sInstance, addresses[index]), "AddIp6Address() failed");
+        SuccessOrQuit(child.AddIp6Address(addresses[index]), "AddIp6Address() failed");
     }
 
     for (uint8_t index = numAddresses - 1; index > 0; index--)
     {
-        SuccessOrQuit(child.RemoveIp6Address(*sInstance, addresses[index]), "RemoveIp6Address() failed");
+        SuccessOrQuit(child.RemoveIp6Address(addresses[index]), "RemoveIp6Address() failed");
         VerifyChildIp6Addresses(child, index, &addresses[0]);
 
-        VerifyOrQuit(child.RemoveIp6Address(*sInstance, addresses[index]) == OT_ERROR_NOT_FOUND,
+        VerifyOrQuit(child.RemoveIp6Address(addresses[index]) == OT_ERROR_NOT_FOUND,
                      "RemoveIp6Address() did not fail when removing an address not on the list");
     }
 
@@ -227,12 +231,12 @@
 
         for (uint8_t index = 0; index < numAddresses; index++)
         {
-            SuccessOrQuit(child.AddIp6Address(*sInstance, addresses[index]), "AddIp6Address() failed");
+            SuccessOrQuit(child.AddIp6Address(addresses[index]), "AddIp6Address() failed");
         }
 
-        SuccessOrQuit(child.RemoveIp6Address(*sInstance, addresses[indexToRemove]), "RemoveIp6Address() failed");
+        SuccessOrQuit(child.RemoveIp6Address(addresses[indexToRemove]), "RemoveIp6Address() failed");
 
-        VerifyOrQuit(child.RemoveIp6Address(*sInstance, addresses[indexToRemove]) == OT_ERROR_NOT_FOUND,
+        VerifyOrQuit(child.RemoveIp6Address(addresses[indexToRemove]) == OT_ERROR_NOT_FOUND,
                      "RemoveIp6Address() did not fail when removing an address not on the list");
 
         {
diff --git a/tests/unit/test_child_table.cpp b/tests/unit/test_child_table.cpp
index 056362f..ea658e4 100644
--- a/tests/unit/test_child_table.cpp
+++ b/tests/unit/test_child_table.cpp
@@ -126,115 +126,103 @@
             }
 
             child = aTable.FindChild(aChildList[listIndex].mRloc16, filter);
-            VerifyOrQuit(child != NULL, "FindChild(rloc) failed");
+            VerifyOrQuit(child != nullptr, "FindChild(rloc) failed");
             VerifyOrQuit(ChildMatches(*child, aChildList[listIndex]), "FindChild(rloc) returned incorrect child");
 
             child = aTable.FindChild(static_cast<const Mac::ExtAddress &>(aChildList[listIndex].mExtAddress), filter);
-            VerifyOrQuit(child != NULL, "FindChild(ExtAddress) failed");
+            VerifyOrQuit(child != nullptr, "FindChild(ExtAddress) failed");
             VerifyOrQuit(ChildMatches(*child, aChildList[listIndex]), "FindChild(ExtAddress) returned incorrect child");
 
             address.SetShort(aChildList[listIndex].mRloc16);
             child = aTable.FindChild(address, filter);
-            VerifyOrQuit(child != NULL, "FindChild(address) failed");
+            VerifyOrQuit(child != nullptr, "FindChild(address) failed");
             VerifyOrQuit(ChildMatches(*child, aChildList[listIndex]), "FindChild(address) returned incorrect child");
 
             address.SetExtended(static_cast<const Mac::ExtAddress &>(aChildList[listIndex].mExtAddress));
             child = aTable.FindChild(address, filter);
-            VerifyOrQuit(child != NULL, "FindChild(address) failed");
+            VerifyOrQuit(child != nullptr, "FindChild(address) failed");
             VerifyOrQuit(ChildMatches(*child, aChildList[listIndex]), "FindChild(address) returned incorrect child");
         }
 
-        // Verify `ChildTable::Iterator` behavior when starting from different child entries.
+        // Verify `ChildTable::Iterator` behavior.
 
-        for (uint16_t listIndex = 0; listIndex <= aChildListLength; listIndex++)
         {
-            Child *startingChild = NULL;
+            ChildTable::Iterator iter(*sInstance, filter);
+            bool                 childObserved[kMaxChildren];
+            uint16_t             numChildren = 0;
 
-            if (listIndex < aChildListLength)
+            memset(childObserved, 0, sizeof(childObserved));
+
+            // Use the iterator and verify that each returned `Child` entry is in the expected list.
+
+            for (; !iter.IsDone(); iter++)
             {
-                startingChild = aTable.FindChild(aChildList[listIndex].mRloc16, Child::kInStateAnyExceptInvalid);
-                VerifyOrQuit(startingChild != NULL, "FindChild() failed");
-            }
+                Child *  child    = iter.GetChild();
+                Child &  childRef = *iter;
+                bool     didFind  = false;
+                uint16_t childIndex;
 
-            // Test an iterator starting from `startingChild`.
+                VerifyOrQuit(child != nullptr, "iter.GetChild() failed");
+                VerifyOrQuit(&childRef == child, "iter.operator*() failed");
+                VerifyOrQuit(iter->GetRloc16() == child->GetRloc16(), "iter.operator->() failed");
 
-            {
-                ChildTable::Iterator iter(*sInstance, filter, startingChild);
-                bool                 childObserved[kMaxChildren];
-                uint16_t             numChildren = 0;
-
-                memset(childObserved, 0, sizeof(childObserved));
-
-                // Check if the first entry matches the `startingChild`
-
-                if ((startingChild != NULL) && StateMatchesFilter(startingChild->GetState(), filter))
-                {
-                    VerifyOrQuit(!iter.IsDone(), "iterator IsDone() failed");
-                    VerifyOrQuit(iter.GetChild() != NULL, "iterator GetChild() failed");
-                    VerifyOrQuit(iter.GetChild() == startingChild,
-                                 "Iterator failed to start from the given child entry");
-
-                    iter++;
-                    iter.Reset();
-                    VerifyOrQuit(iter.GetChild() == startingChild, "iterator Reset() failed");
-                }
-
-                // Use the iterator and verify that each returned `Child` entry is in the expected list.
-
-                for (; !iter.IsDone(); iter++)
-                {
-                    Child *  child   = iter.GetChild();
-                    bool     didFind = false;
-                    uint16_t childIndex;
-
-                    VerifyOrQuit(child != NULL, "iter.GetChild() failed");
-
-                    childIndex = aTable.GetChildIndex(*child);
-                    VerifyOrQuit(childIndex < aTable.GetMaxChildrenAllowed(), "Child Index is out of bound");
-                    VerifyOrQuit(aTable.GetChildAtIndex(childIndex) == child, "GetChildAtIndex() failed");
-
-                    for (uint16_t index = 0; index < aChildListLength; index++)
-                    {
-                        if (ChildMatches(*iter.GetChild(), aChildList[index]))
-                        {
-                            childObserved[index] = true;
-                            numChildren++;
-                            didFind = true;
-                            break;
-                        }
-                    }
-
-                    VerifyOrQuit(didFind, "ChildTable::Iterator returned an entry not in the expected list");
-                }
-
-                // Verify that when iterator is done, it points to `NULL`.
-
-                VerifyOrQuit(iter.GetChild() == NULL, "iterator GetChild() failed");
-
-                iter++;
-                VerifyOrQuit(iter.IsDone(), "iterator Advance() (after iterator is done) failed");
-                VerifyOrQuit(iter.GetChild() == NULL, "iterator GetChild() failed");
-
-                // Verify that the number of children matches the number of entries we get from iterator.
-
-                VerifyOrQuit(aTable.GetNumChildren(filter) == numChildren, "GetNumChildren() failed");
-                VerifyOrQuit(aTable.HasChildren(filter) == (numChildren != 0), "HasChildren() failed");
-
-                // Verify that there is no missing or extra entry between the expected list
-                // and what was observed/returned by the iterator.
+                childIndex = aTable.GetChildIndex(*child);
+                VerifyOrQuit(childIndex < aTable.GetMaxChildrenAllowed(), "Child Index is out of bound");
+                VerifyOrQuit(aTable.GetChildAtIndex(childIndex) == child, "GetChildAtIndex() failed");
 
                 for (uint16_t index = 0; index < aChildListLength; index++)
                 {
-                    if (StateMatchesFilter(aChildList[index].mState, filter))
+                    if (ChildMatches(*iter.GetChild(), aChildList[index]))
                     {
-                        VerifyOrQuit(childObserved[index], "iterator failed to return an expected entry");
-                    }
-                    else
-                    {
-                        VerifyOrQuit(!childObserved[index], "iterator returned an extra unexpected entry");
+                        childObserved[index] = true;
+                        numChildren++;
+                        didFind = true;
+                        break;
                     }
                 }
+
+                VerifyOrQuit(didFind, "ChildTable::Iterator returned an entry not in the expected list");
             }
+
+            // Verify that when iterator is done, it points to `nullptr`.
+
+            VerifyOrQuit(iter.GetChild() == nullptr, "iterator GetChild() failed");
+
+            iter++;
+            VerifyOrQuit(iter.IsDone(), "iterator Advance() (after iterator is done) failed");
+            VerifyOrQuit(iter.GetChild() == nullptr, "iterator GetChild() failed");
+
+            // Verify that the number of children matches the number of entries we get from iterator.
+
+            VerifyOrQuit(aTable.GetNumChildren(filter) == numChildren, "GetNumChildren() failed");
+            VerifyOrQuit(aTable.HasChildren(filter) == (numChildren != 0), "HasChildren() failed");
+
+            // Verify that there is no missing or extra entry between the expected list
+            // and what was observed/returned by the iterator.
+
+            for (uint16_t index = 0; index < aChildListLength; index++)
+            {
+                if (StateMatchesFilter(aChildList[index].mState, filter))
+                {
+                    VerifyOrQuit(childObserved[index], "iterator failed to return an expected entry");
+                }
+                else
+                {
+                    VerifyOrQuit(!childObserved[index], "iterator returned an extra unexpected entry");
+                }
+            }
+
+            // Verify the behavior of range-based `for` iteration.
+
+            iter.Reset();
+
+            for (Child &child : aTable.Iterate(filter))
+            {
+                VerifyOrQuit(&child == iter.GetChild(), "range-based for loop Iterate() failed");
+                iter++;
+            }
+
+            VerifyOrQuit(iter.IsDone(), "range-based for loop Iterate() did not return all entries");
         }
     }
 
@@ -304,7 +292,7 @@
     otError     error;
 
     sInstance = testInitInstance();
-    VerifyOrQuit(sInstance != NULL, "Null instance");
+    VerifyOrQuit(sInstance != nullptr, "Null instance");
 
     table = &sInstance->Get<ChildTable>();
 
@@ -337,7 +325,7 @@
         Child *child;
 
         child = table->GetNewChild();
-        VerifyOrQuit(child != NULL, "GetNewChild() failed");
+        VerifyOrQuit(child != nullptr, "GetNewChild() failed");
 
         child->SetState(testChildList[i].mState);
         child->SetRloc16(testChildList[i].mRloc16);
@@ -359,7 +347,7 @@
         Child *child;
 
         child = table->GetNewChild();
-        VerifyOrQuit(child != NULL, "GetNewChild() failed");
+        VerifyOrQuit(child != nullptr, "GetNewChild() failed");
 
         child->SetState(testChildList[i - 1].mState);
         child->SetRloc16(testChildList[i - 1].mRloc16);
@@ -389,11 +377,11 @@
     {
         Child *child = table->GetNewChild();
 
-        VerifyOrQuit(child != NULL, "GetNewChild() failed");
+        VerifyOrQuit(child != nullptr, "GetNewChild() failed");
         child->SetState(Child::kStateValid);
     }
 
-    VerifyOrQuit(table->GetNewChild() == NULL, "GetNewChild() did not fail when table was full");
+    VerifyOrQuit(table->GetNewChild() == nullptr, "GetNewChild() did not fail when table was full");
 
     printf(" -- PASS\n");
 
diff --git a/tests/unit/test_flash.cpp b/tests/unit/test_flash.cpp
new file mode 100644
index 0000000..4710a30
--- /dev/null
+++ b/tests/unit/test_flash.cpp
@@ -0,0 +1,196 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <openthread/platform/flash.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "utils/flash.hpp"
+
+#include "test_platform.h"
+#include "test_util.h"
+
+namespace ot {
+
+void TestFlash(void)
+{
+#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+    uint8_t readBuffer[256];
+    uint8_t writeBuffer[256];
+
+    Instance *instance = testInitInstance();
+    Flash     flash(*instance);
+
+    for (uint32_t i = 0; i < sizeof(readBuffer); i++)
+    {
+        readBuffer[i] = i & 0xff;
+    }
+
+    flash.Init();
+
+    // No records in settings
+
+    VerifyOrQuit(flash.Delete(0, 0) == OT_ERROR_NOT_FOUND, "Delete() failed");
+    VerifyOrQuit(flash.Get(0, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND, "Get() failed");
+
+    // Multiple records with different keys
+
+    for (uint16_t key = 0; key < 16; key++)
+    {
+        uint16_t length = key;
+
+        SuccessOrQuit(flash.Add(key, writeBuffer, length), "Add() failed");
+    }
+
+    for (uint16_t key = 0; key < 16; key++)
+    {
+        uint16_t length = key;
+
+        SuccessOrQuit(flash.Get(key, 0, readBuffer, &length), "Get() failed");
+        VerifyOrQuit(length == key, "Get() did not return expected length");
+        VerifyOrQuit(memcmp(readBuffer, writeBuffer, length) == 0, "Get() did not return expected value");
+    }
+
+    for (uint16_t key = 0; key < 16; key++)
+    {
+        SuccessOrQuit(flash.Delete(key, 0), "Delete() failed");
+    }
+
+    for (uint16_t key = 0; key < 16; key++)
+    {
+        VerifyOrQuit(flash.Delete(key, 0) == OT_ERROR_NOT_FOUND, "Delete() failed");
+        VerifyOrQuit(flash.Get(key, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND, "Get() failed");
+    }
+
+    // Multiple records with the same key
+
+    for (uint16_t index = 0; index < 16; index++)
+    {
+        uint16_t length = index;
+
+        SuccessOrQuit(flash.Add(0, writeBuffer, length), "Add() failed");
+    }
+
+    for (uint16_t index = 0; index < 16; index++)
+    {
+        uint16_t length = index;
+
+        SuccessOrQuit(flash.Get(0, index, readBuffer, &length), "Get() failed");
+        VerifyOrQuit(length == index, "Get() did not return expected length");
+        VerifyOrQuit(memcmp(readBuffer, writeBuffer, length) == 0, "Get() did not return expected value");
+    }
+
+    for (uint16_t index = 0; index < 16; index++)
+    {
+        SuccessOrQuit(flash.Delete(0, 0), "Delete() failed");
+    }
+
+    VerifyOrQuit(flash.Delete(0, 0) == OT_ERROR_NOT_FOUND, "Delete() failed");
+    VerifyOrQuit(flash.Get(0, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND, "Get() failed");
+
+    // Multiple records with the same key
+
+    for (uint16_t index = 0; index < 16; index++)
+    {
+        uint16_t length = index;
+
+        if ((index % 4) == 0)
+        {
+            SuccessOrQuit(flash.Set(0, writeBuffer, length), "Add() failed");
+        }
+        else
+        {
+            SuccessOrQuit(flash.Add(0, writeBuffer, length), "Add() failed");
+        }
+    }
+
+    for (uint16_t index = 0; index < 4; index++)
+    {
+        uint16_t length = index + 12;
+
+        SuccessOrQuit(flash.Get(0, index, readBuffer, &length), "Get() failed");
+        VerifyOrQuit(length == (index + 12), "Get() did not return expected length");
+        VerifyOrQuit(memcmp(readBuffer, writeBuffer, length) == 0, "Get() did not return expected value");
+    }
+
+    for (uint16_t index = 0; index < 4; index++)
+    {
+        SuccessOrQuit(flash.Delete(0, 0), "Delete() failed");
+    }
+
+    VerifyOrQuit(flash.Delete(0, 0) == OT_ERROR_NOT_FOUND, "Delete() failed");
+    VerifyOrQuit(flash.Get(0, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND, "Get() failed");
+
+    // Wipe()
+
+    for (uint16_t key = 0; key < 16; key++)
+    {
+        uint16_t length = key;
+
+        SuccessOrQuit(flash.Add(key, writeBuffer, length), "Add() failed");
+    }
+
+    flash.Wipe();
+
+    for (uint16_t key = 0; key < 16; key++)
+    {
+        VerifyOrQuit(flash.Delete(key, 0) == OT_ERROR_NOT_FOUND, "Delete() failed");
+        VerifyOrQuit(flash.Get(key, 0, nullptr, nullptr) == OT_ERROR_NOT_FOUND, "Get() failed");
+    }
+
+    // Test swap
+
+    for (uint16_t index = 0; index < 4096; index++)
+    {
+        uint16_t key    = index & 0xf;
+        uint16_t length = index & 0xf;
+
+        SuccessOrQuit(flash.Set(key, writeBuffer, length), "Set() failed");
+    }
+
+    for (uint16_t key = 0; key < 16; key++)
+    {
+        uint16_t length = key;
+
+        SuccessOrQuit(flash.Get(key, 0, readBuffer, &length), "Get() failed");
+        VerifyOrQuit(length == key, "Get() did not return expected length");
+        VerifyOrQuit(memcmp(readBuffer, writeBuffer, length) == 0, "Get() did not return expected value");
+    }
+#endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
+}
+
+} // namespace ot
+
+int main(void)
+{
+    ot::TestFlash();
+    printf("All tests passed\n");
+    return 0;
+}
diff --git a/tests/unit/test_hdlc.cpp b/tests/unit/test_hdlc.cpp
index a478531..8db427a 100644
--- a/tests/unit/test_hdlc.cpp
+++ b/tests/unit/test_hdlc.cpp
@@ -30,7 +30,7 @@
 
 #include "common/code_utils.hpp"
 #include "common/instance.hpp"
-#include "ncp/hdlc.hpp"
+#include "lib/hdlc/hdlc.hpp"
 
 #include "test_util.h"
 
@@ -42,6 +42,7 @@
     kBufferSize        = 1500,  // Frame buffer size
     kMaxFrameLength    = 500,   // Maximum allowed frame length (used when randomly generating frames)
     kFuzzTestIteration = 50000, // Number of iteration during fuzz test (randomly generating frames)
+    kFrameHeaderSize   = 4,     // Frame header size
 
     kFlagXOn        = 0x11,
     kFlagXOff       = 0x13,
@@ -55,7 +56,8 @@
 static const uint8_t sHelloText[]      = "Hello there!";
 static const uint8_t sMottoText[]      = "Think good thoughts, say good words, do good deeds!";
 static const uint8_t sHexText[]        = "0123456789abcdef";
-static const uint8_t sHdlcSpeicals[]   = {kFlagSequence, kFlagXOn,        kFlagXOff,
+static const uint8_t sSkipText[]       = "Skip text";
+static const uint8_t sHdlcSpecials[]   = {kFlagSequence, kFlagXOn,        kFlagXOff,
                                         kFlagSequence, kEscapeSequence, kFlagSpecial};
 
 otError WriteToBuffer(const uint8_t *aText, Hdlc::FrameWritePointer &aWritePointer)
@@ -127,9 +129,10 @@
 void TestHdlcMultiFrameBuffer(void)
 {
     Hdlc::MultiFrameBuffer<kBufferSize> frameBuffer;
-    uint8_t *                           frame    = NULL;
-    uint8_t *                           newFrame = NULL;
+    uint8_t *                           frame    = nullptr;
+    uint8_t *                           newFrame = nullptr;
     uint16_t                            length;
+    uint16_t                            newLength;
 
     printf("Testing Hdlc::MultiFrameBuffer");
 
@@ -206,7 +209,7 @@
                  "GetFrame() content is incorrect");
 
     // Read the first saved frame and check the content
-    frame = NULL;
+    frame = nullptr;
     SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
     VerifyOrQuit(length == sizeof(sMottoText) - 1, "GetNextSavedFrame() length is incorrect");
     VerifyOrQuit(memcmp(frame, sMottoText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
@@ -221,10 +224,11 @@
     VerifyOrQuit(length == sizeof(sHexText) - 1, "GetNextSavedFrame() length is incorrect");
     VerifyOrQuit(memcmp(frame, sHexText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
 
-    newFrame = frame;
-    VerifyOrQuit(frameBuffer.GetNextSavedFrame(newFrame, length) == OT_ERROR_NOT_FOUND,
+    newFrame  = frame;
+    newLength = length;
+    VerifyOrQuit(frameBuffer.GetNextSavedFrame(newFrame, newLength) == OT_ERROR_NOT_FOUND,
                  "GetNextSavedFrame() incorrect behavior after all frames were read");
-    VerifyOrQuit(newFrame == NULL, "GetNextSavedFrame() incorrect behavior after all frames were read");
+    VerifyOrQuit(newFrame == nullptr, "GetNextSavedFrame() incorrect behavior after all frames were read");
 
     VerifyOrQuit(frameBuffer.GetLength() == sizeof(sOpenThreadText) - 1, "GetLength() failed");
     VerifyOrQuit(memcmp(frameBuffer.GetFrame(), sOpenThreadText, frameBuffer.GetLength()) == 0,
@@ -238,7 +242,7 @@
     VerifyOrQuit(memcmp(frame, sOpenThreadText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
 
     // Re-read all the saved frames
-    frame = NULL;
+    frame = nullptr;
     SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
     VerifyOrQuit(length == sizeof(sMottoText) - 1, "GetNextSavedFrame() length is incorrect");
     VerifyOrQuit(memcmp(frame, sMottoText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
@@ -274,20 +278,22 @@
     frameBuffer.SaveFrame();
     VerifyOrQuit(frameBuffer.HasSavedFrame(), "HasFrame() incorrect behavior after SaveFrame()");
 
-    frame = NULL;
+    frame = nullptr;
     SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
     VerifyOrQuit(frameBuffer.HasSavedFrame(), "HasFrame() incorrect behavior after SaveFrame()");
 
     frameBuffer.Clear();
 
-    frame = NULL;
+    frame = nullptr;
     VerifyOrQuit(frameBuffer.GetNextSavedFrame(frame, length) == OT_ERROR_NOT_FOUND,
                  "GetNextSavedFrame() incorrect behavior after Clear()");
 
     VerifyOrQuit(!frameBuffer.HasFrame(), "HasFrame() incorrect behavior after Clear()");
     VerifyOrQuit(!frameBuffer.HasSavedFrame(), "HasFrame() incorrect behavior after Clear()");
-    VerifyOrQuit(frameBuffer.CanWrite(kBufferSize - 1) == false, "CanWrite() incorrect behavior after Clear()");
-    VerifyOrQuit(frameBuffer.CanWrite(kBufferSize - 2) == true, "CanWrite() incorrect behavior after Clear()");
+    VerifyOrQuit(frameBuffer.CanWrite(kBufferSize - (kFrameHeaderSize - 1)) == false,
+                 "CanWrite() incorrect behavior after Clear()");
+    VerifyOrQuit(frameBuffer.CanWrite(kBufferSize - kFrameHeaderSize) == true,
+                 "CanWrite() incorrect behavior after Clear()");
 
     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     // Verify behavior of `ClearSavedFrames()`
@@ -300,7 +306,7 @@
     frameBuffer.SaveFrame();
     SuccessOrQuit(WriteToBuffer(sHexText, frameBuffer), "WriteByte() failed");
 
-    frame = NULL;
+    frame = nullptr;
     SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
     VerifyOrQuit(length == sizeof(sHelloText) - 1, "GetNextSavedFrame() length is incorrect");
     VerifyOrQuit(memcmp(frame, sHelloText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
@@ -318,7 +324,7 @@
 
     SuccessOrQuit(WriteToBuffer(sHelloText, frameBuffer), "WriteByte() failed");
 
-    frame = NULL;
+    frame = nullptr;
     SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
     VerifyOrQuit(length == sizeof(sHexText) - 1, "GetNextSavedFrame() length is incorrect");
     VerifyOrQuit(memcmp(frame, sHexText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
@@ -333,9 +339,9 @@
 
     VerifyOrQuit(!frameBuffer.HasFrame(), "HasFrame() incorrect behavior after all frames are read and discarded");
     VerifyOrQuit(!frameBuffer.HasSavedFrame(), "HasFrame() incorrect behavior after all read or discarded");
-    VerifyOrQuit(frameBuffer.CanWrite(kBufferSize - 1) == false,
+    VerifyOrQuit(frameBuffer.CanWrite(kBufferSize - (kFrameHeaderSize - 1)) == false,
                  "CanWrite() incorrect behavior after all read or discarded");
-    VerifyOrQuit(frameBuffer.CanWrite(kBufferSize - 2) == true,
+    VerifyOrQuit(frameBuffer.CanWrite(kBufferSize - kFrameHeaderSize) == true,
                  "CanWrite() incorrect behavior after all read of discarded");
 
     SuccessOrQuit(WriteToBuffer(sHelloText, frameBuffer), "WriteByte() failed");
@@ -347,11 +353,108 @@
                  "GetFrame() content is incorrect");
 
     frameBuffer.SaveFrame();
-    frame = NULL;
+    frame = nullptr;
     SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
     VerifyOrQuit(length == sizeof(sHelloText) - 1, "GetNextSavedFrame() length is incorrect");
     VerifyOrQuit(memcmp(frame, sHelloText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
 
+    //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    // Verify behavior of `SetSkipLength()` and `GetSkipLength()`
+
+    frameBuffer.Clear();
+
+    VerifyOrQuit(frameBuffer.GetSkipLength() == 0, "GetSkipLength() incorrect behavior after Clear()");
+    VerifyOrQuit(frameBuffer.SetSkipLength(sizeof(sSkipText)) == OT_ERROR_NONE, "SetSkipLength() failed");
+    SuccessOrQuit(WriteToBuffer(sMottoText, frameBuffer), "WriteByte() failed");
+    VerifyOrQuit(memcmp(frameBuffer.GetFrame(), sMottoText, frameBuffer.GetLength()) == 0,
+                 "GetFrame() content is incorrect");
+    memcpy(frameBuffer.GetFrame() - sizeof(sSkipText), sSkipText, sizeof(sSkipText));
+    VerifyOrQuit(frameBuffer.GetSkipLength() == sizeof(sSkipText), "GetSkipLength() failed");
+    VerifyOrQuit(frameBuffer.GetLength() == sizeof(sMottoText) - 1, "GetLength() failed");
+    VerifyOrQuit(memcmp(frameBuffer.GetFrame(), sMottoText, frameBuffer.GetLength()) == 0,
+                 "GetFrame() content is incorrect");
+
+    frameBuffer.SaveFrame();
+    VerifyOrQuit(!frameBuffer.HasFrame(), "HasFrame() incorrect behavior after SaveFrame()");
+    VerifyOrQuit(frameBuffer.HasSavedFrame(), "HasFrame() incorrect behavior after SaveFrame()");
+    VerifyOrQuit(frameBuffer.GetSkipLength() == 0, "GetSkipLength() incorrect behavior after SaveFrame()");
+
+    VerifyOrQuit(frameBuffer.SetSkipLength(sizeof(sSkipText)) == OT_ERROR_NONE, "SetSkipLength() failed");
+    SuccessOrQuit(WriteToBuffer(sOpenThreadText, frameBuffer), "WriteByte() failed");
+    VerifyOrQuit(memcmp(frameBuffer.GetFrame(), sOpenThreadText, frameBuffer.GetLength()) == 0,
+                 "GetFrame() content is incorrect");
+    memcpy(frameBuffer.GetFrame() - sizeof(sSkipText), sSkipText, sizeof(sSkipText));
+    VerifyOrQuit(frameBuffer.GetSkipLength() == sizeof(sSkipText), "GetSkipLength() failed");
+    VerifyOrQuit(frameBuffer.GetLength() == sizeof(sOpenThreadText) - 1, "GetLength() failed");
+    VerifyOrQuit(memcmp(frameBuffer.GetFrame(), sOpenThreadText, frameBuffer.GetLength()) == 0,
+                 "GetFrame() content is incorrect");
+
+    frameBuffer.SaveFrame();
+    VerifyOrQuit(!frameBuffer.HasFrame(), "HasFrame() incorrect behavior after SaveFrame()");
+    VerifyOrQuit(frameBuffer.HasSavedFrame(), "HasFrame() incorrect behavior after SaveFrame()");
+    VerifyOrQuit(frameBuffer.GetSkipLength() == 0, "GetSkipLength() incorrect behavior after SaveFrame()");
+
+    frame = nullptr;
+    SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
+    VerifyOrQuit(length == sizeof(sMottoText) - 1, "GetNextSavedFrame() length is incorrect");
+    VerifyOrQuit(memcmp(frame, sMottoText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
+    VerifyOrQuit(memcmp(frame - sizeof(sSkipText), sSkipText, sizeof(sSkipText)) == 0,
+                 "GetNextSavedFrame() reserved frame buffer content is incorrect");
+
+    SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
+    VerifyOrQuit(length == sizeof(sOpenThreadText) - 1, "GetNextSavedFrame() length is incorrect");
+    VerifyOrQuit(memcmp(frame, sOpenThreadText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
+    VerifyOrQuit(memcmp(frame - sizeof(sSkipText), sSkipText, sizeof(sSkipText)) == 0,
+                 "GetNextSavedFrame() reserved frame buffer content is incorrect");
+
+    frameBuffer.Clear();
+    VerifyOrQuit(frameBuffer.SetSkipLength(kBufferSize - (kFrameHeaderSize - 1)) == OT_ERROR_NO_BUFS,
+                 "SetSkipLength() incorrect behavior after Clear()");
+    VerifyOrQuit(frameBuffer.SetSkipLength(kBufferSize - kFrameHeaderSize) == OT_ERROR_NONE,
+                 "SetSkipLength() incorrect behavior after Clear()");
+
+    //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    // Verify behavior of `SetLength()` and `GetLength()`
+
+    frameBuffer.Clear();
+    VerifyOrQuit((frame = frameBuffer.GetFrame()) != nullptr, "GetFrame() failed");
+    memcpy(frame, sHelloText, sizeof(sHelloText));
+    VerifyOrQuit(frameBuffer.SetLength(sizeof(sHelloText)) == OT_ERROR_NONE, "SetLength() failed");
+    VerifyOrQuit(frameBuffer.GetLength() == sizeof(sHelloText), "GetLength() failed");
+    VerifyOrQuit(frameBuffer.HasFrame(), "HasFrame() is incorrect");
+    frameBuffer.SaveFrame();
+
+    VerifyOrQuit((frame = frameBuffer.GetFrame()) != nullptr, "GetFrame() failed");
+    memcpy(frame, sMottoText, sizeof(sMottoText));
+    VerifyOrQuit(frameBuffer.SetLength(sizeof(sMottoText)) == OT_ERROR_NONE, "SetLength() failed");
+    VerifyOrQuit(frameBuffer.GetLength() == sizeof(sMottoText), "GetLength() failed");
+    VerifyOrQuit(frameBuffer.HasFrame(), "HasFrame() is incorrect");
+    frameBuffer.SaveFrame();
+
+    VerifyOrQuit((frame = frameBuffer.GetFrame()) != nullptr, "GetFrame() failed");
+    memcpy(frame, sHexText, sizeof(sHexText));
+    VerifyOrQuit(frameBuffer.SetLength(sizeof(sHexText)) == OT_ERROR_NONE, "SetLength() failed");
+    VerifyOrQuit(frameBuffer.GetLength() == sizeof(sHexText), "GetLength() failed");
+    frameBuffer.DiscardFrame();
+    VerifyOrQuit(!frameBuffer.HasFrame(), "HasFrame() is incorrect");
+
+    frame = nullptr;
+    SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
+    VerifyOrQuit(length == sizeof(sHelloText), "GetNextSavedFrame() length is incorrect");
+    VerifyOrQuit(memcmp(frame, sHelloText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
+
+    SuccessOrQuit(frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
+    VerifyOrQuit(length == sizeof(sMottoText), "GetNextSavedFrame() length is incorrect");
+    VerifyOrQuit(memcmp(frame, sMottoText, length) == 0, "GetNextSavedFrame() frame content is incorrect");
+
+    SuccessOrQuit(!frameBuffer.GetNextSavedFrame(frame, length), "GetNextSavedFrame() failed unexpectedly");
+
+    frameBuffer.Clear();
+    VerifyOrQuit(frameBuffer.SetLength(kBufferSize - (kFrameHeaderSize - 1)) == OT_ERROR_NO_BUFS,
+                 "SetLength() incorrect behavior after Clear()");
+    VerifyOrQuit(frameBuffer.SetLength(kBufferSize - kFrameHeaderSize) == OT_ERROR_NONE,
+                 "SetLength() incorrect behavior after Clear()");
+
     printf(" -- PASS\n");
 }
 
@@ -395,7 +498,7 @@
     encoderBuffer.SaveFrame();
 
     SuccessOrQuit(encoder.BeginFrame(), "Encoder::BeginFrame() failed");
-    SuccessOrQuit(encoder.Encode(sHdlcSpeicals, sizeof(sHdlcSpeicals)), "Encoder::Encode() failed");
+    SuccessOrQuit(encoder.Encode(sHdlcSpecials, sizeof(sHdlcSpecials)), "Encoder::Encode() failed");
     SuccessOrQuit(encoder.EndFrame(), "Encoder::EndFrame() failed");
     encoderBuffer.SaveFrame();
 
@@ -416,7 +519,7 @@
     encoderBuffer.SaveFrame();
 
     // Feed the encoded frames to decoder and save the content
-    for (frame = NULL; encoderBuffer.GetNextSavedFrame(frame, length) == OT_ERROR_NONE;)
+    for (frame = nullptr; encoderBuffer.GetNextSavedFrame(frame, length) == OT_ERROR_NONE;)
     {
         decoderContext.mWasCalled = false;
 
@@ -429,7 +532,7 @@
     }
 
     // Verify the decoded frames match the original frames
-    frame = NULL;
+    frame = nullptr;
     SuccessOrQuit(decoderBuffer.GetNextSavedFrame(frame, length), "Incorrect decoded frame");
     VerifyOrQuit(length == sizeof(sOpenThreadText) - 1, "Decoded frame length does not match original frame");
     VerifyOrQuit(memcmp(frame, sOpenThreadText, length) == 0, "Decoded frame content does not match original frame");
@@ -439,8 +542,8 @@
     VerifyOrQuit(memcmp(frame, sMottoText, length) == 0, "Decoded frame content does not match original frame");
 
     SuccessOrQuit(decoderBuffer.GetNextSavedFrame(frame, length), "Incorrect decoded frame");
-    VerifyOrQuit(length == sizeof(sHdlcSpeicals), "Decoded frame length does not match original frame");
-    VerifyOrQuit(memcmp(frame, sHdlcSpeicals, length) == 0, "Decoded frame content does not match original frame");
+    VerifyOrQuit(length == sizeof(sHdlcSpecials), "Decoded frame length does not match original frame");
+    VerifyOrQuit(memcmp(frame, sHdlcSpecials, length) == 0, "Decoded frame content does not match original frame");
 
     SuccessOrQuit(decoderBuffer.GetNextSavedFrame(frame, length), "Incorrect decoded frame");
     VerifyOrQuit(length == sizeof(sHelloText) - 1, "Decoded frame length does not match original frame");
diff --git a/tests/unit/test_heap.cpp b/tests/unit/test_heap.cpp
index f95a6b2..651d60a 100644
--- a/tests/unit/test_heap.cpp
+++ b/tests/unit/test_heap.cpp
@@ -50,11 +50,11 @@
 
     {
         void *p = heap.CAlloc(1, 0);
-        VerifyOrQuit(p == NULL && totalSize == heap.GetFreeSize(), "TestAllocateSingle allocate 1 x 0 byte failed!");
+        VerifyOrQuit(p == nullptr && totalSize == heap.GetFreeSize(), "TestAllocateSingle allocate 1 x 0 byte failed!");
         heap.Free(p);
 
         p = heap.CAlloc(0, 1);
-        VerifyOrQuit(p == NULL && totalSize == heap.GetFreeSize(), "TestAllocateSingle allocate 0 x 1 byte failed!");
+        VerifyOrQuit(p == nullptr && totalSize == heap.GetFreeSize(), "TestAllocateSingle allocate 0 x 1 byte failed!");
         heap.Free(p);
     }
 
@@ -62,7 +62,7 @@
     {
         printf("%s allocating %zu bytes...\n", __func__, size);
         void *p = heap.CAlloc(1, size);
-        VerifyOrQuit(p != NULL && !heap.IsClean() && heap.GetFreeSize() + size <= totalSize, "allocating failed!");
+        VerifyOrQuit(p != nullptr && !heap.IsClean() && heap.GetFreeSize() + size <= totalSize, "allocating failed!");
         memset(p, 0xff, size);
         heap.Free(p);
         VerifyOrQuit(heap.IsClean() && heap.GetFreeSize() == totalSize, "freeing failed!\n");
@@ -100,12 +100,12 @@
         last->mNext = static_cast<Node *>(heap.CAlloc(1, size));
 
         // No more memory for allocation.
-        if (last->mNext == NULL)
+        if (last->mNext == nullptr)
         {
             break;
         }
 
-        VerifyOrQuit(last->mNext->mNext == NULL, "TestAllocateRandomly memory not initialized to zero!");
+        VerifyOrQuit(last->mNext->mNext == nullptr, "TestAllocateRandomly memory not initialized to zero!");
         last        = last->mNext;
         last->mSize = size;
         ++nnodes;
diff --git a/tests/unit/test_hmac_sha256.cpp b/tests/unit/test_hmac_sha256.cpp
index 35fcb58..0563028 100644
--- a/tests/unit/test_hmac_sha256.cpp
+++ b/tests/unit/test_hmac_sha256.cpp
@@ -51,8 +51,8 @@
             },
         },
         {
-            NULL,
-            NULL,
+            nullptr,
+            nullptr,
             {},
         },
     };
@@ -64,9 +64,9 @@
         ot::Crypto::HmacSha256 hmac;
         uint8_t                hash[ot::Crypto::HmacSha256::kHashSize];
 
-        VerifyOrQuit(instance != NULL, "Null OpenThread instance");
+        VerifyOrQuit(instance != nullptr, "Null OpenThread instance");
 
-        for (int i = 0; tests[i].key != NULL; i++)
+        for (int i = 0; tests[i].key != nullptr; i++)
         {
             hmac.Start(reinterpret_cast<const uint8_t *>(tests[i].key), static_cast<uint16_t>(strlen(tests[i].key)));
             hmac.Update(reinterpret_cast<const uint8_t *>(tests[i].data), static_cast<uint16_t>(strlen(tests[i].data)));
diff --git a/tests/unit/test_ip6_address.cpp b/tests/unit/test_ip6_address.cpp
index ffbf854..d60587f 100644
--- a/tests/unit/test_ip6_address.cpp
+++ b/tests/unit/test_ip6_address.cpp
@@ -26,11 +26,14 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <limits.h>
+
 #include "net/ip6_address.hpp"
 
 #include "test_util.h"
 
-struct Ip6AddressStringTestVector{
+struct Ip6AddressStringTestVector
+{
     const char *  mString;
     const uint8_t mAddr[OT_IP6_ADDRESS_SIZE];
     otError       mError;
@@ -54,147 +57,77 @@
 
 void TestIp6AddressFromString(void)
 {
-    Ip6AddressStringTestVector testVectors[] =
-    {
+    Ip6AddressStringTestVector testVectors[] = {
         // Valid full IPv6 address.
-        {
-            "0102:0304:0506:0708:090a:0b0c:0d0e:0f00",
-            {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-             0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00},
-            OT_ERROR_NONE
-        },
+        {"0102:0304:0506:0708:090a:0b0c:0d0e:0f00",
+         {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00},
+         OT_ERROR_NONE},
 
         // Valid full IPv6 address with mixed capital and small letters.
-        {
-            "0102:0304:0506:0708:090a:0B0C:0d0E:0F00",
-            {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-             0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00},
-            OT_ERROR_NONE
-        },
+        {"0102:0304:0506:0708:090a:0B0C:0d0E:0F00",
+         {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00},
+         OT_ERROR_NONE},
 
         // Short prefix and full IID.
-        {
-            "fd11::abcd:e0e0:d10e:0001",
-            {0xfd, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-             0xab, 0xcd, 0xe0, 0xe0, 0xd1, 0x0e, 0x00, 0x01},
-            OT_ERROR_NONE
-        },
+        {"fd11::abcd:e0e0:d10e:0001",
+         {0xfd, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xcd, 0xe0, 0xe0, 0xd1, 0x0e, 0x00, 0x01},
+         OT_ERROR_NONE},
 
         // Valid IPv6 address with unnecessary :: symbol.
-        {
-            "fd11:1234:5678:abcd::abcd:e0e0:d10e:1000",
-            {0xfd, 0x11, 0x12, 0x34, 0x56, 0x78, 0xab, 0xcd,
-             0xab, 0xcd, 0xe0, 0xe0, 0xd1, 0x0e, 0x10, 0x00},
-            OT_ERROR_NONE
-        },
+        {"fd11:1234:5678:abcd::abcd:e0e0:d10e:1000",
+         {0xfd, 0x11, 0x12, 0x34, 0x56, 0x78, 0xab, 0xcd, 0xab, 0xcd, 0xe0, 0xe0, 0xd1, 0x0e, 0x10, 0x00},
+         OT_ERROR_NONE},
 
         // Short multicast address.
-        {
-            "ff03::0b",
-            {0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b},
-            OT_ERROR_NONE
-        },
+        {"ff03::0b",
+         {0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b},
+         OT_ERROR_NONE},
 
         // Unspecified address.
-        {
-            "::",
-            {0},
-            OT_ERROR_NONE
-        },
+        {"::", {0}, OT_ERROR_NONE},
 
         // Valid embedded IPv4 address.
-        {
-            "64:ff9b::100.200.15.4",
-            {0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00,
-             0x00, 0x00, 0x00, 0x00, 0x64, 0xc8, 0x0f, 0x04},
-            OT_ERROR_NONE
-        },
+        {"64:ff9b::100.200.15.4",
+         {0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xc8, 0x0f, 0x04},
+         OT_ERROR_NONE},
 
         // Valid embedded IPv4 address.
-        {
-            "2001:db8::abc:def1:127.0.0.1",
-            {0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
-             0x0a, 0xbc, 0xde, 0xf1, 0x7f, 0x00, 0x00, 0x01},
-            OT_ERROR_NONE
-        },
+        {"2001:db8::abc:def1:127.0.0.1",
+         {0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xbc, 0xde, 0xf1, 0x7f, 0x00, 0x00, 0x01},
+         OT_ERROR_NONE},
 
         // Two :: should cause a parse error.
-        {
-            "2001:db8::a::b",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {"2001:db8::a::b", {0}, OT_ERROR_PARSE},
 
         // The "g" and "h" are not the hex characters.
-        {
-            "2001:db8::abcd:efgh",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {"2001:db8::abcd:efgh", {0}, OT_ERROR_PARSE},
 
         // Too many colons.
-        {
-            "1:2:3:4:5:6:7:8:9",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {"1:2:3:4:5:6:7:8:9", {0}, OT_ERROR_PARSE},
 
         // Too many characters in a single part.
-        {
-            "2001:db8::abc:def12:1:2",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {"2001:db8::abc:def12:1:2", {0}, OT_ERROR_PARSE},
 
         // Invalid embedded IPv4 address.
-        {
-            "64:ff9b::123.231.0.257",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {"64:ff9b::123.231.0.257", {0}, OT_ERROR_PARSE},
 
         // Invalid embedded IPv4 address.
-        {
-            "64:ff9b::1.22.33",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {"64:ff9b::1.22.33", {0}, OT_ERROR_PARSE},
 
         // Invalid embedded IPv4 address.
-        {
-            "64:ff9b::1.22.33.44.5",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {"64:ff9b::1.22.33.44.5", {0}, OT_ERROR_PARSE},
 
         // Invalid embedded IPv4 address.
-        {
-            ".",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {".", {0}, OT_ERROR_PARSE},
 
         // Invalid embedded IPv4 address.
-        {
-            ":.",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {":.", {0}, OT_ERROR_PARSE},
 
         // Invalid embedded IPv4 address.
-        {
-            "::.",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {"::.", {0}, OT_ERROR_PARSE},
 
         // Invalid embedded IPv4 address.
-        {
-            ":f:0:0:c:0:f:f:.",
-            {0},
-            OT_ERROR_PARSE
-        },
+        {":f:0:0:c:0:f:f:.", {0}, OT_ERROR_PARSE},
     };
 
     for (uint32_t index = 0; index < OT_ARRAY_LENGTH(testVectors); index++)
@@ -203,8 +136,92 @@
     }
 }
 
+bool CheckPrefix(const ot::Ip6::Address &aAddress, const uint8_t *aPrefix, uint8_t aPrefixLength)
+{
+    // Check the first aPrefixLength bits of aAddress to match the given aPrefix.
+
+    bool matches = true;
+
+    for (uint8_t bit = 0; bit < aPrefixLength; bit++)
+    {
+        uint8_t index = bit / CHAR_BIT;
+        uint8_t mask  = (0x80 >> (bit % CHAR_BIT));
+
+        if ((aAddress.mFields.m8[index] & mask) != (aPrefix[index] & mask))
+        {
+            matches = false;
+            break;
+        }
+    }
+
+    return matches;
+}
+
+bool CheckInterfaceId(const ot::Ip6::Address &aAddress1, const ot::Ip6::Address &aAddress2, uint8_t aPrefixLength)
+{
+    // Check whether all the bits after aPrefixLength of the two given IPv6 Address match or not.
+
+    bool matches = true;
+
+    for (uint8_t bit = aPrefixLength; bit < sizeof(ot::Ip6::Address) * CHAR_BIT; bit++)
+    {
+        uint8_t index = bit / CHAR_BIT;
+        uint8_t mask  = (0x80 >> (bit % CHAR_BIT));
+
+        if ((aAddress1.mFields.m8[index] & mask) != (aAddress2.mFields.m8[index] & mask))
+        {
+            matches = false;
+            break;
+        }
+    }
+
+    return matches;
+}
+
+void TestIp6AddressSetPrefix(void)
+{
+    const uint8_t kPrefixes[][OT_IP6_ADDRESS_SIZE] = {
+        {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+        {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
+        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+        {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+    };
+
+    ot::Ip6::Address address;
+    ot::Ip6::Address allZeroAddress;
+    ot::Ip6::Address allOneAddress;
+
+    allZeroAddress.Clear();
+    memset(&allOneAddress, 0xff, sizeof(allOneAddress));
+
+    for (uint8_t index = 0; index < OT_ARRAY_LENGTH(kPrefixes); index++)
+    {
+        const uint8_t *prefix = kPrefixes[index];
+
+        memcpy(address.mFields.m8, prefix, sizeof(address));
+        printf("Prefix is %s\n", address.ToString().AsCString());
+
+        for (uint8_t prefixLength = 0; prefixLength <= sizeof(ot::Ip6::Address) * CHAR_BIT; prefixLength++)
+        {
+            address = allZeroAddress;
+            address.SetPrefix(prefix, prefixLength);
+            printf("   prefix-len:%-3d --> %s\n", prefixLength, address.ToString().AsCString());
+            VerifyOrQuit(CheckPrefix(address, prefix, prefixLength), "Prefix does not match after SetPrefix()");
+            VerifyOrQuit(CheckInterfaceId(address, allZeroAddress, prefixLength),
+                         "SetPrefix changed bits beyond the prefix length");
+
+            address = allOneAddress;
+            address.SetPrefix(prefix, prefixLength);
+            VerifyOrQuit(CheckPrefix(address, prefix, prefixLength), "Prefix does not match after SetPrefix()");
+            VerifyOrQuit(CheckInterfaceId(address, allOneAddress, prefixLength),
+                         "SetPrefix changed bits beyond the prefix length");
+        }
+    }
+}
+
 int main(void)
 {
+    TestIp6AddressSetPrefix();
     TestIp6AddressFromString();
     printf("All tests passed\n");
     return 0;
diff --git a/tests/unit/test_link_quality.cpp b/tests/unit/test_link_quality.cpp
index f352f2c..c6bf83b 100644
--- a/tests/unit/test_link_quality.cpp
+++ b/tests/unit/test_link_quality.cpp
@@ -34,6 +34,8 @@
 
 namespace ot {
 
+static ot::Instance *sInstance;
+
 enum
 {
     kMaxRssValue = 0,
@@ -89,6 +91,10 @@
     int8_t          rss, ave, min, max;
     size_t          i;
 
+    sInstance = testInitInstance();
+    VerifyOrQuit(sInstance != nullptr, "Null instance");
+    linkInfo.Init(*sInstance);
+
     printf("- - - - - - - - - - - - - - - - - -\n");
     linkInfo.Clear();
     min = kMinRssValue;
@@ -99,7 +105,7 @@
         rss = aRssData.mRssList[i];
         min = MIN_RSS(rss, min);
         max = MAX_RSS(rss, max);
-        linkInfo.AddRss(sNoiseFloor, rss);
+        linkInfo.AddRss(rss);
         VerifyOrQuit(linkInfo.GetLastRss() == rss, "TestLinkQualityInfo failed - GetLastRss() is incorrect");
         ave = linkInfo.GetAverageRss();
         VerifyOrQuit(ave >= min, "TestLinkQualityInfo failed - GetAverageRss() is smaller than min value.");
@@ -168,7 +174,7 @@
     // Adding a single value
     rss = -70;
     printf("AddRss(%d): ", rss);
-    rssAverager.Add(rss);
+    IgnoreError(rssAverager.Add(rss));
     VerifyOrQuit(rssAverager.GetAverage() == rss, "TestLinkQualityInfo - GetAverage() failed after a single AddRss().");
     VerifyRawRssValue(rssAverager);
     PrintOutcome(rssAverager);
@@ -196,7 +202,7 @@
 
         for (i = 0; i < kNumRssAdds; i++)
         {
-            rssAverager.Add(rss);
+            IgnoreError(rssAverager.Add(rss));
             VerifyOrQuit(rssAverager.GetAverage() == rss,
                          "TestLinkQualityInfo failed - GetAverage() returned incorrect value.");
             VerifyRawRssValue(rssAverager);
@@ -223,8 +229,8 @@
 
             rss2 = rssValues[k];
             rssAverager.Reset();
-            rssAverager.Add(rss);
-            rssAverager.Add(rss2);
+            IgnoreError(rssAverager.Add(rss));
+            IgnoreError(rssAverager.Add(rss2));
             printf("AddRss(%4d), AddRss(%4d): ", rss, rss2);
             VerifyOrQuit(rssAverager.GetAverage() == ((rss + rss2) >> 1),
                          "TestLinkQualityInfo failed - GetAverage() returned incorrect value.");
@@ -254,10 +260,10 @@
 
             for (i = 0; i < kNumRssAdds; i++)
             {
-                rssAverager.Add(rss);
+                IgnoreError(rssAverager.Add(rss));
             }
 
-            rssAverager.Add(rss2);
+            IgnoreError(rssAverager.Add(rss2));
             printf("AddRss(%4d) %d times, AddRss(%4d): ", rss, kNumRssAdds, rss2);
             ave = rssAverager.GetAverage();
             VerifyOrQuit(ave >= MIN_RSS(rss, rss2),
@@ -290,8 +296,8 @@
 
             for (i = 0; i < kNumRssAdds; i++)
             {
-                rssAverager.Add(rss);
-                rssAverager.Add(rss2);
+                IgnoreError(rssAverager.Add(rss));
+                IgnoreError(rssAverager.Add(rss2));
                 ave = rssAverager.GetAverage();
                 VerifyOrQuit(ave >= MIN_RSS(rss, rss2),
                              "TestLinkQualityInfo failed - GetAverage() is smaller than min value.");
@@ -325,7 +331,7 @@
         for (j = 1; j <= 8; j++)
         {
             rss = GetRandomRss();
-            rssAverager.Add(rss);
+            IgnoreError(rssAverager.Add(rss));
             sum += rss;
             mean = static_cast<double>(sum) / j;
             VerifyOrQuit(ABS(rssAverager.GetAverage() - mean) < 1, "Average does not match the arithmetic mean!");
diff --git a/tests/unit/test_linked_list.cpp b/tests/unit/test_linked_list.cpp
index 2a13a78..5664a00 100644
--- a/tests/unit/test_linked_list.cpp
+++ b/tests/unit/test_linked_list.cpp
@@ -27,6 +27,7 @@
  */
 
 #include <stdarg.h>
+#include <string.h>
 
 #include "test_platform.h"
 
@@ -45,64 +46,99 @@
 
 struct Entry : public EntryBase, ot::LinkedListEntry<Entry>
 {
+public:
+    Entry(const char *aName, uint16_t aId)
+        : mName(aName)
+        , mId(aId)
+    {
+    }
+
+    const char *GetName(void) const { return mName; }
+    uint16_t    GetId(void) const { return mId; }
+    bool        Matches(const char *aName) const { return strcmp(mName, aName) == 0; }
+    bool        Matches(uint16_t aId) const { return mId == aId; }
+
+private:
+    const char *mName;
+    uint16_t    mId;
 };
 
 // This function verifies the content of the linked list matches a given list of entries.
-void VerifyLinkedListContent(const ot::LinkedList<Entry> &aList, ...)
+void VerifyLinkedListContent(const ot::LinkedList<Entry> *aList, ...)
 {
-    va_list args;
-    Entry * argEntry;
-    Entry * argPrev = NULL;
+    va_list      args;
+    Entry *      argEntry;
+    Entry *      argPrev = nullptr;
+    const Entry *prev;
+    uint16_t     unusedId = 100;
 
     va_start(args, aList);
 
-    for (const Entry *entry = aList.GetHead(); entry; entry = entry->GetNext())
+    for (const Entry *entry = aList->GetHead(); entry; entry = entry->GetNext())
     {
-        Entry *prev;
-
         argEntry = va_arg(args, Entry *);
-        VerifyOrQuit(argEntry != NULL, "List contains more entries than expected");
+        VerifyOrQuit(argEntry != nullptr, "List contains more entries than expected");
         VerifyOrQuit(argEntry == entry, "List does not contain the same entry");
-        VerifyOrQuit(aList.Contains(*argEntry), "List::Contains() failed");
+        VerifyOrQuit(aList->Contains(*argEntry), "List::Contains() failed");
+        VerifyOrQuit(aList->ContainsMatching(argEntry->GetName()), "List::ContainsMatching() failed");
+        VerifyOrQuit(aList->ContainsMatching(argEntry->GetId()), "List::ContainsMatching() failed");
 
-        SuccessOrQuit(aList.Find(*argEntry, prev), "List::Find() failed");
+        SuccessOrQuit(aList->Find(*argEntry, prev), "List::Find() failed");
         VerifyOrQuit(prev == argPrev, "List::Find() returned prev entry is incorrect");
 
+        VerifyOrQuit(aList->FindMatching(argEntry->GetName(), prev) == argEntry, "List::FindMatching() failed");
+        VerifyOrQuit(prev == argPrev, "List::FindMatching() returned prev entry is incorrect");
+
+        VerifyOrQuit(aList->FindMatching(argEntry->GetId(), prev) == argEntry, "List::FindMatching() failed");
+        VerifyOrQuit(prev == argPrev, "List::FindMatching() returned prev entry is incorrect");
+
         argPrev = argEntry;
     }
 
     argEntry = va_arg(args, Entry *);
-    VerifyOrQuit(argEntry == NULL, "List contains less entries than expected");
+    VerifyOrQuit(argEntry == nullptr, "List contains less entries than expected");
 
-    VerifyOrQuit(aList.GetTail() == argPrev, "List::GetTail() failed");
+    VerifyOrQuit(aList->GetTail() == argPrev, "List::GetTail() failed");
+
+    VerifyOrQuit(!aList->ContainsMatching("none"), "List::ContainsMatching() succeeded for a missing entry");
+    VerifyOrQuit(!aList->ContainsMatching(unusedId), "List::ContainsMatching() succeeded for a missing entry");
+
+    VerifyOrQuit(aList->FindMatching("none", prev) == nullptr,
+                 "LinkedList::FindMatching() succeeded for a missing entry");
+    VerifyOrQuit(aList->FindMatching(unusedId, prev) == nullptr,
+                 "LinkedList::FindMatching() succeeded for a missing entry");
 }
 
 void TestLinkedList(void)
 {
-    Entry                 a, b, c, d, e;
+    Entry                 a("a", 1), b("b", 2), c("c", 3), d("d", 4), e("e", 5);
+    Entry *               prev;
     ot::LinkedList<Entry> list;
 
     VerifyOrQuit(list.IsEmpty(), "LinkedList::IsEmpty() failed after init");
-    VerifyOrQuit(list.GetHead() == NULL, "LinkedList::GetHead() failed after init");
-    VerifyOrQuit(list.Pop() == NULL, "LinkedList::Pop() failed when empty");
+    VerifyOrQuit(list.GetHead() == nullptr, "LinkedList::GetHead() failed after init");
+    VerifyOrQuit(list.Pop() == nullptr, "LinkedList::Pop() failed when empty");
+    VerifyOrQuit(list.Find(a, prev) == OT_ERROR_NOT_FOUND, "LinkedList::Find() succeeded for a missing entry");
 
-    VerifyLinkedListContent(list, NULL);
+    VerifyLinkedListContent(&list, nullptr);
 
     list.Push(a);
     VerifyOrQuit(!list.IsEmpty(), "LinkedList::IsEmpty() failed");
-    VerifyLinkedListContent(list, &a, NULL);
+    VerifyLinkedListContent(&list, &a, nullptr);
+    VerifyOrQuit(list.Find(b, prev) == OT_ERROR_NOT_FOUND, "LinkedList::Find() succeeded for a missing entry");
 
     SuccessOrQuit(list.Add(b), "LinkedList::Add() failed");
-    VerifyLinkedListContent(list, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &b, &a, nullptr);
+    VerifyOrQuit(list.Find(c, prev) == OT_ERROR_NOT_FOUND, "LinkedList::Find() succeeded for a missing entry");
 
     list.Push(c);
-    VerifyLinkedListContent(list, &c, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &c, &b, &a, nullptr);
 
     SuccessOrQuit(list.Add(d), "LinkedList::Add() failed");
-    VerifyLinkedListContent(list, &d, &c, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &d, &c, &b, &a, nullptr);
 
     SuccessOrQuit(list.Add(e), "LinkedList::Add() failed");
-    VerifyLinkedListContent(list, &e, &d, &c, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &e, &d, &c, &b, &a, nullptr);
 
     VerifyOrQuit(list.Add(a) == OT_ERROR_ALREADY, "LinkedList::Add() did not detect duplicate");
     VerifyOrQuit(list.Add(b) == OT_ERROR_ALREADY, "LinkedList::Add() did not detect duplicate");
@@ -110,46 +146,90 @@
     VerifyOrQuit(list.Add(e) == OT_ERROR_ALREADY, "LinkedList::Add() did not detect duplicate");
 
     VerifyOrQuit(list.Pop() == &e, "LinkedList::Pop() failed");
-    VerifyLinkedListContent(list, &d, &c, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &d, &c, &b, &a, nullptr);
+    VerifyOrQuit(list.Find(e, prev) == OT_ERROR_NOT_FOUND, "LinkedList::Find() succeeded for a missing entry");
+
+    VerifyOrQuit(list.FindMatching(d.GetName(), prev) == &d, "List::FindMatching() failed");
+    VerifyOrQuit(prev == nullptr, "List::FindMatching() failed");
+    VerifyOrQuit(list.FindMatching(c.GetId(), prev) == &c, "List::FindMatching() failed");
+    VerifyOrQuit(prev == &d, "List::FindMatching() failed");
+    VerifyOrQuit(list.FindMatching(b.GetName(), prev) == &b, "List::FindMatching() failed");
+    VerifyOrQuit(prev == &c, "List::FindMatching() failed");
+    VerifyOrQuit(list.FindMatching(a.GetId(), prev) == &a, "List::FindMatching() failed");
+    VerifyOrQuit(prev == &b, "List::FindMatching() failed");
+    VerifyOrQuit(list.FindMatching(e.GetId(), prev) == nullptr, "List::FindMatching() succeeded for a missing entry");
+    VerifyOrQuit(list.FindMatching(e.GetName(), prev) == nullptr, "List::FindMatching() succeeded for a missing entry");
 
     list.SetHead(&e);
-    VerifyLinkedListContent(list, &e, &d, &c, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &e, &d, &c, &b, &a, nullptr);
 
     SuccessOrQuit(list.Remove(c), "LinkedList::Remove() failed");
-    VerifyLinkedListContent(list, &e, &d, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &e, &d, &b, &a, nullptr);
 
     VerifyOrQuit(list.Remove(c) == OT_ERROR_NOT_FOUND, "LinkedList::Remove() failed");
-    VerifyLinkedListContent(list, &e, &d, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &e, &d, &b, &a, nullptr);
+    VerifyOrQuit(list.Find(c, prev) == OT_ERROR_NOT_FOUND, "LinkedList::Find() succeeded for a missing entry");
 
     SuccessOrQuit(list.Remove(e), "LinkedList::Remove() failed");
-    VerifyLinkedListContent(list, &d, &b, &a, NULL);
+    VerifyLinkedListContent(&list, &d, &b, &a, nullptr);
+    VerifyOrQuit(list.Find(e, prev) == OT_ERROR_NOT_FOUND, "LinkedList::Find() succeeded for a missing entry");
 
     SuccessOrQuit(list.Remove(a), "LinkedList::Remove() failed");
-    VerifyLinkedListContent(list, &d, &b, NULL);
+    VerifyLinkedListContent(&list, &d, &b, nullptr);
+    VerifyOrQuit(list.Find(a, prev) == OT_ERROR_NOT_FOUND, "LinkedList::Find() succeeded for a missing entry");
 
     list.Push(a);
     list.Push(c);
     list.Push(e);
-    VerifyLinkedListContent(list, &e, &c, &a, &d, &b, NULL);
+    VerifyLinkedListContent(&list, &e, &c, &a, &d, &b, nullptr);
 
-    VerifyOrQuit(list.PopAfter(a) == &d, "LinkedList::PopAfter() failed");
-    VerifyLinkedListContent(list, &e, &c, &a, &b, NULL);
+    VerifyOrQuit(list.PopAfter(&a) == &d, "LinkedList::PopAfter() failed");
+    VerifyLinkedListContent(&list, &e, &c, &a, &b, nullptr);
 
-    VerifyOrQuit(list.PopAfter(b) == NULL, "LinkedList::PopAfter() failed");
-    VerifyLinkedListContent(list, &e, &c, &a, &b, NULL);
+    VerifyOrQuit(list.PopAfter(&b) == nullptr, "LinkedList::PopAfter() failed");
+    VerifyLinkedListContent(&list, &e, &c, &a, &b, nullptr);
 
-    VerifyOrQuit(list.PopAfter(e) == &c, "LinkedList::PopAfter() failed");
-    VerifyLinkedListContent(list, &e, &a, &b, NULL);
+    VerifyOrQuit(list.PopAfter(&e) == &c, "LinkedList::PopAfter() failed");
+    VerifyLinkedListContent(&list, &e, &a, &b, nullptr);
 
     list.PushAfter(c, b);
-    VerifyLinkedListContent(list, &e, &a, &b, &c, NULL);
+    VerifyLinkedListContent(&list, &e, &a, &b, &c, nullptr);
 
     list.PushAfter(d, a);
-    VerifyLinkedListContent(list, &e, &a, &d, &b, &c, NULL);
+    VerifyLinkedListContent(&list, &e, &a, &d, &b, &c, nullptr);
+
+    VerifyOrQuit(list.PopAfter(nullptr) == &e, "LinkedList::PopAfter() failed");
+    VerifyLinkedListContent(&list, &a, &d, &b, &c, nullptr);
+
+    VerifyOrQuit(list.PopAfter(nullptr) == &a, "LinkedList::PopAfter() failed");
+    VerifyLinkedListContent(&list, &d, &b, &c, nullptr);
+
+    list.Push(e);
+    list.Push(a);
+    VerifyLinkedListContent(&list, &a, &e, &d, &b, &c, nullptr);
+
+    VerifyOrQuit(list.RemoveMatching(a.GetName()) == &a, "LinkedList::RemoveMatching() failed");
+    VerifyLinkedListContent(&list, &e, &d, &b, &c, nullptr);
+
+    VerifyOrQuit(list.RemoveMatching(c.GetId()) == &c, "LinkedList::RemoveMatching() failed");
+    VerifyLinkedListContent(&list, &e, &d, &b, nullptr);
+
+    VerifyOrQuit(list.RemoveMatching(c.GetId()) == nullptr, "LinkedList::RemoveMatching() succeeded for missing entry");
+    VerifyOrQuit(list.RemoveMatching(a.GetName()) == nullptr,
+                 "LinkedList::RemoveMatching() succeeded for missing entry");
+
+    VerifyOrQuit(list.RemoveMatching(d.GetId()) == &d, "LinkedList::RemoveMatching() failed");
+    VerifyLinkedListContent(&list, &e, &b, nullptr);
 
     list.Clear();
     VerifyOrQuit(list.IsEmpty(), "LinkedList::IsEmpty() failed after Clear()");
-    VerifyLinkedListContent(list, NULL);
+    VerifyOrQuit(list.PopAfter(nullptr) == nullptr, "LinkedList::PopAfter() failed");
+    VerifyLinkedListContent(&list, nullptr);
+    VerifyOrQuit(list.Find(a, prev) == OT_ERROR_NOT_FOUND, "LinkedList::Find() succeeded for a missing entry");
+    VerifyOrQuit(list.FindMatching(b.GetName(), prev) == nullptr, "LinkedList::FindMatching() succeeded when empty");
+    VerifyOrQuit(list.FindMatching(c.GetId(), prev) == nullptr, "LinkedList::FindMatching() succeeded when empty");
+    VerifyOrQuit(list.RemoveMatching(a.GetName()) == nullptr, "LinkedList::RemoveMatching() succeeded when empty");
+    VerifyOrQuit(list.Remove(a) == OT_ERROR_NOT_FOUND, "LinkedList::Remove() succeeded when empty");
 }
 
 int main(void)
diff --git a/tests/unit/test_lowpan.cpp b/tests/unit/test_lowpan.cpp
index 1eb8772..db86f84 100644
--- a/tests/unit/test_lowpan.cpp
+++ b/tests/unit/test_lowpan.cpp
@@ -106,10 +106,11 @@
  * This function initializes Thread Interface.
  *
  */
-static void Init()
+static void Init(void)
 {
     otMeshLocalPrefix meshLocalPrefix = {{0xfd, 0x00, 0xca, 0xfe, 0xfa, 0xce, 0x12, 0x34}};
-    sInstance->Get<Mle::MleRouter>().SetMeshLocalPrefix(meshLocalPrefix);
+
+    sInstance->Get<Mle::MleRouter>().SetMeshLocalPrefix(static_cast<Mle::MeshLocalPrefix &>(meshLocalPrefix));
 
     // Emulate global prefixes with contextes.
     uint8_t mockNetworkData[] = {
@@ -128,11 +129,11 @@
     };
 
     Message *message = sInstance->Get<MessagePool>().New(Message::kTypeIp6, 0);
-    VerifyOrQuit(message != NULL, "6lo: Ip6::NewMessage failed");
+    VerifyOrQuit(message != nullptr, "6lo: Ip6::NewMessage failed");
 
     SuccessOrQuit(message->Append(mockNetworkData, sizeof(mockNetworkData)), "6lo: Message::Append failed");
 
-    sInstance->Get<NetworkData::Leader>().SetNetworkData(0, 0, true, *message, 0);
+    IgnoreError(sInstance->Get<NetworkData::Leader>().SetNetworkData(0, 0, true, *message, 0));
 }
 
 /**
@@ -148,7 +149,7 @@
  */
 static void Test(TestIphcVector &aVector, bool aCompress, bool aDecompress)
 {
-    Message *message = NULL;
+    Message *message = nullptr;
     uint8_t  result[512];
     uint8_t  iphc[512];
     uint8_t  ip6[512];
@@ -174,7 +175,7 @@
     {
         Lowpan::BufferWriter buffer(result, 127);
 
-        VerifyOrQuit((message = sInstance->Get<MessagePool>().New(Message::kTypeIp6, 0)) != NULL,
+        VerifyOrQuit((message = sInstance->Get<MessagePool>().New(Message::kTypeIp6, 0)) != nullptr,
                      "6lo: Ip6::NewMessage failed");
 
         aVector.GetUncompressedStream(*message);
@@ -198,12 +199,12 @@
         }
 
         message->Free();
-        message = NULL;
+        message = nullptr;
     }
 
     if (aDecompress)
     {
-        VerifyOrQuit((message = sInstance->Get<MessagePool>().New(Message::kTypeIp6, 0)) != NULL,
+        VerifyOrQuit((message = sInstance->Get<MessagePool>().New(Message::kTypeIp6, 0)) != nullptr,
                      "6lo: Ip6::NewMessage failed");
 
         int decompressedBytes =
@@ -218,7 +219,7 @@
                    iphcLength - static_cast<uint16_t>(decompressedBytes));
 
             DumpBuffer("Resulted IPv6 uncompressed packet", result,
-                       message->GetLength() + iphcLength - decompressedBytes);
+                       message->GetLength() + iphcLength - static_cast<uint16_t>(decompressedBytes));
 
             VerifyOrQuit(decompressedBytes == aVector.mIphcHeader.mLength, "6lo: Lowpan::Decompress failed");
             VerifyOrQuit(message->GetOffset() == aVector.mPayloadOffset, "6lo: Lowpan::Decompress failed");
@@ -231,7 +232,7 @@
         }
 
         message->Free();
-        message = NULL;
+        message = nullptr;
     }
 
     printf("PASS\n\n");
@@ -1744,7 +1745,7 @@
 {
     sInstance = testInitInstance();
 
-    VerifyOrQuit(sInstance != NULL, "NULL instance");
+    VerifyOrQuit(sInstance != nullptr, "nullptr instance");
 
     sIp6    = &sInstance->Get<Ip6::Ip6>();
     sLowpan = &sInstance->Get<Lowpan::Lowpan>();
diff --git a/tests/unit/test_lowpan.hpp b/tests/unit/test_lowpan.hpp
index ae76982..16b5e5a 100644
--- a/tests/unit/test_lowpan.hpp
+++ b/tests/unit/test_lowpan.hpp
@@ -31,6 +31,7 @@
 
 #include <stdint.h>
 
+#include "common/code_utils.hpp"
 #include "common/instance.hpp"
 #include "mac/mac.hpp"
 #include "net/ip6_headers.hpp"
@@ -60,7 +61,7 @@
      */
     TestIphcVector(const char *aTestName)
     {
-        memset(this, 0, sizeof(*this));
+        memset(reinterpret_cast<void *>(this), 0, sizeof(TestIphcVector));
         mTestName              = aTestName;
         mSrcContext.mContextId = kContextUnused;
         mDstContext.mContextId = kContextUnused;
@@ -120,8 +121,8 @@
         mIpHeader.SetPayloadLength(aPayloadLength);
         mIpHeader.SetNextHeader(aNextHeader);
         mIpHeader.SetHopLimit(aHopLimit);
-        mIpHeader.GetSource().FromString(aSource);
-        mIpHeader.GetDestination().FromString(aDestination);
+        IgnoreError(mIpHeader.GetSource().FromString(aSource));
+        IgnoreError(mIpHeader.GetDestination().FromString(aDestination));
     }
 
     /**
@@ -146,8 +147,8 @@
         mIpTunneledHeader.SetPayloadLength(aPayloadLength);
         mIpTunneledHeader.SetNextHeader(aNextHeader);
         mIpTunneledHeader.SetHopLimit(aHopLimit);
-        mIpTunneledHeader.GetSource().FromString(aSource);
-        mIpTunneledHeader.GetDestination().FromString(aDestination);
+        IgnoreError(mIpTunneledHeader.GetSource().FromString(aSource));
+        IgnoreError(mIpTunneledHeader.GetDestination().FromString(aDestination));
     }
 
     /**
@@ -252,12 +253,12 @@
      * This fields represent uncompressed IPv6 packet.
      *
      */
-    Mac::Address   mMacSource;
-    Mac::Address   mMacDestination;
-    Ip6::Header    mIpHeader;
-    Payload        mExtHeader;
-    Ip6::Header    mIpTunneledHeader;
-    Ip6::UdpHeader mUdpHeader;
+    Mac::Address     mMacSource;
+    Mac::Address     mMacDestination;
+    Ip6::Header      mIpHeader;
+    Payload          mExtHeader;
+    Ip6::Header      mIpTunneledHeader;
+    Ip6::Udp::Header mUdpHeader;
 
     /**
      * This fields represent compressed IPv6 packet.
diff --git a/tests/unit/test_mac_frame.cpp b/tests/unit/test_mac_frame.cpp
index e573645..c7a4b24 100644
--- a/tests/unit/test_mac_frame.cpp
+++ b/tests/unit/test_mac_frame.cpp
@@ -64,7 +64,7 @@
     uint8_t         buffer[OT_EXT_ADDRESS_SIZE];
 
     instance = testInitInstance();
-    VerifyOrQuit(instance != NULL, "NULL instance\n");
+    VerifyOrQuit(instance != nullptr, "nullptr instance\n");
 
     // Mac::ExtAddress
 
@@ -179,55 +179,55 @@
 
     CompareNetworkName(networkName, kEmptyName);
 
-    SuccessOrQuit(networkName.Set(Mac::NetworkName::Data(kName1, sizeof(kName1))), "NetworkName::Set() failed");
+    SuccessOrQuit(networkName.Set(Mac::NameData(kName1, sizeof(kName1))), "NetworkName::Set() failed");
     CompareNetworkName(networkName, kName1);
 
-    VerifyOrQuit(networkName.Set(Mac::NetworkName::Data(kName1, sizeof(kName1))) == OT_ERROR_ALREADY,
+    VerifyOrQuit(networkName.Set(Mac::NameData(kName1, sizeof(kName1))) == OT_ERROR_ALREADY,
                  "NetworkName::Set() accepted same name without returning OT_ERROR_ALREADY");
     CompareNetworkName(networkName, kName1);
 
-    VerifyOrQuit(networkName.Set(Mac::NetworkName::Data(kName1, sizeof(kName1) - 1)) == OT_ERROR_ALREADY,
+    VerifyOrQuit(networkName.Set(Mac::NameData(kName1, sizeof(kName1) - 1)) == OT_ERROR_ALREADY,
                  "NetworkName::Set() accepted same name without returning OT_ERROR_ALREADY");
 
-    SuccessOrQuit(networkName.Set(Mac::NetworkName::Data(kName2, sizeof(kName2))), "NetworkName::Set() failed");
+    SuccessOrQuit(networkName.Set(Mac::NameData(kName2, sizeof(kName2))), "NetworkName::Set() failed");
     CompareNetworkName(networkName, kName2);
 
-    SuccessOrQuit(networkName.Set(Mac::NetworkName::Data(kEmptyName, 0)), "NetworkName::Set() failed");
+    SuccessOrQuit(networkName.Set(Mac::NameData(kEmptyName, 0)), "NetworkName::Set() failed");
     CompareNetworkName(networkName, kEmptyName);
 
-    SuccessOrQuit(networkName.Set(Mac::NetworkName::Data(kLongName, sizeof(kLongName))), "NetworkName::Set() failed");
+    SuccessOrQuit(networkName.Set(Mac::NameData(kLongName, sizeof(kLongName))), "NetworkName::Set() failed");
     CompareNetworkName(networkName, kLongName);
 
-    VerifyOrQuit(networkName.Set(Mac::NetworkName::Data(kLongName, sizeof(kLongName) - 1)) == OT_ERROR_ALREADY,
+    VerifyOrQuit(networkName.Set(Mac::NameData(kLongName, sizeof(kLongName) - 1)) == OT_ERROR_ALREADY,
                  "NetworkName::Set() accepted same name without returning OT_ERROR_ALREADY");
 
-    SuccessOrQuit(networkName.Set(Mac::NetworkName::Data(NULL, 0)), "NetworkName::Set() failed");
+    SuccessOrQuit(networkName.Set(Mac::NameData(nullptr, 0)), "NetworkName::Set() failed");
     CompareNetworkName(networkName, kEmptyName);
 
-    SuccessOrQuit(networkName.Set(Mac::NetworkName::Data(kName1, sizeof(kName1))), "NetworkName::Set() failed");
+    SuccessOrQuit(networkName.Set(Mac::NameData(kName1, sizeof(kName1))), "NetworkName::Set() failed");
 
-    VerifyOrQuit(networkName.Set(Mac::NetworkName::Data(kTooLongName, sizeof(kTooLongName))) == OT_ERROR_INVALID_ARGS,
+    VerifyOrQuit(networkName.Set(Mac::NameData(kTooLongName, sizeof(kTooLongName))) == OT_ERROR_INVALID_ARGS,
                  "NetworkName::Set() accepted an invalid (too long) name");
 
     CompareNetworkName(networkName, kName1);
 
     memset(buffer, 'a', sizeof(buffer));
     len = networkName.GetAsData().CopyTo(buffer, 1);
-    VerifyOrQuit(len == 1, "NetworkName::Data::CopyTo() failed");
-    VerifyOrQuit(buffer[0] == kName1[0], "NetworkName::Data::CopyTo() failed");
-    VerifyOrQuit(buffer[1] == 'a', "NetworkName::Data::CopyTo() failed");
+    VerifyOrQuit(len == 1, "NameData::CopyTo() failed");
+    VerifyOrQuit(buffer[0] == kName1[0], "NameData::CopyTo() failed");
+    VerifyOrQuit(buffer[1] == 'a', "NameData::CopyTo() failed");
 
     memset(buffer, 'a', sizeof(buffer));
     len = networkName.GetAsData().CopyTo(buffer, sizeof(kName1) - 1);
-    VerifyOrQuit(len == sizeof(kName1) - 1, "NetworkName::Data::CopyTo() failed");
-    VerifyOrQuit(memcmp(buffer, kName1, sizeof(kName1) - 1) == 0, "NetworkName::Data::CopyTo() failed");
-    VerifyOrQuit(buffer[sizeof(kName1)] == 'a', "NetworkName::Data::CopyTo() failed");
+    VerifyOrQuit(len == sizeof(kName1) - 1, "NameData::CopyTo() failed");
+    VerifyOrQuit(memcmp(buffer, kName1, sizeof(kName1) - 1) == 0, "NameData::CopyTo() failed");
+    VerifyOrQuit(buffer[sizeof(kName1)] == 'a', "NameData::CopyTo() failed");
 
     memset(buffer, 'a', sizeof(buffer));
     len = networkName.GetAsData().CopyTo(buffer, sizeof(buffer));
-    VerifyOrQuit(len == sizeof(kName1) - 1, "NetworkName::Data::CopyTo() failed");
-    VerifyOrQuit(memcmp(buffer, kName1, sizeof(kName1) - 1) == 0, "NetworkName::Data::CopyTo() failed");
-    VerifyOrQuit(buffer[sizeof(kName1)] == 0, "NetworkName::Data::CopyTo() failed");
+    VerifyOrQuit(len == sizeof(kName1) - 1, "NameData::CopyTo() failed");
+    VerifyOrQuit(memcmp(buffer, kName1, sizeof(kName1) - 1) == 0, "NameData::CopyTo() failed");
+    VerifyOrQuit(buffer[sizeof(kName1)] == 0, "NameData::CopyTo() failed");
 }
 
 void TestMacHeader(void)
@@ -237,36 +237,37 @@
         uint16_t fcf;
         uint8_t  secCtl;
         uint8_t  headerLength;
+        uint8_t  footerLength;
     } tests[] = {
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrNone, 0, 3},
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrShort, 0, 7},
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrExt, 0, 13},
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrNone, 0, 7},
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrNone, 0, 13},
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort, 0, 11},
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrExt, 0, 17},
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrShort, 0, 17},
-        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrExt, 0, 23},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrNone, 0, 3, 2},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrShort, 0, 7, 2},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrExt, 0, 13, 2},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrNone, 0, 7, 2},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrNone, 0, 13, 2},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort, 0, 11, 2},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrExt, 0, 17, 2},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrShort, 0, 17, 2},
+        {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrExt, 0, 23, 2},
 
         {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort |
              Mac::Frame::kFcfPanidCompression,
-         0, 9},
+         0, 9, 2},
         {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrExt |
              Mac::Frame::kFcfPanidCompression,
-         0, 15},
+         0, 15, 2},
         {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrShort |
              Mac::Frame::kFcfPanidCompression,
-         0, 15},
+         0, 15, 2},
         {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrExt |
              Mac::Frame::kFcfPanidCompression,
-         0, 21},
+         0, 21, 2},
 
         {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort |
              Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfSecurityEnabled,
-         Mac::Frame::kSecMic32 | Mac::Frame::kKeyIdMode1, 15},
+         Mac::Frame::kSecMic32 | Mac::Frame::kKeyIdMode1, 15, 6},
         {Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort |
              Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfSecurityEnabled,
-         Mac::Frame::kSecMic32 | Mac::Frame::kKeyIdMode2, 19},
+         Mac::Frame::kSecMic32 | Mac::Frame::kKeyIdMode2, 19, 6},
     };
 
     for (unsigned i = 0; i < OT_ARRAY_LENGTH(tests); i++)
@@ -274,11 +275,13 @@
         uint8_t      psdu[Mac::Frame::kMtu];
         Mac::TxFrame frame;
 
-        frame.mPsdu = psdu;
+        frame.mPsdu   = psdu;
+        frame.mLength = 0;
 
         frame.InitMacHeader(tests[i].fcf, tests[i].secCtl);
-        printf("%d\n", frame.GetHeaderLength());
         VerifyOrQuit(frame.GetHeaderLength() == tests[i].headerLength, "MacHeader test failed");
+        VerifyOrQuit(frame.GetFooterLength() == tests[i].footerLength, "MacHeader test failed");
+        VerifyOrQuit(frame.GetLength() == tests[i].headerLength + tests[i].footerLength, "MacHeader test failed");
     }
 }
 
@@ -360,7 +363,7 @@
 
     mask1.Clear();
     VerifyOrQuit(mask1.IsEmpty(), "ChannelMask.IsEmpty failed");
-    VerifyChannelMaskContent(mask1, NULL, 0);
+    VerifyChannelMaskContent(mask1, nullptr, 0);
 
     for (uint16_t index = 0; index < sizeof(channels1); index++)
     {
@@ -405,6 +408,201 @@
     VerifyOrQuit(mask1 != mask2, "ChannelMask.operator== failed");
 }
 
+void TestMacFrameApi(void)
+{
+    uint8_t ack_psdu1[] = {0x02, 0x10, 0x5e, 0xd2, 0x9b};
+
+    Mac::Frame frame;
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    uint8_t data_psdu1[] = {0x29, 0xee, 0x53, 0xce, 0xfa, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x6e, 0x16, 0x05,
+                            0x00, 0x00, 0x00, 0x00, 0x0a, 0x6e, 0x16, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x01};
+    otError error;
+    uint8_t scf; // SecurityControlField
+#endif
+
+    // Imm-Ack, Sequence Number: 94
+    //   Frame Control Field: 0x1002
+    //     .... .... .... .010 = Frame Type: Ack (0x2)
+    //     .... .... .... 0... = Security Enabled: False
+    //     .... .... ...0 .... = Frame Pending: False
+    //     .... .... ..0. .... = Acknowledge Request: False
+    //     .... .... .0.. .... = PAN ID Compression: False
+    //     .... ...0 .... .... = Sequence Number Suppression: False
+    //     .... ..0. .... .... = Information Elements Present: False
+    //     .... 00.. .... .... = Destination Addressing Mode: None (0x0)
+    //     ..01 .... .... .... = Frame Version: IEEE Std 802.15.4-2006 (1)
+    //     00.. .... .... .... = Source Addressing Mode: None (0x0)
+    //   Sequence Number: 94
+    //   FCS: 0x9bd2 (Correct)
+    frame.mPsdu   = ack_psdu1;
+    frame.mLength = sizeof(ack_psdu1);
+    VerifyOrQuit(frame.GetType() == Mac::Frame::kFcfFrameAck, "Mac::Frame::GetType() failed\n");
+    VerifyOrQuit(frame.GetSecurityEnabled() == false, "Mac::Frame::GetSecurityEnabled() failed\n");
+    VerifyOrQuit(frame.GetFramePending() == false, "Mac::Frame::GetFramePendIng() failed\n");
+    VerifyOrQuit(frame.GetAckRequest() == false, "Mac::Frame::GetAckRequest failed\n");
+    VerifyOrQuit(frame.IsIePresent() == false, "Mac::Frame::IsIePresent failed\n");
+    VerifyOrQuit(frame.IsDstPanIdPresent() == false, "Mac::Frame::IsDstPanIdPresent failed\n");
+    VerifyOrQuit(frame.IsDstAddrPresent() == false, "Mac::Frame::IsDstAddrPresent failed\n");
+    VerifyOrQuit(frame.GetVersion() == Mac::Frame::kFcfFrameVersion2006, "Mac::Frame::GetVersion failed\n");
+    VerifyOrQuit(frame.IsSrcAddrPresent() == false, "Mac::Frame::IsSrcAddrPresent failed\n");
+    VerifyOrQuit(frame.GetSequence() == 94, "Mac::Frame::GetSequence failed\n");
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    // IEEE 802.15.4-2015 Data
+    //   Sequence Number: 83
+    //   Destination PAN: 0xface
+    //   Destination: 16:6e:0a:00:00:00:00:01
+    //   Extended Source: 16:6e:0a:00:00:00:00:05
+    //   Auxiliary Security Header
+    //     Security Control Field: 0x0d
+    frame.mPsdu   = data_psdu1;
+    frame.mLength = sizeof(data_psdu1);
+    VerifyOrQuit(frame.IsVersion2015() == true, "Mac::Frame::IsVersion2015 failed\n");
+    VerifyOrQuit(frame.IsDstPanIdPresent() == true, "Mac::Frame::IsDstPanIdPresent failed\n");
+    VerifyOrQuit(frame.IsDstAddrPresent() == true, "Mac::Frame::IsDstAddrPresent failed\n");
+    VerifyOrQuit(frame.IsSrcAddrPresent() == true, "Mac::Frame::IsSrcAddrPresent failed\n");
+    VerifyOrQuit((error = frame.GetSecurityControlField(scf)) == OT_ERROR_NONE,
+                 "Mac::Frame::GetSecurityControlField failed\n");
+    VerifyOrQuit(scf == 0x0d, "Mac::Frame::GetSecurityControlField value failed\n");
+    frame.SetSecurityControlField(0xff);
+    VerifyOrQuit((error = frame.GetSecurityControlField(scf)) == OT_ERROR_NONE,
+                 "Mac::Frame::GetSecurityControlField failed\n");
+    VerifyOrQuit(scf == 0xff, "Mac::Frame::SetSecurityControlField value failed\n");
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
+}
+
+void TestMacFrameAckGeneration(void)
+{
+    Mac::RxFrame receivedFrame;
+    Mac::TxFrame ackFrame;
+    uint8_t      ackFrameBuffer[100];
+
+    ackFrame.mPsdu   = ackFrameBuffer;
+    ackFrame.mLength = sizeof(ackFrameBuffer);
+
+    // Received Frame 1
+    // IEEE 802.15.4 Data
+    //   Frame Control Field: 0xdc61
+    //     .... .... .... .001 = Frame Type: Data (0x1)
+    //     .... .... .... 0... = Security Enabled: False
+    //     .... .... ...0 .... = Frame Pending: False
+    //     .... .... ..1. .... = Acknowledge Request: True
+    //     .... .... .1.. .... = PAN ID Compression: True
+    //     .... ...0 .... .... = Sequence Number Suppression: False
+    //     .... ..0. .... .... = Information Elements Present: False
+    //     .... 11.. .... .... = Destination Addressing Mode: Long/64-bit (0x3)
+    //     ..01 .... .... .... = Frame Version: IEEE Std 802.15.4-2006 (1)
+    //     11.. .... .... .... = Source Addressing Mode: Long/64-bit (0x3)
+    //  Sequence Number: 189
+    //  Destination PAN: 0xface
+    //  Destination: 16:6e:0a:00:00:00:00:01 (16:6e:0a:00:00:00:00:01)
+    //  Extended Source: 16:6e:0a:00:00:00:00:02 (16:6e:0a:00:00:00:00:02)
+    uint8_t data_psdu1[]  = {0x61, 0xdc, 0xbd, 0xce, 0xfa, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x6e, 0x16, 0x02,
+                            0x00, 0x00, 0x00, 0x00, 0x0a, 0x6e, 0x16, 0x7f, 0x33, 0xf0, 0x4d, 0x4c, 0x4d, 0x4c,
+                            0x8b, 0xf0, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc2,
+                            0x57, 0x9c, 0x31, 0xb3, 0x2a, 0xa1, 0x86, 0xba, 0x9a, 0xed, 0x5a, 0xb9, 0xa3, 0x59,
+                            0x88, 0xeb, 0xbb, 0x0d, 0xc3, 0xed, 0xeb, 0x8a, 0x53, 0xa6, 0xed, 0xf7, 0xdd, 0x45,
+                            0x6e, 0xf7, 0x9a, 0x17, 0xb4, 0xab, 0xc6, 0x75, 0x71, 0x46, 0x37, 0x93, 0x4a, 0x32,
+                            0xb1, 0x21, 0x9f, 0x9d, 0xb3, 0x65, 0x27, 0xd5, 0xfc, 0x50, 0x16, 0x90, 0xd2, 0xd4};
+    receivedFrame.mPsdu   = data_psdu1;
+    receivedFrame.mLength = sizeof(data_psdu1);
+
+    ackFrame.GenerateImmAck(receivedFrame, false);
+    VerifyOrQuit(ackFrame.mLength == Mac::Frame::kImmAckLength,
+                 "Mac::Frame::GenerateImmAck() failed, length incorrect\n");
+    VerifyOrQuit(ackFrame.GetType() == Mac::Frame::kFcfFrameAck,
+                 "Mac::Frame::GenerateImmAck() failed, GetType() incorrect\n");
+    VerifyOrQuit(ackFrame.GetSecurityEnabled() == false,
+                 "Mac::Frame::GenerateImmAck failed, GetSecurityEnabled() incorrect\n");
+    VerifyOrQuit(ackFrame.GetFramePending() == false,
+                 "Mac::Frame::GenerateImmAck failed, GetFramePending() incorrect\n");
+    VerifyOrQuit(ackFrame.GetAckRequest() == false, "Mac::Frame::GenerateImmAck failed, GetAckRequest() incorrect\n");
+    VerifyOrQuit(ackFrame.IsIePresent() == false, "Mac::Frame::GenerateImmAck failed, IsIePresent() incorrect\n");
+    VerifyOrQuit(ackFrame.IsDstPanIdPresent() == false,
+                 "Mac::Frame::GenerateImmAck failed, IsDstPanIdPresent() incorrect\n");
+    VerifyOrQuit(ackFrame.IsDstAddrPresent() == false,
+                 "Mac::Frame::GenerateImmAck failed, IsDstAddrPresent() incorrect\n");
+    VerifyOrQuit(ackFrame.IsSrcAddrPresent() == false,
+                 "Mac::Frame::GenerateImmAck failed, IsSrcAddrPresent() incorrect\n");
+    VerifyOrQuit(ackFrame.GetVersion() == Mac::Frame::kFcfFrameVersion2006,
+                 "Mac::Frame::GenerateImmAck failed, GetVersion() incorrect\n");
+    VerifyOrQuit(ackFrame.GetSequence() == 189, "Mac::Frame::GenerateImmAck failed, GetSequence() incorrect\n");
+
+#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+    // Received Frame 2
+    // IEEE 802.15.4 Data
+    //   Frame Control Field: 0xa869, Frame Type: Data, Security Enabled, Acknowledge Request, PAN ID Compression,
+    //   Destination Addressing Mode: Short/16-bit, Frame Version: IEEE Std 802.15.4-2015, Source Addressing Mode:
+    //   Short/16-bit
+    //     .... .... .... .001 = Frame Type: Data (0x1)
+    //     .... .... .... 1... = Security Enabled: True
+    //     .... .... ...0 .... = Frame Pending: False
+    //     .... .... ..1. .... = Acknowledge Request: True
+    //     .... .... .1.. .... = PAN ID Compression: True
+    //     .... ...0 .... .... = Sequence Number Suppression: False
+    //     .... ..0. .... .... = Information Elements Present: False
+    //     .... 10.. .... .... = Destination Addressing Mode: Short/16-bit (0x2)
+    //     ..10 .... .... .... = Frame Version: IEEE Std 802.15.4-2015 (2)
+    //     10.. .... .... .... = Source Addressing Mode: Short/16-bit (0x2)
+    //   Sequence Number: 142
+    //   Destination PAN: 0xface
+    //   Destination: 0x2402
+    //   Source: 0x2400
+    //   [Extended Source: 16:6e:0a:00:00:00:00:01 (16:6e:0a:00:00:00:00:01)]
+    //   [Origin: 2]
+    //   Auxiliary Security Header
+    //     Security Control Field: 0x0d, Security Level: Encryption with 32-bit Message Integrity Code, Key Identifier
+    //     Mode: Indexed Key using the Default Key Source
+    //       .... .101 = Security Level: Encryption with 32-bit Message Integrity Code (0x5)
+    //       ...0 1... = Key Identifier Mode: Indexed Key using the Default Key Source (0x1)
+    //       ..0. .... = Frame Counter Suppression: False
+    //       .0.. .... = ASN in Nonce: False
+    //       0... .... = Reserved: 0x0
+    //     Frame Counter: 2
+    //     Key Identifier Field
+    //       Key Index: 0x01
+    //   MIC: f94e5870
+    //   [Key Number: 0]
+    //   FCS: 0x8c40 (Correct)
+    uint8_t data_psdu2[]  = {0x69, 0xa8, 0x8e, 0xce, 0xfa, 0x02, 0x24, 0x00, 0x24, 0x0d, 0x02,
+                            0x00, 0x00, 0x00, 0x01, 0x6b, 0x64, 0x60, 0x08, 0x55, 0xb8, 0x10,
+                            0x18, 0xc7, 0x40, 0x2e, 0xfb, 0xf3, 0xda, 0xf9, 0x4e, 0x58, 0x70};
+    receivedFrame.mPsdu   = data_psdu2;
+    receivedFrame.mLength = sizeof(data_psdu2);
+
+    uint8_t     ie_data[6] = {0x04, 0x0d, 0x21, 0x0c, 0x35, 0x0c};
+    Mac::CslIe *csl;
+
+    IgnoreError(ackFrame.GenerateEnhAck(receivedFrame, false, ie_data, sizeof(ie_data)));
+    csl = reinterpret_cast<Mac::CslIe *>(ackFrame.GetHeaderIe(Mac::Frame::kHeaderIeCsl) + sizeof(Mac::HeaderIe));
+    VerifyOrQuit(ackFrame.mLength == 23,
+                 "Mac::Frame::GenerateEnhAck() failed, length incorrect\n"); // 23 is the length of the correct ack
+    VerifyOrQuit(ackFrame.GetType() == Mac::Frame::kFcfFrameAck,
+                 "Mac::Frame::GenerateEnhAck() failed, GetType() incorrect\n");
+    VerifyOrQuit(ackFrame.GetSecurityEnabled() == true,
+                 "Mac::Frame::GenerateEnhAck failed, GetSecurityEnabled() incorrect\n");
+    VerifyOrQuit(ackFrame.IsIePresent() == true, "Mac::Frame::GenerateEnhAck failed, IsIePresent() incorrect\n");
+    VerifyOrQuit(ackFrame.IsDstPanIdPresent() == false,
+                 "Mac::Frame::GenerateEnhAck failed, IsDstPanIdPresent() incorrect\n");
+    VerifyOrQuit(ackFrame.IsDstAddrPresent() == true,
+                 "Mac::Frame::GenerateEnhAck failed, IsDstAddrPresent() incorrect\n");
+    VerifyOrQuit(ackFrame.IsSrcAddrPresent() == false,
+                 "Mac::Frame::GenerateEnhAck failed, IsSrcAddrPresent() incorrect\n");
+    VerifyOrQuit(ackFrame.GetVersion() == Mac::Frame::kFcfFrameVersion2015,
+                 "Mac::Frame::GenerateEnhAck failed, GetVersion() incorrect\n");
+    VerifyOrQuit(ackFrame.GetSequence() == 142, "Mac::Frame::GenerateEnhAck failed, GetSequence() incorrect\n");
+    VerifyOrQuit(csl->GetPeriod() == 3125 && csl->GetPhase() == 3105,
+                 "Mac::Frame::GenerateEnhAck failed, CslIe incorrect\n");
+
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+    ackFrame.SetCslIe(123, 456);
+    csl = reinterpret_cast<Mac::CslIe *>(ackFrame.GetHeaderIe(Mac::Frame::kHeaderIeCsl) + sizeof(Mac::HeaderIe));
+    VerifyOrQuit(csl->GetPeriod() == 123 && csl->GetPhase() == 456, "Mac::Frame::SetCslIe failed, CslIe incorrect\n");
+#endif
+#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
+}
+
 } // namespace ot
 
 int main(void)
@@ -413,6 +611,8 @@
     ot::TestMacNetworkName();
     ot::TestMacHeader();
     ot::TestMacChannelMask();
+    ot::TestMacFrameApi();
+    ot::TestMacFrameAckGeneration();
     printf("All tests passed\n");
     return 0;
 }
diff --git a/tests/unit/test_message.cpp b/tests/unit/test_message.cpp
index 80cf7d8..7ad0490 100644
--- a/tests/unit/test_message.cpp
+++ b/tests/unit/test_message.cpp
@@ -42,7 +42,7 @@
     uint8_t          readBuffer[1024];
 
     instance = static_cast<ot::Instance *>(testInitInstance());
-    VerifyOrQuit(instance != NULL, "Null OpenThread instance\n");
+    VerifyOrQuit(instance != nullptr, "Null OpenThread instance\n");
 
     messagePool = &instance->Get<ot::MessagePool>();
 
@@ -51,7 +51,7 @@
         writeBuffer[i] = static_cast<uint8_t>(random());
     }
 
-    VerifyOrQuit((message = messagePool->New(ot::Message::kTypeIp6, 0)) != NULL, "Message::New failed");
+    VerifyOrQuit((message = messagePool->New(ot::Message::kTypeIp6, 0)) != nullptr, "Message::New failed");
     SuccessOrQuit(message->SetLength(sizeof(writeBuffer)), "Message::SetLength failed");
     VerifyOrQuit(message->Write(0, sizeof(writeBuffer), writeBuffer) == sizeof(writeBuffer), "Message::Write failed");
     VerifyOrQuit(message->Read(0, sizeof(readBuffer), readBuffer) == sizeof(readBuffer), "Message::Read failed");
diff --git a/tests/unit/test_message_queue.cpp b/tests/unit/test_message_queue.cpp
index 911b07c..35af431 100644
--- a/tests/unit/test_message_queue.cpp
+++ b/tests/unit/test_message_queue.cpp
@@ -55,11 +55,11 @@
     if (aExpectedLength == 0)
     {
         message = aMessageQueue.GetHead();
-        VerifyOrQuit(message == NULL, "MessageQueue is not empty when expected len is zero.");
+        VerifyOrQuit(message == nullptr, "MessageQueue is not empty when expected len is zero.");
     }
     else
     {
-        for (message = aMessageQueue.GetHead(); message != NULL; message = message->GetNext())
+        for (message = aMessageQueue.GetHead(); message != nullptr; message = message->GetNext())
         {
             VerifyOrQuit(aExpectedLength != 0, "MessageQueue contains more entries than expected");
 
@@ -79,45 +79,43 @@
 {
     ot::MessageQueue messageQueue;
     ot::Message *    msg[kNumTestMessages];
-    otError          error;
     uint16_t         msgCount, bufferCount;
 
     sInstance = testInitInstance();
-    VerifyOrQuit(sInstance != NULL, "Null instance");
+    VerifyOrQuit(sInstance != nullptr, "Null instance");
 
     sMessagePool = &sInstance->Get<ot::MessagePool>();
 
     for (int i = 0; i < kNumTestMessages; i++)
     {
         msg[i] = sMessagePool->New(ot::Message::kTypeIp6, 0);
-        VerifyOrQuit(msg[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msg[i] != nullptr, "Message::New failed");
     }
 
     VerifyMessageQueueContent(messageQueue, 0);
 
     // Enqueue 1 message and remove it
-    SuccessOrQuit(messageQueue.Enqueue(*msg[0]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[0]);
     VerifyMessageQueueContent(messageQueue, 1, msg[0]);
-    SuccessOrQuit(messageQueue.Dequeue(*msg[0]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[0]);
     VerifyMessageQueueContent(messageQueue, 0);
 
     // Enqueue 1 message at head and remove it
-    SuccessOrQuit(messageQueue.Enqueue(*msg[0], ot::MessageQueue::kQueuePositionHead),
-                  "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[0], ot::MessageQueue::kQueuePositionHead);
     VerifyMessageQueueContent(messageQueue, 1, msg[0]);
-    SuccessOrQuit(messageQueue.Dequeue(*msg[0]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[0]);
     VerifyMessageQueueContent(messageQueue, 0);
 
     // Enqueue 5 messages
-    SuccessOrQuit(messageQueue.Enqueue(*msg[0]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[0]);
     VerifyMessageQueueContent(messageQueue, 1, msg[0]);
-    SuccessOrQuit(messageQueue.Enqueue(*msg[1]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[1]);
     VerifyMessageQueueContent(messageQueue, 2, msg[0], msg[1]);
-    SuccessOrQuit(messageQueue.Enqueue(*msg[2]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[2]);
     VerifyMessageQueueContent(messageQueue, 3, msg[0], msg[1], msg[2]);
-    SuccessOrQuit(messageQueue.Enqueue(*msg[3]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[3]);
     VerifyMessageQueueContent(messageQueue, 4, msg[0], msg[1], msg[2], msg[3]);
-    SuccessOrQuit(messageQueue.Enqueue(*msg[4]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[4]);
     VerifyMessageQueueContent(messageQueue, 5, msg[0], msg[1], msg[2], msg[3], msg[4]);
 
     // Check the GetInfo()
@@ -125,68 +123,57 @@
     VerifyOrQuit(msgCount == 5, "MessageQueue::GetInfo() failed.");
 
     // Remove from head
-    SuccessOrQuit(messageQueue.Dequeue(*msg[0]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[0]);
     VerifyMessageQueueContent(messageQueue, 4, msg[1], msg[2], msg[3], msg[4]);
 
     // Remove a message in middle
-    SuccessOrQuit(messageQueue.Dequeue(*msg[3]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[3]);
     VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[2], msg[4]);
 
     // Remove from tail
-    SuccessOrQuit(messageQueue.Dequeue(*msg[4]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[4]);
     VerifyMessageQueueContent(messageQueue, 2, msg[1], msg[2]);
 
     // Add after remove
-    SuccessOrQuit(messageQueue.Enqueue(*msg[0]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[0]);
     VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[2], msg[0]);
-    SuccessOrQuit(messageQueue.Enqueue(*msg[3]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[3]);
     VerifyMessageQueueContent(messageQueue, 4, msg[1], msg[2], msg[0], msg[3]);
 
     // Remove from middle
-    SuccessOrQuit(messageQueue.Dequeue(*msg[2]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[2]);
     VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[0], msg[3]);
 
     // Add to head
-    SuccessOrQuit(messageQueue.Enqueue(*msg[2], ot::MessageQueue::kQueuePositionHead),
-                  "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[2], ot::MessageQueue::kQueuePositionHead);
     VerifyMessageQueueContent(messageQueue, 4, msg[2], msg[1], msg[0], msg[3]);
 
     // Remove from head
-    SuccessOrQuit(messageQueue.Dequeue(*msg[2]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[2]);
     VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[0], msg[3]);
 
     // Remove from head
-    SuccessOrQuit(messageQueue.Dequeue(*msg[1]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[1]);
     VerifyMessageQueueContent(messageQueue, 2, msg[0], msg[3]);
 
     // Add to head
-    SuccessOrQuit(messageQueue.Enqueue(*msg[1], ot::MessageQueue::kQueuePositionHead),
-                  "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[1], ot::MessageQueue::kQueuePositionHead);
     VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[0], msg[3]);
 
     // Add to tail
-    SuccessOrQuit(messageQueue.Enqueue(*msg[2], ot::MessageQueue::kQueuePositionTail),
-                  "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msg[2], ot::MessageQueue::kQueuePositionTail);
     VerifyMessageQueueContent(messageQueue, 4, msg[1], msg[0], msg[3], msg[2]);
 
     // Remove all messages.
-    SuccessOrQuit(messageQueue.Dequeue(*msg[3]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[3]);
     VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[0], msg[2]);
-    SuccessOrQuit(messageQueue.Dequeue(*msg[1]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[1]);
     VerifyMessageQueueContent(messageQueue, 2, msg[0], msg[2]);
-    SuccessOrQuit(messageQueue.Dequeue(*msg[2]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[2]);
     VerifyMessageQueueContent(messageQueue, 1, msg[0]);
-    SuccessOrQuit(messageQueue.Dequeue(*msg[0]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msg[0]);
     VerifyMessageQueueContent(messageQueue, 0);
 
-    // Check the failure cases: Enqueue an already queued message or dequeue a message not in the queue.
-    SuccessOrQuit(messageQueue.Enqueue(*msg[0]), "MessageQueue::Enqueue() failed.");
-    VerifyMessageQueueContent(messageQueue, 1, msg[0]);
-    error = messageQueue.Enqueue(*msg[0]);
-    VerifyOrQuit(error == OT_ERROR_ALREADY, "Enqueuing an already queued message did not fail as expected.");
-    error = messageQueue.Dequeue(*msg[1]);
-    VerifyOrQuit(error == OT_ERROR_NOT_FOUND, "Dequeuing a message not in the queue did not fail as expected.");
-
     testFreeInstance(sInstance);
 }
 
@@ -202,11 +189,12 @@
     if (aExpectedLength == 0)
     {
         message = otMessageQueueGetHead(aQueue);
-        VerifyOrQuit(message == NULL, "MessageQueue is not empty when expected len is zero.");
+        VerifyOrQuit(message == nullptr, "MessageQueue is not empty when expected len is zero.");
     }
     else
     {
-        for (message = otMessageQueueGetHead(aQueue); message != NULL; message = otMessageQueueGetNext(aQueue, message))
+        for (message = otMessageQueueGetHead(aQueue); message != nullptr;
+             message = otMessageQueueGetNext(aQueue, message))
         {
             VerifyOrQuit(aExpectedLength != 0, "MessageQueue contains more entries than expected");
 
@@ -226,17 +214,16 @@
 void TestMessageQueueOtApis(void)
 {
     otMessage *    msg[kNumTestMessages];
-    otError        error;
     otMessage *    message;
     otMessageQueue queue, queue2;
 
     sInstance = testInitInstance();
-    VerifyOrQuit(sInstance != NULL, "Null instance");
+    VerifyOrQuit(sInstance != nullptr, "Null instance");
 
     for (int i = 0; i < kNumTestMessages; i++)
     {
-        msg[i] = otIp6NewMessage(sInstance, NULL);
-        VerifyOrQuit(msg[i] != NULL, "otIp6NewMessage() failed.");
+        msg[i] = otIp6NewMessage(sInstance, nullptr);
+        VerifyOrQuit(msg[i] != nullptr, "otIp6NewMessage() failed.");
     }
 
     otMessageQueueInit(&queue);
@@ -246,48 +233,42 @@
     VerifyMessageQueueContentUsingOtApi(&queue, 0);
 
     // Add message to the queue and check the content
-    SuccessOrQuit(otMessageQueueEnqueue(&queue, msg[0]), "Failed to enqueue a message to otMessageQueue.");
+    otMessageQueueEnqueue(&queue, msg[0]);
     VerifyMessageQueueContentUsingOtApi(&queue, 1, msg[0]);
-    SuccessOrQuit(otMessageQueueEnqueue(&queue, msg[1]), "Failed to enqueue a message to otMessageQueue.");
+    otMessageQueueEnqueue(&queue, msg[1]);
     VerifyMessageQueueContentUsingOtApi(&queue, 2, msg[0], msg[1]);
-    SuccessOrQuit(otMessageQueueEnqueueAtHead(&queue, msg[2]), "Failed to enqueue a message to otMessageQueue.");
+    otMessageQueueEnqueueAtHead(&queue, msg[2]);
     VerifyMessageQueueContentUsingOtApi(&queue, 3, msg[2], msg[0], msg[1]);
-    SuccessOrQuit(otMessageQueueEnqueue(&queue, msg[3]), "Failed to enqueue a message to otMessageQueue.");
+    otMessageQueueEnqueue(&queue, msg[3]);
     VerifyMessageQueueContentUsingOtApi(&queue, 4, msg[2], msg[0], msg[1], msg[3]);
 
     // Remove elements and check the content
-    SuccessOrQuit(otMessageQueueDequeue(&queue, msg[1]), "Failed to dequeue a message from otMessageQueue.");
+    otMessageQueueDequeue(&queue, msg[1]);
     VerifyMessageQueueContentUsingOtApi(&queue, 3, msg[2], msg[0], msg[3]);
-    SuccessOrQuit(otMessageQueueDequeue(&queue, msg[0]), "Failed to dequeue a message from otMessageQueue.");
+    otMessageQueueDequeue(&queue, msg[0]);
     VerifyMessageQueueContentUsingOtApi(&queue, 2, msg[2], msg[3]);
-    SuccessOrQuit(otMessageQueueDequeue(&queue, msg[3]), "Failed to dequeue a message from otMessageQueue.");
+    otMessageQueueDequeue(&queue, msg[3]);
     VerifyMessageQueueContentUsingOtApi(&queue, 1, msg[2]);
 
-    // Check the expected failure cases for the enqueue and dequeue:
-    error = otMessageQueueEnqueue(&queue, msg[2]);
-    VerifyOrQuit(error == OT_ERROR_ALREADY, "Enqueuing an already queued message did not fail as expected.");
-    error = otMessageQueueDequeue(&queue, msg[0]);
-    VerifyOrQuit(error == OT_ERROR_NOT_FOUND, "Dequeuing a message not in the queue did not fail as expected.");
-
     // Check the failure cases for otMessageQueueGetNext()
-    message = otMessageQueueGetNext(&queue, NULL);
-    VerifyOrQuit(message == NULL, "otMessageQueueGetNext(queue, NULL) did not return NULL.");
+    message = otMessageQueueGetNext(&queue, nullptr);
+    VerifyOrQuit(message == nullptr, "otMessageQueueGetNext(queue, nullptr) did not return nullptr.");
     message = otMessageQueueGetNext(&queue, msg[1]);
-    VerifyOrQuit(message == NULL, "otMessageQueueGetNext() did not return NULL for a message not in the queue.");
+    VerifyOrQuit(message == nullptr, "otMessageQueueGetNext() did not return nullptr for a message not in the queue.");
 
     // Check the failure case when attempting to do otMessageQueueGetNext() but passing in a wrong queue pointer.
-    SuccessOrQuit(otMessageQueueEnqueue(&queue2, msg[0]), "Failed to enqueue a message to otMessageQueue.");
+    otMessageQueueEnqueue(&queue2, msg[0]);
     VerifyMessageQueueContentUsingOtApi(&queue2, 1, msg[0]);
-    SuccessOrQuit(otMessageQueueEnqueue(&queue2, msg[1]), "Failed to enqueue a message to otMessageQueue.");
+    otMessageQueueEnqueue(&queue2, msg[1]);
     VerifyMessageQueueContentUsingOtApi(&queue2, 2, msg[0], msg[1]);
 
     message = otMessageQueueGetNext(&queue2, msg[0]);
     VerifyOrQuit(message == msg[1], "otMessageQueueGetNext() failed");
     message = otMessageQueueGetNext(&queue, msg[0]);
-    VerifyOrQuit(message == NULL, "otMessageQueueGetNext() did not return NULL for message not in  the queue.");
+    VerifyOrQuit(message == nullptr, "otMessageQueueGetNext() did not return nullptr for message not in  the queue.");
 
     // Remove all element and make sure queue is empty
-    SuccessOrQuit(otMessageQueueDequeue(&queue, msg[2]), "Failed to dequeue a message from otMessageQueue.");
+    otMessageQueueDequeue(&queue, msg[2]);
     VerifyMessageQueueContentUsingOtApi(&queue, 0);
 
     testFreeInstance(sInstance);
diff --git a/tests/unit/test_ncp_buffer.cpp b/tests/unit/test_ncp_buffer.cpp
deleted file mode 100644
index 3545290..0000000
--- a/tests/unit/test_ncp_buffer.cpp
+++ /dev/null
@@ -1,1066 +0,0 @@
-/*
- *  Copyright (c) 2016, The OpenThread Authors.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the copyright holder nor the
- *     names of its contributors may be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-
-#include "common/code_utils.hpp"
-#include "common/instance.hpp"
-#include "common/message.hpp"
-#include "common/random.hpp"
-#include "ncp/ncp_buffer.hpp"
-
-#include "test_platform.h"
-#include "test_util.hpp"
-
-namespace ot {
-namespace Ncp {
-
-// This module implements unit-test for NcpFrameBuffer class.
-
-// Test related constants:
-enum
-{
-    kTestBufferSize       = 800,
-    kTestIterationAttemps = 10000,
-    kTagArraySize         = 1000,
-};
-
-//  Messages used for building frames...
-static const uint8_t sOpenThreadText[] = "OpenThread Rocks";
-static const uint8_t sHelloText[]      = "Hello there!";
-static const uint8_t sMottoText[]      = "Think good thoughts, say good words, do good deeds!";
-static const uint8_t sMysteryText[]    = "4871(\\):|(3$}{4|/4/2%14(\\)";
-static const uint8_t sHexText[]        = "0123456789abcdef";
-
-static ot::Instance *sInstance;
-static MessagePool * sMessagePool;
-
-struct CallbackContext
-{
-    uint32_t mFrameAddedCount;   // Number of times FrameAddedCallback is invoked.
-    uint32_t mFrameRemovedCount; // Number of times FrameRemovedCallback is invoked.
-};
-
-CallbackContext sContext;
-
-enum
-{
-    kNumPrios = 2, // Number of priority levels.
-
-    kTestFrame1Size = sizeof(sMottoText) + sizeof(sMysteryText) + sizeof(sMottoText) + sizeof(sHelloText),
-    kTestFrame2Size = sizeof(sMysteryText) + sizeof(sHelloText) + sizeof(sOpenThreadText),
-    kTestFrame3Size = sizeof(sMysteryText),
-    kTestFrame4Size = sizeof(sOpenThreadText),
-};
-
-NcpFrameBuffer::FrameTag sTagHistoryArray[kNumPrios][kTagArraySize];
-uint32_t                 sTagHistoryHead[kNumPrios] = {0};
-uint32_t                 sTagHistoryTail[kNumPrios] = {0};
-NcpFrameBuffer::FrameTag sExpectedRemovedTag        = NcpFrameBuffer::kInvalidTag;
-
-void ClearTagHistory(void)
-{
-    for (uint8_t priority = 0; priority < kNumPrios; priority++)
-    {
-        sTagHistoryHead[priority] = sTagHistoryTail[priority];
-    }
-}
-
-void AddTagToHistory(NcpFrameBuffer::FrameTag aTag, NcpFrameBuffer::Priority aPriority)
-{
-    uint8_t priority = static_cast<uint8_t>(aPriority);
-
-    sTagHistoryArray[priority][sTagHistoryTail[priority]] = aTag;
-
-    if (++sTagHistoryTail[priority] == kTagArraySize)
-    {
-        sTagHistoryTail[priority] = 0;
-    }
-
-    VerifyOrQuit(sTagHistoryTail[priority] != sTagHistoryHead[priority],
-                 "Ran out of space in `TagHistoryArray`, increase its size.");
-}
-
-void VerifyAndRemoveTagFromHistory(NcpFrameBuffer::FrameTag aTag, NcpFrameBuffer::Priority aPriority)
-{
-    uint8_t priority = static_cast<uint8_t>(aPriority);
-
-    VerifyOrQuit(sTagHistoryHead[priority] != sTagHistoryTail[priority], "Tag history is empty,");
-    VerifyOrQuit(aTag == sTagHistoryArray[priority][sTagHistoryHead[priority]],
-                 "Removed tag does not match the added one");
-
-    if (++sTagHistoryHead[priority] == kTagArraySize)
-    {
-        sTagHistoryHead[priority] = 0;
-    }
-
-    if (sExpectedRemovedTag != NcpFrameBuffer::kInvalidTag)
-    {
-        VerifyOrQuit(sExpectedRemovedTag == aTag, "Removed tag does match the previous OutFrameGetTag()");
-        sExpectedRemovedTag = NcpFrameBuffer::kInvalidTag;
-    }
-}
-
-void FrameAddedCallback(void *                   aContext,
-                        NcpFrameBuffer::FrameTag aTag,
-                        NcpFrameBuffer::Priority aPriority,
-                        NcpFrameBuffer *         aNcpBuffer)
-{
-    CallbackContext *callbackContext = reinterpret_cast<CallbackContext *>(aContext);
-
-    VerifyOrQuit(aNcpBuffer != NULL, "Null NcpFrameBuffer in the callback");
-    VerifyOrQuit(callbackContext != NULL, "Null context in the callback");
-    VerifyOrQuit(aTag != NcpFrameBuffer::kInvalidTag, "Invalid tag in the callback");
-    VerifyOrQuit(aTag == aNcpBuffer->InFrameGetLastTag(), "InFrameGetLastTag() does not match the tag from callback");
-
-    AddTagToHistory(aTag, aPriority);
-
-    callbackContext->mFrameAddedCount++;
-}
-
-void FrameRemovedCallback(void *                   aContext,
-                          NcpFrameBuffer::FrameTag aTag,
-                          NcpFrameBuffer::Priority aPriority,
-                          NcpFrameBuffer *         aNcpBuffer)
-{
-    CallbackContext *callbackContext = reinterpret_cast<CallbackContext *>(aContext);
-
-    VerifyOrQuit(aNcpBuffer != NULL, "Null NcpFrameBuffer in the callback");
-    VerifyOrQuit(callbackContext != NULL, "Null context in the callback");
-    VerifyOrQuit(aTag != NcpFrameBuffer::kInvalidTag, "Invalid tag in the callback");
-
-    VerifyAndRemoveTagFromHistory(aTag, aPriority);
-
-    callbackContext->mFrameRemovedCount++;
-}
-
-// Reads bytes from the ncp buffer, and verifies that it matches with the given content buffer.
-void ReadAndVerifyContent(NcpFrameBuffer &aNcpBuffer, const uint8_t *aContentBuffer, uint16_t aBufferLength)
-{
-    while (aBufferLength--)
-    {
-        VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == false, "Out frame ended before end of expected content.");
-
-        VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == *aContentBuffer++,
-                     "Out frame read byte does not match expected content");
-    }
-}
-
-void WriteTestFrame1(NcpFrameBuffer &aNcpBuffer, NcpFrameBuffer::Priority aPriority)
-{
-    Message *       message;
-    CallbackContext oldContext;
-
-    message = sMessagePool->New(Message::kTypeIp6, 0);
-    VerifyOrQuit(message != NULL, "Null Message");
-    SuccessOrQuit(message->SetLength(sizeof(sMottoText)), "Could not set the length of message.");
-    message->Write(0, sizeof(sMottoText), sMottoText);
-
-    oldContext = sContext;
-    aNcpBuffer.InFrameBegin(aPriority);
-    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMottoText, sizeof(sMottoText)), "InFrameFeedData() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMysteryText, sizeof(sMysteryText)), "InFrameFeedData() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message), "InFrameFeedMessage() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)), "InFrameFeedData() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-}
-
-void VerifyAndRemoveFrame1(NcpFrameBuffer &aNcpBuffer)
-{
-    CallbackContext oldContext = sContext;
-
-    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
-    VerifyOrQuit(sExpectedRemovedTag == aNcpBuffer.OutFrameGetTag(), "OutFrameGetTag() value changed unexpectedly.");
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    ReadAndVerifyContent(aNcpBuffer, sMottoText, sizeof(sMottoText));
-    ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
-    ReadAndVerifyContent(aNcpBuffer, sMottoText, sizeof(sMottoText));
-    ReadAndVerifyContent(aNcpBuffer, sHelloText, sizeof(sHelloText));
-    VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
-    VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
-    VerifyOrQuit(sExpectedRemovedTag == aNcpBuffer.OutFrameGetTag(), "OutFrameGetTag() value changed unexpectedly.");
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "Remove() failed.");
-    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-}
-
-void WriteTestFrame2(NcpFrameBuffer &aNcpBuffer, NcpFrameBuffer::Priority aPriority)
-{
-    Message *       message1;
-    Message *       message2;
-    CallbackContext oldContext = sContext;
-
-    message1 = sMessagePool->New(Message::kTypeIp6, 0);
-    VerifyOrQuit(message1 != NULL, "Null Message");
-    SuccessOrQuit(message1->SetLength(sizeof(sMysteryText)), "Could not set the length of message.");
-    message1->Write(0, sizeof(sMysteryText), sMysteryText);
-
-    message2 = sMessagePool->New(Message::kTypeIp6, 0);
-    VerifyOrQuit(message2 != NULL, "Null Message");
-    SuccessOrQuit(message2->SetLength(sizeof(sHelloText)), "Could not set the length of message.");
-    message2->Write(0, sizeof(sHelloText), sHelloText);
-
-    aNcpBuffer.InFrameBegin(aPriority);
-    SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message1), "InFrameFeedMessage() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message2), "InFrameFeedMessage() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-
-    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-}
-
-void VerifyAndRemoveFrame2(NcpFrameBuffer &aNcpBuffer)
-{
-    CallbackContext oldContext = sContext;
-
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size, "GetLength() is incorrect.");
-    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size, "GetLength() is incorrect.");
-    ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
-    ReadAndVerifyContent(aNcpBuffer, sOpenThreadText, sizeof(sOpenThreadText));
-    ReadAndVerifyContent(aNcpBuffer, sHelloText, sizeof(sHelloText));
-    VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
-    VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
-    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size, "GetLength() is incorrect.");
-    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "Remove() failed.");
-
-    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-}
-
-void WriteTestFrame3(NcpFrameBuffer &aNcpBuffer, NcpFrameBuffer::Priority aPriority)
-{
-    Message *       message1;
-    CallbackContext oldContext = sContext;
-
-    message1 = sMessagePool->New(Message::kTypeIp6, 0);
-    VerifyOrQuit(message1 != NULL, "Null Message");
-
-    // An empty message with no content.
-    SuccessOrQuit(message1->SetLength(0), "Could not set the length of message.");
-
-    aNcpBuffer.InFrameBegin(aPriority);
-    SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message1), "InFrameFeedMessage() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMysteryText, sizeof(sMysteryText)), "InFrameFeedData() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-
-    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-}
-
-void VerifyAndRemoveFrame3(NcpFrameBuffer &aNcpBuffer)
-{
-    CallbackContext oldContext = sContext;
-
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText), "GetLength() is incorrect.");
-    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText), "GetLength() is incorrect.");
-    ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
-    VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
-    VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
-    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText), "GetLength() is incorrect.");
-    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "Remove() failed.");
-
-    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-}
-
-void WriteTestFrame4(NcpFrameBuffer &aNcpBuffer, NcpFrameBuffer::Priority aPriority)
-{
-    CallbackContext oldContext = sContext;
-
-    aNcpBuffer.InFrameBegin(aPriority);
-    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
-    SuccessOrQuit(aNcpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-
-    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-}
-
-void VerifyAndRemoveFrame4(NcpFrameBuffer &aNcpBuffer)
-{
-    CallbackContext oldContext = sContext;
-
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText), "GetLength() is incorrect.");
-    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText), "GetLength() is incorrect.");
-    ReadAndVerifyContent(aNcpBuffer, sOpenThreadText, sizeof(sOpenThreadText));
-    VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
-    VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
-    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText), "GetLength() is incorrect.");
-    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "Remove() failed.");
-
-    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-}
-
-// This function implements the NcpFrameBuffer tests
-void TestNcpFrameBuffer(void)
-{
-    unsigned       i, j;
-    uint8_t        buffer[kTestBufferSize];
-    NcpFrameBuffer ncpBuffer(buffer, kTestBufferSize);
-
-    Message *                     message;
-    uint8_t                       readBuffer[16];
-    uint16_t                      readLen, readOffset;
-    NcpFrameBuffer::WritePosition pos1, pos2;
-
-    sInstance    = testInitInstance();
-    sMessagePool = &sInstance->Get<MessagePool>();
-
-    for (i = 0; i < sizeof(buffer); i++)
-    {
-        buffer[i] = 0;
-    }
-
-    sContext.mFrameAddedCount   = 0;
-    sContext.mFrameRemovedCount = 0;
-    ClearTagHistory();
-
-    // Set the callbacks.
-    ncpBuffer.SetFrameAddedCallback(FrameAddedCallback, &sContext);
-    ncpBuffer.SetFrameRemovedCallback(FrameRemovedCallback, &sContext);
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 1: Check initial buffer state");
-
-    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "Not empty after init.");
-    VerifyOrQuit(ncpBuffer.InFrameGetLastTag() == NcpFrameBuffer::kInvalidTag, "Incorrect tag after init.");
-    VerifyOrQuit(ncpBuffer.OutFrameGetTag() == NcpFrameBuffer::kInvalidTag, "Incorrect OutFrameTag after init.");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 2: Write and read a single frame");
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    DumpBuffer("\nBuffer after frame1 (low priority)", buffer, kTestBufferSize);
-    printf("\nFrameLen is %u", ncpBuffer.OutFrameGetLength());
-    VerifyAndRemoveFrame1(ncpBuffer);
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    DumpBuffer("\nBuffer after frame1 (high priority)", buffer, kTestBufferSize);
-    printf("\nFrameLen is %u", ncpBuffer.OutFrameGetLength());
-    VerifyAndRemoveFrame1(ncpBuffer);
-
-    printf("\nIterations: ");
-
-    // Always add as low priority.
-    for (j = 0; j < kTestIterationAttemps; j++)
-    {
-        printf("*");
-        WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-        VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
-
-        VerifyAndRemoveFrame1(ncpBuffer);
-        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
-    }
-
-    // Always add as high priority.
-    for (j = 0; j < kTestIterationAttemps; j++)
-    {
-        printf("*");
-        WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-        VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
-
-        VerifyAndRemoveFrame1(ncpBuffer);
-        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
-    }
-
-    // Every 5th add as high priority.
-    for (j = 0; j < kTestIterationAttemps; j++)
-    {
-        printf("*");
-        WriteTestFrame1(ncpBuffer, ((j % 5) == 0) ? NcpFrameBuffer::kPriorityHigh : NcpFrameBuffer::kPriorityLow);
-        VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
-
-        VerifyAndRemoveFrame1(ncpBuffer);
-        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
-    }
-
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 3: Multiple frames write and read (same priority)");
-
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-
-    DumpBuffer("\nBuffer after multiple frames", buffer, kTestBufferSize);
-
-    VerifyAndRemoveFrame2(ncpBuffer);
-    VerifyAndRemoveFrame3(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-
-    printf("\nIterations: ");
-
-    // Repeat this multiple times.
-    for (j = 0; j < kTestIterationAttemps; j++)
-    {
-        printf("*");
-
-        WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-        WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-        WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-
-        VerifyAndRemoveFrame2(ncpBuffer);
-        VerifyAndRemoveFrame3(ncpBuffer);
-
-        WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-        WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-
-        VerifyAndRemoveFrame2(ncpBuffer);
-        VerifyAndRemoveFrame2(ncpBuffer);
-        VerifyAndRemoveFrame3(ncpBuffer);
-
-        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
-    }
-
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 4: Multiple frames write and read (mixed priority)");
-
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyAndRemoveFrame3(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame4(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyAndRemoveFrame3(ncpBuffer);
-    VerifyAndRemoveFrame4(ncpBuffer);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame4(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    VerifyAndRemoveFrame4(ncpBuffer);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyAndRemoveFrame3(ncpBuffer);
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame4(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    VerifyAndRemoveFrame4(ncpBuffer);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyAndRemoveFrame3(ncpBuffer);
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame4(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    VerifyAndRemoveFrame3(ncpBuffer);
-    VerifyAndRemoveFrame4(ncpBuffer);
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    WriteTestFrame4(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyAndRemoveFrame3(ncpBuffer);
-    VerifyAndRemoveFrame4(ncpBuffer);
-    VerifyAndRemoveFrame1(ncpBuffer);
-
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 5: Frame discard when buffer full and partial read restart");
-
-    printf("\nIterations: ");
-
-    for (j = 0; j < kTestIterationAttemps; j++)
-    {
-        bool frame1IsHighPriority = ((j % 3) == 0);
-
-        printf("*");
-
-        WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-        WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-
-        ncpBuffer.InFrameBegin((j % 2) == 0 ? NcpFrameBuffer::kPriorityHigh : NcpFrameBuffer::kPriorityLow);
-        ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText));
-
-        message = sMessagePool->New(Message::kTypeIp6, 0);
-        VerifyOrQuit(message != NULL, "Null Message");
-        SuccessOrQuit(message->SetLength(sizeof(sMysteryText)), "Could not set the length of message.");
-        message->Write(0, sizeof(sMysteryText), sMysteryText);
-
-        ncpBuffer.InFrameFeedMessage(message);
-
-        // Start writing a new frame in middle of an unfinished frame. Ensure the first one is discarded.
-        WriteTestFrame1(ncpBuffer, frame1IsHighPriority ? NcpFrameBuffer::kPriorityHigh : NcpFrameBuffer::kPriorityLow);
-
-        // Note that message will not be freed by the NCP buffer since the frame associated with it was discarded and
-        // not yet finished/ended.
-        otMessageFree(message);
-
-        VerifyAndRemoveFrame3(ncpBuffer);
-
-        // Start reading few bytes from the frame
-        ncpBuffer.OutFrameBegin();
-        ncpBuffer.OutFrameReadByte();
-        ncpBuffer.OutFrameReadByte();
-        ncpBuffer.OutFrameReadByte();
-
-        // Now reset the read pointer and read/verify the frame from start.
-        if (frame1IsHighPriority)
-        {
-            VerifyAndRemoveFrame1(ncpBuffer);
-            VerifyAndRemoveFrame2(ncpBuffer);
-        }
-        else
-        {
-            VerifyAndRemoveFrame2(ncpBuffer);
-            VerifyAndRemoveFrame1(ncpBuffer);
-        }
-
-        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
-    }
-
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 6: Clear() and empty buffer method tests");
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-
-    ncpBuffer.Clear();
-    ClearTagHistory();
-
-    VerifyOrQuit(ncpBuffer.InFrameGetLastTag() == NcpFrameBuffer::kInvalidTag, "Incorrect last tag after Clear().");
-    VerifyOrQuit(ncpBuffer.OutFrameGetTag() == NcpFrameBuffer::kInvalidTag, "Incorrect OutFrameTag after Clear().");
-    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
-    VerifyOrQuit(ncpBuffer.OutFrameHasEnded() == true, "OutFrameHasEnded() is incorrect when no data in buffer.");
-    VerifyOrQuit(ncpBuffer.OutFrameRemove() == OT_ERROR_NOT_FOUND,
-                 "Remove() returned incorrect error status when buffer is empty.");
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == 0,
-                 "OutFrameGetLength() returned non-zero length when buffer is empty.");
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    VerifyAndRemoveFrame1(ncpBuffer);
-
-    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
-    VerifyOrQuit(ncpBuffer.OutFrameHasEnded() == true, "OutFrameHasEnded() is incorrect when no data in buffer.");
-    VerifyOrQuit(ncpBuffer.OutFrameRemove() == OT_ERROR_NOT_FOUND,
-                 "Remove() returned incorrect error status when buffer is empty.");
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == 0,
-                 "OutFrameGetLength() returned non-zero length when buffer is empty.");
-
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 7: OutFrameRead() in parts\n");
-
-    ncpBuffer.InFrameBegin(NcpFrameBuffer::kPriorityLow);
-    ncpBuffer.InFrameFeedData(sMottoText, sizeof(sMottoText));
-    ncpBuffer.InFrameEnd();
-
-    ncpBuffer.OutFrameBegin();
-    readOffset = 0;
-
-    while ((readLen = ncpBuffer.OutFrameRead(sizeof(readBuffer), readBuffer)) != 0)
-    {
-        DumpBuffer("Read() returned", readBuffer, readLen);
-
-        VerifyOrQuit(memcmp(readBuffer, sMottoText + readOffset, readLen) == 0,
-                     "Read() does not match expected content.");
-
-        readOffset += readLen;
-    }
-
-    VerifyOrQuit(readOffset == sizeof(sMottoText), "Read len does not match expected length.");
-
-    ncpBuffer.OutFrameRemove();
-
-    printf("\n -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 8: Remove a frame without reading it first");
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    SuccessOrQuit(ncpBuffer.OutFrameRemove(), "Remove() failed.");
-    VerifyAndRemoveFrame2(ncpBuffer);
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 9: Check length when front frame gets changed (a higher priority frame is added)");
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame3Size, "GetLength() is incorrect.");
-    VerifyAndRemoveFrame3(ncpBuffer);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\nTest 10: Active out frame remaining unchanged when a higher priority frame is written while reading it");
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
-    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
-    ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
-    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
-    ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
-    VerifyOrQuit(ncpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame4(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    VerifyAndRemoveFrame3(ncpBuffer);
-    VerifyAndRemoveFrame4(ncpBuffer);
-    // Repeat test reversing frame priority orders.
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
-    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
-    ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
-    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
-    ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
-    VerifyOrQuit(ncpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
-    WriteTestFrame3(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame4(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyAndRemoveFrame3(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    VerifyAndRemoveFrame4(ncpBuffer);
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\n Test 11: Read and remove in middle of an active input frame write");
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    ncpBuffer.InFrameBegin(NcpFrameBuffer::kPriorityHigh);
-    SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() failed.");
-    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-    VerifyAndRemoveFrame4(ncpBuffer);
-    // Repeat the test reversing priorities
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    ncpBuffer.InFrameBegin(NcpFrameBuffer::kPriorityLow);
-    SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() failed.");
-    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-    VerifyAndRemoveFrame4(ncpBuffer);
-    // Repeat the test with same priorities
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    ncpBuffer.InFrameBegin(NcpFrameBuffer::kPriorityHigh);
-    SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() failed.");
-    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-    VerifyAndRemoveFrame4(ncpBuffer);
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\n Test 12: Check returned error status");
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    ncpBuffer.InFrameBegin(NcpFrameBuffer::kPriorityHigh);
-    VerifyOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer)) == OT_ERROR_NO_BUFS, "Incorrect error status");
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() failed.");
-
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    // Ensure writes with starting `InFrameBegin()` fail
-    VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 1) == OT_ERROR_INVALID_STATE, "Incorrect error status");
-    VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 0) == OT_ERROR_INVALID_STATE, "Incorrect error status");
-    VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 0) == OT_ERROR_INVALID_STATE, "Incorrect error status");
-    VerifyOrQuit(ncpBuffer.InFrameEnd() == OT_ERROR_INVALID_STATE, "Incorrect error status");
-    message = sMessagePool->New(Message::kTypeIp6, 0);
-    VerifyOrQuit(message != NULL, "Null Message");
-    SuccessOrQuit(message->SetLength(sizeof(sMysteryText)), "Could not set the length of message.");
-    message->Write(0, sizeof(sMysteryText), sMysteryText);
-    VerifyOrQuit(ncpBuffer.InFrameFeedMessage(message) == OT_ERROR_INVALID_STATE, "Incorrect error status");
-    message->Free();
-    VerifyOrQuit(ncpBuffer.InFrameEnd() == OT_ERROR_INVALID_STATE, "Incorrect error status");
-    VerifyAndRemoveFrame2(ncpBuffer);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() failed");
-    VerifyOrQuit(ncpBuffer.OutFrameBegin() == OT_ERROR_NOT_FOUND, "OutFrameBegin() failed on empty queue");
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() failed");
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\n Test 13: Ensure we can utilize the full buffer size when frames removed during write");
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    ncpBuffer.InFrameBegin(NcpFrameBuffer::kPriorityHigh);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    SuccessOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer) - 4), "InFrameFeedData() failed.");
-    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-    SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed.");
-    // Repeat the test with a low priority buffer write
-    WriteTestFrame1(ncpBuffer, NcpFrameBuffer::kPriorityHigh);
-    WriteTestFrame2(ncpBuffer, NcpFrameBuffer::kPriorityLow);
-    ncpBuffer.InFrameBegin(NcpFrameBuffer::kPriorityLow);
-    VerifyAndRemoveFrame1(ncpBuffer);
-    VerifyAndRemoveFrame2(ncpBuffer);
-    SuccessOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer) - 4), "InFrameFeedData() failed.");
-    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-    SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed.");
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\n Test 14: Test InFrameOverwrite ");
-    printf("\nIterations: ");
-
-    for (j = 0; j < kTestIterationAttemps; j++)
-    {
-        uint16_t                 index;
-        bool                     addExtra = ((j % 7) != 0);
-        NcpFrameBuffer::Priority priority;
-
-        printf("*");
-        priority = ((j % 3) == 0) ? NcpFrameBuffer::kPriorityHigh : NcpFrameBuffer::kPriorityLow;
-        index    = static_cast<uint16_t>(j % sizeof(sHexText));
-        ncpBuffer.InFrameBegin(priority);
-        SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText, index), "InFrameFeedData() failed.");
-        SuccessOrQuit(ncpBuffer.InFrameGetPosition(pos1), "InFrameGetPosition() failed");
-        SuccessOrQuit(ncpBuffer.InFrameFeedData(sMysteryText, sizeof(sHexText) - index), "InFrameFeedData() failed.");
-        VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index, "InFrameGetDistance() failed");
-
-        if (addExtra)
-        {
-            SuccessOrQuit(ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)), "InFrameFeedData() failed.");
-        }
-
-        SuccessOrQuit(ncpBuffer.InFrameOverwrite(pos1, sHexText + index, sizeof(sHexText) - index),
-                      "InFrameOverwrite() failed.");
-        VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) ==
-                         sizeof(sHexText) - index + (addExtra ? sizeof(sHelloText) : 0),
-                     "InFrameGetDistance() failed");
-        SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-        VerifyOrQuit(ncpBuffer.InFrameGetPosition(pos2) == OT_ERROR_INVALID_STATE, "GetPosition failed.");
-        VerifyOrQuit(ncpBuffer.InFrameOverwrite(pos1, sHexText, 0) != OT_ERROR_NONE, "Failed to give error.");
-        SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed");
-        ReadAndVerifyContent(ncpBuffer, sHexText, sizeof(sHexText));
-
-        if (addExtra)
-        {
-            ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
-        }
-
-        SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed");
-        VerifyOrQuit(ncpBuffer.InFrameGetPosition(pos2) == OT_ERROR_INVALID_STATE, "GetPosition failed");
-    }
-
-    printf(" -- PASS\n");
-
-    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
-    printf("\n Test 15: Test InFrameReset()");
-    printf("\nIterations: ");
-
-    for (j = 0; j < kTestIterationAttemps; j++)
-    {
-        uint16_t                 index;
-        bool                     addExtra = ((j % 7) != 0);
-        NcpFrameBuffer::Priority priority;
-
-        printf("*");
-        priority = ((j % 3) == 0) ? NcpFrameBuffer::kPriorityHigh : NcpFrameBuffer::kPriorityLow;
-        index    = static_cast<uint16_t>(j % sizeof(sHexText));
-        ncpBuffer.InFrameBegin(priority);
-        SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText, index), "InFrameFeedData() failed.");
-        SuccessOrQuit(ncpBuffer.InFrameGetPosition(pos1), "InFrameGetPosition() failed");
-        SuccessOrQuit(ncpBuffer.InFrameFeedData(sMysteryText, sizeof(sHexText) - index), "InFrameFeedData() failed.");
-        VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index, "InFrameGetDistance() failed");
-
-        if (addExtra)
-        {
-            SuccessOrQuit(ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)), "InFrameFeedData() failed.");
-        }
-
-        SuccessOrQuit(ncpBuffer.InFrameReset(pos1), "InFrameReset() failed.");
-        SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText + index, sizeof(sHexText) - index),
-                      "InFrameOverwrite() failed.");
-
-        if (addExtra)
-        {
-            SuccessOrQuit(ncpBuffer.InFrameReset(pos1), "InFrameReset() failed.");
-            SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText + index, sizeof(sHexText) - index),
-                          "InFrameOverwrite() failed.");
-        }
-
-        VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index, "InFrameGetDistance() failed");
-        SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
-        SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed");
-        ReadAndVerifyContent(ncpBuffer, sHexText, sizeof(sHexText));
-        SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed");
-    }
-
-    printf(" -- PASS\n");
-
-    testFreeInstance(sInstance);
-}
-
-/**
- * NCP Buffer Fuzz testing
- *
- * Randomly decide if to read or write a frame to the NCP buffer (use `kReadProbability` in percent to control the
- * behavior).
- *
- * When writing a frame, use a random length (1 up to `kMaxFrameLen`) and generate random byte sequences.
- * When reading a frame ensure the length and the content matches what was written earlier.
- * Handle the cases where buffer gets full or empty.
- *
- */
-
-enum
-{
-    kFuzTestBufferSize            = 2000,   // Size of the buffer used during fuzz testing
-    kFuzTestIterationAttempts     = 500000, // Number of iterations  to run
-    kLensArraySize                = 500,    // Size of "Lengths" array.
-    kMaxFrameLen                  = 400,    // Maximum frame length
-    kReadProbability              = 50,     // Probability (in percent) to randomly choose to read vs write frame
-    kHighPriorityProbablity       = 20,     // Probability (in percent) to write a high priority frame
-    kUseTrueRandomNumberGenerator = 1,      // To use true random number generator or not.
-};
-
-uint8_t  sFrameBuffer[kNumPrios][kFuzTestBufferSize];
-uint32_t sFrameBufferTailIndex[kNumPrios] = {0};
-
-uint32_t GetRandom(uint32_t max)
-{
-    uint32_t value;
-
-    if (kUseTrueRandomNumberGenerator)
-    {
-        Random::Crypto::FillBuffer(reinterpret_cast<uint8_t *>(&value), sizeof(value));
-    }
-    else
-    {
-        value = Random::NonCrypto::GetUint32();
-    }
-
-    return value % max;
-}
-
-otError WriteRandomFrame(uint32_t aLength, NcpFrameBuffer &aNcpBuffer, NcpFrameBuffer::Priority aPriority)
-{
-    otError         error;
-    uint8_t         byte;
-    uint8_t         priority   = static_cast<uint8_t>(aPriority);
-    CallbackContext oldContext = sContext;
-    uint32_t        tail       = sFrameBufferTailIndex[priority];
-
-    aNcpBuffer.InFrameBegin(aPriority);
-
-    while (aLength--)
-    {
-        byte = static_cast<uint8_t>(GetRandom(256));
-        SuccessOrExit(error = aNcpBuffer.InFrameFeedData(&byte, sizeof(byte)));
-        sFrameBuffer[priority][tail++] = byte;
-    }
-
-    SuccessOrExit(error = aNcpBuffer.InFrameEnd());
-
-    sFrameBufferTailIndex[priority] = tail;
-
-    // check the callbacks
-    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-
-exit:
-    return error;
-}
-
-otError ReadRandomFrame(uint32_t aLength, NcpFrameBuffer &aNcpBuffer, uint8_t priority)
-{
-    CallbackContext oldContext = sContext;
-
-    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin failed");
-    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == aLength, "OutFrameGetLength() does not match");
-
-    // Read and verify that the content is same as sFrameBuffer values...
-    ReadAndVerifyContent(aNcpBuffer, sFrameBuffer[priority], static_cast<uint16_t>(aLength));
-    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
-
-    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "OutFrameRemove failed");
-
-    sFrameBufferTailIndex[priority] -= aLength;
-    memmove(sFrameBuffer[priority], sFrameBuffer[priority] + aLength, sFrameBufferTailIndex[priority]);
-
-    // If successful check the callbacks
-    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
-    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
-
-    return OT_ERROR_NONE;
-}
-
-// This runs a fuzz test of NCP buffer
-void TestFuzzNcpFrameBuffer(void)
-{
-    uint8_t        buffer[kFuzTestBufferSize];
-    NcpFrameBuffer ncpBuffer(buffer, kFuzTestBufferSize);
-
-    uint32_t lensArray[kNumPrios][kLensArraySize]; // Keeps track of length of written frames so far
-    uint32_t lensArrayStart[kNumPrios];
-    uint32_t lensArrayCount[kNumPrios];
-
-    sInstance    = testInitInstance();
-    sMessagePool = &sInstance->Get<MessagePool>();
-
-    memset(buffer, 0, sizeof(buffer));
-
-    memset(lensArray, 0, sizeof(lensArray));
-    memset(lensArrayStart, 0, sizeof(lensArrayStart));
-    memset(lensArrayCount, 0, sizeof(lensArrayCount));
-
-    sContext.mFrameAddedCount   = 0;
-    sContext.mFrameRemovedCount = 0;
-    ClearTagHistory();
-
-    ncpBuffer.SetFrameAddedCallback(FrameAddedCallback, &sContext);
-    ncpBuffer.SetFrameRemovedCallback(FrameRemovedCallback, &sContext);
-
-    for (uint32_t iter = 0; iter < kFuzTestIterationAttempts; iter++)
-    {
-        bool shouldRead;
-
-        if (lensArrayCount[0] == 0 && lensArrayCount[1] == 0)
-        {
-            shouldRead = false;
-        }
-        else if (lensArrayCount[0] == kLensArraySize - 1 || lensArrayCount[1] == kLensArraySize - 1)
-        {
-            shouldRead = true;
-        }
-        else
-        {
-            // Randomly decide to read or write.
-            shouldRead = (GetRandom(100) < kReadProbability);
-        }
-
-        if (shouldRead)
-        {
-            uint32_t len;
-            uint8_t  priority;
-
-            priority = (lensArrayCount[NcpFrameBuffer::kPriorityHigh] != 0) ? NcpFrameBuffer::kPriorityHigh
-                                                                            : NcpFrameBuffer::kPriorityLow;
-
-            len                      = lensArray[priority][lensArrayStart[priority]];
-            lensArrayStart[priority] = (lensArrayStart[priority] + 1) % kLensArraySize;
-            lensArrayCount[priority]--;
-
-            printf("R%c%d ", priority == NcpFrameBuffer::kPriorityHigh ? 'H' : 'L', len);
-
-            SuccessOrQuit(ReadRandomFrame(len, ncpBuffer, priority), "Failed to read random frame.");
-        }
-        else
-        {
-            uint32_t                 len = GetRandom(kMaxFrameLen) + 1;
-            NcpFrameBuffer::Priority priority;
-
-            if (GetRandom(100) < kHighPriorityProbablity)
-            {
-                priority = NcpFrameBuffer::kPriorityHigh;
-            }
-            else
-            {
-                priority = NcpFrameBuffer::kPriorityLow;
-            }
-
-            if (WriteRandomFrame(len, ncpBuffer, priority) == OT_ERROR_NONE)
-            {
-                lensArray[priority][(lensArrayStart[priority] + lensArrayCount[priority]) % kLensArraySize] = len;
-                lensArrayCount[priority]++;
-
-                printf("W%c%d ", priority == NcpFrameBuffer::kPriorityHigh ? 'H' : 'L', len);
-            }
-            else
-            {
-                printf("FULL ");
-            }
-        }
-
-        if (lensArrayCount[0] == 0 && lensArrayCount[1] == 0)
-        {
-            VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty failed.");
-            printf("EMPTY ");
-        }
-    }
-
-    printf("\n -- PASS\n");
-
-    testFreeInstance(sInstance);
-}
-
-} // namespace Ncp
-} // namespace ot
-
-int main(void)
-{
-    ot::Ncp::TestNcpFrameBuffer();
-    ot::Ncp::TestFuzzNcpFrameBuffer();
-    printf("\nAll tests passed.\n");
-    return 0;
-}
diff --git a/tests/unit/test_netif.cpp b/tests/unit/test_netif.cpp
index 98dc5d4..f8ddc2a 100644
--- a/tests/unit/test_netif.cpp
+++ b/tests/unit/test_netif.cpp
@@ -32,6 +32,7 @@
 
 #include <openthread/config.h>
 
+#include "common/code_utils.hpp"
 #include "common/debug.hpp"
 #include "common/instance.hpp"
 #include "net/netif.hpp"
@@ -50,8 +51,8 @@
 
     // Provide `protected` methods in `Netif` as `public` from `TestNetif`
     // so that we can verify their behavior in this test
-    otError SubscribeAllNodesMulticast(void) { return Ip6::Netif::SubscribeAllNodesMulticast(); }
-    otError UnsubscribeAllNodesMulticast(void) { return Ip6::Netif::UnsubscribeAllNodesMulticast(); }
+    void SubscribeAllNodesMulticast(void) { Ip6::Netif::SubscribeAllNodesMulticast(); }
+    void UnsubscribeAllNodesMulticast(void) { Ip6::Netif::UnsubscribeAllNodesMulticast(); }
 };
 
 // This function verifies the multicast addresses on Netif matches the list of given addresses.
@@ -104,94 +105,93 @@
     const char *kTestAddress2         = "ff03::114";
     const char *kTestAddress3         = "ff04::114";
 
-    addresses[0].FromString(kLinkLocalAllRouters);
-    addresses[1].FromString(kRealmLocalAllRouters);
-    addresses[2].FromString(kLinkLocalAllNodes);
-    addresses[3].FromString(kRealmLocalAllNodes);
-    addresses[4].FromString(kRealmLocalAllMpl);
-    addresses[5].FromString(kTestAddress1);
-    addresses[6].FromString(kTestAddress2);
-    addresses[7].FromString(kTestAddress3);
+    IgnoreError(addresses[0].FromString(kLinkLocalAllRouters));
+    IgnoreError(addresses[1].FromString(kRealmLocalAllRouters));
+    IgnoreError(addresses[2].FromString(kLinkLocalAllNodes));
+    IgnoreError(addresses[3].FromString(kRealmLocalAllNodes));
+    IgnoreError(addresses[4].FromString(kRealmLocalAllMpl));
+    IgnoreError(addresses[5].FromString(kTestAddress1));
+    IgnoreError(addresses[6].FromString(kTestAddress2));
+    IgnoreError(addresses[7].FromString(kTestAddress3));
 
     VerifyMulticastAddressList(netif, addresses, 0);
 
-    SuccessOrQuit(netif.SubscribeAllNodesMulticast(), "SubscribeAllNodesMulticast() failed");
-
+    netif.SubscribeAllNodesMulticast();
     VerifyMulticastAddressList(netif, &addresses[2], 3);
 
-    VerifyOrQuit(netif.SubscribeAllNodesMulticast() == OT_ERROR_ALREADY,
-                 "SubscribeAllNodesMulticast() did not fail when already subscribed");
+    netif.SubscribeAllNodesMulticast();
+    VerifyMulticastAddressList(netif, &addresses[2], 3);
 
-    SuccessOrQuit(netif.SubscribeAllRoutersMulticast(), "SubscribeAllRoutersMulticast() failed");
+    netif.SubscribeAllRoutersMulticast();
     VerifyMulticastAddressList(netif, &addresses[0], 5);
 
-    VerifyOrQuit(netif.SubscribeAllRoutersMulticast() == OT_ERROR_ALREADY,
-                 "SubscribeAllRoutersMulticast() did not fail when already subscribed");
+    netif.SubscribeAllRoutersMulticast();
+    VerifyMulticastAddressList(netif, &addresses[0], 5);
 
-    SuccessOrQuit(netif.UnsubscribeAllRoutersMulticast(), "UnsubscribeAllRoutersMulticast() failed");
+    netif.UnsubscribeAllRoutersMulticast();
     VerifyMulticastAddressList(netif, &addresses[2], 3);
 
-    VerifyOrQuit(netif.UnsubscribeAllRoutersMulticast() == OT_ERROR_NOT_FOUND,
-                 "UnsubscribeAllRoutersMulticast() did not fail when not subscribed");
+    netif.UnsubscribeAllRoutersMulticast();
+    VerifyMulticastAddressList(netif, &addresses[2], 3);
 
-    netifAddress.GetAddress().FromString(kTestAddress1);
-    SuccessOrQuit(netif.SubscribeMulticast(netifAddress), "SubscribeMulticast() failed");
+    IgnoreError(netifAddress.GetAddress().FromString(kTestAddress1));
+    netif.SubscribeMulticast(netifAddress);
     VerifyMulticastAddressList(netif, &addresses[2], 4);
 
-    VerifyOrQuit(netif.SubscribeMulticast(netifAddress) == OT_ERROR_ALREADY,
-                 "SubscribeMulticast() did not fail when address was already subscribed");
+    netif.SubscribeMulticast(netifAddress);
+    VerifyMulticastAddressList(netif, &addresses[2], 4);
 
-    SuccessOrQuit(netif.UnsubscribeAllNodesMulticast(), "UnsubscribeAllNodesMulticast() failed");
+    netif.UnsubscribeAllNodesMulticast();
     VerifyMulticastAddressList(netif, &addresses[5], 1);
 
-    VerifyOrQuit(netif.UnsubscribeAllNodesMulticast() == OT_ERROR_NOT_FOUND,
-                 "UnsubscribeAllNodesMulticast() did not fail when not subscribed");
+    netif.UnsubscribeAllNodesMulticast();
+    VerifyMulticastAddressList(netif, &addresses[5], 1);
 
-    address.FromString(kTestAddress2);
+    IgnoreError(address.FromString(kTestAddress2));
     SuccessOrQuit(netif.SubscribeExternalMulticast(address), "SubscribeExternalMulticast() failed");
     VerifyMulticastAddressList(netif, &addresses[5], 2);
 
-    SuccessOrQuit(netif.SubscribeAllNodesMulticast(), "SubscribeAllNodesMulticast() failed");
+    netif.SubscribeAllNodesMulticast();
     VerifyMulticastAddressList(netif, &addresses[2], 5);
 
-    VerifyOrQuit(netif.SubscribeExternalMulticast(address) == OT_ERROR_ALREADY,
-                 "SubscribeExternalMulticast() did not fail when address was already subscribed");
+    netif.SubscribeAllNodesMulticast();
+    VerifyMulticastAddressList(netif, &addresses[2], 5);
 
-    SuccessOrQuit(netif.SubscribeAllRoutersMulticast(), "SubscribeAllRoutersMulticast() failed");
+    netif.SubscribeAllRoutersMulticast();
     VerifyMulticastAddressList(netif, &addresses[0], 7);
 
-    VerifyOrQuit(netif.SubscribeAllRoutersMulticast() == OT_ERROR_ALREADY,
-                 "SubscribeAllRoutersMulticast() did not fail when already subscribed");
+    netif.SubscribeAllRoutersMulticast();
+    VerifyMulticastAddressList(netif, &addresses[0], 7);
 
-    address.FromString(kTestAddress3);
+    IgnoreError(address.FromString(kTestAddress3));
     SuccessOrQuit(netif.SubscribeExternalMulticast(address), "SubscribeExternalMulticast() failed");
     VerifyMulticastAddressList(netif, &addresses[0], 8);
 
-    address.FromString(kTestAddress1); // same as netifAddress (internal)
+    IgnoreError(address.FromString(kTestAddress1)); // same as netifAddress (internal)
     VerifyOrQuit(netif.UnsubscribeExternalMulticast(address) == OT_ERROR_INVALID_ARGS,
                  "UnsubscribeExternalMulticast() did not fail when address was not external");
 
-    address.FromString(kRealmLocalAllMpl);
+    IgnoreError(address.FromString(kRealmLocalAllMpl));
     VerifyOrQuit(netif.UnsubscribeExternalMulticast(address) == OT_ERROR_INVALID_ARGS,
                  "UnsubscribeExternalMulticast() did not fail when address was fixed address");
 
-    SuccessOrQuit(netif.UnsubscribeAllRoutersMulticast(), "UnsubscribeAllRoutersMulticast() failed");
+    netif.UnsubscribeAllRoutersMulticast();
     VerifyMulticastAddressList(netif, &addresses[2], 6);
 
-    VerifyOrQuit(netif.UnsubscribeAllRoutersMulticast() == OT_ERROR_NOT_FOUND,
-                 "UnsubscribeAllRoutersMulticast() did not fail when not subscribed");
+    netif.UnsubscribeAllRoutersMulticast();
+    VerifyMulticastAddressList(netif, &addresses[2], 6);
 
     netif.UnsubscribeAllExternalMulticastAddresses();
     VerifyMulticastAddressList(netif, &addresses[2], 4);
 
-    SuccessOrQuit(netif.UnsubscribeMulticast(netifAddress), "UnsubscribeMulticast() failed");
+    netif.UnsubscribeMulticast(netifAddress);
     VerifyMulticastAddressList(netif, &addresses[2], 3);
 
-    VerifyOrQuit(netif.UnsubscribeMulticast(netifAddress) == OT_ERROR_NOT_FOUND,
-                 "UnsubscribeMulticast() did not fail when address was not subscribed");
+    netif.UnsubscribeMulticast(netifAddress);
+    VerifyMulticastAddressList(netif, &addresses[2], 3);
 
-    SuccessOrQuit(netif.UnsubscribeAllNodesMulticast(), "UnsubscribeAllNodesMulticast() failed");
-    VerifyMulticastAddressList(netif, NULL, 0);
+    netif.UnsubscribeAllNodesMulticast();
+    VerifyMulticastAddressList(netif, nullptr, 0);
 
     // The first five elements in `addresses[]` are the default/fixed addresses:
     // kLinkLocalAllRouters, kRealmLocalAllRouters, kLinkLocalAllNodes,
diff --git a/tests/unit/test_network_data.cpp b/tests/unit/test_network_data.cpp
index cddb344..8dc8850 100644
--- a/tests/unit/test_network_data.cpp
+++ b/tests/unit/test_network_data.cpp
@@ -78,7 +78,7 @@
     ExternalRouteConfig config;
 
     instance = testInitInstance();
-    VerifyOrQuit(instance != NULL, "Null OpenThread instance\n");
+    VerifyOrQuit(instance != nullptr, "Null OpenThread instance\n");
 
     {
         const uint8_t kNetworkData[] = {0x08, 0x04, 0x0B, 0x02, 0x00, 0x00, 0x03, 0x14, 0x00, 0x40,
diff --git a/tests/unit/test_platform.cpp b/tests/unit/test_platform.cpp
index 3e1df85..12edc30 100644
--- a/tests/unit/test_platform.cpp
+++ b/tests/unit/test_platform.cpp
@@ -32,55 +32,43 @@
 
 bool                 g_testPlatAlarmSet     = false;
 uint32_t             g_testPlatAlarmNext    = 0;
-testPlatAlarmStop    g_testPlatAlarmStop    = NULL;
-testPlatAlarmStartAt g_testPlatAlarmStartAt = NULL;
-testPlatAlarmGetNow  g_testPlatAlarmGetNow  = NULL;
+testPlatAlarmStop    g_testPlatAlarmStop    = nullptr;
+testPlatAlarmStartAt g_testPlatAlarmStartAt = nullptr;
+testPlatAlarmGetNow  g_testPlatAlarmGetNow  = nullptr;
 
 otRadioCaps                     g_testPlatRadioCaps               = OT_RADIO_CAPS_NONE;
-testPlatRadioSetPanId           g_testPlatRadioSetPanId           = NULL;
-testPlatRadioSetExtendedAddress g_testPlatRadioSetExtendedAddress = NULL;
-testPlatRadioIsEnabled          g_testPlatRadioIsEnabled          = NULL;
-testPlatRadioEnable             g_testPlatRadioEnable             = NULL;
-testPlatRadioDisable            g_testPlatRadioDisable            = NULL;
-testPlatRadioSetShortAddress    g_testPlatRadioSetShortAddress    = NULL;
-testPlatRadioReceive            g_testPlatRadioReceive            = NULL;
-testPlatRadioTransmit           g_testPlatRadioTransmit           = NULL;
-testPlatRadioGetTransmitBuffer  g_testPlatRadioGetTransmitBuffer  = NULL;
+testPlatRadioSetPanId           g_testPlatRadioSetPanId           = nullptr;
+testPlatRadioSetExtendedAddress g_testPlatRadioSetExtendedAddress = nullptr;
+testPlatRadioIsEnabled          g_testPlatRadioIsEnabled          = nullptr;
+testPlatRadioEnable             g_testPlatRadioEnable             = nullptr;
+testPlatRadioDisable            g_testPlatRadioDisable            = nullptr;
+testPlatRadioSetShortAddress    g_testPlatRadioSetShortAddress    = nullptr;
+testPlatRadioReceive            g_testPlatRadioReceive            = nullptr;
+testPlatRadioTransmit           g_testPlatRadioTransmit           = nullptr;
+testPlatRadioGetTransmitBuffer  g_testPlatRadioGetTransmitBuffer  = nullptr;
 
-void testPlatResetToDefaults(void)
+enum
 {
-    g_testPlatAlarmSet     = false;
-    g_testPlatAlarmNext    = 0;
-    g_testPlatAlarmStop    = NULL;
-    g_testPlatAlarmStartAt = NULL;
-    g_testPlatAlarmGetNow  = NULL;
+    FLASH_SWAP_SIZE = 2048,
+    FLASH_SWAP_NUM  = 2,
+};
 
-    g_testPlatRadioCaps               = OT_RADIO_CAPS_NONE;
-    g_testPlatRadioSetPanId           = NULL;
-    g_testPlatRadioSetExtendedAddress = NULL;
-    g_testPlatRadioSetShortAddress    = NULL;
-    g_testPlatRadioIsEnabled          = NULL;
-    g_testPlatRadioEnable             = NULL;
-    g_testPlatRadioDisable            = NULL;
-    g_testPlatRadioReceive            = NULL;
-    g_testPlatRadioTransmit           = NULL;
-    g_testPlatRadioGetTransmitBuffer  = NULL;
-}
+uint8_t g_flash[FLASH_SWAP_SIZE * FLASH_SWAP_NUM];
 
 ot::Instance *testInitInstance(void)
 {
-    otInstance *instance = NULL;
+    otInstance *instance = nullptr;
 
 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
     size_t   instanceBufferLength = 0;
-    uint8_t *instanceBuffer       = NULL;
+    uint8_t *instanceBuffer       = nullptr;
 
     // Call to query the buffer size
-    (void)otInstanceInit(NULL, &instanceBufferLength);
+    (void)otInstanceInit(nullptr, &instanceBufferLength);
 
     // Call to allocate the buffer
     instanceBuffer = (uint8_t *)malloc(instanceBufferLength);
-    VerifyOrQuit(instanceBuffer != NULL, "Failed to allocate otInstance");
+    VerifyOrQuit(instanceBuffer != nullptr, "Failed to allocate otInstance");
     memset(instanceBuffer, 0, instanceBufferLength);
 
     // Initialize OpenThread with the buffer
@@ -159,7 +147,7 @@
     else
     {
         struct timeval tv;
-        gettimeofday(&tv, NULL);
+        gettimeofday(&tv, nullptr);
         return (uint32_t)((tv.tv_sec * 1000) + (tv.tv_usec / 1000) + 123456);
     }
 }
@@ -198,7 +186,7 @@
     else
     {
         struct timeval tv;
-        gettimeofday(&tv, NULL);
+        gettimeofday(&tv, nullptr);
         return (uint32_t)((tv.tv_sec * 1000000) + tv.tv_usec + 123456);
     }
 }
@@ -339,7 +327,7 @@
     OT_UNUSED_VARIABLE(aEnable);
 }
 
-otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
     OT_UNUSED_VARIABLE(aShortAddress);
@@ -353,7 +341,7 @@
     return OT_ERROR_NONE;
 }
 
-otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
+otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
 {
     OT_UNUSED_VARIABLE(aInstance);
     OT_UNUSED_VARIABLE(aShortAddress);
@@ -392,7 +380,7 @@
 int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
 {
     OT_UNUSED_VARIABLE(aInstance);
-    return 0;
+    return -100;
 }
 //
 // Random
@@ -417,14 +405,14 @@
 // Diag
 //
 
-void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
+void otPlatDiagProcess(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
 {
     OT_UNUSED_VARIABLE(aInstance);
-    OT_UNUSED_VARIABLE(argc);
+    OT_UNUSED_VARIABLE(aArgsLength);
     OT_UNUSED_VARIABLE(aOutputMaxLen);
 
     // no more diagnostics features for Posix platform
-    sprintf(aOutput, "diag feature '%s' is not supported\r\n", argv[0]);
+    sprintf(aOutput, "diag feature '%s' is not supported\r\n", aArgs[0]);
 }
 
 void otPlatDiagModeSet(bool aMode)
@@ -543,12 +531,72 @@
     OT_UNUSED_VARIABLE(aInstance);
 }
 
+void otPlatFlashInit(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    memset(g_flash, 0xff, sizeof(g_flash));
+}
+
+uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    return FLASH_SWAP_SIZE;
+}
+
+void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address;
+
+    VerifyOrQuit(aSwapIndex < FLASH_SWAP_NUM, "aSwapIndex invalid");
+
+    address = aSwapIndex ? FLASH_SWAP_SIZE : 0;
+
+    memset(g_flash + address, 0xff, FLASH_SWAP_SIZE);
+}
+
+void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address;
+
+    VerifyOrQuit(aSwapIndex < FLASH_SWAP_NUM, "aSwapIndex invalid");
+    VerifyOrQuit(aSize <= FLASH_SWAP_SIZE, "aSize invalid");
+    VerifyOrQuit(aOffset <= (FLASH_SWAP_SIZE - aSize), "aOffset + aSize invalid");
+
+    address = aSwapIndex ? FLASH_SWAP_SIZE : 0;
+
+    memcpy(aData, g_flash + address + aOffset, aSize);
+}
+
+void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
+{
+    OT_UNUSED_VARIABLE(aInstance);
+
+    uint32_t address;
+
+    VerifyOrQuit(aSwapIndex < FLASH_SWAP_NUM, "aSwapIndex invalid");
+    VerifyOrQuit(aSize <= FLASH_SWAP_SIZE, "aSize invalid");
+    VerifyOrQuit(aOffset <= (FLASH_SWAP_SIZE - aSize), "aOffset + aSize invalid");
+
+    address = aSwapIndex ? FLASH_SWAP_SIZE : 0;
+
+    for (uint32_t index = 0; index < aSize; index++)
+    {
+        g_flash[address + aOffset + index] &= ((uint8_t *)aData)[index];
+    }
+}
+
 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 uint64_t otPlatTimeGet(void)
 {
     struct timeval tv;
 
-    gettimeofday(&tv, NULL);
+    gettimeofday(&tv, nullptr);
 
     return (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
 }
@@ -559,4 +607,11 @@
 }
 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
 
+#if OPENTHREAD_CONFIG_OTNS_ENABLE
+void otPlatOtnsStatus(const char *aStatus)
+{
+    OT_UNUSED_VARIABLE(aStatus);
+}
+#endif // OPENTHREAD_CONFIG_OTNS_ENABLE
+
 } // extern "C"
diff --git a/tests/unit/test_platform.h b/tests/unit/test_platform.h
index 322b23e..c7f4228 100644
--- a/tests/unit/test_platform.h
+++ b/tests/unit/test_platform.h
@@ -86,7 +86,4 @@
 ot::Instance *testInitInstance(void);
 void          testFreeInstance(otInstance *aInstance);
 
-// Resets platform functions to defaults
-void testPlatResetToDefaults(void);
-
 #endif // TEST_PLATFORM_H
diff --git a/tests/unit/test_pool.cpp b/tests/unit/test_pool.cpp
new file mode 100644
index 0000000..6ab037f
--- /dev/null
+++ b/tests/unit/test_pool.cpp
@@ -0,0 +1,136 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test_platform.h"
+
+#include <openthread/config.h>
+
+#include "common/instance.hpp"
+#include "common/pool.hpp"
+
+#include "test_util.h"
+
+struct EntryBase
+{
+    EntryBase *mNext;
+};
+
+struct Entry : public EntryBase, ot::LinkedListEntry<Entry>
+{
+public:
+    Entry(void)
+        : mInitWithInstance(false)
+    {
+    }
+
+    void Init(ot::Instance &) { mInitWithInstance = true; }
+
+    bool IsInitializedWithInstance(void) const { return mInitWithInstance; }
+
+private:
+    bool mInitWithInstance;
+};
+
+enum : uint16_t
+{
+    kPoolSize = 11,
+};
+
+typedef ot::Pool<Entry, kPoolSize> EntryPool;
+
+static Entry sNonPoolEntry;
+
+void VerifyEntry(EntryPool &aPool, const Entry &aEntry, bool aInitWithInstance)
+{
+    uint16_t         index;
+    const EntryPool &constPool = const_cast<const EntryPool &>(aPool);
+
+    VerifyOrQuit(aPool.IsPoolEntry(aEntry), "Pool::IsPoolEntry() failed");
+    VerifyOrQuit(!aPool.IsPoolEntry(sNonPoolEntry), "Pool::IsPoolEntry() succeeded for non-pool entry");
+
+    index = aPool.GetIndexOf(aEntry);
+    VerifyOrQuit(&aPool.GetEntryAt(index) == &aEntry, "Pool::GetEntryAt() failed");
+    VerifyOrQuit(&constPool.GetEntryAt(index) == &aEntry, "Pool::GetEntryAt() failed");
+
+    VerifyOrQuit(aEntry.IsInitializedWithInstance() == aInitWithInstance, "Pool did not correctly Init() entry");
+}
+
+void TestPool(EntryPool &aPool, bool aInitWithInstance)
+{
+    Entry *entries[kPoolSize];
+
+    VerifyOrQuit(aPool.GetSize() == kPoolSize, "Pool::GetSize() failed");
+
+    for (uint16_t i = 0; i < kPoolSize; i++)
+    {
+        entries[i] = aPool.Allocate();
+        VerifyOrQuit(entries[i] != nullptr, "Pool::Allocate() failed");
+
+        VerifyEntry(aPool, *entries[i], aInitWithInstance);
+    }
+
+    for (uint16_t numEntriesToFree = 1; numEntriesToFree <= kPoolSize; numEntriesToFree++)
+    {
+        VerifyOrQuit(aPool.Allocate() == nullptr, "Pool::Allocate() did not fail when all pool entries were allocated");
+
+        for (uint16_t i = 0; i < numEntriesToFree; i++)
+        {
+            VerifyEntry(aPool, *entries[i], aInitWithInstance);
+            aPool.Free(*entries[i]);
+        }
+
+        for (uint16_t i = 0; i < numEntriesToFree; i++)
+        {
+            entries[i] = aPool.Allocate();
+            VerifyOrQuit(entries[i] != nullptr, "Pool::Allocate() failed");
+
+            VerifyEntry(aPool, *entries[i], aInitWithInstance);
+        }
+    }
+
+    VerifyOrQuit(aPool.Allocate() == nullptr, "Pool::Allocate() did not fail when all pool entries were allocated");
+}
+
+void TestPool(void)
+{
+    ot::Instance *instance = testInitInstance();
+    EntryPool     pool1;
+    EntryPool     pool2(*instance);
+
+    TestPool(pool1, /* aInitWithInstance */ false);
+    TestPool(pool2, /* aInitWithInstance */ true);
+
+    testFreeInstance(instance);
+}
+
+int main(void)
+{
+    TestPool();
+    printf("All tests passed\n");
+    return 0;
+}
diff --git a/tests/unit/test_priority_queue.cpp b/tests/unit/test_priority_queue.cpp
index 914db28..feadba3 100644
--- a/tests/unit/test_priority_queue.cpp
+++ b/tests/unit/test_priority_queue.cpp
@@ -57,21 +57,21 @@
     if (aExpectedLength == 0)
     {
         message = aPriorityQueue.GetHead();
-        VerifyOrQuit(message == NULL, "PriorityQueue is not empty when expected len is zero.");
+        VerifyOrQuit(message == nullptr, "PriorityQueue is not empty when expected len is zero.");
 
-        VerifyOrQuit(aPriorityQueue.GetHeadForPriority(ot::Message::kPriorityLow) == NULL,
-                     "GetHeadForPriority() non-NULL when empty");
-        VerifyOrQuit(aPriorityQueue.GetHeadForPriority(ot::Message::kPriorityNormal) == NULL,
-                     "GetHeadForPriority() non-NULL when empty");
-        VerifyOrQuit(aPriorityQueue.GetHeadForPriority(ot::Message::kPriorityHigh) == NULL,
-                     "GetHeadForPriority() non-NULL when empty");
-        VerifyOrQuit(aPriorityQueue.GetHeadForPriority(ot::Message::kPriorityNet) == NULL,
-                     "GetHeadForPriority() non-NULL when empty");
+        VerifyOrQuit(aPriorityQueue.GetHeadForPriority(ot::Message::kPriorityLow) == nullptr,
+                     "GetHeadForPriority() non-nullptr when empty");
+        VerifyOrQuit(aPriorityQueue.GetHeadForPriority(ot::Message::kPriorityNormal) == nullptr,
+                     "GetHeadForPriority() non-nullptr when empty");
+        VerifyOrQuit(aPriorityQueue.GetHeadForPriority(ot::Message::kPriorityHigh) == nullptr,
+                     "GetHeadForPriority() non-nullptr when empty");
+        VerifyOrQuit(aPriorityQueue.GetHeadForPriority(ot::Message::kPriorityNet) == nullptr,
+                     "GetHeadForPriority() non-nullptr when empty");
     }
     else
     {
         // Go through all messages in the queue and verify they match the passed-in messages
-        for (message = aPriorityQueue.GetHead(); message != NULL; message = message->GetNext())
+        for (message = aPriorityQueue.GetHead(); message != nullptr; message = message->GetNext())
         {
             VerifyOrQuit(aExpectedLength != 0, "PriorityQueue contains more entries than expected.");
 
@@ -81,14 +81,16 @@
             {
                 for (curPriority--; curPriority != msgArg->GetPriority(); curPriority--)
                 {
-                    // Check the `GetHeadForPriority` is NULL if there are no expected message for this priority level.
+                    // Check the `GetHeadForPriority` is nullptr if there are no expected message for this priority
+                    // level.
                     VerifyOrQuit(
-                        aPriorityQueue.GetHeadForPriority(static_cast<uint8_t>(curPriority)) == NULL,
-                        "PriorityQueue::GetHeadForPriority is non-NULL when no expected msg for this priority.");
+                        aPriorityQueue.GetHeadForPriority(static_cast<ot::Message::Priority>(curPriority)) == nullptr,
+                        "PriorityQueue::GetHeadForPriority is non-nullptr when no expected msg for this priority.");
                 }
 
                 // Check the `GetHeadForPriority`.
-                VerifyOrQuit(aPriorityQueue.GetHeadForPriority(static_cast<uint8_t>(curPriority)) == msgArg,
+                VerifyOrQuit(aPriorityQueue.GetHeadForPriority(static_cast<ot::Message::Priority>(curPriority)) ==
+                                 msgArg,
                              "PriorityQueue::GetHeadForPriority failed.");
             }
 
@@ -100,11 +102,11 @@
 
         VerifyOrQuit(aExpectedLength == 0, "PriorityQueue contains less entries than expected.");
 
-        // Check the `GetHeadForPriority` is NULL if there are no expected message for any remaining priority level.
+        // Check the `GetHeadForPriority` is nullptr if there are no expected message for any remaining priority level.
         for (curPriority--; curPriority >= 0; curPriority--)
         {
-            VerifyOrQuit(aPriorityQueue.GetHeadForPriority(static_cast<uint8_t>(curPriority)) == NULL,
-                         "PriorityQueue::GetHeadForPriority is non-NULL when no expected msg for this priority.");
+            VerifyOrQuit(aPriorityQueue.GetHeadForPriority(static_cast<ot::Message::Priority>(curPriority)) == nullptr,
+                         "PriorityQueue::GetHeadForPriority is non-nullptr when no expected msg for this priority.");
         }
     }
 
@@ -123,11 +125,11 @@
     if (aExpectedLength == 0)
     {
         message = aMessageQueue.GetHead();
-        VerifyOrQuit(message == NULL, "MessageQueue is not empty when expected len is zero.");
+        VerifyOrQuit(message == nullptr, "MessageQueue is not empty when expected len is zero.");
     }
     else
     {
-        for (message = aMessageQueue.GetHead(); message != NULL; message = message->GetNext())
+        for (message = aMessageQueue.GetHead(); message != nullptr; message = message->GetNext())
         {
             VerifyOrQuit(aExpectedLength != 0, "MessageQueue contains more entries than expected");
 
@@ -155,7 +157,7 @@
     ot::Message *     msgLow[kNumTestMessages];
 
     instance = testInitInstance();
-    VerifyOrQuit(instance != NULL, "Null OpenThread instance");
+    VerifyOrQuit(instance != nullptr, "Null OpenThread instance");
 
     messagePool = &instance->Get<ot::MessagePool>();
 
@@ -163,40 +165,32 @@
     for (int i = 0; i < kNumNewPriorityTestMessages; i++)
     {
         msgNet[i] = messagePool->New(ot::Message::kTypeIp6, 0, ot::Message::kPriorityNet);
-        VerifyOrQuit(msgNet[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msgNet[i] != nullptr, "Message::New failed");
         msgHigh[i] = messagePool->New(ot::Message::kTypeIp6, 0, ot::Message::kPriorityHigh);
-        VerifyOrQuit(msgHigh[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msgHigh[i] != nullptr, "Message::New failed");
         msgNor[i] = messagePool->New(ot::Message::kTypeIp6, 0, ot::Message::kPriorityNormal);
-        VerifyOrQuit(msgNor[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msgNor[i] != nullptr, "Message::New failed");
         msgLow[i] = messagePool->New(ot::Message::kTypeIp6, 0, ot::Message::kPriorityLow);
-        VerifyOrQuit(msgLow[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msgLow[i] != nullptr, "Message::New failed");
     }
 
-    // Check the failure case for `New()` for invalid argument.
-    VerifyOrQuit(messagePool->New(ot::Message::kTypeIp6, 0, ot::Message::kNumPriorities) == NULL,
-                 "Message::New() with out of range value did not fail as expected.");
-
     // Use the function "SetPriority()" to allocate messages with different priorities
     for (int i = kNumNewPriorityTestMessages; i < kNumTestMessages; i++)
     {
         msgNet[i] = messagePool->New(ot::Message::kTypeIp6, 0);
-        VerifyOrQuit(msgNet[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msgNet[i] != nullptr, "Message::New failed");
         SuccessOrQuit(msgNet[i]->SetPriority(ot::Message::kPriorityNet), "Message:SetPriority failed");
         msgHigh[i] = messagePool->New(ot::Message::kTypeIp6, 0);
-        VerifyOrQuit(msgHigh[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msgHigh[i] != nullptr, "Message::New failed");
         SuccessOrQuit(msgHigh[i]->SetPriority(ot::Message::kPriorityHigh), "Message:SetPriority failed");
         msgNor[i] = messagePool->New(ot::Message::kTypeIp6, 0);
-        VerifyOrQuit(msgNor[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msgNor[i] != nullptr, "Message::New failed");
         SuccessOrQuit(msgNor[i]->SetPriority(ot::Message::kPriorityNormal), "Message:SetPriority failed");
         msgLow[i] = messagePool->New(ot::Message::kTypeIp6, 0);
-        VerifyOrQuit(msgLow[i] != NULL, "Message::New failed");
+        VerifyOrQuit(msgLow[i] != nullptr, "Message::New failed");
         SuccessOrQuit(msgLow[i]->SetPriority(ot::Message::kPriorityLow), "Message:SetPriority failed");
     }
 
-    // Check the failure case for `SetPriority()` for invalid argument.
-    VerifyOrQuit(msgNet[2]->SetPriority(ot::Message::kNumPriorities) == OT_ERROR_INVALID_ARGS,
-                 "Message::SetPriority() with out of range value did not fail as expected.");
-
     // Check the `GetPriority()`
     for (int i = 0; i < kNumTestMessages; i++)
     {
@@ -210,60 +204,50 @@
     VerifyPriorityQueueContent(queue, 0);
 
     // Add msgs in different orders and check the content of queue.
-    SuccessOrQuit(queue.Enqueue(*msgHigh[0]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgHigh[0]);
     VerifyPriorityQueueContent(queue, 1, msgHigh[0]);
-    SuccessOrQuit(queue.Enqueue(*msgHigh[1]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgHigh[1]);
     VerifyPriorityQueueContent(queue, 2, msgHigh[0], msgHigh[1]);
-    SuccessOrQuit(queue.Enqueue(*msgNet[0]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgNet[0]);
     VerifyPriorityQueueContent(queue, 3, msgNet[0], msgHigh[0], msgHigh[1]);
-    SuccessOrQuit(queue.Enqueue(*msgNet[1]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgNet[1]);
     VerifyPriorityQueueContent(queue, 4, msgNet[0], msgNet[1], msgHigh[0], msgHigh[1]);
-    SuccessOrQuit(queue.Enqueue(*msgHigh[2]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgHigh[2]);
     VerifyPriorityQueueContent(queue, 5, msgNet[0], msgNet[1], msgHigh[0], msgHigh[1], msgHigh[2]);
-    SuccessOrQuit(queue.Enqueue(*msgLow[0]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgLow[0]);
     VerifyPriorityQueueContent(queue, 6, msgNet[0], msgNet[1], msgHigh[0], msgHigh[1], msgHigh[2], msgLow[0]);
-    SuccessOrQuit(queue.Enqueue(*msgNor[0]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgNor[0]);
     VerifyPriorityQueueContent(queue, 7, msgNet[0], msgNet[1], msgHigh[0], msgHigh[1], msgHigh[2], msgNor[0],
                                msgLow[0]);
-    SuccessOrQuit(queue.Enqueue(*msgHigh[3]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgHigh[3]);
     VerifyPriorityQueueContent(queue, 8, msgNet[0], msgNet[1], msgHigh[0], msgHigh[1], msgHigh[2], msgHigh[3],
                                msgNor[0], msgLow[0]);
 
     // Remove messages in different order and check the content of queue in each step.
-    SuccessOrQuit(queue.Dequeue(*msgNet[0]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgNet[0]);
     VerifyPriorityQueueContent(queue, 7, msgNet[1], msgHigh[0], msgHigh[1], msgHigh[2], msgHigh[3], msgNor[0],
                                msgLow[0]);
-    SuccessOrQuit(queue.Dequeue(*msgHigh[2]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgHigh[2]);
     VerifyPriorityQueueContent(queue, 6, msgNet[1], msgHigh[0], msgHigh[1], msgHigh[3], msgNor[0], msgLow[0]);
-    SuccessOrQuit(queue.Dequeue(*msgNor[0]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgNor[0]);
     VerifyPriorityQueueContent(queue, 5, msgNet[1], msgHigh[0], msgHigh[1], msgHigh[3], msgLow[0]);
-    SuccessOrQuit(queue.Dequeue(*msgHigh[1]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgHigh[1]);
     VerifyPriorityQueueContent(queue, 4, msgNet[1], msgHigh[0], msgHigh[3], msgLow[0]);
-    SuccessOrQuit(queue.Dequeue(*msgLow[0]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgLow[0]);
     VerifyPriorityQueueContent(queue, 3, msgNet[1], msgHigh[0], msgHigh[3]);
-    SuccessOrQuit(queue.Dequeue(*msgNet[1]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgNet[1]);
     VerifyPriorityQueueContent(queue, 2, msgHigh[0], msgHigh[3]);
-    SuccessOrQuit(queue.Dequeue(*msgHigh[0]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgHigh[0]);
     VerifyPriorityQueueContent(queue, 1, msgHigh[3]);
-    SuccessOrQuit(queue.Dequeue(*msgHigh[3]), "PriorityQueue::Dequeue() failed.");
-    VerifyPriorityQueueContent(queue, 0);
-
-    // Check the failure cases: Enqueuing an already queued message, or dequeuing a message not queued.
-    SuccessOrQuit(queue.Enqueue(*msgNet[0]), "PriorityQueue::Enqueue() failed.");
-    VerifyPriorityQueueContent(queue, 1, msgNet[0]);
-    VerifyOrQuit(queue.Enqueue(*msgNet[0]) == OT_ERROR_ALREADY,
-                 "Enqueuing an already queued message did not fail as expected.");
-    VerifyOrQuit(queue.Dequeue(*msgHigh[0]) == OT_ERROR_NOT_FOUND,
-                 "Dequeuing a message not queued, did not fail as expected.");
-    SuccessOrQuit(queue.Dequeue(*msgNet[0]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgHigh[3]);
     VerifyPriorityQueueContent(queue, 0);
 
     // Change the priority of an already queued message and check the order change in the queue.
-    SuccessOrQuit(queue.Enqueue(*msgNor[0]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgNor[0]);
     VerifyPriorityQueueContent(queue, 1, msgNor[0]);
-    SuccessOrQuit(queue.Enqueue(*msgHigh[0]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgHigh[0]);
     VerifyPriorityQueueContent(queue, 2, msgHigh[0], msgNor[0]);
-    SuccessOrQuit(queue.Enqueue(*msgLow[0]), "PriorityQueue::Enqueue() failed.");
+    queue.Enqueue(*msgLow[0]);
     VerifyPriorityQueueContent(queue, 3, msgHigh[0], msgNor[0], msgLow[0]);
 
     SuccessOrQuit(msgNor[0]->SetPriority(ot::Message::kPriorityNet),
@@ -287,9 +271,9 @@
                   "SetPriority failed for an already queued message.");
     VerifyPriorityQueueContent(queue, 3, msgHigh[0], msgNor[0], msgLow[0]);
 
-    SuccessOrQuit(messageQueue.Enqueue(*msgNor[1]), "MessageQueue::Enqueue() failed.");
-    SuccessOrQuit(messageQueue.Enqueue(*msgHigh[1]), "MessageQueue::Enqueue() failed.");
-    SuccessOrQuit(messageQueue.Enqueue(*msgNet[1]), "MessageQueue::Enqueue() failed.");
+    messageQueue.Enqueue(*msgNor[1]);
+    messageQueue.Enqueue(*msgHigh[1]);
+    messageQueue.Enqueue(*msgNet[1]);
     VerifyMsgQueueContent(messageQueue, 3, msgNor[1], msgHigh[1], msgNet[1]);
 
     // Change priority of message and check for not in messageQueue.
@@ -303,19 +287,19 @@
     VerifyMsgQueueContent(messageQueue, 3, msgNor[1], msgHigh[1], msgNet[1]);
 
     // Remove messages from the two queues
-    SuccessOrQuit(queue.Dequeue(*msgHigh[0]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgHigh[0]);
     VerifyPriorityQueueContent(queue, 2, msgLow[0], msgNor[0]);
     VerifyMsgQueueContent(messageQueue, 3, msgNor[1], msgHigh[1], msgNet[1]);
 
-    SuccessOrQuit(messageQueue.Dequeue(*msgNet[1]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msgNet[1]);
     VerifyPriorityQueueContent(queue, 2, msgLow[0], msgNor[0]);
     VerifyMsgQueueContent(messageQueue, 2, msgNor[1], msgHigh[1]);
 
-    SuccessOrQuit(messageQueue.Dequeue(*msgHigh[1]), "MessageQueue::Dequeue() failed.");
+    messageQueue.Dequeue(*msgHigh[1]);
     VerifyPriorityQueueContent(queue, 2, msgLow[0], msgNor[0]);
     VerifyMsgQueueContent(messageQueue, 1, msgNor[1]);
 
-    SuccessOrQuit(queue.Dequeue(*msgLow[0]), "PriorityQueue::Dequeue() failed.");
+    queue.Dequeue(*msgLow[0]);
     VerifyPriorityQueueContent(queue, 1, msgNor[0]);
     VerifyMsgQueueContent(messageQueue, 1, msgNor[1]);
 
diff --git a/tests/unit/test_pskc.cpp b/tests/unit/test_pskc.cpp
index e80d0cd..da708ab 100644
--- a/tests/unit/test_pskc.cpp
+++ b/tests/unit/test_pskc.cpp
@@ -29,23 +29,23 @@
 
 #include "common/logging.hpp"
 #include "meshcop/commissioner.hpp"
+#include "meshcop/meshcop.hpp"
 
 #include "test_platform.h"
 #include "test_util.h"
 
-#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
-
-static const otExtendedPanId sXPanId = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+#if OPENTHREAD_FTD
 
 void TestMinimumPassphrase(void)
 {
-    ot::Pskc      pskc;
-    const uint8_t expectedPskc[] = {0x44, 0x98, 0x8e, 0x22, 0xcf, 0x65, 0x2e, 0xee,
+    ot::Pskc              pskc;
+    const uint8_t         expectedPskc[] = {0x44, 0x98, 0x8e, 0x22, 0xcf, 0x65, 0x2e, 0xee,
                                     0xcc, 0xd1, 0xe4, 0xc0, 0x1d, 0x01, 0x54, 0xf8};
-    const char    passphrase[]   = "123456";
-    otInstance *  instance       = testInitInstance();
-    SuccessOrQuit(ot::MeshCoP::Commissioner::GeneratePskc(passphrase, "OpenThread",
-                                                          static_cast<const ot::Mac::ExtendedPanId &>(sXPanId), pskc),
+    const otExtendedPanId xpanid         = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+    const char            passphrase[]   = "123456";
+    otInstance *          instance       = testInitInstance();
+    SuccessOrQuit(ot::MeshCoP::GeneratePskc(passphrase, *reinterpret_cast<const ot::Mac::NetworkName *>("OpenThread"),
+                                            static_cast<const ot::Mac::ExtendedPanId &>(xpanid), pskc),
                   "TestMinimumPassphrase failed to generate PSKc");
     VerifyOrQuit(memcmp(pskc.m8, expectedPskc, sizeof(pskc)) == 0, "TestMinimumPassphrase got wrong pskc");
     testFreeInstance(instance);
@@ -53,10 +53,11 @@
 
 void TestMaximumPassphrase(void)
 {
-    ot::Pskc      pskc;
-    const uint8_t expectedPskc[] = {0x9e, 0x81, 0xbd, 0x35, 0xa2, 0x53, 0x76, 0x2f,
+    ot::Pskc              pskc;
+    const uint8_t         expectedPskc[] = {0x9e, 0x81, 0xbd, 0x35, 0xa2, 0x53, 0x76, 0x2f,
                                     0x80, 0xee, 0x04, 0xff, 0x2f, 0xa2, 0x85, 0xe9};
-    const char    passphrase[]   = "1234567812345678"
+    const otExtendedPanId xpanid         = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+    const char            passphrase[]   = "1234567812345678"
                               "1234567812345678"
                               "1234567812345678"
                               "1234567812345678"
@@ -74,27 +75,44 @@
                               "123456781234567";
 
     otInstance *instance = testInitInstance();
-    SuccessOrQuit(ot::MeshCoP::Commissioner::GeneratePskc(passphrase, "OpenThread",
-                                                          static_cast<const ot::Mac::ExtendedPanId &>(sXPanId), pskc),
+    SuccessOrQuit(ot::MeshCoP::GeneratePskc(passphrase, *reinterpret_cast<const ot::Mac::NetworkName *>("OpenThread"),
+                                            static_cast<const ot::Mac::ExtendedPanId &>(xpanid), pskc),
                   "TestMaximumPassphrase failed to generate PSKc");
     VerifyOrQuit(memcmp(pskc.m8, expectedPskc, sizeof(pskc)) == 0, "TestMaximumPassphrase got wrong pskc");
     testFreeInstance(instance);
 }
 
+void TestExampleInSpec(void)
+{
+    ot::Pskc              pskc;
+    const uint8_t         expectedPskc[] = {0xc3, 0xf5, 0x93, 0x68, 0x44, 0x5a, 0x1b, 0x61,
+                                    0x06, 0xbe, 0x42, 0x0a, 0x70, 0x6d, 0x4c, 0xc9};
+    const otExtendedPanId xpanid         = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}};
+    const char            passphrase[]   = "12SECRETPASSWORD34";
+
+    otInstance *instance = testInitInstance();
+    SuccessOrQuit(ot::MeshCoP::GeneratePskc(passphrase, *reinterpret_cast<const ot::Mac::NetworkName *>("Test Network"),
+                                            static_cast<const ot::Mac::ExtendedPanId &>(xpanid), pskc),
+                  "ExampleInSpec failed to generate PSKc");
+    VerifyOrQuit(memcmp(pskc.m8, expectedPskc, sizeof(pskc)) == 0, "TestExampleInSpec got wrong pskc");
+    testFreeInstance(instance);
+}
+
 int main(void)
 {
     TestMinimumPassphrase();
     TestMaximumPassphrase();
+    TestExampleInSpec();
     printf("All tests passed\n");
     return 0;
 }
 
-#else // #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
+#else // #if OPENTHREAD_FTD
 
 int main(void)
 {
-    printf("Commissioenr role disabled\n");
+    printf("PSKc generation is not supported on non-ftd build\n");
     return 0;
 }
 
-#endif // #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
+#endif // #if OPENTHREAD_FTD
diff --git a/tests/unit/test_spinel_buffer.cpp b/tests/unit/test_spinel_buffer.cpp
new file mode 100644
index 0000000..9c14fa2
--- /dev/null
+++ b/tests/unit/test_spinel_buffer.cpp
@@ -0,0 +1,1067 @@
+/*
+ *  Copyright (c) 2016, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+
+#include "common/code_utils.hpp"
+#include "common/instance.hpp"
+#include "common/message.hpp"
+#include "common/random.hpp"
+#include "lib/spinel/spinel_buffer.hpp"
+
+#include "test_platform.h"
+#include "test_util.hpp"
+
+namespace ot {
+namespace Spinel {
+
+// This module implements unit-test for Spinel::Buffer class.
+
+// Test related constants:
+enum
+{
+    kTestBufferSize       = 800,
+    kTestIterationAttemps = 10000,
+    kTagArraySize         = 1000,
+};
+
+//  Messages used for building frames...
+static const uint8_t sOpenThreadText[] = "OpenThread Rocks";
+static const uint8_t sHelloText[]      = "Hello there!";
+static const uint8_t sMottoText[]      = "Think good thoughts, say good words, do good deeds!";
+static const uint8_t sMysteryText[]    = "4871(\\):|(3$}{4|/4/2%14(\\)";
+static const uint8_t sHexText[]        = "0123456789abcdef";
+
+static ot::Instance *sInstance;
+static MessagePool * sMessagePool;
+
+struct CallbackContext
+{
+    uint32_t mFrameAddedCount;   // Number of times FrameAddedCallback is invoked.
+    uint32_t mFrameRemovedCount; // Number of times FrameRemovedCallback is invoked.
+};
+
+CallbackContext sContext;
+
+enum
+{
+    kNumPrios = 2, // Number of priority levels.
+
+    kTestFrame1Size = sizeof(sMottoText) + sizeof(sMysteryText) + sizeof(sMottoText) + sizeof(sHelloText),
+    kTestFrame2Size = sizeof(sMysteryText) + sizeof(sHelloText) + sizeof(sOpenThreadText),
+    kTestFrame3Size = sizeof(sMysteryText),
+    kTestFrame4Size = sizeof(sOpenThreadText),
+};
+
+Spinel::Buffer::FrameTag sTagHistoryArray[kNumPrios][kTagArraySize];
+uint32_t                 sTagHistoryHead[kNumPrios] = {0};
+uint32_t                 sTagHistoryTail[kNumPrios] = {0};
+Spinel::Buffer::FrameTag sExpectedRemovedTag        = Spinel::Buffer::kInvalidTag;
+
+void ClearTagHistory(void)
+{
+    for (uint8_t priority = 0; priority < kNumPrios; priority++)
+    {
+        sTagHistoryHead[priority] = sTagHistoryTail[priority];
+    }
+}
+
+void AddTagToHistory(Spinel::Buffer::FrameTag aTag, Spinel::Buffer::Priority aPriority)
+{
+    uint8_t priority = static_cast<uint8_t>(aPriority);
+
+    sTagHistoryArray[priority][sTagHistoryTail[priority]] = aTag;
+
+    if (++sTagHistoryTail[priority] == kTagArraySize)
+    {
+        sTagHistoryTail[priority] = 0;
+    }
+
+    VerifyOrQuit(sTagHistoryTail[priority] != sTagHistoryHead[priority],
+                 "Ran out of space in `TagHistoryArray`, increase its size.");
+}
+
+void VerifyAndRemoveTagFromHistory(Spinel::Buffer::FrameTag aTag, Spinel::Buffer::Priority aPriority)
+{
+    uint8_t priority = static_cast<uint8_t>(aPriority);
+
+    VerifyOrQuit(sTagHistoryHead[priority] != sTagHistoryTail[priority], "Tag history is empty,");
+    VerifyOrQuit(aTag == sTagHistoryArray[priority][sTagHistoryHead[priority]],
+                 "Removed tag does not match the added one");
+
+    if (++sTagHistoryHead[priority] == kTagArraySize)
+    {
+        sTagHistoryHead[priority] = 0;
+    }
+
+    if (sExpectedRemovedTag != Spinel::Buffer::kInvalidTag)
+    {
+        VerifyOrQuit(sExpectedRemovedTag == aTag, "Removed tag does match the previous OutFrameGetTag()");
+        sExpectedRemovedTag = Spinel::Buffer::kInvalidTag;
+    }
+}
+
+void FrameAddedCallback(void *                   aContext,
+                        Spinel::Buffer::FrameTag aTag,
+                        Spinel::Buffer::Priority aPriority,
+                        Spinel::Buffer *         aNcpBuffer)
+{
+    CallbackContext *callbackContext = reinterpret_cast<CallbackContext *>(aContext);
+
+    VerifyOrQuit(aNcpBuffer != nullptr, "Null Spinel::Buffer in the callback");
+    VerifyOrQuit(callbackContext != nullptr, "Null context in the callback");
+    VerifyOrQuit(aTag != Spinel::Buffer::kInvalidTag, "Invalid tag in the callback");
+    VerifyOrQuit(aTag == aNcpBuffer->InFrameGetLastTag(), "InFrameGetLastTag() does not match the tag from callback");
+
+    AddTagToHistory(aTag, aPriority);
+
+    callbackContext->mFrameAddedCount++;
+}
+
+void FrameRemovedCallback(void *                   aContext,
+                          Spinel::Buffer::FrameTag aTag,
+                          Spinel::Buffer::Priority aPriority,
+                          Spinel::Buffer *         aNcpBuffer)
+{
+    CallbackContext *callbackContext = reinterpret_cast<CallbackContext *>(aContext);
+
+    VerifyOrQuit(aNcpBuffer != nullptr, "Null Spinel::Buffer in the callback");
+    VerifyOrQuit(callbackContext != nullptr, "Null context in the callback");
+    VerifyOrQuit(aTag != Spinel::Buffer::kInvalidTag, "Invalid tag in the callback");
+
+    VerifyAndRemoveTagFromHistory(aTag, aPriority);
+
+    callbackContext->mFrameRemovedCount++;
+}
+
+// Reads bytes from the ncp buffer, and verifies that it matches with the given content buffer.
+void ReadAndVerifyContent(Spinel::Buffer &aNcpBuffer, const uint8_t *aContentBuffer, uint16_t aBufferLength)
+{
+    while (aBufferLength--)
+    {
+        VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == false, "Out frame ended before end of expected content.");
+
+        VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == *aContentBuffer++,
+                     "Out frame read byte does not match expected content");
+    }
+}
+
+void WriteTestFrame1(Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
+{
+    Message *       message;
+    CallbackContext oldContext;
+
+    message = sMessagePool->New(Message::kTypeIp6, 0);
+    VerifyOrQuit(message != nullptr, "Null Message");
+    SuccessOrQuit(message->SetLength(sizeof(sMottoText)), "Could not set the length of message.");
+    message->Write(0, sizeof(sMottoText), sMottoText);
+
+    oldContext = sContext;
+    aNcpBuffer.InFrameBegin(aPriority);
+    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMottoText, sizeof(sMottoText)), "InFrameFeedData() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMysteryText, sizeof(sMysteryText)), "InFrameFeedData() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message), "InFrameFeedMessage() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)), "InFrameFeedData() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+}
+
+void VerifyAndRemoveFrame1(Spinel::Buffer &aNcpBuffer)
+{
+    CallbackContext oldContext = sContext;
+
+    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
+    VerifyOrQuit(sExpectedRemovedTag == aNcpBuffer.OutFrameGetTag(), "OutFrameGetTag() value changed unexpectedly.");
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    ReadAndVerifyContent(aNcpBuffer, sMottoText, sizeof(sMottoText));
+    ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
+    ReadAndVerifyContent(aNcpBuffer, sMottoText, sizeof(sMottoText));
+    ReadAndVerifyContent(aNcpBuffer, sHelloText, sizeof(sHelloText));
+    VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
+    VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
+    VerifyOrQuit(sExpectedRemovedTag == aNcpBuffer.OutFrameGetTag(), "OutFrameGetTag() value changed unexpectedly.");
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "Remove() failed.");
+    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+}
+
+void WriteTestFrame2(Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
+{
+    Message *       message1;
+    Message *       message2;
+    CallbackContext oldContext = sContext;
+
+    message1 = sMessagePool->New(Message::kTypeIp6, 0);
+    VerifyOrQuit(message1 != nullptr, "Null Message");
+    SuccessOrQuit(message1->SetLength(sizeof(sMysteryText)), "Could not set the length of message.");
+    message1->Write(0, sizeof(sMysteryText), sMysteryText);
+
+    message2 = sMessagePool->New(Message::kTypeIp6, 0);
+    VerifyOrQuit(message2 != nullptr, "Null Message");
+    SuccessOrQuit(message2->SetLength(sizeof(sHelloText)), "Could not set the length of message.");
+    message2->Write(0, sizeof(sHelloText), sHelloText);
+
+    aNcpBuffer.InFrameBegin(aPriority);
+    SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message1), "InFrameFeedMessage() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message2), "InFrameFeedMessage() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+
+    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+}
+
+void VerifyAndRemoveFrame2(Spinel::Buffer &aNcpBuffer)
+{
+    CallbackContext oldContext = sContext;
+
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size, "GetLength() is incorrect.");
+    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size, "GetLength() is incorrect.");
+    ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
+    ReadAndVerifyContent(aNcpBuffer, sOpenThreadText, sizeof(sOpenThreadText));
+    ReadAndVerifyContent(aNcpBuffer, sHelloText, sizeof(sHelloText));
+    VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
+    VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
+    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size, "GetLength() is incorrect.");
+    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "Remove() failed.");
+
+    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+}
+
+void WriteTestFrame3(Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
+{
+    Message *       message1;
+    CallbackContext oldContext = sContext;
+
+    message1 = sMessagePool->New(Message::kTypeIp6, 0);
+    VerifyOrQuit(message1 != nullptr, "Null Message");
+
+    // An empty message with no content.
+    SuccessOrQuit(message1->SetLength(0), "Could not set the length of message.");
+
+    aNcpBuffer.InFrameBegin(aPriority);
+    SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message1), "InFrameFeedMessage() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMysteryText, sizeof(sMysteryText)), "InFrameFeedData() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+
+    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+}
+
+void VerifyAndRemoveFrame3(Spinel::Buffer &aNcpBuffer)
+{
+    CallbackContext oldContext = sContext;
+
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText), "GetLength() is incorrect.");
+    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText), "GetLength() is incorrect.");
+    ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
+    VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
+    VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
+    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText), "GetLength() is incorrect.");
+    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "Remove() failed.");
+
+    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+}
+
+void WriteTestFrame4(Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
+{
+    CallbackContext oldContext = sContext;
+
+    aNcpBuffer.InFrameBegin(aPriority);
+    SuccessOrQuit(aNcpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
+    SuccessOrQuit(aNcpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+
+    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+}
+
+void VerifyAndRemoveFrame4(Spinel::Buffer &aNcpBuffer)
+{
+    CallbackContext oldContext = sContext;
+
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText), "GetLength() is incorrect.");
+    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText), "GetLength() is incorrect.");
+    ReadAndVerifyContent(aNcpBuffer, sOpenThreadText, sizeof(sOpenThreadText));
+    VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
+    VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
+    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText), "GetLength() is incorrect.");
+    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "Remove() failed.");
+
+    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+}
+
+// This function implements the Spinel::Buffer tests
+void TestBuffer(void)
+{
+    unsigned       i, j;
+    uint8_t        buffer[kTestBufferSize];
+    Spinel::Buffer ncpBuffer(buffer, kTestBufferSize);
+
+    Message *                     message;
+    uint8_t                       readBuffer[16];
+    uint16_t                      readLen, readOffset;
+    Spinel::Buffer::WritePosition pos1, pos2;
+
+    sInstance    = testInitInstance();
+    sMessagePool = &sInstance->Get<MessagePool>();
+
+    for (i = 0; i < sizeof(buffer); i++)
+    {
+        buffer[i] = 0;
+    }
+
+    sContext.mFrameAddedCount   = 0;
+    sContext.mFrameRemovedCount = 0;
+    ClearTagHistory();
+
+    // Set the callbacks.
+    ncpBuffer.SetFrameAddedCallback(FrameAddedCallback, &sContext);
+    ncpBuffer.SetFrameRemovedCallback(FrameRemovedCallback, &sContext);
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 1: Check initial buffer state");
+
+    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "Not empty after init.");
+    VerifyOrQuit(ncpBuffer.InFrameGetLastTag() == Spinel::Buffer::kInvalidTag, "Incorrect tag after init.");
+    VerifyOrQuit(ncpBuffer.OutFrameGetTag() == Spinel::Buffer::kInvalidTag, "Incorrect OutFrameTag after init.");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 2: Write and read a single frame");
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    DumpBuffer("\nBuffer after frame1 (low priority)", buffer, kTestBufferSize);
+    printf("\nFrameLen is %u", ncpBuffer.OutFrameGetLength());
+    VerifyAndRemoveFrame1(ncpBuffer);
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    DumpBuffer("\nBuffer after frame1 (high priority)", buffer, kTestBufferSize);
+    printf("\nFrameLen is %u", ncpBuffer.OutFrameGetLength());
+    VerifyAndRemoveFrame1(ncpBuffer);
+
+    printf("\nIterations: ");
+
+    // Always add as low priority.
+    for (j = 0; j < kTestIterationAttemps; j++)
+    {
+        printf("*");
+        WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+        VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
+
+        VerifyAndRemoveFrame1(ncpBuffer);
+        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
+    }
+
+    // Always add as high priority.
+    for (j = 0; j < kTestIterationAttemps; j++)
+    {
+        printf("*");
+        WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+        VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
+
+        VerifyAndRemoveFrame1(ncpBuffer);
+        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
+    }
+
+    // Every 5th add as high priority.
+    for (j = 0; j < kTestIterationAttemps; j++)
+    {
+        printf("*");
+        WriteTestFrame1(ncpBuffer, ((j % 5) == 0) ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow);
+        VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
+
+        VerifyAndRemoveFrame1(ncpBuffer);
+        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
+    }
+
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 3: Multiple frames write and read (same priority)");
+
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+
+    DumpBuffer("\nBuffer after multiple frames", buffer, kTestBufferSize);
+
+    VerifyAndRemoveFrame2(ncpBuffer);
+    VerifyAndRemoveFrame3(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+
+    printf("\nIterations: ");
+
+    // Repeat this multiple times.
+    for (j = 0; j < kTestIterationAttemps; j++)
+    {
+        printf("*");
+
+        WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+        WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
+        WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+
+        VerifyAndRemoveFrame2(ncpBuffer);
+        VerifyAndRemoveFrame3(ncpBuffer);
+
+        WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+        WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
+
+        VerifyAndRemoveFrame2(ncpBuffer);
+        VerifyAndRemoveFrame2(ncpBuffer);
+        VerifyAndRemoveFrame3(ncpBuffer);
+
+        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
+    }
+
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 4: Multiple frames write and read (mixed priority)");
+
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyAndRemoveFrame3(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyAndRemoveFrame3(ncpBuffer);
+    VerifyAndRemoveFrame4(ncpBuffer);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    VerifyAndRemoveFrame4(ncpBuffer);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyAndRemoveFrame3(ncpBuffer);
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    VerifyAndRemoveFrame4(ncpBuffer);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyAndRemoveFrame3(ncpBuffer);
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    VerifyAndRemoveFrame3(ncpBuffer);
+    VerifyAndRemoveFrame4(ncpBuffer);
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyAndRemoveFrame3(ncpBuffer);
+    VerifyAndRemoveFrame4(ncpBuffer);
+    VerifyAndRemoveFrame1(ncpBuffer);
+
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 5: Frame discard when buffer full and partial read restart");
+
+    printf("\nIterations: ");
+
+    for (j = 0; j < kTestIterationAttemps; j++)
+    {
+        bool frame1IsHighPriority = ((j % 3) == 0);
+
+        printf("*");
+
+        WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+        WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+
+        ncpBuffer.InFrameBegin((j % 2) == 0 ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow);
+        SuccessOrQuit(ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)), "InFrameFeedData() failed.");
+
+        message = sMessagePool->New(Message::kTypeIp6, 0);
+        VerifyOrQuit(message != nullptr, "Null Message");
+        SuccessOrQuit(message->SetLength(sizeof(sMysteryText)), "Could not set the length of message.");
+        message->Write(0, sizeof(sMysteryText), sMysteryText);
+
+        SuccessOrQuit(ncpBuffer.InFrameFeedMessage(message), "InFrameFeedMessage() failed.");
+
+        // Start writing a new frame in middle of an unfinished frame. Ensure the first one is discarded.
+        WriteTestFrame1(ncpBuffer, frame1IsHighPriority ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow);
+
+        // Note that message will not be freed by the NCP buffer since the frame associated with it was discarded and
+        // not yet finished/ended.
+        otMessageFree(message);
+
+        VerifyAndRemoveFrame3(ncpBuffer);
+
+        // Start reading few bytes from the frame
+        SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed.");
+        ncpBuffer.OutFrameReadByte();
+        ncpBuffer.OutFrameReadByte();
+        ncpBuffer.OutFrameReadByte();
+
+        // Now reset the read pointer and read/verify the frame from start.
+        if (frame1IsHighPriority)
+        {
+            VerifyAndRemoveFrame1(ncpBuffer);
+            VerifyAndRemoveFrame2(ncpBuffer);
+        }
+        else
+        {
+            VerifyAndRemoveFrame2(ncpBuffer);
+            VerifyAndRemoveFrame1(ncpBuffer);
+        }
+
+        VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
+    }
+
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 6: Clear() and empty buffer method tests");
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+
+    ncpBuffer.Clear();
+    ClearTagHistory();
+
+    VerifyOrQuit(ncpBuffer.InFrameGetLastTag() == Spinel::Buffer::kInvalidTag, "Incorrect last tag after Clear().");
+    VerifyOrQuit(ncpBuffer.OutFrameGetTag() == Spinel::Buffer::kInvalidTag, "Incorrect OutFrameTag after Clear().");
+    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
+    VerifyOrQuit(ncpBuffer.OutFrameHasEnded() == true, "OutFrameHasEnded() is incorrect when no data in buffer.");
+    VerifyOrQuit(ncpBuffer.OutFrameRemove() == OT_ERROR_NOT_FOUND,
+                 "Remove() returned incorrect error status when buffer is empty.");
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == 0,
+                 "OutFrameGetLength() returned non-zero length when buffer is empty.");
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    VerifyAndRemoveFrame1(ncpBuffer);
+
+    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() is incorrect when buffer is empty.");
+    VerifyOrQuit(ncpBuffer.OutFrameHasEnded() == true, "OutFrameHasEnded() is incorrect when no data in buffer.");
+    VerifyOrQuit(ncpBuffer.OutFrameRemove() == OT_ERROR_NOT_FOUND,
+                 "Remove() returned incorrect error status when buffer is empty.");
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == 0,
+                 "OutFrameGetLength() returned non-zero length when buffer is empty.");
+
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 7: OutFrameRead() in parts\n");
+
+    ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityLow);
+    SuccessOrQuit(ncpBuffer.InFrameFeedData(sMottoText, sizeof(sMottoText)), "InFrameFeedData() failed.");
+    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+
+    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed.");
+    readOffset = 0;
+
+    while ((readLen = ncpBuffer.OutFrameRead(sizeof(readBuffer), readBuffer)) != 0)
+    {
+        DumpBuffer("Read() returned", readBuffer, readLen);
+
+        VerifyOrQuit(memcmp(readBuffer, sMottoText + readOffset, readLen) == 0,
+                     "Read() does not match expected content.");
+
+        readOffset += readLen;
+    }
+
+    VerifyOrQuit(readOffset == sizeof(sMottoText), "Read len does not match expected length.");
+
+    SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed.");
+
+    printf("\n -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 8: Remove a frame without reading it first");
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    SuccessOrQuit(ncpBuffer.OutFrameRemove(), "Remove() failed.");
+    VerifyAndRemoveFrame2(ncpBuffer);
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 9: Check length when front frame gets changed (a higher priority frame is added)");
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame3Size, "GetLength() is incorrect.");
+    VerifyAndRemoveFrame3(ncpBuffer);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\nTest 10: Active out frame remaining unchanged when a higher priority frame is written while reading it");
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
+    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
+    ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
+    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
+    ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
+    VerifyOrQuit(ncpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    VerifyAndRemoveFrame3(ncpBuffer);
+    VerifyAndRemoveFrame4(ncpBuffer);
+    // Repeat test reversing frame priority orders.
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
+    SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed unexpectedly.");
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
+    ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
+    ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
+    ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
+    VerifyOrQuit(ncpBuffer.OutFrameHasEnded() == true, "Frame longer than expected.");
+    WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size, "GetLength() is incorrect.");
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyAndRemoveFrame3(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    VerifyAndRemoveFrame4(ncpBuffer);
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\n Test 11: Read and remove in middle of an active input frame write");
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityHigh);
+    SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() failed.");
+    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+    VerifyAndRemoveFrame4(ncpBuffer);
+    // Repeat the test reversing priorities
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityLow);
+    SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() failed.");
+    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+    VerifyAndRemoveFrame4(ncpBuffer);
+    // Repeat the test with same priorities
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityHigh);
+    SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)), "InFrameFeedData() failed.");
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() failed.");
+    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+    VerifyAndRemoveFrame4(ncpBuffer);
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\n Test 12: Check returned error status");
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityHigh);
+    VerifyOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer)) == OT_ERROR_NO_BUFS, "Incorrect error status");
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty() failed.");
+
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    // Ensure writes with starting `InFrameBegin()` fail
+    VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 1) == OT_ERROR_INVALID_STATE, "Incorrect error status");
+    VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 0) == OT_ERROR_INVALID_STATE, "Incorrect error status");
+    VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 0) == OT_ERROR_INVALID_STATE, "Incorrect error status");
+    VerifyOrQuit(ncpBuffer.InFrameEnd() == OT_ERROR_INVALID_STATE, "Incorrect error status");
+    message = sMessagePool->New(Message::kTypeIp6, 0);
+    VerifyOrQuit(message != nullptr, "Null Message");
+    SuccessOrQuit(message->SetLength(sizeof(sMysteryText)), "Could not set the length of message.");
+    message->Write(0, sizeof(sMysteryText), sMysteryText);
+    VerifyOrQuit(ncpBuffer.InFrameFeedMessage(message) == OT_ERROR_INVALID_STATE, "Incorrect error status");
+    message->Free();
+    VerifyOrQuit(ncpBuffer.InFrameEnd() == OT_ERROR_INVALID_STATE, "Incorrect error status");
+    VerifyAndRemoveFrame2(ncpBuffer);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() failed");
+    VerifyOrQuit(ncpBuffer.OutFrameBegin() == OT_ERROR_NOT_FOUND, "OutFrameBegin() failed on empty queue");
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() failed");
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\n Test 13: Ensure we can utilize the full buffer size when frames removed during write");
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityHigh);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    SuccessOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer) - 4), "InFrameFeedData() failed.");
+    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+    SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed.");
+    // Repeat the test with a low priority buffer write
+    WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
+    WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
+    ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityLow);
+    VerifyAndRemoveFrame1(ncpBuffer);
+    VerifyAndRemoveFrame2(ncpBuffer);
+    SuccessOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer) - 4), "InFrameFeedData() failed.");
+    SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+    SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed.");
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\n Test 14: Test InFrameOverwrite ");
+    printf("\nIterations: ");
+
+    for (j = 0; j < kTestIterationAttemps; j++)
+    {
+        uint16_t                 index;
+        bool                     addExtra = ((j % 7) != 0);
+        Spinel::Buffer::Priority priority;
+
+        printf("*");
+        priority = ((j % 3) == 0) ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow;
+        index    = static_cast<uint16_t>(j % sizeof(sHexText));
+        ncpBuffer.InFrameBegin(priority);
+        SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText, index), "InFrameFeedData() failed.");
+        SuccessOrQuit(ncpBuffer.InFrameGetPosition(pos1), "InFrameGetPosition() failed");
+        SuccessOrQuit(ncpBuffer.InFrameFeedData(sMysteryText, sizeof(sHexText) - index), "InFrameFeedData() failed.");
+        VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index, "InFrameGetDistance() failed");
+
+        if (addExtra)
+        {
+            SuccessOrQuit(ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)), "InFrameFeedData() failed.");
+        }
+
+        SuccessOrQuit(ncpBuffer.InFrameOverwrite(pos1, sHexText + index, sizeof(sHexText) - index),
+                      "InFrameOverwrite() failed.");
+        VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) ==
+                         sizeof(sHexText) - index + (addExtra ? sizeof(sHelloText) : 0),
+                     "InFrameGetDistance() failed");
+        SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+        VerifyOrQuit(ncpBuffer.InFrameGetPosition(pos2) == OT_ERROR_INVALID_STATE, "GetPosition failed.");
+        VerifyOrQuit(ncpBuffer.InFrameOverwrite(pos1, sHexText, 0) != OT_ERROR_NONE, "Failed to give error.");
+        SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed");
+        ReadAndVerifyContent(ncpBuffer, sHexText, sizeof(sHexText));
+
+        if (addExtra)
+        {
+            ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
+        }
+
+        SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed");
+        VerifyOrQuit(ncpBuffer.InFrameGetPosition(pos2) == OT_ERROR_INVALID_STATE, "GetPosition failed");
+    }
+
+    printf(" -- PASS\n");
+
+    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    printf("\n Test 15: Test InFrameReset()");
+    printf("\nIterations: ");
+
+    for (j = 0; j < kTestIterationAttemps; j++)
+    {
+        uint16_t                 index;
+        bool                     addExtra = ((j % 7) != 0);
+        Spinel::Buffer::Priority priority;
+
+        printf("*");
+        priority = ((j % 3) == 0) ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow;
+        index    = static_cast<uint16_t>(j % sizeof(sHexText));
+        ncpBuffer.InFrameBegin(priority);
+        SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText, index), "InFrameFeedData() failed.");
+        SuccessOrQuit(ncpBuffer.InFrameGetPosition(pos1), "InFrameGetPosition() failed");
+        SuccessOrQuit(ncpBuffer.InFrameFeedData(sMysteryText, sizeof(sHexText) - index), "InFrameFeedData() failed.");
+        VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index, "InFrameGetDistance() failed");
+
+        if (addExtra)
+        {
+            SuccessOrQuit(ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)), "InFrameFeedData() failed.");
+        }
+
+        SuccessOrQuit(ncpBuffer.InFrameReset(pos1), "InFrameReset() failed.");
+        SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText + index, sizeof(sHexText) - index),
+                      "InFrameOverwrite() failed.");
+
+        if (addExtra)
+        {
+            SuccessOrQuit(ncpBuffer.InFrameReset(pos1), "InFrameReset() failed.");
+            SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText + index, sizeof(sHexText) - index),
+                          "InFrameOverwrite() failed.");
+        }
+
+        VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index, "InFrameGetDistance() failed");
+        SuccessOrQuit(ncpBuffer.InFrameEnd(), "InFrameEnd() failed.");
+        SuccessOrQuit(ncpBuffer.OutFrameBegin(), "OutFrameBegin() failed");
+        ReadAndVerifyContent(ncpBuffer, sHexText, sizeof(sHexText));
+        SuccessOrQuit(ncpBuffer.OutFrameRemove(), "OutFrameRemove() failed");
+    }
+
+    printf(" -- PASS\n");
+
+    testFreeInstance(sInstance);
+}
+
+/**
+ * NCP Buffer Fuzz testing
+ *
+ * Randomly decide if to read or write a frame to the NCP buffer (use `kReadProbability` in percent to control the
+ * behavior).
+ *
+ * When writing a frame, use a random length (1 up to `kMaxFrameLen`) and generate random byte sequences.
+ * When reading a frame ensure the length and the content matches what was written earlier.
+ * Handle the cases where buffer gets full or empty.
+ *
+ */
+
+enum
+{
+    kFuzTestBufferSize            = 2000,   // Size of the buffer used during fuzz testing
+    kFuzTestIterationAttempts     = 500000, // Number of iterations  to run
+    kLensArraySize                = 500,    // Size of "Lengths" array.
+    kMaxFrameLen                  = 400,    // Maximum frame length
+    kReadProbability              = 50,     // Probability (in percent) to randomly choose to read vs write frame
+    kHighPriorityProbability      = 20,     // Probability (in percent) to write a high priority frame
+    kUseTrueRandomNumberGenerator = 1,      // To use true random number generator or not.
+};
+
+uint8_t  sFrameBuffer[kNumPrios][kFuzTestBufferSize];
+uint32_t sFrameBufferTailIndex[kNumPrios] = {0};
+
+uint32_t GetRandom(uint32_t max)
+{
+    uint32_t value;
+
+    if (kUseTrueRandomNumberGenerator)
+    {
+        SuccessOrQuit(Random::Crypto::FillBuffer(reinterpret_cast<uint8_t *>(&value), sizeof(value)),
+                      "Random::Crypto::FillBuffer() failed.");
+    }
+    else
+    {
+        value = Random::NonCrypto::GetUint32();
+    }
+
+    return value % max;
+}
+
+otError WriteRandomFrame(uint32_t aLength, Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
+{
+    otError         error;
+    uint8_t         byte;
+    uint8_t         priority   = static_cast<uint8_t>(aPriority);
+    CallbackContext oldContext = sContext;
+    uint32_t        tail       = sFrameBufferTailIndex[priority];
+
+    aNcpBuffer.InFrameBegin(aPriority);
+
+    while (aLength--)
+    {
+        byte = static_cast<uint8_t>(GetRandom(256));
+        SuccessOrExit(error = aNcpBuffer.InFrameFeedData(&byte, sizeof(byte)));
+        sFrameBuffer[priority][tail++] = byte;
+    }
+
+    SuccessOrExit(error = aNcpBuffer.InFrameEnd());
+
+    sFrameBufferTailIndex[priority] = tail;
+
+    // check the callbacks
+    VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+
+exit:
+    return error;
+}
+
+otError ReadRandomFrame(uint32_t aLength, Spinel::Buffer &aNcpBuffer, uint8_t priority)
+{
+    CallbackContext oldContext = sContext;
+
+    SuccessOrQuit(aNcpBuffer.OutFrameBegin(), "OutFrameBegin failed");
+    VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == aLength, "OutFrameGetLength() does not match");
+
+    // Read and verify that the content is same as sFrameBuffer values...
+    ReadAndVerifyContent(aNcpBuffer, sFrameBuffer[priority], static_cast<uint16_t>(aLength));
+    sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
+
+    SuccessOrQuit(aNcpBuffer.OutFrameRemove(), "OutFrameRemove failed");
+
+    sFrameBufferTailIndex[priority] -= aLength;
+    memmove(sFrameBuffer[priority], sFrameBuffer[priority] + aLength, sFrameBufferTailIndex[priority]);
+
+    // If successful check the callbacks
+    VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
+    VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
+
+    return OT_ERROR_NONE;
+}
+
+// This runs a fuzz test of NCP buffer
+void TestFuzzBuffer(void)
+{
+    uint8_t        buffer[kFuzTestBufferSize];
+    Spinel::Buffer ncpBuffer(buffer, kFuzTestBufferSize);
+
+    uint32_t lensArray[kNumPrios][kLensArraySize]; // Keeps track of length of written frames so far
+    uint32_t lensArrayStart[kNumPrios];
+    uint32_t lensArrayCount[kNumPrios];
+
+    sInstance    = testInitInstance();
+    sMessagePool = &sInstance->Get<MessagePool>();
+
+    memset(buffer, 0, sizeof(buffer));
+
+    memset(lensArray, 0, sizeof(lensArray));
+    memset(lensArrayStart, 0, sizeof(lensArrayStart));
+    memset(lensArrayCount, 0, sizeof(lensArrayCount));
+
+    sContext.mFrameAddedCount   = 0;
+    sContext.mFrameRemovedCount = 0;
+    ClearTagHistory();
+
+    ncpBuffer.SetFrameAddedCallback(FrameAddedCallback, &sContext);
+    ncpBuffer.SetFrameRemovedCallback(FrameRemovedCallback, &sContext);
+
+    for (uint32_t iter = 0; iter < kFuzTestIterationAttempts; iter++)
+    {
+        bool shouldRead;
+
+        if (lensArrayCount[0] == 0 && lensArrayCount[1] == 0)
+        {
+            shouldRead = false;
+        }
+        else if (lensArrayCount[0] == kLensArraySize - 1 || lensArrayCount[1] == kLensArraySize - 1)
+        {
+            shouldRead = true;
+        }
+        else
+        {
+            // Randomly decide to read or write.
+            shouldRead = (GetRandom(100) < kReadProbability);
+        }
+
+        if (shouldRead)
+        {
+            uint32_t len;
+            uint8_t  priority;
+
+            priority = (lensArrayCount[Spinel::Buffer::kPriorityHigh] != 0) ? Spinel::Buffer::kPriorityHigh
+                                                                            : Spinel::Buffer::kPriorityLow;
+
+            len                      = lensArray[priority][lensArrayStart[priority]];
+            lensArrayStart[priority] = (lensArrayStart[priority] + 1) % kLensArraySize;
+            lensArrayCount[priority]--;
+
+            printf("R%c%d ", priority == Spinel::Buffer::kPriorityHigh ? 'H' : 'L', len);
+
+            SuccessOrQuit(ReadRandomFrame(len, ncpBuffer, priority), "Failed to read random frame.");
+        }
+        else
+        {
+            uint32_t                 len = GetRandom(kMaxFrameLen) + 1;
+            Spinel::Buffer::Priority priority;
+
+            if (GetRandom(100) < kHighPriorityProbability)
+            {
+                priority = Spinel::Buffer::kPriorityHigh;
+            }
+            else
+            {
+                priority = Spinel::Buffer::kPriorityLow;
+            }
+
+            if (WriteRandomFrame(len, ncpBuffer, priority) == OT_ERROR_NONE)
+            {
+                lensArray[priority][(lensArrayStart[priority] + lensArrayCount[priority]) % kLensArraySize] = len;
+                lensArrayCount[priority]++;
+
+                printf("W%c%d ", priority == Spinel::Buffer::kPriorityHigh ? 'H' : 'L', len);
+            }
+            else
+            {
+                printf("FULL ");
+            }
+        }
+
+        if (lensArrayCount[0] == 0 && lensArrayCount[1] == 0)
+        {
+            VerifyOrQuit(ncpBuffer.IsEmpty() == true, "IsEmpty failed.");
+            printf("EMPTY ");
+        }
+    }
+
+    printf("\n -- PASS\n");
+
+    testFreeInstance(sInstance);
+}
+
+} // namespace Spinel
+} // namespace ot
+
+int main(void)
+{
+    ot::Spinel::TestBuffer();
+    ot::Spinel::TestFuzzBuffer();
+    printf("\nAll tests passed.\n");
+    return 0;
+}
diff --git a/tests/unit/test_spinel_decoder.cpp b/tests/unit/test_spinel_decoder.cpp
index 0a2d674..96f340a 100644
--- a/tests/unit/test_spinel_decoder.cpp
+++ b/tests/unit/test_spinel_decoder.cpp
@@ -28,22 +28,22 @@
 
 #include "common/code_utils.hpp"
 #include "common/instance.hpp"
-#include "ncp/spinel_decoder.hpp"
+#include "lib/spinel/spinel_decoder.hpp"
 
 #include "test_util.hpp"
 
 namespace ot {
-namespace Ncp {
+namespace Spinel {
 
 enum
 {
     kTestBufferSize = 800,
 };
 
-void TestSpinelDecoder(void)
+void TestDecoder(void)
 {
-    uint8_t       buffer[kTestBufferSize];
-    SpinelDecoder decoder;
+    uint8_t         buffer[kTestBufferSize];
+    Spinel::Decoder decoder;
 
     spinel_ssize_t frameLen;
 
@@ -594,7 +594,7 @@
         SuccessOrQuit(decoder.CloseStruct(), "CloseStruct() failed.");
         SuccessOrQuit(decoder.ReadUint16(u16), "ReadUint16() failed.");
 
-        // `ResetToSaved()` should fail sicne the enclosing struct for the saved position is closed.
+        // `ResetToSaved()` should fail since the enclosing struct for the saved position is closed.
         VerifyOrQuit(decoder.ResetToSaved() == OT_ERROR_INVALID_STATE, "ResetToSaved() did not fail.");
     }
 
@@ -621,13 +621,13 @@
     // bytes in the frame.
     VerifyOrQuit(decoder.OpenStruct() == OT_ERROR_PARSE, "OpenStruct() did not fail.");
 
-    decoder.ResetToSaved();
+    SuccessOrQuit(decoder.ResetToSaved(), "ResetToSaved() failed.");
 
     SuccessOrQuit(decoder.ReadUint8(u8), "ReadUint8() failed.");
     VerifyOrQuit(u8 == kUint8, "ReadUint8() parse failed.");
     VerifyOrQuit(decoder.ReadDataWithLen(dataPtr_1, dataLen_1) == OT_ERROR_PARSE, "ReadDataWithLen() did not fail.");
 
-    decoder.ResetToSaved();
+    SuccessOrQuit(decoder.ResetToSaved(), "ResetToSaved() failed.");
     SuccessOrQuit(decoder.ReadUint8(u8), "ReadUint8() failed.");
     SuccessOrQuit(decoder.ReadUint16(u16), "ReadUint16() failed.");
     SuccessOrQuit(decoder.ReadBool(b_1), "ReadUint16() failed.");
@@ -638,12 +638,12 @@
     printf(" -- PASS\n");
 }
 
-} // namespace Ncp
+} // namespace Spinel
 } // namespace ot
 
 int main(void)
 {
-    ot::Ncp::TestSpinelDecoder();
+    ot::Spinel::Decoder();
     printf("\nAll tests passed.\n");
     return 0;
 }
diff --git a/tests/unit/test_spinel_encoder.cpp b/tests/unit/test_spinel_encoder.cpp
index 3030bc4..65dccd1 100644
--- a/tests/unit/test_spinel_encoder.cpp
+++ b/tests/unit/test_spinel_encoder.cpp
@@ -28,19 +28,19 @@
 
 #include "common/code_utils.hpp"
 #include "common/instance.hpp"
-#include "ncp/spinel_encoder.hpp"
+#include "lib/spinel/spinel_encoder.hpp"
 
 #include "test_util.hpp"
 
 namespace ot {
-namespace Ncp {
+namespace Spinel {
 
 enum
 {
     kTestBufferSize = 800,
 };
 
-otError ReadFrame(NcpFrameBuffer &aNcpBuffer, uint8_t *aFrame, uint16_t &aFrameLen)
+otError ReadFrame(Spinel::Buffer &aNcpBuffer, uint8_t *aFrame, uint16_t &aFrameLen)
 {
     otError error = OT_ERROR_NONE;
 
@@ -53,11 +53,11 @@
     return error;
 }
 
-void TestSpinelEncoder(void)
+void TestEncoder(void)
 {
-    uint8_t        buffer[kTestBufferSize];
-    NcpFrameBuffer ncpBuffer(buffer, kTestBufferSize);
-    SpinelEncoder  encoder(ncpBuffer);
+    uint8_t         buffer[kTestBufferSize];
+    Spinel::Buffer  ncpBuffer(buffer, kTestBufferSize);
+    Spinel::Encoder encoder(ncpBuffer);
 
     uint8_t        frame[kTestBufferSize];
     uint16_t       frameLen;
@@ -117,7 +117,7 @@
     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
     printf("\nTest 1: Encoding of simple types");
 
-    SuccessOrQuit(encoder.BeginFrame(NcpFrameBuffer::kPriorityLow), "BeginFrame() failed.");
+    SuccessOrQuit(encoder.BeginFrame(Spinel::Buffer::kPriorityLow), "BeginFrame() failed.");
     SuccessOrQuit(encoder.WriteBool(kBool_1), "WriteBool() failed.");
     SuccessOrQuit(encoder.WriteBool(kBool_2), "WriteBool() failed.");
     SuccessOrQuit(encoder.WriteUint8(kUint8), "WriteUint8() failed.");
@@ -183,7 +183,7 @@
     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
     printf("\nTest 2: Test a single simple struct.");
 
-    SuccessOrQuit(encoder.BeginFrame(NcpFrameBuffer::kPriorityLow), "BeginFrame() failed.");
+    SuccessOrQuit(encoder.BeginFrame(Spinel::Buffer::kPriorityLow), "BeginFrame() failed.");
     SuccessOrQuit(encoder.WriteUint8(kUint8), "WriteUint8() failed.");
     SuccessOrQuit(encoder.OpenStruct(), "OpenStruct() failed.");
     {
@@ -230,7 +230,7 @@
     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
     printf("\nTest 3: Test multiple structs and struct within struct.");
 
-    SuccessOrQuit(encoder.BeginFrame(NcpFrameBuffer::kPriorityLow), "BeginFrame() failed.");
+    SuccessOrQuit(encoder.BeginFrame(Spinel::Buffer::kPriorityLow), "BeginFrame() failed.");
     SuccessOrQuit(encoder.OpenStruct(), "OpenStruct() failed.");
     {
         SuccessOrQuit(encoder.WriteUint8(kUint8), "WriteUint8() failed.");
@@ -279,7 +279,7 @@
     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
     printf("\nTest 4: Test unclosed struct.");
 
-    SuccessOrQuit(encoder.BeginFrame(NcpFrameBuffer::kPriorityLow), "BeginFrame() failed.");
+    SuccessOrQuit(encoder.BeginFrame(Spinel::Buffer::kPriorityLow), "BeginFrame() failed.");
     SuccessOrQuit(encoder.WriteUint8(kUint8), "WriteUint8() failed.");
     SuccessOrQuit(encoder.OpenStruct(), "OpenStruct() failed.");
     {
@@ -312,7 +312,7 @@
     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
     printf("\nTest 5: Test saving position and reseting back to a saved position");
 
-    SuccessOrQuit(encoder.BeginFrame(NcpFrameBuffer::kPriorityLow), "BeginFrame() failed.");
+    SuccessOrQuit(encoder.BeginFrame(Spinel::Buffer::kPriorityLow), "BeginFrame() failed.");
     SuccessOrQuit(encoder.WriteUint8(kUint8), "WriteUint8() failed.");
     SuccessOrQuit(encoder.OpenStruct(), "OpenStruct() failed.");
     {
@@ -357,12 +357,12 @@
     printf(" -- PASS\n");
 }
 
-} // namespace Ncp
+} // namespace Spinel
 } // namespace ot
 
 int main(void)
 {
-    ot::Ncp::TestSpinelEncoder();
+    ot::Spinel::TestEncoder();
     printf("\nAll tests passed.\n");
     return 0;
 }
diff --git a/tests/unit/test_steering_data.cpp b/tests/unit/test_steering_data.cpp
new file mode 100644
index 0000000..50c7511
--- /dev/null
+++ b/tests/unit/test_steering_data.cpp
@@ -0,0 +1,120 @@
+/*
+ *  Copyright (c) 2020, The OpenThread Authors.
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the copyright holder nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test_platform.h"
+
+#include <openthread/config.h>
+
+#include "test_util.hpp"
+#include "meshcop/meshcop.hpp"
+
+namespace ot {
+
+void TestSteeringData(void)
+{
+    MeshCoP::SteeringData                 steeringData;
+    MeshCoP::SteeringData::HashBitIndexes indexes;
+    Mac::ExtAddress                       joinerId1;
+    Mac::ExtAddress                       joinerId2;
+
+    const uint8_t kAddress1[sizeof(Mac::ExtAddress)] = {0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x16};
+    const uint8_t kAddress2[sizeof(Mac::ExtAddress)] = {0xbe, 0xef, 0xca, 0xfe, 0xde, 0xad, 0xba, 0xbe};
+
+    joinerId1.Set(kAddress1);
+    joinerId2.Set(kAddress2);
+
+    MeshCoP::SteeringData::CalculateHashBitIndexes(joinerId2, indexes);
+
+    steeringData.SetToPermitAllJoiners();
+
+    DumpBuffer("After SetToPermitAllJoiners()", steeringData.GetData(), steeringData.GetLength());
+    VerifyOrQuit(steeringData.GetLength() == 1, "GetLength is incorrect after SetToPermitAllJoiners()");
+    VerifyOrQuit(steeringData.PermitsAllJoiners(), "PermitsAllJoiners() failed after SetToPermitAllJoiners()");
+    VerifyOrQuit(!steeringData.IsEmpty(), "IsEmpty() failed after SetToPermitAllJoiners()");
+    VerifyOrQuit(steeringData.Contains(joinerId1), "Contains(joinerId1) failed after SetToPermitAllJoiners()");
+    VerifyOrQuit(steeringData.Contains(joinerId2), "Contains(joinerId2) failed after SetToPermitAllJoiners()");
+    VerifyOrQuit(steeringData.Contains(indexes), "Contains(indexes) failed after SetToPermitAllJoiners()");
+
+    steeringData.Clear();
+
+    DumpBuffer("After Clear()", steeringData.GetData(), steeringData.GetLength());
+    VerifyOrQuit(steeringData.GetLength() == 1, "GetLength is incorrect after Clear()");
+    VerifyOrQuit(!steeringData.PermitsAllJoiners(), "PermitsAllJoiners() failed after Clear()");
+    VerifyOrQuit(steeringData.IsEmpty(), "IsEmpty() failed after Clear()");
+    VerifyOrQuit(!steeringData.Contains(joinerId1), "Contains(joinerId1) failed after Clear()");
+    VerifyOrQuit(!steeringData.Contains(joinerId2), "Contains(joinerId2) failed after Clear()");
+    VerifyOrQuit(!steeringData.Contains(indexes), "Contains(indexes) failed after Clear()");
+
+    for (uint8_t len = 1; len <= MeshCoP::SteeringData::kMaxLength; len++)
+    {
+        printf("\n--------------------------------------------");
+
+        steeringData.Init(len);
+
+        VerifyOrQuit(steeringData.GetLength() == len, "GetLength is incorrect after Init()");
+        VerifyOrQuit(steeringData.IsEmpty(), "IsEmpy() failed after Init()");
+        VerifyOrQuit(!steeringData.PermitsAllJoiners(), "PermitsAllJoiners() failed after Init()");
+        VerifyOrQuit(!steeringData.Contains(joinerId1), "Contains(joinerId1) failed after Init()");
+        VerifyOrQuit(!steeringData.Contains(joinerId2), "Contains(joinerId2) failed after Init()");
+        VerifyOrQuit(!steeringData.Contains(indexes), "Contains(indexes) failed after Init()");
+
+        steeringData.UpdateBloomFilter(joinerId1);
+        DumpBuffer("After UpdateBloomFilter(joinerId1)", steeringData.GetData(), steeringData.GetLength());
+        VerifyOrQuit(steeringData.GetLength() == len, "GetLength is incorrect after UpdateBloomFilter()");
+        VerifyOrQuit(!steeringData.IsEmpty(), "IsEmpy() failed after UpdateBloomFilter()");
+        VerifyOrQuit(!steeringData.PermitsAllJoiners(), "PermitsAllJoiners() failed after UpdateBloomFilter");
+        VerifyOrQuit(steeringData.Contains(joinerId1), "Contains(joinerId1) failed after UpdateBloomFilter");
+
+        steeringData.UpdateBloomFilter(joinerId2);
+        DumpBuffer("After UpdateBloomFilter(joinerId2)", steeringData.GetData(), steeringData.GetLength());
+        VerifyOrQuit(steeringData.GetLength() == len, "GetLength is incorrect after UpdateBloomFilter()");
+        VerifyOrQuit(!steeringData.IsEmpty(), "IsEmpy() failed after UpdateBloomFilter()");
+        VerifyOrQuit(!steeringData.PermitsAllJoiners(), "PermitsAllJoiners() failed after UpdateBloomFilter");
+        VerifyOrQuit(steeringData.Contains(joinerId1), "Contains(joinerId1) failed after UpdateBloomFilter");
+        VerifyOrQuit(steeringData.Contains(joinerId2), "Contains(joinerId2) failed after UpdateBloomFilter");
+        VerifyOrQuit(steeringData.Contains(indexes), "Contains(joinerId2) failed after UpdateBloomFilter");
+    }
+
+    steeringData.Init(0);
+
+    VerifyOrQuit(steeringData.GetLength() == 0, "GetLength is incorrect after Init()");
+    VerifyOrQuit(steeringData.IsEmpty(), "IsEmpy() failed after Init()");
+    VerifyOrQuit(!steeringData.PermitsAllJoiners(), "PermitsAllJoiners() failed after Init()");
+    VerifyOrQuit(!steeringData.Contains(joinerId1), "Contains(joinerId1) failed after Init()");
+    VerifyOrQuit(!steeringData.Contains(joinerId2), "Contains(joinerId2) failed after Init()");
+    VerifyOrQuit(!steeringData.Contains(indexes), "Contains(indexes) failed after Init()");
+}
+
+} // namespace ot
+
+int main(void)
+{
+    ot::TestSteeringData();
+    printf("\nAll tests passed.\n");
+    return 0;
+}
diff --git a/tests/unit/test_string.cpp b/tests/unit/test_string.cpp
index 692819a..d7dd505 100644
--- a/tests/unit/test_string.cpp
+++ b/tests/unit/test_string.cpp
@@ -83,7 +83,7 @@
     VerifyOrQuit(str1.GetLength() == 0, "GetLength() failed for empty string");
     VerifyOrQuit(strcmp(str1.AsCString(), "") == 0, "String content is incorrect");
 
-    str1.Set("%d", 12);
+    IgnoreError(str1.Set("%d", 12));
     VerifyOrQuit(str1.GetLength() == 2, "GetLength() failed");
     VerifyOrQuit(strcmp(str1.AsCString(), "12") == 0, "String content is incorrect");
     PrintString("str1", str1);
diff --git a/tests/unit/test_timer.cpp b/tests/unit/test_timer.cpp
index 9b86871..ad63ed8 100644
--- a/tests/unit/test_timer.cpp
+++ b/tests/unit/test_timer.cpp
@@ -83,11 +83,11 @@
  * `TestTimer` sub-classes `ot::TimerMilli` and provides a handler and a counter to keep track of number of times timer
  * gets fired.
  */
-class TestTimer : public ot::TimerMilli
+template <typename TimerType> class TestTimer : public TimerType
 {
 public:
     TestTimer(ot::Instance &aInstance)
-        : ot::TimerMilli(aInstance, TestTimer::HandleTimerFired, NULL)
+        : TimerType(aInstance, TestTimer::HandleTimerFired, nullptr)
         , mFiredCounter(0)
     {
     }
@@ -108,15 +108,29 @@
     uint32_t mFiredCounter; //< Number of times timer has been fired so far
 };
 
+template <typename TimerType> void AlarmFired(otInstance *aInstance);
+
+template <> void AlarmFired<ot::TimerMilli>(otInstance *aInstance)
+{
+    otPlatAlarmMilliFired(aInstance);
+}
+
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+template <> void AlarmFired<ot::TimerMicro>(otInstance *aInstance)
+{
+    otPlatAlarmMicroFired(aInstance);
+}
+#endif
+
 /**
  * Test the TimerScheduler's behavior of one timer started and fired.
  */
-int TestOneTimer(void)
+template <typename TimerType> int TestOneTimer(void)
 {
-    const uint32_t kTimeT0        = 1000;
-    const uint32_t kTimerInterval = 10;
-    ot::Instance * instance       = testInitInstance();
-    TestTimer      timer(*instance);
+    const uint32_t       kTimeT0        = 1000;
+    const uint32_t       kTimerInterval = 10;
+    ot::Instance *       instance       = testInitInstance();
+    TestTimer<TimerType> timer(*instance);
 
     // Test one Timer basic operation.
 
@@ -137,7 +151,7 @@
 
     sNow += kTimerInterval;
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 1, "TestOneTimer: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 1, "TestOneTimer: Stop CallCount Failed.");
@@ -161,7 +175,7 @@
 
     sNow += kTimerInterval;
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 1, "TestOneTimer: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 1, "TestOneTimer: Stop CallCount Failed.");
@@ -185,7 +199,7 @@
 
     sNow += kTimerInterval + 5;
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 1, "TestOneTimer: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 1, "TestOneTimer: Stop CallCount Failed.");
@@ -209,7 +223,7 @@
 
     sNow += kTimerInterval - 2;
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 2, "TestOneTimer: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 0, "TestOneTimer: Stop CallCount Failed.");
@@ -219,7 +233,7 @@
 
     sNow += kTimerInterval;
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 2, "TestOneTimer: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 1, "TestOneTimer: Stop CallCount Failed.");
@@ -237,13 +251,13 @@
 /**
  * Test the TimerScheduler's behavior of two timers started and fired.
  */
-int TestTwoTimers(void)
+template <typename TimerType> int TestTwoTimers(void)
 {
-    const uint32_t kTimeT0        = 1000;
-    const uint32_t kTimerInterval = 10;
-    ot::Instance * instance       = testInitInstance();
-    TestTimer      timer1(*instance);
-    TestTimer      timer2(*instance);
+    const uint32_t       kTimeT0        = 1000;
+    const uint32_t       kTimerInterval = 10;
+    ot::Instance *       instance       = testInitInstance();
+    TestTimer<TimerType> timer1(*instance);
+    TestTimer<TimerType> timer2(*instance);
 
     InitTestTimer();
     printf("TestTwoTimers() ");
@@ -275,7 +289,7 @@
     VerifyOrQuit(timer2.IsRunning() == true, "TestTwoTimers: Timer running Failed.");
     VerifyOrQuit(sTimerOn, "TestTwoTimers: Platform Timer State Failed.");
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 2, "TestTwoTimers: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 0, "TestTwoTimers: Stop CallCount Failed.");
@@ -287,7 +301,7 @@
     VerifyOrQuit(sTimerOn == true, "TestTwoTimers: Platform Timer State Failed.");
 
     sNow += kTimerInterval;
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 2, "TestTwoTimers: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 1, "TestTwoTimers: Stop CallCount Failed.");
@@ -297,7 +311,7 @@
     VerifyOrQuit(timer2.IsRunning() == false, "TestTwoTimers: Timer running Failed.");
     VerifyOrQuit(sTimerOn == false, "TestTwoTimers: Platform Timer State Failed.");
 
-    // Test when second timer starts at the fire time of first timer (before otPlatAlarmMilliFired()) and its fire time
+    // Test when second timer starts at the fire time of first timer (before AlarmFired<TimerType>()) and its fire time
     // is before the first timer. Ensure that the second timer handler is invoked before the first one.
 
     InitCounters();
@@ -324,7 +338,7 @@
     VerifyOrQuit(timer2.IsRunning() == true, "TestTwoTimers: Timer running Failed.");
     VerifyOrQuit(sTimerOn, "TestTwoTimers: Platform Timer State Failed.");
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 0, "TestTwoTimers: Stop CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexTimerHandler] == 1, "TestTwoTimers: Handler CallCount Failed.");
@@ -334,7 +348,7 @@
     VerifyOrQuit(timer2.IsRunning() == false, "TestTwoTimers: Timer running Failed.");
     VerifyOrQuit(sTimerOn == true, "TestTwoTimers: Platform Timer State Failed.");
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 1, "TestTwoTimers: Stop CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexTimerHandler] == 2, "TestTwoTimers: Handler CallCount Failed.");
@@ -344,7 +358,7 @@
     VerifyOrQuit(sTimerOn == false, "TestTwoTimers: Platform Timer State Failed.");
 
     // Timer 1 fire callback is late by some ticks/ms, and second timer is scheduled (before call to
-    // otPlatAlarmMilliFired) with a maximum interval. This is to test (corner-case) scenario where the fire time of two
+    // AlarmFired) with a maximum interval. This is to test (corner-case) scenario where the fire time of two
     // timers spanning over the maximum interval.
 
     InitCounters();
@@ -373,7 +387,7 @@
     VerifyOrQuit(timer2.IsRunning() == true, "TestTwoTimers: Timer running Failed.");
     VerifyOrQuit(sTimerOn, "TestTwoTimers: Platform Timer State Failed.");
 
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 2, "TestTwoTimers: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 0, "TestTwoTimers: Stop CallCount Failed.");
@@ -386,7 +400,7 @@
     VerifyOrQuit(sTimerOn == true, "TestTwoTimers: Platform Timer State Failed.");
 
     sNow += ot::Timer::kMaxDelay;
-    otPlatAlarmMilliFired(instance);
+    AlarmFired<TimerType>(instance);
 
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 2, "TestTwoTimers: Start CallCount Failed.");
     VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 1, "TestTwoTimers: Stop CallCount Failed.");
@@ -409,7 +423,7 @@
  * `aTimeShift` is added to the t0 and trigger times for all timers. It can be used to check the ten timer behavior
  * at different start time (e.g., around a 32-bit wrap).
  */
-static void TenTimers(uint32_t aTimeShift)
+template <typename TimerType> static void TenTimers(uint32_t aTimeShift)
 {
     const uint32_t kNumTimers                 = 10;
     const uint32_t kNumTriggers               = 7;
@@ -459,19 +473,19 @@
 
     ot::Instance *instance = testInitInstance();
 
-    TestTimer  timer0(*instance);
-    TestTimer  timer1(*instance);
-    TestTimer  timer2(*instance);
-    TestTimer  timer3(*instance);
-    TestTimer  timer4(*instance);
-    TestTimer  timer5(*instance);
-    TestTimer  timer6(*instance);
-    TestTimer  timer7(*instance);
-    TestTimer  timer8(*instance);
-    TestTimer  timer9(*instance);
-    TestTimer *timers[kNumTimers] = {&timer0, &timer1, &timer2, &timer3, &timer4,
-                                     &timer5, &timer6, &timer7, &timer8, &timer9};
-    size_t     i;
+    TestTimer<TimerType>  timer0(*instance);
+    TestTimer<TimerType>  timer1(*instance);
+    TestTimer<TimerType>  timer2(*instance);
+    TestTimer<TimerType>  timer3(*instance);
+    TestTimer<TimerType>  timer4(*instance);
+    TestTimer<TimerType>  timer5(*instance);
+    TestTimer<TimerType>  timer6(*instance);
+    TestTimer<TimerType>  timer7(*instance);
+    TestTimer<TimerType>  timer8(*instance);
+    TestTimer<TimerType>  timer9(*instance);
+    TestTimer<TimerType> *timers[kNumTimers] = {&timer0, &timer1, &timer2, &timer3, &timer4,
+                                                &timer5, &timer6, &timer7, &timer8, &timer9};
+    size_t                i;
 
     printf("TestTenTimer() with aTimeShift=%-10u ", aTimeShift);
 
@@ -508,13 +522,13 @@
 
         do
         {
-            // By design, each call to otPlatAlarmMilliFired() can result in 0 or 1 calls to a timer handler.
-            // For some combinations of sNow and Timers queued, it is necessary to call otPlatAlarmMilliFired()
+            // By design, each call to AlarmFired<TimerType>() can result in 0 or 1 calls to a timer handler.
+            // For some combinations of sNow and Timers queued, it is necessary to call AlarmFired<TimerType>()
             // multiple times in order to handle all the expired timers.  It can be determined that another
             // timer is ready to be triggered by examining the aDt arg passed into otPlatAlarmMilliStartAt().  If
-            // that value is 0, then otPlatAlarmMilliFired should be fired immediately. This loop calls
-            // otPlatAlarmMilliFired() the requisite number of times based on the aDt argument.
-            otPlatAlarmMilliFired(instance);
+            // that value is 0, then AlarmFired should be fired immediately. This loop calls
+            // AlarmFired<TimerType>() the requisite number of times based on the aDt argument.
+            AlarmFired<TimerType>(instance);
         } while (sPlatDt == 0);
 
         VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == kTimerStartCountAfterTrigger[trigger],
@@ -542,7 +556,7 @@
     testFreeInstance(instance);
 }
 
-int TestTenTimers(void)
+template <typename TimerType> int TestTenTimers(void)
 {
     // Time shift to change the start/fire time of ten timers.
     const uint32_t kTimeShift[] = {
@@ -553,7 +567,7 @@
 
     for (i = 0; i < OT_ARRAY_LENGTH(kTimeShift); i++)
     {
-        TenTimers(kTimeShift[i]);
+        TenTimers<TimerType>(kTimeShift[i]);
     }
 
     return 0;
@@ -650,16 +664,19 @@
     return 0;
 }
 
-void RunTimerTests(void)
+template <typename TimerType> void RunTimerTests(void)
 {
-    TestOneTimer();
-    TestTwoTimers();
-    TestTenTimers();
+    TestOneTimer<TimerType>();
+    TestTwoTimers<TimerType>();
+    TestTenTimers<TimerType>();
 }
 
 int main(void)
 {
-    RunTimerTests();
+    RunTimerTests<ot::TimerMilli>();
+#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+    RunTimerTests<ot::TimerMicro>();
+#endif
     TestTimerTime();
     printf("All tests passed\n");
     return 0;
diff --git a/tests/unit/test_toolchain.cpp b/tests/unit/test_toolchain.cpp
index a66317a..c43ce14 100644
--- a/tests/unit/test_toolchain.cpp
+++ b/tests/unit/test_toolchain.cpp
@@ -34,7 +34,6 @@
 
 #include "test_util.h"
 #include "thread/topology.hpp"
-#include "utils/static_assert.hpp"
 
 extern "C" {
 uint32_t       otNetifAddress_Size_c();
@@ -52,7 +51,7 @@
         uint16_t mShort;
     } OT_TOOL_PACKED_END;
 
-    OT_STATIC_ASSERT(sizeof(packed_t) == 7, "packed_t should be packed to 7 bytes");
+    static_assert(sizeof(packed_t) == 7, "packed_t should be packed to 7 bytes");
 
     VerifyOrQuit(sizeof(packed_t) == 7, "Toolchain::OT_TOOL_PACKED failed 1");
 }
@@ -66,7 +65,7 @@
         uint8_t mByte;
     } OT_TOOL_PACKED_END;
 
-    OT_STATIC_ASSERT(sizeof(packed_t) == 4, "packed_t should be packed to 4 bytes");
+    static_assert(sizeof(packed_t) == 4, "packed_t should be packed to 4 bytes");
 
     VerifyOrQuit(sizeof(packed_t) == 4, "Toolchain::OT_TOOL_PACKED failed 2");
 }
@@ -89,7 +88,7 @@
         } OT_TOOL_PACKED_FIELD;
     } OT_TOOL_PACKED_END;
 
-    OT_STATIC_ASSERT(sizeof(packed_t) == 5, "packed_t should be packed to 5 bytes");
+    static_assert(sizeof(packed_t) == 5, "packed_t should be packed to 5 bytes");
 
     VerifyOrQuit(sizeof(packed_t) == 5, "Toolchain::OT_TOOL_PACKED failed 3");
 }
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index 56bf9c7..f777749 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -26,6 +26,16 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-if(OT_BUILTIN_MBEDTLS)
+if(NOT OT_EXTERNAL_MBEDTLS)
     add_subdirectory(mbedtls)
 endif()
+
+if(OT_PLATFORM STREQUAL "kw41z")
+    add_subdirectory(nxp)
+elseif(OT_PLATFORM MATCHES "cc*")
+    add_subdirectory(ti)
+elseif(OT_PLATFORM STREQUAL "qpg6095")
+    add_subdirectory(Qorvo)
+elseif(OT_PLATFORM STREQUAL "samr21")
+    add_subdirectory(microchip)
+endif()
diff --git a/third_party/Makefile.am b/third_party/Makefile.am
index 6b13cac..cb1a40f 100644
--- a/third_party/Makefile.am
+++ b/third_party/Makefile.am
@@ -45,37 +45,36 @@
 
 SUBDIRS =
 
-if OPENTHREAD_EXAMPLES_EFR32MG12
+if OPENTHREAD_PLATFORM_EFR32MG1
 SUBDIRS                                += \
     silabs                                \
     jlink                                 \
     $(NULL)
 endif
 
-if OPENTHREAD_EXAMPLES_EFR32MG13
+if OPENTHREAD_PLATFORM_EFR32MG12
 SUBDIRS                                += \
     silabs                                \
     jlink                                 \
     $(NULL)
 endif
 
-if OPENTHREAD_EXAMPLES_EFR32MG21
+if OPENTHREAD_PLATFORM_EFR32MG13
 SUBDIRS                                += \
     silabs                                \
     jlink                                 \
     $(NULL)
 endif
 
-if OPENTHREAD_EXAMPLES_NRF52840
+if OPENTHREAD_PLATFORM_EFR32MG21
 SUBDIRS                                += \
+    silabs                                \
     jlink                                 \
-    NordicSemiconductor                   \
     $(NULL)
 endif
 
-if OPENTHREAD_EXAMPLES_NRF52833
+if OPENTHREAD_PLATFORM_NRF52811
 SUBDIRS                                += \
-    jlink                                 \
     NordicSemiconductor                   \
     $(NULL)
 endif
@@ -83,10 +82,33 @@
 if OPENTHREAD_EXAMPLES_NRF52811
 SUBDIRS                                += \
     jlink                                 \
+    $(NULL)
+endif
+
+if OPENTHREAD_PLATFORM_NRF52833
+SUBDIRS                                += \
     NordicSemiconductor                   \
     $(NULL)
 endif
 
+if OPENTHREAD_EXAMPLES_NRF52833
+SUBDIRS                                += \
+    jlink                                 \
+    $(NULL)
+endif
+
+if OPENTHREAD_PLATFORM_NRF52840
+SUBDIRS                                += \
+    NordicSemiconductor                   \
+    $(NULL)
+endif
+
+if OPENTHREAD_EXAMPLES_NRF52840
+SUBDIRS                                += \
+    jlink                                 \
+    $(NULL)
+endif
+
 if OPENTHREAD_ENABLE_BUILTIN_MBEDTLS
 SUBDIRS                                += \
     mbedtls                               \
diff --git a/third_party/NordicSemiconductor/Makefile.am b/third_party/NordicSemiconductor/Makefile.am
index bd0307b..b657ca1 100644
--- a/third_party/NordicSemiconductor/Makefile.am
+++ b/third_party/NordicSemiconductor/Makefile.am
@@ -28,26 +28,47 @@
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
 
-if OPENTHREAD_EXAMPLES_NRF52811
+
 lib_LIBRARIES                                                                                                           = \
-    libnordicsemi-nrf52811-sdk.a                                                                                          \
+    $(NULL)
+
+# Build radio drivers when building platform libraries.
+if OPENTHREAD_PLATFORM_NRF52811
+lib_LIBRARIES                                                                                                          += \
     libnordicsemi-nrf52811-radio-driver.a                                                                                 \
     $(NULL)
 endif
 
-if OPENTHREAD_EXAMPLES_NRF52840
-lib_LIBRARIES                                                                                                           = \
-    libnordicsemi-nrf52840-sdk.a                                                                                          \
+if OPENTHREAD_PLATFORM_NRF52833
+lib_LIBRARIES                                                                                                          += \
+    libnordicsemi-nrf52833-radio-driver.a                                                                                 \
+    libnordicsemi-nrf52833-radio-driver-softdevice.a                                                                      \
+    $(NULL)
+endif
+
+if OPENTHREAD_PLATFORM_NRF52840
+lib_LIBRARIES                                                                                                          += \
     libnordicsemi-nrf52840-radio-driver.a                                                                                 \
     libnordicsemi-nrf52840-radio-driver-softdevice.a                                                                      \
     $(NULL)
 endif
 
+# Only build the SDK library when building the example applications.
+if OPENTHREAD_EXAMPLES_NRF52811
+lib_LIBRARIES                                                                                                          += \
+    libnordicsemi-nrf52811-sdk.a                                                                                          \
+    $(NULL)
+endif
+
 if OPENTHREAD_EXAMPLES_NRF52833
-lib_LIBRARIES                                                                                                           = \
+lib_LIBRARIES                                                                                                          += \
     libnordicsemi-nrf52833-sdk.a                                                                                          \
-    libnordicsemi-nrf52833-radio-driver.a                                                                                 \
-    libnordicsemi-nrf52833-radio-driver-softdevice.a                                                                      \
+    $(NULL)
+endif
+
+if OPENTHREAD_EXAMPLES_NRF52840
+lib_LIBRARIES                                                                                                          += \
+    libnordicsemi-nrf52840-sdk.a                                                                                          \
     $(NULL)
 endif
 
@@ -59,26 +80,44 @@
 override CFLAGS   := $(filter-out -Wundef,$(CFLAGS))
 override CXXFLAGS := $(filter-out -Wundef,$(CXXFLAGS))
 
+# Do not enable -Wcast-align for Nordic Semiconductor driver library
+override CFLAGS   := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 COMMONCPPFLAGS                                                                                                          = \
     -DCONFIG_GPIO_AS_PINRESET                                                                                             \
     -DENABLE_FEM=1                                                                                                        \
+    -DUSE_APP_CONFIG=1                                                                                                    \
     -I$(srcdir)                                                                                                           \
     -I$(top_srcdir)/include                                                                                               \
     -I$(top_srcdir)/src/core                                                                                              \
-    -I$(top_srcdir)/third_party/NordicSemiconductor                                                                       \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                                 \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                                          \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock                                                         \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common                                                        \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio                                                         \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem                                                     \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/three_pin_gpio                                      \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal                                                     \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch                                                    \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal                                               \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice                                    \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features                                            \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator                              \
+    $(NULL)
+
+# Only reference the SDK header files included in third_party/NordicSemiconductor
+# when building the example applications.
+#
+# When building just the platform libraries, the caller of configure is expected
+# to provide the correct -I arguments to locate the necessary header files in an
+# external copy of the Nordic nRF5 SDK.
+#
+# Note that an exception is made for the 802.15.4 radio driver, which is always built
+# using the sources in third_party/NordicSemiconductor/drivers/radio.
+if OPENTHREAD_ENABLE_EXAMPLES
+COMMONCPPFLAGS                                                                                                         += \
+    -I$(top_srcdir)/third_party/NordicSemiconductor                                                                       \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                                 \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config                                                                \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                                          \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock                                                         \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common                                                        \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power                                                         \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick                                                       \
     -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd                                                          \
@@ -100,18 +139,7 @@
     -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/soc                                                              \
     -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers                                               \
     -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf52                                         \
-    $(NULL)
-
-NRF52833_CPPFLAGS                                                                                                       = \
-    -DNRF52833_XXAA                                                                                                       \
-    -DNRF_802154_PROJECT_CONFIG=\"platform-config.h\"                                                                     \
-    -I$(top_srcdir)/examples/platforms/nrf52833                                                                           \
-    $(NULL)
-
-NRF52840_CPPFLAGS                                                                                                       = \
-    -DNRF52840_XXAA                                                                                                       \
-    -DNRF_802154_PROJECT_CONFIG=\"platform-config.h\"                                                                     \
-    -I$(top_srcdir)/examples/platforms/nrf528xx/nrf52840/                                                                 \
+    -Wno-unused-parameter                                                                                                 \
     $(NULL)
 
 NRF52811_CPPFLAGS                                                                                                       = \
@@ -120,6 +148,22 @@
     -D__HEAP_SIZE=0                                                                                                       \
     -D__STACK_SIZE=2048                                                                                                   \
     -I$(top_srcdir)/examples/platforms/nrf528xx/nrf52811                                                                  \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52811/config                                                \
+    $(NULL)
+endif
+
+NRF52833_CPPFLAGS                                                                                                       = \
+    -DNRF52833_XXAA                                                                                                       \
+    -DNRF_802154_PROJECT_CONFIG=\"platform-config.h\"                                                                     \
+    -I$(top_srcdir)/examples/platforms/nrf52833                                                                           \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52833/config                                                \
+    $(NULL)
+
+NRF52840_CPPFLAGS                                                                                                       = \
+    -DNRF52840_XXAA                                                                                                       \
+    -DNRF_802154_PROJECT_CONFIG=\"platform-config.h\"                                                                     \
+    -I$(top_srcdir)/examples/platforms/nrf528xx/nrf52840/                                                                 \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52840/config                                                \
     $(NULL)
 
 NORDICSEMI_COMMON_SOURCES                                                                                               = \
@@ -130,6 +174,7 @@
     libraries/app_error/app_error_weak.c                                                                                  \
     libraries/utf_converter/utf.c                                                                                         \
     nrfx/drivers/src/nrfx_clock.c                                                                                         \
+    nrfx/drivers/src/nrfx_nvmc.c                                                                                          \
     nrfx/drivers/src/nrfx_power.c                                                                                         \
     nrfx/drivers/src/nrfx_spis.c                                                                                          \
     nrfx/drivers/src/nrfx_systick.c                                                                                       \
@@ -150,6 +195,11 @@
     libraries/usb/class/cdc/acm/app_usbd_cdc_acm.c                                                                        \
     $(NULL)
 
+NORDICSEMI_NRF52811_SOURCES                                                                                             = \
+    nrfx/mdk/gcc_startup_nrf52811.S                                                                                       \
+    nrfx/mdk/system_nrf52811.c                                                                                            \
+    $(NULL)
+
 NORDICSEMI_NRF52833_SOURCES                                                                                             = \
     nrfx/mdk/gcc_startup_nrf52833.S                                                                                       \
     nrfx/mdk/system_nrf52833.c                                                                                            \
@@ -160,11 +210,6 @@
     nrfx/mdk/system_nrf52840.c                                                                                            \
     $(NULL)
 
-NORDICSEMI_NRF52811_SOURCES                                                                                             = \
-    nrfx/mdk/gcc_startup_nrf52811.S                                                                                       \
-    nrfx/mdk/system_nrf52811.c                                                                                            \
-    $(NULL)
-
 RADIO_DRIVER_SOURCES                                                                                                    = \
     drivers/radio/fal/nrf_802154_fal.c                                                                                    \
     drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.c                                                        \
@@ -223,40 +268,27 @@
     -DRAAL_SOFTDEVICE=1                                                                                                   \
     $(NULL)
 
-libnordicsemi_nrf52840_sdk_a_CPPFLAGS                                                                                   = \
+libnordicsemi_nrf52811_sdk_a_CPPFLAGS                                                                                   = \
     $(COMMONCPPFLAGS)                                                                                                     \
-    $(NRF52840_CPPFLAGS)                                                                                                  \
+    $(NRF52811_CPPFLAGS)                                                                                                  \
     $(NULL)
 
-libnordicsemi_nrf52840_sdk_a_SOURCES                                                                                    = \
+libnordicsemi_nrf52811_sdk_a_SOURCES                                                                                    = \
     $(NORDICSEMI_COMMON_SOURCES)                                                                                          \
-    $(NORDICSEMI_USB_SOURCES)                                                                                             \
-    $(NORDICSEMI_NRF52840_SOURCES)                                                                                        \
+    $(NORDICSEMI_NRF52811_SOURCES)                                                                                        \
     $(NULL)
 
-libnordicsemi_nrf52840_radio_driver_a_CPPFLAGS                                                                          = \
+libnordicsemi_nrf52811_radio_driver_a_CPPFLAGS                                                                          = \
     $(COMMONCPPFLAGS)                                                                                                     \
-    $(NRF52840_CPPFLAGS)                                                                                                  \
+    $(NRF52811_CPPFLAGS)                                                                                                  \
     $(RADIO_DRIVER_SINGLE_PHY_CPPFLAGS)                                                                                   \
     $(NULL)
 
-libnordicsemi_nrf52840_radio_driver_a_SOURCES                                                                           = \
+libnordicsemi_nrf52811_radio_driver_a_SOURCES                                                                           = \
     $(RADIO_DRIVER_SOURCES)                                                                                               \
     $(RADIO_DRIVER_SINGLE_PHY_SOURCES)                                                                                    \
     $(NULL)
 
-libnordicsemi_nrf52840_radio_driver_softdevice_a_CPPFLAGS                                                               = \
-    $(COMMONCPPFLAGS)                                                                                                     \
-    $(NRF52840_CPPFLAGS)                                                                                                  \
-    $(SOFTDEVICE_CPPFLAGS)                                                                                                \
-    $(RADIO_DRIVER_SOFTDEVICE_CPPFLAGS)                                                                                   \
-    $(NULL)
-
-libnordicsemi_nrf52840_radio_driver_softdevice_a_SOURCES                                                                = \
-    $(RADIO_DRIVER_SOURCES)                                                                                               \
-    $(RADIO_DRIVER_SOFTDEVICE_SOURCES)                                                                                    \
-    $(NULL)
-
 libnordicsemi_nrf52833_sdk_a_CPPFLAGS                                                                                   = \
     $(COMMONCPPFLAGS)                                                                                                     \
     $(NRF52833_CPPFLAGS)                                                                                                  \
@@ -291,27 +323,40 @@
     $(RADIO_DRIVER_SOFTDEVICE_SOURCES)                                                                                    \
     $(NULL)
 
-libnordicsemi_nrf52811_sdk_a_CPPFLAGS                                                                                   = \
+libnordicsemi_nrf52840_sdk_a_CPPFLAGS                                                                                   = \
     $(COMMONCPPFLAGS)                                                                                                     \
-    $(NRF52811_CPPFLAGS)                                                                                                  \
+    $(NRF52840_CPPFLAGS)                                                                                                  \
     $(NULL)
 
-libnordicsemi_nrf52811_sdk_a_SOURCES                                                                                    = \
+libnordicsemi_nrf52840_sdk_a_SOURCES                                                                                    = \
     $(NORDICSEMI_COMMON_SOURCES)                                                                                          \
-    $(NORDICSEMI_NRF52811_SOURCES)                                                                                        \
+    $(NORDICSEMI_USB_SOURCES)                                                                                             \
+    $(NORDICSEMI_NRF52840_SOURCES)                                                                                        \
     $(NULL)
 
-libnordicsemi_nrf52811_radio_driver_a_CPPFLAGS                                                                          = \
+libnordicsemi_nrf52840_radio_driver_a_CPPFLAGS                                                                          = \
     $(COMMONCPPFLAGS)                                                                                                     \
-    $(NRF52811_CPPFLAGS)                                                                                                  \
+    $(NRF52840_CPPFLAGS)                                                                                                  \
     $(RADIO_DRIVER_SINGLE_PHY_CPPFLAGS)                                                                                   \
     $(NULL)
 
-libnordicsemi_nrf52811_radio_driver_a_SOURCES                                                                           = \
+libnordicsemi_nrf52840_radio_driver_a_SOURCES                                                                           = \
     $(RADIO_DRIVER_SOURCES)                                                                                               \
     $(RADIO_DRIVER_SINGLE_PHY_SOURCES)                                                                                    \
     $(NULL)
 
+libnordicsemi_nrf52840_radio_driver_softdevice_a_CPPFLAGS                                                               = \
+    $(COMMONCPPFLAGS)                                                                                                     \
+    $(NRF52840_CPPFLAGS)                                                                                                  \
+    $(SOFTDEVICE_CPPFLAGS)                                                                                                \
+    $(RADIO_DRIVER_SOFTDEVICE_CPPFLAGS)                                                                                   \
+    $(NULL)
+
+libnordicsemi_nrf52840_radio_driver_softdevice_a_SOURCES                                                                = \
+    $(RADIO_DRIVER_SOURCES)                                                                                               \
+    $(RADIO_DRIVER_SOFTDEVICE_SOURCES)                                                                                    \
+    $(NULL)
+
 noinst_HEADERS                                                                                                          = \
     $(top_srcdir)/third_party/NordicSemiconductor/cmsis/arm_math.h                                                        \
     $(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc_V6.h                                                  \
@@ -321,6 +366,10 @@
     $(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmFunc.h                                                     \
     $(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmInstr.h                                                    \
     $(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmSimd.h                                                     \
+    $(top_srcdir)/third_party/NordicSemiconductor/config/app_config.h                                                     \
+    $(top_srcdir)/third_party/NordicSemiconductor/config/nrf52811/config/sdk_config.h                                     \
+    $(top_srcdir)/third_party/NordicSemiconductor/config/nrf52833/config/sdk_config.h                                     \
+    $(top_srcdir)/third_party/NordicSemiconductor/config/nrf52840/config/sdk_config.h                                     \
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/app_util_platform.h                                        \
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/app_util.h                                                 \
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/legacy/apply_old_config.h                                  \
@@ -338,7 +387,6 @@
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_glue.h                                                \
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_log.h                                                 \
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_common.h                                               \
-    $(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_config.h                                               \
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_errors.h                                               \
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_macros.h                                               \
     $(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_os.h                                                   \
@@ -428,6 +476,7 @@
     $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/nrfx_common.h                                              \
     $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/nrfx_errors.h                                              \
     $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_clock.h                                       \
+    $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_nvmc.h                                        \
     $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power_clock.h                                 \
     $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power.h                                       \
     $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_spis.h                                        \
diff --git a/third_party/NordicSemiconductor/config/app_config.h b/third_party/NordicSemiconductor/config/app_config.h
new file mode 100644
index 0000000..65f36bd
--- /dev/null
+++ b/third_party/NordicSemiconductor/config/app_config.h
@@ -0,0 +1,258 @@
+/**
+ * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ *    Semiconductor ASA integrated circuit in a product or a software update for
+ *    such product, must reproduce the above copyright notice, this list of
+ *    conditions and the following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ *    Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ *    engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @brief This file provides OpenThread configuration of nRF5 SDK modules.
+ *
+ * Below configuration overwrites the default sdk_config.h file for certain platform.
+ *
+ * Default configuration for the vanilla OpenThread can be overwritten by the custom configuration.
+ * To do that, provide the configuration through the APP_CONFIG_CUSTOM_FILE define.
+ *
+ */
+
+#ifndef APP_CONFIG_H
+#define APP_CONFIG_H
+
+#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
+
+#ifndef APP_USBD_ENABLED
+#define APP_USBD_ENABLED 1
+#endif
+
+#ifndef APP_USBD_VID
+#define APP_USBD_VID 0x1915
+#endif
+
+#ifndef APP_USBD_PID
+#define APP_USBD_PID 0xCAFE
+#endif
+
+#ifndef APP_USBD_DEVICE_VER_MAJOR
+#define APP_USBD_DEVICE_VER_MAJOR 1
+#endif
+
+#ifndef APP_USBD_DEVICE_VER_MINOR
+#define APP_USBD_DEVICE_VER_MINOR 0
+#endif
+
+#ifndef APP_USBD_DEVICE_VER_SUB
+#define APP_USBD_DEVICE_VER_SUB 0
+#endif
+
+#ifndef APP_USBD_CONFIG_MAX_POWER
+#define APP_USBD_CONFIG_MAX_POWER 500
+#endif
+
+#ifndef APP_USBD_STRING_ID_PRODUCT
+#define APP_USBD_STRING_ID_PRODUCT 2
+#endif
+
+#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
+#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
+#endif
+
+#ifndef APP_USBD_STRINGS_PRODUCT
+#define APP_USBD_STRINGS_PRODUCT APP_USBD_STRING_DESC("nRF528xx OpenThread Device")
+#endif
+
+#ifndef APP_USBD_STRING_ID_SERIAL
+#define APP_USBD_STRING_ID_SERIAL 3
+#endif
+
+#ifndef APP_USBD_STRING_SERIAL_EXTERN
+#define APP_USBD_STRING_SERIAL_EXTERN 1
+#endif
+
+#ifndef APP_USBD_STRING_SERIAL
+#define APP_USBD_STRING_SERIAL g_extern_serial_number
+#endif
+
+#ifndef APP_USBD_CONFIG_LOG_ENABLED
+#define APP_USBD_CONFIG_LOG_ENABLED 0
+#endif
+
+#ifndef USBD_ENABLED
+#define USBD_ENABLED 1
+#endif
+
+#ifndef NRFX_USBD_ENABLED
+#define NRFX_USBD_ENABLED 1
+#endif
+
+#ifndef NRFX_USBD_CONFIG_IRQ_PRIORITY
+#define NRFX_USBD_CONFIG_IRQ_PRIORITY 7
+#endif
+
+#ifndef NRFX_SYSTICK_ENABLED
+#define NRFX_SYSTICK_ENABLED 1
+#endif
+
+#ifndef APP_USBD_CDC_ACM_ENABLED
+#define APP_USBD_CDC_ACM_ENABLED 1
+#endif
+
+#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
+
+#ifndef APP_USBD_NRF_DFU_TRIGGER_ENABLED
+#define APP_USBD_NRF_DFU_TRIGGER_ENABLED 0
+#endif
+
+#ifndef BSP_SELF_PINRESET_PIN
+#define BSP_SELF_PINRESET_PIN NRF_GPIO_PIN_MAP(0, 19)
+#endif
+
+#ifndef NRF_DFU_TRIGGER_USB_USB_SHARED
+#define NRF_DFU_TRIGGER_USB_USB_SHARED 1
+#endif
+
+#ifndef NRF_DFU_TRIGGER_USB_INTERFACE_NUM
+#define NRF_DFU_TRIGGER_USB_INTERFACE_NUM 0
+#endif
+
+#ifndef APP_NAME
+#define APP_NAME "OpenThread App"
+#endif
+
+#ifndef APP_VERSION_MAJOR
+#define APP_VERSION_MAJOR 1
+#endif
+
+#ifndef APP_VERSION_MINOR
+#define APP_VERSION_MINOR 0
+#endif
+
+#ifndef APP_VERSION_PATCH
+#define APP_VERSION_PATCH 0
+#endif
+
+#ifndef APP_ID
+#define APP_ID 1
+#endif
+
+#ifndef APP_VERSION_PRERELEASE
+#define APP_VERSION_PRERELEASE ""
+#endif
+
+#ifndef APP_VERSION_METADATA
+#define APP_VERSION_METADATA ""
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP
+#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 512
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS
+#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN
+#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS
+#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE
+#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
+#endif
+
+#ifndef NRF_CLOCK_ENABLED
+#define NRF_CLOCK_ENABLED 1
+#endif
+
+#ifndef CLOCK_CONFIG_LF_SRC
+#define CLOCK_CONFIG_LF_SRC 1
+#endif
+
+#ifndef CLOCK_CONFIG_IRQ_PRIORITY
+#define CLOCK_CONFIG_IRQ_PRIORITY 7
+#endif
+
+#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
+
+#ifndef POWER_ENABLED
+#define POWER_ENABLED 1
+#endif
+
+#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
+
+#ifndef POWER_CONFIG_IRQ_PRIORITY
+#define POWER_CONFIG_IRQ_PRIORITY 7
+#endif
+
+#if (SPIS_AS_SERIAL_TRANSPORT == 1)
+
+#ifndef SPIS_ENABLED
+#define SPIS_ENABLED 1
+#endif
+
+#ifndef SPIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+#ifndef SPIS0_ENABLED
+#define SPIS0_ENABLED 1
+#endif
+
+#endif // SPIS_AS_SERIAL_TRANSPORT == 1
+
+#ifndef NRFX_NVMC_ENABLED
+#define NRFX_NVMC_ENABLED 1
+#endif
+
+#ifndef TIMER_ENABLED
+#define TIMER_ENABLED 1
+#endif
+
+#ifndef TIMER0_ENABLED
+#define TIMER0_ENABLED 1
+#endif
+
+#ifndef TIMER1_ENABLED
+#define TIMER1_ENABLED 1
+#endif
+
+#ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+#endif // APP_CONFIG_H
diff --git a/third_party/NordicSemiconductor/config/nrf52811/config/sdk_config.h b/third_party/NordicSemiconductor/config/nrf52811/config/sdk_config.h
new file mode 100644
index 0000000..0fc9038
--- /dev/null
+++ b/third_party/NordicSemiconductor/config/nrf52811/config/sdk_config.h
@@ -0,0 +1,10335 @@
+/**
+ * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ *    Semiconductor ASA integrated circuit in a product or a software update for
+ *    such product, must reproduce the above copyright notice, this list of
+ *    conditions and the following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ *    Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ *    engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+
+#ifndef SDK_CONFIG_H
+#define SDK_CONFIG_H
+// <<< Use Configuration Wizard in Context Menu >>>\n
+#ifdef USE_APP_CONFIG
+#include "app_config.h"
+#endif
+// <h> nRF_BLE 
+
+//==========================================================
+// <q> BLE_ADVERTISING_ENABLED  - ble_advertising - Advertising module
+ 
+
+#ifndef BLE_ADVERTISING_ENABLED
+#define BLE_ADVERTISING_ENABLED 0
+#endif
+
+// <q> BLE_DTM_ENABLED  - ble_dtm - Module for testing RF/PHY using DTM commands
+ 
+
+#ifndef BLE_DTM_ENABLED
+#define BLE_DTM_ENABLED 0
+#endif
+
+// <q> BLE_RACP_ENABLED  - ble_racp - Record Access Control Point library
+ 
+
+#ifndef BLE_RACP_ENABLED
+#define BLE_RACP_ENABLED 0
+#endif
+
+// <e> NRF_BLE_QWR_ENABLED - nrf_ble_qwr - Queued writes support module (prepare/execute write)
+//==========================================================
+#ifndef NRF_BLE_QWR_ENABLED
+#define NRF_BLE_QWR_ENABLED 0
+#endif
+// <o> NRF_BLE_QWR_MAX_ATTR - Maximum number of attribute handles that can be registered. This number must be adjusted according to the number of attributes for which Queued Writes will be enabled. If it is zero, the module will reject all Queued Write requests. 
+#ifndef NRF_BLE_QWR_MAX_ATTR
+#define NRF_BLE_QWR_MAX_ATTR 0
+#endif
+
+// </e>
+
+// <e> PEER_MANAGER_ENABLED - peer_manager - Peer Manager
+//==========================================================
+#ifndef PEER_MANAGER_ENABLED
+#define PEER_MANAGER_ENABLED 0
+#endif
+// <o> PM_MAX_REGISTRANTS - Number of event handlers that can be registered. 
+#ifndef PM_MAX_REGISTRANTS
+#define PM_MAX_REGISTRANTS 3
+#endif
+
+// <o> PM_FLASH_BUFFERS - Number of internal buffers for flash operations. 
+// <i> Decrease this value to lower RAM usage.
+
+#ifndef PM_FLASH_BUFFERS
+#define PM_FLASH_BUFFERS 4
+#endif
+
+// <q> PM_CENTRAL_ENABLED  - Enable/disable central-specific Peer Manager functionality.
+ 
+
+// <i> Enable/disable central-specific Peer Manager functionality.
+
+#ifndef PM_CENTRAL_ENABLED
+#define PM_CENTRAL_ENABLED 1
+#endif
+
+// <q> PM_SERVICE_CHANGED_ENABLED  - Enable/disable the service changed management for GATT server in Peer Manager.
+ 
+
+// <i> If not using a GATT server, or using a server wihout a service changed characteristic,
+// <i> disable this to save code space.
+
+#ifndef PM_SERVICE_CHANGED_ENABLED
+#define PM_SERVICE_CHANGED_ENABLED 1
+#endif
+
+// <q> PM_PEER_RANKS_ENABLED  - Enable/disable the peer rank management in Peer Manager.
+ 
+
+// <i> Set this to false to save code space if not using the peer rank API.
+
+#ifndef PM_PEER_RANKS_ENABLED
+#define PM_PEER_RANKS_ENABLED 1
+#endif
+
+// <q> PM_LESC_ENABLED  - Enable/disable LESC support in Peer Manager.
+ 
+
+// <i> If set to true, you need to call nrf_ble_lesc_request_handler() in the main loop to respond to LESC-related BLE events. If LESC support is not required, set this to false to save code space.
+
+#ifndef PM_LESC_ENABLED
+#define PM_LESC_ENABLED 0
+#endif
+
+// <e> PM_RA_PROTECTION_ENABLED - Enable/disable protection against repeated pairing attempts in Peer Manager.
+//==========================================================
+#ifndef PM_RA_PROTECTION_ENABLED
+#define PM_RA_PROTECTION_ENABLED 0
+#endif
+// <o> PM_RA_PROTECTION_TRACKED_PEERS_NUM - Maximum number of peers whose authorization status can be tracked. 
+#ifndef PM_RA_PROTECTION_TRACKED_PEERS_NUM
+#define PM_RA_PROTECTION_TRACKED_PEERS_NUM 8
+#endif
+
+// <o> PM_RA_PROTECTION_MIN_WAIT_INTERVAL - Minimum waiting interval (in ms) before a new pairing attempt can be initiated. 
+#ifndef PM_RA_PROTECTION_MIN_WAIT_INTERVAL
+#define PM_RA_PROTECTION_MIN_WAIT_INTERVAL 4000
+#endif
+
+// <o> PM_RA_PROTECTION_MAX_WAIT_INTERVAL - Maximum waiting interval (in ms) before a new pairing attempt can be initiated. 
+#ifndef PM_RA_PROTECTION_MAX_WAIT_INTERVAL
+#define PM_RA_PROTECTION_MAX_WAIT_INTERVAL 64000
+#endif
+
+// <o> PM_RA_PROTECTION_REWARD_PERIOD - Reward period (in ms). 
+// <i> The waiting interval is gradually decreased when no new failed pairing attempts are made during reward period.
+
+#ifndef PM_RA_PROTECTION_REWARD_PERIOD
+#define PM_RA_PROTECTION_REWARD_PERIOD 10000
+#endif
+
+// </e>
+
+// <o> PM_HANDLER_SEC_DELAY_MS - Delay before starting security. 
+// <i>  This might be necessary for interoperability reasons, especially as peripheral.
+
+#ifndef PM_HANDLER_SEC_DELAY_MS
+#define PM_HANDLER_SEC_DELAY_MS 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_BLE_Services 
+
+//==========================================================
+// <q> BLE_ANCS_C_ENABLED  - ble_ancs_c - Apple Notification Service Client
+ 
+
+#ifndef BLE_ANCS_C_ENABLED
+#define BLE_ANCS_C_ENABLED 0
+#endif
+
+// <q> BLE_ANS_C_ENABLED  - ble_ans_c - Alert Notification Service Client
+ 
+
+#ifndef BLE_ANS_C_ENABLED
+#define BLE_ANS_C_ENABLED 0
+#endif
+
+// <q> BLE_BAS_C_ENABLED  - ble_bas_c - Battery Service Client
+ 
+
+#ifndef BLE_BAS_C_ENABLED
+#define BLE_BAS_C_ENABLED 0
+#endif
+
+// <e> BLE_BAS_ENABLED - ble_bas - Battery Service
+//==========================================================
+#ifndef BLE_BAS_ENABLED
+#define BLE_BAS_ENABLED 0
+#endif
+// <e> BLE_BAS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_BAS_CONFIG_LOG_ENABLED
+#define BLE_BAS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_BAS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_BAS_CONFIG_LOG_LEVEL
+#define BLE_BAS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_BAS_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 BLE_BAS_CONFIG_INFO_COLOR
+#define BLE_BAS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_BAS_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 BLE_BAS_CONFIG_DEBUG_COLOR
+#define BLE_BAS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_CSCS_ENABLED  - ble_cscs - Cycling Speed and Cadence Service
+ 
+
+#ifndef BLE_CSCS_ENABLED
+#define BLE_CSCS_ENABLED 0
+#endif
+
+// <q> BLE_CTS_C_ENABLED  - ble_cts_c - Current Time Service Client
+ 
+
+#ifndef BLE_CTS_C_ENABLED
+#define BLE_CTS_C_ENABLED 0
+#endif
+
+// <q> BLE_DIS_ENABLED  - ble_dis - Device Information Service
+ 
+
+#ifndef BLE_DIS_ENABLED
+#define BLE_DIS_ENABLED 0
+#endif
+
+// <q> BLE_GLS_ENABLED  - ble_gls - Glucose Service
+ 
+
+#ifndef BLE_GLS_ENABLED
+#define BLE_GLS_ENABLED 0
+#endif
+
+// <q> BLE_HIDS_ENABLED  - ble_hids - Human Interface Device Service
+ 
+
+#ifndef BLE_HIDS_ENABLED
+#define BLE_HIDS_ENABLED 0
+#endif
+
+// <q> BLE_HRS_C_ENABLED  - ble_hrs_c - Heart Rate Service Client
+ 
+
+#ifndef BLE_HRS_C_ENABLED
+#define BLE_HRS_C_ENABLED 0
+#endif
+
+// <q> BLE_HRS_ENABLED  - ble_hrs - Heart Rate Service
+ 
+
+#ifndef BLE_HRS_ENABLED
+#define BLE_HRS_ENABLED 0
+#endif
+
+// <q> BLE_HTS_ENABLED  - ble_hts - Health Thermometer Service
+ 
+
+#ifndef BLE_HTS_ENABLED
+#define BLE_HTS_ENABLED 0
+#endif
+
+// <q> BLE_IAS_C_ENABLED  - ble_ias_c - Immediate Alert Service Client
+ 
+
+#ifndef BLE_IAS_C_ENABLED
+#define BLE_IAS_C_ENABLED 0
+#endif
+
+// <e> BLE_IAS_ENABLED - ble_ias - Immediate Alert Service
+//==========================================================
+#ifndef BLE_IAS_ENABLED
+#define BLE_IAS_ENABLED 0
+#endif
+// <e> BLE_IAS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_IAS_CONFIG_LOG_ENABLED
+#define BLE_IAS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_IAS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_IAS_CONFIG_LOG_LEVEL
+#define BLE_IAS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_IAS_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 BLE_IAS_CONFIG_INFO_COLOR
+#define BLE_IAS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_IAS_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 BLE_IAS_CONFIG_DEBUG_COLOR
+#define BLE_IAS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_LBS_C_ENABLED  - ble_lbs_c - Nordic LED Button Service Client
+ 
+
+#ifndef BLE_LBS_C_ENABLED
+#define BLE_LBS_C_ENABLED 0
+#endif
+
+// <q> BLE_LBS_ENABLED  - ble_lbs - LED Button Service
+ 
+
+#ifndef BLE_LBS_ENABLED
+#define BLE_LBS_ENABLED 0
+#endif
+
+// <q> BLE_LLS_ENABLED  - ble_lls - Link Loss Service
+ 
+
+#ifndef BLE_LLS_ENABLED
+#define BLE_LLS_ENABLED 0
+#endif
+
+// <q> BLE_NUS_C_ENABLED  - ble_nus_c - Nordic UART Central Service
+ 
+
+#ifndef BLE_NUS_C_ENABLED
+#define BLE_NUS_C_ENABLED 0
+#endif
+
+// <e> BLE_NUS_ENABLED - ble_nus - Nordic UART Service
+//==========================================================
+#ifndef BLE_NUS_ENABLED
+#define BLE_NUS_ENABLED 0
+#endif
+// <e> BLE_NUS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_NUS_CONFIG_LOG_ENABLED
+#define BLE_NUS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_NUS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_NUS_CONFIG_LOG_LEVEL
+#define BLE_NUS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_NUS_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 BLE_NUS_CONFIG_INFO_COLOR
+#define BLE_NUS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_NUS_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 BLE_NUS_CONFIG_DEBUG_COLOR
+#define BLE_NUS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_RSCS_C_ENABLED  - ble_rscs_c - Running Speed and Cadence Client
+ 
+
+#ifndef BLE_RSCS_C_ENABLED
+#define BLE_RSCS_C_ENABLED 0
+#endif
+
+// <q> BLE_RSCS_ENABLED  - ble_rscs - Running Speed and Cadence Service
+ 
+
+#ifndef BLE_RSCS_ENABLED
+#define BLE_RSCS_ENABLED 0
+#endif
+
+// <q> BLE_TPS_ENABLED  - ble_tps - TX Power Service
+ 
+
+#ifndef BLE_TPS_ENABLED
+#define BLE_TPS_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Core 
+
+//==========================================================
+// <e> NRF_MPU_LIB_ENABLED - nrf_mpu_lib - Module for MPU
+//==========================================================
+#ifndef NRF_MPU_LIB_ENABLED
+#define NRF_MPU_LIB_ENABLED 0
+#endif
+// <q> NRF_MPU_LIB_CLI_CMDS  - Enable CLI commands specific to the module.
+ 
+
+#ifndef NRF_MPU_LIB_CLI_CMDS
+#define NRF_MPU_LIB_CLI_CMDS 0
+#endif
+
+// </e>
+
+// <e> NRF_STACK_GUARD_ENABLED - nrf_stack_guard - Stack guard
+//==========================================================
+#ifndef NRF_STACK_GUARD_ENABLED
+#define NRF_STACK_GUARD_ENABLED 0
+#endif
+// <o> NRF_STACK_GUARD_CONFIG_SIZE  - Size of the stack guard.
+ 
+// <5=> 32 bytes 
+// <6=> 64 bytes 
+// <7=> 128 bytes 
+// <8=> 256 bytes 
+// <9=> 512 bytes 
+// <10=> 1024 bytes 
+// <11=> 2048 bytes 
+// <12=> 4096 bytes 
+
+#ifndef NRF_STACK_GUARD_CONFIG_SIZE
+#define NRF_STACK_GUARD_CONFIG_SIZE 7
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Crypto 
+
+//==========================================================
+// <e> NRF_CRYPTO_ENABLED - nrf_crypto - Cryptography library.
+//==========================================================
+#ifndef NRF_CRYPTO_ENABLED
+#define NRF_CRYPTO_ENABLED 1
+#endif
+// <o> NRF_CRYPTO_ALLOCATOR  - Memory allocator
+ 
+
+// <i> Choose memory allocator used by nrf_crypto. Default is alloca if possible or nrf_malloc otherwise. If 'User macros' are selected, the user has to create 'nrf_crypto_allocator.h' file that contains NRF_CRYPTO_ALLOC, NRF_CRYPTO_FREE, and NRF_CRYPTO_ALLOC_ON_STACK.
+// <0=> Default 
+// <1=> User macros 
+// <2=> On stack (alloca) 
+// <3=> C dynamic memory (malloc) 
+// <4=> SDK Memory Manager (nrf_malloc) 
+
+#ifndef NRF_CRYPTO_ALLOCATOR
+#define NRF_CRYPTO_ALLOCATOR 0
+#endif
+
+// <e> NRF_CRYPTO_BACKEND_CC310_BL_ENABLED - Enable the ARM Cryptocell CC310 reduced backend.
+
+// <i> The CC310 hardware-accelerated cryptography backend with reduced functionality and footprint (only available on nRF52840).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED  - Enable the secp224r1 elliptic curve support using CC310_BL.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED 0
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED  - Enable the secp256r1 elliptic curve support using CC310_BL.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED  - CC310_BL SHA-256 hash functionality.
+ 
+
+// <i> CC310_BL backend implementation for hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED  - nrf_cc310_bl buffers to RAM before running hash operation
+ 
+
+// <i> Enabling this makes hashing of addresses in FLASH range possible. Size of buffer allocated for hashing is set by NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED 0
+#endif
+
+// <o> NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE - nrf_cc310_bl hash outputs digests in little endian 
+// <i> Makes the nrf_cc310_bl hash functions output digests in little endian format. Only for use in nRF SDK DFU!
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE 4096
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED  - Enable Interrupts while support using CC310 bl.
+ 
+
+// <i> Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_CC310_ENABLED - Enable the ARM Cryptocell CC310 backend.
+
+// <i> The CC310 hardware-accelerated cryptography backend (only available on nRF52840).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CC310_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED  - Enable the AES CBC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED  - Enable the AES CTR mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED  - Enable the AES ECB mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED  - Enable the AES CBC_MAC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED  - Enable the AES CMAC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED  - Enable the AES CCM mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED  - Enable the AES CCM* mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED  - Enable the CHACHA-POLY mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED  - Enable the secp160r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED  - Enable the secp160r2 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED  - Enable the secp192r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED  - Enable the secp224r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED  - Enable the secp256r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED  - Enable the secp384r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED  - Enable the secp521r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED  - Enable the secp160k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED  - Enable the secp192k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED  - Enable the secp224k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED  - Enable the secp256k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED  - Enable the Curve25519 curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED  - Enable the Ed25519 curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED  - CC310 SHA-256 hash functionality.
+ 
+
+// <i> CC310 backend implementation for hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED  - CC310 SHA-512 hash functionality
+ 
+
+// <i> CC310 backend implementation for SHA-512 (in software).
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED  - CC310 HMAC using SHA-256
+ 
+
+// <i> CC310 backend implementation for HMAC using hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED  - CC310 HMAC using SHA-512
+ 
+
+// <i> CC310 backend implementation for HMAC using SHA-512 (in software).
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED  - Enable RNG support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED  - Enable Interrupts while support using CC310.
+ 
+
+// <i> Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_CIFRA_ENABLED - Enable the Cifra backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CIFRA_ENABLED
+#define NRF_CRYPTO_BACKEND_CIFRA_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED  - Enable the AES EAX mode using Cifra.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED
+#define NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED - Enable the mbed TLS backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED  - Enable the AES CBC mode mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED  - Enable the AES CTR mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED  - Enable the AES CFB mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED  - Enable the AES ECB mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED  - Enable the AES CBC MAC mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED  - Enable the AES CMAC mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED  - Enable the AES CCM mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED  - Enable the AES GCM mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED  - Enable secp192r1 (NIST 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192r1 (NIST 192-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED  - Enable secp224r1 (NIST 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224r1 (NIST 224-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED  - Enable secp256r1 (NIST 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256r1 (NIST 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED  - Enable secp384r1 (NIST 384-bit) curve
+ 
+
+// <i> Enable this setting if you need secp384r1 (NIST 384-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED  - Enable secp521r1 (NIST 521-bit) curve
+ 
+
+// <i> Enable this setting if you need secp521r1 (NIST 521-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED  - Enable secp192k1 (Koblitz 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192k1 (Koblitz 192-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED  - Enable secp224k1 (Koblitz 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224k1 (Koblitz 224-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED  - Enable secp256k1 (Koblitz 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256k1 (Koblitz 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED  - Enable bp256r1 (Brainpool 256-bit) curve
+ 
+
+// <i> Enable this setting if you need bp256r1 (Brainpool 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED  - Enable bp384r1 (Brainpool 384-bit) curve
+ 
+
+// <i> Enable this setting if you need bp384r1 (Brainpool 384-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED  - Enable bp512r1 (Brainpool 512-bit) curve
+ 
+
+// <i> Enable this setting if you need bp512r1 (Brainpool 512-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED  - Enable Curve25519 curve
+ 
+
+// <i> Enable this setting if you need Curve25519 support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED  - Enable mbed TLS SHA-256 hash functionality.
+ 
+
+// <i> mbed TLS backend implementation for SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED  - Enable mbed TLS SHA-512 hash functionality.
+ 
+
+// <i> mbed TLS backend implementation for SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED  - Enable mbed TLS HMAC using SHA-256.
+ 
+
+// <i> mbed TLS backend implementation for HMAC using SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED  - Enable mbed TLS HMAC using SHA-512.
+ 
+
+// <i> mbed TLS backend implementation for HMAC using SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED - Enable the micro-ecc backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED  - Enable secp192r1 (NIST 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192r1 (NIST 192-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED  - Enable secp224r1 (NIST 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224r1 (NIST 224-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED  - Enable secp256r1 (NIST 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256r1 (NIST 256-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED  - Enable secp256k1 (Koblitz 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256k1 (Koblitz 256-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED - Enable the nRF HW RNG backend.
+
+// <i> The nRF HW backend provide access to RNG peripheral in nRF5x devices.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED  - Enable mbed TLS CTR-DRBG algorithm.
+ 
+
+// <i> Enable mbed TLS CTR-DRBG standardized by NIST (NIST SP 800-90A Rev. 1). The nRF HW RNG is used as an entropy source for seeding.
+
+#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_NRF_SW_ENABLED - Enable the legacy nRFx sw for crypto.
+
+// <i> The nRF SW cryptography backend (only used in bootloader context).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_NRF_SW_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_SW_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED  - nRF SW hash backend support for SHA-256
+ 
+
+// <i> The nRF SW backend provide access to nRF SDK legacy hash implementation of SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_OBERON_ENABLED - Enable the Oberon backend
+
+// <i> The Oberon backend
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED  - Enable the CHACHA-POLY mode using Oberon.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED  - Enable secp256r1 curve
+ 
+
+// <i> Enable this setting if you need secp256r1 curve support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED  - Enable Curve25519 ECDH
+ 
+
+// <i> Enable this setting if you need Curve25519 ECDH support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED  - Enable Ed25519 signature scheme
+ 
+
+// <i> Enable this setting if you need Ed25519 support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED  - Oberon SHA-256 hash functionality
+ 
+
+// <i> Oberon backend implementation for SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED  - Oberon SHA-512 hash functionality
+ 
+
+// <i> Oberon backend implementation for SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED  - Oberon HMAC using SHA-256
+ 
+
+// <i> Oberon backend implementation for HMAC using SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED  - Oberon HMAC using SHA-512
+ 
+
+// <i> Oberon backend implementation for HMAC using SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_OPTIGA_ENABLED - Enable the nrf_crypto Optiga Trust X backend.
+
+// <i> Enables the nrf_crypto backend for Optiga Trust X devices.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED  - Optiga backend support for RNG
+ 
+
+// <i> The Optiga backend provide external chip RNG.
+
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED 0
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED  - Optiga backend support for ECC secp256r1
+ 
+
+// <i> The Optiga backend provide external chip ECC using secp256r1.
+
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED 1
+#endif
+
+// </e>
+
+// <q> NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED  - Big-endian byte order in raw Curve25519 data
+ 
+
+// <i> Enable big-endian byte order in Curve25519 API, if set to 1. Use little-endian, if set to 0.
+
+#ifndef NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED
+#define NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_DFU 
+
+//==========================================================
+// <h> ble_dfu - Device Firmware Update
+
+//==========================================================
+// <q> BLE_DFU_ENABLED  - Enable DFU Service.
+ 
+
+#ifndef BLE_DFU_ENABLED
+#define BLE_DFU_ENABLED 0
+#endif
+
+// <q> NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS  - Buttonless DFU supports bonds.
+ 
+
+#ifndef NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS
+#define NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Drivers 
+
+//==========================================================
+// <e> COMP_ENABLED - nrf_drv_comp - COMP peripheral driver - legacy layer
+//==========================================================
+#ifndef COMP_ENABLED
+#define COMP_ENABLED 0
+#endif
+// <o> COMP_CONFIG_REF  - Reference voltage
+ 
+// <0=> Internal 1.2V 
+// <1=> Internal 1.8V 
+// <2=> Internal 2.4V 
+// <4=> VDD 
+// <7=> ARef 
+
+#ifndef COMP_CONFIG_REF
+#define COMP_CONFIG_REF 1
+#endif
+
+// <o> COMP_CONFIG_MAIN_MODE  - Main mode
+ 
+// <0=> Single ended 
+// <1=> Differential 
+
+#ifndef COMP_CONFIG_MAIN_MODE
+#define COMP_CONFIG_MAIN_MODE 0
+#endif
+
+// <o> COMP_CONFIG_SPEED_MODE  - Speed mode
+ 
+// <0=> Low power 
+// <1=> Normal 
+// <2=> High speed 
+
+#ifndef COMP_CONFIG_SPEED_MODE
+#define COMP_CONFIG_SPEED_MODE 2
+#endif
+
+// <o> COMP_CONFIG_HYST  - Hystheresis
+ 
+// <0=> No 
+// <1=> 50mV 
+
+#ifndef COMP_CONFIG_HYST
+#define COMP_CONFIG_HYST 0
+#endif
+
+// <o> COMP_CONFIG_ISOURCE  - Current Source
+ 
+// <0=> Off 
+// <1=> 2.5 uA 
+// <2=> 5 uA 
+// <3=> 10 uA 
+
+#ifndef COMP_CONFIG_ISOURCE
+#define COMP_CONFIG_ISOURCE 0
+#endif
+
+// <o> COMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef COMP_CONFIG_INPUT
+#define COMP_CONFIG_INPUT 0
+#endif
+
+// <o> COMP_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef COMP_CONFIG_IRQ_PRIORITY
+#define COMP_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <q> EGU_ENABLED  - nrf_drv_swi - SWI(EGU) peripheral driver - legacy layer
+ 
+
+#ifndef EGU_ENABLED
+#define EGU_ENABLED 0
+#endif
+
+// <e> GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver - legacy layer
+//==========================================================
+#ifndef GPIOTE_ENABLED
+#define GPIOTE_ENABLED 0
+#endif
+// <o> GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins 
+#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS
+#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1
+#endif
+
+// <o> GPIOTE_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef GPIOTE_CONFIG_IRQ_PRIORITY
+#define GPIOTE_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> I2S_ENABLED - nrf_drv_i2s - I2S peripheral driver - legacy layer
+//==========================================================
+#ifndef I2S_ENABLED
+#define I2S_ENABLED 0
+#endif
+// <o> I2S_CONFIG_SCK_PIN - SCK pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SCK_PIN
+#define I2S_CONFIG_SCK_PIN 31
+#endif
+
+// <o> I2S_CONFIG_LRCK_PIN - LRCK pin  <1-31> 
+
+
+#ifndef I2S_CONFIG_LRCK_PIN
+#define I2S_CONFIG_LRCK_PIN 30
+#endif
+
+// <o> I2S_CONFIG_MCK_PIN - MCK pin 
+#ifndef I2S_CONFIG_MCK_PIN
+#define I2S_CONFIG_MCK_PIN 255
+#endif
+
+// <o> I2S_CONFIG_SDOUT_PIN - SDOUT pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SDOUT_PIN
+#define I2S_CONFIG_SDOUT_PIN 29
+#endif
+
+// <o> I2S_CONFIG_SDIN_PIN - SDIN pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SDIN_PIN
+#define I2S_CONFIG_SDIN_PIN 28
+#endif
+
+// <o> I2S_CONFIG_MASTER  - Mode
+ 
+// <0=> Master 
+// <1=> Slave 
+
+#ifndef I2S_CONFIG_MASTER
+#define I2S_CONFIG_MASTER 0
+#endif
+
+// <o> I2S_CONFIG_FORMAT  - Format
+ 
+// <0=> I2S 
+// <1=> Aligned 
+
+#ifndef I2S_CONFIG_FORMAT
+#define I2S_CONFIG_FORMAT 0
+#endif
+
+// <o> I2S_CONFIG_ALIGN  - Alignment
+ 
+// <0=> Left 
+// <1=> Right 
+
+#ifndef I2S_CONFIG_ALIGN
+#define I2S_CONFIG_ALIGN 0
+#endif
+
+// <o> I2S_CONFIG_SWIDTH  - Sample width (bits)
+ 
+// <0=> 8 
+// <1=> 16 
+// <2=> 24 
+
+#ifndef I2S_CONFIG_SWIDTH
+#define I2S_CONFIG_SWIDTH 1
+#endif
+
+// <o> I2S_CONFIG_CHANNELS  - Channels
+ 
+// <0=> Stereo 
+// <1=> Left 
+// <2=> Right 
+
+#ifndef I2S_CONFIG_CHANNELS
+#define I2S_CONFIG_CHANNELS 1
+#endif
+
+// <o> I2S_CONFIG_MCK_SETUP  - MCK behavior
+ 
+// <0=> Disabled 
+// <2147483648=> 32MHz/2 
+// <1342177280=> 32MHz/3 
+// <1073741824=> 32MHz/4 
+// <805306368=> 32MHz/5 
+// <671088640=> 32MHz/6 
+// <536870912=> 32MHz/8 
+// <402653184=> 32MHz/10 
+// <369098752=> 32MHz/11 
+// <285212672=> 32MHz/15 
+// <268435456=> 32MHz/16 
+// <201326592=> 32MHz/21 
+// <184549376=> 32MHz/23 
+// <142606336=> 32MHz/30 
+// <138412032=> 32MHz/31 
+// <134217728=> 32MHz/32 
+// <100663296=> 32MHz/42 
+// <68157440=> 32MHz/63 
+// <34340864=> 32MHz/125 
+
+#ifndef I2S_CONFIG_MCK_SETUP
+#define I2S_CONFIG_MCK_SETUP 536870912
+#endif
+
+// <o> I2S_CONFIG_RATIO  - MCK/LRCK ratio
+ 
+// <0=> 32x 
+// <1=> 48x 
+// <2=> 64x 
+// <3=> 96x 
+// <4=> 128x 
+// <5=> 192x 
+// <6=> 256x 
+// <7=> 384x 
+// <8=> 512x 
+
+#ifndef I2S_CONFIG_RATIO
+#define I2S_CONFIG_RATIO 2000
+#endif
+
+// <o> I2S_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef I2S_CONFIG_IRQ_PRIORITY
+#define I2S_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> I2S_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef I2S_CONFIG_LOG_ENABLED
+#define I2S_CONFIG_LOG_ENABLED 0
+#endif
+// <o> I2S_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef I2S_CONFIG_LOG_LEVEL
+#define I2S_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 I2S_CONFIG_INFO_COLOR
+#define I2S_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 I2S_CONFIG_DEBUG_COLOR
+#define I2S_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> LPCOMP_ENABLED - nrf_drv_lpcomp - LPCOMP peripheral driver - legacy layer
+//==========================================================
+#ifndef LPCOMP_ENABLED
+#define LPCOMP_ENABLED 0
+#endif
+// <o> LPCOMP_CONFIG_REFERENCE  - Reference voltage
+ 
+// <0=> Supply 1/8 
+// <1=> Supply 2/8 
+// <2=> Supply 3/8 
+// <3=> Supply 4/8 
+// <4=> Supply 5/8 
+// <5=> Supply 6/8 
+// <6=> Supply 7/8 
+// <8=> Supply 1/16 (nRF52) 
+// <9=> Supply 3/16 (nRF52) 
+// <10=> Supply 5/16 (nRF52) 
+// <11=> Supply 7/16 (nRF52) 
+// <12=> Supply 9/16 (nRF52) 
+// <13=> Supply 11/16 (nRF52) 
+// <14=> Supply 13/16 (nRF52) 
+// <15=> Supply 15/16 (nRF52) 
+// <7=> External Ref 0 
+// <65543=> External Ref 1 
+
+#ifndef LPCOMP_CONFIG_REFERENCE
+#define LPCOMP_CONFIG_REFERENCE 3
+#endif
+
+// <o> LPCOMP_CONFIG_DETECTION  - Detection
+ 
+// <0=> Crossing 
+// <1=> Up 
+// <2=> Down 
+
+#ifndef LPCOMP_CONFIG_DETECTION
+#define LPCOMP_CONFIG_DETECTION 2
+#endif
+
+// <o> LPCOMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef LPCOMP_CONFIG_INPUT
+#define LPCOMP_CONFIG_INPUT 0
+#endif
+
+// <q> LPCOMP_CONFIG_HYST  - Hysteresis
+ 
+
+#ifndef LPCOMP_CONFIG_HYST
+#define LPCOMP_CONFIG_HYST 0
+#endif
+
+// <o> LPCOMP_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef LPCOMP_CONFIG_IRQ_PRIORITY
+#define LPCOMP_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <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=> RC 
+// <1=> XTAL 
+// <2=> Synth 
+// <131073=> External Low Swing 
+// <196609=> External Full Swing 
+
+#ifndef NRFX_CLOCK_CONFIG_LF_SRC
+#define NRFX_CLOCK_CONFIG_LF_SRC 1
+#endif
+
+// <o> NRFX_CLOCK_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_CONFIG_IRQ_PRIORITY
+#define NRFX_CLOCK_CONFIG_IRQ_PRIORITY 6
+#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_CONFIG_REF  - Reference voltage
+ 
+// <0=> Internal 1.2V 
+// <1=> Internal 1.8V 
+// <2=> Internal 2.4V 
+// <4=> VDD 
+// <7=> ARef 
+
+#ifndef NRFX_COMP_CONFIG_REF
+#define NRFX_COMP_CONFIG_REF 1
+#endif
+
+// <o> NRFX_COMP_CONFIG_MAIN_MODE  - Main mode
+ 
+// <0=> Single ended 
+// <1=> Differential 
+
+#ifndef NRFX_COMP_CONFIG_MAIN_MODE
+#define NRFX_COMP_CONFIG_MAIN_MODE 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_SPEED_MODE  - Speed mode
+ 
+// <0=> Low power 
+// <1=> Normal 
+// <2=> High speed 
+
+#ifndef NRFX_COMP_CONFIG_SPEED_MODE
+#define NRFX_COMP_CONFIG_SPEED_MODE 2
+#endif
+
+// <o> NRFX_COMP_CONFIG_HYST  - Hystheresis
+ 
+// <0=> No 
+// <1=> 50mV 
+
+#ifndef NRFX_COMP_CONFIG_HYST
+#define NRFX_COMP_CONFIG_HYST 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_ISOURCE  - Current Source
+ 
+// <0=> Off 
+// <1=> 2.5 uA 
+// <2=> 5 uA 
+// <3=> 10 uA 
+
+#ifndef NRFX_COMP_CONFIG_ISOURCE
+#define NRFX_COMP_CONFIG_ISOURCE 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef NRFX_COMP_CONFIG_INPUT
+#define NRFX_COMP_CONFIG_INPUT 0
+#endif
+
+// <o> NRFX_COMP_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_CONFIG_IRQ_PRIORITY
+#define NRFX_COMP_CONFIG_IRQ_PRIORITY 6
+#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_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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 6
+#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_PDM_ENABLED - nrfx_pdm - PDM peripheral driver
+//==========================================================
+#ifndef NRFX_PDM_ENABLED
+#define NRFX_PDM_ENABLED 0
+#endif
+// <o> NRFX_PDM_CONFIG_MODE  - Mode
+ 
+// <0=> Stereo 
+// <1=> Mono 
+
+#ifndef NRFX_PDM_CONFIG_MODE
+#define NRFX_PDM_CONFIG_MODE 1
+#endif
+
+// <o> NRFX_PDM_CONFIG_EDGE  - Edge
+ 
+// <0=> Left falling 
+// <1=> Left rising 
+
+#ifndef NRFX_PDM_CONFIG_EDGE
+#define NRFX_PDM_CONFIG_EDGE 0
+#endif
+
+// <o> NRFX_PDM_CONFIG_CLOCK_FREQ  - Clock frequency
+ 
+// <134217728=> 1000k 
+// <138412032=> 1032k (default) 
+// <142606336=> 1067k 
+
+#ifndef NRFX_PDM_CONFIG_CLOCK_FREQ
+#define NRFX_PDM_CONFIG_CLOCK_FREQ 138412032
+#endif
+
+// <o> NRFX_PDM_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_CONFIG_IRQ_PRIORITY
+#define NRFX_PDM_CONFIG_IRQ_PRIORITY 6
+#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 1
+#endif
+// <o> NRFX_POWER_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_CONFIG_IRQ_PRIORITY
+#define NRFX_POWER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> NRFX_POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCEN
+#define NRFX_POWER_CONFIG_DEFAULT_DCDCEN 0
+#endif
+
+// <q> NRFX_POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCENHV
+#define NRFX_POWER_CONFIG_DEFAULT_DCDCENHV 0
+#endif
+
+// </e>
+
+// <e> NRFX_PPI_ENABLED - nrfx_ppi - PPI peripheral allocator
+//==========================================================
+#ifndef NRFX_PPI_ENABLED
+#define NRFX_PPI_ENABLED 0
+#endif
+// <e> NRFX_PPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_PPI_CONFIG_LOG_ENABLED
+#define NRFX_PPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_PPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_PPI_CONFIG_LOG_LEVEL
+#define NRFX_PPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_PPI_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_PPI_CONFIG_INFO_COLOR
+#define NRFX_PPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_PPI_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_PPI_CONFIG_DEBUG_COLOR
+#define NRFX_PPI_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  - Enable PWM0 instance
+ 
+
+#ifndef NRFX_PWM0_ENABLED
+#define NRFX_PWM0_ENABLED 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK  - Base clock
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK
+#define NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK 4
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE  - Count mode
+ 
+// <0=> Up 
+// <1=> Up and Down 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE - Top value 
+#ifndef NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE
+#define NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE 1000
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE  - Load mode
+ 
+// <0=> Common 
+// <1=> Grouped 
+// <2=> Individual 
+// <3=> Waveform 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_STEP_MODE  - Step mode
+ 
+// <0=> Auto 
+// <1=> Triggered 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_STEP_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_STEP_MODE 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 6
+#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_CONFIG_REPORTPER  - Report period
+ 
+// <0=> 10 Samples 
+// <1=> 40 Samples 
+// <2=> 80 Samples 
+// <3=> 120 Samples 
+// <4=> 160 Samples 
+// <5=> 200 Samples 
+// <6=> 240 Samples 
+// <7=> 280 Samples 
+
+#ifndef NRFX_QDEC_CONFIG_REPORTPER
+#define NRFX_QDEC_CONFIG_REPORTPER 0
+#endif
+
+// <o> NRFX_QDEC_CONFIG_SAMPLEPER  - Sample period
+ 
+// <0=> 128 us 
+// <1=> 256 us 
+// <2=> 512 us 
+// <3=> 1024 us 
+// <4=> 2048 us 
+// <5=> 4096 us 
+// <6=> 8192 us 
+// <7=> 16384 us 
+
+#ifndef NRFX_QDEC_CONFIG_SAMPLEPER
+#define NRFX_QDEC_CONFIG_SAMPLEPER 7
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_A - A pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_A
+#define NRFX_QDEC_CONFIG_PIO_A 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_B - B pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_B
+#define NRFX_QDEC_CONFIG_PIO_B 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_LED - LED pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_LED
+#define NRFX_QDEC_CONFIG_PIO_LED 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_LEDPRE - LED pre 
+#ifndef NRFX_QDEC_CONFIG_LEDPRE
+#define NRFX_QDEC_CONFIG_LEDPRE 511
+#endif
+
+// <o> NRFX_QDEC_CONFIG_LEDPOL  - LED polarity
+ 
+// <0=> Active low 
+// <1=> Active high 
+
+#ifndef NRFX_QDEC_CONFIG_LEDPOL
+#define NRFX_QDEC_CONFIG_LEDPOL 1
+#endif
+
+// <q> NRFX_QDEC_CONFIG_DBFEN  - Debouncing enable
+ 
+
+#ifndef NRFX_QDEC_CONFIG_DBFEN
+#define NRFX_QDEC_CONFIG_DBFEN 0
+#endif
+
+// <q> NRFX_QDEC_CONFIG_SAMPLE_INTEN  - Sample ready interrupt enable
+ 
+
+#ifndef NRFX_QDEC_CONFIG_SAMPLE_INTEN
+#define NRFX_QDEC_CONFIG_SAMPLE_INTEN 0
+#endif
+
+// <o> NRFX_QDEC_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_CONFIG_IRQ_PRIORITY
+#define NRFX_QDEC_CONFIG_IRQ_PRIORITY 6
+#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_RNG_ENABLED - nrfx_rng - RNG peripheral driver
+//==========================================================
+#ifndef NRFX_RNG_ENABLED
+#define NRFX_RNG_ENABLED 0
+#endif
+// <q> NRFX_RNG_CONFIG_ERROR_CORRECTION  - Error correction
+ 
+
+#ifndef NRFX_RNG_CONFIG_ERROR_CORRECTION
+#define NRFX_RNG_CONFIG_ERROR_CORRECTION 1
+#endif
+
+// <o> NRFX_RNG_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef NRFX_RNG_CONFIG_IRQ_PRIORITY
+#define NRFX_RNG_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_RNG_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_RNG_CONFIG_LOG_ENABLED
+#define NRFX_RNG_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_RNG_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_RNG_CONFIG_LOG_LEVEL
+#define NRFX_RNG_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_RNG_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_RNG_CONFIG_INFO_COLOR
+#define NRFX_RNG_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_RNG_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_RNG_CONFIG_DEBUG_COLOR
+#define NRFX_RNG_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_RTC_ENABLED - nrfx_rtc - RTC peripheral driver
+//==========================================================
+#ifndef NRFX_RTC_ENABLED
+#define NRFX_RTC_ENABLED 0
+#endif
+// <q> NRFX_RTC0_ENABLED  - Enable RTC0 instance
+ 
+
+#ifndef NRFX_RTC0_ENABLED
+#define NRFX_RTC0_ENABLED 0
+#endif
+
+// <q> NRFX_RTC1_ENABLED  - Enable RTC1 instance
+ 
+
+#ifndef NRFX_RTC1_ENABLED
+#define NRFX_RTC1_ENABLED 0
+#endif
+
+// <o> NRFX_RTC_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt 
+#ifndef NRFX_RTC_MAXIMUM_LATENCY_US
+#define NRFX_RTC_MAXIMUM_LATENCY_US 2000
+#endif
+
+// <o> NRFX_RTC_DEFAULT_CONFIG_FREQUENCY - Frequency  <16-32768> 
+
+
+#ifndef NRFX_RTC_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_RTC_DEFAULT_CONFIG_FREQUENCY 32768
+#endif
+
+// <q> NRFX_RTC_DEFAULT_CONFIG_RELIABLE  - Ensures safe compare event triggering
+ 
+
+#ifndef NRFX_RTC_DEFAULT_CONFIG_RELIABLE
+#define NRFX_RTC_DEFAULT_CONFIG_RELIABLE 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 6
+#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_CONFIG_RESOLUTION  - Resolution
+ 
+// <0=> 8 bit 
+// <1=> 10 bit 
+// <2=> 12 bit 
+// <3=> 14 bit 
+
+#ifndef NRFX_SAADC_CONFIG_RESOLUTION
+#define NRFX_SAADC_CONFIG_RESOLUTION 1
+#endif
+
+// <o> NRFX_SAADC_CONFIG_OVERSAMPLE  - Sample period
+ 
+// <0=> Disabled 
+// <1=> 2x 
+// <2=> 4x 
+// <3=> 8x 
+// <4=> 16x 
+// <5=> 32x 
+// <6=> 64x 
+// <7=> 128x 
+// <8=> 256x 
+
+#ifndef NRFX_SAADC_CONFIG_OVERSAMPLE
+#define NRFX_SAADC_CONFIG_OVERSAMPLE 0
+#endif
+
+// <q> NRFX_SAADC_CONFIG_LP_MODE  - Enabling low power mode
+ 
+
+#ifndef NRFX_SAADC_CONFIG_LP_MODE
+#define NRFX_SAADC_CONFIG_LP_MODE 0
+#endif
+
+// <o> NRFX_SAADC_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_CONFIG_IRQ_PRIORITY
+#define NRFX_SAADC_CONFIG_IRQ_PRIORITY 6
+#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  - Enable SPIM0 instance
+ 
+
+#ifndef NRFX_SPIM0_ENABLED
+#define NRFX_SPIM0_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM1_ENABLED  - Enable SPIM1 instance
+ 
+
+#ifndef NRFX_SPIM1_ENABLED
+#define NRFX_SPIM1_ENABLED 0
+#endif
+
+// <o> NRFX_SPIM_MISO_PULL_CFG  - MISO pin pull configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRFX_SPIM_MISO_PULL_CFG
+#define NRFX_SPIM_MISO_PULL_CFG 1
+#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 6
+#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  - Enable SPIS0 instance
+ 
+
+#ifndef NRFX_SPIS0_ENABLED
+#define NRFX_SPIS0_ENABLED 0
+#endif
+
+// <q> NRFX_SPIS1_ENABLED  - Enable SPIS1 instance
+ 
+
+#ifndef NRFX_SPIS1_ENABLED
+#define NRFX_SPIS1_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 6
+#endif
+
+// <o> NRFX_SPIS_DEFAULT_DEF - SPIS default DEF character  <0-255> 
+
+
+#ifndef NRFX_SPIS_DEFAULT_DEF
+#define NRFX_SPIS_DEFAULT_DEF 255
+#endif
+
+// <o> NRFX_SPIS_DEFAULT_ORC - SPIS default ORC character  <0-255> 
+
+
+#ifndef NRFX_SPIS_DEFAULT_ORC
+#define NRFX_SPIS_DEFAULT_ORC 255
+#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>
+
+// <e> NRFX_SPI_ENABLED - nrfx_spi - SPI peripheral driver
+//==========================================================
+#ifndef NRFX_SPI_ENABLED
+#define NRFX_SPI_ENABLED 0
+#endif
+// <q> NRFX_SPI0_ENABLED  - Enable SPI0 instance
+ 
+
+#ifndef NRFX_SPI0_ENABLED
+#define NRFX_SPI0_ENABLED 0
+#endif
+
+// <q> NRFX_SPI1_ENABLED  - Enable SPI1 instance
+ 
+
+#ifndef NRFX_SPI1_ENABLED
+#define NRFX_SPI1_ENABLED 0
+#endif
+
+// <o> NRFX_SPI_MISO_PULL_CFG  - MISO pin pull configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRFX_SPI_MISO_PULL_CFG
+#define NRFX_SPI_MISO_PULL_CFG 1
+#endif
+
+// <o> NRFX_SPI_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_SPI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_SPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SPI_CONFIG_LOG_ENABLED
+#define NRFX_SPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_SPI_CONFIG_LOG_LEVEL
+#define NRFX_SPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SPI_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_SPI_CONFIG_INFO_COLOR
+#define NRFX_SPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SPI_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_SPI_CONFIG_DEBUG_COLOR
+#define NRFX_SPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_SWI_ENABLED - nrfx_swi - SWI/EGU peripheral allocator
+//==========================================================
+#ifndef NRFX_SWI_ENABLED
+#define NRFX_SWI_ENABLED 0
+#endif
+// <q> NRFX_EGU_ENABLED  - Enable EGU support
+ 
+
+#ifndef NRFX_EGU_ENABLED
+#define NRFX_EGU_ENABLED 0
+#endif
+
+// <q> NRFX_SWI0_DISABLED  - Exclude SWI0 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI0_DISABLED
+#define NRFX_SWI0_DISABLED 0
+#endif
+
+// <q> NRFX_SWI1_DISABLED  - Exclude SWI1 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI1_DISABLED
+#define NRFX_SWI1_DISABLED 0
+#endif
+
+// <q> NRFX_SWI2_DISABLED  - Exclude SWI2 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI2_DISABLED
+#define NRFX_SWI2_DISABLED 0
+#endif
+
+// <q> NRFX_SWI3_DISABLED  - Exclude SWI3 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI3_DISABLED
+#define NRFX_SWI3_DISABLED 0
+#endif
+
+// <q> NRFX_SWI4_DISABLED  - Exclude SWI4 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI4_DISABLED
+#define NRFX_SWI4_DISABLED 0
+#endif
+
+// <q> NRFX_SWI5_DISABLED  - Exclude SWI5 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI5_DISABLED
+#define NRFX_SWI5_DISABLED 0
+#endif
+
+// <e> NRFX_SWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SWI_CONFIG_LOG_ENABLED
+#define NRFX_SWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_SWI_CONFIG_LOG_LEVEL
+#define NRFX_SWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SWI_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_SWI_CONFIG_INFO_COLOR
+#define NRFX_SWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SWI_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_SWI_CONFIG_DEBUG_COLOR
+#define NRFX_SWI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_TIMER_ENABLED - nrfx_timer - TIMER periperal driver
+//==========================================================
+#ifndef NRFX_TIMER_ENABLED
+#define NRFX_TIMER_ENABLED 0
+#endif
+// <q> NRFX_TIMER0_ENABLED  - Enable TIMER0 instance
+ 
+
+#ifndef NRFX_TIMER0_ENABLED
+#define NRFX_TIMER0_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER1_ENABLED  - Enable TIMER1 instance
+ 
+
+#ifndef NRFX_TIMER1_ENABLED
+#define NRFX_TIMER1_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER2_ENABLED  - Enable TIMER2 instance
+ 
+
+#ifndef NRFX_TIMER2_ENABLED
+#define NRFX_TIMER2_ENABLED 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY  - Timer frequency if in Timer mode
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+// <8=> 62.5 kHz 
+// <9=> 31.25 kHz 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_MODE  - Timer mode or operation
+ 
+// <0=> Timer 
+// <1=> Counter 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_MODE
+#define NRFX_TIMER_DEFAULT_CONFIG_MODE 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH  - Timer counter bit width
+ 
+// <0=> 16 bit 
+// <1=> 8 bit 
+// <2=> 24 bit 
+// <3=> 32 bit 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH
+#define NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH 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 6
+#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  - Enable TWIM0 instance
+ 
+
+#ifndef NRFX_TWIM0_ENABLED
+#define NRFX_TWIM0_ENABLED 0
+#endif
+
+// <o> NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT 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 6
+#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  - Enable TWIS0 instance
+ 
+
+#ifndef NRFX_TWIS0_ENABLED
+#define NRFX_TWIS0_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY  - Assume 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  - Remove 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_ADDR0 - Address0 
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR0
+#define NRFX_TWIS_DEFAULT_CONFIG_ADDR0 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_ADDR1 - Address1 
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR1
+#define NRFX_TWIS_DEFAULT_CONFIG_ADDR1 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL  - SCL pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL
+#define NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL  - SDA pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL
+#define NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL 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 6
+#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_TWI_ENABLED - nrfx_twi - TWI peripheral driver
+//==========================================================
+#ifndef NRFX_TWI_ENABLED
+#define NRFX_TWI_ENABLED 0
+#endif
+// <q> NRFX_TWI0_ENABLED  - Enable TWI0 instance
+ 
+
+#ifndef NRFX_TWI0_ENABLED
+#define NRFX_TWI0_ENABLED 0
+#endif
+
+// <o> NRFX_TWI_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef NRFX_TWI_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TWI_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
+#endif
+
+// <o> NRFX_TWI_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_TWI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_TWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_TWI_CONFIG_LOG_ENABLED
+#define NRFX_TWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_TWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_TWI_CONFIG_LOG_LEVEL
+#define NRFX_TWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_TWI_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_TWI_CONFIG_INFO_COLOR
+#define NRFX_TWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_TWI_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_TWI_CONFIG_DEBUG_COLOR
+#define NRFX_TWI_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 - Enable UARTE0 instance 
+#ifndef NRFX_UARTE0_ENABLED
+#define NRFX_UARTE0_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_HWFC
+#define NRFX_UARTE_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_PARITY
+#define NRFX_UARTE_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <8388608=> 31250 baud 
+// <10289152=> 38400 baud 
+// <15007744=> 56000 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE
+#define NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE 30801920
+#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 6
+#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_UART_ENABLED - nrfx_uart - UART peripheral driver
+//==========================================================
+#ifndef NRFX_UART_ENABLED
+#define NRFX_UART_ENABLED 0
+#endif
+// <o> NRFX_UART0_ENABLED - Enable UART0 instance 
+#ifndef NRFX_UART0_ENABLED
+#define NRFX_UART0_ENABLED 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_HWFC
+#define NRFX_UART_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_PARITY
+#define NRFX_UART_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3866624=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7729152=> 28800 baud 
+// <8388608=> 31250 baud 
+// <10309632=> 38400 baud 
+// <15007744=> 56000 baud 
+// <15462400=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30924800=> 115200 baud 
+// <61845504=> 230400 baud 
+// <67108864=> 250000 baud 
+// <123695104=> 460800 baud 
+// <247386112=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_BAUDRATE
+#define NRFX_UART_DEFAULT_CONFIG_BAUDRATE 30924800
+#endif
+
+// <o> NRFX_UART_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_UART_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_UART_CONFIG_LOG_ENABLED
+#define NRFX_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_UART_CONFIG_LOG_LEVEL
+#define NRFX_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_UART_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_UART_CONFIG_INFO_COLOR
+#define NRFX_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_UART_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_UART_CONFIG_DEBUG_COLOR
+#define NRFX_UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_WDT_ENABLED - nrfx_wdt - WDT peripheral driver
+//==========================================================
+#ifndef NRFX_WDT_ENABLED
+#define NRFX_WDT_ENABLED 0
+#endif
+// <o> NRFX_WDT_CONFIG_BEHAVIOUR  - WDT behavior in CPU SLEEP or HALT mode
+ 
+// <1=> Run in SLEEP, Pause in HALT 
+// <8=> Pause in SLEEP, Run in HALT 
+// <9=> Run in SLEEP and HALT 
+// <0=> Pause in SLEEP and HALT 
+
+#ifndef NRFX_WDT_CONFIG_BEHAVIOUR
+#define NRFX_WDT_CONFIG_BEHAVIOUR 1
+#endif
+
+// <o> NRFX_WDT_CONFIG_RELOAD_VALUE - Reload value  <15-4294967295> 
+
+
+#ifndef NRFX_WDT_CONFIG_RELOAD_VALUE
+#define NRFX_WDT_CONFIG_RELOAD_VALUE 2000
+#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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_WDT_CONFIG_IRQ_PRIORITY 6
+#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>
+
+// <e> NRF_CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver - legacy layer
+//==========================================================
+#ifndef NRF_CLOCK_ENABLED
+#define NRF_CLOCK_ENABLED 0
+#endif
+// <o> CLOCK_CONFIG_LF_SRC  - LF Clock Source
+ 
+// <0=> RC 
+// <1=> XTAL 
+// <2=> Synth 
+// <131073=> External Low Swing 
+// <196609=> External Full Swing 
+
+#ifndef CLOCK_CONFIG_LF_SRC
+#define CLOCK_CONFIG_LF_SRC 1
+#endif
+
+// <q> CLOCK_CONFIG_LF_CAL_ENABLED  - Calibration enable for LF Clock Source
+ 
+
+#ifndef CLOCK_CONFIG_LF_CAL_ENABLED
+#define CLOCK_CONFIG_LF_CAL_ENABLED 0
+#endif
+
+// <o> CLOCK_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef CLOCK_CONFIG_IRQ_PRIORITY
+#define CLOCK_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> PDM_ENABLED - nrf_drv_pdm - PDM peripheral driver - legacy layer
+//==========================================================
+#ifndef PDM_ENABLED
+#define PDM_ENABLED 0
+#endif
+// <o> PDM_CONFIG_MODE  - Mode
+ 
+// <0=> Stereo 
+// <1=> Mono 
+
+#ifndef PDM_CONFIG_MODE
+#define PDM_CONFIG_MODE 1
+#endif
+
+// <o> PDM_CONFIG_EDGE  - Edge
+ 
+// <0=> Left falling 
+// <1=> Left rising 
+
+#ifndef PDM_CONFIG_EDGE
+#define PDM_CONFIG_EDGE 0
+#endif
+
+// <o> PDM_CONFIG_CLOCK_FREQ  - Clock frequency
+ 
+// <134217728=> 1000k 
+// <138412032=> 1032k (default) 
+// <142606336=> 1067k 
+
+#ifndef PDM_CONFIG_CLOCK_FREQ
+#define PDM_CONFIG_CLOCK_FREQ 138412032
+#endif
+
+// <o> PDM_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef PDM_CONFIG_IRQ_PRIORITY
+#define PDM_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> POWER_ENABLED - nrf_drv_power - POWER peripheral driver - legacy layer
+//==========================================================
+#ifndef POWER_ENABLED
+#define POWER_ENABLED 1
+#endif
+// <o> POWER_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef POWER_CONFIG_IRQ_PRIORITY
+#define POWER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef POWER_CONFIG_DEFAULT_DCDCEN
+#define POWER_CONFIG_DEFAULT_DCDCEN 0
+#endif
+
+// <q> POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef POWER_CONFIG_DEFAULT_DCDCENHV
+#define POWER_CONFIG_DEFAULT_DCDCENHV 0
+#endif
+
+// </e>
+
+// <q> PPI_ENABLED  - nrf_drv_ppi - PPI peripheral driver - legacy layer
+ 
+
+#ifndef PPI_ENABLED
+#define PPI_ENABLED 0
+#endif
+
+// <e> PWM_ENABLED - nrf_drv_pwm - PWM peripheral driver - legacy layer
+//==========================================================
+#ifndef PWM_ENABLED
+#define PWM_ENABLED 0
+#endif
+// <o> PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT0_PIN
+#define PWM_DEFAULT_CONFIG_OUT0_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT1_PIN
+#define PWM_DEFAULT_CONFIG_OUT1_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT2_PIN
+#define PWM_DEFAULT_CONFIG_OUT2_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT3_PIN
+#define PWM_DEFAULT_CONFIG_OUT3_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_BASE_CLOCK  - Base clock
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+
+#ifndef PWM_DEFAULT_CONFIG_BASE_CLOCK
+#define PWM_DEFAULT_CONFIG_BASE_CLOCK 4
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_COUNT_MODE  - Count mode
+ 
+// <0=> Up 
+// <1=> Up and Down 
+
+#ifndef PWM_DEFAULT_CONFIG_COUNT_MODE
+#define PWM_DEFAULT_CONFIG_COUNT_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_TOP_VALUE - Top value 
+#ifndef PWM_DEFAULT_CONFIG_TOP_VALUE
+#define PWM_DEFAULT_CONFIG_TOP_VALUE 1000
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_LOAD_MODE  - Load mode
+ 
+// <0=> Common 
+// <1=> Grouped 
+// <2=> Individual 
+// <3=> Waveform 
+
+#ifndef PWM_DEFAULT_CONFIG_LOAD_MODE
+#define PWM_DEFAULT_CONFIG_LOAD_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_STEP_MODE  - Step mode
+ 
+// <0=> Auto 
+// <1=> Triggered 
+
+#ifndef PWM_DEFAULT_CONFIG_STEP_MODE
+#define PWM_DEFAULT_CONFIG_STEP_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef PWM_DEFAULT_CONFIG_IRQ_PRIORITY
+#define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> PWM0_ENABLED  - Enable PWM0 instance
+ 
+
+#ifndef PWM0_ENABLED
+#define PWM0_ENABLED 0
+#endif
+
+// <q> PWM1_ENABLED  - Enable PWM1 instance
+ 
+
+#ifndef PWM1_ENABLED
+#define PWM1_ENABLED 0
+#endif
+
+// <q> PWM2_ENABLED  - Enable PWM2 instance
+ 
+
+#ifndef PWM2_ENABLED
+#define PWM2_ENABLED 0
+#endif
+
+// </e>
+
+// <e> QDEC_ENABLED - nrf_drv_qdec - QDEC peripheral driver - legacy layer
+//==========================================================
+#ifndef QDEC_ENABLED
+#define QDEC_ENABLED 0
+#endif
+// <o> QDEC_CONFIG_REPORTPER  - Report period
+ 
+// <0=> 10 Samples 
+// <1=> 40 Samples 
+// <2=> 80 Samples 
+// <3=> 120 Samples 
+// <4=> 160 Samples 
+// <5=> 200 Samples 
+// <6=> 240 Samples 
+// <7=> 280 Samples 
+
+#ifndef QDEC_CONFIG_REPORTPER
+#define QDEC_CONFIG_REPORTPER 0
+#endif
+
+// <o> QDEC_CONFIG_SAMPLEPER  - Sample period
+ 
+// <0=> 128 us 
+// <1=> 256 us 
+// <2=> 512 us 
+// <3=> 1024 us 
+// <4=> 2048 us 
+// <5=> 4096 us 
+// <6=> 8192 us 
+// <7=> 16384 us 
+
+#ifndef QDEC_CONFIG_SAMPLEPER
+#define QDEC_CONFIG_SAMPLEPER 7
+#endif
+
+// <o> QDEC_CONFIG_PIO_A - A pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_A
+#define QDEC_CONFIG_PIO_A 31
+#endif
+
+// <o> QDEC_CONFIG_PIO_B - B pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_B
+#define QDEC_CONFIG_PIO_B 31
+#endif
+
+// <o> QDEC_CONFIG_PIO_LED - LED pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_LED
+#define QDEC_CONFIG_PIO_LED 31
+#endif
+
+// <o> QDEC_CONFIG_LEDPRE - LED pre 
+#ifndef QDEC_CONFIG_LEDPRE
+#define QDEC_CONFIG_LEDPRE 511
+#endif
+
+// <o> QDEC_CONFIG_LEDPOL  - LED polarity
+ 
+// <0=> Active low 
+// <1=> Active high 
+
+#ifndef QDEC_CONFIG_LEDPOL
+#define QDEC_CONFIG_LEDPOL 1
+#endif
+
+// <q> QDEC_CONFIG_DBFEN  - Debouncing enable
+ 
+
+#ifndef QDEC_CONFIG_DBFEN
+#define QDEC_CONFIG_DBFEN 0
+#endif
+
+// <q> QDEC_CONFIG_SAMPLE_INTEN  - Sample ready interrupt enable
+ 
+
+#ifndef QDEC_CONFIG_SAMPLE_INTEN
+#define QDEC_CONFIG_SAMPLE_INTEN 0
+#endif
+
+// <o> QDEC_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef QDEC_CONFIG_IRQ_PRIORITY
+#define QDEC_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> QSPI_ENABLED - nrf_drv_qspi - QSPI peripheral driver - legacy layer
+//==========================================================
+#ifndef QSPI_ENABLED
+#define QSPI_ENABLED 0
+#endif
+// <o> QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).  <0-255> 
+
+
+#ifndef QSPI_CONFIG_SCK_DELAY
+#define QSPI_CONFIG_SCK_DELAY 1
+#endif
+
+// <o> QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation. 
+#ifndef QSPI_CONFIG_XIP_OFFSET
+#define QSPI_CONFIG_XIP_OFFSET 0
+#endif
+
+// <o> QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
+ 
+// <0=> FastRead 
+// <1=> Read2O 
+// <2=> Read2IO 
+// <3=> Read4O 
+// <4=> Read4IO 
+
+#ifndef QSPI_CONFIG_READOC
+#define QSPI_CONFIG_READOC 0
+#endif
+
+// <o> QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
+ 
+// <0=> PP 
+// <1=> PP2O 
+// <2=> PP4O 
+// <3=> PP4IO 
+
+#ifndef QSPI_CONFIG_WRITEOC
+#define QSPI_CONFIG_WRITEOC 0
+#endif
+
+// <o> QSPI_CONFIG_ADDRMODE  - Addressing mode.
+ 
+// <0=> 24bit 
+// <1=> 32bit 
+
+#ifndef QSPI_CONFIG_ADDRMODE
+#define QSPI_CONFIG_ADDRMODE 0
+#endif
+
+// <o> QSPI_CONFIG_MODE  - SPI mode.
+ 
+// <0=> Mode 0 
+// <1=> Mode 1 
+
+#ifndef QSPI_CONFIG_MODE
+#define QSPI_CONFIG_MODE 0
+#endif
+
+// <o> QSPI_CONFIG_FREQUENCY  - Frequency divider.
+ 
+// <0=> 32MHz/1 
+// <1=> 32MHz/2 
+// <2=> 32MHz/3 
+// <3=> 32MHz/4 
+// <4=> 32MHz/5 
+// <5=> 32MHz/6 
+// <6=> 32MHz/7 
+// <7=> 32MHz/8 
+// <8=> 32MHz/9 
+// <9=> 32MHz/10 
+// <10=> 32MHz/11 
+// <11=> 32MHz/12 
+// <12=> 32MHz/13 
+// <13=> 32MHz/14 
+// <14=> 32MHz/15 
+// <15=> 32MHz/16 
+
+#ifndef QSPI_CONFIG_FREQUENCY
+#define QSPI_CONFIG_FREQUENCY 15
+#endif
+
+// <s> QSPI_PIN_SCK - SCK pin value.
+#ifndef QSPI_PIN_SCK
+#define QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_CSN - CSN pin value.
+#ifndef QSPI_PIN_CSN
+#define QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO0 - IO0 pin value.
+#ifndef QSPI_PIN_IO0
+#define QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO1 - IO1 pin value.
+#ifndef QSPI_PIN_IO1
+#define QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO2 - IO2 pin value.
+#ifndef QSPI_PIN_IO2
+#define QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO3 - IO3 pin value.
+#ifndef QSPI_PIN_IO3
+#define QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <o> QSPI_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef QSPI_CONFIG_IRQ_PRIORITY
+#define QSPI_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> RNG_ENABLED - nrf_drv_rng - RNG peripheral driver - legacy layer
+//==========================================================
+#ifndef RNG_ENABLED
+#define RNG_ENABLED 0
+#endif
+// <q> RNG_CONFIG_ERROR_CORRECTION  - Error correction
+ 
+
+#ifndef RNG_CONFIG_ERROR_CORRECTION
+#define RNG_CONFIG_ERROR_CORRECTION 1
+#endif
+
+// <o> RNG_CONFIG_POOL_SIZE - Pool size 
+#ifndef RNG_CONFIG_POOL_SIZE
+#define RNG_CONFIG_POOL_SIZE 64
+#endif
+
+// <o> RNG_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef RNG_CONFIG_IRQ_PRIORITY
+#define RNG_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> RTC_ENABLED - nrf_drv_rtc - RTC peripheral driver - legacy layer
+//==========================================================
+#ifndef RTC_ENABLED
+#define RTC_ENABLED 0
+#endif
+// <o> RTC_DEFAULT_CONFIG_FREQUENCY - Frequency  <16-32768> 
+
+
+#ifndef RTC_DEFAULT_CONFIG_FREQUENCY
+#define RTC_DEFAULT_CONFIG_FREQUENCY 32768
+#endif
+
+// <q> RTC_DEFAULT_CONFIG_RELIABLE  - Ensures safe compare event triggering
+ 
+
+#ifndef RTC_DEFAULT_CONFIG_RELIABLE
+#define RTC_DEFAULT_CONFIG_RELIABLE 0
+#endif
+
+// <o> RTC_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef RTC_DEFAULT_CONFIG_IRQ_PRIORITY
+#define RTC_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> RTC0_ENABLED  - Enable RTC0 instance
+ 
+
+#ifndef RTC0_ENABLED
+#define RTC0_ENABLED 0
+#endif
+
+// <q> RTC1_ENABLED  - Enable RTC1 instance
+ 
+
+#ifndef RTC1_ENABLED
+#define RTC1_ENABLED 0
+#endif
+
+// <q> RTC2_ENABLED  - Enable RTC2 instance
+ 
+
+#ifndef RTC2_ENABLED
+#define RTC2_ENABLED 0
+#endif
+
+// <o> NRF_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt 
+#ifndef NRF_MAXIMUM_LATENCY_US
+#define NRF_MAXIMUM_LATENCY_US 2000
+#endif
+
+// </e>
+
+// <e> SAADC_ENABLED - nrf_drv_saadc - SAADC peripheral driver - legacy layer
+//==========================================================
+#ifndef SAADC_ENABLED
+#define SAADC_ENABLED 0
+#endif
+// <o> SAADC_CONFIG_RESOLUTION  - Resolution
+ 
+// <0=> 8 bit 
+// <1=> 10 bit 
+// <2=> 12 bit 
+// <3=> 14 bit 
+
+#ifndef SAADC_CONFIG_RESOLUTION
+#define SAADC_CONFIG_RESOLUTION 1
+#endif
+
+// <o> SAADC_CONFIG_OVERSAMPLE  - Sample period
+ 
+// <0=> Disabled 
+// <1=> 2x 
+// <2=> 4x 
+// <3=> 8x 
+// <4=> 16x 
+// <5=> 32x 
+// <6=> 64x 
+// <7=> 128x 
+// <8=> 256x 
+
+#ifndef SAADC_CONFIG_OVERSAMPLE
+#define SAADC_CONFIG_OVERSAMPLE 0
+#endif
+
+// <q> SAADC_CONFIG_LP_MODE  - Enabling low power mode
+ 
+
+#ifndef SAADC_CONFIG_LP_MODE
+#define SAADC_CONFIG_LP_MODE 0
+#endif
+
+// <o> SAADC_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SAADC_CONFIG_IRQ_PRIORITY
+#define SAADC_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> SPIS_ENABLED - nrf_drv_spis - SPIS peripheral driver - legacy layer
+//==========================================================
+#ifndef SPIS_ENABLED
+#define SPIS_ENABLED 0
+#endif
+// <o> SPIS_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SPIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> SPIS_DEFAULT_MODE  - Mode
+ 
+// <0=> MODE_0 
+// <1=> MODE_1 
+// <2=> MODE_2 
+// <3=> MODE_3 
+
+#ifndef SPIS_DEFAULT_MODE
+#define SPIS_DEFAULT_MODE 0
+#endif
+
+// <o> SPIS_DEFAULT_BIT_ORDER  - SPIS default bit order
+ 
+// <0=> MSB first 
+// <1=> LSB first 
+
+#ifndef SPIS_DEFAULT_BIT_ORDER
+#define SPIS_DEFAULT_BIT_ORDER 0
+#endif
+
+// <o> SPIS_DEFAULT_DEF - SPIS default DEF character  <0-255> 
+
+
+#ifndef SPIS_DEFAULT_DEF
+#define SPIS_DEFAULT_DEF 255
+#endif
+
+// <o> SPIS_DEFAULT_ORC - SPIS default ORC character  <0-255> 
+
+
+#ifndef SPIS_DEFAULT_ORC
+#define SPIS_DEFAULT_ORC 255
+#endif
+
+// <q> SPIS0_ENABLED  - Enable SPIS0 instance
+ 
+
+#ifndef SPIS0_ENABLED
+#define SPIS0_ENABLED 0
+#endif
+
+// <q> SPIS1_ENABLED  - Enable SPIS1 instance
+ 
+
+#ifndef SPIS1_ENABLED
+#define SPIS1_ENABLED 0
+#endif
+
+// </e>
+
+// <e> SPI_ENABLED - nrf_drv_spi - SPI/SPIM peripheral driver - legacy layer
+//==========================================================
+#ifndef SPI_ENABLED
+#define SPI_ENABLED 0
+#endif
+// <o> SPI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SPI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> NRF_SPI_DRV_MISO_PULLUP_CFG  - MISO PIN pull-up configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRF_SPI_DRV_MISO_PULLUP_CFG
+#define NRF_SPI_DRV_MISO_PULLUP_CFG 1
+#endif
+
+// <e> SPI0_ENABLED - Enable SPI0 instance
+//==========================================================
+#ifndef SPI0_ENABLED
+#define SPI0_ENABLED 0
+#endif
+// <q> SPI0_USE_EASY_DMA  - Use EasyDMA
+ 
+
+#ifndef SPI0_USE_EASY_DMA
+#define SPI0_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// <e> SPI1_ENABLED - Enable SPI1 instance
+//==========================================================
+#ifndef SPI1_ENABLED
+#define SPI1_ENABLED 0
+#endif
+// <q> SPI1_USE_EASY_DMA  - Use EasyDMA
+ 
+
+#ifndef SPI1_USE_EASY_DMA
+#define SPI1_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// </e>
+
+// <e> TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver - legacy layer
+//==========================================================
+#ifndef TIMER_ENABLED
+#define TIMER_ENABLED 0
+#endif
+// <o> TIMER_DEFAULT_CONFIG_FREQUENCY  - Timer frequency if in Timer mode
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+// <8=> 62.5 kHz 
+// <9=> 31.25 kHz 
+
+#ifndef TIMER_DEFAULT_CONFIG_FREQUENCY
+#define TIMER_DEFAULT_CONFIG_FREQUENCY 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_MODE  - Timer mode or operation
+ 
+// <0=> Timer 
+// <1=> Counter 
+
+#ifndef TIMER_DEFAULT_CONFIG_MODE
+#define TIMER_DEFAULT_CONFIG_MODE 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_BIT_WIDTH  - Timer counter bit width
+ 
+// <0=> 16 bit 
+// <1=> 8 bit 
+// <2=> 24 bit 
+// <3=> 32 bit 
+
+#ifndef TIMER_DEFAULT_CONFIG_BIT_WIDTH
+#define TIMER_DEFAULT_CONFIG_BIT_WIDTH 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> TIMER0_ENABLED  - Enable TIMER0 instance
+ 
+
+#ifndef TIMER0_ENABLED
+#define TIMER0_ENABLED 0
+#endif
+
+// <q> TIMER1_ENABLED  - Enable TIMER1 instance
+ 
+
+#ifndef TIMER1_ENABLED
+#define TIMER1_ENABLED 0
+#endif
+
+// <q> TIMER2_ENABLED  - Enable TIMER2 instance
+ 
+
+#ifndef TIMER2_ENABLED
+#define TIMER2_ENABLED 0
+#endif
+
+// <q> TIMER3_ENABLED  - Enable TIMER3 instance
+ 
+
+#ifndef TIMER3_ENABLED
+#define TIMER3_ENABLED 0
+#endif
+
+// <q> TIMER4_ENABLED  - Enable TIMER4 instance
+ 
+
+#ifndef TIMER4_ENABLED
+#define TIMER4_ENABLED 0
+#endif
+
+// </e>
+
+// <e> TWIS_ENABLED - nrf_drv_twis - TWIS peripheral driver - legacy layer
+//==========================================================
+#ifndef TWIS_ENABLED
+#define TWIS_ENABLED 0
+#endif
+// <q> TWIS0_ENABLED  - Enable TWIS0 instance
+ 
+
+#ifndef TWIS0_ENABLED
+#define TWIS0_ENABLED 0
+#endif
+
+// <q> TWIS1_ENABLED  - Enable TWIS1 instance
+ 
+
+#ifndef TWIS1_ENABLED
+#define TWIS1_ENABLED 0
+#endif
+
+// <q> TWIS_ASSUME_INIT_AFTER_RESET_ONLY  - Assume 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 TWIS_ASSUME_INIT_AFTER_RESET_ONLY
+#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0
+#endif
+
+// <q> TWIS_NO_SYNC_MODE  - Remove 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 TWIS_NO_SYNC_MODE
+#define TWIS_NO_SYNC_MODE 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_ADDR0 - Address0 
+#ifndef TWIS_DEFAULT_CONFIG_ADDR0
+#define TWIS_DEFAULT_CONFIG_ADDR0 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_ADDR1 - Address1 
+#ifndef TWIS_DEFAULT_CONFIG_ADDR1
+#define TWIS_DEFAULT_CONFIG_ADDR1 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_SCL_PULL  - SCL pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef TWIS_DEFAULT_CONFIG_SCL_PULL
+#define TWIS_DEFAULT_CONFIG_SCL_PULL 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_SDA_PULL  - SDA pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef TWIS_DEFAULT_CONFIG_SDA_PULL
+#define TWIS_DEFAULT_CONFIG_SDA_PULL 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TWIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver - legacy layer
+//==========================================================
+#ifndef TWI_ENABLED
+#define TWI_ENABLED 0
+#endif
+// <o> TWI_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef TWI_DEFAULT_CONFIG_FREQUENCY
+#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> TWI_DEFAULT_CONFIG_CLR_BUS_INIT  - Enables bus clearing procedure during init
+ 
+
+#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT
+#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0
+#endif
+
+// <q> TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
+#endif
+
+// <o> TWI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> TWI0_ENABLED - Enable TWI0 instance
+//==========================================================
+#ifndef TWI0_ENABLED
+#define TWI0_ENABLED 0
+#endif
+// <q> TWI0_USE_EASY_DMA  - Use EasyDMA (if present)
+ 
+
+#ifndef TWI0_USE_EASY_DMA
+#define TWI0_USE_EASY_DMA 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
+//==========================================================
+#ifndef UART_ENABLED
+#define UART_ENABLED 0
+#endif
+// <o> UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef UART_DEFAULT_CONFIG_HWFC
+#define UART_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> UART_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef UART_DEFAULT_CONFIG_PARITY
+#define UART_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <10289152=> 38400 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef UART_DEFAULT_CONFIG_BAUDRATE
+#define UART_DEFAULT_CONFIG_BAUDRATE 30801920
+#endif
+
+// <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY
+#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> UART_EASY_DMA_SUPPORT  - Driver supporting EasyDMA
+ 
+
+#ifndef UART_EASY_DMA_SUPPORT
+#define UART_EASY_DMA_SUPPORT 1
+#endif
+
+// <q> UART_LEGACY_SUPPORT  - Driver supporting Legacy mode
+ 
+
+#ifndef UART_LEGACY_SUPPORT
+#define UART_LEGACY_SUPPORT 1
+#endif
+
+// <e> UART0_ENABLED - Enable UART0 instance
+//==========================================================
+#ifndef UART0_ENABLED
+#define UART0_ENABLED 0
+#endif
+// <q> UART0_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA
+ 
+
+#ifndef UART0_CONFIG_USE_EASY_DMA
+#define UART0_CONFIG_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// </e>
+
+// <e> USBD_ENABLED - nrf_drv_usbd - Software Component
+//==========================================================
+#ifndef USBD_ENABLED
+#define USBD_ENABLED 0
+#endif
+// <o> USBD_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef USBD_CONFIG_IRQ_PRIORITY
+#define USBD_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> USBD_CONFIG_DMASCHEDULER_MODE  - USBD SMA scheduler working scheme
+ 
+// <0=> Prioritized access 
+// <1=> Round Robin 
+
+#ifndef USBD_CONFIG_DMASCHEDULER_MODE
+#define USBD_CONFIG_DMASCHEDULER_MODE 0
+#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 USBD_CONFIG_DMASCHEDULER_ISO_BOOST
+#define 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.
+// <i> NOTE: This option does not work on Engineering A chip.
+
+#ifndef USBD_CONFIG_ISO_IN_ZLP
+#define USBD_CONFIG_ISO_IN_ZLP 0
+#endif
+
+// </e>
+
+// <e> WDT_ENABLED - nrf_drv_wdt - WDT peripheral driver - legacy layer
+//==========================================================
+#ifndef WDT_ENABLED
+#define WDT_ENABLED 0
+#endif
+// <o> WDT_CONFIG_BEHAVIOUR  - WDT behavior in CPU SLEEP or HALT mode
+ 
+// <1=> Run in SLEEP, Pause in HALT 
+// <8=> Pause in SLEEP, Run in HALT 
+// <9=> Run in SLEEP and HALT 
+// <0=> Pause in SLEEP and HALT 
+
+#ifndef WDT_CONFIG_BEHAVIOUR
+#define WDT_CONFIG_BEHAVIOUR 1
+#endif
+
+// <o> WDT_CONFIG_RELOAD_VALUE - Reload value  <15-4294967295> 
+
+
+#ifndef WDT_CONFIG_RELOAD_VALUE
+#define WDT_CONFIG_RELOAD_VALUE 2000
+#endif
+
+// <o> WDT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef WDT_CONFIG_IRQ_PRIORITY
+#define WDT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <h> nrfx_i2s - I2S peripheral driver
+
+//==========================================================
+// </h> 
+//==========================================================
+
+// <h> nrfx_lpcomp - LPCOMP peripheral driver
+
+//==========================================================
+// </h> 
+//==========================================================
+
+// <h> nrfx_qspi - QSPI peripheral driver
+
+//==========================================================
+// </h> 
+//==========================================================
+
+// <h> nrfx_usbd - USBD peripheral driver
+
+//==========================================================
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Drivers_External 
+
+//==========================================================
+// <q> NRF_TWI_SENSOR_ENABLED  - nrf_twi_sensor - nRF TWI Sensor module
+ 
+
+#ifndef NRF_TWI_SENSOR_ENABLED
+#define NRF_TWI_SENSOR_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Libraries 
+
+//==========================================================
+// <q> APP_GPIOTE_ENABLED  - app_gpiote - GPIOTE events dispatcher
+ 
+
+#ifndef APP_GPIOTE_ENABLED
+#define APP_GPIOTE_ENABLED 0
+#endif
+
+// <q> APP_PWM_ENABLED  - app_pwm - PWM functionality
+ 
+
+#ifndef APP_PWM_ENABLED
+#define APP_PWM_ENABLED 0
+#endif
+
+// <e> APP_SCHEDULER_ENABLED - app_scheduler - Events scheduler
+//==========================================================
+#ifndef APP_SCHEDULER_ENABLED
+#define APP_SCHEDULER_ENABLED 0
+#endif
+// <q> APP_SCHEDULER_WITH_PAUSE  - Enabling pause feature
+ 
+
+#ifndef APP_SCHEDULER_WITH_PAUSE
+#define APP_SCHEDULER_WITH_PAUSE 0
+#endif
+
+// <q> APP_SCHEDULER_WITH_PROFILER  - Enabling scheduler profiling
+ 
+
+#ifndef APP_SCHEDULER_WITH_PROFILER
+#define APP_SCHEDULER_WITH_PROFILER 0
+#endif
+
+// </e>
+
+// <e> APP_SDCARD_ENABLED - app_sdcard - SD/MMC card support using SPI
+//==========================================================
+#ifndef APP_SDCARD_ENABLED
+#define APP_SDCARD_ENABLED 0
+#endif
+// <o> APP_SDCARD_SPI_INSTANCE  - SPI instance used
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+
+#ifndef APP_SDCARD_SPI_INSTANCE
+#define APP_SDCARD_SPI_INSTANCE 0
+#endif
+
+// <o> APP_SDCARD_FREQ_INIT  - SPI frequency
+ 
+// <33554432=> 125 kHz 
+// <67108864=> 250 kHz 
+// <134217728=> 500 kHz 
+// <268435456=> 1 MHz 
+// <536870912=> 2 MHz 
+// <1073741824=> 4 MHz 
+// <2147483648=> 8 MHz 
+
+#ifndef APP_SDCARD_FREQ_INIT
+#define APP_SDCARD_FREQ_INIT 67108864
+#endif
+
+// <o> APP_SDCARD_FREQ_DATA  - SPI frequency
+ 
+// <33554432=> 125 kHz 
+// <67108864=> 250 kHz 
+// <134217728=> 500 kHz 
+// <268435456=> 1 MHz 
+// <536870912=> 2 MHz 
+// <1073741824=> 4 MHz 
+// <2147483648=> 8 MHz 
+
+#ifndef APP_SDCARD_FREQ_DATA
+#define APP_SDCARD_FREQ_DATA 1073741824
+#endif
+
+// </e>
+
+// <e> APP_TIMER_ENABLED - app_timer - Application timer functionality
+//==========================================================
+#ifndef APP_TIMER_ENABLED
+#define APP_TIMER_ENABLED 0
+#endif
+// <o> APP_TIMER_CONFIG_RTC_FREQUENCY  - Configure RTC prescaler.
+ 
+// <0=> 32768 Hz 
+// <1=> 16384 Hz 
+// <3=> 8192 Hz 
+// <7=> 4096 Hz 
+// <15=> 2048 Hz 
+// <31=> 1024 Hz 
+
+#ifndef APP_TIMER_CONFIG_RTC_FREQUENCY
+#define APP_TIMER_CONFIG_RTC_FREQUENCY 1
+#endif
+
+// <o> APP_TIMER_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef APP_TIMER_CONFIG_IRQ_PRIORITY
+#define APP_TIMER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> APP_TIMER_CONFIG_OP_QUEUE_SIZE - Capacity of timer requests queue. 
+// <i> Size of the queue depends on how many timers are used
+// <i> in the system, how often timers are started and overall
+// <i> system latency. If queue size is too small app_timer calls
+// <i> will fail.
+
+#ifndef APP_TIMER_CONFIG_OP_QUEUE_SIZE
+#define APP_TIMER_CONFIG_OP_QUEUE_SIZE 10
+#endif
+
+// <q> APP_TIMER_CONFIG_USE_SCHEDULER  - Enable scheduling app_timer events to app_scheduler
+ 
+
+#ifndef APP_TIMER_CONFIG_USE_SCHEDULER
+#define APP_TIMER_CONFIG_USE_SCHEDULER 0
+#endif
+
+// <q> APP_TIMER_KEEPS_RTC_ACTIVE  - Enable RTC always on
+ 
+
+// <i> If option is enabled RTC is kept running even if there is no active timers.
+// <i> This option can be used when app_timer is used for timestamping.
+
+#ifndef APP_TIMER_KEEPS_RTC_ACTIVE
+#define APP_TIMER_KEEPS_RTC_ACTIVE 0
+#endif
+
+// <o> APP_TIMER_SAFE_WINDOW_MS - Maximum possible latency (in milliseconds) of handling app_timer event. 
+// <i> Maximum possible timeout that can be set is reduced by safe window.
+// <i> Example: RTC frequency 16384 Hz, maximum possible timeout 1024 seconds - APP_TIMER_SAFE_WINDOW_MS.
+// <i> Since RTC is not stopped when processor is halted in debugging session, this value
+// <i> must cover it if debugging is needed. It is possible to halt processor for APP_TIMER_SAFE_WINDOW_MS
+// <i> without corrupting app_timer behavior.
+
+#ifndef APP_TIMER_SAFE_WINDOW_MS
+#define APP_TIMER_SAFE_WINDOW_MS 300000
+#endif
+
+// <h> App Timer Legacy configuration - Legacy configuration.
+
+//==========================================================
+// <q> APP_TIMER_WITH_PROFILER  - Enable app_timer profiling
+ 
+
+#ifndef APP_TIMER_WITH_PROFILER
+#define APP_TIMER_WITH_PROFILER 0
+#endif
+
+// <q> APP_TIMER_CONFIG_SWI_NUMBER  - Configure SWI instance used.
+ 
+
+#ifndef APP_TIMER_CONFIG_SWI_NUMBER
+#define APP_TIMER_CONFIG_SWI_NUMBER 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> APP_USBD_AUDIO_ENABLED  - app_usbd_audio - USB AUDIO class
+ 
+
+#ifndef APP_USBD_AUDIO_ENABLED
+#define APP_USBD_AUDIO_ENABLED 0
+#endif
+
+// <e> APP_USBD_ENABLED - app_usbd - USB Device library
+//==========================================================
+#ifndef APP_USBD_ENABLED
+#define APP_USBD_ENABLED 0
+#endif
+// <o> APP_USBD_VID - Vendor ID.  <0x0000-0xFFFF> 
+
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/
+
+#ifndef APP_USBD_VID
+#define APP_USBD_VID 0
+#endif
+
+// <o> APP_USBD_PID - Product ID.  <0x0000-0xFFFF> 
+
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Selected Product ID
+
+#ifndef APP_USBD_PID
+#define APP_USBD_PID 0
+#endif
+
+// <o> APP_USBD_DEVICE_VER_MAJOR - Major device version  <0-99> 
+
+
+// <i> Major device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_MAJOR
+#define APP_USBD_DEVICE_VER_MAJOR 1
+#endif
+
+// <o> APP_USBD_DEVICE_VER_MINOR - Minor device version  <0-9> 
+
+
+// <i> Minor device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_MINOR
+#define APP_USBD_DEVICE_VER_MINOR 0
+#endif
+
+// <o> APP_USBD_DEVICE_VER_SUB - Sub-minor device version  <0-9> 
+
+
+// <i> Sub-minor device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_SUB
+#define APP_USBD_DEVICE_VER_SUB 0
+#endif
+
+// <q> APP_USBD_CONFIG_SELF_POWERED  - Self-powered device, as opposed to bus-powered.
+ 
+
+#ifndef APP_USBD_CONFIG_SELF_POWERED
+#define APP_USBD_CONFIG_SELF_POWERED 1
+#endif
+
+// <o> APP_USBD_CONFIG_MAX_POWER - MaxPower field in configuration descriptor in milliamps.  <0-500> 
+
+
+#ifndef APP_USBD_CONFIG_MAX_POWER
+#define APP_USBD_CONFIG_MAX_POWER 100
+#endif
+
+// <q> APP_USBD_CONFIG_POWER_EVENTS_PROCESS  - Process power events.
+ 
+
+// <i> Enable processing power events in USB event handler.
+
+#ifndef APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+#define APP_USBD_CONFIG_POWER_EVENTS_PROCESS 1
+#endif
+
+// <e> APP_USBD_CONFIG_EVENT_QUEUE_ENABLE - Enable event queue.
+
+// <i> This is the default configuration when all the events are placed into internal queue.
+// <i> Disable it when an external queue is used like app_scheduler or if you wish to process all events inside interrupts.
+// <i> Processing all events from the interrupt level adds requirement not to call any functions that modifies the USBD library state from the context higher than USB interrupt context.
+// <i> Functions that modify USBD state are functions for sleep, wakeup, start, stop, enable, and disable.
+//==========================================================
+#ifndef APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
+#define APP_USBD_CONFIG_EVENT_QUEUE_ENABLE 1
+#endif
+// <o> APP_USBD_CONFIG_EVENT_QUEUE_SIZE - The size of the event queue.  <16-64> 
+
+
+// <i> The size of the queue for the events that would be processed in the main loop.
+
+#ifndef APP_USBD_CONFIG_EVENT_QUEUE_SIZE
+#define APP_USBD_CONFIG_EVENT_QUEUE_SIZE 32
+#endif
+
+// <o> APP_USBD_CONFIG_SOF_HANDLING_MODE  - Change SOF events handling mode.
+ 
+
+// <i> Normal queue   - SOF events are pushed normally into the event queue.
+// <i> Compress queue - SOF events are counted and binded with other events or executed when the queue is empty.
+// <i>                  This prevents the queue from filling up with SOF events.
+// <i> Interrupt      - SOF events are processed in interrupt.
+// <0=> Normal queue 
+// <1=> Compress queue 
+// <2=> Interrupt 
+
+#ifndef APP_USBD_CONFIG_SOF_HANDLING_MODE
+#define APP_USBD_CONFIG_SOF_HANDLING_MODE 1
+#endif
+
+// </e>
+
+// <q> APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE  - Provide a function that generates timestamps for logs based on the current SOF.
+ 
+
+// <i> The function app_usbd_sof_timestamp_get is implemented if the logger is enabled. 
+// <i> Use it when initializing the logger. 
+// <i> SOF processing is always enabled when this configuration parameter is active. 
+// <i> Note: This option is configured outside of APP_USBD_CONFIG_LOG_ENABLED. 
+// <i> This means that it works even if the logging in this very module is disabled. 
+
+#ifndef APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE
+#define APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE 0
+#endif
+
+// <o> APP_USBD_CONFIG_DESC_STRING_SIZE - Maximum size of the NULL-terminated string of the string descriptor.  <31-254> 
+
+
+// <i> 31 characters can be stored in the internal USB buffer used for transfers.
+// <i> Any value higher than 31 creates an additional buffer just for descriptor strings.
+
+#ifndef APP_USBD_CONFIG_DESC_STRING_SIZE
+#define APP_USBD_CONFIG_DESC_STRING_SIZE 31
+#endif
+
+// <q> APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED  - Enable UTF8 conversion.
+ 
+
+// <i> Enable UTF8-encoded characters. In normal processing, only ASCII characters are available.
+
+#ifndef APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED
+#define APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED 0
+#endif
+
+// <s> APP_USBD_STRINGS_LANGIDS - Supported languages identifiers.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Comma-separated list of supported languages.
+#ifndef APP_USBD_STRINGS_LANGIDS
+#define APP_USBD_STRINGS_LANGIDS APP_USBD_LANG_AND_SUBLANG(APP_USBD_LANG_ENGLISH, APP_USBD_SUBLANG_ENGLISH_US)
+#endif
+
+// <e> APP_USBD_STRING_ID_MANUFACTURER - Define manufacturer string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_MANUFACTURER
+#define APP_USBD_STRING_ID_MANUFACTURER 1
+#endif
+// <q> APP_USBD_STRINGS_MANUFACTURER_EXTERN  - Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN
+#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_MANUFACTURER - String descriptor for the manufacturer name.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Comma-separated list of manufacturer names for each defined language.
+// <i> Use @ref APP_USBD_STRING_DESC macro to create string descriptor from a NULL-terminated string.
+// <i> Use @ref APP_USBD_STRING_RAW8_DESC macro to create string descriptor from comma-separated uint8_t values.
+// <i> Use @ref APP_USBD_STRING_RAW16_DESC macro to create string descriptor from comma-separated uint16_t values.
+// <i> Alternatively, configure the macro to point to any internal variable pointer that already contains the descriptor.
+// <i> Setting string to NULL disables that string.
+// <i> The order of manufacturer names must be the same like in @ref APP_USBD_STRINGS_LANGIDS.
+#ifndef APP_USBD_STRINGS_MANUFACTURER
+#define APP_USBD_STRINGS_MANUFACTURER APP_USBD_STRING_DESC("Nordic Semiconductor")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_PRODUCT - Define product string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_PRODUCT
+#define APP_USBD_STRING_ID_PRODUCT 2
+#endif
+// <q> APP_USBD_STRINGS_PRODUCT_EXTERN  - Define whether @ref APP_USBD_STRINGS_PRODUCT is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
+#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_PRODUCT - String descriptor for the product name.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> List of product names that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRINGS_PRODUCT
+#define APP_USBD_STRINGS_PRODUCT APP_USBD_STRING_DESC("nRF52 USB Product")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_SERIAL - Define serial number string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_SERIAL
+#define APP_USBD_STRING_ID_SERIAL 3
+#endif
+// <q> APP_USBD_STRING_SERIAL_EXTERN  - Define whether @ref APP_USBD_STRING_SERIAL is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRING_SERIAL_EXTERN
+#define APP_USBD_STRING_SERIAL_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRING_SERIAL - String descriptor for the serial number.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRING_SERIAL
+#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("000000000000")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_CONFIGURATION - Define configuration string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_CONFIGURATION
+#define APP_USBD_STRING_ID_CONFIGURATION 4
+#endif
+// <q> APP_USBD_STRING_CONFIGURATION_EXTERN  - Define whether @ref APP_USBD_STRINGS_CONFIGURATION is created by macro or declared as global variable.
+ 
+
+#ifndef APP_USBD_STRING_CONFIGURATION_EXTERN
+#define APP_USBD_STRING_CONFIGURATION_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_CONFIGURATION - String descriptor for the device configuration.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Configuration string that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRINGS_CONFIGURATION
+#define APP_USBD_STRINGS_CONFIGURATION APP_USBD_STRING_DESC("Default configuration")
+#endif
+
+// </e>
+
+// <s> APP_USBD_STRINGS_USER - Default values for user strings.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> This value stores all application specific user strings with the default initialization.
+// <i> The setup is done by X-macros.
+// <i> Expected macro parameters:
+// <i> @code
+// <i> X(mnemonic, [=str_idx], ...)
+// <i> @endcode
+// <i> - @c mnemonic: Mnemonic of the string descriptor that would be added to
+// <i>                @ref app_usbd_string_desc_idx_t enumerator.
+// <i> - @c str_idx : String index value, can be set or left empty.
+// <i>                For example, WinUSB driver requires descriptor to be present on 0xEE index.
+// <i>                Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
+// <i> - @c ...     : List of string descriptors for each defined language.
+#ifndef APP_USBD_STRINGS_USER
+#define APP_USBD_STRINGS_USER X(APP_USER_1, , APP_USBD_STRING_DESC("User 1"))
+#endif
+
+// </e>
+
+// <e> APP_USBD_HID_ENABLED - app_usbd_hid - USB HID class
+//==========================================================
+#ifndef APP_USBD_HID_ENABLED
+#define APP_USBD_HID_ENABLED 0
+#endif
+// <o> APP_USBD_HID_DEFAULT_IDLE_RATE - Default idle rate for HID class.   <0-255> 
+
+
+// <i> 0 means indefinite duration, any other value is multiplied by 4 milliseconds. Refer to Chapter 7.2.4 of HID 1.11 Specification.
+
+#ifndef APP_USBD_HID_DEFAULT_IDLE_RATE
+#define APP_USBD_HID_DEFAULT_IDLE_RATE 0
+#endif
+
+// <o> APP_USBD_HID_REPORT_IDLE_TABLE_SIZE - Size of idle rate table.   <1-255> 
+
+
+// <i> Must be higher than the highest report ID used.
+
+#ifndef APP_USBD_HID_REPORT_IDLE_TABLE_SIZE
+#define APP_USBD_HID_REPORT_IDLE_TABLE_SIZE 4
+#endif
+
+// </e>
+
+// <q> APP_USBD_HID_GENERIC_ENABLED  - app_usbd_hid_generic - USB HID generic
+ 
+
+#ifndef APP_USBD_HID_GENERIC_ENABLED
+#define APP_USBD_HID_GENERIC_ENABLED 0
+#endif
+
+// <q> APP_USBD_HID_KBD_ENABLED  - app_usbd_hid_kbd - USB HID keyboard
+ 
+
+#ifndef APP_USBD_HID_KBD_ENABLED
+#define APP_USBD_HID_KBD_ENABLED 0
+#endif
+
+// <q> APP_USBD_HID_MOUSE_ENABLED  - app_usbd_hid_mouse - USB HID mouse
+ 
+
+#ifndef APP_USBD_HID_MOUSE_ENABLED
+#define APP_USBD_HID_MOUSE_ENABLED 0
+#endif
+
+// <q> APP_USBD_MSC_ENABLED  - app_usbd_msc - USB MSC class
+ 
+
+#ifndef APP_USBD_MSC_ENABLED
+#define APP_USBD_MSC_ENABLED 0
+#endif
+
+// <q> CRC16_ENABLED  - crc16 - CRC16 calculation routines
+ 
+
+#ifndef CRC16_ENABLED
+#define CRC16_ENABLED 0
+#endif
+
+// <q> CRC32_ENABLED  - crc32 - CRC32 calculation routines
+ 
+
+#ifndef CRC32_ENABLED
+#define CRC32_ENABLED 0
+#endif
+
+// <q> ECC_ENABLED  - ecc - Elliptic Curve Cryptography Library
+ 
+
+#ifndef ECC_ENABLED
+#define ECC_ENABLED 0
+#endif
+
+// <e> FDS_ENABLED - fds - Flash data storage module
+//==========================================================
+#ifndef FDS_ENABLED
+#define FDS_ENABLED 0
+#endif
+// <h> Pages - Virtual page settings
+
+// <i> Configure the number of virtual pages to use and their size.
+//==========================================================
+// <o> FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. 
+// <i> One of the virtual pages is reserved by the system for garbage collection.
+// <i> Therefore, the minimum is two virtual pages: one page to store data and one page to be used by the system for garbage collection.
+// <i> The total amount of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES * @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes.
+
+#ifndef FDS_VIRTUAL_PAGES
+#define FDS_VIRTUAL_PAGES 3
+#endif
+
+// <o> FDS_VIRTUAL_PAGE_SIZE  - The size of a virtual flash page.
+ 
+
+// <i> Expressed in number of 4-byte words.
+// <i> By default, a virtual page is the same size as a physical page.
+// <i> The size of a virtual page must be a multiple of the size of a physical page.
+// <1024=> 1024 
+// <2048=> 2048 
+
+#ifndef FDS_VIRTUAL_PAGE_SIZE
+#define FDS_VIRTUAL_PAGE_SIZE 1024
+#endif
+
+// <o> FDS_VIRTUAL_PAGES_RESERVED - The number of virtual flash pages that are used by other modules. 
+// <i> FDS module stores its data in the last pages of the flash memory.
+// <i> By setting this value, you can move flash end address used by the FDS.
+// <i> As a result the reserved space can be used by other modules.
+
+#ifndef FDS_VIRTUAL_PAGES_RESERVED
+#define FDS_VIRTUAL_PAGES_RESERVED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Backend - Backend configuration
+
+// <i> Configure which nrf_fstorage backend is used by FDS to write to flash.
+//==========================================================
+// <o> FDS_BACKEND  - FDS flash backend.
+ 
+
+// <i> NRF_FSTORAGE_SD uses the nrf_fstorage_sd backend implementation using the SoftDevice API. Use this if you have a SoftDevice present.
+// <i> NRF_FSTORAGE_NVMC uses the nrf_fstorage_nvmc implementation. Use this setting if you don't use the SoftDevice.
+// <1=> NRF_FSTORAGE_NVMC 
+// <2=> NRF_FSTORAGE_SD 
+
+#ifndef FDS_BACKEND
+#define FDS_BACKEND 2
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Queue - Queue settings
+
+//==========================================================
+// <o> FDS_OP_QUEUE_SIZE - Size of the internal queue. 
+// <i> Increase this value if you frequently get synchronous FDS_ERR_NO_SPACE_IN_QUEUES errors.
+
+#ifndef FDS_OP_QUEUE_SIZE
+#define FDS_OP_QUEUE_SIZE 4
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> CRC - CRC functionality
+
+//==========================================================
+// <e> FDS_CRC_CHECK_ON_READ - Enable CRC checks.
+
+// <i> Save a record's CRC when it is written to flash and check it when the record is opened.
+// <i> Records with an incorrect CRC can still be 'seen' by the user using FDS functions, but they cannot be opened.
+// <i> Additionally, they will not be garbage collected until they are deleted.
+//==========================================================
+#ifndef FDS_CRC_CHECK_ON_READ
+#define FDS_CRC_CHECK_ON_READ 0
+#endif
+// <o> FDS_CRC_CHECK_ON_WRITE  - Perform a CRC check on newly written records.
+ 
+
+// <i> Perform a CRC check on newly written records.
+// <i> This setting can be used to make sure that the record data was not altered while being written to flash.
+// <1=> Enabled 
+// <0=> Disabled 
+
+#ifndef FDS_CRC_CHECK_ON_WRITE
+#define FDS_CRC_CHECK_ON_WRITE 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> Users - Number of users
+
+//==========================================================
+// <o> FDS_MAX_USERS - Maximum number of callbacks that can be registered. 
+#ifndef FDS_MAX_USERS
+#define FDS_MAX_USERS 4
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> HARDFAULT_HANDLER_ENABLED  - hardfault_default - HardFault default handler for debugging and release
+ 
+
+#ifndef HARDFAULT_HANDLER_ENABLED
+#define HARDFAULT_HANDLER_ENABLED 0
+#endif
+
+// <e> HCI_MEM_POOL_ENABLED - hci_mem_pool - memory pool implementation used by HCI
+//==========================================================
+#ifndef HCI_MEM_POOL_ENABLED
+#define HCI_MEM_POOL_ENABLED 0
+#endif
+// <o> HCI_TX_BUF_SIZE - TX buffer size in bytes. 
+#ifndef HCI_TX_BUF_SIZE
+#define HCI_TX_BUF_SIZE 600
+#endif
+
+// <o> HCI_RX_BUF_SIZE - RX buffer size in bytes. 
+#ifndef HCI_RX_BUF_SIZE
+#define HCI_RX_BUF_SIZE 600
+#endif
+
+// <o> HCI_RX_BUF_QUEUE_SIZE - RX buffer queue size. 
+#ifndef HCI_RX_BUF_QUEUE_SIZE
+#define HCI_RX_BUF_QUEUE_SIZE 4
+#endif
+
+// </e>
+
+// <e> HCI_SLIP_ENABLED - hci_slip - SLIP protocol implementation used by HCI
+//==========================================================
+#ifndef HCI_SLIP_ENABLED
+#define HCI_SLIP_ENABLED 0
+#endif
+// <o> HCI_UART_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <10289152=> 38400 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef HCI_UART_BAUDRATE
+#define HCI_UART_BAUDRATE 30801920
+#endif
+
+// <o> HCI_UART_FLOW_CONTROL  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef HCI_UART_FLOW_CONTROL
+#define HCI_UART_FLOW_CONTROL 0
+#endif
+
+// <o> HCI_UART_RX_PIN - UART RX pin 
+#ifndef HCI_UART_RX_PIN
+#define HCI_UART_RX_PIN 31
+#endif
+
+// <o> HCI_UART_TX_PIN - UART TX pin 
+#ifndef HCI_UART_TX_PIN
+#define HCI_UART_TX_PIN 31
+#endif
+
+// <o> HCI_UART_RTS_PIN - UART RTS pin 
+#ifndef HCI_UART_RTS_PIN
+#define HCI_UART_RTS_PIN 31
+#endif
+
+// <o> HCI_UART_CTS_PIN - UART CTS pin 
+#ifndef HCI_UART_CTS_PIN
+#define HCI_UART_CTS_PIN 31
+#endif
+
+// </e>
+
+// <e> HCI_TRANSPORT_ENABLED - hci_transport - HCI transport
+//==========================================================
+#ifndef HCI_TRANSPORT_ENABLED
+#define HCI_TRANSPORT_ENABLED 0
+#endif
+// <o> HCI_MAX_PACKET_SIZE_IN_BITS - Maximum size of a single application packet in bits. 
+#ifndef HCI_MAX_PACKET_SIZE_IN_BITS
+#define HCI_MAX_PACKET_SIZE_IN_BITS 8000
+#endif
+
+// </e>
+
+// <q> LED_SOFTBLINK_ENABLED  - led_softblink - led_softblink module
+ 
+
+#ifndef LED_SOFTBLINK_ENABLED
+#define LED_SOFTBLINK_ENABLED 0
+#endif
+
+// <q> LOW_POWER_PWM_ENABLED  - low_power_pwm - low_power_pwm module
+ 
+
+#ifndef LOW_POWER_PWM_ENABLED
+#define LOW_POWER_PWM_ENABLED 0
+#endif
+
+// <e> MEM_MANAGER_ENABLED - mem_manager - Dynamic memory allocator
+//==========================================================
+#ifndef MEM_MANAGER_ENABLED
+#define MEM_MANAGER_ENABLED 0
+#endif
+// <o> MEMORY_MANAGER_SMALL_BLOCK_COUNT - Size of each memory blocks identified as 'small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_SMALL_BLOCK_COUNT 1
+#endif
+
+// <o> MEMORY_MANAGER_SMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'small' block. 
+// <i>  Size of each memory blocks identified as 'small' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_SMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_SMALL_BLOCK_SIZE 32
+#endif
+
+// <o> MEMORY_MANAGER_MEDIUM_BLOCK_COUNT - Size of each memory blocks identified as 'medium' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
+#define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_MEDIUM_BLOCK_SIZE -  Size of each memory blocks identified as 'medium' block. 
+// <i>  Size of each memory blocks identified as 'medium' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_SIZE
+#define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 256
+#endif
+
+// <o> MEMORY_MANAGER_LARGE_BLOCK_COUNT - Size of each memory blocks identified as 'large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_LARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'large' block. 
+// <i>  Size of each memory blocks identified as 'large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_LARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_LARGE_BLOCK_SIZE 256
+#endif
+
+// <o> MEMORY_MANAGER_XLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XLARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'extra large' block. 
+// <i>  Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XLARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 1320
+#endif
+
+// <o> MEMORY_MANAGER_XXLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XXLARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'extra extra large' block. 
+// <i>  Size of each memory blocks identified as 'extra extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 3444
+#endif
+
+// <o> MEMORY_MANAGER_XSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XSMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'extra small' block. 
+// <i>  Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XSMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 64
+#endif
+
+// <o> MEMORY_MANAGER_XXSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XXSMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'extra extra small' block. 
+// <i>  Size of each memory blocks identified as 'extra extra small' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 32
+#endif
+
+// <e> MEM_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef MEM_MANAGER_CONFIG_LOG_ENABLED
+#define MEM_MANAGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> MEM_MANAGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef MEM_MANAGER_CONFIG_LOG_LEVEL
+#define MEM_MANAGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> MEM_MANAGER_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 MEM_MANAGER_CONFIG_INFO_COLOR
+#define MEM_MANAGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> MEM_MANAGER_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 MEM_MANAGER_CONFIG_DEBUG_COLOR
+#define MEM_MANAGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <q> MEM_MANAGER_DISABLE_API_PARAM_CHECK  - Disable API parameter checks in the module.
+ 
+
+#ifndef MEM_MANAGER_DISABLE_API_PARAM_CHECK
+#define MEM_MANAGER_DISABLE_API_PARAM_CHECK 0
+#endif
+
+// </e>
+
+// <e> NRF_BALLOC_ENABLED - nrf_balloc - Block allocator module
+//==========================================================
+#ifndef NRF_BALLOC_ENABLED
+#define NRF_BALLOC_ENABLED 1
+#endif
+// <e> NRF_BALLOC_CONFIG_DEBUG_ENABLED - Enables debug mode in the module.
+//==========================================================
+#ifndef NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define NRF_BALLOC_CONFIG_DEBUG_ENABLED 0
+#endif
+// <o> NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS - Number of words used as head guard.  <0-255> 
+
+
+#ifndef NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS
+#define NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS 1
+#endif
+
+// <o> NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS - Number of words used as tail guard.  <0-255> 
+
+
+#ifndef NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS
+#define NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS 1
+#endif
+
+// <q> NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED  - Enables basic checks in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED
+#define NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED  - Enables double memory free check in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED
+#define NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED  - Enables free memory corruption check in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED
+#define NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef NRF_BALLOC_CLI_CMDS
+#define NRF_BALLOC_CLI_CMDS 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRF_CSENSE_ENABLED - nrf_csense - Capacitive sensor module
+//==========================================================
+#ifndef NRF_CSENSE_ENABLED
+#define NRF_CSENSE_ENABLED 0
+#endif
+// <o> NRF_CSENSE_PAD_HYSTERESIS - Minimum value of change required to determine that a pad was touched. 
+#ifndef NRF_CSENSE_PAD_HYSTERESIS
+#define NRF_CSENSE_PAD_HYSTERESIS 15
+#endif
+
+// <o> NRF_CSENSE_PAD_DEVIATION - Minimum value measured on a pad required to take it into account while calculating the step. 
+#ifndef NRF_CSENSE_PAD_DEVIATION
+#define NRF_CSENSE_PAD_DEVIATION 70
+#endif
+
+// <o> NRF_CSENSE_MIN_PAD_VALUE - Minimum normalized value on a pad required to take its value into account. 
+#ifndef NRF_CSENSE_MIN_PAD_VALUE
+#define NRF_CSENSE_MIN_PAD_VALUE 20
+#endif
+
+// <o> NRF_CSENSE_MAX_PADS_NUMBER - Maximum number of pads used for one instance. 
+#ifndef NRF_CSENSE_MAX_PADS_NUMBER
+#define NRF_CSENSE_MAX_PADS_NUMBER 20
+#endif
+
+// <o> NRF_CSENSE_MAX_VALUE - Maximum normalized value obtained from measurement. 
+#ifndef NRF_CSENSE_MAX_VALUE
+#define NRF_CSENSE_MAX_VALUE 1000
+#endif
+
+// <o> NRF_CSENSE_OUTPUT_PIN - Output pin used by the low-level module. 
+// <i> This is used when capacitive sensor does not use COMP.
+
+#ifndef NRF_CSENSE_OUTPUT_PIN
+#define NRF_CSENSE_OUTPUT_PIN 26
+#endif
+
+// </e>
+
+// <e> NRF_DRV_CSENSE_ENABLED - nrf_drv_csense - Capacitive sensor low-level module
+//==========================================================
+#ifndef NRF_DRV_CSENSE_ENABLED
+#define NRF_DRV_CSENSE_ENABLED 0
+#endif
+// <e> USE_COMP - Use the comparator to implement the capacitive sensor driver.
+
+// <i> Due to Anomaly 84, COMP I_SOURCE is not functional. It has too high a varation.
+//==========================================================
+#ifndef USE_COMP
+#define USE_COMP 0
+#endif
+// <o> TIMER0_FOR_CSENSE - First TIMER instance used by the driver (not used on nRF51). 
+#ifndef TIMER0_FOR_CSENSE
+#define TIMER0_FOR_CSENSE 1
+#endif
+
+// <o> TIMER1_FOR_CSENSE - Second TIMER instance used by the driver (not used on nRF51). 
+#ifndef TIMER1_FOR_CSENSE
+#define TIMER1_FOR_CSENSE 2
+#endif
+
+// <o> MEASUREMENT_PERIOD - Single measurement period. 
+// <i> Time of a single measurement can be calculated as
+// <i> T = (1/2)*MEASUREMENT_PERIOD*(1/f_OSC) where f_OSC = I_SOURCE / (2C*(VUP-VDOWN) ).
+// <i> I_SOURCE, VUP, and VDOWN are values used to initialize COMP and C is the capacitance of the used pad.
+
+#ifndef MEASUREMENT_PERIOD
+#define MEASUREMENT_PERIOD 20
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRF_FSTORAGE_ENABLED - nrf_fstorage - Flash abstraction library
+//==========================================================
+#ifndef NRF_FSTORAGE_ENABLED
+#define NRF_FSTORAGE_ENABLED 0
+#endif
+// <h> nrf_fstorage - Common settings
+
+// <i> Common settings to all fstorage implementations
+//==========================================================
+// <q> NRF_FSTORAGE_PARAM_CHECK_DISABLED  - Disable user input validation
+ 
+
+// <i> If selected, use ASSERT to validate user input.
+// <i> This effectively removes user input validation in production code.
+// <i> Recommended setting: OFF, only enable this setting if size is a major concern.
+
+#ifndef NRF_FSTORAGE_PARAM_CHECK_DISABLED
+#define NRF_FSTORAGE_PARAM_CHECK_DISABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_fstorage_sd - Implementation using the SoftDevice
+
+// <i> Configuration options for the fstorage implementation using the SoftDevice
+//==========================================================
+// <o> NRF_FSTORAGE_SD_QUEUE_SIZE - Size of the internal queue of operations 
+// <i> Increase this value if API calls frequently return the error @ref NRF_ERROR_NO_MEM.
+
+#ifndef NRF_FSTORAGE_SD_QUEUE_SIZE
+#define NRF_FSTORAGE_SD_QUEUE_SIZE 4
+#endif
+
+// <o> NRF_FSTORAGE_SD_MAX_RETRIES - Maximum number of attempts at executing an operation when the SoftDevice is busy 
+// <i> Increase this value if events frequently return the @ref NRF_ERROR_TIMEOUT error.
+// <i> The SoftDevice might fail to schedule flash access due to high BLE activity.
+
+#ifndef NRF_FSTORAGE_SD_MAX_RETRIES
+#define NRF_FSTORAGE_SD_MAX_RETRIES 8
+#endif
+
+// <o> NRF_FSTORAGE_SD_MAX_WRITE_SIZE - Maximum number of bytes to be written to flash in a single operation 
+// <i> This value must be a multiple of four.
+// <i> Lowering this value can increase the chances of the SoftDevice being able to execute flash operations in between radio activity.
+// <i> This value is bound by the maximum number of bytes that can be written to flash in a single call to @ref sd_flash_write.
+// <i> That is 1024 bytes for nRF51 ICs and 4096 bytes for nRF52 ICs.
+
+#ifndef NRF_FSTORAGE_SD_MAX_WRITE_SIZE
+#define NRF_FSTORAGE_SD_MAX_WRITE_SIZE 4096
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> NRF_GFX_ENABLED  - nrf_gfx - GFX module
+ 
+
+#ifndef NRF_GFX_ENABLED
+#define NRF_GFX_ENABLED 0
+#endif
+
+// <q> NRF_MEMOBJ_ENABLED  - nrf_memobj - Linked memory allocator module
+ 
+
+#ifndef NRF_MEMOBJ_ENABLED
+#define NRF_MEMOBJ_ENABLED 1
+#endif
+
+// <e> NRF_PWR_MGMT_ENABLED - nrf_pwr_mgmt - Power management module
+//==========================================================
+#ifndef NRF_PWR_MGMT_ENABLED
+#define NRF_PWR_MGMT_ENABLED 0
+#endif
+// <e> NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED - Enables pin debug in the module.
+
+// <i> Selected pin will be set when CPU is in sleep mode.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED
+#define NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_SLEEP_DEBUG_PIN  - Pin number
+ 
+// <0=> 0 (P0.0) 
+// <1=> 1 (P0.1) 
+// <2=> 2 (P0.2) 
+// <3=> 3 (P0.3) 
+// <4=> 4 (P0.4) 
+// <5=> 5 (P0.5) 
+// <6=> 6 (P0.6) 
+// <7=> 7 (P0.7) 
+// <8=> 8 (P0.8) 
+// <9=> 9 (P0.9) 
+// <10=> 10 (P0.10) 
+// <11=> 11 (P0.11) 
+// <12=> 12 (P0.12) 
+// <13=> 13 (P0.13) 
+// <14=> 14 (P0.14) 
+// <15=> 15 (P0.15) 
+// <16=> 16 (P0.16) 
+// <17=> 17 (P0.17) 
+// <18=> 18 (P0.18) 
+// <19=> 19 (P0.19) 
+// <20=> 20 (P0.20) 
+// <21=> 21 (P0.21) 
+// <22=> 22 (P0.22) 
+// <23=> 23 (P0.23) 
+// <24=> 24 (P0.24) 
+// <25=> 25 (P0.25) 
+// <26=> 26 (P0.26) 
+// <27=> 27 (P0.27) 
+// <28=> 28 (P0.28) 
+// <29=> 29 (P0.29) 
+// <30=> 30 (P0.30) 
+// <31=> 31 (P0.31) 
+// <4294967295=> Not connected 
+
+#ifndef NRF_PWR_MGMT_SLEEP_DEBUG_PIN
+#define NRF_PWR_MGMT_SLEEP_DEBUG_PIN 31
+#endif
+
+// </e>
+
+// <q> NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED  - Enables CPU usage monitor.
+ 
+
+// <i> Module will trace percentage of CPU usage in one second intervals.
+
+#ifndef NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED
+#define NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED 0
+#endif
+
+// <e> NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED - Enable standby timeout.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED
+#define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S - Standby timeout (in seconds). 
+// <i> Shutdown procedure will begin no earlier than after this number of seconds.
+
+#ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S
+#define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S 3
+#endif
+
+// </e>
+
+// <q> NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED  - Enables FPU event cleaning.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED
+#define NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED 0
+#endif
+
+// <q> NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY  - Blocked shutdown procedure will be retried every second.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
+#define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 0
+#endif
+
+// <q> NRF_PWR_MGMT_CONFIG_USE_SCHEDULER  - Module will use @ref app_scheduler.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+#define NRF_PWR_MGMT_CONFIG_USE_SCHEDULER 0
+#endif
+
+// <o> NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT - The number of priorities for module handlers. 
+// <i> The number of stages of the shutdown process.
+
+#ifndef NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT
+#define NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT 3
+#endif
+
+// </e>
+
+// <e> NRF_QUEUE_ENABLED - nrf_queue - Queue module
+//==========================================================
+#ifndef NRF_QUEUE_ENABLED
+#define NRF_QUEUE_ENABLED 0
+#endif
+// <q> NRF_QUEUE_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef NRF_QUEUE_CLI_CMDS
+#define NRF_QUEUE_CLI_CMDS 0
+#endif
+
+// </e>
+
+// <q> NRF_SECTION_ITER_ENABLED  - nrf_section_iter - Section iterator
+ 
+
+#ifndef NRF_SECTION_ITER_ENABLED
+#define NRF_SECTION_ITER_ENABLED 1
+#endif
+
+// <q> NRF_SORTLIST_ENABLED  - nrf_sortlist - Sorted list
+ 
+
+#ifndef NRF_SORTLIST_ENABLED
+#define NRF_SORTLIST_ENABLED 1
+#endif
+
+// <q> NRF_SPI_MNGR_ENABLED  - nrf_spi_mngr - SPI transaction manager
+ 
+
+#ifndef NRF_SPI_MNGR_ENABLED
+#define NRF_SPI_MNGR_ENABLED 0
+#endif
+
+// <q> NRF_STRERROR_ENABLED  - nrf_strerror - Library for converting error code to string.
+ 
+
+#ifndef NRF_STRERROR_ENABLED
+#define NRF_STRERROR_ENABLED 1
+#endif
+
+// <q> NRF_TWI_MNGR_ENABLED  - nrf_twi_mngr - TWI transaction manager
+ 
+
+#ifndef NRF_TWI_MNGR_ENABLED
+#define NRF_TWI_MNGR_ENABLED 0
+#endif
+
+// <q> SLIP_ENABLED  - slip - SLIP encoding and decoding
+ 
+
+#ifndef SLIP_ENABLED
+#define SLIP_ENABLED 0
+#endif
+
+// <e> TASK_MANAGER_ENABLED - task_manager - Task manager.
+//==========================================================
+#ifndef TASK_MANAGER_ENABLED
+#define TASK_MANAGER_ENABLED 0
+#endif
+// <q> TASK_MANAGER_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef TASK_MANAGER_CLI_CMDS
+#define TASK_MANAGER_CLI_CMDS 0
+#endif
+
+// <o> TASK_MANAGER_CONFIG_MAX_TASKS - Maximum number of tasks which can be created 
+#ifndef TASK_MANAGER_CONFIG_MAX_TASKS
+#define TASK_MANAGER_CONFIG_MAX_TASKS 2
+#endif
+
+// <o> TASK_MANAGER_CONFIG_STACK_SIZE - Stack size for every task (power of 2) 
+#ifndef TASK_MANAGER_CONFIG_STACK_SIZE
+#define TASK_MANAGER_CONFIG_STACK_SIZE 1024
+#endif
+
+// <q> TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED  - Enable stack profiling.
+ 
+
+#ifndef TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED
+#define TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED 1
+#endif
+
+// <o> TASK_MANAGER_CONFIG_STACK_GUARD  - Configures stack guard.
+ 
+// <0=> Disabled 
+// <4=> 32 bytes 
+// <5=> 64 bytes 
+// <6=> 128 bytes 
+// <7=> 256 bytes 
+// <8=> 512 bytes 
+
+#ifndef TASK_MANAGER_CONFIG_STACK_GUARD
+#define TASK_MANAGER_CONFIG_STACK_GUARD 7
+#endif
+
+// </e>
+
+// <h> app_button - buttons handling module
+
+//==========================================================
+// <q> BUTTON_ENABLED  - Enables Button module
+ 
+
+#ifndef BUTTON_ENABLED
+#define BUTTON_ENABLED 0
+#endif
+
+// <q> BUTTON_HIGH_ACCURACY_ENABLED  - Enables GPIOTE high accuracy for buttons
+ 
+
+#ifndef BUTTON_HIGH_ACCURACY_ENABLED
+#define BUTTON_HIGH_ACCURACY_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> app_usbd_cdc_acm - USB CDC ACM class
+
+//==========================================================
+// <q> APP_USBD_CDC_ACM_ENABLED  - Enabling USBD CDC ACM Class library
+ 
+
+#ifndef APP_USBD_CDC_ACM_ENABLED
+#define APP_USBD_CDC_ACM_ENABLED 0
+#endif
+
+// <q> APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE  - Send ZLP on write with same size as endpoint
+ 
+
+// <i> If enabled, CDC ACM class will automatically send a zero length packet after transfer which has the same size as endpoint.
+// <i> This may limit throughput if a lot of binary data is sent, but in terminal mode operation it makes sure that the data is always displayed right after it is sent.
+
+#ifndef APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE
+#define APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE 1
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_cli - Command line interface
+
+//==========================================================
+// <q> NRF_CLI_ENABLED  - Enable/disable the CLI module.
+ 
+
+#ifndef NRF_CLI_ENABLED
+#define NRF_CLI_ENABLED 0
+#endif
+
+// <o> NRF_CLI_ARGC_MAX - Maximum number of parameters passed to the command handler. 
+#ifndef NRF_CLI_ARGC_MAX
+#define NRF_CLI_ARGC_MAX 12
+#endif
+
+// <q> NRF_CLI_BUILD_IN_CMDS_ENABLED  - CLI built-in commands.
+ 
+
+#ifndef NRF_CLI_BUILD_IN_CMDS_ENABLED
+#define NRF_CLI_BUILD_IN_CMDS_ENABLED 1
+#endif
+
+// <o> NRF_CLI_CMD_BUFF_SIZE - Maximum buffer size for a single command. 
+#ifndef NRF_CLI_CMD_BUFF_SIZE
+#define NRF_CLI_CMD_BUFF_SIZE 128
+#endif
+
+// <q> NRF_CLI_ECHO_STATUS  - CLI echo status. If set, echo is ON.
+ 
+
+#ifndef NRF_CLI_ECHO_STATUS
+#define NRF_CLI_ECHO_STATUS 1
+#endif
+
+// <q> NRF_CLI_WILDCARD_ENABLED  - Enable wildcard functionality for CLI commands.
+ 
+
+#ifndef NRF_CLI_WILDCARD_ENABLED
+#define NRF_CLI_WILDCARD_ENABLED 0
+#endif
+
+// <q> NRF_CLI_METAKEYS_ENABLED  - Enable additional control keys for CLI commands like ctrl+a, ctrl+e, ctrl+w, ctrl+u
+ 
+
+#ifndef NRF_CLI_METAKEYS_ENABLED
+#define NRF_CLI_METAKEYS_ENABLED 0
+#endif
+
+// <o> NRF_CLI_PRINTF_BUFF_SIZE - Maximum print buffer size. 
+#ifndef NRF_CLI_PRINTF_BUFF_SIZE
+#define NRF_CLI_PRINTF_BUFF_SIZE 23
+#endif
+
+// <e> NRF_CLI_HISTORY_ENABLED - Enable CLI history mode.
+//==========================================================
+#ifndef NRF_CLI_HISTORY_ENABLED
+#define NRF_CLI_HISTORY_ENABLED 1
+#endif
+// <o> NRF_CLI_HISTORY_ELEMENT_SIZE - Size of one memory object reserved for CLI history. 
+#ifndef NRF_CLI_HISTORY_ELEMENT_SIZE
+#define NRF_CLI_HISTORY_ELEMENT_SIZE 32
+#endif
+
+// <o> NRF_CLI_HISTORY_ELEMENT_COUNT - Number of history memory objects. 
+#ifndef NRF_CLI_HISTORY_ELEMENT_COUNT
+#define NRF_CLI_HISTORY_ELEMENT_COUNT 8
+#endif
+
+// </e>
+
+// <q> NRF_CLI_VT100_COLORS_ENABLED  - CLI VT100 colors.
+ 
+
+#ifndef NRF_CLI_VT100_COLORS_ENABLED
+#define NRF_CLI_VT100_COLORS_ENABLED 1
+#endif
+
+// <q> NRF_CLI_STATISTICS_ENABLED  - Enable CLI statistics.
+ 
+
+#ifndef NRF_CLI_STATISTICS_ENABLED
+#define NRF_CLI_STATISTICS_ENABLED 1
+#endif
+
+// <q> NRF_CLI_LOG_BACKEND  - Enable logger backend interface.
+ 
+
+#ifndef NRF_CLI_LOG_BACKEND
+#define NRF_CLI_LOG_BACKEND 1
+#endif
+
+// <q> NRF_CLI_USES_TASK_MANAGER_ENABLED  - Enable CLI to use task_manager
+ 
+
+#ifndef NRF_CLI_USES_TASK_MANAGER_ENABLED
+#define NRF_CLI_USES_TASK_MANAGER_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_fprintf - fprintf function.
+
+//==========================================================
+// <q> NRF_FPRINTF_ENABLED  - Enable/disable fprintf module.
+ 
+
+#ifndef NRF_FPRINTF_ENABLED
+#define NRF_FPRINTF_ENABLED 1
+#endif
+
+// <q> NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED  - For each printed LF, function will add CR.
+ 
+
+#ifndef NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED
+#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1
+#endif
+
+// <q> NRF_FPRINTF_DOUBLE_ENABLED  - Enable IEEE-754 double precision formatting.
+ 
+
+#ifndef NRF_FPRINTF_DOUBLE_ENABLED
+#define NRF_FPRINTF_DOUBLE_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Log 
+
+//==========================================================
+// <e> NRF_LOG_ENABLED - nrf_log - Logger
+//==========================================================
+#ifndef NRF_LOG_ENABLED
+#define NRF_LOG_ENABLED 0
+#endif
+// <h> Log message pool - Configuration of log message pool
+
+//==========================================================
+// <o> NRF_LOG_MSGPOOL_ELEMENT_SIZE - Size of a single element in the pool of memory objects. 
+// <i> If a small value is set, then performance of logs processing
+// <i> is degraded because data is fragmented. Bigger value impacts
+// <i> RAM memory utilization. The size is set to fit a message with
+// <i> a timestamp and up to 2 arguments in a single memory object.
+
+#ifndef NRF_LOG_MSGPOOL_ELEMENT_SIZE
+#define NRF_LOG_MSGPOOL_ELEMENT_SIZE 20
+#endif
+
+// <o> NRF_LOG_MSGPOOL_ELEMENT_COUNT - Number of elements in the pool of memory objects 
+// <i> If a small value is set, then it may lead to a deadlock
+// <i> in certain cases if backend has high latency and holds
+// <i> multiple messages for long time. Bigger value impacts
+// <i> RAM memory usage.
+
+#ifndef NRF_LOG_MSGPOOL_ELEMENT_COUNT
+#define NRF_LOG_MSGPOOL_ELEMENT_COUNT 8
+#endif
+
+// </h> 
+//==========================================================
+
+// <q> NRF_LOG_ALLOW_OVERFLOW  - Configures behavior when circular buffer is full.
+ 
+
+// <i> If set then oldest logs are overwritten. Otherwise a 
+// <i> marker is injected informing about overflow.
+
+#ifndef NRF_LOG_ALLOW_OVERFLOW
+#define NRF_LOG_ALLOW_OVERFLOW 1
+#endif
+
+// <o> NRF_LOG_BUFSIZE  - Size of the buffer for storing logs (in bytes).
+ 
+
+// <i> Must be power of 2 and multiple of 4.
+// <i> If NRF_LOG_DEFERRED = 0 then buffer size can be reduced to minimum.
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+// <2048=> 2048 
+// <4096=> 4096 
+// <8192=> 8192 
+// <16384=> 16384 
+
+#ifndef NRF_LOG_BUFSIZE
+#define NRF_LOG_BUFSIZE 1024
+#endif
+
+// <q> NRF_LOG_CLI_CMDS  - Enable CLI commands for the module.
+ 
+
+#ifndef NRF_LOG_CLI_CMDS
+#define NRF_LOG_CLI_CMDS 0
+#endif
+
+// <o> NRF_LOG_DEFAULT_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_LOG_DEFAULT_LEVEL
+#define NRF_LOG_DEFAULT_LEVEL 3
+#endif
+
+// <q> NRF_LOG_DEFERRED  - Enable deffered logger.
+ 
+
+// <i> Log data is buffered and can be processed in idle.
+
+#ifndef NRF_LOG_DEFERRED
+#define NRF_LOG_DEFERRED 1
+#endif
+
+// <q> NRF_LOG_FILTERS_ENABLED  - Enable dynamic filtering of logs.
+ 
+
+#ifndef NRF_LOG_FILTERS_ENABLED
+#define NRF_LOG_FILTERS_ENABLED 0
+#endif
+
+// <q> NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED  - Enable use of critical region for non deffered mode when flushing logs.
+ 
+
+// <i> When enabled NRF_LOG_FLUSH is called from critical section when non deffered mode is used.
+// <i> Log output will never be corrupted as access to the log backend is exclusive
+// <i> but system will spend significant amount of time in critical section
+
+#ifndef NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED
+#define NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED 0
+#endif
+
+// <o> NRF_LOG_STR_PUSH_BUFFER_SIZE  - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH.
+ 
+// <16=> 16 
+// <32=> 32 
+// <64=> 64 
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+
+#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE
+#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128
+#endif
+
+// <o> NRF_LOG_STR_PUSH_BUFFER_SIZE  - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH.
+ 
+// <16=> 16 
+// <32=> 32 
+// <64=> 64 
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+
+#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE
+#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128
+#endif
+
+// <e> NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string
+//==========================================================
+#ifndef NRF_LOG_USES_COLORS
+#define NRF_LOG_USES_COLORS 0
+#endif
+// <o> NRF_LOG_COLOR_DEFAULT  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_COLOR_DEFAULT
+#define NRF_LOG_COLOR_DEFAULT 0
+#endif
+
+// <o> NRF_LOG_ERROR_COLOR  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_ERROR_COLOR
+#define NRF_LOG_ERROR_COLOR 2
+#endif
+
+// <o> NRF_LOG_WARNING_COLOR  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_WARNING_COLOR
+#define NRF_LOG_WARNING_COLOR 4
+#endif
+
+// </e>
+
+// <e> NRF_LOG_USES_TIMESTAMP - Enable timestamping
+
+// <i> Function for getting the timestamp is provided by the user
+//==========================================================
+#ifndef NRF_LOG_USES_TIMESTAMP
+#define NRF_LOG_USES_TIMESTAMP 0
+#endif
+// <o> NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY - Default frequency of the timestamp (in Hz) or 0 to use app_timer frequency. 
+#ifndef NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY
+#define NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY 0
+#endif
+
+// </e>
+
+// <h> nrf_log module configuration 
+
+//==========================================================
+// <h> nrf_log in nRF_Core 
+
+//==========================================================
+// <e> NRF_MPU_LIB_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_MPU_LIB_CONFIG_LOG_ENABLED
+#define NRF_MPU_LIB_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_MPU_LIB_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_MPU_LIB_CONFIG_LOG_LEVEL
+#define NRF_MPU_LIB_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_MPU_LIB_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 NRF_MPU_LIB_CONFIG_INFO_COLOR
+#define NRF_MPU_LIB_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_MPU_LIB_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 NRF_MPU_LIB_CONFIG_DEBUG_COLOR
+#define NRF_MPU_LIB_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_STACK_GUARD_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_STACK_GUARD_CONFIG_LOG_ENABLED
+#define NRF_STACK_GUARD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_STACK_GUARD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_STACK_GUARD_CONFIG_LOG_LEVEL
+#define NRF_STACK_GUARD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_STACK_GUARD_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 NRF_STACK_GUARD_CONFIG_INFO_COLOR
+#define NRF_STACK_GUARD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_STACK_GUARD_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 NRF_STACK_GUARD_CONFIG_DEBUG_COLOR
+#define NRF_STACK_GUARD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TASK_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TASK_MANAGER_CONFIG_LOG_ENABLED
+#define TASK_MANAGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TASK_MANAGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TASK_MANAGER_CONFIG_LOG_LEVEL
+#define TASK_MANAGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> TASK_MANAGER_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 TASK_MANAGER_CONFIG_INFO_COLOR
+#define TASK_MANAGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> TASK_MANAGER_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 TASK_MANAGER_CONFIG_DEBUG_COLOR
+#define TASK_MANAGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Drivers 
+
+//==========================================================
+// <e> CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef CLOCK_CONFIG_LOG_ENABLED
+#define CLOCK_CONFIG_LOG_ENABLED 0
+#endif
+// <o> CLOCK_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef CLOCK_CONFIG_LOG_LEVEL
+#define CLOCK_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 CLOCK_CONFIG_INFO_COLOR
+#define CLOCK_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 CLOCK_CONFIG_DEBUG_COLOR
+#define CLOCK_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> COMP_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef COMP_CONFIG_LOG_ENABLED
+#define COMP_CONFIG_LOG_ENABLED 0
+#endif
+// <o> COMP_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef COMP_CONFIG_LOG_LEVEL
+#define COMP_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 COMP_CONFIG_INFO_COLOR
+#define COMP_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 COMP_CONFIG_DEBUG_COLOR
+#define COMP_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef GPIOTE_CONFIG_LOG_ENABLED
+#define GPIOTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> GPIOTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef GPIOTE_CONFIG_LOG_LEVEL
+#define GPIOTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 GPIOTE_CONFIG_INFO_COLOR
+#define GPIOTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 GPIOTE_CONFIG_DEBUG_COLOR
+#define GPIOTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef LPCOMP_CONFIG_LOG_ENABLED
+#define LPCOMP_CONFIG_LOG_ENABLED 0
+#endif
+// <o> LPCOMP_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef LPCOMP_CONFIG_LOG_LEVEL
+#define LPCOMP_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 LPCOMP_CONFIG_INFO_COLOR
+#define LPCOMP_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 LPCOMP_CONFIG_DEBUG_COLOR
+#define LPCOMP_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> MAX3421E_HOST_CONFIG_LOG_ENABLED - Enable logging in the module
+//==========================================================
+#ifndef MAX3421E_HOST_CONFIG_LOG_ENABLED
+#define MAX3421E_HOST_CONFIG_LOG_ENABLED 0
+#endif
+// <o> MAX3421E_HOST_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef MAX3421E_HOST_CONFIG_LOG_LEVEL
+#define MAX3421E_HOST_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> MAX3421E_HOST_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 MAX3421E_HOST_CONFIG_INFO_COLOR
+#define MAX3421E_HOST_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> MAX3421E_HOST_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 MAX3421E_HOST_CONFIG_DEBUG_COLOR
+#define MAX3421E_HOST_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <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> PDM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PDM_CONFIG_LOG_ENABLED
+#define PDM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PDM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PDM_CONFIG_LOG_LEVEL
+#define PDM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 PDM_CONFIG_INFO_COLOR
+#define PDM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 PDM_CONFIG_DEBUG_COLOR
+#define PDM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PPI_CONFIG_LOG_ENABLED
+#define PPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PPI_CONFIG_LOG_LEVEL
+#define PPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> PPI_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 PPI_CONFIG_INFO_COLOR
+#define PPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> PPI_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 PPI_CONFIG_DEBUG_COLOR
+#define PPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PWM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PWM_CONFIG_LOG_ENABLED
+#define PWM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PWM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PWM_CONFIG_LOG_LEVEL
+#define PWM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 PWM_CONFIG_INFO_COLOR
+#define PWM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 PWM_CONFIG_DEBUG_COLOR
+#define PWM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> QDEC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef QDEC_CONFIG_LOG_ENABLED
+#define QDEC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> QDEC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef QDEC_CONFIG_LOG_LEVEL
+#define QDEC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 QDEC_CONFIG_INFO_COLOR
+#define QDEC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 QDEC_CONFIG_DEBUG_COLOR
+#define QDEC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> RNG_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef RNG_CONFIG_LOG_ENABLED
+#define RNG_CONFIG_LOG_ENABLED 0
+#endif
+// <o> RNG_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef RNG_CONFIG_LOG_LEVEL
+#define RNG_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> RNG_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 RNG_CONFIG_INFO_COLOR
+#define RNG_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> RNG_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 RNG_CONFIG_DEBUG_COLOR
+#define RNG_CONFIG_DEBUG_COLOR 0
+#endif
+
+// <q> RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED  - Enables logging of random numbers.
+ 
+
+#ifndef RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED
+#define RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED 0
+#endif
+
+// </e>
+
+// <e> RTC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef RTC_CONFIG_LOG_ENABLED
+#define RTC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> RTC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef RTC_CONFIG_LOG_LEVEL
+#define RTC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 RTC_CONFIG_INFO_COLOR
+#define RTC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 RTC_CONFIG_DEBUG_COLOR
+#define RTC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SAADC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SAADC_CONFIG_LOG_ENABLED
+#define SAADC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SAADC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SAADC_CONFIG_LOG_LEVEL
+#define SAADC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 SAADC_CONFIG_INFO_COLOR
+#define SAADC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 SAADC_CONFIG_DEBUG_COLOR
+#define SAADC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SPIS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SPIS_CONFIG_LOG_ENABLED
+#define SPIS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SPIS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SPIS_CONFIG_LOG_LEVEL
+#define SPIS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 SPIS_CONFIG_INFO_COLOR
+#define SPIS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 SPIS_CONFIG_DEBUG_COLOR
+#define SPIS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SPI_CONFIG_LOG_ENABLED
+#define SPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SPI_CONFIG_LOG_LEVEL
+#define SPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> SPI_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 SPI_CONFIG_INFO_COLOR
+#define SPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> SPI_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 SPI_CONFIG_DEBUG_COLOR
+#define SPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TIMER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TIMER_CONFIG_LOG_ENABLED
+#define TIMER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TIMER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TIMER_CONFIG_LOG_LEVEL
+#define TIMER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 TIMER_CONFIG_INFO_COLOR
+#define TIMER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 TIMER_CONFIG_DEBUG_COLOR
+#define TIMER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TWIS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TWIS_CONFIG_LOG_ENABLED
+#define TWIS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TWIS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TWIS_CONFIG_LOG_LEVEL
+#define TWIS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 TWIS_CONFIG_INFO_COLOR
+#define TWIS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 TWIS_CONFIG_DEBUG_COLOR
+#define TWIS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TWI_CONFIG_LOG_ENABLED
+#define TWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TWI_CONFIG_LOG_LEVEL
+#define TWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> TWI_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 TWI_CONFIG_INFO_COLOR
+#define TWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> TWI_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 TWI_CONFIG_DEBUG_COLOR
+#define TWI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef UART_CONFIG_LOG_ENABLED
+#define UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef UART_CONFIG_LOG_LEVEL
+#define UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> UART_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 UART_CONFIG_INFO_COLOR
+#define UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> UART_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 UART_CONFIG_DEBUG_COLOR
+#define UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> USBD_CONFIG_LOG_ENABLED - Enable logging in the module
+//==========================================================
+#ifndef USBD_CONFIG_LOG_ENABLED
+#define USBD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> USBD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef USBD_CONFIG_LOG_LEVEL
+#define USBD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 USBD_CONFIG_INFO_COLOR
+#define USBD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 USBD_CONFIG_DEBUG_COLOR
+#define USBD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> WDT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef WDT_CONFIG_LOG_ENABLED
+#define WDT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> WDT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef WDT_CONFIG_LOG_LEVEL
+#define WDT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 WDT_CONFIG_INFO_COLOR
+#define WDT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 WDT_CONFIG_DEBUG_COLOR
+#define WDT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Libraries 
+
+//==========================================================
+// <e> APP_BUTTON_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_BUTTON_CONFIG_LOG_ENABLED
+#define APP_BUTTON_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_BUTTON_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_BUTTON_CONFIG_LOG_LEVEL
+#define APP_BUTTON_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL
+#define APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> APP_BUTTON_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 APP_BUTTON_CONFIG_INFO_COLOR
+#define APP_BUTTON_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_BUTTON_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 APP_BUTTON_CONFIG_DEBUG_COLOR
+#define APP_BUTTON_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_TIMER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_TIMER_CONFIG_LOG_ENABLED
+#define APP_TIMER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_TIMER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_TIMER_CONFIG_LOG_LEVEL
+#define APP_TIMER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_TIMER_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_TIMER_CONFIG_INITIAL_LOG_LEVEL
+#define APP_TIMER_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> APP_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 APP_TIMER_CONFIG_INFO_COLOR
+#define APP_TIMER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_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 APP_TIMER_CONFIG_DEBUG_COLOR
+#define APP_TIMER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL
+#define APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_CDC_ACM_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 APP_USBD_CDC_ACM_CONFIG_INFO_COLOR
+#define APP_USBD_CDC_ACM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_CDC_ACM_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 APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR
+#define APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module.
+//==========================================================
+#ifndef APP_USBD_CONFIG_LOG_ENABLED
+#define APP_USBD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_CONFIG_LOG_LEVEL
+#define APP_USBD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_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 APP_USBD_CONFIG_INFO_COLOR
+#define APP_USBD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_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 APP_USBD_CONFIG_DEBUG_COLOR
+#define APP_USBD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_DUMMY_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#define APP_USBD_DUMMY_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_DUMMY_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_DUMMY_CONFIG_LOG_LEVEL
+#define APP_USBD_DUMMY_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_DUMMY_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 APP_USBD_DUMMY_CONFIG_INFO_COLOR
+#define APP_USBD_DUMMY_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_DUMMY_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 APP_USBD_DUMMY_CONFIG_DEBUG_COLOR
+#define APP_USBD_DUMMY_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_MSC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_MSC_CONFIG_LOG_ENABLED
+#define APP_USBD_MSC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_MSC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_MSC_CONFIG_LOG_LEVEL
+#define APP_USBD_MSC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_MSC_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 APP_USBD_MSC_CONFIG_INFO_COLOR
+#define APP_USBD_MSC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_MSC_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 APP_USBD_MSC_CONFIG_DEBUG_COLOR
+#define APP_USBD_MSC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_NRF_DFU_TRIGGER_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 APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_NRF_DFU_TRIGGER_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 APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_ATFIFO_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_ATFIFO_CONFIG_LOG_ENABLED
+#define NRF_ATFIFO_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_ATFIFO_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_ATFIFO_CONFIG_LOG_LEVEL
+#define NRF_ATFIFO_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_ATFIFO_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 NRF_ATFIFO_CONFIG_INFO_COLOR
+#define NRF_ATFIFO_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_ATFIFO_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 NRF_ATFIFO_CONFIG_DEBUG_COLOR
+#define NRF_ATFIFO_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BALLOC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BALLOC_CONFIG_LOG_ENABLED
+#define NRF_BALLOC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BALLOC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BALLOC_CONFIG_LOG_LEVEL
+#define NRF_BALLOC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL
+#define NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BALLOC_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 NRF_BALLOC_CONFIG_INFO_COLOR
+#define NRF_BALLOC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BALLOC_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 NRF_BALLOC_CONFIG_DEBUG_COLOR
+#define NRF_BALLOC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_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 NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_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 NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_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 NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_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 NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_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 NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_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 NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#define NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL
+#define NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_BLE_UART_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 NRF_CLI_BLE_UART_CONFIG_INFO_COLOR
+#define NRF_CLI_BLE_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_BLE_UART_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 NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR
+#define NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_LIBUARTE_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 NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_LIBUARTE_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 NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR
+#define NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_UART_CONFIG_LOG_ENABLED
+#define NRF_CLI_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_UART_CONFIG_LOG_LEVEL
+#define NRF_CLI_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_UART_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 NRF_CLI_UART_CONFIG_INFO_COLOR
+#define NRF_CLI_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_UART_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 NRF_CLI_UART_CONFIG_DEBUG_COLOR
+#define NRF_CLI_UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LIBUARTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_LIBUARTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LIBUARTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_LIBUARTE_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 NRF_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LIBUARTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_LIBUARTE_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 NRF_LIBUARTE_CONFIG_DEBUG_COLOR
+#define NRF_LIBUARTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_MEMOBJ_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_MEMOBJ_CONFIG_LOG_ENABLED
+#define NRF_MEMOBJ_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_MEMOBJ_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_MEMOBJ_CONFIG_LOG_LEVEL
+#define NRF_MEMOBJ_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_MEMOBJ_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 NRF_MEMOBJ_CONFIG_INFO_COLOR
+#define NRF_MEMOBJ_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_MEMOBJ_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 NRF_MEMOBJ_CONFIG_DEBUG_COLOR
+#define NRF_MEMOBJ_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_PWR_MGMT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_LOG_ENABLED
+#define NRF_PWR_MGMT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_PWR_MGMT_CONFIG_LOG_LEVEL
+#define NRF_PWR_MGMT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_PWR_MGMT_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 NRF_PWR_MGMT_CONFIG_INFO_COLOR
+#define NRF_PWR_MGMT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_PWR_MGMT_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 NRF_PWR_MGMT_CONFIG_DEBUG_COLOR
+#define NRF_PWR_MGMT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_QUEUE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_QUEUE_CONFIG_LOG_ENABLED
+#define NRF_QUEUE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_QUEUE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_QUEUE_CONFIG_LOG_LEVEL
+#define NRF_QUEUE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_QUEUE_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 NRF_QUEUE_CONFIG_INFO_COLOR
+#define NRF_QUEUE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_QUEUE_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 NRF_QUEUE_CONFIG_DEBUG_COLOR
+#define NRF_QUEUE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_ANT_LOG_ENABLED - Enable logging in SoftDevice handler (ANT) module.
+//==========================================================
+#ifndef NRF_SDH_ANT_LOG_ENABLED
+#define NRF_SDH_ANT_LOG_ENABLED 0
+#endif
+// <o> NRF_SDH_ANT_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_ANT_LOG_LEVEL
+#define NRF_SDH_ANT_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_ANT_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 NRF_SDH_ANT_INFO_COLOR
+#define NRF_SDH_ANT_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_ANT_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 NRF_SDH_ANT_DEBUG_COLOR
+#define NRF_SDH_ANT_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_BLE_LOG_ENABLED - Enable logging in SoftDevice handler (BLE) module.
+//==========================================================
+#ifndef NRF_SDH_BLE_LOG_ENABLED
+#define NRF_SDH_BLE_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_BLE_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_BLE_LOG_LEVEL
+#define NRF_SDH_BLE_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_BLE_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 NRF_SDH_BLE_INFO_COLOR
+#define NRF_SDH_BLE_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_BLE_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 NRF_SDH_BLE_DEBUG_COLOR
+#define NRF_SDH_BLE_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_LOG_ENABLED - Enable logging in SoftDevice handler module.
+//==========================================================
+#ifndef NRF_SDH_LOG_ENABLED
+#define NRF_SDH_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_LOG_LEVEL
+#define NRF_SDH_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_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 NRF_SDH_INFO_COLOR
+#define NRF_SDH_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_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 NRF_SDH_DEBUG_COLOR
+#define NRF_SDH_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_SOC_LOG_ENABLED - Enable logging in SoftDevice handler (SoC) module.
+//==========================================================
+#ifndef NRF_SDH_SOC_LOG_ENABLED
+#define NRF_SDH_SOC_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_SOC_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_SOC_LOG_LEVEL
+#define NRF_SDH_SOC_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_SOC_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 NRF_SDH_SOC_INFO_COLOR
+#define NRF_SDH_SOC_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_SOC_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 NRF_SDH_SOC_DEBUG_COLOR
+#define NRF_SDH_SOC_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SORTLIST_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_SORTLIST_CONFIG_LOG_ENABLED
+#define NRF_SORTLIST_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_SORTLIST_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SORTLIST_CONFIG_LOG_LEVEL
+#define NRF_SORTLIST_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SORTLIST_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 NRF_SORTLIST_CONFIG_INFO_COLOR
+#define NRF_SORTLIST_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_SORTLIST_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 NRF_SORTLIST_CONFIG_DEBUG_COLOR
+#define NRF_SORTLIST_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_TWI_SENSOR_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_TWI_SENSOR_CONFIG_LOG_ENABLED
+#define NRF_TWI_SENSOR_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_TWI_SENSOR_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_TWI_SENSOR_CONFIG_LOG_LEVEL
+#define NRF_TWI_SENSOR_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_TWI_SENSOR_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 NRF_TWI_SENSOR_CONFIG_INFO_COLOR
+#define NRF_TWI_SENSOR_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_TWI_SENSOR_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 NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR
+#define NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PM_LOG_ENABLED - Enable logging in Peer Manager and its submodules.
+//==========================================================
+#ifndef PM_LOG_ENABLED
+#define PM_LOG_ENABLED 1
+#endif
+// <o> PM_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PM_LOG_LEVEL
+#define PM_LOG_LEVEL 3
+#endif
+
+// <o> PM_LOG_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 PM_LOG_INFO_COLOR
+#define PM_LOG_INFO_COLOR 0
+#endif
+
+// <o> PM_LOG_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 PM_LOG_DEBUG_COLOR
+#define PM_LOG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Serialization 
+
+//==========================================================
+// <e> SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
+#define SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL
+#define SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> SER_HAL_TRANSPORT_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 SER_HAL_TRANSPORT_CONFIG_INFO_COLOR
+#define SER_HAL_TRANSPORT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> SER_HAL_TRANSPORT_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 SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR
+#define SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED  - nrf_log_str_formatter - Log string formatter
+ 
+
+#ifndef NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED
+#define NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED 1
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_SoftDevice 
+
+//==========================================================
+// <e> NRF_SDH_BLE_ENABLED - nrf_sdh_ble - SoftDevice BLE event handler
+//==========================================================
+#ifndef NRF_SDH_BLE_ENABLED
+#define NRF_SDH_BLE_ENABLED 0
+#endif
+// <h> BLE Stack configuration - Stack configuration parameters
+
+// <i> The SoftDevice handler will configure the stack with these parameters when calling @ref nrf_sdh_ble_default_cfg_set.
+// <i> Other libraries might depend on these values; keep them up-to-date even if you are not explicitely calling @ref nrf_sdh_ble_default_cfg_set.
+//==========================================================
+// <o> NRF_SDH_BLE_GAP_DATA_LENGTH   <27-251> 
+
+
+// <i> Requested BLE GAP data length to be negotiated.
+
+#ifndef NRF_SDH_BLE_GAP_DATA_LENGTH
+#define NRF_SDH_BLE_GAP_DATA_LENGTH 27
+#endif
+
+// <o> NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - Maximum number of peripheral links. 
+#ifndef NRF_SDH_BLE_PERIPHERAL_LINK_COUNT
+#define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 0
+#endif
+
+// <o> NRF_SDH_BLE_CENTRAL_LINK_COUNT - Maximum number of central links. 
+#ifndef NRF_SDH_BLE_CENTRAL_LINK_COUNT
+#define NRF_SDH_BLE_CENTRAL_LINK_COUNT 0
+#endif
+
+// <o> NRF_SDH_BLE_TOTAL_LINK_COUNT - Total link count. 
+// <i> Maximum number of total concurrent connections using the default configuration.
+
+#ifndef NRF_SDH_BLE_TOTAL_LINK_COUNT
+#define NRF_SDH_BLE_TOTAL_LINK_COUNT 1
+#endif
+
+// <o> NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length. 
+// <i> The time set aside for this connection on every connection interval in 1.25 ms units.
+
+#ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH
+#define NRF_SDH_BLE_GAP_EVENT_LENGTH 6
+#endif
+
+// <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
+#ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
+#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 23
+#endif
+
+// <o> NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE - Attribute Table size in bytes. The size must be a multiple of 4. 
+#ifndef NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE
+#define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1408
+#endif
+
+// <o> NRF_SDH_BLE_VS_UUID_COUNT - The number of vendor-specific UUIDs. 
+#ifndef NRF_SDH_BLE_VS_UUID_COUNT
+#define NRF_SDH_BLE_VS_UUID_COUNT 0
+#endif
+
+// <q> NRF_SDH_BLE_SERVICE_CHANGED  - Include the Service Changed characteristic in the Attribute Table.
+ 
+
+#ifndef NRF_SDH_BLE_SERVICE_CHANGED
+#define NRF_SDH_BLE_SERVICE_CHANGED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> BLE Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_BLE_OBSERVER_PRIO_LEVELS - Total number of priority levels for BLE observers. 
+// <i> This setting configures the number of priority levels available for BLE event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_BLE_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_BLE_OBSERVER_PRIO_LEVELS 4
+#endif
+
+// <h> BLE Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> BLE_ADV_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Advertising module.
+
+#ifndef BLE_ADV_BLE_OBSERVER_PRIO
+#define BLE_ADV_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_ANCS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Apple Notification Service Client.
+
+#ifndef BLE_ANCS_C_BLE_OBSERVER_PRIO
+#define BLE_ANCS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_ANS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Alert Notification Service Client.
+
+#ifndef BLE_ANS_C_BLE_OBSERVER_PRIO
+#define BLE_ANS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BAS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Battery Service.
+
+#ifndef BLE_BAS_BLE_OBSERVER_PRIO
+#define BLE_BAS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BAS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Battery Service Client.
+
+#ifndef BLE_BAS_C_BLE_OBSERVER_PRIO
+#define BLE_BAS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BPS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Blood Pressure Service.
+
+#ifndef BLE_BPS_BLE_OBSERVER_PRIO
+#define BLE_BPS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_CONN_PARAMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Connection parameters module.
+
+#ifndef BLE_CONN_PARAMS_BLE_OBSERVER_PRIO
+#define BLE_CONN_PARAMS_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_CONN_STATE_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Connection State module.
+
+#ifndef BLE_CONN_STATE_BLE_OBSERVER_PRIO
+#define BLE_CONN_STATE_BLE_OBSERVER_PRIO 0
+#endif
+
+// <o> BLE_CSCS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Cycling Speed and Cadence Service.
+
+#ifndef BLE_CSCS_BLE_OBSERVER_PRIO
+#define BLE_CSCS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_CTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Current Time Service Client.
+
+#ifndef BLE_CTS_C_BLE_OBSERVER_PRIO
+#define BLE_CTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_DB_DISC_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Database Discovery module.
+
+#ifndef BLE_DB_DISC_BLE_OBSERVER_PRIO
+#define BLE_DB_DISC_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_DFU_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the DFU Service.
+
+#ifndef BLE_DFU_BLE_OBSERVER_PRIO
+#define BLE_DFU_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_DIS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Device Information Client.
+
+#ifndef BLE_DIS_C_BLE_OBSERVER_PRIO
+#define BLE_DIS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_GLS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Glucose Service.
+
+#ifndef BLE_GLS_BLE_OBSERVER_PRIO
+#define BLE_GLS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HIDS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Human Interface Device Service.
+
+#ifndef BLE_HIDS_BLE_OBSERVER_PRIO
+#define BLE_HIDS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HRS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Heart Rate Service.
+
+#ifndef BLE_HRS_BLE_OBSERVER_PRIO
+#define BLE_HRS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HRS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Heart Rate Service Client.
+
+#ifndef BLE_HRS_C_BLE_OBSERVER_PRIO
+#define BLE_HRS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HTS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Health Thermometer Service.
+
+#ifndef BLE_HTS_BLE_OBSERVER_PRIO
+#define BLE_HTS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_IAS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Immediate Alert Service.
+
+#ifndef BLE_IAS_BLE_OBSERVER_PRIO
+#define BLE_IAS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_IAS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Immediate Alert Service Client.
+
+#ifndef BLE_IAS_C_BLE_OBSERVER_PRIO
+#define BLE_IAS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LBS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the LED Button Service.
+
+#ifndef BLE_LBS_BLE_OBSERVER_PRIO
+#define BLE_LBS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LBS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the LED Button Service Client.
+
+#ifndef BLE_LBS_C_BLE_OBSERVER_PRIO
+#define BLE_LBS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LLS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Link Loss Service.
+
+#ifndef BLE_LLS_BLE_OBSERVER_PRIO
+#define BLE_LLS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LNS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Location Navigation Service.
+
+#ifndef BLE_LNS_BLE_OBSERVER_PRIO
+#define BLE_LNS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_NUS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the UART Service.
+
+#ifndef BLE_NUS_BLE_OBSERVER_PRIO
+#define BLE_NUS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_NUS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the UART Central Service.
+
+#ifndef BLE_NUS_C_BLE_OBSERVER_PRIO
+#define BLE_NUS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_OTS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Object transfer service.
+
+#ifndef BLE_OTS_BLE_OBSERVER_PRIO
+#define BLE_OTS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_OTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Object transfer service client.
+
+#ifndef BLE_OTS_C_BLE_OBSERVER_PRIO
+#define BLE_OTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_RSCS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Running Speed and Cadence Service.
+
+#ifndef BLE_RSCS_BLE_OBSERVER_PRIO
+#define BLE_RSCS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_RSCS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Running Speed and Cadence Client.
+
+#ifndef BLE_RSCS_C_BLE_OBSERVER_PRIO
+#define BLE_RSCS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_TPS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the TX Power Service.
+
+#ifndef BLE_TPS_BLE_OBSERVER_PRIO
+#define BLE_TPS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BSP_BTN_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Button Control module.
+
+#ifndef BSP_BTN_BLE_OBSERVER_PRIO
+#define BSP_BTN_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_BMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Bond Management Service.
+
+#ifndef NRF_BLE_BMS_BLE_OBSERVER_PRIO
+#define NRF_BLE_BMS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_CGMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Contiuon Glucose Monitoring Service.
+
+#ifndef NRF_BLE_CGMS_BLE_OBSERVER_PRIO
+#define NRF_BLE_CGMS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_ES_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Eddystone module.
+
+#ifndef NRF_BLE_ES_BLE_OBSERVER_PRIO
+#define NRF_BLE_ES_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT Service Client.
+
+#ifndef NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO
+#define NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_GATT_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT module.
+
+#ifndef NRF_BLE_GATT_BLE_OBSERVER_PRIO
+#define NRF_BLE_GATT_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_GQ_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT Queue module.
+
+#ifndef NRF_BLE_GQ_BLE_OBSERVER_PRIO
+#define NRF_BLE_GQ_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_QWR_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Queued writes module.
+
+#ifndef NRF_BLE_QWR_BLE_OBSERVER_PRIO
+#define NRF_BLE_QWR_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_SCAN_OBSERVER_PRIO  
+// <i> Priority for dispatching the BLE events to the Scanning Module.
+
+#ifndef NRF_BLE_SCAN_OBSERVER_PRIO
+#define NRF_BLE_SCAN_OBSERVER_PRIO 1
+#endif
+
+// <o> PM_BLE_OBSERVER_PRIO - Priority with which BLE events are dispatched to the Peer Manager module. 
+#ifndef PM_BLE_OBSERVER_PRIO
+#define PM_BLE_OBSERVER_PRIO 1
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// <e> NRF_SDH_ENABLED - nrf_sdh - SoftDevice handler
+//==========================================================
+#ifndef NRF_SDH_ENABLED
+#define NRF_SDH_ENABLED 0
+#endif
+// <h> Dispatch model 
+
+// <i> This setting configures how Stack events are dispatched to the application.
+//==========================================================
+// <o> NRF_SDH_DISPATCH_MODEL
+ 
+
+// <i> NRF_SDH_DISPATCH_MODEL_INTERRUPT: SoftDevice events are passed to the application from the interrupt context.
+// <i> NRF_SDH_DISPATCH_MODEL_APPSH: SoftDevice events are scheduled using @ref app_scheduler.
+// <i> NRF_SDH_DISPATCH_MODEL_POLLING: SoftDevice events are to be fetched manually.
+// <0=> NRF_SDH_DISPATCH_MODEL_INTERRUPT 
+// <1=> NRF_SDH_DISPATCH_MODEL_APPSH 
+// <2=> NRF_SDH_DISPATCH_MODEL_POLLING 
+
+#ifndef NRF_SDH_DISPATCH_MODEL
+#define NRF_SDH_DISPATCH_MODEL 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Clock - SoftDevice clock configuration
+
+//==========================================================
+// <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
+ 
+// <0=> NRF_CLOCK_LF_SRC_RC 
+// <1=> NRF_CLOCK_LF_SRC_XTAL 
+// <2=> NRF_CLOCK_LF_SRC_SYNTH 
+
+#ifndef NRF_SDH_CLOCK_LF_SRC
+#define NRF_SDH_CLOCK_LF_SRC 1
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
+#ifndef NRF_SDH_CLOCK_LF_RC_CTIV
+#define NRF_SDH_CLOCK_LF_RC_CTIV 0
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
+// <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
+// <i>  if the temperature has not changed.
+
+#ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
+#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
+ 
+// <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
+// <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
+// <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
+// <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
+// <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
+// <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
+// <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
+// <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
+// <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
+// <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
+// <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
+// <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
+
+#ifndef NRF_SDH_CLOCK_LF_ACCURACY
+#define NRF_SDH_CLOCK_LF_ACCURACY 7
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> SDH Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_REQ_OBSERVER_PRIO_LEVELS - Total number of priority levels for request observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice request event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_REQ_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_REQ_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <o> NRF_SDH_STATE_OBSERVER_PRIO_LEVELS - Total number of priority levels for state observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice state event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_STATE_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_STATE_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <o> NRF_SDH_STACK_OBSERVER_PRIO_LEVELS - Total number of priority levels for stack event observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice stack event handlers (ANT, BLE, SoC).
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_STACK_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_STACK_OBSERVER_PRIO_LEVELS 2
+#endif
+
+
+// <h> State Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> CLOCK_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to the Clock driver.
+
+#ifndef CLOCK_CONFIG_STATE_OBSERVER_PRIO
+#define CLOCK_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// <o> POWER_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to the Power driver.
+
+#ifndef POWER_CONFIG_STATE_OBSERVER_PRIO
+#define POWER_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// <o> RNG_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to this module.
+
+#ifndef RNG_CONFIG_STATE_OBSERVER_PRIO
+#define RNG_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Stack Event Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> NRF_SDH_ANT_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which ANT events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have ANT events dispatched before or after other stack events, such as BLE or SoC.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_ANT_STACK_OBSERVER_PRIO
+#define NRF_SDH_ANT_STACK_OBSERVER_PRIO 0
+#endif
+
+// <o> NRF_SDH_BLE_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which BLE events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have BLE events dispatched before or after other stack events, such as ANT or SoC.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_BLE_STACK_OBSERVER_PRIO
+#define NRF_SDH_BLE_STACK_OBSERVER_PRIO 0
+#endif
+
+// <o> NRF_SDH_SOC_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which SoC events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have SoC events dispatched before or after other stack events, such as ANT or BLE.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_SOC_STACK_OBSERVER_PRIO
+#define NRF_SDH_SOC_STACK_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// <e> NRF_SDH_SOC_ENABLED - nrf_sdh_soc - SoftDevice SoC event handler
+//==========================================================
+#ifndef NRF_SDH_SOC_ENABLED
+#define NRF_SDH_SOC_ENABLED 0
+#endif
+// <h> SoC Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_SOC_OBSERVER_PRIO_LEVELS - Total number of priority levels for SoC observers. 
+// <i> This setting configures the number of priority levels available for the SoC event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_SOC_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_SOC_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <h> SoC Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> BLE_DFU_SOC_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the DFU Service.
+
+#ifndef BLE_DFU_SOC_OBSERVER_PRIO
+#define BLE_DFU_SOC_OBSERVER_PRIO 1
+#endif
+
+// <o> CLOCK_CONFIG_SOC_OBSERVER_PRIO  
+// <i> Priority with which SoC events are dispatched to the Clock driver.
+
+#ifndef CLOCK_CONFIG_SOC_OBSERVER_PRIO
+#define CLOCK_CONFIG_SOC_OBSERVER_PRIO 0
+#endif
+
+// <o> POWER_CONFIG_SOC_OBSERVER_PRIO  
+// <i> Priority with which SoC events are dispatched to the Power driver.
+
+#ifndef POWER_CONFIG_SOC_OBSERVER_PRIO
+#define POWER_CONFIG_SOC_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <<< end of configuration section >>>
+#endif //SDK_CONFIG_H
+
diff --git a/third_party/NordicSemiconductor/config/nrf52833/config/sdk_config.h b/third_party/NordicSemiconductor/config/nrf52833/config/sdk_config.h
new file mode 100644
index 0000000..13eb3be
--- /dev/null
+++ b/third_party/NordicSemiconductor/config/nrf52833/config/sdk_config.h
@@ -0,0 +1,11576 @@
+/**
+ * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ *    Semiconductor ASA integrated circuit in a product or a software update for
+ *    such product, must reproduce the above copyright notice, this list of
+ *    conditions and the following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ *    Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ *    engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+
+#ifndef SDK_CONFIG_H
+#define SDK_CONFIG_H
+// <<< Use Configuration Wizard in Context Menu >>>\n
+#ifdef USE_APP_CONFIG
+#include "app_config.h"
+#endif
+// <h> nRF_BLE 
+
+//==========================================================
+// <q> BLE_ADVERTISING_ENABLED  - ble_advertising - Advertising module
+ 
+
+#ifndef BLE_ADVERTISING_ENABLED
+#define BLE_ADVERTISING_ENABLED 0
+#endif
+
+// <q> BLE_DTM_ENABLED  - ble_dtm - Module for testing RF/PHY using DTM commands
+ 
+
+#ifndef BLE_DTM_ENABLED
+#define BLE_DTM_ENABLED 0
+#endif
+
+// <q> BLE_RACP_ENABLED  - ble_racp - Record Access Control Point library
+ 
+
+#ifndef BLE_RACP_ENABLED
+#define BLE_RACP_ENABLED 0
+#endif
+
+// <e> NRF_BLE_QWR_ENABLED - nrf_ble_qwr - Queued writes support module (prepare/execute write)
+//==========================================================
+#ifndef NRF_BLE_QWR_ENABLED
+#define NRF_BLE_QWR_ENABLED 0
+#endif
+// <o> NRF_BLE_QWR_MAX_ATTR - Maximum number of attribute handles that can be registered. This number must be adjusted according to the number of attributes for which Queued Writes will be enabled. If it is zero, the module will reject all Queued Write requests. 
+#ifndef NRF_BLE_QWR_MAX_ATTR
+#define NRF_BLE_QWR_MAX_ATTR 0
+#endif
+
+// </e>
+
+// <e> PEER_MANAGER_ENABLED - peer_manager - Peer Manager
+//==========================================================
+#ifndef PEER_MANAGER_ENABLED
+#define PEER_MANAGER_ENABLED 0
+#endif
+// <o> PM_MAX_REGISTRANTS - Number of event handlers that can be registered. 
+#ifndef PM_MAX_REGISTRANTS
+#define PM_MAX_REGISTRANTS 3
+#endif
+
+// <o> PM_FLASH_BUFFERS - Number of internal buffers for flash operations. 
+// <i> Decrease this value to lower RAM usage.
+
+#ifndef PM_FLASH_BUFFERS
+#define PM_FLASH_BUFFERS 4
+#endif
+
+// <q> PM_CENTRAL_ENABLED  - Enable/disable central-specific Peer Manager functionality.
+ 
+
+// <i> Enable/disable central-specific Peer Manager functionality.
+
+#ifndef PM_CENTRAL_ENABLED
+#define PM_CENTRAL_ENABLED 1
+#endif
+
+// <q> PM_SERVICE_CHANGED_ENABLED  - Enable/disable the service changed management for GATT server in Peer Manager.
+ 
+
+// <i> If not using a GATT server, or using a server wihout a service changed characteristic,
+// <i> disable this to save code space.
+
+#ifndef PM_SERVICE_CHANGED_ENABLED
+#define PM_SERVICE_CHANGED_ENABLED 1
+#endif
+
+// <q> PM_PEER_RANKS_ENABLED  - Enable/disable the peer rank management in Peer Manager.
+ 
+
+// <i> Set this to false to save code space if not using the peer rank API.
+
+#ifndef PM_PEER_RANKS_ENABLED
+#define PM_PEER_RANKS_ENABLED 1
+#endif
+
+// <q> PM_LESC_ENABLED  - Enable/disable LESC support in Peer Manager.
+ 
+
+// <i> If set to true, you need to call nrf_ble_lesc_request_handler() in the main loop to respond to LESC-related BLE events. If LESC support is not required, set this to false to save code space.
+
+#ifndef PM_LESC_ENABLED
+#define PM_LESC_ENABLED 0
+#endif
+
+// <e> PM_RA_PROTECTION_ENABLED - Enable/disable protection against repeated pairing attempts in Peer Manager.
+//==========================================================
+#ifndef PM_RA_PROTECTION_ENABLED
+#define PM_RA_PROTECTION_ENABLED 0
+#endif
+// <o> PM_RA_PROTECTION_TRACKED_PEERS_NUM - Maximum number of peers whose authorization status can be tracked. 
+#ifndef PM_RA_PROTECTION_TRACKED_PEERS_NUM
+#define PM_RA_PROTECTION_TRACKED_PEERS_NUM 8
+#endif
+
+// <o> PM_RA_PROTECTION_MIN_WAIT_INTERVAL - Minimum waiting interval (in ms) before a new pairing attempt can be initiated. 
+#ifndef PM_RA_PROTECTION_MIN_WAIT_INTERVAL
+#define PM_RA_PROTECTION_MIN_WAIT_INTERVAL 4000
+#endif
+
+// <o> PM_RA_PROTECTION_MAX_WAIT_INTERVAL - Maximum waiting interval (in ms) before a new pairing attempt can be initiated. 
+#ifndef PM_RA_PROTECTION_MAX_WAIT_INTERVAL
+#define PM_RA_PROTECTION_MAX_WAIT_INTERVAL 64000
+#endif
+
+// <o> PM_RA_PROTECTION_REWARD_PERIOD - Reward period (in ms). 
+// <i> The waiting interval is gradually decreased when no new failed pairing attempts are made during reward period.
+
+#ifndef PM_RA_PROTECTION_REWARD_PERIOD
+#define PM_RA_PROTECTION_REWARD_PERIOD 10000
+#endif
+
+// </e>
+
+// <o> PM_HANDLER_SEC_DELAY_MS - Delay before starting security. 
+// <i>  This might be necessary for interoperability reasons, especially as peripheral.
+
+#ifndef PM_HANDLER_SEC_DELAY_MS
+#define PM_HANDLER_SEC_DELAY_MS 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_BLE_Services 
+
+//==========================================================
+// <q> BLE_ANCS_C_ENABLED  - ble_ancs_c - Apple Notification Service Client
+ 
+
+#ifndef BLE_ANCS_C_ENABLED
+#define BLE_ANCS_C_ENABLED 0
+#endif
+
+// <q> BLE_ANS_C_ENABLED  - ble_ans_c - Alert Notification Service Client
+ 
+
+#ifndef BLE_ANS_C_ENABLED
+#define BLE_ANS_C_ENABLED 0
+#endif
+
+// <q> BLE_BAS_C_ENABLED  - ble_bas_c - Battery Service Client
+ 
+
+#ifndef BLE_BAS_C_ENABLED
+#define BLE_BAS_C_ENABLED 0
+#endif
+
+// <e> BLE_BAS_ENABLED - ble_bas - Battery Service
+//==========================================================
+#ifndef BLE_BAS_ENABLED
+#define BLE_BAS_ENABLED 0
+#endif
+// <e> BLE_BAS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_BAS_CONFIG_LOG_ENABLED
+#define BLE_BAS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_BAS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_BAS_CONFIG_LOG_LEVEL
+#define BLE_BAS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_BAS_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 BLE_BAS_CONFIG_INFO_COLOR
+#define BLE_BAS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_BAS_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 BLE_BAS_CONFIG_DEBUG_COLOR
+#define BLE_BAS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_CSCS_ENABLED  - ble_cscs - Cycling Speed and Cadence Service
+ 
+
+#ifndef BLE_CSCS_ENABLED
+#define BLE_CSCS_ENABLED 0
+#endif
+
+// <q> BLE_CTS_C_ENABLED  - ble_cts_c - Current Time Service Client
+ 
+
+#ifndef BLE_CTS_C_ENABLED
+#define BLE_CTS_C_ENABLED 0
+#endif
+
+// <q> BLE_DIS_ENABLED  - ble_dis - Device Information Service
+ 
+
+#ifndef BLE_DIS_ENABLED
+#define BLE_DIS_ENABLED 0
+#endif
+
+// <q> BLE_GLS_ENABLED  - ble_gls - Glucose Service
+ 
+
+#ifndef BLE_GLS_ENABLED
+#define BLE_GLS_ENABLED 0
+#endif
+
+// <q> BLE_HIDS_ENABLED  - ble_hids - Human Interface Device Service
+ 
+
+#ifndef BLE_HIDS_ENABLED
+#define BLE_HIDS_ENABLED 0
+#endif
+
+// <q> BLE_HRS_C_ENABLED  - ble_hrs_c - Heart Rate Service Client
+ 
+
+#ifndef BLE_HRS_C_ENABLED
+#define BLE_HRS_C_ENABLED 0
+#endif
+
+// <q> BLE_HRS_ENABLED  - ble_hrs - Heart Rate Service
+ 
+
+#ifndef BLE_HRS_ENABLED
+#define BLE_HRS_ENABLED 0
+#endif
+
+// <q> BLE_HTS_ENABLED  - ble_hts - Health Thermometer Service
+ 
+
+#ifndef BLE_HTS_ENABLED
+#define BLE_HTS_ENABLED 0
+#endif
+
+// <q> BLE_IAS_C_ENABLED  - ble_ias_c - Immediate Alert Service Client
+ 
+
+#ifndef BLE_IAS_C_ENABLED
+#define BLE_IAS_C_ENABLED 0
+#endif
+
+// <e> BLE_IAS_ENABLED - ble_ias - Immediate Alert Service
+//==========================================================
+#ifndef BLE_IAS_ENABLED
+#define BLE_IAS_ENABLED 0
+#endif
+// <e> BLE_IAS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_IAS_CONFIG_LOG_ENABLED
+#define BLE_IAS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_IAS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_IAS_CONFIG_LOG_LEVEL
+#define BLE_IAS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_IAS_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 BLE_IAS_CONFIG_INFO_COLOR
+#define BLE_IAS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_IAS_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 BLE_IAS_CONFIG_DEBUG_COLOR
+#define BLE_IAS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_LBS_C_ENABLED  - ble_lbs_c - Nordic LED Button Service Client
+ 
+
+#ifndef BLE_LBS_C_ENABLED
+#define BLE_LBS_C_ENABLED 0
+#endif
+
+// <q> BLE_LBS_ENABLED  - ble_lbs - LED Button Service
+ 
+
+#ifndef BLE_LBS_ENABLED
+#define BLE_LBS_ENABLED 0
+#endif
+
+// <q> BLE_LLS_ENABLED  - ble_lls - Link Loss Service
+ 
+
+#ifndef BLE_LLS_ENABLED
+#define BLE_LLS_ENABLED 0
+#endif
+
+// <q> BLE_NUS_C_ENABLED  - ble_nus_c - Nordic UART Central Service
+ 
+
+#ifndef BLE_NUS_C_ENABLED
+#define BLE_NUS_C_ENABLED 0
+#endif
+
+// <e> BLE_NUS_ENABLED - ble_nus - Nordic UART Service
+//==========================================================
+#ifndef BLE_NUS_ENABLED
+#define BLE_NUS_ENABLED 0
+#endif
+// <e> BLE_NUS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_NUS_CONFIG_LOG_ENABLED
+#define BLE_NUS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_NUS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_NUS_CONFIG_LOG_LEVEL
+#define BLE_NUS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_NUS_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 BLE_NUS_CONFIG_INFO_COLOR
+#define BLE_NUS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_NUS_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 BLE_NUS_CONFIG_DEBUG_COLOR
+#define BLE_NUS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_RSCS_C_ENABLED  - ble_rscs_c - Running Speed and Cadence Client
+ 
+
+#ifndef BLE_RSCS_C_ENABLED
+#define BLE_RSCS_C_ENABLED 0
+#endif
+
+// <q> BLE_RSCS_ENABLED  - ble_rscs - Running Speed and Cadence Service
+ 
+
+#ifndef BLE_RSCS_ENABLED
+#define BLE_RSCS_ENABLED 0
+#endif
+
+// <q> BLE_TPS_ENABLED  - ble_tps - TX Power Service
+ 
+
+#ifndef BLE_TPS_ENABLED
+#define BLE_TPS_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Core 
+
+//==========================================================
+// <e> NRF_MPU_LIB_ENABLED - nrf_mpu_lib - Module for MPU
+//==========================================================
+#ifndef NRF_MPU_LIB_ENABLED
+#define NRF_MPU_LIB_ENABLED 0
+#endif
+// <q> NRF_MPU_LIB_CLI_CMDS  - Enable CLI commands specific to the module.
+ 
+
+#ifndef NRF_MPU_LIB_CLI_CMDS
+#define NRF_MPU_LIB_CLI_CMDS 0
+#endif
+
+// </e>
+
+// <e> NRF_STACK_GUARD_ENABLED - nrf_stack_guard - Stack guard
+//==========================================================
+#ifndef NRF_STACK_GUARD_ENABLED
+#define NRF_STACK_GUARD_ENABLED 0
+#endif
+// <o> NRF_STACK_GUARD_CONFIG_SIZE  - Size of the stack guard.
+ 
+// <5=> 32 bytes 
+// <6=> 64 bytes 
+// <7=> 128 bytes 
+// <8=> 256 bytes 
+// <9=> 512 bytes 
+// <10=> 1024 bytes 
+// <11=> 2048 bytes 
+// <12=> 4096 bytes 
+
+#ifndef NRF_STACK_GUARD_CONFIG_SIZE
+#define NRF_STACK_GUARD_CONFIG_SIZE 7
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Crypto 
+
+//==========================================================
+// <e> NRF_CRYPTO_ENABLED - nrf_crypto - Cryptography library.
+//==========================================================
+#ifndef NRF_CRYPTO_ENABLED
+#define NRF_CRYPTO_ENABLED 1
+#endif
+// <o> NRF_CRYPTO_ALLOCATOR  - Memory allocator
+ 
+
+// <i> Choose memory allocator used by nrf_crypto. Default is alloca if possible or nrf_malloc otherwise. If 'User macros' are selected, the user has to create 'nrf_crypto_allocator.h' file that contains NRF_CRYPTO_ALLOC, NRF_CRYPTO_FREE, and NRF_CRYPTO_ALLOC_ON_STACK.
+// <0=> Default 
+// <1=> User macros 
+// <2=> On stack (alloca) 
+// <3=> C dynamic memory (malloc) 
+// <4=> SDK Memory Manager (nrf_malloc) 
+
+#ifndef NRF_CRYPTO_ALLOCATOR
+#define NRF_CRYPTO_ALLOCATOR 0
+#endif
+
+// <e> NRF_CRYPTO_BACKEND_CC310_BL_ENABLED - Enable the ARM Cryptocell CC310 reduced backend.
+
+// <i> The CC310 hardware-accelerated cryptography backend with reduced functionality and footprint (only available on nRF52840).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED  - Enable the secp224r1 elliptic curve support using CC310_BL.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED 0
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED  - Enable the secp256r1 elliptic curve support using CC310_BL.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED  - CC310_BL SHA-256 hash functionality.
+ 
+
+// <i> CC310_BL backend implementation for hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED  - nrf_cc310_bl buffers to RAM before running hash operation
+ 
+
+// <i> Enabling this makes hashing of addresses in FLASH range possible. Size of buffer allocated for hashing is set by NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED 0
+#endif
+
+// <o> NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE - nrf_cc310_bl hash outputs digests in little endian 
+// <i> Makes the nrf_cc310_bl hash functions output digests in little endian format. Only for use in nRF SDK DFU!
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE 4096
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED  - Enable Interrupts while support using CC310 bl.
+ 
+
+// <i> Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_CC310_ENABLED - Enable the ARM Cryptocell CC310 backend.
+
+// <i> The CC310 hardware-accelerated cryptography backend (only available on nRF52840).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CC310_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED  - Enable the AES CBC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED  - Enable the AES CTR mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED  - Enable the AES ECB mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED  - Enable the AES CBC_MAC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED  - Enable the AES CMAC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED  - Enable the AES CCM mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED  - Enable the AES CCM* mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED  - Enable the CHACHA-POLY mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED  - Enable the secp160r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED  - Enable the secp160r2 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED  - Enable the secp192r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED  - Enable the secp224r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED  - Enable the secp256r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED  - Enable the secp384r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED  - Enable the secp521r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED  - Enable the secp160k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED  - Enable the secp192k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED  - Enable the secp224k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED  - Enable the secp256k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED  - Enable the Curve25519 curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED  - Enable the Ed25519 curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED  - CC310 SHA-256 hash functionality.
+ 
+
+// <i> CC310 backend implementation for hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED  - CC310 SHA-512 hash functionality
+ 
+
+// <i> CC310 backend implementation for SHA-512 (in software).
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED  - CC310 HMAC using SHA-256
+ 
+
+// <i> CC310 backend implementation for HMAC using hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED  - CC310 HMAC using SHA-512
+ 
+
+// <i> CC310 backend implementation for HMAC using SHA-512 (in software).
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED  - Enable RNG support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED  - Enable Interrupts while support using CC310.
+ 
+
+// <i> Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_CIFRA_ENABLED - Enable the Cifra backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CIFRA_ENABLED
+#define NRF_CRYPTO_BACKEND_CIFRA_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED  - Enable the AES EAX mode using Cifra.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED
+#define NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED - Enable the mbed TLS backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED  - Enable the AES CBC mode mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED  - Enable the AES CTR mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED  - Enable the AES CFB mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED  - Enable the AES ECB mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED  - Enable the AES CBC MAC mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED  - Enable the AES CMAC mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED  - Enable the AES CCM mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED  - Enable the AES GCM mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED  - Enable secp192r1 (NIST 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192r1 (NIST 192-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED  - Enable secp224r1 (NIST 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224r1 (NIST 224-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED  - Enable secp256r1 (NIST 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256r1 (NIST 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED  - Enable secp384r1 (NIST 384-bit) curve
+ 
+
+// <i> Enable this setting if you need secp384r1 (NIST 384-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED  - Enable secp521r1 (NIST 521-bit) curve
+ 
+
+// <i> Enable this setting if you need secp521r1 (NIST 521-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED  - Enable secp192k1 (Koblitz 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192k1 (Koblitz 192-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED  - Enable secp224k1 (Koblitz 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224k1 (Koblitz 224-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED  - Enable secp256k1 (Koblitz 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256k1 (Koblitz 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED  - Enable bp256r1 (Brainpool 256-bit) curve
+ 
+
+// <i> Enable this setting if you need bp256r1 (Brainpool 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED  - Enable bp384r1 (Brainpool 384-bit) curve
+ 
+
+// <i> Enable this setting if you need bp384r1 (Brainpool 384-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED  - Enable bp512r1 (Brainpool 512-bit) curve
+ 
+
+// <i> Enable this setting if you need bp512r1 (Brainpool 512-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED  - Enable Curve25519 curve
+ 
+
+// <i> Enable this setting if you need Curve25519 support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED  - Enable mbed TLS SHA-256 hash functionality.
+ 
+
+// <i> mbed TLS backend implementation for SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED  - Enable mbed TLS SHA-512 hash functionality.
+ 
+
+// <i> mbed TLS backend implementation for SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED  - Enable mbed TLS HMAC using SHA-256.
+ 
+
+// <i> mbed TLS backend implementation for HMAC using SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED  - Enable mbed TLS HMAC using SHA-512.
+ 
+
+// <i> mbed TLS backend implementation for HMAC using SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED - Enable the micro-ecc backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED  - Enable secp192r1 (NIST 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192r1 (NIST 192-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED  - Enable secp224r1 (NIST 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224r1 (NIST 224-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED  - Enable secp256r1 (NIST 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256r1 (NIST 256-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED  - Enable secp256k1 (Koblitz 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256k1 (Koblitz 256-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED - Enable the nRF HW RNG backend.
+
+// <i> The nRF HW backend provide access to RNG peripheral in nRF5x devices.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED  - Enable mbed TLS CTR-DRBG algorithm.
+ 
+
+// <i> Enable mbed TLS CTR-DRBG standardized by NIST (NIST SP 800-90A Rev. 1). The nRF HW RNG is used as an entropy source for seeding.
+
+#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_NRF_SW_ENABLED - Enable the legacy nRFx sw for crypto.
+
+// <i> The nRF SW cryptography backend (only used in bootloader context).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_NRF_SW_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_SW_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED  - nRF SW hash backend support for SHA-256
+ 
+
+// <i> The nRF SW backend provide access to nRF SDK legacy hash implementation of SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_OBERON_ENABLED - Enable the Oberon backend
+
+// <i> The Oberon backend
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED  - Enable the CHACHA-POLY mode using Oberon.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED  - Enable secp256r1 curve
+ 
+
+// <i> Enable this setting if you need secp256r1 curve support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED  - Enable Curve25519 ECDH
+ 
+
+// <i> Enable this setting if you need Curve25519 ECDH support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED  - Enable Ed25519 signature scheme
+ 
+
+// <i> Enable this setting if you need Ed25519 support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED  - Oberon SHA-256 hash functionality
+ 
+
+// <i> Oberon backend implementation for SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED  - Oberon SHA-512 hash functionality
+ 
+
+// <i> Oberon backend implementation for SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED  - Oberon HMAC using SHA-256
+ 
+
+// <i> Oberon backend implementation for HMAC using SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED  - Oberon HMAC using SHA-512
+ 
+
+// <i> Oberon backend implementation for HMAC using SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_OPTIGA_ENABLED - Enable the nrf_crypto Optiga Trust X backend.
+
+// <i> Enables the nrf_crypto backend for Optiga Trust X devices.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED  - Optiga backend support for RNG
+ 
+
+// <i> The Optiga backend provide external chip RNG.
+
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED 0
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED  - Optiga backend support for ECC secp256r1
+ 
+
+// <i> The Optiga backend provide external chip ECC using secp256r1.
+
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED 1
+#endif
+
+// </e>
+
+// <q> NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED  - Big-endian byte order in raw Curve25519 data
+ 
+
+// <i> Enable big-endian byte order in Curve25519 API, if set to 1. Use little-endian, if set to 0.
+
+#ifndef NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED
+#define NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_DFU 
+
+//==========================================================
+// <h> ble_dfu - Device Firmware Update
+
+//==========================================================
+// <q> BLE_DFU_ENABLED  - Enable DFU Service.
+ 
+
+#ifndef BLE_DFU_ENABLED
+#define BLE_DFU_ENABLED 0
+#endif
+
+// <q> NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS  - Buttonless DFU supports bonds.
+ 
+
+#ifndef NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS
+#define NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Drivers 
+
+//==========================================================
+// <e> COMP_ENABLED - nrf_drv_comp - COMP peripheral driver - legacy layer
+//==========================================================
+#ifndef COMP_ENABLED
+#define COMP_ENABLED 0
+#endif
+// <o> COMP_CONFIG_REF  - Reference voltage
+ 
+// <0=> Internal 1.2V 
+// <1=> Internal 1.8V 
+// <2=> Internal 2.4V 
+// <4=> VDD 
+// <7=> ARef 
+
+#ifndef COMP_CONFIG_REF
+#define COMP_CONFIG_REF 1
+#endif
+
+// <o> COMP_CONFIG_MAIN_MODE  - Main mode
+ 
+// <0=> Single ended 
+// <1=> Differential 
+
+#ifndef COMP_CONFIG_MAIN_MODE
+#define COMP_CONFIG_MAIN_MODE 0
+#endif
+
+// <o> COMP_CONFIG_SPEED_MODE  - Speed mode
+ 
+// <0=> Low power 
+// <1=> Normal 
+// <2=> High speed 
+
+#ifndef COMP_CONFIG_SPEED_MODE
+#define COMP_CONFIG_SPEED_MODE 2
+#endif
+
+// <o> COMP_CONFIG_HYST  - Hystheresis
+ 
+// <0=> No 
+// <1=> 50mV 
+
+#ifndef COMP_CONFIG_HYST
+#define COMP_CONFIG_HYST 0
+#endif
+
+// <o> COMP_CONFIG_ISOURCE  - Current Source
+ 
+// <0=> Off 
+// <1=> 2.5 uA 
+// <2=> 5 uA 
+// <3=> 10 uA 
+
+#ifndef COMP_CONFIG_ISOURCE
+#define COMP_CONFIG_ISOURCE 0
+#endif
+
+// <o> COMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef COMP_CONFIG_INPUT
+#define COMP_CONFIG_INPUT 0
+#endif
+
+// <o> COMP_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef COMP_CONFIG_IRQ_PRIORITY
+#define COMP_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <q> EGU_ENABLED  - nrf_drv_swi - SWI(EGU) peripheral driver - legacy layer
+ 
+
+#ifndef EGU_ENABLED
+#define EGU_ENABLED 0
+#endif
+
+// <e> GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver - legacy layer
+//==========================================================
+#ifndef GPIOTE_ENABLED
+#define GPIOTE_ENABLED 0
+#endif
+// <o> GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins 
+#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS
+#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1
+#endif
+
+// <o> GPIOTE_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef GPIOTE_CONFIG_IRQ_PRIORITY
+#define GPIOTE_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> I2S_ENABLED - nrf_drv_i2s - I2S peripheral driver - legacy layer
+//==========================================================
+#ifndef I2S_ENABLED
+#define I2S_ENABLED 0
+#endif
+// <o> I2S_CONFIG_SCK_PIN - SCK pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SCK_PIN
+#define I2S_CONFIG_SCK_PIN 31
+#endif
+
+// <o> I2S_CONFIG_LRCK_PIN - LRCK pin  <1-31> 
+
+
+#ifndef I2S_CONFIG_LRCK_PIN
+#define I2S_CONFIG_LRCK_PIN 30
+#endif
+
+// <o> I2S_CONFIG_MCK_PIN - MCK pin 
+#ifndef I2S_CONFIG_MCK_PIN
+#define I2S_CONFIG_MCK_PIN 255
+#endif
+
+// <o> I2S_CONFIG_SDOUT_PIN - SDOUT pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SDOUT_PIN
+#define I2S_CONFIG_SDOUT_PIN 29
+#endif
+
+// <o> I2S_CONFIG_SDIN_PIN - SDIN pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SDIN_PIN
+#define I2S_CONFIG_SDIN_PIN 28
+#endif
+
+// <o> I2S_CONFIG_MASTER  - Mode
+ 
+// <0=> Master 
+// <1=> Slave 
+
+#ifndef I2S_CONFIG_MASTER
+#define I2S_CONFIG_MASTER 0
+#endif
+
+// <o> I2S_CONFIG_FORMAT  - Format
+ 
+// <0=> I2S 
+// <1=> Aligned 
+
+#ifndef I2S_CONFIG_FORMAT
+#define I2S_CONFIG_FORMAT 0
+#endif
+
+// <o> I2S_CONFIG_ALIGN  - Alignment
+ 
+// <0=> Left 
+// <1=> Right 
+
+#ifndef I2S_CONFIG_ALIGN
+#define I2S_CONFIG_ALIGN 0
+#endif
+
+// <o> I2S_CONFIG_SWIDTH  - Sample width (bits)
+ 
+// <0=> 8 
+// <1=> 16 
+// <2=> 24 
+
+#ifndef I2S_CONFIG_SWIDTH
+#define I2S_CONFIG_SWIDTH 1
+#endif
+
+// <o> I2S_CONFIG_CHANNELS  - Channels
+ 
+// <0=> Stereo 
+// <1=> Left 
+// <2=> Right 
+
+#ifndef I2S_CONFIG_CHANNELS
+#define I2S_CONFIG_CHANNELS 1
+#endif
+
+// <o> I2S_CONFIG_MCK_SETUP  - MCK behavior
+ 
+// <0=> Disabled 
+// <2147483648=> 32MHz/2 
+// <1342177280=> 32MHz/3 
+// <1073741824=> 32MHz/4 
+// <805306368=> 32MHz/5 
+// <671088640=> 32MHz/6 
+// <536870912=> 32MHz/8 
+// <402653184=> 32MHz/10 
+// <369098752=> 32MHz/11 
+// <285212672=> 32MHz/15 
+// <268435456=> 32MHz/16 
+// <201326592=> 32MHz/21 
+// <184549376=> 32MHz/23 
+// <142606336=> 32MHz/30 
+// <138412032=> 32MHz/31 
+// <134217728=> 32MHz/32 
+// <100663296=> 32MHz/42 
+// <68157440=> 32MHz/63 
+// <34340864=> 32MHz/125 
+
+#ifndef I2S_CONFIG_MCK_SETUP
+#define I2S_CONFIG_MCK_SETUP 536870912
+#endif
+
+// <o> I2S_CONFIG_RATIO  - MCK/LRCK ratio
+ 
+// <0=> 32x 
+// <1=> 48x 
+// <2=> 64x 
+// <3=> 96x 
+// <4=> 128x 
+// <5=> 192x 
+// <6=> 256x 
+// <7=> 384x 
+// <8=> 512x 
+
+#ifndef I2S_CONFIG_RATIO
+#define I2S_CONFIG_RATIO 2000
+#endif
+
+// <o> I2S_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef I2S_CONFIG_IRQ_PRIORITY
+#define I2S_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> I2S_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef I2S_CONFIG_LOG_ENABLED
+#define I2S_CONFIG_LOG_ENABLED 0
+#endif
+// <o> I2S_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef I2S_CONFIG_LOG_LEVEL
+#define I2S_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 I2S_CONFIG_INFO_COLOR
+#define I2S_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 I2S_CONFIG_DEBUG_COLOR
+#define I2S_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> LPCOMP_ENABLED - nrf_drv_lpcomp - LPCOMP peripheral driver - legacy layer
+//==========================================================
+#ifndef LPCOMP_ENABLED
+#define LPCOMP_ENABLED 0
+#endif
+// <o> LPCOMP_CONFIG_REFERENCE  - Reference voltage
+ 
+// <0=> Supply 1/8 
+// <1=> Supply 2/8 
+// <2=> Supply 3/8 
+// <3=> Supply 4/8 
+// <4=> Supply 5/8 
+// <5=> Supply 6/8 
+// <6=> Supply 7/8 
+// <8=> Supply 1/16 (nRF52) 
+// <9=> Supply 3/16 (nRF52) 
+// <10=> Supply 5/16 (nRF52) 
+// <11=> Supply 7/16 (nRF52) 
+// <12=> Supply 9/16 (nRF52) 
+// <13=> Supply 11/16 (nRF52) 
+// <14=> Supply 13/16 (nRF52) 
+// <15=> Supply 15/16 (nRF52) 
+// <7=> External Ref 0 
+// <65543=> External Ref 1 
+
+#ifndef LPCOMP_CONFIG_REFERENCE
+#define LPCOMP_CONFIG_REFERENCE 3
+#endif
+
+// <o> LPCOMP_CONFIG_DETECTION  - Detection
+ 
+// <0=> Crossing 
+// <1=> Up 
+// <2=> Down 
+
+#ifndef LPCOMP_CONFIG_DETECTION
+#define LPCOMP_CONFIG_DETECTION 2
+#endif
+
+// <o> LPCOMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef LPCOMP_CONFIG_INPUT
+#define LPCOMP_CONFIG_INPUT 0
+#endif
+
+// <q> LPCOMP_CONFIG_HYST  - Hysteresis
+ 
+
+#ifndef LPCOMP_CONFIG_HYST
+#define LPCOMP_CONFIG_HYST 0
+#endif
+
+// <o> LPCOMP_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef LPCOMP_CONFIG_IRQ_PRIORITY
+#define LPCOMP_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <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=> RC 
+// <1=> XTAL 
+// <2=> Synth 
+// <131073=> External Low Swing 
+// <196609=> External Full Swing 
+
+#ifndef NRFX_CLOCK_CONFIG_LF_SRC
+#define NRFX_CLOCK_CONFIG_LF_SRC 1
+#endif
+
+// <o> NRFX_CLOCK_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_CONFIG_IRQ_PRIORITY
+#define NRFX_CLOCK_CONFIG_IRQ_PRIORITY 6
+#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_CONFIG_REF  - Reference voltage
+ 
+// <0=> Internal 1.2V 
+// <1=> Internal 1.8V 
+// <2=> Internal 2.4V 
+// <4=> VDD 
+// <7=> ARef 
+
+#ifndef NRFX_COMP_CONFIG_REF
+#define NRFX_COMP_CONFIG_REF 1
+#endif
+
+// <o> NRFX_COMP_CONFIG_MAIN_MODE  - Main mode
+ 
+// <0=> Single ended 
+// <1=> Differential 
+
+#ifndef NRFX_COMP_CONFIG_MAIN_MODE
+#define NRFX_COMP_CONFIG_MAIN_MODE 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_SPEED_MODE  - Speed mode
+ 
+// <0=> Low power 
+// <1=> Normal 
+// <2=> High speed 
+
+#ifndef NRFX_COMP_CONFIG_SPEED_MODE
+#define NRFX_COMP_CONFIG_SPEED_MODE 2
+#endif
+
+// <o> NRFX_COMP_CONFIG_HYST  - Hystheresis
+ 
+// <0=> No 
+// <1=> 50mV 
+
+#ifndef NRFX_COMP_CONFIG_HYST
+#define NRFX_COMP_CONFIG_HYST 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_ISOURCE  - Current Source
+ 
+// <0=> Off 
+// <1=> 2.5 uA 
+// <2=> 5 uA 
+// <3=> 10 uA 
+
+#ifndef NRFX_COMP_CONFIG_ISOURCE
+#define NRFX_COMP_CONFIG_ISOURCE 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef NRFX_COMP_CONFIG_INPUT
+#define NRFX_COMP_CONFIG_INPUT 0
+#endif
+
+// <o> NRFX_COMP_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_CONFIG_IRQ_PRIORITY
+#define NRFX_COMP_CONFIG_IRQ_PRIORITY 6
+#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_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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 6
+#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_CONFIG_SCK_PIN - SCK pin  <0-31> 
+
+
+#ifndef NRFX_I2S_CONFIG_SCK_PIN
+#define NRFX_I2S_CONFIG_SCK_PIN 31
+#endif
+
+// <o> NRFX_I2S_CONFIG_LRCK_PIN - LRCK pin  <1-31> 
+
+
+#ifndef NRFX_I2S_CONFIG_LRCK_PIN
+#define NRFX_I2S_CONFIG_LRCK_PIN 30
+#endif
+
+// <o> NRFX_I2S_CONFIG_MCK_PIN - MCK pin 
+#ifndef NRFX_I2S_CONFIG_MCK_PIN
+#define NRFX_I2S_CONFIG_MCK_PIN 255
+#endif
+
+// <o> NRFX_I2S_CONFIG_SDOUT_PIN - SDOUT pin  <0-31> 
+
+
+#ifndef NRFX_I2S_CONFIG_SDOUT_PIN
+#define NRFX_I2S_CONFIG_SDOUT_PIN 29
+#endif
+
+// <o> NRFX_I2S_CONFIG_SDIN_PIN - SDIN pin  <0-31> 
+
+
+#ifndef NRFX_I2S_CONFIG_SDIN_PIN
+#define NRFX_I2S_CONFIG_SDIN_PIN 28
+#endif
+
+// <o> NRFX_I2S_CONFIG_MASTER  - Mode
+ 
+// <0=> Master 
+// <1=> Slave 
+
+#ifndef NRFX_I2S_CONFIG_MASTER
+#define NRFX_I2S_CONFIG_MASTER 0
+#endif
+
+// <o> NRFX_I2S_CONFIG_FORMAT  - Format
+ 
+// <0=> I2S 
+// <1=> Aligned 
+
+#ifndef NRFX_I2S_CONFIG_FORMAT
+#define NRFX_I2S_CONFIG_FORMAT 0
+#endif
+
+// <o> NRFX_I2S_CONFIG_ALIGN  - Alignment
+ 
+// <0=> Left 
+// <1=> Right 
+
+#ifndef NRFX_I2S_CONFIG_ALIGN
+#define NRFX_I2S_CONFIG_ALIGN 0
+#endif
+
+// <o> NRFX_I2S_CONFIG_SWIDTH  - Sample width (bits)
+ 
+// <0=> 8 
+// <1=> 16 
+// <2=> 24 
+
+#ifndef NRFX_I2S_CONFIG_SWIDTH
+#define NRFX_I2S_CONFIG_SWIDTH 1
+#endif
+
+// <o> NRFX_I2S_CONFIG_CHANNELS  - Channels
+ 
+// <0=> Stereo 
+// <1=> Left 
+// <2=> Right 
+
+#ifndef NRFX_I2S_CONFIG_CHANNELS
+#define NRFX_I2S_CONFIG_CHANNELS 1
+#endif
+
+// <o> NRFX_I2S_CONFIG_MCK_SETUP  - MCK behavior
+ 
+// <0=> Disabled 
+// <2147483648=> 32MHz/2 
+// <1342177280=> 32MHz/3 
+// <1073741824=> 32MHz/4 
+// <805306368=> 32MHz/5 
+// <671088640=> 32MHz/6 
+// <536870912=> 32MHz/8 
+// <402653184=> 32MHz/10 
+// <369098752=> 32MHz/11 
+// <285212672=> 32MHz/15 
+// <268435456=> 32MHz/16 
+// <201326592=> 32MHz/21 
+// <184549376=> 32MHz/23 
+// <142606336=> 32MHz/30 
+// <138412032=> 32MHz/31 
+// <134217728=> 32MHz/32 
+// <100663296=> 32MHz/42 
+// <68157440=> 32MHz/63 
+// <34340864=> 32MHz/125 
+
+#ifndef NRFX_I2S_CONFIG_MCK_SETUP
+#define NRFX_I2S_CONFIG_MCK_SETUP 536870912
+#endif
+
+// <o> NRFX_I2S_CONFIG_RATIO  - MCK/LRCK ratio
+ 
+// <0=> 32x 
+// <1=> 48x 
+// <2=> 64x 
+// <3=> 96x 
+// <4=> 128x 
+// <5=> 192x 
+// <6=> 256x 
+// <7=> 384x 
+// <8=> 512x 
+
+#ifndef NRFX_I2S_CONFIG_RATIO
+#define NRFX_I2S_CONFIG_RATIO 2000
+#endif
+
+// <o> NRFX_I2S_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_CONFIG_IRQ_PRIORITY
+#define NRFX_I2S_CONFIG_IRQ_PRIORITY 6
+#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_LPCOMP_ENABLED - nrfx_lpcomp - LPCOMP peripheral driver
+//==========================================================
+#ifndef NRFX_LPCOMP_ENABLED
+#define NRFX_LPCOMP_ENABLED 0
+#endif
+// <o> NRFX_LPCOMP_CONFIG_REFERENCE  - Reference voltage
+ 
+// <0=> Supply 1/8 
+// <1=> Supply 2/8 
+// <2=> Supply 3/8 
+// <3=> Supply 4/8 
+// <4=> Supply 5/8 
+// <5=> Supply 6/8 
+// <6=> Supply 7/8 
+// <8=> Supply 1/16 (nRF52) 
+// <9=> Supply 3/16 (nRF52) 
+// <10=> Supply 5/16 (nRF52) 
+// <11=> Supply 7/16 (nRF52) 
+// <12=> Supply 9/16 (nRF52) 
+// <13=> Supply 11/16 (nRF52) 
+// <14=> Supply 13/16 (nRF52) 
+// <15=> Supply 15/16 (nRF52) 
+// <7=> External Ref 0 
+// <65543=> External Ref 1 
+
+#ifndef NRFX_LPCOMP_CONFIG_REFERENCE
+#define NRFX_LPCOMP_CONFIG_REFERENCE 3
+#endif
+
+// <o> NRFX_LPCOMP_CONFIG_DETECTION  - Detection
+ 
+// <0=> Crossing 
+// <1=> Up 
+// <2=> Down 
+
+#ifndef NRFX_LPCOMP_CONFIG_DETECTION
+#define NRFX_LPCOMP_CONFIG_DETECTION 2
+#endif
+
+// <o> NRFX_LPCOMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef NRFX_LPCOMP_CONFIG_INPUT
+#define NRFX_LPCOMP_CONFIG_INPUT 0
+#endif
+
+// <q> NRFX_LPCOMP_CONFIG_HYST  - Hysteresis
+ 
+
+#ifndef NRFX_LPCOMP_CONFIG_HYST
+#define NRFX_LPCOMP_CONFIG_HYST 0
+#endif
+
+// <o> NRFX_LPCOMP_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_CONFIG_IRQ_PRIORITY
+#define NRFX_LPCOMP_CONFIG_IRQ_PRIORITY 6
+#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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_NFCT_CONFIG_IRQ_PRIORITY 6
+#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_PDM_ENABLED - nrfx_pdm - PDM peripheral driver
+//==========================================================
+#ifndef NRFX_PDM_ENABLED
+#define NRFX_PDM_ENABLED 0
+#endif
+// <o> NRFX_PDM_CONFIG_MODE  - Mode
+ 
+// <0=> Stereo 
+// <1=> Mono 
+
+#ifndef NRFX_PDM_CONFIG_MODE
+#define NRFX_PDM_CONFIG_MODE 1
+#endif
+
+// <o> NRFX_PDM_CONFIG_EDGE  - Edge
+ 
+// <0=> Left falling 
+// <1=> Left rising 
+
+#ifndef NRFX_PDM_CONFIG_EDGE
+#define NRFX_PDM_CONFIG_EDGE 0
+#endif
+
+// <o> NRFX_PDM_CONFIG_CLOCK_FREQ  - Clock frequency
+ 
+// <134217728=> 1000k 
+// <138412032=> 1032k (default) 
+// <142606336=> 1067k 
+
+#ifndef NRFX_PDM_CONFIG_CLOCK_FREQ
+#define NRFX_PDM_CONFIG_CLOCK_FREQ 138412032
+#endif
+
+// <o> NRFX_PDM_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_CONFIG_IRQ_PRIORITY
+#define NRFX_PDM_CONFIG_IRQ_PRIORITY 6
+#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 1
+#endif
+// <o> NRFX_POWER_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_CONFIG_IRQ_PRIORITY
+#define NRFX_POWER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> NRFX_POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCEN
+#define NRFX_POWER_CONFIG_DEFAULT_DCDCEN 0
+#endif
+
+// <q> NRFX_POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCENHV
+#define NRFX_POWER_CONFIG_DEFAULT_DCDCENHV 0
+#endif
+
+// </e>
+
+// <e> NRFX_PPI_ENABLED - nrfx_ppi - PPI peripheral allocator
+//==========================================================
+#ifndef NRFX_PPI_ENABLED
+#define NRFX_PPI_ENABLED 0
+#endif
+// <e> NRFX_PPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_PPI_CONFIG_LOG_ENABLED
+#define NRFX_PPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_PPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_PPI_CONFIG_LOG_LEVEL
+#define NRFX_PPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_PPI_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_PPI_CONFIG_INFO_COLOR
+#define NRFX_PPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_PPI_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_PPI_CONFIG_DEBUG_COLOR
+#define NRFX_PPI_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  - Enable PWM0 instance
+ 
+
+#ifndef NRFX_PWM0_ENABLED
+#define NRFX_PWM0_ENABLED 0
+#endif
+
+// <q> NRFX_PWM1_ENABLED  - Enable PWM1 instance
+ 
+
+#ifndef NRFX_PWM1_ENABLED
+#define NRFX_PWM1_ENABLED 0
+#endif
+
+// <q> NRFX_PWM2_ENABLED  - Enable PWM2 instance
+ 
+
+#ifndef NRFX_PWM2_ENABLED
+#define NRFX_PWM2_ENABLED 0
+#endif
+
+// <q> NRFX_PWM3_ENABLED  - Enable PWM3 instance
+ 
+
+#ifndef NRFX_PWM3_ENABLED
+#define NRFX_PWM3_ENABLED 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK  - Base clock
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK
+#define NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK 4
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE  - Count mode
+ 
+// <0=> Up 
+// <1=> Up and Down 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE - Top value 
+#ifndef NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE
+#define NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE 1000
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE  - Load mode
+ 
+// <0=> Common 
+// <1=> Grouped 
+// <2=> Individual 
+// <3=> Waveform 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_STEP_MODE  - Step mode
+ 
+// <0=> Auto 
+// <1=> Triggered 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_STEP_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_STEP_MODE 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 6
+#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_CONFIG_REPORTPER  - Report period
+ 
+// <0=> 10 Samples 
+// <1=> 40 Samples 
+// <2=> 80 Samples 
+// <3=> 120 Samples 
+// <4=> 160 Samples 
+// <5=> 200 Samples 
+// <6=> 240 Samples 
+// <7=> 280 Samples 
+
+#ifndef NRFX_QDEC_CONFIG_REPORTPER
+#define NRFX_QDEC_CONFIG_REPORTPER 0
+#endif
+
+// <o> NRFX_QDEC_CONFIG_SAMPLEPER  - Sample period
+ 
+// <0=> 128 us 
+// <1=> 256 us 
+// <2=> 512 us 
+// <3=> 1024 us 
+// <4=> 2048 us 
+// <5=> 4096 us 
+// <6=> 8192 us 
+// <7=> 16384 us 
+
+#ifndef NRFX_QDEC_CONFIG_SAMPLEPER
+#define NRFX_QDEC_CONFIG_SAMPLEPER 7
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_A - A pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_A
+#define NRFX_QDEC_CONFIG_PIO_A 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_B - B pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_B
+#define NRFX_QDEC_CONFIG_PIO_B 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_LED - LED pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_LED
+#define NRFX_QDEC_CONFIG_PIO_LED 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_LEDPRE - LED pre 
+#ifndef NRFX_QDEC_CONFIG_LEDPRE
+#define NRFX_QDEC_CONFIG_LEDPRE 511
+#endif
+
+// <o> NRFX_QDEC_CONFIG_LEDPOL  - LED polarity
+ 
+// <0=> Active low 
+// <1=> Active high 
+
+#ifndef NRFX_QDEC_CONFIG_LEDPOL
+#define NRFX_QDEC_CONFIG_LEDPOL 1
+#endif
+
+// <q> NRFX_QDEC_CONFIG_DBFEN  - Debouncing enable
+ 
+
+#ifndef NRFX_QDEC_CONFIG_DBFEN
+#define NRFX_QDEC_CONFIG_DBFEN 0
+#endif
+
+// <q> NRFX_QDEC_CONFIG_SAMPLE_INTEN  - Sample ready interrupt enable
+ 
+
+#ifndef NRFX_QDEC_CONFIG_SAMPLE_INTEN
+#define NRFX_QDEC_CONFIG_SAMPLE_INTEN 0
+#endif
+
+// <o> NRFX_QDEC_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_CONFIG_IRQ_PRIORITY
+#define NRFX_QDEC_CONFIG_IRQ_PRIORITY 6
+#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_RNG_ENABLED - nrfx_rng - RNG peripheral driver
+//==========================================================
+#ifndef NRFX_RNG_ENABLED
+#define NRFX_RNG_ENABLED 0
+#endif
+// <q> NRFX_RNG_CONFIG_ERROR_CORRECTION  - Error correction
+ 
+
+#ifndef NRFX_RNG_CONFIG_ERROR_CORRECTION
+#define NRFX_RNG_CONFIG_ERROR_CORRECTION 1
+#endif
+
+// <o> NRFX_RNG_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef NRFX_RNG_CONFIG_IRQ_PRIORITY
+#define NRFX_RNG_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_RNG_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_RNG_CONFIG_LOG_ENABLED
+#define NRFX_RNG_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_RNG_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_RNG_CONFIG_LOG_LEVEL
+#define NRFX_RNG_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_RNG_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_RNG_CONFIG_INFO_COLOR
+#define NRFX_RNG_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_RNG_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_RNG_CONFIG_DEBUG_COLOR
+#define NRFX_RNG_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_RTC_ENABLED - nrfx_rtc - RTC peripheral driver
+//==========================================================
+#ifndef NRFX_RTC_ENABLED
+#define NRFX_RTC_ENABLED 0
+#endif
+// <q> NRFX_RTC0_ENABLED  - Enable RTC0 instance
+ 
+
+#ifndef NRFX_RTC0_ENABLED
+#define NRFX_RTC0_ENABLED 0
+#endif
+
+// <q> NRFX_RTC1_ENABLED  - Enable RTC1 instance
+ 
+
+#ifndef NRFX_RTC1_ENABLED
+#define NRFX_RTC1_ENABLED 0
+#endif
+
+// <q> NRFX_RTC2_ENABLED  - Enable RTC2 instance
+ 
+
+#ifndef NRFX_RTC2_ENABLED
+#define NRFX_RTC2_ENABLED 0
+#endif
+
+// <o> NRFX_RTC_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt 
+#ifndef NRFX_RTC_MAXIMUM_LATENCY_US
+#define NRFX_RTC_MAXIMUM_LATENCY_US 2000
+#endif
+
+// <o> NRFX_RTC_DEFAULT_CONFIG_FREQUENCY - Frequency  <16-32768> 
+
+
+#ifndef NRFX_RTC_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_RTC_DEFAULT_CONFIG_FREQUENCY 32768
+#endif
+
+// <q> NRFX_RTC_DEFAULT_CONFIG_RELIABLE  - Ensures safe compare event triggering
+ 
+
+#ifndef NRFX_RTC_DEFAULT_CONFIG_RELIABLE
+#define NRFX_RTC_DEFAULT_CONFIG_RELIABLE 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 6
+#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_CONFIG_RESOLUTION  - Resolution
+ 
+// <0=> 8 bit 
+// <1=> 10 bit 
+// <2=> 12 bit 
+// <3=> 14 bit 
+
+#ifndef NRFX_SAADC_CONFIG_RESOLUTION
+#define NRFX_SAADC_CONFIG_RESOLUTION 1
+#endif
+
+// <o> NRFX_SAADC_CONFIG_OVERSAMPLE  - Sample period
+ 
+// <0=> Disabled 
+// <1=> 2x 
+// <2=> 4x 
+// <3=> 8x 
+// <4=> 16x 
+// <5=> 32x 
+// <6=> 64x 
+// <7=> 128x 
+// <8=> 256x 
+
+#ifndef NRFX_SAADC_CONFIG_OVERSAMPLE
+#define NRFX_SAADC_CONFIG_OVERSAMPLE 0
+#endif
+
+// <q> NRFX_SAADC_CONFIG_LP_MODE  - Enabling low power mode
+ 
+
+#ifndef NRFX_SAADC_CONFIG_LP_MODE
+#define NRFX_SAADC_CONFIG_LP_MODE 0
+#endif
+
+// <o> NRFX_SAADC_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_CONFIG_IRQ_PRIORITY
+#define NRFX_SAADC_CONFIG_IRQ_PRIORITY 6
+#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  - Enable SPIM0 instance
+ 
+
+#ifndef NRFX_SPIM0_ENABLED
+#define NRFX_SPIM0_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM1_ENABLED  - Enable SPIM1 instance
+ 
+
+#ifndef NRFX_SPIM1_ENABLED
+#define NRFX_SPIM1_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM2_ENABLED  - Enable SPIM2 instance
+ 
+
+#ifndef NRFX_SPIM2_ENABLED
+#define NRFX_SPIM2_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM3_ENABLED  - Enable SPIM3 instance
+ 
+
+#ifndef NRFX_SPIM3_ENABLED
+#define NRFX_SPIM3_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_MISO_PULL_CFG  - MISO pin pull configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRFX_SPIM_MISO_PULL_CFG
+#define NRFX_SPIM_MISO_PULL_CFG 1
+#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 6
+#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  - Enable SPIS0 instance
+ 
+
+#ifndef NRFX_SPIS0_ENABLED
+#define NRFX_SPIS0_ENABLED 0
+#endif
+
+// <q> NRFX_SPIS1_ENABLED  - Enable SPIS1 instance
+ 
+
+#ifndef NRFX_SPIS1_ENABLED
+#define NRFX_SPIS1_ENABLED 0
+#endif
+
+// <q> NRFX_SPIS2_ENABLED  - Enable SPIS2 instance
+ 
+
+#ifndef NRFX_SPIS2_ENABLED
+#define NRFX_SPIS2_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 6
+#endif
+
+// <o> NRFX_SPIS_DEFAULT_DEF - SPIS default DEF character  <0-255> 
+
+
+#ifndef NRFX_SPIS_DEFAULT_DEF
+#define NRFX_SPIS_DEFAULT_DEF 255
+#endif
+
+// <o> NRFX_SPIS_DEFAULT_ORC - SPIS default ORC character  <0-255> 
+
+
+#ifndef NRFX_SPIS_DEFAULT_ORC
+#define NRFX_SPIS_DEFAULT_ORC 255
+#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>
+
+// <e> NRFX_SPI_ENABLED - nrfx_spi - SPI peripheral driver
+//==========================================================
+#ifndef NRFX_SPI_ENABLED
+#define NRFX_SPI_ENABLED 0
+#endif
+// <q> NRFX_SPI0_ENABLED  - Enable SPI0 instance
+ 
+
+#ifndef NRFX_SPI0_ENABLED
+#define NRFX_SPI0_ENABLED 0
+#endif
+
+// <q> NRFX_SPI1_ENABLED  - Enable SPI1 instance
+ 
+
+#ifndef NRFX_SPI1_ENABLED
+#define NRFX_SPI1_ENABLED 0
+#endif
+
+// <q> NRFX_SPI2_ENABLED  - Enable SPI2 instance
+ 
+
+#ifndef NRFX_SPI2_ENABLED
+#define NRFX_SPI2_ENABLED 0
+#endif
+
+// <o> NRFX_SPI_MISO_PULL_CFG  - MISO pin pull configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRFX_SPI_MISO_PULL_CFG
+#define NRFX_SPI_MISO_PULL_CFG 1
+#endif
+
+// <o> NRFX_SPI_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_SPI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_SPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SPI_CONFIG_LOG_ENABLED
+#define NRFX_SPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_SPI_CONFIG_LOG_LEVEL
+#define NRFX_SPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SPI_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_SPI_CONFIG_INFO_COLOR
+#define NRFX_SPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SPI_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_SPI_CONFIG_DEBUG_COLOR
+#define NRFX_SPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_SWI_ENABLED - nrfx_swi - SWI/EGU peripheral allocator
+//==========================================================
+#ifndef NRFX_SWI_ENABLED
+#define NRFX_SWI_ENABLED 0
+#endif
+// <q> NRFX_EGU_ENABLED  - Enable EGU support
+ 
+
+#ifndef NRFX_EGU_ENABLED
+#define NRFX_EGU_ENABLED 0
+#endif
+
+// <q> NRFX_SWI0_DISABLED  - Exclude SWI0 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI0_DISABLED
+#define NRFX_SWI0_DISABLED 0
+#endif
+
+// <q> NRFX_SWI1_DISABLED  - Exclude SWI1 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI1_DISABLED
+#define NRFX_SWI1_DISABLED 0
+#endif
+
+// <q> NRFX_SWI2_DISABLED  - Exclude SWI2 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI2_DISABLED
+#define NRFX_SWI2_DISABLED 0
+#endif
+
+// <q> NRFX_SWI3_DISABLED  - Exclude SWI3 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI3_DISABLED
+#define NRFX_SWI3_DISABLED 0
+#endif
+
+// <q> NRFX_SWI4_DISABLED  - Exclude SWI4 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI4_DISABLED
+#define NRFX_SWI4_DISABLED 0
+#endif
+
+// <q> NRFX_SWI5_DISABLED  - Exclude SWI5 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI5_DISABLED
+#define NRFX_SWI5_DISABLED 0
+#endif
+
+// <e> NRFX_SWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SWI_CONFIG_LOG_ENABLED
+#define NRFX_SWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_SWI_CONFIG_LOG_LEVEL
+#define NRFX_SWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SWI_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_SWI_CONFIG_INFO_COLOR
+#define NRFX_SWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SWI_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_SWI_CONFIG_DEBUG_COLOR
+#define NRFX_SWI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_TIMER_ENABLED - nrfx_timer - TIMER periperal driver
+//==========================================================
+#ifndef NRFX_TIMER_ENABLED
+#define NRFX_TIMER_ENABLED 0
+#endif
+// <q> NRFX_TIMER0_ENABLED  - Enable TIMER0 instance
+ 
+
+#ifndef NRFX_TIMER0_ENABLED
+#define NRFX_TIMER0_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER1_ENABLED  - Enable TIMER1 instance
+ 
+
+#ifndef NRFX_TIMER1_ENABLED
+#define NRFX_TIMER1_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER2_ENABLED  - Enable TIMER2 instance
+ 
+
+#ifndef NRFX_TIMER2_ENABLED
+#define NRFX_TIMER2_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER3_ENABLED  - Enable TIMER3 instance
+ 
+
+#ifndef NRFX_TIMER3_ENABLED
+#define NRFX_TIMER3_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER4_ENABLED  - Enable TIMER4 instance
+ 
+
+#ifndef NRFX_TIMER4_ENABLED
+#define NRFX_TIMER4_ENABLED 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY  - Timer frequency if in Timer mode
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+// <8=> 62.5 kHz 
+// <9=> 31.25 kHz 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_MODE  - Timer mode or operation
+ 
+// <0=> Timer 
+// <1=> Counter 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_MODE
+#define NRFX_TIMER_DEFAULT_CONFIG_MODE 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH  - Timer counter bit width
+ 
+// <0=> 16 bit 
+// <1=> 8 bit 
+// <2=> 24 bit 
+// <3=> 32 bit 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH
+#define NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH 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 6
+#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  - Enable TWIM0 instance
+ 
+
+#ifndef NRFX_TWIM0_ENABLED
+#define NRFX_TWIM0_ENABLED 0
+#endif
+
+// <q> NRFX_TWIM1_ENABLED  - Enable TWIM1 instance
+ 
+
+#ifndef NRFX_TWIM1_ENABLED
+#define NRFX_TWIM1_ENABLED 0
+#endif
+
+// <o> NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT 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 6
+#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  - Enable TWIS0 instance
+ 
+
+#ifndef NRFX_TWIS0_ENABLED
+#define NRFX_TWIS0_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS1_ENABLED  - Enable TWIS1 instance
+ 
+
+#ifndef NRFX_TWIS1_ENABLED
+#define NRFX_TWIS1_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY  - Assume 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  - Remove 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_ADDR0 - Address0 
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR0
+#define NRFX_TWIS_DEFAULT_CONFIG_ADDR0 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_ADDR1 - Address1 
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR1
+#define NRFX_TWIS_DEFAULT_CONFIG_ADDR1 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL  - SCL pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL
+#define NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL  - SDA pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL
+#define NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL 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 6
+#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_TWI_ENABLED - nrfx_twi - TWI peripheral driver
+//==========================================================
+#ifndef NRFX_TWI_ENABLED
+#define NRFX_TWI_ENABLED 0
+#endif
+// <q> NRFX_TWI0_ENABLED  - Enable TWI0 instance
+ 
+
+#ifndef NRFX_TWI0_ENABLED
+#define NRFX_TWI0_ENABLED 0
+#endif
+
+// <q> NRFX_TWI1_ENABLED  - Enable TWI1 instance
+ 
+
+#ifndef NRFX_TWI1_ENABLED
+#define NRFX_TWI1_ENABLED 0
+#endif
+
+// <o> NRFX_TWI_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef NRFX_TWI_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TWI_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
+#endif
+
+// <o> NRFX_TWI_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_TWI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_TWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_TWI_CONFIG_LOG_ENABLED
+#define NRFX_TWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_TWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_TWI_CONFIG_LOG_LEVEL
+#define NRFX_TWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_TWI_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_TWI_CONFIG_INFO_COLOR
+#define NRFX_TWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_TWI_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_TWI_CONFIG_DEBUG_COLOR
+#define NRFX_TWI_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 - Enable UARTE0 instance 
+#ifndef NRFX_UARTE0_ENABLED
+#define NRFX_UARTE0_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE1_ENABLED - Enable UARTE1 instance 
+#ifndef NRFX_UARTE1_ENABLED
+#define NRFX_UARTE1_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_HWFC
+#define NRFX_UARTE_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_PARITY
+#define NRFX_UARTE_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <8388608=> 31250 baud 
+// <10289152=> 38400 baud 
+// <15007744=> 56000 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE
+#define NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE 30801920
+#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 6
+#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_UART_ENABLED - nrfx_uart - UART peripheral driver
+//==========================================================
+#ifndef NRFX_UART_ENABLED
+#define NRFX_UART_ENABLED 0
+#endif
+// <o> NRFX_UART0_ENABLED - Enable UART0 instance 
+#ifndef NRFX_UART0_ENABLED
+#define NRFX_UART0_ENABLED 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_HWFC
+#define NRFX_UART_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_PARITY
+#define NRFX_UART_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3866624=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7729152=> 28800 baud 
+// <8388608=> 31250 baud 
+// <10309632=> 38400 baud 
+// <15007744=> 56000 baud 
+// <15462400=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30924800=> 115200 baud 
+// <61845504=> 230400 baud 
+// <67108864=> 250000 baud 
+// <123695104=> 460800 baud 
+// <247386112=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_BAUDRATE
+#define NRFX_UART_DEFAULT_CONFIG_BAUDRATE 30924800
+#endif
+
+// <o> NRFX_UART_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_UART_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_UART_CONFIG_LOG_ENABLED
+#define NRFX_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_UART_CONFIG_LOG_LEVEL
+#define NRFX_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_UART_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_UART_CONFIG_INFO_COLOR
+#define NRFX_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_UART_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_UART_CONFIG_DEBUG_COLOR
+#define NRFX_UART_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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_USBD_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> NRFX_USBD_CONFIG_DMASCHEDULER_MODE  - USBD DMA scheduler working scheme
+ 
+// <0=> Prioritized access 
+// <1=> Round Robin 
+
+#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_MODE
+#define NRFX_USBD_CONFIG_DMASCHEDULER_MODE 0
+#endif
+
+// <q> NRFX_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> NRFX_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>
+
+// <e> NRFX_WDT_ENABLED - nrfx_wdt - WDT peripheral driver
+//==========================================================
+#ifndef NRFX_WDT_ENABLED
+#define NRFX_WDT_ENABLED 0
+#endif
+// <o> NRFX_WDT_CONFIG_BEHAVIOUR  - WDT behavior in CPU SLEEP or HALT mode
+ 
+// <1=> Run in SLEEP, Pause in HALT 
+// <8=> Pause in SLEEP, Run in HALT 
+// <9=> Run in SLEEP and HALT 
+// <0=> Pause in SLEEP and HALT 
+
+#ifndef NRFX_WDT_CONFIG_BEHAVIOUR
+#define NRFX_WDT_CONFIG_BEHAVIOUR 1
+#endif
+
+// <o> NRFX_WDT_CONFIG_RELOAD_VALUE - Reload value  <15-4294967295> 
+
+
+#ifndef NRFX_WDT_CONFIG_RELOAD_VALUE
+#define NRFX_WDT_CONFIG_RELOAD_VALUE 2000
+#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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_WDT_CONFIG_IRQ_PRIORITY 6
+#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>
+
+// <e> NRF_CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver - legacy layer
+//==========================================================
+#ifndef NRF_CLOCK_ENABLED
+#define NRF_CLOCK_ENABLED 0
+#endif
+// <o> CLOCK_CONFIG_LF_SRC  - LF Clock Source
+ 
+// <0=> RC 
+// <1=> XTAL 
+// <2=> Synth 
+// <131073=> External Low Swing 
+// <196609=> External Full Swing 
+
+#ifndef CLOCK_CONFIG_LF_SRC
+#define CLOCK_CONFIG_LF_SRC 1
+#endif
+
+// <q> CLOCK_CONFIG_LF_CAL_ENABLED  - Calibration enable for LF Clock Source
+ 
+
+#ifndef CLOCK_CONFIG_LF_CAL_ENABLED
+#define CLOCK_CONFIG_LF_CAL_ENABLED 0
+#endif
+
+// <o> CLOCK_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef CLOCK_CONFIG_IRQ_PRIORITY
+#define CLOCK_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> PDM_ENABLED - nrf_drv_pdm - PDM peripheral driver - legacy layer
+//==========================================================
+#ifndef PDM_ENABLED
+#define PDM_ENABLED 0
+#endif
+// <o> PDM_CONFIG_MODE  - Mode
+ 
+// <0=> Stereo 
+// <1=> Mono 
+
+#ifndef PDM_CONFIG_MODE
+#define PDM_CONFIG_MODE 1
+#endif
+
+// <o> PDM_CONFIG_EDGE  - Edge
+ 
+// <0=> Left falling 
+// <1=> Left rising 
+
+#ifndef PDM_CONFIG_EDGE
+#define PDM_CONFIG_EDGE 0
+#endif
+
+// <o> PDM_CONFIG_CLOCK_FREQ  - Clock frequency
+ 
+// <134217728=> 1000k 
+// <138412032=> 1032k (default) 
+// <142606336=> 1067k 
+
+#ifndef PDM_CONFIG_CLOCK_FREQ
+#define PDM_CONFIG_CLOCK_FREQ 138412032
+#endif
+
+// <o> PDM_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef PDM_CONFIG_IRQ_PRIORITY
+#define PDM_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> POWER_ENABLED - nrf_drv_power - POWER peripheral driver - legacy layer
+//==========================================================
+#ifndef POWER_ENABLED
+#define POWER_ENABLED 1
+#endif
+// <o> POWER_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef POWER_CONFIG_IRQ_PRIORITY
+#define POWER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef POWER_CONFIG_DEFAULT_DCDCEN
+#define POWER_CONFIG_DEFAULT_DCDCEN 0
+#endif
+
+// <q> POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef POWER_CONFIG_DEFAULT_DCDCENHV
+#define POWER_CONFIG_DEFAULT_DCDCENHV 0
+#endif
+
+// </e>
+
+// <q> PPI_ENABLED  - nrf_drv_ppi - PPI peripheral driver - legacy layer
+ 
+
+#ifndef PPI_ENABLED
+#define PPI_ENABLED 0
+#endif
+
+// <e> PWM_ENABLED - nrf_drv_pwm - PWM peripheral driver - legacy layer
+//==========================================================
+#ifndef PWM_ENABLED
+#define PWM_ENABLED 0
+#endif
+// <o> PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT0_PIN
+#define PWM_DEFAULT_CONFIG_OUT0_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT1_PIN
+#define PWM_DEFAULT_CONFIG_OUT1_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT2_PIN
+#define PWM_DEFAULT_CONFIG_OUT2_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT3_PIN
+#define PWM_DEFAULT_CONFIG_OUT3_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_BASE_CLOCK  - Base clock
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+
+#ifndef PWM_DEFAULT_CONFIG_BASE_CLOCK
+#define PWM_DEFAULT_CONFIG_BASE_CLOCK 4
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_COUNT_MODE  - Count mode
+ 
+// <0=> Up 
+// <1=> Up and Down 
+
+#ifndef PWM_DEFAULT_CONFIG_COUNT_MODE
+#define PWM_DEFAULT_CONFIG_COUNT_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_TOP_VALUE - Top value 
+#ifndef PWM_DEFAULT_CONFIG_TOP_VALUE
+#define PWM_DEFAULT_CONFIG_TOP_VALUE 1000
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_LOAD_MODE  - Load mode
+ 
+// <0=> Common 
+// <1=> Grouped 
+// <2=> Individual 
+// <3=> Waveform 
+
+#ifndef PWM_DEFAULT_CONFIG_LOAD_MODE
+#define PWM_DEFAULT_CONFIG_LOAD_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_STEP_MODE  - Step mode
+ 
+// <0=> Auto 
+// <1=> Triggered 
+
+#ifndef PWM_DEFAULT_CONFIG_STEP_MODE
+#define PWM_DEFAULT_CONFIG_STEP_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef PWM_DEFAULT_CONFIG_IRQ_PRIORITY
+#define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> PWM0_ENABLED  - Enable PWM0 instance
+ 
+
+#ifndef PWM0_ENABLED
+#define PWM0_ENABLED 0
+#endif
+
+// <q> PWM1_ENABLED  - Enable PWM1 instance
+ 
+
+#ifndef PWM1_ENABLED
+#define PWM1_ENABLED 0
+#endif
+
+// <q> PWM2_ENABLED  - Enable PWM2 instance
+ 
+
+#ifndef PWM2_ENABLED
+#define PWM2_ENABLED 0
+#endif
+
+// <q> PWM3_ENABLED  - Enable PWM3 instance
+ 
+
+#ifndef PWM3_ENABLED
+#define PWM3_ENABLED 0
+#endif
+
+// </e>
+
+// <e> QDEC_ENABLED - nrf_drv_qdec - QDEC peripheral driver - legacy layer
+//==========================================================
+#ifndef QDEC_ENABLED
+#define QDEC_ENABLED 0
+#endif
+// <o> QDEC_CONFIG_REPORTPER  - Report period
+ 
+// <0=> 10 Samples 
+// <1=> 40 Samples 
+// <2=> 80 Samples 
+// <3=> 120 Samples 
+// <4=> 160 Samples 
+// <5=> 200 Samples 
+// <6=> 240 Samples 
+// <7=> 280 Samples 
+
+#ifndef QDEC_CONFIG_REPORTPER
+#define QDEC_CONFIG_REPORTPER 0
+#endif
+
+// <o> QDEC_CONFIG_SAMPLEPER  - Sample period
+ 
+// <0=> 128 us 
+// <1=> 256 us 
+// <2=> 512 us 
+// <3=> 1024 us 
+// <4=> 2048 us 
+// <5=> 4096 us 
+// <6=> 8192 us 
+// <7=> 16384 us 
+
+#ifndef QDEC_CONFIG_SAMPLEPER
+#define QDEC_CONFIG_SAMPLEPER 7
+#endif
+
+// <o> QDEC_CONFIG_PIO_A - A pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_A
+#define QDEC_CONFIG_PIO_A 31
+#endif
+
+// <o> QDEC_CONFIG_PIO_B - B pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_B
+#define QDEC_CONFIG_PIO_B 31
+#endif
+
+// <o> QDEC_CONFIG_PIO_LED - LED pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_LED
+#define QDEC_CONFIG_PIO_LED 31
+#endif
+
+// <o> QDEC_CONFIG_LEDPRE - LED pre 
+#ifndef QDEC_CONFIG_LEDPRE
+#define QDEC_CONFIG_LEDPRE 511
+#endif
+
+// <o> QDEC_CONFIG_LEDPOL  - LED polarity
+ 
+// <0=> Active low 
+// <1=> Active high 
+
+#ifndef QDEC_CONFIG_LEDPOL
+#define QDEC_CONFIG_LEDPOL 1
+#endif
+
+// <q> QDEC_CONFIG_DBFEN  - Debouncing enable
+ 
+
+#ifndef QDEC_CONFIG_DBFEN
+#define QDEC_CONFIG_DBFEN 0
+#endif
+
+// <q> QDEC_CONFIG_SAMPLE_INTEN  - Sample ready interrupt enable
+ 
+
+#ifndef QDEC_CONFIG_SAMPLE_INTEN
+#define QDEC_CONFIG_SAMPLE_INTEN 0
+#endif
+
+// <o> QDEC_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef QDEC_CONFIG_IRQ_PRIORITY
+#define QDEC_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> QSPI_ENABLED - nrf_drv_qspi - QSPI peripheral driver - legacy layer
+//==========================================================
+#ifndef QSPI_ENABLED
+#define QSPI_ENABLED 0
+#endif
+// <o> QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).  <0-255> 
+
+
+#ifndef QSPI_CONFIG_SCK_DELAY
+#define QSPI_CONFIG_SCK_DELAY 1
+#endif
+
+// <o> QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation. 
+#ifndef QSPI_CONFIG_XIP_OFFSET
+#define QSPI_CONFIG_XIP_OFFSET 0
+#endif
+
+// <o> QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
+ 
+// <0=> FastRead 
+// <1=> Read2O 
+// <2=> Read2IO 
+// <3=> Read4O 
+// <4=> Read4IO 
+
+#ifndef QSPI_CONFIG_READOC
+#define QSPI_CONFIG_READOC 0
+#endif
+
+// <o> QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
+ 
+// <0=> PP 
+// <1=> PP2O 
+// <2=> PP4O 
+// <3=> PP4IO 
+
+#ifndef QSPI_CONFIG_WRITEOC
+#define QSPI_CONFIG_WRITEOC 0
+#endif
+
+// <o> QSPI_CONFIG_ADDRMODE  - Addressing mode.
+ 
+// <0=> 24bit 
+// <1=> 32bit 
+
+#ifndef QSPI_CONFIG_ADDRMODE
+#define QSPI_CONFIG_ADDRMODE 0
+#endif
+
+// <o> QSPI_CONFIG_MODE  - SPI mode.
+ 
+// <0=> Mode 0 
+// <1=> Mode 1 
+
+#ifndef QSPI_CONFIG_MODE
+#define QSPI_CONFIG_MODE 0
+#endif
+
+// <o> QSPI_CONFIG_FREQUENCY  - Frequency divider.
+ 
+// <0=> 32MHz/1 
+// <1=> 32MHz/2 
+// <2=> 32MHz/3 
+// <3=> 32MHz/4 
+// <4=> 32MHz/5 
+// <5=> 32MHz/6 
+// <6=> 32MHz/7 
+// <7=> 32MHz/8 
+// <8=> 32MHz/9 
+// <9=> 32MHz/10 
+// <10=> 32MHz/11 
+// <11=> 32MHz/12 
+// <12=> 32MHz/13 
+// <13=> 32MHz/14 
+// <14=> 32MHz/15 
+// <15=> 32MHz/16 
+
+#ifndef QSPI_CONFIG_FREQUENCY
+#define QSPI_CONFIG_FREQUENCY 15
+#endif
+
+// <s> QSPI_PIN_SCK - SCK pin value.
+#ifndef QSPI_PIN_SCK
+#define QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_CSN - CSN pin value.
+#ifndef QSPI_PIN_CSN
+#define QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO0 - IO0 pin value.
+#ifndef QSPI_PIN_IO0
+#define QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO1 - IO1 pin value.
+#ifndef QSPI_PIN_IO1
+#define QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO2 - IO2 pin value.
+#ifndef QSPI_PIN_IO2
+#define QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO3 - IO3 pin value.
+#ifndef QSPI_PIN_IO3
+#define QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <o> QSPI_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef QSPI_CONFIG_IRQ_PRIORITY
+#define QSPI_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> RNG_ENABLED - nrf_drv_rng - RNG peripheral driver - legacy layer
+//==========================================================
+#ifndef RNG_ENABLED
+#define RNG_ENABLED 0
+#endif
+// <q> RNG_CONFIG_ERROR_CORRECTION  - Error correction
+ 
+
+#ifndef RNG_CONFIG_ERROR_CORRECTION
+#define RNG_CONFIG_ERROR_CORRECTION 1
+#endif
+
+// <o> RNG_CONFIG_POOL_SIZE - Pool size 
+#ifndef RNG_CONFIG_POOL_SIZE
+#define RNG_CONFIG_POOL_SIZE 64
+#endif
+
+// <o> RNG_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef RNG_CONFIG_IRQ_PRIORITY
+#define RNG_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> RTC_ENABLED - nrf_drv_rtc - RTC peripheral driver - legacy layer
+//==========================================================
+#ifndef RTC_ENABLED
+#define RTC_ENABLED 0
+#endif
+// <o> RTC_DEFAULT_CONFIG_FREQUENCY - Frequency  <16-32768> 
+
+
+#ifndef RTC_DEFAULT_CONFIG_FREQUENCY
+#define RTC_DEFAULT_CONFIG_FREQUENCY 32768
+#endif
+
+// <q> RTC_DEFAULT_CONFIG_RELIABLE  - Ensures safe compare event triggering
+ 
+
+#ifndef RTC_DEFAULT_CONFIG_RELIABLE
+#define RTC_DEFAULT_CONFIG_RELIABLE 0
+#endif
+
+// <o> RTC_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef RTC_DEFAULT_CONFIG_IRQ_PRIORITY
+#define RTC_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> RTC0_ENABLED  - Enable RTC0 instance
+ 
+
+#ifndef RTC0_ENABLED
+#define RTC0_ENABLED 0
+#endif
+
+// <q> RTC1_ENABLED  - Enable RTC1 instance
+ 
+
+#ifndef RTC1_ENABLED
+#define RTC1_ENABLED 0
+#endif
+
+// <q> RTC2_ENABLED  - Enable RTC2 instance
+ 
+
+#ifndef RTC2_ENABLED
+#define RTC2_ENABLED 0
+#endif
+
+// <o> NRF_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt 
+#ifndef NRF_MAXIMUM_LATENCY_US
+#define NRF_MAXIMUM_LATENCY_US 2000
+#endif
+
+// </e>
+
+// <e> SAADC_ENABLED - nrf_drv_saadc - SAADC peripheral driver - legacy layer
+//==========================================================
+#ifndef SAADC_ENABLED
+#define SAADC_ENABLED 0
+#endif
+// <o> SAADC_CONFIG_RESOLUTION  - Resolution
+ 
+// <0=> 8 bit 
+// <1=> 10 bit 
+// <2=> 12 bit 
+// <3=> 14 bit 
+
+#ifndef SAADC_CONFIG_RESOLUTION
+#define SAADC_CONFIG_RESOLUTION 1
+#endif
+
+// <o> SAADC_CONFIG_OVERSAMPLE  - Sample period
+ 
+// <0=> Disabled 
+// <1=> 2x 
+// <2=> 4x 
+// <3=> 8x 
+// <4=> 16x 
+// <5=> 32x 
+// <6=> 64x 
+// <7=> 128x 
+// <8=> 256x 
+
+#ifndef SAADC_CONFIG_OVERSAMPLE
+#define SAADC_CONFIG_OVERSAMPLE 0
+#endif
+
+// <q> SAADC_CONFIG_LP_MODE  - Enabling low power mode
+ 
+
+#ifndef SAADC_CONFIG_LP_MODE
+#define SAADC_CONFIG_LP_MODE 0
+#endif
+
+// <o> SAADC_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SAADC_CONFIG_IRQ_PRIORITY
+#define SAADC_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> SPIS_ENABLED - nrf_drv_spis - SPIS peripheral driver - legacy layer
+//==========================================================
+#ifndef SPIS_ENABLED
+#define SPIS_ENABLED 0
+#endif
+// <o> SPIS_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SPIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> SPIS_DEFAULT_MODE  - Mode
+ 
+// <0=> MODE_0 
+// <1=> MODE_1 
+// <2=> MODE_2 
+// <3=> MODE_3 
+
+#ifndef SPIS_DEFAULT_MODE
+#define SPIS_DEFAULT_MODE 0
+#endif
+
+// <o> SPIS_DEFAULT_BIT_ORDER  - SPIS default bit order
+ 
+// <0=> MSB first 
+// <1=> LSB first 
+
+#ifndef SPIS_DEFAULT_BIT_ORDER
+#define SPIS_DEFAULT_BIT_ORDER 0
+#endif
+
+// <o> SPIS_DEFAULT_DEF - SPIS default DEF character  <0-255> 
+
+
+#ifndef SPIS_DEFAULT_DEF
+#define SPIS_DEFAULT_DEF 255
+#endif
+
+// <o> SPIS_DEFAULT_ORC - SPIS default ORC character  <0-255> 
+
+
+#ifndef SPIS_DEFAULT_ORC
+#define SPIS_DEFAULT_ORC 255
+#endif
+
+// <q> SPIS0_ENABLED  - Enable SPIS0 instance
+ 
+
+#ifndef SPIS0_ENABLED
+#define SPIS0_ENABLED 0
+#endif
+
+// <q> SPIS1_ENABLED  - Enable SPIS1 instance
+ 
+
+#ifndef SPIS1_ENABLED
+#define SPIS1_ENABLED 0
+#endif
+
+// <q> SPIS2_ENABLED  - Enable SPIS2 instance
+ 
+
+#ifndef SPIS2_ENABLED
+#define SPIS2_ENABLED 0
+#endif
+
+// </e>
+
+// <e> SPI_ENABLED - nrf_drv_spi - SPI/SPIM peripheral driver - legacy layer
+//==========================================================
+#ifndef SPI_ENABLED
+#define SPI_ENABLED 0
+#endif
+// <o> SPI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SPI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> NRF_SPI_DRV_MISO_PULLUP_CFG  - MISO PIN pull-up configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRF_SPI_DRV_MISO_PULLUP_CFG
+#define NRF_SPI_DRV_MISO_PULLUP_CFG 1
+#endif
+
+// <e> SPI0_ENABLED - Enable SPI0 instance
+//==========================================================
+#ifndef SPI0_ENABLED
+#define SPI0_ENABLED 0
+#endif
+// <q> SPI0_USE_EASY_DMA  - Use EasyDMA
+ 
+
+#ifndef SPI0_USE_EASY_DMA
+#define SPI0_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// <e> SPI1_ENABLED - Enable SPI1 instance
+//==========================================================
+#ifndef SPI1_ENABLED
+#define SPI1_ENABLED 0
+#endif
+// <q> SPI1_USE_EASY_DMA  - Use EasyDMA
+ 
+
+#ifndef SPI1_USE_EASY_DMA
+#define SPI1_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// <e> SPI2_ENABLED - Enable SPI2 instance
+//==========================================================
+#ifndef SPI2_ENABLED
+#define SPI2_ENABLED 0
+#endif
+// <q> SPI2_USE_EASY_DMA  - Use EasyDMA
+ 
+
+#ifndef SPI2_USE_EASY_DMA
+#define SPI2_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// </e>
+
+// <e> TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver - legacy layer
+//==========================================================
+#ifndef TIMER_ENABLED
+#define TIMER_ENABLED 0
+#endif
+// <o> TIMER_DEFAULT_CONFIG_FREQUENCY  - Timer frequency if in Timer mode
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+// <8=> 62.5 kHz 
+// <9=> 31.25 kHz 
+
+#ifndef TIMER_DEFAULT_CONFIG_FREQUENCY
+#define TIMER_DEFAULT_CONFIG_FREQUENCY 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_MODE  - Timer mode or operation
+ 
+// <0=> Timer 
+// <1=> Counter 
+
+#ifndef TIMER_DEFAULT_CONFIG_MODE
+#define TIMER_DEFAULT_CONFIG_MODE 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_BIT_WIDTH  - Timer counter bit width
+ 
+// <0=> 16 bit 
+// <1=> 8 bit 
+// <2=> 24 bit 
+// <3=> 32 bit 
+
+#ifndef TIMER_DEFAULT_CONFIG_BIT_WIDTH
+#define TIMER_DEFAULT_CONFIG_BIT_WIDTH 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> TIMER0_ENABLED  - Enable TIMER0 instance
+ 
+
+#ifndef TIMER0_ENABLED
+#define TIMER0_ENABLED 0
+#endif
+
+// <q> TIMER1_ENABLED  - Enable TIMER1 instance
+ 
+
+#ifndef TIMER1_ENABLED
+#define TIMER1_ENABLED 0
+#endif
+
+// <q> TIMER2_ENABLED  - Enable TIMER2 instance
+ 
+
+#ifndef TIMER2_ENABLED
+#define TIMER2_ENABLED 0
+#endif
+
+// <q> TIMER3_ENABLED  - Enable TIMER3 instance
+ 
+
+#ifndef TIMER3_ENABLED
+#define TIMER3_ENABLED 0
+#endif
+
+// <q> TIMER4_ENABLED  - Enable TIMER4 instance
+ 
+
+#ifndef TIMER4_ENABLED
+#define TIMER4_ENABLED 0
+#endif
+
+// </e>
+
+// <e> TWIS_ENABLED - nrf_drv_twis - TWIS peripheral driver - legacy layer
+//==========================================================
+#ifndef TWIS_ENABLED
+#define TWIS_ENABLED 0
+#endif
+// <q> TWIS0_ENABLED  - Enable TWIS0 instance
+ 
+
+#ifndef TWIS0_ENABLED
+#define TWIS0_ENABLED 0
+#endif
+
+// <q> TWIS1_ENABLED  - Enable TWIS1 instance
+ 
+
+#ifndef TWIS1_ENABLED
+#define TWIS1_ENABLED 0
+#endif
+
+// <q> TWIS_ASSUME_INIT_AFTER_RESET_ONLY  - Assume 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 TWIS_ASSUME_INIT_AFTER_RESET_ONLY
+#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0
+#endif
+
+// <q> TWIS_NO_SYNC_MODE  - Remove 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 TWIS_NO_SYNC_MODE
+#define TWIS_NO_SYNC_MODE 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_ADDR0 - Address0 
+#ifndef TWIS_DEFAULT_CONFIG_ADDR0
+#define TWIS_DEFAULT_CONFIG_ADDR0 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_ADDR1 - Address1 
+#ifndef TWIS_DEFAULT_CONFIG_ADDR1
+#define TWIS_DEFAULT_CONFIG_ADDR1 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_SCL_PULL  - SCL pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef TWIS_DEFAULT_CONFIG_SCL_PULL
+#define TWIS_DEFAULT_CONFIG_SCL_PULL 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_SDA_PULL  - SDA pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef TWIS_DEFAULT_CONFIG_SDA_PULL
+#define TWIS_DEFAULT_CONFIG_SDA_PULL 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TWIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver - legacy layer
+//==========================================================
+#ifndef TWI_ENABLED
+#define TWI_ENABLED 0
+#endif
+// <o> TWI_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef TWI_DEFAULT_CONFIG_FREQUENCY
+#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> TWI_DEFAULT_CONFIG_CLR_BUS_INIT  - Enables bus clearing procedure during init
+ 
+
+#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT
+#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0
+#endif
+
+// <q> TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
+#endif
+
+// <o> TWI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> TWI0_ENABLED - Enable TWI0 instance
+//==========================================================
+#ifndef TWI0_ENABLED
+#define TWI0_ENABLED 0
+#endif
+// <q> TWI0_USE_EASY_DMA  - Use EasyDMA (if present)
+ 
+
+#ifndef TWI0_USE_EASY_DMA
+#define TWI0_USE_EASY_DMA 0
+#endif
+
+// </e>
+
+// <e> TWI1_ENABLED - Enable TWI1 instance
+//==========================================================
+#ifndef TWI1_ENABLED
+#define TWI1_ENABLED 0
+#endif
+// <q> TWI1_USE_EASY_DMA  - Use EasyDMA (if present)
+ 
+
+#ifndef TWI1_USE_EASY_DMA
+#define TWI1_USE_EASY_DMA 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
+//==========================================================
+#ifndef UART_ENABLED
+#define UART_ENABLED 0
+#endif
+// <o> UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef UART_DEFAULT_CONFIG_HWFC
+#define UART_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> UART_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef UART_DEFAULT_CONFIG_PARITY
+#define UART_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <10289152=> 38400 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef UART_DEFAULT_CONFIG_BAUDRATE
+#define UART_DEFAULT_CONFIG_BAUDRATE 30801920
+#endif
+
+// <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY
+#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> UART_EASY_DMA_SUPPORT  - Driver supporting EasyDMA
+ 
+
+#ifndef UART_EASY_DMA_SUPPORT
+#define UART_EASY_DMA_SUPPORT 1
+#endif
+
+// <q> UART_LEGACY_SUPPORT  - Driver supporting Legacy mode
+ 
+
+#ifndef UART_LEGACY_SUPPORT
+#define UART_LEGACY_SUPPORT 1
+#endif
+
+// <e> UART0_ENABLED - Enable UART0 instance
+//==========================================================
+#ifndef UART0_ENABLED
+#define UART0_ENABLED 0
+#endif
+// <q> UART0_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA
+ 
+
+#ifndef UART0_CONFIG_USE_EASY_DMA
+#define UART0_CONFIG_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// <e> UART1_ENABLED - Enable UART1 instance
+//==========================================================
+#ifndef UART1_ENABLED
+#define UART1_ENABLED 0
+#endif
+// </e>
+
+// </e>
+
+// <e> USBD_ENABLED - nrf_drv_usbd - Software Component
+//==========================================================
+#ifndef USBD_ENABLED
+#define USBD_ENABLED 0
+#endif
+// <o> USBD_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef USBD_CONFIG_IRQ_PRIORITY
+#define USBD_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> USBD_CONFIG_DMASCHEDULER_MODE  - USBD SMA scheduler working scheme
+ 
+// <0=> Prioritized access 
+// <1=> Round Robin 
+
+#ifndef USBD_CONFIG_DMASCHEDULER_MODE
+#define USBD_CONFIG_DMASCHEDULER_MODE 0
+#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 USBD_CONFIG_DMASCHEDULER_ISO_BOOST
+#define 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.
+// <i> NOTE: This option does not work on Engineering A chip.
+
+#ifndef USBD_CONFIG_ISO_IN_ZLP
+#define USBD_CONFIG_ISO_IN_ZLP 0
+#endif
+
+// </e>
+
+// <e> WDT_ENABLED - nrf_drv_wdt - WDT peripheral driver - legacy layer
+//==========================================================
+#ifndef WDT_ENABLED
+#define WDT_ENABLED 0
+#endif
+// <o> WDT_CONFIG_BEHAVIOUR  - WDT behavior in CPU SLEEP or HALT mode
+ 
+// <1=> Run in SLEEP, Pause in HALT 
+// <8=> Pause in SLEEP, Run in HALT 
+// <9=> Run in SLEEP and HALT 
+// <0=> Pause in SLEEP and HALT 
+
+#ifndef WDT_CONFIG_BEHAVIOUR
+#define WDT_CONFIG_BEHAVIOUR 1
+#endif
+
+// <o> WDT_CONFIG_RELOAD_VALUE - Reload value  <15-4294967295> 
+
+
+#ifndef WDT_CONFIG_RELOAD_VALUE
+#define WDT_CONFIG_RELOAD_VALUE 2000
+#endif
+
+// <o> WDT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef WDT_CONFIG_IRQ_PRIORITY
+#define WDT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <h> nrfx_qspi - QSPI peripheral driver
+
+//==========================================================
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Drivers_External 
+
+//==========================================================
+// <q> NRF_TWI_SENSOR_ENABLED  - nrf_twi_sensor - nRF TWI Sensor module
+ 
+
+#ifndef NRF_TWI_SENSOR_ENABLED
+#define NRF_TWI_SENSOR_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Libraries 
+
+//==========================================================
+// <q> APP_GPIOTE_ENABLED  - app_gpiote - GPIOTE events dispatcher
+ 
+
+#ifndef APP_GPIOTE_ENABLED
+#define APP_GPIOTE_ENABLED 0
+#endif
+
+// <q> APP_PWM_ENABLED  - app_pwm - PWM functionality
+ 
+
+#ifndef APP_PWM_ENABLED
+#define APP_PWM_ENABLED 0
+#endif
+
+// <e> APP_SCHEDULER_ENABLED - app_scheduler - Events scheduler
+//==========================================================
+#ifndef APP_SCHEDULER_ENABLED
+#define APP_SCHEDULER_ENABLED 0
+#endif
+// <q> APP_SCHEDULER_WITH_PAUSE  - Enabling pause feature
+ 
+
+#ifndef APP_SCHEDULER_WITH_PAUSE
+#define APP_SCHEDULER_WITH_PAUSE 0
+#endif
+
+// <q> APP_SCHEDULER_WITH_PROFILER  - Enabling scheduler profiling
+ 
+
+#ifndef APP_SCHEDULER_WITH_PROFILER
+#define APP_SCHEDULER_WITH_PROFILER 0
+#endif
+
+// </e>
+
+// <e> APP_SDCARD_ENABLED - app_sdcard - SD/MMC card support using SPI
+//==========================================================
+#ifndef APP_SDCARD_ENABLED
+#define APP_SDCARD_ENABLED 0
+#endif
+// <o> APP_SDCARD_SPI_INSTANCE  - SPI instance used
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+
+#ifndef APP_SDCARD_SPI_INSTANCE
+#define APP_SDCARD_SPI_INSTANCE 0
+#endif
+
+// <o> APP_SDCARD_FREQ_INIT  - SPI frequency
+ 
+// <33554432=> 125 kHz 
+// <67108864=> 250 kHz 
+// <134217728=> 500 kHz 
+// <268435456=> 1 MHz 
+// <536870912=> 2 MHz 
+// <1073741824=> 4 MHz 
+// <2147483648=> 8 MHz 
+
+#ifndef APP_SDCARD_FREQ_INIT
+#define APP_SDCARD_FREQ_INIT 67108864
+#endif
+
+// <o> APP_SDCARD_FREQ_DATA  - SPI frequency
+ 
+// <33554432=> 125 kHz 
+// <67108864=> 250 kHz 
+// <134217728=> 500 kHz 
+// <268435456=> 1 MHz 
+// <536870912=> 2 MHz 
+// <1073741824=> 4 MHz 
+// <2147483648=> 8 MHz 
+
+#ifndef APP_SDCARD_FREQ_DATA
+#define APP_SDCARD_FREQ_DATA 1073741824
+#endif
+
+// </e>
+
+// <e> APP_TIMER_ENABLED - app_timer - Application timer functionality
+//==========================================================
+#ifndef APP_TIMER_ENABLED
+#define APP_TIMER_ENABLED 0
+#endif
+// <o> APP_TIMER_CONFIG_RTC_FREQUENCY  - Configure RTC prescaler.
+ 
+// <0=> 32768 Hz 
+// <1=> 16384 Hz 
+// <3=> 8192 Hz 
+// <7=> 4096 Hz 
+// <15=> 2048 Hz 
+// <31=> 1024 Hz 
+
+#ifndef APP_TIMER_CONFIG_RTC_FREQUENCY
+#define APP_TIMER_CONFIG_RTC_FREQUENCY 1
+#endif
+
+// <o> APP_TIMER_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef APP_TIMER_CONFIG_IRQ_PRIORITY
+#define APP_TIMER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> APP_TIMER_CONFIG_OP_QUEUE_SIZE - Capacity of timer requests queue. 
+// <i> Size of the queue depends on how many timers are used
+// <i> in the system, how often timers are started and overall
+// <i> system latency. If queue size is too small app_timer calls
+// <i> will fail.
+
+#ifndef APP_TIMER_CONFIG_OP_QUEUE_SIZE
+#define APP_TIMER_CONFIG_OP_QUEUE_SIZE 10
+#endif
+
+// <q> APP_TIMER_CONFIG_USE_SCHEDULER  - Enable scheduling app_timer events to app_scheduler
+ 
+
+#ifndef APP_TIMER_CONFIG_USE_SCHEDULER
+#define APP_TIMER_CONFIG_USE_SCHEDULER 0
+#endif
+
+// <q> APP_TIMER_KEEPS_RTC_ACTIVE  - Enable RTC always on
+ 
+
+// <i> If option is enabled RTC is kept running even if there is no active timers.
+// <i> This option can be used when app_timer is used for timestamping.
+
+#ifndef APP_TIMER_KEEPS_RTC_ACTIVE
+#define APP_TIMER_KEEPS_RTC_ACTIVE 0
+#endif
+
+// <o> APP_TIMER_SAFE_WINDOW_MS - Maximum possible latency (in milliseconds) of handling app_timer event. 
+// <i> Maximum possible timeout that can be set is reduced by safe window.
+// <i> Example: RTC frequency 16384 Hz, maximum possible timeout 1024 seconds - APP_TIMER_SAFE_WINDOW_MS.
+// <i> Since RTC is not stopped when processor is halted in debugging session, this value
+// <i> must cover it if debugging is needed. It is possible to halt processor for APP_TIMER_SAFE_WINDOW_MS
+// <i> without corrupting app_timer behavior.
+
+#ifndef APP_TIMER_SAFE_WINDOW_MS
+#define APP_TIMER_SAFE_WINDOW_MS 300000
+#endif
+
+// <h> App Timer Legacy configuration - Legacy configuration.
+
+//==========================================================
+// <q> APP_TIMER_WITH_PROFILER  - Enable app_timer profiling
+ 
+
+#ifndef APP_TIMER_WITH_PROFILER
+#define APP_TIMER_WITH_PROFILER 0
+#endif
+
+// <q> APP_TIMER_CONFIG_SWI_NUMBER  - Configure SWI instance used.
+ 
+
+#ifndef APP_TIMER_CONFIG_SWI_NUMBER
+#define APP_TIMER_CONFIG_SWI_NUMBER 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> APP_USBD_AUDIO_ENABLED  - app_usbd_audio - USB AUDIO class
+ 
+
+#ifndef APP_USBD_AUDIO_ENABLED
+#define APP_USBD_AUDIO_ENABLED 0
+#endif
+
+// <e> APP_USBD_ENABLED - app_usbd - USB Device library
+//==========================================================
+#ifndef APP_USBD_ENABLED
+#define APP_USBD_ENABLED 0
+#endif
+// <o> APP_USBD_VID - Vendor ID.  <0x0000-0xFFFF> 
+
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/
+
+#ifndef APP_USBD_VID
+#define APP_USBD_VID 0
+#endif
+
+// <o> APP_USBD_PID - Product ID.  <0x0000-0xFFFF> 
+
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Selected Product ID
+
+#ifndef APP_USBD_PID
+#define APP_USBD_PID 0
+#endif
+
+// <o> APP_USBD_DEVICE_VER_MAJOR - Major device version  <0-99> 
+
+
+// <i> Major device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_MAJOR
+#define APP_USBD_DEVICE_VER_MAJOR 1
+#endif
+
+// <o> APP_USBD_DEVICE_VER_MINOR - Minor device version  <0-9> 
+
+
+// <i> Minor device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_MINOR
+#define APP_USBD_DEVICE_VER_MINOR 0
+#endif
+
+// <o> APP_USBD_DEVICE_VER_SUB - Sub-minor device version  <0-9> 
+
+
+// <i> Sub-minor device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_SUB
+#define APP_USBD_DEVICE_VER_SUB 0
+#endif
+
+// <q> APP_USBD_CONFIG_SELF_POWERED  - Self-powered device, as opposed to bus-powered.
+ 
+
+#ifndef APP_USBD_CONFIG_SELF_POWERED
+#define APP_USBD_CONFIG_SELF_POWERED 1
+#endif
+
+// <o> APP_USBD_CONFIG_MAX_POWER - MaxPower field in configuration descriptor in milliamps.  <0-500> 
+
+
+#ifndef APP_USBD_CONFIG_MAX_POWER
+#define APP_USBD_CONFIG_MAX_POWER 100
+#endif
+
+// <q> APP_USBD_CONFIG_POWER_EVENTS_PROCESS  - Process power events.
+ 
+
+// <i> Enable processing power events in USB event handler.
+
+#ifndef APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+#define APP_USBD_CONFIG_POWER_EVENTS_PROCESS 1
+#endif
+
+// <e> APP_USBD_CONFIG_EVENT_QUEUE_ENABLE - Enable event queue.
+
+// <i> This is the default configuration when all the events are placed into internal queue.
+// <i> Disable it when an external queue is used like app_scheduler or if you wish to process all events inside interrupts.
+// <i> Processing all events from the interrupt level adds requirement not to call any functions that modifies the USBD library state from the context higher than USB interrupt context.
+// <i> Functions that modify USBD state are functions for sleep, wakeup, start, stop, enable, and disable.
+//==========================================================
+#ifndef APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
+#define APP_USBD_CONFIG_EVENT_QUEUE_ENABLE 1
+#endif
+// <o> APP_USBD_CONFIG_EVENT_QUEUE_SIZE - The size of the event queue.  <16-64> 
+
+
+// <i> The size of the queue for the events that would be processed in the main loop.
+
+#ifndef APP_USBD_CONFIG_EVENT_QUEUE_SIZE
+#define APP_USBD_CONFIG_EVENT_QUEUE_SIZE 32
+#endif
+
+// <o> APP_USBD_CONFIG_SOF_HANDLING_MODE  - Change SOF events handling mode.
+ 
+
+// <i> Normal queue   - SOF events are pushed normally into the event queue.
+// <i> Compress queue - SOF events are counted and binded with other events or executed when the queue is empty.
+// <i>                  This prevents the queue from filling up with SOF events.
+// <i> Interrupt      - SOF events are processed in interrupt.
+// <0=> Normal queue 
+// <1=> Compress queue 
+// <2=> Interrupt 
+
+#ifndef APP_USBD_CONFIG_SOF_HANDLING_MODE
+#define APP_USBD_CONFIG_SOF_HANDLING_MODE 1
+#endif
+
+// </e>
+
+// <q> APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE  - Provide a function that generates timestamps for logs based on the current SOF.
+ 
+
+// <i> The function app_usbd_sof_timestamp_get is implemented if the logger is enabled. 
+// <i> Use it when initializing the logger. 
+// <i> SOF processing is always enabled when this configuration parameter is active. 
+// <i> Note: This option is configured outside of APP_USBD_CONFIG_LOG_ENABLED. 
+// <i> This means that it works even if the logging in this very module is disabled. 
+
+#ifndef APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE
+#define APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE 0
+#endif
+
+// <o> APP_USBD_CONFIG_DESC_STRING_SIZE - Maximum size of the NULL-terminated string of the string descriptor.  <31-254> 
+
+
+// <i> 31 characters can be stored in the internal USB buffer used for transfers.
+// <i> Any value higher than 31 creates an additional buffer just for descriptor strings.
+
+#ifndef APP_USBD_CONFIG_DESC_STRING_SIZE
+#define APP_USBD_CONFIG_DESC_STRING_SIZE 31
+#endif
+
+// <q> APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED  - Enable UTF8 conversion.
+ 
+
+// <i> Enable UTF8-encoded characters. In normal processing, only ASCII characters are available.
+
+#ifndef APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED
+#define APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED 0
+#endif
+
+// <s> APP_USBD_STRINGS_LANGIDS - Supported languages identifiers.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Comma-separated list of supported languages.
+#ifndef APP_USBD_STRINGS_LANGIDS
+#define APP_USBD_STRINGS_LANGIDS APP_USBD_LANG_AND_SUBLANG(APP_USBD_LANG_ENGLISH, APP_USBD_SUBLANG_ENGLISH_US)
+#endif
+
+// <e> APP_USBD_STRING_ID_MANUFACTURER - Define manufacturer string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_MANUFACTURER
+#define APP_USBD_STRING_ID_MANUFACTURER 1
+#endif
+// <q> APP_USBD_STRINGS_MANUFACTURER_EXTERN  - Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN
+#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_MANUFACTURER - String descriptor for the manufacturer name.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Comma-separated list of manufacturer names for each defined language.
+// <i> Use @ref APP_USBD_STRING_DESC macro to create string descriptor from a NULL-terminated string.
+// <i> Use @ref APP_USBD_STRING_RAW8_DESC macro to create string descriptor from comma-separated uint8_t values.
+// <i> Use @ref APP_USBD_STRING_RAW16_DESC macro to create string descriptor from comma-separated uint16_t values.
+// <i> Alternatively, configure the macro to point to any internal variable pointer that already contains the descriptor.
+// <i> Setting string to NULL disables that string.
+// <i> The order of manufacturer names must be the same like in @ref APP_USBD_STRINGS_LANGIDS.
+#ifndef APP_USBD_STRINGS_MANUFACTURER
+#define APP_USBD_STRINGS_MANUFACTURER APP_USBD_STRING_DESC("Nordic Semiconductor")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_PRODUCT - Define product string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_PRODUCT
+#define APP_USBD_STRING_ID_PRODUCT 2
+#endif
+// <q> APP_USBD_STRINGS_PRODUCT_EXTERN  - Define whether @ref APP_USBD_STRINGS_PRODUCT is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
+#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_PRODUCT - String descriptor for the product name.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> List of product names that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRINGS_PRODUCT
+#define APP_USBD_STRINGS_PRODUCT APP_USBD_STRING_DESC("nRF52 USB Product")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_SERIAL - Define serial number string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_SERIAL
+#define APP_USBD_STRING_ID_SERIAL 3
+#endif
+// <q> APP_USBD_STRING_SERIAL_EXTERN  - Define whether @ref APP_USBD_STRING_SERIAL is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRING_SERIAL_EXTERN
+#define APP_USBD_STRING_SERIAL_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRING_SERIAL - String descriptor for the serial number.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRING_SERIAL
+#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("000000000000")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_CONFIGURATION - Define configuration string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_CONFIGURATION
+#define APP_USBD_STRING_ID_CONFIGURATION 4
+#endif
+// <q> APP_USBD_STRING_CONFIGURATION_EXTERN  - Define whether @ref APP_USBD_STRINGS_CONFIGURATION is created by macro or declared as global variable.
+ 
+
+#ifndef APP_USBD_STRING_CONFIGURATION_EXTERN
+#define APP_USBD_STRING_CONFIGURATION_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_CONFIGURATION - String descriptor for the device configuration.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Configuration string that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRINGS_CONFIGURATION
+#define APP_USBD_STRINGS_CONFIGURATION APP_USBD_STRING_DESC("Default configuration")
+#endif
+
+// </e>
+
+// <s> APP_USBD_STRINGS_USER - Default values for user strings.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> This value stores all application specific user strings with the default initialization.
+// <i> The setup is done by X-macros.
+// <i> Expected macro parameters:
+// <i> @code
+// <i> X(mnemonic, [=str_idx], ...)
+// <i> @endcode
+// <i> - @c mnemonic: Mnemonic of the string descriptor that would be added to
+// <i>                @ref app_usbd_string_desc_idx_t enumerator.
+// <i> - @c str_idx : String index value, can be set or left empty.
+// <i>                For example, WinUSB driver requires descriptor to be present on 0xEE index.
+// <i>                Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
+// <i> - @c ...     : List of string descriptors for each defined language.
+#ifndef APP_USBD_STRINGS_USER
+#define APP_USBD_STRINGS_USER X(APP_USER_1, , APP_USBD_STRING_DESC("User 1"))
+#endif
+
+// </e>
+
+// <e> APP_USBD_HID_ENABLED - app_usbd_hid - USB HID class
+//==========================================================
+#ifndef APP_USBD_HID_ENABLED
+#define APP_USBD_HID_ENABLED 0
+#endif
+// <o> APP_USBD_HID_DEFAULT_IDLE_RATE - Default idle rate for HID class.   <0-255> 
+
+
+// <i> 0 means indefinite duration, any other value is multiplied by 4 milliseconds. Refer to Chapter 7.2.4 of HID 1.11 Specification.
+
+#ifndef APP_USBD_HID_DEFAULT_IDLE_RATE
+#define APP_USBD_HID_DEFAULT_IDLE_RATE 0
+#endif
+
+// <o> APP_USBD_HID_REPORT_IDLE_TABLE_SIZE - Size of idle rate table.   <1-255> 
+
+
+// <i> Must be higher than the highest report ID used.
+
+#ifndef APP_USBD_HID_REPORT_IDLE_TABLE_SIZE
+#define APP_USBD_HID_REPORT_IDLE_TABLE_SIZE 4
+#endif
+
+// </e>
+
+// <q> APP_USBD_HID_GENERIC_ENABLED  - app_usbd_hid_generic - USB HID generic
+ 
+
+#ifndef APP_USBD_HID_GENERIC_ENABLED
+#define APP_USBD_HID_GENERIC_ENABLED 0
+#endif
+
+// <q> APP_USBD_HID_KBD_ENABLED  - app_usbd_hid_kbd - USB HID keyboard
+ 
+
+#ifndef APP_USBD_HID_KBD_ENABLED
+#define APP_USBD_HID_KBD_ENABLED 0
+#endif
+
+// <q> APP_USBD_HID_MOUSE_ENABLED  - app_usbd_hid_mouse - USB HID mouse
+ 
+
+#ifndef APP_USBD_HID_MOUSE_ENABLED
+#define APP_USBD_HID_MOUSE_ENABLED 0
+#endif
+
+// <q> APP_USBD_MSC_ENABLED  - app_usbd_msc - USB MSC class
+ 
+
+#ifndef APP_USBD_MSC_ENABLED
+#define APP_USBD_MSC_ENABLED 0
+#endif
+
+// <q> CRC16_ENABLED  - crc16 - CRC16 calculation routines
+ 
+
+#ifndef CRC16_ENABLED
+#define CRC16_ENABLED 0
+#endif
+
+// <q> CRC32_ENABLED  - crc32 - CRC32 calculation routines
+ 
+
+#ifndef CRC32_ENABLED
+#define CRC32_ENABLED 0
+#endif
+
+// <q> ECC_ENABLED  - ecc - Elliptic Curve Cryptography Library
+ 
+
+#ifndef ECC_ENABLED
+#define ECC_ENABLED 0
+#endif
+
+// <e> FDS_ENABLED - fds - Flash data storage module
+//==========================================================
+#ifndef FDS_ENABLED
+#define FDS_ENABLED 0
+#endif
+// <h> Pages - Virtual page settings
+
+// <i> Configure the number of virtual pages to use and their size.
+//==========================================================
+// <o> FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. 
+// <i> One of the virtual pages is reserved by the system for garbage collection.
+// <i> Therefore, the minimum is two virtual pages: one page to store data and one page to be used by the system for garbage collection.
+// <i> The total amount of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES * @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes.
+
+#ifndef FDS_VIRTUAL_PAGES
+#define FDS_VIRTUAL_PAGES 3
+#endif
+
+// <o> FDS_VIRTUAL_PAGE_SIZE  - The size of a virtual flash page.
+ 
+
+// <i> Expressed in number of 4-byte words.
+// <i> By default, a virtual page is the same size as a physical page.
+// <i> The size of a virtual page must be a multiple of the size of a physical page.
+// <1024=> 1024 
+// <2048=> 2048 
+
+#ifndef FDS_VIRTUAL_PAGE_SIZE
+#define FDS_VIRTUAL_PAGE_SIZE 1024
+#endif
+
+// <o> FDS_VIRTUAL_PAGES_RESERVED - The number of virtual flash pages that are used by other modules. 
+// <i> FDS module stores its data in the last pages of the flash memory.
+// <i> By setting this value, you can move flash end address used by the FDS.
+// <i> As a result the reserved space can be used by other modules.
+
+#ifndef FDS_VIRTUAL_PAGES_RESERVED
+#define FDS_VIRTUAL_PAGES_RESERVED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Backend - Backend configuration
+
+// <i> Configure which nrf_fstorage backend is used by FDS to write to flash.
+//==========================================================
+// <o> FDS_BACKEND  - FDS flash backend.
+ 
+
+// <i> NRF_FSTORAGE_SD uses the nrf_fstorage_sd backend implementation using the SoftDevice API. Use this if you have a SoftDevice present.
+// <i> NRF_FSTORAGE_NVMC uses the nrf_fstorage_nvmc implementation. Use this setting if you don't use the SoftDevice.
+// <1=> NRF_FSTORAGE_NVMC 
+// <2=> NRF_FSTORAGE_SD 
+
+#ifndef FDS_BACKEND
+#define FDS_BACKEND 2
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Queue - Queue settings
+
+//==========================================================
+// <o> FDS_OP_QUEUE_SIZE - Size of the internal queue. 
+// <i> Increase this value if you frequently get synchronous FDS_ERR_NO_SPACE_IN_QUEUES errors.
+
+#ifndef FDS_OP_QUEUE_SIZE
+#define FDS_OP_QUEUE_SIZE 4
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> CRC - CRC functionality
+
+//==========================================================
+// <e> FDS_CRC_CHECK_ON_READ - Enable CRC checks.
+
+// <i> Save a record's CRC when it is written to flash and check it when the record is opened.
+// <i> Records with an incorrect CRC can still be 'seen' by the user using FDS functions, but they cannot be opened.
+// <i> Additionally, they will not be garbage collected until they are deleted.
+//==========================================================
+#ifndef FDS_CRC_CHECK_ON_READ
+#define FDS_CRC_CHECK_ON_READ 0
+#endif
+// <o> FDS_CRC_CHECK_ON_WRITE  - Perform a CRC check on newly written records.
+ 
+
+// <i> Perform a CRC check on newly written records.
+// <i> This setting can be used to make sure that the record data was not altered while being written to flash.
+// <1=> Enabled 
+// <0=> Disabled 
+
+#ifndef FDS_CRC_CHECK_ON_WRITE
+#define FDS_CRC_CHECK_ON_WRITE 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> Users - Number of users
+
+//==========================================================
+// <o> FDS_MAX_USERS - Maximum number of callbacks that can be registered. 
+#ifndef FDS_MAX_USERS
+#define FDS_MAX_USERS 4
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> HARDFAULT_HANDLER_ENABLED  - hardfault_default - HardFault default handler for debugging and release
+ 
+
+#ifndef HARDFAULT_HANDLER_ENABLED
+#define HARDFAULT_HANDLER_ENABLED 0
+#endif
+
+// <e> HCI_MEM_POOL_ENABLED - hci_mem_pool - memory pool implementation used by HCI
+//==========================================================
+#ifndef HCI_MEM_POOL_ENABLED
+#define HCI_MEM_POOL_ENABLED 0
+#endif
+// <o> HCI_TX_BUF_SIZE - TX buffer size in bytes. 
+#ifndef HCI_TX_BUF_SIZE
+#define HCI_TX_BUF_SIZE 600
+#endif
+
+// <o> HCI_RX_BUF_SIZE - RX buffer size in bytes. 
+#ifndef HCI_RX_BUF_SIZE
+#define HCI_RX_BUF_SIZE 600
+#endif
+
+// <o> HCI_RX_BUF_QUEUE_SIZE - RX buffer queue size. 
+#ifndef HCI_RX_BUF_QUEUE_SIZE
+#define HCI_RX_BUF_QUEUE_SIZE 4
+#endif
+
+// </e>
+
+// <e> HCI_SLIP_ENABLED - hci_slip - SLIP protocol implementation used by HCI
+//==========================================================
+#ifndef HCI_SLIP_ENABLED
+#define HCI_SLIP_ENABLED 0
+#endif
+// <o> HCI_UART_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <10289152=> 38400 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef HCI_UART_BAUDRATE
+#define HCI_UART_BAUDRATE 30801920
+#endif
+
+// <o> HCI_UART_FLOW_CONTROL  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef HCI_UART_FLOW_CONTROL
+#define HCI_UART_FLOW_CONTROL 0
+#endif
+
+// <o> HCI_UART_RX_PIN - UART RX pin 
+#ifndef HCI_UART_RX_PIN
+#define HCI_UART_RX_PIN 31
+#endif
+
+// <o> HCI_UART_TX_PIN - UART TX pin 
+#ifndef HCI_UART_TX_PIN
+#define HCI_UART_TX_PIN 31
+#endif
+
+// <o> HCI_UART_RTS_PIN - UART RTS pin 
+#ifndef HCI_UART_RTS_PIN
+#define HCI_UART_RTS_PIN 31
+#endif
+
+// <o> HCI_UART_CTS_PIN - UART CTS pin 
+#ifndef HCI_UART_CTS_PIN
+#define HCI_UART_CTS_PIN 31
+#endif
+
+// </e>
+
+// <e> HCI_TRANSPORT_ENABLED - hci_transport - HCI transport
+//==========================================================
+#ifndef HCI_TRANSPORT_ENABLED
+#define HCI_TRANSPORT_ENABLED 0
+#endif
+// <o> HCI_MAX_PACKET_SIZE_IN_BITS - Maximum size of a single application packet in bits. 
+#ifndef HCI_MAX_PACKET_SIZE_IN_BITS
+#define HCI_MAX_PACKET_SIZE_IN_BITS 8000
+#endif
+
+// </e>
+
+// <q> LED_SOFTBLINK_ENABLED  - led_softblink - led_softblink module
+ 
+
+#ifndef LED_SOFTBLINK_ENABLED
+#define LED_SOFTBLINK_ENABLED 0
+#endif
+
+// <q> LOW_POWER_PWM_ENABLED  - low_power_pwm - low_power_pwm module
+ 
+
+#ifndef LOW_POWER_PWM_ENABLED
+#define LOW_POWER_PWM_ENABLED 0
+#endif
+
+// <e> MEM_MANAGER_ENABLED - mem_manager - Dynamic memory allocator
+//==========================================================
+#ifndef MEM_MANAGER_ENABLED
+#define MEM_MANAGER_ENABLED 0
+#endif
+// <o> MEMORY_MANAGER_SMALL_BLOCK_COUNT - Size of each memory blocks identified as 'small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_SMALL_BLOCK_COUNT 1
+#endif
+
+// <o> MEMORY_MANAGER_SMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'small' block. 
+// <i>  Size of each memory blocks identified as 'small' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_SMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_SMALL_BLOCK_SIZE 32
+#endif
+
+// <o> MEMORY_MANAGER_MEDIUM_BLOCK_COUNT - Size of each memory blocks identified as 'medium' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
+#define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_MEDIUM_BLOCK_SIZE -  Size of each memory blocks identified as 'medium' block. 
+// <i>  Size of each memory blocks identified as 'medium' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_SIZE
+#define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 256
+#endif
+
+// <o> MEMORY_MANAGER_LARGE_BLOCK_COUNT - Size of each memory blocks identified as 'large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_LARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'large' block. 
+// <i>  Size of each memory blocks identified as 'large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_LARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_LARGE_BLOCK_SIZE 256
+#endif
+
+// <o> MEMORY_MANAGER_XLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XLARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'extra large' block. 
+// <i>  Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XLARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 1320
+#endif
+
+// <o> MEMORY_MANAGER_XXLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XXLARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'extra extra large' block. 
+// <i>  Size of each memory blocks identified as 'extra extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 3444
+#endif
+
+// <o> MEMORY_MANAGER_XSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XSMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'extra small' block. 
+// <i>  Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XSMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 64
+#endif
+
+// <o> MEMORY_MANAGER_XXSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XXSMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'extra extra small' block. 
+// <i>  Size of each memory blocks identified as 'extra extra small' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 32
+#endif
+
+// <e> MEM_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef MEM_MANAGER_CONFIG_LOG_ENABLED
+#define MEM_MANAGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> MEM_MANAGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef MEM_MANAGER_CONFIG_LOG_LEVEL
+#define MEM_MANAGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> MEM_MANAGER_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 MEM_MANAGER_CONFIG_INFO_COLOR
+#define MEM_MANAGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> MEM_MANAGER_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 MEM_MANAGER_CONFIG_DEBUG_COLOR
+#define MEM_MANAGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <q> MEM_MANAGER_DISABLE_API_PARAM_CHECK  - Disable API parameter checks in the module.
+ 
+
+#ifndef MEM_MANAGER_DISABLE_API_PARAM_CHECK
+#define MEM_MANAGER_DISABLE_API_PARAM_CHECK 0
+#endif
+
+// </e>
+
+// <e> NRF_BALLOC_ENABLED - nrf_balloc - Block allocator module
+//==========================================================
+#ifndef NRF_BALLOC_ENABLED
+#define NRF_BALLOC_ENABLED 1
+#endif
+// <e> NRF_BALLOC_CONFIG_DEBUG_ENABLED - Enables debug mode in the module.
+//==========================================================
+#ifndef NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define NRF_BALLOC_CONFIG_DEBUG_ENABLED 0
+#endif
+// <o> NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS - Number of words used as head guard.  <0-255> 
+
+
+#ifndef NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS
+#define NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS 1
+#endif
+
+// <o> NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS - Number of words used as tail guard.  <0-255> 
+
+
+#ifndef NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS
+#define NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS 1
+#endif
+
+// <q> NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED  - Enables basic checks in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED
+#define NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED  - Enables double memory free check in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED
+#define NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED  - Enables free memory corruption check in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED
+#define NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef NRF_BALLOC_CLI_CMDS
+#define NRF_BALLOC_CLI_CMDS 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRF_CSENSE_ENABLED - nrf_csense - Capacitive sensor module
+//==========================================================
+#ifndef NRF_CSENSE_ENABLED
+#define NRF_CSENSE_ENABLED 0
+#endif
+// <o> NRF_CSENSE_PAD_HYSTERESIS - Minimum value of change required to determine that a pad was touched. 
+#ifndef NRF_CSENSE_PAD_HYSTERESIS
+#define NRF_CSENSE_PAD_HYSTERESIS 15
+#endif
+
+// <o> NRF_CSENSE_PAD_DEVIATION - Minimum value measured on a pad required to take it into account while calculating the step. 
+#ifndef NRF_CSENSE_PAD_DEVIATION
+#define NRF_CSENSE_PAD_DEVIATION 70
+#endif
+
+// <o> NRF_CSENSE_MIN_PAD_VALUE - Minimum normalized value on a pad required to take its value into account. 
+#ifndef NRF_CSENSE_MIN_PAD_VALUE
+#define NRF_CSENSE_MIN_PAD_VALUE 20
+#endif
+
+// <o> NRF_CSENSE_MAX_PADS_NUMBER - Maximum number of pads used for one instance. 
+#ifndef NRF_CSENSE_MAX_PADS_NUMBER
+#define NRF_CSENSE_MAX_PADS_NUMBER 20
+#endif
+
+// <o> NRF_CSENSE_MAX_VALUE - Maximum normalized value obtained from measurement. 
+#ifndef NRF_CSENSE_MAX_VALUE
+#define NRF_CSENSE_MAX_VALUE 1000
+#endif
+
+// <o> NRF_CSENSE_OUTPUT_PIN - Output pin used by the low-level module. 
+// <i> This is used when capacitive sensor does not use COMP.
+
+#ifndef NRF_CSENSE_OUTPUT_PIN
+#define NRF_CSENSE_OUTPUT_PIN 26
+#endif
+
+// </e>
+
+// <e> NRF_DRV_CSENSE_ENABLED - nrf_drv_csense - Capacitive sensor low-level module
+//==========================================================
+#ifndef NRF_DRV_CSENSE_ENABLED
+#define NRF_DRV_CSENSE_ENABLED 0
+#endif
+// <e> USE_COMP - Use the comparator to implement the capacitive sensor driver.
+
+// <i> Due to Anomaly 84, COMP I_SOURCE is not functional. It has too high a varation.
+//==========================================================
+#ifndef USE_COMP
+#define USE_COMP 0
+#endif
+// <o> TIMER0_FOR_CSENSE - First TIMER instance used by the driver (not used on nRF51). 
+#ifndef TIMER0_FOR_CSENSE
+#define TIMER0_FOR_CSENSE 1
+#endif
+
+// <o> TIMER1_FOR_CSENSE - Second TIMER instance used by the driver (not used on nRF51). 
+#ifndef TIMER1_FOR_CSENSE
+#define TIMER1_FOR_CSENSE 2
+#endif
+
+// <o> MEASUREMENT_PERIOD - Single measurement period. 
+// <i> Time of a single measurement can be calculated as
+// <i> T = (1/2)*MEASUREMENT_PERIOD*(1/f_OSC) where f_OSC = I_SOURCE / (2C*(VUP-VDOWN) ).
+// <i> I_SOURCE, VUP, and VDOWN are values used to initialize COMP and C is the capacitance of the used pad.
+
+#ifndef MEASUREMENT_PERIOD
+#define MEASUREMENT_PERIOD 20
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRF_FSTORAGE_ENABLED - nrf_fstorage - Flash abstraction library
+//==========================================================
+#ifndef NRF_FSTORAGE_ENABLED
+#define NRF_FSTORAGE_ENABLED 0
+#endif
+// <h> nrf_fstorage - Common settings
+
+// <i> Common settings to all fstorage implementations
+//==========================================================
+// <q> NRF_FSTORAGE_PARAM_CHECK_DISABLED  - Disable user input validation
+ 
+
+// <i> If selected, use ASSERT to validate user input.
+// <i> This effectively removes user input validation in production code.
+// <i> Recommended setting: OFF, only enable this setting if size is a major concern.
+
+#ifndef NRF_FSTORAGE_PARAM_CHECK_DISABLED
+#define NRF_FSTORAGE_PARAM_CHECK_DISABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_fstorage_sd - Implementation using the SoftDevice
+
+// <i> Configuration options for the fstorage implementation using the SoftDevice
+//==========================================================
+// <o> NRF_FSTORAGE_SD_QUEUE_SIZE - Size of the internal queue of operations 
+// <i> Increase this value if API calls frequently return the error @ref NRF_ERROR_NO_MEM.
+
+#ifndef NRF_FSTORAGE_SD_QUEUE_SIZE
+#define NRF_FSTORAGE_SD_QUEUE_SIZE 4
+#endif
+
+// <o> NRF_FSTORAGE_SD_MAX_RETRIES - Maximum number of attempts at executing an operation when the SoftDevice is busy 
+// <i> Increase this value if events frequently return the @ref NRF_ERROR_TIMEOUT error.
+// <i> The SoftDevice might fail to schedule flash access due to high BLE activity.
+
+#ifndef NRF_FSTORAGE_SD_MAX_RETRIES
+#define NRF_FSTORAGE_SD_MAX_RETRIES 8
+#endif
+
+// <o> NRF_FSTORAGE_SD_MAX_WRITE_SIZE - Maximum number of bytes to be written to flash in a single operation 
+// <i> This value must be a multiple of four.
+// <i> Lowering this value can increase the chances of the SoftDevice being able to execute flash operations in between radio activity.
+// <i> This value is bound by the maximum number of bytes that can be written to flash in a single call to @ref sd_flash_write.
+// <i> That is 1024 bytes for nRF51 ICs and 4096 bytes for nRF52 ICs.
+
+#ifndef NRF_FSTORAGE_SD_MAX_WRITE_SIZE
+#define NRF_FSTORAGE_SD_MAX_WRITE_SIZE 4096
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> NRF_GFX_ENABLED  - nrf_gfx - GFX module
+ 
+
+#ifndef NRF_GFX_ENABLED
+#define NRF_GFX_ENABLED 0
+#endif
+
+// <q> NRF_MEMOBJ_ENABLED  - nrf_memobj - Linked memory allocator module
+ 
+
+#ifndef NRF_MEMOBJ_ENABLED
+#define NRF_MEMOBJ_ENABLED 1
+#endif
+
+// <e> NRF_PWR_MGMT_ENABLED - nrf_pwr_mgmt - Power management module
+//==========================================================
+#ifndef NRF_PWR_MGMT_ENABLED
+#define NRF_PWR_MGMT_ENABLED 0
+#endif
+// <e> NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED - Enables pin debug in the module.
+
+// <i> Selected pin will be set when CPU is in sleep mode.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED
+#define NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_SLEEP_DEBUG_PIN  - Pin number
+ 
+// <0=> 0 (P0.0) 
+// <1=> 1 (P0.1) 
+// <2=> 2 (P0.2) 
+// <3=> 3 (P0.3) 
+// <4=> 4 (P0.4) 
+// <5=> 5 (P0.5) 
+// <6=> 6 (P0.6) 
+// <7=> 7 (P0.7) 
+// <8=> 8 (P0.8) 
+// <9=> 9 (P0.9) 
+// <10=> 10 (P0.10) 
+// <11=> 11 (P0.11) 
+// <12=> 12 (P0.12) 
+// <13=> 13 (P0.13) 
+// <14=> 14 (P0.14) 
+// <15=> 15 (P0.15) 
+// <16=> 16 (P0.16) 
+// <17=> 17 (P0.17) 
+// <18=> 18 (P0.18) 
+// <19=> 19 (P0.19) 
+// <20=> 20 (P0.20) 
+// <21=> 21 (P0.21) 
+// <22=> 22 (P0.22) 
+// <23=> 23 (P0.23) 
+// <24=> 24 (P0.24) 
+// <25=> 25 (P0.25) 
+// <26=> 26 (P0.26) 
+// <27=> 27 (P0.27) 
+// <28=> 28 (P0.28) 
+// <29=> 29 (P0.29) 
+// <30=> 30 (P0.30) 
+// <31=> 31 (P0.31) 
+// <32=> 32 (P1.0) 
+// <33=> 33 (P1.1) 
+// <34=> 34 (P1.2) 
+// <35=> 35 (P1.3) 
+// <36=> 36 (P1.4) 
+// <37=> 37 (P1.5) 
+// <38=> 38 (P1.6) 
+// <39=> 39 (P1.7) 
+// <40=> 40 (P1.8) 
+// <41=> 41 (P1.9) 
+// <42=> 42 (P1.10) 
+// <43=> 43 (P1.11) 
+// <44=> 44 (P1.12) 
+// <45=> 45 (P1.13) 
+// <46=> 46 (P1.14) 
+// <47=> 47 (P1.15) 
+// <4294967295=> Not connected 
+
+#ifndef NRF_PWR_MGMT_SLEEP_DEBUG_PIN
+#define NRF_PWR_MGMT_SLEEP_DEBUG_PIN 31
+#endif
+
+// </e>
+
+// <q> NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED  - Enables CPU usage monitor.
+ 
+
+// <i> Module will trace percentage of CPU usage in one second intervals.
+
+#ifndef NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED
+#define NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED 0
+#endif
+
+// <e> NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED - Enable standby timeout.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED
+#define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S - Standby timeout (in seconds). 
+// <i> Shutdown procedure will begin no earlier than after this number of seconds.
+
+#ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S
+#define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S 3
+#endif
+
+// </e>
+
+// <q> NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED  - Enables FPU event cleaning.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED
+#define NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED 0
+#endif
+
+// <q> NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY  - Blocked shutdown procedure will be retried every second.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
+#define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 0
+#endif
+
+// <q> NRF_PWR_MGMT_CONFIG_USE_SCHEDULER  - Module will use @ref app_scheduler.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+#define NRF_PWR_MGMT_CONFIG_USE_SCHEDULER 0
+#endif
+
+// <o> NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT - The number of priorities for module handlers. 
+// <i> The number of stages of the shutdown process.
+
+#ifndef NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT
+#define NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT 3
+#endif
+
+// </e>
+
+// <e> NRF_QUEUE_ENABLED - nrf_queue - Queue module
+//==========================================================
+#ifndef NRF_QUEUE_ENABLED
+#define NRF_QUEUE_ENABLED 0
+#endif
+// <q> NRF_QUEUE_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef NRF_QUEUE_CLI_CMDS
+#define NRF_QUEUE_CLI_CMDS 0
+#endif
+
+// </e>
+
+// <q> NRF_SECTION_ITER_ENABLED  - nrf_section_iter - Section iterator
+ 
+
+#ifndef NRF_SECTION_ITER_ENABLED
+#define NRF_SECTION_ITER_ENABLED 1
+#endif
+
+// <q> NRF_SORTLIST_ENABLED  - nrf_sortlist - Sorted list
+ 
+
+#ifndef NRF_SORTLIST_ENABLED
+#define NRF_SORTLIST_ENABLED 1
+#endif
+
+// <q> NRF_SPI_MNGR_ENABLED  - nrf_spi_mngr - SPI transaction manager
+ 
+
+#ifndef NRF_SPI_MNGR_ENABLED
+#define NRF_SPI_MNGR_ENABLED 0
+#endif
+
+// <q> NRF_STRERROR_ENABLED  - nrf_strerror - Library for converting error code to string.
+ 
+
+#ifndef NRF_STRERROR_ENABLED
+#define NRF_STRERROR_ENABLED 1
+#endif
+
+// <q> NRF_TWI_MNGR_ENABLED  - nrf_twi_mngr - TWI transaction manager
+ 
+
+#ifndef NRF_TWI_MNGR_ENABLED
+#define NRF_TWI_MNGR_ENABLED 0
+#endif
+
+// <q> SLIP_ENABLED  - slip - SLIP encoding and decoding
+ 
+
+#ifndef SLIP_ENABLED
+#define SLIP_ENABLED 0
+#endif
+
+// <e> TASK_MANAGER_ENABLED - task_manager - Task manager.
+//==========================================================
+#ifndef TASK_MANAGER_ENABLED
+#define TASK_MANAGER_ENABLED 0
+#endif
+// <q> TASK_MANAGER_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef TASK_MANAGER_CLI_CMDS
+#define TASK_MANAGER_CLI_CMDS 0
+#endif
+
+// <o> TASK_MANAGER_CONFIG_MAX_TASKS - Maximum number of tasks which can be created 
+#ifndef TASK_MANAGER_CONFIG_MAX_TASKS
+#define TASK_MANAGER_CONFIG_MAX_TASKS 2
+#endif
+
+// <o> TASK_MANAGER_CONFIG_STACK_SIZE - Stack size for every task (power of 2) 
+#ifndef TASK_MANAGER_CONFIG_STACK_SIZE
+#define TASK_MANAGER_CONFIG_STACK_SIZE 1024
+#endif
+
+// <q> TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED  - Enable stack profiling.
+ 
+
+#ifndef TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED
+#define TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED 1
+#endif
+
+// <o> TASK_MANAGER_CONFIG_STACK_GUARD  - Configures stack guard.
+ 
+// <0=> Disabled 
+// <4=> 32 bytes 
+// <5=> 64 bytes 
+// <6=> 128 bytes 
+// <7=> 256 bytes 
+// <8=> 512 bytes 
+
+#ifndef TASK_MANAGER_CONFIG_STACK_GUARD
+#define TASK_MANAGER_CONFIG_STACK_GUARD 7
+#endif
+
+// </e>
+
+// <h> app_button - buttons handling module
+
+//==========================================================
+// <q> BUTTON_ENABLED  - Enables Button module
+ 
+
+#ifndef BUTTON_ENABLED
+#define BUTTON_ENABLED 0
+#endif
+
+// <q> BUTTON_HIGH_ACCURACY_ENABLED  - Enables GPIOTE high accuracy for buttons
+ 
+
+#ifndef BUTTON_HIGH_ACCURACY_ENABLED
+#define BUTTON_HIGH_ACCURACY_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> app_usbd_cdc_acm - USB CDC ACM class
+
+//==========================================================
+// <q> APP_USBD_CDC_ACM_ENABLED  - Enabling USBD CDC ACM Class library
+ 
+
+#ifndef APP_USBD_CDC_ACM_ENABLED
+#define APP_USBD_CDC_ACM_ENABLED 0
+#endif
+
+// <q> APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE  - Send ZLP on write with same size as endpoint
+ 
+
+// <i> If enabled, CDC ACM class will automatically send a zero length packet after transfer which has the same size as endpoint.
+// <i> This may limit throughput if a lot of binary data is sent, but in terminal mode operation it makes sure that the data is always displayed right after it is sent.
+
+#ifndef APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE
+#define APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE 1
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_cli - Command line interface
+
+//==========================================================
+// <q> NRF_CLI_ENABLED  - Enable/disable the CLI module.
+ 
+
+#ifndef NRF_CLI_ENABLED
+#define NRF_CLI_ENABLED 0
+#endif
+
+// <o> NRF_CLI_ARGC_MAX - Maximum number of parameters passed to the command handler. 
+#ifndef NRF_CLI_ARGC_MAX
+#define NRF_CLI_ARGC_MAX 12
+#endif
+
+// <q> NRF_CLI_BUILD_IN_CMDS_ENABLED  - CLI built-in commands.
+ 
+
+#ifndef NRF_CLI_BUILD_IN_CMDS_ENABLED
+#define NRF_CLI_BUILD_IN_CMDS_ENABLED 1
+#endif
+
+// <o> NRF_CLI_CMD_BUFF_SIZE - Maximum buffer size for a single command. 
+#ifndef NRF_CLI_CMD_BUFF_SIZE
+#define NRF_CLI_CMD_BUFF_SIZE 128
+#endif
+
+// <q> NRF_CLI_ECHO_STATUS  - CLI echo status. If set, echo is ON.
+ 
+
+#ifndef NRF_CLI_ECHO_STATUS
+#define NRF_CLI_ECHO_STATUS 1
+#endif
+
+// <q> NRF_CLI_WILDCARD_ENABLED  - Enable wildcard functionality for CLI commands.
+ 
+
+#ifndef NRF_CLI_WILDCARD_ENABLED
+#define NRF_CLI_WILDCARD_ENABLED 0
+#endif
+
+// <q> NRF_CLI_METAKEYS_ENABLED  - Enable additional control keys for CLI commands like ctrl+a, ctrl+e, ctrl+w, ctrl+u
+ 
+
+#ifndef NRF_CLI_METAKEYS_ENABLED
+#define NRF_CLI_METAKEYS_ENABLED 0
+#endif
+
+// <o> NRF_CLI_PRINTF_BUFF_SIZE - Maximum print buffer size. 
+#ifndef NRF_CLI_PRINTF_BUFF_SIZE
+#define NRF_CLI_PRINTF_BUFF_SIZE 23
+#endif
+
+// <e> NRF_CLI_HISTORY_ENABLED - Enable CLI history mode.
+//==========================================================
+#ifndef NRF_CLI_HISTORY_ENABLED
+#define NRF_CLI_HISTORY_ENABLED 1
+#endif
+// <o> NRF_CLI_HISTORY_ELEMENT_SIZE - Size of one memory object reserved for CLI history. 
+#ifndef NRF_CLI_HISTORY_ELEMENT_SIZE
+#define NRF_CLI_HISTORY_ELEMENT_SIZE 32
+#endif
+
+// <o> NRF_CLI_HISTORY_ELEMENT_COUNT - Number of history memory objects. 
+#ifndef NRF_CLI_HISTORY_ELEMENT_COUNT
+#define NRF_CLI_HISTORY_ELEMENT_COUNT 8
+#endif
+
+// </e>
+
+// <q> NRF_CLI_VT100_COLORS_ENABLED  - CLI VT100 colors.
+ 
+
+#ifndef NRF_CLI_VT100_COLORS_ENABLED
+#define NRF_CLI_VT100_COLORS_ENABLED 1
+#endif
+
+// <q> NRF_CLI_STATISTICS_ENABLED  - Enable CLI statistics.
+ 
+
+#ifndef NRF_CLI_STATISTICS_ENABLED
+#define NRF_CLI_STATISTICS_ENABLED 1
+#endif
+
+// <q> NRF_CLI_LOG_BACKEND  - Enable logger backend interface.
+ 
+
+#ifndef NRF_CLI_LOG_BACKEND
+#define NRF_CLI_LOG_BACKEND 1
+#endif
+
+// <q> NRF_CLI_USES_TASK_MANAGER_ENABLED  - Enable CLI to use task_manager
+ 
+
+#ifndef NRF_CLI_USES_TASK_MANAGER_ENABLED
+#define NRF_CLI_USES_TASK_MANAGER_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_fprintf - fprintf function.
+
+//==========================================================
+// <q> NRF_FPRINTF_ENABLED  - Enable/disable fprintf module.
+ 
+
+#ifndef NRF_FPRINTF_ENABLED
+#define NRF_FPRINTF_ENABLED 1
+#endif
+
+// <q> NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED  - For each printed LF, function will add CR.
+ 
+
+#ifndef NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED
+#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1
+#endif
+
+// <q> NRF_FPRINTF_DOUBLE_ENABLED  - Enable IEEE-754 double precision formatting.
+ 
+
+#ifndef NRF_FPRINTF_DOUBLE_ENABLED
+#define NRF_FPRINTF_DOUBLE_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Log 
+
+//==========================================================
+// <e> NRF_LOG_ENABLED - nrf_log - Logger
+//==========================================================
+#ifndef NRF_LOG_ENABLED
+#define NRF_LOG_ENABLED 0
+#endif
+// <h> Log message pool - Configuration of log message pool
+
+//==========================================================
+// <o> NRF_LOG_MSGPOOL_ELEMENT_SIZE - Size of a single element in the pool of memory objects. 
+// <i> If a small value is set, then performance of logs processing
+// <i> is degraded because data is fragmented. Bigger value impacts
+// <i> RAM memory utilization. The size is set to fit a message with
+// <i> a timestamp and up to 2 arguments in a single memory object.
+
+#ifndef NRF_LOG_MSGPOOL_ELEMENT_SIZE
+#define NRF_LOG_MSGPOOL_ELEMENT_SIZE 20
+#endif
+
+// <o> NRF_LOG_MSGPOOL_ELEMENT_COUNT - Number of elements in the pool of memory objects 
+// <i> If a small value is set, then it may lead to a deadlock
+// <i> in certain cases if backend has high latency and holds
+// <i> multiple messages for long time. Bigger value impacts
+// <i> RAM memory usage.
+
+#ifndef NRF_LOG_MSGPOOL_ELEMENT_COUNT
+#define NRF_LOG_MSGPOOL_ELEMENT_COUNT 8
+#endif
+
+// </h> 
+//==========================================================
+
+// <q> NRF_LOG_ALLOW_OVERFLOW  - Configures behavior when circular buffer is full.
+ 
+
+// <i> If set then oldest logs are overwritten. Otherwise a 
+// <i> marker is injected informing about overflow.
+
+#ifndef NRF_LOG_ALLOW_OVERFLOW
+#define NRF_LOG_ALLOW_OVERFLOW 1
+#endif
+
+// <o> NRF_LOG_BUFSIZE  - Size of the buffer for storing logs (in bytes).
+ 
+
+// <i> Must be power of 2 and multiple of 4.
+// <i> If NRF_LOG_DEFERRED = 0 then buffer size can be reduced to minimum.
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+// <2048=> 2048 
+// <4096=> 4096 
+// <8192=> 8192 
+// <16384=> 16384 
+
+#ifndef NRF_LOG_BUFSIZE
+#define NRF_LOG_BUFSIZE 1024
+#endif
+
+// <q> NRF_LOG_CLI_CMDS  - Enable CLI commands for the module.
+ 
+
+#ifndef NRF_LOG_CLI_CMDS
+#define NRF_LOG_CLI_CMDS 0
+#endif
+
+// <o> NRF_LOG_DEFAULT_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_LOG_DEFAULT_LEVEL
+#define NRF_LOG_DEFAULT_LEVEL 3
+#endif
+
+// <q> NRF_LOG_DEFERRED  - Enable deffered logger.
+ 
+
+// <i> Log data is buffered and can be processed in idle.
+
+#ifndef NRF_LOG_DEFERRED
+#define NRF_LOG_DEFERRED 1
+#endif
+
+// <q> NRF_LOG_FILTERS_ENABLED  - Enable dynamic filtering of logs.
+ 
+
+#ifndef NRF_LOG_FILTERS_ENABLED
+#define NRF_LOG_FILTERS_ENABLED 0
+#endif
+
+// <q> NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED  - Enable use of critical region for non deffered mode when flushing logs.
+ 
+
+// <i> When enabled NRF_LOG_FLUSH is called from critical section when non deffered mode is used.
+// <i> Log output will never be corrupted as access to the log backend is exclusive
+// <i> but system will spend significant amount of time in critical section
+
+#ifndef NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED
+#define NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED 0
+#endif
+
+// <o> NRF_LOG_STR_PUSH_BUFFER_SIZE  - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH.
+ 
+// <16=> 16 
+// <32=> 32 
+// <64=> 64 
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+
+#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE
+#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128
+#endif
+
+// <o> NRF_LOG_STR_PUSH_BUFFER_SIZE  - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH.
+ 
+// <16=> 16 
+// <32=> 32 
+// <64=> 64 
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+
+#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE
+#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128
+#endif
+
+// <e> NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string
+//==========================================================
+#ifndef NRF_LOG_USES_COLORS
+#define NRF_LOG_USES_COLORS 0
+#endif
+// <o> NRF_LOG_COLOR_DEFAULT  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_COLOR_DEFAULT
+#define NRF_LOG_COLOR_DEFAULT 0
+#endif
+
+// <o> NRF_LOG_ERROR_COLOR  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_ERROR_COLOR
+#define NRF_LOG_ERROR_COLOR 2
+#endif
+
+// <o> NRF_LOG_WARNING_COLOR  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_WARNING_COLOR
+#define NRF_LOG_WARNING_COLOR 4
+#endif
+
+// </e>
+
+// <e> NRF_LOG_USES_TIMESTAMP - Enable timestamping
+
+// <i> Function for getting the timestamp is provided by the user
+//==========================================================
+#ifndef NRF_LOG_USES_TIMESTAMP
+#define NRF_LOG_USES_TIMESTAMP 0
+#endif
+// <o> NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY - Default frequency of the timestamp (in Hz) or 0 to use app_timer frequency. 
+#ifndef NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY
+#define NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY 0
+#endif
+
+// </e>
+
+// <h> nrf_log module configuration 
+
+//==========================================================
+// <h> nrf_log in nRF_Core 
+
+//==========================================================
+// <e> NRF_MPU_LIB_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_MPU_LIB_CONFIG_LOG_ENABLED
+#define NRF_MPU_LIB_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_MPU_LIB_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_MPU_LIB_CONFIG_LOG_LEVEL
+#define NRF_MPU_LIB_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_MPU_LIB_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 NRF_MPU_LIB_CONFIG_INFO_COLOR
+#define NRF_MPU_LIB_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_MPU_LIB_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 NRF_MPU_LIB_CONFIG_DEBUG_COLOR
+#define NRF_MPU_LIB_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_STACK_GUARD_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_STACK_GUARD_CONFIG_LOG_ENABLED
+#define NRF_STACK_GUARD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_STACK_GUARD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_STACK_GUARD_CONFIG_LOG_LEVEL
+#define NRF_STACK_GUARD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_STACK_GUARD_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 NRF_STACK_GUARD_CONFIG_INFO_COLOR
+#define NRF_STACK_GUARD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_STACK_GUARD_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 NRF_STACK_GUARD_CONFIG_DEBUG_COLOR
+#define NRF_STACK_GUARD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TASK_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TASK_MANAGER_CONFIG_LOG_ENABLED
+#define TASK_MANAGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TASK_MANAGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TASK_MANAGER_CONFIG_LOG_LEVEL
+#define TASK_MANAGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> TASK_MANAGER_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 TASK_MANAGER_CONFIG_INFO_COLOR
+#define TASK_MANAGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> TASK_MANAGER_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 TASK_MANAGER_CONFIG_DEBUG_COLOR
+#define TASK_MANAGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Drivers 
+
+//==========================================================
+// <e> CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef CLOCK_CONFIG_LOG_ENABLED
+#define CLOCK_CONFIG_LOG_ENABLED 0
+#endif
+// <o> CLOCK_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef CLOCK_CONFIG_LOG_LEVEL
+#define CLOCK_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 CLOCK_CONFIG_INFO_COLOR
+#define CLOCK_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 CLOCK_CONFIG_DEBUG_COLOR
+#define CLOCK_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> COMP_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef COMP_CONFIG_LOG_ENABLED
+#define COMP_CONFIG_LOG_ENABLED 0
+#endif
+// <o> COMP_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef COMP_CONFIG_LOG_LEVEL
+#define COMP_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 COMP_CONFIG_INFO_COLOR
+#define COMP_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 COMP_CONFIG_DEBUG_COLOR
+#define COMP_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef GPIOTE_CONFIG_LOG_ENABLED
+#define GPIOTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> GPIOTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef GPIOTE_CONFIG_LOG_LEVEL
+#define GPIOTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 GPIOTE_CONFIG_INFO_COLOR
+#define GPIOTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 GPIOTE_CONFIG_DEBUG_COLOR
+#define GPIOTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef LPCOMP_CONFIG_LOG_ENABLED
+#define LPCOMP_CONFIG_LOG_ENABLED 0
+#endif
+// <o> LPCOMP_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef LPCOMP_CONFIG_LOG_LEVEL
+#define LPCOMP_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 LPCOMP_CONFIG_INFO_COLOR
+#define LPCOMP_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 LPCOMP_CONFIG_DEBUG_COLOR
+#define LPCOMP_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> MAX3421E_HOST_CONFIG_LOG_ENABLED - Enable logging in the module
+//==========================================================
+#ifndef MAX3421E_HOST_CONFIG_LOG_ENABLED
+#define MAX3421E_HOST_CONFIG_LOG_ENABLED 0
+#endif
+// <o> MAX3421E_HOST_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef MAX3421E_HOST_CONFIG_LOG_LEVEL
+#define MAX3421E_HOST_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> MAX3421E_HOST_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 MAX3421E_HOST_CONFIG_INFO_COLOR
+#define MAX3421E_HOST_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> MAX3421E_HOST_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 MAX3421E_HOST_CONFIG_DEBUG_COLOR
+#define MAX3421E_HOST_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <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> PDM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PDM_CONFIG_LOG_ENABLED
+#define PDM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PDM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PDM_CONFIG_LOG_LEVEL
+#define PDM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 PDM_CONFIG_INFO_COLOR
+#define PDM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 PDM_CONFIG_DEBUG_COLOR
+#define PDM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PPI_CONFIG_LOG_ENABLED
+#define PPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PPI_CONFIG_LOG_LEVEL
+#define PPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> PPI_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 PPI_CONFIG_INFO_COLOR
+#define PPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> PPI_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 PPI_CONFIG_DEBUG_COLOR
+#define PPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PWM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PWM_CONFIG_LOG_ENABLED
+#define PWM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PWM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PWM_CONFIG_LOG_LEVEL
+#define PWM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 PWM_CONFIG_INFO_COLOR
+#define PWM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 PWM_CONFIG_DEBUG_COLOR
+#define PWM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> QDEC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef QDEC_CONFIG_LOG_ENABLED
+#define QDEC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> QDEC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef QDEC_CONFIG_LOG_LEVEL
+#define QDEC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 QDEC_CONFIG_INFO_COLOR
+#define QDEC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 QDEC_CONFIG_DEBUG_COLOR
+#define QDEC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> RNG_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef RNG_CONFIG_LOG_ENABLED
+#define RNG_CONFIG_LOG_ENABLED 0
+#endif
+// <o> RNG_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef RNG_CONFIG_LOG_LEVEL
+#define RNG_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> RNG_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 RNG_CONFIG_INFO_COLOR
+#define RNG_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> RNG_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 RNG_CONFIG_DEBUG_COLOR
+#define RNG_CONFIG_DEBUG_COLOR 0
+#endif
+
+// <q> RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED  - Enables logging of random numbers.
+ 
+
+#ifndef RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED
+#define RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED 0
+#endif
+
+// </e>
+
+// <e> RTC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef RTC_CONFIG_LOG_ENABLED
+#define RTC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> RTC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef RTC_CONFIG_LOG_LEVEL
+#define RTC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 RTC_CONFIG_INFO_COLOR
+#define RTC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 RTC_CONFIG_DEBUG_COLOR
+#define RTC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SAADC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SAADC_CONFIG_LOG_ENABLED
+#define SAADC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SAADC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SAADC_CONFIG_LOG_LEVEL
+#define SAADC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 SAADC_CONFIG_INFO_COLOR
+#define SAADC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 SAADC_CONFIG_DEBUG_COLOR
+#define SAADC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SPIS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SPIS_CONFIG_LOG_ENABLED
+#define SPIS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SPIS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SPIS_CONFIG_LOG_LEVEL
+#define SPIS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 SPIS_CONFIG_INFO_COLOR
+#define SPIS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 SPIS_CONFIG_DEBUG_COLOR
+#define SPIS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SPI_CONFIG_LOG_ENABLED
+#define SPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SPI_CONFIG_LOG_LEVEL
+#define SPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> SPI_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 SPI_CONFIG_INFO_COLOR
+#define SPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> SPI_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 SPI_CONFIG_DEBUG_COLOR
+#define SPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TIMER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TIMER_CONFIG_LOG_ENABLED
+#define TIMER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TIMER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TIMER_CONFIG_LOG_LEVEL
+#define TIMER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 TIMER_CONFIG_INFO_COLOR
+#define TIMER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 TIMER_CONFIG_DEBUG_COLOR
+#define TIMER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TWIS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TWIS_CONFIG_LOG_ENABLED
+#define TWIS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TWIS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TWIS_CONFIG_LOG_LEVEL
+#define TWIS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 TWIS_CONFIG_INFO_COLOR
+#define TWIS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 TWIS_CONFIG_DEBUG_COLOR
+#define TWIS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TWI_CONFIG_LOG_ENABLED
+#define TWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TWI_CONFIG_LOG_LEVEL
+#define TWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> TWI_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 TWI_CONFIG_INFO_COLOR
+#define TWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> TWI_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 TWI_CONFIG_DEBUG_COLOR
+#define TWI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef UART_CONFIG_LOG_ENABLED
+#define UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef UART_CONFIG_LOG_LEVEL
+#define UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> UART_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 UART_CONFIG_INFO_COLOR
+#define UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> UART_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 UART_CONFIG_DEBUG_COLOR
+#define UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> USBD_CONFIG_LOG_ENABLED - Enable logging in the module
+//==========================================================
+#ifndef USBD_CONFIG_LOG_ENABLED
+#define USBD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> USBD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef USBD_CONFIG_LOG_LEVEL
+#define USBD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 USBD_CONFIG_INFO_COLOR
+#define USBD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 USBD_CONFIG_DEBUG_COLOR
+#define USBD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> WDT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef WDT_CONFIG_LOG_ENABLED
+#define WDT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> WDT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef WDT_CONFIG_LOG_LEVEL
+#define WDT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 WDT_CONFIG_INFO_COLOR
+#define WDT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 WDT_CONFIG_DEBUG_COLOR
+#define WDT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Libraries 
+
+//==========================================================
+// <e> APP_BUTTON_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_BUTTON_CONFIG_LOG_ENABLED
+#define APP_BUTTON_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_BUTTON_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_BUTTON_CONFIG_LOG_LEVEL
+#define APP_BUTTON_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL
+#define APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> APP_BUTTON_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 APP_BUTTON_CONFIG_INFO_COLOR
+#define APP_BUTTON_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_BUTTON_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 APP_BUTTON_CONFIG_DEBUG_COLOR
+#define APP_BUTTON_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_TIMER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_TIMER_CONFIG_LOG_ENABLED
+#define APP_TIMER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_TIMER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_TIMER_CONFIG_LOG_LEVEL
+#define APP_TIMER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_TIMER_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_TIMER_CONFIG_INITIAL_LOG_LEVEL
+#define APP_TIMER_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> APP_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 APP_TIMER_CONFIG_INFO_COLOR
+#define APP_TIMER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_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 APP_TIMER_CONFIG_DEBUG_COLOR
+#define APP_TIMER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL
+#define APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_CDC_ACM_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 APP_USBD_CDC_ACM_CONFIG_INFO_COLOR
+#define APP_USBD_CDC_ACM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_CDC_ACM_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 APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR
+#define APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module.
+//==========================================================
+#ifndef APP_USBD_CONFIG_LOG_ENABLED
+#define APP_USBD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_CONFIG_LOG_LEVEL
+#define APP_USBD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_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 APP_USBD_CONFIG_INFO_COLOR
+#define APP_USBD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_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 APP_USBD_CONFIG_DEBUG_COLOR
+#define APP_USBD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_DUMMY_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#define APP_USBD_DUMMY_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_DUMMY_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_DUMMY_CONFIG_LOG_LEVEL
+#define APP_USBD_DUMMY_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_DUMMY_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 APP_USBD_DUMMY_CONFIG_INFO_COLOR
+#define APP_USBD_DUMMY_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_DUMMY_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 APP_USBD_DUMMY_CONFIG_DEBUG_COLOR
+#define APP_USBD_DUMMY_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_MSC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_MSC_CONFIG_LOG_ENABLED
+#define APP_USBD_MSC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_MSC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_MSC_CONFIG_LOG_LEVEL
+#define APP_USBD_MSC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_MSC_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 APP_USBD_MSC_CONFIG_INFO_COLOR
+#define APP_USBD_MSC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_MSC_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 APP_USBD_MSC_CONFIG_DEBUG_COLOR
+#define APP_USBD_MSC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_NRF_DFU_TRIGGER_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 APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_NRF_DFU_TRIGGER_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 APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_ATFIFO_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_ATFIFO_CONFIG_LOG_ENABLED
+#define NRF_ATFIFO_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_ATFIFO_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_ATFIFO_CONFIG_LOG_LEVEL
+#define NRF_ATFIFO_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_ATFIFO_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 NRF_ATFIFO_CONFIG_INFO_COLOR
+#define NRF_ATFIFO_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_ATFIFO_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 NRF_ATFIFO_CONFIG_DEBUG_COLOR
+#define NRF_ATFIFO_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BALLOC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BALLOC_CONFIG_LOG_ENABLED
+#define NRF_BALLOC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BALLOC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BALLOC_CONFIG_LOG_LEVEL
+#define NRF_BALLOC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL
+#define NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BALLOC_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 NRF_BALLOC_CONFIG_INFO_COLOR
+#define NRF_BALLOC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BALLOC_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 NRF_BALLOC_CONFIG_DEBUG_COLOR
+#define NRF_BALLOC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_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 NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_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 NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_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 NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_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 NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_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 NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_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 NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#define NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL
+#define NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_BLE_UART_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 NRF_CLI_BLE_UART_CONFIG_INFO_COLOR
+#define NRF_CLI_BLE_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_BLE_UART_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 NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR
+#define NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_LIBUARTE_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 NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_LIBUARTE_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 NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR
+#define NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_UART_CONFIG_LOG_ENABLED
+#define NRF_CLI_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_UART_CONFIG_LOG_LEVEL
+#define NRF_CLI_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_UART_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 NRF_CLI_UART_CONFIG_INFO_COLOR
+#define NRF_CLI_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_UART_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 NRF_CLI_UART_CONFIG_DEBUG_COLOR
+#define NRF_CLI_UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LIBUARTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_LIBUARTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LIBUARTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_LIBUARTE_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 NRF_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LIBUARTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_LIBUARTE_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 NRF_LIBUARTE_CONFIG_DEBUG_COLOR
+#define NRF_LIBUARTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_MEMOBJ_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_MEMOBJ_CONFIG_LOG_ENABLED
+#define NRF_MEMOBJ_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_MEMOBJ_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_MEMOBJ_CONFIG_LOG_LEVEL
+#define NRF_MEMOBJ_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_MEMOBJ_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 NRF_MEMOBJ_CONFIG_INFO_COLOR
+#define NRF_MEMOBJ_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_MEMOBJ_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 NRF_MEMOBJ_CONFIG_DEBUG_COLOR
+#define NRF_MEMOBJ_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_PWR_MGMT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_LOG_ENABLED
+#define NRF_PWR_MGMT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_PWR_MGMT_CONFIG_LOG_LEVEL
+#define NRF_PWR_MGMT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_PWR_MGMT_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 NRF_PWR_MGMT_CONFIG_INFO_COLOR
+#define NRF_PWR_MGMT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_PWR_MGMT_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 NRF_PWR_MGMT_CONFIG_DEBUG_COLOR
+#define NRF_PWR_MGMT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_QUEUE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_QUEUE_CONFIG_LOG_ENABLED
+#define NRF_QUEUE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_QUEUE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_QUEUE_CONFIG_LOG_LEVEL
+#define NRF_QUEUE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_QUEUE_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 NRF_QUEUE_CONFIG_INFO_COLOR
+#define NRF_QUEUE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_QUEUE_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 NRF_QUEUE_CONFIG_DEBUG_COLOR
+#define NRF_QUEUE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_ANT_LOG_ENABLED - Enable logging in SoftDevice handler (ANT) module.
+//==========================================================
+#ifndef NRF_SDH_ANT_LOG_ENABLED
+#define NRF_SDH_ANT_LOG_ENABLED 0
+#endif
+// <o> NRF_SDH_ANT_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_ANT_LOG_LEVEL
+#define NRF_SDH_ANT_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_ANT_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 NRF_SDH_ANT_INFO_COLOR
+#define NRF_SDH_ANT_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_ANT_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 NRF_SDH_ANT_DEBUG_COLOR
+#define NRF_SDH_ANT_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_BLE_LOG_ENABLED - Enable logging in SoftDevice handler (BLE) module.
+//==========================================================
+#ifndef NRF_SDH_BLE_LOG_ENABLED
+#define NRF_SDH_BLE_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_BLE_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_BLE_LOG_LEVEL
+#define NRF_SDH_BLE_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_BLE_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 NRF_SDH_BLE_INFO_COLOR
+#define NRF_SDH_BLE_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_BLE_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 NRF_SDH_BLE_DEBUG_COLOR
+#define NRF_SDH_BLE_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_LOG_ENABLED - Enable logging in SoftDevice handler module.
+//==========================================================
+#ifndef NRF_SDH_LOG_ENABLED
+#define NRF_SDH_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_LOG_LEVEL
+#define NRF_SDH_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_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 NRF_SDH_INFO_COLOR
+#define NRF_SDH_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_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 NRF_SDH_DEBUG_COLOR
+#define NRF_SDH_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_SOC_LOG_ENABLED - Enable logging in SoftDevice handler (SoC) module.
+//==========================================================
+#ifndef NRF_SDH_SOC_LOG_ENABLED
+#define NRF_SDH_SOC_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_SOC_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_SOC_LOG_LEVEL
+#define NRF_SDH_SOC_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_SOC_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 NRF_SDH_SOC_INFO_COLOR
+#define NRF_SDH_SOC_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_SOC_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 NRF_SDH_SOC_DEBUG_COLOR
+#define NRF_SDH_SOC_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SORTLIST_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_SORTLIST_CONFIG_LOG_ENABLED
+#define NRF_SORTLIST_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_SORTLIST_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SORTLIST_CONFIG_LOG_LEVEL
+#define NRF_SORTLIST_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SORTLIST_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 NRF_SORTLIST_CONFIG_INFO_COLOR
+#define NRF_SORTLIST_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_SORTLIST_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 NRF_SORTLIST_CONFIG_DEBUG_COLOR
+#define NRF_SORTLIST_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_TWI_SENSOR_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_TWI_SENSOR_CONFIG_LOG_ENABLED
+#define NRF_TWI_SENSOR_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_TWI_SENSOR_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_TWI_SENSOR_CONFIG_LOG_LEVEL
+#define NRF_TWI_SENSOR_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_TWI_SENSOR_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 NRF_TWI_SENSOR_CONFIG_INFO_COLOR
+#define NRF_TWI_SENSOR_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_TWI_SENSOR_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 NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR
+#define NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PM_LOG_ENABLED - Enable logging in Peer Manager and its submodules.
+//==========================================================
+#ifndef PM_LOG_ENABLED
+#define PM_LOG_ENABLED 1
+#endif
+// <o> PM_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PM_LOG_LEVEL
+#define PM_LOG_LEVEL 3
+#endif
+
+// <o> PM_LOG_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 PM_LOG_INFO_COLOR
+#define PM_LOG_INFO_COLOR 0
+#endif
+
+// <o> PM_LOG_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 PM_LOG_DEBUG_COLOR
+#define PM_LOG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Serialization 
+
+//==========================================================
+// <e> SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
+#define SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL
+#define SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> SER_HAL_TRANSPORT_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 SER_HAL_TRANSPORT_CONFIG_INFO_COLOR
+#define SER_HAL_TRANSPORT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> SER_HAL_TRANSPORT_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 SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR
+#define SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED  - nrf_log_str_formatter - Log string formatter
+ 
+
+#ifndef NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED
+#define NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED 1
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_NFC 
+
+//==========================================================
+// <q> NFC_AC_REC_ENABLED  - nfc_ac_rec - NFC NDEF Alternative Carrier record encoder
+ 
+
+#ifndef NFC_AC_REC_ENABLED
+#define NFC_AC_REC_ENABLED 0
+#endif
+
+// <q> NFC_AC_REC_PARSER_ENABLED  - nfc_ac_rec_parser - Alternative Carrier record parser
+ 
+
+#ifndef NFC_AC_REC_PARSER_ENABLED
+#define NFC_AC_REC_PARSER_ENABLED 0
+#endif
+
+// <e> NFC_BLE_OOB_ADVDATA_ENABLED - nfc_ble_oob_advdata - AD data for OOB pairing encoder
+//==========================================================
+#ifndef NFC_BLE_OOB_ADVDATA_ENABLED
+#define NFC_BLE_OOB_ADVDATA_ENABLED 0
+#endif
+// <o> ADVANCED_ADVDATA_SUPPORT  - Non-mandatory AD types for BLE OOB pairing are encoded inside the NDEF message (e.g. service UUIDs)
+ 
+// <1=> Enabled 
+// <0=> Disabled 
+
+#ifndef ADVANCED_ADVDATA_SUPPORT
+#define ADVANCED_ADVDATA_SUPPORT 0
+#endif
+
+// </e>
+
+// <q> NFC_BLE_OOB_ADVDATA_PARSER_ENABLED  - nfc_ble_oob_advdata_parser - BLE OOB pairing AD data parser
+ 
+
+#ifndef NFC_BLE_OOB_ADVDATA_PARSER_ENABLED
+#define NFC_BLE_OOB_ADVDATA_PARSER_ENABLED 0
+#endif
+
+// <e> NFC_BLE_PAIR_LIB_ENABLED - nfc_ble_pair_lib - Library parameters
+//==========================================================
+#ifndef NFC_BLE_PAIR_LIB_ENABLED
+#define NFC_BLE_PAIR_LIB_ENABLED 0
+#endif
+// <e> NFC_BLE_PAIR_LIB_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_BLE_PAIR_LIB_LOG_ENABLED
+#define NFC_BLE_PAIR_LIB_LOG_ENABLED 0
+#endif
+// <o> NFC_BLE_PAIR_LIB_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_BLE_PAIR_LIB_LOG_LEVEL
+#define NFC_BLE_PAIR_LIB_LOG_LEVEL 3
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_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 NFC_BLE_PAIR_LIB_INFO_COLOR
+#define NFC_BLE_PAIR_LIB_INFO_COLOR 0
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_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 NFC_BLE_PAIR_LIB_DEBUG_COLOR
+#define NFC_BLE_PAIR_LIB_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <h> NFC_BLE_PAIR_LIB_SECURITY_PARAMETERS - Common Peer Manager security parameters.
+
+//==========================================================
+// <e> BLE_NFC_SEC_PARAM_BOND - Enables device bonding.
+
+// <i> If bonding is enabled at least one of the BLE_NFC_SEC_PARAM_KDIST options must be enabled.
+//==========================================================
+#ifndef BLE_NFC_SEC_PARAM_BOND
+#define BLE_NFC_SEC_PARAM_BOND 1
+#endif
+// <q> BLE_NFC_SEC_PARAM_KDIST_OWN_ENC  - Enables Long Term Key and Master Identification distribution by device.
+ 
+
+#ifndef BLE_NFC_SEC_PARAM_KDIST_OWN_ENC
+#define BLE_NFC_SEC_PARAM_KDIST_OWN_ENC 1
+#endif
+
+// <q> BLE_NFC_SEC_PARAM_KDIST_OWN_ID  - Enables Identity Resolving Key and Identity Address Information distribution by device.
+ 
+
+#ifndef BLE_NFC_SEC_PARAM_KDIST_OWN_ID
+#define BLE_NFC_SEC_PARAM_KDIST_OWN_ID 1
+#endif
+
+// <q> BLE_NFC_SEC_PARAM_KDIST_PEER_ENC  - Enables Long Term Key and Master Identification distribution by peer.
+ 
+
+#ifndef BLE_NFC_SEC_PARAM_KDIST_PEER_ENC
+#define BLE_NFC_SEC_PARAM_KDIST_PEER_ENC 1
+#endif
+
+// <q> BLE_NFC_SEC_PARAM_KDIST_PEER_ID  - Enables Identity Resolving Key and Identity Address Information distribution by peer.
+ 
+
+#ifndef BLE_NFC_SEC_PARAM_KDIST_PEER_ID
+#define BLE_NFC_SEC_PARAM_KDIST_PEER_ID 1
+#endif
+
+// </e>
+
+// <o> BLE_NFC_SEC_PARAM_MIN_KEY_SIZE  - Minimal size of a security key.
+ 
+// <7=> 7 
+// <8=> 8 
+// <9=> 9 
+// <10=> 10 
+// <11=> 11 
+// <12=> 12 
+// <13=> 13 
+// <14=> 14 
+// <15=> 15 
+// <16=> 16 
+
+#ifndef BLE_NFC_SEC_PARAM_MIN_KEY_SIZE
+#define BLE_NFC_SEC_PARAM_MIN_KEY_SIZE 7
+#endif
+
+// <o> BLE_NFC_SEC_PARAM_MAX_KEY_SIZE  - Maximal size of a security key.
+ 
+// <7=> 7 
+// <8=> 8 
+// <9=> 9 
+// <10=> 10 
+// <11=> 11 
+// <12=> 12 
+// <13=> 13 
+// <14=> 14 
+// <15=> 15 
+// <16=> 16 
+
+#ifndef BLE_NFC_SEC_PARAM_MAX_KEY_SIZE
+#define BLE_NFC_SEC_PARAM_MAX_KEY_SIZE 16
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> NFC_BLE_PAIR_MSG_ENABLED  - nfc_ble_pair_msg - NDEF message for OOB pairing encoder
+ 
+
+#ifndef NFC_BLE_PAIR_MSG_ENABLED
+#define NFC_BLE_PAIR_MSG_ENABLED 0
+#endif
+
+// <q> NFC_CH_COMMON_ENABLED  - nfc_ble_pair_common - OOB pairing common data
+ 
+
+#ifndef NFC_CH_COMMON_ENABLED
+#define NFC_CH_COMMON_ENABLED 0
+#endif
+
+// <q> NFC_EP_OOB_REC_ENABLED  - nfc_ep_oob_rec - EP record for BLE pairing encoder
+ 
+
+#ifndef NFC_EP_OOB_REC_ENABLED
+#define NFC_EP_OOB_REC_ENABLED 0
+#endif
+
+// <q> NFC_HS_REC_ENABLED  - nfc_hs_rec - Handover Select NDEF record encoder
+ 
+
+#ifndef NFC_HS_REC_ENABLED
+#define NFC_HS_REC_ENABLED 0
+#endif
+
+// <q> NFC_LE_OOB_REC_ENABLED  - nfc_le_oob_rec - LE record for BLE pairing encoder
+ 
+
+#ifndef NFC_LE_OOB_REC_ENABLED
+#define NFC_LE_OOB_REC_ENABLED 0
+#endif
+
+// <q> NFC_LE_OOB_REC_PARSER_ENABLED  - nfc_le_oob_rec_parser - LE record parser
+ 
+
+#ifndef NFC_LE_OOB_REC_PARSER_ENABLED
+#define NFC_LE_OOB_REC_PARSER_ENABLED 0
+#endif
+
+// <q> NFC_NDEF_LAUNCHAPP_MSG_ENABLED  - nfc_launchapp_msg - Encoding data for NDEF Application Launching message for NFC Tag
+ 
+
+#ifndef NFC_NDEF_LAUNCHAPP_MSG_ENABLED
+#define NFC_NDEF_LAUNCHAPP_MSG_ENABLED 0
+#endif
+
+// <q> NFC_NDEF_LAUNCHAPP_REC_ENABLED  - nfc_launchapp_rec - Encoding data for NDEF Application Launching record for NFC Tag
+ 
+
+#ifndef NFC_NDEF_LAUNCHAPP_REC_ENABLED
+#define NFC_NDEF_LAUNCHAPP_REC_ENABLED 0
+#endif
+
+// <e> NFC_NDEF_MSG_ENABLED - nfc_ndef_msg - NFC NDEF Message generator module
+//==========================================================
+#ifndef NFC_NDEF_MSG_ENABLED
+#define NFC_NDEF_MSG_ENABLED 0
+#endif
+// <o> NFC_NDEF_MSG_TAG_TYPE  - NFC Tag Type
+ 
+// <2=> Type 2 Tag 
+// <4=> Type 4 Tag 
+
+#ifndef NFC_NDEF_MSG_TAG_TYPE
+#define NFC_NDEF_MSG_TAG_TYPE 2
+#endif
+
+// </e>
+
+// <e> NFC_NDEF_MSG_PARSER_ENABLED - nfc_ndef_msg_parser - NFC NDEF message parser module
+//==========================================================
+#ifndef NFC_NDEF_MSG_PARSER_ENABLED
+#define NFC_NDEF_MSG_PARSER_ENABLED 0
+#endif
+// <e> NFC_NDEF_MSG_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_NDEF_MSG_PARSER_LOG_ENABLED
+#define NFC_NDEF_MSG_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_NDEF_MSG_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_NDEF_MSG_PARSER_LOG_LEVEL
+#define NFC_NDEF_MSG_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_NDEF_MSG_PARSER_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 NFC_NDEF_MSG_PARSER_INFO_COLOR
+#define NFC_NDEF_MSG_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> NFC_NDEF_RECORD_ENABLED  - nfc_ndef_record - NFC NDEF Record generator module
+ 
+
+#ifndef NFC_NDEF_RECORD_ENABLED
+#define NFC_NDEF_RECORD_ENABLED 0
+#endif
+
+// <e> NFC_NDEF_RECORD_PARSER_ENABLED - nfc_ndef_record_parser - NFC NDEF Record parser module
+//==========================================================
+#ifndef NFC_NDEF_RECORD_PARSER_ENABLED
+#define NFC_NDEF_RECORD_PARSER_ENABLED 0
+#endif
+// <e> NFC_NDEF_RECORD_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_NDEF_RECORD_PARSER_LOG_ENABLED
+#define NFC_NDEF_RECORD_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_NDEF_RECORD_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_NDEF_RECORD_PARSER_LOG_LEVEL
+#define NFC_NDEF_RECORD_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_NDEF_RECORD_PARSER_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 NFC_NDEF_RECORD_PARSER_INFO_COLOR
+#define NFC_NDEF_RECORD_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> NFC_NDEF_TEXT_RECORD_ENABLED  - nfc_text_rec - Encoding data for a text record for NFC Tag
+ 
+
+#ifndef NFC_NDEF_TEXT_RECORD_ENABLED
+#define NFC_NDEF_TEXT_RECORD_ENABLED 0
+#endif
+
+// <q> NFC_NDEF_URI_MSG_ENABLED  - nfc_uri_msg - Encoding data for NDEF message with URI record for NFC Tag
+ 
+
+#ifndef NFC_NDEF_URI_MSG_ENABLED
+#define NFC_NDEF_URI_MSG_ENABLED 0
+#endif
+
+// <q> NFC_NDEF_URI_REC_ENABLED  - nfc_uri_rec - Encoding data for a URI record for NFC Tag
+ 
+
+#ifndef NFC_NDEF_URI_REC_ENABLED
+#define NFC_NDEF_URI_REC_ENABLED 0
+#endif
+
+// <e> NFC_PLATFORM_ENABLED - nfc_platform - NFC platform module for Clock control.
+//==========================================================
+#ifndef NFC_PLATFORM_ENABLED
+#define NFC_PLATFORM_ENABLED 0
+#endif
+// <e> NFC_PLATFORM_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_PLATFORM_LOG_ENABLED
+#define NFC_PLATFORM_LOG_ENABLED 0
+#endif
+// <o> NFC_PLATFORM_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_PLATFORM_LOG_LEVEL
+#define NFC_PLATFORM_LOG_LEVEL 3
+#endif
+
+// <o> NFC_PLATFORM_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 NFC_PLATFORM_INFO_COLOR
+#define NFC_PLATFORM_INFO_COLOR 0
+#endif
+
+// <o> NFC_PLATFORM_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 NFC_PLATFORM_DEBUG_COLOR
+#define NFC_PLATFORM_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NFC_T2T_PARSER_ENABLED - nfc_type_2_tag_parser - Parser for decoding Type 2 Tag data
+//==========================================================
+#ifndef NFC_T2T_PARSER_ENABLED
+#define NFC_T2T_PARSER_ENABLED 0
+#endif
+// <e> NFC_T2T_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T2T_PARSER_LOG_ENABLED
+#define NFC_T2T_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_T2T_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T2T_PARSER_LOG_LEVEL
+#define NFC_T2T_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T2T_PARSER_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 NFC_T2T_PARSER_INFO_COLOR
+#define NFC_T2T_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NFC_T4T_APDU_ENABLED - nfc_t4t_apdu - APDU encoder/decoder for Type 4 Tag
+//==========================================================
+#ifndef NFC_T4T_APDU_ENABLED
+#define NFC_T4T_APDU_ENABLED 0
+#endif
+// <e> NFC_T4T_APDU_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T4T_APDU_LOG_ENABLED
+#define NFC_T4T_APDU_LOG_ENABLED 0
+#endif
+// <o> NFC_T4T_APDU_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T4T_APDU_LOG_LEVEL
+#define NFC_T4T_APDU_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T4T_APDU_LOG_COLOR  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NFC_T4T_APDU_LOG_COLOR
+#define NFC_T4T_APDU_LOG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NFC_T4T_CC_FILE_PARSER_ENABLED - nfc_t4t_cc_file - Capability Container file for Type 4 Tag
+//==========================================================
+#ifndef NFC_T4T_CC_FILE_PARSER_ENABLED
+#define NFC_T4T_CC_FILE_PARSER_ENABLED 0
+#endif
+// <e> NFC_T4T_CC_FILE_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T4T_CC_FILE_PARSER_LOG_ENABLED
+#define NFC_T4T_CC_FILE_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_T4T_CC_FILE_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T4T_CC_FILE_PARSER_LOG_LEVEL
+#define NFC_T4T_CC_FILE_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T4T_CC_FILE_PARSER_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 NFC_T4T_CC_FILE_PARSER_INFO_COLOR
+#define NFC_T4T_CC_FILE_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED - nfc_t4t_hl_detection_procedures - NDEF Detection Procedure for Type 4 Tag
+//==========================================================
+#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED
+#define NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED 0
+#endif
+// <e> NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED
+#define NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED 0
+#endif
+// <o> NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL
+#define NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T4T_HL_DETECTION_PROCEDURES_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 NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR
+#define NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR 0
+#endif
+
+// </e>
+
+// <o> APDU_BUFF_SIZE - Size (in bytes) of the buffer for APDU storage 
+#ifndef APDU_BUFF_SIZE
+#define APDU_BUFF_SIZE 250
+#endif
+
+// <o> CC_STORAGE_BUFF_SIZE - Size (in bytes) of the buffer for CC file storage 
+#ifndef CC_STORAGE_BUFF_SIZE
+#define CC_STORAGE_BUFF_SIZE 64
+#endif
+
+// </e>
+
+// <e> NFC_T4T_TLV_BLOCK_PARSER_ENABLED - nfc_t4t_tlv_block - TLV block for Type 4 Tag
+//==========================================================
+#ifndef NFC_T4T_TLV_BLOCK_PARSER_ENABLED
+#define NFC_T4T_TLV_BLOCK_PARSER_ENABLED 0
+#endif
+// <e> NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED
+#define NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL
+#define NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T4T_TLV_BLOCK_PARSER_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 NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR
+#define NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_SoftDevice 
+
+//==========================================================
+// <e> NRF_SDH_BLE_ENABLED - nrf_sdh_ble - SoftDevice BLE event handler
+//==========================================================
+#ifndef NRF_SDH_BLE_ENABLED
+#define NRF_SDH_BLE_ENABLED 0
+#endif
+// <h> BLE Stack configuration - Stack configuration parameters
+
+// <i> The SoftDevice handler will configure the stack with these parameters when calling @ref nrf_sdh_ble_default_cfg_set.
+// <i> Other libraries might depend on these values; keep them up-to-date even if you are not explicitely calling @ref nrf_sdh_ble_default_cfg_set.
+//==========================================================
+// <o> NRF_SDH_BLE_GAP_DATA_LENGTH   <27-251> 
+
+
+// <i> Requested BLE GAP data length to be negotiated.
+
+#ifndef NRF_SDH_BLE_GAP_DATA_LENGTH
+#define NRF_SDH_BLE_GAP_DATA_LENGTH 27
+#endif
+
+// <o> NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - Maximum number of peripheral links. 
+#ifndef NRF_SDH_BLE_PERIPHERAL_LINK_COUNT
+#define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 0
+#endif
+
+// <o> NRF_SDH_BLE_CENTRAL_LINK_COUNT - Maximum number of central links. 
+#ifndef NRF_SDH_BLE_CENTRAL_LINK_COUNT
+#define NRF_SDH_BLE_CENTRAL_LINK_COUNT 0
+#endif
+
+// <o> NRF_SDH_BLE_TOTAL_LINK_COUNT - Total link count. 
+// <i> Maximum number of total concurrent connections using the default configuration.
+
+#ifndef NRF_SDH_BLE_TOTAL_LINK_COUNT
+#define NRF_SDH_BLE_TOTAL_LINK_COUNT 1
+#endif
+
+// <o> NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length. 
+// <i> The time set aside for this connection on every connection interval in 1.25 ms units.
+
+#ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH
+#define NRF_SDH_BLE_GAP_EVENT_LENGTH 6
+#endif
+
+// <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
+#ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
+#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 23
+#endif
+
+// <o> NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE - Attribute Table size in bytes. The size must be a multiple of 4. 
+#ifndef NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE
+#define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1408
+#endif
+
+// <o> NRF_SDH_BLE_VS_UUID_COUNT - The number of vendor-specific UUIDs. 
+#ifndef NRF_SDH_BLE_VS_UUID_COUNT
+#define NRF_SDH_BLE_VS_UUID_COUNT 0
+#endif
+
+// <q> NRF_SDH_BLE_SERVICE_CHANGED  - Include the Service Changed characteristic in the Attribute Table.
+ 
+
+#ifndef NRF_SDH_BLE_SERVICE_CHANGED
+#define NRF_SDH_BLE_SERVICE_CHANGED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> BLE Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_BLE_OBSERVER_PRIO_LEVELS - Total number of priority levels for BLE observers. 
+// <i> This setting configures the number of priority levels available for BLE event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_BLE_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_BLE_OBSERVER_PRIO_LEVELS 4
+#endif
+
+// <h> BLE Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> BLE_ADV_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Advertising module.
+
+#ifndef BLE_ADV_BLE_OBSERVER_PRIO
+#define BLE_ADV_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_ANCS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Apple Notification Service Client.
+
+#ifndef BLE_ANCS_C_BLE_OBSERVER_PRIO
+#define BLE_ANCS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_ANS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Alert Notification Service Client.
+
+#ifndef BLE_ANS_C_BLE_OBSERVER_PRIO
+#define BLE_ANS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BAS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Battery Service.
+
+#ifndef BLE_BAS_BLE_OBSERVER_PRIO
+#define BLE_BAS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BAS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Battery Service Client.
+
+#ifndef BLE_BAS_C_BLE_OBSERVER_PRIO
+#define BLE_BAS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BPS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Blood Pressure Service.
+
+#ifndef BLE_BPS_BLE_OBSERVER_PRIO
+#define BLE_BPS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_CONN_PARAMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Connection parameters module.
+
+#ifndef BLE_CONN_PARAMS_BLE_OBSERVER_PRIO
+#define BLE_CONN_PARAMS_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_CONN_STATE_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Connection State module.
+
+#ifndef BLE_CONN_STATE_BLE_OBSERVER_PRIO
+#define BLE_CONN_STATE_BLE_OBSERVER_PRIO 0
+#endif
+
+// <o> BLE_CSCS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Cycling Speed and Cadence Service.
+
+#ifndef BLE_CSCS_BLE_OBSERVER_PRIO
+#define BLE_CSCS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_CTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Current Time Service Client.
+
+#ifndef BLE_CTS_C_BLE_OBSERVER_PRIO
+#define BLE_CTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_DB_DISC_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Database Discovery module.
+
+#ifndef BLE_DB_DISC_BLE_OBSERVER_PRIO
+#define BLE_DB_DISC_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_DFU_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the DFU Service.
+
+#ifndef BLE_DFU_BLE_OBSERVER_PRIO
+#define BLE_DFU_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_DIS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Device Information Client.
+
+#ifndef BLE_DIS_C_BLE_OBSERVER_PRIO
+#define BLE_DIS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_GLS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Glucose Service.
+
+#ifndef BLE_GLS_BLE_OBSERVER_PRIO
+#define BLE_GLS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HIDS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Human Interface Device Service.
+
+#ifndef BLE_HIDS_BLE_OBSERVER_PRIO
+#define BLE_HIDS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HRS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Heart Rate Service.
+
+#ifndef BLE_HRS_BLE_OBSERVER_PRIO
+#define BLE_HRS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HRS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Heart Rate Service Client.
+
+#ifndef BLE_HRS_C_BLE_OBSERVER_PRIO
+#define BLE_HRS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HTS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Health Thermometer Service.
+
+#ifndef BLE_HTS_BLE_OBSERVER_PRIO
+#define BLE_HTS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_IAS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Immediate Alert Service.
+
+#ifndef BLE_IAS_BLE_OBSERVER_PRIO
+#define BLE_IAS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_IAS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Immediate Alert Service Client.
+
+#ifndef BLE_IAS_C_BLE_OBSERVER_PRIO
+#define BLE_IAS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LBS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the LED Button Service.
+
+#ifndef BLE_LBS_BLE_OBSERVER_PRIO
+#define BLE_LBS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LBS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the LED Button Service Client.
+
+#ifndef BLE_LBS_C_BLE_OBSERVER_PRIO
+#define BLE_LBS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LLS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Link Loss Service.
+
+#ifndef BLE_LLS_BLE_OBSERVER_PRIO
+#define BLE_LLS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LNS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Location Navigation Service.
+
+#ifndef BLE_LNS_BLE_OBSERVER_PRIO
+#define BLE_LNS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_NUS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the UART Service.
+
+#ifndef BLE_NUS_BLE_OBSERVER_PRIO
+#define BLE_NUS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_NUS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the UART Central Service.
+
+#ifndef BLE_NUS_C_BLE_OBSERVER_PRIO
+#define BLE_NUS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_OTS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Object transfer service.
+
+#ifndef BLE_OTS_BLE_OBSERVER_PRIO
+#define BLE_OTS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_OTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Object transfer service client.
+
+#ifndef BLE_OTS_C_BLE_OBSERVER_PRIO
+#define BLE_OTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_RSCS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Running Speed and Cadence Service.
+
+#ifndef BLE_RSCS_BLE_OBSERVER_PRIO
+#define BLE_RSCS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_RSCS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Running Speed and Cadence Client.
+
+#ifndef BLE_RSCS_C_BLE_OBSERVER_PRIO
+#define BLE_RSCS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_TPS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the TX Power Service.
+
+#ifndef BLE_TPS_BLE_OBSERVER_PRIO
+#define BLE_TPS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BSP_BTN_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Button Control module.
+
+#ifndef BSP_BTN_BLE_OBSERVER_PRIO
+#define BSP_BTN_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_BMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Bond Management Service.
+
+#ifndef NRF_BLE_BMS_BLE_OBSERVER_PRIO
+#define NRF_BLE_BMS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_CGMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Contiuon Glucose Monitoring Service.
+
+#ifndef NRF_BLE_CGMS_BLE_OBSERVER_PRIO
+#define NRF_BLE_CGMS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_ES_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Eddystone module.
+
+#ifndef NRF_BLE_ES_BLE_OBSERVER_PRIO
+#define NRF_BLE_ES_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT Service Client.
+
+#ifndef NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO
+#define NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_GATT_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT module.
+
+#ifndef NRF_BLE_GATT_BLE_OBSERVER_PRIO
+#define NRF_BLE_GATT_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_GQ_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT Queue module.
+
+#ifndef NRF_BLE_GQ_BLE_OBSERVER_PRIO
+#define NRF_BLE_GQ_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_QWR_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Queued writes module.
+
+#ifndef NRF_BLE_QWR_BLE_OBSERVER_PRIO
+#define NRF_BLE_QWR_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_SCAN_OBSERVER_PRIO  
+// <i> Priority for dispatching the BLE events to the Scanning Module.
+
+#ifndef NRF_BLE_SCAN_OBSERVER_PRIO
+#define NRF_BLE_SCAN_OBSERVER_PRIO 1
+#endif
+
+// <o> PM_BLE_OBSERVER_PRIO - Priority with which BLE events are dispatched to the Peer Manager module. 
+#ifndef PM_BLE_OBSERVER_PRIO
+#define PM_BLE_OBSERVER_PRIO 1
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// <e> NRF_SDH_ENABLED - nrf_sdh - SoftDevice handler
+//==========================================================
+#ifndef NRF_SDH_ENABLED
+#define NRF_SDH_ENABLED 0
+#endif
+// <h> Dispatch model 
+
+// <i> This setting configures how Stack events are dispatched to the application.
+//==========================================================
+// <o> NRF_SDH_DISPATCH_MODEL
+ 
+
+// <i> NRF_SDH_DISPATCH_MODEL_INTERRUPT: SoftDevice events are passed to the application from the interrupt context.
+// <i> NRF_SDH_DISPATCH_MODEL_APPSH: SoftDevice events are scheduled using @ref app_scheduler.
+// <i> NRF_SDH_DISPATCH_MODEL_POLLING: SoftDevice events are to be fetched manually.
+// <0=> NRF_SDH_DISPATCH_MODEL_INTERRUPT 
+// <1=> NRF_SDH_DISPATCH_MODEL_APPSH 
+// <2=> NRF_SDH_DISPATCH_MODEL_POLLING 
+
+#ifndef NRF_SDH_DISPATCH_MODEL
+#define NRF_SDH_DISPATCH_MODEL 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Clock - SoftDevice clock configuration
+
+//==========================================================
+// <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
+ 
+// <0=> NRF_CLOCK_LF_SRC_RC 
+// <1=> NRF_CLOCK_LF_SRC_XTAL 
+// <2=> NRF_CLOCK_LF_SRC_SYNTH 
+
+#ifndef NRF_SDH_CLOCK_LF_SRC
+#define NRF_SDH_CLOCK_LF_SRC 1
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
+#ifndef NRF_SDH_CLOCK_LF_RC_CTIV
+#define NRF_SDH_CLOCK_LF_RC_CTIV 0
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
+// <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
+// <i>  if the temperature has not changed.
+
+#ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
+#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
+ 
+// <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
+// <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
+// <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
+// <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
+// <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
+// <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
+// <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
+// <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
+// <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
+// <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
+// <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
+// <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
+
+#ifndef NRF_SDH_CLOCK_LF_ACCURACY
+#define NRF_SDH_CLOCK_LF_ACCURACY 7
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> SDH Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_REQ_OBSERVER_PRIO_LEVELS - Total number of priority levels for request observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice request event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_REQ_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_REQ_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <o> NRF_SDH_STATE_OBSERVER_PRIO_LEVELS - Total number of priority levels for state observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice state event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_STATE_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_STATE_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <o> NRF_SDH_STACK_OBSERVER_PRIO_LEVELS - Total number of priority levels for stack event observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice stack event handlers (ANT, BLE, SoC).
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_STACK_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_STACK_OBSERVER_PRIO_LEVELS 2
+#endif
+
+
+// <h> State Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> CLOCK_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to the Clock driver.
+
+#ifndef CLOCK_CONFIG_STATE_OBSERVER_PRIO
+#define CLOCK_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// <o> POWER_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to the Power driver.
+
+#ifndef POWER_CONFIG_STATE_OBSERVER_PRIO
+#define POWER_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// <o> RNG_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to this module.
+
+#ifndef RNG_CONFIG_STATE_OBSERVER_PRIO
+#define RNG_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Stack Event Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> NRF_SDH_ANT_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which ANT events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have ANT events dispatched before or after other stack events, such as BLE or SoC.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_ANT_STACK_OBSERVER_PRIO
+#define NRF_SDH_ANT_STACK_OBSERVER_PRIO 0
+#endif
+
+// <o> NRF_SDH_BLE_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which BLE events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have BLE events dispatched before or after other stack events, such as ANT or SoC.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_BLE_STACK_OBSERVER_PRIO
+#define NRF_SDH_BLE_STACK_OBSERVER_PRIO 0
+#endif
+
+// <o> NRF_SDH_SOC_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which SoC events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have SoC events dispatched before or after other stack events, such as ANT or BLE.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_SOC_STACK_OBSERVER_PRIO
+#define NRF_SDH_SOC_STACK_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// <e> NRF_SDH_SOC_ENABLED - nrf_sdh_soc - SoftDevice SoC event handler
+//==========================================================
+#ifndef NRF_SDH_SOC_ENABLED
+#define NRF_SDH_SOC_ENABLED 0
+#endif
+// <h> SoC Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_SOC_OBSERVER_PRIO_LEVELS - Total number of priority levels for SoC observers. 
+// <i> This setting configures the number of priority levels available for the SoC event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_SOC_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_SOC_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <h> SoC Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> BLE_DFU_SOC_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the DFU Service.
+
+#ifndef BLE_DFU_SOC_OBSERVER_PRIO
+#define BLE_DFU_SOC_OBSERVER_PRIO 1
+#endif
+
+// <o> CLOCK_CONFIG_SOC_OBSERVER_PRIO  
+// <i> Priority with which SoC events are dispatched to the Clock driver.
+
+#ifndef CLOCK_CONFIG_SOC_OBSERVER_PRIO
+#define CLOCK_CONFIG_SOC_OBSERVER_PRIO 0
+#endif
+
+// <o> POWER_CONFIG_SOC_OBSERVER_PRIO  
+// <i> Priority with which SoC events are dispatched to the Power driver.
+
+#ifndef POWER_CONFIG_SOC_OBSERVER_PRIO
+#define POWER_CONFIG_SOC_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <<< end of configuration section >>>
+#endif //SDK_CONFIG_H
+
diff --git a/third_party/NordicSemiconductor/config/nrf52840/config/sdk_config.h b/third_party/NordicSemiconductor/config/nrf52840/config/sdk_config.h
new file mode 100644
index 0000000..07e1387
--- /dev/null
+++ b/third_party/NordicSemiconductor/config/nrf52840/config/sdk_config.h
@@ -0,0 +1,11698 @@
+/**
+ * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ *    Semiconductor ASA integrated circuit in a product or a software update for
+ *    such product, must reproduce the above copyright notice, this list of
+ *    conditions and the following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ *    Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ *    engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+
+#ifndef SDK_CONFIG_H
+#define SDK_CONFIG_H
+// <<< Use Configuration Wizard in Context Menu >>>\n
+#ifdef USE_APP_CONFIG
+#include "app_config.h"
+#endif
+// <h> nRF_BLE 
+
+//==========================================================
+// <q> BLE_ADVERTISING_ENABLED  - ble_advertising - Advertising module
+ 
+
+#ifndef BLE_ADVERTISING_ENABLED
+#define BLE_ADVERTISING_ENABLED 0
+#endif
+
+// <q> BLE_DTM_ENABLED  - ble_dtm - Module for testing RF/PHY using DTM commands
+ 
+
+#ifndef BLE_DTM_ENABLED
+#define BLE_DTM_ENABLED 0
+#endif
+
+// <q> BLE_RACP_ENABLED  - ble_racp - Record Access Control Point library
+ 
+
+#ifndef BLE_RACP_ENABLED
+#define BLE_RACP_ENABLED 0
+#endif
+
+// <e> NRF_BLE_QWR_ENABLED - nrf_ble_qwr - Queued writes support module (prepare/execute write)
+//==========================================================
+#ifndef NRF_BLE_QWR_ENABLED
+#define NRF_BLE_QWR_ENABLED 0
+#endif
+// <o> NRF_BLE_QWR_MAX_ATTR - Maximum number of attribute handles that can be registered. This number must be adjusted according to the number of attributes for which Queued Writes will be enabled. If it is zero, the module will reject all Queued Write requests. 
+#ifndef NRF_BLE_QWR_MAX_ATTR
+#define NRF_BLE_QWR_MAX_ATTR 0
+#endif
+
+// </e>
+
+// <e> PEER_MANAGER_ENABLED - peer_manager - Peer Manager
+//==========================================================
+#ifndef PEER_MANAGER_ENABLED
+#define PEER_MANAGER_ENABLED 0
+#endif
+// <o> PM_MAX_REGISTRANTS - Number of event handlers that can be registered. 
+#ifndef PM_MAX_REGISTRANTS
+#define PM_MAX_REGISTRANTS 3
+#endif
+
+// <o> PM_FLASH_BUFFERS - Number of internal buffers for flash operations. 
+// <i> Decrease this value to lower RAM usage.
+
+#ifndef PM_FLASH_BUFFERS
+#define PM_FLASH_BUFFERS 4
+#endif
+
+// <q> PM_CENTRAL_ENABLED  - Enable/disable central-specific Peer Manager functionality.
+ 
+
+// <i> Enable/disable central-specific Peer Manager functionality.
+
+#ifndef PM_CENTRAL_ENABLED
+#define PM_CENTRAL_ENABLED 1
+#endif
+
+// <q> PM_SERVICE_CHANGED_ENABLED  - Enable/disable the service changed management for GATT server in Peer Manager.
+ 
+
+// <i> If not using a GATT server, or using a server wihout a service changed characteristic,
+// <i> disable this to save code space.
+
+#ifndef PM_SERVICE_CHANGED_ENABLED
+#define PM_SERVICE_CHANGED_ENABLED 1
+#endif
+
+// <q> PM_PEER_RANKS_ENABLED  - Enable/disable the peer rank management in Peer Manager.
+ 
+
+// <i> Set this to false to save code space if not using the peer rank API.
+
+#ifndef PM_PEER_RANKS_ENABLED
+#define PM_PEER_RANKS_ENABLED 1
+#endif
+
+// <q> PM_LESC_ENABLED  - Enable/disable LESC support in Peer Manager.
+ 
+
+// <i> If set to true, you need to call nrf_ble_lesc_request_handler() in the main loop to respond to LESC-related BLE events. If LESC support is not required, set this to false to save code space.
+
+#ifndef PM_LESC_ENABLED
+#define PM_LESC_ENABLED 0
+#endif
+
+// <e> PM_RA_PROTECTION_ENABLED - Enable/disable protection against repeated pairing attempts in Peer Manager.
+//==========================================================
+#ifndef PM_RA_PROTECTION_ENABLED
+#define PM_RA_PROTECTION_ENABLED 0
+#endif
+// <o> PM_RA_PROTECTION_TRACKED_PEERS_NUM - Maximum number of peers whose authorization status can be tracked. 
+#ifndef PM_RA_PROTECTION_TRACKED_PEERS_NUM
+#define PM_RA_PROTECTION_TRACKED_PEERS_NUM 8
+#endif
+
+// <o> PM_RA_PROTECTION_MIN_WAIT_INTERVAL - Minimum waiting interval (in ms) before a new pairing attempt can be initiated. 
+#ifndef PM_RA_PROTECTION_MIN_WAIT_INTERVAL
+#define PM_RA_PROTECTION_MIN_WAIT_INTERVAL 4000
+#endif
+
+// <o> PM_RA_PROTECTION_MAX_WAIT_INTERVAL - Maximum waiting interval (in ms) before a new pairing attempt can be initiated. 
+#ifndef PM_RA_PROTECTION_MAX_WAIT_INTERVAL
+#define PM_RA_PROTECTION_MAX_WAIT_INTERVAL 64000
+#endif
+
+// <o> PM_RA_PROTECTION_REWARD_PERIOD - Reward period (in ms). 
+// <i> The waiting interval is gradually decreased when no new failed pairing attempts are made during reward period.
+
+#ifndef PM_RA_PROTECTION_REWARD_PERIOD
+#define PM_RA_PROTECTION_REWARD_PERIOD 10000
+#endif
+
+// </e>
+
+// <o> PM_HANDLER_SEC_DELAY_MS - Delay before starting security. 
+// <i>  This might be necessary for interoperability reasons, especially as peripheral.
+
+#ifndef PM_HANDLER_SEC_DELAY_MS
+#define PM_HANDLER_SEC_DELAY_MS 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_BLE_Services 
+
+//==========================================================
+// <q> BLE_ANCS_C_ENABLED  - ble_ancs_c - Apple Notification Service Client
+ 
+
+#ifndef BLE_ANCS_C_ENABLED
+#define BLE_ANCS_C_ENABLED 0
+#endif
+
+// <q> BLE_ANS_C_ENABLED  - ble_ans_c - Alert Notification Service Client
+ 
+
+#ifndef BLE_ANS_C_ENABLED
+#define BLE_ANS_C_ENABLED 0
+#endif
+
+// <q> BLE_BAS_C_ENABLED  - ble_bas_c - Battery Service Client
+ 
+
+#ifndef BLE_BAS_C_ENABLED
+#define BLE_BAS_C_ENABLED 0
+#endif
+
+// <e> BLE_BAS_ENABLED - ble_bas - Battery Service
+//==========================================================
+#ifndef BLE_BAS_ENABLED
+#define BLE_BAS_ENABLED 0
+#endif
+// <e> BLE_BAS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_BAS_CONFIG_LOG_ENABLED
+#define BLE_BAS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_BAS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_BAS_CONFIG_LOG_LEVEL
+#define BLE_BAS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_BAS_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 BLE_BAS_CONFIG_INFO_COLOR
+#define BLE_BAS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_BAS_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 BLE_BAS_CONFIG_DEBUG_COLOR
+#define BLE_BAS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_CSCS_ENABLED  - ble_cscs - Cycling Speed and Cadence Service
+ 
+
+#ifndef BLE_CSCS_ENABLED
+#define BLE_CSCS_ENABLED 0
+#endif
+
+// <q> BLE_CTS_C_ENABLED  - ble_cts_c - Current Time Service Client
+ 
+
+#ifndef BLE_CTS_C_ENABLED
+#define BLE_CTS_C_ENABLED 0
+#endif
+
+// <q> BLE_DIS_ENABLED  - ble_dis - Device Information Service
+ 
+
+#ifndef BLE_DIS_ENABLED
+#define BLE_DIS_ENABLED 0
+#endif
+
+// <q> BLE_GLS_ENABLED  - ble_gls - Glucose Service
+ 
+
+#ifndef BLE_GLS_ENABLED
+#define BLE_GLS_ENABLED 0
+#endif
+
+// <q> BLE_HIDS_ENABLED  - ble_hids - Human Interface Device Service
+ 
+
+#ifndef BLE_HIDS_ENABLED
+#define BLE_HIDS_ENABLED 0
+#endif
+
+// <q> BLE_HRS_C_ENABLED  - ble_hrs_c - Heart Rate Service Client
+ 
+
+#ifndef BLE_HRS_C_ENABLED
+#define BLE_HRS_C_ENABLED 0
+#endif
+
+// <q> BLE_HRS_ENABLED  - ble_hrs - Heart Rate Service
+ 
+
+#ifndef BLE_HRS_ENABLED
+#define BLE_HRS_ENABLED 0
+#endif
+
+// <q> BLE_HTS_ENABLED  - ble_hts - Health Thermometer Service
+ 
+
+#ifndef BLE_HTS_ENABLED
+#define BLE_HTS_ENABLED 0
+#endif
+
+// <q> BLE_IAS_C_ENABLED  - ble_ias_c - Immediate Alert Service Client
+ 
+
+#ifndef BLE_IAS_C_ENABLED
+#define BLE_IAS_C_ENABLED 0
+#endif
+
+// <e> BLE_IAS_ENABLED - ble_ias - Immediate Alert Service
+//==========================================================
+#ifndef BLE_IAS_ENABLED
+#define BLE_IAS_ENABLED 0
+#endif
+// <e> BLE_IAS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_IAS_CONFIG_LOG_ENABLED
+#define BLE_IAS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_IAS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_IAS_CONFIG_LOG_LEVEL
+#define BLE_IAS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_IAS_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 BLE_IAS_CONFIG_INFO_COLOR
+#define BLE_IAS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_IAS_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 BLE_IAS_CONFIG_DEBUG_COLOR
+#define BLE_IAS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_LBS_C_ENABLED  - ble_lbs_c - Nordic LED Button Service Client
+ 
+
+#ifndef BLE_LBS_C_ENABLED
+#define BLE_LBS_C_ENABLED 0
+#endif
+
+// <q> BLE_LBS_ENABLED  - ble_lbs - LED Button Service
+ 
+
+#ifndef BLE_LBS_ENABLED
+#define BLE_LBS_ENABLED 0
+#endif
+
+// <q> BLE_LLS_ENABLED  - ble_lls - Link Loss Service
+ 
+
+#ifndef BLE_LLS_ENABLED
+#define BLE_LLS_ENABLED 0
+#endif
+
+// <q> BLE_NUS_C_ENABLED  - ble_nus_c - Nordic UART Central Service
+ 
+
+#ifndef BLE_NUS_C_ENABLED
+#define BLE_NUS_C_ENABLED 0
+#endif
+
+// <e> BLE_NUS_ENABLED - ble_nus - Nordic UART Service
+//==========================================================
+#ifndef BLE_NUS_ENABLED
+#define BLE_NUS_ENABLED 0
+#endif
+// <e> BLE_NUS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef BLE_NUS_CONFIG_LOG_ENABLED
+#define BLE_NUS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> BLE_NUS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef BLE_NUS_CONFIG_LOG_LEVEL
+#define BLE_NUS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> BLE_NUS_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 BLE_NUS_CONFIG_INFO_COLOR
+#define BLE_NUS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> BLE_NUS_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 BLE_NUS_CONFIG_DEBUG_COLOR
+#define BLE_NUS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> BLE_RSCS_C_ENABLED  - ble_rscs_c - Running Speed and Cadence Client
+ 
+
+#ifndef BLE_RSCS_C_ENABLED
+#define BLE_RSCS_C_ENABLED 0
+#endif
+
+// <q> BLE_RSCS_ENABLED  - ble_rscs - Running Speed and Cadence Service
+ 
+
+#ifndef BLE_RSCS_ENABLED
+#define BLE_RSCS_ENABLED 0
+#endif
+
+// <q> BLE_TPS_ENABLED  - ble_tps - TX Power Service
+ 
+
+#ifndef BLE_TPS_ENABLED
+#define BLE_TPS_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Core 
+
+//==========================================================
+// <e> NRF_MPU_LIB_ENABLED - nrf_mpu_lib - Module for MPU
+//==========================================================
+#ifndef NRF_MPU_LIB_ENABLED
+#define NRF_MPU_LIB_ENABLED 0
+#endif
+// <q> NRF_MPU_LIB_CLI_CMDS  - Enable CLI commands specific to the module.
+ 
+
+#ifndef NRF_MPU_LIB_CLI_CMDS
+#define NRF_MPU_LIB_CLI_CMDS 0
+#endif
+
+// </e>
+
+// <e> NRF_STACK_GUARD_ENABLED - nrf_stack_guard - Stack guard
+//==========================================================
+#ifndef NRF_STACK_GUARD_ENABLED
+#define NRF_STACK_GUARD_ENABLED 0
+#endif
+// <o> NRF_STACK_GUARD_CONFIG_SIZE  - Size of the stack guard.
+ 
+// <5=> 32 bytes 
+// <6=> 64 bytes 
+// <7=> 128 bytes 
+// <8=> 256 bytes 
+// <9=> 512 bytes 
+// <10=> 1024 bytes 
+// <11=> 2048 bytes 
+// <12=> 4096 bytes 
+
+#ifndef NRF_STACK_GUARD_CONFIG_SIZE
+#define NRF_STACK_GUARD_CONFIG_SIZE 7
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Crypto 
+
+//==========================================================
+// <e> NRF_CRYPTO_ENABLED - nrf_crypto - Cryptography library.
+//==========================================================
+#ifndef NRF_CRYPTO_ENABLED
+#define NRF_CRYPTO_ENABLED 1
+#endif
+// <o> NRF_CRYPTO_ALLOCATOR  - Memory allocator
+ 
+
+// <i> Choose memory allocator used by nrf_crypto. Default is alloca if possible or nrf_malloc otherwise. If 'User macros' are selected, the user has to create 'nrf_crypto_allocator.h' file that contains NRF_CRYPTO_ALLOC, NRF_CRYPTO_FREE, and NRF_CRYPTO_ALLOC_ON_STACK.
+// <0=> Default 
+// <1=> User macros 
+// <2=> On stack (alloca) 
+// <3=> C dynamic memory (malloc) 
+// <4=> SDK Memory Manager (nrf_malloc) 
+
+#ifndef NRF_CRYPTO_ALLOCATOR
+#define NRF_CRYPTO_ALLOCATOR 0
+#endif
+
+// <e> NRF_CRYPTO_BACKEND_CC310_BL_ENABLED - Enable the ARM Cryptocell CC310 reduced backend.
+
+// <i> The CC310 hardware-accelerated cryptography backend with reduced functionality and footprint (only available on nRF52840).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED  - Enable the secp224r1 elliptic curve support using CC310_BL.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED 0
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED  - Enable the secp256r1 elliptic curve support using CC310_BL.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED  - CC310_BL SHA-256 hash functionality.
+ 
+
+// <i> CC310_BL backend implementation for hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED  - nrf_cc310_bl buffers to RAM before running hash operation
+ 
+
+// <i> Enabling this makes hashing of addresses in FLASH range possible. Size of buffer allocated for hashing is set by NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED 0
+#endif
+
+// <o> NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE - nrf_cc310_bl hash outputs digests in little endian 
+// <i> Makes the nrf_cc310_bl hash functions output digests in little endian format. Only for use in nRF SDK DFU!
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE
+#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE 4096
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED  - Enable Interrupts while support using CC310 bl.
+ 
+
+// <i> Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_CC310_ENABLED - Enable the ARM Cryptocell CC310 backend.
+
+// <i> The CC310 hardware-accelerated cryptography backend (only available on nRF52840).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CC310_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED  - Enable the AES CBC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED  - Enable the AES CTR mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED  - Enable the AES ECB mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED  - Enable the AES CBC_MAC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED  - Enable the AES CMAC mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED  - Enable the AES CCM mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED  - Enable the AES CCM* mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED  - Enable the CHACHA-POLY mode using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED  - Enable the secp160r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED  - Enable the secp160r2 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED  - Enable the secp192r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED  - Enable the secp224r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED  - Enable the secp256r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED  - Enable the secp384r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED  - Enable the secp521r1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED  - Enable the secp160k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED  - Enable the secp192k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED  - Enable the secp224k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED  - Enable the secp256k1 elliptic curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED  - Enable the Curve25519 curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED  - Enable the Ed25519 curve support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED  - CC310 SHA-256 hash functionality.
+ 
+
+// <i> CC310 backend implementation for hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED  - CC310 SHA-512 hash functionality
+ 
+
+// <i> CC310 backend implementation for SHA-512 (in software).
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED  - CC310 HMAC using SHA-256
+ 
+
+// <i> CC310 backend implementation for HMAC using hardware-accelerated SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED  - CC310 HMAC using SHA-512
+ 
+
+// <i> CC310 backend implementation for HMAC using SHA-512 (in software).
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED  - Enable RNG support using CC310.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED  - Enable Interrupts while support using CC310.
+ 
+
+// <i> Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used
+
+#ifndef NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED
+#define NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_CIFRA_ENABLED - Enable the Cifra backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_CIFRA_ENABLED
+#define NRF_CRYPTO_BACKEND_CIFRA_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED  - Enable the AES EAX mode using Cifra.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED
+#define NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED - Enable the mbed TLS backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED  - Enable the AES CBC mode mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED  - Enable the AES CTR mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED  - Enable the AES CFB mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED  - Enable the AES ECB mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED  - Enable the AES CBC MAC mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED  - Enable the AES CMAC mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED  - Enable the AES CCM mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED  - Enable the AES GCM mode using mbed TLS.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED  - Enable secp192r1 (NIST 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192r1 (NIST 192-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED  - Enable secp224r1 (NIST 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224r1 (NIST 224-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED  - Enable secp256r1 (NIST 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256r1 (NIST 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED  - Enable secp384r1 (NIST 384-bit) curve
+ 
+
+// <i> Enable this setting if you need secp384r1 (NIST 384-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED  - Enable secp521r1 (NIST 521-bit) curve
+ 
+
+// <i> Enable this setting if you need secp521r1 (NIST 521-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED  - Enable secp192k1 (Koblitz 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192k1 (Koblitz 192-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED  - Enable secp224k1 (Koblitz 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224k1 (Koblitz 224-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED  - Enable secp256k1 (Koblitz 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256k1 (Koblitz 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED  - Enable bp256r1 (Brainpool 256-bit) curve
+ 
+
+// <i> Enable this setting if you need bp256r1 (Brainpool 256-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED  - Enable bp384r1 (Brainpool 384-bit) curve
+ 
+
+// <i> Enable this setting if you need bp384r1 (Brainpool 384-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED  - Enable bp512r1 (Brainpool 512-bit) curve
+ 
+
+// <i> Enable this setting if you need bp512r1 (Brainpool 512-bit) support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED  - Enable Curve25519 curve
+ 
+
+// <i> Enable this setting if you need Curve25519 support using MBEDTLS
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED  - Enable mbed TLS SHA-256 hash functionality.
+ 
+
+// <i> mbed TLS backend implementation for SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED  - Enable mbed TLS SHA-512 hash functionality.
+ 
+
+// <i> mbed TLS backend implementation for SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED  - Enable mbed TLS HMAC using SHA-256.
+ 
+
+// <i> mbed TLS backend implementation for HMAC using SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED  - Enable mbed TLS HMAC using SHA-512.
+ 
+
+// <i> mbed TLS backend implementation for HMAC using SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED - Enable the micro-ecc backend.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED  - Enable secp192r1 (NIST 192-bit) curve
+ 
+
+// <i> Enable this setting if you need secp192r1 (NIST 192-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED  - Enable secp224r1 (NIST 224-bit) curve
+ 
+
+// <i> Enable this setting if you need secp224r1 (NIST 224-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED  - Enable secp256r1 (NIST 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256r1 (NIST 256-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED  - Enable secp256k1 (Koblitz 256-bit) curve
+ 
+
+// <i> Enable this setting if you need secp256k1 (Koblitz 256-bit) support using micro-ecc
+
+#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED
+#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED - Enable the nRF HW RNG backend.
+
+// <i> The nRF HW backend provide access to RNG peripheral in nRF5x devices.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED  - Enable mbed TLS CTR-DRBG algorithm.
+ 
+
+// <i> Enable mbed TLS CTR-DRBG standardized by NIST (NIST SP 800-90A Rev. 1). The nRF HW RNG is used as an entropy source for seeding.
+
+#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_NRF_SW_ENABLED - Enable the legacy nRFx sw for crypto.
+
+// <i> The nRF SW cryptography backend (only used in bootloader context).
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_NRF_SW_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_SW_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED  - nRF SW hash backend support for SHA-256
+ 
+
+// <i> The nRF SW backend provide access to nRF SDK legacy hash implementation of SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_OBERON_ENABLED - Enable the Oberon backend
+
+// <i> The Oberon backend
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED  - Enable the CHACHA-POLY mode using Oberon.
+ 
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED  - Enable secp256r1 curve
+ 
+
+// <i> Enable this setting if you need secp256r1 curve support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED  - Enable Curve25519 ECDH
+ 
+
+// <i> Enable this setting if you need Curve25519 ECDH support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED  - Enable Ed25519 signature scheme
+ 
+
+// <i> Enable this setting if you need Ed25519 support using Oberon library
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED  - Oberon SHA-256 hash functionality
+ 
+
+// <i> Oberon backend implementation for SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED  - Oberon SHA-512 hash functionality
+ 
+
+// <i> Oberon backend implementation for SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED  - Oberon HMAC using SHA-256
+ 
+
+// <i> Oberon backend implementation for HMAC using SHA-256.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED 1
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED  - Oberon HMAC using SHA-512
+ 
+
+// <i> Oberon backend implementation for HMAC using SHA-512.
+
+#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED 1
+#endif
+
+// </e>
+
+// <e> NRF_CRYPTO_BACKEND_OPTIGA_ENABLED - Enable the nrf_crypto Optiga Trust X backend.
+
+// <i> Enables the nrf_crypto backend for Optiga Trust X devices.
+//==========================================================
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_ENABLED 0
+#endif
+// <q> NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED  - Optiga backend support for RNG
+ 
+
+// <i> The Optiga backend provide external chip RNG.
+
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED 0
+#endif
+
+// <q> NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED  - Optiga backend support for ECC secp256r1
+ 
+
+// <i> The Optiga backend provide external chip ECC using secp256r1.
+
+#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED
+#define NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED 1
+#endif
+
+// </e>
+
+// <q> NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED  - Big-endian byte order in raw Curve25519 data
+ 
+
+// <i> Enable big-endian byte order in Curve25519 API, if set to 1. Use little-endian, if set to 0.
+
+#ifndef NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED
+#define NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_DFU 
+
+//==========================================================
+// <h> ble_dfu - Device Firmware Update
+
+//==========================================================
+// <q> BLE_DFU_ENABLED  - Enable DFU Service.
+ 
+
+#ifndef BLE_DFU_ENABLED
+#define BLE_DFU_ENABLED 0
+#endif
+
+// <q> NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS  - Buttonless DFU supports bonds.
+ 
+
+#ifndef NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS
+#define NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Drivers 
+
+//==========================================================
+// <e> COMP_ENABLED - nrf_drv_comp - COMP peripheral driver - legacy layer
+//==========================================================
+#ifndef COMP_ENABLED
+#define COMP_ENABLED 0
+#endif
+// <o> COMP_CONFIG_REF  - Reference voltage
+ 
+// <0=> Internal 1.2V 
+// <1=> Internal 1.8V 
+// <2=> Internal 2.4V 
+// <4=> VDD 
+// <7=> ARef 
+
+#ifndef COMP_CONFIG_REF
+#define COMP_CONFIG_REF 1
+#endif
+
+// <o> COMP_CONFIG_MAIN_MODE  - Main mode
+ 
+// <0=> Single ended 
+// <1=> Differential 
+
+#ifndef COMP_CONFIG_MAIN_MODE
+#define COMP_CONFIG_MAIN_MODE 0
+#endif
+
+// <o> COMP_CONFIG_SPEED_MODE  - Speed mode
+ 
+// <0=> Low power 
+// <1=> Normal 
+// <2=> High speed 
+
+#ifndef COMP_CONFIG_SPEED_MODE
+#define COMP_CONFIG_SPEED_MODE 2
+#endif
+
+// <o> COMP_CONFIG_HYST  - Hystheresis
+ 
+// <0=> No 
+// <1=> 50mV 
+
+#ifndef COMP_CONFIG_HYST
+#define COMP_CONFIG_HYST 0
+#endif
+
+// <o> COMP_CONFIG_ISOURCE  - Current Source
+ 
+// <0=> Off 
+// <1=> 2.5 uA 
+// <2=> 5 uA 
+// <3=> 10 uA 
+
+#ifndef COMP_CONFIG_ISOURCE
+#define COMP_CONFIG_ISOURCE 0
+#endif
+
+// <o> COMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef COMP_CONFIG_INPUT
+#define COMP_CONFIG_INPUT 0
+#endif
+
+// <o> COMP_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef COMP_CONFIG_IRQ_PRIORITY
+#define COMP_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <q> EGU_ENABLED  - nrf_drv_swi - SWI(EGU) peripheral driver - legacy layer
+ 
+
+#ifndef EGU_ENABLED
+#define EGU_ENABLED 0
+#endif
+
+// <e> GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver - legacy layer
+//==========================================================
+#ifndef GPIOTE_ENABLED
+#define GPIOTE_ENABLED 0
+#endif
+// <o> GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins 
+#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS
+#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1
+#endif
+
+// <o> GPIOTE_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef GPIOTE_CONFIG_IRQ_PRIORITY
+#define GPIOTE_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> I2S_ENABLED - nrf_drv_i2s - I2S peripheral driver - legacy layer
+//==========================================================
+#ifndef I2S_ENABLED
+#define I2S_ENABLED 0
+#endif
+// <o> I2S_CONFIG_SCK_PIN - SCK pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SCK_PIN
+#define I2S_CONFIG_SCK_PIN 31
+#endif
+
+// <o> I2S_CONFIG_LRCK_PIN - LRCK pin  <1-31> 
+
+
+#ifndef I2S_CONFIG_LRCK_PIN
+#define I2S_CONFIG_LRCK_PIN 30
+#endif
+
+// <o> I2S_CONFIG_MCK_PIN - MCK pin 
+#ifndef I2S_CONFIG_MCK_PIN
+#define I2S_CONFIG_MCK_PIN 255
+#endif
+
+// <o> I2S_CONFIG_SDOUT_PIN - SDOUT pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SDOUT_PIN
+#define I2S_CONFIG_SDOUT_PIN 29
+#endif
+
+// <o> I2S_CONFIG_SDIN_PIN - SDIN pin  <0-31> 
+
+
+#ifndef I2S_CONFIG_SDIN_PIN
+#define I2S_CONFIG_SDIN_PIN 28
+#endif
+
+// <o> I2S_CONFIG_MASTER  - Mode
+ 
+// <0=> Master 
+// <1=> Slave 
+
+#ifndef I2S_CONFIG_MASTER
+#define I2S_CONFIG_MASTER 0
+#endif
+
+// <o> I2S_CONFIG_FORMAT  - Format
+ 
+// <0=> I2S 
+// <1=> Aligned 
+
+#ifndef I2S_CONFIG_FORMAT
+#define I2S_CONFIG_FORMAT 0
+#endif
+
+// <o> I2S_CONFIG_ALIGN  - Alignment
+ 
+// <0=> Left 
+// <1=> Right 
+
+#ifndef I2S_CONFIG_ALIGN
+#define I2S_CONFIG_ALIGN 0
+#endif
+
+// <o> I2S_CONFIG_SWIDTH  - Sample width (bits)
+ 
+// <0=> 8 
+// <1=> 16 
+// <2=> 24 
+
+#ifndef I2S_CONFIG_SWIDTH
+#define I2S_CONFIG_SWIDTH 1
+#endif
+
+// <o> I2S_CONFIG_CHANNELS  - Channels
+ 
+// <0=> Stereo 
+// <1=> Left 
+// <2=> Right 
+
+#ifndef I2S_CONFIG_CHANNELS
+#define I2S_CONFIG_CHANNELS 1
+#endif
+
+// <o> I2S_CONFIG_MCK_SETUP  - MCK behavior
+ 
+// <0=> Disabled 
+// <2147483648=> 32MHz/2 
+// <1342177280=> 32MHz/3 
+// <1073741824=> 32MHz/4 
+// <805306368=> 32MHz/5 
+// <671088640=> 32MHz/6 
+// <536870912=> 32MHz/8 
+// <402653184=> 32MHz/10 
+// <369098752=> 32MHz/11 
+// <285212672=> 32MHz/15 
+// <268435456=> 32MHz/16 
+// <201326592=> 32MHz/21 
+// <184549376=> 32MHz/23 
+// <142606336=> 32MHz/30 
+// <138412032=> 32MHz/31 
+// <134217728=> 32MHz/32 
+// <100663296=> 32MHz/42 
+// <68157440=> 32MHz/63 
+// <34340864=> 32MHz/125 
+
+#ifndef I2S_CONFIG_MCK_SETUP
+#define I2S_CONFIG_MCK_SETUP 536870912
+#endif
+
+// <o> I2S_CONFIG_RATIO  - MCK/LRCK ratio
+ 
+// <0=> 32x 
+// <1=> 48x 
+// <2=> 64x 
+// <3=> 96x 
+// <4=> 128x 
+// <5=> 192x 
+// <6=> 256x 
+// <7=> 384x 
+// <8=> 512x 
+
+#ifndef I2S_CONFIG_RATIO
+#define I2S_CONFIG_RATIO 2000
+#endif
+
+// <o> I2S_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef I2S_CONFIG_IRQ_PRIORITY
+#define I2S_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> I2S_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef I2S_CONFIG_LOG_ENABLED
+#define I2S_CONFIG_LOG_ENABLED 0
+#endif
+// <o> I2S_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef I2S_CONFIG_LOG_LEVEL
+#define I2S_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 I2S_CONFIG_INFO_COLOR
+#define I2S_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 I2S_CONFIG_DEBUG_COLOR
+#define I2S_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> LPCOMP_ENABLED - nrf_drv_lpcomp - LPCOMP peripheral driver - legacy layer
+//==========================================================
+#ifndef LPCOMP_ENABLED
+#define LPCOMP_ENABLED 0
+#endif
+// <o> LPCOMP_CONFIG_REFERENCE  - Reference voltage
+ 
+// <0=> Supply 1/8 
+// <1=> Supply 2/8 
+// <2=> Supply 3/8 
+// <3=> Supply 4/8 
+// <4=> Supply 5/8 
+// <5=> Supply 6/8 
+// <6=> Supply 7/8 
+// <8=> Supply 1/16 (nRF52) 
+// <9=> Supply 3/16 (nRF52) 
+// <10=> Supply 5/16 (nRF52) 
+// <11=> Supply 7/16 (nRF52) 
+// <12=> Supply 9/16 (nRF52) 
+// <13=> Supply 11/16 (nRF52) 
+// <14=> Supply 13/16 (nRF52) 
+// <15=> Supply 15/16 (nRF52) 
+// <7=> External Ref 0 
+// <65543=> External Ref 1 
+
+#ifndef LPCOMP_CONFIG_REFERENCE
+#define LPCOMP_CONFIG_REFERENCE 3
+#endif
+
+// <o> LPCOMP_CONFIG_DETECTION  - Detection
+ 
+// <0=> Crossing 
+// <1=> Up 
+// <2=> Down 
+
+#ifndef LPCOMP_CONFIG_DETECTION
+#define LPCOMP_CONFIG_DETECTION 2
+#endif
+
+// <o> LPCOMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef LPCOMP_CONFIG_INPUT
+#define LPCOMP_CONFIG_INPUT 0
+#endif
+
+// <q> LPCOMP_CONFIG_HYST  - Hysteresis
+ 
+
+#ifndef LPCOMP_CONFIG_HYST
+#define LPCOMP_CONFIG_HYST 0
+#endif
+
+// <o> LPCOMP_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef LPCOMP_CONFIG_IRQ_PRIORITY
+#define LPCOMP_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <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=> RC 
+// <1=> XTAL 
+// <2=> Synth 
+// <131073=> External Low Swing 
+// <196609=> External Full Swing 
+
+#ifndef NRFX_CLOCK_CONFIG_LF_SRC
+#define NRFX_CLOCK_CONFIG_LF_SRC 1
+#endif
+
+// <o> NRFX_CLOCK_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_CONFIG_IRQ_PRIORITY
+#define NRFX_CLOCK_CONFIG_IRQ_PRIORITY 6
+#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_CONFIG_REF  - Reference voltage
+ 
+// <0=> Internal 1.2V 
+// <1=> Internal 1.8V 
+// <2=> Internal 2.4V 
+// <4=> VDD 
+// <7=> ARef 
+
+#ifndef NRFX_COMP_CONFIG_REF
+#define NRFX_COMP_CONFIG_REF 1
+#endif
+
+// <o> NRFX_COMP_CONFIG_MAIN_MODE  - Main mode
+ 
+// <0=> Single ended 
+// <1=> Differential 
+
+#ifndef NRFX_COMP_CONFIG_MAIN_MODE
+#define NRFX_COMP_CONFIG_MAIN_MODE 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_SPEED_MODE  - Speed mode
+ 
+// <0=> Low power 
+// <1=> Normal 
+// <2=> High speed 
+
+#ifndef NRFX_COMP_CONFIG_SPEED_MODE
+#define NRFX_COMP_CONFIG_SPEED_MODE 2
+#endif
+
+// <o> NRFX_COMP_CONFIG_HYST  - Hystheresis
+ 
+// <0=> No 
+// <1=> 50mV 
+
+#ifndef NRFX_COMP_CONFIG_HYST
+#define NRFX_COMP_CONFIG_HYST 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_ISOURCE  - Current Source
+ 
+// <0=> Off 
+// <1=> 2.5 uA 
+// <2=> 5 uA 
+// <3=> 10 uA 
+
+#ifndef NRFX_COMP_CONFIG_ISOURCE
+#define NRFX_COMP_CONFIG_ISOURCE 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef NRFX_COMP_CONFIG_INPUT
+#define NRFX_COMP_CONFIG_INPUT 0
+#endif
+
+// <o> NRFX_COMP_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_CONFIG_IRQ_PRIORITY
+#define NRFX_COMP_CONFIG_IRQ_PRIORITY 6
+#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_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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 6
+#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_CONFIG_SCK_PIN - SCK pin  <0-31> 
+
+
+#ifndef NRFX_I2S_CONFIG_SCK_PIN
+#define NRFX_I2S_CONFIG_SCK_PIN 31
+#endif
+
+// <o> NRFX_I2S_CONFIG_LRCK_PIN - LRCK pin  <1-31> 
+
+
+#ifndef NRFX_I2S_CONFIG_LRCK_PIN
+#define NRFX_I2S_CONFIG_LRCK_PIN 30
+#endif
+
+// <o> NRFX_I2S_CONFIG_MCK_PIN - MCK pin 
+#ifndef NRFX_I2S_CONFIG_MCK_PIN
+#define NRFX_I2S_CONFIG_MCK_PIN 255
+#endif
+
+// <o> NRFX_I2S_CONFIG_SDOUT_PIN - SDOUT pin  <0-31> 
+
+
+#ifndef NRFX_I2S_CONFIG_SDOUT_PIN
+#define NRFX_I2S_CONFIG_SDOUT_PIN 29
+#endif
+
+// <o> NRFX_I2S_CONFIG_SDIN_PIN - SDIN pin  <0-31> 
+
+
+#ifndef NRFX_I2S_CONFIG_SDIN_PIN
+#define NRFX_I2S_CONFIG_SDIN_PIN 28
+#endif
+
+// <o> NRFX_I2S_CONFIG_MASTER  - Mode
+ 
+// <0=> Master 
+// <1=> Slave 
+
+#ifndef NRFX_I2S_CONFIG_MASTER
+#define NRFX_I2S_CONFIG_MASTER 0
+#endif
+
+// <o> NRFX_I2S_CONFIG_FORMAT  - Format
+ 
+// <0=> I2S 
+// <1=> Aligned 
+
+#ifndef NRFX_I2S_CONFIG_FORMAT
+#define NRFX_I2S_CONFIG_FORMAT 0
+#endif
+
+// <o> NRFX_I2S_CONFIG_ALIGN  - Alignment
+ 
+// <0=> Left 
+// <1=> Right 
+
+#ifndef NRFX_I2S_CONFIG_ALIGN
+#define NRFX_I2S_CONFIG_ALIGN 0
+#endif
+
+// <o> NRFX_I2S_CONFIG_SWIDTH  - Sample width (bits)
+ 
+// <0=> 8 
+// <1=> 16 
+// <2=> 24 
+
+#ifndef NRFX_I2S_CONFIG_SWIDTH
+#define NRFX_I2S_CONFIG_SWIDTH 1
+#endif
+
+// <o> NRFX_I2S_CONFIG_CHANNELS  - Channels
+ 
+// <0=> Stereo 
+// <1=> Left 
+// <2=> Right 
+
+#ifndef NRFX_I2S_CONFIG_CHANNELS
+#define NRFX_I2S_CONFIG_CHANNELS 1
+#endif
+
+// <o> NRFX_I2S_CONFIG_MCK_SETUP  - MCK behavior
+ 
+// <0=> Disabled 
+// <2147483648=> 32MHz/2 
+// <1342177280=> 32MHz/3 
+// <1073741824=> 32MHz/4 
+// <805306368=> 32MHz/5 
+// <671088640=> 32MHz/6 
+// <536870912=> 32MHz/8 
+// <402653184=> 32MHz/10 
+// <369098752=> 32MHz/11 
+// <285212672=> 32MHz/15 
+// <268435456=> 32MHz/16 
+// <201326592=> 32MHz/21 
+// <184549376=> 32MHz/23 
+// <142606336=> 32MHz/30 
+// <138412032=> 32MHz/31 
+// <134217728=> 32MHz/32 
+// <100663296=> 32MHz/42 
+// <68157440=> 32MHz/63 
+// <34340864=> 32MHz/125 
+
+#ifndef NRFX_I2S_CONFIG_MCK_SETUP
+#define NRFX_I2S_CONFIG_MCK_SETUP 536870912
+#endif
+
+// <o> NRFX_I2S_CONFIG_RATIO  - MCK/LRCK ratio
+ 
+// <0=> 32x 
+// <1=> 48x 
+// <2=> 64x 
+// <3=> 96x 
+// <4=> 128x 
+// <5=> 192x 
+// <6=> 256x 
+// <7=> 384x 
+// <8=> 512x 
+
+#ifndef NRFX_I2S_CONFIG_RATIO
+#define NRFX_I2S_CONFIG_RATIO 2000
+#endif
+
+// <o> NRFX_I2S_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_CONFIG_IRQ_PRIORITY
+#define NRFX_I2S_CONFIG_IRQ_PRIORITY 6
+#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_LPCOMP_ENABLED - nrfx_lpcomp - LPCOMP peripheral driver
+//==========================================================
+#ifndef NRFX_LPCOMP_ENABLED
+#define NRFX_LPCOMP_ENABLED 0
+#endif
+// <o> NRFX_LPCOMP_CONFIG_REFERENCE  - Reference voltage
+ 
+// <0=> Supply 1/8 
+// <1=> Supply 2/8 
+// <2=> Supply 3/8 
+// <3=> Supply 4/8 
+// <4=> Supply 5/8 
+// <5=> Supply 6/8 
+// <6=> Supply 7/8 
+// <8=> Supply 1/16 (nRF52) 
+// <9=> Supply 3/16 (nRF52) 
+// <10=> Supply 5/16 (nRF52) 
+// <11=> Supply 7/16 (nRF52) 
+// <12=> Supply 9/16 (nRF52) 
+// <13=> Supply 11/16 (nRF52) 
+// <14=> Supply 13/16 (nRF52) 
+// <15=> Supply 15/16 (nRF52) 
+// <7=> External Ref 0 
+// <65543=> External Ref 1 
+
+#ifndef NRFX_LPCOMP_CONFIG_REFERENCE
+#define NRFX_LPCOMP_CONFIG_REFERENCE 3
+#endif
+
+// <o> NRFX_LPCOMP_CONFIG_DETECTION  - Detection
+ 
+// <0=> Crossing 
+// <1=> Up 
+// <2=> Down 
+
+#ifndef NRFX_LPCOMP_CONFIG_DETECTION
+#define NRFX_LPCOMP_CONFIG_DETECTION 2
+#endif
+
+// <o> NRFX_LPCOMP_CONFIG_INPUT  - Analog input
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef NRFX_LPCOMP_CONFIG_INPUT
+#define NRFX_LPCOMP_CONFIG_INPUT 0
+#endif
+
+// <q> NRFX_LPCOMP_CONFIG_HYST  - Hysteresis
+ 
+
+#ifndef NRFX_LPCOMP_CONFIG_HYST
+#define NRFX_LPCOMP_CONFIG_HYST 0
+#endif
+
+// <o> NRFX_LPCOMP_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_CONFIG_IRQ_PRIORITY
+#define NRFX_LPCOMP_CONFIG_IRQ_PRIORITY 6
+#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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_NFCT_CONFIG_IRQ_PRIORITY 6
+#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_PDM_ENABLED - nrfx_pdm - PDM peripheral driver
+//==========================================================
+#ifndef NRFX_PDM_ENABLED
+#define NRFX_PDM_ENABLED 0
+#endif
+// <o> NRFX_PDM_CONFIG_MODE  - Mode
+ 
+// <0=> Stereo 
+// <1=> Mono 
+
+#ifndef NRFX_PDM_CONFIG_MODE
+#define NRFX_PDM_CONFIG_MODE 1
+#endif
+
+// <o> NRFX_PDM_CONFIG_EDGE  - Edge
+ 
+// <0=> Left falling 
+// <1=> Left rising 
+
+#ifndef NRFX_PDM_CONFIG_EDGE
+#define NRFX_PDM_CONFIG_EDGE 0
+#endif
+
+// <o> NRFX_PDM_CONFIG_CLOCK_FREQ  - Clock frequency
+ 
+// <134217728=> 1000k 
+// <138412032=> 1032k (default) 
+// <142606336=> 1067k 
+
+#ifndef NRFX_PDM_CONFIG_CLOCK_FREQ
+#define NRFX_PDM_CONFIG_CLOCK_FREQ 138412032
+#endif
+
+// <o> NRFX_PDM_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_CONFIG_IRQ_PRIORITY
+#define NRFX_PDM_CONFIG_IRQ_PRIORITY 6
+#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 1
+#endif
+// <o> NRFX_POWER_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_CONFIG_IRQ_PRIORITY
+#define NRFX_POWER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> NRFX_POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCEN
+#define NRFX_POWER_CONFIG_DEFAULT_DCDCEN 0
+#endif
+
+// <q> NRFX_POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCENHV
+#define NRFX_POWER_CONFIG_DEFAULT_DCDCENHV 0
+#endif
+
+// </e>
+
+// <e> NRFX_PPI_ENABLED - nrfx_ppi - PPI peripheral allocator
+//==========================================================
+#ifndef NRFX_PPI_ENABLED
+#define NRFX_PPI_ENABLED 0
+#endif
+// <e> NRFX_PPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_PPI_CONFIG_LOG_ENABLED
+#define NRFX_PPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_PPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_PPI_CONFIG_LOG_LEVEL
+#define NRFX_PPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_PPI_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_PPI_CONFIG_INFO_COLOR
+#define NRFX_PPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_PPI_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_PPI_CONFIG_DEBUG_COLOR
+#define NRFX_PPI_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  - Enable PWM0 instance
+ 
+
+#ifndef NRFX_PWM0_ENABLED
+#define NRFX_PWM0_ENABLED 0
+#endif
+
+// <q> NRFX_PWM1_ENABLED  - Enable PWM1 instance
+ 
+
+#ifndef NRFX_PWM1_ENABLED
+#define NRFX_PWM1_ENABLED 0
+#endif
+
+// <q> NRFX_PWM2_ENABLED  - Enable PWM2 instance
+ 
+
+#ifndef NRFX_PWM2_ENABLED
+#define NRFX_PWM2_ENABLED 0
+#endif
+
+// <q> NRFX_PWM3_ENABLED  - Enable PWM3 instance
+ 
+
+#ifndef NRFX_PWM3_ENABLED
+#define NRFX_PWM3_ENABLED 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin  <0-31> 
+
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN
+#define NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN 31
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK  - Base clock
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK
+#define NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK 4
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE  - Count mode
+ 
+// <0=> Up 
+// <1=> Up and Down 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE - Top value 
+#ifndef NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE
+#define NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE 1000
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE  - Load mode
+ 
+// <0=> Common 
+// <1=> Grouped 
+// <2=> Individual 
+// <3=> Waveform 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_STEP_MODE  - Step mode
+ 
+// <0=> Auto 
+// <1=> Triggered 
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_STEP_MODE
+#define NRFX_PWM_DEFAULT_CONFIG_STEP_MODE 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 6
+#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_CONFIG_REPORTPER  - Report period
+ 
+// <0=> 10 Samples 
+// <1=> 40 Samples 
+// <2=> 80 Samples 
+// <3=> 120 Samples 
+// <4=> 160 Samples 
+// <5=> 200 Samples 
+// <6=> 240 Samples 
+// <7=> 280 Samples 
+
+#ifndef NRFX_QDEC_CONFIG_REPORTPER
+#define NRFX_QDEC_CONFIG_REPORTPER 0
+#endif
+
+// <o> NRFX_QDEC_CONFIG_SAMPLEPER  - Sample period
+ 
+// <0=> 128 us 
+// <1=> 256 us 
+// <2=> 512 us 
+// <3=> 1024 us 
+// <4=> 2048 us 
+// <5=> 4096 us 
+// <6=> 8192 us 
+// <7=> 16384 us 
+
+#ifndef NRFX_QDEC_CONFIG_SAMPLEPER
+#define NRFX_QDEC_CONFIG_SAMPLEPER 7
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_A - A pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_A
+#define NRFX_QDEC_CONFIG_PIO_A 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_B - B pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_B
+#define NRFX_QDEC_CONFIG_PIO_B 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_PIO_LED - LED pin  <0-31> 
+
+
+#ifndef NRFX_QDEC_CONFIG_PIO_LED
+#define NRFX_QDEC_CONFIG_PIO_LED 31
+#endif
+
+// <o> NRFX_QDEC_CONFIG_LEDPRE - LED pre 
+#ifndef NRFX_QDEC_CONFIG_LEDPRE
+#define NRFX_QDEC_CONFIG_LEDPRE 511
+#endif
+
+// <o> NRFX_QDEC_CONFIG_LEDPOL  - LED polarity
+ 
+// <0=> Active low 
+// <1=> Active high 
+
+#ifndef NRFX_QDEC_CONFIG_LEDPOL
+#define NRFX_QDEC_CONFIG_LEDPOL 1
+#endif
+
+// <q> NRFX_QDEC_CONFIG_DBFEN  - Debouncing enable
+ 
+
+#ifndef NRFX_QDEC_CONFIG_DBFEN
+#define NRFX_QDEC_CONFIG_DBFEN 0
+#endif
+
+// <q> NRFX_QDEC_CONFIG_SAMPLE_INTEN  - Sample ready interrupt enable
+ 
+
+#ifndef NRFX_QDEC_CONFIG_SAMPLE_INTEN
+#define NRFX_QDEC_CONFIG_SAMPLE_INTEN 0
+#endif
+
+// <o> NRFX_QDEC_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_CONFIG_IRQ_PRIORITY
+#define NRFX_QDEC_CONFIG_IRQ_PRIORITY 6
+#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_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).  <0-255> 
+
+
+#ifndef NRFX_QSPI_CONFIG_SCK_DELAY
+#define NRFX_QSPI_CONFIG_SCK_DELAY 1
+#endif
+
+// <o> NRFX_QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation. 
+#ifndef NRFX_QSPI_CONFIG_XIP_OFFSET
+#define NRFX_QSPI_CONFIG_XIP_OFFSET 0
+#endif
+
+// <o> NRFX_QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
+ 
+// <0=> FastRead 
+// <1=> Read2O 
+// <2=> Read2IO 
+// <3=> Read4O 
+// <4=> Read4IO 
+
+#ifndef NRFX_QSPI_CONFIG_READOC
+#define NRFX_QSPI_CONFIG_READOC 0
+#endif
+
+// <o> NRFX_QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
+ 
+// <0=> PP 
+// <1=> PP2O 
+// <2=> PP4O 
+// <3=> PP4IO 
+
+#ifndef NRFX_QSPI_CONFIG_WRITEOC
+#define NRFX_QSPI_CONFIG_WRITEOC 0
+#endif
+
+// <o> NRFX_QSPI_CONFIG_ADDRMODE  - Addressing mode.
+ 
+// <0=> 24bit 
+// <1=> 32bit 
+
+#ifndef NRFX_QSPI_CONFIG_ADDRMODE
+#define NRFX_QSPI_CONFIG_ADDRMODE 0
+#endif
+
+// <o> NRFX_QSPI_CONFIG_MODE  - SPI mode.
+ 
+// <0=> Mode 0 
+// <1=> Mode 1 
+
+#ifndef NRFX_QSPI_CONFIG_MODE
+#define NRFX_QSPI_CONFIG_MODE 0
+#endif
+
+// <o> NRFX_QSPI_CONFIG_FREQUENCY  - Frequency divider.
+ 
+// <0=> 32MHz/1 
+// <1=> 32MHz/2 
+// <2=> 32MHz/3 
+// <3=> 32MHz/4 
+// <4=> 32MHz/5 
+// <5=> 32MHz/6 
+// <6=> 32MHz/7 
+// <7=> 32MHz/8 
+// <8=> 32MHz/9 
+// <9=> 32MHz/10 
+// <10=> 32MHz/11 
+// <11=> 32MHz/12 
+// <12=> 32MHz/13 
+// <13=> 32MHz/14 
+// <14=> 32MHz/15 
+// <15=> 32MHz/16 
+
+#ifndef NRFX_QSPI_CONFIG_FREQUENCY
+#define NRFX_QSPI_CONFIG_FREQUENCY 15
+#endif
+
+// <s> NRFX_QSPI_PIN_SCK - SCK pin value.
+#ifndef NRFX_QSPI_PIN_SCK
+#define NRFX_QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> NRFX_QSPI_PIN_CSN - CSN pin value.
+#ifndef NRFX_QSPI_PIN_CSN
+#define NRFX_QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> NRFX_QSPI_PIN_IO0 - IO0 pin value.
+#ifndef NRFX_QSPI_PIN_IO0
+#define NRFX_QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> NRFX_QSPI_PIN_IO1 - IO1 pin value.
+#ifndef NRFX_QSPI_PIN_IO1
+#define NRFX_QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> NRFX_QSPI_PIN_IO2 - IO2 pin value.
+#ifndef NRFX_QSPI_PIN_IO2
+#define NRFX_QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> NRFX_QSPI_PIN_IO3 - IO3 pin value.
+#ifndef NRFX_QSPI_PIN_IO3
+#define NRFX_QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <o> NRFX_QSPI_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_CONFIG_IRQ_PRIORITY
+#define NRFX_QSPI_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> NRFX_RNG_ENABLED - nrfx_rng - RNG peripheral driver
+//==========================================================
+#ifndef NRFX_RNG_ENABLED
+#define NRFX_RNG_ENABLED 0
+#endif
+// <q> NRFX_RNG_CONFIG_ERROR_CORRECTION  - Error correction
+ 
+
+#ifndef NRFX_RNG_CONFIG_ERROR_CORRECTION
+#define NRFX_RNG_CONFIG_ERROR_CORRECTION 1
+#endif
+
+// <o> NRFX_RNG_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef NRFX_RNG_CONFIG_IRQ_PRIORITY
+#define NRFX_RNG_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_RNG_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_RNG_CONFIG_LOG_ENABLED
+#define NRFX_RNG_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_RNG_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_RNG_CONFIG_LOG_LEVEL
+#define NRFX_RNG_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_RNG_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_RNG_CONFIG_INFO_COLOR
+#define NRFX_RNG_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_RNG_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_RNG_CONFIG_DEBUG_COLOR
+#define NRFX_RNG_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_RTC_ENABLED - nrfx_rtc - RTC peripheral driver
+//==========================================================
+#ifndef NRFX_RTC_ENABLED
+#define NRFX_RTC_ENABLED 0
+#endif
+// <q> NRFX_RTC0_ENABLED  - Enable RTC0 instance
+ 
+
+#ifndef NRFX_RTC0_ENABLED
+#define NRFX_RTC0_ENABLED 0
+#endif
+
+// <q> NRFX_RTC1_ENABLED  - Enable RTC1 instance
+ 
+
+#ifndef NRFX_RTC1_ENABLED
+#define NRFX_RTC1_ENABLED 0
+#endif
+
+// <q> NRFX_RTC2_ENABLED  - Enable RTC2 instance
+ 
+
+#ifndef NRFX_RTC2_ENABLED
+#define NRFX_RTC2_ENABLED 0
+#endif
+
+// <o> NRFX_RTC_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt 
+#ifndef NRFX_RTC_MAXIMUM_LATENCY_US
+#define NRFX_RTC_MAXIMUM_LATENCY_US 2000
+#endif
+
+// <o> NRFX_RTC_DEFAULT_CONFIG_FREQUENCY - Frequency  <16-32768> 
+
+
+#ifndef NRFX_RTC_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_RTC_DEFAULT_CONFIG_FREQUENCY 32768
+#endif
+
+// <q> NRFX_RTC_DEFAULT_CONFIG_RELIABLE  - Ensures safe compare event triggering
+ 
+
+#ifndef NRFX_RTC_DEFAULT_CONFIG_RELIABLE
+#define NRFX_RTC_DEFAULT_CONFIG_RELIABLE 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 6
+#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_CONFIG_RESOLUTION  - Resolution
+ 
+// <0=> 8 bit 
+// <1=> 10 bit 
+// <2=> 12 bit 
+// <3=> 14 bit 
+
+#ifndef NRFX_SAADC_CONFIG_RESOLUTION
+#define NRFX_SAADC_CONFIG_RESOLUTION 1
+#endif
+
+// <o> NRFX_SAADC_CONFIG_OVERSAMPLE  - Sample period
+ 
+// <0=> Disabled 
+// <1=> 2x 
+// <2=> 4x 
+// <3=> 8x 
+// <4=> 16x 
+// <5=> 32x 
+// <6=> 64x 
+// <7=> 128x 
+// <8=> 256x 
+
+#ifndef NRFX_SAADC_CONFIG_OVERSAMPLE
+#define NRFX_SAADC_CONFIG_OVERSAMPLE 0
+#endif
+
+// <q> NRFX_SAADC_CONFIG_LP_MODE  - Enabling low power mode
+ 
+
+#ifndef NRFX_SAADC_CONFIG_LP_MODE
+#define NRFX_SAADC_CONFIG_LP_MODE 0
+#endif
+
+// <o> NRFX_SAADC_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_CONFIG_IRQ_PRIORITY
+#define NRFX_SAADC_CONFIG_IRQ_PRIORITY 6
+#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  - Enable SPIM0 instance
+ 
+
+#ifndef NRFX_SPIM0_ENABLED
+#define NRFX_SPIM0_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM1_ENABLED  - Enable SPIM1 instance
+ 
+
+#ifndef NRFX_SPIM1_ENABLED
+#define NRFX_SPIM1_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM2_ENABLED  - Enable SPIM2 instance
+ 
+
+#ifndef NRFX_SPIM2_ENABLED
+#define NRFX_SPIM2_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM3_ENABLED  - Enable SPIM3 instance
+ 
+
+#ifndef NRFX_SPIM3_ENABLED
+#define NRFX_SPIM3_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_MISO_PULL_CFG  - MISO pin pull configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRFX_SPIM_MISO_PULL_CFG
+#define NRFX_SPIM_MISO_PULL_CFG 1
+#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 6
+#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  - Enable SPIS0 instance
+ 
+
+#ifndef NRFX_SPIS0_ENABLED
+#define NRFX_SPIS0_ENABLED 0
+#endif
+
+// <q> NRFX_SPIS1_ENABLED  - Enable SPIS1 instance
+ 
+
+#ifndef NRFX_SPIS1_ENABLED
+#define NRFX_SPIS1_ENABLED 0
+#endif
+
+// <q> NRFX_SPIS2_ENABLED  - Enable SPIS2 instance
+ 
+
+#ifndef NRFX_SPIS2_ENABLED
+#define NRFX_SPIS2_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 6
+#endif
+
+// <o> NRFX_SPIS_DEFAULT_DEF - SPIS default DEF character  <0-255> 
+
+
+#ifndef NRFX_SPIS_DEFAULT_DEF
+#define NRFX_SPIS_DEFAULT_DEF 255
+#endif
+
+// <o> NRFX_SPIS_DEFAULT_ORC - SPIS default ORC character  <0-255> 
+
+
+#ifndef NRFX_SPIS_DEFAULT_ORC
+#define NRFX_SPIS_DEFAULT_ORC 255
+#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>
+
+// <e> NRFX_SPI_ENABLED - nrfx_spi - SPI peripheral driver
+//==========================================================
+#ifndef NRFX_SPI_ENABLED
+#define NRFX_SPI_ENABLED 0
+#endif
+// <q> NRFX_SPI0_ENABLED  - Enable SPI0 instance
+ 
+
+#ifndef NRFX_SPI0_ENABLED
+#define NRFX_SPI0_ENABLED 0
+#endif
+
+// <q> NRFX_SPI1_ENABLED  - Enable SPI1 instance
+ 
+
+#ifndef NRFX_SPI1_ENABLED
+#define NRFX_SPI1_ENABLED 0
+#endif
+
+// <q> NRFX_SPI2_ENABLED  - Enable SPI2 instance
+ 
+
+#ifndef NRFX_SPI2_ENABLED
+#define NRFX_SPI2_ENABLED 0
+#endif
+
+// <o> NRFX_SPI_MISO_PULL_CFG  - MISO pin pull configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRFX_SPI_MISO_PULL_CFG
+#define NRFX_SPI_MISO_PULL_CFG 1
+#endif
+
+// <o> NRFX_SPI_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_SPI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_SPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SPI_CONFIG_LOG_ENABLED
+#define NRFX_SPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_SPI_CONFIG_LOG_LEVEL
+#define NRFX_SPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SPI_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_SPI_CONFIG_INFO_COLOR
+#define NRFX_SPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SPI_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_SPI_CONFIG_DEBUG_COLOR
+#define NRFX_SPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_SWI_ENABLED - nrfx_swi - SWI/EGU peripheral allocator
+//==========================================================
+#ifndef NRFX_SWI_ENABLED
+#define NRFX_SWI_ENABLED 0
+#endif
+// <q> NRFX_EGU_ENABLED  - Enable EGU support
+ 
+
+#ifndef NRFX_EGU_ENABLED
+#define NRFX_EGU_ENABLED 0
+#endif
+
+// <q> NRFX_SWI0_DISABLED  - Exclude SWI0 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI0_DISABLED
+#define NRFX_SWI0_DISABLED 0
+#endif
+
+// <q> NRFX_SWI1_DISABLED  - Exclude SWI1 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI1_DISABLED
+#define NRFX_SWI1_DISABLED 0
+#endif
+
+// <q> NRFX_SWI2_DISABLED  - Exclude SWI2 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI2_DISABLED
+#define NRFX_SWI2_DISABLED 0
+#endif
+
+// <q> NRFX_SWI3_DISABLED  - Exclude SWI3 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI3_DISABLED
+#define NRFX_SWI3_DISABLED 0
+#endif
+
+// <q> NRFX_SWI4_DISABLED  - Exclude SWI4 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI4_DISABLED
+#define NRFX_SWI4_DISABLED 0
+#endif
+
+// <q> NRFX_SWI5_DISABLED  - Exclude SWI5 from being utilized by the driver
+ 
+
+#ifndef NRFX_SWI5_DISABLED
+#define NRFX_SWI5_DISABLED 0
+#endif
+
+// <e> NRFX_SWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SWI_CONFIG_LOG_ENABLED
+#define NRFX_SWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_SWI_CONFIG_LOG_LEVEL
+#define NRFX_SWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SWI_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_SWI_CONFIG_INFO_COLOR
+#define NRFX_SWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SWI_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_SWI_CONFIG_DEBUG_COLOR
+#define NRFX_SWI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_TIMER_ENABLED - nrfx_timer - TIMER periperal driver
+//==========================================================
+#ifndef NRFX_TIMER_ENABLED
+#define NRFX_TIMER_ENABLED 0
+#endif
+// <q> NRFX_TIMER0_ENABLED  - Enable TIMER0 instance
+ 
+
+#ifndef NRFX_TIMER0_ENABLED
+#define NRFX_TIMER0_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER1_ENABLED  - Enable TIMER1 instance
+ 
+
+#ifndef NRFX_TIMER1_ENABLED
+#define NRFX_TIMER1_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER2_ENABLED  - Enable TIMER2 instance
+ 
+
+#ifndef NRFX_TIMER2_ENABLED
+#define NRFX_TIMER2_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER3_ENABLED  - Enable TIMER3 instance
+ 
+
+#ifndef NRFX_TIMER3_ENABLED
+#define NRFX_TIMER3_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER4_ENABLED  - Enable TIMER4 instance
+ 
+
+#ifndef NRFX_TIMER4_ENABLED
+#define NRFX_TIMER4_ENABLED 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY  - Timer frequency if in Timer mode
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+// <8=> 62.5 kHz 
+// <9=> 31.25 kHz 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_MODE  - Timer mode or operation
+ 
+// <0=> Timer 
+// <1=> Counter 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_MODE
+#define NRFX_TIMER_DEFAULT_CONFIG_MODE 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH  - Timer counter bit width
+ 
+// <0=> 16 bit 
+// <1=> 8 bit 
+// <2=> 24 bit 
+// <3=> 32 bit 
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH
+#define NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH 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 6
+#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  - Enable TWIM0 instance
+ 
+
+#ifndef NRFX_TWIM0_ENABLED
+#define NRFX_TWIM0_ENABLED 0
+#endif
+
+// <q> NRFX_TWIM1_ENABLED  - Enable TWIM1 instance
+ 
+
+#ifndef NRFX_TWIM1_ENABLED
+#define NRFX_TWIM1_ENABLED 0
+#endif
+
+// <o> NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT 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 6
+#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  - Enable TWIS0 instance
+ 
+
+#ifndef NRFX_TWIS0_ENABLED
+#define NRFX_TWIS0_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS1_ENABLED  - Enable TWIS1 instance
+ 
+
+#ifndef NRFX_TWIS1_ENABLED
+#define NRFX_TWIS1_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY  - Assume 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  - Remove 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_ADDR0 - Address0 
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR0
+#define NRFX_TWIS_DEFAULT_CONFIG_ADDR0 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_ADDR1 - Address1 
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR1
+#define NRFX_TWIS_DEFAULT_CONFIG_ADDR1 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL  - SCL pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL
+#define NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL  - SDA pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL
+#define NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL 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 6
+#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_TWI_ENABLED - nrfx_twi - TWI peripheral driver
+//==========================================================
+#ifndef NRFX_TWI_ENABLED
+#define NRFX_TWI_ENABLED 0
+#endif
+// <q> NRFX_TWI0_ENABLED  - Enable TWI0 instance
+ 
+
+#ifndef NRFX_TWI0_ENABLED
+#define NRFX_TWI0_ENABLED 0
+#endif
+
+// <q> NRFX_TWI1_ENABLED  - Enable TWI1 instance
+ 
+
+#ifndef NRFX_TWI1_ENABLED
+#define NRFX_TWI1_ENABLED 0
+#endif
+
+// <o> NRFX_TWI_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef NRFX_TWI_DEFAULT_CONFIG_FREQUENCY
+#define NRFX_TWI_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
+#endif
+
+// <o> NRFX_TWI_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_TWI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_TWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_TWI_CONFIG_LOG_ENABLED
+#define NRFX_TWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_TWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_TWI_CONFIG_LOG_LEVEL
+#define NRFX_TWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_TWI_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_TWI_CONFIG_INFO_COLOR
+#define NRFX_TWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_TWI_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_TWI_CONFIG_DEBUG_COLOR
+#define NRFX_TWI_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 - Enable UARTE0 instance 
+#ifndef NRFX_UARTE0_ENABLED
+#define NRFX_UARTE0_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE1_ENABLED - Enable UARTE1 instance 
+#ifndef NRFX_UARTE1_ENABLED
+#define NRFX_UARTE1_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_HWFC
+#define NRFX_UARTE_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_PARITY
+#define NRFX_UARTE_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <8388608=> 31250 baud 
+// <10289152=> 38400 baud 
+// <15007744=> 56000 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE
+#define NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE 30801920
+#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 6
+#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_UART_ENABLED - nrfx_uart - UART peripheral driver
+//==========================================================
+#ifndef NRFX_UART_ENABLED
+#define NRFX_UART_ENABLED 0
+#endif
+// <o> NRFX_UART0_ENABLED - Enable UART0 instance 
+#ifndef NRFX_UART0_ENABLED
+#define NRFX_UART0_ENABLED 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_HWFC
+#define NRFX_UART_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_PARITY
+#define NRFX_UART_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> NRFX_UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3866624=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7729152=> 28800 baud 
+// <8388608=> 31250 baud 
+// <10309632=> 38400 baud 
+// <15007744=> 56000 baud 
+// <15462400=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30924800=> 115200 baud 
+// <61845504=> 230400 baud 
+// <67108864=> 250000 baud 
+// <123695104=> 460800 baud 
+// <247386112=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef NRFX_UART_DEFAULT_CONFIG_BAUDRATE
+#define NRFX_UART_DEFAULT_CONFIG_BAUDRATE 30924800
+#endif
+
+// <o> NRFX_UART_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_UART_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> NRFX_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_UART_CONFIG_LOG_ENABLED
+#define NRFX_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRFX_UART_CONFIG_LOG_LEVEL
+#define NRFX_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_UART_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_UART_CONFIG_INFO_COLOR
+#define NRFX_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_UART_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_UART_CONFIG_DEBUG_COLOR
+#define NRFX_UART_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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_USBD_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> NRFX_USBD_CONFIG_DMASCHEDULER_MODE  - USBD DMA scheduler working scheme
+ 
+// <0=> Prioritized access 
+// <1=> Round Robin 
+
+#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_MODE
+#define NRFX_USBD_CONFIG_DMASCHEDULER_MODE 0
+#endif
+
+// <q> NRFX_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> NRFX_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>
+
+// <e> NRFX_WDT_ENABLED - nrfx_wdt - WDT peripheral driver
+//==========================================================
+#ifndef NRFX_WDT_ENABLED
+#define NRFX_WDT_ENABLED 0
+#endif
+// <o> NRFX_WDT_CONFIG_BEHAVIOUR  - WDT behavior in CPU SLEEP or HALT mode
+ 
+// <1=> Run in SLEEP, Pause in HALT 
+// <8=> Pause in SLEEP, Run in HALT 
+// <9=> Run in SLEEP and HALT 
+// <0=> Pause in SLEEP and HALT 
+
+#ifndef NRFX_WDT_CONFIG_BEHAVIOUR
+#define NRFX_WDT_CONFIG_BEHAVIOUR 1
+#endif
+
+// <o> NRFX_WDT_CONFIG_RELOAD_VALUE - Reload value  <15-4294967295> 
+
+
+#ifndef NRFX_WDT_CONFIG_RELOAD_VALUE
+#define NRFX_WDT_CONFIG_RELOAD_VALUE 2000
+#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_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_CONFIG_IRQ_PRIORITY
+#define NRFX_WDT_CONFIG_IRQ_PRIORITY 6
+#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>
+
+// <e> NRF_CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver - legacy layer
+//==========================================================
+#ifndef NRF_CLOCK_ENABLED
+#define NRF_CLOCK_ENABLED 0
+#endif
+// <o> CLOCK_CONFIG_LF_SRC  - LF Clock Source
+ 
+// <0=> RC 
+// <1=> XTAL 
+// <2=> Synth 
+// <131073=> External Low Swing 
+// <196609=> External Full Swing 
+
+#ifndef CLOCK_CONFIG_LF_SRC
+#define CLOCK_CONFIG_LF_SRC 1
+#endif
+
+// <q> CLOCK_CONFIG_LF_CAL_ENABLED  - Calibration enable for LF Clock Source
+ 
+
+#ifndef CLOCK_CONFIG_LF_CAL_ENABLED
+#define CLOCK_CONFIG_LF_CAL_ENABLED 0
+#endif
+
+// <o> CLOCK_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef CLOCK_CONFIG_IRQ_PRIORITY
+#define CLOCK_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> PDM_ENABLED - nrf_drv_pdm - PDM peripheral driver - legacy layer
+//==========================================================
+#ifndef PDM_ENABLED
+#define PDM_ENABLED 0
+#endif
+// <o> PDM_CONFIG_MODE  - Mode
+ 
+// <0=> Stereo 
+// <1=> Mono 
+
+#ifndef PDM_CONFIG_MODE
+#define PDM_CONFIG_MODE 1
+#endif
+
+// <o> PDM_CONFIG_EDGE  - Edge
+ 
+// <0=> Left falling 
+// <1=> Left rising 
+
+#ifndef PDM_CONFIG_EDGE
+#define PDM_CONFIG_EDGE 0
+#endif
+
+// <o> PDM_CONFIG_CLOCK_FREQ  - Clock frequency
+ 
+// <134217728=> 1000k 
+// <138412032=> 1032k (default) 
+// <142606336=> 1067k 
+
+#ifndef PDM_CONFIG_CLOCK_FREQ
+#define PDM_CONFIG_CLOCK_FREQ 138412032
+#endif
+
+// <o> PDM_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef PDM_CONFIG_IRQ_PRIORITY
+#define PDM_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> POWER_ENABLED - nrf_drv_power - POWER peripheral driver - legacy layer
+//==========================================================
+#ifndef POWER_ENABLED
+#define POWER_ENABLED 1
+#endif
+// <o> POWER_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef POWER_CONFIG_IRQ_PRIORITY
+#define POWER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef POWER_CONFIG_DEFAULT_DCDCEN
+#define POWER_CONFIG_DEFAULT_DCDCEN 0
+#endif
+
+// <q> POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
+ 
+
+// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
+
+#ifndef POWER_CONFIG_DEFAULT_DCDCENHV
+#define POWER_CONFIG_DEFAULT_DCDCENHV 0
+#endif
+
+// </e>
+
+// <q> PPI_ENABLED  - nrf_drv_ppi - PPI peripheral driver - legacy layer
+ 
+
+#ifndef PPI_ENABLED
+#define PPI_ENABLED 0
+#endif
+
+// <e> PWM_ENABLED - nrf_drv_pwm - PWM peripheral driver - legacy layer
+//==========================================================
+#ifndef PWM_ENABLED
+#define PWM_ENABLED 0
+#endif
+// <o> PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT0_PIN
+#define PWM_DEFAULT_CONFIG_OUT0_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT1_PIN
+#define PWM_DEFAULT_CONFIG_OUT1_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT2_PIN
+#define PWM_DEFAULT_CONFIG_OUT2_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin  <0-31> 
+
+
+#ifndef PWM_DEFAULT_CONFIG_OUT3_PIN
+#define PWM_DEFAULT_CONFIG_OUT3_PIN 31
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_BASE_CLOCK  - Base clock
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+
+#ifndef PWM_DEFAULT_CONFIG_BASE_CLOCK
+#define PWM_DEFAULT_CONFIG_BASE_CLOCK 4
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_COUNT_MODE  - Count mode
+ 
+// <0=> Up 
+// <1=> Up and Down 
+
+#ifndef PWM_DEFAULT_CONFIG_COUNT_MODE
+#define PWM_DEFAULT_CONFIG_COUNT_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_TOP_VALUE - Top value 
+#ifndef PWM_DEFAULT_CONFIG_TOP_VALUE
+#define PWM_DEFAULT_CONFIG_TOP_VALUE 1000
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_LOAD_MODE  - Load mode
+ 
+// <0=> Common 
+// <1=> Grouped 
+// <2=> Individual 
+// <3=> Waveform 
+
+#ifndef PWM_DEFAULT_CONFIG_LOAD_MODE
+#define PWM_DEFAULT_CONFIG_LOAD_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_STEP_MODE  - Step mode
+ 
+// <0=> Auto 
+// <1=> Triggered 
+
+#ifndef PWM_DEFAULT_CONFIG_STEP_MODE
+#define PWM_DEFAULT_CONFIG_STEP_MODE 0
+#endif
+
+// <o> PWM_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef PWM_DEFAULT_CONFIG_IRQ_PRIORITY
+#define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> PWM0_ENABLED  - Enable PWM0 instance
+ 
+
+#ifndef PWM0_ENABLED
+#define PWM0_ENABLED 0
+#endif
+
+// <q> PWM1_ENABLED  - Enable PWM1 instance
+ 
+
+#ifndef PWM1_ENABLED
+#define PWM1_ENABLED 0
+#endif
+
+// <q> PWM2_ENABLED  - Enable PWM2 instance
+ 
+
+#ifndef PWM2_ENABLED
+#define PWM2_ENABLED 0
+#endif
+
+// <q> PWM3_ENABLED  - Enable PWM3 instance
+ 
+
+#ifndef PWM3_ENABLED
+#define PWM3_ENABLED 0
+#endif
+
+// </e>
+
+// <e> QDEC_ENABLED - nrf_drv_qdec - QDEC peripheral driver - legacy layer
+//==========================================================
+#ifndef QDEC_ENABLED
+#define QDEC_ENABLED 0
+#endif
+// <o> QDEC_CONFIG_REPORTPER  - Report period
+ 
+// <0=> 10 Samples 
+// <1=> 40 Samples 
+// <2=> 80 Samples 
+// <3=> 120 Samples 
+// <4=> 160 Samples 
+// <5=> 200 Samples 
+// <6=> 240 Samples 
+// <7=> 280 Samples 
+
+#ifndef QDEC_CONFIG_REPORTPER
+#define QDEC_CONFIG_REPORTPER 0
+#endif
+
+// <o> QDEC_CONFIG_SAMPLEPER  - Sample period
+ 
+// <0=> 128 us 
+// <1=> 256 us 
+// <2=> 512 us 
+// <3=> 1024 us 
+// <4=> 2048 us 
+// <5=> 4096 us 
+// <6=> 8192 us 
+// <7=> 16384 us 
+
+#ifndef QDEC_CONFIG_SAMPLEPER
+#define QDEC_CONFIG_SAMPLEPER 7
+#endif
+
+// <o> QDEC_CONFIG_PIO_A - A pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_A
+#define QDEC_CONFIG_PIO_A 31
+#endif
+
+// <o> QDEC_CONFIG_PIO_B - B pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_B
+#define QDEC_CONFIG_PIO_B 31
+#endif
+
+// <o> QDEC_CONFIG_PIO_LED - LED pin  <0-31> 
+
+
+#ifndef QDEC_CONFIG_PIO_LED
+#define QDEC_CONFIG_PIO_LED 31
+#endif
+
+// <o> QDEC_CONFIG_LEDPRE - LED pre 
+#ifndef QDEC_CONFIG_LEDPRE
+#define QDEC_CONFIG_LEDPRE 511
+#endif
+
+// <o> QDEC_CONFIG_LEDPOL  - LED polarity
+ 
+// <0=> Active low 
+// <1=> Active high 
+
+#ifndef QDEC_CONFIG_LEDPOL
+#define QDEC_CONFIG_LEDPOL 1
+#endif
+
+// <q> QDEC_CONFIG_DBFEN  - Debouncing enable
+ 
+
+#ifndef QDEC_CONFIG_DBFEN
+#define QDEC_CONFIG_DBFEN 0
+#endif
+
+// <q> QDEC_CONFIG_SAMPLE_INTEN  - Sample ready interrupt enable
+ 
+
+#ifndef QDEC_CONFIG_SAMPLE_INTEN
+#define QDEC_CONFIG_SAMPLE_INTEN 0
+#endif
+
+// <o> QDEC_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef QDEC_CONFIG_IRQ_PRIORITY
+#define QDEC_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> QSPI_ENABLED - nrf_drv_qspi - QSPI peripheral driver - legacy layer
+//==========================================================
+#ifndef QSPI_ENABLED
+#define QSPI_ENABLED 0
+#endif
+// <o> QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).  <0-255> 
+
+
+#ifndef QSPI_CONFIG_SCK_DELAY
+#define QSPI_CONFIG_SCK_DELAY 1
+#endif
+
+// <o> QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation. 
+#ifndef QSPI_CONFIG_XIP_OFFSET
+#define QSPI_CONFIG_XIP_OFFSET 0
+#endif
+
+// <o> QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
+ 
+// <0=> FastRead 
+// <1=> Read2O 
+// <2=> Read2IO 
+// <3=> Read4O 
+// <4=> Read4IO 
+
+#ifndef QSPI_CONFIG_READOC
+#define QSPI_CONFIG_READOC 0
+#endif
+
+// <o> QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
+ 
+// <0=> PP 
+// <1=> PP2O 
+// <2=> PP4O 
+// <3=> PP4IO 
+
+#ifndef QSPI_CONFIG_WRITEOC
+#define QSPI_CONFIG_WRITEOC 0
+#endif
+
+// <o> QSPI_CONFIG_ADDRMODE  - Addressing mode.
+ 
+// <0=> 24bit 
+// <1=> 32bit 
+
+#ifndef QSPI_CONFIG_ADDRMODE
+#define QSPI_CONFIG_ADDRMODE 0
+#endif
+
+// <o> QSPI_CONFIG_MODE  - SPI mode.
+ 
+// <0=> Mode 0 
+// <1=> Mode 1 
+
+#ifndef QSPI_CONFIG_MODE
+#define QSPI_CONFIG_MODE 0
+#endif
+
+// <o> QSPI_CONFIG_FREQUENCY  - Frequency divider.
+ 
+// <0=> 32MHz/1 
+// <1=> 32MHz/2 
+// <2=> 32MHz/3 
+// <3=> 32MHz/4 
+// <4=> 32MHz/5 
+// <5=> 32MHz/6 
+// <6=> 32MHz/7 
+// <7=> 32MHz/8 
+// <8=> 32MHz/9 
+// <9=> 32MHz/10 
+// <10=> 32MHz/11 
+// <11=> 32MHz/12 
+// <12=> 32MHz/13 
+// <13=> 32MHz/14 
+// <14=> 32MHz/15 
+// <15=> 32MHz/16 
+
+#ifndef QSPI_CONFIG_FREQUENCY
+#define QSPI_CONFIG_FREQUENCY 15
+#endif
+
+// <s> QSPI_PIN_SCK - SCK pin value.
+#ifndef QSPI_PIN_SCK
+#define QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_CSN - CSN pin value.
+#ifndef QSPI_PIN_CSN
+#define QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO0 - IO0 pin value.
+#ifndef QSPI_PIN_IO0
+#define QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO1 - IO1 pin value.
+#ifndef QSPI_PIN_IO1
+#define QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO2 - IO2 pin value.
+#ifndef QSPI_PIN_IO2
+#define QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <s> QSPI_PIN_IO3 - IO3 pin value.
+#ifndef QSPI_PIN_IO3
+#define QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// <o> QSPI_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef QSPI_CONFIG_IRQ_PRIORITY
+#define QSPI_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> RNG_ENABLED - nrf_drv_rng - RNG peripheral driver - legacy layer
+//==========================================================
+#ifndef RNG_ENABLED
+#define RNG_ENABLED 0
+#endif
+// <q> RNG_CONFIG_ERROR_CORRECTION  - Error correction
+ 
+
+#ifndef RNG_CONFIG_ERROR_CORRECTION
+#define RNG_CONFIG_ERROR_CORRECTION 1
+#endif
+
+// <o> RNG_CONFIG_POOL_SIZE - Pool size 
+#ifndef RNG_CONFIG_POOL_SIZE
+#define RNG_CONFIG_POOL_SIZE 64
+#endif
+
+// <o> RNG_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef RNG_CONFIG_IRQ_PRIORITY
+#define RNG_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> RTC_ENABLED - nrf_drv_rtc - RTC peripheral driver - legacy layer
+//==========================================================
+#ifndef RTC_ENABLED
+#define RTC_ENABLED 0
+#endif
+// <o> RTC_DEFAULT_CONFIG_FREQUENCY - Frequency  <16-32768> 
+
+
+#ifndef RTC_DEFAULT_CONFIG_FREQUENCY
+#define RTC_DEFAULT_CONFIG_FREQUENCY 32768
+#endif
+
+// <q> RTC_DEFAULT_CONFIG_RELIABLE  - Ensures safe compare event triggering
+ 
+
+#ifndef RTC_DEFAULT_CONFIG_RELIABLE
+#define RTC_DEFAULT_CONFIG_RELIABLE 0
+#endif
+
+// <o> RTC_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef RTC_DEFAULT_CONFIG_IRQ_PRIORITY
+#define RTC_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> RTC0_ENABLED  - Enable RTC0 instance
+ 
+
+#ifndef RTC0_ENABLED
+#define RTC0_ENABLED 0
+#endif
+
+// <q> RTC1_ENABLED  - Enable RTC1 instance
+ 
+
+#ifndef RTC1_ENABLED
+#define RTC1_ENABLED 0
+#endif
+
+// <q> RTC2_ENABLED  - Enable RTC2 instance
+ 
+
+#ifndef RTC2_ENABLED
+#define RTC2_ENABLED 0
+#endif
+
+// <o> NRF_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt 
+#ifndef NRF_MAXIMUM_LATENCY_US
+#define NRF_MAXIMUM_LATENCY_US 2000
+#endif
+
+// </e>
+
+// <e> SAADC_ENABLED - nrf_drv_saadc - SAADC peripheral driver - legacy layer
+//==========================================================
+#ifndef SAADC_ENABLED
+#define SAADC_ENABLED 0
+#endif
+// <o> SAADC_CONFIG_RESOLUTION  - Resolution
+ 
+// <0=> 8 bit 
+// <1=> 10 bit 
+// <2=> 12 bit 
+// <3=> 14 bit 
+
+#ifndef SAADC_CONFIG_RESOLUTION
+#define SAADC_CONFIG_RESOLUTION 1
+#endif
+
+// <o> SAADC_CONFIG_OVERSAMPLE  - Sample period
+ 
+// <0=> Disabled 
+// <1=> 2x 
+// <2=> 4x 
+// <3=> 8x 
+// <4=> 16x 
+// <5=> 32x 
+// <6=> 64x 
+// <7=> 128x 
+// <8=> 256x 
+
+#ifndef SAADC_CONFIG_OVERSAMPLE
+#define SAADC_CONFIG_OVERSAMPLE 0
+#endif
+
+// <q> SAADC_CONFIG_LP_MODE  - Enabling low power mode
+ 
+
+#ifndef SAADC_CONFIG_LP_MODE
+#define SAADC_CONFIG_LP_MODE 0
+#endif
+
+// <o> SAADC_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SAADC_CONFIG_IRQ_PRIORITY
+#define SAADC_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> SPIS_ENABLED - nrf_drv_spis - SPIS peripheral driver - legacy layer
+//==========================================================
+#ifndef SPIS_ENABLED
+#define SPIS_ENABLED 0
+#endif
+// <o> SPIS_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SPIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> SPIS_DEFAULT_MODE  - Mode
+ 
+// <0=> MODE_0 
+// <1=> MODE_1 
+// <2=> MODE_2 
+// <3=> MODE_3 
+
+#ifndef SPIS_DEFAULT_MODE
+#define SPIS_DEFAULT_MODE 0
+#endif
+
+// <o> SPIS_DEFAULT_BIT_ORDER  - SPIS default bit order
+ 
+// <0=> MSB first 
+// <1=> LSB first 
+
+#ifndef SPIS_DEFAULT_BIT_ORDER
+#define SPIS_DEFAULT_BIT_ORDER 0
+#endif
+
+// <o> SPIS_DEFAULT_DEF - SPIS default DEF character  <0-255> 
+
+
+#ifndef SPIS_DEFAULT_DEF
+#define SPIS_DEFAULT_DEF 255
+#endif
+
+// <o> SPIS_DEFAULT_ORC - SPIS default ORC character  <0-255> 
+
+
+#ifndef SPIS_DEFAULT_ORC
+#define SPIS_DEFAULT_ORC 255
+#endif
+
+// <q> SPIS0_ENABLED  - Enable SPIS0 instance
+ 
+
+#ifndef SPIS0_ENABLED
+#define SPIS0_ENABLED 0
+#endif
+
+// <q> SPIS1_ENABLED  - Enable SPIS1 instance
+ 
+
+#ifndef SPIS1_ENABLED
+#define SPIS1_ENABLED 0
+#endif
+
+// <q> SPIS2_ENABLED  - Enable SPIS2 instance
+ 
+
+#ifndef SPIS2_ENABLED
+#define SPIS2_ENABLED 0
+#endif
+
+// </e>
+
+// <e> SPI_ENABLED - nrf_drv_spi - SPI/SPIM peripheral driver - legacy layer
+//==========================================================
+#ifndef SPI_ENABLED
+#define SPI_ENABLED 0
+#endif
+// <o> SPI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef SPI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> NRF_SPI_DRV_MISO_PULLUP_CFG  - MISO PIN pull-up configuration.
+ 
+// <0=> NRF_GPIO_PIN_NOPULL 
+// <1=> NRF_GPIO_PIN_PULLDOWN 
+// <3=> NRF_GPIO_PIN_PULLUP 
+
+#ifndef NRF_SPI_DRV_MISO_PULLUP_CFG
+#define NRF_SPI_DRV_MISO_PULLUP_CFG 1
+#endif
+
+// <e> SPI0_ENABLED - Enable SPI0 instance
+//==========================================================
+#ifndef SPI0_ENABLED
+#define SPI0_ENABLED 0
+#endif
+// <q> SPI0_USE_EASY_DMA  - Use EasyDMA
+ 
+
+#ifndef SPI0_USE_EASY_DMA
+#define SPI0_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// <e> SPI1_ENABLED - Enable SPI1 instance
+//==========================================================
+#ifndef SPI1_ENABLED
+#define SPI1_ENABLED 0
+#endif
+// <q> SPI1_USE_EASY_DMA  - Use EasyDMA
+ 
+
+#ifndef SPI1_USE_EASY_DMA
+#define SPI1_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// <e> SPI2_ENABLED - Enable SPI2 instance
+//==========================================================
+#ifndef SPI2_ENABLED
+#define SPI2_ENABLED 0
+#endif
+// <q> SPI2_USE_EASY_DMA  - Use EasyDMA
+ 
+
+#ifndef SPI2_USE_EASY_DMA
+#define SPI2_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// </e>
+
+// <e> TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver - legacy layer
+//==========================================================
+#ifndef TIMER_ENABLED
+#define TIMER_ENABLED 0
+#endif
+// <o> TIMER_DEFAULT_CONFIG_FREQUENCY  - Timer frequency if in Timer mode
+ 
+// <0=> 16 MHz 
+// <1=> 8 MHz 
+// <2=> 4 MHz 
+// <3=> 2 MHz 
+// <4=> 1 MHz 
+// <5=> 500 kHz 
+// <6=> 250 kHz 
+// <7=> 125 kHz 
+// <8=> 62.5 kHz 
+// <9=> 31.25 kHz 
+
+#ifndef TIMER_DEFAULT_CONFIG_FREQUENCY
+#define TIMER_DEFAULT_CONFIG_FREQUENCY 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_MODE  - Timer mode or operation
+ 
+// <0=> Timer 
+// <1=> Counter 
+
+#ifndef TIMER_DEFAULT_CONFIG_MODE
+#define TIMER_DEFAULT_CONFIG_MODE 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_BIT_WIDTH  - Timer counter bit width
+ 
+// <0=> 16 bit 
+// <1=> 8 bit 
+// <2=> 24 bit 
+// <3=> 32 bit 
+
+#ifndef TIMER_DEFAULT_CONFIG_BIT_WIDTH
+#define TIMER_DEFAULT_CONFIG_BIT_WIDTH 0
+#endif
+
+// <o> TIMER_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> TIMER0_ENABLED  - Enable TIMER0 instance
+ 
+
+#ifndef TIMER0_ENABLED
+#define TIMER0_ENABLED 0
+#endif
+
+// <q> TIMER1_ENABLED  - Enable TIMER1 instance
+ 
+
+#ifndef TIMER1_ENABLED
+#define TIMER1_ENABLED 0
+#endif
+
+// <q> TIMER2_ENABLED  - Enable TIMER2 instance
+ 
+
+#ifndef TIMER2_ENABLED
+#define TIMER2_ENABLED 0
+#endif
+
+// <q> TIMER3_ENABLED  - Enable TIMER3 instance
+ 
+
+#ifndef TIMER3_ENABLED
+#define TIMER3_ENABLED 0
+#endif
+
+// <q> TIMER4_ENABLED  - Enable TIMER4 instance
+ 
+
+#ifndef TIMER4_ENABLED
+#define TIMER4_ENABLED 0
+#endif
+
+// </e>
+
+// <e> TWIS_ENABLED - nrf_drv_twis - TWIS peripheral driver - legacy layer
+//==========================================================
+#ifndef TWIS_ENABLED
+#define TWIS_ENABLED 0
+#endif
+// <q> TWIS0_ENABLED  - Enable TWIS0 instance
+ 
+
+#ifndef TWIS0_ENABLED
+#define TWIS0_ENABLED 0
+#endif
+
+// <q> TWIS1_ENABLED  - Enable TWIS1 instance
+ 
+
+#ifndef TWIS1_ENABLED
+#define TWIS1_ENABLED 0
+#endif
+
+// <q> TWIS_ASSUME_INIT_AFTER_RESET_ONLY  - Assume 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 TWIS_ASSUME_INIT_AFTER_RESET_ONLY
+#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0
+#endif
+
+// <q> TWIS_NO_SYNC_MODE  - Remove 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 TWIS_NO_SYNC_MODE
+#define TWIS_NO_SYNC_MODE 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_ADDR0 - Address0 
+#ifndef TWIS_DEFAULT_CONFIG_ADDR0
+#define TWIS_DEFAULT_CONFIG_ADDR0 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_ADDR1 - Address1 
+#ifndef TWIS_DEFAULT_CONFIG_ADDR1
+#define TWIS_DEFAULT_CONFIG_ADDR1 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_SCL_PULL  - SCL pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef TWIS_DEFAULT_CONFIG_SCL_PULL
+#define TWIS_DEFAULT_CONFIG_SCL_PULL 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_SDA_PULL  - SDA pin pull configuration
+ 
+// <0=> Disabled 
+// <1=> Pull down 
+// <3=> Pull up 
+
+#ifndef TWIS_DEFAULT_CONFIG_SDA_PULL
+#define TWIS_DEFAULT_CONFIG_SDA_PULL 0
+#endif
+
+// <o> TWIS_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TWIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// <e> TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver - legacy layer
+//==========================================================
+#ifndef TWI_ENABLED
+#define TWI_ENABLED 0
+#endif
+// <o> TWI_DEFAULT_CONFIG_FREQUENCY  - Frequency
+ 
+// <26738688=> 100k 
+// <67108864=> 250k 
+// <104857600=> 400k 
+
+#ifndef TWI_DEFAULT_CONFIG_FREQUENCY
+#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688
+#endif
+
+// <q> TWI_DEFAULT_CONFIG_CLR_BUS_INIT  - Enables bus clearing procedure during init
+ 
+
+#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT
+#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0
+#endif
+
+// <q> TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
+ 
+
+#ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
+#define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
+#endif
+
+// <o> TWI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <e> TWI0_ENABLED - Enable TWI0 instance
+//==========================================================
+#ifndef TWI0_ENABLED
+#define TWI0_ENABLED 0
+#endif
+// <q> TWI0_USE_EASY_DMA  - Use EasyDMA (if present)
+ 
+
+#ifndef TWI0_USE_EASY_DMA
+#define TWI0_USE_EASY_DMA 0
+#endif
+
+// </e>
+
+// <e> TWI1_ENABLED - Enable TWI1 instance
+//==========================================================
+#ifndef TWI1_ENABLED
+#define TWI1_ENABLED 0
+#endif
+// <q> TWI1_USE_EASY_DMA  - Use EasyDMA (if present)
+ 
+
+#ifndef TWI1_USE_EASY_DMA
+#define TWI1_USE_EASY_DMA 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
+//==========================================================
+#ifndef UART_ENABLED
+#define UART_ENABLED 0
+#endif
+// <o> UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef UART_DEFAULT_CONFIG_HWFC
+#define UART_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> UART_DEFAULT_CONFIG_PARITY  - Parity
+ 
+// <0=> Excluded 
+// <14=> Included 
+
+#ifndef UART_DEFAULT_CONFIG_PARITY
+#define UART_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <10289152=> 38400 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef UART_DEFAULT_CONFIG_BAUDRATE
+#define UART_DEFAULT_CONFIG_BAUDRATE 30801920
+#endif
+
+// <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY
+#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <q> UART_EASY_DMA_SUPPORT  - Driver supporting EasyDMA
+ 
+
+#ifndef UART_EASY_DMA_SUPPORT
+#define UART_EASY_DMA_SUPPORT 1
+#endif
+
+// <q> UART_LEGACY_SUPPORT  - Driver supporting Legacy mode
+ 
+
+#ifndef UART_LEGACY_SUPPORT
+#define UART_LEGACY_SUPPORT 1
+#endif
+
+// <e> UART0_ENABLED - Enable UART0 instance
+//==========================================================
+#ifndef UART0_ENABLED
+#define UART0_ENABLED 0
+#endif
+// <q> UART0_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA
+ 
+
+#ifndef UART0_CONFIG_USE_EASY_DMA
+#define UART0_CONFIG_USE_EASY_DMA 1
+#endif
+
+// </e>
+
+// <e> UART1_ENABLED - Enable UART1 instance
+//==========================================================
+#ifndef UART1_ENABLED
+#define UART1_ENABLED 0
+#endif
+// </e>
+
+// </e>
+
+// <e> USBD_ENABLED - nrf_drv_usbd - Software Component
+//==========================================================
+#ifndef USBD_ENABLED
+#define USBD_ENABLED 0
+#endif
+// <o> USBD_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef USBD_CONFIG_IRQ_PRIORITY
+#define USBD_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> USBD_CONFIG_DMASCHEDULER_MODE  - USBD SMA scheduler working scheme
+ 
+// <0=> Prioritized access 
+// <1=> Round Robin 
+
+#ifndef USBD_CONFIG_DMASCHEDULER_MODE
+#define USBD_CONFIG_DMASCHEDULER_MODE 0
+#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 USBD_CONFIG_DMASCHEDULER_ISO_BOOST
+#define 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.
+// <i> NOTE: This option does not work on Engineering A chip.
+
+#ifndef USBD_CONFIG_ISO_IN_ZLP
+#define USBD_CONFIG_ISO_IN_ZLP 0
+#endif
+
+// </e>
+
+// <e> WDT_ENABLED - nrf_drv_wdt - WDT peripheral driver - legacy layer
+//==========================================================
+#ifndef WDT_ENABLED
+#define WDT_ENABLED 0
+#endif
+// <o> WDT_CONFIG_BEHAVIOUR  - WDT behavior in CPU SLEEP or HALT mode
+ 
+// <1=> Run in SLEEP, Pause in HALT 
+// <8=> Pause in SLEEP, Run in HALT 
+// <9=> Run in SLEEP and HALT 
+// <0=> Pause in SLEEP and HALT 
+
+#ifndef WDT_CONFIG_BEHAVIOUR
+#define WDT_CONFIG_BEHAVIOUR 1
+#endif
+
+// <o> WDT_CONFIG_RELOAD_VALUE - Reload value  <15-4294967295> 
+
+
+#ifndef WDT_CONFIG_RELOAD_VALUE
+#define WDT_CONFIG_RELOAD_VALUE 2000
+#endif
+
+// <o> WDT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef WDT_CONFIG_IRQ_PRIORITY
+#define WDT_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Drivers_External 
+
+//==========================================================
+// <q> NRF_TWI_SENSOR_ENABLED  - nrf_twi_sensor - nRF TWI Sensor module
+ 
+
+#ifndef NRF_TWI_SENSOR_ENABLED
+#define NRF_TWI_SENSOR_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Libraries 
+
+//==========================================================
+// <q> APP_GPIOTE_ENABLED  - app_gpiote - GPIOTE events dispatcher
+ 
+
+#ifndef APP_GPIOTE_ENABLED
+#define APP_GPIOTE_ENABLED 0
+#endif
+
+// <q> APP_PWM_ENABLED  - app_pwm - PWM functionality
+ 
+
+#ifndef APP_PWM_ENABLED
+#define APP_PWM_ENABLED 0
+#endif
+
+// <e> APP_SCHEDULER_ENABLED - app_scheduler - Events scheduler
+//==========================================================
+#ifndef APP_SCHEDULER_ENABLED
+#define APP_SCHEDULER_ENABLED 0
+#endif
+// <q> APP_SCHEDULER_WITH_PAUSE  - Enabling pause feature
+ 
+
+#ifndef APP_SCHEDULER_WITH_PAUSE
+#define APP_SCHEDULER_WITH_PAUSE 0
+#endif
+
+// <q> APP_SCHEDULER_WITH_PROFILER  - Enabling scheduler profiling
+ 
+
+#ifndef APP_SCHEDULER_WITH_PROFILER
+#define APP_SCHEDULER_WITH_PROFILER 0
+#endif
+
+// </e>
+
+// <e> APP_SDCARD_ENABLED - app_sdcard - SD/MMC card support using SPI
+//==========================================================
+#ifndef APP_SDCARD_ENABLED
+#define APP_SDCARD_ENABLED 0
+#endif
+// <o> APP_SDCARD_SPI_INSTANCE  - SPI instance used
+ 
+// <0=> 0 
+// <1=> 1 
+// <2=> 2 
+
+#ifndef APP_SDCARD_SPI_INSTANCE
+#define APP_SDCARD_SPI_INSTANCE 0
+#endif
+
+// <o> APP_SDCARD_FREQ_INIT  - SPI frequency
+ 
+// <33554432=> 125 kHz 
+// <67108864=> 250 kHz 
+// <134217728=> 500 kHz 
+// <268435456=> 1 MHz 
+// <536870912=> 2 MHz 
+// <1073741824=> 4 MHz 
+// <2147483648=> 8 MHz 
+
+#ifndef APP_SDCARD_FREQ_INIT
+#define APP_SDCARD_FREQ_INIT 67108864
+#endif
+
+// <o> APP_SDCARD_FREQ_DATA  - SPI frequency
+ 
+// <33554432=> 125 kHz 
+// <67108864=> 250 kHz 
+// <134217728=> 500 kHz 
+// <268435456=> 1 MHz 
+// <536870912=> 2 MHz 
+// <1073741824=> 4 MHz 
+// <2147483648=> 8 MHz 
+
+#ifndef APP_SDCARD_FREQ_DATA
+#define APP_SDCARD_FREQ_DATA 1073741824
+#endif
+
+// </e>
+
+// <e> APP_TIMER_ENABLED - app_timer - Application timer functionality
+//==========================================================
+#ifndef APP_TIMER_ENABLED
+#define APP_TIMER_ENABLED 0
+#endif
+// <o> APP_TIMER_CONFIG_RTC_FREQUENCY  - Configure RTC prescaler.
+ 
+// <0=> 32768 Hz 
+// <1=> 16384 Hz 
+// <3=> 8192 Hz 
+// <7=> 4096 Hz 
+// <15=> 2048 Hz 
+// <31=> 1024 Hz 
+
+#ifndef APP_TIMER_CONFIG_RTC_FREQUENCY
+#define APP_TIMER_CONFIG_RTC_FREQUENCY 1
+#endif
+
+// <o> APP_TIMER_CONFIG_IRQ_PRIORITY  - Interrupt priority
+ 
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest) 
+// <1=> 1 
+// <2=> 2 
+// <3=> 3 
+// <4=> 4 
+// <5=> 5 
+// <6=> 6 
+// <7=> 7 
+
+#ifndef APP_TIMER_CONFIG_IRQ_PRIORITY
+#define APP_TIMER_CONFIG_IRQ_PRIORITY 6
+#endif
+
+// <o> APP_TIMER_CONFIG_OP_QUEUE_SIZE - Capacity of timer requests queue. 
+// <i> Size of the queue depends on how many timers are used
+// <i> in the system, how often timers are started and overall
+// <i> system latency. If queue size is too small app_timer calls
+// <i> will fail.
+
+#ifndef APP_TIMER_CONFIG_OP_QUEUE_SIZE
+#define APP_TIMER_CONFIG_OP_QUEUE_SIZE 10
+#endif
+
+// <q> APP_TIMER_CONFIG_USE_SCHEDULER  - Enable scheduling app_timer events to app_scheduler
+ 
+
+#ifndef APP_TIMER_CONFIG_USE_SCHEDULER
+#define APP_TIMER_CONFIG_USE_SCHEDULER 0
+#endif
+
+// <q> APP_TIMER_KEEPS_RTC_ACTIVE  - Enable RTC always on
+ 
+
+// <i> If option is enabled RTC is kept running even if there is no active timers.
+// <i> This option can be used when app_timer is used for timestamping.
+
+#ifndef APP_TIMER_KEEPS_RTC_ACTIVE
+#define APP_TIMER_KEEPS_RTC_ACTIVE 0
+#endif
+
+// <o> APP_TIMER_SAFE_WINDOW_MS - Maximum possible latency (in milliseconds) of handling app_timer event. 
+// <i> Maximum possible timeout that can be set is reduced by safe window.
+// <i> Example: RTC frequency 16384 Hz, maximum possible timeout 1024 seconds - APP_TIMER_SAFE_WINDOW_MS.
+// <i> Since RTC is not stopped when processor is halted in debugging session, this value
+// <i> must cover it if debugging is needed. It is possible to halt processor for APP_TIMER_SAFE_WINDOW_MS
+// <i> without corrupting app_timer behavior.
+
+#ifndef APP_TIMER_SAFE_WINDOW_MS
+#define APP_TIMER_SAFE_WINDOW_MS 300000
+#endif
+
+// <h> App Timer Legacy configuration - Legacy configuration.
+
+//==========================================================
+// <q> APP_TIMER_WITH_PROFILER  - Enable app_timer profiling
+ 
+
+#ifndef APP_TIMER_WITH_PROFILER
+#define APP_TIMER_WITH_PROFILER 0
+#endif
+
+// <q> APP_TIMER_CONFIG_SWI_NUMBER  - Configure SWI instance used.
+ 
+
+#ifndef APP_TIMER_CONFIG_SWI_NUMBER
+#define APP_TIMER_CONFIG_SWI_NUMBER 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> APP_USBD_AUDIO_ENABLED  - app_usbd_audio - USB AUDIO class
+ 
+
+#ifndef APP_USBD_AUDIO_ENABLED
+#define APP_USBD_AUDIO_ENABLED 0
+#endif
+
+// <e> APP_USBD_ENABLED - app_usbd - USB Device library
+//==========================================================
+#ifndef APP_USBD_ENABLED
+#define APP_USBD_ENABLED 0
+#endif
+// <o> APP_USBD_VID - Vendor ID.  <0x0000-0xFFFF> 
+
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/
+
+#ifndef APP_USBD_VID
+#define APP_USBD_VID 0
+#endif
+
+// <o> APP_USBD_PID - Product ID.  <0x0000-0xFFFF> 
+
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Selected Product ID
+
+#ifndef APP_USBD_PID
+#define APP_USBD_PID 0
+#endif
+
+// <o> APP_USBD_DEVICE_VER_MAJOR - Major device version  <0-99> 
+
+
+// <i> Major device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_MAJOR
+#define APP_USBD_DEVICE_VER_MAJOR 1
+#endif
+
+// <o> APP_USBD_DEVICE_VER_MINOR - Minor device version  <0-9> 
+
+
+// <i> Minor device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_MINOR
+#define APP_USBD_DEVICE_VER_MINOR 0
+#endif
+
+// <o> APP_USBD_DEVICE_VER_SUB - Sub-minor device version  <0-9> 
+
+
+// <i> Sub-minor device version, will be converted automatically to BCD notation. Use just decimal values.
+
+#ifndef APP_USBD_DEVICE_VER_SUB
+#define APP_USBD_DEVICE_VER_SUB 0
+#endif
+
+// <q> APP_USBD_CONFIG_SELF_POWERED  - Self-powered device, as opposed to bus-powered.
+ 
+
+#ifndef APP_USBD_CONFIG_SELF_POWERED
+#define APP_USBD_CONFIG_SELF_POWERED 1
+#endif
+
+// <o> APP_USBD_CONFIG_MAX_POWER - MaxPower field in configuration descriptor in milliamps.  <0-500> 
+
+
+#ifndef APP_USBD_CONFIG_MAX_POWER
+#define APP_USBD_CONFIG_MAX_POWER 100
+#endif
+
+// <q> APP_USBD_CONFIG_POWER_EVENTS_PROCESS  - Process power events.
+ 
+
+// <i> Enable processing power events in USB event handler.
+
+#ifndef APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+#define APP_USBD_CONFIG_POWER_EVENTS_PROCESS 1
+#endif
+
+// <e> APP_USBD_CONFIG_EVENT_QUEUE_ENABLE - Enable event queue.
+
+// <i> This is the default configuration when all the events are placed into internal queue.
+// <i> Disable it when an external queue is used like app_scheduler or if you wish to process all events inside interrupts.
+// <i> Processing all events from the interrupt level adds requirement not to call any functions that modifies the USBD library state from the context higher than USB interrupt context.
+// <i> Functions that modify USBD state are functions for sleep, wakeup, start, stop, enable, and disable.
+//==========================================================
+#ifndef APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
+#define APP_USBD_CONFIG_EVENT_QUEUE_ENABLE 1
+#endif
+// <o> APP_USBD_CONFIG_EVENT_QUEUE_SIZE - The size of the event queue.  <16-64> 
+
+
+// <i> The size of the queue for the events that would be processed in the main loop.
+
+#ifndef APP_USBD_CONFIG_EVENT_QUEUE_SIZE
+#define APP_USBD_CONFIG_EVENT_QUEUE_SIZE 32
+#endif
+
+// <o> APP_USBD_CONFIG_SOF_HANDLING_MODE  - Change SOF events handling mode.
+ 
+
+// <i> Normal queue   - SOF events are pushed normally into the event queue.
+// <i> Compress queue - SOF events are counted and binded with other events or executed when the queue is empty.
+// <i>                  This prevents the queue from filling up with SOF events.
+// <i> Interrupt      - SOF events are processed in interrupt.
+// <0=> Normal queue 
+// <1=> Compress queue 
+// <2=> Interrupt 
+
+#ifndef APP_USBD_CONFIG_SOF_HANDLING_MODE
+#define APP_USBD_CONFIG_SOF_HANDLING_MODE 1
+#endif
+
+// </e>
+
+// <q> APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE  - Provide a function that generates timestamps for logs based on the current SOF.
+ 
+
+// <i> The function app_usbd_sof_timestamp_get is implemented if the logger is enabled. 
+// <i> Use it when initializing the logger. 
+// <i> SOF processing is always enabled when this configuration parameter is active. 
+// <i> Note: This option is configured outside of APP_USBD_CONFIG_LOG_ENABLED. 
+// <i> This means that it works even if the logging in this very module is disabled. 
+
+#ifndef APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE
+#define APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE 0
+#endif
+
+// <o> APP_USBD_CONFIG_DESC_STRING_SIZE - Maximum size of the NULL-terminated string of the string descriptor.  <31-254> 
+
+
+// <i> 31 characters can be stored in the internal USB buffer used for transfers.
+// <i> Any value higher than 31 creates an additional buffer just for descriptor strings.
+
+#ifndef APP_USBD_CONFIG_DESC_STRING_SIZE
+#define APP_USBD_CONFIG_DESC_STRING_SIZE 31
+#endif
+
+// <q> APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED  - Enable UTF8 conversion.
+ 
+
+// <i> Enable UTF8-encoded characters. In normal processing, only ASCII characters are available.
+
+#ifndef APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED
+#define APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED 0
+#endif
+
+// <s> APP_USBD_STRINGS_LANGIDS - Supported languages identifiers.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Comma-separated list of supported languages.
+#ifndef APP_USBD_STRINGS_LANGIDS
+#define APP_USBD_STRINGS_LANGIDS APP_USBD_LANG_AND_SUBLANG(APP_USBD_LANG_ENGLISH, APP_USBD_SUBLANG_ENGLISH_US)
+#endif
+
+// <e> APP_USBD_STRING_ID_MANUFACTURER - Define manufacturer string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_MANUFACTURER
+#define APP_USBD_STRING_ID_MANUFACTURER 1
+#endif
+// <q> APP_USBD_STRINGS_MANUFACTURER_EXTERN  - Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN
+#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_MANUFACTURER - String descriptor for the manufacturer name.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Comma-separated list of manufacturer names for each defined language.
+// <i> Use @ref APP_USBD_STRING_DESC macro to create string descriptor from a NULL-terminated string.
+// <i> Use @ref APP_USBD_STRING_RAW8_DESC macro to create string descriptor from comma-separated uint8_t values.
+// <i> Use @ref APP_USBD_STRING_RAW16_DESC macro to create string descriptor from comma-separated uint16_t values.
+// <i> Alternatively, configure the macro to point to any internal variable pointer that already contains the descriptor.
+// <i> Setting string to NULL disables that string.
+// <i> The order of manufacturer names must be the same like in @ref APP_USBD_STRINGS_LANGIDS.
+#ifndef APP_USBD_STRINGS_MANUFACTURER
+#define APP_USBD_STRINGS_MANUFACTURER APP_USBD_STRING_DESC("Nordic Semiconductor")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_PRODUCT - Define product string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_PRODUCT
+#define APP_USBD_STRING_ID_PRODUCT 2
+#endif
+// <q> APP_USBD_STRINGS_PRODUCT_EXTERN  - Define whether @ref APP_USBD_STRINGS_PRODUCT is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
+#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_PRODUCT - String descriptor for the product name.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> List of product names that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRINGS_PRODUCT
+#define APP_USBD_STRINGS_PRODUCT APP_USBD_STRING_DESC("nRF52 USB Product")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_SERIAL - Define serial number string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_SERIAL
+#define APP_USBD_STRING_ID_SERIAL 3
+#endif
+// <q> APP_USBD_STRING_SERIAL_EXTERN  - Define whether @ref APP_USBD_STRING_SERIAL is created by macro or declared as a global variable.
+ 
+
+#ifndef APP_USBD_STRING_SERIAL_EXTERN
+#define APP_USBD_STRING_SERIAL_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRING_SERIAL - String descriptor for the serial number.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRING_SERIAL
+#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("000000000000")
+#endif
+
+// </e>
+
+// <e> APP_USBD_STRING_ID_CONFIGURATION - Define configuration string ID.
+
+// <i> Setting ID to 0 disables the string.
+//==========================================================
+#ifndef APP_USBD_STRING_ID_CONFIGURATION
+#define APP_USBD_STRING_ID_CONFIGURATION 4
+#endif
+// <q> APP_USBD_STRING_CONFIGURATION_EXTERN  - Define whether @ref APP_USBD_STRINGS_CONFIGURATION is created by macro or declared as global variable.
+ 
+
+#ifndef APP_USBD_STRING_CONFIGURATION_EXTERN
+#define APP_USBD_STRING_CONFIGURATION_EXTERN 0
+#endif
+
+// <s> APP_USBD_STRINGS_CONFIGURATION - String descriptor for the device configuration.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> Configuration string that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
+#ifndef APP_USBD_STRINGS_CONFIGURATION
+#define APP_USBD_STRINGS_CONFIGURATION APP_USBD_STRING_DESC("Default configuration")
+#endif
+
+// </e>
+
+// <s> APP_USBD_STRINGS_USER - Default values for user strings.
+
+// <i> Note: This value is not editable in Configuration Wizard.
+// <i> This value stores all application specific user strings with the default initialization.
+// <i> The setup is done by X-macros.
+// <i> Expected macro parameters:
+// <i> @code
+// <i> X(mnemonic, [=str_idx], ...)
+// <i> @endcode
+// <i> - @c mnemonic: Mnemonic of the string descriptor that would be added to
+// <i>                @ref app_usbd_string_desc_idx_t enumerator.
+// <i> - @c str_idx : String index value, can be set or left empty.
+// <i>                For example, WinUSB driver requires descriptor to be present on 0xEE index.
+// <i>                Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
+// <i> - @c ...     : List of string descriptors for each defined language.
+#ifndef APP_USBD_STRINGS_USER
+#define APP_USBD_STRINGS_USER X(APP_USER_1, , APP_USBD_STRING_DESC("User 1"))
+#endif
+
+// </e>
+
+// <e> APP_USBD_HID_ENABLED - app_usbd_hid - USB HID class
+//==========================================================
+#ifndef APP_USBD_HID_ENABLED
+#define APP_USBD_HID_ENABLED 0
+#endif
+// <o> APP_USBD_HID_DEFAULT_IDLE_RATE - Default idle rate for HID class.   <0-255> 
+
+
+// <i> 0 means indefinite duration, any other value is multiplied by 4 milliseconds. Refer to Chapter 7.2.4 of HID 1.11 Specification.
+
+#ifndef APP_USBD_HID_DEFAULT_IDLE_RATE
+#define APP_USBD_HID_DEFAULT_IDLE_RATE 0
+#endif
+
+// <o> APP_USBD_HID_REPORT_IDLE_TABLE_SIZE - Size of idle rate table.   <1-255> 
+
+
+// <i> Must be higher than the highest report ID used.
+
+#ifndef APP_USBD_HID_REPORT_IDLE_TABLE_SIZE
+#define APP_USBD_HID_REPORT_IDLE_TABLE_SIZE 4
+#endif
+
+// </e>
+
+// <q> APP_USBD_HID_GENERIC_ENABLED  - app_usbd_hid_generic - USB HID generic
+ 
+
+#ifndef APP_USBD_HID_GENERIC_ENABLED
+#define APP_USBD_HID_GENERIC_ENABLED 0
+#endif
+
+// <q> APP_USBD_HID_KBD_ENABLED  - app_usbd_hid_kbd - USB HID keyboard
+ 
+
+#ifndef APP_USBD_HID_KBD_ENABLED
+#define APP_USBD_HID_KBD_ENABLED 0
+#endif
+
+// <q> APP_USBD_HID_MOUSE_ENABLED  - app_usbd_hid_mouse - USB HID mouse
+ 
+
+#ifndef APP_USBD_HID_MOUSE_ENABLED
+#define APP_USBD_HID_MOUSE_ENABLED 0
+#endif
+
+// <q> APP_USBD_MSC_ENABLED  - app_usbd_msc - USB MSC class
+ 
+
+#ifndef APP_USBD_MSC_ENABLED
+#define APP_USBD_MSC_ENABLED 0
+#endif
+
+// <q> CRC16_ENABLED  - crc16 - CRC16 calculation routines
+ 
+
+#ifndef CRC16_ENABLED
+#define CRC16_ENABLED 0
+#endif
+
+// <q> CRC32_ENABLED  - crc32 - CRC32 calculation routines
+ 
+
+#ifndef CRC32_ENABLED
+#define CRC32_ENABLED 0
+#endif
+
+// <q> ECC_ENABLED  - ecc - Elliptic Curve Cryptography Library
+ 
+
+#ifndef ECC_ENABLED
+#define ECC_ENABLED 0
+#endif
+
+// <e> FDS_ENABLED - fds - Flash data storage module
+//==========================================================
+#ifndef FDS_ENABLED
+#define FDS_ENABLED 0
+#endif
+// <h> Pages - Virtual page settings
+
+// <i> Configure the number of virtual pages to use and their size.
+//==========================================================
+// <o> FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. 
+// <i> One of the virtual pages is reserved by the system for garbage collection.
+// <i> Therefore, the minimum is two virtual pages: one page to store data and one page to be used by the system for garbage collection.
+// <i> The total amount of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES * @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes.
+
+#ifndef FDS_VIRTUAL_PAGES
+#define FDS_VIRTUAL_PAGES 3
+#endif
+
+// <o> FDS_VIRTUAL_PAGE_SIZE  - The size of a virtual flash page.
+ 
+
+// <i> Expressed in number of 4-byte words.
+// <i> By default, a virtual page is the same size as a physical page.
+// <i> The size of a virtual page must be a multiple of the size of a physical page.
+// <1024=> 1024 
+// <2048=> 2048 
+
+#ifndef FDS_VIRTUAL_PAGE_SIZE
+#define FDS_VIRTUAL_PAGE_SIZE 1024
+#endif
+
+// <o> FDS_VIRTUAL_PAGES_RESERVED - The number of virtual flash pages that are used by other modules. 
+// <i> FDS module stores its data in the last pages of the flash memory.
+// <i> By setting this value, you can move flash end address used by the FDS.
+// <i> As a result the reserved space can be used by other modules.
+
+#ifndef FDS_VIRTUAL_PAGES_RESERVED
+#define FDS_VIRTUAL_PAGES_RESERVED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Backend - Backend configuration
+
+// <i> Configure which nrf_fstorage backend is used by FDS to write to flash.
+//==========================================================
+// <o> FDS_BACKEND  - FDS flash backend.
+ 
+
+// <i> NRF_FSTORAGE_SD uses the nrf_fstorage_sd backend implementation using the SoftDevice API. Use this if you have a SoftDevice present.
+// <i> NRF_FSTORAGE_NVMC uses the nrf_fstorage_nvmc implementation. Use this setting if you don't use the SoftDevice.
+// <1=> NRF_FSTORAGE_NVMC 
+// <2=> NRF_FSTORAGE_SD 
+
+#ifndef FDS_BACKEND
+#define FDS_BACKEND 2
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Queue - Queue settings
+
+//==========================================================
+// <o> FDS_OP_QUEUE_SIZE - Size of the internal queue. 
+// <i> Increase this value if you frequently get synchronous FDS_ERR_NO_SPACE_IN_QUEUES errors.
+
+#ifndef FDS_OP_QUEUE_SIZE
+#define FDS_OP_QUEUE_SIZE 4
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> CRC - CRC functionality
+
+//==========================================================
+// <e> FDS_CRC_CHECK_ON_READ - Enable CRC checks.
+
+// <i> Save a record's CRC when it is written to flash and check it when the record is opened.
+// <i> Records with an incorrect CRC can still be 'seen' by the user using FDS functions, but they cannot be opened.
+// <i> Additionally, they will not be garbage collected until they are deleted.
+//==========================================================
+#ifndef FDS_CRC_CHECK_ON_READ
+#define FDS_CRC_CHECK_ON_READ 0
+#endif
+// <o> FDS_CRC_CHECK_ON_WRITE  - Perform a CRC check on newly written records.
+ 
+
+// <i> Perform a CRC check on newly written records.
+// <i> This setting can be used to make sure that the record data was not altered while being written to flash.
+// <1=> Enabled 
+// <0=> Disabled 
+
+#ifndef FDS_CRC_CHECK_ON_WRITE
+#define FDS_CRC_CHECK_ON_WRITE 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> Users - Number of users
+
+//==========================================================
+// <o> FDS_MAX_USERS - Maximum number of callbacks that can be registered. 
+#ifndef FDS_MAX_USERS
+#define FDS_MAX_USERS 4
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> HARDFAULT_HANDLER_ENABLED  - hardfault_default - HardFault default handler for debugging and release
+ 
+
+#ifndef HARDFAULT_HANDLER_ENABLED
+#define HARDFAULT_HANDLER_ENABLED 0
+#endif
+
+// <e> HCI_MEM_POOL_ENABLED - hci_mem_pool - memory pool implementation used by HCI
+//==========================================================
+#ifndef HCI_MEM_POOL_ENABLED
+#define HCI_MEM_POOL_ENABLED 0
+#endif
+// <o> HCI_TX_BUF_SIZE - TX buffer size in bytes. 
+#ifndef HCI_TX_BUF_SIZE
+#define HCI_TX_BUF_SIZE 600
+#endif
+
+// <o> HCI_RX_BUF_SIZE - RX buffer size in bytes. 
+#ifndef HCI_RX_BUF_SIZE
+#define HCI_RX_BUF_SIZE 600
+#endif
+
+// <o> HCI_RX_BUF_QUEUE_SIZE - RX buffer queue size. 
+#ifndef HCI_RX_BUF_QUEUE_SIZE
+#define HCI_RX_BUF_QUEUE_SIZE 4
+#endif
+
+// </e>
+
+// <e> HCI_SLIP_ENABLED - hci_slip - SLIP protocol implementation used by HCI
+//==========================================================
+#ifndef HCI_SLIP_ENABLED
+#define HCI_SLIP_ENABLED 0
+#endif
+// <o> HCI_UART_BAUDRATE  - Default Baudrate
+ 
+// <323584=> 1200 baud 
+// <643072=> 2400 baud 
+// <1290240=> 4800 baud 
+// <2576384=> 9600 baud 
+// <3862528=> 14400 baud 
+// <5152768=> 19200 baud 
+// <7716864=> 28800 baud 
+// <10289152=> 38400 baud 
+// <15400960=> 57600 baud 
+// <20615168=> 76800 baud 
+// <30801920=> 115200 baud 
+// <61865984=> 230400 baud 
+// <67108864=> 250000 baud 
+// <121634816=> 460800 baud 
+// <251658240=> 921600 baud 
+// <268435456=> 1000000 baud 
+
+#ifndef HCI_UART_BAUDRATE
+#define HCI_UART_BAUDRATE 30801920
+#endif
+
+// <o> HCI_UART_FLOW_CONTROL  - Hardware Flow Control
+ 
+// <0=> Disabled 
+// <1=> Enabled 
+
+#ifndef HCI_UART_FLOW_CONTROL
+#define HCI_UART_FLOW_CONTROL 0
+#endif
+
+// <o> HCI_UART_RX_PIN - UART RX pin 
+#ifndef HCI_UART_RX_PIN
+#define HCI_UART_RX_PIN 31
+#endif
+
+// <o> HCI_UART_TX_PIN - UART TX pin 
+#ifndef HCI_UART_TX_PIN
+#define HCI_UART_TX_PIN 31
+#endif
+
+// <o> HCI_UART_RTS_PIN - UART RTS pin 
+#ifndef HCI_UART_RTS_PIN
+#define HCI_UART_RTS_PIN 31
+#endif
+
+// <o> HCI_UART_CTS_PIN - UART CTS pin 
+#ifndef HCI_UART_CTS_PIN
+#define HCI_UART_CTS_PIN 31
+#endif
+
+// </e>
+
+// <e> HCI_TRANSPORT_ENABLED - hci_transport - HCI transport
+//==========================================================
+#ifndef HCI_TRANSPORT_ENABLED
+#define HCI_TRANSPORT_ENABLED 0
+#endif
+// <o> HCI_MAX_PACKET_SIZE_IN_BITS - Maximum size of a single application packet in bits. 
+#ifndef HCI_MAX_PACKET_SIZE_IN_BITS
+#define HCI_MAX_PACKET_SIZE_IN_BITS 8000
+#endif
+
+// </e>
+
+// <q> LED_SOFTBLINK_ENABLED  - led_softblink - led_softblink module
+ 
+
+#ifndef LED_SOFTBLINK_ENABLED
+#define LED_SOFTBLINK_ENABLED 0
+#endif
+
+// <q> LOW_POWER_PWM_ENABLED  - low_power_pwm - low_power_pwm module
+ 
+
+#ifndef LOW_POWER_PWM_ENABLED
+#define LOW_POWER_PWM_ENABLED 0
+#endif
+
+// <e> MEM_MANAGER_ENABLED - mem_manager - Dynamic memory allocator
+//==========================================================
+#ifndef MEM_MANAGER_ENABLED
+#define MEM_MANAGER_ENABLED 0
+#endif
+// <o> MEMORY_MANAGER_SMALL_BLOCK_COUNT - Size of each memory blocks identified as 'small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_SMALL_BLOCK_COUNT 1
+#endif
+
+// <o> MEMORY_MANAGER_SMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'small' block. 
+// <i>  Size of each memory blocks identified as 'small' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_SMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_SMALL_BLOCK_SIZE 32
+#endif
+
+// <o> MEMORY_MANAGER_MEDIUM_BLOCK_COUNT - Size of each memory blocks identified as 'medium' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
+#define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_MEDIUM_BLOCK_SIZE -  Size of each memory blocks identified as 'medium' block. 
+// <i>  Size of each memory blocks identified as 'medium' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_SIZE
+#define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 256
+#endif
+
+// <o> MEMORY_MANAGER_LARGE_BLOCK_COUNT - Size of each memory blocks identified as 'large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_LARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'large' block. 
+// <i>  Size of each memory blocks identified as 'large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_LARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_LARGE_BLOCK_SIZE 256
+#endif
+
+// <o> MEMORY_MANAGER_XLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XLARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'extra large' block. 
+// <i>  Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XLARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 1320
+#endif
+
+// <o> MEMORY_MANAGER_XXLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra large' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+#define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XXLARGE_BLOCK_SIZE -  Size of each memory blocks identified as 'extra extra large' block. 
+// <i>  Size of each memory blocks identified as 'extra extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+#define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 3444
+#endif
+
+// <o> MEMORY_MANAGER_XSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XSMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'extra small' block. 
+// <i>  Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XSMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 64
+#endif
+
+// <o> MEMORY_MANAGER_XXSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra small' block.  <0-255> 
+
+
+#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT
+#define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0
+#endif
+
+// <o> MEMORY_MANAGER_XXSMALL_BLOCK_SIZE -  Size of each memory blocks identified as 'extra extra small' block. 
+// <i>  Size of each memory blocks identified as 'extra extra small' block. Memory block are recommended to be word-sized.
+
+#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
+#define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 32
+#endif
+
+// <e> MEM_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef MEM_MANAGER_CONFIG_LOG_ENABLED
+#define MEM_MANAGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> MEM_MANAGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef MEM_MANAGER_CONFIG_LOG_LEVEL
+#define MEM_MANAGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> MEM_MANAGER_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 MEM_MANAGER_CONFIG_INFO_COLOR
+#define MEM_MANAGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> MEM_MANAGER_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 MEM_MANAGER_CONFIG_DEBUG_COLOR
+#define MEM_MANAGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <q> MEM_MANAGER_DISABLE_API_PARAM_CHECK  - Disable API parameter checks in the module.
+ 
+
+#ifndef MEM_MANAGER_DISABLE_API_PARAM_CHECK
+#define MEM_MANAGER_DISABLE_API_PARAM_CHECK 0
+#endif
+
+// </e>
+
+// <e> NRF_BALLOC_ENABLED - nrf_balloc - Block allocator module
+//==========================================================
+#ifndef NRF_BALLOC_ENABLED
+#define NRF_BALLOC_ENABLED 1
+#endif
+// <e> NRF_BALLOC_CONFIG_DEBUG_ENABLED - Enables debug mode in the module.
+//==========================================================
+#ifndef NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define NRF_BALLOC_CONFIG_DEBUG_ENABLED 0
+#endif
+// <o> NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS - Number of words used as head guard.  <0-255> 
+
+
+#ifndef NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS
+#define NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS 1
+#endif
+
+// <o> NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS - Number of words used as tail guard.  <0-255> 
+
+
+#ifndef NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS
+#define NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS 1
+#endif
+
+// <q> NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED  - Enables basic checks in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED
+#define NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED  - Enables double memory free check in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED
+#define NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED  - Enables free memory corruption check in this module.
+ 
+
+#ifndef NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED
+#define NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED 0
+#endif
+
+// <q> NRF_BALLOC_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef NRF_BALLOC_CLI_CMDS
+#define NRF_BALLOC_CLI_CMDS 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRF_CSENSE_ENABLED - nrf_csense - Capacitive sensor module
+//==========================================================
+#ifndef NRF_CSENSE_ENABLED
+#define NRF_CSENSE_ENABLED 0
+#endif
+// <o> NRF_CSENSE_PAD_HYSTERESIS - Minimum value of change required to determine that a pad was touched. 
+#ifndef NRF_CSENSE_PAD_HYSTERESIS
+#define NRF_CSENSE_PAD_HYSTERESIS 15
+#endif
+
+// <o> NRF_CSENSE_PAD_DEVIATION - Minimum value measured on a pad required to take it into account while calculating the step. 
+#ifndef NRF_CSENSE_PAD_DEVIATION
+#define NRF_CSENSE_PAD_DEVIATION 70
+#endif
+
+// <o> NRF_CSENSE_MIN_PAD_VALUE - Minimum normalized value on a pad required to take its value into account. 
+#ifndef NRF_CSENSE_MIN_PAD_VALUE
+#define NRF_CSENSE_MIN_PAD_VALUE 20
+#endif
+
+// <o> NRF_CSENSE_MAX_PADS_NUMBER - Maximum number of pads used for one instance. 
+#ifndef NRF_CSENSE_MAX_PADS_NUMBER
+#define NRF_CSENSE_MAX_PADS_NUMBER 20
+#endif
+
+// <o> NRF_CSENSE_MAX_VALUE - Maximum normalized value obtained from measurement. 
+#ifndef NRF_CSENSE_MAX_VALUE
+#define NRF_CSENSE_MAX_VALUE 1000
+#endif
+
+// <o> NRF_CSENSE_OUTPUT_PIN - Output pin used by the low-level module. 
+// <i> This is used when capacitive sensor does not use COMP.
+
+#ifndef NRF_CSENSE_OUTPUT_PIN
+#define NRF_CSENSE_OUTPUT_PIN 26
+#endif
+
+// </e>
+
+// <e> NRF_DRV_CSENSE_ENABLED - nrf_drv_csense - Capacitive sensor low-level module
+//==========================================================
+#ifndef NRF_DRV_CSENSE_ENABLED
+#define NRF_DRV_CSENSE_ENABLED 0
+#endif
+// <e> USE_COMP - Use the comparator to implement the capacitive sensor driver.
+
+// <i> Due to Anomaly 84, COMP I_SOURCE is not functional. It has too high a varation.
+//==========================================================
+#ifndef USE_COMP
+#define USE_COMP 0
+#endif
+// <o> TIMER0_FOR_CSENSE - First TIMER instance used by the driver (not used on nRF51). 
+#ifndef TIMER0_FOR_CSENSE
+#define TIMER0_FOR_CSENSE 1
+#endif
+
+// <o> TIMER1_FOR_CSENSE - Second TIMER instance used by the driver (not used on nRF51). 
+#ifndef TIMER1_FOR_CSENSE
+#define TIMER1_FOR_CSENSE 2
+#endif
+
+// <o> MEASUREMENT_PERIOD - Single measurement period. 
+// <i> Time of a single measurement can be calculated as
+// <i> T = (1/2)*MEASUREMENT_PERIOD*(1/f_OSC) where f_OSC = I_SOURCE / (2C*(VUP-VDOWN) ).
+// <i> I_SOURCE, VUP, and VDOWN are values used to initialize COMP and C is the capacitance of the used pad.
+
+#ifndef MEASUREMENT_PERIOD
+#define MEASUREMENT_PERIOD 20
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRF_FSTORAGE_ENABLED - nrf_fstorage - Flash abstraction library
+//==========================================================
+#ifndef NRF_FSTORAGE_ENABLED
+#define NRF_FSTORAGE_ENABLED 0
+#endif
+// <h> nrf_fstorage - Common settings
+
+// <i> Common settings to all fstorage implementations
+//==========================================================
+// <q> NRF_FSTORAGE_PARAM_CHECK_DISABLED  - Disable user input validation
+ 
+
+// <i> If selected, use ASSERT to validate user input.
+// <i> This effectively removes user input validation in production code.
+// <i> Recommended setting: OFF, only enable this setting if size is a major concern.
+
+#ifndef NRF_FSTORAGE_PARAM_CHECK_DISABLED
+#define NRF_FSTORAGE_PARAM_CHECK_DISABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_fstorage_sd - Implementation using the SoftDevice
+
+// <i> Configuration options for the fstorage implementation using the SoftDevice
+//==========================================================
+// <o> NRF_FSTORAGE_SD_QUEUE_SIZE - Size of the internal queue of operations 
+// <i> Increase this value if API calls frequently return the error @ref NRF_ERROR_NO_MEM.
+
+#ifndef NRF_FSTORAGE_SD_QUEUE_SIZE
+#define NRF_FSTORAGE_SD_QUEUE_SIZE 4
+#endif
+
+// <o> NRF_FSTORAGE_SD_MAX_RETRIES - Maximum number of attempts at executing an operation when the SoftDevice is busy 
+// <i> Increase this value if events frequently return the @ref NRF_ERROR_TIMEOUT error.
+// <i> The SoftDevice might fail to schedule flash access due to high BLE activity.
+
+#ifndef NRF_FSTORAGE_SD_MAX_RETRIES
+#define NRF_FSTORAGE_SD_MAX_RETRIES 8
+#endif
+
+// <o> NRF_FSTORAGE_SD_MAX_WRITE_SIZE - Maximum number of bytes to be written to flash in a single operation 
+// <i> This value must be a multiple of four.
+// <i> Lowering this value can increase the chances of the SoftDevice being able to execute flash operations in between radio activity.
+// <i> This value is bound by the maximum number of bytes that can be written to flash in a single call to @ref sd_flash_write.
+// <i> That is 1024 bytes for nRF51 ICs and 4096 bytes for nRF52 ICs.
+
+#ifndef NRF_FSTORAGE_SD_MAX_WRITE_SIZE
+#define NRF_FSTORAGE_SD_MAX_WRITE_SIZE 4096
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> NRF_GFX_ENABLED  - nrf_gfx - GFX module
+ 
+
+#ifndef NRF_GFX_ENABLED
+#define NRF_GFX_ENABLED 0
+#endif
+
+// <q> NRF_MEMOBJ_ENABLED  - nrf_memobj - Linked memory allocator module
+ 
+
+#ifndef NRF_MEMOBJ_ENABLED
+#define NRF_MEMOBJ_ENABLED 1
+#endif
+
+// <e> NRF_PWR_MGMT_ENABLED - nrf_pwr_mgmt - Power management module
+//==========================================================
+#ifndef NRF_PWR_MGMT_ENABLED
+#define NRF_PWR_MGMT_ENABLED 0
+#endif
+// <e> NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED - Enables pin debug in the module.
+
+// <i> Selected pin will be set when CPU is in sleep mode.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED
+#define NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_SLEEP_DEBUG_PIN  - Pin number
+ 
+// <0=> 0 (P0.0) 
+// <1=> 1 (P0.1) 
+// <2=> 2 (P0.2) 
+// <3=> 3 (P0.3) 
+// <4=> 4 (P0.4) 
+// <5=> 5 (P0.5) 
+// <6=> 6 (P0.6) 
+// <7=> 7 (P0.7) 
+// <8=> 8 (P0.8) 
+// <9=> 9 (P0.9) 
+// <10=> 10 (P0.10) 
+// <11=> 11 (P0.11) 
+// <12=> 12 (P0.12) 
+// <13=> 13 (P0.13) 
+// <14=> 14 (P0.14) 
+// <15=> 15 (P0.15) 
+// <16=> 16 (P0.16) 
+// <17=> 17 (P0.17) 
+// <18=> 18 (P0.18) 
+// <19=> 19 (P0.19) 
+// <20=> 20 (P0.20) 
+// <21=> 21 (P0.21) 
+// <22=> 22 (P0.22) 
+// <23=> 23 (P0.23) 
+// <24=> 24 (P0.24) 
+// <25=> 25 (P0.25) 
+// <26=> 26 (P0.26) 
+// <27=> 27 (P0.27) 
+// <28=> 28 (P0.28) 
+// <29=> 29 (P0.29) 
+// <30=> 30 (P0.30) 
+// <31=> 31 (P0.31) 
+// <32=> 32 (P1.0) 
+// <33=> 33 (P1.1) 
+// <34=> 34 (P1.2) 
+// <35=> 35 (P1.3) 
+// <36=> 36 (P1.4) 
+// <37=> 37 (P1.5) 
+// <38=> 38 (P1.6) 
+// <39=> 39 (P1.7) 
+// <40=> 40 (P1.8) 
+// <41=> 41 (P1.9) 
+// <42=> 42 (P1.10) 
+// <43=> 43 (P1.11) 
+// <44=> 44 (P1.12) 
+// <45=> 45 (P1.13) 
+// <46=> 46 (P1.14) 
+// <47=> 47 (P1.15) 
+// <4294967295=> Not connected 
+
+#ifndef NRF_PWR_MGMT_SLEEP_DEBUG_PIN
+#define NRF_PWR_MGMT_SLEEP_DEBUG_PIN 31
+#endif
+
+// </e>
+
+// <q> NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED  - Enables CPU usage monitor.
+ 
+
+// <i> Module will trace percentage of CPU usage in one second intervals.
+
+#ifndef NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED
+#define NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED 0
+#endif
+
+// <e> NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED - Enable standby timeout.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED
+#define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S - Standby timeout (in seconds). 
+// <i> Shutdown procedure will begin no earlier than after this number of seconds.
+
+#ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S
+#define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S 3
+#endif
+
+// </e>
+
+// <q> NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED  - Enables FPU event cleaning.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED
+#define NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED 0
+#endif
+
+// <q> NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY  - Blocked shutdown procedure will be retried every second.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
+#define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 0
+#endif
+
+// <q> NRF_PWR_MGMT_CONFIG_USE_SCHEDULER  - Module will use @ref app_scheduler.
+ 
+
+#ifndef NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+#define NRF_PWR_MGMT_CONFIG_USE_SCHEDULER 0
+#endif
+
+// <o> NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT - The number of priorities for module handlers. 
+// <i> The number of stages of the shutdown process.
+
+#ifndef NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT
+#define NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT 3
+#endif
+
+// </e>
+
+// <e> NRF_QUEUE_ENABLED - nrf_queue - Queue module
+//==========================================================
+#ifndef NRF_QUEUE_ENABLED
+#define NRF_QUEUE_ENABLED 0
+#endif
+// <q> NRF_QUEUE_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef NRF_QUEUE_CLI_CMDS
+#define NRF_QUEUE_CLI_CMDS 0
+#endif
+
+// </e>
+
+// <q> NRF_SECTION_ITER_ENABLED  - nrf_section_iter - Section iterator
+ 
+
+#ifndef NRF_SECTION_ITER_ENABLED
+#define NRF_SECTION_ITER_ENABLED 1
+#endif
+
+// <q> NRF_SORTLIST_ENABLED  - nrf_sortlist - Sorted list
+ 
+
+#ifndef NRF_SORTLIST_ENABLED
+#define NRF_SORTLIST_ENABLED 1
+#endif
+
+// <q> NRF_SPI_MNGR_ENABLED  - nrf_spi_mngr - SPI transaction manager
+ 
+
+#ifndef NRF_SPI_MNGR_ENABLED
+#define NRF_SPI_MNGR_ENABLED 0
+#endif
+
+// <q> NRF_STRERROR_ENABLED  - nrf_strerror - Library for converting error code to string.
+ 
+
+#ifndef NRF_STRERROR_ENABLED
+#define NRF_STRERROR_ENABLED 1
+#endif
+
+// <q> NRF_TWI_MNGR_ENABLED  - nrf_twi_mngr - TWI transaction manager
+ 
+
+#ifndef NRF_TWI_MNGR_ENABLED
+#define NRF_TWI_MNGR_ENABLED 0
+#endif
+
+// <q> SLIP_ENABLED  - slip - SLIP encoding and decoding
+ 
+
+#ifndef SLIP_ENABLED
+#define SLIP_ENABLED 0
+#endif
+
+// <e> TASK_MANAGER_ENABLED - task_manager - Task manager.
+//==========================================================
+#ifndef TASK_MANAGER_ENABLED
+#define TASK_MANAGER_ENABLED 0
+#endif
+// <q> TASK_MANAGER_CLI_CMDS  - Enable CLI commands specific to the module
+ 
+
+#ifndef TASK_MANAGER_CLI_CMDS
+#define TASK_MANAGER_CLI_CMDS 0
+#endif
+
+// <o> TASK_MANAGER_CONFIG_MAX_TASKS - Maximum number of tasks which can be created 
+#ifndef TASK_MANAGER_CONFIG_MAX_TASKS
+#define TASK_MANAGER_CONFIG_MAX_TASKS 2
+#endif
+
+// <o> TASK_MANAGER_CONFIG_STACK_SIZE - Stack size for every task (power of 2) 
+#ifndef TASK_MANAGER_CONFIG_STACK_SIZE
+#define TASK_MANAGER_CONFIG_STACK_SIZE 1024
+#endif
+
+// <q> TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED  - Enable stack profiling.
+ 
+
+#ifndef TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED
+#define TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED 1
+#endif
+
+// <o> TASK_MANAGER_CONFIG_STACK_GUARD  - Configures stack guard.
+ 
+// <0=> Disabled 
+// <4=> 32 bytes 
+// <5=> 64 bytes 
+// <6=> 128 bytes 
+// <7=> 256 bytes 
+// <8=> 512 bytes 
+
+#ifndef TASK_MANAGER_CONFIG_STACK_GUARD
+#define TASK_MANAGER_CONFIG_STACK_GUARD 7
+#endif
+
+// </e>
+
+// <h> app_button - buttons handling module
+
+//==========================================================
+// <q> BUTTON_ENABLED  - Enables Button module
+ 
+
+#ifndef BUTTON_ENABLED
+#define BUTTON_ENABLED 0
+#endif
+
+// <q> BUTTON_HIGH_ACCURACY_ENABLED  - Enables GPIOTE high accuracy for buttons
+ 
+
+#ifndef BUTTON_HIGH_ACCURACY_ENABLED
+#define BUTTON_HIGH_ACCURACY_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> app_usbd_cdc_acm - USB CDC ACM class
+
+//==========================================================
+// <q> APP_USBD_CDC_ACM_ENABLED  - Enabling USBD CDC ACM Class library
+ 
+
+#ifndef APP_USBD_CDC_ACM_ENABLED
+#define APP_USBD_CDC_ACM_ENABLED 0
+#endif
+
+// <q> APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE  - Send ZLP on write with same size as endpoint
+ 
+
+// <i> If enabled, CDC ACM class will automatically send a zero length packet after transfer which has the same size as endpoint.
+// <i> This may limit throughput if a lot of binary data is sent, but in terminal mode operation it makes sure that the data is always displayed right after it is sent.
+
+#ifndef APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE
+#define APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE 1
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_cli - Command line interface
+
+//==========================================================
+// <q> NRF_CLI_ENABLED  - Enable/disable the CLI module.
+ 
+
+#ifndef NRF_CLI_ENABLED
+#define NRF_CLI_ENABLED 0
+#endif
+
+// <o> NRF_CLI_ARGC_MAX - Maximum number of parameters passed to the command handler. 
+#ifndef NRF_CLI_ARGC_MAX
+#define NRF_CLI_ARGC_MAX 12
+#endif
+
+// <q> NRF_CLI_BUILD_IN_CMDS_ENABLED  - CLI built-in commands.
+ 
+
+#ifndef NRF_CLI_BUILD_IN_CMDS_ENABLED
+#define NRF_CLI_BUILD_IN_CMDS_ENABLED 1
+#endif
+
+// <o> NRF_CLI_CMD_BUFF_SIZE - Maximum buffer size for a single command. 
+#ifndef NRF_CLI_CMD_BUFF_SIZE
+#define NRF_CLI_CMD_BUFF_SIZE 128
+#endif
+
+// <q> NRF_CLI_ECHO_STATUS  - CLI echo status. If set, echo is ON.
+ 
+
+#ifndef NRF_CLI_ECHO_STATUS
+#define NRF_CLI_ECHO_STATUS 1
+#endif
+
+// <q> NRF_CLI_WILDCARD_ENABLED  - Enable wildcard functionality for CLI commands.
+ 
+
+#ifndef NRF_CLI_WILDCARD_ENABLED
+#define NRF_CLI_WILDCARD_ENABLED 0
+#endif
+
+// <q> NRF_CLI_METAKEYS_ENABLED  - Enable additional control keys for CLI commands like ctrl+a, ctrl+e, ctrl+w, ctrl+u
+ 
+
+#ifndef NRF_CLI_METAKEYS_ENABLED
+#define NRF_CLI_METAKEYS_ENABLED 0
+#endif
+
+// <o> NRF_CLI_PRINTF_BUFF_SIZE - Maximum print buffer size. 
+#ifndef NRF_CLI_PRINTF_BUFF_SIZE
+#define NRF_CLI_PRINTF_BUFF_SIZE 23
+#endif
+
+// <e> NRF_CLI_HISTORY_ENABLED - Enable CLI history mode.
+//==========================================================
+#ifndef NRF_CLI_HISTORY_ENABLED
+#define NRF_CLI_HISTORY_ENABLED 1
+#endif
+// <o> NRF_CLI_HISTORY_ELEMENT_SIZE - Size of one memory object reserved for CLI history. 
+#ifndef NRF_CLI_HISTORY_ELEMENT_SIZE
+#define NRF_CLI_HISTORY_ELEMENT_SIZE 32
+#endif
+
+// <o> NRF_CLI_HISTORY_ELEMENT_COUNT - Number of history memory objects. 
+#ifndef NRF_CLI_HISTORY_ELEMENT_COUNT
+#define NRF_CLI_HISTORY_ELEMENT_COUNT 8
+#endif
+
+// </e>
+
+// <q> NRF_CLI_VT100_COLORS_ENABLED  - CLI VT100 colors.
+ 
+
+#ifndef NRF_CLI_VT100_COLORS_ENABLED
+#define NRF_CLI_VT100_COLORS_ENABLED 1
+#endif
+
+// <q> NRF_CLI_STATISTICS_ENABLED  - Enable CLI statistics.
+ 
+
+#ifndef NRF_CLI_STATISTICS_ENABLED
+#define NRF_CLI_STATISTICS_ENABLED 1
+#endif
+
+// <q> NRF_CLI_LOG_BACKEND  - Enable logger backend interface.
+ 
+
+#ifndef NRF_CLI_LOG_BACKEND
+#define NRF_CLI_LOG_BACKEND 1
+#endif
+
+// <q> NRF_CLI_USES_TASK_MANAGER_ENABLED  - Enable CLI to use task_manager
+ 
+
+#ifndef NRF_CLI_USES_TASK_MANAGER_ENABLED
+#define NRF_CLI_USES_TASK_MANAGER_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nrf_fprintf - fprintf function.
+
+//==========================================================
+// <q> NRF_FPRINTF_ENABLED  - Enable/disable fprintf module.
+ 
+
+#ifndef NRF_FPRINTF_ENABLED
+#define NRF_FPRINTF_ENABLED 1
+#endif
+
+// <q> NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED  - For each printed LF, function will add CR.
+ 
+
+#ifndef NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED
+#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1
+#endif
+
+// <q> NRF_FPRINTF_DOUBLE_ENABLED  - Enable IEEE-754 double precision formatting.
+ 
+
+#ifndef NRF_FPRINTF_DOUBLE_ENABLED
+#define NRF_FPRINTF_DOUBLE_ENABLED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// <h> nRF_Log 
+
+//==========================================================
+// <e> NRF_LOG_ENABLED - nrf_log - Logger
+//==========================================================
+#ifndef NRF_LOG_ENABLED
+#define NRF_LOG_ENABLED 0
+#endif
+// <h> Log message pool - Configuration of log message pool
+
+//==========================================================
+// <o> NRF_LOG_MSGPOOL_ELEMENT_SIZE - Size of a single element in the pool of memory objects. 
+// <i> If a small value is set, then performance of logs processing
+// <i> is degraded because data is fragmented. Bigger value impacts
+// <i> RAM memory utilization. The size is set to fit a message with
+// <i> a timestamp and up to 2 arguments in a single memory object.
+
+#ifndef NRF_LOG_MSGPOOL_ELEMENT_SIZE
+#define NRF_LOG_MSGPOOL_ELEMENT_SIZE 20
+#endif
+
+// <o> NRF_LOG_MSGPOOL_ELEMENT_COUNT - Number of elements in the pool of memory objects 
+// <i> If a small value is set, then it may lead to a deadlock
+// <i> in certain cases if backend has high latency and holds
+// <i> multiple messages for long time. Bigger value impacts
+// <i> RAM memory usage.
+
+#ifndef NRF_LOG_MSGPOOL_ELEMENT_COUNT
+#define NRF_LOG_MSGPOOL_ELEMENT_COUNT 8
+#endif
+
+// </h> 
+//==========================================================
+
+// <q> NRF_LOG_ALLOW_OVERFLOW  - Configures behavior when circular buffer is full.
+ 
+
+// <i> If set then oldest logs are overwritten. Otherwise a 
+// <i> marker is injected informing about overflow.
+
+#ifndef NRF_LOG_ALLOW_OVERFLOW
+#define NRF_LOG_ALLOW_OVERFLOW 1
+#endif
+
+// <o> NRF_LOG_BUFSIZE  - Size of the buffer for storing logs (in bytes).
+ 
+
+// <i> Must be power of 2 and multiple of 4.
+// <i> If NRF_LOG_DEFERRED = 0 then buffer size can be reduced to minimum.
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+// <2048=> 2048 
+// <4096=> 4096 
+// <8192=> 8192 
+// <16384=> 16384 
+
+#ifndef NRF_LOG_BUFSIZE
+#define NRF_LOG_BUFSIZE 1024
+#endif
+
+// <q> NRF_LOG_CLI_CMDS  - Enable CLI commands for the module.
+ 
+
+#ifndef NRF_LOG_CLI_CMDS
+#define NRF_LOG_CLI_CMDS 0
+#endif
+
+// <o> NRF_LOG_DEFAULT_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_LOG_DEFAULT_LEVEL
+#define NRF_LOG_DEFAULT_LEVEL 3
+#endif
+
+// <q> NRF_LOG_DEFERRED  - Enable deffered logger.
+ 
+
+// <i> Log data is buffered and can be processed in idle.
+
+#ifndef NRF_LOG_DEFERRED
+#define NRF_LOG_DEFERRED 1
+#endif
+
+// <q> NRF_LOG_FILTERS_ENABLED  - Enable dynamic filtering of logs.
+ 
+
+#ifndef NRF_LOG_FILTERS_ENABLED
+#define NRF_LOG_FILTERS_ENABLED 0
+#endif
+
+// <q> NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED  - Enable use of critical region for non deffered mode when flushing logs.
+ 
+
+// <i> When enabled NRF_LOG_FLUSH is called from critical section when non deffered mode is used.
+// <i> Log output will never be corrupted as access to the log backend is exclusive
+// <i> but system will spend significant amount of time in critical section
+
+#ifndef NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED
+#define NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED 0
+#endif
+
+// <o> NRF_LOG_STR_PUSH_BUFFER_SIZE  - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH.
+ 
+// <16=> 16 
+// <32=> 32 
+// <64=> 64 
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+
+#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE
+#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128
+#endif
+
+// <o> NRF_LOG_STR_PUSH_BUFFER_SIZE  - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH.
+ 
+// <16=> 16 
+// <32=> 32 
+// <64=> 64 
+// <128=> 128 
+// <256=> 256 
+// <512=> 512 
+// <1024=> 1024 
+
+#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE
+#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128
+#endif
+
+// <e> NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string
+//==========================================================
+#ifndef NRF_LOG_USES_COLORS
+#define NRF_LOG_USES_COLORS 0
+#endif
+// <o> NRF_LOG_COLOR_DEFAULT  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_COLOR_DEFAULT
+#define NRF_LOG_COLOR_DEFAULT 0
+#endif
+
+// <o> NRF_LOG_ERROR_COLOR  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_ERROR_COLOR
+#define NRF_LOG_ERROR_COLOR 2
+#endif
+
+// <o> NRF_LOG_WARNING_COLOR  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NRF_LOG_WARNING_COLOR
+#define NRF_LOG_WARNING_COLOR 4
+#endif
+
+// </e>
+
+// <e> NRF_LOG_USES_TIMESTAMP - Enable timestamping
+
+// <i> Function for getting the timestamp is provided by the user
+//==========================================================
+#ifndef NRF_LOG_USES_TIMESTAMP
+#define NRF_LOG_USES_TIMESTAMP 0
+#endif
+// <o> NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY - Default frequency of the timestamp (in Hz) or 0 to use app_timer frequency. 
+#ifndef NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY
+#define NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY 0
+#endif
+
+// </e>
+
+// <h> nrf_log module configuration 
+
+//==========================================================
+// <h> nrf_log in nRF_Core 
+
+//==========================================================
+// <e> NRF_MPU_LIB_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_MPU_LIB_CONFIG_LOG_ENABLED
+#define NRF_MPU_LIB_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_MPU_LIB_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_MPU_LIB_CONFIG_LOG_LEVEL
+#define NRF_MPU_LIB_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_MPU_LIB_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 NRF_MPU_LIB_CONFIG_INFO_COLOR
+#define NRF_MPU_LIB_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_MPU_LIB_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 NRF_MPU_LIB_CONFIG_DEBUG_COLOR
+#define NRF_MPU_LIB_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_STACK_GUARD_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_STACK_GUARD_CONFIG_LOG_ENABLED
+#define NRF_STACK_GUARD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_STACK_GUARD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_STACK_GUARD_CONFIG_LOG_LEVEL
+#define NRF_STACK_GUARD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_STACK_GUARD_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 NRF_STACK_GUARD_CONFIG_INFO_COLOR
+#define NRF_STACK_GUARD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_STACK_GUARD_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 NRF_STACK_GUARD_CONFIG_DEBUG_COLOR
+#define NRF_STACK_GUARD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TASK_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TASK_MANAGER_CONFIG_LOG_ENABLED
+#define TASK_MANAGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TASK_MANAGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TASK_MANAGER_CONFIG_LOG_LEVEL
+#define TASK_MANAGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> TASK_MANAGER_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 TASK_MANAGER_CONFIG_INFO_COLOR
+#define TASK_MANAGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> TASK_MANAGER_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 TASK_MANAGER_CONFIG_DEBUG_COLOR
+#define TASK_MANAGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Drivers 
+
+//==========================================================
+// <e> CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef CLOCK_CONFIG_LOG_ENABLED
+#define CLOCK_CONFIG_LOG_ENABLED 0
+#endif
+// <o> CLOCK_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef CLOCK_CONFIG_LOG_LEVEL
+#define CLOCK_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 CLOCK_CONFIG_INFO_COLOR
+#define CLOCK_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 CLOCK_CONFIG_DEBUG_COLOR
+#define CLOCK_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> COMP_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef COMP_CONFIG_LOG_ENABLED
+#define COMP_CONFIG_LOG_ENABLED 0
+#endif
+// <o> COMP_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef COMP_CONFIG_LOG_LEVEL
+#define COMP_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 COMP_CONFIG_INFO_COLOR
+#define COMP_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 COMP_CONFIG_DEBUG_COLOR
+#define COMP_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef GPIOTE_CONFIG_LOG_ENABLED
+#define GPIOTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> GPIOTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef GPIOTE_CONFIG_LOG_LEVEL
+#define GPIOTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 GPIOTE_CONFIG_INFO_COLOR
+#define GPIOTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 GPIOTE_CONFIG_DEBUG_COLOR
+#define GPIOTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef LPCOMP_CONFIG_LOG_ENABLED
+#define LPCOMP_CONFIG_LOG_ENABLED 0
+#endif
+// <o> LPCOMP_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef LPCOMP_CONFIG_LOG_LEVEL
+#define LPCOMP_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 LPCOMP_CONFIG_INFO_COLOR
+#define LPCOMP_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 LPCOMP_CONFIG_DEBUG_COLOR
+#define LPCOMP_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> MAX3421E_HOST_CONFIG_LOG_ENABLED - Enable logging in the module
+//==========================================================
+#ifndef MAX3421E_HOST_CONFIG_LOG_ENABLED
+#define MAX3421E_HOST_CONFIG_LOG_ENABLED 0
+#endif
+// <o> MAX3421E_HOST_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef MAX3421E_HOST_CONFIG_LOG_LEVEL
+#define MAX3421E_HOST_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> MAX3421E_HOST_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 MAX3421E_HOST_CONFIG_INFO_COLOR
+#define MAX3421E_HOST_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> MAX3421E_HOST_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 MAX3421E_HOST_CONFIG_DEBUG_COLOR
+#define MAX3421E_HOST_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <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> PDM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PDM_CONFIG_LOG_ENABLED
+#define PDM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PDM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PDM_CONFIG_LOG_LEVEL
+#define PDM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 PDM_CONFIG_INFO_COLOR
+#define PDM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 PDM_CONFIG_DEBUG_COLOR
+#define PDM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PPI_CONFIG_LOG_ENABLED
+#define PPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PPI_CONFIG_LOG_LEVEL
+#define PPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> PPI_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 PPI_CONFIG_INFO_COLOR
+#define PPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> PPI_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 PPI_CONFIG_DEBUG_COLOR
+#define PPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PWM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef PWM_CONFIG_LOG_ENABLED
+#define PWM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> PWM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PWM_CONFIG_LOG_LEVEL
+#define PWM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 PWM_CONFIG_INFO_COLOR
+#define PWM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 PWM_CONFIG_DEBUG_COLOR
+#define PWM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> QDEC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef QDEC_CONFIG_LOG_ENABLED
+#define QDEC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> QDEC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef QDEC_CONFIG_LOG_LEVEL
+#define QDEC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 QDEC_CONFIG_INFO_COLOR
+#define QDEC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 QDEC_CONFIG_DEBUG_COLOR
+#define QDEC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> RNG_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef RNG_CONFIG_LOG_ENABLED
+#define RNG_CONFIG_LOG_ENABLED 0
+#endif
+// <o> RNG_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef RNG_CONFIG_LOG_LEVEL
+#define RNG_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> RNG_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 RNG_CONFIG_INFO_COLOR
+#define RNG_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> RNG_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 RNG_CONFIG_DEBUG_COLOR
+#define RNG_CONFIG_DEBUG_COLOR 0
+#endif
+
+// <q> RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED  - Enables logging of random numbers.
+ 
+
+#ifndef RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED
+#define RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED 0
+#endif
+
+// </e>
+
+// <e> RTC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef RTC_CONFIG_LOG_ENABLED
+#define RTC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> RTC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef RTC_CONFIG_LOG_LEVEL
+#define RTC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 RTC_CONFIG_INFO_COLOR
+#define RTC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 RTC_CONFIG_DEBUG_COLOR
+#define RTC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SAADC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SAADC_CONFIG_LOG_ENABLED
+#define SAADC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SAADC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SAADC_CONFIG_LOG_LEVEL
+#define SAADC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 SAADC_CONFIG_INFO_COLOR
+#define SAADC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 SAADC_CONFIG_DEBUG_COLOR
+#define SAADC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SPIS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SPIS_CONFIG_LOG_ENABLED
+#define SPIS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SPIS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SPIS_CONFIG_LOG_LEVEL
+#define SPIS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 SPIS_CONFIG_INFO_COLOR
+#define SPIS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 SPIS_CONFIG_DEBUG_COLOR
+#define SPIS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> SPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SPI_CONFIG_LOG_ENABLED
+#define SPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SPI_CONFIG_LOG_LEVEL
+#define SPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> SPI_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 SPI_CONFIG_INFO_COLOR
+#define SPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> SPI_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 SPI_CONFIG_DEBUG_COLOR
+#define SPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TIMER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TIMER_CONFIG_LOG_ENABLED
+#define TIMER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TIMER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TIMER_CONFIG_LOG_LEVEL
+#define TIMER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 TIMER_CONFIG_INFO_COLOR
+#define TIMER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 TIMER_CONFIG_DEBUG_COLOR
+#define TIMER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TWIS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TWIS_CONFIG_LOG_ENABLED
+#define TWIS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TWIS_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TWIS_CONFIG_LOG_LEVEL
+#define TWIS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 TWIS_CONFIG_INFO_COLOR
+#define TWIS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 TWIS_CONFIG_DEBUG_COLOR
+#define TWIS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> TWI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef TWI_CONFIG_LOG_ENABLED
+#define TWI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> TWI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef TWI_CONFIG_LOG_LEVEL
+#define TWI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> TWI_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 TWI_CONFIG_INFO_COLOR
+#define TWI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> TWI_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 TWI_CONFIG_DEBUG_COLOR
+#define TWI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef UART_CONFIG_LOG_ENABLED
+#define UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef UART_CONFIG_LOG_LEVEL
+#define UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> UART_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 UART_CONFIG_INFO_COLOR
+#define UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> UART_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 UART_CONFIG_DEBUG_COLOR
+#define UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> USBD_CONFIG_LOG_ENABLED - Enable logging in the module
+//==========================================================
+#ifndef USBD_CONFIG_LOG_ENABLED
+#define USBD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> USBD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef USBD_CONFIG_LOG_LEVEL
+#define USBD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 USBD_CONFIG_INFO_COLOR
+#define USBD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 USBD_CONFIG_DEBUG_COLOR
+#define USBD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> WDT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef WDT_CONFIG_LOG_ENABLED
+#define WDT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> WDT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef WDT_CONFIG_LOG_LEVEL
+#define WDT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> 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 WDT_CONFIG_INFO_COLOR
+#define WDT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> 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 WDT_CONFIG_DEBUG_COLOR
+#define WDT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Libraries 
+
+//==========================================================
+// <e> APP_BUTTON_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_BUTTON_CONFIG_LOG_ENABLED
+#define APP_BUTTON_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_BUTTON_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_BUTTON_CONFIG_LOG_LEVEL
+#define APP_BUTTON_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL
+#define APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> APP_BUTTON_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 APP_BUTTON_CONFIG_INFO_COLOR
+#define APP_BUTTON_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_BUTTON_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 APP_BUTTON_CONFIG_DEBUG_COLOR
+#define APP_BUTTON_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_TIMER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_TIMER_CONFIG_LOG_ENABLED
+#define APP_TIMER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_TIMER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_TIMER_CONFIG_LOG_LEVEL
+#define APP_TIMER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_TIMER_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_TIMER_CONFIG_INITIAL_LOG_LEVEL
+#define APP_TIMER_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> APP_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 APP_TIMER_CONFIG_INFO_COLOR
+#define APP_TIMER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_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 APP_TIMER_CONFIG_DEBUG_COLOR
+#define APP_TIMER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL
+#define APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_CDC_ACM_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 APP_USBD_CDC_ACM_CONFIG_INFO_COLOR
+#define APP_USBD_CDC_ACM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_CDC_ACM_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 APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR
+#define APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module.
+//==========================================================
+#ifndef APP_USBD_CONFIG_LOG_ENABLED
+#define APP_USBD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_CONFIG_LOG_LEVEL
+#define APP_USBD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_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 APP_USBD_CONFIG_INFO_COLOR
+#define APP_USBD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_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 APP_USBD_CONFIG_DEBUG_COLOR
+#define APP_USBD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_DUMMY_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#define APP_USBD_DUMMY_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_DUMMY_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_DUMMY_CONFIG_LOG_LEVEL
+#define APP_USBD_DUMMY_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_DUMMY_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 APP_USBD_DUMMY_CONFIG_INFO_COLOR
+#define APP_USBD_DUMMY_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_DUMMY_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 APP_USBD_DUMMY_CONFIG_DEBUG_COLOR
+#define APP_USBD_DUMMY_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_MSC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_MSC_CONFIG_LOG_ENABLED
+#define APP_USBD_MSC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_MSC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_MSC_CONFIG_LOG_LEVEL
+#define APP_USBD_MSC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_MSC_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 APP_USBD_MSC_CONFIG_INFO_COLOR
+#define APP_USBD_MSC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_MSC_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 APP_USBD_MSC_CONFIG_DEBUG_COLOR
+#define APP_USBD_MSC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> APP_USBD_NRF_DFU_TRIGGER_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 APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> APP_USBD_NRF_DFU_TRIGGER_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 APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_ATFIFO_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_ATFIFO_CONFIG_LOG_ENABLED
+#define NRF_ATFIFO_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_ATFIFO_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_ATFIFO_CONFIG_LOG_LEVEL
+#define NRF_ATFIFO_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_ATFIFO_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 NRF_ATFIFO_CONFIG_INFO_COLOR
+#define NRF_ATFIFO_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_ATFIFO_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 NRF_ATFIFO_CONFIG_DEBUG_COLOR
+#define NRF_ATFIFO_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BALLOC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BALLOC_CONFIG_LOG_ENABLED
+#define NRF_BALLOC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BALLOC_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BALLOC_CONFIG_LOG_LEVEL
+#define NRF_BALLOC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL  - Initial severity level if dynamic filtering is enabled.
+ 
+
+// <i> If module generates a lot of logs, initial log level can
+// <i> be decreased to prevent flooding. Severity level can be
+// <i> increased on instance basis.
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL
+#define NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BALLOC_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 NRF_BALLOC_CONFIG_INFO_COLOR
+#define NRF_BALLOC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BALLOC_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 NRF_BALLOC_CONFIG_DEBUG_COLOR
+#define NRF_BALLOC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_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 NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_EMPTY_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 NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_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 NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_QSPI_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 NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_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 NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR
+#define NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_BLOCK_DEV_RAM_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 NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR
+#define NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#define NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL
+#define NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_BLE_UART_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 NRF_CLI_BLE_UART_CONFIG_INFO_COLOR
+#define NRF_CLI_BLE_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_BLE_UART_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 NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR
+#define NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_LIBUARTE_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 NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_LIBUARTE_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 NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR
+#define NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_CLI_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_CLI_UART_CONFIG_LOG_ENABLED
+#define NRF_CLI_UART_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_CLI_UART_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_CLI_UART_CONFIG_LOG_LEVEL
+#define NRF_CLI_UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_CLI_UART_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 NRF_CLI_UART_CONFIG_INFO_COLOR
+#define NRF_CLI_UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_CLI_UART_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 NRF_CLI_UART_CONFIG_DEBUG_COLOR
+#define NRF_CLI_UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LIBUARTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_LIBUARTE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LIBUARTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_LIBUARTE_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 NRF_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LIBUARTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_LIBUARTE_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 NRF_LIBUARTE_CONFIG_DEBUG_COLOR
+#define NRF_LIBUARTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_MEMOBJ_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_MEMOBJ_CONFIG_LOG_ENABLED
+#define NRF_MEMOBJ_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_MEMOBJ_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_MEMOBJ_CONFIG_LOG_LEVEL
+#define NRF_MEMOBJ_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_MEMOBJ_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 NRF_MEMOBJ_CONFIG_INFO_COLOR
+#define NRF_MEMOBJ_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_MEMOBJ_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 NRF_MEMOBJ_CONFIG_DEBUG_COLOR
+#define NRF_MEMOBJ_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_PWR_MGMT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_PWR_MGMT_CONFIG_LOG_ENABLED
+#define NRF_PWR_MGMT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_PWR_MGMT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_PWR_MGMT_CONFIG_LOG_LEVEL
+#define NRF_PWR_MGMT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_PWR_MGMT_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 NRF_PWR_MGMT_CONFIG_INFO_COLOR
+#define NRF_PWR_MGMT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_PWR_MGMT_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 NRF_PWR_MGMT_CONFIG_DEBUG_COLOR
+#define NRF_PWR_MGMT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_QUEUE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_QUEUE_CONFIG_LOG_ENABLED
+#define NRF_QUEUE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_QUEUE_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_QUEUE_CONFIG_LOG_LEVEL
+#define NRF_QUEUE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL
+#define NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL 3
+#endif
+
+// <o> NRF_QUEUE_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 NRF_QUEUE_CONFIG_INFO_COLOR
+#define NRF_QUEUE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_QUEUE_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 NRF_QUEUE_CONFIG_DEBUG_COLOR
+#define NRF_QUEUE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_ANT_LOG_ENABLED - Enable logging in SoftDevice handler (ANT) module.
+//==========================================================
+#ifndef NRF_SDH_ANT_LOG_ENABLED
+#define NRF_SDH_ANT_LOG_ENABLED 0
+#endif
+// <o> NRF_SDH_ANT_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_ANT_LOG_LEVEL
+#define NRF_SDH_ANT_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_ANT_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 NRF_SDH_ANT_INFO_COLOR
+#define NRF_SDH_ANT_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_ANT_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 NRF_SDH_ANT_DEBUG_COLOR
+#define NRF_SDH_ANT_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_BLE_LOG_ENABLED - Enable logging in SoftDevice handler (BLE) module.
+//==========================================================
+#ifndef NRF_SDH_BLE_LOG_ENABLED
+#define NRF_SDH_BLE_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_BLE_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_BLE_LOG_LEVEL
+#define NRF_SDH_BLE_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_BLE_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 NRF_SDH_BLE_INFO_COLOR
+#define NRF_SDH_BLE_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_BLE_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 NRF_SDH_BLE_DEBUG_COLOR
+#define NRF_SDH_BLE_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_LOG_ENABLED - Enable logging in SoftDevice handler module.
+//==========================================================
+#ifndef NRF_SDH_LOG_ENABLED
+#define NRF_SDH_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_LOG_LEVEL
+#define NRF_SDH_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_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 NRF_SDH_INFO_COLOR
+#define NRF_SDH_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_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 NRF_SDH_DEBUG_COLOR
+#define NRF_SDH_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SDH_SOC_LOG_ENABLED - Enable logging in SoftDevice handler (SoC) module.
+//==========================================================
+#ifndef NRF_SDH_SOC_LOG_ENABLED
+#define NRF_SDH_SOC_LOG_ENABLED 1
+#endif
+// <o> NRF_SDH_SOC_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SDH_SOC_LOG_LEVEL
+#define NRF_SDH_SOC_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SDH_SOC_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 NRF_SDH_SOC_INFO_COLOR
+#define NRF_SDH_SOC_INFO_COLOR 0
+#endif
+
+// <o> NRF_SDH_SOC_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 NRF_SDH_SOC_DEBUG_COLOR
+#define NRF_SDH_SOC_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_SORTLIST_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_SORTLIST_CONFIG_LOG_ENABLED
+#define NRF_SORTLIST_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_SORTLIST_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_SORTLIST_CONFIG_LOG_LEVEL
+#define NRF_SORTLIST_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_SORTLIST_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 NRF_SORTLIST_CONFIG_INFO_COLOR
+#define NRF_SORTLIST_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_SORTLIST_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 NRF_SORTLIST_CONFIG_DEBUG_COLOR
+#define NRF_SORTLIST_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> NRF_TWI_SENSOR_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRF_TWI_SENSOR_CONFIG_LOG_ENABLED
+#define NRF_TWI_SENSOR_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRF_TWI_SENSOR_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NRF_TWI_SENSOR_CONFIG_LOG_LEVEL
+#define NRF_TWI_SENSOR_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRF_TWI_SENSOR_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 NRF_TWI_SENSOR_CONFIG_INFO_COLOR
+#define NRF_TWI_SENSOR_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRF_TWI_SENSOR_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 NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR
+#define NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <e> PM_LOG_ENABLED - Enable logging in Peer Manager and its submodules.
+//==========================================================
+#ifndef PM_LOG_ENABLED
+#define PM_LOG_ENABLED 1
+#endif
+// <o> PM_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef PM_LOG_LEVEL
+#define PM_LOG_LEVEL 3
+#endif
+
+// <o> PM_LOG_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 PM_LOG_INFO_COLOR
+#define PM_LOG_INFO_COLOR 0
+#endif
+
+// <o> PM_LOG_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 PM_LOG_DEBUG_COLOR
+#define PM_LOG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nrf_log in nRF_Serialization 
+
+//==========================================================
+// <e> SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
+#define SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL
+#define SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> SER_HAL_TRANSPORT_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 SER_HAL_TRANSPORT_CONFIG_INFO_COLOR
+#define SER_HAL_TRANSPORT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> SER_HAL_TRANSPORT_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 SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR
+#define SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED  - nrf_log_str_formatter - Log string formatter
+ 
+
+#ifndef NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED
+#define NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED 1
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> nRF_NFC 
+
+//==========================================================
+// <q> NFC_AC_REC_ENABLED  - nfc_ac_rec - NFC NDEF Alternative Carrier record encoder
+ 
+
+#ifndef NFC_AC_REC_ENABLED
+#define NFC_AC_REC_ENABLED 0
+#endif
+
+// <q> NFC_AC_REC_PARSER_ENABLED  - nfc_ac_rec_parser - Alternative Carrier record parser
+ 
+
+#ifndef NFC_AC_REC_PARSER_ENABLED
+#define NFC_AC_REC_PARSER_ENABLED 0
+#endif
+
+// <e> NFC_BLE_OOB_ADVDATA_ENABLED - nfc_ble_oob_advdata - AD data for OOB pairing encoder
+//==========================================================
+#ifndef NFC_BLE_OOB_ADVDATA_ENABLED
+#define NFC_BLE_OOB_ADVDATA_ENABLED 0
+#endif
+// <o> ADVANCED_ADVDATA_SUPPORT  - Non-mandatory AD types for BLE OOB pairing are encoded inside the NDEF message (e.g. service UUIDs)
+ 
+// <1=> Enabled 
+// <0=> Disabled 
+
+#ifndef ADVANCED_ADVDATA_SUPPORT
+#define ADVANCED_ADVDATA_SUPPORT 0
+#endif
+
+// </e>
+
+// <q> NFC_BLE_OOB_ADVDATA_PARSER_ENABLED  - nfc_ble_oob_advdata_parser - BLE OOB pairing AD data parser
+ 
+
+#ifndef NFC_BLE_OOB_ADVDATA_PARSER_ENABLED
+#define NFC_BLE_OOB_ADVDATA_PARSER_ENABLED 0
+#endif
+
+// <e> NFC_BLE_PAIR_LIB_ENABLED - nfc_ble_pair_lib - Library parameters
+//==========================================================
+#ifndef NFC_BLE_PAIR_LIB_ENABLED
+#define NFC_BLE_PAIR_LIB_ENABLED 0
+#endif
+// <e> NFC_BLE_PAIR_LIB_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_BLE_PAIR_LIB_LOG_ENABLED
+#define NFC_BLE_PAIR_LIB_LOG_ENABLED 0
+#endif
+// <o> NFC_BLE_PAIR_LIB_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_BLE_PAIR_LIB_LOG_LEVEL
+#define NFC_BLE_PAIR_LIB_LOG_LEVEL 3
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_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 NFC_BLE_PAIR_LIB_INFO_COLOR
+#define NFC_BLE_PAIR_LIB_INFO_COLOR 0
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_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 NFC_BLE_PAIR_LIB_DEBUG_COLOR
+#define NFC_BLE_PAIR_LIB_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// <h> NFC_BLE_PAIR_LIB_SECURITY_PARAMETERS - Common Peer Manager security parameters.
+
+//==========================================================
+// <e> BLE_NFC_SEC_PARAM_BOND - Enables device bonding.
+
+// <i> If bonding is enabled at least one of the BLE_NFC_SEC_PARAM_KDIST options must be enabled.
+//==========================================================
+#ifndef BLE_NFC_SEC_PARAM_BOND
+#define BLE_NFC_SEC_PARAM_BOND 1
+#endif
+// <q> BLE_NFC_SEC_PARAM_KDIST_OWN_ENC  - Enables Long Term Key and Master Identification distribution by device.
+ 
+
+#ifndef BLE_NFC_SEC_PARAM_KDIST_OWN_ENC
+#define BLE_NFC_SEC_PARAM_KDIST_OWN_ENC 1
+#endif
+
+// <q> BLE_NFC_SEC_PARAM_KDIST_OWN_ID  - Enables Identity Resolving Key and Identity Address Information distribution by device.
+ 
+
+#ifndef BLE_NFC_SEC_PARAM_KDIST_OWN_ID
+#define BLE_NFC_SEC_PARAM_KDIST_OWN_ID 1
+#endif
+
+// <q> BLE_NFC_SEC_PARAM_KDIST_PEER_ENC  - Enables Long Term Key and Master Identification distribution by peer.
+ 
+
+#ifndef BLE_NFC_SEC_PARAM_KDIST_PEER_ENC
+#define BLE_NFC_SEC_PARAM_KDIST_PEER_ENC 1
+#endif
+
+// <q> BLE_NFC_SEC_PARAM_KDIST_PEER_ID  - Enables Identity Resolving Key and Identity Address Information distribution by peer.
+ 
+
+#ifndef BLE_NFC_SEC_PARAM_KDIST_PEER_ID
+#define BLE_NFC_SEC_PARAM_KDIST_PEER_ID 1
+#endif
+
+// </e>
+
+// <o> BLE_NFC_SEC_PARAM_MIN_KEY_SIZE  - Minimal size of a security key.
+ 
+// <7=> 7 
+// <8=> 8 
+// <9=> 9 
+// <10=> 10 
+// <11=> 11 
+// <12=> 12 
+// <13=> 13 
+// <14=> 14 
+// <15=> 15 
+// <16=> 16 
+
+#ifndef BLE_NFC_SEC_PARAM_MIN_KEY_SIZE
+#define BLE_NFC_SEC_PARAM_MIN_KEY_SIZE 7
+#endif
+
+// <o> BLE_NFC_SEC_PARAM_MAX_KEY_SIZE  - Maximal size of a security key.
+ 
+// <7=> 7 
+// <8=> 8 
+// <9=> 9 
+// <10=> 10 
+// <11=> 11 
+// <12=> 12 
+// <13=> 13 
+// <14=> 14 
+// <15=> 15 
+// <16=> 16 
+
+#ifndef BLE_NFC_SEC_PARAM_MAX_KEY_SIZE
+#define BLE_NFC_SEC_PARAM_MAX_KEY_SIZE 16
+#endif
+
+// </h> 
+//==========================================================
+
+// </e>
+
+// <q> NFC_BLE_PAIR_MSG_ENABLED  - nfc_ble_pair_msg - NDEF message for OOB pairing encoder
+ 
+
+#ifndef NFC_BLE_PAIR_MSG_ENABLED
+#define NFC_BLE_PAIR_MSG_ENABLED 0
+#endif
+
+// <q> NFC_CH_COMMON_ENABLED  - nfc_ble_pair_common - OOB pairing common data
+ 
+
+#ifndef NFC_CH_COMMON_ENABLED
+#define NFC_CH_COMMON_ENABLED 0
+#endif
+
+// <q> NFC_EP_OOB_REC_ENABLED  - nfc_ep_oob_rec - EP record for BLE pairing encoder
+ 
+
+#ifndef NFC_EP_OOB_REC_ENABLED
+#define NFC_EP_OOB_REC_ENABLED 0
+#endif
+
+// <q> NFC_HS_REC_ENABLED  - nfc_hs_rec - Handover Select NDEF record encoder
+ 
+
+#ifndef NFC_HS_REC_ENABLED
+#define NFC_HS_REC_ENABLED 0
+#endif
+
+// <q> NFC_LE_OOB_REC_ENABLED  - nfc_le_oob_rec - LE record for BLE pairing encoder
+ 
+
+#ifndef NFC_LE_OOB_REC_ENABLED
+#define NFC_LE_OOB_REC_ENABLED 0
+#endif
+
+// <q> NFC_LE_OOB_REC_PARSER_ENABLED  - nfc_le_oob_rec_parser - LE record parser
+ 
+
+#ifndef NFC_LE_OOB_REC_PARSER_ENABLED
+#define NFC_LE_OOB_REC_PARSER_ENABLED 0
+#endif
+
+// <q> NFC_NDEF_LAUNCHAPP_MSG_ENABLED  - nfc_launchapp_msg - Encoding data for NDEF Application Launching message for NFC Tag
+ 
+
+#ifndef NFC_NDEF_LAUNCHAPP_MSG_ENABLED
+#define NFC_NDEF_LAUNCHAPP_MSG_ENABLED 0
+#endif
+
+// <q> NFC_NDEF_LAUNCHAPP_REC_ENABLED  - nfc_launchapp_rec - Encoding data for NDEF Application Launching record for NFC Tag
+ 
+
+#ifndef NFC_NDEF_LAUNCHAPP_REC_ENABLED
+#define NFC_NDEF_LAUNCHAPP_REC_ENABLED 0
+#endif
+
+// <e> NFC_NDEF_MSG_ENABLED - nfc_ndef_msg - NFC NDEF Message generator module
+//==========================================================
+#ifndef NFC_NDEF_MSG_ENABLED
+#define NFC_NDEF_MSG_ENABLED 0
+#endif
+// <o> NFC_NDEF_MSG_TAG_TYPE  - NFC Tag Type
+ 
+// <2=> Type 2 Tag 
+// <4=> Type 4 Tag 
+
+#ifndef NFC_NDEF_MSG_TAG_TYPE
+#define NFC_NDEF_MSG_TAG_TYPE 2
+#endif
+
+// </e>
+
+// <e> NFC_NDEF_MSG_PARSER_ENABLED - nfc_ndef_msg_parser - NFC NDEF message parser module
+//==========================================================
+#ifndef NFC_NDEF_MSG_PARSER_ENABLED
+#define NFC_NDEF_MSG_PARSER_ENABLED 0
+#endif
+// <e> NFC_NDEF_MSG_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_NDEF_MSG_PARSER_LOG_ENABLED
+#define NFC_NDEF_MSG_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_NDEF_MSG_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_NDEF_MSG_PARSER_LOG_LEVEL
+#define NFC_NDEF_MSG_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_NDEF_MSG_PARSER_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 NFC_NDEF_MSG_PARSER_INFO_COLOR
+#define NFC_NDEF_MSG_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> NFC_NDEF_RECORD_ENABLED  - nfc_ndef_record - NFC NDEF Record generator module
+ 
+
+#ifndef NFC_NDEF_RECORD_ENABLED
+#define NFC_NDEF_RECORD_ENABLED 0
+#endif
+
+// <e> NFC_NDEF_RECORD_PARSER_ENABLED - nfc_ndef_record_parser - NFC NDEF Record parser module
+//==========================================================
+#ifndef NFC_NDEF_RECORD_PARSER_ENABLED
+#define NFC_NDEF_RECORD_PARSER_ENABLED 0
+#endif
+// <e> NFC_NDEF_RECORD_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_NDEF_RECORD_PARSER_LOG_ENABLED
+#define NFC_NDEF_RECORD_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_NDEF_RECORD_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_NDEF_RECORD_PARSER_LOG_LEVEL
+#define NFC_NDEF_RECORD_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_NDEF_RECORD_PARSER_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 NFC_NDEF_RECORD_PARSER_INFO_COLOR
+#define NFC_NDEF_RECORD_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> NFC_NDEF_TEXT_RECORD_ENABLED  - nfc_text_rec - Encoding data for a text record for NFC Tag
+ 
+
+#ifndef NFC_NDEF_TEXT_RECORD_ENABLED
+#define NFC_NDEF_TEXT_RECORD_ENABLED 0
+#endif
+
+// <q> NFC_NDEF_URI_MSG_ENABLED  - nfc_uri_msg - Encoding data for NDEF message with URI record for NFC Tag
+ 
+
+#ifndef NFC_NDEF_URI_MSG_ENABLED
+#define NFC_NDEF_URI_MSG_ENABLED 0
+#endif
+
+// <q> NFC_NDEF_URI_REC_ENABLED  - nfc_uri_rec - Encoding data for a URI record for NFC Tag
+ 
+
+#ifndef NFC_NDEF_URI_REC_ENABLED
+#define NFC_NDEF_URI_REC_ENABLED 0
+#endif
+
+// <e> NFC_PLATFORM_ENABLED - nfc_platform - NFC platform module for Clock control.
+//==========================================================
+#ifndef NFC_PLATFORM_ENABLED
+#define NFC_PLATFORM_ENABLED 0
+#endif
+// <e> NFC_PLATFORM_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_PLATFORM_LOG_ENABLED
+#define NFC_PLATFORM_LOG_ENABLED 0
+#endif
+// <o> NFC_PLATFORM_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_PLATFORM_LOG_LEVEL
+#define NFC_PLATFORM_LOG_LEVEL 3
+#endif
+
+// <o> NFC_PLATFORM_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 NFC_PLATFORM_INFO_COLOR
+#define NFC_PLATFORM_INFO_COLOR 0
+#endif
+
+// <o> NFC_PLATFORM_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 NFC_PLATFORM_DEBUG_COLOR
+#define NFC_PLATFORM_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NFC_T2T_PARSER_ENABLED - nfc_type_2_tag_parser - Parser for decoding Type 2 Tag data
+//==========================================================
+#ifndef NFC_T2T_PARSER_ENABLED
+#define NFC_T2T_PARSER_ENABLED 0
+#endif
+// <e> NFC_T2T_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T2T_PARSER_LOG_ENABLED
+#define NFC_T2T_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_T2T_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T2T_PARSER_LOG_LEVEL
+#define NFC_T2T_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T2T_PARSER_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 NFC_T2T_PARSER_INFO_COLOR
+#define NFC_T2T_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NFC_T4T_APDU_ENABLED - nfc_t4t_apdu - APDU encoder/decoder for Type 4 Tag
+//==========================================================
+#ifndef NFC_T4T_APDU_ENABLED
+#define NFC_T4T_APDU_ENABLED 0
+#endif
+// <e> NFC_T4T_APDU_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T4T_APDU_LOG_ENABLED
+#define NFC_T4T_APDU_LOG_ENABLED 0
+#endif
+// <o> NFC_T4T_APDU_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T4T_APDU_LOG_LEVEL
+#define NFC_T4T_APDU_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T4T_APDU_LOG_COLOR  - ANSI escape code prefix.
+ 
+// <0=> Default 
+// <1=> Black 
+// <2=> Red 
+// <3=> Green 
+// <4=> Yellow 
+// <5=> Blue 
+// <6=> Magenta 
+// <7=> Cyan 
+// <8=> White 
+
+#ifndef NFC_T4T_APDU_LOG_COLOR
+#define NFC_T4T_APDU_LOG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NFC_T4T_CC_FILE_PARSER_ENABLED - nfc_t4t_cc_file - Capability Container file for Type 4 Tag
+//==========================================================
+#ifndef NFC_T4T_CC_FILE_PARSER_ENABLED
+#define NFC_T4T_CC_FILE_PARSER_ENABLED 0
+#endif
+// <e> NFC_T4T_CC_FILE_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T4T_CC_FILE_PARSER_LOG_ENABLED
+#define NFC_T4T_CC_FILE_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_T4T_CC_FILE_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T4T_CC_FILE_PARSER_LOG_LEVEL
+#define NFC_T4T_CC_FILE_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T4T_CC_FILE_PARSER_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 NFC_T4T_CC_FILE_PARSER_INFO_COLOR
+#define NFC_T4T_CC_FILE_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED - nfc_t4t_hl_detection_procedures - NDEF Detection Procedure for Type 4 Tag
+//==========================================================
+#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED
+#define NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED 0
+#endif
+// <e> NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED
+#define NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED 0
+#endif
+// <o> NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL
+#define NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T4T_HL_DETECTION_PROCEDURES_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 NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR
+#define NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR 0
+#endif
+
+// </e>
+
+// <o> APDU_BUFF_SIZE - Size (in bytes) of the buffer for APDU storage 
+#ifndef APDU_BUFF_SIZE
+#define APDU_BUFF_SIZE 250
+#endif
+
+// <o> CC_STORAGE_BUFF_SIZE - Size (in bytes) of the buffer for CC file storage 
+#ifndef CC_STORAGE_BUFF_SIZE
+#define CC_STORAGE_BUFF_SIZE 64
+#endif
+
+// </e>
+
+// <e> NFC_T4T_TLV_BLOCK_PARSER_ENABLED - nfc_t4t_tlv_block - TLV block for Type 4 Tag
+//==========================================================
+#ifndef NFC_T4T_TLV_BLOCK_PARSER_ENABLED
+#define NFC_T4T_TLV_BLOCK_PARSER_ENABLED 0
+#endif
+// <e> NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED
+#define NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED 0
+#endif
+// <o> NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL  - Default Severity level
+ 
+// <0=> Off 
+// <1=> Error 
+// <2=> Warning 
+// <3=> Info 
+// <4=> Debug 
+
+#ifndef NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL
+#define NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL 3
+#endif
+
+// <o> NFC_T4T_TLV_BLOCK_PARSER_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 NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR
+#define NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <h> nRF_SoftDevice 
+
+//==========================================================
+// <e> NRF_SDH_BLE_ENABLED - nrf_sdh_ble - SoftDevice BLE event handler
+//==========================================================
+#ifndef NRF_SDH_BLE_ENABLED
+#define NRF_SDH_BLE_ENABLED 0
+#endif
+// <h> BLE Stack configuration - Stack configuration parameters
+
+// <i> The SoftDevice handler will configure the stack with these parameters when calling @ref nrf_sdh_ble_default_cfg_set.
+// <i> Other libraries might depend on these values; keep them up-to-date even if you are not explicitely calling @ref nrf_sdh_ble_default_cfg_set.
+//==========================================================
+// <o> NRF_SDH_BLE_GAP_DATA_LENGTH   <27-251> 
+
+
+// <i> Requested BLE GAP data length to be negotiated.
+
+#ifndef NRF_SDH_BLE_GAP_DATA_LENGTH
+#define NRF_SDH_BLE_GAP_DATA_LENGTH 27
+#endif
+
+// <o> NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - Maximum number of peripheral links. 
+#ifndef NRF_SDH_BLE_PERIPHERAL_LINK_COUNT
+#define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 0
+#endif
+
+// <o> NRF_SDH_BLE_CENTRAL_LINK_COUNT - Maximum number of central links. 
+#ifndef NRF_SDH_BLE_CENTRAL_LINK_COUNT
+#define NRF_SDH_BLE_CENTRAL_LINK_COUNT 0
+#endif
+
+// <o> NRF_SDH_BLE_TOTAL_LINK_COUNT - Total link count. 
+// <i> Maximum number of total concurrent connections using the default configuration.
+
+#ifndef NRF_SDH_BLE_TOTAL_LINK_COUNT
+#define NRF_SDH_BLE_TOTAL_LINK_COUNT 1
+#endif
+
+// <o> NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length. 
+// <i> The time set aside for this connection on every connection interval in 1.25 ms units.
+
+#ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH
+#define NRF_SDH_BLE_GAP_EVENT_LENGTH 6
+#endif
+
+// <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
+#ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
+#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 23
+#endif
+
+// <o> NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE - Attribute Table size in bytes. The size must be a multiple of 4. 
+#ifndef NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE
+#define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1408
+#endif
+
+// <o> NRF_SDH_BLE_VS_UUID_COUNT - The number of vendor-specific UUIDs. 
+#ifndef NRF_SDH_BLE_VS_UUID_COUNT
+#define NRF_SDH_BLE_VS_UUID_COUNT 0
+#endif
+
+// <q> NRF_SDH_BLE_SERVICE_CHANGED  - Include the Service Changed characteristic in the Attribute Table.
+ 
+
+#ifndef NRF_SDH_BLE_SERVICE_CHANGED
+#define NRF_SDH_BLE_SERVICE_CHANGED 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> BLE Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_BLE_OBSERVER_PRIO_LEVELS - Total number of priority levels for BLE observers. 
+// <i> This setting configures the number of priority levels available for BLE event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_BLE_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_BLE_OBSERVER_PRIO_LEVELS 4
+#endif
+
+// <h> BLE Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> BLE_ADV_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Advertising module.
+
+#ifndef BLE_ADV_BLE_OBSERVER_PRIO
+#define BLE_ADV_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_ANCS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Apple Notification Service Client.
+
+#ifndef BLE_ANCS_C_BLE_OBSERVER_PRIO
+#define BLE_ANCS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_ANS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Alert Notification Service Client.
+
+#ifndef BLE_ANS_C_BLE_OBSERVER_PRIO
+#define BLE_ANS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BAS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Battery Service.
+
+#ifndef BLE_BAS_BLE_OBSERVER_PRIO
+#define BLE_BAS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BAS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Battery Service Client.
+
+#ifndef BLE_BAS_C_BLE_OBSERVER_PRIO
+#define BLE_BAS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_BPS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Blood Pressure Service.
+
+#ifndef BLE_BPS_BLE_OBSERVER_PRIO
+#define BLE_BPS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_CONN_PARAMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Connection parameters module.
+
+#ifndef BLE_CONN_PARAMS_BLE_OBSERVER_PRIO
+#define BLE_CONN_PARAMS_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_CONN_STATE_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Connection State module.
+
+#ifndef BLE_CONN_STATE_BLE_OBSERVER_PRIO
+#define BLE_CONN_STATE_BLE_OBSERVER_PRIO 0
+#endif
+
+// <o> BLE_CSCS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Cycling Speed and Cadence Service.
+
+#ifndef BLE_CSCS_BLE_OBSERVER_PRIO
+#define BLE_CSCS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_CTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Current Time Service Client.
+
+#ifndef BLE_CTS_C_BLE_OBSERVER_PRIO
+#define BLE_CTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_DB_DISC_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Database Discovery module.
+
+#ifndef BLE_DB_DISC_BLE_OBSERVER_PRIO
+#define BLE_DB_DISC_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> BLE_DFU_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the DFU Service.
+
+#ifndef BLE_DFU_BLE_OBSERVER_PRIO
+#define BLE_DFU_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_DIS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Device Information Client.
+
+#ifndef BLE_DIS_C_BLE_OBSERVER_PRIO
+#define BLE_DIS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_GLS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Glucose Service.
+
+#ifndef BLE_GLS_BLE_OBSERVER_PRIO
+#define BLE_GLS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HIDS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Human Interface Device Service.
+
+#ifndef BLE_HIDS_BLE_OBSERVER_PRIO
+#define BLE_HIDS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HRS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Heart Rate Service.
+
+#ifndef BLE_HRS_BLE_OBSERVER_PRIO
+#define BLE_HRS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HRS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Heart Rate Service Client.
+
+#ifndef BLE_HRS_C_BLE_OBSERVER_PRIO
+#define BLE_HRS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_HTS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Health Thermometer Service.
+
+#ifndef BLE_HTS_BLE_OBSERVER_PRIO
+#define BLE_HTS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_IAS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Immediate Alert Service.
+
+#ifndef BLE_IAS_BLE_OBSERVER_PRIO
+#define BLE_IAS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_IAS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Immediate Alert Service Client.
+
+#ifndef BLE_IAS_C_BLE_OBSERVER_PRIO
+#define BLE_IAS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LBS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the LED Button Service.
+
+#ifndef BLE_LBS_BLE_OBSERVER_PRIO
+#define BLE_LBS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LBS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the LED Button Service Client.
+
+#ifndef BLE_LBS_C_BLE_OBSERVER_PRIO
+#define BLE_LBS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LLS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Link Loss Service.
+
+#ifndef BLE_LLS_BLE_OBSERVER_PRIO
+#define BLE_LLS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_LNS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Location Navigation Service.
+
+#ifndef BLE_LNS_BLE_OBSERVER_PRIO
+#define BLE_LNS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_NUS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the UART Service.
+
+#ifndef BLE_NUS_BLE_OBSERVER_PRIO
+#define BLE_NUS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_NUS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the UART Central Service.
+
+#ifndef BLE_NUS_C_BLE_OBSERVER_PRIO
+#define BLE_NUS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_OTS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Object transfer service.
+
+#ifndef BLE_OTS_BLE_OBSERVER_PRIO
+#define BLE_OTS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_OTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Object transfer service client.
+
+#ifndef BLE_OTS_C_BLE_OBSERVER_PRIO
+#define BLE_OTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_RSCS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Running Speed and Cadence Service.
+
+#ifndef BLE_RSCS_BLE_OBSERVER_PRIO
+#define BLE_RSCS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_RSCS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Running Speed and Cadence Client.
+
+#ifndef BLE_RSCS_C_BLE_OBSERVER_PRIO
+#define BLE_RSCS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BLE_TPS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the TX Power Service.
+
+#ifndef BLE_TPS_BLE_OBSERVER_PRIO
+#define BLE_TPS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> BSP_BTN_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Button Control module.
+
+#ifndef BSP_BTN_BLE_OBSERVER_PRIO
+#define BSP_BTN_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the NFC pairing library.
+
+#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO
+#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_BMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Bond Management Service.
+
+#ifndef NRF_BLE_BMS_BLE_OBSERVER_PRIO
+#define NRF_BLE_BMS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_CGMS_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Contiuon Glucose Monitoring Service.
+
+#ifndef NRF_BLE_CGMS_BLE_OBSERVER_PRIO
+#define NRF_BLE_CGMS_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_ES_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Eddystone module.
+
+#ifndef NRF_BLE_ES_BLE_OBSERVER_PRIO
+#define NRF_BLE_ES_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT Service Client.
+
+#ifndef NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO
+#define NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_GATT_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT module.
+
+#ifndef NRF_BLE_GATT_BLE_OBSERVER_PRIO
+#define NRF_BLE_GATT_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_GQ_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the GATT Queue module.
+
+#ifndef NRF_BLE_GQ_BLE_OBSERVER_PRIO
+#define NRF_BLE_GQ_BLE_OBSERVER_PRIO 1
+#endif
+
+// <o> NRF_BLE_QWR_BLE_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the Queued writes module.
+
+#ifndef NRF_BLE_QWR_BLE_OBSERVER_PRIO
+#define NRF_BLE_QWR_BLE_OBSERVER_PRIO 2
+#endif
+
+// <o> NRF_BLE_SCAN_OBSERVER_PRIO  
+// <i> Priority for dispatching the BLE events to the Scanning Module.
+
+#ifndef NRF_BLE_SCAN_OBSERVER_PRIO
+#define NRF_BLE_SCAN_OBSERVER_PRIO 1
+#endif
+
+// <o> PM_BLE_OBSERVER_PRIO - Priority with which BLE events are dispatched to the Peer Manager module. 
+#ifndef PM_BLE_OBSERVER_PRIO
+#define PM_BLE_OBSERVER_PRIO 1
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// <e> NRF_SDH_ENABLED - nrf_sdh - SoftDevice handler
+//==========================================================
+#ifndef NRF_SDH_ENABLED
+#define NRF_SDH_ENABLED 0
+#endif
+// <h> Dispatch model 
+
+// <i> This setting configures how Stack events are dispatched to the application.
+//==========================================================
+// <o> NRF_SDH_DISPATCH_MODEL
+ 
+
+// <i> NRF_SDH_DISPATCH_MODEL_INTERRUPT: SoftDevice events are passed to the application from the interrupt context.
+// <i> NRF_SDH_DISPATCH_MODEL_APPSH: SoftDevice events are scheduled using @ref app_scheduler.
+// <i> NRF_SDH_DISPATCH_MODEL_POLLING: SoftDevice events are to be fetched manually.
+// <0=> NRF_SDH_DISPATCH_MODEL_INTERRUPT 
+// <1=> NRF_SDH_DISPATCH_MODEL_APPSH 
+// <2=> NRF_SDH_DISPATCH_MODEL_POLLING 
+
+#ifndef NRF_SDH_DISPATCH_MODEL
+#define NRF_SDH_DISPATCH_MODEL 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Clock - SoftDevice clock configuration
+
+//==========================================================
+// <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
+ 
+// <0=> NRF_CLOCK_LF_SRC_RC 
+// <1=> NRF_CLOCK_LF_SRC_XTAL 
+// <2=> NRF_CLOCK_LF_SRC_SYNTH 
+
+#ifndef NRF_SDH_CLOCK_LF_SRC
+#define NRF_SDH_CLOCK_LF_SRC 1
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
+#ifndef NRF_SDH_CLOCK_LF_RC_CTIV
+#define NRF_SDH_CLOCK_LF_RC_CTIV 0
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
+// <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
+// <i>  if the temperature has not changed.
+
+#ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
+#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
+#endif
+
+// <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
+ 
+// <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
+// <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
+// <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
+// <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
+// <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
+// <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
+// <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
+// <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
+// <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
+// <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
+// <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
+// <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
+
+#ifndef NRF_SDH_CLOCK_LF_ACCURACY
+#define NRF_SDH_CLOCK_LF_ACCURACY 7
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> SDH Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_REQ_OBSERVER_PRIO_LEVELS - Total number of priority levels for request observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice request event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_REQ_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_REQ_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <o> NRF_SDH_STATE_OBSERVER_PRIO_LEVELS - Total number of priority levels for state observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice state event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_STATE_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_STATE_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <o> NRF_SDH_STACK_OBSERVER_PRIO_LEVELS - Total number of priority levels for stack event observers. 
+// <i> This setting configures the number of priority levels available for the SoftDevice stack event handlers (ANT, BLE, SoC).
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_STACK_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_STACK_OBSERVER_PRIO_LEVELS 2
+#endif
+
+
+// <h> State Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> CLOCK_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to the Clock driver.
+
+#ifndef CLOCK_CONFIG_STATE_OBSERVER_PRIO
+#define CLOCK_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// <o> POWER_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to the Power driver.
+
+#ifndef POWER_CONFIG_STATE_OBSERVER_PRIO
+#define POWER_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// <o> RNG_CONFIG_STATE_OBSERVER_PRIO  
+// <i> Priority with which state events are dispatched to this module.
+
+#ifndef RNG_CONFIG_STATE_OBSERVER_PRIO
+#define RNG_CONFIG_STATE_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// <h> Stack Event Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> NRF_SDH_ANT_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which ANT events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have ANT events dispatched before or after other stack events, such as BLE or SoC.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_ANT_STACK_OBSERVER_PRIO
+#define NRF_SDH_ANT_STACK_OBSERVER_PRIO 0
+#endif
+
+// <o> NRF_SDH_BLE_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which BLE events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have BLE events dispatched before or after other stack events, such as ANT or SoC.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_BLE_STACK_OBSERVER_PRIO
+#define NRF_SDH_BLE_STACK_OBSERVER_PRIO 0
+#endif
+
+// <o> NRF_SDH_SOC_STACK_OBSERVER_PRIO  
+// <i> This setting configures the priority with which SoC events are processed with respect to other events coming from the stack.
+// <i> Modify this setting if you need to have SoC events dispatched before or after other stack events, such as ANT or BLE.
+// <i> Zero is the highest priority.
+
+#ifndef NRF_SDH_SOC_STACK_OBSERVER_PRIO
+#define NRF_SDH_SOC_STACK_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// <e> NRF_SDH_SOC_ENABLED - nrf_sdh_soc - SoftDevice SoC event handler
+//==========================================================
+#ifndef NRF_SDH_SOC_ENABLED
+#define NRF_SDH_SOC_ENABLED 0
+#endif
+// <h> SoC Observers - Observers and priority levels
+
+//==========================================================
+// <o> NRF_SDH_SOC_OBSERVER_PRIO_LEVELS - Total number of priority levels for SoC observers. 
+// <i> This setting configures the number of priority levels available for the SoC event handlers.
+// <i> The priority level of a handler determines the order in which it receives events, with respect to other handlers.
+
+#ifndef NRF_SDH_SOC_OBSERVER_PRIO_LEVELS
+#define NRF_SDH_SOC_OBSERVER_PRIO_LEVELS 2
+#endif
+
+// <h> SoC Observers priorities - Invididual priorities
+
+//==========================================================
+// <o> BLE_DFU_SOC_OBSERVER_PRIO  
+// <i> Priority with which BLE events are dispatched to the DFU Service.
+
+#ifndef BLE_DFU_SOC_OBSERVER_PRIO
+#define BLE_DFU_SOC_OBSERVER_PRIO 1
+#endif
+
+// <o> CLOCK_CONFIG_SOC_OBSERVER_PRIO  
+// <i> Priority with which SoC events are dispatched to the Clock driver.
+
+#ifndef CLOCK_CONFIG_SOC_OBSERVER_PRIO
+#define CLOCK_CONFIG_SOC_OBSERVER_PRIO 0
+#endif
+
+// <o> POWER_CONFIG_SOC_OBSERVER_PRIO  
+// <i> Priority with which SoC events are dispatched to the Power driver.
+
+#ifndef POWER_CONFIG_SOC_OBSERVER_PRIO
+#define POWER_CONFIG_SOC_OBSERVER_PRIO 0
+#endif
+
+// </h> 
+//==========================================================
+
+// </h> 
+//==========================================================
+
+
+// </e>
+
+// </h> 
+//==========================================================
+
+// <<< end of configuration section >>>
+#endif //SDK_CONFIG_H
+
diff --git a/third_party/NordicSemiconductor/dependencies/sdk_config.h b/third_party/NordicSemiconductor/dependencies/sdk_config.h
deleted file mode 100644
index e9d08f0..0000000
--- a/third_party/NordicSemiconductor/dependencies/sdk_config.h
+++ /dev/null
@@ -1,935 +0,0 @@
-#ifndef SDK_CONFIG_H
-#define SDK_CONFIG_H
-
-#include <openthread/config.h>
-#undef PACKAGE
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic ignored "-Wpedantic"
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//==========================================================
-// <e> APP_USBD_ENABLED - app_usbd - USB Device library
-//==========================================================
-#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
-#ifndef APP_USBD_ENABLED
-#define APP_USBD_ENABLED 1
-#endif
-#else  // USB_CDC_AS_SERIAL_TRANSPORT == 1
-#ifndef APP_USBD_ENABLED
-#define APP_USBD_ENABLED 0
-#endif
-#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
-
-// <s> APP_USBD_VID - Vendor ID
-
-// <i> Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/
-#ifndef APP_USBD_VID
-#define APP_USBD_VID 0x1915
-#endif
-
-// <s> APP_USBD_PID - Product ID
-
-// <i> Selected Product ID
-#ifndef APP_USBD_PID
-#define APP_USBD_PID 0xCAFE
-#endif
-
-// <o> APP_USBD_DEVICE_VER_MAJOR - Major device version  <0-99>
-
-
-// <i> Major device version, will be converted automatically to BCD notation. Use just decimal values.
-
-#ifndef APP_USBD_DEVICE_VER_MAJOR
-#define APP_USBD_DEVICE_VER_MAJOR 1
-#endif
-
-// <o> APP_USBD_DEVICE_VER_MINOR - Minor device version  <0-9>
-
-
-// <i> Minor device version, will be converted automatically to BCD notation. Use just decimal values.
-
-#ifndef APP_USBD_DEVICE_VER_MINOR
-#define APP_USBD_DEVICE_VER_MINOR 0
-#endif
-
-// <o> APP_USBD_DEVICE_VER_SUB - Sub-minor device version  <0-9>
-
-
-// <i> Sub-minor device version, will be converted automatically to BCD notation. Use just decimal values.
-
-#ifndef APP_USBD_DEVICE_VER_SUB
-#define APP_USBD_DEVICE_VER_SUB 0
-#endif
-
-// <q> APP_USBD_CONFIG_SELF_POWERED  - Self powered
-
-
-#ifndef APP_USBD_CONFIG_SELF_POWERED
-#define APP_USBD_CONFIG_SELF_POWERED 1
-#endif
-
-// <o> APP_USBD_CONFIG_MAX_POWER - MaxPower field in configuration descriptor in milliamps.  <0-500> 
-
-
-#ifndef APP_USBD_CONFIG_MAX_POWER
-#define APP_USBD_CONFIG_MAX_POWER 500
-#endif
-
-// <q> APP_USBD_CONFIG_POWER_EVENTS_PROCESS  - Process power events
-
-
-// <i> Enable processing power events in USB event handler.
-
-#ifndef APP_USBD_CONFIG_POWER_EVENTS_PROCESS
-#define APP_USBD_CONFIG_POWER_EVENTS_PROCESS 1
-#endif
-
-// <e> APP_USBD_CONFIG_EVENT_QUEUE_ENABLE - Enable event queue
-
-// <i> This is the default configuration when all the events are placed into internal queue.
-// <i> Disable it when external queue is used like app_scheduler or if you wish to process all events inside interrupts.
-// <i> Processing all events from the interrupt level adds requirement not to call any functions that modifies the USBD library state from the context higher than USB interrupt context.
-// <i> Functions that modify USBD state are functions for sleep, wakeup, start, stop, enable and disable.
-//==========================================================
-#ifndef APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
-#define APP_USBD_CONFIG_EVENT_QUEUE_ENABLE 1
-#endif
-// <o> APP_USBD_CONFIG_EVENT_QUEUE_SIZE - The size of event queue  <16-64>
-
-
-// <i> The size of the queue for the events that would be processed in the main loop.
-
-#ifndef APP_USBD_CONFIG_EVENT_QUEUE_SIZE
-#define APP_USBD_CONFIG_EVENT_QUEUE_SIZE 32
-#endif
-
-// <o> APP_USBD_CONFIG_SOF_HANDLING_MODE  - Change SOF events handling mode.
-
-
-// <i> Normal queue   - SOF events are pushed normally into event queue.
-// <i> Compress queue - SOF events are counted and binded with other events or executed when queue is empty.
-// <i>                  This prevents queue from filling with SOF events.
-// <i> Interrupt      - SOF events are processed in interrupt.
-// <0=> Normal queue
-// <1=> Compress queue
-// <2=> Interrupt
-
-#ifndef APP_USBD_CONFIG_SOF_HANDLING_MODE
-#define APP_USBD_CONFIG_SOF_HANDLING_MODE 1
-#endif
-
-// </e>
-
-// <q> APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE  - Provide a function that generates timestamps for logs based on the current SOF
-
-
-// <i> The function app_usbd_sof_timestamp_get will be implemented if the logger is enabled.
-// <i> Use it when initializing the logger.
-// <i> SOF processing will be always enabled when this configuration parameter is active.
-// <i> Notice that this option is configured outside of APP_USBD_CONFIG_LOG_ENABLED.
-// <i> This means that it will work even if the logging in this very module is disabled.
-
-#ifndef APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE
-#define APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE 0
-#endif
-
-// <o> APP_USBD_CONFIG_DESC_STRING_SIZE - Maximum size of the NULL-terminated string of the string descriptor.  <31-254>
-
-
-// <i> 31 characters can be stored in the internal USB buffer used for transfers.
-// <i> Any value higher than 31 creates an additional buffer just for descriptor strings.
-
-#ifndef APP_USBD_CONFIG_DESC_STRING_SIZE
-#define APP_USBD_CONFIG_DESC_STRING_SIZE 31
-#endif
-
-// <q> APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED  - Enable UTF8 conversion.
-
-
-// <i> Enable UTF8-encoded characters. In normal processing, only ASCII characters are available.
-
-#ifndef APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED
-#define APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED 0
-#endif
-
-// <s> APP_USBD_STRINGS_LANGIDS - Supported languages identifiers.
-
-// <i> Note: This value is not editable in Configuration Wizard.
-// <i> Comma-separated list of supported languages.
-#ifndef APP_USBD_STRINGS_LANGIDS
-#define APP_USBD_STRINGS_LANGIDS APP_USBD_LANG_AND_SUBLANG(APP_USBD_LANG_ENGLISH, APP_USBD_SUBLANG_ENGLISH_US)
-#endif
-
-// <e> APP_USBD_STRING_ID_MANUFACTURER - Define manufacturer string ID.
-
-// <i> Setting ID to 0 disables the string.
-//==========================================================
-#ifndef APP_USBD_STRING_ID_MANUFACTURER
-#define APP_USBD_STRING_ID_MANUFACTURER 1
-#endif
-// <q> APP_USBD_STRINGS_MANUFACTURER_EXTERN  - Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by macro or declared as a global variable.
-
-
-#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN
-#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
-#endif
-
-// <s> APP_USBD_STRINGS_MANUFACTURER - String descriptor for the manufacturer name.
-
-// <i> Note: This value is not editable in Configuration Wizard.
-// <i> Comma-separated list of manufacturer names for each defined language.
-// <i> Use @ref APP_USBD_STRING_DESC macro to create string descriptor from a NULL-terminated string.
-// <i> Use @ref APP_USBD_STRING_RAW8_DESC macro to create string descriptor from comma-separated uint8_t values.
-// <i> Use @ref APP_USBD_STRING_RAW16_DESC macro to create string descriptor from comma-separated uint16_t values.
-// <i> Alternatively, configure the macro to point to any internal variable pointer that already contains the descriptor.
-// <i> Setting string to NULL disables that string.
-// <i> The order of manufacturer names must be the same like in @ref APP_USBD_STRINGS_LANGIDS.
-#ifndef APP_USBD_STRINGS_MANUFACTURER
-#define APP_USBD_STRINGS_MANUFACTURER APP_USBD_STRING_DESC("Nordic Semiconductor")
-#endif
-
-// </e>
-
-// <e> APP_USBD_STRING_ID_PRODUCT - Define product string ID.
-
-// <i> Setting ID to 0 disables the string.
-//==========================================================
-#ifndef APP_USBD_STRING_ID_PRODUCT
-#define APP_USBD_STRING_ID_PRODUCT 2
-#endif
-// <q> APP_USBD_STRINGS_PRODUCT_EXTERN  - Define whether @ref APP_USBD_STRINGS_PRODUCT is created by macro or declared as a global variable.
-
-
-#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
-#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
-#endif
-
-// <s> APP_USBD_STRINGS_PRODUCT - String descriptor for the product name.
-
-// <i> Note: This value is not editable in Configuration Wizard.
-// <i> List of product names that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
-#ifndef APP_USBD_STRINGS_PRODUCT
-#define APP_USBD_STRINGS_PRODUCT APP_USBD_STRING_DESC("nRF52840 OpenThread Device")
-#endif
-
-// </e>
-
-// <e> APP_USBD_STRING_ID_SERIAL - Define serial number string ID.
-
-// <i> Setting ID to 0 disables the string.
-//==========================================================
-#ifndef APP_USBD_STRING_ID_SERIAL
-#define APP_USBD_STRING_ID_SERIAL 3
-#endif
-// <q> APP_USBD_STRING_SERIAL_EXTERN  - Define whether @ref APP_USBD_STRING_SERIAL is created by macro or declared as a global variable.
-
-
-#ifndef APP_USBD_STRING_SERIAL_EXTERN
-#define APP_USBD_STRING_SERIAL_EXTERN 1
-#endif
-
-// <s> APP_USBD_STRING_SERIAL - String descriptor for the serial number.
-
-// <i> Note: This value is not editable in Configuration Wizard.
-// <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
-#ifndef APP_USBD_STRING_SERIAL
-#define APP_USBD_STRING_SERIAL g_extern_serial_number
-#endif
-
-// </e>
-
-// <e> APP_USBD_STRING_ID_CONFIGURATION - Define configuration string ID.
-
-// <i> Setting ID to 0 disables the string.
-//==========================================================
-#ifndef APP_USBD_STRING_ID_CONFIGURATION
-#define APP_USBD_STRING_ID_CONFIGURATION 4
-#endif
-// <q> APP_USBD_STRING_CONFIGURATION_EXTERN  - Define whether @ref APP_USBD_STRINGS_CONFIGURATION is created by macro or declared as global variable.
-
-
-#ifndef APP_USBD_STRING_CONFIGURATION_EXTERN
-#define APP_USBD_STRING_CONFIGURATION_EXTERN 0
-#endif
-
-// <s> APP_USBD_STRINGS_CONFIGURATION - String descriptor for the device configuration.
-
-// <i> Note: This value is not editable in Configuration Wizard.
-// <i> Configuration string that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
-#ifndef APP_USBD_STRINGS_CONFIGURATION
-#define APP_USBD_STRINGS_CONFIGURATION APP_USBD_STRING_DESC("Default configuration")
-#endif
-
-// </e>
-
-// <s> APP_USBD_STRINGS_USER - Default values for user strings.
-
-// <i> Note: This value is not editable in Configuration Wizard.
-// <i> This value stores all application specific user strings with the default initialization.
-// <i> The setup is done by X-macros.
-// <i> Expected macro parameters:
-// <i> @code
-// <i> X(mnemonic, [=str_idx], ...)
-// <i> @endcode
-// <i> - @c mnemonic: Mnemonic of the string descriptor that would be added to
-// <i>                @ref app_usbd_string_desc_idx_t enumerator.
-// <i> - @c str_idx : String index value, can be set or left empty.
-// <i>                For example, WinUSB driver requires descriptor to be present on 0xEE index.
-// <i>                Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
-// <i> - @c ...     : List of string descriptors for each defined language.
-#ifndef APP_USBD_STRINGS_USER
-#define APP_USBD_STRINGS_USER X(APP_USER_1, , APP_USBD_STRING_DESC("User 1"))
-#endif
-
-// </e>
-
-// <e> APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module
-//==========================================================
-#ifndef APP_USBD_CONFIG_LOG_ENABLED
-#define APP_USBD_CONFIG_LOG_ENABLED 0
-#endif
-
-// </e>
-
-// </e>
-
-// <e> USBD_ENABLED - nrf_drv_usbd - USB driver
-//==========================================================
-#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
-#ifndef USBD_ENABLED
-#define USBD_ENABLED 1
-#endif
-#else  // USB_CDC_AS_SERIAL_TRANSPORT == 1
-#ifndef USBD_ENABLED
-#define USBD_ENABLED 0
-#endif
-#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
-
-// <q> Enable power USB detection.
-
-// <i> Configure if the example supports USB port connection.
-
-#ifndef USBD_POWER_DETECTION
-#define USBD_POWER_DETECTION 1
-#endif
-
-// <o> USBD_CONFIG_IRQ_PRIORITY  - Interrupt priority
-
-// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
-// <0=> 0 (highest)
-// <1=> 1
-// <2=> 2
-// <3=> 3
-// <4=> 4
-// <5=> 5
-// <6=> 6
-// <7=> 7
-
-#ifndef USBD_CONFIG_IRQ_PRIORITY
-#define USBD_CONFIG_IRQ_PRIORITY 7
-#endif
-
-// <o> USBD_CONFIG_DMASCHEDULER_MODE  - USBD SMA scheduler working scheme
-
-// <0=> Prioritized access
-// <1=> Round Robin
-
-#ifndef USBD_CONFIG_DMASCHEDULER_MODE
-#define USBD_CONFIG_DMASCHEDULER_MODE 0
-#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 USBD_CONFIG_DMASCHEDULER_ISO_BOOST
-#define 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 USBD_CONFIG_ISO_IN_ZLP
-#define USBD_CONFIG_ISO_IN_ZLP 0
-#endif
-
-#define NRFX_USBD_ENABLED                       USBD_ENABLED
-#define NRFX_USBD_POWER_DETECTION               USBD_POWER_DETECTION
-#define NRFX_USBD_CONFIG_IRQ_PRIORITY           USBD_CONFIG_IRQ_PRIORITY
-#define NRFX_USBD_CONFIG_DMASCHEDULER_MODE      USBD_CONFIG_DMASCHEDULER_MODE
-#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST USBD_CONFIG_DMASCHEDULER_ISO_BOOST
-#define NRFX_USBD_CONFIG_ISO_IN_ZLP             USBD_CONFIG_ISO_IN_ZLP
-
-// </e>
-
-
-// <h> Application info used by the USB DFU.
- 
-// <q> @def APP_NAME
-
-// <i> Application name in a human readable string.
-
-
-#ifndef APP_NAME
-#define APP_NAME "OpenThread App"
-#endif
-
-
-// <q> APP_VERSION_MAJOR
-
-// <i> Application version major version.
-
-#ifndef APP_VERSION_MAJOR
-#define APP_VERSION_MAJOR 1
-#endif
-
-
-// <q> APP_VERSION_MINOR
-
-// <i> Application version minor version.
-
-
-#ifndef APP_VERSION_MINOR
-#define APP_VERSION_MINOR 0
-#endif
-
-
-// <q> APP_VERSION_PATCH
-
-// <i> Application version patch version.
-
-
-#ifndef APP_VERSION_PATCH
-#define APP_VERSION_PATCH 0
-#endif
-
-
-// <q> @def APP_ID
-
-// <i> Application ID.
-
-
-#ifndef APP_ID
-#define APP_ID 1
-#endif
-
-
-// <q> APP_VERSION_PRERELEASE
-
-// <i> Application prerelease tag.
-
-
-#ifndef APP_VERSION_PRERELEASE
-#define APP_VERSION_PRERELEASE ""
-#endif
-
-
-// <q> APP_VERSION_METADATA
-
-// <i> Application metadata.
-
-
-#ifndef APP_VERSION_METADATA
-#define APP_VERSION_METADATA ""
-#endif
-
-// <h> app_usbd_cdc_acm - USB CDC ACM class
-
-//==========================================================
-// <q> APP_USBD_CDC_ACM_ENABLED  - app_usbd_cdc_acm - USB CDC ACM class
-
-
-#ifndef APP_USBD_CDC_ACM_ENABLED
-#define APP_USBD_CDC_ACM_ENABLED 1
-#endif
-
-// <q> APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE  - Send ZLP on write with same size as endpoint
-
-
-// <i> If enabled, CDC ACM class will automatically send a zero length packet after transfer which has the same size as endpoint.
-// <i> This may limit throughput if a lot of binary data is sent, but in terminal mode operation it makes sure that the data is always displayed right after it is sent.
-
-#ifndef APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE
-#define APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE 1
-#endif
-
-// </h>
-
-// <h> app_usbd_nrf_dfu_trigger - USB Trigger library
-
-//==========================================================
-// <q> APP_USBD_NRF_DFU_TRIGGER_ENABLED
-
-
-// <i> Enable possibility to enter the bootloader from the application via a software trigger send over USB.
-// <i> Requires configured BSP_SELF_PINRESET_PIN which is a GPIO pin connected to the reset pin.
-
-#ifndef APP_USBD_NRF_DFU_TRIGGER_ENABLED
-#define APP_USBD_NRF_DFU_TRIGGER_ENABLED 0
-#endif
-
-// <q> BSP_SELF_PINRESET_PIN
-
-
-// <i> Enable possibility to enter the bootloader from the application via a software trigger send over USB.
-// <i> Requires configured BSP_SELF_PINRESET_PIN which is a GPIO pin connected to the reset pin.
-// <i> NRF_GPIO_PIN_MAP(0,19) is a pin used on Nordic PCA10059 Dongle.
-
-#ifndef BSP_SELF_PINRESET_PIN
-#define BSP_SELF_PINRESET_PIN NRF_GPIO_PIN_MAP(0, 19)
-#endif
-
-// <q> NRF_DFU_TRIGGER_USB_USB_SHARED
-
-// <i> Flag indicating whether USB is used for other purposes in the application.
-
-#ifndef NRF_DFU_TRIGGER_USB_USB_SHARED
-#define NRF_DFU_TRIGGER_USB_USB_SHARED 1
-#endif
-
-
-// <q> NRF_DFU_TRIGGER_USB_INTERFACE_NUM
-
-// <i> The USB interface to use for the DFU Trigger library.
-// <i> According to the USB Specification, interface numbers cannot have gaps. Tailor this value to adhere to this
-// <i> limitation. Takes values between 0-255
-
-#ifndef NRF_DFU_TRIGGER_USB_INTERFACE_NUM
-#define NRF_DFU_TRIGGER_USB_INTERFACE_NUM 0
-#endif
-
-// </h>
-
-//==========================================================
-
-// <h> nrf_log - Logging
-
-//==========================================================
-// <e> NRF_LOG_ENABLED - Logging module for nRF5 SDK
-//==========================================================
-#ifndef NRF_LOG_ENABLED
-#define NRF_LOG_ENABLED 0
-#endif
-
-// </e>
-// </h>
-
-// <h> segger_rtt - SEGGER RTT
-
-//==========================================================
-// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer.
-// <i> Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE
-// <i> or this value is actually used. It depends on which one is bigger.
-
-#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP
-#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 512
-#endif
-
-// <o> SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer.
-#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS
-#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
-#endif
-
-// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer.
-#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN
-#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
-#endif
-
-// <o> SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer.
-#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS
-#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
-#endif
-
-// <o> SEGGER_RTT_CONFIG_DEFAULT_MODE  - RTT behavior if the buffer is full.
-
-
-// <i> The following modes are supported:
-// <i> - SKIP  - Do not block, output nothing.
-// <i> - TRIM  - Do not block, output as much as fits.
-// <i> - BLOCK - Wait until there is space in the buffer.
-// <0=> SKIP
-// <1=> TRIM
-// <2=> BLOCK_IF_FIFO_FULL
-
-#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE
-#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
-#endif
-
-// </h>
-//==========================================================
-
-// <e> NRF_CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver
-//==========================================================
-#ifndef NRF_CLOCK_ENABLED
-#define NRF_CLOCK_ENABLED 1
-#endif
-// <o> CLOCK_CONFIG_XTAL_FREQ  - HF XTAL Frequency
-
-// <0=> Default (64 MHz)
-
-#ifndef CLOCK_CONFIG_XTAL_FREQ
-#define CLOCK_CONFIG_XTAL_FREQ 0
-#endif
-
-// <o> CLOCK_CONFIG_LF_SRC  - LF Clock Source
-
-// <0=> RC
-// <1=> XTAL
-// <2=> Synth
-
-#ifndef CLOCK_CONFIG_LF_SRC
-#define CLOCK_CONFIG_LF_SRC 1
-#endif
-
-// <o> CLOCK_CONFIG_IRQ_PRIORITY  - Interrupt priority
-
-
-// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
-// <0=> 0 (highest)
-// <1=> 1
-// <2=> 2
-// <3=> 3
-// <4=> 4
-// <5=> 5
-// <6=> 6
-// <7=> 7
-
-#ifndef CLOCK_CONFIG_IRQ_PRIORITY
-#define CLOCK_CONFIG_IRQ_PRIORITY 7
-#endif
-
-// </e>
-
-// <e> POWER_ENABLED - nrf_drv_power - POWER peripheral driver
-//==========================================================
-
-#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
-#ifndef POWER_ENABLED
-#define POWER_ENABLED 1
-#endif
-#else  // USB_CDC_AS_SERIAL_TRANSPORT == 1
-#ifndef POWER_ENABLED
-#define POWER_ENABLED 0
-#endif
-#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
-
-// <o> POWER_CONFIG_IRQ_PRIORITY  - Interrupt priority
-
-
-// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
-// <0=> 0 (highest)
-// <1=> 1
-// <2=> 2
-// <3=> 3
-// <4=> 4
-// <5=> 5
-// <6=> 6
-// <7=> 7
-
-#ifndef POWER_CONFIG_IRQ_PRIORITY
-#define POWER_CONFIG_IRQ_PRIORITY 7
-#endif
-
-// <q> POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
-
-
-// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
-
-#ifndef POWER_CONFIG_DEFAULT_DCDCEN
-#define POWER_CONFIG_DEFAULT_DCDCEN 0
-#endif
-
-// <q> POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
-
-
-// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
-
-#ifndef POWER_CONFIG_DEFAULT_DCDCENHV
-#define POWER_CONFIG_DEFAULT_DCDCENHV 0
-#endif
-
-// </e>
-
-
-// <e> NRFX_SPIS_ENABLED - nrfx_spis - SPIS peripheral driver
-//==========================================================
-#if (SPIS_AS_SERIAL_TRANSPORT == 1)
-#ifndef NRFX_SPIS_ENABLED
-#define NRFX_SPIS_ENABLED 1
-#endif
-#else  // SPIS_AS_SERIAL_TRANSPORT == 1
-#ifndef NRFX_SPIS_ENABLED
-#define NRFX_SPIS_ENABLED 0
-#endif
-#endif // SPIS_AS_SERIAL_TRANSPORT == 1
-
-// <q> NRFX_SPIS0_ENABLED  - Enable SPIS0 instance
-
-#ifndef NRFX_SPIS0_ENABLED
-#define NRFX_SPIS0_ENABLED 1
-#endif
-
-// <q> NRFX_SPIS1_ENABLED  - Enable SPIS1 instance
-
-
-#ifndef NRFX_SPIS1_ENABLED
-#define NRFX_SPIS1_ENABLED 0
-#endif
-
-// <q> NRFX_SPIS2_ENABLED  - Enable SPIS2 instance
-
-
-#ifndef NRFX_SPIS2_ENABLED
-#define NRFX_SPIS2_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
-
-// <o> NRFX_SPIS_DEFAULT_DEF - SPIS default DEF character  <0-255>
-
-
-#ifndef NRFX_SPIS_DEFAULT_DEF
-#define NRFX_SPIS_DEFAULT_DEF 255
-#endif
-
-// <o> NRFX_SPIS_DEFAULT_ORC - SPIS default ORC character  <0-255>
-
-
-#ifndef NRFX_SPIS_DEFAULT_ORC
-#define NRFX_SPIS_DEFAULT_ORC 255
-#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>
-
-// <e> NRFX_TIMER_ENABLED - nrfx_timer - TIMER periperal driver
-//==========================================================
-#ifndef NRFX_TIMER_ENABLED
-#define NRFX_TIMER_ENABLED 1
-#endif
-// <q> NRFX_TIMER0_ENABLED  - Enable TIMER0 instance
-
-
-#ifndef NRFX_TIMER0_ENABLED
-#define NRFX_TIMER0_ENABLED 1
-#endif
-
-// <q> NRFX_TIMER1_ENABLED  - Enable TIMER1 instance
-
-
-#ifndef NRFX_TIMER1_ENABLED
-#define NRFX_TIMER1_ENABLED 1
-#endif
-
-// <q> NRFX_TIMER2_ENABLED  - Enable TIMER2 instance
-
-
-#ifndef NRFX_TIMER2_ENABLED
-#define NRFX_TIMER2_ENABLED 1
-#endif
-
-// <q> NRFX_TIMER3_ENABLED  - Enable TIMER3 instance
-
-
-#ifndef NRFX_TIMER3_ENABLED
-#define NRFX_TIMER3_ENABLED 1
-#endif
-
-// <q> NRFX_TIMER4_ENABLED  - Enable TIMER4 instance
-
-
-#ifndef NRFX_TIMER4_ENABLED
-#define NRFX_TIMER4_ENABLED 1
-#endif
-
-// <o> NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY  - Timer frequency if in Timer mode
-
-// <0=> 16 MHz
-// <1=> 8 MHz
-// <2=> 4 MHz
-// <3=> 2 MHz
-// <4=> 1 MHz
-// <5=> 500 kHz
-// <6=> 250 kHz
-// <7=> 125 kHz
-// <8=> 62.5 kHz
-// <9=> 31.25 kHz
-
-#ifndef NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY
-#define NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY 0
-#endif
-
-// <o> NRFX_TIMER_DEFAULT_CONFIG_MODE  - Timer mode or operation
-
-// <0=> Timer
-// <1=> Counter
-
-#ifndef NRFX_TIMER_DEFAULT_CONFIG_MODE
-#define NRFX_TIMER_DEFAULT_CONFIG_MODE 0
-#endif
-
-// <o> NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH  - Timer counter bit width
-
-// <0=> 16 bit
-// <1=> 8 bit
-// <2=> 24 bit
-// <3=> 32 bit
-
-#ifndef NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH
-#define NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH 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>
-
-// <q> SYSTICK_ENABLED  - nrf_drv_systick - SysTick driver
-
-#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
-#ifndef SYSTICK_ENABLED
-#define SYSTICK_ENABLED 1
-#endif
-#else  // USB_CDC_AS_SERIAL_TRANSPORT == 1
-#ifndef SYSTICK_ENABLED
-#define SYSTICK_ENABLED 0
-#endif
-#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
-
-#endif //SDK_CONFIG_H
diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c
index a973064..54545f5 100644
--- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c
+++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c
@@ -73,7 +73,7 @@
     nrf_802154_enh_ack_generator_init();
 }
 
-const uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame)
+uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame)
 {
     // This function should not be called if ACK is not requested.
     assert(p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT);
diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h
index 561ec80..059a19f 100644
--- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h
+++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h
@@ -49,6 +49,6 @@
  * @returns  Either pointer to a constant buffer that contains PHR and PSDU
  *           of the created ACK frame, or NULL in case of an invalid frame.
  */
-const uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame);
+uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame);
 
 #endif // NRF_802154_ACK_GENERATOR_H
diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c
index 9985758..c441066 100644
--- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c
+++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c
@@ -334,7 +334,7 @@
     // Intentionally empty.
 }
 
-const uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame)
+uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame)
 {
 
     nrf_802154_frame_parser_mhr_data_t frame_offsets;
diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h
index 15005db..91e812d 100644
--- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h
+++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h
@@ -53,6 +53,6 @@
  * @returns  Pointer to a constant buffer that contains PHR and PSDU
  *           of the created Enhanced ACK frame.
  */
-const uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame);
+uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame);
 
 #endif // NRF_802154_ENH_ACK_GENERATOR_H
diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c
index 748e622..bc26050 100644
--- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c
+++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c
@@ -53,7 +53,7 @@
     memcpy(m_ack_data, ack_data, sizeof(ack_data));
 }
 
-const uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame)
+uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame)
 {
     // Set valid sequence number in ACK frame.
     m_ack_data[DSN_OFFSET] = p_frame[DSN_OFFSET];
diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h
index 8504a51..db6be61 100644
--- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h
+++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h
@@ -53,6 +53,6 @@
  * @returns  Pointer to a constant buffer that contains PHR and PSDU of the created
  *           Immediate ACK frame.
  */
-const uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame);
+uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame);
 
 #endif // NRF_802154_IMM_ACK_GENERATOR_H
diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c
index 02d9fdb..a2c590b 100644
--- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c
+++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c
@@ -697,7 +697,7 @@
 
 #endif // NRF_802154_ACK_TIMEOUT_ENABLED
 
-__WEAK void nrf_802154_tx_ack_started(const uint8_t * p_data)
+__WEAK void nrf_802154_tx_ack_started(uint8_t * p_data)
 {
     (void)p_data;
 }
diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h
index b1adba4..ad982a3 100644
--- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h
+++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h
@@ -537,7 +537,7 @@
  *
  * @param[in]  p_data  Pointer to a buffer with PHR and PSDU of the ACK frame.
  */
-extern void nrf_802154_tx_ack_started(const uint8_t * p_data);
+extern void nrf_802154_tx_ack_started(uint8_t * p_data);
 
 #if NRF_802154_USE_RAW_API
 
diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c
index ea15796..e938f39 100644
--- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c
+++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c
@@ -165,7 +165,7 @@
 
 #endif
 
-static const uint8_t * mp_ack;         ///< Pointer to Ack frame buffer.
+static uint8_t *       mp_ack;         ///< Pointer to Ack frame buffer.
 static const uint8_t * mp_tx_data;     ///< Pointer to the data to transmit.
 static uint32_t        m_ed_time_left; ///< Remaining time of the current energy detection procedure [us].
 static uint8_t         m_ed_result;    ///< Result of the current energy detection procedure.
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/config/nrf-config.h b/third_party/NordicSemiconductor/libraries/nrf_security/config/nrf-config.h
index a9c6ea4..60cc245 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/config/nrf-config.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/config/nrf-config.h
@@ -55,7 +55,7 @@
  * Required by:
  *      MBEDTLS_AESNI_C
  *      MBEDTLS_PADLOCK_C
- * 
+ *
  * Comment to disable the use of assembly code.
  */
 #define MBEDTLS_HAVE_ASM
@@ -310,8 +310,8 @@
 //#define MBEDTLS_BLOWFISH_ALT
 //#define MBEDTLS_CAMELLIA_ALT
 #define MBEDTLS_CCM_ALT
-/* #undef MBEDTLS_CHACHA20_ALT */
-/* #undef MBEDTLS_CHACHAPOLY_ALT */
+#define MBEDTLS_CHACHA20_ALT
+#define MBEDTLS_CHACHAPOLY_ALT
 #define MBEDTLS_CMAC_ALT
 //#define MBEDTLS_DES_ALT
 #define MBEDTLS_DHM_ALT
@@ -321,11 +321,11 @@
 //#define MBEDTLS_MD2_ALT
 //#define MBEDTLS_MD4_ALT
 //#define MBEDTLS_MD5_ALT
-/* #undef MBEDTLS_POLY1305_ALT */
+#define MBEDTLS_POLY1305_ALT
 //#define MBEDTLS_RIPEMD160_ALT
 #define MBEDTLS_ECP_ALT
 /* #undef MBEDTLS_RSA_ALT */
-/* #undef MBEDTLS_SHA1_ALT */
+#define MBEDTLS_SHA1_ALT
 #define MBEDTLS_SHA256_ALT
 //#define MBEDTLS_SHA512_ALT
 //#define MBEDTLS_XTEA_ALT
@@ -1141,7 +1141,7 @@
  *
  * Do not use the Chinese Remainder Theorem
  * for the RSA private operation.
- * 
+ *
  * Uncomment this macro to disable the use of CRT in RSA.
  *
  */
@@ -1168,7 +1168,7 @@
  *
  * Uncomment to enable the smaller implementation of SHA256.
  */
-#define MBEDTLS_SHA256_SMALLER
+/* #undef MBEDTLS_SHA256_SMALLER */
 
 /**
  * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
@@ -1987,7 +1987,7 @@
  *
  * Module:  library/chacha20.c
  */
-/* #undef MBEDTLS_CHACHA20_C */
+#define MBEDTLS_CHACHA20_C
 
 /**
  * \def MBEDTLS_CHACHAPOLY_C
@@ -1998,7 +1998,7 @@
  *
  * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
  */
-/* #undef MBEDTLS_CHACHAPOLY_C */
+#define MBEDTLS_CHACHAPOLY_C
 
 /**
  * \def MBEDTLS_CIPHER_C
@@ -2489,7 +2489,7 @@
  *
  * Uncomment to enable generic public key write functions.
  */
-/* #undef MBEDTLS_PK_WRITE_C */
+#define MBEDTLS_PK_WRITE_C
 
 /**
  * \def MBEDTLS_PKCS5_C
@@ -2563,7 +2563,7 @@
  * Module:  library/poly1305.c
  * Caller:  library/chachapoly.c
  */
-/* #undef MBEDTLS_POLY1305_C */
+#define MBEDTLS_POLY1305_C
 
 /**
  * \def MBEDTLS_RIPEMD160_C
@@ -2613,9 +2613,9 @@
  * \warning   SHA-1 is considered a weak message digest and its use constitutes
  *            a security risk. If possible, we recommend avoiding dependencies
  *            on it, and considering stronger message digests instead.
- * 
+ *
  */
-/* #undef MBEDTLS_SHA1_C */
+#define MBEDTLS_SHA1_C
 
 /**
  * \def MBEDTLS_SHA256_C
@@ -2647,7 +2647,7 @@
  *
  * This module adds support for SHA-384 and SHA-512.
  */
-/* #undef MBEDTLS_SHA512_C */
+#define MBEDTLS_SHA512_C
 
 /**
  * \def MBEDTLS_SSL_CACHE_C
@@ -3139,6 +3139,8 @@
 #define CONFIG_CC310_MBEDTLS_AES_C
 #define CONFIG_CC310_MBEDTLS_C
 #define CONFIG_CC310_MBEDTLS_CCM_C
+#define CONFIG_CC310_MBEDTLS_CHACHA20_C
+#define CONFIG_CC310_MBEDTLS_CHACHAPOLY_C
 #define CONFIG_CC310_MBEDTLS_CIPHER_MODE_C
 #define CONFIG_CC310_MBEDTLS_CMAC_C
 #define CONFIG_CC310_MBEDTLS_DHM_C
@@ -3146,6 +3148,8 @@
 #define CONFIG_CC310_MBEDTLS_ECDSA_C
 #define CONFIG_CC310_MBEDTLS_ECJPAKE_C
 #define CONFIG_CC310_MBEDTLS_ECP_C
+#define CONFIG_CC310_MBEDTLS_POLY1305_C
+#define CONFIG_CC310_MBEDTLS_SHA1_C
 #define CONFIG_CC310_MBEDTLS_SHA256_C
 #define CONFIG_GLUE_MBEDTLS_AES_C
 #define CONFIG_GLUE_MBEDTLS_C
@@ -3191,6 +3195,14 @@
  */
 /* #undef MBEDTLS_AES_256_CMAC_C */
 
+/*
+ * Nordic added. Ensure there is a definition of mbedtls_ecp_restart_ctx
+ */
+#if defined(MBEDTLS_ECP_ALT) && !defined(MBEDTLS_ECP_RESTARTABLE) && !defined(MBEDTLS_ECP_RESTART_CTX_DECLARED)
+#define MBEDTLS_ECP_RESTART_CTX_DECLARED
+typedef void mbedtls_ecp_restart_ctx;
+#endif
+
 
 
 #include "mbedtls/check_config.h"
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/bignum.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/bignum.h
index 1c86072..22b3731 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/bignum.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/bignum.h
@@ -184,7 +184,7 @@
  */
 typedef struct mbedtls_mpi
 {
-    int s;              /*!<  integer sign      */
+    int s;              /*!<  Sign: -1 if the mpi is negative, 1 otherwise */
     size_t n;           /*!<  total # of limbs  */
     mbedtls_mpi_uint *p;          /*!<  pointer to limbs  */
 }
@@ -560,6 +560,24 @@
 int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
 
 /**
+ * \brief          Check if an MPI is less than the other in constant time.
+ *
+ * \param X        The left-hand MPI. This must point to an initialized MPI
+ *                 with the same allocated length as Y.
+ * \param Y        The right-hand MPI. This must point to an initialized MPI
+ *                 with the same allocated length as X.
+ * \param ret      The result of the comparison:
+ *                 \c 1 if \p X is less than \p Y.
+ *                 \c 0 if \p X is greater than or equal to \p Y.
+ *
+ * \return         0 on success.
+ * \return         MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of
+ *                 the two input MPIs is not the same.
+ */
+int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
+        unsigned *ret );
+
+/**
  * \brief          Compare an MPI with an integer.
  *
  * \param X        The left-hand MPI. This must point to an initialized MPI.
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/bn_mul.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/bn_mul.h
index c33bd8d..748975e 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/bn_mul.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/bn_mul.h
@@ -642,7 +642,8 @@
            "r6", "r7", "r8", "r9", "cc"         \
          );
 
-#elif defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
+#elif (__ARM_ARCH >= 6) && \
+    defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
 
 #define MULADDC_INIT                            \
     asm(
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/chacha20_alt.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/chacha20_alt.h
new file mode 100644
index 0000000..52018f1
--- /dev/null
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/chacha20_alt.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause OR Arm’s non-OSI source license
+ */
+
+#ifndef MBEDTLS_CHACHA20_ALT_H
+#define MBEDTLS_CHACHA20_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#include <stddef.h>
+#include <stdint.h>
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/*! The size of the ChaCha user-context in words. */
+#define MBEDTLS_CHACHA_USER_CTX_SIZE_IN_WORDS         17
+/*! The size of the ChaCha block in Bytes. */
+#define MBEDTLS_CHACHA_BLOCK_SIZE_BYTES               64
+/*! The size of the ChaCha block in Bytes. As defined in rfc7539 */
+#define MBEDTLS_CHACHA_NONCE_SIZE_BYTES               12
+/*! The size of the ChaCha key in Bytes. */
+#define MBEDTLS_CHACHA_KEY_SIZE_BYTES                 32
+/*! Internal type to identify 12 byte nonce */
+#define MBEDTLS_CHACHA_NONCE_SIZE_12BYTE_TYPE         1
+
+/*! The definition of the 12-Byte array of the nonce buffer. */
+typedef uint8_t mbedtls_chacha_nonce[MBEDTLS_CHACHA_NONCE_SIZE_BYTES];
+
+/*! The definition of the key buffer of the ChaCha engine. */
+typedef uint8_t mbedtls_chacha_key[MBEDTLS_CHACHA_KEY_SIZE_BYTES];
+
+#if defined(MBEDTLS_CHACHA20_ALT)
+
+typedef struct
+{
+    uint32_t buf[MBEDTLS_CHACHA_USER_CTX_SIZE_IN_WORDS];
+}
+mbedtls_chacha20_context;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MBEDTLS_CHACHA20_ALT_H */
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/chachapoly_alt.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/chachapoly_alt.h
new file mode 100644
index 0000000..edfecbe
--- /dev/null
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/chachapoly_alt.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause OR Arm’s non-OSI source license
+ */
+
+#ifndef MBEDTLS_CHACHAPOLY_ALT_H
+#define MBEDTLS_CHACHAPOLY_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+#if defined(MBEDTLS_CHACHAPOLY_ALT)
+
+
+#define MBEDTLS_CHACHAPOLY_KEY_SIZE_BYTES 32
+
+
+typedef struct mbedtls_chachapoly_context
+{
+    unsigned char key[MBEDTLS_CHACHAPOLY_KEY_SIZE_BYTES];
+}
+mbedtls_chachapoly_context;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MBEDTLS_CHACHAPOLY_ALT_H */
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/check_config.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/check_config.h
index b86e580..d076c23 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/check_config.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/check_config.h
@@ -123,7 +123,7 @@
 #error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || (   \
+#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || (    \
     !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) &&                  \
     !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) &&                  \
     !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) &&                  \
@@ -134,7 +134,9 @@
     !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)   &&                  \
     !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) &&                  \
     !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) &&                  \
-    !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
+    !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) &&                 \
+    !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) )
 #error "MBEDTLS_ECP_C defined, but not all prerequisites"
 #endif
 
@@ -279,6 +281,14 @@
 #error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites"
+#endif
+
+#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites"
+#endif
+
 #if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
 #error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
 #endif
@@ -691,7 +701,7 @@
 /*
  * Avoid warning from -pedantic. This is a convenient place for this
  * workaround since this is included by every single file before the
- * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
+ * #if defined(MBEDTLS_xxx_C) that results in empty translation units.
  */
 typedef int mbedtls_iso_c_forbids_empty_translation_units;
 
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/config.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/config.h
index 654f972..834cced 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/config.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/config.h
@@ -139,7 +139,7 @@
  *
  * System has time.h, time(), and an implementation for
  * mbedtls_platform_gmtime_r() (see below).
- * The time needs to be correct (not necesarily very accurate, but at least
+ * The time needs to be correct (not necessarily very accurate, but at least
  * the date should be correct). This is used to verify the validity period of
  * X.509 certificates.
  *
@@ -276,28 +276,52 @@
  * For example, when a function accepts as input a pointer to a buffer that may
  * contain untrusted data, and its documentation mentions that this pointer
  * must not be NULL:
- * - the pointer is checked to be non-NULL only if this option is enabled
- * - the content of the buffer is always validated
+ * - The pointer is checked to be non-NULL only if this option is enabled.
+ * - The content of the buffer is always validated.
  *
  * When this flag is defined, if a library function receives a parameter that
- * is invalid, it will:
- * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a
- *   call to the function mbedtls_param_failed()
- * - immediately return (with a specific error code unless the function
- *   returns void and can't communicate an error).
+ * is invalid:
+ * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED().
+ * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function
+ *   will immediately return. If the function returns an Mbed TLS error code,
+ *   the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA.
  *
- * When defining this flag, you also need to:
- * - either provide a definition of the function mbedtls_param_failed() in
- *   your application (see platform_util.h for its prototype) as the library
- *   calls that function, but does not provide a default definition for it,
- * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED()
- *   below if the above mechanism is not flexible enough to suit your needs.
- *   See the documentation of this macro later in this file.
+ * When defining this flag, you also need to arrange a definition for
+ * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods:
+ * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a
+ *   function mbedtls_param_failed(), but the library does not define this
+ *   function. If you do not make any other arrangements, you must provide
+ *   the function mbedtls_param_failed() in your application.
+ *   See `platform_util.h` for its prototype.
+ * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the
+ *   library defines #MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
+ *   You can still supply an alternative definition of
+ *   MBEDTLS_PARAM_FAILED(), which may call `assert`.
+ * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h`
+ *   or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`,
+ *   the library will call the macro that you defined and will not supply
+ *   its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`,
+ *   you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source
+ *   files include `<assert.h>`.
  *
  * Uncomment to enable validation of application-controlled parameters.
  */
 //#define MBEDTLS_CHECK_PARAMS
 
+/**
+ * \def MBEDTLS_CHECK_PARAMS_ASSERT
+ *
+ * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to
+ * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined.
+ *
+ * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to
+ * calling a function mbedtls_param_failed(). See the documentation of
+ * #MBEDTLS_CHECK_PARAMS for details.
+ *
+ * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`.
+ */
+//#define MBEDTLS_CHECK_PARAMS_ASSERT
+
 /* \} name SECTION: System support */
 
 /**
@@ -401,7 +425,7 @@
  * \note Because of a signature change, the core AES encryption and decryption routines are
  *       currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
  *       respectively. When setting up alternative implementations, these functions should
- *       be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
+ *       be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
  *       must stay untouched.
  *
  * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
@@ -416,6 +440,16 @@
  *            dependencies on them, and considering stronger message digests
  *            and ciphers instead.
  *
+ * \warning   If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are
+ *            enabled, then the deterministic ECDH signature functions pass the
+ *            the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore
+ *            alternative implementations should use the RNG only for generating
+ *            the ephemeral key and nothing else. If this is not possible, then
+ *            MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative
+ *            implementation should be provided for mbedtls_ecdsa_sign_det_ext()
+ *            (and for mbedtls_ecdsa_sign_det() too if backward compatibility is
+ *            desirable).
+ *
  */
 //#define MBEDTLS_MD2_PROCESS_ALT
 //#define MBEDTLS_MD4_PROCESS_ALT
@@ -655,6 +689,13 @@
 #define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
 #define MBEDTLS_CIPHER_PADDING_ZEROS
 
+/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+ *
+ * Uncomment this macro to use a 128-bit key in the CTR_DRBG module.
+ * By default, CTR_DRBG uses a 256-bit key.
+ */
+//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+
 /**
  * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
  *
@@ -1558,7 +1599,7 @@
  * \def MBEDTLS_SSL_SESSION_TICKETS
  *
  * Enable support for RFC 5077 session tickets in SSL.
- * Client-side, provides full support for session tickets (maintainance of a
+ * Client-side, provides full support for session tickets (maintenance of a
  * session store remains the responsibility of the application, though).
  * Server-side, you also need to provide callbacks for writing and parsing
  * tickets, including authenticated encryption and key management. Example
@@ -1724,7 +1765,7 @@
  *
  * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
  * CRIME attack. Before enabling this option, you should examine with care if
- * CRIME or similar exploits may be a applicable to your use case.
+ * CRIME or similar exploits may be applicable to your use case.
  *
  * \note Currently compression can't be used with DTLS.
  *
@@ -2115,7 +2156,11 @@
  *
  * Enable the CTR_DRBG AES-based random generator.
  * The CTR_DRBG generator uses AES-256 by default.
- * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
+ * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
+ *
+ * \note To achieve a 256-bit security strength with CTR_DRBG,
+ *       you must use AES-256 *and* use sufficient entropy.
+ *       See ctr_drbg.h for more details.
  *
  * Module:  library/ctr_drbg.c
  * Caller:
@@ -3007,7 +3052,6 @@
 //#define MBEDTLS_CTR_DRBG_MAX_INPUT                256 /**< Maximum number of additional input bytes */
 //#define MBEDTLS_CTR_DRBG_MAX_REQUEST             1024 /**< Maximum number of requested bytes per call */
 //#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT           384 /**< Maximum size of (re)seed buffer */
-//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY              /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */
 
 /* HMAC_DRBG options */
 //#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL   10000 /**< Interval before reseed is performed by default */
@@ -3036,7 +3080,7 @@
 //#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
 //#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
-/* Note: your snprintf must correclty zero-terminate the buffer! */
+/* Note: your snprintf must correctly zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
@@ -3053,20 +3097,23 @@
 //#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO       time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
 //#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
-/* Note: your snprintf must correclty zero-terminate the buffer! */
+/* Note: your snprintf must correctly zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
 //#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
 
 /**
  * \brief       This macro is invoked by the library when an invalid parameter
- *              is detected that is only checked with MBEDTLS_CHECK_PARAMS
+ *              is detected that is only checked with #MBEDTLS_CHECK_PARAMS
  *              (see the documentation of that option for context).
  *
- *              When you leave this undefined here, a default definition is
- *              provided that invokes the function mbedtls_param_failed(),
- *              which is declared in platform_util.h for the benefit of the
- *              library, but that you need to define in your application.
+ *              When you leave this undefined here, the library provides
+ *              a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT
+ *              is defined, the default definition is `assert(cond)`,
+ *              otherwise the default definition calls a function
+ *              mbedtls_param_failed(). This function is declared in
+ *              `platform_util.h` for the benefit of the library, but
+ *              you need to define in your application.
  *
  *              When you define this here, this replaces the default
  *              definition in platform_util.h (which no longer declares the
@@ -3075,6 +3122,9 @@
  *              particular, that all the necessary declarations are visible
  *              from within the library - you can ensure that by providing
  *              them in this file next to the macro definition).
+ *              If you define this macro to call `assert`, also define
+ *              #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files
+ *              include `<assert.h>`.
  *
  *              Note that you may define this macro to expand to nothing, in
  *              which case you don't have to worry about declarations or
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ctr_drbg.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ctr_drbg.h
index cc3df7b..e0b5ed9 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ctr_drbg.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ctr_drbg.h
@@ -1,7 +1,8 @@
 /**
  * \file ctr_drbg.h
  *
- * \brief    This file contains CTR_DRBG definitions and functions.
+ * \brief    This file contains definitions and functions for the
+ *           CTR_DRBG pseudorandom generator.
  *
  * CTR_DRBG is a standardized way of building a PRNG from a block-cipher
  * in counter mode operation, as defined in <em>NIST SP 800-90A:
@@ -9,13 +10,35 @@
  * Bit Generators</em>.
  *
  * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
- * as the underlying block cipher.
+ * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
+ * as the underlying block cipher, with a derivation function.
+ * The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy.
+ * See the documentation of mbedtls_ctr_drbg_seed() for more details.
  *
- *  \warning Using 128-bit keys for CTR_DRBG limits the security of generated
- *  keys and operations that use random values generated to 128-bit security.
+ * Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2,
+ * here are the security strengths achieved in typical configuration:
+ * - 256 bits under the default configuration of the library, with AES-256
+ *   and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more.
+ * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
+ *   to 32 or more, and the DRBG is initialized with an explicit
+ *   nonce in the \c custom parameter to mbedtls_ctr_drbg_seed().
+ * - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
+ *   between 24 and 47 and the DRBG is not initialized with an explicit
+ *   nonce (see mbedtls_ctr_drbg_seed()).
+ * - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
+ *   and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is
+ *   always the case unless it is explicitly set to a different value
+ *   in config.h).
+ *
+ * Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to:
+ * - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol
+ *   \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time.
+ *   This is the default configuration of the library.
+ * - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time.
+ * - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
  */
 /*
- *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -56,9 +79,19 @@
 #define MBEDTLS_CTR_DRBG_BLOCKSIZE          16 /**< The block size used by the cipher. */
 
 #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
-#define MBEDTLS_CTR_DRBG_KEYSIZE            16 /**< The key size used by the cipher (compile-time choice: 128 bits). */
+#define MBEDTLS_CTR_DRBG_KEYSIZE            16
+/**< The key size in bytes used by the cipher.
+ *
+ * Compile-time choice: 16 bytes (128 bits)
+ * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled.
+ */
 #else
-#define MBEDTLS_CTR_DRBG_KEYSIZE            32 /**< The key size used by the cipher (compile-time choice: 256 bits). */
+#define MBEDTLS_CTR_DRBG_KEYSIZE            32
+/**< The key size in bytes used by the cipher.
+ *
+ * Compile-time choice: 32 bytes (256 bits)
+ * because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled.
+ */
 #endif
 
 #define MBEDTLS_CTR_DRBG_KEYBITS            ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
@@ -73,21 +106,31 @@
  * \{
  */
 
+/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN
+ *
+ * \brief The amount of entropy used per seed by default, in bytes.
+ */
 #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
 #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
+/** This is 48 bytes because the entropy module uses SHA-512
+ * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled).
+ */
 #define MBEDTLS_CTR_DRBG_ENTROPY_LEN        48
-/**< The amount of entropy used per seed by default:
- * <ul><li>48 with SHA-512.</li>
- * <li>32 with SHA-256.</li></ul>
+
+#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
+
+/** This is 32 bytes because the entropy module uses SHA-256
+ * (the SHA512 module is disabled or
+ * \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled).
  */
-#else
+#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
+/** \warning To achieve a 256-bit security strength, you must pass a nonce
+ *           to mbedtls_ctr_drbg_seed().
+ */
+#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */
 #define MBEDTLS_CTR_DRBG_ENTROPY_LEN        32
-/**< Amount of entropy used per seed by default:
- * <ul><li>48 with SHA-512.</li>
- * <li>32 with SHA-256.</li></ul>
- */
-#endif
-#endif
+#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
+#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
 
 #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
 #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL    10000
@@ -106,7 +149,7 @@
 
 #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
 #define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT     384
-/**< The maximum size of seed or reseed buffer. */
+/**< The maximum size of seed or reseed buffer in bytes. */
 #endif
 
 /* \} name SECTION: Module settings */
@@ -164,17 +207,68 @@
  * \brief               This function seeds and sets up the CTR_DRBG
  *                      entropy source for future reseeds.
  *
- * \note Personalization data can be provided in addition to the more generic
- *       entropy source, to make this instantiation as unique as possible.
+ * A typical choice for the \p f_entropy and \p p_entropy parameters is
+ * to use the entropy module:
+ * - \p f_entropy is mbedtls_entropy_func();
+ * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
+ *   with mbedtls_entropy_init() (which registers the platform's default
+ *   entropy sources).
  *
+ * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
+ * You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
+ *
+ * You can provide a personalization string in addition to the
+ * entropy source, to make this instantiation as unique as possible.
+ *
+ * \note                The _seed_material_ value passed to the derivation
+ *                      function in the CTR_DRBG Instantiate Process
+ *                      described in NIST SP 800-90A §10.2.1.3.2
+ *                      is the concatenation of the string obtained from
+ *                      calling \p f_entropy and the \p custom string.
+ *                      The origin of the nonce depends on the value of
+ *                      the entropy length relative to the security strength.
+ *                      - If the entropy length is at least 1.5 times the
+ *                        security strength then the nonce is taken from the
+ *                        string obtained with \p f_entropy.
+ *                      - If the entropy length is less than the security
+ *                        strength, then the nonce is taken from \p custom.
+ *                        In this case, for compliance with SP 800-90A,
+ *                        you must pass a unique value of \p custom at
+ *                        each invocation. See SP 800-90A §8.6.7 for more
+ *                        details.
+ */
+#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
+/** \warning            When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than
+ *                      #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the
+ *                      maximum security strength permitted by CTR_DRBG,
+ *                      you must pass a value of \p custom that is a nonce:
+ *                      this value must never be repeated in subsequent
+ *                      runs of the same application or on a different
+ *                      device.
+ */
+#endif
+/**
  * \param ctx           The CTR_DRBG context to seed.
+ *                      It must have been initialized with
+ *                      mbedtls_ctr_drbg_init().
+ *                      After a successful call to mbedtls_ctr_drbg_seed(),
+ *                      you may not call mbedtls_ctr_drbg_seed() again on
+ *                      the same context unless you call
+ *                      mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
+ *                      again first.
  * \param f_entropy     The entropy callback, taking as arguments the
  *                      \p p_entropy context, the buffer to fill, and the
-                        length of the buffer.
- * \param p_entropy     The entropy context.
- * \param custom        Personalization data, that is device-specific
-                        identifiers. Can be NULL.
- * \param len           The length of the personalization data.
+ *                      length of the buffer.
+ *                      \p f_entropy is always called with a buffer size
+ *                      equal to the entropy length.
+ * \param p_entropy     The entropy context to pass to \p f_entropy.
+ * \param custom        The personalization string.
+ *                      This can be \c NULL, in which case the personalization
+ *                      string is empty regardless of the value of \p len.
+ * \param len           The length of the personalization string.
+ *                      This must be at most
+ *                      #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
+ *                      - #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
  *
  * \return              \c 0 on success.
  * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
@@ -197,7 +291,8 @@
  *                      The default value is off.
  *
  * \note                If enabled, entropy is gathered at the beginning of
- *                      every call to mbedtls_ctr_drbg_random_with_add().
+ *                      every call to mbedtls_ctr_drbg_random_with_add()
+ *                      or mbedtls_ctr_drbg_random().
  *                      Only use this if your entropy source has sufficient
  *                      throughput.
  *
@@ -209,18 +304,37 @@
 
 /**
  * \brief               This function sets the amount of entropy grabbed on each
- *                      seed or reseed. The default value is
- *                      #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
+ *                      seed or reseed.
+ *
+ * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
+ *
+ * \note                The security strength of CTR_DRBG is bounded by the
+ *                      entropy length. Thus:
+ *                      - When using AES-256
+ *                        (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled,
+ *                        which is the default),
+ *                        \p len must be at least 32 (in bytes)
+ *                        to achieve a 256-bit strength.
+ *                      - When using AES-128
+ *                        (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled)
+ *                        \p len must be at least 16 (in bytes)
+ *                        to achieve a 128-bit strength.
  *
  * \param ctx           The CTR_DRBG context.
- * \param len           The amount of entropy to grab.
+ * \param len           The amount of entropy to grab, in bytes.
+ *                      This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
  */
 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
                                size_t len );
 
 /**
  * \brief               This function sets the reseed interval.
- *                      The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
+ *
+ * The reseed interval is the number of calls to mbedtls_ctr_drbg_random()
+ * or mbedtls_ctr_drbg_random_with_add() after which the entropy function
+ * is called again.
+ *
+ * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
  *
  * \param ctx           The CTR_DRBG context.
  * \param interval      The reseed interval.
@@ -233,8 +347,12 @@
  *                      extracts data from the entropy source.
  *
  * \param ctx           The CTR_DRBG context.
- * \param additional    Additional data to add to the state. Can be NULL.
+ * \param additional    Additional data to add to the state. Can be \c NULL.
  * \param len           The length of the additional data.
+ *                      This must be less than
+ *                      #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
+ *                      where \c entropy_len is the entropy length
+ *                      configured for the context.
  *
  * \return              \c 0 on success.
  * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
@@ -246,7 +364,8 @@
  * \brief              This function updates the state of the CTR_DRBG context.
  *
  * \param ctx          The CTR_DRBG context.
- * \param additional   The data to update the state with.
+ * \param additional   The data to update the state with. This must not be
+ *                     \c NULL unless \p add_len is \c 0.
  * \param add_len      Length of \p additional in bytes. This must be at
  *                     most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
  *
@@ -264,14 +383,23 @@
  * \brief   This function updates a CTR_DRBG instance with additional
  *          data and uses it to generate random data.
  *
- * \note    The function automatically reseeds if the reseed counter is exceeded.
+ * This function automatically reseeds if the reseed counter is exceeded
+ * or prediction resistance is enabled.
  *
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
- * \param output_len    The length of the buffer.
- * \param additional    Additional data to update. Can be NULL.
- * \param add_len       The length of the additional data.
+ * \param output_len    The length of the buffer in bytes.
+ * \param additional    Additional data to update. Can be \c NULL, in which
+ *                      case the additional data is empty regardless of
+ *                      the value of \p add_len.
+ * \param add_len       The length of the additional data
+ *                      if \p additional is not \c NULL.
+ *                      This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT
+ *                      and less than
+ *                      #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
+ *                      where \c entropy_len is the entropy length
+ *                      configured for the context.
  *
  * \return    \c 0 on success.
  * \return    #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
@@ -284,12 +412,14 @@
 /**
  * \brief   This function uses CTR_DRBG to generate random data.
  *
- * \note    The function automatically reseeds if the reseed counter is exceeded.
+ * This function automatically reseeds if the reseed counter is exceeded
+ * or prediction resistance is enabled.
+ *
  *
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
- * \param output_len    The length of the buffer.
+ * \param output_len    The length of the buffer in bytes.
  *
  * \return              \c 0 on success.
  * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
@@ -336,7 +466,7 @@
  *
  * \return              \c 0 on success.
  * \return              #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
- * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed
  *                      failure.
  */
 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
@@ -350,8 +480,10 @@
  *
  * \return              \c 0 on success.
  * \return              #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
- * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
- *                      #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
+ *                      reseed failure.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing
+ *                      seed file is too large.
  */
 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
 #endif /* MBEDTLS_FS_IO */
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ecdsa.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ecdsa.h
index f8b2850..932acc6 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ecdsa.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ecdsa.h
@@ -175,6 +175,19 @@
  *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
  *                  4.1.3, step 5.
  *
+ * \warning         Since the output of the internal RNG is always the same for
+ *                  the same key and message, this limits the efficiency of
+ *                  blinding and leaks information through side channels. For
+ *                  secure behavior use mbedtls_ecdsa_sign_det_ext() instead.
+ *
+ *                  (Optimally the blinding is a random value that is different
+ *                  on every execution. In this case the blinding is still
+ *                  random from the attackers perspective, but is the same on
+ *                  each execution. This means that this blinding does not
+ *                  prevent attackers from recovering secrets by combining
+ *                  several measurement traces, but may prevent some attacks
+ *                  that exploit relationships between secret data.)
+ *
  * \see             ecp.h
  *
  * \param grp       The context for the elliptic curve to use.
@@ -200,6 +213,52 @@
                             mbedtls_mpi *s, const mbedtls_mpi *d,
                             const unsigned char *buf, size_t blen,
                             mbedtls_md_type_t md_alg );
+/**
+ * \brief           This function computes the ECDSA signature of a
+ *                  previously-hashed message, deterministic version.
+ *
+ *                  For more information, see <em>RFC-6979: Deterministic
+ *                  Usage of the Digital Signature Algorithm (DSA) and Elliptic
+ *                  Curve Digital Signature Algorithm (ECDSA)</em>.
+ *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
+ * \param grp           The context for the elliptic curve to use.
+ *                      This must be initialized and have group parameters
+ *                      set, for example through mbedtls_ecp_group_load().
+ * \param r             The MPI context in which to store the first part
+ *                      the signature. This must be initialized.
+ * \param s             The MPI context in which to store the second part
+ *                      the signature. This must be initialized.
+ * \param d             The private signing key. This must be initialized
+ *                      and setup, for example through mbedtls_ecp_gen_privkey().
+ * \param buf           The hashed content to be signed. This must be a readable
+ *                      buffer of length \p blen Bytes. It may be \c NULL if
+ *                      \p blen is zero.
+ * \param blen          The length of \p buf in Bytes.
+ * \param md_alg        The hash algorithm used to hash the original data.
+ * \param f_rng_blind   The RNG function used for blinding. This must not be
+ *                      \c NULL.
+ * \param p_rng_blind   The RNG context to be passed to \p f_rng. This may be
+ *                      \c NULL if \p f_rng doesn't need a context parameter.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ *                  error code on failure.
+ */
+int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+                                mbedtls_mpi *s, const mbedtls_mpi *d,
+                                const unsigned char *buf, size_t blen,
+                                mbedtls_md_type_t md_alg,
+                                int (*f_rng_blind)(void *, unsigned char *,
+                                                   size_t),
+                                void *p_rng_blind );
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
 /**
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ecp.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ecp.h
index 065a4cc..361fd0b 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ecp.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ecp.h
@@ -317,7 +317,10 @@
 #define MBEDTLS_ECP_BUDGET( ops )   /* no-op; for compatibility */
 
 /* We want to declare restartable versions of existing functions anyway */
+#if !defined(MBEDTLS_ECP_RESTART_CTX_DECLARED)
+#define MBEDTLS_ECP_RESTART_CTX_DECLARED
 typedef void mbedtls_ecp_restart_ctx;
+#endif /* MBEDTLS_ECP_RESTART_CTX_DECLARED */
 
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/hkdf.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/hkdf.h
index 40ee64e..bcafe42 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/hkdf.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/hkdf.h
@@ -7,22 +7,22 @@
  *          specified by RFC 5869.
  */
 /*
- * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
+ *  Copyright (C) 2016-2019, ARM Limited, 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
+ *  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
+ *  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.
+ *  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.
  *
- * This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 #ifndef MBEDTLS_HKDF_H
 #define MBEDTLS_HKDF_H
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/hmac_drbg.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/hmac_drbg.h
index 7eae32b..7931c22 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/hmac_drbg.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/hmac_drbg.h
@@ -1,10 +1,14 @@
 /**
  * \file hmac_drbg.h
  *
- * \brief HMAC_DRBG (NIST SP 800-90A)
+ * \brief The HMAC_DRBG pseudorandom generator.
+ *
+ * This module implements the HMAC_DRBG pseudorandom generator described
+ * in <em>NIST SP 800-90A: Recommendation for Random Number Generation Using
+ * Deterministic Random Bit Generators</em>.
  */
 /*
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2019, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -82,7 +86,7 @@
  */
 typedef struct mbedtls_hmac_drbg_context
 {
-    /* Working state: the key K is not stored explicitely,
+    /* Working state: the key K is not stored explicitly,
      * but is implied by the HMAC context */
     mbedtls_md_context_t md_ctx;                    /*!< HMAC context (inc. K)  */
     unsigned char V[MBEDTLS_MD_MAX_SIZE];  /*!< V in the spec          */
@@ -104,38 +108,72 @@
 } mbedtls_hmac_drbg_context;
 
 /**
- * \brief               HMAC_DRBG context initialization
- *                      Makes the context ready for mbedtls_hmac_drbg_seed(),
- *                      mbedtls_hmac_drbg_seed_buf() or
- *                      mbedtls_hmac_drbg_free().
+ * \brief               HMAC_DRBG context initialization.
  *
- * \param ctx           HMAC_DRBG context to be initialized
+ * This function makes the context ready for mbedtls_hmac_drbg_seed(),
+ * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
+ *
+ * \param ctx           HMAC_DRBG context to be initialized.
  */
 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
 
 /**
- * \brief               HMAC_DRBG initial seeding
- *                      Seed and setup entropy source for future reseeds.
+ * \brief               HMAC_DRBG initial seeding.
  *
- * \param ctx           HMAC_DRBG context to be seeded
- * \param md_info       MD algorithm to use for HMAC_DRBG
- * \param f_entropy     Entropy callback (p_entropy, buffer to fill, buffer
- *                      length)
- * \param p_entropy     Entropy context
- * \param custom        Personalization data (Device specific identifiers)
- *                      (Can be NULL)
- * \param len           Length of personalization data
+ * Set the initial seed and set up the entropy source for future reseeds.
  *
- * \note                The "security strength" as defined by NIST is set to:
- *                      128 bits if md_alg is SHA-1,
- *                      192 bits if md_alg is SHA-224,
- *                      256 bits if md_alg is SHA-256 or higher.
+ * A typical choice for the \p f_entropy and \p p_entropy parameters is
+ * to use the entropy module:
+ * - \p f_entropy is mbedtls_entropy_func();
+ * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
+ *   with mbedtls_entropy_init() (which registers the platform's default
+ *   entropy sources).
+ *
+ * You can provide a personalization string in addition to the
+ * entropy source, to make this instantiation as unique as possible.
+ *
+ * \note                By default, the security strength as defined by NIST is:
+ *                      - 128 bits if \p md_info is SHA-1;
+ *                      - 192 bits if \p md_info is SHA-224;
+ *                      - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512.
  *                      Note that SHA-256 is just as efficient as SHA-224.
+ *                      The security strength can be reduced if a smaller
+ *                      entropy length is set with
+ *                      mbedtls_hmac_drbg_set_entropy_len().
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
- *                      MBEDTLS_ERR_MD_ALLOC_FAILED, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED.
+ * \note                The default entropy length is the security strength
+ *                      (converted from bits to bytes). You can override
+ *                      it by calling mbedtls_hmac_drbg_set_entropy_len().
+ *
+ * \note                During the initial seeding, this function calls
+ *                      the entropy source to obtain a nonce
+ *                      whose length is half the entropy length.
+ *
+ * \param ctx           HMAC_DRBG context to be seeded.
+ * \param md_info       MD algorithm to use for HMAC_DRBG.
+ * \param f_entropy     The entropy callback, taking as arguments the
+ *                      \p p_entropy context, the buffer to fill, and the
+ *                      length of the buffer.
+ *                      \p f_entropy is always called with a length that is
+ *                      less than or equal to the entropy length.
+ * \param p_entropy     The entropy context to pass to \p f_entropy.
+ * \param custom        The personalization string.
+ *                      This can be \c NULL, in which case the personalization
+ *                      string is empty regardless of the value of \p len.
+ * \param len           The length of the personalization string.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
+ *                      and also at most
+ *                      #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2
+ *                      where \p entropy_len is the entropy length
+ *                      described above.
+ *
+ * \return              \c 0 if successful.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
+ *                      invalid.
+ * \return              #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
+ *                      memory to allocate context data.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ *                      if the call to \p f_entropy failed.
  */
 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
                     const mbedtls_md_info_t * md_info,
@@ -146,98 +184,131 @@
 
 /**
  * \brief               Initilisation of simpified HMAC_DRBG (never reseeds).
- *                      (For use with deterministic ECDSA.)
  *
- * \param ctx           HMAC_DRBG context to be initialised
- * \param md_info       MD algorithm to use for HMAC_DRBG
- * \param data          Concatenation of entropy string and additional data
- * \param data_len      Length of data in bytes
+ * This function is meant for use in algorithms that need a pseudorandom
+ * input such as deterministic ECDSA.
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
- *                      MBEDTLS_ERR_MD_ALLOC_FAILED.
+ * \param ctx           HMAC_DRBG context to be initialised.
+ * \param md_info       MD algorithm to use for HMAC_DRBG.
+ * \param data          Concatenation of the initial entropy string and
+ *                      the additional data.
+ * \param data_len      Length of \p data in bytes.
+ *
+ * \return              \c 0 if successful. or
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
+ *                      invalid.
+ * \return              #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
+ *                      memory to allocate context data.
  */
 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
                         const mbedtls_md_info_t * md_info,
                         const unsigned char *data, size_t data_len );
 
 /**
- * \brief               Enable / disable prediction resistance (Default: Off)
+ * \brief               This function turns prediction resistance on or off.
+ *                      The default value is off.
  *
- * Note: If enabled, entropy is used for ctx->entropy_len before each call!
- *       Only use this if you have ample supply of good entropy!
+ * \note                If enabled, entropy is gathered at the beginning of
+ *                      every call to mbedtls_hmac_drbg_random_with_add()
+ *                      or mbedtls_hmac_drbg_random().
+ *                      Only use this if your entropy source has sufficient
+ *                      throughput.
  *
- * \param ctx           HMAC_DRBG context
- * \param resistance    MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF
+ * \param ctx           The HMAC_DRBG context.
+ * \param resistance    #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF.
  */
 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
                                           int resistance );
 
 /**
- * \brief               Set the amount of entropy grabbed on each reseed
- *                      (Default: given by the security strength, which
- *                      depends on the hash used, see \c mbedtls_hmac_drbg_init() )
+ * \brief               This function sets the amount of entropy grabbed on each
+ *                      seed or reseed.
  *
- * \param ctx           HMAC_DRBG context
- * \param len           Amount of entropy to grab, in bytes
+ * See the documentation of mbedtls_hmac_drbg_seed() for the default value.
+ *
+ * \param ctx           The HMAC_DRBG context.
+ * \param len           The amount of entropy to grab, in bytes.
  */
 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
                                 size_t len );
 
 /**
- * \brief               Set the reseed interval
- *                      (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
+ * \brief               Set the reseed interval.
  *
- * \param ctx           HMAC_DRBG context
- * \param interval      Reseed interval
+ * The reseed interval is the number of calls to mbedtls_hmac_drbg_random()
+ * or mbedtls_hmac_drbg_random_with_add() after which the entropy function
+ * is called again.
+ *
+ * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL.
+ *
+ * \param ctx           The HMAC_DRBG context.
+ * \param interval      The reseed interval.
  */
 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
                                     int interval );
 
 /**
- * \brief               HMAC_DRBG update state
+ * \brief               This function updates the state of the HMAC_DRBG context.
  *
- * \param ctx           HMAC_DRBG context
- * \param additional    Additional data to update state with, or NULL
- * \param add_len       Length of additional data, or 0
+ * \param ctx           The HMAC_DRBG context.
+ * \param additional    The data to update the state with.
+ *                      If this is \c NULL, there is no additional data.
+ * \param add_len       Length of \p additional in bytes.
+ *                      Unused if \p additional is \c NULL.
  *
  * \return              \c 0 on success, or an error from the underlying
  *                      hash calculation.
- *
- * \note                Additional data is optional, pass NULL and 0 as second
- *                      third argument if no additional data is being used.
  */
 int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
                        const unsigned char *additional, size_t add_len );
 
 /**
- * \brief               HMAC_DRBG reseeding (extracts data from entropy source)
+ * \brief               This function reseeds the HMAC_DRBG context, that is
+ *                      extracts data from the entropy source.
  *
- * \param ctx           HMAC_DRBG context
- * \param additional    Additional data to add to state (Can be NULL)
- * \param len           Length of additional data
+ * \param ctx           The HMAC_DRBG context.
+ * \param additional    Additional data to add to the state.
+ *                      If this is \c NULL, there is no additional data
+ *                      and \p len should be \c 0.
+ * \param len           The length of the additional data.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
+ *                      and also at most
+ *                      #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len
+ *                      where \p entropy_len is the entropy length
+ *                      (see mbedtls_hmac_drbg_set_entropy_len()).
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ * \return              \c 0 if successful.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ *                      if a call to the entropy function failed.
  */
 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
                       const unsigned char *additional, size_t len );
 
 /**
- * \brief               HMAC_DRBG generate random with additional update input
+ * \brief   This function updates an HMAC_DRBG instance with additional
+ *          data and uses it to generate random data.
  *
- * Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
+ * This function automatically reseeds if the reseed counter is exceeded
+ * or prediction resistance is enabled.
  *
- * \param p_rng         HMAC_DRBG context
- * \param output        Buffer to fill
- * \param output_len    Length of the buffer
- * \param additional    Additional data to update with (can be NULL)
- * \param add_len       Length of additional data (can be 0)
+ * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
+ *                      #mbedtls_hmac_drbg_context structure.
+ * \param output        The buffer to fill.
+ * \param output_len    The length of the buffer in bytes.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
+ * \param additional    Additional data to update with.
+ *                      If this is \c NULL, there is no additional data
+ *                      and \p add_len should be \c 0.
+ * \param add_len       The length of the additional data.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT.
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
- *                      MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or
- *                      MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG.
+ * \return              \c 0 if successful.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ *                      if a call to the entropy source failed.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
+ *                      \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if
+ *                      \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT.
  */
 int mbedtls_hmac_drbg_random_with_add( void *p_rng,
                                unsigned char *output, size_t output_len,
@@ -245,24 +316,29 @@
                                size_t add_len );
 
 /**
- * \brief               HMAC_DRBG generate random
+ * \brief   This function uses HMAC_DRBG to generate random data.
  *
- * Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
+ * This function automatically reseeds if the reseed counter is exceeded
+ * or prediction resistance is enabled.
  *
- * \param p_rng         HMAC_DRBG context
- * \param output        Buffer to fill
- * \param out_len       Length of the buffer
+ * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
+ *                      #mbedtls_hmac_drbg_context structure.
+ * \param output        The buffer to fill.
+ * \param out_len       The length of the buffer in bytes.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
- *                      MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG
+ * \return              \c 0 if successful.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ *                      if a call to the entropy source failed.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
+ *                      \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
  */
 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
 
 /**
  * \brief               Free an HMAC_DRBG context
  *
- * \param ctx           HMAC_DRBG context to free.
+ * \param ctx           The HMAC_DRBG context to free.
  */
 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
 
@@ -273,17 +349,16 @@
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief               HMAC_DRBG update state
+ * \brief               This function updates the state of the HMAC_DRBG context.
  *
  * \deprecated          Superseded by mbedtls_hmac_drbg_update_ret()
  *                      in 2.16.0.
  *
- * \param ctx           HMAC_DRBG context
- * \param additional    Additional data to update state with, or NULL
- * \param add_len       Length of additional data, or 0
- *
- * \note                Additional data is optional, pass NULL and 0 as second
- *                      third argument if no additional data is being used.
+ * \param ctx           The HMAC_DRBG context.
+ * \param additional    The data to update the state with.
+ *                      If this is \c NULL, there is no additional data.
+ * \param add_len       Length of \p additional in bytes.
+ *                      Unused if \p additional is \c NULL.
  */
 MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
     mbedtls_hmac_drbg_context *ctx,
@@ -293,26 +368,31 @@
 
 #if defined(MBEDTLS_FS_IO)
 /**
- * \brief               Write a seed file
+ * \brief               This function writes a seed file.
  *
- * \param ctx           HMAC_DRBG context
- * \param path          Name of the file
+ * \param ctx           The HMAC_DRBG context.
+ * \param path          The name of the file.
  *
- * \return              0 if successful, 1 on file error, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed
+ *                      failure.
  */
 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
 
 /**
- * \brief               Read and update a seed file. Seed is added to this
- *                      instance
+ * \brief               This function reads and updates a seed file. The seed
+ *                      is added to this instance.
  *
- * \param ctx           HMAC_DRBG context
- * \param path          Name of the file
+ * \param ctx           The HMAC_DRBG context.
+ * \param path          The name of the file.
  *
- * \return              0 if successful, 1 on file error,
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or
- *                      MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on
+ *                      reseed failure.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing
+ *                      seed file is too large.
  */
 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
 #endif /* MBEDTLS_FS_IO */
@@ -320,9 +400,10 @@
 
 #if defined(MBEDTLS_SELF_TEST)
 /**
- * \brief               Checkup routine
+ * \brief               The HMAC_DRBG Checkup routine.
  *
- * \return              0 if successful, or 1 if the test failed
+ * \return              \c 0 if successful.
+ * \return              \c 1 if the test failed.
  */
 int mbedtls_hmac_drbg_self_test( int verbose );
 #endif
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/pk.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/pk.h
index 91950f9..1364275 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/pk.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/pk.h
@@ -416,6 +416,10 @@
  *
  * \note            For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
  *                  For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
+ *
+ * \note            In order to ensure enough space for the signature, the
+ *                  \p sig buffer size must be of at least
+ *                  `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes.
  */
 int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
              const unsigned char *hash, size_t hash_len,
@@ -430,6 +434,10 @@
  *                  \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
  *                  operations. For RSA, same as \c mbedtls_pk_sign().
  *
+ * \note            In order to ensure enough space for the signature, the
+ *                  \p sig buffer size must be of at least
+ *                  `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes.
+ *
  * \param ctx       The PK context to use. It must have been set up
  *                  with a private key.
  * \param md_alg    Hash algorithm used (see notes)
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/platform_util.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/platform_util.h
index dba6d45..09d0965 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/platform_util.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/platform_util.h
@@ -43,6 +43,12 @@
 
 #if defined(MBEDTLS_CHECK_PARAMS)
 
+#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert
+ * (which is what our config.h suggests). */
+#include <assert.h>
+#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
+
 #if defined(MBEDTLS_PARAM_FAILED)
 /** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
  *
@@ -50,6 +56,11 @@
  * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
  */
 #define MBEDTLS_PARAM_FAILED_ALT
+
+#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
+#define MBEDTLS_PARAM_FAILED_ALT
+
 #else /* MBEDTLS_PARAM_FAILED */
 #define MBEDTLS_PARAM_FAILED( cond ) \
     mbedtls_param_failed( #cond, __FILE__, __LINE__ )
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/poly1305_alt.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/poly1305_alt.h
new file mode 100644
index 0000000..c9fffad
--- /dev/null
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/poly1305_alt.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause OR Arm’s non-OSI source license
+ */
+
+#ifndef MBEDTLS_POLY1305_ALT_H
+#define MBEDTLS_POLY1305_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if defined(MBEDTLS_POLY1305_ALT)
+
+/************************ defines  ****************************/
+/*! The size of the POLY key in words. */
+#define MBEDTLS_POLY_KEY_SIZE_WORDS       8
+
+/*! The size of the POLY key in bytes. */
+#define MBEDTLS_POLY_KEY_SIZE_BYTES       32
+
+/*! The size of the POLY MAC in words. */
+#define MBEDTLS_POLY_MAC_SIZE_WORDS       4
+
+/*! The size of the POLY MAC in bytes. */
+#define MBEDTLS_POLY_MAC_SIZE_BYTES       16
+
+/************************ Typedefs  ****************************/
+/*! The definition of the ChaCha-MAC buffer. */
+typedef uint32_t mbedtls_poly_mac[MBEDTLS_POLY_MAC_SIZE_WORDS];
+
+/*! The definition of the ChaCha-key buffer. */
+typedef uint32_t mbedtls_poly_key[MBEDTLS_POLY_KEY_SIZE_WORDS];
+
+typedef struct mbedtls_poly1305_context
+{
+    uint32_t r[4];      /** The value for 'r' (low 128 bits of the key). */
+    uint32_t s[4];      /** The value for 's' (high 128 bits of the key). */
+    uint32_t acc[5];    /** The accumulator number. */
+    uint8_t queue[16];  /** The current partial block of data. */
+    size_t queue_len;   /** The number of bytes stored in 'queue'. */
+}
+mbedtls_poly1305_context;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MBEDTLS_POLY1305_ALT_H */
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/rsa.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/rsa.h
index 906c427..35bacd8 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/rsa.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/rsa.h
@@ -150,13 +150,13 @@
  * \note           The choice of padding mode is strictly enforced for private key
  *                 operations, since there might be security concerns in
  *                 mixing padding modes. For public key operations it is
- *                 a default value, which can be overriden by calling specific
+ *                 a default value, which can be overridden by calling specific
  *                 \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions.
  *
  * \note           The hash selected in \p hash_id is always used for OEAP
  *                 encryption. For PSS signatures, it is always used for
- *                 making signatures, but can be overriden for verifying them.
- *                 If set to #MBEDTLS_MD_NONE, it is always overriden.
+ *                 making signatures, but can be overridden for verifying them.
+ *                 If set to #MBEDTLS_MD_NONE, it is always overridden.
  *
  * \param ctx      The RSA context to initialize. This must not be \c NULL.
  * \param padding  The padding mode to use. This must be either
@@ -904,7 +904,8 @@
  *                 the size of the hash corresponding to \p md_alg.
  * \param sig      The buffer to hold the signature. This must be a writable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
- *                 for an 2048-bit RSA modulus.
+ *                 for an 2048-bit RSA modulus. A buffer length of
+ *                 #MBEDTLS_MPI_MAX_SIZE is always safe.
  *
  * \return         \c 0 if the signing operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -951,7 +952,8 @@
  *                 the size of the hash corresponding to \p md_alg.
  * \param sig      The buffer to hold the signature. This must be a writable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
- *                 for an 2048-bit RSA modulus.
+ *                 for an 2048-bit RSA modulus. A buffer length of
+ *                 #MBEDTLS_MPI_MAX_SIZE is always safe.
  *
  * \return         \c 0 if the signing operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -1012,7 +1014,8 @@
  *                 the size of the hash corresponding to \p md_alg.
  * \param sig      The buffer to hold the signature. This must be a writable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
- *                 for an 2048-bit RSA modulus.
+ *                 for an 2048-bit RSA modulus. A buffer length of
+ *                 #MBEDTLS_MPI_MAX_SIZE is always safe.
  *
  * \return         \c 0 if the signing operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/sha1_alt.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/sha1_alt.h
new file mode 100644
index 0000000..2d6cbaf
--- /dev/null
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/sha1_alt.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause OR Arm’s non-OSI source license
+ */
+
+#ifndef MBEDTLS_SHA1_ALT_H
+#define MBEDTLS_SHA1_ALT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined (MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined (MBEDTLS_SHA1_ALT)
+
+#define CC_HASH_USER_CTX_SIZE_IN_WORDS 60
+
+#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          SHA-1 context structure
+ */
+typedef struct mbedtls_sha1_context {
+        /*! Internal buffer */
+        uint32_t buff[CC_HASH_USER_CTX_SIZE_IN_WORDS]; // defined in cc_hash_defs_proj.h
+} mbedtls_sha1_context;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*  MBEDTLS_SHA1_ALT  */
+
+#endif /* MBEDTLS_SHA1_ALT_H */
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ssl.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ssl.h
index d31f6cd..1adf960 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ssl.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ssl.h
@@ -2033,7 +2033,7 @@
  *                 provision more than one cert/key pair (eg one ECDSA, one
  *                 RSA with SHA-256, one RSA with SHA-1). An adequate
  *                 certificate will be selected according to the client's
- *                 advertised capabilities. In case mutliple certificates are
+ *                 advertised capabilities. In case multiple certificates are
  *                 adequate, preference is given to the one set by the first
  *                 call to this function, then second, etc.
  *
@@ -3206,7 +3206,7 @@
  *                 mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free().
  *
  * \note           You need to call mbedtls_ssl_config_defaults() unless you
- *                 manually set all of the relevent fields yourself.
+ *                 manually set all of the relevant fields yourself.
  *
  * \param conf     SSL configuration context
  */
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ssl_ticket.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ssl_ticket.h
index a84e781..774a007 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ssl_ticket.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/ssl_ticket.h
@@ -117,14 +117,14 @@
 /**
  * \brief           Implementation of the ticket write callback
  *
- * \note            See \c mbedlts_ssl_ticket_write_t for description
+ * \note            See \c mbedtls_ssl_ticket_write_t for description
  */
 mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write;
 
 /**
  * \brief           Implementation of the ticket parse callback
  *
- * \note            See \c mbedlts_ssl_ticket_parse_t for description
+ * \note            See \c mbedtls_ssl_ticket_parse_t for description
  */
 mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse;
 
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/version.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/version.h
index ef8e4c1..b4eef71 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/version.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/version.h
@@ -40,16 +40,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  2
 #define MBEDTLS_VERSION_MINOR  16
-#define MBEDTLS_VERSION_PATCH  2
+#define MBEDTLS_VERSION_PATCH  3
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02100200
-#define MBEDTLS_VERSION_STRING         "2.16.2"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.2"
+#define MBEDTLS_VERSION_NUMBER         0x02100300
+#define MBEDTLS_VERSION_STRING         "2.16.3"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.3"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/x509.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/x509.h
index 9ae825c..63aae32 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/x509.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/x509.h
@@ -77,7 +77,7 @@
 #define MBEDTLS_ERR_X509_ALLOC_FAILED                     -0x2880  /**< Allocation of memory failed. */
 #define MBEDTLS_ERR_X509_FILE_IO_ERROR                    -0x2900  /**< Read/write of file failed. */
 #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL                 -0x2980  /**< Destination buffer is too small. */
-#define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000  /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */
+#define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000  /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */
 /* \} name */
 
 /**
@@ -250,7 +250,7 @@
  *
  * \param to       mbedtls_x509_time to check
  *
- * \return         1 if the given time is in the past or an error occured,
+ * \return         1 if the given time is in the past or an error occurred,
  *                 0 otherwise.
  */
 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to );
@@ -264,7 +264,7 @@
  *
  * \param from     mbedtls_x509_time to check
  *
- * \return         1 if the given time is in the future or an error occured,
+ * \return         1 if the given time is in the future or an error occurred,
  *                 0 otherwise.
  */
 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/x509_crl.h b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/x509_crl.h
index 08a4283..fa838d6 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/x509_crl.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/include/mbedtls/x509_crl.h
@@ -111,7 +111,7 @@
 /**
  * \brief          Parse one or more CRLs and append them to the chained list
  *
- * \note           Mutliple CRLs are accepted only if using PEM format
+ * \note           Multiple CRLs are accepted only if using PEM format
  *
  * \param chain    points to the start of the chain
  * \param buf      buffer holding the CRL data in PEM or DER format
@@ -126,7 +126,7 @@
 /**
  * \brief          Load one or more CRLs and append them to the chained list
  *
- * \note           Mutliple CRLs are accepted only if using PEM format
+ * \note           Multiple CRLs are accepted only if using PEM format
  *
  * \param chain    points to the start of the chain
  * \param path     filename to read the CRLs from (in PEM or DER encoding)
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_cc310_backend.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_cc310_backend.a
index 8ce36c0..d416af7 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_cc310_backend.a
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_cc310_backend.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue.a
index 4b50d30..12bae79 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue.a
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_cc310.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_cc310.a
index 7638c6a..697b349 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_cc310.a
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_cc310.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_vanilla.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_vanilla.a
index fdf857e..643eb12 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_vanilla.a
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_glue_vanilla.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_vanilla_backend.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_vanilla_backend.a
index ebbdcd4..721f151 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_vanilla_backend.a
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedcrypto_vanilla_backend.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_base_vanilla.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_base_vanilla.a
index 377cea9..89e41b9 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_base_vanilla.a
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_base_vanilla.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_tls_vanilla.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_tls_vanilla.a
index b2f1adf..26f030c 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_tls_vanilla.a
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_tls_vanilla.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_x509_vanilla.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_x509_vanilla.a
index 77b0385..105503a 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_x509_vanilla.a
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libmbedtls_x509_vanilla.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.1.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.1.a
deleted file mode 100644
index 7ca2e31..0000000
--- a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.1.a
+++ /dev/null
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.2.a b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.2.a
new file mode 100644
index 0000000..de3c73b
--- /dev/null
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/lib/libnrf_cc310_platform_0.9.2.a
Binary files differ
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config/nrf52833-mbedtls-config.h b/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config/nrf52833-mbedtls-config.h
index 90672cf..d519e7b 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config/nrf52833-mbedtls-config.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config/nrf52833-mbedtls-config.h
@@ -29,6 +29,8 @@
 #ifndef NRF52833_MBEDTLS_CONFIG_H_
 #define NRF52833_MBEDTLS_CONFIG_H_
 
+#define MBEDTLS_PK_WRITE_C
+
 #if defined(__ICCARM__)
     _Pragma("diag_suppress=Pe550")
 #endif
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config/nrf52840-mbedtls-config.h b/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config/nrf52840-mbedtls-config.h
index 88aded9..bbec893 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config/nrf52840-mbedtls-config.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/mbedtls_plat_config/nrf52840-mbedtls-config.h
@@ -29,6 +29,8 @@
 #ifndef NRF52840_MBEDTLS_CONFIG_H_
 #define NRF52840_MBEDTLS_CONFIG_H_
 
+#define MBEDTLS_PK_WRITE_C
+
 #include <openthread/config.h>
 
 #if defined(__ICCARM__)
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_plat/include/nrf_cc310_platform.h b/third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_plat/include/nrf_cc310_platform.h
index 0df7658..a34e4f4 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_plat/include/nrf_cc310_platform.h
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_plat/include/nrf_cc310_platform.h
@@ -70,6 +70,15 @@
  */
 bool nrf_cc310_platform_rng_is_initialized(void);
 
+
+/** @brief ISR Function for processing of CC310 Interrupts.
+ *         This CC310 interrupt service routine function should be called for
+ *         interrupt processing.
+ *         Either by placing this functions directly in the vector table or by
+ *         calling it from the ISR in the OS.
+ */
+void CRYPTOCELL_IRQHandler(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_plat/src/nrf_cc310_platform_abort_zephyr.c b/third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_plat/src/nrf_cc310_platform_abort_zephyr.c
index 7df6106..ec18630 100644
--- a/third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_plat/src/nrf_cc310_platform_abort_zephyr.c
+++ b/third_party/NordicSemiconductor/libraries/nrf_security/nrf_cc310_plat/src/nrf_cc310_platform_abort_zephyr.c
@@ -5,7 +5,7 @@
  * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
  */
 #include <kernel.h>
-#include <misc/reboot.h>
+#include <power/reboot.h>
 //#include <logging/log.h>
 //LOG_MODULE_DECLARE(cc310_platform);
 
diff --git a/third_party/NordicSemiconductor/nrfx/hal/nrf_ficr.h b/third_party/NordicSemiconductor/nrfx/hal/nrf_ficr.h
index 40b5698..c5016d1 100644
--- a/third_party/NordicSemiconductor/nrfx/hal/nrf_ficr.h
+++ b/third_party/NordicSemiconductor/nrfx/hal/nrf_ficr.h
@@ -123,16 +123,12 @@
     switch(tagheader_id) {
         case 0:
             return p_reg->NFC.TAGHEADER0;
-            break;
         case 1:
             return p_reg->NFC.TAGHEADER1;
-            break;
         case 2:
             return p_reg->NFC.TAGHEADER2;
-            break;
         case 3:
             return p_reg->NFC.TAGHEADER3;
-            break;
         default:
             return 0;
     }
diff --git a/third_party/Qorvo/CMakeLists.txt b/third_party/Qorvo/CMakeLists.txt
new file mode 100644
index 0000000..32d7cf6
--- /dev/null
+++ b/third_party/Qorvo/CMakeLists.txt
@@ -0,0 +1,34 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_library(qpg6095-driver INTERFACE)
+
+target_link_libraries(qpg6095-driver
+    INTERFACE
+        ${CMAKE_CURRENT_SOURCE_DIR}/qpg6095/libQorvoQPG6095.a
+)
diff --git a/third_party/jlink/Makefile.am b/third_party/jlink/Makefile.am
index 16e3aa6..ac4f36d 100644
--- a/third_party/jlink/Makefile.am
+++ b/third_party/jlink/Makefile.am
@@ -32,6 +32,10 @@
 override CFLAGS                                      := $(filter-out -Wundef,$(CFLAGS))
 override CXXFLAGS                                    := $(filter-out -Wundef,$(CXXFLAGS))
 
+# Do not enable -Wcast-align for jlink library
+override CFLAGS                                      := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                                    := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 lib_LIBRARIES                                             = libjlinkrtt.a
 
 libjlinkrtt_a_CPPFLAGS                                    = \
@@ -47,15 +51,18 @@
     SEGGER_RTT_V640/RTT/SEGGER_RTT_Conf.h                   \
     $(NULL)
 
-if OPENTHREAD_EXAMPLES_NRF52840
+if OPENTHREAD_EXAMPLES_NRF52811
 libjlinkrtt_a_CPPFLAGS                                                                                 += \
-    -DNRF52840_XXAA                                                                                       \
+    -DNRF52811_XXAA                                                                                       \
     -DSEGGER_RTT_CONFIG_H=\"$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT_Conf.h\"  \
+    -DUSE_APP_CONFIG=1                                                                                    \
     -I$(top_srcdir)/include                                                                               \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                 \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config                                                \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52811/config                                \
     -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                          \
     -I$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error                                   \
     -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk                                              \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                 \
     $(NULL)
 endif
 
@@ -63,21 +70,29 @@
 libjlinkrtt_a_CPPFLAGS                                                                                 += \
     -DNRF52833_XXAA                                                                                       \
     -DSEGGER_RTT_CONFIG_H=\"$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT_Conf.h\"  \
+    -DUSE_APP_CONFIG=1                                                                                    \
     -I$(top_srcdir)/include                                                                               \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                 \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config                                                \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52833/config                                \
     -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                          \
     -I$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error                                   \
     -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk                                              \
-    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                 \
     $(NULL)
 endif
 
-if OPENTHREAD_EXAMPLES_NRF52811
+if OPENTHREAD_EXAMPLES_NRF52840
 libjlinkrtt_a_CPPFLAGS                                                                                 += \
-    -DNRF52811_XXAA                                                                                       \
+    -DNRF52840_XXAA                                                                                       \
     -DSEGGER_RTT_CONFIG_H=\"$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT_Conf.h\"  \
+    -DUSE_APP_CONFIG=1                                                                                    \
     -I$(top_srcdir)/include                                                                               \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/cmsis                                                 \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config                                                \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/config/nrf52840/config                                \
     -I$(top_srcdir)/third_party/NordicSemiconductor/dependencies                                          \
     -I$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error                                   \
+    -I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk                                              \
     $(NULL)
 endif
 
diff --git a/third_party/mbedtls/CMakeLists.txt b/third_party/mbedtls/CMakeLists.txt
index 00ca416..7b5dcae 100644
--- a/third_party/mbedtls/CMakeLists.txt
+++ b/third_party/mbedtls/CMakeLists.txt
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2019, The OpenThread Authors.
+#  Copyright (c) 2020, The OpenThread Authors.
 #  All rights reserved.
 #
 #  Redistribution and use in source and binary forms, with or without
@@ -26,55 +26,81 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-add_library(mbedcrypto)
+set(OT_MBEDTLS_DEFAULT_CONFIG_FILE \"${CMAKE_CURRENT_BINARY_DIR}/openthread-mbedtls-config.h\")
 
-target_compile_definitions(mbedcrypto PRIVATE
-    ${OT_PRIVATE_DEFINES}
+set(OT_MBEDTLS_CONFIG_FILE "" CACHE STRING "The mbedTLS config file")
+
+set(ENABLE_TESTING OFF CACHE BOOL "Disable mbedtls test" FORCE)
+set(ENABLE_PROGRAMS OFF CACHE BOOL "Disable mbetls program" FORCE)
+
+find_program(UNIFDEFALL_EXE unifdefall)
+find_program(UNIFDEF_EXE unifdef)
+if(UNIFDEF_EXE)
+    execute_process(COMMAND ${UNIFDEF_EXE} -V ERROR_VARIABLE VERSION_OUTPUT)
+    string(REGEX MATCH "Version: unifdef-([0-9]+\\.[0-9]+)" VERSION_MATCH "${VERSION_OUTPUT}")
+    set(UNIFDEF_VERSION ${CMAKE_MATCH_1})
+endif()
+find_program(SED_EXE sed)
+
+add_subdirectory(repo)
+
+if(UNIFDEFALL_EXE AND SED_EXE AND UNIFDEF_VERSION VERSION_GREATER_EQUAL 2.10)
+    add_custom_target(openthread-mbedtls-config
+        ${UNIFDEFALL_EXE}
+            "'-D$<JOIN:$<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>,';'-D>'"
+            "-I$<JOIN:$<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>,;-I>"
+            "-I$<JOIN:${OT_PUBLIC_INCLUDES},;-I>"
+            "-I${CMAKE_CURRENT_SOURCE_DIR}/repo/include"
+            "${CMAKE_CURRENT_SOURCE_DIR}/mbedtls-config.h" |
+            ${SED_EXE} '/openthread-core-config\.h/d' >
+            openthread-mbedtls-config.h
+        COMMAND_EXPAND_LISTS
+    )
+    add_dependencies(mbedtls openthread-mbedtls-config)
+    add_dependencies(mbedx509 openthread-mbedtls-config)
+    add_dependencies(mbedcrypto openthread-mbedtls-config)
+else()
+    configure_file(mbedtls-config.h openthread-mbedtls-config.h COPYONLY)
+endif()
+
+target_compile_definitions(mbedtls
+    PUBLIC
+        "MBEDTLS_CONFIG_FILE=$<IF:$<BOOL:${OT_MBEDTLS_CONFIG_FILE}>,${OT_MBEDTLS_CONFIG_FILE},${OT_MBEDTLS_DEFAULT_CONFIG_FILE}>"
+    PRIVATE
+        $<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
+)
+target_include_directories(mbedtls
+    PUBLIC
+        ${CMAKE_CURRENT_SOURCE_DIR}/repo/include
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        $<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>
 )
 
-target_include_directories(mbedcrypto PRIVATE
-    ${OT_PUBLIC_INCLUDES}
-    ${OT_PRIVATE_INCLUDES}
-    ${PROJECT_SOURCE_DIR}/src/core
+target_compile_definitions(mbedx509
+    PUBLIC
+        "MBEDTLS_CONFIG_FILE=$<IF:$<BOOL:${OT_MBEDTLS_CONFIG_FILE}>,${OT_MBEDTLS_CONFIG_FILE},${OT_MBEDTLS_DEFAULT_CONFIG_FILE}>"
+    PRIVATE
+        $<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
+)
+target_include_directories(mbedx509
+    PUBLIC
+        ${CMAKE_CURRENT_SOURCE_DIR}/repo/include
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        $<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>
 )
 
-target_sources(mbedcrypto PRIVATE
-    repo/library/aes.c
-    repo/library/asn1parse.c
-    repo/library/asn1write.c
-    repo/library/base64.c
-    repo/library/bignum.c
-    repo/library/ccm.c
-    repo/library/cipher.c
-    repo/library/cipher_wrap.c
-    repo/library/cmac.c
-    repo/library/ctr_drbg.c
-    repo/library/debug.c
-    repo/library/ecdh.c
-    repo/library/ecdsa.c
-    repo/library/ecjpake.c
-    repo/library/ecp.c
-    repo/library/ecp_curves.c
-    repo/library/entropy.c
-    repo/library/entropy_poll.c
-    repo/library/md.c
-    repo/library/md_wrap.c
-    repo/library/memory_buffer_alloc.c
-    repo/library/oid.c
-    repo/library/pem.c
-    repo/library/pk.c
-    repo/library/pk_wrap.c
-    repo/library/pkparse.c
-    repo/library/platform.c
-    repo/library/platform_util.c
-    repo/library/sha256.c
-    repo/library/ssl_cookie.c
-    repo/library/ssl_ciphersuites.c
-    repo/library/ssl_cli.c
-    repo/library/ssl_srv.c
-    repo/library/ssl_ticket.c
-    repo/library/ssl_tls.c
-    repo/library/threading.c
-    repo/library/x509.c
-    repo/library/x509_crt.c
+target_compile_definitions(mbedcrypto
+    PUBLIC
+        "MBEDTLS_CONFIG_FILE=$<IF:$<BOOL:${OT_MBEDTLS_CONFIG_FILE}>,${OT_MBEDTLS_CONFIG_FILE},${OT_MBEDTLS_DEFAULT_CONFIG_FILE}>"
+    PRIVATE
+        $<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
+)
+target_include_directories(mbedcrypto
+    PUBLIC
+        ${CMAKE_CURRENT_SOURCE_DIR}/repo/include
+    PRIVATE
+        ${OT_PUBLIC_INCLUDES}
+        $<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>
 )
diff --git a/third_party/mbedtls/Makefile.am b/third_party/mbedtls/Makefile.am
index aae66a9..fa45090 100644
--- a/third_party/mbedtls/Makefile.am
+++ b/third_party/mbedtls/Makefile.am
@@ -21,7 +21,10 @@
     repo/include                                \
     $(NULL)
 
-lib_LIBRARIES                                 = libmbedcrypto.a
+lib_LIBRARIES                                 = \
+    libmbedcrypto.a                             \
+    libmbedcrypto-radio.a                       \
+    $(NULL)
 
 # Do not enable -Wconversion for mbedtls
 override CFLAGS                              := $(filter-out -Wconversion,$(CFLAGS))
@@ -31,6 +34,10 @@
 override CFLAGS                              := $(filter-out -pedantic-errors,$(CFLAGS))
 override CXXFLAGS                            := $(filter-out -pedantic-errors,$(CXXFLAGS))
 
+# Do not enable -Wcast-align for mbedtls
+override CFLAGS                              := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS                            := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 MBEDTLS_SRCDIR                                = $(top_srcdir)/third_party/mbedtls/repo
 
 libmbedcrypto_a_CPPFLAGS                      = \
@@ -67,6 +74,7 @@
     repo/library/pk.c                           \
     repo/library/pk_wrap.c                      \
     repo/library/pkparse.c                      \
+    repo/library/pkwrite.c                      \
     repo/library/platform.c                     \
     repo/library/platform_util.c                \
     repo/library/sha256.c                       \
@@ -81,6 +89,18 @@
     repo/library/x509_crt.c                     \
     $(NULL)
 
+libmbedcrypto_radio_a_CPPFLAGS                = \
+    -I$(top_srcdir)/include                     \
+    -I$(top_srcdir)/src/core                    \
+    -I$(MBEDTLS_SRCDIR)/include                 \
+    $(MBEDTLS_CPPFLAGS)                         \
+    $(NULL)
+
+libmbedcrypto_radio_a_SOURCES                 = \
+    repo/library/aes.c                          \
+    repo/library/platform_util.c                \
+    $(NULL)
+
 if OPENTHREAD_BUILD_COVERAGE
 Dash                                          = -
 CLEANFILES                                    = $(shell find $(top_builddir)/third_party/mbedtls $(Dash)name "*.gcda" $(Dash)o $(Dash)name "*.gcno")
diff --git a/third_party/mbedtls/mbedtls-config.h b/third_party/mbedtls/mbedtls-config.h
index 4ce7a57..6de6cfd 100644
--- a/third_party/mbedtls/mbedtls-config.h
+++ b/third_party/mbedtls/mbedtls-config.h
@@ -26,7 +26,9 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef MBEDTLS_CONFIG_H
+// Spans multiple lines to avoid being processed by unifdef
+#ifndef \
+    MBEDTLS_CONFIG_H
 #define MBEDTLS_CONFIG_H
 
 #include "openthread-core-config.h"
@@ -76,8 +78,7 @@
 #define MBEDTLS_SSL_PROTO_DTLS
 #define MBEDTLS_SSL_TLS_C
 
-#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE || OPENTHREAD_CONFIG_COMMISSIONER_ENABLE || \
-    OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
+#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE || OPENTHREAD_CONFIG_COMMISSIONER_ENABLE || OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
 #define MBEDTLS_SSL_COOKIE_C
 #define MBEDTLS_SSL_SRV_C
 #endif
@@ -129,7 +130,9 @@
 
 #define MBEDTLS_SSL_CIPHERSUITES         MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
 
-#if defined(MBEDTLS_USER_CONFIG_FILE)
+// Spans multiple lines to avoid being processed by unifdef
+#if defined(\
+    MBEDTLS_USER_CONFIG_FILE)
 #include MBEDTLS_USER_CONFIG_FILE
 #endif
 
diff --git a/third_party/microchip/CMakeLists.txt b/third_party/microchip/CMakeLists.txt
new file mode 100644
index 0000000..6091848
--- /dev/null
+++ b/third_party/microchip/CMakeLists.txt
@@ -0,0 +1,127 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+add_library(samr21-driver
+    asf/common/utils/interrupt/interrupt_sam_nvic.c
+    asf/common2/services/delay/sam0/cycle_counter.c
+    asf/sam0/drivers/extint/extint_callback.c
+    asf/sam0/drivers/extint/extint_sam_d_r_h/extint.c
+    asf/sam0/drivers/nvm/nvm.c
+    asf/sam0/drivers/port/port.c
+    asf/sam0/drivers/system/clock/clock_samd21_r21_da_ha1/clock.c
+    asf/sam0/drivers/system/clock/clock_samd21_r21_da_ha1/gclk.c
+    asf/sam0/drivers/system/interrupt/system_interrupt.c
+    asf/sam0/drivers/system/pinmux/pinmux.c
+    asf/sam0/drivers/sercom/sercom.c
+    asf/sam0/drivers/sercom/sercom_interrupt.c
+    asf/sam0/drivers/sercom/i2c/i2c_sam0/i2c_master.c
+    asf/sam0/drivers/sercom/spi/spi.c
+    asf/sam0/drivers/sercom/usart/usart.c
+    asf/sam0/drivers/sercom/usart/usart_interrupt.c
+    asf/sam0/utils/cmsis/samr21/source/gcc/startup_samr21.c
+    asf/sam0/utils/cmsis/samr21/source/system_samr21.c
+    asf/sam0/utils/syscalls/gcc/syscalls.c
+    asf/thirdparty/wireless/avr2130_lwmesh/source/phy/at86rf233/src/phy.c
+    asf/thirdparty/wireless/services/sal/at86rf2xx/src/sal.c
+    asf/thirdparty/wireless/services/trx_access/trx_access.c
+)
+
+if(OT_CFLAGS MATCHES "-pedantic-errors")
+    string(REPLACE "-pedantic-errors" "" OT_CFLAGS "${OT_CFLAGS}")
+endif()
+
+target_link_options(samr21-driver
+    PUBLIC
+        -T${PROJECT_SOURCE_DIR}/third_party/microchip/include/samr21x18a.ld
+)
+
+target_link_libraries(samr21-driver PRIVATE ot-config)
+
+target_compile_definitions(samr21-driver
+    PUBLIC
+        ${OT_PLATFORM_DEFINES}
+        -DBOARD=SAMR21_XPLAINED_PRO
+        -D__SAMR21G18A__
+        -DARM_MATH_CM0PLUS=true
+        -DPHY_AT86RF233
+        -DSAL_TYPE=AT86RF2xx
+        -DUSART_CALLBACK_MODE=true
+        -DEXTINT_CALLBACK_MODE=true
+        -DSPI_CALLBACK_MODE=false
+        -DCYCLE_MODE
+)
+
+target_compile_options(samr21-driver
+    PUBLIC
+        -Werror
+        -Wno-unused-parameter
+        -fno-strict-aliasing
+    PRIVATE
+        -Wno-implicit-function-declaration
+        -Wno-expansion-to-defined
+        ${OT_CFLAGS}
+)
+
+target_include_directories(samr21-driver
+    PUBLIC
+        include
+        asf/common/boards
+        asf/common/utils
+        asf/common2/services/delay
+        asf/common2/services/delay/sam0
+        asf/sam0/boards
+        asf/sam0/boards/samr21_xplained_pro
+        asf/sam0/drivers/extint
+        asf/sam0/drivers/extint/extint_sam_d_r_h
+        asf/sam0/drivers/nvm
+        asf/sam0/drivers/port
+        asf/sam0/drivers/system
+        asf/sam0/drivers/system/clock
+        asf/sam0/drivers/system/clock/clock_samd21_r21_da_ha1
+        asf/sam0/drivers/system/interrupt
+        asf/sam0/drivers/system/interrupt/system_interrupt_samr21
+        asf/sam0/drivers/system/pinmux
+        asf/sam0/drivers/system/power
+        asf/sam0/drivers/system/power/power_sam_d_r_h
+        asf/sam0/drivers/system/reset
+        asf/sam0/drivers/system/reset/reset_sam_d_r_h
+        asf/sam0/drivers/sercom
+        asf/sam0/drivers/sercom/i2c
+        asf/sam0/drivers/sercom/i2c/i2c_sam0
+        asf/sam0/drivers/sercom/spi
+        asf/sam0/drivers/sercom/usart
+        asf/sam0/utils/cmsis/samr21/include
+        asf/sam0/utils/cmsis/samr21/source
+        asf/sam0/utils/header_files
+        asf/sam0/utils/preprocessor
+        asf/thirdparty/CMSIS/Include
+        asf/thirdparty/wireless/avr2130_lwmesh/source/phy/at86rf233/inc
+        asf/thirdparty/wireless/services/sal/inc
+        asf/thirdparty/wireless/services/trx_access
+        asf/thirdparty/wireless/services/trx_access/module_config
+)
diff --git a/third_party/nxp/CMakeLists.txt b/third_party/nxp/CMakeLists.txt
new file mode 100644
index 0000000..855843a
--- /dev/null
+++ b/third_party/nxp/CMakeLists.txt
@@ -0,0 +1,86 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+if(OT_PLATFORM STREQUAL "kw41z")
+    set_property(SOURCE ${PROJECT_SOURCE_DIR}/third_party/nxp/MKW41Z4/startup_MKW41Z4.S PROPERTY LANGUAGE C)
+
+    add_library(nxp-kw41z-driver
+        MKW41Z4/clock_config.c
+        MKW41Z4/drivers/fsl_clock.c
+        MKW41Z4/drivers/fsl_flash.c
+        MKW41Z4/drivers/fsl_lpuart.c
+        MKW41Z4/drivers/fsl_gpio.c
+        MKW41Z4/drivers/fsl_pit.c
+        MKW41Z4/drivers/fsl_trng.c
+        MKW41Z4/startup_MKW41Z4.S
+        MKW41Z4/system_MKW41Z4.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_ant_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_ble_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_common_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p3_h_0p5_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p32_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p5_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p7_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_1p0_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p7_h_0p5_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_mode_datarate_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_msk_config.c
+        MKW41Z4/XCVR/cfgs_kw4x_3x_2x/fsl_xcvr_zgbe_config.c
+        MKW41Z4/XCVR/dbg_ram_capture.c
+        MKW41Z4/XCVR/fsl_xcvr.c
+        MKW41Z4/XCVR/fsl_xcvr_trim.c
+        MKW41Z4/XCVR/ifr_radio.c
+    )
+
+    target_compile_definitions(nxp-kw41z-driver
+        PUBLIC
+            ${OT_PLATFORM_DEFINES}
+            -DCPU_MKW41Z512VHT4
+    )
+
+    target_compile_options(nxp-kw41z-driver
+        PRIVATE
+            ${OT_CFLAGS}
+            -Wno-unknown-pragmas
+            -Wno-sign-compare
+            -Wno-unused-function
+            -Wno-unused-parameter
+            -Wno-empty-body
+    )
+
+    target_include_directories(nxp-kw41z-driver
+        PUBLIC
+            CMSIS/Include
+            MKW41Z4
+            MKW41Z4/drivers
+            MKW41Z4/XCVR
+            MKW41Z4/XCVR/cfgs_kw4x_3x_2x
+    )
+
+    target_link_libraries(nxp-kw41z-driver PRIVATE ot-config)
+endif()
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/arm_common_tables.h b/third_party/nxp/JN5189DK6/CMSIS/Include/arm_common_tables.h
new file mode 100755
index 0000000..8742a56
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/arm_common_tables.h
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date:        19. October 2015
+* $Revision: 	V.1.4.5 a
+*
+* Project: 	    CMSIS DSP Library
+* Title:	    arm_common_tables.h
+*
+* Description:	This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED 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 OWNER 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 _ARM_COMMON_TABLES_H
+#define _ARM_COMMON_TABLES_H
+
+#include "arm_math.h"
+
+extern const uint16_t armBitRevTable[1024];
+extern const q15_t armRecipTableQ15[64];
+extern const q31_t armRecipTableQ31[64];
+/* extern const q31_t realCoefAQ31[1024]; */
+/* extern const q31_t realCoefBQ31[1024]; */
+extern const float32_t twiddleCoef_16[32];
+extern const float32_t twiddleCoef_32[64];
+extern const float32_t twiddleCoef_64[128];
+extern const float32_t twiddleCoef_128[256];
+extern const float32_t twiddleCoef_256[512];
+extern const float32_t twiddleCoef_512[1024];
+extern const float32_t twiddleCoef_1024[2048];
+extern const float32_t twiddleCoef_2048[4096];
+extern const float32_t twiddleCoef_4096[8192];
+#define twiddleCoef twiddleCoef_4096
+extern const q31_t twiddleCoef_16_q31[24];
+extern const q31_t twiddleCoef_32_q31[48];
+extern const q31_t twiddleCoef_64_q31[96];
+extern const q31_t twiddleCoef_128_q31[192];
+extern const q31_t twiddleCoef_256_q31[384];
+extern const q31_t twiddleCoef_512_q31[768];
+extern const q31_t twiddleCoef_1024_q31[1536];
+extern const q31_t twiddleCoef_2048_q31[3072];
+extern const q31_t twiddleCoef_4096_q31[6144];
+extern const q15_t twiddleCoef_16_q15[24];
+extern const q15_t twiddleCoef_32_q15[48];
+extern const q15_t twiddleCoef_64_q15[96];
+extern const q15_t twiddleCoef_128_q15[192];
+extern const q15_t twiddleCoef_256_q15[384];
+extern const q15_t twiddleCoef_512_q15[768];
+extern const q15_t twiddleCoef_1024_q15[1536];
+extern const q15_t twiddleCoef_2048_q15[3072];
+extern const q15_t twiddleCoef_4096_q15[6144];
+extern const float32_t twiddleCoef_rfft_32[32];
+extern const float32_t twiddleCoef_rfft_64[64];
+extern const float32_t twiddleCoef_rfft_128[128];
+extern const float32_t twiddleCoef_rfft_256[256];
+extern const float32_t twiddleCoef_rfft_512[512];
+extern const float32_t twiddleCoef_rfft_1024[1024];
+extern const float32_t twiddleCoef_rfft_2048[2048];
+extern const float32_t twiddleCoef_rfft_4096[4096];
+
+
+/* floating-point bit reversal tables */
+#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20  )
+#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48  )
+#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56  )
+#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
+#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
+#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
+#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
+#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
+#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
+
+/* fixed-point bit reversal tables */
+#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12  )
+#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24  )
+#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56  )
+#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
+#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
+#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
+#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
+#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
+#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
+
+/* Tables for Fast Math Sine and Cosine */
+extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
+extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
+extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
+
+#endif /*  ARM_COMMON_TABLES_H */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/arm_const_structs.h b/third_party/nxp/JN5189DK6/CMSIS/Include/arm_const_structs.h
new file mode 100755
index 0000000..726d06e
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/arm_const_structs.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date:        19. March 2015
+* $Revision: 	V.1.4.5
+*
+* Project: 	    CMSIS DSP Library
+* Title:	    arm_const_structs.h
+*
+* Description:	This file has constant structs that are initialized for
+*              user convenience.  For example, some can be given as
+*              arguments to the arm_cfft_f32() function.
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED 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 OWNER 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 _ARM_CONST_STRUCTS_H
+#define _ARM_CONST_STRUCTS_H
+
+#include "arm_math.h"
+#include "arm_common_tables.h"
+
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
+
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
+
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
+
+#endif
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/arm_math.h b/third_party/nxp/JN5189DK6/CMSIS/Include/arm_math.h
new file mode 100755
index 0000000..d33f8a9
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/arm_math.h
@@ -0,0 +1,7154 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+*
+* $Date:        20. October 2015
+* $Revision:    V1.4.5 b
+*
+* Project:      CMSIS DSP Library
+* Title:        arm_math.h
+*
+* Description:  Public header file for CMSIS DSP Library
+*
+* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED 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 OWNER 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.
+ * -------------------------------------------------------------------- */
+
+/**
+   \mainpage CMSIS DSP Software Library
+   *
+   * Introduction
+   * ------------
+   *
+   * This user manual describes the CMSIS DSP software library,
+   * a suite of common signal processing functions for use on Cortex-M processor based devices.
+   *
+   * The library is divided into a number of functions each covering a specific category:
+   * - Basic math functions
+   * - Fast math functions
+   * - Complex math functions
+   * - Filters
+   * - Matrix functions
+   * - Transforms
+   * - Motor control functions
+   * - Statistical functions
+   * - Support functions
+   * - Interpolation functions
+   *
+   * The library has separate functions for operating on 8-bit integers, 16-bit integers,
+   * 32-bit integer and 32-bit floating-point values.
+   *
+   * Using the Library
+   * ------------
+   *
+   * The library installer contains prebuilt versions of the libraries in the <code>Lib</code> folder.
+   * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7)
+   * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7)
+   * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7)
+   * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7)
+   * - arm_cortexM7l_math.lib (Little endian on Cortex-M7)
+   * - arm_cortexM7b_math.lib (Big endian on Cortex-M7)
+   * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
+   * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
+   * - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
+   * - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
+   * - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
+   * - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
+   * - arm_cortexM0l_math.lib (Little endian on Cortex-M0 / CortexM0+)
+   * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+)
+   *
+   * The library functions are declared in the public file <code>arm_math.h</code> which is placed in the <code>Include</code> folder.
+   * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single
+   * public header file <code> arm_math.h</code> for Cortex-M7/M4/M3/M0/M0+ with little endian and big endian. Same header file will be used for floating point unit(FPU) variants.
+   * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or  ARM_MATH_CM3 or
+   * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application.
+   *
+   * Examples
+   * --------
+   *
+   * The library ships with a number of examples which demonstrate how to use the library functions.
+   *
+   * Toolchain Support
+   * ------------
+   *
+   * The library has been developed and tested with MDK-ARM version 5.14.0.0
+   * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly.
+   *
+   * Building the Library
+   * ------------
+   *
+   * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the <code>CMSIS\\DSP_Lib\\Source\\ARM</code> folder.
+   * - arm_cortexM_math.uvprojx
+   *
+   *
+   * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above.
+   *
+   * Pre-processor Macros
+   * ------------
+   *
+   * Each library project have differant pre-processor macros.
+   *
+   * - UNALIGNED_SUPPORT_DISABLE:
+   *
+   * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access
+   *
+   * - ARM_MATH_BIG_ENDIAN:
+   *
+   * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets.
+   *
+   * - ARM_MATH_MATRIX_CHECK:
+   *
+   * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices
+   *
+   * - ARM_MATH_ROUNDING:
+   *
+   * Define macro ARM_MATH_ROUNDING for rounding on support functions
+   *
+   * - ARM_MATH_CMx:
+   *
+   * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target
+   * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and
+   * ARM_MATH_CM7 for building the library on cortex-M7.
+   *
+   * - __FPU_PRESENT:
+   *
+   * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries
+   *
+   * <hr>
+   * CMSIS-DSP in ARM::CMSIS Pack
+   * -----------------------------
+   *
+   * The following files relevant to CMSIS-DSP are present in the <b>ARM::CMSIS</b> Pack directories:
+   * |File/Folder                   |Content                                                                 |
+   * |------------------------------|------------------------------------------------------------------------|
+   * |\b CMSIS\\Documentation\\DSP  | This documentation                                                     |
+   * |\b CMSIS\\DSP_Lib             | Software license agreement (license.txt)                               |
+   * |\b CMSIS\\DSP_Lib\\Examples   | Example projects demonstrating the usage of the library functions      |
+   * |\b CMSIS\\DSP_Lib\\Source     | Source files for rebuilding the library                                |
+   *
+   * <hr>
+   * Revision History of CMSIS-DSP
+   * ------------
+   * Please refer to \ref ChangeLog_pg.
+   *
+   * Copyright Notice
+   * ------------
+   *
+   * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+   */
+
+
+/**
+ * @defgroup groupMath Basic Math Functions
+ */
+
+/**
+ * @defgroup groupFastMath Fast Math Functions
+ * This set of functions provides a fast approximation to sine, cosine, and square root.
+ * As compared to most of the other functions in the CMSIS math library, the fast math functions
+ * operate on individual values and not arrays.
+ * There are separate functions for Q15, Q31, and floating-point data.
+ *
+ */
+
+/**
+ * @defgroup groupCmplxMath Complex Math Functions
+ * This set of functions operates on complex data vectors.
+ * The data in the complex arrays is stored in an interleaved fashion
+ * (real, imag, real, imag, ...).
+ * In the API functions, the number of samples in a complex array refers
+ * to the number of complex values; the array contains twice this number of
+ * real values.
+ */
+
+/**
+ * @defgroup groupFilters Filtering Functions
+ */
+
+/**
+ * @defgroup groupMatrix Matrix Functions
+ *
+ * This set of functions provides basic matrix math operations.
+ * The functions operate on matrix data structures.  For example,
+ * the type
+ * definition for the floating-point matrix structure is shown
+ * below:
+ * <pre>
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * </pre>
+ * There are similar definitions for Q15 and Q31 data types.
+ *
+ * The structure specifies the size of the matrix and then points to
+ * an array of data.  The array is of size <code>numRows X numCols</code>
+ * and the values are arranged in row order.  That is, the
+ * matrix element (i, j) is stored at:
+ * <pre>
+ *     pData[i*numCols + j]
+ * </pre>
+ *
+ * \par Init Functions
+ * There is an associated initialization function for each type of matrix
+ * data structure.
+ * The initialization function sets the values of the internal structure fields.
+ * Refer to the function <code>arm_mat_init_f32()</code>, <code>arm_mat_init_q31()</code>
+ * and <code>arm_mat_init_q15()</code> for floating-point, Q31 and Q15 types,  respectively.
+ *
+ * \par
+ * Use of the initialization function is optional. However, if initialization function is used
+ * then the instance structure cannot be placed into a const data section.
+ * To place the instance structure in a const data
+ * section, manually initialize the data structure.  For example:
+ * <pre>
+ * <code>arm_matrix_instance_f32 S = {nRows, nColumns, pData};</code>
+ * <code>arm_matrix_instance_q31 S = {nRows, nColumns, pData};</code>
+ * <code>arm_matrix_instance_q15 S = {nRows, nColumns, pData};</code>
+ * </pre>
+ * where <code>nRows</code> specifies the number of rows, <code>nColumns</code>
+ * specifies the number of columns, and <code>pData</code> points to the
+ * data array.
+ *
+ * \par Size Checking
+ * By default all of the matrix functions perform size checking on the input and
+ * output matrices.  For example, the matrix addition function verifies that the
+ * two input matrices and the output matrix all have the same number of rows and
+ * columns.  If the size check fails the functions return:
+ * <pre>
+ *     ARM_MATH_SIZE_MISMATCH
+ * </pre>
+ * Otherwise the functions return
+ * <pre>
+ *     ARM_MATH_SUCCESS
+ * </pre>
+ * There is some overhead associated with this matrix size checking.
+ * The matrix size checking is enabled via the \#define
+ * <pre>
+ *     ARM_MATH_MATRIX_CHECK
+ * </pre>
+ * within the library project settings.  By default this macro is defined
+ * and size checking is enabled.  By changing the project settings and
+ * undefining this macro size checking is eliminated and the functions
+ * run a bit faster.  With size checking disabled the functions always
+ * return <code>ARM_MATH_SUCCESS</code>.
+ */
+
+/**
+ * @defgroup groupTransforms Transform Functions
+ */
+
+/**
+ * @defgroup groupController Controller Functions
+ */
+
+/**
+ * @defgroup groupStats Statistics Functions
+ */
+/**
+ * @defgroup groupSupport Support Functions
+ */
+
+/**
+ * @defgroup groupInterpolation Interpolation Functions
+ * These functions perform 1- and 2-dimensional interpolation of data.
+ * Linear interpolation is used for 1-dimensional data and
+ * bilinear interpolation is used for 2-dimensional data.
+ */
+
+/**
+ * @defgroup groupExamples Examples
+ */
+#ifndef _ARM_MATH_H
+#define _ARM_MATH_H
+
+/* ignore some GCC warnings */
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#define __CMSIS_GENERIC         /* disable NVIC and Systick functions */
+
+#if defined(ARM_MATH_CM7)
+  #include "core_cm7.h"
+#elif defined (ARM_MATH_CM4)
+  #include "core_cm4.h"
+#elif defined (ARM_MATH_CM3)
+  #include "core_cm3.h"
+#elif defined (ARM_MATH_CM0)
+  #include "core_cm0.h"
+  #define ARM_MATH_CM0_FAMILY
+#elif defined (ARM_MATH_CM0PLUS)
+  #include "core_cm0plus.h"
+  #define ARM_MATH_CM0_FAMILY
+#else
+  #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0"
+#endif
+
+#undef  __CMSIS_GENERIC         /* enable NVIC and Systick functions */
+#include "string.h"
+#include "math.h"
+#ifdef   __cplusplus
+extern "C"
+{
+#endif
+
+
+  /**
+   * @brief Macros required for reciprocal calculation in Normalized LMS
+   */
+
+#define DELTA_Q31          (0x100)
+#define DELTA_Q15          0x5
+#define INDEX_MASK         0x0000003F
+#ifndef PI
+#define PI                 3.14159265358979f
+#endif
+
+  /**
+   * @brief Macros required for SINE and COSINE Fast math approximations
+   */
+
+#define FAST_MATH_TABLE_SIZE  512
+#define FAST_MATH_Q31_SHIFT   (32 - 10)
+#define FAST_MATH_Q15_SHIFT   (16 - 10)
+#define CONTROLLER_Q31_SHIFT  (32 - 9)
+#define TABLE_SIZE  256
+#define TABLE_SPACING_Q31     0x400000
+#define TABLE_SPACING_Q15     0x80
+
+  /**
+   * @brief Macros required for SINE and COSINE Controller functions
+   */
+  /* 1.31(q31) Fixed value of 2/360 */
+  /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
+#define INPUT_SPACING         0xB60B61
+
+  /**
+   * @brief Macro for Unaligned Support
+   */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+    #define ALIGN4
+#else
+  #if defined  (__GNUC__)
+    #define ALIGN4 __attribute__((aligned(4)))
+  #else
+    #define ALIGN4 __align(4)
+  #endif
+#endif   /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+  /**
+   * @brief Error status returned by some functions in the library.
+   */
+
+  typedef enum
+  {
+    ARM_MATH_SUCCESS = 0,                /**< No error */
+    ARM_MATH_ARGUMENT_ERROR = -1,        /**< One or more arguments are incorrect */
+    ARM_MATH_LENGTH_ERROR = -2,          /**< Length of data buffer is incorrect */
+    ARM_MATH_SIZE_MISMATCH = -3,         /**< Size of matrices is not compatible with the operation. */
+    ARM_MATH_NANINF = -4,                /**< Not-a-number (NaN) or infinity is generated */
+    ARM_MATH_SINGULAR = -5,              /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+    ARM_MATH_TEST_FAILURE = -6           /**< Test Failed  */
+  } arm_status;
+
+  /**
+   * @brief 8-bit fractional data type in 1.7 format.
+   */
+  typedef int8_t q7_t;
+
+  /**
+   * @brief 16-bit fractional data type in 1.15 format.
+   */
+  typedef int16_t q15_t;
+
+  /**
+   * @brief 32-bit fractional data type in 1.31 format.
+   */
+  typedef int32_t q31_t;
+
+  /**
+   * @brief 64-bit fractional data type in 1.63 format.
+   */
+  typedef int64_t q63_t;
+
+  /**
+   * @brief 32-bit floating-point type definition.
+   */
+  typedef float float32_t;
+
+  /**
+   * @brief 64-bit floating-point type definition.
+   */
+  typedef double float64_t;
+
+  /**
+   * @brief definition to read/write two 16 bit values.
+   */
+#if defined __CC_ARM
+  #define __SIMD32_TYPE int32_t __packed
+  #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __SIMD32_TYPE int32_t
+  #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined __GNUC__
+  #define __SIMD32_TYPE int32_t
+  #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined __ICCARM__
+  #define __SIMD32_TYPE int32_t __packed
+  #define CMSIS_UNUSED
+
+#elif defined __CSMC__
+  #define __SIMD32_TYPE int32_t
+  #define CMSIS_UNUSED
+
+#elif defined __TASKING__
+  #define __SIMD32_TYPE __unaligned int32_t
+  #define CMSIS_UNUSED
+
+#else
+  #error Unknown compiler
+#endif
+
+#define __SIMD32(addr)        (*(__SIMD32_TYPE **) & (addr))
+#define __SIMD32_CONST(addr)  ((__SIMD32_TYPE *)(addr))
+#define _SIMD32_OFFSET(addr)  (*(__SIMD32_TYPE *)  (addr))
+#define __SIMD64(addr)        (*(int64_t **) & (addr))
+
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+  /**
+   * @brief definition to pack two 16 bit values.
+   */
+#define __PKHBT(ARG1, ARG2, ARG3)      ( (((int32_t)(ARG1) <<  0) & (int32_t)0x0000FFFF) | \
+                                         (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000)  )
+#define __PKHTB(ARG1, ARG2, ARG3)      ( (((int32_t)(ARG1) <<  0) & (int32_t)0xFFFF0000) | \
+                                         (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF)  )
+
+#endif
+
+
+   /**
+   * @brief definition to pack four 8 bit values.
+   */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) <<  0) & (int32_t)0x000000FF) | \
+                                (((int32_t)(v1) <<  8) & (int32_t)0x0000FF00) | \
+                                (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \
+                                (((int32_t)(v3) << 24) & (int32_t)0xFF000000)  )
+#else
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) <<  0) & (int32_t)0x000000FF) | \
+                                (((int32_t)(v2) <<  8) & (int32_t)0x0000FF00) | \
+                                (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \
+                                (((int32_t)(v0) << 24) & (int32_t)0xFF000000)  )
+
+#endif
+
+
+  /**
+   * @brief Clips Q63 to Q31 values.
+   */
+  static __INLINE q31_t clip_q63_to_q31(
+  q63_t x)
+  {
+    return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+      ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
+  }
+
+  /**
+   * @brief Clips Q63 to Q15 values.
+   */
+  static __INLINE q15_t clip_q63_to_q15(
+  q63_t x)
+  {
+    return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+      ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15);
+  }
+
+  /**
+   * @brief Clips Q31 to Q7 values.
+   */
+  static __INLINE q7_t clip_q31_to_q7(
+  q31_t x)
+  {
+    return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ?
+      ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x;
+  }
+
+  /**
+   * @brief Clips Q31 to Q15 values.
+   */
+  static __INLINE q15_t clip_q31_to_q15(
+  q31_t x)
+  {
+    return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ?
+      ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x;
+  }
+
+  /**
+   * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format.
+   */
+
+  static __INLINE q63_t mult32x64(
+  q63_t x,
+  q31_t y)
+  {
+    return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) +
+            (((q63_t) (x >> 32) * y)));
+  }
+
+/*
+  #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM   )
+  #define __CLZ __clz
+  #endif
+ */
+/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */
+#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__))  )
+  static __INLINE uint32_t __CLZ(
+  q31_t data);
+
+  static __INLINE uint32_t __CLZ(
+  q31_t data)
+  {
+    uint32_t count = 0;
+    uint32_t mask = 0x80000000;
+
+    while((data & mask) == 0)
+    {
+      count += 1u;
+      mask = mask >> 1u;
+    }
+
+    return (count);
+  }
+#endif
+
+  /**
+   * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
+   */
+
+  static __INLINE uint32_t arm_recip_q31(
+  q31_t in,
+  q31_t * dst,
+  q31_t * pRecipTable)
+  {
+    q31_t out;
+    uint32_t tempVal;
+    uint32_t index, i;
+    uint32_t signBits;
+
+    if(in > 0)
+    {
+      signBits = ((uint32_t) (__CLZ( in) - 1));
+    }
+    else
+    {
+      signBits = ((uint32_t) (__CLZ(-in) - 1));
+    }
+
+    /* Convert input sample to 1.31 format */
+    in = (in << signBits);
+
+    /* calculation of index for initial approximated Val */
+    index = (uint32_t)(in >> 24);
+    index = (index & INDEX_MASK);
+
+    /* 1.31 with exp 1 */
+    out = pRecipTable[index];
+
+    /* calculation of reciprocal value */
+    /* running approximation for two iterations */
+    for (i = 0u; i < 2u; i++)
+    {
+      tempVal = (uint32_t) (((q63_t) in * out) >> 31);
+      tempVal = 0x7FFFFFFFu - tempVal;
+      /*      1.31 with exp 1 */
+      /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */
+      out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30);
+    }
+
+    /* write output */
+    *dst = out;
+
+    /* return num of signbits of out = 1/in value */
+    return (signBits + 1u);
+  }
+
+
+  /**
+   * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type.
+   */
+  static __INLINE uint32_t arm_recip_q15(
+  q15_t in,
+  q15_t * dst,
+  q15_t * pRecipTable)
+  {
+    q15_t out = 0;
+    uint32_t tempVal = 0;
+    uint32_t index = 0, i = 0;
+    uint32_t signBits = 0;
+
+    if(in > 0)
+    {
+      signBits = ((uint32_t)(__CLZ( in) - 17));
+    }
+    else
+    {
+      signBits = ((uint32_t)(__CLZ(-in) - 17));
+    }
+
+    /* Convert input sample to 1.15 format */
+    in = (in << signBits);
+
+    /* calculation of index for initial approximated Val */
+    index = (uint32_t)(in >>  8);
+    index = (index & INDEX_MASK);
+
+    /*      1.15 with exp 1  */
+    out = pRecipTable[index];
+
+    /* calculation of reciprocal value */
+    /* running approximation for two iterations */
+    for (i = 0u; i < 2u; i++)
+    {
+      tempVal = (uint32_t) (((q31_t) in * out) >> 15);
+      tempVal = 0x7FFFu - tempVal;
+      /*      1.15 with exp 1 */
+      out = (q15_t) (((q31_t) out * tempVal) >> 14);
+      /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */
+    }
+
+    /* write output */
+    *dst = out;
+
+    /* return num of signbits of out = 1/in value */
+    return (signBits + 1);
+  }
+
+
+  /*
+   * @brief C custom defined intrinisic function for only M0 processors
+   */
+#if defined(ARM_MATH_CM0_FAMILY)
+  static __INLINE q31_t __SSAT(
+  q31_t x,
+  uint32_t y)
+  {
+    int32_t posMax, negMin;
+    uint32_t i;
+
+    posMax = 1;
+    for (i = 0; i < (y - 1); i++)
+    {
+      posMax = posMax * 2;
+    }
+
+    if(x > 0)
+    {
+      posMax = (posMax - 1);
+
+      if(x > posMax)
+      {
+        x = posMax;
+      }
+    }
+    else
+    {
+      negMin = -posMax;
+
+      if(x < negMin)
+      {
+        x = negMin;
+      }
+    }
+    return (x);
+  }
+#endif /* end of ARM_MATH_CM0_FAMILY */
+
+
+  /*
+   * @brief C custom defined intrinsic function for M3 and M0 processors
+   */
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+
+  /*
+   * @brief C custom defined QADD8 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QADD8(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s, t, u;
+
+    r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+    s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+    t = __SSAT(((((q31_t)x <<  8) >> 24) + (((q31_t)y <<  8) >> 24)), 8) & (int32_t)0x000000FF;
+    u = __SSAT(((((q31_t)x      ) >> 24) + (((q31_t)y      ) >> 24)), 8) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QSUB8 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QSUB8(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s, t, u;
+
+    r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+    s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+    t = __SSAT(((((q31_t)x <<  8) >> 24) - (((q31_t)y <<  8) >> 24)), 8) & (int32_t)0x000000FF;
+    u = __SSAT(((((q31_t)x      ) >> 24) - (((q31_t)y      ) >> 24)), 8) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QADD16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QADD16(
+  uint32_t x,
+  uint32_t y)
+  {
+/*  q31_t r,     s;  without initialisation 'arm_offset_q15 test' fails  but 'intrinsic' tests pass! for armCC */
+    q31_t r = 0, s = 0;
+
+    r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((q31_t)x      ) >> 16) + (((q31_t)y      ) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SHADD16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SHADD16(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((q31_t)x      ) >> 16) + (((q31_t)y      ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QSUB16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QSUB16(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((q31_t)x      ) >> 16) - (((q31_t)y      ) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SHSUB16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SHSUB16(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((q31_t)x      ) >> 16) - (((q31_t)y      ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QASX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QASX(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y      ) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((q31_t)x      ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SHASX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SHASX(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = (((((q31_t)x << 16) >> 16) - (((q31_t)y      ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((q31_t)x      ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QSAX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QSAX(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y      ) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((q31_t)x      ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SHSAX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SHSAX(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = (((((q31_t)x << 16) >> 16) + (((q31_t)y      ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((q31_t)x      ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SMUSDX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMUSDX(
+  uint32_t x,
+  uint32_t y)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) -
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16))   ));
+  }
+
+  /*
+   * @brief C custom defined SMUADX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMUADX(
+  uint32_t x,
+  uint32_t y)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16))   ));
+  }
+
+
+  /*
+   * @brief C custom defined QADD for M3 and M0 processors
+   */
+  static __INLINE int32_t __QADD(
+  int32_t x,
+  int32_t y)
+  {
+    return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y)));
+  }
+
+
+  /*
+   * @brief C custom defined QSUB for M3 and M0 processors
+   */
+  static __INLINE int32_t __QSUB(
+  int32_t x,
+  int32_t y)
+  {
+    return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y)));
+  }
+
+
+  /*
+   * @brief C custom defined SMLAD for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMLAD(
+  uint32_t x,
+  uint32_t y,
+  uint32_t sum)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ( ((q31_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMLADX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMLADX(
+  uint32_t x,
+  uint32_t y,
+  uint32_t sum)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ( ((q31_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMLSDX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMLSDX(
+  uint32_t x,
+  uint32_t y,
+  uint32_t sum)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) -
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ( ((q31_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMLALD for M3 and M0 processors
+   */
+  static __INLINE uint64_t __SMLALD(
+  uint32_t x,
+  uint32_t y,
+  uint64_t sum)
+  {
+/*  return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */
+    return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ( ((q63_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMLALDX for M3 and M0 processors
+   */
+  static __INLINE uint64_t __SMLALDX(
+  uint32_t x,
+  uint32_t y,
+  uint64_t sum)
+  {
+/*  return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */
+    return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ( ((q63_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMUAD for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMUAD(
+  uint32_t x,
+  uint32_t y)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y      ) >> 16))   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMUSD for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMUSD(
+  uint32_t x,
+  uint32_t y)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) -
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y      ) >> 16))   ));
+  }
+
+
+  /*
+   * @brief C custom defined SXTB16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SXTB16(
+  uint32_t x)
+  {
+    return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) |
+                       ((((q31_t)x <<  8) >>  8) & (q31_t)0xFFFF0000)  ));
+  }
+
+#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */
+
+
+  /**
+   * @brief Instance structure for the Q7 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;        /**< number of filter coefficients in the filter. */
+    q7_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q7_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } arm_fir_instance_q7;
+
+  /**
+   * @brief Instance structure for the Q15 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q15_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } arm_fir_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q31_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps. */
+  } arm_fir_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of filter coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+  } arm_fir_instance_f32;
+
+
+  /**
+   * @brief Processing function for the Q7 FIR filter.
+   * @param[in]  S          points to an instance of the Q7 FIR filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_q7(
+  const arm_fir_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q7 FIR filter.
+   * @param[in,out] S          points to an instance of the Q7 FIR structure.
+   * @param[in]     numTaps    Number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of samples that are processed.
+   */
+  void arm_fir_init_q7(
+  arm_fir_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR filter.
+   * @param[in]  S          points to an instance of the Q15 FIR structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_q15(
+  const arm_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q15 FIR filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_fast_q15(
+  const arm_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 FIR filter.
+   * @param[in,out] S          points to an instance of the Q15 FIR filter structure.
+   * @param[in]     numTaps    Number of filter coefficients in the filter. Must be even and greater than or equal to 4.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of samples that are processed at a time.
+   * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if
+   * <code>numTaps</code> is not a supported value.
+   */
+  arm_status arm_fir_init_q15(
+  arm_fir_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR filter.
+   * @param[in]  S          points to an instance of the Q31 FIR filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_q31(
+  const arm_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q31 FIR structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_fast_q31(
+  const arm_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 FIR filter.
+   * @param[in,out] S          points to an instance of the Q31 FIR structure.
+   * @param[in]     numTaps    Number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of samples that are processed at a time.
+   */
+  void arm_fir_init_q31(
+  arm_fir_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point FIR filter.
+   * @param[in]  S          points to an instance of the floating-point FIR structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_f32(
+  const arm_fir_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point FIR filter.
+   * @param[in,out] S          points to an instance of the floating-point FIR filter structure.
+   * @param[in]     numTaps    Number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of samples that are processed at a time.
+   */
+  void arm_fir_init_f32(
+  arm_fir_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    int8_t numStages;        /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q15_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q15_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    int8_t postShift;        /**< Additional shift, in bits, applied to each output sample. */
+  } arm_biquad_casd_df1_inst_q15;
+
+  /**
+   * @brief Instance structure for the Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q31_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< Additional shift, in bits, applied to each output sample. */
+  } arm_biquad_casd_df1_inst_q31;
+
+  /**
+   * @brief Instance structure for the floating-point Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;       /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;      /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_casd_df1_inst_f32;
+
+
+  /**
+   * @brief Processing function for the Q15 Biquad cascade filter.
+   * @param[in]  S          points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_q15(
+  const arm_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     postShift  Shift to be applied to the output. Varies according to the coefficients format
+   */
+  void arm_biquad_cascade_df1_init_q15(
+  arm_biquad_casd_df1_inst_q15 * S,
+  uint8_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int8_t postShift);
+
+
+  /**
+   * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_fast_q15(
+  const arm_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 Biquad cascade filter
+   * @param[in]  S          points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_q31(
+  const arm_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_fast_q31(
+  const arm_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     postShift  Shift to be applied to the output. Varies according to the coefficients format
+   */
+  void arm_biquad_cascade_df1_init_q31(
+  arm_biquad_casd_df1_inst_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int8_t postShift);
+
+
+  /**
+   * @brief Processing function for the floating-point Biquad cascade filter.
+   * @param[in]  S          points to an instance of the floating-point Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_f32(
+  const arm_biquad_casd_df1_inst_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the floating-point Biquad cascade structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   */
+  void arm_biquad_cascade_df1_init_f32(
+  arm_biquad_casd_df1_inst_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float32_t *pData;     /**< points to the data of the matrix. */
+  } arm_matrix_instance_f32;
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float64_t *pData;     /**< points to the data of the matrix. */
+  } arm_matrix_instance_f64;
+
+  /**
+   * @brief Instance structure for the Q15 matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q15_t *pData;         /**< points to the data of the matrix. */
+  } arm_matrix_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q31_t *pData;         /**< points to the data of the matrix. */
+  } arm_matrix_instance_q31;
+
+
+  /**
+   * @brief Floating-point matrix addition.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_add_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix addition.
+   * @param[in]   pSrcA  points to the first input matrix structure
+   * @param[in]   pSrcB  points to the second input matrix structure
+   * @param[out]  pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_add_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst);
+
+
+  /**
+   * @brief Q31 matrix addition.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_add_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point, complex, matrix multiplication.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_cmplx_mult_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15, complex,  matrix multiplication.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_cmplx_mult_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst,
+  q15_t * pScratch);
+
+
+  /**
+   * @brief Q31, complex, matrix multiplication.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_cmplx_mult_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix transpose.
+   * @param[in]  pSrc  points to the input matrix
+   * @param[out] pDst  points to the output matrix
+   * @return    The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_trans_f32(
+  const arm_matrix_instance_f32 * pSrc,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix transpose.
+   * @param[in]  pSrc  points to the input matrix
+   * @param[out] pDst  points to the output matrix
+   * @return    The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_trans_q15(
+  const arm_matrix_instance_q15 * pSrc,
+  arm_matrix_instance_q15 * pDst);
+
+
+  /**
+   * @brief Q31 matrix transpose.
+   * @param[in]  pSrc  points to the input matrix
+   * @param[out] pDst  points to the output matrix
+   * @return    The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_trans_q31(
+  const arm_matrix_instance_q31 * pSrc,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix multiplication
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix multiplication
+   * @param[in]  pSrcA   points to the first input matrix structure
+   * @param[in]  pSrcB   points to the second input matrix structure
+   * @param[out] pDst    points to output matrix structure
+   * @param[in]  pState  points to the array for storing intermediate results
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+
+  /**
+   * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA   points to the first input matrix structure
+   * @param[in]  pSrcB   points to the second input matrix structure
+   * @param[out] pDst    points to output matrix structure
+   * @param[in]  pState  points to the array for storing intermediate results
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_fast_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+
+  /**
+   * @brief Q31 matrix multiplication
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_fast_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix subtraction
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_sub_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix subtraction
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_sub_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst);
+
+
+  /**
+   * @brief Q31 matrix subtraction
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_sub_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix scaling.
+   * @param[in]  pSrc   points to the input matrix
+   * @param[in]  scale  scale factor
+   * @param[out] pDst   points to the output matrix
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_scale_f32(
+  const arm_matrix_instance_f32 * pSrc,
+  float32_t scale,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix scaling.
+   * @param[in]  pSrc        points to input matrix
+   * @param[in]  scaleFract  fractional portion of the scale factor
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to output matrix
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_scale_q15(
+  const arm_matrix_instance_q15 * pSrc,
+  q15_t scaleFract,
+  int32_t shift,
+  arm_matrix_instance_q15 * pDst);
+
+
+  /**
+   * @brief Q31 matrix scaling.
+   * @param[in]  pSrc        points to input matrix
+   * @param[in]  scaleFract  fractional portion of the scale factor
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_scale_q31(
+  const arm_matrix_instance_q31 * pSrc,
+  q31_t scaleFract,
+  int32_t shift,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief  Q31 matrix initialization.
+   * @param[in,out] S         points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows     number of rows in the matrix.
+   * @param[in]     nColumns  number of columns in the matrix.
+   * @param[in]     pData     points to the matrix data array.
+   */
+  void arm_mat_init_q31(
+  arm_matrix_instance_q31 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q31_t * pData);
+
+
+  /**
+   * @brief  Q15 matrix initialization.
+   * @param[in,out] S         points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows     number of rows in the matrix.
+   * @param[in]     nColumns  number of columns in the matrix.
+   * @param[in]     pData     points to the matrix data array.
+   */
+  void arm_mat_init_q15(
+  arm_matrix_instance_q15 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q15_t * pData);
+
+
+  /**
+   * @brief  Floating-point matrix initialization.
+   * @param[in,out] S         points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows     number of rows in the matrix.
+   * @param[in]     nColumns  number of columns in the matrix.
+   * @param[in]     pData     points to the matrix data array.
+   */
+  void arm_mat_init_f32(
+  arm_matrix_instance_f32 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  float32_t * pData);
+
+
+
+  /**
+   * @brief Instance structure for the Q15 PID Control.
+   */
+  typedef struct
+  {
+    q15_t A0;           /**< The derived gain, A0 = Kp + Ki + Kd . */
+#ifdef ARM_MATH_CM0_FAMILY
+    q15_t A1;
+    q15_t A2;
+#else
+    q31_t A1;           /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
+#endif
+    q15_t state[3];     /**< The state array of length 3. */
+    q15_t Kp;           /**< The proportional gain. */
+    q15_t Ki;           /**< The integral gain. */
+    q15_t Kd;           /**< The derivative gain. */
+  } arm_pid_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 PID Control.
+   */
+  typedef struct
+  {
+    q31_t A0;            /**< The derived gain, A0 = Kp + Ki + Kd . */
+    q31_t A1;            /**< The derived gain, A1 = -Kp - 2Kd. */
+    q31_t A2;            /**< The derived gain, A2 = Kd . */
+    q31_t state[3];      /**< The state array of length 3. */
+    q31_t Kp;            /**< The proportional gain. */
+    q31_t Ki;            /**< The integral gain. */
+    q31_t Kd;            /**< The derivative gain. */
+  } arm_pid_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point PID Control.
+   */
+  typedef struct
+  {
+    float32_t A0;          /**< The derived gain, A0 = Kp + Ki + Kd . */
+    float32_t A1;          /**< The derived gain, A1 = -Kp - 2Kd. */
+    float32_t A2;          /**< The derived gain, A2 = Kd . */
+    float32_t state[3];    /**< The state array of length 3. */
+    float32_t Kp;          /**< The proportional gain. */
+    float32_t Ki;          /**< The integral gain. */
+    float32_t Kd;          /**< The derivative gain. */
+  } arm_pid_instance_f32;
+
+
+
+  /**
+   * @brief  Initialization function for the floating-point PID Control.
+   * @param[in,out] S               points to an instance of the PID structure.
+   * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   */
+  void arm_pid_init_f32(
+  arm_pid_instance_f32 * S,
+  int32_t resetStateFlag);
+
+
+  /**
+   * @brief  Reset function for the floating-point PID Control.
+   * @param[in,out] S  is an instance of the floating-point PID Control structure
+   */
+  void arm_pid_reset_f32(
+  arm_pid_instance_f32 * S);
+
+
+  /**
+   * @brief  Initialization function for the Q31 PID Control.
+   * @param[in,out] S               points to an instance of the Q15 PID structure.
+   * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   */
+  void arm_pid_init_q31(
+  arm_pid_instance_q31 * S,
+  int32_t resetStateFlag);
+
+
+  /**
+   * @brief  Reset function for the Q31 PID Control.
+   * @param[in,out] S   points to an instance of the Q31 PID Control structure
+   */
+
+  void arm_pid_reset_q31(
+  arm_pid_instance_q31 * S);
+
+
+  /**
+   * @brief  Initialization function for the Q15 PID Control.
+   * @param[in,out] S               points to an instance of the Q15 PID structure.
+   * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   */
+  void arm_pid_init_q15(
+  arm_pid_instance_q15 * S,
+  int32_t resetStateFlag);
+
+
+  /**
+   * @brief  Reset function for the Q15 PID Control.
+   * @param[in,out] S  points to an instance of the q15 PID Control structure
+   */
+  void arm_pid_reset_q15(
+  arm_pid_instance_q15 * S);
+
+
+  /**
+   * @brief Instance structure for the floating-point Linear Interpolate function.
+   */
+  typedef struct
+  {
+    uint32_t nValues;           /**< nValues */
+    float32_t x1;               /**< x1 */
+    float32_t xSpacing;         /**< xSpacing */
+    float32_t *pYData;          /**< pointer to the table of Y values */
+  } arm_linear_interp_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    float32_t *pData;   /**< points to the data table. */
+  } arm_bilinear_interp_instance_f32;
+
+   /**
+   * @brief Instance structure for the Q31 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q31_t *pData;       /**< points to the data table. */
+  } arm_bilinear_interp_instance_q31;
+
+   /**
+   * @brief Instance structure for the Q15 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q15_t *pData;       /**< points to the data table. */
+  } arm_bilinear_interp_instance_q15;
+
+   /**
+   * @brief Instance structure for the Q15 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q7_t *pData;        /**< points to the data table. */
+  } arm_bilinear_interp_instance_q7;
+
+
+  /**
+   * @brief Q7 vector multiplication.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_mult_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q15 vector multiplication.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_mult_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q31 vector multiplication.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_mult_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Floating-point vector multiplication.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_mult_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the Sin twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix2_instance_q15;
+
+/* Deprecated */
+  arm_status arm_cfft_radix2_init_q15(
+  arm_cfft_radix2_instance_q15 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix2_q15(
+  const arm_cfft_radix2_instance_q15 * S,
+  q15_t * pSrc);
+
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix4_instance_q15;
+
+/* Deprecated */
+  arm_status arm_cfft_radix4_init_q15(
+  arm_cfft_radix4_instance_q15 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix4_q15(
+  const arm_cfft_radix4_instance_q15 * S,
+  q15_t * pSrc);
+
+  /**
+   * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix2_instance_q31;
+
+/* Deprecated */
+  arm_status arm_cfft_radix2_init_q31(
+  arm_cfft_radix2_instance_q31 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix2_q31(
+  const arm_cfft_radix2_instance_q31 * S,
+  q31_t * pSrc);
+
+  /**
+   * @brief Instance structure for the Q31 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix4_instance_q31;
+
+/* Deprecated */
+  void arm_cfft_radix4_q31(
+  const arm_cfft_radix4_instance_q31 * S,
+  q31_t * pSrc);
+
+/* Deprecated */
+  arm_status arm_cfft_radix4_init_q31(
+  arm_cfft_radix4_instance_q31 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;             /**< value of 1/fftLen. */
+  } arm_cfft_radix2_instance_f32;
+
+/* Deprecated */
+  arm_status arm_cfft_radix2_init_f32(
+  arm_cfft_radix2_instance_f32 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix2_f32(
+  const arm_cfft_radix2_instance_f32 * S,
+  float32_t * pSrc);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;             /**< value of 1/fftLen. */
+  } arm_cfft_radix4_instance_f32;
+
+/* Deprecated */
+  arm_status arm_cfft_radix4_init_f32(
+  arm_cfft_radix4_instance_f32 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix4_f32(
+  const arm_cfft_radix4_instance_f32 * S,
+  float32_t * pSrc);
+
+  /**
+   * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const q15_t *pTwiddle;             /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } arm_cfft_instance_q15;
+
+void arm_cfft_q15(
+    const arm_cfft_instance_q15 * S,
+    q15_t * p1,
+    uint8_t ifftFlag,
+    uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const q31_t *pTwiddle;             /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } arm_cfft_instance_q31;
+
+void arm_cfft_q31(
+    const arm_cfft_instance_q31 * S,
+    q31_t * p1,
+    uint8_t ifftFlag,
+    uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const float32_t *pTwiddle;         /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } arm_cfft_instance_f32;
+
+  void arm_cfft_f32(
+  const arm_cfft_instance_f32 * S,
+  float32_t * p1,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the Q15 RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                      /**< length of the real FFT. */
+    uint8_t ifftFlagR;                        /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                  /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;               /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q15_t *pTwiddleAReal;                     /**< points to the real twiddle factor table. */
+    q15_t *pTwiddleBReal;                     /**< points to the imag twiddle factor table. */
+    const arm_cfft_instance_q15 *pCfft;       /**< points to the complex FFT instance. */
+  } arm_rfft_instance_q15;
+
+  arm_status arm_rfft_init_q15(
+  arm_rfft_instance_q15 * S,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_q15(
+  const arm_rfft_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst);
+
+  /**
+   * @brief Instance structure for the Q31 RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                 /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q31_t *pTwiddleAReal;                       /**< points to the real twiddle factor table. */
+    q31_t *pTwiddleBReal;                       /**< points to the imag twiddle factor table. */
+    const arm_cfft_instance_q31 *pCfft;         /**< points to the complex FFT instance. */
+  } arm_rfft_instance_q31;
+
+  arm_status arm_rfft_init_q31(
+  arm_rfft_instance_q31 * S,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_q31(
+  const arm_rfft_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint16_t fftLenBy2;                         /**< length of the complex FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                     /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    float32_t *pTwiddleAReal;                   /**< points to the real twiddle factor table. */
+    float32_t *pTwiddleBReal;                   /**< points to the imag twiddle factor table. */
+    arm_cfft_radix4_instance_f32 *pCfft;        /**< points to the complex FFT instance. */
+  } arm_rfft_instance_f32;
+
+  arm_status arm_rfft_init_f32(
+  arm_rfft_instance_f32 * S,
+  arm_cfft_radix4_instance_f32 * S_CFFT,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_f32(
+  const arm_rfft_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+typedef struct
+  {
+    arm_cfft_instance_f32 Sint;      /**< Internal CFFT structure. */
+    uint16_t fftLenRFFT;             /**< length of the real sequence */
+    float32_t * pTwiddleRFFT;        /**< Twiddle factors real stage  */
+  } arm_rfft_fast_instance_f32 ;
+
+arm_status arm_rfft_fast_init_f32 (
+   arm_rfft_fast_instance_f32 * S,
+   uint16_t fftLen);
+
+void arm_rfft_fast_f32(
+  arm_rfft_fast_instance_f32 * S,
+  float32_t * p, float32_t * pOut,
+  uint8_t ifftFlag);
+
+  /**
+   * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                          /**< length of the DCT4. */
+    uint16_t Nby2;                       /**< half of the length of the DCT4. */
+    float32_t normalize;                 /**< normalizing factor. */
+    float32_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    float32_t *pCosFactor;               /**< points to the cosFactor table. */
+    arm_rfft_instance_f32 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_f32;
+
+
+  /**
+   * @brief  Initialization function for the floating-point DCT4/IDCT4.
+   * @param[in,out] S          points to an instance of floating-point DCT4/IDCT4 structure.
+   * @param[in]     S_RFFT     points to an instance of floating-point RFFT/RIFFT structure.
+   * @param[in]     S_CFFT     points to an instance of floating-point CFFT/CIFFT structure.
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return      arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported transform length.
+   */
+  arm_status arm_dct4_init_f32(
+  arm_dct4_instance_f32 * S,
+  arm_rfft_instance_f32 * S_RFFT,
+  arm_cfft_radix4_instance_f32 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  float32_t normalize);
+
+
+  /**
+   * @brief Processing function for the floating-point DCT4/IDCT4.
+   * @param[in]     S              points to an instance of the floating-point DCT4/IDCT4 structure.
+   * @param[in]     pState         points to state buffer.
+   * @param[in,out] pInlineBuffer  points to the in-place input and output buffer.
+   */
+  void arm_dct4_f32(
+  const arm_dct4_instance_f32 * S,
+  float32_t * pState,
+  float32_t * pInlineBuffer);
+
+
+  /**
+   * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                          /**< length of the DCT4. */
+    uint16_t Nby2;                       /**< half of the length of the DCT4. */
+    q31_t normalize;                     /**< normalizing factor. */
+    q31_t *pTwiddle;                     /**< points to the twiddle factor table. */
+    q31_t *pCosFactor;                   /**< points to the cosFactor table. */
+    arm_rfft_instance_q31 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_q31;
+
+
+  /**
+   * @brief  Initialization function for the Q31 DCT4/IDCT4.
+   * @param[in,out] S          points to an instance of Q31 DCT4/IDCT4 structure.
+   * @param[in]     S_RFFT     points to an instance of Q31 RFFT/RIFFT structure
+   * @param[in]     S_CFFT     points to an instance of Q31 CFFT/CIFFT structure
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return      arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
+   */
+  arm_status arm_dct4_init_q31(
+  arm_dct4_instance_q31 * S,
+  arm_rfft_instance_q31 * S_RFFT,
+  arm_cfft_radix4_instance_q31 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q31_t normalize);
+
+
+  /**
+   * @brief Processing function for the Q31 DCT4/IDCT4.
+   * @param[in]     S              points to an instance of the Q31 DCT4 structure.
+   * @param[in]     pState         points to state buffer.
+   * @param[in,out] pInlineBuffer  points to the in-place input and output buffer.
+   */
+  void arm_dct4_q31(
+  const arm_dct4_instance_q31 * S,
+  q31_t * pState,
+  q31_t * pInlineBuffer);
+
+
+  /**
+   * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                          /**< length of the DCT4. */
+    uint16_t Nby2;                       /**< half of the length of the DCT4. */
+    q15_t normalize;                     /**< normalizing factor. */
+    q15_t *pTwiddle;                     /**< points to the twiddle factor table. */
+    q15_t *pCosFactor;                   /**< points to the cosFactor table. */
+    arm_rfft_instance_q15 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_q15;
+
+
+  /**
+   * @brief  Initialization function for the Q15 DCT4/IDCT4.
+   * @param[in,out] S          points to an instance of Q15 DCT4/IDCT4 structure.
+   * @param[in]     S_RFFT     points to an instance of Q15 RFFT/RIFFT structure.
+   * @param[in]     S_CFFT     points to an instance of Q15 CFFT/CIFFT structure.
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return      arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
+   */
+  arm_status arm_dct4_init_q15(
+  arm_dct4_instance_q15 * S,
+  arm_rfft_instance_q15 * S_RFFT,
+  arm_cfft_radix4_instance_q15 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q15_t normalize);
+
+
+  /**
+   * @brief Processing function for the Q15 DCT4/IDCT4.
+   * @param[in]     S              points to an instance of the Q15 DCT4 structure.
+   * @param[in]     pState         points to state buffer.
+   * @param[in,out] pInlineBuffer  points to the in-place input and output buffer.
+   */
+  void arm_dct4_q15(
+  const arm_dct4_instance_q15 * S,
+  q15_t * pState,
+  q15_t * pInlineBuffer);
+
+
+  /**
+   * @brief Floating-point vector addition.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_add_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q7 vector addition.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_add_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q15 vector addition.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_add_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q31 vector addition.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_add_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Floating-point vector subtraction.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_sub_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q7 vector subtraction.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_sub_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q15 vector subtraction.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_sub_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q31 vector subtraction.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_sub_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Multiplies a floating-point vector by a scalar.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  scale      scale factor to be applied
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_scale_f32(
+  float32_t * pSrc,
+  float32_t scale,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Multiplies a Q7 vector by a scalar.
+   * @param[in]  pSrc        points to the input vector
+   * @param[in]  scaleFract  fractional portion of the scale value
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to the output vector
+   * @param[in]  blockSize   number of samples in the vector
+   */
+  void arm_scale_q7(
+  q7_t * pSrc,
+  q7_t scaleFract,
+  int8_t shift,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Multiplies a Q15 vector by a scalar.
+   * @param[in]  pSrc        points to the input vector
+   * @param[in]  scaleFract  fractional portion of the scale value
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to the output vector
+   * @param[in]  blockSize   number of samples in the vector
+   */
+  void arm_scale_q15(
+  q15_t * pSrc,
+  q15_t scaleFract,
+  int8_t shift,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Multiplies a Q31 vector by a scalar.
+   * @param[in]  pSrc        points to the input vector
+   * @param[in]  scaleFract  fractional portion of the scale value
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to the output vector
+   * @param[in]  blockSize   number of samples in the vector
+   */
+  void arm_scale_q31(
+  q31_t * pSrc,
+  q31_t scaleFract,
+  int8_t shift,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q7 vector absolute value.
+   * @param[in]  pSrc       points to the input buffer
+   * @param[out] pDst       points to the output buffer
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_abs_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Floating-point vector absolute value.
+   * @param[in]  pSrc       points to the input buffer
+   * @param[out] pDst       points to the output buffer
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_abs_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q15 vector absolute value.
+   * @param[in]  pSrc       points to the input buffer
+   * @param[out] pDst       points to the output buffer
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_abs_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q31 vector absolute value.
+   * @param[in]  pSrc       points to the input buffer
+   * @param[out] pDst       points to the output buffer
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_abs_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Dot product of floating-point vectors.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[in]  blockSize  number of samples in each vector
+   * @param[out] result     output result returned here
+   */
+  void arm_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t blockSize,
+  float32_t * result);
+
+
+  /**
+   * @brief Dot product of Q7 vectors.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[in]  blockSize  number of samples in each vector
+   * @param[out] result     output result returned here
+   */
+  void arm_dot_prod_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  uint32_t blockSize,
+  q31_t * result);
+
+
+  /**
+   * @brief Dot product of Q15 vectors.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[in]  blockSize  number of samples in each vector
+   * @param[out] result     output result returned here
+   */
+  void arm_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+
+  /**
+   * @brief Dot product of Q31 vectors.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[in]  blockSize  number of samples in each vector
+   * @param[out] result     output result returned here
+   */
+  void arm_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+
+  /**
+   * @brief  Shifts the elements of a Q7 vector a specified number of bits.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  shiftBits  number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_shift_q7(
+  q7_t * pSrc,
+  int8_t shiftBits,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Shifts the elements of a Q15 vector a specified number of bits.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  shiftBits  number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_shift_q15(
+  q15_t * pSrc,
+  int8_t shiftBits,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Shifts the elements of a Q31 vector a specified number of bits.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  shiftBits  number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_shift_q31(
+  q31_t * pSrc,
+  int8_t shiftBits,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Adds a constant offset to a floating-point vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  offset     is the offset to be added
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_offset_f32(
+  float32_t * pSrc,
+  float32_t offset,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Adds a constant offset to a Q7 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  offset     is the offset to be added
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_offset_q7(
+  q7_t * pSrc,
+  q7_t offset,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Adds a constant offset to a Q15 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  offset     is the offset to be added
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_offset_q15(
+  q15_t * pSrc,
+  q15_t offset,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Adds a constant offset to a Q31 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  offset     is the offset to be added
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_offset_q31(
+  q31_t * pSrc,
+  q31_t offset,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Negates the elements of a floating-point vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_negate_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Negates the elements of a Q7 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_negate_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Negates the elements of a Q15 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_negate_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Negates the elements of a Q31 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_negate_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Copies the elements of a floating-point vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_copy_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Copies the elements of a Q7 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_copy_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Copies the elements of a Q15 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_copy_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Copies the elements of a Q31 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_copy_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Fills a constant value into a floating-point vector.
+   * @param[in]  value      input value to be filled
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_fill_f32(
+  float32_t value,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Fills a constant value into a Q7 vector.
+   * @param[in]  value      input value to be filled
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_fill_q7(
+  q7_t value,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Fills a constant value into a Q15 vector.
+   * @param[in]  value      input value to be filled
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_fill_q15(
+  q15_t value,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Fills a constant value into a Q31 vector.
+   * @param[in]  value      input value to be filled
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_fill_q31(
+  q31_t value,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+/**
+ * @brief Convolution of floating-point sequences.
+ * @param[in]  pSrcA    points to the first input sequence.
+ * @param[in]  srcALen  length of the first input sequence.
+ * @param[in]  pSrcB    points to the second input sequence.
+ * @param[in]  srcBLen  length of the second input sequence.
+ * @param[out] pDst     points to the location where the output result is written.  Length srcALen+srcBLen-1.
+ */
+  void arm_conv_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q15 sequences.
+   * @param[in]  pSrcA      points to the first input sequence.
+   * @param[in]  srcALen    length of the first input sequence.
+   * @param[in]  pSrcB      points to the second input sequence.
+   * @param[in]  srcBLen    length of the second input sequence.
+   * @param[out] pDst       points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  pScratch1  points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2  points to scratch buffer of size min(srcALen, srcBLen).
+   */
+  void arm_conv_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+/**
+ * @brief Convolution of Q15 sequences.
+ * @param[in]  pSrcA    points to the first input sequence.
+ * @param[in]  srcALen  length of the first input sequence.
+ * @param[in]  pSrcB    points to the second input sequence.
+ * @param[in]  srcBLen  length of the second input sequence.
+ * @param[out] pDst     points to the location where the output result is written.  Length srcALen+srcBLen-1.
+ */
+  void arm_conv_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length srcALen+srcBLen-1.
+   */
+  void arm_conv_fast_q15(
+          q15_t * pSrcA,
+          uint32_t srcALen,
+          q15_t * pSrcB,
+          uint32_t srcBLen,
+          q15_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA      points to the first input sequence.
+   * @param[in]  srcALen    length of the first input sequence.
+   * @param[in]  pSrcB      points to the second input sequence.
+   * @param[in]  srcBLen    length of the second input sequence.
+   * @param[out] pDst       points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  pScratch1  points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2  points to scratch buffer of size min(srcALen, srcBLen).
+   */
+  void arm_conv_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Convolution of Q31 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length srcALen+srcBLen-1.
+   */
+  void arm_conv_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length srcALen+srcBLen-1.
+   */
+  void arm_conv_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+    /**
+   * @brief Convolution of Q7 sequences.
+   * @param[in]  pSrcA      points to the first input sequence.
+   * @param[in]  srcALen    length of the first input sequence.
+   * @param[in]  pSrcB      points to the second input sequence.
+   * @param[in]  srcBLen    length of the second input sequence.
+   * @param[out] pDst       points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  pScratch1  points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2  points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   */
+  void arm_conv_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Convolution of Q7 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length srcALen+srcBLen-1.
+   */
+  void arm_conv_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+
+  /**
+   * @brief Partial convolution of floating-point sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @param[in]  pScratch1   points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2   points to scratch buffer of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_fast_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @param[in]  pScratch1   points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2   points to scratch buffer of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Partial convolution of Q31 sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q7 sequences
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @param[in]  pScratch1   points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2   points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+/**
+   * @brief Partial convolution of Q7 sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q15_t *pCoeffs;             /**< points to the coefficient array. The array is of length numTaps.*/
+    q15_t *pState;              /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } arm_fir_decimate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q31_t *pCoeffs;             /**< points to the coefficient array. The array is of length numTaps.*/
+    q31_t *pState;              /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } arm_fir_decimate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    float32_t *pCoeffs;         /**< points to the coefficient array. The array is of length numTaps.*/
+    float32_t *pState;          /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } arm_fir_decimate_instance_f32;
+
+
+  /**
+   * @brief Processing function for the floating-point FIR decimator.
+   * @param[in]  S          points to an instance of the floating-point FIR decimator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_decimate_f32(
+  const arm_fir_decimate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point FIR decimator.
+   * @param[in,out] S          points to an instance of the floating-point FIR decimator structure.
+   * @param[in]     numTaps    number of coefficients in the filter.
+   * @param[in]     M          decimation factor.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+  arm_status arm_fir_decimate_init_f32(
+  arm_fir_decimate_instance_f32 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR decimator.
+   * @param[in]  S          points to an instance of the Q15 FIR decimator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_decimate_q15(
+  const arm_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q15 FIR decimator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_decimate_fast_q15(
+  const arm_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 FIR decimator.
+   * @param[in,out] S          points to an instance of the Q15 FIR decimator structure.
+   * @param[in]     numTaps    number of coefficients in the filter.
+   * @param[in]     M          decimation factor.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+  arm_status arm_fir_decimate_init_q15(
+  arm_fir_decimate_instance_q15 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR decimator.
+   * @param[in]  S     points to an instance of the Q31 FIR decimator structure.
+   * @param[in]  pSrc  points to the block of input data.
+   * @param[out] pDst  points to the block of output data
+   * @param[in] blockSize number of input samples to process per call.
+   */
+  void arm_fir_decimate_q31(
+  const arm_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q31 FIR decimator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_decimate_fast_q31(
+  arm_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 FIR decimator.
+   * @param[in,out] S          points to an instance of the Q31 FIR decimator structure.
+   * @param[in]     numTaps    number of coefficients in the filter.
+   * @param[in]     M          decimation factor.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+  arm_status arm_fir_decimate_init_q31(
+  arm_fir_decimate_instance_q31 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q15_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q15_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } arm_fir_interpolate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q31_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q31_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } arm_fir_interpolate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                     /**< upsample factor. */
+    uint16_t phaseLength;          /**< length of each polyphase filter component. */
+    float32_t *pCoeffs;            /**< points to the coefficient array. The array is of length L*phaseLength. */
+    float32_t *pState;             /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */
+  } arm_fir_interpolate_instance_f32;
+
+
+  /**
+   * @brief Processing function for the Q15 FIR interpolator.
+   * @param[in]  S          points to an instance of the Q15 FIR interpolator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_interpolate_q15(
+  const arm_fir_interpolate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 FIR interpolator.
+   * @param[in,out] S          points to an instance of the Q15 FIR interpolator structure.
+   * @param[in]     L          upsample factor.
+   * @param[in]     numTaps    number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficient buffer.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+  arm_status arm_fir_interpolate_init_q15(
+  arm_fir_interpolate_instance_q15 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR interpolator.
+   * @param[in]  S          points to an instance of the Q15 FIR interpolator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_interpolate_q31(
+  const arm_fir_interpolate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 FIR interpolator.
+   * @param[in,out] S          points to an instance of the Q31 FIR interpolator structure.
+   * @param[in]     L          upsample factor.
+   * @param[in]     numTaps    number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficient buffer.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+  arm_status arm_fir_interpolate_init_q31(
+  arm_fir_interpolate_instance_q31 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point FIR interpolator.
+   * @param[in]  S          points to an instance of the floating-point FIR interpolator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_interpolate_f32(
+  const arm_fir_interpolate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point FIR interpolator.
+   * @param[in,out] S          points to an instance of the floating-point FIR interpolator structure.
+   * @param[in]     L          upsample factor.
+   * @param[in]     numTaps    number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficient buffer.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+  arm_status arm_fir_interpolate_init_f32(
+  arm_fir_interpolate_instance_f32 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;       /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q63_t *pState;           /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< additional shift, in bits, applied to each output sample. */
+  } arm_biquad_cas_df1_32x64_ins_q31;
+
+
+  /**
+   * @param[in]  S          points to an instance of the high precision Q31 Biquad cascade filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cas_df1_32x64_q31(
+  const arm_biquad_cas_df1_32x64_ins_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @param[in,out] S          points to an instance of the high precision Q31 Biquad cascade filter structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     postShift  shift to be applied to the output. Varies according to the coefficients format
+   */
+  void arm_biquad_cas_df1_32x64_init_q31(
+  arm_biquad_cas_df1_32x64_ins_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q63_t * pState,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_cascade_df2T_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_cascade_stereo_df2T_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float64_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float64_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_cascade_df2T_instance_f64;
+
+
+  /**
+   * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in]  S          points to an instance of the filter data structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df2T_f32(
+  const arm_biquad_cascade_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels
+   * @param[in]  S          points to an instance of the filter data structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_stereo_df2T_f32(
+  const arm_biquad_cascade_stereo_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in]  S          points to an instance of the filter data structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df2T_f64(
+  const arm_biquad_cascade_df2T_instance_f64 * S,
+  float64_t * pSrc,
+  float64_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the filter data structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   */
+  void arm_biquad_cascade_df2T_init_f32(
+  arm_biquad_cascade_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief  Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the filter data structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   */
+  void arm_biquad_cascade_stereo_df2T_init_f32(
+  arm_biquad_cascade_stereo_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief  Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the filter data structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   */
+  void arm_biquad_cascade_df2T_init_f64(
+  arm_biquad_cascade_df2T_instance_f64 * S,
+  uint8_t numStages,
+  float64_t * pCoeffs,
+  float64_t * pState);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    q15_t *pState;                       /**< points to the state variable array. The array is of length numStages. */
+    q15_t *pCoeffs;                      /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    q31_t *pState;                       /**< points to the state variable array. The array is of length numStages. */
+    q31_t *pCoeffs;                      /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages. */
+    float32_t *pCoeffs;                  /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_f32;
+
+
+  /**
+   * @brief Initialization function for the Q15 FIR lattice filter.
+   * @param[in] S          points to an instance of the Q15 FIR lattice structure.
+   * @param[in] numStages  number of filter stages.
+   * @param[in] pCoeffs    points to the coefficient buffer.  The array is of length numStages.
+   * @param[in] pState     points to the state buffer.  The array is of length numStages.
+   */
+  void arm_fir_lattice_init_q15(
+  arm_fir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR lattice filter.
+   * @param[in]  S          points to an instance of the Q15 FIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_lattice_q15(
+  const arm_fir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for the Q31 FIR lattice filter.
+   * @param[in] S          points to an instance of the Q31 FIR lattice structure.
+   * @param[in] numStages  number of filter stages.
+   * @param[in] pCoeffs    points to the coefficient buffer.  The array is of length numStages.
+   * @param[in] pState     points to the state buffer.   The array is of length numStages.
+   */
+  void arm_fir_lattice_init_q31(
+  arm_fir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR lattice filter.
+   * @param[in]  S          points to an instance of the Q31 FIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_lattice_q31(
+  const arm_fir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the floating-point FIR lattice filter.
+ * @param[in] S          points to an instance of the floating-point FIR lattice structure.
+ * @param[in] numStages  number of filter stages.
+ * @param[in] pCoeffs    points to the coefficient buffer.  The array is of length numStages.
+ * @param[in] pState     points to the state buffer.  The array is of length numStages.
+ */
+  void arm_fir_lattice_init_f32(
+  arm_fir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief Processing function for the floating-point FIR lattice filter.
+   * @param[in]  S          points to an instance of the floating-point FIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_lattice_f32(
+  const arm_fir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    q15_t *pState;                       /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q15_t *pkCoeffs;                     /**< points to the reflection coefficient array. The array is of length numStages. */
+    q15_t *pvCoeffs;                     /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    q31_t *pState;                       /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q31_t *pkCoeffs;                     /**< points to the reflection coefficient array. The array is of length numStages. */
+    q31_t *pvCoeffs;                     /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages+blockSize. */
+    float32_t *pkCoeffs;                 /**< points to the reflection coefficient array. The array is of length numStages. */
+    float32_t *pvCoeffs;                 /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_f32;
+
+
+  /**
+   * @brief Processing function for the floating-point IIR lattice filter.
+   * @param[in]  S          points to an instance of the floating-point IIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_f32(
+  const arm_iir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for the floating-point IIR lattice filter.
+   * @param[in] S          points to an instance of the floating-point IIR lattice structure.
+   * @param[in] numStages  number of stages in the filter.
+   * @param[in] pkCoeffs   points to the reflection coefficient buffer.  The array is of length numStages.
+   * @param[in] pvCoeffs   points to the ladder coefficient buffer.  The array is of length numStages+1.
+   * @param[in] pState     points to the state buffer.  The array is of length numStages+blockSize-1.
+   * @param[in] blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_init_f32(
+  arm_iir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pkCoeffs,
+  float32_t * pvCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 IIR lattice filter.
+   * @param[in]  S          points to an instance of the Q31 IIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_q31(
+  const arm_iir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for the Q31 IIR lattice filter.
+   * @param[in] S          points to an instance of the Q31 IIR lattice structure.
+   * @param[in] numStages  number of stages in the filter.
+   * @param[in] pkCoeffs   points to the reflection coefficient buffer.  The array is of length numStages.
+   * @param[in] pvCoeffs   points to the ladder coefficient buffer.  The array is of length numStages+1.
+   * @param[in] pState     points to the state buffer.  The array is of length numStages+blockSize.
+   * @param[in] blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_init_q31(
+  arm_iir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pkCoeffs,
+  q31_t * pvCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 IIR lattice filter.
+   * @param[in]  S          points to an instance of the Q15 IIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_q15(
+  const arm_iir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the Q15 IIR lattice filter.
+ * @param[in] S          points to an instance of the fixed-point Q15 IIR lattice structure.
+ * @param[in] numStages  number of stages in the filter.
+ * @param[in] pkCoeffs   points to reflection coefficient buffer.  The array is of length numStages.
+ * @param[in] pvCoeffs   points to ladder coefficient buffer.  The array is of length numStages+1.
+ * @param[in] pState     points to state buffer.  The array is of length numStages+blockSize.
+ * @param[in] blockSize  number of samples to process per call.
+ */
+  void arm_iir_lattice_init_q15(
+  arm_iir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pkCoeffs,
+  q15_t * pvCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the floating-point LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    float32_t *pState;   /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;  /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;        /**< step size that controls filter coefficient updates. */
+  } arm_lms_instance_f32;
+
+
+  /**
+   * @brief Processing function for floating-point LMS filter.
+   * @param[in]  S          points to an instance of the floating-point LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_f32(
+  const arm_lms_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for floating-point LMS filter.
+   * @param[in] S          points to an instance of the floating-point LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to the coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   */
+  void arm_lms_init_f32(
+  arm_lms_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q15_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } arm_lms_instance_q15;
+
+
+  /**
+   * @brief Initialization function for the Q15 LMS filter.
+   * @param[in] S          points to an instance of the Q15 LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to the coefficient buffer.
+   * @param[in] pState     points to the state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   * @param[in] postShift  bit shift applied to coefficients.
+   */
+  void arm_lms_init_q15(
+  arm_lms_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+
+  /**
+   * @brief Processing function for Q15 LMS filter.
+   * @param[in]  S          points to an instance of the Q15 LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_q15(
+  const arm_lms_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q31_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } arm_lms_instance_q31;
+
+
+  /**
+   * @brief Processing function for Q31 LMS filter.
+   * @param[in]  S          points to an instance of the Q15 LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_q31(
+  const arm_lms_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for Q31 LMS filter.
+   * @param[in] S          points to an instance of the Q31 LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   * @param[in] postShift  bit shift applied to coefficients.
+   */
+  void arm_lms_init_q31(
+  arm_lms_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+
+  /**
+   * @brief Instance structure for the floating-point normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;         /**< step size that control filter coefficient updates. */
+    float32_t energy;     /**< saves previous frame energy. */
+    float32_t x0;         /**< saves previous input sample. */
+  } arm_lms_norm_instance_f32;
+
+
+  /**
+   * @brief Processing function for floating-point normalized LMS filter.
+   * @param[in]  S          points to an instance of the floating-point normalized LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_norm_f32(
+  arm_lms_norm_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for floating-point normalized LMS filter.
+   * @param[in] S          points to an instance of the floating-point LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   */
+  void arm_lms_norm_init_f32(
+  arm_lms_norm_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    q31_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q31_t *recipTable;    /**< points to the reciprocal initial value table. */
+    q31_t energy;         /**< saves previous frame energy. */
+    q31_t x0;             /**< saves previous input sample. */
+  } arm_lms_norm_instance_q31;
+
+
+  /**
+   * @brief Processing function for Q31 normalized LMS filter.
+   * @param[in]  S          points to an instance of the Q31 normalized LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_norm_q31(
+  arm_lms_norm_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for Q31 normalized LMS filter.
+   * @param[in] S          points to an instance of the Q31 normalized LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   * @param[in] postShift  bit shift applied to coefficients.
+   */
+  void arm_lms_norm_init_q31(
+  arm_lms_norm_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Instance structure for the Q15 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< Number of coefficients in the filter. */
+    q15_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q15_t *recipTable;    /**< Points to the reciprocal initial value table. */
+    q15_t energy;         /**< saves previous frame energy. */
+    q15_t x0;             /**< saves previous input sample. */
+  } arm_lms_norm_instance_q15;
+
+
+  /**
+   * @brief Processing function for Q15 normalized LMS filter.
+   * @param[in]  S          points to an instance of the Q15 normalized LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_norm_q15(
+  arm_lms_norm_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for Q15 normalized LMS filter.
+   * @param[in] S          points to an instance of the Q15 normalized LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   * @param[in] postShift  bit shift applied to coefficients.
+   */
+  void arm_lms_norm_init_q15(
+  arm_lms_norm_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Correlation of floating-point sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+  void arm_correlate_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+
+   /**
+   * @brief Correlation of Q15 sequences
+   * @param[in]  pSrcA     points to the first input sequence.
+   * @param[in]  srcALen   length of the first input sequence.
+   * @param[in]  pSrcB     points to the second input sequence.
+   * @param[in]  srcBLen   length of the second input sequence.
+   * @param[out] pDst      points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  pScratch  points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   */
+  void arm_correlate_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+
+  /**
+   * @brief Correlation of Q15 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+
+  void arm_correlate_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+
+  /**
+   * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+
+  void arm_correlate_fast_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+
+  /**
+   * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+   * @param[in]  pSrcA     points to the first input sequence.
+   * @param[in]  srcALen   length of the first input sequence.
+   * @param[in]  pSrcB     points to the second input sequence.
+   * @param[in]  srcBLen   length of the second input sequence.
+   * @param[out] pDst      points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  pScratch  points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   */
+  void arm_correlate_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+
+  /**
+   * @brief Correlation of Q31 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+  void arm_correlate_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+  /**
+   * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+  void arm_correlate_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+ /**
+   * @brief Correlation of Q7 sequences.
+   * @param[in]  pSrcA      points to the first input sequence.
+   * @param[in]  srcALen    length of the first input sequence.
+   * @param[in]  pSrcB      points to the second input sequence.
+   * @param[in]  srcBLen    length of the second input sequence.
+   * @param[out] pDst       points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  pScratch1  points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2  points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   */
+  void arm_correlate_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Correlation of Q7 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+  void arm_correlate_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+
+  /**
+   * @brief Instance structure for the floating-point sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    float32_t *pState;            /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    float32_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_f32;
+
+  /**
+   * @brief Instance structure for the Q31 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q31_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q31_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q31;
+
+  /**
+   * @brief Instance structure for the Q15 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q15_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q15_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q7 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q7_t *pState;                 /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q7_t *pCoeffs;                /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q7;
+
+
+  /**
+   * @brief Processing function for the floating-point sparse FIR filter.
+   * @param[in]  S           points to an instance of the floating-point sparse FIR structure.
+   * @param[in]  pSrc        points to the block of input data.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  pScratchIn  points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize   number of input samples to process per call.
+   */
+  void arm_fir_sparse_f32(
+  arm_fir_sparse_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  float32_t * pScratchIn,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point sparse FIR filter.
+   * @param[in,out] S          points to an instance of the floating-point sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     pCoeffs    points to the array of filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     pTapDelay  points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   */
+  void arm_fir_sparse_init_f32(
+  arm_fir_sparse_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 sparse FIR filter.
+   * @param[in]  S           points to an instance of the Q31 sparse FIR structure.
+   * @param[in]  pSrc        points to the block of input data.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  pScratchIn  points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize   number of input samples to process per call.
+   */
+  void arm_fir_sparse_q31(
+  arm_fir_sparse_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  q31_t * pScratchIn,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 sparse FIR filter.
+   * @param[in,out] S          points to an instance of the Q31 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     pCoeffs    points to the array of filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     pTapDelay  points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   */
+  void arm_fir_sparse_init_q31(
+  arm_fir_sparse_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 sparse FIR filter.
+   * @param[in]  S            points to an instance of the Q15 sparse FIR structure.
+   * @param[in]  pSrc         points to the block of input data.
+   * @param[out] pDst         points to the block of output data
+   * @param[in]  pScratchIn   points to a temporary buffer of size blockSize.
+   * @param[in]  pScratchOut  points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize    number of input samples to process per call.
+   */
+  void arm_fir_sparse_q15(
+  arm_fir_sparse_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  q15_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 sparse FIR filter.
+   * @param[in,out] S          points to an instance of the Q15 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     pCoeffs    points to the array of filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     pTapDelay  points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   */
+  void arm_fir_sparse_init_q15(
+  arm_fir_sparse_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q7 sparse FIR filter.
+   * @param[in]  S            points to an instance of the Q7 sparse FIR structure.
+   * @param[in]  pSrc         points to the block of input data.
+   * @param[out] pDst         points to the block of output data
+   * @param[in]  pScratchIn   points to a temporary buffer of size blockSize.
+   * @param[in]  pScratchOut  points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize    number of input samples to process per call.
+   */
+  void arm_fir_sparse_q7(
+  arm_fir_sparse_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  q7_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q7 sparse FIR filter.
+   * @param[in,out] S          points to an instance of the Q7 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     pCoeffs    points to the array of filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     pTapDelay  points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   */
+  void arm_fir_sparse_init_q7(
+  arm_fir_sparse_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Floating-point sin_cos function.
+   * @param[in]  theta   input value in degrees
+   * @param[out] pSinVal  points to the processed sine output.
+   * @param[out] pCosVal  points to the processed cos output.
+   */
+  void arm_sin_cos_f32(
+  float32_t theta,
+  float32_t * pSinVal,
+  float32_t * pCosVal);
+
+
+  /**
+   * @brief  Q31 sin_cos function.
+   * @param[in]  theta    scaled input value in degrees
+   * @param[out] pSinVal  points to the processed sine output.
+   * @param[out] pCosVal  points to the processed cosine output.
+   */
+  void arm_sin_cos_q31(
+  q31_t theta,
+  q31_t * pSinVal,
+  q31_t * pCosVal);
+
+
+  /**
+   * @brief  Floating-point complex conjugate.
+   * @param[in]  pSrc        points to the input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_conj_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q31 complex conjugate.
+   * @param[in]  pSrc        points to the input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_conj_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q15 complex conjugate.
+   * @param[in]  pSrc        points to the input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_conj_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Floating-point complex magnitude squared
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_squared_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q31 complex magnitude squared
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_squared_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q15 complex magnitude squared
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_squared_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+ /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup PID PID Motor Control
+   *
+   * A Proportional Integral Derivative (PID) controller is a generic feedback control
+   * loop mechanism widely used in industrial control systems.
+   * A PID controller is the most commonly used type of feedback controller.
+   *
+   * This set of functions implements (PID) controllers
+   * for Q15, Q31, and floating-point data types.  The functions operate on a single sample
+   * of data and each call to the function returns a single processed value.
+   * <code>S</code> points to an instance of the PID control data structure.  <code>in</code>
+   * is the input sample value. The functions return the output value.
+   *
+   * \par Algorithm:
+   * <pre>
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  </pre>
+   *
+   * \par
+   * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
+   *
+   * \par
+   * \image html PID.gif "Proportional Integral Derivative Controller"
+   *
+   * \par
+   * The PID controller calculates an "error" value as the difference between
+   * the measured output and the reference input.
+   * The controller attempts to minimize the error by adjusting the process control inputs.
+   * The proportional value determines the reaction to the current error,
+   * the integral value determines the reaction based on the sum of recent errors,
+   * and the derivative value determines the reaction based on the rate at which the error has been changing.
+   *
+   * \par Instance Structure
+   * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
+   * A separate instance structure must be defined for each PID Controller.
+   * There are separate instance structure declarations for each of the 3 supported data types.
+   *
+   * \par Reset Functions
+   * There is also an associated reset function for each data type which clears the state array.
+   *
+   * \par Initialization Functions
+   * There is also an associated initialization function for each data type.
+   * The initialization function performs the following operations:
+   * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
+   * - Zeros out the values in the state buffer.
+   *
+   * \par
+   * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
+   *
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the fixed-point versions of the PID Controller functions.
+   * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup PID
+   * @{
+   */
+
+  /**
+   * @brief  Process function for the floating-point PID Control.
+   * @param[in,out] S   is an instance of the floating-point PID Control structure
+   * @param[in]     in  input sample to process
+   * @return out processed output sample.
+   */
+  static __INLINE float32_t arm_pid_f32(
+  arm_pid_instance_f32 * S,
+  float32_t in)
+  {
+    float32_t out;
+
+    /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]  */
+    out = (S->A0 * in) +
+      (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+
+  }
+
+  /**
+   * @brief  Process function for the Q31 PID Control.
+   * @param[in,out] S  points to an instance of the Q31 PID Control structure
+   * @param[in]     in  input sample to process
+   * @return out processed output sample.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 64-bit accumulator.
+   * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
+   * Thus, if the accumulator result overflows it wraps around rather than clip.
+   * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
+   * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
+   */
+  static __INLINE q31_t arm_pid_q31(
+  arm_pid_instance_q31 * S,
+  q31_t in)
+  {
+    q63_t acc;
+    q31_t out;
+
+    /* acc = A0 * x[n]  */
+    acc = (q63_t) S->A0 * in;
+
+    /* acc += A1 * x[n-1] */
+    acc += (q63_t) S->A1 * S->state[0];
+
+    /* acc += A2 * x[n-2]  */
+    acc += (q63_t) S->A2 * S->state[1];
+
+    /* convert output to 1.31 format to add y[n-1] */
+    out = (q31_t) (acc >> 31u);
+
+    /* out += y[n-1] */
+    out += S->state[2];
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+  }
+
+
+  /**
+   * @brief  Process function for the Q15 PID Control.
+   * @param[in,out] S   points to an instance of the Q15 PID Control structure
+   * @param[in]     in  input sample to process
+   * @return out processed output sample.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using a 64-bit internal accumulator.
+   * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
+   * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
+   * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
+   * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
+   * Lastly, the accumulator is saturated to yield a result in 1.15 format.
+   */
+  static __INLINE q15_t arm_pid_q15(
+  arm_pid_instance_q15 * S,
+  q15_t in)
+  {
+    q63_t acc;
+    q15_t out;
+
+#ifndef ARM_MATH_CM0_FAMILY
+    __SIMD32_TYPE *vstate;
+
+    /* Implementation of PID controller */
+
+    /* acc = A0 * x[n]  */
+    acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in);
+
+    /* acc += A1 * x[n-1] + A2 * x[n-2]  */
+    vstate = __SIMD32_CONST(S->state);
+    acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc);
+#else
+    /* acc = A0 * x[n]  */
+    acc = ((q31_t) S->A0) * in;
+
+    /* acc += A1 * x[n-1] + A2 * x[n-2]  */
+    acc += (q31_t) S->A1 * S->state[0];
+    acc += (q31_t) S->A2 * S->state[1];
+#endif
+
+    /* acc += y[n-1] */
+    acc += (q31_t) S->state[2] << 15;
+
+    /* saturate the output */
+    out = (q15_t) (__SSAT((acc >> 15), 16));
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+  }
+
+  /**
+   * @} end of PID group
+   */
+
+
+  /**
+   * @brief Floating-point matrix inverse.
+   * @param[in]  src   points to the instance of the input floating-point matrix structure.
+   * @param[out] dst   points to the instance of the output floating-point matrix structure.
+   * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+   * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+   */
+  arm_status arm_mat_inverse_f32(
+  const arm_matrix_instance_f32 * src,
+  arm_matrix_instance_f32 * dst);
+
+
+  /**
+   * @brief Floating-point matrix inverse.
+   * @param[in]  src   points to the instance of the input floating-point matrix structure.
+   * @param[out] dst   points to the instance of the output floating-point matrix structure.
+   * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+   * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+   */
+  arm_status arm_mat_inverse_f64(
+  const arm_matrix_instance_f64 * src,
+  arm_matrix_instance_f64 * dst);
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup clarke Vector Clarke Transform
+   * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
+   * Generally the Clarke transform uses three-phase currents <code>Ia, Ib and Ic</code> to calculate currents
+   * in the two-phase orthogonal stator axis <code>Ialpha</code> and <code>Ibeta</code>.
+   * When <code>Ialpha</code> is superposed with <code>Ia</code> as shown in the figure below
+   * \image html clarke.gif Stator current space vector and its components in (a,b).
+   * and <code>Ia + Ib + Ic = 0</code>, in this condition <code>Ialpha</code> and <code>Ibeta</code>
+   * can be calculated using only <code>Ia</code> and <code>Ib</code>.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html clarkeFormula.gif
+   * where <code>Ia</code> and <code>Ib</code> are the instantaneous stator phases and
+   * <code>pIalpha</code> and <code>pIbeta</code> are the two coordinates of time invariant vector.
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Clarke transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup clarke
+   * @{
+   */
+
+  /**
+   *
+   * @brief  Floating-point Clarke transform
+   * @param[in]  Ia       input three-phase coordinate <code>a</code>
+   * @param[in]  Ib       input three-phase coordinate <code>b</code>
+   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+   */
+  static __INLINE void arm_clarke_f32(
+  float32_t Ia,
+  float32_t Ib,
+  float32_t * pIalpha,
+  float32_t * pIbeta)
+  {
+    /* Calculate pIalpha using the equation, pIalpha = Ia */
+    *pIalpha = Ia;
+
+    /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
+    *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib);
+  }
+
+
+  /**
+   * @brief  Clarke transform for Q31 version
+   * @param[in]  Ia       input three-phase coordinate <code>a</code>
+   * @param[in]  Ib       input three-phase coordinate <code>b</code>
+   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition, hence there is no risk of overflow.
+   */
+  static __INLINE void arm_clarke_q31(
+  q31_t Ia,
+  q31_t Ib,
+  q31_t * pIalpha,
+  q31_t * pIbeta)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+
+    /* Calculating pIalpha from Ia by equation pIalpha = Ia */
+    *pIalpha = Ia;
+
+    /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+    product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
+
+    /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+    product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
+
+    /* pIbeta is calculated by adding the intermediate products */
+    *pIbeta = __QADD(product1, product2);
+  }
+
+  /**
+   * @} end of clarke group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to Q31 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_q7_to_q31(
+  q7_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup inv_clarke Vector Inverse Clarke Transform
+   * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html clarkeInvFormula.gif
+   * where <code>pIa</code> and <code>pIb</code> are the instantaneous stator phases and
+   * <code>Ialpha</code> and <code>Ibeta</code> are the two coordinates of time invariant vector.
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Clarke transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup inv_clarke
+   * @{
+   */
+
+   /**
+   * @brief  Floating-point Inverse Clarke transform
+   * @param[in]  Ialpha  input two-phase orthogonal vector axis alpha
+   * @param[in]  Ibeta   input two-phase orthogonal vector axis beta
+   * @param[out] pIa     points to output three-phase coordinate <code>a</code>
+   * @param[out] pIb     points to output three-phase coordinate <code>b</code>
+   */
+  static __INLINE void arm_inv_clarke_f32(
+  float32_t Ialpha,
+  float32_t Ibeta,
+  float32_t * pIa,
+  float32_t * pIb)
+  {
+    /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+    *pIa = Ialpha;
+
+    /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
+    *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta;
+  }
+
+
+  /**
+   * @brief  Inverse Clarke transform for Q31 version
+   * @param[in]  Ialpha  input two-phase orthogonal vector axis alpha
+   * @param[in]  Ibeta   input two-phase orthogonal vector axis beta
+   * @param[out] pIa     points to output three-phase coordinate <code>a</code>
+   * @param[out] pIb     points to output three-phase coordinate <code>b</code>
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the subtraction, hence there is no risk of overflow.
+   */
+  static __INLINE void arm_inv_clarke_q31(
+  q31_t Ialpha,
+  q31_t Ibeta,
+  q31_t * pIa,
+  q31_t * pIb)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+
+    /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+    *pIa = Ialpha;
+
+    /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+    product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
+
+    /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+    product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
+
+    /* pIb is calculated by subtracting the products */
+    *pIb = __QSUB(product2, product1);
+  }
+
+  /**
+   * @} end of inv_clarke group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to Q15 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_q7_to_q15(
+  q7_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup park Vector Park Transform
+   *
+   * Forward Park transform converts the input two-coordinate vector to flux and torque components.
+   * The Park transform can be used to realize the transformation of the <code>Ialpha</code> and the <code>Ibeta</code> currents
+   * from the stationary to the moving reference frame and control the spatial relationship between
+   * the stator vector current and rotor flux vector.
+   * If we consider the d axis aligned with the rotor flux, the diagram below shows the
+   * current vector and the relationship from the two reference frames:
+   * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html parkFormula.gif
+   * where <code>Ialpha</code> and <code>Ibeta</code> are the stator vector components,
+   * <code>pId</code> and <code>pIq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+   * cosine and sine values of theta (rotor flux position).
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Park transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup park
+   * @{
+   */
+
+  /**
+   * @brief Floating-point Park transform
+   * @param[in]  Ialpha  input two-phase vector coordinate alpha
+   * @param[in]  Ibeta   input two-phase vector coordinate beta
+   * @param[out] pId     points to output   rotor reference frame d
+   * @param[out] pIq     points to output   rotor reference frame q
+   * @param[in]  sinVal  sine value of rotation angle theta
+   * @param[in]  cosVal  cosine value of rotation angle theta
+   *
+   * The function implements the forward Park transform.
+   *
+   */
+  static __INLINE void arm_park_f32(
+  float32_t Ialpha,
+  float32_t Ibeta,
+  float32_t * pId,
+  float32_t * pIq,
+  float32_t sinVal,
+  float32_t cosVal)
+  {
+    /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
+    *pId = Ialpha * cosVal + Ibeta * sinVal;
+
+    /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
+    *pIq = -Ialpha * sinVal + Ibeta * cosVal;
+  }
+
+
+  /**
+   * @brief  Park transform for Q31 version
+   * @param[in]  Ialpha  input two-phase vector coordinate alpha
+   * @param[in]  Ibeta   input two-phase vector coordinate beta
+   * @param[out] pId     points to output rotor reference frame d
+   * @param[out] pIq     points to output rotor reference frame q
+   * @param[in]  sinVal  sine value of rotation angle theta
+   * @param[in]  cosVal  cosine value of rotation angle theta
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition and subtraction, hence there is no risk of overflow.
+   */
+  static __INLINE void arm_park_q31(
+  q31_t Ialpha,
+  q31_t Ibeta,
+  q31_t * pId,
+  q31_t * pIq,
+  q31_t sinVal,
+  q31_t cosVal)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+    q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
+
+    /* Intermediate product is calculated by (Ialpha * cosVal) */
+    product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
+
+    /* Intermediate product is calculated by (Ibeta * sinVal) */
+    product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
+
+
+    /* Intermediate product is calculated by (Ialpha * sinVal) */
+    product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
+
+    /* Intermediate product is calculated by (Ibeta * cosVal) */
+    product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
+
+    /* Calculate pId by adding the two intermediate products 1 and 2 */
+    *pId = __QADD(product1, product2);
+
+    /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
+    *pIq = __QSUB(product4, product3);
+  }
+
+  /**
+   * @} end of park group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q7_to_float(
+  q7_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup inv_park Vector Inverse Park transform
+   * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html parkInvFormula.gif
+   * where <code>pIalpha</code> and <code>pIbeta</code> are the stator vector components,
+   * <code>Id</code> and <code>Iq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+   * cosine and sine values of theta (rotor flux position).
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Park transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup inv_park
+   * @{
+   */
+
+   /**
+   * @brief  Floating-point Inverse Park transform
+   * @param[in]  Id       input coordinate of rotor reference frame d
+   * @param[in]  Iq       input coordinate of rotor reference frame q
+   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+   * @param[in]  sinVal   sine value of rotation angle theta
+   * @param[in]  cosVal   cosine value of rotation angle theta
+   */
+  static __INLINE void arm_inv_park_f32(
+  float32_t Id,
+  float32_t Iq,
+  float32_t * pIalpha,
+  float32_t * pIbeta,
+  float32_t sinVal,
+  float32_t cosVal)
+  {
+    /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
+    *pIalpha = Id * cosVal - Iq * sinVal;
+
+    /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
+    *pIbeta = Id * sinVal + Iq * cosVal;
+  }
+
+
+  /**
+   * @brief  Inverse Park transform for   Q31 version
+   * @param[in]  Id       input coordinate of rotor reference frame d
+   * @param[in]  Iq       input coordinate of rotor reference frame q
+   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+   * @param[in]  sinVal   sine value of rotation angle theta
+   * @param[in]  cosVal   cosine value of rotation angle theta
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition, hence there is no risk of overflow.
+   */
+  static __INLINE void arm_inv_park_q31(
+  q31_t Id,
+  q31_t Iq,
+  q31_t * pIalpha,
+  q31_t * pIbeta,
+  q31_t sinVal,
+  q31_t cosVal)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+    q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
+
+    /* Intermediate product is calculated by (Id * cosVal) */
+    product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
+
+    /* Intermediate product is calculated by (Iq * sinVal) */
+    product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
+
+
+    /* Intermediate product is calculated by (Id * sinVal) */
+    product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
+
+    /* Intermediate product is calculated by (Iq * cosVal) */
+    product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
+
+    /* Calculate pIalpha by using the two intermediate products 1 and 2 */
+    *pIalpha = __QSUB(product1, product2);
+
+    /* Calculate pIbeta by using the two intermediate products 3 and 4 */
+    *pIbeta = __QADD(product4, product3);
+  }
+
+  /**
+   * @} end of Inverse park group
+   */
+
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q31_to_float(
+  q31_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @ingroup groupInterpolation
+   */
+
+  /**
+   * @defgroup LinearInterpolate Linear Interpolation
+   *
+   * Linear interpolation is a method of curve fitting using linear polynomials.
+   * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line
+   *
+   * \par
+   * \image html LinearInterp.gif "Linear interpolation"
+   *
+   * \par
+   * A  Linear Interpolate function calculates an output value(y), for the input(x)
+   * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values)
+   *
+   * \par Algorithm:
+   * <pre>
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * </pre>
+   *
+   * \par
+   * This set of functions implements Linear interpolation process
+   * for Q7, Q15, Q31, and floating-point data types.  The functions operate on a single
+   * sample of data and each call to the function returns a single processed value.
+   * <code>S</code> points to an instance of the Linear Interpolate function data structure.
+   * <code>x</code> is the input sample value. The functions returns the output value.
+   *
+   * \par
+   * if x is outside of the table boundary, Linear interpolation returns first value of the table
+   * if x is below input range and returns last value of table if x is above range.
+   */
+
+  /**
+   * @addtogroup LinearInterpolate
+   * @{
+   */
+
+  /**
+   * @brief  Process function for the floating-point Linear Interpolation Function.
+   * @param[in,out] S  is an instance of the floating-point Linear Interpolation structure
+   * @param[in]     x  input sample to process
+   * @return y processed output sample.
+   *
+   */
+  static __INLINE float32_t arm_linear_interp_f32(
+  arm_linear_interp_instance_f32 * S,
+  float32_t x)
+  {
+    float32_t y;
+    float32_t x0, x1;                            /* Nearest input values */
+    float32_t y0, y1;                            /* Nearest output values */
+    float32_t xSpacing = S->xSpacing;            /* spacing between input values */
+    int32_t i;                                   /* Index variable */
+    float32_t *pYData = S->pYData;               /* pointer to output table */
+
+    /* Calculation of index */
+    i = (int32_t) ((x - S->x1) / xSpacing);
+
+    if(i < 0)
+    {
+      /* Iniatilize output for below specified range as least output value of table */
+      y = pYData[0];
+    }
+    else if((uint32_t)i >= S->nValues)
+    {
+      /* Iniatilize output for above specified range as last output value of table */
+      y = pYData[S->nValues - 1];
+    }
+    else
+    {
+      /* Calculation of nearest input values */
+      x0 = S->x1 +  i      * xSpacing;
+      x1 = S->x1 + (i + 1) * xSpacing;
+
+      /* Read of nearest output values */
+      y0 = pYData[i];
+      y1 = pYData[i + 1];
+
+      /* Calculation of output */
+      y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0));
+
+    }
+
+    /* returns output value */
+    return (y);
+  }
+
+
+   /**
+   *
+   * @brief  Process function for the Q31 Linear Interpolation Function.
+   * @param[in] pYData   pointer to Q31 Linear Interpolation table
+   * @param[in] x        input sample to process
+   * @param[in] nValues  number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   *
+   */
+  static __INLINE q31_t arm_linear_interp_q31(
+  q31_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q31_t y;                                     /* output */
+    q31_t y0, y1;                                /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    int32_t index;                               /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    index = ((x & (q31_t)0xFFF00000) >> 20);
+
+    if(index >= (int32_t)(nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else if(index < 0)
+    {
+      return (pYData[0]);
+    }
+    else
+    {
+      /* 20 bits for the fractional part */
+      /* shift left by 11 to keep fract in 1.31 format */
+      fract = (x & 0x000FFFFF) << 11;
+
+      /* Read two nearest output values from the index in 1.31(q31) format */
+      y0 = pYData[index];
+      y1 = pYData[index + 1];
+
+      /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+      y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32));
+
+      /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+      y += ((q31_t) (((q63_t) y1 * fract) >> 32));
+
+      /* Convert y to 1.31 format */
+      return (y << 1u);
+    }
+  }
+
+
+  /**
+   *
+   * @brief  Process function for the Q15 Linear Interpolation Function.
+   * @param[in] pYData   pointer to Q15 Linear Interpolation table
+   * @param[in] x        input sample to process
+   * @param[in] nValues  number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   *
+   */
+  static __INLINE q15_t arm_linear_interp_q15(
+  q15_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q63_t y;                                     /* output */
+    q15_t y0, y1;                                /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    int32_t index;                               /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    index = ((x & (int32_t)0xFFF00000) >> 20);
+
+    if(index >= (int32_t)(nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else if(index < 0)
+    {
+      return (pYData[0]);
+    }
+    else
+    {
+      /* 20 bits for the fractional part */
+      /* fract is in 12.20 format */
+      fract = (x & 0x000FFFFF);
+
+      /* Read two nearest output values from the index */
+      y0 = pYData[index];
+      y1 = pYData[index + 1];
+
+      /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+      y = ((q63_t) y0 * (0xFFFFF - fract));
+
+      /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+      y += ((q63_t) y1 * (fract));
+
+      /* convert y to 1.15 format */
+      return (q15_t) (y >> 20);
+    }
+  }
+
+
+  /**
+   *
+   * @brief  Process function for the Q7 Linear Interpolation Function.
+   * @param[in] pYData   pointer to Q7 Linear Interpolation table
+   * @param[in] x        input sample to process
+   * @param[in] nValues  number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   */
+  static __INLINE q7_t arm_linear_interp_q7(
+  q7_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q31_t y;                                     /* output */
+    q7_t y0, y1;                                 /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    uint32_t index;                              /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    if (x < 0)
+    {
+      return (pYData[0]);
+    }
+    index = (x >> 20) & 0xfff;
+
+    if(index >= (nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else
+    {
+      /* 20 bits for the fractional part */
+      /* fract is in 12.20 format */
+      fract = (x & 0x000FFFFF);
+
+      /* Read two nearest output values from the index and are in 1.7(q7) format */
+      y0 = pYData[index];
+      y1 = pYData[index + 1];
+
+      /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */
+      y = ((y0 * (0xFFFFF - fract)));
+
+      /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */
+      y += (y1 * fract);
+
+      /* convert y to 1.7(q7) format */
+      return (q7_t) (y >> 20);
+     }
+  }
+
+  /**
+   * @} end of LinearInterpolate group
+   */
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for floating-point data.
+   * @param[in] x  input value in radians.
+   * @return  sin(x).
+   */
+  float32_t arm_sin_f32(
+  float32_t x);
+
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for Q31 data.
+   * @param[in] x  Scaled input value in radians.
+   * @return  sin(x).
+   */
+  q31_t arm_sin_q31(
+  q31_t x);
+
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for Q15 data.
+   * @param[in] x  Scaled input value in radians.
+   * @return  sin(x).
+   */
+  q15_t arm_sin_q15(
+  q15_t x);
+
+
+  /**
+   * @brief  Fast approximation to the trigonometric cosine function for floating-point data.
+   * @param[in] x  input value in radians.
+   * @return  cos(x).
+   */
+  float32_t arm_cos_f32(
+  float32_t x);
+
+
+  /**
+   * @brief Fast approximation to the trigonometric cosine function for Q31 data.
+   * @param[in] x  Scaled input value in radians.
+   * @return  cos(x).
+   */
+  q31_t arm_cos_q31(
+  q31_t x);
+
+
+  /**
+   * @brief  Fast approximation to the trigonometric cosine function for Q15 data.
+   * @param[in] x  Scaled input value in radians.
+   * @return  cos(x).
+   */
+  q15_t arm_cos_q15(
+  q15_t x);
+
+
+  /**
+   * @ingroup groupFastMath
+   */
+
+
+  /**
+   * @defgroup SQRT Square Root
+   *
+   * Computes the square root of a number.
+   * There are separate functions for Q15, Q31, and floating-point data types.
+   * The square root function is computed using the Newton-Raphson algorithm.
+   * This is an iterative algorithm of the form:
+   * <pre>
+   *      x1 = x0 - f(x0)/f'(x0)
+   * </pre>
+   * where <code>x1</code> is the current estimate,
+   * <code>x0</code> is the previous estimate, and
+   * <code>f'(x0)</code> is the derivative of <code>f()</code> evaluated at <code>x0</code>.
+   * For the square root function, the algorithm reduces to:
+   * <pre>
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * </pre>
+   */
+
+
+  /**
+   * @addtogroup SQRT
+   * @{
+   */
+
+  /**
+   * @brief  Floating-point square root function.
+   * @param[in]  in    input value.
+   * @param[out] pOut  square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+  static __INLINE arm_status arm_sqrt_f32(
+  float32_t in,
+  float32_t * pOut)
+  {
+    if(in >= 0.0f)
+    {
+
+#if   (__FPU_USED == 1) && defined ( __CC_ARM   )
+      *pOut = __sqrtf(in);
+#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
+      *pOut = __builtin_sqrtf(in);
+#elif (__FPU_USED == 1) && defined(__GNUC__)
+      *pOut = __builtin_sqrtf(in);
+#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000)
+      __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in));
+#else
+      *pOut = sqrtf(in);
+#endif
+
+      return (ARM_MATH_SUCCESS);
+    }
+    else
+    {
+      *pOut = 0.0f;
+      return (ARM_MATH_ARGUMENT_ERROR);
+    }
+  }
+
+
+  /**
+   * @brief Q31 square root function.
+   * @param[in]  in    input value.  The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF.
+   * @param[out] pOut  square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+  arm_status arm_sqrt_q31(
+  q31_t in,
+  q31_t * pOut);
+
+
+  /**
+   * @brief  Q15 square root function.
+   * @param[in]  in    input value.  The range of the input value is [0 +1) or 0x0000 to 0x7FFF.
+   * @param[out] pOut  square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+  arm_status arm_sqrt_q15(
+  q15_t in,
+  q15_t * pOut);
+
+  /**
+   * @} end of SQRT group
+   */
+
+
+  /**
+   * @brief floating-point Circular write function.
+   */
+  static __INLINE void arm_circularWrite_f32(
+  int32_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const int32_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = (uint16_t)wOffset;
+  }
+
+
+
+  /**
+   * @brief floating-point Circular Read function.
+   */
+  static __INLINE void arm_circularRead_f32(
+  int32_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  int32_t * dst,
+  int32_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (int32_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update rOffset.  Watch out for positive and negative value  */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+
+  /**
+   * @brief Q15 Circular write function.
+   */
+  static __INLINE void arm_circularWrite_q15(
+  q15_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const q15_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = (uint16_t)wOffset;
+  }
+
+
+  /**
+   * @brief Q15 Circular Read function.
+   */
+  static __INLINE void arm_circularRead_q15(
+  q15_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  q15_t * dst,
+  q15_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (q15_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+
+  /**
+   * @brief Q7 Circular write function.
+   */
+  static __INLINE void arm_circularWrite_q7(
+  q7_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const q7_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = (uint16_t)wOffset;
+  }
+
+
+  /**
+   * @brief Q7 Circular Read function.
+   */
+  static __INLINE void arm_circularRead_q7(
+  q7_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  q7_t * dst,
+  q7_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (q7_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update rOffset.  Watch out for positive and negative value */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_power_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_power_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_power_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_power_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Mean value of a Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_mean_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult);
+
+
+  /**
+   * @brief  Mean value of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_mean_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+
+  /**
+   * @brief  Mean value of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_mean_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Mean value of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_mean_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Variance of the elements of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_var_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Variance of the elements of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_var_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Variance of the elements of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_var_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+
+  /**
+   * @brief  Root Mean Square of the elements of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_rms_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Root Mean Square of the elements of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_rms_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Root Mean Square of the elements of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_rms_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+
+  /**
+   * @brief  Standard deviation of the elements of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_std_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Standard deviation of the elements of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_std_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Standard deviation of the elements of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_std_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+
+  /**
+   * @brief  Floating-point complex magnitude
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q31 complex magnitude
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q15 complex magnitude
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q15 complex dot product
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   * @param[out] realResult  real part of the result returned here
+   * @param[out] imagResult  imaginary part of the result returned here
+   */
+  void arm_cmplx_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t numSamples,
+  q31_t * realResult,
+  q31_t * imagResult);
+
+
+  /**
+   * @brief  Q31 complex dot product
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   * @param[out] realResult  real part of the result returned here
+   * @param[out] imagResult  imaginary part of the result returned here
+   */
+  void arm_cmplx_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t numSamples,
+  q63_t * realResult,
+  q63_t * imagResult);
+
+
+  /**
+   * @brief  Floating-point complex dot product
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   * @param[out] realResult  real part of the result returned here
+   * @param[out] imagResult  imaginary part of the result returned here
+   */
+  void arm_cmplx_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t numSamples,
+  float32_t * realResult,
+  float32_t * imagResult);
+
+
+  /**
+   * @brief  Q15 complex-by-real multiplication
+   * @param[in]  pSrcCmplx   points to the complex input vector
+   * @param[in]  pSrcReal    points to the real input vector
+   * @param[out] pCmplxDst   points to the complex output vector
+   * @param[in]  numSamples  number of samples in each vector
+   */
+  void arm_cmplx_mult_real_q15(
+  q15_t * pSrcCmplx,
+  q15_t * pSrcReal,
+  q15_t * pCmplxDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q31 complex-by-real multiplication
+   * @param[in]  pSrcCmplx   points to the complex input vector
+   * @param[in]  pSrcReal    points to the real input vector
+   * @param[out] pCmplxDst   points to the complex output vector
+   * @param[in]  numSamples  number of samples in each vector
+   */
+  void arm_cmplx_mult_real_q31(
+  q31_t * pSrcCmplx,
+  q31_t * pSrcReal,
+  q31_t * pCmplxDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Floating-point complex-by-real multiplication
+   * @param[in]  pSrcCmplx   points to the complex input vector
+   * @param[in]  pSrcReal    points to the real input vector
+   * @param[out] pCmplxDst   points to the complex output vector
+   * @param[in]  numSamples  number of samples in each vector
+   */
+  void arm_cmplx_mult_real_f32(
+  float32_t * pSrcCmplx,
+  float32_t * pSrcReal,
+  float32_t * pCmplxDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Minimum value of a Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] result     is output pointer
+   * @param[in]  index      is the array index of the minimum value in the input buffer.
+   */
+  void arm_min_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * result,
+  uint32_t * index);
+
+
+  /**
+   * @brief  Minimum value of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output pointer
+   * @param[in]  pIndex     is the array index of the minimum value in the input buffer.
+   */
+  void arm_min_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+
+  /**
+   * @brief  Minimum value of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output pointer
+   * @param[out] pIndex     is the array index of the minimum value in the input buffer.
+   */
+  void arm_min_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+
+  /**
+   * @brief  Minimum value of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output pointer
+   * @param[out] pIndex     is the array index of the minimum value in the input buffer.
+   */
+  void arm_min_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q7 vector.
+ * @param[in]  pSrc       points to the input buffer
+ * @param[in]  blockSize  length of the input vector
+ * @param[out] pResult    maximum value returned here
+ * @param[out] pIndex     index of maximum value returned here
+ */
+  void arm_max_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult,
+  uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q15 vector.
+ * @param[in]  pSrc       points to the input buffer
+ * @param[in]  blockSize  length of the input vector
+ * @param[out] pResult    maximum value returned here
+ * @param[out] pIndex     index of maximum value returned here
+ */
+  void arm_max_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q31 vector.
+ * @param[in]  pSrc       points to the input buffer
+ * @param[in]  blockSize  length of the input vector
+ * @param[out] pResult    maximum value returned here
+ * @param[out] pIndex     index of maximum value returned here
+ */
+  void arm_max_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a floating-point vector.
+ * @param[in]  pSrc       points to the input buffer
+ * @param[in]  blockSize  length of the input vector
+ * @param[out] pResult    maximum value returned here
+ * @param[out] pIndex     index of maximum value returned here
+ */
+  void arm_max_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+
+  /**
+   * @brief  Q15 complex-by-complex multiplication
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_mult_cmplx_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q31 complex-by-complex multiplication
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_mult_cmplx_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Floating-point complex-by-complex multiplication
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_mult_cmplx_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q31 vector.
+   * @param[in]  pSrc       points to the floating-point input vector
+   * @param[out] pDst       points to the Q31 output vector
+   * @param[in]  blockSize  length of the input vector
+   */
+  void arm_float_to_q31(
+  float32_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q15 vector.
+   * @param[in]  pSrc       points to the floating-point input vector
+   * @param[out] pDst       points to the Q15 output vector
+   * @param[in]  blockSize  length of the input vector
+   */
+  void arm_float_to_q15(
+  float32_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q7 vector.
+   * @param[in]  pSrc       points to the floating-point input vector
+   * @param[out] pDst       points to the Q7 output vector
+   * @param[in]  blockSize  length of the input vector
+   */
+  void arm_float_to_q7(
+  float32_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q31_to_q15(
+  q31_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q31_to_q7(
+  q31_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q15_to_float(
+  q15_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q15_to_q31(
+  q15_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q15_to_q7(
+  q15_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @ingroup groupInterpolation
+   */
+
+  /**
+   * @defgroup BilinearInterpolate Bilinear Interpolation
+   *
+   * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
+   * The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process
+   * determines values between the grid points.
+   * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
+   * Bilinear interpolation is often used in image processing to rescale images.
+   * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
+   *
+   * <b>Algorithm</b>
+   * \par
+   * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
+   * For floating-point, the instance structure is defined as:
+   * <pre>
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * </pre>
+   *
+   * \par
+   * where <code>numRows</code> specifies the number of rows in the table;
+   * <code>numCols</code> specifies the number of columns in the table;
+   * and <code>pData</code> points to an array of size <code>numRows*numCols</code> values.
+   * The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes.
+   * That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers.
+   *
+   * \par
+   * Let <code>(x, y)</code> specify the desired interpolation point.  Then define:
+   * <pre>
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * </pre>
+   * \par
+   * The interpolated output point is computed as:
+   * <pre>
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * </pre>
+   * Note that the coordinates (x, y) contain integer and fractional components.
+   * The integer components specify which portion of the table to use while the
+   * fractional components control the interpolation processor.
+   *
+   * \par
+   * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
+   */
+
+  /**
+   * @addtogroup BilinearInterpolate
+   * @{
+   */
+
+
+  /**
+  *
+  * @brief  Floating-point bilinear interpolation.
+  * @param[in,out] S  points to an instance of the interpolation structure.
+  * @param[in]     X  interpolation coordinate.
+  * @param[in]     Y  interpolation coordinate.
+  * @return out interpolated value.
+  */
+  static __INLINE float32_t arm_bilinear_interp_f32(
+  const arm_bilinear_interp_instance_f32 * S,
+  float32_t X,
+  float32_t Y)
+  {
+    float32_t out;
+    float32_t f00, f01, f10, f11;
+    float32_t *pData = S->pData;
+    int32_t xIndex, yIndex, index;
+    float32_t xdiff, ydiff;
+    float32_t b1, b2, b3, b4;
+
+    xIndex = (int32_t) X;
+    yIndex = (int32_t) Y;
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* Calculation of index for two nearest points in X-direction */
+    index = (xIndex - 1) + (yIndex - 1) * S->numCols;
+
+
+    /* Read two nearest points in X-direction */
+    f00 = pData[index];
+    f01 = pData[index + 1];
+
+    /* Calculation of index for two nearest points in Y-direction */
+    index = (xIndex - 1) + (yIndex) * S->numCols;
+
+
+    /* Read two nearest points in Y-direction */
+    f10 = pData[index];
+    f11 = pData[index + 1];
+
+    /* Calculation of intermediate values */
+    b1 = f00;
+    b2 = f01 - f00;
+    b3 = f10 - f00;
+    b4 = f00 - f01 - f10 + f11;
+
+    /* Calculation of fractional part in X */
+    xdiff = X - xIndex;
+
+    /* Calculation of fractional part in Y */
+    ydiff = Y - yIndex;
+
+    /* Calculation of bi-linear interpolated output */
+    out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
+
+    /* return to application */
+    return (out);
+  }
+
+
+  /**
+  *
+  * @brief  Q31 bilinear interpolation.
+  * @param[in,out] S  points to an instance of the interpolation structure.
+  * @param[in]     X  interpolation coordinate in 12.20 format.
+  * @param[in]     Y  interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+  static __INLINE q31_t arm_bilinear_interp_q31(
+  arm_bilinear_interp_instance_q31 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q31_t out;                                   /* Temporary output */
+    q31_t acc = 0;                               /* output */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    q31_t x1, x2, y1, y2;                        /* Nearest output values */
+    int32_t rI, cI;                              /* Row and column indices */
+    q31_t *pYData = S->pData;                    /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* shift left xfract by 11 to keep 1.31 format */
+    xfract = (X & 0x000FFFFF) << 11u;
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[(rI) + (int32_t)nCols * (cI)    ];
+    x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1];
+
+    /* 20 bits for the fractional part */
+    /* shift left yfract by 11 to keep 1.31 format */
+    yfract = (Y & 0x000FFFFF) << 11u;
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[(rI) + (int32_t)nCols * (cI + 1)    ];
+    y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
+    out = ((q31_t) (((q63_t) x1  * (0x7FFFFFFF - xfract)) >> 32));
+    acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32));
+
+    /* x2 * (xfract) * (1-yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (xfract) >> 32));
+
+    /* y1 * (1 - xfract) * (yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+    /* y2 * (xfract) * (yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) y2 * (xfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+    /* Convert acc to 1.31(q31) format */
+    return ((q31_t)(acc << 2));
+  }
+
+
+  /**
+  * @brief  Q15 bilinear interpolation.
+  * @param[in,out] S  points to an instance of the interpolation structure.
+  * @param[in]     X  interpolation coordinate in 12.20 format.
+  * @param[in]     Y  interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+  static __INLINE q15_t arm_bilinear_interp_q15(
+  arm_bilinear_interp_instance_q15 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q63_t acc = 0;                               /* output */
+    q31_t out;                                   /* Temporary output */
+    q15_t x1, x2, y1, y2;                        /* Nearest output values */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    int32_t rI, cI;                              /* Row and column indices */
+    q15_t *pYData = S->pData;                    /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* xfract should be in 12.20 format */
+    xfract = (X & 0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI)    ];
+    x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+
+    /* 20 bits for the fractional part */
+    /* yfract should be in 12.20 format */
+    yfract = (Y & 0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1)    ];
+    y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */
+
+    /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */
+    /* convert 13.35 to 13.31 by right shifting  and out is in 1.31 */
+    out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u);
+    acc = ((q63_t) out * (0xFFFFF - yfract));
+
+    /* x2 * (xfract) * (1-yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u);
+    acc += ((q63_t) out * (xfract));
+
+    /* y1 * (1 - xfract) * (yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u);
+    acc += ((q63_t) out * (yfract));
+
+    /* y2 * (xfract) * (yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u);
+    acc += ((q63_t) out * (yfract));
+
+    /* acc is in 13.51 format and down shift acc by 36 times */
+    /* Convert out to 1.15 format */
+    return ((q15_t)(acc >> 36));
+  }
+
+
+  /**
+  * @brief  Q7 bilinear interpolation.
+  * @param[in,out] S  points to an instance of the interpolation structure.
+  * @param[in]     X  interpolation coordinate in 12.20 format.
+  * @param[in]     Y  interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+  static __INLINE q7_t arm_bilinear_interp_q7(
+  arm_bilinear_interp_instance_q7 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q63_t acc = 0;                               /* output */
+    q31_t out;                                   /* Temporary output */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    q7_t x1, x2, y1, y2;                         /* Nearest output values */
+    int32_t rI, cI;                              /* Row and column indices */
+    q7_t *pYData = S->pData;                     /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* xfract should be in 12.20 format */
+    xfract = (X & (q31_t)0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI)    ];
+    x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+
+    /* 20 bits for the fractional part */
+    /* yfract should be in 12.20 format */
+    yfract = (Y & (q31_t)0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1)    ];
+    y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */
+    out = ((x1 * (0xFFFFF - xfract)));
+    acc = (((q63_t) out * (0xFFFFF - yfract)));
+
+    /* x2 * (xfract) * (1-yfract)  in 2.22 and adding to acc */
+    out = ((x2 * (0xFFFFF - yfract)));
+    acc += (((q63_t) out * (xfract)));
+
+    /* y1 * (1 - xfract) * (yfract)  in 2.22 and adding to acc */
+    out = ((y1 * (0xFFFFF - xfract)));
+    acc += (((q63_t) out * (yfract)));
+
+    /* y2 * (xfract) * (yfract)  in 2.22 and adding to acc */
+    out = ((y2 * (yfract)));
+    acc += (((q63_t) out * (xfract)));
+
+    /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */
+    return ((q7_t)(acc >> 40));
+  }
+
+  /**
+   * @} end of BilinearInterpolate group
+   */
+
+
+/* SMMLAR */
+#define multAcc_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMLSR */
+#define multSub_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMULR */
+#define mult_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32)
+
+/* SMMLA */
+#define multAcc_32x32_keep32(a, x, y) \
+    a += (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMLS */
+#define multSub_32x32_keep32(a, x, y) \
+    a -= (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMUL */
+#define mult_32x32_keep32(a, x, y) \
+    a = (q31_t) (((q63_t) x * y ) >> 32)
+
+
+#if defined ( __CC_ARM )
+  /* Enter low optimization region - place directly above function definition */
+  #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+    #define LOW_OPTIMIZATION_ENTER \
+       _Pragma ("push")         \
+       _Pragma ("O1")
+  #else
+    #define LOW_OPTIMIZATION_ENTER
+  #endif
+
+  /* Exit low optimization region - place directly after end of function definition */
+  #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+    #define LOW_OPTIMIZATION_EXIT \
+       _Pragma ("pop")
+  #else
+    #define LOW_OPTIMIZATION_EXIT
+  #endif
+
+  /* Enter low optimization region - place directly above function definition */
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+
+  /* Exit low optimization region - place directly after end of function definition */
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define LOW_OPTIMIZATION_ENTER
+  #define LOW_OPTIMIZATION_EXIT
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__GNUC__)
+  #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") ))
+  #define LOW_OPTIMIZATION_EXIT
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ICCARM__)
+  /* Enter low optimization region - place directly above function definition */
+  #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+    #define LOW_OPTIMIZATION_ENTER \
+       _Pragma ("optimize=low")
+  #else
+    #define LOW_OPTIMIZATION_ENTER
+  #endif
+
+  /* Exit low optimization region - place directly after end of function definition */
+  #define LOW_OPTIMIZATION_EXIT
+
+  /* Enter low optimization region - place directly above function definition */
+  #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+    #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \
+       _Pragma ("optimize=low")
+  #else
+    #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #endif
+
+  /* Exit low optimization region - place directly after end of function definition */
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__CSMC__)
+  #define LOW_OPTIMIZATION_ENTER
+  #define LOW_OPTIMIZATION_EXIT
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__TASKING__)
+  #define LOW_OPTIMIZATION_ENTER
+  #define LOW_OPTIMIZATION_EXIT
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#endif
+
+
+#ifdef   __cplusplus
+}
+#endif
+
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* _ARM_MATH_H */
+
+/**
+ *
+ * End of file.
+ */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_armcc.h b/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_armcc.h
new file mode 100755
index 0000000..74c49c6
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_armcc.h
@@ -0,0 +1,734 @@
+/**************************************************************************//**
+ * @file     cmsis_armcc.h
+ * @brief    CMSIS Cortex-M Core Function/Instruction Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_ARMCC_H
+#define __CMSIS_ARMCC_H
+
+
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+/* intrinsic void __enable_irq();     */
+/* intrinsic void __disable_irq();    */
+
+/**
+  \brief   Get Control Register
+  \details Returns the content of the Control Register.
+  \return               Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  register uint32_t __regControl         __ASM("control");
+  return(__regControl);
+}
+
+
+/**
+  \brief   Set Control Register
+  \details Writes the given value to the Control Register.
+  \param [in]    control  Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  register uint32_t __regControl         __ASM("control");
+  __regControl = control;
+}
+
+
+/**
+  \brief   Get IPSR Register
+  \details Returns the content of the IPSR Register.
+  \return               IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  register uint32_t __regIPSR          __ASM("ipsr");
+  return(__regIPSR);
+}
+
+
+/**
+  \brief   Get APSR Register
+  \details Returns the content of the APSR Register.
+  \return               APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+  register uint32_t __regAPSR          __ASM("apsr");
+  return(__regAPSR);
+}
+
+
+/**
+  \brief   Get xPSR Register
+  \details Returns the content of the xPSR Register.
+  \return               xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  register uint32_t __regXPSR          __ASM("xpsr");
+  return(__regXPSR);
+}
+
+
+/**
+  \brief   Get Process Stack Pointer
+  \details Returns the current value of the Process Stack Pointer (PSP).
+  \return               PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  return(__regProcessStackPointer);
+}
+
+
+/**
+  \brief   Set Process Stack Pointer
+  \details Assigns the given value to the Process Stack Pointer (PSP).
+  \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  __regProcessStackPointer = topOfProcStack;
+}
+
+
+/**
+  \brief   Get Main Stack Pointer
+  \details Returns the current value of the Main Stack Pointer (MSP).
+  \return               MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  return(__regMainStackPointer);
+}
+
+
+/**
+  \brief   Set Main Stack Pointer
+  \details Assigns the given value to the Main Stack Pointer (MSP).
+  \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  __regMainStackPointer = topOfMainStack;
+}
+
+
+/**
+  \brief   Get Priority Mask
+  \details Returns the current state of the priority mask bit from the Priority Mask Register.
+  \return               Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  return(__regPriMask);
+}
+
+
+/**
+  \brief   Set Priority Mask
+  \details Assigns the given value to the Priority Mask Register.
+  \param [in]    priMask  Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  __regPriMask = (priMask);
+}
+
+
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+  \brief   Enable FIQ
+  \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/**
+  \brief   Disable FIQ
+  \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/**
+  \brief   Get Base Priority
+  \details Returns the current value of the Base Priority register.
+  \return               Base Priority register value
+ */
+__STATIC_INLINE uint32_t  __get_BASEPRI(void)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  return(__regBasePri);
+}
+
+
+/**
+  \brief   Set Base Priority
+  \details Assigns the given value to the Base Priority register.
+  \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  __regBasePri = (basePri & 0xFFU);
+}
+
+
+/**
+  \brief   Set Base Priority with condition
+  \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+           or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+  register uint32_t __regBasePriMax      __ASM("basepri_max");
+  __regBasePriMax = (basePri & 0xFFU);
+}
+
+
+/**
+  \brief   Get Fault Mask
+  \details Returns the current value of the Fault Mask register.
+  \return               Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  return(__regFaultMask);
+}
+
+
+/**
+  \brief   Set Fault Mask
+  \details Assigns the given value to the Fault Mask register.
+  \param [in]    faultMask  Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+
+#if       (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
+
+/**
+  \brief   Get FPSCR
+  \details Returns the current value of the Floating Point Status/Control register.
+  \return               Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#else
+   return(0U);
+#endif
+}
+
+
+/**
+  \brief   Set FPSCR
+  \details Assigns the given value to the Floating Point Status/Control register.
+  \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/**
+  \brief   No Operation
+  \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP                             __nop
+
+
+/**
+  \brief   Wait For Interrupt
+  \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI                             __wfi
+
+
+/**
+  \brief   Wait For Event
+  \details Wait For Event is a hint instruction that permits the processor to enter
+           a low-power state until one of a number of events occurs.
+ */
+#define __WFE                             __wfe
+
+
+/**
+  \brief   Send Event
+  \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV                             __sev
+
+
+/**
+  \brief   Instruction Synchronization Barrier
+  \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+           so that all instructions following the ISB are fetched from cache or memory,
+           after the instruction has been completed.
+ */
+#define __ISB() do {\
+                   __schedule_barrier();\
+                   __isb(0xF);\
+                   __schedule_barrier();\
+                } while (0U)
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() do {\
+                   __schedule_barrier();\
+                   __dsb(0xF);\
+                   __schedule_barrier();\
+                } while (0U)
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+#define __DMB() do {\
+                   __schedule_barrier();\
+                   __dmb(0xF);\
+                   __schedule_barrier();\
+                } while (0U)
+
+/**
+  \brief   Reverse byte order (32 bit)
+  \details Reverses the byte order in integer value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#define __REV                             __rev
+
+
+/**
+  \brief   Reverse byte order (16 bit)
+  \details Reverses the byte order in two unsigned short values.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+  rev16 r0, r0
+  bx lr
+}
+#endif
+
+/**
+  \brief   Reverse byte order in signed short value
+  \details Reverses the byte order in a signed short value with sign extension to integer.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+  revsh r0, r0
+  bx lr
+}
+#endif
+
+
+/**
+  \brief   Rotate Right in unsigned value (32 bit)
+  \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+  \param [in]    value  Value to rotate
+  \param [in]    value  Number of Bits to rotate
+  \return               Rotated value
+ */
+#define __ROR                             __ror
+
+
+/**
+  \brief   Breakpoint
+  \details Causes the processor to enter Debug state.
+           Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+  \param [in]    value  is ignored by the processor.
+                 If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __breakpoint(value)
+
+
+/**
+  \brief   Reverse bit order of value
+  \details Reverses the bit order of the given value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+  #define __RBIT                          __rbit
+#else
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+  int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+  result = value;                      /* r will be reversed bits of v; first get LSB of v */
+  for (value >>= 1U; value; value >>= 1U)
+  {
+    result <<= 1U;
+    result |= value & 1U;
+    s--;
+  }
+  result <<= s;                        /* shift when v's highest bits are zero */
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Count leading zeros
+  \details Counts the number of leading zeros of a data value.
+  \param [in]  value  Value to count the leading zeros
+  \return             number of leading zeros in value
+ */
+#define __CLZ                             __clz
+
+
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+  \brief   LDR Exclusive (8 bit)
+  \details Executes a exclusive LDR instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXB(ptr)                                                        ((uint8_t ) __ldrex(ptr))
+#else
+  #define __LDREXB(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   LDR Exclusive (16 bit)
+  \details Executes a exclusive LDR instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXH(ptr)                                                        ((uint16_t) __ldrex(ptr))
+#else
+  #define __LDREXH(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   LDR Exclusive (32 bit)
+  \details Executes a exclusive LDR instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXW(ptr)                                                        ((uint32_t ) __ldrex(ptr))
+#else
+  #define __LDREXW(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (8 bit)
+  \details Executes a exclusive STR instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXB(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXB(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (16 bit)
+  \details Executes a exclusive STR instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXH(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXH(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (32 bit)
+  \details Executes a exclusive STR instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXW(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXW(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   Remove the exclusive lock
+  \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX                           __clrex
+
+
+/**
+  \brief   Signed Saturate
+  \details Saturates a signed value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (1..32)
+  \return             Saturated value
+ */
+#define __SSAT                            __ssat
+
+
+/**
+  \brief   Unsigned Saturate
+  \details Saturates an unsigned value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+#define __USAT                            __usat
+
+
+/**
+  \brief   Rotate Right with Extend (32 bit)
+  \details Moves each bit of a bitstring right by one bit.
+           The carry input is shifted in at the left end of the bitstring.
+  \param [in]    value  Value to rotate
+  \return               Rotated value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
+{
+  rrx r0, r0
+  bx lr
+}
+#endif
+
+
+/**
+  \brief   LDRT Unprivileged (8 bit)
+  \details Executes a Unprivileged LDRT instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#define __LDRBT(ptr)                      ((uint8_t )  __ldrt(ptr))
+
+
+/**
+  \brief   LDRT Unprivileged (16 bit)
+  \details Executes a Unprivileged LDRT instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#define __LDRHT(ptr)                      ((uint16_t)  __ldrt(ptr))
+
+
+/**
+  \brief   LDRT Unprivileged (32 bit)
+  \details Executes a Unprivileged LDRT instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#define __LDRT(ptr)                       ((uint32_t ) __ldrt(ptr))
+
+
+/**
+  \brief   STRT Unprivileged (8 bit)
+  \details Executes a Unprivileged STRT instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+#define __STRBT(value, ptr)               __strt(value, ptr)
+
+
+/**
+  \brief   STRT Unprivileged (16 bit)
+  \details Executes a Unprivileged STRT instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+#define __STRHT(value, ptr)               __strt(value, ptr)
+
+
+/**
+  \brief   STRT Unprivileged (32 bit)
+  \details Executes a Unprivileged STRT instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+#define __STRT(value, ptr)                __strt(value, ptr)
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if (__CORTEX_M >= 0x04U)  /* only for Cortex-M4 and above */
+
+#define __SADD8                           __sadd8
+#define __QADD8                           __qadd8
+#define __SHADD8                          __shadd8
+#define __UADD8                           __uadd8
+#define __UQADD8                          __uqadd8
+#define __UHADD8                          __uhadd8
+#define __SSUB8                           __ssub8
+#define __QSUB8                           __qsub8
+#define __SHSUB8                          __shsub8
+#define __USUB8                           __usub8
+#define __UQSUB8                          __uqsub8
+#define __UHSUB8                          __uhsub8
+#define __SADD16                          __sadd16
+#define __QADD16                          __qadd16
+#define __SHADD16                         __shadd16
+#define __UADD16                          __uadd16
+#define __UQADD16                         __uqadd16
+#define __UHADD16                         __uhadd16
+#define __SSUB16                          __ssub16
+#define __QSUB16                          __qsub16
+#define __SHSUB16                         __shsub16
+#define __USUB16                          __usub16
+#define __UQSUB16                         __uqsub16
+#define __UHSUB16                         __uhsub16
+#define __SASX                            __sasx
+#define __QASX                            __qasx
+#define __SHASX                           __shasx
+#define __UASX                            __uasx
+#define __UQASX                           __uqasx
+#define __UHASX                           __uhasx
+#define __SSAX                            __ssax
+#define __QSAX                            __qsax
+#define __SHSAX                           __shsax
+#define __USAX                            __usax
+#define __UQSAX                           __uqsax
+#define __UHSAX                           __uhsax
+#define __USAD8                           __usad8
+#define __USADA8                          __usada8
+#define __SSAT16                          __ssat16
+#define __USAT16                          __usat16
+#define __UXTB16                          __uxtb16
+#define __UXTAB16                         __uxtab16
+#define __SXTB16                          __sxtb16
+#define __SXTAB16                         __sxtab16
+#define __SMUAD                           __smuad
+#define __SMUADX                          __smuadx
+#define __SMLAD                           __smlad
+#define __SMLADX                          __smladx
+#define __SMLALD                          __smlald
+#define __SMLALDX                         __smlaldx
+#define __SMUSD                           __smusd
+#define __SMUSDX                          __smusdx
+#define __SMLSD                           __smlsd
+#define __SMLSDX                          __smlsdx
+#define __SMLSLD                          __smlsld
+#define __SMLSLDX                         __smlsldx
+#define __SEL                             __sel
+#define __QADD                            __qadd
+#define __QSUB                            __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0x0000FFFFUL) |  \
+                                           ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)  )
+
+#define __PKHTB(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0xFFFF0000UL) |  \
+                                           ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)  )
+
+#define __SMMLA(ARG1,ARG2,ARG3)          ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+                                                      ((int64_t)(ARG3) << 32U)     ) >> 32U))
+
+#endif /* (__CORTEX_M >= 0x04) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_H */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_armcc_V6.h b/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_armcc_V6.h
new file mode 100755
index 0000000..cd13240
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_armcc_V6.h
@@ -0,0 +1,1800 @@
+/**************************************************************************//**
+ * @file     cmsis_armcc_V6.h
+ * @brief    CMSIS Cortex-M Core Function/Instruction Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_ARMCC_V6_H
+#define __CMSIS_ARMCC_V6_H
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+/**
+  \brief   Enable IRQ Interrupts
+  \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void)
+{
+  __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/**
+  \brief   Disable IRQ Interrupts
+  \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void)
+{
+  __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/**
+  \brief   Get Control Register
+  \details Returns the content of the Control Register.
+  \return               Control Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Control Register (non-secure)
+  \details Returns the content of the non-secure Control Register when in secure mode.
+  \return               non-secure Control Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Control Register
+  \details Writes the given value to the Control Register.
+  \param [in]    control  Control Register value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Control Register (non-secure)
+  \details Writes the given value to the non-secure Control Register when in secure state.
+  \param [in]    control  Control Register value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control)
+{
+  __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
+}
+#endif
+
+
+/**
+  \brief   Get IPSR Register
+  \details Returns the content of the IPSR Register.
+  \return               IPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get IPSR Register (non-secure)
+  \details Returns the content of the non-secure IPSR Register when in secure state.
+  \return               IPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_IPSR_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Get APSR Register
+  \details Returns the content of the APSR Register.
+  \return               APSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get APSR Register (non-secure)
+  \details Returns the content of the non-secure APSR Register when in secure state.
+  \return               APSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_APSR_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Get xPSR Register
+  \details Returns the content of the xPSR Register.
+  \return               xPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get xPSR Register (non-secure)
+  \details Returns the content of the non-secure xPSR Register when in secure state.
+  \return               xPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_xPSR_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Get Process Stack Pointer
+  \details Returns the current value of the Process Stack Pointer (PSP).
+  \return               PSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp"  : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Process Stack Pointer (non-secure)
+  \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
+  \return               PSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp_ns"  : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Process Stack Pointer
+  \details Assigns the given value to the Process Stack Pointer (PSP).
+  \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : "sp");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Process Stack Pointer (non-secure)
+  \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
+  \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : "sp");
+}
+#endif
+
+
+/**
+  \brief   Get Main Stack Pointer
+  \details Returns the current value of the Main Stack Pointer (MSP).
+  \return               MSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Main Stack Pointer (non-secure)
+  \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
+  \return               MSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Main Stack Pointer
+  \details Assigns the given value to the Main Stack Pointer (MSP).
+  \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : "sp");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Main Stack Pointer (non-secure)
+  \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
+  \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : "sp");
+}
+#endif
+
+
+/**
+  \brief   Get Priority Mask
+  \details Returns the current state of the priority mask bit from the Priority Mask Register.
+  \return               Priority Mask value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Priority Mask (non-secure)
+  \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
+  \return               Priority Mask value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Priority Mask
+  \details Assigns the given value to the Priority Mask Register.
+  \param [in]    priMask  Priority Mask
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Priority Mask (non-secure)
+  \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
+  \param [in]    priMask  Priority Mask
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
+}
+#endif
+
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U))  /* ToDo:  ARMCC_V6: check if this is ok for cortex >=3 */
+
+/**
+  \brief   Enable FIQ
+  \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void)
+{
+  __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/**
+  \brief   Disable FIQ
+  \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void)
+{
+  __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/**
+  \brief   Get Base Priority
+  \details Returns the current value of the Base Priority register.
+  \return               Base Priority register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Base Priority (non-secure)
+  \details Returns the current value of the non-secure Base Priority register when in secure state.
+  \return               Base Priority register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Base Priority
+  \details Assigns the given value to the Base Priority register.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+  __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Base Priority (non-secure)
+  \details Assigns the given value to the non-secure Base Priority register when in secure state.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_ns, %0" : : "r" (value) : "memory");
+}
+#endif
+
+
+/**
+  \brief   Set Base Priority with condition
+  \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+           or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Base Priority with condition (non_secure)
+  \details Assigns the given value to the non-secure Base Priority register when in secure state only if BASEPRI masking is disabled,
+	       or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_MAX_NS(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_max_ns, %0" : : "r" (value) : "memory");
+}
+#endif
+
+
+/**
+  \brief   Get Fault Mask
+  \details Returns the current value of the Fault Mask register.
+  \return               Fault Mask register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Fault Mask (non-secure)
+  \details Returns the current value of the non-secure Fault Mask register when in secure state.
+  \return               Fault Mask register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Fault Mask
+  \details Assigns the given value to the Fault Mask register.
+  \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Fault Mask (non-secure)
+  \details Assigns the given value to the non-secure Fault Mask register when in secure state.
+  \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
+}
+#endif
+
+
+#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+#if (__ARM_ARCH_8M__ == 1U)
+
+/**
+  \brief   Get Process Stack Pointer Limit
+  \details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
+  \return               PSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psplim"  : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M')     /* ToDo:  ARMCC_V6: check predefined macro for mainline */
+/**
+  \brief   Get Process Stack Pointer Limit (non-secure)
+  \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+  \return               PSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psplim_ns"  : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Process Stack Pointer Limit
+  \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
+  \param [in]    ProcStackPtrLimit  Process Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
+{
+  __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M')     /* ToDo:  ARMCC_V6: check predefined macro for mainline */
+/**
+  \brief   Set Process Stack Pointer (non-secure)
+  \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+  \param [in]    ProcStackPtrLimit  Process Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
+{
+  __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
+}
+#endif
+
+
+/**
+  \brief   Get Main Stack Pointer Limit
+  \details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
+  \return               MSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msplim" : "=r" (result) );
+
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M')     /* ToDo:  ARMCC_V6: check predefined macro for mainline */
+/**
+  \brief   Get Main Stack Pointer Limit (non-secure)
+  \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
+  \return               MSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Main Stack Pointer Limit
+  \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
+  \param [in]    MainStackPtrLimit  Main Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
+{
+  __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M')     /* ToDo:  ARMCC_V6: check predefined macro for mainline */
+/**
+  \brief   Set Main Stack Pointer Limit (non-secure)
+  \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
+  \param [in]    MainStackPtrLimit  Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
+{
+  __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
+}
+#endif
+
+#endif /* (__ARM_ARCH_8M__ == 1U) */
+
+
+#if ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U))  /* ToDo:  ARMCC_V6: check if this is ok for cortex >=4 */
+
+/**
+  \brief   Get FPSCR
+  \details eturns the current value of the Floating Point Status/Control register.
+  \return               Floating Point Status/Control register value
+ */
+#define __get_FPSCR      __builtin_arm_get_fpscr
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  uint32_t result;
+
+  __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+#endif
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get FPSCR (non-secure)
+  \details Returns the current value of the non-secure Floating Point Status/Control register when in secure state.
+  \return               Floating Point Status/Control register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FPSCR_NS(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  uint32_t result;
+
+  __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("VMRS %0, fpscr_ns" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+#endif
+
+
+/**
+  \brief   Set FPSCR
+  \details Assigns the given value to the Floating Point Status/Control register.
+  \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+#define __set_FPSCR      __builtin_arm_set_fpscr
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+#endif
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set FPSCR (non-secure)
+  \details Assigns the given value to the non-secure Floating Point Status/Control register when in secure state.
+  \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FPSCR_NS(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("VMSR fpscr_ns, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+#endif
+
+#endif /* ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+  \brief   No Operation
+  \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP          __builtin_arm_nop
+
+/**
+  \brief   Wait For Interrupt
+  \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI          __builtin_arm_wfi
+
+
+/**
+  \brief   Wait For Event
+  \details Wait For Event is a hint instruction that permits the processor to enter
+           a low-power state until one of a number of events occurs.
+ */
+#define __WFE          __builtin_arm_wfe
+
+
+/**
+  \brief   Send Event
+  \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV          __builtin_arm_sev
+
+
+/**
+  \brief   Instruction Synchronization Barrier
+  \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+           so that all instructions following the ISB are fetched from cache or memory,
+           after the instruction has been completed.
+ */
+#define __ISB()        __builtin_arm_isb(0xF);
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB()        __builtin_arm_dsb(0xF);
+
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+#define __DMB()        __builtin_arm_dmb(0xF);
+
+
+/**
+  \brief   Reverse byte order (32 bit)
+  \details Reverses the byte order in integer value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#define __REV          __builtin_bswap32
+
+
+/**
+  \brief   Reverse byte order (16 bit)
+  \details Reverses the byte order in two unsigned short values.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#define __REV16          __builtin_bswap16                           /* ToDo:  ARMCC_V6: check if __builtin_bswap16 could be used */
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Reverse byte order in signed short value
+  \details Reverses the byte order in a signed short value with sign extension to integer.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+                                                          /* ToDo:  ARMCC_V6: check if __builtin_bswap16 could be used */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+  int32_t result;
+
+  __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/**
+  \brief   Rotate Right in unsigned value (32 bit)
+  \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+  \param [in]    op1  Value to rotate
+  \param [in]    op2  Number of Bits to rotate
+  \return               Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+  return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+  \brief   Breakpoint
+  \details Causes the processor to enter Debug state.
+            Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+    \param [in]    value  is ignored by the processor.
+                   If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __ASM volatile ("bkpt "#value)
+
+
+/**
+  \brief   Reverse bit order of value
+  \details Reverses the bit order of the given value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+                                                          /* ToDo:  ARMCC_V6: check if __builtin_arm_rbit is supported */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U))  /* ToDo:  ARMCC_V6: check if this is ok for cortex >=3 */
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+#else
+  int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+  result = value;                      /* r will be reversed bits of v; first get LSB of v */
+  for (value >>= 1U; value; value >>= 1U)
+  {
+    result <<= 1U;
+    result |= value & 1U;
+    s--;
+  }
+  result <<= s;                        /* shift when v's highest bits are zero */
+#endif
+  return(result);
+}
+
+
+/**
+  \brief   Count leading zeros
+  \details Counts the number of leading zeros of a data value.
+  \param [in]  value  Value to count the leading zeros
+  \return             number of leading zeros in value
+ */
+#define __CLZ             __builtin_clz
+
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U))  /* ToDo:  ARMCC_V6: check if this is ok for cortex >=3 */
+
+/**
+  \brief   LDR Exclusive (8 bit)
+  \details Executes a exclusive LDR instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#define __LDREXB        (uint8_t)__builtin_arm_ldrex
+
+
+/**
+  \brief   LDR Exclusive (16 bit)
+  \details Executes a exclusive LDR instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#define __LDREXH        (uint16_t)__builtin_arm_ldrex
+
+
+/**
+  \brief   LDR Exclusive (32 bit)
+  \details Executes a exclusive LDR instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#define __LDREXW        (uint32_t)__builtin_arm_ldrex
+
+
+/**
+  \brief   STR Exclusive (8 bit)
+  \details Executes a exclusive STR instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define __STREXB        (uint32_t)__builtin_arm_strex
+
+
+/**
+  \brief   STR Exclusive (16 bit)
+  \details Executes a exclusive STR instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define __STREXH        (uint32_t)__builtin_arm_strex
+
+
+/**
+  \brief   STR Exclusive (32 bit)
+  \details Executes a exclusive STR instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define __STREXW        (uint32_t)__builtin_arm_strex
+
+
+/**
+  \brief   Remove the exclusive lock
+  \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX             __builtin_arm_clrex
+
+
+/**
+  \brief   Signed Saturate
+  \details Saturates a signed value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (1..32)
+  \return             Saturated value
+ */
+/*#define __SSAT             __builtin_arm_ssat*/
+#define __SSAT(ARG1,ARG2) \
+({                          \
+  int32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/**
+  \brief   Unsigned Saturate
+  \details Saturates an unsigned value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+#define __USAT             __builtin_arm_usat
+#if 0
+#define __USAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+#endif
+
+
+/**
+  \brief   Rotate Right with Extend (32 bit)
+  \details Moves each bit of a bitstring right by one bit.
+           The carry input is shifted in at the left end of the bitstring.
+  \param [in]    value  Value to rotate
+  \return               Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/**
+  \brief   LDRT Unprivileged (8 bit)
+  \details Executes a Unprivileged LDRT instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (16 bit)
+  \details Executes a Unprivileged LDRT instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (32 bit)
+  \details Executes a Unprivileged LDRT instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return(result);
+}
+
+
+/**
+  \brief   STRT Unprivileged (8 bit)
+  \details Executes a Unprivileged STRT instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
+{
+   __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   STRT Unprivileged (16 bit)
+  \details Executes a Unprivileged STRT instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
+{
+   __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   STRT Unprivileged (32 bit)
+  \details Executes a Unprivileged STRT instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
+{
+   __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
+}
+
+#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+#if (__ARM_ARCH_8M__ == 1U)
+
+/**
+  \brief   Load-Acquire (8 bit)
+  \details Executes a LDAB instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return ((uint8_t) result);
+}
+
+
+/**
+  \brief   Load-Acquire (16 bit)
+  \details Executes a LDAH instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return ((uint16_t) result);
+}
+
+
+/**
+  \brief   Load-Acquire (32 bit)
+  \details Executes a LDA instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return(result);
+}
+
+
+/**
+  \brief   Store-Release (8 bit)
+  \details Executes a STLB instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
+{
+   __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   Store-Release (16 bit)
+  \details Executes a STLH instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
+{
+   __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   Store-Release (32 bit)
+  \details Executes a STL instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr)
+{
+   __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   Load-Acquire Exclusive (8 bit)
+  \details Executes a LDAB exclusive instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#define     __LDAEXB                 (uint8_t)__builtin_arm_ldaex
+
+
+/**
+  \brief   Load-Acquire Exclusive (16 bit)
+  \details Executes a LDAH exclusive instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#define     __LDAEXH                 (uint16_t)__builtin_arm_ldaex
+
+
+/**
+  \brief   Load-Acquire Exclusive (32 bit)
+  \details Executes a LDA exclusive instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#define     __LDAEX                  (uint32_t)__builtin_arm_ldaex
+
+
+/**
+  \brief   Store-Release Exclusive (8 bit)
+  \details Executes a STLB exclusive instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define     __STLEXB                 (uint32_t)__builtin_arm_stlex
+
+
+/**
+  \brief   Store-Release Exclusive (16 bit)
+  \details Executes a STLH exclusive instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define     __STLEXH                 (uint32_t)__builtin_arm_stlex
+
+
+/**
+  \brief   Store-Release Exclusive (32 bit)
+  \details Executes a STL exclusive instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define     __STLEX                  (uint32_t)__builtin_arm_stlex
+
+#endif /* (__ARM_ARCH_8M__ == 1U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if (__ARM_FEATURE_DSP == 1U)        /* ToDo:  ARMCC_V6: This should be ARCH >= ARMv7-M + SIMD */
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE  int32_t __QADD( int32_t op1,  int32_t op2)
+{
+  int32_t result;
+
+  __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE  int32_t __QSUB( int32_t op1,  int32_t op2)
+{
+  int32_t result;
+
+  __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  if (ARG3 == 0) \
+    __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2)  ); \
+  else \
+    __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#endif /* (__ARM_FEATURE_DSP == 1U) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_V6_H */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_gcc.h b/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_gcc.h
new file mode 100755
index 0000000..bb89fbb
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/cmsis_gcc.h
@@ -0,0 +1,1373 @@
+/**************************************************************************//**
+ * @file     cmsis_gcc.h
+ * @brief    CMSIS Cortex-M Core Function/Instruction Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_GCC_H
+#define __CMSIS_GCC_H
+
+/* ignore some GCC warnings */
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+/**
+  \brief   Enable IRQ Interrupts
+  \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+  __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/**
+  \brief   Disable IRQ Interrupts
+  \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+  __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/**
+  \brief   Get Control Register
+  \details Returns the content of the Control Register.
+  \return               Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Control Register
+  \details Writes the given value to the Control Register.
+  \param [in]    control  Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+/**
+  \brief   Get IPSR Register
+  \details Returns the content of the IPSR Register.
+  \return               IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Get APSR Register
+  \details Returns the content of the APSR Register.
+  \return               APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Get xPSR Register
+  \details Returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Get Process Stack Pointer
+  \details Returns the current value of the Process Stack Pointer (PSP).
+  \return               PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp\n"  : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Process Stack Pointer
+  \details Assigns the given value to the Process Stack Pointer (PSP).
+  \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
+}
+
+
+/**
+  \brief   Get Main Stack Pointer
+  \details Returns the current value of the Main Stack Pointer (MSP).
+  \return               MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Main Stack Pointer
+  \details Assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
+}
+
+
+/**
+  \brief   Get Priority Mask
+  \details Returns the current state of the priority mask bit from the Priority Mask Register.
+  \return               Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Priority Mask
+  \details Assigns the given value to the Priority Mask Register.
+  \param [in]    priMask  Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if       (__CORTEX_M >= 0x03U)
+
+/**
+  \brief   Enable FIQ
+  \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+  __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/**
+  \brief   Disable FIQ
+  \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+  __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/**
+  \brief   Get Base Priority
+  \details Returns the current value of the Base Priority register.
+  \return               Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Base Priority
+  \details Assigns the given value to the Base Priority register.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+  __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+/**
+  \brief   Set Base Priority with condition
+  \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+           or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
+}
+
+
+/**
+  \brief   Get Fault Mask
+  \details Returns the current value of the Fault Mask register.
+  \return               Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Fault Mask
+  \details Assigns the given value to the Fault Mask register.
+  \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+#endif /* (__CORTEX_M >= 0x03U) */
+
+
+#if       (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
+
+/**
+  \brief   Get FPSCR
+  \details Returns the current value of the Floating Point Status/Control register.
+  \return               Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  uint32_t result;
+
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+
+
+/**
+  \brief   Set FPSCR
+  \details Assigns the given value to the Floating Point Status/Control register.
+  \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+  \brief   No Operation
+  \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
+{
+  __ASM volatile ("nop");
+}
+
+
+/**
+  \brief   Wait For Interrupt
+  \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
+{
+  __ASM volatile ("wfi");
+}
+
+
+/**
+  \brief   Wait For Event
+  \details Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
+{
+  __ASM volatile ("wfe");
+}
+
+
+/**
+  \brief   Send Event
+  \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
+{
+  __ASM volatile ("sev");
+}
+
+
+/**
+  \brief   Instruction Synchronization Barrier
+  \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+           so that all instructions following the ISB are fetched from cache or memory,
+           after the instruction has been completed.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
+{
+  __ASM volatile ("isb 0xF":::"memory");
+}
+
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
+{
+  __ASM volatile ("dsb 0xF":::"memory");
+}
+
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
+{
+  __ASM volatile ("dmb 0xF":::"memory");
+}
+
+
+/**
+  \brief   Reverse byte order (32 bit)
+  \details Reverses the byte order in integer value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+  return __builtin_bswap32(value);
+#else
+  uint32_t result;
+
+  __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/**
+  \brief   Reverse byte order (16 bit)
+  \details Reverses the byte order in two unsigned short values.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/**
+  \brief   Reverse byte order in signed short value
+  \details Reverses the byte order in a signed short value with sign extension to integer.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+  return (short)__builtin_bswap16(value);
+#else
+  int32_t result;
+
+  __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/**
+  \brief   Rotate Right in unsigned value (32 bit)
+  \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+  \param [in]    value  Value to rotate
+  \param [in]    value  Number of Bits to rotate
+  \return               Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+  return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+  \brief   Breakpoint
+  \details Causes the processor to enter Debug state.
+           Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+  \param [in]    value  is ignored by the processor.
+                 If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __ASM volatile ("bkpt "#value)
+
+
+/**
+  \brief   Reverse bit order of value
+  \details Reverses the bit order of the given value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+#else
+  int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+  result = value;                      /* r will be reversed bits of v; first get LSB of v */
+  for (value >>= 1U; value; value >>= 1U)
+  {
+    result <<= 1U;
+    result |= value & 1U;
+    s--;
+  }
+  result <<= s;                        /* shift when v's highest bits are zero */
+#endif
+  return(result);
+}
+
+
+/**
+  \brief   Count leading zeros
+  \details Counts the number of leading zeros of a data value.
+  \param [in]  value  Value to count the leading zeros
+  \return             number of leading zeros in value
+ */
+#define __CLZ             __builtin_clz
+
+
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+  \brief   LDR Exclusive (8 bit)
+  \details Executes a exclusive LDR instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDR Exclusive (16 bit)
+  \details Executes a exclusive LDR instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDR Exclusive (32 bit)
+  \details Executes a exclusive LDR instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
+   return(result);
+}
+
+
+/**
+  \brief   STR Exclusive (8 bit)
+  \details Executes a exclusive STR instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+   return(result);
+}
+
+
+/**
+  \brief   STR Exclusive (16 bit)
+  \details Executes a exclusive STR instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+   return(result);
+}
+
+
+/**
+  \brief   STR Exclusive (32 bit)
+  \details Executes a exclusive STR instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/**
+  \brief   Remove the exclusive lock
+  \details Removes the exclusive lock which is created by LDREX.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
+{
+  __ASM volatile ("clrex" ::: "memory");
+}
+
+
+/**
+  \brief   Signed Saturate
+  \details Saturates a signed value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (1..32)
+  \return             Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/**
+  \brief   Unsigned Saturate
+  \details Saturates an unsigned value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/**
+  \brief   Rotate Right with Extend (32 bit)
+  \details Moves each bit of a bitstring right by one bit.
+           The carry input is shifted in at the left end of the bitstring.
+  \param [in]    value  Value to rotate
+  \return               Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/**
+  \brief   LDRT Unprivileged (8 bit)
+  \details Executes a Unprivileged LDRT instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (16 bit)
+  \details Executes a Unprivileged LDRT instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (32 bit)
+  \details Executes a Unprivileged LDRT instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
+   return(result);
+}
+
+
+/**
+  \brief   STRT Unprivileged (8 bit)
+  \details Executes a Unprivileged STRT instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
+{
+   __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   STRT Unprivileged (16 bit)
+  \details Executes a Unprivileged STRT instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
+{
+   __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   STRT Unprivileged (32 bit)
+  \details Executes a Unprivileged STRT instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
+{
+   __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
+}
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if (__CORTEX_M >= 0x04U)  /* only for Cortex-M4 and above */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({                          \
+  int32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE  int32_t __QADD( int32_t op1,  int32_t op2)
+{
+  int32_t result;
+
+  __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE  int32_t __QSUB( int32_t op1,  int32_t op2)
+{
+  int32_t result;
+
+  __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  if (ARG3 == 0) \
+    __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2)  ); \
+  else \
+    __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x04) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* __CMSIS_GCC_H */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm0.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm0.h
new file mode 100755
index 0000000..711dad5
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm0.h
@@ -0,0 +1,798 @@
+/**************************************************************************//**
+ * @file     core_cm0.h
+ * @brief    CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0_H_GENERIC
+#define __CORE_CM0_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex_M0
+  @{
+ */
+
+/*  CMSIS CM0 definitions */
+#define __CM0_CMSIS_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CMSIS HAL main version */
+#define __CM0_CMSIS_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CMSIS HAL sub version */
+#define __CM0_CMSIS_VERSION       ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
+                                    __CM0_CMSIS_VERSION_SUB           )        /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x00U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0_H_DEPENDANT
+#define __CORE_CM0_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM0_REV
+    #define __CM0_REV               0x0000U
+    #warning "__CM0_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M0 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:28;              /*!< bit:  0..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t _reserved1:3;               /*!< bit: 25..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:1;               /*!< bit:      0  Reserved */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[1U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[31U];
+  __IOM uint32_t ICER[1U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[31U];
+  __IOM uint32_t ISPR[1U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[31U];
+  __IOM uint32_t ICPR[1U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[31U];
+        uint32_t RESERVED4[64U];
+  __IOM uint32_t IP[8U];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+        uint32_t RESERVED0;
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+        uint32_t RESERVED1;
+  __IOM uint32_t SHP[2U];                /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+            Therefore they are not covered by the Cortex-M0 header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
+#define _SHP_IDX(IRQn)           ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >>    2UL)      )
+#define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      )
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+  else
+  {
+    NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm0plus.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm0plus.h
new file mode 100755
index 0000000..b04aa39
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm0plus.h
@@ -0,0 +1,914 @@
+/**************************************************************************//**
+ * @file     core_cm0plus.h
+ * @brief    CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0PLUS_H_GENERIC
+#define __CORE_CM0PLUS_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex-M0+
+  @{
+ */
+
+/*  CMSIS CM0+ definitions */
+#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U)                                   /*!< [31:16] CMSIS HAL main version */
+#define __CM0PLUS_CMSIS_VERSION_SUB  (0x1EU)                                   /*!< [15:0]  CMSIS HAL sub version */
+#define __CM0PLUS_CMSIS_VERSION      ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
+                                       __CM0PLUS_CMSIS_VERSION_SUB           ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x00U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0PLUS_H_DEPENDANT
+#define __CORE_CM0PLUS_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM0PLUS_REV
+    #define __CM0PLUS_REV             0x0000U
+    #warning "__CM0PLUS_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __VTOR_PRESENT
+    #define __VTOR_PRESENT            0U
+    #warning "__VTOR_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex-M0+ */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core MPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:28;              /*!< bit:  0..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t _reserved1:3;               /*!< bit: 25..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[1U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[31U];
+  __IOM uint32_t ICER[1U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[31U];
+  __IOM uint32_t ISPR[1U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[31U];
+  __IOM uint32_t ICPR[1U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[31U];
+        uint32_t RESERVED4[64U];
+  __IOM uint32_t IP[8U];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+#if (__VTOR_PRESENT == 1U)
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+#else
+        uint32_t RESERVED0;
+#endif
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+        uint32_t RESERVED1;
+  __IOM uint32_t SHP[2U];                /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+#if (__VTOR_PRESENT == 1U)
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 8U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   8U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0xFFFFFFUL << MPU_RBAR_ADDR_Pos)              /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+            Therefore they are not covered by the Cortex-M0+ header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M0+ Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
+#define _SHP_IDX(IRQn)           ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >>    2UL)      )
+#define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      )
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+  else
+  {
+    NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm3.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm3.h
new file mode 100755
index 0000000..b4ac4c7
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm3.h
@@ -0,0 +1,1763 @@
+/**************************************************************************//**
+ * @file     core_cm3.h
+ * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM3_H_GENERIC
+#define __CORE_CM3_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex_M3
+  @{
+ */
+
+/*  CMSIS CM3 definitions */
+#define __CM3_CMSIS_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16U) | \
+                                    __CM3_CMSIS_VERSION_SUB           )        /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x03U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM3_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM3_H_DEPENDANT
+#define __CORE_CM3_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM3_REV
+    #define __CM3_REV               0x0200U
+    #warning "__CM3_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M3 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27U                                            /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0) */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27U                                            /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25U                                            /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[24U];
+  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[24U];
+  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[24U];
+  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[24U];
+  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
+        uint32_t RESERVED4[56U];
+  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+        uint32_t RESERVED5[644U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0U                                         /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+  __IOM uint8_t  SHP[12U];               /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
+  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
+  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
+  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
+  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
+  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
+  __IM  uint32_t PFR[2U];                /*!< Offset: 0x040 (R/ )  Processor Feature Register */
+  __IM  uint32_t DFR;                    /*!< Offset: 0x048 (R/ )  Debug Feature Register */
+  __IM  uint32_t ADR;                    /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
+  __IM  uint32_t MMFR[4U];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
+  __IM  uint32_t ISAR[5U];               /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
+        uint32_t RESERVED0[5U];
+  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11U                                            /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#if (__CM3_REV < 0x0201U)                   /* core r2p1 */
+#define SCB_VTOR_TBLBASE_Pos               29U                                            /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk               (1UL << SCB_VTOR_TBLBASE_Pos)                  /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+#else
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8U                                            /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0U                                            /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8U                                            /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4U                                            /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1U                                            /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0U                                            /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18U                                            /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17U                                            /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16U                                            /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14U                                            /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13U                                            /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12U                                            /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11U                                            /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10U                                            /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8U                                            /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7U                                            /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3U                                            /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1U                                            /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0U                                            /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16U                                            /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8U                                            /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0U                                            /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31U                                            /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30U                                            /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1U                                            /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4U                                            /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3U                                            /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2U                                            /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1U                                            /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0U                                            /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t ICTR;                   /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200U))
+  __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */
+#else
+        uint32_t RESERVED1[1U];
+#endif
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0U                                         /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2U                                         /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1U                                         /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0U                                         /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+  \brief    Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __OM  union
+  {
+    __OM  uint8_t    u8;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit */
+    __OM  uint16_t   u16;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit */
+    __OM  uint32_t   u32;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit */
+  }  PORT [32U];                         /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers */
+        uint32_t RESERVED0[864U];
+  __IOM uint32_t TER;                    /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register */
+        uint32_t RESERVED1[15U];
+  __IOM uint32_t TPR;                    /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register */
+        uint32_t RESERVED2[15U];
+  __IOM uint32_t TCR;                    /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register */
+        uint32_t RESERVED3[29U];
+  __OM  uint32_t IWR;                    /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register */
+  __IM  uint32_t IRR;                    /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register */
+  __IOM uint32_t IMCR;                   /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register */
+        uint32_t RESERVED4[43U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register */
+        uint32_t RESERVED5[6U];
+  __IM  uint32_t PID4;                   /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __IM  uint32_t PID5;                   /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __IM  uint32_t PID6;                   /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __IM  uint32_t PID7;                   /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __IM  uint32_t PID0;                   /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __IM  uint32_t PID1;                   /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __IM  uint32_t PID2;                   /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __IM  uint32_t PID3;                   /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __IM  uint32_t CID0;                   /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __IM  uint32_t CID1;                   /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __IM  uint32_t CID2;                   /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __IM  uint32_t CID3;                   /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0U                                            /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23U                                            /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16U                                            /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10U                                            /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8U                                            /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4U                                            /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3U                                            /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2U                                            /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1U                                            /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0U                                            /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0U                                            /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0U                                            /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0U                                            /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2U                                            /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1U                                            /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0U                                            /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+  \brief    Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control Register */
+  __IOM uint32_t CYCCNT;                 /*!< Offset: 0x004 (R/W)  Cycle Count Register */
+  __IOM uint32_t CPICNT;                 /*!< Offset: 0x008 (R/W)  CPI Count Register */
+  __IOM uint32_t EXCCNT;                 /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register */
+  __IOM uint32_t SLEEPCNT;               /*!< Offset: 0x010 (R/W)  Sleep Count Register */
+  __IOM uint32_t LSUCNT;                 /*!< Offset: 0x014 (R/W)  LSU Count Register */
+  __IOM uint32_t FOLDCNT;                /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register */
+  __IM  uint32_t PCSR;                   /*!< Offset: 0x01C (R/ )  Program Counter Sample Register */
+  __IOM uint32_t COMP0;                  /*!< Offset: 0x020 (R/W)  Comparator Register 0 */
+  __IOM uint32_t MASK0;                  /*!< Offset: 0x024 (R/W)  Mask Register 0 */
+  __IOM uint32_t FUNCTION0;              /*!< Offset: 0x028 (R/W)  Function Register 0 */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t COMP1;                  /*!< Offset: 0x030 (R/W)  Comparator Register 1 */
+  __IOM uint32_t MASK1;                  /*!< Offset: 0x034 (R/W)  Mask Register 1 */
+  __IOM uint32_t FUNCTION1;              /*!< Offset: 0x038 (R/W)  Function Register 1 */
+        uint32_t RESERVED1[1U];
+  __IOM uint32_t COMP2;                  /*!< Offset: 0x040 (R/W)  Comparator Register 2 */
+  __IOM uint32_t MASK2;                  /*!< Offset: 0x044 (R/W)  Mask Register 2 */
+  __IOM uint32_t FUNCTION2;              /*!< Offset: 0x048 (R/W)  Function Register 2 */
+        uint32_t RESERVED2[1U];
+  __IOM uint32_t COMP3;                  /*!< Offset: 0x050 (R/W)  Comparator Register 3 */
+  __IOM uint32_t MASK3;                  /*!< Offset: 0x054 (R/W)  Mask Register 3 */
+  __IOM uint32_t FUNCTION3;              /*!< Offset: 0x058 (R/W)  Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28U                                         /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27U                                         /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26U                                         /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25U                                         /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24U                                         /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22U                                         /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21U                                         /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20U                                         /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19U                                         /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18U                                         /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17U                                         /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16U                                         /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12U                                         /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10U                                         /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9U                                         /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5U                                         /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1U                                         /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0U                                         /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0U                                         /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0U                                         /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0U                                         /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0U                                         /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0U                                         /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24U                                         /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16U                                         /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12U                                         /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10U                                         /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9U                                         /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8U                                         /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7U                                         /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5U                                         /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0U                                         /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+  \brief    Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IOM uint32_t SSPSR;                  /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register */
+  __IOM uint32_t CSPSR;                  /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACPR;                   /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+        uint32_t RESERVED1[55U];
+  __IOM uint32_t SPPR;                   /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+        uint32_t RESERVED2[131U];
+  __IM  uint32_t FFSR;                   /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IOM uint32_t FFCR;                   /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __IM  uint32_t FSCR;                   /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+        uint32_t RESERVED3[759U];
+  __IM  uint32_t TRIGGER;                /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __IM  uint32_t FIFO0;                  /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __IM  uint32_t ITATBCTR2;              /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+        uint32_t RESERVED4[1U];
+  __IM  uint32_t ITATBCTR0;              /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __IM  uint32_t FIFO1;                  /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IOM uint32_t ITCTRL;                 /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+        uint32_t RESERVED5[39U];
+  __IOM uint32_t CLAIMSET;               /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IOM uint32_t CLAIMCLR;               /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+        uint32_t RESERVED7[8U];
+  __IM  uint32_t DEVID;                  /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __IM  uint32_t DEVTYPE;                /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0U                                         /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0U                                         /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3U                                         /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2U                                         /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1U                                         /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0U                                         /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8U                                         /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1U                                         /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0U                                         /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16U                                         /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8U                                         /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0U                                         /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16U                                         /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8U                                         /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0U                                         /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0U                                         /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11U                                         /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10U                                         /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9U                                         /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6U                                         /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5U                                         /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0U                                         /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4U                                         /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0U                                         /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A1;                /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register */
+  __IOM uint32_t RASR_A1;                /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A2;                /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register */
+  __IOM uint32_t RASR_A2;                /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A3;                /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register */
+  __IOM uint32_t RASR_A3;                /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Type definitions for the Core Debug Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IOM uint32_t DHCSR;                  /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register */
+  __OM  uint32_t DCRSR;                  /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register */
+  __IOM uint32_t DCRDR;                  /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register */
+  __IOM uint32_t DEMCR;                  /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16U                                            /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25U                                            /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24U                                            /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19U                                            /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18U                                            /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17U                                            /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16U                                            /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5U                                            /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3U                                            /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2U                                            /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1U                                            /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0U                                            /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos         16U                                            /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0U                                            /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19U                                            /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18U                                            /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17U                                            /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16U                                            /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10U                                            /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9U                                            /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8U                                            /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7U                                            /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6U                                            /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5U                                            /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4U                                            /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0U                                            /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/**
+  \brief   Set Priority Grouping
+  \details Sets the priority grouping field using the required unlock sequence.
+           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+           Only values from 0..7 are used.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8U)                      );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/**
+  \brief   Get Priority Grouping
+  \details Reads the priority grouping field from the NVIC Interrupt Controller.
+  \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Active Interrupt
+  \details Reads the active register in NVIC and returns the active bit.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else
+  {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]               >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   Encode Priority
+  \details Encodes the priority for an interrupt with the given priority group,
+           preemptive priority value, and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]     PriorityGroup  Used priority group.
+  \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+  \param [in]       SubPriority  Subpriority value (starting from 0).
+  \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/**
+  \brief   Decode Priority
+  \details Decodes an interrupt priority value with a given priority group to
+           preemptive priority value and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+  \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+  \param [in]     PriorityGroup  Used priority group.
+  \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+  \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_core_DebugFunctions ITM Functions
+  \brief    Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters. */
+#define                 ITM_RXBUFFER_EMPTY   0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+  \brief   ITM Send Character
+  \details Transmits a character via the ITM channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0U].u32 == 0UL)
+    {
+      __NOP();
+    }
+    ITM->PORT[0U].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Receive Character
+  \details Inputs a character via the external variable \ref ITM_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+  {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Check Character
+  \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+  {
+    return (0);                              /* no character available */
+  }
+  else
+  {
+    return (1);                              /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM3_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm4.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm4.h
new file mode 100755
index 0000000..dc840eb
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm4.h
@@ -0,0 +1,1937 @@
+/**************************************************************************//**
+ * @file     core_cm4.h
+ * @brief    CMSIS Cortex-M4 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM4_H_GENERIC
+#define __CORE_CM4_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex_M4
+  @{
+ */
+
+/*  CMSIS CM4 definitions */
+#define __CM4_CMSIS_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CMSIS HAL main version */
+#define __CM4_CMSIS_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CMSIS HAL sub version */
+#define __CM4_CMSIS_VERSION       ((__CM4_CMSIS_VERSION_MAIN << 16U) | \
+                                    __CM4_CMSIS_VERSION_SUB           )        /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x04U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1U
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+#include "core_cmSimd.h"                 /* Compiler specific SIMD Intrinsics */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM4_H_DEPENDANT
+#define __CORE_CM4_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM4_REV
+    #define __CM4_REV               0x0000U
+    #warning "__CM4_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __FPU_PRESENT
+    #define __FPU_PRESENT             0U
+    #warning "__FPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M4 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+  - Core FPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27U                                            /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+#define APSR_GE_Pos                        16U                                            /*!< APSR: GE Position */
+#define APSR_GE_Msk                        (0xFUL << APSR_GE_Pos)                         /*!< APSR: GE Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0) */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27U                                            /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25U                                            /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_GE_Pos                        16U                                            /*!< xPSR: GE Position */
+#define xPSR_GE_Msk                        (0xFUL << xPSR_GE_Pos)                         /*!< xPSR: GE Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_FPCA_Pos                    2U                                            /*!< CONTROL: FPCA Position */
+#define CONTROL_FPCA_Msk                   (1UL << CONTROL_FPCA_Pos)                      /*!< CONTROL: FPCA Mask */
+
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[24U];
+  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[24U];
+  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[24U];
+  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[24U];
+  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
+        uint32_t RESERVED4[56U];
+  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+        uint32_t RESERVED5[644U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0U                                         /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+  __IOM uint8_t  SHP[12U];               /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
+  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
+  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
+  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
+  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
+  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
+  __IM  uint32_t PFR[2U];                /*!< Offset: 0x040 (R/ )  Processor Feature Register */
+  __IM  uint32_t DFR;                    /*!< Offset: 0x048 (R/ )  Debug Feature Register */
+  __IM  uint32_t ADR;                    /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
+  __IM  uint32_t MMFR[4U];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
+  __IM  uint32_t ISAR[5U];               /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
+        uint32_t RESERVED0[5U];
+  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11U                                            /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8U                                            /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0U                                            /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8U                                            /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4U                                            /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1U                                            /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0U                                            /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18U                                            /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17U                                            /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16U                                            /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14U                                            /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13U                                            /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12U                                            /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11U                                            /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10U                                            /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8U                                            /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7U                                            /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3U                                            /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1U                                            /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0U                                            /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16U                                            /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8U                                            /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0U                                            /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31U                                            /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30U                                            /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1U                                            /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4U                                            /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3U                                            /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2U                                            /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1U                                            /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0U                                            /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t ICTR;                   /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register */
+  __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0U                                         /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISOOFP_Pos            9U                                         /*!< ACTLR: DISOOFP Position */
+#define SCnSCB_ACTLR_DISOOFP_Msk           (1UL << SCnSCB_ACTLR_DISOOFP_Pos)           /*!< ACTLR: DISOOFP Mask */
+
+#define SCnSCB_ACTLR_DISFPCA_Pos            8U                                         /*!< ACTLR: DISFPCA Position */
+#define SCnSCB_ACTLR_DISFPCA_Msk           (1UL << SCnSCB_ACTLR_DISFPCA_Pos)           /*!< ACTLR: DISFPCA Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2U                                         /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1U                                         /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0U                                         /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+  \brief    Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __OM  union
+  {
+    __OM  uint8_t    u8;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit */
+    __OM  uint16_t   u16;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit */
+    __OM  uint32_t   u32;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit */
+  }  PORT [32U];                         /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers */
+        uint32_t RESERVED0[864U];
+  __IOM uint32_t TER;                    /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register */
+        uint32_t RESERVED1[15U];
+  __IOM uint32_t TPR;                    /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register */
+        uint32_t RESERVED2[15U];
+  __IOM uint32_t TCR;                    /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register */
+        uint32_t RESERVED3[29U];
+  __OM  uint32_t IWR;                    /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register */
+  __IM  uint32_t IRR;                    /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register */
+  __IOM uint32_t IMCR;                   /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register */
+        uint32_t RESERVED4[43U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register */
+        uint32_t RESERVED5[6U];
+  __IM  uint32_t PID4;                   /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __IM  uint32_t PID5;                   /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __IM  uint32_t PID6;                   /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __IM  uint32_t PID7;                   /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __IM  uint32_t PID0;                   /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __IM  uint32_t PID1;                   /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __IM  uint32_t PID2;                   /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __IM  uint32_t PID3;                   /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __IM  uint32_t CID0;                   /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __IM  uint32_t CID1;                   /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __IM  uint32_t CID2;                   /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __IM  uint32_t CID3;                   /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0U                                            /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23U                                            /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16U                                            /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10U                                            /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8U                                            /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4U                                            /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3U                                            /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2U                                            /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1U                                            /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0U                                            /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0U                                            /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0U                                            /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0U                                            /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2U                                            /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1U                                            /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0U                                            /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+  \brief    Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control Register */
+  __IOM uint32_t CYCCNT;                 /*!< Offset: 0x004 (R/W)  Cycle Count Register */
+  __IOM uint32_t CPICNT;                 /*!< Offset: 0x008 (R/W)  CPI Count Register */
+  __IOM uint32_t EXCCNT;                 /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register */
+  __IOM uint32_t SLEEPCNT;               /*!< Offset: 0x010 (R/W)  Sleep Count Register */
+  __IOM uint32_t LSUCNT;                 /*!< Offset: 0x014 (R/W)  LSU Count Register */
+  __IOM uint32_t FOLDCNT;                /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register */
+  __IM  uint32_t PCSR;                   /*!< Offset: 0x01C (R/ )  Program Counter Sample Register */
+  __IOM uint32_t COMP0;                  /*!< Offset: 0x020 (R/W)  Comparator Register 0 */
+  __IOM uint32_t MASK0;                  /*!< Offset: 0x024 (R/W)  Mask Register 0 */
+  __IOM uint32_t FUNCTION0;              /*!< Offset: 0x028 (R/W)  Function Register 0 */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t COMP1;                  /*!< Offset: 0x030 (R/W)  Comparator Register 1 */
+  __IOM uint32_t MASK1;                  /*!< Offset: 0x034 (R/W)  Mask Register 1 */
+  __IOM uint32_t FUNCTION1;              /*!< Offset: 0x038 (R/W)  Function Register 1 */
+        uint32_t RESERVED1[1U];
+  __IOM uint32_t COMP2;                  /*!< Offset: 0x040 (R/W)  Comparator Register 2 */
+  __IOM uint32_t MASK2;                  /*!< Offset: 0x044 (R/W)  Mask Register 2 */
+  __IOM uint32_t FUNCTION2;              /*!< Offset: 0x048 (R/W)  Function Register 2 */
+        uint32_t RESERVED2[1U];
+  __IOM uint32_t COMP3;                  /*!< Offset: 0x050 (R/W)  Comparator Register 3 */
+  __IOM uint32_t MASK3;                  /*!< Offset: 0x054 (R/W)  Mask Register 3 */
+  __IOM uint32_t FUNCTION3;              /*!< Offset: 0x058 (R/W)  Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28U                                         /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27U                                         /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26U                                         /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25U                                         /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24U                                         /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22U                                         /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21U                                         /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20U                                         /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19U                                         /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18U                                         /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17U                                         /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16U                                         /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12U                                         /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10U                                         /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9U                                         /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5U                                         /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1U                                         /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0U                                         /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0U                                         /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0U                                         /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0U                                         /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0U                                         /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0U                                         /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24U                                         /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16U                                         /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12U                                         /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10U                                         /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9U                                         /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8U                                         /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7U                                         /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5U                                         /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0U                                         /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+  \brief    Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IOM uint32_t SSPSR;                  /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register */
+  __IOM uint32_t CSPSR;                  /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACPR;                   /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+        uint32_t RESERVED1[55U];
+  __IOM uint32_t SPPR;                   /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+        uint32_t RESERVED2[131U];
+  __IM  uint32_t FFSR;                   /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IOM uint32_t FFCR;                   /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __IM  uint32_t FSCR;                   /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+        uint32_t RESERVED3[759U];
+  __IM  uint32_t TRIGGER;                /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __IM  uint32_t FIFO0;                  /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __IM  uint32_t ITATBCTR2;              /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+        uint32_t RESERVED4[1U];
+  __IM  uint32_t ITATBCTR0;              /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __IM  uint32_t FIFO1;                  /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IOM uint32_t ITCTRL;                 /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+        uint32_t RESERVED5[39U];
+  __IOM uint32_t CLAIMSET;               /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IOM uint32_t CLAIMCLR;               /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+        uint32_t RESERVED7[8U];
+  __IM  uint32_t DEVID;                  /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __IM  uint32_t DEVTYPE;                /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0U                                         /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0U                                         /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3U                                         /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2U                                         /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1U                                         /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0U                                         /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8U                                         /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1U                                         /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0U                                         /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16U                                         /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8U                                         /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0U                                         /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16U                                         /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8U                                         /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0U                                         /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0U                                         /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11U                                         /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10U                                         /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9U                                         /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6U                                         /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5U                                         /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0U                                         /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4U                                         /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0U                                         /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A1;                /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register */
+  __IOM uint32_t RASR_A1;                /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A2;                /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register */
+  __IOM uint32_t RASR_A2;                /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A3;                /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register */
+  __IOM uint32_t RASR_A3;                /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_FPU     Floating Point Unit (FPU)
+  \brief    Type definitions for the Floating Point Unit (FPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t FPCCR;                  /*!< Offset: 0x004 (R/W)  Floating-Point Context Control Register */
+  __IOM uint32_t FPCAR;                  /*!< Offset: 0x008 (R/W)  Floating-Point Context Address Register */
+  __IOM uint32_t FPDSCR;                 /*!< Offset: 0x00C (R/W)  Floating-Point Default Status Control Register */
+  __IM  uint32_t MVFR0;                  /*!< Offset: 0x010 (R/ )  Media and FP Feature Register 0 */
+  __IM  uint32_t MVFR1;                  /*!< Offset: 0x014 (R/ )  Media and FP Feature Register 1 */
+} FPU_Type;
+
+/* Floating-Point Context Control Register Definitions */
+#define FPU_FPCCR_ASPEN_Pos                31U                                            /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk                (1UL << FPU_FPCCR_ASPEN_Pos)                   /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos                30U                                            /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk                (1UL << FPU_FPCCR_LSPEN_Pos)                   /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos                8U                                            /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk               (1UL << FPU_FPCCR_MONRDY_Pos)                  /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos                 6U                                            /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk                (1UL << FPU_FPCCR_BFRDY_Pos)                   /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos                 5U                                            /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk                (1UL << FPU_FPCCR_MMRDY_Pos)                   /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos                 4U                                            /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk                (1UL << FPU_FPCCR_HFRDY_Pos)                   /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos                3U                                            /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk               (1UL << FPU_FPCCR_THREAD_Pos)                  /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos                  1U                                            /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk                 (1UL << FPU_FPCCR_USER_Pos)                    /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos                0U                                            /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk               (1UL /*<< FPU_FPCCR_LSPACT_Pos*/)              /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register Definitions */
+#define FPU_FPCAR_ADDRESS_Pos               3U                                            /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk              (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos)        /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register Definitions */
+#define FPU_FPDSCR_AHP_Pos                 26U                                            /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk                 (1UL << FPU_FPDSCR_AHP_Pos)                    /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos                  25U                                            /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk                  (1UL << FPU_FPDSCR_DN_Pos)                     /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos                  24U                                            /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk                  (1UL << FPU_FPDSCR_FZ_Pos)                     /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos               22U                                            /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk               (3UL << FPU_FPDSCR_RMode_Pos)                  /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 Definitions */
+#define FPU_MVFR0_FP_rounding_modes_Pos    28U                                            /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk    (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos)     /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos        24U                                            /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk        (0xFUL << FPU_MVFR0_Short_vectors_Pos)         /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos          20U                                            /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk          (0xFUL << FPU_MVFR0_Square_root_Pos)           /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos               16U                                            /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk               (0xFUL << FPU_MVFR0_Divide_Pos)                /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos    12U                                            /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk    (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos)     /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos      8U                                            /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk     (0xFUL << FPU_MVFR0_Double_precision_Pos)      /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos      4U                                            /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk     (0xFUL << FPU_MVFR0_Single_precision_Pos)      /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos      0U                                            /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk     (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/)  /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 Definitions */
+#define FPU_MVFR1_FP_fused_MAC_Pos         28U                                            /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk         (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos)          /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos              24U                                            /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk              (0xFUL << FPU_MVFR1_FP_HPFP_Pos)               /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos            4U                                            /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk           (0xFUL << FPU_MVFR1_D_NaN_mode_Pos)            /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos              0U                                            /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk             (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/)          /*!< MVFR1: FtZ mode bits Mask */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Type definitions for the Core Debug Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IOM uint32_t DHCSR;                  /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register */
+  __OM  uint32_t DCRSR;                  /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register */
+  __IOM uint32_t DCRDR;                  /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register */
+  __IOM uint32_t DEMCR;                  /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16U                                            /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25U                                            /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24U                                            /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19U                                            /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18U                                            /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17U                                            /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16U                                            /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5U                                            /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3U                                            /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2U                                            /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1U                                            /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0U                                            /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos         16U                                            /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0U                                            /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19U                                            /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18U                                            /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17U                                            /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16U                                            /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10U                                            /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9U                                            /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8U                                            /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7U                                            /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6U                                            /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5U                                            /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4U                                            /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0U                                            /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+#if (__FPU_PRESENT == 1U)
+  #define FPU_BASE          (SCS_BASE +  0x0F30UL)                    /*!< Floating Point Unit */
+  #define FPU               ((FPU_Type       *)     FPU_BASE      )   /*!< Floating Point Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/**
+  \brief   Set Priority Grouping
+  \details Sets the priority grouping field using the required unlock sequence.
+           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+           Only values from 0..7 are used.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8U)                      );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/**
+  \brief   Get Priority Grouping
+  \details Reads the priority grouping field from the NVIC Interrupt Controller.
+  \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Active Interrupt
+  \details Reads the active register in NVIC and returns the active bit.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else
+  {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]               >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   Encode Priority
+  \details Encodes the priority for an interrupt with the given priority group,
+           preemptive priority value, and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]     PriorityGroup  Used priority group.
+  \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+  \param [in]       SubPriority  Subpriority value (starting from 0).
+  \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/**
+  \brief   Decode Priority
+  \details Decodes an interrupt priority value with a given priority group to
+           preemptive priority value and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+  \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+  \param [in]     PriorityGroup  Used priority group.
+  \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+  \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_core_DebugFunctions ITM Functions
+  \brief    Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters. */
+#define                 ITM_RXBUFFER_EMPTY   0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+  \brief   ITM Send Character
+  \details Transmits a character via the ITM channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0U].u32 == 0UL)
+    {
+      __NOP();
+    }
+    ITM->PORT[0U].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Receive Character
+  \details Inputs a character via the external variable \ref ITM_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+  {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Check Character
+  \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+  {
+    return (0);                              /* no character available */
+  }
+  else
+  {
+    return (1);                              /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm7.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm7.h
new file mode 100755
index 0000000..3b7530a
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cm7.h
@@ -0,0 +1,2512 @@
+/**************************************************************************//**
+ * @file     core_cm7.h
+ * @brief    CMSIS Cortex-M7 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM7_H_GENERIC
+#define __CORE_CM7_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex_M7
+  @{
+ */
+
+/*  CMSIS CM7 definitions */
+#define __CM7_CMSIS_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CMSIS HAL main version */
+#define __CM7_CMSIS_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CMSIS HAL sub version */
+#define __CM7_CMSIS_VERSION       ((__CM7_CMSIS_VERSION_MAIN << 16U) | \
+                                    __CM7_CMSIS_VERSION_SUB           )        /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x07U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1U
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+#include "core_cmSimd.h"                 /* Compiler specific SIMD Intrinsics */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM7_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM7_H_DEPENDANT
+#define __CORE_CM7_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM7_REV
+    #define __CM7_REV               0x0000U
+    #warning "__CM7_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __FPU_PRESENT
+    #define __FPU_PRESENT             0U
+    #warning "__FPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __ICACHE_PRESENT
+    #define __ICACHE_PRESENT          0U
+    #warning "__ICACHE_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __DCACHE_PRESENT
+    #define __DCACHE_PRESENT          0U
+    #warning "__DCACHE_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __DTCM_PRESENT
+    #define __DTCM_PRESENT            0U
+    #warning "__DTCM_PRESENT        not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          3U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M7 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+  - Core FPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27U                                            /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+#define APSR_GE_Pos                        16U                                            /*!< APSR: GE Position */
+#define APSR_GE_Msk                        (0xFUL << APSR_GE_Pos)                         /*!< APSR: GE Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0) */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27U                                            /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25U                                            /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_GE_Pos                        16U                                            /*!< xPSR: GE Position */
+#define xPSR_GE_Msk                        (0xFUL << xPSR_GE_Pos)                         /*!< xPSR: GE Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_FPCA_Pos                    2U                                            /*!< CONTROL: FPCA Position */
+#define CONTROL_FPCA_Msk                   (1UL << CONTROL_FPCA_Pos)                      /*!< CONTROL: FPCA Mask */
+
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[24U];
+  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[24U];
+  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[24U];
+  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[24U];
+  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
+        uint32_t RESERVED4[56U];
+  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+        uint32_t RESERVED5[644U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0U                                         /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+  __IOM uint8_t  SHPR[12U];              /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
+  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
+  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
+  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
+  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
+  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
+  __IM  uint32_t ID_PFR[2U];             /*!< Offset: 0x040 (R/ )  Processor Feature Register */
+  __IM  uint32_t ID_DFR;                 /*!< Offset: 0x048 (R/ )  Debug Feature Register */
+  __IM  uint32_t ID_AFR;                 /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
+  __IM  uint32_t ID_MFR[4U];             /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
+  __IM  uint32_t ID_ISAR[5U];            /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t CLIDR;                  /*!< Offset: 0x078 (R/ )  Cache Level ID register */
+  __IM  uint32_t CTR;                    /*!< Offset: 0x07C (R/ )  Cache Type register */
+  __IM  uint32_t CCSIDR;                 /*!< Offset: 0x080 (R/ )  Cache Size ID Register */
+  __IOM uint32_t CSSELR;                 /*!< Offset: 0x084 (R/W)  Cache Size Selection Register */
+  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
+        uint32_t RESERVED3[93U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0x200 ( /W)  Software Triggered Interrupt Register */
+        uint32_t RESERVED4[15U];
+  __IM  uint32_t MVFR0;                  /*!< Offset: 0x240 (R/ )  Media and VFP Feature Register 0 */
+  __IM  uint32_t MVFR1;                  /*!< Offset: 0x244 (R/ )  Media and VFP Feature Register 1 */
+  __IM  uint32_t MVFR2;                  /*!< Offset: 0x248 (R/ )  Media and VFP Feature Register 1 */
+        uint32_t RESERVED5[1U];
+  __OM  uint32_t ICIALLU;                /*!< Offset: 0x250 ( /W)  I-Cache Invalidate All to PoU */
+        uint32_t RESERVED6[1U];
+  __OM  uint32_t ICIMVAU;                /*!< Offset: 0x258 ( /W)  I-Cache Invalidate by MVA to PoU */
+  __OM  uint32_t DCIMVAC;                /*!< Offset: 0x25C ( /W)  D-Cache Invalidate by MVA to PoC */
+  __OM  uint32_t DCISW;                  /*!< Offset: 0x260 ( /W)  D-Cache Invalidate by Set-way */
+  __OM  uint32_t DCCMVAU;                /*!< Offset: 0x264 ( /W)  D-Cache Clean by MVA to PoU */
+  __OM  uint32_t DCCMVAC;                /*!< Offset: 0x268 ( /W)  D-Cache Clean by MVA to PoC */
+  __OM  uint32_t DCCSW;                  /*!< Offset: 0x26C ( /W)  D-Cache Clean by Set-way */
+  __OM  uint32_t DCCIMVAC;               /*!< Offset: 0x270 ( /W)  D-Cache Clean and Invalidate by MVA to PoC */
+  __OM  uint32_t DCCISW;                 /*!< Offset: 0x274 ( /W)  D-Cache Clean and Invalidate by Set-way */
+        uint32_t RESERVED7[6U];
+  __IOM uint32_t ITCMCR;                 /*!< Offset: 0x290 (R/W)  Instruction Tightly-Coupled Memory Control Register */
+  __IOM uint32_t DTCMCR;                 /*!< Offset: 0x294 (R/W)  Data Tightly-Coupled Memory Control Registers */
+  __IOM uint32_t AHBPCR;                 /*!< Offset: 0x298 (R/W)  AHBP Control Register */
+  __IOM uint32_t CACR;                   /*!< Offset: 0x29C (R/W)  L1 Cache Control Register */
+  __IOM uint32_t AHBSCR;                 /*!< Offset: 0x2A0 (R/W)  AHB Slave Control Register */
+        uint32_t RESERVED8[1U];
+  __IOM uint32_t ABFSR;                  /*!< Offset: 0x2A8 (R/W)  Auxiliary Bus Fault Status Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11U                                            /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8U                                            /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0U                                            /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_BP_Pos                      18U                                           /*!< SCB CCR: Branch prediction enable bit Position */
+#define SCB_CCR_BP_Msk                     (1UL << SCB_CCR_BP_Pos)                        /*!< SCB CCR: Branch prediction enable bit Mask */
+
+#define SCB_CCR_IC_Pos                      17U                                           /*!< SCB CCR: Instruction cache enable bit Position */
+#define SCB_CCR_IC_Msk                     (1UL << SCB_CCR_IC_Pos)                        /*!< SCB CCR: Instruction cache enable bit Mask */
+
+#define SCB_CCR_DC_Pos                      16U                                           /*!< SCB CCR: Cache enable bit Position */
+#define SCB_CCR_DC_Msk                     (1UL << SCB_CCR_DC_Pos)                        /*!< SCB CCR: Cache enable bit Mask */
+
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8U                                            /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4U                                            /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1U                                            /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0U                                            /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18U                                            /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17U                                            /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16U                                            /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14U                                            /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13U                                            /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12U                                            /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11U                                            /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10U                                            /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8U                                            /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7U                                            /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3U                                            /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1U                                            /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0U                                            /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16U                                            /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8U                                            /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0U                                            /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31U                                            /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30U                                            /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1U                                            /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4U                                            /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3U                                            /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2U                                            /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1U                                            /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0U                                            /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/* SCB Cache Level ID Register Definitions */
+#define SCB_CLIDR_LOUU_Pos                 27U                                            /*!< SCB CLIDR: LoUU Position */
+#define SCB_CLIDR_LOUU_Msk                 (7UL << SCB_CLIDR_LOUU_Pos)                    /*!< SCB CLIDR: LoUU Mask */
+
+#define SCB_CLIDR_LOC_Pos                  24U                                            /*!< SCB CLIDR: LoC Position */
+#define SCB_CLIDR_LOC_Msk                  (7UL << SCB_CLIDR_LOC_Pos)                     /*!< SCB CLIDR: LoC Mask */
+
+/* SCB Cache Type Register Definitions */
+#define SCB_CTR_FORMAT_Pos                 29U                                            /*!< SCB CTR: Format Position */
+#define SCB_CTR_FORMAT_Msk                 (7UL << SCB_CTR_FORMAT_Pos)                    /*!< SCB CTR: Format Mask */
+
+#define SCB_CTR_CWG_Pos                    24U                                            /*!< SCB CTR: CWG Position */
+#define SCB_CTR_CWG_Msk                    (0xFUL << SCB_CTR_CWG_Pos)                     /*!< SCB CTR: CWG Mask */
+
+#define SCB_CTR_ERG_Pos                    20U                                            /*!< SCB CTR: ERG Position */
+#define SCB_CTR_ERG_Msk                    (0xFUL << SCB_CTR_ERG_Pos)                     /*!< SCB CTR: ERG Mask */
+
+#define SCB_CTR_DMINLINE_Pos               16U                                            /*!< SCB CTR: DminLine Position */
+#define SCB_CTR_DMINLINE_Msk               (0xFUL << SCB_CTR_DMINLINE_Pos)                /*!< SCB CTR: DminLine Mask */
+
+#define SCB_CTR_IMINLINE_Pos                0U                                            /*!< SCB CTR: ImInLine Position */
+#define SCB_CTR_IMINLINE_Msk               (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/)            /*!< SCB CTR: ImInLine Mask */
+
+/* SCB Cache Size ID Register Definitions */
+#define SCB_CCSIDR_WT_Pos                  31U                                            /*!< SCB CCSIDR: WT Position */
+#define SCB_CCSIDR_WT_Msk                  (1UL << SCB_CCSIDR_WT_Pos)                     /*!< SCB CCSIDR: WT Mask */
+
+#define SCB_CCSIDR_WB_Pos                  30U                                            /*!< SCB CCSIDR: WB Position */
+#define SCB_CCSIDR_WB_Msk                  (1UL << SCB_CCSIDR_WB_Pos)                     /*!< SCB CCSIDR: WB Mask */
+
+#define SCB_CCSIDR_RA_Pos                  29U                                            /*!< SCB CCSIDR: RA Position */
+#define SCB_CCSIDR_RA_Msk                  (1UL << SCB_CCSIDR_RA_Pos)                     /*!< SCB CCSIDR: RA Mask */
+
+#define SCB_CCSIDR_WA_Pos                  28U                                            /*!< SCB CCSIDR: WA Position */
+#define SCB_CCSIDR_WA_Msk                  (1UL << SCB_CCSIDR_WA_Pos)                     /*!< SCB CCSIDR: WA Mask */
+
+#define SCB_CCSIDR_NUMSETS_Pos             13U                                            /*!< SCB CCSIDR: NumSets Position */
+#define SCB_CCSIDR_NUMSETS_Msk             (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos)           /*!< SCB CCSIDR: NumSets Mask */
+
+#define SCB_CCSIDR_ASSOCIATIVITY_Pos        3U                                            /*!< SCB CCSIDR: Associativity Position */
+#define SCB_CCSIDR_ASSOCIATIVITY_Msk       (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos)      /*!< SCB CCSIDR: Associativity Mask */
+
+#define SCB_CCSIDR_LINESIZE_Pos             0U                                            /*!< SCB CCSIDR: LineSize Position */
+#define SCB_CCSIDR_LINESIZE_Msk            (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/)           /*!< SCB CCSIDR: LineSize Mask */
+
+/* SCB Cache Size Selection Register Definitions */
+#define SCB_CSSELR_LEVEL_Pos                1U                                            /*!< SCB CSSELR: Level Position */
+#define SCB_CSSELR_LEVEL_Msk               (7UL << SCB_CSSELR_LEVEL_Pos)                  /*!< SCB CSSELR: Level Mask */
+
+#define SCB_CSSELR_IND_Pos                  0U                                            /*!< SCB CSSELR: InD Position */
+#define SCB_CSSELR_IND_Msk                 (1UL /*<< SCB_CSSELR_IND_Pos*/)                /*!< SCB CSSELR: InD Mask */
+
+/* SCB Software Triggered Interrupt Register Definitions */
+#define SCB_STIR_INTID_Pos                  0U                                            /*!< SCB STIR: INTID Position */
+#define SCB_STIR_INTID_Msk                 (0x1FFUL /*<< SCB_STIR_INTID_Pos*/)            /*!< SCB STIR: INTID Mask */
+
+/* SCB D-Cache Invalidate by Set-way Register Definitions */
+#define SCB_DCISW_WAY_Pos                  30U                                            /*!< SCB DCISW: Way Position */
+#define SCB_DCISW_WAY_Msk                  (3UL << SCB_DCISW_WAY_Pos)                     /*!< SCB DCISW: Way Mask */
+
+#define SCB_DCISW_SET_Pos                   5U                                            /*!< SCB DCISW: Set Position */
+#define SCB_DCISW_SET_Msk                  (0x1FFUL << SCB_DCISW_SET_Pos)                 /*!< SCB DCISW: Set Mask */
+
+/* SCB D-Cache Clean by Set-way Register Definitions */
+#define SCB_DCCSW_WAY_Pos                  30U                                            /*!< SCB DCCSW: Way Position */
+#define SCB_DCCSW_WAY_Msk                  (3UL << SCB_DCCSW_WAY_Pos)                     /*!< SCB DCCSW: Way Mask */
+
+#define SCB_DCCSW_SET_Pos                   5U                                            /*!< SCB DCCSW: Set Position */
+#define SCB_DCCSW_SET_Msk                  (0x1FFUL << SCB_DCCSW_SET_Pos)                 /*!< SCB DCCSW: Set Mask */
+
+/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */
+#define SCB_DCCISW_WAY_Pos                 30U                                            /*!< SCB DCCISW: Way Position */
+#define SCB_DCCISW_WAY_Msk                 (3UL << SCB_DCCISW_WAY_Pos)                    /*!< SCB DCCISW: Way Mask */
+
+#define SCB_DCCISW_SET_Pos                  5U                                            /*!< SCB DCCISW: Set Position */
+#define SCB_DCCISW_SET_Msk                 (0x1FFUL << SCB_DCCISW_SET_Pos)                /*!< SCB DCCISW: Set Mask */
+
+/* Instruction Tightly-Coupled Memory Control Register Definitions */
+#define SCB_ITCMCR_SZ_Pos                   3U                                            /*!< SCB ITCMCR: SZ Position */
+#define SCB_ITCMCR_SZ_Msk                  (0xFUL << SCB_ITCMCR_SZ_Pos)                   /*!< SCB ITCMCR: SZ Mask */
+
+#define SCB_ITCMCR_RETEN_Pos                2U                                            /*!< SCB ITCMCR: RETEN Position */
+#define SCB_ITCMCR_RETEN_Msk               (1UL << SCB_ITCMCR_RETEN_Pos)                  /*!< SCB ITCMCR: RETEN Mask */
+
+#define SCB_ITCMCR_RMW_Pos                  1U                                            /*!< SCB ITCMCR: RMW Position */
+#define SCB_ITCMCR_RMW_Msk                 (1UL << SCB_ITCMCR_RMW_Pos)                    /*!< SCB ITCMCR: RMW Mask */
+
+#define SCB_ITCMCR_EN_Pos                   0U                                            /*!< SCB ITCMCR: EN Position */
+#define SCB_ITCMCR_EN_Msk                  (1UL /*<< SCB_ITCMCR_EN_Pos*/)                 /*!< SCB ITCMCR: EN Mask */
+
+/* Data Tightly-Coupled Memory Control Register Definitions */
+#define SCB_DTCMCR_SZ_Pos                   3U                                            /*!< SCB DTCMCR: SZ Position */
+#define SCB_DTCMCR_SZ_Msk                  (0xFUL << SCB_DTCMCR_SZ_Pos)                   /*!< SCB DTCMCR: SZ Mask */
+
+#define SCB_DTCMCR_RETEN_Pos                2U                                            /*!< SCB DTCMCR: RETEN Position */
+#define SCB_DTCMCR_RETEN_Msk               (1UL << SCB_DTCMCR_RETEN_Pos)                   /*!< SCB DTCMCR: RETEN Mask */
+
+#define SCB_DTCMCR_RMW_Pos                  1U                                            /*!< SCB DTCMCR: RMW Position */
+#define SCB_DTCMCR_RMW_Msk                 (1UL << SCB_DTCMCR_RMW_Pos)                    /*!< SCB DTCMCR: RMW Mask */
+
+#define SCB_DTCMCR_EN_Pos                   0U                                            /*!< SCB DTCMCR: EN Position */
+#define SCB_DTCMCR_EN_Msk                  (1UL /*<< SCB_DTCMCR_EN_Pos*/)                 /*!< SCB DTCMCR: EN Mask */
+
+/* AHBP Control Register Definitions */
+#define SCB_AHBPCR_SZ_Pos                   1U                                            /*!< SCB AHBPCR: SZ Position */
+#define SCB_AHBPCR_SZ_Msk                  (7UL << SCB_AHBPCR_SZ_Pos)                     /*!< SCB AHBPCR: SZ Mask */
+
+#define SCB_AHBPCR_EN_Pos                   0U                                            /*!< SCB AHBPCR: EN Position */
+#define SCB_AHBPCR_EN_Msk                  (1UL /*<< SCB_AHBPCR_EN_Pos*/)                 /*!< SCB AHBPCR: EN Mask */
+
+/* L1 Cache Control Register Definitions */
+#define SCB_CACR_FORCEWT_Pos                2U                                            /*!< SCB CACR: FORCEWT Position */
+#define SCB_CACR_FORCEWT_Msk               (1UL << SCB_CACR_FORCEWT_Pos)                  /*!< SCB CACR: FORCEWT Mask */
+
+#define SCB_CACR_ECCEN_Pos                  1U                                            /*!< SCB CACR: ECCEN Position */
+#define SCB_CACR_ECCEN_Msk                 (1UL << SCB_CACR_ECCEN_Pos)                    /*!< SCB CACR: ECCEN Mask */
+
+#define SCB_CACR_SIWT_Pos                   0U                                            /*!< SCB CACR: SIWT Position */
+#define SCB_CACR_SIWT_Msk                  (1UL /*<< SCB_CACR_SIWT_Pos*/)                 /*!< SCB CACR: SIWT Mask */
+
+/* AHBS Control Register Definitions */
+#define SCB_AHBSCR_INITCOUNT_Pos           11U                                            /*!< SCB AHBSCR: INITCOUNT Position */
+#define SCB_AHBSCR_INITCOUNT_Msk           (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos)           /*!< SCB AHBSCR: INITCOUNT Mask */
+
+#define SCB_AHBSCR_TPRI_Pos                 2U                                            /*!< SCB AHBSCR: TPRI Position */
+#define SCB_AHBSCR_TPRI_Msk                (0x1FFUL << SCB_AHBPCR_TPRI_Pos)               /*!< SCB AHBSCR: TPRI Mask */
+
+#define SCB_AHBSCR_CTL_Pos                  0U                                            /*!< SCB AHBSCR: CTL Position*/
+#define SCB_AHBSCR_CTL_Msk                 (3UL /*<< SCB_AHBPCR_CTL_Pos*/)                /*!< SCB AHBSCR: CTL Mask */
+
+/* Auxiliary Bus Fault Status Register Definitions */
+#define SCB_ABFSR_AXIMTYPE_Pos              8U                                            /*!< SCB ABFSR: AXIMTYPE Position*/
+#define SCB_ABFSR_AXIMTYPE_Msk             (3UL << SCB_ABFSR_AXIMTYPE_Pos)                /*!< SCB ABFSR: AXIMTYPE Mask */
+
+#define SCB_ABFSR_EPPB_Pos                  4U                                            /*!< SCB ABFSR: EPPB Position*/
+#define SCB_ABFSR_EPPB_Msk                 (1UL << SCB_ABFSR_EPPB_Pos)                    /*!< SCB ABFSR: EPPB Mask */
+
+#define SCB_ABFSR_AXIM_Pos                  3U                                            /*!< SCB ABFSR: AXIM Position*/
+#define SCB_ABFSR_AXIM_Msk                 (1UL << SCB_ABFSR_AXIM_Pos)                    /*!< SCB ABFSR: AXIM Mask */
+
+#define SCB_ABFSR_AHBP_Pos                  2U                                            /*!< SCB ABFSR: AHBP Position*/
+#define SCB_ABFSR_AHBP_Msk                 (1UL << SCB_ABFSR_AHBP_Pos)                    /*!< SCB ABFSR: AHBP Mask */
+
+#define SCB_ABFSR_DTCM_Pos                  1U                                            /*!< SCB ABFSR: DTCM Position*/
+#define SCB_ABFSR_DTCM_Msk                 (1UL << SCB_ABFSR_DTCM_Pos)                    /*!< SCB ABFSR: DTCM Mask */
+
+#define SCB_ABFSR_ITCM_Pos                  0U                                            /*!< SCB ABFSR: ITCM Position*/
+#define SCB_ABFSR_ITCM_Msk                 (1UL /*<< SCB_ABFSR_ITCM_Pos*/)                /*!< SCB ABFSR: ITCM Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t ICTR;                   /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register */
+  __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0U                                         /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos    12U                                         /*!< ACTLR: DISITMATBFLUSH Position */
+#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk    (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos)    /*!< ACTLR: DISITMATBFLUSH Mask */
+
+#define SCnSCB_ACTLR_DISRAMODE_Pos         11U                                         /*!< ACTLR: DISRAMODE Position */
+#define SCnSCB_ACTLR_DISRAMODE_Msk         (1UL << SCnSCB_ACTLR_DISRAMODE_Pos)         /*!< ACTLR: DISRAMODE Mask */
+
+#define SCnSCB_ACTLR_FPEXCODIS_Pos         10U                                         /*!< ACTLR: FPEXCODIS Position */
+#define SCnSCB_ACTLR_FPEXCODIS_Msk         (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos)         /*!< ACTLR: FPEXCODIS Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2U                                         /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0U                                         /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+  \brief    Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __OM  union
+  {
+    __OM  uint8_t    u8;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit */
+    __OM  uint16_t   u16;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit */
+    __OM  uint32_t   u32;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit */
+  }  PORT [32U];                         /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers */
+        uint32_t RESERVED0[864U];
+  __IOM uint32_t TER;                    /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register */
+        uint32_t RESERVED1[15U];
+  __IOM uint32_t TPR;                    /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register */
+        uint32_t RESERVED2[15U];
+  __IOM uint32_t TCR;                    /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register */
+        uint32_t RESERVED3[29U];
+  __OM  uint32_t IWR;                    /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register */
+  __IM  uint32_t IRR;                    /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register */
+  __IOM uint32_t IMCR;                   /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register */
+        uint32_t RESERVED4[43U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register */
+        uint32_t RESERVED5[6U];
+  __IM  uint32_t PID4;                   /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __IM  uint32_t PID5;                   /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __IM  uint32_t PID6;                   /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __IM  uint32_t PID7;                   /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __IM  uint32_t PID0;                   /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __IM  uint32_t PID1;                   /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __IM  uint32_t PID2;                   /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __IM  uint32_t PID3;                   /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __IM  uint32_t CID0;                   /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __IM  uint32_t CID1;                   /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __IM  uint32_t CID2;                   /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __IM  uint32_t CID3;                   /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0U                                            /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23U                                            /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16U                                            /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10U                                            /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8U                                            /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4U                                            /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3U                                            /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2U                                            /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1U                                            /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0U                                            /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0U                                            /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0U                                            /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0U                                            /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2U                                            /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1U                                            /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0U                                            /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+  \brief    Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control Register */
+  __IOM uint32_t CYCCNT;                 /*!< Offset: 0x004 (R/W)  Cycle Count Register */
+  __IOM uint32_t CPICNT;                 /*!< Offset: 0x008 (R/W)  CPI Count Register */
+  __IOM uint32_t EXCCNT;                 /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register */
+  __IOM uint32_t SLEEPCNT;               /*!< Offset: 0x010 (R/W)  Sleep Count Register */
+  __IOM uint32_t LSUCNT;                 /*!< Offset: 0x014 (R/W)  LSU Count Register */
+  __IOM uint32_t FOLDCNT;                /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register */
+  __IM  uint32_t PCSR;                   /*!< Offset: 0x01C (R/ )  Program Counter Sample Register */
+  __IOM uint32_t COMP0;                  /*!< Offset: 0x020 (R/W)  Comparator Register 0 */
+  __IOM uint32_t MASK0;                  /*!< Offset: 0x024 (R/W)  Mask Register 0 */
+  __IOM uint32_t FUNCTION0;              /*!< Offset: 0x028 (R/W)  Function Register 0 */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t COMP1;                  /*!< Offset: 0x030 (R/W)  Comparator Register 1 */
+  __IOM uint32_t MASK1;                  /*!< Offset: 0x034 (R/W)  Mask Register 1 */
+  __IOM uint32_t FUNCTION1;              /*!< Offset: 0x038 (R/W)  Function Register 1 */
+        uint32_t RESERVED1[1U];
+  __IOM uint32_t COMP2;                  /*!< Offset: 0x040 (R/W)  Comparator Register 2 */
+  __IOM uint32_t MASK2;                  /*!< Offset: 0x044 (R/W)  Mask Register 2 */
+  __IOM uint32_t FUNCTION2;              /*!< Offset: 0x048 (R/W)  Function Register 2 */
+        uint32_t RESERVED2[1U];
+  __IOM uint32_t COMP3;                  /*!< Offset: 0x050 (R/W)  Comparator Register 3 */
+  __IOM uint32_t MASK3;                  /*!< Offset: 0x054 (R/W)  Mask Register 3 */
+  __IOM uint32_t FUNCTION3;              /*!< Offset: 0x058 (R/W)  Function Register 3 */
+        uint32_t RESERVED3[981U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 (  W)  Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R  )  Lock Status Register */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28U                                         /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27U                                         /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26U                                         /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25U                                         /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24U                                         /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22U                                         /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21U                                         /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20U                                         /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19U                                         /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18U                                         /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17U                                         /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16U                                         /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12U                                         /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10U                                         /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9U                                         /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5U                                         /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1U                                         /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0U                                         /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0U                                         /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0U                                         /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0U                                         /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0U                                         /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0U                                         /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24U                                         /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16U                                         /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12U                                         /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10U                                         /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9U                                         /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8U                                         /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7U                                         /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5U                                         /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0U                                         /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+  \brief    Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IOM uint32_t SSPSR;                  /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register */
+  __IOM uint32_t CSPSR;                  /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACPR;                   /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+        uint32_t RESERVED1[55U];
+  __IOM uint32_t SPPR;                   /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+        uint32_t RESERVED2[131U];
+  __IM  uint32_t FFSR;                   /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IOM uint32_t FFCR;                   /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __IM  uint32_t FSCR;                   /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+        uint32_t RESERVED3[759U];
+  __IM  uint32_t TRIGGER;                /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __IM  uint32_t FIFO0;                  /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __IM  uint32_t ITATBCTR2;              /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+        uint32_t RESERVED4[1U];
+  __IM  uint32_t ITATBCTR0;              /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __IM  uint32_t FIFO1;                  /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IOM uint32_t ITCTRL;                 /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+        uint32_t RESERVED5[39U];
+  __IOM uint32_t CLAIMSET;               /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IOM uint32_t CLAIMCLR;               /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+        uint32_t RESERVED7[8U];
+  __IM  uint32_t DEVID;                  /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __IM  uint32_t DEVTYPE;                /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0U                                         /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0U                                         /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3U                                         /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2U                                         /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1U                                         /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0U                                         /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8U                                         /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1U                                         /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0U                                         /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16U                                         /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8U                                         /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0U                                         /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16U                                         /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8U                                         /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0U                                         /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0U                                         /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11U                                         /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10U                                         /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9U                                         /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6U                                         /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5U                                         /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0U                                         /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4U                                         /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0U                                         /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A1;                /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register */
+  __IOM uint32_t RASR_A1;                /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A2;                /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register */
+  __IOM uint32_t RASR_A2;                /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A3;                /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register */
+  __IOM uint32_t RASR_A3;                /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_FPU     Floating Point Unit (FPU)
+  \brief    Type definitions for the Floating Point Unit (FPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t FPCCR;                  /*!< Offset: 0x004 (R/W)  Floating-Point Context Control Register */
+  __IOM uint32_t FPCAR;                  /*!< Offset: 0x008 (R/W)  Floating-Point Context Address Register */
+  __IOM uint32_t FPDSCR;                 /*!< Offset: 0x00C (R/W)  Floating-Point Default Status Control Register */
+  __IM  uint32_t MVFR0;                  /*!< Offset: 0x010 (R/ )  Media and FP Feature Register 0 */
+  __IM  uint32_t MVFR1;                  /*!< Offset: 0x014 (R/ )  Media and FP Feature Register 1 */
+  __IM  uint32_t MVFR2;                  /*!< Offset: 0x018 (R/ )  Media and FP Feature Register 2 */
+} FPU_Type;
+
+/* Floating-Point Context Control Register Definitions */
+#define FPU_FPCCR_ASPEN_Pos                31U                                            /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk                (1UL << FPU_FPCCR_ASPEN_Pos)                   /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos                30U                                            /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk                (1UL << FPU_FPCCR_LSPEN_Pos)                   /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos                8U                                            /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk               (1UL << FPU_FPCCR_MONRDY_Pos)                  /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos                 6U                                            /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk                (1UL << FPU_FPCCR_BFRDY_Pos)                   /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos                 5U                                            /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk                (1UL << FPU_FPCCR_MMRDY_Pos)                   /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos                 4U                                            /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk                (1UL << FPU_FPCCR_HFRDY_Pos)                   /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos                3U                                            /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk               (1UL << FPU_FPCCR_THREAD_Pos)                  /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos                  1U                                            /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk                 (1UL << FPU_FPCCR_USER_Pos)                    /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos                0U                                            /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk               (1UL /*<< FPU_FPCCR_LSPACT_Pos*/)              /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register Definitions */
+#define FPU_FPCAR_ADDRESS_Pos               3U                                            /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk              (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos)        /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register Definitions */
+#define FPU_FPDSCR_AHP_Pos                 26U                                            /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk                 (1UL << FPU_FPDSCR_AHP_Pos)                    /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos                  25U                                            /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk                  (1UL << FPU_FPDSCR_DN_Pos)                     /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos                  24U                                            /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk                  (1UL << FPU_FPDSCR_FZ_Pos)                     /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos               22U                                            /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk               (3UL << FPU_FPDSCR_RMode_Pos)                  /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 Definitions */
+#define FPU_MVFR0_FP_rounding_modes_Pos    28U                                            /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk    (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos)     /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos        24U                                            /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk        (0xFUL << FPU_MVFR0_Short_vectors_Pos)         /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos          20U                                            /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk          (0xFUL << FPU_MVFR0_Square_root_Pos)           /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos               16U                                            /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk               (0xFUL << FPU_MVFR0_Divide_Pos)                /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos    12U                                            /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk    (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos)     /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos      8U                                            /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk     (0xFUL << FPU_MVFR0_Double_precision_Pos)      /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos      4U                                            /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk     (0xFUL << FPU_MVFR0_Single_precision_Pos)      /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos      0U                                            /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk     (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/)  /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 Definitions */
+#define FPU_MVFR1_FP_fused_MAC_Pos         28U                                            /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk         (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos)          /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos              24U                                            /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk              (0xFUL << FPU_MVFR1_FP_HPFP_Pos)               /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos            4U                                            /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk           (0xFUL << FPU_MVFR1_D_NaN_mode_Pos)            /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos              0U                                            /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk             (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/)          /*!< MVFR1: FtZ mode bits Mask */
+
+/* Media and FP Feature Register 2 Definitions */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Type definitions for the Core Debug Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IOM uint32_t DHCSR;                  /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register */
+  __OM  uint32_t DCRSR;                  /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register */
+  __IOM uint32_t DCRDR;                  /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register */
+  __IOM uint32_t DEMCR;                  /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16U                                            /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25U                                            /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24U                                            /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19U                                            /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18U                                            /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17U                                            /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16U                                            /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5U                                            /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3U                                            /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2U                                            /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1U                                            /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0U                                            /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos         16U                                            /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0U                                            /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19U                                            /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18U                                            /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17U                                            /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16U                                            /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10U                                            /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9U                                            /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8U                                            /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7U                                            /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6U                                            /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5U                                            /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4U                                            /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0U                                            /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+#if (__FPU_PRESENT == 1U)
+  #define FPU_BASE          (SCS_BASE +  0x0F30UL)                    /*!< Floating Point Unit */
+  #define FPU               ((FPU_Type       *)     FPU_BASE      )   /*!< Floating Point Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/**
+  \brief   Set Priority Grouping
+  \details Sets the priority grouping field using the required unlock sequence.
+           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+           Only values from 0..7 are used.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8U)                      );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/**
+  \brief   Get Priority Grouping
+  \details Reads the priority grouping field from the NVIC Interrupt Controller.
+  \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Active Interrupt
+  \details Reads the active register in NVIC and returns the active bit.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else
+  {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]                = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]                >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   Encode Priority
+  \details Encodes the priority for an interrupt with the given priority group,
+           preemptive priority value, and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]     PriorityGroup  Used priority group.
+  \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+  \param [in]       SubPriority  Subpriority value (starting from 0).
+  \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/**
+  \brief   Decode Priority
+  \details Decodes an interrupt priority value with a given priority group to
+           preemptive priority value and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+  \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+  \param [in]     PriorityGroup  Used priority group.
+  \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+  \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+/* ##########################  FPU functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_FpuFunctions FPU Functions
+  \brief    Function that provides FPU type.
+  @{
+ */
+
+/**
+  \brief   get FPU type
+  \details returns the FPU type
+  \returns
+   - \b  0: No FPU
+   - \b  1: Single precision FPU
+   - \b  2: Double + Single precision FPU
+ */
+__STATIC_INLINE uint32_t SCB_GetFPUType(void)
+{
+  uint32_t mvfr0;
+
+  mvfr0 = SCB->MVFR0;
+  if        ((mvfr0 & 0x00000FF0UL) == 0x220UL)
+  {
+    return 2UL;           /* Double + Single precision FPU */
+  }
+  else if ((mvfr0 & 0x00000FF0UL) == 0x020UL)
+  {
+    return 1UL;           /* Single precision FPU */
+  }
+  else
+  {
+    return 0UL;           /* No FPU */
+  }
+}
+
+
+/*@} end of CMSIS_Core_FpuFunctions */
+
+
+
+/* ##########################  Cache functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_CacheFunctions Cache Functions
+  \brief    Functions that configure Instruction and Data cache.
+  @{
+ */
+
+/* Cache Size ID Register Macros */
+#define CCSIDR_WAYS(x)         (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
+#define CCSIDR_SETS(x)         (((x) & SCB_CCSIDR_NUMSETS_Msk      ) >> SCB_CCSIDR_NUMSETS_Pos      )
+
+
+/**
+  \brief   Enable I-Cache
+  \details Turns on I-Cache
+  */
+__STATIC_INLINE void SCB_EnableICache (void)
+{
+  #if (__ICACHE_PRESENT == 1U)
+    __DSB();
+    __ISB();
+    SCB->ICIALLU = 0UL;                     /* invalidate I-Cache */
+    SCB->CCR |=  (uint32_t)SCB_CCR_IC_Msk;  /* enable I-Cache */
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Disable I-Cache
+  \details Turns off I-Cache
+  */
+__STATIC_INLINE void SCB_DisableICache (void)
+{
+  #if (__ICACHE_PRESENT == 1U)
+    __DSB();
+    __ISB();
+    SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk;  /* disable I-Cache */
+    SCB->ICIALLU = 0UL;                     /* invalidate I-Cache */
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Invalidate I-Cache
+  \details Invalidates I-Cache
+  */
+__STATIC_INLINE void SCB_InvalidateICache (void)
+{
+  #if (__ICACHE_PRESENT == 1U)
+    __DSB();
+    __ISB();
+    SCB->ICIALLU = 0UL;
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Enable D-Cache
+  \details Turns on D-Cache
+  */
+__STATIC_INLINE void SCB_EnableDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+                                            /* invalidate D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
+                      ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+    __DSB();
+
+    SCB->CCR |=  (uint32_t)SCB_CCR_DC_Msk;  /* enable D-Cache */
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Disable D-Cache
+  \details Turns off D-Cache
+  */
+__STATIC_INLINE void SCB_DisableDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+    SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk;  /* disable D-Cache */
+
+                                            /* clean & invalidate D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
+                       ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Invalidate D-Cache
+  \details Invalidates D-Cache
+  */
+__STATIC_INLINE void SCB_InvalidateDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+                                            /* invalidate D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
+                      ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Clean D-Cache
+  \details Cleans D-Cache
+  */
+__STATIC_INLINE void SCB_CleanDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+                                            /* clean D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
+                      ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Clean & Invalidate D-Cache
+  \details Cleans and Invalidates D-Cache
+  */
+__STATIC_INLINE void SCB_CleanInvalidateDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+                                            /* clean & invalidate D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
+                       ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   D-Cache Invalidate by address
+  \details Invalidates D-Cache for the given address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1U)
+     int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t)addr;
+     int32_t linesize = 32U;                /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCIMVAC = op_addr;
+      op_addr += linesize;
+      op_size -= linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   D-Cache Clean by address
+  \details Cleans D-Cache for the given address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1)
+     int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t) addr;
+     int32_t linesize = 32U;                /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCCMVAC = op_addr;
+      op_addr += linesize;
+      op_size -= linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   D-Cache Clean and Invalidate by address
+  \details Cleans and invalidates D_Cache for the given address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1U)
+     int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t) addr;
+     int32_t linesize = 32U;                /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCCIMVAC = op_addr;
+      op_addr += linesize;
+      op_size -= linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/*@} end of CMSIS_Core_CacheFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_core_DebugFunctions ITM Functions
+  \brief    Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters. */
+#define                 ITM_RXBUFFER_EMPTY   0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+  \brief   ITM Send Character
+  \details Transmits a character via the ITM channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0U].u32 == 0UL)
+    {
+      __NOP();
+    }
+    ITM->PORT[0U].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Receive Character
+  \details Inputs a character via the external variable \ref ITM_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+  {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Check Character
+  \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+  {
+    return (0);                              /* no character available */
+  }
+  else
+  {
+    return (1);                              /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM7_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmFunc.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmFunc.h
new file mode 100755
index 0000000..652a48a
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmFunc.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file     core_cmFunc.h
+ * @brief    CMSIS Cortex-M Core Function Access Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if   defined ( __CC_ARM )
+  #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+  #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+  #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+  #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+  /*
+   * The CMSIS functions have been implemented as intrinsics in the compiler.
+   * Please use "carm -?i" to get an up to date list of all intrinsics,
+   * Including the CMSIS ones.
+   */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+  #include <cmsis_csm.h>
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+#endif /* __CORE_CMFUNC_H */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmInstr.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmInstr.h
new file mode 100755
index 0000000..f474b0e
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmInstr.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file     core_cmInstr.h
+ * @brief    CMSIS Cortex-M Core Instruction Access Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if   defined ( __CC_ARM )
+  #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+  #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+  #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+  #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+  /*
+   * The CMSIS functions have been implemented as intrinsics in the compiler.
+   * Please use "carm -?i" to get an up to date list of all intrinsics,
+   * Including the CMSIS ones.
+   */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+  #include <cmsis_csm.h>
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmSimd.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmSimd.h
new file mode 100755
index 0000000..66bf5c2
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_cmSimd.h
@@ -0,0 +1,96 @@
+/**************************************************************************//**
+ * @file     core_cmSimd.h
+ * @brief    CMSIS Cortex-M SIMD Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMSIMD_H
+#define __CORE_CMSIMD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if   defined ( __CC_ARM )
+  #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+  #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+  #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+  #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+  /*
+   * The CMSIS functions have been implemented as intrinsics in the compiler.
+   * Please use "carm -?i" to get an up to date list of all intrinsics,
+   * Including the CMSIS ones.
+   */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+  #include <cmsis_csm.h>
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CMSIMD_H */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_sc000.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_sc000.h
new file mode 100755
index 0000000..514dbd8
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_sc000.h
@@ -0,0 +1,926 @@
+/**************************************************************************//**
+ * @file     core_sc000.h
+ * @brief    CMSIS SC000 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_SC000_H_GENERIC
+#define __CORE_SC000_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup SC000
+  @{
+ */
+
+/*  CMSIS SC000 definitions */
+#define __SC000_CMSIS_VERSION_MAIN  (0x04U)                                    /*!< [31:16] CMSIS HAL main version */
+#define __SC000_CMSIS_VERSION_SUB   (0x1EU)                                    /*!< [15:0]  CMSIS HAL sub version */
+#define __SC000_CMSIS_VERSION       ((__SC000_CMSIS_VERSION_MAIN << 16U) | \
+                                      __SC000_CMSIS_VERSION_SUB           )    /*!< CMSIS HAL version number */
+
+#define __CORTEX_SC                 (000U)                                     /*!< Cortex secure core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC000_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_SC000_H_DEPENDANT
+#define __CORE_SC000_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __SC000_REV
+    #define __SC000_REV             0x0000U
+    #warning "__SC000_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group SC000 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core MPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:28;              /*!< bit:  0..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t _reserved1:3;               /*!< bit: 25..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:1;               /*!< bit:      0  Reserved */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[1U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[31U];
+  __IOM uint32_t ICER[1U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[31U];
+  __IOM uint32_t ISPR[1U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[31U];
+  __IOM uint32_t ICPR[1U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[31U];
+        uint32_t RESERVED4[64U];
+  __IOM uint32_t IP[8U];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t SHP[2U];                /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+        uint32_t RESERVED1[154U];
+  __IOM uint32_t SFCR;                   /*!< Offset: 0x290 (R/W)  Security Features Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0U                                         /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   8U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0xFFFFFFUL << MPU_RBAR_ADDR_Pos)              /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+            Therefore they are not covered by the SC000 header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of SC000 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
+#define _SHP_IDX(IRQn)           ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >>    2UL)      )
+#define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      )
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+  else
+  {
+    NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC000_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/JN5189DK6/CMSIS/Include/core_sc300.h b/third_party/nxp/JN5189DK6/CMSIS/Include/core_sc300.h
new file mode 100755
index 0000000..8bd18aa
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/CMSIS/Include/core_sc300.h
@@ -0,0 +1,1745 @@
+/**************************************************************************//**
+ * @file     core_sc300.h
+ * @brief    CMSIS SC300 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_SC300_H_GENERIC
+#define __CORE_SC300_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup SC3000
+  @{
+ */
+
+/*  CMSIS SC300 definitions */
+#define __SC300_CMSIS_VERSION_MAIN  (0x04U)                                    /*!< [31:16] CMSIS HAL main version */
+#define __SC300_CMSIS_VERSION_SUB   (0x1EU)                                    /*!< [15:0]  CMSIS HAL sub version */
+#define __SC300_CMSIS_VERSION       ((__SC300_CMSIS_VERSION_MAIN << 16U) | \
+                                      __SC300_CMSIS_VERSION_SUB           )    /*!< CMSIS HAL version number */
+
+#define __CORTEX_SC                 (300U)                                     /*!< Cortex secure core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC300_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_SC300_H_DEPENDANT
+#define __CORE_SC300_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __SC300_REV
+    #define __SC300_REV               0x0000U
+    #warning "__SC300_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group SC300 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27U                                            /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0) */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27U                                            /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25U                                            /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[24U];
+  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[24U];
+  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[24U];
+  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[24U];
+  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
+        uint32_t RESERVED4[56U];
+  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+        uint32_t RESERVED5[644U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0U                                         /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+  __IOM uint8_t  SHP[12U];               /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
+  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
+  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
+  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
+  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
+  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
+  __IM  uint32_t PFR[2U];                /*!< Offset: 0x040 (R/ )  Processor Feature Register */
+  __IM  uint32_t DFR;                    /*!< Offset: 0x048 (R/ )  Debug Feature Register */
+  __IM  uint32_t ADR;                    /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
+  __IM  uint32_t MMFR[4U];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
+  __IM  uint32_t ISAR[5U];               /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
+        uint32_t RESERVED0[5U];
+  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
+        uint32_t RESERVED1[129U];
+  __IOM uint32_t SFCR;                   /*!< Offset: 0x290 (R/W)  Security Features Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11U                                            /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLBASE_Pos               29U                                            /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk               (1UL << SCB_VTOR_TBLBASE_Pos)                  /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8U                                            /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0U                                            /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8U                                            /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4U                                            /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1U                                            /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0U                                            /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18U                                            /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17U                                            /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16U                                            /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14U                                            /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13U                                            /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12U                                            /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11U                                            /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10U                                            /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8U                                            /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7U                                            /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3U                                            /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1U                                            /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0U                                            /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16U                                            /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8U                                            /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0U                                            /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31U                                            /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30U                                            /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1U                                            /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4U                                            /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3U                                            /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2U                                            /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1U                                            /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0U                                            /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t ICTR;                   /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register */
+        uint32_t RESERVED1[1U];
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0U                                         /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+  \brief    Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __OM  union
+  {
+    __OM  uint8_t    u8;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit */
+    __OM  uint16_t   u16;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit */
+    __OM  uint32_t   u32;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit */
+  }  PORT [32U];                         /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers */
+        uint32_t RESERVED0[864U];
+  __IOM uint32_t TER;                    /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register */
+        uint32_t RESERVED1[15U];
+  __IOM uint32_t TPR;                    /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register */
+        uint32_t RESERVED2[15U];
+  __IOM uint32_t TCR;                    /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register */
+        uint32_t RESERVED3[29U];
+  __OM  uint32_t IWR;                    /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register */
+  __IM  uint32_t IRR;                    /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register */
+  __IOM uint32_t IMCR;                   /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register */
+        uint32_t RESERVED4[43U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register */
+        uint32_t RESERVED5[6U];
+  __IM  uint32_t PID4;                   /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __IM  uint32_t PID5;                   /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __IM  uint32_t PID6;                   /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __IM  uint32_t PID7;                   /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __IM  uint32_t PID0;                   /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __IM  uint32_t PID1;                   /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __IM  uint32_t PID2;                   /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __IM  uint32_t PID3;                   /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __IM  uint32_t CID0;                   /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __IM  uint32_t CID1;                   /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __IM  uint32_t CID2;                   /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __IM  uint32_t CID3;                   /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0U                                            /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23U                                            /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16U                                            /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10U                                            /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8U                                            /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4U                                            /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3U                                            /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2U                                            /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1U                                            /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0U                                            /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0U                                            /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0U                                            /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0U                                            /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2U                                            /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1U                                            /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0U                                            /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+  \brief    Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control Register */
+  __IOM uint32_t CYCCNT;                 /*!< Offset: 0x004 (R/W)  Cycle Count Register */
+  __IOM uint32_t CPICNT;                 /*!< Offset: 0x008 (R/W)  CPI Count Register */
+  __IOM uint32_t EXCCNT;                 /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register */
+  __IOM uint32_t SLEEPCNT;               /*!< Offset: 0x010 (R/W)  Sleep Count Register */
+  __IOM uint32_t LSUCNT;                 /*!< Offset: 0x014 (R/W)  LSU Count Register */
+  __IOM uint32_t FOLDCNT;                /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register */
+  __IM  uint32_t PCSR;                   /*!< Offset: 0x01C (R/ )  Program Counter Sample Register */
+  __IOM uint32_t COMP0;                  /*!< Offset: 0x020 (R/W)  Comparator Register 0 */
+  __IOM uint32_t MASK0;                  /*!< Offset: 0x024 (R/W)  Mask Register 0 */
+  __IOM uint32_t FUNCTION0;              /*!< Offset: 0x028 (R/W)  Function Register 0 */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t COMP1;                  /*!< Offset: 0x030 (R/W)  Comparator Register 1 */
+  __IOM uint32_t MASK1;                  /*!< Offset: 0x034 (R/W)  Mask Register 1 */
+  __IOM uint32_t FUNCTION1;              /*!< Offset: 0x038 (R/W)  Function Register 1 */
+        uint32_t RESERVED1[1U];
+  __IOM uint32_t COMP2;                  /*!< Offset: 0x040 (R/W)  Comparator Register 2 */
+  __IOM uint32_t MASK2;                  /*!< Offset: 0x044 (R/W)  Mask Register 2 */
+  __IOM uint32_t FUNCTION2;              /*!< Offset: 0x048 (R/W)  Function Register 2 */
+        uint32_t RESERVED2[1U];
+  __IOM uint32_t COMP3;                  /*!< Offset: 0x050 (R/W)  Comparator Register 3 */
+  __IOM uint32_t MASK3;                  /*!< Offset: 0x054 (R/W)  Mask Register 3 */
+  __IOM uint32_t FUNCTION3;              /*!< Offset: 0x058 (R/W)  Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28U                                         /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27U                                         /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26U                                         /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25U                                         /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24U                                         /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22U                                         /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21U                                         /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20U                                         /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19U                                         /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18U                                         /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17U                                         /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16U                                         /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12U                                         /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10U                                         /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9U                                         /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5U                                         /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1U                                         /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0U                                         /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0U                                         /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0U                                         /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0U                                         /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0U                                         /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0U                                         /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24U                                         /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16U                                         /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12U                                         /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10U                                         /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9U                                         /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8U                                         /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7U                                         /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5U                                         /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0U                                         /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+  \brief    Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IOM uint32_t SSPSR;                  /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register */
+  __IOM uint32_t CSPSR;                  /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACPR;                   /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+        uint32_t RESERVED1[55U];
+  __IOM uint32_t SPPR;                   /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+        uint32_t RESERVED2[131U];
+  __IM  uint32_t FFSR;                   /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IOM uint32_t FFCR;                   /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __IM  uint32_t FSCR;                   /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+        uint32_t RESERVED3[759U];
+  __IM  uint32_t TRIGGER;                /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __IM  uint32_t FIFO0;                  /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __IM  uint32_t ITATBCTR2;              /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+        uint32_t RESERVED4[1U];
+  __IM  uint32_t ITATBCTR0;              /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __IM  uint32_t FIFO1;                  /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IOM uint32_t ITCTRL;                 /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+        uint32_t RESERVED5[39U];
+  __IOM uint32_t CLAIMSET;               /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IOM uint32_t CLAIMCLR;               /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+        uint32_t RESERVED7[8U];
+  __IM  uint32_t DEVID;                  /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __IM  uint32_t DEVTYPE;                /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0U                                         /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0U                                         /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3U                                         /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2U                                         /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1U                                         /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0U                                         /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8U                                         /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1U                                         /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0U                                         /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16U                                         /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8U                                         /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0U                                         /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16U                                         /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8U                                         /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0U                                         /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0U                                         /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11U                                         /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10U                                         /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9U                                         /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6U                                         /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5U                                         /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0U                                         /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4U                                         /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0U                                         /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A1;                /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register */
+  __IOM uint32_t RASR_A1;                /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A2;                /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register */
+  __IOM uint32_t RASR_A2;                /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A3;                /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register */
+  __IOM uint32_t RASR_A3;                /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Type definitions for the Core Debug Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IOM uint32_t DHCSR;                  /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register */
+  __OM  uint32_t DCRSR;                  /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register */
+  __IOM uint32_t DCRDR;                  /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register */
+  __IOM uint32_t DEMCR;                  /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16U                                            /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25U                                            /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24U                                            /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19U                                            /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18U                                            /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17U                                            /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16U                                            /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5U                                            /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3U                                            /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2U                                            /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1U                                            /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0U                                            /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos         16U                                            /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0U                                            /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19U                                            /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18U                                            /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17U                                            /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16U                                            /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10U                                            /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9U                                            /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8U                                            /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7U                                            /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6U                                            /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5U                                            /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4U                                            /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0U                                            /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/**
+  \brief   Set Priority Grouping
+  \details Sets the priority grouping field using the required unlock sequence.
+           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+           Only values from 0..7 are used.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8U)                      );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/**
+  \brief   Get Priority Grouping
+  \details Reads the priority grouping field from the NVIC Interrupt Controller.
+  \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Active Interrupt
+  \details Reads the active register in NVIC and returns the active bit.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else
+  {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]               >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   Encode Priority
+  \details Encodes the priority for an interrupt with the given priority group,
+           preemptive priority value, and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]     PriorityGroup  Used priority group.
+  \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+  \param [in]       SubPriority  Subpriority value (starting from 0).
+  \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/**
+  \brief   Decode Priority
+  \details Decodes an interrupt priority value with a given priority group to
+           preemptive priority value and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+  \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+  \param [in]     PriorityGroup  Used priority group.
+  \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+  \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_core_DebugFunctions ITM Functions
+  \brief    Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters. */
+#define                 ITM_RXBUFFER_EMPTY   0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+  \brief   ITM Send Character
+  \details Transmits a character via the ITM channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0U].u32 == 0UL)
+    {
+      __NOP();
+    }
+    ITM->PORT[0U].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Receive Character
+  \details Inputs a character via the external variable \ref ITM_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+  {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Check Character
+  \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+  {
+    return (0);                              /* no character available */
+  }
+  else
+  {
+    return (1);                              /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC300_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/board.c b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/board.c
new file mode 100755
index 0000000..7e27ab4
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/board.c
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#include "fsl_debug_console.h"
+#include "fsl_clock.h"
+#include "board.h"
+
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+#if (defined TCXO_32M_MODE_EN) && (TCXO_32M_MODE_EN != 0)
+/* Table of load capacitance versus temperature for 32MHz crystal. Values below
+   are for NDK NX2016SA 32MHz EXS00A-CS11213-6(IEC). Values are for temperatures
+   from -40 to +130 in steps of 5 */
+int32_t CLOCK_ai32MXtalIecLoadPfVsTemp_x1000[HW_32M_LOAD_VS_TEMP_SIZE] =
+    {  960,  1097,  1194,  1246,  1253,  1216,  1137,  1023, /* -40, -35, ... -5 */
+       879,   710,   523,   325,   122,   -81,  -277,  -464, /* 0, 5, ... 35 */
+      -637,  -794,  -933, -1052, -1150, -1227, -1283, -1317, /* 40, 45, ... 75 */
+     -1328, -1315, -1274, -1202, -1090,  -930,  -709,  -409, /* 80, 85, ... 115 */
+        -9,   518,  1205};                                   /* 120, 125, 130 */
+#endif
+
+#if (defined TCXO_32k_MODE_EN) && (TCXO_32k_MODE_EN != 0)
+/* Table of load capacitance versus temperature for 32kHz crystal. Values are
+   for temperatures from -20 to +100 in steps of 20. *Note* values below are
+   just for example */
+int32_t CLOCK_ai32kXtalIecLoadPfVsTemp_x1000[HW_32k_LOAD_VS_TEMP_SIZE] =
+    {  960,  /* -20 */
+      1097,  /*   0 */
+      1194,  /*  20 */
+      1246,  /*  40 */
+      1253,  /*  60 */
+      1216,  /*  80 */
+      1137}; /* 100 */
+#endif
+
+/*******************************************************************************
+* Local Prototypes
+******************************************************************************/
+
+/*****************************************************************************
+* Local functions
+****************************************************************************/
+
+/*****************************************************************************
+ * Public functions
+ ****************************************************************************/
+
+/* Initialize debug console. */
+status_t BOARD_InitDebugConsole(void)
+{
+    status_t result;
+
+    uint32_t uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ;
+
+    result = DbgConsole_Init(BOARD_DEBUG_UART_BASEADDR, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
+
+#ifndef RTL_SIMU_ON_ES2
+    CLOCK_uDelay(500);
+#endif
+
+    return result;
+}
+
+
diff --git a/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/board.h b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/board.h
new file mode 100755
index 0000000..786cc88
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/board.h
@@ -0,0 +1,206 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#include "fsl_device_registers.h"
+#include "fsl_common.h"
+#include "clock_config.h"
+#include "fsl_clock.h"
+#include "fsl_power.h"
+#include "fsl_gpio.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*! @brief The board name */
+#define BOARD_NAME "DK6"
+
+/* The UART to use for debug messages. */
+#define BOARD_DEBUG_UART_TYPE       DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM
+#define BOARD_DEBUG_UART_BAUDRATE   115200U
+#define BOARD_DEBUG_UART_BASEADDR   (uint32_t) USART0
+#define BOARD_DEBUG_UART_CLK_FREQ   CLOCK_GetFreq(kCLOCK_Fro32M)
+#define BOARD_UART_IRQ              LPUART0_IRQn
+#define BOARD_UART_IRQ_HANDLER      LPUART0_IRQHandler
+#define BOARD_DEBUG_UART_CLK_ATTACH kOSC32M_to_USART_CLK
+
+/* There are 2 red LEDs on DK6 board: PIO0 and PIO3 */
+#define BOARD_LED_RED_GPIO        GPIO
+#define BOARD_LED_RED_GPIO_PORT   0U
+#define BOARD_LED_RED_GPIO_PIN    0U
+#define BOARD_LED_GREEN_GPIO      GPIO
+#define BOARD_LED_GREEN_GPIO_PORT 0U
+#define BOARD_LED_GREEN_GPIO_PIN  5U
+#define BOARD_LED_BLUE_GPIO       GPIO
+#define BOARD_LED_BLUE_GPIO_PORT  0U
+#define BOARD_LED_BLUE_GPIO_PIN   3U
+
+/* Board led color mapping */
+#define LOGIC_LED_ON  0U
+#define LOGIC_LED_OFF 1U
+
+#define LED_RED_INIT(output)                                                          \
+    GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, BOARD_LED_RED_GPIO_PIN, \
+                 &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_RED */
+#define LED_RED_ON()                                                  \
+    GPIO_ClearPinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
+                         1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn on target LED_RED */
+#define LED_RED_OFF()                                               \
+    GPIO_SetPinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
+                       1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn off target LED_RED */
+#define LED_RED_TOGGLE()                                               \
+    GPIO_TogglePinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
+                          1U << BOARD_LED_RED_GPIO_PIN) /*!< Toggle on target LED_RED */
+
+#define LED_GREEN_INIT(output)                                                              \
+    GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, BOARD_LED_GREEN_GPIO_PIN, \
+                 &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_GREEN */
+#define LED_GREEN_ON()                                                    \
+    GPIO_ClearPinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
+                         1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn on target LED_GREEN */
+#define LED_GREEN_OFF()                                                 \
+    GPIO_SetPinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
+                       1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn off target LED_GREEN */
+#define LED_GREEN_TOGGLE()                                                 \
+    GPIO_TogglePinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
+                          1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Toggle on target LED_GREEN */
+
+#define LED_BLUE_INIT(output)                                                            \
+    GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, BOARD_LED_BLUE_GPIO_PIN, \
+                 &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_BLUE */
+#define LED_BLUE_ON()                                                   \
+    GPIO_ClearPinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
+                         1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn on target LED_BLUE */
+#define LED_BLUE_OFF()                                                \
+    GPIO_SetPinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
+                       1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn off target LED_BLUE */
+#define LED_BLUE_TOGGLE()                                                \
+    GPIO_TogglePinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
+                          1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Toggle on target LED_BLUE */
+
+/* There are 2 red LEDs on USB Dongle: PIO4 and PIO10 */
+#define BOARD_LED_USB_DONGLE_GPIO GPIO
+#define BOARD_LED_USB_DONGLE_GPIO_PORT 0U
+#define BOARD_LED_USB_DONGLE1_GPIO_PIN 4U
+#define BOARD_LED_USB_DONGLE2_GPIO_PIN 10U
+
+#define BOARD_SW1_GPIO GPIO
+#define BOARD_SW1_GPIO_PORT 0U
+#define BOARD_SW1_GPIO_PIN  1U
+#define BOARD_SW1_NAME "SW1"
+#define BOARD_SW3_IRQ PIN_INT0_IRQn
+#define BOARD_SW3_IRQ_HANDLER PIN_INT0_IRQHandler
+
+#define BOARD_SW2_GPIO GPIO
+#define BOARD_SW2_GPIO_PORT 0U
+#define BOARD_SW2_GPIO_PIN  5U
+#define BOARD_SW2_NAME "SW2"
+#define BOARD_SW3_IRQ PIN_INT0_IRQn
+#define BOARD_SW3_IRQ_HANDLER PIN_INT0_IRQHandler
+
+/* Capacitance values for 32MHz and 32kHz crystals; board-specific. Value is
+   pF x 100. For example, 6pF becomes 600, 1.2pF becomes 120 */
+#define CLOCK_32MfXtalIecLoadpF_x100    (600) /* 6.0pF */
+#define CLOCK_32MfXtalPPcbParCappF_x100 (20)  /* 0.2pF */
+#define CLOCK_32MfXtalNPcbParCappF_x100 (40)  /* 0.4pF */
+#define CLOCK_32kfXtalIecLoadpF_x100    (600) /* 6.0pF */
+#define CLOCK_32kfXtalPPcbParCappF_x100 (40)  /* 0.4pF */
+#define CLOCK_32kfXtalNPcbParCappF_x100 (40)  /* 0.4pF */
+
+/* Capacitance variation for 32MHz crystal across temperature
+   ----------------------------------------------------------
+
+   TCXO_32M_MODE_EN should be 1 to indicate that temperature-compensated 32MHz
+   XO is supported and required. If so, HW_32M_LOAD_VS_TEMP_MIN,
+   _MAX, _STEP must be defined here and CLOCK_ai32MXtalIecLoadPfVsTemp_x1000
+   must be defined in board.c.
+
+   Values are used as follows:
+   CLOCK_ai32MXtalIecLoadPfVsTemp_x1000 is an array of crystal load capacitance
+   values across temp, with each value being at a specific temp. First value is
+   for temp given by HW_32M_LOAD_VS_TEMP_MIN, next value is for
+   temp given by HW_32M_LOAD_VS_TEMP_MIN + _STEP, next value is
+   for temp given by HW_32M_LOAD_VS_TEMP_MIN + _ STEP x 2, etc.
+   Final value is for temp given by HW_32M_LOAD_VS_TEMP_MAX. It is
+   important for HW_32M_LOAD_VS_TEMP_x defines and the table to be
+   matched to one another */
+#define TCXO_32M_MODE_EN                     (1)
+
+/* Values below are for NDK NX2016SA 32MHz EXS00A-CS11213-6(IEC) */
+
+/* Temperature related to element 0 of CLOCK_ai32MXtalIecLoadPfVsTemp_x1000 */
+#define HW_32M_LOAD_VS_TEMP_MIN  (-40)
+
+/* Temperature related to final element of CLOCK_ai32MXtalIecLoadPfVsTemp_x1000 */
+#define HW_32M_LOAD_VS_TEMP_MAX  (130)
+
+/* Temperature step between elements of CLOCK_ai32MXtalIecLoadPfVsTemp_x1000 */
+#define HW_32M_LOAD_VS_TEMP_STEP (5)
+
+#define HW_32M_LOAD_VS_TEMP_SIZE ((HW_32M_LOAD_VS_TEMP_MAX \
+                                   - HW_32M_LOAD_VS_TEMP_MIN) \
+                                  / HW_32M_LOAD_VS_TEMP_STEP + 1U)
+
+/* Table of load capacitance versus temperature for 32MHz crystal. Values are
+   for temperatures from -40 to +130 in steps of 5 */
+extern int32_t CLOCK_ai32MXtalIecLoadPfVsTemp_x1000[HW_32M_LOAD_VS_TEMP_SIZE];
+
+/* Capacitance variation for 32kHz crystal across temperature
+   ----------------------------------------------------------
+
+   TCXO_32k_MODE_EN should be 1 to indicate that temperature-compensated 32kHz
+   XO is supported and required. If so, HW_32k_LOAD_VS_TEMP_MIN,
+   _MAX, _STEP must be defined here and CLOCK_ai32kXtalIecLoadPfVsTemp_x1000
+   must be defined in board.c.
+
+   Values are used as follows:
+   CLOCK_ai32kXtalIecLoadPfVsTemp_x1000 is an array of crystal load capacitance
+   values across temp, with each value being at a specific temp. First value is
+   for temp given by HW_32k_LOAD_VS_TEMP_MIN, next value is for
+   temp given by HW_32k_LOAD_VS_TEMP_MIN + _STEP, next value is
+   for temp given by HW_32k_LOAD_VS_TEMP_MIN + _ STEP x 2, etc.
+   Final value is for temp given by HW_32k_LOAD_VS_TEMP_MAX. It is
+   important for HW_32k_LOAD_VS_TEMP_x defines and the table to be
+   matched to one another */
+#define TCXO_32k_MODE_EN                     (0) /* Disabled because table is
+                                                    *not* correct: values below
+                                                    are just for example */
+
+/* Temperature related to element 0 of CLOCK_ai32kXtalIecLoadPfVsTemp_x1000 */
+#define HW_32k_LOAD_VS_TEMP_MIN  (-20)
+
+/* Temperature related to final element of CLOCK_ai32kXtalIecLoadPfVsTemp_x1000 */
+#define HW_32k_LOAD_VS_TEMP_MAX  (100)
+
+/* Temperature step between elements of CLOCK_ai32kXtalIecLoadPfVsTemp_x1000 */
+#define HW_32k_LOAD_VS_TEMP_STEP (20)
+
+#define HW_32k_LOAD_VS_TEMP_SIZE ((HW_32k_LOAD_VS_TEMP_MAX \
+                                   - HW_32k_LOAD_VS_TEMP_MIN) \
+                                  / HW_32k_LOAD_VS_TEMP_STEP + 1U)
+
+/* Table of load capacitance versus temperature for 32kHz crystal. Values are
+   for temperatures from -20 to +100 in steps of 20 */
+extern int32_t CLOCK_ai32kXtalIecLoadPfVsTemp_x1000[HW_32k_LOAD_VS_TEMP_SIZE];
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+status_t BOARD_InitDebugConsole(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+#endif /* _BOARD_H_ */
diff --git a/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/clock_config.c b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/clock_config.c
new file mode 100755
index 0000000..1a4ca32
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/clock_config.c
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#include "fsl_common.h"
+#include "clock_config.h"
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/* System clock frequency. */
+extern uint32_t SystemCoreClock;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+void BOARD_BootClockVLPR(void)
+{
+}
+
+void BOARD_BootClockRUN(void)
+{
+    /* Set PMC FRO selection */
+    CLOCK_EnableClock(kCLOCK_Fro32M);
+    CLOCK_EnableClock(kCLOCK_Fro48M);
+    CLOCK_EnableClock(kCLOCK_Gpio0);
+    CLOCK_EnableClock(kCLOCK_Rtc);
+
+    /* INMUX and IOCON are used by many apps, enable both INMUX and IOCON clock bits here. */
+    CLOCK_AttachClk(kOSC32M_to_FRG_CLK);
+    CLOCK_AttachClk(kMAIN_CLK_to_DMI_CLK);
+
+    CLOCK_EnableAPBBridge();
+    SYSCON->DMICCLKDIV=0;
+    CLOCK_SetClkDiv(kCLOCK_DivClkout, 1, false);
+
+    CLOCK_EnableClock(kCLOCK_Xtal32M);
+    CLOCK_EnableClock(kCLOCK_Xtal32k);
+    CLOCK_AttachClk(kXTAL32K_to_OSC32K_CLK);
+
+    /* Enable 48MHz CPU freq */
+    CLOCK_AttachClk(kFRO48M_to_MAIN_CLK);
+    /* Enable 32MHZ XTAL to Ctimer */
+    CLOCK_AttachClk(kXTAL32M_to_ASYNC_APB);
+
+    /* WWDT clock config (32k oscillator, no division) */
+    CLOCK_AttachClk(kOSC32K_to_WDT_CLK);
+    CLOCK_SetClkDiv(kCLOCK_DivWdtClk, 1, true);
+
+    /* enable the clocks for the cryto blocks */
+    CLOCK_EnableClock(kCLOCK_Aes);
+
+    SystemCoreClockUpdate();
+}
+
+void BOARD_BootClockHSRUN(void)
+{
+}
diff --git a/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/clock_config.h b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/clock_config.h
new file mode 100755
index 0000000..54630dc
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/clock_config.h
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _CLOCK_CONFIG_H_
+#define _CLOCK_CONFIG_H_
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus*/
+
+void BOARD_BootClockVLPR(void);
+void BOARD_BootClockRUN(void);
+void BOARD_BootClockHSRUN(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus*/
+
+#endif /* _CLOCK_CONFIG_H_ */
diff --git a/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/pin_mux.c b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/pin_mux.c
new file mode 100755
index 0000000..f1facfa
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/pin_mux.c
@@ -0,0 +1,139 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#include "fsl_common.h"
+#include "fsl_iocon.h"
+#include "fsl_gpio.h"
+#include "pin_mux.h"
+
+/*****************************************************************************
+ * Private types/enumerations/variables
+ ****************************************************************************/
+
+#ifndef BOARD_USECLKINSRC
+#define BOARD_USECLKINSRC (0)
+#endif
+
+/*****************************************************************************
+ * Public types/enumerations/variables
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Prototypes
+ ****************************************************************************/
+/*****************************************************************************
+* Private functions
+****************************************************************************/
+static void ConfigureConsolePort(void)
+{
+    /* UART0 RX/TX pins */
+    IOCON_PinMuxSet(IOCON, 0, 8, IOCON_MODE_INACT | IOCON_FUNC2 | IOCON_DIGITAL_EN);
+    IOCON_PinMuxSet(IOCON, 0, 9, IOCON_MODE_INACT | IOCON_FUNC2 | IOCON_DIGITAL_EN);
+}
+
+static void ConfigureDebugPort(void)
+{
+    /* SWD SWCLK/SWDIO pins */
+    IOCON_PinMuxSet(IOCON, 0, 12, IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN);
+    IOCON_PinMuxSet(IOCON, 0, 13, IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN);
+#ifdef ENABLE_DEBUG_PORT_SWO
+    /* SWD SWO pin (optional) */
+    IOCON_PinMuxSet(IOCON, 0, 14, IOCON_FUNC5 | IOCON_MODE_INACT | IOCON_DIGITAL_EN);
+    SYSCON->TRACECLKDIV = 0; /* Clear HALT bit */
+#endif
+}
+
+static void ConfigureDongleLEDs(void)
+{
+    const uint32_t port0_pin4_config = (/* Pin is configured as PIO0_4 */
+                                        IOCON_PIO_FUNC0 |
+                                        /* Selects pull-up function */
+                                        IOCON_PIO_MODE_PULLUP |
+                                        /* Standard mode, output slew rate control is disabled */
+                                        IOCON_PIO_SLEW0_STANDARD |
+                                        /* Input function is not inverted */
+                                        IOCON_PIO_INV_DI |
+                                        /* Enables digital function */
+                                        IOCON_PIO_DIGITAL_EN |
+                                        /* Input filter disabled */
+                                        IOCON_PIO_INPFILT_OFF |
+                                        /* Standard mode, output slew rate control is disabled */
+                                        IOCON_PIO_SLEW1_STANDARD |
+                                        /* Open drain is disabled */
+                                        IOCON_PIO_OPENDRAIN_DI |
+                                        /* SSEL is disabled */
+                                        IOCON_PIO_SSEL_DI);
+    /* PORT0 PIN4 (coords: 7) is configured as PIO0_4 */
+    IOCON_PinMuxSet(IOCON, 0U, 4U, port0_pin4_config);
+
+    const uint32_t port0_pin10_config = (/* Pin is configured as PIO0_10 */
+                                         IOCON_PIO_FUNC0 |
+                                         /* GPIO mode */
+                                         IOCON_PIO_EGP_GPIO |
+                                         /* IO is an open drain cell */
+                                         IOCON_PIO_ECS_DI |
+                                         /* High speed IO for GPIO mode, IIC not */
+                                         IOCON_PIO_EHS_DI |
+                                         /* Input function is not inverted */
+                                         IOCON_PIO_INV_DI |
+                                         /* Enables digital function */
+                                         IOCON_PIO_DIGITAL_EN |
+                                         /* Input filter disabled */
+                                         IOCON_PIO_INPFILT_OFF |
+                                         /* IIC mode:Noise pulses below approximately 50ns are filtered out. GPIO mode:a 3ns filter */
+                                         IOCON_PIO_FSEL_DI |
+                                         /* Open drain is disabled */
+                                         IOCON_PIO_OPENDRAIN_DI |
+                                         /* IO_CLAMP disabled */
+                                         IOCON_PIO_IO_CLAMP_DI);
+    /* PORT0 PIN10 (coords: 13) is configured as PIO0_10 */
+    IOCON_PinMuxSet(IOCON, 0U, 10U, port0_pin10_config);
+}
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+void BOARD_InitPins(void)
+{
+    /* Define the init structure for the output LED pin*/
+    gpio_pin_config_t led_config = {
+        kGPIO_DigitalOutput,
+        0,
+    };
+
+    /* Enable IOCON clock */
+    CLOCK_EnableClock(kCLOCK_Iocon);
+    CLOCK_EnableClock(kCLOCK_InputMux);
+
+    /* Console signals */
+    ConfigureConsolePort();
+
+    /* Debugger signals */
+    ConfigureDebugPort();
+
+    ConfigureDongleLEDs();
+
+    /* IOCON clock left on, this is needed if CLKIN is used. */
+    /* Initialize GPIO */
+    CLOCK_EnableClock(kCLOCK_Gpio0);
+    RESET_PeripheralReset(kGPIO0_RST_SHIFT_RSTn);
+
+    /* Init output LED GPIO. */
+    GPIO_PortInit(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT);
+    GPIO_PinInit(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, BOARD_LED_USB_DONGLE1_GPIO_PIN, &led_config);
+    GPIO_PinInit(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, BOARD_LED_USB_DONGLE2_GPIO_PIN, &led_config);
+
+    GPIO_PortToggle(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, 1u << BOARD_LED_USB_DONGLE1_GPIO_PIN);
+}
+
+
+void BOARD_LedDongleToggle(void)
+{
+    GPIO_PortToggle(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, 1u << BOARD_LED_USB_DONGLE1_GPIO_PIN);
+    GPIO_PortToggle(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, 1u << BOARD_LED_USB_DONGLE2_GPIO_PIN);
+}
diff --git a/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/pin_mux.h b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/pin_mux.h
new file mode 100755
index 0000000..307ed13
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/boards/jn5189dk6/wireless_examples/openthread/enablement/pin_mux.h
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _PIN_MUX_H_
+#define _PIN_MUX_H_
+
+#include "board.h"
+#include "fsl_common.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus*/
+       /*!
+        * @brief configure all pins for this demo/example
+        *
+        */
+
+#define IOCON_PIO_DIGITAL_EN 0x80u     /*!<@brief Enables digital function */
+#define IOCON_PIO_ECS_DI 0x00u         /*!<@brief IO is an open drain cell */
+#define IOCON_PIO_EGP_GPIO 0x08u       /*!<@brief GPIO mode */
+#define IOCON_PIO_EHS_DI 0x00u         /*!<@brief High speed IO for GPIO mode, IIC not */
+#define IOCON_PIO_FSEL_DI 0x00u        /*!<@brief IIC mode:Noise pulses below approximately 50ns are filtered out. GPIO mode:a 3ns filter */
+#define IOCON_PIO_FUNC0 0x00u          /*!<@brief Selects pin function 2 */
+#define IOCON_PIO_FUNC2 0x02u          /*!<@brief Selects pin function 2 */
+#define IOCON_PIO_INPFILT_OFF 0x0100u  /*!<@brief Input filter disabled */
+#define IOCON_PIO_INV_DI 0x00u         /*!<@brief Input function is not inverted */
+#define IOCON_PIO_MODE_PULLUP 0x00u    /*!<@brief Selects pull-up function */
+#define IOCON_PIO_OPENDRAIN_DI 0x00u   /*!<@brief Open drain is disabled */
+#define IOCON_PIO_SLEW0_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is disabled */
+#define IOCON_PIO_SLEW1_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is disabled */
+#define IOCON_PIO_SSEL_DI 0x00u        /*!<@brief SSEL is disabled */
+#define IOCON_PIO_IO_CLAMP_DI 0x00u    /*!<@brief IO_CLAMP disabled */
+
+void BOARD_InitPins(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus*/
+
+#endif /* _PIN_MUX_H_  */
diff --git a/third_party/nxp/JN5189DK6/components/serial_manager/serial_manager.c b/third_party/nxp/JN5189DK6/components/serial_manager/serial_manager.c
new file mode 100755
index 0000000..42dc0a4
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/components/serial_manager/serial_manager.c
@@ -0,0 +1,1326 @@
+/*
+ * Copyright 2018-2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include <string.h>
+
+#include "serial_manager.h"
+#include "serial_port_internal.h"
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#include "generic_list.h"
+
+/*
+ * The OSA_USED macro can only be defined when the OSA component is used.
+ * If the source code of the OSA component does not exist, the OSA_USED cannot be defined.
+ * OR, If OSA component is not added into project event the OSA source code exists, the OSA_USED
+ * also cannot be defined.
+ * The source code path of the OSA component is <MCUXpresso_SDK>/components/osa.
+ *
+ */
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#include "common_task.h"
+#else
+#include "fsl_os_abstraction.h"
+#endif
+
+#endif
+
+#endif
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+#ifndef NDEBUG
+#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
+#undef assert
+#define assert(n)
+#endif
+#endif
+
+#define SERIAL_EVENT_DATA_RECEIVED (1U << 0)
+#define SERIAL_EVENT_DATA_SENT (1U << 1)
+
+#define SERIAL_MANAGER_WRITE_TAG 0xAABB5754U
+#define SERIAL_MANAGER_READ_TAG 0xBBAA5244U
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+typedef enum _serial_manager_transmission_mode
+{
+    kSerialManager_TransmissionBlocking    = 0x0U, /*!< Blocking transmission*/
+    kSerialManager_TransmissionNonBlocking = 0x1U, /*!< None blocking transmission*/
+} serial_manager_transmission_mode_t;
+
+/* TX transfer structure */
+typedef struct _serial_manager_transfer
+{
+    uint8_t *buffer;
+    volatile uint32_t length;
+    volatile uint32_t soFar;
+    serial_manager_transmission_mode_t mode;
+    serial_manager_status_t status;
+} serial_manager_transfer_t;
+#endif
+
+/* write handle structure */
+typedef struct _serial_manager_send_handle
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    list_element_t link; /*!< list element of the link */
+    serial_manager_transfer_t transfer;
+#endif
+    struct _serial_manager_handle *serialManagerHandle;
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serial_manager_callback_t callback;
+    void *callbackParam;
+    uint32_t tag;
+#endif
+} serial_manager_write_handle_t;
+
+typedef serial_manager_write_handle_t serial_manager_read_handle_t;
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+/* receive state structure */
+typedef struct _serial_manager_read_ring_buffer
+{
+    uint8_t *ringBuffer;
+    uint32_t ringBufferSize;
+    volatile uint32_t ringHead;
+    volatile uint32_t ringTail;
+} serial_manager_read_ring_buffer_t;
+#endif
+
+#if defined(__CC_ARM)
+#pragma anon_unions
+#endif
+/* The serial manager handle structure */
+typedef struct _serial_manager_handle
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    list_label_t runningWriteHandleHead;   /*!< The queue of running write handle */
+    list_label_t completedWriteHandleHead; /*!< The queue of completed write handle */
+#endif
+    serial_manager_read_handle_t *volatile openedReadHandleHead;
+    volatile uint32_t openedWriteHandleCount;
+    union
+    {
+        uint8_t lowLevelhandleBuffer[1];
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        uint8_t uartHandleBuffer[SERIAL_PORT_UART_HANDLE_SIZE];
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        uint8_t usbcdcHandleBuffer[SERIAL_PORT_USB_CDC_HANDLE_SIZE];
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        uint8_t swoHandleBuffer[SERIAL_PORT_SWO_HANDLE_SIZE];
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        uint8_t usbcdcVirtualHandleBuffer[SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE];
+#endif
+    };
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serial_manager_read_ring_buffer_t ringBuffer;
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+    common_task_message_t commontaskMsg;
+#else
+    uint8_t event[OSA_EVENT_HANDLE_SIZE]; /*!< Event instance */
+    uint8_t taskId[OSA_TASK_HANDLE_SIZE]; /*!< Task handle */
+#endif
+
+#endif
+
+#endif
+
+    serial_port_type_t type;
+} serial_manager_handle_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+static void SerialManager_Task(void *param);
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+
+#else
+                                          /*
+                                           * \brief Defines the serial manager task's stack
+                                           */
+OSA_TASK_DEFINE(SerialManager_Task, SERIAL_MANAGER_TASK_PRIORITY, 1, SERIAL_MANAGER_TASK_STACK_SIZE, false);
+#endif
+
+#endif
+
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+static void SerialManager_AddTail(list_label_t *queue, serial_manager_write_handle_t *node)
+{
+    (void)LIST_AddTail(queue, &node->link);
+}
+
+static void SerialManager_RemoveHead(list_label_t *queue)
+{
+    (void)LIST_RemoveHead(queue);
+}
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+static serial_manager_status_t SerialManager_StartWriting(serial_manager_handle_t *handle)
+{
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+    serial_manager_write_handle_t *writeHandle =
+        (serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->runningWriteHandleHead);
+
+    if (writeHandle != NULL)
+    {
+        switch (handle->type)
+        {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+            case kSerialPort_Uart:
+                status = Serial_UartWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                          writeHandle->transfer.buffer, writeHandle->transfer.length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+            case kSerialPort_UsbCdc:
+                status = Serial_UsbCdcWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                            writeHandle->transfer.buffer, writeHandle->transfer.length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+            case kSerialPort_Swo:
+                status = Serial_SwoWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                         writeHandle->transfer.buffer, writeHandle->transfer.length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+            case kSerialPort_UsbCdcVirtual:
+                status = Serial_UsbCdcVirtualWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                   writeHandle->transfer.buffer, writeHandle->transfer.length);
+                break;
+#endif
+            default:
+                status = kStatus_SerialManager_Error;
+                break;
+        }
+    }
+    return status;
+}
+
+static serial_manager_status_t SerialManager_StartReading(serial_manager_handle_t *handle,
+                                                          serial_manager_read_handle_t *readHandle,
+                                                          uint8_t *buffer,
+                                                          uint32_t length)
+{
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+
+    if (readHandle != NULL)
+    {
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        if (handle->type == kSerialPort_UsbCdc)
+        {
+            status = Serial_UsbCdcRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+        }
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        if (handle->type == kSerialPort_UsbCdcVirtual)
+        {
+            status = Serial_UsbCdcVirtualRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+        }
+#endif
+    }
+    return status;
+}
+
+#else
+
+static serial_manager_status_t SerialManager_StartWriting(serial_manager_handle_t *handle,
+                                                          serial_manager_write_handle_t *writeHandle,
+                                                          uint8_t *buffer,
+                                                          uint32_t length)
+{
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+
+    if (writeHandle != NULL)
+    {
+        switch (handle->type)
+        {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+            case kSerialPort_Uart:
+                status = Serial_UartWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+            case kSerialPort_UsbCdc:
+                status = Serial_UsbCdcWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+            case kSerialPort_Swo:
+                status = Serial_SwoWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+            case kSerialPort_UsbCdcVirtual:
+                status = Serial_UsbCdcVirtualWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+            default:
+                status = kStatus_SerialManager_Error;
+                break;
+        }
+    }
+    return status;
+}
+
+static serial_manager_status_t SerialManager_StartReading(serial_manager_handle_t *handle,
+                                                          serial_manager_read_handle_t *readHandle,
+                                                          uint8_t *buffer,
+                                                          uint32_t length)
+{
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+
+    if (readHandle != NULL)
+    {
+        switch (handle->type)
+        {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+            case kSerialPort_Uart:
+                status = Serial_UartRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+            case kSerialPort_UsbCdc:
+                status = Serial_UsbCdcRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+            case kSerialPort_Swo:
+                status = Serial_SwoRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+            case kSerialPort_UsbCdcVirtual:
+                status = Serial_UsbCdcVirtualRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+            default:
+                status = kStatus_SerialManager_Error;
+                break;
+        }
+    }
+    return status;
+}
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+static void SerialManager_IsrFunction(serial_manager_handle_t *handle)
+{
+    uint32_t regPrimask = DisableGlobalIRQ();
+    switch (handle->type)
+    {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        case kSerialPort_Uart:
+            Serial_UartIsrFunction(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        case kSerialPort_UsbCdc:
+            Serial_UsbCdcIsrFunction(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        case kSerialPort_Swo:
+            Serial_SwoIsrFunction(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        case kSerialPort_UsbCdcVirtual:
+            Serial_UsbCdcVirtualIsrFunction(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+        default:
+            /*MISRA rule 16.4*/
+            break;
+    }
+    EnableGlobalIRQ(regPrimask);
+}
+
+static void SerialManager_Task(void *param)
+{
+    serial_manager_handle_t *handle = (serial_manager_handle_t *)param;
+    serial_manager_write_handle_t *serialWriteHandle;
+    serial_manager_read_handle_t *serialReadHandle;
+    uint32_t primask;
+    serial_manager_callback_message_t msg;
+
+    if (NULL != handle)
+    {
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#else
+        osa_event_flags_t ev = 0;
+
+        do
+        {
+            if (KOSA_StatusSuccess ==
+                OSA_EventWait((osa_event_handle_t)handle->event, osaEventFlagsAll_c, false, osaWaitForever_c, &ev))
+            {
+                if (ev & SERIAL_EVENT_DATA_SENT)
+#endif
+
+#endif
+        {
+            serialWriteHandle =
+                (serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->completedWriteHandleHead);
+            while (NULL != serialWriteHandle)
+            {
+                SerialManager_RemoveHead(&handle->completedWriteHandleHead);
+                msg.buffer                         = serialWriteHandle->transfer.buffer;
+                msg.length                         = serialWriteHandle->transfer.soFar;
+                serialWriteHandle->transfer.buffer = NULL;
+                if (serialWriteHandle->callback != NULL)
+                {
+                    serialWriteHandle->callback(serialWriteHandle->callbackParam, &msg,
+                                                serialWriteHandle->transfer.status);
+                }
+                serialWriteHandle =
+                    (serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->completedWriteHandleHead);
+            }
+        }
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#else
+                if (ev & SERIAL_EVENT_DATA_RECEIVED)
+#endif
+
+#endif
+        {
+            primask          = DisableGlobalIRQ();
+            serialReadHandle = handle->openedReadHandleHead;
+            EnableGlobalIRQ(primask);
+
+            if (serialReadHandle != NULL)
+            {
+                if (serialReadHandle->transfer.buffer != NULL)
+                {
+                    if (serialReadHandle->transfer.soFar >= serialReadHandle->transfer.length)
+                    {
+                        msg.buffer                        = serialReadHandle->transfer.buffer;
+                        msg.length                        = serialReadHandle->transfer.soFar;
+                        serialReadHandle->transfer.buffer = NULL;
+                        if (serialReadHandle->callback != NULL)
+                        {
+                            serialReadHandle->callback(serialReadHandle->callbackParam, &msg,
+                                                       serialReadHandle->transfer.status);
+                        }
+                    }
+                }
+            }
+        }
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#else
+            }
+        } while (gUseRtos_c);
+#endif
+
+#endif
+    }
+}
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+static void SerialManager_TxCallback(void *callbackParam,
+                                     serial_manager_callback_message_t *message,
+                                     serial_manager_status_t status)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_write_handle_t *writeHandle;
+
+    assert(callbackParam);
+    assert(message);
+
+    handle = (serial_manager_handle_t *)callbackParam;
+
+    writeHandle = (serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->runningWriteHandleHead);
+
+    if (NULL != writeHandle)
+    {
+        SerialManager_RemoveHead(&handle->runningWriteHandleHead);
+        (void)SerialManager_StartWriting(handle);
+        writeHandle->transfer.soFar  = message->length;
+        writeHandle->transfer.status = status;
+        if (kSerialManager_TransmissionNonBlocking == writeHandle->transfer.mode)
+        {
+            SerialManager_AddTail(&handle->completedWriteHandleHead, writeHandle);
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+            handle->commontaskMsg.callback      = SerialManager_Task;
+            handle->commontaskMsg.callbackParam = handle;
+            COMMON_TASK_post_message(&handle->commontaskMsg);
+#else
+            (void)OSA_EventSet((osa_event_handle_t)handle->event, SERIAL_EVENT_DATA_SENT);
+#endif
+
+#else
+            SerialManager_Task(handle);
+#endif
+        }
+        else
+        {
+            writeHandle->transfer.buffer = NULL;
+        }
+    }
+}
+
+static void SerialManager_RxCallback(void *callbackParam,
+                                     serial_manager_callback_message_t *message,
+                                     serial_manager_status_t status)
+{
+    serial_manager_handle_t *handle;
+    uint32_t ringBufferLength;
+    uint32_t primask;
+
+    assert(callbackParam);
+    assert(message);
+
+    handle = (serial_manager_handle_t *)callbackParam;
+
+    status = kStatus_SerialManager_Notify;
+
+    for (uint32_t i = 0; i < message->length; i++)
+    {
+        handle->ringBuffer.ringBuffer[handle->ringBuffer.ringHead++] = message->buffer[i];
+        if (handle->ringBuffer.ringHead >= handle->ringBuffer.ringBufferSize)
+        {
+            handle->ringBuffer.ringHead = 0U;
+        }
+        if (handle->ringBuffer.ringHead == handle->ringBuffer.ringTail)
+        {
+            status = kStatus_SerialManager_RingBufferOverflow;
+            handle->ringBuffer.ringTail++;
+            if (handle->ringBuffer.ringTail >= handle->ringBuffer.ringBufferSize)
+            {
+                handle->ringBuffer.ringTail = 0U;
+            }
+        }
+    }
+
+    ringBufferLength = handle->ringBuffer.ringHead + handle->ringBuffer.ringBufferSize - handle->ringBuffer.ringTail;
+    ringBufferLength = ringBufferLength % handle->ringBuffer.ringBufferSize;
+
+    primask = DisableGlobalIRQ();
+    if ((handle->openedReadHandleHead != NULL) && (handle->openedReadHandleHead->transfer.buffer != NULL))
+    {
+        if (handle->openedReadHandleHead->transfer.length > handle->openedReadHandleHead->transfer.soFar)
+        {
+            uint32_t remainLength =
+                handle->openedReadHandleHead->transfer.length - handle->openedReadHandleHead->transfer.soFar;
+            for (uint32_t i = 0; i < MIN(ringBufferLength, remainLength); i++)
+            {
+                handle->openedReadHandleHead->transfer.buffer[handle->openedReadHandleHead->transfer.soFar] =
+                    handle->ringBuffer.ringBuffer[handle->ringBuffer.ringTail];
+                handle->ringBuffer.ringTail++;
+                handle->openedReadHandleHead->transfer.soFar++;
+                if (handle->ringBuffer.ringTail >= handle->ringBuffer.ringBufferSize)
+                {
+                    handle->ringBuffer.ringTail = 0U;
+                }
+            }
+            ringBufferLength = ringBufferLength - MIN(ringBufferLength, remainLength);
+        }
+
+        if (handle->openedReadHandleHead->transfer.length > handle->openedReadHandleHead->transfer.soFar)
+        {
+        }
+        else
+        {
+            if (kSerialManager_TransmissionBlocking == handle->openedReadHandleHead->transfer.mode)
+            {
+                handle->openedReadHandleHead->transfer.buffer = NULL;
+            }
+            else
+            {
+                handle->openedReadHandleHead->transfer.status = kStatus_SerialManager_Success;
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+                handle->commontaskMsg.callback      = SerialManager_Task;
+                handle->commontaskMsg.callbackParam = handle;
+                COMMON_TASK_post_message(&handle->commontaskMsg);
+#else
+                (void)OSA_EventSet((osa_event_handle_t)handle->event, SERIAL_EVENT_DATA_RECEIVED);
+#endif
+
+#else
+                SerialManager_Task(handle);
+#endif
+            }
+        }
+    }
+
+    if (ringBufferLength != 0U)
+    {
+        message->buffer = NULL;
+        message->length = ringBufferLength;
+        if ((NULL != handle->openedReadHandleHead) && (NULL != handle->openedReadHandleHead->callback))
+        {
+            handle->openedReadHandleHead->callback(handle->openedReadHandleHead->callbackParam, message, status);
+        }
+    }
+
+    ringBufferLength = handle->ringBuffer.ringBufferSize - 1U - ringBufferLength;
+
+    if (NULL != handle->openedReadHandleHead)
+    {
+        (void)SerialManager_StartReading(handle, handle->openedReadHandleHead, NULL, ringBufferLength);
+    }
+    EnableGlobalIRQ(primask);
+}
+
+static serial_manager_status_t SerialManager_Write(serial_write_handle_t writeHandle,
+                                                   uint8_t *buffer,
+                                                   uint32_t length,
+                                                   serial_manager_transmission_mode_t mode)
+{
+    serial_manager_write_handle_t *serialWriteHandle;
+    serial_manager_handle_t *handle;
+    serial_manager_status_t status = kStatus_SerialManager_Success;
+    uint32_t primask;
+    uint8_t isEmpty = 0U;
+
+    assert(writeHandle);
+    assert(buffer);
+    assert(length);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+    handle            = serialWriteHandle->serialManagerHandle;
+
+    assert(handle);
+    assert(SERIAL_MANAGER_WRITE_TAG == serialWriteHandle->tag);
+    assert(!((kSerialManager_TransmissionNonBlocking == mode) && (NULL == serialWriteHandle->callback)));
+
+    primask = DisableGlobalIRQ();
+    if (serialWriteHandle->transfer.buffer != NULL)
+    {
+        EnableGlobalIRQ(primask);
+        return kStatus_SerialManager_Busy;
+    }
+    serialWriteHandle->transfer.buffer = buffer;
+    serialWriteHandle->transfer.length = length;
+    serialWriteHandle->transfer.soFar  = 0U;
+    serialWriteHandle->transfer.mode   = mode;
+
+    if (NULL == LIST_GetHead(&handle->runningWriteHandleHead))
+    {
+        isEmpty = 1U;
+    }
+    SerialManager_AddTail(&handle->runningWriteHandleHead, serialWriteHandle);
+    EnableGlobalIRQ(primask);
+
+    if (isEmpty != 0U)
+    {
+        status = SerialManager_StartWriting(handle);
+        if ((serial_manager_status_t)kStatus_SerialManager_Success != status)
+        {
+            return status;
+        }
+    }
+
+    if (kSerialManager_TransmissionBlocking == mode)
+    {
+        while (serialWriteHandle->transfer.length > serialWriteHandle->transfer.soFar)
+        {
+#if defined(__GIC_PRIO_BITS)
+            if ((__get_CPSR() & CPSR_M_Msk) == 0x13)
+#else
+            if (__get_IPSR() != 0U)
+#endif
+            {
+                SerialManager_IsrFunction(handle);
+            }
+        }
+    }
+    return kStatus_SerialManager_Success;
+}
+
+static serial_manager_status_t SerialManager_Read(serial_read_handle_t readHandle,
+                                                  uint8_t *buffer,
+                                                  uint32_t length,
+                                                  serial_manager_transmission_mode_t mode,
+                                                  uint32_t *receivedLength)
+{
+    serial_manager_read_handle_t *serialReadHandle;
+    serial_manager_handle_t *handle;
+    uint32_t dataLength;
+    uint32_t primask;
+
+    assert(readHandle);
+    assert(buffer);
+    assert(length);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+    handle           = serialReadHandle->serialManagerHandle;
+
+    assert(handle);
+    assert(SERIAL_MANAGER_READ_TAG == serialReadHandle->tag);
+    assert(!((kSerialManager_TransmissionNonBlocking == mode) && (NULL == serialReadHandle->callback)));
+
+    primask = DisableGlobalIRQ();
+    if (serialReadHandle->transfer.buffer != NULL)
+    {
+        EnableGlobalIRQ(primask);
+        return kStatus_SerialManager_Busy;
+    }
+    serialReadHandle->transfer.buffer = buffer;
+    serialReadHandle->transfer.length = length;
+    serialReadHandle->transfer.soFar  = 0U;
+    serialReadHandle->transfer.mode   = mode;
+
+    dataLength = handle->ringBuffer.ringHead + handle->ringBuffer.ringBufferSize - handle->ringBuffer.ringTail;
+    dataLength = dataLength % handle->ringBuffer.ringBufferSize;
+
+    for (serialReadHandle->transfer.soFar = 0U; serialReadHandle->transfer.soFar < MIN(dataLength, length);
+         serialReadHandle->transfer.soFar++)
+    {
+        buffer[serialReadHandle->transfer.soFar] = handle->ringBuffer.ringBuffer[handle->ringBuffer.ringTail];
+        handle->ringBuffer.ringTail++;
+        if (handle->ringBuffer.ringTail >= handle->ringBuffer.ringBufferSize)
+        {
+            handle->ringBuffer.ringTail = 0U;
+        }
+    }
+
+    dataLength = handle->ringBuffer.ringHead + handle->ringBuffer.ringBufferSize - handle->ringBuffer.ringTail;
+    dataLength = dataLength % handle->ringBuffer.ringBufferSize;
+    dataLength = handle->ringBuffer.ringBufferSize - 1U - dataLength;
+
+    (void)SerialManager_StartReading(handle, readHandle, NULL, dataLength);
+
+    if (receivedLength != NULL)
+    {
+        *receivedLength                   = serialReadHandle->transfer.soFar;
+        serialReadHandle->transfer.buffer = NULL;
+        EnableGlobalIRQ(primask);
+    }
+    else
+    {
+        if (serialReadHandle->transfer.soFar >= serialReadHandle->transfer.length)
+        {
+            serialReadHandle->transfer.buffer = NULL;
+            EnableGlobalIRQ(primask);
+            if (kSerialManager_TransmissionNonBlocking == mode)
+            {
+                if (serialReadHandle->callback != NULL)
+                {
+                    serial_manager_callback_message_t msg;
+                    msg.buffer = buffer;
+                    msg.length = serialReadHandle->transfer.soFar;
+                    serialReadHandle->callback(serialReadHandle->callbackParam, &msg, kStatus_SerialManager_Success);
+                }
+            }
+        }
+        else
+        {
+            EnableGlobalIRQ(primask);
+        }
+
+        if (kSerialManager_TransmissionBlocking == mode)
+        {
+            while (serialReadHandle->transfer.length > serialReadHandle->transfer.soFar)
+            {
+            }
+        }
+    }
+
+    return kStatus_SerialManager_Success;
+}
+
+#else
+
+static serial_manager_status_t SerialManager_Write(serial_write_handle_t writeHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_manager_write_handle_t *serialWriteHandle;
+    serial_manager_handle_t *handle;
+
+    assert(writeHandle);
+    assert(buffer);
+    assert(length);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+    handle            = serialWriteHandle->serialManagerHandle;
+
+    assert(handle);
+
+    return SerialManager_StartWriting(handle, serialWriteHandle, buffer, length);
+}
+
+static serial_manager_status_t SerialManager_Read(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_manager_read_handle_t *serialReadHandle;
+    serial_manager_handle_t *handle;
+
+    assert(readHandle);
+    assert(buffer);
+    assert(length);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+    handle           = serialReadHandle->serialManagerHandle;
+
+    assert(handle);
+
+    return SerialManager_StartReading(handle, serialReadHandle, buffer, length);
+}
+#endif
+
+serial_manager_status_t SerialManager_Init(serial_handle_t serialHandle, serial_manager_config_t *config)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+
+    assert(config);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    assert(config->ringBuffer);
+    assert(config->ringBufferSize);
+#endif
+    assert(serialHandle);
+    assert(SERIAL_MANAGER_HANDLE_SIZE >= sizeof(serial_manager_handle_t));
+
+    handle = (serial_manager_handle_t *)serialHandle;
+
+    (void)memset(handle, 0, SERIAL_MANAGER_HANDLE_SIZE);
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+
+    COMMON_TASK_init();
+
+#else
+    if (KOSA_StatusSuccess != OSA_EventCreate((osa_event_handle_t)handle->event, true))
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+    if (KOSA_StatusSuccess != OSA_TaskCreate((osa_task_handle_t)handle->taskId, OSA_TASK(SerialManager_Task), handle))
+    {
+        return kStatus_SerialManager_Error;
+    }
+#endif
+
+#endif
+
+#endif
+
+    handle->type = config->type;
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    handle->ringBuffer.ringBuffer     = config->ringBuffer;
+    handle->ringBuffer.ringBufferSize = config->ringBufferSize;
+#endif
+
+    switch (config->type)
+    {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        case kSerialPort_Uart:
+            status = Serial_UartInit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), config->portConfig);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+            if ((serial_manager_status_t)kStatus_SerialManager_Success == status)
+            {
+                status = Serial_UartInstallTxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                      SerialManager_TxCallback, handle);
+                if ((serial_manager_status_t)kStatus_SerialManager_Success == status)
+                {
+                    status = Serial_UartInstallRxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                          SerialManager_RxCallback, handle);
+                }
+            }
+#endif
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        case kSerialPort_UsbCdc:
+            status = Serial_UsbCdcInit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), config->portConfig);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+            if (kStatus_SerialManager_Success == status)
+            {
+                status = Serial_UsbCdcInstallTxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                        SerialManager_TxCallback, handle);
+                if (kStatus_SerialManager_Success == status)
+                {
+                    status = Serial_UsbCdcInstallRxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                            SerialManager_RxCallback, handle);
+                }
+            }
+#endif
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        case kSerialPort_Swo:
+            status = Serial_SwoInit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), config->portConfig);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+            if (kStatus_SerialManager_Success == status)
+            {
+                status = Serial_SwoInstallTxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                     SerialManager_TxCallback, handle);
+            }
+#endif
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        case kSerialPort_UsbCdcVirtual:
+            status = Serial_UsbCdcVirtualInit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), config->portConfig);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+            if (kStatus_SerialManager_Success == status)
+            {
+                status = Serial_UsbCdcVirtualInstallTxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                               SerialManager_TxCallback, handle);
+                if (kStatus_SerialManager_Success == status)
+                {
+                    status = Serial_UsbCdcVirtualInstallRxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                                   SerialManager_RxCallback, handle);
+                }
+            }
+#endif
+            break;
+#endif
+        default:
+            /*MISRA rule 16.4*/
+            break;
+    }
+
+    return status;
+}
+
+serial_manager_status_t SerialManager_Deinit(serial_handle_t serialHandle)
+{
+    serial_manager_handle_t *handle;
+    uint32_t primask;
+
+    assert(serialHandle);
+
+    handle = (serial_manager_handle_t *)serialHandle;
+
+    primask = DisableGlobalIRQ();
+    if ((handle->openedReadHandleHead != NULL) || (handle->openedWriteHandleCount != 0U))
+    {
+        EnableGlobalIRQ(primask);
+        return kStatus_SerialManager_Busy;
+    }
+    EnableGlobalIRQ(primask);
+
+    switch (handle->type)
+    {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        case kSerialPort_Uart:
+            (void)Serial_UartDeinit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        case kSerialPort_UsbCdc:
+            (void)Serial_UsbCdcDeinit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        case kSerialPort_Swo:
+            (void)Serial_SwoDeinit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        case kSerialPort_UsbCdcVirtual:
+            (void)Serial_UsbCdcVirtualDeinit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+        default:
+            /*MISRA rule 16.4*/
+            break;
+    }
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#else
+    OSA_EventDestroy((osa_event_handle_t)handle->event);
+    OSA_TaskDestroy((osa_task_handle_t)handle->taskId);
+#endif
+
+#endif
+
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_OpenWriteHandle(serial_handle_t serialHandle, serial_write_handle_t writeHandle)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_write_handle_t *serialWriteHandle;
+    uint32_t primask;
+
+    assert(serialHandle);
+    assert(writeHandle);
+    assert(SERIAL_MANAGER_WRITE_HANDLE_SIZE >= sizeof(serial_manager_write_handle_t));
+
+    handle            = (serial_manager_handle_t *)serialHandle;
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+
+    (void)memset(writeHandle, 0, SERIAL_MANAGER_WRITE_HANDLE_SIZE);
+
+    primask = DisableGlobalIRQ();
+    handle->openedWriteHandleCount++;
+    EnableGlobalIRQ(primask);
+
+    serialWriteHandle->serialManagerHandle = handle;
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serialWriteHandle->tag = SERIAL_MANAGER_WRITE_TAG;
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_CloseWriteHandle(serial_write_handle_t writeHandle)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_write_handle_t *serialWriteHandle;
+    uint32_t primask;
+
+    assert(writeHandle);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+    handle            = (serial_manager_handle_t *)(void *)serialWriteHandle->serialManagerHandle;
+
+    assert(handle);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    assert(SERIAL_MANAGER_WRITE_TAG == serialWriteHandle->tag);
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    (void)SerialManager_CancelWriting(writeHandle);
+#endif
+    primask = DisableGlobalIRQ();
+    if (handle->openedWriteHandleCount > 0U)
+    {
+        handle->openedWriteHandleCount--;
+    }
+    EnableGlobalIRQ(primask);
+
+    (void)memset(writeHandle, 0, SERIAL_MANAGER_WRITE_HANDLE_SIZE);
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_OpenReadHandle(serial_handle_t serialHandle, serial_read_handle_t readHandle)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_read_handle_t *serialReadHandle;
+    uint32_t primask;
+
+    assert(serialHandle);
+    assert(readHandle);
+    assert(SERIAL_MANAGER_READ_HANDLE_SIZE >= sizeof(serial_manager_read_handle_t));
+
+    handle           = (serial_manager_handle_t *)serialHandle;
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+
+    primask = DisableGlobalIRQ();
+    if (handle->openedReadHandleHead != NULL)
+    {
+        EnableGlobalIRQ(primask);
+        return kStatus_SerialManager_Busy;
+    }
+    handle->openedReadHandleHead = serialReadHandle;
+    EnableGlobalIRQ(primask);
+
+    (void)memset(readHandle, 0, SERIAL_MANAGER_READ_HANDLE_SIZE);
+
+    serialReadHandle->serialManagerHandle = handle;
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serialReadHandle->tag = SERIAL_MANAGER_READ_TAG;
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_CloseReadHandle(serial_read_handle_t readHandle)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_read_handle_t *serialReadHandle;
+    uint32_t primask;
+
+    assert(readHandle);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+    handle           = (serial_manager_handle_t *)(void *)serialReadHandle->serialManagerHandle;
+
+    assert(handle && (handle->openedReadHandleHead == serialReadHandle));
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    assert(SERIAL_MANAGER_READ_TAG == serialReadHandle->tag);
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    (void)SerialManager_CancelReading(readHandle);
+#endif
+
+    primask                      = DisableGlobalIRQ();
+    handle->openedReadHandleHead = NULL;
+    EnableGlobalIRQ(primask);
+
+    (void)memset(readHandle, 0, SERIAL_MANAGER_READ_HANDLE_SIZE);
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_WriteBlocking(serial_write_handle_t writeHandle, uint8_t *buffer, uint32_t length)
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    return SerialManager_Write(writeHandle, buffer, length, kSerialManager_TransmissionBlocking);
+#else
+    return SerialManager_Write(writeHandle, buffer, length);
+#endif
+}
+
+serial_manager_status_t SerialManager_ReadBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length)
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    return SerialManager_Read(readHandle, buffer, length, kSerialManager_TransmissionBlocking, NULL);
+#else
+    return SerialManager_Read(readHandle, buffer, length);
+#endif
+}
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t SerialManager_WriteNonBlocking(serial_write_handle_t writeHandle,
+                                                       uint8_t *buffer,
+                                                       uint32_t length)
+{
+    return SerialManager_Write(writeHandle, buffer, length, kSerialManager_TransmissionNonBlocking);
+}
+
+serial_manager_status_t SerialManager_ReadNonBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length)
+{
+    return SerialManager_Read(readHandle, buffer, length, kSerialManager_TransmissionNonBlocking, NULL);
+}
+
+serial_manager_status_t SerialManager_CancelWriting(serial_write_handle_t writeHandle)
+{
+    serial_manager_write_handle_t *serialWriteHandle;
+    uint32_t primask;
+    uint8_t isNotUsed = 0;
+
+    assert(writeHandle);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+
+    assert(serialWriteHandle->serialManagerHandle);
+    assert(SERIAL_MANAGER_WRITE_TAG == serialWriteHandle->tag);
+
+    if ((serialWriteHandle->transfer.buffer != NULL) &&
+        (kSerialManager_TransmissionBlocking == serialWriteHandle->transfer.mode))
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+    primask = DisableGlobalIRQ();
+    if (serialWriteHandle != (serial_manager_write_handle_t *)(void *)LIST_GetHead(
+                                 &serialWriteHandle->serialManagerHandle->runningWriteHandleHead))
+    {
+        (void)LIST_RemoveElement(&serialWriteHandle->link);
+        isNotUsed = 1;
+    }
+    EnableGlobalIRQ(primask);
+
+    if (isNotUsed != 0U)
+    {
+        serialWriteHandle->transfer.soFar  = 0;
+        serialWriteHandle->transfer.status = kStatus_SerialManager_Canceled;
+
+        SerialManager_AddTail(&serialWriteHandle->serialManagerHandle->completedWriteHandleHead, serialWriteHandle);
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+        serialWriteHandle->serialManagerHandle->commontaskMsg.callback      = SerialManager_Task;
+        serialWriteHandle->serialManagerHandle->commontaskMsg.callbackParam = serialWriteHandle->serialManagerHandle;
+        COMMON_TASK_post_message(&serialWriteHandle->serialManagerHandle->commontaskMsg);
+#else
+        (void)OSA_EventSet((osa_event_handle_t)serialWriteHandle->serialManagerHandle->event, SERIAL_EVENT_DATA_SENT);
+#endif
+
+#else
+        SerialManager_Task(serialWriteHandle->serialManagerHandle);
+#endif
+    }
+    else
+    {
+        switch (serialWriteHandle->serialManagerHandle->type)
+        {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+            case kSerialPort_Uart:
+                (void)Serial_UartCancelWrite(
+                    ((serial_handle_t)&serialWriteHandle->serialManagerHandle->lowLevelhandleBuffer[0]));
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+            case kSerialPort_UsbCdc:
+                (void)Serial_UsbCdcCancelWrite(
+                    ((serial_handle_t)&serialWriteHandle->serialManagerHandle->lowLevelhandleBuffer[0]));
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+            case kSerialPort_Swo:
+                (void)Serial_SwoCancelWrite(
+                    ((serial_handle_t)&serialWriteHandle->serialManagerHandle->lowLevelhandleBuffer[0]));
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+            case kSerialPort_UsbCdcVirtual:
+                (void)Serial_UsbCdcVirtualCancelWrite(
+                    ((serial_handle_t)&serialWriteHandle->serialManagerHandle->lowLevelhandleBuffer[0]));
+                break;
+#endif
+            default:
+                /*MISRA rule 16.4*/
+                break;
+        }
+    }
+
+    (void)SerialManager_StartWriting(serialWriteHandle->serialManagerHandle);
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_CancelReading(serial_read_handle_t readHandle)
+{
+    serial_manager_read_handle_t *serialReadHandle;
+    serial_manager_callback_message_t msg;
+    uint8_t *buffer;
+    uint32_t primask;
+
+    assert(readHandle);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+
+    assert(SERIAL_MANAGER_READ_TAG == serialReadHandle->tag);
+
+    if ((serialReadHandle->transfer.buffer != NULL) &&
+        (kSerialManager_TransmissionBlocking == serialReadHandle->transfer.mode))
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+    primask                           = DisableGlobalIRQ();
+    buffer                            = serialReadHandle->transfer.buffer;
+    serialReadHandle->transfer.buffer = NULL;
+    serialReadHandle->transfer.length = 0;
+    msg.buffer                        = buffer;
+    msg.length                        = serialReadHandle->transfer.soFar;
+    EnableGlobalIRQ(primask);
+
+    if (buffer != NULL)
+    {
+        if (serialReadHandle->callback != NULL)
+        {
+            serialReadHandle->callback(serialReadHandle->callbackParam, &msg, kStatus_SerialManager_Canceled);
+        }
+    }
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_TryRead(serial_read_handle_t readHandle,
+                                              uint8_t *buffer,
+                                              uint32_t length,
+                                              uint32_t *receivedLength)
+{
+    assert(receivedLength);
+
+    return SerialManager_Read(readHandle, buffer, length, kSerialManager_TransmissionBlocking, receivedLength);
+}
+
+serial_manager_status_t SerialManager_InstallTxCallback(serial_write_handle_t writeHandle,
+                                                        serial_manager_callback_t callback,
+                                                        void *callbackParam)
+{
+    serial_manager_write_handle_t *serialWriteHandle;
+
+    assert(writeHandle);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+
+    assert(SERIAL_MANAGER_WRITE_TAG == serialWriteHandle->tag);
+
+    serialWriteHandle->callbackParam = callbackParam;
+    serialWriteHandle->callback      = callback;
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_InstallRxCallback(serial_read_handle_t readHandle,
+                                                        serial_manager_callback_t callback,
+                                                        void *callbackParam)
+{
+    serial_manager_read_handle_t *serialReadHandle;
+
+    assert(readHandle);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+
+    assert(SERIAL_MANAGER_READ_TAG == serialReadHandle->tag);
+
+    serialReadHandle->callbackParam = callbackParam;
+    serialReadHandle->callback      = callback;
+
+    return kStatus_SerialManager_Success;
+}
+#endif
+
+serial_manager_status_t SerialManager_EnterLowpower(serial_handle_t serialHandle)
+{
+    assert(serialHandle);
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_ExitLowpower(serial_handle_t serialHandle)
+{
+    assert(serialHandle);
+
+    return kStatus_SerialManager_Success;
+}
diff --git a/third_party/nxp/JN5189DK6/components/serial_manager/serial_manager.h b/third_party/nxp/JN5189DK6/components/serial_manager/serial_manager.h
new file mode 100755
index 0000000..0b4e334
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/components/serial_manager/serial_manager.h
@@ -0,0 +1,548 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SERIAL_MANAGER_H__
+#define __SERIAL_MANAGER_H__
+
+/*!
+ * @addtogroup serialmanager
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*! @brief Enable or disable serial manager non-blocking mode (1 - enable, 0 - disable) */
+#define SERIAL_MANAGER_NON_BLOCKING_MODE (1U)
+#else
+#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
+#define SERIAL_MANAGER_NON_BLOCKING_MODE (0U)
+#endif
+#endif
+
+/*! @brief Enable or disable uart port (1 - enable, 0 - disable) */
+#ifndef SERIAL_PORT_TYPE_UART
+#define SERIAL_PORT_TYPE_UART (1U)
+#endif
+
+/*! @brief Enable or disable USB CDC port (1 - enable, 0 - disable) */
+#ifndef SERIAL_PORT_TYPE_USBCDC
+#define SERIAL_PORT_TYPE_USBCDC (0U)
+#endif
+
+/*! @brief Enable or disable SWO port (1 - enable, 0 - disable) */
+#ifndef SERIAL_PORT_TYPE_SWO
+#define SERIAL_PORT_TYPE_SWO (0U)
+#endif
+
+/*! @brief Enable or disable USB CDC virtual port (1 - enable, 0 - disable) */
+#ifndef SERIAL_PORT_TYPE_USBCDC_VIRTUAL
+#define SERIAL_PORT_TYPE_USBCDC_VIRTUAL (0U)
+#endif
+
+/*! @brief Set serial manager write handle size */
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#define SERIAL_MANAGER_WRITE_HANDLE_SIZE (44U)
+#define SERIAL_MANAGER_READ_HANDLE_SIZE (44U)
+#else
+#define SERIAL_MANAGER_WRITE_HANDLE_SIZE (4U)
+#define SERIAL_MANAGER_READ_HANDLE_SIZE (4U)
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+#include "serial_port_uart.h"
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+
+#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#error The serial manager blocking mode cannot be supported for USB CDC.
+#endif
+
+#include "serial_port_usb.h"
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+#include "serial_port_swo.h"
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+
+#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#error The serial manager blocking mode cannot be supported for USB CDC.
+#endif
+
+#include "serial_port_usb_virtual.h"
+#endif
+
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP 0U
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+
+#if (SERIAL_PORT_UART_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
+#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_UART_HANDLE_SIZE
+#endif
+
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+
+#if (SERIAL_PORT_USB_CDC_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
+#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_CDC_HANDLE_SIZE
+#endif
+
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+
+#if (SERIAL_PORT_SWO_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
+#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_SWO_HANDLE_SIZE
+#endif
+
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+
+#if (SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
+#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE
+#endif
+
+#endif
+
+/*! @brief SERIAL_PORT_UART_HANDLE_SIZE/SERIAL_PORT_USB_CDC_HANDLE_SIZE + serial manager dedicated size */
+#if ((defined(SERIAL_MANAGER_HANDLE_SIZE_TEMP) && (SERIAL_MANAGER_HANDLE_SIZE_TEMP > 0U)))
+#else
+#error SERIAL_PORT_TYPE_UART, SERIAL_PORT_TYPE_USBCDC, SERIAL_PORT_TYPE_SWO and SERIAL_PORT_TYPE_USBCDC_VIRTUAL should not be cleared at same time.
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 120U)
+#else
+#define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 12U)
+#endif
+
+#define SERIAL_MANAGER_USE_COMMON_TASK (1U)
+#define SERIAL_MANAGER_TASK_PRIORITY (2U)
+#define SERIAL_MANAGER_TASK_STACK_SIZE (1000U)
+
+typedef void *serial_handle_t;
+typedef void *serial_write_handle_t;
+typedef void *serial_read_handle_t;
+
+/*! @brief serial port type*/
+typedef enum _serial_port_type
+{
+    kSerialPort_Uart = 1U,     /*!< Serial port UART */
+    kSerialPort_UsbCdc,        /*!< Serial port USB CDC */
+    kSerialPort_Swo,           /*!< Serial port SWO */
+    kSerialPort_UsbCdcVirtual, /*!< Serial port USB CDC Virtual */
+} serial_port_type_t;
+
+/*! @brief serial manager config structure*/
+typedef struct _serial_manager_config
+{
+    uint8_t *ringBuffer;     /*!< Ring buffer address, it is used to buffer data received by the hardware.
+                                  Besides, the memory space cannot be free during the lifetime of the serial
+                                  manager module. */
+    uint32_t ringBufferSize; /*!< The size of the ring buffer */
+    serial_port_type_t type; /*!< Serial port type */
+    void *portConfig;        /*!< Serial port configuration */
+} serial_manager_config_t;
+
+/*! @brief serial manager error code*/
+typedef enum _serial_manager_status
+{
+    kStatus_SerialManager_Success = kStatus_Success,                            /*!< Success */
+    kStatus_SerialManager_Error   = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 1), /*!< Failed */
+    kStatus_SerialManager_Busy    = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 2), /*!< Busy */
+    kStatus_SerialManager_Notify  = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 3), /*!< Ring buffer is not empty */
+    kStatus_SerialManager_Canceled =
+        MAKE_STATUS(kStatusGroup_SERIALMANAGER, 4), /*!< the non-blocking request is canceled */
+    kStatus_SerialManager_HandleConflict = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 5), /*!< The handle is opened */
+    kStatus_SerialManager_RingBufferOverflow =
+        MAKE_STATUS(kStatusGroup_SERIALMANAGER, 6), /*!< The ring buffer is overflowed */
+} serial_manager_status_t;
+
+/*! @brief Callback message structure */
+typedef struct _serial_manager_callback_message
+{
+    uint8_t *buffer; /*!< Transferred buffer */
+    uint32_t length; /*!< Transferred data length */
+} serial_manager_callback_message_t;
+
+/*! @brief callback function */
+typedef void (*serial_manager_callback_t)(void *callbackParam,
+                                          serial_manager_callback_message_t *message,
+                                          serial_manager_status_t status);
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+/*!
+ * @brief Initializes a serial manager module with the serial manager handle and the user configuration structure.
+ *
+ * This function configures the Serial Manager module with user-defined settings. The user can configure the
+ * configuration
+ * structure. The parameter serialHandle is a pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE
+ * allocated by the caller.
+ * The Serial Manager module supports two types of serial port, UART (includes UART, USART, LPSCI, LPUART, etc) and USB
+ * CDC.
+ * Please refer to #serial_port_type_t for serial port setting. These two types can be set by using
+ * #serial_manager_config_t.
+ *
+ * Example below shows how to use this API to configure the Serial Manager.
+ * For UART,
+ *  @code
+ *   #define SERIAL_MANAGER_RING_BUFFER_SIZE          (256U)
+ *   static uint8_t s_serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
+ *   static serial_handle_t s_serialHandle = &s_serialHandleBuffer[0];
+ *   static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
+ *
+ *   serial_manager_config_t config;
+ *   serial_port_uart_config_t uartConfig;
+ *   config.type = kSerialPort_Uart;
+ *   config.ringBuffer = &s_ringBuffer[0];
+ *   config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
+ *   uartConfig.instance = 0;
+ *   uartConfig.clockRate = 24000000;
+ *   uartConfig.baudRate = 115200;
+ *   uartConfig.parityMode = kSerialManager_UartParityDisabled;
+ *   uartConfig.stopBitCount = kSerialManager_UartOneStopBit;
+ *   uartConfig.enableRx = 1;
+ *   uartConfig.enableTx = 1;
+ *   config.portConfig = &uartConfig;
+ *   SerialManager_Init(s_serialHandle, &config);
+ *  @endcode
+ * For USB CDC,
+ *  @code
+ *   #define SERIAL_MANAGER_RING_BUFFER_SIZE          (256U)
+ *   static uint8_t s_serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
+ *   static serial_handle_t s_serialHandle = &s_serialHandleBuffer[0];
+ *   static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
+ *
+ *   serial_manager_config_t config;
+ *   serial_port_usb_cdc_config_t usbCdcConfig;
+ *   config.type = kSerialPort_UsbCdc;
+ *   config.ringBuffer = &s_ringBuffer[0];
+ *   config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
+ *   usbCdcConfig.controllerIndex = kSerialManager_UsbControllerKhci0;
+ *   config.portConfig = &usbCdcConfig;
+ *   SerialManager_Init(s_serialHandle, &config);
+ *  @endcode
+ *
+ * @param serialHandle Pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE allocated by the caller.
+ * @param config Pointer to user-defined configuration structure.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ * @retval kStatus_SerialManager_Success The Serial Manager module initialization succeed.
+ */
+serial_manager_status_t SerialManager_Init(serial_handle_t serialHandle, serial_manager_config_t *config);
+
+/*!
+ * @brief De-initializes the serial manager module instance.
+ *
+ * This function de-initializes the serial manager module instance. If the opened writing or
+ * reading handle is not closed, the function will return kStatus_SerialManager_Busy.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success The serial manager de-initialization succeed.
+ * @retval kStatus_SerialManager_Busy Opened reading or writing handle is not closed.
+ */
+serial_manager_status_t SerialManager_Deinit(serial_handle_t serialHandle);
+
+/*!
+ * @brief Opens a writing handle for the serial manager module.
+ *
+ * This function Opens a writing handle for the serial manager module. If the serial manager needs to
+ * be used in different tasks, the task should open a dedicated write handle for itself by calling
+ * #SerialManager_OpenWriteHandle. Since there can only one buffer for transmission for the writing
+ * handle at the same time, multiple writing handles need to be opened when the multiple transmission
+ * is needed for a task.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @param writeHandle The serial manager module writing handle pointer.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ * @retval kStatus_SerialManager_HandleConflict The writing handle was opened.
+ * @retval kStatus_SerialManager_Success The writing handle is opened.
+ *
+ * Example below shows how to use this API to write data.
+ * For task 1,
+ *  @code
+ *   static uint8_t s_serialWriteHandleBuffer1[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
+ *   static serial_write_handle_t s_serialWriteHandle1 = &s_serialWriteHandleBuffer1[0];
+ *   static uint8_t s_nonBlockingWelcome1[] = "This is non-blocking writing log for task1!\r\n";
+ *   SerialManager_OpenWriteHandle(serialHandle, s_serialWriteHandle1);
+ *   SerialManager_InstallTxCallback(s_serialWriteHandle1, Task1_SerialManagerTxCallback, s_serialWriteHandle1);
+ *   SerialManager_WriteNonBlocking(s_serialWriteHandle1, s_nonBlockingWelcome1, sizeof(s_nonBlockingWelcome1) - 1);
+ *  @endcode
+ * For task 2,
+ *  @code
+ *   static uint8_t s_serialWriteHandleBuffer2[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
+ *   static serial_write_handle_t s_serialWriteHandle2 = &s_serialWriteHandleBuffer2[0];
+ *   static uint8_t s_nonBlockingWelcome2[] = "This is non-blocking writing log for task2!\r\n";
+ *   SerialManager_OpenWriteHandle(serialHandle, s_serialWriteHandle2);
+ *   SerialManager_InstallTxCallback(s_serialWriteHandle2, Task2_SerialManagerTxCallback, s_serialWriteHandle2);
+ *   SerialManager_WriteNonBlocking(s_serialWriteHandle2, s_nonBlockingWelcome2, sizeof(s_nonBlockingWelcome2) - 1);
+ *  @endcode
+ */
+serial_manager_status_t SerialManager_OpenWriteHandle(serial_handle_t serialHandle, serial_write_handle_t writeHandle);
+
+/*!
+ * @brief Closes a writing handle for the serial manager module.
+ *
+ * This function Closes a writing handle for the serial manager module.
+ *
+ * @param writeHandle The serial manager module writing handle pointer.
+ * @retval kStatus_SerialManager_Success The writing handle is closed.
+ */
+serial_manager_status_t SerialManager_CloseWriteHandle(serial_write_handle_t writeHandle);
+
+/*!
+ * @brief Opens a reading handle for the serial manager module.
+ *
+ * This function Opens a reading handle for the serial manager module. The reading handle can not be
+ * opened multiple at the same time. The error code kStatus_SerialManager_Busy would be returned when
+ * the previous reading handle is not closed. And There can only be one buffer for receiving for the
+ * reading handle at the same time.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @param readHandle The serial manager module reading handle pointer.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ * @retval kStatus_SerialManager_Success The reading handle is opened.
+ * @retval kStatus_SerialManager_Busy Previous reading handle is not closed.
+ *
+ * Example below shows how to use this API to read data.
+ *  @code
+ *   static uint8_t s_serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE];
+ *   static serial_read_handle_t s_serialReadHandle = &s_serialReadHandleBuffer[0];
+ *   SerialManager_OpenReadHandle(serialHandle, s_serialReadHandle);
+ *   static uint8_t s_nonBlockingBuffer[64];
+ *   SerialManager_InstallRxCallback(s_serialReadHandle, APP_SerialManagerRxCallback, s_serialReadHandle);
+ *   SerialManager_ReadNonBlocking(s_serialReadHandle, s_nonBlockingBuffer, sizeof(s_nonBlockingBuffer));
+ *  @endcode
+ */
+serial_manager_status_t SerialManager_OpenReadHandle(serial_handle_t serialHandle, serial_read_handle_t readHandle);
+
+/*!
+ * @brief Closes a reading for the serial manager module.
+ *
+ * This function Closes a reading for the serial manager module.
+ *
+ * @param readHandle The serial manager module reading handle pointer.
+ * @retval kStatus_SerialManager_Success The reading handle is closed.
+ */
+serial_manager_status_t SerialManager_CloseReadHandle(serial_read_handle_t readHandle);
+
+/*!
+ * @brief Transmits data with the blocking mode.
+ *
+ * This is a blocking function, which polls the sending queue, waits for the sending queue to be empty.
+ * This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
+ * And There can only one buffer for transmission for the writing handle at the same time.
+ *
+ * @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
+ * cannot be used at the same time.
+ * And, the function #SerialManager_CancelWriting cannot be used to abort the transmission of this function.
+ *
+ * @param writeHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to write.
+ * @param length Length of the data to write.
+ * @retval kStatus_SerialManager_Success Successfully sent all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_WriteBlocking(serial_write_handle_t writeHandle,
+                                                    uint8_t *buffer,
+                                                    uint32_t length);
+
+/*!
+ * @brief Reads data with the blocking mode.
+ *
+ * This is a blocking function, which polls the receiving buffer, waits for the receiving buffer to be full.
+ * This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
+ * And There can only one buffer for receiving for the reading handle at the same time.
+ *
+ * @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
+ * cannot be used at the same time.
+ * And, the function #SerialManager_CancelReading cannot be used to abort the transmission of this function.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to store the received data.
+ * @param length The length of the data to be received.
+ * @retval kStatus_SerialManager_Success Successfully received all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_ReadBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length);
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+/*!
+ * @brief Transmits data with the non-blocking mode.
+ *
+ * This is a non-blocking function, which returns directly without waiting for all data to be sent.
+ * When all data is sent, the module notifies the upper layer through a TX callback function and passes
+ * the status parameter @ref kStatus_SerialManager_Success.
+ * This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
+ * And There can only one buffer for transmission for the writing handle at the same time.
+ *
+ * @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
+ * cannot be used at the same time. And, the TX callback is mandatory before the function could be used.
+ *
+ * @param writeHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to write.
+ * @param length Length of the data to write.
+ * @retval kStatus_SerialManager_Success Successfully sent all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_WriteNonBlocking(serial_write_handle_t writeHandle,
+                                                       uint8_t *buffer,
+                                                       uint32_t length);
+
+/*!
+ * @brief Reads data with the non-blocking mode.
+ *
+ * This is a non-blocking function, which returns directly without waiting for all data to be received.
+ * When all data is received, the module driver notifies the upper layer
+ * through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Success.
+ * This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
+ * And There can only one buffer for receiving for the reading handle at the same time.
+ *
+ * @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
+ * cannot be used at the same time. And, the RX callback is mandatory before the function could be used.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to store the received data.
+ * @param length The length of the data to be received.
+ * @retval kStatus_SerialManager_Success Successfully received all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_ReadNonBlocking(serial_read_handle_t readHandle,
+                                                      uint8_t *buffer,
+                                                      uint32_t length);
+
+/*!
+ * @brief Tries to read data.
+ *
+ * The function tries to read data from internal ring buffer. If the ring buffer is not empty, the data will be
+ * copied from ring buffer to up layer buffer. The copied length is the minimum of the ring buffer and up layer length.
+ * After the data is copied, the actual data length is passed by the parameter length.
+ * And There can only one buffer for receiving for the reading handle at the same time.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to store the received data.
+ * @param length The length of the data to be received.
+ * @param receivedLength Length received from the ring buffer directly.
+ * @retval kStatus_SerialManager_Success Successfully received all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_TryRead(serial_read_handle_t readHandle,
+                                              uint8_t *buffer,
+                                              uint32_t length,
+                                              uint32_t *receivedLength);
+
+/*!
+ * @brief Cancels unfinished send transmission.
+ *
+ * The function cancels unfinished send transmission. When the transfer is canceled, the module notifies the upper layer
+ * through a TX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
+ *
+ * @note The function #SerialManager_CancelWriting cannot be used to abort the transmission of
+ * the function #SerialManager_WriteBlocking.
+ *
+ * @param writeHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success Get successfully abort the sending.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_CancelWriting(serial_write_handle_t writeHandle);
+
+/*!
+ * @brief Cancels unfinished receive transmission.
+ *
+ * The function cancels unfinished receive transmission. When the transfer is canceled, the module notifies the upper
+ * layer
+ * through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
+ *
+ * @note The function #SerialManager_CancelReading cannot be used to abort the transmission of
+ * the function #SerialManager_ReadBlocking.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success Get successfully abort the receiving.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_CancelReading(serial_read_handle_t readHandle);
+
+/*!
+ * @brief Installs a TX callback and callback parameter.
+ *
+ * This function is used to install the TX callback and callback parameter for the serial manager module.
+ * When any status of TX transmission changed, the driver will notify the upper layer by the installed callback
+ * function. And the status is also passed as status parameter when the callback is called.
+ *
+ * @param writeHandle The serial manager module handle pointer.
+ * @param callback The callback function.
+ * @param callbackParam The parameter of the callback function.
+ * @retval kStatus_SerialManager_Success Successfully install the callback.
+ */
+serial_manager_status_t SerialManager_InstallTxCallback(serial_write_handle_t writeHandle,
+                                                        serial_manager_callback_t callback,
+                                                        void *callbackParam);
+
+/*!
+ * @brief Installs a RX callback and callback parameter.
+ *
+ * This function is used to install the RX callback and callback parameter for the serial manager module.
+ * When any status of RX transmission changed, the driver will notify the upper layer by the installed callback
+ * function. And the status is also passed as status parameter when the callback is called.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @param callback The callback function.
+ * @param callbackParam The parameter of the callback function.
+ * @retval kStatus_SerialManager_Success Successfully install the callback.
+ */
+serial_manager_status_t SerialManager_InstallRxCallback(serial_read_handle_t readHandle,
+                                                        serial_manager_callback_t callback,
+                                                        void *callbackParam);
+
+#endif
+
+/*!
+ * @brief Prepares to enter low power consumption.
+ *
+ * This function is used to prepare to enter low power consumption.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success Successful operation.
+ */
+serial_manager_status_t SerialManager_EnterLowpower(serial_handle_t serialHandle);
+
+/*!
+ * @brief Restores from low power consumption.
+ *
+ * This function is used to restore from low power consumption.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success Successful operation.
+ */
+serial_manager_status_t SerialManager_ExitLowpower(serial_handle_t serialHandle);
+
+#if defined(__cplusplus)
+}
+#endif
+/*! @} */
+#endif /* __SERIAL_MANAGER_H__ */
diff --git a/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_internal.h b/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_internal.h
new file mode 100755
index 0000000..abccd47
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_internal.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SERIAL_PORT_INTERNAL_H__
+#define __SERIAL_PORT_INTERNAL_H__
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+serial_manager_status_t Serial_UartInit(serial_handle_t serialHandle, void *serialConfig);
+serial_manager_status_t Serial_UartDeinit(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UartWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_UartRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_UartCancelWrite(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UartInstallTxCallback(serial_handle_t serialHandle,
+                                                     serial_manager_callback_t callback,
+                                                     void *callbackParam);
+serial_manager_status_t Serial_UartInstallRxCallback(serial_handle_t serialHandle,
+                                                     serial_manager_callback_t callback,
+                                                     void *callbackParam);
+void Serial_UartIsrFunction(serial_handle_t serialHandle);
+#endif
+
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+serial_manager_status_t Serial_UsbCdcInit(serial_handle_t serialHandle, void *config);
+serial_manager_status_t Serial_UsbCdcDeinit(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UsbCdcWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+serial_manager_status_t Serial_UsbCdcRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+serial_manager_status_t Serial_UsbCdcCancelWrite(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UsbCdcInstallTxCallback(serial_handle_t serialHandle,
+                                                       serial_manager_callback_t callback,
+                                                       void *callbackParam);
+serial_manager_status_t Serial_UsbCdcInstallRxCallback(serial_handle_t serialHandle,
+                                                       serial_manager_callback_t callback,
+                                                       void *callbackParam);
+void Serial_UsbCdcIsrFunction(serial_handle_t serialHandle);
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+serial_manager_status_t Serial_SwoInit(serial_handle_t serialHandle, void *config);
+serial_manager_status_t Serial_SwoDeinit(serial_handle_t serialHandle);
+serial_manager_status_t Serial_SwoWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_SwoRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+#endif
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_SwoCancelWrite(serial_handle_t serialHandle);
+serial_manager_status_t Serial_SwoInstallTxCallback(serial_handle_t serialHandle,
+                                                    serial_manager_callback_t callback,
+                                                    void *callbackParam);
+serial_manager_status_t Serial_SwoInstallRxCallback(serial_handle_t serialHandle,
+                                                    serial_manager_callback_t callback,
+                                                    void *callbackParam);
+void Serial_SwoIsrFunction(serial_handle_t serialHandle);
+#endif
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+serial_manager_status_t Serial_UsbCdcVirtualInit(serial_handle_t serialHandle, void *config);
+serial_manager_status_t Serial_UsbCdcVirtualDeinit(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UsbCdcVirtualWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+serial_manager_status_t Serial_UsbCdcVirtualRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+serial_manager_status_t Serial_UsbCdcVirtualCancelWrite(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UsbCdcVirtualInstallTxCallback(serial_handle_t serialHandle,
+                                                              serial_manager_callback_t callback,
+                                                              void *callbackParam);
+serial_manager_status_t Serial_UsbCdcVirtualInstallRxCallback(serial_handle_t serialHandle,
+                                                              serial_manager_callback_t callback,
+                                                              void *callbackParam);
+void Serial_UsbCdcVirtualIsrFunction(serial_handle_t serialHandle);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __SERIAL_PORT_INTERNAL_H__ */
diff --git a/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_uart.c b/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_uart.c
new file mode 100755
index 0000000..f60320d
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_uart.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "serial_manager.h"
+#include "serial_port_internal.h"
+
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+#include "uart.h"
+
+#include "serial_port_uart.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifndef NDEBUG
+#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
+#undef assert
+#define assert(n)
+#endif
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#define SERIAL_PORT_UART_RECEIVE_DATA_LENGTH 1U
+
+typedef struct _serial_uart_send_state
+{
+    serial_manager_callback_t callback;
+    void *callbackParam;
+    uint8_t *buffer;
+    uint32_t length;
+    volatile uint8_t busy;
+} serial_uart_send_state_t;
+
+typedef struct _serial_uart_recv_state
+{
+    serial_manager_callback_t callback;
+    void *callbackParam;
+    volatile uint8_t busy;
+    uint8_t readBuffer[SERIAL_PORT_UART_RECEIVE_DATA_LENGTH];
+} serial_uart_recv_state_t;
+#endif
+
+typedef struct _serial_uart_state
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serial_uart_send_state_t tx;
+    serial_uart_recv_state_t rx;
+#endif
+    uint8_t usartHandleBuffer[HAL_UART_HANDLE_SIZE];
+} serial_uart_state_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+/* UART user callback */
+static void Serial_UartCallback(hal_uart_handle_t handle, hal_uart_status_t status, void *userData)
+{
+    serial_uart_state_t *serialUartHandle;
+    serial_manager_callback_message_t msg;
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    hal_uart_transfer_t transfer;
+#endif
+
+    if (NULL == userData)
+    {
+        return;
+    }
+
+    serialUartHandle = (serial_uart_state_t *)userData;
+
+    if ((hal_uart_status_t)kStatus_HAL_UartRxIdle == status)
+    {
+        if ((NULL != serialUartHandle->rx.callback))
+        {
+            msg.buffer = &serialUartHandle->rx.readBuffer[0];
+            msg.length = sizeof(serialUartHandle->rx.readBuffer);
+            serialUartHandle->rx.callback(serialUartHandle->rx.callbackParam, &msg, kStatus_SerialManager_Success);
+        }
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+        transfer.data     = &serialUartHandle->rx.readBuffer[0];
+        transfer.dataSize = sizeof(serialUartHandle->rx.readBuffer);
+        if (kStatus_HAL_UartSuccess ==
+            HAL_UartTransferReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
+#else
+        if ((hal_uart_status_t)kStatus_HAL_UartSuccess ==
+            HAL_UartReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                       &serialUartHandle->rx.readBuffer[0], sizeof(serialUartHandle->rx.readBuffer)))
+#endif
+        {
+            serialUartHandle->rx.busy = 1U;
+        }
+        else
+        {
+            serialUartHandle->rx.busy = 0U;
+        }
+    }
+    else if ((hal_uart_status_t)kStatus_HAL_UartTxIdle == status)
+    {
+        if (serialUartHandle->tx.busy != 0U)
+        {
+            serialUartHandle->tx.busy = 0U;
+            if ((NULL != serialUartHandle->tx.callback))
+            {
+                msg.buffer = serialUartHandle->tx.buffer;
+                msg.length = serialUartHandle->tx.length;
+                serialUartHandle->tx.callback(serialUartHandle->tx.callbackParam, &msg, kStatus_SerialManager_Success);
+            }
+        }
+    }
+    else
+    {
+    }
+}
+#endif
+
+serial_manager_status_t Serial_UartInit(serial_handle_t serialHandle, void *serialConfig)
+{
+    serial_uart_state_t *serialUartHandle;
+    serial_port_uart_config_t *uartConfig;
+    hal_uart_config_t config;
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    hal_uart_transfer_t transfer;
+#endif
+#endif
+
+    assert(serialConfig);
+    assert(serialHandle);
+    assert(SERIAL_PORT_UART_HANDLE_SIZE >= sizeof(serial_uart_state_t));
+
+    uartConfig       = (serial_port_uart_config_t *)serialConfig;
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    config.baudRate_Bps = uartConfig->baudRate;
+    config.parityMode   = (hal_uart_parity_mode_t)uartConfig->parityMode;
+    config.stopBitCount = (hal_uart_stop_bit_count_t)uartConfig->stopBitCount;
+    config.enableRx     = uartConfig->enableRx;
+    config.enableTx     = uartConfig->enableTx;
+    config.srcClock_Hz  = uartConfig->clockRate;
+    config.instance     = uartConfig->instance;
+
+    if (kStatus_HAL_UartSuccess != HAL_UartInit(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &config))
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    if (kStatus_HAL_UartSuccess !=
+        HAL_UartTransferInstallCallback(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                        Serial_UartCallback, serialUartHandle))
+#else
+    if (kStatus_HAL_UartSuccess != HAL_UartInstallCallback(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                                           Serial_UartCallback, serialUartHandle))
+#endif
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+    if (uartConfig->enableRx != 0U)
+    {
+        serialUartHandle->rx.busy = 1U;
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+        transfer.data     = &serialUartHandle->rx.readBuffer[0];
+        transfer.dataSize = sizeof(serialUartHandle->rx.readBuffer);
+        if (kStatus_HAL_UartSuccess !=
+            HAL_UartTransferReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
+#else
+        if (kStatus_HAL_UartSuccess !=
+            HAL_UartReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                       &serialUartHandle->rx.readBuffer[0], sizeof(serialUartHandle->rx.readBuffer)))
+#endif
+        {
+            serialUartHandle->rx.busy = 0U;
+            return kStatus_SerialManager_Error;
+        }
+    }
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t Serial_UartDeinit(serial_handle_t serialHandle)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    (void)HAL_UartTransferAbortReceive(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+#else
+    (void)HAL_UartAbortReceive(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+#endif
+#endif
+    (void)HAL_UartDeinit(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serialUartHandle->tx.busy = 0U;
+    serialUartHandle->rx.busy = 0U;
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+serial_manager_status_t Serial_UartWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_uart_state_t *serialUartHandle;
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    hal_uart_transfer_t transfer;
+#endif
+
+    assert(serialHandle);
+    assert(buffer);
+    assert(length);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    if (serialUartHandle->tx.busy != 0U)
+    {
+        return kStatus_SerialManager_Busy;
+    }
+    serialUartHandle->tx.busy = 1U;
+
+    serialUartHandle->tx.buffer = buffer;
+    serialUartHandle->tx.length = length;
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    transfer.data     = buffer;
+    transfer.dataSize = length;
+    if (kStatus_HAL_UartSuccess !=
+        HAL_UartTransferSendNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
+#else
+    if (kStatus_HAL_UartSuccess !=
+        HAL_UartSendNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), buffer, length))
+#endif
+    {
+        serialUartHandle->tx.busy = 0U;
+        return kStatus_SerialManager_Error;
+    }
+    return kStatus_SerialManager_Success;
+}
+
+#else
+
+serial_manager_status_t Serial_UartWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+    assert(buffer);
+    assert(length);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    return (serial_manager_status_t)HAL_UartSendBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                                         buffer, length);
+}
+
+serial_manager_status_t Serial_UartRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+    assert(buffer);
+    assert(length);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    return (serial_manager_status_t)HAL_UartReceiveBlocking(
+        ((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), buffer, length);
+}
+
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_UartCancelWrite(serial_handle_t serialHandle)
+{
+    serial_uart_state_t *serialUartHandle;
+    serial_manager_callback_message_t msg;
+    uint32_t primask;
+    uint8_t isBusy = 0U;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    primask                   = DisableGlobalIRQ();
+    isBusy                    = serialUartHandle->tx.busy;
+    serialUartHandle->tx.busy = 0U;
+    EnableGlobalIRQ(primask);
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    (void)HAL_UartTransferAbortSend(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+#else
+    (void)HAL_UartAbortSend(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+#endif
+    if (isBusy != 0U)
+    {
+        if ((NULL != serialUartHandle->tx.callback))
+        {
+            msg.buffer = serialUartHandle->tx.buffer;
+            msg.length = serialUartHandle->tx.length;
+            serialUartHandle->tx.callback(serialUartHandle->tx.callbackParam, &msg, kStatus_SerialManager_Canceled);
+        }
+    }
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t Serial_UartInstallTxCallback(serial_handle_t serialHandle,
+                                                     serial_manager_callback_t callback,
+                                                     void *callbackParam)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    serialUartHandle->tx.callback      = callback;
+    serialUartHandle->tx.callbackParam = callbackParam;
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t Serial_UartInstallRxCallback(serial_handle_t serialHandle,
+                                                     serial_manager_callback_t callback,
+                                                     void *callbackParam)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    serialUartHandle->rx.callback      = callback;
+    serialUartHandle->rx.callbackParam = callbackParam;
+
+    return kStatus_SerialManager_Success;
+}
+
+void Serial_UartIsrFunction(serial_handle_t serialHandle)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    HAL_UartIsrFunction(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+}
+#endif
+
+#endif
diff --git a/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_uart.h b/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_uart.h
new file mode 100755
index 0000000..2d5d21e
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/components/serial_manager/serial_port_uart.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SERIAL_PORT_UART_H__
+#define __SERIAL_PORT_UART_H__
+
+/*!
+ * @addtogroup serial_port_uart
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*! @brief serial port uart handle size*/
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#define SERIAL_PORT_UART_HANDLE_SIZE (166U)
+#else
+#define SERIAL_PORT_UART_HANDLE_SIZE (4U)
+#endif
+
+/*! @brief serial port uart parity mode*/
+typedef enum _serial_port_uart_parity_mode
+{
+    kSerialManager_UartParityDisabled = 0x0U, /*!< Parity disabled */
+    kSerialManager_UartParityEven     = 0x1U, /*!< Parity even enabled */
+    kSerialManager_UartParityOdd      = 0x2U, /*!< Parity odd enabled */
+} serial_port_uart_parity_mode_t;
+
+/*! @brief serial port uart stop bit count*/
+typedef enum _serial_port_uart_stop_bit_count
+{
+    kSerialManager_UartOneStopBit = 0U, /*!< One stop bit */
+    kSerialManager_UartTwoStopBit = 1U, /*!< Two stop bits */
+} serial_port_uart_stop_bit_count_t;
+
+/*! @brief serial port uart config struct*/
+typedef struct _serial_port_uart_config
+{
+    uint32_t clockRate;                             /*!< clock rate  */
+    uint32_t baudRate;                              /*!< baud rate  */
+    serial_port_uart_parity_mode_t parityMode;      /*!< Parity mode, disabled (default), even, odd */
+    serial_port_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
+    uint8_t instance;                               /*!< Instance (0 - UART0, 1 - UART1, ...), detail information
+                                                         please refer to the SOC corresponding RM. */
+    uint8_t enableRx;                               /*!< Enable RX */
+    uint8_t enableTx;                               /*!< Enable TX */
+} serial_port_uart_config_t;
+/*! @} */
+#endif /* __SERIAL_PORT_UART_H__ */
diff --git a/third_party/nxp/JN5189DK6/components/uart/uart.h b/third_party/nxp/JN5189DK6/components/uart/uart.h
new file mode 100755
index 0000000..11db5c4
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/components/uart/uart.h
@@ -0,0 +1,475 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HAL_UART_ADAPTER_H__
+#define __HAL_UART_ADAPTER_H__
+
+#if defined(FSL_RTOS_FREE_RTOS)
+#include "FreeRTOS.h"
+#endif
+
+/*!
+ * @addtogroup UART_Adapter
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Enable or disable UART adapter non-blocking mode (1 - enable, 0 - disable) */
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+#define UART_ADAPTER_NON_BLOCKING_MODE (1U)
+#else
+#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
+#define UART_ADAPTER_NON_BLOCKING_MODE (0U)
+#else
+#define UART_ADAPTER_NON_BLOCKING_MODE SERIAL_MANAGER_NON_BLOCKING_MODE
+#endif
+#endif
+
+#if defined(__GIC_PRIO_BITS)
+#define HAL_UART_ISR_PRIORITY (25U)
+#else
+#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
+#define HAL_UART_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
+#else
+/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
+ * The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
+ * priority is 3 (2^2 - 1). So, the default value is 3.
+ */
+#define HAL_UART_ISR_PRIORITY (3U)
+#endif
+#endif
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+#define HAL_UART_HANDLE_SIZE (90U)
+#else
+#define HAL_UART_HANDLE_SIZE (4U)
+#endif
+
+/*! @brief Whether enable transactional function of the UART. (0 - disable, 1 - enable) */
+#define HAL_UART_TRANSFER_MODE (0U)
+
+typedef void *hal_uart_handle_t;
+
+/*! @brief UART status */
+typedef enum _hal_uart_status
+{
+    kStatus_HAL_UartSuccess = kStatus_Success,                       /*!< Successfully */
+    kStatus_HAL_UartTxBusy  = MAKE_STATUS(kStatusGroup_HAL_UART, 1), /*!< TX busy */
+    kStatus_HAL_UartRxBusy  = MAKE_STATUS(kStatusGroup_HAL_UART, 2), /*!< RX busy */
+    kStatus_HAL_UartTxIdle  = MAKE_STATUS(kStatusGroup_HAL_UART, 3), /*!< HAL UART transmitter is idle. */
+    kStatus_HAL_UartRxIdle  = MAKE_STATUS(kStatusGroup_HAL_UART, 4), /*!< HAL UART receiver is idle */
+    kStatus_HAL_UartBaudrateNotSupport =
+        MAKE_STATUS(kStatusGroup_HAL_UART, 5), /*!< Baudrate is not support in current clock source */
+    kStatus_HAL_UartProtocolError = MAKE_STATUS(
+        kStatusGroup_HAL_UART,
+        6),                                                        /*!< Error occurs for Noise, Framing, Parity, etc.
+                                                                        For transactional transfer, The up layer needs to abort the transfer and then starts again */
+    kStatus_HAL_UartError = MAKE_STATUS(kStatusGroup_HAL_UART, 7), /*!< Error occurs on HAL UART */
+} hal_uart_status_t;
+
+/*! @brief UART parity mode. */
+typedef enum _hal_uart_parity_mode
+{
+    kHAL_UartParityDisabled = 0x0U, /*!< Parity disabled */
+    kHAL_UartParityEven     = 0x1U, /*!< Parity even enabled */
+    kHAL_UartParityOdd      = 0x2U, /*!< Parity odd enabled */
+} hal_uart_parity_mode_t;
+
+/*! @brief UART stop bit count. */
+typedef enum _hal_uart_stop_bit_count
+{
+    kHAL_UartOneStopBit = 0U, /*!< One stop bit */
+    kHAL_UartTwoStopBit = 1U, /*!< Two stop bits */
+} hal_uart_stop_bit_count_t;
+
+/*! @brief UART configuration structure. */
+typedef struct _hal_uart_config
+{
+    uint32_t srcClock_Hz;                   /*!< Source clock */
+    uint32_t baudRate_Bps;                  /*!< Baud rate  */
+    hal_uart_parity_mode_t parityMode;      /*!< Parity mode, disabled (default), even, odd */
+    hal_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
+    uint8_t enableRx;                       /*!< Enable RX */
+    uint8_t enableTx;                       /*!< Enable TX */
+    uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information please refer to the
+                           SOC corresponding RM.
+                           Invalid instance value will cause initialization failure. */
+} hal_uart_config_t;
+
+/*! @brief UART transfer callback function. */
+typedef void (*hal_uart_transfer_callback_t)(hal_uart_handle_t handle, hal_uart_status_t status, void *callbackParam);
+
+/*! @brief UART transfer structure. */
+typedef struct _hal_uart_transfer
+{
+    uint8_t *data;   /*!< The buffer of data to be transfer.*/
+    size_t dataSize; /*!< The byte count to be transfer. */
+} hal_uart_transfer_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Initializes a UART instance with the UART handle and the user configuration structure.
+ *
+ * This function configures the UART module with user-defined settings. The user can configure the configuration
+ * structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by
+ * the caller. Example below shows how to use this API to configure the UART.
+ *  @code
+ *   uint8_t g_UartHandleBuffer[HAL_UART_HANDLE_SIZE];
+ *   hal_uart_handle_t g_UartHandle = &g_UartHandleBuffer[0];
+ *   hal_uart_config_t config;
+ *   config.srcClock_Hz = 48000000;
+ *   config.baudRate_Bps = 115200U;
+ *   config.parityMode = kHAL_UartParityDisabled;
+ *   config.stopBitCount = kHAL_UartOneStopBit;
+ *   config.enableRx = 1;
+ *   config.enableTx = 1;
+ *   config.instance = 0;
+ *   HAL_UartInit(g_UartHandle, &config);
+ *  @endcode
+ *
+ * @param handle Pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by the caller.
+ * @param config Pointer to user-defined configuration structure.
+ * @retval kStatus_HAL_UartBaudrateNotSupport Baudrate is not support in current clock source.
+ * @retval kStatus_HAL_UartSuccess UART initialization succeed
+ */
+hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, hal_uart_config_t *config);
+
+/*!
+ * @brief Deinitializes a UART instance.
+ *
+ * This function waits for TX complete, disables TX and RX, and disables the UART clock.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_HAL_UartSuccess UART de-initialization succeed
+ */
+hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle);
+
+/*! @}*/
+
+/*!
+ * @name Blocking bus Operations
+ * @{
+ */
+
+/*!
+ * @brief Reads RX data register using a blocking method.
+ *
+ * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
+ * have data, and reads data from the RX register.
+ *
+ * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking
+ * cannot be used at the same time.
+ * And, the function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of this function.
+ *
+ * @param handle UART handle pointer.
+ * @param data Start address of the buffer to store the received data.
+ * @param length Size of the buffer.
+ * @retval kStatus_HAL_UartError An error occurred while receiving data.
+ * @retval kStatus_HAL_UartParityError A parity error occurred while receiving data.
+ * @retval kStatus_HAL_UartSuccess Successfully received all data.
+ */
+hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
+
+/*!
+ * @brief Writes to the TX register using a blocking method.
+ *
+ * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
+ * to have room and writes data to the TX buffer.
+ *
+ * @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking
+ * cannot be used at the same time.
+ * And, the function #HAL_UartTransferAbortSend cannot be used to abort the transmission of this function.
+ *
+ * @param handle UART handle pointer.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ * @retval kStatus_HAL_UartSuccess Successfully sent all data.
+ */
+hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length);
+
+/*! @}*/
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+
+/*!
+ * @name Transactional
+ * @note The transactional API and the functional API cannot be used at the same time. The macro
+ * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
+ * functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
+ * @{
+ */
+
+/*!
+ * @brief Installs a callback and callback parameter.
+ *
+ * This function is used to install the callback and callback parameter for UART module.
+ * When any status of the UART changed, the driver will notify the upper layer by the installed callback
+ * function. And the status is also passed as status parameter when the callback is called.
+ *
+ * @param handle UART handle pointer.
+ * @param callback The callback function.
+ * @param callbackParam The parameter of the callback function.
+ * @retval kStatus_HAL_UartSuccess Successfully install the callback.
+ */
+hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
+                                                  hal_uart_transfer_callback_t callback,
+                                                  void *callbackParam);
+
+/*!
+ * @brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be received.
+ * The receive request is saved by the UART driver.
+ * When the new data arrives, the receive request is serviced first.
+ * When all data is received, the UART driver notifies the upper layer
+ * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
+ *
+ * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking
+ * cannot be used at the same time.
+ *
+ * @param handle UART handle pointer.
+ * @param transfer UART transfer structure, see #hal_uart_transfer_t.
+ * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
+ * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
+ * @retval kStatus_HAL_UartError An error occurred.
+ */
+hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
+
+/*!
+ * @brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the ISR, the UART driver calls the callback
+ * function and passes the @ref kStatus_UART_TxIdle as status parameter.
+ *
+ * @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking
+ * cannot be used at the same time.
+ *
+ * @param handle UART handle pointer.
+ * @param transfer UART transfer structure. See #hal_uart_transfer_t.
+ * @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
+ * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
+ * @retval kStatus_HAL_UartError An error occurred.
+ */
+hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
+
+/*!
+ * @brief Gets the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * @param handle UART handle pointer.
+ * @param count Receive bytes count.
+ * @retval kStatus_HAL_UartError An error occurred.
+ * @retval kStatus_Success Get successfully through the parameter \p count.
+ */
+hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count);
+
+/*!
+ * @brief Gets the number of bytes written to the UART TX register.
+ *
+ * This function gets the number of bytes written to the UART TX
+ * register by using the interrupt method.
+ *
+ * @param handle UART handle pointer.
+ * @param count Send bytes count.
+ * @retval kStatus_HAL_UartError An error occurred.
+ * @retval kStatus_Success Get successfully through the parameter \p count.
+ */
+hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count);
+
+/*!
+ * @brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
+ * how many bytes are not received yet.
+ *
+ * @note The function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of
+ * the function #HAL_UartReceiveBlocking.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_Success Get successfully abort the receiving.
+ */
+hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle);
+
+/*!
+ * @brief Aborts the interrupt-driven data sending.
+ *
+ * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
+ * how many bytes are not sent out.
+ *
+ * @note The function #HAL_UartTransferAbortSend cannot be used to abort the transmission of
+ * the function #HAL_UartSendBlocking.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_Success Get successfully abort the sending.
+ */
+hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle);
+
+/*! @}*/
+
+#else
+
+/*!
+ * @name Functional API with non-blocking mode.
+ * @note The functional API and the transactional API cannot be used at the same time. The macro
+ * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
+ * functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
+ * @{
+ */
+
+/*!
+ * @brief Installs a callback and callback parameter.
+ *
+ * This function is used to install the callback and callback parameter for UART module.
+ * When non-blocking sending or receiving finished, the adapter will notify the upper layer by the installed callback
+ * function. And the status is also passed as status parameter when the callback is called.
+ *
+ * @param handle UART handle pointer.
+ * @param callback The callback function.
+ * @param callbackParam The parameter of the callback function.
+ * @retval kStatus_HAL_UartSuccess Successfully install the callback.
+ */
+hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
+                                          hal_uart_transfer_callback_t callback,
+                                          void *callbackParam);
+
+/*!
+ * @brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be received.
+ * The receive request is saved by the UART adapter.
+ * When the new data arrives, the receive request is serviced first.
+ * When all data is received, the UART adapter notifies the upper layer
+ * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
+ *
+ * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartReceiveNonBlocking
+ * cannot be used at the same time.
+ *
+ * @param handle UART handle pointer.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
+ * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
+ * @retval kStatus_HAL_UartError An error occurred.
+ */
+hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
+
+/*!
+ * @brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the ISR, the UART driver calls the callback
+ * function and passes the @ref kStatus_UART_TxIdle as status parameter.
+ *
+ * @note The function #HAL_UartSendBlocking and the function #HAL_UartSendNonBlocking
+ * cannot be used at the same time.
+ *
+ * @param handle UART handle pointer.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ * @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
+ * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
+ * @retval kStatus_HAL_UartError An error occurred.
+ */
+hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
+
+/*!
+ * @brief Gets the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * @param handle UART handle pointer.
+ * @param count Receive bytes count.
+ * @retval kStatus_HAL_UartError An error occurred.
+ * @retval kStatus_Success Get successfully through the parameter \p count.
+ */
+hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount);
+
+/*!
+ * @brief Gets the number of bytes written to the UART TX register.
+ *
+ * This function gets the number of bytes written to the UART TX
+ * register by using the interrupt method.
+ *
+ * @param handle UART handle pointer.
+ * @param count Send bytes count.
+ * @retval kStatus_HAL_UartError An error occurred.
+ * @retval kStatus_Success Get successfully through the parameter \p count.
+ */
+hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount);
+
+/*!
+ * @brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
+ * how many bytes are not received yet.
+ *
+ * @note The function #HAL_UartAbortReceive cannot be used to abort the transmission of
+ * the function #HAL_UartReceiveBlocking.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_Success Get successfully abort the receiving.
+ */
+hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle);
+
+/*!
+ * @brief Aborts the interrupt-driven data sending.
+ *
+ * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
+ * how many bytes are not sent out.
+ *
+ * @note The function #HAL_UartAbortSend cannot be used to abort the transmission of
+ * the function #HAL_UartSendBlocking.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_Success Get successfully abort the sending.
+ */
+hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle);
+
+/*! @}*/
+
+#endif
+#endif
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+/*!
+ * @brief UART IRQ handle function.
+ *
+ * This function handles the UART transmit and receive IRQ request.
+ *
+ * @param handle UART handle pointer.
+ */
+void HAL_UartIsrFunction(hal_uart_handle_t handle);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+/*! @}*/
+#endif /* __HAL_UART_ADAPTER_H__ */
diff --git a/third_party/nxp/JN5189DK6/components/uart/usart_adapter.c b/third_party/nxp/JN5189DK6/components/uart/usart_adapter.c
new file mode 100755
index 0000000..9b04160
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/components/uart/usart_adapter.c
@@ -0,0 +1,629 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_usart.h"
+#include "fsl_flexcomm.h"
+
+#include "uart.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifndef NDEBUG
+#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
+#undef assert
+#define assert(n)
+#endif
+#endif
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+/*! @brief uart RX state structure. */
+typedef struct _hal_uart_receive_state
+{
+    volatile uint8_t *buffer;
+    volatile uint32_t bufferLength;
+    volatile uint32_t bufferSofar;
+} hal_uart_receive_state_t;
+
+/*! @brief uart TX state structure. */
+typedef struct _hal_uart_send_state
+{
+    volatile uint8_t *buffer;
+    volatile uint32_t bufferLength;
+    volatile uint32_t bufferSofar;
+} hal_uart_send_state_t;
+#endif
+/*! @brief uart state structure. */
+typedef struct _hal_uart_state
+{
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+    hal_uart_transfer_callback_t callback;
+    void *callbackParam;
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    usart_handle_t hardwareHandle;
+#endif
+    hal_uart_receive_state_t rx;
+    hal_uart_send_state_t tx;
+#endif
+    uint8_t instance;
+} hal_uart_state_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+static USART_Type *const s_UsartAdapterBase[] = USART_BASE_PTRS;
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+
+#if !(defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+/* Array of USART IRQ number. */
+static const IRQn_Type s_UsartIRQ[] = USART_IRQS;
+#endif
+
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+static hal_uart_status_t HAL_UartGetStatus(status_t status)
+{
+    hal_uart_status_t uartStatus = kStatus_HAL_UartError;
+    switch (status)
+    {
+        case kStatus_Success:
+            uartStatus = kStatus_HAL_UartSuccess;
+            break;
+        case kStatus_USART_TxBusy:
+            uartStatus = kStatus_HAL_UartTxBusy;
+            break;
+        case kStatus_USART_RxBusy:
+            uartStatus = kStatus_HAL_UartRxBusy;
+            break;
+        case kStatus_USART_TxIdle:
+            uartStatus = kStatus_HAL_UartTxIdle;
+            break;
+        case kStatus_USART_RxIdle:
+            uartStatus = kStatus_HAL_UartRxIdle;
+            break;
+        case kStatus_USART_BaudrateNotSupport:
+            uartStatus = kStatus_HAL_UartBaudrateNotSupport;
+            break;
+        case kStatus_USART_NoiseError:
+        case kStatus_USART_FramingError:
+        case kStatus_USART_ParityError:
+            uartStatus = kStatus_HAL_UartProtocolError;
+            break;
+        default:
+            break;
+    }
+    return uartStatus;
+}
+#else
+static hal_uart_status_t HAL_UartGetStatus(status_t status)
+{
+    if (kStatus_Success == status)
+    {
+        return kStatus_HAL_UartSuccess;
+    }
+    else
+    {
+        return kStatus_HAL_UartError;
+    }
+}
+#endif
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+static void HAL_UartCallback(USART_Type *base, usart_handle_t *handle, status_t status, void *callbackParam)
+{
+    hal_uart_state_t *uartHandle;
+    hal_uart_status_t uartStatus = HAL_UartGetStatus(status);
+    assert(callbackParam);
+
+    uartHandle = (hal_uart_state_t *)callbackParam;
+
+    if (kStatus_HAL_UartProtocolError == uartStatus)
+    {
+        if (uartHandle->hardwareHandle.rxDataSize)
+        {
+            uartStatus = kStatus_HAL_UartError;
+        }
+    }
+
+    if (uartHandle->callback)
+    {
+        uartHandle->callback(uartHandle, uartStatus, uartHandle->callbackParam);
+    }
+}
+
+#else
+
+static void HAL_UartInterruptHandle(USART_Type *base, void *handle)
+{
+    hal_uart_state_t *uartHandle = (hal_uart_state_t *)handle;
+    uint32_t status;
+    uint8_t instance;
+
+    if (NULL == uartHandle)
+    {
+        return;
+    }
+    instance = uartHandle->instance;
+
+    status = USART_GetStatusFlags(s_UsartAdapterBase[instance]);
+
+    /* Receive data register full */
+    if ((USART_FIFOSTAT_RXNOTEMPTY_MASK & status) &&
+        (USART_GetEnabledInterrupts(s_UsartAdapterBase[instance]) & USART_FIFOINTENSET_RXLVL_MASK))
+    {
+        if (uartHandle->rx.buffer)
+        {
+            uartHandle->rx.buffer[uartHandle->rx.bufferSofar++] = USART_ReadByte(s_UsartAdapterBase[instance]);
+            if (uartHandle->rx.bufferSofar >= uartHandle->rx.bufferLength)
+            {
+                USART_DisableInterrupts(s_UsartAdapterBase[instance],
+                                        USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK);
+                uartHandle->rx.buffer = NULL;
+                if (uartHandle->callback)
+                {
+                    uartHandle->callback(uartHandle, kStatus_HAL_UartRxIdle, uartHandle->callbackParam);
+                }
+            }
+        }
+    }
+
+    /* Send data register empty and the interrupt is enabled. */
+    if ((USART_FIFOSTAT_TXNOTFULL_MASK & status) &&
+        (USART_GetEnabledInterrupts(s_UsartAdapterBase[instance]) & USART_FIFOINTENSET_TXLVL_MASK))
+    {
+        if (uartHandle->tx.buffer)
+        {
+            USART_WriteByte(s_UsartAdapterBase[instance], uartHandle->tx.buffer[uartHandle->tx.bufferSofar++]);
+            if (uartHandle->tx.bufferSofar >= uartHandle->tx.bufferLength)
+            {
+                USART_DisableInterrupts(s_UsartAdapterBase[instance], USART_FIFOINTENCLR_TXLVL_MASK);
+                uartHandle->tx.buffer = NULL;
+                if (uartHandle->callback)
+                {
+                    uartHandle->callback(uartHandle, kStatus_HAL_UartTxIdle, uartHandle->callbackParam);
+                }
+            }
+        }
+    }
+
+#if 1
+    USART_ClearStatusFlags(s_UsartAdapterBase[instance], status);
+#endif
+}
+#endif
+
+#endif
+
+hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, hal_uart_config_t *config)
+{
+    hal_uart_state_t *uartHandle;
+    usart_config_t usartConfig;
+    status_t status;
+    assert(handle);
+    assert(config);
+    assert(config->instance < (sizeof(s_UsartAdapterBase) / sizeof(USART_Type *)));
+    assert(s_UsartAdapterBase[config->instance]);
+
+    if (HAL_UART_HANDLE_SIZE < sizeof(hal_uart_state_t))
+    {
+        return kStatus_HAL_UartError;
+    }
+
+    USART_GetDefaultConfig(&usartConfig);
+    usartConfig.baudRate_Bps = config->baudRate_Bps;
+
+    if (kHAL_UartParityEven == config->parityMode)
+    {
+        usartConfig.parityMode = kUSART_ParityEven;
+    }
+    else if (kHAL_UartParityOdd == config->parityMode)
+    {
+        usartConfig.parityMode = kUSART_ParityOdd;
+    }
+    else
+    {
+        usartConfig.parityMode = kUSART_ParityDisabled;
+    }
+
+    if (kHAL_UartTwoStopBit == config->stopBitCount)
+    {
+        usartConfig.stopBitCount = kUSART_TwoStopBit;
+    }
+    else
+    {
+        usartConfig.stopBitCount = kUSART_OneStopBit;
+    }
+    usartConfig.enableRx    = config->enableRx;
+    usartConfig.enableTx    = config->enableTx;
+    usartConfig.txWatermark = kUSART_TxFifo0;
+    usartConfig.rxWatermark = kUSART_RxFifo1;
+
+    status = USART_Init(s_UsartAdapterBase[config->instance], &usartConfig, config->srcClock_Hz);
+
+    if (kStatus_Success != status)
+    {
+        return HAL_UartGetStatus(status);
+    }
+
+    uartHandle           = (hal_uart_state_t *)handle;
+    uartHandle->instance = config->instance;
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    USART_TransferCreateHandle(s_UsartAdapterBase[config->instance], &uartHandle->hardwareHandle,
+                               (usart_transfer_callback_t)HAL_UartCallback, handle);
+#else
+    /* Enable interrupt in NVIC. */
+    FLEXCOMM_SetIRQHandler(s_UsartAdapterBase[config->instance], (flexcomm_irq_handler_t)HAL_UartInterruptHandle,
+                           handle);
+    NVIC_SetPriority((IRQn_Type)s_UsartIRQ[config->instance], HAL_UART_ISR_PRIORITY);
+    EnableIRQ(s_UsartIRQ[config->instance]);
+#endif
+
+#endif
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+
+    assert(handle);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    USART_Deinit(s_UsartAdapterBase[uartHandle->instance]);
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(data);
+    assert(length);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+    if (uartHandle->rx.buffer)
+    {
+        return kStatus_HAL_UartRxBusy;
+    }
+#endif
+
+    status = USART_ReadBlocking(s_UsartAdapterBase[uartHandle->instance], data, length);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(data);
+    assert(length);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+    if (uartHandle->tx.buffer)
+    {
+        return kStatus_HAL_UartTxBusy;
+    }
+#endif
+
+    USART_WriteBlocking(s_UsartAdapterBase[uartHandle->instance], data, length);
+
+    return kStatus_HAL_UartSuccess;
+}
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+
+hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
+                                                  hal_uart_transfer_callback_t callback,
+                                                  void *callbackParam)
+{
+    hal_uart_state_t *uartHandle;
+
+    assert(handle);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    uartHandle->callbackParam = callbackParam;
+    uartHandle->callback      = callback;
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(transfer);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    status = USART_TransferReceiveNonBlocking(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle,
+                                              (usart_transfer_t *)transfer, NULL);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(transfer);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    status = USART_TransferSendNonBlocking(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle,
+                                           (usart_transfer_t *)transfer);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(count);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    status =
+        USART_TransferGetReceiveCount(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(count);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    status = USART_TransferGetSendCount(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    USART_TransferAbortReceive(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    USART_TransferAbortSend(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
+
+    return kStatus_HAL_UartSuccess;
+}
+
+#else
+
+/* None transactional API with non-blocking mode. */
+hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
+                                          hal_uart_transfer_callback_t callback,
+                                          void *callbackParam)
+{
+    hal_uart_state_t *uartHandle;
+
+    assert(handle);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    uartHandle->callbackParam = callbackParam;
+    uartHandle->callback      = callback;
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(data);
+    assert(length);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->rx.buffer)
+    {
+        return kStatus_HAL_UartRxBusy;
+    }
+
+    uartHandle->rx.bufferLength = length;
+    uartHandle->rx.bufferSofar  = 0;
+    uartHandle->rx.buffer       = data;
+    USART_EnableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENSET_RXLVL_MASK);
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(data);
+    assert(length);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->tx.buffer)
+    {
+        return kStatus_HAL_UartTxBusy;
+    }
+    uartHandle->tx.bufferLength = length;
+    uartHandle->tx.bufferSofar  = 0;
+    uartHandle->tx.buffer       = (volatile uint8_t *)data;
+    USART_EnableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENSET_TXLVL_MASK);
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(reCount);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->rx.buffer)
+    {
+        *reCount = uartHandle->rx.bufferSofar;
+        return kStatus_HAL_UartSuccess;
+    }
+    return kStatus_HAL_UartError;
+}
+
+hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(seCount);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->tx.buffer)
+    {
+        *seCount = uartHandle->tx.bufferSofar;
+        return kStatus_HAL_UartSuccess;
+    }
+    return kStatus_HAL_UartError;
+}
+
+hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->rx.buffer)
+    {
+        USART_DisableInterrupts(s_UsartAdapterBase[uartHandle->instance],
+                                USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK);
+        uartHandle->rx.buffer = NULL;
+    }
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->tx.buffer)
+    {
+        USART_DisableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENCLR_TXLVL_MASK);
+        uartHandle->tx.buffer = NULL;
+    }
+
+    return kStatus_HAL_UartSuccess;
+}
+
+#endif
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+
+void HAL_UartIsrFunction(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+#if 0
+    DisableIRQ(s_UsartIRQ[uartHandle->instance]);
+#endif
+    USART_TransferHandleIRQ(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
+#if 0
+    NVIC_SetPriority((IRQn_Type)s_UsartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY);
+    EnableIRQ(s_UsartIRQ[uartHandle->instance]);
+#endif
+}
+
+#else
+
+void HAL_UartIsrFunction(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+#if 0
+    DisableIRQ(s_UsartIRQ[uartHandle->instance]);
+#endif
+    HAL_UartInterruptHandle(s_UsartAdapterBase[uartHandle->instance], (void *)uartHandle);
+#if 0
+    NVIC_SetPriority((IRQn_Type)s_UsartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY);
+    EnableIRQ(s_UsartIRQ[uartHandle->instance]);
+#endif
+}
+
+#endif
+
+#endif
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/JN5189.h b/third_party/nxp/JN5189DK6/devices/JN5189/JN5189.h
new file mode 100755
index 0000000..c171daa
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/JN5189.h
@@ -0,0 +1,14891 @@
+/*
+** ###################################################################
+**     Processors:          JN5188HN
+**                          JN5188THN
+**                          JN5189HN
+**                          JN5189THN
+**
+**     Compilers:           GNU C Compiler
+**                          IAR ANSI C/C++ Compiler for ARM
+**                          Keil ARM C/C++ Compiler
+**                          MCUXpresso Compiler
+**
+**     Reference manual:    JN5189UM_Rev.1.2 20 December 2018
+**     Version:             rev. 1.0, 2018-07-31
+**     Build:               b191225
+**
+**     Abstract:
+**         CMSIS Peripheral Access Layer for JN5189
+**
+**     Copyright 1997-2016 Freescale Semiconductor, Inc.
+**     Copyright 2016-2019 NXP
+**     All rights reserved.
+**
+**     SPDX-License-Identifier: BSD-3-Clause
+**
+**     http:                 www.nxp.com
+**     mail:                 support@nxp.com
+**
+**     Revisions:
+**     - rev. 1.0 (2018-07-31)
+**         Initial version.
+**
+** ###################################################################
+*/
+
+/*!
+ * @file JN5189.h
+ * @version 1.0
+ * @date 2018-07-31
+ * @brief CMSIS Peripheral Access Layer for JN5189
+ *
+ * CMSIS Peripheral Access Layer for JN5189
+ */
+
+#ifndef _JN5189_H_
+#define _JN5189_H_                               /**< Symbol preventing repeated inclusion */
+
+/** Memory map major version (memory maps with equal major version number are
+ * compatible) */
+#define MCU_MEM_MAP_VERSION 0x0100U
+/** Memory map minor version */
+#define MCU_MEM_MAP_VERSION_MINOR 0x0000U
+
+
+/* ----------------------------------------------------------------------------
+   -- Interrupt vector numbers
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Interrupt_vector_numbers Interrupt vector numbers
+ * @{
+ */
+
+/** Interrupt Number Definitions */
+#define NUMBER_OF_INT_VECTORS 72                 /**< Number of interrupts in the Vector table */
+
+typedef enum IRQn {
+  /* Auxiliary constants */
+  NotAvail_IRQn                = -128,             /**< Not available device specific interrupt */
+
+  /* Core interrupts */
+  NonMaskableInt_IRQn          = -14,              /**< Non Maskable Interrupt */
+  HardFault_IRQn               = -13,              /**< Cortex-M4 SV Hard Fault Interrupt */
+  MemoryManagement_IRQn        = -12,              /**< Cortex-M4 Memory Management Interrupt */
+  BusFault_IRQn                = -11,              /**< Cortex-M4 Bus Fault Interrupt */
+  UsageFault_IRQn              = -10,              /**< Cortex-M4 Usage Fault Interrupt */
+  SVCall_IRQn                  = -5,               /**< Cortex-M4 SV Call Interrupt */
+  DebugMonitor_IRQn            = -4,               /**< Cortex-M4 Debug Monitor Interrupt */
+  PendSV_IRQn                  = -2,               /**< Cortex-M4 Pend SV Interrupt */
+  SysTick_IRQn                 = -1,               /**< Cortex-M4 System Tick Interrupt */
+
+  /* Device specific interrupts */
+  WDT_BOD_IRQn                 = 0,                /**< System (BOD, Watchdog Timer, Flash controller) interrupt */
+  DMA0_IRQn                    = 1,                /**< DMA interrupt */
+  GINT0_IRQn                   = 2,                /**< GPIO global interrupt */
+  CIC_IRB_IRQn                 = 3,                /**< Infra Red Blaster interrupt */
+  PIN_INT0_IRQn                = 4,                /**< Pin Interrupt and Pattern matching 0 */
+  PIN_INT1_IRQn                = 5,                /**< Pin Interrupt and Pattern matching 1 */
+  PIN_INT2_IRQn                = 6,                /**< Pin Interrupt and Pattern matching 2 */
+  PIN_INT3_IRQn                = 7,                /**< Pin Interrupt and Pattern matching 3 */
+  SPIFI0_IRQn                  = 8,                /**< Quad-SPI flash interface interrupt */
+  CTIMER0_IRQn                 = 9,                /**< Counter/Timer 0 interrupt */
+  CTIMER1_IRQn                 = 10,               /**< Counter/Timer 1 interrupt */
+  FLEXCOMM0_IRQn               = 11,               /**< Flexcomm Interface 0 (USART0, FLEXCOMM0) */
+  FLEXCOMM1_IRQn               = 12,               /**< Flexcomm Interface 1 (USART1, FLEXCOMM1) */
+  FLEXCOMM2_IRQn               = 13,               /**< Flexcomm Interface 2 (I2C0, FLEXCOMM2) */
+  FLEXCOMM3_IRQn               = 14,               /**< Flexcomm Interface 3 (I2C1, FLEXCOMM3) */
+  FLEXCOMM4_IRQn               = 15,               /**< Flexcomm Interface 4 (SPI0, FLEXCOMM4) */
+  FLEXCOMM5_IRQn               = 16,               /**< Flexcomm Interface 5 (SPI5, FLEXCOMM) */
+  PWM0_IRQn                    = 17,               /**< PWM channel 0 interrupt */
+  PWM1_IRQn                    = 18,               /**< PWM channel 1 interrupt */
+  PWM2_IRQn                    = 19,               /**< PWM channel 2 interrupt */
+  PWM3_IRQn                    = 20,               /**< PWM channel 3 interrupt */
+  PWM4_IRQn                    = 21,               /**< PWM channel 4 interrupt */
+  PWM5_IRQn                    = 22,               /**< PWM channel 5 interrupt */
+  PWM6_IRQn                    = 23,               /**< PWM channel 6  interrupt */
+  PWM7_IRQn                    = 24,               /**< PWM channel 7 interrupt */
+  PWM8_IRQn                    = 25,               /**< PWM channel 8 interrupt */
+  PWM9_IRQn                    = 26,               /**< PWM channel 9 interrupt */
+  PWM10_IRQn                   = 27,               /**< PWM channel 10 interrupt */
+  FLEXCOMM6_IRQn               = 28,               /**< Flexcomm Interface6 (I2C2, FLEXCOMM6) */
+  RTC_IRQn                     = 29,               /**< Real Time Clock interrupt */
+  NFCTag_IRQn                  = 30,               /**< NFC Tag interrupt */
+  MAILBOX_IRQn                 = 31,               /**< Mailbox interrupts, Wake-up from Deep Sleep interrupt */
+  ADC0_SEQA_IRQn               = 32,               /**< ADC Sequence A interrupt */
+  ADC0_SEQB_IRQn               = 33,               /**< ADC Sequence B interrupt */
+  ADC0_THCMP_IRQn              = 34,               /**< ADC Threshold compare and overrun interrupt */
+  DMIC0_IRQn                   = 35,               /**< DMIC interrupt */
+  HWVAD0_IRQn                  = 36,               /**< Hardware Voice activity detection interrupt */
+  BLE_DP_IRQn                  = 37,               /**< BLE Data Path interrupt */
+  BLE_DP0_IRQn                 = 38,               /**< BLE Data Path interrupt 0 */
+  BLE_DP1_IRQn                 = 39,               /**< BLE Data Path interrupt 1 */
+  BLE_DP2_IRQn                 = 40,               /**< BLE Data Path interrupt 2 */
+  BLE_LL_ALL_IRQn              = 41,               /**< All BLE link layer interrupts */
+  ZIGBEE_MAC_IRQn              = 42,               /**< Zigbee MAC interrupt */
+  ZIGBEE_MODEM_IRQn            = 43,               /**< Zigbee MoDem interrupt */
+  RFP_TMU_IRQn                 = 44,               /**< RFP Timing Managemnt Unit (TMU) interrupt */
+  RFP_AGC_IRQn                 = 45,               /**< RFP AGC interrupt */
+  ISO7816_IRQn                 = 46,               /**< ISO7816 controller interrupt */
+  ANA_COMP_IRQn                = 47,               /**< Analog Comparator interrupt */
+  WAKE_UP_TIMER0_IRQn          = 48,               /**< Wake up Timer 0 interrupt */
+  WAKE_UP_TIMER1_IRQn          = 49,               /**< Wake up Timer 1 interrupt */
+  PVTVF0_AMBER_IRQn            = 50,               /**< PVT Monitor interrupt */
+  PVTVF0_RED_IRQn              = 51,               /**< PVT Monitor interrupt */
+  PVTVF1_AMBER_IRQn            = 52,               /**< PVT Monitor interrupt */
+  PVTVF1_RED_IRQn              = 53,               /**< PVT Monitor interrupt */
+  BLE_WAKE_UP_TIMER_IRQn       = 54,               /**< BLE Wake up Timer interrupt */
+  SHA_IRQn                     = 55                /**< SHA interrupt */
+} IRQn_Type;
+
+/*!
+ * @}
+ */ /* end of group Interrupt_vector_numbers */
+
+
+/* ----------------------------------------------------------------------------
+   -- Cortex M4 Core Configuration
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Cortex_Core_Configuration Cortex M4 Core Configuration
+ * @{
+ */
+
+#define __MPU_PRESENT                  1         /**< Defines if an MPU is present or not */
+#define __NVIC_PRIO_BITS               3         /**< Number of priority bits implemented in the NVIC */
+#define __Vendor_SysTickConfig         0         /**< Vendor specific implementation of SysTickConfig is defined */
+#define __FPU_PRESENT                  0         /**< Defines if an FPU is present or not */
+
+#include "core_cm4.h"                  /* Core Peripheral Access Layer */
+#include "system_JN5189.h"             /* Device specific configuration file */
+
+/*!
+ * @}
+ */ /* end of group Cortex_Core_Configuration */
+
+
+/* ----------------------------------------------------------------------------
+   -- Mapping Information
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Mapping_Information Mapping Information
+ * @{
+ */
+
+/** Mapping Information */
+/*!
+ * @addtogroup dma_request
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*!
+ * @brief Structure for the DMA hardware request
+ *
+ * Defines the structure for the DMA hardware request collections. The user can configure the
+ * hardware request to trigger the DMA transfer accordingly. The index
+ * of the hardware request varies according  to the to SoC.
+ */
+typedef enum _dma_request_source
+{
+    kDmaRequestUsart0Rx             = 0U,          /**< USART 0 RX */
+    kDmaRequestUsart0Tx             = 1U,          /**< USART 0 TX */
+    kDmaRequestUsart1Rx             = 2U,          /**< USART 1 RX */
+    kDmaRequestUsart1Tx             = 3U,          /**< USART 1 TX */
+    kDmaRequestI2c0Slave            = 4U,          /**< I2C 0 Slave */
+    kDmaRequestI2c0Master           = 5U,          /**< I2C 0 Master */
+    kDmaRequestI2c1Slave            = 6U,          /**< I2C 1 Slave */
+    kDmaRequestI2c1Master           = 7U,          /**< I2C 1 Master */
+    kDmaRequestSpi0Rx               = 8U,          /**< SPI 0 RX */
+    kDmaRequestSpi0Tx               = 9U,          /**< SPI 0 TX */
+    kDmaRequestSpi1Rx               = 10U,         /**< SPI 1 RX */
+    kDmaRequestSpi1Tx               = 11U,         /**< SPI 1 TX */
+    kDmaRequestSPIFI                = 12U,         /**< SPIFI */
+    kDmaRequestI2c2Slave            = 13U,         /**< I2C 2 Slave */
+    kDmaRequestI2c2Master           = 14U,         /**< I2C 2 Master */
+    kDmaRequestDMIC0                = 15U,         /**< DMIC Channel 0 */
+    kDmaRequestDMIC1                = 16U,         /**< DMIC Channel 1 */
+    kDmaRequestHashRx               = 17U,         /**< Hash RX */
+    kDmaRequestHashTx               = 18U,         /**< Hash TX */
+} dma_request_source_t;
+
+/* @} */
+
+
+/*!
+ * @}
+ */ /* end of group Mapping_Information */
+
+
+/* ----------------------------------------------------------------------------
+   -- Device Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Peripheral_access_layer Device Peripheral Access Layer
+ * @{
+ */
+
+
+/*
+** Start of section using anonymous unions
+*/
+
+#if defined(__ARMCC_VERSION)
+  #if (__ARMCC_VERSION >= 6010050)
+    #pragma clang diagnostic push
+  #else
+    #pragma push
+    #pragma anon_unions
+  #endif
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#elif defined(__IAR_SYSTEMS_ICC__)
+  #pragma language=extended
+#else
+  #error Not supported compiler type
+#endif
+
+/* ----------------------------------------------------------------------------
+   -- ADC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer
+ * @{
+ */
+
+/** ADC - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls., offset: 0x0 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t SEQ_CTRL[1];                       /**< ADC Conversion Sequence-A control register: Controls triggering and channel selection for conversion sequence-A. Also specifies interrupt mode for sequence-A., array offset: 0x8, array step: 0x4 */
+       uint8_t RESERVED_1[4];
+  __I  uint32_t SEQ_GDAT[1];                       /**< ADC Sequence-A Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-A., array offset: 0x10, array step: 0x4 */
+       uint8_t RESERVED_2[12];
+  __I  uint32_t DAT[8];                            /**< ADC Channel X [0:7] Data register. This register contains the result of the most recent conversion completed on channel X [0:7] ., array offset: 0x20, array step: 0x4 */
+       uint8_t RESERVED_3[16];
+  __IO uint32_t THR0_LOW;                          /**< ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x50 */
+  __IO uint32_t THR1_LOW;                          /**< ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x54 */
+  __IO uint32_t THR0_HIGH;                         /**< ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x58 */
+  __IO uint32_t THR1_HIGH;                         /**< ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x5C */
+  __IO uint32_t CHAN_THRSEL;                       /**< ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel, offset: 0x60 */
+  __IO uint32_t INTEN;                             /**< ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated., offset: 0x64 */
+  __IO uint32_t FLAGS;                             /**< ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers)., offset: 0x68 */
+  __IO uint32_t STARTUP;                           /**< ADC Startup register (typically only used by the ADC API)., offset: 0x6C */
+  __IO uint32_t GPADC_CTRL0;                       /**< Second ADC Control register : ADC internal LDO (within ADC sub-system), offset: 0x70 */
+  __IO uint32_t GPADC_CTRL1;                       /**< Third ADC Control register : ADC internal gain and offset, offset: 0x74 */
+} ADC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- ADC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ADC_Register_Masks ADC Register Masks
+ * @{
+ */
+
+/*! @name CTRL - ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls. */
+/*! @{ */
+#define ADC_CTRL_CLKDIV_MASK                     (0xFFU)
+#define ADC_CTRL_CLKDIV_SHIFT                    (0U)
+/*! CLKDIV - Reserved. No changes to this fiedl are necessary.
+ */
+#define ADC_CTRL_CLKDIV(x)                       (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_CLKDIV_SHIFT)) & ADC_CTRL_CLKDIV_MASK)
+#define ADC_CTRL_ASYNMODE_MASK                   (0x100U)
+#define ADC_CTRL_ASYNMODE_SHIFT                  (8U)
+/*! ASYNMODE - Select clock mode. 0: Synchronous mode. Not Supported. 1: Asynchronous mode. The ADC
+ *    clock is based on the output of the ADC clock divider ADCCLKSEL in the SYSCON block.
+ */
+#define ADC_CTRL_ASYNMODE(x)                     (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_ASYNMODE_SHIFT)) & ADC_CTRL_ASYNMODE_MASK)
+#define ADC_CTRL_RESOL_MASK                      (0x600U)
+#define ADC_CTRL_RESOL_SHIFT                     (9U)
+/*! RESOL - The number of bits of ADC resolution. Note, whatever the resolution setting, the ADC
+ *    data will always be shifted to use the MSBs of any ADC data words. Accuracy can be reduced to
+ *    achieve higher conversion rates. A single conversion (including one conversion in a burst or
+ *    sequence) requires the selected number of bits of resolution plus 3 ADC clocks. Remark: This field
+ *    must only be altered when the ADC is fully idle. Changing it during any kind of ADC operation
+ *    may have unpredictable results. Remark: ADC clock frequencies for various resolutions must
+ *    not exceed: - 5x the system clock rate for 12-bit resolution. - 4.3x the system clock rate for
+ *    10-bit resolution. - 3.6x the system clock for 8-bit resolution. - 3x the bus clock rate for
+ *    6-bit resolution. Settings: 0x3: 6-bit resolution. An ADC conversion requires 9 ADC clocks, plus
+ *    any clocks specified by the TSAMP field; 0x2: 8-bit resolution. An ADC conversion requires 11
+ *    ADC clocks, plus any clocks specified by the TSAMP field; 0x1:10-bit resolution. An ADC
+ *    conversion requires 13 ADC clocks, plus any clocks specified by the TSAMP field; 0x0: 12-bit
+ *    resolution. An ADC conversion requires 15 ADC clocks, plus any clocks specified by the TSAMP field.
+ */
+#define ADC_CTRL_RESOL(x)                        (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_RESOL_SHIFT)) & ADC_CTRL_RESOL_MASK)
+#define ADC_CTRL_RESOL_MASK_DIS_MASK             (0x800U)
+#define ADC_CTRL_RESOL_MASK_DIS_SHIFT            (11U)
+/*! RESOL_MASK_DIS - According RESOL bit LSB bits are automatickly masked if RESOL_MASK_DIS = 0. If
+ *    RESOL_MASK_DIS = 1, the 12bits comming from ADC are directly connect to register RESULT
+ */
+#define ADC_CTRL_RESOL_MASK_DIS(x)               (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_RESOL_MASK_DIS_SHIFT)) & ADC_CTRL_RESOL_MASK_DIS_MASK)
+#define ADC_CTRL_TSAMP_MASK                      (0x7000U)
+#define ADC_CTRL_TSAMP_SHIFT                     (12U)
+/*! TSAMP - Sample Time. The default sampling period (TSAMP = 000 ) at the start of each conversion
+ *    is 2.5 ADC clock periods. Depending on a variety of factors, including operating conditions
+ *    and the output impedance of the analog source, longer sampling times may be required. The TSAMP
+ *    field should stay to default during application The TSAMP field specifies the number of
+ *    additional ADC clock cycles, from zero to seven, by which the sample period will be extended. The
+ *    total conversion time will increase by the same number of clocks. 000 - The sample period will
+ *    be the default 2.5 ADC clocks. A complete conversion with 12-bits of accuracy will require 15
+ *    clocks. 001- The sample period will be extended by one ADC clock to a total of 3.5 clock
+ *    periods. A complete 12-bit conversion will require 16 clocks. 010 - The sample period will be
+ *    extended by two clocks to 4.5 ADC clock cycles. A complete 12-bit conversion will require 17 ADC
+ *    clocks. ... 111 - The sample period will be extended by seven clocks to 9.5 ADC clock cycles. A
+ *    complete 12-bit conversion will require 22 ADC clocks.
+ */
+#define ADC_CTRL_TSAMP(x)                        (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_TSAMP_SHIFT)) & ADC_CTRL_TSAMP_MASK)
+/*! @} */
+
+/*! @name SEQ_CTRL - ADC Conversion Sequence-A control register: Controls triggering and channel selection for conversion sequence-A. Also specifies interrupt mode for sequence-A. */
+/*! @{ */
+#define ADC_SEQ_CTRL_CHANNELS_MASK               (0xFFU)
+#define ADC_SEQ_CTRL_CHANNELS_SHIFT              (0U)
+/*! CHANNELS - Selects which one or more of the ADC channels will be sampled and converted when this
+ *    sequence is launched. A 1 in any bit of this field will cause the corresponding channel to be
+ *    included in the conversion sequence, where bit 0 corresponds to channel 0, bit 1 to channel 1
+ *    and so forth. Bit 6 is channel 6; the supply monitor. Bit 7 is channel 7; the temperature
+ *    sensor. When this conversion sequence is triggered, either by a hardware trigger or via software
+ *    command, ADC conversions will be performed on each enabled channel, in sequence, beginning
+ *    with the lowest-ordered channel. Remark: This field can ONLY be changed while SEQA_ENA (bit 31)
+ *    is LOW. It is allowed to change this field and set bit 31 in the same write.
+ */
+#define ADC_SEQ_CTRL_CHANNELS(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_CHANNELS_SHIFT)) & ADC_SEQ_CTRL_CHANNELS_MASK)
+#define ADC_SEQ_CTRL_TRIGGER_MASK                (0x3F000U)
+#define ADC_SEQ_CTRL_TRIGGER_SHIFT               (12U)
+/*! TRIGGER - Selects which of the available hardware trigger sources will cause this conversion
+ *    sequence to be initiated. Program the trigger input number in this field. Setting: 0 : PINT0; 1 :
+ *    PWM8; 2 : PWM9; 3 : ARM TX EV. Remark: In order to avoid generating a spurious trigger, it is
+ *    recommended writing to+I32 this field only when SEQA_ENA (bit 31) is low. It is safe to
+ *    change this field and set bit 31 in the same write.
+ */
+#define ADC_SEQ_CTRL_TRIGGER(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGGER_SHIFT)) & ADC_SEQ_CTRL_TRIGGER_MASK)
+#define ADC_SEQ_CTRL_TRIGPOL_MASK                (0x40000U)
+#define ADC_SEQ_CTRL_TRIGPOL_SHIFT               (18U)
+/*! TRIGPOL - Select the polarity of the selected input trigger for this conversion sequence.
+ *    Remark: In order to avoid generating a spurious trigger, it is recommended writing to this field
+ *    only when SEQA_ENA (bit 31) is low. It is safe to change this field and set bit 31 in the same
+ *    write. 0: A negative edge launches the conversion sequence on the selected trigger input. 1: A
+ *    positive edge launches the conversion sequence on the selected trigger input.
+ */
+#define ADC_SEQ_CTRL_TRIGPOL(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGPOL_SHIFT)) & ADC_SEQ_CTRL_TRIGPOL_MASK)
+#define ADC_SEQ_CTRL_SYNCBYPASS_MASK             (0x80000U)
+#define ADC_SEQ_CTRL_SYNCBYPASS_SHIFT            (19U)
+/*! SYNCBYPASS - Setting this bit allows the hardware trigger input to bypass synchronization
+ *    flip-flop stages and therefore shorten the time between the trigger input signal and the start of a
+ *    conversion. There are slightly different criteria for whether or not this bit can be set
+ *    depending on the clock operating mode: Synchronous mode (the ASYNMODE in the CTRL register = 0):
+ *    Synchronization may be bypassed (this bit may be set) if the selected trigger source is already
+ *    synchronous with the main system clock (eg. coming from an on-chip, system-clock-based timer).
+ *    Whether this bit is set or not, a trigger pulse must be maintained for at least one system
+ *    clock period. Asynchronous mode (the ASYNMODE in the CTRL register = 1): Synchronization may be
+ *    bypassed (this bit may be set) if it is certain that the duration of a trigger input pulse
+ *    will be at least one cycle of the ADC clock (regardless of whether the trigger comes from and
+ *    on-chip or off-chip source). If this bit is NOT set, the trigger pulse must at least be
+ *    maintained for one system clock period. 0: Enable trigger synchronization. The hardware trigger bypass
+ *    is not enabled. 1: Bypass trigger synchronization. The hardware trigger bypass is enabled.
+ */
+#define ADC_SEQ_CTRL_SYNCBYPASS(x)               (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SYNCBYPASS_SHIFT)) & ADC_SEQ_CTRL_SYNCBYPASS_MASK)
+#define ADC_SEQ_CTRL_START_BEHAVIOUR_MASK        (0x2000000U)
+#define ADC_SEQ_CTRL_START_BEHAVIOUR_SHIFT       (25U)
+/*! START_BEHAVIOUR - the Start behavior used on gpadc: writing 0 for repeat start after each input
+ *    selection changed, used for seqA with multiple inputs. writing 1 for continuous start, this
+ *    bit is only if seqA is used to have full speed on a single input. Remark: with 0 the word rate
+ *    is divided by two.
+ */
+#define ADC_SEQ_CTRL_START_BEHAVIOUR(x)          (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_START_BEHAVIOUR_SHIFT)) & ADC_SEQ_CTRL_START_BEHAVIOUR_MASK)
+#define ADC_SEQ_CTRL_START_MASK                  (0x4000000U)
+#define ADC_SEQ_CTRL_START_SHIFT                 (26U)
+/*! START - Writing a 1 to this field will launch one pass through this conversion sequence. The
+ *    behavior will be identical to a sequence triggered by a hardware trigger. Do not write 1 to this
+ *    bit if the BURST bit is set. Remark: This bit is only set to a 1 momentarily when written to
+ *    launch a conversion sequence. It will consequently always read back as a zero.
+ */
+#define ADC_SEQ_CTRL_START(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_START_SHIFT)) & ADC_SEQ_CTRL_START_MASK)
+#define ADC_SEQ_CTRL_BURST_MASK                  (0x8000000U)
+#define ADC_SEQ_CTRL_BURST_SHIFT                 (27U)
+/*! BURST - Writing a 1 to this bit will cause this conversion sequence to be continuously cycled
+ *    through. Other sequence A triggers will be ignored while this bit is set. Repeated conversions
+ *    can be halted by clearing this bit. The sequence currently in progress will be completed before
+ *    conversions are terminated. Note that a new sequence could begin just before BURST is cleared.
+ */
+#define ADC_SEQ_CTRL_BURST(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_BURST_SHIFT)) & ADC_SEQ_CTRL_BURST_MASK)
+#define ADC_SEQ_CTRL_SINGLESTEP_MASK             (0x10000000U)
+#define ADC_SEQ_CTRL_SINGLESTEP_SHIFT            (28U)
+/*! SINGLESTEP - When this bit is set, a hardware trigger or a write to the START bit will launch a
+ *    single conversion on the next channel in the sequence instead of the default response of
+ *    launching an entire sequence of conversions. Once all of the channels comprising a sequence have
+ *    been converted, a subsequent trigger will repeat the sequence beginning with the first enabled
+ *    channel. Interrupt generation will still occur either after each individual conversion or at
+ *    the end of the entire sequence, depending on the state of the MODE bit.
+ */
+#define ADC_SEQ_CTRL_SINGLESTEP(x)               (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SINGLESTEP_SHIFT)) & ADC_SEQ_CTRL_SINGLESTEP_MASK)
+#define ADC_SEQ_CTRL_MODE_MASK                   (0x40000000U)
+#define ADC_SEQ_CTRL_MODE_SHIFT                  (30U)
+/*! MODE - Indicates whether the primary method for retrieving conversion results for this sequence
+ *    will be accomplished via reading the global data register (SEQA_GDAT) at the end of each
+ *    conversion, or the individual channel result registers at the end of the entire sequence. Impacts
+ *    when conversion-complete interrupt/DMA trigger for sequence-A will be generated and which
+ *    overrun conditions contribute to an overrun interrupt as described below. 0: End of conversion. The
+ *    sequence A interrupt/DMA trigger will be set at the end of each individual ADC conversion
+ *    performed under sequence A. This flag will mirror the DATAVALID bit in the SEQA_GDAT register.
+ *    The OVERRUN bit in the SEQA_GDAT register will contribute to generation of an overrun
+ *    interrupt/DMA trigger if enabled. 1: End of sequence. The sequence A interrupt/DMA trigger will be set
+ *    when the entire set of sequence-A conversions completes. This flag will need to be explicitly
+ *    cleared by software or by the DMA-clear signal in this mode. The OVERRUN bit in the SEQA_GDAT
+ *    register will NOT contribute to generation of an overrun interrupt/DMA trigger since it is
+ *    assumed this register may not be utilized in this mode.
+ */
+#define ADC_SEQ_CTRL_MODE(x)                     (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_MODE_SHIFT)) & ADC_SEQ_CTRL_MODE_MASK)
+#define ADC_SEQ_CTRL_SEQ_ENA_MASK                (0x80000000U)
+#define ADC_SEQ_CTRL_SEQ_ENA_SHIFT               (31U)
+/*! SEQ_ENA - Sequence Enable. In order to avoid spuriously triggering the sequence, care should be
+ *    taken to only set the SEQA_ENA bit when the selected trigger input is in its INACTIVE state
+ *    (as defined by the TRIGPOL bit). If this condition is not met, the sequence will be triggered
+ *    immediately upon being enabled. Remark: In order to avoid spuriously triggering the sequence,
+ *    care should be taken to only set the SEQA_ENA bit when the selected trigger input is in its
+ *    INACTIVE state (as defined by the TRIGPOL bit). If this condition is not met, the sequence will be
+ *    triggered immediately upon being enabled. 0: Disabled. Sequence A is disabled. Sequence A
+ *    triggers are ignored. If this bit is cleared while sequence A is in progress, the sequence will
+ *    be halted at the end of the current conversion. After the sequence is re-enabled, a new trigger
+ *    will be required to restart the sequence beginning with the next enabled channel. 1: Enabled.
+ *    Sequence A is enabled.
+ */
+#define ADC_SEQ_CTRL_SEQ_ENA(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SEQ_ENA_SHIFT)) & ADC_SEQ_CTRL_SEQ_ENA_MASK)
+/*! @} */
+
+/* The count of ADC_SEQ_CTRL */
+#define ADC_SEQ_CTRL_COUNT                       (1U)
+
+/*! @name SEQ_GDAT - ADC Sequence-A Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-A. */
+/*! @{ */
+#define ADC_SEQ_GDAT_RESULT_MASK                 (0xFFF0U)
+#define ADC_SEQ_GDAT_RESULT_SHIFT                (4U)
+/*! RESULT - This field contains the 12-bit ADC conversion result from the most recent conversion
+ *    performed under conversion sequence associated with this register. DATAVALID = 1 indicates that
+ *    this result has not yet been read. If less than 12-bit resolultion is used the ADC result
+ *    occupies the upper MSBs and unused LSBs should be ignored.
+ */
+#define ADC_SEQ_GDAT_RESULT(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_RESULT_SHIFT)) & ADC_SEQ_GDAT_RESULT_MASK)
+#define ADC_SEQ_GDAT_THCMPRANGE_MASK             (0x30000U)
+#define ADC_SEQ_GDAT_THCMPRANGE_SHIFT            (16U)
+/*! THCMPRANGE - Threshold Range Comparison result. 0x0 = In Range: The last completed conversion
+ *    was greater than or equal to the value programmed into the designated LOW threshold register
+ *    (THRn_LOW) but less than or equal to the value programmed into the designated HIGH threshold
+ *    register (THRn_HIGH). 0x1 = Below Range: The last completed conversion on was less than the value
+ *    programmed into the designated LOW threshold register (THRn_LOW). 0x2 = Above Range: The last
+ *    completed conversion was greater than the value programmed into the designated HIGH threshold
+ *    register (THRn_HIGH). 0x3 = Reserved.
+ */
+#define ADC_SEQ_GDAT_THCMPRANGE(x)               (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPRANGE_SHIFT)) & ADC_SEQ_GDAT_THCMPRANGE_MASK)
+#define ADC_SEQ_GDAT_THCMPCROSS_MASK             (0xC0000U)
+#define ADC_SEQ_GDAT_THCMPCROSS_SHIFT            (18U)
+/*! THCMPCROSS - Threshold Crossing Comparison result. 0x0 = No threshold Crossing detected: The
+ *    most recent completed conversion on this channel had the same relationship (above or below) to
+ *    the threshold value established by the designated LOW threshold register (THRn_LOW) as did the
+ *    previous conversion on this channel. 0x1 = Reserved. 0x2 = Downward Threshold Crossing
+ *    Detected. Indicates that a threshold crossing in the downward direction has occurred - i.e. the
+ *    previous sample on this channel was above the threshold value established by the designated LOW
+ *    threshold register (THRn_LOW) and the current sample is below that threshold. 0x3 = Upward
+ *    Threshold Crossing Detected. Indicates that a threshold crossing in the upward direction has occurred
+ *    - i.e. the previous sample on this channel was below the threshold value established by the
+ *    designated LOW threshold register (THRn_LOW) and the current sample is above that threshold.
+ */
+#define ADC_SEQ_GDAT_THCMPCROSS(x)               (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPCROSS_SHIFT)) & ADC_SEQ_GDAT_THCMPCROSS_MASK)
+#define ADC_SEQ_GDAT_CHN_MASK                    (0x3C000000U)
+#define ADC_SEQ_GDAT_CHN_SHIFT                   (26U)
+/*! CHN - These bits contain the channel from which the RESULT bits were converted (e.g. 0000
+ *    identifies channel 0, 0001 channel 1, etc.).
+ */
+#define ADC_SEQ_GDAT_CHN(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_CHN_SHIFT)) & ADC_SEQ_GDAT_CHN_MASK)
+#define ADC_SEQ_GDAT_OVERRUN_MASK                (0x40000000U)
+#define ADC_SEQ_GDAT_OVERRUN_SHIFT               (30U)
+/*! OVERRUN - This bit is set if a new conversion result is loaded into the RESULT field before a
+ *    previous result has been read - i.e. while the DATAVALID bit is set. This bit is cleared, along
+ *    with the DATAVALID bit, whenever this register is read. This bit will contribute to an overrun
+ *    interrupt/DMA trigger if the MODE bit (in SEQA_CTRL) for the corresponding sequence is set to
+ *    0 (and if the overrun interrupt is enabled).
+ */
+#define ADC_SEQ_GDAT_OVERRUN(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_OVERRUN_SHIFT)) & ADC_SEQ_GDAT_OVERRUN_MASK)
+#define ADC_SEQ_GDAT_DATAVALID_MASK              (0x80000000U)
+#define ADC_SEQ_GDAT_DATAVALID_SHIFT             (31U)
+/*! DATAVALID - This bit is set to 1 at the end of each conversion when a new result is loaded into
+ *    the RESULT field. It is cleared whenever this register is read. This bit will cause a
+ *    conversion-complete interrupt for the corresponding sequence if the MODE bit (in SEQA_CTRL) for that
+ *    sequence is set to 0 (and if the interrupt is enabled).
+ */
+#define ADC_SEQ_GDAT_DATAVALID(x)                (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_DATAVALID_SHIFT)) & ADC_SEQ_GDAT_DATAVALID_MASK)
+/*! @} */
+
+/* The count of ADC_SEQ_GDAT */
+#define ADC_SEQ_GDAT_COUNT                       (1U)
+
+/*! @name DAT - ADC Channel X [0:7] Data register. This register contains the result of the most recent conversion completed on channel X [0:7] . */
+/*! @{ */
+#define ADC_DAT_RESULT_MASK                      (0xFFF0U)
+#define ADC_DAT_RESULT_SHIFT                     (4U)
+/*! RESULT - This field contains the 12-bit ADC conversion result from the most recent conversion
+ *    performed for this channel under conversion sequence associated with this register. DATAVALID =
+ *    1 indicates that this result has not yet been read. If less than 12-bit resolultion is used
+ *    the ADC result occupies the upper MSBs and unused LSBs should be ignored.
+ */
+#define ADC_DAT_RESULT(x)                        (((uint32_t)(((uint32_t)(x)) << ADC_DAT_RESULT_SHIFT)) & ADC_DAT_RESULT_MASK)
+#define ADC_DAT_THCMPRANGE_MASK                  (0x30000U)
+#define ADC_DAT_THCMPRANGE_SHIFT                 (16U)
+/*! THCMPRANGE - Threshold Range Comparison result for this channel. 0x0 = In Range: The last
+ *    completed conversion was greater than or equal to the value programmed into the designated LOW
+ *    threshold register (THRn_LOW) but less than or equal to the value programmed into the designated
+ *    HIGH threshold register (THRn_HIGH). 0x1 = Below Range: The last completed conversion on was
+ *    less than the value programmed into the designated LOW threshold register (THRn_LOW). 0x2 = Above
+ *    Range: The last completed conversion was greater than the value programmed into the
+ *    designated HIGH threshold register (THRn_HIGH). 0x3 = Reserved.
+ */
+#define ADC_DAT_THCMPRANGE(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPRANGE_SHIFT)) & ADC_DAT_THCMPRANGE_MASK)
+#define ADC_DAT_THCMPCROSS_MASK                  (0xC0000U)
+#define ADC_DAT_THCMPCROSS_SHIFT                 (18U)
+/*! THCMPCROSS - Threshold Crossing Comparison result for this channel. 0x0 = No threshold Crossing
+ *    detected: The most recent completed conversion on this channel had the same relationship
+ *    (above or below) to the threshold value established by the designated LOW threshold register
+ *    (THRn_LOW) as did the previous conversion on this channel. 0x1 = Reserved. 0x2 = Downward Threshold
+ *    Crossing Detected. Indicates that a threshold crossing in the downward direction has occurred
+ *    - i.e. the previous sample on this channel was above the threshold value established by the
+ *    designated LOW threshold register (THRn_LOW) and the current sample is below that threshold. 0x3
+ *    = Upward Threshold Crossing Detected. Indicates that a threshold crossing in the upward
+ *    direction has occurred - i.e. the previous sample on this channel was below the threshold value
+ *    established by the designated LOW threshold register (THRn_LOW) and the current sample is above
+ *    that threshold.
+ */
+#define ADC_DAT_THCMPCROSS(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPCROSS_SHIFT)) & ADC_DAT_THCMPCROSS_MASK)
+#define ADC_DAT_CHANNEL_MASK                     (0x3C000000U)
+#define ADC_DAT_CHANNEL_SHIFT                    (26U)
+/*! CHANNEL - This field is hard-coded to contain the channel number that this particular register
+ *    relates to (i.e. this field will contain 0b0000 for the DAT0 register, 0b0001 for the DAT1
+ *    register, etc)
+ */
+#define ADC_DAT_CHANNEL(x)                       (((uint32_t)(((uint32_t)(x)) << ADC_DAT_CHANNEL_SHIFT)) & ADC_DAT_CHANNEL_MASK)
+#define ADC_DAT_OVERRUN_MASK                     (0x40000000U)
+#define ADC_DAT_OVERRUN_SHIFT                    (30U)
+/*! OVERRUN - This bit is set if a new conversion result is loaded into the RESULT field before a
+ *    previous result has been read - i.e. while the DATAVALID bit is set. This bit is cleared, along
+ *    with the DATAVALID bit, whenever this register is read or when the data related to this
+ *    channel is read from the global SEQA_GDAT register. This bit will contribute to an overrun
+ *    interrupt/DMA trigger if the MODE bit (in SEQA_CTRL) for the corresponding sequence is set to 0 (and if
+ *    the overrun interrupt is enabled).
+ */
+#define ADC_DAT_OVERRUN(x)                       (((uint32_t)(((uint32_t)(x)) << ADC_DAT_OVERRUN_SHIFT)) & ADC_DAT_OVERRUN_MASK)
+#define ADC_DAT_DATAVALID_MASK                   (0x80000000U)
+#define ADC_DAT_DATAVALID_SHIFT                  (31U)
+/*! DATAVALID - This bit is set to 1 at the end of each conversion for this channel when a new
+ *    result is loaded into the RESULT field. It is cleared whenever this register is read or when the
+ *    data related to this channel is read from the global SEQA_GDAT regsiter.
+ */
+#define ADC_DAT_DATAVALID(x)                     (((uint32_t)(((uint32_t)(x)) << ADC_DAT_DATAVALID_SHIFT)) & ADC_DAT_DATAVALID_MASK)
+/*! @} */
+
+/* The count of ADC_DAT */
+#define ADC_DAT_COUNT                            (8U)
+
+/*! @name THR0_LOW - ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */
+/*! @{ */
+#define ADC_THR0_LOW_THRLOW_MASK                 (0xFFF0U)
+#define ADC_THR0_LOW_THRLOW_SHIFT                (4U)
+/*! THRLOW - Low threshold value against which ADC results will be compared
+ */
+#define ADC_THR0_LOW_THRLOW(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_THR0_LOW_THRLOW_SHIFT)) & ADC_THR0_LOW_THRLOW_MASK)
+/*! @} */
+
+/*! @name THR1_LOW - ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */
+/*! @{ */
+#define ADC_THR1_LOW_THRLOW_MASK                 (0xFFF0U)
+#define ADC_THR1_LOW_THRLOW_SHIFT                (4U)
+/*! THRLOW - Low threshold value against which ADC results will be compared
+ */
+#define ADC_THR1_LOW_THRLOW(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_THR1_LOW_THRLOW_SHIFT)) & ADC_THR1_LOW_THRLOW_MASK)
+/*! @} */
+
+/*! @name THR0_HIGH - ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */
+/*! @{ */
+#define ADC_THR0_HIGH_THRHIGH_MASK               (0xFFF0U)
+#define ADC_THR0_HIGH_THRHIGH_SHIFT              (4U)
+/*! THRHIGH - High threshold value against which ADC results will be compared
+ */
+#define ADC_THR0_HIGH_THRHIGH(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_THR0_HIGH_THRHIGH_SHIFT)) & ADC_THR0_HIGH_THRHIGH_MASK)
+/*! @} */
+
+/*! @name THR1_HIGH - ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */
+/*! @{ */
+#define ADC_THR1_HIGH_THRHIGH_MASK               (0xFFF0U)
+#define ADC_THR1_HIGH_THRHIGH_SHIFT              (4U)
+/*! THRHIGH - High threshold value against which ADC results will be compared
+ */
+#define ADC_THR1_HIGH_THRHIGH(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_THR1_HIGH_THRHIGH_SHIFT)) & ADC_THR1_HIGH_THRHIGH_MASK)
+/*! @} */
+
+/*! @name CHAN_THRSEL - ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel */
+/*! @{ */
+#define ADC_CHAN_THRSEL_CH0_THRSEL_MASK          (0x1U)
+#define ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT         (0U)
+/*! CH0_THRSEL - Threshold select for channel 0. 0: Threshold 0. Results for this channel will be
+ *    compared against the threshold levels indicated in the THR0_LOW and THR0_HIGH registers. 1:
+ *    Threshold 1. Results for this channel will be compared against the threshold levels indicated in
+ *    the THR1_LOW and THR1_HIGH registers.
+ */
+#define ADC_CHAN_THRSEL_CH0_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH0_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH1_THRSEL_MASK          (0x2U)
+#define ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT         (1U)
+/*! CH1_THRSEL - Threshold select for channel 1. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH1_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH1_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH2_THRSEL_MASK          (0x4U)
+#define ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT         (2U)
+/*! CH2_THRSEL - Threshold select for channel 2. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH2_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH2_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH3_THRSEL_MASK          (0x8U)
+#define ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT         (3U)
+/*! CH3_THRSEL - Threshold select for channel 3. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH3_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH3_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH4_THRSEL_MASK          (0x10U)
+#define ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT         (4U)
+/*! CH4_THRSEL - Threshold select for channel 4. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH4_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH4_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH5_THRSEL_MASK          (0x20U)
+#define ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT         (5U)
+/*! CH5_THRSEL - Threshold select for channel 5. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH5_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH5_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH6_THRSEL_MASK          (0x40U)
+#define ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT         (6U)
+/*! CH6_THRSEL - Threshold select for channel 6. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH6_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH6_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH7_THRSEL_MASK          (0x80U)
+#define ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT         (7U)
+/*! CH7_THRSEL - Threshold select for channel 7. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH7_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH7_THRSEL_MASK)
+/*! @} */
+
+/*! @name INTEN - ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated. */
+/*! @{ */
+#define ADC_INTEN_SEQA_INTEN_MASK                (0x1U)
+#define ADC_INTEN_SEQA_INTEN_SHIFT               (0U)
+/*! SEQA_INTEN - Sequence A interrupt enable. 0: Disabled. The sequence A interrupt/DMA trigger is
+ *    disabled. 1: Enabled. The sequence A interrupt/DMA trigger is enabled and will be asserted
+ *    either upon completion of each individual conversion performed as part of sequence A, or upon
+ *    completion of the entire A sequence of conversions, depending on the MODE bit in the SEQA_CTRL
+ *    register.
+ */
+#define ADC_INTEN_SEQA_INTEN(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_SEQA_INTEN_SHIFT)) & ADC_INTEN_SEQA_INTEN_MASK)
+#define ADC_INTEN_OVR_INTEN_MASK                 (0x4U)
+#define ADC_INTEN_OVR_INTEN_SHIFT                (2U)
+/*! OVR_INTEN - Overrun interrupt enable. 0: Disabled. The overrun interrupt is disabled. 1:
+ *    Enabled. The overrun interrupt is enabled. Detection of an overrun condition on any of the 12 channel
+ *    data registers will cause an overrun interrupt/DMA trigger. In addition, if the MODE bit for
+ *    a particular sequence is 0, then an overrun in the global data register for that sequence will
+ *    also cause this interrupt/DMA trigger to be asserted.
+ */
+#define ADC_INTEN_OVR_INTEN(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_OVR_INTEN_SHIFT)) & ADC_INTEN_OVR_INTEN_MASK)
+#define ADC_INTEN_ADCMPINTEN0_MASK               (0x18U)
+#define ADC_INTEN_ADCMPINTEN0_SHIFT              (3U)
+/*! ADCMPINTEN0 - Threshold comparison interrupt enable for channel 0. 0x0: Disabled. 0x1: Outside
+ *    threshold. 0x2: Crossing threshold. 0x3: Reserved
+ */
+#define ADC_INTEN_ADCMPINTEN0(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN0_SHIFT)) & ADC_INTEN_ADCMPINTEN0_MASK)
+#define ADC_INTEN_ADCMPINTEN1_MASK               (0x60U)
+#define ADC_INTEN_ADCMPINTEN1_SHIFT              (5U)
+/*! ADCMPINTEN1 - Channel 1 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN1(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN1_SHIFT)) & ADC_INTEN_ADCMPINTEN1_MASK)
+#define ADC_INTEN_ADCMPINTEN2_MASK               (0x180U)
+#define ADC_INTEN_ADCMPINTEN2_SHIFT              (7U)
+/*! ADCMPINTEN2 - Channel 2 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN2(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN2_SHIFT)) & ADC_INTEN_ADCMPINTEN2_MASK)
+#define ADC_INTEN_ADCMPINTEN3_MASK               (0x600U)
+#define ADC_INTEN_ADCMPINTEN3_SHIFT              (9U)
+/*! ADCMPINTEN3 - Channel 3 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN3(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN3_SHIFT)) & ADC_INTEN_ADCMPINTEN3_MASK)
+#define ADC_INTEN_ADCMPINTEN4_MASK               (0x1800U)
+#define ADC_INTEN_ADCMPINTEN4_SHIFT              (11U)
+/*! ADCMPINTEN4 - Channel 4 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN4(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN4_SHIFT)) & ADC_INTEN_ADCMPINTEN4_MASK)
+#define ADC_INTEN_ADCMPINTEN5_MASK               (0x6000U)
+#define ADC_INTEN_ADCMPINTEN5_SHIFT              (13U)
+/*! ADCMPINTEN5 - Channel 5 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN5(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN5_SHIFT)) & ADC_INTEN_ADCMPINTEN5_MASK)
+#define ADC_INTEN_ADCMPINTEN6_MASK               (0x18000U)
+#define ADC_INTEN_ADCMPINTEN6_SHIFT              (15U)
+/*! ADCMPINTEN6 - Channel 6 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN6(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN6_SHIFT)) & ADC_INTEN_ADCMPINTEN6_MASK)
+#define ADC_INTEN_ADCMPINTEN7_MASK               (0x60000U)
+#define ADC_INTEN_ADCMPINTEN7_SHIFT              (17U)
+/*! ADCMPINTEN7 - Channel 7 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN7(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN7_SHIFT)) & ADC_INTEN_ADCMPINTEN7_MASK)
+/*! @} */
+
+/*! @name FLAGS - ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers). */
+/*! @{ */
+#define ADC_FLAGS_THCMP0_MASK                    (0x1U)
+#define ADC_FLAGS_THCMP0_SHIFT                   (0U)
+/*! THCMP0 - Threshold comparison event on Channel 0. Set to 1 upon either an out-of-range result or
+ *    a threshold-crossing result if enabled to do so in the INTEN register. This bit is cleared by
+ *    writing a 1.
+ */
+#define ADC_FLAGS_THCMP0(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP0_SHIFT)) & ADC_FLAGS_THCMP0_MASK)
+#define ADC_FLAGS_THCMP1_MASK                    (0x2U)
+#define ADC_FLAGS_THCMP1_SHIFT                   (1U)
+/*! THCMP1 - Threshold comparison event on Channel 1. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP1(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP1_SHIFT)) & ADC_FLAGS_THCMP1_MASK)
+#define ADC_FLAGS_THCMP2_MASK                    (0x4U)
+#define ADC_FLAGS_THCMP2_SHIFT                   (2U)
+/*! THCMP2 - Threshold comparison event on Channel 2. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP2(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP2_SHIFT)) & ADC_FLAGS_THCMP2_MASK)
+#define ADC_FLAGS_THCMP3_MASK                    (0x8U)
+#define ADC_FLAGS_THCMP3_SHIFT                   (3U)
+/*! THCMP3 - Threshold comparison event on Channel 3. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP3(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP3_SHIFT)) & ADC_FLAGS_THCMP3_MASK)
+#define ADC_FLAGS_THCMP4_MASK                    (0x10U)
+#define ADC_FLAGS_THCMP4_SHIFT                   (4U)
+/*! THCMP4 - Threshold comparison event on Channel 4. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP4(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP4_SHIFT)) & ADC_FLAGS_THCMP4_MASK)
+#define ADC_FLAGS_THCMP5_MASK                    (0x20U)
+#define ADC_FLAGS_THCMP5_SHIFT                   (5U)
+/*! THCMP5 - Threshold comparison event on Channel 5. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP5(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP5_SHIFT)) & ADC_FLAGS_THCMP5_MASK)
+#define ADC_FLAGS_THCMP6_MASK                    (0x40U)
+#define ADC_FLAGS_THCMP6_SHIFT                   (6U)
+/*! THCMP6 - Threshold comparison event on Channel 6. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP6(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP6_SHIFT)) & ADC_FLAGS_THCMP6_MASK)
+#define ADC_FLAGS_THCMP7_MASK                    (0x80U)
+#define ADC_FLAGS_THCMP7_SHIFT                   (7U)
+/*! THCMP7 - Threshold comparison event on Channel 7. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP7(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP7_SHIFT)) & ADC_FLAGS_THCMP7_MASK)
+#define ADC_FLAGS_OVERRUN0_MASK                  (0x1000U)
+#define ADC_FLAGS_OVERRUN0_SHIFT                 (12U)
+/*! OVERRUN0 - Mirrors the OVERRRUN status flag from the result register for ADC channel 0
+ */
+#define ADC_FLAGS_OVERRUN0(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN0_SHIFT)) & ADC_FLAGS_OVERRUN0_MASK)
+#define ADC_FLAGS_OVERRUN1_MASK                  (0x2000U)
+#define ADC_FLAGS_OVERRUN1_SHIFT                 (13U)
+/*! OVERRUN1 - Mirrors the OVERRRUN status flag from the result register for ADC channel 1
+ */
+#define ADC_FLAGS_OVERRUN1(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN1_SHIFT)) & ADC_FLAGS_OVERRUN1_MASK)
+#define ADC_FLAGS_OVERRUN2_MASK                  (0x4000U)
+#define ADC_FLAGS_OVERRUN2_SHIFT                 (14U)
+/*! OVERRUN2 - Mirrors the OVERRRUN status flag from the result register for ADC channel 2
+ */
+#define ADC_FLAGS_OVERRUN2(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN2_SHIFT)) & ADC_FLAGS_OVERRUN2_MASK)
+#define ADC_FLAGS_OVERRUN3_MASK                  (0x8000U)
+#define ADC_FLAGS_OVERRUN3_SHIFT                 (15U)
+/*! OVERRUN3 - Mirrors the OVERRRUN status flag from the result register for ADC channel 3
+ */
+#define ADC_FLAGS_OVERRUN3(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN3_SHIFT)) & ADC_FLAGS_OVERRUN3_MASK)
+#define ADC_FLAGS_OVERRUN4_MASK                  (0x10000U)
+#define ADC_FLAGS_OVERRUN4_SHIFT                 (16U)
+/*! OVERRUN4 - Mirrors the OVERRRUN status flag from the result register for ADC channel 4
+ */
+#define ADC_FLAGS_OVERRUN4(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN4_SHIFT)) & ADC_FLAGS_OVERRUN4_MASK)
+#define ADC_FLAGS_OVERRUN5_MASK                  (0x20000U)
+#define ADC_FLAGS_OVERRUN5_SHIFT                 (17U)
+/*! OVERRUN5 - Mirrors the OVERRRUN status flag from the result register for ADC channel 5
+ */
+#define ADC_FLAGS_OVERRUN5(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN5_SHIFT)) & ADC_FLAGS_OVERRUN5_MASK)
+#define ADC_FLAGS_OVERRUN6_MASK                  (0x40000U)
+#define ADC_FLAGS_OVERRUN6_SHIFT                 (18U)
+/*! OVERRUN6 - Mirrors the OVERRRUN status flag from the result register for ADC channel 6
+ */
+#define ADC_FLAGS_OVERRUN6(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN6_SHIFT)) & ADC_FLAGS_OVERRUN6_MASK)
+#define ADC_FLAGS_OVERRUN7_MASK                  (0x80000U)
+#define ADC_FLAGS_OVERRUN7_SHIFT                 (19U)
+/*! OVERRUN7 - Mirrors the OVERRRUN status flag from the result register for ADC channel 7
+ */
+#define ADC_FLAGS_OVERRUN7(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN7_SHIFT)) & ADC_FLAGS_OVERRUN7_MASK)
+#define ADC_FLAGS_SEQA_OVR_MASK                  (0x1000000U)
+#define ADC_FLAGS_SEQA_OVR_SHIFT                 (24U)
+/*! SEQA_OVR - Mirrors the global OVERRUN status flag in the SEQA_GDAT register
+ */
+#define ADC_FLAGS_SEQA_OVR(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_OVR_SHIFT)) & ADC_FLAGS_SEQA_OVR_MASK)
+#define ADC_FLAGS_SEQA_INT_MASK                  (0x10000000U)
+#define ADC_FLAGS_SEQA_INT_SHIFT                 (28U)
+/*! SEQA_INT - Sequence A interrupt/DMA trigger. If the MODE bit in the SEQA_CTRL register is 0,
+ *    this flag will mirror the DATAVALID bit in the sequence A global data register (SEQA_GDAT), which
+ *    is set at the end of every ADC conversion performed as part of sequence A. It will be cleared
+ *    automatically when the SEQA_GDAT register is read. If the MODE bit in the SEQA_CTRL register
+ *    is 1, this flag will be set upon completion of an entire A sequence. In this case it must be
+ *    cleared by writing a 1 to this SEQA_INT bit. This interrupt must be enabled in the INTEN
+ *    register.
+ */
+#define ADC_FLAGS_SEQA_INT(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_INT_SHIFT)) & ADC_FLAGS_SEQA_INT_MASK)
+#define ADC_FLAGS_THCMP_INT_MASK                 (0x40000000U)
+#define ADC_FLAGS_THCMP_INT_SHIFT                (30U)
+/*! THCMP_INT - Threshold Comparison Interrupt. This bit will be set if any of the THCMP flags in
+ *    the lower bits of this register are set to 1 (due to an enabled out-of-range or
+ *    threshold-crossing event on any channel). Each type of threshold comparison interrupt on each channel must be
+ *    individually enabled in the INTEN register to cause this interrupt. This bit will be cleared
+ *    when all of the individual threshold flags are cleared via writing 1s to those bits.
+ */
+#define ADC_FLAGS_THCMP_INT(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP_INT_SHIFT)) & ADC_FLAGS_THCMP_INT_MASK)
+#define ADC_FLAGS_OVR_INT_MASK                   (0x80000000U)
+#define ADC_FLAGS_OVR_INT_SHIFT                  (31U)
+/*! OVR_INT - Overrun Interrupt flag. Any overrun bit in any of the individual channel data
+ *    registers will cause this interrupt. In addition, if the MODE bit in either of the SEQn_CTRL registers
+ *    is 0 then the OVERRUN bit in the corresponding SEQn_GDAT register will also cause this
+ *    interrupt. This interrupt must be enabled in the INTEN register. This bit will be cleared when all
+ *    of the individual overrun bits have been cleared via reading the corresponding data registers.
+ */
+#define ADC_FLAGS_OVR_INT(x)                     (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVR_INT_SHIFT)) & ADC_FLAGS_OVR_INT_MASK)
+/*! @} */
+
+/*! @name STARTUP - ADC Startup register (typically only used by the ADC API). */
+/*! @{ */
+#define ADC_STARTUP_ADC_ENA_MASK                 (0x1U)
+#define ADC_STARTUP_ADC_ENA_SHIFT                (0U)
+/*! ADC_ENA - ADC Enable bit. This bit can only be set to a 1 by software. It is cleared
+ *    automatically whenever the ADC is powered down. This bit must not be set until at least 10 microseconds
+ *    after the ADC is powered up (typically by altering a system-level ADC power control bit).
+ */
+#define ADC_STARTUP_ADC_ENA(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_STARTUP_ADC_ENA_SHIFT)) & ADC_STARTUP_ADC_ENA_MASK)
+/*! @} */
+
+/*! @name GPADC_CTRL0 - Second ADC Control register : ADC internal LDO (within ADC sub-system) */
+/*! @{ */
+#define ADC_GPADC_CTRL0_LDO_POWER_EN_MASK        (0x1U)
+#define ADC_GPADC_CTRL0_LDO_POWER_EN_SHIFT       (0U)
+/*! LDO_POWER_EN - LDO Power enable signal (active high). This is for the LDO within the ADC itself.
+ *    There is also LDOADC controlled from PMC that is outside the ADC block. The LDOADC should
+ *    have been enabled for 10usec before enabling this LDO. After enabling this LDO it is necessary to
+ *    wait for 230usec, before ADC sampling is commenced, so that full accuraccy of the ADC will be
+ *    obtained.
+ */
+#define ADC_GPADC_CTRL0_LDO_POWER_EN(x)          (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_LDO_POWER_EN_SHIFT)) & ADC_GPADC_CTRL0_LDO_POWER_EN_MASK)
+#define ADC_GPADC_CTRL0_LDO_SEL_OUT_MASK         (0xF8U)
+#define ADC_GPADC_CTRL0_LDO_SEL_OUT_SHIFT        (3U)
+/*! LDO_SEL_OUT - Select LDO output voltage (10mV step) [between 0.64V and 0.95V]. This is for the
+ *    LDO within the ADC itself. There is also LDOADC controlled from PMC that is outside the ADC
+ *    block.
+ */
+#define ADC_GPADC_CTRL0_LDO_SEL_OUT(x)           (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_LDO_SEL_OUT_SHIFT)) & ADC_GPADC_CTRL0_LDO_SEL_OUT_MASK)
+#define ADC_GPADC_CTRL0_PASS_ENABLE_MASK         (0x100U)
+#define ADC_GPADC_CTRL0_PASS_ENABLE_SHIFT        (8U)
+/*! PASS_ENABLE - Enable pass mode when set to high. This is for the LDO within the ADC itself.
+ *    There is also LDOADC controlled from PMC that is outside the ADC block.
+ */
+#define ADC_GPADC_CTRL0_PASS_ENABLE(x)           (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_PASS_ENABLE_SHIFT)) & ADC_GPADC_CTRL0_PASS_ENABLE_MASK)
+#define ADC_GPADC_CTRL0_GPADC_TSAMP_MASK         (0x3E00U)
+#define ADC_GPADC_CTRL0_GPADC_TSAMP_SHIFT        (9U)
+/*! GPADC_TSAMP - Extand ADC sampling time according to source impedance 1: 0.621 kOhm 20 (default): 55 kOhm 31: 87 kOhm
+ */
+#define ADC_GPADC_CTRL0_GPADC_TSAMP(x)           (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_GPADC_TSAMP_SHIFT)) & ADC_GPADC_CTRL0_GPADC_TSAMP_MASK)
+#define ADC_GPADC_CTRL0_TEST_MASK                (0xC000U)
+#define ADC_GPADC_CTRL0_TEST_SHIFT               (14U)
+/*! TEST - Mode selection: '00': Normal functional mode (DIV4 mode). Input range is 0 to 3.6V,
+ *    although max input voltage is affected by supply voltage of the device. '01': Multiplexer test mode
+ *    '10': ADC in unity gain mode. (DIV1 mode). Input range is 0 to 0.9V. Voltages above this may
+ *    damage the device. '11': Not used
+ */
+#define ADC_GPADC_CTRL0_TEST(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_TEST_SHIFT)) & ADC_GPADC_CTRL0_TEST_MASK)
+/*! @} */
+
+/*! @name GPADC_CTRL1 - Third ADC Control register : ADC internal gain and offset */
+/*! @{ */
+#define ADC_GPADC_CTRL1_OFFSET_CAL_MASK          (0x3FFU)
+#define ADC_GPADC_CTRL1_OFFSET_CAL_SHIFT         (0U)
+/*! OFFSET_CAL - offset_cal the setting is used within the ADC to compensate for a DC shift in values for this particular device.
+ */
+#define ADC_GPADC_CTRL1_OFFSET_CAL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL1_OFFSET_CAL_SHIFT)) & ADC_GPADC_CTRL1_OFFSET_CAL_MASK)
+#define ADC_GPADC_CTRL1_GAIN_CAL_MASK            (0xFFC00U)
+#define ADC_GPADC_CTRL1_GAIN_CAL_SHIFT           (10U)
+/*! GAIN_CAL - gain_cal the setting is used within the ADC to compensate for any gain variation for this particular device.
+ */
+#define ADC_GPADC_CTRL1_GAIN_CAL(x)              (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL1_GAIN_CAL_SHIFT)) & ADC_GPADC_CTRL1_GAIN_CAL_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group ADC_Register_Masks */
+
+
+/* ADC - Peripheral instance base addresses */
+/** Peripheral ADC0 base address */
+#define ADC0_BASE                                (0x40089000u)
+/** Peripheral ADC0 base pointer */
+#define ADC0                                     ((ADC_Type *)ADC0_BASE)
+/** Array initializer of ADC peripheral base addresses */
+#define ADC_BASE_ADDRS                           { ADC0_BASE }
+/** Array initializer of ADC peripheral base pointers */
+#define ADC_BASE_PTRS                            { ADC0 }
+/** Interrupt vectors for the ADC peripheral type */
+#define ADC_SEQ_IRQS                             { ADC0_SEQA_IRQn, ADC0_SEQB_IRQn }
+#define ADC_THCMP_IRQS                           { ADC0_THCMP_IRQn }
+
+/*!
+ * @}
+ */ /* end of group ADC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- AES Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup AES_Peripheral_Access_Layer AES Peripheral Access Layer
+ * @{
+ */
+
+/** AES - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CFG;                               /**< Configuration, offset: 0x0 */
+  __IO uint32_t CMD;                               /**< Command, offset: 0x4 */
+  __IO uint32_t STAT;                              /**< Status, offset: 0x8 */
+  __IO uint32_t CTR_INCR;                          /**< Counter Increment. Increment value for HOLDING when in Counter modes, offset: 0xC */
+       uint8_t RESERVED_0[16];
+  __O  uint32_t KEY[8];                            /**< Bits of the AES key, array offset: 0x20, array step: 0x4 */
+  __O  uint32_t INTEXT[4];                         /**< Input text bits, array offset: 0x40, array step: 0x4 */
+  __O  uint32_t HOLDING[4];                        /**< Holding register bits, array offset: 0x50, array step: 0x4 */
+  __I  uint32_t OUTTEXT[4];                        /**< Output text bits, array offset: 0x60, array step: 0x4 */
+  __O  uint32_t GF128_Y[4];                        /**< Y bits input of GF128 hash, array offset: 0x70, array step: 0x4 */
+  __I  uint32_t GF128_Z[4];                        /**< Result bits of GF128 hash, array offset: 0x80, array step: 0x4 */
+  __I  uint32_t GCM_TAG[4];                        /**< GCM Tag bits, array offset: 0x90, array step: 0x4 */
+} AES_Type;
+
+/* ----------------------------------------------------------------------------
+   -- AES Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup AES_Register_Masks AES Register Masks
+ * @{
+ */
+
+/*! @name CFG - Configuration */
+/*! @{ */
+#define AES_CFG_PROC_EN_MASK                     (0x3U)
+#define AES_CFG_PROC_EN_SHIFT                    (0U)
+/*! PROC_EN - Processing Mode Enable. 00: Reserved. 01: Encrypt/Decrypt Only. 10: GF128 Hash Only. 11: Encrypt/Decrypt and Hash.
+ */
+#define AES_CFG_PROC_EN(x)                       (((uint32_t)(((uint32_t)(x)) << AES_CFG_PROC_EN_SHIFT)) & AES_CFG_PROC_EN_MASK)
+#define AES_CFG_GF128_SEL_MASK                   (0x4U)
+#define AES_CFG_GF128_SEL_SHIFT                  (2U)
+/*! GF128_SEL - GF128 Select Mode. 0: GF128 Hash Input Text. 1: GF128 Hash Output Text.
+ */
+#define AES_CFG_GF128_SEL(x)                     (((uint32_t)(((uint32_t)(x)) << AES_CFG_GF128_SEL_SHIFT)) & AES_CFG_GF128_SEL_MASK)
+#define AES_CFG_INTEXT_BSWAP_MASK                (0x10U)
+#define AES_CFG_INTEXT_BSWAP_SHIFT               (4U)
+/*! INTEXT_BSWAP - Input Text Byte Swap
+ */
+#define AES_CFG_INTEXT_BSWAP(x)                  (((uint32_t)(((uint32_t)(x)) << AES_CFG_INTEXT_BSWAP_SHIFT)) & AES_CFG_INTEXT_BSWAP_MASK)
+#define AES_CFG_INTEXT_WSWAP_MASK                (0x20U)
+#define AES_CFG_INTEXT_WSWAP_SHIFT               (5U)
+/*! INTEXT_WSWAP - Input Text Word Swap
+ */
+#define AES_CFG_INTEXT_WSWAP(x)                  (((uint32_t)(((uint32_t)(x)) << AES_CFG_INTEXT_WSWAP_SHIFT)) & AES_CFG_INTEXT_WSWAP_MASK)
+#define AES_CFG_OUTTEXT_BSWAP_MASK               (0x40U)
+#define AES_CFG_OUTTEXT_BSWAP_SHIFT              (6U)
+/*! OUTTEXT_BSWAP - Output Text Byte Swap
+ */
+#define AES_CFG_OUTTEXT_BSWAP(x)                 (((uint32_t)(((uint32_t)(x)) << AES_CFG_OUTTEXT_BSWAP_SHIFT)) & AES_CFG_OUTTEXT_BSWAP_MASK)
+#define AES_CFG_OUTTEXT_WSWAP_MASK               (0x80U)
+#define AES_CFG_OUTTEXT_WSWAP_SHIFT              (7U)
+/*! OUTTEXT_WSWAP - Output Text Word Swap
+ */
+#define AES_CFG_OUTTEXT_WSWAP(x)                 (((uint32_t)(((uint32_t)(x)) << AES_CFG_OUTTEXT_WSWAP_SHIFT)) & AES_CFG_OUTTEXT_WSWAP_MASK)
+#define AES_CFG_KEY_CFG_MASK                     (0x300U)
+#define AES_CFG_KEY_CFG_SHIFT                    (8U)
+/*! KEY_CFG - Key Configuration. 00: 128 Bit Key. 01: 192 Bit Key. 10: 256 Bit Key. 11: Reserved.
+ */
+#define AES_CFG_KEY_CFG(x)                       (((uint32_t)(((uint32_t)(x)) << AES_CFG_KEY_CFG_SHIFT)) & AES_CFG_KEY_CFG_MASK)
+#define AES_CFG_INBLK_SEL_MASK                   (0x30000U)
+#define AES_CFG_INBLK_SEL_SHIFT                  (16U)
+/*! INBLK_SEL - Input Block Selection From: 00: Reserved. 01: Input Text. 10: Holding. 11: Input Text XOR Holding.
+ */
+#define AES_CFG_INBLK_SEL(x)                     (((uint32_t)(((uint32_t)(x)) << AES_CFG_INBLK_SEL_SHIFT)) & AES_CFG_INBLK_SEL_MASK)
+#define AES_CFG_HOLD_SEL_MASK                    (0x300000U)
+#define AES_CFG_HOLD_SEL_SHIFT                   (20U)
+/*! HOLD_SEL - Holding Select From: 00: Counter. 01: Input Text. 10: Output Block. 11: Input Text XOR Output Block.
+ */
+#define AES_CFG_HOLD_SEL(x)                      (((uint32_t)(((uint32_t)(x)) << AES_CFG_HOLD_SEL_SHIFT)) & AES_CFG_HOLD_SEL_MASK)
+#define AES_CFG_OUTTEXT_SEL_MASK                 (0x3000000U)
+#define AES_CFG_OUTTEXT_SEL_SHIFT                (24U)
+/*! OUTTEXT_SEL - Output Text Selection From: 00: Output Block. 01: Output Block XOR Input Text. 10:
+ *    Output Block XOR Holding. 11: Reserved.
+ */
+#define AES_CFG_OUTTEXT_SEL(x)                   (((uint32_t)(((uint32_t)(x)) << AES_CFG_OUTTEXT_SEL_SHIFT)) & AES_CFG_OUTTEXT_SEL_MASK)
+/*! @} */
+
+/*! @name CMD - Command */
+/*! @{ */
+#define AES_CMD_COPY_SKEY_MASK                   (0x1U)
+#define AES_CMD_COPY_SKEY_SHIFT                  (0U)
+/*! COPY_SKEY - Copies Secret Key and enables cipher. Secret key is typically held in OTP or other secure memory.
+ */
+#define AES_CMD_COPY_SKEY(x)                     (((uint32_t)(((uint32_t)(x)) << AES_CMD_COPY_SKEY_SHIFT)) & AES_CMD_COPY_SKEY_MASK)
+#define AES_CMD_COPY_TO_Y_MASK                   (0x2U)
+#define AES_CMD_COPY_TO_Y_SHIFT                  (1U)
+/*! COPY_TO_Y - Copies Output Text to GF128 Y. Typically used for GCM where the Hash requires a Y
+ *    input which is the result of an ECB encryption of 0s. Should be performed after encryption of 0s.
+ */
+#define AES_CMD_COPY_TO_Y(x)                     (((uint32_t)(((uint32_t)(x)) << AES_CMD_COPY_TO_Y_SHIFT)) & AES_CMD_COPY_TO_Y_MASK)
+#define AES_CMD_SWITCH_MODE_MASK                 (0x10U)
+#define AES_CMD_SWITCH_MODE_SHIFT                (4U)
+/*! SWITCH_MODE - Switches mode from Forward to Reverse or from Reverse to Forward. Must wait for
+ *    Idle after command. Typically used for non-counter modes (ECB, CBC, CFB, OFB) to switch from
+ *    forward to reverse mode for decryption.
+ */
+#define AES_CMD_SWITCH_MODE(x)                   (((uint32_t)(((uint32_t)(x)) << AES_CMD_SWITCH_MODE_SHIFT)) & AES_CMD_SWITCH_MODE_MASK)
+#define AES_CMD_ABORT_MASK                       (0x100U)
+#define AES_CMD_ABORT_SHIFT                      (8U)
+/*! ABORT - Aborts Encrypt/Decrypt and GF128 Hash, clears INTEXT, clears OUTTEXT, and clears HOLDING
+ */
+#define AES_CMD_ABORT(x)                         (((uint32_t)(((uint32_t)(x)) << AES_CMD_ABORT_SHIFT)) & AES_CMD_ABORT_MASK)
+#define AES_CMD_WIPE_MASK                        (0x200U)
+#define AES_CMD_WIPE_SHIFT                       (9U)
+/*! WIPE - Performs Abort, clears KEY, disables cipher, and clears GF128_Y
+ */
+#define AES_CMD_WIPE(x)                          (((uint32_t)(((uint32_t)(x)) << AES_CMD_WIPE_SHIFT)) & AES_CMD_WIPE_MASK)
+/*! @} */
+
+/*! @name STAT - Status */
+/*! @{ */
+#define AES_STAT_IDLE_MASK                       (0x1U)
+#define AES_STAT_IDLE_SHIFT                      (0U)
+/*! IDLE - When set, all state machines are idle
+ */
+#define AES_STAT_IDLE(x)                         (((uint32_t)(((uint32_t)(x)) << AES_STAT_IDLE_SHIFT)) & AES_STAT_IDLE_MASK)
+#define AES_STAT_IN_READY_MASK                   (0x2U)
+#define AES_STAT_IN_READY_SHIFT                  (1U)
+/*! IN_READY - When set, input Text can be written
+ */
+#define AES_STAT_IN_READY(x)                     (((uint32_t)(((uint32_t)(x)) << AES_STAT_IN_READY_SHIFT)) & AES_STAT_IN_READY_MASK)
+#define AES_STAT_OUT_READY_MASK                  (0x4U)
+#define AES_STAT_OUT_READY_SHIFT                 (2U)
+/*! OUT_READY - When set, output Text can be read
+ */
+#define AES_STAT_OUT_READY(x)                    (((uint32_t)(((uint32_t)(x)) << AES_STAT_OUT_READY_SHIFT)) & AES_STAT_OUT_READY_MASK)
+#define AES_STAT_REVERSE_MASK                    (0x10U)
+#define AES_STAT_REVERSE_SHIFT                   (4U)
+/*! REVERSE - When set, Cipher in reverse mode
+ */
+#define AES_STAT_REVERSE(x)                      (((uint32_t)(((uint32_t)(x)) << AES_STAT_REVERSE_SHIFT)) & AES_STAT_REVERSE_MASK)
+#define AES_STAT_KEY_VALID_MASK                  (0x20U)
+#define AES_STAT_KEY_VALID_SHIFT                 (5U)
+/*! KEY_VALID - When set, Key is valid
+ */
+#define AES_STAT_KEY_VALID(x)                    (((uint32_t)(((uint32_t)(x)) << AES_STAT_KEY_VALID_SHIFT)) & AES_STAT_KEY_VALID_MASK)
+/*! @} */
+
+/*! @name CTR_INCR - Counter Increment. Increment value for HOLDING when in Counter modes */
+/*! @{ */
+#define AES_CTR_INCR_CTR_INCR_MASK               (0xFFFFFFFFU)
+#define AES_CTR_INCR_CTR_INCR_SHIFT              (0U)
+/*! CTR_INCR - Counter Increment. Increment value for HOLDING when in Counter modes
+ */
+#define AES_CTR_INCR_CTR_INCR(x)                 (((uint32_t)(((uint32_t)(x)) << AES_CTR_INCR_CTR_INCR_SHIFT)) & AES_CTR_INCR_CTR_INCR_MASK)
+/*! @} */
+
+/*! @name KEY - Bits of the AES key */
+/*! @{ */
+#define AES_KEY_KEY_MASK                         (0xFFFFFFFFU)
+#define AES_KEY_KEY_SHIFT                        (0U)
+/*! KEY - Contains the bits of the AES key.
+ */
+#define AES_KEY_KEY(x)                           (((uint32_t)(((uint32_t)(x)) << AES_KEY_KEY_SHIFT)) & AES_KEY_KEY_MASK)
+/*! @} */
+
+/* The count of AES_KEY */
+#define AES_KEY_COUNT                            (8U)
+
+/*! @name INTEXT - Input text bits */
+/*! @{ */
+#define AES_INTEXT_INTEXT_MASK                   (0xFFFFFFFFU)
+#define AES_INTEXT_INTEXT_SHIFT                  (0U)
+/*! INTEXT - Contains bits of the AES key.
+ */
+#define AES_INTEXT_INTEXT(x)                     (((uint32_t)(((uint32_t)(x)) << AES_INTEXT_INTEXT_SHIFT)) & AES_INTEXT_INTEXT_MASK)
+/*! @} */
+
+/* The count of AES_INTEXT */
+#define AES_INTEXT_COUNT                         (4U)
+
+/*! @name HOLDING - Holding register bits */
+/*! @{ */
+#define AES_HOLDING_HOLDING_MASK                 (0xFFFFFFFFU)
+#define AES_HOLDING_HOLDING_SHIFT                (0U)
+/*! HOLDING - Contains the first word (bits 31:0) of the 128 bit Holding value.
+ */
+#define AES_HOLDING_HOLDING(x)                   (((uint32_t)(((uint32_t)(x)) << AES_HOLDING_HOLDING_SHIFT)) & AES_HOLDING_HOLDING_MASK)
+/*! @} */
+
+/* The count of AES_HOLDING */
+#define AES_HOLDING_COUNT                        (4U)
+
+/*! @name OUTTEXT - Output text bits */
+/*! @{ */
+#define AES_OUTTEXT_OUTTEXT_MASK                 (0xFFFFFFFFU)
+#define AES_OUTTEXT_OUTTEXT_SHIFT                (0U)
+/*! OUTTEXT - Contains the bits of the 128 bit Output text data.
+ */
+#define AES_OUTTEXT_OUTTEXT(x)                   (((uint32_t)(((uint32_t)(x)) << AES_OUTTEXT_OUTTEXT_SHIFT)) & AES_OUTTEXT_OUTTEXT_MASK)
+/*! @} */
+
+/* The count of AES_OUTTEXT */
+#define AES_OUTTEXT_COUNT                        (4U)
+
+/*! @name GF128_Y - Y bits input of GF128 hash */
+/*! @{ */
+#define AES_GF128_Y_GF128_Y_MASK                 (0xFFFFFFFFU)
+#define AES_GF128_Y_GF128_Y_SHIFT                (0U)
+/*! GF128_Y - Contains the bits of the Y input of GF128 hash.
+ */
+#define AES_GF128_Y_GF128_Y(x)                   (((uint32_t)(((uint32_t)(x)) << AES_GF128_Y_GF128_Y_SHIFT)) & AES_GF128_Y_GF128_Y_MASK)
+/*! @} */
+
+/* The count of AES_GF128_Y */
+#define AES_GF128_Y_COUNT                        (4U)
+
+/*! @name GF128_Z - Result bits of GF128 hash */
+/*! @{ */
+#define AES_GF128_Z_GF128_Z_MASK                 (0xFFFFFFFFU)
+#define AES_GF128_Z_GF128_Z_SHIFT                (0U)
+/*! GF128_Z - Contains bits of the result of GF128 hash.
+ */
+#define AES_GF128_Z_GF128_Z(x)                   (((uint32_t)(((uint32_t)(x)) << AES_GF128_Z_GF128_Z_SHIFT)) & AES_GF128_Z_GF128_Z_MASK)
+/*! @} */
+
+/* The count of AES_GF128_Z */
+#define AES_GF128_Z_COUNT                        (4U)
+
+/*! @name GCM_TAG - GCM Tag bits */
+/*! @{ */
+#define AES_GCM_TAG_GCM_TAG_MASK                 (0xFFFFFFFFU)
+#define AES_GCM_TAG_GCM_TAG_SHIFT                (0U)
+/*! GCM_TAG - Contains bits of the 128 bit GCM tag.
+ */
+#define AES_GCM_TAG_GCM_TAG(x)                   (((uint32_t)(((uint32_t)(x)) << AES_GCM_TAG_GCM_TAG_SHIFT)) & AES_GCM_TAG_GCM_TAG_MASK)
+/*! @} */
+
+/* The count of AES_GCM_TAG */
+#define AES_GCM_TAG_COUNT                        (4U)
+
+
+/*!
+ * @}
+ */ /* end of group AES_Register_Masks */
+
+
+/* AES - Peripheral instance base addresses */
+/** Peripheral AES0 base address */
+#define AES0_BASE                                (0x40086000u)
+/** Peripheral AES0 base pointer */
+#define AES0                                     ((AES_Type *)AES0_BASE)
+/** Array initializer of AES peripheral base addresses */
+#define AES_BASE_ADDRS                           { AES0_BASE }
+/** Array initializer of AES peripheral base pointers */
+#define AES_BASE_PTRS                            { AES0 }
+
+/*!
+ * @}
+ */ /* end of group AES_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- ASYNC_SYSCON Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ASYNC_SYSCON_Peripheral_Access_Layer ASYNC_SYSCON Peripheral Access Layer
+ * @{
+ */
+
+/** ASYNC_SYSCON - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t ASYNCPRESETCTRL;                   /**< Asynchronous peripherals reset control. The ASYNCPRESETCTRL register allows software to reset specific peripherals attached to the async APB bridge. Writing a zero to any assigned bit in this register clears the reset and allows the specified peripheral to operate. Writing a one asserts the reset., offset: 0x0 */
+  __O  uint32_t ASYNCPRESETCTRLSET;                /**< Set bits in ASYNCPRESETCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCPRESETCTRL register, if they are implemented, offset: 0x4 */
+  __O  uint32_t ASYNCPRESETCTRLCLR;                /**< Clear bits in ASYNCPRESETCTRL. Writing ones to this register clears the corresponding bit or bits in the ASYNCPRESETCTRL register, if they are implemented, offset: 0x8 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t ASYNCAPBCLKCTRL;                   /**< Asynchronous peripherals clock control. This register controls how the clock selected for the asynchronous APB peripherals is divided to provide the clock to the asynchronous peripherals, offset: 0x10 */
+  __O  uint32_t ASYNCAPBCLKCTRLSET;                /**< Set bits in ASYNCAPBCLKCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCAPBCLKCTRLSET register, if they are implemented, offset: 0x14 */
+  __O  uint32_t ASYNCAPBCLKCTRLCLR;                /**< Clear bits in ASYNCAPBCLKCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCAPBCLKCTRLSET register, if they are implemented, offset: 0x18 */
+       uint8_t RESERVED_1[4];
+  __IO uint32_t ASYNCAPBCLKSELA;                   /**< Asynchronous APB clock source select, offset: 0x20 */
+       uint8_t RESERVED_2[124];
+  __IO uint32_t TEMPSENSORCTRL;                    /**< Temperature Sensor controls, offset: 0xA0 */
+  __IO uint32_t NFCTAGPADSCTRL;                    /**< NFC Tag pads control for I2C interface to internal NFC Tag (T parts only): I2C interface + 1 interrupt/ field detect input pad + NTAG VDD output pad, offset: 0xA4 */
+  __IO uint32_t XTAL32MLDOCTRL;                    /**< XTAL 32 MHz LDO control register. If XTAL has been auto started due to EFUSE XTAL32MSTART_ENA or BLE low power timers then the effect of these need disabling via SYSCON.XTAL32MCTRL before the full control by this register is possible., offset: 0xA8 */
+  __IO uint32_t XTAL32MCTRL;                       /**< XTAL 32 MHz control register. If XTAL has been auto started due to EFUSE XTAL32MSTART_ENA or BLE low power timers then the effect of these need disabling via SYSCON.XTAL32MCTRL before the full control by this register is possible., offset: 0xAC */
+  __I  uint32_t ANALOGID;                          /**< Analog Interfaces (PMU and Radio) identity registers, offset: 0xB0 */
+  __I  uint32_t RADIOSTATUS;                       /**< All Radio Analog modules status register., offset: 0xB4 */
+       uint8_t RESERVED_3[4];
+  __IO uint32_t DCBUSCTRL;                         /**< DC Bus can be used during device test and evaluation to give observation of internal signals., offset: 0xBC */
+  __IO uint32_t FREQMECTRL;                        /**< Frequency measure register, offset: 0xC0 */
+       uint8_t RESERVED_4[4];
+  __IO uint32_t NFCTAG_VDD;                        /**< NFCTAG VDD output control, offset: 0xC8 */
+  __O  uint32_t SWRESETCTRL;                       /**< Full IC reset request (from Software application)., offset: 0xCC */
+} ASYNC_SYSCON_Type;
+
+/* ----------------------------------------------------------------------------
+   -- ASYNC_SYSCON Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ASYNC_SYSCON_Register_Masks ASYNC_SYSCON Register Masks
+ * @{
+ */
+
+/*! @name ASYNCPRESETCTRL - Asynchronous peripherals reset control. The ASYNCPRESETCTRL register allows software to reset specific peripherals attached to the async APB bridge. Writing a zero to any assigned bit in this register clears the reset and allows the specified peripheral to operate. Writing a one asserts the reset. */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT (1U)
+/*! CT32B0 - Controls the reset for Counter/Timer CT32B0
+ *  0b0..Clear reset to Counter/Timer CT32B0.
+ *  0b1..Assert reset to Counter/Timer CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT (2U)
+/*! CT32B1 - Controls the reset for Counter/Timer CT32B1
+ *  0b0..Clear reset to Counter/Timer CT32B1.
+ *  0b1..Assert reset to Counter/Timer CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCPRESETCTRLSET - Set bits in ASYNCPRESETCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCPRESETCTRL register, if they are implemented */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0_SHIFT (1U)
+/*! CT32B0 - Writing 1 to this register sets the bit ASYNCPRESETCTRL.CT32B0
+ *  0b0..No effect.
+ *  0b1..Set the bit ASYNCPRESETCTRL.CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1_SHIFT (2U)
+/*! CT32B1 - Writing 1 to this register sets the bit ASYNCPRESETCTRL.CT32B1
+ *  0b0..No effect.
+ *  0b1..Set the bit ASYNCPRESETCTRL.CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCPRESETCTRLCLR - Clear bits in ASYNCPRESETCTRL. Writing ones to this register clears the corresponding bit or bits in the ASYNCPRESETCTRL register, if they are implemented */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0_SHIFT (1U)
+/*! CT32B0 - Writing 1 to this register clears the bit ASYNCPRESETCTRL.CT32B0
+ *  0b0..No effect.
+ *  0b1..Clear the bit ASYNCPRESETCTRL.CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1_SHIFT (2U)
+/*! CT32B1 - Writing 1 to this register clears the bit ASYNCPRESETCTRL.CT32B1
+ *  0b0..No effect.
+ *  0b1..Clear the bit ASYNCPRESETCTRL.CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCLKCTRL - Asynchronous peripherals clock control. This register controls how the clock selected for the asynchronous APB peripherals is divided to provide the clock to the asynchronous peripherals */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_SHIFT (1U)
+/*! CT32B0 - Controls the clock for Counter/Timer CT32B0
+ *  0b0..Disable clock to Counter/Timer CT32B0.
+ *  0b1..Enable clock to Counter/Timer CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_SHIFT (2U)
+/*! CT32B1 - Controls the clock for Counter/Timer CT32B1
+ *  0b0..Disable clock to Counter/Timer CT32B1.
+ *  0b1..Enable clock to Counter/Timer CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCLKCTRLSET - Set bits in ASYNCAPBCLKCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCAPBCLKCTRLSET register, if they are implemented */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0_SHIFT (1U)
+/*! CT32B0 - Writing 1 to this register sets the bit ASYNCAPBCLKCTRL.CT32B0
+ *  0b0..No effect.
+ *  0b1..Set the bit ASYNCAPBCLKCTRL.CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1_SHIFT (2U)
+/*! CT32B1 - Writing 1 to this register sets the bit ASYNCAPBCLKCTRL.CT32B1
+ *  0b0..No effect.
+ *  0b1..Set the bit ASYNCAPBCLKCTRL.CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCLKCTRLCLR - Clear bits in ASYNCAPBCLKCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCAPBCLKCTRLSET register, if they are implemented */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0_SHIFT (1U)
+/*! CT32B0 - Writing 1 to this register clears the bit ASYNCAPBCLKCTRL.CT32B0
+ *  0b0..No effect.
+ *  0b1..Clear the ASYNCAPBCLKCTRL.CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1_SHIFT (2U)
+/*! CT32B1 - Writing 1 to this register clears the bit ASYNCAPBCLKCTRL.CT32B1
+ *  0b0..No effect.
+ *  0b1..Clear the bit ASYNCAPBCLKCTRL.CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCLKSELA - Asynchronous APB clock source select */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK    (0x3U)
+#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT   (0U)
+/*! SEL - Clock source for modules beyond asynchronous Bus bridge: ASYNC_SYSCON itself, timers 0/1.
+ *  0b00..System Bus clock.
+ *  0b01..32 MHz crystal oscillator (XTAL32M).
+ *  0b10..32 MHz free running oscillator (FRO32M).
+ *  0b11..48 MHz free running oscillator (FRO48M).
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL(x)      (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK)
+/*! @} */
+
+/*! @name TEMPSENSORCTRL - Temperature Sensor controls */
+/*! @{ */
+#define ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_MASK  (0x1U)
+#define ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_SHIFT (0U)
+/*! ENABLE - Temperature sensor enable
+ */
+#define ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE(x)    (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_SHIFT)) & ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_MASK)
+#define ASYNC_SYSCON_TEMPSENSORCTRL_CM_MASK      (0xCU)
+#define ASYNC_SYSCON_TEMPSENSORCTRL_CM_SHIFT     (2U)
+/*! CM - Temerature sensor common mode output voltage selection: 0x0: high negative offset added;
+ *    0x1: intermediate negative offset added; 0x2: no offset added; 0x3: low positive offset added.
+ *    Only setting 0x2 should be used.
+ */
+#define ASYNC_SYSCON_TEMPSENSORCTRL_CM(x)        (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_TEMPSENSORCTRL_CM_SHIFT)) & ASYNC_SYSCON_TEMPSENSORCTRL_CM_MASK)
+/*! @} */
+
+/*! @name NFCTAGPADSCTRL - NFC Tag pads control for I2C interface to internal NFC Tag (T parts only): I2C interface + 1 interrupt/ field detect input pad + NTAG VDD output pad */
+/*! @{ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD_MASK (0x1U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD_SHIFT (0U)
+/*! I2C_SDA_EPD - I2C_SDA, Enable weak pull down on IO pad. 0= disabled. 1=pull down enabled.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN_MASK (0x2U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN_SHIFT (1U)
+/*! I2C_SDA_EPUN - I2C_SDA, Enable weak pull up on IO pad, active low. 0=pullup enabled. 1=pullup disabled
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0_MASK (0x4U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0_SHIFT (2U)
+/*! I2C_SDA_EHS0 - I2C_SDA IO Driver slew rate LSB. (I2C_SDA_EHS1, I2C_SDA_EHS0). RESERVED: use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT_MASK (0x8U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT_SHIFT (3U)
+/*! I2C_SDA_INVERT - I2C_SDA Input polarity. 0 : Input function is not inverted. 1 : Input function is inverted.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI_MASK (0x10U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI_SHIFT (4U)
+/*! I2C_SDA_ENZI - I2C_SDA Receiver enable, active high
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF_MASK (0x20U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF_SHIFT (5U)
+/*! I2C_SDA_FILTEROFF - I2C_SDA input glitch filter control. 0 Filter enabled. Short noise pulses
+ *    are filtered out. 1 Filter disabled. No input filtering is done.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1_MASK (0x40U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1_SHIFT (6U)
+/*! I2C_SDA_EHS1 - I2C_SDA IO Driver slew rate MSB. (I2C_SDA_EHS1, I2C_SDA_EHS0). RESERVED: use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD_MASK (0x80U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD_SHIFT (7U)
+/*! I2C_SDA_OD - I2C_SDA, Controls open-drain mode. 0 Normal. Normal push-pull output 1 Open-drain.
+ *    Simulated open-drain output (high drive disabled).
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD_MASK (0x100U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD_SHIFT (8U)
+/*! I2C_SCL_EPD - I2C_SCL, Enable weak pull down on IO pad. 0: disabled; 1: pull down enabled.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN_MASK (0x200U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN_SHIFT (9U)
+/*! I2C_SCL_EPUN - I2C_SCL, Enable weak pull up on IO pad, active low. 0: pullup enabled; 1: pullup disabled.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0_MASK (0x400U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0_SHIFT (10U)
+/*! I2C_SCL_EHS0 - I2C_SCL IO Driver slew rate LSB. (I2C_SCL_EHS1, I2C_SCL_EHS0). RESERVED: use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI_MASK (0x1000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI_SHIFT (12U)
+/*! I2C_SCL_ENZI - I2C_SCL Receiver enable, active high
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF_MASK (0x2000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF_SHIFT (13U)
+/*! I2C_SCL_FILTEROFF - I2C_SCL, input glitch filter control: 0: Filter enabled. Short noise pulses
+ *    are filtered out; 1: Filter disabled. No input filtering is done.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1_MASK (0x4000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1_SHIFT (14U)
+/*! I2C_SCL_EHS1 - I2C_SCL IO Driver slew rate MSB. (I2C_SCL_EHS1, I2C_SCL_EHS0). RESERVED: use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD_MASK (0x8000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD_SHIFT (15U)
+/*! I2C_SCL_OD - I2C_SCL open-drain mode control: 0: Normal. Normal push-pull output; 1: Open-drain.
+ *    Simulated open-drain output (high drive disabled).
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT_MASK (0x40000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT_SHIFT (18U)
+/*! INT_INVERT - NTAG INT/FD Input polarity: 0: Input function is not inverted; 1: Input function is inverted.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI_MASK (0x80000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI_SHIFT (19U)
+/*! INT_ENZI - Reserved. NTAG INT/FD IO cell always enabled, not configurable
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF_MASK (0x100000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF_SHIFT (20U)
+/*! INT_FILTEROFF - Reserved. NTAG INT/FD IO cell always filters signal, not configurable
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD_MASK (0x200000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD_SHIFT (21U)
+/*! VDD_EPD - NTAG VDD, Enable weak pull down on IO pad
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN_MASK (0x400000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN_SHIFT (22U)
+/*! VDD_EPUN - NTAG_VDD, Enable weak pull up on IO pad, active low
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0_MASK (0x800000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0_SHIFT (23U)
+/*! VDD_EHS0 - NTAG VDD IO Driver slew rate LSB. (VDD_EHS1, VDD_EHS0) sets IO cell speed when
+ *    enabled as an output. 00=Low speed, 01=nominal speed, 10=fast speed, 11=high speed. Recommendation
+ *    is to use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1_MASK (0x8000000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1_SHIFT (27U)
+/*! VDD_EHS1 - NTAG VDD IO Driver slew rate MSB. (VDD_EHS1, VDD_EHS0) sets IO cell speed when
+ *    enabled as an output. 00: Low speed; 01: nominal speed; 10: fast speed; 11: high speed.
+ *    Recommendation is to use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD_MASK  (0x10000000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD_SHIFT (28U)
+/*! VDD_OD - NTAG VDD open-drain mode control: 0: Normal. Normal push-pull output; 1: Open-drain.
+ *    Simulated open-drain output (high drive disabled).
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD(x)    (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD_MASK)
+/*! @} */
+
+/*! @name XTAL32MLDOCTRL - XTAL 32 MHz LDO control register. If XTAL has been auto started due to EFUSE XTAL32MSTART_ENA or BLE low power timers then the effect of these need disabling via SYSCON.XTAL32MCTRL before the full control by this register is possible. */
+/*! @{ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_MASK  (0x2U)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_SHIFT (1U)
+/*! ENABLE - Enable the LDO when set. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE(x)    (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_MASK    (0x38U)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_SHIFT   (3U)
+/*! VOUT - Adjust the output voltage level, setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT(x)      (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_SHIFT)) & ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_MASK)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_MASK   (0xC0U)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_SHIFT  (6U)
+/*! IBIAS - Adjust the biasing current, setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS(x)     (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_SHIFT)) & ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_MASK)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_MASK (0x300U)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_SHIFT (8U)
+/*! STABMODE - Stability configuration, only required for test purposes.
+ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_SHIFT)) & ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_MASK)
+/*! @} */
+
+/*! @name XTAL32MCTRL - XTAL 32 MHz control register. If XTAL has been auto started due to EFUSE XTAL32MSTART_ENA or BLE low power timers then the effect of these need disabling via SYSCON.XTAL32MCTRL before the full control by this register is possible. */
+/*! @{ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK (0x1U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_SHIFT (0U)
+/*! XO_ACBUF_PASS_ENABLE - Bypass enable of XTAL AC buffer enable in pll and top level. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_AMP_MASK     (0xEU)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_AMP_SHIFT    (1U)
+/*! XO_AMP - Amplitude selection , Min amp: 001, Max amp: 110. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_AMP(x)       (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_AMP_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_AMP_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_MASK (0x7F0U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_SHIFT (4U)
+/*! XO_OSC_CAP_IN - Internal Capacitor Selection for XTAL_P. Each XTAL pin has a capacitance value
+ *    up to approximately 25pF. Device test calibration data is stored on chip so that a software
+ *    function can configure a capacitiance with high accuracy.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_MASK (0x3F800U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_SHIFT (11U)
+/*! XO_OSC_CAP_OUT - Internal Capacitor Selection for XTAL_N. Each XTAL pin has a capacitance value
+ *    up to approximately 25pF. Device test calibration data is stored on chip so that a software
+ *    function can configure a capacitiance with high accuracy.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK  (0x400000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_SHIFT (22U)
+/*! XO_ENABLE - Enable signal for 32MHz XTAL.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE(x)    (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_GM_MASK      (0x3800000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_GM_SHIFT     (23U)
+/*! XO_GM - Gm value for XTAL.. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_GM(x)        (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_GM_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_GM_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_MASK   (0x4000000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_SHIFT  (26U)
+/*! XO_SLAVE - XTAL in slave mode. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE(x)     (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_MASK (0x8000000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_SHIFT (27U)
+/*! XO_STANDALONE_ENABLE - Selection of the LDO and core XO reference biasing sources (1uA bandgap
+ *    current and 0.6V bandgap voltage): 0: biasing provided by radio reference biasing sources.
+ *    Don't switch to this value without prior radio biasing, LDO XO, core XO, LDO 1.4V and PLL current
+ *    distribution enabling. 1: biasing is provided by Power Management Unit (PMU). Control of this
+ *    bit is generally managed by the radio or clock software functions.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_MASK (0x10000000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_SHIFT (28U)
+/*! XO32M_TO_MCU_ENABLE - Enable the 32MHz clock to MCU and the clock generators.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE_MASK (0x20000000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE_SHIFT (29U)
+/*! CLK_TO_GPADC_ENABLE - Enable the 16MHz clock to General Purpose ADC
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE_MASK)
+/*! @} */
+
+/*! @name ANALOGID - Analog Interfaces (PMU and Radio) identity registers */
+/*! @{ */
+#define ASYNC_SYSCON_ANALOGID_PMUID_MASK         (0x3FU)
+#define ASYNC_SYSCON_ANALOGID_PMUID_SHIFT        (0U)
+/*! PMUID - PMU Identitty register used ti indicate a version of the PMU.
+ */
+#define ASYNC_SYSCON_ANALOGID_PMUID(x)           (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ANALOGID_PMUID_SHIFT)) & ASYNC_SYSCON_ANALOGID_PMUID_MASK)
+/*! @} */
+
+/*! @name RADIOSTATUS - All Radio Analog modules status register. */
+/*! @{ */
+#define ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_MASK (0x1U)
+#define ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_SHIFT (0U)
+/*! PLLXOREADY - Value of status output by 32M XTAL oscillator. Aserted to indicate that the clock
+ *    is active. Note that the quality of the 32M clock may improve even after this is asserted.
+ *    Additionally, if settings are changed such as ibias control then this status flag will probably
+ *    remain asserted even though changes to the clock signal will be occuring,
+ */
+#define ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_SHIFT)) & ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_MASK)
+/*! @} */
+
+/*! @name DCBUSCTRL - DC Bus can be used during device test and evaluation to give observation of internal signals. */
+/*! @{ */
+#define ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK         (0x1FFU)
+#define ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT        (0U)
+/*! ADDR - ADDR[8] should be set to 1 before entering power down to prevent the risk of a small
+ *    amount of leakage current during power down.
+ */
+#define ASYNC_SYSCON_DCBUSCTRL_ADDR(x)           (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT)) & ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK)
+/*! @} */
+
+/*! @name FREQMECTRL - Frequency measure register */
+/*! @{ */
+#define ASYNC_SYSCON_FREQMECTRL_CAPVAL_MASK      (0x7FFFFFFFU)
+#define ASYNC_SYSCON_FREQMECTRL_CAPVAL_SHIFT     (0U)
+/*! CAPVAL - Frequency Measure control and status; the function differs for a read and write
+ *    operation. CAPVAL: FREQMECTRL[30:0] (Read-only) : Stores the target counter result from the last
+ *    frequency measure activiation, this is used in the calculation of the unknown clock frequency of
+ *    the reference or target clock. SCALE: FREQMECTRL[4:0] (Write-only) : define the count duration,
+ *    (2^SCALE)-1, that reference counter counts to during measurement. Note that the value is 2
+ *    giving a minimum count 2^2-1 = 3. The result of freq_me_plus can be calculated as follows :
+ *    freq_targetclk =freq_refclk* (CAPVAL+1) / ((2^SCALE)-1);
+ */
+#define ASYNC_SYSCON_FREQMECTRL_CAPVAL(x)        (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_FREQMECTRL_CAPVAL_SHIFT)) & ASYNC_SYSCON_FREQMECTRL_CAPVAL_MASK)
+#define ASYNC_SYSCON_FREQMECTRL_PROG_MASK        (0x80000000U)
+#define ASYNC_SYSCON_FREQMECTRL_PROG_SHIFT       (31U)
+/*! PROG - Set this bit to one to initiate a frequency measurement cycle. Hardware clears this bit
+ *    when the measurement cycle has completed and there is valid capture data in the CAPVAL field
+ *    (bits 13:0).
+ */
+#define ASYNC_SYSCON_FREQMECTRL_PROG(x)          (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_FREQMECTRL_PROG_SHIFT)) & ASYNC_SYSCON_FREQMECTRL_PROG_MASK)
+/*! @} */
+
+/*! @name NFCTAG_VDD - NFCTAG VDD output control */
+/*! @{ */
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT_MASK (0x1U)
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT_SHIFT (0U)
+/*! NFCTAG_VDD_OUT - Output value for the NFC Tag Vdd IO, if enabled with NFCTAG_VDD_OE.
+ */
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT_SHIFT)) & ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT_MASK)
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE_MASK (0x2U)
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE_SHIFT (1U)
+/*! NFCTAG_VDD_OE - Output enable for the NFC Tag Vdd IO cell.
+ */
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE_SHIFT)) & ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE_MASK)
+/*! @} */
+
+/*! @name SWRESETCTRL - Full IC reset request (from Software application). */
+/*! @{ */
+#define ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ_MASK (0x1U)
+#define ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ_SHIFT (0U)
+/*! ICRESETREQ - IC reset request. This bit is only valid if VECTKEY is set correctly. 0: No effect;
+ *    1: Request a fulll IC reset level reset
+ */
+#define ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ_SHIFT)) & ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ_MASK)
+#define ASYNC_SYSCON_SWRESETCTRL_VECTKEY_MASK    (0xFFFF0000U)
+#define ASYNC_SYSCON_SWRESETCTRL_VECTKEY_SHIFT   (16U)
+/*! VECTKEY - Register Key: On write, write 0x05FA to VECTKEY, otherwise the write is ignored.
+ */
+#define ASYNC_SYSCON_SWRESETCTRL_VECTKEY(x)      (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_SWRESETCTRL_VECTKEY_SHIFT)) & ASYNC_SYSCON_SWRESETCTRL_VECTKEY_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group ASYNC_SYSCON_Register_Masks */
+
+
+/* ASYNC_SYSCON - Peripheral instance base addresses */
+/** Peripheral ASYNC_SYSCON base address */
+#define ASYNC_SYSCON_BASE                        (0x40020000u)
+/** Peripheral ASYNC_SYSCON base pointer */
+#define ASYNC_SYSCON                             ((ASYNC_SYSCON_Type *)ASYNC_SYSCON_BASE)
+/** Array initializer of ASYNC_SYSCON peripheral base addresses */
+#define ASYNC_SYSCON_BASE_ADDRS                  { ASYNC_SYSCON_BASE }
+/** Array initializer of ASYNC_SYSCON peripheral base pointers */
+#define ASYNC_SYSCON_BASE_PTRS                   { ASYNC_SYSCON }
+
+/*!
+ * @}
+ */ /* end of group ASYNC_SYSCON_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- CIC_IRB Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup CIC_IRB_Peripheral_Access_Layer CIC_IRB Peripheral Access Layer
+ * @{
+ */
+
+/** CIC_IRB - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CONF;                              /**< IR Blaster configuration, offset: 0x0 */
+  __IO uint32_t CARRIER;                           /**< IR Blaster carrier configuration, offset: 0x4 */
+  __IO uint32_t FIFO_IN;                           /**< IR Blaster Envelope FIFO input, offset: 0x8 */
+  __I  uint32_t STATUS;                            /**< IR Blaster Status, offset: 0xC */
+  __O  uint32_t CMD;                               /**< IR Blaster Commands, offset: 0x10 */
+       uint8_t RESERVED_0[4044];
+  __I  uint32_t INT_STATUS;                        /**< Interrupt Status, offset: 0xFE0 */
+  __IO uint32_t INT_ENA;                           /**< Interrupt Enable, offset: 0xFE4 */
+  __O  uint32_t INT_CLR;                           /**< Interrupt Clear, offset: 0xFE8 */
+  __O  uint32_t INT_SET;                           /**< Interrupt Set, offset: 0xFEC */
+       uint8_t RESERVED_1[12];
+  __I  uint32_t MODULE_ID;                         /**< IR Blaster Module Identifier, offset: 0xFFC */
+} CIC_IRB_Type;
+
+/* ----------------------------------------------------------------------------
+   -- CIC_IRB Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup CIC_IRB_Register_Masks CIC_IRB Register Masks
+ * @{
+ */
+
+/*! @name CONF - IR Blaster configuration */
+/*! @{ */
+#define CIC_IRB_CONF_ENV_INI_MASK                (0x1U)
+#define CIC_IRB_CONF_ENV_INI_SHIFT               (0U)
+/*! ENV_INI - Initial envelope value. This is the level of the first envelope after IR Blaster start or restart.
+ *  0b0..First envelope will be a low level
+ *  0b1..First envelope will be a high level
+ */
+#define CIC_IRB_CONF_ENV_INI(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_ENV_INI_SHIFT)) & CIC_IRB_CONF_ENV_INI_MASK)
+#define CIC_IRB_CONF_MODE_MASK                   (0x2U)
+#define CIC_IRB_CONF_MODE_SHIFT                  (1U)
+/*! MODE - Blaster mode
+ *  0b0..Normal mode. IR Blaster will stop when it encouter an envelope with ENV_LAST bit = '1'
+ *  0b1..Automatic restart. IR Blaster will transmit all envelopes and stop only when FIFO becames empty. ENV_LAST
+ *       bit only generates an interrupt but doesn't stop transmission.
+ */
+#define CIC_IRB_CONF_MODE(x)                     (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_MODE_SHIFT)) & CIC_IRB_CONF_MODE_MASK)
+#define CIC_IRB_CONF_OUT_MASK                    (0xCU)
+#define CIC_IRB_CONF_OUT_SHIFT                   (2U)
+/*! OUT - Output logic function
+ *  0b00..envelope AND carrier
+ *  0b01..envelope OR carrier
+ *  0b10..envelope NAND carrier
+ *  0b11..envelope NOR carrier
+ */
+#define CIC_IRB_CONF_OUT(x)                      (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_OUT_SHIFT)) & CIC_IRB_CONF_OUT_MASK)
+#define CIC_IRB_CONF_NO_CAR_MASK                 (0x10U)
+#define CIC_IRB_CONF_NO_CAR_SHIFT                (4U)
+/*! NO_CAR - No carrier
+ *  0b0..Normal. IR_OUT = envelope + carrier
+ *  0b1..Carrier is inhibited. IR_OUT = envelope only
+ */
+#define CIC_IRB_CONF_NO_CAR(x)                   (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_NO_CAR_SHIFT)) & CIC_IRB_CONF_NO_CAR_MASK)
+#define CIC_IRB_CONF_CAR_INI_MASK                (0x20U)
+#define CIC_IRB_CONF_CAR_INI_SHIFT               (5U)
+/*! CAR_INI - Initial carrier value.
+ *  0b0..Carrier starts with '0' (the carrier is low during CHIGH[1:0] and high during CLOW[2:0])
+ *  0b1..Carrier starts with '1' (the carrier is high during CHIGH[1:0] and low during CLOW[2:0])
+ */
+#define CIC_IRB_CONF_CAR_INI(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_CAR_INI_SHIFT)) & CIC_IRB_CONF_CAR_INI_MASK)
+/*! @} */
+
+/*! @name CARRIER - IR Blaster carrier configuration */
+/*! @{ */
+#define CIC_IRB_CARRIER_CTU_MASK                 (0xFFFFU)
+#define CIC_IRB_CARRIER_CTU_SHIFT                (0U)
+/*! CTU - Carrier Time Unit (CTU) CTU = CTU * TIRCP, TIRCP = IR module clock period = 1/48MHz. Value
+ *    0x0 is equivalent to 0x1. It is recommended to modify this field when the blaster unit is
+ *    disable (i.e when ENA_ST = '0' in STATUS register)
+ */
+#define CIC_IRB_CARRIER_CTU(x)                   (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CARRIER_CTU_SHIFT)) & CIC_IRB_CARRIER_CTU_MASK)
+#define CIC_IRB_CARRIER_CLOW_MASK                (0x70000U)
+#define CIC_IRB_CARRIER_CLOW_SHIFT               (16U)
+/*! CLOW - Carrier low period. Carrier low level duration = (CLOW + 1) * CTU. It is recommended to
+ *    modify this field when the blaster unit is disable (i.e when ENA_ST = '0' in STATUS register)
+ */
+#define CIC_IRB_CARRIER_CLOW(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CARRIER_CLOW_SHIFT)) & CIC_IRB_CARRIER_CLOW_MASK)
+#define CIC_IRB_CARRIER_CHIGH_MASK               (0x180000U)
+#define CIC_IRB_CARRIER_CHIGH_SHIFT              (19U)
+/*! CHIGH - Carrier high period Carrier high level duration = (CHIGH + 1) * CTU. It is recommended
+ *    to modify this field when the blaster unit is disable (i.e when ENA_ST = '0' in STATUS register)
+ */
+#define CIC_IRB_CARRIER_CHIGH(x)                 (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CARRIER_CHIGH_SHIFT)) & CIC_IRB_CARRIER_CHIGH_MASK)
+/*! @} */
+
+/*! @name FIFO_IN - IR Blaster Envelope FIFO input */
+/*! @{ */
+#define CIC_IRB_FIFO_IN_ENV_MASK                 (0xFFFU)
+#define CIC_IRB_FIFO_IN_ENV_SHIFT                (0U)
+/*! ENV - Envelope duration expressed in carrier period number. Tenvelope = ENV * (CHIGH + CLOW + 2
+ *    ) * CTU. Value 0x000 has the same behaviour has value 0x001.
+ */
+#define CIC_IRB_FIFO_IN_ENV(x)                   (((uint32_t)(((uint32_t)(x)) << CIC_IRB_FIFO_IN_ENV_SHIFT)) & CIC_IRB_FIFO_IN_ENV_MASK)
+#define CIC_IRB_FIFO_IN_ENV_INT_MASK             (0x1000U)
+#define CIC_IRB_FIFO_IN_ENV_INT_SHIFT            (12U)
+/*! ENV_INT - Generate an interrupt when starting emission of the envelope
+ *  0b0..Don't generate interrupt
+ *  0b1..Generate interrupt
+ */
+#define CIC_IRB_FIFO_IN_ENV_INT(x)               (((uint32_t)(((uint32_t)(x)) << CIC_IRB_FIFO_IN_ENV_INT_SHIFT)) & CIC_IRB_FIFO_IN_ENV_INT_MASK)
+#define CIC_IRB_FIFO_IN_ENV_LAST_MASK            (0x2000U)
+#define CIC_IRB_FIFO_IN_ENV_LAST_SHIFT           (13U)
+/*! ENV_LAST - Last envelope.
+ *  0b0..IR Blaster loads the next envelope when this envelope finishes.
+ *  0b1..IR Blaster stops and generates an interrupt when this envelope is completly transmitted. If MODE = '1',
+ *       then IR Blaster only generates an interrupt
+ */
+#define CIC_IRB_FIFO_IN_ENV_LAST(x)              (((uint32_t)(((uint32_t)(x)) << CIC_IRB_FIFO_IN_ENV_LAST_SHIFT)) & CIC_IRB_FIFO_IN_ENV_LAST_MASK)
+/*! @} */
+
+/*! @name STATUS - IR Blaster Status */
+/*! @{ */
+#define CIC_IRB_STATUS_FIFO_LVL_MASK             (0x1FU)
+#define CIC_IRB_STATUS_FIFO_LVL_SHIFT            (0U)
+/*! FIFO_LVL - Current IR Blaster FIFO level
+ *  0b00000..FIFO is empty
+ *  0b10000..FIFO is full
+ */
+#define CIC_IRB_STATUS_FIFO_LVL(x)               (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_FIFO_LVL_SHIFT)) & CIC_IRB_STATUS_FIFO_LVL_MASK)
+#define CIC_IRB_STATUS_FIFO_FULL_MASK            (0x20U)
+#define CIC_IRB_STATUS_FIFO_FULL_SHIFT           (5U)
+/*! FIFO_FULL - IR Blaster FIFO full flag
+ *  0b0..FIFO is not full
+ *  0b1..FIFO is full (FIFO level = 100000)
+ */
+#define CIC_IRB_STATUS_FIFO_FULL(x)              (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_FIFO_FULL_SHIFT)) & CIC_IRB_STATUS_FIFO_FULL_MASK)
+#define CIC_IRB_STATUS_FIFO_EMPTY_MASK           (0x40U)
+#define CIC_IRB_STATUS_FIFO_EMPTY_SHIFT          (6U)
+/*! FIFO_EMPTY - IR Blaster FIFO empty flag
+ *  0b0..FIFO is not empty
+ *  0b1..FIFO is empty (FIFO level = 000000)
+ */
+#define CIC_IRB_STATUS_FIFO_EMPTY(x)             (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_FIFO_EMPTY_SHIFT)) & CIC_IRB_STATUS_FIFO_EMPTY_MASK)
+#define CIC_IRB_STATUS_ENA_ST_MASK               (0x80U)
+#define CIC_IRB_STATUS_ENA_ST_SHIFT              (7U)
+/*! ENA_ST - IR Blaster status
+ *  0b0..IR Blaster is disabled
+ *  0b1..IR Blaster is enabled
+ */
+#define CIC_IRB_STATUS_ENA_ST(x)                 (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_ENA_ST_SHIFT)) & CIC_IRB_STATUS_ENA_ST_MASK)
+#define CIC_IRB_STATUS_RUN_ST_MASK               (0x100U)
+#define CIC_IRB_STATUS_RUN_ST_SHIFT              (8U)
+/*! RUN_ST - IR Blaster run status
+ *  0b0..IR Blaster is not running. Either transmission has not yet been started or it is finished.
+ *  0b1..IR Blaster is running.
+ */
+#define CIC_IRB_STATUS_RUN_ST(x)                 (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_RUN_ST_SHIFT)) & CIC_IRB_STATUS_RUN_ST_MASK)
+/*! @} */
+
+/*! @name CMD - IR Blaster Commands */
+/*! @{ */
+#define CIC_IRB_CMD_ENA_MASK                     (0x1U)
+#define CIC_IRB_CMD_ENA_SHIFT                    (0U)
+/*! ENA - Enable IR Blaster. This bit is self clearing.
+ *  0b0..No effect
+ *  0b1..Enable IR Blaster
+ */
+#define CIC_IRB_CMD_ENA(x)                       (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CMD_ENA_SHIFT)) & CIC_IRB_CMD_ENA_MASK)
+#define CIC_IRB_CMD_DIS_MASK                     (0x2U)
+#define CIC_IRB_CMD_DIS_SHIFT                    (1U)
+/*! DIS - Disable IR Blaster. This bit is self clearing.
+ *  0b0..No effect
+ *  0b1..Disable IR Blaster. The transmission of envelopes is immediatly stopped. The FIFO is not reinitialized
+ *       (the content of the FIFO is conserved).
+ */
+#define CIC_IRB_CMD_DIS(x)                       (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CMD_DIS_SHIFT)) & CIC_IRB_CMD_DIS_MASK)
+#define CIC_IRB_CMD_START_MASK                   (0x4U)
+#define CIC_IRB_CMD_START_SHIFT                  (2U)
+/*! START - Start IR Blaster. This bit is self clearing.
+ *  0b0..No effect
+ *  0b1..Start transmission Before setting this field, the blaster must be enable (the bit field ENA must be set first).
+ */
+#define CIC_IRB_CMD_START(x)                     (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CMD_START_SHIFT)) & CIC_IRB_CMD_START_MASK)
+#define CIC_IRB_CMD_FIFO_RST_MASK                (0x8U)
+#define CIC_IRB_CMD_FIFO_RST_SHIFT               (3U)
+/*! FIFO_RST - Reset IR Blaster FIFO. This bit is self clearing.
+ *  0b0..No effect
+ *  0b1..Reset FIFO. IR Blaster FIFO is completly re-initialized all data present in FIFO are erased.
+ */
+#define CIC_IRB_CMD_FIFO_RST(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CMD_FIFO_RST_SHIFT)) & CIC_IRB_CMD_FIFO_RST_MASK)
+/*! @} */
+
+/*! @name INT_STATUS - Interrupt Status */
+/*! @{ */
+#define CIC_IRB_INT_STATUS_ENV_START_INT_MASK    (0x1U)
+#define CIC_IRB_INT_STATUS_ENV_START_INT_SHIFT   (0U)
+/*! ENV_START_INT - IR Blaster has started to transmit an envelope with ENV_INT bit = '1
+ *  0b0..Interrupt is not pending
+ *  0b1..Interrupt is pending
+ */
+#define CIC_IRB_INT_STATUS_ENV_START_INT(x)      (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_STATUS_ENV_START_INT_SHIFT)) & CIC_IRB_INT_STATUS_ENV_START_INT_MASK)
+#define CIC_IRB_INT_STATUS_ENV_LAST_INT_MASK     (0x2U)
+#define CIC_IRB_INT_STATUS_ENV_LAST_INT_SHIFT    (1U)
+/*! ENV_LAST_INT - IR Blaster has finished to transmit an envelope with ENV_LAST bit = '1'.
+ *  0b0..Interrupt is not pending
+ *  0b1..Interrupt is pending
+ */
+#define CIC_IRB_INT_STATUS_ENV_LAST_INT(x)       (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_STATUS_ENV_LAST_INT_SHIFT)) & CIC_IRB_INT_STATUS_ENV_LAST_INT_MASK)
+#define CIC_IRB_INT_STATUS_FIFO_UFL_INT_MASK     (0x4U)
+#define CIC_IRB_INT_STATUS_FIFO_UFL_INT_SHIFT    (2U)
+/*! FIFO_UFL_INT - IR Blaster FIFO underflow. IR Blaster has tried to transmit a data but the FIFO was empty.
+ *  0b0..Interrupt is not pending
+ *  0b1..Interrupt is pending
+ */
+#define CIC_IRB_INT_STATUS_FIFO_UFL_INT(x)       (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_STATUS_FIFO_UFL_INT_SHIFT)) & CIC_IRB_INT_STATUS_FIFO_UFL_INT_MASK)
+/*! @} */
+
+/*! @name INT_ENA - Interrupt Enable */
+/*! @{ */
+#define CIC_IRB_INT_ENA_ENV_START_ENA_MASK       (0x1U)
+#define CIC_IRB_INT_ENA_ENV_START_ENA_SHIFT      (0U)
+/*! ENV_START_ENA - Enable/Disable ENV_START interrupt
+ *  0b0..Disable ENV_START interrupt
+ *  0b1..Enable ENV_START interrupt
+ */
+#define CIC_IRB_INT_ENA_ENV_START_ENA(x)         (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_ENA_ENV_START_ENA_SHIFT)) & CIC_IRB_INT_ENA_ENV_START_ENA_MASK)
+#define CIC_IRB_INT_ENA_ENV_LAST_ENA_MASK        (0x2U)
+#define CIC_IRB_INT_ENA_ENV_LAST_ENA_SHIFT       (1U)
+/*! ENV_LAST_ENA - Enable/Disable ENV_LAST interrupt
+ *  0b0..Disable ENV_LAST interrupt
+ *  0b1..Enable ENV_LAST interrupt
+ */
+#define CIC_IRB_INT_ENA_ENV_LAST_ENA(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_ENA_ENV_LAST_ENA_SHIFT)) & CIC_IRB_INT_ENA_ENV_LAST_ENA_MASK)
+#define CIC_IRB_INT_ENA_FIFO_UFL_ENA_MASK        (0x4U)
+#define CIC_IRB_INT_ENA_FIFO_UFL_ENA_SHIFT       (2U)
+/*! FIFO_UFL_ENA - Enable/Disable FIFO_UFL interrupt
+ *  0b0..Disable FIFO_UFL interrupt
+ *  0b1..Enable FIFO_UFL nterrupt
+ */
+#define CIC_IRB_INT_ENA_FIFO_UFL_ENA(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_ENA_FIFO_UFL_ENA_SHIFT)) & CIC_IRB_INT_ENA_FIFO_UFL_ENA_MASK)
+/*! @} */
+
+/*! @name INT_CLR - Interrupt Clear */
+/*! @{ */
+#define CIC_IRB_INT_CLR_ENV_START_CLR_MASK       (0x1U)
+#define CIC_IRB_INT_CLR_ENV_START_CLR_SHIFT      (0U)
+/*! ENV_START_CLR - Clear ENV_START interrupt
+ *  0b0..no effect
+ *  0b1..clear ENV_START interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_CLR_ENV_START_CLR(x)         (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_CLR_ENV_START_CLR_SHIFT)) & CIC_IRB_INT_CLR_ENV_START_CLR_MASK)
+#define CIC_IRB_INT_CLR_ENV_LAST_CLR_MASK        (0x2U)
+#define CIC_IRB_INT_CLR_ENV_LAST_CLR_SHIFT       (1U)
+/*! ENV_LAST_CLR - Clear ENV_LAST interrupt
+ *  0b0..no effect
+ *  0b1..clear ENV_LAST interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_CLR_ENV_LAST_CLR(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_CLR_ENV_LAST_CLR_SHIFT)) & CIC_IRB_INT_CLR_ENV_LAST_CLR_MASK)
+#define CIC_IRB_INT_CLR_FIFO_UFL_CLR_MASK        (0x4U)
+#define CIC_IRB_INT_CLR_FIFO_UFL_CLR_SHIFT       (2U)
+/*! FIFO_UFL_CLR - Clear FIFO_UFL interrupt
+ *  0b0..no effect
+ *  0b1..clear FIFO_UFL interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_CLR_FIFO_UFL_CLR(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_CLR_FIFO_UFL_CLR_SHIFT)) & CIC_IRB_INT_CLR_FIFO_UFL_CLR_MASK)
+/*! @} */
+
+/*! @name INT_SET - Interrupt Set */
+/*! @{ */
+#define CIC_IRB_INT_SET_ENV_START_SET_MASK       (0x1U)
+#define CIC_IRB_INT_SET_ENV_START_SET_SHIFT      (0U)
+/*! ENV_START_SET - Set ENV_START interrupt
+ *  0b0..no effect
+ *  0b1..set ENV_START interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_SET_ENV_START_SET(x)         (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_SET_ENV_START_SET_SHIFT)) & CIC_IRB_INT_SET_ENV_START_SET_MASK)
+#define CIC_IRB_INT_SET_ENV_LAST_SET_MASK        (0x2U)
+#define CIC_IRB_INT_SET_ENV_LAST_SET_SHIFT       (1U)
+/*! ENV_LAST_SET - Set ENV_LAST interrupt
+ *  0b0..no effect
+ *  0b1..set ENV_LAST interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_SET_ENV_LAST_SET(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_SET_ENV_LAST_SET_SHIFT)) & CIC_IRB_INT_SET_ENV_LAST_SET_MASK)
+#define CIC_IRB_INT_SET_FIFO_UFL_SET_MASK        (0x4U)
+#define CIC_IRB_INT_SET_FIFO_UFL_SET_SHIFT       (2U)
+/*! FIFO_UFL_SET - Set FIFO_UFL interrupt
+ *  0b0..no effect
+ *  0b1..set FIFO_UFL interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_SET_FIFO_UFL_SET(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_SET_FIFO_UFL_SET_SHIFT)) & CIC_IRB_INT_SET_FIFO_UFL_SET_MASK)
+/*! @} */
+
+/*! @name MODULE_ID - IR Blaster Module Identifier */
+/*! @{ */
+#define CIC_IRB_MODULE_ID_APERTURE_MASK          (0xFFU)
+#define CIC_IRB_MODULE_ID_APERTURE_SHIFT         (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define CIC_IRB_MODULE_ID_APERTURE(x)            (((uint32_t)(((uint32_t)(x)) << CIC_IRB_MODULE_ID_APERTURE_SHIFT)) & CIC_IRB_MODULE_ID_APERTURE_MASK)
+#define CIC_IRB_MODULE_ID_MIN_REV_MASK           (0xF00U)
+#define CIC_IRB_MODULE_ID_MIN_REV_SHIFT          (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define CIC_IRB_MODULE_ID_MIN_REV(x)             (((uint32_t)(((uint32_t)(x)) << CIC_IRB_MODULE_ID_MIN_REV_SHIFT)) & CIC_IRB_MODULE_ID_MIN_REV_MASK)
+#define CIC_IRB_MODULE_ID_MAJ_REV_MASK           (0xF000U)
+#define CIC_IRB_MODULE_ID_MAJ_REV_SHIFT          (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define CIC_IRB_MODULE_ID_MAJ_REV(x)             (((uint32_t)(((uint32_t)(x)) << CIC_IRB_MODULE_ID_MAJ_REV_SHIFT)) & CIC_IRB_MODULE_ID_MAJ_REV_MASK)
+#define CIC_IRB_MODULE_ID_ID_MASK                (0xFFFF0000U)
+#define CIC_IRB_MODULE_ID_ID_SHIFT               (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define CIC_IRB_MODULE_ID_ID(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_MODULE_ID_ID_SHIFT)) & CIC_IRB_MODULE_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group CIC_IRB_Register_Masks */
+
+
+/* CIC_IRB - Peripheral instance base addresses */
+/** Peripheral CIC_IRB base address */
+#define CIC_IRB_BASE                             (0x40007000u)
+/** Peripheral CIC_IRB base pointer */
+#define CIC_IRB                                  ((CIC_IRB_Type *)CIC_IRB_BASE)
+/** Array initializer of CIC_IRB peripheral base addresses */
+#define CIC_IRB_BASE_ADDRS                       { CIC_IRB_BASE }
+/** Array initializer of CIC_IRB peripheral base pointers */
+#define CIC_IRB_BASE_PTRS                        { CIC_IRB }
+/** Interrupt vectors for the CIC_IRB peripheral type */
+#define CIC_IRB_IRQS                             { CIC_IRB_IRQn }
+
+/*!
+ * @}
+ */ /* end of group CIC_IRB_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- CTIMER Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup CTIMER_Peripheral_Access_Layer CTIMER Peripheral Access Layer
+ * @{
+ */
+
+/** CTIMER - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t IR;                                /**< Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending., offset: 0x0 */
+  __IO uint32_t TCR;                               /**< Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR., offset: 0x4 */
+  __IO uint32_t TC;                                /**< Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR., offset: 0x8 */
+  __IO uint32_t PR;                                /**< Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC., offset: 0xC */
+  __IO uint32_t PC;                                /**< Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface., offset: 0x10 */
+  __IO uint32_t MCR;                               /**< Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs., offset: 0x14 */
+  __IO uint32_t MR[4];                             /**< Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC., array offset: 0x18, array step: 0x4 */
+  __IO uint32_t CCR;                               /**< Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place., offset: 0x28 */
+  __I  uint32_t CR[2];                             /**< Capture Register . CR is loaded with the value of TC when there is an event on the CAPn.0 input., array offset: 0x2C, array step: 0x4 */
+       uint8_t RESERVED_0[8];
+  __IO uint32_t EMR;                               /**< External Match Register. The EMR controls the match function and the external match pins., offset: 0x3C */
+       uint8_t RESERVED_1[48];
+  __IO uint32_t CTCR;                              /**< Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting., offset: 0x70 */
+  __IO uint32_t PWMC;                              /**< PWM Control Register. The PWMCON enables PWM mode for the external match pins., offset: 0x74 */
+} CTIMER_Type;
+
+/* ----------------------------------------------------------------------------
+   -- CTIMER Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup CTIMER_Register_Masks CTIMER Register Masks
+ * @{
+ */
+
+/*! @name IR - Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */
+/*! @{ */
+#define CTIMER_IR_MR0INT_MASK                    (0x1U)
+#define CTIMER_IR_MR0INT_SHIFT                   (0U)
+/*! MR0INT - Interrupt flag for match channel 0.
+ */
+#define CTIMER_IR_MR0INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR0INT_SHIFT)) & CTIMER_IR_MR0INT_MASK)
+#define CTIMER_IR_MR1INT_MASK                    (0x2U)
+#define CTIMER_IR_MR1INT_SHIFT                   (1U)
+/*! MR1INT - Interrupt flag for match channel 1.
+ */
+#define CTIMER_IR_MR1INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR1INT_SHIFT)) & CTIMER_IR_MR1INT_MASK)
+#define CTIMER_IR_MR2INT_MASK                    (0x4U)
+#define CTIMER_IR_MR2INT_SHIFT                   (2U)
+/*! MR2INT - Interrupt flag for match channel 2.
+ */
+#define CTIMER_IR_MR2INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR2INT_SHIFT)) & CTIMER_IR_MR2INT_MASK)
+#define CTIMER_IR_MR3INT_MASK                    (0x8U)
+#define CTIMER_IR_MR3INT_SHIFT                   (3U)
+/*! MR3INT - Interrupt flag for match channel 3.
+ */
+#define CTIMER_IR_MR3INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR3INT_SHIFT)) & CTIMER_IR_MR3INT_MASK)
+#define CTIMER_IR_CR0INT_MASK                    (0x10U)
+#define CTIMER_IR_CR0INT_SHIFT                   (4U)
+/*! CR0INT - Interrupt flag for capture channel 0 event.
+ */
+#define CTIMER_IR_CR0INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR0INT_SHIFT)) & CTIMER_IR_CR0INT_MASK)
+#define CTIMER_IR_CR1INT_MASK                    (0x20U)
+#define CTIMER_IR_CR1INT_SHIFT                   (5U)
+/*! CR1INT - Interrupt flag for capture channel 1 event.
+ */
+#define CTIMER_IR_CR1INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR1INT_SHIFT)) & CTIMER_IR_CR1INT_MASK)
+#define CTIMER_IR_CR2INT_MASK                    (0x40U)
+#define CTIMER_IR_CR2INT_SHIFT                   (6U)
+/*! CR2INT - Interrupt flag for capture channel 2 event.
+ */
+#define CTIMER_IR_CR2INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR2INT_SHIFT)) & CTIMER_IR_CR2INT_MASK)
+#define CTIMER_IR_CR3INT_MASK                    (0x80U)
+#define CTIMER_IR_CR3INT_SHIFT                   (7U)
+/*! CR3INT - Interrupt flag for capture channel 3 event.
+ */
+#define CTIMER_IR_CR3INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR3INT_SHIFT)) & CTIMER_IR_CR3INT_MASK)
+/*! @} */
+
+/*! @name TCR - Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */
+/*! @{ */
+#define CTIMER_TCR_CEN_MASK                      (0x1U)
+#define CTIMER_TCR_CEN_SHIFT                     (0U)
+/*! CEN - Counter enable. 0 Disabled.The counters are disabled. 1 Enabled. The Timer Counter and Prescale Counter are enabled.
+ */
+#define CTIMER_TCR_CEN(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CEN_SHIFT)) & CTIMER_TCR_CEN_MASK)
+#define CTIMER_TCR_CRST_MASK                     (0x2U)
+#define CTIMER_TCR_CRST_SHIFT                    (1U)
+/*! CRST - Counter reset. 0 Disabled. Do nothing. 1 Enabled. The Timer Counter and the Prescale
+ *    Counter are synchronously reset on the next positive edge of the APB bus clock. The counters
+ *    remain reset until TCR[1] is returned to zero.
+ */
+#define CTIMER_TCR_CRST(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CRST_SHIFT)) & CTIMER_TCR_CRST_MASK)
+/*! @} */
+
+/*! @name TC - Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR. */
+/*! @{ */
+#define CTIMER_TC_TCVAL_MASK                     (0xFFFFFFFFU)
+#define CTIMER_TC_TCVAL_SHIFT                    (0U)
+/*! TCVAL - Timer counter value.
+ */
+#define CTIMER_TC_TCVAL(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_TC_TCVAL_SHIFT)) & CTIMER_TC_TCVAL_MASK)
+/*! @} */
+
+/*! @name PR - Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC. */
+/*! @{ */
+#define CTIMER_PR_PRVAL_MASK                     (0xFFFFFFFFU)
+#define CTIMER_PR_PRVAL_SHIFT                    (0U)
+/*! PRVAL - Prescale counter value.
+ */
+#define CTIMER_PR_PRVAL(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_PR_PRVAL_SHIFT)) & CTIMER_PR_PRVAL_MASK)
+/*! @} */
+
+/*! @name PC - Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */
+/*! @{ */
+#define CTIMER_PC_PCVAL_MASK                     (0xFFFFFFFFU)
+#define CTIMER_PC_PCVAL_SHIFT                    (0U)
+/*! PCVAL - Prescale counter value.
+ */
+#define CTIMER_PC_PCVAL(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_PC_PCVAL_SHIFT)) & CTIMER_PC_PCVAL_MASK)
+/*! @} */
+
+/*! @name MCR - Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */
+/*! @{ */
+#define CTIMER_MCR_MR0I_MASK                     (0x1U)
+#define CTIMER_MCR_MR0I_SHIFT                    (0U)
+/*! MR0I - Interrupt on MR0: an interrupt is generated when MR0 matches the value in the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR0I(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0I_SHIFT)) & CTIMER_MCR_MR0I_MASK)
+#define CTIMER_MCR_MR0R_MASK                     (0x2U)
+#define CTIMER_MCR_MR0R_SHIFT                    (1U)
+/*! MR0R - Reset on MR0: the TC will be reset if MR0 matches it. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR0R(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0R_SHIFT)) & CTIMER_MCR_MR0R_MASK)
+#define CTIMER_MCR_MR0S_MASK                     (0x4U)
+#define CTIMER_MCR_MR0S_SHIFT                    (2U)
+/*! MR0S - Stop on MR0: the TC and PC will be stopped and TCR[0] will be set to 0 if MR0 matches the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR0S(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0S_SHIFT)) & CTIMER_MCR_MR0S_MASK)
+#define CTIMER_MCR_MR1I_MASK                     (0x8U)
+#define CTIMER_MCR_MR1I_SHIFT                    (3U)
+/*! MR1I - Interrupt on MR1: an interrupt is generated when MR1 matches the value in the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR1I(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1I_SHIFT)) & CTIMER_MCR_MR1I_MASK)
+#define CTIMER_MCR_MR1R_MASK                     (0x10U)
+#define CTIMER_MCR_MR1R_SHIFT                    (4U)
+/*! MR1R - Reset on MR1: the TC will be reset if MR1 matches it. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR1R(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1R_SHIFT)) & CTIMER_MCR_MR1R_MASK)
+#define CTIMER_MCR_MR1S_MASK                     (0x20U)
+#define CTIMER_MCR_MR1S_SHIFT                    (5U)
+/*! MR1S - Stop on MR1: the TC and PC will be stopped and TCR[0] will be set to 0 if MR1 matches the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR1S(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1S_SHIFT)) & CTIMER_MCR_MR1S_MASK)
+#define CTIMER_MCR_MR2I_MASK                     (0x40U)
+#define CTIMER_MCR_MR2I_SHIFT                    (6U)
+/*! MR2I - Interrupt on MR2: an interrupt is generated when MR2 matches the value in the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR2I(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2I_SHIFT)) & CTIMER_MCR_MR2I_MASK)
+#define CTIMER_MCR_MR2R_MASK                     (0x80U)
+#define CTIMER_MCR_MR2R_SHIFT                    (7U)
+/*! MR2R - Reset on MR2: the TC will be reset if MR2 matches it. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR2R(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2R_SHIFT)) & CTIMER_MCR_MR2R_MASK)
+#define CTIMER_MCR_MR2S_MASK                     (0x100U)
+#define CTIMER_MCR_MR2S_SHIFT                    (8U)
+/*! MR2S - Stop on MR2: the TC and PC will be stopped and TCR[0] will be set to 0 if MR2 matches the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR2S(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2S_SHIFT)) & CTIMER_MCR_MR2S_MASK)
+#define CTIMER_MCR_MR3I_MASK                     (0x200U)
+#define CTIMER_MCR_MR3I_SHIFT                    (9U)
+/*! MR3I - Interrupt on MR3: an interrupt is generated when MR3 matches the value in the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR3I(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3I_SHIFT)) & CTIMER_MCR_MR3I_MASK)
+#define CTIMER_MCR_MR3R_MASK                     (0x400U)
+#define CTIMER_MCR_MR3R_SHIFT                    (10U)
+/*! MR3R - Reset on MR3: the TC will be reset if MR3 matches it. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR3R(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3R_SHIFT)) & CTIMER_MCR_MR3R_MASK)
+#define CTIMER_MCR_MR3S_MASK                     (0x800U)
+#define CTIMER_MCR_MR3S_SHIFT                    (11U)
+/*! MR3S - Stop on MR3: the TC and PC will be stopped and TCR[0] will be set to 0 if MR3 matches the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR3S(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3S_SHIFT)) & CTIMER_MCR_MR3S_MASK)
+/*! @} */
+
+/*! @name MR - Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */
+/*! @{ */
+#define CTIMER_MR_MATCH_MASK                     (0xFFFFFFFFU)
+#define CTIMER_MR_MATCH_SHIFT                    (0U)
+/*! MATCH - Timer counter match value.
+ */
+#define CTIMER_MR_MATCH(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MR_MATCH_SHIFT)) & CTIMER_MR_MATCH_MASK)
+/*! @} */
+
+/* The count of CTIMER_MR */
+#define CTIMER_MR_COUNT                          (4U)
+
+/*! @name CCR - Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */
+/*! @{ */
+#define CTIMER_CCR_CAP0RE_MASK                   (0x1U)
+#define CTIMER_CCR_CAP0RE_SHIFT                  (0U)
+/*! CAP0RE - Rising edge of capture channel 0: a sequence of 0 then 1 causes CR0 to be loaded with
+ *    the contents of TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_CCR_CAP0RE(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0RE_SHIFT)) & CTIMER_CCR_CAP0RE_MASK)
+#define CTIMER_CCR_CAP0FE_MASK                   (0x2U)
+#define CTIMER_CCR_CAP0FE_SHIFT                  (1U)
+/*! CAP0FE - Falling edge of capture channel 0: a sequence of 1 then 0 causes CR0 to be loaded with
+ *    the contents of TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_CCR_CAP0FE(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0FE_SHIFT)) & CTIMER_CCR_CAP0FE_MASK)
+#define CTIMER_CCR_CAP0I_MASK                    (0x4U)
+#define CTIMER_CCR_CAP0I_SHIFT                   (2U)
+/*! CAP0I - Generate interrupt on channel 0 capture event: a CR0 load generates an interrupt.
+ */
+#define CTIMER_CCR_CAP0I(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0I_SHIFT)) & CTIMER_CCR_CAP0I_MASK)
+#define CTIMER_CCR_CAP1RE_MASK                   (0x8U)
+#define CTIMER_CCR_CAP1RE_SHIFT                  (3U)
+/*! CAP1RE - Rising edge of capture channel 1: a sequence of 0 then 1 causes CR1 to be loaded with
+ *    the contents of TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_CCR_CAP1RE(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1RE_SHIFT)) & CTIMER_CCR_CAP1RE_MASK)
+#define CTIMER_CCR_CAP1FE_MASK                   (0x10U)
+#define CTIMER_CCR_CAP1FE_SHIFT                  (4U)
+/*! CAP1FE - Falling edge of capture channel 1: a sequence of 1 then 0 causes CR1 to be loaded with
+ *    the contents of TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_CCR_CAP1FE(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1FE_SHIFT)) & CTIMER_CCR_CAP1FE_MASK)
+#define CTIMER_CCR_CAP1I_MASK                    (0x20U)
+#define CTIMER_CCR_CAP1I_SHIFT                   (5U)
+/*! CAP1I - Generate interrupt on channel 1 capture event: a CR1 load generates an interrupt.
+ */
+#define CTIMER_CCR_CAP1I(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1I_SHIFT)) & CTIMER_CCR_CAP1I_MASK)
+/*! @} */
+
+/*! @name CR - Capture Register . CR is loaded with the value of TC when there is an event on the CAPn.0 input. */
+/*! @{ */
+#define CTIMER_CR_CAP_MASK                       (0xFFFFFFFFU)
+#define CTIMER_CR_CAP_SHIFT                      (0U)
+/*! CAP - Timer counter capture value.
+ */
+#define CTIMER_CR_CAP(x)                         (((uint32_t)(((uint32_t)(x)) << CTIMER_CR_CAP_SHIFT)) & CTIMER_CR_CAP_MASK)
+/*! @} */
+
+/* The count of CTIMER_CR */
+#define CTIMER_CR_COUNT                          (2U)
+
+/*! @name EMR - External Match Register. The EMR controls the match function and the external match pins. */
+/*! @{ */
+#define CTIMER_EMR_EM0_MASK                      (0x1U)
+#define CTIMER_EMR_EM0_SHIFT                     (0U)
+/*! EM0 - External Match 0. This bit reflects the state of output MAT0, whether or not this output
+ *    is connected to a pin. When a match occurs between the TC and MR0, this bit can either toggle,
+ *    go LOW, go HIGH, or do nothing, as selected by EMR[5:4]. This bit is driven to the MAT pins if
+ *    the match function is selected via IOCON. 0 = LOW. 1 = HIGH.
+ */
+#define CTIMER_EMR_EM0(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM0_SHIFT)) & CTIMER_EMR_EM0_MASK)
+#define CTIMER_EMR_EM1_MASK                      (0x2U)
+#define CTIMER_EMR_EM1_SHIFT                     (1U)
+/*! EM1 - External Match 1. This bit reflects the state of output MAT1, whether or not this output
+ *    is connected to a pin. When a match occurs between the TC and MR1, this bit can either toggle,
+ *    go LOW, go HIGH, or do nothing, as selected by EMR[7:6]. This bit is driven to the MAT pins if
+ *    the match function is selected via IOCON. 0 = LOW. 1 = HIGH.
+ */
+#define CTIMER_EMR_EM1(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM1_SHIFT)) & CTIMER_EMR_EM1_MASK)
+#define CTIMER_EMR_EM2_MASK                      (0x4U)
+#define CTIMER_EMR_EM2_SHIFT                     (2U)
+/*! EM2 - External Match 2. This bit reflects the state of output MAT2, whether or not this output
+ *    is connected to a pin. When a match occurs between the TC and MR2, this bit can either toggle,
+ *    go LOW, go HIGH, or do nothing, as selected by EMR[9:8]. This bit is driven to the MAT pins if
+ *    the match function is selected via IOCON. 0 = LOW. 1 = HIGH
+ */
+#define CTIMER_EMR_EM2(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM2_SHIFT)) & CTIMER_EMR_EM2_MASK)
+#define CTIMER_EMR_EM3_MASK                      (0x8U)
+#define CTIMER_EMR_EM3_SHIFT                     (3U)
+/*! EM3 - External Match 3. This bit reflects the state of output MAT3, whether or not this output
+ *    is connected to a pin. When a match occurs between the TC and MR3, this bit can either toggle,
+ *    go LOW, go HIGH, or do nothing, as selected by MR[11:10]. This bit is driven to the MAT pins
+ *    if the match function is selected via IOCON. 0 = LOW. 1 = HIGH.
+ */
+#define CTIMER_EMR_EM3(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM3_SHIFT)) & CTIMER_EMR_EM3_MASK)
+#define CTIMER_EMR_EMC0_MASK                     (0x30U)
+#define CTIMER_EMR_EMC0_SHIFT                    (4U)
+/*! EMC0 - External Match Control 0. Determines the functionality of External Match 0. 0x0 Do
+ *    Nothing. 0x1 Clear. Clear the corresponding External Match bit/output to 0 (MAT0 pin is LOW if
+ *    pinned out). 0x2 Set. Set the corresponding External Match bit/output to 1 (MAT0 pin is HIGH if
+ *    pinned out). 0x3 Toggle. Toggle the corresponding External Match bit/output.
+ */
+#define CTIMER_EMR_EMC0(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC0_SHIFT)) & CTIMER_EMR_EMC0_MASK)
+#define CTIMER_EMR_EMC1_MASK                     (0xC0U)
+#define CTIMER_EMR_EMC1_SHIFT                    (6U)
+/*! EMC1 - External Match Control 1. Determines the functionality of External Match 1. 0x0 Do
+ *    Nothing. 0x1 Clear. Clear the corresponding External Match bit/output to 0 (MAT1 pin is LOW if
+ *    pinned out). 0x2 Set. Set the corresponding External Match bit/output to 1 (MAT1 pin is HIGH if
+ *    pinned out). 0x3 Toggle. Toggle the corresponding External Match bit/output.
+ */
+#define CTIMER_EMR_EMC1(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC1_SHIFT)) & CTIMER_EMR_EMC1_MASK)
+#define CTIMER_EMR_EMC2_MASK                     (0x300U)
+#define CTIMER_EMR_EMC2_SHIFT                    (8U)
+/*! EMC2 - External Match Control 2. Determines the functionality of External Match 2. 0x0 Do
+ *    Nothing. 0x1 Clear. Clear the corresponding External Match bit/output to 0 (MAT2 pin is LOW if
+ *    pinned out). 0x2 Set. Set the corresponding External Match bit/output to 1 (MAT2 pin is HIGH if
+ *    pinned out). 0x3 Toggle. Toggle the corresponding External Match bit/output.
+ */
+#define CTIMER_EMR_EMC2(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC2_SHIFT)) & CTIMER_EMR_EMC2_MASK)
+#define CTIMER_EMR_EMC3_MASK                     (0xC00U)
+#define CTIMER_EMR_EMC3_SHIFT                    (10U)
+/*! EMC3 - External Match Control 3. Determines the functionality of External Match 3. 0x0 Do
+ *    Nothing. 0x1 Clear. Clear the corresponding External Match bit/output to 0 (MAT3 pin is LOW if
+ *    pinned out). 0x2 Set. Set the corresponding External Match bit/output to 1 (MAT3 pin is HIGH if
+ *    pinned out). 0x3 Toggle. Toggle the corresponding External Match bit/output.
+ */
+#define CTIMER_EMR_EMC3(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC3_SHIFT)) & CTIMER_EMR_EMC3_MASK)
+/*! @} */
+
+/*! @name CTCR - Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */
+/*! @{ */
+#define CTIMER_CTCR_CTMODE_MASK                  (0x3U)
+#define CTIMER_CTCR_CTMODE_SHIFT                 (0U)
+/*! CTMODE - Counter/Timer Mode This field selects which rising APB bus clock edges can increment
+ *    Timer s Prescale Counter (PC), or clear PC and increment Timer Counter (TC). Timer Mode: the TC
+ *    is incremented when the Prescale Counter matches the Prescale Register. 0x0 Timer Mode.
+ *    Incremented every rising APB bus clock edge. 0x1 Counter Mode rising edge. TC is incremented on
+ *    rising edges on the CAP input selected by bits 3:2. 0x2 Counter Mode falling edge. TC is
+ *    incremented on falling edges on the CAP input selected by bits 3:2. 0x3 Counter Mode dual edge. TC is
+ *    incremented on both edges on the CAP input selected by bits 3:2.
+ */
+#define CTIMER_CTCR_CTMODE(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CTMODE_SHIFT)) & CTIMER_CTCR_CTMODE_MASK)
+#define CTIMER_CTCR_CINSEL_MASK                  (0xCU)
+#define CTIMER_CTCR_CINSEL_SHIFT                 (2U)
+/*! CINSEL - Count Input Select When bits 1:0 in this register are not 00, these bits select which
+ *    CAP pin is sampled for clocking. Note: If Counter mode is selected for a particular CAPn input
+ *    in the CTCR, the 3 bits for that input in the Capture Control Register (CCR) must be
+ *    programmed as 000. However, capture and/or interrupt can be selected for the other 3 CAPn inputs in the
+ *    same timer. 0x0 Channel 0. CAPn.0 for CT32Bn 0x1 Channel 1. CAPn.1 for CT32Bn 0x2 Channel 2.
+ *    CAPn.2 for CT32Bn 0x3 Channel 3. CAPn.3 for CT32Bn
+ */
+#define CTIMER_CTCR_CINSEL(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CINSEL_SHIFT)) & CTIMER_CTCR_CINSEL_MASK)
+#define CTIMER_CTCR_ENCC_MASK                    (0x10U)
+#define CTIMER_CTCR_ENCC_SHIFT                   (4U)
+/*! ENCC - Setting this bit to 1 enables clearing of the timer and the prescaler when the
+ *    capture-edge event specified in bits 7:5 occurs.
+ */
+#define CTIMER_CTCR_ENCC(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_ENCC_SHIFT)) & CTIMER_CTCR_ENCC_MASK)
+#define CTIMER_CTCR_SELCC_MASK                   (0xE0U)
+#define CTIMER_CTCR_SELCC_SHIFT                  (5U)
+/*! SELCC - Edge select. When bit 4 is 1, these bits select which capture input edge will cause the
+ *    timer and prescaler to be cleared. These bits have no effect when bit 4 is low. Values 0x2 to
+ *    0x3 and 0x6 to 0x7 are reserved. 0 0x0 Channel 0 Rising Edge. Rising edge of the signal on
+ *    capture channel 0 clears the timer (if bit 4 is set). 0x1 Channel 0 Falling Edge. Falling edge of
+ *    the signal on capture channel 0 clears the timer (if bit 4 is set). 0x2 Channel 1 Rising
+ *    Edge. Rising edge of the signal on capture channel 1 clears the timer (if bit 4 is set). 0x3
+ *    Channel 1 Falling Edge. Falling edge of the signal on capture channel 1 clears the timer (if bit 4
+ *    is set). 0x4 Channel 2 Rising Edge. Rising edge of the signal on capture channel 2 clears the
+ *    timer (if bit 4 is set). 0x5 Channel 2 Falling Edge. Falling edge of the signal on capture
+ *    channel 2 clears the timer (if bit 4 is set).
+ */
+#define CTIMER_CTCR_SELCC(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_SELCC_SHIFT)) & CTIMER_CTCR_SELCC_MASK)
+/*! @} */
+
+/*! @name PWMC - PWM Control Register. The PWMCON enables PWM mode for the external match pins. */
+/*! @{ */
+#define CTIMER_PWMC_PWMEN0_MASK                  (0x1U)
+#define CTIMER_PWMC_PWMEN0_SHIFT                 (0U)
+/*! PWMEN0 - PWM mode enable for channel0. 0 Match. CT32Bn_MAT0 is controlled by EM0. 1 PWM. PWM mode is enabled for CT32Bn_MAT0.
+ */
+#define CTIMER_PWMC_PWMEN0(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN0_SHIFT)) & CTIMER_PWMC_PWMEN0_MASK)
+#define CTIMER_PWMC_PWMEN1_MASK                  (0x2U)
+#define CTIMER_PWMC_PWMEN1_SHIFT                 (1U)
+/*! PWMEN1 - PWM mode enable for channel1. 0 Match. CT32Bn_MAT01 is controlled by EM1. 1 PWM. PWM mode is enabled for CT32Bn_MAT1.
+ */
+#define CTIMER_PWMC_PWMEN1(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN1_SHIFT)) & CTIMER_PWMC_PWMEN1_MASK)
+#define CTIMER_PWMC_PWMEN2_MASK                  (0x4U)
+#define CTIMER_PWMC_PWMEN2_SHIFT                 (2U)
+/*! PWMEN2 - PWM mode enable for channel2. 0 Match. CT32Bn_MAT2 is controlled by EM2. 1 PWM. PWM mode is enabled for CT32Bn_MAT2.
+ */
+#define CTIMER_PWMC_PWMEN2(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN2_SHIFT)) & CTIMER_PWMC_PWMEN2_MASK)
+#define CTIMER_PWMC_PWMEN3_MASK                  (0x8U)
+#define CTIMER_PWMC_PWMEN3_SHIFT                 (3U)
+/*! PWMEN3 - PWM mode enable for channel3. Note: It is recommended to use match channel 3 to set the
+ *    PWM cycle. 0 Match. CT32Bn_MAT3 is controlled by EM3. 1 PWM. PWM mode is enabled for
+ *    CT132Bn_MAT3
+ */
+#define CTIMER_PWMC_PWMEN3(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN3_SHIFT)) & CTIMER_PWMC_PWMEN3_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group CTIMER_Register_Masks */
+
+
+/* CTIMER - Peripheral instance base addresses */
+/** Peripheral CTIMER0 base address */
+#define CTIMER0_BASE                             (0x40021000u)
+/** Peripheral CTIMER0 base pointer */
+#define CTIMER0                                  ((CTIMER_Type *)CTIMER0_BASE)
+/** Peripheral CTIMER1 base address */
+#define CTIMER1_BASE                             (0x40022000u)
+/** Peripheral CTIMER1 base pointer */
+#define CTIMER1                                  ((CTIMER_Type *)CTIMER1_BASE)
+/** Array initializer of CTIMER peripheral base addresses */
+#define CTIMER_BASE_ADDRS                        { CTIMER0_BASE, CTIMER1_BASE }
+/** Array initializer of CTIMER peripheral base pointers */
+#define CTIMER_BASE_PTRS                         { CTIMER0, CTIMER1 }
+/** Interrupt vectors for the CTIMER peripheral type */
+#define CTIMER_IRQS                              { CTIMER0_IRQn, CTIMER1_IRQn }
+
+/*!
+ * @}
+ */ /* end of group CTIMER_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- DMA Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup DMA_Peripheral_Access_Layer DMA Peripheral Access Layer
+ * @{
+ */
+
+/** DMA - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< DMA control., offset: 0x0 */
+  __I  uint32_t INTSTAT;                           /**< Interrupt status., offset: 0x4 */
+  __IO uint32_t SRAMBASE;                          /**< SRAM address of the channel configuration table., offset: 0x8 */
+       uint8_t RESERVED_0[20];
+  struct {                                         /* offset: 0x20, array step: 0x5C */
+    __IO uint32_t ENABLESET;                         /**< Channel Enable read and Set for all DMA channels, array offset: 0x20, array step: 0x5C */
+         uint8_t RESERVED_0[4];
+    __O  uint32_t ENABLECLR;                         /**< Channel Enable Clear for all DMA channels., array offset: 0x28, array step: 0x5C */
+         uint8_t RESERVED_1[4];
+    __I  uint32_t ACTIVE;                            /**< Channel Active status for all DMA channels., array offset: 0x30, array step: 0x5C */
+         uint8_t RESERVED_2[4];
+    __I  uint32_t BUSY;                              /**< Channel Busy status for all DMA channels., array offset: 0x38, array step: 0x5C */
+         uint8_t RESERVED_3[4];
+    __IO uint32_t ERRINT;                            /**< Error Interrupt status for all DMA channels., array offset: 0x40, array step: 0x5C */
+         uint8_t RESERVED_4[4];
+    __IO uint32_t INTENSET;                          /**< Interrupt Enable read and Set for all DMA channels., array offset: 0x48, array step: 0x5C */
+         uint8_t RESERVED_5[4];
+    __O  uint32_t INTENCLR;                          /**< Interrupt Enable Clear for all DMA channels., array offset: 0x50, array step: 0x5C */
+         uint8_t RESERVED_6[4];
+    __IO uint32_t INTA;                              /**< Interrupt A status for all DMA channels., array offset: 0x58, array step: 0x5C */
+         uint8_t RESERVED_7[4];
+    __IO uint32_t INTB;                              /**< Interrupt B status for all DMA channels., array offset: 0x60, array step: 0x5C */
+         uint8_t RESERVED_8[4];
+    __O  uint32_t SETVALID;                          /**< Set ValidPending control bits for all DMA channels., array offset: 0x68, array step: 0x5C */
+         uint8_t RESERVED_9[4];
+    __O  uint32_t SETTRIG;                           /**< Set Trigger control bits for all DMA channels., array offset: 0x70, array step: 0x5C */
+         uint8_t RESERVED_10[4];
+    __O  uint32_t ABORT;                             /**< Channel Abort control for all DMA channels., array offset: 0x78, array step: 0x5C */
+  } COMMON[1];
+       uint8_t RESERVED_1[900];
+  struct {                                         /* offset: 0x400, array step: 0x10 */
+    __IO uint32_t CFG;                               /**< Configuration register for DMA channel x, array offset: 0x400, array step: 0x10 */
+    __I  uint32_t CTLSTAT;                           /**< Control and status register for DMA channel x, array offset: 0x404, array step: 0x10 */
+    __IO uint32_t XFERCFG;                           /**< Transfer configuration register for DMA channel x, array offset: 0x408, array step: 0x10 */
+    __IO uint32_t RESERVED0;                         /**< Reserved, array offset: 0x40C, array step: 0x10 */
+  } CHANNEL[19];
+} DMA_Type;
+
+/* ----------------------------------------------------------------------------
+   -- DMA Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup DMA_Register_Masks DMA Register Masks
+ * @{
+ */
+
+/*! @name CTRL - DMA control. */
+/*! @{ */
+#define DMA_CTRL_ENABLE_MASK                     (0x1U)
+#define DMA_CTRL_ENABLE_SHIFT                    (0U)
+/*! ENABLE - DMA controller master enable. 0: Disabled. The DMA controller is disabled. This clears
+ *    any triggers that were asserted at the point when disabled, but does not prevent re-triggering
+ *    when the DMA controller is re-enabled. 1: Enabled. The DMA controller is enabled.
+ */
+#define DMA_CTRL_ENABLE(x)                       (((uint32_t)(((uint32_t)(x)) << DMA_CTRL_ENABLE_SHIFT)) & DMA_CTRL_ENABLE_MASK)
+/*! @} */
+
+/*! @name INTSTAT - Interrupt status. */
+/*! @{ */
+#define DMA_INTSTAT_ACTIVEINT_MASK               (0x2U)
+#define DMA_INTSTAT_ACTIVEINT_SHIFT              (1U)
+/*! ACTIVEINT - Summarizes whether any enabled interrupts (other than error interrupts) are pending.
+ *    0: Not pending. No enabled interrupts are pending. 1: Pending. At least one enabled interrupt
+ *    is pending.
+ */
+#define DMA_INTSTAT_ACTIVEINT(x)                 (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEINT_SHIFT)) & DMA_INTSTAT_ACTIVEINT_MASK)
+#define DMA_INTSTAT_ACTIVEERRINT_MASK            (0x4U)
+#define DMA_INTSTAT_ACTIVEERRINT_SHIFT           (2U)
+/*! ACTIVEERRINT - Summarizes whether any error interrupts are pending. 0: Not pending. No error
+ *    interrupts are pending. 1: Pending. At least one error interrupt is pending.
+ */
+#define DMA_INTSTAT_ACTIVEERRINT(x)              (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEERRINT_SHIFT)) & DMA_INTSTAT_ACTIVEERRINT_MASK)
+/*! @} */
+
+/*! @name SRAMBASE - SRAM address of the channel configuration table. */
+/*! @{ */
+#define DMA_SRAMBASE_OFFSET_MASK                 (0xFFFFFE00U)
+#define DMA_SRAMBASE_OFFSET_SHIFT                (9U)
+/*! OFFSET - Address bits 31:9 of the beginning of the DMA descriptor table. For 19 channels, the
+ *    table must begin on a 512 byte boundary. The SRAMBASE register must be configured with an
+ *    address (preferably in on-chip SRAM) where DMA descriptors will be stored.
+ */
+#define DMA_SRAMBASE_OFFSET(x)                   (((uint32_t)(((uint32_t)(x)) << DMA_SRAMBASE_OFFSET_SHIFT)) & DMA_SRAMBASE_OFFSET_MASK)
+/*! @} */
+
+/*! @name COMMON_ENABLESET - Channel Enable read and Set for all DMA channels */
+/*! @{ */
+#define DMA_COMMON_ENABLESET_ENA_MASK            (0xFFFFFFFFU)
+#define DMA_COMMON_ENABLESET_ENA_SHIFT           (0U)
+/*! ENA - Enable for DMA channels. Bit n enables or disables DMA channel n. 0: disabled. 1: enabled.
+ */
+#define DMA_COMMON_ENABLESET_ENA(x)              (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLESET_ENA_SHIFT)) & DMA_COMMON_ENABLESET_ENA_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ENABLESET */
+#define DMA_COMMON_ENABLESET_COUNT               (1U)
+
+/*! @name COMMON_ENABLECLR - Channel Enable Clear for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_ENABLECLR_CLR_MASK            (0xFFFFFFFFU)
+#define DMA_COMMON_ENABLECLR_CLR_SHIFT           (0U)
+/*! CLR - Writing ones to this register clears the corresponding bits in ENABLESET0. Bit n clears the channel enable bit n.
+ */
+#define DMA_COMMON_ENABLECLR_CLR(x)              (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLECLR_CLR_SHIFT)) & DMA_COMMON_ENABLECLR_CLR_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ENABLECLR */
+#define DMA_COMMON_ENABLECLR_COUNT               (1U)
+
+/*! @name COMMON_ACTIVE - Channel Active status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_ACTIVE_ACT_MASK               (0xFFFFFFFFU)
+#define DMA_COMMON_ACTIVE_ACT_SHIFT              (0U)
+/*! ACT - Active flag for DMA channel n. Bit n corresponds to DMA channel n. 0: not active. 1: active.
+ */
+#define DMA_COMMON_ACTIVE_ACT(x)                 (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ACTIVE_ACT_SHIFT)) & DMA_COMMON_ACTIVE_ACT_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ACTIVE */
+#define DMA_COMMON_ACTIVE_COUNT                  (1U)
+
+/*! @name COMMON_BUSY - Channel Busy status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_BUSY_BSY_MASK                 (0xFFFFFFFFU)
+#define DMA_COMMON_BUSY_BSY_SHIFT                (0U)
+/*! BSY - Busy flag for DMA channel n. Bit n corresponds to DMA channel n. 0 : not busy. 1: busy.
+ */
+#define DMA_COMMON_BUSY_BSY(x)                   (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_BUSY_BSY_SHIFT)) & DMA_COMMON_BUSY_BSY_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_BUSY */
+#define DMA_COMMON_BUSY_COUNT                    (1U)
+
+/*! @name COMMON_ERRINT - Error Interrupt status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_ERRINT_ERR_MASK               (0xFFFFFFFFU)
+#define DMA_COMMON_ERRINT_ERR_SHIFT              (0U)
+/*! ERR - Error Interrupt flag for DMA channel n. Bit n corresponds to DMA channel n. 0: error
+ *    interrupt is not active. 1: error interrupt is active.
+ */
+#define DMA_COMMON_ERRINT_ERR(x)                 (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ERRINT_ERR_SHIFT)) & DMA_COMMON_ERRINT_ERR_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ERRINT */
+#define DMA_COMMON_ERRINT_COUNT                  (1U)
+
+/*! @name COMMON_INTENSET - Interrupt Enable read and Set for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_INTENSET_INTEN_MASK           (0xFFFFFFFFU)
+#define DMA_COMMON_INTENSET_INTEN_SHIFT          (0U)
+/*! INTEN - Interrupt Enable read and set for DMA channel n. Bit n corresponds to DMA channel n. 0:
+ *    interrupt for DMA channel is disabled. 1: interrupt for DMA channel is enabled.
+ */
+#define DMA_COMMON_INTENSET_INTEN(x)             (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENSET_INTEN_SHIFT)) & DMA_COMMON_INTENSET_INTEN_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_INTENSET */
+#define DMA_COMMON_INTENSET_COUNT                (1U)
+
+/*! @name COMMON_INTENCLR - Interrupt Enable Clear for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_INTENCLR_CLR_MASK             (0xFFFFFFFFU)
+#define DMA_COMMON_INTENCLR_CLR_SHIFT            (0U)
+/*! CLR - Writing ones to this register clears corresponding bits in the INTENSET0. Bit n corresponds to DMA channel n.
+ */
+#define DMA_COMMON_INTENCLR_CLR(x)               (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENCLR_CLR_SHIFT)) & DMA_COMMON_INTENCLR_CLR_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_INTENCLR */
+#define DMA_COMMON_INTENCLR_COUNT                (1U)
+
+/*! @name COMMON_INTA - Interrupt A status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_INTA_IA_MASK                  (0xFFFFFFFFU)
+#define DMA_COMMON_INTA_IA_SHIFT                 (0U)
+/*! IA - Interrupt A status for DMA channel n. Bit n corresponds to DMA channel n. 0: the DMA
+ *    channel interrupt A is not active. 1: the DMA channel interrupt A is active.
+ */
+#define DMA_COMMON_INTA_IA(x)                    (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTA_IA_SHIFT)) & DMA_COMMON_INTA_IA_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_INTA */
+#define DMA_COMMON_INTA_COUNT                    (1U)
+
+/*! @name COMMON_INTB - Interrupt B status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_INTB_IB_MASK                  (0xFFFFFFFFU)
+#define DMA_COMMON_INTB_IB_SHIFT                 (0U)
+/*! IB - Interrupt B status for DMA channel n. Bit n corresponds to DMA channel n. 0: the DMA
+ *    channel interrupt B is not active. 1: the DMA channel interrupt B is active.
+ */
+#define DMA_COMMON_INTB_IB(x)                    (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTB_IB_SHIFT)) & DMA_COMMON_INTB_IB_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_INTB */
+#define DMA_COMMON_INTB_COUNT                    (1U)
+
+/*! @name COMMON_SETVALID - Set ValidPending control bits for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_SETVALID_SV_MASK              (0xFFFFFFFFU)
+#define DMA_COMMON_SETVALID_SV_SHIFT             (0U)
+/*! SV - SETVALID control for DMA channel n. Bit n corresponds to DMA channel n. 0: no effect. 1:
+ *    sets the VALIDPENDING control bit for DMA channel n
+ */
+#define DMA_COMMON_SETVALID_SV(x)                (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETVALID_SV_SHIFT)) & DMA_COMMON_SETVALID_SV_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_SETVALID */
+#define DMA_COMMON_SETVALID_COUNT                (1U)
+
+/*! @name COMMON_SETTRIG - Set Trigger control bits for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_SETTRIG_TRIG_MASK             (0xFFFFFFFFU)
+#define DMA_COMMON_SETTRIG_TRIG_SHIFT            (0U)
+/*! TRIG - Set Trigger control bit for DMA channel n. Bit n corresponds to DMA channel n. 0: no
+ *    effect. 1: sets the TRIG bit for DMA channel n.
+ */
+#define DMA_COMMON_SETTRIG_TRIG(x)               (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETTRIG_TRIG_SHIFT)) & DMA_COMMON_SETTRIG_TRIG_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_SETTRIG */
+#define DMA_COMMON_SETTRIG_COUNT                 (1U)
+
+/*! @name COMMON_ABORT - Channel Abort control for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_ABORT_ABORTCTRL_MASK          (0xFFFFFFFFU)
+#define DMA_COMMON_ABORT_ABORTCTRL_SHIFT         (0U)
+/*! ABORTCTRL - Abort control for DMA channel 0. Bit n corresponds to DMA channel n. 0: no effect.
+ *    1: aborts DMA operations on channel n.
+ */
+#define DMA_COMMON_ABORT_ABORTCTRL(x)            (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ABORT_ABORTCTRL_SHIFT)) & DMA_COMMON_ABORT_ABORTCTRL_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ABORT */
+#define DMA_COMMON_ABORT_COUNT                   (1U)
+
+/*! @name CHANNEL_CFG - Configuration register for DMA channel x */
+/*! @{ */
+#define DMA_CHANNEL_CFG_PERIPHREQEN_MASK         (0x1U)
+#define DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT        (0U)
+/*! PERIPHREQEN - Peripheral request Enable. If a DMA channel is used to perform a memory-to-memory
+ *    move, any peripheral DMA request associated with that channel can be disabled to prevent any
+ *    interaction between the peripheral and the DMA controller. 0 Disabled. Peripheral DMA requests
+ *    are disabled. 1 Enabled. Peripheral DMA requests are enabled.
+ */
+#define DMA_CHANNEL_CFG_PERIPHREQEN(x)           (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT)) & DMA_CHANNEL_CFG_PERIPHREQEN_MASK)
+#define DMA_CHANNEL_CFG_HWTRIGEN_MASK            (0x2U)
+#define DMA_CHANNEL_CFG_HWTRIGEN_SHIFT           (1U)
+/*! HWTRIGEN - Hardware Triggering Enable for this channel. 0 Disabled. Hardware triggering is not
+ *    used. 1 Enabled. Use hardware triggering.
+ */
+#define DMA_CHANNEL_CFG_HWTRIGEN(x)              (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_HWTRIGEN_SHIFT)) & DMA_CHANNEL_CFG_HWTRIGEN_MASK)
+#define DMA_CHANNEL_CFG_TRIGPOL_MASK             (0x10U)
+#define DMA_CHANNEL_CFG_TRIGPOL_SHIFT            (4U)
+/*! TRIGPOL - Trigger Polarity. Selects the polarity of a hardware trigger for this channel. 0
+ *    Active low - falling edge. Hardware trigger is active low or falling edge triggered, based on
+ *    TRIGTYPE. 1 Active high - rising edge. Hardware trigger is active high or rising edge triggered,
+ *    based on TRIGTYPE.
+ */
+#define DMA_CHANNEL_CFG_TRIGPOL(x)               (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGPOL_SHIFT)) & DMA_CHANNEL_CFG_TRIGPOL_MASK)
+#define DMA_CHANNEL_CFG_TRIGTYPE_MASK            (0x20U)
+#define DMA_CHANNEL_CFG_TRIGTYPE_SHIFT           (5U)
+/*! TRIGTYPE - Trigger Type. Selects hardware trigger as edge triggered or level triggered. 0 Edge.
+ *    Hardware trigger is edge triggered. Transfers will be initiated and completed, as specified
+ *    for a single trigger. 1 Level. Hardware trigger is level triggered. Note that when level
+ *    triggering without burst (BURSTPOWER = 0) is selected, only hardware triggers should be used on that
+ *    channel. Transfers continue as long as the trigger level is asserted. Once the trigger is
+ *    de-asserted, the transfer will be paused until the trigger is, again, asserted. However, the
+ *    transfer will not be paused until any remaining transfers within the current BURSTPOWER length are
+ *    completed.
+ */
+#define DMA_CHANNEL_CFG_TRIGTYPE(x)              (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGTYPE_SHIFT)) & DMA_CHANNEL_CFG_TRIGTYPE_MASK)
+#define DMA_CHANNEL_CFG_TRIGBURST_MASK           (0x40U)
+#define DMA_CHANNEL_CFG_TRIGBURST_SHIFT          (6U)
+/*! TRIGBURST - Trigger Burst. Selects whether hardware triggers cause a single or burst transfer. 0
+ *    Single transfer. Hardware trigger causes a single transfer. 1 Burst transfer. When the
+ *    trigger for this channel is set to edge triggered, a hardware trigger causes a burst transfer, as
+ *    defined by BURSTPOWER. When the trigger for this channel is set to level triggered, a hardware
+ *    trigger causes transfers to continue as long as the trigger is asserted, unless the transfer is
+ *    complete.
+ */
+#define DMA_CHANNEL_CFG_TRIGBURST(x)             (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGBURST_SHIFT)) & DMA_CHANNEL_CFG_TRIGBURST_MASK)
+#define DMA_CHANNEL_CFG_BURSTPOWER_MASK          (0xF00U)
+#define DMA_CHANNEL_CFG_BURSTPOWER_SHIFT         (8U)
+/*! BURSTPOWER - Burst Power is used in two ways. It always selects the address wrap size when
+ *    SRCBURSTWRAP and/or DSTBURSTWRAP modes are selected (see descriptions elsewhere in this register).
+ *    When the TRIGBURST field elsewhere in this register = 1, Burst Power selects how many
+ *    transfers are performed for each DMA trigger. This can be used, for example, with peripherals that
+ *    contain a FIFO that can initiate a DMA operation when the FIFO reaches a certain level. 0000:
+ *    Burst size = 1 (2^0). 0001: Burst size = 2 (2^1). 0010: Burst size = 4 (2^2). ... 1010: Burst
+ *    size = 1024 (2^10). This corresponds to the maximum supported transfer count. others: not
+ *    supported. The total transfer length as defined in the XFERCOUNT bits in the XFERCFG register must be
+ *    an even multiple of the burst size.
+ */
+#define DMA_CHANNEL_CFG_BURSTPOWER(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_BURSTPOWER_SHIFT)) & DMA_CHANNEL_CFG_BURSTPOWER_MASK)
+#define DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK        (0x4000U)
+#define DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT       (14U)
+/*! SRCBURSTWRAP - Source Burst Wrap. When enabled, the source data address for the DMA is wrapped ,
+ *    meaning that the source address range for each burst will be the same. As an example, this
+ *    could be used to read several sequential registers from a peripheral for each DMA burst, reading
+ *    the same registers again for each burst. 0 Disabled. Source burst wrapping is not enabled for
+ *    this DMA channel. 1 Enabled. Source burst wrapping is enabled for this DMA channel.
+ */
+#define DMA_CHANNEL_CFG_SRCBURSTWRAP(x)          (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK)
+#define DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK        (0x8000U)
+#define DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT       (15U)
+/*! DSTBURSTWRAP - Destination Burst Wrap. When enabled, the destination data address for the DMA is
+ *    wrapped , meaning that the destination address range for each burst will be the same. As an
+ *    example, this could be used to write several sequential registers to a peripheral for each DMA
+ *    burst, writing the same registers again for each burst. 0 Disabled. Destination burst wrapping
+ *    is not enabled for this DMA channel. 1 Enabled. Destination burst wrapping is enabled for
+ *    this DMA channel.
+ */
+#define DMA_CHANNEL_CFG_DSTBURSTWRAP(x)          (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK)
+#define DMA_CHANNEL_CFG_CHPRIORITY_MASK          (0x70000U)
+#define DMA_CHANNEL_CFG_CHPRIORITY_SHIFT         (16U)
+/*! CHPRIORITY - Priority of this channel when multiple DMA requests are pending. Eight priority
+ *    levels are supported: 0x0 = highest priority. 0x7 = lowest priority.
+ */
+#define DMA_CHANNEL_CFG_CHPRIORITY(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_CHPRIORITY_SHIFT)) & DMA_CHANNEL_CFG_CHPRIORITY_MASK)
+/*! @} */
+
+/* The count of DMA_CHANNEL_CFG */
+#define DMA_CHANNEL_CFG_COUNT                    (19U)
+
+/*! @name CHANNEL_CTLSTAT - Control and status register for DMA channel x */
+/*! @{ */
+#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK    (0x1U)
+#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT   (0U)
+/*! VALIDPENDING - Valid pending flag for this channel. This bit is set when a 1 is written to the
+ *    corresponding bit in the related SETVALID register when CFGVALID = 1 for the same channel. 0 No
+ *    effect. No effect on DMA operation. 1 Valid pending.
+ */
+#define DMA_CHANNEL_CTLSTAT_VALIDPENDING(x)      (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT)) & DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK)
+#define DMA_CHANNEL_CTLSTAT_TRIG_MASK            (0x4U)
+#define DMA_CHANNEL_CTLSTAT_TRIG_SHIFT           (2U)
+/*! TRIG - Trigger flag. Indicates that the trigger for this channel is currently set. This bit is
+ *    cleared at the end of an entire transfer or upon reload when CLRTRIG = 1. 0 Not triggered. The
+ *    trigger for this DMA channel is not set. DMA operations will not be carried out. 1 Triggered.
+ *    The trigger for this DMA channel is set. DMA operations will be carried out.
+ */
+#define DMA_CHANNEL_CTLSTAT_TRIG(x)              (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_TRIG_SHIFT)) & DMA_CHANNEL_CTLSTAT_TRIG_MASK)
+/*! @} */
+
+/* The count of DMA_CHANNEL_CTLSTAT */
+#define DMA_CHANNEL_CTLSTAT_COUNT                (19U)
+
+/*! @name CHANNEL_XFERCFG - Transfer configuration register for DMA channel x */
+/*! @{ */
+#define DMA_CHANNEL_XFERCFG_CFGVALID_MASK        (0x1U)
+#define DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT       (0U)
+/*! CFGVALID - Configuration Valid flag. This bit indicates whether the current channel descriptor
+ *    is valid and can potentially be acted upon, if all other activation criteria are fulfilled. 0
+ *    Not valid. The channel descriptor is not considered valid until validated by an associated
+ *    SETVALID0 setting. 1 Valid. The current channel descriptor is considered valid.
+ */
+#define DMA_CHANNEL_XFERCFG_CFGVALID(x)          (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT)) & DMA_CHANNEL_XFERCFG_CFGVALID_MASK)
+#define DMA_CHANNEL_XFERCFG_RELOAD_MASK          (0x2U)
+#define DMA_CHANNEL_XFERCFG_RELOAD_SHIFT         (1U)
+/*! RELOAD - Indicates whether the channel s control structure will be reloaded when the current
+ *    descriptor is exhausted. Reloading allows ping-pong and linked transfers. 0 Disabled. Do not
+ *    reload the channels control structure when the current descriptor is exhausted. 1 Enabled. Reload
+ *    the channels control structure when the current descriptor is exhausted.
+ */
+#define DMA_CHANNEL_XFERCFG_RELOAD(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_RELOAD_SHIFT)) & DMA_CHANNEL_XFERCFG_RELOAD_MASK)
+#define DMA_CHANNEL_XFERCFG_SWTRIG_MASK          (0x4U)
+#define DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT         (2U)
+/*! SWTRIG - Software Trigger. 0 Not set. When written by software, the trigger for this channel is
+ *    not set. A new trigger, as defined by the HWTRIGEN, TRIGPOL, and TRIGTYPE will be needed to
+ *    start the channel. 1 Set. When written by software, the trigger for this channel is set
+ *    immediately. This feature should not be used with level triggering when TRIGBURST = 0.
+ */
+#define DMA_CHANNEL_XFERCFG_SWTRIG(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_SWTRIG_MASK)
+#define DMA_CHANNEL_XFERCFG_CLRTRIG_MASK         (0x8U)
+#define DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT        (3U)
+/*! CLRTRIG - Clear Trigger. 0 Not cleared. The trigger is not cleared when this descriptor is
+ *    exhausted. If there is a reload, the next descriptor will be started. 1 Cleared. The trigger is
+ *    cleared when this descriptor is exhausted.
+ */
+#define DMA_CHANNEL_XFERCFG_CLRTRIG(x)           (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_CLRTRIG_MASK)
+#define DMA_CHANNEL_XFERCFG_SETINTA_MASK         (0x10U)
+#define DMA_CHANNEL_XFERCFG_SETINTA_SHIFT        (4U)
+/*! SETINTA - Set Interrupt flag A for this channel. There is no hardware distinction between
+ *    interrupt A and B. They can be used by software to assist with more complex descriptor usage. By
+ *    convention, interrupt A may be used when only one interrupt flag is needed. 0 No effect. 1 Set.
+ *    The INTA flag for this channel will be set when the current descriptor is exhausted.
+ */
+#define DMA_CHANNEL_XFERCFG_SETINTA(x)           (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTA_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTA_MASK)
+#define DMA_CHANNEL_XFERCFG_SETINTB_MASK         (0x20U)
+#define DMA_CHANNEL_XFERCFG_SETINTB_SHIFT        (5U)
+/*! SETINTB - Set Interrupt flag B for this channel. There is no hardware distinction between
+ *    interrupt A and B. They can be used by software to assist with more complex descriptor usage. By
+ *    convention, interrupt A may be used when only one interrupt flag is needed. 0 No effect. 1 Set.
+ *    The INTB flag for this channel will be set when the current descriptor is exhausted.
+ */
+#define DMA_CHANNEL_XFERCFG_SETINTB(x)           (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTB_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTB_MASK)
+#define DMA_CHANNEL_XFERCFG_WIDTH_MASK           (0x300U)
+#define DMA_CHANNEL_XFERCFG_WIDTH_SHIFT          (8U)
+/*! WIDTH - Transfer width used for this DMA channel. 0x0 8-bit. 8-bit transfers are performed
+ *    (8-bit source reads and destination writes). 0x1 16-bit. 6-bit transfers are performed (16-bit
+ *    source reads and destination writes). 0x2 32-bit. 32-bit transfers are performed (32-bit source
+ *    reads and destination writes). 0x3 Reserved. Reserved setting, do not use.
+ */
+#define DMA_CHANNEL_XFERCFG_WIDTH(x)             (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_WIDTH_SHIFT)) & DMA_CHANNEL_XFERCFG_WIDTH_MASK)
+#define DMA_CHANNEL_XFERCFG_SRCINC_MASK          (0x3000U)
+#define DMA_CHANNEL_XFERCFG_SRCINC_SHIFT         (12U)
+/*! SRCINC - Determines whether the source address is incremented for each DMA transfer. 0x0 No
+ *    increment. The source address is not incremented for each transfer. This is the usual case when
+ *    the source is a peripheral device. 0x1 1 x width. The source address is incremented by the
+ *    amount specified by Width for each transfer. This is the usual case when the source is memory. 0x2
+ *    2 x width. The source address is incremented by 2 times the amount specified by Width for each
+ *    transfer. 0x3 4 x width. The source address is incremented by 4 times the amount specified by
+ *    Width for each transfer.
+ */
+#define DMA_CHANNEL_XFERCFG_SRCINC(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SRCINC_SHIFT)) & DMA_CHANNEL_XFERCFG_SRCINC_MASK)
+#define DMA_CHANNEL_XFERCFG_DSTINC_MASK          (0xC000U)
+#define DMA_CHANNEL_XFERCFG_DSTINC_SHIFT         (14U)
+/*! DSTINC - Determines whether the destination address is incremented for each DMA transfer. 0x0 No
+ *    increment. The destination address is not incremented for each transfer. This is the usual
+ *    case when the destination is a peripheral device. 0x1 1 x width. The destination address is
+ *    incremented by the amount specified by Width for each transfer. This is the usual case when the
+ *    destination is memory. 0x2 2 x width. The destination address is incremented by 2 times the
+ *    amount specified by Width for each transfer. 0x3 4 x width. The destination address is incremented
+ *    by 4 times the amount specified by Width for each transfer.
+ */
+#define DMA_CHANNEL_XFERCFG_DSTINC(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_DSTINC_SHIFT)) & DMA_CHANNEL_XFERCFG_DSTINC_MASK)
+#define DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK       (0x3FF0000U)
+#define DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT      (16U)
+/*! XFERCOUNT - Total number of transfers to be performed, minus 1 encoded. The number of bytes
+ *    transferred is: (XFERCOUNT + 1) x data width (as defined by the WIDTH field). Remark: The DMA
+ *    controller uses this bit field during transfer to count down. Hence, it cannot be used by software
+ *    to read back the size of the transfer, for instance, in an interrupt handler. 0x0 = a total
+ *    of 1 transfer will be performed. 0x1 = a total of 2 transfers will be performed. ... 0x3FF = a
+ *    total of 1,024 transfers will be performed.
+ */
+#define DMA_CHANNEL_XFERCFG_XFERCOUNT(x)         (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT)) & DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK)
+/*! @} */
+
+/* The count of DMA_CHANNEL_XFERCFG */
+#define DMA_CHANNEL_XFERCFG_COUNT                (19U)
+
+/*! @name CHANNEL_RESERVED0 - Reserved */
+/*! @{ */
+#define DMA_CHANNEL_RESERVED0_DUMMYWORD_MASK     (0xFFFFFFFFU)
+#define DMA_CHANNEL_RESERVED0_DUMMYWORD_SHIFT    (0U)
+/*! DUMMYWORD - Reserved. The value read from a reserved bit is not defined.
+ */
+#define DMA_CHANNEL_RESERVED0_DUMMYWORD(x)       (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_RESERVED0_DUMMYWORD_SHIFT)) & DMA_CHANNEL_RESERVED0_DUMMYWORD_MASK)
+/*! @} */
+
+/* The count of DMA_CHANNEL_RESERVED0 */
+#define DMA_CHANNEL_RESERVED0_COUNT              (19U)
+
+
+/*!
+ * @}
+ */ /* end of group DMA_Register_Masks */
+
+
+/* DMA - Peripheral instance base addresses */
+/** Peripheral DMA0 base address */
+#define DMA0_BASE                                (0x40085000u)
+/** Peripheral DMA0 base pointer */
+#define DMA0                                     ((DMA_Type *)DMA0_BASE)
+/** Array initializer of DMA peripheral base addresses */
+#define DMA_BASE_ADDRS                           { DMA0_BASE }
+/** Array initializer of DMA peripheral base pointers */
+#define DMA_BASE_PTRS                            { DMA0 }
+/** Interrupt vectors for the DMA peripheral type */
+#define DMA_IRQS                                 { DMA0_IRQn }
+
+/*!
+ * @}
+ */ /* end of group DMA_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- DMIC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup DMIC_Peripheral_Access_Layer DMIC Peripheral Access Layer
+ * @{
+ */
+
+/** DMIC - Register Layout Typedef */
+typedef struct {
+  struct {                                         /* offset: 0x0, array step: 0x100 */
+    __IO uint32_t OSR;                               /**< Oversample Rate register 0. This register selects the oversample rate (CIC decimation rate) for the input channel., array offset: 0x0, array step: 0x100 */
+    __IO uint32_t DIVHFCLK;                          /**< DMIC Clock Register 0. This register controls the clock pre-divider for the input channel., array offset: 0x4, array step: 0x100 */
+    __IO uint32_t PREAC2FSCOEF;                      /**< Pre-Emphasis Filter Coefficient for 2 FS register 0. This register seclects the pre-emphasis filter coeffcient for the input channel when 2 FS mode is used., array offset: 0x8, array step: 0x100 */
+    __IO uint32_t PREAC4FSCOEF;                      /**< Pre-Emphasis Filter Coefficient for 4 FS register 0. This register seclects the pre-emphasis filter coeffcient for the input channel when 4FS mode is used, array offset: 0xC, array step: 0x100 */
+    __IO uint32_t GAINSHIFT;                         /**< Decimator Gain Shift register 0. This register adjusts the gain of the 4FS PCM data from the input filter., array offset: 0x10, array step: 0x100 */
+         uint8_t RESERVED_0[108];
+    __IO uint32_t FIFO_CTRL;                         /**< FIFO Control register 0. This register configures FIFO usage., array offset: 0x80, array step: 0x100 */
+    __IO uint32_t FIFO_STATUS;                       /**< FIFO Status register 0 . This register provides status information for the FIFO and also indicates an interrupt from the peripheral funcion., array offset: 0x84, array step: 0x100 */
+    __IO uint32_t FIFO_DATA;                         /**< FIFO Data Register 0. This register is used to read values that have been received via the PDM stream., array offset: 0x88, array step: 0x100 */
+    __IO uint32_t PHY_CTRL;                          /**< PHY Control / PDM Source Configuration register 0. This register configures how the PDM source signals are interpreted., array offset: 0x8C, array step: 0x100 */
+    __IO uint32_t DC_CTRL;                           /**< DC Control register 0. This register controls the DC filter., array offset: 0x90, array step: 0x100 */
+         uint8_t RESERVED_1[108];
+  } CHANNEL[2];
+       uint8_t RESERVED_0[3328];
+  __IO uint32_t CHANEN;                            /**< Channel Enable register. This register allows enabling either or both PDM channels., offset: 0xF00 */
+       uint8_t RESERVED_1[8];
+  __IO uint32_t IOCFG;                             /**< I/O Configuration register. This register configures the use of the PDM pins., offset: 0xF0C */
+  __IO uint32_t USE2FS;                            /**< Use 2FS register. This register allow selecting 2FS output rather than 1FS output., offset: 0xF10 */
+       uint8_t RESERVED_2[108];
+  __IO uint32_t HWVADGAIN;                         /**< HWVAD input gain register. This register controls the input gain of the HWVAD., offset: 0xF80 */
+  __IO uint32_t HWVADHPFS;                         /**< HWVAD filter control register. This register controls the HWVAD filter setting., offset: 0xF84 */
+  __IO uint32_t HWVADST10;                         /**< HWVAD control register. This register controls the operation of the filter block and resets the internal interrut flag., offset: 0xF88 */
+  __IO uint32_t HWVADRSTT;                         /**< HWVAD filter reset register, offset: 0xF8C */
+  __IO uint32_t HWVADTHGN;                         /**< HWVAD noise estimator gain register, offset: 0xF90 */
+  __IO uint32_t HWVADTHGS;                         /**< HWVAD signal estimator gain register, offset: 0xF94 */
+  __I  uint32_t HWVADLOWZ;                         /**< HWVAD noise envelope estimator register, offset: 0xF98 */
+       uint8_t RESERVED_3[96];
+  __I  uint32_t ID;                                /**< Module Identification register, offset: 0xFFC */
+} DMIC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- DMIC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup DMIC_Register_Masks DMIC Register Masks
+ * @{
+ */
+
+/*! @name CHANNEL_OSR - Oversample Rate register 0. This register selects the oversample rate (CIC decimation rate) for the input channel. */
+/*! @{ */
+#define DMIC_CHANNEL_OSR_OSR_MASK                (0xFFU)
+#define DMIC_CHANNEL_OSR_OSR_SHIFT               (0U)
+/*! OSR - Selects the oversample rate for the related input channel.
+ */
+#define DMIC_CHANNEL_OSR_OSR(x)                  (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_OSR_OSR_SHIFT)) & DMIC_CHANNEL_OSR_OSR_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_OSR */
+#define DMIC_CHANNEL_OSR_COUNT                   (2U)
+
+/*! @name CHANNEL_DIVHFCLK - DMIC Clock Register 0. This register controls the clock pre-divider for the input channel. */
+/*! @{ */
+#define DMIC_CHANNEL_DIVHFCLK_PDMDIV_MASK        (0xFU)
+#define DMIC_CHANNEL_DIVHFCLK_PDMDIV_SHIFT       (0U)
+/*! PDMDIV - PDM clock divider value. 0: divide by 1; 1: divide by 2; 2: divide by 3; 3: divide by
+ *    4; 4: divide by 6; 5: divide by 8; 6: divide by 12; 7: divide by 16; 8: divide by 24; 9: divide
+ *    by 32; 10: divide by 48; 11: divide by 64; 12: divide by 96; 13: divide by 128; others =
+ *    reserved.
+ */
+#define DMIC_CHANNEL_DIVHFCLK_PDMDIV(x)          (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DIVHFCLK_PDMDIV_SHIFT)) & DMIC_CHANNEL_DIVHFCLK_PDMDIV_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_DIVHFCLK */
+#define DMIC_CHANNEL_DIVHFCLK_COUNT              (2U)
+
+/*! @name CHANNEL_PREAC2FSCOEF - Pre-Emphasis Filter Coefficient for 2 FS register 0. This register seclects the pre-emphasis filter coeffcient for the input channel when 2 FS mode is used. */
+/*! @{ */
+#define DMIC_CHANNEL_PREAC2FSCOEF_COMP_MASK      (0x3U)
+#define DMIC_CHANNEL_PREAC2FSCOEF_COMP_SHIFT     (0U)
+/*! COMP - Pre-emphasis filer coefficient for 2 FS mode. 0: Compensation = 0 1: Compensation = -0.16
+ *    2: Compensation = -0.15 3: Compensation = -0.13
+ */
+#define DMIC_CHANNEL_PREAC2FSCOEF_COMP(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PREAC2FSCOEF_COMP_SHIFT)) & DMIC_CHANNEL_PREAC2FSCOEF_COMP_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_PREAC2FSCOEF */
+#define DMIC_CHANNEL_PREAC2FSCOEF_COUNT          (2U)
+
+/*! @name CHANNEL_PREAC4FSCOEF - Pre-Emphasis Filter Coefficient for 4 FS register 0. This register seclects the pre-emphasis filter coeffcient for the input channel when 4FS mode is used */
+/*! @{ */
+#define DMIC_CHANNEL_PREAC4FSCOEF_COMP_MASK      (0x3U)
+#define DMIC_CHANNEL_PREAC4FSCOEF_COMP_SHIFT     (0U)
+/*! COMP - Pre-emphasis filer coefficient for 4 FS mode. 0: Compensation = 0; 1: Compensation =
+ *    -0.16; 2: Compensation = -0.15; 3: Compensation = -0.13.
+ */
+#define DMIC_CHANNEL_PREAC4FSCOEF_COMP(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PREAC4FSCOEF_COMP_SHIFT)) & DMIC_CHANNEL_PREAC4FSCOEF_COMP_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_PREAC4FSCOEF */
+#define DMIC_CHANNEL_PREAC4FSCOEF_COUNT          (2U)
+
+/*! @name CHANNEL_GAINSHIFT - Decimator Gain Shift register 0. This register adjusts the gain of the 4FS PCM data from the input filter. */
+/*! @{ */
+#define DMIC_CHANNEL_GAINSHIFT_GAIN_MASK         (0x3FU)
+#define DMIC_CHANNEL_GAINSHIFT_GAIN_SHIFT        (0U)
+/*! GAIN - Gain control, as a positive or negative (two s complement) number of bits to shift.
+ */
+#define DMIC_CHANNEL_GAINSHIFT_GAIN(x)           (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_GAINSHIFT_GAIN_SHIFT)) & DMIC_CHANNEL_GAINSHIFT_GAIN_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_GAINSHIFT */
+#define DMIC_CHANNEL_GAINSHIFT_COUNT             (2U)
+
+/*! @name CHANNEL_FIFO_CTRL - FIFO Control register 0. This register configures FIFO usage. */
+/*! @{ */
+#define DMIC_CHANNEL_FIFO_CTRL_ENABLE_MASK       (0x1U)
+#define DMIC_CHANNEL_FIFO_CTRL_ENABLE_SHIFT      (0U)
+/*! ENABLE - FIFO enable. 0: FIFO is not enabled. Enabling a DMIC channel with the FIFO disabled
+ *    could be useful in order to avoid a filter settling. delay when a channel is re-enabled after a
+ *    period when the data was not needed. 1: FIFO is enabled. The FIFO must be enabled in order for
+ *    the CPU or DMA to read data from the DMIC via the FIFODATA register.
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_ENABLE(x)         (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_ENABLE_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_ENABLE_MASK)
+#define DMIC_CHANNEL_FIFO_CTRL_RESETN_MASK       (0x2U)
+#define DMIC_CHANNEL_FIFO_CTRL_RESETN_SHIFT      (1U)
+/*! RESETN - FIFO reset. 0: Reset the FIFO. This bit must be cleared before resuming operation. 1: Normal operation.
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_RESETN(x)         (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_RESETN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_RESETN_MASK)
+#define DMIC_CHANNEL_FIFO_CTRL_INTEN_MASK        (0x4U)
+#define DMIC_CHANNEL_FIFO_CTRL_INTEN_SHIFT       (2U)
+/*! INTEN - Interrupt enable. 0: FIFO level interrupts are not enabled. 1: FIFO level interrupts are enabled.
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_INTEN(x)          (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_INTEN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_INTEN_MASK)
+#define DMIC_CHANNEL_FIFO_CTRL_DMAEN_MASK        (0x8U)
+#define DMIC_CHANNEL_FIFO_CTRL_DMAEN_SHIFT       (3U)
+/*! DMAEN - DMA enable. 0: DMA requests are not enabled. 1: DMA requests based on FIFO level are enabled.
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_DMAEN(x)          (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_DMAEN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_DMAEN_MASK)
+#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_MASK      (0x1F0000U)
+#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_SHIFT     (16U)
+/*! TRIGLVL - FIFO trigger level. Selects the data trigger level for interrupt or DMA operation. If
+ *    enabled to do so, the FIFO level can wake up the device. 0: trigger when the FIFO has received
+ *    one entry (is no longer empty). 1: trigger when the FIFO has received two entries. 15:
+ *    trigger when the FIFO has received 16 entries (has become full).
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_FIFO_CTRL */
+#define DMIC_CHANNEL_FIFO_CTRL_COUNT             (2U)
+
+/*! @name CHANNEL_FIFO_STATUS - FIFO Status register 0 . This register provides status information for the FIFO and also indicates an interrupt from the peripheral funcion. */
+/*! @{ */
+#define DMIC_CHANNEL_FIFO_STATUS_INT_MASK        (0x1U)
+#define DMIC_CHANNEL_FIFO_STATUS_INT_SHIFT       (0U)
+/*! INT - Interrupt flag. Asserted when FIFO data reaches the level specified in the FIFOCTRL
+ *    register. Writing a one to this bit clears the flag. Remark: note that the bus clock to the DMIC
+ *    subsystem must be running in order for an interrupt to occur.
+ */
+#define DMIC_CHANNEL_FIFO_STATUS_INT(x)          (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_INT_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_INT_MASK)
+#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN_MASK    (0x2U)
+#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN_SHIFT   (1U)
+/*! OVERRUN - Overrun flag. Indicates that a FIFO overflow has occurred at some point. Writing a one
+ *    to this bit clears the flag. This flag does not cause an interrupt.
+ */
+#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN(x)      (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_OVERRUN_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_OVERRUN_MASK)
+#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_MASK   (0x4U)
+#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_SHIFT  (2U)
+/*! UNDERRUN - Underrun flag. Indicates that a FIFO underflow has occurred at some point. Writing a one to this bit clears the flag.
+ */
+#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN(x)     (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_FIFO_STATUS */
+#define DMIC_CHANNEL_FIFO_STATUS_COUNT           (2U)
+
+/*! @name CHANNEL_FIFO_DATA - FIFO Data Register 0. This register is used to read values that have been received via the PDM stream. */
+/*! @{ */
+#define DMIC_CHANNEL_FIFO_DATA_DATA_MASK         (0xFFFFFFU)
+#define DMIC_CHANNEL_FIFO_DATA_DATA_SHIFT        (0U)
+/*! DATA - Data from the top of the input filter FIFO.
+ */
+#define DMIC_CHANNEL_FIFO_DATA_DATA(x)           (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_DATA_DATA_SHIFT)) & DMIC_CHANNEL_FIFO_DATA_DATA_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_FIFO_DATA */
+#define DMIC_CHANNEL_FIFO_DATA_COUNT             (2U)
+
+/*! @name CHANNEL_PHY_CTRL - PHY Control / PDM Source Configuration register 0. This register configures how the PDM source signals are interpreted. */
+/*! @{ */
+#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL_MASK      (0x1U)
+#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL_SHIFT     (0U)
+/*! PHY_FALL - Capture PDM_DATA. 0: Capture PDM_DATA on the rising edge of PDM_CLK. 1: Capture PDM_DATA on the falling edge of PDM_CLK.
+ */
+#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PHY_CTRL_PHY_FALL_SHIFT)) & DMIC_CHANNEL_PHY_CTRL_PHY_FALL_MASK)
+#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF_MASK      (0x2U)
+#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF_SHIFT     (1U)
+/*! PHY_HALF - Half rate sampling. 0: Standard half rate sampling. The clock to the DMIC is sent at
+ *    the same rate as the decimator is providing. 1: Use half rate sampling. The PDM clock to DMIC
+ *    is divided by 2. Each PDM data is sampled twice into the decimator. The purpose of this mode
+ *    is to allow slower sampling rate in quiet periods of listening for a trigger. Allowing the
+ *    decimator to maintain the same decimation rate between the higher quality, higher PDM clock rate
+ *    and the lower quality lower PDM clock rate means that the user can quickly switch to higher
+ *    quality without re-configuring the decimator, and thus avoiding long filter settling times, when
+ *    switching to higher quality (higher freq PDM clock) for recognition.
+ */
+#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PHY_CTRL_PHY_HALF_SHIFT)) & DMIC_CHANNEL_PHY_CTRL_PHY_HALF_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_PHY_CTRL */
+#define DMIC_CHANNEL_PHY_CTRL_COUNT              (2U)
+
+/*! @name CHANNEL_DC_CTRL - DC Control register 0. This register controls the DC filter. */
+/*! @{ */
+#define DMIC_CHANNEL_DC_CTRL_DCPOLE_MASK         (0x3U)
+#define DMIC_CHANNEL_DC_CTRL_DCPOLE_SHIFT        (0U)
+/*! DCPOLE - DC block filter. 0: Flat response, no filter. 1: 155 Hz. 2: 78 Hz. 3: 39 Hz. These
+ *    frequencies assume a PCM output frequency of 16 MHz. If the actual PCM output frequency is 8 MHz,
+ *    for example, the noted frequencies would be divided by 2.
+ */
+#define DMIC_CHANNEL_DC_CTRL_DCPOLE(x)           (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_DCPOLE_SHIFT)) & DMIC_CHANNEL_DC_CTRL_DCPOLE_MASK)
+#define DMIC_CHANNEL_DC_CTRL_DCGAIN_MASK         (0xF0U)
+#define DMIC_CHANNEL_DC_CTRL_DCGAIN_SHIFT        (4U)
+/*! DCGAIN - Fine gain adjustment in the form of a number of bits to downshift.
+ */
+#define DMIC_CHANNEL_DC_CTRL_DCGAIN(x)           (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_DCGAIN_SHIFT)) & DMIC_CHANNEL_DC_CTRL_DCGAIN_MASK)
+#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_MASK (0x100U)
+#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_SHIFT (8U)
+/*! SATURATEAT16BIT - Selects 16-bit saturation. 0:Results roll over if out range and do not
+ *    saturate. 1:If the result overflows, it saturates at 0xFFFF for positive overflow and 0x8000 for
+ *    negative overflow.
+ */
+#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT(x)  (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_SHIFT)) & DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_DC_CTRL */
+#define DMIC_CHANNEL_DC_CTRL_COUNT               (2U)
+
+/*! @name CHANEN - Channel Enable register. This register allows enabling either or both PDM channels. */
+/*! @{ */
+#define DMIC_CHANEN_EN_CH0_MASK                  (0x1U)
+#define DMIC_CHANEN_EN_CH0_SHIFT                 (0U)
+/*! EN_CH0 - Enable channel 0. When 1, PDM channel 0 is enabled.
+ */
+#define DMIC_CHANEN_EN_CH0(x)                    (((uint32_t)(((uint32_t)(x)) << DMIC_CHANEN_EN_CH0_SHIFT)) & DMIC_CHANEN_EN_CH0_MASK)
+#define DMIC_CHANEN_EN_CH1_MASK                  (0x2U)
+#define DMIC_CHANEN_EN_CH1_SHIFT                 (1U)
+/*! EN_CH1 - Enable channel 1. When 1, PDM channel 1 is enabled.
+ */
+#define DMIC_CHANEN_EN_CH1(x)                    (((uint32_t)(((uint32_t)(x)) << DMIC_CHANEN_EN_CH1_SHIFT)) & DMIC_CHANEN_EN_CH1_MASK)
+/*! @} */
+
+/*! @name IOCFG - I/O Configuration register. This register configures the use of the PDM pins. */
+/*! @{ */
+#define DMIC_IOCFG_CLK_BYPASS0_MASK              (0x1U)
+#define DMIC_IOCFG_CLK_BYPASS0_SHIFT             (0U)
+/*! CLK_BYPASS0 - Bypass CLK0. When 1, PDM_DATA1 becomes the clock for PDM channel 0. This provides
+ *    for the possibility of an external codec taking over the PDM bus.
+ */
+#define DMIC_IOCFG_CLK_BYPASS0(x)                (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_CLK_BYPASS0_SHIFT)) & DMIC_IOCFG_CLK_BYPASS0_MASK)
+#define DMIC_IOCFG_CLK_BYPASS1_MASK              (0x2U)
+#define DMIC_IOCFG_CLK_BYPASS1_SHIFT             (1U)
+/*! CLK_BYPASS1 - Bypass CLK1. When 1, PDM_DATA1 becomes the clock for PDM channel 1. This provides
+ *    for the possibility of an external codec taking over the PDM bus.
+ */
+#define DMIC_IOCFG_CLK_BYPASS1(x)                (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_CLK_BYPASS1_SHIFT)) & DMIC_IOCFG_CLK_BYPASS1_MASK)
+#define DMIC_IOCFG_STEREO_DATA0_MASK             (0x4U)
+#define DMIC_IOCFG_STEREO_DATA0_SHIFT            (2U)
+/*! STEREO_DATA0 - Stereo PDM select. When 1, PDM_DATA0 is routed to both PDM channels in a
+ *    configuration that supports a single stereo digital microphone.
+ */
+#define DMIC_IOCFG_STEREO_DATA0(x)               (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_STEREO_DATA0_SHIFT)) & DMIC_IOCFG_STEREO_DATA0_MASK)
+/*! @} */
+
+/*! @name USE2FS - Use 2FS register. This register allow selecting 2FS output rather than 1FS output. */
+/*! @{ */
+#define DMIC_USE2FS_USE2FS_MASK                  (0x1U)
+#define DMIC_USE2FS_USE2FS_SHIFT                 (0U)
+/*! USE2FS - Use 2FS register. 0: Use 1FS output for PCM data. 1: Use 2FS output for PCM data.
+ */
+#define DMIC_USE2FS_USE2FS(x)                    (((uint32_t)(((uint32_t)(x)) << DMIC_USE2FS_USE2FS_SHIFT)) & DMIC_USE2FS_USE2FS_MASK)
+/*! @} */
+
+/*! @name HWVADGAIN - HWVAD input gain register. This register controls the input gain of the HWVAD. */
+/*! @{ */
+#define DMIC_HWVADGAIN_INPUTGAIN_MASK            (0xFU)
+#define DMIC_HWVADGAIN_INPUTGAIN_SHIFT           (0U)
+/*! INPUTGAIN - Shift value for input bits. 0x0: -10 bits; 0x1: -8 bits; 0x2: -6 bits; 0x3: -4 bits;
+ *    0x4: -2 bits; 0x5: 0 bits (default); 0x6: +2 bits; 0x7: +4 bits; 0x8: +6 bits; 0x9: +8 bits;
+ *    0xA: +10 bits; 0xB: +12 bits; 0xC: +14 bits; 0xD to 0xF: Reserved.
+ */
+#define DMIC_HWVADGAIN_INPUTGAIN(x)              (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADGAIN_INPUTGAIN_SHIFT)) & DMIC_HWVADGAIN_INPUTGAIN_MASK)
+/*! @} */
+
+/*! @name HWVADHPFS - HWVAD filter control register. This register controls the HWVAD filter setting. */
+/*! @{ */
+#define DMIC_HWVADHPFS_HPFS_MASK                 (0x3U)
+#define DMIC_HWVADHPFS_HPFS_SHIFT                (0U)
+/*! HPFS - High pass filter. 0: First filter by-pass; 1: High pass filter with -3dB cut-off at
+ *    1750Hz; 2: High pass filter with -3dB cut-off at 215Hz.; 3: Reserved. This filter setting parameter
+ *    can be used to optimize performance for different background noise situations. In order to
+ *    find the best setting, software needs to perform a rough spectral analysis of the audio signal.
+ *    Rule of thumb: If the amount of low-frequency content in the background noise is small, then
+ *    set HPFS=0x2, otherwise use 0x1.
+ */
+#define DMIC_HWVADHPFS_HPFS(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADHPFS_HPFS_SHIFT)) & DMIC_HWVADHPFS_HPFS_MASK)
+/*! @} */
+
+/*! @name HWVADST10 - HWVAD control register. This register controls the operation of the filter block and resets the internal interrut flag. */
+/*! @{ */
+#define DMIC_HWVADST10_ST10_MASK                 (0x1U)
+#define DMIC_HWVADST10_ST10_SHIFT                (0U)
+/*! ST10 - ST10. Once the HWVAD has triggered an interrupt, a short '1' pulse on bit ST10 clears the
+ *    interrupt. Alternatively, keeping the bit on '1' level for some time has a special function
+ *    for filter convergence. 0: Normal operation, waiting for HWVAD trigger event (stage 0). 1:
+ *    Reset internal interrupt flag by writing a 1 pulse.
+ */
+#define DMIC_HWVADST10_ST10(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADST10_ST10_SHIFT)) & DMIC_HWVADST10_ST10_MASK)
+/*! @} */
+
+/*! @name HWVADRSTT - HWVAD filter reset register */
+/*! @{ */
+#define DMIC_HWVADRSTT_RSTT_MASK                 (0x1U)
+#define DMIC_HWVADRSTT_RSTT_SHIFT                (0U)
+/*! RSTT - HWVAD filter reset. Writing a 1, then writing a '0' resets all filter values. 0: Filters
+ *    anr not held in reset. 1: Holds the filters in reset.
+ */
+#define DMIC_HWVADRSTT_RSTT(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADRSTT_RSTT_SHIFT)) & DMIC_HWVADRSTT_RSTT_MASK)
+/*! @} */
+
+/*! @name HWVADTHGN - HWVAD noise estimator gain register */
+/*! @{ */
+#define DMIC_HWVADTHGN_THGN_MASK                 (0xFU)
+#define DMIC_HWVADTHGN_THGN_SHIFT                (0U)
+/*! THGN - Gain value for the noise estimator. Values 0 to 14. 0 corresponds to a gain of 1. THGN
+ *    and THGS are used within the hardware to determine when to assert the HWVAD result.
+ */
+#define DMIC_HWVADTHGN_THGN(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADTHGN_THGN_SHIFT)) & DMIC_HWVADTHGN_THGN_MASK)
+/*! @} */
+
+/*! @name HWVADTHGS - HWVAD signal estimator gain register */
+/*! @{ */
+#define DMIC_HWVADTHGS_THGS_MASK                 (0xFU)
+#define DMIC_HWVADTHGS_THGS_SHIFT                (0U)
+/*! THGS - Gain value for the signal estimator. Values 0 to 14. 0 corresponds to a gain of 1. THGN
+ *    and THGS are used within the hardware to determine when to assert the HWVAD result.
+ */
+#define DMIC_HWVADTHGS_THGS(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADTHGS_THGS_SHIFT)) & DMIC_HWVADTHGS_THGS_MASK)
+/*! @} */
+
+/*! @name HWVADLOWZ - HWVAD noise envelope estimator register */
+/*! @{ */
+#define DMIC_HWVADLOWZ_LOWZ_MASK                 (0xFFFFU)
+#define DMIC_HWVADLOWZ_LOWZ_SHIFT                (0U)
+/*! LOWZ - Noise envelope estimator value. This register contains 2 bytes of the output of filter
+ *    stage z7. It can be used as an indication for the noise floor and must be evaluated by software.
+ *    Note: For power saving reasons this register is not synchronized to the AHB bus clock domain.
+ *    To ensure correct data is read, the register should be read twice. If the data is the same,
+ *    then the data is correct, if not, the register should be read one more time. The noise floor is
+ *    a slowly moving calculation, so several reads in a row can guarantee that register value
+ *    being read can be assured to not be in the middle of a transition.
+ */
+#define DMIC_HWVADLOWZ_LOWZ(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADLOWZ_LOWZ_SHIFT)) & DMIC_HWVADLOWZ_LOWZ_MASK)
+/*! @} */
+
+/*! @name ID - Module Identification register */
+/*! @{ */
+#define DMIC_ID_ID_MASK                          (0xFFFFFFFFU)
+#define DMIC_ID_ID_SHIFT                         (0U)
+/*! ID - Indicates module ID and the number of channels in this DMIC interface.
+ */
+#define DMIC_ID_ID(x)                            (((uint32_t)(((uint32_t)(x)) << DMIC_ID_ID_SHIFT)) & DMIC_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group DMIC_Register_Masks */
+
+
+/* DMIC - Peripheral instance base addresses */
+/** Peripheral DMIC0 base address */
+#define DMIC0_BASE                               (0x4008A000u)
+/** Peripheral DMIC0 base pointer */
+#define DMIC0                                    ((DMIC_Type *)DMIC0_BASE)
+/** Array initializer of DMIC peripheral base addresses */
+#define DMIC_BASE_ADDRS                          { DMIC0_BASE }
+/** Array initializer of DMIC peripheral base pointers */
+#define DMIC_BASE_PTRS                           { DMIC0 }
+/** Interrupt vectors for the DMIC peripheral type */
+#define DMIC_IRQS                                { DMIC0_IRQn }
+#define DMIC_HWVAD_IRQS                          { HWVAD0_IRQn }
+
+/*!
+ * @}
+ */ /* end of group DMIC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- FLASH Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup FLASH_Peripheral_Access_Layer FLASH Peripheral Access Layer
+ * @{
+ */
+
+/** FLASH - Register Layout Typedef */
+typedef struct {
+  __O  uint32_t CMD;                               /**< command register, offset: 0x0 */
+  __O  uint32_t EVENT;                             /**< event register, offset: 0x4 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t AUTOPROG;                          /**< specifies what commands are performed on AHB write, offset: 0xC */
+  __IO uint32_t STARTA;                            /**< start address for next flash command, offset: 0x10 */
+  __IO uint32_t STOPA;                             /**< end address for next flash command, if command operates on address ranges, offset: 0x14 */
+       uint8_t RESERVED_1[104];
+  __IO uint32_t DATAW[4];                          /**< data register, word 0-3; Memory data, or command parameter, or command result., array offset: 0x80, array step: 0x4 */
+       uint8_t RESERVED_2[3912];
+  __O  uint32_t INT_CLR_ENABLE;                    /**< Clear interrupt enable bits, offset: 0xFD8 */
+  __O  uint32_t INT_SET_ENABLE;                    /**< Set interrupt enable bits, offset: 0xFDC */
+  __I  uint32_t INT_STATUS;                        /**< Interrupt status bits, offset: 0xFE0 */
+  __I  uint32_t INT_ENABLE;                        /**< Interrupt enable bits, offset: 0xFE4 */
+  __O  uint32_t INT_CLR_STATUS;                    /**< Clear interrupt status bits, offset: 0xFE8 */
+  __O  uint32_t INT_SET_STATUS;                    /**< Set interrupt status bits, offset: 0xFEC */
+       uint8_t RESERVED_3[12];
+  __I  uint32_t MODULE_ID;                         /**< Controller and Memory module identification, offset: 0xFFC */
+} FLASH_Type;
+
+/* ----------------------------------------------------------------------------
+   -- FLASH Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup FLASH_Register_Masks FLASH Register Masks
+ * @{
+ */
+
+/*! @name CMD - command register */
+/*! @{ */
+#define FLASH_CMD_CMD_MASK                       (0xFFFFFFFFU)
+#define FLASH_CMD_CMD_SHIFT                      (0U)
+/*! CMD - command register
+ */
+#define FLASH_CMD_CMD(x)                         (((uint32_t)(((uint32_t)(x)) << FLASH_CMD_CMD_SHIFT)) & FLASH_CMD_CMD_MASK)
+/*! @} */
+
+/*! @name EVENT - event register */
+/*! @{ */
+#define FLASH_EVENT_RST_MASK                     (0x1U)
+#define FLASH_EVENT_RST_SHIFT                    (0U)
+/*! RST - When bit is set, the controller and flash are reset.
+ */
+#define FLASH_EVENT_RST(x)                       (((uint32_t)(((uint32_t)(x)) << FLASH_EVENT_RST_SHIFT)) & FLASH_EVENT_RST_MASK)
+#define FLASH_EVENT_WAKEUP_MASK                  (0x2U)
+#define FLASH_EVENT_WAKEUP_SHIFT                 (1U)
+/*! WAKEUP - When bit is set, the controller wakes up from whatever low power or powerdown mode was
+ *    active. If not in a powerdown mode, this bit has no effect.
+ */
+#define FLASH_EVENT_WAKEUP(x)                    (((uint32_t)(((uint32_t)(x)) << FLASH_EVENT_WAKEUP_SHIFT)) & FLASH_EVENT_WAKEUP_MASK)
+#define FLASH_EVENT_ABORT_MASK                   (0x4U)
+#define FLASH_EVENT_ABORT_SHIFT                  (2U)
+/*! ABORT - When bit is set, a running program/erase command is aborted.
+ */
+#define FLASH_EVENT_ABORT(x)                     (((uint32_t)(((uint32_t)(x)) << FLASH_EVENT_ABORT_SHIFT)) & FLASH_EVENT_ABORT_MASK)
+/*! @} */
+
+/*! @name AUTOPROG - specifies what commands are performed on AHB write */
+/*! @{ */
+#define FLASH_AUTOPROG_AUTOPROG_MASK             (0x3U)
+#define FLASH_AUTOPROG_AUTOPROG_SHIFT            (0U)
+/*! AUTOPROG - Auto programmings configuration. 00: auto programming switched off. 01: execute write
+ *    word . 10: execute write word then, if the last word in a page was written, program page .
+ *    11: reserved for future use / no action.
+ */
+#define FLASH_AUTOPROG_AUTOPROG(x)               (((uint32_t)(((uint32_t)(x)) << FLASH_AUTOPROG_AUTOPROG_SHIFT)) & FLASH_AUTOPROG_AUTOPROG_MASK)
+/*! @} */
+
+/*! @name STARTA - start address for next flash command */
+/*! @{ */
+#define FLASH_STARTA_STARTA_MASK                 (0x3FFFFU)
+#define FLASH_STARTA_STARTA_SHIFT                (0U)
+/*! STARTA - Address / Start address for commands that take an address (range) as a parameter. The
+ *    address is in units of memory words, not bytes.
+ */
+#define FLASH_STARTA_STARTA(x)                   (((uint32_t)(((uint32_t)(x)) << FLASH_STARTA_STARTA_SHIFT)) & FLASH_STARTA_STARTA_MASK)
+/*! @} */
+
+/*! @name STOPA - end address for next flash command, if command operates on address ranges */
+/*! @{ */
+#define FLASH_STOPA_STOPA_MASK                   (0x3FFFFU)
+#define FLASH_STOPA_STOPA_SHIFT                  (0U)
+/*! STOPA - Stop address for commands that take an address range as a parameter (the word specified
+ *    by STOPA is included in the address range). The address is in units of memory words, not bytes.
+ */
+#define FLASH_STOPA_STOPA(x)                     (((uint32_t)(((uint32_t)(x)) << FLASH_STOPA_STOPA_SHIFT)) & FLASH_STOPA_STOPA_MASK)
+/*! @} */
+
+/*! @name DATAW - data register, word 0-3; Memory data, or command parameter, or command result. */
+/*! @{ */
+#define FLASH_DATAW_DATAW_MASK                   (0xFFFFFFFFU)
+#define FLASH_DATAW_DATAW_SHIFT                  (0U)
+/*! DATAW - data register, word 0-3; Memory data, or command parameter, or command result.
+ */
+#define FLASH_DATAW_DATAW(x)                     (((uint32_t)(((uint32_t)(x)) << FLASH_DATAW_DATAW_SHIFT)) & FLASH_DATAW_DATAW_MASK)
+/*! @} */
+
+/* The count of FLASH_DATAW */
+#define FLASH_DATAW_COUNT                        (4U)
+
+/*! @name INT_CLR_ENABLE - Clear interrupt enable bits */
+/*! @{ */
+#define FLASH_INT_CLR_ENABLE_FAIL_MASK           (0x1U)
+#define FLASH_INT_CLR_ENABLE_FAIL_SHIFT          (0U)
+/*! FAIL - When a CLR_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is cleared
+ */
+#define FLASH_INT_CLR_ENABLE_FAIL(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_ENABLE_FAIL_SHIFT)) & FLASH_INT_CLR_ENABLE_FAIL_MASK)
+#define FLASH_INT_CLR_ENABLE_ERR_MASK            (0x2U)
+#define FLASH_INT_CLR_ENABLE_ERR_SHIFT           (1U)
+/*! ERR - When a CLR_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is cleared
+ */
+#define FLASH_INT_CLR_ENABLE_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_ENABLE_ERR_SHIFT)) & FLASH_INT_CLR_ENABLE_ERR_MASK)
+#define FLASH_INT_CLR_ENABLE_DONE_MASK           (0x4U)
+#define FLASH_INT_CLR_ENABLE_DONE_SHIFT          (2U)
+/*! DONE - When a CLR_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is cleared
+ */
+#define FLASH_INT_CLR_ENABLE_DONE(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_ENABLE_DONE_SHIFT)) & FLASH_INT_CLR_ENABLE_DONE_MASK)
+#define FLASH_INT_CLR_ENABLE_ECC_ERR_MASK        (0x8U)
+#define FLASH_INT_CLR_ENABLE_ECC_ERR_SHIFT       (3U)
+/*! ECC_ERR - When a CLR_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is cleared
+ */
+#define FLASH_INT_CLR_ENABLE_ECC_ERR(x)          (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_ENABLE_ECC_ERR_SHIFT)) & FLASH_INT_CLR_ENABLE_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_SET_ENABLE - Set interrupt enable bits */
+/*! @{ */
+#define FLASH_INT_SET_ENABLE_FAIL_MASK           (0x1U)
+#define FLASH_INT_SET_ENABLE_FAIL_SHIFT          (0U)
+/*! FAIL - When a SET_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is set
+ */
+#define FLASH_INT_SET_ENABLE_FAIL(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_ENABLE_FAIL_SHIFT)) & FLASH_INT_SET_ENABLE_FAIL_MASK)
+#define FLASH_INT_SET_ENABLE_ERR_MASK            (0x2U)
+#define FLASH_INT_SET_ENABLE_ERR_SHIFT           (1U)
+/*! ERR - When a SET_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is set
+ */
+#define FLASH_INT_SET_ENABLE_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_ENABLE_ERR_SHIFT)) & FLASH_INT_SET_ENABLE_ERR_MASK)
+#define FLASH_INT_SET_ENABLE_DONE_MASK           (0x4U)
+#define FLASH_INT_SET_ENABLE_DONE_SHIFT          (2U)
+/*! DONE - When a SET_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is set
+ */
+#define FLASH_INT_SET_ENABLE_DONE(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_ENABLE_DONE_SHIFT)) & FLASH_INT_SET_ENABLE_DONE_MASK)
+#define FLASH_INT_SET_ENABLE_ECC_ERR_MASK        (0x8U)
+#define FLASH_INT_SET_ENABLE_ECC_ERR_SHIFT       (3U)
+/*! ECC_ERR - When a SET_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is set
+ */
+#define FLASH_INT_SET_ENABLE_ECC_ERR(x)          (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_ENABLE_ECC_ERR_SHIFT)) & FLASH_INT_SET_ENABLE_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_STATUS - Interrupt status bits */
+/*! @{ */
+#define FLASH_INT_STATUS_FAIL_MASK               (0x1U)
+#define FLASH_INT_STATUS_FAIL_SHIFT              (0U)
+/*! FAIL - This status bit is set if execution of a (legal) command failed. The flag can be set at
+ *    any time during command execution, not just at the end.
+ */
+#define FLASH_INT_STATUS_FAIL(x)                 (((uint32_t)(((uint32_t)(x)) << FLASH_INT_STATUS_FAIL_SHIFT)) & FLASH_INT_STATUS_FAIL_MASK)
+#define FLASH_INT_STATUS_ERR_MASK                (0x2U)
+#define FLASH_INT_STATUS_ERR_SHIFT               (1U)
+/*! ERR - This status bit is set if execution of an illegal command is detected. A command is
+ *    illegal if it is unknown, or it is not allowed in the current mode, or it is violating access
+ *    restrictions, or it has invalid parameters.
+ */
+#define FLASH_INT_STATUS_ERR(x)                  (((uint32_t)(((uint32_t)(x)) << FLASH_INT_STATUS_ERR_SHIFT)) & FLASH_INT_STATUS_ERR_MASK)
+#define FLASH_INT_STATUS_DONE_MASK               (0x4U)
+#define FLASH_INT_STATUS_DONE_SHIFT              (2U)
+/*! DONE - This status bit is set at the end of command execution
+ */
+#define FLASH_INT_STATUS_DONE(x)                 (((uint32_t)(((uint32_t)(x)) << FLASH_INT_STATUS_DONE_SHIFT)) & FLASH_INT_STATUS_DONE_MASK)
+#define FLASH_INT_STATUS_ECC_ERR_MASK            (0x8U)
+#define FLASH_INT_STATUS_ECC_ERR_SHIFT           (3U)
+/*! ECC_ERR - This status bit is set if, during a memory read operation (either a user-requested
+ *    read, or a speculative read, or reads performed by a controller command), a correctable or
+ *    uncorrectable error is detected by ECC decoding logic.
+ */
+#define FLASH_INT_STATUS_ECC_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_STATUS_ECC_ERR_SHIFT)) & FLASH_INT_STATUS_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_ENABLE - Interrupt enable bits */
+/*! @{ */
+#define FLASH_INT_ENABLE_FAIL_MASK               (0x1U)
+#define FLASH_INT_ENABLE_FAIL_SHIFT              (0U)
+/*! FAIL - If an INT_ENABLE bit is set, an interrupt request will be generated if the corresponding INT_STATUS bit is high.
+ */
+#define FLASH_INT_ENABLE_FAIL(x)                 (((uint32_t)(((uint32_t)(x)) << FLASH_INT_ENABLE_FAIL_SHIFT)) & FLASH_INT_ENABLE_FAIL_MASK)
+#define FLASH_INT_ENABLE_ERR_MASK                (0x2U)
+#define FLASH_INT_ENABLE_ERR_SHIFT               (1U)
+/*! ERR - If an INT_ENABLE bit is set, an interrupt request will be generated if the corresponding INT_STATUS bit is high.
+ */
+#define FLASH_INT_ENABLE_ERR(x)                  (((uint32_t)(((uint32_t)(x)) << FLASH_INT_ENABLE_ERR_SHIFT)) & FLASH_INT_ENABLE_ERR_MASK)
+#define FLASH_INT_ENABLE_DONE_MASK               (0x4U)
+#define FLASH_INT_ENABLE_DONE_SHIFT              (2U)
+/*! DONE - If an INT_ENABLE bit is set, an interrupt request will be generated if the corresponding INT_STATUS bit is high.
+ */
+#define FLASH_INT_ENABLE_DONE(x)                 (((uint32_t)(((uint32_t)(x)) << FLASH_INT_ENABLE_DONE_SHIFT)) & FLASH_INT_ENABLE_DONE_MASK)
+#define FLASH_INT_ENABLE_ECC_ERR_MASK            (0x8U)
+#define FLASH_INT_ENABLE_ECC_ERR_SHIFT           (3U)
+/*! ECC_ERR - If an INT_ENABLE bit is set, an interrupt request will be generated if the corresponding INT_STATUS bit is high.
+ */
+#define FLASH_INT_ENABLE_ECC_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_ENABLE_ECC_ERR_SHIFT)) & FLASH_INT_ENABLE_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_CLR_STATUS - Clear interrupt status bits */
+/*! @{ */
+#define FLASH_INT_CLR_STATUS_FAIL_MASK           (0x1U)
+#define FLASH_INT_CLR_STATUS_FAIL_SHIFT          (0U)
+/*! FAIL - When a CLR_STATUS bit is written to 1, the corresponding INT_STATUS bit is cleared
+ */
+#define FLASH_INT_CLR_STATUS_FAIL(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_STATUS_FAIL_SHIFT)) & FLASH_INT_CLR_STATUS_FAIL_MASK)
+#define FLASH_INT_CLR_STATUS_ERR_MASK            (0x2U)
+#define FLASH_INT_CLR_STATUS_ERR_SHIFT           (1U)
+/*! ERR - When a CLR_STATUS bit is written to 1, the corresponding INT_STATUS bit is cleared
+ */
+#define FLASH_INT_CLR_STATUS_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_STATUS_ERR_SHIFT)) & FLASH_INT_CLR_STATUS_ERR_MASK)
+#define FLASH_INT_CLR_STATUS_DONE_MASK           (0x4U)
+#define FLASH_INT_CLR_STATUS_DONE_SHIFT          (2U)
+/*! DONE - When a CLR_STATUS bit is written to 1, the corresponding INT_STATUS bit is cleared
+ */
+#define FLASH_INT_CLR_STATUS_DONE(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_STATUS_DONE_SHIFT)) & FLASH_INT_CLR_STATUS_DONE_MASK)
+#define FLASH_INT_CLR_STATUS_ECC_ERR_MASK        (0x8U)
+#define FLASH_INT_CLR_STATUS_ECC_ERR_SHIFT       (3U)
+/*! ECC_ERR - When a CLR_STATUS bit is written to 1, the corresponding INT_STATUS bit is cleared
+ */
+#define FLASH_INT_CLR_STATUS_ECC_ERR(x)          (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_STATUS_ECC_ERR_SHIFT)) & FLASH_INT_CLR_STATUS_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_SET_STATUS - Set interrupt status bits */
+/*! @{ */
+#define FLASH_INT_SET_STATUS_FAIL_MASK           (0x1U)
+#define FLASH_INT_SET_STATUS_FAIL_SHIFT          (0U)
+/*! FAIL - When a SET_STATUS bit is written to 1, the corresponding INT_STATUS bit is set
+ */
+#define FLASH_INT_SET_STATUS_FAIL(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_STATUS_FAIL_SHIFT)) & FLASH_INT_SET_STATUS_FAIL_MASK)
+#define FLASH_INT_SET_STATUS_ERR_MASK            (0x2U)
+#define FLASH_INT_SET_STATUS_ERR_SHIFT           (1U)
+/*! ERR - When a SET_STATUS bit is written to 1, the corresponding INT_STATUS bit is set
+ */
+#define FLASH_INT_SET_STATUS_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_STATUS_ERR_SHIFT)) & FLASH_INT_SET_STATUS_ERR_MASK)
+#define FLASH_INT_SET_STATUS_DONE_MASK           (0x4U)
+#define FLASH_INT_SET_STATUS_DONE_SHIFT          (2U)
+/*! DONE - When a SET_STATUS bit is written to 1, the corresponding INT_STATUS bit is set
+ */
+#define FLASH_INT_SET_STATUS_DONE(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_STATUS_DONE_SHIFT)) & FLASH_INT_SET_STATUS_DONE_MASK)
+#define FLASH_INT_SET_STATUS_ECC_ERR_MASK        (0x8U)
+#define FLASH_INT_SET_STATUS_ECC_ERR_SHIFT       (3U)
+/*! ECC_ERR - When a SET_STATUS bit is written to 1, the corresponding INT_STATUS bit is set
+ */
+#define FLASH_INT_SET_STATUS_ECC_ERR(x)          (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_STATUS_ECC_ERR_SHIFT)) & FLASH_INT_SET_STATUS_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name MODULE_ID - Controller and Memory module identification */
+/*! @{ */
+#define FLASH_MODULE_ID_APERTURE_MASK            (0xFFU)
+#define FLASH_MODULE_ID_APERTURE_SHIFT           (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define FLASH_MODULE_ID_APERTURE(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_MODULE_ID_APERTURE_SHIFT)) & FLASH_MODULE_ID_APERTURE_MASK)
+#define FLASH_MODULE_ID_MINOR_REV_MASK           (0xF00U)
+#define FLASH_MODULE_ID_MINOR_REV_SHIFT          (8U)
+/*! MINOR_REV - Minor revision i.e. with no software consequences
+ */
+#define FLASH_MODULE_ID_MINOR_REV(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_MODULE_ID_MINOR_REV_SHIFT)) & FLASH_MODULE_ID_MINOR_REV_MASK)
+#define FLASH_MODULE_ID_MAJOR_REV_MASK           (0xF000U)
+#define FLASH_MODULE_ID_MAJOR_REV_SHIFT          (12U)
+/*! MAJOR_REV - Major revision i.e. implies software modifications
+ */
+#define FLASH_MODULE_ID_MAJOR_REV(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_MODULE_ID_MAJOR_REV_SHIFT)) & FLASH_MODULE_ID_MAJOR_REV_MASK)
+#define FLASH_MODULE_ID_ID_MASK                  (0xFFFF0000U)
+#define FLASH_MODULE_ID_ID_SHIFT                 (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define FLASH_MODULE_ID_ID(x)                    (((uint32_t)(((uint32_t)(x)) << FLASH_MODULE_ID_ID_SHIFT)) & FLASH_MODULE_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group FLASH_Register_Masks */
+
+
+/* FLASH - Peripheral instance base addresses */
+/** Peripheral FLASH base address */
+#define FLASH_BASE                               (0x40009000u)
+/** Peripheral FLASH base pointer */
+#define FLASH                                    ((FLASH_Type *)FLASH_BASE)
+/** Array initializer of FLASH peripheral base addresses */
+#define FLASH_BASE_ADDRS                         { FLASH_BASE }
+/** Array initializer of FLASH peripheral base pointers */
+#define FLASH_BASE_PTRS                          { FLASH }
+
+/*!
+ * @}
+ */ /* end of group FLASH_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- FLEXCOMM Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup FLEXCOMM_Peripheral_Access_Layer FLEXCOMM Peripheral Access Layer
+ * @{
+ */
+
+/** FLEXCOMM - Register Layout Typedef */
+typedef struct {
+       uint8_t RESERVED_0[4088];
+  __IO uint32_t PSELID;                            /**< Peripheral Select and Flexcomm ID register., offset: 0xFF8 */
+  __IO uint32_t PID;                               /**< Peripheral identification register., offset: 0xFFC */
+} FLEXCOMM_Type;
+
+/* ----------------------------------------------------------------------------
+   -- FLEXCOMM Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup FLEXCOMM_Register_Masks FLEXCOMM Register Masks
+ * @{
+ */
+
+/*! @name PSELID - Peripheral Select and Flexcomm ID register. */
+/*! @{ */
+#define FLEXCOMM_PSELID_PERSEL_MASK              (0x7U)
+#define FLEXCOMM_PSELID_PERSEL_SHIFT             (0U)
+/*! PERSEL - Peripheral Select. This field is writable by software.
+ *  0b000..No peripheral selected.
+ *  0b001..USART function selected.
+ *  0b010..SPI function selected.
+ *  0b011..I2C function selected.
+ *  0b100..I2S transmit function selected.
+ *  0b101..I2S receive function selected.
+ *  0b110..Reserved
+ *  0b111..Reserved
+ */
+#define FLEXCOMM_PSELID_PERSEL(x)                (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_PERSEL_SHIFT)) & FLEXCOMM_PSELID_PERSEL_MASK)
+#define FLEXCOMM_PSELID_LOCK_MASK                (0x8U)
+#define FLEXCOMM_PSELID_LOCK_SHIFT               (3U)
+/*! LOCK - Lock the peripheral select. This field is writable by software.
+ *  0b0..Peripheral select can be changed by software.
+ *  0b1..Peripheral select is locked and cannot be changed until this Flexcomm or the entire device is reset.
+ */
+#define FLEXCOMM_PSELID_LOCK(x)                  (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_LOCK_SHIFT)) & FLEXCOMM_PSELID_LOCK_MASK)
+#define FLEXCOMM_PSELID_USARTPRESENT_MASK        (0x10U)
+#define FLEXCOMM_PSELID_USARTPRESENT_SHIFT       (4U)
+/*! USARTPRESENT - USART present indicator. This field is Read-only.
+ *  0b0..This Flexcomm does not include the USART function.
+ *  0b1..This Flexcomm includes the USART function.
+ */
+#define FLEXCOMM_PSELID_USARTPRESENT(x)          (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_USARTPRESENT_SHIFT)) & FLEXCOMM_PSELID_USARTPRESENT_MASK)
+#define FLEXCOMM_PSELID_SPIPRESENT_MASK          (0x20U)
+#define FLEXCOMM_PSELID_SPIPRESENT_SHIFT         (5U)
+/*! SPIPRESENT - SPI present indicator. This field is Read-only.
+ *  0b0..This Flexcomm does not include the SPI function.
+ *  0b1..This Flexcomm includes the SPI function.
+ */
+#define FLEXCOMM_PSELID_SPIPRESENT(x)            (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_SPIPRESENT_SHIFT)) & FLEXCOMM_PSELID_SPIPRESENT_MASK)
+#define FLEXCOMM_PSELID_I2CPRESENT_MASK          (0x40U)
+#define FLEXCOMM_PSELID_I2CPRESENT_SHIFT         (6U)
+/*! I2CPRESENT - I2C present indicator. This field is Read-only.
+ *  0b0..This Flexcomm does not include the I2C function.
+ *  0b1..This Flexcomm includes the I2C function.
+ */
+#define FLEXCOMM_PSELID_I2CPRESENT(x)            (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_I2CPRESENT_SHIFT)) & FLEXCOMM_PSELID_I2CPRESENT_MASK)
+#define FLEXCOMM_PSELID_I2SPRESENT_MASK          (0x80U)
+#define FLEXCOMM_PSELID_I2SPRESENT_SHIFT         (7U)
+/*! I2SPRESENT - I 2S present indicator. This field is Read-only.
+ *  0b0..This Flexcomm does not include the I2S function.
+ *  0b1..This Flexcomm includes the I2S function.
+ */
+#define FLEXCOMM_PSELID_I2SPRESENT(x)            (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_I2SPRESENT_SHIFT)) & FLEXCOMM_PSELID_I2SPRESENT_MASK)
+#define FLEXCOMM_PSELID_ID_MASK                  (0xFFFFF000U)
+#define FLEXCOMM_PSELID_ID_SHIFT                 (12U)
+/*! ID - Flexcomm ID.
+ */
+#define FLEXCOMM_PSELID_ID(x)                    (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_ID_SHIFT)) & FLEXCOMM_PSELID_ID_MASK)
+/*! @} */
+
+/*! @name PID - Peripheral identification register. */
+/*! @{ */
+#define FLEXCOMM_PID_Minor_Rev_MASK              (0xF00U)
+#define FLEXCOMM_PID_Minor_Rev_SHIFT             (8U)
+/*! Minor_Rev - Minor revision of module implementation.
+ */
+#define FLEXCOMM_PID_Minor_Rev(x)                (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_Minor_Rev_SHIFT)) & FLEXCOMM_PID_Minor_Rev_MASK)
+#define FLEXCOMM_PID_Major_Rev_MASK              (0xF000U)
+#define FLEXCOMM_PID_Major_Rev_SHIFT             (12U)
+/*! Major_Rev - Major revision of module implementation.
+ */
+#define FLEXCOMM_PID_Major_Rev(x)                (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_Major_Rev_SHIFT)) & FLEXCOMM_PID_Major_Rev_MASK)
+#define FLEXCOMM_PID_ID_MASK                     (0xFFFF0000U)
+#define FLEXCOMM_PID_ID_SHIFT                    (16U)
+/*! ID - Module identifier for the selected function.
+ */
+#define FLEXCOMM_PID_ID(x)                       (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_ID_SHIFT)) & FLEXCOMM_PID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group FLEXCOMM_Register_Masks */
+
+
+/* FLEXCOMM - Peripheral instance base addresses */
+/** Peripheral FLEXCOMM0 base address */
+#define FLEXCOMM0_BASE                           (0x4008B000u)
+/** Peripheral FLEXCOMM0 base pointer */
+#define FLEXCOMM0                                ((FLEXCOMM_Type *)FLEXCOMM0_BASE)
+/** Peripheral FLEXCOMM1 base address */
+#define FLEXCOMM1_BASE                           (0x4008C000u)
+/** Peripheral FLEXCOMM1 base pointer */
+#define FLEXCOMM1                                ((FLEXCOMM_Type *)FLEXCOMM1_BASE)
+/** Peripheral FLEXCOMM2 base address */
+#define FLEXCOMM2_BASE                           (0x40003000u)
+/** Peripheral FLEXCOMM2 base pointer */
+#define FLEXCOMM2                                ((FLEXCOMM_Type *)FLEXCOMM2_BASE)
+/** Peripheral FLEXCOMM3 base address */
+#define FLEXCOMM3_BASE                           (0x40004000u)
+/** Peripheral FLEXCOMM3 base pointer */
+#define FLEXCOMM3                                ((FLEXCOMM_Type *)FLEXCOMM3_BASE)
+/** Peripheral FLEXCOMM4 base address */
+#define FLEXCOMM4_BASE                           (0x4008D000u)
+/** Peripheral FLEXCOMM4 base pointer */
+#define FLEXCOMM4                                ((FLEXCOMM_Type *)FLEXCOMM4_BASE)
+/** Peripheral FLEXCOMM5 base address */
+#define FLEXCOMM5_BASE                           (0x4008E000u)
+/** Peripheral FLEXCOMM5 base pointer */
+#define FLEXCOMM5                                ((FLEXCOMM_Type *)FLEXCOMM5_BASE)
+/** Peripheral FLEXCOMM6 base address */
+#define FLEXCOMM6_BASE                           (0x40005000u)
+/** Peripheral FLEXCOMM6 base pointer */
+#define FLEXCOMM6                                ((FLEXCOMM_Type *)FLEXCOMM6_BASE)
+/** Array initializer of FLEXCOMM peripheral base addresses */
+#define FLEXCOMM_BASE_ADDRS                      { FLEXCOMM0_BASE, FLEXCOMM1_BASE, FLEXCOMM2_BASE, FLEXCOMM3_BASE, FLEXCOMM4_BASE, FLEXCOMM5_BASE, FLEXCOMM6_BASE }
+/** Array initializer of FLEXCOMM peripheral base pointers */
+#define FLEXCOMM_BASE_PTRS                       { FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6 }
+/** Interrupt vectors for the FLEXCOMM peripheral type */
+#define FLEXCOMM_IRQS                            { FLEXCOMM0_IRQn, FLEXCOMM1_IRQn, FLEXCOMM2_IRQn, FLEXCOMM3_IRQn, FLEXCOMM4_IRQn, FLEXCOMM5_IRQn, FLEXCOMM6_IRQn }
+/*!
+ * @}
+ */ /* end of group FLEXCOMM_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- GINT Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup GINT_Peripheral_Access_Layer GINT Peripheral Access Layer
+ * @{
+ */
+
+/** GINT - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< GPIO Grouped interrupt control register, offset: 0x0 */
+       uint8_t RESERVED_0[28];
+  __IO uint32_t PORT_POL[1];                       /**< GPIO Grouped Interrupt polarity register. Configure the pin polarity of each PIO signal into the group interrupt function. If a bit is low then the corresponding PIO has an active low contribution into the group interrupt. If a bit is high then the corresponding PIO has an active high contribution., array offset: 0x20, array step: 0x4 */
+       uint8_t RESERVED_1[28];
+  __IO uint32_t PORT_ENA[1];                       /**< GPIO Grouped Interrupt port enable register. When a bit is set then the corresponding PIO is enabled for the group interrupt function., array offset: 0x40, array step: 0x4 */
+} GINT_Type;
+
+/* ----------------------------------------------------------------------------
+   -- GINT Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup GINT_Register_Masks GINT Register Masks
+ * @{
+ */
+
+/*! @name CTRL - GPIO Grouped interrupt control register */
+/*! @{ */
+#define GINT_CTRL_INT_MASK                       (0x1U)
+#define GINT_CTRL_INT_SHIFT                      (0U)
+/*! INT - Group interrupt status. This bit is cleared by writing a one to it. Writing zero has no effect.
+ */
+#define GINT_CTRL_INT(x)                         (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_INT_SHIFT)) & GINT_CTRL_INT_MASK)
+#define GINT_CTRL_COMB_MASK                      (0x2U)
+#define GINT_CTRL_COMB_SHIFT                     (1U)
+/*! COMB - Combine enabled inputs for group interrupt. 0: Or, OR functionality: A grouped interrupt
+ *    is generated when any one of the enabled inputs is active (based on its programmed polarity)
+ *    1: And, AND functionality: An interrupt is generated when all enabled bits are active (based on
+ *    their programmed polarity)
+ */
+#define GINT_CTRL_COMB(x)                        (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_COMB_SHIFT)) & GINT_CTRL_COMB_MASK)
+#define GINT_CTRL_TRIG_MASK                      (0x4U)
+#define GINT_CTRL_TRIG_SHIFT                     (2U)
+/*! TRIG - Group interrupt trigger. 0: Edge Triggered. 1: Level Triggered.
+ */
+#define GINT_CTRL_TRIG(x)                        (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_TRIG_SHIFT)) & GINT_CTRL_TRIG_MASK)
+/*! @} */
+
+/*! @name PORT_POL - GPIO Grouped Interrupt polarity register. Configure the pin polarity of each PIO signal into the group interrupt function. If a bit is low then the corresponding PIO has an active low contribution into the group interrupt. If a bit is high then the corresponding PIO has an active high contribution. */
+/*! @{ */
+#define GINT_PORT_POL_POL_MASK                   (0x3FFFFFU)
+#define GINT_PORT_POL_POL_SHIFT                  (0U)
+/*! POL - Configure pin polarity of pin PIOn.
+ */
+#define GINT_PORT_POL_POL(x)                     (((uint32_t)(((uint32_t)(x)) << GINT_PORT_POL_POL_SHIFT)) & GINT_PORT_POL_POL_MASK)
+/*! @} */
+
+/* The count of GINT_PORT_POL */
+#define GINT_PORT_POL_COUNT                      (1U)
+
+/*! @name PORT_ENA - GPIO Grouped Interrupt port enable register. When a bit is set then the corresponding PIO is enabled for the group interrupt function. */
+/*! @{ */
+#define GINT_PORT_ENA_ENA_MASK                   (0x3FFFFFU)
+#define GINT_PORT_ENA_ENA_SHIFT                  (0U)
+/*! ENA - Enable pin PIOn for group interrupt.
+ */
+#define GINT_PORT_ENA_ENA(x)                     (((uint32_t)(((uint32_t)(x)) << GINT_PORT_ENA_ENA_SHIFT)) & GINT_PORT_ENA_ENA_MASK)
+/*! @} */
+
+/* The count of GINT_PORT_ENA */
+#define GINT_PORT_ENA_COUNT                      (1U)
+
+
+/*!
+ * @}
+ */ /* end of group GINT_Register_Masks */
+
+
+/* GINT - Peripheral instance base addresses */
+/** Peripheral GINT0 base address */
+#define GINT0_BASE                               (0x40011000u)
+/** Peripheral GINT0 base pointer */
+#define GINT0                                    ((GINT_Type *)GINT0_BASE)
+/** Array initializer of GINT peripheral base addresses */
+#define GINT_BASE_ADDRS                          { GINT0_BASE }
+/** Array initializer of GINT peripheral base pointers */
+#define GINT_BASE_PTRS                           { GINT0 }
+/** Interrupt vectors for the GINT peripheral type */
+#define GINT_IRQS                                { GINT0_IRQn }
+
+/*!
+ * @}
+ */ /* end of group GINT_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- GPIO Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup GPIO_Peripheral_Access_Layer GPIO Peripheral Access Layer
+ * @{
+ */
+
+/** GPIO - Register Layout Typedef */
+typedef struct {
+  __IO uint8_t B[1][22];                           /**< Byte pin registers. Read 0: pin PIOn is LOW. Read 0xFF: pin PIOn is HIGH. Only 0 or 0xFF can be read. Write 0: clear output bit. Write any value 0x01 to 0xFF: set output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset value, array offset: 0x0, array step: index*0x16, index2*0x1 */
+       uint8_t RESERVED_0[4074];
+  __IO uint32_t W[1][22];                          /**< Word pin registers Read 0: pin PIOn is LOW. Read 0xFFFFFFFF: pin PIOn is HIGH. Only 0 or 0xFFFF FFFF can be read. Write 0: clear output bit. Write any value 0x00000001 to 0xFFFFFFFF: set output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset value, array offset: 0x1000, array step: index*0x58, index2*0x4 */
+       uint8_t RESERVED_1[4008];
+  __IO uint32_t DIR[1];                            /**< Direction register, array offset: 0x2000, array step: 0x4 */
+       uint8_t RESERVED_2[124];
+  __IO uint32_t MASK[1];                           /**< Mask register, array offset: 0x2080, array step: 0x4 */
+       uint8_t RESERVED_3[124];
+  __IO uint32_t PIN[1];                            /**< Pin register, array offset: 0x2100, array step: 0x4 */
+       uint8_t RESERVED_4[124];
+  __IO uint32_t MPIN[1];                           /**< Masked Pin register, array offset: 0x2180, array step: 0x4 */
+       uint8_t RESERVED_5[124];
+  __IO uint32_t SET[1];                            /**< Write: Set Pin register bits Read: output bits, array offset: 0x2200, array step: 0x4 */
+       uint8_t RESERVED_6[124];
+  __O  uint32_t CLR[1];                            /**< Clear Pin register bits, array offset: 0x2280, array step: 0x4 */
+       uint8_t RESERVED_7[124];
+  __O  uint32_t NOT[1];                            /**< Toggle Pin register bits, array offset: 0x2300, array step: 0x4 */
+       uint8_t RESERVED_8[124];
+  __O  uint32_t DIRSET[1];                         /**< Set pin direction bits, array offset: 0x2380, array step: 0x4 */
+       uint8_t RESERVED_9[124];
+  __O  uint32_t DIRCLR[1];                         /**< Clear pin direction bits, array offset: 0x2400, array step: 0x4 */
+       uint8_t RESERVED_10[124];
+  __O  uint32_t DIRNOT[1];                         /**< Toggle pin direction bits, array offset: 0x2480, array step: 0x4 */
+} GPIO_Type;
+
+/* ----------------------------------------------------------------------------
+   -- GPIO Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup GPIO_Register_Masks GPIO Register Masks
+ * @{
+ */
+
+/*! @name B - Byte pin registers. Read 0: pin PIOn is LOW. Read 0xFF: pin PIOn is HIGH. Only 0 or 0xFF can be read. Write 0: clear output bit. Write any value 0x01 to 0xFF: set output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset value */
+/*! @{ */
+#define GPIO_B_B_MASK                            (0xFFU)
+#define GPIO_B_B_SHIFT                           (0U)
+/*! B - Byte pin registers. Read 0: pin PIOn is LOW. Read 0xFF: pin PIOn is HIGH. Only 0 or 0xFF can
+ *    be read. Write 0: clear output bit. Write any value 0x01 to 0xFF: set output bit. Reset
+ *    values reflects the state of pin given by the relevant bit of PIN reset value
+ */
+#define GPIO_B_B(x)                              (((uint8_t)(((uint8_t)(x)) << GPIO_B_B_SHIFT)) & GPIO_B_B_MASK)
+/*! @} */
+
+/* The count of GPIO_B */
+#define GPIO_B_COUNT                             (1U)
+
+/* The count of GPIO_B */
+#define GPIO_B_COUNT2                            (22U)
+
+/*! @name W - Word pin registers Read 0: pin PIOn is LOW. Read 0xFFFFFFFF: pin PIOn is HIGH. Only 0 or 0xFFFF FFFF can be read. Write 0: clear output bit. Write any value 0x00000001 to 0xFFFFFFFF: set output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset value */
+/*! @{ */
+#define GPIO_W_W_MASK                            (0xFFFFFFFFU)
+#define GPIO_W_W_SHIFT                           (0U)
+/*! W - Word pin registers Read 0: pin PIOn is LOW. Read 0xFFFFFFFF: pin PIOn is HIGH. Only 0 or
+ *    0xFFFF FFFF can be read. Write 0: clear output bit. Write any value 0x00000001 to 0xFFFFFFFF: set
+ *    output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset
+ *    value
+ */
+#define GPIO_W_W(x)                              (((uint32_t)(((uint32_t)(x)) << GPIO_W_W_SHIFT)) & GPIO_W_W_MASK)
+/*! @} */
+
+/* The count of GPIO_W */
+#define GPIO_W_COUNT                             (1U)
+
+/* The count of GPIO_W */
+#define GPIO_W_COUNT2                            (22U)
+
+/*! @name DIR - Direction register */
+/*! @{ */
+#define GPIO_DIR_DIRP_PIO0_MASK                  (0x1U)
+#define GPIO_DIR_DIRP_PIO0_SHIFT                 (0U)
+/*! DIRP_PIO0 - Selects pin direction for pin PIO0 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO0_SHIFT)) & GPIO_DIR_DIRP_PIO0_MASK)
+#define GPIO_DIR_DIRP_PIO1_MASK                  (0x2U)
+#define GPIO_DIR_DIRP_PIO1_SHIFT                 (1U)
+/*! DIRP_PIO1 - Selects pin direction for pin PIO1 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO1_SHIFT)) & GPIO_DIR_DIRP_PIO1_MASK)
+#define GPIO_DIR_DIRP_PIO2_MASK                  (0x4U)
+#define GPIO_DIR_DIRP_PIO2_SHIFT                 (2U)
+/*! DIRP_PIO2 - Selects pin direction for pin PIO2 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO2_SHIFT)) & GPIO_DIR_DIRP_PIO2_MASK)
+#define GPIO_DIR_DIRP_PIO3_MASK                  (0x8U)
+#define GPIO_DIR_DIRP_PIO3_SHIFT                 (3U)
+/*! DIRP_PIO3 - Selects pin direction for pin PIO3 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO3_SHIFT)) & GPIO_DIR_DIRP_PIO3_MASK)
+#define GPIO_DIR_DIRP_PIO4_MASK                  (0x10U)
+#define GPIO_DIR_DIRP_PIO4_SHIFT                 (4U)
+/*! DIRP_PIO4 - Selects pin direction for pin PIO4 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO4_SHIFT)) & GPIO_DIR_DIRP_PIO4_MASK)
+#define GPIO_DIR_DIRP_PIO5_MASK                  (0x20U)
+#define GPIO_DIR_DIRP_PIO5_SHIFT                 (5U)
+/*! DIRP_PIO5 - Selects pin direction for pin PIO5 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO5_SHIFT)) & GPIO_DIR_DIRP_PIO5_MASK)
+#define GPIO_DIR_DIRP_PIO6_MASK                  (0x40U)
+#define GPIO_DIR_DIRP_PIO6_SHIFT                 (6U)
+/*! DIRP_PIO6 - Selects pin direction for pin PIO6 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO6_SHIFT)) & GPIO_DIR_DIRP_PIO6_MASK)
+#define GPIO_DIR_DIRP_PIO7_MASK                  (0x80U)
+#define GPIO_DIR_DIRP_PIO7_SHIFT                 (7U)
+/*! DIRP_PIO7 - Selects pin direction for pin PIO7 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO7_SHIFT)) & GPIO_DIR_DIRP_PIO7_MASK)
+#define GPIO_DIR_DIRP_PIO8_MASK                  (0x100U)
+#define GPIO_DIR_DIRP_PIO8_SHIFT                 (8U)
+/*! DIRP_PIO8 - Selects pin direction for pin PIO8 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO8_SHIFT)) & GPIO_DIR_DIRP_PIO8_MASK)
+#define GPIO_DIR_DIRP_PIO9_MASK                  (0x200U)
+#define GPIO_DIR_DIRP_PIO9_SHIFT                 (9U)
+/*! DIRP_PIO9 - Selects pin direction for pin PIO9 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO9_SHIFT)) & GPIO_DIR_DIRP_PIO9_MASK)
+#define GPIO_DIR_DIRP_PIO10_MASK                 (0x400U)
+#define GPIO_DIR_DIRP_PIO10_SHIFT                (10U)
+/*! DIRP_PIO10 - Selects pin direction for pin PIO10 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO10_SHIFT)) & GPIO_DIR_DIRP_PIO10_MASK)
+#define GPIO_DIR_DIRP_PIO11_MASK                 (0x800U)
+#define GPIO_DIR_DIRP_PIO11_SHIFT                (11U)
+/*! DIRP_PIO11 - Selects pin direction for pin PIO11 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO11_SHIFT)) & GPIO_DIR_DIRP_PIO11_MASK)
+#define GPIO_DIR_DIRP_PIO12_MASK                 (0x1000U)
+#define GPIO_DIR_DIRP_PIO12_SHIFT                (12U)
+/*! DIRP_PIO12 - Selects pin direction for pin PIO12 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO12_SHIFT)) & GPIO_DIR_DIRP_PIO12_MASK)
+#define GPIO_DIR_DIRP_PIO13_MASK                 (0x2000U)
+#define GPIO_DIR_DIRP_PIO13_SHIFT                (13U)
+/*! DIRP_PIO13 - Selects pin direction for pin PIO13 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO13_SHIFT)) & GPIO_DIR_DIRP_PIO13_MASK)
+#define GPIO_DIR_DIRP_PIO14_MASK                 (0x4000U)
+#define GPIO_DIR_DIRP_PIO14_SHIFT                (14U)
+/*! DIRP_PIO14 - Selects pin direction for pin PIO14 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO14_SHIFT)) & GPIO_DIR_DIRP_PIO14_MASK)
+#define GPIO_DIR_DIRP_PIO15_MASK                 (0x8000U)
+#define GPIO_DIR_DIRP_PIO15_SHIFT                (15U)
+/*! DIRP_PIO15 - Selects pin direction for pin PIO15 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO15_SHIFT)) & GPIO_DIR_DIRP_PIO15_MASK)
+#define GPIO_DIR_DIRP_PIO16_MASK                 (0x10000U)
+#define GPIO_DIR_DIRP_PIO16_SHIFT                (16U)
+/*! DIRP_PIO16 - Selects pin direction for pin PIO16 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO16_SHIFT)) & GPIO_DIR_DIRP_PIO16_MASK)
+#define GPIO_DIR_DIRP_PIO17_MASK                 (0x20000U)
+#define GPIO_DIR_DIRP_PIO17_SHIFT                (17U)
+/*! DIRP_PIO17 - Selects pin direction for pin PIO17 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO17_SHIFT)) & GPIO_DIR_DIRP_PIO17_MASK)
+#define GPIO_DIR_DIRP_PIO18_MASK                 (0x40000U)
+#define GPIO_DIR_DIRP_PIO18_SHIFT                (18U)
+/*! DIRP_PIO18 - Selects pin direction for pin PIO18 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO18_SHIFT)) & GPIO_DIR_DIRP_PIO18_MASK)
+#define GPIO_DIR_DIRP_PIO19_MASK                 (0x80000U)
+#define GPIO_DIR_DIRP_PIO19_SHIFT                (19U)
+/*! DIRP_PIO19 - Selects pin direction for pin PIO19 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO19_SHIFT)) & GPIO_DIR_DIRP_PIO19_MASK)
+#define GPIO_DIR_DIRP_PIO20_MASK                 (0x100000U)
+#define GPIO_DIR_DIRP_PIO20_SHIFT                (20U)
+/*! DIRP_PIO20 - Selects pin direction for pin PIO20 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO20_SHIFT)) & GPIO_DIR_DIRP_PIO20_MASK)
+#define GPIO_DIR_DIRP_PIO21_MASK                 (0x200000U)
+#define GPIO_DIR_DIRP_PIO21_SHIFT                (21U)
+/*! DIRP_PIO21 - Selects pin direction for pin PIO21 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO21_SHIFT)) & GPIO_DIR_DIRP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_DIR */
+#define GPIO_DIR_COUNT                           (1U)
+
+/*! @name MASK - Mask register */
+/*! @{ */
+#define GPIO_MASK_MASKP_PIO0_MASK                (0x1U)
+#define GPIO_MASK_MASKP_PIO0_SHIFT               (0U)
+/*! MASKP_PIO0 - Controls if PIO0 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO0(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO0_SHIFT)) & GPIO_MASK_MASKP_PIO0_MASK)
+#define GPIO_MASK_MASKP_PIO1_MASK                (0x2U)
+#define GPIO_MASK_MASKP_PIO1_SHIFT               (1U)
+/*! MASKP_PIO1 - Controls if PIO1 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO1(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO1_SHIFT)) & GPIO_MASK_MASKP_PIO1_MASK)
+#define GPIO_MASK_MASKP_PIO2_MASK                (0x4U)
+#define GPIO_MASK_MASKP_PIO2_SHIFT               (2U)
+/*! MASKP_PIO2 - Controls if PIO2 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO2(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO2_SHIFT)) & GPIO_MASK_MASKP_PIO2_MASK)
+#define GPIO_MASK_MASKP_PIO3_MASK                (0x8U)
+#define GPIO_MASK_MASKP_PIO3_SHIFT               (3U)
+/*! MASKP_PIO3 - Controls if PIO3 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO3(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO3_SHIFT)) & GPIO_MASK_MASKP_PIO3_MASK)
+#define GPIO_MASK_MASKP_PIO4_MASK                (0x10U)
+#define GPIO_MASK_MASKP_PIO4_SHIFT               (4U)
+/*! MASKP_PIO4 - Controls if PIO4 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO4(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO4_SHIFT)) & GPIO_MASK_MASKP_PIO4_MASK)
+#define GPIO_MASK_MASKP_PIO5_MASK                (0x20U)
+#define GPIO_MASK_MASKP_PIO5_SHIFT               (5U)
+/*! MASKP_PIO5 - Controls if PIO5 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO5(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO5_SHIFT)) & GPIO_MASK_MASKP_PIO5_MASK)
+#define GPIO_MASK_MASKP_PIO6_MASK                (0x40U)
+#define GPIO_MASK_MASKP_PIO6_SHIFT               (6U)
+/*! MASKP_PIO6 - Controls if PIO6 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO6(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO6_SHIFT)) & GPIO_MASK_MASKP_PIO6_MASK)
+#define GPIO_MASK_MASKP_PIO7_MASK                (0x80U)
+#define GPIO_MASK_MASKP_PIO7_SHIFT               (7U)
+/*! MASKP_PIO7 - Controls if PIO7 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO7(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO7_SHIFT)) & GPIO_MASK_MASKP_PIO7_MASK)
+#define GPIO_MASK_MASKP_PIO8_MASK                (0x100U)
+#define GPIO_MASK_MASKP_PIO8_SHIFT               (8U)
+/*! MASKP_PIO8 - Controls if PIO8 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO8(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO8_SHIFT)) & GPIO_MASK_MASKP_PIO8_MASK)
+#define GPIO_MASK_MASKP_PIO9_MASK                (0x200U)
+#define GPIO_MASK_MASKP_PIO9_SHIFT               (9U)
+/*! MASKP_PIO9 - Controls if PIO9 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO9(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO9_SHIFT)) & GPIO_MASK_MASKP_PIO9_MASK)
+#define GPIO_MASK_MASKP_PIO10_MASK               (0x400U)
+#define GPIO_MASK_MASKP_PIO10_SHIFT              (10U)
+/*! MASKP_PIO10 - Controls if PIO10 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO10(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO10_SHIFT)) & GPIO_MASK_MASKP_PIO10_MASK)
+#define GPIO_MASK_MASKP_PIO11_MASK               (0x800U)
+#define GPIO_MASK_MASKP_PIO11_SHIFT              (11U)
+/*! MASKP_PIO11 - Controls if PIO11 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO11(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO11_SHIFT)) & GPIO_MASK_MASKP_PIO11_MASK)
+#define GPIO_MASK_MASKP_PIO12_MASK               (0x1000U)
+#define GPIO_MASK_MASKP_PIO12_SHIFT              (12U)
+/*! MASKP_PIO12 - Controls if PIO12 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO12(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO12_SHIFT)) & GPIO_MASK_MASKP_PIO12_MASK)
+#define GPIO_MASK_MASKP_PIO13_MASK               (0x2000U)
+#define GPIO_MASK_MASKP_PIO13_SHIFT              (13U)
+/*! MASKP_PIO13 - Controls if PIO13 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO13(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO13_SHIFT)) & GPIO_MASK_MASKP_PIO13_MASK)
+#define GPIO_MASK_MASKP_PIO14_MASK               (0x4000U)
+#define GPIO_MASK_MASKP_PIO14_SHIFT              (14U)
+/*! MASKP_PIO14 - Controls if PIO14 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO14(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO14_SHIFT)) & GPIO_MASK_MASKP_PIO14_MASK)
+#define GPIO_MASK_MASKP_PIO15_MASK               (0x8000U)
+#define GPIO_MASK_MASKP_PIO15_SHIFT              (15U)
+/*! MASKP_PIO15 - Controls if PIO150 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO15(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO15_SHIFT)) & GPIO_MASK_MASKP_PIO15_MASK)
+#define GPIO_MASK_MASKP_PIO16_MASK               (0x10000U)
+#define GPIO_MASK_MASKP_PIO16_SHIFT              (16U)
+/*! MASKP_PIO16 - Controls if PIO16 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO16(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO16_SHIFT)) & GPIO_MASK_MASKP_PIO16_MASK)
+#define GPIO_MASK_MASKP_PIO17_MASK               (0x20000U)
+#define GPIO_MASK_MASKP_PIO17_SHIFT              (17U)
+/*! MASKP_PIO17 - Controls if PIO17 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO17(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO17_SHIFT)) & GPIO_MASK_MASKP_PIO17_MASK)
+#define GPIO_MASK_MASKP_PIO18_MASK               (0x40000U)
+#define GPIO_MASK_MASKP_PIO18_SHIFT              (18U)
+/*! MASKP_PIO18 - Controls if PIO18 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO18(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO18_SHIFT)) & GPIO_MASK_MASKP_PIO18_MASK)
+#define GPIO_MASK_MASKP_PIO19_MASK               (0x80000U)
+#define GPIO_MASK_MASKP_PIO19_SHIFT              (19U)
+/*! MASKP_PIO19 - Controls if PIO19 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO19(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO19_SHIFT)) & GPIO_MASK_MASKP_PIO19_MASK)
+#define GPIO_MASK_MASKP_PIO20_MASK               (0x100000U)
+#define GPIO_MASK_MASKP_PIO20_SHIFT              (20U)
+/*! MASKP_PIO20 - Controls if PIO20 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO20(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO20_SHIFT)) & GPIO_MASK_MASKP_PIO20_MASK)
+#define GPIO_MASK_MASKP_PIO21_MASK               (0x200000U)
+#define GPIO_MASK_MASKP_PIO21_SHIFT              (21U)
+/*! MASKP_PIO21 - Controls if PIO21 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO21(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO21_SHIFT)) & GPIO_MASK_MASKP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_MASK */
+#define GPIO_MASK_COUNT                          (1U)
+
+/*! @name PIN - Pin register */
+/*! @{ */
+#define GPIO_PIN_PORT_PIO0_MASK                  (0x1U)
+#define GPIO_PIN_PORT_PIO0_SHIFT                 (0U)
+/*! PORT_PIO0 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO0_SHIFT)) & GPIO_PIN_PORT_PIO0_MASK)
+#define GPIO_PIN_PORT_PIO1_MASK                  (0x2U)
+#define GPIO_PIN_PORT_PIO1_SHIFT                 (1U)
+/*! PORT_PIO1 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO1_SHIFT)) & GPIO_PIN_PORT_PIO1_MASK)
+#define GPIO_PIN_PORT_PIO2_MASK                  (0x4U)
+#define GPIO_PIN_PORT_PIO2_SHIFT                 (2U)
+/*! PORT_PIO2 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO2_SHIFT)) & GPIO_PIN_PORT_PIO2_MASK)
+#define GPIO_PIN_PORT_PIO3_MASK                  (0x8U)
+#define GPIO_PIN_PORT_PIO3_SHIFT                 (3U)
+/*! PORT_PIO3 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO3_SHIFT)) & GPIO_PIN_PORT_PIO3_MASK)
+#define GPIO_PIN_PORT_PIO4_MASK                  (0x10U)
+#define GPIO_PIN_PORT_PIO4_SHIFT                 (4U)
+/*! PORT_PIO4 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO4_SHIFT)) & GPIO_PIN_PORT_PIO4_MASK)
+#define GPIO_PIN_PORT_PIO5_MASK                  (0x20U)
+#define GPIO_PIN_PORT_PIO5_SHIFT                 (5U)
+/*! PORT_PIO5 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO5_SHIFT)) & GPIO_PIN_PORT_PIO5_MASK)
+#define GPIO_PIN_PORT_PIO6_MASK                  (0x40U)
+#define GPIO_PIN_PORT_PIO6_SHIFT                 (6U)
+/*! PORT_PIO6 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO6_SHIFT)) & GPIO_PIN_PORT_PIO6_MASK)
+#define GPIO_PIN_PORT_PIO7_MASK                  (0x80U)
+#define GPIO_PIN_PORT_PIO7_SHIFT                 (7U)
+/*! PORT_PIO7 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO7_SHIFT)) & GPIO_PIN_PORT_PIO7_MASK)
+#define GPIO_PIN_PORT_PIO8_MASK                  (0x100U)
+#define GPIO_PIN_PORT_PIO8_SHIFT                 (8U)
+/*! PORT_PIO8 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO8_SHIFT)) & GPIO_PIN_PORT_PIO8_MASK)
+#define GPIO_PIN_PORT_PIO9_MASK                  (0x200U)
+#define GPIO_PIN_PORT_PIO9_SHIFT                 (9U)
+/*! PORT_PIO9 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO9_SHIFT)) & GPIO_PIN_PORT_PIO9_MASK)
+#define GPIO_PIN_PORT_PIO10_MASK                 (0x400U)
+#define GPIO_PIN_PORT_PIO10_SHIFT                (10U)
+/*! PORT_PIO10 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO10_SHIFT)) & GPIO_PIN_PORT_PIO10_MASK)
+#define GPIO_PIN_PORT_PIO11_MASK                 (0x800U)
+#define GPIO_PIN_PORT_PIO11_SHIFT                (11U)
+/*! PORT_PIO11 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO11_SHIFT)) & GPIO_PIN_PORT_PIO11_MASK)
+#define GPIO_PIN_PORT_PIO12_MASK                 (0x1000U)
+#define GPIO_PIN_PORT_PIO12_SHIFT                (12U)
+/*! PORT_PIO12 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO12_SHIFT)) & GPIO_PIN_PORT_PIO12_MASK)
+#define GPIO_PIN_PORT_PIO13_MASK                 (0x2000U)
+#define GPIO_PIN_PORT_PIO13_SHIFT                (13U)
+/*! PORT_PIO13 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO13_SHIFT)) & GPIO_PIN_PORT_PIO13_MASK)
+#define GPIO_PIN_PORT_PIO14_MASK                 (0x4000U)
+#define GPIO_PIN_PORT_PIO14_SHIFT                (14U)
+/*! PORT_PIO14 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO14_SHIFT)) & GPIO_PIN_PORT_PIO14_MASK)
+#define GPIO_PIN_PORT_PIO15_MASK                 (0x8000U)
+#define GPIO_PIN_PORT_PIO15_SHIFT                (15U)
+/*! PORT_PIO15 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO15_SHIFT)) & GPIO_PIN_PORT_PIO15_MASK)
+#define GPIO_PIN_PORT_PIO16_MASK                 (0x10000U)
+#define GPIO_PIN_PORT_PIO16_SHIFT                (16U)
+/*! PORT_PIO16 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO16_SHIFT)) & GPIO_PIN_PORT_PIO16_MASK)
+#define GPIO_PIN_PORT_PIO17_MASK                 (0x20000U)
+#define GPIO_PIN_PORT_PIO17_SHIFT                (17U)
+/*! PORT_PIO17 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO17_SHIFT)) & GPIO_PIN_PORT_PIO17_MASK)
+#define GPIO_PIN_PORT_PIO18_MASK                 (0x40000U)
+#define GPIO_PIN_PORT_PIO18_SHIFT                (18U)
+/*! PORT_PIO18 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO18_SHIFT)) & GPIO_PIN_PORT_PIO18_MASK)
+#define GPIO_PIN_PORT_PIO19_MASK                 (0x80000U)
+#define GPIO_PIN_PORT_PIO19_SHIFT                (19U)
+/*! PORT_PIO19 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO19_SHIFT)) & GPIO_PIN_PORT_PIO19_MASK)
+#define GPIO_PIN_PORT_PIO20_MASK                 (0x100000U)
+#define GPIO_PIN_PORT_PIO20_SHIFT                (20U)
+/*! PORT_PIO20 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO20_SHIFT)) & GPIO_PIN_PORT_PIO20_MASK)
+#define GPIO_PIN_PORT_PIO21_MASK                 (0x200000U)
+#define GPIO_PIN_PORT_PIO21_SHIFT                (21U)
+/*! PORT_PIO21 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO21_SHIFT)) & GPIO_PIN_PORT_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_PIN */
+#define GPIO_PIN_COUNT                           (1U)
+
+/*! @name MPIN - Masked Pin register */
+/*! @{ */
+#define GPIO_MPIN_MPORT_PIO0_MASK                (0x1U)
+#define GPIO_MPIN_MPORT_PIO0_SHIFT               (0U)
+/*! MPORT_PIO0 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO0(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO0_SHIFT)) & GPIO_MPIN_MPORT_PIO0_MASK)
+#define GPIO_MPIN_MPORT_PIO1_MASK                (0x2U)
+#define GPIO_MPIN_MPORT_PIO1_SHIFT               (1U)
+/*! MPORT_PIO1 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO1(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO1_SHIFT)) & GPIO_MPIN_MPORT_PIO1_MASK)
+#define GPIO_MPIN_MPORT_PIO2_MASK                (0x4U)
+#define GPIO_MPIN_MPORT_PIO2_SHIFT               (2U)
+/*! MPORT_PIO2 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO2(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO2_SHIFT)) & GPIO_MPIN_MPORT_PIO2_MASK)
+#define GPIO_MPIN_MPORT_PIO3_MASK                (0x8U)
+#define GPIO_MPIN_MPORT_PIO3_SHIFT               (3U)
+/*! MPORT_PIO3 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO3(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO3_SHIFT)) & GPIO_MPIN_MPORT_PIO3_MASK)
+#define GPIO_MPIN_MPORT_PIO4_MASK                (0x10U)
+#define GPIO_MPIN_MPORT_PIO4_SHIFT               (4U)
+/*! MPORT_PIO4 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO4(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO4_SHIFT)) & GPIO_MPIN_MPORT_PIO4_MASK)
+#define GPIO_MPIN_MPORT_PIO5_MASK                (0x20U)
+#define GPIO_MPIN_MPORT_PIO5_SHIFT               (5U)
+/*! MPORT_PIO5 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO5(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO5_SHIFT)) & GPIO_MPIN_MPORT_PIO5_MASK)
+#define GPIO_MPIN_MPORT_PIO6_MASK                (0x40U)
+#define GPIO_MPIN_MPORT_PIO6_SHIFT               (6U)
+/*! MPORT_PIO6 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO6(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO6_SHIFT)) & GPIO_MPIN_MPORT_PIO6_MASK)
+#define GPIO_MPIN_MPORT_PIO7_MASK                (0x80U)
+#define GPIO_MPIN_MPORT_PIO7_SHIFT               (7U)
+/*! MPORT_PIO7 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO7(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO7_SHIFT)) & GPIO_MPIN_MPORT_PIO7_MASK)
+#define GPIO_MPIN_MPORT_PIO8_MASK                (0x100U)
+#define GPIO_MPIN_MPORT_PIO8_SHIFT               (8U)
+/*! MPORT_PIO8 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO8(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO8_SHIFT)) & GPIO_MPIN_MPORT_PIO8_MASK)
+#define GPIO_MPIN_MPORT_PIO9_MASK                (0x200U)
+#define GPIO_MPIN_MPORT_PIO9_SHIFT               (9U)
+/*! MPORT_PIO9 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO9(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO9_SHIFT)) & GPIO_MPIN_MPORT_PIO9_MASK)
+#define GPIO_MPIN_MPORT_PIO10_MASK               (0x400U)
+#define GPIO_MPIN_MPORT_PIO10_SHIFT              (10U)
+/*! MPORT_PIO10 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO10(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO10_SHIFT)) & GPIO_MPIN_MPORT_PIO10_MASK)
+#define GPIO_MPIN_MPORT_PIO11_MASK               (0x800U)
+#define GPIO_MPIN_MPORT_PIO11_SHIFT              (11U)
+/*! MPORT_PIO11 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO11(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO11_SHIFT)) & GPIO_MPIN_MPORT_PIO11_MASK)
+#define GPIO_MPIN_MPORT_PIO12_MASK               (0x1000U)
+#define GPIO_MPIN_MPORT_PIO12_SHIFT              (12U)
+/*! MPORT_PIO12 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO12(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO12_SHIFT)) & GPIO_MPIN_MPORT_PIO12_MASK)
+#define GPIO_MPIN_MPORT_PIO13_MASK               (0x2000U)
+#define GPIO_MPIN_MPORT_PIO13_SHIFT              (13U)
+/*! MPORT_PIO13 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO13(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO13_SHIFT)) & GPIO_MPIN_MPORT_PIO13_MASK)
+#define GPIO_MPIN_MPORT_PIO14_MASK               (0x4000U)
+#define GPIO_MPIN_MPORT_PIO14_SHIFT              (14U)
+/*! MPORT_PIO14 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO14(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO14_SHIFT)) & GPIO_MPIN_MPORT_PIO14_MASK)
+#define GPIO_MPIN_MPORT_PIO15_MASK               (0x8000U)
+#define GPIO_MPIN_MPORT_PIO15_SHIFT              (15U)
+/*! MPORT_PIO15 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO15(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO15_SHIFT)) & GPIO_MPIN_MPORT_PIO15_MASK)
+#define GPIO_MPIN_MPORT_PIO16_MASK               (0x10000U)
+#define GPIO_MPIN_MPORT_PIO16_SHIFT              (16U)
+/*! MPORT_PIO16 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO16(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO16_SHIFT)) & GPIO_MPIN_MPORT_PIO16_MASK)
+#define GPIO_MPIN_MPORT_PIO17_MASK               (0x20000U)
+#define GPIO_MPIN_MPORT_PIO17_SHIFT              (17U)
+/*! MPORT_PIO17 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO17(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO17_SHIFT)) & GPIO_MPIN_MPORT_PIO17_MASK)
+#define GPIO_MPIN_MPORT_PIO18_MASK               (0x40000U)
+#define GPIO_MPIN_MPORT_PIO18_SHIFT              (18U)
+/*! MPORT_PIO18 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO18(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO18_SHIFT)) & GPIO_MPIN_MPORT_PIO18_MASK)
+#define GPIO_MPIN_MPORT_PIO19_MASK               (0x80000U)
+#define GPIO_MPIN_MPORT_PIO19_SHIFT              (19U)
+/*! MPORT_PIO19 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO19(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO19_SHIFT)) & GPIO_MPIN_MPORT_PIO19_MASK)
+#define GPIO_MPIN_MPORT_PIO20_MASK               (0x100000U)
+#define GPIO_MPIN_MPORT_PIO20_SHIFT              (20U)
+/*! MPORT_PIO20 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO20(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO20_SHIFT)) & GPIO_MPIN_MPORT_PIO20_MASK)
+#define GPIO_MPIN_MPORT_PIO21_MASK               (0x200000U)
+#define GPIO_MPIN_MPORT_PIO21_SHIFT              (21U)
+/*! MPORT_PIO21 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO21(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO21_SHIFT)) & GPIO_MPIN_MPORT_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_MPIN */
+#define GPIO_MPIN_COUNT                          (1U)
+
+/*! @name SET - Write: Set Pin register bits Read: output bits */
+/*! @{ */
+#define GPIO_SET_SETP_PIO0_MASK                  (0x1U)
+#define GPIO_SET_SETP_PIO0_SHIFT                 (0U)
+/*! SETP_PIO0 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO0_SHIFT)) & GPIO_SET_SETP_PIO0_MASK)
+#define GPIO_SET_SETP_PIO1_MASK                  (0x2U)
+#define GPIO_SET_SETP_PIO1_SHIFT                 (1U)
+/*! SETP_PIO1 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO1_SHIFT)) & GPIO_SET_SETP_PIO1_MASK)
+#define GPIO_SET_SETP_PIO2_MASK                  (0x4U)
+#define GPIO_SET_SETP_PIO2_SHIFT                 (2U)
+/*! SETP_PIO2 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO2_SHIFT)) & GPIO_SET_SETP_PIO2_MASK)
+#define GPIO_SET_SETP_PIO3_MASK                  (0x8U)
+#define GPIO_SET_SETP_PIO3_SHIFT                 (3U)
+/*! SETP_PIO3 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO3_SHIFT)) & GPIO_SET_SETP_PIO3_MASK)
+#define GPIO_SET_SETP_PIO4_MASK                  (0x10U)
+#define GPIO_SET_SETP_PIO4_SHIFT                 (4U)
+/*! SETP_PIO4 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO4_SHIFT)) & GPIO_SET_SETP_PIO4_MASK)
+#define GPIO_SET_SETP_PIO5_MASK                  (0x20U)
+#define GPIO_SET_SETP_PIO5_SHIFT                 (5U)
+/*! SETP_PIO5 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO5_SHIFT)) & GPIO_SET_SETP_PIO5_MASK)
+#define GPIO_SET_SETP_PIO6_MASK                  (0x40U)
+#define GPIO_SET_SETP_PIO6_SHIFT                 (6U)
+/*! SETP_PIO6 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO6_SHIFT)) & GPIO_SET_SETP_PIO6_MASK)
+#define GPIO_SET_SETP_PIO7_MASK                  (0x80U)
+#define GPIO_SET_SETP_PIO7_SHIFT                 (7U)
+/*! SETP_PIO7 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO7_SHIFT)) & GPIO_SET_SETP_PIO7_MASK)
+#define GPIO_SET_SETP_PIO8_MASK                  (0x100U)
+#define GPIO_SET_SETP_PIO8_SHIFT                 (8U)
+/*! SETP_PIO8 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO8_SHIFT)) & GPIO_SET_SETP_PIO8_MASK)
+#define GPIO_SET_SETP_PIO9_MASK                  (0x200U)
+#define GPIO_SET_SETP_PIO9_SHIFT                 (9U)
+/*! SETP_PIO9 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO9_SHIFT)) & GPIO_SET_SETP_PIO9_MASK)
+#define GPIO_SET_SETP_PIO10_MASK                 (0x400U)
+#define GPIO_SET_SETP_PIO10_SHIFT                (10U)
+/*! SETP_PIO10 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO10_SHIFT)) & GPIO_SET_SETP_PIO10_MASK)
+#define GPIO_SET_SETP_PIO11_MASK                 (0x800U)
+#define GPIO_SET_SETP_PIO11_SHIFT                (11U)
+/*! SETP_PIO11 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO11_SHIFT)) & GPIO_SET_SETP_PIO11_MASK)
+#define GPIO_SET_SETP_PIO12_MASK                 (0x1000U)
+#define GPIO_SET_SETP_PIO12_SHIFT                (12U)
+/*! SETP_PIO12 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO12_SHIFT)) & GPIO_SET_SETP_PIO12_MASK)
+#define GPIO_SET_SETP_PIO13_MASK                 (0x2000U)
+#define GPIO_SET_SETP_PIO13_SHIFT                (13U)
+/*! SETP_PIO13 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO13_SHIFT)) & GPIO_SET_SETP_PIO13_MASK)
+#define GPIO_SET_SETP_PIO14_MASK                 (0x4000U)
+#define GPIO_SET_SETP_PIO14_SHIFT                (14U)
+/*! SETP_PIO14 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO14_SHIFT)) & GPIO_SET_SETP_PIO14_MASK)
+#define GPIO_SET_SETP_PIO15_MASK                 (0x8000U)
+#define GPIO_SET_SETP_PIO15_SHIFT                (15U)
+/*! SETP_PIO15 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO15_SHIFT)) & GPIO_SET_SETP_PIO15_MASK)
+#define GPIO_SET_SETP_PIO16_MASK                 (0x10000U)
+#define GPIO_SET_SETP_PIO16_SHIFT                (16U)
+/*! SETP_PIO16 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO16_SHIFT)) & GPIO_SET_SETP_PIO16_MASK)
+#define GPIO_SET_SETP_PIO17_MASK                 (0x20000U)
+#define GPIO_SET_SETP_PIO17_SHIFT                (17U)
+/*! SETP_PIO17 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO17_SHIFT)) & GPIO_SET_SETP_PIO17_MASK)
+#define GPIO_SET_SETP_PIO18_MASK                 (0x40000U)
+#define GPIO_SET_SETP_PIO18_SHIFT                (18U)
+/*! SETP_PIO18 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO18_SHIFT)) & GPIO_SET_SETP_PIO18_MASK)
+#define GPIO_SET_SETP_PIO19_MASK                 (0x80000U)
+#define GPIO_SET_SETP_PIO19_SHIFT                (19U)
+/*! SETP_PIO19 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO19_SHIFT)) & GPIO_SET_SETP_PIO19_MASK)
+#define GPIO_SET_SETP_PIO20_MASK                 (0x100000U)
+#define GPIO_SET_SETP_PIO20_SHIFT                (20U)
+/*! SETP_PIO20 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO20_SHIFT)) & GPIO_SET_SETP_PIO20_MASK)
+#define GPIO_SET_SETP_PIO21_MASK                 (0x200000U)
+#define GPIO_SET_SETP_PIO21_SHIFT                (21U)
+/*! SETP_PIO21 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO21_SHIFT)) & GPIO_SET_SETP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_SET */
+#define GPIO_SET_COUNT                           (1U)
+
+/*! @name CLR - Clear Pin register bits */
+/*! @{ */
+#define GPIO_CLR_CLRP_PIO0_MASK                  (0x1U)
+#define GPIO_CLR_CLRP_PIO0_SHIFT                 (0U)
+/*! CLRP_PIO0 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO0_SHIFT)) & GPIO_CLR_CLRP_PIO0_MASK)
+#define GPIO_CLR_CLRP_PIO1_MASK                  (0x2U)
+#define GPIO_CLR_CLRP_PIO1_SHIFT                 (1U)
+/*! CLRP_PIO1 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO1_SHIFT)) & GPIO_CLR_CLRP_PIO1_MASK)
+#define GPIO_CLR_CLRP_PIO2_MASK                  (0x4U)
+#define GPIO_CLR_CLRP_PIO2_SHIFT                 (2U)
+/*! CLRP_PIO2 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO2_SHIFT)) & GPIO_CLR_CLRP_PIO2_MASK)
+#define GPIO_CLR_CLRP_PIO3_MASK                  (0x8U)
+#define GPIO_CLR_CLRP_PIO3_SHIFT                 (3U)
+/*! CLRP_PIO3 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO3_SHIFT)) & GPIO_CLR_CLRP_PIO3_MASK)
+#define GPIO_CLR_CLRP_PIO4_MASK                  (0x10U)
+#define GPIO_CLR_CLRP_PIO4_SHIFT                 (4U)
+/*! CLRP_PIO4 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO4_SHIFT)) & GPIO_CLR_CLRP_PIO4_MASK)
+#define GPIO_CLR_CLRP_PIO5_MASK                  (0x20U)
+#define GPIO_CLR_CLRP_PIO5_SHIFT                 (5U)
+/*! CLRP_PIO5 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO5_SHIFT)) & GPIO_CLR_CLRP_PIO5_MASK)
+#define GPIO_CLR_CLRP_PIO6_MASK                  (0x40U)
+#define GPIO_CLR_CLRP_PIO6_SHIFT                 (6U)
+/*! CLRP_PIO6 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO6_SHIFT)) & GPIO_CLR_CLRP_PIO6_MASK)
+#define GPIO_CLR_CLRP_PIO7_MASK                  (0x80U)
+#define GPIO_CLR_CLRP_PIO7_SHIFT                 (7U)
+/*! CLRP_PIO7 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO7_SHIFT)) & GPIO_CLR_CLRP_PIO7_MASK)
+#define GPIO_CLR_CLRP_PIO8_MASK                  (0x100U)
+#define GPIO_CLR_CLRP_PIO8_SHIFT                 (8U)
+/*! CLRP_PIO8 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO8_SHIFT)) & GPIO_CLR_CLRP_PIO8_MASK)
+#define GPIO_CLR_CLRP_PIO9_MASK                  (0x200U)
+#define GPIO_CLR_CLRP_PIO9_SHIFT                 (9U)
+/*! CLRP_PIO9 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO9_SHIFT)) & GPIO_CLR_CLRP_PIO9_MASK)
+#define GPIO_CLR_CLRP_PIO10_MASK                 (0x400U)
+#define GPIO_CLR_CLRP_PIO10_SHIFT                (10U)
+/*! CLRP_PIO10 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO10_SHIFT)) & GPIO_CLR_CLRP_PIO10_MASK)
+#define GPIO_CLR_CLRP_PIO11_MASK                 (0x800U)
+#define GPIO_CLR_CLRP_PIO11_SHIFT                (11U)
+/*! CLRP_PIO11 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO11_SHIFT)) & GPIO_CLR_CLRP_PIO11_MASK)
+#define GPIO_CLR_CLRP_PIO12_MASK                 (0x1000U)
+#define GPIO_CLR_CLRP_PIO12_SHIFT                (12U)
+/*! CLRP_PIO12 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO12_SHIFT)) & GPIO_CLR_CLRP_PIO12_MASK)
+#define GPIO_CLR_CLRP_PIO13_MASK                 (0x2000U)
+#define GPIO_CLR_CLRP_PIO13_SHIFT                (13U)
+/*! CLRP_PIO13 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO13_SHIFT)) & GPIO_CLR_CLRP_PIO13_MASK)
+#define GPIO_CLR_CLRP_PIO14_MASK                 (0x4000U)
+#define GPIO_CLR_CLRP_PIO14_SHIFT                (14U)
+/*! CLRP_PIO14 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO14_SHIFT)) & GPIO_CLR_CLRP_PIO14_MASK)
+#define GPIO_CLR_CLRP_PIO15_MASK                 (0x8000U)
+#define GPIO_CLR_CLRP_PIO15_SHIFT                (15U)
+/*! CLRP_PIO15 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO15_SHIFT)) & GPIO_CLR_CLRP_PIO15_MASK)
+#define GPIO_CLR_CLRP_PIO16_MASK                 (0x10000U)
+#define GPIO_CLR_CLRP_PIO16_SHIFT                (16U)
+/*! CLRP_PIO16 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO16_SHIFT)) & GPIO_CLR_CLRP_PIO16_MASK)
+#define GPIO_CLR_CLRP_PIO17_MASK                 (0x20000U)
+#define GPIO_CLR_CLRP_PIO17_SHIFT                (17U)
+/*! CLRP_PIO17 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO17_SHIFT)) & GPIO_CLR_CLRP_PIO17_MASK)
+#define GPIO_CLR_CLRP_PIO18_MASK                 (0x40000U)
+#define GPIO_CLR_CLRP_PIO18_SHIFT                (18U)
+/*! CLRP_PIO18 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO18_SHIFT)) & GPIO_CLR_CLRP_PIO18_MASK)
+#define GPIO_CLR_CLRP_PIO19_MASK                 (0x80000U)
+#define GPIO_CLR_CLRP_PIO19_SHIFT                (19U)
+/*! CLRP_PIO19 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO19_SHIFT)) & GPIO_CLR_CLRP_PIO19_MASK)
+#define GPIO_CLR_CLRP_PIO20_MASK                 (0x100000U)
+#define GPIO_CLR_CLRP_PIO20_SHIFT                (20U)
+/*! CLRP_PIO20 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO20_SHIFT)) & GPIO_CLR_CLRP_PIO20_MASK)
+#define GPIO_CLR_CLRP_PIO21_MASK                 (0x200000U)
+#define GPIO_CLR_CLRP_PIO21_SHIFT                (21U)
+/*! CLRP_PIO21 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO21_SHIFT)) & GPIO_CLR_CLRP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_CLR */
+#define GPIO_CLR_COUNT                           (1U)
+
+/*! @name NOT - Toggle Pin register bits */
+/*! @{ */
+#define GPIO_NOT_NOTP_PIO0_MASK                  (0x1U)
+#define GPIO_NOT_NOTP_PIO0_SHIFT                 (0U)
+/*! NOTP_PIO0 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO0_SHIFT)) & GPIO_NOT_NOTP_PIO0_MASK)
+#define GPIO_NOT_NOTP_PIO1_MASK                  (0x2U)
+#define GPIO_NOT_NOTP_PIO1_SHIFT                 (1U)
+/*! NOTP_PIO1 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO1_SHIFT)) & GPIO_NOT_NOTP_PIO1_MASK)
+#define GPIO_NOT_NOTP_PIO2_MASK                  (0x4U)
+#define GPIO_NOT_NOTP_PIO2_SHIFT                 (2U)
+/*! NOTP_PIO2 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO2_SHIFT)) & GPIO_NOT_NOTP_PIO2_MASK)
+#define GPIO_NOT_NOTP_PIO3_MASK                  (0x8U)
+#define GPIO_NOT_NOTP_PIO3_SHIFT                 (3U)
+/*! NOTP_PIO3 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO3_SHIFT)) & GPIO_NOT_NOTP_PIO3_MASK)
+#define GPIO_NOT_NOTP_PIO4_MASK                  (0x10U)
+#define GPIO_NOT_NOTP_PIO4_SHIFT                 (4U)
+/*! NOTP_PIO4 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO4_SHIFT)) & GPIO_NOT_NOTP_PIO4_MASK)
+#define GPIO_NOT_NOTP_PIO5_MASK                  (0x20U)
+#define GPIO_NOT_NOTP_PIO5_SHIFT                 (5U)
+/*! NOTP_PIO5 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO5_SHIFT)) & GPIO_NOT_NOTP_PIO5_MASK)
+#define GPIO_NOT_NOTP_PIO6_MASK                  (0x40U)
+#define GPIO_NOT_NOTP_PIO6_SHIFT                 (6U)
+/*! NOTP_PIO6 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO6_SHIFT)) & GPIO_NOT_NOTP_PIO6_MASK)
+#define GPIO_NOT_NOTP_PIO7_MASK                  (0x80U)
+#define GPIO_NOT_NOTP_PIO7_SHIFT                 (7U)
+/*! NOTP_PIO7 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO7_SHIFT)) & GPIO_NOT_NOTP_PIO7_MASK)
+#define GPIO_NOT_NOTP_PIO8_MASK                  (0x100U)
+#define GPIO_NOT_NOTP_PIO8_SHIFT                 (8U)
+/*! NOTP_PIO8 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO8_SHIFT)) & GPIO_NOT_NOTP_PIO8_MASK)
+#define GPIO_NOT_NOTP_PIO9_MASK                  (0x200U)
+#define GPIO_NOT_NOTP_PIO9_SHIFT                 (9U)
+/*! NOTP_PIO9 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO9_SHIFT)) & GPIO_NOT_NOTP_PIO9_MASK)
+#define GPIO_NOT_NOTP_PIO10_MASK                 (0x400U)
+#define GPIO_NOT_NOTP_PIO10_SHIFT                (10U)
+/*! NOTP_PIO10 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO10_SHIFT)) & GPIO_NOT_NOTP_PIO10_MASK)
+#define GPIO_NOT_NOTP_PIO11_MASK                 (0x800U)
+#define GPIO_NOT_NOTP_PIO11_SHIFT                (11U)
+/*! NOTP_PIO11 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO11_SHIFT)) & GPIO_NOT_NOTP_PIO11_MASK)
+#define GPIO_NOT_NOTP_PIO12_MASK                 (0x1000U)
+#define GPIO_NOT_NOTP_PIO12_SHIFT                (12U)
+/*! NOTP_PIO12 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO12_SHIFT)) & GPIO_NOT_NOTP_PIO12_MASK)
+#define GPIO_NOT_NOTP_PIO13_MASK                 (0x2000U)
+#define GPIO_NOT_NOTP_PIO13_SHIFT                (13U)
+/*! NOTP_PIO13 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO13_SHIFT)) & GPIO_NOT_NOTP_PIO13_MASK)
+#define GPIO_NOT_NOTP_PIO14_MASK                 (0x4000U)
+#define GPIO_NOT_NOTP_PIO14_SHIFT                (14U)
+/*! NOTP_PIO14 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO14_SHIFT)) & GPIO_NOT_NOTP_PIO14_MASK)
+#define GPIO_NOT_NOTP_PIO15_MASK                 (0x8000U)
+#define GPIO_NOT_NOTP_PIO15_SHIFT                (15U)
+/*! NOTP_PIO15 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO15_SHIFT)) & GPIO_NOT_NOTP_PIO15_MASK)
+#define GPIO_NOT_NOTP_PIO16_MASK                 (0x10000U)
+#define GPIO_NOT_NOTP_PIO16_SHIFT                (16U)
+/*! NOTP_PIO16 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO16_SHIFT)) & GPIO_NOT_NOTP_PIO16_MASK)
+#define GPIO_NOT_NOTP_PIO17_MASK                 (0x20000U)
+#define GPIO_NOT_NOTP_PIO17_SHIFT                (17U)
+/*! NOTP_PIO17 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO17_SHIFT)) & GPIO_NOT_NOTP_PIO17_MASK)
+#define GPIO_NOT_NOTP_PIO18_MASK                 (0x40000U)
+#define GPIO_NOT_NOTP_PIO18_SHIFT                (18U)
+/*! NOTP_PIO18 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO18_SHIFT)) & GPIO_NOT_NOTP_PIO18_MASK)
+#define GPIO_NOT_NOTP_PIO19_MASK                 (0x80000U)
+#define GPIO_NOT_NOTP_PIO19_SHIFT                (19U)
+/*! NOTP_PIO19 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO19_SHIFT)) & GPIO_NOT_NOTP_PIO19_MASK)
+#define GPIO_NOT_NOTP_PIO20_MASK                 (0x100000U)
+#define GPIO_NOT_NOTP_PIO20_SHIFT                (20U)
+/*! NOTP_PIO20 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO20_SHIFT)) & GPIO_NOT_NOTP_PIO20_MASK)
+#define GPIO_NOT_NOTP_PIO21_MASK                 (0x200000U)
+#define GPIO_NOT_NOTP_PIO21_SHIFT                (21U)
+/*! NOTP_PIO21 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO21_SHIFT)) & GPIO_NOT_NOTP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_NOT */
+#define GPIO_NOT_COUNT                           (1U)
+
+/*! @name DIRSET - Set pin direction bits */
+/*! @{ */
+#define GPIO_DIRSET_DIRSETP_PIO0_MASK            (0x1U)
+#define GPIO_DIRSET_DIRSETP_PIO0_SHIFT           (0U)
+/*! DIRSETP_PIO0 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO0(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO0_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO0_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO1_MASK            (0x2U)
+#define GPIO_DIRSET_DIRSETP_PIO1_SHIFT           (1U)
+/*! DIRSETP_PIO1 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO1(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO1_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO1_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO2_MASK            (0x4U)
+#define GPIO_DIRSET_DIRSETP_PIO2_SHIFT           (2U)
+/*! DIRSETP_PIO2 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO2(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO2_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO2_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO3_MASK            (0x8U)
+#define GPIO_DIRSET_DIRSETP_PIO3_SHIFT           (3U)
+/*! DIRSETP_PIO3 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO3(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO3_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO3_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO4_MASK            (0x10U)
+#define GPIO_DIRSET_DIRSETP_PIO4_SHIFT           (4U)
+/*! DIRSETP_PIO4 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO4(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO4_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO4_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO5_MASK            (0x20U)
+#define GPIO_DIRSET_DIRSETP_PIO5_SHIFT           (5U)
+/*! DIRSETP_PIO5 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO5(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO5_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO5_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO6_MASK            (0x40U)
+#define GPIO_DIRSET_DIRSETP_PIO6_SHIFT           (6U)
+/*! DIRSETP_PIO6 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO6(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO6_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO6_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO7_MASK            (0x80U)
+#define GPIO_DIRSET_DIRSETP_PIO7_SHIFT           (7U)
+/*! DIRSETP_PIO7 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO7(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO7_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO7_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO8_MASK            (0x100U)
+#define GPIO_DIRSET_DIRSETP_PIO8_SHIFT           (8U)
+/*! DIRSETP_PIO8 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO8(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO8_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO8_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO9_MASK            (0x200U)
+#define GPIO_DIRSET_DIRSETP_PIO9_SHIFT           (9U)
+/*! DIRSETP_PIO9 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO9(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO9_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO9_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO10_MASK           (0x400U)
+#define GPIO_DIRSET_DIRSETP_PIO10_SHIFT          (10U)
+/*! DIRSETP_PIO10 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO10(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO10_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO10_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO11_MASK           (0x800U)
+#define GPIO_DIRSET_DIRSETP_PIO11_SHIFT          (11U)
+/*! DIRSETP_PIO11 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO11(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO11_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO11_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO12_MASK           (0x1000U)
+#define GPIO_DIRSET_DIRSETP_PIO12_SHIFT          (12U)
+/*! DIRSETP_PIO12 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO12(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO12_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO12_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO13_MASK           (0x2000U)
+#define GPIO_DIRSET_DIRSETP_PIO13_SHIFT          (13U)
+/*! DIRSETP_PIO13 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO13(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO13_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO13_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO14_MASK           (0x4000U)
+#define GPIO_DIRSET_DIRSETP_PIO14_SHIFT          (14U)
+/*! DIRSETP_PIO14 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO14(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO14_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO14_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO15_MASK           (0x8000U)
+#define GPIO_DIRSET_DIRSETP_PIO15_SHIFT          (15U)
+/*! DIRSETP_PIO15 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO15(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO15_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO15_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO16_MASK           (0x10000U)
+#define GPIO_DIRSET_DIRSETP_PIO16_SHIFT          (16U)
+/*! DIRSETP_PIO16 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO16(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO16_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO16_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO17_MASK           (0x20000U)
+#define GPIO_DIRSET_DIRSETP_PIO17_SHIFT          (17U)
+/*! DIRSETP_PIO17 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO17(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO17_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO17_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO18_MASK           (0x40000U)
+#define GPIO_DIRSET_DIRSETP_PIO18_SHIFT          (18U)
+/*! DIRSETP_PIO18 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO18(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO18_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO18_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO19_MASK           (0x80000U)
+#define GPIO_DIRSET_DIRSETP_PIO19_SHIFT          (19U)
+/*! DIRSETP_PIO19 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO19(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO19_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO19_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO20_MASK           (0x100000U)
+#define GPIO_DIRSET_DIRSETP_PIO20_SHIFT          (20U)
+/*! DIRSETP_PIO20 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO20(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO20_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO20_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO21_MASK           (0x200000U)
+#define GPIO_DIRSET_DIRSETP_PIO21_SHIFT          (21U)
+/*! DIRSETP_PIO21 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO21(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO21_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_DIRSET */
+#define GPIO_DIRSET_COUNT                        (1U)
+
+/*! @name DIRCLR - Clear pin direction bits */
+/*! @{ */
+#define GPIO_DIRCLR_DIRCLRP_PIO0_MASK            (0x1U)
+#define GPIO_DIRCLR_DIRCLRP_PIO0_SHIFT           (0U)
+/*! DIRCLRP_PIO0 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO0(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO0_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO0_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO1_MASK            (0x2U)
+#define GPIO_DIRCLR_DIRCLRP_PIO1_SHIFT           (1U)
+/*! DIRCLRP_PIO1 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO1(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO1_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO1_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO2_MASK            (0x4U)
+#define GPIO_DIRCLR_DIRCLRP_PIO2_SHIFT           (2U)
+/*! DIRCLRP_PIO2 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO2(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO2_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO2_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO3_MASK            (0x8U)
+#define GPIO_DIRCLR_DIRCLRP_PIO3_SHIFT           (3U)
+/*! DIRCLRP_PIO3 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO3(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO3_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO3_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO4_MASK            (0x10U)
+#define GPIO_DIRCLR_DIRCLRP_PIO4_SHIFT           (4U)
+/*! DIRCLRP_PIO4 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO4(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO4_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO4_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO5_MASK            (0x20U)
+#define GPIO_DIRCLR_DIRCLRP_PIO5_SHIFT           (5U)
+/*! DIRCLRP_PIO5 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO5(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO5_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO5_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO6_MASK            (0x40U)
+#define GPIO_DIRCLR_DIRCLRP_PIO6_SHIFT           (6U)
+/*! DIRCLRP_PIO6 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO6(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO6_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO6_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO7_MASK            (0x80U)
+#define GPIO_DIRCLR_DIRCLRP_PIO7_SHIFT           (7U)
+/*! DIRCLRP_PIO7 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO7(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO7_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO7_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO8_MASK            (0x100U)
+#define GPIO_DIRCLR_DIRCLRP_PIO8_SHIFT           (8U)
+/*! DIRCLRP_PIO8 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO8(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO8_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO8_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO9_MASK            (0x200U)
+#define GPIO_DIRCLR_DIRCLRP_PIO9_SHIFT           (9U)
+/*! DIRCLRP_PIO9 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO9(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO9_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO9_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO10_MASK           (0x400U)
+#define GPIO_DIRCLR_DIRCLRP_PIO10_SHIFT          (10U)
+/*! DIRCLRP_PIO10 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO10(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO10_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO10_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO11_MASK           (0x800U)
+#define GPIO_DIRCLR_DIRCLRP_PIO11_SHIFT          (11U)
+/*! DIRCLRP_PIO11 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO11(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO11_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO11_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO12_MASK           (0x1000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO12_SHIFT          (12U)
+/*! DIRCLRP_PIO12 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO12(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO12_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO12_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO13_MASK           (0x2000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO13_SHIFT          (13U)
+/*! DIRCLRP_PIO13 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO13(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO13_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO13_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO14_MASK           (0x4000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO14_SHIFT          (14U)
+/*! DIRCLRP_PIO14 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO14(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO14_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO14_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO15_MASK           (0x8000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO15_SHIFT          (15U)
+/*! DIRCLRP_PIO15 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO15(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO15_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO15_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO16_MASK           (0x10000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO16_SHIFT          (16U)
+/*! DIRCLRP_PIO16 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO16(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO16_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO16_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO17_MASK           (0x20000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO17_SHIFT          (17U)
+/*! DIRCLRP_PIO17 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO17(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO17_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO17_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO18_MASK           (0x40000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO18_SHIFT          (18U)
+/*! DIRCLRP_PIO18 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO18(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO18_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO18_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO19_MASK           (0x80000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO19_SHIFT          (19U)
+/*! DIRCLRP_PIO19 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO19(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO19_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO19_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO20_MASK           (0x100000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO20_SHIFT          (20U)
+/*! DIRCLRP_PIO20 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO20(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO20_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO20_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO21_MASK           (0x200000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO21_SHIFT          (21U)
+/*! DIRCLRP_PIO21 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO21(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO21_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_DIRCLR */
+#define GPIO_DIRCLR_COUNT                        (1U)
+
+/*! @name DIRNOT - Toggle pin direction bits */
+/*! @{ */
+#define GPIO_DIRNOT_DIRNOTP_PIO0_MASK            (0x1U)
+#define GPIO_DIRNOT_DIRNOTP_PIO0_SHIFT           (0U)
+/*! DIRNOTP_PIO0 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO0(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO0_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO0_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO1_MASK            (0x2U)
+#define GPIO_DIRNOT_DIRNOTP_PIO1_SHIFT           (1U)
+/*! DIRNOTP_PIO1 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO1(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO1_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO1_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO2_MASK            (0x4U)
+#define GPIO_DIRNOT_DIRNOTP_PIO2_SHIFT           (2U)
+/*! DIRNOTP_PIO2 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO2(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO2_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO2_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO3_MASK            (0x8U)
+#define GPIO_DIRNOT_DIRNOTP_PIO3_SHIFT           (3U)
+/*! DIRNOTP_PIO3 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO3(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO3_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO3_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO4_MASK            (0x10U)
+#define GPIO_DIRNOT_DIRNOTP_PIO4_SHIFT           (4U)
+/*! DIRNOTP_PIO4 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO4(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO4_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO4_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO5_MASK            (0x20U)
+#define GPIO_DIRNOT_DIRNOTP_PIO5_SHIFT           (5U)
+/*! DIRNOTP_PIO5 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO5(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO5_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO5_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO6_MASK            (0x40U)
+#define GPIO_DIRNOT_DIRNOTP_PIO6_SHIFT           (6U)
+/*! DIRNOTP_PIO6 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO6(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO6_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO6_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO7_MASK            (0x80U)
+#define GPIO_DIRNOT_DIRNOTP_PIO7_SHIFT           (7U)
+/*! DIRNOTP_PIO7 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO7(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO7_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO7_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO8_MASK            (0x100U)
+#define GPIO_DIRNOT_DIRNOTP_PIO8_SHIFT           (8U)
+/*! DIRNOTP_PIO8 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO8(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO8_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO8_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO9_MASK            (0x200U)
+#define GPIO_DIRNOT_DIRNOTP_PIO9_SHIFT           (9U)
+/*! DIRNOTP_PIO9 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO9(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO9_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO9_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO10_MASK           (0x400U)
+#define GPIO_DIRNOT_DIRNOTP_PIO10_SHIFT          (10U)
+/*! DIRNOTP_PIO10 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO10(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO10_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO10_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO11_MASK           (0x800U)
+#define GPIO_DIRNOT_DIRNOTP_PIO11_SHIFT          (11U)
+/*! DIRNOTP_PIO11 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO11(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO11_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO11_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO12_MASK           (0x1000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO12_SHIFT          (12U)
+/*! DIRNOTP_PIO12 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO12(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO12_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO12_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO13_MASK           (0x2000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO13_SHIFT          (13U)
+/*! DIRNOTP_PIO13 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO13(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO13_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO13_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO14_MASK           (0x4000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO14_SHIFT          (14U)
+/*! DIRNOTP_PIO14 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO14(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO14_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO14_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO15_MASK           (0x8000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO15_SHIFT          (15U)
+/*! DIRNOTP_PIO15 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO15(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO15_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO15_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO16_MASK           (0x10000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO16_SHIFT          (16U)
+/*! DIRNOTP_PIO16 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO16(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO16_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO16_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO17_MASK           (0x20000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO17_SHIFT          (17U)
+/*! DIRNOTP_PIO17 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO17(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO17_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO17_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO18_MASK           (0x40000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO18_SHIFT          (18U)
+/*! DIRNOTP_PIO18 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO18(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO18_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO18_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO19_MASK           (0x80000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO19_SHIFT          (19U)
+/*! DIRNOTP_PIO19 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO19(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO19_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO19_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO20_MASK           (0x100000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO20_SHIFT          (20U)
+/*! DIRNOTP_PIO20 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO20(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO20_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO20_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO21_MASK           (0x200000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO21_SHIFT          (21U)
+/*! DIRNOTP_PIO21 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO21(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO21_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_DIRNOT */
+#define GPIO_DIRNOT_COUNT                        (1U)
+
+
+/*!
+ * @}
+ */ /* end of group GPIO_Register_Masks */
+
+
+/* GPIO - Peripheral instance base addresses */
+/** Peripheral GPIO base address */
+#define GPIO_BASE                                (0x40080000u)
+/** Peripheral GPIO base pointer */
+#define GPIO                                     ((GPIO_Type *)GPIO_BASE)
+/** Array initializer of GPIO peripheral base addresses */
+#define GPIO_BASE_ADDRS                          { GPIO_BASE }
+/** Array initializer of GPIO peripheral base pointers */
+#define GPIO_BASE_PTRS                           { GPIO }
+
+/*!
+ * @}
+ */ /* end of group GPIO_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- I2C Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup I2C_Peripheral_Access_Layer I2C Peripheral Access Layer
+ * @{
+ */
+
+/** I2C - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CFG;                               /**< Configuration for shared functions., offset: 0x0 */
+  __IO uint32_t STAT;                              /**< Status register for Master, Slave and Monitor functions., offset: 0x4 */
+  __IO uint32_t INTENSET;                          /**< Interrupt Enable Set and read register., offset: 0x8 */
+  __O  uint32_t INTENCLR;                          /**< Interrupt Enable Clear register. Writing a 1 to this bit clears the corresponding bit in the INTENSET register, disabling that interrupt. This is a Write-only register., offset: 0xC */
+  __IO uint32_t TIMEOUT;                           /**< Time-out value register., offset: 0x10 */
+  __IO uint32_t CLKDIV;                            /**< Clock pre-divider for the entire I2C interface. This determines what time increments are used for the MSTTIME register and controls some timing of the Slave function., offset: 0x14 */
+  __I  uint32_t INTSTAT;                           /**< Interrupt Status register for Master, Slave and Monitor functions., offset: 0x18 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t MSTCTL;                            /**< Master control register., offset: 0x20 */
+  __IO uint32_t MSTTIME;                           /**< Master timing configuration., offset: 0x24 */
+  __IO uint32_t MSTDAT;                            /**< Combined Master receiver and transmitter data register., offset: 0x28 */
+       uint8_t RESERVED_1[20];
+  __IO uint32_t SLVCTL;                            /**< Slave control register., offset: 0x40 */
+  __IO uint32_t SLVDAT;                            /**< Combined Slave receiver and transmitter data register., offset: 0x44 */
+  __IO uint32_t SLVADR[4];                         /**< Slave address 0., array offset: 0x48, array step: 0x4 */
+  __IO uint32_t SLVQUAL0;                          /**< Slave Qualification for address 0., offset: 0x58 */
+       uint8_t RESERVED_2[36];
+  __I  uint32_t MONRXDAT;                          /**< Monitor receiver data register., offset: 0x80 */
+       uint8_t RESERVED_3[3960];
+  __I  uint32_t ID;                                /**< I2C Module Identifier, offset: 0xFFC */
+} I2C_Type;
+
+/* ----------------------------------------------------------------------------
+   -- I2C Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup I2C_Register_Masks I2C Register Masks
+ * @{
+ */
+
+/*! @name CFG - Configuration for shared functions. */
+/*! @{ */
+#define I2C_CFG_MSTEN_MASK                       (0x1U)
+#define I2C_CFG_MSTEN_SHIFT                      (0U)
+/*! MSTEN - Master Enable. When disabled, configurations settings for the Master function are not
+ *    changed, but the Master function is internally reset.
+ */
+#define I2C_CFG_MSTEN(x)                         (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MSTEN_SHIFT)) & I2C_CFG_MSTEN_MASK)
+#define I2C_CFG_SLVEN_MASK                       (0x2U)
+#define I2C_CFG_SLVEN_SHIFT                      (1U)
+/*! SLVEN - Slave Enable. When disabled, configurations settings for the Slave function are not
+ *    changed, but the Slave function is internally reset.
+ */
+#define I2C_CFG_SLVEN(x)                         (((uint32_t)(((uint32_t)(x)) << I2C_CFG_SLVEN_SHIFT)) & I2C_CFG_SLVEN_MASK)
+#define I2C_CFG_MONEN_MASK                       (0x4U)
+#define I2C_CFG_MONEN_SHIFT                      (2U)
+/*! MONEN - Monitor Enable. When disabled, configurations settings for the Monitor function are not
+ *    changed, but the Monitor function is internally reset.
+ */
+#define I2C_CFG_MONEN(x)                         (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONEN_SHIFT)) & I2C_CFG_MONEN_MASK)
+#define I2C_CFG_TIMEOUT_MASK                     (0x8U)
+#define I2C_CFG_TIMEOUT_SHIFT                    (3U)
+/*! TIMEOUT - I2C bus Time-out Enable. When disabled, the time-out function is internally reset.
+ */
+#define I2C_CFG_TIMEOUT(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_CFG_TIMEOUT_SHIFT)) & I2C_CFG_TIMEOUT_MASK)
+#define I2C_CFG_MONCLKSTR_MASK                   (0x10U)
+#define I2C_CFG_MONCLKSTR_SHIFT                  (4U)
+/*! MONCLKSTR - Monitor function Clock Stretching.
+ */
+#define I2C_CFG_MONCLKSTR(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONCLKSTR_SHIFT)) & I2C_CFG_MONCLKSTR_MASK)
+#define I2C_CFG_HSCAPABLE_MASK                   (0x20U)
+#define I2C_CFG_HSCAPABLE_SHIFT                  (5U)
+/*! HSCAPABLE - High-speed mode Capable enable. Since High Speed mode alters the way I2C pins drive
+ *    and filter, as well as the timing for certain I2C signalling, enabling High-speed mode applies
+ *    to all functions: master, slave, and monitor.
+ */
+#define I2C_CFG_HSCAPABLE(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_CFG_HSCAPABLE_SHIFT)) & I2C_CFG_HSCAPABLE_MASK)
+/*! @} */
+
+/*! @name STAT - Status register for Master, Slave and Monitor functions. */
+/*! @{ */
+#define I2C_STAT_MSTPENDING_MASK                 (0x1U)
+#define I2C_STAT_MSTPENDING_SHIFT                (0U)
+/*! MSTPENDING - Master Pending. Indicates that the Master is waiting to continue communication on
+ *    the I2C-bus (pending) or is idle. When the master is pending, the MSTSTATE bits indicate what
+ *    type of software service if any the master expects. This flag will cause an interrupt when set
+ *    if, enabled via the INTENSET register. The MSTPENDING flag is not set when the DMA is handling
+ *    an event (if the MSTDMA bit in the MSTCTL register is set). If the master is in the idle
+ *    state, and no communication is needed, mask this interrupt. 0: In progress. Communication is in
+ *    progress and the Master function is busy and cannot currently accept a command. 1: Pending. The
+ *    Master function needs software service or is in the idle state. If the master is not in the
+ *    idle state, it is waiting to receive or transmit data or the NACK bit.
+ */
+#define I2C_STAT_MSTPENDING(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTPENDING_SHIFT)) & I2C_STAT_MSTPENDING_MASK)
+#define I2C_STAT_MSTSTATE_MASK                   (0xEU)
+#define I2C_STAT_MSTSTATE_SHIFT                  (1U)
+/*! MSTSTATE - Master State code. The master state code reflects the master state when the
+ *    MSTPENDING bit is set, that is the master is pending or in the idle state. Each value of this field
+ *    indicates a specific required service for the Master function. All other values are reserved. 0:
+ *    Idle. The Master function is available to be used for a new transaction. 1: Receive ready.
+ *    Received data available (Master Receiver mode). Address plus Read was previously sent and
+ *    Acknowledged by slave. 2: Transmit ready. Data can be transmitted (Master Transmitter mode). Address
+ *    plus Write was previously sent and Acknowledged by slave. 3: NACK address. Slave NACKed
+ *    address. 4: NACK data. Slave NACKed transmitted data.
+ */
+#define I2C_STAT_MSTSTATE(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTATE_SHIFT)) & I2C_STAT_MSTSTATE_MASK)
+#define I2C_STAT_MSTARBLOSS_MASK                 (0x10U)
+#define I2C_STAT_MSTARBLOSS_SHIFT                (4U)
+/*! MSTARBLOSS - Master Arbitration Loss flag. This flag can be cleared by software writing a 1 to
+ *    this bit. It is also cleared automatically a 1 is written to MSTCONTINUE. 0: No Arbitration
+ *    Loss has occurred. 1: Arbitration Loss. The mater function has experienced an Arbitration Loss.
+ *    At this point, the Master function has already stopped driving the bus and gone to an idle
+ *    state. Software can respond by doing nothing, or by sending a Start in order to attempt to gain
+ *    control of the bus when it next becomes idle.
+ */
+#define I2C_STAT_MSTARBLOSS(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTARBLOSS_SHIFT)) & I2C_STAT_MSTARBLOSS_MASK)
+#define I2C_STAT_MSTSTSTPERR_MASK                (0x40U)
+#define I2C_STAT_MSTSTSTPERR_SHIFT               (6U)
+/*! MSTSTSTPERR - Master Start/Stop Error flag. This flag can be cleared by software writing a 1 to
+ *    this bit. It is also cleared automatically a 1 is written to MSTCONTINUE. 0: No start/stop
+ *    Error has occurred. 1: The master function has experienced a Start/Stop Error. A Start or Stop
+ *    was detected at a time when it is not allowed by the I2C specification. The Master interface has
+ *    stopped driving the bus and gone to an idle state, no action is required. A request for a
+ *    Start could be made, or software could attempt to insure that thet bus has not stalled.
+ */
+#define I2C_STAT_MSTSTSTPERR(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTSTPERR_SHIFT)) & I2C_STAT_MSTSTSTPERR_MASK)
+#define I2C_STAT_SLVPENDING_MASK                 (0x100U)
+#define I2C_STAT_SLVPENDING_SHIFT                (8U)
+/*! SLVPENDING - Slave Pending. Indicates that the Slave function is waiting to continue
+ *    communication on the I2C-bus and needs software service. This flag will cause an interrupt when set if
+ *    enabled via INTENSET. The SLVPENDING flag is not set when the DMA is handling an event (if the
+ *    SLVDMA bit in the SLVCTL register is set). The SLVPENDING flag is read-only and is
+ *    automatically cleared when a 1 is written to the SLVCONTINUE bit in the SLVCTL register. The point in time
+ *    when SlvPending is set depends on whether the I2C interface is in HSCAPABLE mode. When the
+ *    I2C interface is configured to be HSCAPABLE, HS master codes are detected automatically. Due to
+ *    the requirements of the HS I2C specification, slave addresses must also be detected
+ *    automatically, since the address must be acknowledged before the clock can be stretched. 0: In progress.
+ *    The slave function does not currently need service. 1: Pending. The Slave function needs
+ *    service. Information on what is needed can be found in the adjacent SLVSTATE field.
+ */
+#define I2C_STAT_SLVPENDING(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVPENDING_SHIFT)) & I2C_STAT_SLVPENDING_MASK)
+#define I2C_STAT_SLVSTATE_MASK                   (0x600U)
+#define I2C_STAT_SLVSTATE_SHIFT                  (9U)
+/*! SLVSTATE - Slave State code. Each value of this field indicates a specific required service for
+ *    the Slave function. All other values are reserved. See Table 393 for state values and actions.
+ *    Remark: note that the occurrence of some states and how they are handled are affected by DMA
+ *    mode and Automatic Operation modes. Slave state codes are: 0: Slave address. Address plus R/W
+ *    received. At least one of the four slave addresses has been matched by hardware. 1: Slave
+ *    receive. Received data is available (Slave Receiver mode). 2: Slave transmit. Data can be
+ *    transmitted (Slave transmitter mode).
+ */
+#define I2C_STAT_SLVSTATE(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSTATE_SHIFT)) & I2C_STAT_SLVSTATE_MASK)
+#define I2C_STAT_SLVNOTSTR_MASK                  (0x800U)
+#define I2C_STAT_SLVNOTSTR_SHIFT                 (11U)
+/*! SLVNOTSTR - Slave Not Stretching. Indicates when the slave function is stretching the I2C clock.
+ *    This is needed in order to gracefully invoke Deep Sleep or Power-down modes during slave
+ *    operation. This read-only flag reflects the slave function status in real time. 0: stretching. The
+ *    slave function is currently stretching the I2C bus clock. Deep-sleep mode can not be entered
+ *    at this time. 1. Not stretching. The slave function is not currently stretching the I2C bus
+ *    clock. Deep-sleep mode could be entered at this time.
+ */
+#define I2C_STAT_SLVNOTSTR(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVNOTSTR_SHIFT)) & I2C_STAT_SLVNOTSTR_MASK)
+#define I2C_STAT_SLVIDX_MASK                     (0x3000U)
+#define I2C_STAT_SLVIDX_SHIFT                    (12U)
+/*! SLVIDX - Slave address match Index. This field is valid when the I2C slave function has been
+ *    selected by receiving an address that matches one of the slave addresses defined by any enabled
+ *    slave address registers, and provides an identification of the address that was matched. It is
+ *    possible that more than one address could be matched, but only one match can be reported here.
+ *    0: Address 0. Slave address 0 was matched. 1: Address 1. Slave address 1 was matched. 2:
+ *    Address 2. Slave address 2 was matched. 3: Address 3. Slave address 3 was matched.
+ */
+#define I2C_STAT_SLVIDX(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVIDX_SHIFT)) & I2C_STAT_SLVIDX_MASK)
+#define I2C_STAT_SLVSEL_MASK                     (0x4000U)
+#define I2C_STAT_SLVSEL_SHIFT                    (14U)
+/*! SLVSEL - Slave selected flag. SLVSEL is set after an address match when software tells the Slave
+ *    function to acknowledge the address, or when the address has been automatically acknowledged.
+ *    It is cleared when another address cycle presents an address that does not match an enabled
+ *    address on the Slave function, when slave software decides to NACK a matched address, when
+ *    there is a Stop detected on the bus, when the master NACKs slave data, and in some combinations of
+ *    Automatic Operation. SLVSEL is not cleared if software NACKs data. 0: Not selected. The slave
+ *    function is not currently selected. 1: Selected. The slave function is currently selected.
+ */
+#define I2C_STAT_SLVSEL(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSEL_SHIFT)) & I2C_STAT_SLVSEL_MASK)
+#define I2C_STAT_SLVDESEL_MASK                   (0x8000U)
+#define I2C_STAT_SLVDESEL_SHIFT                  (15U)
+/*! SLVDESEL - Slave Deselected flag. This flag will cause an interrupt when set if enabled via
+ *    INTENSET. This flag can be cleared by writing a 1 to this bit. 0: Not deselected. The slave
+ *    function has not become deslected. This does not mean that it is currently selected. That
+ *    information can be found in the SLVSEL flag. 1: Deselected. The slave function has become deselected.
+ *    This is specifically caused by the SLVSEL flag changing from 1 to 0. See the description of
+ *    SLVSEL for details on when that event occurs.
+ */
+#define I2C_STAT_SLVDESEL(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVDESEL_SHIFT)) & I2C_STAT_SLVDESEL_MASK)
+#define I2C_STAT_MONRDY_MASK                     (0x10000U)
+#define I2C_STAT_MONRDY_SHIFT                    (16U)
+/*! MONRDY - Monitor Ready. This flag is cleared when the MONRXDAT register is read. 0: No data. The
+ *    Monitor function does not currently have data available. 1: Data waiting. The Monitor
+ *    function has data waiting to be read.
+ */
+#define I2C_STAT_MONRDY(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONRDY_SHIFT)) & I2C_STAT_MONRDY_MASK)
+#define I2C_STAT_MONOV_MASK                      (0x20000U)
+#define I2C_STAT_MONOV_SHIFT                     (17U)
+/*! MONOV - Monitor Overflow flag. 0: No overrun. Monitor data has not overrun 1: Overrun. A monitor
+ *    data overrun has occurred. This can only happen when Monitor clock stretching is not enabled
+ *    via the MOCCLKSTR bit in the CFG register. Writing 1 to this bit clears the flag.
+ */
+#define I2C_STAT_MONOV(x)                        (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONOV_SHIFT)) & I2C_STAT_MONOV_MASK)
+#define I2C_STAT_MONACTIVE_MASK                  (0x40000U)
+#define I2C_STAT_MONACTIVE_SHIFT                 (18U)
+/*! MONACTIVE - Monitor Active flag. Indicates when the Monitor function considers the I2C bus to be
+ *    active. Active is defined here as when some Master is on the bus: a bus Start has occurred
+ *    more recently than a bus Stop. 0: Inactive. The Monitor function considers the I2C bus to be
+ *    inactive. 1: Active. The Monitor function considers the I2C bus to be active.
+ */
+#define I2C_STAT_MONACTIVE(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONACTIVE_SHIFT)) & I2C_STAT_MONACTIVE_MASK)
+#define I2C_STAT_MONIDLE_MASK                    (0x80000U)
+#define I2C_STAT_MONIDLE_SHIFT                   (19U)
+/*! MONIDLE - Monitor Idle flag. This flag is set when the Monitor function sees the I2C bus change
+ *    from active to inactive. This can be used by software to decide when to process data
+ *    accumulated by the Monitor function. This flag will cause an interrupt when set if enabled via the
+ *    INTENSET register. The flag can be cleared by writing a 1 to this bit. 0: Not idle. The I2C bus is
+ *    not idle, or this flag has been cleared by software. 1: Idle. The I2C bus has gone idle at
+ *    least once since the last time this flag was cleared by software.
+ */
+#define I2C_STAT_MONIDLE(x)                      (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONIDLE_SHIFT)) & I2C_STAT_MONIDLE_MASK)
+#define I2C_STAT_EVENTTIMEOUT_MASK               (0x1000000U)
+#define I2C_STAT_EVENTTIMEOUT_SHIFT              (24U)
+/*! EVENTTIMEOUT - Event Time-out Interrupt flag. Indicates when the time between events has been
+ *    longer than the time specified by the TIMEOUT register. Events include Start, Stop, and clock
+ *    edges. The flag is cleared by writing a 1 to this bit. No time-out is created when the I2C-bus
+ *    is idle. 0: No time-out. I2C bus events have not casued a time-out. 1: Event time-out. The time
+ *    between I2C bus events has been longer than the time specified by the TIMEOUT register.
+ */
+#define I2C_STAT_EVENTTIMEOUT(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_STAT_EVENTTIMEOUT_SHIFT)) & I2C_STAT_EVENTTIMEOUT_MASK)
+#define I2C_STAT_SCLTIMEOUT_MASK                 (0x2000000U)
+#define I2C_STAT_SCLTIMEOUT_SHIFT                (25U)
+/*! SCLTIMEOUT - SCL Time-out Interrupt flag. Indicates when SCL has remained low longer than the
+ *    time specific by the TIMEOUT register. The flag is cleared by writing a 1 to this bit. 0: No
+ *    time-out. SCL low time has not caused a time-out. 1: Time-out. SCL low time has not caused a
+ *    time-out.
+ */
+#define I2C_STAT_SCLTIMEOUT(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SCLTIMEOUT_SHIFT)) & I2C_STAT_SCLTIMEOUT_MASK)
+/*! @} */
+
+/*! @name INTENSET - Interrupt Enable Set and read register. */
+/*! @{ */
+#define I2C_INTENSET_MSTPENDINGEN_MASK           (0x1U)
+#define I2C_INTENSET_MSTPENDINGEN_SHIFT          (0U)
+/*! MSTPENDINGEN - Master Pending interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MSTPENDINGEN(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTPENDINGEN_SHIFT)) & I2C_INTENSET_MSTPENDINGEN_MASK)
+#define I2C_INTENSET_MSTARBLOSSEN_MASK           (0x10U)
+#define I2C_INTENSET_MSTARBLOSSEN_SHIFT          (4U)
+/*! MSTARBLOSSEN - Master Arbitration Loss interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MSTARBLOSSEN(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTARBLOSSEN_SHIFT)) & I2C_INTENSET_MSTARBLOSSEN_MASK)
+#define I2C_INTENSET_MSTSTSTPERREN_MASK          (0x40U)
+#define I2C_INTENSET_MSTSTSTPERREN_SHIFT         (6U)
+/*! MSTSTSTPERREN - Master Start/Stop Error interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MSTSTSTPERREN(x)            (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTSTSTPERREN_SHIFT)) & I2C_INTENSET_MSTSTSTPERREN_MASK)
+#define I2C_INTENSET_SLVPENDINGEN_MASK           (0x100U)
+#define I2C_INTENSET_SLVPENDINGEN_SHIFT          (8U)
+/*! SLVPENDINGEN - Slave Pending interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_SLVPENDINGEN(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVPENDINGEN_SHIFT)) & I2C_INTENSET_SLVPENDINGEN_MASK)
+#define I2C_INTENSET_SLVNOTSTREN_MASK            (0x800U)
+#define I2C_INTENSET_SLVNOTSTREN_SHIFT           (11U)
+/*! SLVNOTSTREN - Slave Not Stretching interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_SLVNOTSTREN(x)              (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVNOTSTREN_SHIFT)) & I2C_INTENSET_SLVNOTSTREN_MASK)
+#define I2C_INTENSET_SLVDESELEN_MASK             (0x8000U)
+#define I2C_INTENSET_SLVDESELEN_SHIFT            (15U)
+/*! SLVDESELEN - Slave Deselect interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_SLVDESELEN(x)               (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVDESELEN_SHIFT)) & I2C_INTENSET_SLVDESELEN_MASK)
+#define I2C_INTENSET_MONRDYEN_MASK               (0x10000U)
+#define I2C_INTENSET_MONRDYEN_SHIFT              (16U)
+/*! MONRDYEN - Monitor data Ready interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MONRDYEN(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONRDYEN_SHIFT)) & I2C_INTENSET_MONRDYEN_MASK)
+#define I2C_INTENSET_MONOVEN_MASK                (0x20000U)
+#define I2C_INTENSET_MONOVEN_SHIFT               (17U)
+/*! MONOVEN - Monitor Overrun interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MONOVEN(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONOVEN_SHIFT)) & I2C_INTENSET_MONOVEN_MASK)
+#define I2C_INTENSET_MONIDLEEN_MASK              (0x80000U)
+#define I2C_INTENSET_MONIDLEEN_SHIFT             (19U)
+/*! MONIDLEEN - Monitor Idle interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MONIDLEEN(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONIDLEEN_SHIFT)) & I2C_INTENSET_MONIDLEEN_MASK)
+#define I2C_INTENSET_EVENTTIMEOUTEN_MASK         (0x1000000U)
+#define I2C_INTENSET_EVENTTIMEOUTEN_SHIFT        (24U)
+/*! EVENTTIMEOUTEN - Event time-out interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_EVENTTIMEOUTEN(x)           (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_EVENTTIMEOUTEN_SHIFT)) & I2C_INTENSET_EVENTTIMEOUTEN_MASK)
+#define I2C_INTENSET_SCLTIMEOUTEN_MASK           (0x2000000U)
+#define I2C_INTENSET_SCLTIMEOUTEN_SHIFT          (25U)
+/*! SCLTIMEOUTEN - SCL time-out interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_SCLTIMEOUTEN(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SCLTIMEOUTEN_SHIFT)) & I2C_INTENSET_SCLTIMEOUTEN_MASK)
+/*! @} */
+
+/*! @name INTENCLR - Interrupt Enable Clear register. Writing a 1 to this bit clears the corresponding bit in the INTENSET register, disabling that interrupt. This is a Write-only register. */
+/*! @{ */
+#define I2C_INTENCLR_MSTPCLRDINGCLR_MASK         (0x1U)
+#define I2C_INTENCLR_MSTPCLRDINGCLR_SHIFT        (0U)
+/*! MSTPCLRDINGCLR - Master Pending interrupt clear.
+ */
+#define I2C_INTENCLR_MSTPCLRDINGCLR(x)           (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTPCLRDINGCLR_SHIFT)) & I2C_INTENCLR_MSTPCLRDINGCLR_MASK)
+#define I2C_INTENCLR_MSTARBLOSSCLR_MASK          (0x10U)
+#define I2C_INTENCLR_MSTARBLOSSCLR_SHIFT         (4U)
+/*! MSTARBLOSSCLR - Master Arbitration Loss interrupt clear.
+ */
+#define I2C_INTENCLR_MSTARBLOSSCLR(x)            (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTARBLOSSCLR_SHIFT)) & I2C_INTENCLR_MSTARBLOSSCLR_MASK)
+#define I2C_INTENCLR_MSTSTSTPERRCLR_MASK         (0x40U)
+#define I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT        (6U)
+/*! MSTSTSTPERRCLR - Master Start/Stop Error interrupt clear.
+ */
+#define I2C_INTENCLR_MSTSTSTPERRCLR(x)           (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT)) & I2C_INTENCLR_MSTSTSTPERRCLR_MASK)
+#define I2C_INTENCLR_SLVPENDINGCLR_MASK          (0x100U)
+#define I2C_INTENCLR_SLVPENDINGCLR_SHIFT         (8U)
+/*! SLVPENDINGCLR - Slave Pending interrupt clear.
+ */
+#define I2C_INTENCLR_SLVPENDINGCLR(x)            (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVPENDINGCLR_SHIFT)) & I2C_INTENCLR_SLVPENDINGCLR_MASK)
+#define I2C_INTENCLR_SLVNOTSTRCLR_MASK           (0x800U)
+#define I2C_INTENCLR_SLVNOTSTRCLR_SHIFT          (11U)
+/*! SLVNOTSTRCLR - Slave Not Stretching interrupt clear.
+ */
+#define I2C_INTENCLR_SLVNOTSTRCLR(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVNOTSTRCLR_SHIFT)) & I2C_INTENCLR_SLVNOTSTRCLR_MASK)
+#define I2C_INTENCLR_SLVDESELCLR_MASK            (0x8000U)
+#define I2C_INTENCLR_SLVDESELCLR_SHIFT           (15U)
+/*! SLVDESELCLR - Slave Deselect interrupt clear.
+ */
+#define I2C_INTENCLR_SLVDESELCLR(x)              (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVDESELCLR_SHIFT)) & I2C_INTENCLR_SLVDESELCLR_MASK)
+#define I2C_INTENCLR_MONRDYCLR_MASK              (0x10000U)
+#define I2C_INTENCLR_MONRDYCLR_SHIFT             (16U)
+/*! MONRDYCLR - Monitor data Ready interrupt clear.
+ */
+#define I2C_INTENCLR_MONRDYCLR(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONRDYCLR_SHIFT)) & I2C_INTENCLR_MONRDYCLR_MASK)
+#define I2C_INTENCLR_MONOVCLR_MASK               (0x20000U)
+#define I2C_INTENCLR_MONOVCLR_SHIFT              (17U)
+/*! MONOVCLR - Monitor Overrun interrupt clear.
+ */
+#define I2C_INTENCLR_MONOVCLR(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONOVCLR_SHIFT)) & I2C_INTENCLR_MONOVCLR_MASK)
+#define I2C_INTENCLR_MONIDLECLR_MASK             (0x80000U)
+#define I2C_INTENCLR_MONIDLECLR_SHIFT            (19U)
+/*! MONIDLECLR - Monitor Idle interrupt clear.
+ */
+#define I2C_INTENCLR_MONIDLECLR(x)               (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONIDLECLR_SHIFT)) & I2C_INTENCLR_MONIDLECLR_MASK)
+#define I2C_INTENCLR_EVCLRTTIMEOUTCLR_MASK       (0x1000000U)
+#define I2C_INTENCLR_EVCLRTTIMEOUTCLR_SHIFT      (24U)
+/*! EVCLRTTIMEOUTCLR - Event time-out interrupt clear.
+ */
+#define I2C_INTENCLR_EVCLRTTIMEOUTCLR(x)         (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_EVCLRTTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_EVCLRTTIMEOUTCLR_MASK)
+#define I2C_INTENCLR_SCLTIMEOUTCLR_MASK          (0x2000000U)
+#define I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT         (25U)
+/*! SCLTIMEOUTCLR - SCL time-out interrupt clear.
+ */
+#define I2C_INTENCLR_SCLTIMEOUTCLR(x)            (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_SCLTIMEOUTCLR_MASK)
+/*! @} */
+
+/*! @name TIMEOUT - Time-out value register. */
+/*! @{ */
+#define I2C_TIMEOUT_TOMIN_MASK                   (0xFU)
+#define I2C_TIMEOUT_TOMIN_SHIFT                  (0U)
+/*! TOMIN - Time-out time value, bottom four bits. These are hard-wired to 0xF. This gives a minimum
+ *    time-out of 16 I2C function clocks and also a time-out resolution of 16 I2C function clocks.
+ */
+#define I2C_TIMEOUT_TOMIN(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TOMIN_SHIFT)) & I2C_TIMEOUT_TOMIN_MASK)
+#define I2C_TIMEOUT_TO_MASK                      (0xFFF0U)
+#define I2C_TIMEOUT_TO_SHIFT                     (4U)
+/*! TO - Time-out time value. Specifies the time-out interval value in increments of 16 I2C function
+ *    clocks, as defined by the CLKDIV register. To change this value while I2C is in operation,
+ *    disable all time-outs, write a new value to TIMEOUT, then re-enable time-outs. 0x000: A time-out
+ *    will occur after 16 counts of the I2C function clock. 0x001: A time-out will occur after 32
+ *    counts of the I2C function clock. ... 0xFFF: A time-out will occur after 65,536 counts of the
+ *    I2C function clock.
+ */
+#define I2C_TIMEOUT_TO(x)                        (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TO_SHIFT)) & I2C_TIMEOUT_TO_MASK)
+/*! @} */
+
+/*! @name CLKDIV - Clock pre-divider for the entire I2C interface. This determines what time increments are used for the MSTTIME register and controls some timing of the Slave function. */
+/*! @{ */
+#define I2C_CLKDIV_DIVVAL_MASK                   (0xFFFFU)
+#define I2C_CLKDIV_DIVVAL_SHIFT                  (0U)
+/*! DIVVAL - This field controls how the I2C clock (FCLK) is used by the I2C functions that need an
+ *    internal clock in order to operate. I2C block should be configured for 8MHz clock, this will
+ *    limit SCL master clock range from 444kHz to 2MHz. 0x0000 = FCLK is used directly by the I2C.
+ *    0x0001 = FCLK is divided by 2 before use. 0x0002 = FCLK is divided by 3 before use. ... 0xFFFF =
+ *    FCLK is divided by 65,536 before use.
+ */
+#define I2C_CLKDIV_DIVVAL(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_CLKDIV_DIVVAL_SHIFT)) & I2C_CLKDIV_DIVVAL_MASK)
+/*! @} */
+
+/*! @name INTSTAT - Interrupt Status register for Master, Slave and Monitor functions. */
+/*! @{ */
+#define I2C_INTSTAT_MSTPENDING_MASK              (0x1U)
+#define I2C_INTSTAT_MSTPENDING_SHIFT             (0U)
+/*! MSTPENDING - Master Pending interrupt.
+ */
+#define I2C_INTSTAT_MSTPENDING(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTPENDING_SHIFT)) & I2C_INTSTAT_MSTPENDING_MASK)
+#define I2C_INTSTAT_MSTARBLOSS_MASK              (0x10U)
+#define I2C_INTSTAT_MSTARBLOSS_SHIFT             (4U)
+/*! MSTARBLOSS - Master Arbitration Loss interrupt.
+ */
+#define I2C_INTSTAT_MSTARBLOSS(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTARBLOSS_SHIFT)) & I2C_INTSTAT_MSTARBLOSS_MASK)
+#define I2C_INTSTAT_MSTSTSTPERR_MASK             (0x40U)
+#define I2C_INTSTAT_MSTSTSTPERR_SHIFT            (6U)
+/*! MSTSTSTPERR - Master Start/Stop Error interrupt.
+ */
+#define I2C_INTSTAT_MSTSTSTPERR(x)               (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTSTSTPERR_SHIFT)) & I2C_INTSTAT_MSTSTSTPERR_MASK)
+#define I2C_INTSTAT_SLVPENDING_MASK              (0x100U)
+#define I2C_INTSTAT_SLVPENDING_SHIFT             (8U)
+/*! SLVPENDING - Slave Pending interrupt.
+ */
+#define I2C_INTSTAT_SLVPENDING(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVPENDING_SHIFT)) & I2C_INTSTAT_SLVPENDING_MASK)
+#define I2C_INTSTAT_SLVNOTSTR_MASK               (0x800U)
+#define I2C_INTSTAT_SLVNOTSTR_SHIFT              (11U)
+/*! SLVNOTSTR - Slave Not Stretching interrupt.
+ */
+#define I2C_INTSTAT_SLVNOTSTR(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVNOTSTR_SHIFT)) & I2C_INTSTAT_SLVNOTSTR_MASK)
+#define I2C_INTSTAT_SLVDESEL_MASK                (0x8000U)
+#define I2C_INTSTAT_SLVDESEL_SHIFT               (15U)
+/*! SLVDESEL - Slave Deselect interrupt.
+ */
+#define I2C_INTSTAT_SLVDESEL(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVDESEL_SHIFT)) & I2C_INTSTAT_SLVDESEL_MASK)
+#define I2C_INTSTAT_MONRDY_MASK                  (0x10000U)
+#define I2C_INTSTAT_MONRDY_SHIFT                 (16U)
+/*! MONRDY - Monitor data Ready interrupt.
+ */
+#define I2C_INTSTAT_MONRDY(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONRDY_SHIFT)) & I2C_INTSTAT_MONRDY_MASK)
+#define I2C_INTSTAT_MONOV_MASK                   (0x20000U)
+#define I2C_INTSTAT_MONOV_SHIFT                  (17U)
+/*! MONOV - Monitor Overrun interrupt.
+ */
+#define I2C_INTSTAT_MONOV(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONOV_SHIFT)) & I2C_INTSTAT_MONOV_MASK)
+#define I2C_INTSTAT_MONIDLE_MASK                 (0x80000U)
+#define I2C_INTSTAT_MONIDLE_SHIFT                (19U)
+/*! MONIDLE - Monitor Idle interrupt.
+ */
+#define I2C_INTSTAT_MONIDLE(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONIDLE_SHIFT)) & I2C_INTSTAT_MONIDLE_MASK)
+#define I2C_INTSTAT_EVTTIMEOUT_MASK              (0x1000000U)
+#define I2C_INTSTAT_EVTTIMEOUT_SHIFT             (24U)
+/*! EVTTIMEOUT - Event time-out interrupt.
+ */
+#define I2C_INTSTAT_EVTTIMEOUT(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_EVTTIMEOUT_SHIFT)) & I2C_INTSTAT_EVTTIMEOUT_MASK)
+#define I2C_INTSTAT_SCLTIMEOUT_MASK              (0x2000000U)
+#define I2C_INTSTAT_SCLTIMEOUT_SHIFT             (25U)
+/*! SCLTIMEOUT - SCL time-out interrupt.
+ */
+#define I2C_INTSTAT_SCLTIMEOUT(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SCLTIMEOUT_SHIFT)) & I2C_INTSTAT_SCLTIMEOUT_MASK)
+/*! @} */
+
+/*! @name MSTCTL - Master control register. */
+/*! @{ */
+#define I2C_MSTCTL_MSTCONTINUE_MASK              (0x1U)
+#define I2C_MSTCTL_MSTCONTINUE_SHIFT             (0U)
+/*! MSTCONTINUE - Master Continue. This bit is write-only. 0: No effect. 1: Continue. Informs the
+ *    Master function to continue to the next operation. This must be done after writing transmit
+ *    data, reading received data, or other housekeeping related to the next bus operation.
+ */
+#define I2C_MSTCTL_MSTCONTINUE(x)                (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTCONTINUE_SHIFT)) & I2C_MSTCTL_MSTCONTINUE_MASK)
+#define I2C_MSTCTL_MSTSTART_MASK                 (0x2U)
+#define I2C_MSTCTL_MSTSTART_SHIFT                (1U)
+/*! MSTSTART - Master Start control. This bit is write-only. 0: No effect. 1. Start. A start will be
+ *    generated on the I2C bus at the next allowed time.
+ */
+#define I2C_MSTCTL_MSTSTART(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTART_SHIFT)) & I2C_MSTCTL_MSTSTART_MASK)
+#define I2C_MSTCTL_MSTSTOP_MASK                  (0x4U)
+#define I2C_MSTCTL_MSTSTOP_SHIFT                 (2U)
+/*! MSTSTOP - Master Stop control. This bit is write-only. 0: No effect. 1. Stop. A stop will be
+ *    generated on the I2C bus at the next allowed time, preceded by a NACK to the slave if the master
+ *    is receiving data from the salve (Master Receiver mode).
+ */
+#define I2C_MSTCTL_MSTSTOP(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTOP_SHIFT)) & I2C_MSTCTL_MSTSTOP_MASK)
+#define I2C_MSTCTL_MSTDMA_MASK                   (0x8U)
+#define I2C_MSTCTL_MSTDMA_SHIFT                  (3U)
+/*! MSTDMA - Master DMA enable. Data operations of the I2C can be performed with DMA. Protocol type
+ *    operations such as Start, address, Stop, and address match must always be done with software,
+ *    typically via an interrupt. Address acknowledgement must also be done by software except when
+ *    the I2C is configured to be HSCAPABLE (and address acknowledgement is handled entirely by
+ *    hardware) or when Automatic Operation is enabled. When a DMA data transfer is complete, MSTDMA
+ *    must be cleared prior to beginning the next operation, typically a Start or Stop.This bit is
+ *    read/write. 0: Disable. No DMA requests are generated for master operation. 1: Enable. A DMA
+ *    request is generated for I2C master data operations. When this I2C master is generating Acknowledge
+ *    bits in Master Receiver mode, the acknowledge is generated automatically.
+ */
+#define I2C_MSTCTL_MSTDMA(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTDMA_SHIFT)) & I2C_MSTCTL_MSTDMA_MASK)
+/*! @} */
+
+/*! @name MSTTIME - Master timing configuration. */
+/*! @{ */
+#define I2C_MSTTIME_MSTSCLLOW_MASK               (0x7U)
+#define I2C_MSTTIME_MSTSCLLOW_SHIFT              (0U)
+/*! MSTSCLLOW - Master SCL Low time. Specifies the minimum low time that will be asserted by this
+ *    master on SCL. Other devices on the bus (masters or slaves) could lengthen this time. This
+ *    corresponds to the parameter tLOW in the I2C bus specification. I2C bus specification parameters
+ *    tBUF and tSU;STA have the same values and are also controlled by MSTSCLLOW. The minimum SCL low
+ *    time is (MSTSCLLOW + 2) clocks of the I2C clock pre-divider.
+ */
+#define I2C_MSTTIME_MSTSCLLOW(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLLOW_SHIFT)) & I2C_MSTTIME_MSTSCLLOW_MASK)
+#define I2C_MSTTIME_MSTSCLHIGH_MASK              (0x70U)
+#define I2C_MSTTIME_MSTSCLHIGH_SHIFT             (4U)
+/*! MSTSCLHIGH - Master SCL High time. Specifies the minimum high time that will be asserted by this
+ *    master on SCL. Other masters in a multi-master system could shorten this time. This
+ *    corresponds to the parameter tHIGH in the I2C bus specification. I2C bus specification parameters
+ *    tSU;STO and tHD;STA have the same values and are also controlled by MSTSCLHIGH.
+ */
+#define I2C_MSTTIME_MSTSCLHIGH(x)                (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLHIGH_SHIFT)) & I2C_MSTTIME_MSTSCLHIGH_MASK)
+/*! @} */
+
+/*! @name MSTDAT - Combined Master receiver and transmitter data register. */
+/*! @{ */
+#define I2C_MSTDAT_DATA_MASK                     (0xFFU)
+#define I2C_MSTDAT_DATA_SHIFT                    (0U)
+/*! DATA - Master function data register. Read: read the most recently received data for the Master
+ *    function. Write: transmit data using the Master function.
+ */
+#define I2C_MSTDAT_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_MSTDAT_DATA_SHIFT)) & I2C_MSTDAT_DATA_MASK)
+/*! @} */
+
+/*! @name SLVCTL - Slave control register. */
+/*! @{ */
+#define I2C_SLVCTL_SLVCONTINUE_MASK              (0x1U)
+#define I2C_SLVCTL_SLVCONTINUE_SHIFT             (0U)
+/*! SLVCONTINUE - Slave Continue. 0: no effect 1: Continue. Informs the Slave function to continue
+ *    to the next operation, by clearing the SLVPENDING flag in the STAT register. This must be done
+ *    after writing transmit data, reading recevied data, or any other housekeeping related to the
+ *    next bus operation. Automatic Operation has different requirements. SLVCONTINUE should not be
+ *    set unless SLVPENDING=1.
+ */
+#define I2C_SLVCTL_SLVCONTINUE(x)                (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVCONTINUE_SHIFT)) & I2C_SLVCTL_SLVCONTINUE_MASK)
+#define I2C_SLVCTL_SLVNACK_MASK                  (0x2U)
+#define I2C_SLVCTL_SLVNACK_SHIFT                 (1U)
+/*! SLVNACK - Slave NACK. 0: No effect. 1: NACK. Causes the Slave function to NACK the master when
+ *    the slave is receiving data from the master (Slave Receiver mode).
+ */
+#define I2C_SLVCTL_SLVNACK(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVNACK_SHIFT)) & I2C_SLVCTL_SLVNACK_MASK)
+#define I2C_SLVCTL_SLVDMA_MASK                   (0x8U)
+#define I2C_SLVCTL_SLVDMA_SHIFT                  (3U)
+/*! SLVDMA - Slave DMA enable. 0: Slave DMA enable. 1: Enabled. DMA requests are issued for I2C
+ *    slave data transmission and reception.
+ */
+#define I2C_SLVCTL_SLVDMA(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVDMA_SHIFT)) & I2C_SLVCTL_SLVDMA_MASK)
+#define I2C_SLVCTL_AUTOACK_MASK                  (0x100U)
+#define I2C_SLVCTL_AUTOACK_SHIFT                 (8U)
+/*! AUTOACK - Automatic Acknowledge.When this bit is set, it will cause an I2C header which matches
+ *    SLVADR0 and the direction set by AUTOMATCHREAD to be ACKed immediately; this is used with DMA
+ *    to allow processing of the data without intervention. If this bit is clear and a header
+ *    matches SLVADR0, the behavior is controlled by AUTONACK in the SLVADR0 register: allowing NACK or
+ *    interrupt. 0: Normal, non-automatic operation. If AUTONACK = 0, an SlvPending interrupt is
+ *    generated when a matching address is received. If AUTONACK-1, receiver addresses are NACKed
+ *    (ignored). 1: A header with matching SLVADR0 and matching direction as set by AUTOMATCHREAD will be
+ *    ACKed immediately, allowing the master to move on to the data bytes. If the address matches
+ *    SLVADR0, but the direction does not match AUTOMATCHREAD, the behaviour will depend on the
+ *    AUTONACK bit in the SLVADR0 register: if AUTONACK is set, then it will be Nacked; else if AUTONACK is
+ *    cl;ear, then a SlvPending interrupt is geernated.
+ */
+#define I2C_SLVCTL_AUTOACK(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_AUTOACK_SHIFT)) & I2C_SLVCTL_AUTOACK_MASK)
+#define I2C_SLVCTL_AUTOMATCHREAD_MASK            (0x200U)
+#define I2C_SLVCTL_AUTOMATCHREAD_SHIFT           (9U)
+/*! AUTOMATCHREAD - When AUTOACK is set, this bit controls whether it matches a read or write
+ *    request on the next header with an address matching SLVADR0. Since DMA needs to be configured to
+ *    match the transfer direction, the direction needs to be specified. This bit allows a direction to
+ *    be chosen for the next operation. 0: The expected next operation in Automatic Mode is an I2C
+ *    write. 1: The expected next operation in Automatic Mode is an I2C read.
+ */
+#define I2C_SLVCTL_AUTOMATCHREAD(x)              (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_AUTOMATCHREAD_SHIFT)) & I2C_SLVCTL_AUTOMATCHREAD_MASK)
+/*! @} */
+
+/*! @name SLVDAT - Combined Slave receiver and transmitter data register. */
+/*! @{ */
+#define I2C_SLVDAT_DATA_MASK                     (0xFFU)
+#define I2C_SLVDAT_DATA_SHIFT                    (0U)
+/*! DATA - Slave function data register. Read: read the most recently received data for the Slave
+ *    function. Write: transmit data using the Slave function.
+ */
+#define I2C_SLVDAT_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_SLVDAT_DATA_SHIFT)) & I2C_SLVDAT_DATA_MASK)
+/*! @} */
+
+/*! @name SLVADR - Slave address 0. */
+/*! @{ */
+#define I2C_SLVADR_SADISABLE_MASK                (0x1U)
+#define I2C_SLVADR_SADISABLE_SHIFT               (0U)
+/*! SADISABLE - Slave Address 0 Disable. 0: Slave Address 0 is enabled. 1: Slave Address 0 is ignored.
+ */
+#define I2C_SLVADR_SADISABLE(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SADISABLE_SHIFT)) & I2C_SLVADR_SADISABLE_MASK)
+#define I2C_SLVADR_SLVADR_MASK                   (0xFEU)
+#define I2C_SLVADR_SLVADR_SHIFT                  (1U)
+/*! SLVADR - Slave Address. Seven bit slave address that is compared to received addresses if
+ *    enabled. The compare can be affected by the setting of the SLVQUAL0 register.
+ */
+#define I2C_SLVADR_SLVADR(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SLVADR_SHIFT)) & I2C_SLVADR_SLVADR_MASK)
+#define I2C_SLVADR_AUTONACK_MASK                 (0x8000U)
+#define I2C_SLVADR_AUTONACK_SHIFT                (15U)
+/*! AUTONACK - Automatic NACK operation. Used in conjunction with AUTOACK and AUTOMATCHREAD, allows
+ *    software to ignore I2C traffic while handling previous I2C data or other operations. 0: Normal
+ *    operation, matching I2C addresses are not ignored. 1: Automatic-only mode. If AUTOACK is not
+ *    set, all incoming I2C addresses are ignored.
+ */
+#define I2C_SLVADR_AUTONACK(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_AUTONACK_SHIFT)) & I2C_SLVADR_AUTONACK_MASK)
+/*! @} */
+
+/* The count of I2C_SLVADR */
+#define I2C_SLVADR_COUNT                         (4U)
+
+/*! @name SLVQUAL0 - Slave Qualification for address 0. */
+/*! @{ */
+#define I2C_SLVQUAL0_QUALMODE0_MASK              (0x1U)
+#define I2C_SLVQUAL0_QUALMODE0_SHIFT             (0U)
+/*! QUALMODE0 - Qualify mode for slave address 0. 0: Mask. The SLVQUAL0 field is used as a logical
+ *    mask for matching address 0. 1: Extend. The SLVQAL0 field is used to extend address 0 matching
+ *    in a range of addresses.
+ */
+#define I2C_SLVQUAL0_QUALMODE0(x)                (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_QUALMODE0_SHIFT)) & I2C_SLVQUAL0_QUALMODE0_MASK)
+#define I2C_SLVQUAL0_SLVQUAL0_MASK               (0xFEU)
+#define I2C_SLVQUAL0_SLVQUAL0_SHIFT              (1U)
+/*! SLVQUAL0 - Slave address Qualifier for address 0. A value of 0 causes the address in SLVADR0 to
+ *    be used as-is, assuming that it is enabled. If QUALMODE0 = 0, any bit in this field which is
+ *    set to 1 will cause an automatic match of the corresponding bit of the received address when it
+ *    is compared to the SLVADR0 register. If QUALMODE0 = 1, an address range is matched for
+ *    address 0. This range extends from the value defined by SLVADR0 to the address defined by SLVQUAL0
+ *    (address matches when SLVADR0[7:1] received address SLVQUAL0[7:1]).
+ */
+#define I2C_SLVQUAL0_SLVQUAL0(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_SLVQUAL0_SHIFT)) & I2C_SLVQUAL0_SLVQUAL0_MASK)
+/*! @} */
+
+/*! @name MONRXDAT - Monitor receiver data register. */
+/*! @{ */
+#define I2C_MONRXDAT_MONRXDAT_MASK               (0xFFU)
+#define I2C_MONRXDAT_MONRXDAT_SHIFT              (0U)
+/*! MONRXDAT - Monitor function Receiver Data. This reflects every data byte that passes on the I2C pins.
+ */
+#define I2C_MONRXDAT_MONRXDAT(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRXDAT_SHIFT)) & I2C_MONRXDAT_MONRXDAT_MASK)
+#define I2C_MONRXDAT_MONSTART_MASK               (0x100U)
+#define I2C_MONRXDAT_MONSTART_SHIFT              (8U)
+/*! MONSTART - Monitor Received Start. 0: No start detected. The monitor function has not detected a
+ *    Start event on the I2C bus. 1: Start detected. The Monitor function has detected a Start
+ *    event on the I2C bus.
+ */
+#define I2C_MONRXDAT_MONSTART(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONSTART_SHIFT)) & I2C_MONRXDAT_MONSTART_MASK)
+#define I2C_MONRXDAT_MONRESTART_MASK             (0x200U)
+#define I2C_MONRXDAT_MONRESTART_SHIFT            (9U)
+/*! MONRESTART - Monitor Received Repeated Start. 0: No repeated start detected. The Monitor
+ *    function has not detected a Repeated Start event on the I2C bus. 1: Repeate start detected. The
+ *    Monitor function has detected a Repeated Start event on the I2C bus.
+ */
+#define I2C_MONRXDAT_MONRESTART(x)               (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRESTART_SHIFT)) & I2C_MONRXDAT_MONRESTART_MASK)
+#define I2C_MONRXDAT_MONNACK_MASK                (0x400U)
+#define I2C_MONRXDAT_MONNACK_SHIFT               (10U)
+/*! MONNACK - Monitor Received NACK. 0: Acknowledged. The data currently being provided by the
+ *    Monitor function was acknowledged by at least one master or slave recevier. 1: Not Acknowledged.
+ *    The data currently being provided by the Monitor function was not acknowledged by any receiver.
+ */
+#define I2C_MONRXDAT_MONNACK(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONNACK_SHIFT)) & I2C_MONRXDAT_MONNACK_MASK)
+/*! @} */
+
+/*! @name ID - I2C Module Identifier */
+/*! @{ */
+#define I2C_ID_APERTURE_MASK                     (0xFFU)
+#define I2C_ID_APERTURE_SHIFT                    (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define I2C_ID_APERTURE(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_ID_APERTURE_SHIFT)) & I2C_ID_APERTURE_MASK)
+#define I2C_ID_MIN_REV_MASK                      (0xF00U)
+#define I2C_ID_MIN_REV_SHIFT                     (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define I2C_ID_MIN_REV(x)                        (((uint32_t)(((uint32_t)(x)) << I2C_ID_MIN_REV_SHIFT)) & I2C_ID_MIN_REV_MASK)
+#define I2C_ID_MAJ_REV_MASK                      (0xF000U)
+#define I2C_ID_MAJ_REV_SHIFT                     (12U)
+/*! MAJ_REV - Major revision i.e. there may be software incompatability between major revisions.
+ */
+#define I2C_ID_MAJ_REV(x)                        (((uint32_t)(((uint32_t)(x)) << I2C_ID_MAJ_REV_SHIFT)) & I2C_ID_MAJ_REV_MASK)
+#define I2C_ID_ID_MASK                           (0xFFFF0000U)
+#define I2C_ID_ID_SHIFT                          (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define I2C_ID_ID(x)                             (((uint32_t)(((uint32_t)(x)) << I2C_ID_ID_SHIFT)) & I2C_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group I2C_Register_Masks */
+
+
+/* I2C - Peripheral instance base addresses */
+/** Peripheral I2C0 base address */
+#define I2C0_BASE                                (0x40003000u)
+/** Peripheral I2C0 base pointer */
+#define I2C0                                     ((I2C_Type *)I2C0_BASE)
+/** Peripheral I2C1 base address */
+#define I2C1_BASE                                (0x40004000u)
+/** Peripheral I2C1 base pointer */
+#define I2C1                                     ((I2C_Type *)I2C1_BASE)
+/** Peripheral I2C2 base address */
+#define I2C2_BASE                                (0x40005000u)
+/** Peripheral I2C2 base pointer */
+#define I2C2                                     ((I2C_Type *)I2C2_BASE)
+/** Array initializer of I2C peripheral base addresses */
+#define I2C_BASE_ADDRS                           { I2C0_BASE, I2C1_BASE, I2C2_BASE }
+/** Array initializer of I2C peripheral base pointers */
+#define I2C_BASE_PTRS                            { I2C0, I2C1, I2C2 }
+/** Interrupt vectors for the I2C peripheral type */
+#define I2C_IRQS                                 { FLEXCOMM2_IRQn, FLEXCOMM3_IRQn, FLEXCOMM6_IRQn }
+
+/*!
+ * @}
+ */ /* end of group I2C_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- INPUTMUX Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup INPUTMUX_Peripheral_Access_Layer INPUTMUX Peripheral Access Layer
+ * @{
+ */
+
+/** INPUTMUX - Register Layout Typedef */
+typedef struct {
+       uint8_t RESERVED_0[192];
+  __IO uint32_t PINTSEL[8];                        /**< Pin interrupt select register, array offset: 0xC0, array step: 0x4 */
+  __IO uint32_t DMA_ITRIG_INMUX[19];               /**< Trigger select register for DMA channel. Configurable for each of the DMA channels., array offset: 0xE0, array step: 0x4 */
+       uint8_t RESERVED_1[52];
+  __IO uint32_t DMA_OTRIG_INMUX[4];                /**< DMA output trigger selection to become an input to the DMA trigger mux. Four selections can be made., array offset: 0x160, array step: 0x4 */
+       uint8_t RESERVED_2[16];
+  __IO uint32_t FREQMEAS_REF;                      /**< Selection for frequency measurement reference clock, offset: 0x180 */
+  __IO uint32_t FREQMEAS_TARGET;                   /**< Selection for frequency measurement target clock, offset: 0x184 */
+} INPUTMUX_Type;
+
+/* ----------------------------------------------------------------------------
+   -- INPUTMUX Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup INPUTMUX_Register_Masks INPUTMUX Register Masks
+ * @{
+ */
+
+/*! @name PINTSEL - Pin interrupt select register */
+/*! @{ */
+#define INPUTMUX_PINTSEL_INTPIN_MASK             (0x1FU)
+#define INPUTMUX_PINTSEL_INTPIN_SHIFT            (0U)
+/*! INTPIN - Pin number select for pin interrupt or pattern match engine input.
+ */
+#define INPUTMUX_PINTSEL_INTPIN(x)               (((uint32_t)(((uint32_t)(x)) << INPUTMUX_PINTSEL_INTPIN_SHIFT)) & INPUTMUX_PINTSEL_INTPIN_MASK)
+/*! @} */
+
+/* The count of INPUTMUX_PINTSEL */
+#define INPUTMUX_PINTSEL_COUNT                   (8U)
+
+/*! @name DMA_ITRIG_INMUX - Trigger select register for DMA channel. Configurable for each of the DMA channels. */
+/*! @{ */
+#define INPUTMUX_DMA_ITRIG_INMUX_INP_MASK        (0x1FU)
+#define INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT       (0U)
+/*! INP - Trigger input number (decimal value) for DMA channel n (n = 0 to 17). 0: ADC0 Sequence A
+ *    interrupt; 1: ADC0 Sequence B interrupt; 2: Timer CT32B0 Match 0; 3: Timer CT32B0 Match 1; 4:
+ *    Timer CT32B1 Match 0; 5: Timer CT32B1 Match 1; 6: Pin interrupt 0; 7: Pin interrupt 1; 8: Pin
+ *    interrupt 2; 9: Pin interrupt 3; 10: AES RX; 11: AES TX; 12: Hash RX; 13: Hash TX; 14: DMA
+ *    output trigger mux 0; 15: DMA output trigger mux 1; 16: DMA output trigger mux 2; 17: DMA output
+ *    trigger mux 3; 18- 31: reserved.
+ */
+#define INPUTMUX_DMA_ITRIG_INMUX_INP(x)          (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_ITRIG_INMUX_INP_MASK)
+/*! @} */
+
+/* The count of INPUTMUX_DMA_ITRIG_INMUX */
+#define INPUTMUX_DMA_ITRIG_INMUX_COUNT           (19U)
+
+/*! @name DMA_OTRIG_INMUX - DMA output trigger selection to become an input to the DMA trigger mux. Four selections can be made. */
+/*! @{ */
+#define INPUTMUX_DMA_OTRIG_INMUX_INP_MASK        (0x1FU)
+#define INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT       (0U)
+/*! INP - DMA trigger output number (decimal value) for DMA channel n (n = 0 to 19).
+ */
+#define INPUTMUX_DMA_OTRIG_INMUX_INP(x)          (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_OTRIG_INMUX_INP_MASK)
+/*! @} */
+
+/* The count of INPUTMUX_DMA_OTRIG_INMUX */
+#define INPUTMUX_DMA_OTRIG_INMUX_COUNT           (4U)
+
+/*! @name FREQMEAS_REF - Selection for frequency measurement reference clock */
+/*! @{ */
+#define INPUTMUX_FREQMEAS_REF_CLKIN_MASK         (0xFU)
+#define INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT        (0U)
+/*! CLKIN - Clock source number (decimal value) for frequency measure function ref clock: 0: CLK_IN
+ *    (must be enabled in functional mux); 1: XTAL 32 MHz (must be enabled in clock_ctrl); 2: FRO 1
+ *    MHz (must be enabled in clock_ctrl); 3: 32 kHz oscillator (either FRO 32 KHz or XTAL 32 KHZ);
+ *    4: Main clock (divided); 5: PIO[4] (must be configured as GPIO); 6: PIO[20] (must be
+ *    configured as GPIO); 7: PIO[16] (must be configured as GPIO); 8: PIO[15] (must be configured as GPIO);
+ *    9 - 15: reserved.
+ */
+#define INPUTMUX_FREQMEAS_REF_CLKIN(x)           (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_REF_CLKIN_MASK)
+/*! @} */
+
+/*! @name FREQMEAS_TARGET - Selection for frequency measurement target clock */
+/*! @{ */
+#define INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK      (0xFU)
+#define INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT     (0U)
+/*! CLKIN - Clock source number (decimal value) for frequency measure function target clock: 0:
+ *    CLK_IN (must be enabled in functional mux); 1: XTAL 32 MHz (must be enabled in clock_ctrl); 2: FRO
+ *    1 MHz (must be enabled in clock_ctrl); 3: 32 kHz oscillator (either FRO 32 KHz or XTAL 32
+ *    KHZ); 4: Main clock (divided); 5: PIO[4] (must be configured as GPIO); 6: PIO[20] (must be
+ *    configured as GPIO); 7: PIO[16] (must be configured as GPIO); 8: PIO[15] (must be configured as
+ *    GPIO); 9 - 15: reserved.
+ */
+#define INPUTMUX_FREQMEAS_TARGET_CLKIN(x)        (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group INPUTMUX_Register_Masks */
+
+
+/* INPUTMUX - Peripheral instance base addresses */
+/** Peripheral INPUTMUX base address */
+#define INPUTMUX_BASE                            (0x4000E000u)
+/** Peripheral INPUTMUX base pointer */
+#define INPUTMUX                                 ((INPUTMUX_Type *)INPUTMUX_BASE)
+/** Array initializer of INPUTMUX peripheral base addresses */
+#define INPUTMUX_BASE_ADDRS                      { INPUTMUX_BASE }
+/** Array initializer of INPUTMUX peripheral base pointers */
+#define INPUTMUX_BASE_PTRS                       { INPUTMUX }
+
+/*!
+ * @}
+ */ /* end of group INPUTMUX_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- IOCON Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup IOCON_Peripheral_Access_Layer IOCON Peripheral Access Layer
+ * @{
+ */
+
+/** IOCON - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t PIO[1][22];                        /**< Configuration array for PIO0 to PIO21. PIO[10] and PIO[11] use a different IO cell type to the other PIO pins and so there are some differences in the bit field descriptions of the PIO register for these Ios. Reset values vary depending on whether the IO is configured with a pull-up or pull-down resistor as default. The value is also affected by the IO type. Reset value 0x180 for PIO 0,3,4,5,8,9,12,13,14,15,16,21. Reset value 0x198 for PIO 1,2,6,7,17,18,19,20. Reset value 0x188 for PIO 10,11., array offset: 0x0, array step: index*0x58, index2*0x4 */
+} IOCON_Type;
+
+/* ----------------------------------------------------------------------------
+   -- IOCON Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup IOCON_Register_Masks IOCON Register Masks
+ * @{
+ */
+
+/*! @name PIO - Configuration array for PIO0 to PIO21. PIO[10] and PIO[11] use a different IO cell type to the other PIO pins and so there are some differences in the bit field descriptions of the PIO register for these Ios. Reset values vary depending on whether the IO is configured with a pull-up or pull-down resistor as default. The value is also affected by the IO type. Reset value 0x180 for PIO 0,3,4,5,8,9,12,13,14,15,16,21. Reset value 0x198 for PIO 1,2,6,7,17,18,19,20. Reset value 0x188 for PIO 10,11. */
+/*! @{ */
+#define IOCON_PIO_FUNC_MASK                      (0x7U)
+#define IOCON_PIO_FUNC_SHIFT                     (0U)
+/*! FUNC - Select digital function assigned to this pin.
+ *  0b000..Alternative connection 0.
+ *  0b001..Alternative connection 1.
+ *  0b010..Alternative connection 2.
+ *  0b011..Alternative connection 3.
+ *  0b100..Alternative connection 4.
+ *  0b101..Alternative connection 5.
+ *  0b110..Alternative connection 6.
+ *  0b111..Alternative connection 7.
+ */
+#define IOCON_PIO_FUNC(x)                        (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FUNC_SHIFT)) & IOCON_PIO_FUNC_MASK)
+#define IOCON_PIO_EGP_MASK                       (0x8U)
+#define IOCON_PIO_EGP_SHIFT                      (3U)
+/*! EGP - GPIO Mode of IO Cell.
+ *  0b0..IIC mode.
+ *  0b1..GPIO mode.
+ */
+#define IOCON_PIO_EGP(x)                         (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_EGP_SHIFT)) & IOCON_PIO_EGP_MASK)
+#define IOCON_PIO_MODE_MASK                      (0x18U)
+#define IOCON_PIO_MODE_SHIFT                     (3U)
+/*! MODE - Select function mode (on-chip pull-up/pull-down resistor control). For MFIO type ONLY
+ *    (all PIOs except PIO10 & 11): 0x0 : Pull-up. Pull-up resistor enabled. 0x1 : Repeater mode (bus
+ *    keeper) 0x2 : Plain Input 0x3 : Pull-down. Pull-down resistor enabled. Note: When the register
+ *    is related to a general purpose MFIO type pad (that is all PIOs except PIO10 & 11) - Bit [3]
+ *    (of the register) is connected to EPD (enable pull-down) input of the MFIO pad. - Bit [4] (of
+ *    the register) is connected to EPUN (enable pull-up NOT) input of MFIO pad.
+ *  0b00..Pull-up. Pull-up resistor enabled.
+ *  0b01..Repeater. Repeater mode (bus keeper).
+ *  0b10..Inactive. Plain Input.
+ *  0b11..Pull-down. Pull-down resistor enabled.
+ */
+#define IOCON_PIO_MODE(x)                        (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_MODE_SHIFT)) & IOCON_PIO_MODE_MASK)
+#define IOCON_PIO_ECS_MASK                       (0x10U)
+#define IOCON_PIO_ECS_SHIFT                      (4U)
+/*! ECS - Pull-up current source enable when set. When IO is is IIC mode (EGP=0) and ECS is low, the
+ *    IO cell is an open drain cell.
+ *  0b0..Pull-up current source disabled.
+ *  0b1..Pull-up current source enabled.
+ */
+#define IOCON_PIO_ECS(x)                         (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_ECS_SHIFT)) & IOCON_PIO_ECS_MASK)
+#define IOCON_PIO_EHS_MASK                       (0x20U)
+#define IOCON_PIO_EHS_SHIFT                      (5U)
+/*! EHS - Speed selection bit. When IO is in GPIO mode set high for high speed GPIO, low for low
+ *    speed GPIO. For IIC mode this bit has no effect and the IO is always in low speed.
+ *  0b0..low speed for GPIO mode or i2c mode.
+ *  0b1..High speed for GPIO mode.
+ */
+#define IOCON_PIO_EHS(x)                         (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_EHS_SHIFT)) & IOCON_PIO_EHS_MASK)
+#define IOCON_PIO_SLEW0_MASK                     (0x20U)
+#define IOCON_PIO_SLEW0_SHIFT                    (5U)
+/*! SLEW0 - This bit field is used in combination with SLEW1. The higher [SLEW1,SLEW0] the quicker the IO cell slew rate.
+ *  0b0..Driver slew0 rate is disabled.
+ *  0b1..Driver slew0 rate is enabled.
+ */
+#define IOCON_PIO_SLEW0(x)                       (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SLEW0_SHIFT)) & IOCON_PIO_SLEW0_MASK)
+#define IOCON_PIO_INVERT_MASK                    (0x40U)
+#define IOCON_PIO_INVERT_SHIFT                   (6U)
+/*! INVERT - Input polarity.
+ *  0b0..Disabled. Input function is not inverted.
+ *  0b1..Enabled. Input is function inverted.
+ */
+#define IOCON_PIO_INVERT(x)                      (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_INVERT_SHIFT)) & IOCON_PIO_INVERT_MASK)
+#define IOCON_PIO_DIGIMODE_MASK                  (0x80U)
+#define IOCON_PIO_DIGIMODE_SHIFT                 (7U)
+/*! DIGIMODE - Select Analog/Digital mode. 0 Analog mode. 1 Digital mode. When in analog mode, the
+ *    receiver path in the IO cell is disabled. In this mode, it is essential that the digital
+ *    function (e.g. GPIO) is not configured as an output. Otherwise it may conflict with analog stuff
+ *    (loopback of digital on analog input). In other words, the digital output is not automatically
+ *    disabled when the IO is in analog mode. As a consequence, it is not possible to disable the
+ *    receiver path when the IO is used for digital output purpose.
+ *  0b0..Analog mode, digital input is disabled.
+ *  0b1..Digital mode, digital input is enabled.
+ */
+#define IOCON_PIO_DIGIMODE(x)                    (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DIGIMODE_SHIFT)) & IOCON_PIO_DIGIMODE_MASK)
+#define IOCON_PIO_FILTEROFF_MASK                 (0x100U)
+#define IOCON_PIO_FILTEROFF_SHIFT                (8U)
+/*! FILTEROFF - Controls input glitch filter.
+ *  0b0..Filter enabled. Noise pulses below approximately 10 ns are filtered out.
+ *  0b1..Filter disabled. No input filtering is done.
+ */
+#define IOCON_PIO_FILTEROFF(x)                   (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FILTEROFF_SHIFT)) & IOCON_PIO_FILTEROFF_MASK)
+#define IOCON_PIO_FSEL_MASK                      (0x200U)
+#define IOCON_PIO_FSEL_SHIFT                     (9U)
+/*! FSEL - Control Input Glitch Filter.
+ *  0b0..In IIC mode: Noise pulses below approximately 50ns are filtered out. In GPIO mode: A 3ns filter is used.
+ *  0b1..In IIC mode: Noise pulses below approximately 10ns are filtered out. In GPIO mode: A 3ns filter is used.
+ */
+#define IOCON_PIO_FSEL(x)                        (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FSEL_SHIFT)) & IOCON_PIO_FSEL_MASK)
+#define IOCON_PIO_SLEW1_MASK                     (0x200U)
+#define IOCON_PIO_SLEW1_SHIFT                    (9U)
+/*! SLEW1 - Driver Slew Rate. This bit is used in combination with SLEW0. The higher [SLEW1,SLEW0], the quicker the slew rate.
+ *  0b0..Driver slew1 rate is disabled.
+ *  0b1..Driver slew1 rate is enabled.
+ */
+#define IOCON_PIO_SLEW1(x)                       (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SLEW1_SHIFT)) & IOCON_PIO_SLEW1_MASK)
+#define IOCON_PIO_OD_MASK                        (0x400U)
+#define IOCON_PIO_OD_SHIFT                       (10U)
+/*! OD - Controls open-drain mode.
+ *  0b0..Normal. Normal push-pull output
+ *  0b1..Open-drain. Simulated open-drain output (high drive disabled).
+ */
+#define IOCON_PIO_OD(x)                          (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_OD_SHIFT)) & IOCON_PIO_OD_MASK)
+#define IOCON_PIO_SSEL_MASK                      (0x800U)
+#define IOCON_PIO_SSEL_SHIFT                     (11U)
+/*! SSEL - This bit controls the IO clamping function.
+ *  0b0..This bit controls the IO clamping function is disabled.
+ *  0b1..This bit controls the IO clamping function is enabled.
+ */
+#define IOCON_PIO_SSEL(x)                        (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SSEL_SHIFT)) & IOCON_PIO_SSEL_MASK)
+#define IOCON_PIO_IO_CLAMP_MASK                  (0x1000U)
+#define IOCON_PIO_IO_CLAMP_SHIFT                 (12U)
+/*! IO_CLAMP - Assert to freeze the IO. Also needs SYSCON:RETENTIONCTRL set as well. Useful in power
+ *    down mode. This mode is held through power down cycle. Before releasing this mode on a
+ *    wake-up, ensure the IO is set to the required direction and value using GPIO DIR and PIN registers.
+ *  0b0..IO_CLAMP is disabled.
+ *  0b1..IO_CLAMP is enabled.
+ */
+#define IOCON_PIO_IO_CLAMP(x)                    (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_IO_CLAMP_SHIFT)) & IOCON_PIO_IO_CLAMP_MASK)
+/*! @} */
+
+/* The count of IOCON_PIO */
+#define IOCON_PIO_COUNT                          (1U)
+
+/* The count of IOCON_PIO */
+#define IOCON_PIO_COUNT2                         (22U)
+
+
+/*!
+ * @}
+ */ /* end of group IOCON_Register_Masks */
+
+
+/* IOCON - Peripheral instance base addresses */
+/** Peripheral IOCON base address */
+#define IOCON_BASE                               (0x4000F000u)
+/** Peripheral IOCON base pointer */
+#define IOCON                                    ((IOCON_Type *)IOCON_BASE)
+/** Array initializer of IOCON peripheral base addresses */
+#define IOCON_BASE_ADDRS                         { IOCON_BASE }
+/** Array initializer of IOCON peripheral base pointers */
+#define IOCON_BASE_PTRS                          { IOCON }
+
+/*!
+ * @}
+ */ /* end of group IOCON_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- ISO7816 Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ISO7816_Peripheral_Access_Layer ISO7816 Peripheral Access Layer
+ * @{
+ */
+
+/** ISO7816 - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t SSR;                               /**< Slot Select Register, offset: 0x0 */
+  __IO uint32_t PDR1_LSB;                          /**< Programmable Divider Register (LSB) slot 1. Least significant byte of a 16-bit counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock, this defines the ETU. The minimum acceptable value is 0001 0000b., offset: 0x4 */
+  __IO uint32_t PDR1_MSB;                          /**< Programmable Divider Register (MSB) slot 1. Most significant byte of a 16-bit counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock, this defines the ETU, offset: 0x8 */
+  __IO uint32_t FCR;                               /**< FIFO Control Register, offset: 0xC */
+  __IO uint32_t GTR1;                              /**< Guard Time Register slot 1. Value used by the Contact UART notably in transmission mode. The Contact UART will wait this number of ETUs before transmitting the character. In protocol T=1, gtr = FFh means operation at 11 ETUs. In protocol T=0, gtr = FFh means operation at 12 ETUs., offset: 0x10 */
+  __IO uint32_t UCR11;                             /**< UART Configuration Register 1 slot 1, offset: 0x14 */
+  __IO uint32_t UCR21;                             /**< UART Configuration Register 2 slot 1, offset: 0x18 */
+  __IO uint32_t CCR1;                              /**< Clock Configuration Register slot 1, offset: 0x1C */
+  __IO uint32_t PCR;                               /**< Power Control Register, offset: 0x20 */
+  __IO uint32_t ECR;                               /**< Early answer Counter register, offset: 0x24 */
+  __IO uint32_t MCRL_LSB;                          /**< Mute card Counter RST Low register (LSB), offset: 0x28 */
+  __IO uint32_t MCRL_MSB;                          /**< Mute card Counter RST Low register (MSB), offset: 0x2C */
+  __IO uint32_t MCRH_LSB;                          /**< Mute card Counter RST High register (LSB), offset: 0x30 */
+  __IO uint32_t MCRH_MSB;                          /**< Mute card Counter RST High register (MSB), offset: 0x34 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t URR_UTR;                           /**< UART Receive Register / UART Transmit Register, offset: 0x3C */
+       uint8_t RESERVED_1[12];
+  __O  uint32_t TOR1;                              /**< Time-Out Register 1, offset: 0x4C */
+  __O  uint32_t TOR2;                              /**< Time-Out Register 2, offset: 0x50 */
+  __O  uint32_t TOR3;                              /**< Time-Out Register 3, offset: 0x54 */
+  __IO uint32_t TOC;                               /**< Time-Out Configuration register, offset: 0x58 */
+  __I  uint32_t FSR;                               /**< FIFO Status Register, offset: 0x5C */
+  __I  uint32_t MSR;                               /**< Mixed Status Register, offset: 0x60 */
+  __I  uint32_t USR1;                              /**< UART Status Register 1, offset: 0x64 */
+  __I  uint32_t USR2;                              /**< UART Status Register 2, offset: 0x68 */
+} ISO7816_Type;
+
+/* ----------------------------------------------------------------------------
+   -- ISO7816 Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ISO7816_Register_Masks ISO7816 Register Masks
+ * @{
+ */
+
+/*! @name SSR - Slot Select Register */
+/*! @{ */
+#define ISO7816_SSR_SOFTRESETN_MASK              (0x1U)
+#define ISO7816_SSR_SOFTRESETN_SHIFT             (0U)
+/*! SOFTRESETN - When set to logic 0 this bit resets the whole Contact UART (software reset), sets
+ *    to logic 1 automatically by hardware after after one clock cycle if slot 1 is not activated
+ *    else after one clock cycle after slot 1 has been automatically deactivated. Software should check
+ *    soft reset is finished by reading SSR register before any further action.
+ */
+#define ISO7816_SSR_SOFTRESETN(x)                (((uint32_t)(((uint32_t)(x)) << ISO7816_SSR_SOFTRESETN_SHIFT)) & ISO7816_SSR_SOFTRESETN_MASK)
+#define ISO7816_SSR_SEQ_EN_MASK                  (0x2U)
+#define ISO7816_SSR_SEQ_EN_SHIFT                 (1U)
+/*! SEQ_EN - Set this bit to enable the sequencer. If this field is 0b, the sequencer will not respond to the Start control bit.
+ */
+#define ISO7816_SSR_SEQ_EN(x)                    (((uint32_t)(((uint32_t)(x)) << ISO7816_SSR_SEQ_EN_SHIFT)) & ISO7816_SSR_SEQ_EN_MASK)
+/*! @} */
+
+/*! @name PDR1_LSB - Programmable Divider Register (LSB) slot 1. Least significant byte of a 16-bit counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock, this defines the ETU. The minimum acceptable value is 0001 0000b. */
+/*! @{ */
+#define ISO7816_PDR1_LSB_PDR1_LSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_PDR1_LSB_PDR1_LSB_SHIFT          (0U)
+/*! PDR1_LSB - Programmable Divider Register (LSB) slot 1. Least significant byte of a 16-bit
+ *    counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock,
+ *    this defines the ETU. The minimum acceptable value is 0001 0000b.
+ */
+#define ISO7816_PDR1_LSB_PDR1_LSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_PDR1_LSB_PDR1_LSB_SHIFT)) & ISO7816_PDR1_LSB_PDR1_LSB_MASK)
+/*! @} */
+
+/*! @name PDR1_MSB - Programmable Divider Register (MSB) slot 1. Most significant byte of a 16-bit counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock, this defines the ETU */
+/*! @{ */
+#define ISO7816_PDR1_MSB_PDR1_MSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_PDR1_MSB_PDR1_MSB_SHIFT          (0U)
+/*! PDR1_MSB - Programmable Divider Register (MSB) slot 1. Most significant byte of a 16-bit counter
+ *    defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock,
+ *    this defines the ETU
+ */
+#define ISO7816_PDR1_MSB_PDR1_MSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_PDR1_MSB_PDR1_MSB_SHIFT)) & ISO7816_PDR1_MSB_PDR1_MSB_MASK)
+/*! @} */
+
+/*! @name FCR - FIFO Control Register */
+/*! @{ */
+#define ISO7816_FCR_FTC_MASK                     (0x1FU)
+#define ISO7816_FCR_FTC_SHIFT                    (0U)
+/*! FTC - FIFO Threshold Configuration: Define the number of received or transmitted characters in
+ *    the FIFO triggering the ft bit in USR1. The FIFO depth is 32 bytes. In reception mode, it
+ *    enables to know that a number equals to ftc(4:0) + 1 bytes have been received. In transmission
+ *    mode, ftc(4:0) equals to the number of remaining bytes into the FIFO. Be careful: in reception
+ *    mode 00000 = length 1, and in transmission mode 00000 = length 0.
+ */
+#define ISO7816_FCR_FTC(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_FCR_FTC_SHIFT)) & ISO7816_FCR_FTC_MASK)
+#define ISO7816_FCR_PEC_MASK                     (0xE0U)
+#define ISO7816_FCR_PEC_SHIFT                    (5U)
+/*! PEC - Parity Error Count [For protocol T = 0] Set the number of allowed repetitions in reception
+ *    or transmission mode before setting pe in ct_usr1_reg. The value 000 indicates that, if only
+ *    one parity error has occurred, bit pe is set at logic 1; the value 111 indicates that bit pe
+ *    will be set at logic 1 after 8 parity errors. If a correct character is received before the
+ *    programmed error number is reached, the error counter will be reset. If the programmed number of
+ *    allowed parity errors is reached, bit pe in register ct_usr1_reg will be set at logic 1. If a
+ *    transmitted character has been naked by the card, then the Contact UART will automatically
+ *    retransmit it up to a number of times equal to the value programmed in bits PEC(2:0); the
+ *    character will be resent at 15 ETU. If a transmitted character is considered as correct by the card
+ *    after having been naked a number of times less than the value programmed in bits PEC(2:0) +1,
+ *    the error counter will be reset. If a transmitted has been naked by the card a number of times
+ *    equal to the value programmed in bits PEC(2:0) +1, the transmission stops and bit pe in
+ *    register ct_usr1_reg is set at logic 1. The firmware is supposed to deactivate the card. If not, the
+ *    firmware has the possibility to pursue the transmission. By reading the number of bytes
+ *    present into the FIFO (ffl bits), it can determine which character has been naked PEC +1 times by
+ *    the card. It will then flush the FIFO (FIFO flush bit). The next step consits in unlocking the
+ *    transmission using dispe bit. By writing this bit at logic level one (and then at logic level
+ *    zero if the firmware still wants to check parity errors), the transmission is unlocked. The
+ *    firmware can now write bytes into the FIFO. In transmission mode, if bits PEC(2:0) are at logic
+ *    0, then the automatic retransmission is invalidated. There is no retransmission; the
+ *    transmission continues with the next character sent at 13 ETU. [For protocol T = 1]: The error counter
+ *    has no action: bit pe is set at logic 1 at the first wrong received character.
+ */
+#define ISO7816_FCR_PEC(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_FCR_PEC_SHIFT)) & ISO7816_FCR_PEC_MASK)
+/*! @} */
+
+/*! @name GTR1 - Guard Time Register slot 1. Value used by the Contact UART notably in transmission mode. The Contact UART will wait this number of ETUs before transmitting the character. In protocol T=1, gtr = FFh means operation at 11 ETUs. In protocol T=0, gtr = FFh means operation at 12 ETUs. */
+/*! @{ */
+#define ISO7816_GTR1_GTR1_MASK                   (0xFFFFFFFFU)
+#define ISO7816_GTR1_GTR1_SHIFT                  (0U)
+/*! GTR1 - Guard Time Register slot 1. Value used by the Contact UART notably in transmission mode.
+ *    The Contact UART will wait this number of ETUs before transmitting the character. In protocol
+ *    T=1, gtr = FFh means operation at 11 ETUs. In protocol T=0, gtr = FFh means operation at 12
+ *    ETUs.
+ */
+#define ISO7816_GTR1_GTR1(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_GTR1_GTR1_SHIFT)) & ISO7816_GTR1_GTR1_MASK)
+/*! @} */
+
+/*! @name UCR11 - UART Configuration Register 1 slot 1 */
+/*! @{ */
+#define ISO7816_UCR11_CONV_MASK                  (0x1U)
+#define ISO7816_UCR11_CONV_SHIFT                 (0U)
+/*! CONV - CONVention: Bit CONV is set to logic 1 if the convention is direct. Bit CONV is either
+ *    automatically written by hardware according to the convention detected during ATR, or by
+ *    software if the bit AUTOCONV in register ct_ucr1_reg is set to logic 1.
+ */
+#define ISO7816_UCR11_CONV(x)                    (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_CONV_SHIFT)) & ISO7816_UCR11_CONV_MASK)
+#define ISO7816_UCR11_LCT_MASK                   (0x2U)
+#define ISO7816_UCR11_LCT_SHIFT                  (1U)
+/*! LCT - Last Character to Transmit: Bit LCT is set to logic 1 by software before writing the last
+ *    character to be transmitted in register ct_utr_reg. It allows automatic change to reception
+ *    mode. It is reset to logic 0 by hardware at the end of a successful transmission after 11.75
+ *    ETUs in protocol T = 0 and after 10.75 ETUs in protocol T = 1. When bit LCT is being reset to
+ *    logic 0, bit T/R is also reset to logic 0 and the UART is ready to receive a character. LCT bit
+ *    can be set to logic 1 by software not only when writing the last character to be transmitted
+ *    but also during the transmission or even at the beginning of the transmission. It will be taken
+ *    into account when the FIFO becomes empty, which implies for the software to be able to
+ *    regularly re-load the FIFO when transmitting more than 32 bytes to ensure there is at least one byte
+ *    into the FIFO as long as the transmission is not finished. Else, a switch to reception mode
+ *    will prematurely occur before having transmitted all the bytes.
+ */
+#define ISO7816_UCR11_LCT(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_LCT_SHIFT)) & ISO7816_UCR11_LCT_MASK)
+#define ISO7816_UCR11_T_R_MASK                   (0x4U)
+#define ISO7816_UCR11_T_R_SHIFT                  (2U)
+/*! T_R - Transmit/Receive: Defines the mode: logic 1 means transmission and logic 0 reception. Bit
+ *    T/R is set by software for transmission mode. Bit T/R is automatically reset to logic 0 by
+ *    hardware, if bit LCT has been used before transmitting the last character. Note that when
+ *    switching from/to reception to/from transmission mode, the FIFO is flushed. Any remaining bytes are
+ *    lost.
+ */
+#define ISO7816_UCR11_T_R(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_T_R_SHIFT)) & ISO7816_UCR11_T_R_MASK)
+#define ISO7816_UCR11_PROT_MASK                  (0x8U)
+#define ISO7816_UCR11_PROT_SHIFT                 (3U)
+/*! PROT - PROTocol: Selects the protocol: logic 1 means T=1 and logic 0 T=0.
+ */
+#define ISO7816_UCR11_PROT(x)                    (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_PROT_SHIFT)) & ISO7816_UCR11_PROT_MASK)
+#define ISO7816_UCR11_FC_MASK                    (0x10U)
+#define ISO7816_UCR11_FC_SHIFT                   (4U)
+/*! FC - Described in a separated document.
+ */
+#define ISO7816_UCR11_FC(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_FC_SHIFT)) & ISO7816_UCR11_FC_MASK)
+#define ISO7816_UCR11_FIP_MASK                   (0x20U)
+#define ISO7816_UCR11_FIP_SHIFT                  (5U)
+/*! FIP - Force Inverse Parity: If bit FIP is set to logic 1, the Contact UART will NAK a correctly
+ *    received character, and will transmit characters with wrong parity bits.
+ */
+#define ISO7816_UCR11_FIP(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_FIP_SHIFT)) & ISO7816_UCR11_FIP_MASK)
+/*! @} */
+
+/*! @name UCR21 - UART Configuration Register 2 slot 1 */
+/*! @{ */
+#define ISO7816_UCR21_AUTOCONVN_MASK             (0x1U)
+#define ISO7816_UCR21_AUTOCONVN_SHIFT            (0U)
+/*! AUTOCONVN - AUTOmatically detected CONVention: If bit AUTOCONV = 1, then the convention is set
+ *    by software using bit CONV in register ct_ucr1_reg. If the bit is reset to logic 0, then the
+ *    configuration is automatically detected on the first received character and the bit
+ *    automatically set after convention detection.
+ */
+#define ISO7816_UCR21_AUTOCONVN(x)               (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_AUTOCONVN_SHIFT)) & ISO7816_UCR21_AUTOCONVN_MASK)
+#define ISO7816_UCR21_MANBGT_MASK                (0x2U)
+#define ISO7816_UCR21_MANBGT_SHIFT               (1U)
+/*! MANBGT - MANual BGT: When set to logic 1, BGT is managed by software, else by hardware.
+ */
+#define ISO7816_UCR21_MANBGT(x)                  (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_MANBGT_SHIFT)) & ISO7816_UCR21_MANBGT_MASK)
+#define ISO7816_UCR21_DISFT_MASK                 (0x4U)
+#define ISO7816_UCR21_DISFT_SHIFT                (2U)
+/*! DISFT - DISable Fifo Threshold interrupt bit: When set to logic 1 the bit ft in register
+ *    ct_usr1_reg will not generate interrupt.
+ */
+#define ISO7816_UCR21_DISFT(x)                   (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_DISFT_SHIFT)) & ISO7816_UCR21_DISFT_MASK)
+#define ISO7816_UCR21_DISPE_MASK                 (0x8U)
+#define ISO7816_UCR21_DISPE_SHIFT                (3U)
+/*! DISPE - DISable Parity Error interrupt bit: When set to logic 1, the parity is not checked in
+ *    both reception and transmission modes, the bit pe in register ct_usr1_reg will not generate
+ *    interrupt.
+ */
+#define ISO7816_UCR21_DISPE(x)                   (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_DISPE_SHIFT)) & ISO7816_UCR21_DISPE_MASK)
+#define ISO7816_UCR21_DISATRCOUNTER_MASK         (0x10U)
+#define ISO7816_UCR21_DISATRCOUNTER_SHIFT        (4U)
+/*! DISATRCOUNTER - DISable ATR counter: [For Slot 1 only] When set to logic 1 the bits EARLY and
+ *    MUTE in register ct_usr1_reg will not generate interrupt. This bit should be set before
+ *    activating.
+ */
+#define ISO7816_UCR21_DISATRCOUNTER(x)           (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_DISATRCOUNTER_SHIFT)) & ISO7816_UCR21_DISATRCOUNTER_MASK)
+#define ISO7816_UCR21_FIFOFLUSH_MASK             (0x40U)
+#define ISO7816_UCR21_FIFOFLUSH_SHIFT            (6U)
+/*! FIFOFLUSH - FIFO flush: When set to logic 1, the FIFO is flushed whatever the mode (reception or
+ *    transmission) is. It can be used before any reception or transmission of characters but not
+ *    while receiving or transmitting a character. It is reset to logic 0 by hardware after one
+ *    clk_ip cycle.
+ */
+#define ISO7816_UCR21_FIFOFLUSH(x)               (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_FIFOFLUSH_SHIFT)) & ISO7816_UCR21_FIFOFLUSH_MASK)
+#define ISO7816_UCR21_WRDACC_MASK                (0x80U)
+#define ISO7816_UCR21_WRDACC_SHIFT               (7U)
+/*! WRDACC - FIFO WoRD ACCess: When set to logic 1, the FIFO supports word (4 bytes) access (read
+ *    and write), access failure is indicated by bit wrdaccerr in register USR2. When set to logic 0,
+ *    the FIFO supports byte access (read and write).
+ */
+#define ISO7816_UCR21_WRDACC(x)                  (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_WRDACC_SHIFT)) & ISO7816_UCR21_WRDACC_MASK)
+/*! @} */
+
+/*! @name CCR1 - Clock Configuration Register slot 1 */
+/*! @{ */
+#define ISO7816_CCR1_ACC_MASK                    (0x7U)
+#define ISO7816_CCR1_ACC_SHIFT                   (0U)
+/*! ACC - Asynchronous Card Clock: Defines the card clock frequency: 000: card clock frequency =
+ *    fclk_ip; 001: card clock frequency = fclk_ip /2; 010: card clock frequency = fclk_ip /3; 011:
+ *    card clock frequency = fclk_ip /4; 100: card clock frequency = fclk_ip /5; 101: card clock
+ *    frequency = fclk_ip /6; 110: card clock frequency = fclk_ip /8; 111: card clock frequency = fclk_ip
+ *    /16. All frequency changes are synchronous, thus ensuring that no spikes or unwanted pulse
+ *    widths occur during changes. In conjunction with registers ct_etucr_lsb_reg and ct_etucr_msb_reg,
+ *    the bits ACC2, ACC1 and ACC0 defines the baudrate used by the Contact UART.
+ */
+#define ISO7816_CCR1_ACC(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_CCR1_ACC_SHIFT)) & ISO7816_CCR1_ACC_MASK)
+#define ISO7816_CCR1_SAN_MASK                    (0x8U)
+#define ISO7816_CCR1_SAN_SHIFT                   (3U)
+/*! SAN - Synchronous/Asynchronous Card: [For Slot 1]: When set to logic 1, the Contact UART
+ *    supports synchronous card. The Contact UART is then bypassed, only bit 0 of registers ct_urr_reg and
+ *    ct_utr_reg is connected to pin I/O. In this case, the card clock is controlled by bit SHL and
+ *    RST card is controlled by bit RSTIN in register ct_pcr_reg. When set to logic 0, the Contact
+ *    UART supports asynchronous card. Dynamic change (while activated) is not supported. The choice
+ *    should be done before activating the card. [For Slot AUX]: When set to logic 1, the Contact
+ *    UART supports synchronous card. The Contact UART is then bypassed, only bit 0 of registers
+ *    ct_urr_reg and ct_utr_reg is connected to pin I/O. In this case, the card clock is controlled by
+ *    bit SHL. When set to logic 0, the Contact UART supports asynchronous card. Dynamic change (while
+ *    CLKAUXen = 1) is not supported. The choice should be done before enabling CLKAUX clock.
+ */
+#define ISO7816_CCR1_SAN(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_CCR1_SAN_SHIFT)) & ISO7816_CCR1_SAN_MASK)
+#define ISO7816_CCR1_CST_MASK                    (0x10U)
+#define ISO7816_CCR1_CST_SHIFT                   (4U)
+/*! CST - Clock STop: [For Slot 1]: In the case of an asynchronous card, bit CST defines whether the
+ *    clock to the card is stopped or not; if bit CST is reset to logic 0, then the clock is
+ *    determined by bits ACC0, ACC1 and ACC2. [For Slot AUX]+I40: This bit is not available for the
+ *    auxiliary slot (ct_ccr2_reg) since clock stop feature is supported using CLKAUXen bit in ct_ssr_reg
+ *    register.
+ */
+#define ISO7816_CCR1_CST(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_CCR1_CST_SHIFT)) & ISO7816_CCR1_CST_MASK)
+#define ISO7816_CCR1_SHL_MASK                    (0x20U)
+#define ISO7816_CCR1_SHL_SHIFT                   (5U)
+/*! SHL - Stop HIGH or LOW: - Slot 1: If bits SAN = 0 and CST = 1, then the clock is stopped at LOW
+ *    level. If bit SHL = 0, and at HIGH level if bit SHL = 1. I+I10f bit SAN = 1, then contact CLK
+ *    is the copy of the value of bit SHL.
+ */
+#define ISO7816_CCR1_SHL(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_CCR1_SHL_SHIFT)) & ISO7816_CCR1_SHL_MASK)
+/*! @} */
+
+/*! @name PCR - Power Control Register */
+/*! @{ */
+#define ISO7816_PCR_PCR_MASK                     (0xFFFFFFFFU)
+#define ISO7816_PCR_PCR_SHIFT                    (0U)
+/*! PCR - Power Control Register
+ */
+#define ISO7816_PCR_PCR(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_PCR_PCR_SHIFT)) & ISO7816_PCR_PCR_MASK)
+/*! @} */
+
+/*! @name ECR - Early answer Counter register */
+/*! @{ */
+#define ISO7816_ECR_ECR_MASK                     (0xFFFFFFFFU)
+#define ISO7816_ECR_ECR_SHIFT                    (0U)
+/*! ECR - Early answer Counter register
+ */
+#define ISO7816_ECR_ECR(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_ECR_ECR_SHIFT)) & ISO7816_ECR_ECR_MASK)
+/*! @} */
+
+/*! @name MCRL_LSB - Mute card Counter RST Low register (LSB) */
+/*! @{ */
+#define ISO7816_MCRL_LSB_MCRL_LSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_MCRL_LSB_MCRL_LSB_SHIFT          (0U)
+/*! MCRL_LSB - Mute card Counter RST Low register (LSB)
+ */
+#define ISO7816_MCRL_LSB_MCRL_LSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_MCRL_LSB_MCRL_LSB_SHIFT)) & ISO7816_MCRL_LSB_MCRL_LSB_MASK)
+/*! @} */
+
+/*! @name MCRL_MSB - Mute card Counter RST Low register (MSB) */
+/*! @{ */
+#define ISO7816_MCRL_MSB_MCRL_MSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_MCRL_MSB_MCRL_MSB_SHIFT          (0U)
+/*! MCRL_MSB - Mute card Counter RST Low register (MSB)
+ */
+#define ISO7816_MCRL_MSB_MCRL_MSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_MCRL_MSB_MCRL_MSB_SHIFT)) & ISO7816_MCRL_MSB_MCRL_MSB_MASK)
+/*! @} */
+
+/*! @name MCRH_LSB - Mute card Counter RST High register (LSB) */
+/*! @{ */
+#define ISO7816_MCRH_LSB_MCRH_LSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_MCRH_LSB_MCRH_LSB_SHIFT          (0U)
+/*! MCRH_LSB - Mute card Counter RST High register (LSB)
+ */
+#define ISO7816_MCRH_LSB_MCRH_LSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_MCRH_LSB_MCRH_LSB_SHIFT)) & ISO7816_MCRH_LSB_MCRH_LSB_MASK)
+/*! @} */
+
+/*! @name MCRH_MSB - Mute card Counter RST High register (MSB) */
+/*! @{ */
+#define ISO7816_MCRH_MSB_MCRH_MSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_MCRH_MSB_MCRH_MSB_SHIFT          (0U)
+/*! MCRH_MSB - Mute card Counter RST High register (MSB)
+ */
+#define ISO7816_MCRH_MSB_MCRH_MSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_MCRH_MSB_MCRH_MSB_SHIFT)) & ISO7816_MCRH_MSB_MCRH_MSB_MASK)
+/*! @} */
+
+/*! @name URR_UTR - UART Receive Register / UART Transmit Register */
+/*! @{ */
+#define ISO7816_URR_UTR_URR_UTR_MASK             (0xFFFFFFFFU)
+#define ISO7816_URR_UTR_URR_UTR_SHIFT            (0U)
+/*! URR_UTR - UART Receive Register / UART Transmit Register
+ */
+#define ISO7816_URR_UTR_URR_UTR(x)               (((uint32_t)(((uint32_t)(x)) << ISO7816_URR_UTR_URR_UTR_SHIFT)) & ISO7816_URR_UTR_URR_UTR_MASK)
+/*! @} */
+
+/*! @name TOR1 - Time-Out Register 1 */
+/*! @{ */
+#define ISO7816_TOR1_TOR1_MASK                   (0xFFFFFFFFU)
+#define ISO7816_TOR1_TOR1_SHIFT                  (0U)
+/*! TOR1 - Time-Out Register 1
+ */
+#define ISO7816_TOR1_TOR1(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_TOR1_TOR1_SHIFT)) & ISO7816_TOR1_TOR1_MASK)
+/*! @} */
+
+/*! @name TOR2 - Time-Out Register 2 */
+/*! @{ */
+#define ISO7816_TOR2_TOR2_MASK                   (0xFFFFFFFFU)
+#define ISO7816_TOR2_TOR2_SHIFT                  (0U)
+/*! TOR2 - Time-Out Register 2
+ */
+#define ISO7816_TOR2_TOR2(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_TOR2_TOR2_SHIFT)) & ISO7816_TOR2_TOR2_MASK)
+/*! @} */
+
+/*! @name TOR3 - Time-Out Register 3 */
+/*! @{ */
+#define ISO7816_TOR3_TOR3_MASK                   (0xFFFFFFFFU)
+#define ISO7816_TOR3_TOR3_SHIFT                  (0U)
+/*! TOR3 - Time-Out Register 3
+ */
+#define ISO7816_TOR3_TOR3(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_TOR3_TOR3_SHIFT)) & ISO7816_TOR3_TOR3_MASK)
+/*! @} */
+
+/*! @name TOC - Time-Out Configuration register */
+/*! @{ */
+#define ISO7816_TOC_TOC_MASK                     (0xFFFFFFFFU)
+#define ISO7816_TOC_TOC_SHIFT                    (0U)
+/*! TOC - Time-Out Configuration register
+ */
+#define ISO7816_TOC_TOC(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_TOC_TOC_SHIFT)) & ISO7816_TOC_TOC_MASK)
+/*! @} */
+
+/*! @name FSR - FIFO Status Register */
+/*! @{ */
+#define ISO7816_FSR_FSR_MASK                     (0xFFFFFFFFU)
+#define ISO7816_FSR_FSR_SHIFT                    (0U)
+/*! FSR - FIFO Status Register
+ */
+#define ISO7816_FSR_FSR(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_FSR_FSR_SHIFT)) & ISO7816_FSR_FSR_MASK)
+/*! @} */
+
+/*! @name MSR - Mixed Status Register */
+/*! @{ */
+#define ISO7816_MSR_MSR_MASK                     (0xFFFFFFFFU)
+#define ISO7816_MSR_MSR_SHIFT                    (0U)
+/*! MSR - Mixed Status Register
+ */
+#define ISO7816_MSR_MSR(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_MSR_MSR_SHIFT)) & ISO7816_MSR_MSR_MASK)
+/*! @} */
+
+/*! @name USR1 - UART Status Register 1 */
+/*! @{ */
+#define ISO7816_USR1_USR1_MASK                   (0xFFFFFFFFU)
+#define ISO7816_USR1_USR1_SHIFT                  (0U)
+/*! USR1 - UART Status Register 1
+ */
+#define ISO7816_USR1_USR1(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_USR1_USR1_SHIFT)) & ISO7816_USR1_USR1_MASK)
+/*! @} */
+
+/*! @name USR2 - UART Status Register 2 */
+/*! @{ */
+#define ISO7816_USR2_USR2_MASK                   (0xFFFFFFFFU)
+#define ISO7816_USR2_USR2_SHIFT                  (0U)
+/*! USR2 - UART Status Register 2
+ */
+#define ISO7816_USR2_USR2(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_USR2_USR2_SHIFT)) & ISO7816_USR2_USR2_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group ISO7816_Register_Masks */
+
+
+/* ISO7816 - Peripheral instance base addresses */
+/** Peripheral ISO7816 base address */
+#define ISO7816_BASE                             (0x40006000u)
+/** Peripheral ISO7816 base pointer */
+#define ISO7816                                  ((ISO7816_Type *)ISO7816_BASE)
+/** Array initializer of ISO7816 peripheral base addresses */
+#define ISO7816_BASE_ADDRS                       { ISO7816_BASE }
+/** Array initializer of ISO7816 peripheral base pointers */
+#define ISO7816_BASE_PTRS                        { ISO7816 }
+
+/*!
+ * @}
+ */ /* end of group ISO7816_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- OTPC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup OTPC_Peripheral_Access_Layer OTPC Peripheral Access Layer
+ * @{
+ */
+
+/** OTPC - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t ADDR;                              /**< Address register for reading the E-Fuse OTP, offset: 0x0 */
+       uint8_t RESERVED_0[4];
+  __O  uint32_t READ;                              /**< Register for reading the E-Fuse OTP., offset: 0x8 */
+       uint8_t RESERVED_1[8];
+  __I  uint32_t RDATA;                             /**< Register for the OTP read back data., offset: 0x14 */
+} OTPC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- OTPC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup OTPC_Register_Masks OTPC Register Masks
+ * @{
+ */
+
+/*! @name ADDR - Address register for reading the E-Fuse OTP */
+/*! @{ */
+#define OTPC_ADDR_ADDR_MASK                      (0xFFFU)
+#define OTPC_ADDR_ADDR_SHIFT                     (0U)
+/*! ADDR - Address of OTP value to be read
+ */
+#define OTPC_ADDR_ADDR(x)                        (((uint32_t)(((uint32_t)(x)) << OTPC_ADDR_ADDR_SHIFT)) & OTPC_ADDR_ADDR_MASK)
+/*! @} */
+
+/*! @name READ - Register for reading the E-Fuse OTP. */
+/*! @{ */
+#define OTPC_READ_READ_MASK                      (0x1U)
+#define OTPC_READ_READ_SHIFT                     (0U)
+/*! READ - When 1 is written, the OTP is read. Note, this operation only occurs if correct SEQ value is also written.
+ */
+#define OTPC_READ_READ(x)                        (((uint32_t)(((uint32_t)(x)) << OTPC_READ_READ_SHIFT)) & OTPC_READ_READ_MASK)
+#define OTPC_READ_SEQ_MASK                       (0xFFFF0000U)
+#define OTPC_READ_SEQ_SHIFT                      (16U)
+/*! SEQ - Read unlock sequence: only when 0x7F12 is written is the Read command accepted.
+ */
+#define OTPC_READ_SEQ(x)                         (((uint32_t)(((uint32_t)(x)) << OTPC_READ_SEQ_SHIFT)) & OTPC_READ_SEQ_MASK)
+/*! @} */
+
+/*! @name RDATA - Register for the OTP read back data. */
+/*! @{ */
+#define OTPC_RDATA_DATA_MASK                     (0xFFFFU)
+#define OTPC_RDATA_DATA_SHIFT                    (0U)
+/*! DATA - Read back data from the E-Fuse OTP.
+ */
+#define OTPC_RDATA_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << OTPC_RDATA_DATA_SHIFT)) & OTPC_RDATA_DATA_MASK)
+#define OTPC_RDATA_VALID_MASK                    (0x80000000U)
+#define OTPC_RDATA_VALID_SHIFT                   (31U)
+/*! VALID - Valid bit. This bit will be cleared when a Read command has been given and will be set
+ *    when the sequencer has successfully captured the E-Fuse OTP data.
+ */
+#define OTPC_RDATA_VALID(x)                      (((uint32_t)(((uint32_t)(x)) << OTPC_RDATA_VALID_SHIFT)) & OTPC_RDATA_VALID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group OTPC_Register_Masks */
+
+
+/* OTPC - Peripheral instance base addresses */
+/** Peripheral OTPC base address */
+#define OTPC_BASE                                (0x40002000u)
+/** Peripheral OTPC base pointer */
+#define OTPC                                     ((OTPC_Type *)OTPC_BASE)
+/** Array initializer of OTPC peripheral base addresses */
+#define OTPC_BASE_ADDRS                          { OTPC_BASE }
+/** Array initializer of OTPC peripheral base pointers */
+#define OTPC_BASE_PTRS                           { OTPC }
+
+/*!
+ * @}
+ */ /* end of group OTPC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- PINT Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PINT_Peripheral_Access_Layer PINT Peripheral Access Layer
+ * @{
+ */
+
+/** PINT - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t ISEL;                              /**< Pin Interrupt Mode register (only interrupts 0 to 3 supported to processor), offset: 0x0 */
+  __IO uint32_t IENR;                              /**< Pin interrupt level or rising edge interrupt enable register (only interrupts 0 to 3 supported to processor), offset: 0x4 */
+  __O  uint32_t SIENR;                             /**< Pin interrupt level or rising edge interrupt set register (only interrupts 0 to 3 supported to processor), offset: 0x8 */
+  __O  uint32_t CIENR;                             /**< Pin interrupt level (rising edge interrupt) clear register (only interrupts 0 to 3 supported to processor), offset: 0xC */
+  __IO uint32_t IENF;                              /**< Pin interrupt active level or falling edge interrupt enable register, offset: 0x10 */
+  __O  uint32_t SIENF;                             /**< Pin interrupt active level or falling edge interrupt set register, offset: 0x14 */
+  __O  uint32_t CIENF;                             /**< Pin interrupt active level or falling edge interrupt clear register, offset: 0x18 */
+  __IO uint32_t RISE;                              /**< Pin interrupt rising edge register, offset: 0x1C */
+  __IO uint32_t FALL;                              /**< Pin interrupt falling edge register, offset: 0x20 */
+  __IO uint32_t IST;                               /**< Pin interrupt status register. For bits in this regsiter the following functionality occurs for the corresponding PIN bit: Read 0: interrupt is not being requested for this interrupt pin. Write 0: no operation. Read 1: interrupt is being requested for this interrupt pin. Write 1 (edge-sensitive): clear rising- and falling-edge detection for this pin. Write 1 (level-sensitive): switch the active level for this pin (in the IENF register)., offset: 0x24 */
+  __IO uint32_t PMCTRL;                            /**< Pattern match interrupt control register, offset: 0x28 */
+  __IO uint32_t PMSRC;                             /**< Pattern match interrupt bit-slice source register, offset: 0x2C */
+  __IO uint32_t PMCFG;                             /**< Pattern match interrupt bit slice configuration register, offset: 0x30 */
+} PINT_Type;
+
+/* ----------------------------------------------------------------------------
+   -- PINT Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PINT_Register_Masks PINT Register Masks
+ * @{
+ */
+
+/*! @name ISEL - Pin Interrupt Mode register (only interrupts 0 to 3 supported to processor) */
+/*! @{ */
+#define PINT_ISEL_PMODE_PIN0_MASK                (0x1U)
+#define PINT_ISEL_PMODE_PIN0_SHIFT               (0U)
+/*! PMODE_PIN0 - Selects the interrupt mode for pin interrupt 0 (selected in PINTSEL0). 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN0(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN0_SHIFT)) & PINT_ISEL_PMODE_PIN0_MASK)
+#define PINT_ISEL_PMODE_PIN1_MASK                (0x2U)
+#define PINT_ISEL_PMODE_PIN1_SHIFT               (1U)
+/*! PMODE_PIN1 - Selects the interrupt mode for pin interrupt 1 (selected in PINTSEL1). 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN1(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN1_SHIFT)) & PINT_ISEL_PMODE_PIN1_MASK)
+#define PINT_ISEL_PMODE_PIN2_MASK                (0x4U)
+#define PINT_ISEL_PMODE_PIN2_SHIFT               (2U)
+/*! PMODE_PIN2 - Selects the interrupt mode for pin interrupt 2 (selected in PINTSEL2). 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN2(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN2_SHIFT)) & PINT_ISEL_PMODE_PIN2_MASK)
+#define PINT_ISEL_PMODE_PIN3_MASK                (0x8U)
+#define PINT_ISEL_PMODE_PIN3_SHIFT               (3U)
+/*! PMODE_PIN3 - Selects the interrupt mode for pin interrupt 3 (selected in PINTSEL3). 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN3(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN3_SHIFT)) & PINT_ISEL_PMODE_PIN3_MASK)
+#define PINT_ISEL_PMODE_PIN4_MASK                (0x10U)
+#define PINT_ISEL_PMODE_PIN4_SHIFT               (4U)
+/*! PMODE_PIN4 - Selects the interrupt mode for pin interrupt 4 (selected in PINTSEL4). [Note
+ *    interrupt not supported to processor] 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN4(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN4_SHIFT)) & PINT_ISEL_PMODE_PIN4_MASK)
+#define PINT_ISEL_PMODE_PIN5_MASK                (0x20U)
+#define PINT_ISEL_PMODE_PIN5_SHIFT               (5U)
+/*! PMODE_PIN5 - Selects the interrupt mode for pin interrupt 5 (selected in PINTSEL5). [Note
+ *    interrupt not supported to processor] 0: Edge sensitive 1: Level sensitive
+ */
+#define PINT_ISEL_PMODE_PIN5(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN5_SHIFT)) & PINT_ISEL_PMODE_PIN5_MASK)
+#define PINT_ISEL_PMODE_PIN6_MASK                (0x40U)
+#define PINT_ISEL_PMODE_PIN6_SHIFT               (6U)
+/*! PMODE_PIN6 - Selects the interrupt mode for pin interrupt 6 (selected in PINTSEL6). [Note
+ *    interrupt not supported to processor] 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN6(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN6_SHIFT)) & PINT_ISEL_PMODE_PIN6_MASK)
+#define PINT_ISEL_PMODE_PIN7_MASK                (0x80U)
+#define PINT_ISEL_PMODE_PIN7_SHIFT               (7U)
+/*! PMODE_PIN7 - Selects the interrupt mode for pin interrupt 7 (selected in PINTSEL7). [Note
+ *    interrupt not supported to processor] 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN7(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN7_SHIFT)) & PINT_ISEL_PMODE_PIN7_MASK)
+/*! @} */
+
+/*! @name IENR - Pin interrupt level or rising edge interrupt enable register (only interrupts 0 to 3 supported to processor) */
+/*! @{ */
+#define PINT_IENR_ENRL_PIN0_MASK                 (0x1U)
+#define PINT_IENR_ENRL_PIN0_SHIFT                (0U)
+/*! ENRL_PIN0 - Enables the rising edge or level interrupt for pin interrupt 0 (selected in
+ *    PINTSEL0). 0: Disable rising edge or level interrupt. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN0(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN0_SHIFT)) & PINT_IENR_ENRL_PIN0_MASK)
+#define PINT_IENR_ENRL_PIN1_MASK                 (0x2U)
+#define PINT_IENR_ENRL_PIN1_SHIFT                (1U)
+/*! ENRL_PIN1 - Enables the rising edge or level interrupt for pin interrupt 1 (selected in
+ *    PINTSEL1). 0: Disable rising edge or level interrupt. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN1(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN1_SHIFT)) & PINT_IENR_ENRL_PIN1_MASK)
+#define PINT_IENR_ENRL_PIN2_MASK                 (0x4U)
+#define PINT_IENR_ENRL_PIN2_SHIFT                (2U)
+/*! ENRL_PIN2 - Enables the rising edge or level interrupt for pin interrupt 2 (selected in
+ *    PINTSEL2). 0: Disable rising edge or level interrupt. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN2(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN2_SHIFT)) & PINT_IENR_ENRL_PIN2_MASK)
+#define PINT_IENR_ENRL_PIN3_MASK                 (0x8U)
+#define PINT_IENR_ENRL_PIN3_SHIFT                (3U)
+/*! ENRL_PIN3 - Enables the rising edge or level interrupt for pin interrupt 3 (selected in
+ *    PINTSEL3). 0: Disable rising edge or level interrupt. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN3(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN3_SHIFT)) & PINT_IENR_ENRL_PIN3_MASK)
+#define PINT_IENR_ENRL_PIN4_MASK                 (0x10U)
+#define PINT_IENR_ENRL_PIN4_SHIFT                (4U)
+/*! ENRL_PIN4 - Enables the rising edge or level interrupt for pin interrupt 4 (selected in
+ *    PINTSEL4). [Note interrupt not supported to processor] 0: Disable rising edge or level interrupt. 1:
+ *    Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN4(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN4_SHIFT)) & PINT_IENR_ENRL_PIN4_MASK)
+#define PINT_IENR_ENRL_PIN5_MASK                 (0x20U)
+#define PINT_IENR_ENRL_PIN5_SHIFT                (5U)
+/*! ENRL_PIN5 - Enables the rising edge or level interrupt for pin interrupt 5 (selected in
+ *    PINTSEL5). [Note interrupt not supported to processor] 0: Disable rising edge or level interrupt. 1:
+ *    Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN5(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN5_SHIFT)) & PINT_IENR_ENRL_PIN5_MASK)
+#define PINT_IENR_ENRL_PIN6_MASK                 (0x40U)
+#define PINT_IENR_ENRL_PIN6_SHIFT                (6U)
+/*! ENRL_PIN6 - Enables the rising edge or level interrupt for pin interrupt 6 (selected in
+ *    PINTSEL6). [Note interrupt not supported to processor] 0: Disable rising edge or level interrupt. 1:
+ *    Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN6(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN6_SHIFT)) & PINT_IENR_ENRL_PIN6_MASK)
+#define PINT_IENR_ENRL_PIN7_MASK                 (0x80U)
+#define PINT_IENR_ENRL_PIN7_SHIFT                (7U)
+/*! ENRL_PIN7 - Enables the rising edge or level interrupt for pin interrupt 7 (selected in
+ *    PINTSEL7). [Note interrupt not supported to processor] 0: Disable rising edge or level interrupt. 1:
+ *    Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN7(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN7_SHIFT)) & PINT_IENR_ENRL_PIN7_MASK)
+/*! @} */
+
+/*! @name SIENR - Pin interrupt level or rising edge interrupt set register (only interrupts 0 to 3 supported to processor) */
+/*! @{ */
+#define PINT_SIENR_SETENRL_PIN0_MASK             (0x1U)
+#define PINT_SIENR_SETENRL_PIN0_SHIFT            (0U)
+/*! SETENRL_PIN0 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    0 sets bit 0 in the IENR register. 0: No operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN0_SHIFT)) & PINT_SIENR_SETENRL_PIN0_MASK)
+#define PINT_SIENR_SETENRL_PIN1_MASK             (0x2U)
+#define PINT_SIENR_SETENRL_PIN1_SHIFT            (1U)
+/*! SETENRL_PIN1 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    1 sets bit 1 in the IENR register. 0: No operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN1_SHIFT)) & PINT_SIENR_SETENRL_PIN1_MASK)
+#define PINT_SIENR_SETENRL_PIN2_MASK             (0x4U)
+#define PINT_SIENR_SETENRL_PIN2_SHIFT            (2U)
+/*! SETENRL_PIN2 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    2 sets bit 2 in the IENR register. 0: No operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN2_SHIFT)) & PINT_SIENR_SETENRL_PIN2_MASK)
+#define PINT_SIENR_SETENRL_PIN3_MASK             (0x8U)
+#define PINT_SIENR_SETENRL_PIN3_SHIFT            (3U)
+/*! SETENRL_PIN3 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    3 sets bit 3 in the IENR register. 0: No operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN3_SHIFT)) & PINT_SIENR_SETENRL_PIN3_MASK)
+#define PINT_SIENR_SETENRL_PIN4_MASK             (0x10U)
+#define PINT_SIENR_SETENRL_PIN4_SHIFT            (4U)
+/*! SETENRL_PIN4 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    4 sets bit 4 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN4_SHIFT)) & PINT_SIENR_SETENRL_PIN4_MASK)
+#define PINT_SIENR_SETENRL_PIN5_MASK             (0x20U)
+#define PINT_SIENR_SETENRL_PIN5_SHIFT            (5U)
+/*! SETENRL_PIN5 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    5 sets bit 5 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN5_SHIFT)) & PINT_SIENR_SETENRL_PIN5_MASK)
+#define PINT_SIENR_SETENRL_PIN6_MASK             (0x40U)
+#define PINT_SIENR_SETENRL_PIN6_SHIFT            (6U)
+/*! SETENRL_PIN6 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    6 sets bit 6 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN6_SHIFT)) & PINT_SIENR_SETENRL_PIN6_MASK)
+#define PINT_SIENR_SETENRL_PIN7_MASK             (0x80U)
+#define PINT_SIENR_SETENRL_PIN7_SHIFT            (7U)
+/*! SETENRL_PIN7 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    7 sets bit 7 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN7(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN7_SHIFT)) & PINT_SIENR_SETENRL_PIN7_MASK)
+/*! @} */
+
+/*! @name CIENR - Pin interrupt level (rising edge interrupt) clear register (only interrupts 0 to 3 supported to processor) */
+/*! @{ */
+#define PINT_CIENR_CLRENRL_PIN0_MASK             (0x1U)
+#define PINT_CIENR_CLRENRL_PIN0_SHIFT            (0U)
+/*! CLRENRL_PIN0 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 0 clears bit 0 in the IENR register. 0: No operation. 1: Disable rising edge or level
+ *    interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN0_SHIFT)) & PINT_CIENR_CLRENRL_PIN0_MASK)
+#define PINT_CIENR_CLRENRL_PIN1_MASK             (0x2U)
+#define PINT_CIENR_CLRENRL_PIN1_SHIFT            (1U)
+/*! CLRENRL_PIN1 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 1 clears bit 1 in the IENR register. 0: No operation. 1: Disable rising edge or level
+ *    interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN1_SHIFT)) & PINT_CIENR_CLRENRL_PIN1_MASK)
+#define PINT_CIENR_CLRENRL_PIN2_MASK             (0x4U)
+#define PINT_CIENR_CLRENRL_PIN2_SHIFT            (2U)
+/*! CLRENRL_PIN2 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 2 clears bit 2 in the IENR register. 0: No operation. 1: Disable rising edge or level
+ *    interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN2_SHIFT)) & PINT_CIENR_CLRENRL_PIN2_MASK)
+#define PINT_CIENR_CLRENRL_PIN3_MASK             (0x8U)
+#define PINT_CIENR_CLRENRL_PIN3_SHIFT            (3U)
+/*! CLRENRL_PIN3 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 3 clears bit 3 in the IENR register. 0: No operation. 1: Disable rising edge or level
+ *    interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN3_SHIFT)) & PINT_CIENR_CLRENRL_PIN3_MASK)
+#define PINT_CIENR_CLRENRL_PIN4_MASK             (0x10U)
+#define PINT_CIENR_CLRENRL_PIN4_SHIFT            (4U)
+/*! CLRENRL_PIN4 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 4 clears bit 4 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Disable rising edge or level interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN4_SHIFT)) & PINT_CIENR_CLRENRL_PIN4_MASK)
+#define PINT_CIENR_CLRENRL_PIN5_MASK             (0x20U)
+#define PINT_CIENR_CLRENRL_PIN5_SHIFT            (5U)
+/*! CLRENRL_PIN5 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 5 clears bit 5 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Disable rising edge or level interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN5_SHIFT)) & PINT_CIENR_CLRENRL_PIN5_MASK)
+#define PINT_CIENR_CLRENRL_PIN6_MASK             (0x40U)
+#define PINT_CIENR_CLRENRL_PIN6_SHIFT            (6U)
+/*! CLRENRL_PIN6 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 6 clears bit 6 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Disable rising edge or level interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN6_SHIFT)) & PINT_CIENR_CLRENRL_PIN6_MASK)
+#define PINT_CIENR_CLRENRL_PIN7_MASK             (0x80U)
+#define PINT_CIENR_CLRENRL_PIN7_SHIFT            (7U)
+/*! CLRENRL_PIN7 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 7 clears bit 7 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Disable rising edge or level interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN7(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN7_SHIFT)) & PINT_CIENR_CLRENRL_PIN7_MASK)
+/*! @} */
+
+/*! @name IENF - Pin interrupt active level or falling edge interrupt enable register */
+/*! @{ */
+#define PINT_IENF_ENAF_PIN0_MASK                 (0x1U)
+#define PINT_IENF_ENAF_PIN0_SHIFT                (0U)
+/*! ENAF_PIN0 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    0 (selected in PINTSEL0). 0: Disable falling edge interrupt or set active interrupt level LOW.
+ *    1: Enable falling edge interrupt enabled or set active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN0(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN0_SHIFT)) & PINT_IENF_ENAF_PIN0_MASK)
+#define PINT_IENF_ENAF_PIN1_MASK                 (0x2U)
+#define PINT_IENF_ENAF_PIN1_SHIFT                (1U)
+/*! ENAF_PIN1 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    1 (selected in PINTSEL1). 0: Disable falling edge interrupt or set active interrupt level LOW.
+ *    1: Enable falling edge interrupt enabled or set active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN1(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN1_SHIFT)) & PINT_IENF_ENAF_PIN1_MASK)
+#define PINT_IENF_ENAF_PIN2_MASK                 (0x4U)
+#define PINT_IENF_ENAF_PIN2_SHIFT                (2U)
+/*! ENAF_PIN2 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    2 (selected in PINTSEL2). 0: Disable falling edge interrupt or set active interrupt level LOW.
+ *    1: Enable falling edge interrupt enabled or set active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN2(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN2_SHIFT)) & PINT_IENF_ENAF_PIN2_MASK)
+#define PINT_IENF_ENAF_PIN3_MASK                 (0x8U)
+#define PINT_IENF_ENAF_PIN3_SHIFT                (3U)
+/*! ENAF_PIN3 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    3 (selected in PINTSEL3). 0: Disable falling edge interrupt or set active interrupt level LOW.
+ *    1: Enable falling edge interrupt enabled or set active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN3(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN3_SHIFT)) & PINT_IENF_ENAF_PIN3_MASK)
+#define PINT_IENF_ENAF_PIN4_MASK                 (0x10U)
+#define PINT_IENF_ENAF_PIN4_SHIFT                (4U)
+/*! ENAF_PIN4 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    4 (selected in PINTSEL4). [Note interrupt not supported to processor] 0: Disable falling edge
+ *    interrupt or set active interrupt level LOW. 1: Enable falling edge interrupt enabled or set
+ *    active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN4(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN4_SHIFT)) & PINT_IENF_ENAF_PIN4_MASK)
+#define PINT_IENF_ENAF_PIN5_MASK                 (0x20U)
+#define PINT_IENF_ENAF_PIN5_SHIFT                (5U)
+/*! ENAF_PIN5 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    5 (selected in PINTSEL5). [Note interrupt not supported to processor] 0: Disable falling edge
+ *    interrupt or set active interrupt level LOW. 1: Enable falling edge interrupt enabled or set
+ *    active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN5(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN5_SHIFT)) & PINT_IENF_ENAF_PIN5_MASK)
+#define PINT_IENF_ENAF_PIN6_MASK                 (0x40U)
+#define PINT_IENF_ENAF_PIN6_SHIFT                (6U)
+/*! ENAF_PIN6 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    6 (selected in PINTSEL6). [Note interrupt not supported to processor] 0: Disable falling edge
+ *    interrupt or set active interrupt level LOW. 1: Enable falling edge interrupt enabled or set
+ *    active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN6(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN6_SHIFT)) & PINT_IENF_ENAF_PIN6_MASK)
+#define PINT_IENF_ENAF_PIN7_MASK                 (0x80U)
+#define PINT_IENF_ENAF_PIN7_SHIFT                (7U)
+/*! ENAF_PIN7 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    7 (selected in PINTSEL7). [Note interrupt not supported to processor] 0: Disable falling edge
+ *    interrupt or set active interrupt level LOW. 1: Enable falling edge interrupt enabled or set
+ *    active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN7(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN7_SHIFT)) & PINT_IENF_ENAF_PIN7_MASK)
+/*! @} */
+
+/*! @name SIENF - Pin interrupt active level or falling edge interrupt set register */
+/*! @{ */
+#define PINT_SIENF_SETENAF_PIN0_MASK             (0x1U)
+#define PINT_SIENF_SETENAF_PIN0_SHIFT            (0U)
+/*! SETENAF_PIN0 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    0 sets bit 0 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN0_SHIFT)) & PINT_SIENF_SETENAF_PIN0_MASK)
+#define PINT_SIENF_SETENAF_PIN1_MASK             (0x2U)
+#define PINT_SIENF_SETENAF_PIN1_SHIFT            (1U)
+/*! SETENAF_PIN1 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    1 sets bit 1 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN1_SHIFT)) & PINT_SIENF_SETENAF_PIN1_MASK)
+#define PINT_SIENF_SETENAF_PIN2_MASK             (0x4U)
+#define PINT_SIENF_SETENAF_PIN2_SHIFT            (2U)
+/*! SETENAF_PIN2 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    2 sets bit 2 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN2_SHIFT)) & PINT_SIENF_SETENAF_PIN2_MASK)
+#define PINT_SIENF_SETENAF_PIN3_MASK             (0x8U)
+#define PINT_SIENF_SETENAF_PIN3_SHIFT            (3U)
+/*! SETENAF_PIN3 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    3 sets bit 3 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN3_SHIFT)) & PINT_SIENF_SETENAF_PIN3_MASK)
+#define PINT_SIENF_SETENAF_PIN4_MASK             (0x10U)
+#define PINT_SIENF_SETENAF_PIN4_SHIFT            (4U)
+/*! SETENAF_PIN4 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    4 sets bit 4 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN4_SHIFT)) & PINT_SIENF_SETENAF_PIN4_MASK)
+#define PINT_SIENF_SETENAF_PIN5_MASK             (0x20U)
+#define PINT_SIENF_SETENAF_PIN5_SHIFT            (5U)
+/*! SETENAF_PIN5 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    5 sets bit 5 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN5_SHIFT)) & PINT_SIENF_SETENAF_PIN5_MASK)
+#define PINT_SIENF_SETENAF_PIN6_MASK             (0x40U)
+#define PINT_SIENF_SETENAF_PIN6_SHIFT            (6U)
+/*! SETENAF_PIN6 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    6 sets bit 6 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN6_SHIFT)) & PINT_SIENF_SETENAF_PIN6_MASK)
+#define PINT_SIENF_SETENAF_PIN7_MASK             (0x80U)
+#define PINT_SIENF_SETENAF_PIN7_SHIFT            (7U)
+/*! SETENAF_PIN7 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    7 sets bit 7 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN7(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN7_SHIFT)) & PINT_SIENF_SETENAF_PIN7_MASK)
+/*! @} */
+
+/*! @name CIENF - Pin interrupt active level or falling edge interrupt clear register */
+/*! @{ */
+#define PINT_CIENF_CLRENAF_PIN0_MASK             (0x1U)
+#define PINT_CIENF_CLRENAF_PIN0_SHIFT            (0U)
+/*! CLRENAF_PIN0 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 0 clears bit 0 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN0_SHIFT)) & PINT_CIENF_CLRENAF_PIN0_MASK)
+#define PINT_CIENF_CLRENAF_PIN1_MASK             (0x2U)
+#define PINT_CIENF_CLRENAF_PIN1_SHIFT            (1U)
+/*! CLRENAF_PIN1 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 1 clears bit 1 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN1_SHIFT)) & PINT_CIENF_CLRENAF_PIN1_MASK)
+#define PINT_CIENF_CLRENAF_PIN2_MASK             (0x4U)
+#define PINT_CIENF_CLRENAF_PIN2_SHIFT            (2U)
+/*! CLRENAF_PIN2 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 2 clears bit 2 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN2_SHIFT)) & PINT_CIENF_CLRENAF_PIN2_MASK)
+#define PINT_CIENF_CLRENAF_PIN3_MASK             (0x8U)
+#define PINT_CIENF_CLRENAF_PIN3_SHIFT            (3U)
+/*! CLRENAF_PIN3 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 3 clears bit 3 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN3_SHIFT)) & PINT_CIENF_CLRENAF_PIN3_MASK)
+#define PINT_CIENF_CLRENAF_PIN4_MASK             (0x10U)
+#define PINT_CIENF_CLRENAF_PIN4_SHIFT            (4U)
+/*! CLRENAF_PIN4 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 4 clears bit 4 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN4_SHIFT)) & PINT_CIENF_CLRENAF_PIN4_MASK)
+#define PINT_CIENF_CLRENAF_PIN5_MASK             (0x20U)
+#define PINT_CIENF_CLRENAF_PIN5_SHIFT            (5U)
+/*! CLRENAF_PIN5 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 5 clears bit 5 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN5_SHIFT)) & PINT_CIENF_CLRENAF_PIN5_MASK)
+#define PINT_CIENF_CLRENAF_PIN6_MASK             (0x40U)
+#define PINT_CIENF_CLRENAF_PIN6_SHIFT            (6U)
+/*! CLRENAF_PIN6 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 6 clears bit 6 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN6_SHIFT)) & PINT_CIENF_CLRENAF_PIN6_MASK)
+#define PINT_CIENF_CLRENAF_PIN7_MASK             (0x80U)
+#define PINT_CIENF_CLRENAF_PIN7_SHIFT            (7U)
+/*! CLRENAF_PIN7 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 7 clears bit 7 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN7(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN7_SHIFT)) & PINT_CIENF_CLRENAF_PIN7_MASK)
+/*! @} */
+
+/*! @name RISE - Pin interrupt rising edge register */
+/*! @{ */
+#define PINT_RISE_RDET_MASK                      (0xFFU)
+#define PINT_RISE_RDET_SHIFT                     (0U)
+/*! RDET - Rising edge detect. Bit n detects the rising edge of the pin selected in PINTSELn. Read
+ *    0: No rising edge has been detected on this pin since Reset or the last time a one was written
+ *    to this bit. Write 0: no operation. Read 1: a rising edge has been detected since Reset or the
+ *    last time a one was written to this bit. Write 1: clear rising edge detection for this pin.
+ */
+#define PINT_RISE_RDET(x)                        (((uint32_t)(((uint32_t)(x)) << PINT_RISE_RDET_SHIFT)) & PINT_RISE_RDET_MASK)
+/*! @} */
+
+/*! @name FALL - Pin interrupt falling edge register */
+/*! @{ */
+#define PINT_FALL_FDET_MASK                      (0xFFU)
+#define PINT_FALL_FDET_SHIFT                     (0U)
+/*! FDET - Falling edge detect. Bit n detects the falling edge of the pin selected in PINTSELn. Read
+ *    0: No falling edge has been detected on this pin since Reset or the last time a one was
+ *    written to this bit. Write 0: no operation. Read 1: a falling edge has been detected since Reset or
+ *    the last time a one was written to this bit. Write 1: clear falling edge detection for this
+ *    pin.
+ */
+#define PINT_FALL_FDET(x)                        (((uint32_t)(((uint32_t)(x)) << PINT_FALL_FDET_SHIFT)) & PINT_FALL_FDET_MASK)
+/*! @} */
+
+/*! @name IST - Pin interrupt status register. For bits in this regsiter the following functionality occurs for the corresponding PIN bit: Read 0: interrupt is not being requested for this interrupt pin. Write 0: no operation. Read 1: interrupt is being requested for this interrupt pin. Write 1 (edge-sensitive): clear rising- and falling-edge detection for this pin. Write 1 (level-sensitive): switch the active level for this pin (in the IENF register). */
+/*! @{ */
+#define PINT_IST_PSTAT_PIN0_MASK                 (0x1U)
+#define PINT_IST_PSTAT_PIN0_SHIFT                (0U)
+/*! PSTAT_PIN0 - Pin interrupt status. Bit 0 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 0 (selected in PINTSEL0).
+ */
+#define PINT_IST_PSTAT_PIN0(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN0_SHIFT)) & PINT_IST_PSTAT_PIN0_MASK)
+#define PINT_IST_PSTAT_PIN1_MASK                 (0x2U)
+#define PINT_IST_PSTAT_PIN1_SHIFT                (1U)
+/*! PSTAT_PIN1 - Pin interrupt status. Bit 1 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 1 (selected in PINTSEL0).
+ */
+#define PINT_IST_PSTAT_PIN1(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN1_SHIFT)) & PINT_IST_PSTAT_PIN1_MASK)
+#define PINT_IST_PSTAT_PIN2_MASK                 (0x4U)
+#define PINT_IST_PSTAT_PIN2_SHIFT                (2U)
+/*! PSTAT_PIN2 - Pin interrupt status. Bit 2 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 2 (selected in PINTSEL2).
+ */
+#define PINT_IST_PSTAT_PIN2(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN2_SHIFT)) & PINT_IST_PSTAT_PIN2_MASK)
+#define PINT_IST_PSTAT_PIN3_MASK                 (0x8U)
+#define PINT_IST_PSTAT_PIN3_SHIFT                (3U)
+/*! PSTAT_PIN3 - Pin interrupt status. Bit 3 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 3 (selected in PINTSEL3).
+ */
+#define PINT_IST_PSTAT_PIN3(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN3_SHIFT)) & PINT_IST_PSTAT_PIN3_MASK)
+#define PINT_IST_PSTAT_PIN4_MASK                 (0x10U)
+#define PINT_IST_PSTAT_PIN4_SHIFT                (4U)
+/*! PSTAT_PIN4 - Pin interrupt status. Bit 4 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 4 (selected in PINTSEL4).
+ */
+#define PINT_IST_PSTAT_PIN4(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN4_SHIFT)) & PINT_IST_PSTAT_PIN4_MASK)
+#define PINT_IST_PSTAT_PIN5_MASK                 (0x20U)
+#define PINT_IST_PSTAT_PIN5_SHIFT                (5U)
+/*! PSTAT_PIN5 - Pin interrupt status. Bit 5 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 5 (selected in PINTSEL5).
+ */
+#define PINT_IST_PSTAT_PIN5(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN5_SHIFT)) & PINT_IST_PSTAT_PIN5_MASK)
+#define PINT_IST_PSTAT_PIN6_MASK                 (0x40U)
+#define PINT_IST_PSTAT_PIN6_SHIFT                (6U)
+/*! PSTAT_PIN6 - Pin interrupt status. Bit 6 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 6 (selected in PINTSEL6).
+ */
+#define PINT_IST_PSTAT_PIN6(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN6_SHIFT)) & PINT_IST_PSTAT_PIN6_MASK)
+#define PINT_IST_PSTAT_PIN7_MASK                 (0x80U)
+#define PINT_IST_PSTAT_PIN7_SHIFT                (7U)
+/*! PSTAT_PIN7 - Pin interrupt status. Bit 7 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 7 (selected in PINTSEL7).
+ */
+#define PINT_IST_PSTAT_PIN7(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN7_SHIFT)) & PINT_IST_PSTAT_PIN7_MASK)
+/*! @} */
+
+/*! @name PMCTRL - Pattern match interrupt control register */
+/*! @{ */
+#define PINT_PMCTRL_SEL_PMATCH_MASK              (0x1U)
+#define PINT_PMCTRL_SEL_PMATCH_SHIFT             (0U)
+/*! SEL_PMATCH - Specifies whether the 8 pin interrupts are controlled by the pin interrupt function
+ *    or by the pattern match function. 0: Pin interrupt. Interrupts are driven in response to the
+ *    standard pin interrupt function. 1: Pattern match. Interrupts are driven in response to
+ *    pattern matches.
+ */
+#define PINT_PMCTRL_SEL_PMATCH(x)                (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_SEL_PMATCH_SHIFT)) & PINT_PMCTRL_SEL_PMATCH_MASK)
+#define PINT_PMCTRL_ENA_RXEV_MASK                (0x2U)
+#define PINT_PMCTRL_ENA_RXEV_SHIFT               (1U)
+/*! ENA_RXEV - Enables the RXEV output to the CPU when the specified boolean expression evaluates to
+ *    true. 0: Disabled. RXEV output to the CPU is disabled. 1: Enabled. RXEV output to the CPU is
+ *    enabled.
+ */
+#define PINT_PMCTRL_ENA_RXEV(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_ENA_RXEV_SHIFT)) & PINT_PMCTRL_ENA_RXEV_MASK)
+#define PINT_PMCTRL_PMAT_MASK                    (0xFF000000U)
+#define PINT_PMCTRL_PMAT_SHIFT                   (24U)
+/*! PMAT - This field displays the current state of pattern matches. A 1 in any bit of this field
+ *    indicates that the corresponding product term is matched by the current state of the appropriate
+ *    inputs.
+ */
+#define PINT_PMCTRL_PMAT(x)                      (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_PMAT_SHIFT)) & PINT_PMCTRL_PMAT_MASK)
+/*! @} */
+
+/*! @name PMSRC - Pattern match interrupt bit-slice source register */
+/*! @{ */
+#define PINT_PMSRC_SRC0_MASK                     (0x700U)
+#define PINT_PMSRC_SRC0_SHIFT                    (8U)
+/*! SRC0 - Selects the input source for bit slice 0. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC0(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC0_SHIFT)) & PINT_PMSRC_SRC0_MASK)
+#define PINT_PMSRC_SRC1_MASK                     (0x3800U)
+#define PINT_PMSRC_SRC1_SHIFT                    (11U)
+/*! SRC1 - Selects the input source for bit slice 1. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC1(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC1_SHIFT)) & PINT_PMSRC_SRC1_MASK)
+#define PINT_PMSRC_SRC2_MASK                     (0x1C000U)
+#define PINT_PMSRC_SRC2_SHIFT                    (14U)
+/*! SRC2 - Selects the input source for bit slice 2. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC2(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC2_SHIFT)) & PINT_PMSRC_SRC2_MASK)
+#define PINT_PMSRC_SRC3_MASK                     (0xE0000U)
+#define PINT_PMSRC_SRC3_SHIFT                    (17U)
+/*! SRC3 - Selects the input source for bit slice 3. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC3(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC3_SHIFT)) & PINT_PMSRC_SRC3_MASK)
+#define PINT_PMSRC_SRC4_MASK                     (0x700000U)
+#define PINT_PMSRC_SRC4_SHIFT                    (20U)
+/*! SRC4 - Selects the input source for bit slice 4. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC4(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC4_SHIFT)) & PINT_PMSRC_SRC4_MASK)
+#define PINT_PMSRC_SRC5_MASK                     (0x3800000U)
+#define PINT_PMSRC_SRC5_SHIFT                    (23U)
+/*! SRC5 - Selects the input source for bit slice 5. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC5(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC5_SHIFT)) & PINT_PMSRC_SRC5_MASK)
+#define PINT_PMSRC_SRC6_MASK                     (0x1C000000U)
+#define PINT_PMSRC_SRC6_SHIFT                    (26U)
+/*! SRC6 - Selects the input source for bit slice 6. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC6(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC6_SHIFT)) & PINT_PMSRC_SRC6_MASK)
+#define PINT_PMSRC_SRC7_MASK                     (0xE0000000U)
+#define PINT_PMSRC_SRC7_SHIFT                    (29U)
+/*! SRC7 - Selects the input source for bit slice 7. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC7(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC7_SHIFT)) & PINT_PMSRC_SRC7_MASK)
+/*! @} */
+
+/*! @name PMCFG - Pattern match interrupt bit slice configuration register */
+/*! @{ */
+#define PINT_PMCFG_PROD_ENDPTS0_MASK             (0x1U)
+#define PINT_PMCFG_PROD_ENDPTS0_SHIFT            (0U)
+/*! PROD_ENDPTS0 - Determines whether slice 0 is an endpoint. 0: No effect. Slice 0 is not an
+ *    endpoint. 1: endpoint. Slice 0 is the endpoint of a product term (minterm). Interrupt PINT0 in the
+ *    NVIC is raised if the minterm evaluates as true.
+ */
+#define PINT_PMCFG_PROD_ENDPTS0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS0_SHIFT)) & PINT_PMCFG_PROD_ENDPTS0_MASK)
+#define PINT_PMCFG_PROD_ENDPTS1_MASK             (0x2U)
+#define PINT_PMCFG_PROD_ENDPTS1_SHIFT            (1U)
+/*! PROD_ENDPTS1 - Determines whether slice 1 is an endpoint. 0: No effect. Slice 1 is not an
+ *    endpoint. 1: endpoint. Slice 1 is the endpoint of a product term (minterm). Interrupt PINT1 in the
+ *    NVIC is raised if the minterm evaluates as true.
+ */
+#define PINT_PMCFG_PROD_ENDPTS1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS1_SHIFT)) & PINT_PMCFG_PROD_ENDPTS1_MASK)
+#define PINT_PMCFG_PROD_ENDPTS2_MASK             (0x4U)
+#define PINT_PMCFG_PROD_ENDPTS2_SHIFT            (2U)
+/*! PROD_ENDPTS2 - Determines whether slice 2 is an endpoint. 0: No effect. Slice 2 is not an
+ *    endpoint. 1: endpoint. Slice 2 is the endpoint of a product term (minterm). Interrupt PINT2 in the
+ *    NVIC is raised if the minterm evaluates as true.
+ */
+#define PINT_PMCFG_PROD_ENDPTS2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS2_SHIFT)) & PINT_PMCFG_PROD_ENDPTS2_MASK)
+#define PINT_PMCFG_PROD_ENDPTS3_MASK             (0x8U)
+#define PINT_PMCFG_PROD_ENDPTS3_SHIFT            (3U)
+/*! PROD_ENDPTS3 - Determines whether slice 3 is an endpoint. 0: No effect. Slice 3 is not an
+ *    endpoint. 1: endpoint. Slice 3 is the endpoint of a product term (minterm). Interrupt PINT3 in the
+ *    NVIC is raised if the minterm evaluates as true.
+ */
+#define PINT_PMCFG_PROD_ENDPTS3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS3_SHIFT)) & PINT_PMCFG_PROD_ENDPTS3_MASK)
+#define PINT_PMCFG_PROD_ENDPTS4_MASK             (0x10U)
+#define PINT_PMCFG_PROD_ENDPTS4_SHIFT            (4U)
+/*! PROD_ENDPTS4 - Determines whether slice 4 is an endpoint. 0: No effect. Slice 4 is not an
+ *    endpoint. 1: endpoint. Slice 4 is the endpoint of a product term (minterm). No NVIC interrupt is
+ *    assocaited with this.
+ */
+#define PINT_PMCFG_PROD_ENDPTS4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS4_SHIFT)) & PINT_PMCFG_PROD_ENDPTS4_MASK)
+#define PINT_PMCFG_PROD_ENDPTS5_MASK             (0x20U)
+#define PINT_PMCFG_PROD_ENDPTS5_SHIFT            (5U)
+/*! PROD_ENDPTS5 - Determines whether slice 5 is an endpoint. 0 No effect. Slice 5 is not an
+ *    endpoint. 1: endpoint. Slice 5 is the endpoint of a product term (minterm). No NVIC interrupt is
+ *    assocaited with this.
+ */
+#define PINT_PMCFG_PROD_ENDPTS5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS5_SHIFT)) & PINT_PMCFG_PROD_ENDPTS5_MASK)
+#define PINT_PMCFG_PROD_ENDPTS6_MASK             (0x40U)
+#define PINT_PMCFG_PROD_ENDPTS6_SHIFT            (6U)
+/*! PROD_ENDPTS6 - Determines whether slice 6 is an endpoint. 0: No effect. Slice 6 is not an
+ *    endpoint. 1: endpoint. Slice 6 is the endpoint of a product term (minterm). No NVIC interrupt is
+ *    assocaited with this.
+ */
+#define PINT_PMCFG_PROD_ENDPTS6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS6_SHIFT)) & PINT_PMCFG_PROD_ENDPTS6_MASK)
+#define PINT_PMCFG_CFG0_MASK                     (0x700U)
+#define PINT_PMCFG_CFG0_SHIFT                    (8U)
+/*! CFG0 - Specifies the match contribution condition for bit slice 0. 0x0: Constant HIGH. This bit
+ *    slice always contributes to a product term match. 0x1: Sticky rising edge. Match occurs if a
+ *    rising edge on the specified input has occurred since the last time the edge detection for this
+ *    bit slice was cleared. This bit is only cleared when the PMCFG or the PMSRC registers are
+ *    written to. 0x2: Sticky falling edge. Match occurs if a falling edge on the specified input has
+ *    occurred since the last time the edge detection for this bit slice was cleared. This bit is
+ *    only cleared when the PMCFG or the PMSRC registers are written to. 0x3: Sticky rising or falling
+ *    edge. Match occurs if either a rising or falling edge on the specified input has occurred
+ *    since the last time the edge detection for this bit slice was cleared. This bit is only cleared
+ *    when the PMCFG or the PMSRC registers are written to. 0x4: High level. Match (for this bit
+ *    slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC
+ *    register. 0x5: Low level. Match occurs when there is a low level on the specified input. 0x6:
+ *    Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit
+ *    slices). 0x7: Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when
+ *    either a rising or falling edge is first detected on the specified input (this is a non-sticky
+ *    version of value 0x3). This bit is cleared after one clock cycle.
+ */
+#define PINT_PMCFG_CFG0(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG0_SHIFT)) & PINT_PMCFG_CFG0_MASK)
+#define PINT_PMCFG_CFG1_MASK                     (0x3800U)
+#define PINT_PMCFG_CFG1_SHIFT                    (11U)
+/*! CFG1 - Specifies the match contribution condition for bit slice 1. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG1(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG1_SHIFT)) & PINT_PMCFG_CFG1_MASK)
+#define PINT_PMCFG_CFG2_MASK                     (0x1C000U)
+#define PINT_PMCFG_CFG2_SHIFT                    (14U)
+/*! CFG2 - Specifies the match contribution condition for bit slice 2. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG2(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG2_SHIFT)) & PINT_PMCFG_CFG2_MASK)
+#define PINT_PMCFG_CFG3_MASK                     (0xE0000U)
+#define PINT_PMCFG_CFG3_SHIFT                    (17U)
+/*! CFG3 - Specifies the match contribution condition for bit slice 3. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG3(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG3_SHIFT)) & PINT_PMCFG_CFG3_MASK)
+#define PINT_PMCFG_CFG4_MASK                     (0x700000U)
+#define PINT_PMCFG_CFG4_SHIFT                    (20U)
+/*! CFG4 - Specifies the match contribution condition for bit slice 4. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG4(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG4_SHIFT)) & PINT_PMCFG_CFG4_MASK)
+#define PINT_PMCFG_CFG5_MASK                     (0x3800000U)
+#define PINT_PMCFG_CFG5_SHIFT                    (23U)
+/*! CFG5 - Specifies the match contribution condition for bit slice 5. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG5(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG5_SHIFT)) & PINT_PMCFG_CFG5_MASK)
+#define PINT_PMCFG_CFG6_MASK                     (0x1C000000U)
+#define PINT_PMCFG_CFG6_SHIFT                    (26U)
+/*! CFG6 - Specifies the match contribution condition for bit slice 6. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG6(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG6_SHIFT)) & PINT_PMCFG_CFG6_MASK)
+#define PINT_PMCFG_CFG7_MASK                     (0xE0000000U)
+#define PINT_PMCFG_CFG7_SHIFT                    (29U)
+/*! CFG7 - Specifies the match contribution condition for bit slice 7. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG7(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG7_SHIFT)) & PINT_PMCFG_CFG7_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group PINT_Register_Masks */
+
+
+/* PINT - Peripheral instance base addresses */
+/** Peripheral PINT base address */
+#define PINT_BASE                                (0x40010000u)
+/** Peripheral PINT base pointer */
+#define PINT                                     ((PINT_Type *)PINT_BASE)
+/** Array initializer of PINT peripheral base addresses */
+#define PINT_BASE_ADDRS                          { PINT_BASE }
+/** Array initializer of PINT peripheral base pointers */
+#define PINT_BASE_PTRS                           { PINT }
+/** Interrupt vectors for the PINT peripheral type */
+#define PINT_IRQS                                { PIN_INT0_IRQn, PIN_INT1_IRQn, PIN_INT2_IRQn, PIN_INT3_IRQn }
+
+/*!
+ * @}
+ */ /* end of group PINT_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- PMC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PMC_Peripheral_Access_Layer PMC Peripheral Access Layer
+ * @{
+ */
+
+/** PMC - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< Power Management Control [Reset by POR, RSTN, WDT ], offset: 0x0 */
+  __IO uint32_t DCDC0;                             /**< DCDC control register (1st). This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x4 */
+  __IO uint32_t DCDC1;                             /**< DCDC control register (2nd). This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x8 */
+  __IO uint32_t BIAS;                              /**< Bias current source control register. This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ], offset: 0xC */
+  __IO uint32_t LDOPMU;                            /**< PMU & Always On domains LDO control. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x10 */
+  __IO uint32_t LDOMEM;                            /**< Memories LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x14 */
+  __IO uint32_t LDOCORE;                           /**< Digital Core LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x18 */
+  __IO uint32_t LDOFLASHNV;                        /**< Flash LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x1C */
+  __IO uint32_t LDOFLASHCORE;                      /**< Flash Core LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x20 */
+  __IO uint32_t LDOADC;                            /**< General Purpose ADC LDO control register This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x24 */
+       uint8_t RESERVED_0[8];
+  __IO uint32_t BODVBAT;                           /**< VBAT Brown Out Dectector control register This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ], offset: 0x30 */
+       uint8_t RESERVED_1[12];
+  __IO uint32_t FRO192M;                           /**< High Speed FRO control register This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ], offset: 0x40 */
+  __IO uint32_t FRO1M;                             /**< 1 MHz Free Running Oscillator control register. [Reset by all reset sources, except ARM SystemReset], offset: 0x44 */
+       uint8_t RESERVED_2[8];
+  __IO uint32_t ANAMUXCOMP;                        /**< Analog Comparator and Analog Mux control register. [Reset by all reset sources, except ARM SystemReset], offset: 0x50 */
+       uint8_t RESERVED_3[12];
+  __I  uint32_t PWRSWACK;                          /**< Power Switch acknowledge. [Reset by all reset sources, except ARM SystemReset], offset: 0x60 */
+  __IO uint32_t DPDWKSRC;                          /**< Power Down and Deep Power Down wake-up source. [Reset by POR, RSTN, WDT ], offset: 0x64 */
+  __I  uint32_t STATUSPWR;                         /**< Power OK and Ready signals from various analog modules (DCDC, LDO, ). [Reset by all reset sources, except ARM SystemReset], offset: 0x68 */
+  __I  uint32_t STATUSCLK;                         /**< FRO and XTAL status register. [Reset by all reset sources, except ARM SystemReset], offset: 0x6C */
+  __IO uint32_t RESETCAUSE;                        /**< Reset Cause register. [Reset by POR], offset: 0x70 */
+       uint8_t RESERVED_4[12];
+  __IO uint32_t AOREG0;                            /**< General purpose always on domain data storage. [Reset by all reset sources, except ARM SystemReset], offset: 0x80 */
+  __IO uint32_t AOREG1;                            /**< General purpose always on domain data storage. [Reset by POR, RSTN], offset: 0x84 */
+  __IO uint32_t AOREG2;                            /**< General purpose always on domain data storage. [Reset by POR, RSTN], offset: 0x88 */
+       uint8_t RESERVED_5[12];
+  __IO uint32_t DPDCTRL;                           /**< Configuration parameters for Power Down and Deep Power Down mode. [Reset by POR, RSTN, WDT ], offset: 0x98 */
+  __I  uint32_t PIOPORCAP;                         /**< The PIOPORCAP register captures the state of GPIO at power-on-reset or pin reset. Each bit represents the power-on reset state of one GPIO pin. [Reset by POR, RSTN], offset: 0x9C */
+  __I  uint32_t PIORESCAP;                         /**< The PIORESCAP0 register captures the state of GPIO port 0 when a reset other than a power-on reset or pin reset occurs. Each bit represents the reset state of one GPIO pin. [Reset by WDT, BOD, WAKEUP IO, ARM System reset ], offset: 0xA0 */
+       uint8_t RESERVED_6[12];
+  __IO uint32_t PDSLEEPCFG;                        /**< Controls the power to various modules in Low Power modes. [Reset by all reset sources, except ARM SystemReset], offset: 0xB0 */
+       uint8_t RESERVED_7[4];
+  __IO uint32_t PDRUNCFG;                          /**< Controls the power to various analog blocks. [Reset by all reset sources, except ARM SystemReset], offset: 0xB8 */
+  __I  uint32_t WAKEIOCAUSE;                       /**< Wake-up source from Power Down and Deep Power Down modes. Allow to identify the Wake-up source from Power-Down mode or Deep Power Down mode.[Reset by POR, RSTN, WDT ], offset: 0xBC */
+       uint8_t RESERVED_8[12];
+  __IO uint32_t CTRLNORST;                         /**< Extension of CTRL register, but never reset except by POR, offset: 0xCC */
+} PMC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- PMC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PMC_Register_Masks PMC Register Masks
+ * @{
+ */
+
+/*! @name CTRL - Power Management Control [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_CTRL_LPMODE_MASK                     (0x3U)
+#define PMC_CTRL_LPMODE_SHIFT                    (0U)
+/*! LPMODE - Power Mode Control. 00: Active; 01: Deep Sleep; 10: Power Down; 11: Deep Power Down.
+ */
+#define PMC_CTRL_LPMODE(x)                       (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_LPMODE_SHIFT)) & PMC_CTRL_LPMODE_MASK)
+#define PMC_CTRL_SYSTEMRESETENABLE_MASK          (0x4U)
+#define PMC_CTRL_SYSTEMRESETENABLE_SHIFT         (2U)
+/*! SYSTEMRESETENABLE - ARM system reset request enable. If set enables the ARM system reset to affect the system.
+ */
+#define PMC_CTRL_SYSTEMRESETENABLE(x)            (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_SYSTEMRESETENABLE_SHIFT)) & PMC_CTRL_SYSTEMRESETENABLE_MASK)
+#define PMC_CTRL_WDTRESETENABLE_MASK             (0x8U)
+#define PMC_CTRL_WDTRESETENABLE_SHIFT            (3U)
+/*! WDTRESETENABLE - Watchdog Timer reset enable. If set allow a watchdog timer reset event to affect the system.
+ */
+#define PMC_CTRL_WDTRESETENABLE(x)               (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_WDTRESETENABLE_SHIFT)) & PMC_CTRL_WDTRESETENABLE_MASK)
+#define PMC_CTRL_WAKUPRESETENABLE_MASK           (0x10U)
+#define PMC_CTRL_WAKUPRESETENABLE_SHIFT          (4U)
+/*! WAKUPRESETENABLE - Wake-up I/Os reset enable. When set, the I/O power domain is not shutoff in deep powerdown mode.
+ */
+#define PMC_CTRL_WAKUPRESETENABLE(x)             (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_WAKUPRESETENABLE_SHIFT)) & PMC_CTRL_WAKUPRESETENABLE_MASK)
+#define PMC_CTRL_NTAGWAKUPRESETENABLE_MASK       (0x20U)
+#define PMC_CTRL_NTAGWAKUPRESETENABLE_SHIFT      (5U)
+/*! NTAGWAKUPRESETENABLE - Wake-up NTAG reset enable. When set, the device can wake from deep power
+ *    down by edge on NTAG FD signal, even if I/O power domain is off (see WAKUPRESETENABLE). Note
+ *    that if I/O power domain is ON, wake-up by NTAG FD is enabled by default thus content of this
+ *    bit does not care. Do not set unless entering Deep Power Down.
+ */
+#define PMC_CTRL_NTAGWAKUPRESETENABLE(x)         (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_NTAGWAKUPRESETENABLE_SHIFT)) & PMC_CTRL_NTAGWAKUPRESETENABLE_MASK)
+#define PMC_CTRL_SELLDOVOLTAGE_MASK              (0x100U)
+#define PMC_CTRL_SELLDOVOLTAGE_SHIFT             (8U)
+/*! SELLDOVOLTAGE - 0 = all LDOs current output levels are determined by their associated VADJ
+ *    bitfield. 1 = all LDOs current output levels are determined by their associated VADJ_2 bitfield.
+ */
+#define PMC_CTRL_SELLDOVOLTAGE(x)                (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_SELLDOVOLTAGE_SHIFT)) & PMC_CTRL_SELLDOVOLTAGE_MASK)
+#define PMC_CTRL_SWRRESETENABLE_MASK             (0x200U)
+#define PMC_CTRL_SWRRESETENABLE_SHIFT            (9U)
+/*! SWRRESETENABLE - Software reset enable. If set enables the software reset to affect the system.
+ */
+#define PMC_CTRL_SWRRESETENABLE(x)               (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_SWRRESETENABLE_SHIFT)) & PMC_CTRL_SWRRESETENABLE_MASK)
+/*! @} */
+
+/*! @name DCDC0 - DCDC control register (1st). This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_DCDC0_DCDC0_MASK                     (0xFFFFFFFFU)
+#define PMC_DCDC0_DCDC0_SHIFT                    (0U)
+/*! DCDC0 - DCDC control register (1st). This reigster is controlled by the boot code and the Low
+ *    power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_DCDC0_DCDC0(x)                       (((uint32_t)(((uint32_t)(x)) << PMC_DCDC0_DCDC0_SHIFT)) & PMC_DCDC0_DCDC0_MASK)
+/*! @} */
+
+/*! @name DCDC1 - DCDC control register (2nd). This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_DCDC1_DCDC1_MASK                     (0xFFFFFFFFU)
+#define PMC_DCDC1_DCDC1_SHIFT                    (0U)
+/*! DCDC1 - DCDC control register (2nd). This reigster is controlled by the boot code and the Low
+ *    power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_DCDC1_DCDC1(x)                       (((uint32_t)(((uint32_t)(x)) << PMC_DCDC1_DCDC1_SHIFT)) & PMC_DCDC1_DCDC1_MASK)
+/*! @} */
+
+/*! @name BIAS - Bias current source control register. This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_BIAS_BIAS_MASK                       (0xFFFFFFFFU)
+#define PMC_BIAS_BIAS_SHIFT                      (0U)
+/*! BIAS - Bias current source control register. This reigster is controlled by the boot code and
+ *    the Low power API software. [Reset by POR, RSTN, WDT ]
+ */
+#define PMC_BIAS_BIAS(x)                         (((uint32_t)(((uint32_t)(x)) << PMC_BIAS_BIAS_SHIFT)) & PMC_BIAS_BIAS_MASK)
+/*! @} */
+
+/*! @name LDOPMU - PMU & Always On domains LDO control. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOPMU_LDOPMU_MASK                   (0xFFFFFFFFU)
+#define PMC_LDOPMU_LDOPMU_SHIFT                  (0U)
+/*! LDOPMU - PMU & Always On domains LDO control. This reigster is controlled by the boot code and
+ *    the Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOPMU_LDOPMU(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_LDOPMU_LDOPMU_SHIFT)) & PMC_LDOPMU_LDOPMU_MASK)
+/*! @} */
+
+/*! @name LDOMEM - Memories LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOMEM_LDOMEM_MASK                   (0xFFFFFFFFU)
+#define PMC_LDOMEM_LDOMEM_SHIFT                  (0U)
+/*! LDOMEM - Memories LDO control register. This reigster is controlled by the boot code and the Low
+ *    power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOMEM_LDOMEM(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_LDOMEM_LDOMEM_SHIFT)) & PMC_LDOMEM_LDOMEM_MASK)
+/*! @} */
+
+/*! @name LDOCORE - Digital Core LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOCORE_LDOCORE_MASK                 (0xFFFFFFFFU)
+#define PMC_LDOCORE_LDOCORE_SHIFT                (0U)
+/*! LDOCORE - Digital Core LDO control register. This reigster is controlled by the boot code and
+ *    the Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOCORE_LDOCORE(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_LDOCORE_LDOCORE_SHIFT)) & PMC_LDOCORE_LDOCORE_MASK)
+/*! @} */
+
+/*! @name LDOFLASHNV - Flash LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOFLASHNV_LDOFLASHNV_MASK           (0xFFFFFFFFU)
+#define PMC_LDOFLASHNV_LDOFLASHNV_SHIFT          (0U)
+/*! LDOFLASHNV - Flash LDO control register. This reigster is controlled by the boot code and the
+ *    Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOFLASHNV_LDOFLASHNV(x)             (((uint32_t)(((uint32_t)(x)) << PMC_LDOFLASHNV_LDOFLASHNV_SHIFT)) & PMC_LDOFLASHNV_LDOFLASHNV_MASK)
+/*! @} */
+
+/*! @name LDOFLASHCORE - Flash Core LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOFLASHCORE_LDOFLASHCORE_MASK       (0xFFFFFFFFU)
+#define PMC_LDOFLASHCORE_LDOFLASHCORE_SHIFT      (0U)
+/*! LDOFLASHCORE - Flash Core LDO control register. This reigster is controlled by the boot code and
+ *    the Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOFLASHCORE_LDOFLASHCORE(x)         (((uint32_t)(((uint32_t)(x)) << PMC_LDOFLASHCORE_LDOFLASHCORE_SHIFT)) & PMC_LDOFLASHCORE_LDOFLASHCORE_MASK)
+/*! @} */
+
+/*! @name LDOADC - General Purpose ADC LDO control register This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOADC_LDOADC_MASK                   (0xFFFFFFFFU)
+#define PMC_LDOADC_LDOADC_SHIFT                  (0U)
+/*! LDOADC - General Purpose ADC LDO control register This reigster is controlled by the boot code
+ *    and the Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOADC_LDOADC(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_LDOADC_LDOADC_SHIFT)) & PMC_LDOADC_LDOADC_MASK)
+/*! @} */
+
+/*! @name BODVBAT - VBAT Brown Out Dectector control register This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_BODVBAT_TRIGLVL_MASK                 (0x1FU)
+#define PMC_BODVBAT_TRIGLVL_SHIFT                (0U)
+/*! TRIGLVL - BOD trigger level
+ */
+#define PMC_BODVBAT_TRIGLVL(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_BODVBAT_TRIGLVL_SHIFT)) & PMC_BODVBAT_TRIGLVL_MASK)
+#define PMC_BODVBAT_HYST_MASK                    (0x60U)
+#define PMC_BODVBAT_HYST_SHIFT                   (5U)
+/*! HYST - BOD Hysteresis control
+ */
+#define PMC_BODVBAT_HYST(x)                      (((uint32_t)(((uint32_t)(x)) << PMC_BODVBAT_HYST_SHIFT)) & PMC_BODVBAT_HYST_MASK)
+/*! @} */
+
+/*! @name FRO192M - High Speed FRO control register This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_FRO192M_DIVSEL_MASK                  (0x1F00000U)
+#define PMC_FRO192M_DIVSEL_SHIFT                 (20U)
+/*! DIVSEL - Mode of operation (which clock to output). Each bit enables a clocks as shown. Enables
+ *    are additive meaning that two or more clocks can be enabled together. xxxx1: 12MHz enabled;
+ *    xxx1x: 32MHz enabled; xx1xx: 48MHz enabled; x1xxx: 64MHz enabled; 1xxxx: Not applicable.
+ */
+#define PMC_FRO192M_DIVSEL(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_FRO192M_DIVSEL_SHIFT)) & PMC_FRO192M_DIVSEL_MASK)
+/*! @} */
+
+/*! @name FRO1M - 1 MHz Free Running Oscillator control register. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_FRO1M_FREQSEL_MASK                   (0x7FU)
+#define PMC_FRO1M_FREQSEL_SHIFT                  (0U)
+/*! FREQSEL - Frequency trimming bits. This field is used to give accurate frequency for each
+ *    device. The required setting is based upon calibration data sotred in flash during device test. This
+ *    setting is applied by the clock driver function.
+ */
+#define PMC_FRO1M_FREQSEL(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_FRO1M_FREQSEL_SHIFT)) & PMC_FRO1M_FREQSEL_MASK)
+#define PMC_FRO1M_ATBCTRL_MASK                   (0x180U)
+#define PMC_FRO1M_ATBCTRL_SHIFT                  (7U)
+/*! ATBCTRL - Debug control bits to set the analog/digital test modes; only required for test purposes.
+ */
+#define PMC_FRO1M_ATBCTRL(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_FRO1M_ATBCTRL_SHIFT)) & PMC_FRO1M_ATBCTRL_MASK)
+#define PMC_FRO1M_DIVSEL_MASK                    (0x3E00U)
+#define PMC_FRO1M_DIVSEL_SHIFT                   (9U)
+/*! DIVSEL - Divider selection bits.
+ */
+#define PMC_FRO1M_DIVSEL(x)                      (((uint32_t)(((uint32_t)(x)) << PMC_FRO1M_DIVSEL_SHIFT)) & PMC_FRO1M_DIVSEL_MASK)
+/*! @} */
+
+/*! @name ANAMUXCOMP - Analog Comparator and Analog Mux control register. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_ANAMUXCOMP_COMP_HYST_MASK            (0x2U)
+#define PMC_ANAMUXCOMP_COMP_HYST_SHIFT           (1U)
+/*! COMP_HYST - Hysteris enabled in comparator when hyst = '1', no hysteresis when = '0'.
+ */
+#define PMC_ANAMUXCOMP_COMP_HYST(x)              (((uint32_t)(((uint32_t)(x)) << PMC_ANAMUXCOMP_COMP_HYST_SHIFT)) & PMC_ANAMUXCOMP_COMP_HYST_MASK)
+#define PMC_ANAMUXCOMP_COMP_INNINT_MASK          (0x4U)
+#define PMC_ANAMUXCOMP_COMP_INNINT_SHIFT         (2U)
+/*! COMP_INNINT - Voltage reference inn_int input is selected for _n comparator input when
+ *    sel_inn_int = 1 . This setting also requires PMU_BIASING to be active. Also flash biasing and DCDC
+ *    converter needs to be enabled. If this setting = '0' then _n input comes from device pins, based
+ *    on COMP_INPUTSWAP setting.
+ */
+#define PMC_ANAMUXCOMP_COMP_INNINT(x)            (((uint32_t)(((uint32_t)(x)) << PMC_ANAMUXCOMP_COMP_INNINT_SHIFT)) & PMC_ANAMUXCOMP_COMP_INNINT_MASK)
+#define PMC_ANAMUXCOMP_COMP_LOWPOWER_MASK        (0x8U)
+#define PMC_ANAMUXCOMP_COMP_LOWPOWER_SHIFT       (3U)
+/*! COMP_LOWPOWER - Comparator Low power mode enabled when set.
+ */
+#define PMC_ANAMUXCOMP_COMP_LOWPOWER(x)          (((uint32_t)(((uint32_t)(x)) << PMC_ANAMUXCOMP_COMP_LOWPOWER_SHIFT)) & PMC_ANAMUXCOMP_COMP_LOWPOWER_MASK)
+#define PMC_ANAMUXCOMP_COMP_INPUTSWAP_MASK       (0x10U)
+#define PMC_ANAMUXCOMP_COMP_INPUTSWAP_SHIFT      (4U)
+/*! COMP_INPUTSWAP - Input swap is enabled when set. Comparator{ _p, _n} ports are connected to
+ *    {ACM, ACP}. Otherwsie normal configuration occurs, {_p, _n} is connected to {ACP, ACM} .
+ */
+#define PMC_ANAMUXCOMP_COMP_INPUTSWAP(x)         (((uint32_t)(((uint32_t)(x)) << PMC_ANAMUXCOMP_COMP_INPUTSWAP_SHIFT)) & PMC_ANAMUXCOMP_COMP_INPUTSWAP_MASK)
+/*! @} */
+
+/*! @name PWRSWACK - Power Switch acknowledge. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_PWRSWACK_PDCOMM0_MASK                (0x2U)
+#define PMC_PWRSWACK_PDCOMM0_SHIFT               (1U)
+/*! PDCOMM0 - Comm0 (USART0, I2C0, SPI0) Power Domain power switch status.
+ */
+#define PMC_PWRSWACK_PDCOMM0(x)                  (((uint32_t)(((uint32_t)(x)) << PMC_PWRSWACK_PDCOMM0_SHIFT)) & PMC_PWRSWACK_PDCOMM0_MASK)
+#define PMC_PWRSWACK_PDSYSTEM_MASK               (0x4U)
+#define PMC_PWRSWACK_PDSYSTEM_SHIFT              (2U)
+/*! PDSYSTEM - System Power Domain power switch status.
+ */
+#define PMC_PWRSWACK_PDSYSTEM(x)                 (((uint32_t)(((uint32_t)(x)) << PMC_PWRSWACK_PDSYSTEM_SHIFT)) & PMC_PWRSWACK_PDSYSTEM_MASK)
+#define PMC_PWRSWACK_PDMCURETENTION_MASK         (0x8U)
+#define PMC_PWRSWACK_PDMCURETENTION_SHIFT        (3U)
+/*! PDMCURETENTION - MCU Retention Power Domain power switch status.
+ */
+#define PMC_PWRSWACK_PDMCURETENTION(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PWRSWACK_PDMCURETENTION_SHIFT)) & PMC_PWRSWACK_PDMCURETENTION_MASK)
+/*! @} */
+
+/*! @name DPDWKSRC - Power Down and Deep Power Down wake-up source. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_DPDWKSRC_PIO0_MASK                   (0x1U)
+#define PMC_DPDWKSRC_PIO0_SHIFT                  (0U)
+/*! PIO0 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO0: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO0(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO0_SHIFT)) & PMC_DPDWKSRC_PIO0_MASK)
+#define PMC_DPDWKSRC_PIO1_MASK                   (0x2U)
+#define PMC_DPDWKSRC_PIO1_SHIFT                  (1U)
+/*! PIO1 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO1: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO1(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO1_SHIFT)) & PMC_DPDWKSRC_PIO1_MASK)
+#define PMC_DPDWKSRC_PIO2_MASK                   (0x4U)
+#define PMC_DPDWKSRC_PIO2_SHIFT                  (2U)
+/*! PIO2 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO2: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO2(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO2_SHIFT)) & PMC_DPDWKSRC_PIO2_MASK)
+#define PMC_DPDWKSRC_PIO3_MASK                   (0x8U)
+#define PMC_DPDWKSRC_PIO3_SHIFT                  (3U)
+/*! PIO3 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO3: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO3(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO3_SHIFT)) & PMC_DPDWKSRC_PIO3_MASK)
+#define PMC_DPDWKSRC_PIO4_MASK                   (0x10U)
+#define PMC_DPDWKSRC_PIO4_SHIFT                  (4U)
+/*! PIO4 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO4: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO4(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO4_SHIFT)) & PMC_DPDWKSRC_PIO4_MASK)
+#define PMC_DPDWKSRC_PIO5_MASK                   (0x20U)
+#define PMC_DPDWKSRC_PIO5_SHIFT                  (5U)
+/*! PIO5 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO5: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO5(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO5_SHIFT)) & PMC_DPDWKSRC_PIO5_MASK)
+#define PMC_DPDWKSRC_PIO6_MASK                   (0x40U)
+#define PMC_DPDWKSRC_PIO6_SHIFT                  (6U)
+/*! PIO6 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO6: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO6(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO6_SHIFT)) & PMC_DPDWKSRC_PIO6_MASK)
+#define PMC_DPDWKSRC_PIO7_MASK                   (0x80U)
+#define PMC_DPDWKSRC_PIO7_SHIFT                  (7U)
+/*! PIO7 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO7: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO7(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO7_SHIFT)) & PMC_DPDWKSRC_PIO7_MASK)
+#define PMC_DPDWKSRC_PIO8_MASK                   (0x100U)
+#define PMC_DPDWKSRC_PIO8_SHIFT                  (8U)
+/*! PIO8 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO8: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO8(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO8_SHIFT)) & PMC_DPDWKSRC_PIO8_MASK)
+#define PMC_DPDWKSRC_PIO9_MASK                   (0x200U)
+#define PMC_DPDWKSRC_PIO9_SHIFT                  (9U)
+/*! PIO9 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO9: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO9(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO9_SHIFT)) & PMC_DPDWKSRC_PIO9_MASK)
+#define PMC_DPDWKSRC_PIO10_MASK                  (0x400U)
+#define PMC_DPDWKSRC_PIO10_SHIFT                 (10U)
+/*! PIO10 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO10: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO10(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO10_SHIFT)) & PMC_DPDWKSRC_PIO10_MASK)
+#define PMC_DPDWKSRC_PIO11_MASK                  (0x800U)
+#define PMC_DPDWKSRC_PIO11_SHIFT                 (11U)
+/*! PIO11 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO11: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO11(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO11_SHIFT)) & PMC_DPDWKSRC_PIO11_MASK)
+#define PMC_DPDWKSRC_PIO12_MASK                  (0x1000U)
+#define PMC_DPDWKSRC_PIO12_SHIFT                 (12U)
+/*! PIO12 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO12: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO12(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO12_SHIFT)) & PMC_DPDWKSRC_PIO12_MASK)
+#define PMC_DPDWKSRC_PIO13_MASK                  (0x2000U)
+#define PMC_DPDWKSRC_PIO13_SHIFT                 (13U)
+/*! PIO13 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO13: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO13(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO13_SHIFT)) & PMC_DPDWKSRC_PIO13_MASK)
+#define PMC_DPDWKSRC_PIO14_MASK                  (0x4000U)
+#define PMC_DPDWKSRC_PIO14_SHIFT                 (14U)
+/*! PIO14 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO14: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO14(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO14_SHIFT)) & PMC_DPDWKSRC_PIO14_MASK)
+#define PMC_DPDWKSRC_PIO15_MASK                  (0x8000U)
+#define PMC_DPDWKSRC_PIO15_SHIFT                 (15U)
+/*! PIO15 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO15: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO15(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO15_SHIFT)) & PMC_DPDWKSRC_PIO15_MASK)
+#define PMC_DPDWKSRC_PIO16_MASK                  (0x10000U)
+#define PMC_DPDWKSRC_PIO16_SHIFT                 (16U)
+/*! PIO16 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO16: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO16(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO16_SHIFT)) & PMC_DPDWKSRC_PIO16_MASK)
+#define PMC_DPDWKSRC_PIO17_MASK                  (0x20000U)
+#define PMC_DPDWKSRC_PIO17_SHIFT                 (17U)
+/*! PIO17 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO17: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO17(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO17_SHIFT)) & PMC_DPDWKSRC_PIO17_MASK)
+#define PMC_DPDWKSRC_PIO18_MASK                  (0x40000U)
+#define PMC_DPDWKSRC_PIO18_SHIFT                 (18U)
+/*! PIO18 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO18: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO18(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO18_SHIFT)) & PMC_DPDWKSRC_PIO18_MASK)
+#define PMC_DPDWKSRC_PIO19_MASK                  (0x80000U)
+#define PMC_DPDWKSRC_PIO19_SHIFT                 (19U)
+/*! PIO19 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO19: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO19(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO19_SHIFT)) & PMC_DPDWKSRC_PIO19_MASK)
+#define PMC_DPDWKSRC_PIO20_MASK                  (0x100000U)
+#define PMC_DPDWKSRC_PIO20_SHIFT                 (20U)
+/*! PIO20 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO20: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO20(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO20_SHIFT)) & PMC_DPDWKSRC_PIO20_MASK)
+#define PMC_DPDWKSRC_PIO21_MASK                  (0x200000U)
+#define PMC_DPDWKSRC_PIO21_SHIFT                 (21U)
+/*! PIO21 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO21: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO21(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO21_SHIFT)) & PMC_DPDWKSRC_PIO21_MASK)
+#define PMC_DPDWKSRC_NTAG_FD_MASK                (0x400000U)
+#define PMC_DPDWKSRC_NTAG_FD_SHIFT               (22U)
+/*! NTAG_FD - Enable / disable wakeup from Power down and Deep Power Down modes by NTAG_FD: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_NTAG_FD(x)                  (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_NTAG_FD_SHIFT)) & PMC_DPDWKSRC_NTAG_FD_MASK)
+/*! @} */
+
+/*! @name STATUSPWR - Power OK and Ready signals from various analog modules (DCDC, LDO, ). [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_STATUSPWR_DCDCPWROK_MASK             (0x1U)
+#define PMC_STATUSPWR_DCDCPWROK_SHIFT            (0U)
+/*! DCDCPWROK - DCDC converter power OK
+ */
+#define PMC_STATUSPWR_DCDCPWROK(x)               (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_DCDCPWROK_SHIFT)) & PMC_STATUSPWR_DCDCPWROK_MASK)
+#define PMC_STATUSPWR_DCDCVXCTRLMON_MASK         (0x2U)
+#define PMC_STATUSPWR_DCDCVXCTRLMON_SHIFT        (1U)
+/*! DCDCVXCTRLMON - Picture of the DCDC output state.
+ */
+#define PMC_STATUSPWR_DCDCVXCTRLMON(x)           (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_DCDCVXCTRLMON_SHIFT)) & PMC_STATUSPWR_DCDCVXCTRLMON_MASK)
+#define PMC_STATUSPWR_LDOCOREPWROK_MASK          (0x4U)
+#define PMC_STATUSPWR_LDOCOREPWROK_SHIFT         (2U)
+/*! LDOCOREPWROK - CORE LDO power OK. Max switch on time 2us.
+ */
+#define PMC_STATUSPWR_LDOCOREPWROK(x)            (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_LDOCOREPWROK_SHIFT)) & PMC_STATUSPWR_LDOCOREPWROK_MASK)
+#define PMC_STATUSPWR_LDOFLASHNVPWROK_MASK       (0x8U)
+#define PMC_STATUSPWR_LDOFLASHNVPWROK_SHIFT      (3U)
+/*! LDOFLASHNVPWROK - Flash NV LDO power OK Max switch on time 20us.
+ */
+#define PMC_STATUSPWR_LDOFLASHNVPWROK(x)         (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_LDOFLASHNVPWROK_SHIFT)) & PMC_STATUSPWR_LDOFLASHNVPWROK_MASK)
+#define PMC_STATUSPWR_LDOFLASHCOREPWROK_MASK     (0x10U)
+#define PMC_STATUSPWR_LDOFLASHCOREPWROK_SHIFT    (4U)
+/*! LDOFLASHCOREPWROK - Flash Core LDO power OK Max switch on time should be considered as 10us.
+ */
+#define PMC_STATUSPWR_LDOFLASHCOREPWROK(x)       (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_LDOFLASHCOREPWROK_SHIFT)) & PMC_STATUSPWR_LDOFLASHCOREPWROK_MASK)
+#define PMC_STATUSPWR_LDOADC1V1PWROK_MASK        (0x20U)
+#define PMC_STATUSPWR_LDOADC1V1PWROK_SHIFT       (5U)
+/*! LDOADC1V1PWROK - General Purpose ADC LDO power OK. Max switch on time is 8us.
+ */
+#define PMC_STATUSPWR_LDOADC1V1PWROK(x)          (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_LDOADC1V1PWROK_SHIFT)) & PMC_STATUSPWR_LDOADC1V1PWROK_MASK)
+/*! @} */
+
+/*! @name STATUSCLK - FRO and XTAL status register. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_STATUSCLK_FRO192MCLKVALID_MASK       (0x1U)
+#define PMC_STATUSCLK_FRO192MCLKVALID_SHIFT      (0U)
+/*! FRO192MCLKVALID - High Speed FRO (FRO 192 MHz) clock valid signal. The FRO192M clock generator
+ *    also generates the FRO12M, FRO32M and FRO48M clock signals. These will also be valid when this
+ *    flag is assertetd.
+ */
+#define PMC_STATUSCLK_FRO192MCLKVALID(x)         (((uint32_t)(((uint32_t)(x)) << PMC_STATUSCLK_FRO192MCLKVALID_SHIFT)) & PMC_STATUSCLK_FRO192MCLKVALID_MASK)
+#define PMC_STATUSCLK_XTAL32KOK_MASK             (0x2U)
+#define PMC_STATUSCLK_XTAL32KOK_SHIFT            (1U)
+/*! XTAL32KOK - XTAL oscillator 32KHz OK signal. When the XTAL is stable, then a transition from 1
+ *    to 0 will indicate a clock issue. Can not be used to identify a stable clock during XTAL start.
+ */
+#define PMC_STATUSCLK_XTAL32KOK(x)               (((uint32_t)(((uint32_t)(x)) << PMC_STATUSCLK_XTAL32KOK_SHIFT)) & PMC_STATUSCLK_XTAL32KOK_MASK)
+#define PMC_STATUSCLK_FRO1MCLKVALID_MASK         (0x4U)
+#define PMC_STATUSCLK_FRO1MCLKVALID_SHIFT        (2U)
+/*! FRO1MCLKVALID - FRO 1 MHz CCO voltage detector output.
+ */
+#define PMC_STATUSCLK_FRO1MCLKVALID(x)           (((uint32_t)(((uint32_t)(x)) << PMC_STATUSCLK_FRO1MCLKVALID_SHIFT)) & PMC_STATUSCLK_FRO1MCLKVALID_MASK)
+/*! @} */
+
+/*! @name RESETCAUSE - Reset Cause register. [Reset by POR] */
+/*! @{ */
+#define PMC_RESETCAUSE_POR_MASK                  (0x1U)
+#define PMC_RESETCAUSE_POR_SHIFT                 (0U)
+/*! POR - 1 : The last chip reset was caused by a Power On Reset. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_POR(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_POR_SHIFT)) & PMC_RESETCAUSE_POR_MASK)
+#define PMC_RESETCAUSE_PADRESET_MASK             (0x2U)
+#define PMC_RESETCAUSE_PADRESET_SHIFT            (1U)
+/*! PADRESET - 1 : The last chip reset was caused by a Pad Reset. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_PADRESET(x)               (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_PADRESET_SHIFT)) & PMC_RESETCAUSE_PADRESET_MASK)
+#define PMC_RESETCAUSE_BODRESET_MASK             (0x4U)
+#define PMC_RESETCAUSE_BODRESET_SHIFT            (2U)
+/*! BODRESET - 1 : The last chip reset was caused by a Brown Out Detector. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_BODRESET(x)               (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_BODRESET_SHIFT)) & PMC_RESETCAUSE_BODRESET_MASK)
+#define PMC_RESETCAUSE_SYSTEMRESET_MASK          (0x8U)
+#define PMC_RESETCAUSE_SYSTEMRESET_SHIFT         (3U)
+/*! SYSTEMRESET - 1 : The last chip reset was caused by a System Reset requested by the ARM CPU. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_SYSTEMRESET(x)            (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_SYSTEMRESET_SHIFT)) & PMC_RESETCAUSE_SYSTEMRESET_MASK)
+#define PMC_RESETCAUSE_WDTRESET_MASK             (0x10U)
+#define PMC_RESETCAUSE_WDTRESET_SHIFT            (4U)
+/*! WDTRESET - 1 : The last chip reset was caused by the Watchdog Timer. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_WDTRESET(x)               (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_WDTRESET_SHIFT)) & PMC_RESETCAUSE_WDTRESET_MASK)
+#define PMC_RESETCAUSE_WAKEUPIORESET_MASK        (0x20U)
+#define PMC_RESETCAUSE_WAKEUPIORESET_SHIFT       (5U)
+/*! WAKEUPIORESET - 1 : The last chip reset was caused by a Wake-up I/O (GPIO or internal NTAG FD INT). Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_WAKEUPIORESET(x)          (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_WAKEUPIORESET_SHIFT)) & PMC_RESETCAUSE_WAKEUPIORESET_MASK)
+#define PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK      (0x40U)
+#define PMC_RESETCAUSE_WAKEUPPWDNRESET_SHIFT     (6U)
+/*! WAKEUPPWDNRESET - 1 : The last CPU reset was caused by a Wake-up from Power down (many sources
+ *    possible: timer, IO, ...). Write '1' to clear this bit. Check NVIC register if not waken-up by
+ *    IO (NVIC_GetPendingIRQ).
+ */
+#define PMC_RESETCAUSE_WAKEUPPWDNRESET(x)        (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_WAKEUPPWDNRESET_SHIFT)) & PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK)
+#define PMC_RESETCAUSE_SWRRESET_MASK             (0x80U)
+#define PMC_RESETCAUSE_SWRRESET_SHIFT            (7U)
+/*! SWRRESET - 1 : The last chip reset was caused by a Software. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_SWRRESET(x)               (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_SWRRESET_SHIFT)) & PMC_RESETCAUSE_SWRRESET_MASK)
+/*! @} */
+
+/*! @name AOREG0 - General purpose always on domain data storage. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_AOREG0_DATA31_0_MASK                 (0xFFFFFFFFU)
+#define PMC_AOREG0_DATA31_0_SHIFT                (0U)
+/*! DATA31_0 - General purpose always on domain data storage. Only writable 1 time after any chip
+ *    reset. After the 1st write, any further writes are blocked. After any chip reset the write block
+ *    is disabled until after next write. The chip reset includes POR, RSTIN, WDT reset, SW reset
+ *    and WAKEUP IO reset.
+ */
+#define PMC_AOREG0_DATA31_0(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_AOREG0_DATA31_0_SHIFT)) & PMC_AOREG0_DATA31_0_MASK)
+/*! @} */
+
+/*! @name AOREG1 - General purpose always on domain data storage. [Reset by POR, RSTN] */
+/*! @{ */
+#define PMC_AOREG1_DATA31_0_MASK                 (0xFFFFFFFFU)
+#define PMC_AOREG1_DATA31_0_SHIFT                (0U)
+/*! DATA31_0 - Reserved for use by NXP system software. General purpose always on domain data
+ *    storage. Only reinitialized on Power On Reset and RSTIN Pin reset.
+ */
+#define PMC_AOREG1_DATA31_0(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_AOREG1_DATA31_0_SHIFT)) & PMC_AOREG1_DATA31_0_MASK)
+/*! @} */
+
+/*! @name AOREG2 - General purpose always on domain data storage. [Reset by POR, RSTN] */
+/*! @{ */
+#define PMC_AOREG2_DATA31_0_MASK                 (0xFFFFFFFFU)
+#define PMC_AOREG2_DATA31_0_SHIFT                (0U)
+/*! DATA31_0 - General purpose always on domain data storage. Only reinitialized on Power On Reset and RSTIN Pin reset.
+ */
+#define PMC_AOREG2_DATA31_0(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_AOREG2_DATA31_0_SHIFT)) & PMC_AOREG2_DATA31_0_MASK)
+/*! @} */
+
+/*! @name DPDCTRL - Configuration parameters for Power Down and Deep Power Down mode. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_DPDCTRL_XTAL32MSTARTENA_MASK         (0x1U)
+#define PMC_DPDCTRL_XTAL32MSTARTENA_SHIFT        (0U)
+/*! XTAL32MSTARTENA - Enable XTAL32MHz automatic start-up at power up & wake up from power down or
+ *    deep power down. Reset value is set by eFuse content. This register field will overwrite option
+ *    selected by eFuse content only if power-up or wake-up is NOT triggered by any kind of reset.
+ *    Thus if power-up or wake-up is triggered by I/O or a timer. On the contrary, if power-up or
+ *    wake-up is triggered by POR (typically during initial power up) or watchdog reset or SW reset or
+ *    PAD RSTN then eFuse content will reset this register and will be applied. Take care that
+ *    option selected here can by masked in power down by a register of SYSCON - XTAL32MCTRL - which is
+ *    itself reset after each deep power down. Thus SYSCON/XTAL32MCTRL will not have any impact
+ *    after a deep power down, only after a power down.
+ */
+#define PMC_DPDCTRL_XTAL32MSTARTENA(x)           (((uint32_t)(((uint32_t)(x)) << PMC_DPDCTRL_XTAL32MSTARTENA_SHIFT)) & PMC_DPDCTRL_XTAL32MSTARTENA_MASK)
+#define PMC_DPDCTRL_XTAL32MSTARTDLY_MASK         (0x6U)
+#define PMC_DPDCTRL_XTAL32MSTARTDLY_SHIFT        (1U)
+/*! XTAL32MSTARTDLY - Delay between xtal ldo enable and release of reset to xtal 0:16us 1:32us
+ *    2:48us 3:64us. LSB reset value set by efuse (wake-up by I/O only). This delay is applied within PMC
+ *    for Efuse controlled XTAL start and also BLE link layer for BLE controlled auto-start.
+ */
+#define PMC_DPDCTRL_XTAL32MSTARTDLY(x)           (((uint32_t)(((uint32_t)(x)) << PMC_DPDCTRL_XTAL32MSTARTDLY_SHIFT)) & PMC_DPDCTRL_XTAL32MSTARTDLY_MASK)
+/*! @} */
+
+/*! @name PIOPORCAP - The PIOPORCAP register captures the state of GPIO at power-on-reset or pin reset. Each bit represents the power-on reset state of one GPIO pin. [Reset by POR, RSTN] */
+/*! @{ */
+#define PMC_PIOPORCAP_GPIO_MASK                  (0x3FFFFFU)
+#define PMC_PIOPORCAP_GPIO_SHIFT                 (0U)
+/*! GPIO - Capture of GPIO values at power-on-reset and pin reset.
+ */
+#define PMC_PIOPORCAP_GPIO(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_PIOPORCAP_GPIO_SHIFT)) & PMC_PIOPORCAP_GPIO_MASK)
+#define PMC_PIOPORCAP_NTAG_FD_MASK               (0x400000U)
+#define PMC_PIOPORCAP_NTAG_FD_SHIFT              (22U)
+/*! NTAG_FD - Capture of NTAG_FD value at power-on-reset and pin reset.
+ */
+#define PMC_PIOPORCAP_NTAG_FD(x)                 (((uint32_t)(((uint32_t)(x)) << PMC_PIOPORCAP_NTAG_FD_SHIFT)) & PMC_PIOPORCAP_NTAG_FD_MASK)
+/*! @} */
+
+/*! @name PIORESCAP - The PIORESCAP0 register captures the state of GPIO port 0 when a reset other than a power-on reset or pin reset occurs. Each bit represents the reset state of one GPIO pin. [Reset by WDT, BOD, WAKEUP IO, ARM System reset ] */
+/*! @{ */
+#define PMC_PIORESCAP_GPIO_MASK                  (0x3FFFFFU)
+#define PMC_PIORESCAP_GPIO_SHIFT                 (0U)
+/*! GPIO - Capture of GPIO values.
+ */
+#define PMC_PIORESCAP_GPIO(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_PIORESCAP_GPIO_SHIFT)) & PMC_PIORESCAP_GPIO_MASK)
+#define PMC_PIORESCAP_NTAG_FD_MASK               (0x400000U)
+#define PMC_PIORESCAP_NTAG_FD_SHIFT              (22U)
+/*! NTAG_FD - Capture of NTAG_FD value.
+ */
+#define PMC_PIORESCAP_NTAG_FD(x)                 (((uint32_t)(((uint32_t)(x)) << PMC_PIORESCAP_NTAG_FD_SHIFT)) & PMC_PIORESCAP_NTAG_FD_MASK)
+/*! @} */
+
+/*! @name PDSLEEPCFG - Controls the power to various modules in Low Power modes. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_PDSLEEPCFG_PDEN_DCDC_MASK            (0x1U)
+#define PMC_PDSLEEPCFG_PDEN_DCDC_SHIFT           (0U)
+/*! PDEN_DCDC - Controls DCDC power in Power down and Deep Power down modes. Automatically switched
+ *    off in deep power down. 0: DCDC is disabled in Power down and Deep Power down modes; 1: DCDC
+ *    is enabled in Power down and Deep Power down modes.
+ */
+#define PMC_PDSLEEPCFG_PDEN_DCDC(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_DCDC_SHIFT)) & PMC_PDSLEEPCFG_PDEN_DCDC_MASK)
+#define PMC_PDSLEEPCFG_PDEN_BIAS_MASK            (0x2U)
+#define PMC_PDSLEEPCFG_PDEN_BIAS_SHIFT           (1U)
+/*! PDEN_BIAS - Controls Bias power in Power down and Deep Power down modes. 0: Bias is disabled in
+ *    Power down and Deep Power down modes; 1: Bias is enabled in Power down and Deep Power down
+ *    modes.
+ */
+#define PMC_PDSLEEPCFG_PDEN_BIAS(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_BIAS_SHIFT)) & PMC_PDSLEEPCFG_PDEN_BIAS_MASK)
+#define PMC_PDSLEEPCFG_PDEN_LDO_MEM_MASK         (0x4U)
+#define PMC_PDSLEEPCFG_PDEN_LDO_MEM_SHIFT        (2U)
+/*! PDEN_LDO_MEM - Controls LDO memories power in Power down mode. Automatically switched off in
+ *    deep power down 0: LDO is disabled in Power down mode; 1: LDO is enabled in Power down mode.
+ */
+#define PMC_PDSLEEPCFG_PDEN_LDO_MEM(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_LDO_MEM_SHIFT)) & PMC_PDSLEEPCFG_PDEN_LDO_MEM_MASK)
+#define PMC_PDSLEEPCFG_PDEN_VBAT_BOD_MASK        (0x8U)
+#define PMC_PDSLEEPCFG_PDEN_VBAT_BOD_SHIFT       (3U)
+/*! PDEN_VBAT_BOD - Controls VBAT BOD power in Power down and Deep Power down modes. 0: VBAT BOD is
+ *    disabled in Power down and Deep Power down modes; 1: VBAT BOD is enabled in Power down and
+ *    Deep Power down modes.
+ */
+#define PMC_PDSLEEPCFG_PDEN_VBAT_BOD(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_VBAT_BOD_SHIFT)) & PMC_PDSLEEPCFG_PDEN_VBAT_BOD_MASK)
+#define PMC_PDSLEEPCFG_PDEN_FRO192M_MASK         (0x10U)
+#define PMC_PDSLEEPCFG_PDEN_FRO192M_SHIFT        (4U)
+/*! PDEN_FRO192M - Controls FRO192M power in Deep Sleep, Power down and Deep Power down modes. This
+ *    should be disabled before entering power down or deep power down mode. 0: FRO192M is disabled;
+ *    1: FRO192M is enabled.
+ */
+#define PMC_PDSLEEPCFG_PDEN_FRO192M(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_FRO192M_SHIFT)) & PMC_PDSLEEPCFG_PDEN_FRO192M_MASK)
+#define PMC_PDSLEEPCFG_PDEN_FRO1M_MASK           (0x20U)
+#define PMC_PDSLEEPCFG_PDEN_FRO1M_SHIFT          (5U)
+/*! PDEN_FRO1M - Controls FRO1M power in Deep Sleep, Power down and Deep Power down modes. This
+ *    should be disabled before entering power down (unless needed for low power timers) or deep power
+ *    down mode. 0: FRO1M is disabled; 1: FRO1M is enabled.
+ */
+#define PMC_PDSLEEPCFG_PDEN_FRO1M(x)             (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_FRO1M_SHIFT)) & PMC_PDSLEEPCFG_PDEN_FRO1M_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_FLASH_MASK        (0x40U)
+#define PMC_PDSLEEPCFG_PDEN_PD_FLASH_SHIFT       (6U)
+/*! PDEN_PD_FLASH - Enable Flash power domain Power Down mode (power shutoff) when entering in
+ *    DeepSleep. In PowerDown modes this domain is automatically powered off.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_FLASH(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_FLASH_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_FLASH_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_COMM0_MASK        (0x80U)
+#define PMC_PDSLEEPCFG_PDEN_PD_COMM0_SHIFT       (7U)
+/*! PDEN_PD_COMM0 - Enable Comm0 power domain (USART0, I2C0, SPI0) Power Down mode when entering in
+ *    Powerdown mode. In Deep power down it is disabled by hardware. In deep sleep it is always
+ *    enabled.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_COMM0(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_COMM0_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_COMM0_MASK)
+#define PMC_PDSLEEPCFG_EN_PDMCU_RETENTION_MASK   (0x100U)
+#define PMC_PDSLEEPCFG_EN_PDMCU_RETENTION_SHIFT  (8U)
+/*! EN_PDMCU_RETENTION - Enable MCU Power Domain state retention when entering in 'Powerdown' mode for modem and radio cal values
+ */
+#define PMC_PDSLEEPCFG_EN_PDMCU_RETENTION(x)     (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_EN_PDMCU_RETENTION_SHIFT)) & PMC_PDSLEEPCFG_EN_PDMCU_RETENTION_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM0_MASK         (0x400U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM0_SHIFT        (10U)
+/*! PDEN_PD_MEM0 - Enable Power Down mode of SRAM 0 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM0(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM0_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM0_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM1_MASK         (0x800U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM1_SHIFT        (11U)
+/*! PDEN_PD_MEM1 - Enable Power Down mode of SRAM 1 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM1(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM1_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM1_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM2_MASK         (0x1000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM2_SHIFT        (12U)
+/*! PDEN_PD_MEM2 - Enable Power Down mode of SRAM 2 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM2(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM2_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM2_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM3_MASK         (0x2000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM3_SHIFT        (13U)
+/*! PDEN_PD_MEM3 - Enable Power Down mode of SRAM 3 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM3(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM3_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM3_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM4_MASK         (0x4000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM4_SHIFT        (14U)
+/*! PDEN_PD_MEM4 - Enable Power Down mode of SRAM 4 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM4(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM4_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM4_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM5_MASK         (0x8000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM5_SHIFT        (15U)
+/*! PDEN_PD_MEM5 - Enable Power Down mode of SRAM 5 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM5(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM5_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM5_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM6_MASK         (0x10000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM6_SHIFT        (16U)
+/*! PDEN_PD_MEM6 - Enable Power Down mode of SRAM 6 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM6(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM6_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM6_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK         (0x20000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM7_SHIFT        (17U)
+/*! PDEN_PD_MEM7 - Enable Power Down mode of SRAM 7 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM7(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM7_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM8_MASK         (0x40000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM8_SHIFT        (18U)
+/*! PDEN_PD_MEM8 - Enable Power Down mode of SRAM 8 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM8(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM8_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM8_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM9_MASK         (0x80000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM9_SHIFT        (19U)
+/*! PDEN_PD_MEM9 - Enable Power Down mode of SRAM 9 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM9(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM9_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM9_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM10_MASK        (0x100000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM10_SHIFT       (20U)
+/*! PDEN_PD_MEM10 - Enable Power Down mode of SRAM 10 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM10(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM10_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM10_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM11_MASK        (0x200000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM11_SHIFT       (21U)
+/*! PDEN_PD_MEM11 - Enable Power Down mode of SRAM 11 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM11(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM11_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM11_MASK)
+/*! @} */
+
+/*! @name PDRUNCFG - Controls the power to various analog blocks. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_PDRUNCFG_ENA_LDO_ADC_MASK            (0x400000U)
+#define PMC_PDRUNCFG_ENA_LDO_ADC_SHIFT           (22U)
+/*! ENA_LDO_ADC - LDO ADC enabled. See STATUSPWR.LDOADC1V1PWROK for when the power domain is ready.
+ */
+#define PMC_PDRUNCFG_ENA_LDO_ADC(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_LDO_ADC_SHIFT)) & PMC_PDRUNCFG_ENA_LDO_ADC_MASK)
+#define PMC_PDRUNCFG_ENA_BOD_MEM_MASK            (0x800000U)
+#define PMC_PDRUNCFG_ENA_BOD_MEM_SHIFT           (23U)
+/*! ENA_BOD_MEM - BOD MEM enabled.
+ */
+#define PMC_PDRUNCFG_ENA_BOD_MEM(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_BOD_MEM_SHIFT)) & PMC_PDRUNCFG_ENA_BOD_MEM_MASK)
+#define PMC_PDRUNCFG_ENA_BOD_CORE_MASK           (0x1000000U)
+#define PMC_PDRUNCFG_ENA_BOD_CORE_SHIFT          (24U)
+/*! ENA_BOD_CORE - BOD CORE enabled.
+ */
+#define PMC_PDRUNCFG_ENA_BOD_CORE(x)             (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_BOD_CORE_SHIFT)) & PMC_PDRUNCFG_ENA_BOD_CORE_MASK)
+#define PMC_PDRUNCFG_ENA_FRO32K_MASK             (0x2000000U)
+#define PMC_PDRUNCFG_ENA_FRO32K_SHIFT            (25U)
+/*! ENA_FRO32K - FRO32K enabled.
+ */
+#define PMC_PDRUNCFG_ENA_FRO32K(x)               (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_FRO32K_SHIFT)) & PMC_PDRUNCFG_ENA_FRO32K_MASK)
+#define PMC_PDRUNCFG_ENA_XTAL32K_MASK            (0x4000000U)
+#define PMC_PDRUNCFG_ENA_XTAL32K_SHIFT           (26U)
+/*! ENA_XTAL32K - XTAL32K enabled.
+ */
+#define PMC_PDRUNCFG_ENA_XTAL32K(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_XTAL32K_SHIFT)) & PMC_PDRUNCFG_ENA_XTAL32K_MASK)
+#define PMC_PDRUNCFG_ENA_ANA_COMP_MASK           (0x8000000U)
+#define PMC_PDRUNCFG_ENA_ANA_COMP_SHIFT          (27U)
+/*! ENA_ANA_COMP - Analog Comparator enabled.
+ */
+#define PMC_PDRUNCFG_ENA_ANA_COMP(x)             (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_ANA_COMP_SHIFT)) & PMC_PDRUNCFG_ENA_ANA_COMP_MASK)
+/*! @} */
+
+/*! @name WAKEIOCAUSE - Wake-up source from Power Down and Deep Power Down modes. Allow to identify the Wake-up source from Power-Down mode or Deep Power Down mode.[Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_WAKEIOCAUSE_GPIO00_MASK              (0x1U)
+#define PMC_WAKEIOCAUSE_GPIO00_SHIFT             (0U)
+/*! GPIO00 - Wake up was triggered by GPIO 00
+ */
+#define PMC_WAKEIOCAUSE_GPIO00(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO00_SHIFT)) & PMC_WAKEIOCAUSE_GPIO00_MASK)
+#define PMC_WAKEIOCAUSE_GPIO01_MASK              (0x2U)
+#define PMC_WAKEIOCAUSE_GPIO01_SHIFT             (1U)
+/*! GPIO01 - Wake up was triggered by GPIO 01
+ */
+#define PMC_WAKEIOCAUSE_GPIO01(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO01_SHIFT)) & PMC_WAKEIOCAUSE_GPIO01_MASK)
+#define PMC_WAKEIOCAUSE_GPIO02_MASK              (0x4U)
+#define PMC_WAKEIOCAUSE_GPIO02_SHIFT             (2U)
+/*! GPIO02 - Wake up was triggered by GPIO 02
+ */
+#define PMC_WAKEIOCAUSE_GPIO02(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO02_SHIFT)) & PMC_WAKEIOCAUSE_GPIO02_MASK)
+#define PMC_WAKEIOCAUSE_GPIO03_MASK              (0x8U)
+#define PMC_WAKEIOCAUSE_GPIO03_SHIFT             (3U)
+/*! GPIO03 - Wake up was triggered by GPIO 03
+ */
+#define PMC_WAKEIOCAUSE_GPIO03(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO03_SHIFT)) & PMC_WAKEIOCAUSE_GPIO03_MASK)
+#define PMC_WAKEIOCAUSE_GPIO04_MASK              (0x10U)
+#define PMC_WAKEIOCAUSE_GPIO04_SHIFT             (4U)
+/*! GPIO04 - Wake up was triggered by GPIO 04
+ */
+#define PMC_WAKEIOCAUSE_GPIO04(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO04_SHIFT)) & PMC_WAKEIOCAUSE_GPIO04_MASK)
+#define PMC_WAKEIOCAUSE_GPIO05_MASK              (0x20U)
+#define PMC_WAKEIOCAUSE_GPIO05_SHIFT             (5U)
+/*! GPIO05 - Wake up was triggered by GPIO 05
+ */
+#define PMC_WAKEIOCAUSE_GPIO05(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO05_SHIFT)) & PMC_WAKEIOCAUSE_GPIO05_MASK)
+#define PMC_WAKEIOCAUSE_GPIO06_MASK              (0x40U)
+#define PMC_WAKEIOCAUSE_GPIO06_SHIFT             (6U)
+/*! GPIO06 - Wake up was triggered by GPIO 06
+ */
+#define PMC_WAKEIOCAUSE_GPIO06(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO06_SHIFT)) & PMC_WAKEIOCAUSE_GPIO06_MASK)
+#define PMC_WAKEIOCAUSE_GPIO07_MASK              (0x80U)
+#define PMC_WAKEIOCAUSE_GPIO07_SHIFT             (7U)
+/*! GPIO07 - Wake up was triggered by GPIO 07
+ */
+#define PMC_WAKEIOCAUSE_GPIO07(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO07_SHIFT)) & PMC_WAKEIOCAUSE_GPIO07_MASK)
+#define PMC_WAKEIOCAUSE_GPIO08_MASK              (0x100U)
+#define PMC_WAKEIOCAUSE_GPIO08_SHIFT             (8U)
+/*! GPIO08 - Wake up was triggered by GPIO 08
+ */
+#define PMC_WAKEIOCAUSE_GPIO08(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO08_SHIFT)) & PMC_WAKEIOCAUSE_GPIO08_MASK)
+#define PMC_WAKEIOCAUSE_GPIO09_MASK              (0x200U)
+#define PMC_WAKEIOCAUSE_GPIO09_SHIFT             (9U)
+/*! GPIO09 - Wake up was triggered by GPIO 09
+ */
+#define PMC_WAKEIOCAUSE_GPIO09(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO09_SHIFT)) & PMC_WAKEIOCAUSE_GPIO09_MASK)
+#define PMC_WAKEIOCAUSE_GPIO10_MASK              (0x400U)
+#define PMC_WAKEIOCAUSE_GPIO10_SHIFT             (10U)
+/*! GPIO10 - Wake up was triggered by GPIO 10
+ */
+#define PMC_WAKEIOCAUSE_GPIO10(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO10_SHIFT)) & PMC_WAKEIOCAUSE_GPIO10_MASK)
+#define PMC_WAKEIOCAUSE_GPIO11_MASK              (0x800U)
+#define PMC_WAKEIOCAUSE_GPIO11_SHIFT             (11U)
+/*! GPIO11 - Wake up was triggered by GPIO 11
+ */
+#define PMC_WAKEIOCAUSE_GPIO11(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO11_SHIFT)) & PMC_WAKEIOCAUSE_GPIO11_MASK)
+#define PMC_WAKEIOCAUSE_GPIO12_MASK              (0x1000U)
+#define PMC_WAKEIOCAUSE_GPIO12_SHIFT             (12U)
+/*! GPIO12 - Wake up was triggered by GPIO 12
+ */
+#define PMC_WAKEIOCAUSE_GPIO12(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO12_SHIFT)) & PMC_WAKEIOCAUSE_GPIO12_MASK)
+#define PMC_WAKEIOCAUSE_GPIO13_MASK              (0x2000U)
+#define PMC_WAKEIOCAUSE_GPIO13_SHIFT             (13U)
+/*! GPIO13 - Wake up was triggered by GPIO 13
+ */
+#define PMC_WAKEIOCAUSE_GPIO13(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO13_SHIFT)) & PMC_WAKEIOCAUSE_GPIO13_MASK)
+#define PMC_WAKEIOCAUSE_GPIO14_MASK              (0x4000U)
+#define PMC_WAKEIOCAUSE_GPIO14_SHIFT             (14U)
+/*! GPIO14 - Wake up was triggered by GPIO 14
+ */
+#define PMC_WAKEIOCAUSE_GPIO14(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO14_SHIFT)) & PMC_WAKEIOCAUSE_GPIO14_MASK)
+#define PMC_WAKEIOCAUSE_GPIO15_MASK              (0x8000U)
+#define PMC_WAKEIOCAUSE_GPIO15_SHIFT             (15U)
+/*! GPIO15 - Wake up was triggered by GPIO 15
+ */
+#define PMC_WAKEIOCAUSE_GPIO15(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO15_SHIFT)) & PMC_WAKEIOCAUSE_GPIO15_MASK)
+#define PMC_WAKEIOCAUSE_GPIO16_MASK              (0x10000U)
+#define PMC_WAKEIOCAUSE_GPIO16_SHIFT             (16U)
+/*! GPIO16 - Wake up was triggered by GPIO 16
+ */
+#define PMC_WAKEIOCAUSE_GPIO16(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO16_SHIFT)) & PMC_WAKEIOCAUSE_GPIO16_MASK)
+#define PMC_WAKEIOCAUSE_GPIO17_MASK              (0x20000U)
+#define PMC_WAKEIOCAUSE_GPIO17_SHIFT             (17U)
+/*! GPIO17 - Wake up was triggered by GPIO 17
+ */
+#define PMC_WAKEIOCAUSE_GPIO17(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO17_SHIFT)) & PMC_WAKEIOCAUSE_GPIO17_MASK)
+#define PMC_WAKEIOCAUSE_GPIO18_MASK              (0x40000U)
+#define PMC_WAKEIOCAUSE_GPIO18_SHIFT             (18U)
+/*! GPIO18 - Wake up was triggered by GPIO 18
+ */
+#define PMC_WAKEIOCAUSE_GPIO18(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO18_SHIFT)) & PMC_WAKEIOCAUSE_GPIO18_MASK)
+#define PMC_WAKEIOCAUSE_GPIO19_MASK              (0x80000U)
+#define PMC_WAKEIOCAUSE_GPIO19_SHIFT             (19U)
+/*! GPIO19 - Wake up was triggered by GPIO 19
+ */
+#define PMC_WAKEIOCAUSE_GPIO19(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO19_SHIFT)) & PMC_WAKEIOCAUSE_GPIO19_MASK)
+#define PMC_WAKEIOCAUSE_GPIO20_MASK              (0x100000U)
+#define PMC_WAKEIOCAUSE_GPIO20_SHIFT             (20U)
+/*! GPIO20 - Wake up was triggered by GPIO 20
+ */
+#define PMC_WAKEIOCAUSE_GPIO20(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO20_SHIFT)) & PMC_WAKEIOCAUSE_GPIO20_MASK)
+#define PMC_WAKEIOCAUSE_GPIO21_MASK              (0x200000U)
+#define PMC_WAKEIOCAUSE_GPIO21_SHIFT             (21U)
+/*! GPIO21 - Wake up was triggered by GPIO 21
+ */
+#define PMC_WAKEIOCAUSE_GPIO21(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO21_SHIFT)) & PMC_WAKEIOCAUSE_GPIO21_MASK)
+#define PMC_WAKEIOCAUSE_NTAG_FD_MASK             (0x400000U)
+#define PMC_WAKEIOCAUSE_NTAG_FD_SHIFT            (22U)
+/*! NTAG_FD - Wake up was triggered by NTAG FD
+ */
+#define PMC_WAKEIOCAUSE_NTAG_FD(x)               (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_NTAG_FD_SHIFT)) & PMC_WAKEIOCAUSE_NTAG_FD_MASK)
+/*! @} */
+
+/*! @name CTRLNORST - Extension of CTRL register, but never reset except by POR */
+/*! @{ */
+#define PMC_CTRLNORST_FASTLDOENABLE_MASK         (0x7U)
+#define PMC_CTRLNORST_FASTLDOENABLE_SHIFT        (0U)
+/*! FASTLDOENABLE - Fast LDO wake-up enable. 3 bits for the different wake-up sources: {generic
+ *    async wake up event as selected by SLEEPCON/STARTER0&1, IO wake-up event, RSTN pad event}. If
+ *    required, this field should only be managed by the Low power driver software.
+ */
+#define PMC_CTRLNORST_FASTLDOENABLE(x)           (((uint32_t)(((uint32_t)(x)) << PMC_CTRLNORST_FASTLDOENABLE_SHIFT)) & PMC_CTRLNORST_FASTLDOENABLE_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group PMC_Register_Masks */
+
+
+/* PMC - Peripheral instance base addresses */
+/** Peripheral PMC base address */
+#define PMC_BASE                                 (0x40012000u)
+/** Peripheral PMC base pointer */
+#define PMC                                      ((PMC_Type *)PMC_BASE)
+/** Array initializer of PMC peripheral base addresses */
+#define PMC_BASE_ADDRS                           { PMC_BASE }
+/** Array initializer of PMC peripheral base pointers */
+#define PMC_BASE_PTRS                            { PMC }
+
+/*!
+ * @}
+ */ /* end of group PMC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- PWM Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PWM_Peripheral_Access_Layer PWM Peripheral Access Layer
+ * @{
+ */
+
+/** PWM - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL0;                             /**< PWM 1st Control Register (Channel 0 to Channel 10) for channel enables and interrupt enables. Note if all interrupts are enabled with short period timings it will not be possible to manage all the interrupts., offset: 0x0 */
+  __IO uint32_t CTRL1;                             /**< PWM 2nd Control Register (Channel 0 to Channel 10) for channel polarity and output state for a disabled channel., offset: 0x4 */
+  __IO uint32_t PSCL01;                            /**< PWM Channels 0 & 1 prescalers, offset: 0x8 */
+  __IO uint32_t PSCL23;                            /**< PWM Channels 2 & 3 prescalers, offset: 0xC */
+  __IO uint32_t PSCL45;                            /**< PWM Channels 4 & 5 prescalers, offset: 0x10 */
+  __IO uint32_t PSCL67;                            /**< PWM Channels 6 & 7 prescalers, offset: 0x14 */
+  __IO uint32_t PSCL89;                            /**< PWM Channels 8 & 9 prescalers, offset: 0x18 */
+  __IO uint32_t PSCL1011;                          /**< PWM Channel 10 prescaler, offset: 0x1C */
+  __IO uint32_t PCP0;                              /**< PWM Channel 0 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x20 */
+  __IO uint32_t PCP1;                              /**< PWM Channel 1 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x24 */
+  __IO uint32_t PCP2;                              /**< PWM Channel 2 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x28 */
+  __IO uint32_t PCP3;                              /**< PWM Channel 3 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x2C */
+  __IO uint32_t PCP4;                              /**< PWM Channel 4 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x30 */
+  __IO uint32_t PCP5;                              /**< PWM Channel 5 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x34 */
+  __IO uint32_t PCP6;                              /**< PWM Channel 6 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x38 */
+  __IO uint32_t PCP7;                              /**< PWM Channel 7 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x3C */
+  __IO uint32_t PCP8;                              /**< PWM Channel 8 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x40 */
+  __IO uint32_t PCP9;                              /**< PWM Channel 9 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x44 */
+  __IO uint32_t PCP10;                             /**< PWM Channel 10 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached all PWM outputs will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x48 */
+  __IO uint32_t PST0;                              /**< PWM 1st Status Register (Channel 0 to Channel 3), offset: 0x4C */
+  __IO uint32_t PST1;                              /**< PWM 2nd Status Register (Channel 4 to Channel 7), offset: 0x50 */
+  __IO uint32_t PST2;                              /**< PWM 3rd Status Register (Channel 8 to Channel 10), offset: 0x54 */
+       uint8_t RESERVED_0[4004];
+  __I  uint32_t MODULE_ID;                         /**< PWM Module Identifier ('PW' in ASCII), offset: 0xFFC */
+} PWM_Type;
+
+/* ----------------------------------------------------------------------------
+   -- PWM Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PWM_Register_Masks PWM Register Masks
+ * @{
+ */
+
+/*! @name CTRL0 - PWM 1st Control Register (Channel 0 to Channel 10) for channel enables and interrupt enables. Note if all interrupts are enabled with short period timings it will not be possible to manage all the interrupts. */
+/*! @{ */
+#define PWM_CTRL0_PWM_EN_0_MASK                  (0x1U)
+#define PWM_CTRL0_PWM_EN_0_SHIFT                 (0U)
+/*! PWM_EN_0 - PWM channel 0 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_0(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_0_SHIFT)) & PWM_CTRL0_PWM_EN_0_MASK)
+#define PWM_CTRL0_PWM_EN_1_MASK                  (0x2U)
+#define PWM_CTRL0_PWM_EN_1_SHIFT                 (1U)
+/*! PWM_EN_1 - PWM channel 1 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_1(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_1_SHIFT)) & PWM_CTRL0_PWM_EN_1_MASK)
+#define PWM_CTRL0_PWM_EN_2_MASK                  (0x4U)
+#define PWM_CTRL0_PWM_EN_2_SHIFT                 (2U)
+/*! PWM_EN_2 - PWM channel 2 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_2(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_2_SHIFT)) & PWM_CTRL0_PWM_EN_2_MASK)
+#define PWM_CTRL0_PWM_EN_3_MASK                  (0x8U)
+#define PWM_CTRL0_PWM_EN_3_SHIFT                 (3U)
+/*! PWM_EN_3 - PWM channel 3 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_3(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_3_SHIFT)) & PWM_CTRL0_PWM_EN_3_MASK)
+#define PWM_CTRL0_PWM_EN_4_MASK                  (0x10U)
+#define PWM_CTRL0_PWM_EN_4_SHIFT                 (4U)
+/*! PWM_EN_4 - PWM channel 4 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_4(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_4_SHIFT)) & PWM_CTRL0_PWM_EN_4_MASK)
+#define PWM_CTRL0_PWM_EN_5_MASK                  (0x20U)
+#define PWM_CTRL0_PWM_EN_5_SHIFT                 (5U)
+/*! PWM_EN_5 - PWM channel 5 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_5(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_5_SHIFT)) & PWM_CTRL0_PWM_EN_5_MASK)
+#define PWM_CTRL0_PWM_EN_6_MASK                  (0x40U)
+#define PWM_CTRL0_PWM_EN_6_SHIFT                 (6U)
+/*! PWM_EN_6 - PWM channel 6 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_6(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_6_SHIFT)) & PWM_CTRL0_PWM_EN_6_MASK)
+#define PWM_CTRL0_PWM_EN_7_MASK                  (0x80U)
+#define PWM_CTRL0_PWM_EN_7_SHIFT                 (7U)
+/*! PWM_EN_7 - PWM channel 7 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_7(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_7_SHIFT)) & PWM_CTRL0_PWM_EN_7_MASK)
+#define PWM_CTRL0_PWM_EN_8_MASK                  (0x100U)
+#define PWM_CTRL0_PWM_EN_8_SHIFT                 (8U)
+/*! PWM_EN_8 - PWM channel 8 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_8(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_8_SHIFT)) & PWM_CTRL0_PWM_EN_8_MASK)
+#define PWM_CTRL0_PWM_EN_9_MASK                  (0x200U)
+#define PWM_CTRL0_PWM_EN_9_SHIFT                 (9U)
+/*! PWM_EN_9 - PWM channel 9 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_9(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_9_SHIFT)) & PWM_CTRL0_PWM_EN_9_MASK)
+#define PWM_CTRL0_PWM_EN_10_MASK                 (0x400U)
+#define PWM_CTRL0_PWM_EN_10_SHIFT                (10U)
+/*! PWM_EN_10 - PWM channel 10 enable. 0 = Disable / 1 = Enable. Note, this enables the common PWM
+ *    mode where PWM10 will be routed to all PWM channels.
+ */
+#define PWM_CTRL0_PWM_EN_10(x)                   (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_10_SHIFT)) & PWM_CTRL0_PWM_EN_10_MASK)
+#define PWM_CTRL0_INT_EN_0_MASK                  (0x10000U)
+#define PWM_CTRL0_INT_EN_0_SHIFT                 (16U)
+/*! INT_EN_0 - PWM channel 0 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_0(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_0_SHIFT)) & PWM_CTRL0_INT_EN_0_MASK)
+#define PWM_CTRL0_INT_EN_1_MASK                  (0x20000U)
+#define PWM_CTRL0_INT_EN_1_SHIFT                 (17U)
+/*! INT_EN_1 - PWM channel 1 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_1(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_1_SHIFT)) & PWM_CTRL0_INT_EN_1_MASK)
+#define PWM_CTRL0_INT_EN_2_MASK                  (0x40000U)
+#define PWM_CTRL0_INT_EN_2_SHIFT                 (18U)
+/*! INT_EN_2 - PWM channel 2 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_2(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_2_SHIFT)) & PWM_CTRL0_INT_EN_2_MASK)
+#define PWM_CTRL0_INT_EN_3_MASK                  (0x80000U)
+#define PWM_CTRL0_INT_EN_3_SHIFT                 (19U)
+/*! INT_EN_3 - PWM channel 3 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_3(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_3_SHIFT)) & PWM_CTRL0_INT_EN_3_MASK)
+#define PWM_CTRL0_INT_EN_4_MASK                  (0x100000U)
+#define PWM_CTRL0_INT_EN_4_SHIFT                 (20U)
+/*! INT_EN_4 - PWM channel 4 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_4(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_4_SHIFT)) & PWM_CTRL0_INT_EN_4_MASK)
+#define PWM_CTRL0_INT_EN_5_MASK                  (0x200000U)
+#define PWM_CTRL0_INT_EN_5_SHIFT                 (21U)
+/*! INT_EN_5 - PWM channel 5 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_5(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_5_SHIFT)) & PWM_CTRL0_INT_EN_5_MASK)
+#define PWM_CTRL0_INT_EN_6_MASK                  (0x400000U)
+#define PWM_CTRL0_INT_EN_6_SHIFT                 (22U)
+/*! INT_EN_6 - PWM channel 6 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_6(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_6_SHIFT)) & PWM_CTRL0_INT_EN_6_MASK)
+#define PWM_CTRL0_INT_EN_7_MASK                  (0x800000U)
+#define PWM_CTRL0_INT_EN_7_SHIFT                 (23U)
+/*! INT_EN_7 - PWM channel 7 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_7(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_7_SHIFT)) & PWM_CTRL0_INT_EN_7_MASK)
+#define PWM_CTRL0_INT_EN_8_MASK                  (0x1000000U)
+#define PWM_CTRL0_INT_EN_8_SHIFT                 (24U)
+/*! INT_EN_8 - PWM channel 8 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_8(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_8_SHIFT)) & PWM_CTRL0_INT_EN_8_MASK)
+#define PWM_CTRL0_INT_EN_9_MASK                  (0x2000000U)
+#define PWM_CTRL0_INT_EN_9_SHIFT                 (25U)
+/*! INT_EN_9 - PWM channel 9 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_9(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_9_SHIFT)) & PWM_CTRL0_INT_EN_9_MASK)
+#define PWM_CTRL0_INT_EN_10_MASK                 (0x4000000U)
+#define PWM_CTRL0_INT_EN_10_SHIFT                (26U)
+/*! INT_EN_10 - PWM channel 10 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_10(x)                   (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_10_SHIFT)) & PWM_CTRL0_INT_EN_10_MASK)
+/*! @} */
+
+/*! @name CTRL1 - PWM 2nd Control Register (Channel 0 to Channel 10) for channel polarity and output state for a disabled channel. */
+/*! @{ */
+#define PWM_CTRL1_POL_0_MASK                     (0x1U)
+#define PWM_CTRL1_POL_0_SHIFT                    (0U)
+/*! POL_0 - PWM channel 0 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_0(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_0_SHIFT)) & PWM_CTRL1_POL_0_MASK)
+#define PWM_CTRL1_POL_1_MASK                     (0x2U)
+#define PWM_CTRL1_POL_1_SHIFT                    (1U)
+/*! POL_1 - PWM channel 1 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_1(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_1_SHIFT)) & PWM_CTRL1_POL_1_MASK)
+#define PWM_CTRL1_POL_2_MASK                     (0x4U)
+#define PWM_CTRL1_POL_2_SHIFT                    (2U)
+/*! POL_2 - PWM channel 2 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_2(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_2_SHIFT)) & PWM_CTRL1_POL_2_MASK)
+#define PWM_CTRL1_POL_3_MASK                     (0x8U)
+#define PWM_CTRL1_POL_3_SHIFT                    (3U)
+/*! POL_3 - PWM channel 3 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_3(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_3_SHIFT)) & PWM_CTRL1_POL_3_MASK)
+#define PWM_CTRL1_POL_4_MASK                     (0x10U)
+#define PWM_CTRL1_POL_4_SHIFT                    (4U)
+/*! POL_4 - PWM channel 4 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_4(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_4_SHIFT)) & PWM_CTRL1_POL_4_MASK)
+#define PWM_CTRL1_POL_5_MASK                     (0x20U)
+#define PWM_CTRL1_POL_5_SHIFT                    (5U)
+/*! POL_5 - PWM channel 5 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_5(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_5_SHIFT)) & PWM_CTRL1_POL_5_MASK)
+#define PWM_CTRL1_POL_6_MASK                     (0x40U)
+#define PWM_CTRL1_POL_6_SHIFT                    (6U)
+/*! POL_6 - PWM channel 6 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_6(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_6_SHIFT)) & PWM_CTRL1_POL_6_MASK)
+#define PWM_CTRL1_POL_7_MASK                     (0x80U)
+#define PWM_CTRL1_POL_7_SHIFT                    (7U)
+/*! POL_7 - PWM channel 7 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_7(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_7_SHIFT)) & PWM_CTRL1_POL_7_MASK)
+#define PWM_CTRL1_POL_8_MASK                     (0x100U)
+#define PWM_CTRL1_POL_8_SHIFT                    (8U)
+/*! POL_8 - PWM channel 8 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_8(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_8_SHIFT)) & PWM_CTRL1_POL_8_MASK)
+#define PWM_CTRL1_POL_9_MASK                     (0x200U)
+#define PWM_CTRL1_POL_9_SHIFT                    (9U)
+/*! POL_9 - PWM channel 9 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_9(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_9_SHIFT)) & PWM_CTRL1_POL_9_MASK)
+#define PWM_CTRL1_POL_10_MASK                    (0x400U)
+#define PWM_CTRL1_POL_10_SHIFT                   (10U)
+/*! POL_10 - PWM channel 10 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_10(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_10_SHIFT)) & PWM_CTRL1_POL_10_MASK)
+#define PWM_CTRL1_DIS_LEVEL_0_MASK               (0x10000U)
+#define PWM_CTRL1_DIS_LEVEL_0_SHIFT              (16U)
+/*! DIS_LEVEL_0 - PWM channel 0 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_0(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_0_SHIFT)) & PWM_CTRL1_DIS_LEVEL_0_MASK)
+#define PWM_CTRL1_DIS_LEVEL_1_MASK               (0x20000U)
+#define PWM_CTRL1_DIS_LEVEL_1_SHIFT              (17U)
+/*! DIS_LEVEL_1 - PWM channel 1 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_1(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_1_SHIFT)) & PWM_CTRL1_DIS_LEVEL_1_MASK)
+#define PWM_CTRL1_DIS_LEVEL_2_MASK               (0x40000U)
+#define PWM_CTRL1_DIS_LEVEL_2_SHIFT              (18U)
+/*! DIS_LEVEL_2 - PWM channel 2 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_2(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_2_SHIFT)) & PWM_CTRL1_DIS_LEVEL_2_MASK)
+#define PWM_CTRL1_DIS_LEVEL_3_MASK               (0x80000U)
+#define PWM_CTRL1_DIS_LEVEL_3_SHIFT              (19U)
+/*! DIS_LEVEL_3 - PWM channel 3 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_3(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_3_SHIFT)) & PWM_CTRL1_DIS_LEVEL_3_MASK)
+#define PWM_CTRL1_DIS_LEVEL_4_MASK               (0x100000U)
+#define PWM_CTRL1_DIS_LEVEL_4_SHIFT              (20U)
+/*! DIS_LEVEL_4 - PWM channel 4 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_4(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_4_SHIFT)) & PWM_CTRL1_DIS_LEVEL_4_MASK)
+#define PWM_CTRL1_DIS_LEVEL_5_MASK               (0x200000U)
+#define PWM_CTRL1_DIS_LEVEL_5_SHIFT              (21U)
+/*! DIS_LEVEL_5 - PWM channel 5 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_5(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_5_SHIFT)) & PWM_CTRL1_DIS_LEVEL_5_MASK)
+#define PWM_CTRL1_DIS_LEVEL_6_MASK               (0x400000U)
+#define PWM_CTRL1_DIS_LEVEL_6_SHIFT              (22U)
+/*! DIS_LEVEL_6 - PWM channel 6 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_6(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_6_SHIFT)) & PWM_CTRL1_DIS_LEVEL_6_MASK)
+#define PWM_CTRL1_DIS_LEVEL_7_MASK               (0x800000U)
+#define PWM_CTRL1_DIS_LEVEL_7_SHIFT              (23U)
+/*! DIS_LEVEL_7 - PWM channel 7 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_7(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_7_SHIFT)) & PWM_CTRL1_DIS_LEVEL_7_MASK)
+#define PWM_CTRL1_DIS_LEVEL_8_MASK               (0x1000000U)
+#define PWM_CTRL1_DIS_LEVEL_8_SHIFT              (24U)
+/*! DIS_LEVEL_8 - PWM channel 8 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_8(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_8_SHIFT)) & PWM_CTRL1_DIS_LEVEL_8_MASK)
+#define PWM_CTRL1_DIS_LEVEL_9_MASK               (0x2000000U)
+#define PWM_CTRL1_DIS_LEVEL_9_SHIFT              (25U)
+/*! DIS_LEVEL_9 - PWM channel 9 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_9(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_9_SHIFT)) & PWM_CTRL1_DIS_LEVEL_9_MASK)
+/*! @} */
+
+/*! @name PSCL01 - PWM Channels 0 & 1 prescalers */
+/*! @{ */
+#define PWM_PSCL01_PSCL_0_MASK                   (0x3FFU)
+#define PWM_PSCL01_PSCL_0_SHIFT                  (0U)
+/*! PSCL_0 - PWM channel 0 prescaler. The output frequency equals to clk/(PSCL_0 + 1)
+ */
+#define PWM_PSCL01_PSCL_0(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL01_PSCL_0_SHIFT)) & PWM_PSCL01_PSCL_0_MASK)
+#define PWM_PSCL01_PSCL_1_MASK                   (0x3FF0000U)
+#define PWM_PSCL01_PSCL_1_SHIFT                  (16U)
+/*! PSCL_1 - PWM channel 1 prescaler. The output frequency equals to clk/(PSCL_1 + 1)
+ */
+#define PWM_PSCL01_PSCL_1(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL01_PSCL_1_SHIFT)) & PWM_PSCL01_PSCL_1_MASK)
+/*! @} */
+
+/*! @name PSCL23 - PWM Channels 2 & 3 prescalers */
+/*! @{ */
+#define PWM_PSCL23_PSCL_2_MASK                   (0x3FFU)
+#define PWM_PSCL23_PSCL_2_SHIFT                  (0U)
+/*! PSCL_2 - PWM channel 2 prescaler. The output frequency equals to clk/(PSCL_2 + 1)
+ */
+#define PWM_PSCL23_PSCL_2(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL23_PSCL_2_SHIFT)) & PWM_PSCL23_PSCL_2_MASK)
+#define PWM_PSCL23_PSCL_3_MASK                   (0x3FF0000U)
+#define PWM_PSCL23_PSCL_3_SHIFT                  (16U)
+/*! PSCL_3 - PWM channel 3 prescaler. The output frequency equals to clk/(PSCL_3 + 1)
+ */
+#define PWM_PSCL23_PSCL_3(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL23_PSCL_3_SHIFT)) & PWM_PSCL23_PSCL_3_MASK)
+/*! @} */
+
+/*! @name PSCL45 - PWM Channels 4 & 5 prescalers */
+/*! @{ */
+#define PWM_PSCL45_PSCL_4_MASK                   (0x3FFU)
+#define PWM_PSCL45_PSCL_4_SHIFT                  (0U)
+/*! PSCL_4 - PWM channel 4 prescaler. The output frequency equals to clk/(PSCL_4 + 1)
+ */
+#define PWM_PSCL45_PSCL_4(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL45_PSCL_4_SHIFT)) & PWM_PSCL45_PSCL_4_MASK)
+#define PWM_PSCL45_PSCL_5_MASK                   (0x3FF0000U)
+#define PWM_PSCL45_PSCL_5_SHIFT                  (16U)
+/*! PSCL_5 - PWM channel 5 prescaler. The output frequency equals to clk/(PSCL_5 + 1)
+ */
+#define PWM_PSCL45_PSCL_5(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL45_PSCL_5_SHIFT)) & PWM_PSCL45_PSCL_5_MASK)
+/*! @} */
+
+/*! @name PSCL67 - PWM Channels 6 & 7 prescalers */
+/*! @{ */
+#define PWM_PSCL67_PSCL_6_MASK                   (0x3FFU)
+#define PWM_PSCL67_PSCL_6_SHIFT                  (0U)
+/*! PSCL_6 - PWM channel 6 prescaler. The output frequency equals to clk/(PSCL_6 + 1)
+ */
+#define PWM_PSCL67_PSCL_6(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL67_PSCL_6_SHIFT)) & PWM_PSCL67_PSCL_6_MASK)
+#define PWM_PSCL67_PSCL_7_MASK                   (0x3FF0000U)
+#define PWM_PSCL67_PSCL_7_SHIFT                  (16U)
+/*! PSCL_7 - PWM channel 7 prescaler. The output frequency equals to clk/(PSCL_7 + 1)
+ */
+#define PWM_PSCL67_PSCL_7(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL67_PSCL_7_SHIFT)) & PWM_PSCL67_PSCL_7_MASK)
+/*! @} */
+
+/*! @name PSCL89 - PWM Channels 8 & 9 prescalers */
+/*! @{ */
+#define PWM_PSCL89_PSCL_8_MASK                   (0x3FFU)
+#define PWM_PSCL89_PSCL_8_SHIFT                  (0U)
+/*! PSCL_8 - PWM channel 8 prescaler. The output frequency equals to clk/(PSCL_8 + 1)
+ */
+#define PWM_PSCL89_PSCL_8(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL89_PSCL_8_SHIFT)) & PWM_PSCL89_PSCL_8_MASK)
+#define PWM_PSCL89_PSCL_9_MASK                   (0x3FF0000U)
+#define PWM_PSCL89_PSCL_9_SHIFT                  (16U)
+/*! PSCL_9 - PWM channel 9 prescaler. The output frequency equals to clk/(PSCL_9 + 1)
+ */
+#define PWM_PSCL89_PSCL_9(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL89_PSCL_9_SHIFT)) & PWM_PSCL89_PSCL_9_MASK)
+/*! @} */
+
+/*! @name PSCL1011 - PWM Channel 10 prescaler */
+/*! @{ */
+#define PWM_PSCL1011_PSCL_10_MASK                (0x3FFU)
+#define PWM_PSCL1011_PSCL_10_SHIFT               (0U)
+/*! PSCL_10 - PWM channel 10 prescaler. The output frequency equals to clk/(PSCL_10 + 1)
+ */
+#define PWM_PSCL1011_PSCL_10(x)                  (((uint32_t)(((uint32_t)(x)) << PWM_PSCL1011_PSCL_10_SHIFT)) & PWM_PSCL1011_PSCL_10_MASK)
+/*! @} */
+
+/*! @name PCP0 - PWM Channel 0 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP0_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP0_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 0 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP0_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP0_PERIOD_SHIFT)) & PWM_PCP0_PERIOD_MASK)
+#define PWM_PCP0_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP0_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 0 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP0_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP0_COMPARE_SHIFT)) & PWM_PCP0_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP1 - PWM Channel 1 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP1_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP1_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 1 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP1_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP1_PERIOD_SHIFT)) & PWM_PCP1_PERIOD_MASK)
+#define PWM_PCP1_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP1_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 1 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP1_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP1_COMPARE_SHIFT)) & PWM_PCP1_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP2 - PWM Channel 2 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP2_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP2_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 2 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP2_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP2_PERIOD_SHIFT)) & PWM_PCP2_PERIOD_MASK)
+#define PWM_PCP2_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP2_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 2 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP2_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP2_COMPARE_SHIFT)) & PWM_PCP2_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP3 - PWM Channel 3 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP3_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP3_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 3 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP3_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP3_PERIOD_SHIFT)) & PWM_PCP3_PERIOD_MASK)
+#define PWM_PCP3_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP3_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 3 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP3_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP3_COMPARE_SHIFT)) & PWM_PCP3_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP4 - PWM Channel 4 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP4_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP4_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 4 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP4_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP4_PERIOD_SHIFT)) & PWM_PCP4_PERIOD_MASK)
+#define PWM_PCP4_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP4_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 4 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP4_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP4_COMPARE_SHIFT)) & PWM_PCP4_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP5 - PWM Channel 5 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP5_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP5_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 5 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP5_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP5_PERIOD_SHIFT)) & PWM_PCP5_PERIOD_MASK)
+#define PWM_PCP5_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP5_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 5 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP5_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP5_COMPARE_SHIFT)) & PWM_PCP5_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP6 - PWM Channel 6 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP6_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP6_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 6 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP6_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP6_PERIOD_SHIFT)) & PWM_PCP6_PERIOD_MASK)
+#define PWM_PCP6_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP6_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 6 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP6_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP6_COMPARE_SHIFT)) & PWM_PCP6_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP7 - PWM Channel 7 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP7_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP7_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 7 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP7_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP7_PERIOD_SHIFT)) & PWM_PCP7_PERIOD_MASK)
+#define PWM_PCP7_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP7_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 7 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP7_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP7_COMPARE_SHIFT)) & PWM_PCP7_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP8 - PWM Channel 8 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP8_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP8_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 8 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP8_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP8_PERIOD_SHIFT)) & PWM_PCP8_PERIOD_MASK)
+#define PWM_PCP8_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP8_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 8 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP8_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP8_COMPARE_SHIFT)) & PWM_PCP8_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP9 - PWM Channel 9 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP9_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP9_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 9 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP9_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP9_PERIOD_SHIFT)) & PWM_PCP9_PERIOD_MASK)
+#define PWM_PCP9_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP9_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 9 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP9_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP9_COMPARE_SHIFT)) & PWM_PCP9_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP10 - PWM Channel 10 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached all PWM outputs will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP10_PERIOD_MASK                    (0xFFFFU)
+#define PWM_PCP10_PERIOD_SHIFT                   (0U)
+/*! PERIOD - PWM channel 10 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP10_PERIOD(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP10_PERIOD_SHIFT)) & PWM_PCP10_PERIOD_MASK)
+#define PWM_PCP10_COMPARE_MASK                   (0xFFFF0000U)
+#define PWM_PCP10_COMPARE_SHIFT                  (16U)
+/*! COMPARE - PWM channel 10 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP10_COMPARE(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PCP10_COMPARE_SHIFT)) & PWM_PCP10_COMPARE_MASK)
+/*! @} */
+
+/*! @name PST0 - PWM 1st Status Register (Channel 0 to Channel 3) */
+/*! @{ */
+#define PWM_PST0_INT_FLG_0_MASK                  (0x1U)
+#define PWM_PST0_INT_FLG_0_SHIFT                 (0U)
+/*! INT_FLG_0 - PWM channel 0 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST0_INT_FLG_0(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST0_INT_FLG_0_SHIFT)) & PWM_PST0_INT_FLG_0_MASK)
+#define PWM_PST0_INT_FLG_1_MASK                  (0x100U)
+#define PWM_PST0_INT_FLG_1_SHIFT                 (8U)
+/*! INT_FLG_1 - PWM channel 1 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST0_INT_FLG_1(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST0_INT_FLG_1_SHIFT)) & PWM_PST0_INT_FLG_1_MASK)
+#define PWM_PST0_INT_FLG_2_MASK                  (0x10000U)
+#define PWM_PST0_INT_FLG_2_SHIFT                 (16U)
+/*! INT_FLG_2 - PWM channel 2 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST0_INT_FLG_2(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST0_INT_FLG_2_SHIFT)) & PWM_PST0_INT_FLG_2_MASK)
+#define PWM_PST0_INT_FLG_3_MASK                  (0x1000000U)
+#define PWM_PST0_INT_FLG_3_SHIFT                 (24U)
+/*! INT_FLG_3 - PWM channel 3 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST0_INT_FLG_3(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST0_INT_FLG_3_SHIFT)) & PWM_PST0_INT_FLG_3_MASK)
+/*! @} */
+
+/*! @name PST1 - PWM 2nd Status Register (Channel 4 to Channel 7) */
+/*! @{ */
+#define PWM_PST1_INT_FLG_4_MASK                  (0x1U)
+#define PWM_PST1_INT_FLG_4_SHIFT                 (0U)
+/*! INT_FLG_4 - PWM channel 4 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST1_INT_FLG_4(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST1_INT_FLG_4_SHIFT)) & PWM_PST1_INT_FLG_4_MASK)
+#define PWM_PST1_INT_FLG_5_MASK                  (0x100U)
+#define PWM_PST1_INT_FLG_5_SHIFT                 (8U)
+/*! INT_FLG_5 - PWM channel 5 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST1_INT_FLG_5(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST1_INT_FLG_5_SHIFT)) & PWM_PST1_INT_FLG_5_MASK)
+#define PWM_PST1_INT_FLG_6_MASK                  (0x10000U)
+#define PWM_PST1_INT_FLG_6_SHIFT                 (16U)
+/*! INT_FLG_6 - PWM channel 6 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST1_INT_FLG_6(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST1_INT_FLG_6_SHIFT)) & PWM_PST1_INT_FLG_6_MASK)
+#define PWM_PST1_INT_FLG_7_MASK                  (0x1000000U)
+#define PWM_PST1_INT_FLG_7_SHIFT                 (24U)
+/*! INT_FLG_7 - PWM channel 7 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST1_INT_FLG_7(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST1_INT_FLG_7_SHIFT)) & PWM_PST1_INT_FLG_7_MASK)
+/*! @} */
+
+/*! @name PST2 - PWM 3rd Status Register (Channel 8 to Channel 10) */
+/*! @{ */
+#define PWM_PST2_INT_FLG_8_MASK                  (0x1U)
+#define PWM_PST2_INT_FLG_8_SHIFT                 (0U)
+/*! INT_FLG_8 - PWM channel 8 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST2_INT_FLG_8(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST2_INT_FLG_8_SHIFT)) & PWM_PST2_INT_FLG_8_MASK)
+#define PWM_PST2_INT_FLG_9_MASK                  (0x100U)
+#define PWM_PST2_INT_FLG_9_SHIFT                 (8U)
+/*! INT_FLG_9 - PWM channel 9 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST2_INT_FLG_9(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST2_INT_FLG_9_SHIFT)) & PWM_PST2_INT_FLG_9_MASK)
+#define PWM_PST2_INT_FLG_10_MASK                 (0x10000U)
+#define PWM_PST2_INT_FLG_10_SHIFT                (16U)
+/*! INT_FLG_10 - PWM channel 10 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST2_INT_FLG_10(x)                   (((uint32_t)(((uint32_t)(x)) << PWM_PST2_INT_FLG_10_SHIFT)) & PWM_PST2_INT_FLG_10_MASK)
+/*! @} */
+
+/*! @name MODULE_ID - PWM Module Identifier ('PW' in ASCII) */
+/*! @{ */
+#define PWM_MODULE_ID_APERTURE_MASK              (0xFFU)
+#define PWM_MODULE_ID_APERTURE_SHIFT             (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define PWM_MODULE_ID_APERTURE(x)                (((uint32_t)(((uint32_t)(x)) << PWM_MODULE_ID_APERTURE_SHIFT)) & PWM_MODULE_ID_APERTURE_MASK)
+#define PWM_MODULE_ID_MIN_REV_MASK               (0xF00U)
+#define PWM_MODULE_ID_MIN_REV_SHIFT              (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define PWM_MODULE_ID_MIN_REV(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_MODULE_ID_MIN_REV_SHIFT)) & PWM_MODULE_ID_MIN_REV_MASK)
+#define PWM_MODULE_ID_MAJ_REV_MASK               (0xF000U)
+#define PWM_MODULE_ID_MAJ_REV_SHIFT              (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define PWM_MODULE_ID_MAJ_REV(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_MODULE_ID_MAJ_REV_SHIFT)) & PWM_MODULE_ID_MAJ_REV_MASK)
+#define PWM_MODULE_ID_ID_MASK                    (0xFFFF0000U)
+#define PWM_MODULE_ID_ID_SHIFT                   (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define PWM_MODULE_ID_ID(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_MODULE_ID_ID_SHIFT)) & PWM_MODULE_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group PWM_Register_Masks */
+
+
+/* PWM - Peripheral instance base addresses */
+/** Peripheral PWM base address */
+#define PWM_BASE                                 (0x4000C000u)
+/** Peripheral PWM base pointer */
+#define PWM                                      ((PWM_Type *)PWM_BASE)
+/** Array initializer of PWM peripheral base addresses */
+#define PWM_BASE_ADDRS                           { PWM_BASE }
+/** Array initializer of PWM peripheral base pointers */
+#define PWM_BASE_PTRS                            { PWM }
+/** Interrupt vectors for the PWM peripheral type */
+#define PWM_IRQS                                 { PWM0_IRQn, PWM1_IRQn, PWM2_IRQn, PWM3_IRQn, PWM4_IRQn, PWM5_IRQn, PWM6_IRQn, PWM7_IRQn, PWM8_IRQn, PWM9_IRQn, PWM10_IRQn }
+
+/*!
+ * @}
+ */ /* end of group PWM_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- RNG Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup RNG_Peripheral_Access_Layer RNG Peripheral Access Layer
+ * @{
+ */
+
+/** RNG - Register Layout Typedef */
+typedef struct {
+  __I  uint32_t RANDOM_NUMBER;                     /**< Random number, offset: 0x0 */
+       uint8_t RESERVED_0[4];
+  __I  uint32_t COUNTER_VAL;                       /**< Counter values to show information about the random process, offset: 0x8 */
+  __IO uint32_t COUNTER_CFG;                       /**< Register linked to the comupting of statistics, not required for normal operation., offset: 0xC */
+  __IO uint32_t ONLINE_TEST_CFG;                   /**< Configuration for the online test features, offset: 0x10 */
+  __I  uint32_t ONLINE_TEST_VAL;                   /**< Online test results, offset: 0x14 */
+       uint8_t RESERVED_1[4060];
+  __IO uint32_t POWERDOWN;                         /**< Powerdown mode and reset control, generally use of this register is not necessary, offset: 0xFF4 */
+       uint8_t RESERVED_2[4];
+  __I  uint32_t MODULEID;                          /**< IP identifier, offset: 0xFFC */
+} RNG_Type;
+
+/* ----------------------------------------------------------------------------
+   -- RNG Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup RNG_Register_Masks RNG Register Masks
+ * @{
+ */
+
+/*! @name RANDOM_NUMBER - Random number */
+/*! @{ */
+#define RNG_RANDOM_NUMBER_RAND_NUM_MASK          (0xFFFFFFFFU)
+#define RNG_RANDOM_NUMBER_RAND_NUM_SHIFT         (0U)
+/*! RAND_NUM - This register contains a random 32 bit number which is computed on demand, at each
+ *    time it is read. Weak cryptographic post-processing is used to maximize throughput. The block
+ *    will start computing before the first register access and so the reset value is not relevant.
+ */
+#define RNG_RANDOM_NUMBER_RAND_NUM(x)            (((uint32_t)(((uint32_t)(x)) << RNG_RANDOM_NUMBER_RAND_NUM_SHIFT)) & RNG_RANDOM_NUMBER_RAND_NUM_MASK)
+/*! @} */
+
+/*! @name COUNTER_VAL - Counter values to show information about the random process */
+/*! @{ */
+#define RNG_COUNTER_VAL_CLK_RATIO_MASK           (0xFFU)
+#define RNG_COUNTER_VAL_CLK_RATIO_SHIFT          (0U)
+/*! CLK_RATIO - Gives the ratio between the internal clocks frequencies and the register clock
+ *    frequency for evaluation and certification purposes. Internal clock frequencies are half the
+ *    incoming ones: COUNTER_VAL = round[ (intFreq/2)/regFreq*256*(1<<(4*shift4x)) ] MODULO 256 If
+ *    shitf4x==0, intFreq ~= regFreq*COUNTER_VAL/256*2 Use clock_sel to select which clock you want to
+ *    measure, in this range: 1..5
+ */
+#define RNG_COUNTER_VAL_CLK_RATIO(x)             (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_VAL_CLK_RATIO_SHIFT)) & RNG_COUNTER_VAL_CLK_RATIO_MASK)
+#define RNG_COUNTER_VAL_REFRESH_CNT_MASK         (0x1F00U)
+#define RNG_COUNTER_VAL_REFRESH_CNT_SHIFT        (8U)
+/*! REFRESH_CNT - Incremented (till max possible value) each time COUNTER was updated since last
+ *    reading to any *_NUMBER. This gives an indication on 'entropy refill'. Note that there is no
+ *    linear accumulation of entropy: as implemented today, entropy refill will be about 4 bits each
+ *    time 'refresh_cnt' reaches its maximum value. See user manual for further details on how to
+ *    benefit from linear entropy accumulation using a specific procedure.
+ */
+#define RNG_COUNTER_VAL_REFRESH_CNT(x)           (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_VAL_REFRESH_CNT_SHIFT)) & RNG_COUNTER_VAL_REFRESH_CNT_MASK)
+/*! @} */
+
+/*! @name COUNTER_CFG - Register linked to the comupting of statistics, not required for normal operation. */
+/*! @{ */
+#define RNG_COUNTER_CFG_MODE_MASK                (0x3U)
+#define RNG_COUNTER_CFG_MODE_SHIFT               (0U)
+/*! MODE - 00: disabled 01: update once. Will return to 00 once done 10: free running: updates countinuously 11: reserved
+ */
+#define RNG_COUNTER_CFG_MODE(x)                  (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_CFG_MODE_SHIFT)) & RNG_COUNTER_CFG_MODE_MASK)
+#define RNG_COUNTER_CFG_CLOCK_SEL_MASK           (0x1CU)
+#define RNG_COUNTER_CFG_CLOCK_SEL_SHIFT          (2U)
+/*! CLOCK_SEL - Selects the internal clock on which to compute statistics. 1 is for first one, 2 for
+ *    second one, . And 0 is for a XOR of results from all clocks
+ */
+#define RNG_COUNTER_CFG_CLOCK_SEL(x)             (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_CFG_CLOCK_SEL_SHIFT)) & RNG_COUNTER_CFG_CLOCK_SEL_MASK)
+#define RNG_COUNTER_CFG_SHIFT4X_MASK             (0xE0U)
+#define RNG_COUNTER_CFG_SHIFT4X_SHIFT            (5U)
+/*! SHIFT4X - To be used to add precision to clock_ratio and determine 'entropy refill'. Supported
+ *    range is 0..4 Used as well for ONLINE_TEST
+ */
+#define RNG_COUNTER_CFG_SHIFT4X(x)               (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_CFG_SHIFT4X_SHIFT)) & RNG_COUNTER_CFG_SHIFT4X_MASK)
+/*! @} */
+
+/*! @name ONLINE_TEST_CFG - Configuration for the online test features */
+/*! @{ */
+#define RNG_ONLINE_TEST_CFG_ACTIVATE_MASK        (0x1U)
+#define RNG_ONLINE_TEST_CFG_ACTIVATE_SHIFT       (0U)
+/*! ACTIVATE - 0: disabled 1: activated Update rhythm for VAL depends on COUNTER_CFG if data_sel is
+ *    set to COUNTER. Otherwise VAL is updated each time RANDOM_NUMBER is read
+ */
+#define RNG_ONLINE_TEST_CFG_ACTIVATE(x)          (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_CFG_ACTIVATE_SHIFT)) & RNG_ONLINE_TEST_CFG_ACTIVATE_MASK)
+#define RNG_ONLINE_TEST_CFG_DATA_SEL_MASK        (0x6U)
+#define RNG_ONLINE_TEST_CFG_DATA_SEL_SHIFT       (1U)
+/*! DATA_SEL - Selects source on which to apply online test: 00: LSB of COUNTER: raw data from one
+ *    or all sources of entropy 01: MSB of COUNTER: raw data from one or all sources of entropy (do
+ *    not use) 10: RANDOM_NUMBER 11: not valid 'activate' should be set to 'disabled' before changing
+ *    this field
+ */
+#define RNG_ONLINE_TEST_CFG_DATA_SEL(x)          (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_CFG_DATA_SEL_SHIFT)) & RNG_ONLINE_TEST_CFG_DATA_SEL_MASK)
+/*! @} */
+
+/*! @name ONLINE_TEST_VAL - Online test results */
+/*! @{ */
+#define RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED_MASK (0xFU)
+#define RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED_SHIFT (0U)
+/*! LIVE_CHI_SQUARED - This value is updated as described in field 'activate'. This value is a
+ *    statistic value that indicates the quality of entropy generation. Low value means good, high value
+ *    means no good. If 'data_sel'<10, increase 'shift4x' till 'chi' is correct and poll
+ *    'refresh_cnt' before reading RANDOM_NUMBER.
+ */
+#define RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED(x)  (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED_SHIFT)) & RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED_MASK)
+#define RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED_MASK (0xF0U)
+#define RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED_SHIFT (4U)
+/*! MIN_CHI_SQUARED - Minimum value of LIVE_CHI_SQUARED since the last reset of this field. This field is reset when 'activate'=0
+ */
+#define RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED(x)   (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED_SHIFT)) & RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED_MASK)
+#define RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED_MASK (0xF00U)
+#define RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED_SHIFT (8U)
+/*! MAX_CHI_SQUARED - Maximum value of LIVE_CHI_SQUARED since the last reset of this field. This field is reset when 'activate'=0
+ */
+#define RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED(x)   (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED_SHIFT)) & RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED_MASK)
+/*! @} */
+
+/*! @name POWERDOWN - Powerdown mode and reset control, generally use of this register is not necessary */
+/*! @{ */
+#define RNG_POWERDOWN_SOFT_RESET_MASK            (0x1U)
+#define RNG_POWERDOWN_SOFT_RESET_SHIFT           (0U)
+/*! SOFT_RESET - Request softreset that will go low automaticaly after acknowledge from CORE
+ */
+#define RNG_POWERDOWN_SOFT_RESET(x)              (((uint32_t)(((uint32_t)(x)) << RNG_POWERDOWN_SOFT_RESET_SHIFT)) & RNG_POWERDOWN_SOFT_RESET_MASK)
+#define RNG_POWERDOWN_FORCE_SOFT_RESET_MASK      (0x2U)
+#define RNG_POWERDOWN_FORCE_SOFT_RESET_SHIFT     (1U)
+/*! FORCE_SOFT_RESET - When used with softreset it forces CORE_RESETN to low on acknowledge from CORE
+ */
+#define RNG_POWERDOWN_FORCE_SOFT_RESET(x)        (((uint32_t)(((uint32_t)(x)) << RNG_POWERDOWN_FORCE_SOFT_RESET_SHIFT)) & RNG_POWERDOWN_FORCE_SOFT_RESET_MASK)
+#define RNG_POWERDOWN_POWERDOWN_MASK             (0x80000000U)
+#define RNG_POWERDOWN_POWERDOWN_SHIFT            (31U)
+/*! POWERDOWN - When set all accesses to standard registers are blocked
+ */
+#define RNG_POWERDOWN_POWERDOWN(x)               (((uint32_t)(((uint32_t)(x)) << RNG_POWERDOWN_POWERDOWN_SHIFT)) & RNG_POWERDOWN_POWERDOWN_MASK)
+/*! @} */
+
+/*! @name MODULEID - IP identifier */
+/*! @{ */
+#define RNG_MODULEID_APERTURE_MASK               (0xFFU)
+#define RNG_MODULEID_APERTURE_SHIFT              (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define RNG_MODULEID_APERTURE(x)                 (((uint32_t)(((uint32_t)(x)) << RNG_MODULEID_APERTURE_SHIFT)) & RNG_MODULEID_APERTURE_MASK)
+#define RNG_MODULEID_MIN_REV_MASK                (0xF00U)
+#define RNG_MODULEID_MIN_REV_SHIFT               (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define RNG_MODULEID_MIN_REV(x)                  (((uint32_t)(((uint32_t)(x)) << RNG_MODULEID_MIN_REV_SHIFT)) & RNG_MODULEID_MIN_REV_MASK)
+#define RNG_MODULEID_MAJ_REV_MASK                (0xF000U)
+#define RNG_MODULEID_MAJ_REV_SHIFT               (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define RNG_MODULEID_MAJ_REV(x)                  (((uint32_t)(((uint32_t)(x)) << RNG_MODULEID_MAJ_REV_SHIFT)) & RNG_MODULEID_MAJ_REV_MASK)
+#define RNG_MODULEID_ID_MASK                     (0xFFFF0000U)
+#define RNG_MODULEID_ID_SHIFT                    (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define RNG_MODULEID_ID(x)                       (((uint32_t)(((uint32_t)(x)) << RNG_MODULEID_ID_SHIFT)) & RNG_MODULEID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group RNG_Register_Masks */
+
+
+/* RNG - Peripheral instance base addresses */
+/** Peripheral RNG base address */
+#define RNG_BASE                                 (0x4000D000u)
+/** Peripheral RNG base pointer */
+#define RNG                                      ((RNG_Type *)RNG_BASE)
+/** Array initializer of RNG peripheral base addresses */
+#define RNG_BASE_ADDRS                           { RNG_BASE }
+/** Array initializer of RNG peripheral base pointers */
+#define RNG_BASE_PTRS                            { RNG }
+
+/*!
+ * @}
+ */ /* end of group RNG_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- RTC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup RTC_Peripheral_Access_Layer RTC Peripheral Access Layer
+ * @{
+ */
+
+/** RTC - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< RTC control register, offset: 0x0 */
+  __IO uint32_t MATCH;                             /**< RTC 32-bit counter match register, offset: 0x4 */
+  __IO uint32_t COUNT;                             /**< RTC 32-bit counter register, offset: 0x8 */
+  __IO uint32_t WAKE;                              /**< 16-bit RTC timer register, offset: 0xC */
+} RTC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- RTC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup RTC_Register_Masks RTC Register Masks
+ * @{
+ */
+
+/*! @name CTRL - RTC control register */
+/*! @{ */
+#define RTC_CTRL_SWRESET_MASK                    (0x1U)
+#define RTC_CTRL_SWRESET_SHIFT                   (0U)
+/*! SWRESET - Software reset control. 0: Not in reset. The RTC is not held in reset. This bit must
+ *    be cleared prior to configuring or initiating any operation of the RTC. 1: In reset. The RTC is
+ *    held in reset. All register bits within the RTC will be forced to their reset value except
+ *    the OFD bit. This bit must be cleared before writing to any register in the RTC - including
+ *    writes to set any of the other bits within this register. Do not attempt to write to any bits of
+ *    this register at the same time that the reset bit is being cleared.
+ */
+#define RTC_CTRL_SWRESET(x)                      (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_SWRESET_SHIFT)) & RTC_CTRL_SWRESET_MASK)
+#define RTC_CTRL_ALARM1HZ_MASK                   (0x4U)
+#define RTC_CTRL_ALARM1HZ_SHIFT                  (2U)
+/*! ALARM1HZ - RTC 32-bit timer alarm flag status. 0: No match has occurred on the 32-bit RTC timer.
+ *    Writing a 0 has no effect. 1: A match condition has occurred on the 32-bit RTC timer. This
+ *    flag generates an RTC alarm interrupt request. RTC_ALARM which can also wake up the part from
+ *    low power modes (excluding deep power down mode). Writing a 1 clears this bit.
+ */
+#define RTC_CTRL_ALARM1HZ(x)                     (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARM1HZ_SHIFT)) & RTC_CTRL_ALARM1HZ_MASK)
+#define RTC_CTRL_WAKE1KHZ_MASK                   (0x8U)
+#define RTC_CTRL_WAKE1KHZ_SHIFT                  (3U)
+/*! WAKE1KHZ - RTC 16-bit timer wake-up flag status. 0: The RTC 16-bit timer is running. Writing a 0
+ *    has no effect. 1: The 16-bit timer has timed out. This flag generates an RTC wake-up
+ *    interrupt request RTC-WAKE which can also wake up the part from low power modes (excluding deep power
+ *    down mode). Writing a 1 clears this bit.
+ */
+#define RTC_CTRL_WAKE1KHZ(x)                     (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKE1KHZ_SHIFT)) & RTC_CTRL_WAKE1KHZ_MASK)
+#define RTC_CTRL_ALARMDPD_EN_MASK                (0x10U)
+#define RTC_CTRL_ALARMDPD_EN_SHIFT               (4U)
+/*! ALARMDPD_EN - RTC 32-bit timer alarm enable for Low power mode. 0: Disable. A match on the
+ *    32-bit RTC timer will not bring the part out of power-down modes. 1: Enable. A match on the 32-bit
+ *    RTC timer will bring the part out of power-down modes.
+ */
+#define RTC_CTRL_ALARMDPD_EN(x)                  (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARMDPD_EN_SHIFT)) & RTC_CTRL_ALARMDPD_EN_MASK)
+#define RTC_CTRL_WAKEDPD_EN_MASK                 (0x20U)
+#define RTC_CTRL_WAKEDPD_EN_SHIFT                (5U)
+/*! WAKEDPD_EN - RTC 16-bit timer wake-up enable for power-down modes. 0: Disable. A match on the
+ *    16-bit RTC timer will not bring the part out of power-down modes. 1: Enable. A match on the
+ *    16-bit RTC timer will bring the part out of power-down modes.
+ */
+#define RTC_CTRL_WAKEDPD_EN(x)                   (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKEDPD_EN_SHIFT)) & RTC_CTRL_WAKEDPD_EN_MASK)
+#define RTC_CTRL_RTC1KHZ_EN_MASK                 (0x40U)
+#define RTC_CTRL_RTC1KHZ_EN_SHIFT                (6U)
+/*! RTC1KHZ_EN - RTC 16-bit timer clock enable. This bit can be set to 0 to conserve power if the
+ *    16-bit timer is not used. This bit has no effect when the RTC is disabled (bit 7 of this
+ *    register is 0). 0: Disable. A match on the 16-bit RTC timer will not bring the part out of Deep
+ *    power-down mode. 1: Enable. The 16-bit RTC timer is enabled.
+ */
+#define RTC_CTRL_RTC1KHZ_EN(x)                   (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC1KHZ_EN_SHIFT)) & RTC_CTRL_RTC1KHZ_EN_MASK)
+#define RTC_CTRL_RTC_EN_MASK                     (0x80U)
+#define RTC_CTRL_RTC_EN_SHIFT                    (7U)
+/*! RTC_EN - RTC enable. 0: Disable. The RTC 32-bit timer and 16-bit timer clocks are shut down and
+ *    the RTC operation is disabled. This bit should be 0 when writing to load a value in the RTC
+ *    counter register. 1: Enable. The 32-bit RTC clock is running and RTC operation is enabled. This
+ *    bit must be set to initiate operation of the RTC. To also enable the 16-bit timer clock, set
+ *    bit 6 in this register.
+ */
+#define RTC_CTRL_RTC_EN(x)                       (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC_EN_SHIFT)) & RTC_CTRL_RTC_EN_MASK)
+/*! @} */
+
+/*! @name MATCH - RTC 32-bit counter match register */
+/*! @{ */
+#define RTC_MATCH_MATVAL_MASK                    (0xFFFFFFFFU)
+#define RTC_MATCH_MATVAL_SHIFT                   (0U)
+/*! MATVAL - Contains the match value against which the 1 Hz RTC timer will be compared to generate
+ *    the alarm flag RTC_ALARM and generate an alarm interrupt/wake-up if enabled.
+ */
+#define RTC_MATCH_MATVAL(x)                      (((uint32_t)(((uint32_t)(x)) << RTC_MATCH_MATVAL_SHIFT)) & RTC_MATCH_MATVAL_MASK)
+/*! @} */
+
+/*! @name COUNT - RTC 32-bit counter register */
+/*! @{ */
+#define RTC_COUNT_VAL_MASK                       (0xFFFFFFFFU)
+#define RTC_COUNT_VAL_SHIFT                      (0U)
+/*! VAL - A read reflects the current value of the main, 32-bit, RTC timer. A write loads a new
+ *    initial value into the timer. The RTC 32-bit counter will count up continuously at the 32-bit
+ *    timer clock rate once the RTC Software Reset is removed (by clearing bit 0 of the CTRL register).
+ *    Remark: Only write to this register when the RTC_EN bit in the RTC CTRL Register is 0.
+ */
+#define RTC_COUNT_VAL(x)                         (((uint32_t)(((uint32_t)(x)) << RTC_COUNT_VAL_SHIFT)) & RTC_COUNT_VAL_MASK)
+/*! @} */
+
+/*! @name WAKE - 16-bit RTC timer register */
+/*! @{ */
+#define RTC_WAKE_VAL_MASK                        (0xFFFFU)
+#define RTC_WAKE_VAL_SHIFT                       (0U)
+/*! VAL - A read reflects the current value of 16-bit timer. A write pre-loads a start count value
+ *    into the 16-bit timer and initializes a count-down sequence. Do not write to this register
+ *    while counting is in progress.
+ */
+#define RTC_WAKE_VAL(x)                          (((uint32_t)(((uint32_t)(x)) << RTC_WAKE_VAL_SHIFT)) & RTC_WAKE_VAL_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group RTC_Register_Masks */
+
+
+/* RTC - Peripheral instance base addresses */
+/** Peripheral RTC base address */
+#define RTC_BASE                                 (0x4000B000u)
+/** Peripheral RTC base pointer */
+#define RTC                                      ((RTC_Type *)RTC_BASE)
+/** Array initializer of RTC peripheral base addresses */
+#define RTC_BASE_ADDRS                           { RTC_BASE }
+/** Array initializer of RTC peripheral base pointers */
+#define RTC_BASE_PTRS                            { RTC }
+/** Interrupt vectors for the RTC peripheral type */
+#define RTC_IRQS                                 { RTC_IRQn }
+
+/*!
+ * @}
+ */ /* end of group RTC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- SHA Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SHA_Peripheral_Access_Layer SHA Peripheral Access Layer
+ * @{
+ */
+
+/** SHA - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< Control register, offset: 0x0 */
+  __I  uint32_t STATUS;                            /**< Status Regsiter, offset: 0x4 */
+  __IO uint32_t INTENSET;                          /**< Interrupt Enable and Interrupt enable set function, offset: 0x8 */
+  __O  uint32_t INTENCLR;                          /**< Interrupt Clear Register, offset: 0xC */
+  __IO uint32_t MEMCTRL;                           /**< Setup Master to access memory, offset: 0x10 */
+  __IO uint32_t MEMADDR;                           /**< Address to start memory access from, offset: 0x14 */
+       uint8_t RESERVED_0[8];
+  __IO uint32_t INDATA[8];                         /**< Input Data register, array offset: 0x20, array step: 0x4 */
+  __I  uint32_t DIGEST[8];                         /**< DIGEST or OUTD0, 5 or 8 bytes of output data, depending upon mode, array offset: 0x40, array step: 0x4 */
+       uint8_t RESERVED_1[48];
+  __IO uint32_t MASK;                              /**< Mask register, offset: 0x90 */
+       uint8_t RESERVED_2[3944];
+  __I  uint32_t ID;                                /**< IP identifier, offset: 0xFFC */
+} SHA_Type;
+
+/* ----------------------------------------------------------------------------
+   -- SHA Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SHA_Register_Masks SHA Register Masks
+ * @{
+ */
+
+/*! @name CTRL - Control register */
+/*! @{ */
+#define SHA_CTRL_MODE_MASK                       (0x7U)
+#define SHA_CTRL_MODE_SHIFT                      (0U)
+/*! MODE - Operational mode: 0: Disabled; 1: SHA1; 2: SHA2-256; 3: SHA2-512; 4-7: Not valid
+ */
+#define SHA_CTRL_MODE(x)                         (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_MODE_SHIFT)) & SHA_CTRL_MODE_MASK)
+#define SHA_CTRL_NEW_MASK                        (0x10U)
+#define SHA_CTRL_NEW_SHIFT                       (4U)
+/*! NEW - Written with 1 when starting a new Hash. It self clears. Note that the WAITING Status bit
+ *    will clear for a cycle during the initialization from New=1. Digest/Result is initialized when
+ *    New is set to 1.
+ */
+#define SHA_CTRL_NEW(x)                          (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_NEW_SHIFT)) & SHA_CTRL_NEW_MASK)
+#define SHA_CTRL_DMA_I_MASK                      (0x100U)
+#define SHA_CTRL_DMA_I_SHIFT                     (8U)
+/*! DMA_I - Written with 1 to use DMA to fill INDATA. For Hash, will request from DMA for 16 words
+ *    and then will process the Hash. Normal model is that the DMA interrupts the processor when its
+ *    length expires.
+ */
+#define SHA_CTRL_DMA_I(x)                        (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_DMA_I_SHIFT)) & SHA_CTRL_DMA_I_MASK)
+#define SHA_CTRL_DMA_O_MASK                      (0x200U)
+#define SHA_CTRL_DMA_O_SHIFT                     (9U)
+/*! DMA_O - Written to 1 to use DMA to drain the digest/output. If both DMA_I and DMA_O are set, the
+ *    DMA has to know to switch direction and the locations. If written to 0 the DMA is not used
+ *    and the processor has to read the digest/output in response to the DIGEST interrupt.
+ */
+#define SHA_CTRL_DMA_O(x)                        (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_DMA_O_SHIFT)) & SHA_CTRL_DMA_O_MASK)
+#define SHA_CTRL_HASHSWPB_MASK                   (0x1000U)
+#define SHA_CTRL_HASHSWPB_SHIFT                  (12U)
+/*! HASHSWPB - If 1, will swap bytes in the word for SHA hashing. The default is byte order (so LSB
+ *    is first byte) but this allows swapping to MSB is first.
+ */
+#define SHA_CTRL_HASHSWPB(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_HASHSWPB_SHIFT)) & SHA_CTRL_HASHSWPB_MASK)
+/*! @} */
+
+/*! @name STATUS - Status Regsiter */
+/*! @{ */
+#define SHA_STATUS_WAITING_MASK                  (0x1U)
+#define SHA_STATUS_WAITING_SHIFT                 (0U)
+/*! WAITING - Waiting Status 0: Not waiting for data may be disabled or may be busy. Note that for
+ *    cryptographic uses, this is not set if IsLast is set nor will it set until at least 1 word is
+ *    read of the output. 1: Waiting for data to be written in (16 words)
+ */
+#define SHA_STATUS_WAITING(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_WAITING_SHIFT)) & SHA_STATUS_WAITING_MASK)
+#define SHA_STATUS_DIGEST_MASK                   (0x2U)
+#define SHA_STATUS_DIGEST_SHIFT                  (1U)
+/*! DIGEST - If 1 then a DIGEST is ready and waiting and there is no active next block already
+ *    started. This is cleared when any data is written, when New is written, or when the block is
+ *    disabled.
+ */
+#define SHA_STATUS_DIGEST(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_DIGEST_SHIFT)) & SHA_STATUS_DIGEST_MASK)
+#define SHA_STATUS_ERROR_MASK                    (0x4U)
+#define SHA_STATUS_ERROR_SHIFT                   (2U)
+/*! ERROR - If 1, an error occurred. For normal uses, this is due to an attempted overrun: INDATA
+ *    was written when it was not appropriate. Write 1 to clear.
+ */
+#define SHA_STATUS_ERROR(x)                      (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_ERROR_SHIFT)) & SHA_STATUS_ERROR_MASK)
+#define SHA_STATUS_NEEDKEY_MASK                  (0x10U)
+#define SHA_STATUS_NEEDKEY_SHIFT                 (4U)
+/*! NEEDKEY - Indicates the block wants the key to be written in (set along with WAITING). 0: no key
+ *    is needed and writes will not be treated as Key. 1: key is needed and INDATA will be accepted
+ *    as key. Will also set WAITING.
+ */
+#define SHA_STATUS_NEEDKEY(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_NEEDKEY_SHIFT)) & SHA_STATUS_NEEDKEY_MASK)
+#define SHA_STATUS_NEEDIV_MASK                   (0x20U)
+#define SHA_STATUS_NEEDIV_SHIFT                  (5U)
+/*! NEEDIV - Indicates the block wants an IV/NONE to be written in (set along with WAITING). 0: no
+ *    IV is needed, either because written already or because not needed. 1: IV needed and INDATA
+ *    will be accepted as IV.
+ */
+#define SHA_STATUS_NEEDIV(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_NEEDIV_SHIFT)) & SHA_STATUS_NEEDIV_MASK)
+/*! @} */
+
+/*! @name INTENSET - Interrupt Enable and Interrupt enable set function */
+/*! @{ */
+#define SHA_INTENSET_WAITING_MASK                (0x1U)
+#define SHA_INTENSET_WAITING_SHIFT               (0U)
+/*! WAITING - 0: Will not interrupt when waiting. 1: Will interrupt when waiting. Write 1 to set this bit.
+ */
+#define SHA_INTENSET_WAITING(x)                  (((uint32_t)(((uint32_t)(x)) << SHA_INTENSET_WAITING_SHIFT)) & SHA_INTENSET_WAITING_MASK)
+#define SHA_INTENSET_DIGEST_MASK                 (0x2U)
+#define SHA_INTENSET_DIGEST_SHIFT                (1U)
+/*! DIGEST - 0: Will not interrupt when Digest is ready. 1: Will interrupt when Digest is ready. Write 1 to set this bit.
+ */
+#define SHA_INTENSET_DIGEST(x)                   (((uint32_t)(((uint32_t)(x)) << SHA_INTENSET_DIGEST_SHIFT)) & SHA_INTENSET_DIGEST_MASK)
+#define SHA_INTENSET_ERROR_MASK                  (0x4U)
+#define SHA_INTENSET_ERROR_SHIFT                 (2U)
+/*! ERROR - 0: Will not interrupt on Error. 1: Will interrupt on Error. Write 1 to set this bit.
+ */
+#define SHA_INTENSET_ERROR(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_INTENSET_ERROR_SHIFT)) & SHA_INTENSET_ERROR_MASK)
+/*! @} */
+
+/*! @name INTENCLR - Interrupt Clear Register */
+/*! @{ */
+#define SHA_INTENCLR_WAITING_MASK                (0x1U)
+#define SHA_INTENCLR_WAITING_SHIFT               (0U)
+/*! WAITING - Write 1 to clear correspnding bit in INTENSET.
+ */
+#define SHA_INTENCLR_WAITING(x)                  (((uint32_t)(((uint32_t)(x)) << SHA_INTENCLR_WAITING_SHIFT)) & SHA_INTENCLR_WAITING_MASK)
+#define SHA_INTENCLR_DIGEST_MASK                 (0x2U)
+#define SHA_INTENCLR_DIGEST_SHIFT                (1U)
+/*! DIGEST - Write 1 to clear correspnding bit in INTENSET.
+ */
+#define SHA_INTENCLR_DIGEST(x)                   (((uint32_t)(((uint32_t)(x)) << SHA_INTENCLR_DIGEST_SHIFT)) & SHA_INTENCLR_DIGEST_MASK)
+#define SHA_INTENCLR_ERROR_MASK                  (0x4U)
+#define SHA_INTENCLR_ERROR_SHIFT                 (2U)
+/*! ERROR - Write 1 to clear correspnding bit in INTENSET.
+ */
+#define SHA_INTENCLR_ERROR(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_INTENCLR_ERROR_SHIFT)) & SHA_INTENCLR_ERROR_MASK)
+/*! @} */
+
+/*! @name MEMCTRL - Setup Master to access memory */
+/*! @{ */
+#define SHA_MEMCTRL_MASTER_MASK                  (0x1U)
+#define SHA_MEMCTRL_MASTER_SHIFT                 (0U)
+/*! MASTER - Enables Mastering. 0: Mastering is not used and the normal DMA or Interrupt based model
+ *    is used with INDATA. 1: Mastering is enabled and DMA and INDATA should not be used.
+ */
+#define SHA_MEMCTRL_MASTER(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_MEMCTRL_MASTER_SHIFT)) & SHA_MEMCTRL_MASTER_MASK)
+#define SHA_MEMCTRL_COUNT_MASK                   (0x7FF0000U)
+#define SHA_MEMCTRL_COUNT_SHIFT                  (16U)
+/*! COUNT - Number of 512-bit blocks to copy starting at MEMADDR. This register will decrement after
+ *    each block is copied, ending in 0. For Hash, the DIGEST interrupt will occur when it reaches
+ *    0. If a bus error occurs, it will stop with this field set to the block that failed
+ */
+#define SHA_MEMCTRL_COUNT(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_MEMCTRL_COUNT_SHIFT)) & SHA_MEMCTRL_COUNT_MASK)
+/*! @} */
+
+/*! @name MEMADDR - Address to start memory access from */
+/*! @{ */
+#define SHA_MEMADDR_BASEADDR_MASK                (0xFFFFFFFFU)
+#define SHA_MEMADDR_BASEADDR_SHIFT               (0U)
+/*! BASEADDR - This field indicates the base address in Internal Flash, SRAM0, SRAMX, or SPIFI to start copying from.
+ */
+#define SHA_MEMADDR_BASEADDR(x)                  (((uint32_t)(((uint32_t)(x)) << SHA_MEMADDR_BASEADDR_SHIFT)) & SHA_MEMADDR_BASEADDR_MASK)
+/*! @} */
+
+/*! @name INDATA - Input Data register */
+/*! @{ */
+#define SHA_INDATA_DATA_MASK                     (0xFFFFFFFFU)
+#define SHA_INDATA_DATA_SHIFT                    (0U)
+/*! DATA - In this field the next word is written in little-endian format.
+ */
+#define SHA_INDATA_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << SHA_INDATA_DATA_SHIFT)) & SHA_INDATA_DATA_MASK)
+/*! @} */
+
+/* The count of SHA_INDATA */
+#define SHA_INDATA_COUNT                         (8U)
+
+/*! @name DIGEST - DIGEST or OUTD0, 5 or 8 bytes of output data, depending upon mode */
+/*! @{ */
+#define SHA_DIGEST_DIGEST_MASK                   (0xFFFFFFFFU)
+#define SHA_DIGEST_DIGEST_SHIFT                  (0U)
+/*! DIGEST - This field contains one word of the Digest.
+ */
+#define SHA_DIGEST_DIGEST(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_DIGEST_DIGEST_SHIFT)) & SHA_DIGEST_DIGEST_MASK)
+/*! @} */
+
+/* The count of SHA_DIGEST */
+#define SHA_DIGEST_COUNT                         (8U)
+
+/*! @name MASK - Mask register */
+/*! @{ */
+#define SHA_MASK_MASK_MASK                       (0xFFFFFFFFU)
+#define SHA_MASK_MASK_SHIFT                      (0U)
+/*! MASK - Mask register
+ */
+#define SHA_MASK_MASK(x)                         (((uint32_t)(((uint32_t)(x)) << SHA_MASK_MASK_SHIFT)) & SHA_MASK_MASK_MASK)
+/*! @} */
+
+/*! @name ID - IP identifier */
+/*! @{ */
+#define SHA_ID_APERTURE_MASK                     (0xFFU)
+#define SHA_ID_APERTURE_SHIFT                    (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define SHA_ID_APERTURE(x)                       (((uint32_t)(((uint32_t)(x)) << SHA_ID_APERTURE_SHIFT)) & SHA_ID_APERTURE_MASK)
+#define SHA_ID_MIN_REV_MASK                      (0xF00U)
+#define SHA_ID_MIN_REV_SHIFT                     (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define SHA_ID_MIN_REV(x)                        (((uint32_t)(((uint32_t)(x)) << SHA_ID_MIN_REV_SHIFT)) & SHA_ID_MIN_REV_MASK)
+#define SHA_ID_MAJ_REV_MASK                      (0xF000U)
+#define SHA_ID_MAJ_REV_SHIFT                     (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define SHA_ID_MAJ_REV(x)                        (((uint32_t)(((uint32_t)(x)) << SHA_ID_MAJ_REV_SHIFT)) & SHA_ID_MAJ_REV_MASK)
+#define SHA_ID_ID_MASK                           (0xFFFF0000U)
+#define SHA_ID_ID_SHIFT                          (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define SHA_ID_ID(x)                             (((uint32_t)(((uint32_t)(x)) << SHA_ID_ID_SHIFT)) & SHA_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group SHA_Register_Masks */
+
+
+/* SHA - Peripheral instance base addresses */
+/** Peripheral SHA0 base address */
+#define SHA0_BASE                                (0x4008F000u)
+/** Peripheral SHA0 base pointer */
+#define SHA0                                     ((SHA_Type *)SHA0_BASE)
+/** Array initializer of SHA peripheral base addresses */
+#define SHA_BASE_ADDRS                           { SHA0_BASE }
+/** Array initializer of SHA peripheral base pointers */
+#define SHA_BASE_PTRS                            { SHA0 }
+/** Interrupt vectors for the SHA peripheral type */
+#define SHA_IRQS                                 { SHA_IRQn }
+
+/*!
+ * @}
+ */ /* end of group SHA_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- SPI Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SPI_Peripheral_Access_Layer SPI Peripheral Access Layer
+ * @{
+ */
+
+/** SPI - Register Layout Typedef */
+typedef struct {
+       uint8_t RESERVED_0[1024];
+  __IO uint32_t CFG;                               /**< SPI Configuration register, offset: 0x400 */
+  __IO uint32_t DLY;                               /**< SPI Delay register, offset: 0x404 */
+  __IO uint32_t STAT;                              /**< SPI Status. Some status flags can be cleared by writing a 1 to that bit position., offset: 0x408 */
+  __IO uint32_t INTENSET;                          /**< SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0x40C */
+  __IO uint32_t INTENCLR;                          /**< SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared., offset: 0x410 */
+       uint8_t RESERVED_1[12];
+  __IO uint32_t TXCTL;                             /**< SPI Transmit Control. If Transmit FIFO is enabled, in FIFOCFG, then values read in this register are affected values in FIFO., offset: 0x420 */
+  __IO uint32_t DIV;                               /**< SPI clock Divider, offset: 0x424 */
+  __I  uint32_t INTSTAT;                           /**< SPI Interrupt Status, offset: 0x428 */
+       uint8_t RESERVED_2[2516];
+  __IO uint32_t FIFOCFG;                           /**< FIFO configuration and enable register., offset: 0xE00 */
+  __IO uint32_t FIFOSTAT;                          /**< FIFO status register., offset: 0xE04 */
+  __IO uint32_t FIFOTRIG;                          /**< FIFO trigger settings for interrupt and DMA request., offset: 0xE08 */
+       uint8_t RESERVED_3[4];
+  __IO uint32_t FIFOINTENSET;                      /**< FIFO interrupt enable set (enable) and read register., offset: 0xE10 */
+  __IO uint32_t FIFOINTENCLR;                      /**< FIFO interrupt enable clear (disable) and read register., offset: 0xE14 */
+  __I  uint32_t FIFOINTSTAT;                       /**< FIFO interrupt status register., offset: 0xE18 */
+       uint8_t RESERVED_4[4];
+  __O  uint32_t FIFOWR;                            /**< FIFO write data. FIFO data not reset by block reset, offset: 0xE20 */
+       uint8_t RESERVED_5[12];
+  __I  uint32_t FIFORD;                            /**< FIFO read data., offset: 0xE30 */
+       uint8_t RESERVED_6[12];
+  __I  uint32_t FIFORDNOPOP;                       /**< FIFO data read with no FIFO pop., offset: 0xE40 */
+       uint8_t RESERVED_7[436];
+  __IO uint32_t PSELID;                            /**< Peripheral function select and ID register, offset: 0xFF8 */
+  __I  uint32_t ID;                                /**< SPI Module Identifier, offset: 0xFFC */
+} SPI_Type;
+
+/* ----------------------------------------------------------------------------
+   -- SPI Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SPI_Register_Masks SPI Register Masks
+ * @{
+ */
+
+/*! @name CFG - SPI Configuration register */
+/*! @{ */
+#define SPI_CFG_ENABLE_MASK                      (0x1U)
+#define SPI_CFG_ENABLE_SHIFT                     (0U)
+/*! ENABLE - SPI enable.
+ */
+#define SPI_CFG_ENABLE(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_CFG_ENABLE_SHIFT)) & SPI_CFG_ENABLE_MASK)
+#define SPI_CFG_MASTER_MASK                      (0x4U)
+#define SPI_CFG_MASTER_SHIFT                     (2U)
+/*! MASTER - Master mode select.
+ */
+#define SPI_CFG_MASTER(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_CFG_MASTER_SHIFT)) & SPI_CFG_MASTER_MASK)
+#define SPI_CFG_LSBF_MASK                        (0x8U)
+#define SPI_CFG_LSBF_SHIFT                       (3U)
+/*! LSBF - LSB First mode enable.
+ */
+#define SPI_CFG_LSBF(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LSBF_SHIFT)) & SPI_CFG_LSBF_MASK)
+#define SPI_CFG_CPHA_MASK                        (0x10U)
+#define SPI_CFG_CPHA_SHIFT                       (4U)
+/*! CPHA - Clock Phase select.
+ */
+#define SPI_CFG_CPHA(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPHA_SHIFT)) & SPI_CFG_CPHA_MASK)
+#define SPI_CFG_CPOL_MASK                        (0x20U)
+#define SPI_CFG_CPOL_SHIFT                       (5U)
+/*! CPOL - Clock Polarity select.
+ */
+#define SPI_CFG_CPOL(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPOL_SHIFT)) & SPI_CFG_CPOL_MASK)
+#define SPI_CFG_LOOP_MASK                        (0x80U)
+#define SPI_CFG_LOOP_SHIFT                       (7U)
+/*! LOOP - Loopback mode enable. Loopback mode applies only to Master mode, and connects transmit
+ *    and receive data connected together to allow simple software testing.
+ */
+#define SPI_CFG_LOOP(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LOOP_SHIFT)) & SPI_CFG_LOOP_MASK)
+#define SPI_CFG_SPOL0_MASK                       (0x100U)
+#define SPI_CFG_SPOL0_SHIFT                      (8U)
+/*! SPOL0 - SSEL0 Polarity select.
+ */
+#define SPI_CFG_SPOL0(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL0_SHIFT)) & SPI_CFG_SPOL0_MASK)
+#define SPI_CFG_SPOL1_MASK                       (0x200U)
+#define SPI_CFG_SPOL1_SHIFT                      (9U)
+/*! SPOL1 - SSEL1 Polarity select. Valid only for SPI-1
+ */
+#define SPI_CFG_SPOL1(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL1_SHIFT)) & SPI_CFG_SPOL1_MASK)
+#define SPI_CFG_SPOL2_MASK                       (0x400U)
+#define SPI_CFG_SPOL2_SHIFT                      (10U)
+/*! SPOL2 - SSEL2 Polarity select. Valid only for SPI-1
+ */
+#define SPI_CFG_SPOL2(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL2_SHIFT)) & SPI_CFG_SPOL2_MASK)
+/*! @} */
+
+/*! @name DLY - SPI Delay register */
+/*! @{ */
+#define SPI_DLY_PRE_DELAY_MASK                   (0xFU)
+#define SPI_DLY_PRE_DELAY_SHIFT                  (0U)
+/*! PRE_DELAY - Controls the amount of time between SSEL assertion and the beginning of a data
+ *    transfer. There is always one SPI clock time between SSEL assertion and the first clock edge. This
+ *    is not considered part of the pre-delay. 0x0 = No additional time is inserted. 0x1 = 1 SPI
+ *    clock time is inserted. 0x2 = 2 SPI clock times are inserted. ... 0xF = 15 SPI clock times are
+ *    inserted.
+ */
+#define SPI_DLY_PRE_DELAY(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_DLY_PRE_DELAY_SHIFT)) & SPI_DLY_PRE_DELAY_MASK)
+#define SPI_DLY_POST_DELAY_MASK                  (0xF0U)
+#define SPI_DLY_POST_DELAY_SHIFT                 (4U)
+/*! POST_DELAY - Controls the amount of time between the end of a data transfer and SSEL
+ *    deassertion. 0x0 = No additional time is inserted. 0x1 = 1 SPI clock time is inserted. 0x2 = 2 SPI clock
+ *    times are inserted. ... 0xF = 15 SPI clock times are inserted.
+ */
+#define SPI_DLY_POST_DELAY(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_DLY_POST_DELAY_SHIFT)) & SPI_DLY_POST_DELAY_MASK)
+#define SPI_DLY_FRAME_DELAY_MASK                 (0xF00U)
+#define SPI_DLY_FRAME_DELAY_SHIFT                (8U)
+/*! FRAME_DELAY - If the EOFR flag is set, controls the minimum amount of time between the current
+ *    frame and the next frame (or SSEL deassertion if EOTR). 0x0 = No additional time is inserted.
+ *    0x1 = 1 SPI clock time is inserted. 0x2 = 2 SPI clock times are inserted. ... 0xF = 15 SPI
+ *    clock times are inserted.
+ */
+#define SPI_DLY_FRAME_DELAY(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_DLY_FRAME_DELAY_SHIFT)) & SPI_DLY_FRAME_DELAY_MASK)
+#define SPI_DLY_TRANSFER_DELAY_MASK              (0xF000U)
+#define SPI_DLY_TRANSFER_DELAY_SHIFT             (12U)
+/*! TRANSFER_DELAY - Controls the minimum amount of time that the SSEL is deasserted between
+ *    transfers. 0x0 = The minimum time that SSEL is deasserted is 1 SPI clock time. (Zero added time.) 0x1
+ *    = The minimum time that SSEL is deasserted is 2 SPI clock times. 0x2 = The minimum time that
+ *    SSEL is deasserted is 3 SPI clock times. ... 0xF = The minimum time that SSEL is deasserted is
+ *    16 SPI clock times.
+ */
+#define SPI_DLY_TRANSFER_DELAY(x)                (((uint32_t)(((uint32_t)(x)) << SPI_DLY_TRANSFER_DELAY_SHIFT)) & SPI_DLY_TRANSFER_DELAY_MASK)
+/*! @} */
+
+/*! @name STAT - SPI Status. Some status flags can be cleared by writing a 1 to that bit position. */
+/*! @{ */
+#define SPI_STAT_RXOV_MASK                       (0x4U)
+#define SPI_STAT_RXOV_SHIFT                      (2U)
+/*! RXOV - Receiver Overrun interrupt flag. This flag applies only to slave mode (Master = 0). This
+ *    flag is set when the beginning of a received character is detected while the receiver buffer
+ *    is still in use. If this occurs, the receiver buffer contents are preserved, and the incoming
+ *    data is lost. Data received by the SPI should be considered undefined if RxOv is set.
+ */
+#define SPI_STAT_RXOV(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_STAT_RXOV_SHIFT)) & SPI_STAT_RXOV_MASK)
+#define SPI_STAT_TXUR_MASK                       (0x8U)
+#define SPI_STAT_TXUR_SHIFT                      (3U)
+/*! TXUR - Transmitter Underrun interrupt flag. This flag applies only to slave mode (Master = 0).
+ *    In this case, the transmitter must begin sending new data on the next input clock if the
+ *    transmitter is idle. If that data is not available in the transmitter holding register at that
+ *    point, there is no data to transmit and the TXUR flag is set. Data transmitted by the SPI should be
+ *    considered undefined if TXUR is set.
+ */
+#define SPI_STAT_TXUR(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_STAT_TXUR_SHIFT)) & SPI_STAT_TXUR_MASK)
+#define SPI_STAT_SSA_MASK                        (0x10U)
+#define SPI_STAT_SSA_SHIFT                       (4U)
+/*! SSA - Slave Select Assert. This flag is set whenever any slave select transitions from
+ *    deasserted to asserted, in both master and slave modes. This allows determining when the SPI
+ *    transmit/receive functions become busy, and allows waking up the device from reduced power modes when a
+ *    slave mode access begins. This flag is cleared by software.
+ */
+#define SPI_STAT_SSA(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSA_SHIFT)) & SPI_STAT_SSA_MASK)
+#define SPI_STAT_SSD_MASK                        (0x20U)
+#define SPI_STAT_SSD_SHIFT                       (5U)
+/*! SSD - Slave Select Deassert. This flag is set whenever any asserted slave selects transition to
+ *    deasserted, in both master and slave modes. This allows determining when the SPI
+ *    transmit/receive functions become idle. This flag is cleared by software.
+ */
+#define SPI_STAT_SSD(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSD_SHIFT)) & SPI_STAT_SSD_MASK)
+#define SPI_STAT_STALLED_MASK                    (0x40U)
+#define SPI_STAT_STALLED_SHIFT                   (6U)
+/*! STALLED - Stalled status flag. This indicates whether the SPI is currently in a stall condition.
+ */
+#define SPI_STAT_STALLED(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_STAT_STALLED_SHIFT)) & SPI_STAT_STALLED_MASK)
+#define SPI_STAT_ENDTRANSFER_MASK                (0x80U)
+#define SPI_STAT_ENDTRANSFER_SHIFT               (7U)
+/*! ENDTRANSFER - End Transfer control bit. Software can set this bit to force an end to the current
+ *    transfer when the transmitter finishes any activity already in progress, as if the EOTR flag
+ *    had been set prior to the last transmission. This capability is included to support cases
+ *    where it is not known when transmit data is written that it will be the end of a transfer. The bit
+ *    is cleared when the transmitter becomes idle as the transfer comes to an end. Forcing an end
+ *    of transfer in this manner causes any specified FRAME_DELAY and TRANSFER_DELAY to be inserted.
+ */
+#define SPI_STAT_ENDTRANSFER(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_STAT_ENDTRANSFER_SHIFT)) & SPI_STAT_ENDTRANSFER_MASK)
+#define SPI_STAT_MSTIDLE_MASK                    (0x100U)
+#define SPI_STAT_MSTIDLE_SHIFT                   (8U)
+/*! MSTIDLE - Master idle status flag. This bit is 1 whenever the SPI master function is fully idle.
+ *    This means that the transmit holding register is empty and the transmitter is not in the
+ *    process of sending data.
+ */
+#define SPI_STAT_MSTIDLE(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_STAT_MSTIDLE_SHIFT)) & SPI_STAT_MSTIDLE_MASK)
+/*! @} */
+
+/*! @name INTENSET - SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */
+/*! @{ */
+#define SPI_INTENSET_RXOVEN_MASK                 (0x4U)
+#define SPI_INTENSET_RXOVEN_SHIFT                (2U)
+/*! RXOVEN - RX overrun interrupt enable. Determines whether an interrupt occurs when a receiver
+ *    overrun occurs. This happens in slave mode when there is a need for the receiver to move newly
+ *    received data to the RXDAT register when it is already in use. The interface prevents receiver
+ *    overrun in Master mode by not allowing a new transmission to begin when a receiver overrun
+ *    would otherwise occur.
+ */
+#define SPI_INTENSET_RXOVEN(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_RXOVEN_SHIFT)) & SPI_INTENSET_RXOVEN_MASK)
+#define SPI_INTENSET_TXUREN_MASK                 (0x8U)
+#define SPI_INTENSET_TXUREN_SHIFT                (3U)
+/*! TXUREN - TX underrun interrupt enable. Determines whether an interrupt occurs when a transmitter
+ *    underrun occurs. This happens in slave mode when there is a need to transmit data when none
+ *    is available.
+ */
+#define SPI_INTENSET_TXUREN(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_TXUREN_SHIFT)) & SPI_INTENSET_TXUREN_MASK)
+#define SPI_INTENSET_SSAEN_MASK                  (0x10U)
+#define SPI_INTENSET_SSAEN_SHIFT                 (4U)
+/*! SSAEN - Slave select assert interrupt enable. Determines whether an interrupt occurs when the Slave Select is asserted.
+ */
+#define SPI_INTENSET_SSAEN(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSAEN_SHIFT)) & SPI_INTENSET_SSAEN_MASK)
+#define SPI_INTENSET_SSDEN_MASK                  (0x20U)
+#define SPI_INTENSET_SSDEN_SHIFT                 (5U)
+/*! SSDEN - Slave select deassert interrupt enable. Determines whether an interrupt occurs when the Slave Select is deasserted.
+ */
+#define SPI_INTENSET_SSDEN(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSDEN_SHIFT)) & SPI_INTENSET_SSDEN_MASK)
+#define SPI_INTENSET_MSTIDLEEN_MASK              (0x100U)
+#define SPI_INTENSET_MSTIDLEEN_SHIFT             (8U)
+/*! MSTIDLEEN - Master idle interrupt enable.
+ */
+#define SPI_INTENSET_MSTIDLEEN(x)                (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_MSTIDLEEN_SHIFT)) & SPI_INTENSET_MSTIDLEEN_MASK)
+/*! @} */
+
+/*! @name INTENCLR - SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared. */
+/*! @{ */
+#define SPI_INTENCLR_RXOVCLR_MASK                (0x4U)
+#define SPI_INTENCLR_RXOVCLR_SHIFT               (2U)
+/*! RXOVCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_RXOVCLR(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_RXOVCLR_SHIFT)) & SPI_INTENCLR_RXOVCLR_MASK)
+#define SPI_INTENCLR_TXURCLR_MASK                (0x8U)
+#define SPI_INTENCLR_TXURCLR_SHIFT               (3U)
+/*! TXURCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_TXURCLR(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_TXURCLR_SHIFT)) & SPI_INTENCLR_TXURCLR_MASK)
+#define SPI_INTENCLR_SSACLR_MASK                 (0x10U)
+#define SPI_INTENCLR_SSACLR_SHIFT                (4U)
+/*! SSACLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_SSACLR(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSACLR_SHIFT)) & SPI_INTENCLR_SSACLR_MASK)
+#define SPI_INTENCLR_SSDCLR_MASK                 (0x20U)
+#define SPI_INTENCLR_SSDCLR_SHIFT                (5U)
+/*! SSDCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_SSDCLR(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSDCLR_SHIFT)) & SPI_INTENCLR_SSDCLR_MASK)
+#define SPI_INTENCLR_MSTIDLECLR_MASK             (0x100U)
+#define SPI_INTENCLR_MSTIDLECLR_SHIFT            (8U)
+/*! MSTIDLECLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_MSTIDLECLR(x)               (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_MSTIDLECLR_SHIFT)) & SPI_INTENCLR_MSTIDLECLR_MASK)
+/*! @} */
+
+/*! @name TXCTL - SPI Transmit Control. If Transmit FIFO is enabled, in FIFOCFG, then values read in this register are affected values in FIFO. */
+/*! @{ */
+#define SPI_TXCTL_TXSSEL0_N_MASK                 (0x10000U)
+#define SPI_TXCTL_TXSSEL0_N_SHIFT                (16U)
+/*! TXSSEL0_N - Transmit Slave Select 0.
+ */
+#define SPI_TXCTL_TXSSEL0_N(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL0_N_SHIFT)) & SPI_TXCTL_TXSSEL0_N_MASK)
+#define SPI_TXCTL_TXSSEL1_N_MASK                 (0x20000U)
+#define SPI_TXCTL_TXSSEL1_N_SHIFT                (17U)
+/*! TXSSEL1_N - Transmit Slave Select 1. Valid only for SPI-1
+ */
+#define SPI_TXCTL_TXSSEL1_N(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL1_N_SHIFT)) & SPI_TXCTL_TXSSEL1_N_MASK)
+#define SPI_TXCTL_TXSSEL2_N_MASK                 (0x40000U)
+#define SPI_TXCTL_TXSSEL2_N_SHIFT                (18U)
+/*! TXSSEL2_N - Transmit Slave Select 2. Valid only for SPI-1
+ */
+#define SPI_TXCTL_TXSSEL2_N(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL2_N_SHIFT)) & SPI_TXCTL_TXSSEL2_N_MASK)
+#define SPI_TXCTL_TXSSEL3_N_MASK                 (0x80000U)
+#define SPI_TXCTL_TXSSEL3_N_SHIFT                (19U)
+/*! TXSSEL3_N - [Reserved] Transmit Slave Select 3.
+ */
+#define SPI_TXCTL_TXSSEL3_N(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL3_N_SHIFT)) & SPI_TXCTL_TXSSEL3_N_MASK)
+#define SPI_TXCTL_EOTR_MASK                      (0x100000U)
+#define SPI_TXCTL_EOTR_SHIFT                     (20U)
+/*! EOTR - End of Transfer.
+ */
+#define SPI_TXCTL_EOTR(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_EOTR_SHIFT)) & SPI_TXCTL_EOTR_MASK)
+#define SPI_TXCTL_EOFR_MASK                      (0x200000U)
+#define SPI_TXCTL_EOFR_SHIFT                     (21U)
+/*! EOFR - End of Frame.
+ */
+#define SPI_TXCTL_EOFR(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_EOFR_SHIFT)) & SPI_TXCTL_EOFR_MASK)
+#define SPI_TXCTL_RXIGNORE_MASK                  (0x400000U)
+#define SPI_TXCTL_RXIGNORE_SHIFT                 (22U)
+/*! RXIGNORE - Receive Ignore.
+ */
+#define SPI_TXCTL_RXIGNORE(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_RXIGNORE_SHIFT)) & SPI_TXCTL_RXIGNORE_MASK)
+#define SPI_TXCTL_LEN_MASK                       (0xF000000U)
+#define SPI_TXCTL_LEN_SHIFT                      (24U)
+/*! LEN - Data transfer Length.
+ */
+#define SPI_TXCTL_LEN(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_LEN_SHIFT)) & SPI_TXCTL_LEN_MASK)
+/*! @} */
+
+/*! @name DIV - SPI clock Divider */
+/*! @{ */
+#define SPI_DIV_DIVVAL_MASK                      (0xFFFFU)
+#define SPI_DIV_DIVVAL_SHIFT                     (0U)
+/*! DIVVAL - Rate divider value. Specifies how the SPI Module clock is divided to produce the SPI
+ *    clock rate in master mode. DIVVAL is -1 encoded such that the value 0 results in SPICLK/1, the
+ *    value 1 results in SPICLK/2, up to the maximum possible divide value of 0xFFFF, which results
+ *    in SPICLK/65536.
+ */
+#define SPI_DIV_DIVVAL(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_DIV_DIVVAL_SHIFT)) & SPI_DIV_DIVVAL_MASK)
+/*! @} */
+
+/*! @name INTSTAT - SPI Interrupt Status */
+/*! @{ */
+#define SPI_INTSTAT_RXOV_MASK                    (0x4U)
+#define SPI_INTSTAT_RXOV_SHIFT                   (2U)
+/*! RXOV - Receiver Overrun interrupt flag.
+ */
+#define SPI_INTSTAT_RXOV(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_RXOV_SHIFT)) & SPI_INTSTAT_RXOV_MASK)
+#define SPI_INTSTAT_TXUR_MASK                    (0x8U)
+#define SPI_INTSTAT_TXUR_SHIFT                   (3U)
+/*! TXUR - Transmitter Underrun interrupt flag.
+ */
+#define SPI_INTSTAT_TXUR(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_TXUR_SHIFT)) & SPI_INTSTAT_TXUR_MASK)
+#define SPI_INTSTAT_SSA_MASK                     (0x10U)
+#define SPI_INTSTAT_SSA_SHIFT                    (4U)
+/*! SSA - Slave Select Assert.
+ */
+#define SPI_INTSTAT_SSA(x)                       (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSA_SHIFT)) & SPI_INTSTAT_SSA_MASK)
+#define SPI_INTSTAT_SSD_MASK                     (0x20U)
+#define SPI_INTSTAT_SSD_SHIFT                    (5U)
+/*! SSD - Slave Select Deassert.
+ */
+#define SPI_INTSTAT_SSD(x)                       (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSD_SHIFT)) & SPI_INTSTAT_SSD_MASK)
+#define SPI_INTSTAT_MSTIDLE_MASK                 (0x100U)
+#define SPI_INTSTAT_MSTIDLE_SHIFT                (8U)
+/*! MSTIDLE - Master Idle status flag.
+ */
+#define SPI_INTSTAT_MSTIDLE(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_MSTIDLE_SHIFT)) & SPI_INTSTAT_MSTIDLE_MASK)
+/*! @} */
+
+/*! @name FIFOCFG - FIFO configuration and enable register. */
+/*! @{ */
+#define SPI_FIFOCFG_ENABLETX_MASK                (0x1U)
+#define SPI_FIFOCFG_ENABLETX_SHIFT               (0U)
+/*! ENABLETX - Enable the transmit FIFO. This is automatically enabled when PSELID.PERSEL is set to
+ *    2 to configure for SPI functionality
+ */
+#define SPI_FIFOCFG_ENABLETX(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_ENABLETX_SHIFT)) & SPI_FIFOCFG_ENABLETX_MASK)
+#define SPI_FIFOCFG_ENABLERX_MASK                (0x2U)
+#define SPI_FIFOCFG_ENABLERX_SHIFT               (1U)
+/*! ENABLERX - Enable the receive FIFO. This is automatically enabled when PSELID.PERSEL is set to 2 to configure for SPI functionality
+ */
+#define SPI_FIFOCFG_ENABLERX(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_ENABLERX_SHIFT)) & SPI_FIFOCFG_ENABLERX_MASK)
+#define SPI_FIFOCFG_SIZE_MASK                    (0x30U)
+#define SPI_FIFOCFG_SIZE_SHIFT                   (4U)
+/*! SIZE - FIFO size configuration. This is a read-only field. 0x0 = Reset value. 0x1 = FIFO is
+ *    configured as 4 entries of 16bits. This value is read after PSELID.PERSEL=2 for SPI functionlaity.
+ *    0x2, 0x3 = not applicable.
+ */
+#define SPI_FIFOCFG_SIZE(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_SIZE_SHIFT)) & SPI_FIFOCFG_SIZE_MASK)
+#define SPI_FIFOCFG_DMATX_MASK                   (0x1000U)
+#define SPI_FIFOCFG_DMATX_SHIFT                  (12U)
+/*! DMATX - DMA configuration for transmit.
+ */
+#define SPI_FIFOCFG_DMATX(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_DMATX_SHIFT)) & SPI_FIFOCFG_DMATX_MASK)
+#define SPI_FIFOCFG_DMARX_MASK                   (0x2000U)
+#define SPI_FIFOCFG_DMARX_SHIFT                  (13U)
+/*! DMARX - DMA configuration for receive.
+ */
+#define SPI_FIFOCFG_DMARX(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_DMARX_SHIFT)) & SPI_FIFOCFG_DMARX_MASK)
+#define SPI_FIFOCFG_EMPTYTX_MASK                 (0x10000U)
+#define SPI_FIFOCFG_EMPTYTX_SHIFT                (16U)
+/*! EMPTYTX - Empty command for the transmit FIFO. When a 1 is written to this bit, the TX FIFO is emptied.
+ */
+#define SPI_FIFOCFG_EMPTYTX(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_EMPTYTX_SHIFT)) & SPI_FIFOCFG_EMPTYTX_MASK)
+#define SPI_FIFOCFG_EMPTYRX_MASK                 (0x20000U)
+#define SPI_FIFOCFG_EMPTYRX_SHIFT                (17U)
+/*! EMPTYRX - Empty command for the receive FIFO. When a 1 is written to this bit, the RX FIFO is emptied.
+ */
+#define SPI_FIFOCFG_EMPTYRX(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_EMPTYRX_SHIFT)) & SPI_FIFOCFG_EMPTYRX_MASK)
+#define SPI_FIFOCFG_POPDBG_MASK                  (0x40000U)
+#define SPI_FIFOCFG_POPDBG_SHIFT                 (18U)
+/*! POPDBG - Pop FIFO for debug reads.
+ */
+#define SPI_FIFOCFG_POPDBG(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_POPDBG_SHIFT)) & SPI_FIFOCFG_POPDBG_MASK)
+/*! @} */
+
+/*! @name FIFOSTAT - FIFO status register. */
+/*! @{ */
+#define SPI_FIFOSTAT_TXERR_MASK                  (0x1U)
+#define SPI_FIFOSTAT_TXERR_SHIFT                 (0U)
+/*! TXERR - TX FIFO error. Will be set if a transmit FIFO error occurs. This could be an overflow
+ *    caused by pushing data into a full FIFO, or by an underflow if the FIFO is empty when data is
+ *    needed. Cleared by writing a 1 to this bit.
+ */
+#define SPI_FIFOSTAT_TXERR(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXERR_SHIFT)) & SPI_FIFOSTAT_TXERR_MASK)
+#define SPI_FIFOSTAT_RXERR_MASK                  (0x2U)
+#define SPI_FIFOSTAT_RXERR_SHIFT                 (1U)
+/*! RXERR - RX FIFO error. Will be set if a receive FIFO overflow occurs, caused by software or DMA
+ *    not emptying the FIFO fast enough. Cleared by writing a 1 to this bit.
+ */
+#define SPI_FIFOSTAT_RXERR(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXERR_SHIFT)) & SPI_FIFOSTAT_RXERR_MASK)
+#define SPI_FIFOSTAT_PERINT_MASK                 (0x8U)
+#define SPI_FIFOSTAT_PERINT_SHIFT                (3U)
+/*! PERINT - Peripheral interrupt. When 1, this indicates that the peripheral function has asserted
+ *    an interrupt. The details can be found by reading the peripheral s STAT register.
+ */
+#define SPI_FIFOSTAT_PERINT(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_PERINT_SHIFT)) & SPI_FIFOSTAT_PERINT_MASK)
+#define SPI_FIFOSTAT_TXEMPTY_MASK                (0x10U)
+#define SPI_FIFOSTAT_TXEMPTY_SHIFT               (4U)
+/*! TXEMPTY - Transmit FIFO empty. When 1, the transmit FIFO is empty. The peripheral may still be processing the last piece of data.
+ */
+#define SPI_FIFOSTAT_TXEMPTY(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXEMPTY_SHIFT)) & SPI_FIFOSTAT_TXEMPTY_MASK)
+#define SPI_FIFOSTAT_TXNOTFULL_MASK              (0x20U)
+#define SPI_FIFOSTAT_TXNOTFULL_SHIFT             (5U)
+/*! TXNOTFULL - Transmit FIFO not full. When 1, the transmit FIFO is not full, so more data can be
+ *    written. When 0, the transmit FIFO is full and another write would cause it to overflow.
+ */
+#define SPI_FIFOSTAT_TXNOTFULL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXNOTFULL_SHIFT)) & SPI_FIFOSTAT_TXNOTFULL_MASK)
+#define SPI_FIFOSTAT_RXNOTEMPTY_MASK             (0x40U)
+#define SPI_FIFOSTAT_RXNOTEMPTY_SHIFT            (6U)
+/*! RXNOTEMPTY - Receive FIFO not empty. When 1, the receive FIFO is not empty, so data can be read. When 0, the receive FIFO is empty.
+ */
+#define SPI_FIFOSTAT_RXNOTEMPTY(x)               (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXNOTEMPTY_SHIFT)) & SPI_FIFOSTAT_RXNOTEMPTY_MASK)
+#define SPI_FIFOSTAT_RXFULL_MASK                 (0x80U)
+#define SPI_FIFOSTAT_RXFULL_SHIFT                (7U)
+/*! RXFULL - Receive FIFO full. When 1, the receive FIFO is full. Data needs to be read out to
+ *    prevent the peripheral from causing an overflow.
+ */
+#define SPI_FIFOSTAT_RXFULL(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXFULL_SHIFT)) & SPI_FIFOSTAT_RXFULL_MASK)
+#define SPI_FIFOSTAT_TXLVL_MASK                  (0x1F00U)
+#define SPI_FIFOSTAT_TXLVL_SHIFT                 (8U)
+/*! TXLVL - Transmit FIFO current level. A 0 means the TX FIFO is currently empty, and the TXEMPTY
+ *    and TXNOTFULL flags will be 1. Other values tell how much data is actually in the TX FIFO at
+ *    the point where the read occurs. If the TX FIFO is full, the TXEMPTY and TXNOTFULL flags will be
+ *    0.
+ */
+#define SPI_FIFOSTAT_TXLVL(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXLVL_SHIFT)) & SPI_FIFOSTAT_TXLVL_MASK)
+#define SPI_FIFOSTAT_RXLVL_MASK                  (0x1F0000U)
+#define SPI_FIFOSTAT_RXLVL_SHIFT                 (16U)
+/*! RXLVL - Receive FIFO current level. A 0 means the RX FIFO is currently empty, and the RXFULL and
+ *    RXNOTEMPTY flags will be 0. Other values tell how much data is actually in the RX FIFO at the
+ *    point where the read occurs. If the RX FIFO is full, the RXFULL and RXNOTEMPTY flags will be
+ *    1.
+ */
+#define SPI_FIFOSTAT_RXLVL(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXLVL_SHIFT)) & SPI_FIFOSTAT_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOTRIG - FIFO trigger settings for interrupt and DMA request. */
+/*! @{ */
+#define SPI_FIFOTRIG_TXLVLENA_MASK               (0x1U)
+#define SPI_FIFOTRIG_TXLVLENA_SHIFT              (0U)
+/*! TXLVLENA - Transmit FIFO level trigger enable. This trigger will become an interrupt if enabled
+ *    in FIFOINTENSET, or a DMA trigger if DMATX in FIFOCFG is set.
+ */
+#define SPI_FIFOTRIG_TXLVLENA(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_TXLVLENA_SHIFT)) & SPI_FIFOTRIG_TXLVLENA_MASK)
+#define SPI_FIFOTRIG_RXLVLENA_MASK               (0x2U)
+#define SPI_FIFOTRIG_RXLVLENA_SHIFT              (1U)
+/*! RXLVLENA - Receive FIFO level trigger enable. This trigger will become an interrupt if enabled
+ *    in FIFOINTENSET, or a DMA trigger if DMARX in FIFOCFG is set.
+ */
+#define SPI_FIFOTRIG_RXLVLENA(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_RXLVLENA_SHIFT)) & SPI_FIFOTRIG_RXLVLENA_MASK)
+#define SPI_FIFOTRIG_TXLVL_MASK                  (0xF00U)
+#define SPI_FIFOTRIG_TXLVL_SHIFT                 (8U)
+/*! TXLVL - Transmit FIFO level trigger point. This field is used only when TXLVLENA = 1. 0 =
+ *    trigger when the TX FIFO becomes empty. 1 = trigger when the TX FIFO level decreases to one entry.
+ *    ... 7 = 1 = trigger when the TX FIFO level decreases to 7 entries (is no longer full).
+ */
+#define SPI_FIFOTRIG_TXLVL(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_TXLVL_SHIFT)) & SPI_FIFOTRIG_TXLVL_MASK)
+#define SPI_FIFOTRIG_RXLVL_MASK                  (0xF0000U)
+#define SPI_FIFOTRIG_RXLVL_SHIFT                 (16U)
+/*! RXLVL - Receive FIFO level trigger point. The RX FIFO level is checked when a new piece of data
+ *    is received. This field is used only when RXLVLENA = 1. 0 = trigger when the RX FIFO has
+ *    received one entry (is no longer empty). 1 = trigger when the RX FIFO has received two entries. ...
+ *    7 = trigger when the RX FIFO has received 8 entries (has become full).
+ */
+#define SPI_FIFOTRIG_RXLVL(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_RXLVL_SHIFT)) & SPI_FIFOTRIG_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTENSET - FIFO interrupt enable set (enable) and read register. */
+/*! @{ */
+#define SPI_FIFOINTENSET_TXERR_MASK              (0x1U)
+#define SPI_FIFOINTENSET_TXERR_SHIFT             (0U)
+/*! TXERR - Determines whether an interrupt occurs when a transmit error occurs, based on the TXERR flag in the FIFOSTAT register.
+ */
+#define SPI_FIFOINTENSET_TXERR(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_TXERR_SHIFT)) & SPI_FIFOINTENSET_TXERR_MASK)
+#define SPI_FIFOINTENSET_RXERR_MASK              (0x2U)
+#define SPI_FIFOINTENSET_RXERR_SHIFT             (1U)
+/*! RXERR - Determines whether an interrupt occurs when a receive error occurs, based on the RXERR flag in the FIFOSTAT register.
+ */
+#define SPI_FIFOINTENSET_RXERR(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_RXERR_SHIFT)) & SPI_FIFOINTENSET_RXERR_MASK)
+#define SPI_FIFOINTENSET_TXLVL_MASK              (0x4U)
+#define SPI_FIFOINTENSET_TXLVL_SHIFT             (2U)
+/*! TXLVL - Determines whether an interrupt occurs when a the transmit FIFO reaches the level
+ *    specified by the TXLVL field in the FIFOTRIG register.
+ */
+#define SPI_FIFOINTENSET_TXLVL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_TXLVL_SHIFT)) & SPI_FIFOINTENSET_TXLVL_MASK)
+#define SPI_FIFOINTENSET_RXLVL_MASK              (0x8U)
+#define SPI_FIFOINTENSET_RXLVL_SHIFT             (3U)
+/*! RXLVL - Determines whether an interrupt occurs when a the receive FIFO reaches the level
+ *    specified by the TXLVL field in the FIFOTRIG register.
+ */
+#define SPI_FIFOINTENSET_RXLVL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_RXLVL_SHIFT)) & SPI_FIFOINTENSET_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTENCLR - FIFO interrupt enable clear (disable) and read register. */
+/*! @{ */
+#define SPI_FIFOINTENCLR_TXERR_MASK              (0x1U)
+#define SPI_FIFOINTENCLR_TXERR_SHIFT             (0U)
+/*! TXERR - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define SPI_FIFOINTENCLR_TXERR(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_TXERR_SHIFT)) & SPI_FIFOINTENCLR_TXERR_MASK)
+#define SPI_FIFOINTENCLR_RXERR_MASK              (0x2U)
+#define SPI_FIFOINTENCLR_RXERR_SHIFT             (1U)
+/*! RXERR - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define SPI_FIFOINTENCLR_RXERR(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_RXERR_SHIFT)) & SPI_FIFOINTENCLR_RXERR_MASK)
+#define SPI_FIFOINTENCLR_TXLVL_MASK              (0x4U)
+#define SPI_FIFOINTENCLR_TXLVL_SHIFT             (2U)
+/*! TXLVL - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define SPI_FIFOINTENCLR_TXLVL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_TXLVL_SHIFT)) & SPI_FIFOINTENCLR_TXLVL_MASK)
+#define SPI_FIFOINTENCLR_RXLVL_MASK              (0x8U)
+#define SPI_FIFOINTENCLR_RXLVL_SHIFT             (3U)
+/*! RXLVL - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define SPI_FIFOINTENCLR_RXLVL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_RXLVL_SHIFT)) & SPI_FIFOINTENCLR_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTSTAT - FIFO interrupt status register. */
+/*! @{ */
+#define SPI_FIFOINTSTAT_TXERR_MASK               (0x1U)
+#define SPI_FIFOINTSTAT_TXERR_SHIFT              (0U)
+/*! TXERR - TX FIFO error.
+ */
+#define SPI_FIFOINTSTAT_TXERR(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_TXERR_SHIFT)) & SPI_FIFOINTSTAT_TXERR_MASK)
+#define SPI_FIFOINTSTAT_RXERR_MASK               (0x2U)
+#define SPI_FIFOINTSTAT_RXERR_SHIFT              (1U)
+/*! RXERR - RX FIFO error.
+ */
+#define SPI_FIFOINTSTAT_RXERR(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_RXERR_SHIFT)) & SPI_FIFOINTSTAT_RXERR_MASK)
+#define SPI_FIFOINTSTAT_TXLVL_MASK               (0x4U)
+#define SPI_FIFOINTSTAT_TXLVL_SHIFT              (2U)
+/*! TXLVL - Transmit FIFO level interrupt.
+ */
+#define SPI_FIFOINTSTAT_TXLVL(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_TXLVL_SHIFT)) & SPI_FIFOINTSTAT_TXLVL_MASK)
+#define SPI_FIFOINTSTAT_RXLVL_MASK               (0x8U)
+#define SPI_FIFOINTSTAT_RXLVL_SHIFT              (3U)
+/*! RXLVL - Receive FIFO level interrupt.
+ */
+#define SPI_FIFOINTSTAT_RXLVL(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_RXLVL_SHIFT)) & SPI_FIFOINTSTAT_RXLVL_MASK)
+#define SPI_FIFOINTSTAT_PERINT_MASK              (0x10U)
+#define SPI_FIFOINTSTAT_PERINT_SHIFT             (4U)
+/*! PERINT - Peripheral interrupt.
+ */
+#define SPI_FIFOINTSTAT_PERINT(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_PERINT_SHIFT)) & SPI_FIFOINTSTAT_PERINT_MASK)
+/*! @} */
+
+/*! @name FIFOWR - FIFO write data. FIFO data not reset by block reset */
+/*! @{ */
+#define SPI_FIFOWR_TXDATA_MASK                   (0xFFFFU)
+#define SPI_FIFOWR_TXDATA_SHIFT                  (0U)
+/*! TXDATA - Transmit data to the FIFO.
+ */
+#define SPI_FIFOWR_TXDATA(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXDATA_SHIFT)) & SPI_FIFOWR_TXDATA_MASK)
+#define SPI_FIFOWR_TXSSEL0_N_MASK                (0x10000U)
+#define SPI_FIFOWR_TXSSEL0_N_SHIFT               (16U)
+/*! TXSSEL0_N - Transmit Slave Select. This field asserts SSEL0 in master mode. The output on the
+ *    pin is active LOW by default. Remark: The active state of the SSEL0 pin is configured by bits in
+ *    the CFG register.
+ */
+#define SPI_FIFOWR_TXSSEL0_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL0_N_SHIFT)) & SPI_FIFOWR_TXSSEL0_N_MASK)
+#define SPI_FIFOWR_TXSSEL1_N_MASK                (0x20000U)
+#define SPI_FIFOWR_TXSSEL1_N_SHIFT               (17U)
+/*! TXSSEL1_N - Transmit Slave Select. This field asserts SSEL1 in master mode. The output on the
+ *    pin is active LOW by default. Remark: The active state of the SSEL1 pin is configured by bits in
+ *    the CFG register.
+ */
+#define SPI_FIFOWR_TXSSEL1_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL1_N_SHIFT)) & SPI_FIFOWR_TXSSEL1_N_MASK)
+#define SPI_FIFOWR_TXSSEL2_N_MASK                (0x40000U)
+#define SPI_FIFOWR_TXSSEL2_N_SHIFT               (18U)
+/*! TXSSEL2_N - Transmit Slave Select. This field asserts SSEL2 in master mode. The output on the
+ *    pin is active LOW by default. Remark: The active state of the SSEL2 pin is configured by bits in
+ *    the CFG register.
+ */
+#define SPI_FIFOWR_TXSSEL2_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL2_N_SHIFT)) & SPI_FIFOWR_TXSSEL2_N_MASK)
+#define SPI_FIFOWR_EOT_MASK                      (0x100000U)
+#define SPI_FIFOWR_EOT_SHIFT                     (20U)
+/*! EOT - End of Transfer. The asserted SSEL will be deasserted at the end of a transfer, and remain
+ *    so for at least the time specified by the Transfer_delay value in the DLY register.
+ */
+#define SPI_FIFOWR_EOT(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_EOT_SHIFT)) & SPI_FIFOWR_EOT_MASK)
+#define SPI_FIFOWR_EOF_MASK                      (0x200000U)
+#define SPI_FIFOWR_EOF_SHIFT                     (21U)
+/*! EOF - End of Frame. Between frames, a delay may be inserted, as defined by the FRAME_DELAY value
+ *    in the DLY register. The end of a frame may not be particularly meaningful if the FRAME_DELAY
+ *    value = 0. This control can be used as part of the support for frame lengths greater than 16
+ *    bits.
+ */
+#define SPI_FIFOWR_EOF(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_EOF_SHIFT)) & SPI_FIFOWR_EOF_MASK)
+#define SPI_FIFOWR_RXIGNORE_MASK                 (0x400000U)
+#define SPI_FIFOWR_RXIGNORE_SHIFT                (22U)
+/*! RXIGNORE - Receive Ignore. This allows data to be transmitted using the SPI without the need to
+ *    read unneeded data from the receiver.Setting this bit simplifies the transmit process and can
+ *    be used with the DMA.
+ */
+#define SPI_FIFOWR_RXIGNORE(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_RXIGNORE_SHIFT)) & SPI_FIFOWR_RXIGNORE_MASK)
+#define SPI_FIFOWR_LEN_MASK                      (0xF000000U)
+#define SPI_FIFOWR_LEN_SHIFT                     (24U)
+/*! LEN - Data Length. Specifies the data length from 1 to 16 bits. Note that transfer lengths
+ *    greater than 16 bits are supported by implementing multiple sequential transmits. 0x0 = Data
+ *    transfer is 1 bit in length. Note: when LEN = 0, the underrun status is not meaningful. 0x1 = Data
+ *    transfer is 2 bits in length. 0x2 = Data transfer is 3 bits in length. ... 0xF = Data transfer
+ *    is 16 bits in length.
+ */
+#define SPI_FIFOWR_LEN(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_LEN_SHIFT)) & SPI_FIFOWR_LEN_MASK)
+/*! @} */
+
+/*! @name FIFORD - FIFO read data. */
+/*! @{ */
+#define SPI_FIFORD_RXDATA_MASK                   (0xFFFFU)
+#define SPI_FIFORD_RXDATA_SHIFT                  (0U)
+/*! RXDATA - Received data from the FIFO.
+ */
+#define SPI_FIFORD_RXDATA(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXDATA_SHIFT)) & SPI_FIFORD_RXDATA_MASK)
+#define SPI_FIFORD_RXSSEL0_N_MASK                (0x10000U)
+#define SPI_FIFORD_RXSSEL0_N_SHIFT               (16U)
+/*! RXSSEL0_N - Slave Select for receive. This field allows the state of the SSEL0 pin to be saved
+ *    along with received data. The value will reflect the SSEL0 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORD_RXSSEL0_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL0_N_SHIFT)) & SPI_FIFORD_RXSSEL0_N_MASK)
+#define SPI_FIFORD_RXSSEL1_N_MASK                (0x20000U)
+#define SPI_FIFORD_RXSSEL1_N_SHIFT               (17U)
+/*! RXSSEL1_N - Slave Select for receive. This field allows the state of the SSEL1 pin to be saved
+ *    along with received data. The value will reflect the SSEL1 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORD_RXSSEL1_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL1_N_SHIFT)) & SPI_FIFORD_RXSSEL1_N_MASK)
+#define SPI_FIFORD_RXSSEL2_N_MASK                (0x40000U)
+#define SPI_FIFORD_RXSSEL2_N_SHIFT               (18U)
+/*! RXSSEL2_N - Slave Select for receive. This field allows the state of the SSEL2 pin to be saved
+ *    along with received data. The value will reflect the SSEL2 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORD_RXSSEL2_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL2_N_SHIFT)) & SPI_FIFORD_RXSSEL2_N_MASK)
+#define SPI_FIFORD_SOT_MASK                      (0x100000U)
+#define SPI_FIFORD_SOT_SHIFT                     (20U)
+/*! SOT - Start of Transfer flag. This flag will be 1 if this is the first data after the SSELs went
+ *    from deasserted to asserted (i.e., any previous transfer has ended). This information can be
+ *    used to identify the first piece of data in cases where the transfer length is greater than 16
+ *    bit.
+ */
+#define SPI_FIFORD_SOT(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_SOT_SHIFT)) & SPI_FIFORD_SOT_MASK)
+/*! @} */
+
+/*! @name FIFORDNOPOP - FIFO data read with no FIFO pop. */
+/*! @{ */
+#define SPI_FIFORDNOPOP_RXDATA_MASK              (0xFFFFU)
+#define SPI_FIFORDNOPOP_RXDATA_SHIFT             (0U)
+/*! RXDATA - Received data from the FIFO.
+ */
+#define SPI_FIFORDNOPOP_RXDATA(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXDATA_SHIFT)) & SPI_FIFORDNOPOP_RXDATA_MASK)
+#define SPI_FIFORDNOPOP_RXSSEL0_N_MASK           (0x10000U)
+#define SPI_FIFORDNOPOP_RXSSEL0_N_SHIFT          (16U)
+/*! RXSSEL0_N - Slave Select for receive. This field allows the state of the SSEL0 pin to be saved
+ *    along with received data. The value will reflect the SSEL0 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORDNOPOP_RXSSEL0_N(x)             (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL0_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL0_N_MASK)
+#define SPI_FIFORDNOPOP_RXSSEL1_N_MASK           (0x20000U)
+#define SPI_FIFORDNOPOP_RXSSEL1_N_SHIFT          (17U)
+/*! RXSSEL1_N - Slave Select for receive. This field allows the state of the SSEL1 pin to be saved
+ *    along with received data. The value will reflect the SSEL1 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORDNOPOP_RXSSEL1_N(x)             (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL1_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL1_N_MASK)
+#define SPI_FIFORDNOPOP_RXSSEL2_N_MASK           (0x40000U)
+#define SPI_FIFORDNOPOP_RXSSEL2_N_SHIFT          (18U)
+/*! RXSSEL2_N - Slave Select for receive. This field allows the state of the SSEL2 pin to be saved
+ *    along with received data. The value will reflect the SSEL2 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORDNOPOP_RXSSEL2_N(x)             (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL2_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL2_N_MASK)
+#define SPI_FIFORDNOPOP_SOT_MASK                 (0x100000U)
+#define SPI_FIFORDNOPOP_SOT_SHIFT                (20U)
+/*! SOT - Start of Transfer flag. This flag will be 1 if this is the first data after the SSELs went
+ *    from deasserted to asserted (i.e., any previous transfer has ended). This information can be
+ *    used to identify the first piece of data in cases where the transfer length is greater than 16
+ *    bit.
+ */
+#define SPI_FIFORDNOPOP_SOT(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_SOT_SHIFT)) & SPI_FIFORDNOPOP_SOT_MASK)
+/*! @} */
+
+/*! @name PSELID - Peripheral function select and ID register */
+/*! @{ */
+#define SPI_PSELID_PERSEL_MASK                   (0x7U)
+#define SPI_PSELID_PERSEL_SHIFT                  (0U)
+/*! PERSEL - Peripheral Select. This field is writable by software. Reset value is 0x0 showing that
+ *    no peripheral is selected. Write 0x2 to select the SPI function. All other values are not
+ *    valid.
+ */
+#define SPI_PSELID_PERSEL(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_PSELID_PERSEL_SHIFT)) & SPI_PSELID_PERSEL_MASK)
+#define SPI_PSELID_LOCK_MASK                     (0x8U)
+#define SPI_PSELID_LOCK_SHIFT                    (3U)
+/*! LOCK - Lock the peripheral select. This field is writable by software. 0 Peripheral select can
+ *    be changed by software. 1 Peripheral select is locked and cannot be changed until this
+ *    peripheral or the entire device is reset.
+ */
+#define SPI_PSELID_LOCK(x)                       (((uint32_t)(((uint32_t)(x)) << SPI_PSELID_LOCK_SHIFT)) & SPI_PSELID_LOCK_MASK)
+#define SPI_PSELID_SPIPRESENT_MASK               (0x20U)
+#define SPI_PSELID_SPIPRESENT_SHIFT              (5U)
+/*! SPIPRESENT - SPI present indicator. This field is Read-only and has value 0x1 to indicate SPI function is present.
+ */
+#define SPI_PSELID_SPIPRESENT(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_PSELID_SPIPRESENT_SHIFT)) & SPI_PSELID_SPIPRESENT_MASK)
+#define SPI_PSELID_ID_MASK                       (0xFFFFF000U)
+#define SPI_PSELID_ID_SHIFT                      (12U)
+/*! ID - Peripheral Select ID.
+ */
+#define SPI_PSELID_ID(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_PSELID_ID_SHIFT)) & SPI_PSELID_ID_MASK)
+/*! @} */
+
+/*! @name ID - SPI Module Identifier */
+/*! @{ */
+#define SPI_ID_APERTURE_MASK                     (0xFFU)
+#define SPI_ID_APERTURE_SHIFT                    (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define SPI_ID_APERTURE(x)                       (((uint32_t)(((uint32_t)(x)) << SPI_ID_APERTURE_SHIFT)) & SPI_ID_APERTURE_MASK)
+#define SPI_ID_MIN_REV_MASK                      (0xF00U)
+#define SPI_ID_MIN_REV_SHIFT                     (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define SPI_ID_MIN_REV(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_ID_MIN_REV_SHIFT)) & SPI_ID_MIN_REV_MASK)
+#define SPI_ID_MAJ_REV_MASK                      (0xF000U)
+#define SPI_ID_MAJ_REV_SHIFT                     (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define SPI_ID_MAJ_REV(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_ID_MAJ_REV_SHIFT)) & SPI_ID_MAJ_REV_MASK)
+#define SPI_ID_ID_MASK                           (0xFFFF0000U)
+#define SPI_ID_ID_SHIFT                          (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define SPI_ID_ID(x)                             (((uint32_t)(((uint32_t)(x)) << SPI_ID_ID_SHIFT)) & SPI_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group SPI_Register_Masks */
+
+
+/* SPI - Peripheral instance base addresses */
+/** Peripheral SPI0 base address */
+#define SPI0_BASE                                (0x4008D000u)
+/** Peripheral SPI0 base pointer */
+#define SPI0                                     ((SPI_Type *)SPI0_BASE)
+/** Peripheral SPI1 base address */
+#define SPI1_BASE                                (0x4008E000u)
+/** Peripheral SPI1 base pointer */
+#define SPI1                                     ((SPI_Type *)SPI1_BASE)
+/** Array initializer of SPI peripheral base addresses */
+#define SPI_BASE_ADDRS                           { SPI0_BASE, SPI1_BASE }
+/** Array initializer of SPI peripheral base pointers */
+#define SPI_BASE_PTRS                            { SPI0, SPI1 }
+/** Interrupt vectors for the SPI peripheral type */
+#define SPI_IRQS                                 { FLEXCOMM4_IRQn, FLEXCOMM5_IRQn }
+
+/*!
+ * @}
+ */ /* end of group SPI_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- SPIFI Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SPIFI_Peripheral_Access_Layer SPIFI Peripheral Access Layer
+ * @{
+ */
+
+/** SPIFI - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< SPIFI control register, offset: 0x0 */
+  __IO uint32_t CMD;                               /**< SPIFI command register, offset: 0x4 */
+  __IO uint32_t ADDR;                              /**< SPIFI address register, offset: 0x8 */
+  __IO uint32_t IDATA;                             /**< SPIFI intermediate data register, offset: 0xC */
+  __IO uint32_t CLIMIT;                            /**< SPIFI limit register, offset: 0x10 */
+  __IO uint32_t DATA;                              /**< SPIFI data register. Input or output data, offset: 0x14 */
+  __IO uint32_t MCMD;                              /**< SPIFI memory command register, offset: 0x18 */
+  __IO uint32_t STAT;                              /**< SPIFI status register, offset: 0x1C */
+} SPIFI_Type;
+
+/* ----------------------------------------------------------------------------
+   -- SPIFI Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SPIFI_Register_Masks SPIFI Register Masks
+ * @{
+ */
+
+/*! @name CTRL - SPIFI control register */
+/*! @{ */
+#define SPIFI_CTRL_TIMEOUT_MASK                  (0xFFFFU)
+#define SPIFI_CTRL_TIMEOUT_SHIFT                 (0U)
+/*! TIMEOUT - This field contains the number of serial clock periods without the processor reading
+ *    data in memory mode, which will cause the SPIFI hardware to terminate the command by driving
+ *    the CS pin high and negating the CMD bit in the Status register. (This allows the flash memory
+ *    to enter a lower-power state.) If the processor reads data from the flash region after a
+ *    time-out, the command in the Memory Command Register is issued again.
+ */
+#define SPIFI_CTRL_TIMEOUT(x)                    (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_TIMEOUT_SHIFT)) & SPIFI_CTRL_TIMEOUT_MASK)
+#define SPIFI_CTRL_CSHIGH_MASK                   (0xF0000U)
+#define SPIFI_CTRL_CSHIGH_SHIFT                  (16U)
+/*! CSHIGH - This field controls the minimum CS high time, expressed as a number of serial clock periods minus one.
+ */
+#define SPIFI_CTRL_CSHIGH(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_CSHIGH_SHIFT)) & SPIFI_CTRL_CSHIGH_MASK)
+#define SPIFI_CTRL_D_PRFTCH_DIS_MASK             (0x200000U)
+#define SPIFI_CTRL_D_PRFTCH_DIS_SHIFT            (21U)
+/*! D_PRFTCH_DIS - This bit allows conditioning of memory mode prefetches based on the AHB HPROT
+ *    (instruction/data) access information. A 1 in this register means that the SPIFI will not attempt
+ *    a speculative prefetch when it encounters data accesses.
+ */
+#define SPIFI_CTRL_D_PRFTCH_DIS(x)               (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_D_PRFTCH_DIS_SHIFT)) & SPIFI_CTRL_D_PRFTCH_DIS_MASK)
+#define SPIFI_CTRL_INTEN_MASK                    (0x400000U)
+#define SPIFI_CTRL_INTEN_SHIFT                   (22U)
+/*! INTEN - If this bit is 1 when a command ends, the SPIFI will assert its interrupt request
+ *    output. See INTRQ in the status register for further details.
+ */
+#define SPIFI_CTRL_INTEN(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_INTEN_SHIFT)) & SPIFI_CTRL_INTEN_MASK)
+#define SPIFI_CTRL_MODE3_MASK                    (0x800000U)
+#define SPIFI_CTRL_MODE3_SHIFT                   (23U)
+/*! MODE3 - SPI Mode 3 select. 0: SCK LOW. The SPIFI drives SCK low after the rising edge at which
+ *    the last bit of each command is captured, and keeps it low while CS is HIGH. 1: SCK HIGH. the
+ *    SPIFI keeps SCK high after the rising edge for the last bit of each command and while CS is
+ *    HIGH, and drives it low after it drives CS LOW. (Known serial flash devices can handle either
+ *    mode, but some devices may require a particular mode for proper operation.) Remark: MODE3, RFCLK,
+ *    and FBCLK should not all be 1, because in this case there is no final falling edge on SCK on
+ *    which to sample the last data bit of the frame.
+ */
+#define SPIFI_CTRL_MODE3(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_MODE3_SHIFT)) & SPIFI_CTRL_MODE3_MASK)
+#define SPIFI_CTRL_PRFTCH_DIS_MASK               (0x8000000U)
+#define SPIFI_CTRL_PRFTCH_DIS_SHIFT              (27U)
+/*! PRFTCH_DIS - Cache prefetching enable. The SPIFI includes an internal cache. A 1 in this bit
+ *    disables prefetching of cache lines. 0: Enable. Cache prefetching enabled. 1: Disable. Disables
+ *    prefetching of cache lines.
+ */
+#define SPIFI_CTRL_PRFTCH_DIS(x)                 (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_PRFTCH_DIS_SHIFT)) & SPIFI_CTRL_PRFTCH_DIS_MASK)
+#define SPIFI_CTRL_DUAL_MASK                     (0x10000000U)
+#define SPIFI_CTRL_DUAL_SHIFT                    (28U)
+/*! DUAL - Select dual protocol. 0: Quad protocol. This protocol uses IO3:0. 1: Dual protocol. This protocol uses IO1:0.
+ */
+#define SPIFI_CTRL_DUAL(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_DUAL_SHIFT)) & SPIFI_CTRL_DUAL_MASK)
+#define SPIFI_CTRL_RFCLK_MASK                    (0x20000000U)
+#define SPIFI_CTRL_RFCLK_SHIFT                   (29U)
+/*! RFCLK - Select active clock edge for input data. 0: Rising edge. Read data is sampled on rising
+ *    edges on the clock, as in classic SPI operation. 1: Falling edge. Read data is sampled on
+ *    falling edges of the clock, allowing a full serial clock of of time in order to maximize the
+ *    serial clock frequency. Remark: MODE3, RFCLK, and FBCLK should not all be 1, because in this case
+ *    there is no final falling edge on SCK on which to sample the last data bit of the frame.
+ */
+#define SPIFI_CTRL_RFCLK(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_RFCLK_SHIFT)) & SPIFI_CTRL_RFCLK_MASK)
+#define SPIFI_CTRL_FBCLK_MASK                    (0x40000000U)
+#define SPIFI_CTRL_FBCLK_SHIFT                   (30U)
+/*! FBCLK - Feedback clock select. 0: Internal clock. The SPIFI samples read data using an internal
+ *    clock. 1: Feedback clock. Read data is sampled using a feedback clock from the SCK pin. This
+ *    allows slightly more time for each received bit. Remark: MODE3, RFCLK, and FBCLK should not all
+ *    be 1, because in this case there is no final falling edge on SCK on which to sample the last
+ *    data bit of the frame.
+ */
+#define SPIFI_CTRL_FBCLK(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_FBCLK_SHIFT)) & SPIFI_CTRL_FBCLK_MASK)
+#define SPIFI_CTRL_DMAEN_MASK                    (0x80000000U)
+#define SPIFI_CTRL_DMAEN_SHIFT                   (31U)
+/*! DMAEN - A 1 in this bit enables the DMA Request output from the SPIFI. Set this bit only when a
+ *    DMA channel is used to transfer data in peripheral mode. Do not set this bit when a DMA
+ *    channel is used for memory-to-memory transfers from the SPIFI memory area. DRQEN should only be used
+ *    in Command mode.
+ */
+#define SPIFI_CTRL_DMAEN(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_DMAEN_SHIFT)) & SPIFI_CTRL_DMAEN_MASK)
+/*! @} */
+
+/*! @name CMD - SPIFI command register */
+/*! @{ */
+#define SPIFI_CMD_DATALEN_MASK                   (0x3FFFU)
+#define SPIFI_CMD_DATALEN_SHIFT                  (0U)
+/*! DATALEN - Except when the POLL bit in this register is 1, this field controls how many data
+ *    bytes are in the command. 0 indicates that the command does not contain a data field.
+ */
+#define SPIFI_CMD_DATALEN(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_DATALEN_SHIFT)) & SPIFI_CMD_DATALEN_MASK)
+#define SPIFI_CMD_POLL_MASK                      (0x4000U)
+#define SPIFI_CMD_POLL_SHIFT                     (14U)
+/*! POLL - This bit should be written as 1 only with an opcode that a) contains an input data field,
+ *    and b) causes the serial flash device to return byte status repetitively (e.g., a Read Status
+ *    command). When this bit is 1, the SPIFI hardware continues to read bytes until the test
+ *    specified by the DATALEN field is met. The hardware tests the bit in each status byte selected by
+ *    DATALEN bits 2:0, until a bit is found that is equal to DATALEN bit 3. When the test succeeds,
+ *    the SPIFI captures the byte that meets this test so that it can be read from the Data
+ *    Register, and terminates the command by raising CS. The end-of-command interrupt can be enabled to
+ *    inform software when this occurs
+ */
+#define SPIFI_CMD_POLL(x)                        (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_POLL_SHIFT)) & SPIFI_CMD_POLL_MASK)
+#define SPIFI_CMD_DOUT_MASK                      (0x8000U)
+#define SPIFI_CMD_DOUT_SHIFT                     (15U)
+/*! DOUT - If the DATALEN field is not zero, this bit controls the direction of the data: 0: Input
+ *    from serial flash. 1: Output to serial flash.
+ */
+#define SPIFI_CMD_DOUT(x)                        (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_DOUT_SHIFT)) & SPIFI_CMD_DOUT_MASK)
+#define SPIFI_CMD_INTLEN_MASK                    (0x70000U)
+#define SPIFI_CMD_INTLEN_SHIFT                   (16U)
+/*! INTLEN - This field controls how many intermediate bytes precede the data. (Each such byte may
+ *    require 8 or 2 SCK cycles, depending on whether the intermediate field is in serial, 2-bit, or
+ *    4-bit format.) Intermediate bytes are output by the SPIFI, and include post-address control
+ *    information, dummy and delay bytes. See the description of the Intermediate Data register for
+ *    the contents of such bytes.
+ */
+#define SPIFI_CMD_INTLEN(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_INTLEN_SHIFT)) & SPIFI_CMD_INTLEN_MASK)
+#define SPIFI_CMD_FIELDFORM_MASK                 (0x180000U)
+#define SPIFI_CMD_FIELDFORM_SHIFT                (19U)
+/*! FIELDFORM - This field controls how the fields of the command are sent. 0x0: All serial. All
+ *    fields of the command are serial. 0x1: Quad/dual data. Data field is quad/dual, other fields are
+ *    serial. 0x2: Serial opcode. Opcode field is serial. Other fields are quad/dual. 0x3: All
+ *    quad/dual. All fields of the command are in quad/dual format.
+ */
+#define SPIFI_CMD_FIELDFORM(x)                   (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_FIELDFORM_SHIFT)) & SPIFI_CMD_FIELDFORM_MASK)
+#define SPIFI_CMD_FRAMEFORM_MASK                 (0xE00000U)
+#define SPIFI_CMD_FRAMEFORM_SHIFT                (21U)
+/*! FRAMEFORM - This field controls the opcode and address fields. 0x0: Reserved. 0x1: Opcode.
+ *    Opcode only, no address. 0x2: Opcode one byte. Opcode, least significant byte of address. 0x3:
+ *    Opcode two bytes. Opcode, two least significant bytes of address. 0x4: Opcode three bytes. Opcode,
+ *    three least significant bytes of address. 0x5: Opcode four bytes. Opcode, 4 bytes of address.
+ *    0x6: No opcode three bytes. No opcode, 3 least significant bytes of address. 0x7: No opcode
+ *    four bytes. No opcode, 4 bytes of address.
+ */
+#define SPIFI_CMD_FRAMEFORM(x)                   (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_FRAMEFORM_SHIFT)) & SPIFI_CMD_FRAMEFORM_MASK)
+#define SPIFI_CMD_OPCODE_MASK                    (0xFF000000U)
+#define SPIFI_CMD_OPCODE_SHIFT                   (24U)
+/*! OPCODE - The opcode of the command (not used for some FRAMEFORM values).
+ */
+#define SPIFI_CMD_OPCODE(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_OPCODE_SHIFT)) & SPIFI_CMD_OPCODE_MASK)
+/*! @} */
+
+/*! @name ADDR - SPIFI address register */
+/*! @{ */
+#define SPIFI_ADDR_ADDR_MASK                     (0xFFFFFFFFU)
+#define SPIFI_ADDR_ADDR_SHIFT                    (0U)
+/*! ADDR - SPIFI address register
+ */
+#define SPIFI_ADDR_ADDR(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_ADDR_ADDR_SHIFT)) & SPIFI_ADDR_ADDR_MASK)
+/*! @} */
+
+/*! @name IDATA - SPIFI intermediate data register */
+/*! @{ */
+#define SPIFI_IDATA_IDATA_MASK                   (0xFFFFFFFFU)
+#define SPIFI_IDATA_IDATA_SHIFT                  (0U)
+/*! IDATA - SPIFI intermediate data register
+ */
+#define SPIFI_IDATA_IDATA(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_IDATA_IDATA_SHIFT)) & SPIFI_IDATA_IDATA_MASK)
+/*! @} */
+
+/*! @name CLIMIT - SPIFI limit register */
+/*! @{ */
+#define SPIFI_CLIMIT_CLIMIT_MASK                 (0xFFFFFFFFU)
+#define SPIFI_CLIMIT_CLIMIT_SHIFT                (0U)
+/*! CLIMIT - SPIFI limit register
+ */
+#define SPIFI_CLIMIT_CLIMIT(x)                   (((uint32_t)(((uint32_t)(x)) << SPIFI_CLIMIT_CLIMIT_SHIFT)) & SPIFI_CLIMIT_CLIMIT_MASK)
+/*! @} */
+
+/*! @name DATA - SPIFI data register. Input or output data */
+/*! @{ */
+#define SPIFI_DATA_DATA_MASK                     (0xFFFFFFFFU)
+#define SPIFI_DATA_DATA_SHIFT                    (0U)
+/*! DATA - SPIFI data register. Input or output data
+ */
+#define SPIFI_DATA_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_DATA_DATA_SHIFT)) & SPIFI_DATA_DATA_MASK)
+/*! @} */
+
+/*! @name MCMD - SPIFI memory command register */
+/*! @{ */
+#define SPIFI_MCMD_POLL_MASK                     (0x4000U)
+#define SPIFI_MCMD_POLL_SHIFT                    (14U)
+/*! POLL - This bit should be written as 0.
+ */
+#define SPIFI_MCMD_POLL(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_POLL_SHIFT)) & SPIFI_MCMD_POLL_MASK)
+#define SPIFI_MCMD_DOUT_MASK                     (0x8000U)
+#define SPIFI_MCMD_DOUT_SHIFT                    (15U)
+/*! DOUT - This bit should be written as 0.
+ */
+#define SPIFI_MCMD_DOUT(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_DOUT_SHIFT)) & SPIFI_MCMD_DOUT_MASK)
+#define SPIFI_MCMD_INTLEN_MASK                   (0x70000U)
+#define SPIFI_MCMD_INTLEN_SHIFT                  (16U)
+/*! INTLEN - This field controls how many intermediate bytes precede the data. (Each such byte may
+ *    require 8 or 2 SCK cycles, depending on whether the intermediate field is in serial, 2-bit, or
+ *    4-bit format.) Intermediate bytes are output by the SPIFI, and include post-address control
+ *    information, dummy and delay bytes. See the description of the Intermediate Data register for
+ *    the contents of such bytes.
+ */
+#define SPIFI_MCMD_INTLEN(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_INTLEN_SHIFT)) & SPIFI_MCMD_INTLEN_MASK)
+#define SPIFI_MCMD_FIELDFORM_MASK                (0x180000U)
+#define SPIFI_MCMD_FIELDFORM_SHIFT               (19U)
+/*! FIELDFORM - This field controls how the fields of the command are sent. 0x0 All serial. All
+ *    fields of the command are serial. 0x1 Quad/dual data. Data field is quad/dual, other fields are
+ *    serial. 0x2 Serial opcode. Opcode field is serial. Other fields are quad/dual. 0x3 All
+ *    quad/dual. All fields of the command are in quad/dual format.
+ */
+#define SPIFI_MCMD_FIELDFORM(x)                  (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_FIELDFORM_SHIFT)) & SPIFI_MCMD_FIELDFORM_MASK)
+#define SPIFI_MCMD_FRAMEFORM_MASK                (0xE00000U)
+#define SPIFI_MCMD_FRAMEFORM_SHIFT               (21U)
+/*! FRAMEFORM - This field controls the opcode and address fields. 0x0: Reserved. 0x1: Opcode.
+ *    Opcode only, no address. 0x2: Opcode one byte. Opcode, least-significant byte of address. 0x3:
+ *    Opcode two bytes. Opcode, 2 least-significant bytes of address. 0x4: Opcode three bytes. Opcode, 3
+ *    least-significant bytes of address. 0x5: Opcode four bytes. Opcode, 4 bytes of address. 0x6:
+ *    No opcode three bytes. No opcode, 3 least-significant bytes of address. 0x7: No opcode, 4
+ *    bytes of address.
+ */
+#define SPIFI_MCMD_FRAMEFORM(x)                  (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_FRAMEFORM_SHIFT)) & SPIFI_MCMD_FRAMEFORM_MASK)
+#define SPIFI_MCMD_OPCODE_MASK                   (0xFF000000U)
+#define SPIFI_MCMD_OPCODE_SHIFT                  (24U)
+/*! OPCODE - The opcode of the command (not used for some FRAMEFORM values).
+ */
+#define SPIFI_MCMD_OPCODE(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_OPCODE_SHIFT)) & SPIFI_MCMD_OPCODE_MASK)
+/*! @} */
+
+/*! @name STAT - SPIFI status register */
+/*! @{ */
+#define SPIFI_STAT_MCINIT_MASK                   (0x1U)
+#define SPIFI_STAT_MCINIT_SHIFT                  (0U)
+/*! MCINIT - This bit is set when software successfully writes the Memory Command register, and is
+ *    cleared by Reset or by writing a 1 to the RESET bit in this register.
+ */
+#define SPIFI_STAT_MCINIT(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_MCINIT_SHIFT)) & SPIFI_STAT_MCINIT_MASK)
+#define SPIFI_STAT_CMD_MASK                      (0x2U)
+#define SPIFI_STAT_CMD_SHIFT                     (1U)
+/*! CMD - This bit is 1 when the Command register is written. It is cleared by a hardware reset, a
+ *    write to the RESET bit in this register, or the deassertion of CS which indicates that the
+ *    command has completed communication with the SPI Flash.
+ */
+#define SPIFI_STAT_CMD(x)                        (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_CMD_SHIFT)) & SPIFI_STAT_CMD_MASK)
+#define SPIFI_STAT_RESET_MASK                    (0x10U)
+#define SPIFI_STAT_RESET_SHIFT                   (4U)
+/*! RESET - Write a 1 to this bit to abort a current command or memory mode. This bit is cleared
+ *    when the hardware is ready for a new command to be written to the Command register.
+ */
+#define SPIFI_STAT_RESET(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_RESET_SHIFT)) & SPIFI_STAT_RESET_MASK)
+#define SPIFI_STAT_INTRQ_MASK                    (0x20U)
+#define SPIFI_STAT_INTRQ_SHIFT                   (5U)
+/*! INTRQ - This bit reflects the SPIFI interrupt request. Write a 1 to this bit to clear it. This
+ *    bit is set when a CMD was previously 1 and has been cleared due to the deassertion of CS.
+ */
+#define SPIFI_STAT_INTRQ(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_INTRQ_SHIFT)) & SPIFI_STAT_INTRQ_MASK)
+#define SPIFI_STAT_VERSION_MASK                  (0xFF000000U)
+#define SPIFI_STAT_VERSION_SHIFT                 (24U)
+#define SPIFI_STAT_VERSION(x)                    (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_VERSION_SHIFT)) & SPIFI_STAT_VERSION_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group SPIFI_Register_Masks */
+
+
+/* SPIFI - Peripheral instance base addresses */
+/** Peripheral SPIFI base address */
+#define SPIFI_BASE                               (0x40084000u)
+/** Peripheral SPIFI base pointer */
+#define SPIFI                                    ((SPIFI_Type *)SPIFI_BASE)
+/** Array initializer of SPIFI peripheral base addresses */
+#define SPIFI_BASE_ADDRS                         { SPIFI_BASE }
+/** Array initializer of SPIFI peripheral base pointers */
+#define SPIFI_BASE_PTRS                          { SPIFI }
+
+/*!
+ * @}
+ */ /* end of group SPIFI_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- SYSCON Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SYSCON_Peripheral_Access_Layer SYSCON Peripheral Access Layer
+ * @{
+ */
+
+/** SYSCON - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t MEMORYREMAP;                       /**< Memory Remap control register, offset: 0x0 */
+       uint8_t RESERVED_0[12];
+  __IO uint32_t AHBMATPRIO;                        /**< AHB Matrix priority control register, offset: 0x10 */
+       uint8_t RESERVED_1[44];
+  __IO uint32_t SYSTCKCAL;                         /**< System tick counter calibration, offset: 0x40 */
+       uint8_t RESERVED_2[4];
+  __IO uint32_t NMISRC;                            /**< NMI Source Select, offset: 0x48 */
+  __IO uint32_t ASYNCAPBCTRL;                      /**< Asynchronous APB Control, offset: 0x4C */
+       uint8_t RESERVED_3[176];
+  union {                                          /* offset: 0x100 */
+    struct {                                         /* offset: 0x100 */
+      __IO uint32_t PRESETCTRL0;                       /**< Peripheral reset control 0, offset: 0x100 */
+      __IO uint32_t PRESETCTRL1;                       /**< Peripheral reset control 1, offset: 0x104 */
+    } PRESETCTRL;
+    __IO uint32_t PRESETCTRLS[2];                    /**< Pin assign register, array offset: 0x100, array step: 0x4 */
+  };
+       uint8_t RESERVED_4[24];
+  union {                                          /* offset: 0x120 */
+    struct {                                         /* offset: 0x120 */
+      __O  uint32_t PRESETCTRLSET0;                    /**< Set bits in PRESETCTRL0. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers., offset: 0x120 */
+      __O  uint32_t PRESETCTRLSET1;                    /**< Set bits in PRESETCTRL1. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers., offset: 0x124 */
+    } PRESETCTRLSET;
+    __IO uint32_t PRESETCTRLSETS[2];                 /**< Pin assign register, array offset: 0x120, array step: 0x4 */
+  };
+       uint8_t RESERVED_5[24];
+  union {                                          /* offset: 0x140 */
+    struct {                                         /* offset: 0x140 */
+      __O  uint32_t PRESETCTRLCLR0;                    /**< Clear bits in PRESETCTRL0. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers., offset: 0x140 */
+      __O  uint32_t PRESETCTRLCLR1;                    /**< Clear bits in PRESETCTRL1. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers., offset: 0x144 */
+    } PRESETCTRLCLR;
+    __IO uint32_t PRESETCTRLCLRS[2];                 /**< Pin assign register, array offset: 0x140, array step: 0x4 */
+  };
+       uint8_t RESERVED_6[184];
+  union {                                          /* offset: 0x200 */
+    struct {                                         /* offset: 0x200 */
+      __IO uint32_t AHBCLKCTRL0;                       /**< AHB Clock control 0, offset: 0x200 */
+      __IO uint32_t AHBCLKCTRL1;                       /**< AHB Clock control 1, offset: 0x204 */
+    } AHBCLKCTRL;
+    __IO uint32_t AHBCLKCTRLS[2];                    /**< Pin assign register, array offset: 0x200, array step: 0x4 */
+  };
+       uint8_t RESERVED_7[24];
+  union {                                          /* offset: 0x220 */
+    struct {                                         /* offset: 0x220 */
+      __O  uint32_t AHBCLKCTRLSET0;                    /**< Set bits in AHBCLKCTRL0, offset: 0x220 */
+      __O  uint32_t AHBCLKCTRLSET1;                    /**< Set bits in AHBCLKCTRL1, offset: 0x224 */
+    } AHBCLKCTRLSET;
+    __IO uint32_t AHBCLKCTRLSETS[2];                 /**< Pin assign register, array offset: 0x220, array step: 0x4 */
+  };
+       uint8_t RESERVED_8[24];
+  union {                                          /* offset: 0x240 */
+    struct {                                         /* offset: 0x240 */
+      __O  uint32_t AHBCLKCTRLCLR0;                    /**< Clear bits in AHBCLKCTRL0, offset: 0x240 */
+      __O  uint32_t AHBCLKCTRLCLR1;                    /**< Clear bits in AHBCLKCTRL1, offset: 0x244 */
+    } AHBCLKCTRLCLR;
+    __IO uint32_t AHBCLKCTRLCLRS[2];                 /**< Pin assign register, array offset: 0x240, array step: 0x4 */
+  };
+       uint8_t RESERVED_9[56];
+  __IO uint32_t MAINCLKSEL;                        /**< Main clock source select, offset: 0x280 */
+  __IO uint32_t OSC32CLKSEL;                       /**< OSC32KCLK and OSC32MCLK clock sources select. Note: this register is not locked by CLOCKGENUPDATELOCKOUT, offset: 0x284 */
+  __IO uint32_t CLKOUTSEL;                         /**< CLKOUT clock source select, offset: 0x288 */
+       uint8_t RESERVED_10[20];
+  __IO uint32_t SPIFICLKSEL;                       /**< SPIFI clock source select, offset: 0x2A0 */
+  __IO uint32_t ADCCLKSEL;                         /**< ADC clock source select, offset: 0x2A4 */
+       uint8_t RESERVED_11[8];
+  __IO uint32_t USARTCLKSEL;                       /**< USART0 & 1 clock source select, offset: 0x2B0 */
+  __IO uint32_t I2CCLKSEL;                         /**< I2C0, 1 and 2 clock source select, offset: 0x2B4 */
+  __IO uint32_t SPICLKSEL;                         /**< SPI0 & 1 clock source select, offset: 0x2B8 */
+  __IO uint32_t IRCLKSEL;                          /**< Infra Red clock source select, offset: 0x2BC */
+  __IO uint32_t PWMCLKSEL;                         /**< PWM clock source select, offset: 0x2C0 */
+  __IO uint32_t WDTCLKSEL;                         /**< Watchdog Timer clock source select, offset: 0x2C4 */
+       uint8_t RESERVED_12[4];
+  __IO uint32_t MODEMCLKSEL;                       /**< Modem clock source select, offset: 0x2CC */
+       uint8_t RESERVED_13[24];
+  __IO uint32_t FRGCLKSEL;                         /**< Fractional Rate Generator (FRG) clock source select. The FRG is one of the USART clocking options., offset: 0x2E8 */
+  __IO uint32_t DMICCLKSEL;                        /**< Digital microphone (DMIC) subsystem clock select, offset: 0x2EC */
+  __IO uint32_t WKTCLKSEL;                         /**< Wake-up Timer clock select, offset: 0x2F0 */
+       uint8_t RESERVED_14[12];
+  __IO uint32_t SYSTICKCLKDIV;                     /**< SYSTICK clock divider. The SYSTICK clock can drive the SYSTICK function within the processor., offset: 0x300 */
+  __IO uint32_t TRACECLKDIV;                       /**< TRACE clock divider, used for part of the Serial debugger (SWD) feature., offset: 0x304 */
+       uint8_t RESERVED_15[100];
+  __IO uint32_t WDTCLKDIV;                         /**< Watchdog Timer clock divider, offset: 0x36C */
+       uint8_t RESERVED_16[8];
+  __IO uint32_t IRCLKDIV;                          /**< Infra Red clock divider, offset: 0x378 */
+       uint8_t RESERVED_17[4];
+  __IO uint32_t AHBCLKDIV;                         /**< System clock divider, offset: 0x380 */
+  __IO uint32_t CLKOUTDIV;                         /**< CLKOUT clock divider, offset: 0x384 */
+       uint8_t RESERVED_18[8];
+  __IO uint32_t SPIFICLKDIV;                       /**< SPIFI clock divider, offset: 0x390 */
+  __IO uint32_t ADCCLKDIV;                         /**< ADC clock divider, offset: 0x394 */
+  __IO uint32_t RTCCLKDIV;                         /**< Real Time Clock divider (1 KHz clock generation), offset: 0x398 */
+       uint8_t RESERVED_19[4];
+  __IO uint32_t FRGCTRL;                           /**< Fractional rate generator divider. The FRG is one of the USART clocking options., offset: 0x3A0 */
+       uint8_t RESERVED_20[4];
+  __IO uint32_t DMICCLKDIV;                        /**< DMIC clock divider, offset: 0x3A8 */
+  __IO uint32_t RTC1HZCLKDIV;                      /**< Real Time Clock divider (1 Hz clock generation. The divider is fixed to 32768), offset: 0x3AC */
+       uint8_t RESERVED_21[76];
+  __IO uint32_t CLOCKGENUPDATELOCKOUT;             /**< Control clock configuration registers access (like xxxDIV, xxxSEL), offset: 0x3FC */
+       uint8_t RESERVED_22[412];
+  __IO uint32_t RNGCLKCTRL;                        /**< Random Number Generator Clocks control, offset: 0x59C */
+  __IO uint32_t SRAMCTRL;                          /**< All SRAMs common control signals, offset: 0x5A0 */
+       uint8_t RESERVED_23[40];
+  __IO uint32_t MODEMCTRL;                         /**< 32K clock enable, offset: 0x5CC */
+       uint8_t RESERVED_24[4];
+  __IO uint32_t XTAL32KCAP;                        /**< XTAL 32 KHz oscillator Capacitor control, offset: 0x5D4 */
+  __IO uint32_t XTAL32MCTRL;                       /**< XTAL 32 MHz oscillator control register, offset: 0x5D8 */
+       uint8_t RESERVED_25[164];
+  union {                                          /* offset: 0x680 */
+    struct {                                         /* offset: 0x680 */
+      __IO uint32_t STARTER0;                          /**< Start logic 0 wake-up enable register. Enable an interrupt for wake-up from deep-sleep mode. Some bits can also control wake-up from powerdown mode, offset: 0x680 */
+      __IO uint32_t STARTER1;                          /**< Start logic 1 wake-up enable register. Enable an interrupt for wake-up from deep-sleep mode. Some bits can also control wake-up from powerdown mode, offset: 0x684 */
+    } STARTER;
+    __IO uint32_t STARTERS[2];                       /**< Pin assign register, array offset: 0x680, array step: 0x4 */
+  };
+       uint8_t RESERVED_26[24];
+  union {                                          /* offset: 0x6A0 */
+    struct {                                         /* offset: 0x6A0 */
+      __O  uint32_t STARTERSET0;                       /**< Set bits in STARTER0, offset: 0x6A0 */
+      __O  uint32_t STARTERSET1;                       /**< Set bits in STARTER1, offset: 0x6A4 */
+    } STARTERSET;
+    __IO uint32_t STARTERSETS[2];                    /**< Pin assign register, array offset: 0x6A0, array step: 0x4 */
+  };
+       uint8_t RESERVED_27[24];
+  union {                                          /* offset: 0x6C0 */
+    struct {                                         /* offset: 0x6C0 */
+      __O  uint32_t STARTERCLR0;                       /**< Clear bits in STARTER0, offset: 0x6C0 */
+      __O  uint32_t STARTERCLR1;                       /**< Clear bits in STARTER1, offset: 0x6C4 */
+    } STARTERCLR;
+    __IO uint32_t STARTERCLRS[2];                    /**< Pin assign register, array offset: 0x6C0, array step: 0x4 */
+  };
+       uint8_t RESERVED_28[64];
+  __IO uint32_t RETENTIONCTRL;                     /**< I/O retention control register, offset: 0x708 */
+       uint8_t RESERVED_29[252];
+  __IO uint32_t CPSTACK;                           /**< CPSTACK, offset: 0x808 */
+       uint8_t RESERVED_30[500];
+  __IO uint32_t ANACTRL_CTRL;                      /**< Analog Interrupt control register. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set., offset: 0xA00 */
+  __I  uint32_t ANACTRL_VAL;                       /**< Analog modules (BOD and Analog Comparator) outputs current values (BOD 'Power OK' and Analog comparator out). Requires AHBCLKCTRL0.ANA_INT_CTRL to be set., offset: 0xA04 */
+  __IO uint32_t ANACTRL_STAT;                      /**< Analog modules (BOD and Analog Comparator) interrupt status. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set., offset: 0xA08 */
+  __IO uint32_t ANACTRL_INTENSET;                  /**< Analog modules (BOD and Analog Comparator) Interrupt Enable Read and Set register. Read value indicates which interrupts are enabled. Writing ones sets the corresponding interrupt enable bits. Note, interrupt enable bits are cleared using ANACTRL_INTENCLR. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register., offset: 0xA0C */
+  __O  uint32_t ANACTRL_INTENCLR;                  /**< Analog modules (BOD and Analog Comparator) Interrupt Enable Clear register. Writing ones clears the corresponding interrupt enable bits. Note, interrupt enable bits are set in ANACTRL_INTENSET. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register., offset: 0xA10 */
+  __I  uint32_t ANACTRL_INTSTAT;                   /**< Analog modules (BOD and Analog Comparator) Interrupt Status register (masked with interrupt enable). Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register. Interrupt status bit are cleared using ANACTRL_STAT., offset: 0xA14 */
+  __IO uint32_t CLOCK_CTRL;                        /**< Various system clock controls : Flash clock (48 MHz) control, clocks to Frequency Measure function, offset: 0xA18 */
+       uint8_t RESERVED_31[4];
+  __IO uint32_t WKT_CTRL;                          /**< Wake-up timers control, offset: 0xA20 */
+  __IO uint32_t WKT_LOAD_WKT0_LSB;                 /**< Wake-up timer 0 reload value least significant bits ([31:0])., offset: 0xA24 */
+  __IO uint32_t WKT_LOAD_WKT0_MSB;                 /**< Wake-up timer 0 reload value most significant bits ([8:0])., offset: 0xA28 */
+  __IO uint32_t WKT_LOAD_WKT1;                     /**< Wake-up timer 1 reload value., offset: 0xA2C */
+  __I  uint32_t WKT_VAL_WKT0_LSB;                  /**< Wake-up timer 0 current value least significant bits ([31:0]). WARNING : reading not reliable: read this register several times until you get a stable value., offset: 0xA30 */
+  __I  uint32_t WKT_VAL_WKT0_MSB;                  /**< Wake-up timer 0 current value most significant bits ([8:0]). WARNING : reading not reliable: read this register several times until you get a stable value., offset: 0xA34 */
+  __I  uint32_t WKT_VAL_WKT1;                      /**< Wake-up timer 1 current value. WARNING : reading not reliable: read this register several times until you get a stable value., offset: 0xA38 */
+  __IO uint32_t WKT_STAT;                          /**< Wake-up timers status, offset: 0xA3C */
+  __IO uint32_t WKT_INTENSET;                      /**< Interrupt Enable Read and Set register, offset: 0xA40 */
+  __O  uint32_t WKT_INTENCLR;                      /**< Interrupt Enable Clear register, offset: 0xA44 */
+  __I  uint32_t WKT_INTSTAT;                       /**< Interrupt Status register, offset: 0xA48 */
+       uint8_t RESERVED_32[956];
+  __IO uint32_t GPIOPSYNC;                         /**< Enable bypass of the first stage of synchonization inside GPIO_INT module., offset: 0xE08 */
+       uint8_t RESERVED_33[420];
+  __I  uint32_t DIEID;                             /**< Chip revision ID & Number, offset: 0xFB0 */
+       uint8_t RESERVED_34[60];
+  __O  uint32_t CODESECURITYPROT;                  /**< Security code to allow test access via SWD/JTAG. Reset with POR, SW reset or BOD, offset: 0xFF0 */
+} SYSCON_Type;
+
+/* ----------------------------------------------------------------------------
+   -- SYSCON Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SYSCON_Register_Masks SYSCON Register Masks
+ * @{
+ */
+
+/*! @name MEMORYREMAP - Memory Remap control register */
+/*! @{ */
+#define SYSCON_MEMORYREMAP_MAP_MASK              (0x3U)
+#define SYSCON_MEMORYREMAP_MAP_SHIFT             (0U)
+/*! MAP - Select the location of the vector table : 0: Vector Table in ROM. 1: Vector Table in RAM.
+ *    2: Vector Table in Flash. 3: Vector Table in Flash.
+ */
+#define SYSCON_MEMORYREMAP_MAP(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_MAP_SHIFT)) & SYSCON_MEMORYREMAP_MAP_MASK)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0_MASK (0x300000U)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0_SHIFT (20U)
+/*! QSPI_REMAP_APP_0 - Address bits to use when QSPI Flash address [19:18] = 0 (256-KB unit page). Setting 00 gives no remapping.
+ */
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0_SHIFT)) & SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0_MASK)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1_MASK (0xC00000U)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1_SHIFT (22U)
+/*! QSPI_REMAP_APP_1 - Address bits to use when QSPI Flash address [19:18] = 1 (256-KB unit page). Setting 01 gives no remapping.
+ */
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1_SHIFT)) & SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1_MASK)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2_MASK (0x3000000U)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2_SHIFT (24U)
+/*! QSPI_REMAP_APP_2 - Address bits to use when QSPI Flash address [19:18] = 2 (256-KB unit page). Setting 10 gives no remapping.
+ */
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2_SHIFT)) & SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2_MASK)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3_MASK (0xC000000U)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3_SHIFT (26U)
+/*! QSPI_REMAP_APP_3 - Address bits to use when QSPI Flash address [19:18] = 3 (256-KB unit page). Setting 11 gives no remapping.
+ */
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3_SHIFT)) & SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3_MASK)
+/*! @} */
+
+/*! @name AHBMATPRIO - AHB Matrix priority control register */
+/*! @{ */
+#define SYSCON_AHBMATPRIO_AHBMATPRIO_MASK        (0xFFFFFFFFU)
+#define SYSCON_AHBMATPRIO_AHBMATPRIO_SHIFT       (0U)
+/*! AHBMATPRIO - AHB Matrix priority control register
+ */
+#define SYSCON_AHBMATPRIO_AHBMATPRIO(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_AHBMATPRIO_SHIFT)) & SYSCON_AHBMATPRIO_AHBMATPRIO_MASK)
+/*! @} */
+
+/*! @name SYSTCKCAL - System tick counter calibration */
+/*! @{ */
+#define SYSCON_SYSTCKCAL_CAL_MASK                (0xFFFFFFU)
+#define SYSCON_SYSTCKCAL_CAL_SHIFT               (0U)
+/*! CAL - Cortex System tick timer calibration value, readable from Cortex SYST_CALIB.TENMS register
+ *    field. Set this value to be the number of clock periods to give 10ms period. SYSTICK freq is
+ *    a function of the mainclk and SYSTICKCLKDIV register. If the tick timer is configured to use
+ *    the System clock directly then this value must reflect the 10ms tick count for that clock.
+ */
+#define SYSCON_SYSTCKCAL_CAL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_CAL_SHIFT)) & SYSCON_SYSTCKCAL_CAL_MASK)
+#define SYSCON_SYSTCKCAL_SKEW_MASK               (0x1000000U)
+#define SYSCON_SYSTCKCAL_SKEW_SHIFT              (24U)
+/*! SKEW - Cortex System tick timer SYST_CALIB.SKEW setting. When 0, the value of SYST_CALIB.TENMS
+ *    field is considered to be precise. When 1, the value of TENMS is not considered to be precise.
+ */
+#define SYSCON_SYSTCKCAL_SKEW(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_SKEW_SHIFT)) & SYSCON_SYSTCKCAL_SKEW_MASK)
+#define SYSCON_SYSTCKCAL_NOREF_MASK              (0x2000000U)
+#define SYSCON_SYSTCKCAL_NOREF_SHIFT             (25U)
+/*! NOREF - Cortex System tick timer SYST_CALIB.NOREF setting. When 0, a separate reference clock is
+ *    available. When 1, a separate reference clock is not available.
+ */
+#define SYSCON_SYSTCKCAL_NOREF(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_NOREF_SHIFT)) & SYSCON_SYSTCKCAL_NOREF_MASK)
+/*! @} */
+
+/*! @name NMISRC - NMI Source Select */
+/*! @{ */
+#define SYSCON_NMISRC_IRQM40_MASK                (0x3FU)
+#define SYSCON_NMISRC_IRQM40_SHIFT               (0U)
+/*! IRQM40 - The number of the interrupt source within the interrupt array that acts as the
+ *    Non-Maskable Interrupt (NMI) for the Cortex-M4, if enabled by NMIENM40. This can also cause the device
+ *    to wakeup from sleep.
+ */
+#define SYSCON_NMISRC_IRQM40(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_IRQM40_SHIFT)) & SYSCON_NMISRC_IRQM40_MASK)
+#define SYSCON_NMISRC_NMIENM40_MASK              (0x80000000U)
+#define SYSCON_NMISRC_NMIENM40_SHIFT             (31U)
+/*! NMIENM40 - Write a 1 to this bit to enable the Non-Maskable Interrupt (NMI) source selected by
+ *    IRQM40. The NMI Interrupt should be disabled before changing the source selection (IRQM40)
+ */
+#define SYSCON_NMISRC_NMIENM40(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_NMIENM40_SHIFT)) & SYSCON_NMISRC_NMIENM40_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCTRL - Asynchronous APB Control */
+/*! @{ */
+#define SYSCON_ASYNCAPBCTRL_ENABLE_MASK          (0x1U)
+#define SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT         (0U)
+/*! ENABLE - Enables the asynchronous APB bridge and subsystem
+ */
+#define SYSCON_ASYNCAPBCTRL_ENABLE(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT)) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK)
+/*! @} */
+
+/*! @name PRESETCTRL0 - Peripheral reset control 0 */
+/*! @{ */
+#define SYSCON_PRESETCTRL0_SPIFI_RST_MASK        (0x400U)
+#define SYSCON_PRESETCTRL0_SPIFI_RST_SHIFT       (10U)
+/*! SPIFI_RST - Quad SPI Flash controller reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_SPIFI_RST(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_SPIFI_RST_SHIFT)) & SYSCON_PRESETCTRL0_SPIFI_RST_MASK)
+#define SYSCON_PRESETCTRL0_MUX_RST_MASK          (0x800U)
+#define SYSCON_PRESETCTRL0_MUX_RST_SHIFT         (11U)
+/*! MUX_RST - Input Mux reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_MUX_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_MUX_RST_SHIFT)) & SYSCON_PRESETCTRL0_MUX_RST_MASK)
+#define SYSCON_PRESETCTRL0_IOCON_RST_MASK        (0x2000U)
+#define SYSCON_PRESETCTRL0_IOCON_RST_SHIFT       (13U)
+/*! IOCON_RST - I/O controller reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_IOCON_RST(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_IOCON_RST_SHIFT)) & SYSCON_PRESETCTRL0_IOCON_RST_MASK)
+#define SYSCON_PRESETCTRL0_GPIO_RST_MASK         (0x4000U)
+#define SYSCON_PRESETCTRL0_GPIO_RST_SHIFT        (14U)
+/*! GPIO_RST - GPIO reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_GPIO_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_GPIO_RST_SHIFT)) & SYSCON_PRESETCTRL0_GPIO_RST_MASK)
+#define SYSCON_PRESETCTRL0_PINT_RST_MASK         (0x40000U)
+#define SYSCON_PRESETCTRL0_PINT_RST_SHIFT        (18U)
+/*! PINT_RST - Pin interrupt (PINT) reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_PINT_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_PINT_RST_SHIFT)) & SYSCON_PRESETCTRL0_PINT_RST_MASK)
+#define SYSCON_PRESETCTRL0_GINT_RST_MASK         (0x80000U)
+#define SYSCON_PRESETCTRL0_GINT_RST_SHIFT        (19U)
+/*! GINT_RST - Group interrupt (GINT) reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_GINT_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_GINT_RST_SHIFT)) & SYSCON_PRESETCTRL0_GINT_RST_MASK)
+#define SYSCON_PRESETCTRL0_DMA_RST_MASK          (0x100000U)
+#define SYSCON_PRESETCTRL0_DMA_RST_SHIFT         (20U)
+/*! DMA_RST - DMA reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_DMA_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_DMA_RST_SHIFT)) & SYSCON_PRESETCTRL0_DMA_RST_MASK)
+#define SYSCON_PRESETCTRL0_ISO7816_RST_MASK      (0x200000U)
+#define SYSCON_PRESETCTRL0_ISO7816_RST_SHIFT     (21U)
+/*! ISO7816_RST - ISO7816 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_ISO7816_RST(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_ISO7816_RST_SHIFT)) & SYSCON_PRESETCTRL0_ISO7816_RST_MASK)
+#define SYSCON_PRESETCTRL0_WWDT_RST_MASK         (0x400000U)
+#define SYSCON_PRESETCTRL0_WWDT_RST_SHIFT        (22U)
+/*! WWDT_RST - Watchdog Timer reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_WWDT_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_WWDT_RST_SHIFT)) & SYSCON_PRESETCTRL0_WWDT_RST_MASK)
+#define SYSCON_PRESETCTRL0_RTC_RST_MASK          (0x800000U)
+#define SYSCON_PRESETCTRL0_RTC_RST_SHIFT         (23U)
+/*! RTC_RST - Real Time Clock (RTC) reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_RTC_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_RTC_RST_SHIFT)) & SYSCON_PRESETCTRL0_RTC_RST_MASK)
+#define SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_MASK (0x1000000U)
+#define SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_SHIFT (24U)
+/*! ANA_INT_CTRL_RST - Analog Modules Interrupt Controller reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_SHIFT)) & SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_MASK)
+#define SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_MASK (0x2000000U)
+#define SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_SHIFT (25U)
+/*! WAKE_UP_TIMERS_RST - Wake up Timers reset control. 0: Clear reset to this function. 1: Assert
+ *    reset to this function. This will clear interrupt status flag. However, configuration for wake
+ *    timers that is in SYSCON will not be reset, these should be managed through the SYSCON
+ *    regsiters.
+ */
+#define SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_SHIFT)) & SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_MASK)
+#define SYSCON_PRESETCTRL0_ADC_RST_MASK          (0x8000000U)
+#define SYSCON_PRESETCTRL0_ADC_RST_SHIFT         (27U)
+/*! ADC_RST - ADC reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_ADC_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_ADC_RST_SHIFT)) & SYSCON_PRESETCTRL0_ADC_RST_MASK)
+/*! @} */
+
+/*! @name PRESETCTRL1 - Peripheral reset control 1 */
+/*! @{ */
+#define SYSCON_PRESETCTRL1_USART0_RST_MASK       (0x800U)
+#define SYSCON_PRESETCTRL1_USART0_RST_SHIFT      (11U)
+/*! USART0_RST - UART0 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_USART0_RST(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_USART0_RST_SHIFT)) & SYSCON_PRESETCTRL1_USART0_RST_MASK)
+#define SYSCON_PRESETCTRL1_USART1_RST_MASK       (0x1000U)
+#define SYSCON_PRESETCTRL1_USART1_RST_SHIFT      (12U)
+/*! USART1_RST - UART1 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_USART1_RST(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_USART1_RST_SHIFT)) & SYSCON_PRESETCTRL1_USART1_RST_MASK)
+#define SYSCON_PRESETCTRL1_I2C0_RST_MASK         (0x2000U)
+#define SYSCON_PRESETCTRL1_I2C0_RST_SHIFT        (13U)
+/*! I2C0_RST - I2C0 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_I2C0_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_I2C0_RST_SHIFT)) & SYSCON_PRESETCTRL1_I2C0_RST_MASK)
+#define SYSCON_PRESETCTRL1_I2C1_RST_MASK         (0x4000U)
+#define SYSCON_PRESETCTRL1_I2C1_RST_SHIFT        (14U)
+/*! I2C1_RST - I2C1 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_I2C1_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_I2C1_RST_SHIFT)) & SYSCON_PRESETCTRL1_I2C1_RST_MASK)
+#define SYSCON_PRESETCTRL1_SPI0_RST_MASK         (0x8000U)
+#define SYSCON_PRESETCTRL1_SPI0_RST_SHIFT        (15U)
+/*! SPI0_RST - SPI0 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_SPI0_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_SPI0_RST_SHIFT)) & SYSCON_PRESETCTRL1_SPI0_RST_MASK)
+#define SYSCON_PRESETCTRL1_SPI1_RST_MASK         (0x10000U)
+#define SYSCON_PRESETCTRL1_SPI1_RST_SHIFT        (16U)
+/*! SPI1_RST - SPI1 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_SPI1_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_SPI1_RST_SHIFT)) & SYSCON_PRESETCTRL1_SPI1_RST_MASK)
+#define SYSCON_PRESETCTRL1_IR_RST_MASK           (0x20000U)
+#define SYSCON_PRESETCTRL1_IR_RST_SHIFT          (17U)
+/*! IR_RST - Infra Red reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_IR_RST(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_IR_RST_SHIFT)) & SYSCON_PRESETCTRL1_IR_RST_MASK)
+#define SYSCON_PRESETCTRL1_PWM_RST_MASK          (0x40000U)
+#define SYSCON_PRESETCTRL1_PWM_RST_SHIFT         (18U)
+/*! PWM_RST - PWM reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_PWM_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_PWM_RST_SHIFT)) & SYSCON_PRESETCTRL1_PWM_RST_MASK)
+#define SYSCON_PRESETCTRL1_RNG_RST_MASK          (0x80000U)
+#define SYSCON_PRESETCTRL1_RNG_RST_SHIFT         (19U)
+/*! RNG_RST - Random Number Generator reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_RNG_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_RNG_RST_SHIFT)) & SYSCON_PRESETCTRL1_RNG_RST_MASK)
+#define SYSCON_PRESETCTRL1_I2C2_RST_MASK         (0x100000U)
+#define SYSCON_PRESETCTRL1_I2C2_RST_SHIFT        (20U)
+/*! I2C2_RST - I2C2 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_I2C2_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_I2C2_RST_SHIFT)) & SYSCON_PRESETCTRL1_I2C2_RST_MASK)
+#define SYSCON_PRESETCTRL1_ZIGBEE_RST_MASK       (0x200000U)
+#define SYSCON_PRESETCTRL1_ZIGBEE_RST_SHIFT      (21U)
+/*! ZIGBEE_RST - Zigbee reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_ZIGBEE_RST(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_ZIGBEE_RST_SHIFT)) & SYSCON_PRESETCTRL1_ZIGBEE_RST_MASK)
+#define SYSCON_PRESETCTRL1_MODEM_MASTER_RST_MASK (0x800000U)
+#define SYSCON_PRESETCTRL1_MODEM_MASTER_RST_SHIFT (23U)
+/*! MODEM_MASTER_RST - MODEM AHB Master Interface reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_MODEM_MASTER_RST(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_MODEM_MASTER_RST_SHIFT)) & SYSCON_PRESETCTRL1_MODEM_MASTER_RST_MASK)
+#define SYSCON_PRESETCTRL1_AES_RST_MASK          (0x1000000U)
+#define SYSCON_PRESETCTRL1_AES_RST_SHIFT         (24U)
+/*! AES_RST - AES256 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_AES_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_AES_RST_SHIFT)) & SYSCON_PRESETCTRL1_AES_RST_MASK)
+#define SYSCON_PRESETCTRL1_RFP_RST_MASK          (0x2000000U)
+#define SYSCON_PRESETCTRL1_RFP_RST_SHIFT         (25U)
+/*! RFP_RST - RFP (Radio controller) reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_RFP_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_RFP_RST_SHIFT)) & SYSCON_PRESETCTRL1_RFP_RST_MASK)
+#define SYSCON_PRESETCTRL1_DMIC_RST_MASK         (0x4000000U)
+#define SYSCON_PRESETCTRL1_DMIC_RST_SHIFT        (26U)
+/*! DMIC_RST - DMIC Reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_DMIC_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_DMIC_RST_SHIFT)) & SYSCON_PRESETCTRL1_DMIC_RST_MASK)
+#define SYSCON_PRESETCTRL1_HASH_RST_MASK         (0x8000000U)
+#define SYSCON_PRESETCTRL1_HASH_RST_SHIFT        (27U)
+/*! HASH_RST - HASH reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_HASH_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_HASH_RST_SHIFT)) & SYSCON_PRESETCTRL1_HASH_RST_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLX_PRESETCTRLS - Pin assign register */
+/*! @{ */
+#define SYSCON_PRESETCTRLX_PRESETCTRLS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_PRESETCTRLX_PRESETCTRLS_DATA_SHIFT (0U)
+#define SYSCON_PRESETCTRLX_PRESETCTRLS_DATA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLX_PRESETCTRLS_DATA_SHIFT)) & SYSCON_PRESETCTRLX_PRESETCTRLS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_PRESETCTRLX_PRESETCTRLS */
+#define SYSCON_PRESETCTRLX_PRESETCTRLS_COUNT     (2U)
+
+/*! @name PRESETCTRLSET0 - Set bits in PRESETCTRL0. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers. */
+/*! @{ */
+#define SYSCON_PRESETCTRLSET0_SPIFI_RST_SET_MASK (0x400U)
+#define SYSCON_PRESETCTRLSET0_SPIFI_RST_SET_SHIFT (10U)
+/*! SPIFI_RST_SET - Writing one to this register sets the SPIFI_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_SPIFI_RST_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_SPIFI_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_SPIFI_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_MUX_RST_SET_MASK   (0x800U)
+#define SYSCON_PRESETCTRLSET0_MUX_RST_SET_SHIFT  (11U)
+/*! MUX_RST_SET - Writing one to this register sets the MUX_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_MUX_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_MUX_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_MUX_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_IOCON_RST_SET_MASK (0x2000U)
+#define SYSCON_PRESETCTRLSET0_IOCON_RST_SET_SHIFT (13U)
+/*! IOCON_RST_SET - Writing one to this register sets the IOCON_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_IOCON_RST_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_IOCON_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_IOCON_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_GPIO_RST_SET_MASK  (0x4000U)
+#define SYSCON_PRESETCTRLSET0_GPIO_RST_SET_SHIFT (14U)
+/*! GPIO_RST_SET - Writing one to this register sets the GPIO_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_GPIO_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_GPIO_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_GPIO_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_PINT_RST_SET_MASK  (0x40000U)
+#define SYSCON_PRESETCTRLSET0_PINT_RST_SET_SHIFT (18U)
+/*! PINT_RST_SET - Writing one to this register sets the PINT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_PINT_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_PINT_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_PINT_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_GINT_RST_SET_MASK  (0x80000U)
+#define SYSCON_PRESETCTRLSET0_GINT_RST_SET_SHIFT (19U)
+/*! GINT_RST_SET - Writing one to this register sets the GINT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_GINT_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_GINT_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_GINT_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_DMA_RST_SET_MASK   (0x100000U)
+#define SYSCON_PRESETCTRLSET0_DMA_RST_SET_SHIFT  (20U)
+/*! DMA_RST_SET - Writing one to this register sets the DMA_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_DMA_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_DMA_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_DMA_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_ISO7816_RST_SET_MASK (0x200000U)
+#define SYSCON_PRESETCTRLSET0_ISO7816_RST_SET_SHIFT (21U)
+/*! ISO7816_RST_SET - Writing one to this register sets the ISO7816_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_ISO7816_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_ISO7816_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_ISO7816_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_WWDT_RST_SET_MASK  (0x400000U)
+#define SYSCON_PRESETCTRLSET0_WWDT_RST_SET_SHIFT (22U)
+/*! WWDT_RST_SET - Writing one to this register sets the WWDT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_WWDT_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_WWDT_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_WWDT_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_RTC_RST_SET_MASK   (0x800000U)
+#define SYSCON_PRESETCTRLSET0_RTC_RST_SET_SHIFT  (23U)
+/*! RTC_RST_SET - Writing one to this register sets the RTC_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_RTC_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_RTC_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_RTC_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET_MASK (0x1000000U)
+#define SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET_SHIFT (24U)
+/*! ANA_INT_CTRL_RST_SET - Writing one to this register sets the ANA_INT_CTRL_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET_MASK (0x2000000U)
+#define SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET_SHIFT (25U)
+/*! WAKE_UP_TIMERS_RST_SET - Writing one to this register sets the WAKE_UP_TIMERS bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_ADC_RST_SET_MASK   (0x8000000U)
+#define SYSCON_PRESETCTRLSET0_ADC_RST_SET_SHIFT  (27U)
+/*! ADC_RST_SET - Writing one to this register sets the ADC_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_ADC_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_ADC_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_ADC_RST_SET_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLSET1 - Set bits in PRESETCTRL1. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers. */
+/*! @{ */
+#define SYSCON_PRESETCTRLSET1_USART0_RST_SET_MASK (0x800U)
+#define SYSCON_PRESETCTRLSET1_USART0_RST_SET_SHIFT (11U)
+/*! USART0_RST_SET - Writing one to this register sets the UART0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_USART0_RST_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_USART0_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_USART0_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_USART1_RST_SET_MASK (0x1000U)
+#define SYSCON_PRESETCTRLSET1_USART1_RST_SET_SHIFT (12U)
+/*! USART1_RST_SET - Writing one to this register sets the UART1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_USART1_RST_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_USART1_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_USART1_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_I2C0_RST_SET_MASK  (0x2000U)
+#define SYSCON_PRESETCTRLSET1_I2C0_RST_SET_SHIFT (13U)
+/*! I2C0_RST_SET - Writing one to this register sets the I2C0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_I2C0_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_I2C0_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_I2C0_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_I2C1_RST_SET_MASK  (0x4000U)
+#define SYSCON_PRESETCTRLSET1_I2C1_RST_SET_SHIFT (14U)
+/*! I2C1_RST_SET - Writing one to this register sets the I2C1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_I2C1_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_I2C1_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_I2C1_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_SPI0_RST_SET_MASK  (0x8000U)
+#define SYSCON_PRESETCTRLSET1_SPI0_RST_SET_SHIFT (15U)
+/*! SPI0_RST_SET - Writing one to this register sets the SPI0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_SPI0_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_SPI0_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_SPI0_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_SPI1_RST_SET_MASK  (0x10000U)
+#define SYSCON_PRESETCTRLSET1_SPI1_RST_SET_SHIFT (16U)
+/*! SPI1_RST_SET - Writing one to this register sets the SPI1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_SPI1_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_SPI1_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_SPI1_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_IR_RST_SET_MASK    (0x20000U)
+#define SYSCON_PRESETCTRLSET1_IR_RST_SET_SHIFT   (17U)
+/*! IR_RST_SET - Writing one to this register sets the IR_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_IR_RST_SET(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_IR_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_IR_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_PWM_RST_SET_MASK   (0x40000U)
+#define SYSCON_PRESETCTRLSET1_PWM_RST_SET_SHIFT  (18U)
+/*! PWM_RST_SET - Writing one to this register sets the PWM_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_PWM_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_PWM_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_PWM_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_RNG_RST_SET_MASK   (0x80000U)
+#define SYSCON_PRESETCTRLSET1_RNG_RST_SET_SHIFT  (19U)
+/*! RNG_RST_SET - Writing one to this register sets the RNG_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_RNG_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_RNG_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_RNG_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_I2C2_RST_SET_MASK  (0x100000U)
+#define SYSCON_PRESETCTRLSET1_I2C2_RST_SET_SHIFT (20U)
+/*! I2C2_RST_SET - Writing one to this register sets the I2C2_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_I2C2_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_I2C2_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_I2C2_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET_MASK (0x200000U)
+#define SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET_SHIFT (21U)
+/*! ZIGBEE_RST_SET - Writing one to this register sets the ZIGBEE_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET_MASK (0x800000U)
+#define SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET_SHIFT (23U)
+/*! MODEM_MASTER_RST_SET - Writing one to this register sets the MODEM_MASTER_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_AES_RST_SET_MASK   (0x1000000U)
+#define SYSCON_PRESETCTRLSET1_AES_RST_SET_SHIFT  (24U)
+/*! AES_RST_SET - Writing one to this register sets the AES_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_AES_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_AES_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_AES_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_RFP_RST_SET_MASK   (0x2000000U)
+#define SYSCON_PRESETCTRLSET1_RFP_RST_SET_SHIFT  (25U)
+/*! RFP_RST_SET - Writing one to this register sets the RFP_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_RFP_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_RFP_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_RFP_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_DMIC_RST_SET_MASK  (0x4000000U)
+#define SYSCON_PRESETCTRLSET1_DMIC_RST_SET_SHIFT (26U)
+/*! DMIC_RST_SET - Writing one to this register sets the DMIC_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_DMIC_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_DMIC_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_DMIC_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_HASH_RST_SET_MASK  (0x8000000U)
+#define SYSCON_PRESETCTRLSET1_HASH_RST_SET_SHIFT (27U)
+/*! HASH_RST_SET - Writing one to this register sets the HASH_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_HASH_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_HASH_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_HASH_RST_SET_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLSETX_PRESETCTRLSETS - Pin assign register */
+/*! @{ */
+#define SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA_SHIFT (0U)
+#define SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA_SHIFT)) & SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_PRESETCTRLSETX_PRESETCTRLSETS */
+#define SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_COUNT (2U)
+
+/*! @name PRESETCTRLCLR0 - Clear bits in PRESETCTRL0. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers. */
+/*! @{ */
+#define SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR_MASK (0x400U)
+#define SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR_SHIFT (10U)
+/*! SPIFI_RST_CLR - Writing one to this register clears the SPIFI_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_MUX_RST_CLR_MASK   (0x800U)
+#define SYSCON_PRESETCTRLCLR0_MUX_RST_CLR_SHIFT  (11U)
+/*! MUX_RST_CLR - Writing one to this register clears the MUX_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_MUX_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_MUX_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_MUX_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR_MASK (0x2000U)
+#define SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR_SHIFT (13U)
+/*! IOCON_RST_CLR - Writing one to this register clears the IOCON_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR_MASK  (0x4000U)
+#define SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR_SHIFT (14U)
+/*! GPIO_RST_CLR - Writing one to this register clears the GPIO_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_PINT_RST_CLR_MASK  (0x40000U)
+#define SYSCON_PRESETCTRLCLR0_PINT_RST_CLR_SHIFT (18U)
+/*! PINT_RST_CLR - Writing one to this register clears the PINT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_PINT_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_PINT_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_PINT_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_GINT_RST_CLR_MASK  (0x80000U)
+#define SYSCON_PRESETCTRLCLR0_GINT_RST_CLR_SHIFT (19U)
+/*! GINT_RST_CLR - Writing one to this register clears the GINT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_GINT_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_GINT_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_GINT_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_DMA_RST_CLR_MASK   (0x100000U)
+#define SYSCON_PRESETCTRLCLR0_DMA_RST_CLR_SHIFT  (20U)
+/*! DMA_RST_CLR - Writing one to this register clears the DMA_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_DMA_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_DMA_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_DMA_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR_MASK (0x200000U)
+#define SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR_SHIFT (21U)
+/*! ISO7816_RST_CLR - Writing one to this register clears the ISO7816_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR_MASK  (0x400000U)
+#define SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR_SHIFT (22U)
+/*! WWDT_RST_CLR - Writing one to this register clears the WWDT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_RTC_RST_CLR_MASK   (0x800000U)
+#define SYSCON_PRESETCTRLCLR0_RTC_RST_CLR_SHIFT  (23U)
+/*! RTC_RST_CLR - Writing one to this register clears the RTC_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_RTC_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_RTC_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_RTC_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR_MASK (0x1000000U)
+#define SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR_SHIFT (24U)
+/*! ANA_INT_CTRL_RST_CLR - Writing one to this register clears the ANA_INT_CTRL_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR_MASK (0x2000000U)
+#define SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR_SHIFT (25U)
+/*! WAKE_UP_TIMERS_RST_CLR - Writing one to this register clears the WAKE_UP_TIMERS_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_ADC_RST_CLR_MASK   (0x8000000U)
+#define SYSCON_PRESETCTRLCLR0_ADC_RST_CLR_SHIFT  (27U)
+/*! ADC_RST_CLR - Writing one to this register clears the ADC_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_ADC_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_ADC_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_ADC_RST_CLR_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLCLR1 - Clear bits in PRESETCTRL1. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers. */
+/*! @{ */
+#define SYSCON_PRESETCTRLCLR1_USART0_RST_CLR_MASK (0x800U)
+#define SYSCON_PRESETCTRLCLR1_USART0_RST_CLR_SHIFT (11U)
+/*! USART0_RST_CLR - Writing one to this register clears the UART0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_USART0_RST_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_USART0_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_USART0_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_USART1_RST_CLR_MASK (0x1000U)
+#define SYSCON_PRESETCTRLCLR1_USART1_RST_CLR_SHIFT (12U)
+/*! USART1_RST_CLR - Writing one to this register clears the UART1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_USART1_RST_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_USART1_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_USART1_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR_MASK  (0x2000U)
+#define SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR_SHIFT (13U)
+/*! I2C0_RST_CLR - Writing one to this register clears the I2C0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR_MASK  (0x4000U)
+#define SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR_SHIFT (14U)
+/*! I2C1_RST_CLR - Writing one to this register clears the I2C1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR_MASK  (0x8000U)
+#define SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR_SHIFT (15U)
+/*! SPI0_RST_CLR - Writing one to this register clears the SPI0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR_MASK  (0x10000U)
+#define SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR_SHIFT (16U)
+/*! SPI1_RST_CLR - Writing one to this register clears the SPI1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_IR_RST_CLR_MASK    (0x20000U)
+#define SYSCON_PRESETCTRLCLR1_IR_RST_CLR_SHIFT   (17U)
+/*! IR_RST_CLR - Writing one to this register clears the IR_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_IR_RST_CLR(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_IR_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_IR_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_PWM_RST_CLR_MASK   (0x40000U)
+#define SYSCON_PRESETCTRLCLR1_PWM_RST_CLR_SHIFT  (18U)
+/*! PWM_RST_CLR - Writing one to this register clears the PWM_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_PWM_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_PWM_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_PWM_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_MASK   (0x80000U)
+#define SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_SHIFT  (19U)
+/*! RNG_RST_CLR - Writing one to this register clears the RNG_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_RNG_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR_MASK  (0x100000U)
+#define SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR_SHIFT (20U)
+/*! I2C2_RST_CLR - Writing one to this register clears the I2C2_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR_MASK (0x200000U)
+#define SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR_SHIFT (21U)
+/*! ZIGBEE_RST_CLR - Writing one to this register clears the ZIGBEE_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR_MASK (0x800000U)
+#define SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR_SHIFT (23U)
+/*! MODEM_MASTER_RST_CLR - Writing one to this register clears the MODEM_MASTER_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_AES_RST_CLR_MASK   (0x1000000U)
+#define SYSCON_PRESETCTRLCLR1_AES_RST_CLR_SHIFT  (24U)
+/*! AES_RST_CLR - Writing one to this register clears the AES_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_AES_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_AES_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_AES_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_RFP_RST_CLR_MASK   (0x2000000U)
+#define SYSCON_PRESETCTRLCLR1_RFP_RST_CLR_SHIFT  (25U)
+/*! RFP_RST_CLR - Writing one to this register clears the RFP_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_RFP_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_RFP_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_RFP_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR_MASK  (0x4000000U)
+#define SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR_SHIFT (26U)
+/*! DMIC_RST_CLR - Writing one to this register clears the DMIC_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_HASH_RST_CLR_MASK  (0x8000000U)
+#define SYSCON_PRESETCTRLCLR1_HASH_RST_CLR_SHIFT (27U)
+/*! HASH_RST_CLR - Writing one to this register clears the HASH_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_HASH_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_HASH_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_HASH_RST_CLR_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLCLRX_PRESETCTRLCLRS - Pin assign register */
+/*! @{ */
+#define SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA_SHIFT (0U)
+#define SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA_SHIFT)) & SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS */
+#define SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_COUNT (2U)
+
+/*! @name AHBCLKCTRL0 - AHB Clock control 0 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL0_MASK       (0x8U)
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL0_SHIFT      (3U)
+/*! SRAM_CTRL0 - Enables the clock for the SRAM Controller 0 (SRAM 0 to SRAM 7). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL0(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_SRAM_CTRL0_SHIFT)) & SYSCON_AHBCLKCTRL0_SRAM_CTRL0_MASK)
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL1_MASK       (0x10U)
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL1_SHIFT      (4U)
+/*! SRAM_CTRL1 - Enables the clock for the SRAM Controller 1 (SRAM 8 to SRAM 11). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL1(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_SRAM_CTRL1_SHIFT)) & SYSCON_AHBCLKCTRL0_SRAM_CTRL1_MASK)
+#define SYSCON_AHBCLKCTRL0_SPIFI_MASK            (0x400U)
+#define SYSCON_AHBCLKCTRL0_SPIFI_SHIFT           (10U)
+/*! SPIFI - Enables the clock for the Quad SPI Flash controller [Note: SPIFI IOs need configuring
+ *    for high drive]. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_SPIFI(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_SPIFI_SHIFT)) & SYSCON_AHBCLKCTRL0_SPIFI_MASK)
+#define SYSCON_AHBCLKCTRL0_MUX_MASK              (0x800U)
+#define SYSCON_AHBCLKCTRL0_MUX_SHIFT             (11U)
+/*! MUX - Enables the clock for the Input Mux. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_MUX(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_MUX_SHIFT)) & SYSCON_AHBCLKCTRL0_MUX_MASK)
+#define SYSCON_AHBCLKCTRL0_IOCON_MASK            (0x2000U)
+#define SYSCON_AHBCLKCTRL0_IOCON_SHIFT           (13U)
+/*! IOCON - Enables the clock for the I/O controller block. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_IOCON(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_IOCON_SHIFT)) & SYSCON_AHBCLKCTRL0_IOCON_MASK)
+#define SYSCON_AHBCLKCTRL0_GPIO_MASK             (0x4000U)
+#define SYSCON_AHBCLKCTRL0_GPIO_SHIFT            (14U)
+/*! GPIO - Enables the clock for the GPIO. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_GPIO(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_GPIO_SHIFT)) & SYSCON_AHBCLKCTRL0_GPIO_MASK)
+#define SYSCON_AHBCLKCTRL0_PINT_MASK             (0x40000U)
+#define SYSCON_AHBCLKCTRL0_PINT_SHIFT            (18U)
+/*! PINT - Enables the clock for the Pin interrupt block (PINT). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_PINT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_PINT_SHIFT)) & SYSCON_AHBCLKCTRL0_PINT_MASK)
+#define SYSCON_AHBCLKCTRL0_GINT_MASK             (0x80000U)
+#define SYSCON_AHBCLKCTRL0_GINT_SHIFT            (19U)
+/*! GINT - Enables the clock for the Group interrupt block (GINT). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_GINT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_GINT_SHIFT)) & SYSCON_AHBCLKCTRL0_GINT_MASK)
+#define SYSCON_AHBCLKCTRL0_DMA_MASK              (0x100000U)
+#define SYSCON_AHBCLKCTRL0_DMA_SHIFT             (20U)
+/*! DMA - Enables the clock for the DMA controller. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_DMA(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_DMA_SHIFT)) & SYSCON_AHBCLKCTRL0_DMA_MASK)
+#define SYSCON_AHBCLKCTRL0_ISO7816_MASK          (0x200000U)
+#define SYSCON_AHBCLKCTRL0_ISO7816_SHIFT         (21U)
+/*! ISO7816 - Enables the clock for the ISO7816 smart card interface. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_ISO7816(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_ISO7816_SHIFT)) & SYSCON_AHBCLKCTRL0_ISO7816_MASK)
+#define SYSCON_AHBCLKCTRL0_WWDT_MASK             (0x400000U)
+#define SYSCON_AHBCLKCTRL0_WWDT_SHIFT            (22U)
+/*! WWDT - Enables the clock for the Watchdog Timer. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_WWDT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_WWDT_SHIFT)) & SYSCON_AHBCLKCTRL0_WWDT_MASK)
+#define SYSCON_AHBCLKCTRL0_RTC_MASK              (0x800000U)
+#define SYSCON_AHBCLKCTRL0_RTC_SHIFT             (23U)
+/*! RTC - Enables the clock for the RTC. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_RTC(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_RTC_SHIFT)) & SYSCON_AHBCLKCTRL0_RTC_MASK)
+#define SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_MASK     (0x1000000U)
+#define SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_SHIFT    (24U)
+/*! ANA_INT_CTRL - Enables the clock for the Analog Interrupt Control module (for BOD and comparator
+ *    status and interrupt control). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_ANA_INT_CTRL(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_SHIFT)) & SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_MASK)
+#define SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_MASK   (0x2000000U)
+#define SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_SHIFT  (25U)
+/*! WAKE_UP_TIMERS - Enables the clock for the Wake up Timers. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_SHIFT)) & SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_MASK)
+#define SYSCON_AHBCLKCTRL0_ADC_MASK              (0x8000000U)
+#define SYSCON_AHBCLKCTRL0_ADC_SHIFT             (27U)
+/*! ADC - Enables the clock for the ADC Controller. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_ADC(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_ADC_SHIFT)) & SYSCON_AHBCLKCTRL0_ADC_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRL1 - AHB Clock control 1 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRL1_USART0_MASK           (0x800U)
+#define SYSCON_AHBCLKCTRL1_USART0_SHIFT          (11U)
+/*! USART0 - Enable the clock for the UART0. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_USART0(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_USART0_SHIFT)) & SYSCON_AHBCLKCTRL1_USART0_MASK)
+#define SYSCON_AHBCLKCTRL1_USART1_MASK           (0x1000U)
+#define SYSCON_AHBCLKCTRL1_USART1_SHIFT          (12U)
+/*! USART1 - Enable the clock for the UART1. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_USART1(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_USART1_SHIFT)) & SYSCON_AHBCLKCTRL1_USART1_MASK)
+#define SYSCON_AHBCLKCTRL1_I2C0_MASK             (0x2000U)
+#define SYSCON_AHBCLKCTRL1_I2C0_SHIFT            (13U)
+/*! I2C0 - Enable the clock for the I2C0. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_I2C0(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_I2C0_SHIFT)) & SYSCON_AHBCLKCTRL1_I2C0_MASK)
+#define SYSCON_AHBCLKCTRL1_I2C1_MASK             (0x4000U)
+#define SYSCON_AHBCLKCTRL1_I2C1_SHIFT            (14U)
+/*! I2C1 - Enable the clock for the I2C1. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_I2C1(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_I2C1_SHIFT)) & SYSCON_AHBCLKCTRL1_I2C1_MASK)
+#define SYSCON_AHBCLKCTRL1_SPI0_MASK             (0x8000U)
+#define SYSCON_AHBCLKCTRL1_SPI0_SHIFT            (15U)
+/*! SPI0 - Enable the clock for the SPI0. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_SPI0(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_SPI0_SHIFT)) & SYSCON_AHBCLKCTRL1_SPI0_MASK)
+#define SYSCON_AHBCLKCTRL1_SPI1_MASK             (0x10000U)
+#define SYSCON_AHBCLKCTRL1_SPI1_SHIFT            (16U)
+/*! SPI1 - Enable the clock for the SPI1. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_SPI1(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_SPI1_SHIFT)) & SYSCON_AHBCLKCTRL1_SPI1_MASK)
+#define SYSCON_AHBCLKCTRL1_IR_MASK               (0x20000U)
+#define SYSCON_AHBCLKCTRL1_IR_SHIFT              (17U)
+/*! IR - Enable the clock for the Infra Red. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_IR(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_IR_SHIFT)) & SYSCON_AHBCLKCTRL1_IR_MASK)
+#define SYSCON_AHBCLKCTRL1_PWM_MASK              (0x40000U)
+#define SYSCON_AHBCLKCTRL1_PWM_SHIFT             (18U)
+/*! PWM - Enable the clock for the PWM. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_PWM(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_PWM_SHIFT)) & SYSCON_AHBCLKCTRL1_PWM_MASK)
+#define SYSCON_AHBCLKCTRL1_RNG_MASK              (0x80000U)
+#define SYSCON_AHBCLKCTRL1_RNG_SHIFT             (19U)
+/*! RNG - Enable the clock for the Random Number Generator. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_RNG(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_RNG_SHIFT)) & SYSCON_AHBCLKCTRL1_RNG_MASK)
+#define SYSCON_AHBCLKCTRL1_I2C2_MASK             (0x100000U)
+#define SYSCON_AHBCLKCTRL1_I2C2_SHIFT            (20U)
+/*! I2C2 - Enable the clock for the I2C2. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_I2C2(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_I2C2_SHIFT)) & SYSCON_AHBCLKCTRL1_I2C2_MASK)
+#define SYSCON_AHBCLKCTRL1_ZIGBEE_MASK           (0x200000U)
+#define SYSCON_AHBCLKCTRL1_ZIGBEE_SHIFT          (21U)
+/*! ZIGBEE - Enable the clock for the Zigbee Modem . 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_ZIGBEE(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_ZIGBEE_SHIFT)) & SYSCON_AHBCLKCTRL1_ZIGBEE_MASK)
+#define SYSCON_AHBCLKCTRL1_MODEM_MASTER_MASK     (0x800000U)
+#define SYSCON_AHBCLKCTRL1_MODEM_MASTER_SHIFT    (23U)
+/*! MODEM_MASTER - Enable the clock for the Modem AHB Master Interface. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_MODEM_MASTER(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_MODEM_MASTER_SHIFT)) & SYSCON_AHBCLKCTRL1_MODEM_MASTER_MASK)
+#define SYSCON_AHBCLKCTRL1_AES_MASK              (0x1000000U)
+#define SYSCON_AHBCLKCTRL1_AES_SHIFT             (24U)
+/*! AES - Enable the clock for the AES. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_AES(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_AES_SHIFT)) & SYSCON_AHBCLKCTRL1_AES_MASK)
+#define SYSCON_AHBCLKCTRL1_RFP_MASK              (0x2000000U)
+#define SYSCON_AHBCLKCTRL1_RFP_SHIFT             (25U)
+/*! RFP - Enable the clock for the RFP (Radio Front End controller). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_RFP(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_RFP_SHIFT)) & SYSCON_AHBCLKCTRL1_RFP_MASK)
+#define SYSCON_AHBCLKCTRL1_DMIC_MASK             (0x4000000U)
+#define SYSCON_AHBCLKCTRL1_DMIC_SHIFT            (26U)
+/*! DMIC - Enable the clock for the DMIC. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_DMIC(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_DMIC_SHIFT)) & SYSCON_AHBCLKCTRL1_DMIC_MASK)
+#define SYSCON_AHBCLKCTRL1_HASH_MASK             (0x8000000U)
+#define SYSCON_AHBCLKCTRL1_HASH_SHIFT            (27U)
+/*! HASH - Enable the clock for the Hash. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_HASH(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_HASH_SHIFT)) & SYSCON_AHBCLKCTRL1_HASH_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLX_AHBCLKCTRLS - Pin assign register */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA_SHIFT (0U)
+#define SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA_SHIFT)) & SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_AHBCLKCTRLX_AHBCLKCTRLS */
+#define SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_COUNT     (2U)
+
+/*! @name AHBCLKCTRLSET0 - Set bits in AHBCLKCTRL0 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET_MASK (0x8U)
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET_SHIFT (3U)
+/*! SRAM_CTRL0_CLK_SET - Writing one to this register sets the SRAM_CTRL0 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET_MASK (0x10U)
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET_SHIFT (4U)
+/*! SRAM_CTRL1_CLK_SET - Writing one to this register sets the SRAM_CTRL1 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET_MASK (0x400U)
+#define SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET_SHIFT (10U)
+/*! SPIFI_CLK_SET - Writing one to this register sets the SPIFI bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET_MASK   (0x800U)
+#define SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET_SHIFT  (11U)
+/*! MUX_CLK_SET - Writing one to this register sets the MUX bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET_MASK (0x2000U)
+#define SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET_SHIFT (13U)
+/*! IOCON_CLK_SET - Writing one to this register sets the IOCON bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET_MASK  (0x4000U)
+#define SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET_SHIFT (14U)
+/*! GPIO_CLK_SET - Writing one to this register sets the GPIO bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET_MASK  (0x40000U)
+#define SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET_SHIFT (18U)
+/*! PINT_CLK_SET - Writing one to this register sets the PINT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET_MASK  (0x80000U)
+#define SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET_SHIFT (19U)
+/*! GINT_CLK_SET - Writing one to this register sets the GINT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET_MASK   (0x100000U)
+#define SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET_SHIFT  (20U)
+/*! DMA_CLK_SET - Writing one to this register sets the DMA bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET_MASK (0x200000U)
+#define SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET_SHIFT (21U)
+/*! ISO7816_CLK_SET - Writing one to this register sets the ISO7816 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET_MASK  (0x400000U)
+#define SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET_SHIFT (22U)
+/*! WWDT_CLK_SET - Writing one to this register sets the WWDT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET_MASK   (0x800000U)
+#define SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET_SHIFT  (23U)
+/*! RTC_CLK_SET - Writing one to this register sets the RTC bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET_MASK (0x1000000U)
+#define SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET_SHIFT (24U)
+/*! ANA_INT_CTRL_CLK_SET - Writing one to this register sets the ANA_INT_CTRL bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_MASK (0x2000000U)
+#define SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_SHIFT (25U)
+/*! WAKE_UP_TIMERS_CLK_SET - Writing one to this register sets the WAKE_UP_TIMERS bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET_MASK   (0x8000000U)
+#define SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET_SHIFT  (27U)
+/*! ADC_CLK_SET - Writing one to this register sets the ADC bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLSET1 - Set bits in AHBCLKCTRL1 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET_MASK (0x800U)
+#define SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET_SHIFT (11U)
+/*! USART0_CLK_SET - Writing one to this register sets the UART0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET_MASK (0x1000U)
+#define SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET_SHIFT (12U)
+/*! USART1_CLK_SET - Writing one to this register sets the UART1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET_MASK  (0x2000U)
+#define SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET_SHIFT (13U)
+/*! I2C0_CLK_SET - Writing one to this register sets the I2C0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET_MASK  (0x4000U)
+#define SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET_SHIFT (14U)
+/*! I2C1_CLK_SET - Writing one to this register sets the I2C1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET_MASK  (0x8000U)
+#define SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET_SHIFT (15U)
+/*! SPI0_CLK_SET - Writing one to this register sets the SPI0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET_MASK  (0x10000U)
+#define SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET_SHIFT (16U)
+/*! SPI1_CLK_SET - Writing one to this register sets the SPI1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_IR_CLK_SET_MASK    (0x20000U)
+#define SYSCON_AHBCLKCTRLSET1_IR_CLK_SET_SHIFT   (17U)
+/*! IR_CLK_SET - Writing one to this register sets the IR bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_IR_CLK_SET(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_IR_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_IR_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET_MASK   (0x40000U)
+#define SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET_SHIFT  (18U)
+/*! PWM_CLK_SET - Writing one to this register sets the PWM bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET_MASK   (0x80000U)
+#define SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET_SHIFT  (19U)
+/*! RNG_CLK_SET - Writing one to this register sets the RNG bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET_MASK  (0x100000U)
+#define SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET_SHIFT (20U)
+/*! I2C2_CLK_SET - Writing one to this register sets the I2C2 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET_MASK (0x200000U)
+#define SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET_SHIFT (21U)
+/*! ZIGBEE_CLK_SET - Writing one to this register sets the ZIGBEE bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET_MASK (0x800000U)
+#define SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET_SHIFT (23U)
+/*! MODEM_MASTER_CLK_SET - Writing one to this register sets the MODEM_MASTER bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_AES_CLK_SET_MASK   (0x1000000U)
+#define SYSCON_AHBCLKCTRLSET1_AES_CLK_SET_SHIFT  (24U)
+/*! AES_CLK_SET - Writing one to this register sets the AES bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_AES_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_AES_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_AES_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET_MASK   (0x2000000U)
+#define SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET_SHIFT  (25U)
+/*! RFP_CLK_SET - Writing one to this register sets the RFP bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET_MASK  (0x4000000U)
+#define SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET_SHIFT (26U)
+/*! DMIC_CLK_SET - Writing one to this register sets the DMIC bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET_MASK  (0x8000000U)
+#define SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET_SHIFT (27U)
+/*! HASH_CLK_SET - Writing one to this register sets the HASH bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLSETX_AHBCLKCTRLSETS - Pin assign register */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA_SHIFT (0U)
+#define SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA_SHIFT)) & SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS */
+#define SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_COUNT (2U)
+
+/*! @name AHBCLKCTRLCLR0 - Clear bits in AHBCLKCTRL0 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR_MASK   (0x2U)
+#define SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR_SHIFT  (1U)
+/*! ROM_CLK_CLR - Writing one to this register clears the ROM bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR_MASK (0x8U)
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR_SHIFT (3U)
+/*! SRAM_CTRL0_CLK_CLR - Writing one to this register clears the SRAM_CTRL0 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR_MASK (0x10U)
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR_SHIFT (4U)
+/*! SRAM_CTRL1_CLK_CLR - Writing one to this register clears the SRAM_CTRL1 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR_MASK (0x100U)
+#define SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR_SHIFT (8U)
+/*! FLASH_CLK_CLR - Writing one to this register clears the FLASH bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR_MASK (0x400U)
+#define SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR_SHIFT (10U)
+/*! SPIFI_CLK_CLR - Writing one to this register clears the SPIFI bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR_MASK   (0x800U)
+#define SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR_SHIFT  (11U)
+/*! MUX_CLK_CLR - Writing one to this register clears the MUX bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR_MASK (0x2000U)
+#define SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR_SHIFT (13U)
+/*! IOCON_CLK_CLR - Writing one to this register clears the IOCON bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR_MASK  (0x4000U)
+#define SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR_SHIFT (14U)
+/*! GPIO_CLK_CLR - Writing one to this register clears the GPIO bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR_MASK  (0x40000U)
+#define SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR_SHIFT (18U)
+/*! PINT_CLK_CLR - Writing one to this register clears the PINT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR_MASK  (0x80000U)
+#define SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR_SHIFT (19U)
+/*! GINT_CLK_CLR - Writing one to this register clears the GINT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR_MASK   (0x100000U)
+#define SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR_SHIFT  (20U)
+/*! DMA_CLK_CLR - Writing one to this register clears the DMA bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR_MASK (0x200000U)
+#define SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR_SHIFT (21U)
+/*! ISO7816_CLK_CLR - Writing one to this register clears the ISO7816 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR_MASK  (0x400000U)
+#define SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR_SHIFT (22U)
+/*! WWDT_CLK_CLR - Writing one to this register clears the WWDT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR_MASK   (0x800000U)
+#define SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR_SHIFT  (23U)
+/*! RTC_CLK_CLR - Writing one to this register clears the RTC bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET_MASK (0x1000000U)
+#define SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET_SHIFT (24U)
+/*! ANA_INT_CTRL_CLK_SET - Writing one to this register clears the ANA_INT_CTRL bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET_MASK (0x2000000U)
+#define SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET_SHIFT (25U)
+/*! WAKE_UP_TIMERS_CLK_SET - Writing one to this register clears the WAKE_UP_TIMERS bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR_MASK   (0x8000000U)
+#define SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR_SHIFT  (27U)
+/*! ADC_CLK_CLR - Writing one to this register clears the ADC bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR_MASK (0x10000000U)
+#define SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR_SHIFT (28U)
+/*! EFUSE_CLK_CLR - Writing one to this register clears the EFUSE bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLCLR1 - Clear bits in AHBCLKCTRL1 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR_MASK (0x800U)
+#define SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR_SHIFT (11U)
+/*! USART0_CLK_CLR - Writing one to this register clears the UART0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR_MASK (0x1000U)
+#define SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR_SHIFT (12U)
+/*! USART1_CLK_CLR - Writing one to this register clears the UART1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR_MASK  (0x2000U)
+#define SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR_SHIFT (13U)
+/*! I2C0_CLK_CLR - Writing one to this register clears the I2C0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR_MASK  (0x4000U)
+#define SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR_SHIFT (14U)
+/*! I2C1_CLK_CLR - Writing one to this register clears the I2C1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR_MASK  (0x8000U)
+#define SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR_SHIFT (15U)
+/*! SPI0_CLK_CLR - Writing one to this register clears the SPI0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR_MASK  (0x10000U)
+#define SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR_SHIFT (16U)
+/*! SPI1_CLK_CLR - Writing one to this register clears the SPI1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR_MASK    (0x20000U)
+#define SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR_SHIFT   (17U)
+/*! IR_CLK_CLR - Writing one to this register clears the IR bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR_MASK   (0x40000U)
+#define SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR_SHIFT  (18U)
+/*! PWM_CLK_CLR - Writing one to this register clears the PWM bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR_MASK   (0x80000U)
+#define SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR_SHIFT  (19U)
+/*! RNG_CLK_CLR - Writing one to this register clears the RNG bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR_MASK  (0x100000U)
+#define SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR_SHIFT (20U)
+/*! I2C2_CLK_CLR - Writing one to this register clears the I2C2 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR_MASK (0x200000U)
+#define SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR_SHIFT (21U)
+/*! ZIGBEE_CLK_CLR - Writing one to this register clears the ZIGBEE bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR_MASK (0x800000U)
+#define SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR_SHIFT (23U)
+/*! MODEM_MASTER_CLK_CLR - Writing one to this register clears the MODEM_MASTER bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR_MASK   (0x1000000U)
+#define SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR_SHIFT  (24U)
+/*! AES_CLK_CLR - Writing one to this register clears the AES bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR_MASK   (0x2000000U)
+#define SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR_SHIFT  (25U)
+/*! RFP_CLK_CLR - Writing one to this register clears the RFP bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR_MASK  (0x4000000U)
+#define SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR_SHIFT (26U)
+/*! DMIC_CLK_CLR - Writing one to this register clears the DMIC bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR_MASK  (0x8000000U)
+#define SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR_SHIFT (27U)
+/*! HASH_CLK_CLR - Writing one to this register clears the HASH bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLCLRX_AHBCLKCTRLCLRS - Pin assign register */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA_SHIFT (0U)
+#define SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA_SHIFT)) & SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS */
+#define SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_COUNT (2U)
+
+/*! @name MAINCLKSEL - Main clock source select */
+/*! @{ */
+#define SYSCON_MAINCLKSEL_SEL_MASK               (0x7U)
+#define SYSCON_MAINCLKSEL_SEL_SHIFT              (0U)
+/*! SEL - Main clock source selection:
+ *  0b000..12 MHz free running oscillator (FRO)
+ *  0b010..32 MHz crystal oscillator (XTAL)
+ *  0b011..32 MHz free running oscillator (FRO)
+ *  0b100..48 MHz free running oscillator (FRO)
+ */
+#define SYSCON_MAINCLKSEL_SEL(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_MAINCLKSEL_SEL_SHIFT)) & SYSCON_MAINCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name OSC32CLKSEL - OSC32KCLK and OSC32MCLK clock sources select. Note: this register is not locked by CLOCKGENUPDATELOCKOUT */
+/*! @{ */
+#define SYSCON_OSC32CLKSEL_SEL32MHZ_MASK         (0x1U)
+#define SYSCON_OSC32CLKSEL_SEL32MHZ_SHIFT        (0U)
+/*! SEL32MHZ - OSC32MCLK clock source selection
+ *  0b0..32 MHz free running oscillator (FRO)
+ *  0b1..32 MHz crystal oscillator
+ */
+#define SYSCON_OSC32CLKSEL_SEL32MHZ(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_OSC32CLKSEL_SEL32MHZ_SHIFT)) & SYSCON_OSC32CLKSEL_SEL32MHZ_MASK)
+#define SYSCON_OSC32CLKSEL_SEL32KHZ_MASK         (0x2U)
+#define SYSCON_OSC32CLKSEL_SEL32KHZ_SHIFT        (1U)
+/*! SEL32KHZ - OSC32KCLK clock source selection
+ *  0b0..32 KHz free running oscillator (FRO)
+ *  0b1..32 KHz crystal oscillator
+ */
+#define SYSCON_OSC32CLKSEL_SEL32KHZ(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_OSC32CLKSEL_SEL32KHZ_SHIFT)) & SYSCON_OSC32CLKSEL_SEL32KHZ_MASK)
+/*! @} */
+
+/*! @name CLKOUTSEL - CLKOUT clock source select */
+/*! @{ */
+#define SYSCON_CLKOUTSEL_SEL_MASK                (0x7U)
+#define SYSCON_CLKOUTSEL_SEL_SHIFT               (0U)
+/*! SEL - CLKOUT clock source selection
+ *  0b000..CPU & System Bus clock
+ *  0b001..32 KHz crystal oscillator (XTAL)
+ *  0b010..32 KHz free running oscillator (FRO)
+ *  0b011..32 MHz crystal oscillator (XTAL)
+ *  0b101..48 MHz free running oscillator (FRO)
+ *  0b110..1 MHz free running oscillator (FRO)
+ *  0b111..No clock
+ */
+#define SYSCON_CLKOUTSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTSEL_SEL_SHIFT)) & SYSCON_CLKOUTSEL_SEL_MASK)
+/*! @} */
+
+/*! @name SPIFICLKSEL - SPIFI clock source select */
+/*! @{ */
+#define SYSCON_SPIFICLKSEL_SEL_MASK              (0x7U)
+#define SYSCON_SPIFICLKSEL_SEL_SHIFT             (0U)
+/*! SEL - SPIFICLK clock source selection
+ *  0b000..CPU & System Bus clock
+ *  0b001..32 MHz crystal oscillator (XTAL)
+ *  0b010..No clock
+ *  0b011..No clock
+ *  0b100..No clock
+ *  0b101..No clock
+ *  0b110..No clock
+ *  0b111..No clock
+ */
+#define SYSCON_SPIFICLKSEL_SEL(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKSEL_SEL_SHIFT)) & SYSCON_SPIFICLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name ADCCLKSEL - ADC clock source select */
+/*! @{ */
+#define SYSCON_ADCCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_ADCCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - ADCCLK clock source selection
+ *  0b00..32 MHz crystal oscillator (XTAL)
+ *  0b01..FRO 12 MHz
+ *  0b11..No clock
+ */
+#define SYSCON_ADCCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKSEL_SEL_SHIFT)) & SYSCON_ADCCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name USARTCLKSEL - USART0 & 1 clock source select */
+/*! @{ */
+#define SYSCON_USARTCLKSEL_SEL_MASK              (0x3U)
+#define SYSCON_USARTCLKSEL_SEL_SHIFT             (0U)
+/*! SEL - USARTCLK (USART0 & 1) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b10..Fractional Rate Generator clock (see FRGCLKSEL)
+ *  0b11..No clock
+ */
+#define SYSCON_USARTCLKSEL_SEL(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_USARTCLKSEL_SEL_SHIFT)) & SYSCON_USARTCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name I2CCLKSEL - I2C0, 1 and 2 clock source select */
+/*! @{ */
+#define SYSCON_I2CCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_I2CCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - I2CCLK (I2C0 & 1) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b11..No clock
+ */
+#define SYSCON_I2CCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_I2CCLKSEL_SEL_SHIFT)) & SYSCON_I2CCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name SPICLKSEL - SPI0 & 1 clock source select */
+/*! @{ */
+#define SYSCON_SPICLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_SPICLKSEL_SEL_SHIFT               (0U)
+/*! SEL - SPICLK (SPI0 & 1) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b11..No clock
+ */
+#define SYSCON_SPICLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_SPICLKSEL_SEL_SHIFT)) & SYSCON_SPICLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name IRCLKSEL - Infra Red clock source select */
+/*! @{ */
+#define SYSCON_IRCLKSEL_SEL_MASK                 (0x3U)
+#define SYSCON_IRCLKSEL_SEL_SHIFT                (0U)
+/*! SEL - IRCLK (IR Blaster) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b11..No clock
+ */
+#define SYSCON_IRCLKSEL_SEL(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKSEL_SEL_SHIFT)) & SYSCON_IRCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name PWMCLKSEL - PWM clock source select */
+/*! @{ */
+#define SYSCON_PWMCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_PWMCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - PWMCLK (PWM) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b11..No Clock
+ */
+#define SYSCON_PWMCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_PWMCLKSEL_SEL_SHIFT)) & SYSCON_PWMCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name WDTCLKSEL - Watchdog Timer clock source select */
+/*! @{ */
+#define SYSCON_WDTCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_WDTCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - WDTCLK (Watchdog Timer) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..Either 32 KHz FRO or 32 KHz XTAL (see OSC32CLKSEL)
+ *  0b10..1 MHz FRO
+ *  0b11..No Clock
+ */
+#define SYSCON_WDTCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKSEL_SEL_SHIFT)) & SYSCON_WDTCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name MODEMCLKSEL - Modem clock source select */
+/*! @{ */
+#define SYSCON_MODEMCLKSEL_SEL_ZIGBEE_MASK       (0x1U)
+#define SYSCON_MODEMCLKSEL_SEL_ZIGBEE_SHIFT      (0U)
+/*! SEL_ZIGBEE - Zigbee Modem clock source selection
+ *  0b0..32 MHz XTAL
+ *  0b1..No Clock
+ */
+#define SYSCON_MODEMCLKSEL_SEL_ZIGBEE(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCLKSEL_SEL_ZIGBEE_SHIFT)) & SYSCON_MODEMCLKSEL_SEL_ZIGBEE_MASK)
+/*! @} */
+
+/*! @name FRGCLKSEL - Fractional Rate Generator (FRG) clock source select. The FRG is one of the USART clocking options. */
+/*! @{ */
+#define SYSCON_FRGCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_FRGCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - Fractional Rate Generator clock source selection
+ *  0b00..System Bus clock
+ *  0b01..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b10..48 MHz free running oscillator (FRO)
+ *  0b11..No Clock
+ */
+#define SYSCON_FRGCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCLKSEL_SEL_SHIFT)) & SYSCON_FRGCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name DMICCLKSEL - Digital microphone (DMIC) subsystem clock select */
+/*! @{ */
+#define SYSCON_DMICCLKSEL_SEL_MASK               (0x7U)
+#define SYSCON_DMICCLKSEL_SEL_SHIFT              (0U)
+/*! SEL - DMIC clock source selection
+ *  0b000..System Bus clock
+ *  0b001..Either 32 KHz FRO or 32 KHz XTAL (see OSC32CLKSEL)
+ *  0b010..48 MHz free running oscillator (FRO)
+ *  0b011..External clock
+ *  0b100..1 MHz free running oscillator (FRO)
+ *  0b101..12 MHz free running oscillator (FRO)
+ *  0b111..No Clock
+ */
+#define SYSCON_DMICCLKSEL_SEL(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKSEL_SEL_SHIFT)) & SYSCON_DMICCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name WKTCLKSEL - Wake-up Timer clock select */
+/*! @{ */
+#define SYSCON_WKTCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_WKTCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - Wake-up Timers clock source selection
+ *  0b00..Either 32 KHz FRO or 32 KHz XTAL (see OSC32CLKSEL)
+ *  0b11..No Clock
+ */
+#define SYSCON_WKTCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_WKTCLKSEL_SEL_SHIFT)) & SYSCON_WKTCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name SYSTICKCLKDIV - SYSTICK clock divider. The SYSTICK clock can drive the SYSTICK function within the processor. */
+/*! @{ */
+#define SYSCON_SYSTICKCLKDIV_DIV_MASK            (0xFFU)
+#define SYSCON_SYSTICKCLKDIV_DIV_SHIFT           (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_SYSTICKCLKDIV_DIV(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_DIV_SHIFT)) & SYSCON_SYSTICKCLKDIV_DIV_MASK)
+#define SYSCON_SYSTICKCLKDIV_RESET_MASK          (0x20000000U)
+#define SYSCON_SYSTICKCLKDIV_RESET_SHIFT         (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_SYSTICKCLKDIV_RESET(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_RESET_SHIFT)) & SYSCON_SYSTICKCLKDIV_RESET_MASK)
+#define SYSCON_SYSTICKCLKDIV_HALT_MASK           (0x40000000U)
+#define SYSCON_SYSTICKCLKDIV_HALT_SHIFT          (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_SYSTICKCLKDIV_HALT(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_HALT_SHIFT)) & SYSCON_SYSTICKCLKDIV_HALT_MASK)
+#define SYSCON_SYSTICKCLKDIV_REQFLAG_MASK        (0x80000000U)
+#define SYSCON_SYSTICKCLKDIV_REQFLAG_SHIFT       (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_SYSTICKCLKDIV_REQFLAG(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_REQFLAG_SHIFT)) & SYSCON_SYSTICKCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name TRACECLKDIV - TRACE clock divider, used for part of the Serial debugger (SWD) feature. */
+/*! @{ */
+#define SYSCON_TRACECLKDIV_DIV_MASK              (0xFFU)
+#define SYSCON_TRACECLKDIV_DIV_SHIFT             (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_TRACECLKDIV_DIV(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_DIV_SHIFT)) & SYSCON_TRACECLKDIV_DIV_MASK)
+#define SYSCON_TRACECLKDIV_RESET_MASK            (0x20000000U)
+#define SYSCON_TRACECLKDIV_RESET_SHIFT           (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_TRACECLKDIV_RESET(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_RESET_SHIFT)) & SYSCON_TRACECLKDIV_RESET_MASK)
+#define SYSCON_TRACECLKDIV_HALT_MASK             (0x40000000U)
+#define SYSCON_TRACECLKDIV_HALT_SHIFT            (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_TRACECLKDIV_HALT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_HALT_SHIFT)) & SYSCON_TRACECLKDIV_HALT_MASK)
+#define SYSCON_TRACECLKDIV_REQFLAG_MASK          (0x80000000U)
+#define SYSCON_TRACECLKDIV_REQFLAG_SHIFT         (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_TRACECLKDIV_REQFLAG(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_REQFLAG_SHIFT)) & SYSCON_TRACECLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name WDTCLKDIV - Watchdog Timer clock divider */
+/*! @{ */
+#define SYSCON_WDTCLKDIV_DIV_MASK                (0xFFU)
+#define SYSCON_WDTCLKDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_WDTCLKDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKDIV_DIV_SHIFT)) & SYSCON_WDTCLKDIV_DIV_MASK)
+#define SYSCON_WDTCLKDIV_RESET_MASK              (0x20000000U)
+#define SYSCON_WDTCLKDIV_RESET_SHIFT             (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_WDTCLKDIV_RESET(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKDIV_RESET_SHIFT)) & SYSCON_WDTCLKDIV_RESET_MASK)
+#define SYSCON_WDTCLKDIV_HALT_MASK               (0x40000000U)
+#define SYSCON_WDTCLKDIV_HALT_SHIFT              (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_WDTCLKDIV_HALT(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKDIV_HALT_SHIFT)) & SYSCON_WDTCLKDIV_HALT_MASK)
+#define SYSCON_WDTCLKDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_WDTCLKDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_WDTCLKDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKDIV_REQFLAG_SHIFT)) & SYSCON_WDTCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name IRCLKDIV - Infra Red clock divider */
+/*! @{ */
+#define SYSCON_IRCLKDIV_DIV_MASK                 (0xFU)
+#define SYSCON_IRCLKDIV_DIV_SHIFT                (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 15: Divide by 16.
+ */
+#define SYSCON_IRCLKDIV_DIV(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKDIV_DIV_SHIFT)) & SYSCON_IRCLKDIV_DIV_MASK)
+#define SYSCON_IRCLKDIV_RESET_MASK               (0x20000000U)
+#define SYSCON_IRCLKDIV_RESET_SHIFT              (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_IRCLKDIV_RESET(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKDIV_RESET_SHIFT)) & SYSCON_IRCLKDIV_RESET_MASK)
+#define SYSCON_IRCLKDIV_HALT_MASK                (0x40000000U)
+#define SYSCON_IRCLKDIV_HALT_SHIFT               (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_IRCLKDIV_HALT(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKDIV_HALT_SHIFT)) & SYSCON_IRCLKDIV_HALT_MASK)
+#define SYSCON_IRCLKDIV_REQFLAG_MASK             (0x80000000U)
+#define SYSCON_IRCLKDIV_REQFLAG_SHIFT            (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_IRCLKDIV_REQFLAG(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKDIV_REQFLAG_SHIFT)) & SYSCON_IRCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name AHBCLKDIV - System clock divider */
+/*! @{ */
+#define SYSCON_AHBCLKDIV_DIV_MASK                (0xFFU)
+#define SYSCON_AHBCLKDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_AHBCLKDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_DIV_SHIFT)) & SYSCON_AHBCLKDIV_DIV_MASK)
+#define SYSCON_AHBCLKDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_AHBCLKDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_AHBCLKDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_REQFLAG_SHIFT)) & SYSCON_AHBCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name CLKOUTDIV - CLKOUT clock divider */
+/*! @{ */
+#define SYSCON_CLKOUTDIV_DIV_MASK                (0xFU)
+#define SYSCON_CLKOUTDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 15: Divide by 16.
+ */
+#define SYSCON_CLKOUTDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_DIV_SHIFT)) & SYSCON_CLKOUTDIV_DIV_MASK)
+#define SYSCON_CLKOUTDIV_RESET_MASK              (0x20000000U)
+#define SYSCON_CLKOUTDIV_RESET_SHIFT             (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_CLKOUTDIV_RESET(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_RESET_SHIFT)) & SYSCON_CLKOUTDIV_RESET_MASK)
+#define SYSCON_CLKOUTDIV_HALT_MASK               (0x40000000U)
+#define SYSCON_CLKOUTDIV_HALT_SHIFT              (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_CLKOUTDIV_HALT(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_HALT_SHIFT)) & SYSCON_CLKOUTDIV_HALT_MASK)
+#define SYSCON_CLKOUTDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_CLKOUTDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_CLKOUTDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_REQFLAG_SHIFT)) & SYSCON_CLKOUTDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name SPIFICLKDIV - SPIFI clock divider */
+/*! @{ */
+#define SYSCON_SPIFICLKDIV_DIV_MASK              (0x3U)
+#define SYSCON_SPIFICLKDIV_DIV_SHIFT             (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 3: Divide by 4.
+ */
+#define SYSCON_SPIFICLKDIV_DIV(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_DIV_SHIFT)) & SYSCON_SPIFICLKDIV_DIV_MASK)
+#define SYSCON_SPIFICLKDIV_RESET_MASK            (0x20000000U)
+#define SYSCON_SPIFICLKDIV_RESET_SHIFT           (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_SPIFICLKDIV_RESET(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_RESET_SHIFT)) & SYSCON_SPIFICLKDIV_RESET_MASK)
+#define SYSCON_SPIFICLKDIV_HALT_MASK             (0x40000000U)
+#define SYSCON_SPIFICLKDIV_HALT_SHIFT            (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_SPIFICLKDIV_HALT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_HALT_SHIFT)) & SYSCON_SPIFICLKDIV_HALT_MASK)
+#define SYSCON_SPIFICLKDIV_REQFLAG_MASK          (0x80000000U)
+#define SYSCON_SPIFICLKDIV_REQFLAG_SHIFT         (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_SPIFICLKDIV_REQFLAG(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_REQFLAG_SHIFT)) & SYSCON_SPIFICLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name ADCCLKDIV - ADC clock divider */
+/*! @{ */
+#define SYSCON_ADCCLKDIV_DIV_MASK                (0x7U)
+#define SYSCON_ADCCLKDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 7: Divide by 8.
+ */
+#define SYSCON_ADCCLKDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_DIV_SHIFT)) & SYSCON_ADCCLKDIV_DIV_MASK)
+#define SYSCON_ADCCLKDIV_RESET_MASK              (0x20000000U)
+#define SYSCON_ADCCLKDIV_RESET_SHIFT             (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_ADCCLKDIV_RESET(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_RESET_SHIFT)) & SYSCON_ADCCLKDIV_RESET_MASK)
+#define SYSCON_ADCCLKDIV_HALT_MASK               (0x40000000U)
+#define SYSCON_ADCCLKDIV_HALT_SHIFT              (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_ADCCLKDIV_HALT(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_HALT_SHIFT)) & SYSCON_ADCCLKDIV_HALT_MASK)
+#define SYSCON_ADCCLKDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_ADCCLKDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_ADCCLKDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_REQFLAG_SHIFT)) & SYSCON_ADCCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name RTCCLKDIV - Real Time Clock divider (1 KHz clock generation) */
+/*! @{ */
+#define SYSCON_RTCCLKDIV_DIV_MASK                (0x1FU)
+#define SYSCON_RTCCLKDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 31: Divide by 32.
+ */
+#define SYSCON_RTCCLKDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCCLKDIV_DIV_SHIFT)) & SYSCON_RTCCLKDIV_DIV_MASK)
+#define SYSCON_RTCCLKDIV_RESET_MASK              (0x20000000U)
+#define SYSCON_RTCCLKDIV_RESET_SHIFT             (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_RTCCLKDIV_RESET(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCCLKDIV_RESET_SHIFT)) & SYSCON_RTCCLKDIV_RESET_MASK)
+#define SYSCON_RTCCLKDIV_HALT_MASK               (0x40000000U)
+#define SYSCON_RTCCLKDIV_HALT_SHIFT              (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_RTCCLKDIV_HALT(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCCLKDIV_HALT_SHIFT)) & SYSCON_RTCCLKDIV_HALT_MASK)
+#define SYSCON_RTCCLKDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_RTCCLKDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_RTCCLKDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCCLKDIV_REQFLAG_SHIFT)) & SYSCON_RTCCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name FRGCTRL - Fractional rate generator divider. The FRG is one of the USART clocking options. */
+/*! @{ */
+#define SYSCON_FRGCTRL_DIV_MASK                  (0xFFU)
+#define SYSCON_FRGCTRL_DIV_SHIFT                 (0U)
+/*! DIV - Denominator of the fractional divider is equal to the (DIV+1). Always set to 0xFF to use
+ *    with the fractional baud rate generator : fout = fin / (1 + MULT/(DIV+1))
+ */
+#define SYSCON_FRGCTRL_DIV(x)                    (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCTRL_DIV_SHIFT)) & SYSCON_FRGCTRL_DIV_MASK)
+#define SYSCON_FRGCTRL_MULT_MASK                 (0xFF00U)
+#define SYSCON_FRGCTRL_MULT_SHIFT                (8U)
+/*! MULT - Numerator of the fractional divider. MULT is equal to the programmed value
+ */
+#define SYSCON_FRGCTRL_MULT(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCTRL_MULT_SHIFT)) & SYSCON_FRGCTRL_MULT_MASK)
+/*! @} */
+
+/*! @name DMICCLKDIV - DMIC clock divider */
+/*! @{ */
+#define SYSCON_DMICCLKDIV_DIV_MASK               (0xFFU)
+#define SYSCON_DMICCLKDIV_DIV_SHIFT              (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_DMICCLKDIV_DIV(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_DIV_SHIFT)) & SYSCON_DMICCLKDIV_DIV_MASK)
+#define SYSCON_DMICCLKDIV_RESET_MASK             (0x20000000U)
+#define SYSCON_DMICCLKDIV_RESET_SHIFT            (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_DMICCLKDIV_RESET(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_RESET_SHIFT)) & SYSCON_DMICCLKDIV_RESET_MASK)
+#define SYSCON_DMICCLKDIV_HALT_MASK              (0x40000000U)
+#define SYSCON_DMICCLKDIV_HALT_SHIFT             (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_DMICCLKDIV_HALT(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_HALT_SHIFT)) & SYSCON_DMICCLKDIV_HALT_MASK)
+#define SYSCON_DMICCLKDIV_REQFLAG_MASK           (0x80000000U)
+#define SYSCON_DMICCLKDIV_REQFLAG_SHIFT          (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_DMICCLKDIV_REQFLAG(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_REQFLAG_SHIFT)) & SYSCON_DMICCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name RTC1HZCLKDIV - Real Time Clock divider (1 Hz clock generation. The divider is fixed to 32768) */
+/*! @{ */
+#define SYSCON_RTC1HZCLKDIV_RESET_MASK           (0x20000000U)
+#define SYSCON_RTC1HZCLKDIV_RESET_SHIFT          (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_RTC1HZCLKDIV_RESET(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_RTC1HZCLKDIV_RESET_SHIFT)) & SYSCON_RTC1HZCLKDIV_RESET_MASK)
+#define SYSCON_RTC1HZCLKDIV_HALT_MASK            (0x40000000U)
+#define SYSCON_RTC1HZCLKDIV_HALT_SHIFT           (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_RTC1HZCLKDIV_HALT(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_RTC1HZCLKDIV_HALT_SHIFT)) & SYSCON_RTC1HZCLKDIV_HALT_MASK)
+#define SYSCON_RTC1HZCLKDIV_REQFLAG_MASK         (0x80000000U)
+#define SYSCON_RTC1HZCLKDIV_REQFLAG_SHIFT        (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_RTC1HZCLKDIV_REQFLAG(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_RTC1HZCLKDIV_REQFLAG_SHIFT)) & SYSCON_RTC1HZCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name CLOCKGENUPDATELOCKOUT - Control clock configuration registers access (like xxxDIV, xxxSEL) */
+/*! @{ */
+#define SYSCON_CLOCKGENUPDATELOCKOUT_LOCK_MASK   (0x1U)
+#define SYSCON_CLOCKGENUPDATELOCKOUT_LOCK_SHIFT  (0U)
+/*! LOCK - When set, disables access to clock control registers (like xxxDIV, xxxSEL). Affects all
+ *    clock control registers except OSC32CLKSEL.
+ */
+#define SYSCON_CLOCKGENUPDATELOCKOUT_LOCK(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_CLOCKGENUPDATELOCKOUT_LOCK_SHIFT)) & SYSCON_CLOCKGENUPDATELOCKOUT_LOCK_MASK)
+/*! @} */
+
+/*! @name RNGCLKCTRL - Random Number Generator Clocks control */
+/*! @{ */
+#define SYSCON_RNGCLKCTRL_ENABLE_MASK            (0x1U)
+#define SYSCON_RNGCLKCTRL_ENABLE_SHIFT           (0U)
+/*! ENABLE - Enable the clocks used by the Random Number Generator (RNG)
+ */
+#define SYSCON_RNGCLKCTRL_ENABLE(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_RNGCLKCTRL_ENABLE_SHIFT)) & SYSCON_RNGCLKCTRL_ENABLE_MASK)
+/*! @} */
+
+/*! @name SRAMCTRL - All SRAMs common control signals */
+/*! @{ */
+#define SYSCON_SRAMCTRL_SMB_MASK                 (0x3U)
+#define SYSCON_SRAMCTRL_SMB_SHIFT                (0U)
+/*! SMB - SMB
+ */
+#define SYSCON_SRAMCTRL_SMB(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_SRAMCTRL_SMB_SHIFT)) & SYSCON_SRAMCTRL_SMB_MASK)
+/*! @} */
+
+/*! @name MODEMCTRL - 32K clock enable */
+/*! @{ */
+#define SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN_MASK   (0x200U)
+#define SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN_SHIFT  (9U)
+/*! BLE_LP_OSC32K_EN - 1 = enable the 32K clock to the USART 0 & 1, LSPI0 & 1, PMC and the frequency
+ *    measure block. Note: despite its name, this control bit affects peripheral clocking,
+ */
+#define SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN_SHIFT)) & SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN_MASK)
+/*! @} */
+
+/*! @name XTAL32KCAP - XTAL 32 KHz oscillator Capacitor control */
+/*! @{ */
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_MASK     (0x7FU)
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_SHIFT    (0U)
+/*! XO_OSC_CAP_IN - Internal Capacitor setting for XTAL_32K_P. This setting selects the internal
+ *    capacitance, to ground, that is connected to this XTAL pin. During device testing the capacitor
+ *    banks are calibrated so accurate setting of the capacitance can be achieved. Software function
+ *    are provided to support the setting of this register. Capacitance range is to apporximately
+ *    24pF.
+ */
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_IN(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_SHIFT)) & SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_MASK)
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_MASK    (0x3F80U)
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_SHIFT   (7U)
+/*! XO_OSC_CAP_OUT - Internal Capacitor setting for XTAL_32K_N. This setting selects the internal
+ *    capacitance, to ground, that is connected to this XTAL pin. During device testing the capacitor
+ *    banks are calibrated so accurate setting of the capacitance can be achieved. Software function
+ *    are provided to support the setting of this register. Capacitance range is to apporximately
+ *    24pF.
+ */
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_SHIFT)) & SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_MASK)
+/*! @} */
+
+/*! @name XTAL32MCTRL - XTAL 32 MHz oscillator control register */
+/*! @{ */
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL_MASK (0x1U)
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL_SHIFT (0U)
+/*! DEACTIVATE_PMC_CTRL - The 32MHz XTAL is enabled whenever the device is active due to internal
+ *    control signals from the PMC. This control bit can deactivate this. 0: Enable XTAL 32 MHz
+ *    controls coming from PMC. 1: Disable XTAL 32 MHz controls coming from PMC.
+ */
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL_SHIFT)) & SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL_MASK)
+/*! @} */
+
+/*! @name STARTER0 - Start logic 0 wake-up enable register. Enable an interrupt for wake-up from deep-sleep mode. Some bits can also control wake-up from powerdown mode */
+/*! @{ */
+#define SYSCON_STARTER0_WDT_BOD_MASK             (0x1U)
+#define SYSCON_STARTER0_WDT_BOD_SHIFT            (0U)
+/*! WDT_BOD - WWDT and BOD Interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_WDT_BOD(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_WDT_BOD_SHIFT)) & SYSCON_STARTER0_WDT_BOD_MASK)
+#define SYSCON_STARTER0_DMA_MASK                 (0x2U)
+#define SYSCON_STARTER0_DMA_SHIFT                (1U)
+/*! DMA - DMA Operation in Deep-Sleep and Powerdown not supported. Leave set to 0.
+ */
+#define SYSCON_STARTER0_DMA(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_DMA_SHIFT)) & SYSCON_STARTER0_DMA_MASK)
+#define SYSCON_STARTER0_GINT_MASK                (0x4U)
+#define SYSCON_STARTER0_GINT_SHIFT               (2U)
+/*! GINT - Group Interrupt 0 (GINT0) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_GINT(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_GINT_SHIFT)) & SYSCON_STARTER0_GINT_MASK)
+#define SYSCON_STARTER0_IRBLASTER_MASK           (0x8U)
+#define SYSCON_STARTER0_IRBLASTER_SHIFT          (3U)
+/*! IRBLASTER - Infra Red Blaster interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_IRBLASTER(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_IRBLASTER_SHIFT)) & SYSCON_STARTER0_IRBLASTER_MASK)
+#define SYSCON_STARTER0_PINT0_MASK               (0x10U)
+#define SYSCON_STARTER0_PINT0_SHIFT              (4U)
+/*! PINT0 - Pattern Interupt 0 (PINT0) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PINT0(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PINT0_SHIFT)) & SYSCON_STARTER0_PINT0_MASK)
+#define SYSCON_STARTER0_PINT1_MASK               (0x20U)
+#define SYSCON_STARTER0_PINT1_SHIFT              (5U)
+/*! PINT1 - Pattern Interupt 1 (PINT1) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PINT1(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PINT1_SHIFT)) & SYSCON_STARTER0_PINT1_MASK)
+#define SYSCON_STARTER0_PINT2_MASK               (0x40U)
+#define SYSCON_STARTER0_PINT2_SHIFT              (6U)
+/*! PINT2 - Pattern Interupt 2 (PINT2) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PINT2(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PINT2_SHIFT)) & SYSCON_STARTER0_PINT2_MASK)
+#define SYSCON_STARTER0_PINT3_MASK               (0x80U)
+#define SYSCON_STARTER0_PINT3_SHIFT              (7U)
+/*! PINT3 - Pattern Interupt 3 (PINT3) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PINT3(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PINT3_SHIFT)) & SYSCON_STARTER0_PINT3_MASK)
+#define SYSCON_STARTER0_SPIFI_MASK               (0x100U)
+#define SYSCON_STARTER0_SPIFI_SHIFT              (8U)
+/*! SPIFI - SPI Flash Interface (SPIFI) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_SPIFI(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_SPIFI_SHIFT)) & SYSCON_STARTER0_SPIFI_MASK)
+#define SYSCON_STARTER0_TIMER0_MASK              (0x200U)
+#define SYSCON_STARTER0_TIMER0_SHIFT             (9U)
+/*! TIMER0 - Counter/Timer0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_TIMER0(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_TIMER0_SHIFT)) & SYSCON_STARTER0_TIMER0_MASK)
+#define SYSCON_STARTER0_TIMER1_MASK              (0x400U)
+#define SYSCON_STARTER0_TIMER1_SHIFT             (10U)
+/*! TIMER1 - Counter/Timer1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_TIMER1(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_TIMER1_SHIFT)) & SYSCON_STARTER0_TIMER1_MASK)
+#define SYSCON_STARTER0_USART0_MASK              (0x800U)
+#define SYSCON_STARTER0_USART0_SHIFT             (11U)
+/*! USART0 - USART0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_USART0(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_USART0_SHIFT)) & SYSCON_STARTER0_USART0_MASK)
+#define SYSCON_STARTER0_USART1_MASK              (0x1000U)
+#define SYSCON_STARTER0_USART1_SHIFT             (12U)
+/*! USART1 - USART1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_USART1(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_USART1_SHIFT)) & SYSCON_STARTER0_USART1_MASK)
+#define SYSCON_STARTER0_I2C0_MASK                (0x2000U)
+#define SYSCON_STARTER0_I2C0_SHIFT               (13U)
+/*! I2C0 - I2C0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_I2C0(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_I2C0_SHIFT)) & SYSCON_STARTER0_I2C0_MASK)
+#define SYSCON_STARTER0_I2C1_MASK                (0x4000U)
+#define SYSCON_STARTER0_I2C1_SHIFT               (14U)
+/*! I2C1 - I2C1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_I2C1(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_I2C1_SHIFT)) & SYSCON_STARTER0_I2C1_MASK)
+#define SYSCON_STARTER0_SPI0_MASK                (0x8000U)
+#define SYSCON_STARTER0_SPI0_SHIFT               (15U)
+/*! SPI0 - SPI0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_SPI0(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_SPI0_SHIFT)) & SYSCON_STARTER0_SPI0_MASK)
+#define SYSCON_STARTER0_SPI1_MASK                (0x10000U)
+#define SYSCON_STARTER0_SPI1_SHIFT               (16U)
+/*! SPI1 - SPI1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_SPI1(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_SPI1_SHIFT)) & SYSCON_STARTER0_SPI1_MASK)
+#define SYSCON_STARTER0_PWM0_MASK                (0x20000U)
+#define SYSCON_STARTER0_PWM0_SHIFT               (17U)
+/*! PWM0 - PWM0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM0(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM0_SHIFT)) & SYSCON_STARTER0_PWM0_MASK)
+#define SYSCON_STARTER0_PWM1_MASK                (0x40000U)
+#define SYSCON_STARTER0_PWM1_SHIFT               (18U)
+/*! PWM1 - PWM1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM1(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM1_SHIFT)) & SYSCON_STARTER0_PWM1_MASK)
+#define SYSCON_STARTER0_PWM2_MASK                (0x80000U)
+#define SYSCON_STARTER0_PWM2_SHIFT               (19U)
+/*! PWM2 - PWM2 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM2(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM2_SHIFT)) & SYSCON_STARTER0_PWM2_MASK)
+#define SYSCON_STARTER0_PWM3_MASK                (0x100000U)
+#define SYSCON_STARTER0_PWM3_SHIFT               (20U)
+/*! PWM3 - PWM3 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM3(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM3_SHIFT)) & SYSCON_STARTER0_PWM3_MASK)
+#define SYSCON_STARTER0_PWM4_MASK                (0x200000U)
+#define SYSCON_STARTER0_PWM4_SHIFT               (21U)
+/*! PWM4 - PWM4 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM4(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM4_SHIFT)) & SYSCON_STARTER0_PWM4_MASK)
+#define SYSCON_STARTER0_PWM5_MASK                (0x400000U)
+#define SYSCON_STARTER0_PWM5_SHIFT               (22U)
+/*! PWM5 - PWM5 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM5(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM5_SHIFT)) & SYSCON_STARTER0_PWM5_MASK)
+#define SYSCON_STARTER0_PWM6_MASK                (0x800000U)
+#define SYSCON_STARTER0_PWM6_SHIFT               (23U)
+/*! PWM6 - PWM6 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM6(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM6_SHIFT)) & SYSCON_STARTER0_PWM6_MASK)
+#define SYSCON_STARTER0_PWM7_MASK                (0x1000000U)
+#define SYSCON_STARTER0_PWM7_SHIFT               (24U)
+/*! PWM7 - PWM7 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM7(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM7_SHIFT)) & SYSCON_STARTER0_PWM7_MASK)
+#define SYSCON_STARTER0_PWM8_MASK                (0x2000000U)
+#define SYSCON_STARTER0_PWM8_SHIFT               (25U)
+/*! PWM8 - PWM8 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM8(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM8_SHIFT)) & SYSCON_STARTER0_PWM8_MASK)
+#define SYSCON_STARTER0_PWM9_MASK                (0x4000000U)
+#define SYSCON_STARTER0_PWM9_SHIFT               (26U)
+/*! PWM9 - PWM9 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM9(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM9_SHIFT)) & SYSCON_STARTER0_PWM9_MASK)
+#define SYSCON_STARTER0_PWM10_MASK               (0x8000000U)
+#define SYSCON_STARTER0_PWM10_SHIFT              (27U)
+/*! PWM10 - PWM10 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM10(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM10_SHIFT)) & SYSCON_STARTER0_PWM10_MASK)
+#define SYSCON_STARTER0_I2C2_MASK                (0x10000000U)
+#define SYSCON_STARTER0_I2C2_SHIFT               (28U)
+/*! I2C2 - I2C2 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_I2C2(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_I2C2_SHIFT)) & SYSCON_STARTER0_I2C2_MASK)
+#define SYSCON_STARTER0_RTC_MASK                 (0x20000000U)
+#define SYSCON_STARTER0_RTC_SHIFT                (29U)
+/*! RTC - Real Time Clock (RTC) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_RTC(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_RTC_SHIFT)) & SYSCON_STARTER0_RTC_MASK)
+#define SYSCON_STARTER0_NFCTAG_MASK              (0x40000000U)
+#define SYSCON_STARTER0_NFCTAG_SHIFT             (30U)
+/*! NFCTAG - NFC Tag interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from
+ *    Deep-Sleep. Only supported on devices with internal NFC tag.
+ */
+#define SYSCON_STARTER0_NFCTAG(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_NFCTAG_SHIFT)) & SYSCON_STARTER0_NFCTAG_MASK)
+/*! @} */
+
+/*! @name STARTER1 - Start logic 1 wake-up enable register. Enable an interrupt for wake-up from deep-sleep mode. Some bits can also control wake-up from powerdown mode */
+/*! @{ */
+#define SYSCON_STARTER1_ADC_SEQA_MASK            (0x1U)
+#define SYSCON_STARTER1_ADC_SEQA_SHIFT           (0U)
+/*! ADC_SEQA - ADC Sequence A interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ADC_SEQA(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ADC_SEQA_SHIFT)) & SYSCON_STARTER1_ADC_SEQA_MASK)
+#define SYSCON_STARTER1_ADC_THCMP_OVR_MASK       (0x4U)
+#define SYSCON_STARTER1_ADC_THCMP_OVR_SHIFT      (2U)
+/*! ADC_THCMP_OVR - ADC threshold and error interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ADC_THCMP_OVR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ADC_THCMP_OVR_SHIFT)) & SYSCON_STARTER1_ADC_THCMP_OVR_MASK)
+#define SYSCON_STARTER1_DMIC_MASK                (0x8U)
+#define SYSCON_STARTER1_DMIC_SHIFT               (3U)
+/*! DMIC - Digital Microphone (DMIC) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_DMIC(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_DMIC_SHIFT)) & SYSCON_STARTER1_DMIC_MASK)
+#define SYSCON_STARTER1_HWVAD_MASK               (0x10U)
+#define SYSCON_STARTER1_HWVAD_SHIFT              (4U)
+/*! HWVAD - Hardware Voice Activity Detector (HWVAD) interrupt wake-up. 0 = Wake-up disabled. 1 =
+ *    Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_HWVAD(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_HWVAD_SHIFT)) & SYSCON_STARTER1_HWVAD_MASK)
+#define SYSCON_STARTER1_ZIGBEE_MAC_MASK          (0x400U)
+#define SYSCON_STARTER1_ZIGBEE_MAC_SHIFT         (10U)
+/*! ZIGBEE_MAC - Zigbee MAC interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ZIGBEE_MAC(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ZIGBEE_MAC_SHIFT)) & SYSCON_STARTER1_ZIGBEE_MAC_MASK)
+#define SYSCON_STARTER1_ZIGBEE_MODEM_MASK        (0x800U)
+#define SYSCON_STARTER1_ZIGBEE_MODEM_SHIFT       (11U)
+/*! ZIGBEE_MODEM - Zigbee Modem interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ZIGBEE_MODEM(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ZIGBEE_MODEM_SHIFT)) & SYSCON_STARTER1_ZIGBEE_MODEM_MASK)
+#define SYSCON_STARTER1_RFP_TMU_MASK             (0x1000U)
+#define SYSCON_STARTER1_RFP_TMU_SHIFT            (12U)
+/*! RFP_TMU - Radio Controller Timing Controller (RFP TMU) interrupt wake-up. 0 = Wake-up disabled.
+ *    1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_RFP_TMU(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_RFP_TMU_SHIFT)) & SYSCON_STARTER1_RFP_TMU_MASK)
+#define SYSCON_STARTER1_RFP_AGC_MASK             (0x2000U)
+#define SYSCON_STARTER1_RFP_AGC_SHIFT            (13U)
+/*! RFP_AGC - Radio Control AGC (RFP AGC) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_RFP_AGC(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_RFP_AGC_SHIFT)) & SYSCON_STARTER1_RFP_AGC_MASK)
+#define SYSCON_STARTER1_ISO7816_MASK             (0x4000U)
+#define SYSCON_STARTER1_ISO7816_SHIFT            (14U)
+/*! ISO7816 - ISO7816 Smart Card interface interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ISO7816(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ISO7816_SHIFT)) & SYSCON_STARTER1_ISO7816_MASK)
+#define SYSCON_STARTER1_ANA_COMP_MASK            (0x8000U)
+#define SYSCON_STARTER1_ANA_COMP_SHIFT           (15U)
+/*! ANA_COMP - Analog Comparator interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER1_ANA_COMP(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ANA_COMP_SHIFT)) & SYSCON_STARTER1_ANA_COMP_MASK)
+#define SYSCON_STARTER1_WAKE_UP_TIMER0_MASK      (0x10000U)
+#define SYSCON_STARTER1_WAKE_UP_TIMER0_SHIFT     (16U)
+/*! WAKE_UP_TIMER0 - Wake-up Timer0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER1_WAKE_UP_TIMER0(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_WAKE_UP_TIMER0_SHIFT)) & SYSCON_STARTER1_WAKE_UP_TIMER0_MASK)
+#define SYSCON_STARTER1_WAKE_UP_TIMER1_MASK      (0x20000U)
+#define SYSCON_STARTER1_WAKE_UP_TIMER1_SHIFT     (17U)
+/*! WAKE_UP_TIMER1 - Wake-up Timer1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER1_WAKE_UP_TIMER1(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_WAKE_UP_TIMER1_SHIFT)) & SYSCON_STARTER1_WAKE_UP_TIMER1_MASK)
+#define SYSCON_STARTER1_GPIO_MASK                (0x80000000U)
+#define SYSCON_STARTER1_GPIO_SHIFT               (31U)
+/*! GPIO - GPIO interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Set this bit to allow
+ *    GPIO or NTAG_INT to cause a wake-up in Deep-Sleep and Power-down mode.
+ */
+#define SYSCON_STARTER1_GPIO(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_GPIO_SHIFT)) & SYSCON_STARTER1_GPIO_MASK)
+/*! @} */
+
+/*! @name STARTERX_STARTERS - Pin assign register */
+/*! @{ */
+#define SYSCON_STARTERX_STARTERS_DATA_MASK       (0xFFFFFFFFU)
+#define SYSCON_STARTERX_STARTERS_DATA_SHIFT      (0U)
+#define SYSCON_STARTERX_STARTERS_DATA(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERX_STARTERS_DATA_SHIFT)) & SYSCON_STARTERX_STARTERS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_STARTERX_STARTERS */
+#define SYSCON_STARTERX_STARTERS_COUNT           (2U)
+
+/*! @name STARTERSET0 - Set bits in STARTER0 */
+/*! @{ */
+#define SYSCON_STARTERSET0_WDT_BOD_SET_MASK      (0x1U)
+#define SYSCON_STARTERSET0_WDT_BOD_SET_SHIFT     (0U)
+/*! WDT_BOD_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_WDT_BOD_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_WDT_BOD_SET_SHIFT)) & SYSCON_STARTERSET0_WDT_BOD_SET_MASK)
+#define SYSCON_STARTERSET0_DMA_SET_MASK          (0x2U)
+#define SYSCON_STARTERSET0_DMA_SET_SHIFT         (1U)
+/*! DMA_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_DMA_SET(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_DMA_SET_SHIFT)) & SYSCON_STARTERSET0_DMA_SET_MASK)
+#define SYSCON_STARTERSET0_GINT_SET_MASK         (0x4U)
+#define SYSCON_STARTERSET0_GINT_SET_SHIFT        (2U)
+/*! GINT_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_GINT_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_GINT_SET_SHIFT)) & SYSCON_STARTERSET0_GINT_SET_MASK)
+#define SYSCON_STARTERSET0_IRBLASTER_SET_MASK    (0x8U)
+#define SYSCON_STARTERSET0_IRBLASTER_SET_SHIFT   (3U)
+/*! IRBLASTER_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_IRBLASTER_SET(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_IRBLASTER_SET_SHIFT)) & SYSCON_STARTERSET0_IRBLASTER_SET_MASK)
+#define SYSCON_STARTERSET0_PINT0_SET_MASK        (0x10U)
+#define SYSCON_STARTERSET0_PINT0_SET_SHIFT       (4U)
+/*! PINT0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PINT0_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PINT0_SET_SHIFT)) & SYSCON_STARTERSET0_PINT0_SET_MASK)
+#define SYSCON_STARTERSET0_PINT1_SET_MASK        (0x20U)
+#define SYSCON_STARTERSET0_PINT1_SET_SHIFT       (5U)
+/*! PINT1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PINT1_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PINT1_SET_SHIFT)) & SYSCON_STARTERSET0_PINT1_SET_MASK)
+#define SYSCON_STARTERSET0_PINT2_SET_MASK        (0x40U)
+#define SYSCON_STARTERSET0_PINT2_SET_SHIFT       (6U)
+/*! PINT2_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PINT2_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PINT2_SET_SHIFT)) & SYSCON_STARTERSET0_PINT2_SET_MASK)
+#define SYSCON_STARTERSET0_PINT3_SET_MASK        (0x80U)
+#define SYSCON_STARTERSET0_PINT3_SET_SHIFT       (7U)
+/*! PINT3_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PINT3_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PINT3_SET_SHIFT)) & SYSCON_STARTERSET0_PINT3_SET_MASK)
+#define SYSCON_STARTERSET0_SPIFI_SET_MASK        (0x100U)
+#define SYSCON_STARTERSET0_SPIFI_SET_SHIFT       (8U)
+/*! SPIFI_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_SPIFI_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_SPIFI_SET_SHIFT)) & SYSCON_STARTERSET0_SPIFI_SET_MASK)
+#define SYSCON_STARTERSET0_TIMER0_SET_MASK       (0x200U)
+#define SYSCON_STARTERSET0_TIMER0_SET_SHIFT      (9U)
+/*! TIMER0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_TIMER0_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_TIMER0_SET_SHIFT)) & SYSCON_STARTERSET0_TIMER0_SET_MASK)
+#define SYSCON_STARTERSET0_TIMER1_SET_MASK       (0x400U)
+#define SYSCON_STARTERSET0_TIMER1_SET_SHIFT      (10U)
+/*! TIMER1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_TIMER1_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_TIMER1_SET_SHIFT)) & SYSCON_STARTERSET0_TIMER1_SET_MASK)
+#define SYSCON_STARTERSET0_USART0_SET_MASK       (0x800U)
+#define SYSCON_STARTERSET0_USART0_SET_SHIFT      (11U)
+/*! USART0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_USART0_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_USART0_SET_SHIFT)) & SYSCON_STARTERSET0_USART0_SET_MASK)
+#define SYSCON_STARTERSET0_USART1_SET_MASK       (0x1000U)
+#define SYSCON_STARTERSET0_USART1_SET_SHIFT      (12U)
+/*! USART1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_USART1_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_USART1_SET_SHIFT)) & SYSCON_STARTERSET0_USART1_SET_MASK)
+#define SYSCON_STARTERSET0_I2C0_SET_MASK         (0x2000U)
+#define SYSCON_STARTERSET0_I2C0_SET_SHIFT        (13U)
+/*! I2C0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_I2C0_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_I2C0_SET_SHIFT)) & SYSCON_STARTERSET0_I2C0_SET_MASK)
+#define SYSCON_STARTERSET0_I2C1_SET_MASK         (0x4000U)
+#define SYSCON_STARTERSET0_I2C1_SET_SHIFT        (14U)
+/*! I2C1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_I2C1_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_I2C1_SET_SHIFT)) & SYSCON_STARTERSET0_I2C1_SET_MASK)
+#define SYSCON_STARTERSET0_SPI0_SET_MASK         (0x8000U)
+#define SYSCON_STARTERSET0_SPI0_SET_SHIFT        (15U)
+/*! SPI0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_SPI0_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_SPI0_SET_SHIFT)) & SYSCON_STARTERSET0_SPI0_SET_MASK)
+#define SYSCON_STARTERSET0_SPI1_SET_MASK         (0x10000U)
+#define SYSCON_STARTERSET0_SPI1_SET_SHIFT        (16U)
+/*! SPI1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_SPI1_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_SPI1_SET_SHIFT)) & SYSCON_STARTERSET0_SPI1_SET_MASK)
+#define SYSCON_STARTERSET0_PWM0_SET_MASK         (0x20000U)
+#define SYSCON_STARTERSET0_PWM0_SET_SHIFT        (17U)
+/*! PWM0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM0_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM0_SET_SHIFT)) & SYSCON_STARTERSET0_PWM0_SET_MASK)
+#define SYSCON_STARTERSET0_PWM1_SET_MASK         (0x40000U)
+#define SYSCON_STARTERSET0_PWM1_SET_SHIFT        (18U)
+/*! PWM1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM1_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM1_SET_SHIFT)) & SYSCON_STARTERSET0_PWM1_SET_MASK)
+#define SYSCON_STARTERSET0_PWM2_SET_MASK         (0x80000U)
+#define SYSCON_STARTERSET0_PWM2_SET_SHIFT        (19U)
+/*! PWM2_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM2_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM2_SET_SHIFT)) & SYSCON_STARTERSET0_PWM2_SET_MASK)
+#define SYSCON_STARTERSET0_PWM3_SET_MASK         (0x100000U)
+#define SYSCON_STARTERSET0_PWM3_SET_SHIFT        (20U)
+/*! PWM3_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM3_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM3_SET_SHIFT)) & SYSCON_STARTERSET0_PWM3_SET_MASK)
+#define SYSCON_STARTERSET0_PWM4_SET_MASK         (0x200000U)
+#define SYSCON_STARTERSET0_PWM4_SET_SHIFT        (21U)
+/*! PWM4_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM4_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM4_SET_SHIFT)) & SYSCON_STARTERSET0_PWM4_SET_MASK)
+#define SYSCON_STARTERSET0_PWM5_SET_MASK         (0x400000U)
+#define SYSCON_STARTERSET0_PWM5_SET_SHIFT        (22U)
+/*! PWM5_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM5_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM5_SET_SHIFT)) & SYSCON_STARTERSET0_PWM5_SET_MASK)
+#define SYSCON_STARTERSET0_PWM6_SET_MASK         (0x800000U)
+#define SYSCON_STARTERSET0_PWM6_SET_SHIFT        (23U)
+/*! PWM6_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM6_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM6_SET_SHIFT)) & SYSCON_STARTERSET0_PWM6_SET_MASK)
+#define SYSCON_STARTERSET0_PWM7_SET_MASK         (0x1000000U)
+#define SYSCON_STARTERSET0_PWM7_SET_SHIFT        (24U)
+/*! PWM7_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM7_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM7_SET_SHIFT)) & SYSCON_STARTERSET0_PWM7_SET_MASK)
+#define SYSCON_STARTERSET0_PWM8_SET_MASK         (0x2000000U)
+#define SYSCON_STARTERSET0_PWM8_SET_SHIFT        (25U)
+/*! PWM8_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM8_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM8_SET_SHIFT)) & SYSCON_STARTERSET0_PWM8_SET_MASK)
+#define SYSCON_STARTERSET0_PWM9_SET_MASK         (0x4000000U)
+#define SYSCON_STARTERSET0_PWM9_SET_SHIFT        (26U)
+/*! PWM9_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM9_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM9_SET_SHIFT)) & SYSCON_STARTERSET0_PWM9_SET_MASK)
+#define SYSCON_STARTERSET0_PWM10_SET_MASK        (0x8000000U)
+#define SYSCON_STARTERSET0_PWM10_SET_SHIFT       (27U)
+/*! PWM10_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM10_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM10_SET_SHIFT)) & SYSCON_STARTERSET0_PWM10_SET_MASK)
+#define SYSCON_STARTERSET0_I2C2_SET_MASK         (0x10000000U)
+#define SYSCON_STARTERSET0_I2C2_SET_SHIFT        (28U)
+/*! I2C2_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_I2C2_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_I2C2_SET_SHIFT)) & SYSCON_STARTERSET0_I2C2_SET_MASK)
+#define SYSCON_STARTERSET0_RTC_SET_MASK          (0x20000000U)
+#define SYSCON_STARTERSET0_RTC_SET_SHIFT         (29U)
+/*! RTC_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_RTC_SET(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_RTC_SET_SHIFT)) & SYSCON_STARTERSET0_RTC_SET_MASK)
+#define SYSCON_STARTERSET0_NFCTAG_SET_MASK       (0x40000000U)
+#define SYSCON_STARTERSET0_NFCTAG_SET_SHIFT      (30U)
+/*! NFCTAG_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_NFCTAG_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_NFCTAG_SET_SHIFT)) & SYSCON_STARTERSET0_NFCTAG_SET_MASK)
+/*! @} */
+
+/*! @name STARTERSET1 - Set bits in STARTER1 */
+/*! @{ */
+#define SYSCON_STARTERSET1_ADC_SEQA_SET_MASK     (0x1U)
+#define SYSCON_STARTERSET1_ADC_SEQA_SET_SHIFT    (0U)
+/*! ADC_SEQA_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ADC_SEQA_SET(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ADC_SEQA_SET_SHIFT)) & SYSCON_STARTERSET1_ADC_SEQA_SET_MASK)
+#define SYSCON_STARTERSET1_ADC_THCMP_OVR_SET_MASK (0x4U)
+#define SYSCON_STARTERSET1_ADC_THCMP_OVR_SET_SHIFT (2U)
+/*! ADC_THCMP_OVR_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ADC_THCMP_OVR_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ADC_THCMP_OVR_SET_SHIFT)) & SYSCON_STARTERSET1_ADC_THCMP_OVR_SET_MASK)
+#define SYSCON_STARTERSET1_DMIC_SET_MASK         (0x8U)
+#define SYSCON_STARTERSET1_DMIC_SET_SHIFT        (3U)
+/*! DMIC_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_DMIC_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_DMIC_SET_SHIFT)) & SYSCON_STARTERSET1_DMIC_SET_MASK)
+#define SYSCON_STARTERSET1_HWVAD_SET_MASK        (0x10U)
+#define SYSCON_STARTERSET1_HWVAD_SET_SHIFT       (4U)
+/*! HWVAD_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_HWVAD_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_HWVAD_SET_SHIFT)) & SYSCON_STARTERSET1_HWVAD_SET_MASK)
+#define SYSCON_STARTERSET1_ZIGBEE_MAC_SET_MASK   (0x400U)
+#define SYSCON_STARTERSET1_ZIGBEE_MAC_SET_SHIFT  (10U)
+/*! ZIGBEE_MAC_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ZIGBEE_MAC_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ZIGBEE_MAC_SET_SHIFT)) & SYSCON_STARTERSET1_ZIGBEE_MAC_SET_MASK)
+#define SYSCON_STARTERSET1_ZIGBEE_MODEM_SET_MASK (0x800U)
+#define SYSCON_STARTERSET1_ZIGBEE_MODEM_SET_SHIFT (11U)
+/*! ZIGBEE_MODEM_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ZIGBEE_MODEM_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ZIGBEE_MODEM_SET_SHIFT)) & SYSCON_STARTERSET1_ZIGBEE_MODEM_SET_MASK)
+#define SYSCON_STARTERSET1_RFP_TMU_SET_MASK      (0x1000U)
+#define SYSCON_STARTERSET1_RFP_TMU_SET_SHIFT     (12U)
+/*! RFP_TMU_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_RFP_TMU_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_RFP_TMU_SET_SHIFT)) & SYSCON_STARTERSET1_RFP_TMU_SET_MASK)
+#define SYSCON_STARTERSET1_RFP_AGC_SET_MASK      (0x2000U)
+#define SYSCON_STARTERSET1_RFP_AGC_SET_SHIFT     (13U)
+/*! RFP_AGC_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_RFP_AGC_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_RFP_AGC_SET_SHIFT)) & SYSCON_STARTERSET1_RFP_AGC_SET_MASK)
+#define SYSCON_STARTERSET1_ISO7816_SET_MASK      (0x4000U)
+#define SYSCON_STARTERSET1_ISO7816_SET_SHIFT     (14U)
+/*! ISO7816_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ISO7816_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ISO7816_SET_SHIFT)) & SYSCON_STARTERSET1_ISO7816_SET_MASK)
+#define SYSCON_STARTERSET1_ANA_COMP_SET_MASK     (0x8000U)
+#define SYSCON_STARTERSET1_ANA_COMP_SET_SHIFT    (15U)
+/*! ANA_COMP_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ANA_COMP_SET(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ANA_COMP_SET_SHIFT)) & SYSCON_STARTERSET1_ANA_COMP_SET_MASK)
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET_MASK (0x10000U)
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET_SHIFT (16U)
+/*! WAKE_UP_TIMER0_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET_SHIFT)) & SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET_MASK)
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET_MASK (0x20000U)
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET_SHIFT (17U)
+/*! WAKE_UP_TIMER1_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET_SHIFT)) & SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET_MASK)
+#define SYSCON_STARTERSET1_GPIO_SET_MASK         (0x80000000U)
+#define SYSCON_STARTERSET1_GPIO_SET_SHIFT        (31U)
+/*! GPIO_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_GPIO_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_GPIO_SET_SHIFT)) & SYSCON_STARTERSET1_GPIO_SET_MASK)
+/*! @} */
+
+/*! @name STARTERSETX_STARTERSETS - Pin assign register */
+/*! @{ */
+#define SYSCON_STARTERSETX_STARTERSETS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_STARTERSETX_STARTERSETS_DATA_SHIFT (0U)
+#define SYSCON_STARTERSETX_STARTERSETS_DATA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSETX_STARTERSETS_DATA_SHIFT)) & SYSCON_STARTERSETX_STARTERSETS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_STARTERSETX_STARTERSETS */
+#define SYSCON_STARTERSETX_STARTERSETS_COUNT     (2U)
+
+/*! @name STARTERCLR0 - Clear bits in STARTER0 */
+/*! @{ */
+#define SYSCON_STARTERCLR0_WDT_BOD_CLR_MASK      (0x1U)
+#define SYSCON_STARTERCLR0_WDT_BOD_CLR_SHIFT     (0U)
+/*! WDT_BOD_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_WDT_BOD_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_WDT_BOD_CLR_SHIFT)) & SYSCON_STARTERCLR0_WDT_BOD_CLR_MASK)
+#define SYSCON_STARTERCLR0_DMA_CLR_MASK          (0x2U)
+#define SYSCON_STARTERCLR0_DMA_CLR_SHIFT         (1U)
+/*! DMA_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_DMA_CLR(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_DMA_CLR_SHIFT)) & SYSCON_STARTERCLR0_DMA_CLR_MASK)
+#define SYSCON_STARTERCLR0_GINT_CLR_MASK         (0x4U)
+#define SYSCON_STARTERCLR0_GINT_CLR_SHIFT        (2U)
+/*! GINT_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_GINT_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_GINT_CLR_SHIFT)) & SYSCON_STARTERCLR0_GINT_CLR_MASK)
+#define SYSCON_STARTERCLR0_IRBLASTER_CLR_MASK    (0x8U)
+#define SYSCON_STARTERCLR0_IRBLASTER_CLR_SHIFT   (3U)
+/*! IRBLASTER_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_IRBLASTER_CLR(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_IRBLASTER_CLR_SHIFT)) & SYSCON_STARTERCLR0_IRBLASTER_CLR_MASK)
+#define SYSCON_STARTERCLR0_PINT0_CLR_MASK        (0x10U)
+#define SYSCON_STARTERCLR0_PINT0_CLR_SHIFT       (4U)
+/*! PINT0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PINT0_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PINT0_CLR_SHIFT)) & SYSCON_STARTERCLR0_PINT0_CLR_MASK)
+#define SYSCON_STARTERCLR0_PINT1_CLR_MASK        (0x20U)
+#define SYSCON_STARTERCLR0_PINT1_CLR_SHIFT       (5U)
+/*! PINT1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PINT1_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PINT1_CLR_SHIFT)) & SYSCON_STARTERCLR0_PINT1_CLR_MASK)
+#define SYSCON_STARTERCLR0_PINT2_CLR_MASK        (0x40U)
+#define SYSCON_STARTERCLR0_PINT2_CLR_SHIFT       (6U)
+/*! PINT2_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PINT2_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PINT2_CLR_SHIFT)) & SYSCON_STARTERCLR0_PINT2_CLR_MASK)
+#define SYSCON_STARTERCLR0_PINT3_CLR_MASK        (0x80U)
+#define SYSCON_STARTERCLR0_PINT3_CLR_SHIFT       (7U)
+/*! PINT3_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PINT3_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PINT3_CLR_SHIFT)) & SYSCON_STARTERCLR0_PINT3_CLR_MASK)
+#define SYSCON_STARTERCLR0_SPIFI_CLR_MASK        (0x100U)
+#define SYSCON_STARTERCLR0_SPIFI_CLR_SHIFT       (8U)
+/*! SPIFI_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_SPIFI_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_SPIFI_CLR_SHIFT)) & SYSCON_STARTERCLR0_SPIFI_CLR_MASK)
+#define SYSCON_STARTERCLR0_TIMER0_CLR_MASK       (0x200U)
+#define SYSCON_STARTERCLR0_TIMER0_CLR_SHIFT      (9U)
+/*! TIMER0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_TIMER0_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_TIMER0_CLR_SHIFT)) & SYSCON_STARTERCLR0_TIMER0_CLR_MASK)
+#define SYSCON_STARTERCLR0_TIMER1_CLR_MASK       (0x400U)
+#define SYSCON_STARTERCLR0_TIMER1_CLR_SHIFT      (10U)
+/*! TIMER1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_TIMER1_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_TIMER1_CLR_SHIFT)) & SYSCON_STARTERCLR0_TIMER1_CLR_MASK)
+#define SYSCON_STARTERCLR0_USART0_CLR_MASK       (0x800U)
+#define SYSCON_STARTERCLR0_USART0_CLR_SHIFT      (11U)
+/*! USART0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_USART0_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_USART0_CLR_SHIFT)) & SYSCON_STARTERCLR0_USART0_CLR_MASK)
+#define SYSCON_STARTERCLR0_USART1_CLR_MASK       (0x1000U)
+#define SYSCON_STARTERCLR0_USART1_CLR_SHIFT      (12U)
+/*! USART1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_USART1_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_USART1_CLR_SHIFT)) & SYSCON_STARTERCLR0_USART1_CLR_MASK)
+#define SYSCON_STARTERCLR0_I2C0_CLR_MASK         (0x2000U)
+#define SYSCON_STARTERCLR0_I2C0_CLR_SHIFT        (13U)
+/*! I2C0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_I2C0_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_I2C0_CLR_SHIFT)) & SYSCON_STARTERCLR0_I2C0_CLR_MASK)
+#define SYSCON_STARTERCLR0_I2C1_CLR_MASK         (0x4000U)
+#define SYSCON_STARTERCLR0_I2C1_CLR_SHIFT        (14U)
+/*! I2C1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_I2C1_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_I2C1_CLR_SHIFT)) & SYSCON_STARTERCLR0_I2C1_CLR_MASK)
+#define SYSCON_STARTERCLR0_SPI0_CLR_MASK         (0x8000U)
+#define SYSCON_STARTERCLR0_SPI0_CLR_SHIFT        (15U)
+/*! SPI0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_SPI0_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_SPI0_CLR_SHIFT)) & SYSCON_STARTERCLR0_SPI0_CLR_MASK)
+#define SYSCON_STARTERCLR0_SPI1_CLR_MASK         (0x10000U)
+#define SYSCON_STARTERCLR0_SPI1_CLR_SHIFT        (16U)
+/*! SPI1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_SPI1_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_SPI1_CLR_SHIFT)) & SYSCON_STARTERCLR0_SPI1_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM0_CLR_MASK         (0x20000U)
+#define SYSCON_STARTERCLR0_PWM0_CLR_SHIFT        (17U)
+/*! PWM0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM0_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM0_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM0_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM1_CLR_MASK         (0x40000U)
+#define SYSCON_STARTERCLR0_PWM1_CLR_SHIFT        (18U)
+/*! PWM1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM1_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM1_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM1_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM2_CLR_MASK         (0x80000U)
+#define SYSCON_STARTERCLR0_PWM2_CLR_SHIFT        (19U)
+/*! PWM2_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM2_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM2_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM2_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM3_CLR_MASK         (0x100000U)
+#define SYSCON_STARTERCLR0_PWM3_CLR_SHIFT        (20U)
+/*! PWM3_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM3_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM3_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM3_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM4_CLR_MASK         (0x200000U)
+#define SYSCON_STARTERCLR0_PWM4_CLR_SHIFT        (21U)
+/*! PWM4_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM4_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM4_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM4_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM5_CLR_MASK         (0x400000U)
+#define SYSCON_STARTERCLR0_PWM5_CLR_SHIFT        (22U)
+/*! PWM5_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM5_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM5_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM5_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM6_CLR_MASK         (0x800000U)
+#define SYSCON_STARTERCLR0_PWM6_CLR_SHIFT        (23U)
+/*! PWM6_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM6_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM6_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM6_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM7_CLR_MASK         (0x1000000U)
+#define SYSCON_STARTERCLR0_PWM7_CLR_SHIFT        (24U)
+/*! PWM7_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM7_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM7_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM7_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM8_CLR_MASK         (0x2000000U)
+#define SYSCON_STARTERCLR0_PWM8_CLR_SHIFT        (25U)
+/*! PWM8_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM8_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM8_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM8_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM9_CLR_MASK         (0x4000000U)
+#define SYSCON_STARTERCLR0_PWM9_CLR_SHIFT        (26U)
+/*! PWM9_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM9_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM9_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM9_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM10_CLR_MASK        (0x8000000U)
+#define SYSCON_STARTERCLR0_PWM10_CLR_SHIFT       (27U)
+/*! PWM10_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM10_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM10_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM10_CLR_MASK)
+#define SYSCON_STARTERCLR0_I2C2_CLR_MASK         (0x10000000U)
+#define SYSCON_STARTERCLR0_I2C2_CLR_SHIFT        (28U)
+/*! I2C2_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_I2C2_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_I2C2_CLR_SHIFT)) & SYSCON_STARTERCLR0_I2C2_CLR_MASK)
+#define SYSCON_STARTERCLR0_RTC_CLR_MASK          (0x20000000U)
+#define SYSCON_STARTERCLR0_RTC_CLR_SHIFT         (29U)
+/*! RTC_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_RTC_CLR(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_RTC_CLR_SHIFT)) & SYSCON_STARTERCLR0_RTC_CLR_MASK)
+#define SYSCON_STARTERCLR0_NFCTAG_CLR_MASK       (0x40000000U)
+#define SYSCON_STARTERCLR0_NFCTAG_CLR_SHIFT      (30U)
+/*! NFCTAG_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_NFCTAG_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_NFCTAG_CLR_SHIFT)) & SYSCON_STARTERCLR0_NFCTAG_CLR_MASK)
+/*! @} */
+
+/*! @name STARTERCLR1 - Clear bits in STARTER1 */
+/*! @{ */
+#define SYSCON_STARTERCLR1_ADC_SEQA_CLR_MASK     (0x1U)
+#define SYSCON_STARTERCLR1_ADC_SEQA_CLR_SHIFT    (0U)
+/*! ADC_SEQA_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ADC_SEQA_CLR(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ADC_SEQA_CLR_SHIFT)) & SYSCON_STARTERCLR1_ADC_SEQA_CLR_MASK)
+#define SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR_MASK (0x4U)
+#define SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR_SHIFT (2U)
+/*! ADC_THCMP_OVR_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR_SHIFT)) & SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR_MASK)
+#define SYSCON_STARTERCLR1_DMIC_CLR_MASK         (0x8U)
+#define SYSCON_STARTERCLR1_DMIC_CLR_SHIFT        (3U)
+/*! DMIC_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_DMIC_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_DMIC_CLR_SHIFT)) & SYSCON_STARTERCLR1_DMIC_CLR_MASK)
+#define SYSCON_STARTERCLR1_HWVAD_CLR_MASK        (0x10U)
+#define SYSCON_STARTERCLR1_HWVAD_CLR_SHIFT       (4U)
+/*! HWVAD_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_HWVAD_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_HWVAD_CLR_SHIFT)) & SYSCON_STARTERCLR1_HWVAD_CLR_MASK)
+#define SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR_MASK   (0x400U)
+#define SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR_SHIFT  (10U)
+/*! ZIGBEE_MAC_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR_SHIFT)) & SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR_MASK)
+#define SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR_MASK (0x800U)
+#define SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR_SHIFT (11U)
+/*! ZIGBEE_MODEM_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR_SHIFT)) & SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR_MASK)
+#define SYSCON_STARTERCLR1_RFP_TMU_CLR_MASK      (0x1000U)
+#define SYSCON_STARTERCLR1_RFP_TMU_CLR_SHIFT     (12U)
+/*! RFP_TMU_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_RFP_TMU_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_RFP_TMU_CLR_SHIFT)) & SYSCON_STARTERCLR1_RFP_TMU_CLR_MASK)
+#define SYSCON_STARTERCLR1_RFP_AGC_CLR_MASK      (0x2000U)
+#define SYSCON_STARTERCLR1_RFP_AGC_CLR_SHIFT     (13U)
+/*! RFP_AGC_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_RFP_AGC_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_RFP_AGC_CLR_SHIFT)) & SYSCON_STARTERCLR1_RFP_AGC_CLR_MASK)
+#define SYSCON_STARTERCLR1_ISO7816_CLR_MASK      (0x4000U)
+#define SYSCON_STARTERCLR1_ISO7816_CLR_SHIFT     (14U)
+/*! ISO7816_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ISO7816_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ISO7816_CLR_SHIFT)) & SYSCON_STARTERCLR1_ISO7816_CLR_MASK)
+#define SYSCON_STARTERCLR1_ANA_COMP_CLR_MASK     (0x8000U)
+#define SYSCON_STARTERCLR1_ANA_COMP_CLR_SHIFT    (15U)
+/*! ANA_COMP_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ANA_COMP_CLR(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ANA_COMP_CLR_SHIFT)) & SYSCON_STARTERCLR1_ANA_COMP_CLR_MASK)
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR_MASK (0x10000U)
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR_SHIFT (16U)
+/*! WAKE_UP_TIMER0_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR_SHIFT)) & SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR_MASK)
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR_MASK (0x20000U)
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR_SHIFT (17U)
+/*! WAKE_UP_TIMER1_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR_SHIFT)) & SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR_MASK)
+#define SYSCON_STARTERCLR1_GPIO_CLR_MASK         (0x80000000U)
+#define SYSCON_STARTERCLR1_GPIO_CLR_SHIFT        (31U)
+/*! GPIO_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_GPIO_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_GPIO_CLR_SHIFT)) & SYSCON_STARTERCLR1_GPIO_CLR_MASK)
+/*! @} */
+
+/*! @name STARTERCLRX_STARTERCLRS - Pin assign register */
+/*! @{ */
+#define SYSCON_STARTERCLRX_STARTERCLRS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_STARTERCLRX_STARTERCLRS_DATA_SHIFT (0U)
+#define SYSCON_STARTERCLRX_STARTERCLRS_DATA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLRX_STARTERCLRS_DATA_SHIFT)) & SYSCON_STARTERCLRX_STARTERCLRS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_STARTERCLRX_STARTERCLRS */
+#define SYSCON_STARTERCLRX_STARTERCLRS_COUNT     (2U)
+
+/*! @name RETENTIONCTRL - I/O retention control register */
+/*! @{ */
+#define SYSCON_RETENTIONCTRL_IOCLAMP_MASK        (0x1U)
+#define SYSCON_RETENTIONCTRL_IOCLAMP_SHIFT       (0U)
+/*! IOCLAMP - Global control of activation of I/O clamps to allow IOs to hold a value during a power
+ *    mode cycle. To use enable before the power down and then disable after a wake up. Note that
+ *    each I/O clamp must also be enabled/disabled individually in IOCON module and also that for an
+ *    I2C IO cell it must be in GPIO mode for the clamping to work. 0: I/O clamp is disable 1: I/O
+ *    clamp is enable
+ */
+#define SYSCON_RETENTIONCTRL_IOCLAMP(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_RETENTIONCTRL_IOCLAMP_SHIFT)) & SYSCON_RETENTIONCTRL_IOCLAMP_MASK)
+/*! @} */
+
+/*! @name CPSTACK - CPSTACK */
+/*! @{ */
+#define SYSCON_CPSTACK_CPSTACK_MASK              (0xFFFFFFFFU)
+#define SYSCON_CPSTACK_CPSTACK_SHIFT             (0U)
+/*! CPSTACK - CPSTACK
+ */
+#define SYSCON_CPSTACK_CPSTACK(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTACK_CPSTACK_SHIFT)) & SYSCON_CPSTACK_CPSTACK_MASK)
+/*! @} */
+
+/*! @name ANACTRL_CTRL - Analog Interrupt control register. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set. */
+/*! @{ */
+#define SYSCON_ANACTRL_CTRL_COMPINTRLVL_MASK     (0x1U)
+#define SYSCON_ANACTRL_CTRL_COMPINTRLVL_SHIFT    (0U)
+/*! COMPINTRLVL - Analog Comparator interrupt type: 0: Analog Comparator interrupt is edge
+ *    sensitive. 1: Analog Comparator interrupt is level sensitive.
+ */
+#define SYSCON_ANACTRL_CTRL_COMPINTRLVL(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_CTRL_COMPINTRLVL_SHIFT)) & SYSCON_ANACTRL_CTRL_COMPINTRLVL_MASK)
+#define SYSCON_ANACTRL_CTRL_COMPINTRPOL_MASK     (0x6U)
+#define SYSCON_ANACTRL_CTRL_COMPINTRPOL_SHIFT    (1U)
+/*! COMPINTRPOL - Analog Comparator interrupt Polarity: When COMPINTRLVL = 0 (edge sensitive): 00:
+ *    rising edge. 01: falling edge. 10: both edges (rising and falling). 11: both edges (rising and
+ *    falling). When COMPINTRLVL = 1 (level sensitive): 00: Low level ('0'). 01: Low level ('0').
+ *    10: High level ('1'). 11: High level ('1').
+ */
+#define SYSCON_ANACTRL_CTRL_COMPINTRPOL(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_CTRL_COMPINTRPOL_SHIFT)) & SYSCON_ANACTRL_CTRL_COMPINTRPOL_MASK)
+/*! @} */
+
+/*! @name ANACTRL_VAL - Analog modules (BOD and Analog Comparator) outputs current values (BOD 'Power OK' and Analog comparator out). Requires AHBCLKCTRL0.ANA_INT_CTRL to be set. */
+/*! @{ */
+#define SYSCON_ANACTRL_VAL_BODVBAT_MASK          (0x1U)
+#define SYSCON_ANACTRL_VAL_BODVBAT_SHIFT         (0U)
+/*! BODVBAT - BOD VBAT Status : 0 = Power not OK ; 1 = Power OK
+ */
+#define SYSCON_ANACTRL_VAL_BODVBAT(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_VAL_BODVBAT_SHIFT)) & SYSCON_ANACTRL_VAL_BODVBAT_MASK)
+#define SYSCON_ANACTRL_VAL_ANACOMP_MASK          (0x8U)
+#define SYSCON_ANACTRL_VAL_ANACOMP_SHIFT         (3U)
+/*! ANACOMP - Analog comparator Status : 0 = Comparator in 0 < in 1 ; 1 = Comparator in 0 > in 1.
+ */
+#define SYSCON_ANACTRL_VAL_ANACOMP(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_VAL_ANACOMP_SHIFT)) & SYSCON_ANACTRL_VAL_ANACOMP_MASK)
+#define SYSCON_ANACTRL_VAL_BODVBATHIGH_MASK      (0x10U)
+#define SYSCON_ANACTRL_VAL_BODVBATHIGH_SHIFT     (4U)
+/*! BODVBATHIGH - Not(BOD VBAT). Inverse of BOD VBAT. 0 = Power OK; 1 = Power not OK
+ */
+#define SYSCON_ANACTRL_VAL_BODVBATHIGH(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_VAL_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_VAL_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name ANACTRL_STAT - Analog modules (BOD and Analog Comparator) interrupt status. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set. */
+/*! @{ */
+#define SYSCON_ANACTRL_STAT_BODVBAT_MASK         (0x1U)
+#define SYSCON_ANACTRL_STAT_BODVBAT_SHIFT        (0U)
+/*! BODVBAT - BOD VBAT Interrupt status. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear.
+ */
+#define SYSCON_ANACTRL_STAT_BODVBAT(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_STAT_BODVBAT_SHIFT)) & SYSCON_ANACTRL_STAT_BODVBAT_MASK)
+#define SYSCON_ANACTRL_STAT_ANACOMP_MASK         (0x8U)
+#define SYSCON_ANACTRL_STAT_ANACOMP_SHIFT        (3U)
+/*! ANACOMP - Analog comparator Interrupt status. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear.
+ */
+#define SYSCON_ANACTRL_STAT_ANACOMP(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_STAT_ANACOMP_SHIFT)) & SYSCON_ANACTRL_STAT_ANACOMP_MASK)
+#define SYSCON_ANACTRL_STAT_BODVBATHIGH_MASK     (0x10U)
+#define SYSCON_ANACTRL_STAT_BODVBATHIGH_SHIFT    (4U)
+/*! BODVBATHIGH - NOT(BOD VBAT) interrupt status. Will be set when BOD VBAT goes high. Write 1 to clear.
+ */
+#define SYSCON_ANACTRL_STAT_BODVBATHIGH(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_STAT_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_STAT_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name ANACTRL_INTENSET - Analog modules (BOD and Analog Comparator) Interrupt Enable Read and Set register. Read value indicates which interrupts are enabled. Writing ones sets the corresponding interrupt enable bits. Note, interrupt enable bits are cleared using ANACTRL_INTENCLR. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register. */
+/*! @{ */
+#define SYSCON_ANACTRL_INTENSET_BODVBAT_MASK     (0x1U)
+#define SYSCON_ANACTRL_INTENSET_BODVBAT_SHIFT    (0U)
+/*! BODVBAT - BOD VBAT Interrupt Enable Read and Set register
+ */
+#define SYSCON_ANACTRL_INTENSET_BODVBAT(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENSET_BODVBAT_SHIFT)) & SYSCON_ANACTRL_INTENSET_BODVBAT_MASK)
+#define SYSCON_ANACTRL_INTENSET_ANACOMP_MASK     (0x8U)
+#define SYSCON_ANACTRL_INTENSET_ANACOMP_SHIFT    (3U)
+/*! ANACOMP - Analog comparator Interrupt Enable Read and Set register
+ */
+#define SYSCON_ANACTRL_INTENSET_ANACOMP(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENSET_ANACOMP_SHIFT)) & SYSCON_ANACTRL_INTENSET_ANACOMP_MASK)
+#define SYSCON_ANACTRL_INTENSET_BODVBATHIGH_MASK (0x10U)
+#define SYSCON_ANACTRL_INTENSET_BODVBATHIGH_SHIFT (4U)
+/*! BODVBATHIGH - NOT(BOD VBAT) Interrupt Enable Read and Set register
+ */
+#define SYSCON_ANACTRL_INTENSET_BODVBATHIGH(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENSET_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_INTENSET_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name ANACTRL_INTENCLR - Analog modules (BOD and Analog Comparator) Interrupt Enable Clear register. Writing ones clears the corresponding interrupt enable bits. Note, interrupt enable bits are set in ANACTRL_INTENSET. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register. */
+/*! @{ */
+#define SYSCON_ANACTRL_INTENCLR_BODVBAT_MASK     (0x1U)
+#define SYSCON_ANACTRL_INTENCLR_BODVBAT_SHIFT    (0U)
+/*! BODVBAT - BOD VBAT Interrupt Enable Clear register
+ */
+#define SYSCON_ANACTRL_INTENCLR_BODVBAT(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENCLR_BODVBAT_SHIFT)) & SYSCON_ANACTRL_INTENCLR_BODVBAT_MASK)
+#define SYSCON_ANACTRL_INTENCLR_ANACOMP_MASK     (0x8U)
+#define SYSCON_ANACTRL_INTENCLR_ANACOMP_SHIFT    (3U)
+/*! ANACOMP - Analog comparator Interrupt Enable Clear register
+ */
+#define SYSCON_ANACTRL_INTENCLR_ANACOMP(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENCLR_ANACOMP_SHIFT)) & SYSCON_ANACTRL_INTENCLR_ANACOMP_MASK)
+#define SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_MASK (0x10U)
+#define SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_SHIFT (4U)
+/*! BODVBATHIGH - NOT(BOD VBAT) Interrupt Enable Clear register
+ */
+#define SYSCON_ANACTRL_INTENCLR_BODVBATHIGH(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name ANACTRL_INTSTAT - Analog modules (BOD and Analog Comparator) Interrupt Status register (masked with interrupt enable). Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register. Interrupt status bit are cleared using ANACTRL_STAT. */
+/*! @{ */
+#define SYSCON_ANACTRL_INTSTAT_BODVBAT_MASK      (0x1U)
+#define SYSCON_ANACTRL_INTSTAT_BODVBAT_SHIFT     (0U)
+/*! BODVBAT - BOD VBAT Interrupt (after interrupt mask). 0 = No interrupt pending. 1 = Interrupt
+ *    pending. Only set when BODVBAT is enabled in INTENSET
+ */
+#define SYSCON_ANACTRL_INTSTAT_BODVBAT(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTSTAT_BODVBAT_SHIFT)) & SYSCON_ANACTRL_INTSTAT_BODVBAT_MASK)
+#define SYSCON_ANACTRL_INTSTAT_ANACOMP_MASK      (0x8U)
+#define SYSCON_ANACTRL_INTSTAT_ANACOMP_SHIFT     (3U)
+/*! ANACOMP - Analog comparator Interrupt (after interrupt mask). 0 = No interrupt pending. 1 =
+ *    Interrupt pending. Only set when ANACOMP is enabled in INTENSET
+ */
+#define SYSCON_ANACTRL_INTSTAT_ANACOMP(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTSTAT_ANACOMP_SHIFT)) & SYSCON_ANACTRL_INTSTAT_ANACOMP_MASK)
+#define SYSCON_ANACTRL_INTSTAT_BODVBATHIGH_MASK  (0x10U)
+#define SYSCON_ANACTRL_INTSTAT_BODVBATHIGH_SHIFT (4U)
+/*! BODVBATHIGH - NOT(BOD VBAT) Interrupt (after interrupt mask). 0 = No interrupt pending. 1 =
+ *    Interrupt pending. Only set when BODVBATHIGH is enabled in INTENSET
+ */
+#define SYSCON_ANACTRL_INTSTAT_BODVBATHIGH(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTSTAT_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_INTSTAT_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name CLOCK_CTRL - Various system clock controls : Flash clock (48 MHz) control, clocks to Frequency Measure function */
+/*! @{ */
+#define SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA_MASK    (0x1U)
+#define SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA_SHIFT   (0U)
+/*! FLASH48MHZ_ENA - Enable Flash 48 MHz clock. 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA_SHIFT)) & SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA_MASK)
+#define SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_MASK (0x2U)
+#define SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_SHIFT (1U)
+/*! XTAL32MHZ_FREQM_ENA - Enable XTAL32MHz clock for Frequency Measure module. 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_SHIFT)) & SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_MASK)
+#define SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_MASK (0x4U)
+#define SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_SHIFT (2U)
+/*! FRO1MHZ_FREQM_ENA - Enable FRO 1MHz clock for Frequency Measure module. 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_SHIFT)) & SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_MASK)
+/*! @} */
+
+/*! @name WKT_CTRL - Wake-up timers control */
+/*! @{ */
+#define SYSCON_WKT_CTRL_WKT0_ENA_MASK            (0x1U)
+#define SYSCON_WKT_CTRL_WKT0_ENA_SHIFT           (0U)
+/*! WKT0_ENA - Enable wake-up timer 0: 0 = Disabled. 1 = Enabled (counter is running).
+ */
+#define SYSCON_WKT_CTRL_WKT0_ENA(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_CTRL_WKT0_ENA_SHIFT)) & SYSCON_WKT_CTRL_WKT0_ENA_MASK)
+#define SYSCON_WKT_CTRL_WKT1_ENA_MASK            (0x2U)
+#define SYSCON_WKT_CTRL_WKT1_ENA_SHIFT           (1U)
+/*! WKT1_ENA - Enable wake-up timer 1: 0 = Disabled. 1 = Enabled (counter is running).
+ */
+#define SYSCON_WKT_CTRL_WKT1_ENA(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_CTRL_WKT1_ENA_SHIFT)) & SYSCON_WKT_CTRL_WKT1_ENA_MASK)
+#define SYSCON_WKT_CTRL_WKT0_CLK_ENA_MASK        (0x4U)
+#define SYSCON_WKT_CTRL_WKT0_CLK_ENA_SHIFT       (2U)
+/*! WKT0_CLK_ENA - Enable wake-up timer 0 clock: 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_WKT_CTRL_WKT0_CLK_ENA(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_CTRL_WKT0_CLK_ENA_SHIFT)) & SYSCON_WKT_CTRL_WKT0_CLK_ENA_MASK)
+#define SYSCON_WKT_CTRL_WKT1_CLK_ENA_MASK        (0x8U)
+#define SYSCON_WKT_CTRL_WKT1_CLK_ENA_SHIFT       (3U)
+/*! WKT1_CLK_ENA - Enable wake-up timer 1 clock: 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_WKT_CTRL_WKT1_CLK_ENA(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_CTRL_WKT1_CLK_ENA_SHIFT)) & SYSCON_WKT_CTRL_WKT1_CLK_ENA_MASK)
+/*! @} */
+
+/*! @name WKT_LOAD_WKT0_LSB - Wake-up timer 0 reload value least significant bits ([31:0]). */
+/*! @{ */
+#define SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB_MASK (0xFFFFFFFFU)
+#define SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB_SHIFT (0U)
+/*! WKT0_LOAD_LSB - Wake-up timer 0 reload value, least significant bits ([31:0]). Write when timer is not enabled
+ */
+#define SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB_SHIFT)) & SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB_MASK)
+/*! @} */
+
+/*! @name WKT_LOAD_WKT0_MSB - Wake-up timer 0 reload value most significant bits ([8:0]). */
+/*! @{ */
+#define SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB_MASK (0x1FFU)
+#define SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB_SHIFT (0U)
+/*! WKT0_LOAD_MSB - Wake-up timer 0 reload value, most significant bits ([8:0]). Write when timer is not enabled
+ */
+#define SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB_SHIFT)) & SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB_MASK)
+/*! @} */
+
+/*! @name WKT_LOAD_WKT1 - Wake-up timer 1 reload value. */
+/*! @{ */
+#define SYSCON_WKT_LOAD_WKT1_WKT1_LOAD_MASK      (0xFFFFFFFU)
+#define SYSCON_WKT_LOAD_WKT1_WKT1_LOAD_SHIFT     (0U)
+/*! WKT1_LOAD - Wake-up timer 1 reload value. Write when timer is not enabled
+ */
+#define SYSCON_WKT_LOAD_WKT1_WKT1_LOAD(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_LOAD_WKT1_WKT1_LOAD_SHIFT)) & SYSCON_WKT_LOAD_WKT1_WKT1_LOAD_MASK)
+/*! @} */
+
+/*! @name WKT_VAL_WKT0_LSB - Wake-up timer 0 current value least significant bits ([31:0]). WARNING : reading not reliable: read this register several times until you get a stable value. */
+/*! @{ */
+#define SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB_MASK (0xFFFFFFFFU)
+#define SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB_SHIFT (0U)
+/*! WKT0_VAL_LSB - Wake-up timer 0 value, least significant bits ([31:0]). Reread until stable value seen.
+ */
+#define SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB_SHIFT)) & SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB_MASK)
+/*! @} */
+
+/*! @name WKT_VAL_WKT0_MSB - Wake-up timer 0 current value most significant bits ([8:0]). WARNING : reading not reliable: read this register several times until you get a stable value. */
+/*! @{ */
+#define SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB_MASK (0x1FFU)
+#define SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB_SHIFT (0U)
+/*! WKT0_VAL_MSB - Wake-up timer 0 value, most significant bits ([8:0]). Reread until stable value seen.
+ */
+#define SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB_SHIFT)) & SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB_MASK)
+/*! @} */
+
+/*! @name WKT_VAL_WKT1 - Wake-up timer 1 current value. WARNING : reading not reliable: read this register several times until you get a stable value. */
+/*! @{ */
+#define SYSCON_WKT_VAL_WKT1_WKT1_VAL_MASK        (0xFFFFFFFU)
+#define SYSCON_WKT_VAL_WKT1_WKT1_VAL_SHIFT       (0U)
+/*! WKT1_VAL - Wake-up timer 1 value. Reread until stable value seen.
+ */
+#define SYSCON_WKT_VAL_WKT1_WKT1_VAL(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_VAL_WKT1_WKT1_VAL_SHIFT)) & SYSCON_WKT_VAL_WKT1_WKT1_VAL_MASK)
+/*! @} */
+
+/*! @name WKT_STAT - Wake-up timers status */
+/*! @{ */
+#define SYSCON_WKT_STAT_WKT0_TIMEOUT_MASK        (0x1U)
+#define SYSCON_WKT_STAT_WKT0_TIMEOUT_SHIFT       (0U)
+/*! WKT0_TIMEOUT - Timeout Status of Wake-up timer 0 : 0 = timeout not reached ; 1 = timeout reached. Write 1 to clear.
+ */
+#define SYSCON_WKT_STAT_WKT0_TIMEOUT(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_STAT_WKT0_TIMEOUT_SHIFT)) & SYSCON_WKT_STAT_WKT0_TIMEOUT_MASK)
+#define SYSCON_WKT_STAT_WKT1_TIMEOUT_MASK        (0x2U)
+#define SYSCON_WKT_STAT_WKT1_TIMEOUT_SHIFT       (1U)
+/*! WKT1_TIMEOUT - Timeout Status of Wake-up timer 1 : 0 = timeout not reached ; 1 = timeout reached. Write 1 to clear.
+ */
+#define SYSCON_WKT_STAT_WKT1_TIMEOUT(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_STAT_WKT1_TIMEOUT_SHIFT)) & SYSCON_WKT_STAT_WKT1_TIMEOUT_MASK)
+#define SYSCON_WKT_STAT_WKT0_RUNNING_MASK        (0x4U)
+#define SYSCON_WKT_STAT_WKT0_RUNNING_SHIFT       (2U)
+/*! WKT0_RUNNING - Running Status of Wake-up timer 0 : 0 = not running ; 1 = running
+ */
+#define SYSCON_WKT_STAT_WKT0_RUNNING(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_STAT_WKT0_RUNNING_SHIFT)) & SYSCON_WKT_STAT_WKT0_RUNNING_MASK)
+#define SYSCON_WKT_STAT_WKT1_RUNNING_MASK        (0x8U)
+#define SYSCON_WKT_STAT_WKT1_RUNNING_SHIFT       (3U)
+/*! WKT1_RUNNING - Running Status of Wake-up timer 1 : 0 = not running ; 1 = running
+ */
+#define SYSCON_WKT_STAT_WKT1_RUNNING(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_STAT_WKT1_RUNNING_SHIFT)) & SYSCON_WKT_STAT_WKT1_RUNNING_MASK)
+/*! @} */
+
+/*! @name WKT_INTENSET - Interrupt Enable Read and Set register */
+/*! @{ */
+#define SYSCON_WKT_INTENSET_WKT0_TIMEOUT_MASK    (0x1U)
+#define SYSCON_WKT_INTENSET_WKT0_TIMEOUT_SHIFT   (0U)
+/*! WKT0_TIMEOUT - Wake-up Timer 0 Timeout Interrupt Enable Read and Set register. Read value of '1'
+ *    indicates that the interrupt is enabled. Set this bit to enable the interrupt. Use
+ *    WKT_INTENCLR to disable the interrupt.
+ */
+#define SYSCON_WKT_INTENSET_WKT0_TIMEOUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTENSET_WKT0_TIMEOUT_SHIFT)) & SYSCON_WKT_INTENSET_WKT0_TIMEOUT_MASK)
+#define SYSCON_WKT_INTENSET_WKT1_TIMEOUT_MASK    (0x2U)
+#define SYSCON_WKT_INTENSET_WKT1_TIMEOUT_SHIFT   (1U)
+/*! WKT1_TIMEOUT - Wake-up Timer 1 Timeout Interrupt Enable Read and Set register. Read value of '1'
+ *    indicates that the interrupt is enabled. Set this bit to enable the interrupt. Use
+ *    WKT_INTENCLR to disable the interrupt.
+ */
+#define SYSCON_WKT_INTENSET_WKT1_TIMEOUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTENSET_WKT1_TIMEOUT_SHIFT)) & SYSCON_WKT_INTENSET_WKT1_TIMEOUT_MASK)
+/*! @} */
+
+/*! @name WKT_INTENCLR - Interrupt Enable Clear register */
+/*! @{ */
+#define SYSCON_WKT_INTENCLR_WKT0_TIMEOUT_MASK    (0x1U)
+#define SYSCON_WKT_INTENCLR_WKT0_TIMEOUT_SHIFT   (0U)
+/*! WKT0_TIMEOUT - Wake-up Timer 0 Timeout Interrupt Enable Clear register. Set this bit to disable the interrupt.
+ */
+#define SYSCON_WKT_INTENCLR_WKT0_TIMEOUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTENCLR_WKT0_TIMEOUT_SHIFT)) & SYSCON_WKT_INTENCLR_WKT0_TIMEOUT_MASK)
+#define SYSCON_WKT_INTENCLR_WKT1_TIMEOUT_MASK    (0x2U)
+#define SYSCON_WKT_INTENCLR_WKT1_TIMEOUT_SHIFT   (1U)
+/*! WKT1_TIMEOUT - Wake-up Timer 1 Timeout Interrupt Enable Clear register. Set this bit to disable the interrupt.
+ */
+#define SYSCON_WKT_INTENCLR_WKT1_TIMEOUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTENCLR_WKT1_TIMEOUT_SHIFT)) & SYSCON_WKT_INTENCLR_WKT1_TIMEOUT_MASK)
+/*! @} */
+
+/*! @name WKT_INTSTAT - Interrupt Status register */
+/*! @{ */
+#define SYSCON_WKT_INTSTAT_WKT0_TIMEOUT_MASK     (0x1U)
+#define SYSCON_WKT_INTSTAT_WKT0_TIMEOUT_SHIFT    (0U)
+/*! WKT0_TIMEOUT - Wake-up Timer 0 Timeout Interrupt. 0: No interrupt pending. 1: Interrupt pending.
+ *    Only set when WKT0_TIMEOUT is enable in INTENSET
+ */
+#define SYSCON_WKT_INTSTAT_WKT0_TIMEOUT(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTSTAT_WKT0_TIMEOUT_SHIFT)) & SYSCON_WKT_INTSTAT_WKT0_TIMEOUT_MASK)
+#define SYSCON_WKT_INTSTAT_WKT1_TIMEOUT_MASK     (0x2U)
+#define SYSCON_WKT_INTSTAT_WKT1_TIMEOUT_SHIFT    (1U)
+/*! WKT1_TIMEOUT - Wake-up Timer 1 Timeout Interrupt. 0: No interrupt pending. 1: Interrupt pending.
+ *    Only set when WKT1_TIMEOUT is enable in INTENSET
+ */
+#define SYSCON_WKT_INTSTAT_WKT1_TIMEOUT(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTSTAT_WKT1_TIMEOUT_SHIFT)) & SYSCON_WKT_INTSTAT_WKT1_TIMEOUT_MASK)
+/*! @} */
+
+/*! @name GPIOPSYNC - Enable bypass of the first stage of synchonization inside GPIO_INT module. */
+/*! @{ */
+#define SYSCON_GPIOPSYNC_PSYNC_MASK              (0x1U)
+#define SYSCON_GPIOPSYNC_PSYNC_SHIFT             (0U)
+/*! PSYNC - Enable bypass of the first stage of synchonization inside GPIO_INT module.
+ */
+#define SYSCON_GPIOPSYNC_PSYNC(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_GPIOPSYNC_PSYNC_SHIFT)) & SYSCON_GPIOPSYNC_PSYNC_MASK)
+/*! @} */
+
+/*! @name DIEID - Chip revision ID & Number */
+/*! @{ */
+#define SYSCON_DIEID_REV_ID_MASK                 (0xFU)
+#define SYSCON_DIEID_REV_ID_SHIFT                (0U)
+/*! REV_ID - Chip Revision ID
+ */
+#define SYSCON_DIEID_REV_ID(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_DIEID_REV_ID_SHIFT)) & SYSCON_DIEID_REV_ID_MASK)
+#define SYSCON_DIEID_MCO_NUM_IN_DIE_ID_MASK      (0xFFFFF0U)
+#define SYSCON_DIEID_MCO_NUM_IN_DIE_ID_SHIFT     (4U)
+/*! MCO_NUM_IN_DIE_ID - Chip Number
+ */
+#define SYSCON_DIEID_MCO_NUM_IN_DIE_ID(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_DIEID_MCO_NUM_IN_DIE_ID_SHIFT)) & SYSCON_DIEID_MCO_NUM_IN_DIE_ID_MASK)
+/*! @} */
+
+/*! @name CODESECURITYPROT - Security code to allow test access via SWD/JTAG. Reset with POR, SW reset or BOD */
+/*! @{ */
+#define SYSCON_CODESECURITYPROT_SEC_CODE_MASK    (0xFFFFFFFFU)
+#define SYSCON_CODESECURITYPROT_SEC_CODE_SHIFT   (0U)
+/*! SEC_CODE - Security code to allow debug via SWD and JTAG access in test mode. Write once
+ *    register, value 0x87654321 disables the access and therefore prevents any chance to enable it.
+ *    Writing any other value enables the access and locks the mode. In some cases the boot code will
+ *    secure the device by writing to this register to disable SWD and JTAG. This would prevent the
+ *    application being able to re-enable this access.
+ */
+#define SYSCON_CODESECURITYPROT_SEC_CODE(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_CODESECURITYPROT_SEC_CODE_SHIFT)) & SYSCON_CODESECURITYPROT_SEC_CODE_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group SYSCON_Register_Masks */
+
+
+/* SYSCON - Peripheral instance base addresses */
+/** Peripheral SYSCON base address */
+#define SYSCON_BASE                              (0x40000000u)
+/** Peripheral SYSCON base pointer */
+#define SYSCON                                   ((SYSCON_Type *)SYSCON_BASE)
+/** Array initializer of SYSCON peripheral base addresses */
+#define SYSCON_BASE_ADDRS                        { SYSCON_BASE }
+/** Array initializer of SYSCON peripheral base pointers */
+#define SYSCON_BASE_PTRS                         { SYSCON }
+
+/*!
+ * @}
+ */ /* end of group SYSCON_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- USART Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup USART_Peripheral_Access_Layer USART Peripheral Access Layer
+ * @{
+ */
+
+/** USART - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CFG;                               /**< USART Configuration register. Basic USART configuration settings that typically are not changed during operation., offset: 0x0 */
+  __IO uint32_t CTL;                               /**< USART Control register. USART control settings that are more likely to change during operation., offset: 0x4 */
+  __IO uint32_t STAT;                              /**< USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them., offset: 0x8 */
+  __IO uint32_t INTENSET;                          /**< Interrupt Enable read and Set register for USART (not FIFO) status. Contains individual interrupt enable bits for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0xC */
+  __O  uint32_t INTENCLR;                          /**< Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared., offset: 0x10 */
+       uint8_t RESERVED_0[12];
+  __IO uint32_t BRG;                               /**< Baud Rate Generator register. 16-bit integer baud rate divisor value., offset: 0x20 */
+  __I  uint32_t INTSTAT;                           /**< Interrupt status register. Reflects the status of interrupts that are currently enabled., offset: 0x24 */
+  __IO uint32_t OSR;                               /**< Oversample selection register for asynchronous communication., offset: 0x28 */
+  __IO uint32_t ADDR;                              /**< Address register for automatic address matching., offset: 0x2C */
+       uint8_t RESERVED_1[3536];
+  __IO uint32_t FIFOCFG;                           /**< FIFO configuration and enable register., offset: 0xE00 */
+  __IO uint32_t FIFOSTAT;                          /**< FIFO status register., offset: 0xE04 */
+  __IO uint32_t FIFOTRIG;                          /**< FIFO trigger settings for interrupt and DMA request., offset: 0xE08 */
+       uint8_t RESERVED_2[4];
+  __IO uint32_t FIFOINTENSET;                      /**< FIFO interrupt enable set (enable) and read register., offset: 0xE10 */
+  __O  uint32_t FIFOINTENCLR;                      /**< FIFO interrupt enable clear (disable) and read register., offset: 0xE14 */
+  __I  uint32_t FIFOINTSTAT;                       /**< FIFO interrupt status register. Reflects the status of interrupts that are currently enabled., offset: 0xE18 */
+       uint8_t RESERVED_3[4];
+  __O  uint32_t FIFOWR;                            /**< FIFO write data. Used to write values to be transmitted to the FIFO., offset: 0xE20 */
+       uint8_t RESERVED_4[12];
+  __I  uint32_t FIFORD;                            /**< FIFO read data. Used to read values that have been received., offset: 0xE30 */
+       uint8_t RESERVED_5[12];
+  __I  uint32_t FIFORDNOPOP;                       /**< FIFO data read with no FIFO pop. This register acts in exactly the same way as FIFORD, except that it supplies data from the top of the FIFO without popping the FIFO (i.e. leaving the FIFO state unchanged). This could be used to allow system software to observe incoming data without interfering with the peripheral driver., offset: 0xE40 */
+       uint8_t RESERVED_6[436];
+  __IO uint32_t PSELID;                            /**< Flexcomm ID and peripheral function select register, offset: 0xFF8 */
+  __I  uint32_t ID;                                /**< USART Module Identifier, offset: 0xFFC */
+} USART_Type;
+
+/* ----------------------------------------------------------------------------
+   -- USART Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup USART_Register_Masks USART Register Masks
+ * @{
+ */
+
+/*! @name CFG - USART Configuration register. Basic USART configuration settings that typically are not changed during operation. */
+/*! @{ */
+#define USART_CFG_ENABLE_MASK                    (0x1U)
+#define USART_CFG_ENABLE_SHIFT                   (0U)
+/*! ENABLE - USART Enable. 0: Disabled. The USART is disabled and the internal state machine and
+ *    counters are reset. While Enable = 0, all USART interrupts and DMA transfers are disabled. When
+ *    Enable is set again, CFG and most other control bits remain unchanged. When re-enabled, the
+ *    USART will immediately be ready to transmit because the transmitter has been reset and is
+ *    therefore available. 1: Eanbled. The USART is enabled for operation.
+ */
+#define USART_CFG_ENABLE(x)                      (((uint32_t)(((uint32_t)(x)) << USART_CFG_ENABLE_SHIFT)) & USART_CFG_ENABLE_MASK)
+#define USART_CFG_DATALEN_MASK                   (0xCU)
+#define USART_CFG_DATALEN_SHIFT                  (2U)
+/*! DATALEN - Selects the data size for the USART. 0: 7 bit Data Length; 1: 8 bit data length; 2: 9
+ *    bit data length. The 9th bit is commonly used for addressing in multidrop mode. See the
+ *    ADDRDET bit in the CTRL regsiter. 3: Reserved.
+ */
+#define USART_CFG_DATALEN(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_DATALEN_SHIFT)) & USART_CFG_DATALEN_MASK)
+#define USART_CFG_PARITYSEL_MASK                 (0x30U)
+#define USART_CFG_PARITYSEL_SHIFT                (4U)
+/*! PARITYSEL - Selects what type of parity is used by the USART. 0: No parity; 1: Reserved; 2: Even
+ *    Parity. Adds a bit to each character such that the number of 1s in a transmitted character is
+ *    even, and the number of 1s in a received character is expected to be even. 3: Odd parity.
+ *    Adds a bit to each character such that the number of 1s in a transmitted character is odd, and
+ *    the number of 1s in a received character is expected to be odd.
+ */
+#define USART_CFG_PARITYSEL(x)                   (((uint32_t)(((uint32_t)(x)) << USART_CFG_PARITYSEL_SHIFT)) & USART_CFG_PARITYSEL_MASK)
+#define USART_CFG_STOPLEN_MASK                   (0x40U)
+#define USART_CFG_STOPLEN_SHIFT                  (6U)
+/*! STOPLEN - Number of stop bits appended to transmitted data. Only a single stop bit is required
+ *    for received data. 0: 1 stop bit; 1: 2 stop bits. This setting should only be used for
+ *    asynchronous communication.
+ */
+#define USART_CFG_STOPLEN(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_STOPLEN_SHIFT)) & USART_CFG_STOPLEN_MASK)
+#define USART_CFG_MODE32K_MASK                   (0x80U)
+#define USART_CFG_MODE32K_SHIFT                  (7U)
+/*! MODE32K - Selects standard or 32 kHz clocking mode. 0: Disabled. USART uses standard clocking.
+ *    1: Enabled. USART uses the 32 kHz clock from the RTC oscillator as the clock source to the BRG,
+ *    and uses a special bit clocking scheme.
+ */
+#define USART_CFG_MODE32K(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_MODE32K_SHIFT)) & USART_CFG_MODE32K_MASK)
+#define USART_CFG_LINMODE_MASK                   (0x100U)
+#define USART_CFG_LINMODE_SHIFT                  (8U)
+/*! LINMODE - LIN bus break mode enable. 0: Disabled. Break detect and generate is configured for
+ *    normal operation. 1: Enabled. Break detect and generate is configured for LIN bus operation.
+ */
+#define USART_CFG_LINMODE(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_LINMODE_SHIFT)) & USART_CFG_LINMODE_MASK)
+#define USART_CFG_CTSEN_MASK                     (0x200U)
+#define USART_CFG_CTSEN_SHIFT                    (9U)
+/*! CTSEN - CTS Enable. Determines whether CTS is used for flow control. CTS can be from the input
+ *    pin, or from the USART s own RTS if loopback mode is enabled. 0 : No flow control. The
+ *    transmitter does not receive any automatic flow control signal. 1: Flow control enabled. The
+ *    transmitter uses the CTS input (or RTS output in loopback mode) for flow control purposes.
+ */
+#define USART_CFG_CTSEN(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_CTSEN_SHIFT)) & USART_CFG_CTSEN_MASK)
+#define USART_CFG_SYNCEN_MASK                    (0x800U)
+#define USART_CFG_SYNCEN_SHIFT                   (11U)
+/*! SYNCEN - Selects synchronous or asynchronous operation. 0: Asynchronous mode. 1: Synchronous mode.
+ */
+#define USART_CFG_SYNCEN(x)                      (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCEN_SHIFT)) & USART_CFG_SYNCEN_MASK)
+#define USART_CFG_CLKPOL_MASK                    (0x1000U)
+#define USART_CFG_CLKPOL_SHIFT                   (12U)
+/*! CLKPOL - Selects the clock polarity and sampling edge of received data in synchronous mode. 0:
+ *    Falling edge. Un_RXD is sampled on the falling edge of SCLK. 1: Rising edge. Un_RXD is sampled
+ *    on the rising edge of SCLK.
+ */
+#define USART_CFG_CLKPOL(x)                      (((uint32_t)(((uint32_t)(x)) << USART_CFG_CLKPOL_SHIFT)) & USART_CFG_CLKPOL_MASK)
+#define USART_CFG_SYNCMST_MASK                   (0x4000U)
+#define USART_CFG_SYNCMST_SHIFT                  (14U)
+/*! SYNCMST - Synchronous mode Master select. 0: Slave. When synchronous mode is enabled, the USART
+ *    is a slave. 1: Master. When synchronous mode is enabled, the USART is a master.
+ */
+#define USART_CFG_SYNCMST(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCMST_SHIFT)) & USART_CFG_SYNCMST_MASK)
+#define USART_CFG_LOOP_MASK                      (0x8000U)
+#define USART_CFG_LOOP_SHIFT                     (15U)
+/*! LOOP - Selects data loopback mode. 0: Normal operaetion. 1: Loopback mode. This provides a
+ *    mechanism to perform diagnostic loopback testing for USART data. Serial data from the transmitter
+ *    (Un_TXD) is connected internally to serial input of the receive (Un_RXD). Un_TXD and Un_RTS
+ *    activity will also appear on external pins if these functions are configured to appear on device
+ *    pins. The receiver RTS signal is also looped back to CTS and performs flow control if enabled
+ *    by CTSEN.
+ */
+#define USART_CFG_LOOP(x)                        (((uint32_t)(((uint32_t)(x)) << USART_CFG_LOOP_SHIFT)) & USART_CFG_LOOP_MASK)
+#define USART_CFG_OETA_MASK                      (0x40000U)
+#define USART_CFG_OETA_SHIFT                     (18U)
+/*! OETA - Output Enable Turnaround time enable for RS-485 operation. 0: Disabled. If selected by
+ *    OESEL, the Output Enable signal deasserted at the end of the last stop bit of a transmission. 1:
+ *    Enabled. If selected by OESEL, the Output Enable signal remains asserted for one character
+ *    time after the end of the last stop bit of a transmission. OE will also remain asserted if
+ *    another transmit begins before it is deasserted.
+ */
+#define USART_CFG_OETA(x)                        (((uint32_t)(((uint32_t)(x)) << USART_CFG_OETA_SHIFT)) & USART_CFG_OETA_MASK)
+#define USART_CFG_AUTOADDR_MASK                  (0x80000U)
+#define USART_CFG_AUTOADDR_SHIFT                 (19U)
+/*! AUTOADDR - Automatic Address matching enable. 0: Disabled. When addressing is enabled by
+ *    ADDRDET, address matching is done by software. This provides the possibility of versatile addressing
+ *    (e.g. respond to more than one address). 1: Enabled. When addressing is enabled by ADDRDET,
+ *    address matching is done by hardware, using the value in the ADDR register as the address to
+ *    match.
+ */
+#define USART_CFG_AUTOADDR(x)                    (((uint32_t)(((uint32_t)(x)) << USART_CFG_AUTOADDR_SHIFT)) & USART_CFG_AUTOADDR_MASK)
+#define USART_CFG_OESEL_MASK                     (0x100000U)
+#define USART_CFG_OESEL_SHIFT                    (20U)
+/*! OESEL - Output Enable Select. 0: Standard. The RTS signal is used as the standard flow control
+ *    function. 1: RS-485. The RTS signal configured to provide an output enable signal to control an
+ *    RS-485 transceiver.
+ */
+#define USART_CFG_OESEL(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_OESEL_SHIFT)) & USART_CFG_OESEL_MASK)
+#define USART_CFG_OEPOL_MASK                     (0x200000U)
+#define USART_CFG_OEPOL_SHIFT                    (21U)
+/*! OEPOL - Output Enable Polarity. 0: Low. If selected by OESEL, the output enable is active low.
+ *    1: High. If selected by OESEL, the output enable is active high.
+ */
+#define USART_CFG_OEPOL(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_OEPOL_SHIFT)) & USART_CFG_OEPOL_MASK)
+#define USART_CFG_RXPOL_MASK                     (0x400000U)
+#define USART_CFG_RXPOL_SHIFT                    (22U)
+/*! RXPOL - Receive data polarity. 0: Standard. The RX signal is used as it arrives from the pin.
+ *    This means that the RX rest value is 1, start bit is 0, data is not inverted, and the stop bit
+ *    is 1. 1: Inverted. The RX signal is inverted before being used by the USART. This means that
+ *    the RX rest value is 0, start bit is 1, data is inverted, and the stop bit is 0.
+ */
+#define USART_CFG_RXPOL(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_RXPOL_SHIFT)) & USART_CFG_RXPOL_MASK)
+#define USART_CFG_TXPOL_MASK                     (0x800000U)
+#define USART_CFG_TXPOL_SHIFT                    (23U)
+/*! TXPOL - Transmit data polarity. 0: Standard. The TX signal is sent out without change. This
+ *    means that the TX rest value is 1, start bit is 0, data is not inverted, and the stop bit is 1. 1:
+ *    Inverted. The TX signal is inverted by the USART before being sent out. This means that the
+ *    TX rest value is 0, start bit is 1, data is inverted, and the stop bit is 0.
+ */
+#define USART_CFG_TXPOL(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_TXPOL_SHIFT)) & USART_CFG_TXPOL_MASK)
+/*! @} */
+
+/*! @name CTL - USART Control register. USART control settings that are more likely to change during operation. */
+/*! @{ */
+#define USART_CTL_TXBRKEN_MASK                   (0x2U)
+#define USART_CTL_TXBRKEN_SHIFT                  (1U)
+/*! TXBRKEN - Break Enable. 0: Normal Operation. 1: Continuous break. Continuous break is sent
+ *    immediately when this bit is set, and remains until this bit is cleared. A break may be sent
+ *    without danger of corrupting any currently transmitting character if the transmitter is first
+ *    disabled (TXDIS in CTL is set) and then waiting for the transmitter to be disabled (TXDISINT in STAT
+ *    = 1) before writing 1 to TXBRKEN.
+ */
+#define USART_CTL_TXBRKEN(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXBRKEN_SHIFT)) & USART_CTL_TXBRKEN_MASK)
+#define USART_CTL_ADDRDET_MASK                   (0x4U)
+#define USART_CTL_ADDRDET_SHIFT                  (2U)
+/*! ADDRDET - Enable address detect mode. 0: Disabled. The USART presents all incoming data. 1:
+ *    Enabled. The USART receiver ignores incoming data that does not have the most significant bit of
+ *    the data (typically the 9th bit) = 1. When the data MSB bit = 1, the receiver treats the
+ *    incoming data normally, generating a received data interrupt. Software can then check the data to
+ *    see if this is an address that should be handled. If it is, the ADDRDET bit is cleared by
+ *    software and further incoming data is handled normally.
+ */
+#define USART_CTL_ADDRDET(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CTL_ADDRDET_SHIFT)) & USART_CTL_ADDRDET_MASK)
+#define USART_CTL_TXDIS_MASK                     (0x40U)
+#define USART_CTL_TXDIS_SHIFT                    (6U)
+/*! TXDIS - Transmit Disable. 0: Not disabled. USART transmitter is not disabled. 1: Disabled. USART
+ *    transmitter is disabled after any character currently being transmitted is complete. This
+ *    feature can be used to facilitate software flow control.
+ */
+#define USART_CTL_TXDIS(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXDIS_SHIFT)) & USART_CTL_TXDIS_MASK)
+#define USART_CTL_CC_MASK                        (0x100U)
+#define USART_CTL_CC_SHIFT                       (8U)
+/*! CC - Continuous Clock generation. By default, SCLK is only output while data is being
+ *    transmitted in synchronous mode. 0: Clock on character. In synchronous mode, SCLK cycles only when
+ *    characters are being sent on Un_TXD or to complete a character that is being received. 1:
+ *    Continuous clock. SCLK runs continuously in synchronous mode, allowing characters to be received on
+ *    Un_RxD independently from transmission on Un_TXD).
+ */
+#define USART_CTL_CC(x)                          (((uint32_t)(((uint32_t)(x)) << USART_CTL_CC_SHIFT)) & USART_CTL_CC_MASK)
+#define USART_CTL_CLRCCONRX_MASK                 (0x200U)
+#define USART_CTL_CLRCCONRX_SHIFT                (9U)
+/*! CLRCCONRX - Clear Continuous Clock. 0: No effect. No effect on the CC bit. 1: Auto-clear. The CC
+ *    bit is automatically cleared when a complete character has been received. This bit is cleared
+ *    at the same time.
+ */
+#define USART_CTL_CLRCCONRX(x)                   (((uint32_t)(((uint32_t)(x)) << USART_CTL_CLRCCONRX_SHIFT)) & USART_CTL_CLRCCONRX_MASK)
+#define USART_CTL_AUTOBAUD_MASK                  (0x10000U)
+#define USART_CTL_AUTOBAUD_SHIFT                 (16U)
+/*! AUTOBAUD - Autobaud enable. 0: Disabled. USART is in normal operating mode. 1: Enabled. USART is
+ *    in auto-baud mode. This bit should only be set when the USART receiver is idle. The first
+ *    start bit of RX is measured and used the update the BRG register to match the received data rate.
+ *    AUTOBAUD is cleared once this process is complete, or if there is an AERR.
+ */
+#define USART_CTL_AUTOBAUD(x)                    (((uint32_t)(((uint32_t)(x)) << USART_CTL_AUTOBAUD_SHIFT)) & USART_CTL_AUTOBAUD_MASK)
+/*! @} */
+
+/*! @name STAT - USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them. */
+/*! @{ */
+#define USART_STAT_RXIDLE_MASK                   (0x2U)
+#define USART_STAT_RXIDLE_SHIFT                  (1U)
+/*! RXIDLE - Receiver Idle. When 0, indicates that the receiver is currently in the process of
+ *    receiving data. When 1, indicates that the receiver is not currently in the process of receiving
+ *    data.
+ */
+#define USART_STAT_RXIDLE(x)                     (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXIDLE_SHIFT)) & USART_STAT_RXIDLE_MASK)
+#define USART_STAT_TXIDLE_MASK                   (0x8U)
+#define USART_STAT_TXIDLE_SHIFT                  (3U)
+/*! TXIDLE - Transmitter Idle. When 0, indicates that the transmitter is currently in the process of
+ *    sending data.When 1, indicate that the transmitter is not currently in the process of sending
+ *    data.
+ */
+#define USART_STAT_TXIDLE(x)                     (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXIDLE_SHIFT)) & USART_STAT_TXIDLE_MASK)
+#define USART_STAT_CTS_MASK                      (0x10U)
+#define USART_STAT_CTS_SHIFT                     (4U)
+/*! CTS - This bit reflects the current state of the CTS signal, regardless of the setting of the
+ *    CTSEN bit in the CFG register. This will be the value of the CTS input pin unless loopback mode
+ *    is enabled. Hence, reset value not applicable.
+ */
+#define USART_STAT_CTS(x)                        (((uint32_t)(((uint32_t)(x)) << USART_STAT_CTS_SHIFT)) & USART_STAT_CTS_MASK)
+#define USART_STAT_DELTACTS_MASK                 (0x20U)
+#define USART_STAT_DELTACTS_SHIFT                (5U)
+/*! DELTACTS - This bit is set when a change in the state is detected for the CTS flag above. This bit is cleared by software.
+ */
+#define USART_STAT_DELTACTS(x)                   (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTACTS_SHIFT)) & USART_STAT_DELTACTS_MASK)
+#define USART_STAT_TXDISSTAT_MASK                (0x40U)
+#define USART_STAT_TXDISSTAT_SHIFT               (6U)
+/*! TXDISSTAT - Transmitter Disabled Status flag. When 1, this bit indicates that the USART
+ *    transmitter is fully idle after being disabled via the TXDIS bit in the CFG register (TXDIS = 1).
+ */
+#define USART_STAT_TXDISSTAT(x)                  (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXDISSTAT_SHIFT)) & USART_STAT_TXDISSTAT_MASK)
+#define USART_STAT_RXBRK_MASK                    (0x400U)
+#define USART_STAT_RXBRK_SHIFT                   (10U)
+/*! RXBRK - Received Break. This bit reflects the current state of the receiver break detection
+ *    logic. It is set when the Un_RXD pin remains low for 16 bit times. Note that FRAMERRINT will also
+ *    be set when this condition occurs because the stop bit(s) for the character would be missing.
+ *    RXBRK is cleared when the Un_RXD pin goes high.
+ */
+#define USART_STAT_RXBRK(x)                      (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXBRK_SHIFT)) & USART_STAT_RXBRK_MASK)
+#define USART_STAT_DELTARXBRK_MASK               (0x800U)
+#define USART_STAT_DELTARXBRK_SHIFT              (11U)
+/*! DELTARXBRK - This bit is set when a change in the state of receiver break detection occurs. Cleared by software.
+ */
+#define USART_STAT_DELTARXBRK(x)                 (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTARXBRK_SHIFT)) & USART_STAT_DELTARXBRK_MASK)
+#define USART_STAT_START_MASK                    (0x1000U)
+#define USART_STAT_START_SHIFT                   (12U)
+/*! START - This bit is set when a start is detected on the receiver input. Its purpose is primarily
+ *    to allow wake-up from Deep sleep or Power-down mode immediately when a start is detected.
+ *    Cleared by software.
+ */
+#define USART_STAT_START(x)                      (((uint32_t)(((uint32_t)(x)) << USART_STAT_START_SHIFT)) & USART_STAT_START_MASK)
+#define USART_STAT_FRAMERRINT_MASK               (0x2000U)
+#define USART_STAT_FRAMERRINT_SHIFT              (13U)
+/*! FRAMERRINT - Framing Error interrupt flag. This flag is set when a character is received with a
+ *    missing stop bit at the expected location. This could be an indication of a baud rate or
+ *    configuration mismatch with the transmitting source.
+ */
+#define USART_STAT_FRAMERRINT(x)                 (((uint32_t)(((uint32_t)(x)) << USART_STAT_FRAMERRINT_SHIFT)) & USART_STAT_FRAMERRINT_MASK)
+#define USART_STAT_PARITYERRINT_MASK             (0x4000U)
+#define USART_STAT_PARITYERRINT_SHIFT            (14U)
+/*! PARITYERRINT - Parity Error interrupt flag. This flag is set when a parity error is detected in a received character.
+ */
+#define USART_STAT_PARITYERRINT(x)               (((uint32_t)(((uint32_t)(x)) << USART_STAT_PARITYERRINT_SHIFT)) & USART_STAT_PARITYERRINT_MASK)
+#define USART_STAT_RXNOISEINT_MASK               (0x8000U)
+#define USART_STAT_RXNOISEINT_SHIFT              (15U)
+/*! RXNOISEINT - Received Noise interrupt flag. Three samples of received data are taken in order to
+ *    determine the value of each received data bit, except in synchronous mode. This acts as a
+ *    noise filter if one sample disagrees. This flag is set when a received data bit contains one
+ *    disagreeing sample. This could indicate line noise, a baud rate or character format mismatch, or
+ *    loss of synchronization during data reception.
+ */
+#define USART_STAT_RXNOISEINT(x)                 (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXNOISEINT_SHIFT)) & USART_STAT_RXNOISEINT_MASK)
+#define USART_STAT_ABERR_MASK                    (0x10000U)
+#define USART_STAT_ABERR_SHIFT                   (16U)
+/*! ABERR - Auto baud Error. An auto baud error can occur if the BRG counts to its limit before the
+ *    end of the start bit that is being measured, essentially an auto baud time-out.
+ */
+#define USART_STAT_ABERR(x)                      (((uint32_t)(((uint32_t)(x)) << USART_STAT_ABERR_SHIFT)) & USART_STAT_ABERR_MASK)
+/*! @} */
+
+/*! @name INTENSET - Interrupt Enable read and Set register for USART (not FIFO) status. Contains individual interrupt enable bits for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */
+/*! @{ */
+#define USART_INTENSET_RXRDYEN_MASK              (0x1U)
+#define USART_INTENSET_RXRDYEN_SHIFT             (0U)
+/*! RXRDYEN - When 1, enables an interrupt when RX becomes ready
+ */
+#define USART_INTENSET_RXRDYEN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXRDYEN_SHIFT)) & USART_INTENSET_RXRDYEN_MASK)
+#define USART_INTENSET_TXRDTEN_MASK              (0x4U)
+#define USART_INTENSET_TXRDTEN_SHIFT             (2U)
+/*! TXRDTEN - When 1, enables an interrupt when TX becomes ready
+ */
+#define USART_INTENSET_TXRDTEN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXRDTEN_SHIFT)) & USART_INTENSET_TXRDTEN_MASK)
+#define USART_INTENSET_TXIDLEEN_MASK             (0x8U)
+#define USART_INTENSET_TXIDLEEN_SHIFT            (3U)
+/*! TXIDLEEN - When 1, enables an interrupt when the transmitter becomes idle (TXIDLE = 1).
+ */
+#define USART_INTENSET_TXIDLEEN(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXIDLEEN_SHIFT)) & USART_INTENSET_TXIDLEEN_MASK)
+#define USART_INTENSET_DELTACTSEN_MASK           (0x20U)
+#define USART_INTENSET_DELTACTSEN_SHIFT          (5U)
+/*! DELTACTSEN - Transmitter Idle. When 0, indicates that the transmitter is currently in the
+ *    process of sending data.When 1, indicate that the transmitter is not currently in the process of
+ *    sending data.
+ */
+#define USART_INTENSET_DELTACTSEN(x)             (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTACTSEN_SHIFT)) & USART_INTENSET_DELTACTSEN_MASK)
+#define USART_INTENSET_TXDISEN_MASK              (0x40U)
+#define USART_INTENSET_TXDISEN_SHIFT             (6U)
+/*! TXDISEN - When 1, enables an interrupt when the transmitter is fully disabled as indicated by
+ *    the TXDISINT flag in STAT. See description of the TXDISINT bit for details.
+ */
+#define USART_INTENSET_TXDISEN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXDISEN_SHIFT)) & USART_INTENSET_TXDISEN_MASK)
+#define USART_INTENSET_DELTARXBRKEN_MASK         (0x800U)
+#define USART_INTENSET_DELTARXBRKEN_SHIFT        (11U)
+/*! DELTARXBRKEN - When 1, enables an interrupt when a change of state has occurred in the detection
+ *    of a received break condition (break condition asserted or deasserted).
+ */
+#define USART_INTENSET_DELTARXBRKEN(x)           (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTARXBRKEN_SHIFT)) & USART_INTENSET_DELTARXBRKEN_MASK)
+#define USART_INTENSET_STARTEN_MASK              (0x1000U)
+#define USART_INTENSET_STARTEN_SHIFT             (12U)
+/*! STARTEN - When 1, enables an interrupt when a received start bit has been detected.
+ */
+#define USART_INTENSET_STARTEN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_STARTEN_SHIFT)) & USART_INTENSET_STARTEN_MASK)
+#define USART_INTENSET_FRAMERREN_MASK            (0x2000U)
+#define USART_INTENSET_FRAMERREN_SHIFT           (13U)
+/*! FRAMERREN - When 1, enables an interrupt when a framing error has been detected.
+ */
+#define USART_INTENSET_FRAMERREN(x)              (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_FRAMERREN_SHIFT)) & USART_INTENSET_FRAMERREN_MASK)
+#define USART_INTENSET_PARITYERREN_MASK          (0x4000U)
+#define USART_INTENSET_PARITYERREN_SHIFT         (14U)
+/*! PARITYERREN - When 1, enables an interrupt when a parity error has been detected.
+ */
+#define USART_INTENSET_PARITYERREN(x)            (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_PARITYERREN_SHIFT)) & USART_INTENSET_PARITYERREN_MASK)
+#define USART_INTENSET_RXNOISEEN_MASK            (0x8000U)
+#define USART_INTENSET_RXNOISEEN_SHIFT           (15U)
+/*! RXNOISEEN - When 1, enables an interrupt when noise is detected.
+ */
+#define USART_INTENSET_RXNOISEEN(x)              (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXNOISEEN_SHIFT)) & USART_INTENSET_RXNOISEEN_MASK)
+#define USART_INTENSET_ABERREN_MASK              (0x10000U)
+#define USART_INTENSET_ABERREN_SHIFT             (16U)
+/*! ABERREN - When 1, enables an interrupt when an auto baud error occurs.
+ */
+#define USART_INTENSET_ABERREN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_ABERREN_SHIFT)) & USART_INTENSET_ABERREN_MASK)
+/*! @} */
+
+/*! @name INTENCLR - Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared. */
+/*! @{ */
+#define USART_INTENCLR_RXRDYCLR_MASK             (0x1U)
+#define USART_INTENCLR_RXRDYCLR_SHIFT            (0U)
+/*! RXRDYCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_RXRDYCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXRDYCLR_SHIFT)) & USART_INTENCLR_RXRDYCLR_MASK)
+#define USART_INTENCLR_TXRDYCLR_MASK             (0x4U)
+#define USART_INTENCLR_TXRDYCLR_SHIFT            (2U)
+/*! TXRDYCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_TXRDYCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXRDYCLR_SHIFT)) & USART_INTENCLR_TXRDYCLR_MASK)
+#define USART_INTENCLR_TXIDLECLR_MASK            (0x8U)
+#define USART_INTENCLR_TXIDLECLR_SHIFT           (3U)
+/*! TXIDLECLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_TXIDLECLR(x)              (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXIDLECLR_SHIFT)) & USART_INTENCLR_TXIDLECLR_MASK)
+#define USART_INTENCLR_DELTACTSCLR_MASK          (0x20U)
+#define USART_INTENCLR_DELTACTSCLR_SHIFT         (5U)
+/*! DELTACTSCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_DELTACTSCLR(x)            (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTACTSCLR_SHIFT)) & USART_INTENCLR_DELTACTSCLR_MASK)
+#define USART_INTENCLR_TXDISCLR_MASK             (0x40U)
+#define USART_INTENCLR_TXDISCLR_SHIFT            (6U)
+/*! TXDISCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_TXDISCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXDISCLR_SHIFT)) & USART_INTENCLR_TXDISCLR_MASK)
+#define USART_INTENCLR_DELTARXBRKCLR_MASK        (0x800U)
+#define USART_INTENCLR_DELTARXBRKCLR_SHIFT       (11U)
+/*! DELTARXBRKCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_DELTARXBRKCLR(x)          (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTARXBRKCLR_SHIFT)) & USART_INTENCLR_DELTARXBRKCLR_MASK)
+#define USART_INTENCLR_STARTCLR_MASK             (0x1000U)
+#define USART_INTENCLR_STARTCLR_SHIFT            (12U)
+/*! STARTCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_STARTCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_STARTCLR_SHIFT)) & USART_INTENCLR_STARTCLR_MASK)
+#define USART_INTENCLR_FRAMERRCLR_MASK           (0x2000U)
+#define USART_INTENCLR_FRAMERRCLR_SHIFT          (13U)
+/*! FRAMERRCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_FRAMERRCLR(x)             (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_FRAMERRCLR_SHIFT)) & USART_INTENCLR_FRAMERRCLR_MASK)
+#define USART_INTENCLR_PARITYERRCLR_MASK         (0x4000U)
+#define USART_INTENCLR_PARITYERRCLR_SHIFT        (14U)
+/*! PARITYERRCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_PARITYERRCLR(x)           (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_PARITYERRCLR_SHIFT)) & USART_INTENCLR_PARITYERRCLR_MASK)
+#define USART_INTENCLR_RXNOISECLR_MASK           (0x8000U)
+#define USART_INTENCLR_RXNOISECLR_SHIFT          (15U)
+/*! RXNOISECLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_RXNOISECLR(x)             (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXNOISECLR_SHIFT)) & USART_INTENCLR_RXNOISECLR_MASK)
+#define USART_INTENCLR_ABERRCLR_MASK             (0x10000U)
+#define USART_INTENCLR_ABERRCLR_SHIFT            (16U)
+/*! ABERRCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_ABERRCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_ABERRCLR_SHIFT)) & USART_INTENCLR_ABERRCLR_MASK)
+/*! @} */
+
+/*! @name BRG - Baud Rate Generator register. 16-bit integer baud rate divisor value. */
+/*! @{ */
+#define USART_BRG_BRGVAL_MASK                    (0xFFFFU)
+#define USART_BRG_BRGVAL_SHIFT                   (0U)
+/*! BRGVAL - This value is used to divide the USART input clock to determine the baud rate, based on
+ *    the input clock from the FRG. 0: FCLK is used directly by the USART function. 1: FCLK is
+ *    divided by 2 before use by the USART function. 2: FCLK is divided by 3 before use by the USART
+ *    function. ... 0xFFFF = FCLK is divided by 65,536 before use by the USART function.
+ */
+#define USART_BRG_BRGVAL(x)                      (((uint32_t)(((uint32_t)(x)) << USART_BRG_BRGVAL_SHIFT)) & USART_BRG_BRGVAL_MASK)
+/*! @} */
+
+/*! @name INTSTAT - Interrupt status register. Reflects the status of interrupts that are currently enabled. */
+/*! @{ */
+#define USART_INTSTAT_RX_RDY_MASK                (0x1U)
+#define USART_INTSTAT_RX_RDY_SHIFT               (0U)
+/*! RX_RDY - Receiver Ready Status
+ */
+#define USART_INTSTAT_RX_RDY(x)                  (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RX_RDY_SHIFT)) & USART_INTSTAT_RX_RDY_MASK)
+#define USART_INTSTAT_RXIDLE_MASK                (0x2U)
+#define USART_INTSTAT_RXIDLE_SHIFT               (1U)
+/*! RXIDLE - Receiver Idle Status
+ */
+#define USART_INTSTAT_RXIDLE(x)                  (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXIDLE_SHIFT)) & USART_INTSTAT_RXIDLE_MASK)
+#define USART_INTSTAT_TX_RDY_MASK                (0x4U)
+#define USART_INTSTAT_TX_RDY_SHIFT               (2U)
+/*! TX_RDY - Transmitter Ready Status
+ */
+#define USART_INTSTAT_TX_RDY(x)                  (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TX_RDY_SHIFT)) & USART_INTSTAT_TX_RDY_MASK)
+#define USART_INTSTAT_TXIDLE_MASK                (0x8U)
+#define USART_INTSTAT_TXIDLE_SHIFT               (3U)
+/*! TXIDLE - Transmitter Idle status.
+ */
+#define USART_INTSTAT_TXIDLE(x)                  (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXIDLE_SHIFT)) & USART_INTSTAT_TXIDLE_MASK)
+#define USART_INTSTAT_DELTACTS_MASK              (0x20U)
+#define USART_INTSTAT_DELTACTS_SHIFT             (5U)
+/*! DELTACTS - This bit is set when a change in the state of the CTS input is detected.
+ */
+#define USART_INTSTAT_DELTACTS(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTACTS_SHIFT)) & USART_INTSTAT_DELTACTS_MASK)
+#define USART_INTSTAT_TXDIS_MASK                 (0x40U)
+#define USART_INTSTAT_TXDIS_SHIFT                (6U)
+/*! TXDIS - Transmitter Disabled Interrupt flag.
+ */
+#define USART_INTSTAT_TXDIS(x)                   (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXDIS_SHIFT)) & USART_INTSTAT_TXDIS_MASK)
+#define USART_INTSTAT_DELTARXBRK_MASK            (0x800U)
+#define USART_INTSTAT_DELTARXBRK_SHIFT           (11U)
+/*! DELTARXBRK - This bit is set when a change in the state of receiver break detection occurs.
+ */
+#define USART_INTSTAT_DELTARXBRK(x)              (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTARXBRK_SHIFT)) & USART_INTSTAT_DELTARXBRK_MASK)
+#define USART_INTSTAT_START_MASK                 (0x1000U)
+#define USART_INTSTAT_START_SHIFT                (12U)
+/*! START - This bit is set when a start is detected on the receiver input.
+ */
+#define USART_INTSTAT_START(x)                   (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_START_SHIFT)) & USART_INTSTAT_START_MASK)
+#define USART_INTSTAT_FRAMERR_MASK               (0x2000U)
+#define USART_INTSTAT_FRAMERR_SHIFT              (13U)
+/*! FRAMERR - Framing Error interrupt flag.
+ */
+#define USART_INTSTAT_FRAMERR(x)                 (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_FRAMERR_SHIFT)) & USART_INTSTAT_FRAMERR_MASK)
+#define USART_INTSTAT_PARITYERR_MASK             (0x4000U)
+#define USART_INTSTAT_PARITYERR_SHIFT            (14U)
+/*! PARITYERR - Parity Error interrupt flag.
+ */
+#define USART_INTSTAT_PARITYERR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_PARITYERR_SHIFT)) & USART_INTSTAT_PARITYERR_MASK)
+#define USART_INTSTAT_RXNOISE_MASK               (0x8000U)
+#define USART_INTSTAT_RXNOISE_SHIFT              (15U)
+/*! RXNOISE - Received Noise interrupt flag.
+ */
+#define USART_INTSTAT_RXNOISE(x)                 (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXNOISE_SHIFT)) & USART_INTSTAT_RXNOISE_MASK)
+#define USART_INTSTAT_ABERR_MASK                 (0x10000U)
+#define USART_INTSTAT_ABERR_SHIFT                (16U)
+/*! ABERR - Auto baud Error Interrupt flag.
+ */
+#define USART_INTSTAT_ABERR(x)                   (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_ABERR_SHIFT)) & USART_INTSTAT_ABERR_MASK)
+/*! @} */
+
+/*! @name OSR - Oversample selection register for asynchronous communication. */
+/*! @{ */
+#define USART_OSR_OSRVAL_MASK                    (0xFU)
+#define USART_OSR_OSRVAL_SHIFT                   (0U)
+/*! OSRVAL - Oversample Selection Value. 0 to 3: not supported. 0x4: 5 function clocks are used to
+ *    transmit and receive each data bit. 0x5: 6 function clocks are used to transmit and receive
+ *    each data bit. ... 0xF: 16 function clocks are used to transmit and receive each data bit.
+ */
+#define USART_OSR_OSRVAL(x)                      (((uint32_t)(((uint32_t)(x)) << USART_OSR_OSRVAL_SHIFT)) & USART_OSR_OSRVAL_MASK)
+/*! @} */
+
+/*! @name ADDR - Address register for automatic address matching. */
+/*! @{ */
+#define USART_ADDR_ADDRESS_MASK                  (0xFFU)
+#define USART_ADDR_ADDRESS_SHIFT                 (0U)
+/*! ADDRESS - 8-bit address used with automatic address matching. Used when address detection is
+ *    enabled (ADDRDET in CTL = 1) and automatic address matching is enabled (AUTOADDR in CFG = 1).
+ */
+#define USART_ADDR_ADDRESS(x)                    (((uint32_t)(((uint32_t)(x)) << USART_ADDR_ADDRESS_SHIFT)) & USART_ADDR_ADDRESS_MASK)
+/*! @} */
+
+/*! @name FIFOCFG - FIFO configuration and enable register. */
+/*! @{ */
+#define USART_FIFOCFG_ENABLETX_MASK              (0x1U)
+#define USART_FIFOCFG_ENABLETX_SHIFT             (0U)
+/*! ENABLETX - Enable the transmit FIFO. 0: The transmit FIFO is not enabled. 1: The transmit FIFO
+ *    is enabled. This is automatically enabled when PSELID.PERSEL is set to 1 to configure the USART
+ *    functionality.
+ */
+#define USART_FIFOCFG_ENABLETX(x)                (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_ENABLETX_SHIFT)) & USART_FIFOCFG_ENABLETX_MASK)
+#define USART_FIFOCFG_ENABLERX_MASK              (0x2U)
+#define USART_FIFOCFG_ENABLERX_SHIFT             (1U)
+/*! ENABLERX - Enable the receive FIFO. 0: The receive FIFO is not enabled. 1: The receive FIFO is
+ *    enabled. This is automatically enabled when PSELID.PERSEL is set to 1 to configure the USART
+ *    functionality.
+ */
+#define USART_FIFOCFG_ENABLERX(x)                (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_ENABLERX_SHIFT)) & USART_FIFOCFG_ENABLERX_MASK)
+#define USART_FIFOCFG_SIZE_MASK                  (0x30U)
+#define USART_FIFOCFG_SIZE_SHIFT                 (4U)
+/*! SIZE - FIFO size configuration. This is a read-only field. 0x0 = FIFO is configured as 4 entries
+ *    of 8 bits. 0x1, 0x2, 0x3 = not applicable.
+ */
+#define USART_FIFOCFG_SIZE(x)                    (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_SIZE_SHIFT)) & USART_FIFOCFG_SIZE_MASK)
+#define USART_FIFOCFG_DMATX_MASK                 (0x1000U)
+#define USART_FIFOCFG_DMATX_SHIFT                (12U)
+/*! DMATX - DMA configuration for transmit. 0: DMA is not used for the transmit function. 1:
+ *    Generate a DMA request for the transmit function if the FIFO is not full. Generally, data interrupts
+ *    would be disabled if DMA is enabled
+ */
+#define USART_FIFOCFG_DMATX(x)                   (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_DMATX_SHIFT)) & USART_FIFOCFG_DMATX_MASK)
+#define USART_FIFOCFG_DMARX_MASK                 (0x2000U)
+#define USART_FIFOCFG_DMARX_SHIFT                (13U)
+/*! DMARX - DMA configuration for receive. 0: DMA is not used for the receive function. 1: Generate
+ *    a DMA request for the receive function if the FIFO is not empty. Generally, data interrupts
+ *    would be disabled if DMA is enabled.
+ */
+#define USART_FIFOCFG_DMARX(x)                   (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_DMARX_SHIFT)) & USART_FIFOCFG_DMARX_MASK)
+#define USART_FIFOCFG_WAKETX_MASK                (0x4000U)
+#define USART_FIFOCFG_WAKETX_SHIFT               (14U)
+/*! WAKETX - Wakeup for transmit FIFO level. This allows the device to be woken from reduced power
+ *    modes (up to power-down, as long as the peripheral function works in that power mode) without
+ *    enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The
+ *    CPU will remain stopped until woken by another cause, such as DMA completion. 0: Only enabled
+ *    interrupts will wake up the device form reduced power modes. 1: A device wake-up for DMA will
+ *    occur if the transmit FIFO level reaches the value specified by TXLVL in FIFOTRIG, even when the
+ *    TXLVL interrupt is not enabled.
+ */
+#define USART_FIFOCFG_WAKETX(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_WAKETX_SHIFT)) & USART_FIFOCFG_WAKETX_MASK)
+#define USART_FIFOCFG_WAKERX_MASK                (0x8000U)
+#define USART_FIFOCFG_WAKERX_SHIFT               (15U)
+/*! WAKERX - Wakeup for receive FIFO level. This allows the device to be woken from reduced power
+ *    modes (up to power-down, as long as the peripheral function works in that power mode) without
+ *    enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The CPU
+ *    will remain stopped until woken by another cause, such as DMA completion. 0: Only enabled
+ *    interrupts will wake up the device form reduced power modes. 1: A device wake-up for DMA will
+ *    occur if the receive FIFO level reaches the value specified by RXLVL in FIFOTRIG, even when the
+ *    RXLVL interrupt is not enabled.
+ */
+#define USART_FIFOCFG_WAKERX(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_WAKERX_SHIFT)) & USART_FIFOCFG_WAKERX_MASK)
+#define USART_FIFOCFG_EMPTYTX_MASK               (0x10000U)
+#define USART_FIFOCFG_EMPTYTX_SHIFT              (16U)
+/*! EMPTYTX - Empty command for the transmit FIFO. When a 1 is written to this bit, the TX FIFO is emptied.
+ */
+#define USART_FIFOCFG_EMPTYTX(x)                 (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_EMPTYTX_SHIFT)) & USART_FIFOCFG_EMPTYTX_MASK)
+#define USART_FIFOCFG_EMPTYRX_MASK               (0x20000U)
+#define USART_FIFOCFG_EMPTYRX_SHIFT              (17U)
+/*! EMPTYRX - Empty command for the receive FIFO. When a 1 is written to this bit, the RX FIFO is emptied.
+ */
+#define USART_FIFOCFG_EMPTYRX(x)                 (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_EMPTYRX_SHIFT)) & USART_FIFOCFG_EMPTYRX_MASK)
+#define USART_FIFOCFG_POPDBG_MASK                (0x40000U)
+#define USART_FIFOCFG_POPDBG_SHIFT               (18U)
+/*! POPDBG - Pop FIFO for debug reads.
+ */
+#define USART_FIFOCFG_POPDBG(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_POPDBG_SHIFT)) & USART_FIFOCFG_POPDBG_MASK)
+/*! @} */
+
+/*! @name FIFOSTAT - FIFO status register. */
+/*! @{ */
+#define USART_FIFOSTAT_TXERR_MASK                (0x1U)
+#define USART_FIFOSTAT_TXERR_SHIFT               (0U)
+/*! TXERR - TX FIFO error. Will be set if a transmit FIFO error occurs. This could be an overflow
+ *    caused by pushing data into a full FIFO, or by an underflow if the FIFO is empty when data is
+ *    needed. Cleared by writing a 1 to this bit.
+ */
+#define USART_FIFOSTAT_TXERR(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXERR_SHIFT)) & USART_FIFOSTAT_TXERR_MASK)
+#define USART_FIFOSTAT_RXERR_MASK                (0x2U)
+#define USART_FIFOSTAT_RXERR_SHIFT               (1U)
+/*! RXERR - RX FIFO error. Will be set if a receive FIFO overflow occurs, caused by software or DMA
+ *    not emptying the FIFO fast enough. Cleared by writing a 1 to this bit.
+ */
+#define USART_FIFOSTAT_RXERR(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXERR_SHIFT)) & USART_FIFOSTAT_RXERR_MASK)
+#define USART_FIFOSTAT_PERINT_MASK               (0x8U)
+#define USART_FIFOSTAT_PERINT_SHIFT              (3U)
+/*! PERINT - Peripheral interrupt. When 1, this indicates that the peripheral function has asserted
+ *    an interrupt. The details can be found by reading the peripheral s STAT register.
+ */
+#define USART_FIFOSTAT_PERINT(x)                 (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_PERINT_SHIFT)) & USART_FIFOSTAT_PERINT_MASK)
+#define USART_FIFOSTAT_TXEMPTY_MASK              (0x10U)
+#define USART_FIFOSTAT_TXEMPTY_SHIFT             (4U)
+/*! TXEMPTY - Transmit FIFO empty. When 1, the transmit FIFO is empty. The peripheral may still be processing the last piece of data.
+ */
+#define USART_FIFOSTAT_TXEMPTY(x)                (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXEMPTY_SHIFT)) & USART_FIFOSTAT_TXEMPTY_MASK)
+#define USART_FIFOSTAT_TXNOTFULL_MASK            (0x20U)
+#define USART_FIFOSTAT_TXNOTFULL_SHIFT           (5U)
+/*! TXNOTFULL - Transmit FIFO not full. When 1, the transmit FIFO is not full, so more data can be
+ *    written. When 0, the transmit FIFO is full and another write would cause it to overflow.
+ */
+#define USART_FIFOSTAT_TXNOTFULL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXNOTFULL_SHIFT)) & USART_FIFOSTAT_TXNOTFULL_MASK)
+#define USART_FIFOSTAT_RXNOTEMPTY_MASK           (0x40U)
+#define USART_FIFOSTAT_RXNOTEMPTY_SHIFT          (6U)
+/*! RXNOTEMPTY - Receive FIFO not empty. When 1, the receive FIFO is not empty, so data can be read. When 0, the receive FIFO is empty.
+ */
+#define USART_FIFOSTAT_RXNOTEMPTY(x)             (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXNOTEMPTY_SHIFT)) & USART_FIFOSTAT_RXNOTEMPTY_MASK)
+#define USART_FIFOSTAT_RXFULL_MASK               (0x80U)
+#define USART_FIFOSTAT_RXFULL_SHIFT              (7U)
+/*! RXFULL - Receive FIFO full. When 1, the receive FIFO is full. Data needs to be read out to
+ *    prevent the peripheral from causing an overflow.
+ */
+#define USART_FIFOSTAT_RXFULL(x)                 (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXFULL_SHIFT)) & USART_FIFOSTAT_RXFULL_MASK)
+#define USART_FIFOSTAT_TXLVL_MASK                (0x1F00U)
+#define USART_FIFOSTAT_TXLVL_SHIFT               (8U)
+/*! TXLVL - Transmit FIFO current level. A 0 means the TX FIFO is currently empty, and the TXEMPTY
+ *    and TXNOTFULL flags will be 1. Other values tell how much data is actually in the TX FIFO at
+ *    the point where the read occurs. If the TX FIFO is full, the TXEMPTY and TXNOTFULL flags will be
+ *    0.
+ */
+#define USART_FIFOSTAT_TXLVL(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXLVL_SHIFT)) & USART_FIFOSTAT_TXLVL_MASK)
+#define USART_FIFOSTAT_RXLVL_MASK                (0x1F0000U)
+#define USART_FIFOSTAT_RXLVL_SHIFT               (16U)
+/*! RXLVL - Receive FIFO current level. A 0 means the RX FIFO is currently empty, and the RXFULL and
+ *    RXNOTEMPTY flags will be 0. Other values tell how much data is actually in the RX FIFO at the
+ *    point where the read occurs. If the RX FIFO is full, the RXFULL and RXNOTEMPTY flags will be
+ *    1.
+ */
+#define USART_FIFOSTAT_RXLVL(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXLVL_SHIFT)) & USART_FIFOSTAT_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOTRIG - FIFO trigger settings for interrupt and DMA request. */
+/*! @{ */
+#define USART_FIFOTRIG_TXLVLENA_MASK             (0x1U)
+#define USART_FIFOTRIG_TXLVLENA_SHIFT            (0U)
+/*! TXLVLENA - Transmit FIFO level trigger enable. This trigger will become an interrupt if enabled
+ *    in FIFOINTENSET, or a DMA trigger if DMATX in FIFOCFG is set. 0: Transmit FIFO level does not
+ *    generate a FIFO level trigger. 1: An interrupt will be generated if the transmit FIFO level
+ *    reaches the value specified by the TXLVL field in this register.
+ */
+#define USART_FIFOTRIG_TXLVLENA(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_TXLVLENA_SHIFT)) & USART_FIFOTRIG_TXLVLENA_MASK)
+#define USART_FIFOTRIG_RXLVLENA_MASK             (0x2U)
+#define USART_FIFOTRIG_RXLVLENA_SHIFT            (1U)
+/*! RXLVLENA - Receive FIFO level trigger enable. This trigger will become an interrupt if enabled
+ *    in FIFOINTENSET, or a DMA trigger if DMARX in FIFOCFG is set. 0: Receive FIFO level does not
+ *    generate a FIFO level trigger. 1: An interrupt will be generated if the receive FIFO level
+ *    reaches the value specified by the RXLVL field in this register.
+ */
+#define USART_FIFOTRIG_RXLVLENA(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_RXLVLENA_SHIFT)) & USART_FIFOTRIG_RXLVLENA_MASK)
+#define USART_FIFOTRIG_TXLVL_MASK                (0xF00U)
+#define USART_FIFOTRIG_TXLVL_SHIFT               (8U)
+/*! TXLVL - Transmit FIFO level trigger point. This field is used only when TXLVLENA = 1. 0: trigger
+ *    when the TX FIFO becomes empty. 1: trigger when the TX FIFO level decreases to one entry. ...
+ *    3: trigger when the TX FIFO level decreases to 3 entries (is no longer full).
+ */
+#define USART_FIFOTRIG_TXLVL(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_TXLVL_SHIFT)) & USART_FIFOTRIG_TXLVL_MASK)
+#define USART_FIFOTRIG_RXLVL_MASK                (0xF0000U)
+#define USART_FIFOTRIG_RXLVL_SHIFT               (16U)
+/*! RXLVL - Receive FIFO level trigger point. The RX FIFO level is checked when a new piece of data
+ *    is received. This field is used only when RXLVLENA = 1. 0: trigger when the RX FIFO has
+ *    received one entry (is no longer empty). 1: trigger when the RX FIFO has received two entries. ...
+ *    3: trigger when the RX FIFO has received 4 entries (has become full).
+ */
+#define USART_FIFOTRIG_RXLVL(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_RXLVL_SHIFT)) & USART_FIFOTRIG_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTENSET - FIFO interrupt enable set (enable) and read register. */
+/*! @{ */
+#define USART_FIFOINTENSET_TXERR_MASK            (0x1U)
+#define USART_FIFOINTENSET_TXERR_SHIFT           (0U)
+/*! TXERR - Determines whether an interrupt occurs when a transmit error occurs, based on the TXERR
+ *    flag in the FIFOSTAT register. 0: No interrupt will be generated for a transmit error. 1: An
+ *    interrupt will be generated when a transmit error occurs.
+ */
+#define USART_FIFOINTENSET_TXERR(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_TXERR_SHIFT)) & USART_FIFOINTENSET_TXERR_MASK)
+#define USART_FIFOINTENSET_RXERR_MASK            (0x2U)
+#define USART_FIFOINTENSET_RXERR_SHIFT           (1U)
+/*! RXERR - Determines whether an interrupt occurs when a receive error occurs, based on the RXERR
+ *    flag in the FIFOSTAT register. 0: No interrupt will be generated for a receive error. 1: An
+ *    interrupt will be generated when a receive error occurs.
+ */
+#define USART_FIFOINTENSET_RXERR(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_RXERR_SHIFT)) & USART_FIFOINTENSET_RXERR_MASK)
+#define USART_FIFOINTENSET_TXLVL_MASK            (0x4U)
+#define USART_FIFOINTENSET_TXLVL_SHIFT           (2U)
+/*! TXLVL - Determines whether an interrupt occurs when a the transmit FIFO reaches the level
+ *    specified by the TXLVL field in the FIFOTRIG register. 0: No interrupt will be generated based on
+ *    the TX FIFO level. 1: TXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated when
+ *    the TX FIFO level decreases to the level specified by TXLVL in the FIFOTRIG register.
+ */
+#define USART_FIFOINTENSET_TXLVL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_TXLVL_SHIFT)) & USART_FIFOINTENSET_TXLVL_MASK)
+#define USART_FIFOINTENSET_RXLVL_MASK            (0x8U)
+#define USART_FIFOINTENSET_RXLVL_SHIFT           (3U)
+/*! RXLVL - Determines whether an interrupt occurs when a the receive FIFO reaches the level
+ *    specified by the TXLVL field in the FIFOTRIG register. 0: No interrupt will be generated based on the
+ *    RX FIFO level. 1: If RXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated
+ *    when the when the RX FIFO level increases to the level specified by RXLVL in the FIFOTRIG
+ *    register.
+ */
+#define USART_FIFOINTENSET_RXLVL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_RXLVL_SHIFT)) & USART_FIFOINTENSET_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTENCLR - FIFO interrupt enable clear (disable) and read register. */
+/*! @{ */
+#define USART_FIFOINTENCLR_TXERR_MASK            (0x1U)
+#define USART_FIFOINTENCLR_TXERR_SHIFT           (0U)
+/*! TXERR - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define USART_FIFOINTENCLR_TXERR(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_TXERR_SHIFT)) & USART_FIFOINTENCLR_TXERR_MASK)
+#define USART_FIFOINTENCLR_RXERR_MASK            (0x2U)
+#define USART_FIFOINTENCLR_RXERR_SHIFT           (1U)
+/*! RXERR - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define USART_FIFOINTENCLR_RXERR(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_RXERR_SHIFT)) & USART_FIFOINTENCLR_RXERR_MASK)
+#define USART_FIFOINTENCLR_TXLVL_MASK            (0x4U)
+#define USART_FIFOINTENCLR_TXLVL_SHIFT           (2U)
+/*! TXLVL - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define USART_FIFOINTENCLR_TXLVL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_TXLVL_SHIFT)) & USART_FIFOINTENCLR_TXLVL_MASK)
+#define USART_FIFOINTENCLR_RXLVL_MASK            (0x8U)
+#define USART_FIFOINTENCLR_RXLVL_SHIFT           (3U)
+/*! RXLVL - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define USART_FIFOINTENCLR_RXLVL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_RXLVL_SHIFT)) & USART_FIFOINTENCLR_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTSTAT - FIFO interrupt status register. Reflects the status of interrupts that are currently enabled. */
+/*! @{ */
+#define USART_FIFOINTSTAT_TXERR_MASK             (0x1U)
+#define USART_FIFOINTSTAT_TXERR_SHIFT            (0U)
+/*! TXERR - TX FIFO error.
+ */
+#define USART_FIFOINTSTAT_TXERR(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_TXERR_SHIFT)) & USART_FIFOINTSTAT_TXERR_MASK)
+#define USART_FIFOINTSTAT_RXERR_MASK             (0x2U)
+#define USART_FIFOINTSTAT_RXERR_SHIFT            (1U)
+/*! RXERR - RX FIFO error.
+ */
+#define USART_FIFOINTSTAT_RXERR(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_RXERR_SHIFT)) & USART_FIFOINTSTAT_RXERR_MASK)
+#define USART_FIFOINTSTAT_TXLVL_MASK             (0x4U)
+#define USART_FIFOINTSTAT_TXLVL_SHIFT            (2U)
+/*! TXLVL - Transmit FIFO level interrupt.
+ */
+#define USART_FIFOINTSTAT_TXLVL(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_TXLVL_SHIFT)) & USART_FIFOINTSTAT_TXLVL_MASK)
+#define USART_FIFOINTSTAT_RXLVL_MASK             (0x8U)
+#define USART_FIFOINTSTAT_RXLVL_SHIFT            (3U)
+/*! RXLVL - Receive FIFO level interrupt.
+ */
+#define USART_FIFOINTSTAT_RXLVL(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_RXLVL_SHIFT)) & USART_FIFOINTSTAT_RXLVL_MASK)
+#define USART_FIFOINTSTAT_PERINT_MASK            (0x10U)
+#define USART_FIFOINTSTAT_PERINT_SHIFT           (4U)
+/*! PERINT - Peripheral interrupt.
+ */
+#define USART_FIFOINTSTAT_PERINT(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_PERINT_SHIFT)) & USART_FIFOINTSTAT_PERINT_MASK)
+/*! @} */
+
+/*! @name FIFOWR - FIFO write data. Used to write values to be transmitted to the FIFO. */
+/*! @{ */
+#define USART_FIFOWR_TXDATA_MASK                 (0x1FFU)
+#define USART_FIFOWR_TXDATA_SHIFT                (0U)
+/*! TXDATA - Transmit data to the FIFO. The number of bits used depends on the DATALEN
+ */
+#define USART_FIFOWR_TXDATA(x)                   (((uint32_t)(((uint32_t)(x)) << USART_FIFOWR_TXDATA_SHIFT)) & USART_FIFOWR_TXDATA_MASK)
+/*! @} */
+
+/*! @name FIFORD - FIFO read data. Used to read values that have been received. */
+/*! @{ */
+#define USART_FIFORD_RXDATA_MASK                 (0x1FFU)
+#define USART_FIFORD_RXDATA_SHIFT                (0U)
+/*! RXDATA - Received data from the FIFO. The number of bits used depends on the DATALEN and PARITYSEL settings.
+ */
+#define USART_FIFORD_RXDATA(x)                   (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_RXDATA_SHIFT)) & USART_FIFORD_RXDATA_MASK)
+#define USART_FIFORD_FRAMERR_MASK                (0x2000U)
+#define USART_FIFORD_FRAMERR_SHIFT               (13U)
+/*! FRAMERR - Framing Error status flag. This bit reflects the status for the data it is read along
+ *    with from the FIFO, and indicates that the character was received with a missing stop bit at
+ *    the expected location. This could be an indication of a baud rate or configuration mismatch
+ *    with the transmitting source.
+ */
+#define USART_FIFORD_FRAMERR(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_FRAMERR_SHIFT)) & USART_FIFORD_FRAMERR_MASK)
+#define USART_FIFORD_PARITYERR_MASK              (0x4000U)
+#define USART_FIFORD_PARITYERR_SHIFT             (14U)
+/*! PARITYERR - Parity Error status flag. This bit reflects the status for the data it is read along
+ *    with from the FIFO. This bit will be set when a parity error is detected in a received
+ *    character.
+ */
+#define USART_FIFORD_PARITYERR(x)                (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_PARITYERR_SHIFT)) & USART_FIFORD_PARITYERR_MASK)
+#define USART_FIFORD_RXNOISE_MASK                (0x8000U)
+#define USART_FIFORD_RXNOISE_SHIFT               (15U)
+/*! RXNOISE - Received Noise flag.
+ */
+#define USART_FIFORD_RXNOISE(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_RXNOISE_SHIFT)) & USART_FIFORD_RXNOISE_MASK)
+/*! @} */
+
+/*! @name FIFORDNOPOP - FIFO data read with no FIFO pop. This register acts in exactly the same way as FIFORD, except that it supplies data from the top of the FIFO without popping the FIFO (i.e. leaving the FIFO state unchanged). This could be used to allow system software to observe incoming data without interfering with the peripheral driver. */
+/*! @{ */
+#define USART_FIFORDNOPOP_RXDATA_MASK            (0x1FFU)
+#define USART_FIFORDNOPOP_RXDATA_SHIFT           (0U)
+/*! RXDATA - Received data from the FIFO. The number of bits used depends on the DATALEN and PARITYSEL settings.
+ */
+#define USART_FIFORDNOPOP_RXDATA(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_RXDATA_SHIFT)) & USART_FIFORDNOPOP_RXDATA_MASK)
+#define USART_FIFORDNOPOP_FRAMERR_MASK           (0x2000U)
+#define USART_FIFORDNOPOP_FRAMERR_SHIFT          (13U)
+/*! FRAMERR - Framing Error status flag. This bit reflects the status for the data it is read along
+ *    with from the FIFO, and indicates that the character was received with a missing stop bit at
+ *    the expected location. This could be an indication of a baud rate or configuration mismatch
+ *    with the transmitting source.
+ */
+#define USART_FIFORDNOPOP_FRAMERR(x)             (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_FRAMERR_SHIFT)) & USART_FIFORDNOPOP_FRAMERR_MASK)
+#define USART_FIFORDNOPOP_PARITYERR_MASK         (0x4000U)
+#define USART_FIFORDNOPOP_PARITYERR_SHIFT        (14U)
+/*! PARITYERR - Parity Error status flag. This bit reflects the status for the data it is read along
+ *    with from the FIFO. This bit will be set when a parity error is detected in a received
+ *    character.
+ */
+#define USART_FIFORDNOPOP_PARITYERR(x)           (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_PARITYERR_SHIFT)) & USART_FIFORDNOPOP_PARITYERR_MASK)
+#define USART_FIFORDNOPOP_RXNOISE_MASK           (0x8000U)
+#define USART_FIFORDNOPOP_RXNOISE_SHIFT          (15U)
+/*! RXNOISE - Received Noise flag.
+ */
+#define USART_FIFORDNOPOP_RXNOISE(x)             (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_RXNOISE_SHIFT)) & USART_FIFORDNOPOP_RXNOISE_MASK)
+/*! @} */
+
+/*! @name PSELID - Flexcomm ID and peripheral function select register */
+/*! @{ */
+#define USART_PSELID_PERSEL_MASK                 (0x7U)
+#define USART_PSELID_PERSEL_SHIFT                (0U)
+/*! PERSEL - Peripheral Select. This field is writable by software. 0x0: No peripheral selected.
+ *    0x1: USART function selected. 0x2 - 0x7: Reserved.
+ */
+#define USART_PSELID_PERSEL(x)                   (((uint32_t)(((uint32_t)(x)) << USART_PSELID_PERSEL_SHIFT)) & USART_PSELID_PERSEL_MASK)
+#define USART_PSELID_LOCK_MASK                   (0x8U)
+#define USART_PSELID_LOCK_SHIFT                  (3U)
+/*! LOCK - Lock the peripheral select. This field is writable by software. 0: Peripheral select can
+ *    be changed by software. 1: Peripheral select is locked and cannot be changed until this
+ *    Flexcomm or the entire device is reset.
+ */
+#define USART_PSELID_LOCK(x)                     (((uint32_t)(((uint32_t)(x)) << USART_PSELID_LOCK_SHIFT)) & USART_PSELID_LOCK_MASK)
+#define USART_PSELID_USARTPRESENT_MASK           (0x10U)
+#define USART_PSELID_USARTPRESENT_SHIFT          (4U)
+/*! USARTPRESENT - USART present indicator. This field is Read-only. 0: This Flexcomm does not
+ *    include the USART function. 1: This Flexcomm includes the USART function.
+ */
+#define USART_PSELID_USARTPRESENT(x)             (((uint32_t)(((uint32_t)(x)) << USART_PSELID_USARTPRESENT_SHIFT)) & USART_PSELID_USARTPRESENT_MASK)
+#define USART_PSELID_ID_MASK                     (0xFFFFF000U)
+#define USART_PSELID_ID_SHIFT                    (12U)
+/*! ID - Flexcomm ID.
+ */
+#define USART_PSELID_ID(x)                       (((uint32_t)(((uint32_t)(x)) << USART_PSELID_ID_SHIFT)) & USART_PSELID_ID_MASK)
+/*! @} */
+
+/*! @name ID - USART Module Identifier */
+/*! @{ */
+#define USART_ID_APERTURE_MASK                   (0xFFU)
+#define USART_ID_APERTURE_SHIFT                  (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define USART_ID_APERTURE(x)                     (((uint32_t)(((uint32_t)(x)) << USART_ID_APERTURE_SHIFT)) & USART_ID_APERTURE_MASK)
+#define USART_ID_MIN_REV_MASK                    (0xF00U)
+#define USART_ID_MIN_REV_SHIFT                   (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define USART_ID_MIN_REV(x)                      (((uint32_t)(((uint32_t)(x)) << USART_ID_MIN_REV_SHIFT)) & USART_ID_MIN_REV_MASK)
+#define USART_ID_MAJ_REV_MASK                    (0xF000U)
+#define USART_ID_MAJ_REV_SHIFT                   (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define USART_ID_MAJ_REV(x)                      (((uint32_t)(((uint32_t)(x)) << USART_ID_MAJ_REV_SHIFT)) & USART_ID_MAJ_REV_MASK)
+#define USART_ID_ID_MASK                         (0xFFFF0000U)
+#define USART_ID_ID_SHIFT                        (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define USART_ID_ID(x)                           (((uint32_t)(((uint32_t)(x)) << USART_ID_ID_SHIFT)) & USART_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group USART_Register_Masks */
+
+
+/* USART - Peripheral instance base addresses */
+/** Peripheral USART0 base address */
+#define USART0_BASE                              (0x4008B000u)
+/** Peripheral USART0 base pointer */
+#define USART0                                   ((USART_Type *)USART0_BASE)
+/** Peripheral USART1 base address */
+#define USART1_BASE                              (0x4008C000u)
+/** Peripheral USART1 base pointer */
+#define USART1                                   ((USART_Type *)USART1_BASE)
+/** Array initializer of USART peripheral base addresses */
+#define USART_BASE_ADDRS                         { USART0_BASE, USART1_BASE }
+/** Array initializer of USART peripheral base pointers */
+#define USART_BASE_PTRS                          { USART0, USART1 }
+/** Interrupt vectors for the USART peripheral type */
+#define USART_IRQS                               { FLEXCOMM0_IRQn, FLEXCOMM1_IRQn }
+
+/*!
+ * @}
+ */ /* end of group USART_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- WWDT Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup WWDT_Peripheral_Access_Layer WWDT Peripheral Access Layer
+ * @{
+ */
+
+/** WWDT - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t MOD;                               /**< Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer., offset: 0x0 */
+  __IO uint32_t TC;                                /**< Watchdog timer constant register. This 24-bit register determines the time-out value., offset: 0x4 */
+  __O  uint32_t FEED;                              /**< Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in TC., offset: 0x8 */
+  __I  uint32_t TV;                                /**< Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer., offset: 0xC */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t WARNINT;                           /**< Watchdog Warning Interrupt compare value., offset: 0x14 */
+  __IO uint32_t WINDOW;                            /**< Watchdog Window compare value., offset: 0x18 */
+} WWDT_Type;
+
+/* ----------------------------------------------------------------------------
+   -- WWDT Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup WWDT_Register_Masks WWDT Register Masks
+ * @{
+ */
+
+/*! @name MOD - Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer. */
+/*! @{ */
+#define WWDT_MOD_WDEN_MASK                       (0x1U)
+#define WWDT_MOD_WDEN_SHIFT                      (0U)
+/*! WDEN - Watchdog enable bit. Once this bit is set to one and a watchdog feed is performed, the
+ *    watchdog timer will run permanently. 0: The watchdog timer is stopped. 1: The watchdog timer is
+ *    running.
+ */
+#define WWDT_MOD_WDEN(x)                         (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDEN_SHIFT)) & WWDT_MOD_WDEN_MASK)
+#define WWDT_MOD_WDRESET_MASK                    (0x2U)
+#define WWDT_MOD_WDRESET_SHIFT                   (1U)
+/*! WDRESET - Watchdog reset enable bit. Once this bit has been written with a 1 it cannot be
+ *    re-written with a 0. 0: Interrupt. A watchdog time-out will not cause a chip reset. It will cause an
+ *    interrupt of the watchdog. 1: Reset. A watchdog time-out will cause a chip reset.
+ */
+#define WWDT_MOD_WDRESET(x)                      (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDRESET_SHIFT)) & WWDT_MOD_WDRESET_MASK)
+#define WWDT_MOD_WDTOF_MASK                      (0x4U)
+#define WWDT_MOD_WDTOF_SHIFT                     (2U)
+/*! WDTOF - Watchdog time-out flag. Set when the watchdog timer times out, by a feed error, or by
+ *    events associated with WDPROTECT. Cleared by software writing a 0 to this bit position. Causes a
+ *    chip reset if WDRESET = 1.
+ */
+#define WWDT_MOD_WDTOF(x)                        (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDTOF_SHIFT)) & WWDT_MOD_WDTOF_MASK)
+#define WWDT_MOD_WDINT_MASK                      (0x8U)
+#define WWDT_MOD_WDINT_SHIFT                     (3U)
+/*! WDINT - Warning interrupt flag. Set when the timer reaches the value in WDWARNINT. Cleared by
+ *    software writing a 1 to this bit position. Note that this bit cannot be cleared while the
+ *    WARNINT value is equal to the value of the TV register. This can occur if the value of WARNINT is 0
+ *    and the WDRESET bit is 0 when TV decrements to 0.
+ */
+#define WWDT_MOD_WDINT(x)                        (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDINT_SHIFT)) & WWDT_MOD_WDINT_MASK)
+#define WWDT_MOD_WDPROTECT_MASK                  (0x10U)
+#define WWDT_MOD_WDPROTECT_SHIFT                 (4U)
+/*! WDPROTECT - Watchdog update mode. This bit can be set once by software and is only cleared by a
+ *    reset. 0: Flexible. A feed sequence can be performed at any time; ie. the watchdog timer can
+ *    be reloaded with time-out value (TC) at any time. 1: Threshold. A feed sequence can be
+ *    performed only after the counter is below the value of WDWARNINT and WDWINDOW; ie. the watchdog timer
+ *    can be reloaded with time-out value (TC) only when the counter timer value is below the value
+ *    of WDWARNINT and WDWINDOW, otherwise a 'feed error' is created.
+ */
+#define WWDT_MOD_WDPROTECT(x)                    (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDPROTECT_SHIFT)) & WWDT_MOD_WDPROTECT_MASK)
+/*! @} */
+
+/*! @name TC - Watchdog timer constant register. This 24-bit register determines the time-out value. */
+/*! @{ */
+#define WWDT_TC_COUNT_MASK                       (0xFFFFFFU)
+#define WWDT_TC_COUNT_SHIFT                      (0U)
+/*! COUNT - Watchdog time-out value. If MOD.WDPROTECT is set then changing this value may cause an error.
+ */
+#define WWDT_TC_COUNT(x)                         (((uint32_t)(((uint32_t)(x)) << WWDT_TC_COUNT_SHIFT)) & WWDT_TC_COUNT_MASK)
+/*! @} */
+
+/*! @name FEED - Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in TC. */
+/*! @{ */
+#define WWDT_FEED_FEED_MASK                      (0xFFU)
+#define WWDT_FEED_FEED_SHIFT                     (0U)
+/*! FEED - Feed value should be 0xAA followed by 0x55. Writing 0xAA followed by 0x55 to this
+ *    register will reload the Watchdog timer with the TC value. This operation will also start the
+ *    Watchdog if it is enabled via the WDMOD register. Setting the WDEN bit in the WDMOD register is not
+ *    sufficient to enable the Watchdog. A valid feed sequence must be completed after setting WDEN
+ *    before the Watchdog is capable of generating a reset. Until then, the Watchdog will ignore feed
+ *    errors.
+ */
+#define WWDT_FEED_FEED(x)                        (((uint32_t)(((uint32_t)(x)) << WWDT_FEED_FEED_SHIFT)) & WWDT_FEED_FEED_MASK)
+/*! @} */
+
+/*! @name TV - Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer. */
+/*! @{ */
+#define WWDT_TV_COUNT_MASK                       (0xFFFFFFU)
+#define WWDT_TV_COUNT_SHIFT                      (0U)
+/*! COUNT - Counter timer value. The TV register is used to read the current value of Watchdog timer counter.
+ */
+#define WWDT_TV_COUNT(x)                         (((uint32_t)(((uint32_t)(x)) << WWDT_TV_COUNT_SHIFT)) & WWDT_TV_COUNT_MASK)
+/*! @} */
+
+/*! @name WARNINT - Watchdog Warning Interrupt compare value. */
+/*! @{ */
+#define WWDT_WARNINT_WARNINT_MASK                (0x3FFU)
+#define WWDT_WARNINT_WARNINT_SHIFT               (0U)
+/*! WARNINT - Watchdog warning interrupt compare value.A match of the watchdog timer counter to
+ *    WARNINT occurs when the bottom 10 bits of the counter have the same value as the 10 bits of
+ *    WARNINT, and the remaining upper bits of the counter are all 0. This gives a maximum time of 1,023
+ *    watchdog timer counts (4,096 watchdog clocks) for the interrupt to occur prior to a watchdog
+ *    event. If WARNINT is 0, the interrupt will occur at the same time as the watchdog event.
+ */
+#define WWDT_WARNINT_WARNINT(x)                  (((uint32_t)(((uint32_t)(x)) << WWDT_WARNINT_WARNINT_SHIFT)) & WWDT_WARNINT_WARNINT_MASK)
+/*! @} */
+
+/*! @name WINDOW - Watchdog Window compare value. */
+/*! @{ */
+#define WWDT_WINDOW_WINDOW_MASK                  (0xFFFFFFU)
+#define WWDT_WINDOW_WINDOW_SHIFT                 (0U)
+/*! WINDOW - Watchdog window value. The WINDOW register determines the highest TV value allowed when
+ *    a watchdog feed is performed. If a feed sequence occurs when TV is greater than the value in
+ *    WINDOW, a watchdog event will occur
+ */
+#define WWDT_WINDOW_WINDOW(x)                    (((uint32_t)(((uint32_t)(x)) << WWDT_WINDOW_WINDOW_SHIFT)) & WWDT_WINDOW_WINDOW_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group WWDT_Register_Masks */
+
+
+/* WWDT - Peripheral instance base addresses */
+/** Peripheral WWDT base address */
+#define WWDT_BASE                                (0x4000A000u)
+/** Peripheral WWDT base pointer */
+#define WWDT                                     ((WWDT_Type *)WWDT_BASE)
+/** Array initializer of WWDT peripheral base addresses */
+#define WWDT_BASE_ADDRS                          { WWDT_BASE }
+/** Array initializer of WWDT peripheral base pointers */
+#define WWDT_BASE_PTRS                           { WWDT }
+/** Interrupt vectors for the WWDT peripheral type */
+#define WWDT_IRQS                                { WDT_BOD_IRQn }
+
+/*!
+ * @}
+ */ /* end of group WWDT_Peripheral_Access_Layer */
+
+
+/*
+** End of section using anonymous unions
+*/
+
+#if defined(__ARMCC_VERSION)
+  #if (__ARMCC_VERSION >= 6010050)
+    #pragma clang diagnostic pop
+  #else
+    #pragma pop
+  #endif
+#elif defined(__GNUC__)
+  /* leave anonymous unions enabled */
+#elif defined(__IAR_SYSTEMS_ICC__)
+  #pragma language=default
+#else
+  #error Not supported compiler type
+#endif
+
+/*!
+ * @}
+ */ /* end of group Peripheral_access_layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK).
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Bit_Field_Generic_Macros Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK).
+ * @{
+ */
+
+#if defined(__ARMCC_VERSION)
+  #if (__ARMCC_VERSION >= 6010050)
+    #pragma clang system_header
+  #endif
+#elif defined(__IAR_SYSTEMS_ICC__)
+  #pragma system_include
+#endif
+
+/**
+ * @brief Mask and left-shift a bit field value for use in a register bit range.
+ * @param field Name of the register bit field.
+ * @param value Value of the bit field.
+ * @return Masked and shifted value.
+ */
+#define NXP_VAL2FLD(field, value)    (((value) << (field ## _SHIFT)) & (field ## _MASK))
+/**
+ * @brief Mask and right-shift a register value to extract a bit field value.
+ * @param field Name of the register bit field.
+ * @param value Value of the register.
+ * @return Masked and shifted bit field value.
+ */
+#define NXP_FLD2VAL(field, value)    (((value) & (field ## _MASK)) >> (field ## _SHIFT))
+
+/*!
+ * @}
+ */ /* end of group Bit_Field_Generic_Macros */
+
+
+/* ----------------------------------------------------------------------------
+   -- SDK Compatibility
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SDK_Compatibility_Symbols SDK Compatibility
+ * @{
+ */
+
+#define USART0_IRQn FLEXCOMM0_IRQn
+#define USART1_IRQn FLEXCOMM1_IRQn
+#define I2C0_IRQn FLEXCOMM2_IRQn
+#define I2C1_IRQn FLEXCOMM3_IRQn
+#define SPI0_IRQn FLEXCOMM4_IRQn
+#define SPI1_IRQn FLEXCOMM5_IRQn
+#define I2C2_IRQn FLEXCOMM6_IRQn
+#define DMA_IRQn DMA0_IRQn
+#define GINT_IRQn GINT0_IRQn
+#define PINT0_IRQn PIN_INT0_IRQn
+#define PINT1_IRQn PIN_INT1_IRQn
+#define PINT2_IRQn PIN_INT2_IRQn
+#define PINT3_IRQn PIN_INT3_IRQn
+#define SPIFI_IRQn SPIFI0_IRQn
+#define GINT_IRQn GINT0_IRQn
+#define Timer0_IRQn CTIMER0_IRQn
+#define Timer1_IRQn CTIMER1_IRQn
+#define DMIC_IRQn DMIC0_IRQn
+#define HWVAD_IRQn HWVAD0_IRQn
+#define AES256_Type AES_Type
+#define NTAG_IRQ NFCTag_IRQn
+#define PRESETCTRL PRESETCTRLS
+#define PRESETCTRLSET PRESETCTRLSETS
+#define PRESETCTRLCLR PRESETCTRLCLRS
+#define AHBCLKCTRL AHBCLKCTRLS
+#define AHBCLKCTRLSET AHBCLKCTRLSETS
+#define AHBCLKCTRLCLR AHBCLKCTRLCLRS
+#define STARTER STARTERS
+#define STARTERSET STARTERSETS
+#define STARTERCLR STARTERCLRS
+
+/*!
+ * @}
+ */ /* end of group SDK_Compatibility_Symbols */
+
+
+#endif  /* _JN5189_H_ */
+
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/JN5189_features.h b/third_party/nxp/JN5189DK6/devices/JN5189/JN5189_features.h
new file mode 100755
index 0000000..219c60d
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/JN5189_features.h
@@ -0,0 +1,242 @@
+/*
+** ###################################################################
+**     Version:             rev. 1.0, 2018-07-31
+**     Build:               b191225
+**
+**     Abstract:
+**         Chip specific module features.
+**
+**     Copyright 2016 Freescale Semiconductor, Inc.
+**     Copyright 2016-2019 NXP
+**     All rights reserved.
+**
+**     SPDX-License-Identifier: BSD-3-Clause
+**
+**     http:                 www.nxp.com
+**     mail:                 support@nxp.com
+**
+**     Revisions:
+**     - rev. 1.0 (2018-07-31)
+**         Initial version.
+**
+** ###################################################################
+*/
+
+#ifndef _JN5189_FEATURES_H_
+#define _JN5189_FEATURES_H_
+
+/* SOC module features */
+
+/* @brief ADC availability on the SoC. */
+#define FSL_FEATURE_SOC_ADC_COUNT (1)
+/* @brief AES availability on the SoC. */
+#define FSL_FEATURE_SOC_AES_COUNT (1)
+/* @brief ASYNC_SYSCON availability on the SoC. */
+#define FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT (1)
+/* @brief CIC_IRB availability on the SoC. */
+#define FSL_FEATURE_SOC_CIC_IRB_COUNT (1)
+/* @brief CTIMER availability on the SoC. */
+#define FSL_FEATURE_SOC_CTIMER_COUNT (2)
+/* @brief DMA availability on the SoC. */
+#define FSL_FEATURE_SOC_DMA_COUNT (1)
+/* @brief DMIC availability on the SoC. */
+#define FSL_FEATURE_SOC_DMIC_COUNT (1)
+/* @brief FLASH availability on the SoC. */
+#define FSL_FEATURE_SOC_FLASH_COUNT (1)
+/* @brief FLEXCOMM availability on the SoC. */
+#define FSL_FEATURE_SOC_FLEXCOMM_COUNT (7)
+/* @brief GINT availability on the SoC. */
+#define FSL_FEATURE_SOC_GINT_COUNT (1)
+/* @brief I2C availability on the SoC. */
+#define FSL_FEATURE_SOC_I2C_COUNT (3)
+/* @brief INPUTMUX availability on the SoC. */
+#define FSL_FEATURE_SOC_INPUTMUX_COUNT (1)
+/* @brief IOCON availability on the SoC. */
+#define FSL_FEATURE_SOC_IOCON_COUNT (1)
+/* @brief LPC_GPIO availability on the SoC. */
+#define FSL_FEATURE_SOC_LPC_GPIO_COUNT (1)
+/* @brief LPC_RTC availability on the SoC. */
+#define FSL_FEATURE_SOC_LPC_RTC_COUNT (1)
+/* @brief PINT availability on the SoC. */
+#define FSL_FEATURE_SOC_PINT_COUNT (1)
+/* @brief PMC availability on the SoC. */
+#define FSL_FEATURE_SOC_PMC_COUNT (1)
+/* @brief PWM availability on the SoC. */
+#define FSL_FEATURE_SOC_PWM_COUNT (1)
+/* @brief SHA availability on the SoC. */
+#define FSL_FEATURE_SOC_SHA_COUNT (1)
+/* @brief SPI availability on the SoC. */
+#define FSL_FEATURE_SOC_SPI_COUNT (2)
+/* @brief SPIFI availability on the SoC. */
+#define FSL_FEATURE_SOC_SPIFI_COUNT (1)
+/* @brief SYSCON availability on the SoC. */
+#define FSL_FEATURE_SOC_SYSCON_COUNT (1)
+/* @brief TRNG availability on the SoC. */
+#define FSL_FEATURE_SOC_TRNG_COUNT (1)
+/* @brief USART availability on the SoC. */
+#define FSL_FEATURE_SOC_USART_COUNT (2)
+/* @brief WWDT availability on the SoC. */
+#define FSL_FEATURE_SOC_WWDT_COUNT (1)
+
+/* ADC module features */
+
+/* @brief ADC data alignment mode. */
+#define FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT (1)
+/* @brief ADC data alignment mode. */
+#define FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL (1)
+/* @brief Has no Calibration function. */
+#define FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC (1)
+/* @brief ADC has single SEQ. */
+#define FSL_FEATURE_ADC_HAS_SINGLE_SEQ (1)
+/* @brief Has ADC_INIT bitfile in STARTUP register. */
+#define FSL_FEATURE_ADC_HAS_STARTUP_ADC_INIT (0)
+/* @brief Has OFFSET_CAL bitfile in GPADC_CTRL1 reigster. */
+#define FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL (1)
+/* @brief Has LDO_POWER_EN bitfile in GPADC_CTRL0 reigster. */
+#define FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN (1)
+/* @brief ADC require a delay. */
+#define FSL_FEATURE_ADC_REQUIRE_DELAY (1)
+/* @brief ADC TEMPSENSORCTRL in ASYNC_SYSCON. */
+#define FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP (1)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE (1)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_RESOL (1)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL (0)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_TSAMP (1)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE (0)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_CALMODE (0)
+/* @brief Has ADTrim register */
+#define FSL_FEATURE_ADC_HAS_TRIM_REG (0)
+/* @brief Has Calibration register. */
+#define FSL_FEATURE_ADC_HAS_CALIB_REG (0)
+
+/* ASYNC_SYSCON module features */
+
+/* @brief FMEAS FMEAS_INDEX is 20. */
+#define FSL_FEATURE_FMEAS_INDEX_20 (1)
+/* @brief FMEAS FREQMECTRL in ASYNC_SYSCON. */
+#define FSL_FEATURE_FMEAS_ASYNC_SYSCON_FREQMECTRL (1)
+/* @brief FMEAS SYSCON use ASYNC_SYSCON. */
+#define FSL_FEATURE_FMEAS_USE_ASYNC_SYSCON (1)
+/* @brief FMEAS start frequency with ASYNC_SYSCON. */
+#define FSL_FEATURE_FMEAS_START_FRG_ASYNC_SYSCON (1)
+/* @brief FMEAS get frequency with ASYNC_SYSCON. */
+#define FSL_FEATURE_FMEAS_GET_FRG_ASYNC_SYSCON (1)
+/* @brief FMEAS get clock count with scale. */
+#define FSL_FEATURE_FMEAS_GET_COUNT_SCALE (1)
+/* @brief FMEAS start measure with scale. */
+#define FSL_FEATURE_FMEAS_STARTMEAS_SCALE (1)
+
+/* CTIMER module features */
+
+/* @brief CTIMER capture 3 interrupt. */
+#define FSL_FEATURE_CTIMER_HAS_IR_CR3INT (1)
+/* @brief CTIMER has no capture channel. */
+#define FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE (1)
+
+/* DMA module features */
+
+/* @brief Number of channels */
+#define FSL_FEATURE_DMA_NUMBER_OF_CHANNELS (19)
+/* @brief Align size of DMA descriptor */
+#define FSL_FEATURE_DMA_DESCRIPTOR_ALIGN_SIZE (512)
+/* @brief DMA head link descriptor table align size */
+#define FSL_FEATURE_DMA_LINK_DESCRIPTOR_ALIGN_SIZE (16U)
+
+/* FLASH module features */
+
+/* @brief P-Flash write unit size. */
+#define FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE (512U)
+/* @brief P-Flash sector size. */
+#define FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE (512U)
+/* @brief P-Flash block count. */
+#define FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT (1)
+/* @brief P-Flash block size. */
+#define FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE (0xA0000U)
+/* @brief ADC temp cal flash addr. */
+#define FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL (0x9FC80)
+/* @brief ADC temp cal flash data vaild mask. */
+#define FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL_VALID (0x1)
+
+/* FLEXCOMM module features */
+
+/* @brief Has no reset in FLEXCOMM register. */
+#define FSL_FEATURE_FLEXCOMM_HAS_NO_RESET (1)
+/* @brief USART availability on the SoC. */
+#define FSL_FEATURE_SOC_FLEXCOMM_USART_COUNT (FSL_FEATURE_SOC_USART_COUNT)
+/* @brief SPI are FLEXCOMM on the SoC. */
+#define FSL_FEATURE_SOC_FLEXCOMM_SPI_COUNT (FSL_FEATURE_SOC_SPI_COUNT)
+/* @brief I2C are FLEXCOMM on the SoC. */
+#define FSL_FEATURE_SOC_FLEXCOMM_I2C_COUNT (FSL_FEATURE_SOC_I2C_COUNT)
+
+/* GPIO module features */
+
+/* @brief GPIO DIRSET and DIRCLR register. */
+#define FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR (1)
+/* @brief Number of PIOs. */
+#define FSL_FEATURE_GPIO_PIO_COUNT (22)
+/* @brief GPIO availability on the SoC. */
+#define FSL_FEATURE_SOC_GPIO_COUNT (FSL_FEATURE_SOC_LPC_GPIO_COUNT)
+
+/* I2C module features */
+
+/* @brief I2C peripheral clock frequency 8MHz. */
+#define FSL_FEATURE_I2C_PREPCLKFRG_8MHZ (1)
+
+/* IOCON module features */
+
+/* @brief Func bit field width */
+#define FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH (3)
+
+/* PINT module features */
+
+/* @brief Number of connected outputs */
+#define FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS (4)
+
+/* PMC module features */
+
+/* @brief FRO1M trim address. */
+#define FSL_FEATURE_PMC_FRO1M_ADDRESS (0x9FCD0U)
+/* @brief FRO1M trim valid mask. */
+#define FSL_FEATURE_PMC_FRO1M_VALID_MASK (0x1U)
+
+/* RTC module features */
+
+/* @brief Has no separate RTC OSC PD in CTRL register. */
+#define FSL_FEATURE_RTC_HAS_NO_OSC_PD (1)
+
+/* SPI module features */
+
+/* @brief SPI SIZE bitfile in FIFOCFG register */
+#define FSL_FEATURE_SPI_FIFOSIZE_CFG (1)
+/* @brief SPI has only three SSEL pins */
+#define FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE (1)
+
+/* SPIFI module features */
+
+/* @brief SPIFI start address */
+#define FSL_FEATURE_SPIFI_START_ADDR (0x10000000)
+/* @brief SPIFI end address */
+#define FSL_FEATURE_SPIFI_END_ADDR (0x103FFFFF)
+/* @brief SPIFI DATALEN bitfile in CMD register */
+#define FSL_FEATURE_SPIFI_DATALEN_CTRL (1)
+
+/* SYSCON module features */
+
+/* No feature definitions */
+
+/* WWDT module features */
+
+/* @brief WWDT WDTOF is not set in case of WD reset - get info from PMC instead. */
+#define FSL_FEATURE_WWDT_WDTRESET_FROM_PMC (1)
+/* @brief WWDT NO PDCFG. */
+#define FSL_FEATURE_WWDT_HAS_NO_PDCFG (1)
+/* @brief WWDT LOCK bitfile in MOD register */
+#define FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK (1)
+
+#endif /* _JN5189_FEATURES_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/flash_header.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/flash_header.h
new file mode 100755
index 0000000..9579f70
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/flash_header.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FLASH_HEADER_H_
+#define FLASH_HEADER_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stdint.h>
+
+/*!
+ * @addtogroup jn_flash
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+#define NUMBER_CCSUM_VECTORS (7)
+
+#define IMAGE_SIGNATURE (0x98447902)
+#define IMAGE_HEADER_SIGNATURE_V3_ZB (IMAGE_SIGNATURE + 1)
+#define IMAGE_HEADER_SIGNATURE_V3_BLE (IMAGE_SIGNATURE + 2)
+#define BOOT_BLOCK_HDR_MARKER 0xbb0110bb
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/*!
+ * @brief Image header.
+ *
+ * Be very cautious when modifying the IMG_HEADER_T and the BOOT_BLOCK_T structures (alignment) as
+ * these structures are used in the image_tool.py (which does not take care of alignment).
+ */
+typedef struct
+{
+    uint32_t vectors[NUMBER_CCSUM_VECTORS]; /*!< critical vectors protected by csum */
+    uint32_t vectorCsum;                    /*!< csum of vectors 0-7 */
+    uint32_t imageSignature;                /*!< image signature */
+    uint32_t bootBlockOffset;               /*!< offset of boot block structure */
+    uint32_t header_crc;                    /*!< the CRC of header */
+} IMG_HEADER_T;
+
+/*!
+ * @brief Boot block.
+ *
+ * For some ADC16 channels, there are two pin selections in channel multiplexer. For example, ADC0_SE4a and ADC0_SE4b
+ * are the different channels that share the same channel number.
+ */
+typedef struct
+{
+    uint32_t header_marker;        /*!< Image header marker should always be set to 0xbb0110bb+/-2 */
+    uint32_t img_type;             /*!< Image check type, with or without optional CRC */
+    uint32_t target_addr;          /*!< Target address */
+    uint32_t img_len;              /*!< Image length or the length of image CRC check should be done.
+                           For faster boot application could set a smaller length than actual image.
+                           For Secure boot images, this MUST be the entire image length */
+    uint32_t stated_size;          /*!< max size of any subsequent image : AppSize0 = 2 x stated_size */
+    uint32_t certificate_offset;   /*!< Offset of the certificate list */
+    uint32_t compatibility_offset; /*!< Offset of the compatibility list */
+    uint32_t version;              /*!< Image version for multi-image support */
+} BOOT_BLOCK_T;
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* FLASH_HEADER_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_aes.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_aes.c
new file mode 100755
index 0000000..f92cfbb
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_aes.c
@@ -0,0 +1,1283 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_aes.h"
+#include "string.h"
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.aes"
+#endif
+
+/*!< Use standard C library memcpy  */
+#define aes_memcpy memcpy
+
+/*! @brief Definitions used for writing to the AES module CFG register. */
+typedef enum _aes_configuration
+{
+    kAES_CfgEncryptEcb            = 0x001u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Encrypt Ecb */
+    kAES_CfgDecryptEcb            = 0x001u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Decrypt Ecb */
+    kAES_CfgEncryptCbc            = 0x023u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Encrypt Cbc */
+    kAES_CfgDecryptCbc            = 0x211u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Decrypt Cbc */
+    kAES_CfgEncryptCfb            = 0x132u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Encrypt Cfb */
+    kAES_CfgDecryptCfb            = 0x112u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Decrypt Cfb */
+    kAES_CfgCryptOfb              = 0x122u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Ofb */
+    kAES_CfgCryptCtr              = 0x102u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Ctr */
+    kAES_CfgCryptGcmTag           = 0x102u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Gcm */
+    kAES_CfgSwap                  = 0x51u,  /*!< INTEXT swap bytes, OUTTEXT swap bytes, PROC_EN = Encrypt/Decrypt */
+    kAES_CfgIntextSwap            = 0x11u,  /*!< INTEXT swap bytes, PROC_EN = Encrypt/Decrypt */
+    kAES_CfgSwapIntextHashIn      = 0x12u,  /*!< Swap INTEXT only, Hash INTEXT */
+    kAES_CfgSwapIntextHashOut     = 0x16u,  /*!< Swap INTEXT only, Hash OUTTEXT */
+    kAES_CfgSwapEnDecHashIn       = 0x53u,  /*!< Swap INTEXT and OUTTEXT, Encrypt/Decrypt and Hash, Hash INTEXT */
+    kAES_CfgSwapEnDecHashOut      = 0x57u,  /*!< Swap INTEXT and OUTTEXT, Encrypt/Decrypt and Hash, Hash OUTTEXT */
+    kAES_CfgSwapIntextEnDecHashIn = 0x13u,  /*!< Swap INTEXT, Encrypt/Decrypt and Hash, Hash INTEXT */
+} aes_configuration_t;
+
+/*! @brief Actual operation with AES. */
+typedef enum _aes_encryption_decryption_mode
+{
+    kAES_ModeEncrypt = 0U, /*!< Encryption */
+    kAES_ModeDecrypt = 1U, /*!< Decryption */
+} aes_encryption_decryption_mode_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+static void aes_gcm_dec32(uint8_t *input);
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * @brief Reads an unaligned word.
+ *
+ * This function creates a 32-bit word from an input array of four bytes.
+ *
+ * @param src Input array of four bytes. The array can start at any address in memory.
+ * @return 32-bit unsigned int created from the input byte array.
+ */
+static inline uint32_t aes_get_word_from_unaligned(const uint8_t *srcAddr)
+{
+#if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
+    register const uint8_t *src = srcAddr;
+    /* Cortex M0 does not support misaligned loads */
+    if ((uint32_t)src & 0x3u)
+    {
+        union _align_bytes_t
+        {
+            uint32_t word;
+            uint8_t byte[sizeof(uint32_t)];
+        } my_bytes;
+
+        my_bytes.byte[0] = *src;
+        my_bytes.byte[1] = *(src + 1);
+        my_bytes.byte[2] = *(src + 2);
+        my_bytes.byte[3] = *(src + 3);
+        return my_bytes.word;
+    }
+    else
+    {
+        /* addr aligned to 0-modulo-4 so it is safe to type cast */
+        return *((const uint32_t *)src);
+    }
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+    /* -O3 optimization in Keil uses LDM instruction here (LDM r4!, {r0})
+     *    which is wrong, because srcAddr might be unaligned.
+     *    LDM on unaligned address causes hard-fault. so use memcpy() */
+    uint32_t ret;
+    memcpy(&ret, srcAddr, sizeof(uint32_t));
+    return ret;
+#else
+    return *((const uint32_t *)srcAddr);
+#endif
+}
+
+/*!
+ * @brief Converts a 32-bit word into a byte array.
+ *
+ * This function creates an output array of four bytes from an input 32-bit word.
+ *
+ * @param srcWord Input 32-bit unsigned integer.
+ * @param[out] dst Output array of four bytes. The array can start at any address in memory.
+ */
+static inline void aes_set_unaligned_from_word(uint32_t srcWord, uint8_t *dstAddr)
+{
+#if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
+    register uint8_t *dst = dstAddr;
+    /* Cortex M0 does not support misaligned stores */
+    if ((uint32_t)dst & 0x3u)
+    {
+        *dst++ = (srcWord & 0x000000FFU);
+        *dst++ = (srcWord & 0x0000FF00U) >> 8;
+        *dst++ = (srcWord & 0x00FF0000U) >> 16;
+        *dst++ = (srcWord & 0xFF000000U) >> 24;
+    }
+    else
+    {
+        *((uint32_t *)dstAddr) = srcWord; /* addr aligned to 0-modulo-4 so it is safe to type cast */
+    }
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+    uint32_t ret;
+    ret = srcWord;
+    memcpy(dstAddr, &ret, sizeof(uint32_t));
+    return;
+#else
+    *((uint32_t *)dstAddr) = srcWord;
+#endif
+}
+
+/*!
+ * @brief Swap bytes withing 32-bit word.
+ *
+ * This function changes endianess of a 32-bit word.
+ *
+ * @param in 32-bit unsigned integer
+ * @return 32-bit unsigned integer with different endianess (big endian to little endian and vice versa).
+ */
+static uint32_t swap_bytes(uint32_t in)
+{
+    return (((in & 0x000000ffu) << 24) | ((in & 0x0000ff00u) << 8) | ((in & 0x00ff0000u) >> 8) |
+            ((in & 0xff000000u) >> 24));
+}
+
+/*!
+ * @brief Loads key into key registers.
+ *
+ * This function loads the key into the AES key registers.
+ *
+ * @param base AES peripheral base address.
+ * @param key Input key in big endian format.
+ * @param keySize Size of the input key in bytes. Must be 16, 24 or 32.
+ * @return Status of the load key operation.
+ */
+static status_t aes_load_key(AES_Type *base, const uint8_t *key, size_t keySize)
+{
+    uint32_t aesCfgKeyCfg;
+    uint32_t aesCfg;
+    int index;
+    int keyWords;
+
+    switch (keySize)
+    {
+        case 16u:
+            aesCfgKeyCfg = 0u;
+            keyWords     = 4;
+            break;
+
+        case 24u:
+            aesCfgKeyCfg = 1u;
+            keyWords     = 6;
+            break;
+
+        case 32u:
+            aesCfgKeyCfg = 2u;
+            keyWords     = 8;
+            break;
+
+        default:
+            keyWords = 0;
+            break;
+    }
+
+    if (!keyWords)
+    {
+        /* invalidate a possibly valid key. user attempted to set a key but gives incorrect size. */
+        base->CMD = AES_CMD_WIPE(1);
+        /* wait for Idle */
+        while (!(base->STAT & AES_STAT_IDLE_MASK))
+        {
+        }
+        base->CMD = AES_CMD_WIPE(0u);
+        return kStatus_InvalidArgument;
+    }
+
+    aesCfg = base->CFG;
+    aesCfg &= ~AES_CFG_KEY_CFG_MASK;
+    aesCfg |= AES_CFG_KEY_CFG(aesCfgKeyCfg);
+    base->CFG = aesCfg;
+
+    for (index = 0; index < keyWords; index++)
+    {
+        base->KEY[index] = swap_bytes(aes_get_word_from_unaligned(key));
+        key += sizeof(uint32_t);
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * @brief AES process one 16-byte block.
+ *
+ * This function pushes 16 bytes of data to INTEXT and pops 16 bytes of data from OUTTEXT.
+ *
+ * @param base AES peripheral base address.
+ * @param[out] output 16-byte block read from the OUTTEXT registers.
+ * @param input 16-byte block written to the INTEXT registers.
+ */
+static void aes_one_block(AES_Type *base, uint8_t *output, const uint8_t *input)
+{
+    int index;
+    uint32_t aesStat;
+
+    /* If the IN_READY bit in STAT register is 1, write the input text in the INTEXT [3:0]
+       registers. */
+    index = 0;
+    while (index < 4)
+    {
+        aesStat = base->STAT;
+
+        if (aesStat & AES_STAT_IN_READY_MASK)
+        {
+            base->INTEXT[index] = aes_get_word_from_unaligned(input);
+            input += sizeof(uint32_t);
+            index++;
+        }
+    }
+
+    index = 0;
+    while (index < 4)
+    {
+        aesStat = base->STAT;
+
+        if (aesStat & AES_STAT_OUT_READY_MASK)
+        {
+            aes_set_unaligned_from_word(base->OUTTEXT[index], output);
+            output += sizeof(uint32_t);
+            index++;
+        }
+    }
+}
+
+/*!
+ * @brief AES switch to forward mode.
+ *
+ * This function sets the AES to forward mode if it is in reverse mode.
+ *
+ * @param base AES peripheral base address.
+ */
+static void aes_set_forward(AES_Type *base)
+{
+    if (AES_STAT_REVERSE_MASK == (base->STAT & AES_STAT_REVERSE_MASK))
+    {
+        /* currently in reverse, switch to forward */
+        base->CMD = AES_CMD_SWITCH_MODE(1u);
+
+        /* wait for Idle */
+        while (!(base->STAT & AES_STAT_IDLE_MASK))
+        {
+        }
+
+        base->CMD = AES_CMD_SWITCH_MODE(0u);
+    }
+}
+
+/*!
+ * @brief AES switch to reverse mode.
+ *
+ * This function sets the AES to reverse mode if it is in forward mode.
+ *
+ * @param base AES peripheral base address.
+ */
+static void aes_set_reverse(AES_Type *base)
+{
+    if (!(base->STAT & AES_STAT_REVERSE_MASK))
+    {
+        /* currently in forward, switch to reverse */
+        base->CMD = AES_CMD_SWITCH_MODE(1u);
+
+        /* wait for Idle */
+        while (!(base->STAT & AES_STAT_IDLE_MASK))
+        {
+        }
+
+        base->CMD = AES_CMD_SWITCH_MODE(0u);
+    }
+}
+
+/*!
+ * @brief AES write HOLDING registers.
+ *
+ * This function writes input 16-byte data to AES HOLDING registers.
+ *
+ * @param base AES peripheral base address.
+ * @param input 16-byte input data.
+ */
+static void aes_set_holding(AES_Type *base, const uint8_t *input)
+{
+    int index;
+
+    for (index = 0; index < 4; index++)
+    {
+        base->HOLDING[index] = swap_bytes(aes_get_word_from_unaligned(input));
+        input += sizeof(uint32_t);
+    }
+}
+
+/*!
+ * @brief AES check KEY_VALID.
+ *
+ * This function check the KEY_VALID bit in AES status register.
+ *
+ * @param base AES peripheral base address.
+ * @return kStatus_Success if the key is valid.
+ * @return kStatus_InvalidArgument if the key is invalid.
+ */
+static status_t aes_check_key_valid(AES_Type *base)
+{
+    status_t status;
+
+    /* Check the key is valid */
+    status =
+        (AES_STAT_KEY_VALID_MASK == (base->STAT & AES_STAT_KEY_VALID_MASK)) ? kStatus_Success : kStatus_InvalidArgument;
+
+    return status;
+}
+
+/*!
+ * brief Sets AES key.
+ *
+ * Sets AES key.
+ *
+ * param base AES peripheral base address
+ * param key Input key to use for encryption or decryption
+ * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
+ * return Status from Set Key operation
+ */
+status_t AES_SetKey(AES_Type *base, const uint8_t *key, size_t keySize)
+{
+    return aes_load_key(base, key, keySize);
+}
+
+/*!
+ * brief Encrypts AES using the ECB block mode.
+ *
+ * Encrypts AES using the ECB block mode.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptEcb(AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size)
+{
+    status_t status;
+
+    /* ECB mode, size must be 16-byte multiple */
+    if (size % 16u)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /*5. Select the required crypto operation (encryption/decryption/hash) and AES mode in the CFG register.*/
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgEncryptEcb;
+
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /* make sure AES is set to forward mode */
+    aes_set_forward(base);
+
+    while (size)
+    {
+        aes_one_block(base, ciphertext, plaintext);
+        ciphertext += 16;
+        plaintext += 16;
+        size -= 16u;
+    }
+
+    return status;
+}
+
+/*!
+ * brief Decrypts AES using the ECB block mode.
+ *
+ * Decrypts AES using the ECB block mode.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input ciphertext to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptEcb(AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size)
+{
+    status_t status;
+
+    /* ECB mode, size must be 16-byte multiple */
+    if (size % 16u)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /*5. Select the required crypto operation (encryption/decryption/hash) and AES mode in the CFG register.*/
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgDecryptEcb;
+
+    /* make sure AES is set to reverse mode */
+    aes_set_reverse(base);
+
+    while (size)
+    {
+        aes_one_block(base, plaintext, ciphertext);
+        ciphertext += 16;
+        plaintext += 16;
+        size -= 16u;
+    }
+
+    return status;
+}
+
+/*!
+ * @brief Main function for CBC, CFB and OFB modes.
+ *
+ * @param base AES peripheral base address
+ * @param input Input plaintext for encryption, input ciphertext for decryption.
+ * @param[out] output Output ciphertext for encryption, output plaintext for decryption.
+ * @param size Size of input and output data in bytes. For CBC and CFB it must be multiple of 16-bytes.
+ * @param iv Input initial vector to combine with the first input block.
+ * @return Status from the operation.
+ */
+static status_t aes_block_mode(AES_Type *base,
+                               const uint8_t *input,
+                               uint8_t *output,
+                               size_t size,
+                               const uint8_t iv[AES_IV_SIZE],
+                               aes_configuration_t configuration)
+{
+    status_t status;
+
+    /* CBC and CFB128 mode, size must be 16-byte multiple */
+    switch (configuration)
+    {
+        case kAES_CfgEncryptCfb:
+        case kAES_CfgDecryptCfb:
+        case kAES_CfgEncryptCbc:
+        case kAES_CfgDecryptCbc:
+            if (size % 16u)
+            {
+                status = kStatus_InvalidArgument;
+            }
+            else
+            {
+                status = kStatus_Success;
+            }
+            break;
+
+        case kAES_CfgCryptOfb:
+            status = kStatus_Success;
+            break;
+
+        default:
+            status = kStatus_InvalidArgument;
+            break;
+    }
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /* Check the key is valid */
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /*5. Select the required crypto operation (encryption/decryption/hash) and AES mode in the CFG register.*/
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)configuration;
+
+    /* CBC decrypt use reverse AES cipher. */
+    switch (configuration)
+    {
+        case kAES_CfgDecryptCbc:
+            aes_set_reverse(base);
+            break;
+
+        default:
+            aes_set_forward(base);
+            break;
+    }
+
+    /* For CBC, CFB and OFB modes write the Initialization Vector (IV) in the HOLDING
+       [3:0] registers. For CTR mode write the initial counter value in the HOLDING [3:0]
+       registers. */
+    aes_set_holding(base, iv);
+
+    while (size >= 16u)
+    {
+        aes_one_block(base, output, input);
+        size -= 16u;
+        output += 16;
+        input += 16;
+    }
+
+    /* OFB can have non-block multiple size. CBC and CFB128 have size zero at this moment. */
+    if (size)
+    {
+        uint8_t blkTemp[16] = {0};
+
+        aes_memcpy(blkTemp, input, size);
+        aes_one_block(base, blkTemp, blkTemp);
+        aes_memcpy(output, blkTemp, size);
+    }
+
+    return status;
+}
+
+/*!
+ * brief Encrypts AES using CBC block mode.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input initial vector to combine with the first input block.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptCbc(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, plaintext, ciphertext, size, iv, kAES_CfgEncryptCbc);
+}
+
+/*!
+ * brief Decrypts AES using CBC block mode.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input initial vector to combine with the first input block.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptCbc(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, ciphertext, plaintext, size, iv, kAES_CfgDecryptCbc);
+}
+
+/*!
+ * brief Encrypts AES using CFB block mode.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input Initial vector to be used as the first input block.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptCfb(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, plaintext, ciphertext, size, iv, kAES_CfgEncryptCfb);
+}
+
+/*!
+ * brief Decrypts AES using CFB block mode.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input Initial vector to be used as the first input block.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptCfb(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, ciphertext, plaintext, size, iv, kAES_CfgDecryptCfb);
+}
+
+/*!
+ * brief Encrypts AES using OFB block mode.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes.
+ * param iv Input Initial vector to be used as the first input block.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptOfb(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, plaintext, ciphertext, size, iv, kAES_CfgCryptOfb);
+}
+
+/*!
+ * brief Decrypts AES using OFB block mode.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes.
+ * param iv Input Initial vector to be used as the first input block.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptOfb(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, ciphertext, plaintext, size, iv, kAES_CfgCryptOfb);
+}
+
+/*!
+ * brief Encrypts or decrypts AES using CTR block mode.
+ *
+ * Encrypts or decrypts AES using CTR block mode.
+ * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
+ * The only difference between encryption and decryption is that, for encryption, the input argument
+ * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
+ * and the output argument is plain text.
+ *
+ * param base AES peripheral base address
+ * param input Input data for CTR block mode
+ * param[out] output Output data for CTR block mode
+ * param size Size of input and output data in bytes
+ * param[in,out] counter Input counter (updates on return)
+ * param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are
+ * not used.
+ * param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
+ * are not used.
+ * return Status from crypt operation
+ */
+status_t AES_CryptCtr(AES_Type *base,
+                      const uint8_t *input,
+                      uint8_t *output,
+                      size_t size,
+                      uint8_t counter[AES_BLOCK_SIZE],
+                      uint8_t counterlast[AES_BLOCK_SIZE],
+                      size_t *szLeft)
+{
+    status_t status;
+    uint32_t lastSize;
+    uint8_t lastBlock[AES_BLOCK_SIZE] = {0};
+    uint8_t *lastEncryptedCounter;
+
+    /* Check the key is valid */
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /*5. Select the required crypto operation (encryption/decryption/hash) and AES mode in the CFG register.*/
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgCryptCtr;
+    aes_set_forward(base);
+
+    /* For CBC, CFB and OFB modes write the Initialization Vector (IV) in the HOLDING
+       [3:0] registers. For CTR mode write the initial counter value in the HOLDING [3:0]
+       registers. */
+    aes_set_holding(base, counter);
+
+    /* set counter increment by one */
+    base->CTR_INCR = 0x1U;
+
+    /* Split the size into full 16-byte chunks and last incomplete block */
+    lastSize = 0U;
+    if (size <= 16U)
+    {
+        lastSize = size;
+        size     = 0U;
+    }
+    else
+    {
+        /* Process all 16-byte data chunks. */
+        lastSize = size % 16U;
+        if (lastSize == 0U)
+        {
+            lastSize = 16U;
+            size -= 16U;
+        }
+        else
+        {
+            size -= lastSize; /* size will be rounded down to 16 byte boundary. remaining bytes in lastSize */
+        }
+    }
+
+    /* full 16-byte blocks */
+    while (size)
+    {
+        aes_one_block(base, output, input);
+        size -= 16u;
+        input += 16;
+        output += 16;
+    }
+
+    /* last block */
+    if (counterlast)
+    {
+        lastEncryptedCounter = counterlast;
+    }
+    else
+    {
+        lastEncryptedCounter = lastBlock;
+    }
+    aes_one_block(base, lastEncryptedCounter, lastBlock); /* lastBlock is all zeroes, so I get directly ECB of the last
+                                                             counter, as the XOR with zeroes doesn't change */
+
+    /* remain output = input XOR counterlast */
+    for (uint32_t i = 0; i < lastSize; i++)
+    {
+        output[i] = input[i] ^ lastEncryptedCounter[i];
+    }
+
+    /* read counter value after last encryption */
+    aes_set_unaligned_from_word(swap_bytes(base->HOLDING[3]), &counter[12]);
+    aes_gcm_dec32(&counter[0]); /* TODO HW problem? (first time it increments HOLDING3 twice) */
+
+    if (szLeft)
+    {
+        *szLeft = 16U - lastSize;
+    }
+
+    return status;
+}
+
+/*!
+ * @brief AES write input to INTEXT registers.
+ *
+ * This function writes input 16-byte data to AES INTEXT registers
+ * and wait for the engine Idle.
+ *
+ * @param base AES peripheral base address.
+ * @param input 16-byte input data.
+ */
+static void aes_gcm_one_block_input_only(AES_Type *base, const uint8_t *input)
+{
+    int index;
+    uint32_t aesStat;
+
+    /* If the IN_READY bit in STAT register is 1, write the input text in the INTEXT [3:0]
+       registers. */
+    index = 0;
+    while (index < 4)
+    {
+        aesStat = base->STAT;
+
+        if (aesStat & AES_STAT_IN_READY_MASK)
+        {
+            base->INTEXT[index] = aes_get_word_from_unaligned(input);
+            input += sizeof(uint32_t);
+            index++;
+        }
+    }
+
+    while (0 == (base->STAT & AES_STAT_IDLE_MASK))
+    {
+    }
+}
+
+/*!
+ * @brief AES execute command.
+ *
+ * This function issues command to AES CMD register.
+ *
+ * @param base AES peripheral base address.
+ * @param cmdMask Bit mask for the command to be issued.
+ */
+static void aes_command(AES_Type *base, uint32_t cmdMask)
+{
+    base->CMD = cmdMask;
+    /* wait for Idle */
+    while (!(base->STAT & AES_STAT_IDLE_MASK))
+    {
+    }
+    base->CMD = 0;
+}
+
+/*!
+ * @brief AES read GCM_TAG.
+ *
+ * This function reads data from GCM_TAG registers.
+ *
+ * @param base AES peripheral base address.
+ * @param output 16 byte memory to write the GCM_TAG to.
+ */
+static void aes_gcm_get_tag(AES_Type *base, uint8_t *output)
+{
+    int index;
+
+    for (index = 0; index < 4; index++)
+    {
+        aes_set_unaligned_from_word(swap_bytes(base->GCM_TAG[index]), output);
+        output += sizeof(uint32_t);
+    }
+}
+
+/*!
+ * @brief AES GCM check validity of input arguments.
+ *
+ * This function checks the validity of input arguments.
+ *
+ * @param base AES peripheral base address.
+ * @param src Source address (plaintext or ciphertext).
+ * @param iv Initialization vector address.
+ * @param aad Additional authenticated data address.
+ * @param dst Destination address (plaintext or ciphertext).
+ * @param inputSize Size of input (same size as output) data in bytes.
+ * @param ivSize Size of Initialization vector in bytes.
+ * @param aadSize Size of additional data in bytes.
+ * @param tagSize Size of the GCM tag in bytes.
+ */
+static status_t aes_gcm_check_input_args(AES_Type *base,
+                                         const uint8_t *src,
+                                         const uint8_t *iv,
+                                         const uint8_t *aad,
+                                         uint8_t *dst,
+                                         size_t inputSize,
+                                         size_t ivSize,
+                                         size_t aadSize,
+                                         size_t tagSize)
+{
+    if (!base)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* tag can be NULL to skip tag processing */
+    if ((ivSize && (!iv)) || (aadSize && (!aad)) || (inputSize && ((!src) || (!dst))))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* octet length of tag (tagSize) must be element of 4,8,12,13,14,15,16 */
+    if (((tagSize > 16u) || (tagSize < 12u)) && (tagSize != 4u) && (tagSize != 8u))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* no IV AAD DATA makes no sense */
+    if (0 == (inputSize + ivSize + aadSize))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* check length of input strings. This is more strict than the GCM specificaiton due to 32-bit architecture.
+     * The API interface would work on 64-bit architecture as well, but as it has not been tested, let it limit to
+     * 32-bits.
+     */
+    if (!((ivSize >= 1u) && (sizeof(size_t) <= 4u)))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Increment a 16 byte integer.
+ *
+ * This function increments by one a 16 byte integer.
+ *
+ * @param input Pointer to a 16 byte integer to be incremented by one.
+ */
+static void aes_gcm_incr32(uint8_t *input)
+{
+    int i = 15;
+    while (input[i] == (uint8_t)0xFFu)
+    {
+        input[i] = (uint8_t)0x00u;
+        i--;
+        if (i < 0)
+        {
+            return;
+        }
+    }
+
+    if (i >= 0)
+    {
+        input[i] += (uint8_t)1u;
+    }
+}
+
+/*!
+ * @brief Decrement a 16 byte integer.
+ *
+ * This function decrements by one a 16 byte integer.
+ *
+ * @param input Pointer to a 16 byte integer to be decremented by one.
+ */
+static void aes_gcm_dec32(uint8_t *input)
+{
+    int i = 15;
+    while (input[i] == (uint8_t)0x00u)
+    {
+        input[i] = (uint8_t)0xFFu;
+        i--;
+        if (i < 0)
+        {
+            return;
+        }
+    }
+
+    if (i >= 0)
+    {
+        input[i] -= (uint8_t)1u;
+    }
+}
+
+/*!
+ * @brief AES read GF128_Z registers.
+ *
+ * This function reads AES module GF128_Z registers.
+ *
+ * @param base AES peripheral base address.
+ * @param input Pointer to a 16 byte integer to write the GF128_Z value to.
+ */
+static void aes_get_gf128(AES_Type *base, uint8_t *output)
+{
+    int i;
+    for (i = 0; i < 4; i++)
+    {
+        aes_set_unaligned_from_word(swap_bytes(base->GF128_Z[i]), output);
+        output += sizeof(uint32_t);
+    }
+}
+
+/*!
+ * @brief GCM process.
+ *
+ * This function is the main function for AES GCM encryption/decryption and tag generation/comparison.
+ *
+ * @param base AES peripheral base address.
+ * @param encryptMode Whether the actual operation is an encryption or a decryption.
+ * @param src Input plaintext for encryption or ciphertext for decryption.
+ * @param inputSize Size of input and output in bytes.
+ * @param iv Input initial vector.
+ * @param ivSize Size of initial vector in bytes.
+ * @param aad Additional authenticated data.
+ * @param aadSize Size of additional authenticated data in bytes.
+ * @param dst Output ciphertext for encryption or plaintext for decryption.
+ * @param tag For encryption, GCM tag output. For decryption, GCM tag input for comparison.
+ * @param tagSize Size of the GCM tag in bytes.
+ */
+static status_t aes_gcm_process(AES_Type *base,
+                                aes_encryption_decryption_mode_t encryptMode,
+                                const uint8_t *src,
+                                size_t inputSize,
+                                const uint8_t *iv,
+                                size_t ivSize,
+                                const uint8_t *aad,
+                                size_t aadSize,
+                                uint8_t *dst,
+                                uint8_t *tag,
+                                size_t tagSize)
+{
+    status_t status;
+    uint8_t blkZero[16] = {0};
+    uint8_t blkJ0[16]   = {0};
+    uint8_t blkTag[16]  = {0};
+    uint32_t saveSize;
+    uint32_t saveAadSize;
+    uint32_t saveIvSize;
+    uint8_t lastBlock[AES_BLOCK_SIZE] = {0};
+
+    status = aes_gcm_check_input_args(base, src, iv, aad, dst, inputSize, ivSize, aadSize, tagSize);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    saveSize    = inputSize;
+    saveAadSize = aadSize;
+    saveIvSize  = ivSize;
+
+    /* 1. Let H = CIPHK(0_128). */
+    *(volatile uint8_t *)((uint32_t)base) = (uint8_t)
+        kAES_CfgIntextSwap; /* do not swap OUTTEXT, as OUTTEXT is copied for further use into GF128_Y register */
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgEncryptEcb;
+
+    /* make sure AES is set to forward mode */
+    aes_set_forward(base);
+
+    /* move 128-bit zeroes to INTEXT */
+    aes_gcm_one_block_input_only(base, blkZero);
+
+    /* set COPY_TO_Y command */
+    aes_command(base, AES_CMD_COPY_TO_Y(1));
+
+    if (ivSize != 12u)
+    {
+        /* if ivSize is not 12 bytes, we have to compute GF128 hash to get the initial counter J0 */
+        uint8_t ivBlkZero[16] = {0};
+
+        *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwapIntextHashIn;
+        while (ivSize >= 16u)
+        {
+            aes_gcm_one_block_input_only(base, iv);
+            iv += 16;
+            ivSize -= 16u;
+        }
+        if (ivSize)
+        {
+            aes_memcpy(ivBlkZero, iv, ivSize);
+            aes_gcm_one_block_input_only(base, ivBlkZero);
+        }
+
+        aes_memcpy(ivBlkZero, blkZero, 16);
+        aes_set_unaligned_from_word(swap_bytes(8 * saveIvSize), &ivBlkZero[12]);
+        aes_gcm_one_block_input_only(base, ivBlkZero);
+
+        aes_get_gf128(base, blkJ0);
+        aes_gcm_incr32(blkJ0);
+
+        /* put back the hash sub-key. this will abort running GF128, because we have to start new GF128 again for AAD
+         * and C */
+        *(volatile uint8_t *)((uint32_t)base) = (uint8_t)
+            kAES_CfgIntextSwap; /* do not swap OUTTEXT, as OUTTEXT is copied for further use into GF128_Y register */
+        *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgEncryptEcb;
+        aes_gcm_one_block_input_only(base, blkZero);
+        aes_command(base, AES_CMD_COPY_TO_Y(1));
+    }
+    else
+    {
+        aes_memcpy(blkJ0, iv, 12);
+        blkJ0[15] = 0x02U; /* add one to Counter for the first encryption with plaintext - see GCM specification */
+    }
+
+    /* process all AAD as GF128 of INTEXT, pad to full 16-bytes block with zeroes */
+    if (aadSize)
+    {
+        *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwapIntextHashIn;
+        while (aadSize >= 16u)
+        {
+            aes_gcm_one_block_input_only(base, aad);
+            aad += 16;
+            aadSize -= 16u;
+        }
+        if (aadSize)
+        {
+            uint8_t aadBlkZero[16] = {0};
+            aes_memcpy(aadBlkZero, aad, aadSize);
+            aes_gcm_one_block_input_only(base, aadBlkZero);
+        }
+    }
+
+    /* switch to EnryptDecryptHash, Hash of OUTTEXT, EncryptDecrypt in GCM mode */
+    /* Process all plaintext, pad to full 16-bytes block with zeroes */
+    if (encryptMode == kAES_ModeEncrypt)
+    {
+        *(volatile uint8_t *)((uint32_t)base) =
+            (uint8_t)kAES_CfgSwapEnDecHashOut; /* Encrypt operation adds output to hash */
+    }
+    else
+    {
+        *(volatile uint8_t *)((uint32_t)base) =
+            (uint8_t)kAES_CfgSwapEnDecHashIn; /* Decrypt operation adds input to hash */
+    }
+
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t) /*kAES_CfgCryptGcmTag*/ kAES_CfgCryptCtr;
+
+    aes_set_holding(base, blkJ0);
+
+    /* set counter increment by one */
+    base->CTR_INCR = 0x1U;
+
+    if (inputSize)
+    {
+        /* full 16-byte blocks */
+        while (inputSize >= 16u)
+        {
+            aes_one_block(base, dst, src);
+            inputSize -= 16u;
+            src += 16;
+            dst += 16;
+        }
+        /* last incomplete block. output shall be padded. */
+        if (inputSize)
+        {
+            if (encryptMode == kAES_ModeEncrypt)
+            {
+                uint8_t outputBlkZero[16] = {0};
+
+                /* I need to pad ciphertext, so I turn off the hash, and after I have ciphertext, I pad it with zeroes
+                 * and hash manually */
+                *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwap;
+                aes_memcpy(lastBlock, src, inputSize);
+                aes_one_block(base, lastBlock, lastBlock);
+                aes_memcpy(dst, lastBlock, inputSize);
+                /* pad the last output block with zeroes and add it to GF128 hash */
+                aes_memcpy(outputBlkZero, lastBlock, inputSize);
+                *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwapIntextHashIn;
+                aes_gcm_one_block_input_only(base, outputBlkZero);
+            }
+            else
+            {
+                aes_memcpy(lastBlock, src, inputSize);
+                aes_one_block(base, lastBlock, lastBlock);
+                aes_memcpy(dst, lastBlock, inputSize);
+            }
+        }
+    }
+
+    /* Process AAD len plus Ciphertext len */
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgIntextSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgEncryptEcb;
+    aes_gcm_dec32(blkJ0);
+    aes_gcm_one_block_input_only(base, blkJ0);
+    *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwapIntextHashIn;
+    if (saveSize)
+    {
+        aes_set_unaligned_from_word(swap_bytes(saveSize * 8u), &blkZero[12]);
+    }
+    if (saveAadSize)
+    {
+        aes_set_unaligned_from_word(swap_bytes(saveAadSize * 8u), &blkZero[4]);
+    }
+    aes_gcm_one_block_input_only(base, blkZero); /* len(A) || len(C) */
+    aes_gcm_get_tag(base, blkTag);
+
+    if (tag && tagSize)
+    {
+        if (encryptMode == kAES_ModeEncrypt)
+        {
+            aes_memcpy(tag, blkTag, tagSize);
+        }
+        else
+        {
+            size_t i       = 0;
+            uint32_t equal = 0;
+            uint32_t chXor;
+
+            while (i < tagSize)
+            {
+                chXor = tag[i] ^ blkTag[i];
+                equal |= chXor;
+                i++;
+            }
+
+            if (equal != 0)
+            {
+                status = kStatus_Fail;
+            }
+        }
+    }
+
+    return status;
+}
+
+/*!
+ * brief Encrypts AES and tags using GCM block mode.
+ *
+ * Encrypts AES and optionally tags using GCM block mode. If plaintext is NULL, only the GHASH is calculated and output
+ * in the 'tag' field.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text.
+ * param size Size of input and output data in bytes
+ * param iv Input initial vector
+ * param ivSize Size of the IV
+ * param aad Input additional authentication data
+ * param aadSize Input size in bytes of AAD
+ * param[out] tag Output hash tag. Set to NULL to skip tag processing.
+ * param tagSize Input size of the tag to generate, in bytes. Must be 4,8,12,13,14,15 or 16.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptTagGcm(AES_Type *base,
+                           const uint8_t *plaintext,
+                           uint8_t *ciphertext,
+                           size_t size,
+                           const uint8_t *iv,
+                           size_t ivSize,
+                           const uint8_t *aad,
+                           size_t aadSize,
+                           uint8_t *tag,
+                           size_t tagSize)
+{
+    status_t status;
+    status =
+        aes_gcm_process(base, kAES_ModeEncrypt, plaintext, size, iv, ivSize, aad, aadSize, ciphertext, tag, tagSize);
+    return status;
+}
+
+/*!
+ * brief Decrypts AES and authenticates using GCM block mode.
+ *
+ * Decrypts AES and optionally authenticates using GCM block mode. If ciphertext is NULL, only the GHASH is calculated
+ * and compared with the received GHASH in 'tag' field.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text.
+ * param size Size of input and output data in bytes
+ * param iv Input initial vector
+ * param ivSize Size of the IV
+ * param aad Input additional authentication data
+ * param aadSize Input size in bytes of AAD
+ * param tag Input hash tag to compare. Set to NULL to skip tag processing.
+ * param tagSize Input size of the tag, in bytes. Must be 4, 8, 12, 13, 14, 15, or 16.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptTagGcm(AES_Type *base,
+                           const uint8_t *ciphertext,
+                           uint8_t *plaintext,
+                           size_t size,
+                           const uint8_t *iv,
+                           size_t ivSize,
+                           const uint8_t *aad,
+                           size_t aadSize,
+                           const uint8_t *tag,
+                           size_t tagSize)
+{
+    uint8_t temp_tag[16] = {0}; /* max. octet length of MAC (tag) is 16 */
+    uint8_t *tag_ptr;
+    status_t status;
+
+    tag_ptr = NULL;
+    if (tag)
+    {
+        aes_memcpy(temp_tag, tag, tagSize);
+        tag_ptr = &temp_tag[0];
+    }
+
+    status = aes_gcm_process(base, kAES_ModeDecrypt, ciphertext, size, iv, ivSize, aad, aadSize, plaintext, tag_ptr,
+                             tagSize);
+    return status;
+}
+
+void AES_Init(AES_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* ungate clock */
+    CLOCK_EnableClock(kCLOCK_Aes);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+void AES_Deinit(AES_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* gate clock */
+    CLOCK_DisableClock(kCLOCK_Aes);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_aes.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_aes.h
new file mode 100755
index 0000000..7f7cf87
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_aes.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_AES_H_
+#define _FSL_AES_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup aes
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief Defines LPC AES driver version 2.0.1.
+ *
+ * Change log:
+ * - Version 2.0.0
+ *   - initial version
+ * - Version 2.0.1
+ *   - GCM constant time tag comparison
+ */
+#define FSL_AES_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
+/*@}*/
+
+/*******************************************************************************
+ * API
+ *******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @name AES Functional Operation
+ * @{
+ */
+
+/*! AES block size in bytes */
+#define AES_BLOCK_SIZE 16
+/*! AES Input Vector size in bytes */
+#define AES_IV_SIZE 16
+
+/*!
+ * @brief Sets AES key.
+ *
+ * Sets AES key.
+ *
+ * @param base AES peripheral base address
+ * @param key Input key to use for encryption or decryption
+ * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
+ * @return Status from Set Key operation
+ */
+status_t AES_SetKey(AES_Type *base, const uint8_t *key, size_t keySize);
+
+/*!
+ * @brief Encrypts AES using the ECB block mode.
+ *
+ * Encrypts AES using the ECB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptEcb(AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size);
+
+/*!
+ * @brief Decrypts AES using the ECB block mode.
+ *
+ * Decrypts AES using the ECB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input ciphertext to decrypt
+ * @param[out] plaintext Output plain text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptEcb(AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size);
+
+/*!
+ * @brief Encrypts AES using CBC block mode.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @param iv Input initial vector to combine with the first input block.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptCbc(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Decrypts AES using CBC block mode.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input cipher text to decrypt
+ * @param[out] plaintext Output plain text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @param iv Input initial vector to combine with the first input block.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptCbc(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Encrypts AES using CFB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @param iv Input Initial vector to be used as the first input block.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptCfb(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Decrypts AES using CFB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input cipher text to decrypt
+ * @param[out] plaintext Output plain text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @param iv Input Initial vector to be used as the first input block.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptCfb(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Encrypts AES using OFB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text
+ * @param size Size of input and output data in bytes.
+ * @param iv Input Initial vector to be used as the first input block.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptOfb(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Decrypts AES using OFB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input cipher text to decrypt
+ * @param[out] plaintext Output plain text
+ * @param size Size of input and output data in bytes.
+ * @param iv Input Initial vector to be used as the first input block.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptOfb(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Encrypts or decrypts AES using CTR block mode.
+ *
+ * Encrypts or decrypts AES using CTR block mode.
+ * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
+ * The only difference between encryption and decryption is that, for encryption, the input argument
+ * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
+ * and the output argument is plain text.
+ *
+ * @param base AES peripheral base address
+ * @param input Input data for CTR block mode
+ * @param[out] output Output data for CTR block mode
+ * @param size Size of input and output data in bytes
+ * @param[in,out] counter Input counter (updates on return)
+ * @param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are
+ * not used.
+ * @param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
+ * are not used.
+ * @return Status from crypt operation
+ */
+status_t AES_CryptCtr(AES_Type *base,
+                      const uint8_t *input,
+                      uint8_t *output,
+                      size_t size,
+                      uint8_t counter[AES_BLOCK_SIZE],
+                      uint8_t counterlast[AES_BLOCK_SIZE],
+                      size_t *szLeft);
+
+/*!
+ * @brief Encrypts AES and tags using GCM block mode.
+ *
+ * Encrypts AES and optionally tags using GCM block mode. If plaintext is NULL, only the GHASH is calculated and output
+ * in the 'tag' field.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text.
+ * @param size Size of input and output data in bytes
+ * @param iv Input initial vector
+ * @param ivSize Size of the IV
+ * @param aad Input additional authentication data
+ * @param aadSize Input size in bytes of AAD
+ * @param[out] tag Output hash tag. Set to NULL to skip tag processing.
+ * @param tagSize Input size of the tag to generate, in bytes. Must be 4,8,12,13,14,15 or 16.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptTagGcm(AES_Type *base,
+                           const uint8_t *plaintext,
+                           uint8_t *ciphertext,
+                           size_t size,
+                           const uint8_t *iv,
+                           size_t ivSize,
+                           const uint8_t *aad,
+                           size_t aadSize,
+                           uint8_t *tag,
+                           size_t tagSize);
+
+/*!
+ * @brief Decrypts AES and authenticates using GCM block mode.
+ *
+ * Decrypts AES and optionally authenticates using GCM block mode. If ciphertext is NULL, only the GHASH is calculated
+ * and compared with the received GHASH in 'tag' field.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input cipher text to decrypt
+ * @param[out] plaintext Output plain text.
+ * @param size Size of input and output data in bytes
+ * @param iv Input initial vector
+ * @param ivSize Size of the IV
+ * @param aad Input additional authentication data
+ * @param aadSize Input size in bytes of AAD
+ * @param tag Input hash tag to compare. Set to NULL to skip tag processing.
+ * @param tagSize Input size of the tag, in bytes. Must be 4, 8, 12, 13, 14, 15, or 16.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptTagGcm(AES_Type *base,
+                           const uint8_t *ciphertext,
+                           uint8_t *plaintext,
+                           size_t size,
+                           const uint8_t *iv,
+                           size_t ivSize,
+                           const uint8_t *aad,
+                           size_t aadSize,
+                           const uint8_t *tag,
+                           size_t tagSize);
+
+void AES_Init(AES_Type *base);
+
+void AES_Deinit(AES_Type *base);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @}*/
+/*! @}*/ /* end of group aes */
+
+#endif /* _FSL_AES_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_clock.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_clock.c
new file mode 100755
index 0000000..4081940
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_clock.c
@@ -0,0 +1,1191 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_clock.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.clock"
+#endif
+#define OSC32K_FREQ 32768UL
+#define FRO32K_FREQ 32768UL
+#define OSC32M_FREQ 32000000UL
+#define XTAL32M_FREQ 32000000UL
+#define FRO64M_FREQ 64000000UL
+#define FRO1M_FREQ 1000000UL
+#define FRO12M_FREQ 12000000UL
+#define FRO32M_FREQ 32000000UL
+#define FRO48M_FREQ 48000000UL
+
+/* Return values from Config (N-2) page of flash */
+#define GET_CAL_DATE() (*(uint32_t *)0x9FC68)
+#define GET_32MXO_TRIM() (*(uint32_t *)0x9FCF0)
+#define GET_32KXO_TRIM() (*(uint32_t *)0x9FCF4)
+#define GET_ATE_TEMP() (*(uint32_t *)0x9FDC8)
+
+#define XO_SLAVE_EN (1)
+
+/*******************************************************************************
+ * Storage
+ ******************************************************************************/
+/** External clock rate on the CLKIN pin in Hz. If not used,
+    set this to 0. Otherwise, set it to the exact rate in Hz this pin is
+    being driven at. */
+const uint32_t g_Ext_Clk_Freq = 0U;
+
+#define CLOCK_32MfXtalIecLoadpF_x100_default (600)   /* 6.0pF */
+#define CLOCK_32MfXtalPPcbParCappF_x100_default (10) /* 0.1pF */
+#define CLOCK_32MfXtalNPcbParCappF_x100_default (5)  /* 0.05pF */
+
+const ClockCapacitanceCompensation_t default_Clock32MCapacitanceCharacteristics = {
+    .clk_XtalIecLoadpF_x100    = CLOCK_32MfXtalIecLoadpF_x100_default,
+    .clk_XtalPPcbParCappF_x100 = CLOCK_32MfXtalPPcbParCappF_x100_default,
+    .clk_XtalNPcbParCappF_x100 = CLOCK_32MfXtalNPcbParCappF_x100_default};
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+uint32_t CLOCK_GetOsc32kFreq(void);
+uint32_t CLOCK_GetOsc32MFreq(void);
+uint32_t CLOCK_GetFRGInputClock(void);
+/*! brief      Return Frequency of Spifi Clock
+ *  return     Frequency of Spifi.
+ */
+uint32_t CLOCK_GetSpifiClkFreq(void);
+uint32_t CLOCK_GetAdcClock(void);
+uint32_t CLOCK_GetSystemClockRate(void);
+uint32_t CLOCK_GetCoreSysClkFreq(void);
+uint32_t CLOCK_GetMainClockRate(void);
+uint32_t CLOCK_GetXtal32kFreq(void);
+uint32_t CLOCK_GetXtal32MFreq(void);
+uint32_t CLOCK_GetFro32kFreq(void);
+uint32_t CLOCK_GetFro1MFreq(void);
+uint32_t CLOCK_GetFro12MFreq(void);
+uint32_t CLOCK_GetFro32MFreq(void);
+uint32_t CLOCK_GetFro48MFreq(void);
+uint32_t CLOCK_GetFro64MFreq(void);
+uint32_t CLOCK_GetSpifiOscFreq(void);
+uint32_t CLOCK_GetWdtOscFreq(void);
+uint32_t CLOCK_GetPWMClockFreq(void);
+
+static uint8_t CLOCK_u8OscCapConvert(uint32_t OscCap, uint8_t u8CapBankDiscontinuity);
+
+/*******************************************************************************
+ * types
+ ******************************************************************************/
+
+/**
+ * brief	Selects clock source using <name>SEL register in syscon
+ * param   clock_attach_id_t  specify clock mapping
+ * return	none
+ * note
+ */
+void CLOCK_AttachClk(clock_attach_id_t connection)
+{
+    uint8_t mux;
+    uint8_t pos;
+    volatile uint32_t *pClkSel;
+    clock_div_name_t clockDiv = kCLOCK_DivNone;
+
+    pClkSel = (uint32_t *)SYSCON;
+
+    switch (connection)
+    {
+        case kXTAL32M_to_MAIN_CLK:
+        case kXTAL32M_to_OSC32M_CLK:
+        case kXTAL32M_to_CLKOUT:
+        case kXTAL32M_to_SPIFI:
+        case kXTAL32M_to_ADC_CLK:
+        case kXTAL32M_to_ASYNC_APB:
+            /* Enable the 32MHz clock distribution to digital core (CGU, MCU) */
+            ASYNC_SYSCON->XTAL32MCTRL |= ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_MASK;
+            break;
+
+        default:
+            break;
+    }
+
+    switch (connection & 0xFFF)
+    {
+        case CM_CLKOUTCLKSEL:
+            clockDiv = kCLOCK_DivClkout;
+            break;
+        case CM_SPIFICLKSEL:
+            clockDiv = kCLOCK_DivSpifiClk;
+            break;
+        case CM_ADCCLKSEL:
+            clockDiv = kCLOCK_DivAdcClk;
+            break;
+        case CM_IRCLKSEL:
+            clockDiv = kCLOCK_DivIrClk;
+            break;
+        case CM_WDTCLKSEL:
+            clockDiv = kCLOCK_DivWdtClk;
+            break;
+        case CM_DMICLKSEL:
+            clockDiv = kCLOCK_DivDmicClk;
+            break;
+        default:
+            break;
+    }
+
+    if (clockDiv != 0)
+    {
+        pClkSel[clockDiv] |= (1U << 30U); /* halts the divider counter to avoid glitch */
+    }
+
+    mux = (uint8_t)(connection & 0xfff);
+    if (((uint32_t)connection) != 0)
+    {
+        pos = (uint8_t)((connection & 0xf000U) >> 12U) - 1U;
+        if (mux == CM_ASYNCAPB)
+        {
+            ASYNC_SYSCON->ASYNCAPBCLKSELA = pos;
+        }
+        else if (mux == CM_OSC32CLKSEL)
+        {
+            if (pos < 2)
+            {
+                pClkSel[mux] &= ~SYSCON_OSC32CLKSEL_SEL32MHZ_MASK;
+                pClkSel[mux] |= pos;
+            }
+            else
+            {
+                pClkSel[mux] &= ~SYSCON_OSC32CLKSEL_SEL32KHZ_MASK;
+                pClkSel[mux] |= ((pos - 2) << SYSCON_OSC32CLKSEL_SEL32KHZ_SHIFT);
+            }
+        }
+        else if (mux == CM_MODEMCLKSEL)
+        {
+            pClkSel[mux] |= SYSCON_MODEMCLKSEL_SEL_ZIGBEE_MASK;
+            pClkSel[mux] &= ((uint32_t)pos | 0xfffeU);
+        }
+        else
+        {
+            pClkSel[mux] = pos;
+        }
+    }
+
+    if (clockDiv != 0)
+    {
+        pClkSel[clockDiv] &= ~(1U << 30U); /* release the divider counter */
+    }
+}
+
+/**
+ * brief	Selects clock divider using <name>DIV register in syscon
+ * param   clock_div_name_t  	specifies which DIV register we are accessing
+ * param   uint32_t			specifies divisor
+ * param	bool				true if a syscon clock reset should also be carried out
+ * return	none
+ * note
+ */
+void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
+{
+    volatile uint32_t *pClkDiv;
+    pClkDiv = (uint32_t *)SYSCON;
+
+    pClkDiv[div_name] |= (1U << 30U); /* halts the divider counter to avoid glitch */
+
+    if (divided_by_value != 0U)
+    {
+        pClkDiv[div_name] = (1U << 30U) | (divided_by_value - 1U);
+    }
+
+    if (reset)
+    {
+        pClkDiv[div_name] |= 1U << 29U;
+        pClkDiv[div_name] &= ~(1U << 29U);
+    }
+
+    pClkDiv[div_name] &= ~(1U << 30U); /* release the divider counter */
+}
+
+uint32_t CLOCK_GetClkDiv(clock_div_name_t div_name)
+{
+    volatile uint32_t *pClkDiv;
+    uint32_t div = 0;
+
+    pClkDiv = (uint32_t *)SYSCON;
+    div     = pClkDiv[div_name] + 1;
+
+    return div;
+}
+
+uint32_t CLOCK_GetFRGInputClock(void)
+{
+    uint32_t freq = 0;
+
+    switch ((frg_clock_src_t)((SYSCON->FRGCLKSEL & SYSCON_FRGCLKSEL_SEL_MASK) >> SYSCON_FRGCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_FrgMainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+
+        case kCLOCK_FrgOsc32MClk:
+            freq = CLOCK_GetOsc32MFreq();
+            break;
+
+        case kCLOCK_FrgFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+
+        case kCLOCK_FrgNoClock:
+            freq = 0;
+            break;
+
+        default:
+            freq = 0;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_SetFRGClock(uint32_t freq)
+{
+    uint32_t input = CLOCK_GetFRGInputClock();
+    uint32_t mul;
+
+    if ((freq > 48000000) || (freq > input) || ((freq != 0) && (input / freq >= 2)))
+    {
+        /* FRG output frequency should be less than equal to 48MHz */
+        return 0;
+    }
+    else
+    {
+        mul             = ((uint64_t)(input - freq) * 256) / ((uint64_t)freq);
+        SYSCON->FRGCTRL = (mul << SYSCON_FRGCTRL_MULT_SHIFT) | SYSCON_FRGCTRL_DIV_MASK;
+        return 1;
+    }
+}
+
+uint32_t CLOCK_GetFRGClock(void)
+{
+    uint32_t freq = 0;
+
+    if (((SYSCON->FRGCTRL & SYSCON_FRGCTRL_DIV_MASK) >> SYSCON_FRGCTRL_DIV_SHIFT) == 255)
+    {
+        // We can use a shift here since only divide by 256 is supported
+        freq = ((uint64_t)CLOCK_GetFRGInputClock() << 8) /
+               (((SYSCON->FRGCTRL & SYSCON_FRGCTRL_MULT_MASK) >> SYSCON_FRGCTRL_MULT_SHIFT) + 256);
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetClkOutFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((clkout_clock_src_t)((SYSCON->CLKOUTSEL & SYSCON_CLKOUTSEL_SEL_MASK) >> SYSCON_CLKOUTSEL_SEL_SHIFT))
+    {
+        case kCLOCK_ClkoutMainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+
+        case kCLOCK_ClkoutXtal32k:
+            freq = CLOCK_GetXtal32kFreq();
+            break;
+
+        case kCLOCK_ClkoutFro32k:
+            freq = CLOCK_GetFro32kFreq();
+            break;
+
+        case kCLOCK_ClkoutXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_ClkoutDcDcTest:
+            freq = CLOCK_GetFro64MFreq();
+            break;
+
+        case kCLOCK_ClkoutFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        case kCLOCK_ClkoutFro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+        case kCLOCK_ClkoutNoClock:
+            freq = 0;
+            break;
+        default:
+            freq = 0;
+            break;
+    }
+
+    freq /= (((SYSCON->CLKOUTDIV & SYSCON_CLKOUTDIV_DIV_MASK) >> SYSCON_CLKOUTDIV_DIV_SHIFT) + 1);
+
+    return freq;
+}
+
+uint32_t CLOCK_GetWdtOscFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((wdt_clock_src_t)((SYSCON->WDTCLKSEL & SYSCON_WDTCLKSEL_SEL_MASK) >> SYSCON_WDTCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_WdtOsc32MClk:
+            freq = CLOCK_GetOsc32MFreq();
+            break;
+
+        case kCLOCK_WdtOsc32kClk:
+            freq = CLOCK_GetOsc32kFreq();
+            break;
+
+        case kCLOCK_WdtFro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+
+        case kCLOCK_WdtNoClock:
+            freq = 0;
+            break;
+
+        default:
+            freq = 0;
+            break;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetSpifiOscFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((spifi_clock_src_t)((SYSCON->SPIFICLKSEL & SYSCON_SPIFICLKSEL_SEL_MASK) >> SYSCON_SPIFICLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_SpifiMainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+        case kCLOCK_SpifiXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+        case kCLOCK_SpifiFro64M:
+            freq = CLOCK_GetFro64MFreq();
+            break;
+        case kCLOCK_SpifiFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        case kCLOCK_SpifiNoClock:
+            freq = 0;
+            break;
+        default:
+            freq = 0;
+            break;
+    }
+    freq /= (((SYSCON->SPIFICLKDIV & SYSCON_SPIFICLKDIV_DIV_MASK) >> SYSCON_SPIFICLKDIV_DIV_SHIFT) + 1);
+
+    return freq;
+}
+
+uint32_t CLOCK_GetPWMClockFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((pwm_clock_source_t)((SYSCON->PWMCLKSEL & SYSCON_PWMCLKSEL_SEL_MASK) >> SYSCON_PWMCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_PWMOsc32Mclk:
+            freq = CLOCK_GetOsc32MFreq();
+            break;
+        case kCLOCK_PWMFro48Mclk:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        case kCLOCK_PWMNoClkSel:
+            freq = 0;
+            break;
+        case kCLOCK_PWMTestClk:
+            freq = 0;
+            break;
+    }
+
+    return freq;
+}
+
+/**
+ * brief	Obtains frequency of specified clock
+ * param   clock_name_t  specify clock to be read
+ * return	uint32_t      frequency
+ * note
+ */
+uint32_t CLOCK_GetFreq(clock_name_t clockName)
+{
+    uint32_t freq = 0;
+    switch (clockName)
+    {
+        case kCLOCK_MainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+        case kCLOCK_CoreSysClk:
+            freq = CLOCK_GetCoreSysClkFreq();
+            break;
+        case kCLOCK_BusClk:
+            freq = CLOCK_GetCoreSysClkFreq();
+            break;
+        case kCLOCK_Xtal32k:
+            freq = CLOCK_GetXtal32kFreq();
+            break;
+        case kCLOCK_Xtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+        case kCLOCK_Fro32k:
+            freq = CLOCK_GetFro32kFreq();
+            break;
+        case kCLOCK_Fro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+        case kCLOCK_Fro12M:
+            freq = CLOCK_GetFro12MFreq();
+            break;
+        case kCLOCK_Fro32M:
+            freq = CLOCK_GetFro32MFreq();
+            break;
+        case kCLOCK_Fro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        case kCLOCK_Fro64M:
+            freq = CLOCK_GetFro64MFreq();
+            break;
+        case kCLOCK_ExtClk:
+            freq = g_Ext_Clk_Freq;
+            break;
+        case kCLOCK_WdtOsc:
+            freq = CLOCK_GetWdtOscFreq() / ((SYSCON->WDTCLKDIV & SYSCON_WDTCLKDIV_DIV_MASK) + 1);
+            ;
+            break;
+        case kCLOCK_Frg:
+            freq = CLOCK_GetFRGClock();
+            break;
+        case kCLOCK_ClkOut:
+            freq = CLOCK_GetClkOutFreq();
+            break;
+        case kCLOCK_Spifi:
+            freq = CLOCK_GetSpifiOscFreq();
+            break;
+        case kCLOCK_WdtClk:
+            freq = CLOCK_GetWdtOscFreq() / ((SYSCON->WDTCLKDIV & SYSCON_WDTCLKDIV_DIV_MASK) + 1);
+            break;
+        case kCLOCK_Pwm:
+            freq = CLOCK_GetPWMClockFreq();
+            break;
+        case kCLOCK_Timer0:
+        case kCLOCK_Timer1:
+            freq = CLOCK_GetApbCLkFreq();
+            break;
+        default:
+            freq = 0;
+            break;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetCoreSysClkFreq(void)
+{
+    /* No point in checking for divide by 0 */
+    return CLOCK_GetMainClockRate() / ((SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK) + 1U);
+}
+
+/* Return main clock rate */
+uint32_t CLOCK_GetMainClockRate(void)
+{
+    uint32_t freq = 0;
+
+    switch ((main_clock_src_t)((SYSCON->MAINCLKSEL & SYSCON_MAINCLKSEL_SEL_MASK) >> SYSCON_MAINCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_MainFro12M:
+            freq = CLOCK_GetFro12MFreq();
+            break;
+
+        case kCLOCK_MainOsc32k:
+            freq = CLOCK_GetOsc32kFreq();
+            break;
+
+        case kCLOCK_MainXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_MainFro32M:
+            freq = CLOCK_GetFro32MFreq();
+            break;
+
+        case kCLOCK_MainFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+
+        case kCLOCK_MainExtClk:
+            freq = g_Ext_Clk_Freq;
+            break;
+
+        case kCLOCK_MainFro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetOsc32kFreq(void)
+{
+    uint32_t freq = 0;
+    if ((SYSCON->OSC32CLKSEL & SYSCON_OSC32CLKSEL_SEL32KHZ_MASK) != 0)
+    {
+        freq = CLOCK_GetXtal32kFreq();
+    }
+    else
+    {
+        freq = CLOCK_GetFro32kFreq();
+    }
+    return freq;
+}
+
+uint32_t CLOCK_GetOsc32MFreq(void)
+{
+    uint32_t freq = 0;
+    if ((SYSCON->OSC32CLKSEL & SYSCON_OSC32CLKSEL_SEL32MHZ_MASK) != 0)
+    {
+        freq = CLOCK_GetXtal32MFreq();
+    }
+    else
+    {
+        freq = CLOCK_GetFro32MFreq();
+    }
+    return freq;
+}
+
+uint32_t CLOCK_GetXtal32kFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_XTAL32K_MASK) >> PMC_PDRUNCFG_ENA_XTAL32K_SHIFT) != 0)
+    {
+        freq = OSC32K_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetXtal32MFreq(void)
+{
+    return XTAL32M_FREQ;
+}
+
+uint32_t CLOCK_GetFro32kFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_FRO32K_MASK) >> PMC_PDRUNCFG_ENA_FRO32K_SHIFT) != 0)
+    {
+        freq = FRO32K_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetFro1MFreq(void)
+{
+    return FRO1M_FREQ;
+}
+
+uint32_t CLOCK_GetFro12MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO12M_ENA)
+    {
+        freq = FRO12M_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetFro32MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO32M_ENA)
+    {
+        freq = FRO32M_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetFro48MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO48M_ENA)
+    {
+        freq = FRO48M_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetFro64MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO64M_ENA)
+    {
+        freq = FRO64M_FREQ;
+    }
+
+    return freq;
+}
+
+/*! brief      Return Frequency of Spifi Clock
+ *  return     Frequency of Spifi.
+ */
+uint32_t CLOCK_GetSpifiClkFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((spifi_clock_src_t)((SYSCON->SPIFICLKSEL & SYSCON_SPIFICLKSEL_SEL_MASK) >> SYSCON_SPIFICLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_SpifiMainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+
+        case kCLOCK_SpifiXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_SpifiFro64M:
+            freq = CLOCK_GetFro64MFreq();
+            break;
+
+        case kCLOCK_SpifiFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+
+        case kCLOCK_SpifiNoClock:
+            freq = 0;
+            break;
+
+        default:
+            freq = 0;
+            break;
+    }
+
+    if (freq > 0)
+    {
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetAdcClock(void)
+{
+    uint32_t freq = 0;
+
+    switch ((adc_clock_src_t)((SYSCON->ADCCLKSEL) & SYSCON_ADCCLKSEL_SEL_MASK >> SYSCON_ADCCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_AdcXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_AdcFro12M:
+            freq = CLOCK_GetFro12MFreq();
+            break;
+
+        case kCLOCK_AdcNoClock:
+            freq = 0;
+            break;
+
+        default:
+            freq = 0;
+    }
+
+    if (freq > 0)
+    {
+        freq /= (((SYSCON->ADCCLKDIV & SYSCON_ADCCLKDIV_DIV_MASK) >> SYSCON_ADCCLKDIV_DIV_SHIFT) + 1);
+    }
+
+    return freq;
+}
+
+/**
+ * brief	Obtains frequency of APB Bus clock
+ * param   none
+ * return	uint32_t      frequency
+ * note
+ */
+uint32_t CLOCK_GetApbCLkFreq(void)
+{
+    uint32_t freq = 0;
+    /* ASYNCAPBCLKSEL[1:0] says which Clock Mux input is selected for APB */
+    switch (ASYNC_SYSCON->ASYNCAPBCLKSELA & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK)
+    {
+        case kCLOCK_ApbMainClk: /* Main Clk */
+            freq = CLOCK_GetMainClockRate();
+            break;
+        case kCLOCK_ApbXtal32M: /* XTAL 32M */
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+        case kCLOCK_ApbFro32M: /* FRO32M */
+            freq = CLOCK_GetFro32MFreq();
+            break;
+        case kCLOCK_ApbFro48M: /* FRO48M */
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        default:
+            freq = 0;
+            break;
+    }
+
+    return freq;
+}
+/**
+ * brief	Enables specific AHB clock channel
+ * param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * return	none
+ * note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+void CLOCK_EnableClock(clock_ip_name_t clk)
+{
+    uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
+    switch (index)
+    {
+        case 0:
+        case 1:
+            SYSCON->AHBCLKCTRLSETS[index] = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+            break;
+
+        case 2:
+            SYSCON->ASYNCAPBCTRL             = SYSCON_ASYNCAPBCTRL_ENABLE(1);
+            ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+            break;
+
+        default:
+            switch (clk)
+            {
+                case kCLOCK_Xtal32k:
+                    PMC->PDRUNCFG |= PMC_PDRUNCFG_ENA_XTAL32K_MASK;
+                    SYSCON->OSC32CLKSEL |= SYSCON_OSC32CLKSEL_SEL32KHZ_MASK;
+                    break;
+
+                case kCLOCK_Xtal32M:
+                    /* Only do something if not started already */
+                    if (!(ASYNC_SYSCON->XTAL32MCTRL & ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK))
+                    {
+                        /* XTAL only biased from PMC - force this bit on */
+                        ASYNC_SYSCON->XTAL32MCTRL |= ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_MASK;
+                        /* Enable & set-up XTAL 32 MHz clock core */
+                        CLOCK_XtalBasicTrim();
+
+                        /* Wait for clock to stabilize, plus 200us */
+                        CLOCK_Xtal32M_WaitUntilStable(200);
+                    }
+                    break;
+
+                case kCLOCK_Fro32k:
+                    PMC->PDRUNCFG |= PMC_PDRUNCFG_ENA_FRO32K_MASK;
+                    SYSCON->OSC32CLKSEL &= ~SYSCON_OSC32CLKSEL_SEL32KHZ_MASK;
+                    break;
+
+                case kCLOCK_Fro12M:
+                    PMC->FRO192M |= (FRO12M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro32M:
+                    PMC->FRO192M |= (FRO32M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro48M:
+                    PMC->FRO192M |= (FRO48M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro64M:
+                    PMC->FRO192M |= (FRO64M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fmeas:
+                    /* FRO1M and XTAL32M clock gating (SYSCON->CLOCK_CTRL)
+                     * is handled by FMEAS driver */
+                    break;
+
+                default:
+                    break;
+            }
+            break;
+    }
+}
+
+/**
+ * brief	Disables specific AHB clock channel
+ * param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * return	none
+ * note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+void CLOCK_DisableClock(clock_ip_name_t clk)
+{
+    uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
+    switch (index)
+    {
+        case 0:
+        case 1:
+            SYSCON->AHBCLKCTRLCLRS[index] = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+            break;
+
+        case 2:
+            ASYNC_SYSCON->ASYNCAPBCLKCTRLCLR = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+            break;
+
+        default:
+            switch (clk)
+            {
+                case kCLOCK_Fro32k:
+                    PMC->PDRUNCFG &= ~PMC_PDRUNCFG_ENA_FRO32K_MASK;
+                    break;
+
+                case kCLOCK_Xtal32k:
+                    PMC->PDRUNCFG &= ~PMC_PDRUNCFG_ENA_XTAL32K_MASK;
+                    break;
+
+                case kCLOCK_Xtal32M:
+                    ASYNC_SYSCON->XTAL32MCTRL &= ~(ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK);
+                    break;
+
+                case kCLOCK_Fro12M:
+                    PMC->FRO192M &= ~(FRO12M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro32M:
+                    PMC->FRO192M &= ~(FRO32M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro48M:
+                    PMC->FRO192M &= ~(FRO48M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro64M:
+                    PMC->FRO192M &= ~(FRO64M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                default:
+                    break;
+            }
+            break;
+    }
+}
+
+/**
+ * brief	Check if clock is enabled
+ * param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * return  bool
+ * note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+bool CLOCK_IsClockEnable(clock_ip_name_t clk)
+{
+    uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
+    return (SYSCON->AHBCLKCTRLSETS[index] & (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)));
+}
+
+void CLOCK_EnableAPBBridge(void)
+{
+    SYSCON->ASYNCAPBCTRL |= ((1 << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK);
+}
+
+void CLOCK_DisableAPBBridge(void)
+{
+    SYSCON->ASYNCAPBCTRL &= ~((1 << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK);
+}
+
+/*! brief   Delay execution by busy waiting
+ *  param   delayUs delay duration in micro seconds
+ *  return  none
+ */
+void CLOCK_uDelay(uint32_t delayUs)
+{
+    uint32_t freqMhz, timeout;
+    uint32_t trcena, cyccntena;
+
+    trcena    = CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk;
+    cyccntena = DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk;
+
+    /* EMCR.TRCENA: enable DWT unit */
+    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+
+    /* DWT.CYCCNTENA: enable cycle count register */
+    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+
+    freqMhz = CLOCK_GetFreq(kCLOCK_CoreSysClk) / 1000000;
+    timeout = delayUs * freqMhz + DWT->CYCCNT;
+
+    while ((int32_t)(timeout - DWT->CYCCNT) > 0)
+        ;
+
+    /* Restore TRCENA and CYCCNTENA original states */
+    if (!cyccntena)
+    {
+        DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
+    }
+    if (!trcena)
+    {
+        CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
+    }
+}
+
+void CLOCK_XtalBasicTrim(void)
+{
+#ifdef OBSOLETED_CODE
+    /* Basic trim with default good values */
+    uint32_t u32RegVal;
+
+    /* Enable and set LDO, if not already done */
+    CLOCK_SetXtal32M_LDO();
+
+    /* Read, modify, write ASYNC_SYSCON->XTAL32MCTRL register */
+    u32RegVal = ASYNC_SYSCON->XTAL32MCTRL;
+
+#if (XO_SLAVE_EN == 0)
+#error Code below assumes that trimming always sets \
+       ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK but configuration \
+       of XO_SLAVE_EN means that this may not be the case
+#endif
+
+    /* Reset ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK value is 0,
+     * but all trimming operations set it to 1. This function is called as a
+     * default/catch-all, so if trimming has already been applied since reset
+     * we do not want to overwrite it now in case that previous trimming was
+     * the more sophisticated CLOCK_Xtal32M_Trim. Hence we only apply the trim
+     * values if ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK is 0 */
+    if (0U == (u32RegVal & ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK))
+    {
+        u32RegVal &= ~(ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_MASK | ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_MASK |
+                       ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK | ASYNC_SYSCON_XTAL32MCTRL_XO_GM_MASK);
+
+        u32RegVal |= (ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE(1) | ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE(1) |
+                      ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE(1) | ASYNC_SYSCON_XTAL32MCTRL_XO_GM(3));
+
+        /* ES2 default */
+        u32RegVal |= 34U << ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_SHIFT;
+        u32RegVal |= 30U << ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_SHIFT;
+
+        ASYNC_SYSCON->XTAL32MCTRL = u32RegVal;
+    }
+#else
+    CLOCK_Xtal32M_Trim(0, &default_Clock32MCapacitanceCharacteristics);
+#endif
+}
+
+/*
+ * param  XO_32M_OSC_CAP_Delta_x1000 Osc capacitance expressed in fF (femtoFarad).
+ * Must be 0 if no temperature compensation algorithm is implemented for a given board
+ *
+ */
+void CLOCK_Xtal32M_Trim(int32_t XO_32M_OSC_CAP_Delta_x1000, const ClockCapacitanceCompensation_t *capa_charac)
+{
+    uint32_t u32XOTrimValue;
+    uint8_t u8IECXinCapCal6pF, u8IECXinCapCal8pF, u8IECXoutCapCal6pF, u8IECXoutCapCal8pF, u8XOSlave;
+    int32_t iaXin_x4, ibXin, iaXout_x4, ibXout;
+    int32_t iXOCapInpF_x100, iXOCapOutpF_x100;
+    uint32_t u32XOCapInCtrl, u32XOCapOutCtrl;
+    uint32_t u32RegVal;
+
+    /* Enable and set LDO, if not already done */
+    CLOCK_SetXtal32M_LDO();
+
+    /* Get Cal values from Flash */
+    u32XOTrimValue = GET_32MXO_TRIM();
+
+    /* Check validity and apply */
+    if ((u32XOTrimValue & 1) && ((u32XOTrimValue >> 15) & 1) && (GET_CAL_DATE() >= 20181203))
+    {
+        /* These fields are 7 bits, unsigned */
+        u8IECXinCapCal6pF  = (u32XOTrimValue >> 1) & 0x7f;
+        u8IECXinCapCal8pF  = (u32XOTrimValue >> 8) & 0x7f;
+        u8IECXoutCapCal6pF = (u32XOTrimValue >> 16) & 0x7f;
+        u8IECXoutCapCal8pF = (u32XOTrimValue >> 23) & 0x7f;
+
+        /* This field is 1 bit */
+        u8XOSlave = (u32XOTrimValue >> 30) & 0x1;
+
+        /* Linear fit coefficients calculation */
+        iaXin_x4  = (int)u8IECXinCapCal8pF - (int)u8IECXinCapCal6pF;
+        ibXin     = (int)u8IECXinCapCal6pF - iaXin_x4 * 3;
+        iaXout_x4 = (int)u8IECXoutCapCal8pF - (int)u8IECXoutCapCal6pF;
+        ibXout    = (int)u8IECXoutCapCal6pF - iaXout_x4 * 3;
+    }
+    else
+    {
+        iaXin_x4  = 20;  // gain in LSB/pF 4.882pF
+        ibXin     = -14; // offset in LSB -13.586
+        iaXout_x4 = 19;  // gain in LSB/pF 4.864
+        ibXout    = -15; // offset in LSB -14.5
+        u8XOSlave = 0;
+    }
+
+    /* In & out load cap calculation with derating */
+    iXOCapInpF_x100 = 2 * capa_charac->clk_XtalIecLoadpF_x100 - capa_charac->clk_XtalNPcbParCappF_x100 +
+                      39 * (XO_SLAVE_EN - u8XOSlave) - 15;
+    iXOCapOutpF_x100 = 2 * capa_charac->clk_XtalIecLoadpF_x100 - capa_charac->clk_XtalPPcbParCappF_x100 - 21;
+
+    iXOCapInpF_x100  = iXOCapInpF_x100 + XO_32M_OSC_CAP_Delta_x1000 / 5;
+    iXOCapOutpF_x100 = iXOCapOutpF_x100 + XO_32M_OSC_CAP_Delta_x1000 / 5;
+
+    /* In & out XO_OSC_CAP_Code_CTRL calculation, with rounding */
+    u32XOCapInCtrl  = (uint32_t)(((iXOCapInpF_x100 * iaXin_x4 + ibXin * 400) + 200) / 400);
+    u32XOCapOutCtrl = (uint32_t)(((iXOCapOutpF_x100 * iaXout_x4 + ibXout * 400) + 200) / 400);
+
+    uint8_t u8XOCapInCtrl  = CLOCK_u8OscCapConvert(u32XOCapInCtrl, 13);
+    uint8_t u8XOCapOutCtrl = CLOCK_u8OscCapConvert(u32XOCapOutCtrl, 13);
+
+    /* Read register and clear fields to be written */
+    u32RegVal = ASYNC_SYSCON->XTAL32MCTRL;
+    u32RegVal &= ~(ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_MASK | ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_MASK |
+                   ASYNC_SYSCON_XTAL32MCTRL_XO_GM_MASK | ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_MASK |
+                   ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK);
+
+/* Configuration of 32 MHz XO output buffers */
+#if (XO_SLAVE_EN != 0)
+    u32RegVal |= (ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE(1) | ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE(1));
+#endif
+
+    /* XO_OSC_CAP_Code_CTRL to XO_OSC_CAP_Code conversion */
+    u32RegVal |= ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE(1);
+    u32RegVal |= ASYNC_SYSCON_XTAL32MCTRL_XO_GM(3);
+    u32RegVal |= ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN(u8XOCapInCtrl);
+    u32RegVal |= ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT(u8XOCapOutCtrl);
+
+    /* Write back to register */
+    ASYNC_SYSCON->XTAL32MCTRL = u32RegVal;
+}
+
+void CLOCK_Xtal32k_Trim(int32_t XO_32k_OSC_CAP_Delta_x1000, const ClockCapacitanceCompensation_t *capa_charac)
+{
+    uint32_t u32XOTrimValue;
+    uint8_t u8IECXinCapCal6pF, u8IECXinCapCal8pF, u8IECXoutCapCal6pF, u8IECXoutCapCal8pF;
+    int32_t iaXin_x4, ibXin, iaXout_x4, ibXout;
+    int32_t iXOCapInpF_x100, iXOCapOutpF_x100;
+    uint32_t u32XOCapInCtrl, u32XOCapOutCtrl;
+    uint32_t u32RegVal;
+
+    /* Get Cal values from Flash */
+    u32XOTrimValue = GET_32KXO_TRIM();
+
+    /* check validity and apply */
+    if ((u32XOTrimValue & 1) && ((u32XOTrimValue >> 15) & 1) && (GET_CAL_DATE() >= 20180301))
+    {
+        /* These fields are 7 bits, unsigned */
+        u8IECXinCapCal6pF  = (u32XOTrimValue >> 1) & 0x7f;
+        u8IECXinCapCal8pF  = (u32XOTrimValue >> 8) & 0x7f;
+        u8IECXoutCapCal6pF = (u32XOTrimValue >> 16) & 0x7f;
+        u8IECXoutCapCal8pF = (u32XOTrimValue >> 23) & 0x7f;
+        /* Linear fit coefficients calculation */
+        iaXin_x4  = (int)u8IECXinCapCal8pF - (int)u8IECXinCapCal6pF;
+        ibXin     = (int)u8IECXinCapCal6pF - iaXin_x4 * 3;
+        iaXout_x4 = (int)u8IECXoutCapCal8pF - (int)u8IECXoutCapCal6pF;
+        ibXout    = (int)u8IECXoutCapCal6pF - iaXout_x4 * 3;
+    }
+    else
+    {
+        iaXin_x4  = 14; // gain in LSB/pF 3.586
+        ibXin     = 9;  // offset in LSB 9.286
+        iaXout_x4 = 14; // gain in LSB/pF 3.618
+        ibXout    = 8;  // offset in LSB 6.786
+    }
+
+    /* In & out load cap calculation with derating */
+    iXOCapInpF_x100  = 2 * capa_charac->clk_XtalIecLoadpF_x100 - capa_charac->clk_XtalPPcbParCappF_x100 - 130;
+    iXOCapOutpF_x100 = 2 * capa_charac->clk_XtalIecLoadpF_x100 - capa_charac->clk_XtalNPcbParCappF_x100 - 41;
+
+    /* Temperature compensation, if not supported XO_32k_OSC_CAP_Delta_x1000 == 0*/
+    iXOCapInpF_x100  = iXOCapInpF_x100 + XO_32k_OSC_CAP_Delta_x1000 / 5;
+    iXOCapOutpF_x100 = iXOCapOutpF_x100 + XO_32k_OSC_CAP_Delta_x1000 / 5;
+
+    /* In & out XO_OSC_CAP_Code_CTRL calculation, with rounding */
+    u32XOCapInCtrl  = (uint32_t)(((iXOCapInpF_x100 * iaXin_x4 + ibXin * 400) + 200) / 400);
+    u32XOCapOutCtrl = (uint32_t)(((iXOCapOutpF_x100 * iaXout_x4 + ibXout * 400) + 200) / 400);
+
+    uint8_t u8XOCapInCtrl  = CLOCK_u8OscCapConvert(u32XOCapInCtrl, 23);
+    uint8_t u8XOCapOutCtrl = CLOCK_u8OscCapConvert(u32XOCapOutCtrl, 23);
+
+    /* Read register and clear fields to be written */
+    u32RegVal = SYSCON->XTAL32KCAP;
+    u32RegVal &= ~(SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_MASK | SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_MASK);
+
+    /* XO_OSC_CAP_Code_CTRL to XO_OSC_CAP_Code conversion */
+    u32RegVal |= SYSCON_XTAL32KCAP_XO_OSC_CAP_IN(u8XOCapInCtrl);
+    u32RegVal |= SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT(u8XOCapOutCtrl);
+
+    /* Write back to register */
+    SYSCON->XTAL32KCAP = u32RegVal;
+}
+
+void CLOCK_SetXtal32M_LDO(void)
+{
+    uint32_t temp;
+    const uint32_t u32Mask  = (ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_MASK | ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_MASK |
+                              ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_MASK | ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_MASK);
+    const uint32_t u32Value = (ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE(1) | ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT(0x5) |
+                               ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS(0x2) | ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE(0x1));
+
+    /* Enable & set-up XTAL 32 MHz clock LDO */
+    temp = ASYNC_SYSCON->XTAL32MLDOCTRL;
+
+    if ((temp & u32Mask) != u32Value)
+    {
+        temp &= ~u32Mask;
+
+        /*
+         * Enable the XTAL32M LDO
+         * Adjust the output voltage level, 0x5 for 1.1V
+         * Adjust the biasing current, 0x2 value
+         * Stability configuration, 0x1 default mode
+         */
+        temp |= u32Value;
+
+        ASYNC_SYSCON->XTAL32MLDOCTRL = temp;
+
+        /* Delay for LDO to be up */
+        CLOCK_uDelay(20);
+    }
+}
+
+void CLOCK_Xtal32M_WaitUntilStable(uint32_t u32AdditionalWait_us)
+{
+    /* Spin until XO stable flag is set */
+    while ((ASYNC_SYSCON->RADIOSTATUS & ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_MASK) == 0)
+    {
+    }
+
+    /* Extra wait to ensure XTAL is accurate enough */
+    CLOCK_uDelay(u32AdditionalWait_us);
+}
+
+static uint8_t CLOCK_u8OscCapConvert(uint32_t OscCap_val, uint8_t u8CapBankDiscontinuity)
+{
+    /* Compensate for discontinuity in the capacitor banks */
+    if (OscCap_val < 64)
+    {
+        if (OscCap_val >= u8CapBankDiscontinuity)
+        {
+            OscCap_val -= u8CapBankDiscontinuity;
+        }
+        else
+        {
+            OscCap_val = 0;
+        }
+    }
+    else
+    {
+        if (OscCap_val <= (127 - u8CapBankDiscontinuity))
+        {
+            OscCap_val += u8CapBankDiscontinuity;
+        }
+        else
+        {
+            OscCap_val = 127;
+        }
+    }
+
+    return (uint8_t)OscCap_val;
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_clock.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_clock.h
new file mode 100755
index 0000000..caec656
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_clock.h
@@ -0,0 +1,589 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_CLOCK_H_
+#define _FSL_CLOCK_H_
+
+#include "fsl_device_registers.h"
+#include "fsl_common.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <stddef.h>
+
+/*! @addtogroup clock */
+/*! @{ */
+
+/*! @file */
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief CLOCK driver version 2.1.0. */
+#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
+/*@}*/
+
+#ifdef FPGA_50MHZ
+#define SYSCON_BASE_CLOCK_DIV (6)
+#define SYSCON_BASE_CLOCK_MUL (5)
+
+#define SYS_FREQ(A) ((A * SYSCON_BASE_CLOCK_MUL) / SYSCON_BASE_CLOCK_DIV)
+#else
+#define SYS_FREQ(A) (A)
+#endif
+
+/* Definition for delay API in clock driver, users can redefine it to the real application. */
+#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
+#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (48000000UL)
+#endif
+
+/*! @brief Clock ip name array for FLEXCOMM. */
+#define FLEXCOMM_CLOCKS                                                                               \
+    {                                                                                                 \
+        kCLOCK_Usart0, kCLOCK_Usart1, kCLOCK_I2c0, kCLOCK_I2c1, kCLOCK_Spi0, kCLOCK_Spi1, kCLOCK_I2c2 \
+    }
+/*! @brief Clock ip name array for CTIMER. */
+#define CTIMER_CLOCKS                \
+    {                                \
+        kCLOCK_Timer0, kCLOCK_Timer1 \
+    }
+/*! @brief Clock ip name array for GINT. */
+#define GINT_CLOCKS \
+    {               \
+        kCLOCK_Gint \
+    }
+/*! @brief Clock ip name array for WWDT. */
+#define WWDT_CLOCKS   \
+    {                 \
+        kCLOCK_WdtOsc \
+    }
+/*! @brief Clock ip name array for DMIC. */
+#define DMIC_CLOCKS \
+    {               \
+        kCLOCK_DMic \
+    }
+/*! @brief Clock ip name array for ADC. */
+#define ADC_CLOCKS  \
+    {               \
+        kCLOCK_Adc0 \
+    }
+/*! @brief Clock ip name array for SPIFI. */
+#define SPIFI_CLOCKS \
+    {                \
+        kCLOCK_Spifi \
+    }
+/*! @brief Clock ip name array for GPIO. */
+#define GPIO_CLOCKS  \
+    {                \
+        kCLOCK_Gpio0 \
+    }
+/*! @brief Clock ip name array for DMA. */
+#define DMA_CLOCKS \
+    {              \
+        kCLOCK_Dma \
+    }
+
+/* Test line to verify RCS */
+/* Another test line to verify source control */
+/* Test lines added by Robert Gee */
+
+/**
+ * @brief Clock sources for main system clock.
+ */
+typedef enum
+{
+    SYSCON_MAINCLKSRC_FRO12M,  /*!< FRO 12MHz */
+    SYSCON_MAINCLKSRC_OSC32K,  /*!< OSC 32kHz */
+    SYSCON_MAINCLKSRC_XTAL32M, /*!< XTAL 32MHz */
+    SYSCON_MAINCLKSRC_FRO32M,  /*!< FRO 32MHz */
+    SYSCON_MAINCLKSRC_FRO48M,  /*!< FRO 48MHz */
+    SYSCON_MAINCLKSRC_EXT,     /*!< External clock */
+    SYSCON_MAINCLKSRC_FRO1M,   /*!< FRO 1MHz */
+} CHIP_SYSCON_MAINCLKSRC_T;
+
+/**
+ * @brief	Fractional Divider clock sources
+ */
+typedef enum
+{
+    SYSCON_FRGCLKSRC_MAINCLK,  /*!< Main Clock */
+    SYSCON_FRGCLKSRC_OSC32M,   /*!< 32MHz Clock (XTAL or FRO) */
+    SYSCON_FRGCLKSRC_FRO48MHZ, /*!< FRO 48-MHz */
+    SYSCON_FRGCLKSRC_NONE,     /*!< FRO 48-MHz */
+} CHIP_SYSCON_FRGCLKSRC_T;
+
+/*------------------------------------------------------------------------------
+ clock_ip_name_t definition:
+------------------------------------------------------------------------------*/
+
+#define CLK_GATE_REG_OFFSET_SHIFT 8U
+#define CLK_GATE_REG_OFFSET_MASK 0xFFFFFF00U
+#define CLK_GATE_BIT_SHIFT_SHIFT 0U
+#define CLK_GATE_BIT_SHIFT_MASK 0x000000FFU
+
+#define CLK_GATE_DEFINE(reg_offset, bit_shift)                                  \
+    ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
+     (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
+
+#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((uint32_t)(x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
+#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((uint32_t)(x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
+
+#define AHB_CLK_CTRL0 0
+#define AHB_CLK_CTRL1 1
+#define ASYNC_CLK_CTRL0 2
+
+/**
+ * @brief   Clock name definition
+ */
+typedef enum _clock_name
+{
+    kCLOCK_Sram0    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_SRAM_CTRL0_SHIFT), /*!< SRAM0 clock */
+    kCLOCK_Sram1    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_SRAM_CTRL1_SHIFT), /*!< SRAM1 clock */
+    kCLOCK_Spifi    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_SPIFI_SHIFT),      /*!< SPIFI clock */
+    kCLOCK_InputMux = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_MUX_SHIFT),        /*!< InputMux clock */
+    kCLOCK_Iocon    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_IOCON_SHIFT),      /*!< IOCON clock */
+    kCLOCK_Gpio0    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_GPIO_SHIFT),       /*!< GPIO0 clock */
+    kCLOCK_Pint     = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_PINT_SHIFT),       /*!< PINT clock */
+    kCLOCK_Gint     = CLK_GATE_DEFINE(
+        AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_GINT_SHIFT), /* GPIO_GLOBALINT0 and GPIO_GLOBALINT1 share the same slot  */
+    kCLOCK_Dma     = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_DMA_SHIFT),     /*!< DMA clock */
+    kCLOCK_Iso7816 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_ISO7816_SHIFT), /*!< ISO7816 clock */
+    kCLOCK_WdtOsc  = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_WWDT_SHIFT),    /*!< WDTOSC clock */
+    kCLOCK_Rtc     = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_RTC_SHIFT),     /*!< RTC clock */
+    kCLOCK_AnaInt  = CLK_GATE_DEFINE(
+        AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_SHIFT), /*!<  Analog Interrupt Control module clock */
+    kCLOCK_WakeTmr =
+        CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_SHIFT),        /*!<  Wake up Timers clock */
+    kCLOCK_Adc0      = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_ADC_SHIFT),    /*!< ADC0 clock */
+    kCLOCK_FlexComm0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_USART0_SHIFT), /*!< FlexComm0 clock */
+    kCLOCK_FlexComm1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_USART1_SHIFT), /*!< FlexComm1 clock */
+    kCLOCK_FlexComm2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C0_SHIFT),   /*!< FlexComm2 clock */
+    kCLOCK_FlexComm3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C1_SHIFT),   /*!< FlexComm3 clock */
+    kCLOCK_FlexComm4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_SPI0_SHIFT),   /*!< FlexComm4 clock */
+    kCLOCK_FlexComm5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_SPI1_SHIFT),   /*!< FlexComm5 clock */
+    kCLOCK_Ir        = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_IR_SHIFT),     /*!< Infra Red clock */
+    kCLOCK_Pwm       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_PWM_SHIFT),    /*!< PWM clock */
+    kCLOCK_Rng       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_RNG_SHIFT),    /*!< RNG clock */
+    kCLOCK_FlexComm6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C2_SHIFT),   /*!< FlexComm6 clock */
+    kCLOCK_Usart0    = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_USART0_SHIFT), /*!< USART0 clock */
+    kCLOCK_Usart1    = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_USART1_SHIFT), /*!< USART1 clock */
+    kCLOCK_I2c0      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C0_SHIFT),   /*!< I2C0 clock */
+    kCLOCK_I2c1      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C1_SHIFT),   /*!< I2C1 clock */
+    kCLOCK_Spi0      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_SPI0_SHIFT),   /*!< SPI0 clock */
+    kCLOCK_Spi1      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_SPI1_SHIFT),   /*!< SPI1 clock */
+    kCLOCK_I2c2      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C2_SHIFT),   /*!< I2C2 clock */
+    kCLOCK_Modem     = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_MODEM_MASTER_SHIFT), /*!< MODEM clock */
+    kCLOCK_Aes       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_AES_SHIFT),          /*!< AES clock */
+    kCLOCK_Rfp       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_RFP_SHIFT),          /*!< RFP clock */
+    kCLOCK_DMic      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_DMIC_SHIFT),         /*!< DMIC clock */
+    kCLOCK_Sha0      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_HASH_SHIFT),         /*!< SHA0 clock */
+    kCLOCK_Timer0    = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 1),                                   /*!< Timer0 clock */
+    kCLOCK_Timer1    = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 2),                                   /*!< Timer1 clock */
+    kCLOCK_MainClk   = (1 << 16),                                                             /*!< MAIN_CLK */
+    kCLOCK_CoreSysClk,                                                                        /*!< Core/system clock */
+    kCLOCK_BusClk,                                                                            /*!< AHB bus clock */
+    kCLOCK_Xtal32k,                                                             /*!< 32kHz crystal oscillator */
+    kCLOCK_Xtal32M,                                                             /*!< 32MHz crystal oscillator */
+    kCLOCK_Fro32k,                                                              /*!< 32kHz free running oscillator */
+    kCLOCK_Fro1M,                                                               /*!< 1MHz Free Running Oscillator */
+    kCLOCK_Fro12M,                                                              /*!< 12MHz Free Running Oscillator */
+    kCLOCK_Fro32M,                                                              /*!< 32MHz Free Running Oscillator */
+    kCLOCK_Fro48M,                                                              /*!< 48MHz Free Running Oscillator */
+    kCLOCK_Fro64M,                                                              /*!< 64Mhz Free Running Oscillator */
+    kCLOCK_ExtClk,                                                              /*!< External clock */
+    kCLOCK_WdtClk,                                                              /*!< Watchdog clock */
+    kCLOCK_Frg,                                                                 /*!< Fractional divider */
+    kCLOCK_ClkOut,                                                              /*!< Clock out */
+    kCLOCK_Fmeas,                                                               /*!< FMEAS clock */
+    kCLOCK_Sha = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_HASH_SHIFT), /*!< Hash clock */
+} clock_name_t;
+
+typedef clock_name_t clock_ip_name_t;
+
+#define REG_OFST(block, member) (offsetof(block##_Type, member) / sizeof(uint32_t))
+
+#define MUX_A(m, choice) (((m) << 0) | ((choice + 1) << 12))
+
+/*! @brief Clock source selector definition */
+typedef enum
+{
+    CM_MAINCLKSEL   = REG_OFST(SYSCON, MAINCLKSEL),  /*!< Clock source selector of Main clock source */
+    CM_OSC32CLKSEL  = REG_OFST(SYSCON, OSC32CLKSEL), /*!< Clock source selector of OSC32KCLK and OSC32MCLK */
+    CM_CLKOUTCLKSEL = REG_OFST(SYSCON, CLKOUTSEL),   /*!< Clock source selector of CLKOUT */
+    CM_SPIFICLKSEL  = REG_OFST(SYSCON, SPIFICLKSEL), /*!< Clock source selector of SPIFI */
+    CM_ADCCLKSEL    = REG_OFST(SYSCON, ADCCLKSEL),   /*!< Clock source selector of ADC */
+    CM_USARTCLKSEL  = REG_OFST(SYSCON, USARTCLKSEL), /*!< Clock source selector of USART0 & 1 */
+    CM_I2CCLKSEL    = REG_OFST(SYSCON, I2CCLKSEL),   /*!< Clock source selector of I2C0, 1 and 2 */
+    CM_SPICLKSEL    = REG_OFST(SYSCON, SPICLKSEL),   /*!< Clock source selector of SPI0 & 1 */
+    CM_IRCLKSEL     = REG_OFST(SYSCON, IRCLKSEL),    /*!< Clock source selector of Infra Red */
+    CM_PWMCLKSEL    = REG_OFST(SYSCON, PWMCLKSEL),   /*!< Clock source selector of PWM */
+    CM_WDTCLKSEL    = REG_OFST(SYSCON, WDTCLKSEL),   /*!< Clock source selector of Watchdog Timer */
+    CM_MODEMCLKSEL  = REG_OFST(SYSCON, MODEMCLKSEL), /*!< Clock source selector of Modem */
+    CM_FRGCLKSEL    = REG_OFST(SYSCON, FRGCLKSEL),   /*!< Clock source selector of Fractional Rate Generator (FRG) */
+    CM_DMICLKSEL    = REG_OFST(SYSCON, DMICCLKSEL),  /*!< Clock source selector of Digital microphone (DMIC) */
+    CM_WKTCLKSEL    = REG_OFST(SYSCON, WKTCLKSEL),   /*!< Clock source selector of Wake-up Timer */
+    CM_ASYNCAPB
+} clock_sel_ofst_t;
+
+/*! @brief Clock attach definition */
+typedef enum _clock_attach_id
+{
+    kFRO12M_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 0), /*!< Select FRO 12M for main clock */
+    kOSC32K_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 1), /*!< Select OSC 32K for main clock */
+    kXTAL32M_to_MAIN_CLK = MUX_A(CM_MAINCLKSEL, 2), /*!< Select XTAL 32M for main clock */
+    kFRO32M_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 3), /*!< Select FRO 32M for main clock */
+    kFRO48M_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 4), /*!< Select FRO 48M for main clock */
+    kEXT_CLK_to_MAIN_CLK = MUX_A(CM_MAINCLKSEL, 5), /*!< Select external clock for main clock */
+    kFROM1M_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 6), /*!< Select FRO 1M for main clock */
+
+    kFRO32M_to_OSC32M_CLK  = MUX_A(CM_OSC32CLKSEL, 0), /*!< Select FRO 32M for OSC32KCLK and OSC32MCLK */
+    kXTAL32M_to_OSC32M_CLK = MUX_A(CM_OSC32CLKSEL, 1), /*!< Select XTAL 32M for OSC32KCLK and OSC32MCLK */
+    kFRO32K_to_OSC32K_CLK  = MUX_A(CM_OSC32CLKSEL, 2), /*!< Select FRO 32K for OSC32KCLK and OSC32MCLK */
+    kXTAL32K_to_OSC32K_CLK = MUX_A(CM_OSC32CLKSEL, 3), /*!< Select XTAL 32K for OSC32KCLK and OSC32MCLK */
+
+    kMAIN_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSEL, 0), /*!< Select main clock for CLKOUT */
+    kXTAL32K_to_CLKOUT  = MUX_A(CM_CLKOUTCLKSEL, 1), /*!< Select XTAL 32K for CLKOUT */
+    kFRO32K_to_CLKOUT   = MUX_A(CM_CLKOUTCLKSEL, 2), /*!< Select FRO 32K for CLKOUT */
+    kXTAL32M_to_CLKOUT  = MUX_A(CM_CLKOUTCLKSEL, 3), /*!< Select XTAL 32M for CLKOUT */
+    kDCDC_to_CLKOUT     = MUX_A(CM_CLKOUTCLKSEL, 4), /*!< Select DCDC for CLKOUT */
+    kFRO48M_to_CLKOUT   = MUX_A(CM_CLKOUTCLKSEL, 5), /*!< Select FRO 48M for CLKOUT */
+    kFRO1M_to_CLKOUT    = MUX_A(CM_CLKOUTCLKSEL, 6), /*!< Select FRO 1M for CLKOUT */
+    kNONE_to_CLKOUT     = MUX_A(CM_CLKOUTCLKSEL, 7), /*!< No clock for CLKOUT */
+
+    kMAIN_CLK_to_SPIFI = MUX_A(CM_SPIFICLKSEL, 0), /*!< Select main clock for SPIFI */
+    kXTAL32M_to_SPIFI  = MUX_A(CM_SPIFICLKSEL, 1), /*!< Select XTAL 32M for SPIFI */
+    kFRO64M_to_SPIFI   = MUX_A(CM_SPIFICLKSEL, 2), /*!< Select FRO 64M for SPIFI */
+    kFRO48M_to_SPIFI   = MUX_A(CM_SPIFICLKSEL, 3), /*!< Select FRO 48M for SPIFI */
+
+    kXTAL32M_to_ADC_CLK = MUX_A(CM_ADCCLKSEL, 0), /*!< Select XTAL 32M for ADC */
+    kFRO12M_to_ADC_CLK  = MUX_A(CM_ADCCLKSEL, 1), /*!< Select FRO 12M for ADC */
+    kNONE_to_ADC_CLK    = MUX_A(CM_ADCCLKSEL, 2), /*!< No clock for ADC */
+
+    kOSC32M_to_USART_CLK  = MUX_A(CM_USARTCLKSEL, 0), /*!< Select OSC 32M for USART0 & 1 */
+    kFRO48M_to_USART_CLK  = MUX_A(CM_USARTCLKSEL, 1), /*!< Select FRO 48M for USART0 & 1 */
+    kFRG_CLK_to_USART_CLK = MUX_A(CM_USARTCLKSEL, 2), /*!< Select FRG clock for USART0 & 1 */
+    kNONE_to_USART_CLK    = MUX_A(CM_USARTCLKSEL, 3), /*!< No clock for USART0 & 1 */
+
+    kOSC32M_to_I2C_CLK = MUX_A(CM_I2CCLKSEL, 0), /*!< Select OSC 32M for I2C0, 1 and 2 */
+    kFRO48M_to_I2C_CLK = MUX_A(CM_I2CCLKSEL, 1), /*!< Select FRO 48M for I2C0, 1 and 2 */
+    kNONE_to_I2C_CLK   = MUX_A(CM_I2CCLKSEL, 2), /*!< No clock for I2C0, 1 and 2 */
+
+    kOSC32M_to_SPI_CLK = MUX_A(CM_SPICLKSEL, 0), /*!< Select OSC 32M for SPI0 & 1 */
+    kFRO48M_to_SPI_CLK = MUX_A(CM_SPICLKSEL, 1), /*!< Select FRO 48M for SPI0 & 1 */
+    kNONE_to_SPI_CLK   = MUX_A(CM_SPICLKSEL, 2), /*!< No clock for SPI0 & 1 */
+
+    kOSC32M_to_IR_CLK = MUX_A(CM_IRCLKSEL, 0), /*!< Select OSC 32M for Infra Red */
+    kFRO48M_to_IR_CLK = MUX_A(CM_IRCLKSEL, 1), /*!< Select FRO 48M for Infra Red */
+    kNONE_to_IR_CLK   = MUX_A(CM_IRCLKSEL, 2), /*!< No clock for Infra Red */
+
+    kOSC32M_to_PWM_CLK = MUX_A(CM_PWMCLKSEL, 0), /*!< Select OSC 32M for PWM */
+    kFRO48M_to_PWM_CLK = MUX_A(CM_PWMCLKSEL, 1), /*!< Select FRO 48M for PWM */
+    kNONE_to_PWM_CLK   = MUX_A(CM_PWMCLKSEL, 2), /*!< No clock for PWM */
+
+    kOSC32M_to_WDT_CLK = MUX_A(CM_WDTCLKSEL, 0), /*!< Select OSC 32M for Watchdog Timer */
+    kOSC32K_to_WDT_CLK = MUX_A(CM_WDTCLKSEL, 1), /*!< Select FRO 32K for Watchdog Timer */
+    kFRO1M_to_WDT_CLK  = MUX_A(CM_WDTCLKSEL, 2), /*!< Select FRO 1M for Watchdog Timer */
+
+    kMAIN_CLK_to_FRG_CLK = MUX_A(CM_FRGCLKSEL, 0), /*!< Select main clock for FRG */
+    kOSC32M_to_FRG_CLK   = MUX_A(CM_FRGCLKSEL, 1), /*!< Select OSC 32M for FRG */
+    kFRO48M_to_FRG_CLK   = MUX_A(CM_FRGCLKSEL, 2), /*!< Select FRO 48M for FRG */
+    kNONE_to_FRG_CLK     = MUX_A(CM_FRGCLKSEL, 3), /*!< No clock for FRG */
+
+    kMAIN_CLK_to_DMI_CLK = MUX_A(CM_DMICLKSEL, 0), /*!< Select main clock for DMIC */
+    kOSC32K_to_DMI_CLK   = MUX_A(CM_DMICLKSEL, 1), /*!< Select OSC 32K for DMIC */
+    kFRO48M_to_DMI_CLK   = MUX_A(CM_DMICLKSEL, 2), /*!< Select FRO 48M for DMIC */
+    kMCLK_to_DMI_CLK     = MUX_A(CM_DMICLKSEL, 3), /*!< Select external clock for DMIC */
+    kFRO1M_to_DMI_CLK    = MUX_A(CM_DMICLKSEL, 4), /*!< Select FRO 1M for DMIC */
+    kFRO12M_to_DMI_CLK   = MUX_A(CM_DMICLKSEL, 5), /*!< Select FRO 12M for DMIC */
+    kNONE_to_DMI_CLK     = MUX_A(CM_DMICLKSEL, 6), /*!< No clock for DMIC */
+
+    kOSC32K_to_WKT_CLK = MUX_A(CM_WKTCLKSEL, 0), /*!< Select OSC 32K for WKT */
+    kNONE_to_WKT_CLK   = MUX_A(CM_WKTCLKSEL, 3), /*!< No clock for WKT */
+
+    kXTAL32M_DIV2_to_ZIGBEE_CLK = MUX_A(CM_MODEMCLKSEL, 0), /*!< Select XTAL 32M for ZIGBEE */
+    kNONE_to_ZIGBEE_CLK         = MUX_A(CM_MODEMCLKSEL, 1), /*!< No clock for ZIGBEE */
+
+    kMAIN_CLK_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 0), /*!< Select main clock for Asynchronous APB */
+    kXTAL32M_to_ASYNC_APB  = MUX_A(CM_ASYNCAPB, 1), /*!< Select XTAL 32M for Asynchronous APB */
+    kFRO32M_to_ASYNC_APB   = MUX_A(CM_ASYNCAPB, 2), /*!< Select FRO 32M for Asynchronous APB */
+    kFRO48M_to_ASYNC_APB   = MUX_A(CM_ASYNCAPB, 3), /*!< Select FRO 48M for Asynchronous APB */
+    kNONE_to_NONE          = 0x80000000U,
+} clock_attach_id_t;
+
+/*  Clock dividers */
+#define FIRST_DIV_MEMBER SYSTICKCLKDIV
+#define CLOCK_DIV_OFST(member) offsetof(SYSCON_Type, member)
+
+/*! @brief Clock divider definition */
+typedef enum _clock_div_name
+{
+    kCLOCK_DivNone       = 0,
+    kCLOCK_DivSystickClk = (offsetof(SYSCON_Type, SYSTICKCLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivWdtClk     = (offsetof(SYSCON_Type, WDTCLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivIrClk      = (offsetof(SYSCON_Type, IRCLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivAhbClk     = (offsetof(SYSCON_Type, AHBCLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivClkout     = (offsetof(SYSCON_Type, CLKOUTDIV) / sizeof(uint32_t)),
+    kCLOCK_DivSpifiClk   = (offsetof(SYSCON_Type, SPIFICLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivAdcClk     = (offsetof(SYSCON_Type, ADCCLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivRtcClk     = (offsetof(SYSCON_Type, RTCCLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivDmicClk    = (offsetof(SYSCON_Type, DMICCLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivRtc1HzClk  = (offsetof(SYSCON_Type, RTC1HZCLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivTraceClk   = (offsetof(SYSCON_Type, TRACECLKDIV) / sizeof(uint32_t)),
+    kCLOCK_DivFrg        = (offsetof(SYSCON_Type, FRGCTRL) / sizeof(uint32_t))
+} clock_div_name_t;
+
+/*! @brief Clock source selections for the Main Clock */
+typedef enum _main_clock_src
+{
+    kCLOCK_MainFro12M  = 0, /*!< FRO 12M for main clock */
+    kCLOCK_MainOsc32k  = 1, /*!< OSC 32K for main clock */
+    kCLOCK_MainXtal32M = 2, /*!< XTAL 32M for main clock */
+    kCLOCK_MainFro32M  = 3, /*!< FRO 32M for main clock */
+    kCLOCK_MainFro48M  = 4, /*!< FRO 48M for main clock */
+    kCLOCK_MainExtClk  = 5, /*!< External clock for main clock */
+    kCLOCK_MainFro1M   = 6, /*!< FRO 1M for main clock */
+} main_clock_src_t;
+
+/*! @brief Clock source selections for CLKOUT */
+typedef enum _clkout_clock_src
+{
+    kCLOCK_ClkoutMainClk  = 0, /*!< CPU & System Bus clock for CLKOUT */
+    kCLOCK_ClkoutXtal32k  = 1, /*!< XTAL 32K for CLKOUT */
+    kCLOCK_ClkoutFro32k   = 2, /*!< FRO 32K for CLKOUT */
+    kCLOCK_ClkoutXtal32M  = 3, /*!< XTAL 32M for CLKOUT */
+    kCLOCK_ClkoutDcDcTest = 4, /*!< DCDC Test for CLKOUT */
+    kCLOCK_ClkoutFro48M   = 5, /*!< FRO 48M for CLKOUT */
+    kCLOCK_ClkoutFro1M    = 6, /*!< FRO 1M for CLKOUT */
+    kCLOCK_ClkoutNoClock  = 7  /*!< No clock for CLKOUT */
+} clkout_clock_src_t;
+
+/*! @brief Clock source definition for Watchdog timer */
+typedef enum _wdt_clock_src
+{
+    kCLOCK_WdtOsc32MClk = 0, /*!< OSC 32M for WDT */
+    kCLOCK_WdtOsc32kClk = 1, /*!< OSC 32K for WDT */
+    kCLOCK_WdtFro1M     = 2, /*!< FRO 1M for WDT */
+    kCLOCK_WdtNoClock   = 3  /*!< No clock for WDT */
+} wdt_clock_src_t;
+
+/*! @brief Clock source definition for fractional divider */
+typedef enum _frg_clock_src
+{
+    kCLOCK_FrgMainClk   = 0, /*!< CPU & System Bus clock for FRG */
+    kCLOCK_FrgOsc32MClk = 1, /*!< OSC 32M clock for FRG */
+    kCLOCK_FrgFro48M    = 2, /*!< FRO 48M for FRG */
+    kCLOCK_FrgNoClock   = 3  /*!< No clock for FRG */
+} frg_clock_src_t;
+
+/*! @brief Clock source definition for the APB */
+typedef enum _apb_clock_src
+{
+    kCLOCK_ApbMainClk = 0, /*!< CPU & System Bus clock for APB bridge */
+    kCLOCK_ApbXtal32M = 1, /*!< XTAL 32M for APB bridge */
+    kCLOCK_ApbFro32M  = 2, /*!< FRO 32M for APB bridge */
+    kCLOCK_ApbFro48M  = 3  /*!< FRO 48M for APB bridge */
+} apb_clock_src_t;
+
+/*! @brief Clock source definition for frequency measure  */
+typedef enum _fmeas_clock_src
+{
+    kCLOCK_fmeasClkIn     = 0, /*!< Clock in for FMEAS */
+    kCLOCK_fmeasXtal32Mhz = 1, /*!< XTAL 32M for FMEAS */
+    kCLOCK_fmeasFRO1Mhz   = 2, /*!< FRO 1M for FMEAS */
+    kCLOCK_fmeasXtal32kHz = 3, /*!< XTAL 32K for FMEAS */
+    kCLOCK_fmeasMainClock = 4, /*!< CPU & System Bus clock for FMEAS */
+    kCLOCK_fmeasGPIO_0_4  = 5, /*!< GPIO0_4 input for FMEAS */
+    kCLOCK_fmeasGPIO_0_20 = 6, /*!< GPIO0_20 input for FMEAS */
+    kCLOCK_fmeasGPIO_0_16 = 7, /*!< GPIO0_16 input for FMEAS */
+    kCLOCK_fmeasGPIO_0_15 = 8, /*!< GPIO0_15 input for FMEAS */
+} fmeas_clock_src_t;
+
+/*! @brief Clock source selection for SPIFI */
+typedef enum _spifi_clock_src
+{
+    kCLOCK_SpifiMainClk = 0, /*!< CPU & System Bus clock for SPIFI */
+    kCLOCK_SpifiXtal32M = 1, /*!< XTAL 32M for SPIFI */
+    kCLOCK_SpifiFro64M  = 2, /*!< FRO 64M for SPIFI */
+    kCLOCK_SpifiFro48M  = 3, /*!< FRO 48M for SPIFI */
+    kCLOCK_SpifiNoClock = 4  /*!< No clock for SPIFI */
+} spifi_clock_src_t;
+
+/*! @brief Clock definition for ADC */
+typedef enum _adc_clock_src
+{
+    kCLOCK_AdcXtal32M = 0, /*!< XTAL 32MHz for ADC */
+    kCLOCK_AdcFro12M  = 1, /*!< FRO 12MHz for ADC */
+    kCLOCK_AdcNoClock = 2  /*!< No clock for ADC */
+} adc_clock_src_t;
+
+/*! @brief PWM Clock source selection values */
+typedef enum _pwm_clock_source
+{
+    kCLOCK_PWMOsc32Mclk = 0x0, /*!< 32MHz FRO or XTAL clock */
+    kCLOCK_PWMFro48Mclk = 0x1, /*!< FRO 48MHz clock */
+    kCLOCK_PWMNoClkSel  = 0x2, /*!< No clock selected - Shutdown functional
+                            PWM clock for power saving */
+    kCLOCK_PWMTestClk = 0x3,   /*!< Test clock input - Shutdown functional
+                              PWM clock for power saving */
+} pwm_clock_source_t;
+
+/*! @brief FRO clock selection values */
+typedef enum
+{
+    FRO12M_ENA = (1 << 0), /*!< FRO12M */
+    FRO32M_ENA = (1 << 1), /*!< FRO32M */
+    FRO48M_ENA = (1 << 2), /*!< FRO48M */
+    FRO64M_ENA = (1 << 3), /*!< FRO64M */
+    FRO96M_ENA = (1 << 4)  /*!< FRO96M */
+} Fro_ClkSel_t;
+
+/*! @brief Board specific constant capacitance characteristics
+ * Should be supplied by board manufacturer for best performance.
+ * Capacitances are expressed in hundreds of pF
+ */
+typedef struct
+{
+    uint32_t clk_XtalIecLoadpF_x100;    /*< XTAL Load capacitance */
+    uint32_t clk_XtalPPcbParCappF_x100; /*< XTAL PCB +ve parasitic capacitance */
+    uint32_t clk_XtalNPcbParCappF_x100; /*< XTAL PCB -ve parasitic capacitance */
+} ClockCapacitanceCompensation_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @brief	Obtains frequency of specified clock
+ * @param   clock_name_t  specify clock to be read
+ * @return	uint32_t      frequency
+ * @note
+ */
+uint32_t CLOCK_GetFreq(clock_name_t clock);
+
+/**
+ * @brief	Selects clock source using <name>SEL register in syscon
+ * @param   clock_attach_id_t  specify clock mapping
+ * @return	none
+ * @note
+ */
+void CLOCK_AttachClk(clock_attach_id_t connection);
+
+/**
+ * @brief	Selects clock divider using <name>DIV register in syscon
+ * @param   clock_div_name_t  	specifies which DIV register we are accessing
+ * @param   uint32_t			specifies divisor
+ * @param	bool				true if a syscon clock reset should also be carried out
+ * @return	none
+ * @note
+ */
+void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset);
+
+/**
+ * @brief	Enables specific AHB clock channel
+ * @param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * @return	none
+ * @note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+void CLOCK_EnableClock(clock_ip_name_t clk);
+
+/**
+ * @brief	Disables specific AHB clock channel
+ * @param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * @return	none
+ * @note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+void CLOCK_DisableClock(clock_ip_name_t clk);
+
+/**
+ * @brief	Check if clock is enabled
+ * @param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * @return  bool
+ * @note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+bool CLOCK_IsClockEnable(clock_ip_name_t clk);
+
+/**
+ * @brief	Obtains frequency of APB Bus clock
+ * @param   none
+ * @return	uint32_t      frequency
+ * @note
+ */
+uint32_t CLOCK_GetApbCLkFreq(void);
+
+void CLOCK_EnableAPBBridge(void);
+
+void CLOCK_DisableAPBBridge(void);
+
+/*! @brief      Return Frequency of Spifi Clock
+ *  @return     Frequency of Spifi.
+ */
+uint32_t CLOCK_GetSpifiClkFreq(void);
+
+/*! @brief   Delay execution by busy waiting
+ *  @param   delayUs delay duration in micro seconds
+ *  @return  none
+ */
+void CLOCK_uDelay(uint32_t delayUs);
+
+/**
+ * @brief	Sets default trim values for 32MHz XTAL
+ * @param   none
+ * @return	none
+ * @note    Has no effect if CLOCK_Xtal32M_Trim has been called
+ */
+void CLOCK_XtalBasicTrim(void);
+
+/**
+ * @brief   Sets board-specific trim values for 32MHz XTAL
+ * @param   XO_32M_OSC_CAP_Delta_x1000 capacitance correction in fF (femtoFarad)
+ * @param   capa_charac board 32M capacitance characteristics pointer
+ * @return  none
+ * @note    capa_charac must point to a struct set in board.c using
+ *          CLOCK_32MfXtalIecLoadpF    Load capacitance, pF
+ *          CLOCK_32MfXtalPPcbParCappF PCB +ve parasitic capacitance, pF
+ *          CLOCK_32MfXtalNPcbParCappF PCB -ve parasitic capacitance, pF
+ */
+void CLOCK_Xtal32M_Trim(int32_t XO_32M_OSC_CAP_Delta_x1000, const ClockCapacitanceCompensation_t *capa_charac);
+
+/**
+ * @brief   Sets board-specific trim values for 32kHz XTAL
+ * @param   XO_32k_OSC_CAP_Delta_x1000 capacitance correction in fF
+ * @param   capa_charac board 32k capacitance characteristics pointer
+ * @return  none
+ * @note    capa_charac must point to a struct set in board.c using
+ *          CLOCK_32kfXtalIecLoadpF    Load capacitance, pF
+ *          CLOCK_32kfXtalPPcbParCappF PCB +ve parasitic capacitance, pF
+ *          CLOCK_32kfXtalNPcbParCappF PCB -ve parasitic capacitance, pF
+ */
+void CLOCK_Xtal32k_Trim(int32_t XO_32k_OSC_CAP_Delta_x1000, const ClockCapacitanceCompensation_t *capa_charac);
+
+/**
+ * @brief	Enables and sets LDO for 32MHz XTAL
+ * @param   none
+ * @return	none
+ */
+void CLOCK_SetXtal32M_LDO(void);
+
+/**
+ * @brief	Waits for 32MHz XTAL to stabilise
+ * @param   u32AdditionalWait_us Additional wait after hardware indicates that
+ *                               stability has been reached
+ * @return	none
+ * @note    Operates as a tight loop. Worst case would be ~600ms
+ */
+void CLOCK_Xtal32M_WaitUntilStable(uint32_t u32AdditionalWait_us);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_CLOCK_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_common.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_common.h
new file mode 100755
index 0000000..c5e1c2f
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_common.h
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_COMMON_H_
+#define _FSL_COMMON_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(__ICCARM__)
+#include <stddef.h>
+#endif
+
+#include "fsl_device_registers.h"
+
+/*!
+ * @addtogroup ksdk_common
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Construct a status code value from a group and code number. */
+#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
+
+/*! @brief Construct the version number for drivers. */
+#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief common driver version 2.2.0. */
+#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
+/*@}*/
+
+/* Debug console type definition. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_NONE          0U      /*!< No debug console.             */
+#define DEBUG_CONSOLE_DEVICE_TYPE_UART          1U      /*!< Debug console based on UART.   */
+#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART        2U      /*!< Debug console based on LPUART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI         3U      /*!< Debug console based on LPSCI.  */
+#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC        4U      /*!< Debug console based on USBCDC. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM      5U      /*!< Debug console based on FLEXCOMM. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_IUART         6U      /*!< Debug console based on i.MX UART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART        7U      /*!< Debug console based on LPC_VUSART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART    8U      /*!< Debug console based on LPC_USART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_SWO           9U      /*!< Debug console based on SWO. */
+
+/*! @brief Status group numbers. */
+enum _status_groups
+{
+    kStatusGroup_Generic = 0,                 /*!< Group number for generic status codes. */
+    kStatusGroup_FLASH = 1,                   /*!< Group number for FLASH status codes. */
+    kStatusGroup_LPSPI = 4,                   /*!< Group number for LPSPI status codes. */
+    kStatusGroup_FLEXIO_SPI = 5,              /*!< Group number for FLEXIO SPI status codes. */
+    kStatusGroup_DSPI = 6,                    /*!< Group number for DSPI status codes. */
+    kStatusGroup_FLEXIO_UART = 7,             /*!< Group number for FLEXIO UART status codes. */
+    kStatusGroup_FLEXIO_I2C = 8,              /*!< Group number for FLEXIO I2C status codes. */
+    kStatusGroup_LPI2C = 9,                   /*!< Group number for LPI2C status codes. */
+    kStatusGroup_UART = 10,                   /*!< Group number for UART status codes. */
+    kStatusGroup_I2C = 11,                    /*!< Group number for UART status codes. */
+    kStatusGroup_LPSCI = 12,                  /*!< Group number for LPSCI status codes. */
+    kStatusGroup_LPUART = 13,                 /*!< Group number for LPUART status codes. */
+    kStatusGroup_SPI = 14,                    /*!< Group number for SPI status code.*/
+    kStatusGroup_XRDC = 15,                   /*!< Group number for XRDC status code.*/
+    kStatusGroup_SEMA42 = 16,                 /*!< Group number for SEMA42 status code.*/
+    kStatusGroup_SDHC = 17,                   /*!< Group number for SDHC status code */
+    kStatusGroup_SDMMC = 18,                  /*!< Group number for SDMMC status code */
+    kStatusGroup_SAI = 19,                    /*!< Group number for SAI status code */
+    kStatusGroup_MCG = 20,                    /*!< Group number for MCG status codes. */
+    kStatusGroup_SCG = 21,                    /*!< Group number for SCG status codes. */
+    kStatusGroup_SDSPI = 22,                  /*!< Group number for SDSPI status codes. */
+    kStatusGroup_FLEXIO_I2S = 23,             /*!< Group number for FLEXIO I2S status codes */
+    kStatusGroup_FLEXIO_MCULCD = 24,          /*!< Group number for FLEXIO LCD status codes */
+    kStatusGroup_FLASHIAP = 25,               /*!< Group number for FLASHIAP status codes */
+    kStatusGroup_FLEXCOMM_I2C = 26,           /*!< Group number for FLEXCOMM I2C status codes */
+    kStatusGroup_I2S = 27,                    /*!< Group number for I2S status codes */
+    kStatusGroup_IUART = 28,                  /*!< Group number for IUART status codes */
+    kStatusGroup_CSI = 29,                    /*!< Group number for CSI status codes */
+    kStatusGroup_MIPI_DSI = 30,               /*!< Group number for MIPI DSI status codes */
+    kStatusGroup_SDRAMC = 35,                 /*!< Group number for SDRAMC status codes. */
+    kStatusGroup_POWER = 39,                  /*!< Group number for POWER status codes. */
+    kStatusGroup_ENET = 40,                   /*!< Group number for ENET status codes. */
+    kStatusGroup_PHY = 41,                    /*!< Group number for PHY status codes. */
+    kStatusGroup_TRGMUX = 42,                 /*!< Group number for TRGMUX status codes. */
+    kStatusGroup_SMARTCARD = 43,              /*!< Group number for SMARTCARD status codes. */
+    kStatusGroup_LMEM = 44,                   /*!< Group number for LMEM status codes. */
+    kStatusGroup_QSPI = 45,                   /*!< Group number for QSPI status codes. */
+    kStatusGroup_DMA = 50,                    /*!< Group number for DMA status codes. */
+    kStatusGroup_EDMA = 51,                   /*!< Group number for EDMA status codes. */
+    kStatusGroup_DMAMGR = 52,                 /*!< Group number for DMAMGR status codes. */
+    kStatusGroup_FLEXCAN = 53,                /*!< Group number for FlexCAN status codes. */
+    kStatusGroup_LTC = 54,                    /*!< Group number for LTC status codes. */
+    kStatusGroup_FLEXIO_CAMERA = 55,          /*!< Group number for FLEXIO CAMERA status codes. */
+    kStatusGroup_LPC_SPI = 56,                /*!< Group number for LPC_SPI status codes. */
+    kStatusGroup_LPC_USART = 57,              /*!< Group number for LPC_USART status codes. */
+    kStatusGroup_DMIC = 58,                   /*!< Group number for DMIC status codes. */
+    kStatusGroup_SDIF = 59,                   /*!< Group number for SDIF status codes.*/
+    kStatusGroup_SPIFI = 60,                  /*!< Group number for SPIFI status codes. */
+    kStatusGroup_OTP = 61,                    /*!< Group number for OTP status codes. */
+    kStatusGroup_MCAN = 62,                   /*!< Group number for MCAN status codes. */
+    kStatusGroup_CAAM = 63,                   /*!< Group number for CAAM status codes. */
+    kStatusGroup_ECSPI = 64,                  /*!< Group number for ECSPI status codes. */
+    kStatusGroup_USDHC = 65,                  /*!< Group number for USDHC status codes.*/
+    kStatusGroup_LPC_I2C = 66,                /*!< Group number for LPC_I2C status codes.*/
+    kStatusGroup_DCP = 67,                    /*!< Group number for DCP status codes.*/
+    kStatusGroup_MSCAN = 68,                  /*!< Group number for MSCAN status codes.*/
+    kStatusGroup_ESAI = 69,                   /*!< Group number for ESAI status codes. */
+    kStatusGroup_FLEXSPI = 70,                /*!< Group number for FLEXSPI status codes. */
+    kStatusGroup_MMDC = 71,                   /*!< Group number for MMDC status codes. */
+    kStatusGroup_PDM = 72,                    /*!< Group number for MIC status codes. */
+    kStatusGroup_SDMA = 73,                   /*!< Group number for SDMA status codes. */
+    kStatusGroup_ICS = 74,                    /*!< Group number for ICS status codes. */
+    kStatusGroup_SPDIF = 75,                  /*!< Group number for SPDIF status codes. */
+    kStatusGroup_LPC_MINISPI = 76,            /*!< Group number for LPC_MINISPI status codes. */
+    kStatusGroup_HASHCRYPT = 77,              /*!< Group number for Hashcrypt status codes */
+    kStatusGroup_LPC_SPI_SSP = 78,            /*!< Group number for LPC_SPI_SSP status codes. */
+    kStatusGroup_I3C = 79,                    /*!< Group number for I3C status codes */
+    kStatusGroup_LPC_I2C_1 = 97,              /*!< Group number for LPC_I2C_1 status codes. */
+    kStatusGroup_NOTIFIER = 98,               /*!< Group number for NOTIFIER status codes. */
+    kStatusGroup_DebugConsole = 99,           /*!< Group number for debug console status codes. */
+    kStatusGroup_SEMC = 100,                  /*!< Group number for SEMC status codes. */
+    kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
+    kStatusGroup_IAP = 102,                   /*!< Group number for IAP status codes */
+
+    kStatusGroup_HAL_GPIO = 121,              /*!< Group number for HAL GPIO status codes. */
+    kStatusGroup_HAL_UART = 122,              /*!< Group number for HAL UART status codes. */
+    kStatusGroup_HAL_TIMER = 123,             /*!< Group number for HAL TIMER status codes. */
+    kStatusGroup_HAL_SPI = 124,               /*!< Group number for HAL SPI status codes. */
+    kStatusGroup_HAL_I2C = 125,               /*!< Group number for HAL I2C status codes. */
+    kStatusGroup_HAL_FLASH = 126,             /*!< Group number for HAL FLASH status codes. */
+    kStatusGroup_HAL_PWM = 127,               /*!< Group number for HAL PWM status codes. */
+    kStatusGroup_HAL_RNG = 128,               /*!< Group number for HAL RNG status codes. */
+    kStatusGroup_TIMERMANAGER = 135,          /*!< Group number for TiMER MANAGER status codes. */
+    kStatusGroup_SERIALMANAGER = 136,         /*!< Group number for SERIAL MANAGER status codes. */
+    kStatusGroup_LED = 137,                   /*!< Group number for LED status codes. */
+    kStatusGroup_BUTTON = 138,                /*!< Group number for BUTTON status codes. */
+    kStatusGroup_EXTERN_EEPROM = 139,         /*!< Group number for EXTERN EEPROM status codes. */
+    kStatusGroup_SHELL = 140,                 /*!< Group number for SHELL status codes. */
+    kStatusGroup_MEM_MANAGER = 141,           /*!< Group number for MEM MANAGER status codes. */
+    kStatusGroup_LIST = 142,                  /*!< Group number for List status codes. */
+    kStatusGroup_OSA = 143,                   /*!< Group number for OSA status codes. */
+    kStatusGroup_COMMON_TASK = 144,           /*!< Group number for Common task status codes. */
+    kStatusGroup_MSG = 145,                   /*!< Group number for messaging status codes. */
+    kStatusGroup_SDK_OCOTP = 146,             /*!< Group number for OCOTP status codes. */
+    kStatusGroup_SDK_FLEXSPINOR = 147,        /*!< Group number for FLEXSPINOR status codes.*/
+    kStatusGroup_CODEC = 148,                 /*!< Group number for codec status codes. */
+};
+
+/*! @brief Generic status return codes. */
+enum
+{
+    kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0),
+    kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1),
+    kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2),
+    kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3),
+    kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),
+    kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5),
+    kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6),
+};
+
+/*! @brief Type used for all status and error return values. */
+typedef int32_t status_t;
+
+/*
+ * Macro guard for whether to use default weak IRQ implementation in drivers
+ */
+#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
+#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1
+#endif
+
+/*! @name Min/max macros */
+/* @{ */
+#if !defined(MIN)
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#if !defined(MAX)
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+/* @} */
+
+/*! @brief Computes the number of elements in an array. */
+#if !defined(ARRAY_SIZE)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+/*! @name UINT16_MAX/UINT32_MAX value */
+/* @{ */
+#if !defined(UINT16_MAX)
+#define UINT16_MAX ((uint16_t)-1)
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX ((uint32_t)-1)
+#endif
+/* @} */
+
+/*! @name Timer utilities */
+/* @{ */
+/*! Macro to convert a microsecond period to raw count value */
+#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)
+/*! Macro to convert a raw count value to microsecond */
+#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz)
+
+/*! Macro to convert a millisecond period to raw count value */
+#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U)
+/*! Macro to convert a raw count value to millisecond */
+#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz)
+/* @} */
+
+/*! @name Alignment variable definition macros */
+/* @{ */
+#if (defined(__ICCARM__))
+/**
+ * Workaround to disable MISRA C message suppress warnings for IAR compiler.
+ * http://supp.iar.com/Support/?note=24725
+ */
+_Pragma("diag_suppress=Pm120")
+#define SDK_PRAGMA(x) _Pragma(#x)
+    _Pragma("diag_error=Pm120")
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var
+#endif
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) var
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) var
+#endif
+#elif defined(__GNUC__)
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)))
+#endif
+#else
+#error Toolchain not supported
+#define SDK_ALIGN(var, alignbytes) var
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) var
+#endif
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) var
+#endif
+#endif
+
+/*! Macro to change a value to a given size aligned value */
+#define SDK_SIZEALIGN(var, alignbytes) \
+    ((unsigned int)((var) + ((alignbytes)-1)) & (unsigned int)(~(unsigned int)((alignbytes)-1)))
+/* @} */
+
+/*! @name Non-cacheable region definition macros */
+/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
+ * "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables,
+ * please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables
+ * will be initialized to zero in system startup.
+ */
+/* @{ */
+#if (defined(__ICCARM__))
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
+#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+#endif
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+    __attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+    __attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __attribute__((aligned(alignbytes))) var
+#endif
+#elif(defined(__XCC__))
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+    __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+    __attribute__((section("NonCacheable"))) var __attribute__((aligned(alignbytes)))
+#elif(defined(__GNUC__))
+/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
+ * in your projects to make sure the non-cacheable section variables will be initialized in system startup.
+ */
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+    __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+    __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes)))
+#endif
+#else
+#error Toolchain not supported.
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var
+#endif
+/* @} */
+
+/*! @name Time sensitive region */
+/* @{ */
+#if defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE
+#if (defined(__ICCARM__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
+#define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess"
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
+#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
+#elif(defined(__GNUC__))
+#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
+#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
+#else
+#error Toolchain not supported.
+#endif /* defined(__ICCARM__) */
+#else
+#if (defined(__ICCARM__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#elif(defined(__GNUC__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#else
+#error Toolchain not supported.
+#endif
+#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */
+/* @} */
+
+/*! @name Ram Function */
+#if (defined(__ICCARM__))
+#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction"
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
+#elif(defined(__GNUC__))
+#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
+#else
+#error Toolchain not supported.
+#endif /* defined(__ICCARM__) */
+/* @} */
+
+/*! @name Suppress fallthrough warning macro */
+/* For switch case code block, if case section ends without "break;" statement, there wil be
+ fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc.
+ To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each
+ case section which misses "break;"statement.
+ */
+/* @{ */
+#if (defined(__GNUC__))
+#define SUPPRESS_FALL_THROUGH_WARNING() __attribute__ ((fallthrough))
+#else
+#define SUPPRESS_FALL_THROUGH_WARNING()
+#endif /* defined(__GNUC__) */
+/* @} */
+
+/*
+ * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
+ * defined in previous of this file.
+ */
+#include "fsl_clock.h"
+
+/*
+ * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
+ */
+#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
+     (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
+#include "fsl_reset.h"
+#endif
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+        extern "C"
+{
+#endif
+
+    /*!
+     * @brief Enable specific interrupt.
+     *
+     * Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
+     * levels. For example, there are NVIC and intmux. Here the interrupts connected
+     * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
+     * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
+     * to NVIC first then routed to core.
+     *
+     * This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
+     * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
+     *
+     * @param interrupt The IRQ number.
+     * @retval kStatus_Success Interrupt enabled successfully
+     * @retval kStatus_Fail Failed to enable the interrupt
+     */
+    static inline status_t EnableIRQ(IRQn_Type interrupt)
+    {
+        if (NotAvail_IRQn == interrupt)
+        {
+            return kStatus_Fail;
+        }
+
+#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
+        if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
+        {
+            return kStatus_Fail;
+        }
+#endif
+
+#if defined(__GIC_PRIO_BITS)
+        GIC_EnableIRQ(interrupt);
+#else
+        NVIC_EnableIRQ(interrupt);
+#endif
+        return kStatus_Success;
+    }
+
+    /*!
+     * @brief Disable specific interrupt.
+     *
+     * Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
+     * levels. For example, there are NVIC and intmux. Here the interrupts connected
+     * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
+     * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
+     * to NVIC first then routed to core.
+     *
+     * This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
+     * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
+     *
+     * @param interrupt The IRQ number.
+     * @retval kStatus_Success Interrupt disabled successfully
+     * @retval kStatus_Fail Failed to disable the interrupt
+     */
+    static inline status_t DisableIRQ(IRQn_Type interrupt)
+    {
+        if (NotAvail_IRQn == interrupt)
+        {
+            return kStatus_Fail;
+        }
+
+#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
+        if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
+        {
+            return kStatus_Fail;
+        }
+#endif
+
+#if defined(__GIC_PRIO_BITS)
+        GIC_DisableIRQ(interrupt);
+#else
+    NVIC_DisableIRQ(interrupt);
+#endif
+        return kStatus_Success;
+    }
+
+    /*!
+     * @brief Disable the global IRQ
+     *
+     * Disable the global interrupt and return the current primask register. User is required to provided the primask
+     * register for the EnableGlobalIRQ().
+     *
+     * @return Current primask value.
+     */
+    static inline uint32_t DisableGlobalIRQ(void)
+    {
+#if defined (__XCC__)
+        return 0;
+#else
+#if defined(CPSR_I_Msk)
+        uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
+
+        __disable_irq();
+
+        return cpsr;
+#else
+    uint32_t regPrimask = __get_PRIMASK();
+
+    __disable_irq();
+
+    return regPrimask;
+#endif
+#endif
+    }
+
+    /*!
+     * @brief Enable the global IRQ
+     *
+     * Set the primask register with the provided primask value but not just enable the primask. The idea is for the
+     * convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
+     * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
+     *
+     * @param primask value of primask register to be restored. The primask value is supposed to be provided by the
+     * DisableGlobalIRQ().
+     */
+    static inline void EnableGlobalIRQ(uint32_t primask)
+    {
+#if defined (__XCC__)
+#else
+#if defined(CPSR_I_Msk)
+        __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
+#else
+    __set_PRIMASK(primask);
+#endif
+#endif
+    }
+
+#if defined(ENABLE_RAM_VECTOR_TABLE)
+    /*!
+     * @brief install IRQ handler
+     *
+     * @param irq IRQ number
+     * @param irqHandler IRQ handler address
+     * @return The old IRQ handler address
+     */
+    uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
+#endif /* ENABLE_RAM_VECTOR_TABLE. */
+
+#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
+#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)
+    /*!
+     * @brief Enable specific interrupt for wake-up from deep-sleep mode.
+     *
+     * Enable the interrupt for wake-up from deep sleep mode.
+     * Some interrupts are typically used in sleep mode only and will not occur during
+     * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
+     * those clocks (significantly increasing power consumption in the reduced power mode),
+     * making these wake-ups possible.
+     *
+     * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly).
+     *
+     * @param interrupt The IRQ number.
+     */
+    void EnableDeepSleepIRQ(IRQn_Type interrupt);
+
+    /*!
+     * @brief Disable specific interrupt for wake-up from deep-sleep mode.
+     *
+     * Disable the interrupt for wake-up from deep sleep mode.
+     * Some interrupts are typically used in sleep mode only and will not occur during
+     * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
+     * those clocks (significantly increasing power consumption in the reduced power mode),
+     * making these wake-ups possible.
+     *
+     * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly).
+     *
+     * @param interrupt The IRQ number.
+     */
+    void DisableDeepSleepIRQ(IRQn_Type interrupt);
+#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
+#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
+
+    /*!
+     * @brief Allocate memory with given alignment and aligned size.
+     *
+     * This is provided to support the dynamically allocated memory
+     * used in cache-able region.
+     * @param size The length required to malloc.
+     * @param alignbytes The alignment size.
+     * @retval The allocated memory.
+     */
+    void *SDK_Malloc(size_t size, size_t alignbytes);
+
+    /*!
+     * @brief Free memory.
+     *
+     * @param ptr The memory to be release.
+     */
+    void SDK_Free(void *ptr);
+
+    /*!
+    * @brief Delay at least for some time.
+    *  Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
+    *  if precise delay count was needed, please implement a new delay function with hardware timer.
+    *
+    * @param delay_us  Delay time in unit of microsecond.
+    * @param coreClock_Hz  Core clock frequency with Hz.
+    */
+    void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @} */
+
+#endif /* _FSL_COMMON_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_ctimer.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_ctimer.c
new file mode 100755
index 0000000..590ab32
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_ctimer.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_ctimer.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.ctimer"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Gets the instance from the base address
+ *
+ * @param base Ctimer peripheral base address
+ *
+ * @return The Timer instance
+ */
+static uint32_t CTIMER_GetInstance(CTIMER_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to Timer bases for each instance. */
+static CTIMER_Type *const s_ctimerBases[] = CTIMER_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to Timer clocks for each instance. */
+static const clock_ip_name_t s_ctimerClocks[] = CTIMER_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_RESET) && (FSL_FEATURE_CTIMER_HAS_NO_RESET))
+#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
+#if defined(FSL_FEATURE_CTIMER_WRITE_ZERO_ASSERT_RESET) && FSL_FEATURE_CTIMER_WRITE_ZERO_ASSERT_RESET
+/*! @brief Pointers to Timer resets for each instance, writing a zero asserts the reset */
+static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS_N;
+#else
+/*! @brief Pointers to Timer resets for each instance, writing a one asserts the reset */
+static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS;
+#endif
+#endif
+#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
+
+/*! @brief Pointers real ISRs installed by drivers for each instance. */
+static ctimer_callback_t *s_ctimerCallback[FSL_FEATURE_SOC_CTIMER_COUNT] = {0};
+
+/*! @brief Callback type installed by drivers for each instance. */
+static ctimer_callback_type_t ctimerCallbackType[FSL_FEATURE_SOC_CTIMER_COUNT] = {kCTIMER_SingleCallback};
+
+/*! @brief Array to map timer instance to IRQ number. */
+static const IRQn_Type s_ctimerIRQ[] = CTIMER_IRQS;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static uint32_t CTIMER_GetInstance(CTIMER_Type *base)
+{
+    uint32_t instance;
+    uint32_t ctimerArrayCount = (sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0]));
+
+    /* Find the instance index from base address mappings. */
+    for (instance = 0; instance < ctimerArrayCount; instance++)
+    {
+        if (s_ctimerBases[instance] == base)
+        {
+            break;
+        }
+    }
+
+    assert(instance < ctimerArrayCount);
+
+    return instance;
+}
+
+/*!
+ * brief Ungates the clock and configures the peripheral for basic operation.
+ *
+ * note This API should be called at the beginning of the application before using the driver.
+ *
+ * param base   Ctimer peripheral base address
+ * param config Pointer to the user configuration structure.
+ */
+void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config)
+{
+    assert(config);
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* Enable the timer clock*/
+    CLOCK_EnableClock(s_ctimerClocks[CTIMER_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
+/* Reset the module. */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_RESET) && (FSL_FEATURE_CTIMER_HAS_NO_RESET))
+    RESET_PeripheralReset(s_ctimerResets[CTIMER_GetInstance(base)]);
+#endif
+#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
+
+/* Setup the cimer mode and count select */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    base->CTCR = CTIMER_CTCR_CTMODE(config->mode) | CTIMER_CTCR_CINSEL(config->input);
+#endif
+    /* Setup the timer prescale value */
+    base->PR = CTIMER_PR_PRVAL(config->prescale);
+}
+
+/*!
+ * brief Gates the timer clock.
+ *
+ * param base Ctimer peripheral base address
+ */
+void CTIMER_Deinit(CTIMER_Type *base)
+{
+    uint32_t index = CTIMER_GetInstance(base);
+    /* Stop the timer */
+    base->TCR &= ~CTIMER_TCR_CEN_MASK;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* Disable the timer clock*/
+    CLOCK_DisableClock(s_ctimerClocks[index]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+    /* Disable IRQ at NVIC Level */
+    DisableIRQ(s_ctimerIRQ[index]);
+}
+
+/*!
+ * brief  Fills in the timers configuration structure with the default settings.
+ *
+ * The default values are:
+ * code
+ *   config->mode = kCTIMER_TimerMode;
+ *   config->input = kCTIMER_Capture_0;
+ *   config->prescale = 0;
+ * endcode
+ * param config Pointer to the user configuration structure.
+ */
+void CTIMER_GetDefaultConfig(ctimer_config_t *config)
+{
+    assert(config);
+
+    /* Initializes the configure structure to zero. */
+    memset(config, 0, sizeof(*config));
+
+    /* Run as a timer */
+    config->mode = kCTIMER_TimerMode;
+    /* This field is ignored when mode is timer */
+    config->input = kCTIMER_Capture_0;
+    /* Timer counter is incremented on every APB bus clock */
+    config->prescale = 0;
+}
+
+/*!
+ * brief Configures the PWM signal parameters.
+ *
+ * Enables PWM mode on the match channel passed in and will then setup the match value
+ * and other match parameters to generate a PWM signal.
+ * This function will assign match channel 3 to set the PWM cycle.
+ *
+ * note When setting PWM output from multiple output pins, all should use the same PWM
+ * frequency. Please use CTIMER_SetupPwmPeriod to set up the PWM with high resolution.
+ *
+ * param base             Ctimer peripheral base address
+ * param matchChannel     Match pin to be used to output the PWM signal
+ * param dutyCyclePercent PWM pulse width; the value should be between 0 to 100
+ * param pwmFreq_Hz       PWM signal frequency in Hz
+ * param srcClock_Hz      Timer counter clock in Hz
+ * param enableInt        Enable interrupt when the timer value reaches the match value of the PWM pulse,
+ *                         if it is 0 then no interrupt is generated
+ *
+ * return kStatus_Success on success
+ *         kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM cycle
+ */
+status_t CTIMER_SetupPwm(CTIMER_Type *base,
+                         ctimer_match_t matchChannel,
+                         uint8_t dutyCyclePercent,
+                         uint32_t pwmFreq_Hz,
+                         uint32_t srcClock_Hz,
+                         bool enableInt)
+{
+    assert(pwmFreq_Hz > 0);
+
+    uint32_t reg;
+    uint32_t period, pulsePeriod = 0;
+    uint32_t timerClock = srcClock_Hz / (base->PR + 1);
+    uint32_t index      = CTIMER_GetInstance(base);
+
+    if (matchChannel == kCTIMER_Match_3)
+    {
+        return kStatus_Fail;
+    }
+
+    /* Enable PWM mode on the channel */
+    base->PWMC |= (1U << matchChannel);
+
+    /* Clear the stop, reset and interrupt bits for this channel */
+    reg = base->MCR;
+    reg &= ~((CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR0S_MASK | CTIMER_MCR_MR0I_MASK) << (matchChannel * 3));
+
+    /* If call back function is valid then enable match interrupt for the channel */
+    if (enableInt)
+    {
+        reg |= (CTIMER_MCR_MR0I_MASK << (CTIMER_MCR_MR0I_SHIFT + (matchChannel * 3)));
+    }
+
+    /* Reset the counter when match on channel 3 */
+    reg |= CTIMER_MCR_MR3R_MASK;
+
+    base->MCR = reg;
+
+    /* Calculate PWM period match value */
+    period = (timerClock / pwmFreq_Hz) - 1;
+
+    /* Calculate pulse width match value */
+    if (dutyCyclePercent == 0)
+    {
+        pulsePeriod = period + 1;
+    }
+    else
+    {
+        pulsePeriod = (period * (100 - dutyCyclePercent)) / 100;
+    }
+
+    /* Match on channel 3 will define the PWM period */
+    base->MR[kCTIMER_Match_3] = period;
+
+    /* This will define the PWM pulse period */
+    base->MR[matchChannel] = pulsePeriod;
+    /* Clear status flags */
+    CTIMER_ClearStatusFlags(base, CTIMER_IR_MR0INT_MASK << matchChannel);
+    /* If call back function is valid then enable interrupt and update the call back function */
+    if (enableInt)
+    {
+        EnableIRQ(s_ctimerIRQ[index]);
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Configures the PWM signal parameters.
+ *
+ * Enables PWM mode on the match channel passed in and will then setup the match value
+ * and other match parameters to generate a PWM signal.
+ * This function will assign match channel 3 to set the PWM cycle.
+ *
+ * note When setting PWM output from multiple output pins, all should use the same PWM
+ * period
+ *
+ * param base             Ctimer peripheral base address
+ * param matchChannel     Match pin to be used to output the PWM signal
+ * param pwmPeriod        PWM period match value
+ * param pulsePeriod      Pulse width match value
+ * param enableInt        Enable interrupt when the timer value reaches the match value of the PWM pulse,
+ *                         if it is 0 then no interrupt is generated
+ *
+ * return kStatus_Success on success
+ *         kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM period
+ */
+status_t CTIMER_SetupPwmPeriod(
+    CTIMER_Type *base, ctimer_match_t matchChannel, uint32_t pwmPeriod, uint32_t pulsePeriod, bool enableInt)
+{
+/* Some CTimers only have 16bits , so the value is limited*/
+#if defined(FSL_FEATURE_SOC_CTIMER16B) && FSL_FEATURE_SOC_CTIMER16B
+    assert(!((FSL_FEATURE_CTIMER_BIT_SIZEn(base) < 32) && (pulsePeriod > 0xFFFFU)));
+#endif
+
+    uint32_t reg;
+    uint32_t index = CTIMER_GetInstance(base);
+
+    if (matchChannel == kCTIMER_Match_3)
+    {
+        return kStatus_Fail;
+    }
+
+    /* Enable PWM mode on the channel */
+    base->PWMC |= (1U << matchChannel);
+
+    /* Clear the stop, reset and interrupt bits for this channel */
+    reg = base->MCR;
+    reg &= ~((CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR0S_MASK | CTIMER_MCR_MR0I_MASK) << (matchChannel * 3));
+
+    /* If call back function is valid then enable match interrupt for the channel */
+    if (enableInt)
+    {
+        reg |= (CTIMER_MCR_MR0I_MASK << (CTIMER_MCR_MR0I_SHIFT + (matchChannel * 3)));
+    }
+
+    /* Reset the counter when match on channel 3 */
+    reg |= CTIMER_MCR_MR3R_MASK;
+
+    base->MCR = reg;
+
+    /* Match on channel 3 will define the PWM period */
+    base->MR[kCTIMER_Match_3] = pwmPeriod;
+
+    /* This will define the PWM pulse period */
+    base->MR[matchChannel] = pulsePeriod;
+    /* Clear status flags */
+    CTIMER_ClearStatusFlags(base, CTIMER_IR_MR0INT_MASK << matchChannel);
+    /* If call back function is valid then enable interrupt and update the call back function */
+    if (enableInt)
+    {
+        EnableIRQ(s_ctimerIRQ[index]);
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Updates the duty cycle of an active PWM signal.
+ *
+ * note Please use CTIMER_UpdatePwmPulsePeriod to update the PWM with high resolution.
+ *
+ * param base             Ctimer peripheral base address
+ * param matchChannel     Match pin to be used to output the PWM signal
+ * param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100
+ */
+void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent)
+{
+    uint32_t pulsePeriod = 0, period;
+
+    /* Match channel 3 defines the PWM period */
+    period = base->MR[kCTIMER_Match_3];
+
+    /* Calculate pulse width match value */
+    pulsePeriod = (period * dutyCyclePercent) / 100;
+
+    /* For 0% dutycyle, make pulse period greater than period so the event will never occur */
+    if (dutyCyclePercent == 0)
+    {
+        pulsePeriod = period + 1;
+    }
+    else
+    {
+        pulsePeriod = (period * (100 - dutyCyclePercent)) / 100;
+    }
+
+    /* Update dutycycle */
+    base->MR[matchChannel] = pulsePeriod;
+}
+
+/*!
+ * brief Setup the match register.
+ *
+ * User configuration is used to setup the match value and action to be taken when a match occurs.
+ *
+ * param base         Ctimer peripheral base address
+ * param matchChannel Match register to configure
+ * param config       Pointer to the match configuration structure
+ */
+void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config)
+{
+/* Some CTimers only have 16bits , so the value is limited*/
+#if defined(FSL_FEATURE_SOC_CTIMER16B) && FSL_FEATURE_SOC_CTIMER16B
+    assert(!(FSL_FEATURE_CTIMER_BIT_SIZEn(base) < 32 && config->matchValue > 0xFFFFU));
+#endif
+    uint32_t reg;
+    uint32_t index = CTIMER_GetInstance(base);
+
+    /* Set the counter operation when a match on this channel occurs */
+    reg = base->MCR;
+    reg &= ~((CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR0S_MASK | CTIMER_MCR_MR0I_MASK) << (matchChannel * 3));
+    reg |= (uint32_t)((uint32_t)(config->enableCounterReset) << (CTIMER_MCR_MR0R_SHIFT + (matchChannel * 3)));
+    reg |= (uint32_t)((uint32_t)(config->enableCounterStop) << (CTIMER_MCR_MR0S_SHIFT + (matchChannel * 3)));
+    reg |= (uint32_t)((uint32_t)(config->enableInterrupt) << (CTIMER_MCR_MR0I_SHIFT + (matchChannel * 3)));
+    base->MCR = reg;
+
+    reg = base->EMR;
+    /* Set the match output operation when a match on this channel occurs */
+    reg &= ~(CTIMER_EMR_EMC0_MASK << (matchChannel * 2));
+    reg |= (uint32_t)config->outControl << (CTIMER_EMR_EMC0_SHIFT + (matchChannel * 2));
+
+    /* Set the initial state of the EM bit/output */
+    reg &= ~(CTIMER_EMR_EM0_MASK << matchChannel);
+    reg |= (uint32_t)config->outPinInitState << matchChannel;
+    base->EMR = reg;
+
+    /* Set the match value */
+    base->MR[matchChannel] = config->matchValue;
+    /* Clear status flags */
+    CTIMER_ClearStatusFlags(base, CTIMER_IR_MR0INT_MASK << matchChannel);
+    /* If interrupt is enabled then enable interrupt and update the call back function */
+    if (config->enableInterrupt)
+    {
+        EnableIRQ(s_ctimerIRQ[index]);
+    }
+}
+
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+/*!
+ * brief Setup the capture.
+ *
+ * param base      Ctimer peripheral base address
+ * param capture   Capture channel to configure
+ * param edge      Edge on the channel that will trigger a capture
+ * param enableInt Flag to enable channel interrupts, if enabled then the registered call back
+ *                  is called upon capture
+ */
+void CTIMER_SetupCapture(CTIMER_Type *base,
+                         ctimer_capture_channel_t capture,
+                         ctimer_capture_edge_t edge,
+                         bool enableInt)
+{
+    uint32_t reg   = base->CCR;
+    uint32_t index = CTIMER_GetInstance(base);
+
+    /* Set the capture edge */
+    reg &= ~((CTIMER_CCR_CAP0RE_MASK | CTIMER_CCR_CAP0FE_MASK | CTIMER_CCR_CAP0I_MASK) << (capture * 3));
+    reg |= (uint32_t)edge << (CTIMER_CCR_CAP0RE_SHIFT + (capture * 3));
+    /* Clear status flags */
+    CTIMER_ClearStatusFlags(base, (kCTIMER_Capture0Flag << capture));
+    /* If call back function is valid then enable capture interrupt for the channel and update the call back function */
+    if (enableInt)
+    {
+        reg |= CTIMER_CCR_CAP0I_MASK << (capture * 3);
+        EnableIRQ(s_ctimerIRQ[index]);
+    }
+    base->CCR = reg;
+}
+#endif
+
+/*!
+ * brief Register callback.
+ *
+ * param base      Ctimer peripheral base address
+ * param cb_func   callback function
+ * param cb_type   callback function type, singular or multiple
+ */
+void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type)
+{
+    uint32_t index            = CTIMER_GetInstance(base);
+    s_ctimerCallback[index]   = cb_func;
+    ctimerCallbackType[index] = cb_type;
+}
+
+void CTIMER_GenericIRQHandler(uint32_t index)
+{
+    uint32_t int_stat, i, mask;
+    /* Get Interrupt status flags */
+    int_stat = CTIMER_GetStatusFlags(s_ctimerBases[index]);
+    /* Clear the status flags that were set */
+    CTIMER_ClearStatusFlags(s_ctimerBases[index], int_stat);
+    if (ctimerCallbackType[index] == kCTIMER_SingleCallback)
+    {
+        if (s_ctimerCallback[index][0])
+        {
+            s_ctimerCallback[index][0](int_stat);
+        }
+    }
+    else
+    {
+#if defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE
+        for (i = 0; i <= CTIMER_IR_MR3INT_SHIFT; i++)
+#else
+#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT
+        for (i = 0; i <= CTIMER_IR_CR3INT_SHIFT; i++)
+#else
+        for (i = 0; i <= CTIMER_IR_CR2INT_SHIFT; i++)
+#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */
+#endif
+        {
+            mask = 0x01 << i;
+            /* For each status flag bit that was set call the callback function if it is valid */
+            if ((int_stat & mask) && (s_ctimerCallback[index][i]))
+            {
+                s_ctimerCallback[index][i](int_stat);
+            }
+        }
+    }
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+
+/* IRQ handler functions overloading weak symbols in the startup */
+#if defined(CTIMER0)
+void CTIMER0_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(0);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(CTIMER1)
+void CTIMER1_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(1);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(CTIMER2)
+void CTIMER2_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(2);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(CTIMER3)
+void CTIMER3_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(3);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(CTIMER4)
+void CTIMER4_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(4);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_ctimer.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_ctimer.h
new file mode 100755
index 0000000..8ae0d88
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_ctimer.h
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_CTIMER_H_
+#define _FSL_CTIMER_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup ctimer
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+#define FSL_CTIMER_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */
+/*@}*/
+
+/*! @brief List of Timer capture channels */
+typedef enum _ctimer_capture_channel
+{
+    kCTIMER_Capture_0 = 0U, /*!< Timer capture channel 0 */
+    kCTIMER_Capture_1,      /*!< Timer capture channel 1 */
+    kCTIMER_Capture_2,      /*!< Timer capture channel 2 */
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+    kCTIMER_Capture_3 /*!< Timer capture channel 3 */
+#endif                /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */
+} ctimer_capture_channel_t;
+
+/*! @brief List of capture edge options */
+typedef enum _ctimer_capture_edge
+{
+    kCTIMER_Capture_RiseEdge = 1U, /*!< Capture on rising edge */
+    kCTIMER_Capture_FallEdge = 2U, /*!< Capture on falling edge */
+    kCTIMER_Capture_BothEdge = 3U, /*!< Capture on rising and falling edge */
+} ctimer_capture_edge_t;
+
+/*! @brief List of Timer match registers */
+typedef enum _ctimer_match
+{
+    kCTIMER_Match_0 = 0U, /*!< Timer match register 0 */
+    kCTIMER_Match_1,      /*!< Timer match register 1 */
+    kCTIMER_Match_2,      /*!< Timer match register 2 */
+    kCTIMER_Match_3       /*!< Timer match register 3 */
+} ctimer_match_t;
+
+/*! @brief List of output control options */
+typedef enum _ctimer_match_output_control
+{
+    kCTIMER_Output_NoAction = 0U, /*!< No action is taken */
+    kCTIMER_Output_Clear,         /*!< Clear the EM bit/output to 0 */
+    kCTIMER_Output_Set,           /*!< Set the EM bit/output to 1 */
+    kCTIMER_Output_Toggle         /*!< Toggle the EM bit/output */
+} ctimer_match_output_control_t;
+
+/*! @brief List of Timer modes */
+typedef enum _ctimer_timer_mode
+{
+    kCTIMER_TimerMode = 0U,     /* TC is incremented every rising APB bus clock edge */
+    kCTIMER_IncreaseOnRiseEdge, /* TC is incremented on rising edge of input signal */
+    kCTIMER_IncreaseOnFallEdge, /* TC is incremented on falling edge of input signal */
+    kCTIMER_IncreaseOnBothEdge  /* TC is incremented on both edges of input signal */
+} ctimer_timer_mode_t;
+
+/*! @brief List of Timer interrupts */
+typedef enum _ctimer_interrupt_enable
+{
+    kCTIMER_Match0InterruptEnable = CTIMER_MCR_MR0I_MASK, /*!< Match 0 interrupt */
+    kCTIMER_Match1InterruptEnable = CTIMER_MCR_MR1I_MASK, /*!< Match 1 interrupt */
+    kCTIMER_Match2InterruptEnable = CTIMER_MCR_MR2I_MASK, /*!< Match 2 interrupt */
+    kCTIMER_Match3InterruptEnable = CTIMER_MCR_MR3I_MASK, /*!< Match 3 interrupt */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    kCTIMER_Capture0InterruptEnable = CTIMER_CCR_CAP0I_MASK, /*!< Capture 0 interrupt */
+    kCTIMER_Capture1InterruptEnable = CTIMER_CCR_CAP1I_MASK, /*!< Capture 1 interrupt */
+    kCTIMER_Capture2InterruptEnable = CTIMER_CCR_CAP2I_MASK, /*!< Capture 2 interrupt */
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+    kCTIMER_Capture3InterruptEnable = CTIMER_CCR_CAP3I_MASK, /*!< Capture 3 interrupt */
+#endif                                                       /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
+#endif
+} ctimer_interrupt_enable_t;
+
+/*! @brief List of Timer flags */
+typedef enum _ctimer_status_flags
+{
+    kCTIMER_Match0Flag = CTIMER_IR_MR0INT_MASK, /*!< Match 0 interrupt flag */
+    kCTIMER_Match1Flag = CTIMER_IR_MR1INT_MASK, /*!< Match 1 interrupt flag */
+    kCTIMER_Match2Flag = CTIMER_IR_MR2INT_MASK, /*!< Match 2 interrupt flag */
+    kCTIMER_Match3Flag = CTIMER_IR_MR3INT_MASK, /*!< Match 3 interrupt flag */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    kCTIMER_Capture0Flag = CTIMER_IR_CR0INT_MASK, /*!< Capture 0 interrupt flag */
+    kCTIMER_Capture1Flag = CTIMER_IR_CR1INT_MASK, /*!< Capture 1 interrupt flag */
+    kCTIMER_Capture2Flag = CTIMER_IR_CR2INT_MASK, /*!< Capture 2 interrupt flag */
+#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT
+    kCTIMER_Capture3Flag = CTIMER_IR_CR3INT_MASK, /*!< Capture 3 interrupt flag */
+#endif                                            /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */
+#endif
+} ctimer_status_flags_t;
+
+typedef void (*ctimer_callback_t)(uint32_t flags);
+
+/*! @brief Callback type when registering for a callback. When registering a callback
+ *         an array of function pointers is passed the size could be 1 or 8, the callback
+ *         type will tell that.
+ */
+typedef enum
+{
+    kCTIMER_SingleCallback,  /*!< Single Callback type where there is only one callback for the timer.
+                                 based on the status flags different channels needs to be handled differently */
+    kCTIMER_MultipleCallback /*!< Multiple Callback type where there can be 8 valid callbacks, one per channel.
+                                 for both match/capture */
+} ctimer_callback_type_t;
+
+/*!
+ * @brief Match configuration
+ *
+ * This structure holds the configuration settings for each match register.
+ */
+typedef struct _ctimer_match_config
+{
+    uint32_t matchValue;                      /*!< This is stored in the match register */
+    bool enableCounterReset;                  /*!< true: Match will reset the counter
+                                                   false: Match will not reser the counter */
+    bool enableCounterStop;                   /*!< true: Match will stop the counter
+                                                   false: Match will not stop the counter */
+    ctimer_match_output_control_t outControl; /*!< Action to be taken on a match on the EM bit/output */
+    bool outPinInitState;                     /*!< Initial value of the EM bit/output */
+    bool enableInterrupt;                     /*!< true: Generate interrupt upon match
+                                                   false: Do not generate interrupt on match */
+
+} ctimer_match_config_t;
+
+/*!
+ * @brief Timer configuration structure
+ *
+ * This structure holds the configuration settings for the Timer peripheral. To initialize this
+ * structure to reasonable defaults, call the CTIMER_GetDefaultConfig() function and pass a
+ * pointer to the configuration structure instance.
+ *
+ * The configuration structure can be made constant so as to reside in flash.
+ */
+typedef struct _ctimer_config
+{
+    ctimer_timer_mode_t mode;       /*!< Timer mode */
+    ctimer_capture_channel_t input; /*!< Input channel to increment the timer, used only in timer
+                                        modes that rely on this input signal to increment TC */
+    uint32_t prescale;              /*!< Prescale value */
+} ctimer_config_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Ungates the clock and configures the peripheral for basic operation.
+ *
+ * @note This API should be called at the beginning of the application before using the driver.
+ *
+ * @param base   Ctimer peripheral base address
+ * @param config Pointer to the user configuration structure.
+ */
+void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config);
+
+/*!
+ * @brief Gates the timer clock.
+ *
+ * @param base Ctimer peripheral base address
+ */
+void CTIMER_Deinit(CTIMER_Type *base);
+
+/*!
+ * @brief  Fills in the timers configuration structure with the default settings.
+ *
+ * The default values are:
+ * @code
+ *   config->mode = kCTIMER_TimerMode;
+ *   config->input = kCTIMER_Capture_0;
+ *   config->prescale = 0;
+ * @endcode
+ * @param config Pointer to the user configuration structure.
+ */
+void CTIMER_GetDefaultConfig(ctimer_config_t *config);
+
+/*! @}*/
+
+/*!
+ * @name PWM setup operations
+ * @{
+ */
+
+/*!
+ * @brief Configures the PWM signal parameters.
+ *
+ * Enables PWM mode on the match channel passed in and will then setup the match value
+ * and other match parameters to generate a PWM signal.
+ * This function will assign match channel 3 to set the PWM cycle.
+ *
+ * @note When setting PWM output from multiple output pins, all should use the same PWM
+ * period
+ *
+ * @param base             Ctimer peripheral base address
+ * @param matchChannel     Match pin to be used to output the PWM signal
+ * @param pwmPeriod        PWM period match value
+ * @param pulsePeriod      Pulse width match value
+ * @param enableInt        Enable interrupt when the timer value reaches the match value of the PWM pulse,
+ *                         if it is 0 then no interrupt is generated
+ *
+ * @return kStatus_Success on success
+ *         kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM period
+ */
+status_t CTIMER_SetupPwmPeriod(
+    CTIMER_Type *base, ctimer_match_t matchChannel, uint32_t pwmPeriod, uint32_t pulsePeriod, bool enableInt);
+
+/*!
+ * @brief Configures the PWM signal parameters.
+ *
+ * Enables PWM mode on the match channel passed in and will then setup the match value
+ * and other match parameters to generate a PWM signal.
+ * This function will assign match channel 3 to set the PWM cycle.
+ *
+ * @note When setting PWM output from multiple output pins, all should use the same PWM
+ * frequency. Please use CTIMER_SetupPwmPeriod to set up the PWM with high resolution.
+ *
+ * @param base             Ctimer peripheral base address
+ * @param matchChannel     Match pin to be used to output the PWM signal
+ * @param dutyCyclePercent PWM pulse width; the value should be between 0 to 100
+ * @param pwmFreq_Hz       PWM signal frequency in Hz
+ * @param srcClock_Hz      Timer counter clock in Hz
+ * @param enableInt        Enable interrupt when the timer value reaches the match value of the PWM pulse,
+ *                         if it is 0 then no interrupt is generated
+ *
+ * @return kStatus_Success on success
+ *         kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM cycle
+ */
+status_t CTIMER_SetupPwm(CTIMER_Type *base,
+                         ctimer_match_t matchChannel,
+                         uint8_t dutyCyclePercent,
+                         uint32_t pwmFreq_Hz,
+                         uint32_t srcClock_Hz,
+                         bool enableInt);
+
+/*!
+ * @brief Updates the pulse period of an active PWM signal.
+ *
+ * @param base         Ctimer peripheral base address
+ * @param matchChannel Match pin to be used to output the PWM signal
+ * @param pulsePeriod  New PWM pulse width match value
+ */
+static inline void CTIMER_UpdatePwmPulsePeriod(CTIMER_Type *base, ctimer_match_t matchChannel, uint32_t pulsePeriod)
+{
+    /* Update PWM pulse period match value */
+    base->MR[matchChannel] = pulsePeriod;
+}
+
+/*!
+ * @brief Updates the duty cycle of an active PWM signal.
+ *
+ * @note Please use CTIMER_UpdatePwmPulsePeriod to update the PWM with high resolution.
+ *
+ * @param base             Ctimer peripheral base address
+ * @param matchChannel     Match pin to be used to output the PWM signal
+ * @param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100
+ */
+void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent);
+
+/*! @}*/
+
+/*!
+ * @brief Setup the match register.
+ *
+ * User configuration is used to setup the match value and action to be taken when a match occurs.
+ *
+ * @param base         Ctimer peripheral base address
+ * @param matchChannel Match register to configure
+ * @param config       Pointer to the match configuration structure
+ */
+void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config);
+
+/*!
+ * @brief Setup the capture.
+ *
+ * @param base      Ctimer peripheral base address
+ * @param capture   Capture channel to configure
+ * @param edge      Edge on the channel that will trigger a capture
+ * @param enableInt Flag to enable channel interrupts, if enabled then the registered call back
+ *                  is called upon capture
+ */
+void CTIMER_SetupCapture(CTIMER_Type *base,
+                         ctimer_capture_channel_t capture,
+                         ctimer_capture_edge_t edge,
+                         bool enableInt);
+
+/*!
+ * @brief Get the timer count value from TC register.
+ *
+ * @param  base  Ctimer peripheral base address.
+ * @return       return the timer count value.
+ */
+static inline uint32_t CTIMER_GetTimerCountValue(CTIMER_Type *base)
+{
+    return (base->TC);
+}
+
+/*!
+ * @brief Register callback.
+ *
+ * @param base      Ctimer peripheral base address
+ * @param cb_func   callback function
+ * @param cb_type   callback function type, singular or multiple
+ */
+void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type);
+
+/*!
+ * @name Interrupt Interface
+ * @{
+ */
+
+/*!
+ * @brief Enables the selected Timer interrupts.
+ *
+ * @param base Ctimer peripheral base address
+ * @param mask The interrupts to enable. This is a logical OR of members of the
+ *             enumeration ::ctimer_interrupt_enable_t
+ */
+static inline void CTIMER_EnableInterrupts(CTIMER_Type *base, uint32_t mask)
+{
+    /* Enable match interrupts */
+    base->MCR |= mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK);
+
+/* Enable capture interrupts */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    base->CCR |= mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+                         | CTIMER_CCR_CAP3I_MASK
+#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
+                        );
+#endif
+}
+
+/*!
+ * @brief Disables the selected Timer interrupts.
+ *
+ * @param base Ctimer peripheral base address
+ * @param mask The interrupts to enable. This is a logical OR of members of the
+ *             enumeration ::ctimer_interrupt_enable_t
+ */
+static inline void CTIMER_DisableInterrupts(CTIMER_Type *base, uint32_t mask)
+{
+    /* Disable match interrupts */
+    base->MCR &= ~(mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK));
+
+/* Disable capture interrupts */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    base->CCR &= ~(mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+                           | CTIMER_CCR_CAP3I_MASK
+#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
+                           ));
+#endif
+}
+
+/*!
+ * @brief Gets the enabled Timer interrupts.
+ *
+ * @param base Ctimer peripheral base address
+ *
+ * @return The enabled interrupts. This is the logical OR of members of the
+ *         enumeration ::ctimer_interrupt_enable_t
+ */
+static inline uint32_t CTIMER_GetEnabledInterrupts(CTIMER_Type *base)
+{
+    uint32_t enabledIntrs = 0;
+
+    /* Get all the match interrupts enabled */
+    enabledIntrs =
+        base->MCR & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK);
+
+/* Get all the capture interrupts enabled */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    enabledIntrs |= base->CCR & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+                                 | CTIMER_CCR_CAP3I_MASK
+#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
+                                );
+#endif
+
+    return enabledIntrs;
+}
+
+/*! @}*/
+
+/*!
+ * @name Status Interface
+ * @{
+ */
+
+/*!
+ * @brief Gets the Timer status flags.
+ *
+ * @param base Ctimer peripheral base address
+ *
+ * @return The status flags. This is the logical OR of members of the
+ *         enumeration ::ctimer_status_flags_t
+ */
+static inline uint32_t CTIMER_GetStatusFlags(CTIMER_Type *base)
+{
+    return base->IR;
+}
+
+/*!
+ * @brief Clears the Timer status flags.
+ *
+ * @param base Ctimer peripheral base address
+ * @param mask The status flags to clear. This is a logical OR of members of the
+ *             enumeration ::ctimer_status_flags_t
+ */
+static inline void CTIMER_ClearStatusFlags(CTIMER_Type *base, uint32_t mask)
+{
+    base->IR = mask;
+}
+
+/*! @}*/
+
+/*!
+ * @name Counter Start and Stop
+ * @{
+ */
+
+/*!
+ * @brief Starts the Timer counter.
+ *
+ * @param base Ctimer peripheral base address
+ */
+static inline void CTIMER_StartTimer(CTIMER_Type *base)
+{
+    base->TCR |= CTIMER_TCR_CEN_MASK;
+}
+
+/*!
+ * @brief Stops the Timer counter.
+ *
+ * @param base Ctimer peripheral base address
+ */
+static inline void CTIMER_StopTimer(CTIMER_Type *base)
+{
+    base->TCR &= ~CTIMER_TCR_CEN_MASK;
+}
+
+/*! @}*/
+
+/*!
+ * @brief Reset the counter.
+ *
+ * The timer counter and prescale counter are reset on the next positive edge of the APB clock.
+ *
+ * @param base Ctimer peripheral base address
+ */
+static inline void CTIMER_Reset(CTIMER_Type *base)
+{
+    base->TCR |= CTIMER_TCR_CRST_MASK;
+    base->TCR &= ~CTIMER_TCR_CRST_MASK;
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_CTIMER_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flash.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flash.c
new file mode 100755
index 0000000..d48b803
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flash.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flash.h"
+#include "rom_api.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.jn_flash"
+#endif
+
+/*****************************************************************************
+ * Private types/enumerations/variables
+ ****************************************************************************/
+
+#define MAX_ERASE_LENGTH (FLASH_PAGE_SIZE * 100)
+
+/*
+ * Macros below participate to the Flash checksum calculation.
+ * FLASH_CheckSum implements CMD_CHECKSUM function of the flash controller for whole pages strictly.
+ * SW is required when needing to program a checksums or check over areas smaller than a whole flash page.
+ */
+#define RSHIFT_128BIT(_WORD_, _SHIFT_)     \
+    _WORD_[0] >>= (uint32_t)_SHIFT_;\
+    _WORD_[0] |= (uint32_t)((_WORD_[1] & (uint32_t)((1<<_SHIFT_)-1)) << (uint32_t)(32-_SHIFT_));\
+    _WORD_[1] >>=(uint32_t)_SHIFT_;\
+    _WORD_[1] |= (uint32_t)((_WORD_[2] & (uint32_t)((1<<_SHIFT_)-1)) << (uint32_t)(32-_SHIFT_));\
+    _WORD_[2] >>=(uint32_t)_SHIFT_;\
+    _WORD_[2] |= (uint32_t)((_WORD_[3] & (uint32_t)((1<<_SHIFT_)-1)) << (uint32_t)(32-_SHIFT_));\
+    _WORD_[3] >>=(uint32_t)_SHIFT_;
+
+#define PARITY(_WORD_) \
+          (uint32_t)((_WORD_ & (uint32_t)(1<<0UL))>>0UL) \
+        ^ (uint32_t)((_WORD_ & (uint32_t)(1<<2UL))>>2UL) \
+        ^ (uint32_t)((_WORD_ & (uint32_t)(1<<27UL))>>27UL)\
+        ^ (uint32_t)((_WORD_ & (uint32_t)(1<<29UL))>>29UL)
+/*****************************************************************************
+ * Public types/enumerations/variables
+ ****************************************************************************/
+flash_config_t gFlashConfig;
+
+/*****************************************************************************
+ * Private functions
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Public functions
+ ****************************************************************************/
+
+/**
+ * @brief      Enable the FLASH
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     Nothing
+ */
+void FLASH_Init(FLASH_Type *pFLASH)
+{
+    int status;
+    /* From Flash Adapter */
+    gFlashConfig.PFlashSectorSize = FLASH_PAGE_SIZE;
+    ROM_GetFlash(&gFlashConfig.PFlashBlockBase, &gFlashConfig.PFlashTotalSize);
+
+    pFLASH->CMD = FLASH_CMD_INIT;
+
+    status = FLASH_Wait(pFLASH);
+    /* Loop if the flash controller detects an unrecoverable error */
+    /* That should have been caught by the ROM code but might not !*/
+    if (status & FLASH_FAIL)
+    {
+        while (1);
+    }
+}
+
+/**
+ * @brief      Power down the FLASH
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     Nothing
+ */
+void FLASH_Powerdown(FLASH_Type *pFLASH)
+{
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    pFLASH->CMD = FLASH_CMD_POWERDOWN;
+
+    FLASH_Wait(pFLASH);
+}
+
+/**
+ * @brief      Wait for FLASH command to complete
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Wait(FLASH_Type *pFLASH)
+{
+    while (!(pFLASH->INT_STATUS & FLASH_DONE));
+    /* mask out ECC_ERR bit that may raise independantly from flash commands */
+    return (pFLASH->INT_STATUS & ~FLASH_ECC_ERR);
+}
+
+/**
+ * @brief      Return unfiltered FLASH INT_STATUS.
+ * In normal operation FLASH_DONE rises systematically but other status bits
+ * may rise at the same time or have risen before to notify of an error.
+ * Usually testing the value returned by FLASH_Wait is sufficionet but in some special
+ * cases the raw value may be needed.
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral.
+ *
+ * @return     INT_STATUS raw value.
+ * @see flash_status_t
+ */
+int FLASH_GetStatus(FLASH_Type *pFLASH)
+{
+    return pFLASH->INT_STATUS;
+}
+
+/**
+ * @brief      Erase page
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Erase(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End)
+{
+    int status = 0;
+
+    uint32_t erase_length = pu8End - pu8Start;
+
+    while (erase_length > 0)
+    {
+        pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+        if (erase_length > MAX_ERASE_LENGTH)
+        {
+            pu8End = pu8Start + MAX_ERASE_LENGTH - 1;
+            erase_length -= MAX_ERASE_LENGTH;
+        }
+        else
+        {
+            pu8End       = pu8Start + erase_length;
+            erase_length = 0;
+        }
+
+        /* Set end address */
+        *pu8End = 0xAA;
+
+        /* Set start address */
+        *pu8Start = 0xBB;
+
+        pu8Start = pu8End + 1;
+
+        pFLASH->CMD = FLASH_CMD_ERASE_RANGE;
+
+        status = FLASH_Wait(pFLASH);
+    }
+
+    return status;
+}
+
+/**
+ * @brief      Erase multiple pages
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  u32StartPage Index of page to start erasing from
+ * @param[in]  u32PageCount Number of pages to erase
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_ErasePages(FLASH_Type *pFLASH, uint32_t u32StartPage, uint32_t u32PageCount)
+{
+    uint8_t *pu8Start = (uint8_t *)(FLASH_PAGE_SIZE * u32StartPage);
+    uint8_t *pu8End   = (pu8Start + FLASH_PAGE_SIZE * u32PageCount) - 1;
+
+    return FLASH_Erase(pFLASH, pu8Start, pu8End);
+}
+
+/**
+ * @brief      Page Blank check
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_BlankCheck(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End)
+{
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    /* Set end address */
+    *pu8End = 0xAA;
+
+    /* Set start address */
+    *pu8Start = 0xBB;
+
+    pFLASH->CMD = FLASH_CMD_BLANK_CHECK;
+
+    return FLASH_Wait(pFLASH);
+}
+
+/**
+ * @brief      Margin Check
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_MarginCheck(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End)
+{
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    /* Set end address */
+    *pu8End = 0xAA;
+
+    /* Set start address */
+    *pu8Start = 0xBB;
+
+    pFLASH->CMD = FLASH_CMD_MARGIN_CHECK;
+
+    return FLASH_Wait(pFLASH);
+}
+
+/**
+ * @brief      Program page
+ *
+ * @param[in]  pFLASH Pointer to selected FLASH peripheral
+ * @param[out] pu32Start Pointer location that must be programmed in flash
+ * @param[in]  pu32Data Pointer to source buffer being written to flash
+ * @param[in]  u32Length Number of bytes to be programmed
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Program(FLASH_Type *pFLASH, uint32_t *pu32Start, uint32_t *pu32Data, uint32_t u32Length)
+{
+    int status = 0;
+
+    uint32_t end  = (uint32_t)pu32Start + u32Length;
+
+    uint32_t padding  = (FLASH_PAGE_SIZE - (end & (FLASH_PAGE_SIZE-1))) & (FLASH_PAGE_SIZE-1);
+
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    pFLASH->AUTOPROG = FLASH_AUTO_PAGE;
+
+    memcpy(pu32Start, pu32Data, u32Length);
+
+    while (padding-- > 0)
+    {
+        *(uint8_t*)end ++ = 0;
+    }
+
+    status = FLASH_Wait(pFLASH);
+
+    pFLASH->AUTOPROG = FLASH_AUTO_OFF;
+
+    return status;
+}
+
+/**
+ * @brief      Page Checksum
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Pointer to data within starting page  page checksum must be computed
+ * @param[in]  pu8End Pointer to data whose page is the last of the checksum calculation
+ * @param[out] au32Checksum Four 32bit word array to store checksum calculation result
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Checksum(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End, uint32_t au32Checksum[4])
+{
+    int status;
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    /* Set end address */
+    *pu8End = 0xAA;
+
+    /* Set start address */
+    *pu8Start = 0xBB;
+
+    pFLASH->CMD = FLASH_CMD_CHECKSUM;
+
+    status = FLASH_Wait(pFLASH);
+
+    au32Checksum[0] = pFLASH->DATAW[0];
+    au32Checksum[1] = pFLASH->DATAW[1];
+    au32Checksum[2] = pFLASH->DATAW[2];
+    au32Checksum[3] = pFLASH->DATAW[3];
+
+    return status;
+}
+
+/**
+ * @brief      Read flash word (16 byte worth of data)
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Pointer to data to be read
+ * @param[in]  u32ReadMode Read mode see also flash_read_mode_t
+ * @param[out] au32Data Four 32bit word array to store read result
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Read(FLASH_Type *pFLASH, uint8_t *pu8Start, uint32_t u32ReadMode, uint32_t au32Data[4])
+{
+    int status;
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    /* Set start address */
+    *pu8Start = 0xBB;
+
+    /* Set read mode */
+    pFLASH->DATAW[0] = u32ReadMode;
+
+    pFLASH->CMD = FLASH_CMD_READ_SINGLE_WORD;
+
+    status = FLASH_Wait(pFLASH);
+
+    au32Data[0] = pFLASH->DATAW[0];
+    au32Data[1] = pFLASH->DATAW[1];
+    au32Data[2] = pFLASH->DATAW[2];
+    au32Data[3] = pFLASH->DATAW[3];
+
+    return status;
+}
+
+/*
+* Details on the fields that can be updated through the FLASH_CMD_SET_READ_MODE cmd.
+* bit 31   : prefetch enable
+* bit 30   : ignore hprot[0] and assume that all accesses are code accesses
+* bit 29-28: 00: hprot[3] specifies whether an access is cacheable
+*            01: reserved
+*            10: hprot[3] ignored, all accesses are not cacheable
+*            11: hprot[3] ignored, all accesses are cacheable
+* bit 27-8 : reserved
+* bit 7    : ewle read mode active. Default value after reset is: 0
+* bit 6-4  : number of extra precharge states.
+* bit 3-0  : number of extra evaluation states.
+*
+* After reset, the only value field set is the "number of extra evaluation states" field. In other words, if you want to
+* return to the default values, you shall write DEFAULT_READ_MODE to DATAW[0]
+*/
+#define DEFAULT_READ_MODE_VAL          0x00000000
+#define EWLE_MODE_MASK                 0x80
+
+/**
+ * @brief      Configure the flash wait state depending of the elwe mode and CPU frequency.
+ * When the CPU clock frequency is decreased, the Set Read command shall be called after the frequency change.
+ * When the CPU clock frequency is increased, the Set Read command shall be called before the frequency change.
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ * @param      freq_48M_not_32M CPU clock frequency @48MHz - lower or equal to 32Mhz if 0
+ *
+ * @return     Nothing
+ */
+void FLASH_SetReadMode(FLASH_Type *pFLASH, bool cpu_freq_48M_not_32M)
+{
+   int flash_ws = DEFAULT_READ_MODE_VAL;
+
+   pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+   flash_ws += cpu_freq_48M_not_32M ? 1 : 0;
+
+   pFLASH->DATAW[0] = (EWLE_MODE_MASK | flash_ws);
+
+   pFLASH->CMD = FLASH_CMD_SET_READ_MODE;
+
+   /* no need to wait until command is completed: further accesses are stalled
+    * until the command is completed. */
+   //status = FLASH_Wait(pFLASH);
+}
+
+/**
+ * @brief      Calculate checksum using the same checksum algorithm as the CMD_CHECKSUM implementation of the
+ * Flash controller. When executed over a 512 byte page (page size) must return the same value as FLASH_Checksum.
+ *
+ * @param[in]  input Pointer to data over which checksum calculation must be executed.
+ * @param[in]  nb_128b_words Number of 16 byte words on flash.
+ * @param[out] misr Pointer on a four 32bit word array to store calculated checksum.
+ * @param[in]  init Set to true to clear the misr buffer.
+ *
+ * @return     Nothing
+ */
+void FLASH_CalculateChecksum(const uint32_t *input,
+                            size_t nb_128b_words,
+                            uint32_t* misr,
+                            int init)
+{
+    int i;
+
+    if (init)
+    {
+        for (i = 0; i < 4; i++)
+        {
+            misr[i] = 0;
+        }
+    }
+
+    for (i = 0; i < nb_128b_words*4; )
+    {
+        int cy;
+
+        /* Compute carry */
+        cy = PARITY(misr[0]);
+        /* Shift right the 128 bits */
+        RSHIFT_128BIT(misr, 1UL);
+        /* Let Carry become the MISR[127] bit */
+        misr[3] ^= (uint32_t)((cy&1UL) << 31);
+
+        /* Xor with 128 bit word */
+        misr[0] ^= input[i++];
+        misr[1] ^= input[i++];
+        misr[2] ^= input[i++];
+        misr[3] ^= input[i++];
+    }
+
+}
+
+/*
+ * Expected values for Config page checksum and GPO checksum.
+ */
+const uint32_t CONFIG_PAGE_CHSUM[4] = {0x11112222U, 0x33334444U, 0x55556666U, 0x77778888U};
+const uint32_t GPO_CHKSUM[4] =         {0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U};
+
+/**
+ * @brief      Calculate checksum over page (N-2) aka CONFIG page and check it matches the expected value.
+ *
+ * @param[in]  page_buffer Pointer to data over which checksum calculation must be executed.
+ * @param[out] misr Pointer on a four 32bit word array to store calculated checksum.
+ *             Note: this buffer is only useful for debugging purposes.
+ *
+ * @return Result of the page checksum verification:
+ *         -  0: Verification successfully.
+ *         - -1: Verification failed.
+ */
+int FLASH_ConfigPageVerifyPageChecksum(const uint32_t *page_buffer,
+                                      uint32_t *misr)
+{
+    int res = 0;
+    FLASH_CalculateChecksum(page_buffer, 32, &misr[0], 1);
+    for (int i = 0; i < 4; i++)
+    {
+        if (misr[i] != CONFIG_PAGE_CHSUM[i])
+        {
+            res = -1;
+            break;
+        }
+    }
+    return res;
+}
+
+/**
+ * @brief      Calculate checksum over GPO array of CONFIG page and check it matches the expected value
+ *
+ * @param[in]  page_buffer Pointer to data over which checksum calculation must be executed.
+ * @param[out] misr Pointer on a 4 32bit word array to store calculated checksum.
+ *             Note: this buffer is only useful for debugging purposes.
+ *
+ * @return Result of the GPO array checksum verification:
+ *         -  0: Verification successfully.
+ *         - -1: Verification failed.
+ */
+int FLASH_ConfigPageVerifyGpoChecksum(const uint32_t *page_buffer,
+                                     uint32_t *misr)
+{
+    int res = 0;
+    FLASH_CalculateChecksum(page_buffer, 5, misr, 1);
+    for (int i = 0; i < 4; i++)
+    {
+        if (misr[i] != GPO_CHKSUM[i])
+        {
+            res = -1;
+            break;
+        }
+    }
+    return res;
+}
+
+/**
+ * @brief      Configure the flash wait state depending of the elwe mode and CPU frequency.
+ * When the CPU clock frequency is decreased, the Set Read command shall be called after the frequency change.
+ * When the CPU clock frequency is increased, the Set Read command shall be called before the frequency change.
+ *
+ * @param      page_ram_buffer Pointer to RAM page buffer in which the read-modify-write of page (N-2) is performed
+ * @param      gpo_chksum Pointer on a four 32bit word array to store calculated checksum.
+ * @param      page_chksum Pointer on a four 32bit word array to store calculated checksum.
+ *
+ * @return     Nothing
+ */
+void FLASH_ConfigPageUpdate(uint32_t *page_ram_buffer,
+                          uint32_t *gpo_chksum,
+                          uint32_t *page_chksum )
+{
+
+    FLASH_CalculateChecksum(page_ram_buffer, 4, gpo_chksum, 1);
+    FLASH_CalculateChecksum(GPO_CHKSUM, 1, gpo_chksum, 0);
+    for (int i = 0; i < 4; i++)
+    {
+        page_ram_buffer[16+i] = gpo_chksum[i];
+    }
+    FLASH_CalculateChecksum(&page_ram_buffer[0], 31, page_chksum, 1);
+    FLASH_CalculateChecksum(CONFIG_PAGE_CHSUM, 1, page_chksum, 0);
+    for (int i = 0; i < 4; i++)
+    {
+        page_ram_buffer[124+i] = page_chksum[i];
+    }
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flash.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flash.h
new file mode 100755
index 0000000..c21953c
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flash.h
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FSL_FLASH_H_
+#define __FSL_FLASH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup jn_flash
+ * @{
+ */
+
+/*! @file */
+
+/*******************
+ * EXPORTED MACROS  *
+ ********************/
+
+/* FLASH Commands */
+#define FLASH_CMD_INIT 0
+#define FLASH_CMD_POWERDOWN 1
+#define FLASH_CMD_SET_READ_MODE 2
+#define FLASH_CMD_READ_SINGLE_WORD 3
+#define FLASH_CMD_ERASE_RANGE 4
+#define FLASH_CMD_BLANK_CHECK 5
+#define FLASH_CMD_MARGIN_CHECK 6
+#define FLASH_CMD_CHECKSUM 7
+#define FLASH_CMD_WRITE 8
+#define FLASH_CMD_WRITE_PROG 10
+#define FLASH_CMD_PROGRAM 12
+#define FLASH_CMD_REPORT_ECC 13
+
+/* FLASH Autoprogram modes */
+#define FLASH_AUTO_OFF 0
+#define FLASH_AUTO_WORD 1
+#define FLASH_AUTO_PAGE 2
+
+#define FLASH_BASE_ADDRESS 0
+#define FLASH_PAGE_SIZE 512
+#define FLASH_PAGE_SIZE_LOG 9
+
+#define FLASH_CONFIG_PAGE_ADDR 0x9fc00
+#define FLASH_TRIMMING_DATA_ADDR 0x9fe00
+
+/**
+ * @brief FLASH INT_STATUS register definitions
+ */
+#define FLASH_FAIL (1 << 0)    /*!< Command failed */
+#define FLASH_ERR (1 << 1)     /*!< Illegal command */
+#define FLASH_DONE (1 << 2)    /*!< Command complete */
+#define FLASH_ECC_ERR (1 << 3) /*!< ECC error detected */
+
+/**
+ * @brief FLASH INT_ENABLE register definitions
+ */
+#define FLASH_FAIL (1 << 0)    /*!< Command failed */
+#define FLASH_ERR (1 << 1)     /*!< Illegal command */
+#define FLASH_DONE (1 << 2)    /*!< Command complete */
+#define FLASH_ECC_ERR (1 << 3) /*!< ECC error detected */
+
+#define FLASH_STAT_ALL (0xF)
+
+/* FLASH Events */
+#define FLASH_EVENT_RESET (1 << 0)
+//#define FLASH_EVENT_WAKEUP         (1 << 1)
+//#define FLASH_EVENT_ABORT          (1 << 2)
+
+/******************************
+ * EXPORTED TYPE DEFINITIONS  *
+ ******************************/
+typedef enum _flash_status
+{
+    kStatus_FLASH_Success         = FLASH_DONE,                             /*!< flash operation is successful*/
+    kStatus_FLASH_Fail            = FLASH_DONE | FLASH_FAIL,                /*!< flash operation is not successful*/
+    kStatus_FLASH_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),   /*!< Invalid argument */
+    kStatus_FLASH_AlignmentError  = MAKE_STATUS(kStatusGroup_FLASH, 6),     /*!< Alignment Error */
+    kStatus_FLASH_EccError        = FLASH_DONE | FLASH_ECC_ERR,             /*!< ECC error detected */
+    kStatus_FLASH_Error           = FLASH_DONE | FLASH_ERR,                 /*!< Illegal command */
+} flash_status_t;
+
+
+/* Read Mode related definitions */
+#define FLASH_READ_MODE_RD_DMACC_SHIFT    15
+#define FLASH_READ_MODE_SHIFT             10
+#define FLASH_READ_MODE_NORMAL             0
+#define FLASH_READ_MODE_MARGIN_VS_PROGRAM  1
+#define FLASH_READ_MODE_MARGIN_VS_ERASE    2
+#define FLASH_READ_MODE_ILLEGAL            3
+#define FLASH_READ_MODE_MASK (FLASH_READ_MODE_ILLEGAL << FLASH_READ_MODE_SHIFT)
+#define FLASH_READ_MODE_ECC_OFF_SHIFT      2
+
+typedef enum _flash_read_modes
+{
+    FLASH_ReadModeNormal         = (FLASH_READ_MODE_NORMAL << FLASH_READ_MODE_SHIFT),
+    FLASH_ReadModeNormalEccOff   = (FLASH_READ_MODE_NORMAL << FLASH_READ_MODE_SHIFT)|(1<<FLASH_READ_MODE_ECC_OFF_SHIFT),                /*!< flash operation is not successful*/
+    FLASH_ReadModeDMACC          = (1<<FLASH_READ_MODE_RD_DMACC_SHIFT),
+    FLASH_ReadModeMarginProgram  = (FLASH_READ_MODE_MARGIN_VS_PROGRAM << FLASH_READ_MODE_SHIFT),
+    FLASH_ReadModeMarginErase    = (FLASH_READ_MODE_MARGIN_VS_ERASE << FLASH_READ_MODE_SHIFT),
+} flash_read_mode_t;
+
+/*! @brief Flash configuration information.
+ *
+ * An instance of this structure is allocated by the user of the flash driver and
+ * at initialization.
+ */
+typedef struct _flash_config
+{
+    uint32_t PFlashBlockBase;  /*!< A base address of the first PFlash block */
+    uint32_t PFlashTotalSize;  /*!< The size of the combined PFlash block. */
+    uint32_t PFlashSectorSize; /*!< The size in bytes of a sector of PFlash. */
+} flash_config_t;
+
+extern flash_config_t gFlashConfig;
+
+/**
+ * @brief      Enable the FLASH
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     Nothing
+ */
+void FLASH_Init(FLASH_Type *pFLASH);
+
+/**
+ * @brief      Power down the FLASH
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     Nothing
+ */
+void FLASH_Powerdown(FLASH_Type *pFLASH);
+
+/**
+ * @brief      Wait for FLASH command to complete
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ */
+int FLASH_Wait(FLASH_Type *pFLASH);
+
+/**
+ * @brief      Erase page
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Erase(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End);
+
+/**
+ * @brief      Erase multiple pages
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  u32StartPage Index of page to start erasing from
+ * @param[in]  u32PageCount Number of pages to erase
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_ErasePages(FLASH_Type *pFLASH, uint32_t u32StartPage, uint32_t u32PageCount);
+
+/**
+ * @brief      Page Blank check
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_BlankCheck(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End);
+
+/**
+ * @brief      Margin Check
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_MarginCheck(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End);
+
+/**
+ * @brief      Program page
+ *
+ * @param[in]  pFLASH Pointer to selected FLASH peripheral
+ * @param[out] pu32Start Pointer location that must be programmed in flash
+ * @param[in]  pu32Data Pointer to source buffer being written to flash
+ * @param[in]  u32Length Number of bytes to be programmed
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Program(FLASH_Type *pFLASH, uint32_t *pu32Start, uint32_t *pu32Data, uint32_t u32Length);
+
+/**
+ * @brief      Page Checksum
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Pointer to data within starting page  page checksum must be computed
+ * @param[in]  pu8End Pointer to data whose page is the last of the checksum calculation
+ * @param[out] au32Checksum Four 32bit word array to store checksum calculation result
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Checksum(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End, uint32_t au32Checksum[4]);
+
+/**
+ * @brief      Read flash word (16 byte worth of data)
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Pointer to data to be read
+ * @param[in]  u32ReadMode Read mode see also flash_read_mode_t
+ * @param[out] au32Data Four 32bit word array to store read result
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Read(FLASH_Type *pFLASH, uint8_t *pu8Start, uint32_t u32ReadMode, uint32_t au32Data[4]);
+
+/**
+ * @brief      Configure the flash wait state depending of the elwe mode and CPU frequency.
+ * When the CPU clock frequency is decreased, the Set Read command shall be called after the frequency change.
+ * When the CPU clock frequency is increased, the Set Read command shall be called before the frequency change.
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ * @param      freq_48M_not_32M CPU clock frequency @48MHz - lower or equal to 32Mhz if 0
+ *
+ * @return     Nothing
+ */
+void FLASH_SetReadMode(FLASH_Type *pFLASH, bool freq_48M_not_32M);
+
+/**
+ * @brief      Calculate checksum using the same checksum algorithm as the CMD_CHECKSUM implementation of the
+ * Flash controller. When executed over a 512 byte page (page size) must return the same value as FLASH_Checksum.
+ *
+ * @param[in]  input Pointer to data over which checksum calculation must be executed.
+ * @param[in]  nb_128b_words Number of 16 byte words on flash.
+ * @param[out] misr Pointer on a four 32bit word array to store calculated checksum.
+ * @param[in]  init Set to true to clear the misr buffer.
+ *
+ * @return     Nothing
+ */
+void FLASH_CalculateChecksum(const uint32_t *input,
+                            size_t nb_128b_words,
+                            uint32_t* misr,
+                            int init);
+
+/**
+ * @brief      Calculate checksum over page (N-2) aka CONFIG page and check it matches the expected value.
+ *
+ * @param[in]  page_buffer Pointer to data over which checksum calculation must be executed.
+ * @param[out] misr Pointer on a four 32bit word array to store calculated checksum.
+ *             Note: this buffer is only useful for debugging purposes.
+ *
+ * @return Result of the page checksum verification:
+ *         -  0: Verify successfully.
+ *         - -1: Verification failed.
+ */
+int FLASH_ConfigPageVerifyPageChecksum(const uint32_t *page_buffer,
+                                      uint32_t *misr);
+
+/**
+ * @brief      Calculate checksum over GPO array of CONFIG page and check it matches the expected value
+ *
+ * @param[in]  page_buffer Pointer to data over which checksum calculation must be executed.
+ * @param[out] misr Pointer on a 4 32bit word array to store calculated checksum.
+ *             Note: this buffer is only useful for debugging purposes.
+ *
+ * @return Result of the GPO array checksum verification:
+ *         -  0: Verify successfully.
+ *         - -1: Verification failed.
+ */
+int FLASH_ConfigPageVerifyGpoChecksum(const uint32_t *page_buffer,
+                                     uint32_t *misr);
+
+/**
+ * @brief      Configure the flash wait state depending of the elwe mode and CPU frequency.
+ * When the CPU clock frequency is decreased, the Set Read command shall be called after the frequency change.
+ * When the CPU clock frequency is increased, the Set Read command shall be called before the frequency change.
+ *
+ * @param      page_ram_buffer Pointer to RAM page buffer in which the read-modify-write of page (N-2) is performed
+ * @param      gpo_chksum Pointer on a four 32bit word array to store calculated checksum.
+ * @param      page_chksum Pointer on a four 32bit word array to store calculated checksum.
+ *
+ * @return     Nothing
+ */
+void FLASH_ConfigPageUpdate(uint32_t *page_ram_buffer,
+                          uint32_t *gpo_chksum,
+                          uint32_t *page_chksum);
+
+/**
+ * @brief      Return unfiltered FLASH INT_STATUS.
+ * In normal operation FLASH_DONE rises systematically but other status bits
+ * may rise at the same time or have risen before to notify of an error.
+ * Usually testing the value returned by FLASH_Wait is sufficionet but in some special
+ * cases the raw value may be needed.
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral.
+ *
+ * @return     INT_STATUS raw value.
+ * @see flash_status_t
+ */
+int FLASH_GetStatus(FLASH_Type *pFLASH);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FSL_FLASH_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flexcomm.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flexcomm.c
new file mode 100755
index 0000000..d51eb72
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flexcomm.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_flexcomm.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.flexcomm"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*! @brief Set the FLEXCOMM mode . */
+static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);
+
+/*! @brief check whether flexcomm supports peripheral type */
+static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */
+static flexcomm_irq_handler_t s_flexcommIrqHandler[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
+
+/*! @brief Pointers to handles for each instance to provide context to interrupt routines */
+static void *s_flexcommHandle[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
+
+/*! @brief Array to map FLEXCOMM instance number to IRQ number. */
+IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;
+
+/*! @brief Array to map FLEXCOMM instance number to base address. */
+static const uint32_t s_flexcommBaseAddrs[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = FLEXCOMM_BASE_ADDRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief IDs of clock for each FLEXCOMM module */
+static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
+/*! @brief Pointers to FLEXCOMM resets for each instance. */
+static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/* check whether flexcomm supports peripheral type */
+static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)
+{
+    if (periph == FLEXCOMM_PERIPH_NONE)
+    {
+        return true;
+    }
+    else if (periph <= FLEXCOMM_PERIPH_I2S_TX)
+    {
+        return (base->PSELID & (uint32_t)(1 << ((uint32_t)periph + 3))) > (uint32_t)0 ? true : false;
+    }
+    else if (periph == FLEXCOMM_PERIPH_I2S_RX)
+    {
+        return (base->PSELID & (1 << 7)) > (uint32_t)0 ? true : false;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+/* Get the index corresponding to the FLEXCOMM */
+/*! brief Returns instance number for FLEXCOMM module with given base address. */
+uint32_t FLEXCOMM_GetInstance(void *base)
+{
+    int i;
+
+    for (i = 0; i < FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)
+    {
+        if ((uint32_t)base == s_flexcommBaseAddrs[i])
+        {
+            return i;
+        }
+    }
+
+    assert(false);
+    return 0;
+}
+
+/* Changes FLEXCOMM mode */
+static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)
+{
+    /* Check whether peripheral type is present */
+    if (!FLEXCOMM_PeripheralIsPresent(base, periph))
+    {
+        return kStatus_OutOfRange;
+    }
+
+    /* Flexcomm is locked to different peripheral type than expected  */
+    if ((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) && ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != periph))
+    {
+        return kStatus_Fail;
+    }
+
+    /* Check if we are asked to lock */
+    if (lock)
+    {
+        base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;
+    }
+    else
+    {
+        base->PSELID = (uint32_t)periph;
+    }
+
+    return kStatus_Success;
+}
+
+/*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
+status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)
+{
+    int idx = FLEXCOMM_GetInstance(base);
+
+    if (idx < 0)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* Enable the peripheral clock */
+    CLOCK_EnableClock(s_flexcommClocks[idx]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
+    /* Reset the FLEXCOMM module */
+    RESET_PeripheralReset(s_flexcommResets[idx]);
+#endif
+
+    /* Set the FLEXCOMM to given peripheral */
+    return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);
+}
+
+/*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
+ * mode */
+void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle)
+{
+    uint32_t instance;
+
+    /* Look up instance number */
+    instance = FLEXCOMM_GetInstance(base);
+
+    /* Clear handler first to avoid execution of the handler with wrong handle */
+    s_flexcommIrqHandler[instance] = NULL;
+    s_flexcommHandle[instance]     = handle;
+    s_flexcommIrqHandler[instance] = handler;
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+
+/* IRQ handler functions overloading weak symbols in the startup */
+#if defined(FLEXCOMM0)
+void FLEXCOMM0_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[0]);
+    s_flexcommIrqHandler[0]((void *)s_flexcommBaseAddrs[0], s_flexcommHandle[0]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM1)
+void FLEXCOMM1_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[1]);
+    s_flexcommIrqHandler[1]((void *)s_flexcommBaseAddrs[1], s_flexcommHandle[1]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM2)
+void FLEXCOMM2_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[2]);
+    s_flexcommIrqHandler[2]((void *)s_flexcommBaseAddrs[2], s_flexcommHandle[2]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM3)
+void FLEXCOMM3_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[3]);
+    s_flexcommIrqHandler[3]((void *)s_flexcommBaseAddrs[3], s_flexcommHandle[3]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM4)
+void FLEXCOMM4_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[4]);
+    s_flexcommIrqHandler[4]((void *)s_flexcommBaseAddrs[4], s_flexcommHandle[4]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+
+#endif
+
+#if defined(FLEXCOMM5)
+void FLEXCOMM5_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[5]);
+    s_flexcommIrqHandler[5]((void *)s_flexcommBaseAddrs[5], s_flexcommHandle[5]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM6)
+void FLEXCOMM6_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[6]);
+    s_flexcommIrqHandler[6]((void *)s_flexcommBaseAddrs[6], s_flexcommHandle[6]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM7)
+void FLEXCOMM7_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[7]);
+    s_flexcommIrqHandler[7]((void *)s_flexcommBaseAddrs[7], s_flexcommHandle[7]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM8)
+void FLEXCOMM8_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[8]);
+    s_flexcommIrqHandler[8]((void *)s_flexcommBaseAddrs[8], s_flexcommHandle[8]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM9)
+void FLEXCOMM9_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[9]);
+    s_flexcommIrqHandler[9]((void *)s_flexcommBaseAddrs[9], s_flexcommHandle[9]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM10)
+void FLEXCOMM10_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[10]);
+    s_flexcommIrqHandler[10]((void *)s_flexcommBaseAddrs[10], s_flexcommHandle[10]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM11)
+void FLEXCOMM11_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[11]);
+    s_flexcommIrqHandler[11]((void *)s_flexcommBaseAddrs[11], s_flexcommHandle[11]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM12)
+void FLEXCOMM12_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[12]);
+    s_flexcommIrqHandler[12]((void *)s_flexcommBaseAddrs[12], s_flexcommHandle[12]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM13)
+void FLEXCOMM13_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[13]);
+    s_flexcommIrqHandler[13]((void *)s_flexcommBaseAddrs[13], s_flexcommHandle[13]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM14)
+void FLEXCOMM14_DriverIRQHandler(void)
+{
+    uint32_t instance;
+
+    /* Look up instance number */
+    instance = FLEXCOMM_GetInstance(FLEXCOMM14);
+    assert(s_flexcommIrqHandler[instance]);
+    s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM15)
+void FLEXCOMM15_DriverIRQHandler(void)
+{
+    uint32_t instance;
+
+    /* Look up instance number */
+    instance = FLEXCOMM_GetInstance(FLEXCOMM15);
+    assert(s_flexcommIrqHandler[instance]);
+    s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM16)
+void FLEXCOMM16_DriverIRQHandler(void)
+{
+    uint32_t instance;
+
+    /* Look up instance number */
+    instance = FLEXCOMM_GetInstance(FLEXCOMM16);
+    assert(s_flexcommIrqHandler[instance]);
+    s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flexcomm.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flexcomm.h
new file mode 100755
index 0000000..cf5b6ef
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_flexcomm.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_FLEXCOMM_H_
+#define _FSL_FLEXCOMM_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup flexcomm_driver
+ * @{
+ */
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief FlexCOMM driver version 2.0.2. */
+#define FSL_FLEXCOMM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
+/*@}*/
+
+/*! @brief FLEXCOMM peripheral modes. */
+typedef enum
+{
+    FLEXCOMM_PERIPH_NONE,   /*!< No peripheral */
+    FLEXCOMM_PERIPH_USART,  /*!< USART peripheral */
+    FLEXCOMM_PERIPH_SPI,    /*!< SPI Peripheral */
+    FLEXCOMM_PERIPH_I2C,    /*!< I2C Peripheral */
+    FLEXCOMM_PERIPH_I2S_TX, /*!< I2S TX Peripheral */
+    FLEXCOMM_PERIPH_I2S_RX, /*!< I2S RX Peripheral */
+} FLEXCOMM_PERIPH_T;
+
+/*! @brief Typedef for interrupt handler. */
+typedef void (*flexcomm_irq_handler_t)(void *base, void *handle);
+
+/*! @brief Array with IRQ number for each FLEXCOMM module. */
+extern IRQn_Type const kFlexcommIrqs[];
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*! @brief Returns instance number for FLEXCOMM module with given base address. */
+uint32_t FLEXCOMM_GetInstance(void *base);
+
+/*! @brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
+status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph);
+
+/*! @brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
+ * mode */
+void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*@}*/
+
+#endif /* _FSL_FLEXCOMM_H_*/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_gpio.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_gpio.c
new file mode 100755
index 0000000..926880f
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_gpio.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_gpio.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.lpc_gpio"
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Array to map FGPIO instance number to clock name. */
+static const clock_ip_name_t s_gpioClockName[] = GPIO_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
+/*! @brief Pointers to GPIO resets for each instance. */
+static const reset_ip_name_t s_gpioResets[] = GPIO_RSTS_N;
+#endif
+/*******************************************************************************
+ * Prototypes
+ ************ ******************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+/*!
+ * brief Initializes the GPIO peripheral.
+ *
+ * This function ungates the GPIO clock.
+ *
+ * param base   GPIO peripheral base pointer.
+ * param port   GPIO port number.
+ */
+void GPIO_PortInit(GPIO_Type *base, uint32_t port)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    assert(port < ARRAY_SIZE(s_gpioClockName));
+
+    /* Upgate the GPIO clock */
+    CLOCK_EnableClock(s_gpioClockName[port]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
+    /* Reset the GPIO module */
+    RESET_PeripheralReset(s_gpioResets[port]);
+#endif
+}
+
+/*!
+ * brief Initializes a GPIO pin used by the board.
+ *
+ * To initialize the GPIO, define a pin configuration, either input or output, in the user file.
+ * Then, call the GPIO_PinInit() function.
+ *
+ * This is an example to define an input pin or output pin configuration:
+ * code
+ * // Define a digital input pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalInput,
+ *   0,
+ * }
+ * //Define a digital output pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalOutput,
+ *   0,
+ * }
+ * endcode
+ *
+ * param base   GPIO peripheral base pointer(Typically GPIO)
+ * param port   GPIO port number
+ * param pin    GPIO pin number
+ * param config GPIO pin configuration pointer
+ */
+void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config)
+{
+    if (config->pinDirection == kGPIO_DigitalInput)
+    {
+#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
+        base->DIRCLR[port] = 1U << pin;
+#else
+        base->DIR[port] &= ~(1U << pin);
+#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
+    }
+    else
+    {
+        /* Set default output value */
+        if (config->outputLogic == 0U)
+        {
+            base->CLR[port] = (1U << pin);
+        }
+        else
+        {
+            base->SET[port] = (1U << pin);
+        }
+/* Set pin direction */
+#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
+        base->DIRSET[port] = 1U << pin;
+#else
+        base->DIR[port] |= 1U << pin;
+#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
+    }
+}
+
+#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
+/*!
+ * @brief Configures the gpio pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param pin GPIO pin number.
+ * @param config GPIO pin interrupt configuration..
+ */
+void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config)
+{
+    base->INTEDG[port] = base->INTEDG[port] | (config->mode << pin);
+
+    base->INTPOL[port] = base->INTPOL[port] | (config->polarity << pin);
+}
+
+/*!
+ * @brief Enables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTENA[port] = base->INTENA[port] | mask;
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTENB[port] = base->INTENB[port] | mask;
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @brief Disables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTENA[port] = base->INTENA[port] & ~mask;
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTENB[port] = base->INTENB[port] & ~mask;
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @brief Clears multiple pins interrupt flag. Status flags are cleared by
+ *        writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTSTATA[port] = mask;
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTSTATB[port] = mask;
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @ Read port interrupt status.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param index GPIO interrupt number.
+ * @retval masked GPIO status value
+ */
+uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index)
+{
+    uint32_t status = 0U;
+
+    if (kGPIO_InterruptA == index)
+    {
+        status = base->INTSTATA[port];
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        status = base->INTSTATB[port];
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+    return status;
+
+}
+
+/*!
+ * @brief Enables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTENA[port] = base->INTENA[port] | (1U << pin);
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTENB[port] = base->INTENB[port] | (1U << pin);
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @brief Disables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTENA[port] = base->INTENA[port] & ~(1U << pin);
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTENB[port] = base->INTENB[port] & ~(1U << pin);
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @brief Clears the specific pin interrupt flag. Status flags are cleared by
+ *        writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTSTATA[port] = 1U << pin;
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTSTATB[port] = 1U << pin;
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_gpio.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_gpio.h
new file mode 100755
index 0000000..71c7091
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_gpio.h
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _LPC_GPIO_H_
+#define _LPC_GPIO_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup lpc_gpio
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief LPC GPIO driver version 2.1.3. */
+#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 4))
+/*@}*/
+
+/*! @brief LPC GPIO direction definition */
+typedef enum _gpio_pin_direction
+{
+    kGPIO_DigitalInput = 0U,  /*!< Set current pin as digital input*/
+    kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
+} gpio_pin_direction_t;
+
+/*!
+ * @brief The GPIO pin configuration structure.
+ *
+ * Every pin can only be configured as either output pin or input pin at a time.
+ * If configured as a input pin, then leave the outputConfig unused.
+ */
+typedef struct _gpio_pin_config
+{
+    gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */
+    /* Output configurations, please ignore if configured as a input one */
+    uint8_t outputLogic; /*!< Set default output logic, no use in input */
+} gpio_pin_config_t;
+
+#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT)
+#define GPIO_PIN_INT_LEVEL 0x00U
+#define GPIO_PIN_INT_EDGE 0x01U
+
+#define PINT_PIN_INT_HIGH_OR_RISE_TRIGGER 0x00U
+#define PINT_PIN_INT_LOW_OR_FALL_TRIGGER 0x01U
+
+/*! @brief GPIO Pin Interrupt enable mode */
+typedef enum _gpio_pin_enable_mode
+{
+    kGPIO_PinIntEnableLevel = GPIO_PIN_INT_LEVEL, /*!< Generate Pin Interrupt on level mode */
+    kGPIO_PinIntEnableEdge = GPIO_PIN_INT_EDGE    /*!< Generate Pin Interrupt on edge mode */
+} gpio_pin_enable_mode_t;
+
+/*! @brief GPIO Pin Interrupt enable polarity */
+typedef enum _gpio_pin_enable_polarity
+{
+    kGPIO_PinIntEnableHighOrRise =
+        PINT_PIN_INT_HIGH_OR_RISE_TRIGGER, /*!< Generate Pin Interrupt on high level or rising edge */
+    kGPIO_PinIntEnableLowOrFall =
+        PINT_PIN_INT_LOW_OR_FALL_TRIGGER /*!< Generate Pin Interrupt on low level or falling edge */
+} gpio_pin_enable_polarity_t;
+
+/*! @brief LPC GPIO interrupt index definition */
+typedef enum _gpio_interrupt_index
+{
+    kGPIO_InterruptA = 0U, /*!< Set current pin as interrupt A*/
+    kGPIO_InterruptB = 1U, /*!< Set current pin as interrupt B*/
+} gpio_interrupt_index_t;
+
+/*! @brief Configures the interrupt generation condition. */
+typedef struct _gpio_interrupt_config
+{
+    uint8_t mode;         /* The trigger mode of GPIO interrupts */
+    uint8_t polarity;     /* The polarity of GPIO interrupts */
+} gpio_interrupt_config_t;
+#endif
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/*! @name GPIO Configuration */
+/*@{*/
+
+/*!
+ * @brief Initializes the GPIO peripheral.
+ *
+ * This function ungates the GPIO clock.
+ *
+ * @param base   GPIO peripheral base pointer.
+ * @param port   GPIO port number.
+ */
+void GPIO_PortInit(GPIO_Type *base, uint32_t port);
+
+/*!
+ * @brief Initializes a GPIO pin used by the board.
+ *
+ * To initialize the GPIO, define a pin configuration, either input or output, in the user file.
+ * Then, call the GPIO_PinInit() function.
+ *
+ * This is an example to define an input pin or output pin configuration:
+ * @code
+ * // Define a digital input pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalInput,
+ *   0,
+ * }
+ * //Define a digital output pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalOutput,
+ *   0,
+ * }
+ * @endcode
+ *
+ * @param base   GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @param pin    GPIO pin number
+ * @param config GPIO pin configuration pointer
+ */
+void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config);
+
+/*@}*/
+
+/*! @name GPIO Output Operations */
+/*@{*/
+
+/*!
+ * @brief Sets the output level of the one GPIO pin to the logic 1 or 0.
+ *
+ * @param base    GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @param pin    GPIO pin number
+ * @param output  GPIO pin output logic level.
+ *        - 0: corresponding pin output low-logic level.
+ *        - 1: corresponding pin output high-logic level.
+ */
+static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output)
+{
+    base->B[port][pin] = output;
+}
+
+/*@}*/
+/*! @name GPIO Input Operations */
+/*@{*/
+
+/*!
+ * @brief Reads the current input value of the GPIO PIN.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @param pin    GPIO pin number
+ * @retval GPIO port input value
+ *        - 0: corresponding pin input low-logic level.
+ *        - 1: corresponding pin input high-logic level.
+ */
+static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t port, uint32_t pin)
+{
+    return (uint32_t)base->B[port][pin];
+}
+
+/*@}*/
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 1.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortSet(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+    base->SET[port] = mask;
+}
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 0.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortClear(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+    base->CLR[port] = mask;
+}
+
+/*!
+ * @brief Reverses current output logic of the multiple GPIO pins.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+    base->NOT[port] = mask;
+}
+
+/*@}*/
+
+/*!
+ * @brief Reads the current input value of the whole GPIO port.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ */
+static inline uint32_t GPIO_PortRead(GPIO_Type *base, uint32_t port)
+{
+    return (uint32_t)base->PIN[port];
+}
+
+/*@}*/
+/*! @name GPIO Mask Operations */
+/*@{*/
+
+/*!
+ * @brief Sets port mask, 0 - enable pin, 1 - disable pin.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortMaskedSet(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+    base->MASK[port] = mask;
+}
+
+/*!
+ * @brief Sets the output level of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be affected.
+ *
+ * @param base    GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @param output  GPIO port output value.
+ */
+static inline void GPIO_PortMaskedWrite(GPIO_Type *base, uint32_t port, uint32_t output)
+{
+    base->MPIN[port] = output;
+}
+
+/*!
+ * @brief Reads the current input value of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be
+ * affected.
+ *
+ * @param base   GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @retval       masked GPIO port value
+ */
+static inline uint32_t GPIO_PortMaskedRead(GPIO_Type *base, uint32_t port)
+{
+    return (uint32_t)base->MPIN[port];
+}
+
+#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
+/*!
+ * @brief Configures the gpio pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param pin GPIO pin number.
+ * @param config GPIO pin interrupt configuration..
+ */
+void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config);
+
+/*!
+ * @brief Enables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @brief Disables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @brief Clears pin interrupt flag. Status flags are cleared by
+ *        writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @ Read port interrupt status.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param index GPIO interrupt number.
+ * @retval masked GPIO status value
+ */
+uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index);
+
+/*!
+ * @brief Enables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+/*!
+ * @brief Disables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+/*!
+ * @brief Clears the specific pin interrupt flag. Status flags are cleared by
+ *        writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */
+
+/*@}*/
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*!
+ * @}
+ */
+
+#endif /* _LPC_GPIO_H_*/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_iocon.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_iocon.h
new file mode 100755
index 0000000..1b0c3da
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_iocon.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_IOCON_H_
+#define _FSL_IOCON_H_
+
+#include "fsl_common.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.jn_iocon"
+#endif
+
+/*!
+ * @addtogroup jn_iocon
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief IOCON driver version 2.0.0. */
+#define LPC_IOCON_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
+/*@}*/
+
+/**
+ * @brief Array of IOCON pin definitions passed to IOCON_SetPinMuxing() must be in this format
+ */
+typedef struct _iocon_group
+{
+    uint32_t port : 8;      /* Pin port */
+    uint32_t pin : 8;       /* Pin number */
+    uint32_t modefunc : 16; /* Function and mode */
+} iocon_group_t;
+
+/**
+ * @brief IOCON function and mode selection definitions
+ * @note See the User Manual for specific modes and functions supported by the various pins.
+ */
+#define IOCON_FUNC0 IOCON_PIO_FUNC(0) /*!< Selects pin function 0 */
+#define IOCON_FUNC1 IOCON_PIO_FUNC(1) /*!< Selects pin function 1 */
+#define IOCON_FUNC2 IOCON_PIO_FUNC(2) /*!< Selects pin function 2 */
+#define IOCON_FUNC3 IOCON_PIO_FUNC(3) /*!< Selects pin function 3 */
+#define IOCON_FUNC4 IOCON_PIO_FUNC(4) /*!< Selects pin function 4 */
+#define IOCON_FUNC5 IOCON_PIO_FUNC(5) /*!< Selects pin function 5 */
+#define IOCON_FUNC6 IOCON_PIO_FUNC(6) /*!< Selects pin function 6 */
+#define IOCON_FUNC7 IOCON_PIO_FUNC(7) /*!< Selects pin function 7 */
+
+#define IOCON_MODE_PULLUP IOCON_PIO_MODE(0)   /*!< Selects pull-up function */
+#define IOCON_MODE_REPEATER IOCON_PIO_MODE(1) /*!< Selects pin repeater function */
+#define IOCON_MODE_INACT IOCON_PIO_MODE(2)    /*!< No addition pin function */
+#define IOCON_MODE_PULLDOWN IOCON_PIO_MODE(3) /*!< Selects pull-down function */
+
+#define IOCON_HYS_EN (0x1 << 5)            /*!< Enables hysteresis ??*/
+#define IOCON_GPIO_MODE IOCON_PIO_EGP(1)   /*!< GPIO Mode */
+#define IOCON_I2C_SLEW IOCON_PIO_SLEW0(1)  /*!< I2C Slew Rate Control */
+
+#define IOCON_INV_EN IOCON_PIO_INVERT(1) /*!< Enables invert function on input */
+
+#define IOCON_ANALOG_EN IOCON_PIO_DIGIMODE(0)  /*!< Enables analog function by setting 0 to bit 7 */
+#define IOCON_DIGITAL_EN IOCON_PIO_DIGIMODE(1) /*!< Enables digital function by setting 1 to bit 7(default) */
+
+#define IOCON_STDI2C_EN IOCON_PIO_FILTEROFF(1) /*!< I2C standard mode/fast-mode */
+
+#define IOCON_INPFILT_OFF IOCON_PIO_FILTEROFF(1) /*!< Input filter Off for GPIO pins */
+#define IOCON_INPFILT_ON IOCON_PIO_FILTEROFF(0)  /*!< Input filter On for GPIO pins */
+
+#define IOCON_SLEW1_OFF IOCON_PIO_SLEW1(0) /*!< Driver Slew Rate Control */
+#define IOCON_SLEW1_ON IOCON_PIO_SLEW1(1)  /*!< Driver Slew Rate Control */
+
+#define IOCON_FASTI2C_EN (IOCON_INPFILT_ON | IOCON_SLEW1_ON) /*!< I2C Fast-mode Plus and high-speed slave */
+
+#define IOCON_OPENDRAIN_EN IOCON_PIO_OD(1) /*!< Enables open-drain function */
+
+#define IOCON_S_MODE_0CLK IOCON_PIO_SSEL(0) /*!< Bypass input filter */
+#define IOCON_S_MODE_1CLK IOCON_PIO_SSEL(1) /*!< Input pulses shorter than 1 filter clock are rejected */
+#define IOCON_S_MODE_2CLK IOCON_PIO_SSEL(2) /*!< Input pulses shorter than 2 filter clock2 are rejected */
+#define IOCON_S_MODE_3CLK IOCON_PIO_SSEL(3) /*!< Input pulses shorter than 3 filter clock2 are rejected */
+
+/* Set IO clamping to the DIO : freeze the IO state.
+ * Requires SYSCON->RETENTIONCTRL.IOCLAMPING=1 . Automatically set in powerdown */
+#define IOCON_IO_CLAMPING_NORMAL_MFIO (1 << 11)
+#define IOCON_IO_CLAMPING_COMBO_MFIO_I2C (1 << 12) /* Use this flag for PIO11 and PIO12 only */
+
+#define IOCON_PIO_DBG_FUNC_MASK        (0xF000U)
+#define IOCON_PIO_DBG_FUNC_SHIFT       (12U)
+#define IOCON_PIO_DBG_FUNC(x)          (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DBG_FUNC_SHIFT)) & IOCON_PIO_DBG_FUNC_MASK)
+#define IOCON_PIO_DBG_MODE_MASK        (0x10000U)
+#define IOCON_PIO_DBG_MODE_SHIFT       (16U)
+#define IOCON_PIO_DBG_MODE(x)          (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DBG_MODE_SHIFT)) & IOCON_PIO_DBG_MODE_MASK)
+
+
+#define IOCON_CFG(dbg_func) (IOCON_PIO_FUNC(0) | IOCON_MODE_PULLDOWN |\
+                             IOCON_DIGITAL_EN | IOCON_INPFILT_OFF | \
+                             IOCON_PIO_DBG_FUNC(dbg_func) | IOCON_PIO_DBG_MODE(1))
+
+#define IOCON_PIO_I2C_EGP_SHIFT        (3U)
+#define IOCON_PIO_I2C_EGP_MASK         (1 << IOCON_PIO_I2C_EGP_SHIFT)
+#define IOCON_PIO_I2C_ECS_SHIFT        (4U)
+#define IOCON_PIO_I2C_ECS_MASK         (1 << IOCON_PIO_I2C_ECS_SHIFT)
+#define IOCON_PIO_I2C_EHS_SHIFT        (5U)
+#define IOCON_PIO_I2C_EHS_MASK         (1 << IOCON_PIO_I2C_EHS_SHIFT)
+#define IOCON_PIO_I2C_FSEL_SHIFT       (9U)
+#define IOCON_PIO_I2C_FSEL_MASK        (1 << IOCON_PIO_I2C_FSEL_SHIFT)
+#define IOCON_PIO_I2C_CLAMP_SHIFT      (12U)
+#define IOCON_PIO_I2C_CLAMP_MASK       (1 << IOCON_PIO_I2C_CLAMP_SHIFT)
+#define IOCON_PIO_I2C_DBG_FUNC_SHIFT   (13U)
+#define IOCON_PIO_I2C_DBG_FUNC_MASK    (0xf << IOCON_PIO_I2C_DBG_FUNC_SHIFT)
+#define IOCON_PIO_I2C_DBG_FUNC(x)      (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2C_DBG_FUNC_SHIFT)) & IOCON_PIO_I2C_DBG_FUNC_MASK)
+#define IOCON_PIO_I2C_DBG_MODE_SHIFT   (17U)
+#define IOCON_PIO_I2C_DBG_MODE_MASK    (1 << IOCON_PIO_I2C_DBG_MODE_SHIFT)
+#define IOCON_PIO_I2C_DBG_MODE(x)      (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2C_DBG_MODE_SHIFT)) & IOCON_PIO_I2C_DBG_MODE_MASK)
+
+
+#define IOCON_I2C_CFG(dbg_func) (IOCON_PIO_FUNC(0) |\
+                                 IOCON_PIO_I2C_EGP_MASK |\
+                                 IOCON_PIO_I2C_ECS_MASK |\
+                                 IOCON_DIGITAL_EN |\
+                                 IOCON_INPFILT_OFF |\
+                                 IOCON_PIO_I2C_DBG_FUNC(dbg_func)|\
+                                 IOCON_PIO_I2C_DBG_MODE(1))
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * @brief   Sets I/O Control pin mux
+ * @param   base        : The base of IOCON peripheral on the chip
+ * @param   port        : GPIO port to mux
+ * @param   pin         : GPIO pin to mux
+ * @param   modefunc    : OR'ed values of type IOCON_*
+ * @return  Nothing
+ */
+__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint32_t modefunc)
+{
+    base->PIO[port][pin] = modefunc;
+}
+
+/**
+ * @brief   Set all I/O Control pin muxing
+ * @param   base        : The base of IOCON peripheral on the chip
+ * @param   pinArray    : Pointer to array of pin mux selections
+ * @param   arrayLength : Number of entries in pinArray
+ * @return  Nothing
+ */
+__STATIC_INLINE void IOCON_SetPinMuxing(IOCON_Type *base, const iocon_group_t *pinArray, uint32_t arrayLength)
+{
+    uint32_t i;
+
+    for (i = 0; i < arrayLength; i++)
+    {
+        IOCON_PinMuxSet(base, pinArray[i].port, pinArray[i].pin, pinArray[i].modefunc);
+    }
+}
+
+/**
+ * @brief   Sets I/O Control pin mux pull select
+ * @param   base        : The base of IOCON peripheral on the chip
+ * @param   port        : GPIO port to mux
+ * @param   pin         : GPIO pin to mux
+ * @param   pull_select : OR'ed values of type IOCON_*
+ * @return  Nothing
+ */
+__STATIC_INLINE void IOCON_PullSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint8_t pull_select)
+{
+    uint32_t reg = base->PIO[port][pin];
+    reg &= ~IOCON_PIO_MODE_MASK;
+    reg |= IOCON_PIO_MODE(pull_select);
+    base->PIO[port][pin] = reg;
+}
+
+/**
+ * @brief   Sets I/O Control pin mux pull select
+ * @param   base        : The base of IOCON peripheral on the chip
+ * @param   port        : GPIO port to mux
+ * @param   pin         : GPIO pin to mux
+ * @param   func        : Pinmux function
+ * @return  Nothing
+ */
+__STATIC_INLINE void IOCON_FuncSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint8_t func)
+{
+    uint32_t reg = base->PIO[port][pin];
+    reg &= ~IOCON_PIO_FUNC_MASK;
+    reg |= IOCON_PIO_FUNC(func);
+    base->PIO[port][pin] = reg;
+}
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _FSL_IOCON_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_power.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_power.c
new file mode 100755
index 0000000..5e3d97a
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_power.c
@@ -0,0 +1,929 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "fsl_common.h"
+#include "fsl_power.h"
+#include "fsl_debug_console.h"
+#include "fsl_iocon.h"
+
+#include "rom_mpu.h"
+#include "rom_pmc.h"
+#include "rom_api.h"
+#include "rom_lowpower.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.power_no_lib"
+#endif
+
+#define POWER_LIB_VERSION 6042018
+
+/* Do not disable the DC bus when going to power modes */
+//#define POWER_DCBUS_NOT_DISABLED
+
+//#define DUMP_CONFIG
+//#define TRACE_ERR
+//#define TRACE_VRB
+//#define DISPLAY_ACTIVE_VOLTAGE
+
+/* Force BODMEM enable in power down mode for test : 1uA power consumption increase */
+//#define POWER_FORCE_BODMEM_IN_PD
+
+/* On ES2, use directly the safe voltage in deep sleep provided by Patrick */
+/* on ES2 powerdown1/2/3/4 , only BANK7 is maintained in retention */
+#define POWER_DOWN_WARM_4K
+
+#if defined(DUMP_CONFIG) || defined(TRACE_ERR) || defined(TRACE_VRB)
+#define POWER_CONSOLE_DEINIT
+#endif
+
+/*******************************************************************************
+ * Macros/Constants
+ *******************************************************************************/
+
+#if 1                         /* Cope with LDO CORE @ 1.0v in Active and LDO MEM @ 0.9 in power down */
+#define POWER_BODMEM_TRIG 0x4 /* 0.80V  Considering LDOMEM = 0.9v */
+#define POWER_BODMEM_HYST 0x1 /* 0.050V */
+
+#define POWER_BODCORE_TRIG 0x6 /* 0.90V   Considering LDOCORE = 1.0v */
+#define POWER_BODCORE_HYST 0x1 /* 0.050V */
+#else                          // safest setting for LDO CORE @ 1.1v and LDO MEM @ 1.0v
+#define POWER_BODMEM_TRIG 0x6  /* 0.90V - 0.925V +/- 3%   Considering LDOMEM = 1.9v */
+#define POWER_BODMEM_HYST 0x0  /* 0.025V */
+
+#define POWER_BODCORE_TRIG 0x7 /* 0.95V - 0.975V +/- 3%   Considering LDOCORE = 1.1v */
+#define POWER_BODCORE_HYST 0x0 /* 0.025V */
+#endif
+
+#define BODVBAT_LVL_DEFAULT POWER_BOD_LVL_1_75V
+#define BODVBAT_HYST_DEFAULT POWER_BOD_HYST_100MV
+
+#define POWER_LDO_TRIM_UNDEFINED 0x7F
+
+/* **********************   END OF POWER MODE DEFINITIONS   **************************************************/
+
+#define VOLTAGE(Vpmu, Vpmuboost, Vmem, Vmemboost, Vcore, Vpmuboostenable, Vflashcore)                                  \
+    (((Vpmu << LOWPOWER_VOLTAGE_LDO_PMU_INDEX) & LOWPOWER_VOLTAGE_LDO_PMU_MASK) |                                      \
+     ((Vpmuboost << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX) & LOWPOWER_VOLTAGE_LDO_PMU_BOOST_MASK) |                     \
+     ((Vpmuboostenable << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_INDEX) & LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_MASK) | \
+     ((Vmem << LOWPOWER_VOLTAGE_LDO_MEM_INDEX) & LOWPOWER_VOLTAGE_LDO_MEM_MASK) |                                      \
+     ((Vmemboost << LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX) & LOWPOWER_VOLTAGE_LDO_MEM_BOOST_MASK) |                     \
+     ((Vcore << LOWPOWER_VOLTAGE_LDO_CORE_INDEX) & LOWPOWER_VOLTAGE_LDO_CORE_MASK) |                                   \
+     ((Vflashcore << LOWPOWER_VOLTAGE_LDO_FLASH_CORE_INDEX) & LOWPOWER_VOLTAGE_LDO_FLASH_CORE_MASK))
+
+/*
+ * Recommended Voltage settings from
+ * https://www.collabnet.nxp.com/svn/lprfprojects/JN5189/Documents/17_Architecture/17_n_Digital/Block_Specification/jn5189_settings.xlsx
+ */
+#define VOLTAGE_PMU_DOWN 0x5      /* 0.8V  */
+#define VOLTAGE_PMUBOOST_DOWN 0x3 /* 0.75V */
+
+#define VOLTAGE_MEM_DOWN_0_9V 0x9       /* 0.9V  */
+#define VOLTAGE_MEM_DOWN_1_0V 0xE       /* 1V    */
+#define VOLTAGE_MEMBOOST_DOWN_0_85V 0x7 /* 0.85V */
+#define VOLTAGE_MEMBOOST_DOWN_0_96V 0xA /* 0.96V */
+
+#define VOLTAGE_PMU_DEEP_SLEEP 0xA       /* 0.96V */
+#define VOLTAGE_PMUBOOST_DEEP_SLEEP 0x9  /* 0.9V  */
+#define VOLTAGE_MEM_DEEP_SLEEP 0x18      /* 1.1V  */
+#define VOLTAGE_MEMBOOST_DEEP_SLEEP 0x13 /* 1.05V */
+#define VOLTAGE_CORE_DEEP_SLEEP 0x2      /* 0.95V */
+#define VOLTAGE_FLASH_CORE_DEEP_SLEEP 2  /* 0.95V */
+
+#define VOLTAGE_PMU_DEEP_DOWN 0x5      /* 0.8V  */
+#define VOLTAGE_PMUBOOST_DEEP_DOWN 0x3 /* 0.75V */
+
+#define VOLTAGE_LDO_PMU_BOOST 0
+
+#define POWER_ULPGB_TRIM_FLASH_ADDR (uint32_t *)0x9FCD4
+
+#define POWER_GET_ACTIVE_TRIM_VALUE(__reg) ((int8_t)((__reg & (1 << 4)) ? -(__reg & 0xF) : (__reg & 0xF)))
+#define POWER_GET_PWD_TRIM_VALUE(__reg) \
+    ((int8_t)(((__reg >> 5) & (1 << 4)) ? -((__reg >> 5) & 0xF) : ((__reg >> 5) & 0xF)))
+
+#define POWER_APPLY_ACTIVE_TRIM(__voltage)                                                                          \
+    ((active_trim_val != POWER_LDO_TRIM_UNDEFINED) ? (MIN(0x1E, MAX(((int8_t)__voltage + active_trim_val), 0xA))) : \
+                                                     (__voltage))
+#define POWER_APPLY_PWD_TRIM(__voltage)                                                                         \
+    ((active_trim_val != POWER_LDO_TRIM_UNDEFINED) ? (MIN(0x9, MAX(((int8_t)__voltage + pwd_trim_val), 0x1))) : \
+                                                     (__voltage))
+
+#define POWER_APPLY_TRIM(__voltage) \
+    ((__voltage < 0xA) ? POWER_APPLY_PWD_TRIM(__voltage) : POWER_APPLY_ACTIVE_TRIM(__voltage))
+
+/*******************************************************************************
+ * Types
+ ******************************************************************************/
+static const LPC_LOWPOWER_LDOVOLTAGE_T lowpower_ldovoltage_reset = {
+    .LDOPMU             = 0x18, // 1.1V
+    .LDOPMUBOOST        = 0x13, // 1.05V
+    .LDOMEM             = 0x18, // 1.1V
+    .LDOMEMBOOST        = 0x13, // 1.05V
+    .LDOCORE            = 0x5,  // 1.1V
+    .LDOFLASHNV         = 0x5,  // 1.9V
+    .LDOFLASHCORE       = 0x6,  // 1.15V
+    .LDOADC             = 0x5,  // 1.1V
+    .LDOPMUBOOST_ENABLE = 1,    // Force Boost activation on LDOPMU
+};
+
+static const LPC_LOWPOWER_LDOVOLTAGE_T lowpower_ldovoltage_min = {
+    .LDOPMU             = 0xE, // 1V
+    .LDOPMUBOOST        = 0xA, // 0.96V
+    .LDOMEM             = 0xE, // 1V
+    .LDOMEMBOOST        = 0xA, // 0.96V
+    .LDOCORE            = 0x3, // 1V
+    .LDOFLASHNV         = 0x5, // 1.9V
+    .LDOFLASHCORE       = 0x6, // 1.15V
+    .LDOADC             = 0x5, // 1.1V
+    .LDOPMUBOOST_ENABLE = 1,   // Force Boost activation on LDOPMU
+};
+
+/* trimming value to apply to active/pwd voltage - Initialized from flash in POWER_Init() */
+static int8_t active_trim_val = POWER_LDO_TRIM_UNDEFINED;
+static int8_t pwd_trim_val    = POWER_LDO_TRIM_UNDEFINED;
+
+/*******************************************************************************
+ * Local prototypes
+ ******************************************************************************/
+
+#ifdef DUMP_CONFIG
+static void LF_DumpConfig(LPC_LOWPOWER_T *LV_LowPowerMode);
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static void POWER_FlexcomClocksDisable(void)
+{
+    CLOCK_AttachClk(kNONE_to_USART_CLK);
+    CLOCK_AttachClk(kNONE_to_FRG_CLK);
+    CLOCK_AttachClk(kNONE_to_I2C_CLK);
+    CLOCK_AttachClk(kNONE_to_SPI_CLK);
+
+    CLOCK_DisableClock(kCLOCK_Usart0);
+    CLOCK_DisableClock(kCLOCK_I2c0);
+    CLOCK_DisableClock(kCLOCK_Spi0);
+}
+
+#ifdef FOR_BOD_DEBUG
+/******   BODMEM ********/
+static void POWER_BodMemDisable(void)
+{
+    PMC->PDRUNCFG &= ~PMC_PDRUNCFG_ENA_BOD_MEM_MASK;
+    PMC->BODMEM &= ~PMC_BODMEM_RESETENABLE_MASK;
+}
+
+static void POWER_BodMemSetup(void)
+{
+    // TODO : really needed?
+    POWER_BodMemDisable();
+
+    /* Configure BODMEM so it can be enabled before going to power down */
+    PMC->BODMEM = (PMC->BODMEM & ~(PMC_BODMEM_TRIGLVL_MASK | PMC_BODMEM_HYST_MASK)) |
+                  (PMC_BODMEM_TRIGLVL(POWER_BODMEM_TRIG) | PMC_BODMEM_HYST(POWER_BODMEM_HYST));
+
+    /* Clear BODMEM interrupt */
+    SYSCON->ANACTRL_INTENCLR = SYSCON_ANACTRL_INTENSET_BODMEM_MASK;
+
+    /* Enable the BODMEM */
+    PMC->PDRUNCFG |= PMC_PDRUNCFG_ENA_BOD_MEM_MASK;
+}
+
+static void POWER_BodMemEnableInt(void)
+{
+    /* Warning, we should wait for the LDO to set up (27us) before clearing the status and enabling the interrupts
+     * (RFT1852) However, we expect this function to be called more than 27us after POWER_BodCoreConfigure() so we can
+     * discard the 27us delay here */
+    // CLOCK_uDelay(27);
+
+    /* clear initial status  (RFT1891) and enable interrupt */
+    SYSCON->ANACTRL_STAT     = SYSCON_ANACTRL_STAT_BODMEM_MASK;
+    SYSCON->ANACTRL_INTENSET = SYSCON_ANACTRL_INTENSET_BODMEM_MASK;
+
+    /* BODMEM Reset enable */
+    PMC->BODMEM |= PMC_BODMEM_RESETENABLE_MASK;
+}
+
+/******   BODCORE ********/
+static void POWER_BodCoreDisable(void)
+{
+    PMC->PDRUNCFG &= ~PMC_PDRUNCFG_ENA_BOD_CORE_MASK;
+    PMC->BODCORE &= ~PMC_BODCORE_RESETENABLE_MASK;
+}
+
+static void POWER_BodCoreSetup(void)
+{
+    /* TODO : shall we disable it first? */
+    POWER_BodCoreDisable();
+
+    /* Configure BODMEM so it can be enabled before going to power down */
+    PMC->BODCORE = (PMC->BODCORE & ~(PMC_BODCORE_TRIGLVL_MASK | PMC_BODCORE_HYST_MASK)) |
+                   (PMC_BODCORE_TRIGLVL(POWER_BODCORE_TRIG) | PMC_BODCORE_HYST(POWER_BODCORE_TRIG));
+
+    /* Clear BODCORE interrupt */
+    SYSCON->ANACTRL_INTENCLR = SYSCON_ANACTRL_INTENSET_BODCORE_MASK;
+
+    /* Enable the BODCORE */
+    PMC->PDRUNCFG |= PMC_PDRUNCFG_ENA_BOD_CORE_MASK;
+}
+
+static void POWER_BodCoreEnableInt(void)
+{
+    /* Warning, we should wait for the LDO to set up (27us) before clearing the status and enabling the interrupts
+     * (RFT1852) However, we expect this function to be called more than 27us after POWER_BodCoreConfigure() so we can
+     * discard the 27us delay here */
+    // CLOCK_uDelay(27);
+
+    /* clear initial status  (RFT1891) and enable interrupt */
+    SYSCON->ANACTRL_STAT     = SYSCON_ANACTRL_STAT_BODCORE_MASK;
+    SYSCON->ANACTRL_INTENSET = SYSCON_ANACTRL_INTENSET_BODCORE_MASK;
+
+    /* BOD IC Reset enable */
+    PMC->BODCORE |= PMC_BODCORE_RESETENABLE_MASK;
+}
+#endif
+
+static void POWER_UpdateTrimmingVoltageValue(void)
+{
+    uint32_t ulpbg_trim_flash_val;
+    /* Save a bit of time is the trimming values are already retrieved */
+
+    if ((active_trim_val == POWER_LDO_TRIM_UNDEFINED) || (pwd_trim_val == POWER_LDO_TRIM_UNDEFINED))
+    {
+        /* set the trimming values for active and pwd from N-2 page Flash */
+        ulpbg_trim_flash_val = *POWER_ULPGB_TRIM_FLASH_ADDR;
+        active_trim_val      = POWER_GET_ACTIVE_TRIM_VALUE(ulpbg_trim_flash_val);
+        pwd_trim_val         = POWER_GET_PWD_TRIM_VALUE(ulpbg_trim_flash_val);
+    }
+#ifdef DUMP_CONFIG
+    PRINTF("reg=0x%x active_trim=0x%X pwd_trim=0x%X\r\n", ulpbg_trim_flash_val, active_trim_val, pwd_trim_val);
+#endif
+}
+
+static uint32_t POWER_GetIoClampConfig(void)
+{
+    uint32_t io_clamp = 0;
+
+    for (int i = 0; i < 22; i++)
+    {
+        if ((i == 10) | (i == 11))
+        {
+            io_clamp |= (((IOCON->PIO[0][i] & IOCON_IO_CLAMPING_COMBO_MFIO_I2C) >> 12) << i);
+        }
+        else
+        {
+            io_clamp |= (((IOCON->PIO[0][i] & IOCON_IO_CLAMPING_NORMAL_MFIO) >> 11) << i);
+        }
+    }
+    return io_clamp;
+}
+
+/*!
+ * brief Power Library API to return the library version.
+ *
+ * param none
+ * return version number of the power library
+ */
+uint32_t POWER_GetLibVersion(void)
+{
+    return POWER_LIB_VERSION;
+}
+
+/*!
+ * brief determine cause of reset
+ * return reset_cause
+ */
+reset_cause_t POWER_GetResetCause(void)
+{
+    reset_cause_t reset_cause = RESET_UNDEFINED;
+    uint32_t pmc_reset        = pmc_reset_get_cause();
+
+    if (pmc_reset & PMC_RESETCAUSE_POR_MASK)
+    {
+        reset_cause |= RESET_POR;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_PADRESET_MASK)
+    {
+        reset_cause |= RESET_EXT_PIN;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_BODRESET_MASK)
+    {
+        reset_cause |= RESET_BOR;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_SYSTEMRESET_MASK)
+    {
+        reset_cause |= RESET_SYS_REQ;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_WDTRESET_MASK)
+    {
+        reset_cause |= RESET_WDT;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_WAKEUPIORESET_MASK)
+    {
+        reset_cause |= RESET_WAKE_DEEP_PD;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK)
+    {
+        reset_cause |= RESET_WAKE_PD;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_SWRRESET_MASK)
+    {
+        reset_cause |= RESET_SW_REQ;
+    }
+
+    return reset_cause;
+}
+
+/*!
+ * brief Clear cause of reset
+ */
+void POWER_ClearResetCause(void)
+{
+    pmc_reset_clear_cause(0xFFFFFFFF);
+}
+
+void POWER_DisplayActiveVoltage(void)
+{
+    LPC_LOWPOWER_LDOVOLTAGE_T ldo_voltage;
+
+    Chip_LOWPOWER_GetSystemVoltages(&ldo_voltage);
+
+    PRINTF("LDOPMU       : %d\n", (int)(ldo_voltage.LDOPMU & 0x1fUL));
+    PRINTF("LDOPMUBOOST  : %d\n", (int)(ldo_voltage.LDOPMUBOOST & 0x1fUL));
+    PRINTF("LDOMEM       : %d\n", (int)(ldo_voltage.LDOMEM & 0x1fUL));
+    PRINTF("LDOMEMBOOST  : %d\n", (int)(ldo_voltage.LDOMEMBOOST & 0x1fUL));
+    PRINTF("LDOCORE      : %d\n", (int)(ldo_voltage.LDOCORE & 0x07UL));
+    PRINTF("LDOFLASHCORE : %d\n", (int)(ldo_voltage.LDOFLASHCORE & 0x07UL));
+    PRINTF("LDOFLASHNV   : %d\n", (int)(ldo_voltage.LDOFLASHNV & 0x07UL));
+    PRINTF("LDOADC       : %d\n", (int)(ldo_voltage.LDOADC & 0x07UL));
+
+    PRINTF("LDOPMUBOOST_ENABLE : %d\n", ldo_voltage.LDOPMUBOOST_ENABLE);
+
+    PRINTF("\n");
+}
+
+void POWER_ApplyActiveVoltage(const LPC_LOWPOWER_LDOVOLTAGE_T *ldo_voltage)
+{
+    LPC_LOWPOWER_LDOVOLTAGE_T ldo_voltage_l;
+
+    memcpy(&ldo_voltage_l, ldo_voltage, sizeof(LPC_LOWPOWER_LDOVOLTAGE_T));
+
+    /* Apply some trimming on LDOPMU and LDOMEM to avoid extra consumption */
+    ldo_voltage_l.LDOPMU      = POWER_APPLY_TRIM(ldo_voltage->LDOPMU);
+    ldo_voltage_l.LDOPMUBOOST = POWER_APPLY_TRIM(ldo_voltage->LDOPMUBOOST);
+
+    ldo_voltage_l.LDOMEM      = POWER_APPLY_TRIM(ldo_voltage->LDOMEM);
+    ldo_voltage_l.LDOMEMBOOST = POWER_APPLY_TRIM(ldo_voltage->LDOMEMBOOST);
+
+    Chip_LOWPOWER_SetSystemVoltages(&ldo_voltage_l);
+}
+
+void POWER_ApplyLdoActiveVoltage(pm_ldo_volt_t ldoVolt)
+{
+    switch (ldoVolt)
+    {
+        case PM_LDO_VOLT_1_0V:
+            POWER_ApplyActiveVoltage(&lowpower_ldovoltage_min);
+            break;
+
+        case PM_LDO_VOLT_1_1V_DEFAULT:
+        default:
+            POWER_ApplyActiveVoltage(&lowpower_ldovoltage_reset);
+    }
+}
+
+/*!
+ * brief Initialize the sdk power drivers
+ *
+ * Optimize the LDO voltage for power saving
+ * Initialize the power domains
+ * Activate the BOD
+ *
+ * return none
+ */
+void POWER_Init(void)
+{
+    static bool warm_start = false;
+#ifdef FOR_BOD_DEBUG
+    /* Enable the clock for the analog interrupt control module - required for the BOD
+     * and set up BOD core and mem*/
+    POWER_BodSetUp();
+#endif
+    if (warm_start == false)
+    {
+        POWER_SetTrimDefaultActiveVoltage();
+
+        warm_start = true;
+    }
+
+#ifdef DISPLAY_ACTIVE_VOLTAGE
+    POWER_DisplayActiveVoltage();
+#endif
+
+    /* This time, need to wait for LDO to be set up (27us) */
+    CLOCK_uDelay(27);
+#ifdef FOR_BOD_DEBUG
+    /* enable interrupt and SW reset for the BODCORE */
+    POWER_BodActivate();
+#endif
+}
+
+void POWER_SetTrimDefaultActiveVoltage(void)
+{
+    POWER_UpdateTrimmingVoltageValue();
+
+    /* Always startup at 1.1V to cope with higher current load when enabling clocks */
+    POWER_ApplyLdoActiveVoltage(PM_LDO_VOLT_1_1V_DEFAULT);
+
+#ifdef DISPLAY_ACTIVE_VOLTAGE
+    POWER_DisplayActiveVoltage();
+#endif
+}
+
+#ifdef FOR_BOD_DEBUG
+void POWER_BodSetUp(void)
+{
+    /* Enable the clock for the analog interrupt control module - required for the BOD */
+    CLOCK_EnableClock(kCLOCK_AnaInt);
+
+    POWER_BodCoreSetup();
+    POWER_BodMemSetup();
+}
+
+void POWER_BodActivate(void)
+{
+    /* enable interrupt and SW reset for the BODCORE */
+    POWER_BodCoreEnableInt();
+
+    CLOCK_DisableClock(kCLOCK_AnaInt);
+}
+#endif
+
+/*!
+ * brief Get default Vbat BOD config parameters, level 1.75V, Hysteresis  100mV
+ *
+ * param bod_cfg_p
+ * return none
+ */
+void POWER_BodVbatGetDefaultConfig(pm_bod_cfg_t *bod_cfg_p)
+{
+    bod_cfg_p->bod_level = BODVBAT_LVL_DEFAULT;
+    bod_cfg_p->bod_hyst  = BODVBAT_HYST_DEFAULT;
+    bod_cfg_p->bod_cfg   = POWER_BOD_ENABLE | POWER_BOD_INT_ENABLE;
+}
+
+/*!
+ * brief Configure the VBAT BOD
+ *
+ * param bod_cfg_p
+ * return false if configuration parameters are incorrect
+ */
+bool POWER_BodVbatConfig(pm_bod_cfg_t *bod_cfg_p)
+{
+    uint32_t comparator_interrupt;
+
+    if (bod_cfg_p->bod_cfg & POWER_BOD_ENABLE)
+    {
+        if ((bod_cfg_p->bod_level >= POWER_BOD_LVL_1_75V) && (bod_cfg_p->bod_level <= POWER_BOD_LVL_3_3V) &&
+            (bod_cfg_p->bod_hyst <= POWER_BOD_HYST_100MV))
+        {
+            uint32_t bodvbat = PMC->BODVBAT;
+            bodvbat &= ~(PMC_BODVBAT_TRIGLVL_MASK | PMC_BODVBAT_HYST_MASK);
+            bodvbat |= PMC_BODVBAT_TRIGLVL(bod_cfg_p->bod_level);
+            bodvbat |= PMC_BODVBAT_HYST(bod_cfg_p->bod_hyst);
+            PMC->BODVBAT = bodvbat;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /* enable the clock for the analog interrupt control module */
+    CLOCK_EnableClock(kCLOCK_AnaInt);
+
+    if (bod_cfg_p->bod_cfg & POWER_BOD_HIGH)
+    {
+        /* Disable Interrupt on BODVBAT High */
+        SYSCON->ANACTRL_INTENCLR = SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_MASK;
+
+        /* clear initial status of interrupt */
+        SYSCON->ANACTRL_STAT = SYSCON_ANACTRL_STAT_BODVBATHIGH_MASK;
+
+        /* enable comparator interrupt       */
+        comparator_interrupt = SYSCON_ANACTRL_INTENSET_BODVBATHIGH_MASK;
+    }
+    else
+    {
+        /*  BOD IC Interrupt enable */
+        SYSCON->ANACTRL_INTENCLR = SYSCON_ANACTRL_INTENCLR_BODVBAT_MASK;
+
+        /* clear initial status of interrupt */
+        SYSCON->ANACTRL_STAT = SYSCON_ANACTRL_STAT_BODVBAT_MASK;
+
+        /* enable comparator interrupt      */
+        comparator_interrupt = SYSCON_ANACTRL_INTENSET_BODVBAT_MASK;
+    }
+
+    if (bod_cfg_p->bod_cfg & POWER_BOD_ENABLE)
+    {
+        if (bod_cfg_p->bod_cfg & POWER_BOD_INT_ENABLE)
+        {
+            SYSCON->ANACTRL_INTENSET = comparator_interrupt;
+            NVIC_EnableIRQ(WDT_BOD_IRQn);
+        }
+        else
+        {
+            NVIC_DisableIRQ(WDT_BOD_IRQn);
+        }
+#ifdef FOR_BOD_DEBUG
+        if (bod_cfg_p->bod_cfg & POWER_BOD_RST_ENABLE)
+        {
+            PMC->BODVBAT |= PMC_BODVBAT_RESETENABLE_MASK;
+        }
+        else
+        {
+            PMC->BODVBAT &= ~PMC_BODVBAT_RESETENABLE_MASK;
+        }
+#endif
+    }
+
+    CLOCK_DisableClock(kCLOCK_AnaInt);
+    // PRINTF( "BODVBAT=0x%X ANACTRL_CTRL=0x%X _STAT=0x%X _VAL=0x%X _INTENSET=0x%X\n", PMC->BODVBAT,
+    // SYSCON->ANACTRL_CTRL, SYSCON->ANACTRL_STAT, SYSCON->ANACTRL_VAL, SYSCON->ANACTRL_INTENSET);
+
+    return true;
+}
+
+bool POWER_EnterDeepSleepMode(pm_power_config_t *pm_power_config)
+{
+    /* [RFT1911] Disable the DC bus to prevent extra consumption */
+#ifndef POWER_DCBUS_NOT_DISABLED
+    ASYNC_SYSCON->DCBUSCTRL =
+        (ASYNC_SYSCON->DCBUSCTRL & ~ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK) | (1 << ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT);
+#endif
+
+    /* [artf555998] Enable new ES2 feature for fast wakeup */
+    PMC->CTRLNORST = PMC_CTRLNORST_FASTLDOENABLE_MASK;
+
+    return false;
+}
+
+bool POWER_EnterPowerDownMode(pm_power_config_t *pm_power_config)
+{
+    int radio_retention;
+    int autostart_32mhz_xtal;
+    int keep_ao_voltage;
+    int sram_cfg;
+    int wakeup_src0;
+    int wakeup_src1;
+    uint8_t voltage_mem_down;
+    uint8_t voltage_membootst_down;
+    LPC_LOWPOWER_T lp_config;
+    memset(&lp_config, 0, sizeof(lp_config));
+
+    sram_cfg             = pm_power_config->pm_config & PM_CFG_SRAM_ALL_RETENTION;
+    radio_retention      = pm_power_config->pm_config & PM_CFG_RADIO_RET;
+    autostart_32mhz_xtal = pm_power_config->pm_config & PM_CFG_XTAL32M_AUTOSTART;
+    keep_ao_voltage      = pm_power_config->pm_config & PM_CFG_KEEP_AO_VOLTAGE;
+
+    wakeup_src0 = (int)pm_power_config->pm_wakeup_src & 0xFFFFFFFF;
+    wakeup_src1 = (int)(pm_power_config->pm_wakeup_src >> 32) & 0xFFFFFFFF;
+#ifdef TRACE_VRB
+    PRINTF("POWER_EnterPowerDownMode:\n");
+    PRINTF("  wakeup_src0      : 0x%x\n", wakeup_src0);
+    PRINTF("  wakeup_src1      : 0x%x\n", wakeup_src1);
+    PRINTF("  wakeup_io        : 0x%x\n", pm_power_config->pm_wakeup_io);
+    PRINTF("  pm_config        : 0x%x\n", pm_power_config->pm_config);
+#endif
+
+    lp_config.CFG = LOWPOWER_CFG_MODE_POWERDOWN;
+
+    /* PDRUNCFG : on ES2, flag discard to keep the same configuration than active */
+    lp_config.CFG |= LOWPOWER_CFG_PDRUNCFG_DISCARD_MASK;
+
+    /* PDSLEEPCFG (note: LDOMEM will be enabled by lowpower API if one memory bank in retention*/
+    lp_config.PMUPWDN |= LOWPOWER_PMUPWDN_DCDC | LOWPOWER_PMUPWDN_BIAS | LOWPOWER_PMUPWDN_BODVBAT;
+
+    /* Disable All banks except those given in sram_cfg */
+    lp_config.DIGPWDN |= ((LOWPOWER_DIGPWDN_SRAM_ALL_MASK) & ~(sram_cfg << LOWPOWER_DIGPWDN_SRAM0_INDEX));
+
+    // TODO : if COMM0 is disabled, need to switch off the clocks also for safe wake up
+    lp_config.DIGPWDN |= LOWPOWER_DIGPWDN_COMM0; // PDSLEEP DISABLE COM0
+
+    lp_config.DIGPWDN |=
+        LOWPOWER_DIGPWDN_MCU_RET; // PDSLEEP DISABLE retention  : on ES1, CPU retention, on ES2 Zigbee retention
+
+    // lp_config.DIGPWDN |= LOWPOWER_DIGPWDN_NTAG_FD;         // DPDWKSRC DISABLE NTAG  - not used in lowpower API in
+    // power down
+
+    lp_config.SLEEPPOSTPONE = 0;
+    lp_config.GPIOLATCH     = 0;
+
+#if gPWR_LDOMEM_0_9V_PD /* Warning : do not apply this flag , for experimental use only */
+    voltage_mem_down       = VOLTAGE_MEM_DOWN_0_9V;
+    voltage_membootst_down = VOLTAGE_MEMBOOST_DOWN_0_85V;
+#else
+    /* A bit in the flash is now set (bit 31 at address 0x9FCD4).
+     * If this bit is set, RAM retention in sleep should use voltage of 0.9v.
+     * If it is not set, RAM retention in sleep should use voltage of 1.0v. */
+    uint32_t *ate_setting = (uint32_t *)0x9FCD4;
+
+    if ((*ate_setting & 0x80000000) == 0x80000000)
+    {
+        voltage_mem_down       = VOLTAGE_MEM_DOWN_0_9V;
+        voltage_membootst_down = VOLTAGE_MEMBOOST_DOWN_0_85V;
+    }
+    else
+    {
+        voltage_mem_down       = VOLTAGE_MEM_DOWN_1_0V;
+        voltage_membootst_down = VOLTAGE_MEMBOOST_DOWN_0_96V;
+    }
+#endif
+
+    if (keep_ao_voltage)
+    {
+        LPC_LOWPOWER_LDOVOLTAGE_T ldo_voltage;
+
+        Chip_LOWPOWER_GetSystemVoltages(&ldo_voltage);
+
+        /* keep the same voltage than in active for the Always ON powerdomain */
+        lp_config.VOLTAGE = VOLTAGE(POWER_APPLY_TRIM(ldo_voltage.LDOPMU), POWER_APPLY_TRIM(ldo_voltage.LDOPMUBOOST),
+                                    POWER_APPLY_TRIM(voltage_mem_down), POWER_APPLY_TRIM(voltage_membootst_down), 0,
+                                    VOLTAGE_LDO_PMU_BOOST, 0);
+    }
+    else
+    {
+        lp_config.VOLTAGE = VOLTAGE(POWER_APPLY_TRIM(VOLTAGE_PMU_DOWN), POWER_APPLY_TRIM(VOLTAGE_PMUBOOST_DOWN),
+                                    POWER_APPLY_TRIM(voltage_mem_down), POWER_APPLY_TRIM(voltage_membootst_down), 0,
+                                    VOLTAGE_LDO_PMU_BOOST, 0);
+    }
+
+    lp_config.WAKEUPSRCINT0 = wakeup_src0;
+    lp_config.WAKEUPSRCINT1 = wakeup_src1;
+
+    /* Variation from reference */
+    if (radio_retention)
+    {
+        /* Enable Zigbee retention */
+        lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_MCU_RET;
+    }
+
+    /* Configure IO wakeup source */
+    if (lp_config.WAKEUPSRCINT1 & LOWPOWER_WAKEUPSRCINT1_IO_IRQ)
+    {
+        lp_config.WAKEUPIOSRC = pm_power_config->pm_wakeup_io;
+    }
+
+    if (lp_config.WAKEUPSRCINT0 & LOWPOWER_WAKEUPSRCINT0_SYSTEM_IRQ)
+    {
+        /* Need to enable the BIAS for VBAT BOD */
+        lp_config.PMUPWDN &= ~(LOWPOWER_PMUPWDN_BIAS | LOWPOWER_PMUPWDN_BODVBAT);
+    }
+
+    if (lp_config.WAKEUPSRCINT0 &
+        (LOWPOWER_WAKEUPSRCINT0_USART0_IRQ | LOWPOWER_WAKEUPSRCINT0_I2C0_IRQ | LOWPOWER_WAKEUPSRCINT0_SPI0_IRQ))
+    {
+        /* Keep Flexcom0 in power down mode */
+        lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_COMM0;
+    }
+
+    /* On ES2 , Analog comparator is already enabled in PDRUNCFG + RFT1877 : No need to keep the bias */
+    if (sram_cfg)
+    {
+        /* Configure the SRAM to SMB1 (low leakage biasing) */
+        SYSCON->SRAMCTRL =
+            (SYSCON->SRAMCTRL & (~SYSCON_SRAMCTRL_SMB_MASK)) | (SYSCON_SRAMCTRL_SMB(1) << SYSCON_SRAMCTRL_SMB_SHIFT);
+
+        /*
+         * BODMEM requires the bandgap enable in power down, this induces a power consumption increase of 1uA
+         * so Enable BODMEM only if bandgap is already enabled for BODVBAT (see code above)
+         */
+#ifndef POWER_FORCE_BODMEM_IN_PD
+        if ((lp_config.PMUPWDN & LOWPOWER_PMUPWDN_BIAS) == 0)
+#endif
+        {
+#ifdef FOR_BOD_DEBUG
+            CLOCK_EnableClock(kCLOCK_AnaInt);
+
+            /* Note: BODMEM should be already enabled in the POWER_Init() function but do it again if not */
+            if (!(PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_BOD_MEM_MASK))
+            {
+                POWER_BodMemSetup();
+                /* This time, need to wait for LDO to be set up (27us) */
+                CLOCK_uDelay(27);
+            }
+            POWER_BodMemEnableInt();
+#endif
+        }
+#ifndef POWER_FORCE_BODMEM_IN_PD
+        else
+        {
+#ifdef FOR_BOD_DEBUG
+            /* Disable the BODMEM otherwise */
+            POWER_BodMemDisable();
+#endif
+        }
+#endif
+    }
+    else
+    {
+#ifdef FOR_BOD_DEBUG
+        /* Disable the BODMEM otherwise */
+        POWER_BodMemDisable();
+#endif
+    }
+#ifdef FOR_BOD_DEBUG
+    /* Disable BodCore , no longer used in power down */
+    POWER_BodCoreDisable();
+#endif
+    if (wakeup_src0 & LOWPOWER_WAKEUPSRCINT0_NFCTAG_IRQ)
+    {
+        lp_config.WAKEUPSRCINT1 |= LOWPOWER_WAKEUPSRCINT1_IO_IRQ;
+        lp_config.WAKEUPIOSRC |= LOWPOWER_WAKEUPIOSRC_NTAG_FD;
+    }
+
+    /* On Power down, NTAG field detect is enabled by IO so don t need to set the LOWPOWER_DIGPWDN_NTAG_FD */
+    // lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_NTAG_FD;      // used for deep down only
+
+    if (autostart_32mhz_xtal)
+    {
+        lp_config.CFG |= LOWPOWER_CFG_XTAL32MSTARTENA_MASK;
+    }
+
+    /* get IO clamping state already set by the application and give it to lowpower API
+     * Lowpower API overrides the IO configuration with GPIOLATCH setting
+     */
+    lp_config.GPIOLATCH = POWER_GetIoClampConfig();
+
+    /* [RFT1911] Disable the DC bus to prevent extra consumption */
+#ifndef POWER_DCBUS_NOT_DISABLED
+    ASYNC_SYSCON->DCBUSCTRL =
+        (ASYNC_SYSCON->DCBUSCTRL & ~ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK) | (1 << ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT);
+#endif
+
+    /* [artf555998] Enable new ES2 feature for fast wakeup */
+    PMC->CTRLNORST = PMC_CTRLNORST_FASTLDOENABLE_MASK;
+
+#ifdef DUMP_CONFIG
+    LF_DumpConfig(&lp_config);
+#endif
+
+    /* If flexcom is maintained, do not disable the console and the clocks - let the application do it if needed */
+    if (lp_config.DIGPWDN & LOWPOWER_DIGPWDN_COMM0)
+    {
+        /* remove console if not done */
+        DbgConsole_Deinit();
+
+        /* Disable clocks to FLEXCOM power domain. This power domain is not reseted on wakeup by HW */
+        POWER_FlexcomClocksDisable();
+    }
+    /* Apply default LDO voltage */
+    POWER_ApplyLdoActiveVoltage(PM_LDO_VOLT_1_1V_DEFAULT);
+
+    Chip_LOWPOWER_SetLowPowerMode(&lp_config);
+
+    /* If we go here, the power mode has been aborted - this can happen only if WFI is executed in lowpower API*/
+    return false;
+}
+
+bool POWER_EnterDeepDownMode(pm_power_config_t *pm_power_config)
+{
+    int autostart_32mhz_xtal;
+    int wakeup_src0;
+    int wakeup_src1;
+    LPC_LOWPOWER_T lp_config;
+
+    memset(&lp_config, 0, sizeof(lp_config));
+
+    autostart_32mhz_xtal = pm_power_config->pm_config & PM_CFG_XTAL32M_AUTOSTART;
+
+    wakeup_src0 = (int)pm_power_config->pm_wakeup_src & 0xFFFFFFFF;
+    wakeup_src1 = (int)(pm_power_config->pm_wakeup_src >> 32) & 0xFFFFFFFF;
+
+#ifdef TRACE_VRB
+    PRINTF("POWER_EnterDeepDownMode:\n");
+    PRINTF("  wakeup_src0      : 0x%x\n", wakeup_src0);
+    PRINTF("  wakeup_src1      : 0x%x\n", wakeup_src1);
+#else
+    (void)wakeup_src0;
+#endif
+
+    lp_config.CFG = LOWPOWER_CFG_MODE_DEEPPOWERDOWN;
+
+    lp_config.PMUPWDN = LOWPOWER_PMUPWDN_DCDC | LOWPOWER_PMUPWDN_BIAS | LOWPOWER_PMUPWDN_BODVBAT |
+                        LOWPOWER_PMUPWDN_FRO192M | LOWPOWER_PMUPWDN_FRO1M;
+
+    lp_config.DIGPWDN = LOWPOWER_DIGPWDN_IO;
+
+    if (wakeup_src1 & LOWPOWER_WAKEUPSRCINT1_IO_IRQ)
+    {
+        lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_IO;
+        lp_config.WAKEUPIOSRC = pm_power_config->pm_wakeup_io;
+    }
+
+    if (wakeup_src0 & LOWPOWER_WAKEUPSRCINT0_NFCTAG_IRQ)
+    {
+        lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_NTAG_FD;
+    }
+    else
+    {
+        lp_config.DIGPWDN |= LOWPOWER_DIGPWDN_NTAG_FD;
+    }
+
+    lp_config.VOLTAGE = VOLTAGE(POWER_APPLY_TRIM(VOLTAGE_PMU_DEEP_DOWN), POWER_APPLY_TRIM(VOLTAGE_PMUBOOST_DEEP_DOWN),
+                                0, 0, 0, VOLTAGE_LDO_PMU_BOOST, 0);
+
+    if (autostart_32mhz_xtal)
+    {
+        lp_config.CFG |= LOWPOWER_CFG_XTAL32MSTARTENA_MASK;
+    }
+
+    /* [RFT1911] Disable the DC bus to prevent extra consumption */
+#ifndef POWER_DCBUS_NOT_DISABLED
+    ASYNC_SYSCON->DCBUSCTRL =
+        (ASYNC_SYSCON->DCBUSCTRL & ~ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK) | (1 << ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT);
+#endif
+
+    /* [artf555998] Enable new ES2 feature for fast wakeup */
+    PMC->CTRLNORST = PMC_CTRLNORST_FASTLDOENABLE_MASK;
+
+#ifdef DUMP_CONFIG
+    LF_DumpConfig(&lp_config);
+#endif
+
+    /* remove console if not done */
+    DbgConsole_Deinit();
+
+    /* Disable clocks to FLEXCOM power domain. This power domain is not reseted on wakeup by HW */
+    POWER_FlexcomClocksDisable();
+
+    Chip_LOWPOWER_SetLowPowerMode(&lp_config);
+
+    /* If we go here, the power mode has been aborted - this can happen only if WFI is executed in lowpower API*/
+    return false;
+}
+
+/*!
+ * brief Power Library API to enter different power mode.
+ *
+ * If requested mode is PM_POWER_DOWN, the API will perform the clamping of the DIOs
+ * if the PIO register has the bit IO_CLAMPING set: SYSCON->RETENTIONCTRL.IOCLAMP
+ * will be set
+ *
+ * return false if chip could not go to sleep. Configuration structure is incorrect
+ */
+bool POWER_EnterPowerMode(pm_power_mode_t pm_power_mode, pm_power_config_t *pm_power_config)
+{
+    bool ret;
+    switch (pm_power_mode)
+    {
+            /*  case PM_DEEP_SLEEP:
+                    ret = POWER_EnterDeepSleepMode(pm_power_config);
+                    break; */
+        case PM_POWER_DOWN:
+            ret = POWER_EnterPowerDownMode(pm_power_config);
+            break;
+        case PM_DEEP_DOWN:
+            ret = POWER_EnterDeepDownMode(pm_power_config);
+            break;
+        default:
+            ret = false;
+    }
+
+    return ret;
+}
+
+#ifdef DUMP_CONFIG
+static void LF_DumpConfig(LPC_LOWPOWER_T *LV_LowPowerMode)
+{
+    PRINTF("Powerdown configuration\n");
+    PRINTF("CFG:             0x%x\n", LV_LowPowerMode->CFG);
+    PRINTF("PMUPWDN:         0x%x\n", LV_LowPowerMode->PMUPWDN);
+    PRINTF("DIGPWDN:         0x%x\n", LV_LowPowerMode->DIGPWDN);
+    PRINTF("VOLTAGE:         0x%x\n", LV_LowPowerMode->VOLTAGE);
+    PRINTF("WAKEUPSRCINT0:   0x%x\n", LV_LowPowerMode->WAKEUPSRCINT0);
+    PRINTF("WAKEUPSRCINT1:   0x%x\n", LV_LowPowerMode->WAKEUPSRCINT1);
+    PRINTF("SLEEPPOSTPONE:   0x%x\n", LV_LowPowerMode->SLEEPPOSTPONE);
+    PRINTF("WAKEUPIOSRC      0x%x\n", LV_LowPowerMode->WAKEUPIOSRC);
+    PRINTF("GPIOLATCH        0x%x\n", LV_LowPowerMode->GPIOLATCH);
+    PRINTF("TIMERCFG         0x%x\n", LV_LowPowerMode->TIMERCFG);
+    PRINTF("TIMERBLECFG      0x%x\n", LV_LowPowerMode->TIMERBLECFG);
+    PRINTF("TIMERCOUNTLSB    0x%x\n", LV_LowPowerMode->TIMERCOUNTLSB);
+    PRINTF("TIMERCOUNTMSB    0x%x\n", LV_LowPowerMode->TIMERCOUNTMSB);
+    PRINTF("TIMER2NDCOUNTLSB 0x%x\n", LV_LowPowerMode->TIMER2NDCOUNTLSB);
+    PRINTF("TIMER2NDCOUNTMSB 0x%x\n", LV_LowPowerMode->TIMER2NDCOUNTMSB);
+}
+
+#endif
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_power.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_power.h
new file mode 100755
index 0000000..5b44bb1
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_power.h
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_POWER_H_
+#define _FSL_POWER_H_
+
+#include "rom_lowpower.h"
+#include "fsl_common.h"
+
+/*! @addtogroup power */
+/*! @{ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief BODVBAT configuration flag */
+#define POWER_BOD_ENABLE           ( 1 << 0 )
+#define POWER_BOD_DISABLE          ( 0 << 0 )
+#define POWER_BOD_INT_ENABLE       ( 1 << 1 )
+#define POWER_BOD_RST_ENABLE       ( 1 << 2 )
+#define POWER_BOD_HIGH             ( 1 << 3 ) /*!< ES2 BOD VBAT only */
+#define POWER_BOD_LOW              ( 0 << 3 )
+
+/*! @brief BOD trigger level setting */
+#define POWER_BOD_LVL_1_75V        9        /*!< Default at Reset , 1.7V on ES1 */
+#define POWER_BOD_LVL_1_8V         10       /*!< BOD trigger level 1.8V */
+#define POWER_BOD_LVL_1_9V         11       /*!< BOD trigger level 1.9V */
+#define POWER_BOD_LVL_2_0V         12       /*!< BOD trigger level 2.0V */
+#define POWER_BOD_LVL_2_1V         13       /*!< BOD trigger level 2.1V */
+#define POWER_BOD_LVL_2_2V         14       /*!< BOD trigger level 2.2V */
+#define POWER_BOD_LVL_2_3V         15       /*!< BOD trigger level 2.3V */
+#define POWER_BOD_LVL_2_4V         16       /*!< BOD trigger level 2.4V */
+#define POWER_BOD_LVL_2_5V         17       /*!< BOD trigger level 2.5V */
+#define POWER_BOD_LVL_2_6V         18       /*!< BOD trigger level 2.6V */
+#define POWER_BOD_LVL_2_7V         19       /*!< BOD trigger level 2.7V */
+#define POWER_BOD_LVL_2_8V         20       /*!< BOD trigger level 2.8V */
+#define POWER_BOD_LVL_2_9V         21       /*!< BOD trigger level 2.9V */
+#define POWER_BOD_LVL_3_0V         22       /*!< BOD trigger level 3.0V */
+#define POWER_BOD_LVL_3_1V         23       /*!< BOD trigger level 3.1V */
+#define POWER_BOD_LVL_3_2V         24       /*!< BOD trigger level 3.2V */
+#define POWER_BOD_LVL_3_3V         25       /*!< BOD trigger level 3.3V */
+
+/*! @brief BOD Hysteresis control setting */
+#define POWER_BOD_HYST_25MV        0        /*!< BOD Hysteresis control 25mV */
+#define POWER_BOD_HYST_50MV        1        /*!< BOD Hysteresis control 50mV */
+#define POWER_BOD_HYST_75MV        2        /*!< BOD Hysteresis control 75mV */
+#define POWER_BOD_HYST_100MV       3        /*!< BOD Hysteresis control 100mV, default at Reset */
+
+/**
+ * @brief  SRAM banks definition list for retention in power down modes !
+ */
+#define        PM_CFG_SRAM_BANK_BIT_BASE   0
+#define        PM_CFG_SRAM_BANK0_RET       (1<<0)   /*!< On ES1, this bank shall be kept in retention for Warmstart from power down */
+#define        PM_CFG_SRAM_BANK1_RET       (1<<1)   /*!< Bank 1 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK2_RET       (1<<2)   /*!< Bank 2 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK3_RET       (1<<3)   /*!< Bank 3 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK4_RET       (1<<4)   /*!< Bank 4 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK5_RET       (1<<5)   /*!< Bank 5 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK6_RET       (1<<6)   /*!< Bank 6 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK7_RET       (1<<7)   /*!< On ES2, this bank shall be kept in retention for Warmstart */
+#define        PM_CFG_SRAM_BANK8_RET       (1<<8)   /*!< Bank 8 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK9_RET       (1<<9)   /*!< Bank 9 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK10_RET      (1<<10)  /*!< Bank 10 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK11_RET      (1<<11)  /*!< Bank 11 shall be kept in retention */
+
+#define        PM_CFG_SRAM_ALL_RETENTION   0xFFF    /*!< All banks shall be kept in retention */
+
+#define        PM_CFG_RADIO_RET            (1<<13)
+#define        PM_CFG_XTAL32M_AUTOSTART    (1<<14)
+#define        PM_CFG_KEEP_AO_VOLTAGE      (1<<15)  /*!< keep the same voltage on the Always-on power domain - typical used with FRO32K to avoid timebase drift */
+
+#define POWER_WAKEUPSRC_SYSTEM         LOWPOWER_WAKEUPSRCINT0_SYSTEM_IRQ         /*!< BOD, Watchdog Timer, Flash controller, [DEEP SLEEP] BODVBAT [POWER_DOWN]*/
+#define POWER_WAKEUPSRC_DMA            LOWPOWER_WAKEUPSRCINT0_DMA_IRQ            /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_GINT           LOWPOWER_WAKEUPSRCINT0_GINT_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_IRBLASTER      LOWPOWER_WAKEUPSRCINT0_IRBLASTER_IRQ      /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PINT0          LOWPOWER_WAKEUPSRCINT0_PINT0_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PINT1          LOWPOWER_WAKEUPSRCINT0_PINT1_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PINT2          LOWPOWER_WAKEUPSRCINT0_PINT2_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PINT3          LOWPOWER_WAKEUPSRCINT0_PINT3_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_SPIFI          LOWPOWER_WAKEUPSRCINT0_SPIFI_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_TIMER0         LOWPOWER_WAKEUPSRCINT0_TIMER0_IRQ         /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_TIMER1         LOWPOWER_WAKEUPSRCINT0_TIMER1_IRQ         /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_USART0         LOWPOWER_WAKEUPSRCINT0_USART0_IRQ         /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_USART1         LOWPOWER_WAKEUPSRCINT0_USART1_IRQ         /*!< [DEEP SLEEP]  */
+#define POWER_WAKEUPSRC_I2C0           LOWPOWER_WAKEUPSRCINT0_I2C0_IRQ           /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_I2C1           LOWPOWER_WAKEUPSRCINT0_I2C1_IRQ           /*!< [DEEP SLEEP]  */
+#define POWER_WAKEUPSRC_SPI0           LOWPOWER_WAKEUPSRCINT0_SPI0_IRQ           /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_SPI1           LOWPOWER_WAKEUPSRCINT0_SPI1_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM0           LOWPOWER_WAKEUPSRCINT0_PWM0_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM1           LOWPOWER_WAKEUPSRCINT0_PWM1_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM2           LOWPOWER_WAKEUPSRCINT0_PWM2_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM3           LOWPOWER_WAKEUPSRCINT0_PWM3_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM4           LOWPOWER_WAKEUPSRCINT0_PWM4_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM5           LOWPOWER_WAKEUPSRCINT0_PWM5_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM6           LOWPOWER_WAKEUPSRCINT0_PWM6_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM7           LOWPOWER_WAKEUPSRCINT0_PWM7_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM8           LOWPOWER_WAKEUPSRCINT0_PWM8_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM9           LOWPOWER_WAKEUPSRCINT0_PWM9_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM10          LOWPOWER_WAKEUPSRCINT0_PWM10_IR           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_I2C2           LOWPOWER_WAKEUPSRCINT0_I2C2_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_RTC            LOWPOWER_WAKEUPSRCINT0_RTC_IRQ            /*!< [DEEP SLEEP, POWER DOWN]  */
+#define POWER_WAKEUPSRC_NFCTAG         LOWPOWER_WAKEUPSRCINT0_NFCTAG_IRQ         /*!< [DEEP SLEEP, POWER DOWN (ES2 Only), DEEP DOWN (ES2 only)]  */
+#define POWER_WAKEUPSRC_MAILBOX        LOWPOWER_WAKEUPSRCINT0_MAILBOX_IRQ        /*!< Mailbox, Wake-up from DEEP SLEEP and POWER DOWN low power mode [DEEP SLEEP, POWER DOWN] */
+
+#define POWER_WAKEUPSRC_ADC_SEQA       ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ADC_SEQA_IRQ       << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ADC_SEQB       ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ADC_SEQB_IRQ       << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ADC_THCMP_OVR  ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ADC_THCMP_OVR_IRQ  << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_DMIC           ((uint64_t)LOWPOWER_WAKEUPSRCINT1_DMIC_IRQ           << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_HWVAD          ((uint64_t)LOWPOWER_WAKEUPSRCINT1_HWVAD_IRQ          << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_DP         ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_DP_IRQ         << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_DP0        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_DP0_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_DP1        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_DP1_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_DP2        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_DP2_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_LL_ALL     ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_LL_ALL_IRQ     << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ZIGBEE_MAC     ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ZIGBEE_MAC_IRQ     << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ZIGBEE_MODEM   ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ZIGBEE_MODEM_IRQ   << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_RFP_TMU        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_RFP_TMU_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_RFP_AGC        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_RFP_AGC_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ISO7816        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ISO7816_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ANA_COMP       ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ANA_COMP_IRQ       << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_WAKE_UP_TIMER0 ((uint64_t)LOWPOWER_WAKEUPSRCINT1_WAKE_UP_TIMER0_IRQ << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_WAKE_UP_TIMER1 ((uint64_t)LOWPOWER_WAKEUPSRCINT1_WAKE_UP_TIMER1_IRQ << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_BLE_WAKE_TIMER ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_WAKE_TIMER_IRQ << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_BLE_OSC_EN     ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_OSC_EN_IRQ     << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_IO             ((uint64_t)LOWPOWER_WAKEUPSRCINT1_IO_IRQ             << 32)  /*!< [POWER DOWN, DEEP DOWN]  */
+
+/**
+ * @brief  BOD config
+ */
+typedef struct {
+    uint8_t bod_level;  /*!< BOD trigger level */
+    uint8_t bod_hyst;   /*!< BOD Hysteresis control */
+    uint8_t bod_cfg;    /*!< BOD config setting */
+} pm_bod_cfg_t;
+
+typedef uint64_t       pm_wake_source_t;
+
+/**
+ * @brief  PDRUNCFG bits offset
+ */
+typedef enum pd_bits
+{
+    kPDRUNCFG_PD_LDO_ADC_EN = 22,           /*!< Offset is 22, LDO ADC enabled */
+    kPDRUNCFG_PD_BOD_MEM_EN = 23,           /*!< Offset is 23, BOD MEM enabled */
+    kPDRUNCFG_PD_BOD_CORE_EN = 24,          /*!< Offset is 24, BOD CORE enabled */
+    kPDRUNCFG_PD_FRO32K_EN       = 25,      /*!< Offset is 25, FRO32K enabled */
+    kPDRUNCFG_PD_XTAL32K_EN      = 26,      /*!< Offset is 26, XTAL32K enabled */
+    kPDRUNCFG_PD_BOD_ANA_COMP_EN = 27,      /*!< Offset is 27, Analog Comparator enabled */
+
+    kPDRUNCFG_ForceUnsigned = 0x80000000U
+} pd_bit_t;
+
+/**
+ * @brief  Power modes
+ */
+typedef enum {
+    /* PM_DEEP_SLEEP, */
+    PM_POWER_DOWN,  /*!< Power down mode */
+    PM_DEEP_DOWN,   /*!< Deep power down mode */
+} pm_power_mode_t ;
+
+/**
+ * @brief  Power config
+ */
+typedef struct {
+    pm_wake_source_t pm_wakeup_src; /*!< Wakeup source select */
+    uint32_t         pm_wakeup_io;  /*!< Wakeup IO */
+    uint32_t         pm_config;     /*!< Power mode config */
+} pm_power_config_t;
+
+/**
+ * @brief  Reset Cause definition
+ */
+typedef enum reset_cause
+{
+    RESET_UNDEFINED     = 0,
+    RESET_POR           = (1 << 0), /*!< The last chip reset was caused by a Power On Reset. */
+    RESET_EXT_PIN       = (1 << 1), /*!< The last chip reset was caused by a Pad Reset. */
+    RESET_BOR           = (1 << 2), /*!< The last chip reset was caused by a Brown Out Detector. */
+    RESET_SYS_REQ       = (1 << 3), /*!< The last chip reset was caused by a System Reset requested by the ARM CPU. */
+    RESET_WDT           = (1 << 4), /*!< The last chip reset was caused by the Watchdog Timer. */
+    RESET_WAKE_DEEP_PD  = (1 << 5), /*!< The last chip reset was caused by a Wake-up I/O (GPIO or internal NTAG FD INT). */
+    RESET_WAKE_PD       = (1 << 6), /*!< The last CPU reset was caused by a Wake-up from Power down (many sources possible: timer, IO, ...). */
+    RESET_SW_REQ        = (1 << 7)  /*!< The last chip reset was caused by a Software. ES2 Only */
+} reset_cause_t;
+
+/**
+ * @brief  LDO voltage setting
+ */
+typedef enum {
+    PM_LDO_VOLT_1_1V_DEFAULT,   /*!< LDO voltage 1.1V */
+    PM_LDO_VOLT_1_0V,  /*!< not safe at system start/wakeup and CPU clock switch to higher frequency */
+} pm_ldo_volt_t ;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+* @name Power Configuration
+* @{
+*/
+
+/*!
+ * @brief Initialize the sdk power drivers
+ *
+ * Optimize the LDO voltage for power saving
+ * Initialize the power domains
+ *
+ * @return none
+ */
+void POWER_Init(void);
+
+/*!
+ * @brief  Optimize the LDO voltage for power saving
+ * Initialize the power domains
+ *
+ * @return none
+ */
+void POWER_SetTrimDefaultActiveVoltage(void);
+
+/*!
+ * @brief BODMEM and BODCORE setup
+ *
+ * Enable the BOD core and BOD mem
+ * Disable the analog comnparator clock
+ *
+ * @return none
+ */
+void POWER_BodSetUp(void);
+
+/*!
+ * @brief enable SW reset for the BODCORE
+ *
+ * @return none
+ */
+void POWER_BodActivate(void);
+
+/*!
+ * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
+ *
+ * @param en    peripheral for which to enable the PDRUNCFG bit
+ *
+ * @return none
+ */
+static inline void POWER_EnablePD(pd_bit_t en)
+{
+    /* PDRUNCFGSET */
+    PMC->PDRUNCFG |= (1UL << (en & 0xffU));
+}
+
+/*!
+ * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
+ *
+ * @param en    peripheral for which to disable the PDRUNCFG bit
+ *
+ * @return none
+ */
+static inline void POWER_DisablePD(pd_bit_t en)
+{
+    /* PDRUNCFGCLR */
+    PMC->PDRUNCFG &= ~(1UL << (en & 0xffU));
+}
+
+/*!
+ *  @brief Get IO and Ntag Field detect Wake-up sources from Power Down and Deep Power Down modes.
+ *  Allow to identify the wake-up source when waking up from Power-Down modes or Deep Power Down modes.
+ *  Status is reset by POR, RSTN, WDT.
+ *  bit in range from 0 to 21 are for DIO0 to DIO21
+ *  bit 22 is NTAG field detect wakeup source
+ *
+ *  @return IO and Field detect Wake-up source
+ */
+static inline uint32_t POWER_GetIoWakeStatus(void)
+{
+    return PMC->WAKEIOCAUSE;
+}
+
+/*!
+ * @brief Power API to enter sleep mode (Doze mode)
+ *
+ * @note: The static inline function has not the expecetd effect in -O0. If order to force inline this macro is added
+ *
+ * @return none
+ */
+#define POWER_ENTER_SLEEP()  __DSB(); __WFI(); __ISB();
+
+/*!
+ * @brief Power API to enter sleep mode (Doze mode)
+ *
+ * @note: If the user desires to program a wakeup timer before going to sleep, it needs to use
+ * either the fsl_wtimer.h API or use the POWER_SetLowPower() API instead
+ * see POWER_ENTER_SLEEP
+ *
+ * @return none
+ */
+static inline void POWER_EnterSleep(void)
+{
+    POWER_ENTER_SLEEP();
+}
+
+/*!
+ * @brief Power Library API to enter different power mode.
+ * If requested mode is PM_POWER_DOWN, the API will perform the clamping of the DIOs
+ * if the PIO register has the bit IO_CLAMPING set: SYSCON->RETENTIONCTRL.IOCLAMP
+ * will be set
+ *
+ * @param pm_power_mode  Power modes
+ * @see pm_power_mode_t
+ * @param pm_power_config Power config
+ * @see pm_power_config_t
+ *
+ * @return false if chip could not go to sleep. Configuration structure is incorrect
+ */
+bool POWER_EnterPowerMode(pm_power_mode_t pm_power_mode, pm_power_config_t* pm_power_config);
+
+/*!
+ * @brief determine cause of reset
+ *
+ * @return reset_cause
+ */
+reset_cause_t POWER_GetResetCause(void);
+
+/*!
+ * @brief Clear cause of reset
+ */
+void POWER_ClearResetCause(void);
+
+/*!
+ * @brief Power Library API to return the library version.
+ *
+ * @param none
+ *
+ * @return version number of the power library
+ */
+uint32_t POWER_GetLibVersion(void);
+
+/*!
+ * @brief Get default Vbat BOD config parameters, level @1.75V, Hysteresis @ 100mV
+ *
+ * @param bod_cfg_p BOD config
+ * @see pm_bod_cfg_t
+ *
+ * @return none
+ */
+void POWER_BodVbatGetDefaultConfig(pm_bod_cfg_t * bod_cfg_p);
+
+/*!
+ * @brief Configure the VBAT BOD
+ *
+ * @param bod_cfg_p BOD config
+ * @see pm_bod_cfg_t
+ *
+ * @return false if configuration parameters are incorrect
+ */
+bool POWER_BodVbatConfig(pm_bod_cfg_t * bod_cfg_p);
+
+/*!
+ * @brief Configure the LDO voltage
+ *
+ * @param ldoVolt LDO voltage setting
+ * @see pm_ldo_volt_t
+ *
+ * @return none
+ */
+void POWER_ApplyLdoActiveVoltage(pm_ldo_volt_t ldoVolt);
+
+/* @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*! @} */
+
+#endif /* _FSL_POWER_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_reset.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_reset.c
new file mode 100755
index 0000000..c4a584d
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_reset.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_reset.h"
+
+#include "rom_lowpower.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.reset"
+#endif
+/* RG TODO This should be defined in jn518x.h */
+#define SYSCON_PRESETCTRL_COUNT 2
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
+     (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
+
+/*!
+ * brief Assert reset to peripheral.
+ *
+ * Asserts reset signal to specified peripheral module.
+ *
+ * param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_SetPeripheralReset(reset_ip_name_t peripheral)
+{
+    const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
+    const uint32_t bitPos   = ((uint32_t)peripheral & 0x0000FFFFu);
+    const uint32_t bitMask  = 1u << bitPos;
+
+    assert(bitPos < 32u);
+
+    /* ASYNC_SYSCON registers have offset 1024 */
+    if (regIndex >= SYSCON_PRESETCTRL_COUNT)
+    {
+        /* reset register is in ASYNC_SYSCON */
+
+        /* set bit */
+        ASYNC_SYSCON->ASYNCPRESETCTRLSET = bitMask;
+        /* wait until it reads 0b1 */
+        while (0u == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
+        {
+        }
+    }
+    else
+    {
+        /* reset register is in SYSCON */
+
+        /* set bit */
+        SYSCON->PRESETCTRLSETS[regIndex] = bitMask;
+        /* wait until it reads 0b1 */
+        while (0u == (SYSCON->PRESETCTRLS[regIndex] & bitMask))
+        {
+        }
+    }
+}
+
+/*!
+ * brief Clear reset to peripheral.
+ *
+ * Clears reset signal to specified peripheral module, allows it to operate.
+ *
+ * param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_ClearPeripheralReset(reset_ip_name_t peripheral)
+{
+    const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
+    const uint32_t bitPos   = ((uint32_t)peripheral & 0x0000FFFFu);
+    const uint32_t bitMask  = 1u << bitPos;
+
+    assert(bitPos < 32u);
+
+    /* ASYNC_SYSCON registers have offset > SYSCON_PRESETCTRL_COUNT */
+    if (regIndex >= SYSCON_PRESETCTRL_COUNT)
+    {
+        /* reset register is in ASYNC_SYSCON */
+
+        /* clear bit */
+        ASYNC_SYSCON->ASYNCPRESETCTRLCLR = bitMask;
+        /* wait until it reads 0b0 */
+        while (bitMask == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
+        {
+        }
+    }
+    else
+    {
+        /* reset register is in SYSCON */
+
+        /* clear bit */
+        SYSCON->PRESETCTRLCLRS[regIndex] = bitMask;
+        /* wait until it reads 0b0 */
+        while (bitMask == (SYSCON->PRESETCTRLS[regIndex] & bitMask))
+        {
+        }
+    }
+}
+
+/*!
+ * brief Reset peripheral module.
+ *
+ * Reset peripheral module.
+ *
+ * param peripheral Peripheral to reset. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_PeripheralReset(reset_ip_name_t peripheral)
+{
+    RESET_SetPeripheralReset(peripheral);
+    RESET_ClearPeripheralReset(peripheral);
+}
+
+#endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */
+
+/*!
+ * brief Reset the chip.
+ *
+ * Full software reset of the chip.
+ * On reboot, function POWER_GetResetCause() from fsl_power.h will return RESET_SYS_REQ
+ */
+void RESET_SystemReset(void)
+{
+    /* Disable all interrupts */
+    __disable_irq();
+    /* On ES2, software reset is directly implemented in ROM code so the Flash
+     * controller can be correctly powered OFF before the reset */
+    Chip_LOWPOWER_ChipSoftwareReset();
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_reset.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_reset.h
new file mode 100755
index 0000000..5d88ab7
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_reset.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_RESET_H_
+#define _FSL_RESET_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "fsl_device_registers.h"
+
+/*!
+ * @addtogroup ksdk_common
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief RESET driver version 2.0.1. */
+#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
+/*@}*/
+
+/*!
+ * @brief Enumeration for peripheral reset control bits
+ *
+ * Defines the enumeration for peripheral reset control bits in PRESETCTRL/ASYNCPRESETCTRL registers
+ */
+typedef enum _SYSCON_RSTn
+{
+    kSPIFI_RST_SHIFT_RSTn   = (0 | SYSCON_PRESETCTRL0_SPIFI_RST_SHIFT), /**< SpiFi reset control   */
+    kMUX_RST_SHIFT_RSTn     = (0 | SYSCON_PRESETCTRL0_MUX_RST_SHIFT),   /**< Input mux reset control */
+    kIOCON_RST_SHIFT_RSTn   = (0 | SYSCON_PRESETCTRL0_IOCON_RST_SHIFT), /**< IOCON reset control */
+    kGPIO0_RST_SHIFT_RSTn   = (0 | SYSCON_PRESETCTRL0_GPIO_RST_SHIFT),  /**< GPIO0 reset control */
+    kPINT_RST_SHIFT_RSTn    = (0 | SYSCON_PRESETCTRL0_PINT_RST_SHIFT),  /**< Pin interrupt (PINT) reset control */
+    kGINT_RST_SHIFT_RSTn    = (0 | SYSCON_PRESETCTRL0_GINT_RST_SHIFT),  /**< Grouped interrupt (PINT) reset control. */
+    kDMA_RST_SHIFT_RSTn     = (0 | SYSCON_PRESETCTRL0_DMA_RST_SHIFT),   /**< DMA reset control */
+    kWWDT_RST_SHIFT_RSTn    = (0 | SYSCON_PRESETCTRL0_WWDT_RST_SHIFT),  /**< Watchdog timer reset control */
+    kRTC_RST_SHIFT_RSTn     = (0 | SYSCON_PRESETCTRL0_RTC_RST_SHIFT),   /**< RTC reset control */
+    kANA_INT_RST_SHIFT_RSTn = (0 | SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_SHIFT), /**< Analog interrupt controller reset */
+    kWKT_RST_SHIFT_RSTn     = (0 | SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_SHIFT), /**< Wakeup timer reset */
+    kADC0_RST_SHIFT_RSTn    = (0 | SYSCON_PRESETCTRL0_ADC_RST_SHIFT),            /**< ADC0 reset control */
+    kFC0_RST_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_USART0_RST_SHIFT), /**< Flexcomm Interface 0 reset control */
+    kFC1_RST_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_USART1_RST_SHIFT),                 /**< Flexcomm Interface 1 reset control */
+    kFC2_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_I2C0_RST_SHIFT), /**< Flexcomm Interface 2 reset control */
+    kFC3_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_I2C1_RST_SHIFT), /**< Flexcomm Interface 3 reset control */
+    kFC4_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_SPI0_RST_SHIFT), /**< Flexcomm Interface 4 reset control */
+    kFC5_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_SPI1_RST_SHIFT), /**< Flexcomm Interface 5 reset control */
+    kIRB_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_IR_RST_SHIFT),   /**< IR Blaster reset control */
+    kPWM_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_PWM_RST_SHIFT),  /**< PWM reset control */
+    kRNG_RST_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_RNG_RST_SHIFT), /**< Random number generator reset control */
+    kFC6_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_I2C2_RST_SHIFT), /**< Flexcomm Interface 6 reset control */
+    kUSART0_RST_SHIFT_RSTn = kFC0_RST_SHIFT_RSTn,                            /**< USART0 reset control == Flexcomm0 */
+    kUSART1_RST_SHIFT_RSTn = kFC1_RST_SHIFT_RSTn,                            /**< USART0 reset control == Flexcomm1 */
+    kI2C0_RST_SHIFT_RSTn   = kFC2_RST_SHIFT_RSTn,                            /**< I2C0 reset control == Flexcomm 2  */
+    kI2C1_RST_SHIFT_RSTn   = kFC3_RST_SHIFT_RSTn,                            /**< I2C1 reset control == Flexcomm 3  */
+    kSPI0_RST_SHIFT_RSTn   = kFC4_RST_SHIFT_RSTn,                            /**< SPI0 reset control == Flexcomm 4  */
+    kSPI1_RST_SHIFT_RSTn   = kFC5_RST_SHIFT_RSTn,                            /**< SPI1 reset control == Flexcomm 5  */
+    kI2C2_RST_SHIFT_RSTn   = kFC6_RST_SHIFT_RSTn,                            /**< I2C2 reset control == Flexcomm 6  */
+    kMODEM_MASTER_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_MODEM_MASTER_RST_SHIFT),          /**< AHB Modem master interface reset */
+    kAES_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_AES_RST_SHIFT), /**< Encryption module reset control */
+    kRFP_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_RFP_RST_SHIFT), /**< Radio front end controller reset */
+    kDMIC_RST_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_DMIC_RST_SHIFT), /**< Digital microphone interface reset control */
+    kHASH_RST_SHIFT_RSTn    = ((1UL << 16) | SYSCON_PRESETCTRL1_HASH_RST_SHIFT),         /**< Hash SHA reset */
+    kCTIMER0_RST_SHIFT_RSTn = ((2UL << 16) | ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT), /**< CT32B0 reset control */
+    kCTIMER1_RST_SHIFT_RSTn = ((2UL << 16) | ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT), /**< CT32B1 reset control */
+} SYSCON_RSTn_t;
+
+/** Array initializers with peripheral reset bits **/
+#define ADC_RSTS             \
+    {                        \
+        kADC0_RST_SHIFT_RSTn \
+    } /* Reset bits for ADC peripheral */
+#define AES_RSTS             \
+    {                        \
+        kAES_RST_SHIFT_RSTbn \
+    } /* Reset bits for Encryption peripheral */
+#define ANA_INT_RSTS            \
+    {                           \
+        kANA_INT_RST_SHIFT_RSTn \
+    } /* Reset bits for Analog interrupts controller */
+#define BLE_RSTS            \
+    {                       \
+        kBLE_RST_SHIFT_RSTn \
+    } /* Reset bits for Bluetooth LE peripheral */
+#define BLE_TG_RSTS            \
+    {                          \
+        kBLE_TG_RST_SHIFT_RSTn \
+    } /* Bluetooth LE power module reset */
+#define CRC_RSTS            \
+    {                       \
+        kCRC_RST_SHIFT_RSTn \
+    } /* Reset bits for CRC peripheral */
+#define CTIMER_RSTS                                      \
+    {                                                    \
+        kCTIMER0_RST_SHIFT_RSTn, kCTIMER1_RST_SHIFT_RSTn \
+    } /* Reset bits for TIMER peripheral */
+#define DMA_RSTS_N          \
+    {                       \
+        kDMA_RST_SHIFT_RSTn \
+    } /* Reset bits for DMA peripheral */
+#define DMIC_RSTS            \
+    {                        \
+        kDMIC_RST_SHIFT_RSTn \
+    } /* Reset bits for ADC peripheral */
+#define EFUSE_RSTS            \
+    {                         \
+        kEFUSE_RST_SHIFT_RSTn \
+    } /* Reset bits for EFuse peripheral */
+#define FLASH_RSTS            \
+    {                         \
+        kFLASH_RST_SHIFT_RSTn \
+    } /* Reset bits for flash controller */
+#define FLEXCOMM_RSTS                                                                                            \
+    {                                                                                                            \
+        kFC0_RST_SHIFT_RSTn, kFC1_RST_SHIFT_RSTn, kFC2_RST_SHIFT_RSTn, kFC3_RST_SHIFT_RSTn, kFC4_RST_SHIFT_RSTn, \
+            kFC5_RST_SHIFT_RSTn, kFC6_RST_SHIFT_RSTn                                                             \
+    } /* Reset bits for FLEXCOMM peripheral */
+#define GINT_RSTS            \
+    {                        \
+        kGINT_RST_SHIFT_RSTn \
+    } /* Reset bits for GINT peripheral. GINT0 & GINT1 share same slot */
+#define GPIO_RSTS_N           \
+    {                         \
+        kGPIO0_RST_SHIFT_RSTn \
+    } /* Reset bits for GPIO peripheral */
+#define INPUTMUX_RSTS       \
+    {                       \
+        kMUX_RST_SHIFT_RSTn \
+    } /* Reset bits for INPUTMUX peripheral */
+#define IOCON_RSTS            \
+    {                         \
+        kIOCON_RST_SHIFT_RSTn \
+    } /* Reset bits for IOCON peripheral */
+#define ZIGBEE_RSTS            \
+    {                          \
+        kZIGBEE_RST_SHIFT_RSTn \
+    } /* Reset bits for RF/Zigbee peripheral */
+#define MAILBOX_RSTS            \
+    {                           \
+        kMAILBOX_RST_SHIFT_RSTn \
+    } /* Reset bits for inter-CPU mailbox peripheral */
+#define MODEM_RSTS               \
+    {                            \
+        kMODEM_MASTER_SHIFT_RSTn \
+    } /* Reset bits for AHB Modem master interface peripheral */
+#define MRT_RSTS            \
+    {                       \
+        kMRT_RST_SHIFT_RSTn \
+    } /* Reset bits for MRT peripheral */
+#define PINT_RSTS            \
+    {                        \
+        kPINT_RST_SHIFT_RSTn \
+    } /* Reset bits for PINT peripheral */
+#define PVT_RSTS            \
+    {                       \
+        kPVT_RST_SHIFT_RSTn \
+    } /* Reset bits for PVT peripheral */
+#define RTC_RSTS            \
+    {                       \
+        kRTC_RST_SHIFT_RSTn \
+    } /* Reset bits for RTC peripheral */
+#define SPIFI_RSTS            \
+    {                         \
+        kSPIFI_RST_SHIFT_RSTn \
+    } /* Reset bits for SPIFI peripheral */
+#define TPR_RSTS            \
+    {                       \
+        kTPR_RST_SHIFT_RSTn \
+    } /* Reset bits for test pointer register peripheral */
+#define WWDT_RSTS            \
+    {                        \
+        kWWDT_RST_SHIFT_RSTn \
+    } /* Reset bits for windowed watchdog timer */
+
+#define WWDT_RSTS            \
+    {                        \
+        kWWDT_RST_SHIFT_RSTn \
+    } /* Reset bits for WWDT peripheral */
+
+typedef SYSCON_RSTn_t reset_ip_name_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @brief Assert reset to peripheral.
+ *
+ * Asserts reset signal to specified peripheral module.
+ *
+ * @param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_SetPeripheralReset(reset_ip_name_t peripheral);
+
+/*!
+ * @brief Clear reset to peripheral.
+ *
+ * Clears reset signal to specified peripheral module, allows it to operate.
+ *
+ * @param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_ClearPeripheralReset(reset_ip_name_t peripheral);
+
+/*!
+ * @brief Reset peripheral module.
+ *
+ * Reset peripheral module.
+ *
+ * @param peripheral Peripheral to reset. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_PeripheralReset(reset_ip_name_t peripheral);
+
+/*!
+ * @brief Reset the chip.
+ *
+ * Full software reset of the chip.
+ * On reboot, function POWER_GetResetCause() from fsl_power.h will return RESET_SYS_REQ
+ */
+void RESET_SystemReset(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @} */
+
+#endif /* _FSL_RESET_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_rng.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_rng.c
new file mode 100755
index 0000000..f1ba450
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_rng.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_rng.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.jn_rng"
+#endif
+
+#define TRNG_MODE_SEL_BIT_NUM (0)
+#define TRNG_MODE_SEL_BIT_MASK (0x3 << TRNG_MODE_SEL_BIT_NUM)
+#define TRNG_CLOCK_SEL_BIT_NUM (2)
+#define TRNG_CLOCK_SEL_BIT_MASK (0x7 << TRNG_CLOCK_SEL_BIT_NUM)
+#define TRNG_SHIFT4X_BIT_NUM (5)
+#define TRNG_SHIFT4X_BIT_MASK (0x7 << TRNG_SHIFT4X_BIT_NUM)
+
+/*******************************************************************************
+ * Public APIs
+ ******************************************************************************/
+
+status_t TRNG_GetDefaultConfig(trng_config_t *userConfig)
+{
+    /* Check if valid parameters */
+    if (userConfig == NULL)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Initialise configuration structure */
+    userConfig->shift4x   = 0;
+    userConfig->clock_sel = 0;
+    userConfig->mode      = trng_FreeRunning;
+    return kStatus_Success;
+}
+
+status_t TRNG_Init(RNG_Type *base, const trng_config_t *userConfig)
+{
+    /* Check if valid parameters are passed */
+    if ((base == NULL) || (userConfig == NULL))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Check if valid parameters are passed */
+    if ((userConfig->mode != trng_UpdateOnce) && (userConfig->mode != trng_FreeRunning))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Enable RNG peripheral clock for register access */
+    /* Make sure that the XTAL 32MHz clock is enabled before this */
+    if (!(ASYNC_SYSCON->XTAL32MCTRL & ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK))
+    {
+        return kStatus_Fail;
+    }
+    SYSCON->PRESETCTRLSET[1] = SYSCON_PRESETCTRLSET1_RNG_RST_SET_MASK;
+    //CLOCK_EnableClock(kCLOCK_Xtal32M);
+    CLOCK_EnableClock(kCLOCK_Rng);
+    SYSCON->PRESETCTRLCLR[1] = SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_MASK;
+
+    /* Enable Analog clocks for RNG module */
+    SYSCON->RNGCLKCTRL = 1;
+
+    /* Configure TRNG module */
+    base->COUNTER_CFG &= ~(TRNG_CLOCK_SEL_BIT_MASK | TRNG_SHIFT4X_BIT_MASK | TRNG_MODE_SEL_BIT_MASK);
+    base->COUNTER_CFG |=
+        ((userConfig->clock_sel << TRNG_CLOCK_SEL_BIT_NUM) | (userConfig->shift4x << TRNG_SHIFT4X_BIT_NUM));
+
+    /* Set mode */
+    base->COUNTER_CFG |= userConfig->mode;
+
+    return kStatus_Success;
+}
+
+void TRNG_Deinit(RNG_Type *base)
+{
+    /* Disable Analog clocks for RNG module */
+    SYSCON->RNGCLKCTRL = 0;
+
+    /* Disable RNG clock */
+    CLOCK_DisableClock(kCLOCK_Rng);
+    return;
+}
+
+status_t TRNG_GetRandomData(RNG_Type *base, void *data, size_t data_size)
+{
+    uint32_t random_32;
+    uint8_t *random_p;
+    uint32_t random_size;
+    uint8_t *data_p = (uint8_t *)data;
+    uint32_t i;
+
+    /* Check if valid parameters */
+    if ((base == NULL) || (data == NULL) || (data_size == 0))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Read random data as per user request */
+    do
+    {
+        /* Read random data from register Entropy.*/
+        random_32 = base->RANDOM_NUMBER;
+
+        /* Extract required bytes */
+        random_p = (uint8_t *)&random_32;
+
+        if (data_size < sizeof(random_32))
+        {
+            random_size = data_size;
+        }
+        else
+        {
+            random_size = sizeof(random_32);
+        }
+
+        for (i = 0U; i < random_size; i++)
+        {
+            *data_p++ = *random_p++;
+        }
+
+        data_size -= random_size;
+    } while (data_size > 0);
+
+    return kStatus_Success;
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_rng.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_rng.h
new file mode 100755
index 0000000..f1677b2
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_rng.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FSL_RNG_H_
+#define __FSL_RNG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup jn_rng
+ * @{
+ */
+
+/*! @file */
+
+/**
+ * RNG return status types
+ */
+
+/**
+ * RNG operating modes
+ */
+typedef enum _trng_mode
+{
+    trng_UpdateOnce  = 0x1, /*!< TRNG update once & disable */
+    trng_FreeRunning = 0x2, /*!< TRNG updates continuously */
+} trng_mode_t;
+
+typedef struct _trng_config
+{
+    uint8_t shift4x;   /*!< Used to add precision to clock ratio & entropy refill - range from 0 to 4 */
+    uint8_t clock_sel; /*!< Internal clock on which to compute statistics */
+                       /*!< 0 - XOR results from all clocks */
+                       /*!< 1 - First clock */
+                       /*!< 2 - Second clock */
+    trng_mode_t mode;  /*!< TRNG mode select */
+} trng_config_t;
+
+/*!
+ * @brief Gets Default config of TRNG.
+ *
+ * This function initializes the TRNG configuration structure.
+ *
+ * @param userConfig Pointer to TRNG configuration structure
+ */
+status_t TRNG_GetDefaultConfig(trng_config_t *userConfig);
+
+/*!
+ * @brief Initializes the TRNG.
+ *
+ * This function initializes the TRNG.
+ *
+ * @param base TRNG base address
+ * @param userConfig The configuration of TRNG
+ * @return  kStatus_Success - Success
+ *          kStatus_InvalidArgument - Invalid parameter
+ */
+status_t TRNG_Init(RNG_Type *base, const trng_config_t *userConfig);
+
+/*!
+ * @brief Shuts down the TRNG.
+ *
+ * This function shuts down the TRNG.
+ *
+ * @param base TRNG base address
+ */
+void TRNG_Deinit(RNG_Type *base);
+
+/*!
+ * @brief Gets random data.
+ *
+ * This function gets random data from the TRNG.
+ *
+ * @param base TRNG base address
+ * @param data pointer to user buffer to be filled by random data
+ * @param data_size size of data in bytes
+ * @return TRNG status
+ */
+status_t TRNG_GetRandomData(RNG_Type *base, void *data, size_t data_size);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* __RNG_JN518X_H_*/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_sha.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_sha.c
new file mode 100755
index 0000000..81a5c58
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_sha.c
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "fsl_sha.h"
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.sha"
+#endif
+
+/*!< SHA-1 and SHA-256 block size  */
+#define SHA_BLOCK_SIZE 64
+
+/*!< Use standard C library memcpy  */
+#define sha_memcpy memcpy
+
+/*! Internal states of the HASH creation process */
+typedef enum _sha_algo_state
+{
+    kSHA_HashInit = 1u, /*!< Init state, the NEW bit in SHA Control register has not been written yet. */
+    kSHA_HashUpdate, /*!< Update state, DIGEST registers contain running hash, NEW bit in SHA control register has been
+                        written. */
+} sha_algo_state_t;
+
+/*! 64-byte block represented as byte array of 16 32-bit words */
+typedef union _sha_hash_block
+{
+    uint32_t w[SHA_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
+    uint8_t b[SHA_BLOCK_SIZE];      /*!< byte array */
+} sha_block_t;
+
+/*! internal sha context structure */
+typedef struct _sha_ctx_internal
+{
+    sha_block_t blk;        /*!< memory buffer. only full 64-byte blocks are written to SHA during hash updates */
+    size_t blksz;           /*!< number of valid bytes in memory buffer */
+    sha_algo_t algo;        /*!< selected algorithm from the set of supported algorithms */
+    sha_algo_state_t state; /*!< finite machine state of the hash software process */
+    size_t fullMessageSize; /*!< track message size during SHA_Update(). The value is used for padding. */
+} sha_ctx_internal_t;
+
+/*!< SHA-1 and SHA-256 digest length in bytes  */
+enum _sha_digest_len
+{
+    kSHA_OutLenSha1   = 20u,
+    kSHA_OutLenSha256 = 32u,
+};
+
+/*!< macro for checking build time condition. It is used to assure the sha_ctx_internal_t can fit into sha_ctx_t */
+#define BUILD_ASSERT(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * @brief LDM to SHA engine INDATA and ALIAS registers.
+ *
+ * This function writes 16 words starting from the src address (must be word aligned)
+ * to the dst address. Dst address does not increment (destination is peripheral module register INDATA).
+ * Src address increments to load 16 consecutive words.
+ *
+ * @param dst peripheral register address (word aligned)
+ * @param src address of the input 512-bit block (16 words) (word aligned)
+ *
+ */
+#if defined(SHA_ALIAS_DATA_MASK)
+__STATIC_INLINE void sha_ldm_stm_16_words(SHA_Type *base, const uint32_t *src)
+{
+    base->INDATA = src[0];
+    for (int i = 0; i < 7; i++)
+    {
+        base->ALIAS[i] = src[i + 1];
+    }
+    src += 8u;
+    base->INDATA = src[0];
+    for (int i = 0; i < 7; i++)
+    {
+        base->ALIAS[i] = src[i + 1];
+    }
+}
+#else
+__STATIC_INLINE void sha_ldm_stm_16_words(volatile uint32_t *dst, const uint32_t *src)
+{
+    for (int i = 0; i < 8; i++)
+    {
+        dst[i] = src[i];
+    }
+    src += 8u;
+    for (int i = 0; i < 8; i++)
+    {
+        dst[i] = src[i];
+    }
+}
+#endif
+/*!
+ * @brief Swap bytes withing 32-bit word.
+ *
+ * This function changes endianess of a 32-bit word.
+ *
+ * @param in 32-bit unsigned integer
+ * @return 32-bit unsigned integer with different endianess (big endian to little endian and vice versa).
+ */
+static uint32_t swap_bytes(uint32_t in)
+{
+    return (((in & 0x000000ffu) << 24) | ((in & 0x0000ff00u) << 8) | ((in & 0x00ff0000u) >> 8) |
+            ((in & 0xff000000u) >> 24));
+}
+
+/*!
+ * @brief Check validity of algoritm.
+ *
+ * This function checks the validity of input argument.
+ *
+ * @param algo Tested algorithm value.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t sha_check_input_alg(sha_algo_t algo)
+{
+    if ((algo != kSHA_Sha1) && (algo != kSHA_Sha256))
+    {
+        return kStatus_InvalidArgument;
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Check validity of input arguments.
+ *
+ * This function checks the validity of input arguments.
+ *
+ * @param base SHA peripheral base address.
+ * @param ctx Memory buffer given by user application where the SHA_Init/SHA_Update/SHA_Finish store context.
+ * @param algo Tested algorithm value.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t sha_check_input_args(SHA_Type *base, sha_ctx_t *ctx, sha_algo_t algo)
+{
+    /* Check validity of input algorithm */
+    if (kStatus_Success != sha_check_input_alg(algo))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    if ((NULL == ctx) || (NULL == base))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Check validity of internal software context.
+ *
+ * This function checks if the internal context structure looks correct.
+ *
+ * @param ctxInternal Internal context.
+ * @param message Input message address.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t sha_check_context(sha_ctx_internal_t *ctxInternal, const uint8_t *message)
+{
+    if ((NULL == message) || (NULL == ctxInternal) || (kStatus_Success != sha_check_input_alg(ctxInternal->algo)))
+    {
+        return kStatus_InvalidArgument;
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Initialize the SHA engine for new hash.
+ *
+ * This function sets NEW and MODE fields in SHA Control register to start new hash.
+ *
+ * @param base SHA peripheral base address.
+ * @param ctxInternal Internal context.
+ */
+static void sha_engine_init(SHA_Type *base, sha_ctx_internal_t *ctxInternal)
+{
+    uint32_t shaCtrl;
+
+    if (kSHA_Sha1 == ctxInternal->algo)
+    {
+        shaCtrl = SHA_CTRL_MODE(1) | SHA_CTRL_NEW(1);
+    }
+    else
+    {
+        shaCtrl = SHA_CTRL_MODE(2) | SHA_CTRL_NEW(1);
+    }
+    base->CTRL = shaCtrl;
+}
+
+/*!
+ * @brief Load 512-bit block (16 words) into SHA engine.
+ *
+ * This function aligns the input block and moves it into SHA engine INDATA.
+ * CPU polls the WAITING bit and then moves data by using LDM and STM instructions.
+ *
+ * @param base SHA peripheral base address.
+ * @param blk 512-bit block
+ */
+static void sha_one_block(SHA_Type *base, const uint8_t *blk)
+{
+    uint32_t temp[SHA_BLOCK_SIZE / sizeof(uint32_t)];
+    const uint32_t *actBlk;
+
+    /* make sure the 512-bit block is word aligned */
+    if ((uintptr_t)blk & 0x3u)
+    {
+        sha_memcpy(temp, blk, SHA_BLOCK_SIZE);
+        actBlk = (const uint32_t *)(uintptr_t)temp;
+    }
+    else
+    {
+        actBlk = (const uint32_t *)(uintptr_t)blk;
+    }
+
+    /* poll waiting. */
+    while (0 == (base->STATUS & SHA_STATUS_WAITING_MASK))
+    {
+    }
+/* feed INDATA (and ALIASes). use STM instruction. */
+#if defined(SHA_ALIAS_DATA_MASK)
+    sha_ldm_stm_16_words(base, actBlk);
+#else
+    sha_ldm_stm_16_words(&base->INDATA[0], actBlk);
+#endif
+}
+
+/*!
+ * @brief Adds message to current hash.
+ *
+ * This function merges the message to fill the internal buffer, empties the internal buffer if
+ * it becomes full, then process all remaining message data.
+ *
+ *
+ * @param base SHA peripheral base address.
+ * @param ctxInternal Internal context.
+ * @param message Input message.
+ * @param messageSize Size of input message in bytes.
+ * @return kStatus_Success.
+ */
+static status_t sha_process_message_data(SHA_Type *base,
+                                         sha_ctx_internal_t *ctxInternal,
+                                         const uint8_t *message,
+                                         size_t messageSize)
+{
+    /* first fill the internal buffer to full block */
+    size_t toCopy = SHA_BLOCK_SIZE - ctxInternal->blksz;
+    sha_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
+    message += toCopy;
+    messageSize -= toCopy;
+
+    /* process full internal block */
+    sha_one_block(base, &ctxInternal->blk.b[0]);
+
+    /* process all full blocks in message[] */
+    while (messageSize >= SHA_BLOCK_SIZE)
+    {
+        sha_one_block(base, message);
+        message += SHA_BLOCK_SIZE;
+        messageSize -= SHA_BLOCK_SIZE;
+    }
+
+    /* copy last incomplete message bytes into internal block */
+    sha_memcpy(&ctxInternal->blk.b[0], message, messageSize);
+    ctxInternal->blksz = messageSize;
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Finalize the running hash to make digest.
+ *
+ * This function empties the internal buffer, adds padding bits, and generates final digest.
+ *
+ * @param base SHA peripheral base address.
+ * @param ctxInternal Internal context.
+ * @return kStatus_Success.
+ */
+static status_t sha_finalize(SHA_Type *base, sha_ctx_internal_t *ctxInternal)
+{
+    sha_block_t lastBlock;
+
+    memset(&lastBlock, 0, sizeof(sha_block_t));
+
+    /* this is last call, so need to flush buffered message bytes along with padding */
+    if (ctxInternal->blksz <= 55u)
+    {
+        /* last data is 440 bits or less. */
+        sha_memcpy(&lastBlock.b[0], &ctxInternal->blk.b[0], ctxInternal->blksz);
+        lastBlock.b[ctxInternal->blksz]     = (uint8_t)0x80U;
+        lastBlock.w[SHA_BLOCK_SIZE / 4 - 1] = swap_bytes(8u * ctxInternal->fullMessageSize);
+        sha_one_block(base, &lastBlock.b[0]);
+    }
+    else
+    {
+        if (ctxInternal->blksz < SHA_BLOCK_SIZE)
+        {
+            ctxInternal->blk.b[ctxInternal->blksz] = (uint8_t)0x80U;
+            for (uint32_t i = ctxInternal->blksz + 1u; i < SHA_BLOCK_SIZE; i++)
+            {
+                ctxInternal->blk.b[i] = 0;
+            }
+        }
+        else
+        {
+            lastBlock.b[0] = (uint8_t)0x80U;
+        }
+
+        sha_one_block(base, &ctxInternal->blk.b[0]);
+        lastBlock.w[SHA_BLOCK_SIZE / 4 - 1] = swap_bytes(8u * ctxInternal->fullMessageSize);
+        sha_one_block(base, &lastBlock.b[0]);
+    }
+    /* poll wait for final digest */
+    while (0 == (base->STATUS & SHA_STATUS_DIGEST_MASK))
+    {
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Read DIGEST registers.
+ *
+ * This function copies DIGEST to output buffer.
+ *
+ * @param base SHA peripheral base address.
+ * @param[out] output Output buffer.
+ * @param Number of bytes to copy.
+ * @return kStatus_Success.
+ */
+static void sha_get_digest(SHA_Type *base, uint8_t *output, size_t outputSize)
+{
+    uint32_t digest[8];
+
+    for (int i = 0; i < 8; i++)
+    {
+        digest[i] = swap_bytes(base->DIGEST[i]);
+    }
+
+    if (outputSize > sizeof(digest))
+    {
+        outputSize = sizeof(digest);
+    }
+    sha_memcpy(output, digest, outputSize);
+}
+
+/*!
+ * brief Initialize HASH context
+ *
+ * This function initializes new hash context.
+ *
+ * param base SHA peripheral base address
+ * param[out] ctx Output hash context
+ * param algo Underlaying algorithm to use for hash computation. Either SHA-1 or SHA-256.
+ * return Status of initialization
+ */
+status_t SHA_Init(SHA_Type *base, sha_ctx_t *ctx, sha_algo_t algo)
+{
+    status_t status;
+
+    sha_ctx_internal_t *ctxInternal;
+    /* compile time check for the correct structure size */
+    BUILD_ASSERT(sizeof(sha_ctx_t) >= sizeof(sha_ctx_internal_t), sha_ctx_t_size);
+    uint32_t i;
+
+    status = sha_check_input_args(base, ctx, algo);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /* set algorithm in context struct for later use */
+    ctxInternal        = (sha_ctx_internal_t *)ctx;
+    ctxInternal->algo  = algo;
+    ctxInternal->blksz = 0u;
+    for (i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++)
+    {
+        ctxInternal->blk.w[0] = 0u;
+    }
+    ctxInternal->state           = kSHA_HashInit;
+    ctxInternal->fullMessageSize = 0;
+    return status;
+}
+
+/*!
+ * brief Add data to current HASH
+ *
+ * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
+ * hashed.
+ *
+ * param base SHA peripheral base address
+ * param[in,out] ctx HASH context
+ * param message Input message
+ * param messageSize Size of input message in bytes
+ * return Status of the hash update operation
+ */
+status_t SHA_Update(SHA_Type *base, sha_ctx_t *ctx, const uint8_t *message, size_t messageSize)
+{
+    bool isUpdateState;
+    status_t status;
+    sha_ctx_internal_t *ctxInternal;
+    size_t blockSize;
+
+    if (messageSize == 0)
+    {
+        return kStatus_Success;
+    }
+
+    ctxInternal = (sha_ctx_internal_t *)ctx;
+    status      = sha_check_context(ctxInternal, message);
+    if (kStatus_Success != status)
+    {
+        return status;
+    }
+
+    ctxInternal->fullMessageSize += messageSize;
+    blockSize = SHA_BLOCK_SIZE;
+    /* if we are still less than 64 bytes, keep only in context */
+    if ((ctxInternal->blksz + messageSize) <= blockSize)
+    {
+        sha_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, message, messageSize);
+        ctxInternal->blksz += messageSize;
+        return status;
+    }
+    else
+    {
+        isUpdateState = ctxInternal->state == kSHA_HashUpdate;
+        if (!isUpdateState)
+        {
+            /* start NEW hash */
+            sha_engine_init(base, ctxInternal);
+            ctxInternal->state = kSHA_HashUpdate;
+        }
+    }
+
+    /* process message data */
+    status = sha_process_message_data(base, ctxInternal, message, messageSize);
+    return status;
+}
+
+/*!
+ * brief Finalize hashing
+ *
+ * Outputs the final hash and erases the context. SHA-1 or SHA-256 padding bits are automatically added by this
+ * function.
+ *
+ * param base SHA peripheral base address
+ * param[in,out] ctx HASH context
+ * param[out] output Output hash data
+ * param[in,out] outputSize On input, determines the size of bytes of the output array. On output, tells how many bytes
+ * have been written to output.
+ * return Status of the hash finish operation
+ */
+status_t SHA_Finish(SHA_Type *base, sha_ctx_t *ctx, uint8_t *output, size_t *outputSize)
+{
+    size_t algOutSize = 0;
+    status_t status;
+    sha_ctx_internal_t *ctxInternal;
+    uint32_t *ctxW;
+    uint32_t i;
+
+    ctxInternal = (sha_ctx_internal_t *)ctx;
+    status      = sha_check_context(ctxInternal, output);
+    if (kStatus_Success != status)
+    {
+        return status;
+    }
+
+    if (ctxInternal->state == kSHA_HashInit)
+    {
+        sha_engine_init(base, ctxInternal);
+    }
+
+    size_t outSize = 0u;
+
+    /* compute algorithm output length */
+    switch (ctxInternal->algo)
+    {
+        case kSHA_Sha1:
+            outSize = kSHA_OutLenSha1;
+            break;
+        case kSHA_Sha256:
+            outSize = kSHA_OutLenSha256;
+            break;
+        default:
+            break;
+    }
+    algOutSize = outSize;
+
+    /* flush message last incomplete block, if there is any, and add padding bits */
+    status = sha_finalize(base, ctxInternal);
+
+    if (outputSize)
+    {
+        if (algOutSize < *outputSize)
+        {
+            *outputSize = algOutSize;
+        }
+        else
+        {
+            algOutSize = *outputSize;
+        }
+    }
+
+    sha_get_digest(base, &output[0], algOutSize);
+
+    ctxW = (uint32_t *)ctx;
+    for (i = 0; i < SHA_CTX_SIZE; i++)
+    {
+        ctxW[i] = 0u;
+    }
+    return status;
+}
+
+void SHA_ClkInit(SHA_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* ungate clock */
+    CLOCK_EnableClock(kCLOCK_Sha0);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+void SHA_ClkDeinit(SHA_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* gate clock */
+    CLOCK_DisableClock(kCLOCK_Sha0);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_sha.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_sha.h
new file mode 100755
index 0000000..7ea3462
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_sha.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_SHA_H_
+#define _FSL_SHA_H_
+
+#include "fsl_common.h"
+/*!
+ * @addtogroup sha
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief Defines LPC SHA driver version 2.1.0. */
+#define FSL_SHA_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
+/*@}*/
+
+/*! Supported cryptographic block cipher functions for HASH creation */
+typedef enum _sha_algo_t
+{
+    kSHA_Sha1,   /*!< SHA_1 */
+    kSHA_Sha256, /*!< SHA_256  */
+} sha_algo_t;
+
+/*! @brief SHA Context size. */
+#define SHA_CTX_SIZE 20
+
+/*! @brief Storage type used to save hash context. */
+typedef struct _sha_ctx_t
+{
+    uint32_t x[SHA_CTX_SIZE];
+} sha_ctx_t;
+
+/*******************************************************************************
+ * API
+ *******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @name SHA Functional Operation
+ * @{
+ */
+
+/*!
+ * @addtogroup sha_algorithm_level_api
+ * @{
+ */
+/*!
+ * @brief Initialize HASH context
+ *
+ * This function initializes new hash context.
+ *
+ * @param base SHA peripheral base address
+ * @param[out] ctx Output hash context
+ * @param algo Underlaying algorithm to use for hash computation. Either SHA-1 or SHA-256.
+ * @return Status of initialization
+ */
+status_t SHA_Init(SHA_Type *base, sha_ctx_t *ctx, sha_algo_t algo);
+
+/*!
+ * @brief Add data to current HASH
+ *
+ * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
+ * hashed.
+ *
+ * @param base SHA peripheral base address
+ * @param[in,out] ctx HASH context
+ * @param message Input message
+ * @param messageSize Size of input message in bytes
+ * @return Status of the hash update operation
+ */
+status_t SHA_Update(SHA_Type *base, sha_ctx_t *ctx, const uint8_t *message, size_t messageSize);
+
+/*!
+ * @brief Finalize hashing
+ *
+ * Outputs the final hash and erases the context. SHA-1 or SHA-256 padding bits are automatically added by this
+ * function.
+ *
+ * @param base SHA peripheral base address
+ * @param[in,out] ctx HASH context
+ * @param[out] output Output hash data
+ * @param[in,out] outputSize On input, determines the size of bytes of the output array. On output, tells how many bytes
+ * have been written to output.
+ * @return Status of the hash finish operation
+ */
+status_t SHA_Finish(SHA_Type *base, sha_ctx_t *ctx, uint8_t *output, size_t *outputSize);
+/*!
+ * @brief Start SHA clock
+ *
+ * Start SHA clock
+ *
+ * @param base SHA peripheral base address
+ *
+ */
+void SHA_ClkInit(SHA_Type *base);
+
+/*!
+ * @brief Stop SHA clock
+ *
+ * Stop SHA clock
+ *
+ * @param base SHA peripheral base address
+ *
+ */
+void SHA_ClkDeinit(SHA_Type *base);
+
+/*!
+ *@}
+ */ /* sha_algorithm_level_api */
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @}*/
+/*! @}*/ /* end of group sha */
+
+#endif /* _FSL_SHA_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_usart.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_usart.c
new file mode 100755
index 0000000..998fdb8
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_usart.c
@@ -0,0 +1,939 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_usart.h"
+#include "fsl_device_registers.h"
+#include "fsl_flexcomm.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.flexcomm_usart"
+#endif
+
+enum _usart_transfer_states
+{
+    kUSART_TxIdle, /* TX idle. */
+    kUSART_TxBusy, /* TX busy. */
+    kUSART_RxIdle, /* RX idle. */
+    kUSART_RxBusy  /* RX busy. */
+};
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief IRQ name array */
+static const IRQn_Type s_usartIRQ[] = USART_IRQS;
+
+/*! @brief Array to map USART instance number to base address. */
+static const uint32_t s_usartBaseAddrs[FSL_FEATURE_SOC_USART_COUNT] = USART_BASE_ADDRS;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/* Get the index corresponding to the USART */
+/*! brief Returns instance number for USART peripheral base address. */
+uint32_t USART_GetInstance(USART_Type *base)
+{
+    int i;
+
+    for (i = 0; i < FSL_FEATURE_SOC_USART_COUNT; i++)
+    {
+        if ((uint32_t)base == s_usartBaseAddrs[i])
+        {
+            return i;
+        }
+    }
+
+    assert(false);
+    return 0;
+}
+
+/*!
+ * brief Get the length of received data in RX ring buffer.
+ *
+ * param handle USART handle pointer.
+ * return Length of received data in RX ring buffer.
+ */
+size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle)
+{
+    size_t size;
+
+    /* Check arguments */
+    assert(NULL != handle);
+
+    if (handle->rxRingBufferTail > handle->rxRingBufferHead)
+    {
+        size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail);
+    }
+    else
+    {
+        size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail);
+    }
+    return size;
+}
+
+static bool USART_TransferIsRxRingBufferFull(usart_handle_t *handle)
+{
+    bool full;
+
+    /* Check arguments */
+    assert(NULL != handle);
+
+    if (USART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U))
+    {
+        full = true;
+    }
+    else
+    {
+        full = false;
+    }
+    return full;
+}
+
+/*!
+ * brief Sets up the RX ring buffer.
+ *
+ * This function sets up the RX ring buffer to a specific USART handle.
+ *
+ * When the RX ring buffer is used, data received are stored into the ring buffer even when the
+ * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received
+ * in the ring buffer, the user can get the received data from the ring buffer directly.
+ *
+ * note When using the RX ring buffer, one byte is reserved for internal use. In other
+ * words, if p ringBufferSize is 32, then only 31 bytes are used for saving data.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
+ * param ringBufferSize size of the ring buffer.
+ */
+void USART_TransferStartRingBuffer(USART_Type *base, usart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize)
+{
+    /* Check arguments */
+    assert(NULL != base);
+    assert(NULL != handle);
+    assert(NULL != ringBuffer);
+
+    /* Setup the ringbuffer address */
+    handle->rxRingBuffer     = ringBuffer;
+    handle->rxRingBufferSize = ringBufferSize;
+    handle->rxRingBufferHead = 0U;
+    handle->rxRingBufferTail = 0U;
+    /* ring buffer is ready we can start receiving data */
+    base->FIFOINTENSET |= USART_FIFOINTENSET_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK;
+}
+
+/*!
+ * brief Aborts the background transfer and uninstalls the ring buffer.
+ *
+ * This function aborts the background transfer and uninstalls the ring buffer.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle)
+{
+    /* Check arguments */
+    assert(NULL != base);
+    assert(NULL != handle);
+
+    if (handle->rxState == kUSART_RxIdle)
+    {
+        base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK;
+    }
+    handle->rxRingBuffer     = NULL;
+    handle->rxRingBufferSize = 0U;
+    handle->rxRingBufferHead = 0U;
+    handle->rxRingBufferTail = 0U;
+}
+
+/*!
+ * brief Initializes a USART instance with user configuration structure and peripheral clock.
+ *
+ * This function configures the USART module with the user-defined settings. The user can configure the configuration
+ * structure and also get the default configuration by using the USART_GetDefaultConfig() function.
+ * Example below shows how to use this API to configure USART.
+ * code
+ *  usart_config_t usartConfig;
+ *  usartConfig.baudRate_Bps = 115200U;
+ *  usartConfig.parityMode = kUSART_ParityDisabled;
+ *  usartConfig.stopBitCount = kUSART_OneStopBit;
+ *  USART_Init(USART1, &usartConfig, 20000000U);
+ * endcode
+ *
+ * param base USART peripheral base address.
+ * param config Pointer to user-defined configuration structure.
+ * param srcClock_Hz USART clock source frequency in HZ.
+ * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * retval kStatus_InvalidArgument USART base address is not valid
+ * retval kStatus_Success Status USART initialize succeed
+ */
+status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz)
+{
+    int result;
+
+    /* check arguments */
+    assert(!((NULL == base) || (NULL == config) || (0 == srcClock_Hz)));
+    if ((NULL == base) || (NULL == config) || (0 == srcClock_Hz))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* initialize flexcomm to USART mode */
+    result = FLEXCOMM_Init(base, FLEXCOMM_PERIPH_USART);
+    if (kStatus_Success != result)
+    {
+        return result;
+    }
+
+    if (config->enableTx)
+    {
+        /* empty and enable txFIFO */
+        base->FIFOCFG |= USART_FIFOCFG_EMPTYTX_MASK | USART_FIFOCFG_ENABLETX_MASK;
+        /* setup trigger level */
+        base->FIFOTRIG &= ~(USART_FIFOTRIG_TXLVL_MASK);
+        base->FIFOTRIG |= USART_FIFOTRIG_TXLVL(config->txWatermark);
+        /* enable trigger interrupt */
+        base->FIFOTRIG |= USART_FIFOTRIG_TXLVLENA_MASK;
+    }
+
+    /* empty and enable rxFIFO */
+    if (config->enableRx)
+    {
+        base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK | USART_FIFOCFG_ENABLERX_MASK;
+        /* setup trigger level */
+        base->FIFOTRIG &= ~(USART_FIFOTRIG_RXLVL_MASK);
+        base->FIFOTRIG |= USART_FIFOTRIG_RXLVL(config->rxWatermark);
+        /* enable trigger interrupt */
+        base->FIFOTRIG |= USART_FIFOTRIG_RXLVLENA_MASK;
+    }
+    /* setup configuration and enable USART */
+    base->CFG = USART_CFG_PARITYSEL(config->parityMode) | USART_CFG_STOPLEN(config->stopBitCount) |
+                USART_CFG_DATALEN(config->bitCountPerChar) | USART_CFG_LOOP(config->loopback) |
+                USART_CFG_SYNCEN(config->syncMode >> 1) | USART_CFG_SYNCMST(config->syncMode) |
+                USART_CFG_CLKPOL(config->clockPolarity) | USART_CFG_ENABLE_MASK;
+
+    /* Setup baudrate */
+    result = USART_SetBaudRate(base, config->baudRate_Bps, srcClock_Hz);
+    if (kStatus_Success != result)
+    {
+        return result;
+    }
+    /* Setting continuous Clock configuration. used for synchronous mode. */
+    USART_EnableContinuousSCLK(base, config->enableContinuousSCLK);
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Deinitializes a USART instance.
+ *
+ * This function waits for TX complete, disables TX and RX, and disables the USART clock.
+ *
+ * param base USART peripheral base address.
+ */
+void USART_Deinit(USART_Type *base)
+{
+    /* Check arguments */
+    assert(NULL != base);
+    while (!(base->STAT & USART_STAT_TXIDLE_MASK))
+    {
+    }
+    /* Disable interrupts, disable dma requests, disable peripheral */
+    base->FIFOINTENCLR = USART_FIFOINTENCLR_TXERR_MASK | USART_FIFOINTENCLR_RXERR_MASK | USART_FIFOINTENCLR_TXLVL_MASK |
+                         USART_FIFOINTENCLR_RXLVL_MASK;
+    base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK | USART_FIFOCFG_DMARX_MASK);
+    base->CFG &= ~(USART_CFG_ENABLE_MASK);
+}
+
+/*!
+ * brief Gets the default configuration structure.
+ *
+ * This function initializes the USART configuration structure to a default value. The default
+ * values are:
+ *   usartConfig->baudRate_Bps = 115200U;
+ *   usartConfig->parityMode = kUSART_ParityDisabled;
+ *   usartConfig->stopBitCount = kUSART_OneStopBit;
+ *   usartConfig->bitCountPerChar = kUSART_8BitsPerChar;
+ *   usartConfig->loopback = false;
+ *   usartConfig->enableTx = false;
+ *   usartConfig->enableRx = false;
+ *
+ * param config Pointer to configuration structure.
+ */
+void USART_GetDefaultConfig(usart_config_t *config)
+{
+    /* Check arguments */
+    assert(NULL != config);
+
+    /* Initializes the configure structure to zero. */
+    memset(config, 0, sizeof(*config));
+
+    /* Set always all members ! */
+    config->baudRate_Bps         = 115200U;
+    config->parityMode           = kUSART_ParityDisabled;
+    config->stopBitCount         = kUSART_OneStopBit;
+    config->bitCountPerChar      = kUSART_8BitsPerChar;
+    config->loopback             = false;
+    config->enableRx             = false;
+    config->enableTx             = false;
+    config->txWatermark          = kUSART_TxFifo0;
+    config->rxWatermark          = kUSART_RxFifo1;
+    config->syncMode             = kUSART_SyncModeDisabled;
+    config->enableContinuousSCLK = false;
+    config->clockPolarity        = kUSART_RxSampleOnFallingEdge;
+}
+
+/*!
+ * brief Sets the USART instance baud rate.
+ *
+ * This function configures the USART module baud rate. This function is used to update
+ * the USART module baud rate after the USART module is initialized by the USART_Init.
+ * code
+ *  USART_SetBaudRate(USART1, 115200U, 20000000U);
+ * endcode
+ *
+ * param base USART peripheral base address.
+ * param baudrate_Bps USART baudrate to be set.
+ * param srcClock_Hz USART clock source frequency in HZ.
+ * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * retval kStatus_Success Set baudrate succeed.
+ * retval kStatus_InvalidArgument One or more arguments are invalid.
+ */
+status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz)
+{
+    uint32_t best_diff = (uint32_t)-1, best_osrval = 0xf, best_brgval = (uint32_t)-1;
+    uint32_t osrval, brgval, diff, baudrate;
+
+    /* check arguments */
+    assert(!((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz)));
+    if ((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* If synchronous master mode is enabled, only configure the BRG value. */
+    if (base->CFG & USART_CFG_SYNCEN_MASK)
+    {
+        if (base->CFG & USART_CFG_SYNCMST_MASK)
+        {
+            brgval    = srcClock_Hz / baudrate_Bps;
+            base->BRG = brgval - 1;
+        }
+    }
+    else
+    {
+        /*
+         * Smaller values of OSR can make the sampling position within a data bit less accurate and may
+         * potentially cause more noise errors or incorrect data.
+         */
+        for (osrval = best_osrval; osrval >= 8; osrval--)
+        {
+            brgval = (((srcClock_Hz * 10) / ((osrval + 1) * baudrate_Bps)) - 5) / 10;
+            if (brgval > 0xFFFF)
+            {
+                continue;
+            }
+            baudrate = srcClock_Hz / ((osrval + 1) * (brgval + 1));
+            diff     = baudrate_Bps < baudrate ? baudrate - baudrate_Bps : baudrate_Bps - baudrate;
+            if (diff < best_diff)
+            {
+                best_diff   = diff;
+                best_osrval = osrval;
+                best_brgval = brgval;
+            }
+        }
+
+        /* value over range */
+        if (best_brgval > 0xFFFF)
+        {
+            return kStatus_USART_BaudrateNotSupport;
+        }
+
+        base->OSR = best_osrval;
+        base->BRG = best_brgval;
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Writes to the TX register using a blocking method.
+ *
+ * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
+ * to have room and writes data to the TX buffer.
+ *
+ * param base USART peripheral base address.
+ * param data Start address of the data to write.
+ * param length Size of the data to write.
+ */
+void USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length)
+{
+    /* Check arguments */
+    assert(!((NULL == base) || (NULL == data)));
+    if ((NULL == base) || (NULL == data))
+    {
+        return;
+    }
+    /* Check whether txFIFO is enabled */
+    if (!(base->FIFOCFG & USART_FIFOCFG_ENABLETX_MASK))
+    {
+        return;
+    }
+    for (; length > 0; length--)
+    {
+        /* Loop until txFIFO get some space for new data */
+        while (!(base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK))
+        {
+        }
+        base->FIFOWR = *data;
+        data++;
+    }
+    /* Wait to finish transfer */
+    while (!(base->STAT & USART_STAT_TXIDLE_MASK))
+    {
+    }
+}
+
+/*!
+ * brief Read RX data register using a blocking method.
+ *
+ * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
+ * have data and read data from the TX register.
+ *
+ * param base USART peripheral base address.
+ * param data Start address of the buffer to store the received data.
+ * param length Size of the buffer.
+ * retval kStatus_USART_FramingError Receiver overrun happened while receiving data.
+ * retval kStatus_USART_ParityError Noise error happened while receiving data.
+ * retval kStatus_USART_NoiseError Framing error happened while receiving data.
+ * retval kStatus_USART_RxError Overflow or underflow rxFIFO happened.
+ * retval kStatus_Success Successfully received all data.
+ */
+status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length)
+{
+    uint32_t status;
+
+    /* check arguments */
+    assert(!((NULL == base) || (NULL == data)));
+    if ((NULL == base) || (NULL == data))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Check whether rxFIFO is enabled */
+    if (!(base->FIFOCFG & USART_FIFOCFG_ENABLERX_MASK))
+    {
+        return kStatus_Fail;
+    }
+    for (; length > 0; length--)
+    {
+        /* loop until rxFIFO have some data to read */
+        while (!(base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK))
+        {
+        }
+        /* check receive status */
+        status = base->STAT;
+        if (status & USART_STAT_FRAMERRINT_MASK)
+        {
+            base->STAT |= USART_STAT_FRAMERRINT_MASK;
+            return kStatus_USART_FramingError;
+        }
+        if (status & USART_STAT_PARITYERRINT_MASK)
+        {
+            base->STAT |= USART_STAT_PARITYERRINT_MASK;
+            return kStatus_USART_ParityError;
+        }
+        if (status & USART_STAT_RXNOISEINT_MASK)
+        {
+            base->STAT |= USART_STAT_RXNOISEINT_MASK;
+            return kStatus_USART_NoiseError;
+        }
+        /* check rxFIFO status */
+        if (base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK)
+        {
+            base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+            base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
+            return kStatus_USART_RxError;
+        }
+
+        *data = base->FIFORD;
+        data++;
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * brief Initializes the USART handle.
+ *
+ * This function initializes the USART handle which can be used for other USART
+ * transactional APIs. Usually, for a specified USART instance,
+ * call this API once to get the initialized handle.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param callback The callback function.
+ * param userData The parameter of the callback function.
+ */
+status_t USART_TransferCreateHandle(USART_Type *base,
+                                    usart_handle_t *handle,
+                                    usart_transfer_callback_t callback,
+                                    void *userData)
+{
+    int32_t instance = 0;
+
+    /* Check 'base' */
+    assert(!((NULL == base) || (NULL == handle)));
+    if ((NULL == base) || (NULL == handle))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    instance = USART_GetInstance(base);
+
+    memset(handle, 0, sizeof(*handle));
+    /* Set the TX/RX state. */
+    handle->rxState = kUSART_RxIdle;
+    handle->txState = kUSART_TxIdle;
+    /* Set the callback and user data. */
+    handle->callback    = callback;
+    handle->userData    = userData;
+    handle->rxWatermark = (usart_rxfifo_watermark_t)USART_FIFOTRIG_RXLVL_GET(base);
+    handle->txWatermark = (usart_txfifo_watermark_t)USART_FIFOTRIG_TXLVL_GET(base);
+
+    FLEXCOMM_SetIRQHandler(base, (flexcomm_irq_handler_t)USART_TransferHandleIRQ, handle);
+
+    /* Enable interrupt in NVIC. */
+    EnableIRQ(s_usartIRQ[instance]);
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the IRQ handler, the USART driver calls the callback
+ * function and passes the ref kStatus_USART_TxIdle as status parameter.
+ *
+ * note The kStatus_USART_TxIdle is passed to the upper layer when all data is written
+ * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX,
+ * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param xfer USART transfer structure. See  #usart_transfer_t.
+ * retval kStatus_Success Successfully start the data transmission.
+ * retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
+ * retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer)
+{
+    /* Check arguments */
+    assert(!((NULL == base) || (NULL == handle) || (NULL == xfer)));
+    if ((NULL == base) || (NULL == handle) || (NULL == xfer))
+    {
+        return kStatus_InvalidArgument;
+    }
+    /* Check xfer members */
+    assert(!((0 == xfer->dataSize) || (NULL == xfer->data)));
+    if ((0 == xfer->dataSize) || (NULL == xfer->data))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Return error if current TX busy. */
+    if (kUSART_TxBusy == handle->txState)
+    {
+        return kStatus_USART_TxBusy;
+    }
+    else
+    {
+        handle->txData        = xfer->data;
+        handle->txDataSize    = xfer->dataSize;
+        handle->txDataSizeAll = xfer->dataSize;
+        handle->txState       = kUSART_TxBusy;
+        /* Enable transmiter interrupt. */
+        base->FIFOINTENSET |= USART_FIFOINTENSET_TXLVL_MASK;
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * brief Aborts the interrupt-driven data transmit.
+ *
+ * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
+ * how many bytes are still not sent out.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle)
+{
+    assert(NULL != handle);
+
+    /* Disable interrupts */
+    USART_DisableInterrupts(base, kUSART_TxLevelInterruptEnable);
+    /* Empty txFIFO */
+    base->FIFOCFG |= USART_FIFOCFG_EMPTYTX_MASK;
+
+    handle->txDataSize = 0;
+    handle->txState    = kUSART_TxIdle;
+}
+
+/*!
+ * brief Get the number of bytes that have been written to USART TX register.
+ *
+ * This function gets the number of bytes that have been written to USART TX
+ * register by interrupt method.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param count Send bytes count.
+ * retval kStatus_NoTransferInProgress No send in progress.
+ * retval kStatus_InvalidArgument Parameter is invalid.
+ * retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count)
+{
+    assert(NULL != handle);
+    assert(NULL != count);
+
+    if (kUSART_TxIdle == handle->txState)
+    {
+        return kStatus_NoTransferInProgress;
+    }
+
+    *count = handle->txDataSizeAll - handle->txDataSize;
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ *  returns without waiting for all data to be received.
+ * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
+ * the parameter p receivedBytes shows how many bytes are copied from the ring buffer.
+ * After copying, if the data in the ring buffer is not enough to read, the receive
+ * request is saved by the USART driver. When the new data arrives, the receive request
+ * is serviced first. When all data is received, the USART driver notifies the upper layer
+ * through a callback function and passes the status parameter ref kStatus_USART_RxIdle.
+ * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
+ * The 5 bytes are copied to the xfer->data and this function returns with the
+ * parameter p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
+ * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer.
+ * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
+ * to receive data to the xfer->data. When all data is received, the upper layer is notified.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param xfer USART transfer structure, see #usart_transfer_t.
+ * param receivedBytes Bytes received from the ring buffer directly.
+ * retval kStatus_Success Successfully queue the transfer into transmit queue.
+ * retval kStatus_USART_RxBusy Previous receive request is not finished.
+ * retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferReceiveNonBlocking(USART_Type *base,
+                                          usart_handle_t *handle,
+                                          usart_transfer_t *xfer,
+                                          size_t *receivedBytes)
+{
+    uint32_t i;
+    /* How many bytes to copy from ring buffer to user memory. */
+    size_t bytesToCopy = 0U;
+    /* How many bytes to receive. */
+    size_t bytesToReceive;
+    /* How many bytes currently have received. */
+    size_t bytesCurrentReceived;
+    uint32_t regPrimask = 0U;
+
+    /* Check arguments */
+    assert(!((NULL == base) || (NULL == handle) || (NULL == xfer)));
+    if ((NULL == base) || (NULL == handle) || (NULL == xfer))
+    {
+        return kStatus_InvalidArgument;
+    }
+    /* Check xfer members */
+    assert(!((0 == xfer->dataSize) || (NULL == xfer->data)));
+    if ((0 == xfer->dataSize) || (NULL == xfer->data))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* How to get data:
+       1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
+          to uart handle, enable interrupt to store received data to xfer->data. When
+          all data received, trigger callback.
+       2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
+          If there are enough data in ring buffer, copy them to xfer->data and return.
+          If there are not enough data in ring buffer, copy all of them to xfer->data,
+          save the xfer->data remained empty space to uart handle, receive data
+          to this empty space and trigger callback when finished. */
+    if (kUSART_RxBusy == handle->rxState)
+    {
+        return kStatus_USART_RxBusy;
+    }
+    else
+    {
+        bytesToReceive       = xfer->dataSize;
+        bytesCurrentReceived = 0U;
+        /* If RX ring buffer is used. */
+        if (handle->rxRingBuffer)
+        {
+            /* Disable IRQ, protect ring buffer. */
+            regPrimask = DisableGlobalIRQ();
+            /* How many bytes in RX ring buffer currently. */
+            bytesToCopy = USART_TransferGetRxRingBufferLength(handle);
+            if (bytesToCopy)
+            {
+                bytesToCopy = MIN(bytesToReceive, bytesToCopy);
+                bytesToReceive -= bytesToCopy;
+                /* Copy data from ring buffer to user memory. */
+                for (i = 0U; i < bytesToCopy; i++)
+                {
+                    xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
+                    /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
+                    if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
+                    {
+                        handle->rxRingBufferTail = 0U;
+                    }
+                    else
+                    {
+                        handle->rxRingBufferTail++;
+                    }
+                }
+            }
+            /* If ring buffer does not have enough data, still need to read more data. */
+            if (bytesToReceive)
+            {
+                /* No data in ring buffer, save the request to UART handle. */
+                handle->rxData        = xfer->data + bytesCurrentReceived;
+                handle->rxDataSize    = bytesToReceive;
+                handle->rxDataSizeAll = bytesToReceive;
+                handle->rxState       = kUSART_RxBusy;
+            }
+            /* Enable IRQ if previously enabled. */
+            EnableGlobalIRQ(regPrimask);
+            /* Call user callback since all data are received. */
+            if (0 == bytesToReceive)
+            {
+                if (handle->callback)
+                {
+                    handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData);
+                }
+            }
+        }
+        /* Ring buffer not used. */
+        else
+        {
+            handle->rxData        = xfer->data + bytesCurrentReceived;
+            handle->rxDataSize    = bytesToReceive;
+            handle->rxDataSizeAll = bytesToReceive;
+            handle->rxState       = kUSART_RxBusy;
+
+            /* Enable RX interrupt. */
+            base->FIFOINTENSET |= USART_FIFOINTENSET_RXLVL_MASK;
+        }
+        /* Return the how many bytes have read. */
+        if (receivedBytes)
+        {
+            *receivedBytes = bytesCurrentReceived;
+        }
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
+ * how many bytes not received yet.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle)
+{
+    assert(NULL != handle);
+
+    /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
+    if (!handle->rxRingBuffer)
+    {
+        /* Disable interrupts */
+        USART_DisableInterrupts(base, kUSART_RxLevelInterruptEnable);
+        /* Empty rxFIFO */
+        base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+    }
+
+    handle->rxDataSize = 0U;
+    handle->rxState    = kUSART_RxIdle;
+}
+
+/*!
+ * brief Get the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param count Receive bytes count.
+ * retval kStatus_NoTransferInProgress No receive in progress.
+ * retval kStatus_InvalidArgument Parameter is invalid.
+ * retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count)
+{
+    assert(NULL != handle);
+    assert(NULL != count);
+
+    if (kUSART_RxIdle == handle->rxState)
+    {
+        return kStatus_NoTransferInProgress;
+    }
+
+    *count = handle->rxDataSizeAll - handle->rxDataSize;
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief USART IRQ handle function.
+ *
+ * This function handles the USART transmit and receive IRQ request.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle)
+{
+    /* Check arguments */
+    assert((NULL != base) && (NULL != handle));
+
+    bool receiveEnabled = (handle->rxDataSize) || (handle->rxRingBuffer);
+    bool sendEnabled    = handle->txDataSize;
+
+    /* If RX overrun. */
+    if (base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK)
+    {
+        /* Clear rx error state. */
+        base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
+        /* clear rxFIFO */
+        base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+        /* Trigger callback. */
+        if (handle->callback)
+        {
+            handle->callback(base, handle, kStatus_USART_RxError, handle->userData);
+        }
+    }
+    while ((receiveEnabled && (base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK)) ||
+           (sendEnabled && (base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK)))
+    {
+        /* Receive data */
+        if (receiveEnabled && (base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK))
+        {
+            /* Receive to app bufffer if app buffer is present */
+            if (handle->rxDataSize)
+            {
+                *handle->rxData = base->FIFORD;
+                handle->rxDataSize--;
+                handle->rxData++;
+                receiveEnabled = ((handle->rxDataSize != 0) || (handle->rxRingBuffer));
+                if (!handle->rxDataSize)
+                {
+                    if (!handle->rxRingBuffer)
+                    {
+                        base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK;
+                    }
+                    handle->rxState = kUSART_RxIdle;
+                    if (handle->callback)
+                    {
+                        handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData);
+                    }
+                }
+            }
+            /* Otherwise receive to ring buffer if ring buffer is present */
+            else
+            {
+                if (handle->rxRingBuffer)
+                {
+                    /* If RX ring buffer is full, trigger callback to notify over run. */
+                    if (USART_TransferIsRxRingBufferFull(handle))
+                    {
+                        if (handle->callback)
+                        {
+                            handle->callback(base, handle, kStatus_USART_RxRingBufferOverrun, handle->userData);
+                        }
+                    }
+                    /* If ring buffer is still full after callback function, the oldest data is overridden. */
+                    if (USART_TransferIsRxRingBufferFull(handle))
+                    {
+                        /* Increase handle->rxRingBufferTail to make room for new data. */
+                        if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
+                        {
+                            handle->rxRingBufferTail = 0U;
+                        }
+                        else
+                        {
+                            handle->rxRingBufferTail++;
+                        }
+                    }
+                    /* Read data. */
+                    handle->rxRingBuffer[handle->rxRingBufferHead] = base->FIFORD;
+                    /* Increase handle->rxRingBufferHead. */
+                    if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
+                    {
+                        handle->rxRingBufferHead = 0U;
+                    }
+                    else
+                    {
+                        handle->rxRingBufferHead++;
+                    }
+                }
+            }
+        }
+        /* Send data */
+        if (sendEnabled && (base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK))
+        {
+            base->FIFOWR = *handle->txData;
+            handle->txDataSize--;
+            handle->txData++;
+            sendEnabled = handle->txDataSize != 0;
+            if (!sendEnabled)
+            {
+                base->FIFOINTENCLR = USART_FIFOINTENCLR_TXLVL_MASK;
+                handle->txState    = kUSART_TxIdle;
+                if (handle->callback)
+                {
+                    handle->callback(base, handle, kStatus_USART_TxIdle, handle->userData);
+                }
+            }
+        }
+    }
+
+    /* ring buffer is not used */
+    if (NULL == handle->rxRingBuffer)
+    {
+        /* restore if rx transfer ends and rxLevel is different from default value */
+        if ((handle->rxDataSize == 0) && (USART_FIFOTRIG_RXLVL_GET(base) != handle->rxWatermark))
+        {
+            base->FIFOTRIG =
+                (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | USART_FIFOTRIG_RXLVL(handle->rxWatermark);
+        }
+        /* decrease level if rx transfer is bellow */
+        if ((handle->rxDataSize != 0) && (handle->rxDataSize < (USART_FIFOTRIG_RXLVL_GET(base) + 1)))
+        {
+            base->FIFOTRIG =
+                (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | (USART_FIFOTRIG_RXLVL(handle->rxDataSize - 1));
+        }
+    }
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_usart.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_usart.h
new file mode 100755
index 0000000..8a6c5d4
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_usart.h
@@ -0,0 +1,718 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_USART_H_
+#define _FSL_USART_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup usart_driver
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief USART driver version 2.1.0. */
+#define FSL_USART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
+/*@}*/
+
+#define USART_FIFOTRIG_TXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_TXLVL_MASK) >> USART_FIFOTRIG_TXLVL_SHIFT)
+#define USART_FIFOTRIG_RXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_RXLVL_MASK) >> USART_FIFOTRIG_RXLVL_SHIFT)
+
+/*! @brief Error codes for the USART driver. */
+enum _usart_status
+{
+    kStatus_USART_TxBusy              = MAKE_STATUS(kStatusGroup_LPC_USART, 0),  /*!< Transmitter is busy. */
+    kStatus_USART_RxBusy              = MAKE_STATUS(kStatusGroup_LPC_USART, 1),  /*!< Receiver is busy. */
+    kStatus_USART_TxIdle              = MAKE_STATUS(kStatusGroup_LPC_USART, 2),  /*!< USART transmitter is idle. */
+    kStatus_USART_RxIdle              = MAKE_STATUS(kStatusGroup_LPC_USART, 3),  /*!< USART receiver is idle. */
+    kStatus_USART_TxError             = MAKE_STATUS(kStatusGroup_LPC_USART, 7),  /*!< Error happens on txFIFO. */
+    kStatus_USART_RxError             = MAKE_STATUS(kStatusGroup_LPC_USART, 9),  /*!< Error happens on rxFIFO. */
+    kStatus_USART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_LPC_USART, 8),  /*!< Error happens on rx ring buffer */
+    kStatus_USART_NoiseError          = MAKE_STATUS(kStatusGroup_LPC_USART, 10), /*!< USART noise error. */
+    kStatus_USART_FramingError        = MAKE_STATUS(kStatusGroup_LPC_USART, 11), /*!< USART framing error. */
+    kStatus_USART_ParityError         = MAKE_STATUS(kStatusGroup_LPC_USART, 12), /*!< USART parity error. */
+    kStatus_USART_BaudrateNotSupport =
+        MAKE_STATUS(kStatusGroup_LPC_USART, 13), /*!< Baudrate is not support in current clock source */
+};
+
+/*! @brief USART synchronous mode. */
+typedef enum _usart_sync_mode
+{
+    kUSART_SyncModeDisabled = 0x0U, /*!< Asynchronous mode.       */
+    kUSART_SyncModeSlave    = 0x2U, /*!< Synchronous slave mode.  */
+    kUSART_SyncModeMaster   = 0x3U, /*!< Synchronous master mode. */
+} usart_sync_mode_t;
+
+/*! @brief USART parity mode. */
+typedef enum _usart_parity_mode
+{
+    kUSART_ParityDisabled = 0x0U, /*!< Parity disabled */
+    kUSART_ParityEven     = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
+    kUSART_ParityOdd      = 0x3U, /*!< Parity enabled, type odd,  bit setting: PE|PT = 11 */
+} usart_parity_mode_t;
+
+/*! @brief USART stop bit count. */
+typedef enum _usart_stop_bit_count
+{
+    kUSART_OneStopBit = 0U, /*!< One stop bit */
+    kUSART_TwoStopBit = 1U, /*!< Two stop bits */
+} usart_stop_bit_count_t;
+
+/*! @brief USART data size. */
+typedef enum _usart_data_len
+{
+    kUSART_7BitsPerChar = 0U, /*!< Seven bit mode */
+    kUSART_8BitsPerChar = 1U, /*!< Eight bit mode */
+} usart_data_len_t;
+
+/*! @brief USART clock polarity configuration, used in sync mode.*/
+typedef enum _usart_clock_polarity
+{
+    kUSART_RxSampleOnFallingEdge = 0x0U, /*!< Un_RXD is sampled on the falling edge of SCLK. */
+    kUSART_RxSampleOnRisingEdge  = 0x1U, /*!< Un_RXD is sampled on the rising edge of SCLK. */
+} usart_clock_polarity_t;
+
+/*! @brief txFIFO watermark values */
+typedef enum _usart_txfifo_watermark
+{
+    kUSART_TxFifo0 = 0, /*!< USART tx watermark is empty */
+    kUSART_TxFifo1 = 1, /*!< USART tx watermark at 1 item */
+    kUSART_TxFifo2 = 2, /*!< USART tx watermark at 2 items */
+    kUSART_TxFifo3 = 3, /*!< USART tx watermark at 3 items */
+    kUSART_TxFifo4 = 4, /*!< USART tx watermark at 4 items */
+    kUSART_TxFifo5 = 5, /*!< USART tx watermark at 5 items */
+    kUSART_TxFifo6 = 6, /*!< USART tx watermark at 6 items */
+    kUSART_TxFifo7 = 7, /*!< USART tx watermark at 7 items */
+} usart_txfifo_watermark_t;
+
+/*! @brief rxFIFO watermark values */
+typedef enum _usart_rxfifo_watermark
+{
+    kUSART_RxFifo1 = 0, /*!< USART rx watermark at 1 item */
+    kUSART_RxFifo2 = 1, /*!< USART rx watermark at 2 items */
+    kUSART_RxFifo3 = 2, /*!< USART rx watermark at 3 items */
+    kUSART_RxFifo4 = 3, /*!< USART rx watermark at 4 items */
+    kUSART_RxFifo5 = 4, /*!< USART rx watermark at 5 items */
+    kUSART_RxFifo6 = 5, /*!< USART rx watermark at 6 items */
+    kUSART_RxFifo7 = 6, /*!< USART rx watermark at 7 items */
+    kUSART_RxFifo8 = 7, /*!< USART rx watermark at 8 items */
+} usart_rxfifo_watermark_t;
+
+/*!
+ * @brief USART interrupt configuration structure, default settings all disabled.
+ */
+enum _usart_interrupt_enable
+{
+    kUSART_TxErrorInterruptEnable = (USART_FIFOINTENSET_TXERR_MASK),
+    kUSART_RxErrorInterruptEnable = (USART_FIFOINTENSET_RXERR_MASK),
+    kUSART_TxLevelInterruptEnable = (USART_FIFOINTENSET_TXLVL_MASK),
+    kUSART_RxLevelInterruptEnable = (USART_FIFOINTENSET_RXLVL_MASK),
+};
+
+/*!
+ * @brief USART status flags.
+ *
+ * This provides constants for the USART status flags for use in the USART functions.
+ */
+enum _usart_flags
+{
+    kUSART_TxError            = (USART_FIFOSTAT_TXERR_MASK),      /*!< TEERR bit, sets if TX buffer is error */
+    kUSART_RxError            = (USART_FIFOSTAT_RXERR_MASK),      /*!< RXERR bit, sets if RX buffer is error */
+    kUSART_TxFifoEmptyFlag    = (USART_FIFOSTAT_TXEMPTY_MASK),    /*!< TXEMPTY bit, sets if TX buffer is empty */
+    kUSART_TxFifoNotFullFlag  = (USART_FIFOSTAT_TXNOTFULL_MASK),  /*!< TXNOTFULL bit, sets if TX buffer is not full */
+    kUSART_RxFifoNotEmptyFlag = (USART_FIFOSTAT_RXNOTEMPTY_MASK), /*!< RXNOEMPTY bit, sets if RX buffer is not empty */
+    kUSART_RxFifoFullFlag     = (USART_FIFOSTAT_RXFULL_MASK),     /*!< RXFULL bit, sets if RX buffer is full */
+};
+
+/*! @brief USART configuration structure. */
+typedef struct _usart_config
+{
+    uint32_t baudRate_Bps;                /*!< USART baud rate  */
+    usart_parity_mode_t parityMode;       /*!< Parity mode, disabled (default), even, odd */
+    usart_stop_bit_count_t stopBitCount;  /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
+    usart_data_len_t bitCountPerChar;     /*!< Data length - 7 bit, 8 bit  */
+    bool loopback;                        /*!< Enable peripheral loopback */
+    bool enableRx;                        /*!< Enable RX */
+    bool enableTx;                        /*!< Enable TX */
+    bool enableContinuousSCLK;            /*!< USART continuous Clock generation enable in synchronous master mode. */
+    usart_txfifo_watermark_t txWatermark; /*!< txFIFO watermark */
+    usart_rxfifo_watermark_t rxWatermark; /*!< rxFIFO watermark */
+    usart_sync_mode_t syncMode; /*!< Transfer mode select - asynchronous, synchronous master, synchronous slave. */
+    usart_clock_polarity_t clockPolarity; /*!< Selects the clock polarity and sampling edge in synchronous mode. */
+} usart_config_t;
+
+/*! @brief USART transfer structure. */
+typedef struct _usart_transfer
+{
+    uint8_t *data;   /*!< The buffer of data to be transfer.*/
+    size_t dataSize; /*!< The byte count to be transfer. */
+} usart_transfer_t;
+
+/* Forward declaration of the handle typedef. */
+typedef struct _usart_handle usart_handle_t;
+
+/*! @brief USART transfer callback function. */
+typedef void (*usart_transfer_callback_t)(USART_Type *base, usart_handle_t *handle, status_t status, void *userData);
+
+/*! @brief USART handle structure. */
+struct _usart_handle
+{
+    uint8_t *volatile txData;   /*!< Address of remaining data to send. */
+    volatile size_t txDataSize; /*!< Size of the remaining data to send. */
+    size_t txDataSizeAll;       /*!< Size of the data to send out. */
+    uint8_t *volatile rxData;   /*!< Address of remaining data to receive. */
+    volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
+    size_t rxDataSizeAll;       /*!< Size of the data to receive. */
+
+    uint8_t *rxRingBuffer;              /*!< Start address of the receiver ring buffer. */
+    size_t rxRingBufferSize;            /*!< Size of the ring buffer. */
+    volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
+    volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
+
+    usart_transfer_callback_t callback; /*!< Callback function. */
+    void *userData;                     /*!< USART callback function parameter.*/
+
+    volatile uint8_t txState; /*!< TX transfer state. */
+    volatile uint8_t rxState; /*!< RX transfer state */
+
+    usart_txfifo_watermark_t txWatermark; /*!< txFIFO watermark */
+    usart_rxfifo_watermark_t rxWatermark; /*!< rxFIFO watermark */
+};
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+/*! @brief Returns instance number for USART peripheral base address. */
+uint32_t USART_GetInstance(USART_Type *base);
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Initializes a USART instance with user configuration structure and peripheral clock.
+ *
+ * This function configures the USART module with the user-defined settings. The user can configure the configuration
+ * structure and also get the default configuration by using the USART_GetDefaultConfig() function.
+ * Example below shows how to use this API to configure USART.
+ * @code
+ *  usart_config_t usartConfig;
+ *  usartConfig.baudRate_Bps = 115200U;
+ *  usartConfig.parityMode = kUSART_ParityDisabled;
+ *  usartConfig.stopBitCount = kUSART_OneStopBit;
+ *  USART_Init(USART1, &usartConfig, 20000000U);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param config Pointer to user-defined configuration structure.
+ * @param srcClock_Hz USART clock source frequency in HZ.
+ * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * @retval kStatus_InvalidArgument USART base address is not valid
+ * @retval kStatus_Success Status USART initialize succeed
+ */
+status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz);
+
+/*!
+ * @brief Deinitializes a USART instance.
+ *
+ * This function waits for TX complete, disables TX and RX, and disables the USART clock.
+ *
+ * @param base USART peripheral base address.
+ */
+void USART_Deinit(USART_Type *base);
+
+/*!
+ * @brief Gets the default configuration structure.
+ *
+ * This function initializes the USART configuration structure to a default value. The default
+ * values are:
+ *   usartConfig->baudRate_Bps = 115200U;
+ *   usartConfig->parityMode = kUSART_ParityDisabled;
+ *   usartConfig->stopBitCount = kUSART_OneStopBit;
+ *   usartConfig->bitCountPerChar = kUSART_8BitsPerChar;
+ *   usartConfig->loopback = false;
+ *   usartConfig->enableTx = false;
+ *   usartConfig->enableRx = false;
+ *
+ * @param config Pointer to configuration structure.
+ */
+void USART_GetDefaultConfig(usart_config_t *config);
+
+/*!
+ * @brief Sets the USART instance baud rate.
+ *
+ * This function configures the USART module baud rate. This function is used to update
+ * the USART module baud rate after the USART module is initialized by the USART_Init.
+ * @code
+ *  USART_SetBaudRate(USART1, 115200U, 20000000U);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param baudrate_Bps USART baudrate to be set.
+ * @param srcClock_Hz USART clock source frequency in HZ.
+ * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * @retval kStatus_Success Set baudrate succeed.
+ * @retval kStatus_InvalidArgument One or more arguments are invalid.
+ */
+status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz);
+
+/* @} */
+
+/*!
+ * @name Status
+ * @{
+ */
+
+/*!
+ * @brief Get USART status flags.
+ *
+ * This function get all USART status flags, the flags are returned as the logical
+ * OR value of the enumerators @ref _usart_flags. To check a specific status,
+ * compare the return value with enumerators in @ref _usart_flags.
+ * For example, to check whether the TX is empty:
+ * @code
+ *     if (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(USART1))
+ *     {
+ *         ...
+ *     }
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @return USART status flags which are ORed by the enumerators in the _usart_flags.
+ */
+static inline uint32_t USART_GetStatusFlags(USART_Type *base)
+{
+    return base->FIFOSTAT;
+}
+
+/*!
+ * @brief Clear USART status flags.
+ *
+ * This function clear supported USART status flags
+ * Flags that can be cleared or set are:
+ *      kUSART_TxError
+ *      kUSART_RxError
+ * For example:
+ * @code
+ *     USART_ClearStatusFlags(USART1, kUSART_TxError | kUSART_RxError)
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask status flags to be cleared.
+ */
+static inline void USART_ClearStatusFlags(USART_Type *base, uint32_t mask)
+{
+    /* Only TXERR, RXERR fields support write. Remaining fields should be set to zero */
+    base->FIFOSTAT = mask & (USART_FIFOSTAT_TXERR_MASK | USART_FIFOSTAT_RXERR_MASK);
+}
+
+/* @} */
+
+/*!
+ * @name Interrupts
+ * @{
+ */
+
+/*!
+ * @brief Enables USART interrupts according to the provided mask.
+ *
+ * This function enables the USART interrupts according to the provided mask. The mask
+ * is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
+ * For example, to enable TX empty interrupt and RX full interrupt:
+ * @code
+ *     USART_EnableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask The interrupts to enable. Logical OR of @ref _usart_interrupt_enable.
+ */
+static inline void USART_EnableInterrupts(USART_Type *base, uint32_t mask)
+{
+    base->FIFOINTENSET = mask & 0xF;
+}
+
+/*!
+ * @brief Disables USART interrupts according to a provided mask.
+ *
+ * This function disables the USART interrupts according to a provided mask. The mask
+ * is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
+ * This example shows how to disable the TX empty interrupt and RX full interrupt:
+ * @code
+ *     USART_DisableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask The interrupts to disable. Logical OR of @ref _usart_interrupt_enable.
+ */
+static inline void USART_DisableInterrupts(USART_Type *base, uint32_t mask)
+{
+    base->FIFOINTENCLR = mask & 0xF;
+}
+
+/*!
+ * @brief Returns enabled USART interrupts.
+ *
+ * This function returns the enabled USART interrupts.
+ *
+ * @param base USART peripheral base address.
+ */
+static inline uint32_t USART_GetEnabledInterrupts(USART_Type *base)
+{
+    return base->FIFOINTENSET;
+}
+
+/*!
+ * @brief Enable DMA for Tx
+ */
+static inline void USART_EnableTxDMA(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->FIFOCFG |= USART_FIFOCFG_DMATX_MASK;
+    }
+    else
+    {
+        base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK);
+    }
+}
+
+/*!
+ * @brief Enable DMA for Rx
+ */
+static inline void USART_EnableRxDMA(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->FIFOCFG |= USART_FIFOCFG_DMARX_MASK;
+    }
+    else
+    {
+        base->FIFOCFG &= ~(USART_FIFOCFG_DMARX_MASK);
+    }
+}
+
+/*!
+ * @brief Enable CTS.
+ * This function will determine whether CTS is used for flow control.
+ *
+ * @param base    USART peripheral base address.
+ * @param enable  Enable CTS or not, true for enable and false for disable.
+ */
+static inline void USART_EnableCTS(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CFG |= USART_CFG_CTSEN_MASK;
+    }
+    else
+    {
+        base->CFG &= ~USART_CFG_CTSEN_MASK;
+    }
+}
+
+/*!
+ * @brief Continuous Clock generation.
+ * By default, SCLK is only output while data is being transmitted in synchronous mode.
+ * Enable this funciton, SCLK will run continuously in synchronous mode, allowing
+ * characters to be received on Un_RxD independently from transmission on Un_TXD).
+ *
+ * @param base    USART peripheral base address.
+ * @param enable  Enable Continuous Clock generation mode or not, true for enable and false for disable.
+ */
+static inline void USART_EnableContinuousSCLK(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CTL |= USART_CTL_CC_MASK;
+    }
+    else
+    {
+        base->CTL &= ~USART_CTL_CC_MASK;
+    }
+}
+
+/*!
+ * @brief Enable Continuous Clock generation bit auto clear.
+ * While enable this cuntion, the Continuous Clock bit is automatically cleared when a complete
+ * character has been received. This bit is cleared at the same time.
+ *
+ * @param base    USART peripheral base address.
+ * @param enable  Enable auto clear or not, true for enable and false for disable.
+ */
+static inline void USART_EnableAutoClearSCLK(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CTL |= USART_CTL_CLRCCONRX_MASK;
+    }
+    else
+    {
+        base->CTL &= ~USART_CTL_CLRCCONRX_MASK;
+    }
+}
+/* @} */
+
+/*!
+ * @name Bus Operations
+ * @{
+ */
+
+/*!
+ * @brief Writes to the FIFOWR register.
+ *
+ * This function writes data to the txFIFO directly. The upper layer must ensure
+ * that txFIFO has space for data to write before calling this function.
+ *
+ * @param base USART peripheral base address.
+ * @param data The byte to write.
+ */
+static inline void USART_WriteByte(USART_Type *base, uint8_t data)
+{
+    base->FIFOWR = data;
+}
+
+/*!
+ * @brief Reads the FIFORD register directly.
+ *
+ * This function reads data from the rxFIFO directly. The upper layer must
+ * ensure that the rxFIFO is not empty before calling this function.
+ *
+ * @param base USART peripheral base address.
+ * @return The byte read from USART data register.
+ */
+static inline uint8_t USART_ReadByte(USART_Type *base)
+{
+    return base->FIFORD;
+}
+
+/*!
+ * @brief Writes to the TX register using a blocking method.
+ *
+ * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
+ * to have room and writes data to the TX buffer.
+ *
+ * @param base USART peripheral base address.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ */
+void USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length);
+
+/*!
+ * @brief Read RX data register using a blocking method.
+ *
+ * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
+ * have data and read data from the TX register.
+ *
+ * @param base USART peripheral base address.
+ * @param data Start address of the buffer to store the received data.
+ * @param length Size of the buffer.
+ * @retval kStatus_USART_FramingError Receiver overrun happened while receiving data.
+ * @retval kStatus_USART_ParityError Noise error happened while receiving data.
+ * @retval kStatus_USART_NoiseError Framing error happened while receiving data.
+ * @retval kStatus_USART_RxError Overflow or underflow rxFIFO happened.
+ * @retval kStatus_Success Successfully received all data.
+ */
+status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length);
+
+/* @} */
+
+/*!
+ * @name Transactional
+ * @{
+ */
+
+/*!
+ * @brief Initializes the USART handle.
+ *
+ * This function initializes the USART handle which can be used for other USART
+ * transactional APIs. Usually, for a specified USART instance,
+ * call this API once to get the initialized handle.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param callback The callback function.
+ * @param userData The parameter of the callback function.
+ */
+status_t USART_TransferCreateHandle(USART_Type *base,
+                                    usart_handle_t *handle,
+                                    usart_transfer_callback_t callback,
+                                    void *userData);
+
+/*!
+ * @brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the IRQ handler, the USART driver calls the callback
+ * function and passes the @ref kStatus_USART_TxIdle as status parameter.
+ *
+ * @note The kStatus_USART_TxIdle is passed to the upper layer when all data is written
+ * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX,
+ * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param xfer USART transfer structure. See  #usart_transfer_t.
+ * @retval kStatus_Success Successfully start the data transmission.
+ * @retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
+ * @retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer);
+
+/*!
+ * @brief Sets up the RX ring buffer.
+ *
+ * This function sets up the RX ring buffer to a specific USART handle.
+ *
+ * When the RX ring buffer is used, data received are stored into the ring buffer even when the
+ * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received
+ * in the ring buffer, the user can get the received data from the ring buffer directly.
+ *
+ * @note When using the RX ring buffer, one byte is reserved for internal use. In other
+ * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
+ * @param ringBufferSize size of the ring buffer.
+ */
+void USART_TransferStartRingBuffer(USART_Type *base,
+                                   usart_handle_t *handle,
+                                   uint8_t *ringBuffer,
+                                   size_t ringBufferSize);
+
+/*!
+ * @brief Aborts the background transfer and uninstalls the ring buffer.
+ *
+ * This function aborts the background transfer and uninstalls the ring buffer.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the length of received data in RX ring buffer.
+ *
+ * @param handle USART handle pointer.
+ * @return Length of received data in RX ring buffer.
+ */
+size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle);
+
+/*!
+ * @brief Aborts the interrupt-driven data transmit.
+ *
+ * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
+ * how many bytes are still not sent out.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the number of bytes that have been written to USART TX register.
+ *
+ * This function gets the number of bytes that have been written to USART TX
+ * register by interrupt method.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param count Send bytes count.
+ * @retval kStatus_NoTransferInProgress No send in progress.
+ * @retval kStatus_InvalidArgument Parameter is invalid.
+ * @retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
+
+/*!
+ * @brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ *  returns without waiting for all data to be received.
+ * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
+ * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
+ * After copying, if the data in the ring buffer is not enough to read, the receive
+ * request is saved by the USART driver. When the new data arrives, the receive request
+ * is serviced first. When all data is received, the USART driver notifies the upper layer
+ * through a callback function and passes the status parameter @ref kStatus_USART_RxIdle.
+ * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
+ * The 5 bytes are copied to the xfer->data and this function returns with the
+ * parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
+ * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer.
+ * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
+ * to receive data to the xfer->data. When all data is received, the upper layer is notified.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param xfer USART transfer structure, see #usart_transfer_t.
+ * @param receivedBytes Bytes received from the ring buffer directly.
+ * @retval kStatus_Success Successfully queue the transfer into transmit queue.
+ * @retval kStatus_USART_RxBusy Previous receive request is not finished.
+ * @retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferReceiveNonBlocking(USART_Type *base,
+                                          usart_handle_t *handle,
+                                          usart_transfer_t *xfer,
+                                          size_t *receivedBytes);
+
+/*!
+ * @brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
+ * how many bytes not received yet.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param count Receive bytes count.
+ * @retval kStatus_NoTransferInProgress No receive in progress.
+ * @retval kStatus_InvalidArgument Parameter is invalid.
+ * @retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
+
+/*!
+ * @brief USART IRQ handle function.
+ *
+ * This function handles the USART transmit and receive IRQ request.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle);
+
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_USART_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_wtimer.c b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_wtimer.c
new file mode 100755
index 0000000..5ca3070
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_wtimer.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/****************************************************************************/
+/***        Include files                                                 ***/
+/****************************************************************************/
+
+#include "fsl_wtimer.h"
+#include "fsl_clock.h"
+#include "fsl_device_registers.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.wtimer"
+#endif
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+//#define WTIMER_TRACE
+
+#ifndef WTIMER_TRACE
+#define PRINTF(...)
+#else
+#include "fsl_debug_console.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.wtimer"
+#endif
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+typedef struct
+{
+    uint32_t wkt_stat_timeout_mask;
+    uint32_t wkt_stat_running_mask;
+    uint32_t wkt_ctrl_clk_ena_mask;
+    uint32_t wkt_ctrl_ena_mask;
+    uint32_t wkt_intenclr_timeout_mask;
+    volatile uint32_t *wkt_load_lsb_reg;
+    volatile uint32_t *wkt_load_msb_reg;
+    const volatile uint32_t *wkt_val_lsb_reg;
+    const volatile uint32_t *wkt_val_msb_reg;
+    uint8_t wkt_irq_id;
+} timer_param_t;
+
+static const timer_param_t timer_param[2] = {
+    {
+        .wkt_stat_timeout_mask     = SYSCON_WKT_STAT_WKT0_TIMEOUT_MASK,
+        .wkt_stat_running_mask     = SYSCON_WKT_STAT_WKT0_RUNNING_MASK,
+        .wkt_ctrl_clk_ena_mask     = SYSCON_WKT_CTRL_WKT0_CLK_ENA_MASK,
+        .wkt_ctrl_ena_mask         = SYSCON_WKT_CTRL_WKT0_ENA_MASK,
+        .wkt_intenclr_timeout_mask = SYSCON_WKT_INTENSET_WKT0_TIMEOUT_MASK,
+        .wkt_load_lsb_reg          = &SYSCON->WKT_LOAD_WKT0_LSB,
+        .wkt_load_msb_reg          = &SYSCON->WKT_LOAD_WKT0_MSB,
+        .wkt_val_lsb_reg           = &SYSCON->WKT_VAL_WKT0_LSB,
+        .wkt_val_msb_reg           = NULL,
+        .wkt_irq_id                = WAKE_UP_TIMER0_IRQn,
+    },
+    {
+        .wkt_stat_timeout_mask     = SYSCON_WKT_STAT_WKT1_TIMEOUT_MASK,
+        .wkt_stat_running_mask     = SYSCON_WKT_STAT_WKT1_RUNNING_MASK,
+        .wkt_ctrl_clk_ena_mask     = SYSCON_WKT_CTRL_WKT1_CLK_ENA_MASK,
+        .wkt_ctrl_ena_mask         = SYSCON_WKT_CTRL_WKT1_ENA_MASK,
+        .wkt_intenclr_timeout_mask = SYSCON_WKT_INTENSET_WKT1_TIMEOUT_MASK,
+        .wkt_load_lsb_reg          = &SYSCON->WKT_LOAD_WKT1,
+        .wkt_load_msb_reg          = NULL,
+        .wkt_val_lsb_reg           = &SYSCON->WKT_VAL_WKT1,
+        .wkt_val_msb_reg           = NULL,
+        .wkt_irq_id                = WAKE_UP_TIMER1_IRQn,
+    },
+};
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * brief Enable the clocks to the peripheral (functional clock and AHB clock)
+ *
+ * note This function does not reset the wake timer peripheral. Wake timer reset is done in PWRM_vColdStart() from the
+ * PWRM framework module if integrated
+ * If PWRM framework module is integrated, WTIMER_Init() is called in PWRM_vInit() for power modes with Oscillator ON.
+ *
+ */
+void WTIMER_Init(void)
+{
+    /* set clock and divider */
+    SYSCON->AHBCLKCTRLS[0] |= SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_MASK;
+    SYSCON->WKTCLKSEL = SYSCON_WKTCLKSEL_SEL(0); // & ~SYSCON_WKTCLKSEL_SEL_MASK ;
+}
+
+/*!
+ * brief Disable the clocks to the peripheral (functional clock and AHB clock)
+ *
+ * note This function does not reset the wake timer peripheral.
+ *
+ */
+void WTIMER_DeInit(void)
+{
+    /* set clock and divider */
+    SYSCON->AHBCLKCTRLS[0] &= ~SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_MASK;
+    SYSCON->WKTCLKSEL = SYSCON_WKTCLKSEL_SEL(2); // No Clock ;
+}
+
+/*!
+ * brief Gets the Timer status flags.
+ *
+ * param timer_id   Wtimer Id
+ *
+ * return The status flags.
+ */
+WTIMER_status_t WTIMER_GetStatusFlags(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+    WTIMER_status_t status             = WTIMER_STATUS_NOT_RUNNING;
+    uint32_t stat                      = SYSCON->WKT_STAT;
+
+    if (stat & timer_param_l->wkt_stat_timeout_mask)
+    {
+        status = WTIMER_STATUS_EXPIRED;
+        PRINTF("WakeTimerFiredStatus[%d] expired\n", timer_id);
+    }
+    else if (stat & timer_param_l->wkt_stat_running_mask)
+    {
+        status = WTIMER_STATUS_RUNNING;
+        PRINTF("WakeTimerFiredStatus[%d] running\n", timer_id);
+    }
+
+    return status;
+}
+
+/*!
+ * brief Enable the selected Timer interrupts.
+ * The application shall implement the Wake timer ISR
+ *
+ * param timer_id   Wtimer Id
+ */
+void WTIMER_EnableInterrupts(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+
+    EnableIRQ((IRQn_Type)timer_param_l->wkt_irq_id);
+    SYSCON->WKT_INTENSET = timer_param_l->wkt_intenclr_timeout_mask;
+}
+
+/*!
+ * brief Starts the Timer counter.
+ * The function performs:
+ * -stop the timer if running, clear the status and interrupt flag if set (WTIMER_ClearStatusFlags())
+ * -set the counter value
+ * -start the timer
+ *
+ * param timer_id   Wtimer Id
+ * param count      number of 32KHz clock periods before expiration
+ */
+void WTIMER_StartTimer(WTIMER_timer_id_t timer_id, uint32_t count)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+
+    PRINTF("-->> vAHI_WakeTimerStart[%d] : STAT=%x count=%d WKT_INTSTAT=%x count=%d\n", timer_id, SYSCON->WKT_STAT,
+           count, SYSCON->WKT_INTSTAT, count);
+
+    /* enable the clock */
+    SYSCON->WKT_CTRL |= timer_param_l->wkt_ctrl_clk_ena_mask;
+
+    /* clear timeout flag if set */
+    SYSCON->WKT_STAT = timer_param_l->wkt_stat_timeout_mask;
+
+    /* stop timer if running */
+    SYSCON->WKT_CTRL &= ~(timer_param_l->wkt_ctrl_ena_mask);
+
+    /* make sure the timer is really stopped */
+    while ((SYSCON->WKT_STAT & (timer_param_l->wkt_stat_running_mask)) == timer_param_l->wkt_stat_running_mask)
+    {
+        __asm volatile("nop");
+    }
+
+    *(timer_param_l->wkt_load_lsb_reg) = count;
+    if (timer_id == WTIMER_TIMER0_ID)
+    {
+        *(timer_param_l->wkt_load_msb_reg) = 0;
+    }
+
+    /* enable the timer */
+    SYSCON->WKT_CTRL |= timer_param_l->wkt_ctrl_ena_mask;
+
+    while ((SYSCON->WKT_STAT & (timer_param_l->wkt_stat_running_mask)) == 0)
+    {
+        __asm volatile("nop");
+    }
+
+    PRINTF("<<-- vAHI_WakeTimerStart[%d] : STAT=%x WKT_INTSTAT=%x\n", timer_id, SYSCON->WKT_STAT, SYSCON->WKT_INTSTAT);
+}
+
+/*!
+ * brief Read the LSB counter of the wake timer
+ * API checks the next counter update (next 32KHz clock edge) so the value is uptodate
+ * Important note : The counter shall be running otherwise, the API gets locked and never return
+ *
+ * param timer_id   Wtimer Id
+ * return  32KHz clock frequency (number of 32KHz clock in one sec) - expect to have 32768
+ */
+uint32_t WTIMER_ReadTimerSafe(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l    = &timer_param[timer_id];
+    volatile uint32_t u32CurrentCount_ini = *timer_param_l->wkt_val_lsb_reg;
+    volatile uint32_t u32CurrentCount     = *timer_param_l->wkt_val_lsb_reg;
+
+    while (u32CurrentCount == u32CurrentCount_ini)
+        u32CurrentCount = *timer_param_l->wkt_val_lsb_reg;
+
+    return u32CurrentCount;
+}
+
+/*!
+ * brief Read the LSB counter of the wake timer
+ * This API is unsafe. If the counter has just been started, the counter value may not be
+ * up to date until the next 32KHz clock edge.
+ * Use WTIMER_ReadTimerSafe() instead
+ *
+ * param timer_id   Wtimer Id
+ * return  counter value - number of ticks before expiration if running
+ */
+uint32_t WTIMER_ReadTimer(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+    volatile uint32_t u32CurrentCount  = *timer_param_l->wkt_val_lsb_reg;
+
+    return u32CurrentCount;
+}
+
+/*!
+ * brief Clears the Timer status flags if expired and clear the pendng interrupt if active
+ * it needs to be called in ISR
+ *
+ * param timer_id   Wtimer Id
+ */
+void WTIMER_ClearStatusFlags(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+
+    /* clear expiration flag */
+    SYSCON->WKT_STAT = timer_param_l->wkt_stat_timeout_mask;
+
+    /* clear interrupt if pending */
+    NVIC_ClearPendingIRQ((IRQn_Type)timer_param_l->wkt_irq_id);
+}
+
+/*!
+ * brief Stops the Timer counter.
+ *
+ * param timer_id   Wtimer Id
+ */
+void WTIMER_StopTimer(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+
+    /* Stop timer */
+    SYSCON->WKT_CTRL &= ~(timer_param_l->wkt_ctrl_ena_mask);
+
+    /* make sure the timer is really stopped */
+    while ((SYSCON->WKT_STAT & (timer_param_l->wkt_stat_running_mask)) == timer_param_l->wkt_stat_running_mask)
+    {
+        __asm volatile("nop");
+    }
+
+    WTIMER_ClearStatusFlags(timer_id);
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_wtimer.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_wtimer.h
new file mode 100755
index 0000000..1897309
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/fsl_wtimer.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_WTIMER_H_
+#define _FSL_WTIMER_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup wtimer
+ * @{
+ */
+
+/*! @file */
+
+/**
+ * Wake timers provide wakeup capabilities in sleep modes where 32KHz clock is kept active.
+ * Wake timer 0 is a 48bit based counter while wake timer 1 is 32bit based counter.
+ * A special API functions WTIMER_StartTimerLarge(0 and WTIMER_StartTimerLarge() are provided to access the 48bit
+ * counter. The Wake timer 1 is to be used bu the PWRM framework. It shall not be used by the Application directly. API
+ * provides the capability to enable and disable interrupts. The application shall implement the Wake timer ISR on its
+ * side. The wake timer ISR prototypes are : void WAKE_UP_TIMER0_IRQHandler(void); and void
+ * WAKE_UP_TIMER1_IRQHandler(void); The Application shall correctly the 32KHz source amoung the FRO32 or Crystal 32KHz
+ * using CLOCK_EnableClock() API in fsl_clock.h The APi provides the capability to calibrate the 32KHz clock versus a
+ * high reference clock (32MHz crystal).
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+#define FSL_WTIMER_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
+/*@}*/
+
+typedef enum
+{
+    WTIMER_TIMER0_ID = 0,
+    WTIMER_TIMER1_ID = 1,
+} WTIMER_timer_id_t;
+
+typedef enum
+{
+    WTIMER_STATUS_NOT_RUNNING = 0,
+    WTIMER_STATUS_RUNNING     = 1,
+    WTIMER_STATUS_EXPIRED     = 2,
+} WTIMER_status_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Enable the clocks to the peripheral (functional clock and AHB clock)
+ *
+ * @note This function does not reset the wake timer peripheral. Wake timer reset is done in PWRM_vColdStart() from the
+ * PWRM framework module if integrated If PWRM framework module is integrated, WTIMER_Init() is called in PWRM_vInit()
+ * for power modes with Oscillator ON.
+ *
+ */
+void WTIMER_Init(void);
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Disable the clocks to the peripheral (functional clock and AHB clock)
+ *
+ * @note This function does not reset the wake timer peripheral.
+ *
+ */
+void WTIMER_DeInit(void);
+
+/*!
+ * @brief Enable the selected Timer interrupts.
+ * The application shall implement the Wake timer ISR
+ *
+ * @param timer_id   Wtimer Id
+ */
+void WTIMER_EnableInterrupts(WTIMER_timer_id_t timer_id);
+
+#ifdef NOT_IMPLEMENTED_YET
+/*!
+ * @brief Disable the selected Timer interrupts.
+ * Interrupts are disabled by default. The API shall be called if the interrupt was enabled before.
+ *
+ * @param timer_id   Wtimer Id
+ */
+void WTIMER_DisableInterrupts(WTIMER_timer_id_t timer_id);
+#endif
+
+/*!
+ * @brief Gets the Timer status flags.
+ *
+ * @param timer_id   Wtimer Id
+ *
+ * @return The status flags.
+ */
+WTIMER_status_t WTIMER_GetStatusFlags(WTIMER_timer_id_t timer_id);
+
+/*!
+ * @brief Clears the Timer status flags if expired and clear the pendng interrupt if active
+ * it needs to be called in ISR
+ *
+ * @param timer_id   Wtimer Id
+ */
+void WTIMER_ClearStatusFlags(WTIMER_timer_id_t timer_id);
+
+/*!
+ * @brief Starts the Timer counter.
+ * The function performs:
+ * -stop the timer if running, clear the status and interrupt flag if set (WTIMER_ClearStatusFlags())
+ * -set the counter value
+ * -start the timer
+ *
+ * @param timer_id   Wtimer Id
+ * @param count      number of 32KHz clock periods before expiration
+ */
+void WTIMER_StartTimer(WTIMER_timer_id_t timer_id, uint32_t count);
+
+/*!
+ * @brief Stops the Timer counter.
+ *
+ * @param timer_id   Wtimer Id
+ */
+void WTIMER_StopTimer(WTIMER_timer_id_t timer_id);
+
+/*!
+ * @brief Calibrate the 32KHz clock to be used by the wake timer versus the 32MHz crystal clock source
+ * The Applicaton shall switches OFF the 32MHz clock if no longer used by the chip using CLOCK_DisableClock() in
+ * fsl_clock.h
+ *
+ * @return  32KHz clock frequency (number of 32KHz clock in one sec) - expect to have 32768
+ */
+uint32_t WTIMER_CalibrateTimer(void);
+
+/*!
+ * @brief Read the LSB counter of the wake timer
+ * This API is unsafe. If the counter has just been started, the counter value may not be
+ * up to date until the next 32KHz clock edge.
+ * Use WTIMER_ReadTimerSafe() instead
+ *
+ * @param timer_id   Wtimer Id
+ * @return  counter value - number of ticks before expiration if running
+ */
+uint32_t WTIMER_ReadTimer(WTIMER_timer_id_t timer_id);
+
+/*!
+ * @brief Read the LSB counter of the wake timer
+ * API checks the next counter update (next 32KHz clock edge) so the value is uptodate
+ * Important note : The counter shall be running otherwise, the API gets locked and never return
+ *
+ * @param timer_id   Wtimer Id
+ * @return  32KHz clock frequency (number of 32KHz clock in one sec) - expect to have 32768
+ */
+uint32_t WTIMER_ReadTimerSafe(WTIMER_timer_id_t timer_id);
+
+#ifdef NOT_IMPLEMENTED_YET
+/*!
+ * @brief Starts the Timer counter.
+ *
+ * @param timer_id   Wtimer Id
+ * @param count      number of 32KHz clock periods before expiration
+ */
+void WTIMER_StartTimerLarge(WTIMER_timer_id_t timer_id, uint64_t count);
+
+/*!
+ * @brief Read the LSB + MSB counter of the 48bit wake timer, Read the LSB counter for 32bit wale timer
+ *
+ *
+ * @param timer_id   Wtimer Id
+ * @return wake timer counter
+ */
+uint64_t WTIMER_ReadTimerLarge(WTIMER_timer_id_t timer_id);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_WTIMER_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_aes.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_aes.h
new file mode 100755
index 0000000..1e45b24
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_aes.h
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _ROM_AES_H
+#define _ROM_AES_H
+
+/*******************
+ * INCLUDE FILES    *
+ ********************/
+#include <stdint.h>
+#include "rom_common.h"
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+typedef uint32_t ErrorCode_t;  /*!< enum defined in error.h */
+
+/*******************
+ * EXPORTED MACROS  *
+ ********************/
+
+#define AES_ENCDEC_MODE (1 << 0)
+#define AES_GF128HASH_MODE (2 << 0)
+#define AES_ENDEC_GF128HASH_MODE (3 << 0)
+#define AES_GF128_SEL (1 << 2)
+#define AES_INT_BSWAP (1 << 4)
+#define AES_INT_WSWAP (1 << 5)
+#define AES_OUTT_BSWAP (1 << 6)
+#define AES_OUTT_WSWAP (1 << 7)
+#define AES_KEYSIZE_128 (0 << 8)
+#define AES_KEYSIZE_192 (1 << 8)
+#define AES_KEYSIZE_256 (2 << 8)
+#define AES_INB_FSEL(n) ((n) << 16) /*!< n->1=Input Text, n->2=Holding, n->3=Input Text XOR Holding */
+#define AES_HOLD_FSEL(n) \
+    ((n) << 20) /*!< n->0=Counter, n->1=Input Text, n->2=Output Block, n->3=Input Text XOR Output Block */
+#define AES_OUTT_FSEL(n) ((n) << 24) /*!< n->0=OUTT, n->1=Output Block XOR Input Text, n->2=Output Block XOR Holding */
+
+/*********************
+ * EXPORTED TYPEDEFS  *
+ **********************/
+
+/*! @brief AES setup modes */
+typedef enum
+{
+    AES_MODE_ECB_ENCRYPT = 0,
+    AES_MODE_ECB_DECRYPT,
+    AES_MODE_CBC_ENCRYPT,
+    AES_MODE_CBC_DECRYPT,
+    AES_MODE_CFB_ENCRYPT,
+    AES_MODE_CFB_DECRYPT,
+    AES_MODE_OFB,
+    AES_MODE_CTR,
+    AES_MODE_GCM_TAG,
+    AES_MODE_UNUSED = 0x7FFFFFFF /*!< Not used, but forces enum to 32-bit size */
+} AES_MODE_T;
+
+/*! @brief Size of the AES key */
+typedef enum
+{
+    AES_KEY_128BITS = 0, /*!< KEY size 128 bits */
+    AES_KEY_192BITS, /*!< KEY size 192 bits */
+    AES_KEY_256BITS, /*!< KEY size 256 bits */
+    AES_FVAL = 0x7FFFFFFF /*!< Not used, but forces enum to 32-bit size and unsigned */
+} AES_KEY_SIZE_T;
+
+/*******************
+ * EXPORTED DATA    *
+ ********************/
+
+/********************************
+ * EXPORTED FUNCTIONS PROTOTYPES *
+ *********************************/
+
+/**
+ * @brief	Initialize the AES
+ *
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	Driver does not enable AES clock, power, or perform reset peripheral (if needed).
+ */
+static inline ErrorCode_t aesInit(void)
+{
+    ErrorCode_t (*p_aesInit)(void);
+    p_aesInit = (ErrorCode_t (*)(void))0x03001161U;
+
+    return p_aesInit();
+}
+
+/**
+ * @brief	AES control function, byte write (useful for writing configuration register)
+ * @brief	offset	: Register offset in AES, 32-bit aligned value
+ * @brief	val8	: 8-bit value to write
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it perform byte level write access to a register.
+ *			This function is not meant to be public.
+ */
+static inline void aesWriteByte(uint32_t offset, uint8_t val8)
+{
+    void (*p_aesWriteByte)(uint32_t offset, uint8_t val8);
+    p_aesWriteByte = (void (*)(uint32_t offset, uint8_t val8))0x03001175U;
+
+    p_aesWriteByte(offset, val8);
+}
+
+/**
+ * @brief	AES control function, word write
+ * @brief	offset	: Register offset in AES, 32-bit aligned value
+ * @brief	val32	: 32-bit value to write
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it for write access to a register. This function
+ *			is not meant to be public.
+ */
+static inline void aesWrite(uint32_t offset, uint32_t val32)
+{
+    void (*p_aesWrite)(uint32_t offset, uint32_t val32);
+    p_aesWrite = (void (*)(uint32_t offset, uint32_t val32))0x0300118dU;
+
+    p_aesWrite(offset, val32);
+}
+
+/**
+ * @brief	AES control function, word read
+ * @brief	offset	: Register offset in AES, 32-bit aligned value
+ * @brief	pVal32	: Pointer to 32-bit area to read into
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it for read access to a register. This function
+ *			is not meant to be public.
+ */
+static inline void aesRead(uint32_t offset, uint32_t *pVal32)
+{
+    void (*p_aesRead)(uint32_t offset, uint32_t *pVal32);
+    p_aesRead = (void (*)(uint32_t offset, uint32_t *pVal32))0x030011a5U;
+
+    p_aesRead(offset, pVal32);
+}
+
+/**
+ * @brief	AES control function, block write (used for multi-register block writes)
+ * @brief	offset		: Register offset in AES, 32-bit aligned value
+ * @brief	pVal32		: Pointer to 32-bit array to write
+ * @brief	numBytes	: Number of bytes to write, must be 32-bit aligned
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it for write access to a register. This function
+ *			is not meant to be public. Writes occur in 32-bit chunks.
+ */
+static inline void aesWriteBlock(uint32_t offset, uint32_t *pVal32, uint32_t numBytes)
+{
+    void (*p_aesWriteBlock)(uint32_t offset, uint32_t *pVal32, uint32_t numBytes);
+    p_aesWriteBlock = (void (*)(uint32_t offset, uint32_t *pVal32, uint32_t numBytes))0x030011c1U;
+
+    p_aesWriteBlock(offset, pVal32, numBytes);
+}
+
+/**
+ * @brief	AES control function, block read (used for multi-register block read)
+ * @brief	offset		: Register offset in AES, 32-bit aligned value
+ * @brief	pVal32		: Pointer to 32-bit array to read into
+ * @brief	numBytes	: Number of bytes to read, must be 32-bit aligned
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it for read access to a register. This function
+ *			is not meant to be public. Reads occur in 32-bit chunks. Read data if undefined
+ *			if AES not present.
+ */
+static inline void aesReadBlock(uint32_t offset, uint32_t *pVal32, uint32_t numBytes)
+{
+    void (*p_aesReadBlock)(uint32_t offset, uint32_t *pVal32, uint32_t numBytes);
+    p_aesReadBlock = (void (*)(uint32_t offset, uint32_t *pVal32, uint32_t numBytes))0x030011e9U;
+
+    p_aesReadBlock(offset, pVal32, numBytes);
+}
+
+/**
+ * @brief	Sets up the AES mode
+ * @param	wipe	: use true to invalidate AES key and disable cipher
+ * @param	flags	: Applies extra flags (Or'ed in config), normally should be 0, useful for swap bits only
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesMode(AES_MODE_T modeVal, uint32_t flags)
+{
+    ErrorCode_t (*p_aesMode)(AES_MODE_T modeVal, uint32_t flags);
+    p_aesMode = (ErrorCode_t (*)(AES_MODE_T modeVal, uint32_t flags))0x03001211U;
+
+    return p_aesMode(modeVal, flags);
+}
+
+/**
+ * @brief	Aborts optional AES operation and wipes AES engine
+ * @param	wipe	: use true to invalidate AES key and disable cipher
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesAbort(int wipe)
+{
+    ErrorCode_t (*p_aesAbort)(int wipe);
+    p_aesAbort = (ErrorCode_t (*)(int wipe))0x03001269U;
+
+    return p_aesAbort(wipe);
+}
+
+/**
+ * @brief	Loads the increment that is used when in counter modes in the AES block
+ * @param	counter	: 32-bit initial increment counter value
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesLoadCounter(uint32_t counter)
+{
+    ErrorCode_t (*p_aesLoadCounter)(uint32_t counter);
+    p_aesLoadCounter = (ErrorCode_t (*)(uint32_t counter))0x03001291U;
+
+    return p_aesLoadCounter(counter);
+}
+
+/**
+ * @brief	Loads the passed (software) key into the AES block
+ * @param	keySize	: 0 = 128-bits, 1 = 192-bits, 2 = 256-bits, all other values are invalid (AES_KEY_SIZE_T)
+ * @param	key		: Pointer to up to a 256-bit key array
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesLoadKeyFromSW(AES_KEY_SIZE_T keySize, uint32_t *key)
+{
+    ErrorCode_t (*p_aesLoadKeyFromSW)(AES_KEY_SIZE_T keySize, uint32_t *key);
+    p_aesLoadKeyFromSW = (ErrorCode_t (*)(AES_KEY_SIZE_T keySize, uint32_t *key))0x030012a9U;
+
+    return p_aesLoadKeyFromSW(keySize, key);
+}
+
+/**
+ * @brief	Loads the Initialization Vector (IV) into the AES block
+ * @param	iv	: 32-bit initialization vector
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesLoadIV(uint32_t *pIv)
+{
+    ErrorCode_t (*p_aesLoadIV)(uint32_t *pIv);
+    p_aesLoadIV = (ErrorCode_t (*)(uint32_t *pIv))0x030012fdU;
+
+    return p_aesLoadIV(pIv);
+}
+
+/**
+ * @brief	Process AES blocks (descrypt or encrypt)
+ * @param	pBlockIn	: 32-bit aligned pointer to input block of data
+ * @param	pBlockOut	: 32-bit aligned pointer to output block of data
+ * @param	numBlocks	: Number of blocks to process, block size = 128 bits
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	The AES mode and key must be setup prior to calling this function.
+ *			For encryption. the plain text is used as the input and encrypted
+ *			text is output. For descryption, plain text is output while
+ *			encrypted text is input.
+ */
+static inline ErrorCode_t aesProcess(uint32_t *pBlockIn, uint32_t *pBlockOut, uint32_t numBlocks)
+{
+    ErrorCode_t (*p_aesProcess)(uint32_t *pBlockIn, uint32_t *pBlockOut, uint32_t numBlocks);
+    p_aesProcess = (ErrorCode_t (*)(uint32_t *pBlockIn, uint32_t *pBlockOut, uint32_t numBlocks))0x030013d1U;
+
+    return p_aesProcess(pBlockIn, pBlockOut, numBlocks);
+}
+
+/**
+ * @brief	Sets the Y input of the GF128 hash used in GCM mode
+ * @param	pYGf128	: Y input of GF128 hash (4x32-bit words)
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	Calling this function will reset the hash logic.
+ */
+static inline ErrorCode_t aesWriteYInputGf128(uint32_t *pYGf128)
+{
+    ErrorCode_t (*p_aesWriteYInputGf128)(uint32_t *pYGf128);
+    p_aesWriteYInputGf128 = (ErrorCode_t (*)(uint32_t *pYGf128))0x0300132dU;
+
+    return p_aesWriteYInputGf128(pYGf128);
+}
+
+/**
+ * @brief	Reads the results of the GF128(Z) hash used in GCM mode
+ * @param	pGf128Hash	: Array of 4x32-bit words to read hash into
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	Value is undefined if AES is not present.
+ */
+static inline ErrorCode_t aesReadGf128Hash(uint32_t *pGf128Hash)
+{
+    ErrorCode_t (*p_aesReadGf128Hash)(uint32_t *pGf128Hash);
+    p_aesReadGf128Hash = (ErrorCode_t (*)(uint32_t *pGf128Hash))0x0300135dU;
+
+    return p_aesReadGf128Hash(pGf128Hash);
+}
+
+/**
+ * @brief	Reads the GCM tag
+ * @param	pGcmTag	: Array of 4x32-bit words to read GCM tage into
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	The GCM tage is an XOR value of the Output Text and GF128(Z) hash value.
+ *			Value is undefined if AES is not present.
+ */
+static inline ErrorCode_t aesReadGcmTag(uint32_t *pGcmTag)
+{
+    ErrorCode_t (*p_aesReadGcmTag)(uint32_t *pGcmTag);
+    p_aesReadGcmTag = (ErrorCode_t (*)(uint32_t *pGcmTag))0x0300138dU;
+
+    return p_aesReadGcmTag(pGcmTag);
+}
+
+/**
+ * @brief	Returns the version of the AES driver in ROM
+ * @return	Driver version, example 0x00000100 = v1.0
+ */
+static inline uint32_t aesGetDriverVersion(void)
+{
+    uint32_t (*p_aesGetDriverVersion)(void);
+    p_aesGetDriverVersion = (uint32_t (*)(void))0x030013bdU;
+
+    return p_aesGetDriverVersion();
+}
+
+/**
+ * @brief	Returns status of AES IP block (supported or not)
+ * @return	LPC_OK if enabled, ERR_SEC_AES_NOT_SUPPORTED if not supported
+ */
+static inline ErrorCode_t aesIsSupported(void)
+{
+    ErrorCode_t (*p_aesIsSupported)(void);
+    p_aesIsSupported = (ErrorCode_t (*)(void))0x0300115dU;
+
+    return p_aesIsSupported();
+}
+
+#endif /* _ROM_AES_H      Do not add any thing below this line */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_api.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_api.h
new file mode 100755
index 0000000..569bb7e
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_api.h
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_API_H_
+#define ROM_API_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stdint.h>
+#include "rom_common.h"
+#include "rom_psector.h"
+#include "flash_header.h"
+#include "rom_aes.h"
+#include "rom_efuse.h"
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.jn_romapi"
+#endif
+/*! @name Driver version */
+/*@{*/
+/*! @brief JN_ROMAPI driver version 2.0.0. */
+#define FSL_JN_ROMAPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
+/*@}*/
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/*!
+ * @brief Convert logical address into physical address, based on SYSCOM MEMORYREMAP register
+ *
+ * The chip has a remapping capability that allows to remap internal flash areas.
+ * This feature is part of the firmware update mechanism (OTA).
+ *
+ * @param  address logical address to convert
+ *
+ * @return  physical address
+ *
+ */
+static inline uint32_t BOOT_RemapAddress(uint32_t address)
+{
+    uint32_t (*p_BOOT_RemapAddress)(uint32_t address);
+    p_BOOT_RemapAddress = (uint32_t(*)(uint32_t address))0x03000dc9U;
+
+    return p_BOOT_RemapAddress(address);
+}
+
+/*! @brief IMAGE_DATA_T image node : element of single link chained list of images found in flash */
+typedef struct _image_data_t
+{
+    uint32_t version;           /*!< version number found in image  */
+    uint32_t address;           /*!< start address of image */
+    struct _image_data_t *next; /*!< pointer on next IMAGE_DATA_T in list */
+} IMAGE_DATA_T;
+
+/*! @brief IMAGE_VERIFY_T function pointer : verification function  e.g. boot_Verify_eScoreImageList */
+typedef uint32_t (*IMAGE_VERIFY_T)(IMAGE_DATA_T *list_head);
+
+/*!
+ * @brief Parse the image chained list and select the first valid entry.
+ *
+ * The image list is already sorted by version number. Compare image version against
+ * Min version read from PSECT. If it is greater than or equal to Min version, perform the
+ * RSA authentication over the image using the ket found in PFLASH if any.
+ * see IMAGE_VERIFY_T
+ * @param  list_head sorted list of images
+ *
+ * @return  selected image start address
+ *
+ */
+static inline uint32_t boot_Verify_eScoreImageList(IMAGE_DATA_T *list_head)
+{
+    uint32_t (*p_boot_Verify_eScoreImageList)(IMAGE_DATA_T * list_head);
+    p_boot_Verify_eScoreImageList = (uint32_t(*)(IMAGE_DATA_T * list_head))0x030003e5U;
+
+    return p_boot_Verify_eScoreImageList(list_head);
+}
+
+/*!
+ * @brief Search for a valid executable image between boundaries in internal flash.
+ *
+ * This function is involved in the search of a bootable image.
+ * It is called by the boot ROM on Cold boot but can be called by the Selective OTA.
+ *
+ * The application granularity parameter is read from the PSECT, this is used as the
+ * increment used to hop to next position in case of failure.
+ * The function builds up a chained list of image descriptors that it sorts by version number.
+ * The intent is that the most recent version is at the head of the list.
+ *
+ * @param  start_addr address from which to start search
+ *
+ * @param  end_addr  address from which to start search
+ *
+ * @param  signature  magic identifier : constant 0x98447902
+ *
+ * @param  IMAGE_VERIFY_T verification function pointer (see @boot_Verify_eScoreImageList)
+ *         This parameter cannot be NULL.
+ *         The implementer may opt for a version that simply returns the head of the chained list.
+ *
+ * @return  image address if valid, IMAGE_INVALID_ADDR (0xffffffff) otherwise
+ *
+ */
+static inline uint32_t BOOT_FindImage(uint32_t start_addr, uint32_t end_addr, uint32_t signature, IMAGE_VERIFY_T verify)
+{
+    uint32_t (*p_BOOT_FindImage)(uint32_t start_addr, uint32_t end_addr, uint32_t signature, IMAGE_VERIFY_T verify);
+    p_BOOT_FindImage =
+        (uint32_t(*)(uint32_t start_addr, uint32_t end_addr, uint32_t signature, IMAGE_VERIFY_T verify))0x03000519U;
+
+    return p_BOOT_FindImage(start_addr, end_addr, signature, verify);
+}
+
+/*!
+ * @brief Retrieve LPMode value that has been saved previously in retained RAM bank.
+ *
+ * This is mostly used to determine in which power mode the PMC was before reset,
+ * i.e. whether is is a cold or warm reset. This is to be invoked from ResetISR2
+ *
+ * @param  none
+ *
+ * @return  LPMode
+ *
+ */
+static inline uint32_t BOOT_GetStartPowerMode(void)
+{
+    uint32_t (*p_BOOT_GetStartPowerMode)(void);
+    p_BOOT_GetStartPowerMode = (uint32_t(*)(void))0x03000e9dU;
+
+    return p_BOOT_GetStartPowerMode();
+}
+
+/*!
+ * @brief Sets the value of stack pointer to be restored on warm boot.
+ *
+ * @param  stack_pointer address to be written in retained RAM bank so that
+ * boot ROM restores value on warm start
+ *
+ * @return  none
+ *
+ */
+static inline void BOOT_SetResumeStackPointer(uint32_t stack_pointer)
+{
+    void (*p_BOOT_SetResumeStackPointer)(uint32_t stack_pointer);
+    p_BOOT_SetResumeStackPointer = (void (*)(uint32_t stack_pointer))0x03000ea9U;
+
+    p_BOOT_SetResumeStackPointer(stack_pointer);
+}
+
+/*!
+ * @brief Retrieve Internal flash address and size
+ *
+ * The internal flash start address is necessarily 0.
+ * Its size may vary depending on chip options.
+ * The size returned is the number of bytes usable for program and data.
+ * The maximum possible value is 0x9dc00.
+ *
+ * @param address pointer on location to store returned address
+ *
+ * @param size pointer on location to store returned size
+ *
+ * @return  *address is 0x00000000UL and *size is up to 0x9dc00
+ *
+ */
+static inline void ROM_GetFlash(uint32_t *address, uint32_t *size)
+{
+    void (*p_ROM_GetFlash)(uint32_t * address, uint32_t * size);
+    p_ROM_GetFlash = (void (*)(uint32_t * address, uint32_t * size))0x03000e0dU;
+
+    p_ROM_GetFlash(address, size);
+}
+
+/*!
+ * @brief Retrieve SRAM0 address and size
+ *
+ * @param address pointer on location to store returned address
+ *
+ * @param size pointer on location to store returned size
+ *
+ * @return  *address is 0x04000000UL and *size is 88k (0x16000)
+ *
+ */
+static inline void ROM_GetSRAM0(uint32_t *address, uint32_t *size)
+{
+    void (*p_ROM_GetSRAM0)(uint32_t * address, uint32_t * size);
+    p_ROM_GetSRAM0 = (void (*)(uint32_t * address, uint32_t * size))0x03000e21U;
+
+    p_ROM_GetSRAM0(address, size);
+}
+
+/*!
+ * @brief Retrieve SRAM1 address and size.
+ *        SRAM1 presence is optional depending on chip variant
+ *
+ * @param address pointer on location to store returned address
+ *
+ * @param size pointer on location to store returned size
+ *
+ * @return  if SRAM1 not present *address is 0 and *size is 0,
+ *          otherwise *address is  0x04020000UL and *size is up to 64k (0x10000)
+ */
+static inline void ROM_GetSRAM1(uint32_t *address, uint32_t *size)
+{
+    void (*p_ROM_GetSRAM1)(uint32_t * address, uint32_t * size);
+    p_ROM_GetSRAM1 = (void (*)(uint32_t * address, uint32_t * size))0x03000e35U;
+
+    p_ROM_GetSRAM1(address, size);
+}
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_API_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_common.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_common.h
new file mode 100755
index 0000000..f0be8b7
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_common.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_COMMON_H_
+#define ROM_COMMON_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stdbool.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/* Define ROM compilation for ES2 - required for lowpower API as it supports ES1/ES2 compilation */
+//#define CPU_JN518X_REV 2
+
+#ifdef ROM_BUILD
+#define ROM_API __attribute__((section(".text.api")))
+#else
+#ifdef __MINGW32__
+#define ROM_API
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) || (defined(__ICCARM__))
+#define ROM_API
+#else
+#define ROM_API __attribute__((long_call))
+#endif
+#endif
+
+#ifndef WEAK
+#define WEAK __attribute__((weak))
+#endif
+
+#ifdef __CDT_PARSER__
+#define STATIC_ASSERT(value, message)
+#else
+#define STATIC_ASSERT _Static_assert
+#endif
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_COMMON_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_efuse.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_efuse.h
new file mode 100755
index 0000000..1f1badb
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_efuse.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_EFUSE_H_
+#define ROM_EFUSE_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <rom_common.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+static inline bool efuse_ReadBit(uint8_t efuse_bitpos)
+{
+    bool (*p_efuse_ReadBit)(uint8_t bitpos);
+    p_efuse_ReadBit = (bool (*)(uint8_t bitpos))0x03001671U;
+
+    return p_efuse_ReadBit(efuse_bitpos);
+}
+/****************************************************************************/
+/***        Exported Variables
+ ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_EFUSE_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_lowpower.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_lowpower.h
new file mode 100755
index 0000000..9651e35
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_lowpower.h
@@ -0,0 +1,508 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ROM_LOWPOWER_H_
+#define __ROM_LOWPOWER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rom_common.h>
+#include <rom_pmc.h>
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/*******************
+ * EXPORTED MACROS  *
+ ********************/
+
+/* Low Power modes  */
+#define LOWPOWER_CFG_MODE_INDEX 0
+#define LOWPOWER_CFG_MODE_MASK (0x3UL << LOWPOWER_CFG_MODE_INDEX)
+
+#define LOWPOWER_CFG_XTAL32MSTARTENA_INDEX 2
+#define LOWPOWER_CFG_XTAL32MSTARTENA_MASK (0x1UL << LOWPOWER_CFG_XTAL32MSTARTENA_INDEX)
+
+#define LOWPOWER_CFG_FLASHPWDNMODE_INDEX 4
+#define LOWPOWER_CFG_FLASHPWDNMODE_MASK (0x1UL << LOWPOWER_CFG_FLASHPWDNMODE_INDEX)
+
+#define LOWPOWER_CFG_SRAMPWDNMODE_INDEX 6
+#define LOWPOWER_CFG_SRAMPWDNMODE_MASK (0x1UL << LOWPOWER_CFG_SRAMPWDNMODE_INDEX)
+
+#define LOWPOWER_CFG_PDRUNCFG_DISCARD_INDEX 7
+#define LOWPOWER_CFG_PDRUNCFG_DISCARD_MASK (0x1UL << LOWPOWER_CFG_PDRUNCFG_DISCARD_INDEX)
+
+#define LOWPOWER_CFG_WFI_NOT_WFE_INDEX 8
+#define LOWPOWER_CFG_WFI_NOT_WFE_MASK (0x1UL << LOWPOWER_CFG_WFI_NOT_WFE_INDEX)
+
+#define LOWPOWER_CFG_LDOMEM_FORCE_ENABLE_INDEX 9
+#define LOWPOWER_CFG_LDOMEM_FORCE_ENABLE_MASK (0x1UL << LOWPOWER_CFG_LDOMEM_FORCE_ENABLE_INDEX)
+
+#define LOWPOWER_CFG_LDOFLASHCORE_UPDATE_INDEX 10
+#define LOWPOWER_CFG_LDOFLASHCORE_UPDATE_MASK (0x1UL << LOWPOWER_CFG_LDOFLASHCORE_UPDATE_INDEX)
+
+/* Delay to wakeup the flash after the LDO Flash Core has been set up to active voltage : 0: 19us, then increment by
+ * 4.75us steps */
+#define LOWPOWER_CFG_LDOFLASHCORE_DELAY_INDEX 11
+#define LOWPOWER_CFG_LDOFLASHCORE_DELAY_MASK (0x7UL << LOWPOWER_CFG_LDOFLASHCORE_DELAY_INDEX)
+
+#define LOWPOWER_CFG_MODE_ACTIVE 0        /*!< ACTIVE mode */
+#define LOWPOWER_CFG_MODE_DEEPSLEEP 1     /*!< DEEP SLEEP mode */
+#define LOWPOWER_CFG_MODE_POWERDOWN 2     /*!< POWER DOWN mode */
+#define LOWPOWER_CFG_MODE_DEEPPOWERDOWN 3 /*!< DEEP POWER DOWN mode */
+
+#define LOWPOWER_CFG_XTAL32MSTART_DISABLE \
+    0 /*!< Disable Crystal 32 MHz automatic start when waking up from POWER DOWN and DEEP POWER DOWN modes */
+#define LOWPOWER_CFG_XTAL32MSTART_ENABLE \
+    1 /*!< Enable Crystal 32 MHz automatic start when waking up from POWER DOWN and DEEP POWER DOWN modes */
+
+#define LOWPOWER_CFG_FLASHPWDNMODE_FLASHPWND \
+    0 /*!< Power down the Flash only (send CMD_POWERDOWN to Flash controller). Only valid in DEEP SLEEP mode */
+#define LOWPOWER_CFG_FLASHPWDNMODE_LDOSHUTOFF                                                                         \
+    1 /*!< Power down the Flash ((send CMD_POWERDOWN to Flash controller) and shutoff both Flash LDOs (Core and NV) \ \
+         (only valid in DEEP SLEEP mode) */
+
+/**
+ * @brief Analog Power Domains (analog components in Power Management Unit) Low Power Modes control
+ */
+#define LOWPOWER_PMUPWDN_DCDC (1UL << 0)     /*!< Power Down DCDC Converter  */
+#define LOWPOWER_PMUPWDN_BIAS (1UL << 1)     /*!< Power Down all Bias and references */
+#define LOWPOWER_PMUPWDN_LDOMEM (1UL << 2)   /*!< Power Down Memories LDO  */
+#define LOWPOWER_PMUPWDN_BODVBAT (1UL << 3)  /*!< Power Down VBAT Brown Out Detector */
+#define LOWPOWER_PMUPWDN_FRO192M (1UL << 4)  /*!< Power Down FRO 192 MHz  */
+#define LOWPOWER_PMUPWDN_FRO1M (1UL << 5)    /*!< Power Down FRO 1 MHz  */
+#define LOWPOWER_PMUPWDN_GPADC (1UL << 22)   /*!< Power Down General Purpose ADC */
+#define LOWPOWER_PMUPWDN_BODMEM (1UL << 23)  /*!< Power Down Memories Brown Out Detector */
+#define LOWPOWER_PMUPWDN_BODCORE (1UL << 24) /*!< Power Down Core Logic Brown Out Detector */
+#define LOWPOWER_PMUPWDN_FRO32K (1UL << 25)  /*!< Power Down FRO 32 KHz */
+#define LOWPOWER_PMUPWDN_XTAL32K (1UL << 26) /*!< Power Down Crystal 32 KHz */
+#define LOWPOWER_PMUPWDN_ANACOMP (1UL << 27) /*!< Power Down Analog Comparator */
+
+#define LOWPOWER_PMUPWDN_XTAL32M (1UL << 28)    /*!< Power Down Crystal 32 MHz */
+#define LOWPOWER_PMUPWDN_TEMPSENSOR (1UL << 29) /*!< Power Down Temperature Sensor   */
+
+/**
+ * @brief Digital Power Domains Low Power Modes control
+ */
+#define LOWPOWER_DIGPWDN_FLASH                                                                                     \
+    (1UL << 6) /*!< Power Down Flash Power Domain (Flash Macro, Flash Controller and/or FLash LDOs, depending on \ \
+                   LOWPOWER_CFG_FLASHPWDNMODE parameter) */
+#define LOWPOWER_DIGPWDN_COMM0 (1UL << 7) /*!< Power Down Digital COMM0 power domain (USART0, I2C0 and SPI0) */
+#define LOWPOWER_DIGPWDN_MCU_RET                                                                                    \
+    (1UL << 8) /*!< Power Down MCU Retention Power Domain (Disable Zigbee IP retention, ES1:Disable CPU retention \ \
+                   flip-flops) */
+#define LOWPOWER_DIGPWDN_ZIGBLE_RET \
+    (1UL << 9) /*!< Power Down ZIGBEE/BLE retention Power Domain (Disable ZIGBEE/BLE retention flip-flops) */
+
+#define LOWPOWER_DIGPWDN_SRAM0_INDEX 10
+#define LOWPOWER_DIGPWDN_SRAM0 \
+    (1UL << LOWPOWER_DIGPWDN_SRAM0_INDEX)   /*!< Power Down SRAM 0  instance [Bank 0, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM1 (1UL << 11)  /*!< Power Down SRAM 1  instance [Bank 0, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM2 (1UL << 12)  /*!< Power Down SRAM 2  instance [Bank 0, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM3 (1UL << 13)  /*!< Power Down SRAM 3  instance [Bank 0, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM4 (1UL << 14)  /*!< Power Down SRAM 4  instance [Bank 0,  8 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM5 (1UL << 15)  /*!< Power Down SRAM 5  instance [Bank 0,  8 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM6 (1UL << 16)  /*!< Power Down SRAM 6  instance [Bank 0,  4 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM7 (1UL << 17)  /*!< Power Down SRAM 7  instance [Bank 0,  4 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM8 (1UL << 18)  /*!< Power Down SRAM 8  instance [Bank 1, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM9 (1UL << 19)  /*!< Power Down SRAM 9  instance [Bank 1, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM10 (1UL << 20) /*!< Power Down SRAM 10 instance [Bank 1, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM11 (1UL << 21) /*!< Power Down SRAM 11 instance [Bank 1, 16 KB], (no retention) */
+
+#define LOWPOWER_DIGPWDN_SRAM_ALL_MASK                                                                   \
+    (LOWPOWER_DIGPWDN_SRAM0 | LOWPOWER_DIGPWDN_SRAM1 | LOWPOWER_DIGPWDN_SRAM2 | LOWPOWER_DIGPWDN_SRAM3 | \
+     LOWPOWER_DIGPWDN_SRAM4 | LOWPOWER_DIGPWDN_SRAM5 | LOWPOWER_DIGPWDN_SRAM6 | LOWPOWER_DIGPWDN_SRAM7 | \
+     LOWPOWER_DIGPWDN_SRAM8 | LOWPOWER_DIGPWDN_SRAM9 | LOWPOWER_DIGPWDN_SRAM10 | LOWPOWER_DIGPWDN_SRAM11)
+
+#define LOWPOWER_DIGPWDN_IO_INDEX 30
+#define LOWPOWER_DIGPWDN_IO (1UL << LOWPOWER_DIGPWDN_IO_INDEX) /*!< Power Down   */
+
+#define LOWPOWER_DIGPWDN_NTAG_FD_INDEX 31
+#define LOWPOWER_DIGPWDN_NTAG_FD \
+    (1UL << LOWPOWER_DIGPWDN_NTAG_FD_INDEX) /*!< NTAG FD field detect Disable - need the IO source to be set too */
+
+/**
+ * @brief LDO Voltage control in Low Power Modes
+ */
+
+#define LOWPOWER_SRAM_LPMODE_MASK (0xFUL)
+#define LOWPOWER_SRAM_LPMODE_ACTIVE (0x6UL)    /*!<  */
+#define LOWPOWER_SRAM_LPMODE_SLEEP (0xFUL)     /*!<  */
+#define LOWPOWER_SRAM_LPMODE_DEEPSLEEP (0x8UL) /*!<  */
+#define LOWPOWER_SRAM_LPMODE_SHUTDOWN (0x9UL)  /*!<  */
+#define LOWPOWER_SRAM_LPMODE_POWERUP (0xAUL)   /*!<  */
+
+/**
+ * @brief LDO Voltage control in Low Power Modes
+ */
+#define LOWPOWER_VOLTAGE_LDO_PMU_INDEX 0
+#define LOWPOWER_VOLTAGE_LDO_PMU_MASK (0x1FUL << LOWPOWER_VOLTAGE_LDO_PMU_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_MEM_INDEX 5
+#define LOWPOWER_VOLTAGE_LDO_MEM_MASK (0x1FUL << LOWPOWER_VOLTAGE_LDO_MEM_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_CORE_INDEX 10
+#define LOWPOWER_VOLTAGE_LDO_CORE_MASK (0x7UL << LOWPOWER_VOLTAGE_LDO_CORE_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_FLASH_CORE_INDEX 13
+#define LOWPOWER_VOLTAGE_LDO_FLASH_CORE_MASK (0x7UL << LOWPOWER_VOLTAGE_LDO_FLASH_CORE_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_FLASH_NV_INDEX 16
+#define LOWPOWER_VOLTAGE_LDO_FLASH_NV_MASK (0x7UL << LOWPOWER_VOLTAGE_LDO_FLASH_NV_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX 19
+#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_MASK (0x1FUL << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX 24
+#define LOWPOWER_VOLTAGE_LDO_MEM_BOOST_MASK (0x1FUL << LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX)
+/* Only for ES2 but defined it for ES1 for easier power driver writing (has no effect on ES1) */
+#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_INDEX 29
+#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_MASK (0x1UL << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_INDEX)
+
+/**
+ * @brief Low Power Modes Wake up Interrupt sources
+ */
+#define LOWPOWER_WAKEUPSRCINT0_SYSTEM_IRQ \
+    (1UL << 0) /*!< BOD, Watchdog Timer, Flash controller, Firewall [DEEP SLEEP] BOD [POWER_DOWN]*/
+#define LOWPOWER_WAKEUPSRCINT0_DMA_IRQ (1UL << 1)       /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_GINT_IRQ (1UL << 2)      /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_IRBLASTER_IRQ (1UL << 3) /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PINT0_IRQ (1UL << 4)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PINT1_IRQ (1UL << 5)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PINT2_IRQ (1UL << 6)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PINT3_IRQ (1UL << 7)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_SPIFI_IRQ (1UL << 8)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_TIMER0_IRQ (1UL << 9)    /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_TIMER1_IRQ (1UL << 10)   /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_USART0_IRQ (1UL << 11)   /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT0_USART1_IRQ (1UL << 12)   /*!< [DEEP SLEEP]  */
+#define LOWPOWER_WAKEUPSRCINT0_I2C0_IRQ (1UL << 13)     /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT0_I2C1_IRQ (1UL << 14)     /*!< [DEEP SLEEP]  */
+#define LOWPOWER_WAKEUPSRCINT0_SPI0_IRQ (1UL << 15)     /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT0_SPI1_IRQ (1UL << 16)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM0_IRQ (1UL << 17)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM1_IRQ (1UL << 18)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM2_IRQ (1UL << 19)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM3_IRQ (1UL << 20)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM4_IRQ (1UL << 21)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM5_IRQ (1UL << 22)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM6_IRQ (1UL << 23)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM7_IRQ (1UL << 24)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM8_IRQ (1UL << 25)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM9_IRQ (1UL << 26)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM10_IRQ (1UL << 27)    /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_I2C2_IRQ (1UL << 28)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_RTC_IRQ (1UL << 29)      /*!< [DEEP SLEEP, POWER DOWN]  */
+#define LOWPOWER_WAKEUPSRCINT0_NFCTAG_IRQ (1UL << 30)   /*!< [DEEP SLEEP]  */
+#define LOWPOWER_WAKEUPSRCINT0_MAILBOX_IRQ \
+    (1UL << 31) /*!< Mailbox, Wake-up from DEEP SLEEP and POWER DOWN low power mode [DEEP SLEEP, POWER DOWN] */
+
+#define LOWPOWER_WAKEUPSRCINT1_ADC_SEQA_IRQ (1UL << 0)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ADC_SEQB_IRQ (1UL << 1)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ADC_THCMP_OVR_IRQ (1UL << 2)   /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_DMIC_IRQ (1UL << 3)            /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_HWVAD_IRQ (1UL << 4)           /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_DP_IRQ (1UL << 5)          /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_DP0_IRQ (1UL << 6)         /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_DP1_IRQ (1UL << 7)         /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_DP2_IRQ (1UL << 8)         /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_LL_ALL_IRQ (1UL << 9)      /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ZIGBEE_MAC_IRQ (1UL << 10)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ZIGBEE_MODEM_IRQ (1UL << 11)   /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_RFP_TMU_IRQ (1UL << 12)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_RFP_AGC_IRQ (1UL << 13)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ISO7816_IRQ (1UL << 14)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ANA_COMP_IRQ (1UL << 15)       /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_WAKE_UP_TIMER0_IRQ (1UL << 16) /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT1_WAKE_UP_TIMER1_IRQ (1UL << 17) /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_WAKE_TIMER_IRQ (1UL << 22) /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_OSC_EN_IRQ (1UL << 23)     /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT1_IO_IRQ (1UL << 31)             /*!< [POWER DOWN, DEEP DOWN]  */
+
+/**
+ * @brief Sleep Postpone
+ */
+#define LOWPOWER_SLEEPPOSTPONE_FORCED \
+    (1UL << 0) /*!< Forces postpone of power down modes in case the processor request low power mode*/
+#define LOWPOWER_SLEEPPOSTPONE_PERIPHERALS                                                                             \
+    (1UL << 1) /*!< USART0, USART1, SPI0, SPI1, I2C0, I2C1, I2C2 interrupts can postpone power down modes in case an \ \
+                   interrupt is pending when the processor request low power mode */
+#define LOWPOWER_SLEEPPOSTPONE_DMIC                                                                                   \
+    (1UL << 0) /*!< DMIC interrupt can postpone power down modes in case an interrupt is pending when the processor \ \
+                   request low power mode */
+#define LOWPOWER_SLEEPPOSTPONE_SDMA                                                                               \
+    (1UL << 1) /*!< System DMA interrupt can postpone power down modes in case an interrupt is pending when the \ \
+                   processor request low power mode */
+#define LOWPOWER_SLEEPPOSTPONE_NFCTAG                                                                          \
+    (1UL << 0) /*!< NFC Tag interrupt can postpone power down modes in case an interrupt is pending when the \ \
+                   processor request low power mode */
+#define LOWPOWER_SLEEPPOSTPONE_BLEOSC                                                                             \
+    (1UL << 1) /*!< BLE_OSC_EN interrupt can postpone power down modes in case an interrupt is pending when the \ \
+                   processor request low power mode */
+
+/**
+ * @brief Wake up I/O sources
+ */
+#define LOWPOWER_WAKEUPIOSRC_PIO0 (1UL << 0)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO1 (1UL << 1)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO2 (1UL << 2)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO3 (1UL << 3)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO4 (1UL << 4)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO5 (1UL << 5)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO6 (1UL << 6)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO7 (1UL << 7)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO8 (1UL << 8)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO9 (1UL << 9)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO10 (1UL << 10) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO11 (1UL << 11) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO12 (1UL << 12) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO13 (1UL << 13) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO14 (1UL << 14) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO15 (1UL << 15) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO16 (1UL << 16) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO17 (1UL << 17) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO18 (1UL << 18) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO19 (1UL << 19) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO20 (1UL << 20) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO21 (1UL << 21) /*!<    */
+
+#ifndef LOWPOWER_API_ES1_ONLY
+/* For NTAG FD wakeup source, SW shall enable virtual IO 22 in */
+#define LOWPOWER_WAKEUPIOSRC_NTAG_FD (1UL << 22) /*!<    */
+#endif
+
+/**
+ * @brief I/O whose state must be kept in Power Down mode
+ */
+#define LOWPOWER_GPIOLATCH_PIO0 (1UL << 0)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO1 (1UL << 1)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO2 (1UL << 2)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO3 (1UL << 3)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO4 (1UL << 4)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO5 (1UL << 5)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO6 (1UL << 6)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO7 (1UL << 7)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO8 (1UL << 8)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO9 (1UL << 9)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO10 (1UL << 10) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO11 (1UL << 11) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO12 (1UL << 12) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO13 (1UL << 13) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO14 (1UL << 14) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO15 (1UL << 15) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO16 (1UL << 16) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO17 (1UL << 17) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO18 (1UL << 18) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO19 (1UL << 19) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO20 (1UL << 20) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO21 (1UL << 21) /*!<    */
+
+/**
+ * @brief Wake up timers configuration in Low Power Modes
+ */
+#define LOWPOWER_TIMERCFG_ENABLE_INDEX 0
+#define LOWPOWER_TIMERCFG_ENABLE_MASK (0x1UL << LOWPOWER_TIMERCFG_ENABLE_INDEX)
+#define LOWPOWER_TIMERCFG_TIMER_INDEX 1
+#define LOWPOWER_TIMERCFG_TIMER_MASK (0x7UL << LOWPOWER_TIMERCFG_TIMER_INDEX)
+#define LOWPOWER_TIMERCFG_OSC32K_INDEX 4
+#define LOWPOWER_TIMERCFG_OSC32K_MASK (0x1UL << LOWPOWER_TIMERCFG_OSC32K_INDEX)
+#define LOWPOWER_TIMERCFG_2ND_ENABLE_INDEX 5
+#define LOWPOWER_TIMERCFG_2ND_ENABLE_MASK (0x1UL << LOWPOWER_TIMERCFG_2ND_ENABLE_INDEX)
+#define LOWPOWER_TIMERCFG_2ND_TIMER_INDEX 6
+#define LOWPOWER_TIMERCFG_2ND_TIMER_MASK (0x7UL << LOWPOWER_TIMERCFG_2ND_TIMER_INDEX)
+
+#define LOWPOWER_TIMERCFG_TIMER_ENABLE 1 /*!< Wake Timer Enable */
+
+/**
+ * @brief Primary Wake up timers configuration in Low Power Modes
+ */
+#define LOWPOWER_TIMERCFG_TIMER_WAKEUPTIMER0 0   /*!< Zigbee Wake up Counter 0 used as wake up source */
+#define LOWPOWER_TIMERCFG_TIMER_WAKEUPTIMER1 1   /*!< Zigbee Wake up Counter 1 used as wake up source */
+#define LOWPOWER_TIMERCFG_TIMER_BLEWAKEUPTIMER 2 /*!< BLE Wake up Counter used as wake up source */
+#define LOWPOWER_TIMERCFG_TIMER_RTC1KHZ 3        /*!< 1 KHz Real Time Counter (RTC) used as wake up source */
+#define LOWPOWER_TIMERCFG_TIMER_RTC1HZ 4         /*!< 1 Hz Real Time Counter (RTC) used as wake up source */
+
+/**
+ * @brief Secondary Wake up timers configuration in Low Power Modes
+ */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_WAKEUPTIMER0 0   /*!< Zigbee Wake up Counter 0 used as secondary wake up source */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_WAKEUPTIMER1 1   /*!< Zigbee Wake up Counter 1 used as secondary wake up source */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_BLEWAKEUPTIMER 2 /*!< BLE Wake up Counter used as secondary wake up source */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_RTC1KHZ 3 /*!< 1 KHz Real Time Counter (RTC) used as secondary wake up source */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_RTC1HZ 4  /*!< 1 Hz Real Time Counter (RTC) used as secondary wake up source */
+
+#define LOWPOWER_TIMERCFG_OSC32K_FRO32KHZ 0  /*!< Wake up Timers uses FRO 32 KHz as clock source */
+#define LOWPOWER_TIMERCFG_OSC32K_XTAL32KHZ 1 /*!< Wake up Timers uses Chrystal 32 KHz as clock source */
+
+/**
+ * @brief BLE Wake up timers configuration in Low Power Modes
+ */
+#define LOWPOWER_TIMERBLECFG_RADIOEN_INDEX 0
+#define LOWPOWER_TIMERBLECFG_RADIOEN_MASK (0x3FFUL << LOWPOWER_TIMERBLECFG_RADIOEN_INDEX)
+#define LOWPOWER_TIMERBLECFG_OSCEN_INDEX 10
+#define LOWPOWER_TIMERBLECFG_OSCEN_MASK (0x7FFUL << LOWPOWER_TIMERBLECFG_OSCEN_INDEX)
+
+/** @brief	Low Power Main Structure */
+typedef struct
+{                           /*     */
+    uint32_t CFG;           /*!< Low Power Mode Configuration, and miscallenous options  */
+    uint32_t PMUPWDN;       /*!< Analog Power Domains (analog components in Power Management Unit) Low Power Modes  */
+    uint32_t DIGPWDN;       /*!< Digital Power Domains Low Power Modes */
+    uint32_t VOLTAGE;       /*!< LDO Voltage control in Low Power Modes */
+    uint32_t WAKEUPSRCINT0; /*!< Wake up sources Interrupt control */
+    uint32_t WAKEUPSRCINT1; /*!< Wake up sources Interrupt control */
+    uint32_t SLEEPPOSTPONE; /*!< Interrupt that can postpone power down modes in case an interrupt is pending when the
+                               processor request deepsleep */
+    uint32_t WAKEUPIOSRC;   /*!< Wake up I/O sources */
+    uint32_t GPIOLATCH;     /*!< I/Os which outputs level must be kept (in Power Down  mode)*/
+    uint32_t TIMERCFG;      /*!< Wake up timers configuration */
+    uint32_t TIMERBLECFG;   /*!< BLE wake up timer configuration (OSC_EN and RADIO_EN) */
+    uint32_t TIMERCOUNTLSB; /*!< Wake up Timer LSB*/
+    uint32_t TIMERCOUNTMSB; /*!< Wake up Timer MSB*/
+    uint32_t TIMER2NDCOUNTLSB; /*!< Second Wake up Timer LSB*/
+    uint32_t TIMER2NDCOUNTMSB; /*!< Second Wake up Timer MSB*/
+
+} LPC_LOWPOWER_T;
+
+/** @brief	Low Power Main Structure */
+typedef struct
+{                         /*   */
+    uint8_t LDOPMU;       /*!< Always-ON domain LDO voltage configuration */
+    uint8_t LDOPMUBOOST;  /*!< Always-ON domain LDO Boost voltage configuration */
+    uint8_t LDOMEM;       /*!< Memories LDO voltage configuration */
+    uint8_t LDOMEMBOOST;  /*!< Memories LDO Boost voltage configuration */
+    uint8_t LDOCORE;      /*!< Core Logic domain LDO voltage configuration */
+    uint8_t LDOFLASHNV;   /*!< Flash NV domain LDO voltage configuration */
+    uint8_t LDOFLASHCORE; /*!< Flash Core domain LDO voltage configuration */
+    uint8_t LDOADC;       /*!< General Purpose ADC LDO voltage configuration */
+#ifndef LOWPOWER_API_ES1_ONLY
+    uint8_t LDOPMUBOOST_ENABLE; /*!< Force Boost activation on LDOPMU */
+#endif
+} LPC_LOWPOWER_LDOVOLTAGE_T;
+
+/**
+ * @brief	Configure Wake or RTC timers. used for testing only
+ * @param	p_lowpower_cfg: pointer to a structure that contains all low power mode parameters
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_SetUpLowPowerModeWakeUpTimer(LPC_LOWPOWER_T *p_lowpower_cfg)
+{
+    void (*p_Chip_LOWPOWER_SetUpLowPowerModeWakeUpTimer)(LPC_LOWPOWER_T * p_lowpower_cfg);
+    p_Chip_LOWPOWER_SetUpLowPowerModeWakeUpTimer = (void (*)(LPC_LOWPOWER_T * p_lowpower_cfg))0x030038d1U;
+
+    p_Chip_LOWPOWER_SetUpLowPowerModeWakeUpTimer(p_lowpower_cfg);
+}
+/**
+ * @brief	Configure CPU and System Bus clock frequency
+ * @param	Frequency	:
+ * @return	Nothing
+ */
+static inline int Chip_LOWPOWER_SetSystemFrequency(uint32_t frequency)
+{
+    int (*p_Chip_LOWPOWER_SetSystemFrequency)(uint32_t frequency);
+    p_Chip_LOWPOWER_SetSystemFrequency = (int (*)(uint32_t frequency))0x03003d55U;
+
+    return p_Chip_LOWPOWER_SetSystemFrequency(frequency);
+}
+
+/**
+ * @brief	Configure Memory instances Low Power Mode
+ * @param	p_sram_instance: SRAM instance number, between 0 and 11.
+ * @param	p_sram_lp_mode : Low power mode : LOWPOWER_SRAM_LPMODE_ACTIVE, LOWPOWER_SRAM_LPMODE_SLEEP,
+ * LOWPOWER_SRAM_LPMODE_DEEPSLEEP, LOWPOWER_SRAM_LPMODE_SHUTDOWN
+ * @return	Status code
+ */
+static inline int Chip_LOWPOWER_SetMemoryLowPowerMode(uint32_t p_sram_instance, uint32_t p_sram_lp_mode)
+{
+    int (*p_Chip_LOWPOWER_SetMemoryLowPowerMode)(uint32_t p_sram_instance, uint32_t p_sram_lp_mode);
+    p_Chip_LOWPOWER_SetMemoryLowPowerMode = (int (*)(uint32_t p_sram_instance, uint32_t p_sram_lp_mode))0x03003d89U;
+
+    return p_Chip_LOWPOWER_SetMemoryLowPowerMode(p_sram_instance, p_sram_lp_mode);
+}
+
+/**
+ * @brief	Get System Voltages
+ * @param	p_ldo_voltage: pointer to a structure to fill with current voltages on the chip
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_GetSystemVoltages(LPC_LOWPOWER_LDOVOLTAGE_T *p_ldo_voltage)
+{
+    void (*p_Chip_LOWPOWER_GetSystemVoltages)(LPC_LOWPOWER_LDOVOLTAGE_T * p_ldo_voltage);
+    p_Chip_LOWPOWER_GetSystemVoltages = (void (*)(LPC_LOWPOWER_LDOVOLTAGE_T * p_ldo_voltage))0x03003de1U;
+
+    p_Chip_LOWPOWER_GetSystemVoltages(p_ldo_voltage);
+}
+
+/**
+ * @brief	Configure System Voltages
+ * @param	p_ldo_voltage: pointer to a structure that contains new voltages to be applied
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_SetSystemVoltages(LPC_LOWPOWER_LDOVOLTAGE_T *p_ldo_voltage)
+{
+    void (*p_Chip_LOWPOWER_SetSystemVoltages)(LPC_LOWPOWER_LDOVOLTAGE_T * p_ldo_voltage);
+    p_Chip_LOWPOWER_SetSystemVoltages = (void (*)(LPC_LOWPOWER_LDOVOLTAGE_T * p_ldo_voltage))0x03003e99U;
+
+    p_Chip_LOWPOWER_SetSystemVoltages(p_ldo_voltage);
+}
+
+/**
+ * @brief	Configure and enters in low power mode
+ * @param	p_lowpower_cfg: pointer to a structure that contains all low power mode parameters
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_SetLowPowerMode(LPC_LOWPOWER_T *p_lowpower_cfg)
+{
+    void (*p_Chip_LOWPOWER_SetLowPowerMode)(LPC_LOWPOWER_T * p_lowpower_cfg);
+    p_Chip_LOWPOWER_SetLowPowerMode = (void (*)(LPC_LOWPOWER_T * p_lowpower_cfg))0x0300404dU;
+
+    p_Chip_LOWPOWER_SetLowPowerMode(p_lowpower_cfg);
+}
+
+/**
+ * @brief	Perform a Full chip reset using Software reset bit in PMC
+ *
+ *  Power down the flash then perform the full chip reset as POR or Watchdog do,
+ *  The reset includes JTAG debugger, Digital units and Analog modules.
+ *  Use the Software reset bit in PMC
+ *
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_ChipSoftwareReset(void)
+{
+    void (*p_Chip_LOWPOWER_ChipSoftwareReset)(void);
+    p_Chip_LOWPOWER_ChipSoftwareReset = (void (*)(void))0x03003fa1U;
+
+    p_Chip_LOWPOWER_ChipSoftwareReset();
+}
+
+/**
+ * @brief	Perform a digital System reset
+ *
+ *  Power down the flash then perform the Full chip reset as POR or Watchdog,
+ *  The reset includes the digital units but excludes the JTAG debugger, and the analog modules.
+ *  Use the system reset bit in PMC and ARM reset
+ *
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_ArmSoftwareReset(void)
+{
+    void (*p_Chip_LOWPOWER_ArmSoftwareReset)(void);
+    p_Chip_LOWPOWER_ArmSoftwareReset = (void (*)(void))0x0300400dU;
+
+    p_Chip_LOWPOWER_ArmSoftwareReset();
+}
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LOWPOWER_JN518X_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_mpu.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_mpu.h
new file mode 100755
index 0000000..2f40ae7
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_mpu.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _ROM_MPU_H_
+#define _ROM_MPU_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <rom_common.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+/*! @brief bits for access right */
+#define RD_RIGHT (1 << 0)
+#define WR_RIGHT (1 << 1)
+#define X_RIGHT (1 << 2)
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/*! @brief enum MpuRegion_t index of ARM CM4 MPU regions
+ *  The MPU can describe up to 8 region rules.
+ *  Note that a higher order rule prevails over the lower ones.
+ * The boot ROM makes use of upper order rules : 5 .. 7.
+ * Rule 0 is a 'background' rule that opens the whole memory plane.
+ */
+enum MpuRegion_t
+{
+    MPU_REGION_0, /**< Boot Reserved: background rule */
+    MPU_REGION_1, /**< General purpose rule */
+    MPU_REGION_2, /**< General purpose rule */
+    MPU_REGION_3, /**< General purpose rule */
+    MPU_REGION_4, /**< General purpose rule */
+    MPU_APP_LAST_REGION = MPU_REGION_4,
+    MPU_REGION_5, /**< Boot Reserved */
+    MPU_REGION_6, /**< Boot Reserved */
+    MPU_REGION_7, /**< Boot Reserved */
+    MPU_REGIONS_NB
+};
+
+typedef struct __MPU_reg_settings_t
+{
+    uint32_t rbar;
+    uint32_t rasr;
+} MPU_reg_settings_t;
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+/*!
+ * @brief This function is used to grant access to the pSector region.
+ *
+ * Note: The pSector region is 'special' because counter intuitively it requires Write
+ * access in order to be able to read from it using the flash controller indirect method.
+ * The previosuly applied policy.
+ * pSector region is protected under rule 7 (highest precedence).
+ * The previous rule 7 is saved in RAM before changing it.
+ *
+ * @param  addr: address of area to grant access to.
+ * @param  sz:   size in number of bytes of area.
+ * @param  save_rule: save a copy of previous rule
+ * @return  -1 if failure, if succesful return the size of the region.
+ *
+ */
+static inline int MPU_pSectorGrantAccessRights(uint32_t addr, size_t sz, MPU_reg_settings_t *save_rule)
+{
+    int (*p_MPU_pSectorGrantAccessRights)(uint32_t addr, size_t sz, MPU_reg_settings_t * save_rule);
+    p_MPU_pSectorGrantAccessRights = (int (*)(uint32_t addr, size_t sz, MPU_reg_settings_t * save_rule))0x030017e5U;
+
+    return p_MPU_pSectorGrantAccessRights(addr, sz, save_rule);
+}
+
+/*!
+ * @brief This function is used to withdraw access to the pSector region.
+ *
+ * The pSector region is 'special' because counter intuitively it requires Write
+ * access in order to be able to read from it using the flash controller indirect method.
+ *
+ * @param  save_rule: pointer on RAM MPU_reg_settings_t structure saved by MPU_pSectorGrantAccessRights
+ *         used to restore previous settings of region 7 and restrict access to pSector.
+ *
+ * @return  -1 if failure, if succesful return the size of the region.
+ *
+ */
+static inline int MPU_pSectorWithdrawAccessRights(MPU_reg_settings_t *save_rule)
+{
+    int (*p_MPU_pSectorWithdrawAccessRights)(MPU_reg_settings_t * save_rule);
+    p_MPU_pSectorWithdrawAccessRights = (int (*)(MPU_reg_settings_t * save_rule))0x03001841U;
+
+    return p_MPU_pSectorWithdrawAccessRights(save_rule);
+}
+
+/*! @brief MPU_Settings_t structure in RAM to retrieve current MPU configuration
+ * see @MPU_GetCurrentSettings
+ */
+typedef struct
+{
+    uint32_t ctrl;    /*!< MPU Ctrl register */
+    uint32_t rbar[8]; /*!< MPU RBAR array for the 8 rules */
+    uint32_t rasr[8]; /*!< MPU RASR array for the 8 rules */
+} MPU_Settings_t;
+
+/*!
+ * @brief This function is used to read the MPU settings into a RAM structure.
+ *
+ * @param  settings: pointer of structure to receive the MPU register valkues.
+
+ * @return  none
+ *
+ */
+static inline void MPU_GetCurrentSettings(MPU_Settings_t *settings)
+{
+    void (*p_MPU_GetCurrentSettings)(MPU_Settings_t * settings);
+    p_MPU_GetCurrentSettings = (void (*)(MPU_Settings_t * settings))0x0300178dU;
+
+    p_MPU_GetCurrentSettings(settings);
+}
+
+/*!
+ * @brief This function is used to set access rights to a region.
+ *
+ * @param  region_id: 0 .. 7 see @enum MpuRegion_t
+ * @param  addr: address of region
+ * @param  sz: region size
+ * @param  rwx_rights: bit field RD_RIGHT(0) - WR_RIGHT(1) - X_RIGHT(2)
+ * @param  save_rule: save a copy of previous rule
+ *
+ * @return  -1 if failure, if succesful return the size of the region.
+ *
+ */
+static inline int MPU_SetRegionAccessRights(
+    enum MpuRegion_t region_id, uint32_t addr, size_t sz, uint8_t rwx_rights, MPU_reg_settings_t *save_rule)
+{
+    int (*p_MPU_SetRegionAccessRights)(enum MpuRegion_t region_id, uint32_t addr, size_t sz, uint8_t rwx_rights,
+                                       MPU_reg_settings_t * save_rule);
+    p_MPU_SetRegionAccessRights = (int (*)(enum MpuRegion_t region_id, uint32_t addr, size_t sz, uint8_t rwx_rights,
+                                           MPU_reg_settings_t * save_rule))0x03001821U;
+
+    return p_MPU_SetRegionAccessRights(region_id, addr, sz, rwx_rights, save_rule);
+}
+
+/*!
+ * @brief This function is used to set access rights to a region.
+ *
+ * Called after previous call to see @MPU_SetRegionAccessRights
+ *
+ * @param  region_id: 0 .. 7 see @enum MpuRegion_t
+ * @param  save_rule: saved copy of previous rule to be restored.
+ *         if this parameter is NULL, RBAR and RASR of the given region_id
+ *         are cleared.
+ *
+ * @return  -1 if failure, if succesful return the size of the region.
+ *
+ */
+static inline int MPU_ClearRegionSetting(enum MpuRegion_t region_id, MPU_reg_settings_t *saved_rule)
+{
+    int (*p_MPU_ClearRegionSetting)(enum MpuRegion_t region_id, MPU_reg_settings_t * saved_rule);
+    p_MPU_ClearRegionSetting = (int (*)(enum MpuRegion_t region_id, MPU_reg_settings_t * saved_rule))0x0300184dU;
+
+    return p_MPU_ClearRegionSetting(region_id, saved_rule);
+}
+
+/*!
+ * @brief This function is used to select the first available rule.
+ *
+ * Checks if rules have their RASR enable bit set.
+ * This for the application to find free riules that were left unused
+ * by the ROM code.
+ * Implicitly MPU_ClearRegionSetting releases an allocate rule.
+ *
+ *
+ * @param  none
+ *
+ * @return  -1 if none free, value between 1..4 if succesful.
+ *
+ */
+static inline int MPU_AllocateRegionDesc(void)
+{
+    int (*p_MPU_AllocateRegionDesc)(void);
+    p_MPU_AllocateRegionDesc = (int (*)(void))0x030017c1U;
+
+    return p_MPU_AllocateRegionDesc();
+}
+
+#if defined __cplusplus
+}
+#endif
+#endif
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_pmc.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_pmc.h
new file mode 100755
index 0000000..89f1f6a
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_pmc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_RESET_H_
+#define ROM_RESET_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <rom_common.h>
+#include <stdint.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/*!
+ * @brief  Get the cause of the reset.
+ *
+ * @return Reset cause value.
+ * @retval 0x1 POR - The last chip reset was caused by a Power On Reset.
+ * @retval 0x2 PADRESET - The last chip reset was caused by a Pad Reset.
+ * @retval 0x4 BODRESET - The last chip reset was caused by a Brown Out Detector.
+ * @retval 0x8 SYSTEMRESET - The last chip reset was caused by a System Reset requested by the ARM CPU.
+ * @retval 0x10 WDTRESET - The last chip reset was caused by the Watchdog Timer.
+ * @retval 0x20 WAKEUPIORESET -  The last chip reset was caused by a Wake-up I/O (GPIO or internal NTAG FD INT).
+ * @retval 0x40 WAKEUPPWDNRESET - The last CPU reset was caused by a Wake-up from Power down (many sources possible:
+ * timer, IO, ...).
+ * @retval 0x80 SWRRESET - The last chip reset was caused by a Software.
+ */
+static inline uint32_t pmc_reset_get_cause(void)
+{
+    uint32_t (*p_pmc_reset_get_cause)(void);
+    p_pmc_reset_get_cause = (uint32_t(*)(void))0x030046e9U;
+
+    return p_pmc_reset_get_cause();
+}
+
+/*!
+ * @brief  Clear the cause of the reset.
+ *
+ * @param  mask The mask of reset cause which you want to clear.
+ *
+ * @return  none
+ */
+static inline void pmc_reset_clear_cause(uint32_t mask)
+{
+    void (*p_pmc_reset_clear_cause)(uint32_t mask);
+    p_pmc_reset_clear_cause = (void (*)(uint32_t mask))0x030046f5U;
+
+    p_pmc_reset_clear_cause(mask);
+}
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_RESET_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_psector.h b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_psector.h
new file mode 100755
index 0000000..e27d231
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/drivers/rom_psector.h
@@ -0,0 +1,644 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_PSECTOR_H_
+#define ROM_PSECTOR_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stddef.h>
+#include "rom_common.h"
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/*! @brief PSECTOR_PAGE_WORDS number of 16 byte words available in page
+ * A page is 512 bytes in size. That is 32x16 bytes.
+ * The first 32 bytes contain the page header, which leaves 30x16bytes for storage.
+ * Thence the 30.
+ */
+#define PSECTOR_PAGE_WORDS 30
+
+/*! @brief PSECTOR_PAGE0_MAGIC magic word to identify PAGE0 page in header */
+#define PSECTOR_PAGE0_MAGIC  0xc51d8ca9
+/*! @brief PSECTOR_PFLASH_MAGIC magic word to identify PFLASH page in header */
+#define PSECTOR_PFLASH_MAGIC 0xa7b4353d
+
+#ifdef __GNUC__
+#define PSECT_READ(partition, page_type, var)                                               \
+( {                                                                                                \
+    typeof((((page_type *)0)->var)) _a;                                                            \
+    psector_ReadData(partition, 0, offsetof(page_type, var), sizeof((((page_type *)0)->var)), &_a);\
+    _a;                                                                                            \
+} )
+#endif
+
+#define ROM_SEC_BOOT_AUTH_ON_UPGRADE ((1 << 0) | ROM_SEC_BOOT_AUTH_ON_BOOT)
+#define ROM_SEC_BOOT_AUTH_ON_BOOT (1 << 1)
+#define ROM_SEC_BOOT_PREVENT_DOWNGRADE (1 << 2)
+#define ROM_SEC_BOOT_USE_NXP_KEY (1 << 3)
+
+/*! @brief IMG_DIRECTORY_MAX_SIZE max number of entries in image directory
+ * Concerns Secondary Stage Bootloader only
+*/
+#define IMG_DIRECTORY_MAX_SIZE 8
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/*! @brief psector_partition_id_t describes the 2 partitions of psectors.
+ * Note: PAGE0 is termed PSECT in the FlashProgrammer, whereas PFLASH remains PFLASH.
+ *
+ */
+typedef enum {
+
+    PSECTOR_PAGE0_PART,  /*!< Page0 partition : termed PSECT by FLashProgramemr tool
+                         * Image related data */
+    PSECTOR_PFLASH_PART, /*!< PFLASH : Custommer configuration data */
+    MAX_PSECTOR_PARTITIONS,
+} psector_partition_id_t;
+
+/*! @brief psector_page_state_t describes the possible states of the psector partitions. */
+typedef enum
+{
+    PAGE_STATE_BLANK,     /*!< Page has never been programmed or has been erased */
+    PAGE_STATE_ERROR,     /*!< Both subpages constituting the psector contain
+                           *unrecoverable errors that ECC/parity cannot mend */
+    PAGE_STATE_DEGRADED,  /*!< One subpage contains unrecoverable errors or is blank  */
+    PAGE_STATE_OK,        /*!< Both subpages are correct */
+} psector_page_state_t;
+
+/*! @brief psector_write_status_t status code of writes to update page.
+ */
+typedef enum
+{
+    WRITE_OK = 0x0,                    /*!< Succeded in writing page */
+    WRITE_ERROR_BAD_MAGIC,             /*!< Magic word incorrect in page header */
+    WRITE_ERROR_INVALID_PAGE_NUMBER,   /*!< Invalid page number (higher than partition size) */
+    WRITE_ERROR_BAD_VERSION,           /*!< Invalid version number: must increment monotonically */
+    WRITE_ERROR_BAD_CHECKSUM,          /*!< Invalid checksum */
+    WRITE_ERROR_INCORRECT_UPDATE_MODE, /*!< Update mode incorrect */
+    WRITE_ERROR_UPDATE_INVALID,        /*!< Update invalid */
+    WRITE_ERROR_PAGE_ERROR             /*!< Failure to program page in flash */
+} psector_write_status_t;
+
+/*! @brief AuthMode_t authentication options.
+ */
+typedef enum {
+    AUTH_NONE = 0,          /*!< no authentication is performed */
+    AUTH_ON_FW_UPDATE = 1,  /*!< authentication is performed on firmware update */
+    AUTH_ALWAYS = 2,        /*!< authentication is performed at each Cold boot*/
+  AUTH_LEVEL_NB
+} AuthMode_t;
+
+#define IMG_FLAG_BOOTABLE 1
+
+/*! @brief image_directory_entry_t image directory found in PAGE0 (PSECT)
+ * when SSBL is involved in the loading process
+ */
+typedef struct {
+    uint32_t img_base_addr;    /*!< image start address in internal Flash or QSPI flash  */
+    uint16_t img_nb_pages;     /*!< image number of 512 byte pages */
+    uint8_t  flags;            /*!< IMG_FLAG_BOOTABLE : bit 0, other TBD */
+    uint8_t  img_type;         /*!< image type */
+
+} image_directory_entry_t;
+
+typedef union
+{
+    uint8_t data_8[16];
+    uint32_t data_32[4];
+    uint64_t data_64[2];
+} psector_page_word_t;
+
+/*! @brief psector_header_t psector header.
+ */
+typedef struct
+{
+    uint32_t checksum;     /*!< page checksum */
+    uint32_t magic;        /*!< magic:  PSECTOR_PAGE0_MAGIC or PSECTOR_PFLASH_MAGIC*/
+    uint16_t psector_size;
+    uint16_t page_number;  /*!< should be 0 because both partitions contain a single page */
+    uint32_t version;
+    uint8_t update_modes[16];
+
+} psector_header_t;
+
+typedef struct
+{
+    psector_header_t hdr;
+    psector_page_word_t page_word[PSECTOR_PAGE_WORDS];
+} psector_page_t;
+
+typedef struct
+{
+    psector_header_t hdr;
+
+    union
+    {
+        psector_page_word_t page_word[PSECTOR_PAGE_WORDS];
+
+        struct
+        {
+            /* Word 0 - Any */
+            uint32_t SelectedImageAddress;
+            uint32_t RESERVED0[3];
+            /* Word 1 - Increment */
+            uint32_t MinVersion;
+            uint32_t img_pk_valid;
+            uint32_t RESERVED1[2];
+            /* Word [2:17] - OTP */
+            uint8_t image_pubkey[256];
+        } page0_v2;                                   /*!< Deprecated form kept for backward compatibility */
+        struct
+        {
+            /* Word 0 - Any */
+            uint32_t SelectedImageAddress;            /*!< Address of image to be loaded by boot ROM
+                                                       * offset 0x20 */
+            uint32_t preferred_app_index;             /*!< for use with SSBL: index of application to select from image directory value 0..8
+                                                       * offset 0x24 */
+            image_directory_entry_t ota_entry;        /*!< New image written by OTA : SSBL to check validity and authentication
+                                                       * offset 0x28 */
+            /* Word 1 - Increment */
+            uint32_t MinVersion;                      /*!< Minimum version accepted : application's version number must be greater than this one to be accepted.
+                                                       * offset 0x30 */
+            uint32_t img_pk_valid;                    /*!< Image public key valid
+                                                       * offset 0x34 */
+            uint32_t flash_audit_done;                /*!< Flash audit done: already sought for wrongly initialized pages
+                                                       * offset 0x38 */
+            uint32_t RESERVED1;                       /*!< padding reserved word */
+            /* Word [2:17] - OTP */
+            uint8_t image_pubkey[256];                /*!< RSA Public Key to be used to verify authenticity
+                                                       * offset 0x40 */
+            /* Word [18:20] */
+            uint8_t zigbee_install_code[36];          /*!< Zigbee install code
+                                                       * offset 0x140 */
+            uint32_t RESERVED3[3];                    /*!< padding reserved wordes */
+            /* Word 21 */
+            uint8_t zigbee_password[16];              /*!< Zigbee password
+                                                       * offset 0x170 */
+            /*Word 22 */                              /*!< Image directory entries array, used by OTA process to locate images and/or blobs
+                                                       * offset 0x180 */
+            image_directory_entry_t
+                      img_directory[IMG_DIRECTORY_MAX_SIZE];
+
+        } page0_v3;
+        struct
+        {
+            uint32_t rom_patch_region_sz;
+            uint32_t rom_patch_region_addr;    /*!< ROM patch entry point address.
+                                                * A value outside of the address range used to store
+                                                * the ROM patch binary shall be deemed invalid
+                                                */
+            uint32_t rom_patch_checksum;
+            uint32_t rom_patch_checksum_valid; /*!< ROM patch checksum valid:
+                                                * 0 means invalid
+                                                * Any other value means valid
+                                                */
+            uint32_t hwtestmode_disable;       /*< HW test mode control:
+                                                *  0 means enabled
+                                                *  Any other value means disabled
+                                                */
+
+            uint32_t ISP_access_level;         /*!< ISP access level:
+                                                * 0 means full access, unsecure
+                                                * 0x01010101 means full access, secure
+                                                * 0x02020202 means write only, unsecure
+                                                * 0x03030303 means write only, secure
+                                                * 0x04040404 means locked
+                                                * Any other value means disabled
+                                                */
+
+            uint16_t application_flash_sz;     /*!< Application flash size, in kilobytes.
+                                                * 0 is interpreted as maximum (640).
+                                                * This is intended to provide an alternative way of
+                                                * restricting the flash size on a device, and to greater
+                                                * granularity, than the eFuse bit.
+                                                * The actual level of granularity that can be obtained is
+                                                * dependent upon the MPU region configuration
+                                                */
+            uint16_t image_authentication_level; /*!< Image authentication level:
+                                                  * 0 means check only header validity
+                                                  * 1 means check signature of whole image if image has changed
+                                                  * 2 means check signature of whole image on every cold start
+                                                  */
+            uint16_t unlock_key_valid;          /*!<  0: unlock key is not valid, >= 1: is present  */
+            uint16_t ram1_bank_sz;               /*!< RAM bank 1 size, in kilobytes.
+                                                  * This is intended to provide an alternative way of restricting
+                                                  * the RAM size on a device, and to greater granularity,
+                                                  * than the eFuse bit. The actual level of granularity that can
+                                                  * be obtained is dependent upon the MPU region configuration */
+
+            uint32_t app_search_granularity;     /*!< Application search granularity (increment), in bytes.
+                                                  * Value of 0 shall be equated to 4096.
+                                                  * Other values are to be used directly;
+                                                  * configurations that are not using hardware remapping do not
+                                                  * require hard restrictions
+                                                  */
+            uint32_t qspi_app_search_granularity;
+
+            uint32_t reserved1[2];
+
+            uint8_t ISP_protocol_key[16];        /*!< ISP protocol key: key used to encrypt messages over ISP UART
+                                                  * with secure access level
+                                                  */
+            uint64_t ieee_mac_id1;               /*!< IEEE_MAC_ID_1 (Used to over-ride MAC ID_1 in N-2 page) */
+            uint64_t ieee_mac_id2;               /*!< IEEE_MAC_ID_2 if second MAC iID is required */
+
+            uint64_t ble_mac_id;                 /*!< BLE device address : only 6 LSB bytes are significant */
+            uint8_t  reserved2[104];             /*!< Reserved for future use  */
+
+            uint64_t customer_id;                /*!< Customer ID, used for secure handshake */
+            uint64_t min_device_id;              /*!< Min Device ID, used for secure handshake - Certificate compatibility  */
+            uint64_t device_id;                  /*!< Device ID, used for secure handshake */
+            uint64_t max_device_id;              /*!< Max Device ID, used for secure handshake - Certificate compatibility  */
+            uint8_t unlock_key[256];             /*!< 2048-bit public key for secure handshake
+                                                  * (equivalent to ‘unlock’ key). Stored encrypted,
+                                                  * using the AES key in eFuse*/
+        } pFlash;
+
+    };
+} psector_page_data_t;
+
+STATIC_ASSERT(sizeof(psector_page_t) == 512, "Psector page size not equal to flash page");
+STATIC_ASSERT(sizeof(psector_page_data_t) == 512, "Psector data size not equal to flash page");
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/* General access functions */
+
+/*!
+ * @brief This function is used to validate a page content and write it to the update page.
+ *
+ * The actual write to the partition will be effective after a reset only.
+ * Among other checks, the page must have a correct magic, a correct checksum
+ *
+ * @param  part_index: PSECTOR_PAGE0_PART or PFLASH_PAGE0_PART.
+ * @param  page: psector_page_t RAM buffer to be written to update page
+ *
+ * @return  status code see @ psector_write_status_t.
+ *
+ */
+static inline psector_write_status_t psector_WriteUpdatePage(psector_partition_id_t part_index, psector_page_t *page)
+{
+    psector_write_status_t (*p_psector_WriteUpdatePage)(psector_partition_id_t part_index, psector_page_t *page);
+    p_psector_WriteUpdatePage =
+        (psector_write_status_t (*)(psector_partition_id_t part_index, psector_page_t *page))0x03004e11U;
+
+    return p_psector_WriteUpdatePage(part_index, page);
+}
+
+/*!
+ * @brief This function is used to validate a page content and write it to the update page.
+ *
+ * The actual write to the partition will be effective after a reset only.
+ *
+ * @param  part_index: PSECTOR_PAGE0_PART or PFLASH_PAGE0_PART.
+ * @param  page: psector_page_t RAM buffer to be written to update page
+ *
+ * @return  status code see @ psector_write_status_t.
+ *
+ */
+static inline void psector_EraseUpdate(void)
+{
+    void (*p_psector_EraseUpdate)(void);
+    p_psector_EraseUpdate = (void (*)(void))0x03004d59U;
+
+    p_psector_EraseUpdate();
+}
+
+/*!
+ * @brief This function is used to read data from a psector partition.
+ *
+ *
+ * @param  part_index: PSECTOR_PAGE0_PART or PFLASH_PAGE0_PART.
+ * @param  page_number: necessarily 0 since partitions now contain 1 single page.
+ * @param  offset: offset of data from which data is to be read
+ * @param  size: number of bytes to be read
+ * @param  data: pointer on RAM buffer used to copy retrived data.
+ *
+ * @return  status code see @ psector_page_state_t
+ *          if PAGE_STATE_DEGRADED or PAGE_STATE_OK, data is available.
+ *          if PAGE_STATE_ERROR or PAGE_STATE_BLANK, no data was read
+ */
+static inline psector_page_state_t psector_ReadData(
+    psector_partition_id_t part_index, int page_number, uint32_t offset, uint32_t size, void *data)
+{
+    psector_page_state_t (*p_psector_ReadData)(psector_partition_id_t part_index, int page_number, uint32_t offset,
+                                               uint32_t size, void *data);
+    p_psector_ReadData = (psector_page_state_t (*)(psector_partition_id_t part_index, int page_number, uint32_t offset,
+                                                   uint32_t size, void *data))0x03004ef1U;
+
+    return p_psector_ReadData(part_index, page_number, offset, size, data);
+}
+
+/*!
+ * @brief This function is used to calculate a page checksum.
+ *
+ * It is essential to recalculate the checksum when performing a psector page update,
+ * failing to update this field, the write operation would be rejected.
+ *
+ * @param  psector_page: pointer on page over which computation is required.
+ *
+ * @return  checksum value to be checked or to replace checksum field of psector header
+ */
+static inline uint32_t psector_CalculateChecksum(psector_page_t *psector_page)
+{
+    uint32_t (*p_psector_CalculateChecksum)(psector_page_t *psector_page);
+    p_psector_CalculateChecksum = (uint32_t (*)(psector_page_t *psector_page))0x030050bdU;
+
+    return p_psector_CalculateChecksum(psector_page);
+}
+
+/* Access helper functions */
+/*!
+ * @brief This function returns the CustomerId field.
+ *
+ * @param  none
+ *
+ * @return  CustomerId on 64 bit word
+ */
+static inline uint64_t psector_Read_CustomerId(void)
+{
+    uint64_t (*p_psector_Read_CustomerId)(void);
+    p_psector_Read_CustomerId = (uint64_t (*)(void))0x030051ddU;
+
+    return p_psector_Read_CustomerId();
+}
+
+/*!
+ * @brief This function returns the ROM patch information read from the PFLASH.
+ *
+ * @param  patch_region_sz: pointer on unsigned long to return ROM patch size
+ * @param  patch_region_addr: pointer on unsigned long to return ROM patch address
+ * @param  patch_checksum: pointer on unsigned long to return ROM patch checksum value
+ * @param  patch_checksum_valid: pointer on unsigned long to return ROM patch checksum validity (0..1)
+ *
+ * @return -1 if erro is found (any of the input parameters is NULL) or PFLASH is unreadable.
+ */
+static inline int psector_Read_RomPatchInfo(uint32_t *patch_region_sz,
+                                            uint32_t *patch_region_addr,
+                                            uint32_t *patch_checksum,
+                                            uint32_t *patch_checksum_valid)
+{
+    int (*p_psector_Read_RomPatchInfo)(uint32_t *patch_region_sz, uint32_t *patch_region_addr, uint32_t *patch_checksum,
+                                       uint32_t *patch_checksum_valid);
+    p_psector_Read_RomPatchInfo = (int (*)(uint32_t *patch_region_sz, uint32_t *patch_region_addr,
+                                           uint32_t *patch_checksum, uint32_t *patch_checksum_valid))0x03005209U;
+
+    return p_psector_Read_RomPatchInfo(patch_region_sz, patch_region_addr, patch_checksum, patch_checksum_valid);
+}
+
+/*!
+ * @brief This function returns the image authentication level from the PFLASH.
+ *
+ * @param  none.
+ *
+ * @return AUH_NONE if PFLASH unreadable, or the image_authentication_level field value if readable.
+ */
+static inline uint16_t psector_Read_ImgAuthLevel(void)
+{
+    uint16_t (*p_psector_Read_ImgAuthLevel)(void);
+    p_psector_Read_ImgAuthLevel = (uint16_t (*)(void))0x03005299U;
+
+    return p_psector_Read_ImgAuthLevel();
+}
+
+/*!
+ * @brief This function returns the app search granularity value from the PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, or the app_search_granularity field value if not 0 or 4096 if 0.
+ */
+static inline uint32_t psector_Read_AppSearchGranularity(void)
+{
+    uint32_t (*p_psector_Read_AppSearchGranularity)(void);
+    p_psector_Read_AppSearchGranularity = (uint32_t (*)(void))0x030052d5U;
+
+    return p_psector_Read_AppSearchGranularity();
+}
+
+/*!
+ * @brief This function returns the Qspi app search granularity value from the PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, or the qspi_app_search_granularity field value.
+ */
+static inline uint32_t psector_Read_QspiAppSearchGranularity(void)
+{
+    uint32_t (*p_psector_Read_QspiAppSearchGranularity)(void);
+    p_psector_Read_QspiAppSearchGranularity = (uint32_t (*)(void))0x03005305U;
+
+    return p_psector_Read_QspiAppSearchGranularity();
+}
+
+/*!
+ * @brief This function returns the DeviceId value from the PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, or the device_id field value.
+ */
+static inline uint64_t psector_Read_DeviceId(void)
+{
+    uint64_t (*p_psector_Read_DeviceId)(void);
+    p_psector_Read_DeviceId = (uint64_t (*)(void))0x03005329U;
+
+    return p_psector_Read_DeviceId();
+}
+
+/*!
+ * @brief This function returns the unlock key value from the PFLASH.
+ *
+ * @param  valid:  pointer on int to store validity of key (unlock_key_valid field)
+ * @param  key:   pointer on 256 byte storage to receive the key read from PFLASH
+ * @param  raw:    raw  if raw is not requested (0), the key is deciphered
+ *                using the internal AES fused key.
+ *
+ * @return -1 if read error occurred, 0 otherwise
+ */
+static inline int psector_Read_UnlockKey(int *valid, uint8_t key[256], bool raw)
+{
+    int (*p_psector_Read_UnlockKey)(int *valid, uint8_t key[256], bool raw);
+    p_psector_Read_UnlockKey = (int (*)(int *valid, uint8_t key[256], bool raw))0x03005519U;
+
+    return p_psector_Read_UnlockKey(valid, key, raw);
+}
+
+/*!
+ * @brief This function returns the ISP protocol AES key from PFLASH.
+ *
+ * @param  key:   pointer on 16 byte storage to receive the key read from PFLASH.
+ *
+ * @return -1 if read error occurred, 0 otherwise
+ */
+static inline int psector_Read_ISP_protocol_key(uint8_t key[16])
+{
+    int (*p_psector_Read_ISP_protocol_key)(uint8_t key[16]);
+    p_psector_Read_ISP_protocol_key = (int (*)(uint8_t key[16]))0x03005355U;
+
+    return p_psector_Read_ISP_protocol_key(key);
+}
+
+/*!
+ * @brief This function returns the IEEE-802.15.4 Mac address first instance from PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 64 bit word 0 if field unreadable, otherwise MAC address contained in ieee_mac_id1 field.
+ */
+static inline uint64_t psector_ReadIeee802_15_4_MacId1(void)
+{
+    uint64_t (*p_psector_ReadIeee802_15_4_MacId1)(void);
+    p_psector_ReadIeee802_15_4_MacId1 = (uint64_t (*)(void))0x030053b1U;
+
+    return p_psector_ReadIeee802_15_4_MacId1();
+}
+
+/*!
+ * @brief This function returns the IEEE-802.15.4 Mac address second instance from PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 64 bit word 0 if field unreadable, otherwise MAC address contained in ieee_mac_id2 field.
+ */
+static inline uint64_t psector_ReadIeee802_15_4_MacId2(void)
+{
+    uint64_t (*p_psector_ReadIeee802_15_4_MacId2)(void);
+    p_psector_ReadIeee802_15_4_MacId2 = (uint64_t (*)(void))0x03005385U;
+
+    return p_psector_ReadIeee802_15_4_MacId2();
+}
+
+/*!
+ * @brief This function returns the Min Device id from PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, otherwise min_device_id field content.
+ */
+static inline uint64_t psector_Read_MinDeviceId(void)
+{
+    uint64_t (*p_psector_Read_MinDeviceId)(void);
+    p_psector_Read_MinDeviceId = (uint64_t (*)(void))0x030053ddU;
+
+    return p_psector_Read_MinDeviceId();
+}
+
+/*!
+ * @brief This function returns the Max Device id from PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, otherwise max_device_id field content.
+ */
+static inline uint64_t psector_Read_MaxDeviceId(void)
+{
+    uint64_t (*p_psector_Read_MaxDeviceId)(void);
+    p_psector_Read_MaxDeviceId = (uint64_t (*)(void))0x03005409U;
+
+    return p_psector_Read_MaxDeviceId();
+}
+
+/* Helper functions for reading and writing image data */
+
+/*!
+ * @brief This function returns the Min Version from PAGE0.
+ *
+ * @param  none.
+ *
+ * @return if PAGE0 unreadable, otherwise MinVersion field content.
+ */
+static inline uint32_t psector_Read_MinVersion(void)
+{
+    uint32_t (*p_psector_Read_MinVersion)(void);
+    p_psector_Read_MinVersion = (uint32_t (*)(void))0x03005439U;
+
+    return p_psector_Read_MinVersion();
+}
+
+/*!
+ * @brief This function is used to set the selected image address and MinVersion into PAGE0.
+ *
+ * @param  image_addr:   32 bit value to be written to SelectImageAddress.
+ * @param  min_version:   32 bit value to be written to MinVersion.
+ *
+ * @return psector_write_status_t status of operation see @psector_WriteUpdatePage
+ */
+static inline psector_write_status_t psector_SetEscoreImageData(uint32_t image_addr, uint32_t min_version)
+{
+    psector_write_status_t (*p_psector_SetEscoreImageData)(uint32_t image_addr, uint32_t min_version);
+    p_psector_SetEscoreImageData = (psector_write_status_t (*)(uint32_t image_addr, uint32_t min_version))0x0300545dU;
+
+    return p_psector_SetEscoreImageData(image_addr, min_version);
+}
+
+/*!
+ * @brief This function returns the image address and min version value from PAGE0.
+ *
+ * @param  image_addr:   pointer on 32 bit word to receive SelectImageAddress value.
+ * @param  min_versionm:   pointer on 32 bit word to receive SelectImageAddress value.
+ *
+ * @return -1 if read error occurred, 0 otherwise
+ */
+static inline psector_page_state_t psector_ReadEscoreImageData(uint32_t *image_addr, uint32_t *min_version)
+{
+    psector_page_state_t (*p_psector_ReadEscoreImageData)(uint32_t *image_addr, uint32_t *min_version);
+    p_psector_ReadEscoreImageData = (psector_page_state_t (*)(uint32_t *image_addr, uint32_t *min_version))0x03005491U;
+
+    return p_psector_ReadEscoreImageData(image_addr, min_version);
+}
+
+/*!
+ * @brief This function returns the unlock key value from PAGE0.
+ *
+ * @param  valid:  pointer on int to store validity of key (img_pk_valid field)
+ * @param  key:   pointer on 256 byte storage to receive the key read from PAGE0
+ * @param  raw:   raw  if raw is not requested (0), the key is deciphered
+ *                using the internal AES fused key.
+ *
+ * @return -1 if read error occurred, 0 otherwise
+ */
+static inline int psector_Read_ImagePubKey(int *valid, uint8_t key[256], bool raw)
+{
+    int (*p_psector_Read_ImagePubKey)(int *valid, uint8_t key[256], bool raw);
+    p_psector_Read_ImagePubKey = (int (*)(int *valid, uint8_t key[256], bool raw))0x03005531U;
+
+    return p_psector_Read_ImagePubKey(valid, key, raw);
+}
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_PSECTOR_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/fsl_device_registers.h b/third_party/nxp/JN5189DK6/devices/JN5189/fsl_device_registers.h
new file mode 100755
index 0000000..ccabb15
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/fsl_device_registers.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __FSL_DEVICE_REGISTERS_H__
+#define __FSL_DEVICE_REGISTERS_H__
+
+/*
+ * Include the cpu specific register header files.
+ *
+ * The CPU macro should be declared in the project or makefile.
+ */
+#if (defined(CPU_JN518X) || defined(CPU_JN5189HN) || defined(CPU_JN5189THN))
+
+#define JN518X_SERIES
+
+#define JN5189_SERIES
+
+/* CMSIS-style register definitions */
+#include "JN5189.h"
+/* CPU specific feature definitions */
+#include "JN5189_features.h"
+
+#else
+#error "No valid CPU defined!"
+#endif
+
+#endif /* __FSL_DEVICE_REGISTERS_H__ */
+
+/*******************************************************************************
+ * EOF
+ ******************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/mcuxpresso/startup_JN5189.c b/third_party/nxp/JN5189DK6/devices/JN5189/mcuxpresso/startup_JN5189.c
new file mode 100755
index 0000000..f537bfb
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/mcuxpresso/startup_JN5189.c
@@ -0,0 +1,865 @@
+//*****************************************************************************
+// JN5189 startup code for use with MCUXpresso IDE
+//
+// Version : 151018
+//*****************************************************************************
+//
+// Copyright 2016-2018 NXP
+// All rights reserved.
+//
+// SPDX-License-Identifier: BSD-3-Clause
+//*****************************************************************************
+
+#if defined (DEBUG)
+#pragma GCC push_options
+#pragma GCC optimize ("Og")
+#endif // (DEBUG)
+
+#if defined (__cplusplus)
+#ifdef __REDLIB__
+#error Redlib does not support C++
+#else
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+extern "C" {
+    extern void __libc_init_array(void);
+}
+#endif
+#endif
+
+#define WEAK __attribute__ ((weak))
+#define WEAK_AV __attribute__ ((weak, section(".after_vectors")))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+//*****************************************************************************
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+//*****************************************************************************
+// Variable to store CRP value in. Will be placed automatically
+// by the linker when "Enable Code Read Protect" selected.
+// See crp.h header for more information
+//*****************************************************************************
+#if (defined(__MCUXPRESSO))
+#include <NXP/crp.h>
+__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
+#endif
+
+#include "fsl_device_registers.h"
+#include "rom_api.h"
+
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM_ALL_MASK   	(PMC_PDSLEEPCFG_PDEN_PD_MEM0_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM1_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM2_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM3_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM4_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM5_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM6_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM8_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM9_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM10_MASK \
+                                                | PMC_PDSLEEPCFG_PDEN_PD_MEM11_MASK)
+
+//*****************************************************************************
+// Declaration of external SystemInit function
+//*****************************************************************************
+extern WEAK void SystemInit(void);
+
+//*****************************************************************************
+// Declaration of external WarmMain function
+//*****************************************************************************
+extern WEAK void WarmMain(void);
+
+//*****************************************************************************
+// Forward declaration of the core exception handlers.
+// When the application defines a handler (with the same name), this will
+// automatically take precedence over these weak definitions.
+// If your application is a C++ one, then any interrupt handlers defined
+// in C++ files within in your main application will need to have C linkage
+// rather than C++ linkage. To do this, make sure that you are using extern "C"
+// { .... } around the interrupt handler within your main application code.
+//*****************************************************************************
+     void ResetISR(void);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void MemManage_Handler(void);
+WEAK void BusFault_Handler(void);
+WEAK void UsageFault_Handler(void);
+WEAK void SVC_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_Handler(void);
+WEAK void IntDefaultHandler(void);
+
+//*****************************************************************************
+// Forward declaration of the application IRQ handlers. When the application
+// defines a handler (with the same name), this will automatically take
+// precedence over weak definitions below
+//*****************************************************************************
+WEAK void WDT_BOD_IRQHandler(void);
+WEAK void DMA0_IRQHandler(void);
+WEAK void GINT0_IRQHandler(void);
+WEAK void CIC_IRB_IRQHandler(void);
+WEAK void PIN_INT0_IRQHandler(void);
+WEAK void PIN_INT1_IRQHandler(void);
+WEAK void PIN_INT2_IRQHandler(void);
+WEAK void PIN_INT3_IRQHandler(void);
+WEAK void SPIFI0_IRQHandler(void);
+WEAK void CTIMER0_IRQHandler(void);
+WEAK void CTIMER1_IRQHandler(void);
+WEAK void FLEXCOMM0_IRQHandler(void);
+WEAK void FLEXCOMM1_IRQHandler(void);
+WEAK void FLEXCOMM2_IRQHandler(void);
+WEAK void FLEXCOMM3_IRQHandler(void);
+WEAK void FLEXCOMM4_IRQHandler(void);
+WEAK void FLEXCOMM5_IRQHandler(void);
+WEAK void PWM0_IRQHandler(void);
+WEAK void PWM1_IRQHandler(void);
+WEAK void PWM2_IRQHandler(void);
+WEAK void PWM3_IRQHandler(void);
+WEAK void PWM4_IRQHandler(void);
+WEAK void PWM5_IRQHandler(void);
+WEAK void PWM6_IRQHandler(void);
+WEAK void PWM7_IRQHandler(void);
+WEAK void PWM8_IRQHandler(void);
+WEAK void PWM9_IRQHandler(void);
+WEAK void PWM10_IRQHandler(void);
+WEAK void FLEXCOMM6_IRQHandler(void);
+WEAK void RTC_IRQHandler(void);
+WEAK void NFCTag_IRQHandler(void);
+WEAK void MAILBOX_IRQHandler(void);
+WEAK void ADC0_SEQA_IRQHandler(void);
+WEAK void ADC0_SEQB_IRQHandler(void);
+WEAK void ADC0_THCMP_IRQHandler(void);
+WEAK void DMIC0_IRQHandler(void);
+WEAK void HWVAD0_IRQHandler(void);
+WEAK void BLE_DP_IRQHandler(void);
+WEAK void BLE_DP0_IRQHandler(void);
+WEAK void BLE_DP1_IRQHandler(void);
+WEAK void BLE_DP2_IRQHandler(void);
+WEAK void BLE_LL_ALL_IRQHandler(void);
+WEAK void ZIGBEE_MAC_IRQHandler(void);
+WEAK void ZIGBEE_MODEM_IRQHandler(void);
+WEAK void RFP_TMU_IRQHandler(void);
+WEAK void RFP_AGC_IRQHandler(void);
+WEAK void ISO7816_IRQHandler(void);
+WEAK void ANA_COMP_IRQHandler(void);
+WEAK void WAKE_UP_TIMER0_IRQHandler(void);
+WEAK void WAKE_UP_TIMER1_IRQHandler(void);
+WEAK void PVTVF0_AMBER_IRQHandler(void);
+WEAK void PVTVF0_RED_IRQHandler(void);
+WEAK void PVTVF1_AMBER_IRQHandler(void);
+WEAK void PVTVF1_RED_IRQHandler(void);
+WEAK void BLE_WAKE_UP_TIMER_IRQHandler(void);
+WEAK void SHA_IRQHandler(void);
+WEAK void vMMAC_IntHandlerBbc(void);
+WEAK void vMMAC_IntHandlerPhy(void);
+
+//*****************************************************************************
+// Forward declaration of the driver IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the driver
+// defines a handler (with the same name), this will automatically take
+// precedence over these weak definitions
+//*****************************************************************************
+void WDT_BOD_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void DMA0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void GINT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void CIC_IRB_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void SPIFI0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void CTIMER0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void CTIMER1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM4_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM5_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM4_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM5_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM6_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM7_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM8_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM9_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM10_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM6_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void RTC_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void NFCTag_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void MAILBOX_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ADC0_SEQA_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ADC0_SEQB_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ADC0_THCMP_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void DMIC0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void HWVAD0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_DP_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_DP0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_DP1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_DP2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_LL_ALL_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ZIGBEE_MAC_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ZIGBEE_MODEM_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void RFP_TMU_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void RFP_AGC_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ISO7816_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ANA_COMP_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void WAKE_UP_TIMER0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void WAKE_UP_TIMER1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTVF0_AMBER_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTVF0_RED_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTVF1_AMBER_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTVF1_RED_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_WAKE_UP_TIMER_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void SHA_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+// The entry point for the application.
+// __main() is the entry point for Redlib based applications
+// main() is the entry point for Newlib based applications
+//*****************************************************************************
+#if defined (__REDLIB__)
+extern void __main(void);
+#endif
+extern int main(void);
+
+//*****************************************************************************
+// External declaration for the pointer to the stack top from the Linker Script
+//*****************************************************************************
+extern void _vStackTop(void);
+//*****************************************************************************
+// External declaration for LPC MCU vector table checksum from  Linker Script
+//*****************************************************************************
+WEAK extern void __valid_user_code_checksum();
+
+//*****************************************************************************
+//*****************************************************************************
+#if defined (__cplusplus)
+} // extern "C"
+#endif
+//*****************************************************************************
+// The vector table.
+// This relies on the linker script to place at correct location in memory.
+//*****************************************************************************
+extern void (* const g_pfnVectors[])(void);
+extern void * __Vectors __attribute__ ((alias ("g_pfnVectors")));
+
+__attribute__ ((used, section(".isr_vector")))
+void (* const g_pfnVectors[])(void) = {
+    // Core Level - CM4
+    &_vStackTop,                       // The initial stack pointer
+    ResetISR,                          // The reset handler
+    NMI_Handler,                       // The NMI handler
+    HardFault_Handler,                 // The hard fault handler
+    MemManage_Handler,                 // The MPU fault handler
+    BusFault_Handler,                  // The bus fault handler
+    UsageFault_Handler,                // The usage fault handler
+    __valid_user_code_checksum,        // LPC MCU checksum
+    0,                                 // ECRP
+    0,                                 // Reserved
+    0,                                 // Reserved
+    SVC_Handler,                       // SVCall handler
+    0,                                 // Reserved
+    0,                                 // Reserved
+    PendSV_Handler,                    // The PendSV handler
+    SysTick_Handler,                   // The SysTick handler
+
+    // Chip Level - JN5189
+    WDT_BOD_IRQHandler,            // 16: System (BOD, Watchdog Timer, Flash controller) interrupt
+    DMA0_IRQHandler,               // 17: DMA interrupt
+    GINT0_IRQHandler,              // 18: GPIO global interrupt
+    CIC_IRB_IRQHandler,            // 19: Infra Red Blaster interrupt
+    PIN_INT0_IRQHandler,           // 20: Pin Interrupt and Pattern matching 0
+    PIN_INT1_IRQHandler,           // 21: Pin Interrupt and Pattern matching 1
+    PIN_INT2_IRQHandler,           // 22: Pin Interrupt and Pattern matching 2
+    PIN_INT3_IRQHandler,           // 23: Pin Interrupt and Pattern matching 3
+    SPIFI0_IRQHandler,             // 24: Quad-SPI flash interface interrupt
+    CTIMER0_IRQHandler,            // 25: Counter/Timer 0 interrupt
+    CTIMER1_IRQHandler,            // 26: Counter/Timer 1 interrupt
+    FLEXCOMM0_IRQHandler,          // 27: Flexcomm Interface 0 (USART0, FLEXCOMM0)
+    FLEXCOMM1_IRQHandler,          // 28: Flexcomm Interface 1 (USART1, FLEXCOMM1)
+    FLEXCOMM2_IRQHandler,          // 29: Flexcomm Interface 2 (I2C0, FLEXCOMM2)
+    FLEXCOMM3_IRQHandler,          // 30: Flexcomm Interface 3 (I2C1, FLEXCOMM3)
+    FLEXCOMM4_IRQHandler,          // 31: Flexcomm Interface 4 (SPI0, FLEXCOMM4)
+    FLEXCOMM5_IRQHandler,          // 32: Flexcomm Interface 5 (SPI5, FLEXCOMM)
+    PWM0_IRQHandler,               // 33: PWM channel 0 interrupt
+    PWM1_IRQHandler,               // 34: PWM channel 1 interrupt
+    PWM2_IRQHandler,               // 35: PWM channel 2 interrupt
+    PWM3_IRQHandler,               // 36: PWM channel 3 interrupt
+    PWM4_IRQHandler,               // 37: PWM channel 4 interrupt
+    PWM5_IRQHandler,               // 38: PWM channel 5 interrupt
+    PWM6_IRQHandler,               // 39: PWM channel 6  interrupt
+    PWM7_IRQHandler,               // 40: PWM channel 7 interrupt
+    PWM8_IRQHandler,               // 41: PWM channel 8 interrupt
+    PWM9_IRQHandler,               // 42: PWM channel 9 interrupt
+    PWM10_IRQHandler,              // 43: PWM channel 10 interrupt
+    FLEXCOMM6_IRQHandler,          // 44: Flexcomm Interface6 (I2C2, FLEXCOMM6)
+    RTC_IRQHandler,                // 45: Real Time Clock interrupt
+    NFCTag_IRQHandler,             // 46: NFC Tag interrupt
+    MAILBOX_IRQHandler,            // 47: Mailbox interrupts, Wake-up from Deep Sleep interrupt
+    ADC0_SEQA_IRQHandler,          // 48: ADC Sequence A interrupt
+    ADC0_SEQB_IRQHandler,          // 49: ADC Sequence B interrupt
+    ADC0_THCMP_IRQHandler,         // 50: ADC Threshold compare and overrun interrupt
+    DMIC0_IRQHandler,              // 51: DMIC interrupt
+    HWVAD0_IRQHandler,             // 52: Hardware Voice activity detection interrupt
+    BLE_DP_IRQHandler,             // 53: BLE Data Path interrupt
+    BLE_DP0_IRQHandler,            // 54: BLE Data Path interrupt 0
+    BLE_DP1_IRQHandler,            // 55: BLE Data Path interrupt 1
+    BLE_DP2_IRQHandler,            // 56: BLE Data Path interrupt 2
+    BLE_LL_ALL_IRQHandler,         // 57: All BLE link layer interrupts
+    ZIGBEE_MAC_IRQHandler,         // 58: Zigbee MAC interrupt
+    ZIGBEE_MODEM_IRQHandler,       // 59: Zigbee MoDem interrupt
+    RFP_TMU_IRQHandler,            // 60: RFP Timing Managemnt Unit (TMU) interrupt
+    RFP_AGC_IRQHandler,            // 61: RFP AGC interrupt
+    ISO7816_IRQHandler,            // 62: ISO7816 controller interrupt
+    ANA_COMP_IRQHandler,           // 63: Analog Comparator interrupt
+    WAKE_UP_TIMER0_IRQHandler,     // 64: Wake up Timer 0 interrupt
+    WAKE_UP_TIMER1_IRQHandler,     // 65: Wake up Timer 1 interrupt
+    PVTVF0_AMBER_IRQHandler,       // 66: PVT Monitor interrupt
+    PVTVF0_RED_IRQHandler,         // 67: PVT Monitor interrupt
+    PVTVF1_AMBER_IRQHandler,       // 68: PVT Monitor interrupt
+    PVTVF1_RED_IRQHandler,         // 69: PVT Monitor interrupt
+    BLE_WAKE_UP_TIMER_IRQHandler,  // 70: BLE Wake up Timer interrupt
+    SHA_IRQHandler,                // 71: SHA interrupt
+
+}; /* End of g_pfnVectors */
+
+//*****************************************************************************
+// Functions to carry out the initialization of RW and BSS data sections. These
+// are written as separate functions rather than being inlined within the
+// ResetISR() function in order to cope with MCUs with multiple banks of
+// memory.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors.init_data")))
+void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
+    unsigned int *pulDest = (unsigned int*) start;
+    unsigned int *pulSrc = (unsigned int*) romstart;
+    unsigned int loop;
+    for (loop = 0; loop < len; loop = loop + 4)
+        *pulDest++ = *pulSrc++;
+}
+
+__attribute__ ((section(".after_vectors.init_bss")))
+void bss_init(unsigned int start, unsigned int len) {
+    unsigned int *pulDest = (unsigned int*) start;
+    unsigned int loop;
+    for (loop = 0; loop < len; loop = loop + 4)
+        *pulDest++ = 0;
+}
+
+//*****************************************************************************
+// The following symbols are constructs generated by the linker, indicating
+// the location of various points in the "Global Section Table". This table is
+// created by the linker via the Code Red managed linker script mechanism. It
+// contains the load address, execution address and length of each RW data
+// section and the execution and length of each BSS (zero initialized) section.
+//*****************************************************************************
+extern unsigned int __data_section_table;
+extern unsigned int __data_section_table_end;
+extern unsigned int __bss_section_table;
+extern unsigned int __bss_section_table_end;
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors.reset")))
+void ResetISR(void) {
+
+    // Disable interrupts
+    __asm volatile ("cpsid i");
+
+    // Enable SRAM clock used by Stack
+    __asm volatile ("LDR R0, =0x40000220\n\t"
+                    "MOV R1, #56\n\t"
+                    "STR R1, [R0]");
+
+    __asm volatile(
+        ".set   cpu_ctrl,       0x40000800\t\n"
+        ".set   coproc_boot,    0x40000804\t\n"
+        ".set   coproc_stack,   0x40000808\t\n"
+        "LDR    R0,=coproc_boot\t\n"          // load co-processor boot address (from CPBOOT)
+        "LDR    R0,[R0]\t\n"                  // get address to branch to
+        "MOVS   R0,R0\t\n"                    // Check if 0
+        "BEQ.N  masterboot\t\n"               // if zero in boot reg, we just branch to  real reset
+        "LDR    R1,=coproc_stack\t\n"         // load co-processor stack pointer (from CPSTACK)
+        "LDR    R1,[R1]\t\n"
+        "MOV    SP,R1\t\n"
+        "BX     R0\t\n"                       // branch to boot address
+        "masterboot:\t\n"
+        "LDR    R0, =ResetISR2\t\n"           // jump to 'real' reset handler
+        "BX     R0\t\n");
+}
+
+__attribute__ ((used, section(".after_vectors"))) void ResetISR2(void)
+{
+    if ( WarmMain )
+    {
+        unsigned int warm_start;
+        uint32_t     pmc_lpmode;
+        uint32_t     pmc_resetcause;
+        uint32_t     pwr_pdsleepcfg;
+
+        pmc_resetcause = PMC->RESETCAUSE;
+        pwr_pdsleepcfg = PMC->PDSLEEPCFG;
+
+        pmc_lpmode = BOOT_GetStartPowerMode();
+
+        warm_start = (pmc_lpmode == 0x02);  /* coming from power down mode*/
+
+        // check if the reset cause is only a timer wakeup or io wakeup with all memory banks held
+        warm_start  &= ( !(pmc_resetcause & (PMC_RESETCAUSE_POR_MASK
+                                      | PMC_RESETCAUSE_PADRESET_MASK
+                                      | PMC_RESETCAUSE_BODRESET_MASK
+                                      | PMC_RESETCAUSE_SYSTEMRESET_MASK
+                                      | PMC_RESETCAUSE_WDTRESET_MASK
+                                      | PMC_RESETCAUSE_WAKEUPIORESET_MASK ))
+                            &&  ( pmc_resetcause & PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK         )
+                            &&  ((pwr_pdsleepcfg & PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK) == 0x0    )     /* BANK7 memory bank held */
+                            &&  ( pwr_pdsleepcfg & PMC_PDSLEEPCFG_PDEN_LDO_MEM_MASK            )     /* LDO MEM enabled */
+                            );
+
+        if (warm_start)
+        {
+            if (SYSCON->CPSTACK)
+            {
+                /* if CPSTACK is not NULL, switch to CPSTACK value so we avoid to corrupt the stack used before power down
+                     * Note: it looks like enough to switch to new SP now and not earlier */
+                __asm volatile(
+                        ".set   coproc_stack,   0x40000808\t\n"
+                        "LDR    R1,=coproc_stack\t\n" // load co-processor stack pointer (from CPSTACK)
+                        "LDR    R1,[R1]\t\n"
+                        "MOV    SP,R1\t\n"
+                        );
+            }
+
+            // Check to see if we are running the code from a non-zero
+            // address (eg RAM, external flash), in which case we need
+            // to modify the VTOR register to tell the CPU that the
+            // vector table is located at a non-0x0 address.
+            unsigned int *pSCB_VTOR = (unsigned int *)0xE000ED08;
+            if (((unsigned int)g_pfnVectors != 0))
+            {
+                // CMSIS : SCB->VTOR = <address of vector table>
+                *pSCB_VTOR = (unsigned int)g_pfnVectors;
+            }
+
+            if (SystemInit != 0)
+            {
+                SystemInit();
+            }
+
+            WarmMain();
+
+            //
+            // WarmMain() shouldn't return, but if it does, we'll just enter an infinite loop
+            //
+            while (1)
+            {
+                ;
+            }
+        }
+    }
+
+#if defined (__USE_CMSIS)
+// If __USE_CMSIS defined, then call CMSIS SystemInit code
+    SystemInit();
+
+#endif // (__USE_CMSIS)
+
+    //
+    // Copy the data sections from flash to SRAM.
+    //
+    unsigned int LoadAddr, ExeAddr, SectionLen;
+    unsigned int *SectionTableAddr;
+
+    // Load base address of Global Section Table
+    SectionTableAddr = &__data_section_table;
+
+    // Copy the data sections from flash to SRAM.
+    while (SectionTableAddr < &__data_section_table_end) {
+        LoadAddr = *SectionTableAddr++;
+        ExeAddr = *SectionTableAddr++;
+        SectionLen = *SectionTableAddr++;
+        data_init(LoadAddr, ExeAddr, SectionLen);
+    }
+
+    // At this point, SectionTableAddr = &__bss_section_table;
+    // Zero fill the bss segment
+    while (SectionTableAddr < &__bss_section_table_end) {
+        ExeAddr = *SectionTableAddr++;
+        SectionLen = *SectionTableAddr++;
+        bss_init(ExeAddr, SectionLen);
+    }
+
+#if !defined (__USE_CMSIS)
+// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code
+// will enable the FPU
+#if defined (__VFP_FP__) && !defined (__SOFTFP__)
+    //
+    // Code to enable the Cortex-M4 FPU only included
+    // if appropriate build options have been selected.
+    // Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C)
+    //
+    // Read CPACR (located at address 0xE000ED88)
+    // Set bits 20-23 to enable CP10 and CP11 coprocessors
+    // Write back the modified value to the CPACR
+    __asm volatile ("LDR.W R0, =0xE000ED88\n\t"
+                  "LDR R1, [R0]\n\t"
+                  "ORR R1, R1, #(0xF << 20)\n\t"
+                  "STR R1, [R0]");
+#endif // (__VFP_FP__) && !(__SOFTFP__)
+#endif // (__USE_CMSIS)
+
+#if !defined (__USE_CMSIS)
+// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code
+// will setup the VTOR register
+
+    // Check to see if we are running the code from a non-zero
+    // address (eg RAM, external flash), in which case we need
+    // to modify the VTOR register to tell the CPU that the
+    // vector table is located at a non-0x0 address.
+    unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;
+    if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) {
+        *pSCB_VTOR = (unsigned int)g_pfnVectors;
+    }
+#endif // (__USE_CMSIS)
+
+#if defined (__cplusplus)
+    //
+    // Call C++ library initialisation
+    //
+    __libc_init_array();
+#endif
+
+    // Reenable interrupts
+    __asm volatile ("cpsie i");
+
+#if defined (__REDLIB__)
+    // Call the Redlib library, which in turn calls main()
+    __main();
+#else
+    main();
+#endif
+
+    //
+    // main() shouldn't return, but if it does, we'll just enter an infinite loop
+    //
+    while (1) {
+        ;
+    }
+}
+
+//*****************************************************************************
+// Default core exception handlers. Override the ones here by defining your own
+// handler routines in your application code.
+//*****************************************************************************
+WEAK_AV void NMI_Handler(void)
+{ while(1) {}
+}
+
+WEAK_AV void HardFault_Handler(void)
+{ while(1) {}
+}
+
+WEAK_AV void MemManage_Handler(void)
+{ while(1) {}
+}
+
+WEAK_AV void BusFault_Handler(void)
+{ while(1) {}
+}
+
+WEAK_AV void UsageFault_Handler(void)
+{ while(1) {}
+}
+
+WEAK_AV void SVC_Handler(void)
+{ while(1) {}
+}
+
+WEAK_AV void PendSV_Handler(void)
+{ while(1) {}
+}
+
+WEAK_AV void SysTick_Handler(void)
+{ while(1) {}
+}
+
+//*****************************************************************************
+// Processor ends up here if an unexpected interrupt occurs or a specific
+// handler is not present in the application code.
+//*****************************************************************************
+WEAK_AV void IntDefaultHandler(void)
+{ while(1) {}
+}
+
+//*****************************************************************************
+// Default application exception handlers. Override the ones here by defining
+// your own handler routines in your application code. These routines call
+// driver exception handlers or IntDefaultHandler() if no driver exception
+// handler is included.
+//*****************************************************************************
+WEAK void WDT_BOD_IRQHandler(void)
+{   WDT_BOD_DriverIRQHandler();
+}
+
+WEAK void DMA0_IRQHandler(void)
+{   DMA0_DriverIRQHandler();
+}
+
+WEAK void GINT0_IRQHandler(void)
+{   GINT0_DriverIRQHandler();
+}
+
+WEAK void CIC_IRB_IRQHandler(void)
+{   CIC_IRB_DriverIRQHandler();
+}
+
+WEAK void PIN_INT0_IRQHandler(void)
+{   PIN_INT0_DriverIRQHandler();
+}
+
+WEAK void PIN_INT1_IRQHandler(void)
+{   PIN_INT1_DriverIRQHandler();
+}
+
+WEAK void PIN_INT2_IRQHandler(void)
+{   PIN_INT2_DriverIRQHandler();
+}
+
+WEAK void PIN_INT3_IRQHandler(void)
+{   PIN_INT3_DriverIRQHandler();
+}
+
+WEAK void SPIFI0_IRQHandler(void)
+{   SPIFI0_DriverIRQHandler();
+}
+
+WEAK void CTIMER0_IRQHandler(void)
+{   CTIMER0_DriverIRQHandler();
+}
+
+WEAK void CTIMER1_IRQHandler(void)
+{   CTIMER1_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM0_IRQHandler(void)
+{   FLEXCOMM0_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM1_IRQHandler(void)
+{   FLEXCOMM1_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM2_IRQHandler(void)
+{   FLEXCOMM2_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM3_IRQHandler(void)
+{   FLEXCOMM3_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM4_IRQHandler(void)
+{   FLEXCOMM4_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM5_IRQHandler(void)
+{   FLEXCOMM5_DriverIRQHandler();
+}
+
+WEAK void PWM0_IRQHandler(void)
+{   PWM0_DriverIRQHandler();
+}
+
+WEAK void PWM1_IRQHandler(void)
+{   PWM1_DriverIRQHandler();
+}
+
+WEAK void PWM2_IRQHandler(void)
+{   PWM2_DriverIRQHandler();
+}
+
+WEAK void PWM3_IRQHandler(void)
+{   PWM3_DriverIRQHandler();
+}
+
+WEAK void PWM4_IRQHandler(void)
+{   PWM4_DriverIRQHandler();
+}
+
+WEAK void PWM5_IRQHandler(void)
+{   PWM5_DriverIRQHandler();
+}
+
+WEAK void PWM6_IRQHandler(void)
+{   PWM6_DriverIRQHandler();
+}
+
+WEAK void PWM7_IRQHandler(void)
+{   PWM7_DriverIRQHandler();
+}
+
+WEAK void PWM8_IRQHandler(void)
+{   PWM8_DriverIRQHandler();
+}
+
+WEAK void PWM9_IRQHandler(void)
+{   PWM9_DriverIRQHandler();
+}
+
+WEAK void PWM10_IRQHandler(void)
+{   PWM10_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM6_IRQHandler(void)
+{   FLEXCOMM6_DriverIRQHandler();
+}
+
+WEAK void RTC_IRQHandler(void)
+{   RTC_DriverIRQHandler();
+}
+
+WEAK void NFCTag_IRQHandler(void)
+{   NFCTag_DriverIRQHandler();
+}
+
+WEAK void MAILBOX_IRQHandler(void)
+{   MAILBOX_DriverIRQHandler();
+}
+
+WEAK void ADC0_SEQA_IRQHandler(void)
+{   ADC0_SEQA_DriverIRQHandler();
+}
+
+WEAK void ADC0_SEQB_IRQHandler(void)
+{   ADC0_SEQB_DriverIRQHandler();
+}
+
+WEAK void ADC0_THCMP_IRQHandler(void)
+{   ADC0_THCMP_DriverIRQHandler();
+}
+
+WEAK void DMIC0_IRQHandler(void)
+{   DMIC0_DriverIRQHandler();
+}
+
+WEAK void HWVAD0_IRQHandler(void)
+{   HWVAD0_DriverIRQHandler();
+}
+
+WEAK void BLE_DP_IRQHandler(void)
+{   BLE_DP_DriverIRQHandler();
+}
+
+WEAK void BLE_DP0_IRQHandler(void)
+{   BLE_DP0_DriverIRQHandler();
+}
+
+WEAK void BLE_DP1_IRQHandler(void)
+{   BLE_DP1_DriverIRQHandler();
+}
+
+WEAK void BLE_DP2_IRQHandler(void)
+{   BLE_DP2_DriverIRQHandler();
+}
+
+WEAK void BLE_LL_ALL_IRQHandler(void)
+{   BLE_LL_ALL_DriverIRQHandler();
+}
+
+WEAK void ZIGBEE_MAC_IRQHandler(void)
+{
+    if (vMMAC_IntHandlerBbc)
+    {
+        vMMAC_IntHandlerBbc();
+    }
+    else if (ZIGBEE_MAC_IRQHandler)
+    {
+        ZIGBEE_MAC_IRQHandler();
+    }
+    else
+    {
+        IntDefaultHandler();
+    }
+}
+
+WEAK void ZIGBEE_MODEM_IRQHandler(void)
+{
+    if (vMMAC_IntHandlerPhy)
+    {
+        vMMAC_IntHandlerPhy();
+    }
+    else if (ZIGBEE_MODEM_IRQHandler)
+    {
+        ZIGBEE_MODEM_IRQHandler();
+    }
+    else
+    {
+        IntDefaultHandler();
+    }
+}
+
+WEAK void RFP_TMU_IRQHandler(void)
+{   RFP_TMU_DriverIRQHandler();
+}
+
+WEAK void RFP_AGC_IRQHandler(void)
+{   RFP_AGC_DriverIRQHandler();
+}
+
+WEAK void ISO7816_IRQHandler(void)
+{   ISO7816_DriverIRQHandler();
+}
+
+WEAK void ANA_COMP_IRQHandler(void)
+{   ANA_COMP_DriverIRQHandler();
+}
+
+WEAK void WAKE_UP_TIMER0_IRQHandler(void)
+{   WAKE_UP_TIMER0_DriverIRQHandler();
+}
+
+WEAK void WAKE_UP_TIMER1_IRQHandler(void)
+{   WAKE_UP_TIMER1_DriverIRQHandler();
+}
+
+WEAK void PVTVF0_AMBER_IRQHandler(void)
+{   PVTVF0_AMBER_DriverIRQHandler();
+}
+
+WEAK void PVTVF0_RED_IRQHandler(void)
+{   PVTVF0_RED_DriverIRQHandler();
+}
+
+WEAK void PVTVF1_AMBER_IRQHandler(void)
+{   PVTVF1_AMBER_DriverIRQHandler();
+}
+
+WEAK void PVTVF1_RED_IRQHandler(void)
+{   PVTVF1_RED_DriverIRQHandler();
+}
+
+WEAK void BLE_WAKE_UP_TIMER_IRQHandler(void)
+{   BLE_WAKE_UP_TIMER_DriverIRQHandler();
+}
+
+WEAK void SHA_IRQHandler(void)
+{   SHA_DriverIRQHandler();
+}
+
+//*****************************************************************************
+
+#if defined (DEBUG)
+#pragma GCC pop_options
+#endif // (DEBUG)
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/system_JN5189.c b/third_party/nxp/JN5189DK6/devices/JN5189/system_JN5189.c
new file mode 100755
index 0000000..28c225e
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/system_JN5189.c
@@ -0,0 +1,383 @@
+/*
+** ###################################################################
+**     Processors:          JN5189HN
+**                          JN5189THN
+**
+**     Compilers:           Keil ARM C/C++ Compiler
+**                          GNU C Compiler
+**                          IAR ANSI C/C++ Compiler for ARM
+**                          MCUXpresso Compiler
+**
+**     Reference manual:    JN5189 User manual Rev0.1 27 July 2018
+**     Version:             rev. 1.0, 2018-07-31
+**     Build:               b180731
+**
+**     Abstract:
+**         Provides a system configuration function and a global variable that
+**         contains the system frequency. It configures the device and initializes
+**         the oscillator (PLL) that is part of the microcontroller device.
+**
+**     Copyright 2016 Freescale Semiconductor, Inc.
+**     Copyright 2016-2018 NXP
+**
+**     SPDX-License-Identifier: BSD-3-Clause
+**
+**     http:                 www.nxp.com
+**     mail:                 support@nxp.com
+**
+**     Revisions:
+**     - rev. 1.0 (2018-07-31)
+**         Initial version.
+**
+** ###################################################################
+*/
+
+/*!
+ * @file JN5189
+ * @version 1.0
+ * @date 2018-07-31
+ * @brief Device specific configuration file for JN5189 (implementation file)
+ *
+ * Provides a system configuration function and a global variable that contains
+ * the system frequency. It configures the device and initializes the oscillator
+ * (PLL) that is part of the microcontroller device.
+ */
+
+#include <stdint.h>
+#include "fsl_device_registers.h"
+#include "rom_api.h"
+
+/**
+ * Clock source selections for the Main Clock
+ */
+typedef enum _main_clock_src
+{
+    kCLOCK_MainFro12M 		= 0,
+    kCLOCK_MainOsc32k 		= 1,
+    kCLOCK_MainXtal32M		= 2,
+    kCLOCK_MainFro32M		= 3,
+    kCLOCK_MainFro48M		= 4,
+    kCLOCK_MainExtClk		= 5,
+    kCLOCK_MainFro1M		= 6,
+} main_clock_src_t;
+
+
+/**
+ * Clock source selections for CLKOUT
+ */
+typedef enum _clkout_clock_src
+{
+    kCLOCK_ClkoutMainClk = 0,
+    kCLOCK_ClkoutXtal32k = 1,
+    kCLOCK_ClkoutFro32k	 = 2,
+    kCLOCK_ClkoutXtal32M = 3,
+    kCLOCK_ClkoutDcDcTest= 4,
+    kCLOCK_ClkoutFro48M  = 5,
+    kCLOCK_ClkoutFro1M   = 6,
+    kCLOCK_ClkoutNoClock = 7
+} clkout_clock_src_t;
+
+typedef enum
+{
+    FRO12M_ENA  = (1 << 0),
+    FRO32M_ENA  = (1 << 1),
+    FRO48M_ENA  = (1 << 2),
+    FRO64M_ENA  = (1 << 3),
+    FRO96M_ENA  = (1 << 4)
+} Fro_ClkSel_t;
+
+#define OSC32K_FREQ        32768UL
+#define FRO32K_FREQ        32768UL
+#define OSC32M_FREQ        32000000UL
+#define XTAL32M_FREQ       32000000UL
+#define FRO64M_FREQ        64000000UL
+#define FRO1M_FREQ         1000000UL
+#define FRO12M_FREQ        12000000UL
+#define FRO32M_FREQ        32000000UL
+#define FRO48M_FREQ        48000000UL
+
+static const uint32_t g_Ext_Clk_Freq = 0U;
+
+extern unsigned int __Vectors;
+extern WEAK void SystemInit(void);
+extern WEAK void WarmMain(void);
+
+static uint32_t CLOCK_GetXtal32kFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_XTAL32K_MASK)
+                >> PMC_PDRUNCFG_ENA_XTAL32K_SHIFT) != 0)
+    {
+        freq = OSC32K_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetXtal32MFreq(void)
+{
+    return XTAL32M_FREQ;
+}
+
+static uint32_t CLOCK_GetFro32kFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_FRO32K_MASK)
+                >> PMC_PDRUNCFG_ENA_FRO32K_SHIFT) != 0)
+    {
+        freq = FRO32K_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetFro1MFreq(void)
+{
+    return FRO1M_FREQ;
+}
+
+static uint32_t CLOCK_GetFro12MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >>
+            PMC_FRO192M_DIVSEL_SHIFT) & FRO12M_ENA)
+    {
+        freq = FRO12M_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetFro32MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >>
+            PMC_FRO192M_DIVSEL_SHIFT) & FRO32M_ENA)
+    {
+        freq = FRO32M_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetFro48MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >>
+            PMC_FRO192M_DIVSEL_SHIFT) & FRO48M_ENA)
+    {
+        freq = FRO48M_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetOsc32kFreq(void)
+{
+    uint32_t freq = 0;
+    if ((SYSCON->OSC32CLKSEL & SYSCON_OSC32CLKSEL_SEL32KHZ_MASK) != 0)
+    {
+        freq = CLOCK_GetXtal32kFreq();
+    }
+    else
+    {
+        freq = CLOCK_GetFro32kFreq();
+    }
+    return freq;
+}
+
+/* Return main clock rate */
+static uint32_t CLOCK_GetMainClockRate(void)
+{
+    uint32_t freq = 0;
+
+    switch ((main_clock_src_t)((SYSCON->MAINCLKSEL & SYSCON_MAINCLKSEL_SEL_MASK)
+                    >> SYSCON_MAINCLKSEL_SEL_SHIFT))
+    {
+    case kCLOCK_MainFro12M:
+        freq = CLOCK_GetFro12MFreq();
+        break;
+
+    case kCLOCK_MainOsc32k:
+        freq = CLOCK_GetOsc32kFreq();
+        break;
+
+    case kCLOCK_MainXtal32M:
+        freq = CLOCK_GetXtal32MFreq();
+        break;
+
+    case kCLOCK_MainFro32M:
+        freq = CLOCK_GetFro32MFreq();
+        break;
+
+    case kCLOCK_MainFro48M:
+        freq = CLOCK_GetFro48MFreq();
+        break;
+
+    case kCLOCK_MainExtClk:
+        freq = g_Ext_Clk_Freq;
+        break;
+
+    case kCLOCK_MainFro1M:
+        freq = CLOCK_GetFro1MFreq();
+        break;
+    }
+
+    return freq;
+}
+
+
+
+/* ----------------------------------------------------------------------------
+   -- Core clock
+   ---------------------------------------------------------------------------- */
+
+uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
+
+#if defined(__ICCARM__)
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+void ResetISR(void)
+{
+    __asm volatile(
+        "LDR    R0,=0x40000804\t\n"          // load co-processor boot address (from CPBOOT)
+        "LDR    R0,[R0]\t\n"                 // get address to branch to
+        "MOVS   R0,R0\t\n"                   // Check if 0
+        "BEQ.N  masterboot\t\n"              // if zero in boot reg, we just branch to  real reset
+        "LDR    R1,=0x40000808\t\n"          // load co-processor stack pointer (from CPSTACK)
+        "LDR    R1,[R1]\t\n"
+        "MOV    SP,R1\t\n"
+        "BX     R0\t\n"                      // branch to boot address
+        "masterboot:\t\n"
+        "LDR    R0, =ResetISR2\t\n"          // jump to 'real' reset handler
+        "BX     R0\t\n");
+}
+
+void ResetISR2(void)
+{
+    if ((void (*)(void))WarmMain != NULL)
+    {
+        unsigned int warm_start;
+        uint32_t     pmc_lpmode;
+        uint32_t     pmc_resetcause;
+        uint32_t     pwr_pdsleepcfg;
+
+        pmc_resetcause = PMC->RESETCAUSE;
+        pwr_pdsleepcfg = PMC->PDSLEEPCFG;
+
+        pmc_lpmode = BOOT_GetStartPowerMode();
+
+        warm_start = (pmc_lpmode == 0x02);  /* coming from power down mode*/
+
+        // check if the reset cause is only a timer wakeup or io wakeup with all memory banks held
+        warm_start  &= ( !(pmc_resetcause & (PMC_RESETCAUSE_POR_MASK
+                                      | PMC_RESETCAUSE_PADRESET_MASK
+                                      | PMC_RESETCAUSE_BODRESET_MASK
+                                      | PMC_RESETCAUSE_SYSTEMRESET_MASK
+                                      | PMC_RESETCAUSE_WDTRESET_MASK
+                                      | PMC_RESETCAUSE_WAKEUPIORESET_MASK ))
+                            &&  ( pmc_resetcause & PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK         )
+                            &&  ((pwr_pdsleepcfg & PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK) == 0x0    )     /* BANK7 memory bank held */
+                            &&  ( pwr_pdsleepcfg & PMC_PDSLEEPCFG_PDEN_LDO_MEM_MASK            )     /* LDO MEM enabled */
+                        );
+
+        if (warm_start)
+        {
+
+            if (SYSCON->CPSTACK)
+            {
+                /* if CPSTACK is not NULL, switch to CPSTACK value so we avoid to corrupt the stack used before power down
+                 * Note: it looks like enough to switch to new SP now and not earlier */
+                __asm volatile(
+                        "LDR    R1,=0x40000808\t\n" // load co-processor stack pointer (from CPSTACK)
+                        "LDR    R1,[R1]\t\n"
+                        "MOV    SP,R1\t\n"
+                        );
+            }
+            // Check to see if we are running the code from a non-zero
+            // address (eg RAM, external flash), in which case we need
+            // to modify the VTOR register to tell the CPU that the
+            // vector table is located at a non-0x0 address.
+            unsigned int *pSCB_VTOR = (unsigned int *)0xE000ED08;
+            if (((unsigned int)(&__Vectors) != 0))
+            {
+                // CMSIS : SCB->VTOR = <address of vector table>
+                *pSCB_VTOR = (unsigned int)(&__Vectors);
+            }
+
+            if ((void (*)(void))SystemInit != NULL)
+            {
+                SystemInit();
+            }
+
+            WarmMain();
+
+            //
+            // WarmMain() shouldn't return, but if it does, we'll just enter an infinite loop
+            //
+            while (1)
+            {
+                ;
+            }
+        }
+    }
+
+    // Check to see if we are running the code from a non-zero
+    // address (eg RAM, external flash), in which case we need
+    // to modify the VTOR register to tell the CPU that the
+    // vector table is located at a non-0x0 address.
+    unsigned int *pSCB_VTOR = (unsigned int *)0xE000ED08;
+    if ((unsigned int)(&__Vectors) != 0)
+    {
+        // CMSIS : SCB->VTOR = <address of vector table>
+        *pSCB_VTOR = (unsigned int)(&__Vectors);
+    }
+
+    SystemInit();
+
+#if defined(__cplusplus)
+    //
+    // Call C++ library initialisation
+    //
+    __libc_init_array();
+#endif
+}
+#endif
+
+/* ----------------------------------------------------------------------------
+   -- SystemInit()
+   ---------------------------------------------------------------------------- */
+
+void SystemInit (void) {
+    uint32_t trim;
+    /* Initialise SystemCoreClock value */
+    SystemCoreClockUpdate();
+
+    /* Initialise NVIC priority grouping value */
+    NVIC_SetPriorityGrouping(4);
+
+    /* Apply FRO1M trim value */
+    trim = *(uint32_t*)(0x9FCD0U);
+
+    if(trim & 0x1U)
+    {
+        PMC->FRO1M = (PMC->FRO1M & ~PMC_FRO1M_FREQSEL_MASK) | ((trim>>1) & PMC_FRO1M_FREQSEL_MASK);
+    }
+}
+
+/* ----------------------------------------------------------------------------
+   -- SystemCoreClockUpdate()
+   ---------------------------------------------------------------------------- */
+
+void SystemCoreClockUpdate (void) {
+    SystemCoreClock = (CLOCK_GetMainClockRate() / ((SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK) + 1U));
+}
+
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/system_JN5189.h b/third_party/nxp/JN5189DK6/devices/JN5189/system_JN5189.h
new file mode 100755
index 0000000..6f33023
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/system_JN5189.h
@@ -0,0 +1,92 @@
+/*
+** ###################################################################
+**     Processors:          JN5189HN
+**                          JN5189THN
+**
+**     Compilers:           Keil ARM C/C++ Compiler
+**                          GNU C Compiler
+**                          IAR ANSI C/C++ Compiler for ARM
+**                          MCUXpresso Compiler
+**
+**     Reference manual:    JN5189 User manual Rev0.1 27 July 2018
+**     Version:             rev. 1.0, 2018-07-31
+**     Build:               b180731
+**
+**     Abstract:
+**         Provides a system configuration function and a global variable that
+**         contains the system frequency. It configures the device and initializes
+**         the oscillator (PLL) that is part of the microcontroller device.
+**
+**     Copyright 2016 Freescale Semiconductor, Inc.
+**     Copyright 2016-2018 NXP
+**
+**     SPDX-License-Identifier: BSD-3-Clause
+**
+**     http:                 www.nxp.com
+**     mail:                 support@nxp.com
+**
+**     Revisions:
+**     - rev. 1.0 (2018-07-31)
+**         Initial version.
+**
+** ###################################################################
+*/
+
+/*!
+ * @file JN5189
+ * @version 1.0
+ * @date 2018-07-31
+ * @brief Device specific configuration file for JN5189 (header file)
+ *
+ * Provides a system configuration function and a global variable that contains
+ * the system frequency. It configures the device and initializes the oscillator
+ * (PLL) that is part of the microcontroller device.
+ */
+
+#ifndef _SYSTEM_JN5189_H_
+#define _SYSTEM_JN5189_H_                        /**< Symbol preventing repeated inclusion */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define DEFAULT_SYSTEM_CLOCK           12000000u           /* Default System clock value */
+
+
+/**
+ * @brief System clock frequency (core clock)
+ *
+ * The system clock frequency supplied to the SysTick timer and the processor
+ * core clock. This variable can be used by the user application to setup the
+ * SysTick timer or configure other parameters. It may also be used by debugger to
+ * query the frequency of the debug timer or configure the trace clock speed
+ * SystemCoreClock is initialized with a correct predefined value.
+ */
+extern uint32_t SystemCoreClock;
+
+/**
+ * @brief Setup the microcontroller system.
+ *
+ * Typically this function configures the oscillator (PLL) that is part of the
+ * microcontroller device. For systems with variable clock speed it also updates
+ * the variable SystemCoreClock. SystemInit is called from startup_device file.
+ */
+void SystemInit (void);
+
+/**
+ * @brief Updates the SystemCoreClock variable.
+ *
+ * It must be called whenever the core clock is changed during program
+ * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
+ * the current core clock.
+ */
+void SystemCoreClockUpdate (void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _SYSTEM_JN5189_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console.c b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console.c
new file mode 100755
index 0000000..9f4b4ff
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console.c
@@ -0,0 +1,1131 @@
+/*
+ * This is a modified version of the file printf.c, which was distributed
+ * by Motorola as part of the M5407C3BOOT.zip package used to initialize
+ * the M5407C3 evaluation board.
+ *
+ * Copyright:
+ *      1999-2000 MOTOROLA, INC. All Rights Reserved.
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Motorola, Inc. This
+ *  software is provided on an "AS IS" basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, MOTOROLA
+ *  DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ *  PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE
+ *  SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY
+ *  ACCOMPANYING WRITTEN MATERIALS.
+ *
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING
+ *  WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
+ *  INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
+ *  LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
+ *
+ *  Motorola assumes no responsibility for the maintenance and support
+ *  of this software
+
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
+#include <stdio.h>
+#endif
+
+#ifdef FSL_RTOS_FREE_RTOS
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "task.h"
+#endif
+
+#include "fsl_debug_console_conf.h"
+#include "fsl_str.h"
+
+#include "fsl_common.h"
+#include "serial_manager.h"
+
+#include "fsl_debug_console.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifndef NDEBUG
+#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
+#undef assert
+#define assert(n)
+#endif
+#endif
+
+#if SDK_DEBUGCONSOLE
+#define DEBUG_CONSOLE_FUNCTION_PREFIX
+#else
+#define DEBUG_CONSOLE_FUNCTION_PREFIX static
+#endif
+
+/*! @brief character backspace ASCII value */
+#define DEBUG_CONSOLE_BACKSPACE 127U
+
+/* lock definition */
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS)
+
+static SemaphoreHandle_t s_debugConsoleReadSemaphore;
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+static SemaphoreHandle_t s_debugConsoleReadWaitSemaphore;
+#endif
+
+#elif (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM)
+
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+static volatile uint8_t s_debugConsoleReadWaitSemaphore;
+#endif
+
+#else
+
+#endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */
+
+/*! @brief get current runing environment is ISR or not */
+#ifdef __CA7_REV
+#define IS_RUNNING_IN_ISR() SystemGetIRQNestingLevel()
+#else
+#define IS_RUNNING_IN_ISR() __get_IPSR()
+#endif /* __CA7_REV */
+
+/* semaphore definition */
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS)
+
+/* mutex semaphore */
+#define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex) ((mutex) = xSemaphoreCreateMutex())
+
+/* clang-format off */
+#define DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(mutex) \
+{                                                 \
+        if (IS_RUNNING_IN_ISR() == 0U)            \
+        {                                         \
+            (void)xSemaphoreGive(mutex);                \
+        }                                         \
+}
+
+#define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) \
+{                                                          \
+        if (IS_RUNNING_IN_ISR() == 0U)                     \
+        {                                                  \
+            (void)xSemaphoreTake(mutex, portMAX_DELAY);          \
+        }                                                  \
+}
+
+#define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) \
+{                                                                     \
+        if (IS_RUNNING_IN_ISR() == 0U)                                \
+        {                                                             \
+            result = xSemaphoreTake(mutex, 0U);                       \
+        }                                                             \
+        else                                                          \
+        {                                                             \
+            result = 1U;                                              \
+        }                                                             \
+}
+/* clang-format on */
+
+/* Binary semaphore */
+#define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary) ((binary) = xSemaphoreCreateBinary())
+#define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) ((void)xSemaphoreTake(binary, portMAX_DELAY))
+#define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) ((void)xSemaphoreGiveFromISR(binary, NULL))
+
+#elif (DEBUG_CONSOLE_SYNCHRONIZATION_BM == DEBUG_CONSOLE_SYNCHRONIZATION_MODE)
+
+#define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex)
+#define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex)
+#define DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(mutex)
+#define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) (result = 1U)
+
+#define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary)
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+#define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) \
+    {                                                        \
+        while (!binary)                                      \
+        {                                                    \
+        }                                                    \
+        binary = false;                                      \
+    }
+#define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) (binary = true)
+#else
+#define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary)
+#define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary)
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/* add other implementation here
+ *such as :
+ * #elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DDEBUG_CONSOLE_SYNCHRONIZATION_xxx)
+ */
+
+#else
+
+#error RTOS type is not defined by DEBUG_CONSOLE_SYNCHRONIZATION_MODE.
+
+#endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/* receive state structure */
+typedef struct _debug_console_write_ring_buffer
+{
+    uint32_t ringBufferSize;
+    volatile uint32_t ringHead;
+    volatile uint32_t ringTail;
+    uint8_t ringBuffer[DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN];
+} debug_console_write_ring_buffer_t;
+#endif
+
+typedef struct _debug_console_state_struct
+{
+    uint8_t serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
+    serial_handle_t serialHandle; /*!< serial manager handle */
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+    debug_console_write_ring_buffer_t writeRingBuffer;
+    uint8_t readRingBuffer[DEBUG_CONSOLE_RECEIVE_BUFFER_LEN];
+#endif
+    uint8_t serialWriteHandleBuffer[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
+    uint8_t serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE];
+} debug_console_state_struct_t;
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Debug console state information. */
+static debug_console_state_struct_t s_debugConsoleState;
+serial_handle_t g_serialHandle; /*!< serial manager handle */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief This is a printf call back function which is used to relocate the log to buffer
+ * or print the log immediately when the local buffer is full.
+ *
+ * @param[in] buf   Buffer to store log.
+ * @param[in] indicator Buffer index.
+ * @param[in] val Target character to store.
+ * @param[in] len length of the character
+ *
+ */
+#if SDK_DEBUGCONSOLE
+static void DbgConsole_PrintCallback(char *buf, int32_t *indicator, char dbgVal, int len);
+#endif
+
+status_t DbgConsole_ReadOneCharacter(uint8_t *ch);
+int DbgConsole_SendData(uint8_t *ch, size_t size);
+int DbgConsole_SendDataReliable(uint8_t *ch, size_t size);
+int DbgConsole_ReadLine(uint8_t *buf, size_t size);
+int DbgConsole_ReadCharacter(uint8_t *ch);
+
+#if ((SDK_DEBUGCONSOLE > 0U) ||                                                   \
+     ((SDK_DEBUGCONSOLE == 0U) && defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \
+      (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))))
+DEBUG_CONSOLE_FUNCTION_PREFIX status_t DbgConsole_Flush(void);
+#endif
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+
+static void DbgConsole_SerialManagerTxCallback(void *callbackParam,
+                                               serial_manager_callback_message_t *message,
+                                               serial_manager_status_t status)
+{
+    debug_console_state_struct_t *ioState;
+    uint32_t sendDataLength;
+
+    if ((NULL == callbackParam) || (NULL == message))
+    {
+        return;
+    }
+
+    ioState = (debug_console_state_struct_t *)callbackParam;
+
+    ioState->writeRingBuffer.ringTail += message->length;
+    if (ioState->writeRingBuffer.ringTail >= ioState->writeRingBuffer.ringBufferSize)
+    {
+        ioState->writeRingBuffer.ringTail = 0U;
+    }
+
+    if (kStatus_SerialManager_Success == status)
+    {
+        if (ioState->writeRingBuffer.ringTail != ioState->writeRingBuffer.ringHead)
+        {
+            if (ioState->writeRingBuffer.ringHead > ioState->writeRingBuffer.ringTail)
+            {
+                sendDataLength = ioState->writeRingBuffer.ringHead - ioState->writeRingBuffer.ringTail;
+            }
+            else
+            {
+                sendDataLength = ioState->writeRingBuffer.ringBufferSize - ioState->writeRingBuffer.ringTail;
+            }
+
+            (void)SerialManager_WriteNonBlocking(
+                ((serial_write_handle_t)&ioState->serialWriteHandleBuffer[0]),
+                &ioState->writeRingBuffer.ringBuffer[ioState->writeRingBuffer.ringTail], sendDataLength);
+        }
+    }
+    else if (kStatus_SerialManager_Canceled == status)
+    {
+        ioState->writeRingBuffer.ringTail = 0U;
+        ioState->writeRingBuffer.ringHead = 0U;
+    }
+    else
+    {
+        /*MISRA rule 16.4*/
+    }
+}
+
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+
+static void DbgConsole_SerialManagerRxCallback(void *callbackParam,
+                                               serial_manager_callback_message_t *message,
+                                               serial_manager_status_t status)
+{
+    if ((NULL == callbackParam) || (NULL == message))
+    {
+        return;
+    }
+
+    if (kStatus_SerialManager_Notify == status)
+    {
+    }
+    else if (kStatus_SerialManager_Success == status)
+    {
+        /* release s_debugConsoleReadWaitSemaphore from RX callback */
+        DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(s_debugConsoleReadWaitSemaphore);
+    }
+    else
+    {
+        /*MISRA rule 16.4*/
+    }
+}
+#endif
+
+#endif
+
+status_t DbgConsole_ReadOneCharacter(uint8_t *ch)
+{
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \
+    (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED)
+    return kStatus_Fail;
+#else
+    status_t status = (status_t)kStatus_SerialManager_Error;
+
+/* recieve one char every time */
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    status = (status_t)SerialManager_ReadNonBlocking(
+        ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), ch, 1);
+#else
+    status = (status_t)SerialManager_ReadBlocking(
+        ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), ch, 1);
+#endif
+    if ((status_t)kStatus_SerialManager_Success != status)
+    {
+        return (status_t)kStatus_Fail;
+    }
+    /* wait s_debugConsoleReadWaitSemaphore from RX callback */
+    DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(s_debugConsoleReadWaitSemaphore);
+
+    return (status_t)kStatus_Success;
+#endif
+
+#else
+
+    return (status_t)kStatus_Fail;
+
+#endif
+}
+
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+static status_t DbgConsole_EchoCharacter(uint8_t *ch, bool isGetChar, int *index)
+{
+    /* Due to scanf take \n and \r as end of string,should not echo */
+    if (((*ch != (uint8_t)'\r') && (*ch != (uint8_t)'\n')) || (isGetChar))
+    {
+        /* recieve one char every time */
+        if (1 != DbgConsole_SendDataReliable(ch, 1U))
+        {
+            return (status_t)kStatus_Fail;
+        }
+    }
+
+    if ((!isGetChar) && (index != NULL))
+    {
+        if (DEBUG_CONSOLE_BACKSPACE == *ch)
+        {
+            if ((*index >= 2))
+            {
+                *index -= 2;
+            }
+            else
+            {
+                *index = 0;
+            }
+        }
+    }
+
+    return (status_t)kStatus_Success;
+}
+#endif
+
+int DbgConsole_SendData(uint8_t *ch, size_t size)
+{
+    status_t status = (status_t)kStatus_SerialManager_Error;
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    uint32_t sendDataLength;
+    int txBusy = 0;
+#endif
+    assert(NULL != ch);
+    assert(0 != size);
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    uint32_t regPrimask = DisableGlobalIRQ();
+    if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail)
+    {
+        txBusy = 1;
+        sendDataLength =
+            (s_debugConsoleState.writeRingBuffer.ringHead + s_debugConsoleState.writeRingBuffer.ringBufferSize -
+             s_debugConsoleState.writeRingBuffer.ringTail) %
+            s_debugConsoleState.writeRingBuffer.ringBufferSize;
+    }
+    else
+    {
+        sendDataLength = 0U;
+    }
+    sendDataLength = s_debugConsoleState.writeRingBuffer.ringBufferSize - sendDataLength - 1;
+    if (sendDataLength <= size)
+    {
+        EnableGlobalIRQ(regPrimask);
+        return -1;
+    }
+    for (int i = 0; i < (int)size; i++)
+    {
+        s_debugConsoleState.writeRingBuffer.ringBuffer[s_debugConsoleState.writeRingBuffer.ringHead++] = ch[i];
+        if (s_debugConsoleState.writeRingBuffer.ringHead >= s_debugConsoleState.writeRingBuffer.ringBufferSize)
+        {
+            s_debugConsoleState.writeRingBuffer.ringHead = 0U;
+        }
+    }
+
+    status = (status_t)kStatus_SerialManager_Success;
+
+    if (txBusy == 0)
+    {
+        if (s_debugConsoleState.writeRingBuffer.ringHead > s_debugConsoleState.writeRingBuffer.ringTail)
+        {
+            sendDataLength =
+                s_debugConsoleState.writeRingBuffer.ringHead - s_debugConsoleState.writeRingBuffer.ringTail;
+        }
+        else
+        {
+            sendDataLength =
+                s_debugConsoleState.writeRingBuffer.ringBufferSize - s_debugConsoleState.writeRingBuffer.ringTail;
+        }
+
+        status = (status_t)SerialManager_WriteNonBlocking(
+            ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]),
+            &s_debugConsoleState.writeRingBuffer.ringBuffer[s_debugConsoleState.writeRingBuffer.ringTail],
+            sendDataLength);
+    }
+    EnableGlobalIRQ(regPrimask);
+#else
+    status = (status_t)SerialManager_WriteBlocking(
+        ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), ch, size);
+#endif
+    return (((status_t)kStatus_Success == status) ? (int)size : -1);
+}
+
+int DbgConsole_SendDataReliable(uint8_t *ch, size_t size)
+{
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+#if (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))
+    status_t status = kStatus_SerialManager_Error;
+    uint32_t sendDataLength;
+    uint32_t totalLength = size;
+    int sentLength;
+#endif /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */
+#else
+    status_t status = kStatus_SerialManager_Error;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+    assert(NULL != ch);
+    assert(0 != size);
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+
+#if (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))
+    do
+    {
+        uint32_t regPrimask = DisableGlobalIRQ();
+        if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail)
+        {
+            sendDataLength =
+                (s_debugConsoleState.writeRingBuffer.ringHead + s_debugConsoleState.writeRingBuffer.ringBufferSize -
+                 s_debugConsoleState.writeRingBuffer.ringTail) %
+                s_debugConsoleState.writeRingBuffer.ringBufferSize;
+        }
+        else
+        {
+            sendDataLength = 0U;
+        }
+        sendDataLength = s_debugConsoleState.writeRingBuffer.ringBufferSize - sendDataLength - 1U;
+
+        if (sendDataLength > 0U)
+        {
+            if (sendDataLength > totalLength)
+            {
+                sendDataLength = totalLength;
+            }
+
+            sentLength = DbgConsole_SendData(&ch[size - totalLength], sendDataLength);
+            if (sentLength > 0)
+            {
+                totalLength = totalLength - (uint32_t)sentLength;
+            }
+        }
+        EnableGlobalIRQ(regPrimask);
+
+        if (totalLength != 0U)
+        {
+            status = DbgConsole_Flush();
+            if ((status_t)kStatus_Success != status)
+            {
+                break;
+            }
+        }
+    } while (totalLength != 0U);
+    return (status_t)(uint32_t)((uint32_t)size - totalLength);
+#else
+    return DbgConsole_SendData(ch, size);
+#endif /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */
+
+#else
+    status          = (status_t)SerialManager_WriteBlocking(
+        ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), ch, size);
+    return (((status_t)kStatus_Success == status) ? (int)size : -1);
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+}
+
+int DbgConsole_ReadLine(uint8_t *buf, size_t size)
+{
+    int i = 0;
+
+    assert(buf != NULL);
+
+    /* take mutex lock function */
+    DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore);
+
+    do
+    {
+        /* recieve one char every time */
+        if ((status_t)kStatus_Success != DbgConsole_ReadOneCharacter(&buf[i]))
+        {
+            /* release mutex lock function */
+            DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+            i = -1;
+            break;
+        }
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+        (void)DbgConsole_EchoCharacter(&buf[i], false, &i);
+#endif
+        /* analysis data */
+        if (((uint8_t)'\r' == buf[i]) || ((uint8_t)'\n' == buf[i]))
+        {
+            /* End of Line. */
+            if (0 == i)
+            {
+                buf[i] = (uint8_t)'\0';
+                continue;
+            }
+            else
+            {
+                break;
+            }
+        }
+        i++;
+    } while (i < (int)size);
+
+    /* get char should not add '\0'*/
+    if (i == (int)size)
+    {
+        buf[i] = (uint8_t)'\0';
+    }
+    else
+    {
+        buf[i + 1] = (uint8_t)'\0';
+    }
+
+    /* release mutex lock function */
+    DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+
+    return i;
+}
+
+int DbgConsole_ReadCharacter(uint8_t *ch)
+{
+    int ret;
+
+    assert(ch);
+
+    /* take mutex lock function */
+    DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore);
+    /* read one character */
+    if ((status_t)kStatus_Success == DbgConsole_ReadOneCharacter(ch))
+    {
+        ret = 1;
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+        (void)DbgConsole_EchoCharacter(ch, true, NULL);
+#endif
+    }
+    else
+    {
+        ret = -1;
+    }
+
+    /* release mutex lock function */
+    DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+
+    return ret;
+}
+
+#if SDK_DEBUGCONSOLE
+static void DbgConsole_PrintCallback(char *buf, int32_t *indicator, char dbgVal, int len)
+{
+    int i = 0;
+
+    for (i = 0; i < len; i++)
+    {
+        if (((uint32_t)*indicator + 1UL) >= DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN)
+        {
+            (void)DbgConsole_SendDataReliable((uint8_t *)buf, (uint32_t)(*indicator));
+            *indicator = 0;
+        }
+
+        buf[*indicator] = dbgVal;
+        (*indicator)++;
+    }
+}
+#endif
+
+/*************Code for DbgConsole Init, Deinit, Printf, Scanf *******************************/
+
+/* See fsl_debug_console.h for documentation of this function. */
+status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq)
+{
+    serial_manager_config_t serialConfig;
+    status_t status = (status_t)kStatus_SerialManager_Error;
+
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+    serial_port_uart_config_t uartConfig = {
+        .instance     = instance,
+        .clockRate    = clkSrcFreq,
+        .baudRate     = baudRate,
+        .parityMode   = kSerialManager_UartParityDisabled,
+        .stopBitCount = kSerialManager_UartOneStopBit,
+        .enableRx     = 1,
+        .enableTx     = 1,
+    };
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+    serial_port_usb_cdc_config_t usbCdcConfig = {
+        .controllerIndex = (serial_port_usb_cdc_controller_index_t)instance,
+    };
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+    serial_port_swo_config_t swoConfig = {
+        .clockRate = clkSrcFreq,
+        .baudRate  = baudRate,
+        .port      = instance,
+        .protocol  = kSerialManager_SwoProtocolNrz,
+    };
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+    serial_port_usb_cdc_virtual_config_t usbCdcVirtualConfig = {
+        .controllerIndex = (serial_port_usb_cdc_virtual_controller_index_t)instance,
+    };
+#endif
+    serialConfig.type = device;
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    serialConfig.ringBuffer     = &s_debugConsoleState.readRingBuffer[0];
+    serialConfig.ringBufferSize = DEBUG_CONSOLE_RECEIVE_BUFFER_LEN;
+#endif
+
+    if (kSerialPort_Uart == device)
+    {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        serialConfig.portConfig = &uartConfig;
+#else
+        return status;
+#endif
+    }
+    else if (kSerialPort_UsbCdc == device)
+    {
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        serialConfig.portConfig = &usbCdcConfig;
+#else
+        return status;
+#endif
+    }
+    else if (kSerialPort_Swo == device)
+    {
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        serialConfig.portConfig = &swoConfig;
+#else
+        return status;
+#endif
+    }
+    else if (kSerialPort_UsbCdcVirtual == device)
+    {
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        serialConfig.portConfig = &usbCdcVirtualConfig;
+#else
+        return status;
+#endif
+    }
+    else
+    {
+        return status;
+    }
+
+    (void)memset(&s_debugConsoleState, 0, sizeof(s_debugConsoleState));
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    s_debugConsoleState.writeRingBuffer.ringBufferSize = DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN;
+#endif
+
+    s_debugConsoleState.serialHandle = (serial_handle_t)&s_debugConsoleState.serialHandleBuffer[0];
+    status                           = (status_t)SerialManager_Init(s_debugConsoleState.serialHandle, &serialConfig);
+
+    assert(kStatus_SerialManager_Success == status);
+
+    DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+    DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(s_debugConsoleReadWaitSemaphore);
+#endif
+
+    {
+        status = (status_t)SerialManager_OpenWriteHandle(
+            s_debugConsoleState.serialHandle, ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]));
+        assert(kStatus_SerialManager_Success == status);
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+        (void)SerialManager_InstallTxCallback(((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]),
+                                              DbgConsole_SerialManagerTxCallback, &s_debugConsoleState);
+#endif
+    }
+
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+    {
+        status = (status_t)SerialManager_OpenReadHandle(
+            s_debugConsoleState.serialHandle, ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]));
+        assert(kStatus_SerialManager_Success == status);
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+        (void)SerialManager_InstallRxCallback(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]),
+                                              DbgConsole_SerialManagerRxCallback, &s_debugConsoleState);
+#endif
+    }
+#endif
+
+    g_serialHandle = s_debugConsoleState.serialHandle;
+
+    return kStatus_Success;
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+status_t DbgConsole_Deinit(void)
+{
+    {
+        if (s_debugConsoleState.serialHandle != NULL)
+        {
+            (void)SerialManager_CloseWriteHandle(
+                ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]));
+        }
+    }
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+    {
+        if (s_debugConsoleState.serialHandle != NULL)
+        {
+            (void)SerialManager_CloseReadHandle(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]));
+        }
+    }
+#endif
+    if (s_debugConsoleState.serialHandle)
+    {
+        if (kStatus_SerialManager_Success == SerialManager_Deinit(s_debugConsoleState.serialHandle))
+        {
+            s_debugConsoleState.serialHandle = NULL;
+            g_serialHandle                   = NULL;
+        }
+    }
+    return (status_t)kStatus_Success;
+}
+
+#if ((SDK_DEBUGCONSOLE > 0U) ||                                                   \
+     ((SDK_DEBUGCONSOLE == 0U) && defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \
+      (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))))
+DEBUG_CONSOLE_FUNCTION_PREFIX status_t DbgConsole_Flush(void)
+{
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED)
+
+    if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail)
+    {
+        return (status_t)kStatus_Fail;
+    }
+
+#else
+
+    while (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail)
+    {
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS)
+        if (0U == IS_RUNNING_IN_ISR())
+        {
+            if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState())
+            {
+                vTaskDelay(1);
+            }
+        }
+        else
+        {
+            return (status_t)kStatus_Fail;
+        }
+#endif
+    }
+
+#endif
+
+#endif
+    return (status_t)kStatus_Success;
+}
+#endif
+
+#if SDK_DEBUGCONSOLE
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Printf(const char *formatString, ...)
+{
+    va_list ap;
+    int logLength = 0, dbgResult = 0;
+    char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {'\0'};
+
+    if (NULL == g_serialHandle)
+    {
+        return 0;
+    }
+
+    va_start(ap, formatString);
+    /* format print log first */
+    logLength = StrFormatPrintf(formatString, ap, printBuf, DbgConsole_PrintCallback);
+    /* print log */
+    dbgResult = DbgConsole_SendDataReliable((uint8_t *)printBuf, (size_t)logLength);
+
+    va_end(ap);
+
+    return dbgResult;
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Putchar(int ch)
+{
+    /* print char */
+    return DbgConsole_SendDataReliable((uint8_t *)&ch, 1U);
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Scanf(char *formatString, ...)
+{
+    va_list ap;
+    int formatResult;
+    char scanfBuf[DEBUG_CONSOLE_SCANF_MAX_LOG_LEN + 1U] = {'\0'};
+
+    /* scanf log */
+    (void)DbgConsole_ReadLine((uint8_t *)scanfBuf, DEBUG_CONSOLE_SCANF_MAX_LOG_LEN);
+    /* get va_list */
+    va_start(ap, formatString);
+    /* format scanf log */
+    formatResult = StrFormatScanf(scanfBuf, formatString, ap);
+
+    va_end(ap);
+
+    return formatResult;
+}
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+status_t DbgConsole_TryGetchar(char *ch)
+{
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+    uint32_t length = 0;
+    status_t status = (status_t)kStatus_Fail;
+
+    assert(ch);
+
+    /* take mutex lock function */
+    DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore);
+
+    if (kStatus_SerialManager_Success ==
+        SerialManager_TryRead(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), (uint8_t *)ch, 1,
+                              &length))
+    {
+        if (length != 0U)
+        {
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+            (void)DbgConsole_EchoCharacter((uint8_t *)ch, true, NULL);
+#endif
+            status = (status_t)kStatus_Success;
+        }
+    }
+    /* release mutex lock function */
+    DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+    return status;
+#else
+    return (status_t)kStatus_Fail;
+#endif
+}
+#endif
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Getchar(void)
+{
+    uint8_t ch = 0U;
+
+    /* Get char */
+    (void)DbgConsole_ReadCharacter(&ch);
+
+    return (int)ch;
+}
+
+#endif /* SDK_DEBUGCONSOLE */
+
+/*************Code to support toolchain's printf, scanf *******************************/
+/* These function __write and __read is used to support IAR toolchain to printf and scanf*/
+#if (defined(__ICCARM__))
+#if defined(SDK_DEBUGCONSOLE_UART)
+#pragma weak __write
+size_t __write(int handle, const unsigned char *buffer, size_t size)
+{
+    if (buffer == 0)
+    {
+        /*
+         * This means that we should flush internal buffers.  Since we don't we just return.
+         * (Remember, "handle" == -1 means that all handles should be flushed.)
+         */
+        return 0;
+    }
+
+    /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+    if ((handle != 1) && (handle != 2))
+    {
+        return ((size_t)-1);
+    }
+
+    /* Send data. */
+    DbgConsole_SendDataReliable((uint8_t *)buffer, size);
+
+    return size;
+}
+
+#pragma weak __read
+size_t __read(int handle, unsigned char *buffer, size_t size)
+{
+    uint8_t ch     = 0U;
+    int actualSize = 0U;
+
+    /* This function only reads from "standard in", for all other file  handles it returns failure. */
+    if (handle != 0)
+    {
+        return ((size_t)-1);
+    }
+
+    /* Receive data.*/
+    for (; size > 0; size--)
+    {
+        DbgConsole_ReadCharacter(&ch);
+        if (ch == 0)
+        {
+            break;
+        }
+
+        *buffer++ = ch;
+        actualSize++;
+    }
+
+    return actualSize;
+}
+#endif /* SDK_DEBUGCONSOLE_UART */
+
+/* support LPC Xpresso with RedLib */
+#elif (defined(__REDLIB__))
+
+#if (defined(SDK_DEBUGCONSOLE_UART))
+int __attribute__((weak)) __sys_write(int handle, char *buffer, int size)
+{
+    if (buffer == 0)
+    {
+        /* return -1 if error. */
+        return -1;
+    }
+
+    /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+    if ((handle != 1) && (handle != 2))
+    {
+        return -1;
+    }
+
+    /* Send data. */
+    DbgConsole_SendDataReliable((uint8_t *)buffer, size);
+
+    return 0;
+}
+
+int __attribute__((weak)) __sys_readc(void)
+{
+    char tmp;
+
+    /* Receive data. */
+    DbgConsole_ReadCharacter((uint8_t *)&tmp);
+
+    return tmp;
+}
+#endif
+
+/* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+#if defined(SDK_DEBUGCONSOLE_UART)
+#if defined(__CC_ARM)
+struct __FILE
+{
+    int handle;
+    /*
+     * Whatever you require here. If the only file you are using is standard output using printf() for debugging,
+     * no file handling is required.
+     */
+};
+#endif
+
+/* FILE is typedef in stdio.h. */
+#pragma weak __stdout
+#pragma weak __stdin
+FILE __stdout;
+FILE __stdin;
+
+#pragma weak fputc
+int fputc(int ch, FILE *f)
+{
+    /* Send data. */
+    return DbgConsole_SendDataReliable((uint8_t *)(&ch), 1);
+}
+
+#pragma weak fgetc
+int fgetc(FILE *f)
+{
+    char ch;
+
+    /* Receive data. */
+    DbgConsole_ReadCharacter((uint8_t *)&ch);
+
+    return ch;
+}
+
+/*
+ * Terminate the program, passing a return code back to the user.
+ * This function may not return.
+ */
+void _sys_exit(int returncode)
+{
+    while (1)
+    {
+    }
+}
+
+/*
+ * Writes a character to the output channel. This function is used
+ * for last-resort error message output.
+ */
+void _ttywrch(int ch)
+{
+    char ench = ch;
+    DbgConsole_SendDataReliable((uint8_t *)(&ench), 1);
+}
+
+char *_sys_command_string(char *cmd, int len)
+{
+    return (cmd);
+}
+#endif /* SDK_DEBUGCONSOLE_UART */
+
+/* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/
+#elif (defined(__GNUC__))
+
+#if ((defined(__GNUC__) && (!defined(__MCUXPRESSO)) && (defined(SDK_DEBUGCONSOLE_UART))) || \
+     (defined(__MCUXPRESSO) && (defined(SDK_DEBUGCONSOLE_UART))))
+int __attribute__((weak)) _write(int handle, char *buffer, int size);
+int __attribute__((weak)) _write(int handle, char *buffer, int size)
+{
+    if (buffer == NULL)
+    {
+        /* return -1 if error. */
+        return -1;
+    }
+
+    /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+    if ((handle != 1) && (handle != 2))
+    {
+        return -1;
+    }
+
+    /* Send data. */
+    (void)DbgConsole_SendDataReliable((uint8_t *)buffer, (size_t)size);
+
+    return size;
+}
+
+int __attribute__((weak)) _read(int handle, char *buffer, int size);
+int __attribute__((weak)) _read(int handle, char *buffer, int size)
+{
+    uint8_t ch     = 0U;
+    int actualSize = 0;
+
+    /* This function only reads from "standard in", for all other file handles it returns failure. */
+    if (handle != 0)
+    {
+        return -1;
+    }
+
+    /* Receive data. */
+    for (; size > 0; size--)
+    {
+        if (DbgConsole_ReadCharacter(&ch) < 0)
+        {
+            break;
+        }
+
+        *buffer++ = (char)ch;
+        actualSize++;
+
+        if ((ch == 0U) || (ch == (uint8_t)'\n') || (ch == (uint8_t)'\r'))
+        {
+            break;
+        }
+    }
+
+    return (actualSize > 0) ? actualSize : -1;
+}
+#endif
+
+#endif /* __ICCARM__ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console.h b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console.h
new file mode 100755
index 0000000..9adf809
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Debug console shall provide input and output functions to scan and print formatted data.
+ * o Support a format specifier for PRINTF follows this prototype "%[flags][width][.precision][length]specifier"
+ *   - [flags] :'-', '+', '#', ' ', '0'
+ *   - [width]:  number (0,1...)
+ *   - [.precision]: number (0,1...)
+ *   - [length]: do not support
+ *   - [specifier]: 'd', 'i', 'f', 'F', 'x', 'X', 'o', 'p', 'u', 'c', 's', 'n'
+ * o Support a format specifier for SCANF follows this prototype " %[*][width][length]specifier"
+ *   - [*]: is supported.
+ *   - [width]: number (0,1...)
+ *   - [length]: 'h', 'hh', 'l','ll','L'. ignore ('j','z','t')
+ *   - [specifier]: 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'a', 'A', 'o', 'c', 's'
+ */
+
+#ifndef _FSL_DEBUGCONSOLE_H_
+#define _FSL_DEBUGCONSOLE_H_
+
+#include "fsl_common.h"
+#include "serial_manager.h"
+
+/*!
+ * @addtogroup debugconsole
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+extern serial_handle_t g_serialHandle; /*!< serial manager handle */
+
+/*! @brief Definition select redirect toolchain printf, scanf to uart or not. */
+#define DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN 0U /*!< Select toolchain printf and scanf. */
+#define DEBUGCONSOLE_REDIRECT_TO_SDK 1U       /*!< Select SDK version printf, scanf. */
+#define DEBUGCONSOLE_DISABLE 2U               /*!< Disable debugconsole function. */
+
+/*! @brief Definition to select sdk or toolchain printf, scanf. The macro only support
+ * to be redefined in project setting.
+ */
+#ifndef SDK_DEBUGCONSOLE
+#define SDK_DEBUGCONSOLE 1U
+#endif
+
+/*! @brief whether provide low level IO implementation to toolchain printf and scanf.
+ * For example, within MCUXpresso, if the macro SDK_DEBUGCONSOLE_UART is defined,
+ * __sys_write and __sys_readc will be used when __REDLIB__ is defined;
+ * _write and _read will be used in other cases.
+ * If the macro SDK_DEBUGCONSOLE_UART is not defined, the semihost will be used.
+ */
+#ifndef SDK_DEBUGCONSOLE_UART
+/* mcux will handle this macro, not define it here */
+#if (!defined(__MCUXPRESSO))
+#define SDK_DEBUGCONSOLE_UART
+#endif
+#endif
+
+#if defined(SDK_DEBUGCONSOLE) && !(SDK_DEBUGCONSOLE)
+#include <stdio.h>
+#endif
+
+/*! @brief Definition to select redirect toolchain printf, scanf to uart or not.
+ *
+ *  if SDK_DEBUGCONSOLE defined to 0,it represents select toolchain printf, scanf.
+ *  if SDK_DEBUGCONSOLE defined to 1,it represents select SDK version printf, scanf.
+ *  if SDK_DEBUGCONSOLE defined to 2,it represents disable debugconsole function.
+ */
+#if SDK_DEBUGCONSOLE == DEBUGCONSOLE_DISABLE /* Disable debug console */
+#define PRINTF(...) \
+    do              \
+    {               \
+    } while (0)
+#define SCANF(...) \
+    do             \
+    {              \
+    } while (0)
+#define PUTCHAR(...) \
+    do               \
+    {                \
+    } while (0)
+#define GETCHAR() -1
+#elif SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK /* Select printf, scanf, putchar, getchar of SDK version. */
+#define PRINTF DbgConsole_Printf
+#define SCANF DbgConsole_Scanf
+#define PUTCHAR DbgConsole_Putchar
+#define GETCHAR DbgConsole_Getchar
+#elif SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN /* Select printf, scanf, putchar, getchar of toolchain. \ \
+                                                              */
+#define PRINTF printf
+#define SCANF scanf
+#define PUTCHAR putchar
+#define GETCHAR getchar
+#endif /* SDK_DEBUGCONSOLE */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*! @name Initialization*/
+/* @{ */
+
+/*!
+ * @brief Initializes the peripheral used for debug messages.
+ *
+ * Call this function to enable debug log messages to be output via the specified peripheral
+ * initialized by the serial manager module.
+ * After this function has returned, stdout and stdin are connected to the selected peripheral.
+ *
+ * @param instance      The instance of the module.
+ * @param baudRate      The desired baud rate in bits per second.
+ * @param device        Low level device type for the debug console, can be one of the following.
+ *                      @arg kSerialPort_Uart,
+ *                      @arg kSerialPort_UsbCdc
+ *                      @arg kSerialPort_UsbCdcVirtual.
+ * @param clkSrcFreq    Frequency of peripheral source clock.
+ *
+ * @return              Indicates whether initialization was successful or not.
+ * @retval kStatus_Success          Execution successfully
+ */
+status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq);
+
+/*!
+ * @brief De-initializes the peripheral used for debug messages.
+ *
+ * Call this function to disable debug log messages to be output via the specified peripheral
+ * initialized by the serial manager module.
+ *
+ * @return Indicates whether de-initialization was successful or not.
+ */
+status_t DbgConsole_Deinit(void);
+
+#if SDK_DEBUGCONSOLE
+/*!
+ * @brief Writes formatted output to the standard output stream.
+ *
+ * Call this function to write a formatted output to the standard output stream.
+ *
+ * @param   formatString Format control string.
+ * @return  Returns the number of characters printed or a negative value if an error occurs.
+ */
+int DbgConsole_Printf(const char *formatString, ...);
+
+/*!
+ * @brief Writes a character to stdout.
+ *
+ * Call this function to write a character to stdout.
+ *
+ * @param   ch Character to be written.
+ * @return  Returns the character written.
+ */
+int DbgConsole_Putchar(int ch);
+
+/*!
+ * @brief Reads formatted data from the standard input stream.
+ *
+ * Call this function to read formatted data from the standard input stream.
+ *
+ * @note Due the limitation in the BM OSA environment (CPU is blocked in the function,
+ * other tasks will not be scheduled), the function cannot be used when the
+ * DEBUG_CONSOLE_TRANSFER_NON_BLOCKING is set in the BM OSA environment.
+ * And an error is returned when the function called in this case. The suggestion
+ * is that polling the non-blocking function DbgConsole_TryGetchar to get the input char.
+ *
+ * @param   formatString Format control string.
+ * @return  Returns the number of fields successfully converted and assigned.
+ */
+int DbgConsole_Scanf(char *formatString, ...);
+
+/*!
+ * @brief Reads a character from standard input.
+ *
+ * Call this function to read a character from standard input.
+ *
+ * @note Due the limitation in the BM OSA environment (CPU is blocked in the function,
+ * other tasks will not be scheduled), the function cannot be used when the
+ * DEBUG_CONSOLE_TRANSFER_NON_BLOCKING is set in the BM OSA environment.
+ * And an error is returned when the function called in this case. The suggestion
+ * is that polling the non-blocking function DbgConsole_TryGetchar to get the input char.
+ *
+ * @return Returns the character read.
+ */
+int DbgConsole_Getchar(void);
+
+/*!
+ * @brief Debug console flush.
+ *
+ * Call this function to wait the tx buffer empty.
+ * If interrupt transfer is using, make sure the global IRQ is enable before call this function
+ * This function should be called when
+ * 1, before enter power down mode
+ * 2, log is required to print to terminal immediately
+ * @return Indicates whether wait idle was successful or not.
+ */
+status_t DbgConsole_Flush(void);
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*!
+ * @brief Debug console try to get char
+ * This function provides a API which will not block current task, if character is
+ * available return it, otherwise return fail.
+ * @param ch the address of char to receive
+ * @return Indicates get char was successful or not.
+ */
+status_t DbgConsole_TryGetchar(char *ch);
+#endif
+
+#endif /* SDK_DEBUGCONSOLE */
+
+/*! @} */
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_DEBUGCONSOLE_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console_conf.h b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console_conf.h
new file mode 100755
index 0000000..366c6cd
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/debug_console/fsl_debug_console_conf.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2017 - 2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_DEBUG_CONSOLE_CONF_H_
+#define _FSL_DEBUG_CONSOLE_CONF_H_
+
+/****************Debug console configuration********************/
+
+/*! @brief If Non-blocking mode is needed, please define it at project setting,
+ * otherwise blocking mode is the default transfer mode.
+ * Warning: If you want to use non-blocking transfer,please make sure the corresponding
+ * IO interrupt is enable, otherwise there is no output.
+ * And non-blocking is combine with buffer, no matter bare-metal or rtos.
+ * Below shows how to configure in your project if you want to use non-blocking mode.
+ * For IAR, right click project and select "Options", define it in "C/C++ Compiler->Preprocessor->Defined symbols".
+ * For KEIL, click "Options for Target…", define it in "C/C++->Preprocessor Symbols->Define".
+ * For ARMGCC, open CmakeLists.txt and add the following lines,
+ * "SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG_CONSOLE_TRANSFER_NON_BLOCKING")" for debug target.
+ * "SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DDEBUG_CONSOLE_TRANSFER_NON_BLOCKING")" for release target.
+ * For MCUxpresso, right click project and select "Properties", define it in "C/C++ Build->Settings->MCU C
+ * Complier->Preprocessor".
+ *
+ */
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*! @brief define the transmit buffer length which is used to store the multi task log, buffer is enabled automatically
+ * when
+ * non-blocking transfer is using,
+ * This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement.
+ * If it is configured too small, log maybe missed , because the log will not be
+ * buffered if the buffer is full, and the print will return immediately with -1.
+ * And this value should be multiple of 4 to meet memory alignment.
+ *
+ */
+#ifndef DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN
+#define DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN (512U)
+#endif /* DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN */
+
+/*! @brief define the receive buffer length which is used to store the user input, buffer is enabled automatically when
+ * non-blocking transfer is using,
+ * This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement.
+ * If it is configured too small, log maybe missed, because buffer will be overwrited if buffer is too small.
+ * And this value should be multiple of 4 to meet memory alignment.
+ *
+ */
+#ifndef DEBUG_CONSOLE_RECEIVE_BUFFER_LEN
+#define DEBUG_CONSOLE_RECEIVE_BUFFER_LEN (1024U)
+#endif /* DEBUG_CONSOLE_RECEIVE_BUFFER_LEN */
+
+/*!@ brief Whether enable the reliable TX function
+ * If the macro is zero, the reliable TX function of the debug console is disabled.
+ * When the macro is zero, the string of PRINTF will be thrown away after the transmit buffer is full.
+ */
+#ifndef DEBUG_CONSOLE_TX_RELIABLE_ENABLE
+#define DEBUG_CONSOLE_TX_RELIABLE_ENABLE (1U)
+#endif /* DEBUG_CONSOLE_RX_ENABLE */
+
+#else
+#define DEBUG_CONSOLE_TRANSFER_BLOCKING
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/*!@ brief Whether enable the RX function
+ * If the macro is zero, the receive function of the debug console is disabled.
+ */
+#ifndef DEBUG_CONSOLE_RX_ENABLE
+#define DEBUG_CONSOLE_RX_ENABLE (1U)
+#endif /* DEBUG_CONSOLE_RX_ENABLE */
+
+/*!@ brief define the MAX log length debug console support , that is when you call printf("log", x);, the log
+ * length can not bigger than this value.
+ * This macro decide the local log buffer length, the buffer locate at stack, the stack maybe overflow if
+ * the buffer is too big and current task stack size not big enough.
+ */
+#ifndef DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN
+#define DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN (128U)
+#endif /* DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN */
+
+/*!@ brief define the buffer support buffer scanf log length, that is when you call scanf("log", &x);, the log
+ * length can not bigger than this value.
+ * As same as the DEBUG_CONSOLE_BUFFER_PRINTF_MAX_LOG_LEN.
+ */
+#ifndef DEBUG_CONSOLE_SCANF_MAX_LOG_LEN
+#define DEBUG_CONSOLE_SCANF_MAX_LOG_LEN (20U)
+#endif /* DEBUG_CONSOLE_SCANF_MAX_LOG_LEN */
+
+/*! @brief Debug console synchronization
+ * User should not change these macro for synchronization mode, but add the
+ * corresponding synchronization mechanism per different software environment.
+ * Such as, if another RTOS is used,
+ * add:
+ *  #define DEBUG_CONSOLE_SYNCHRONIZATION_XXXX 3
+ * in this configuration file and implement the synchronization in fsl.log.c.
+ */
+/*! @brief synchronization for baremetal software */
+#define DEBUG_CONSOLE_SYNCHRONIZATION_BM 0
+/*! @brief synchronization for freertos software */
+#define DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS 1
+
+/*! @brief RTOS synchronization mechanism disable
+ * If not defined, default is enable, to avoid multitask log print mess.
+ * If other RTOS is used, you can implement the RTOS's specific synchronization mechanism in fsl.log.c
+ * If synchronization is disabled, log maybe messed on terminal.
+ */
+#ifndef DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+#ifdef FSL_RTOS_FREE_RTOS
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS
+#else
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM
+#endif /* FSL_RTOS_FREE_RTOS */
+#else
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+#endif /* DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION */
+
+/*! @brief echo function support
+ * If you want to use the echo function,please define DEBUG_CONSOLE_ENABLE_ECHO
+ * at your project setting.
+ */
+#ifndef DEBUG_CONSOLE_ENABLE_ECHO
+#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 0
+#else
+#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 1
+#endif /* DEBUG_CONSOLE_ENABLE_ECHO */
+
+/*********************************************************************/
+
+/***************Debug console other configuration*********************/
+/*! @brief Definition to printf the float number. */
+#ifndef PRINTF_FLOAT_ENABLE
+#define PRINTF_FLOAT_ENABLE 0U
+#endif /* PRINTF_FLOAT_ENABLE */
+
+/*! @brief Definition to scanf the float number. */
+#ifndef SCANF_FLOAT_ENABLE
+#define SCANF_FLOAT_ENABLE 0U
+#endif /* SCANF_FLOAT_ENABLE */
+
+/*! @brief Definition to support advanced format specifier for printf. */
+#ifndef PRINTF_ADVANCED_ENABLE
+#define PRINTF_ADVANCED_ENABLE 0U
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+/*! @brief Definition to support advanced format specifier for scanf. */
+#ifndef SCANF_ADVANCED_ENABLE
+#define SCANF_ADVANCED_ENABLE 0U
+#endif /* SCANF_ADVANCED_ENABLE */
+
+/*! @brief Definition to select virtual com(USB CDC) as the debug console. */
+#ifndef BOARD_USE_VIRTUALCOM
+#define BOARD_USE_VIRTUALCOM 0U
+#endif
+/*******************************************************************/
+
+#endif /* _FSL_DEBUG_CONSOLE_CONF_H_ */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/utilities/fsl_assert.c b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/fsl_assert.c
new file mode 100755
index 0000000..9052faf
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/fsl_assert.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_debug_console.h"
+
+#ifndef NDEBUG
+#if (defined(__CC_ARM)) || (defined(__ARMCC_VERSION)) || (defined(__ICCARM__))
+void __aeabi_assert(const char *failedExpr, const char *file, int line)
+{
+    PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line);
+    for (;;)
+    {
+        __BKPT(0);
+    }
+}
+#elif (defined(__GNUC__))
+void __assert_func(const char *file, int line, const char *func, const char *failedExpr)
+{
+    PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, func);
+    for (;;)
+    {
+        __BKPT(0);
+    }
+}
+#endif /* (defined(__CC_ARM) || (defined(__ICCARM__)) || (defined(__ARMCC_VERSION)) */
+#endif /* NDEBUG */
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str/fsl_str.c b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str/fsl_str.c
new file mode 100755
index 0000000..c4d1a0c
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str/fsl_str.c
@@ -0,0 +1,1324 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <math.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "fsl_str.h"
+#include "fsl_debug_console_conf.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief The overflow value.*/
+#ifndef HUGE_VAL
+#define HUGE_VAL (99.e99)
+#endif /* HUGE_VAL */
+
+#if PRINTF_ADVANCED_ENABLE
+/*! @brief Specification modifier flags for printf. */
+enum _debugconsole_printf_flag
+{
+    kPRINTF_Minus             = 0x01U,  /*!< Minus FLag. */
+    kPRINTF_Plus              = 0x02U,  /*!< Plus Flag. */
+    kPRINTF_Space             = 0x04U,  /*!< Space Flag. */
+    kPRINTF_Zero              = 0x08U,  /*!< Zero Flag. */
+    kPRINTF_Pound             = 0x10U,  /*!< Pound Flag. */
+    kPRINTF_LengthChar        = 0x20U,  /*!< Length: Char Flag. */
+    kPRINTF_LengthShortInt    = 0x40U,  /*!< Length: Short Int Flag. */
+    kPRINTF_LengthLongInt     = 0x80U,  /*!< Length: Long Int Flag. */
+    kPRINTF_LengthLongLongInt = 0x100U, /*!< Length: Long Long Int Flag. */
+};
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+/*! @brief Specification modifier flags for scanf. */
+enum _debugconsole_scanf_flag
+{
+    kSCANF_Suppress   = 0x2U,    /*!< Suppress Flag. */
+    kSCANF_DestMask   = 0x7cU,   /*!< Destination Mask. */
+    kSCANF_DestChar   = 0x4U,    /*!< Destination Char Flag. */
+    kSCANF_DestString = 0x8U,    /*!< Destination String FLag. */
+    kSCANF_DestSet    = 0x10U,   /*!< Destination Set Flag. */
+    kSCANF_DestInt    = 0x20U,   /*!< Destination Int Flag. */
+    kSCANF_DestFloat  = 0x30U,   /*!< Destination Float Flag. */
+    kSCANF_LengthMask = 0x1f00U, /*!< Length Mask Flag. */
+#if SCANF_ADVANCED_ENABLE
+    kSCANF_LengthChar        = 0x100U, /*!< Length Char Flag. */
+    kSCANF_LengthShortInt    = 0x200U, /*!< Length ShortInt Flag. */
+    kSCANF_LengthLongInt     = 0x400U, /*!< Length LongInt Flag. */
+    kSCANF_LengthLongLongInt = 0x800U, /*!< Length LongLongInt Flag. */
+#endif                                 /* SCANF_ADVANCED_ENABLE */
+#if SCANF_FLOAT_ENABLE
+    kSCANF_LengthLongLongDouble = 0x1000U, /*!< Length LongLongDuoble Flag. */
+#endif                                     /*PRINTF_FLOAT_ENABLE */
+    kSCANF_TypeSinged = 0x2000U,           /*!< TypeSinged Flag. */
+};
+
+/*! @brief Keil: suppress ellipsis warning in va_arg usage below. */
+#if defined(__CC_ARM)
+#pragma diag_suppress 1256
+#endif /* __CC_ARM */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Scanline function which ignores white spaces.
+ *
+ * @param[in]   s The address of the string pointer to update.
+ * @return      String without white spaces.
+ */
+static uint32_t ScanIgnoreWhiteSpace(const char **s);
+
+/*!
+ * @brief Converts a radix number to a string and return its length.
+ *
+ * @param[in] numstr    Converted string of the number.
+ * @param[in] nump      Pointer to the number.
+ * @param[in] neg       Polarity of the number.
+ * @param[in] radix     The radix to be converted to.
+ * @param[in] use_caps  Used to identify %x/X output format.
+
+ * @return Length of the converted string.
+ */
+static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps);
+
+#if PRINTF_FLOAT_ENABLE
+/*!
+ * @brief Converts a floating radix number to a string and return its length.
+ *
+ * @param[in] numstr            Converted string of the number.
+ * @param[in] nump              Pointer to the number.
+ * @param[in] radix             The radix to be converted to.
+ * @param[in] precision_width   Specify the precision width.
+
+ * @return Length of the converted string.
+ */
+static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width);
+#endif /* PRINTF_FLOAT_ENABLE */
+
+/*!
+ *
+ */
+double modf(double input_dbl, double *intpart_ptr);
+
+/*************Code for process formatted data*******************************/
+
+static uint32_t ScanIgnoreWhiteSpace(const char **s)
+{
+    uint8_t count = 0;
+    uint8_t c;
+
+    c = **s;
+    while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\v') || (c == '\f'))
+    {
+        count++;
+        (*s)++;
+        c = **s;
+    }
+    return count;
+}
+
+static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps)
+{
+#if PRINTF_ADVANCED_ENABLE
+    int64_t a;
+    int64_t b;
+    int64_t c;
+
+    uint64_t ua;
+    uint64_t ub;
+    uint64_t uc;
+#else
+    int32_t a;
+    int32_t b;
+    int32_t c;
+
+    uint32_t ua;
+    uint32_t ub;
+    uint32_t uc;
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+    int32_t nlen;
+    char *nstrp;
+
+    nlen     = 0;
+    nstrp    = numstr;
+    *nstrp++ = '\0';
+
+    if (neg)
+    {
+#if PRINTF_ADVANCED_ENABLE
+        a = *(int64_t *)nump;
+#else
+        a = *(int32_t *)nump;
+#endif /* PRINTF_ADVANCED_ENABLE */
+        if (a == 0)
+        {
+            *nstrp = '0';
+            ++nlen;
+            return nlen;
+        }
+        while (a != 0)
+        {
+#if PRINTF_ADVANCED_ENABLE
+            b = (int64_t)a / (int64_t)radix;
+            c = (int64_t)a - ((int64_t)b * (int64_t)radix);
+            if (c < 0)
+            {
+                uc = (uint64_t)c;
+                c  = (int64_t)(~uc) + 1 + '0';
+            }
+#else
+            b = a / radix;
+            c = a - (b * radix);
+            if (c < 0)
+            {
+                uc = (uint32_t)c;
+                c  = (uint32_t)(~uc) + 1 + '0';
+            }
+#endif /* PRINTF_ADVANCED_ENABLE */
+            else
+            {
+                c = c + '0';
+            }
+            a        = b;
+            *nstrp++ = (char)c;
+            ++nlen;
+        }
+    }
+    else
+    {
+#if PRINTF_ADVANCED_ENABLE
+        ua = *(uint64_t *)nump;
+#else
+        ua = *(uint32_t *)nump;
+#endif /* PRINTF_ADVANCED_ENABLE */
+        if (ua == 0)
+        {
+            *nstrp = '0';
+            ++nlen;
+            return nlen;
+        }
+        while (ua != 0)
+        {
+#if PRINTF_ADVANCED_ENABLE
+            ub = (uint64_t)ua / (uint64_t)radix;
+            uc = (uint64_t)ua - ((uint64_t)ub * (uint64_t)radix);
+#else
+            ub = ua / (uint32_t)radix;
+            uc = ua - (ub * (uint32_t)radix);
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+            if (uc < 10)
+            {
+                uc = uc + '0';
+            }
+            else
+            {
+                uc = uc - 10 + (use_caps ? 'A' : 'a');
+            }
+            ua       = ub;
+            *nstrp++ = (char)uc;
+            ++nlen;
+        }
+    }
+    return nlen;
+}
+
+#if PRINTF_FLOAT_ENABLE
+static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width)
+{
+    int32_t a;
+    int32_t b;
+    int32_t c;
+    int32_t i;
+    uint32_t uc;
+    double fa;
+    double dc;
+    double fb;
+    double r;
+    double fractpart;
+    double intpart;
+
+    int32_t nlen;
+    char *nstrp;
+    nlen     = 0;
+    nstrp    = numstr;
+    *nstrp++ = '\0';
+    r        = *(double *)nump;
+    if (!r)
+    {
+        *nstrp = '0';
+        ++nlen;
+        return nlen;
+    }
+    fractpart = modf((double)r, (double *)&intpart);
+    /* Process fractional part. */
+    for (i = 0; i < precision_width; i++)
+    {
+        fractpart *= radix;
+    }
+    if (r >= 0)
+    {
+        fa = fractpart + (double)0.5;
+        if (fa >= pow(10, precision_width))
+        {
+            intpart++;
+        }
+    }
+    else
+    {
+        fa = fractpart - (double)0.5;
+        if (fa <= -pow(10, precision_width))
+        {
+            intpart--;
+        }
+    }
+    for (i = 0; i < precision_width; i++)
+    {
+        fb = fa / (int32_t)radix;
+        dc = (fa - (int64_t)fb * (int32_t)radix);
+        c  = (int32_t)dc;
+        if (c < 0)
+        {
+            uc = (uint32_t)c;
+            c  = (int32_t)(~uc) + 1 + '0';
+        }
+        else
+        {
+            c = c + '0';
+        }
+        fa       = fb;
+        *nstrp++ = (char)c;
+        ++nlen;
+    }
+    *nstrp++ = (char)'.';
+    ++nlen;
+    a = (int32_t)intpart;
+    if (a == 0)
+    {
+        *nstrp++ = '0';
+        ++nlen;
+    }
+    else
+    {
+        while (a != 0)
+        {
+            b = (int32_t)a / (int32_t)radix;
+            c = (int32_t)a - ((int32_t)b * (int32_t)radix);
+            if (c < 0)
+            {
+                uc = (uint32_t)c;
+                c  = (int32_t)(~uc) + 1 + '0';
+            }
+            else
+            {
+                c = c + '0';
+            }
+            a        = b;
+            *nstrp++ = (char)c;
+            ++nlen;
+        }
+    }
+    return nlen;
+}
+#endif /* PRINTF_FLOAT_ENABLE */
+
+/*!
+ * brief This function outputs its parameters according to a formatted string.
+ *
+ * note I/O is performed by calling given function pointer using following
+ * (*func_ptr)(c);
+ *
+ * param[in] fmt_ptr   Format string for printf.
+ * param[in] args_ptr  Arguments to printf.
+ * param[in] buf  pointer to the buffer
+ * param cb print callback function pointer
+ *
+ * return Number of characters to be print
+ */
+int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb)
+{
+    /* va_list ap; */
+    char *p;
+    int32_t c;
+
+    char vstr[33];
+    char *vstrp  = NULL;
+    int32_t vlen = 0;
+
+    int32_t done;
+    int32_t count = 0;
+
+    uint32_t field_width;
+    uint32_t precision_width;
+    char *sval;
+    int32_t cval;
+    bool use_caps;
+    uint8_t radix = 0;
+
+#if PRINTF_ADVANCED_ENABLE
+    uint32_t flags_used;
+    int32_t schar, dschar;
+    int64_t ival;
+    uint64_t uval = 0;
+    bool valid_precision_width;
+#else
+    int32_t ival;
+    uint32_t uval = 0;
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+#if PRINTF_FLOAT_ENABLE
+    double fval;
+#endif /* PRINTF_FLOAT_ENABLE */
+
+    /* Start parsing apart the format string and display appropriate formats and data. */
+    for (p = (char *)fmt; (c = *p) != 0; p++)
+    {
+        /*
+         * All formats begin with a '%' marker.  Special chars like
+         * '\n' or '\t' are normally converted to the appropriate
+         * character by the __compiler__.  Thus, no need for this
+         * routine to account for the '\' character.
+         */
+        if (c != '%')
+        {
+            cb(buf, &count, c, 1);
+            /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */
+            continue;
+        }
+
+        use_caps = true;
+
+#if PRINTF_ADVANCED_ENABLE
+        /* First check for specification modifier flags. */
+        flags_used = 0;
+        done       = false;
+        while (!done)
+        {
+            switch (*++p)
+            {
+                case '-':
+                    flags_used |= kPRINTF_Minus;
+                    break;
+                case '+':
+                    flags_used |= kPRINTF_Plus;
+                    break;
+                case ' ':
+                    flags_used |= kPRINTF_Space;
+                    break;
+                case '0':
+                    flags_used |= kPRINTF_Zero;
+                    break;
+                case '#':
+                    flags_used |= kPRINTF_Pound;
+                    break;
+                default:
+                    /* We've gone one char too far. */
+                    --p;
+                    done = true;
+                    break;
+            }
+        }
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+        /* Next check for minimum field width. */
+        field_width = 0;
+        done        = false;
+        while (!done)
+        {
+            c = *++p;
+            if ((c >= '0') && (c <= '9'))
+            {
+                field_width = (field_width * 10) + (c - '0');
+            }
+#if PRINTF_ADVANCED_ENABLE
+            else if (c == '*')
+            {
+                field_width = (uint32_t)va_arg(ap, uint32_t);
+            }
+#endif /* PRINTF_ADVANCED_ENABLE */
+            else
+            {
+                /* We've gone one char too far. */
+                --p;
+                done = true;
+            }
+        }
+        /* Next check for the width and precision field separator. */
+        precision_width = 6;
+#if PRINTF_ADVANCED_ENABLE
+        valid_precision_width = false;
+#endif /* PRINTF_ADVANCED_ENABLE */
+        if (*++p == '.')
+        {
+            /* Must get precision field width, if present. */
+            precision_width = 0;
+            done            = false;
+            while (!done)
+            {
+                c = *++p;
+                if ((c >= '0') && (c <= '9'))
+                {
+                    precision_width = (precision_width * 10) + (c - '0');
+#if PRINTF_ADVANCED_ENABLE
+                    valid_precision_width = true;
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+#if PRINTF_ADVANCED_ENABLE
+                else if (c == '*')
+                {
+                    precision_width       = (uint32_t)va_arg(ap, uint32_t);
+                    valid_precision_width = true;
+                }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                else
+                {
+                    /* We've gone one char too far. */
+                    --p;
+                    done = true;
+                }
+            }
+        }
+        else
+        {
+            /* We've gone one char too far. */
+            --p;
+        }
+#if PRINTF_ADVANCED_ENABLE
+        /*
+         * Check for the length modifier.
+         */
+        switch (/* c = */ *++p)
+        {
+            case 'h':
+                if (*++p != 'h')
+                {
+                    flags_used |= kPRINTF_LengthShortInt;
+                    --p;
+                }
+                else
+                {
+                    flags_used |= kPRINTF_LengthChar;
+                }
+                break;
+            case 'l':
+                if (*++p != 'l')
+                {
+                    flags_used |= kPRINTF_LengthLongInt;
+                    --p;
+                }
+                else
+                {
+                    flags_used |= kPRINTF_LengthLongLongInt;
+                }
+                break;
+            default:
+                /* we've gone one char too far */
+                --p;
+                break;
+        }
+#endif /* PRINTF_ADVANCED_ENABLE */
+        /* Now we're ready to examine the format. */
+        c = *++p;
+        {
+            if ((c == 'd') || (c == 'i') || (c == 'f') || (c == 'F') || (c == 'x') || (c == 'X') || (c == 'o') ||
+                (c == 'b') || (c == 'p') || (c == 'u'))
+            {
+                if ((c == 'd') || (c == 'i'))
+                {
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_LengthLongLongInt)
+                    {
+                        ival = (int64_t)va_arg(ap, int64_t);
+                    }
+                    else
+#endif /* PRINTF_ADVANCED_ENABLE */
+                    {
+                        ival = (int32_t)va_arg(ap, int32_t);
+                    }
+                    vlen  = ConvertRadixNumToString(vstr, &ival, true, 10, use_caps);
+                    vstrp = &vstr[vlen];
+#if PRINTF_ADVANCED_ENABLE
+                    if (ival < 0)
+                    {
+                        schar = '-';
+                        ++vlen;
+                    }
+                    else
+                    {
+                        if (flags_used & kPRINTF_Plus)
+                        {
+                            schar = '+';
+                            ++vlen;
+                        }
+                        else
+                        {
+                            if (flags_used & kPRINTF_Space)
+                            {
+                                schar = ' ';
+                                ++vlen;
+                            }
+                            else
+                            {
+                                schar = 0;
+                            }
+                        }
+                    }
+                    dschar = false;
+                    /* Do the ZERO pad. */
+                    if (flags_used & kPRINTF_Zero)
+                    {
+                        if (schar)
+                        {
+                            cb(buf, &count, schar, 1);
+                        }
+                        dschar = true;
+
+                        cb(buf, &count, '0', field_width - vlen);
+                        vlen = field_width;
+                    }
+                    else
+                    {
+                        if (!(flags_used & kPRINTF_Minus))
+                        {
+                            cb(buf, &count, ' ', field_width - vlen);
+                            if (schar)
+                            {
+                                cb(buf, &count, schar, 1);
+                            }
+                            dschar = true;
+                        }
+                    }
+                    /* The string was built in reverse order, now display in correct order. */
+                    if ((!dschar) && schar)
+                    {
+                        cb(buf, &count, schar, 1);
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+
+#if PRINTF_FLOAT_ENABLE
+                if ((c == 'f') || (c == 'F'))
+                {
+                    fval  = (double)va_arg(ap, double);
+                    vlen  = ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width);
+                    vstrp = &vstr[vlen];
+
+#if PRINTF_ADVANCED_ENABLE
+                    if (fval < 0)
+                    {
+                        schar = '-';
+                        ++vlen;
+                    }
+                    else
+                    {
+                        if (flags_used & kPRINTF_Plus)
+                        {
+                            schar = '+';
+                            ++vlen;
+                        }
+                        else
+                        {
+                            if (flags_used & kPRINTF_Space)
+                            {
+                                schar = ' ';
+                                ++vlen;
+                            }
+                            else
+                            {
+                                schar = 0;
+                            }
+                        }
+                    }
+                    dschar = false;
+                    if (flags_used & kPRINTF_Zero)
+                    {
+                        if (schar)
+                        {
+                            cb(buf, &count, schar, 1);
+                        }
+                        dschar = true;
+                        cb(buf, &count, '0', field_width - vlen);
+                        vlen = field_width;
+                    }
+                    else
+                    {
+                        if (!(flags_used & kPRINTF_Minus))
+                        {
+                            cb(buf, &count, ' ', field_width - vlen);
+                            if (schar)
+                            {
+                                cb(buf, &count, schar, 1);
+                            }
+                            dschar = true;
+                        }
+                    }
+                    if ((!dschar) && schar)
+                    {
+                        cb(buf, &count, schar, 1);
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+#endif /* PRINTF_FLOAT_ENABLE */
+                if ((c == 'X') || (c == 'x'))
+                {
+                    if (c == 'x')
+                    {
+                        use_caps = false;
+                    }
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_LengthLongLongInt)
+                    {
+                        uval = (uint64_t)va_arg(ap, uint64_t);
+                    }
+                    else
+#endif /* PRINTF_ADVANCED_ENABLE */
+                    {
+                        uval = (uint32_t)va_arg(ap, uint32_t);
+                    }
+                    vlen  = ConvertRadixNumToString(vstr, &uval, false, 16, use_caps);
+                    vstrp = &vstr[vlen];
+
+#if PRINTF_ADVANCED_ENABLE
+                    dschar = false;
+                    if (flags_used & kPRINTF_Zero)
+                    {
+                        if (flags_used & kPRINTF_Pound)
+                        {
+                            cb(buf, &count, '0', 1);
+                            cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+                            dschar = true;
+                        }
+                        cb(buf, &count, '0', field_width - vlen);
+                        vlen = field_width;
+                    }
+                    else
+                    {
+                        if (!(flags_used & kPRINTF_Minus))
+                        {
+                            if (flags_used & kPRINTF_Pound)
+                            {
+                                vlen += 2;
+                            }
+                            cb(buf, &count, ' ', field_width - vlen);
+                            if (flags_used & kPRINTF_Pound)
+                            {
+                                cb(buf, &count, '0', 1);
+                                cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+                                dschar = true;
+                            }
+                        }
+                    }
+
+                    if ((flags_used & kPRINTF_Pound) && (!dschar))
+                    {
+                        cb(buf, &count, '0', 1);
+                        cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+                        vlen += 2;
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+                if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u'))
+                {
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_LengthLongLongInt)
+                    {
+                        uval = (uint64_t)va_arg(ap, uint64_t);
+                    }
+                    else
+#endif /* PRINTF_ADVANCED_ENABLE */
+                    {
+                        uval = (uint32_t)va_arg(ap, uint32_t);
+                    }
+
+                    if (c == 'o')
+                    {
+                        radix = 8;
+                    }
+                    else if (c == 'b')
+                    {
+                        radix = 2;
+                    }
+                    else if (c == 'p')
+                    {
+                        radix = 16;
+                    }
+                    else
+                    {
+                        radix = 10;
+                    }
+
+                    vlen  = ConvertRadixNumToString(vstr, &uval, false, radix, use_caps);
+                    vstrp = &vstr[vlen];
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_Zero)
+                    {
+                        cb(buf, &count, '0', field_width - vlen);
+                        vlen = field_width;
+                    }
+                    else
+                    {
+                        if (!(flags_used & kPRINTF_Minus))
+                        {
+                            cb(buf, &count, ' ', field_width - vlen);
+                        }
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+#if !PRINTF_ADVANCED_ENABLE
+                cb(buf, &count, ' ', field_width - vlen);
+#endif /* !PRINTF_ADVANCED_ENABLE */
+                if (vstrp != NULL)
+                {
+                    while (*vstrp)
+                    {
+                        cb(buf, &count, *vstrp--, 1);
+                    }
+                }
+#if PRINTF_ADVANCED_ENABLE
+                if (flags_used & kPRINTF_Minus)
+                {
+                    cb(buf, &count, ' ', field_width - vlen);
+                }
+#endif /* PRINTF_ADVANCED_ENABLE */
+            }
+            else if (c == 'c')
+            {
+                cval = (char)va_arg(ap, uint32_t);
+                cb(buf, &count, cval, 1);
+            }
+            else if (c == 's')
+            {
+                sval = (char *)va_arg(ap, char *);
+                if (sval)
+                {
+#if PRINTF_ADVANCED_ENABLE
+                    if (valid_precision_width)
+                    {
+                        vlen = precision_width;
+                    }
+                    else
+                    {
+                        vlen = strlen(sval);
+                    }
+#else
+                    vlen = strlen(sval);
+#endif /* PRINTF_ADVANCED_ENABLE */
+#if PRINTF_ADVANCED_ENABLE
+                    if (!(flags_used & kPRINTF_Minus))
+#endif /* PRINTF_ADVANCED_ENABLE */
+                    {
+                        cb(buf, &count, ' ', field_width - vlen);
+                    }
+
+#if PRINTF_ADVANCED_ENABLE
+                    if (valid_precision_width)
+                    {
+                        while ((*sval) && (vlen > 0))
+                        {
+                            cb(buf, &count, *sval++, 1);
+                            vlen--;
+                        }
+                        /* In case that vlen sval is shorter than vlen */
+                        vlen = precision_width - vlen;
+                    }
+                    else
+                    {
+#endif /* PRINTF_ADVANCED_ENABLE */
+                        while (*sval)
+                        {
+                            cb(buf, &count, *sval++, 1);
+                        }
+#if PRINTF_ADVANCED_ENABLE
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_Minus)
+                    {
+                        cb(buf, &count, ' ', field_width - vlen);
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+            }
+            else
+            {
+                cb(buf, &count, c, 1);
+            }
+        }
+    }
+
+    return count;
+}
+
+/*!
+ * brief Converts an input line of ASCII characters based upon a provided
+ * string format.
+ *
+ * param[in] line_ptr The input line of ASCII data.
+ * param[in] format   Format first points to the format string.
+ * param[in] args_ptr The list of parameters.
+ *
+ * return Number of input items converted and assigned.
+ * retval IO_EOF When line_ptr is empty string "".
+ */
+int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr)
+{
+    uint8_t base;
+    int8_t neg;
+    /* Identifier for the format string. */
+    char *c = format;
+    char temp;
+    char *buf;
+    /* Flag telling the conversion specification. */
+    uint32_t flag = 0;
+    /* Filed width for the matching input streams. */
+    uint32_t field_width;
+    /* How many arguments are assigned except the suppress. */
+    uint32_t nassigned = 0;
+    /* How many characters are read from the input streams. */
+    uint32_t n_decode = 0;
+
+    int32_t val;
+
+    const char *s;
+    /* Identifier for the input string. */
+    const char *p = line_ptr;
+
+#if SCANF_FLOAT_ENABLE
+    double fnum = 0.0;
+#endif /* SCANF_FLOAT_ENABLE */
+    /* Return EOF error before any conversion. */
+    if (*p == '\0')
+    {
+        return -1;
+    }
+
+    /* Decode directives. */
+    while ((*c) && (*p))
+    {
+        /* Ignore all white-spaces in the format strings. */
+        if (ScanIgnoreWhiteSpace((const char **)&c))
+        {
+            n_decode += ScanIgnoreWhiteSpace(&p);
+        }
+        else if ((*c != '%') || ((*c == '%') && (*(c + 1) == '%')))
+        {
+            /* Ordinary characters. */
+            c++;
+            if (*p == *c)
+            {
+                n_decode++;
+                p++;
+                c++;
+            }
+            else
+            {
+                /* Match failure. Misalignment with C99, the unmatched characters need to be pushed back to stream.
+                 * However, it is deserted now. */
+                break;
+            }
+        }
+        else
+        {
+            /* convernsion specification */
+            c++;
+            /* Reset. */
+            flag        = 0;
+            field_width = 0;
+            base        = 0;
+
+            /* Loop to get full conversion specification. */
+            while ((*c) && (!(flag & kSCANF_DestMask)))
+            {
+                switch (*c)
+                {
+#if SCANF_ADVANCED_ENABLE
+                    case '*':
+                        if (flag & kSCANF_Suppress)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+                        flag |= kSCANF_Suppress;
+                        c++;
+                        break;
+                    case 'h':
+                        if (flag & kSCANF_LengthMask)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+
+                        if (c[1] == 'h')
+                        {
+                            flag |= kSCANF_LengthChar;
+                            c++;
+                        }
+                        else
+                        {
+                            flag |= kSCANF_LengthShortInt;
+                        }
+                        c++;
+                        break;
+                    case 'l':
+                        if (flag & kSCANF_LengthMask)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+
+                        if (c[1] == 'l')
+                        {
+                            flag |= kSCANF_LengthLongLongInt;
+                            c++;
+                        }
+                        else
+                        {
+                            flag |= kSCANF_LengthLongInt;
+                        }
+                        c++;
+                        break;
+#endif /* SCANF_ADVANCED_ENABLE */
+#if SCANF_FLOAT_ENABLE
+                    case 'L':
+                        if (flag & kSCANF_LengthMask)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+                        flag |= kSCANF_LengthLongLongDouble;
+                        c++;
+                        break;
+#endif /* SCANF_FLOAT_ENABLE */
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                        if (field_width)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+                        do
+                        {
+                            field_width = field_width * 10 + *c - '0';
+                            c++;
+                        } while ((*c >= '0') && (*c <= '9'));
+                        break;
+                    case 'd':
+                        base = 10;
+                        flag |= kSCANF_TypeSinged;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+                    case 'u':
+                        base = 10;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+                    case 'o':
+                        base = 8;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+                    case 'x':
+                    case 'X':
+                        base = 16;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+                    case 'i':
+                        base = 0;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+#if SCANF_FLOAT_ENABLE
+                    case 'a':
+                    case 'A':
+                    case 'e':
+                    case 'E':
+                    case 'f':
+                    case 'F':
+                    case 'g':
+                    case 'G':
+                        flag |= kSCANF_DestFloat;
+                        c++;
+                        break;
+#endif /* SCANF_FLOAT_ENABLE */
+                    case 'c':
+                        flag |= kSCANF_DestChar;
+                        if (!field_width)
+                        {
+                            field_width = 1;
+                        }
+                        c++;
+                        break;
+                    case 's':
+                        flag |= kSCANF_DestString;
+                        c++;
+                        break;
+                    default:
+                        return nassigned;
+                }
+            }
+
+            if (!(flag & kSCANF_DestMask))
+            {
+                /* Format strings are exhausted. */
+                return nassigned;
+            }
+
+            if (!field_width)
+            {
+                /* Large than length of a line. */
+                field_width = 99;
+            }
+
+            /* Matching strings in input streams and assign to argument. */
+            switch (flag & kSCANF_DestMask)
+            {
+                case kSCANF_DestChar:
+                    s   = (const char *)p;
+                    buf = va_arg(args_ptr, char *);
+                    while ((field_width--) && (*p))
+                    {
+                        if (!(flag & kSCANF_Suppress))
+                        {
+                            *buf++ = *p++;
+                        }
+                        else
+                        {
+                            p++;
+                        }
+                        n_decode++;
+                    }
+
+                    if ((!(flag & kSCANF_Suppress)) && (s != p))
+                    {
+                        nassigned++;
+                    }
+                    break;
+                case kSCANF_DestString:
+                    n_decode += ScanIgnoreWhiteSpace(&p);
+                    s   = p;
+                    buf = va_arg(args_ptr, char *);
+                    while ((field_width--) && (*p != '\0') && (*p != ' ') && (*p != '\t') && (*p != '\n') &&
+                           (*p != '\r') && (*p != '\v') && (*p != '\f'))
+                    {
+                        if (flag & kSCANF_Suppress)
+                        {
+                            p++;
+                        }
+                        else
+                        {
+                            *buf++ = *p++;
+                        }
+                        n_decode++;
+                    }
+
+                    if ((!(flag & kSCANF_Suppress)) && (s != p))
+                    {
+                        /* Add NULL to end of string. */
+                        *buf = '\0';
+                        nassigned++;
+                    }
+                    break;
+                case kSCANF_DestInt:
+                    n_decode += ScanIgnoreWhiteSpace(&p);
+                    s   = p;
+                    val = 0;
+                    if ((base == 0) || (base == 16))
+                    {
+                        if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X')))
+                        {
+                            base = 16;
+                            if (field_width >= 1)
+                            {
+                                p += 2;
+                                n_decode += 2;
+                                field_width -= 2;
+                            }
+                        }
+                    }
+
+                    if (base == 0)
+                    {
+                        if (s[0] == '0')
+                        {
+                            base = 8;
+                        }
+                        else
+                        {
+                            base = 10;
+                        }
+                    }
+
+                    neg = 1;
+                    switch (*p)
+                    {
+                        case '-':
+                            neg = -1;
+                            n_decode++;
+                            p++;
+                            field_width--;
+                            break;
+                        case '+':
+                            neg = 1;
+                            n_decode++;
+                            p++;
+                            field_width--;
+                            break;
+                        default:
+                            break;
+                    }
+
+                    while ((*p) && (field_width--))
+                    {
+                        if ((*p <= '9') && (*p >= '0'))
+                        {
+                            temp = *p - '0';
+                        }
+                        else if ((*p <= 'f') && (*p >= 'a'))
+                        {
+                            temp = *p - 'a' + 10;
+                        }
+                        else if ((*p <= 'F') && (*p >= 'A'))
+                        {
+                            temp = *p - 'A' + 10;
+                        }
+                        else
+                        {
+                            temp = base;
+                        }
+
+                        if (temp >= base)
+                        {
+                            break;
+                        }
+                        else
+                        {
+                            val = base * val + temp;
+                        }
+                        p++;
+                        n_decode++;
+                    }
+                    val *= neg;
+                    if (!(flag & kSCANF_Suppress))
+                    {
+#if SCANF_ADVANCED_ENABLE
+                        switch (flag & kSCANF_LengthMask)
+                        {
+                            case kSCANF_LengthChar:
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed char *) = (signed char)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned char *) = (unsigned char)val;
+                                }
+                                break;
+                            case kSCANF_LengthShortInt:
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed short *) = (signed short)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned short *) = (unsigned short)val;
+                                }
+                                break;
+                            case kSCANF_LengthLongInt:
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed long int *) = (signed long int)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned long int *) = (unsigned long int)val;
+                                }
+                                break;
+                            case kSCANF_LengthLongLongInt:
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed long long int *) = (signed long long int)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned long long int *) = (unsigned long long int)val;
+                                }
+                                break;
+                            default:
+                                /* The default type is the type int. */
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed int *) = (signed int)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned int *) = (unsigned int)val;
+                                }
+                                break;
+                        }
+#else
+                        /* The default type is the type int. */
+                        if (flag & kSCANF_TypeSinged)
+                        {
+                            *va_arg(args_ptr, signed int *) = (signed int)val;
+                        }
+                        else
+                        {
+                            *va_arg(args_ptr, unsigned int *) = (unsigned int)val;
+                        }
+#endif /* SCANF_ADVANCED_ENABLE */
+                        nassigned++;
+                    }
+                    break;
+#if SCANF_FLOAT_ENABLE
+                case kSCANF_DestFloat:
+                    n_decode += ScanIgnoreWhiteSpace(&p);
+                    fnum = strtod(p, (char **)&s);
+
+                    if ((fnum >= HUGE_VAL) || (fnum <= -HUGE_VAL))
+                    {
+                        break;
+                    }
+
+                    n_decode += (int)(s) - (int)(p);
+                    p = s;
+                    if (!(flag & kSCANF_Suppress))
+                    {
+                        if (flag & kSCANF_LengthLongLongDouble)
+                        {
+                            *va_arg(args_ptr, double *) = fnum;
+                        }
+                        else
+                        {
+                            *va_arg(args_ptr, float *) = (float)fnum;
+                        }
+                        nassigned++;
+                    }
+                    break;
+#endif /* SCANF_FLOAT_ENABLE */
+                default:
+                    return nassigned;
+            }
+        }
+    }
+    return nassigned;
+}
diff --git a/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str/fsl_str.h b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str/fsl_str.h
new file mode 100755
index 0000000..bf7adcc
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/devices/JN5189/utilities/str/fsl_str.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _FSL_STR_H
+#define _FSL_STR_H
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup debugconsole
+ * @{
+ */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @brief A function pointer which is used when format printf log.
+ */
+typedef void (*printfCb)(char *buf, int32_t *indicator, char val, int len);
+
+/*!
+ * @brief This function outputs its parameters according to a formatted string.
+ *
+ * @note I/O is performed by calling given function pointer using following
+ * (*func_ptr)(c);
+ *
+ * @param[in] fmt   Format string for printf.
+ * @param[in] ap  Arguments to printf.
+ * @param[in] buf  pointer to the buffer
+ * @param cb print callbck function pointer
+ *
+ * @return Number of characters to be print
+ */
+int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb);
+
+/*!
+ * @brief Converts an input line of ASCII characters based upon a provided
+ * string format.
+ *
+ * @param[in] line_ptr The input line of ASCII data.
+ * @param[in] format   Format first points to the format string.
+ * @param[in] args_ptr The list of parameters.
+ *
+ * @return Number of input items converted and assigned.
+ * @retval IO_EOF When line_ptr is empty string "".
+ */
+int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_STR_H */
diff --git a/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/aes_alt.c b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/aes_alt.c
new file mode 100755
index 0000000..31acea7
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/aes_alt.c
@@ -0,0 +1,1531 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_AES_C)
+
+#include <string.h>
+
+#include "mbedtls/aes.h"
+#include "mbedtls/platform_util.h"
+#if defined(MBEDTLS_PADLOCK_C)
+#include "mbedtls/padlock.h"
+#endif
+#if defined(MBEDTLS_AESNI_C)
+#include "mbedtls/aesni.h"
+#endif
+
+#if defined(MBEDTLS_AES_ALT)
+/* clang-format off */
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ]       )             \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE(n,b,i)                                    \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
+    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
+}
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) &&                      \
+    ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
+static int aes_padlock_ace = -1;
+#endif
+
+#if defined(MBEDTLS_AES_ROM_TABLES)
+#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+/*
+ * Forward S-box
+ */
+static const unsigned char FSb[256] =
+{
+    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+    0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+    0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+    0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+    0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+    0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+    0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+    0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+    0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+    0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+    0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+    0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+    0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+    0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+    0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+    0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+    0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+    0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+    0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+    0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+    0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+    0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+    0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+    0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+    0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+    0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+    0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+    0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+    0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+    0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+    0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+    0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+};
+
+/*
+ * Forward tables
+ */
+#define FT \
+\
+    V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
+    V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
+    V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
+    V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
+    V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
+    V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
+    V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
+    V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
+    V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
+    V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
+    V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
+    V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
+    V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
+    V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
+    V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
+    V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
+    V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
+    V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
+    V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
+    V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
+    V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
+    V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
+    V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
+    V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
+    V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
+    V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
+    V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
+    V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
+    V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
+    V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
+    V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
+    V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
+    V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
+    V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
+    V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
+    V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
+    V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
+    V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
+    V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
+    V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
+    V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
+    V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
+    V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
+    V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
+    V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
+    V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
+    V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
+    V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
+    V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
+    V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
+    V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
+    V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
+    V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
+    V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
+    V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
+    V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
+    V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
+    V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
+    V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
+    V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
+    V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
+    V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
+    V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
+    V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t FT0[256] = { FT };
+#undef V
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t FT1[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t FT2[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t FT3[256] = { FT };
+#undef V
+
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+#undef FT
+
+/*
+ * Reverse S-box
+ */
+static const unsigned char RSb[256] =
+{
+    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+    0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+    0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+    0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+    0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+    0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+    0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+    0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+    0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+    0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+    0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+    0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+    0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+    0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+    0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+    0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+    0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+};
+
+/*
+ * Reverse tables
+ */
+#define RT \
+\
+    V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
+    V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
+    V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
+    V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
+    V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
+    V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
+    V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
+    V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
+    V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
+    V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
+    V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
+    V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
+    V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
+    V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
+    V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
+    V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
+    V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
+    V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
+    V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
+    V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
+    V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
+    V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
+    V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
+    V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
+    V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
+    V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
+    V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
+    V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
+    V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
+    V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
+    V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
+    V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
+    V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
+    V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
+    V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
+    V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
+    V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
+    V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
+    V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
+    V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
+    V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
+    V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
+    V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
+    V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
+    V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
+    V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
+    V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
+    V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
+    V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
+    V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
+    V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
+    V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
+    V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
+    V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
+    V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
+    V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
+    V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
+    V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
+    V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
+    V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
+    V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
+    V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
+    V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
+    V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t RT0[256] = { RT };
+#undef V
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t RT1[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t RT2[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t RT3[256] = { RT };
+#undef V
+
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+#undef RT
+
+/*
+ * Round constants
+ */
+static const uint32_t RCON[10] =
+{
+    0x00000001, 0x00000002, 0x00000004, 0x00000008,
+    0x00000010, 0x00000020, 0x00000040, 0x00000080,
+    0x0000001B, 0x00000036
+};
+
+#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */
+#else /* MBEDTLS_AES_ROM_TABLES */
+
+#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+
+/*
+ * Forward S-box & tables
+ */
+static unsigned char FSb[256];
+static uint32_t FT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+static uint32_t FT1[256];
+static uint32_t FT2[256];
+static uint32_t FT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+/*
+ * Reverse S-box & tables
+ */
+static unsigned char RSb[256];
+static uint32_t RT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+static uint32_t RT1[256];
+static uint32_t RT2[256];
+static uint32_t RT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+/*
+ * Round constants
+ */
+static uint32_t RCON[10];
+
+/*
+ * Tables generation code
+ */
+#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
+#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
+#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
+
+static int aes_init_done = 0;
+
+static void aes_gen_tables( void )
+{
+    int i, x, y, z;
+    int pow[256];
+    int log[256];
+
+    /*
+     * compute pow and log tables over GF(2^8)
+     */
+    for( i = 0, x = 1; i < 256; i++ )
+    {
+        pow[i] = x;
+        log[x] = i;
+        x = ( x ^ XTIME( x ) ) & 0xFF;
+    }
+
+    /*
+     * calculate the round constants
+     */
+    for( i = 0, x = 1; i < 10; i++ )
+    {
+        RCON[i] = (uint32_t) x;
+        x = XTIME( x ) & 0xFF;
+    }
+
+    /*
+     * generate the forward and reverse S-boxes
+     */
+    FSb[0x00] = 0x63;
+    RSb[0x63] = 0x00;
+
+    for( i = 1; i < 256; i++ )
+    {
+        x = pow[255 - log[i]];
+
+        y  = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y ^ 0x63;
+
+        FSb[i] = (unsigned char) x;
+        RSb[x] = (unsigned char) i;
+    }
+
+    /*
+     * generate the forward and reverse tables
+     */
+    for( i = 0; i < 256; i++ )
+    {
+        x = FSb[i];
+        y = XTIME( x ) & 0xFF;
+        z =  ( y ^ x ) & 0xFF;
+
+        FT0[i] = ( (uint32_t) y       ) ^
+                 ( (uint32_t) x <<  8 ) ^
+                 ( (uint32_t) x << 16 ) ^
+                 ( (uint32_t) z << 24 );
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+        FT1[i] = ROTL8( FT0[i] );
+        FT2[i] = ROTL8( FT1[i] );
+        FT3[i] = ROTL8( FT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+        x = RSb[i];
+
+        RT0[i] = ( (uint32_t) MUL( 0x0E, x )       ) ^
+                 ( (uint32_t) MUL( 0x09, x ) <<  8 ) ^
+                 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
+                 ( (uint32_t) MUL( 0x0B, x ) << 24 );
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+        RT1[i] = ROTL8( RT0[i] );
+        RT2[i] = ROTL8( RT1[i] );
+        RT3[i] = ROTL8( RT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+    }
+}
+
+#undef ROTL8
+#endif /*!MBEDTLS_AES_SETKEY_ENC_ALT*/
+#endif /* MBEDTLS_AES_ROM_TABLES */
+
+#if defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define ROTL8(x)  ( (uint32_t)( ( x ) <<  8 ) + (uint32_t)( ( x ) >> 24 ) )
+#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
+#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >>  8 ) )
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) ROTL8(  RT0[idx] )
+#define AES_RT2(idx) ROTL16( RT0[idx] )
+#define AES_RT3(idx) ROTL24( RT0[idx] )
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) ROTL8(  FT0[idx] )
+#define AES_FT2(idx) ROTL16( FT0[idx] )
+#define AES_FT3(idx) ROTL24( FT0[idx] )
+
+#else /* MBEDTLS_AES_FEWER_TABLES */
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) RT1[idx]
+#define AES_RT2(idx) RT2[idx]
+#define AES_RT3(idx) RT3[idx]
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) FT1[idx]
+#define AES_FT2(idx) FT2[idx]
+#define AES_FT3(idx) FT3[idx]
+
+#endif /* MBEDTLS_AES_FEWER_TABLES */
+
+void mbedtls_aes_init( mbedtls_aes_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_aes_context ) );
+}
+
+void mbedtls_aes_free( mbedtls_aes_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
+{
+    mbedtls_aes_init( &ctx->crypt );
+    mbedtls_aes_init( &ctx->tweak );
+}
+
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
+{
+    mbedtls_aes_free( &ctx->crypt );
+    mbedtls_aes_free( &ctx->tweak );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/*
+ * AES key schedule (encryption)
+ */
+#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
+                    unsigned int keybits )
+{
+    unsigned int i;
+    uint32_t *RK;
+
+#if !defined(MBEDTLS_AES_ROM_TABLES)
+    if( aes_init_done == 0 )
+    {
+        aes_gen_tables();
+        aes_init_done = 1;
+
+    }
+#endif
+
+    switch( keybits )
+    {
+        case 128: ctx->nr = 10; break;
+        case 192: ctx->nr = 12; break;
+        case 256: ctx->nr = 14; break;
+        default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+    }
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
+    if( aes_padlock_ace == -1 )
+        aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
+
+    if( aes_padlock_ace )
+        ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
+    else
+#endif
+    ctx->rk = RK = ctx->buf;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+        return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
+#endif
+
+    for( i = 0; i < ( keybits >> 5 ); i++ )
+    {
+        GET_UINT32_LE( RK[i], key, i << 2 );
+    }
+
+    switch( ctx->nr )
+    {
+        case 10:
+
+            for( i = 0; i < 10; i++, RK += 4 )
+            {
+                RK[4]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[3] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[3]       ) & 0xFF ] << 24 );
+
+                RK[5]  = RK[1] ^ RK[4];
+                RK[6]  = RK[2] ^ RK[5];
+                RK[7]  = RK[3] ^ RK[6];
+            }
+            break;
+
+        case 12:
+
+            for( i = 0; i < 8; i++, RK += 6 )
+            {
+                RK[6]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[5] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[5]       ) & 0xFF ] << 24 );
+
+                RK[7]  = RK[1] ^ RK[6];
+                RK[8]  = RK[2] ^ RK[7];
+                RK[9]  = RK[3] ^ RK[8];
+                RK[10] = RK[4] ^ RK[9];
+                RK[11] = RK[5] ^ RK[10];
+            }
+            break;
+
+        case 14:
+
+            for( i = 0; i < 7; i++, RK += 8 )
+            {
+                RK[8]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[7] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[7]       ) & 0xFF ] << 24 );
+
+                RK[9]  = RK[1] ^ RK[8];
+                RK[10] = RK[2] ^ RK[9];
+                RK[11] = RK[3] ^ RK[10];
+
+                RK[12] = RK[4] ^
+                ( (uint32_t) FSb[ ( RK[11]       ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[11] >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+
+                RK[13] = RK[5] ^ RK[12];
+                RK[14] = RK[6] ^ RK[13];
+                RK[15] = RK[7] ^ RK[14];
+            }
+            break;
+    }
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
+
+/*
+ * AES key schedule (decryption)
+ */
+#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
+int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
+                    unsigned int keybits )
+{
+    int i, j, ret;
+    mbedtls_aes_context cty;
+    uint32_t *RK;
+    uint32_t *SK;
+
+    mbedtls_aes_init( &cty );
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
+    if( aes_padlock_ace == -1 )
+        aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
+
+    if( aes_padlock_ace )
+        ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
+    else
+#endif
+    ctx->rk = RK = ctx->buf;
+
+    /* Also checks keybits */
+    if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
+        goto exit;
+
+    ctx->nr = cty.nr;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+    {
+        mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
+                           (const unsigned char *) cty.rk, ctx->nr );
+        goto exit;
+    }
+#endif
+
+    SK = cty.rk + cty.nr * 4;
+
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+
+    for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
+    {
+        for( j = 0; j < 4; j++, SK++ )
+        {
+            *RK++ = AES_RT0( FSb[ ( *SK       ) & 0xFF ] ) ^
+                    AES_RT1( FSb[ ( *SK >>  8 ) & 0xFF ] ) ^
+                    AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
+                    AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
+        }
+    }
+
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+
+exit:
+    mbedtls_aes_free( &cty );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
+                                        unsigned int keybits,
+                                        const unsigned char **key1,
+                                        unsigned int *key1bits,
+                                        const unsigned char **key2,
+                                        unsigned int *key2bits )
+{
+    const unsigned int half_keybits = keybits / 2;
+    const unsigned int half_keybytes = half_keybits / 8;
+
+    switch( keybits )
+    {
+        case 256: break;
+        case 512: break;
+        default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+    }
+
+    *key1bits = half_keybits;
+    *key2bits = half_keybits;
+    *key1 = &key[0];
+    *key2 = &key[half_keybytes];
+
+    return 0;
+}
+
+int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits)
+{
+    int ret;
+    const unsigned char *key1, *key2;
+    unsigned int key1bits, key2bits;
+
+    ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
+                                       &key2, &key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set the tweak key. Always set tweak key for the encryption mode. */
+    ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set crypt key for encryption. */
+    return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
+}
+
+int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits)
+{
+    int ret;
+    const unsigned char *key1, *key2;
+    unsigned int key1bits, key2bits;
+
+    ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
+                                       &key2, &key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set the tweak key. Always set tweak key for encryption. */
+    ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set crypt key for decryption. */
+    return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
+
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)         \
+{                                                   \
+    X0 = *RK++ ^ AES_FT0( ( Y0       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y1 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y3 >> 24 ) & 0xFF );    \
+                                                    \
+    X1 = *RK++ ^ AES_FT0( ( Y1       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y2 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y0 >> 24 ) & 0xFF );    \
+                                                    \
+    X2 = *RK++ ^ AES_FT0( ( Y2       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y3 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y1 >> 24 ) & 0xFF );    \
+                                                    \
+    X3 = *RK++ ^ AES_FT0( ( Y3       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y0 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y2 >> 24 ) & 0xFF );    \
+}
+
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)         \
+{                                                   \
+    X0 = *RK++ ^ AES_RT0( ( Y0       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y3 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y1 >> 24 ) & 0xFF );    \
+                                                    \
+    X1 = *RK++ ^ AES_RT0( ( Y1       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y0 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y2 >> 24 ) & 0xFF );    \
+                                                    \
+    X2 = *RK++ ^ AES_RT0( ( Y2       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y1 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y3 >> 24 ) & 0xFF );    \
+                                                    \
+    X3 = *RK++ ^ AES_RT0( ( Y3       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y2 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y0 >> 24 ) & 0xFF );    \
+}
+
+/*
+ * AES-ECB block encryption
+ */
+#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
+int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] )
+{
+    int i;
+    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+    RK = ctx->rk;
+
+    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
+    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
+    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
+    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+    for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+    {
+        AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+        AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+    }
+
+    AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+    X0 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y0       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+    X1 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y1       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+    X2 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y2       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+    X3 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y3       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+    PUT_UINT32_LE( X0, output,  0 );
+    PUT_UINT32_LE( X1, output,  4 );
+    PUT_UINT32_LE( X2, output,  8 );
+    PUT_UINT32_LE( X3, output, 12 );
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
+                          const unsigned char input[16],
+                          unsigned char output[16] )
+{
+    mbedtls_internal_aes_encrypt( ctx, input, output );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * AES-ECB block decryption
+ */
+#if !defined(MBEDTLS_AES_DECRYPT_ALT)
+int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] )
+{
+    int i;
+    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+    RK = ctx->rk;
+
+    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
+    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
+    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
+    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+    for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+    {
+        AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+        AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+    }
+
+    AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+    X0 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y0       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+    X1 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y1       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+    X2 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y2       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+    X3 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y3       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+    PUT_UINT32_LE( X0, output,  0 );
+    PUT_UINT32_LE( X1, output,  4 );
+    PUT_UINT32_LE( X2, output,  8 );
+    PUT_UINT32_LE( X3, output, 12 );
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_DECRYPT_ALT */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
+                          const unsigned char input[16],
+                          unsigned char output[16] )
+{
+    mbedtls_internal_aes_decrypt( ctx, input, output );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * AES-ECB block encryption/decryption
+ */
+int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
+                    int mode,
+                    const unsigned char input[16],
+                    unsigned char output[16] )
+{
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+        return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
+    if( aes_padlock_ace )
+    {
+        if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
+            return( 0 );
+
+        // If padlock data misaligned, we just fall back to
+        // unaccelerated mode
+        //
+    }
+#endif
+
+    if( mode == MBEDTLS_AES_ENCRYPT )
+        return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
+    else
+        return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+#if !defined(MBEDTLS_AES_CRYPT_CBC_ALT)
+int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[16],
+                    const unsigned char *input,
+                    unsigned char *output )
+{
+    int i;
+    unsigned char temp[16];
+
+    if( length % 16 )
+        return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
+    if( aes_padlock_ace )
+    {
+        if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
+            return( 0 );
+
+        // If padlock data misaligned, we just fall back to
+        // unaccelerated mode
+        //
+    }
+#endif
+
+    if( mode == MBEDTLS_AES_DECRYPT )
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, 16 );
+            mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+
+            for( i = 0; i < 16; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+    else
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < 16; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            memcpy( iv, output, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_CRYPT_CBC_ALT */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+
+/* Endianess with 64 bits values */
+#ifndef GET_UINT64_LE
+#define GET_UINT64_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint64_t) (b)[(i) + 7] << 56 )             \
+        | ( (uint64_t) (b)[(i) + 6] << 48 )             \
+        | ( (uint64_t) (b)[(i) + 5] << 40 )             \
+        | ( (uint64_t) (b)[(i) + 4] << 32 )             \
+        | ( (uint64_t) (b)[(i) + 3] << 24 )             \
+        | ( (uint64_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint64_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint64_t) (b)[(i)    ]       );            \
+}
+#endif
+
+#ifndef PUT_UINT64_LE
+#define PUT_UINT64_LE(n,b,i)                            \
+{                                                       \
+    (b)[(i) + 7] = (unsigned char) ( (n) >> 56 );       \
+    (b)[(i) + 6] = (unsigned char) ( (n) >> 48 );       \
+    (b)[(i) + 5] = (unsigned char) ( (n) >> 40 );       \
+    (b)[(i) + 4] = (unsigned char) ( (n) >> 32 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i)    ] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+typedef unsigned char mbedtls_be128[16];
+
+/*
+ * GF(2^128) multiplication function
+ *
+ * This function multiplies a field element by x in the polynomial field
+ * representation. It uses 64-bit word operations to gain speed but compensates
+ * for machine endianess and hence works correctly on both big and little
+ * endian machines.
+ */
+static void mbedtls_gf128mul_x_ble( unsigned char r[16],
+                                    const unsigned char x[16] )
+{
+    uint64_t a, b, ra, rb;
+
+    GET_UINT64_LE( a, x, 0 );
+    GET_UINT64_LE( b, x, 8 );
+
+    ra = ( a << 1 )  ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
+    rb = ( a >> 63 ) | ( b << 1 );
+
+    PUT_UINT64_LE( ra, r, 0 );
+    PUT_UINT64_LE( rb, r, 8 );
+}
+
+/*
+ * AES-XTS buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
+                           int mode,
+                           size_t length,
+                           const unsigned char data_unit[16],
+                           const unsigned char *input,
+                           unsigned char *output )
+{
+    int ret;
+    size_t blocks = length / 16;
+    size_t leftover = length % 16;
+    unsigned char tweak[16];
+    unsigned char prev_tweak[16];
+    unsigned char tmp[16];
+
+    /* Sectors must be at least 16 bytes. */
+    if( length < 16 )
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+    /* NIST SP 80-38E disallows data units larger than 2**20 blocks. */
+    if( length > ( 1 << 20 ) * 16 )
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+    /* Compute the tweak. */
+    ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
+                                 data_unit, tweak );
+    if( ret != 0 )
+        return( ret );
+
+    while( blocks-- )
+    {
+        size_t i;
+
+        if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
+        {
+            /* We are on the last block in a decrypt operation that has
+             * leftover bytes, so we need to use the next tweak for this block,
+             * and this tweak for the lefover bytes. Save the current tweak for
+             * the leftovers and then update the current tweak for use on this,
+             * the last full block. */
+            memcpy( prev_tweak, tweak, sizeof( tweak ) );
+            mbedtls_gf128mul_x_ble( tweak, tweak );
+        }
+
+        for( i = 0; i < 16; i++ )
+            tmp[i] = input[i] ^ tweak[i];
+
+        ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
+        if( ret != 0 )
+            return( ret );
+
+        for( i = 0; i < 16; i++ )
+            output[i] = tmp[i] ^ tweak[i];
+
+        /* Update the tweak for the next block. */
+        mbedtls_gf128mul_x_ble( tweak, tweak );
+
+        output += 16;
+        input += 16;
+    }
+
+    if( leftover )
+    {
+        /* If we are on the leftover bytes in a decrypt operation, we need to
+         * use the previous tweak for these bytes (as saved in prev_tweak). */
+        unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
+
+        /* We are now on the final part of the data unit, which doesn't divide
+         * evenly by 16. It's time for ciphertext stealing. */
+        size_t i;
+        unsigned char *prev_output = output - 16;
+
+        /* Copy ciphertext bytes from the previous block to our output for each
+         * byte of cyphertext we won't steal. At the same time, copy the
+         * remainder of the input for this final round (since the loop bounds
+         * are the same). */
+        for( i = 0; i < leftover; i++ )
+        {
+            output[i] = prev_output[i];
+            tmp[i] = input[i] ^ t[i];
+        }
+
+        /* Copy ciphertext bytes from the previous block for input in this
+         * round. */
+        for( ; i < 16; i++ )
+            tmp[i] = prev_output[i] ^ t[i];
+
+        ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
+        if( ret != 0 )
+            return ret;
+
+        /* Write the result back to the previous block, overriding the previous
+         * output we copied. */
+        for( i = 0; i < 16; i++ )
+            prev_output[i] = tmp[i] ^ t[i];
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+#if !defined(MBEDTLS_AES_CRYPT_CFB_ALT)
+int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c;
+    size_t n = *iv_off;
+
+    if( mode == MBEDTLS_AES_DECRYPT )
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+            c = *input++;
+            *output++ = (unsigned char)( c ^ iv[n] );
+            iv[n] = (unsigned char) c;
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+    else
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+
+    *iv_off = n;
+
+    return( 0 );
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    unsigned char c;
+    unsigned char ov[17];
+
+    while( length-- )
+    {
+        memcpy( ov, iv, 16 );
+        mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+            ov[16] = *input;
+
+        c = *output++ = (unsigned char)( iv[0] ^ *input++ );
+
+        if( mode == MBEDTLS_AES_ENCRYPT )
+            ov[16] = c;
+
+        memcpy( iv, ov + 1, 16 );
+    }
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_CRYPT_CFB_ALT */
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-OFB (Output Feedback Mode) buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+                           size_t length,
+                           size_t *iv_off,
+                           unsigned char iv[16],
+                           const unsigned char *input,
+                           unsigned char *output )
+{
+    int ret = 0;
+    size_t n = *iv_off;
+
+    while( length-- )
+    {
+        if( n == 0 )
+        {
+            ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            if( ret != 0 )
+                goto exit;
+        }
+        *output++ =  *input++ ^ iv[n];
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *iv_off = n;
+
+exit:
+    return( ret );
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+#if !defined(MBEDTLS_AES_CRYPT_CTR_ALT)
+int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[16],
+                       unsigned char stream_block[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c, i;
+    size_t n = *nc_off;
+
+    if ( n > 0x0F )
+        return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
+    while( length-- )
+    {
+        if( n == 0 ) {
+            mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+
+            for( i = 16; i > 0; i-- )
+                if( ++nonce_counter[i - 1] != 0 )
+                    break;
+        }
+        c = *input++;
+        *output++ = (unsigned char)( c ^ stream_block[n] );
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *nc_off = n;
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_CRYPT_CTR_ALT */
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+/* clang-format on */
+
+/*          HASHCRYPT AES          */
+#if defined(MBEDTLS_FREESCALE_HASHCRYPT_AES)
+
+/*
+ * AES key schedule (encryption)
+ */
+int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
+{
+    size_t key_size;
+
+    switch (keybits)
+    {
+        case 128:
+            key_size = 16;
+            break;
+        case 192:
+            key_size = 24;
+            break;
+        case 256:
+            key_size = 32;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+    /* secret bus is marked as key address == HASHCRYPT base */
+    if ((uint32_t)key == (uint32_t)HASHCRYPT)
+    {
+        ctx->keyType = kHASHCRYPT_SecretKey;
+    }
+    else
+    {
+        ctx->keyType = kHASHCRYPT_UserKey;
+    }
+    if (kStatus_Success != HASHCRYPT_AES_SetKey(HASHCRYPT, ctx, key, key_size))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return (0);
+}
+
+/*
+ * AES key schedule (decryption)
+ */
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
+{
+    size_t key_size;
+
+    switch (keybits)
+    {
+        case 128:
+            key_size = 16;
+            break;
+        case 192:
+            key_size = 24;
+            break;
+        case 256:
+            key_size = 32;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+    /* secret bus is marked as key address == HASHCRYPT base */
+    if ((uint32_t)key == (uint32_t)HASHCRYPT)
+    {
+        ctx->keyType = kHASHCRYPT_SecretKey;
+    }
+    else
+    {
+        ctx->keyType = kHASHCRYPT_UserKey;
+    }
+    if (kStatus_Success != HASHCRYPT_AES_SetKey(HASHCRYPT, ctx, key, key_size))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return 0;
+}
+
+/*
+ * AES-ECB block encryption
+ */
+int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16])
+{
+    if (kStatus_Success != HASHCRYPT_AES_EncryptEcb(HASHCRYPT, ctx, input, output, 16))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return (0);
+}
+
+/*
+ * AES-ECB block decryption
+ */
+int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16])
+{
+    if (kStatus_Success != HASHCRYPT_AES_DecryptEcb(HASHCRYPT, ctx, input, output, 16))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return (0);
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        if (kStatus_Success != HASHCRYPT_AES_DecryptCbc(HASHCRYPT, ctx, input, output, length, iv))
+        {
+            return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+        }
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        if (kStatus_Success != HASHCRYPT_AES_EncryptCbc(HASHCRYPT, ctx, input, output, length, iv))
+        {
+            return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+        }
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t length,
+                          size_t *nc_off,
+                          unsigned char nonce_counter[16],
+                          unsigned char stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    if (kStatus_Success !=
+        HASHCRYPT_AES_CryptCtr(HASHCRYPT, ctx, input, output, length, nonce_counter, stream_block, nc_off))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return (0);
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#endif /* MBEDTLS_FREESCALE_HASHCRYPT_AES */
+#endif /* MBEDTLS_AES_ALT */
+#endif /* MBEDTLS_AES_C */
diff --git a/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/aes_alt.h b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/aes_alt.h
new file mode 100755
index 0000000..af00028
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/aes_alt.h
@@ -0,0 +1,86 @@
+/**
+ * \file aes_alt.h
+ *
+ * \brief   This file contains alternate AES definitions and functions.
+ *
+ *          The Advanced Encryption Standard (AES) specifies a FIPS-approved
+ *          cryptographic algorithm that can be used to protect electronic
+ *          data.
+ *
+ *          The AES algorithm is a symmetric block cipher that can
+ *          encrypt and decrypt information. For more information, see
+ *          <em>FIPS Publication 197: Advanced Encryption Standard</em> and
+ *          <em>ISO/IEC 18033-2:2006: Information technology -- Security
+ *          techniques -- Encryption algorithms -- Part 2: Asymmetric
+ *          ciphers</em>.
+ *
+ *          The AES-XTS block mode is standardized by NIST SP 800-38E
+ *          <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
+ *          and described in detail by IEEE P1619
+ *          <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
+ */
+
+/*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ *  SPDX-License-Identifier: Apache-2.0
+ *  Copyright 2018 NXP. Not a Contribution
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_AES_ALT_H
+#define MBEDTLS_AES_ALT_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_AES_ALT)
+
+#if defined(MBEDTLS_FREESCALE_HASHCRYPT_AES)
+/**
+ * \brief          AES context structure
+ */
+#define mbedtls_aes_context hashcrypt_handle_t
+
+#else
+// Regular implementation
+//
+
+/**
+ * \brief The AES context-type definition.
+ */
+typedef struct
+{
+    int nr;                     /*!< The number of rounds. */
+    uint32_t *rk;               /*!< AES round keys. */
+    uint32_t buf[68];           /*!< Unaligned data buffer. This buffer can
+                                     hold 32 extra Bytes, which can be used for
+                                     one of the following purposes:
+                                     <ul><li>Alignment if VIA padlock is
+                                             used.</li>
+                                     <li>Simplifying key expansion in the 256-bit
+                                         case by generating an extra round key.
+                                         </li></ul> */
+}
+mbedtls_aes_context;
+#endif /* MBEDTLS_FREESCALE_HASHCRYPT_AES */
+
+#endif /* MBEDTLS_AES_ALT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aes_alt.h */
diff --git a/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c
new file mode 100755
index 0000000..ad9f0a2
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c
@@ -0,0 +1,4516 @@
+/*
+ * Copyright 2015-2016, Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "fsl_common.h"
+
+#if defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0)
+#include "fsl_ltc.h"
+#endif
+#if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0)
+#include "fsl_caam.h"
+#endif
+#if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)
+#include "fsl_cau3.h"
+#endif
+#if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0)
+#include "fsl_dcp.h"
+#endif
+#if defined(FSL_FEATURE_SOC_HASHCRYPT_COUNT) && (FSL_FEATURE_SOC_HASHCRYPT_COUNT > 0)
+#include "fsl_hashcrypt.h"
+#endif
+#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+#if defined CPU_JN518X
+    #include "fsl_rng.h"
+#else
+    #include "fsl_trng.h"
+#endif
+#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+#include "fsl_rnga.h"
+#elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0)
+#include "fsl_rng.h"
+#endif
+
+#define CLEAN_RETURN(value) \
+    {                       \
+        ret = value;        \
+        goto cleanup;       \
+    }
+
+/******************************************************************************/
+/*************************** CAAM *********************************************/
+/******************************************************************************/
+#if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM)
+static caam_handle_t s_caamHandle = {.jobRing = kCAAM_JobRing0};
+#endif
+
+/******************************************************************************/
+/*************************** CAU3 *********************************************/
+/******************************************************************************/
+#if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)
+static cau3_handle_t s_cau3Handle = {.taskDone = MBEDTLS_CAU3_COMPLETION_SIGNAL, .keySlot = kCAU3_KeySlot0};
+#endif
+
+/******************************************************************************/
+/**************************** DCP *********************************************/
+/******************************************************************************/
+#if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0)
+static dcp_handle_t s_dcpHandle = {.channel = kDCP_Channel0, .keySlot = kDCP_KeySlot0, .swapConfig = kDCP_NoSwap};
+#endif
+
+/******************************************************************************/
+/************************* Key slot management ********************************/
+/******************************************************************************/
+#if (defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)) || (defined(MBEDTLS_FREESCALE_DCP_AES))
+static const void *s_mbedtlsCtx[4] = {0};
+
+static void crypto_attach_ctx_to_key_slot(const void *ctx, uint8_t keySlot)
+{
+    s_mbedtlsCtx[keySlot] = ctx;
+}
+
+static void crypto_detach_ctx_from_key_slot(const void *ctx)
+{
+    for (int i = 0; i < 4; i++)
+    {
+        if (ctx == s_mbedtlsCtx[i])
+        {
+            s_mbedtlsCtx[i] = NULL;
+            break;
+        }
+    }
+}
+
+static bool crypto_key_is_loaded(const void *ctx)
+{
+    bool ret = false;
+    for (int i = 0; i < 4; i++)
+    {
+        if (ctx == s_mbedtlsCtx[i])
+        {
+            ret = true;
+            break;
+        }
+    }
+    return ret;
+}
+#endif
+
+#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT)
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize(void *v, size_t n)
+{
+    volatile unsigned char *p = v;
+    while (n--)
+        *p++ = 0;
+}
+#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT */
+
+/******************************************************************************/
+/******************** CRYPTO_InitHardware **************************************/
+/******************************************************************************/
+/*!
+ * @brief Application init for various Crypto blocks.
+ *
+ * This function is provided to be called by MCUXpresso SDK applications.
+ * It calls basic init for Crypto Hw acceleration and Hw entropy modules.
+ */
+void CRYPTO_InitHardware(void)
+{
+#if defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0)
+    /* Initialize LTC driver.
+     * This enables clocking and resets the module to a known state. */
+    LTC_Init(LTC0);
+#endif
+#if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM)
+    /* Initialize CAAM driver. */
+    caam_config_t caamConfig;
+
+    CAAM_GetDefaultConfig(&caamConfig);
+    caamConfig.jobRingInterface[0] = &s_jrif0;
+    caamConfig.jobRingInterface[1] = &s_jrif1;
+    CAAM_Init(CAAM, &caamConfig);
+#endif
+#if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)
+    /* Initialize CAU3 */
+    CAU3_Init(CAU3);
+#endif
+#if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0)
+    /* Initialize DCP */
+    dcp_config_t dcpConfig;
+
+    DCP_GetDefaultConfig(&dcpConfig);
+    DCP_Init(DCP, &dcpConfig);
+#endif
+#if defined(FSL_FEATURE_SOC_CASPER_COUNT) && (FSL_FEATURE_SOC_CASPER_COUNT > 0)
+    /* Initialize CASPER */
+    CASPER_Init(CASPER);
+#endif
+#if defined(FSL_FEATURE_SOC_HASHCRYPT_COUNT) && (FSL_FEATURE_SOC_HASHCRYPT_COUNT > 0)
+    /* Initialize HASHCRYPT */
+    HASHCRYPT_Init(HASHCRYPT);
+#endif
+    { /* Init RNG module.*/
+#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+#if defined CPU_JN518X
+    #if defined(RNG)
+    #define TRNG0 RNG
+    #endif
+#else
+    #if defined(TRNG)
+    #define TRNG0 TRNG
+    #endif
+#endif
+        trng_config_t trngConfig;
+
+        TRNG_GetDefaultConfig(&trngConfig);
+        /* Set sample mode of the TRNG ring oscillator to Von Neumann, for better random data.*/
+        /* Initialize TRNG */
+        TRNG_Init(TRNG0, &trngConfig);
+#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+        RNGA_Init(RNG);
+        RNGA_Seed(RNG, SIM->UIDL);
+#endif
+    }
+}
+
+/******************************************************************************/
+/*************************** DES **********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_DES_C)
+
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_MMCAU_DES) || \
+    defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+
+#include "mbedtls/des.h"
+
+#if defined(MBEDTLS_FREESCALE_MMCAU_DES)
+const unsigned char parityLookup[128] = {1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0,
+                                         0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1,
+                                         0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1,
+                                         1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+                                         0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
+#endif
+
+#if defined(MBEDTLS_FREESCALE_MMCAU_DES) || defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES)
+/*
+ * DES key schedule (56-bit, encryption)
+ */
+int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE);
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_ENCRYPT;
+
+    return (0);
+}
+
+/*
+ * DES key schedule (56-bit, decryption)
+ */
+int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE);
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_DECRYPT;
+
+    return (0);
+}
+#endif /* MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_CAAM_DES */
+
+/*
+ * Triple-DES key schedule (112-bit, encryption)
+ */
+int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 2);
+    memcpy(&ctx->sk[4], key, MBEDTLS_DES_KEY_SIZE); /* K3 = K1 */
+#if defined(MBEDTLS_FREESCALE_CAU3_DES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 2; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+    for (i = MBEDTLS_DES_KEY_SIZE * 2; i < MBEDTLS_DES_KEY_SIZE * 3; i++)
+    {
+        sk_b[i] = ((key[i - MBEDTLS_DES_KEY_SIZE * 2] & 0xFE) | parityLookup[key[i - MBEDTLS_DES_KEY_SIZE * 2] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_ENCRYPT;
+
+    return (0);
+}
+
+/*
+ * Triple-DES key schedule (112-bit, decryption)
+ */
+int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 2);
+    memcpy(&ctx->sk[4], key, MBEDTLS_DES_KEY_SIZE); /* K3 = K1 */
+#if defined(MBEDTLS_FREESCALE_CAU3_DES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 2; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+    for (i = MBEDTLS_DES_KEY_SIZE * 2; i < MBEDTLS_DES_KEY_SIZE * 3; i++)
+    {
+        sk_b[i] = ((key[i - MBEDTLS_DES_KEY_SIZE * 2] & 0xFE) | parityLookup[key[i - MBEDTLS_DES_KEY_SIZE * 2] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_DECRYPT;
+
+    return (0);
+}
+
+/*
+ * Triple-DES key schedule (168-bit, encryption)
+ */
+int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 3);
+#if defined(MBEDTLS_FREESCALE_CAU3_DES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 3; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_ENCRYPT;
+
+    return (0);
+}
+
+/*
+ * Triple-DES key schedule (168-bit, decryption)
+ */
+int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 3);
+#if defined(MBEDTLS_FREESCALE_CAU3_DES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 3; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_DECRYPT;
+    return (0);
+}
+
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_MMCAU_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES)
+/*
+ * DES-ECB block encryption/decryption
+ */
+int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx, const unsigned char input[8], unsigned char output[8])
+{
+    uint8_t *key = (uint8_t *)ctx->sk;
+#if defined(MBEDTLS_FREESCALE_LTC_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        LTC_DES_EncryptEcb(LTC_INSTANCE, input, output, 8, key);
+    }
+    else
+    {
+        LTC_DES_DecryptEcb(LTC_INSTANCE, input, output, 8, key);
+    }
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        MMCAU_DES_EncryptEcb(input, key, output);
+    }
+    else
+    {
+        MMCAU_DES_DecryptEcb(input, key, output);
+    }
+#elif defined(MBEDTLS_FREESCALE_CAAM_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAAM_DES_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key);
+    }
+    else
+    {
+        CAAM_DES_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key);
+    }
+#endif
+    return (0);
+}
+#endif /* MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_CAAM_DES */
+
+/*
+ * 3DES-ECB block encryption/decryption
+ */
+int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx, const unsigned char input[8], unsigned char output[8])
+{
+    uint8_t *key = (uint8_t *)ctx->sk;
+#if defined(MBEDTLS_FREESCALE_LTC_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        LTC_DES3_EncryptEcb(LTC_INSTANCE, input, output, 8, key, key + 8, key + 16);
+    }
+    else
+    {
+        LTC_DES3_DecryptEcb(LTC_INSTANCE, input, output, 8, key, key + 8, key + 16);
+    }
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        MMCAU_DES_EncryptEcb(input, key, output);
+        MMCAU_DES_DecryptEcb(output, key + 8, output);
+        MMCAU_DES_EncryptEcb(output, key + 16, output);
+    }
+    else
+    {
+        MMCAU_DES_DecryptEcb(input, key + 16, output);
+        MMCAU_DES_EncryptEcb(output, key + 8, output);
+        MMCAU_DES_DecryptEcb(output, key, output);
+    }
+#elif defined(MBEDTLS_FREESCALE_CAAM_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAAM_DES3_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key, key + 8, key + 16);
+    }
+    else
+    {
+        CAAM_DES3_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key, key + 8, key + 16);
+    }
+#elif defined(MBEDTLS_FREESCALE_CAU3_DES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        CAU3_TDES_SetKey(CAU3, &s_cau3Handle, key, 24);
+        crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot);
+    }
+
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAU3_TDES_Encrypt(CAU3, &s_cau3Handle, input, output);
+    }
+    else
+    {
+        CAU3_TDES_Decrypt(CAU3, &s_cau3Handle, input, output);
+    }
+#endif
+    return (0);
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * DES-CBC buffer encryption/decryption
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_DES)
+int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[8],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    unsigned char temp[8];
+    uint8_t *key = (uint8_t *)ctx->sk;
+
+    if (length % 8)
+        return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_DES_ENCRYPT)
+    {
+        LTC_DES_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key);
+        memcpy(iv, output + length - 8, 8);
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        memcpy(temp, input + length - 8, 8);
+        LTC_DES_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key);
+        memcpy(iv, temp, 8);
+    }
+    return (0);
+}
+
+/*
+ * 3DES-CBC buffer encryption/decryption
+ */
+int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
+                           int mode,
+                           size_t length,
+                           unsigned char iv[8],
+                           const unsigned char *input,
+                           unsigned char *output)
+{
+    unsigned char temp[8];
+    uint8_t *key = (uint8_t *)ctx->sk;
+
+    if (length % 8)
+        return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_DES_ENCRYPT)
+    {
+        LTC_DES3_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key, key + 8, key + 16);
+        memcpy(iv, output + length - 8, 8);
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        memcpy(temp, input + length - 8, 8);
+        LTC_DES3_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key, key + 8, key + 16);
+        memcpy(iv, temp, 8);
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_DES)
+int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[8],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    unsigned char temp[8];
+    uint8_t *key = (uint8_t *)ctx->sk;
+
+    if (length % 8)
+        return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAAM_DES_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key);
+        memcpy(iv, output + length - 8, 8);
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        memcpy(temp, input + length - 8, 8);
+        CAAM_DES_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key);
+        memcpy(iv, temp, 8);
+    }
+    return (0);
+}
+
+/*
+ * 3DES-CBC buffer encryption/decryption
+ */
+int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
+                           int mode,
+                           size_t length,
+                           unsigned char iv[8],
+                           const unsigned char *input,
+                           unsigned char *output)
+{
+    unsigned char temp[8];
+    uint8_t *key = (uint8_t *)ctx->sk;
+
+    if (length % 8)
+        return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAAM_DES3_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, key + 8, key + 16);
+        memcpy(iv, output + length - 8, 8);
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        memcpy(temp, input + length - 8, 8);
+        CAAM_DES3_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, key + 8, key + 16);
+        memcpy(iv, temp, 8);
+    }
+
+    return (0);
+}
+
+#endif /* MBEDTLS_FREESCALE_LTC_DES */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#endif /*MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_CAAM_DES*/
+
+#endif /* MBEDTLS_DES_C */
+
+/******************************************************************************/
+/*************************** AES **********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_AES_C)
+
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_MMCAU_AES) || \
+    defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) ||  \
+    defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+
+#include "mbedtls/aes.h"
+
+/*
+ * AES key schedule (encryption)
+ */
+int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
+{
+    uint32_t *RK;
+    
+#ifdef MBEDTLS_AES_ALT_NO_192
+    if (keybits == 192u)
+    {
+        return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE);
+    }
+#endif
+
+#ifdef MBEDTLS_AES_ALT_NO_256
+    if (keybits == 256u)
+    {
+        return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE);
+    }
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) || \
+    defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+    const unsigned char *key_tmp = key;    
+    ctx->rk = RK = ctx->buf;
+    memcpy(RK, key_tmp, keybits / 8);
+
+#if defined(MBEDTLS_FREESCALE_CAU3_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif /* MBEDTLS_FREESCALE_CAU3_AES || MBEDTLS_FREESCALE_DCP_AES */
+
+    switch (keybits)
+    { /* Set keysize in bytes.*/
+        case 128:
+            ctx->nr = 16;
+            break;
+        case 192:
+            ctx->nr = 24;
+            break;
+        case 256:
+            ctx->nr = 32;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+#elif defined(MBEDTLS_FREESCALE_MMCAU_AES)
+    ctx->rk = RK = ctx->buf;
+
+    switch (keybits)
+    {
+        case 128:
+            ctx->nr = 10;
+            break;
+        case 192:
+            ctx->nr = 12;
+            break;
+        case 256:
+            ctx->nr = 14;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+
+    MMCAU_AES_SetKey(key, keybits / 8, (uint8_t *)RK);
+#endif
+
+    return (0);
+}
+
+/*
+ * AES key schedule (decryption)
+ */
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
+{
+    uint32_t *RK;
+    
+#ifdef MBEDTLS_AES_ALT_NO_192
+    if (keybits == 192u)
+    {
+        return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE);
+    }
+#endif
+
+#ifdef MBEDTLS_AES_ALT_NO_256
+    if (keybits == 256u)
+    {
+        return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE);
+    }
+#endif
+
+    ctx->rk = RK = ctx->buf;
+
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) || \
+    defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+    const unsigned char *key_tmp = key;
+    memcpy(RK, key_tmp, keybits / 8);
+
+#if defined(MBEDTLS_FREESCALE_CAU3_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif /* MBEDTLS_FREESCALE_CAU3_AES || MBEDTLS_FREESCALE_DCP_AES */
+
+    switch (keybits)
+    {
+        case 128:
+            ctx->nr = 16;
+            break;
+        case 192:
+            ctx->nr = 24;
+            break;
+        case 256:
+            ctx->nr = 32;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+#elif defined(MBEDTLS_FREESCALE_MMCAU_AES)
+    ctx->rk = RK = ctx->buf;
+
+    switch (keybits)
+    {
+        case 128:
+            ctx->nr = 10;
+            break;
+        case 192:
+            ctx->nr = 12;
+            break;
+        case 256:
+            ctx->nr = 14;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+
+    MMCAU_AES_SetKey(key, keybits / 8, (uint8_t *)RK);
+#endif
+
+    return 0;
+}
+
+/*
+ * AES-ECB block encryption
+ */
+int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16])
+{
+    uint8_t *key;
+
+    key = (uint8_t *)ctx->rk;
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+    LTC_AES_EncryptEcb(LTC_INSTANCE, input, output, 16, key, ctx->nr);
+#elif defined(MBEDTLS_FREESCALE_MMCAU_AES)
+    MMCAU_AES_EncryptEcb(input, key, ctx->nr, output);
+#elif defined(MBEDTLS_FREESCALE_CAU3_AES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot);
+    }
+    CAU3_AES_Encrypt(CAU3, &s_cau3Handle, input, output);
+#elif defined(MBEDTLS_FREESCALE_LPC_AES)
+    AES_SetKey(AES_INSTANCE, key, ctx->nr);
+    AES_EncryptEcb(AES_INSTANCE, input, output, 16);
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+    CAAM_AES_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 16, key, ctx->nr);
+#elif defined(MBEDTLS_FREESCALE_DCP_AES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot);
+    }
+    DCP_AES_EncryptEcb(DCP, &s_dcpHandle, input, output, 16);
+#endif
+
+    return (0);
+}
+
+/*
+ * AES-ECB block decryption
+ */
+int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16])
+{
+    uint8_t *key;
+
+    key = (uint8_t *)ctx->rk;
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+    LTC_AES_DecryptEcb(LTC_INSTANCE, input, output, 16, key, ctx->nr, kLTC_EncryptKey);
+#elif defined(MBEDTLS_FREESCALE_MMCAU_AES)
+    MMCAU_AES_DecryptEcb(input, key, ctx->nr, output);
+#elif defined(MBEDTLS_FREESCALE_CAU3_AES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot);
+    }
+    CAU3_AES_Decrypt(CAU3, &s_cau3Handle, input, output);
+#elif defined(MBEDTLS_FREESCALE_LPC_AES)
+    AES_SetKey(AES_INSTANCE, key, ctx->nr);
+    AES_DecryptEcb(AES_INSTANCE, input, output, 16);
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+    CAAM_AES_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 16, key, ctx->nr);
+#elif defined(MBEDTLS_FREESCALE_DCP_AES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot);
+    }
+    DCP_AES_DecryptEcb(DCP, &s_dcpHandle, input, output, 16);
+#endif
+
+    return (0);
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key = (uint8_t *)ctx->rk;
+    uint32_t keySize = ctx->nr;
+
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        LTC_AES_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key, keySize, kLTC_EncryptKey);
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        LTC_AES_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key, keySize);
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_LPC_AES)
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+    size_t keySize;
+
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    key = (uint8_t *)ctx->rk;
+    keySize = (size_t)ctx->nr;
+    AES_SetKey(AES_INSTANCE, key, keySize);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        AES_DecryptCbc(AES_INSTANCE, tmp, output, length, iv);
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        AES_EncryptCbc(AES_INSTANCE, input, output, length, iv);
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key = (uint8_t *)ctx->rk;
+    uint32_t keySize = ctx->nr;
+
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        CAAM_AES_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, keySize);
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        CAAM_AES_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, keySize);
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_DCP_AES)
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    key = (uint8_t *)ctx->rk;
+    if (!crypto_key_is_loaded(ctx))
+    {
+        DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot);
+    }
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        DCP_AES_DecryptCbc(DCP, &s_dcpHandle, input, output, length, iv);
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        DCP_AES_EncryptCbc(DCP, &s_dcpHandle, input, output, length, iv);
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#endif
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+#if defined(MBEDTLS_FREESCALE_LPC_AES)
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
+                             int mode,
+                             size_t length,
+                             size_t *iv_off,
+                             unsigned char iv[16],
+                             const unsigned char *input,
+                             unsigned char *output)
+{
+    uint8_t *key;
+    size_t keySize;
+
+    key = (uint8_t *)ctx->rk;
+    keySize = (size_t)ctx->nr;
+    AES_SetKey(AES_INSTANCE, key, keySize);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        AES_DecryptCfb(AES_INSTANCE, input, output, length, iv);
+    }
+    else
+    {
+        AES_EncryptCfb(AES_INSTANCE, input, output, length, iv);
+    }
+
+    return (0);
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
+                           int mode,
+                           size_t length,
+                           unsigned char iv[16],
+                           const unsigned char *input,
+                           unsigned char *output)
+{
+    int status;
+    unsigned char c;
+    unsigned char ov[17];
+
+    while (length--)
+    {
+        memcpy(ov, iv, 16);
+        status = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
+        if (status != 0)
+        {
+            return status;
+        }
+
+        if (mode == MBEDTLS_AES_DECRYPT)
+            ov[16] = *input;
+
+        c = *output++ = (unsigned char)(iv[0] ^ *input++);
+
+        if (mode == MBEDTLS_AES_ENCRYPT)
+            ov[16] = c;
+
+        memcpy(iv, ov + 1, 16);
+    }
+
+    return (0);
+}
+#endif /* MBEDTLS_FREESCALE_LPC_AES */
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t length,
+                          size_t *nc_off,
+                          unsigned char nonce_counter[16],
+                          unsigned char stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+    uint32_t keySize;
+
+    key = (uint8_t *)ctx->rk;
+    keySize = ctx->nr;
+    LTC_AES_CryptCtr(LTC_INSTANCE, input, output, length, nonce_counter, key, keySize, stream_block,
+                     (uint32_t *)nc_off);
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_LPC_AES)
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t length,
+                          size_t *nc_off,
+                          unsigned char nonce_counter[16],
+                          unsigned char stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+    size_t keySize;
+
+    key = (uint8_t *)ctx->rk;
+    keySize = (size_t)ctx->nr;
+
+    AES_SetKey(AES_INSTANCE, key, keySize);
+    AES_CryptCtr(AES_INSTANCE, input, output, length, nonce_counter, stream_block, nc_off);
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t length,
+                          size_t *nc_off,
+                          unsigned char nonce_counter[16],
+                          unsigned char stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+    uint32_t keySize;
+
+    key = (uint8_t *)ctx->rk;
+    keySize = ctx->nr;
+
+    CAAM_AES_CryptCtr(CAAM_INSTANCE, &s_caamHandle, input, output, length, nonce_counter, key, keySize, stream_block,
+                      nc_off);
+
+    return (0);
+}
+#endif
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_CMAC_ALT) && defined(MBEDTLS_CMAC_C)
+
+#include "mbedtls/cipher.h"
+#include "mbedtls/cmac.h"
+
+#if defined(MBEDTLS_FREESCALE_CAU3_CIPHER_CMAC)
+int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
+                        const unsigned char *key,
+                        size_t keylen,
+                        const unsigned char *input,
+                        size_t ilen,
+                        unsigned char *output)
+{
+    mbedtls_cipher_context_t ctx;
+    int ret;
+
+    if (cipher_info == NULL || key == NULL || input == NULL || output == NULL)
+        return (MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA);
+
+    mbedtls_cipher_init(&ctx);
+
+    if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0)
+        goto exit;
+
+    ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
+    if (ret != 0)
+        goto exit;
+
+    /* AES-CMAC-128 is directly supported by CAU3 firmware */
+    if (cipher_info->type == MBEDTLS_CIPHER_AES_128_ECB)
+    {
+        status_t status;
+        uint8_t mac[16];
+
+        status = CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, keylen / 8u);
+        if (status != kStatus_Success)
+        {
+            ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+            goto exit;
+        }
+        status = CAU3_AES_Cmac(CAU3, &s_cau3Handle, input, ilen, mac);
+        if (status != kStatus_Success)
+        {
+            ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+            goto exit;
+        }
+        memcpy(output, mac, 16);
+    }
+#if defined(MBEDTLS_CIPHER_CMAC_TDES_ENABLED) || defined(MBEDTLS_CIPHER_CMAC_AES_256_ENABLED)
+    else if (cipher_info->type == MBEDTLS_CIPHER_AES_192_ECB)
+    {
+        /* CAU3 initial firmware does not support AES 192 */
+        ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+        goto exit;
+    }
+    else
+    {
+        /* AES-CMAC-256 and TDES-CMAC.
+         * If both MBEDTLS_DES_C and MBEDTLS_CIPHER_CMAC_WANTS_AES_256 are undefined,
+         * this does not compile
+         */
+        ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
+        if (ret != 0)
+            goto exit;
+
+        ret = mbedtls_cipher_cmac_finish(&ctx, output);
+    }
+#else
+    else
+    {
+        ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+        goto exit;
+    }
+#endif /* MBEDTLS_CIPHER_CMAC_TDES_ENABLED || MBEDTLS_CIPHER_CMAC_AES_256_ENABLED */
+
+exit:
+    mbedtls_cipher_free(&ctx);
+
+    return (ret);
+}
+#endif /* MBEDTLS_FREESCALE_CAU3_CIPHER_CMAC */
+#endif /* MBEDTLS_CIPHER_CMAC_ALT && MBEDTLS_CMAC_C */
+
+#if defined(MBEDTLS_CCM_C)
+
+#include "mbedtls/ccm.h"
+
+#define CCM_ENCRYPT 0
+#define CCM_DECRYPT 1
+
+/*
+ * Authenticated encryption or decryption
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+static int ccm_auth_crypt(mbedtls_ccm_context *ctx,
+                          int mode,
+                          size_t length,
+                          const unsigned char *iv,
+                          size_t iv_len,
+                          const unsigned char *add,
+                          size_t add_len,
+                          const unsigned char *input,
+                          unsigned char *output,
+                          unsigned char *tag,
+                          size_t tag_len)
+{
+    status_t status;
+    const uint8_t *key;
+    uint8_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = aes_ctx->nr;
+    if (mode == CCM_ENCRYPT)
+    {
+        status = LTC_AES_EncryptTagCcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag,
+                                       tag_len);
+    }
+    else
+    {
+        status = LTC_AES_DecryptTagCcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag,
+                                       tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+static int ccm_auth_crypt(mbedtls_ccm_context *ctx,
+                          int mode,
+                          size_t length,
+                          const unsigned char *iv,
+                          size_t iv_len,
+                          const unsigned char *add,
+                          size_t add_len,
+                          const unsigned char *input,
+                          unsigned char *output,
+                          unsigned char *tag,
+                          size_t tag_len)
+{
+    status_t status;
+    const uint8_t *key;
+    uint8_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = aes_ctx->nr;
+    if (mode == CCM_ENCRYPT)
+    {
+        status = CAAM_AES_EncryptTagCcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len,
+                                        key, keySize, tag, tag_len);
+    }
+    else
+    {
+        status = CAAM_AES_DecryptTagCcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len,
+                                        key, keySize, tag, tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    return (0);
+}
+#endif /* MBEDTLS_FREESCALE_LTC_AES */
+
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_CAAM_AES)
+/*
+ * Authenticated encryption
+ */
+int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx,
+                                size_t length,
+                                const unsigned char *iv,
+                                size_t iv_len,
+                                const unsigned char *add,
+                                size_t add_len,
+                                const unsigned char *input,
+                                unsigned char *output,
+                                unsigned char *tag,
+                                size_t tag_len)
+{
+    return (ccm_auth_crypt(ctx, CCM_ENCRYPT, length, iv, iv_len, add, add_len, input, output, tag, tag_len));
+}
+
+/*
+ * Authenticated decryption
+ */
+int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx,
+                             size_t length,
+                             const unsigned char *iv,
+                             size_t iv_len,
+                             const unsigned char *add,
+                             size_t add_len,
+                             const unsigned char *input,
+                             unsigned char *output,
+                             const unsigned char *tag,
+                             size_t tag_len)
+{
+    unsigned char tagCopy[16];
+    unsigned char *actTag = NULL;
+    if (tag)
+    {
+        memcpy(tagCopy, tag, tag_len);
+        actTag = tagCopy;
+    }
+    return (ccm_auth_crypt(ctx, CCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, actTag, tag_len));
+}
+#endif /* MBEDTLS_FREESCALE_LTC_AES || MBEDTLS_FREESCALE_CAAM_AES */
+#endif /* MBEDTLS_CCM_C */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_FREESCALE_LTC_AES_GCM)
+
+#include "mbedtls/gcm.h"
+
+int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
+                              int mode,
+                              size_t length,
+                              const unsigned char *iv,
+                              size_t iv_len,
+                              const unsigned char *add,
+                              size_t add_len,
+                              const unsigned char *input,
+                              unsigned char *output,
+                              size_t tag_len,
+                              unsigned char *tag)
+{
+    status_t status;
+    uint8_t *key;
+    uint32_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    ctx->len = length;
+    ctx->add_len = add_len;
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = aes_ctx->nr;
+    if (mode == MBEDTLS_GCM_ENCRYPT)
+    {
+        status = LTC_AES_EncryptTagGcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag,
+                                       tag_len);
+    }
+    else
+    {
+        status = LTC_AES_DecryptTagGcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag,
+                                       tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
+                             size_t length,
+                             const unsigned char *iv,
+                             size_t iv_len,
+                             const unsigned char *add,
+                             size_t add_len,
+                             const unsigned char *tag,
+                             size_t tag_len,
+                             const unsigned char *input,
+                             unsigned char *output)
+{
+    unsigned char tag_copy[16];
+    unsigned char *actTag = NULL;
+    if (tag)
+    {
+        memcpy(tag_copy, tag, tag_len);
+        actTag = tag_copy;
+    }
+    return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output,
+                                      tag_len, actTag));
+}
+
+#elif defined(MBEDTLS_FREESCALE_LPC_AES_GCM)
+
+#include "mbedtls/gcm.h"
+
+int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
+                              int mode,
+                              size_t length,
+                              const unsigned char *iv,
+                              size_t iv_len,
+                              const unsigned char *add,
+                              size_t add_len,
+                              const unsigned char *input,
+                              unsigned char *output,
+                              size_t tag_len,
+                              unsigned char *tag)
+{
+    status_t status;
+    uint8_t *key;
+    size_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    ctx->len = length;
+    ctx->add_len = add_len;
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = (size_t)aes_ctx->nr;
+
+    status = AES_SetKey(AES_INSTANCE, key, keySize);
+    if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    if (mode == MBEDTLS_GCM_ENCRYPT)
+    {
+        status = AES_EncryptTagGcm(AES_INSTANCE, input, output, length, iv, iv_len, add, add_len, tag, tag_len);
+    }
+    else
+    {
+        status = AES_DecryptTagGcm(AES_INSTANCE, input, output, length, iv, iv_len, add, add_len, tag, tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
+                             size_t length,
+                             const unsigned char *iv,
+                             size_t iv_len,
+                             const unsigned char *add,
+                             size_t add_len,
+                             const unsigned char *tag,
+                             size_t tag_len,
+                             const unsigned char *input,
+                             unsigned char *output)
+{
+    unsigned char tag_copy[16];
+
+    memcpy(tag_copy, tag, tag_len);
+    return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output,
+                                      tag_len, tag_copy));
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES_GCM)
+
+#include "mbedtls/gcm.h"
+
+int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
+                              int mode,
+                              size_t length,
+                              const unsigned char *iv,
+                              size_t iv_len,
+                              const unsigned char *add,
+                              size_t add_len,
+                              const unsigned char *input,
+                              unsigned char *output,
+                              size_t tag_len,
+                              unsigned char *tag)
+{
+    status_t status;
+    uint8_t *key;
+    uint32_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    ctx->len = length;
+    ctx->add_len = add_len;
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = aes_ctx->nr;
+    if (mode == MBEDTLS_GCM_ENCRYPT)
+    {
+        status = CAAM_AES_EncryptTagGcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len,
+                                        key, keySize, tag, tag_len);
+    }
+    else
+    {
+        status = CAAM_AES_DecryptTagGcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len,
+                                        key, keySize, tag, tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
+                             size_t length,
+                             const unsigned char *iv,
+                             size_t iv_len,
+                             const unsigned char *add,
+                             size_t add_len,
+                             const unsigned char *tag,
+                             size_t tag_len,
+                             const unsigned char *input,
+                             unsigned char *output)
+{
+    unsigned char tag_copy[16];
+    unsigned char *actTag = NULL;
+    if (tag)
+    {
+        memcpy(tag_copy, tag, tag_len);
+        actTag = tag_copy;
+    }
+    return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output,
+                                      tag_len, actTag));
+}
+#endif
+#endif /* MBEDTLS_GCM_C */
+
+#endif /* MBEDTLS_FREESCALE_LTC_AES || MBEDTLS_FREESCALE_MMCAU_AES || MBEDTLS_FREESCALE_LPC_AES */
+
+#endif /* MBEDTLS_AES_C */
+
+/******************************************************************************/
+/*************************** PKHA *********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) || defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+static void ltc_reverse_array(uint8_t *src, size_t src_len)
+{
+    int i;
+
+    for (i = 0; i < src_len / 2; i++)
+    {
+        uint8_t tmp;
+
+        tmp = src[i];
+        src[i] = src[src_len - 1 - i];
+        src[src_len - 1 - i] = tmp;
+    }
+}
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#include "mbedtls/bignum.h"
+
+#if defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+#define LTC_PKHA_ModAdd CAU3_PKHA_ModAdd
+#define LTC_PKHA_ModSub1 CAU3_PKHA_ModSub1
+#define LTC_PKHA_ModMul CAU3_PKHA_ModMul
+#define LTC_PKHA_ModRed CAU3_PKHA_ModRed
+#define LTC_PKHA_ModExp CAU3_PKHA_ModExp
+#define LTC_PKHA_GCD CAU3_PKHA_ModGcd
+#define LTC_PKHA_ModInv CAU3_PKHA_ModInv
+#define LTC_PKHA_PrimalityTest CAU3_PKHA_PrimalityTest
+#define LTC_INSTANCE ((CAU3_Type *)CAU3_BASE)
+
+#define kLTC_PKHA_IntegerArith kCAU3_PKHA_IntegerArith
+#define kLTC_PKHA_NormalValue kCAU3_PKHA_NormalValue
+#define kLTC_PKHA_TimingEqualized kCAU3_PKHA_TimingEqualized
+
+#define cau3_reverse_array ltc_reverse_array
+#define cau3_get_from_mbedtls_mpi ltc_get_from_mbedtls_mpi
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA)
+typedef uint16_t pkha_size_t;
+#else
+typedef size_t pkha_size_t;
+#endif
+
+#if defined(MBEDTLS_MPI_ADD_ABS_ALT)
+
+/* Access to original version of mbedtls_mpi_add_abs function. */
+int mbedtls_mpi_add_abs_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Unsigned addition: X = |A| + |B|  (HAC 14.7)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Perform HW acceleration only if the size in bytes is less than maximum.
+     * Since modular add is used below, the result would be wrong
+     * if the real sum of operands exceeded LTC maximum number value.
+     */
+    if ((sizeA < sizeN) && (sizeB < sizeN))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        ret = (int)LTC_PKHA_ModAdd(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC,
+                                   kLTC_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = 1;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_add_abs_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Perform HW acceleration only if the size in bytes is less than maximum.
+     * Since modular add is used below, the result would be wrong
+     * if the real sum of operands exceeded CAAM maximum number value.
+     */
+    if ((sizeA < sizeN) && (sizeB < sizeN))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        ret = (int)CAAM_PKHA_ModAdd(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = 1;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_add_abs_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_ADD_ABS_ALT */
+
+#if defined(MBEDTLS_MPI_SUB_ABS_ALT)
+
+/* Access to original version of mbedtls_mpi_sub_abs function. */
+int mbedtls_mpi_sub_abs_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Unsigned subtraction: X = |A| - |B|  (HAC 14.9)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Perform HW acceleration only if |A| >= |B|. Since modular subtraction is used below,
+     * the result would be wrong if the real sum of operands exceeded maximum.
+     */
+    if ((sizeA <= sizeN) && (sizeB <= sizeN) && (mbedtls_mpi_cmp_abs(A, B) >= 0))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        ret = (int)LTC_PKHA_ModSub1(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = 1;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_sub_abs_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Perform HW acceleration only if |A| >= |B|. Since modular subtraction is used below,
+     * the result would be wrong if the real sum of operands exceeded maximum.
+     */
+    if ((sizeA <= sizeN) && (sizeB <= sizeN) && (mbedtls_mpi_cmp_abs(A, B) >= 0))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        ret = (int)CAAM_PKHA_ModSub1(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = 1;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_sub_abs_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_SUB_ABS_ALT */
+
+#if defined(MBEDTLS_MPI_MUL_MPI_ALT)
+
+/* Access to original version of mbedtls_mpi_mul_mpi function. */
+int mbedtls_mpi_mul_mpi_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Baseline multiplication: X = A * B  (HAC 14.12)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Should be "if ((sizeA + sizeB) <= sizeN)", but if the multiplication result
+     * would be maximum LTC number (the same value as the modulus N below),
+     * zero would be returned instead, which is wrong value.
+     */
+    if ((sizeA + sizeB) < sizeN)
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        int sign = A->s * B->s;
+
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        /*
+         * Modular multiplication operation is used here. Since the modulus N is larger
+         * than the expected result of A * B, the effect is normal multiplication.
+         * TODO use PKHA MUL_IM_OM instead.
+         */
+        ret =
+            (int)LTC_PKHA_ModMul(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC, kLTC_PKHA_IntegerArith,
+                                 kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = sign;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_mul_mpi_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Should be "if ((sizeA + sizeB) <= sizeN)", but if the multiplication result
+     * would be maximum CAAM number (the same value as the modulus N below),
+     * zero would be returned instead, which is wrong value.
+     */
+    if ((sizeA + sizeB) < sizeN)
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        int sign = A->s * B->s;
+
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        /*
+         * Modular multiplication operation is used here. Since the modulus N is larger
+         * than the expected result of A * B, the effect is normal multiplication.
+         * TODO use PKHA MUL_IM_OM instead.
+         */
+        ret = (int)CAAM_PKHA_ModMul(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith, kCAAM_PKHA_NormalValue, kCAAM_PKHA_NormalValue,
+                                    kCAAM_PKHA_TimingEqualized);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = sign;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_mul_mpi_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_MUL_MPI_ALT */
+
+#if defined(MBEDTLS_MPI_MOD_MPI_ALT)
+
+/* Access to original version of mbedtls_mpi_mod_mpi function. */
+int mbedtls_mpi_mod_mpi_orig(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Modulo: R = A mod B
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        int sign = A->s;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(R, ptrC, sizeC);
+        R->s = sign;
+
+        while (mbedtls_mpi_cmp_int(R, 0) < 0)
+            mbedtls_mpi_add_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); */
+
+        while (mbedtls_mpi_cmp_mpi(R, B) >= 0)
+            mbedtls_mpi_sub_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); cleanup:*/
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_mod_mpi_orig(R, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        int sign = A->s;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(R, ptrC, sizeC);
+        R->s = sign;
+
+        while (mbedtls_mpi_cmp_int(R, 0) < 0)
+            mbedtls_mpi_add_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); */
+
+        while (mbedtls_mpi_cmp_mpi(R, B) >= 0)
+            mbedtls_mpi_sub_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); cleanup:*/
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_mod_mpi_orig(R, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_MOD_MPI_ALT */
+
+#if defined(MBEDTLS_MPI_EXP_MOD_ALT)
+
+/* Access to original version of mbedtls_mpi_exp_mod function. */
+int mbedtls_mpi_exp_mod_orig(
+    mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR);
+
+/*
+ * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_exp_mod(
+    mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR)
+{
+    int ret;
+    pkha_size_t sizeE = mbedtls_mpi_size(E);
+    pkha_size_t sizeN = mbedtls_mpi_size(N);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeE <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif                   /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        mbedtls_mpi *AA; // TODO rename etc.
+
+        /*
+         * If number is greater than modulus, we must first reduce it due to LTC requirement
+         * on modular exponentiaton that it needs number less than modulus.
+         * We can take advantage of modular arithmetic rule that: A^B mod C = ( (A mod C)^B ) mod C.
+         * So we do (A mod N) first and if the size of A in bytes fits into LTC, it will be done in LTC
+         * (here LTC does not give size requirement on A versus N), otherwise it will be done in SW
+         * and since the size of N fits into LTC, the result of (A mod N) will also fit into LTC.
+         * Then we can do modular exponentiation in LTC.
+         */
+        if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
+        {
+            /* A >= N, perform X = (A mod N). */
+            ret = mbedtls_mpi_mod_mpi(X, A, N);
+
+            if (ret != kStatus_Success)
+                return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+            /* Exponenciation will be performed with X. */
+            AA = X;
+        }
+        else
+        {
+            /* Exponentiation will be performed with original A. */
+            AA = (mbedtls_mpi *)A;
+        }
+
+        pkha_size_t sizeA = mbedtls_mpi_size(AA);
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrE = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrN = ptrE + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(AA, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(E, ptrE, sizeE);
+        ltc_reverse_array(ptrE, sizeE);
+
+        mbedtls_mpi_write_binary(N, ptrN, sizeN);
+        ltc_reverse_array(ptrN, sizeN);
+
+        ret = (int)LTC_PKHA_ModExp(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrE, sizeE, ptrN, &sizeN,
+                                   kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrN, sizeN);
+        mbedtls_mpi_read_binary(X, ptrN, sizeN);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_exp_mod_orig(X, A, E, N, _RR);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_exp_mod(
+    mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR)
+{
+    int ret;
+    pkha_size_t sizeE = mbedtls_mpi_size(E);
+    pkha_size_t sizeN = mbedtls_mpi_size(N);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeE <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        mbedtls_mpi *AA; // TODO rename etc.
+
+        /*
+         * If number is greater than modulus, we must first reduce it due to CAAM requirement
+         * on modular exponentiaton that it needs number less than modulus.
+         * We can take advantage of modular arithmetic rule that: A^B mod C = ( (A mod C)^B ) mod C.
+         * So we do (A mod N) first and if the size of A in bytes fits into CAAM, it will be done in CAAM
+         * (here CAAM does not give size requirement on A versus N), otherwise it will be done in SW
+         * and since the size of N fits into CAAM, the result of (A mod N) will also fit into CAAM.
+         * Then we can do modular exponentiation in CAAM.
+         */
+        if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
+        {
+            /* A >= N, perform X = (A mod N). */
+            ret = mbedtls_mpi_mod_mpi(X, A, N);
+
+            if (ret != kStatus_Success)
+                return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+            /* Exponenciation will be performed with X. */
+            AA = X;
+        }
+        else
+        {
+            /* Exponentiation will be performed with original A. */
+            AA = (mbedtls_mpi *)A;
+        }
+
+        pkha_size_t sizeA = mbedtls_mpi_size(AA);
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrE = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrN = ptrE + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(AA, ptrA, sizeA);
+        mbedtls_mpi_write_binary(E, ptrE, sizeE);
+        mbedtls_mpi_write_binary(N, ptrN, sizeN);
+
+        ret = (int)CAAM_PKHA_ModExp(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrE, sizeE, ptrN, &sizeN,
+                                    kCAAM_PKHA_IntegerArith, kCAAM_PKHA_NormalValue, kCAAM_PKHA_TimingEqualized);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrN, sizeN);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_exp_mod_orig(X, A, E, N, _RR);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_EXP_MOD_ALT */
+
+#if defined(MBEDTLS_MPI_GCD_ALT)
+
+/* Access to original version of mbedtls_mpi_gcd function. */
+int mbedtls_mpi_gcd_orig(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        if (mbedtls_mpi_cmp_mpi(A, B) >= 0)
+        {
+            ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrA, &sizeA, kLTC_PKHA_IntegerArith);
+
+            if (ret != kStatus_Success)
+                CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        ret = (int)LTC_PKHA_GCD(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(G, ptrC, sizeC);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_gcd_orig(G, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        if (mbedtls_mpi_cmp_mpi(A, B) >= 0)
+        {
+            ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrA, &sizeA,
+                                        kCAAM_PKHA_IntegerArith);
+
+            if (ret != kStatus_Success)
+                CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        ret = (int)CAAM_PKHA_ModGcd(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(G, ptrC, sizeC);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_gcd_orig(G, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_GCD_ALT */
+
+#if defined(MBEDTLS_MPI_INV_MOD_ALT)
+
+/* Access to original version of mbedtls_mpi_inv_mod function. */
+int mbedtls_mpi_inv_mod_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N);
+
+/*
+ * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeN = mbedtls_mpi_size(N);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrN + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        /* N cannot be negative */
+        if (N->s < 0 || mbedtls_mpi_cmp_int(N, 0) == 0)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(N, ptrN, sizeN);
+        ltc_reverse_array(ptrN, sizeN);
+
+        if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
+        {
+            ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrA, &sizeA, kLTC_PKHA_IntegerArith);
+
+            if (ret != kStatus_Success)
+                CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        ret = (int)LTC_PKHA_ModInv(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrC, &sizeC, kLTC_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_inv_mod_orig(X, A, N);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeN = mbedtls_mpi_size(N);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrN + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        /* N cannot be negative */
+        if (N->s < 0 || mbedtls_mpi_cmp_int(N, 0) == 0)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(N, ptrN, sizeN);
+
+        if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
+        {
+            ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrA, &sizeA,
+                                        kCAAM_PKHA_IntegerArith);
+
+            if (ret != kStatus_Success)
+                CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        ret = (int)CAAM_PKHA_ModInv(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_inv_mod_orig(X, A, N);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_INV_MOD_ALT */
+
+#if defined(MBEDTLS_MPI_IS_PRIME_ALT)
+
+/* Access to original version of mbedtls_mpi_is_prime function. */
+int mbedtls_mpi_is_prime_orig(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+
+/*
+ * Pseudo-primality test: small factors, then Miller-Rabin
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_is_prime(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
+{
+    pkha_size_t sizeX = mbedtls_mpi_size(X);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if (sizeX <= FREESCALE_PKHA_INT_MAX_BYTES)
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        int random;
+        bool result = false;
+        uint8_t *ptrX = mbedtls_calloc(1, FREESCALE_PKHA_INT_MAX_BYTES);
+        if (NULL == ptrX)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(X, ptrX, FREESCALE_PKHA_INT_MAX_BYTES);
+        ltc_reverse_array(ptrX, FREESCALE_PKHA_INT_MAX_BYTES);
+
+        // Get the random seed number
+        f_rng(p_rng, (unsigned char *)(&random), sizeof(random));
+
+        ret = (int)LTC_PKHA_PrimalityTest(LTC_INSTANCE, (unsigned char *)&random, sizeof(random), (const uint8_t *)"1",
+                                          1u, ptrX, sizeX, &result);
+
+        if (ret != kStatus_Success)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        if (result == false)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+    cleanup:
+        if (ptrX)
+        {
+            mbedtls_free(ptrX);
+        }
+        return ret;
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_is_prime_orig(X, f_rng, p_rng);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_is_prime(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
+{
+    pkha_size_t sizeX = mbedtls_mpi_size(X);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if (sizeX <= FREESCALE_PKHA_INT_MAX_BYTES)
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        int random;
+        bool result = false;
+        uint8_t *ptrX = mbedtls_calloc(1, FREESCALE_PKHA_INT_MAX_BYTES);
+        if (NULL == ptrX)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(X, ptrX, FREESCALE_PKHA_INT_MAX_BYTES);
+
+        // Get the random seed number
+        f_rng(p_rng, (unsigned char *)(&random), sizeof(random));
+
+        ret = (int)CAAM_PKHA_PrimalityTest(CAAM_INSTANCE, &s_caamHandle, (unsigned char *)&random, sizeof(random),
+                                           (const uint8_t *)"1", 1u, ptrX, sizeX, &result);
+
+        if (ret != kStatus_Success)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        if (result == false)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+    cleanup:
+        if (ptrX)
+        {
+            mbedtls_free(ptrX);
+        }
+        return ret;
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_is_prime_orig(X, f_rng, p_rng);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_IS_PRIME_ALT */
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_ECP_C)
+
+#include "mbedtls/ecp.h"
+
+#define LTC_MAX_ECC (512)
+#define CAAM_MAX_ECC (528)
+#define CAU3_MAX_ECC (512)
+
+typedef enum
+{
+    kBigEndian = 0U,
+    kLittleEndian = 1U
+} endian_t;
+
+/* convert from mbedtls_mpi to LTC or CAAM integer, as array of bytes of size sz.
+ * if mbedtls_mpi has less bytes than sz, add zero bytes at most significant byte positions.
+ * This is when for example modulus is 32 bytes (P-256 curve)
+ * and mbedtls_mpi has only 31 bytes, we add leading zeroes
+ * so that result array has 32 bytes, same as modulus (sz).
+ */
+#if defined(MBEDTLS_ECP_MUL_COMB_ALT) || defined(MBEDTLS_ECP_ADD_ALT)
+static int get_and_extend_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz, endian_t endian)
+{
+    size_t szbin;
+    int offset;
+    int ret;
+
+    /* check how many bytes are in the mbedtls_mpi */
+    szbin = mbedtls_mpi_size(a);
+
+    /* compute offset from dst */
+    offset = sz - szbin;
+    if (offset < 0)
+        offset = 0;
+    if (offset > sz)
+        offset = sz;
+
+    /* add leading zeroes */
+    if (offset)
+        memset(dst, 0, offset);
+
+    /* convert mbedtls_mpi to array of bytes */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(a, dst + offset, szbin));
+
+    /* reverse array for LTC direct use */
+    if (endian == kLittleEndian)
+        ltc_reverse_array(dst, sz);
+cleanup:
+    return (ret);
+}
+
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+static int ltc_get_from_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz)
+{
+    return get_and_extend_mbedtls_mpi(dst, a, sz, kLittleEndian);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+static int caam_get_from_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz)
+{
+    return get_and_extend_mbedtls_mpi(dst, a, sz, kBigEndian);
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA */
+#endif /* MBEDTLS_ECP_MUL_COMB_ALT || MBEDTLS_ECP_ADD_ALT */
+
+/*
+ * Multiplication using the comb method,
+ * for curves in short Weierstrass form
+ */
+#if defined(MBEDTLS_ECP_MUL_COMB_ALT)
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA)
+int ecp_mul_comb(mbedtls_ecp_group *grp,
+                 mbedtls_ecp_point *R,
+                 const mbedtls_mpi *m,
+                 const mbedtls_ecp_point *P,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng)
+{
+    int ret;
+    bool is_inf;
+    size_t size;
+    size_t size_bin;
+    int sign = m->s;
+
+    ltc_pkha_ecc_point_t A;
+    ltc_pkha_ecc_point_t result;
+
+    /* Allocate 7 elements with size of (LTC_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */
+    uint8_t *ptrAX = mbedtls_calloc((7 * (LTC_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1);
+    uint8_t *ptrAY = ptrAX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrAY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (LTC_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (LTC_MAX_ECC / 8);
+    uint8_t *ptrE = ptrParamB + (LTC_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (LTC_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(ptrParamA, &grp->A, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(ptrParamB, &grp->B, size));
+
+    /* scalar multiplier integer of any size */
+    size_bin = mbedtls_mpi_size(m);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin));
+    ltc_reverse_array(ptrE, size_bin);
+
+    /* modulus */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+    ltc_reverse_array(ptrN, size);
+
+    /* Multiply */
+    LTC_PKHA_ECC_PointMul(LTC_INSTANCE, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size,
+                          kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, &result, &is_inf);
+    /* Convert result */
+    ltc_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    ltc_reverse_array(ptrRY, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    /* if the integer multiplier is negative, the computation happens with abs() value
+     * and the result (x,y) is changed to (x, -y)
+     */
+    R->Y.s = sign;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int ecp_mul_comb(mbedtls_ecp_group *grp,
+                 mbedtls_ecp_point *R,
+                 const mbedtls_mpi *m,
+                 const mbedtls_ecp_point *P,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng)
+{
+    int ret;
+    size_t size;
+    size_t size_bin;
+    int sign = m->s;
+
+    caam_pkha_ecc_point_t A;
+    caam_pkha_ecc_point_t result;
+
+    /* Allocate 7 elements with size of (CAAM_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */
+    uint8_t *ptrAX = mbedtls_calloc((7 * (CAAM_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1);
+    uint8_t *ptrAY = ptrAX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrAY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrE = ptrParamB + (CAAM_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(ptrParamA, &grp->A, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(ptrParamB, &grp->B, size));
+
+    /* scalar multiplier integer of any size */
+    size_bin = mbedtls_mpi_size(m);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin));
+
+    /* modulus */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+
+    /* Multiply */
+    CAAM_PKHA_ECC_PointMul(CAAM_INSTANCE, &s_caamHandle, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size,
+                           kCAAM_PKHA_TimingEqualized, kCAAM_PKHA_IntegerArith, &result);
+    /* Convert result */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    /* if the integer multiplier is negative, the computation happens with abs() value
+     * and the result (x,y) is changed to (x, -y)
+     */
+    R->Y.s = sign;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int ecp_mul_comb(mbedtls_ecp_group *grp,
+                 mbedtls_ecp_point *R,
+                 const mbedtls_mpi *m,
+                 const mbedtls_ecp_point *P,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng)
+{
+    int ret;
+    status_t status;
+    size_t size;
+    size_t size_bin;
+    int sign = m->s;
+
+    cau3_pkha_ecc_point_t A;
+    cau3_pkha_ecc_point_t result;
+
+    /* Allocate 7 elements with size of (CAU3_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */
+    uint8_t *ptrAX = mbedtls_calloc((7 * (CAU3_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1);
+    uint8_t *ptrAY = ptrAX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrAY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrE = ptrParamB + (CAU3_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAU3_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(ptrParamA, &grp->A, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(ptrParamB, &grp->B, size));
+
+    /* scalar multiplier integer of any size */
+    size_bin = mbedtls_mpi_size(m);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin));
+    cau3_reverse_array(ptrE, size_bin);
+
+    /* modulus */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+    cau3_reverse_array(ptrN, size);
+
+    /* Multiply */
+    status = CAU3_PKHA_ECC_PointMul(CAU3, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size,
+                                    kCAU3_PKHA_TimingEqualized, kCAU3_PKHA_IntegerArith, &result);
+
+    if (status != kStatus_Success)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert result */
+    cau3_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    cau3_reverse_array(ptrRY, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    /* if the integer multiplier is negative, the computation happens with abs() value
+     * and the result (x,y) is changed to (x, -y)
+     */
+    R->Y.s = sign;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA */
+#endif /* MBEDTLS_ECP_MUL_COMB_ALT */
+
+/*
+ * Curve types: internal for now, might be exposed later
+ */
+typedef enum
+{
+    ECP_TYPE_NONE = 0,
+    ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b      */
+    ECP_TYPE_MONTGOMERY,        /* y^2 = x^3 + a x^2 + x    */
+} ecp_curve_type;
+/*
+ * Get the type of a curve
+ */
+static inline ecp_curve_type ecp_get_type(const mbedtls_ecp_group *grp)
+{
+    if (grp->G.X.p == NULL)
+        return (ECP_TYPE_NONE);
+
+    if (grp->G.Y.p == NULL)
+        return (ECP_TYPE_MONTGOMERY);
+    else
+        return (ECP_TYPE_SHORT_WEIERSTRASS);
+}
+
+/*
+ * Addition: R = P + Q, result's coordinates normalized
+ */
+#if defined(MBEDTLS_ECP_ADD_ALT)
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA)
+int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q)
+{
+    int ret;
+    size_t size;
+    ltc_pkha_ecc_point_t A;
+    ltc_pkha_ecc_point_t B;
+    ltc_pkha_ecc_point_t result;
+
+    uint8_t *ptrAX = mbedtls_calloc(9, (LTC_MAX_ECC / 8));
+    uint8_t *ptrAY = ptrAX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrBX = ptrAY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrBY = ptrBX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrBY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (LTC_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (LTC_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS)
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE);
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    B.X = ptrBX;
+    B.Y = ptrBY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (LTC_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(B.X, &Q->X, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(B.Y, &Q->Y, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+    ltc_reverse_array(ptrN, size);
+    /* Multiply */
+    LTC_PKHA_ECC_PointAdd(LTC_INSTANCE, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size, kLTC_PKHA_IntegerArith,
+                          &result);
+    /* Convert result */
+    ltc_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    ltc_reverse_array(ptrRY, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    R->X.s = P->X.s;
+    R->Y.s = P->Y.s;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q)
+{
+    int ret;
+    size_t size;
+    caam_pkha_ecc_point_t A;
+    caam_pkha_ecc_point_t B;
+    caam_pkha_ecc_point_t result;
+
+    uint8_t *ptrAX = mbedtls_calloc(9, (CAAM_MAX_ECC / 8));
+    uint8_t *ptrAY = ptrAX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrBX = ptrAY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrBY = ptrBX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrBY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (CAAM_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS)
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE);
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    B.X = ptrBX;
+    B.Y = ptrBY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(B.X, &Q->X, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(B.Y, &Q->Y, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+
+    /* Multiply */
+    CAAM_PKHA_ECC_PointAdd(CAAM_INSTANCE, &s_caamHandle, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size,
+                           kCAAM_PKHA_IntegerArith, &result);
+    /* Convert result */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    R->X.s = P->X.s;
+    R->Y.s = P->Y.s;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q)
+{
+    int ret;
+    status_t status;
+    size_t size;
+    cau3_pkha_ecc_point_t A;
+    cau3_pkha_ecc_point_t B;
+    cau3_pkha_ecc_point_t result;
+
+    uint8_t *ptrAX = mbedtls_calloc(9, (CAU3_MAX_ECC / 8));
+    uint8_t *ptrAY = ptrAX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrBX = ptrAY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrBY = ptrBX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrBY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (CAU3_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS)
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE);
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    B.X = ptrBX;
+    B.Y = ptrBY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAU3_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(B.X, &Q->X, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(B.Y, &Q->Y, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+    cau3_reverse_array(ptrN, size);
+    /* Multiply */
+    status =
+        CAU3_PKHA_ECC_PointAdd(CAU3, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size, kCAU3_PKHA_IntegerArith, &result);
+
+    if (status != kStatus_Success)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert result */
+    cau3_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    cau3_reverse_array(ptrRY, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    R->X.s = P->X.s;
+    R->Y.s = P->Y.s;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA */
+
+#endif /* MBEDTLS_ECP_ADD_ALT */
+
+#if defined(MBEDTLS_ECP_MUL_MXZ_ALT)
+#if defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+
+/* curve25519 params - in little endian for CAU3 */
+static const uint8_t s_curve25519_A24[] = {0x42, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const uint8_t s_curve25519_N[] = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
+
+static const uint8_t s_curve25519_R2modN[] = {0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+int ecp_mul_mxz(mbedtls_ecp_group *grp,
+                mbedtls_ecp_point *R,
+                const mbedtls_mpi *m,
+                const mbedtls_ecp_point *P,
+                int (*f_rng)(void *, unsigned char *, size_t),
+                void *p_rng)
+{
+    int ret;
+    status_t status;
+    size_t size;
+    size_t size_bin;
+
+    cau3_pkha_ecc_point_t A;
+    cau3_pkha_ecc_point_t result;
+
+    /* Allocate 2 elements with size of (CAU3_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */
+    uint8_t *ptrAX = mbedtls_calloc((2 * (CAU3_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1);
+    uint8_t *ptrRX = ptrAX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrE = ptrRX + (CAU3_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    A.X = ptrAX;
+    result.X = ptrRX;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size));
+
+    /* scalar multiplier integer of any size */
+    size_bin = mbedtls_mpi_size(m);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin));
+    cau3_reverse_array(ptrE, size_bin);
+
+    /* Multiply */
+    status = CAU3_PKHA_ECM_PointMul(CAU3, ptrE, size_bin, A.X, s_curve25519_A24, s_curve25519_N, s_curve25519_R2modN,
+                                    size, kCAU3_PKHA_TimingEqualized, result.X);
+
+    if (status != kStatus_Success)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert result */
+    cau3_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#endif /* MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_ECP_MUL_MXZ_ALT */
+
+#endif /* MBEDTLS_ECP_C */
+
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA */
+
+#if defined(MBEDTLS_RSA_PUBLIC_ALT)
+#if defined(MBEDTLS_FREESCALE_CASPER_PKHA)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#include "mbedtls/bignum.h"
+#include "mbedtls/rsa.h"
+
+static void reverse_array(uint8_t *src, size_t src_len)
+{
+    int i;
+
+    for (i = 0; i < src_len / 2; i++)
+    {
+        uint8_t tmp;
+
+        tmp = src[i];
+        src[i] = src[src_len - 1 - i];
+        src[src_len - 1 - i] = tmp;
+    }
+}
+/*
+ * Do an RSA public key operation
+ */
+static int mbedtls_mpi_exp_mod_shim(mbedtls_mpi *X,
+                                    const mbedtls_mpi *A,
+                                    const mbedtls_mpi *E,
+                                    const mbedtls_mpi *N /*, mbedtls_mpi *_RR */)
+{
+    int ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
+    size_t sizeA = mbedtls_mpi_size(A);
+    size_t sizeN = mbedtls_mpi_size(N);
+    uint8_t *ptrX = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+    uint8_t *ptrA = ptrX + FREESCALE_PKHA_INT_MAX_BYTES;
+    uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+
+    if (NULL == ptrX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(A, ptrA, sizeA));
+    reverse_array(ptrA, sizeA);
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(N, ptrN, sizeN));
+    reverse_array(ptrN, sizeN);
+
+    CASPER_ModExp(CASPER, ptrA, ptrN, sizeN / 4, E->p[0], ptrX);
+
+    reverse_array(ptrX, sizeN);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(X, ptrX, sizeN));
+cleanup:
+    if (ptrX != NULL)
+    {
+        mbedtls_free(ptrX);
+    }
+
+    return ret;
+}
+
+int mbedtls_rsa_public(mbedtls_rsa_context *ctx, const unsigned char *input, unsigned char *output)
+{
+    int ret;
+    size_t olen;
+    mbedtls_mpi T;
+
+    mbedtls_mpi_init(&T);
+
+#if defined(MBEDTLS_THREADING_C)
+    if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0)
+        return (ret);
+#endif
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len));
+
+    if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0)
+    {
+        ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    olen = ctx->len;
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod_shim(&T, &T, &ctx->E, &ctx->N /*, &ctx->RN */));
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
+
+cleanup:
+#if defined(MBEDTLS_THREADING_C)
+    if (mbedtls_mutex_unlock(&ctx->mutex) != 0)
+        return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
+#endif
+
+    mbedtls_mpi_free(&T);
+
+    if (ret != 0)
+        return (MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret);
+
+    return (0);
+}
+
+#endif /* MBEDTLS_FREESCALE_CASPER_PKHA */
+#endif /* MBEDTLS_RSA_PUBLIC_ALT */
+
+/******************************************************************************/
+/*************************** MD5 **********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_MD5_C)
+
+#if defined(MBEDTLS_FREESCALE_MMCAU_MD5)
+
+#include "mbedtls/md5.h"
+
+int mbedtls_internal_md5_process(mbedtls_md5_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = MMCAU_MD5_HashN(data, 1, ctx->state);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_MD5_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#endif /* MBEDTLS_FREESCALE_MMCAU_MD5 */
+
+#endif /* MBEDTLS_MD5_C */
+
+/******************************************************************************/
+/*************************** SHA1 *********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_SHA1_C)
+
+#if defined(MBEDTLS_FREESCALE_LTC_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha1, NULL, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Update(ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Update(ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Finish(ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_MMCAU_SHA1)
+
+#include "mbedtls/sha1.h"
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = MMCAU_SHA1_HashN(data, 1, ctx->state);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_LPC_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Init(SHA_INSTANCE, ctx, kSHA_Sha1);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Update(SHA_INSTANCE, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Update(SHA_INSTANCE, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    size_t outputSize = 20u;
+    status_t ret = kStatus_Fail;
+    ret = SHA_Finish(SHA_INSTANCE, ctx, output, &outputSize);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha1, NULL, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Update(ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Update(ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Finish(ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Init(CAU3, ctx, kCAU3_Sha1);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Update(CAU3, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Update(CAU3, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Finish(CAU3, ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_DCP_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Init(DCP, &s_dcpHandle, ctx, kDCP_Sha1);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Update(DCP, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Update(DCP, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Finish(DCP, ctx, output, NULL);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Init(HASHCRYPT, ctx, kHASHCRYPT_Sha1);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    size_t outputSize = 20;
+    ret = HASHCRYPT_SHA_Finish(HASHCRYPT, ctx, output, &outputSize);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+#endif /* MBEDTLS_FREESCALE_LPC_SHA1 */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SHA1_ALT)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_starts(mbedtls_sha1_context *ctx)
+{
+    mbedtls_sha1_starts_ret(ctx);
+}
+
+void mbedtls_sha1_update(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    mbedtls_sha1_update_ret(ctx, input, ilen);
+}
+
+void mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    mbedtls_sha1_finish_ret(ctx, output);
+}
+
+void mbedtls_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    mbedtls_internal_sha1_process(ctx, data);
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_SHA1_C */
+
+/******************************************************************************/
+/*************************** SHA256********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_SHA256_C)
+
+#if defined(MBEDTLS_FREESCALE_LTC_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (is224)
+    {
+        ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha224, NULL, 0);
+    }
+    else
+    {
+        ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha256, NULL, 0);
+    }
+
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Update(ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Update(ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Finish(ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_MMCAU_SHA256)
+
+#include "mbedtls/sha256.h"
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = MMCAU_SHA256_HashN(data, 1, ctx->state);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_SHA256)
+
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (!is224) /* SHA-224 not supported at the moment */
+    {
+        ret = CAU3_HASH_Init(CAU3, ctx, kCAU3_Sha256);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Update(CAU3, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Update(CAU3, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Finish(CAU3, ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_LPC_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (!is224) /* SHA-224 not supported */
+    {
+        ret = SHA_Init(SHA_INSTANCE, ctx, kSHA_Sha256);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Update(SHA_INSTANCE, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Update(SHA_INSTANCE, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    size_t outputSize = 32u;
+    status_t ret = kStatus_Fail;
+    ret = SHA_Finish(SHA_INSTANCE, ctx, output, &outputSize);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (is224)
+    {
+        ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha224, NULL, 0);
+    }
+    else
+    {
+        ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha256, NULL, 0);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Update(ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Update(ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Finish(ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_DCP_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (!is224)
+    {
+        ret = DCP_HASH_Init(DCP, &s_dcpHandle, ctx, kDCP_Sha256);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Update(DCP, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Update(DCP, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Finish(DCP, ctx, output, NULL);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (!is224) /* SHA-224 not supported */
+    {
+        ret = HASHCRYPT_SHA_Init(HASHCRYPT, ctx, kHASHCRYPT_Sha256);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    size_t outputSize = 32;
+    ret = HASHCRYPT_SHA_Finish(HASHCRYPT, ctx, output, &outputSize);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+#endif /* MBEDTLS_FREESCALE_LTC_SHA256 */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SHA256_ALT)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
+{
+    mbedtls_sha256_starts_ret(ctx, is224);
+}
+
+void mbedtls_sha256_update(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    mbedtls_sha256_update_ret(ctx, input, ilen);
+}
+
+void mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    mbedtls_sha256_finish_ret(ctx, output);
+}
+
+void mbedtls_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    mbedtls_internal_sha256_process(ctx, data);
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_SHA256_C */
+
+/* Entropy poll callback for a hardware source */
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+
+#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+#if defined CPU_JN518X
+    #include "fsl_rng.h"
+#else
+    #include "fsl_trng.h"
+#endif
+#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+#include "fsl_rnga.h"
+#elif defined(FSL_FEATURE_SOC_LPC_RNG_COUNT) && (FSL_FEATURE_SOC_LPC_RNG_COUNT > 0)
+#include "fsl_rng.h"
+#elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0)
+#include "fsl_rng.h"
+#endif
+
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen)
+{
+    status_t result = kStatus_Success;
+
+#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+#if defined CPU_JN518X
+    #ifndef TRNG0
+    #define TRNG0 RNG
+    #endif
+#else
+    #ifndef TRNG0
+    #define TRNG0 TRNG
+    #endif
+#endif
+    result = TRNG_GetRandomData(TRNG0, output, len);
+#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+    result = RNGA_GetRandomData(RNG, (void *)output, len);
+#elif defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM)
+    result = CAAM_RNG_GetRandomData(CAAM_INSTANCE, &s_caamHandle, kCAAM_RngStateHandle0, output, len, kCAAM_RngDataAny,
+                                    NULL);
+#elif defined(FSL_FEATURE_SOC_LPC_RNG_COUNT) && (FSL_FEATURE_SOC_LPC_RNG_COUNT > 0)
+    uint32_t rn;
+    size_t length;
+    int i;
+
+    length = len;
+
+    while (length > 0)
+    {
+        rn = RNG_GetRandomData();
+
+        if (length >= sizeof(uint32_t))
+        {
+            memcpy(output, &rn, sizeof(uint32_t));
+            length -= sizeof(uint32_t);
+            output += sizeof(uint32_t);
+        }
+        else
+        {
+            memcpy(output, &rn, length);
+            output += length;
+            len = 0U;
+        }
+
+        /* Discard next 32 random words for better entropy */
+        for (i = 0; i < 32; i++)
+        {
+            RNG_GetRandomData();
+        }
+    }
+
+    result = kStatus_Success;
+#elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0)
+    status_t status = kStatus_Fail;
+
+    while(status != kStatus_Success)
+    {
+        status = RNG_GetRandomData(RNG, output, len);
+
+        if(status == kStatus_Fail)
+        {
+            RNG_Init(RNG);
+        }
+    }
+
+    result = status;
+#endif
+    if (result == kStatus_Success)
+    {
+        *olen = len;
+        return 0;
+    }
+    else
+    {
+        return result;
+    }
+}
+
+#endif
+
+/******************************************************************************/
+/*************************** FreeRTOS ********************************************/
+/******************************************************************************/
+#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) && defined(MBEDTLS_FREESCALE_FREERTOS_CALLOC_ALT)
+#include <stdlib.h>
+#include "FreeRTOS.h"
+#include "task.h"
+
+/*---------HEAP_3 calloc --------------------------------------------------*/
+
+void *pvPortCalloc(size_t num, size_t size)
+{
+    void *pvReturn;
+
+    vTaskSuspendAll();
+    {
+        pvReturn = calloc(num, size);
+        traceMALLOC(pvReturn, xWantedSize);
+    }
+    (void)xTaskResumeAll();
+
+#if (configUSE_MALLOC_FAILED_HOOK == 1)
+    {
+        if (pvReturn == NULL)
+        {
+            extern void vApplicationMallocFailedHook(void);
+            vApplicationMallocFailedHook();
+        }
+    }
+#endif
+
+    return pvReturn;
+}
+#endif /* USE_RTOS && defined(FSL_RTOS_FREE_RTOS) && defined(MBEDTLS_FREESCALE_FREERTOS_CALLOC_ALT) */
diff --git a/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.h b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.h
new file mode 100755
index 0000000..cb545c5
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * 
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+ 
+#ifndef KSDK_MBEDTLS_H
+#define KSDK_MBEDTLS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int fsl_mbedtls_printf(const char *fmt_s, ...);
+void CRYPTO_InitHardware(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* KSDK_MBEDTLS_H */
diff --git a/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/sha1_alt.h b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/sha1_alt.h
new file mode 100755
index 0000000..76d0883
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/sha1_alt.h
@@ -0,0 +1,79 @@
+/**
+ * \file mbedtls_alt_sha1.h
+ *
+ * \brief SHA-1 cryptographic hash function
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *  Copyright 2017 NXP. Not a Contribution
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SHA1_ALT_H
+#define MBEDTLS_SHA1_ALT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context ltc_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_LPC_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context sha_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context caam_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context cau3_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_DCP_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context dcp_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context hashcrypt_hash_ctx_t
+
+#endif /* MBEDTLS_FREESCALE_LTC_SHA1 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_SHA1_ALT_H */
diff --git a/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/sha256_alt.h b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/sha256_alt.h
new file mode 100755
index 0000000..2fe0148
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/mbedtls/port/ksdk/sha256_alt.h
@@ -0,0 +1,82 @@
+/**
+ * \file mbedtls_sha256.h
+ *
+ * \brief SHA-224 and SHA-256 cryptographic hash function
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *  Copyright 2017 NXP. Not a Contribution
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SHA256_ALT_H
+#define MBEDTLS_SHA256_ALT_H
+
+// Regular implementation
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context ltc_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_LPC_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context sha_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context caam_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context cau3_hash_ctx_t  
+
+#elif defined(MBEDTLS_FREESCALE_DCP_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context dcp_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context hashcrypt_hash_ctx_t
+
+#endif /* MBEDTLS_FREESCALE_LTC_SHA256 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha256_alt.h */
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroInt_arm_sdk2.c b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroInt_arm_sdk2.c
new file mode 100755
index 0000000..c6d0ab5
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroInt_arm_sdk2.c
@@ -0,0 +1,233 @@
+/*****************************************************************************
+ *
+ * MODULE:             Microspecific
+ *
+ * COMPONENT:          Microspecific
+ *
+ * AUTHOR:             Wayne Ellis
+ *
+ * DESCRIPTION:        JN517x Microspecific Interrupt Controller Code
+ *
+ * $HeadURL:  $
+ *
+ * $Revision:  $
+ *
+ * $LastChangedBy: we1 $
+ *
+ * $LastChangedDate:  $
+ *
+ * $Id:  $
+ *
+ *****************************************************************************
+ *
+ * This software is owned by Jennic and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on Jennic products. You, and any third parties must reproduce
+ * the copyright and warranty notice and any other legend of ownership on each
+ * copy or partial copy of the software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". JENNIC MAKES NO WARRANTIES, WHETHER
+ * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * ACCURACY OR LACK OF NEGLIGENCE. JENNIC SHALL NOT, IN ANY CIRCUMSTANCES,
+ * BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, SPECIAL,
+ * INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON WHATSOEVER.
+ *
+ * Copyright Jennic Ltd. 2014 All rights reserved
+ *
+ ****************************************************************************/
+
+/****************************************************************************/
+/***        Include files                                                 ***/
+/****************************************************************************/
+#include "jendefs.h"
+
+#include "MicroSpecific.h"
+//#include "jn518x.h"
+//#include "PeripheralRegs.h"
+//#include <ARMcortexM3Registers_JN51xx.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+// PreEmpt Priority field is [7:5]
+#define PREEMPT_PRIORITY_FIELD          (4)
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Local Function Prototypes                                     ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Local Variables                                               ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+#if 0
+/****************************************************************************
+ * NAME:        vAHI_InitialiseInterruptController
+ *
+ * DESCRIPTION:
+ * Initialise ARM NVIC.
+ *
+ * RETURNS:
+ * Nothing.
+ *
+ * NOTES:
+ *
+ ****************************************************************************/
+
+PUBLIC void vAHI_InitialiseInterruptController(
+            uint32 *pu32InterruptVectorTable)
+{
+    uint32 u32RegisterValue=0;
+
+    // set application interrupt and reset control register
+
+    // write vector key
+    U32_SET_BITS(&u32RegisterValue, REG_APP_INT_RESET_CTRL_VECTKEY);
+    // set priority group
+    U32_SET_BITS(&u32RegisterValue, PREEMPT_PRIORITY_FIELD << REG_APP_INT_RESET_CTRL_PRIGROUP_BIT);
+
+    vREG_Write(REG_APP_INT_RESET_CTRL, u32RegisterValue);
+
+    // set vector table location
+    u32RegisterValue=0;
+
+    // table in RAM - this bit isn't required in the JN5172 at all
+    // U32_SET_BITS(&u32RegisterValue, 1 << REG_INT_VECTOR_TABLE_OFFSET_TBLBASE_BIT);
+
+    // table address
+    U32_SET_BITS(&u32RegisterValue, (uint32)pu32InterruptVectorTable);
+    vREG_Write(REG_INT_VECTOR_TABLE_OFFSET, u32RegisterValue);
+
+    // enable exception features - DIV0 and align errors
+    u32RegisterValue=0;
+
+    U32_SET_BITS(
+       &u32RegisterValue,
+    /*    REG_CONFIGURATION_CONTROL_UNALIGN_TRP_MASK | */REG_CONFIGURATION_CONTROL_DIV_0_TRP_MASK);
+
+    vREG_Write(REG_CONFIGURATION_CONTROL, u32RegisterValue);
+
+    // set the exception priorities here - benign but listed so we know where they are
+    // MemManage
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_4, 0);
+    // BusFault
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_5, 0);
+    // UsageFault
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_6, 0);
+    // SVC
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_11, 0);
+    // debug monitor
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_12, 0);
+    // pend SV
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_14, 0);
+    // SYSTICK
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_15, MICRO_INTERRUPT_WRITE_PRIORITY_VALUE(MICRO_JENNIC_TO_ARM_PRIORITY_MAP(8)));
+
+    u32RegisterValue=0;
+    U32_SET_BITS(
+       &u32RegisterValue,
+       REG_SYSTEM_HANDLER_CNTRL_STATE_USGFAULTEN_MASK | REG_SYSTEM_HANDLER_CNTRL_STATE_BUSFAULTEN_MASK | REG_SYSTEM_HANDLER_CNTRL_STATE_MEMFAULTEN_MASK);
+    vREG_Write(REG_SYSTEM_HANDLER_CNTRL_STATE, u32RegisterValue);
+
+}
+#endif
+
+#if 0
+/****************************************************************************
+ * NAME:        vMicroIntSetGlobalEnable
+ *
+ * DESCRIPTION:
+ * Enable specified interrupts.
+ *
+ * RETURNS:
+ * Nothing.
+ *
+ * NOTES:
+ *
+ ****************************************************************************/
+
+PUBLIC void vMicroIntSetGlobalEnable(
+        uint32      u32EnableMask)
+{
+    // all API's work with the old BA stack numbers, appropriate translations
+    // occur within the call
+    vAHI_InterruptSetPriority(u32EnableMask, 12);
+}
+#endif
+
+/****************************************************************************
+ * NAME:        vMicroIntEnableOnly
+ *
+ * DESCRIPTION:
+ * Enable specified interrupt.
+ *
+ * RETURNS:
+ * Nothing.
+ *
+ * NOTES:
+ *
+ ****************************************************************************/
+
+PUBLIC void vMicroIntEnableOnly(
+        tsMicroIntStorage      *psIntStorage,
+        uint32                  u32EnableMask)
+{
+    uint32 u32Store;
+
+    /* Not used in this implementation */
+    VARIABLE_INTENTIONALLY_NOT_REFERENCED(u32EnableMask)
+
+    /* Disable interrupts for duration of this function */
+#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
+    /* unroll MICRO_DISABLE_AND_SAVE_INTERRUPTS macro content becasue IAR < 8.40 fails to see u32Store is set */
+    u32Store = __get_PRIMASK();
+    __disable_irq();
+#else
+    MICRO_DISABLE_AND_SAVE_INTERRUPTS(u32Store);
+#endif
+    /* Store old priority level */
+    psIntStorage->u8Level = MICRO_GET_ACTIVE_INT_LEVEL();
+
+    /* Update priority level, but only if it is a more restrictive value */
+    MICRO_SET_ACTIVE_INT_LEVEL_MAX(MICRO_INTERRUPT_WRITE_PRIORITY_VALUE(3));
+
+    /* Restore interrupts */
+    MICRO_RESTORE_INTERRUPTS(u32Store);
+}
+
+/****************************************************************************
+ * NAME:        vMicroIntRestoreState
+ *
+ * DESCRIPTION:
+ * Restore Previous Interrupt State.
+ *
+ * RETURNS:
+ * Nothing.
+ *
+ * NOTES:
+ *
+ ****************************************************************************/
+
+PUBLIC void vMicroIntRestoreState(
+        tsMicroIntStorage      *psIntStorage)
+{
+    // write value direct into register ARM to ARM, no translations required
+    MICRO_SET_ACTIVE_INT_LEVEL(psIntStorage->u8Level);
+}
+
+/****************************************************************************/
+/***        End of file                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific.h b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific.h
new file mode 100755
index 0000000..ff8a0fb
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific.h
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ *
+ * MODULE:              Definitions specific to a particular processor
+ *
+ * DESCRIPTION:
+ * Definitions for a specific processor, i.e. functions that can only be
+ * resolved by op codes
+ *
+ ****************************************************************************
+ *
+ * This software is owned by NXP B.V. and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142, JN5139].
+ * You, and any third parties must reproduce the copyright and warranty notice
+ * and any other legend of ownership on each copy or partial copy of the
+ * software.
+ *
+ * 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.
+ *
+ * Copyright NXP B.V. 2012. All rights reserved
+ *
+ ***************************************************************************/
+
+/****************************************************************************/
+/***        Include files                                                 ***/
+/****************************************************************************/
+
+#define EXPAND1(x) x
+#define EXPAND2(x, y)    EXPAND1(x)y
+#define EXPAND3(x, y, z) EXPAND2(x, y)z
+
+/* Convoluted way to #include <MicroSpecific_JN51xx.h> */
+#undef INCLUDE_NAME
+#define INCLUDE_NAME <EXPAND3(MicroSpecific,JENNIC_CHIP_FAMILY_NAME,.h)>
+#include INCLUDE_NAME
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
+
+
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific_JN518x.h b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific_JN518x.h
new file mode 100755
index 0000000..596fae7
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific_JN518x.h
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ *
+ * MODULE:              Definitions specific to a particular processor
+ *
+ * DESCRIPTION:
+ * Definitions for a specific processor, i.e. functions that can only be
+ * resolved by op codes
+ *
+ ****************************************************************************
+ *
+ * This software is owned by NXP B.V. and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142, JN5139].
+ * You, and any third parties must reproduce the copyright and warranty notice
+ * and any other legend of ownership on each copy or partial copy of the
+ * software.
+ *
+ * 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.
+ *
+ * Copyright NXP B.V. 2012. All rights reserved
+ *
+ ***************************************************************************/
+
+/****************************************************************************/
+/***        Include files                                                 ***/
+/****************************************************************************/
+
+#include "MicroSpecific_arm_sdk2.h"
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
+
+
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific_arm_sdk2.h b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific_arm_sdk2.h
new file mode 100755
index 0000000..1639803
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/MicroSpecific_arm_sdk2.h
@@ -0,0 +1,389 @@
+/*****************************************************************************
+ *
+ * MODULE:              Definitions specific to a particular processor
+ *
+ * DESCRIPTION:
+ * Definitions for a specific processor, i.e. functions that can only be
+ * resolved by op codes
+ *
+ ****************************************************************************
+ *
+ * This software is owned by NXP B.V. and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142, JN5139].
+ * You, and any third parties must reproduce the copyright and warranty notice
+ * and any other legend of ownership on each copy or partial copy of the
+ * software.
+ *
+ * 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.
+ *
+ * Copyright NXP B.V. 2012, 2019. All rights reserved
+ *
+ ***************************************************************************/
+
+#ifndef  MICRO_SPECIFIC_INCLUDED
+#define  MICRO_SPECIFIC_INCLUDED
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+#include <jendefs.h>
+#include "fsl_device_registers.h"
+
+extern void (*isr_handlers[])(void);
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/** @{ Defined system call numbers */
+#define SYSCALL_SEMIHOSTING   						0xAB
+
+#define SEMIHOSTING_WRITE0      					0x04
+#define SEMIHOSTING_READC       0x07
+/** @} */
+
+#define MICRO_INTERRUPT_EXCEPTION_OFFSET            16
+
+// number of bits are defined by the hardware
+#define MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS     __NVIC_PRIO_BITS
+
+// this macro depends on the setting of the priority group in the NVIC, setting G=3 in this case
+#define MICRO_INTERRUPT_MAX_PRIORITY                ((1 << MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS) - 1)
+// half way
+#define MICRO_INTERRUPT_MID_PRIORITY                (MICRO_INTERRUPT_MAX_PRIORITY/2)
+
+// Priority levels in the arm are higher for lower values - B-Semi chips were the other way around
+#define MICRO_INTERRUPT_ELEVATED_PRIORITY           (11)
+#define MICRO_INTERRUPT_MEDIUM_PRIORITY             (12)
+
+// priority/sub priority register 8-bits wide
+// read/write priority
+#define MICRO_INTERRUPT_WRITE_PRIORITY_VALUE(W)     ((W) << (8 - MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS))
+#define MICRO_INTERRUPT_READ_PRIORITY_VALUE(R)      ((R) >> (8 - MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS))
+// read/write sub-priority
+#define MICRO_INTERRUPT_SUBPRIORITY_MASK            ((1  << (8 - MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS)) -1)
+#define MICRO_INTERRUPT_SUBPRIORITY_VALUE(S)        ((S) & (MICRO_INTERRUPT_SUBPRIORITY_MASK))
+
+
+extern void vAHI_InterruptSetPriority(uint32 u32Mask, uint8 u8Level);
+extern uint8 u8AHI_InterruptGetPriority(uint32 u32InterruptNumber);
+extern void vAHI_InterruptDisable(uint32 u32EnableMask);
+extern void vAHI_TickTimerIntEnable(bool_t bIntEnable);
+extern void vAHI_InterruptSetActivePriorityLevel(uint8 u8Level);
+extern uint8 u8AHI_InterruptReadActivePriorityLevel(void);
+
+#define MICRO_ENABLE_TICK_TIMER_INTERRUPT();                                \
+        vAHI_TickTimerIntEnable(TRUE);
+
+// use same value as Jennic/BA devices
+#define MICRO_SET_PIC_ENABLE(A)                                             \
+    vAHI_InterruptSetPriority(A, 8);
+
+#define MICRO_CLEAR_PIC_ENABLE(A)                                           \
+    vAHI_InterruptDisable(A)
+
+#define MICRO_SET_PIC_PRIORITY_LEVEL(A,B)                                   \
+    vAHI_InterruptSetPriority(A, B);
+
+#define MICRO_GET_PIC_PRIORITY_LEVEL(A)                                     \
+    u8AHI_InterruptGetPriority(A);
+
+/* Actual macros are instantiated in the respective CMSIS files */
+#define MICRO_ENABLE_INTERRUPTS()             __enable_irq()
+
+#define MICRO_DISABLE_INTERRUPTS()            __disable_irq()
+
+#define MICRO_GET_PRIMASK_LEVEL()            __get_PRIMASK()
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_GET_PRIMASK_LEVEL()                                 \
+ *  ({                                                               \
+ *       register uint32 __u32primaskLevelStore;                     \
+ *       asm volatile ("MRS %[primasklevelstore], PRIMASK;"          \
+ *           :[primasklevelstore] "=r"(__u32primaskLevelStore)       \
+ *           :                                                       \
+ *           );                                                      \
+ *       __u32primaskLevelStore;                                     \
+ *  })
+ */
+#define MICRO_SET_PRIMASK_LEVEL(A)           __set_PRIMASK(A)
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_SET_PRIMASK_LEVEL(A)                                \
+ *  ({                                                               \
+ *       register uint32 __u32primaskLevelStore  = A;                \
+ *       asm volatile ("MSR PRIMASK, %[primasklevelstore];"          \
+ *           :                                                       \
+ *           :[primasklevelstore] "r"(__u32primaskLevelStore)        \
+ *           );                                                      \
+ *  })
+ */
+#define MICRO_GET_ACTIVE_INT_LEVEL()         __get_BASEPRI()
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_GET_ACTIVE_INT_LEVEL()                              \
+ *   ({                                                              \
+ *       register uint32 __u32interruptActiveLevel;                  \
+ *       asm volatile ("MRS %[activelevelstore], BASEPRI;"           \
+ *           :[activelevelstore] "=r"(__u32interruptActiveLevel)     \
+ *           : );                                                    \
+ *       __u32interruptActiveLevel;                                  \
+ *   })
+ */
+#define MICRO_SET_ACTIVE_INT_LEVEL_MAX(A)    __set_BASEPRI_MAX(A)
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_SET_ACTIVE_INT_LEVEL_MAX(A)                         \
+ *  ({                                                               \
+ *     register uint32 __u32interruptLevelStore  = A;                \
+ *       asm volatile ("MSR BASEPRI_MAX, %[intlevelstore];"          \
+ *           :                                                       \
+ *           :[intlevelstore] "r"(__u32interruptLevelStore)          \
+ *           );                                                       \
+ *  })
+ */
+#define MICRO_SET_ACTIVE_INT_LEVEL(A)        __set_BASEPRI(A)
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_SET_ACTIVE_INT_LEVEL(A)                             \
+ *  ({                                                               \
+ *      register uint32 __u32interruptLevelStore  = A;               \
+ *       asm volatile ("MSR BASEPRI, %[intlevelstore];"              \
+ *           :                                                       \
+ *           :[intlevelstore] "r"(__u32interruptLevelStore)          \
+ *           );                                                      \
+ *  })
+ */
+/* Read back PRIMASK status into u32Store variable then disable 
+ * the interrupts */
+#define MICRO_DISABLE_AND_SAVE_INTERRUPTS(u32Store)                  \
+   ({                                                                \
+        u32Store = __get_PRIMASK();                                  \
+        __disable_irq();                                             \
+   })
+/* Former implementation : deprecated since combining CMSIS alternative is 
+ * possible.
+ * #define MICRO_DISABLE_AND_SAVE_INTERRUPTS(u32Store)               \
+ *  ({                                                               \
+ *       asm volatile ("MRS %[primasklevelstore], PRIMASK;"          \
+ *               :[primasklevelstore] "=r"(u32Store)                 \
+ *               :                                                   \
+ *               );                                                  \
+ *       asm volatile ("CPSID I;" : : );                             \
+ *  })
+ */
+#define MICRO_RESTORE_INTERRUPTS(u32Store)  __set_PRIMASK(u32Store)
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_RESTORE_INTERRUPTS(u32Store)                        \
+ *  ({                                                               \
+ *       asm volatile ("MSR PRIMASK, %[primasklevelstore];"          \
+ *               :                                                   \
+ *               :[primasklevelstore] "r"(u32Store)                  \
+ *               );                                                  \
+ *  })
+ */
+#define MICRO_GET_EXCEPTION_STACK_FRAME()   __get_MSP()
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * using AAPCS the parameter (the stack frame) wouuld map to r0
+ * #define MICRO_GET_EXCEPTION_STACK_FRAME()                         \
+ *  {                                                                \
+ *       asm volatile("MRS R0, MSP");                                \
+ *  }
+ */
+
+#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
+/* Count Trailing Zeroes implementation for IAR :
+ * no builtin implementation for IAR, whereas __CLZ exists */
+static inline uint32_t __ctz(uint32_t x)
+{
+    uint32_t res;
+    x = __RBIT(x);
+    res = __CLZ(x);
+    return res;
+}
+#define _CTZ(x)             __ctz(x)
+
+/* Find First Set : returns 0 if no bit set, otherwise returns the order 
+ *  of LSB bit set + 1
+ * __ffs(0) return 0, __ffs(1) returns 1, __ffs(0x8000000) returns 31
+ */
+static inline uint32_t __ffs(uint32_t x) 
+{
+   register uint32 __u32Reg;
+   __u32Reg = _CTZ(x);
+   __u32Reg = __u32Reg == 32 ? 0 : __u32Reg + 1U;
+   return __u32Reg;
+}
+
+#define _FFS(x)            __ffs(x)
+#else  /* __IAR_SYSTEMS_ICC__ */
+/* GCC builtin */
+#define _CTZ(x)             __builtin_ctz(x)
+
+#define _FFS(x)                                     \
+({   register uint32_t __u32Reg, __ret;             \
+   __u32Reg = _CTZ(x);                              \
+   __ret = __u32Reg == 32 ? 0 : __u32Reg + 1U;      \
+   __ret;                                           \
+})
+#endif  /* __IAR_SYSTEMS_ICC__ */
+
+/* Bit Scan Reverse */
+#define MICRO_BSR(x) (31 - _CLZ(x))
+/* Bit Scan Forward */
+#define MICRO_BSF(x) _CTZ(x)
+
+#define MICRO_FFS(x)       _FFS(x)
+
+
+#define FF1(__input)      MICRO_FFS(__input)
+
+#define MICRO_GET_LX()           __get_LR()
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_GET_LX()                               \
+ * ({                                                   \
+ *   register uint32 __u32lxRegister;                   \
+ *   asm volatile ("MOV %[lxRegister], R14;"            \
+ *         :[lxRegister] "=r"(__u32lxRegister)          \
+ *           :                                          \
+ *           );                                         \
+ *       __u32lxRegister;                               \
+ * })
+ */
+#define MICRO_GET_STACK_LEVEL()  __get_SP()
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_GET_STACK_LEVEL()                       \
+ *  ({                                                   \
+ *       register uint32 __u32stackRegister;             \
+ *       asm volatile ("MOV %[stackRegister], SP;"       \
+ *           :[stackRegister] "=r"(__u32stackRegister)   \
+ *           :                                           \
+ *           );                                          \
+ *       __u32stackRegister;                             \
+ *  })
+ */
+
+#define MICRO_TRAP()             __BKPT(0)
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_TRAP()         asm volatile("BKPT 0;")
+ */
+#define MICRO_NOP()              __NOP()
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_NOP()          asm volatile ("nop;")
+ */
+
+/* macro using privilege/non-privilege model:
+ * u32reg is the register to return the stack pointer that corresponds to 
+ * the mode we are in: either MSP or PSP.
+ * Note: this macro has chnaged fir IAR compatibility u32reg is the return
+ * register so that R0 is not implicitly the returned value
+ */
+#define MICRO_GET_EXCEPTION_STACK_FRAME_PNPM(u32reg)              \
+     register uint32_t u32reg;                                    \
+     asm volatile("TST LR, #4\n\t"                                \
+                  "ITE EQ\n\t"                                    \
+                  "MRSEQ R0, MSP\n\t"                             \
+                  "MRSNE R0, PSP\n\t");                           \
+     asm volatile ("MOV %0, R0" : "=r" (u32reg) : /* no input */ ); 
+
+/* Interrupt Handler registration - only useful if you're putting the handlers
+ * in RAM */
+
+/* Location of isr_handlers is no longer at a known location, but we can link
+   to it directly instead */
+#define MICRO_SET_INT_HANDLER(INT, FUNC);                                   \
+    isr_handlers[(MICRO_INTERRUPT_EXCEPTION_OFFSET + INT)] = (void *)(FUNC);
+
+#define MICRO_GET_INT_HANDLER(INT)                                          \
+    (isr_handlers[(MICRO_INTERRUPT_EXCEPTION_OFFSET + INT)])
+
+/* Nested interrupt control */
+#define MICRO_INT_STORAGE         tsMicroIntStorage sIntStorage
+#define MICRO_INT_ENABLE_ONLY(A)  vMicroIntEnableOnly(&sIntStorage, A)
+#define MICRO_INT_RESTORE_STATE() vMicroIntRestoreState(&sIntStorage)
+
+/* Exception Handlers */
+#define MICRO_ESR_NUM_RESETISR                    1
+#define MICRO_ESR_NUM_NMI                         2
+#define MICRO_ESR_NUM_HARDFAULT                   3
+#define MICRO_ESR_NUM_MEMMANAGE                   4
+#define MICRO_ESR_NUM_BUSFAULT                    5
+#define MICRO_ESR_NUM_USGFAULT                    6
+// 4 reserved handlers here
+#define MICRO_ESR_NUM_SVCALL                      11
+#define MICRO_ESR_NUM_DEBUGMON                    12
+// 1 reserved handler here
+#define MICRO_ESR_NUM_PENDSV                      14
+#define MICRO_ESR_NUM_SYSTICK                     15
+
+/* Location of exception_handlers is no longer at a known location, but we can link
+   to it directly instead - only useful if you're putting the handlers
+ * in RAM */
+#define MICRO_SET_EXCEPTION_HANDLER(EXCEPTION, FUNC)                        \
+    isr_handlers[EXCEPTION] = (void *)(FUNC);
+
+#define MICRO_GET_EXCEPTION_HANDLER(INT)                                    \
+    (isr_handlers[EXCEPTION])
+
+/* NOP instruction */
+
+
+/* TRAP instruction */
+
+#define MICRO_JUMP_TO_ADDRESS(ADDRESS)                                      \
+   ({                                                                       \
+       register uint32 __u32programAddressStore = ADDRESS | 0x1;            \
+       asm volatile ("BLX %[programAddressStore];"                          \
+           :                                                                \
+           :[programAddressStore] "r"(__u32programAddressStore));           \
+    })
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+/* Nested interrupt control */
+typedef struct
+{
+    uint8 u8Level;
+} tsMicroIntStorage;
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+PUBLIC void vAHI_InitialiseInterruptController(uint32 *pu32InterruptVectorTable);
+
+/* Nested interrupt control */
+PUBLIC void vMicroIntSetGlobalEnable(uint32 u32EnableMask);
+PUBLIC void vMicroIntEnableOnly(tsMicroIntStorage *, uint32 u32EnableMask);
+PUBLIC void vMicroIntRestoreState(tsMicroIntStorage *);
+/* Default Exception Handler */
+PUBLIC void vIntDefaultHandler(void);
+
+PUBLIC void __attribute__((noinline)) vMicroSyscall(volatile uint32 u32SysCallNumber, ...);
+PUBLIC void __attribute__((noinline)) vMicroSemihost(volatile uint32 u32SemihostNumber, ...);
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif  /* MICRO_SPECIFIC_INCLUDED */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
+
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/jendefs.h b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/jendefs.h
new file mode 100755
index 0000000..a54189f
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/framework/Common/jendefs.h
@@ -0,0 +1,344 @@
+/*****************************************************************************
+ *
+ * MODULE:             ALL MODULES
+ *
+ * DESCRIPTION:        The JENNIC standard header file defining extensions to
+ *                     ANSI C standard required by the Jennic C coding standard.
+ *
+ ****************************************************************************
+ *
+ * This software is owned by NXP B.V. and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142, JN5139].
+ * You, and any third parties must reproduce the copyright and warranty notice
+ * and any other legend of ownership on each copy or partial copy of the
+ * software.
+ *
+ * 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.
+ *
+ * Copyright NXP B.V. 2012. All rights reserved
+ *
+ ***************************************************************************/
+
+#ifndef  JENDEFS_INCLUDED
+#define  JENDEFS_INCLUDED
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stdint.h>
+
+#ifndef __KERNEL__
+#include <stdarg.h>
+#include <stdio.h>
+#endif
+
+#ifdef ECOS
+#include <cyg/infra/cyg_type.h>
+#endif
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/*--------------------------------------------------------------------------*/
+/*          Compiler Constants for GCC compiler                             */
+/*--------------------------------------------------------------------------*/
+
+#if defined(__GNUC__)
+
+/* The following 5 macros force the compiler to align the specified object  */
+/* on a given byte boundary.                                                */
+/* Example:                                                                 */
+/*     int  iVar  ALIGN_(16);  Force iVar to be aligned on the next         */
+/*                             16 byte boundary                             */
+
+#define PACK      __attribute__ ((packed))        /* align to byte boundary  */
+#define ALIGN_2   __attribute__ ((aligned (2)))   /* 16-bit boundary (2 byte)*/
+#define ALIGN_4   __attribute__ ((aligned (4)))   /* 32-bit boundary (4 byte)*/
+#define ALIGN_8   __attribute__ ((aligned (8)))   /* 64-bit boundary (8 byte)*/
+#define ALIGN_(x) __attribute__ (((aligned (x)))) /* arbitrary alignment     */
+
+/* force an unused variable not to be elided */
+#define USED      __attribute__ ((used))
+
+#if __GNUC__ < 5
+#define INLINE    extern inline
+#else
+#if (defined JENNIC_CHIP_FAMILY_JN516x) || (defined JENNIC_CHIP_FAMILY_JN517x)
+#pragma message ( "Unsupported version of GCC is being used!!" )
+#endif
+#define INLINE    inline
+#endif
+
+#define ALWAYS_INLINE __attribute__((always_inline))
+
+#ifndef WEAK
+#define WEAK      __attribute__ ((weak))
+#endif
+#define ALIAS(f)  __attribute__ ((weak, alias (#f)))
+
+#elif defined(_MSC_VER)
+
+#define PACK
+#define USED
+#define __attribute__(x)
+#define ALWAYS_INLINE
+#define INLINE __inline
+
+
+#elif defined(__IAR_SYSTEMS_ICC__)
+// if compiled for IAR, none of the above defines are required
+#else
+#error "Unsupported compiler"
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Alignment masks                                                 */
+/*--------------------------------------------------------------------------*/
+
+#define ALIGNMENT_MASK_4_BYTE     ((uint32)0x00000003)
+#define ALIGNMENT_MASK_16_BYTE    ((uint32)0x0000000F)
+
+/* Test for alignment on an arbitrary byte boundary - TRUE if aligned */
+
+#define IS_ALIGNED(addr, mask) (((((uint32)addr) & mask) ? FALSE : TRUE))
+
+/*--------------------------------------------------------------------------*/
+/*          Boolean Constants                                               */
+/*--------------------------------------------------------------------------*/
+
+#if !defined FALSE && !defined TRUE
+#define TRUE            (1)   /* page 207 K+R 2nd Edition */
+#define FALSE           (0)
+#endif /* !defined FALSE && #if !defined TRUE */
+
+/*     Note that WINDOWS.H also defines TRUE and FALSE                 */
+
+/*--------------------------------------------------------------------------*/
+/*          Null pointers                                                   */
+/*--------------------------------------------------------------------------*/
+
+/* NULL data pointer */
+#if !defined NULL
+#define NULL                    ( (void *) 0 )
+#endif
+
+/* NULL routine pointer */
+#if !defined RNULL
+#define RNULL                   ((void *) 0 ())
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for setting/clearing bits efficiently                    */
+/*--------------------------------------------------------------------------*/
+
+#define U8_CLR_BITS( P, B )   (( *(uint8 *)P ) &= ~( B ))
+#define U8_SET_BITS( P, B )   (( *(uint8 *)P ) |=  ( B ))
+#define U16_CLR_BITS( P, B )  (( *(uint16 *)P ) &= ~( B ))
+#define U16_SET_BITS( P, B )  (( *(uint16 *)P ) |=  ( B ))
+#define U32_CLR_BITS( P, B )  (( *(uint32 *)P ) &= ~( B ))
+#define U32_SET_BITS( P, B )  (( *(uint32 *)P ) |=  ( B ))
+#define U64_CLR_BITS( P, B )  (( *(uint64 *)P ) &= ~( B ))
+#define U64_SET_BITS( P, B )  (( *(uint64 *)P ) |=  ( B ))
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for obtaining maximum/minimum values                     */
+/*--------------------------------------------------------------------------*/
+#ifndef MAX
+#define MAX(A,B)                ( ( ( A ) > ( B ) ) ? ( A ) : ( B ) )
+#endif
+#ifndef MIN
+#define MIN(A,B)                ( ( ( A ) < ( B ) ) ? ( A ) : ( B ) )
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Number of bits in quantities                                    */
+/*--------------------------------------------------------------------------*/
+
+#define BITS_PER_U32            (32)
+#define BITS_PER_U16            (16)
+#define BITS_PER_U8             (8)
+#define BITS_PER_NIBBLE         (4)
+
+/*--------------------------------------------------------------------------*/
+/*          Masking macros                                                  */
+/*--------------------------------------------------------------------------*/
+
+#define U8_LOW_NIBBLE_MASK      (0x0F)
+#define U8_HIGH_NIBBLE_MASK     (0xF0)
+
+#define U16_LOW_U8_MASK         (0x00FF)
+#define U16_HIGH_U8_MASK        (0xFF00)
+
+#define U32_LOWEST_U8_MASK      (0x000000FFL)
+#define U32_LOW_U8_MASK         (0x0000FF00L)
+#define U32_HIGH_U8_MASK        (0x00FF0000L)
+#define U32_HIGHEST_U8_MASK     (0xFF000000L)
+
+#define U32_LOWEST_U16_MASK     (0x0000FFFFL)
+#define U32_HIGHEST_U16_MASK    (0xFFFF0000L)
+
+#define U64_LOWEST_U32_MASK     (0x00000000FFFFFFFFLL)
+#define U64_HIGHEST_U32_MASK    (0xFFFFFFFF00000000LL)
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for extracting uint8s from a uint16                      */
+/*--------------------------------------------------------------------------*/
+
+/* NOTE: U16_UPPER_U8 is only safe for an unsigned U16 as >> fills with the sign bit for signed variables */
+#define U16_UPPER_U8( x )      ((uint8) ((x) >> BITS_PER_U8))
+#define U16_LOWER_U8( x )      ((uint8) (((x) & U16_LOW_U8_MASK)))
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for extracting uint8s from a uint32                      */
+/*--------------------------------------------------------------------------*/
+
+#define U32_HIGHEST_U8( x ) ((uint8)(((x) & U32_HIGHEST_U8_MASK) >> (BITS_PER_U16 + BITS_PER_U8)))
+
+#define U32_HIGH_U8( x ) ((uint8)( ( ( x ) & U32_HIGH_U8_MASK ) >> BITS_PER_U16 ))
+
+#define U32_LOW_U8( x ) ((uint8)( ( ( x ) & U32_LOW_U8_MASK ) >> BITS_PER_U8 ))
+
+#define U32_LOWEST_U8( x ) ((uint8)( ( ( x ) & U32_LOWEST_U8_MASK ) ))
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for extracting uint16s from a uint32                     */
+/*--------------------------------------------------------------------------*/
+
+#define U32_UPPER_U16( x )     ((uint16)( ( ( x ) & U32_HIGHEST_U16_MASK ) >> ( BITS_PER_U16 ) ))
+#define U32_LOWER_U16( x )     ((uint16)( ( ( x ) & U32_LOWEST_U16_MASK ) ))
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for extracting uint32s from a uint64                     */
+/*--------------------------------------------------------------------------*/
+
+#define U64_UPPER_U32( x )     ((uint32)( ( ( x ) & U64_HIGHEST_U32_MASK ) >> ( BITS_PER_U32 ) ))
+#define U64_LOWER_U32( x )     ((uint32)( ( ( x ) & U64_LOWEST_U32_MASK ) ))
+
+/*--------------------------------------------------------------------------*/
+/*         Macros for assembling byte sequences into various word sizes     */
+/*--------------------------------------------------------------------------*/
+
+/* B0 - LSB, B3 - MSB */
+
+#ifdef HOST_PROCESSOR_BIG_ENDIAN
+/* BIG ENDIAN DEFINITIONS */
+#define BYTE_ORDER_32(B3, B2, B1, B0)   ((B0) + (B1<<8) + (B2<<16) + (B3<<24))
+
+#define BYTE_ORDER_24(B2, B1, B0)       ((B0) + (B1<<8) + (B2<<16))
+
+#define BYTE_ORDER_16(B1, B0)           (uint16)(((B0) + (B1<<8)))
+
+#define BYTE_ORDER_8(B0)                (B0)
+
+#define BYTE_ORDER_4(B0)                (B0)
+#else
+/* LITTLE ENDIAN DEFINITIONS */
+#define BYTE_ORDER_32(B3, B2, B1, B0)   ((B3) + (B2<<8) + (B1<<16) + (B0<<24))
+
+#define BYTE_ORDER_24(B2, B1, B0)       ((B2) + (B1<<8) + (B0<<16))
+
+#define BYTE_ORDER_16(B1, B0)           (uint16)(((B1) + (B0<<8)))
+
+#define BYTE_ORDER_8(B0)                (B0)
+
+#define BYTE_ORDER_4(B0)                (B0)
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Storage classes                                                 */
+/*--------------------------------------------------------------------------*/
+
+#if !defined PUBLIC
+#define PUBLIC
+#endif
+
+#if !defined MODULE
+#define MODULE
+#endif
+
+#if !defined PRIVATE
+#define PRIVATE static
+#endif
+
+#if !defined BANKED
+#define BANKED
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Useful macro for variables that are not currently referenced             */
+/* Prevents compiler warnings and should not produce any code               */
+/*--------------------------------------------------------------------------*/
+
+#define VARIABLE_INTENTIONALLY_NOT_REFERENCED(x) (x=x);
+#define CONST_POINTER_INTENTIONALLY_NOT_REFERENCED(p) (*p);
+#define CONST_VARIABLE_INTENTIONALLY_NOT_REFERENCED(x) (x);
+
+/*--------------------------------------------------------------------------*/
+/* Offset of field m in a struct s                                          */
+/*--------------------------------------------------------------------------*/
+
+#if !defined(__GNUC__) && !defined(ECOS) && !defined(offsetof)
+#define offsetof(type, tag)     ( (int)&( (type *)0 )->tag )
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Diagnostics                                                     */
+/*--------------------------------------------------------------------------*/
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+    #ifndef __cplusplus /* microsoft specific */
+        #ifndef bool /* Seems to need this in for certain M$ builds*/
+            typedef int                     bool;     /* boolean type */
+        #endif
+    #endif
+
+    typedef uint8_t                 BOOL_T;     /* boolean type nothing to do with C++ */
+    typedef uint8_t                 bool_t;     /* boolean type nothing to do with C++ */
+
+    typedef int8_t                  int8;
+    typedef int16_t                 int16;
+    typedef int32_t                 int32;
+    typedef int64_t                 int64;
+    typedef uint8_t                 uint8;
+    typedef uint16_t                uint16;
+    typedef uint32_t                uint32;
+    typedef uint64_t                uint64;
+
+    typedef char *                  string;
+
+    typedef volatile uint8          u8Register;
+    typedef volatile uint16         u16Register;
+    typedef volatile uint32         u32Register;
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#endif  /* JENDEFS_INCLUDED */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
+
+
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/DK6/radio.h b/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/DK6/radio.h
new file mode 100755
index 0000000..a081ddb
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/DK6/radio.h
@@ -0,0 +1,808 @@
+/*
+ * @brief Radio driver
+ *
+ * @note
+ * Copyright 2019 NXP
+ *
+ * @par
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * LPC products.  This software is supplied "AS IS" without any warranties of
+ * any kind, and NXP Semiconductors and its licensor disclaim any and
+ * all warranties, express or implied, including all implied warranties of
+ * merchantability, fitness for a particular purpose and non-infringement of
+ * intellectual property rights.  NXP Semiconductors assumes no responsibility
+ * or liability for the use of the software, conveys no license or rights under any
+ * patent, copyright, mask work right, or any other intellectual property rights in
+ * or to any products. NXP Semiconductors reserves the right to make changes
+ * in the software without notification. NXP Semiconductors also makes no
+ * representation or warranty that such application will be suitable for the
+ * specified use without further testing or modification.
+ *
+ * @par
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, under NXP Semiconductors' and its
+ * licensor's relevant copyrights in the software, without fee, provided that it
+ * is used in conjunction with NXP Semiconductors microcontrollers.  This
+ * copyright, permission, and disclaimer notice must appear in all copies of
+ * this code.
+ */
+
+#ifndef __RADIO_H_
+#define __RADIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+/****************************************************************************/
+/***        Macro/Type Definitions                                        ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***    Radio driver version (XYYY): X major version, YYY minor version   ***/
+/****************************************************************************/
+#define RADIO_VERSION (2088)
+
+/****************************************************************************/
+/***    Radio calibration data record version                             ***/
+/****************************************************************************/
+#define RADIO_CAL_RECORD_VERSION (1001)
+
+/****************************************************************************/
+/***    Radio driver int time values									  ***/
+/***	RADIO_INIT_TIME_WITH_KMOD_INIT_US full init time with Kmod cal    ***/
+/***	This init is done only when KMOD cal results are not available    ***/
+/***	in flash for the current initialization temperature. As results   ***/
+/***	are valid in a [-40...+40C] temperature range around the cal      ***/
+/***	temperature, only 4 full calibration are needed in the whole live ***/
+/***	of the chip and this init time is quite never reached.            ***/
+/***	RADIO_INIT_TIME_WITHOUT_KMOD_INIT_US full init time without Kmod  ***/
+/***	calibration. This is the typical coldstart radio init time		  ***/
+/***	RADIO_INIT_TIME_WITH_RETENTION_US init time when using retention  ***/
+/***	In that case calibrations are not run and parameters kept in      ***/
+/***	in retention flops are used instead. This is a the typical warm   ***/
+/***	start init time.                                                  ***/
+/****************************************************************************/
+
+#define RADIO_FULL_INIT_FIRST_TIME (80300) // no record available and all cal to be done because TCur far from TCAL ATE
+#define RADIO_FULL_INIT_TIME (85500) // record available but all cal to be done because TCur far from TCAL ATE
+#define RADIO_INIT_ALL_CAL_IN_FLASH (850) // record available, no cal to be done and TCur close to TCAL ATE
+#define RADIO_INIT_NO_DCO_CAL_IN_FLASH (13500) // no record available, DCO cal only and TCur close to TCAL ATE
+#define RADIO_INIT_TIME_WITH_RETENTION_US (250) // can use retention values
+#define RADIO_RECAL_TIME_ALL_CAL_IN_FLASH_US (750) // recal with cal available in flash for TCur
+#define RADIO_RECAL_TIME_NO_CAL_IN_FLASH_US (86800) // recal with cal data not available in flash, all call to be done
+#define RADIO_RECAL_TIME_NO_DCO_CAL_IN_FLASH_US (16100) // recal with DCO cal to do
+#define RADIO_RECAL_TIME_NORECAL_US (8) // recal when not needed
+#define RADIO_GET_NEXT_RECAL_DURATION (20) // u32Radio_Get_Next_Recal_Duration max execution time
+
+/****************************************************************************/
+/***    Number of bytes of the u8AppliData buffer                         ***/
+/***    See vRadio_Save_ApplicationData_Retention                  ***/
+/***    and vRadio_Restore_Retention_ApplicationData               ***/
+/****************************************************************************/
+#define APP_DATA_RET_NB_BYTES (114)
+#define ADD_DATA_RET_NB_BITS (906)
+
+
+
+/****************************************************************************/
+/***    Local defined values        									  ***/
+/****************************************************************************/
+#define RADIO_MODE_LOPOWER          (0)
+#define RADIO_MODE_HITXPOWER        (1)
+
+#define RADIO_INIT_INITCAL			(0)
+#define RADIO_INIT_DEF_VAL			(1)
+#define RADIO_INIT_RETENTION		(2)
+#define RADIO_INIT_FORCE_CAL		(3)
+
+/****************************************************************************/
+/***	Values to be used as u32RadioMode parameter                       ***/
+/***	for vRadio_RadioInit API                                   ***/
+/*** 	RADIO_MODE_STD_USE_INITCAL default init mode to use. in this mode ***/
+/***	the radio init will be done in standard lowpower mode and the     ***/
+/***	calibrations will be launched automatically based on temperature  ***/
+/***	deviation since last calibration. Calibration will also be done   ***/
+/***	if no retention values are available or if it is the first init.  ***/
+/***	Other values are for test or special needs.                       ***/
+/***	RADIO_MODE_STD_USE_DEF_VAL will force using default values for    ***/
+/***	all parameters. No calibration is done.                           ***/
+/***	RADIO_MODE_STD_USE_RETENTION will force usage of retention values ***/
+/***	without any validity test nor temperature control                 ***/
+/***    RADIO_MODE_STD_USE_FORCE_CAL will force calibration, ignoring any ***/
+/***	retention values and even if temperature has not changed          ***/
+/***	RADIO_MODE_HTXP_... have the same meaning but configure radio in  ***/
+/***	high tx power mode.                                               ***/
+/****************************************************************************/
+#define RADIO_MODE_STD_USE_INITCAL		((RADIO_MODE_LOPOWER << 8) | RADIO_INIT_INITCAL)
+#define RADIO_MODE_STD_USE_DEF_VAL      ((RADIO_MODE_LOPOWER << 8) | RADIO_INIT_DEF_VAL)
+#define RADIO_MODE_STD_USE_RETENTION	((RADIO_MODE_LOPOWER << 8) | RADIO_INIT_RETENTION)
+#define RADIO_MODE_STD_USE_FORCE_CAL	((RADIO_MODE_LOPOWER << 8) | RADIO_INIT_FORCE_CAL)
+#define RADIO_MODE_HTXP_USE_INITCAL		((RADIO_MODE_HITXPOWER << 8) | RADIO_INIT_INITCAL)
+#define RADIO_MODE_HTXP_USE_DEF_VAL		((RADIO_MODE_HITXPOWER << 8) | RADIO_INIT_DEF_VAL)
+#define RADIO_MODE_HTXP_USE_RETENTION	((RADIO_MODE_HITXPOWER << 8) | RADIO_INIT_RETENTION)
+#define RADIO_MODE_HTXP_USE_FORCE_CAL	((RADIO_MODE_HITXPOWER << 8) | RADIO_INIT_FORCE_CAL)
+
+/****************************************************************************/
+/***    Local defined values        									  ***/
+/****************************************************************************/
+#define TX_REGULAR 0
+#define TX_PROP_1  1
+#define TX_PROP_2  2
+#define TX_BLE_1MB 3
+#define TX_BLE_2MB 4
+#define TX_UNDEFINED 0xFF
+
+#define RX_DETECTOR_ONLY 0
+#define RX_ENABLE_LUT    1
+#define RX_BLE_1MB       3
+#define RX_BLE_2MB       4
+#define RX_UNDEFINED 0xFF
+
+/****************************************************************************/
+/***	Values to be used as u32RadioStandard parameter                   ***/
+/***	for vRadio_Standard_Init API                               ***/
+/***	RADIO_STANDARD_ZIGBEE_REGULAR standard Zigbee Mode                ***/
+/***	RADIO_STANDARD_ZIGBEE_PROP_1 Zigbee mode with proprietary mode 1  ***/
+/***	Tx configuration (soft spread reduction)                          ***/
+/***	RADIO_STANDARD_ZIGBEE_PROP_2 Zigbee mode with proprietary mode 2  ***/
+/***	Tx configuration (more agressive spread reduction)                ***/
+/***	RADIO_STANDARD_ZIGBEE_REGULAR Zigbee Mode using LUT mode for AGC  ***/
+/***	control. Test only.                                               ***/
+/***	RADIO_STANDARD_ZIGBEE_PROP_1_LUT and _PROP_2_LUT LUT AGC control  ***/
+/***	and Tx mode1/2                                                    ***/
+/***	RADIO_STANDARD_BLE_1MB BLE 1 Mbps mode (for TX and RX)			  ***/
+/***	RADIO_STANDARD_BLE_2MB BLE 2 Mbps mode (for TX and RX)			  ***/
+/***	RADIO_STANDARD_BLE_RX1MB_TX2MB and RADIO_STANDARD_BLE_RX2MB_TX1MB ***/
+/***	are BLE configuration with different RX/TX bitrates               ***/
+/****************************************************************************/
+
+#define RADIO_STANDARD_ZIGBEE_REGULAR ((RX_DETECTOR_ONLY << 8) | (TX_REGULAR))
+#define RADIO_STANDARD_ZIGBEE_PROP_1  ((RX_DETECTOR_ONLY << 8) | (TX_PROP_1))
+#define RADIO_STANDARD_ZIGBEE_PROP_2  ((RX_DETECTOR_ONLY << 8) | (TX_PROP_2))
+#define RADIO_STANDARD_ZIGBEE_REGULAR_LUT ((RX_ENABLE_LUT << 8) | (TX_REGULAR))
+#define RADIO_STANDARD_ZIGBEE_PROP_1_LUT  ((RX_ENABLE_LUT << 8) | (TX_PROP_1))
+#define RADIO_STANDARD_ZIGBEE_PROP_2_LUT  ((RX_ENABLE_LUT << 8) | (TX_PROP_2))
+#define RADIO_STANDARD_BLE_1MB ((RX_BLE_1MB << 8) | (TX_BLE_1MB))
+#define RADIO_STANDARD_BLE_2MB ((RX_BLE_2MB << 8) | (TX_BLE_2MB))
+#define RADIO_STANDARD_BLE_RX1MB_TX2MB ((RX_BLE_1MB << 8) | (TX_BLE_2MB))
+#define RADIO_STANDARD_BLE_RX2MB_TX1MB ((RX_BLE_2MB << 8) | (TX_BLE_1MB))
+
+/****************************************************************************/
+
+/****************************************************************************/
+/*** radio driver types/macros/prototypes                                 ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***    Type definition for vRadio_SetChannelStandards function			  ***/
+/****************************************************************************/
+typedef enum
+{
+    E_RADIO_TX_MODE_STD    = TX_REGULAR,
+    E_RADIO_TX_MODE_PROP_1 = TX_PROP_1,
+    E_RADIO_TX_MODE_PROP_2 = TX_PROP_2,
+    E_RADIO_TX_MODE_RESET  = TX_UNDEFINED
+} teRadioTxMode;
+
+/* RSSI reported by XCV in 1/4 dBm step */
+#define RADIO_MAX_RSSI_REPORT       40
+#define RADIO_MIN_RSSI_REPORT     -400
+
+/****************************************************************************/
+/*** radio driver API prototypes                                          ***/
+/****************************************************************************/
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_RadioInit
+ *
+ * DESCRIPTION:
+ * Radio driver initialisation function.
+ *
+ * PARAMETERS:
+ * uint32_t u32RadioMode: use one of the defined values described above
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_RadioInit(uint32_t u32RadioMode);
+/****************************************************************************
+ *
+ * NAME:       vRadio_RadioDeInit
+ *
+ * DESCRIPTION:
+ * Radio driver de-initialisation function.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_RadioDeInit(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Standard_Init
+ *
+ * DESCRIPTION:
+ * Set radio parameters for the specified standard in the corresponding
+ * parameter bank of the radio HW block. There is one bank of each radio standard.
+ *
+ * PARAMETERS:
+ * uint32_t u32RadioStandard: use one of the defined values described above
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_Standard_Init(uint32_t u32RadioStandard);
+
+/****************************************************************************
+ *
+ * NAME:       u8Radio_GetEDfromRSSI
+ *
+ * DESCRIPTION:
+ * Returns Energy Detect value calculated from RSSI value
+ *
+ * PARAMETERS:
+ * int16_t i16RSSIval: RSSI value expressed in fourth of dBm (2'complement signed value)
+ *
+ * RETURNS:
+ * uint8_t ED in [0..255] range
+ *
+ ****************************************************************************/
+uint8_t u8Radio_GetEDfromRSSI(int16_t i16RSSIval);
+
+/****************************************************************************
+ *
+ * NAME:       u32Radio_RadioModesAvailable
+ *
+ * DESCRIPTION:
+ * Returns returns bit combination of available radio modes (1 for LOPOWER and/or 2 for HIGHPOWER)
+ * Currently only LOPOWER is implemented so always returns 1
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * uint32_t bit combination of radio modes
+ *
+ ****************************************************************************/
+uint32_t u32Radio_RadioModesAvailable(void);
+
+/****************************************************************************
+ *
+ * NAME:       u32Radio_RadioGetVersion
+ *
+ * DESCRIPTION:
+ * Returns radio driver version. This function can be used to check the version
+ * of the radio driver embedded in the library used for the link against the value
+ * defined above as RADIO_VERSION and detected possible mismatch between this
+ * header file and the driver version itself.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * uint32_t radio version
+ *
+ ****************************************************************************/
+uint32_t u32Radio_RadioGetVersion(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Temp_Update
+ *
+ * DESCRIPTION:
+ * Provides the radio driver with the current temperature value.
+ *
+ * PARAMETERS:
+ * int16_t s16Temp: Temperature expressed in half of degre C (2'complement 16 bit value)
+ * 					For example 40 (or 0x28) for 20 degre Celsius
+ * 					or -40 (0xFFD8) for -20 degre Celsius
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_Temp_Update(int16_t s16Temp);
+
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_ConfigCalFlashUsage
+ *
+ * DESCRIPTION:
+ * Configure usage of flash record for radio calibration parameter.
+ * For example, this function can be used to temporarily disable write of
+ * calibration results in flash if there is a risk that the power can be removed
+ * during next radio init (e.g. energy harvesting application).
+ *
+ * PARAMETERS:
+ * bool bWriteToFlash: Allows radio_init/recal to write calibration results from flash.
+ * 					   If set to false, after new calibration, new results will not be
+ * 					   saved in flash for future re-use.
+ * 					   Default value is true.
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_ConfigCalFlashUsage(bool bWriteToFlash);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Save_ApplicationData_Retention
+ *
+ * DESCRIPTION:
+ * Save application data into radio retention registers.
+ *
+ * PARAMETERS:
+ * uint8_t *u8AppliData: Table of 8bit values to be stored in retention registers
+ * 						 It is the responsibility of the application that data
+ * 						 are compacted in the table as a bit steam of maximum
+ * 						 ADD_DATA_RET_NB_BITS bits over APP_DATA_RET_NB_BYTES bytes
+ * 						 See above for ADD_DATA_RET_NB_BITS and APP_DATA_RET_NB_BYTES
+ * 						 values.
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_Save_ApplicationData_Retention(uint8_t *u8AppliData);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Restore_Retention_ApplicationData
+ *
+ * DESCRIPTION:
+ * Save application data into radio retention registers.
+ *
+ * PARAMETERS:
+ * uint8_t *u8AppliData: Table of 8bit values to restore the table saved using
+ * 						 vRadio_Save_ApplicationData_Retention API
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_Restore_Retention_ApplicationData( uint8_t *u8AppliData);
+
+
+
+
+
+/****************************************************************************/
+/***        Public Functions (to be called by LL or MAC layer)            ***/
+/****************************************************************************/
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Recal
+ *
+ * DESCRIPTION:
+ * This function is to be called when it is possible (from the LL or MAC perspective)
+ * to re-calibrate the radio. This function will check the latest temperature
+ * value provided by the last vRadio_Temp_Update API, and if the difference between
+ * this temperature and the temperature used for the latest calibration is higher than
+ * 40 degre C, a new calibration is done and this new temperature is saved as the
+ * temperature of the latest calibration.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+bool vRadio_Recal(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_RFT1778_bad_crc
+ *
+ * DESCRIPTION:
+ * This function is to be called by the ZB MAC when a CRC error has been detected.
+ * This avoid lockup of the radio in some cases.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * int : 1 if lockup condition has been detected and unlocked, 0 otherwise.
+ *
+ ****************************************************************************/
+int vRadio_RFT1778_bad_crc(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_AD_control
+ *
+ * DESCRIPTION:
+ * When RX antenna diversity is enabled,  function is to be called by the ZB MAC
+ * when PRE_STATE_1 state is reached.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_AD_control(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_LockupCheckAndAbortRadio
+ *
+ * DESCRIPTION:
+ * This function is to be called by the BLE LL when an error has been detected.
+ * This avoid lockup of the radio in some cases.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_LockupCheckAndAbortRadio(void);
+
+/****************************************************************************
+ *
+ * The next 7 APIs are dedicated to the MAC layer for its internal needs.
+ *
+ ****************************************************************************/
+/* There are 3 sets of operating 'standards', which affects the frequency
+   response of the radio:
+     normal
+     proprietary 1
+     proprietary 2
+
+   For compliance it may be necessary to select different standards for
+   different channels, and this function allows that to be configured.
+   Note that this function has the AppApi prefix rather than the MMAC
+   prefix; we have traditionally provided customer-facing functions with
+   the AppApi prefix and this avoids a level of indirection via the shim
+   layer. */
+void vRadio_SetComplianceLimits(int8_t i8TxMaxPower,
+                                       int8_t i8TxMaxPowerCh26);
+void vRadio_SetChannelStandards(teRadioTxMode eNewTxMode,
+                                       teRadioTxMode eNewTxModeCh26);
+void vRadio_InitialiseRadioStandard(void);
+void vRadio_UpdateRadioStandard(uint8_t u8NewChannel);
+void vRadio_SetChannelAndPower(uint8_t u8Channel, int8_t i8TxPower_dBm);
+int8_t i8Radio_GetTxPowerLevel_dBm(void);
+
+int16_t i16Radio_GetRSSI(uint32_t u32DurationSymbols,bool bAverage, uint8_t *u8antenna);
+int16_t i16Radio_GetNbRSSISync(void);
+int16_t i16Radio_GetNbRSSISyncCor(uint8_t u8rate);
+int8_t i8Radio_GetLastPacketRSSI();
+int16_t i16Radio_BoundRssiValue(int16_t value);
+
+/****************************************************************************
+ *
+ * These APIs are dedicated to the BLE LL to reset BLE HW block if needed
+ * and to execute patch at end of RX process
+ *
+ ****************************************************************************/
+
+/* BLE reset APIs */
+void vRadio_BLE_ResetOn(void);
+void vRadio_BLE_ResetOff(void);
+
+void vRadio_remove_patch_ISR(void);
+void vRadio_SingleRX_AgcReadyPatch(void);
+void vRadio_MultiRX_AgcReadyPatch(void);
+void vRadio_Enable_AgcReadyPatch(void);
+void vRadio_Disable_AgcReadyPatch(void);
+
+
+
+/****************************************************************************
+ *
+ * The next 2 APIs are for temporary usage and are to be removed when XTAL init
+ * will be put out of radio driver
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_SkipXTALInit
+ *
+ * DESCRIPTION:
+ * Set an internal flag in the radio driver to skip any XTAL 32MHz handling
+ * by the radio driver. With this flag set, the radio driver does not start
+ * nor Trim the 32M XO.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_SkipXTALInit(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_EnableXTALInit
+ *
+ * DESCRIPTION:
+ * Reset the internal flag in the radio driver used to skip any XTAL 32MHz handling
+ * by the radio driver. With this flag cleared, the radio driver checks if 32M XO is
+ * running and start it if not already started. It also trim the 32M XO.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_EnableXTALInit(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_ActivateXtal32MRadioBiasing
+ *
+ * DESCRIPTION:
+ * Reset Radio HW block and switch XTAL32M to radio biasing control.
+ * ASSUMES THAT XTAL32M IS ALREADY SETUP, TRIMMED AND RUNNING UNDER PMC BIASING
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_ActivateXtal32MRadioBiasing(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_DisableZBRadio
+ *
+ * DESCRIPTION:
+ * Disable ZB radio block.
+ * This API needs to be called before vRadio_RadioInit and vRadio_ActivateXtal32MRadioBiasing.
+ * When ZB radio block is disabled, it is not reset and clocks are not enabled for this
+ * HW block.
+ * ONLY ONE OF vRadio_DisableZBRadio or vRadio_DisableBLERadio can be called.
+ * IF BOTH APIS ARE CALLED, ONLY THE FIRST ONE HAS EFFECT.
+ * IT CANNOT BE REVERSED. NEED HW RESET TO USE ZB RADIO AGAIN.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_DisableZBRadio(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_DisableBLERadio
+ *
+ * DESCRIPTION:
+ * Disable BLE radio block.
+ * This API needs to be called before vRadio_RadioInit and vRadio_ActivateXtal32MRadioBiasing.
+ * When BLEB radio block is disabled, clocks are not enabled for this HW block.
+ * ONLY ONE OF vRadio_DisableZBRadio or vRadio_DisableBLERadio can be called.
+ * IF BOTH APIS ARE CALLED, ONLY THE FIRST ONE HAS EFFECT.
+ * IT CANNOT BE REVERSED. NEED HW RESET TO USE BLE RADIO AGAIN.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_DisableBLERadio(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_EnableBLEFastTX
+ *
+ * DESCRIPTION:
+ * Enable keeping G1 and G2 on to give more time between RX and TX.
+ * On ES2MF it is also possible to keep PLL group using bKeepPll parameter.
+ *
+ * PARAMETERS:
+ * bool bKeepPll: when true, PLL group is kept active (ES2MF only, no effect
+ *                otherwise)
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_EnableBLEFastTX(bool bKeepPll);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_DisableBLEFastTX
+ *
+ * DESCRIPTION:
+ * Disable keeping G1 and G2 on to give more time between RX and TX.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_DisableBLEFastTX(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Disable_DCO_DAC
+ *
+ * DESCRIPTION:
+ * Disable keeping DCO DAC always on. By default vRadio_ActivateXtal32MRadioBiasing
+ * and vRadio_RadioInit force DCO DAC to on state to ensure it is ready to operate
+ * at the very beginning of RX process. If no RX is foreseen before next powerdown or sleep
+ * DCO DAC can be disable to reduce power consumption.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_Disable_DCO_DAC(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_ZBtoBLE
+ *
+ * DESCRIPTION:
+ * Change some settings needed when switching from ZB to BLE.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_ZBtoBLE(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_BLEtoZB
+ *
+ * DESCRIPTION:
+ * Change some settings needed when switching from BLE to ZB.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_BLEtoZB(void);
+
+/****************************************************************************
+ *
+ * NAME:       u16Radio_Get_Next_Recal_Duration
+ *
+ * DESCRIPTION:
+ * Returns estimate time duration of the next calibration. This estimate is
+ * based on the last temperature provided by the vRadio_Temp_Update,
+ * the temperature of the last calibration and the operations to do for this
+ * calibrations.
+ * If no calibration is needed or vRadio_RadioInit has not bee called before,
+ * the API returns 0. Otherwise it returns the estimated duration in us.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+uint32_t u32Radio_Get_Next_Recal_Duration(void);
+
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_AntennaDiversityTxRxEnable
+ *
+ * DESCRIPTION:
+ * Enables Antenna Diversity for Tx and/or Rx.
+ *
+ * PARAMETERS:
+ * bool bRxEnabled: true to enable Rx AD, false to disable it
+ * bool bTxEnabled: true to enable Tx AD, false to disable it
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_AntennaDiversityTxRxEnable(bool bRxEnabled, bool bTxEnabled);
+/****************************************************************************
+ *
+ * NAME:       vRadio_AntennaDiversityConfigure
+ *
+ * DESCRIPTION:
+ * Configure some AD setings.
+ *
+ * PARAMETERS:
+ * uint16_t rssi_thr: RSSI threshold to switch antenna (10bit fourth dBm in two complement)
+ *                    Default value is 0x278 (-98dBm)
+ * uint8_t rx_timer: Timer before to check received power again (4us steps, 4bits)
+ *                   Default value is 0x8 (32us)
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_AntennaDiversityConfigure(uint16_t rssi_thr, uint8_t rx_timer);
+/****************************************************************************
+ *
+ * NAME:       vRadio_AntennaDiversitySwitch
+ *
+ * DESCRIPTION:
+ * Toggle antenna selection.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_AntennaDiversitySwitch(void);
+/****************************************************************************
+ *
+ * NAME:       u8Radio_AntennaDiversityStatus
+ *
+ * DESCRIPTION:
+ * Returns current selected antenna.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * Selected antenna (0 or 1) on uint8_t .
+ *
+ ****************************************************************************/
+uint8_t u8Radio_AntennaDiversityStatus(void);
+
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_SetBLEdpTopEmAddr
+ *
+ * DESCRIPTION:
+ * Configure LL_EM_BASE_ADDRESS of BLEMODEM parameter.
+ *
+ * PARAMETERS:
+ * uint32_t em_addr: EM address.
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_SetBLEdpTopEmAddr(uint32_t em_addr);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RADIO_H_ */
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/lib/libRadio.a b/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/lib/libRadio.a
new file mode 100755
index 0000000..b4e3ae9
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/framework/XCVR/lib/libRadio.a
Binary files differ
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/ieee-802.15.4/lib/libMiniMac.a b/third_party/nxp/JN5189DK6/middleware/wireless/ieee-802.15.4/lib/libMiniMac.a
new file mode 100755
index 0000000..4c5bd12
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/ieee-802.15.4/lib/libMiniMac.a
Binary files differ
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/ieee-802.15.4/uMac/Include/MMAC.h b/third_party/nxp/JN5189DK6/middleware/wireless/ieee-802.15.4/uMac/Include/MMAC.h
new file mode 100755
index 0000000..dba5a96
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/ieee-802.15.4/uMac/Include/MMAC.h
@@ -0,0 +1,251 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef MICRO_MAC_H
+#define MICRO_MAC_H
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+#include "jendefs.h"
+
+/****************************************************************************/
+/***        Macro/Type Definitions                                        ***/
+/****************************************************************************/
+
+typedef struct
+{
+    uint32 u32L;  /**< Low word */
+    uint32 u32H;  /**< High word */
+} tsExtAddr;
+
+typedef union
+{
+    uint16    u16Short;
+    tsExtAddr sExt;
+} tuAddr;
+
+/* Structure for building a MAC frame, where the MAC header alignment is
+   handled by the hardware */
+typedef struct
+{
+    uint8           u8PayloadLength;
+    uint8           u8SequenceNum;
+    uint16          u16FCF;
+    uint16          u16DestPAN;
+    uint16          u16SrcPAN;
+    tuAddr          uDestAddr;
+    tuAddr          uSrcAddr;
+    uint16          u16FCS;
+    uint16          u16Unused;
+    union
+    {
+        uint8     au8Byte[127]; /* Payload as both bytes and words */
+        uint32    au32Word[32];
+    } uPayload;
+} tsMacFrame;
+
+/* Structure for building a PHY frame, where the MAC header format is
+   undefined */
+typedef struct
+{
+    uint8           u8PayloadLength;
+    uint8           au8Padding[3];
+    union
+    {
+        uint8     au8Byte[127]; /* Payload as both bytes and words */
+        uint32    au32Word[32];
+    } uPayload;
+} tsPhyFrame;
+
+typedef struct
+{
+    uint8  u8SecurityLevel;
+    uint8  u8KeyIdMode;
+    uint8  u8KeyIndex;
+    bool_t bPassedSecurity;
+} tsSecurity;
+
+typedef struct
+{
+    tsMacFrame     sFrameBody;
+    tsSecurity     sSecurityData;
+    uint32         u32Timestamp;
+    uint8          u8LinkQuality;
+    uint8          u8Msq;
+} tsRxFrameFormat;
+
+/* Options for reception, to pass to vMMAC_StartReceive. User should select
+   one from each pair of options, and logical OR the options together */
+typedef enum
+{
+    /* Receive start time: now or delayed */
+    E_MMAC_RX_START_NOW        = 0x0002,
+    E_MMAC_RX_DELAY_START      = 0x0003,
+
+    /* Timing alignment for auto ack transmission: normal or aligned to
+       backoff clock (used in CAP period in beacon networks) */
+    E_MMAC_RX_ALIGN_NORMAL     = 0x0000,
+    E_MMAC_RX_ALIGNED          = 0x0004,
+
+    /* Wait for auto ack and retry: don't use or use */
+    E_MMAC_RX_NO_AUTO_ACK      = 0x0000,
+    E_MMAC_RX_USE_AUTO_ACK     = 0x0008,
+
+    /* Malformed packets: reject or accept */
+    E_MMAC_RX_NO_MALFORMED     = 0x0000,
+    E_MMAC_RX_ALLOW_MALFORMED  = 0x0400,
+
+    /* Frame Check Sequence errors: reject or accept */
+    E_MMAC_RX_NO_FCS_ERROR     = 0x0000,
+    E_MMAC_RX_ALLOW_FCS_ERROR  = 0x0200,
+
+    /* Address matching: enable or disable */
+    E_MMAC_RX_NO_ADDRESS_MATCH = 0x0000,
+    E_MMAC_RX_ADDRESS_MATCH    = 0x0100
+
+} teRxOption;
+
+/* Options for transmission, to pass to vMMAC_StartMacTransmit or
+   vMMAC_StartPhyTransmit. User should select one from each set of options,
+   and logical OR the options together */
+typedef enum
+{
+    /* Transmit start time: now or delayed */
+    E_MMAC_TX_START_NOW       = 0x02,
+    E_MMAC_TX_DELAY_START     = 0x03,
+
+    /* Wait for auto ack and retry: don't use or use */
+    E_MMAC_TX_NO_AUTO_ACK     = 0x00,
+    E_MMAC_TX_USE_AUTO_ACK    = 0x08,
+
+    /* Clear channel assessment: don't use or use, plus option to align to
+       backoff clock */
+    E_MMAC_TX_NO_CCA          = 0x00,
+    E_MMAC_TX_USE_CCA         = 0x10,
+    E_MMAC_TX_USE_CCA_ALIGNED = 0x20
+
+} teTxOption;
+
+/* Flags for receive status, as returned by u32MMAC_GetRxErrors */
+typedef enum
+{
+    E_MMAC_RXSTAT_ERROR     = 0x01, /* Frame check sequence error */
+    E_MMAC_RXSTAT_ABORTED   = 0x02, /* Reception aborted by user */
+    E_MMAC_RXSTAT_MALFORMED = 0x20  /* Frame was malformed */
+} teRxStatus;
+
+/* Flags for transmit status, as returned by u32MMAC_GetTxErrors */
+typedef enum
+{
+    E_MMAC_TXSTAT_CCA_BUSY = 0x01, /* Channel wasn't free */
+    E_MMAC_TXSTAT_NO_ACK   = 0x02, /* Ack requested but not seen */
+    E_MMAC_TXSTAT_ABORTED  = 0x04, /* Transmission aborted by user */
+    E_MMAC_TXSTAT_TXTO     = 0x20, /* Radio transmission timeout */
+    E_MMAC_TXSTAT_TXPCTO   = 0x40  /* Modem transmission timeout */
+} teTxStatus;
+
+/* Flags for interrupt status, as returned to handler registered with
+   vMMAC_EnableInterrupts and as used in the mask passed to
+   vMMAC_ConfigureInterruptSources, u32MMAC_PollInterruptSource,
+   u32MMAC_PollInterruptSourceUntilFired */
+typedef enum
+{
+    E_MMAC_INT_TX_COMPLETE  = 0x01, /* Transmission attempt has finished */
+    E_MMAC_INT_RX_HEADER    = 0x02, /* MAC header has been received */
+    E_MMAC_INT_RX_COMPLETE  = 0x04  /* Complete frame has been received */
+} teIntStatus;
+
+/* CCA mode to use when transmitting. Use with vMMAC_SetCcaMode(). Default is
+   E_MMAC_CCAMODE_ENERGY */
+typedef enum
+{
+    E_MMAC_CCAMODE_ENERGY            = 0x01, /* Energy above threshold */
+    E_MMAC_CCAMODE_CARRIER           = 0x02, /* Carrier sense */
+    E_MMAC_CCAMODE_ENERGY_OR_CARRIER = 0x03  /* Either energy or carrier */
+} teCcaMode;
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+/* Initialisation */
+PUBLIC void vMMAC_Enable(void);
+PUBLIC void vMMAC_Disable(void);
+PUBLIC void vMMAC_ConfigureRadio(void);
+PUBLIC void vMMAC_SetChannel(uint8 u8Channel);
+PUBLIC void vMMAC_SetChannelAndPower(uint8 u8Channel, int i8TxPower);
+PUBLIC int8 i8MMAC_GetTxPowerLevel(void);
+
+/* Interrupt control */
+PUBLIC void vMMAC_EnableInterrupts(void (*prHandler)(uint32 u32Mask));
+PUBLIC void vMMAC_RegisterPhyIntHandler(void (*prHandler)(uint32 u32Mask));
+PUBLIC void vMMAC_ConfigureInterruptSources(uint32 u32Mask);
+PUBLIC uint32 u32MMAC_PollInterruptSource(uint32 u32Mask);
+PUBLIC uint32 u32MMAC_PollInterruptSourceUntilFired(uint32 u32Mask);
+
+/* Miscellaneous */
+PUBLIC uint32 u32MMAC_GetTime(void);
+PUBLIC void vMMAC_RadioOff(void);
+PUBLIC void vMMAC_RadioToOffAndWait(void);
+PUBLIC void vMMAC_SetCutOffTimer(uint32 u32CutOffTime, bool_t bEnable);
+PUBLIC void vMMAC_SynchroniseBackoffClock(bool_t bEnable);
+PUBLIC void vMMAC_GetMacAddress(tsExtAddr *psMacAddr);
+PUBLIC uint8 u8MMAC_EnergyDetect(uint32 u32DurationSymbols);
+PUBLIC uint32 u32MMAC_GetPhyState(void);
+PUBLIC void vMMAC_RxCtlUpdate(uint32 u32NewValue);
+PUBLIC void vMMAC_AbortRadio(void);
+PUBLIC void vMMAC_SetHighPowerOptions(void);
+PUBLIC void vMMAC_PromiscuousMode(bool_t bPromiscuous);
+PUBLIC void vMMAC_WriteCcaThreshold(uint8 u8CcaThreshold);
+PUBLIC uint8 u8MMAC_ReadCcaThreshold(void);
+
+/* Receive */
+PUBLIC void vMMAC_SetRxAddress(uint32 u32PanId, uint16 u16Short,
+                               tsExtAddr *psMacAddr);
+PUBLIC void vMMAC_SetRxPanId(uint32 u32PanId);
+PUBLIC void vMMAC_SetRxShortAddr(uint16 u16Short);
+PUBLIC void vMMAC_SetRxExtendedAddr(tsExtAddr *psMacAddr);
+PUBLIC void vMMAC_SetRxStartTime(uint32 u32Time);
+PUBLIC void vMMAC_StartMacReceive(tsMacFrame *psFrame, teRxOption eOptions);
+PUBLIC void vMMAC_StartPhyReceive(tsPhyFrame *psFrame, teRxOption eOptions);
+PUBLIC void vMMAC_SetRxFrame(tsRxFrameFormat *pRxFrame);
+PUBLIC void vMMAC_SetRxProm(uint32_t u32Prom);
+PUBLIC bool_t bMMAC_RxDetected(void);
+PUBLIC uint32 u32MMAC_GetRxErrors(void);
+PUBLIC uint32 u32MMAC_GetRxTime(void);
+PUBLIC uint8 u8MMAC_GetRxLqi(uint8 *pu8Msq);
+
+/* Transmit */
+PUBLIC void vMMAC_SetTxParameters(uint8 u8Attempts, uint8 u8MinBE,
+                                  uint8 u8MaxBE, uint8 u8MaxBackoffs);
+PUBLIC void vMMAC_SetTxStartTime(uint32 u32Time);
+PUBLIC void vMMAC_SetCcaMode(teCcaMode eCcaMode);
+PUBLIC void vMMAC_StartMacTransmit(tsMacFrame *psFrame, teTxOption eOptions);
+PUBLIC void vMMAC_StartPhyTransmit(tsPhyFrame *psFrame, teTxOption eOptions);
+PUBLIC void vMMAC_SetTxPend(bool_t bTxPend);
+PUBLIC uint32 u32MMAC_GetTxErrors(void);
+PUBLIC bool_t bMMAC_PowerStatus(void);
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* #ifndef MICRO_MAC_H */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h
new file mode 100755
index 0000000..df7d876
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h
@@ -0,0 +1,379 @@
+/*
+* Copyright 2019-2020 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _APP_OTA_H
+#define _APP_OTA_H
+
+/*!=================================================================================================
+\file       app_ota.h
+\brief      This is the header file for the ota module
+==================================================================================================*/
+
+/*==================================================================================================
+Include Files
+==================================================================================================*/
+#include <openthread/coap.h>
+#include <openthread/thread.h>
+/*==================================================================================================
+Public macros
+==================================================================================================*/
+#define OTA_CLIENT_URI_PATH                     "otaclient"
+#define OTA_SERVER_URI_PATH                     "otaserver"
+
+#ifndef OTA_USE_NWK_DATA
+    #define OTA_USE_NWK_DATA                    FALSE
+#endif
+
+#if OTA_USE_NWK_DATA
+    #define GET_OTA_ADDRESS(otInst)             otThreadGetRloc(otInst)
+#else
+    #define GET_OTA_ADDRESS(otInst)             otThreadGetMeshLocalEid(otInst)
+#endif
+
+/* ota params */
+#define gOtaFileIdentifierNo_c                  0x0BEEF11E
+#define gOtaManufacturerCode_c                  0x04, 0x10
+#define gOtaManufacturerCodeNo_c                0x1004
+#define gOtaCurrentImageType_c                  0x00, 0x00
+#define gOtaCurrentImageTypeNo_c                0x0000
+#define gOtaCurrentFileVersion_c                0x05, 0x40, 0x03, 0x40
+#define gOtaCurrentFileVersionNo_c              0x40034005
+#define gOtaHardwareVersion_c                   0x21, 0x24
+#define gOtaHardwareVersionNo_c                 0x2421
+
+#define gOtaMaxBlockDataSize_c                  64 /* 60 bytes */
+
+#define gOtaServer_MaxSimultaneousClients_c     0x0A
+
+/*==================================================================================================
+Public type definitions
+==================================================================================================*/
+
+/* ota commands */
+typedef enum
+{
+    gOtaCmd_ImageNotify_c          =       0x00,
+    gOtaCmd_QueryImageReq_c,
+    gOtaCmd_QueryImageRsp_c,
+    gOtaCmd_BlockReq_c,
+    gOtaCmd_BlockRsp_c,
+    gOtaCmd_UpgradeEndReq_c,
+    gOtaCmd_UpgradeEndRsp_c,
+    gOtaCmd_ServerDiscovery_c,
+    gOtaCmd_Invalid_c              =       0xFF
+} gOtaCmd_t;
+
+/*! Ota status */
+typedef enum otaStatus_tag
+{
+    gOtaStatus_Success_c                       = 0x00,
+    gOtaStatus_Failed_c                        = 0x01,
+    gOtaStatus_InvalidInstance_c               = 0x02,
+    gOtaStatus_InvalidParam_c                  = 0x03,
+    gOtaStatus_NotPermitted_c                  = 0x04,
+    gOtaStatus_NotStarted_c                    = 0x05,
+    gOtaStatus_NoMem_c                         = 0x06,
+    gOtaStatus_UnsupportedAttr_c               = 0x07,
+    gOtaStatus_EmptyEntry_c                    = 0x08,
+    gOtaStatus_InvalidValue_c                  = 0x09,
+    gOtaStatus_AlreadyStarted_c                = 0x0A,
+    gOtaStatus_NoTimers_c                      = 0x0B,
+    gOtaStatus_NoUdpSocket_c                   = 0x0C,
+	gOtaStatus_FlashError_c                    = 0x0D,
+    gOtaStatus_TransferTypeNotSupported_c      = 0x0E,
+    gOtaStatus_EntryNotFound_c                 = 0xFF
+} otaStatus_t;
+
+/* OTA File Status */
+typedef enum otaFileStatus_tag
+{
+    gOtaFileStatus_Success_c          = 0x00, /* Success Operation */
+    gOtaFileStatus_NotAuthorized_c    = 0x7E, /* Server is not authorized to upgrade the client. */
+    gOtaFileStatus_Abort_c            = 0x95, /* Failed case when a client or a server decides to abort the upgrade process. */
+    gOtaFileStatus_InvalidImage_c     = 0x96, /* Invalid OTA upgrade image. */
+    gOtaFileStatus_ServerBusy_c       = 0x97, /* Server is busy, retry later. */
+    gOtaFileStatus_NoImageAvailable_c = 0x98, /* No OTA upgrade image available for a particular client. */
+    gOtaFileStatus_ImageTooLarge_c    = 0x99, /* Received OTA image is larger than the available storage space. */
+    gOtaFileStatus_InvalidOperation_c = 0x9A, /* Client encountered an invalid operation error. */
+    gOtaFileStatus_InvalidParameter_c = 0x9B, /* Client encountered an invalid parameter error. */
+    gOtaFileStatus_ExtFlashError_c    = 0x9C, /* Client encountered an external flash error. */
+    gOtaFileStatus_ClientError_c      = 0x9D /* Generic client error. */
+} otaFileStatus_t;
+
+typedef enum otaTransferType_tag
+{
+    gOtaUnicast_c = 0x00,
+    gOtaMulticast_c
+} otaTransferType_t;
+
+/* ota command format */
+typedef struct otaCommand_tag
+{
+    uint8_t commandId;
+    uint8_t pPayload[1];
+} otaCommand_t;
+
+/* ota image notify command format*/
+typedef struct otaServerCmd_ImageNotify_tag
+{
+    uint8_t commandId;
+    uint8_t transferType;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t imageSize[4];
+    uint8_t fileSize[4];
+    uint8_t fileVersion[4];
+    uint8_t serverDownloadPort[2];
+    uint8_t fragmentSize[2];
+} otaServerCmd_ImageNotify_t;
+
+/* ota query image req command format*/
+typedef struct otaCmd_QueryImageReq_tag
+{
+    uint8_t commandId;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+    uint8_t hardwareVersion[2];
+} otaCmd_QueryImageReq_t;
+
+/* ota query image rsp - success */
+typedef struct otaCmd_QueryImageRspSuccess_tag
+{
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+    uint8_t fileSize[4];
+    uint8_t serverDownloadPort[2];
+} otaCmd_QueryImageRspSuccess_t;
+
+/* ota query image rsp - wait */
+typedef struct otaCmd_QueryImageRspWait_tag
+{
+    uint8_t currentTime[4];
+    uint8_t requestTime[4];
+} otaCmd_QueryImageRspWait_t;
+
+/* ota query image rsp command format*/
+typedef struct otaCmd_QueryImageRsp_tag
+{
+    uint8_t commandId;
+    uint8_t status;
+    union
+    {
+        otaCmd_QueryImageRspSuccess_t success;
+        otaCmd_QueryImageRspWait_t wait;
+    } data;
+} otaCmd_QueryImageRsp_t;
+
+/* ota block req command format*/
+typedef struct otaCmd_BlockReq_tag
+{
+    uint8_t commandId;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+    uint8_t fileOffset[4];
+    uint8_t maxDataSize;
+} otaCmd_BlockReq_t;
+
+/* ota block rsp - success */
+typedef struct otaCmd_BlockRspSuccess_tag
+{
+    uint8_t fileVersion[4];
+    uint8_t fileOffset[4];
+    uint8_t dataSize;
+    uint8_t pData[1];
+} otaCmd_BlockRspSuccess_t;
+
+/* ota block rsp - wait for data */
+typedef struct otaCmd_BlockRspWaitForData_tag
+{
+    uint8_t currentTime[4];
+    uint8_t requestTime[4];
+} otaCmd_BlockRspWaitForData_t;
+
+/* ota block rsp command format*/
+typedef struct otaCmd_BlockRsp_tag
+{
+    uint8_t commandId;
+    uint8_t status;
+    union
+    {
+        otaCmd_BlockRspSuccess_t success;
+        otaCmd_BlockRspWaitForData_t wait;
+    } data;
+} otaCmd_BlockRsp_t;
+
+/* ota upgrade end req command format*/
+typedef struct otaCmd_UpgradeEndReq_tag
+{
+    uint8_t commandId;
+    uint8_t status;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+} otaCmd_UpgradeEndReq_t;
+
+/* ota upgrade end rsp - success */
+typedef struct otaCmd_UpgradeEndRspSuccess_tag
+{
+    uint8_t currentTime[4];     /* milliseconds */
+    uint8_t upgradeTime[4];     /* milliseconds */
+    uint8_t fileVersion[4];
+} otaCmd_UpgradeEndRspSuccess_t;
+
+/* ota upgrade end rsp - wait for data */
+typedef struct otaCmd_UpgradeEndRspWaitForData_tag
+{
+    uint8_t currentTime[4];
+    uint8_t requestTime[4];
+} otaCmd_UpgradeEndRspWaitForData_t;
+
+/* ota upgrade end rsp command format*/
+typedef struct otaCmd_UpgradeEndRsp_tag
+{
+    uint8_t commandId;
+    uint8_t status;
+    union
+    {
+        otaCmd_UpgradeEndRspSuccess_t success;
+        otaCmd_UpgradeEndRspWaitForData_t wait;
+    } data;
+} otaCmd_UpgradeEndRsp_t;
+
+/* ota upgrade server discovery command format */
+typedef struct otaCmd_ServerDiscovery_tag
+{
+    uint8_t commandId;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+} otaCmd_ServerDiscovery_t;
+
+/* ota file header */
+typedef struct otaFileHeader_tag
+{
+    uint8_t fileIdentifier[4];
+    uint8_t headerVersion[2];
+    uint8_t headerLength[2];
+    uint8_t fieldControl[2];
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+    uint8_t stackVersion[2];
+    uint8_t headerString[32];
+    uint8_t totalImageSize[4];
+    uint8_t minHwVersion[2];
+    uint8_t maxHwVersion[2];
+} otaFileHeader_t;
+
+typedef struct otaFileSubElement_tag
+{
+    uint8_t id[2];
+    uint8_t length[4];
+} otaFileSubElement_t;
+
+/* OTA Server Serial Protocol */
+
+/* Image notify command format */
+typedef struct otaServer_ImageNotify_tag
+{
+    uint8_t deviceId[2];
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t imageSize[4];
+    uint8_t fileSize[4];
+    uint8_t fileVersion[4];
+} otaServer_ImageNotify_t;
+
+/* OTA unicast and multicast finished percentage information structures */
+typedef struct otaServerUnicastClientEntry_tag
+{
+    uint16_t clientId;
+    uint8_t percentage;
+} otaServerUnicastClientEntry_t;
+
+typedef struct otaServerPercentageInfo_tag
+{
+	uint8_t otaType;
+	uint8_t multicastPercentage;
+	otaServerUnicastClientEntry_t unicastEntry[gOtaServer_MaxSimultaneousClients_c];
+} otaServerPercentageInfo_t;
+
+/* ota server operation mode */
+typedef enum
+{
+    gOtaServerOpMode_Reserved_c = 0,
+    gOtaServerOpMode_Standalone_c,           /* requires an external memory or a reserved region of internal MCU flash to keep the client image */
+    gOtaServerOpMode_Dongle_c,               /* without internal/external memory capacity */
+} otaServerOpMode_t;
+
+/*==================================================================================================
+Public global variables declarations
+==================================================================================================*/
+
+extern otCoapResource gOTA_CLIENT_URI_PATH;
+extern otCoapResource gOTA_SERVER_URI_PATH;
+
+/*==================================================================================================
+Public function prototypes
+==================================================================================================*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!*************************************************************************************************
+\public
+\fn  otaStatus_t OtaServerInit(taskMsgQueue_t *pMsgQueue)
+\brief  Initialize OTA server application
+
+\param  [in]    pMsgQueue   Pointer to task message queue
+
+\return   otaStatus_t
+ ***************************************************************************************************/
+otaStatus_t OtaServerInit(otInstance *pOtInstance);
+
+/*!*************************************************************************************************
+\public
+\fn  otaStatus_t OtaServer_StartOta()
+\brief  Start OTA process
+
+\param  [in]    otaType        Type of OTA process (unicast or multicast)
+\param  [in]    pFilePath      Path to binary
+
+\return         otaStatus_t    Status of the operation
+ ***************************************************************************************************/
+otaStatus_t OtaServer_StartOta(uint8_t otaType, const char *pFilePath);
+
+/*!*************************************************************************************************
+\fn     otaResult_t OtaServer_StopOta(void)
+\brief  Process Stop OTA command received from an external application.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+otaStatus_t OtaServer_StopOta(void);
+
+/*!*************************************************************************************************
+\fn     void OtaServer_CheckTime(void)
+\brief  This function is used to check if a timer callback for OTA needs to be called.
+***************************************************************************************************/
+void OtaServer_CheckTime(void);
+
+/*!*************************************************************************************************
+\fn     void OtaServer_GetOtaStatus(otaServerPercentageInfo_t *pData)
+\brief  This function is used to check the status of the OTA transfer.
+
+\param  [in]    pData        Pointer to output structure
+***************************************************************************************************/
+void OtaServer_GetOtaStatus(otaServerPercentageInfo_t *pData);
+
+#ifdef __cplusplus
+}
+#endif
+
+/*================================================================================================*/
+#endif  /*  _APP_OTA_H */
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c
new file mode 100755
index 0000000..8c7792a
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c
@@ -0,0 +1,2081 @@
+/*
+* Copyright 2019-2020 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+/*!=================================================================================================
+\file       app_ota_server.c
+\brief      This is a public source file for the OTA server module
+==================================================================================================*/
+
+/*==================================================================================================
+Include Files
+==================================================================================================*/
+
+/* Application */
+#include <openthread/udp.h>
+#include <openthread/coap.h>
+#include <openthread/instance.h>
+#include <openthread/error.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/alarm-micro.h>
+#include <openthread/ip6.h>
+#include <openthread/random_noncrypto.h>
+
+#include "app_ota.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "network_utils.h"
+
+/*==================================================================================================
+Private macros
+==================================================================================================*/
+
+#ifndef OTA_SERVER_DEFAULT_PORT
+    #define OTA_SERVER_DEFAULT_PORT (61630)
+#endif
+
+#ifndef gOtaServer_DefaultTransferType_c
+    #define gOtaServer_DefaultTransferType_c             gOtaMulticast_c
+#endif
+
+#define gOtaServer_MinDelayForEndRequestMs_c             20000
+#define gOtaServer_MaxDelayForEndRequestMs_c             40000
+#define gOtaServer_InvalidClientId_c                     0xFFFF
+#define gOtaServer_MaxOtaImages_c                        0x01
+
+#define gOtaServer_DelayForNextRequestMs_c               60000   /* 60 seconds */
+#define gOtaServer_ClientSessionExpirationMs_c           30000   /* 30 seconds */
+
+#define gOtaServer_MulticastInterval_c                   500     /* 500 miliseconds */
+#define gOtaServer_MulticastImgNtfInterval_c             1000    /* 1 second */
+#define gOtaServer_MulticastImgNtfRetransmissions_c      4
+#define gOtaServer_MulticastBlockRspInterval_c           300
+#define gOtaServer_MulticastUpgradeEndDelay_c            1000
+#define gOtaServer_MulticastNoOfBlockRsps_c              0
+#define gOtaServer_MulticastWindowSize_c                 32      /* Must be multiple of 8 */
+#define gOtaServer_MulticastWindowRetries_c              0
+#define gOtaServer_MulticastAckTimeout_c                 300
+
+#define gOtaFileVersionPolicies_Upgrade_c       (1<<0)
+#define gOtaFileVersionPolicies_Reinstall_c     (1<<1)
+#define gOtaFileVersionPolicies_Downgrade_c     (1<<2)
+
+#define gOtaFileVersionDefaultPolicies_c         gOtaFileVersionPolicies_Upgrade_c | \
+                                                 gOtaFileVersionPolicies_Reinstall_c | \
+                                                 gOtaFileVersionPolicies_Downgrade_c
+
+/*==================================================================================================
+Private type definitions
+==================================================================================================*/
+/* ota server multicast state: */
+typedef enum
+{
+    gOtaServerMulticastState_NotInit_c = 0,
+    gOtaServerMulticastState_Idle_c,
+    gOtaServerMulticastState_SendImgNtf_c,
+    gOtaServerMulticastState_GenBlockReq_c,
+    gOtaServerMulticastState_WaitForAck_c,
+    gOtaServerMulticastState_SendUpgradeEnd_c,
+    gOtaServerMulticastState_ResetMulticast_c
+} otaServerMulticastState_t;
+
+/* ota server multicast state: */
+typedef enum
+{
+	otaServerClientImageTypeREED = 0x0000,
+	otaServerClientImageTypeED   = 0x0001,
+	otaServerClientImageTypeLPED = 0x0002
+} otaServerClientImageType;
+
+typedef struct otaServerSetup_tag
+{
+    otInstance *pOtInstance;
+    otUdpSocket *pOtaUdpSrvSocket;
+    bool_t            isActive;
+    uint8_t           fileVersionPolicy;
+    otaTransferType_t transferType;
+    uint16_t          downloadPort;
+    /* Multicast parameters */
+    otaServerMulticastState_t multicastState;
+    uint8_t ackBitmask[4];
+    uint32_t currentWindowOffset;
+    uint8_t multicastNoOfImgNtf;
+    uint8_t multicastNoOfBlockRsp;
+    uint8_t multicastNoOfWindowRetries;
+    uint16_t multicastManufacturerCode;
+    uint16_t multicastImageType;
+    uint32_t multicastImageSize;
+    uint32_t multicastFileVersion;
+} otaServerSetup_t;
+
+typedef struct otaServerImageList_tag
+{
+    uint16_t manufCode;
+    uint16_t imageType;
+    uint32_t fileSize;
+    uint32_t imageAddr;
+    uint32_t fileVersion;
+    bool_t isValidEntry;
+} otaServerImageList_t;
+
+typedef struct otaClientInfo_tag
+{
+    otIp6Address  remoteAddr;
+    otIp6Address  sourceAddr;
+    uint16_t  port;
+    uint32_t  timeStamp;
+    uint32_t  dataLen;
+    uint8_t   pData[1];
+} otaClientInfo_t;
+
+typedef struct otaClientSessionInfo_tag
+{
+    otIp6Address remoteAddr;
+    uint32_t timeStamp;
+} otaClientSessionInfo_t;
+
+typedef void ( *otaTmrCallback ) ( void *param );
+
+/*==================================================================================================
+Private function prototypes
+==================================================================================================*/
+/* OTA Server Coap command handlers */
+static void OtaServer_ClientProcess(otaClientInfo_t *pOtaClientInfo);
+static void OtaServer_CmdProcess(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_CmdCheck(uint8_t otaCommand, uint32_t dataLen);
+static otaStatus_t OtaServer_QueryImageReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_BlockReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_UpgradeEndReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_ServerDiscoveryHandler(otaClientInfo_t *pOtaClientInfo);
+static void OtaServer_CoapCb(void *pCtx, otMessage *pMsg, const otMessageInfo *pMsgInfo);
+
+/* OTA Server Coap commands */
+static otaStatus_t OtaServer_SendImageNotifty(otaServer_ImageNotify_t *pImgNtf, otIp6Address *pAddr);
+static otaStatus_t OtaServer_CoapSendImageNotify(otaServer_ImageNotify_t *pImageNotify, otIp6Address *pDestAddr);
+static otaStatus_t OtaServer_CoapSendRsp(otaClientInfo_t *pOtaClientInfo, uint8_t *pData, uint32_t pDataLen);
+static otaStatus_t OtaServer_CoapSendRspWaitAbortData(otaClientInfo_t *pOtaClientInfo, uint8_t status,
+        uint32_t delayInMs);
+
+/* OTA Server utility functions */
+static void OtaServer_SetTimeCallback(otaTmrCallback pFunc, void *pData, uint32_t setTime);
+static void OtaServer_StopTimeCallback(void);
+static bool_t OtaServer_IsClientValid(uint16_t clientId);
+static bool_t OtaServer_RemoveClientFromPercentageInfo(uint16_t clientId);
+static void OtaServer_ResetPercentageInfo(void);
+static otaStatus_t OtaServer_CheckClientSessionTable(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_HandleBlockSocket(bool_t onOff);
+
+/* OTA Server standalone functions: */
+static void OtaServer_InitStandaloneOpMode(void);
+static uint8_t OtaServerStandalone_ValidateImage(uint16_t manufCode, uint16_t imageType, uint32_t fileVersion, bool_t serialProtocol);
+static uint8_t OtaServerStandalone_KeepImageInfo(uint16_t manufCode, uint16_t imageType, uint32_t fileVersion, uint32_t fileSize);
+static otaStatus_t OtaServerStandalone_QueryImageReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServerStandalone_BlockReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServerStandalone_ServerDiscoveryHandler(otaClientInfo_t *pOtaClientInfo);
+
+/* OTA Server Multicast */
+static otaStatus_t OtaServer_InitMulticast(void *pParam);
+static void OtaServer_MulticastMngr(void *pParam);
+static void OtaServer_MulticastTimeoutCb(void *pParam);
+static otaStatus_t OtaServer_SendImgNtf(void *pParam);
+static otaStatus_t OtaServer_ProcessAckTimeout(void *pParam);
+static otaStatus_t OtaServer_MulticastUpgradeEnd(void *pParam);
+static otaStatus_t OtaServer_GenerateBlockReq(void *pParam);
+static void OtaServer_ResetMulticastModule(void *pParam);
+
+/*==================================================================================================
+Private global variables declarations
+==================================================================================================*/
+/* Ota server setup parameters */
+static otaServerSetup_t mOtaServerSetup = {.pOtaUdpSrvSocket = NULL,
+                                           .downloadPort = OTA_SERVER_DEFAULT_PORT,
+                                           .multicastState = gOtaServerMulticastState_NotInit_c,
+                                           .transferType = gOtaServer_DefaultTransferType_c
+                                          };
+
+/* Ota server standalone informations: */
+static otaServerImageList_t mOtaServerImageList[gOtaServer_MaxOtaImages_c];
+static uint32_t mOtaServerTempImageIdx = gOtaServer_MaxOtaImages_c;
+
+/* Ota server percentages information */
+static otaServerPercentageInfo_t mOtaServerPercentageInformation;
+
+static otaClientSessionInfo_t mOtaClientSessionInfoTable[gOtaServer_MaxSimultaneousClients_c];
+static otUdpSocket mOtaUdpSrvSocket;
+
+static char binary_file_path[255];
+/*==================================================================================================
+Public global variables declarations
+==================================================================================================*/
+otCoapResource gOTA_CLIENT_URI_PATH = {.mUriPath = OTA_CLIENT_URI_PATH, .mHandler = NULL/*OtaServer_CoapCb*/, .mContext = NULL, .mNext = NULL };
+otCoapResource gOTA_SERVER_URI_PATH = {.mUriPath = OTA_SERVER_URI_PATH, .mHandler = NULL/*OtaClient_CoapCb*/, .mContext = NULL, .mNext = NULL };
+
+/* Parameters for simple timer callback */
+uint32_t setMilliTime = 0;
+otaTmrCallback gpFunction = NULL;
+void *gpParameter = NULL;
+bool_t callbackIsSet = false;
+
+/*==================================================================================================
+Public functions
+==================================================================================================*/
+/*!*************************************************************************************************
+\fn     void OtaServer_CheckTime(void)
+\brief  This function is used to check if a timer callback for OTA needs to be called.
+***************************************************************************************************/
+void OtaServer_CheckTime(void)
+{
+    if((otPlatAlarmMilliGetNow() > setMilliTime) && (callbackIsSet == true) && (setMilliTime != 0))
+    {
+        setMilliTime = 0;
+
+        if(gpFunction != NULL)
+        {
+            callbackIsSet = false;
+            gpFunction(gpParameter);
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\fn     otaStatus_t OtaServerInit(taskMsgQueue_t *pMsgQueue)
+\brief  Initialize OTA server application.
+
+\param  [in]    pMsgQueue      Pointer to task message queue
+
+\return         otaStatus_t    Status of the operation
+ ***************************************************************************************************/
+otaStatus_t OtaServerInit
+(
+    otInstance *pOtInstance
+)
+{
+    otaStatus_t otaStatus = gOtaStatus_Success_c;
+
+    if (pOtInstance == NULL)
+    {
+        otaStatus = gOtaStatus_InvalidInstance_c;
+    }
+
+    if (otaStatus == gOtaStatus_Success_c)
+    {
+        /* Register Services in COAP */
+        mOtaServerSetup.pOtInstance = pOtInstance;
+        otCoapStart(mOtaServerSetup.pOtInstance, OT_DEFAULT_COAP_PORT);
+        gOTA_CLIENT_URI_PATH.mContext = mOtaServerSetup.pOtInstance;
+        gOTA_CLIENT_URI_PATH.mHandler = OtaServer_CoapCb;
+        otCoapAddResource(mOtaServerSetup.pOtInstance, &gOTA_CLIENT_URI_PATH);
+
+        // Set operation mode to standalone
+        mOtaServerSetup.isActive = false;
+
+        OtaServer_ResetPercentageInfo();
+
+        memset(&mOtaClientSessionInfoTable, 0x00,
+               sizeof(otaClientSessionInfo_t) * gOtaServer_MaxSimultaneousClients_c);
+        mOtaServerSetup.fileVersionPolicy = gOtaFileVersionDefaultPolicies_c;
+        memset(&binary_file_path[0], 0x00, sizeof(binary_file_path));
+
+        if (true == mOtaServerSetup.isActive)
+        {
+            OtaServer_HandleBlockSocket(true);
+        }
+    }
+
+    return otaStatus;
+}
+
+/*!*************************************************************************************************
+\public
+\fn  otaStatus_t OtaServer_StartOta()
+\brief  Start OTA process
+
+\param  [in]    otaType        Type of OTA process (unicast or multicast)
+\param  [in]    pFilePath      Path to binary
+
+\return         otaStatus_t    Status of the operation
+ ***************************************************************************************************/
+otaStatus_t OtaServer_StartOta(uint8_t otaType, const char *pFilePath)
+{
+    otaServer_ImageNotify_t *pImageNotify = NULL;
+    otaStatus_t status = gOtaStatus_Success_c;
+
+    if ((otaType != gOtaUnicast_c) && (otaType != gOtaMulticast_c))
+    {
+        status = gOtaStatus_Failed_c;
+        goto exit;
+    }
+
+    // Check if device is connected before starting OTA
+    if (otThreadGetDeviceRole(mOtaServerSetup.pOtInstance) < OT_DEVICE_ROLE_CHILD)
+    {
+        status = gOtaStatus_NotPermitted_c;
+        goto exit;
+    }
+
+    // Check if OTA process is already active
+    if (mOtaServerSetup.isActive == true)
+    {
+        status = gOtaStatus_AlreadyStarted_c;
+        goto exit;
+    }
+
+    if (pFilePath != NULL)
+    {
+        memcpy(binary_file_path, pFilePath, strlen(pFilePath));
+
+        if (!(access(binary_file_path, F_OK) != -1))
+        {
+            status = gOtaStatus_InvalidValue_c;
+            goto exit;
+        }
+    }
+    else
+    {
+        status = gOtaStatus_EmptyEntry_c;
+        goto exit;
+    }
+
+    // Set multicast addresses used in OTA process
+    NWKU_OtSetMulticastAddresses(mOtaServerSetup.pOtInstance);
+    mOtaServerSetup.transferType = otaType;
+
+    OtaServer_ResetPercentageInfo();
+    mOtaServerPercentageInformation.otaType = otaType;
+
+    /* clear current image entries */
+    for (uint8_t i = 0; i < gOtaServer_MaxOtaImages_c; i++)
+    {
+        mOtaServerImageList[i].isValidEntry = false;
+    }
+
+    mOtaServerTempImageIdx = gOtaServer_MaxOtaImages_c;
+
+    OtaServer_InitStandaloneOpMode();
+
+    if (mOtaServerImageList[mOtaServerTempImageIdx].imageType == otaServerClientImageTypeLPED)
+    {
+        if (otaType == gOtaMulticast_c)
+        {
+            mOtaServerSetup.transferType = gOtaUnicast_c;
+            mOtaServerPercentageInformation.otaType = gOtaUnicast_c;
+            status = gOtaStatus_TransferTypeNotSupported_c;
+        }
+    }
+
+    // OTA Multicast parameters. Not used for OTA unicast.
+    if (mOtaServerSetup.transferType == gOtaMulticast_c)
+    {
+        // OTA multicast.
+        pImageNotify = (otaServer_ImageNotify_t *)calloc(1, sizeof(otaServer_ImageNotify_t));
+    }
+
+    OtaServer_SendImageNotifty(pImageNotify, &in6addr_realmlocal_allthreadnodes);
+
+    if (mOtaServerSetup.transferType == gOtaMulticast_c)
+    {
+        OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, (void *)pImageNotify, 100);
+    }
+
+exit:
+    return status;
+}
+
+/*!*************************************************************************************************
+\fn     otaResult_t OtaServer_StopOta(void)
+\brief  Process Stop OTA command received from an external application.
+
+\return         otaStatus_t    Result of the operation
+***************************************************************************************************/
+otaStatus_t OtaServer_StopOta
+(
+    void
+)
+{
+    otaStatus_t result = gOtaStatus_NoMem_c;
+    uint8_t size = sizeof(otaClientInfo_t) - 1 + sizeof(otaCmd_UpgradeEndRsp_t);
+    otaClientInfo_t *pOtaClientInfo;
+
+    pOtaClientInfo = calloc(1, size);
+    mOtaServerSetup.isActive = false;
+
+    /* clear current image entries */
+    for (uint8_t i = 0; i < gOtaServer_MaxOtaImages_c; i++)
+    {
+        mOtaServerImageList[i].isValidEntry = false;
+    }
+
+    mOtaServerTempImageIdx = gOtaServer_MaxOtaImages_c;
+
+    if (pOtaClientInfo)
+    {
+        otaCmd_QueryImageRsp_t queryRsp = {0};
+        uint32_t timeInMs = otPlatAlarmMilliGetNow();
+        uint32_t delayInMs = 0;
+
+        queryRsp.commandId = gOtaCmd_UpgradeEndRsp_c;
+        queryRsp.status = gOtaFileStatus_Abort_c;
+
+        memcpy(&pOtaClientInfo->remoteAddr, &in6addr_realmlocal_allthreadnodes, sizeof(otIp6Address));
+        memcpy(&pOtaClientInfo->sourceAddr, GET_OTA_ADDRESS(mOtaServerSetup.pOtInstance), sizeof(otIp6Address));
+
+        pOtaClientInfo->port = OTA_SERVER_DEFAULT_PORT;
+        pOtaClientInfo->dataLen = size - sizeof(otaClientInfo_t) + 1;
+        pOtaClientInfo->pData[0] = gOtaCmd_UpgradeEndRsp_c;
+
+        memcpy(&queryRsp.data.wait.currentTime, &timeInMs, sizeof(uint32_t));
+        timeInMs = timeInMs + delayInMs;
+        memcpy(&queryRsp.data.wait.requestTime, &timeInMs, sizeof(uint32_t));
+
+        // Send the Block Req to the OTA Server.
+        result = OtaServer_CoapSendRsp(pOtaClientInfo, (uint8_t *)&queryRsp, sizeof(queryRsp));
+    }
+
+    OtaServer_ResetMulticastModule(NULL);
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\fn     void OtaServer_GetOtaStatus(otaServerPercentageInfo_t *pData)
+\brief  This function is used to check the status of the OTA transfer.
+
+\param  [in]    pData        Pointer to output structure
+***************************************************************************************************/
+void OtaServer_GetOtaStatus(otaServerPercentageInfo_t *pData)
+{
+    memcpy(pData, (uint8_t *)&mOtaServerPercentageInformation, sizeof(mOtaServerPercentageInformation));
+}
+
+/*==================================================================================================
+Private functions
+==================================================================================================*/
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_SetTimeCallback(otaTmrCallback pFunc, void *param, uint32_t setTime)
+\brief  This function sets a timer callback for OTA functions.
+
+\param  [in]    pFunc           Callback function
+\param  [in]    pData           Callback function parameter
+\param  [in]    setTime         Set time for callback in milliseconds
+***************************************************************************************************/
+static void OtaServer_SetTimeCallback
+(
+    otaTmrCallback pFunc,
+    void *pData,
+    uint32_t setTime
+)
+{
+    if(mOtaServerSetup.isActive == true)
+    {
+        if(pFunc != NULL)
+        {
+            gpFunction = pFunc;
+        }
+
+        gpParameter = pData;
+        setMilliTime = otPlatAlarmMilliGetNow() + setTime;
+        callbackIsSet = true;
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_StopTimeCallback(void)
+\brief  This function stops and clears the timer callback for OTA functions.
+***************************************************************************************************/
+static void OtaServer_StopTimeCallback(void)
+{
+    gpFunction = NULL;
+    gpParameter = NULL;
+    setMilliTime = 0;
+    callbackIsSet = false;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_CoapCb(void *pCtx, otMessage *pMsg, const otMessageInfo *pMsgInfo)
+\brief  This function is the callback function for CoAP message.
+
+\param  [in]    pCtx            Pointer to OpenThread context
+\param  [in]    pMsg            Pointer to CoAP message
+\param  [in]    pMsgInfo        Pointer to CoAP message information
+***************************************************************************************************/
+static void OtaServer_CoapCb
+(
+    void *pCtx,
+    otMessage *pMsg,
+    const otMessageInfo *pMsgInfo
+)
+{
+    uint16_t dataLen = otMessageGetLength(pMsg) - otMessageGetOffset(pMsg);
+    uint8_t otaCommand = gOtaCmd_Invalid_c;
+
+    otMessageRead(pMsg, otMessageGetOffset(pMsg), (void *)&otaCommand, sizeof(otaCommand));
+
+    if (gOtaStatus_Success_c == OtaServer_CmdCheck(otaCommand, dataLen))
+    {
+        otaClientInfo_t *pOtaClientInfo = (otaClientInfo_t *)calloc(1, sizeof(otaClientInfo_t) + dataLen);
+    
+        if (NULL != pOtaClientInfo)
+        {
+            otIp6Address nullAddr = {0};
+
+            /* Save client info params */
+            otMessageRead(pMsg, otMessageGetOffset(pMsg), (void *)&pOtaClientInfo->pData, dataLen);
+            pOtaClientInfo->dataLen = dataLen;
+            memcpy(&pOtaClientInfo->remoteAddr, &pMsgInfo->mPeerAddr, sizeof(otIp6Address));
+
+            if (memcmp(&pOtaClientInfo->remoteAddr, &nullAddr, sizeof(otIp6Address)))
+            {
+                memcpy(&pOtaClientInfo->sourceAddr, &in6addr_realmlocal_allthreadnodes, sizeof(otIp6Address));
+            }
+
+            pOtaClientInfo->timeStamp = otPlatAlarmMilliGetNow();
+            OtaServer_ClientProcess(pOtaClientInfo);
+        }
+    }
+    (void)pCtx;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaClient_UdpServerService(uint8_t *pInData)
+\brief  This function is the callback function for Ota server socket.
+
+\param  [in]    pCtx            Pointer to OpenThread context
+\param  [in]    pMsg            Pointer to CoAP message
+\param  [in]    pMsgInfo        Pointer to CoAP message information
+***************************************************************************************************/
+static void OtaClient_UdpServerService
+(
+    void *pCtx,
+    otMessage *pMsg,
+    const otMessageInfo *pMsgInfo
+)
+{
+    uint16_t dataLen = otMessageGetLength(pMsg) - otMessageGetOffset(pMsg);
+    uint8_t otaCommand = gOtaCmd_Invalid_c;
+
+    otMessageRead(pMsg, otMessageGetOffset(pMsg), (void *)&otaCommand, sizeof(otaCommand));
+
+    if (gOtaCmd_BlockReq_c == otaCommand)
+    {
+        otaClientInfo_t *pOtaClientInfo = (otaClientInfo_t *)calloc(1, sizeof(otaClientInfo_t) + dataLen);
+
+        if (NULL != pOtaClientInfo)
+        {
+            /* Save client info params */
+            otMessageRead(pMsg, otMessageGetOffset(pMsg), (void *)pOtaClientInfo->pData, dataLen);
+            memcpy(&pOtaClientInfo->remoteAddr, (void *)&pMsgInfo->mPeerAddr, sizeof(otIp6Address));
+            memcpy(&pOtaClientInfo->sourceAddr, (void *)&pMsgInfo->mSockAddr, sizeof(otIp6Address));
+            pOtaClientInfo->port = pMsgInfo->mPeerPort;
+            pOtaClientInfo->dataLen = dataLen;
+            pOtaClientInfo->timeStamp = otPlatAlarmMilliGetNow();
+            OtaServer_ClientProcess(pOtaClientInfo);
+        }
+    }
+    (void) pCtx;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_SendImageNotifty(otaServer_ImageNotify_t *pImgNtf, otIp6Address *pAddr)
+\brief  This function is used for the transmission of Image Notification commands.
+
+\param  [in]    pImgNtf         Pointer to the otaServer_ImageNotify_t structure
+\param  [in]    pAddr           Pointer to peer address
+
+\return         otaStatus_t     Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_SendImageNotifty
+(
+    otaServer_ImageNotify_t *pImgNtf,
+    otIp6Address *pAddr
+)
+{
+    bool_t status = false;
+    FILE *pFile = fopen(binary_file_path,"rb");
+    
+    if(pFile != NULL)
+    {
+        otaServer_ImageNotify_t imageNotify;
+        otaFileSubElement_t imageTag;
+
+        /* transfer completed */
+        mOtaServerImageList[mOtaServerTempImageIdx].isValidEntry = true;
+        mOtaServerSetup.isActive = true;
+
+        /* Set position after file header */
+        fseek(pFile, mOtaServerImageList[mOtaServerTempImageIdx].imageAddr + sizeof(otaFileHeader_t), SEEK_SET);
+
+        if(fread((void *)&imageTag, sizeof(otaFileSubElement_t), 1, pFile))
+        {
+            // Inform clients that a new image is available
+            memset(&imageNotify, 0, sizeof(otaServer_ImageNotify_t));
+            memcpy(&imageNotify.fileVersion, &mOtaServerImageList[mOtaServerTempImageIdx].fileVersion, sizeof(uint32_t));
+            memcpy(&imageNotify.imageType, &mOtaServerImageList[mOtaServerTempImageIdx].imageType, sizeof(uint16_t));
+            memcpy(&imageNotify.manufacturerCode, &mOtaServerImageList[mOtaServerTempImageIdx].manufCode, sizeof(uint16_t));
+            memcpy(&imageNotify.imageSize, &imageTag.length, sizeof(imageNotify.imageSize));
+            memcpy(&imageNotify.fileSize, &mOtaServerImageList[mOtaServerTempImageIdx].fileSize, sizeof(uint32_t));
+        }
+
+        /* return image notify data for multicast usage */
+        if(pImgNtf != NULL)
+        {
+            memcpy(pImgNtf, &imageNotify, sizeof(otaServer_ImageNotify_t));
+        }
+
+        status = (OtaServer_CoapSendImageNotify(&imageNotify, pAddr) == gOtaStatus_Success_c) ? true : false;
+    }
+
+    if (pFile != NULL)
+    {
+        fclose(pFile);
+    }
+
+    return (status == true) ? gOtaStatus_Success_c : gOtaStatus_Failed_c;
+}
+
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_ClientProcess(uint8_t *param)
+\brief  This function is used to process ota client commands.
+
+\param  [in]    pOtaClientInfo    Pointer to pOtaClientInfo structure
+***************************************************************************************************/
+static void OtaServer_ClientProcess
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    bool_t isServerBusy = false;
+    uint16_t clientId;
+
+    if (false == mOtaServerSetup.isActive)
+    {
+        /* Server is not active -  send back a Rsp command with status no image available */
+        OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo, gOtaFileStatus_NoImageAvailable_c, 0);
+    }
+    else
+    {
+        if ((gOtaStatus_Success_c == OtaServer_CheckClientSessionTable(pOtaClientInfo)) &&
+                (gOtaStatus_Success_c == OtaServer_HandleBlockSocket(true)))
+        {
+            if (mOtaServerSetup.transferType == gOtaUnicast_c)
+            {
+                clientId = (pOtaClientInfo->remoteAddr.mFields.m8[14] << 8) + pOtaClientInfo->remoteAddr.mFields.m8[15];
+
+                if((clientId != gOtaServer_InvalidClientId_c) && OtaServer_IsClientValid(clientId))
+                {
+                    OtaServer_CmdProcess(pOtaClientInfo);
+                }
+                else
+                {
+                    isServerBusy = true;
+                }
+            }
+            else if (mOtaServerSetup.transferType == gOtaMulticast_c)
+            {
+                OtaServer_CmdProcess(pOtaClientInfo);
+            }
+        }
+        else
+        {
+            isServerBusy = true;
+        }
+
+        if (isServerBusy)
+        {
+            OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo,
+                                               gOtaFileStatus_ServerBusy_c,
+                                               gOtaServer_DelayForNextRequestMs_c);
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CheckClientSessionTable(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to check if the server can process this new client request.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_CheckClientSessionTable
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    uint8_t idxInfoTable;
+    uint8_t firstExpiredEntry = gOtaServer_MaxSimultaneousClients_c;
+
+    for (idxInfoTable = 0; idxInfoTable < gOtaServer_MaxSimultaneousClients_c; idxInfoTable++)
+    {
+        if (memcmp(&pOtaClientInfo->remoteAddr, &mOtaClientSessionInfoTable[idxInfoTable].remoteAddr, sizeof(otIp6Address)))
+        {
+            mOtaClientSessionInfoTable[idxInfoTable].timeStamp = pOtaClientInfo->timeStamp;
+            return gOtaStatus_Success_c;
+        }
+
+        if (((mOtaClientSessionInfoTable[idxInfoTable].timeStamp == 0) ||
+                (mOtaClientSessionInfoTable[idxInfoTable].timeStamp + (gOtaServer_ClientSessionExpirationMs_c) < pOtaClientInfo->timeStamp)) &&
+                (firstExpiredEntry == gOtaServer_MaxSimultaneousClients_c))
+        {
+            firstExpiredEntry = idxInfoTable;
+        }
+    }
+
+    if (firstExpiredEntry < gOtaServer_MaxSimultaneousClients_c)
+    {
+        memcpy(&mOtaClientSessionInfoTable[firstExpiredEntry].remoteAddr, &pOtaClientInfo->remoteAddr, sizeof(otIp6Address));
+        mOtaClientSessionInfoTable[firstExpiredEntry].timeStamp = pOtaClientInfo->timeStamp;
+        status = gOtaStatus_Success_c;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CmdCheck(void *pData, uint32_t dataLen)
+\brief  This function is used to check if ota client command is valid.
+
+\param  [in]    pData          OTA cmd data
+\param  [in]    dataLen        OTA cmd length
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_CmdCheck
+(
+    uint8_t otaCommand,
+    uint32_t dataLen
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+
+    switch (otaCommand)
+    {
+        case gOtaCmd_QueryImageReq_c:
+            if (dataLen == sizeof(otaCmd_QueryImageReq_t))
+            {
+                status = gOtaStatus_Success_c;
+            }
+
+            break;
+
+        case gOtaCmd_BlockReq_c:
+            if (dataLen == (sizeof(otaCmd_BlockReq_t)))
+            {
+                status = gOtaStatus_Success_c;
+            }
+
+            break;
+
+        case gOtaCmd_UpgradeEndReq_c:
+            if (dataLen == sizeof(otaCmd_UpgradeEndReq_t))
+            {
+                status = gOtaStatus_Success_c;
+            }
+
+            break;
+
+        case gOtaCmd_ServerDiscovery_c:
+            if (dataLen == sizeof(otaCmd_ServerDiscovery_t))
+            {
+                status = gOtaStatus_Success_c;
+            }
+
+            break;
+
+        default:
+            break;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_CmdProcess(void *param)
+\brief  This function is used to process ota client commands.
+
+\param  [in]    pOtaClientInfo    Pointer to pOtaClientInfo structure
+***************************************************************************************************/
+static void OtaServer_CmdProcess
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    uint8_t otaCommand = *pOtaClientInfo->pData;
+
+    switch (otaCommand)
+    {
+        case gOtaCmd_QueryImageReq_c:
+            (void)OtaServer_QueryImageReqHandler(pOtaClientInfo);
+            break;
+
+        case gOtaCmd_BlockReq_c:
+            (void)OtaServer_BlockReqHandler(pOtaClientInfo);
+            break;
+
+        case gOtaCmd_UpgradeEndReq_c:
+            (void)OtaServer_UpgradeEndReqHandler(pOtaClientInfo);
+            break;
+
+        case gOtaCmd_ServerDiscovery_c:
+            (void)OtaServer_ServerDiscoveryHandler(pOtaClientInfo);
+            break;
+
+        default:
+            free((void *)pOtaClientInfo);
+            break;
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_QueryImageReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a QueryImageReq command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_QueryImageReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    return OtaServerStandalone_QueryImageReqHandler(pOtaClientInfo);
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_BlockReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a BlockRequest command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_BlockReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    return OtaServerStandalone_BlockReqHandler(pOtaClientInfo);
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_UpgradeEndReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process an UpdateEndRequest command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_UpgradeEndReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaCmd_UpgradeEndRsp_t upgradeRsp = {0};
+    uint32_t timeInMs = otPlatAlarmMilliGetNow();
+    /* Get the client status from the received packet */
+    otaFileStatus_t client_status = (otaFileStatus_t) (*(pOtaClientInfo->pData + 1));
+    uint16_t clientId = 0;
+
+    upgradeRsp.commandId = gOtaCmd_UpgradeEndRsp_c;
+    upgradeRsp.status = gOtaStatus_Success_c;
+    memcpy(&upgradeRsp.data.success.currentTime, &timeInMs, sizeof(uint32_t));
+    timeInMs += otRandomNonCryptoGetUint32InRange(gOtaServer_MinDelayForEndRequestMs_c, gOtaServer_MaxDelayForEndRequestMs_c);
+    memcpy(&upgradeRsp.data.success.upgradeTime, &timeInMs, sizeof(uint32_t));
+
+    if (client_status == gOtaFileStatus_Success_c)
+    {
+        (void)OtaServer_CoapSendRsp(pOtaClientInfo, (uint8_t *)&upgradeRsp, sizeof(otaCmd_UpgradeEndRsp_t));
+    }
+
+    NWKU_MemCpyReverseOrder(&clientId, &pOtaClientInfo->remoteAddr.mFields.m8[14], sizeof(uint16_t));
+
+    OtaServer_RemoveClientFromPercentageInfo(clientId);
+
+    if (client_status != gOtaFileStatus_Success_c)
+    {
+        free(pOtaClientInfo);
+    }
+
+    return gOtaStatus_Success_c;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_ServerDiscoveryHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a ServerDiscovery command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_ServerDiscoveryHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    return OtaServerStandalone_ServerDiscoveryHandler(pOtaClientInfo);
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CoapSendImageNotify(otaServer_ImageNotify_t *pThciImageNotify,
+                                                         otIp6Address *pDestAddr)
+\brief  This function is used to send multicast a coap Image notify command to all thread nodes
+
+\param  [in]   pThciImageNotify    Pointer to image notify message
+\param  [in]   pDestAddr           Pointer to IPv6 address
+
+\return        otaStatus_t         Status of the operation
+ ***************************************************************************************************/
+static otaStatus_t OtaServer_CoapSendImageNotify
+(
+    otaServer_ImageNotify_t *pImageNotify,
+    otIp6Address *pDestAddr
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    uint16_t fragmentSize = gOtaMaxBlockDataSize_c;
+    otCoapType coapType = OT_COAP_TYPE_NON_CONFIRMABLE;
+    otCoapCode coapCode = OT_COAP_CODE_POST;
+    otError error = OT_ERROR_NONE;
+
+    otMessage *pMsg = otCoapNewMessage(mOtaServerSetup.pOtInstance, NULL);
+
+    if(pMsg)
+    {
+        otMessageInfo messageInfo = {0};
+        otaServerCmd_ImageNotify_t imageNotify;
+
+        otCoapMessageInit(pMsg, coapType, coapCode);
+        otCoapMessageGenerateToken(pMsg, 4);
+
+        /* Complete command */
+        imageNotify.commandId = gOtaCmd_ImageNotify_c;
+        imageNotify.transferType = mOtaServerSetup.transferType;
+        memcpy(&imageNotify.manufacturerCode, &pImageNotify->manufacturerCode,
+                    sizeof(otaServer_ImageNotify_t) - 2);
+        memcpy(&imageNotify.serverDownloadPort[0], (void *)&mOtaServerSetup.downloadPort, sizeof(uint16_t));
+        memcpy(&imageNotify.fragmentSize[0], &fragmentSize, sizeof(imageNotify.fragmentSize));
+
+        error = otCoapMessageAppendUriPathOptions(pMsg, OTA_SERVER_URI_PATH);
+        error = otCoapMessageSetPayloadMarker(pMsg);
+        error = otMessageAppend(pMsg, (const void *)&imageNotify, sizeof(imageNotify));
+        
+        memset(&messageInfo, 0, sizeof(messageInfo));
+
+        messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
+        memcpy(&messageInfo.mSockAddr, GET_OTA_ADDRESS(mOtaServerSetup.pOtInstance), sizeof(otIp6Address));
+        memcpy(&messageInfo.mPeerAddr, pDestAddr, sizeof(otIp6Address));
+        
+        error = otCoapSendRequest(mOtaServerSetup.pOtInstance, pMsg, &messageInfo, NULL, NULL);
+
+        if ((error != OT_ERROR_NONE) && (pMsg != NULL))
+        {
+            otMessageFree(pMsg);
+        }
+        else
+        {
+            status = gOtaStatus_Success_c;
+        }
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CoapSendRsp(otaClientInfo_t *pOtaClientInfo, uint8_t *pData, uint32_t dataLen)
+\brief  This function is used to send a coap response to a OTA client node.
+
+\param  [in]   pOtaClientInfo    Pointer to client info
+\param  [in]   pData             Pointer to data
+\param  [in]   dataLen           Payload length
+
+\return        otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_CoapSendRsp
+(
+    otaClientInfo_t *pOtaClientInfo,
+    uint8_t *pData,
+    uint32_t dataLen
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    otCoapType coapType = OT_COAP_TYPE_NON_CONFIRMABLE;
+    otCoapCode coapCode = OT_COAP_CODE_POST;
+    otError error = OT_ERROR_NONE;
+    otMessage *pMsg = otCoapNewMessage(mOtaServerSetup.pOtInstance, NULL);
+
+    if(pMsg)
+    {
+        otMessageInfo messageInfo = {0};
+
+        otCoapMessageInit(pMsg, coapType, coapCode);
+        otCoapMessageGenerateToken(pMsg, 4);
+
+        /* Complete command */
+        error = otCoapMessageAppendUriPathOptions(pMsg, OTA_SERVER_URI_PATH);
+        error = otCoapMessageSetPayloadMarker(pMsg);
+        error = otMessageAppend(pMsg, (const void *)pData, dataLen);
+
+        memset(&messageInfo, 0, sizeof(messageInfo));
+
+        messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
+        memcpy(&messageInfo.mSockAddr, GET_OTA_ADDRESS(mOtaServerSetup.pOtInstance), sizeof(otIp6Address));
+        memcpy(&messageInfo.mPeerAddr, &pOtaClientInfo->remoteAddr, sizeof(otIp6Address));
+
+        error = otCoapSendRequest(mOtaServerSetup.pOtInstance, pMsg, &messageInfo, NULL, NULL);
+
+        if ((error != OT_ERROR_NONE) && (pMsg != NULL))
+        {
+            otMessageFree(pMsg);
+        }
+        else
+        {
+            status = gOtaStatus_Success_c;
+        }
+    }
+
+    free((void *)pOtaClientInfo);
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_SocketSendRsp(otaClientInfo_t *pOtaClientInfo, uint8_t *pData, uint32_t dataLen)
+\brief  This function is used to send a socket response to a OTA client node.
+
+\param  [in]   pOtaClientInfo    Pointer to client info
+\param  [in]   pData             Pointer to data
+\param  [in]   dataLen           Payload length
+
+\return        otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_SocketSendRsp
+(
+    otaClientInfo_t *pOtaClientInfo,
+    uint8_t *pData,
+    uint32_t dataLen
+)
+{
+    otMessageInfo messageInfo;
+    otMessage *message = NULL;
+    otError error = OT_ERROR_NONE;
+
+    /* Set remote address and local port */
+    memset(&messageInfo, 0, sizeof(messageInfo));
+    messageInfo.mPeerPort = pOtaClientInfo->port;
+    memcpy(&messageInfo.mPeerAddr, &pOtaClientInfo->remoteAddr, sizeof(otIp6Address));
+
+    message = otUdpNewMessage(mOtaServerSetup.pOtInstance, NULL);
+    error = otMessageAppend(message, (const void *)pData, dataLen);
+    error = otUdpSend(mOtaServerSetup.pOtaUdpSrvSocket, message, &messageInfo);
+
+    if (error != OT_ERROR_NONE && message != NULL)
+    {
+        otMessageFree(message);
+    }
+
+    free((void *)pOtaClientInfo);
+
+    return gOtaStatus_Success_c;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CoapSendRspWaitAbortData(otaClientInfo_t *pOtaClientInfo, uint8_t status,
+                                                              uint32_t delayInMs)
+\brief  This function is used to send a Query Image Rsp command to the OTA client node using
+        a status != Success
+
+\param  [in]   pOtaClientInfo    Pointer to client info
+\param  [in]   status            Query image response status != Success
+\param  [in]   delayInMs         Delay in milliseconds
+
+\return        otaStatus_t       Status of the operation
+ ***************************************************************************************************/
+static otaStatus_t OtaServer_CoapSendRspWaitAbortData
+(
+    otaClientInfo_t *pOtaClientInfo,
+    uint8_t status,
+    uint32_t delayInMs
+)
+{
+    otaStatus_t result = gOtaStatus_Failed_c;
+
+    if (status != gOtaFileStatus_Success_c)
+    {
+        /* All busy / abort responses have the same structure as queryRsp*/
+        otaCmd_QueryImageRsp_t queryRsp = {0};
+        uint8_t len = 2 + sizeof(otaCmd_QueryImageRspWait_t);
+        uint8_t otaCommand = *pOtaClientInfo->pData;
+        uint32_t timeInMs = otPlatAlarmMilliGetNow();
+
+        queryRsp.commandId = gOtaCmd_QueryImageRsp_c;
+
+        switch (otaCommand)
+        {
+            case gOtaCmd_BlockReq_c:
+                queryRsp.commandId = gOtaCmd_BlockRsp_c;
+                break;
+
+            case gOtaCmd_QueryImageReq_c:
+                queryRsp.commandId = gOtaCmd_QueryImageRsp_c;
+                break;
+
+            case gOtaCmd_UpgradeEndReq_c:
+                queryRsp.commandId = gOtaCmd_UpgradeEndRsp_c;
+                break;
+
+            default:
+                free((void *)pOtaClientInfo);
+                return gOtaStatus_InvalidParam_c;
+        }
+
+        queryRsp.status = status;
+        memcpy(&queryRsp.data.wait.currentTime, &timeInMs, sizeof(uint32_t));
+        timeInMs = timeInMs + delayInMs;
+        memcpy(&queryRsp.data.wait.requestTime, &timeInMs, sizeof(uint32_t));
+
+        if (gOtaStatus_Success_c == OtaServer_CoapSendRsp(pOtaClientInfo, (uint8_t *)&queryRsp, len))
+        {
+            result = gOtaStatus_Success_c;
+        }
+    }
+    else
+    {
+        free((void *)pOtaClientInfo);
+    }
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static bool_t OtaServer_IsClientValid(uint16_t clientId)
+\brief  This function is used to validate client ID and add it to percentage list.
+
+\param  [in]   clientId    Client ID
+
+\return        bool_t    TRUE - client valid, FALSE - client is in the abort list
+ ***************************************************************************************************/
+static bool_t OtaServer_IsClientValid
+(
+    uint16_t clientId
+)
+{
+    bool_t result = false;
+    uint8_t i;
+
+    for (i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+    {
+        if (mOtaServerPercentageInformation.unicastEntry[i].clientId == clientId)
+        {
+            result = true;
+            break;
+        }
+    }
+
+    if (result == false)
+    {
+        for (i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+        {
+            if (mOtaServerPercentageInformation.unicastEntry[i].clientId == gOtaServer_InvalidClientId_c)
+            {
+                mOtaServerPercentageInformation.unicastEntry[i].clientId = clientId;
+                mOtaServerPercentageInformation.unicastEntry[i].percentage = 0;
+                result = true;
+                break;
+            }
+        }
+    }
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static bool_t OtaServer_RemoveClientFromPercentageInfo(uint16_t clientId)
+\brief  This function is used to remove a client ID from percentage information list.
+
+\param [in]   clientId    Client ID
+
+\return       bool_t      TRUE - client removed, FALSE - otherwise
+ ***************************************************************************************************/
+static bool_t OtaServer_RemoveClientFromPercentageInfo
+(
+    uint16_t clientId
+)
+{
+    bool_t result = false;
+
+    for (uint8_t i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+    {
+        if (mOtaServerPercentageInformation.unicastEntry[i].clientId == clientId)
+        {
+            mOtaServerPercentageInformation.unicastEntry[i].clientId = gOtaServer_InvalidClientId_c;
+            mOtaServerPercentageInformation.unicastEntry[i].percentage = 0;
+            result = true;
+            break;
+        }
+    }
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_ResetPercentageInfo(void)
+\brief  This function is resets the percentage information.
+ ***************************************************************************************************/
+static void OtaServer_ResetPercentageInfo
+(
+    void
+)
+{
+    mOtaServerPercentageInformation.multicastPercentage = 0;
+    mOtaServerPercentageInformation.otaType = 0xFF;
+
+    for (uint8_t i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+    {
+        mOtaServerPercentageInformation.unicastEntry[i].clientId = gOtaServer_InvalidClientId_c;
+        mOtaServerPercentageInformation.unicastEntry[i].percentage = 0;
+    }
+}
+
+/*************************************************************************************************
+*
+*  OTA Server Standalone functions
+*
+**************************************************************************************************/
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_InitStandaloneOpMode(void)
+\brief  Initialize ota server standalone operation mode.
+***************************************************************************************************/
+static void OtaServer_InitStandaloneOpMode
+(
+    void
+)
+{
+    bool_t imageAvailable = false;
+    uint8_t index = 0;
+    otaFileHeader_t otaHeader;
+    FILE *pFile = NULL;
+
+    /* init external memory */
+    pFile = fopen(binary_file_path,"rb");
+
+    /* process OTA header information */
+    while ((index < gOtaServer_MaxOtaImages_c) && (pFile != NULL))
+    {
+        uint32_t fileIdentifier;
+
+        /* Read OTA Header */
+        if (fread((void *)&otaHeader, sizeof(otaFileHeader_t), 1, pFile))
+        {
+            memcpy(&fileIdentifier, otaHeader.fileIdentifier, sizeof(fileIdentifier));
+
+            if (fileIdentifier == gOtaFileIdentifierNo_c)
+            {
+                uint16_t manufCode, imageType;
+                uint32_t fileVersion, fileSize;
+
+                memcpy(&fileVersion, &otaHeader.fileVersion, sizeof(uint32_t));
+                memcpy(&imageType, &otaHeader.imageType, sizeof(uint16_t));
+                memcpy(&manufCode, &otaHeader.manufacturerCode, sizeof(uint16_t));
+                memcpy(&fileSize, &otaHeader.totalImageSize, sizeof(uint32_t));
+                
+                index = OtaServerStandalone_KeepImageInfo(manufCode, imageType, fileVersion, fileSize);
+
+                if (index < gOtaServer_MaxOtaImages_c)
+                {
+                    mOtaServerTempImageIdx = index;
+                    mOtaServerImageList[index].isValidEntry = true;
+                    imageAvailable = true;
+                }
+            }
+            else
+            {
+                break;
+            }
+        }
+        else
+        {
+            /* ignore other data */
+            break;
+        }
+    }
+
+    if (pFile != NULL)
+    {
+        fclose(pFile);
+    }
+
+    mOtaServerSetup.isActive = imageAvailable;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static uint8_t OtaServerStandalone_ValidateImage(uint16_t manufCode, uint16_t imageType,
+                                                         uint32_t fileVersion, bool_t serialProtocol)
+\brief  Validate image by checking internal table.
+
+\param  [in]    manufCode         Manufacturer code
+        [in]    imageType         Image type
+        [in]    fileVersion       File version
+        [in]    serialProtocol    Image validation is required for the ota Server serial protocol
+
+\return         uint8_t           Image index if success, otherwise returns gOtaServer_MaxOtaImages_c
+***************************************************************************************************/
+static uint8_t OtaServerStandalone_ValidateImage
+(
+    uint16_t manufCode,
+    uint16_t imageType,
+    uint32_t fileVersion,
+    bool_t serialProtocol
+)
+{
+    uint8_t result = gOtaServer_MaxOtaImages_c;
+
+    /* validate internal list */
+    for (uint8_t i = 0; i < gOtaServer_MaxOtaImages_c; i++)
+    {
+        if ((manufCode == mOtaServerImageList[i].manufCode) &&
+                (imageType == mOtaServerImageList[i].imageType) &&
+                (mOtaServerImageList[i].isValidEntry))
+        {
+            if (((fileVersion ==  mOtaServerImageList[i].fileVersion) && (mOtaServerSetup.fileVersionPolicy & gOtaFileVersionPolicies_Reinstall_c)) ||
+                    ((fileVersion <  mOtaServerImageList[i].fileVersion) && (mOtaServerSetup.fileVersionPolicy & gOtaFileVersionPolicies_Upgrade_c)) ||
+                    ((fileVersion >  mOtaServerImageList[i].fileVersion) && (mOtaServerSetup.fileVersionPolicy & gOtaFileVersionPolicies_Downgrade_c)) ||
+                    ((serialProtocol) && (fileVersion ==  mOtaServerImageList[i].fileVersion)) || (fileVersion == 0xFFFFFFFF))
+            {
+                result = i;
+                break;
+            }
+        }
+    }
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServerStandalone_QueryImageReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a QueryImageReq command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServerStandalone_QueryImageReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    uint8_t index = 0;
+    otaCmd_QueryImageReq_t *pQueryImgReq = (otaCmd_QueryImageReq_t *)pOtaClientInfo->pData;
+
+    index = OtaServerStandalone_ValidateImage((uint16_t)(pQueryImgReq->manufacturerCode[0] + (pQueryImgReq->manufacturerCode[1] << 8)),
+            (uint16_t)(pQueryImgReq->imageType[0] + (pQueryImgReq->imageType[1] << 8)),
+            (uint32_t)(pQueryImgReq->fileVersion[0] + (pQueryImgReq->fileVersion[1] << 8) +
+                       (pQueryImgReq->fileVersion[2] << 16) + (pQueryImgReq->fileVersion[3] << 24)), false);
+
+    if (index < gOtaServer_MaxOtaImages_c)
+    {
+        otaCmd_QueryImageRsp_t queryImgRsp = {0};
+        /* image size */
+        uint8_t len = sizeof(otaCmd_QueryImageRsp_t) - sizeof(queryImgRsp.data);
+
+        queryImgRsp.commandId = gOtaCmd_QueryImageRsp_c;
+        queryImgRsp.status = gOtaFileStatus_Success_c;
+        memcpy(&queryImgRsp.data.success.manufacturerCode, &mOtaServerImageList[index].manufCode, sizeof(uint16_t));
+        memcpy(&queryImgRsp.data.success.fileVersion, &mOtaServerImageList[index].fileVersion, sizeof(uint32_t));
+        memcpy(&queryImgRsp.data.success.imageType, &mOtaServerImageList[index].imageType, sizeof(uint16_t));
+        memcpy(&queryImgRsp.data.success.fileSize, &mOtaServerImageList[index].fileSize, sizeof(uint32_t));
+        memcpy(&queryImgRsp.data.success.serverDownloadPort, &mOtaServerSetup.downloadPort, sizeof(uint16_t));
+
+        len += sizeof(otaCmd_QueryImageRspSuccess_t);
+        (void)OtaServer_CoapSendRsp(pOtaClientInfo, (uint8_t *)&queryImgRsp, len);
+        status = gOtaStatus_Success_c;
+    }
+    else
+    {
+        /* packet in progress -  send back a Query Image Rsp command with status no image available */
+        OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo, gOtaFileStatus_NoImageAvailable_c, 0);
+        status = gOtaStatus_Success_c;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_AddPercentageInfoPerClient(uint16_t clientId, uint8_t percent)
+\brief  This function is used to process a BlockRequest command.
+
+\param  [in]    clientId    Client ID
+\param  [in]    percent     Unicast OTAP percent done
+***************************************************************************************************/
+static void OtaServer_AddPercentageInfoPerClient
+(
+    uint16_t clientId,
+    uint8_t percent
+)
+{
+    for (int i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+    {
+        if (mOtaServerPercentageInformation.unicastEntry[i].clientId == clientId)
+        {
+            mOtaServerPercentageInformation.unicastEntry[i].percentage = percent;
+            break;
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServerStandalone_BlockReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a BlockRequest command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServerStandalone_BlockReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    uint8_t index = gOtaServer_MaxOtaImages_c;
+    otaCmd_BlockReq_t *pBlockReq = (otaCmd_BlockReq_t *)pOtaClientInfo->pData;
+    index = OtaServerStandalone_ValidateImage((uint16_t)(pBlockReq->manufacturerCode[0] + (pBlockReq->manufacturerCode[1] << 8)),
+            (uint16_t)(pBlockReq->imageType[0] + (pBlockReq->imageType[1] << 8)),
+            (uint32_t)(pBlockReq->fileVersion[0] + (pBlockReq->fileVersion[1] << 8) +
+                       (pBlockReq->fileVersion[2] << 16) + (pBlockReq->fileVersion[3] << 24)), false);
+
+    if (index < gOtaServer_MaxOtaImages_c)
+    {
+        otaCmd_BlockRsp_t *pBlockRsp = NULL;
+        uint32_t respLength = 0;
+        uint32_t len =  pBlockReq->maxDataSize;
+        uint32_t imageOffset = (uint32_t)(pBlockReq->fileOffset[0] + (pBlockReq->fileOffset[1] << 8) +
+                                          (pBlockReq->fileOffset[2] << 16) + (pBlockReq->fileOffset[3] << 24));
+
+        if ((mOtaServerImageList[index].fileSize - imageOffset) < len)
+        {
+            len = mOtaServerImageList[index].fileSize - imageOffset;
+        }
+
+        respLength = 2 + sizeof(otaCmd_BlockRspSuccess_t) - 1 + len;
+        pBlockRsp = (otaCmd_BlockRsp_t *)calloc(1, respLength);
+
+        if (pBlockRsp)
+        {
+            uint32_t addr = imageOffset + mOtaServerImageList[index].imageAddr;
+            FILE *pFile = fopen(binary_file_path,"rb");
+            fseek(pFile, addr, SEEK_SET);
+
+            status = gOtaStatus_Success_c;
+            pBlockRsp->commandId = gOtaCmd_BlockRsp_c;
+            pBlockRsp->status = gOtaFileStatus_Success_c;
+            memcpy(pBlockRsp->data.success.fileVersion, pBlockReq->fileVersion, sizeof(uint32_t));
+            memcpy(pBlockRsp->data.success.fileOffset, &imageOffset, sizeof(uint32_t));
+            pBlockRsp->data.success.dataSize = len;
+
+            if(fread((void *)&pBlockRsp->data.success.pData[0], len, 1, pFile) == 0)
+            {
+                (void)OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo, gOtaFileStatus_Abort_c, 0);
+            }
+            else
+            {
+                uint16_t clientId = (pOtaClientInfo->remoteAddr.mFields.m8[14] << 8) + pOtaClientInfo->remoteAddr.mFields.m8[15];
+                uint8_t percent = 0;
+
+                OtaServer_SocketSendRsp(pOtaClientInfo, (uint8_t *)pBlockRsp, respLength);
+
+                //Calculate percentage of image already sent
+                percent = (uint8_t)(((imageOffset + len) * 100) / mOtaServerImageList[index].fileSize);
+                mOtaServerPercentageInformation.otaType = mOtaServerSetup.transferType;
+
+                if (mOtaServerSetup.transferType == gOtaMulticast_c)
+                {
+                    //Percentage of sent packages over multicast OTA
+                    mOtaServerPercentageInformation.multicastPercentage = percent;
+                }
+                else
+                {
+                    //Percentage of sent packages for a unicast client
+                    OtaServer_AddPercentageInfoPerClient(clientId, percent);
+                }
+            }
+
+            free(pBlockRsp);
+
+            if(pFile != NULL)
+            {
+                fclose(pFile);    
+            }
+        }
+    }
+    else
+    {
+        /* image is not available, abort current session */
+        status = gOtaStatus_Success_c;
+        (void)OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo, gOtaFileStatus_Abort_c, 0);
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServerStandalone_ServerDiscoveryHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a ServerDiscovery command.
+
+\param  [in]    pOtaClientInfo    Pointer to OTA client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServerStandalone_ServerDiscoveryHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaStatus_t status = gOtaStatus_Success_c;
+    uint8_t index = gOtaServer_MaxOtaImages_c;
+    otaCmd_ServerDiscovery_t *pCmdData = (otaCmd_ServerDiscovery_t *)pOtaClientInfo->pData;
+
+    index = OtaServerStandalone_ValidateImage((uint16_t)(pCmdData->manufacturerCode[0] + (pCmdData->manufacturerCode[1] << 8)),
+            (uint16_t)(pCmdData->imageType[0] + (pCmdData->imageType[1] << 8)),
+            0xFFFFFFFF, false);
+
+    if (index < gOtaServer_MaxOtaImages_c)
+    {
+        /* send back a unicast image notify command */
+        status = OtaServer_SendImageNotifty(NULL, &pOtaClientInfo->remoteAddr);
+    }
+
+    free(pOtaClientInfo);
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static uint8_t OtaServerStandalone_KeepImageInfo(uint16_t manufCode, uint16_t imageType,
+                                                        uint32_t fileVersion, uint32_t fileSize)
+\brief  This function is used to store image information in local table.
+
+\param  [in]    manufCode      Manufacturer code
+        [in]    imageType      Image type
+        [in]    fileVersion    File version
+        [in]    imageSize      Image size
+
+\return         uint8_t        Image index if success, otherwise returns gOtaServer_MaxOtaImages_c
+***************************************************************************************************/
+static uint8_t OtaServerStandalone_KeepImageInfo
+(
+    uint16_t manufCode,
+    uint16_t imageType,
+    uint32_t fileVersion,
+    uint32_t fileSize
+)
+{
+    uint8_t result = gOtaServer_MaxOtaImages_c;
+    uint32_t imageAddrOffset = 0;
+
+    for (uint8_t i = 0; i < gOtaServer_MaxOtaImages_c; i++)
+    {
+        if (mOtaServerImageList[i].isValidEntry)
+        {
+            /* entry is valid, update image offset */
+            imageAddrOffset += mOtaServerImageList[i].fileSize;
+        }
+        else
+        {
+            /* entry is free */
+            mOtaServerImageList[i].fileVersion = fileVersion;
+            mOtaServerImageList[i].imageAddr = imageAddrOffset;
+            mOtaServerImageList[i].imageType = imageType;
+            mOtaServerImageList[i].manufCode = manufCode;
+            mOtaServerImageList[i].fileSize = fileSize;
+            mOtaServerImageList[i].isValidEntry = false; /* True when the download is completed */
+            result = i;
+            break;
+        }
+    }
+
+    return result;
+}
+
+/*************************************************************************************************
+*
+*  OTA Server Serial Protocol callbacks
+*
+**************************************************************************************************/
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_HandleBlockSocket(bool_t onOff)
+\brief  This function is used to handle block sockets.
+
+\param  [in]   onOff          If TRUE, create and bind and if FALSE, close socket
+
+\return        otaStatus_t    Status of the operation
+ ***************************************************************************************************/
+static otaStatus_t OtaServer_HandleBlockSocket
+(
+    bool_t onOff
+)
+{
+    otaStatus_t status = gOtaStatus_Success_c;
+
+    if (true == onOff)
+    {
+        if (mOtaServerSetup.pOtaUdpSrvSocket == NULL)
+        {
+            otError    error;
+            otSockAddr portAddr;
+            
+            /* Set Ota Server local address and local port */
+            memset(&portAddr, 0, sizeof(portAddr));
+            portAddr.mPort = OTA_SERVER_DEFAULT_PORT;
+            mOtaServerSetup.pOtaUdpSrvSocket = &mOtaUdpSrvSocket;
+
+            /* Open Ota Server UDP socket */
+            error = otUdpOpen(mOtaServerSetup.pOtInstance, mOtaServerSetup.pOtaUdpSrvSocket, OtaClient_UdpServerService, NULL);
+
+            if (error != OT_ERROR_NONE)
+            {
+                status = gOtaStatus_NoUdpSocket_c;
+            }
+
+            if(status == gOtaStatus_Success_c)
+            {
+                error = otUdpBind(mOtaServerSetup.pOtaUdpSrvSocket, &portAddr);
+
+                if (error != OT_ERROR_NONE)
+                {
+                    otUdpClose(mOtaServerSetup.pOtaUdpSrvSocket);
+                    mOtaServerSetup.pOtaUdpSrvSocket = NULL;
+                    status = gOtaStatus_Failed_c;
+                }
+            }
+        }
+        else
+        {
+            status = gOtaStatus_Success_c;
+        }
+    }
+    else
+    {
+        if (mOtaServerSetup.pOtaUdpSrvSocket != NULL)
+        {
+            otUdpClose(mOtaServerSetup.pOtaUdpSrvSocket);
+            mOtaServerSetup.pOtaUdpSrvSocket = NULL;
+        }
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_MulticastTimeoutCb(void *pParam)
+\brief  This function is used for the ota server multicast timer callback.
+
+\param  [in]    pParam    Generic pointer containing information dependent on the multicast state.
+***************************************************************************************************/
+static void OtaServer_MulticastTimeoutCb
+(
+    void *pParam
+)
+{
+    OtaServer_MulticastMngr(pParam);
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_InitMulticast(void *pParam)
+\brief  This function is used for the initialization of the OTA Multicast mechanism.
+
+\param  [in]    pParam         Pointer to the otaServer_ImageNotify_t structure containing
+                               the Image Notification information required for initialization.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_InitMulticast
+(
+    void *pParam
+)
+{
+    otaServer_ImageNotify_t *pImageNotify;
+    otaStatus_t status = gOtaStatus_Failed_c;
+
+    if (pParam)
+    {
+        uint32_t delay;
+
+        pImageNotify = (otaServer_ImageNotify_t *)pParam;
+        memcpy(&mOtaServerSetup.multicastManufacturerCode, pImageNotify->manufacturerCode, sizeof(uint16_t));
+        memcpy(&mOtaServerSetup.multicastImageType, pImageNotify->imageType, sizeof(uint16_t));
+        memcpy(&mOtaServerSetup.multicastFileVersion, pImageNotify->fileVersion, sizeof(uint32_t));
+        memset(&mOtaServerSetup.ackBitmask, 0xFF, sizeof(mOtaServerSetup.ackBitmask));
+        mOtaServerSetup.currentWindowOffset = 0;
+        memcpy(&mOtaServerSetup.multicastImageSize, pImageNotify->fileSize, sizeof(mOtaServerSetup.multicastImageSize));
+        mOtaServerSetup.multicastNoOfImgNtf = gOtaServer_MulticastImgNtfRetransmissions_c;
+        mOtaServerSetup.multicastNoOfBlockRsp = gOtaServer_MulticastNoOfBlockRsps_c;
+        mOtaServerSetup.multicastNoOfWindowRetries = gOtaServer_MulticastWindowRetries_c;
+
+        if (mOtaServerSetup.multicastNoOfImgNtf)
+        {
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_SendImgNtf_c;
+            delay = gOtaServer_MulticastImgNtfInterval_c;
+        }
+        else
+        {
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_GenBlockReq_c;
+            delay = gOtaServer_MulticastInterval_c;
+            free(pParam);
+            pParam = NULL;
+        }
+
+        OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, pParam, delay);
+        status = gOtaStatus_Success_c;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_SendImgNtf(void *pParam)
+\brief  This function is used for the retransmission of Image Notification commands.
+
+\param  [in]    pParam          Pointer to the otaServer_ImageNotify_t structure containing
+                                the Image Notification information used for the OTA command.
+
+\return         otaStatus_t     Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_SendImgNtf
+(
+    void *pParam
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+
+    if (pParam)
+    {
+        uint32_t delay;
+        otaServer_ImageNotify_t *pImageNotify = pParam;
+        status = OtaServer_CoapSendImageNotify(pImageNotify, &in6addr_realmlocal_allthreadnodes);
+
+        if (status == gOtaStatus_Success_c)
+        {
+            mOtaServerSetup.multicastNoOfImgNtf--;
+        }
+
+        if (mOtaServerSetup.multicastNoOfImgNtf)
+        {
+            delay = gOtaServer_MulticastImgNtfInterval_c;
+        }
+        else
+        {
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_GenBlockReq_c;
+            delay = gOtaServer_MulticastInterval_c;
+            free(pParam);
+            pParam = NULL;
+        }
+
+        OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, pParam, delay);
+
+        status = gOtaStatus_Success_c;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_GenerateBlockReq(void *pParam)
+\brief  This function is used for generating a Block Request to the local OTA Server
+        that will result in a OTA Block Response sent as a multicast.
+
+\param  [in]    pParam         Pointer to additional data. Reserved for future enhancements. Not used.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_GenerateBlockReq
+(
+    void *pParam
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    otaClientInfo_t *pOtaClientInfo;
+    otaCmd_BlockReq_t *pBlockReq;
+
+    /* Calculate the size of the Block Req taking into acount the variable length ACK bitfield. */
+    uint8_t size = sizeof(otaClientInfo_t) - 1 + sizeof(otaCmd_BlockReq_t);
+
+    (void)pParam;
+
+    pOtaClientInfo = (otaClientInfo_t *)calloc(1, size);
+
+    if (NULL == pOtaClientInfo)
+    {
+        status = gOtaStatus_NoMem_c;
+    }
+    else
+    {
+        uint32_t fragIdx, imageOffset;
+        uint32_t delay = gOtaServer_MulticastBlockRspInterval_c;
+
+        memcpy(&pOtaClientInfo->remoteAddr, &in6addr_realmlocal_allthreadnodes, sizeof(otIp6Address));
+        memcpy(&pOtaClientInfo->sourceAddr, GET_OTA_ADDRESS(mOtaServerSetup.pOtInstance), sizeof(otIp6Address));
+        pOtaClientInfo->port = OTA_SERVER_DEFAULT_PORT;
+        pOtaClientInfo->dataLen = size - sizeof(otaClientInfo_t) + 1;
+        pOtaClientInfo->timeStamp = otPlatAlarmMilliGetNow();
+
+        pBlockReq = (otaCmd_BlockReq_t *)pOtaClientInfo->pData;
+        pBlockReq->commandId = gOtaCmd_BlockReq_c;
+        memcpy(pBlockReq->manufacturerCode, &mOtaServerSetup.multicastManufacturerCode, sizeof(pBlockReq->manufacturerCode));
+        memcpy(pBlockReq->imageType, &mOtaServerSetup.multicastImageType, sizeof(pBlockReq->imageType));
+        memcpy(pBlockReq->fileVersion, &mOtaServerSetup.multicastFileVersion, sizeof(pBlockReq->fileVersion));
+        fragIdx = NWKU_GetFirstBitValue(mOtaServerSetup.ackBitmask, gOtaServer_MulticastWindowSize_c / 8, true);
+
+        imageOffset = mOtaServerSetup.currentWindowOffset + (fragIdx * gOtaMaxBlockDataSize_c);
+        memcpy(pBlockReq->fileOffset, &imageOffset, sizeof(pBlockReq->fileOffset));
+        pBlockReq->maxDataSize = gOtaMaxBlockDataSize_c;
+
+        /* Send the Block Req to the OTA Server. */
+        OtaServer_ClientProcess(pOtaClientInfo);
+
+        if (mOtaServerSetup.multicastNoOfBlockRsp == 0)
+        {
+            if (fragIdx < gOtaServer_MulticastWindowSize_c)
+            {
+                /* Last retry. */
+                NWKU_ClearBit(fragIdx, mOtaServerSetup.ackBitmask);
+                mOtaServerSetup.multicastNoOfBlockRsp = gOtaServer_MulticastNoOfBlockRsps_c;
+                /* Get next fragment index */
+                fragIdx = NWKU_GetFirstBitValue(mOtaServerSetup.ackBitmask, gOtaServer_MulticastWindowSize_c / 8, true);
+
+                if (fragIdx > (gOtaServer_MulticastWindowSize_c - 1))
+                {
+                    /* Last retry of last fragment from current window. */
+                    mOtaServerSetup.multicastState = gOtaServerMulticastState_WaitForAck_c;
+                    delay = gOtaServer_MulticastAckTimeout_c;
+                }
+            }
+        }
+        else
+        {
+            mOtaServerSetup.multicastNoOfBlockRsp--;
+        }
+
+        OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, NULL, delay);
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_MulticastUpgradeEnd(void *pParam)
+\brief  This function is used for sending the Upgrade End Response command at the end of
+        the OTA multicast process.
+
+\param  [in]    pParam         Pointer to additional data. Reserved for future enhancements. Not used.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_MulticastUpgradeEnd
+(
+    void *pParam
+)
+{
+    (void)pParam;
+    OtaServer_ResetMulticastModule(NULL);
+
+    return gOtaStatus_Success_c;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_ProcessAckTimeout(void *pParam)
+\brief  This function is used for determining the next steps after the ACK window closes.
+
+\param  [in]    pParam         Pointer to additional data. Reserved for future enhancements. Not used.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_ProcessAckTimeout
+(
+    void *pParam
+)
+{
+    otaStatus_t status = gOtaStatus_Success_c;
+    uint32_t fragIdx;
+    uint32_t delay = gOtaServer_MulticastBlockRspInterval_c;
+
+    (void)pParam;
+
+    fragIdx = NWKU_GetFirstBitValue(mOtaServerSetup.ackBitmask, gOtaServer_MulticastWindowSize_c / 8, true);
+
+    /* Check if there are fragments that require retransmission. */
+    if ((fragIdx < gOtaServer_MulticastWindowSize_c - 1) && (mOtaServerSetup.multicastNoOfWindowRetries))
+    {
+        /* Retransmit current window. */
+        mOtaServerSetup.multicastNoOfWindowRetries--;
+    }
+    else
+    {
+        /* Last window? */
+        if (mOtaServerSetup.currentWindowOffset + (gOtaServer_MulticastWindowSize_c * gOtaMaxBlockDataSize_c) >= mOtaServerSetup.multicastImageSize)
+        {
+            /* Move to the next state */
+            delay = gOtaServer_MulticastUpgradeEndDelay_c;
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_SendUpgradeEnd_c;
+        }
+        else
+        {
+            /* Window completed. Move to the next window. */
+            mOtaServerSetup.currentWindowOffset += (gOtaServer_MulticastWindowSize_c * gOtaMaxBlockDataSize_c);
+
+            if (mOtaServerSetup.currentWindowOffset + (gOtaServer_MulticastWindowSize_c * gOtaMaxBlockDataSize_c) <= mOtaServerSetup.multicastImageSize)
+            {
+                /* Current window is full */
+                memset(mOtaServerSetup.ackBitmask, 0xFF, sizeof(mOtaServerSetup.ackBitmask));
+            }
+            else
+            {
+                /* Calculate the number of fragments remaining */
+                uint8_t fragsInWindow = (mOtaServerSetup.multicastImageSize - mOtaServerSetup.currentWindowOffset) / gOtaMaxBlockDataSize_c;
+
+                if ((mOtaServerSetup.multicastImageSize - mOtaServerSetup.currentWindowOffset) % gOtaMaxBlockDataSize_c != 0)
+                {
+                    fragsInWindow++;
+                }
+
+                /* Set corresponding bits in ack bitmask. */
+                for (int i = 0; i < fragsInWindow; i++)
+                {
+                    NWKU_SetBit(i, mOtaServerSetup.ackBitmask);
+                }
+            }
+
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_GenBlockReq_c;
+            /* Debug only */
+            /* Get fragment index. Should be 0, should not fail. */
+            fragIdx = NWKU_GetFirstBitValue(mOtaServerSetup.ackBitmask, gOtaServer_MulticastWindowSize_c / 8, true);
+
+        }
+    }
+
+    OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, NULL, delay);
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_ResetMulticastModule(void *pParam)
+\brief  Reset the OTA Multicast mechanism.
+
+\param  [in]    pParam    Pointer to data
+***************************************************************************************************/
+static void OtaServer_ResetMulticastModule
+(
+    void *pParam
+)
+{
+    if (callbackIsSet == true)
+    {
+        mOtaServerSetup.multicastState = gOtaServerMulticastState_ResetMulticast_c;
+    }
+    else
+    {
+        mOtaServerSetup.multicastState = gOtaServerMulticastState_NotInit_c;
+        mOtaServerSetup.transferType = gOtaUnicast_c;
+
+        OtaServer_ResetPercentageInfo();
+        OtaServer_StopTimeCallback();
+
+        if (pParam)
+        {
+            free(pParam);
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_MulticastMngr(void *pParam)
+\brief  Ota Multicast state machine.
+
+\param  [in]    pParam    Generic pointer containing state depended information
+***************************************************************************************************/
+static void OtaServer_MulticastMngr
+(
+    void *pParam
+)
+{
+    switch (mOtaServerSetup.multicastState)
+    {
+        case gOtaServerMulticastState_NotInit_c:
+            (void)OtaServer_InitMulticast(pParam);
+            break;
+
+        case gOtaServerMulticastState_SendImgNtf_c:
+            (void)OtaServer_SendImgNtf(pParam);
+            break;
+
+        case gOtaServerMulticastState_GenBlockReq_c:
+            (void)OtaServer_GenerateBlockReq(pParam);
+            break;
+
+        case gOtaServerMulticastState_WaitForAck_c:
+            (void)OtaServer_ProcessAckTimeout(pParam);
+            break;
+
+        case gOtaServerMulticastState_SendUpgradeEnd_c:
+            (void)OtaServer_MulticastUpgradeEnd(pParam);
+            break;
+
+        case gOtaServerMulticastState_ResetMulticast_c:
+            OtaServer_ResetMulticastModule(pParam);
+            break;
+
+        case gOtaServerMulticastState_Idle_c:
+            break;
+    }
+}
+
+/*==================================================================================================
+Private debug functions
+==================================================================================================*/
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp
new file mode 100755
index 0000000..0c47ca4
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp
@@ -0,0 +1,195 @@
+/*
+ *    Copyright (c) 2019-2020, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file shows how to implement the NCP vendor hook.
+ */
+
+#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
+
+#include "ncp_base.hpp"
+
+#include "../../third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h"
+namespace ot {
+namespace Ncp {
+
+otError NcpBase::VendorCommandHandler(uint8_t aHeader, unsigned int aCommand)
+{
+    otError error = OT_ERROR_NONE;
+
+    switch (aCommand)
+    {
+
+    // TODO: Implement your command handlers here.
+    case SPINEL_CMD_VENDOR_NXP_OTA_START:
+        uint8_t        otaType, start_result;
+        const char *   file_path;
+
+        SuccessOrExit(error = mDecoder.ReadUint8(otaType));
+        SuccessOrExit(error = mDecoder.ReadUtf8(file_path));
+
+        //Start OTA process
+        start_result = OtaServer_StartOta(otaType, file_path);
+
+        SuccessOrExit(error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_NXP_OTA_START_RET));
+        SuccessOrExit(error = mEncoder.WriteUint8(start_result));
+        SuccessOrExit(error = mEncoder.EndFrame());
+
+        break;
+
+    case SPINEL_CMD_VENDOR_NXP_OTA_STOP:
+        //Stop OTA process
+        SuccessOrExit(error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_NXP_OTA_STOP_RET));
+        SuccessOrExit(error = mEncoder.WriteUint8(OtaServer_StopOta()));
+        SuccessOrExit(error = mEncoder.EndFrame());
+
+        break;
+
+    case SPINEL_CMD_VENDOR_NXP_OTA_STATUS:
+        //Get OTA process status
+        otaServerPercentageInfo_t otaInfo;
+        OtaServer_GetOtaStatus(&otaInfo);
+
+        SuccessOrExit(error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_NXP_OTA_STATUS_RET));
+        SuccessOrExit(error = mEncoder.WriteData((uint8_t *)&otaInfo, sizeof(otaInfo)));
+        SuccessOrExit(error = mEncoder.EndFrame());
+
+        break;
+
+    default:
+        error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_INVALID_COMMAND);
+    }
+
+exit:
+
+    return error;
+}
+
+void NcpBase::VendorHandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag)
+{
+    // This method is a callback which mirrors `NcpBase::HandleFrameRemovedFromNcpBuffer()`.
+    // It is called when a spinel frame is sent and removed from NCP buffer.
+    //
+    // (a) This can be used to track and verify that a vendor spinel frame response is
+    //     delivered to the host (tracking the frame using its tag).
+    //
+    // (b) It indicates that NCP buffer space is now available (since a spinel frame is
+    //     removed). This can be used to implement reliability mechanisms to re-send
+    //     a failed spinel command response (or an async spinel frame) transmission
+    //     (failed earlier due to NCP buffer being full).
+
+    OT_UNUSED_VARIABLE(aFrameTag);
+}
+
+otError NcpBase::VendorGetPropertyHandler(spinel_prop_key_t aPropKey)
+{
+    otError error = OT_ERROR_NONE;
+
+    switch (aPropKey)
+    {
+
+    // TODO: Implement your property get handlers here.
+    //
+    // Get handler should retrieve the property value and then encode and write the
+    // value into the NCP buffer. If the "get" operation itself fails, handler should
+    // write a `LAST_STATUS` with the error status into the NCP buffer. `OT_ERROR_NO_BUFS`
+    // should be returned if NCP buffer is full and response cannot be written.
+
+    default:
+        error = OT_ERROR_NOT_FOUND;
+        break;
+    }
+
+    return error;
+}
+
+otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey)
+{
+    otError error = OT_ERROR_NONE;
+
+    switch (aPropKey)
+    {
+
+    // TODO: Implement your property set handlers here.
+    //
+    // Set handler should first decode the value from the input Spinel frame and then
+    // perform the corresponding set operation. The handler should not prepare the
+    // spinel response and therefore should not write anything to the NCP buffer.
+    // The error returned from handler (other than `OT_ERROR_NOT_FOUND`) indicates the
+    // error in either parsing of the input or the error of the set operation. In case
+    // of a successful "set", `NcpBase` set command handler will invoke the
+    // `VendorGetPropertyHandler()` for the same property key to prepare the response.
+
+    default:
+        error = OT_ERROR_NOT_FOUND;
+        break;
+    }
+
+    return error;
+}
+
+}  // namespace Ncp
+}  // namespace ot
+
+//-------------------------------------------------------------------------------------------------------------------
+// When OPENTHREAD_ENABLE_NCP_VENDOR_HOOK is enabled, vendor code is
+// expected to provide the `otNcpInit()` function. The reason behind
+// this is to enable vendor code to define its own sub-class of
+// `NcpBase` or `NcpUart`/`NcpSpi`.
+//
+// Example below show how to add a vendor sub-class over `NcpUart`.
+
+#include "ncp_uart.hpp"
+#include "common/new.hpp"
+
+class NcpVendorUart : public ot::Ncp::NcpUart
+{
+public:
+    NcpVendorUart(ot::Instance *aInstance)
+        : ot::Ncp::NcpUart(aInstance)
+    {}
+
+    // Add public/private methods or member variables
+};
+
+static otDEFINE_ALIGNED_VAR(sNcpVendorRaw, sizeof(NcpVendorUart), uint64_t);
+
+extern "C" void otNcpInit(otInstance *aInstance)
+{
+    NcpVendorUart *ncpVendor = NULL;
+    ot::Instance * instance  = static_cast<ot::Instance *>(aInstance);
+
+    ncpVendor = new (&sNcpVendorRaw) NcpVendorUart(instance);
+
+    if (ncpVendor == NULL || ncpVendor != ot::Ncp::NcpBase::GetNcpInstance())
+    {
+        assert(false);
+    }
+}
+
+#endif // #if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c
new file mode 100755
index 0000000..6cd1baf
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c
@@ -0,0 +1,239 @@
+/*
+* Copyright 2019-2020 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+/*==================================================================================================
+Include Files
+==================================================================================================*/
+
+#include <string.h>
+
+#include "network_utils.h"
+
+#include <openthread/ip6.h>
+
+/*==================================================================================================
+Private macros
+==================================================================================================*/
+
+/*==================================================================================================
+Private type definitions
+==================================================================================================*/
+
+/*==================================================================================================
+Private prototypes
+==================================================================================================*/
+
+/*==================================================================================================
+Private global variables declarations
+==================================================================================================*/
+
+/*==================================================================================================
+Public global variables declarations
+==================================================================================================*/
+
+/* RAM global addresses - updated when the device join the network */
+otIp6Address in6addr_linklocal_allthreadnodes = {0};
+otIp6Address in6addr_realmlocal_allthreadnodes = {0};
+otIp6Address in6addr_realmlocal_threadleaderanycast = {0};
+
+/*==================================================================================================
+Public functions
+==================================================================================================*/
+void NWKU_MemCpyReverseOrder(void* pDst, void* pSrc, uint32_t cBytes)
+{
+    if(cBytes)
+    {
+        pDst = (uint8_t *)pDst + (uint32_t)(cBytes - 1);
+
+        while (cBytes)
+        {
+            *((uint8_t *)pDst) = *((uint8_t *)pSrc);
+            pDst = (uint8_t *)pDst-1;
+            pSrc = (uint8_t *)pSrc+1;
+            cBytes--;
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\fn     bool_t NWKU_GetBit(uint32_t bitNr, uint8_t *pArray)
+\brief  This function returns the value of a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+
+\retval         TRUE            if the bit is set
+\retval         FALSE           if the bit is not set
+***************************************************************************************************/
+bool_t NWKU_GetBit
+(
+    uint32_t bitNr,
+    uint8_t *pArray
+)
+{
+    return ((pArray[bitNr / 8] & (1 << (bitNr % 8))) ? true : false);
+}
+
+/*!*************************************************************************************************
+\fn     void NWKU_ClearBit(uint32_t bitNr, uint8_t* pArray)
+\brief  This function clears a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+***************************************************************************************************/
+void NWKU_ClearBit
+(
+    uint32_t bitNr,
+    uint8_t *pArray
+)
+{
+    pArray[bitNr / 8] &= ~(1 << (bitNr % 8));
+}
+
+/*!*************************************************************************************************
+\fn     void NWKU_SetBit(uint32_t bitNr, uint8_t* pArray)
+\brief  This function sets a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+***************************************************************************************************/
+void NWKU_SetBit
+(
+    uint32_t bitNr,
+    uint8_t *pArray
+)
+{
+    pArray[bitNr / 8] |= (1 << (bitNr % 8));
+}
+
+/*!*************************************************************************************************
+\fn     uint32_t NWKU_GetFirstBitValueInRange(uint8_t* pArray, uint32_t lowBitNr, uint32_t
+        highBitNr, bool_t bitValue)
+\brief  This function returns the first bit with value=bitValue in a range in the array.
+
+\param  [in]    pArray          pointer to the start of the array
+\param  [in]    lowBitNr        starting bit number
+\param  [in]    highBitNr       ending bit number
+\param  [in]    bitValue        bit value
+
+\return         uint32_t        bit number
+***************************************************************************************************/
+uint32_t NWKU_GetFirstBitValueInRange
+(
+    uint8_t *pArray,
+    uint32_t lowBitNr,
+    uint32_t highBitNr,
+    bool_t bitValue
+)
+{
+    for (; lowBitNr < highBitNr; lowBitNr++)
+    {
+        if (bitValue == NWKU_GetBit(lowBitNr, pArray))
+        {
+            return lowBitNr;
+        }
+    }
+
+    return ((uint32_t) - 1); // invalid
+}
+
+/*!*************************************************************************************************
+\fn     uint32_t getFirstBitValue(uint8_t* pArray, uint32_t arrayBytes, bool_t bitValue)
+\brief  This function returns the index of the first bit with value=bitValue.
+
+\param  [in]    pArray          pointer to the start of the array
+\param  [in]    arrayBytes      number of bytes in the array
+\param  [in]    bitValue        bit value
+
+\return         uint32_t        bit value
+***************************************************************************************************/
+uint32_t NWKU_GetFirstBitValue
+(
+    uint8_t *pArray,
+    uint32_t arrayBytes,
+    bool_t bitValue
+)
+{
+    return NWKU_GetFirstBitValueInRange(pArray, 0, (arrayBytes * 8), bitValue);
+}
+
+/*!*************************************************************************************************
+\fn    otIp6Address *NWKU_GetSpecificMcastAddr(otInstance *pOtInstance, thrMcastAllThrNodes_t type)
+\brief This function is used to get a specific multicast address (Mesh Local All nodes multicast or
+       link local All nodes multicast)
+
+\param [in]    pOtInstance         Pointer to the OpenThread instance
+\param [in]    type                Ip address type: gMcastLLAddrAllThrNodes_c, gMcastMLAddrAllThrNodes_c
+
+\retval        otIp6Address        Pointer to requested multicast address
+***************************************************************************************************/
+
+otIp6Address *NWKU_GetSpecificMcastAddr
+(
+    otInstance *pOtInstance,
+    thrMcastAllThrNodes_t type
+)
+{
+    otIp6Address *pAddr = NULL;
+    const otNetifMulticastAddress *pMCastAddr = otIp6GetMulticastAddresses(pOtInstance);
+
+    while(pMCastAddr != NULL)
+    {
+        if((type == gMcastLLAddrAllThrNodes_c) && (pMCastAddr->mAddress.mFields.m8[1] == 0x32))
+        {
+            pAddr = (otIp6Address *)&pMCastAddr->mAddress;
+            break;
+        }
+        else if((type == gMcastMLAddrAllThrNodes_c) && (pMCastAddr->mAddress.mFields.m8[1] == 0x33))
+        {
+            pAddr = (otIp6Address *)&pMCastAddr->mAddress;
+            break;
+        }
+
+        pMCastAddr = pMCastAddr->mNext;
+    }
+
+    return pAddr;
+}
+
+/*!*************************************************************************************************
+\fn     void APP_OtSetMulticastAddresses(otInstance *pOtInstance)
+\brief  This function is used to set the multicast addresses from the stack for application usage.
+
+\param  [in]    pOtInstance      Pointer to OpenThread instance
+
+\return         NONE
+***************************************************************************************************/
+void NWKU_OtSetMulticastAddresses
+(
+    otInstance *pOtInstance
+)
+{
+    otIp6Address *pAddr = NULL;
+
+    pAddr = NWKU_GetSpecificMcastAddr(pOtInstance, gMcastLLAddrAllThrNodes_c);
+
+    if(pAddr != NULL)
+    {
+        memcpy(&in6addr_linklocal_allthreadnodes, pAddr, sizeof(otIp6Address));
+    }
+
+    pAddr = NWKU_GetSpecificMcastAddr(pOtInstance, gMcastMLAddrAllThrNodes_c);
+
+    if(pAddr != NULL)
+    {
+    	memcpy(&in6addr_realmlocal_allthreadnodes, pAddr, sizeof(otIp6Address));
+    }
+}
+
+/*==================================================================================================
+Private functions
+==================================================================================================*/
+
+/*==================================================================================================
+Private debug functions
+==================================================================================================*/
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.h b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.h
new file mode 100755
index 0000000..2145c94
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.h
@@ -0,0 +1,129 @@
+/*
+* Copyright 2019-2020 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _NETWORK_UTILS_H
+#define _NETWORK_UTILS_H
+
+/*!
+\file       network_utils.h
+\brief      This is a header file for the Network Utils module.
+*/
+
+/*==================================================================================================
+Include Files
+==================================================================================================*/
+#include <openthread/ip6.h>
+
+typedef bool bool_t;
+
+/*! Macro for IP address copy */
+#define IP_AddrCopy(dst, src) \
+        (dst)->m32[0] = (src)->m32[0]; \
+        (dst)->m32[1] = (src)->m32[1]; \
+        (dst)->m32[2] = (src)->m32[2]; \
+        (dst)->m32[3] = (src)->m32[3];
+
+/*! Macro for IPV6 address comparison */
+#define IP_IsAddrEqual(addr1, addr2) \
+        (((addr1)->m32[0] == (addr2)->m32[0]) && \
+         ((addr1)->m32[1] == (addr2)->m32[1]) && \
+         ((addr1)->m32[2] == (addr2)->m32[2]) && \
+         ((addr1)->m32[3] == (addr2)->m32[3]))
+
+/* RAM global addresses - updated when the device join the network */
+extern otIp6Address in6addr_linklocal_allthreadnodes;
+extern otIp6Address in6addr_realmlocal_allthreadnodes;
+extern otIp6Address in6addr_realmlocal_threadleaderanycast;
+
+/*==================================================================================================
+Public type definitions
+==================================================================================================*/
+/*! Multicast all thread nodes */
+typedef enum thrMcastAllThrNodes_tag
+{
+    gMcastLLAddrAllThrNodes_c,  /*!< Multicast link local - all thread nodes */
+    gMcastMLAddrAllThrNodes_c,  /*!< Multicast mesh local - all thread nodes */
+} thrMcastAllThrNodes_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!*************************************************************************************************
+\fn    otIp6Address *NWKU_GetSpecificMcastAddr(otInstance *pOtInstance, thrMcastAllThrNodes_t type)
+\brief This function is used to get a specific multicast address (Mesh Local All nodes multicast or
+       link local All nodes multicast)
+
+\param [in]    pOtInstance         Pointer to the OpenThread instance
+\param [in]    type                Ip address type: gMcastLLAddrAllThrNodes_c, gMcastMLAddrAllThrNodes_c
+
+\retval        otIp6Address        Pointer to requested multicast address
+***************************************************************************************************/
+otIp6Address *NWKU_GetSpecificMcastAddr(otInstance *pOtInstance, thrMcastAllThrNodes_t type);
+
+void NWKU_MemCpyReverseOrder(void* pDst, void* pSrc, uint32_t cBytes);
+
+/*!*************************************************************************************************
+\fn     uint32_t NWKU_GetFirstBitValueInRange(uint8_t* pArray, uint32_t lowBitNr, uint32_t
+        highBitNr, bool_t bitValue)
+\brief  This function returns the first bit with value=bitValue in a range in the array.
+
+\param  [in]    pArray          pointer to the start of the array
+\param  [in]    lowBitNr        starting bit number
+\param  [in]    highBitNr       ending bit number
+\param  [in]    bitValue        bit value
+
+\return         uint32_t        bit number
+***************************************************************************************************/
+uint32_t NWKU_GetFirstBitValueInRange(uint8_t *pArray, uint32_t lowBitNr, uint32_t highBitNr, bool_t bitValue);
+
+/*!*************************************************************************************************
+\fn     void NWKU_ClearBit(uint32_t bitNr, uint8_t* pArray)
+\brief  This function clears a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+***************************************************************************************************/
+void NWKU_ClearBit(uint32_t bitNr, uint8_t *pArray);
+
+/*!*************************************************************************************************
+\fn     void NWKU_SetBit(uint32_t bitNr, uint8_t* pArray)
+\brief  This function sets a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+***************************************************************************************************/
+void NWKU_SetBit(uint32_t bitNr, uint8_t *pArray);
+
+/*!*************************************************************************************************
+\fn     uint32_t getFirstBitValue(uint8_t* pArray, uint32_t arrayBytes, bool_t bitValue)
+\brief  This function returns the index of the first bit with value=bitValue.
+
+\param  [in]    pArray          pointer to the start of the array
+\param  [in]    arrayBytes      number of bytes in the array
+\param  [in]    bitValue        bit value
+
+\return         uint32_t        bit value
+***************************************************************************************************/
+uint32_t NWKU_GetFirstBitValue(uint8_t *pArray, uint32_t arrayBytes, bool_t bitValue);
+
+/*!*************************************************************************************************
+\fn     void APP_OtSetMulticastAddresses(otInstance *pOtInstance)
+\brief  This function is used to set the multicast addresses from the stack for application usage.
+
+\param  [in]    pOtInstance      Pointer to OpenThread instance
+
+\return         NONE
+***************************************************************************************************/
+void NWKU_OtSetMulticastAddresses(otInstance *pOtInstance);
+
+#ifdef __cplusplus
+}
+#endif
+/*================================================================================================*/
+#endif  /* _NETWORK_UTILS_H */
diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/posix_ota_server_readme.txt b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/posix_ota_server_readme.txt
new file mode 100755
index 0000000..8a11ceb
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/posix_ota_server_readme.txt
@@ -0,0 +1,64 @@
+This readme is intended to be used as a guideline for building the OpenThread POSIX Border Router application with NXP OTA server support,
+available for JN5189/K32W061(041) OpenThread SDK.
+
+The following steps must be followed:
+1. Clone the OpenThread repository available here: https://github.com/openthread
+
+2. Search for the spinel.h header file and open it. In older releases, the file was located in <ot_root>\src\ncp\, while in newer releases, the file resides in <ot_root>\src\lib\spinel\.
+
+	a. Beneath the line containing "SPINEL_CMD_VENDOR__BEGIN = 15360,", add the following lines:
+"
+    // NXP OTA START COMMAND
+	SPINEL_CMD_VENDOR_NXP_OTA_START = SPINEL_CMD_VENDOR__BEGIN + 1,
+	SPINEL_CMD_VENDOR_NXP_OTA_START_RET = SPINEL_CMD_VENDOR__BEGIN + 2,
+    SPINEL_CMD_VENDOR_NXP_OTA_STOP = SPINEL_CMD_VENDOR__BEGIN + 3,
+	SPINEL_CMD_VENDOR_NXP_OTA_STOP_RET = SPINEL_CMD_VENDOR__BEGIN + 4,
+    SPINEL_CMD_VENDOR_NXP_OTA_STATUS = SPINEL_CMD_VENDOR__BEGIN + 5,
+	SPINEL_CMD_VENDOR_NXP_OTA_STATUS_RET = SPINEL_CMD_VENDOR__BEGIN + 6,
+"
+
+	b. Beneath the line containing "SPINEL_PROP_VENDOR__BEGIN = 0x3C00,", add the following lines:
+"
+    SPINEL_PROP_NXP_OTA_START_RET = SPINEL_PROP_VENDOR__BEGIN + 0,
+    SPINEL_PROP_NXP_OTA_STOP_RET = SPINEL_PROP_VENDOR__BEGIN + 1,
+    SPINEL_PROP_NXP_OTA_STATUS_RET = SPINEL_PROP_VENDOR__BEGIN + 2,
+"
+
+	c. Save and close the file.
+
+3. Open main.c source file from <ot_root>\src\posix\.
+	a. Add the following include at the beginning of the file: #include "app_ota.h"
+	b. Before the "while (true)" loop, add a function call to OtaServerInit, for example "OtaServerInit(instance);".
+	c. At the end of the loop, before the closing brackets, add a function call to OtaServer_CheckTime, for example "OtaServer_CheckTime();".
+	d. Save and close the file.
+
+4. In Makefile.am from <ot_root>\src\posix\, do the following changes:
+	a. Add the following entry to CPPFLAGS_COMMON before $(NULL):
+"-I$(top_srcdir)/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server \"
+
+	b. Add the following entry to ot_ncp_SOURCES before $(NULL):
+"
+@top_builddir@/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c           \
+@top_builddir@/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c            \
+"
+
+	c. Add the following entry to ot_cli_SOURCES before $(NULL):
+"
+@top_builddir@/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c           \
+@top_builddir@/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c            \
+"
+
+	d. Save and close the file.
+
+5. In Makefile-posix from <ot_root>\src\posix\, do the following changes:
+	a. Add the following entry to configure_OPTIONS before $(NULL):
+"--with-ncp-vendor-hook-source="$(AbsTopSourceDir)/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp"\"
+
+	b. Add the following line under "# Platform specific switches":
+"COMMONCFLAGS                   += -DOPENTHREAD_ENABLE_NCP_VENDOR_HOOK=1"
+
+	c. Save and close the file.
+
+6. Run the bootstrap script and follow the rest of the steps to build and run the POSIX application described in <ot_root>\src\posix\README.md.
+
+Note: <sdk_root> needs to be replaced with JN5189DK6 or K32W061DK6.
\ No newline at end of file
diff --git a/third_party/nxp/JN5189DK6/tools/imagetool/dk6_image_tool.py b/third_party/nxp/JN5189DK6/tools/imagetool/dk6_image_tool.py
new file mode 100755
index 0000000..48ea6a2
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/tools/imagetool/dk6_image_tool.py
@@ -0,0 +1,503 @@
+#!python
+
+from collections import namedtuple
+import re
+import argparse
+import subprocess
+import struct
+from Crypto.Signature import pkcs1_15
+from Crypto.PublicKey import RSA
+from Crypto.Hash import SHA256
+from Crypto.Util import number
+import binascii
+import os
+import StringIO
+
+def auto_int(x):
+   return int(x, 0)
+
+parser = argparse.ArgumentParser(description='DK6 Image Header Generator')
+parser.add_argument('in_file', help="Binary to be post-processed: generating header and optionally appending certificate and/or signature.")
+parser.add_argument('out_file', nargs='?')
+parser.add_argument('-g', '--signature_path', help="Sets directory from which certificate and private key are to be retrieved")
+parser.add_argument('-k', '--key', action='store_true', help="2048 bits RSA private key in PEM format used to sign the full image. If -c option is used the full image includes the certificate + the signature of the certificate. The key shall be located in the same directory as the image_tool script. See priv_key.pem example.")
+parser.add_argument('-p', '--password',help="This is the pass phrase from which the encryption key is derived. This parameter is only required if key provided through the -k option is a PEM encrypted key.")
+parser.add_argument('-c', '--certificate', action='store_true', help="When option is selected, the certificate cert.bin is appended to the image.")
+parser.add_argument('-i', '--image_identifier', type=int, help="This parameter is to set the archive identifier. 0: SSBL or legacy JN518x/QN9090 applications, loaded at 0x00000000. 1: application (ZB) loaded at address 0x00004000 by default. 2: application (BLE) image loaded at address 0x00053000 by default")
+parser.add_argument('-a', '--appcore_image', action='store_true',help="This parameter is only relevant if dual application (app1 image) shall reside in flash. Do not use in conjunction with -i option.")
+parser.add_argument('-t', '--target_addr', type=int, help="Target address of image. Used in conjunction with -i option to override the default set by image identifier, or with -a option to specify address of the appcore image (app1 image).")
+parser.add_argument('-s', '--stated_size', type=int, help="This is the stated size of the image in bytes. Default is 0x48000.")
+parser.add_argument('-v', '--version', type=auto_int, default=0, help="Image version. Default is 0.")
+parser.add_argument('-b', '--verbose', type=int, default=0, help="verbosity level. Default is 0.")
+parser.add_argument('-cl', '--compatibility_list', help="Compatibility list")
+parser.add_argument('-sota', '--sota_number_of_blob', type=int, help="This parameter is used to generate the image directory command to be provisioned")
+parser.add_argument('-bid', '--blob_id', type=auto_int, help="This parameter is to add a blob id. Can be used only if the sota arg is given")
+
+
+JN518x_ES1 = 0
+args = parser.parse_args()
+
+elf_file_name = args.in_file
+bin_file_name = elf_file_name.split(".")[0]+'_temp.bin'
+
+if args.out_file is None:
+    args.out_file = elf_file_name
+
+verbose = args.verbose != 0
+
+
+def get_symbol_value(file, symb_name):
+    val = 0
+
+    objdump = subprocess.check_output(['arm-none-eabi-objdump', '--syms', file])
+
+    symb_re = re.compile(r'^([0-9a-f]{8})[\s\S]+[\s]+([0-9a-f]{8})\s([\w\.]+)')
+
+    for ln in StringIO.StringIO(objdump):
+        m = symb_re.match(ln)
+        if m:
+            if m.group(3) == symb_name:
+                val = int(m.group(1), 16)
+                break
+
+    return val
+
+def parse_sections(file):
+    sections = {}
+
+    Section = namedtuple('Section', ['idx', 'name', 'size', 'vma', 'lma', 'offset', 'align', 'flags'])
+
+    objdump = subprocess.check_output(['arm-none-eabi-objdump', '-h', file])
+
+    section_re = re.compile(r'(?P<idx>[0-9]+)\s'
+                            r'(?P<name>.{13,})s*'
+                            r'(?P<size>[0-9a-f]{8})\s*'
+                            r'(?P<vma>[0-9a-f]{8})\s*'
+                            r'(?P<lma>[0-9a-f]{8})\s*'
+                            r'(?P<offset>[0-9a-f]{8})\s*'
+                            r'(?P<align>[0-9*]*)\s*'
+                            r'(?P<flags>[[[\w]*[, [\w]*]*)')
+
+    for match in re.finditer(section_re, objdump):
+        sec_dict = match.groupdict()
+
+        sec_dict['idx'] = int(sec_dict['idx'])
+
+        for attr in ['vma', 'lma', 'size', 'offset']:
+            sec_dict[attr] = int(sec_dict[attr], 16)
+
+        sec_dict['align'] = eval(sec_dict['align'])
+
+        sections[sec_dict['name']] = Section(**sec_dict)
+
+    return sections
+
+def reverseString2by2(string, stringLength):
+    result = ""
+    i = stringLength-1
+    while i >=0:
+        result = result + string[i-1]
+        result = result + string[i]
+        i = i-2
+    return result
+
+def print_sota_img_directory_cmd(blobNumber):
+    nbBlobFound = 0
+    sota_final_print = ""
+    sota_final_print += "=================> SOTA information\n"
+    # Generate the image directory command that will be used to provison the device
+    valueToPrint = ".\\DK6Programmer.exe -V5 -s <COM_PORT> -P 1000000 -w PSECT:64@0x160="
+    for i in range(1,9):
+        bootable = "00"
+        if i==1:
+            bootable = "01"
+        position_in_flash = get_symbol_value(elf_file_name, "m_blob_position"+str(i))
+        position_in_flash = '%0*X' % (2,position_in_flash)
+        blobTargetAddr = get_symbol_value(elf_file_name, "m_blob"+str(i)+"_start")
+        blobTargetAddr = '%0*X' % (8,blobTargetAddr)
+        blobStatedSize = get_symbol_value(elf_file_name, "m_blob"+str(i)+"_size")
+        if position_in_flash != "00" and blobStatedSize != 0:
+            nbBlobFound=nbBlobFound+1
+            sota_final_print += "Position in flash = "+ position_in_flash+" - targetAddr = 0x" +blobTargetAddr+ "\n"
+        blobTargetAddr = reverseString2by2(blobTargetAddr, len(blobTargetAddr))
+        blobNbPage = blobStatedSize/512
+        blobNbPage = '%0*X' % (4,blobNbPage)
+        blobNbPage = reverseString2by2(blobNbPage, len(blobNbPage))
+        if blobStatedSize != 0:
+            valueToPrint = valueToPrint + blobTargetAddr + blobNbPage + bootable + position_in_flash
+        else:
+            valueToPrint = valueToPrint + "0000000000000000"
+    sota_final_print += "=====> Image directory command"
+    sota_final_print += valueToPrint
+    sota_final_print += "=================> (end) SOTA information"
+    if nbBlobFound == blobNumber:
+        print sota_final_print
+
+#
+# JN518x ES1 version
+######################
+if JN518x_ES1 == 1: # deprecated
+
+    BOOT_BLOCK_MARKER = 0xBB0110BB
+
+    header_struct     = struct.Struct('<7LLLLL')
+    boot_block_struct = struct.Struct('<6LQ')
+
+    sections = parse_sections(args.in_file)
+
+    last_section = None
+
+    for name, section in sections.iteritems():
+        if 'LOAD' in section.flags:
+            if last_section is None or section.lma > last_section.lma:
+                if section.size > 0:
+                    last_section = section
+
+    if args.appcore_image is True:
+        image_size = last_section.lma + last_section.size - args.target_appcore_addr
+    else:
+        image_size = last_section.lma + last_section.size
+
+    dump_section = subprocess.check_output(['arm-none-eabi-objcopy', '--dump-section', '%s=data.bin' % last_section.name, args.in_file])
+
+    if args.appcore_image is True:
+        boot_block = boot_block_struct.pack(BOOT_BLOCK_MARKER, 1, args.target_appcore_addr, image_size + boot_block_struct.size, 0, 0, 0)
+    else:
+        boot_block = boot_block_struct.pack(BOOT_BLOCK_MARKER, 0, 0, image_size + boot_block_struct.size, 0, 0, 0)
+
+    with open('data.bin', 'ab') as out_file:
+        out_file.write(boot_block)
+
+    update_section = subprocess.check_output(['arm-none-eabi-objcopy', '--update-section', '%s=data.bin' % last_section.name, args.in_file, args.out_file])
+
+    first_section = None
+
+    for name, section in sections.iteritems():
+        if 'LOAD' in section.flags:
+            if first_section is None or section.lma < first_section.lma:
+                first_section = section
+
+    with open(args.out_file, 'r+b') as elf_file:
+        elf_file.seek(first_section.offset)
+        vectors = elf_file.read(header_struct.size)
+
+        fields = list(header_struct.unpack(vectors))
+
+        vectsum = 0
+
+        for x in range(7):
+            vectsum += fields[x]
+
+        fields[7]  = (~vectsum & 0xFFFFFFFF) + 1
+        if args.appcore_image is True:
+            fields[9]  = 0x02794498
+        else:
+            fields[9]  = 0x98447902
+        #fields[9]  = 0x98447902
+        fields[10] = image_size
+
+        print "Writing checksum {:08x} to file {:s}".format(vectsum, args.out_file)
+
+        elf_file.seek(first_section.offset)
+        elf_file.write(header_struct.pack(*fields))
+
+#
+# JN518x ES2 version
+######################
+else:
+    is_signature = False
+    error = 0
+    if args.signature_path is not None:
+        sign_dir_path = os.path.join(os.path.dirname(__file__), args.signature_path)
+        priv_key_file_path = os.path.join(sign_dir_path, 'priv_key.pem')
+        cert_file_path = os.path.join(sign_dir_path, 'cert.bin')
+    else:
+        sign_dir_path = os.path.join(os.path.dirname(__file__), '')
+        priv_key_file_path = os.path.join(sign_dir_path, 'testkey_es2.pem')
+        cert_file_path = os.path.join(sign_dir_path, 'certif_es2')
+
+    if args.key is True:
+        key_file_path = priv_key_file_path
+        if verbose:
+            print "key path is " + key_file_path
+        if (os.path.isfile(key_file_path)):
+            key_file=open(key_file_path, 'r')
+            key = RSA.importKey(key_file.read(), args.password)
+            print "Private RSA key processing..."
+            is_signature = True
+
+    compatibility_struct     = struct.Struct('<2L')
+    compatibility_len_struct = struct.Struct('<L')
+    if args.compatibility_list is not None:
+        print "Compatibility list:"
+        if verbose:
+            print "    {}".format(args.compatibility_list)
+        compatibility_list = [map(auto_int, compatibility_item.split(",")) for compatibility_item in args.compatibility_list.split(";")]
+        print "    Length: {}".format(len(compatibility_list))
+        for i in range(len(compatibility_list)):
+            item = compatibility_list[i]
+            for j in range(len(item)):
+                if j ==1:
+                    blobIdCompatibilityList = "     Blob ID 0x="  + '%0*X' % (8,item[j-1])
+                    print "Blob ID =0x"+'%0*X' % (4,item[j-1]) +" - version =0x"+'%0*X' % (8,item[j])
+        compatibility_len = len(compatibility_list) * compatibility_struct.size + compatibility_len_struct.size
+        if verbose:
+            print "    {}".format(compatibility_len)
+    else:
+        compatibility_list = []
+        compatibility_len = 0
+        print "No compatibility list"
+
+    # make sure that the compatibility list is added and equals to nb_blob - 1
+    if args.sota_number_of_blob is not None and (compatibility_len/compatibility_struct.size) != args.sota_number_of_blob-1:
+        print "!!! Error the compatibility list length must be = to the number of blobs -1 : "+str(compatibility_len/compatibility_struct.size)+"(len) != "+ str(args.sota_number_of_blob-1)
+        error = 1
+    #make sure that the blob ID is given
+    if args.sota_number_of_blob is not None and args.blob_id is None:
+        print "!!! Error the blob ID is missing"
+        error = 1
+
+    bin_output = subprocess.check_output(['arm-none-eabi-objcopy', '-O', 'binary', elf_file_name, bin_file_name])
+
+    with open(bin_file_name, 'rb') as in_file:
+        input_file = in_file.read()
+
+    BOOT_BLOCK_MARKER      = 0xBB0110BB
+    IMAGE_HEADER_MARKER    = 0x98447902
+    IMAGE_HEADER_APP_CORE  = 0x02794498
+    IMAGE_HEADER_ESCORE    = IMAGE_HEADER_MARKER
+    SSBL_OR_LEGACY_ADDRESS = 0x00000000
+    SSBL_STATED_SIZE       = 0x2000
+    ZB_TARGET_ADDRESS      = SSBL_STATED_SIZE * 2
+    ZB_STATED_SIZE         = 0x4f000
+    BLE_TARGET_ADDRESS     = ZB_TARGET_ADDRESS + ZB_STATED_SIZE
+    BLE_STATED_SIZE        = 0x40000
+
+    header_struct     = struct.Struct('<7LLLLL')
+    boot_block_struct = struct.Struct('<8L')
+
+    boot_block_marker = BOOT_BLOCK_MARKER
+    if args.image_identifier is not None:
+        image_iden = args.image_identifier
+    else:
+        image_iden = 0
+
+    if verbose:
+        print "Image Identifier is {:d}".format(image_iden)
+
+   #Default value initialization
+    image_addr = 0
+    stated_size = 0
+
+    #Default value for SSBL, ZigbeeFull and BleFull image id
+    if image_iden == 0:
+        image_addr = SSBL_OR_LEGACY_ADDRESS
+        stated_size = SSBL_STATED_SIZE
+    elif image_iden == 1:
+        image_addr = ZB_TARGET_ADDRESS
+    elif image_iden == 2:
+        image_addr = BLE_TARGET_ADDRESS
+
+    image_addr = get_symbol_value(elf_file_name, 'm_app_start')
+
+    stated_size = get_symbol_value(elf_file_name, 'm_app_size')
+
+    # In case of SOTA get the position in flash from the linker it should be the app_id
+    if args.sota_number_of_blob is not None:
+        if args.image_identifier is None:
+            image_iden = get_symbol_value(elf_file_name, '__blob_position__')
+            print "Blob position in flash = #"+str(image_iden)
+
+    img_header_marker = IMAGE_HEADER_MARKER + image_iden
+
+    # Overwrite defaults for image address, stated size and header marker (-t, -s, -a options)
+    if args.target_addr is not None:
+        image_addr = args.target_addr
+    if args.stated_size is not None:
+        stated_size = args.stated_size
+    if args.appcore_image is True:
+        img_header_marker  = IMAGE_HEADER_APP_CORE
+
+    if verbose:
+        print "image_iden=%d image_addr=%x" % (image_iden, image_addr)
+        print "stated_size=%d" % (stated_size)
+        print "version=0x%0*X" % (8,args.version)
+        print "boot_block_marker=%x" % (boot_block_marker)
+
+    sections = parse_sections(elf_file_name)
+
+    last_section = None
+    for name, section in sections.iteritems():
+        if 'LOAD' in section.flags:
+            if last_section is None or section.lma > last_section.lma:
+                if section.size > 0:
+                    last_section = section
+
+    # IAR toolchain uses odd section names that contain spaces
+    # the regexp now may now return trailing spaces too, need to strip them
+    last_section_name = last_section.name.rstrip()
+    # and add quotes around the section name 
+    last_section_name = r"%s" % (last_section_name)
+	
+    boot_block_offset = last_section.lma + last_section.size + compatibility_len - image_addr
+
+    # Correction for image size not being multiple of 4 (IAR)
+    padding_len = ((4 - (boot_block_offset%4)) & 3)
+    padding_bytes = bytearray(padding_len)
+    boot_block_offset = boot_block_offset + padding_len
+
+    print "boot block offset =%x" % (boot_block_offset)
+    if verbose:
+        print "Last Section LMA={:08x} Size={:08x}".format(last_section.lma, last_section.size)
+        print "ImageAddress={:08x}".format(image_addr)
+
+    first_section = None
+
+    for name, section in sections.iteritems():
+        # print "Section: {:s} {:s} {:x} {:x}".format(name, section.flags, section.lma, section.size)
+        if 'LOAD' in section.flags:
+            if first_section is None or section.lma < first_section.lma:
+                first_section = section
+
+    header=""
+    with open(args.out_file, 'r+b') as elf_file:
+        elf_file.seek(first_section.offset)
+        vectors = elf_file.read(header_struct.size)
+
+        fields = list(header_struct.unpack(vectors))
+
+        vectsum = 0
+        for x in range(7):
+            vectsum += fields[x]
+
+        fields[7]  = (~vectsum & 0xFFFFFFFF) + 1
+        fields[8]  = img_header_marker
+        fields[9]  = boot_block_offset
+
+        #Compute crc
+        head_struct     = struct.Struct('<10L')
+        try:
+            if verbose:
+                for i in range(10):
+                    print "Header[{:d}]= {:08x}".format(i, fields[i])
+            values = head_struct.pack(fields[0],
+                                  fields[1],
+                                  fields[2],
+                                  fields[3],
+                                  fields[4],
+                                  fields[5],
+                                  fields[6],
+                                  fields[7],
+                                  fields[8],
+                                  fields[9])
+            fields[10] = binascii.crc32(values) & 0xFFFFFFFF
+        except:
+            error = 1
+
+        print "Writing checksum {:08x} to file {:s}".format(vectsum, args.out_file)
+        print "Writing CRC32 of header {:08x} to file {:s}".format(fields[10], args.out_file)
+
+
+        elf_file.seek(first_section.offset)
+        header = header_struct.pack(*fields);
+        elf_file.write(header)
+
+    dump_section = subprocess.check_output(['arm-none-eabi-objcopy',
+                                            '--dump-section',
+                                            '%s=data.bin' % last_section_name,
+                                            args.out_file])
+
+    certificate = ""
+    certificate_offset = 0
+    signature = ""
+    compatibility = ""
+    compatibility_offset = 0
+
+    if args.compatibility_list is not None:
+        compatibility_offset = last_section.lma + last_section.size - image_addr
+        compatibility = compatibility_len_struct.pack(len(compatibility_list)) + ''.join([compatibility_struct.pack(*compatibility_item) for compatibility_item in compatibility_list])
+        print "Compatibility processing..."
+
+    if (args.certificate is True):
+        certificate_offset = boot_block_offset + boot_block_struct.size
+        certif_file_path = cert_file_path
+        if verbose:
+            print "Cert key path is " + cert_file_path
+        if (os.path.isfile(certif_file_path)):
+            certif_file=open(certif_file_path, 'rb')
+            certificate = certif_file.read()
+
+        print "Certificate processing..."
+        if len(certificate) != (40+256+256):
+            print "Certificate error"
+            error = 1
+
+    if verbose:
+        print "stated size is {:08x} ({})".format(stated_size,stated_size)
+
+    if args.appcore_image is True:
+        boot_block_id = 1
+    else:
+        boot_block_id = 0
+
+    if args.blob_id is not None:
+        boot_block_id = args.blob_id
+
+    boot_block = boot_block_struct.pack(boot_block_marker,
+                                        boot_block_id,
+                                        image_addr,
+                                        boot_block_offset + boot_block_struct.size + len(certificate), # padding already included in the boot_block_offset
+                                        stated_size,
+                                        certificate_offset,
+                                        compatibility_offset,
+                                        args.version)
+
+    if (is_signature == True):
+        # Sign the complete image
+        message = header + input_file[header_struct.size:] + boot_block + certificate
+        hash = SHA256.new(message)
+
+        out_file_path = os.path.join(os.path.dirname(__file__), 'dump_python.bin')
+        file_out=open(out_file_path, 'wb')
+        file_out.write(message)
+
+        signer = pkcs1_15.new(key)
+        signature = signer.sign(hash)
+
+        print "Signature processing..."
+
+    with open('data.bin', 'ab') as out_file:
+        out_file.write(compatibility+padding_bytes+boot_block+certificate+signature)
+    if verbose:
+        print "Updating last section " + last_section.name
+
+    update_section = subprocess.check_output(['arm-none-eabi-objcopy',
+                                              '--update-section',
+                                              '%s=data.bin' % last_section_name,
+                                              elf_file_name,
+                                              args.out_file])
+
+
+    if (is_signature == True):
+        file_out.close()
+
+    bin_output = subprocess.check_output(['arm-none-eabi-objcopy',
+                                          '-O',
+                                          'binary',
+                                          elf_file_name,
+                                          bin_file_name])
+
+    print "Binary size is {:08x} ({})".format(os.stat(bin_file_name).st_size,os.stat(bin_file_name).st_size)
+
+    if args.sota_number_of_blob is not None:
+        print_sota_img_directory_cmd(args.sota_number_of_blob)
+
+    if os.stat(bin_file_name).st_size > stated_size:
+        print "Error: Binary file size ({:08x}) must be less or equal to stated size {:08x}".format(os.stat(bin_file_name).st_size, stated_size)
+        error = 1
+
+    if error != 0:
+        os.remove(elf_file_name)
+        os.remove(out_file_path)
+
+    os.remove(bin_file_name)
diff --git a/third_party/nxp/JN5189DK6/tools/imagetool/sign_images.sh b/third_party/nxp/JN5189DK6/tools/imagetool/sign_images.sh
new file mode 100755
index 0000000..5e0105a
--- /dev/null
+++ b/third_party/nxp/JN5189DK6/tools/imagetool/sign_images.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+# Copyright 2019 NXP
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Script gets as first command line argument the directory
+# containing the ELF files which will be signed using
+# $SIGNING_TOOL. After the signing process, the binary
+# is extracted from the ELF file and placed in an equivalent
+# filename with the .bin extension.
+
+
+function is_linux_package_installed()
+{
+	dpkg -s ${1} &> /dev/null
+
+	if [ $? -ne 0 ]; then
+        echo "Linux package ** ${1} ** is not installed! Please install it then recompile."
+        echo "Installation command (Debian-based Linux system): sudo apt-get install ${1}"
+		exit 1
+	fi
+}
+
+function is_python_package_installed()
+{
+	pip list --format=columns | grep -F ${1} &> /dev/null
+
+	if [ $? -ne 0 ]; then
+        echo "Python package ** ${1} ** is not installed! Please install it then recompile."
+        echo "Installation command: pip install ${1}"
+		exit 1
+	fi
+}
+
+is_linux_package_installed "python"
+is_linux_package_installed "python-pip"
+is_python_package_installed "pycrypto"
+is_python_package_installed "pycryptodome"
+
+CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+SIGNING_TOOL=$CURR_DIR/dk6_image_tool.py
+MIME_PATTERN="application/x-executable"
+
+if [ "$#" -eq 1 ]; then
+	DIR_WITH_ELFS=$1
+
+	for FILENAME in $DIR_WITH_ELFS/*; do
+		MIME_SET="$(file -ib $FILENAME)"
+
+		if [[ $MIME_SET == *"$MIME_PATTERN"* ]]; then
+			python $SIGNING_TOOL $FILENAME
+			arm-none-eabi-objcopy -O binary $FILENAME $FILENAME.bin
+		fi
+	done
+fi
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/arm_common_tables.h b/third_party/nxp/K32W061DK6/CMSIS/Include/arm_common_tables.h
new file mode 100755
index 0000000..8742a56
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/arm_common_tables.h
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date:        19. October 2015
+* $Revision: 	V.1.4.5 a
+*
+* Project: 	    CMSIS DSP Library
+* Title:	    arm_common_tables.h
+*
+* Description:	This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED 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 OWNER 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 _ARM_COMMON_TABLES_H
+#define _ARM_COMMON_TABLES_H
+
+#include "arm_math.h"
+
+extern const uint16_t armBitRevTable[1024];
+extern const q15_t armRecipTableQ15[64];
+extern const q31_t armRecipTableQ31[64];
+/* extern const q31_t realCoefAQ31[1024]; */
+/* extern const q31_t realCoefBQ31[1024]; */
+extern const float32_t twiddleCoef_16[32];
+extern const float32_t twiddleCoef_32[64];
+extern const float32_t twiddleCoef_64[128];
+extern const float32_t twiddleCoef_128[256];
+extern const float32_t twiddleCoef_256[512];
+extern const float32_t twiddleCoef_512[1024];
+extern const float32_t twiddleCoef_1024[2048];
+extern const float32_t twiddleCoef_2048[4096];
+extern const float32_t twiddleCoef_4096[8192];
+#define twiddleCoef twiddleCoef_4096
+extern const q31_t twiddleCoef_16_q31[24];
+extern const q31_t twiddleCoef_32_q31[48];
+extern const q31_t twiddleCoef_64_q31[96];
+extern const q31_t twiddleCoef_128_q31[192];
+extern const q31_t twiddleCoef_256_q31[384];
+extern const q31_t twiddleCoef_512_q31[768];
+extern const q31_t twiddleCoef_1024_q31[1536];
+extern const q31_t twiddleCoef_2048_q31[3072];
+extern const q31_t twiddleCoef_4096_q31[6144];
+extern const q15_t twiddleCoef_16_q15[24];
+extern const q15_t twiddleCoef_32_q15[48];
+extern const q15_t twiddleCoef_64_q15[96];
+extern const q15_t twiddleCoef_128_q15[192];
+extern const q15_t twiddleCoef_256_q15[384];
+extern const q15_t twiddleCoef_512_q15[768];
+extern const q15_t twiddleCoef_1024_q15[1536];
+extern const q15_t twiddleCoef_2048_q15[3072];
+extern const q15_t twiddleCoef_4096_q15[6144];
+extern const float32_t twiddleCoef_rfft_32[32];
+extern const float32_t twiddleCoef_rfft_64[64];
+extern const float32_t twiddleCoef_rfft_128[128];
+extern const float32_t twiddleCoef_rfft_256[256];
+extern const float32_t twiddleCoef_rfft_512[512];
+extern const float32_t twiddleCoef_rfft_1024[1024];
+extern const float32_t twiddleCoef_rfft_2048[2048];
+extern const float32_t twiddleCoef_rfft_4096[4096];
+
+
+/* floating-point bit reversal tables */
+#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20  )
+#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48  )
+#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56  )
+#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
+#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
+#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
+#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
+#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
+#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
+
+/* fixed-point bit reversal tables */
+#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12  )
+#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24  )
+#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56  )
+#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
+#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
+#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
+#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
+#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
+#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
+
+/* Tables for Fast Math Sine and Cosine */
+extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
+extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
+extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
+
+#endif /*  ARM_COMMON_TABLES_H */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/arm_const_structs.h b/third_party/nxp/K32W061DK6/CMSIS/Include/arm_const_structs.h
new file mode 100755
index 0000000..726d06e
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/arm_const_structs.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date:        19. March 2015
+* $Revision: 	V.1.4.5
+*
+* Project: 	    CMSIS DSP Library
+* Title:	    arm_const_structs.h
+*
+* Description:	This file has constant structs that are initialized for
+*              user convenience.  For example, some can be given as
+*              arguments to the arm_cfft_f32() function.
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED 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 OWNER 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 _ARM_CONST_STRUCTS_H
+#define _ARM_CONST_STRUCTS_H
+
+#include "arm_math.h"
+#include "arm_common_tables.h"
+
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
+   extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
+
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
+   extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
+
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
+   extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
+
+#endif
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/arm_math.h b/third_party/nxp/K32W061DK6/CMSIS/Include/arm_math.h
new file mode 100755
index 0000000..d33f8a9
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/arm_math.h
@@ -0,0 +1,7154 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+*
+* $Date:        20. October 2015
+* $Revision:    V1.4.5 b
+*
+* Project:      CMSIS DSP Library
+* Title:        arm_math.h
+*
+* Description:  Public header file for CMSIS DSP Library
+*
+* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED 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 OWNER 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.
+ * -------------------------------------------------------------------- */
+
+/**
+   \mainpage CMSIS DSP Software Library
+   *
+   * Introduction
+   * ------------
+   *
+   * This user manual describes the CMSIS DSP software library,
+   * a suite of common signal processing functions for use on Cortex-M processor based devices.
+   *
+   * The library is divided into a number of functions each covering a specific category:
+   * - Basic math functions
+   * - Fast math functions
+   * - Complex math functions
+   * - Filters
+   * - Matrix functions
+   * - Transforms
+   * - Motor control functions
+   * - Statistical functions
+   * - Support functions
+   * - Interpolation functions
+   *
+   * The library has separate functions for operating on 8-bit integers, 16-bit integers,
+   * 32-bit integer and 32-bit floating-point values.
+   *
+   * Using the Library
+   * ------------
+   *
+   * The library installer contains prebuilt versions of the libraries in the <code>Lib</code> folder.
+   * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7)
+   * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7)
+   * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7)
+   * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7)
+   * - arm_cortexM7l_math.lib (Little endian on Cortex-M7)
+   * - arm_cortexM7b_math.lib (Big endian on Cortex-M7)
+   * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
+   * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
+   * - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
+   * - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
+   * - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
+   * - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
+   * - arm_cortexM0l_math.lib (Little endian on Cortex-M0 / CortexM0+)
+   * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+)
+   *
+   * The library functions are declared in the public file <code>arm_math.h</code> which is placed in the <code>Include</code> folder.
+   * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single
+   * public header file <code> arm_math.h</code> for Cortex-M7/M4/M3/M0/M0+ with little endian and big endian. Same header file will be used for floating point unit(FPU) variants.
+   * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or  ARM_MATH_CM3 or
+   * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application.
+   *
+   * Examples
+   * --------
+   *
+   * The library ships with a number of examples which demonstrate how to use the library functions.
+   *
+   * Toolchain Support
+   * ------------
+   *
+   * The library has been developed and tested with MDK-ARM version 5.14.0.0
+   * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly.
+   *
+   * Building the Library
+   * ------------
+   *
+   * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the <code>CMSIS\\DSP_Lib\\Source\\ARM</code> folder.
+   * - arm_cortexM_math.uvprojx
+   *
+   *
+   * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above.
+   *
+   * Pre-processor Macros
+   * ------------
+   *
+   * Each library project have differant pre-processor macros.
+   *
+   * - UNALIGNED_SUPPORT_DISABLE:
+   *
+   * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access
+   *
+   * - ARM_MATH_BIG_ENDIAN:
+   *
+   * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets.
+   *
+   * - ARM_MATH_MATRIX_CHECK:
+   *
+   * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices
+   *
+   * - ARM_MATH_ROUNDING:
+   *
+   * Define macro ARM_MATH_ROUNDING for rounding on support functions
+   *
+   * - ARM_MATH_CMx:
+   *
+   * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target
+   * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and
+   * ARM_MATH_CM7 for building the library on cortex-M7.
+   *
+   * - __FPU_PRESENT:
+   *
+   * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries
+   *
+   * <hr>
+   * CMSIS-DSP in ARM::CMSIS Pack
+   * -----------------------------
+   *
+   * The following files relevant to CMSIS-DSP are present in the <b>ARM::CMSIS</b> Pack directories:
+   * |File/Folder                   |Content                                                                 |
+   * |------------------------------|------------------------------------------------------------------------|
+   * |\b CMSIS\\Documentation\\DSP  | This documentation                                                     |
+   * |\b CMSIS\\DSP_Lib             | Software license agreement (license.txt)                               |
+   * |\b CMSIS\\DSP_Lib\\Examples   | Example projects demonstrating the usage of the library functions      |
+   * |\b CMSIS\\DSP_Lib\\Source     | Source files for rebuilding the library                                |
+   *
+   * <hr>
+   * Revision History of CMSIS-DSP
+   * ------------
+   * Please refer to \ref ChangeLog_pg.
+   *
+   * Copyright Notice
+   * ------------
+   *
+   * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+   */
+
+
+/**
+ * @defgroup groupMath Basic Math Functions
+ */
+
+/**
+ * @defgroup groupFastMath Fast Math Functions
+ * This set of functions provides a fast approximation to sine, cosine, and square root.
+ * As compared to most of the other functions in the CMSIS math library, the fast math functions
+ * operate on individual values and not arrays.
+ * There are separate functions for Q15, Q31, and floating-point data.
+ *
+ */
+
+/**
+ * @defgroup groupCmplxMath Complex Math Functions
+ * This set of functions operates on complex data vectors.
+ * The data in the complex arrays is stored in an interleaved fashion
+ * (real, imag, real, imag, ...).
+ * In the API functions, the number of samples in a complex array refers
+ * to the number of complex values; the array contains twice this number of
+ * real values.
+ */
+
+/**
+ * @defgroup groupFilters Filtering Functions
+ */
+
+/**
+ * @defgroup groupMatrix Matrix Functions
+ *
+ * This set of functions provides basic matrix math operations.
+ * The functions operate on matrix data structures.  For example,
+ * the type
+ * definition for the floating-point matrix structure is shown
+ * below:
+ * <pre>
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * </pre>
+ * There are similar definitions for Q15 and Q31 data types.
+ *
+ * The structure specifies the size of the matrix and then points to
+ * an array of data.  The array is of size <code>numRows X numCols</code>
+ * and the values are arranged in row order.  That is, the
+ * matrix element (i, j) is stored at:
+ * <pre>
+ *     pData[i*numCols + j]
+ * </pre>
+ *
+ * \par Init Functions
+ * There is an associated initialization function for each type of matrix
+ * data structure.
+ * The initialization function sets the values of the internal structure fields.
+ * Refer to the function <code>arm_mat_init_f32()</code>, <code>arm_mat_init_q31()</code>
+ * and <code>arm_mat_init_q15()</code> for floating-point, Q31 and Q15 types,  respectively.
+ *
+ * \par
+ * Use of the initialization function is optional. However, if initialization function is used
+ * then the instance structure cannot be placed into a const data section.
+ * To place the instance structure in a const data
+ * section, manually initialize the data structure.  For example:
+ * <pre>
+ * <code>arm_matrix_instance_f32 S = {nRows, nColumns, pData};</code>
+ * <code>arm_matrix_instance_q31 S = {nRows, nColumns, pData};</code>
+ * <code>arm_matrix_instance_q15 S = {nRows, nColumns, pData};</code>
+ * </pre>
+ * where <code>nRows</code> specifies the number of rows, <code>nColumns</code>
+ * specifies the number of columns, and <code>pData</code> points to the
+ * data array.
+ *
+ * \par Size Checking
+ * By default all of the matrix functions perform size checking on the input and
+ * output matrices.  For example, the matrix addition function verifies that the
+ * two input matrices and the output matrix all have the same number of rows and
+ * columns.  If the size check fails the functions return:
+ * <pre>
+ *     ARM_MATH_SIZE_MISMATCH
+ * </pre>
+ * Otherwise the functions return
+ * <pre>
+ *     ARM_MATH_SUCCESS
+ * </pre>
+ * There is some overhead associated with this matrix size checking.
+ * The matrix size checking is enabled via the \#define
+ * <pre>
+ *     ARM_MATH_MATRIX_CHECK
+ * </pre>
+ * within the library project settings.  By default this macro is defined
+ * and size checking is enabled.  By changing the project settings and
+ * undefining this macro size checking is eliminated and the functions
+ * run a bit faster.  With size checking disabled the functions always
+ * return <code>ARM_MATH_SUCCESS</code>.
+ */
+
+/**
+ * @defgroup groupTransforms Transform Functions
+ */
+
+/**
+ * @defgroup groupController Controller Functions
+ */
+
+/**
+ * @defgroup groupStats Statistics Functions
+ */
+/**
+ * @defgroup groupSupport Support Functions
+ */
+
+/**
+ * @defgroup groupInterpolation Interpolation Functions
+ * These functions perform 1- and 2-dimensional interpolation of data.
+ * Linear interpolation is used for 1-dimensional data and
+ * bilinear interpolation is used for 2-dimensional data.
+ */
+
+/**
+ * @defgroup groupExamples Examples
+ */
+#ifndef _ARM_MATH_H
+#define _ARM_MATH_H
+
+/* ignore some GCC warnings */
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#define __CMSIS_GENERIC         /* disable NVIC and Systick functions */
+
+#if defined(ARM_MATH_CM7)
+  #include "core_cm7.h"
+#elif defined (ARM_MATH_CM4)
+  #include "core_cm4.h"
+#elif defined (ARM_MATH_CM3)
+  #include "core_cm3.h"
+#elif defined (ARM_MATH_CM0)
+  #include "core_cm0.h"
+  #define ARM_MATH_CM0_FAMILY
+#elif defined (ARM_MATH_CM0PLUS)
+  #include "core_cm0plus.h"
+  #define ARM_MATH_CM0_FAMILY
+#else
+  #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0"
+#endif
+
+#undef  __CMSIS_GENERIC         /* enable NVIC and Systick functions */
+#include "string.h"
+#include "math.h"
+#ifdef   __cplusplus
+extern "C"
+{
+#endif
+
+
+  /**
+   * @brief Macros required for reciprocal calculation in Normalized LMS
+   */
+
+#define DELTA_Q31          (0x100)
+#define DELTA_Q15          0x5
+#define INDEX_MASK         0x0000003F
+#ifndef PI
+#define PI                 3.14159265358979f
+#endif
+
+  /**
+   * @brief Macros required for SINE and COSINE Fast math approximations
+   */
+
+#define FAST_MATH_TABLE_SIZE  512
+#define FAST_MATH_Q31_SHIFT   (32 - 10)
+#define FAST_MATH_Q15_SHIFT   (16 - 10)
+#define CONTROLLER_Q31_SHIFT  (32 - 9)
+#define TABLE_SIZE  256
+#define TABLE_SPACING_Q31     0x400000
+#define TABLE_SPACING_Q15     0x80
+
+  /**
+   * @brief Macros required for SINE and COSINE Controller functions
+   */
+  /* 1.31(q31) Fixed value of 2/360 */
+  /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
+#define INPUT_SPACING         0xB60B61
+
+  /**
+   * @brief Macro for Unaligned Support
+   */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+    #define ALIGN4
+#else
+  #if defined  (__GNUC__)
+    #define ALIGN4 __attribute__((aligned(4)))
+  #else
+    #define ALIGN4 __align(4)
+  #endif
+#endif   /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+  /**
+   * @brief Error status returned by some functions in the library.
+   */
+
+  typedef enum
+  {
+    ARM_MATH_SUCCESS = 0,                /**< No error */
+    ARM_MATH_ARGUMENT_ERROR = -1,        /**< One or more arguments are incorrect */
+    ARM_MATH_LENGTH_ERROR = -2,          /**< Length of data buffer is incorrect */
+    ARM_MATH_SIZE_MISMATCH = -3,         /**< Size of matrices is not compatible with the operation. */
+    ARM_MATH_NANINF = -4,                /**< Not-a-number (NaN) or infinity is generated */
+    ARM_MATH_SINGULAR = -5,              /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+    ARM_MATH_TEST_FAILURE = -6           /**< Test Failed  */
+  } arm_status;
+
+  /**
+   * @brief 8-bit fractional data type in 1.7 format.
+   */
+  typedef int8_t q7_t;
+
+  /**
+   * @brief 16-bit fractional data type in 1.15 format.
+   */
+  typedef int16_t q15_t;
+
+  /**
+   * @brief 32-bit fractional data type in 1.31 format.
+   */
+  typedef int32_t q31_t;
+
+  /**
+   * @brief 64-bit fractional data type in 1.63 format.
+   */
+  typedef int64_t q63_t;
+
+  /**
+   * @brief 32-bit floating-point type definition.
+   */
+  typedef float float32_t;
+
+  /**
+   * @brief 64-bit floating-point type definition.
+   */
+  typedef double float64_t;
+
+  /**
+   * @brief definition to read/write two 16 bit values.
+   */
+#if defined __CC_ARM
+  #define __SIMD32_TYPE int32_t __packed
+  #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __SIMD32_TYPE int32_t
+  #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined __GNUC__
+  #define __SIMD32_TYPE int32_t
+  #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined __ICCARM__
+  #define __SIMD32_TYPE int32_t __packed
+  #define CMSIS_UNUSED
+
+#elif defined __CSMC__
+  #define __SIMD32_TYPE int32_t
+  #define CMSIS_UNUSED
+
+#elif defined __TASKING__
+  #define __SIMD32_TYPE __unaligned int32_t
+  #define CMSIS_UNUSED
+
+#else
+  #error Unknown compiler
+#endif
+
+#define __SIMD32(addr)        (*(__SIMD32_TYPE **) & (addr))
+#define __SIMD32_CONST(addr)  ((__SIMD32_TYPE *)(addr))
+#define _SIMD32_OFFSET(addr)  (*(__SIMD32_TYPE *)  (addr))
+#define __SIMD64(addr)        (*(int64_t **) & (addr))
+
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+  /**
+   * @brief definition to pack two 16 bit values.
+   */
+#define __PKHBT(ARG1, ARG2, ARG3)      ( (((int32_t)(ARG1) <<  0) & (int32_t)0x0000FFFF) | \
+                                         (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000)  )
+#define __PKHTB(ARG1, ARG2, ARG3)      ( (((int32_t)(ARG1) <<  0) & (int32_t)0xFFFF0000) | \
+                                         (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF)  )
+
+#endif
+
+
+   /**
+   * @brief definition to pack four 8 bit values.
+   */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) <<  0) & (int32_t)0x000000FF) | \
+                                (((int32_t)(v1) <<  8) & (int32_t)0x0000FF00) | \
+                                (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \
+                                (((int32_t)(v3) << 24) & (int32_t)0xFF000000)  )
+#else
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) <<  0) & (int32_t)0x000000FF) | \
+                                (((int32_t)(v2) <<  8) & (int32_t)0x0000FF00) | \
+                                (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \
+                                (((int32_t)(v0) << 24) & (int32_t)0xFF000000)  )
+
+#endif
+
+
+  /**
+   * @brief Clips Q63 to Q31 values.
+   */
+  static __INLINE q31_t clip_q63_to_q31(
+  q63_t x)
+  {
+    return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+      ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
+  }
+
+  /**
+   * @brief Clips Q63 to Q15 values.
+   */
+  static __INLINE q15_t clip_q63_to_q15(
+  q63_t x)
+  {
+    return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+      ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15);
+  }
+
+  /**
+   * @brief Clips Q31 to Q7 values.
+   */
+  static __INLINE q7_t clip_q31_to_q7(
+  q31_t x)
+  {
+    return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ?
+      ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x;
+  }
+
+  /**
+   * @brief Clips Q31 to Q15 values.
+   */
+  static __INLINE q15_t clip_q31_to_q15(
+  q31_t x)
+  {
+    return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ?
+      ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x;
+  }
+
+  /**
+   * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format.
+   */
+
+  static __INLINE q63_t mult32x64(
+  q63_t x,
+  q31_t y)
+  {
+    return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) +
+            (((q63_t) (x >> 32) * y)));
+  }
+
+/*
+  #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM   )
+  #define __CLZ __clz
+  #endif
+ */
+/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */
+#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__))  )
+  static __INLINE uint32_t __CLZ(
+  q31_t data);
+
+  static __INLINE uint32_t __CLZ(
+  q31_t data)
+  {
+    uint32_t count = 0;
+    uint32_t mask = 0x80000000;
+
+    while((data & mask) == 0)
+    {
+      count += 1u;
+      mask = mask >> 1u;
+    }
+
+    return (count);
+  }
+#endif
+
+  /**
+   * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
+   */
+
+  static __INLINE uint32_t arm_recip_q31(
+  q31_t in,
+  q31_t * dst,
+  q31_t * pRecipTable)
+  {
+    q31_t out;
+    uint32_t tempVal;
+    uint32_t index, i;
+    uint32_t signBits;
+
+    if(in > 0)
+    {
+      signBits = ((uint32_t) (__CLZ( in) - 1));
+    }
+    else
+    {
+      signBits = ((uint32_t) (__CLZ(-in) - 1));
+    }
+
+    /* Convert input sample to 1.31 format */
+    in = (in << signBits);
+
+    /* calculation of index for initial approximated Val */
+    index = (uint32_t)(in >> 24);
+    index = (index & INDEX_MASK);
+
+    /* 1.31 with exp 1 */
+    out = pRecipTable[index];
+
+    /* calculation of reciprocal value */
+    /* running approximation for two iterations */
+    for (i = 0u; i < 2u; i++)
+    {
+      tempVal = (uint32_t) (((q63_t) in * out) >> 31);
+      tempVal = 0x7FFFFFFFu - tempVal;
+      /*      1.31 with exp 1 */
+      /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */
+      out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30);
+    }
+
+    /* write output */
+    *dst = out;
+
+    /* return num of signbits of out = 1/in value */
+    return (signBits + 1u);
+  }
+
+
+  /**
+   * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type.
+   */
+  static __INLINE uint32_t arm_recip_q15(
+  q15_t in,
+  q15_t * dst,
+  q15_t * pRecipTable)
+  {
+    q15_t out = 0;
+    uint32_t tempVal = 0;
+    uint32_t index = 0, i = 0;
+    uint32_t signBits = 0;
+
+    if(in > 0)
+    {
+      signBits = ((uint32_t)(__CLZ( in) - 17));
+    }
+    else
+    {
+      signBits = ((uint32_t)(__CLZ(-in) - 17));
+    }
+
+    /* Convert input sample to 1.15 format */
+    in = (in << signBits);
+
+    /* calculation of index for initial approximated Val */
+    index = (uint32_t)(in >>  8);
+    index = (index & INDEX_MASK);
+
+    /*      1.15 with exp 1  */
+    out = pRecipTable[index];
+
+    /* calculation of reciprocal value */
+    /* running approximation for two iterations */
+    for (i = 0u; i < 2u; i++)
+    {
+      tempVal = (uint32_t) (((q31_t) in * out) >> 15);
+      tempVal = 0x7FFFu - tempVal;
+      /*      1.15 with exp 1 */
+      out = (q15_t) (((q31_t) out * tempVal) >> 14);
+      /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */
+    }
+
+    /* write output */
+    *dst = out;
+
+    /* return num of signbits of out = 1/in value */
+    return (signBits + 1);
+  }
+
+
+  /*
+   * @brief C custom defined intrinisic function for only M0 processors
+   */
+#if defined(ARM_MATH_CM0_FAMILY)
+  static __INLINE q31_t __SSAT(
+  q31_t x,
+  uint32_t y)
+  {
+    int32_t posMax, negMin;
+    uint32_t i;
+
+    posMax = 1;
+    for (i = 0; i < (y - 1); i++)
+    {
+      posMax = posMax * 2;
+    }
+
+    if(x > 0)
+    {
+      posMax = (posMax - 1);
+
+      if(x > posMax)
+      {
+        x = posMax;
+      }
+    }
+    else
+    {
+      negMin = -posMax;
+
+      if(x < negMin)
+      {
+        x = negMin;
+      }
+    }
+    return (x);
+  }
+#endif /* end of ARM_MATH_CM0_FAMILY */
+
+
+  /*
+   * @brief C custom defined intrinsic function for M3 and M0 processors
+   */
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+
+  /*
+   * @brief C custom defined QADD8 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QADD8(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s, t, u;
+
+    r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+    s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+    t = __SSAT(((((q31_t)x <<  8) >> 24) + (((q31_t)y <<  8) >> 24)), 8) & (int32_t)0x000000FF;
+    u = __SSAT(((((q31_t)x      ) >> 24) + (((q31_t)y      ) >> 24)), 8) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QSUB8 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QSUB8(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s, t, u;
+
+    r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+    s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+    t = __SSAT(((((q31_t)x <<  8) >> 24) - (((q31_t)y <<  8) >> 24)), 8) & (int32_t)0x000000FF;
+    u = __SSAT(((((q31_t)x      ) >> 24) - (((q31_t)y      ) >> 24)), 8) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QADD16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QADD16(
+  uint32_t x,
+  uint32_t y)
+  {
+/*  q31_t r,     s;  without initialisation 'arm_offset_q15 test' fails  but 'intrinsic' tests pass! for armCC */
+    q31_t r = 0, s = 0;
+
+    r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((q31_t)x      ) >> 16) + (((q31_t)y      ) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SHADD16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SHADD16(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((q31_t)x      ) >> 16) + (((q31_t)y      ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QSUB16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QSUB16(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((q31_t)x      ) >> 16) - (((q31_t)y      ) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SHSUB16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SHSUB16(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((q31_t)x      ) >> 16) - (((q31_t)y      ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QASX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QASX(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y      ) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((q31_t)x      ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SHASX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SHASX(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = (((((q31_t)x << 16) >> 16) - (((q31_t)y      ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((q31_t)x      ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined QSAX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __QSAX(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y      ) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((q31_t)x      ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SHSAX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SHSAX(
+  uint32_t x,
+  uint32_t y)
+  {
+    q31_t r, s;
+
+    r = (((((q31_t)x << 16) >> 16) + (((q31_t)y      ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((q31_t)x      ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r      )));
+  }
+
+
+  /*
+   * @brief C custom defined SMUSDX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMUSDX(
+  uint32_t x,
+  uint32_t y)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) -
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16))   ));
+  }
+
+  /*
+   * @brief C custom defined SMUADX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMUADX(
+  uint32_t x,
+  uint32_t y)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16))   ));
+  }
+
+
+  /*
+   * @brief C custom defined QADD for M3 and M0 processors
+   */
+  static __INLINE int32_t __QADD(
+  int32_t x,
+  int32_t y)
+  {
+    return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y)));
+  }
+
+
+  /*
+   * @brief C custom defined QSUB for M3 and M0 processors
+   */
+  static __INLINE int32_t __QSUB(
+  int32_t x,
+  int32_t y)
+  {
+    return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y)));
+  }
+
+
+  /*
+   * @brief C custom defined SMLAD for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMLAD(
+  uint32_t x,
+  uint32_t y,
+  uint32_t sum)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ( ((q31_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMLADX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMLADX(
+  uint32_t x,
+  uint32_t y,
+  uint32_t sum)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ( ((q31_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMLSDX for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMLSDX(
+  uint32_t x,
+  uint32_t y,
+  uint32_t sum)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) -
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ( ((q31_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMLALD for M3 and M0 processors
+   */
+  static __INLINE uint64_t __SMLALD(
+  uint32_t x,
+  uint32_t y,
+  uint64_t sum)
+  {
+/*  return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */
+    return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ( ((q63_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMLALDX for M3 and M0 processors
+   */
+  static __INLINE uint64_t __SMLALDX(
+  uint32_t x,
+  uint32_t y,
+  uint64_t sum)
+  {
+/*  return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */
+    return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y      ) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ( ((q63_t)sum    )                                  )   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMUAD for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMUAD(
+  uint32_t x,
+  uint32_t y)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y      ) >> 16))   ));
+  }
+
+
+  /*
+   * @brief C custom defined SMUSD for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SMUSD(
+  uint32_t x,
+  uint32_t y)
+  {
+    return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) -
+                       ((((q31_t)x      ) >> 16) * (((q31_t)y      ) >> 16))   ));
+  }
+
+
+  /*
+   * @brief C custom defined SXTB16 for M3 and M0 processors
+   */
+  static __INLINE uint32_t __SXTB16(
+  uint32_t x)
+  {
+    return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) |
+                       ((((q31_t)x <<  8) >>  8) & (q31_t)0xFFFF0000)  ));
+  }
+
+#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */
+
+
+  /**
+   * @brief Instance structure for the Q7 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;        /**< number of filter coefficients in the filter. */
+    q7_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q7_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } arm_fir_instance_q7;
+
+  /**
+   * @brief Instance structure for the Q15 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q15_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } arm_fir_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q31_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps. */
+  } arm_fir_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of filter coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+  } arm_fir_instance_f32;
+
+
+  /**
+   * @brief Processing function for the Q7 FIR filter.
+   * @param[in]  S          points to an instance of the Q7 FIR filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_q7(
+  const arm_fir_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q7 FIR filter.
+   * @param[in,out] S          points to an instance of the Q7 FIR structure.
+   * @param[in]     numTaps    Number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of samples that are processed.
+   */
+  void arm_fir_init_q7(
+  arm_fir_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR filter.
+   * @param[in]  S          points to an instance of the Q15 FIR structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_q15(
+  const arm_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q15 FIR filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_fast_q15(
+  const arm_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 FIR filter.
+   * @param[in,out] S          points to an instance of the Q15 FIR filter structure.
+   * @param[in]     numTaps    Number of filter coefficients in the filter. Must be even and greater than or equal to 4.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of samples that are processed at a time.
+   * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if
+   * <code>numTaps</code> is not a supported value.
+   */
+  arm_status arm_fir_init_q15(
+  arm_fir_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR filter.
+   * @param[in]  S          points to an instance of the Q31 FIR filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_q31(
+  const arm_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q31 FIR structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_fast_q31(
+  const arm_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 FIR filter.
+   * @param[in,out] S          points to an instance of the Q31 FIR structure.
+   * @param[in]     numTaps    Number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of samples that are processed at a time.
+   */
+  void arm_fir_init_q31(
+  arm_fir_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point FIR filter.
+   * @param[in]  S          points to an instance of the floating-point FIR structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_f32(
+  const arm_fir_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point FIR filter.
+   * @param[in,out] S          points to an instance of the floating-point FIR filter structure.
+   * @param[in]     numTaps    Number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of samples that are processed at a time.
+   */
+  void arm_fir_init_f32(
+  arm_fir_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    int8_t numStages;        /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q15_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q15_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    int8_t postShift;        /**< Additional shift, in bits, applied to each output sample. */
+  } arm_biquad_casd_df1_inst_q15;
+
+  /**
+   * @brief Instance structure for the Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q31_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< Additional shift, in bits, applied to each output sample. */
+  } arm_biquad_casd_df1_inst_q31;
+
+  /**
+   * @brief Instance structure for the floating-point Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;       /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;      /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_casd_df1_inst_f32;
+
+
+  /**
+   * @brief Processing function for the Q15 Biquad cascade filter.
+   * @param[in]  S          points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_q15(
+  const arm_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     postShift  Shift to be applied to the output. Varies according to the coefficients format
+   */
+  void arm_biquad_cascade_df1_init_q15(
+  arm_biquad_casd_df1_inst_q15 * S,
+  uint8_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int8_t postShift);
+
+
+  /**
+   * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_fast_q15(
+  const arm_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 Biquad cascade filter
+   * @param[in]  S          points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_q31(
+  const arm_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_fast_q31(
+  const arm_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     postShift  Shift to be applied to the output. Varies according to the coefficients format
+   */
+  void arm_biquad_cascade_df1_init_q31(
+  arm_biquad_casd_df1_inst_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int8_t postShift);
+
+
+  /**
+   * @brief Processing function for the floating-point Biquad cascade filter.
+   * @param[in]  S          points to an instance of the floating-point Biquad cascade structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df1_f32(
+  const arm_biquad_casd_df1_inst_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the floating-point Biquad cascade structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   */
+  void arm_biquad_cascade_df1_init_f32(
+  arm_biquad_casd_df1_inst_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float32_t *pData;     /**< points to the data of the matrix. */
+  } arm_matrix_instance_f32;
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float64_t *pData;     /**< points to the data of the matrix. */
+  } arm_matrix_instance_f64;
+
+  /**
+   * @brief Instance structure for the Q15 matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q15_t *pData;         /**< points to the data of the matrix. */
+  } arm_matrix_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q31_t *pData;         /**< points to the data of the matrix. */
+  } arm_matrix_instance_q31;
+
+
+  /**
+   * @brief Floating-point matrix addition.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_add_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix addition.
+   * @param[in]   pSrcA  points to the first input matrix structure
+   * @param[in]   pSrcB  points to the second input matrix structure
+   * @param[out]  pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_add_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst);
+
+
+  /**
+   * @brief Q31 matrix addition.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_add_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point, complex, matrix multiplication.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_cmplx_mult_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15, complex,  matrix multiplication.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_cmplx_mult_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst,
+  q15_t * pScratch);
+
+
+  /**
+   * @brief Q31, complex, matrix multiplication.
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_cmplx_mult_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix transpose.
+   * @param[in]  pSrc  points to the input matrix
+   * @param[out] pDst  points to the output matrix
+   * @return    The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_trans_f32(
+  const arm_matrix_instance_f32 * pSrc,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix transpose.
+   * @param[in]  pSrc  points to the input matrix
+   * @param[out] pDst  points to the output matrix
+   * @return    The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_trans_q15(
+  const arm_matrix_instance_q15 * pSrc,
+  arm_matrix_instance_q15 * pDst);
+
+
+  /**
+   * @brief Q31 matrix transpose.
+   * @param[in]  pSrc  points to the input matrix
+   * @param[out] pDst  points to the output matrix
+   * @return    The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_trans_q31(
+  const arm_matrix_instance_q31 * pSrc,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix multiplication
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix multiplication
+   * @param[in]  pSrcA   points to the first input matrix structure
+   * @param[in]  pSrcB   points to the second input matrix structure
+   * @param[out] pDst    points to output matrix structure
+   * @param[in]  pState  points to the array for storing intermediate results
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+
+  /**
+   * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA   points to the first input matrix structure
+   * @param[in]  pSrcB   points to the second input matrix structure
+   * @param[out] pDst    points to output matrix structure
+   * @param[in]  pState  points to the array for storing intermediate results
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_fast_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+
+  /**
+   * @brief Q31 matrix multiplication
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_mult_fast_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix subtraction
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_sub_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix subtraction
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_sub_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst);
+
+
+  /**
+   * @brief Q31 matrix subtraction
+   * @param[in]  pSrcA  points to the first input matrix structure
+   * @param[in]  pSrcB  points to the second input matrix structure
+   * @param[out] pDst   points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_sub_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix scaling.
+   * @param[in]  pSrc   points to the input matrix
+   * @param[in]  scale  scale factor
+   * @param[out] pDst   points to the output matrix
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_scale_f32(
+  const arm_matrix_instance_f32 * pSrc,
+  float32_t scale,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix scaling.
+   * @param[in]  pSrc        points to input matrix
+   * @param[in]  scaleFract  fractional portion of the scale factor
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to output matrix
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_scale_q15(
+  const arm_matrix_instance_q15 * pSrc,
+  q15_t scaleFract,
+  int32_t shift,
+  arm_matrix_instance_q15 * pDst);
+
+
+  /**
+   * @brief Q31 matrix scaling.
+   * @param[in]  pSrc        points to input matrix
+   * @param[in]  scaleFract  fractional portion of the scale factor
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+  arm_status arm_mat_scale_q31(
+  const arm_matrix_instance_q31 * pSrc,
+  q31_t scaleFract,
+  int32_t shift,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief  Q31 matrix initialization.
+   * @param[in,out] S         points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows     number of rows in the matrix.
+   * @param[in]     nColumns  number of columns in the matrix.
+   * @param[in]     pData     points to the matrix data array.
+   */
+  void arm_mat_init_q31(
+  arm_matrix_instance_q31 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q31_t * pData);
+
+
+  /**
+   * @brief  Q15 matrix initialization.
+   * @param[in,out] S         points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows     number of rows in the matrix.
+   * @param[in]     nColumns  number of columns in the matrix.
+   * @param[in]     pData     points to the matrix data array.
+   */
+  void arm_mat_init_q15(
+  arm_matrix_instance_q15 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q15_t * pData);
+
+
+  /**
+   * @brief  Floating-point matrix initialization.
+   * @param[in,out] S         points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows     number of rows in the matrix.
+   * @param[in]     nColumns  number of columns in the matrix.
+   * @param[in]     pData     points to the matrix data array.
+   */
+  void arm_mat_init_f32(
+  arm_matrix_instance_f32 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  float32_t * pData);
+
+
+
+  /**
+   * @brief Instance structure for the Q15 PID Control.
+   */
+  typedef struct
+  {
+    q15_t A0;           /**< The derived gain, A0 = Kp + Ki + Kd . */
+#ifdef ARM_MATH_CM0_FAMILY
+    q15_t A1;
+    q15_t A2;
+#else
+    q31_t A1;           /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
+#endif
+    q15_t state[3];     /**< The state array of length 3. */
+    q15_t Kp;           /**< The proportional gain. */
+    q15_t Ki;           /**< The integral gain. */
+    q15_t Kd;           /**< The derivative gain. */
+  } arm_pid_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 PID Control.
+   */
+  typedef struct
+  {
+    q31_t A0;            /**< The derived gain, A0 = Kp + Ki + Kd . */
+    q31_t A1;            /**< The derived gain, A1 = -Kp - 2Kd. */
+    q31_t A2;            /**< The derived gain, A2 = Kd . */
+    q31_t state[3];      /**< The state array of length 3. */
+    q31_t Kp;            /**< The proportional gain. */
+    q31_t Ki;            /**< The integral gain. */
+    q31_t Kd;            /**< The derivative gain. */
+  } arm_pid_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point PID Control.
+   */
+  typedef struct
+  {
+    float32_t A0;          /**< The derived gain, A0 = Kp + Ki + Kd . */
+    float32_t A1;          /**< The derived gain, A1 = -Kp - 2Kd. */
+    float32_t A2;          /**< The derived gain, A2 = Kd . */
+    float32_t state[3];    /**< The state array of length 3. */
+    float32_t Kp;          /**< The proportional gain. */
+    float32_t Ki;          /**< The integral gain. */
+    float32_t Kd;          /**< The derivative gain. */
+  } arm_pid_instance_f32;
+
+
+
+  /**
+   * @brief  Initialization function for the floating-point PID Control.
+   * @param[in,out] S               points to an instance of the PID structure.
+   * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   */
+  void arm_pid_init_f32(
+  arm_pid_instance_f32 * S,
+  int32_t resetStateFlag);
+
+
+  /**
+   * @brief  Reset function for the floating-point PID Control.
+   * @param[in,out] S  is an instance of the floating-point PID Control structure
+   */
+  void arm_pid_reset_f32(
+  arm_pid_instance_f32 * S);
+
+
+  /**
+   * @brief  Initialization function for the Q31 PID Control.
+   * @param[in,out] S               points to an instance of the Q15 PID structure.
+   * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   */
+  void arm_pid_init_q31(
+  arm_pid_instance_q31 * S,
+  int32_t resetStateFlag);
+
+
+  /**
+   * @brief  Reset function for the Q31 PID Control.
+   * @param[in,out] S   points to an instance of the Q31 PID Control structure
+   */
+
+  void arm_pid_reset_q31(
+  arm_pid_instance_q31 * S);
+
+
+  /**
+   * @brief  Initialization function for the Q15 PID Control.
+   * @param[in,out] S               points to an instance of the Q15 PID structure.
+   * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   */
+  void arm_pid_init_q15(
+  arm_pid_instance_q15 * S,
+  int32_t resetStateFlag);
+
+
+  /**
+   * @brief  Reset function for the Q15 PID Control.
+   * @param[in,out] S  points to an instance of the q15 PID Control structure
+   */
+  void arm_pid_reset_q15(
+  arm_pid_instance_q15 * S);
+
+
+  /**
+   * @brief Instance structure for the floating-point Linear Interpolate function.
+   */
+  typedef struct
+  {
+    uint32_t nValues;           /**< nValues */
+    float32_t x1;               /**< x1 */
+    float32_t xSpacing;         /**< xSpacing */
+    float32_t *pYData;          /**< pointer to the table of Y values */
+  } arm_linear_interp_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    float32_t *pData;   /**< points to the data table. */
+  } arm_bilinear_interp_instance_f32;
+
+   /**
+   * @brief Instance structure for the Q31 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q31_t *pData;       /**< points to the data table. */
+  } arm_bilinear_interp_instance_q31;
+
+   /**
+   * @brief Instance structure for the Q15 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q15_t *pData;       /**< points to the data table. */
+  } arm_bilinear_interp_instance_q15;
+
+   /**
+   * @brief Instance structure for the Q15 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q7_t *pData;        /**< points to the data table. */
+  } arm_bilinear_interp_instance_q7;
+
+
+  /**
+   * @brief Q7 vector multiplication.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_mult_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q15 vector multiplication.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_mult_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q31 vector multiplication.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_mult_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Floating-point vector multiplication.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_mult_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the Sin twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix2_instance_q15;
+
+/* Deprecated */
+  arm_status arm_cfft_radix2_init_q15(
+  arm_cfft_radix2_instance_q15 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix2_q15(
+  const arm_cfft_radix2_instance_q15 * S,
+  q15_t * pSrc);
+
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix4_instance_q15;
+
+/* Deprecated */
+  arm_status arm_cfft_radix4_init_q15(
+  arm_cfft_radix4_instance_q15 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix4_q15(
+  const arm_cfft_radix4_instance_q15 * S,
+  q15_t * pSrc);
+
+  /**
+   * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix2_instance_q31;
+
+/* Deprecated */
+  arm_status arm_cfft_radix2_init_q31(
+  arm_cfft_radix2_instance_q31 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix2_q31(
+  const arm_cfft_radix2_instance_q31 * S,
+  q31_t * pSrc);
+
+  /**
+   * @brief Instance structure for the Q31 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix4_instance_q31;
+
+/* Deprecated */
+  void arm_cfft_radix4_q31(
+  const arm_cfft_radix4_instance_q31 * S,
+  q31_t * pSrc);
+
+/* Deprecated */
+  arm_status arm_cfft_radix4_init_q31(
+  arm_cfft_radix4_instance_q31 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;             /**< value of 1/fftLen. */
+  } arm_cfft_radix2_instance_f32;
+
+/* Deprecated */
+  arm_status arm_cfft_radix2_init_f32(
+  arm_cfft_radix2_instance_f32 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix2_f32(
+  const arm_cfft_radix2_instance_f32 * S,
+  float32_t * pSrc);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;             /**< value of 1/fftLen. */
+  } arm_cfft_radix4_instance_f32;
+
+/* Deprecated */
+  arm_status arm_cfft_radix4_init_f32(
+  arm_cfft_radix4_instance_f32 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix4_f32(
+  const arm_cfft_radix4_instance_f32 * S,
+  float32_t * pSrc);
+
+  /**
+   * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const q15_t *pTwiddle;             /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } arm_cfft_instance_q15;
+
+void arm_cfft_q15(
+    const arm_cfft_instance_q15 * S,
+    q15_t * p1,
+    uint8_t ifftFlag,
+    uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const q31_t *pTwiddle;             /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } arm_cfft_instance_q31;
+
+void arm_cfft_q31(
+    const arm_cfft_instance_q31 * S,
+    q31_t * p1,
+    uint8_t ifftFlag,
+    uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const float32_t *pTwiddle;         /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } arm_cfft_instance_f32;
+
+  void arm_cfft_f32(
+  const arm_cfft_instance_f32 * S,
+  float32_t * p1,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the Q15 RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                      /**< length of the real FFT. */
+    uint8_t ifftFlagR;                        /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                  /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;               /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q15_t *pTwiddleAReal;                     /**< points to the real twiddle factor table. */
+    q15_t *pTwiddleBReal;                     /**< points to the imag twiddle factor table. */
+    const arm_cfft_instance_q15 *pCfft;       /**< points to the complex FFT instance. */
+  } arm_rfft_instance_q15;
+
+  arm_status arm_rfft_init_q15(
+  arm_rfft_instance_q15 * S,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_q15(
+  const arm_rfft_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst);
+
+  /**
+   * @brief Instance structure for the Q31 RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                 /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q31_t *pTwiddleAReal;                       /**< points to the real twiddle factor table. */
+    q31_t *pTwiddleBReal;                       /**< points to the imag twiddle factor table. */
+    const arm_cfft_instance_q31 *pCfft;         /**< points to the complex FFT instance. */
+  } arm_rfft_instance_q31;
+
+  arm_status arm_rfft_init_q31(
+  arm_rfft_instance_q31 * S,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_q31(
+  const arm_rfft_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint16_t fftLenBy2;                         /**< length of the complex FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                     /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    float32_t *pTwiddleAReal;                   /**< points to the real twiddle factor table. */
+    float32_t *pTwiddleBReal;                   /**< points to the imag twiddle factor table. */
+    arm_cfft_radix4_instance_f32 *pCfft;        /**< points to the complex FFT instance. */
+  } arm_rfft_instance_f32;
+
+  arm_status arm_rfft_init_f32(
+  arm_rfft_instance_f32 * S,
+  arm_cfft_radix4_instance_f32 * S_CFFT,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_f32(
+  const arm_rfft_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+typedef struct
+  {
+    arm_cfft_instance_f32 Sint;      /**< Internal CFFT structure. */
+    uint16_t fftLenRFFT;             /**< length of the real sequence */
+    float32_t * pTwiddleRFFT;        /**< Twiddle factors real stage  */
+  } arm_rfft_fast_instance_f32 ;
+
+arm_status arm_rfft_fast_init_f32 (
+   arm_rfft_fast_instance_f32 * S,
+   uint16_t fftLen);
+
+void arm_rfft_fast_f32(
+  arm_rfft_fast_instance_f32 * S,
+  float32_t * p, float32_t * pOut,
+  uint8_t ifftFlag);
+
+  /**
+   * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                          /**< length of the DCT4. */
+    uint16_t Nby2;                       /**< half of the length of the DCT4. */
+    float32_t normalize;                 /**< normalizing factor. */
+    float32_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    float32_t *pCosFactor;               /**< points to the cosFactor table. */
+    arm_rfft_instance_f32 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_f32;
+
+
+  /**
+   * @brief  Initialization function for the floating-point DCT4/IDCT4.
+   * @param[in,out] S          points to an instance of floating-point DCT4/IDCT4 structure.
+   * @param[in]     S_RFFT     points to an instance of floating-point RFFT/RIFFT structure.
+   * @param[in]     S_CFFT     points to an instance of floating-point CFFT/CIFFT structure.
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return      arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported transform length.
+   */
+  arm_status arm_dct4_init_f32(
+  arm_dct4_instance_f32 * S,
+  arm_rfft_instance_f32 * S_RFFT,
+  arm_cfft_radix4_instance_f32 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  float32_t normalize);
+
+
+  /**
+   * @brief Processing function for the floating-point DCT4/IDCT4.
+   * @param[in]     S              points to an instance of the floating-point DCT4/IDCT4 structure.
+   * @param[in]     pState         points to state buffer.
+   * @param[in,out] pInlineBuffer  points to the in-place input and output buffer.
+   */
+  void arm_dct4_f32(
+  const arm_dct4_instance_f32 * S,
+  float32_t * pState,
+  float32_t * pInlineBuffer);
+
+
+  /**
+   * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                          /**< length of the DCT4. */
+    uint16_t Nby2;                       /**< half of the length of the DCT4. */
+    q31_t normalize;                     /**< normalizing factor. */
+    q31_t *pTwiddle;                     /**< points to the twiddle factor table. */
+    q31_t *pCosFactor;                   /**< points to the cosFactor table. */
+    arm_rfft_instance_q31 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_q31;
+
+
+  /**
+   * @brief  Initialization function for the Q31 DCT4/IDCT4.
+   * @param[in,out] S          points to an instance of Q31 DCT4/IDCT4 structure.
+   * @param[in]     S_RFFT     points to an instance of Q31 RFFT/RIFFT structure
+   * @param[in]     S_CFFT     points to an instance of Q31 CFFT/CIFFT structure
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return      arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
+   */
+  arm_status arm_dct4_init_q31(
+  arm_dct4_instance_q31 * S,
+  arm_rfft_instance_q31 * S_RFFT,
+  arm_cfft_radix4_instance_q31 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q31_t normalize);
+
+
+  /**
+   * @brief Processing function for the Q31 DCT4/IDCT4.
+   * @param[in]     S              points to an instance of the Q31 DCT4 structure.
+   * @param[in]     pState         points to state buffer.
+   * @param[in,out] pInlineBuffer  points to the in-place input and output buffer.
+   */
+  void arm_dct4_q31(
+  const arm_dct4_instance_q31 * S,
+  q31_t * pState,
+  q31_t * pInlineBuffer);
+
+
+  /**
+   * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                          /**< length of the DCT4. */
+    uint16_t Nby2;                       /**< half of the length of the DCT4. */
+    q15_t normalize;                     /**< normalizing factor. */
+    q15_t *pTwiddle;                     /**< points to the twiddle factor table. */
+    q15_t *pCosFactor;                   /**< points to the cosFactor table. */
+    arm_rfft_instance_q15 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_q15;
+
+
+  /**
+   * @brief  Initialization function for the Q15 DCT4/IDCT4.
+   * @param[in,out] S          points to an instance of Q15 DCT4/IDCT4 structure.
+   * @param[in]     S_RFFT     points to an instance of Q15 RFFT/RIFFT structure.
+   * @param[in]     S_CFFT     points to an instance of Q15 CFFT/CIFFT structure.
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return      arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
+   */
+  arm_status arm_dct4_init_q15(
+  arm_dct4_instance_q15 * S,
+  arm_rfft_instance_q15 * S_RFFT,
+  arm_cfft_radix4_instance_q15 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q15_t normalize);
+
+
+  /**
+   * @brief Processing function for the Q15 DCT4/IDCT4.
+   * @param[in]     S              points to an instance of the Q15 DCT4 structure.
+   * @param[in]     pState         points to state buffer.
+   * @param[in,out] pInlineBuffer  points to the in-place input and output buffer.
+   */
+  void arm_dct4_q15(
+  const arm_dct4_instance_q15 * S,
+  q15_t * pState,
+  q15_t * pInlineBuffer);
+
+
+  /**
+   * @brief Floating-point vector addition.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_add_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q7 vector addition.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_add_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q15 vector addition.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_add_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q31 vector addition.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_add_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Floating-point vector subtraction.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_sub_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q7 vector subtraction.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_sub_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q15 vector subtraction.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_sub_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q31 vector subtraction.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_sub_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Multiplies a floating-point vector by a scalar.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  scale      scale factor to be applied
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_scale_f32(
+  float32_t * pSrc,
+  float32_t scale,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Multiplies a Q7 vector by a scalar.
+   * @param[in]  pSrc        points to the input vector
+   * @param[in]  scaleFract  fractional portion of the scale value
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to the output vector
+   * @param[in]  blockSize   number of samples in the vector
+   */
+  void arm_scale_q7(
+  q7_t * pSrc,
+  q7_t scaleFract,
+  int8_t shift,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Multiplies a Q15 vector by a scalar.
+   * @param[in]  pSrc        points to the input vector
+   * @param[in]  scaleFract  fractional portion of the scale value
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to the output vector
+   * @param[in]  blockSize   number of samples in the vector
+   */
+  void arm_scale_q15(
+  q15_t * pSrc,
+  q15_t scaleFract,
+  int8_t shift,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Multiplies a Q31 vector by a scalar.
+   * @param[in]  pSrc        points to the input vector
+   * @param[in]  scaleFract  fractional portion of the scale value
+   * @param[in]  shift       number of bits to shift the result by
+   * @param[out] pDst        points to the output vector
+   * @param[in]  blockSize   number of samples in the vector
+   */
+  void arm_scale_q31(
+  q31_t * pSrc,
+  q31_t scaleFract,
+  int8_t shift,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q7 vector absolute value.
+   * @param[in]  pSrc       points to the input buffer
+   * @param[out] pDst       points to the output buffer
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_abs_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Floating-point vector absolute value.
+   * @param[in]  pSrc       points to the input buffer
+   * @param[out] pDst       points to the output buffer
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_abs_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q15 vector absolute value.
+   * @param[in]  pSrc       points to the input buffer
+   * @param[out] pDst       points to the output buffer
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_abs_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Q31 vector absolute value.
+   * @param[in]  pSrc       points to the input buffer
+   * @param[out] pDst       points to the output buffer
+   * @param[in]  blockSize  number of samples in each vector
+   */
+  void arm_abs_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Dot product of floating-point vectors.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[in]  blockSize  number of samples in each vector
+   * @param[out] result     output result returned here
+   */
+  void arm_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t blockSize,
+  float32_t * result);
+
+
+  /**
+   * @brief Dot product of Q7 vectors.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[in]  blockSize  number of samples in each vector
+   * @param[out] result     output result returned here
+   */
+  void arm_dot_prod_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  uint32_t blockSize,
+  q31_t * result);
+
+
+  /**
+   * @brief Dot product of Q15 vectors.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[in]  blockSize  number of samples in each vector
+   * @param[out] result     output result returned here
+   */
+  void arm_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+
+  /**
+   * @brief Dot product of Q31 vectors.
+   * @param[in]  pSrcA      points to the first input vector
+   * @param[in]  pSrcB      points to the second input vector
+   * @param[in]  blockSize  number of samples in each vector
+   * @param[out] result     output result returned here
+   */
+  void arm_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+
+  /**
+   * @brief  Shifts the elements of a Q7 vector a specified number of bits.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  shiftBits  number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_shift_q7(
+  q7_t * pSrc,
+  int8_t shiftBits,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Shifts the elements of a Q15 vector a specified number of bits.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  shiftBits  number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_shift_q15(
+  q15_t * pSrc,
+  int8_t shiftBits,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Shifts the elements of a Q31 vector a specified number of bits.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  shiftBits  number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_shift_q31(
+  q31_t * pSrc,
+  int8_t shiftBits,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Adds a constant offset to a floating-point vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  offset     is the offset to be added
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_offset_f32(
+  float32_t * pSrc,
+  float32_t offset,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Adds a constant offset to a Q7 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  offset     is the offset to be added
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_offset_q7(
+  q7_t * pSrc,
+  q7_t offset,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Adds a constant offset to a Q15 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  offset     is the offset to be added
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_offset_q15(
+  q15_t * pSrc,
+  q15_t offset,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Adds a constant offset to a Q31 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[in]  offset     is the offset to be added
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_offset_q31(
+  q31_t * pSrc,
+  q31_t offset,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Negates the elements of a floating-point vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_negate_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Negates the elements of a Q7 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_negate_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Negates the elements of a Q15 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_negate_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Negates the elements of a Q31 vector.
+   * @param[in]  pSrc       points to the input vector
+   * @param[out] pDst       points to the output vector
+   * @param[in]  blockSize  number of samples in the vector
+   */
+  void arm_negate_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Copies the elements of a floating-point vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_copy_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Copies the elements of a Q7 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_copy_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Copies the elements of a Q15 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_copy_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Copies the elements of a Q31 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_copy_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Fills a constant value into a floating-point vector.
+   * @param[in]  value      input value to be filled
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_fill_f32(
+  float32_t value,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Fills a constant value into a Q7 vector.
+   * @param[in]  value      input value to be filled
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_fill_q7(
+  q7_t value,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Fills a constant value into a Q15 vector.
+   * @param[in]  value      input value to be filled
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_fill_q15(
+  q15_t value,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Fills a constant value into a Q31 vector.
+   * @param[in]  value      input value to be filled
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_fill_q31(
+  q31_t value,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+/**
+ * @brief Convolution of floating-point sequences.
+ * @param[in]  pSrcA    points to the first input sequence.
+ * @param[in]  srcALen  length of the first input sequence.
+ * @param[in]  pSrcB    points to the second input sequence.
+ * @param[in]  srcBLen  length of the second input sequence.
+ * @param[out] pDst     points to the location where the output result is written.  Length srcALen+srcBLen-1.
+ */
+  void arm_conv_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q15 sequences.
+   * @param[in]  pSrcA      points to the first input sequence.
+   * @param[in]  srcALen    length of the first input sequence.
+   * @param[in]  pSrcB      points to the second input sequence.
+   * @param[in]  srcBLen    length of the second input sequence.
+   * @param[out] pDst       points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  pScratch1  points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2  points to scratch buffer of size min(srcALen, srcBLen).
+   */
+  void arm_conv_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+/**
+ * @brief Convolution of Q15 sequences.
+ * @param[in]  pSrcA    points to the first input sequence.
+ * @param[in]  srcALen  length of the first input sequence.
+ * @param[in]  pSrcB    points to the second input sequence.
+ * @param[in]  srcBLen  length of the second input sequence.
+ * @param[out] pDst     points to the location where the output result is written.  Length srcALen+srcBLen-1.
+ */
+  void arm_conv_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length srcALen+srcBLen-1.
+   */
+  void arm_conv_fast_q15(
+          q15_t * pSrcA,
+          uint32_t srcALen,
+          q15_t * pSrcB,
+          uint32_t srcBLen,
+          q15_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA      points to the first input sequence.
+   * @param[in]  srcALen    length of the first input sequence.
+   * @param[in]  pSrcB      points to the second input sequence.
+   * @param[in]  srcBLen    length of the second input sequence.
+   * @param[out] pDst       points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  pScratch1  points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2  points to scratch buffer of size min(srcALen, srcBLen).
+   */
+  void arm_conv_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Convolution of Q31 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length srcALen+srcBLen-1.
+   */
+  void arm_conv_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length srcALen+srcBLen-1.
+   */
+  void arm_conv_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+    /**
+   * @brief Convolution of Q7 sequences.
+   * @param[in]  pSrcA      points to the first input sequence.
+   * @param[in]  srcALen    length of the first input sequence.
+   * @param[in]  pSrcB      points to the second input sequence.
+   * @param[in]  srcBLen    length of the second input sequence.
+   * @param[out] pDst       points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  pScratch1  points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2  points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   */
+  void arm_conv_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Convolution of Q7 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length srcALen+srcBLen-1.
+   */
+  void arm_conv_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+
+  /**
+   * @brief Partial convolution of floating-point sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @param[in]  pScratch1   points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2   points to scratch buffer of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_fast_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @param[in]  pScratch1   points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2   points to scratch buffer of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Partial convolution of Q31 sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q7 sequences
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @param[in]  pScratch1   points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2   points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+/**
+   * @brief Partial convolution of Q7 sequences.
+   * @param[in]  pSrcA       points to the first input sequence.
+   * @param[in]  srcALen     length of the first input sequence.
+   * @param[in]  pSrcB       points to the second input sequence.
+   * @param[in]  srcBLen     length of the second input sequence.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  firstIndex  is the first output sample to start with.
+   * @param[in]  numPoints   is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+  arm_status arm_conv_partial_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q15_t *pCoeffs;             /**< points to the coefficient array. The array is of length numTaps.*/
+    q15_t *pState;              /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } arm_fir_decimate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q31_t *pCoeffs;             /**< points to the coefficient array. The array is of length numTaps.*/
+    q31_t *pState;              /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } arm_fir_decimate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    float32_t *pCoeffs;         /**< points to the coefficient array. The array is of length numTaps.*/
+    float32_t *pState;          /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } arm_fir_decimate_instance_f32;
+
+
+  /**
+   * @brief Processing function for the floating-point FIR decimator.
+   * @param[in]  S          points to an instance of the floating-point FIR decimator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_decimate_f32(
+  const arm_fir_decimate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point FIR decimator.
+   * @param[in,out] S          points to an instance of the floating-point FIR decimator structure.
+   * @param[in]     numTaps    number of coefficients in the filter.
+   * @param[in]     M          decimation factor.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+  arm_status arm_fir_decimate_init_f32(
+  arm_fir_decimate_instance_f32 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR decimator.
+   * @param[in]  S          points to an instance of the Q15 FIR decimator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_decimate_q15(
+  const arm_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q15 FIR decimator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_decimate_fast_q15(
+  const arm_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 FIR decimator.
+   * @param[in,out] S          points to an instance of the Q15 FIR decimator structure.
+   * @param[in]     numTaps    number of coefficients in the filter.
+   * @param[in]     M          decimation factor.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+  arm_status arm_fir_decimate_init_q15(
+  arm_fir_decimate_instance_q15 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR decimator.
+   * @param[in]  S     points to an instance of the Q31 FIR decimator structure.
+   * @param[in]  pSrc  points to the block of input data.
+   * @param[out] pDst  points to the block of output data
+   * @param[in] blockSize number of input samples to process per call.
+   */
+  void arm_fir_decimate_q31(
+  const arm_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+   * @param[in]  S          points to an instance of the Q31 FIR decimator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_decimate_fast_q31(
+  arm_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 FIR decimator.
+   * @param[in,out] S          points to an instance of the Q31 FIR decimator structure.
+   * @param[in]     numTaps    number of coefficients in the filter.
+   * @param[in]     M          decimation factor.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+  arm_status arm_fir_decimate_init_q31(
+  arm_fir_decimate_instance_q31 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q15_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q15_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } arm_fir_interpolate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q31_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q31_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } arm_fir_interpolate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                     /**< upsample factor. */
+    uint16_t phaseLength;          /**< length of each polyphase filter component. */
+    float32_t *pCoeffs;            /**< points to the coefficient array. The array is of length L*phaseLength. */
+    float32_t *pState;             /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */
+  } arm_fir_interpolate_instance_f32;
+
+
+  /**
+   * @brief Processing function for the Q15 FIR interpolator.
+   * @param[in]  S          points to an instance of the Q15 FIR interpolator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_interpolate_q15(
+  const arm_fir_interpolate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 FIR interpolator.
+   * @param[in,out] S          points to an instance of the Q15 FIR interpolator structure.
+   * @param[in]     L          upsample factor.
+   * @param[in]     numTaps    number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficient buffer.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+  arm_status arm_fir_interpolate_init_q15(
+  arm_fir_interpolate_instance_q15 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR interpolator.
+   * @param[in]  S          points to an instance of the Q15 FIR interpolator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_interpolate_q31(
+  const arm_fir_interpolate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 FIR interpolator.
+   * @param[in,out] S          points to an instance of the Q31 FIR interpolator structure.
+   * @param[in]     L          upsample factor.
+   * @param[in]     numTaps    number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficient buffer.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+  arm_status arm_fir_interpolate_init_q31(
+  arm_fir_interpolate_instance_q31 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point FIR interpolator.
+   * @param[in]  S          points to an instance of the floating-point FIR interpolator structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of input samples to process per call.
+   */
+  void arm_fir_interpolate_f32(
+  const arm_fir_interpolate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point FIR interpolator.
+   * @param[in,out] S          points to an instance of the floating-point FIR interpolator structure.
+   * @param[in]     L          upsample factor.
+   * @param[in]     numTaps    number of filter coefficients in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficient buffer.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     blockSize  number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+  arm_status arm_fir_interpolate_init_f32(
+  arm_fir_interpolate_instance_f32 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;       /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q63_t *pState;           /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< additional shift, in bits, applied to each output sample. */
+  } arm_biquad_cas_df1_32x64_ins_q31;
+
+
+  /**
+   * @param[in]  S          points to an instance of the high precision Q31 Biquad cascade filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cas_df1_32x64_q31(
+  const arm_biquad_cas_df1_32x64_ins_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @param[in,out] S          points to an instance of the high precision Q31 Biquad cascade filter structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     postShift  shift to be applied to the output. Varies according to the coefficients format
+   */
+  void arm_biquad_cas_df1_32x64_init_q31(
+  arm_biquad_cas_df1_32x64_ins_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q63_t * pState,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_cascade_df2T_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_cascade_stereo_df2T_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float64_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float64_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_cascade_df2T_instance_f64;
+
+
+  /**
+   * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in]  S          points to an instance of the filter data structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df2T_f32(
+  const arm_biquad_cascade_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels
+   * @param[in]  S          points to an instance of the filter data structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_stereo_df2T_f32(
+  const arm_biquad_cascade_stereo_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in]  S          points to an instance of the filter data structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_biquad_cascade_df2T_f64(
+  const arm_biquad_cascade_df2T_instance_f64 * S,
+  float64_t * pSrc,
+  float64_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the filter data structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   */
+  void arm_biquad_cascade_df2T_init_f32(
+  arm_biquad_cascade_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief  Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the filter data structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   */
+  void arm_biquad_cascade_stereo_df2T_init_f32(
+  arm_biquad_cascade_stereo_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief  Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in,out] S          points to an instance of the filter data structure.
+   * @param[in]     numStages  number of 2nd order stages in the filter.
+   * @param[in]     pCoeffs    points to the filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   */
+  void arm_biquad_cascade_df2T_init_f64(
+  arm_biquad_cascade_df2T_instance_f64 * S,
+  uint8_t numStages,
+  float64_t * pCoeffs,
+  float64_t * pState);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    q15_t *pState;                       /**< points to the state variable array. The array is of length numStages. */
+    q15_t *pCoeffs;                      /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    q31_t *pState;                       /**< points to the state variable array. The array is of length numStages. */
+    q31_t *pCoeffs;                      /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages. */
+    float32_t *pCoeffs;                  /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_f32;
+
+
+  /**
+   * @brief Initialization function for the Q15 FIR lattice filter.
+   * @param[in] S          points to an instance of the Q15 FIR lattice structure.
+   * @param[in] numStages  number of filter stages.
+   * @param[in] pCoeffs    points to the coefficient buffer.  The array is of length numStages.
+   * @param[in] pState     points to the state buffer.  The array is of length numStages.
+   */
+  void arm_fir_lattice_init_q15(
+  arm_fir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR lattice filter.
+   * @param[in]  S          points to an instance of the Q15 FIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_lattice_q15(
+  const arm_fir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for the Q31 FIR lattice filter.
+   * @param[in] S          points to an instance of the Q31 FIR lattice structure.
+   * @param[in] numStages  number of filter stages.
+   * @param[in] pCoeffs    points to the coefficient buffer.  The array is of length numStages.
+   * @param[in] pState     points to the state buffer.   The array is of length numStages.
+   */
+  void arm_fir_lattice_init_q31(
+  arm_fir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR lattice filter.
+   * @param[in]  S          points to an instance of the Q31 FIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_lattice_q31(
+  const arm_fir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the floating-point FIR lattice filter.
+ * @param[in] S          points to an instance of the floating-point FIR lattice structure.
+ * @param[in] numStages  number of filter stages.
+ * @param[in] pCoeffs    points to the coefficient buffer.  The array is of length numStages.
+ * @param[in] pState     points to the state buffer.  The array is of length numStages.
+ */
+  void arm_fir_lattice_init_f32(
+  arm_fir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief Processing function for the floating-point FIR lattice filter.
+   * @param[in]  S          points to an instance of the floating-point FIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_fir_lattice_f32(
+  const arm_fir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    q15_t *pState;                       /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q15_t *pkCoeffs;                     /**< points to the reflection coefficient array. The array is of length numStages. */
+    q15_t *pvCoeffs;                     /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    q31_t *pState;                       /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q31_t *pkCoeffs;                     /**< points to the reflection coefficient array. The array is of length numStages. */
+    q31_t *pvCoeffs;                     /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages+blockSize. */
+    float32_t *pkCoeffs;                 /**< points to the reflection coefficient array. The array is of length numStages. */
+    float32_t *pvCoeffs;                 /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_f32;
+
+
+  /**
+   * @brief Processing function for the floating-point IIR lattice filter.
+   * @param[in]  S          points to an instance of the floating-point IIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_f32(
+  const arm_iir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for the floating-point IIR lattice filter.
+   * @param[in] S          points to an instance of the floating-point IIR lattice structure.
+   * @param[in] numStages  number of stages in the filter.
+   * @param[in] pkCoeffs   points to the reflection coefficient buffer.  The array is of length numStages.
+   * @param[in] pvCoeffs   points to the ladder coefficient buffer.  The array is of length numStages+1.
+   * @param[in] pState     points to the state buffer.  The array is of length numStages+blockSize-1.
+   * @param[in] blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_init_f32(
+  arm_iir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pkCoeffs,
+  float32_t * pvCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 IIR lattice filter.
+   * @param[in]  S          points to an instance of the Q31 IIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_q31(
+  const arm_iir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for the Q31 IIR lattice filter.
+   * @param[in] S          points to an instance of the Q31 IIR lattice structure.
+   * @param[in] numStages  number of stages in the filter.
+   * @param[in] pkCoeffs   points to the reflection coefficient buffer.  The array is of length numStages.
+   * @param[in] pvCoeffs   points to the ladder coefficient buffer.  The array is of length numStages+1.
+   * @param[in] pState     points to the state buffer.  The array is of length numStages+blockSize.
+   * @param[in] blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_init_q31(
+  arm_iir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pkCoeffs,
+  q31_t * pvCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 IIR lattice filter.
+   * @param[in]  S          points to an instance of the Q15 IIR lattice structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[out] pDst       points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_iir_lattice_q15(
+  const arm_iir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the Q15 IIR lattice filter.
+ * @param[in] S          points to an instance of the fixed-point Q15 IIR lattice structure.
+ * @param[in] numStages  number of stages in the filter.
+ * @param[in] pkCoeffs   points to reflection coefficient buffer.  The array is of length numStages.
+ * @param[in] pvCoeffs   points to ladder coefficient buffer.  The array is of length numStages+1.
+ * @param[in] pState     points to state buffer.  The array is of length numStages+blockSize.
+ * @param[in] blockSize  number of samples to process per call.
+ */
+  void arm_iir_lattice_init_q15(
+  arm_iir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pkCoeffs,
+  q15_t * pvCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the floating-point LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    float32_t *pState;   /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;  /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;        /**< step size that controls filter coefficient updates. */
+  } arm_lms_instance_f32;
+
+
+  /**
+   * @brief Processing function for floating-point LMS filter.
+   * @param[in]  S          points to an instance of the floating-point LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_f32(
+  const arm_lms_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for floating-point LMS filter.
+   * @param[in] S          points to an instance of the floating-point LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to the coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   */
+  void arm_lms_init_f32(
+  arm_lms_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q15_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } arm_lms_instance_q15;
+
+
+  /**
+   * @brief Initialization function for the Q15 LMS filter.
+   * @param[in] S          points to an instance of the Q15 LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to the coefficient buffer.
+   * @param[in] pState     points to the state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   * @param[in] postShift  bit shift applied to coefficients.
+   */
+  void arm_lms_init_q15(
+  arm_lms_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+
+  /**
+   * @brief Processing function for Q15 LMS filter.
+   * @param[in]  S          points to an instance of the Q15 LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_q15(
+  const arm_lms_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q31_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } arm_lms_instance_q31;
+
+
+  /**
+   * @brief Processing function for Q31 LMS filter.
+   * @param[in]  S          points to an instance of the Q15 LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_q31(
+  const arm_lms_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for Q31 LMS filter.
+   * @param[in] S          points to an instance of the Q31 LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   * @param[in] postShift  bit shift applied to coefficients.
+   */
+  void arm_lms_init_q31(
+  arm_lms_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+
+  /**
+   * @brief Instance structure for the floating-point normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;         /**< step size that control filter coefficient updates. */
+    float32_t energy;     /**< saves previous frame energy. */
+    float32_t x0;         /**< saves previous input sample. */
+  } arm_lms_norm_instance_f32;
+
+
+  /**
+   * @brief Processing function for floating-point normalized LMS filter.
+   * @param[in]  S          points to an instance of the floating-point normalized LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_norm_f32(
+  arm_lms_norm_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for floating-point normalized LMS filter.
+   * @param[in] S          points to an instance of the floating-point LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   */
+  void arm_lms_norm_init_f32(
+  arm_lms_norm_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    q31_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q31_t *recipTable;    /**< points to the reciprocal initial value table. */
+    q31_t energy;         /**< saves previous frame energy. */
+    q31_t x0;             /**< saves previous input sample. */
+  } arm_lms_norm_instance_q31;
+
+
+  /**
+   * @brief Processing function for Q31 normalized LMS filter.
+   * @param[in]  S          points to an instance of the Q31 normalized LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_norm_q31(
+  arm_lms_norm_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for Q31 normalized LMS filter.
+   * @param[in] S          points to an instance of the Q31 normalized LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   * @param[in] postShift  bit shift applied to coefficients.
+   */
+  void arm_lms_norm_init_q31(
+  arm_lms_norm_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Instance structure for the Q15 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< Number of coefficients in the filter. */
+    q15_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q15_t *recipTable;    /**< Points to the reciprocal initial value table. */
+    q15_t energy;         /**< saves previous frame energy. */
+    q15_t x0;             /**< saves previous input sample. */
+  } arm_lms_norm_instance_q15;
+
+
+  /**
+   * @brief Processing function for Q15 normalized LMS filter.
+   * @param[in]  S          points to an instance of the Q15 normalized LMS filter structure.
+   * @param[in]  pSrc       points to the block of input data.
+   * @param[in]  pRef       points to the block of reference data.
+   * @param[out] pOut       points to the block of output data.
+   * @param[out] pErr       points to the block of error data.
+   * @param[in]  blockSize  number of samples to process.
+   */
+  void arm_lms_norm_q15(
+  arm_lms_norm_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for Q15 normalized LMS filter.
+   * @param[in] S          points to an instance of the Q15 normalized LMS filter structure.
+   * @param[in] numTaps    number of filter coefficients.
+   * @param[in] pCoeffs    points to coefficient buffer.
+   * @param[in] pState     points to state buffer.
+   * @param[in] mu         step size that controls filter coefficient updates.
+   * @param[in] blockSize  number of samples to process.
+   * @param[in] postShift  bit shift applied to coefficients.
+   */
+  void arm_lms_norm_init_q15(
+  arm_lms_norm_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Correlation of floating-point sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+  void arm_correlate_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+
+   /**
+   * @brief Correlation of Q15 sequences
+   * @param[in]  pSrcA     points to the first input sequence.
+   * @param[in]  srcALen   length of the first input sequence.
+   * @param[in]  pSrcB     points to the second input sequence.
+   * @param[in]  srcBLen   length of the second input sequence.
+   * @param[out] pDst      points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  pScratch  points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   */
+  void arm_correlate_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+
+  /**
+   * @brief Correlation of Q15 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+
+  void arm_correlate_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+
+  /**
+   * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+
+  void arm_correlate_fast_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+
+  /**
+   * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+   * @param[in]  pSrcA     points to the first input sequence.
+   * @param[in]  srcALen   length of the first input sequence.
+   * @param[in]  pSrcB     points to the second input sequence.
+   * @param[in]  srcBLen   length of the second input sequence.
+   * @param[out] pDst      points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  pScratch  points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   */
+  void arm_correlate_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+
+  /**
+   * @brief Correlation of Q31 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+  void arm_correlate_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+  /**
+   * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+  void arm_correlate_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+ /**
+   * @brief Correlation of Q7 sequences.
+   * @param[in]  pSrcA      points to the first input sequence.
+   * @param[in]  srcALen    length of the first input sequence.
+   * @param[in]  pSrcB      points to the second input sequence.
+   * @param[in]  srcBLen    length of the second input sequence.
+   * @param[out] pDst       points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  pScratch1  points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  pScratch2  points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   */
+  void arm_correlate_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Correlation of Q7 sequences.
+   * @param[in]  pSrcA    points to the first input sequence.
+   * @param[in]  srcALen  length of the first input sequence.
+   * @param[in]  pSrcB    points to the second input sequence.
+   * @param[in]  srcBLen  length of the second input sequence.
+   * @param[out] pDst     points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   */
+  void arm_correlate_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+
+  /**
+   * @brief Instance structure for the floating-point sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    float32_t *pState;            /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    float32_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_f32;
+
+  /**
+   * @brief Instance structure for the Q31 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q31_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q31_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q31;
+
+  /**
+   * @brief Instance structure for the Q15 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q15_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q15_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q7 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q7_t *pState;                 /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q7_t *pCoeffs;                /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q7;
+
+
+  /**
+   * @brief Processing function for the floating-point sparse FIR filter.
+   * @param[in]  S           points to an instance of the floating-point sparse FIR structure.
+   * @param[in]  pSrc        points to the block of input data.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  pScratchIn  points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize   number of input samples to process per call.
+   */
+  void arm_fir_sparse_f32(
+  arm_fir_sparse_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  float32_t * pScratchIn,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point sparse FIR filter.
+   * @param[in,out] S          points to an instance of the floating-point sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     pCoeffs    points to the array of filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     pTapDelay  points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   */
+  void arm_fir_sparse_init_f32(
+  arm_fir_sparse_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 sparse FIR filter.
+   * @param[in]  S           points to an instance of the Q31 sparse FIR structure.
+   * @param[in]  pSrc        points to the block of input data.
+   * @param[out] pDst        points to the block of output data
+   * @param[in]  pScratchIn  points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize   number of input samples to process per call.
+   */
+  void arm_fir_sparse_q31(
+  arm_fir_sparse_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  q31_t * pScratchIn,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 sparse FIR filter.
+   * @param[in,out] S          points to an instance of the Q31 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     pCoeffs    points to the array of filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     pTapDelay  points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   */
+  void arm_fir_sparse_init_q31(
+  arm_fir_sparse_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 sparse FIR filter.
+   * @param[in]  S            points to an instance of the Q15 sparse FIR structure.
+   * @param[in]  pSrc         points to the block of input data.
+   * @param[out] pDst         points to the block of output data
+   * @param[in]  pScratchIn   points to a temporary buffer of size blockSize.
+   * @param[in]  pScratchOut  points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize    number of input samples to process per call.
+   */
+  void arm_fir_sparse_q15(
+  arm_fir_sparse_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  q15_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 sparse FIR filter.
+   * @param[in,out] S          points to an instance of the Q15 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     pCoeffs    points to the array of filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     pTapDelay  points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   */
+  void arm_fir_sparse_init_q15(
+  arm_fir_sparse_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q7 sparse FIR filter.
+   * @param[in]  S            points to an instance of the Q7 sparse FIR structure.
+   * @param[in]  pSrc         points to the block of input data.
+   * @param[out] pDst         points to the block of output data
+   * @param[in]  pScratchIn   points to a temporary buffer of size blockSize.
+   * @param[in]  pScratchOut  points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize    number of input samples to process per call.
+   */
+  void arm_fir_sparse_q7(
+  arm_fir_sparse_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  q7_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q7 sparse FIR filter.
+   * @param[in,out] S          points to an instance of the Q7 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     pCoeffs    points to the array of filter coefficients.
+   * @param[in]     pState     points to the state buffer.
+   * @param[in]     pTapDelay  points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   */
+  void arm_fir_sparse_init_q7(
+  arm_fir_sparse_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Floating-point sin_cos function.
+   * @param[in]  theta   input value in degrees
+   * @param[out] pSinVal  points to the processed sine output.
+   * @param[out] pCosVal  points to the processed cos output.
+   */
+  void arm_sin_cos_f32(
+  float32_t theta,
+  float32_t * pSinVal,
+  float32_t * pCosVal);
+
+
+  /**
+   * @brief  Q31 sin_cos function.
+   * @param[in]  theta    scaled input value in degrees
+   * @param[out] pSinVal  points to the processed sine output.
+   * @param[out] pCosVal  points to the processed cosine output.
+   */
+  void arm_sin_cos_q31(
+  q31_t theta,
+  q31_t * pSinVal,
+  q31_t * pCosVal);
+
+
+  /**
+   * @brief  Floating-point complex conjugate.
+   * @param[in]  pSrc        points to the input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_conj_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q31 complex conjugate.
+   * @param[in]  pSrc        points to the input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_conj_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q15 complex conjugate.
+   * @param[in]  pSrc        points to the input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_conj_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Floating-point complex magnitude squared
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_squared_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q31 complex magnitude squared
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_squared_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q15 complex magnitude squared
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_squared_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+ /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup PID PID Motor Control
+   *
+   * A Proportional Integral Derivative (PID) controller is a generic feedback control
+   * loop mechanism widely used in industrial control systems.
+   * A PID controller is the most commonly used type of feedback controller.
+   *
+   * This set of functions implements (PID) controllers
+   * for Q15, Q31, and floating-point data types.  The functions operate on a single sample
+   * of data and each call to the function returns a single processed value.
+   * <code>S</code> points to an instance of the PID control data structure.  <code>in</code>
+   * is the input sample value. The functions return the output value.
+   *
+   * \par Algorithm:
+   * <pre>
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  </pre>
+   *
+   * \par
+   * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
+   *
+   * \par
+   * \image html PID.gif "Proportional Integral Derivative Controller"
+   *
+   * \par
+   * The PID controller calculates an "error" value as the difference between
+   * the measured output and the reference input.
+   * The controller attempts to minimize the error by adjusting the process control inputs.
+   * The proportional value determines the reaction to the current error,
+   * the integral value determines the reaction based on the sum of recent errors,
+   * and the derivative value determines the reaction based on the rate at which the error has been changing.
+   *
+   * \par Instance Structure
+   * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
+   * A separate instance structure must be defined for each PID Controller.
+   * There are separate instance structure declarations for each of the 3 supported data types.
+   *
+   * \par Reset Functions
+   * There is also an associated reset function for each data type which clears the state array.
+   *
+   * \par Initialization Functions
+   * There is also an associated initialization function for each data type.
+   * The initialization function performs the following operations:
+   * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
+   * - Zeros out the values in the state buffer.
+   *
+   * \par
+   * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
+   *
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the fixed-point versions of the PID Controller functions.
+   * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup PID
+   * @{
+   */
+
+  /**
+   * @brief  Process function for the floating-point PID Control.
+   * @param[in,out] S   is an instance of the floating-point PID Control structure
+   * @param[in]     in  input sample to process
+   * @return out processed output sample.
+   */
+  static __INLINE float32_t arm_pid_f32(
+  arm_pid_instance_f32 * S,
+  float32_t in)
+  {
+    float32_t out;
+
+    /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]  */
+    out = (S->A0 * in) +
+      (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+
+  }
+
+  /**
+   * @brief  Process function for the Q31 PID Control.
+   * @param[in,out] S  points to an instance of the Q31 PID Control structure
+   * @param[in]     in  input sample to process
+   * @return out processed output sample.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 64-bit accumulator.
+   * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
+   * Thus, if the accumulator result overflows it wraps around rather than clip.
+   * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
+   * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
+   */
+  static __INLINE q31_t arm_pid_q31(
+  arm_pid_instance_q31 * S,
+  q31_t in)
+  {
+    q63_t acc;
+    q31_t out;
+
+    /* acc = A0 * x[n]  */
+    acc = (q63_t) S->A0 * in;
+
+    /* acc += A1 * x[n-1] */
+    acc += (q63_t) S->A1 * S->state[0];
+
+    /* acc += A2 * x[n-2]  */
+    acc += (q63_t) S->A2 * S->state[1];
+
+    /* convert output to 1.31 format to add y[n-1] */
+    out = (q31_t) (acc >> 31u);
+
+    /* out += y[n-1] */
+    out += S->state[2];
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+  }
+
+
+  /**
+   * @brief  Process function for the Q15 PID Control.
+   * @param[in,out] S   points to an instance of the Q15 PID Control structure
+   * @param[in]     in  input sample to process
+   * @return out processed output sample.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using a 64-bit internal accumulator.
+   * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
+   * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
+   * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
+   * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
+   * Lastly, the accumulator is saturated to yield a result in 1.15 format.
+   */
+  static __INLINE q15_t arm_pid_q15(
+  arm_pid_instance_q15 * S,
+  q15_t in)
+  {
+    q63_t acc;
+    q15_t out;
+
+#ifndef ARM_MATH_CM0_FAMILY
+    __SIMD32_TYPE *vstate;
+
+    /* Implementation of PID controller */
+
+    /* acc = A0 * x[n]  */
+    acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in);
+
+    /* acc += A1 * x[n-1] + A2 * x[n-2]  */
+    vstate = __SIMD32_CONST(S->state);
+    acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc);
+#else
+    /* acc = A0 * x[n]  */
+    acc = ((q31_t) S->A0) * in;
+
+    /* acc += A1 * x[n-1] + A2 * x[n-2]  */
+    acc += (q31_t) S->A1 * S->state[0];
+    acc += (q31_t) S->A2 * S->state[1];
+#endif
+
+    /* acc += y[n-1] */
+    acc += (q31_t) S->state[2] << 15;
+
+    /* saturate the output */
+    out = (q15_t) (__SSAT((acc >> 15), 16));
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+  }
+
+  /**
+   * @} end of PID group
+   */
+
+
+  /**
+   * @brief Floating-point matrix inverse.
+   * @param[in]  src   points to the instance of the input floating-point matrix structure.
+   * @param[out] dst   points to the instance of the output floating-point matrix structure.
+   * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+   * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+   */
+  arm_status arm_mat_inverse_f32(
+  const arm_matrix_instance_f32 * src,
+  arm_matrix_instance_f32 * dst);
+
+
+  /**
+   * @brief Floating-point matrix inverse.
+   * @param[in]  src   points to the instance of the input floating-point matrix structure.
+   * @param[out] dst   points to the instance of the output floating-point matrix structure.
+   * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+   * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+   */
+  arm_status arm_mat_inverse_f64(
+  const arm_matrix_instance_f64 * src,
+  arm_matrix_instance_f64 * dst);
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup clarke Vector Clarke Transform
+   * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
+   * Generally the Clarke transform uses three-phase currents <code>Ia, Ib and Ic</code> to calculate currents
+   * in the two-phase orthogonal stator axis <code>Ialpha</code> and <code>Ibeta</code>.
+   * When <code>Ialpha</code> is superposed with <code>Ia</code> as shown in the figure below
+   * \image html clarke.gif Stator current space vector and its components in (a,b).
+   * and <code>Ia + Ib + Ic = 0</code>, in this condition <code>Ialpha</code> and <code>Ibeta</code>
+   * can be calculated using only <code>Ia</code> and <code>Ib</code>.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html clarkeFormula.gif
+   * where <code>Ia</code> and <code>Ib</code> are the instantaneous stator phases and
+   * <code>pIalpha</code> and <code>pIbeta</code> are the two coordinates of time invariant vector.
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Clarke transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup clarke
+   * @{
+   */
+
+  /**
+   *
+   * @brief  Floating-point Clarke transform
+   * @param[in]  Ia       input three-phase coordinate <code>a</code>
+   * @param[in]  Ib       input three-phase coordinate <code>b</code>
+   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+   */
+  static __INLINE void arm_clarke_f32(
+  float32_t Ia,
+  float32_t Ib,
+  float32_t * pIalpha,
+  float32_t * pIbeta)
+  {
+    /* Calculate pIalpha using the equation, pIalpha = Ia */
+    *pIalpha = Ia;
+
+    /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
+    *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib);
+  }
+
+
+  /**
+   * @brief  Clarke transform for Q31 version
+   * @param[in]  Ia       input three-phase coordinate <code>a</code>
+   * @param[in]  Ib       input three-phase coordinate <code>b</code>
+   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition, hence there is no risk of overflow.
+   */
+  static __INLINE void arm_clarke_q31(
+  q31_t Ia,
+  q31_t Ib,
+  q31_t * pIalpha,
+  q31_t * pIbeta)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+
+    /* Calculating pIalpha from Ia by equation pIalpha = Ia */
+    *pIalpha = Ia;
+
+    /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+    product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
+
+    /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+    product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
+
+    /* pIbeta is calculated by adding the intermediate products */
+    *pIbeta = __QADD(product1, product2);
+  }
+
+  /**
+   * @} end of clarke group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to Q31 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_q7_to_q31(
+  q7_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup inv_clarke Vector Inverse Clarke Transform
+   * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html clarkeInvFormula.gif
+   * where <code>pIa</code> and <code>pIb</code> are the instantaneous stator phases and
+   * <code>Ialpha</code> and <code>Ibeta</code> are the two coordinates of time invariant vector.
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Clarke transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup inv_clarke
+   * @{
+   */
+
+   /**
+   * @brief  Floating-point Inverse Clarke transform
+   * @param[in]  Ialpha  input two-phase orthogonal vector axis alpha
+   * @param[in]  Ibeta   input two-phase orthogonal vector axis beta
+   * @param[out] pIa     points to output three-phase coordinate <code>a</code>
+   * @param[out] pIb     points to output three-phase coordinate <code>b</code>
+   */
+  static __INLINE void arm_inv_clarke_f32(
+  float32_t Ialpha,
+  float32_t Ibeta,
+  float32_t * pIa,
+  float32_t * pIb)
+  {
+    /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+    *pIa = Ialpha;
+
+    /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
+    *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta;
+  }
+
+
+  /**
+   * @brief  Inverse Clarke transform for Q31 version
+   * @param[in]  Ialpha  input two-phase orthogonal vector axis alpha
+   * @param[in]  Ibeta   input two-phase orthogonal vector axis beta
+   * @param[out] pIa     points to output three-phase coordinate <code>a</code>
+   * @param[out] pIb     points to output three-phase coordinate <code>b</code>
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the subtraction, hence there is no risk of overflow.
+   */
+  static __INLINE void arm_inv_clarke_q31(
+  q31_t Ialpha,
+  q31_t Ibeta,
+  q31_t * pIa,
+  q31_t * pIb)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+
+    /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+    *pIa = Ialpha;
+
+    /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+    product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
+
+    /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+    product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
+
+    /* pIb is calculated by subtracting the products */
+    *pIb = __QSUB(product2, product1);
+  }
+
+  /**
+   * @} end of inv_clarke group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to Q15 vector.
+   * @param[in]  pSrc       input pointer
+   * @param[out] pDst       output pointer
+   * @param[in]  blockSize  number of samples to process
+   */
+  void arm_q7_to_q15(
+  q7_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup park Vector Park Transform
+   *
+   * Forward Park transform converts the input two-coordinate vector to flux and torque components.
+   * The Park transform can be used to realize the transformation of the <code>Ialpha</code> and the <code>Ibeta</code> currents
+   * from the stationary to the moving reference frame and control the spatial relationship between
+   * the stator vector current and rotor flux vector.
+   * If we consider the d axis aligned with the rotor flux, the diagram below shows the
+   * current vector and the relationship from the two reference frames:
+   * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html parkFormula.gif
+   * where <code>Ialpha</code> and <code>Ibeta</code> are the stator vector components,
+   * <code>pId</code> and <code>pIq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+   * cosine and sine values of theta (rotor flux position).
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Park transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup park
+   * @{
+   */
+
+  /**
+   * @brief Floating-point Park transform
+   * @param[in]  Ialpha  input two-phase vector coordinate alpha
+   * @param[in]  Ibeta   input two-phase vector coordinate beta
+   * @param[out] pId     points to output   rotor reference frame d
+   * @param[out] pIq     points to output   rotor reference frame q
+   * @param[in]  sinVal  sine value of rotation angle theta
+   * @param[in]  cosVal  cosine value of rotation angle theta
+   *
+   * The function implements the forward Park transform.
+   *
+   */
+  static __INLINE void arm_park_f32(
+  float32_t Ialpha,
+  float32_t Ibeta,
+  float32_t * pId,
+  float32_t * pIq,
+  float32_t sinVal,
+  float32_t cosVal)
+  {
+    /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
+    *pId = Ialpha * cosVal + Ibeta * sinVal;
+
+    /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
+    *pIq = -Ialpha * sinVal + Ibeta * cosVal;
+  }
+
+
+  /**
+   * @brief  Park transform for Q31 version
+   * @param[in]  Ialpha  input two-phase vector coordinate alpha
+   * @param[in]  Ibeta   input two-phase vector coordinate beta
+   * @param[out] pId     points to output rotor reference frame d
+   * @param[out] pIq     points to output rotor reference frame q
+   * @param[in]  sinVal  sine value of rotation angle theta
+   * @param[in]  cosVal  cosine value of rotation angle theta
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition and subtraction, hence there is no risk of overflow.
+   */
+  static __INLINE void arm_park_q31(
+  q31_t Ialpha,
+  q31_t Ibeta,
+  q31_t * pId,
+  q31_t * pIq,
+  q31_t sinVal,
+  q31_t cosVal)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+    q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
+
+    /* Intermediate product is calculated by (Ialpha * cosVal) */
+    product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
+
+    /* Intermediate product is calculated by (Ibeta * sinVal) */
+    product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
+
+
+    /* Intermediate product is calculated by (Ialpha * sinVal) */
+    product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
+
+    /* Intermediate product is calculated by (Ibeta * cosVal) */
+    product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
+
+    /* Calculate pId by adding the two intermediate products 1 and 2 */
+    *pId = __QADD(product1, product2);
+
+    /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
+    *pIq = __QSUB(product4, product3);
+  }
+
+  /**
+   * @} end of park group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q7_to_float(
+  q7_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup inv_park Vector Inverse Park transform
+   * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html parkInvFormula.gif
+   * where <code>pIalpha</code> and <code>pIbeta</code> are the stator vector components,
+   * <code>Id</code> and <code>Iq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+   * cosine and sine values of theta (rotor flux position).
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Park transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup inv_park
+   * @{
+   */
+
+   /**
+   * @brief  Floating-point Inverse Park transform
+   * @param[in]  Id       input coordinate of rotor reference frame d
+   * @param[in]  Iq       input coordinate of rotor reference frame q
+   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+   * @param[in]  sinVal   sine value of rotation angle theta
+   * @param[in]  cosVal   cosine value of rotation angle theta
+   */
+  static __INLINE void arm_inv_park_f32(
+  float32_t Id,
+  float32_t Iq,
+  float32_t * pIalpha,
+  float32_t * pIbeta,
+  float32_t sinVal,
+  float32_t cosVal)
+  {
+    /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
+    *pIalpha = Id * cosVal - Iq * sinVal;
+
+    /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
+    *pIbeta = Id * sinVal + Iq * cosVal;
+  }
+
+
+  /**
+   * @brief  Inverse Park transform for   Q31 version
+   * @param[in]  Id       input coordinate of rotor reference frame d
+   * @param[in]  Iq       input coordinate of rotor reference frame q
+   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+   * @param[in]  sinVal   sine value of rotation angle theta
+   * @param[in]  cosVal   cosine value of rotation angle theta
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition, hence there is no risk of overflow.
+   */
+  static __INLINE void arm_inv_park_q31(
+  q31_t Id,
+  q31_t Iq,
+  q31_t * pIalpha,
+  q31_t * pIbeta,
+  q31_t sinVal,
+  q31_t cosVal)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+    q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
+
+    /* Intermediate product is calculated by (Id * cosVal) */
+    product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
+
+    /* Intermediate product is calculated by (Iq * sinVal) */
+    product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
+
+
+    /* Intermediate product is calculated by (Id * sinVal) */
+    product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
+
+    /* Intermediate product is calculated by (Iq * cosVal) */
+    product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
+
+    /* Calculate pIalpha by using the two intermediate products 1 and 2 */
+    *pIalpha = __QSUB(product1, product2);
+
+    /* Calculate pIbeta by using the two intermediate products 3 and 4 */
+    *pIbeta = __QADD(product4, product3);
+  }
+
+  /**
+   * @} end of Inverse park group
+   */
+
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q31_to_float(
+  q31_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @ingroup groupInterpolation
+   */
+
+  /**
+   * @defgroup LinearInterpolate Linear Interpolation
+   *
+   * Linear interpolation is a method of curve fitting using linear polynomials.
+   * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line
+   *
+   * \par
+   * \image html LinearInterp.gif "Linear interpolation"
+   *
+   * \par
+   * A  Linear Interpolate function calculates an output value(y), for the input(x)
+   * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values)
+   *
+   * \par Algorithm:
+   * <pre>
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * </pre>
+   *
+   * \par
+   * This set of functions implements Linear interpolation process
+   * for Q7, Q15, Q31, and floating-point data types.  The functions operate on a single
+   * sample of data and each call to the function returns a single processed value.
+   * <code>S</code> points to an instance of the Linear Interpolate function data structure.
+   * <code>x</code> is the input sample value. The functions returns the output value.
+   *
+   * \par
+   * if x is outside of the table boundary, Linear interpolation returns first value of the table
+   * if x is below input range and returns last value of table if x is above range.
+   */
+
+  /**
+   * @addtogroup LinearInterpolate
+   * @{
+   */
+
+  /**
+   * @brief  Process function for the floating-point Linear Interpolation Function.
+   * @param[in,out] S  is an instance of the floating-point Linear Interpolation structure
+   * @param[in]     x  input sample to process
+   * @return y processed output sample.
+   *
+   */
+  static __INLINE float32_t arm_linear_interp_f32(
+  arm_linear_interp_instance_f32 * S,
+  float32_t x)
+  {
+    float32_t y;
+    float32_t x0, x1;                            /* Nearest input values */
+    float32_t y0, y1;                            /* Nearest output values */
+    float32_t xSpacing = S->xSpacing;            /* spacing between input values */
+    int32_t i;                                   /* Index variable */
+    float32_t *pYData = S->pYData;               /* pointer to output table */
+
+    /* Calculation of index */
+    i = (int32_t) ((x - S->x1) / xSpacing);
+
+    if(i < 0)
+    {
+      /* Iniatilize output for below specified range as least output value of table */
+      y = pYData[0];
+    }
+    else if((uint32_t)i >= S->nValues)
+    {
+      /* Iniatilize output for above specified range as last output value of table */
+      y = pYData[S->nValues - 1];
+    }
+    else
+    {
+      /* Calculation of nearest input values */
+      x0 = S->x1 +  i      * xSpacing;
+      x1 = S->x1 + (i + 1) * xSpacing;
+
+      /* Read of nearest output values */
+      y0 = pYData[i];
+      y1 = pYData[i + 1];
+
+      /* Calculation of output */
+      y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0));
+
+    }
+
+    /* returns output value */
+    return (y);
+  }
+
+
+   /**
+   *
+   * @brief  Process function for the Q31 Linear Interpolation Function.
+   * @param[in] pYData   pointer to Q31 Linear Interpolation table
+   * @param[in] x        input sample to process
+   * @param[in] nValues  number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   *
+   */
+  static __INLINE q31_t arm_linear_interp_q31(
+  q31_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q31_t y;                                     /* output */
+    q31_t y0, y1;                                /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    int32_t index;                               /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    index = ((x & (q31_t)0xFFF00000) >> 20);
+
+    if(index >= (int32_t)(nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else if(index < 0)
+    {
+      return (pYData[0]);
+    }
+    else
+    {
+      /* 20 bits for the fractional part */
+      /* shift left by 11 to keep fract in 1.31 format */
+      fract = (x & 0x000FFFFF) << 11;
+
+      /* Read two nearest output values from the index in 1.31(q31) format */
+      y0 = pYData[index];
+      y1 = pYData[index + 1];
+
+      /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+      y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32));
+
+      /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+      y += ((q31_t) (((q63_t) y1 * fract) >> 32));
+
+      /* Convert y to 1.31 format */
+      return (y << 1u);
+    }
+  }
+
+
+  /**
+   *
+   * @brief  Process function for the Q15 Linear Interpolation Function.
+   * @param[in] pYData   pointer to Q15 Linear Interpolation table
+   * @param[in] x        input sample to process
+   * @param[in] nValues  number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   *
+   */
+  static __INLINE q15_t arm_linear_interp_q15(
+  q15_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q63_t y;                                     /* output */
+    q15_t y0, y1;                                /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    int32_t index;                               /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    index = ((x & (int32_t)0xFFF00000) >> 20);
+
+    if(index >= (int32_t)(nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else if(index < 0)
+    {
+      return (pYData[0]);
+    }
+    else
+    {
+      /* 20 bits for the fractional part */
+      /* fract is in 12.20 format */
+      fract = (x & 0x000FFFFF);
+
+      /* Read two nearest output values from the index */
+      y0 = pYData[index];
+      y1 = pYData[index + 1];
+
+      /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+      y = ((q63_t) y0 * (0xFFFFF - fract));
+
+      /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+      y += ((q63_t) y1 * (fract));
+
+      /* convert y to 1.15 format */
+      return (q15_t) (y >> 20);
+    }
+  }
+
+
+  /**
+   *
+   * @brief  Process function for the Q7 Linear Interpolation Function.
+   * @param[in] pYData   pointer to Q7 Linear Interpolation table
+   * @param[in] x        input sample to process
+   * @param[in] nValues  number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   */
+  static __INLINE q7_t arm_linear_interp_q7(
+  q7_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q31_t y;                                     /* output */
+    q7_t y0, y1;                                 /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    uint32_t index;                              /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    if (x < 0)
+    {
+      return (pYData[0]);
+    }
+    index = (x >> 20) & 0xfff;
+
+    if(index >= (nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else
+    {
+      /* 20 bits for the fractional part */
+      /* fract is in 12.20 format */
+      fract = (x & 0x000FFFFF);
+
+      /* Read two nearest output values from the index and are in 1.7(q7) format */
+      y0 = pYData[index];
+      y1 = pYData[index + 1];
+
+      /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */
+      y = ((y0 * (0xFFFFF - fract)));
+
+      /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */
+      y += (y1 * fract);
+
+      /* convert y to 1.7(q7) format */
+      return (q7_t) (y >> 20);
+     }
+  }
+
+  /**
+   * @} end of LinearInterpolate group
+   */
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for floating-point data.
+   * @param[in] x  input value in radians.
+   * @return  sin(x).
+   */
+  float32_t arm_sin_f32(
+  float32_t x);
+
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for Q31 data.
+   * @param[in] x  Scaled input value in radians.
+   * @return  sin(x).
+   */
+  q31_t arm_sin_q31(
+  q31_t x);
+
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for Q15 data.
+   * @param[in] x  Scaled input value in radians.
+   * @return  sin(x).
+   */
+  q15_t arm_sin_q15(
+  q15_t x);
+
+
+  /**
+   * @brief  Fast approximation to the trigonometric cosine function for floating-point data.
+   * @param[in] x  input value in radians.
+   * @return  cos(x).
+   */
+  float32_t arm_cos_f32(
+  float32_t x);
+
+
+  /**
+   * @brief Fast approximation to the trigonometric cosine function for Q31 data.
+   * @param[in] x  Scaled input value in radians.
+   * @return  cos(x).
+   */
+  q31_t arm_cos_q31(
+  q31_t x);
+
+
+  /**
+   * @brief  Fast approximation to the trigonometric cosine function for Q15 data.
+   * @param[in] x  Scaled input value in radians.
+   * @return  cos(x).
+   */
+  q15_t arm_cos_q15(
+  q15_t x);
+
+
+  /**
+   * @ingroup groupFastMath
+   */
+
+
+  /**
+   * @defgroup SQRT Square Root
+   *
+   * Computes the square root of a number.
+   * There are separate functions for Q15, Q31, and floating-point data types.
+   * The square root function is computed using the Newton-Raphson algorithm.
+   * This is an iterative algorithm of the form:
+   * <pre>
+   *      x1 = x0 - f(x0)/f'(x0)
+   * </pre>
+   * where <code>x1</code> is the current estimate,
+   * <code>x0</code> is the previous estimate, and
+   * <code>f'(x0)</code> is the derivative of <code>f()</code> evaluated at <code>x0</code>.
+   * For the square root function, the algorithm reduces to:
+   * <pre>
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * </pre>
+   */
+
+
+  /**
+   * @addtogroup SQRT
+   * @{
+   */
+
+  /**
+   * @brief  Floating-point square root function.
+   * @param[in]  in    input value.
+   * @param[out] pOut  square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+  static __INLINE arm_status arm_sqrt_f32(
+  float32_t in,
+  float32_t * pOut)
+  {
+    if(in >= 0.0f)
+    {
+
+#if   (__FPU_USED == 1) && defined ( __CC_ARM   )
+      *pOut = __sqrtf(in);
+#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
+      *pOut = __builtin_sqrtf(in);
+#elif (__FPU_USED == 1) && defined(__GNUC__)
+      *pOut = __builtin_sqrtf(in);
+#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000)
+      __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in));
+#else
+      *pOut = sqrtf(in);
+#endif
+
+      return (ARM_MATH_SUCCESS);
+    }
+    else
+    {
+      *pOut = 0.0f;
+      return (ARM_MATH_ARGUMENT_ERROR);
+    }
+  }
+
+
+  /**
+   * @brief Q31 square root function.
+   * @param[in]  in    input value.  The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF.
+   * @param[out] pOut  square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+  arm_status arm_sqrt_q31(
+  q31_t in,
+  q31_t * pOut);
+
+
+  /**
+   * @brief  Q15 square root function.
+   * @param[in]  in    input value.  The range of the input value is [0 +1) or 0x0000 to 0x7FFF.
+   * @param[out] pOut  square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+  arm_status arm_sqrt_q15(
+  q15_t in,
+  q15_t * pOut);
+
+  /**
+   * @} end of SQRT group
+   */
+
+
+  /**
+   * @brief floating-point Circular write function.
+   */
+  static __INLINE void arm_circularWrite_f32(
+  int32_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const int32_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = (uint16_t)wOffset;
+  }
+
+
+
+  /**
+   * @brief floating-point Circular Read function.
+   */
+  static __INLINE void arm_circularRead_f32(
+  int32_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  int32_t * dst,
+  int32_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (int32_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update rOffset.  Watch out for positive and negative value  */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+
+  /**
+   * @brief Q15 Circular write function.
+   */
+  static __INLINE void arm_circularWrite_q15(
+  q15_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const q15_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = (uint16_t)wOffset;
+  }
+
+
+  /**
+   * @brief Q15 Circular Read function.
+   */
+  static __INLINE void arm_circularRead_q15(
+  q15_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  q15_t * dst,
+  q15_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (q15_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+
+  /**
+   * @brief Q7 Circular write function.
+   */
+  static __INLINE void arm_circularWrite_q7(
+  q7_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const q7_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = (uint16_t)wOffset;
+  }
+
+
+  /**
+   * @brief Q7 Circular Read function.
+   */
+  static __INLINE void arm_circularRead_q7(
+  q7_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  q7_t * dst,
+  q7_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (q7_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update rOffset.  Watch out for positive and negative value */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_power_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_power_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_power_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_power_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Mean value of a Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_mean_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult);
+
+
+  /**
+   * @brief  Mean value of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_mean_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+
+  /**
+   * @brief  Mean value of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_mean_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Mean value of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_mean_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Variance of the elements of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_var_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Variance of the elements of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_var_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Variance of the elements of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_var_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+
+  /**
+   * @brief  Root Mean Square of the elements of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_rms_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Root Mean Square of the elements of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_rms_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Root Mean Square of the elements of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_rms_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+
+  /**
+   * @brief  Standard deviation of the elements of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_std_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+
+  /**
+   * @brief  Standard deviation of the elements of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_std_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+
+  /**
+   * @brief  Standard deviation of the elements of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output value.
+   */
+  void arm_std_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+
+  /**
+   * @brief  Floating-point complex magnitude
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q31 complex magnitude
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q15 complex magnitude
+   * @param[in]  pSrc        points to the complex input vector
+   * @param[out] pDst        points to the real output vector
+   * @param[in]  numSamples  number of complex samples in the input vector
+   */
+  void arm_cmplx_mag_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q15 complex dot product
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   * @param[out] realResult  real part of the result returned here
+   * @param[out] imagResult  imaginary part of the result returned here
+   */
+  void arm_cmplx_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t numSamples,
+  q31_t * realResult,
+  q31_t * imagResult);
+
+
+  /**
+   * @brief  Q31 complex dot product
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   * @param[out] realResult  real part of the result returned here
+   * @param[out] imagResult  imaginary part of the result returned here
+   */
+  void arm_cmplx_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t numSamples,
+  q63_t * realResult,
+  q63_t * imagResult);
+
+
+  /**
+   * @brief  Floating-point complex dot product
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   * @param[out] realResult  real part of the result returned here
+   * @param[out] imagResult  imaginary part of the result returned here
+   */
+  void arm_cmplx_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t numSamples,
+  float32_t * realResult,
+  float32_t * imagResult);
+
+
+  /**
+   * @brief  Q15 complex-by-real multiplication
+   * @param[in]  pSrcCmplx   points to the complex input vector
+   * @param[in]  pSrcReal    points to the real input vector
+   * @param[out] pCmplxDst   points to the complex output vector
+   * @param[in]  numSamples  number of samples in each vector
+   */
+  void arm_cmplx_mult_real_q15(
+  q15_t * pSrcCmplx,
+  q15_t * pSrcReal,
+  q15_t * pCmplxDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q31 complex-by-real multiplication
+   * @param[in]  pSrcCmplx   points to the complex input vector
+   * @param[in]  pSrcReal    points to the real input vector
+   * @param[out] pCmplxDst   points to the complex output vector
+   * @param[in]  numSamples  number of samples in each vector
+   */
+  void arm_cmplx_mult_real_q31(
+  q31_t * pSrcCmplx,
+  q31_t * pSrcReal,
+  q31_t * pCmplxDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Floating-point complex-by-real multiplication
+   * @param[in]  pSrcCmplx   points to the complex input vector
+   * @param[in]  pSrcReal    points to the real input vector
+   * @param[out] pCmplxDst   points to the complex output vector
+   * @param[in]  numSamples  number of samples in each vector
+   */
+  void arm_cmplx_mult_real_f32(
+  float32_t * pSrcCmplx,
+  float32_t * pSrcReal,
+  float32_t * pCmplxDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Minimum value of a Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] result     is output pointer
+   * @param[in]  index      is the array index of the minimum value in the input buffer.
+   */
+  void arm_min_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * result,
+  uint32_t * index);
+
+
+  /**
+   * @brief  Minimum value of a Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output pointer
+   * @param[in]  pIndex     is the array index of the minimum value in the input buffer.
+   */
+  void arm_min_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+
+  /**
+   * @brief  Minimum value of a Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output pointer
+   * @param[out] pIndex     is the array index of the minimum value in the input buffer.
+   */
+  void arm_min_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+
+  /**
+   * @brief  Minimum value of a floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[in]  blockSize  is the number of samples to process
+   * @param[out] pResult    is output pointer
+   * @param[out] pIndex     is the array index of the minimum value in the input buffer.
+   */
+  void arm_min_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q7 vector.
+ * @param[in]  pSrc       points to the input buffer
+ * @param[in]  blockSize  length of the input vector
+ * @param[out] pResult    maximum value returned here
+ * @param[out] pIndex     index of maximum value returned here
+ */
+  void arm_max_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult,
+  uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q15 vector.
+ * @param[in]  pSrc       points to the input buffer
+ * @param[in]  blockSize  length of the input vector
+ * @param[out] pResult    maximum value returned here
+ * @param[out] pIndex     index of maximum value returned here
+ */
+  void arm_max_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q31 vector.
+ * @param[in]  pSrc       points to the input buffer
+ * @param[in]  blockSize  length of the input vector
+ * @param[out] pResult    maximum value returned here
+ * @param[out] pIndex     index of maximum value returned here
+ */
+  void arm_max_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a floating-point vector.
+ * @param[in]  pSrc       points to the input buffer
+ * @param[in]  blockSize  length of the input vector
+ * @param[out] pResult    maximum value returned here
+ * @param[out] pIndex     index of maximum value returned here
+ */
+  void arm_max_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+
+  /**
+   * @brief  Q15 complex-by-complex multiplication
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_mult_cmplx_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Q31 complex-by-complex multiplication
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_mult_cmplx_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief  Floating-point complex-by-complex multiplication
+   * @param[in]  pSrcA       points to the first input vector
+   * @param[in]  pSrcB       points to the second input vector
+   * @param[out] pDst        points to the output vector
+   * @param[in]  numSamples  number of complex samples in each vector
+   */
+  void arm_cmplx_mult_cmplx_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q31 vector.
+   * @param[in]  pSrc       points to the floating-point input vector
+   * @param[out] pDst       points to the Q31 output vector
+   * @param[in]  blockSize  length of the input vector
+   */
+  void arm_float_to_q31(
+  float32_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q15 vector.
+   * @param[in]  pSrc       points to the floating-point input vector
+   * @param[out] pDst       points to the Q15 output vector
+   * @param[in]  blockSize  length of the input vector
+   */
+  void arm_float_to_q15(
+  float32_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q7 vector.
+   * @param[in]  pSrc       points to the floating-point input vector
+   * @param[out] pDst       points to the Q7 output vector
+   * @param[in]  blockSize  length of the input vector
+   */
+  void arm_float_to_q7(
+  float32_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to Q15 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q31_to_q15(
+  q31_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q31_to_q7(
+  q31_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to floating-point vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q15_to_float(
+  q15_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to Q31 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q15_to_q31(
+  q15_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to Q7 vector.
+   * @param[in]  pSrc       is input pointer
+   * @param[out] pDst       is output pointer
+   * @param[in]  blockSize  is the number of samples to process
+   */
+  void arm_q15_to_q7(
+  q15_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @ingroup groupInterpolation
+   */
+
+  /**
+   * @defgroup BilinearInterpolate Bilinear Interpolation
+   *
+   * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
+   * The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process
+   * determines values between the grid points.
+   * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
+   * Bilinear interpolation is often used in image processing to rescale images.
+   * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
+   *
+   * <b>Algorithm</b>
+   * \par
+   * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
+   * For floating-point, the instance structure is defined as:
+   * <pre>
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * </pre>
+   *
+   * \par
+   * where <code>numRows</code> specifies the number of rows in the table;
+   * <code>numCols</code> specifies the number of columns in the table;
+   * and <code>pData</code> points to an array of size <code>numRows*numCols</code> values.
+   * The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes.
+   * That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers.
+   *
+   * \par
+   * Let <code>(x, y)</code> specify the desired interpolation point.  Then define:
+   * <pre>
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * </pre>
+   * \par
+   * The interpolated output point is computed as:
+   * <pre>
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * </pre>
+   * Note that the coordinates (x, y) contain integer and fractional components.
+   * The integer components specify which portion of the table to use while the
+   * fractional components control the interpolation processor.
+   *
+   * \par
+   * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
+   */
+
+  /**
+   * @addtogroup BilinearInterpolate
+   * @{
+   */
+
+
+  /**
+  *
+  * @brief  Floating-point bilinear interpolation.
+  * @param[in,out] S  points to an instance of the interpolation structure.
+  * @param[in]     X  interpolation coordinate.
+  * @param[in]     Y  interpolation coordinate.
+  * @return out interpolated value.
+  */
+  static __INLINE float32_t arm_bilinear_interp_f32(
+  const arm_bilinear_interp_instance_f32 * S,
+  float32_t X,
+  float32_t Y)
+  {
+    float32_t out;
+    float32_t f00, f01, f10, f11;
+    float32_t *pData = S->pData;
+    int32_t xIndex, yIndex, index;
+    float32_t xdiff, ydiff;
+    float32_t b1, b2, b3, b4;
+
+    xIndex = (int32_t) X;
+    yIndex = (int32_t) Y;
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* Calculation of index for two nearest points in X-direction */
+    index = (xIndex - 1) + (yIndex - 1) * S->numCols;
+
+
+    /* Read two nearest points in X-direction */
+    f00 = pData[index];
+    f01 = pData[index + 1];
+
+    /* Calculation of index for two nearest points in Y-direction */
+    index = (xIndex - 1) + (yIndex) * S->numCols;
+
+
+    /* Read two nearest points in Y-direction */
+    f10 = pData[index];
+    f11 = pData[index + 1];
+
+    /* Calculation of intermediate values */
+    b1 = f00;
+    b2 = f01 - f00;
+    b3 = f10 - f00;
+    b4 = f00 - f01 - f10 + f11;
+
+    /* Calculation of fractional part in X */
+    xdiff = X - xIndex;
+
+    /* Calculation of fractional part in Y */
+    ydiff = Y - yIndex;
+
+    /* Calculation of bi-linear interpolated output */
+    out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
+
+    /* return to application */
+    return (out);
+  }
+
+
+  /**
+  *
+  * @brief  Q31 bilinear interpolation.
+  * @param[in,out] S  points to an instance of the interpolation structure.
+  * @param[in]     X  interpolation coordinate in 12.20 format.
+  * @param[in]     Y  interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+  static __INLINE q31_t arm_bilinear_interp_q31(
+  arm_bilinear_interp_instance_q31 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q31_t out;                                   /* Temporary output */
+    q31_t acc = 0;                               /* output */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    q31_t x1, x2, y1, y2;                        /* Nearest output values */
+    int32_t rI, cI;                              /* Row and column indices */
+    q31_t *pYData = S->pData;                    /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* shift left xfract by 11 to keep 1.31 format */
+    xfract = (X & 0x000FFFFF) << 11u;
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[(rI) + (int32_t)nCols * (cI)    ];
+    x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1];
+
+    /* 20 bits for the fractional part */
+    /* shift left yfract by 11 to keep 1.31 format */
+    yfract = (Y & 0x000FFFFF) << 11u;
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[(rI) + (int32_t)nCols * (cI + 1)    ];
+    y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
+    out = ((q31_t) (((q63_t) x1  * (0x7FFFFFFF - xfract)) >> 32));
+    acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32));
+
+    /* x2 * (xfract) * (1-yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (xfract) >> 32));
+
+    /* y1 * (1 - xfract) * (yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+    /* y2 * (xfract) * (yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) y2 * (xfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+    /* Convert acc to 1.31(q31) format */
+    return ((q31_t)(acc << 2));
+  }
+
+
+  /**
+  * @brief  Q15 bilinear interpolation.
+  * @param[in,out] S  points to an instance of the interpolation structure.
+  * @param[in]     X  interpolation coordinate in 12.20 format.
+  * @param[in]     Y  interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+  static __INLINE q15_t arm_bilinear_interp_q15(
+  arm_bilinear_interp_instance_q15 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q63_t acc = 0;                               /* output */
+    q31_t out;                                   /* Temporary output */
+    q15_t x1, x2, y1, y2;                        /* Nearest output values */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    int32_t rI, cI;                              /* Row and column indices */
+    q15_t *pYData = S->pData;                    /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* xfract should be in 12.20 format */
+    xfract = (X & 0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI)    ];
+    x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+
+    /* 20 bits for the fractional part */
+    /* yfract should be in 12.20 format */
+    yfract = (Y & 0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1)    ];
+    y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */
+
+    /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */
+    /* convert 13.35 to 13.31 by right shifting  and out is in 1.31 */
+    out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u);
+    acc = ((q63_t) out * (0xFFFFF - yfract));
+
+    /* x2 * (xfract) * (1-yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u);
+    acc += ((q63_t) out * (xfract));
+
+    /* y1 * (1 - xfract) * (yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u);
+    acc += ((q63_t) out * (yfract));
+
+    /* y2 * (xfract) * (yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u);
+    acc += ((q63_t) out * (yfract));
+
+    /* acc is in 13.51 format and down shift acc by 36 times */
+    /* Convert out to 1.15 format */
+    return ((q15_t)(acc >> 36));
+  }
+
+
+  /**
+  * @brief  Q7 bilinear interpolation.
+  * @param[in,out] S  points to an instance of the interpolation structure.
+  * @param[in]     X  interpolation coordinate in 12.20 format.
+  * @param[in]     Y  interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+  static __INLINE q7_t arm_bilinear_interp_q7(
+  arm_bilinear_interp_instance_q7 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q63_t acc = 0;                               /* output */
+    q31_t out;                                   /* Temporary output */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    q7_t x1, x2, y1, y2;                         /* Nearest output values */
+    int32_t rI, cI;                              /* Row and column indices */
+    q7_t *pYData = S->pData;                     /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* xfract should be in 12.20 format */
+    xfract = (X & (q31_t)0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI)    ];
+    x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+
+    /* 20 bits for the fractional part */
+    /* yfract should be in 12.20 format */
+    yfract = (Y & (q31_t)0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1)    ];
+    y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */
+    out = ((x1 * (0xFFFFF - xfract)));
+    acc = (((q63_t) out * (0xFFFFF - yfract)));
+
+    /* x2 * (xfract) * (1-yfract)  in 2.22 and adding to acc */
+    out = ((x2 * (0xFFFFF - yfract)));
+    acc += (((q63_t) out * (xfract)));
+
+    /* y1 * (1 - xfract) * (yfract)  in 2.22 and adding to acc */
+    out = ((y1 * (0xFFFFF - xfract)));
+    acc += (((q63_t) out * (yfract)));
+
+    /* y2 * (xfract) * (yfract)  in 2.22 and adding to acc */
+    out = ((y2 * (yfract)));
+    acc += (((q63_t) out * (xfract)));
+
+    /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */
+    return ((q7_t)(acc >> 40));
+  }
+
+  /**
+   * @} end of BilinearInterpolate group
+   */
+
+
+/* SMMLAR */
+#define multAcc_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMLSR */
+#define multSub_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMULR */
+#define mult_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32)
+
+/* SMMLA */
+#define multAcc_32x32_keep32(a, x, y) \
+    a += (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMLS */
+#define multSub_32x32_keep32(a, x, y) \
+    a -= (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMUL */
+#define mult_32x32_keep32(a, x, y) \
+    a = (q31_t) (((q63_t) x * y ) >> 32)
+
+
+#if defined ( __CC_ARM )
+  /* Enter low optimization region - place directly above function definition */
+  #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+    #define LOW_OPTIMIZATION_ENTER \
+       _Pragma ("push")         \
+       _Pragma ("O1")
+  #else
+    #define LOW_OPTIMIZATION_ENTER
+  #endif
+
+  /* Exit low optimization region - place directly after end of function definition */
+  #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+    #define LOW_OPTIMIZATION_EXIT \
+       _Pragma ("pop")
+  #else
+    #define LOW_OPTIMIZATION_EXIT
+  #endif
+
+  /* Enter low optimization region - place directly above function definition */
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+
+  /* Exit low optimization region - place directly after end of function definition */
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define LOW_OPTIMIZATION_ENTER
+  #define LOW_OPTIMIZATION_EXIT
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__GNUC__)
+  #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") ))
+  #define LOW_OPTIMIZATION_EXIT
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ICCARM__)
+  /* Enter low optimization region - place directly above function definition */
+  #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+    #define LOW_OPTIMIZATION_ENTER \
+       _Pragma ("optimize=low")
+  #else
+    #define LOW_OPTIMIZATION_ENTER
+  #endif
+
+  /* Exit low optimization region - place directly after end of function definition */
+  #define LOW_OPTIMIZATION_EXIT
+
+  /* Enter low optimization region - place directly above function definition */
+  #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+    #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \
+       _Pragma ("optimize=low")
+  #else
+    #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #endif
+
+  /* Exit low optimization region - place directly after end of function definition */
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__CSMC__)
+  #define LOW_OPTIMIZATION_ENTER
+  #define LOW_OPTIMIZATION_EXIT
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__TASKING__)
+  #define LOW_OPTIMIZATION_ENTER
+  #define LOW_OPTIMIZATION_EXIT
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#endif
+
+
+#ifdef   __cplusplus
+}
+#endif
+
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* _ARM_MATH_H */
+
+/**
+ *
+ * End of file.
+ */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_armcc.h b/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_armcc.h
new file mode 100755
index 0000000..74c49c6
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_armcc.h
@@ -0,0 +1,734 @@
+/**************************************************************************//**
+ * @file     cmsis_armcc.h
+ * @brief    CMSIS Cortex-M Core Function/Instruction Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_ARMCC_H
+#define __CMSIS_ARMCC_H
+
+
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+/* intrinsic void __enable_irq();     */
+/* intrinsic void __disable_irq();    */
+
+/**
+  \brief   Get Control Register
+  \details Returns the content of the Control Register.
+  \return               Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  register uint32_t __regControl         __ASM("control");
+  return(__regControl);
+}
+
+
+/**
+  \brief   Set Control Register
+  \details Writes the given value to the Control Register.
+  \param [in]    control  Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  register uint32_t __regControl         __ASM("control");
+  __regControl = control;
+}
+
+
+/**
+  \brief   Get IPSR Register
+  \details Returns the content of the IPSR Register.
+  \return               IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  register uint32_t __regIPSR          __ASM("ipsr");
+  return(__regIPSR);
+}
+
+
+/**
+  \brief   Get APSR Register
+  \details Returns the content of the APSR Register.
+  \return               APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+  register uint32_t __regAPSR          __ASM("apsr");
+  return(__regAPSR);
+}
+
+
+/**
+  \brief   Get xPSR Register
+  \details Returns the content of the xPSR Register.
+  \return               xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  register uint32_t __regXPSR          __ASM("xpsr");
+  return(__regXPSR);
+}
+
+
+/**
+  \brief   Get Process Stack Pointer
+  \details Returns the current value of the Process Stack Pointer (PSP).
+  \return               PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  return(__regProcessStackPointer);
+}
+
+
+/**
+  \brief   Set Process Stack Pointer
+  \details Assigns the given value to the Process Stack Pointer (PSP).
+  \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  __regProcessStackPointer = topOfProcStack;
+}
+
+
+/**
+  \brief   Get Main Stack Pointer
+  \details Returns the current value of the Main Stack Pointer (MSP).
+  \return               MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  return(__regMainStackPointer);
+}
+
+
+/**
+  \brief   Set Main Stack Pointer
+  \details Assigns the given value to the Main Stack Pointer (MSP).
+  \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  __regMainStackPointer = topOfMainStack;
+}
+
+
+/**
+  \brief   Get Priority Mask
+  \details Returns the current state of the priority mask bit from the Priority Mask Register.
+  \return               Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  return(__regPriMask);
+}
+
+
+/**
+  \brief   Set Priority Mask
+  \details Assigns the given value to the Priority Mask Register.
+  \param [in]    priMask  Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  __regPriMask = (priMask);
+}
+
+
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+  \brief   Enable FIQ
+  \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/**
+  \brief   Disable FIQ
+  \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/**
+  \brief   Get Base Priority
+  \details Returns the current value of the Base Priority register.
+  \return               Base Priority register value
+ */
+__STATIC_INLINE uint32_t  __get_BASEPRI(void)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  return(__regBasePri);
+}
+
+
+/**
+  \brief   Set Base Priority
+  \details Assigns the given value to the Base Priority register.
+  \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  __regBasePri = (basePri & 0xFFU);
+}
+
+
+/**
+  \brief   Set Base Priority with condition
+  \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+           or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+  register uint32_t __regBasePriMax      __ASM("basepri_max");
+  __regBasePriMax = (basePri & 0xFFU);
+}
+
+
+/**
+  \brief   Get Fault Mask
+  \details Returns the current value of the Fault Mask register.
+  \return               Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  return(__regFaultMask);
+}
+
+
+/**
+  \brief   Set Fault Mask
+  \details Assigns the given value to the Fault Mask register.
+  \param [in]    faultMask  Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+
+#if       (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
+
+/**
+  \brief   Get FPSCR
+  \details Returns the current value of the Floating Point Status/Control register.
+  \return               Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#else
+   return(0U);
+#endif
+}
+
+
+/**
+  \brief   Set FPSCR
+  \details Assigns the given value to the Floating Point Status/Control register.
+  \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/**
+  \brief   No Operation
+  \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP                             __nop
+
+
+/**
+  \brief   Wait For Interrupt
+  \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI                             __wfi
+
+
+/**
+  \brief   Wait For Event
+  \details Wait For Event is a hint instruction that permits the processor to enter
+           a low-power state until one of a number of events occurs.
+ */
+#define __WFE                             __wfe
+
+
+/**
+  \brief   Send Event
+  \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV                             __sev
+
+
+/**
+  \brief   Instruction Synchronization Barrier
+  \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+           so that all instructions following the ISB are fetched from cache or memory,
+           after the instruction has been completed.
+ */
+#define __ISB() do {\
+                   __schedule_barrier();\
+                   __isb(0xF);\
+                   __schedule_barrier();\
+                } while (0U)
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() do {\
+                   __schedule_barrier();\
+                   __dsb(0xF);\
+                   __schedule_barrier();\
+                } while (0U)
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+#define __DMB() do {\
+                   __schedule_barrier();\
+                   __dmb(0xF);\
+                   __schedule_barrier();\
+                } while (0U)
+
+/**
+  \brief   Reverse byte order (32 bit)
+  \details Reverses the byte order in integer value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#define __REV                             __rev
+
+
+/**
+  \brief   Reverse byte order (16 bit)
+  \details Reverses the byte order in two unsigned short values.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+  rev16 r0, r0
+  bx lr
+}
+#endif
+
+/**
+  \brief   Reverse byte order in signed short value
+  \details Reverses the byte order in a signed short value with sign extension to integer.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+  revsh r0, r0
+  bx lr
+}
+#endif
+
+
+/**
+  \brief   Rotate Right in unsigned value (32 bit)
+  \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+  \param [in]    value  Value to rotate
+  \param [in]    value  Number of Bits to rotate
+  \return               Rotated value
+ */
+#define __ROR                             __ror
+
+
+/**
+  \brief   Breakpoint
+  \details Causes the processor to enter Debug state.
+           Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+  \param [in]    value  is ignored by the processor.
+                 If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __breakpoint(value)
+
+
+/**
+  \brief   Reverse bit order of value
+  \details Reverses the bit order of the given value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+  #define __RBIT                          __rbit
+#else
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+  int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+  result = value;                      /* r will be reversed bits of v; first get LSB of v */
+  for (value >>= 1U; value; value >>= 1U)
+  {
+    result <<= 1U;
+    result |= value & 1U;
+    s--;
+  }
+  result <<= s;                        /* shift when v's highest bits are zero */
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Count leading zeros
+  \details Counts the number of leading zeros of a data value.
+  \param [in]  value  Value to count the leading zeros
+  \return             number of leading zeros in value
+ */
+#define __CLZ                             __clz
+
+
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+  \brief   LDR Exclusive (8 bit)
+  \details Executes a exclusive LDR instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXB(ptr)                                                        ((uint8_t ) __ldrex(ptr))
+#else
+  #define __LDREXB(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   LDR Exclusive (16 bit)
+  \details Executes a exclusive LDR instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXH(ptr)                                                        ((uint16_t) __ldrex(ptr))
+#else
+  #define __LDREXH(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   LDR Exclusive (32 bit)
+  \details Executes a exclusive LDR instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXW(ptr)                                                        ((uint32_t ) __ldrex(ptr))
+#else
+  #define __LDREXW(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (8 bit)
+  \details Executes a exclusive STR instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXB(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXB(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (16 bit)
+  \details Executes a exclusive STR instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXH(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXH(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (32 bit)
+  \details Executes a exclusive STR instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXW(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXW(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   Remove the exclusive lock
+  \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX                           __clrex
+
+
+/**
+  \brief   Signed Saturate
+  \details Saturates a signed value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (1..32)
+  \return             Saturated value
+ */
+#define __SSAT                            __ssat
+
+
+/**
+  \brief   Unsigned Saturate
+  \details Saturates an unsigned value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+#define __USAT                            __usat
+
+
+/**
+  \brief   Rotate Right with Extend (32 bit)
+  \details Moves each bit of a bitstring right by one bit.
+           The carry input is shifted in at the left end of the bitstring.
+  \param [in]    value  Value to rotate
+  \return               Rotated value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
+{
+  rrx r0, r0
+  bx lr
+}
+#endif
+
+
+/**
+  \brief   LDRT Unprivileged (8 bit)
+  \details Executes a Unprivileged LDRT instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#define __LDRBT(ptr)                      ((uint8_t )  __ldrt(ptr))
+
+
+/**
+  \brief   LDRT Unprivileged (16 bit)
+  \details Executes a Unprivileged LDRT instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#define __LDRHT(ptr)                      ((uint16_t)  __ldrt(ptr))
+
+
+/**
+  \brief   LDRT Unprivileged (32 bit)
+  \details Executes a Unprivileged LDRT instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#define __LDRT(ptr)                       ((uint32_t ) __ldrt(ptr))
+
+
+/**
+  \brief   STRT Unprivileged (8 bit)
+  \details Executes a Unprivileged STRT instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+#define __STRBT(value, ptr)               __strt(value, ptr)
+
+
+/**
+  \brief   STRT Unprivileged (16 bit)
+  \details Executes a Unprivileged STRT instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+#define __STRHT(value, ptr)               __strt(value, ptr)
+
+
+/**
+  \brief   STRT Unprivileged (32 bit)
+  \details Executes a Unprivileged STRT instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+#define __STRT(value, ptr)                __strt(value, ptr)
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if (__CORTEX_M >= 0x04U)  /* only for Cortex-M4 and above */
+
+#define __SADD8                           __sadd8
+#define __QADD8                           __qadd8
+#define __SHADD8                          __shadd8
+#define __UADD8                           __uadd8
+#define __UQADD8                          __uqadd8
+#define __UHADD8                          __uhadd8
+#define __SSUB8                           __ssub8
+#define __QSUB8                           __qsub8
+#define __SHSUB8                          __shsub8
+#define __USUB8                           __usub8
+#define __UQSUB8                          __uqsub8
+#define __UHSUB8                          __uhsub8
+#define __SADD16                          __sadd16
+#define __QADD16                          __qadd16
+#define __SHADD16                         __shadd16
+#define __UADD16                          __uadd16
+#define __UQADD16                         __uqadd16
+#define __UHADD16                         __uhadd16
+#define __SSUB16                          __ssub16
+#define __QSUB16                          __qsub16
+#define __SHSUB16                         __shsub16
+#define __USUB16                          __usub16
+#define __UQSUB16                         __uqsub16
+#define __UHSUB16                         __uhsub16
+#define __SASX                            __sasx
+#define __QASX                            __qasx
+#define __SHASX                           __shasx
+#define __UASX                            __uasx
+#define __UQASX                           __uqasx
+#define __UHASX                           __uhasx
+#define __SSAX                            __ssax
+#define __QSAX                            __qsax
+#define __SHSAX                           __shsax
+#define __USAX                            __usax
+#define __UQSAX                           __uqsax
+#define __UHSAX                           __uhsax
+#define __USAD8                           __usad8
+#define __USADA8                          __usada8
+#define __SSAT16                          __ssat16
+#define __USAT16                          __usat16
+#define __UXTB16                          __uxtb16
+#define __UXTAB16                         __uxtab16
+#define __SXTB16                          __sxtb16
+#define __SXTAB16                         __sxtab16
+#define __SMUAD                           __smuad
+#define __SMUADX                          __smuadx
+#define __SMLAD                           __smlad
+#define __SMLADX                          __smladx
+#define __SMLALD                          __smlald
+#define __SMLALDX                         __smlaldx
+#define __SMUSD                           __smusd
+#define __SMUSDX                          __smusdx
+#define __SMLSD                           __smlsd
+#define __SMLSDX                          __smlsdx
+#define __SMLSLD                          __smlsld
+#define __SMLSLDX                         __smlsldx
+#define __SEL                             __sel
+#define __QADD                            __qadd
+#define __QSUB                            __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0x0000FFFFUL) |  \
+                                           ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)  )
+
+#define __PKHTB(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0xFFFF0000UL) |  \
+                                           ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)  )
+
+#define __SMMLA(ARG1,ARG2,ARG3)          ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+                                                      ((int64_t)(ARG3) << 32U)     ) >> 32U))
+
+#endif /* (__CORTEX_M >= 0x04) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_H */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_armcc_V6.h b/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_armcc_V6.h
new file mode 100755
index 0000000..cd13240
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_armcc_V6.h
@@ -0,0 +1,1800 @@
+/**************************************************************************//**
+ * @file     cmsis_armcc_V6.h
+ * @brief    CMSIS Cortex-M Core Function/Instruction Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_ARMCC_V6_H
+#define __CMSIS_ARMCC_V6_H
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+/**
+  \brief   Enable IRQ Interrupts
+  \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void)
+{
+  __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/**
+  \brief   Disable IRQ Interrupts
+  \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void)
+{
+  __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/**
+  \brief   Get Control Register
+  \details Returns the content of the Control Register.
+  \return               Control Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Control Register (non-secure)
+  \details Returns the content of the non-secure Control Register when in secure mode.
+  \return               non-secure Control Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Control Register
+  \details Writes the given value to the Control Register.
+  \param [in]    control  Control Register value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Control Register (non-secure)
+  \details Writes the given value to the non-secure Control Register when in secure state.
+  \param [in]    control  Control Register value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control)
+{
+  __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
+}
+#endif
+
+
+/**
+  \brief   Get IPSR Register
+  \details Returns the content of the IPSR Register.
+  \return               IPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get IPSR Register (non-secure)
+  \details Returns the content of the non-secure IPSR Register when in secure state.
+  \return               IPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_IPSR_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Get APSR Register
+  \details Returns the content of the APSR Register.
+  \return               APSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get APSR Register (non-secure)
+  \details Returns the content of the non-secure APSR Register when in secure state.
+  \return               APSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_APSR_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Get xPSR Register
+  \details Returns the content of the xPSR Register.
+  \return               xPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get xPSR Register (non-secure)
+  \details Returns the content of the non-secure xPSR Register when in secure state.
+  \return               xPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_xPSR_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Get Process Stack Pointer
+  \details Returns the current value of the Process Stack Pointer (PSP).
+  \return               PSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp"  : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Process Stack Pointer (non-secure)
+  \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
+  \return               PSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp_ns"  : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Process Stack Pointer
+  \details Assigns the given value to the Process Stack Pointer (PSP).
+  \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : "sp");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Process Stack Pointer (non-secure)
+  \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
+  \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : "sp");
+}
+#endif
+
+
+/**
+  \brief   Get Main Stack Pointer
+  \details Returns the current value of the Main Stack Pointer (MSP).
+  \return               MSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Main Stack Pointer (non-secure)
+  \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
+  \return               MSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Main Stack Pointer
+  \details Assigns the given value to the Main Stack Pointer (MSP).
+  \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : "sp");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Main Stack Pointer (non-secure)
+  \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
+  \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : "sp");
+}
+#endif
+
+
+/**
+  \brief   Get Priority Mask
+  \details Returns the current state of the priority mask bit from the Priority Mask Register.
+  \return               Priority Mask value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Priority Mask (non-secure)
+  \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
+  \return               Priority Mask value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Priority Mask
+  \details Assigns the given value to the Priority Mask Register.
+  \param [in]    priMask  Priority Mask
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Priority Mask (non-secure)
+  \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
+  \param [in]    priMask  Priority Mask
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
+}
+#endif
+
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U))  /* ToDo:  ARMCC_V6: check if this is ok for cortex >=3 */
+
+/**
+  \brief   Enable FIQ
+  \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void)
+{
+  __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/**
+  \brief   Disable FIQ
+  \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void)
+{
+  __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/**
+  \brief   Get Base Priority
+  \details Returns the current value of the Base Priority register.
+  \return               Base Priority register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Base Priority (non-secure)
+  \details Returns the current value of the non-secure Base Priority register when in secure state.
+  \return               Base Priority register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Base Priority
+  \details Assigns the given value to the Base Priority register.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+  __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Base Priority (non-secure)
+  \details Assigns the given value to the non-secure Base Priority register when in secure state.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_ns, %0" : : "r" (value) : "memory");
+}
+#endif
+
+
+/**
+  \brief   Set Base Priority with condition
+  \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+           or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Base Priority with condition (non_secure)
+  \details Assigns the given value to the non-secure Base Priority register when in secure state only if BASEPRI masking is disabled,
+	       or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_MAX_NS(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_max_ns, %0" : : "r" (value) : "memory");
+}
+#endif
+
+
+/**
+  \brief   Get Fault Mask
+  \details Returns the current value of the Fault Mask register.
+  \return               Fault Mask register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get Fault Mask (non-secure)
+  \details Returns the current value of the non-secure Fault Mask register when in secure state.
+  \return               Fault Mask register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Fault Mask
+  \details Assigns the given value to the Fault Mask register.
+  \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set Fault Mask (non-secure)
+  \details Assigns the given value to the non-secure Fault Mask register when in secure state.
+  \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
+}
+#endif
+
+
+#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+#if (__ARM_ARCH_8M__ == 1U)
+
+/**
+  \brief   Get Process Stack Pointer Limit
+  \details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
+  \return               PSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psplim"  : "=r" (result) );
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M')     /* ToDo:  ARMCC_V6: check predefined macro for mainline */
+/**
+  \brief   Get Process Stack Pointer Limit (non-secure)
+  \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+  \return               PSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psplim_ns"  : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Process Stack Pointer Limit
+  \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
+  \param [in]    ProcStackPtrLimit  Process Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
+{
+  __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M')     /* ToDo:  ARMCC_V6: check predefined macro for mainline */
+/**
+  \brief   Set Process Stack Pointer (non-secure)
+  \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+  \param [in]    ProcStackPtrLimit  Process Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
+{
+  __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
+}
+#endif
+
+
+/**
+  \brief   Get Main Stack Pointer Limit
+  \details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
+  \return               MSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msplim" : "=r" (result) );
+
+  return(result);
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M')     /* ToDo:  ARMCC_V6: check predefined macro for mainline */
+/**
+  \brief   Get Main Stack Pointer Limit (non-secure)
+  \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
+  \return               MSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Set Main Stack Pointer Limit
+  \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
+  \param [in]    MainStackPtrLimit  Main Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
+{
+  __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
+}
+
+
+#if  (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M')     /* ToDo:  ARMCC_V6: check predefined macro for mainline */
+/**
+  \brief   Set Main Stack Pointer Limit (non-secure)
+  \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
+  \param [in]    MainStackPtrLimit  Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
+{
+  __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
+}
+#endif
+
+#endif /* (__ARM_ARCH_8M__ == 1U) */
+
+
+#if ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U))  /* ToDo:  ARMCC_V6: check if this is ok for cortex >=4 */
+
+/**
+  \brief   Get FPSCR
+  \details eturns the current value of the Floating Point Status/Control register.
+  \return               Floating Point Status/Control register value
+ */
+#define __get_FPSCR      __builtin_arm_get_fpscr
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  uint32_t result;
+
+  __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+#endif
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Get FPSCR (non-secure)
+  \details Returns the current value of the non-secure Floating Point Status/Control register when in secure state.
+  \return               Floating Point Status/Control register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FPSCR_NS(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  uint32_t result;
+
+  __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("VMRS %0, fpscr_ns" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+#endif
+
+
+/**
+  \brief   Set FPSCR
+  \details Assigns the given value to the Floating Point Status/Control register.
+  \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+#define __set_FPSCR      __builtin_arm_set_fpscr
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+#endif
+
+#if  (__ARM_FEATURE_CMSE == 3U)
+/**
+  \brief   Set FPSCR (non-secure)
+  \details Assigns the given value to the non-secure Floating Point Status/Control register when in secure state.
+  \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FPSCR_NS(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  __ASM volatile ("");                                 /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("VMSR fpscr_ns, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+#endif
+
+#endif /* ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+  \brief   No Operation
+  \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP          __builtin_arm_nop
+
+/**
+  \brief   Wait For Interrupt
+  \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI          __builtin_arm_wfi
+
+
+/**
+  \brief   Wait For Event
+  \details Wait For Event is a hint instruction that permits the processor to enter
+           a low-power state until one of a number of events occurs.
+ */
+#define __WFE          __builtin_arm_wfe
+
+
+/**
+  \brief   Send Event
+  \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV          __builtin_arm_sev
+
+
+/**
+  \brief   Instruction Synchronization Barrier
+  \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+           so that all instructions following the ISB are fetched from cache or memory,
+           after the instruction has been completed.
+ */
+#define __ISB()        __builtin_arm_isb(0xF);
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB()        __builtin_arm_dsb(0xF);
+
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+#define __DMB()        __builtin_arm_dmb(0xF);
+
+
+/**
+  \brief   Reverse byte order (32 bit)
+  \details Reverses the byte order in integer value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#define __REV          __builtin_bswap32
+
+
+/**
+  \brief   Reverse byte order (16 bit)
+  \details Reverses the byte order in two unsigned short values.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#define __REV16          __builtin_bswap16                           /* ToDo:  ARMCC_V6: check if __builtin_bswap16 could be used */
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+#endif
+
+
+/**
+  \brief   Reverse byte order in signed short value
+  \details Reverses the byte order in a signed short value with sign extension to integer.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+                                                          /* ToDo:  ARMCC_V6: check if __builtin_bswap16 could be used */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+  int32_t result;
+
+  __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/**
+  \brief   Rotate Right in unsigned value (32 bit)
+  \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+  \param [in]    op1  Value to rotate
+  \param [in]    op2  Number of Bits to rotate
+  \return               Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+  return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+  \brief   Breakpoint
+  \details Causes the processor to enter Debug state.
+            Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+    \param [in]    value  is ignored by the processor.
+                   If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __ASM volatile ("bkpt "#value)
+
+
+/**
+  \brief   Reverse bit order of value
+  \details Reverses the bit order of the given value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+                                                          /* ToDo:  ARMCC_V6: check if __builtin_arm_rbit is supported */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U))  /* ToDo:  ARMCC_V6: check if this is ok for cortex >=3 */
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+#else
+  int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+  result = value;                      /* r will be reversed bits of v; first get LSB of v */
+  for (value >>= 1U; value; value >>= 1U)
+  {
+    result <<= 1U;
+    result |= value & 1U;
+    s--;
+  }
+  result <<= s;                        /* shift when v's highest bits are zero */
+#endif
+  return(result);
+}
+
+
+/**
+  \brief   Count leading zeros
+  \details Counts the number of leading zeros of a data value.
+  \param [in]  value  Value to count the leading zeros
+  \return             number of leading zeros in value
+ */
+#define __CLZ             __builtin_clz
+
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U))  /* ToDo:  ARMCC_V6: check if this is ok for cortex >=3 */
+
+/**
+  \brief   LDR Exclusive (8 bit)
+  \details Executes a exclusive LDR instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#define __LDREXB        (uint8_t)__builtin_arm_ldrex
+
+
+/**
+  \brief   LDR Exclusive (16 bit)
+  \details Executes a exclusive LDR instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#define __LDREXH        (uint16_t)__builtin_arm_ldrex
+
+
+/**
+  \brief   LDR Exclusive (32 bit)
+  \details Executes a exclusive LDR instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#define __LDREXW        (uint32_t)__builtin_arm_ldrex
+
+
+/**
+  \brief   STR Exclusive (8 bit)
+  \details Executes a exclusive STR instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define __STREXB        (uint32_t)__builtin_arm_strex
+
+
+/**
+  \brief   STR Exclusive (16 bit)
+  \details Executes a exclusive STR instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define __STREXH        (uint32_t)__builtin_arm_strex
+
+
+/**
+  \brief   STR Exclusive (32 bit)
+  \details Executes a exclusive STR instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define __STREXW        (uint32_t)__builtin_arm_strex
+
+
+/**
+  \brief   Remove the exclusive lock
+  \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX             __builtin_arm_clrex
+
+
+/**
+  \brief   Signed Saturate
+  \details Saturates a signed value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (1..32)
+  \return             Saturated value
+ */
+/*#define __SSAT             __builtin_arm_ssat*/
+#define __SSAT(ARG1,ARG2) \
+({                          \
+  int32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/**
+  \brief   Unsigned Saturate
+  \details Saturates an unsigned value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+#define __USAT             __builtin_arm_usat
+#if 0
+#define __USAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+#endif
+
+
+/**
+  \brief   Rotate Right with Extend (32 bit)
+  \details Moves each bit of a bitstring right by one bit.
+           The carry input is shifted in at the left end of the bitstring.
+  \param [in]    value  Value to rotate
+  \return               Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/**
+  \brief   LDRT Unprivileged (8 bit)
+  \details Executes a Unprivileged LDRT instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (16 bit)
+  \details Executes a Unprivileged LDRT instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (32 bit)
+  \details Executes a Unprivileged LDRT instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return(result);
+}
+
+
+/**
+  \brief   STRT Unprivileged (8 bit)
+  \details Executes a Unprivileged STRT instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
+{
+   __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   STRT Unprivileged (16 bit)
+  \details Executes a Unprivileged STRT instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
+{
+   __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   STRT Unprivileged (32 bit)
+  \details Executes a Unprivileged STRT instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
+{
+   __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
+}
+
+#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+#if (__ARM_ARCH_8M__ == 1U)
+
+/**
+  \brief   Load-Acquire (8 bit)
+  \details Executes a LDAB instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return ((uint8_t) result);
+}
+
+
+/**
+  \brief   Load-Acquire (16 bit)
+  \details Executes a LDAH instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return ((uint16_t) result);
+}
+
+
+/**
+  \brief   Load-Acquire (32 bit)
+  \details Executes a LDA instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr)
+{
+    uint32_t result;
+
+   __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) );
+   return(result);
+}
+
+
+/**
+  \brief   Store-Release (8 bit)
+  \details Executes a STLB instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
+{
+   __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   Store-Release (16 bit)
+  \details Executes a STLH instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
+{
+   __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   Store-Release (32 bit)
+  \details Executes a STL instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr)
+{
+   __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   Load-Acquire Exclusive (8 bit)
+  \details Executes a LDAB exclusive instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#define     __LDAEXB                 (uint8_t)__builtin_arm_ldaex
+
+
+/**
+  \brief   Load-Acquire Exclusive (16 bit)
+  \details Executes a LDAH exclusive instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#define     __LDAEXH                 (uint16_t)__builtin_arm_ldaex
+
+
+/**
+  \brief   Load-Acquire Exclusive (32 bit)
+  \details Executes a LDA exclusive instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#define     __LDAEX                  (uint32_t)__builtin_arm_ldaex
+
+
+/**
+  \brief   Store-Release Exclusive (8 bit)
+  \details Executes a STLB exclusive instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define     __STLEXB                 (uint32_t)__builtin_arm_stlex
+
+
+/**
+  \brief   Store-Release Exclusive (16 bit)
+  \details Executes a STLH exclusive instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define     __STLEXH                 (uint32_t)__builtin_arm_stlex
+
+
+/**
+  \brief   Store-Release Exclusive (32 bit)
+  \details Executes a STL exclusive instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+#define     __STLEX                  (uint32_t)__builtin_arm_stlex
+
+#endif /* (__ARM_ARCH_8M__ == 1U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if (__ARM_FEATURE_DSP == 1U)        /* ToDo:  ARMCC_V6: This should be ARCH >= ARMv7-M + SIMD */
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE  int32_t __QADD( int32_t op1,  int32_t op2)
+{
+  int32_t result;
+
+  __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE  int32_t __QSUB( int32_t op1,  int32_t op2)
+{
+  int32_t result;
+
+  __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  if (ARG3 == 0) \
+    __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2)  ); \
+  else \
+    __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#endif /* (__ARM_FEATURE_DSP == 1U) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_V6_H */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_gcc.h b/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_gcc.h
new file mode 100755
index 0000000..bb89fbb
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/cmsis_gcc.h
@@ -0,0 +1,1373 @@
+/**************************************************************************//**
+ * @file     cmsis_gcc.h
+ * @brief    CMSIS Cortex-M Core Function/Instruction Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_GCC_H
+#define __CMSIS_GCC_H
+
+/* ignore some GCC warnings */
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+/**
+  \brief   Enable IRQ Interrupts
+  \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+  __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/**
+  \brief   Disable IRQ Interrupts
+  \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+  __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/**
+  \brief   Get Control Register
+  \details Returns the content of the Control Register.
+  \return               Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Control Register
+  \details Writes the given value to the Control Register.
+  \param [in]    control  Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+/**
+  \brief   Get IPSR Register
+  \details Returns the content of the IPSR Register.
+  \return               IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Get APSR Register
+  \details Returns the content of the APSR Register.
+  \return               APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Get xPSR Register
+  \details Returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Get Process Stack Pointer
+  \details Returns the current value of the Process Stack Pointer (PSP).
+  \return               PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp\n"  : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Process Stack Pointer
+  \details Assigns the given value to the Process Stack Pointer (PSP).
+  \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
+}
+
+
+/**
+  \brief   Get Main Stack Pointer
+  \details Returns the current value of the Main Stack Pointer (MSP).
+  \return               MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Main Stack Pointer
+  \details Assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
+}
+
+
+/**
+  \brief   Get Priority Mask
+  \details Returns the current state of the priority mask bit from the Priority Mask Register.
+  \return               Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Priority Mask
+  \details Assigns the given value to the Priority Mask Register.
+  \param [in]    priMask  Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if       (__CORTEX_M >= 0x03U)
+
+/**
+  \brief   Enable FIQ
+  \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+  __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/**
+  \brief   Disable FIQ
+  \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+           Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+  __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/**
+  \brief   Get Base Priority
+  \details Returns the current value of the Base Priority register.
+  \return               Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Base Priority
+  \details Assigns the given value to the Base Priority register.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+  __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+/**
+  \brief   Set Base Priority with condition
+  \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+           or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
+}
+
+
+/**
+  \brief   Get Fault Mask
+  \details Returns the current value of the Fault Mask register.
+  \return               Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+  return(result);
+}
+
+
+/**
+  \brief   Set Fault Mask
+  \details Assigns the given value to the Fault Mask register.
+  \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+#endif /* (__CORTEX_M >= 0x03U) */
+
+
+#if       (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
+
+/**
+  \brief   Get FPSCR
+  \details Returns the current value of the Floating Point Status/Control register.
+  \return               Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  uint32_t result;
+
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+
+
+/**
+  \brief   Set FPSCR
+  \details Assigns the given value to the Floating Point Status/Control register.
+  \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+  \brief   No Operation
+  \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
+{
+  __ASM volatile ("nop");
+}
+
+
+/**
+  \brief   Wait For Interrupt
+  \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
+{
+  __ASM volatile ("wfi");
+}
+
+
+/**
+  \brief   Wait For Event
+  \details Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
+{
+  __ASM volatile ("wfe");
+}
+
+
+/**
+  \brief   Send Event
+  \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
+{
+  __ASM volatile ("sev");
+}
+
+
+/**
+  \brief   Instruction Synchronization Barrier
+  \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+           so that all instructions following the ISB are fetched from cache or memory,
+           after the instruction has been completed.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
+{
+  __ASM volatile ("isb 0xF":::"memory");
+}
+
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
+{
+  __ASM volatile ("dsb 0xF":::"memory");
+}
+
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
+{
+  __ASM volatile ("dmb 0xF":::"memory");
+}
+
+
+/**
+  \brief   Reverse byte order (32 bit)
+  \details Reverses the byte order in integer value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+  return __builtin_bswap32(value);
+#else
+  uint32_t result;
+
+  __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/**
+  \brief   Reverse byte order (16 bit)
+  \details Reverses the byte order in two unsigned short values.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/**
+  \brief   Reverse byte order in signed short value
+  \details Reverses the byte order in a signed short value with sign extension to integer.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+  return (short)__builtin_bswap16(value);
+#else
+  int32_t result;
+
+  __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/**
+  \brief   Rotate Right in unsigned value (32 bit)
+  \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+  \param [in]    value  Value to rotate
+  \param [in]    value  Number of Bits to rotate
+  \return               Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+  return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+  \brief   Breakpoint
+  \details Causes the processor to enter Debug state.
+           Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+  \param [in]    value  is ignored by the processor.
+                 If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __ASM volatile ("bkpt "#value)
+
+
+/**
+  \brief   Reverse bit order of value
+  \details Reverses the bit order of the given value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+#else
+  int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+  result = value;                      /* r will be reversed bits of v; first get LSB of v */
+  for (value >>= 1U; value; value >>= 1U)
+  {
+    result <<= 1U;
+    result |= value & 1U;
+    s--;
+  }
+  result <<= s;                        /* shift when v's highest bits are zero */
+#endif
+  return(result);
+}
+
+
+/**
+  \brief   Count leading zeros
+  \details Counts the number of leading zeros of a data value.
+  \param [in]  value  Value to count the leading zeros
+  \return             number of leading zeros in value
+ */
+#define __CLZ             __builtin_clz
+
+
+#if       (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+  \brief   LDR Exclusive (8 bit)
+  \details Executes a exclusive LDR instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDR Exclusive (16 bit)
+  \details Executes a exclusive LDR instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDR Exclusive (32 bit)
+  \details Executes a exclusive LDR instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
+   return(result);
+}
+
+
+/**
+  \brief   STR Exclusive (8 bit)
+  \details Executes a exclusive STR instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+   return(result);
+}
+
+
+/**
+  \brief   STR Exclusive (16 bit)
+  \details Executes a exclusive STR instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+   return(result);
+}
+
+
+/**
+  \brief   STR Exclusive (32 bit)
+  \details Executes a exclusive STR instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+  \return          0  Function succeeded
+  \return          1  Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/**
+  \brief   Remove the exclusive lock
+  \details Removes the exclusive lock which is created by LDREX.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
+{
+  __ASM volatile ("clrex" ::: "memory");
+}
+
+
+/**
+  \brief   Signed Saturate
+  \details Saturates a signed value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (1..32)
+  \return             Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/**
+  \brief   Unsigned Saturate
+  \details Saturates an unsigned value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/**
+  \brief   Rotate Right with Extend (32 bit)
+  \details Moves each bit of a bitstring right by one bit.
+           The carry input is shifted in at the left end of the bitstring.
+  \param [in]    value  Value to rotate
+  \return               Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/**
+  \brief   LDRT Unprivileged (8 bit)
+  \details Executes a Unprivileged LDRT instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (16 bit)
+  \details Executes a Unprivileged LDRT instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (32 bit)
+  \details Executes a Unprivileged LDRT instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
+   return(result);
+}
+
+
+/**
+  \brief   STRT Unprivileged (8 bit)
+  \details Executes a Unprivileged STRT instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
+{
+   __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   STRT Unprivileged (16 bit)
+  \details Executes a Unprivileged STRT instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
+{
+   __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+  \brief   STRT Unprivileged (32 bit)
+  \details Executes a Unprivileged STRT instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    ptr  Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
+{
+   __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
+}
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if (__CORTEX_M >= 0x04U)  /* only for Cortex-M4 and above */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({                          \
+  int32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   /* Little endian */
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               /* Big endian */
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE  int32_t __QADD( int32_t op1,  int32_t op2)
+{
+  int32_t result;
+
+  __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE  int32_t __QSUB( int32_t op1,  int32_t op2)
+{
+  int32_t result;
+
+  __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  if (ARG3 == 0) \
+    __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2)  ); \
+  else \
+    __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x04) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* __CMSIS_GCC_H */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm0.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm0.h
new file mode 100755
index 0000000..711dad5
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm0.h
@@ -0,0 +1,798 @@
+/**************************************************************************//**
+ * @file     core_cm0.h
+ * @brief    CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0_H_GENERIC
+#define __CORE_CM0_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex_M0
+  @{
+ */
+
+/*  CMSIS CM0 definitions */
+#define __CM0_CMSIS_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CMSIS HAL main version */
+#define __CM0_CMSIS_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CMSIS HAL sub version */
+#define __CM0_CMSIS_VERSION       ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
+                                    __CM0_CMSIS_VERSION_SUB           )        /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x00U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0_H_DEPENDANT
+#define __CORE_CM0_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM0_REV
+    #define __CM0_REV               0x0000U
+    #warning "__CM0_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M0 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:28;              /*!< bit:  0..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t _reserved1:3;               /*!< bit: 25..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:1;               /*!< bit:      0  Reserved */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[1U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[31U];
+  __IOM uint32_t ICER[1U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[31U];
+  __IOM uint32_t ISPR[1U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[31U];
+  __IOM uint32_t ICPR[1U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[31U];
+        uint32_t RESERVED4[64U];
+  __IOM uint32_t IP[8U];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+        uint32_t RESERVED0;
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+        uint32_t RESERVED1;
+  __IOM uint32_t SHP[2U];                /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+            Therefore they are not covered by the Cortex-M0 header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
+#define _SHP_IDX(IRQn)           ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >>    2UL)      )
+#define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      )
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+  else
+  {
+    NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm0plus.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm0plus.h
new file mode 100755
index 0000000..b04aa39
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm0plus.h
@@ -0,0 +1,914 @@
+/**************************************************************************//**
+ * @file     core_cm0plus.h
+ * @brief    CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0PLUS_H_GENERIC
+#define __CORE_CM0PLUS_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex-M0+
+  @{
+ */
+
+/*  CMSIS CM0+ definitions */
+#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U)                                   /*!< [31:16] CMSIS HAL main version */
+#define __CM0PLUS_CMSIS_VERSION_SUB  (0x1EU)                                   /*!< [15:0]  CMSIS HAL sub version */
+#define __CM0PLUS_CMSIS_VERSION      ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
+                                       __CM0PLUS_CMSIS_VERSION_SUB           ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x00U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0PLUS_H_DEPENDANT
+#define __CORE_CM0PLUS_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM0PLUS_REV
+    #define __CM0PLUS_REV             0x0000U
+    #warning "__CM0PLUS_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __VTOR_PRESENT
+    #define __VTOR_PRESENT            0U
+    #warning "__VTOR_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex-M0+ */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core MPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:28;              /*!< bit:  0..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t _reserved1:3;               /*!< bit: 25..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[1U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[31U];
+  __IOM uint32_t ICER[1U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[31U];
+  __IOM uint32_t ISPR[1U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[31U];
+  __IOM uint32_t ICPR[1U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[31U];
+        uint32_t RESERVED4[64U];
+  __IOM uint32_t IP[8U];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+#if (__VTOR_PRESENT == 1U)
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+#else
+        uint32_t RESERVED0;
+#endif
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+        uint32_t RESERVED1;
+  __IOM uint32_t SHP[2U];                /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+#if (__VTOR_PRESENT == 1U)
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 8U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   8U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0xFFFFFFUL << MPU_RBAR_ADDR_Pos)              /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+            Therefore they are not covered by the Cortex-M0+ header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M0+ Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
+#define _SHP_IDX(IRQn)           ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >>    2UL)      )
+#define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      )
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+  else
+  {
+    NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm3.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm3.h
new file mode 100755
index 0000000..b4ac4c7
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm3.h
@@ -0,0 +1,1763 @@
+/**************************************************************************//**
+ * @file     core_cm3.h
+ * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM3_H_GENERIC
+#define __CORE_CM3_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex_M3
+  @{
+ */
+
+/*  CMSIS CM3 definitions */
+#define __CM3_CMSIS_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16U) | \
+                                    __CM3_CMSIS_VERSION_SUB           )        /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x03U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM3_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM3_H_DEPENDANT
+#define __CORE_CM3_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM3_REV
+    #define __CM3_REV               0x0200U
+    #warning "__CM3_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M3 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27U                                            /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0) */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27U                                            /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25U                                            /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[24U];
+  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[24U];
+  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[24U];
+  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[24U];
+  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
+        uint32_t RESERVED4[56U];
+  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+        uint32_t RESERVED5[644U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0U                                         /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+  __IOM uint8_t  SHP[12U];               /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
+  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
+  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
+  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
+  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
+  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
+  __IM  uint32_t PFR[2U];                /*!< Offset: 0x040 (R/ )  Processor Feature Register */
+  __IM  uint32_t DFR;                    /*!< Offset: 0x048 (R/ )  Debug Feature Register */
+  __IM  uint32_t ADR;                    /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
+  __IM  uint32_t MMFR[4U];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
+  __IM  uint32_t ISAR[5U];               /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
+        uint32_t RESERVED0[5U];
+  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11U                                            /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#if (__CM3_REV < 0x0201U)                   /* core r2p1 */
+#define SCB_VTOR_TBLBASE_Pos               29U                                            /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk               (1UL << SCB_VTOR_TBLBASE_Pos)                  /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+#else
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8U                                            /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0U                                            /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8U                                            /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4U                                            /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1U                                            /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0U                                            /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18U                                            /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17U                                            /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16U                                            /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14U                                            /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13U                                            /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12U                                            /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11U                                            /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10U                                            /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8U                                            /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7U                                            /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3U                                            /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1U                                            /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0U                                            /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16U                                            /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8U                                            /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0U                                            /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31U                                            /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30U                                            /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1U                                            /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4U                                            /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3U                                            /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2U                                            /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1U                                            /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0U                                            /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t ICTR;                   /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200U))
+  __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */
+#else
+        uint32_t RESERVED1[1U];
+#endif
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0U                                         /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2U                                         /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1U                                         /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0U                                         /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+  \brief    Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __OM  union
+  {
+    __OM  uint8_t    u8;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit */
+    __OM  uint16_t   u16;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit */
+    __OM  uint32_t   u32;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit */
+  }  PORT [32U];                         /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers */
+        uint32_t RESERVED0[864U];
+  __IOM uint32_t TER;                    /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register */
+        uint32_t RESERVED1[15U];
+  __IOM uint32_t TPR;                    /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register */
+        uint32_t RESERVED2[15U];
+  __IOM uint32_t TCR;                    /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register */
+        uint32_t RESERVED3[29U];
+  __OM  uint32_t IWR;                    /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register */
+  __IM  uint32_t IRR;                    /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register */
+  __IOM uint32_t IMCR;                   /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register */
+        uint32_t RESERVED4[43U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register */
+        uint32_t RESERVED5[6U];
+  __IM  uint32_t PID4;                   /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __IM  uint32_t PID5;                   /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __IM  uint32_t PID6;                   /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __IM  uint32_t PID7;                   /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __IM  uint32_t PID0;                   /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __IM  uint32_t PID1;                   /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __IM  uint32_t PID2;                   /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __IM  uint32_t PID3;                   /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __IM  uint32_t CID0;                   /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __IM  uint32_t CID1;                   /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __IM  uint32_t CID2;                   /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __IM  uint32_t CID3;                   /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0U                                            /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23U                                            /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16U                                            /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10U                                            /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8U                                            /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4U                                            /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3U                                            /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2U                                            /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1U                                            /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0U                                            /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0U                                            /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0U                                            /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0U                                            /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2U                                            /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1U                                            /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0U                                            /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+  \brief    Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control Register */
+  __IOM uint32_t CYCCNT;                 /*!< Offset: 0x004 (R/W)  Cycle Count Register */
+  __IOM uint32_t CPICNT;                 /*!< Offset: 0x008 (R/W)  CPI Count Register */
+  __IOM uint32_t EXCCNT;                 /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register */
+  __IOM uint32_t SLEEPCNT;               /*!< Offset: 0x010 (R/W)  Sleep Count Register */
+  __IOM uint32_t LSUCNT;                 /*!< Offset: 0x014 (R/W)  LSU Count Register */
+  __IOM uint32_t FOLDCNT;                /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register */
+  __IM  uint32_t PCSR;                   /*!< Offset: 0x01C (R/ )  Program Counter Sample Register */
+  __IOM uint32_t COMP0;                  /*!< Offset: 0x020 (R/W)  Comparator Register 0 */
+  __IOM uint32_t MASK0;                  /*!< Offset: 0x024 (R/W)  Mask Register 0 */
+  __IOM uint32_t FUNCTION0;              /*!< Offset: 0x028 (R/W)  Function Register 0 */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t COMP1;                  /*!< Offset: 0x030 (R/W)  Comparator Register 1 */
+  __IOM uint32_t MASK1;                  /*!< Offset: 0x034 (R/W)  Mask Register 1 */
+  __IOM uint32_t FUNCTION1;              /*!< Offset: 0x038 (R/W)  Function Register 1 */
+        uint32_t RESERVED1[1U];
+  __IOM uint32_t COMP2;                  /*!< Offset: 0x040 (R/W)  Comparator Register 2 */
+  __IOM uint32_t MASK2;                  /*!< Offset: 0x044 (R/W)  Mask Register 2 */
+  __IOM uint32_t FUNCTION2;              /*!< Offset: 0x048 (R/W)  Function Register 2 */
+        uint32_t RESERVED2[1U];
+  __IOM uint32_t COMP3;                  /*!< Offset: 0x050 (R/W)  Comparator Register 3 */
+  __IOM uint32_t MASK3;                  /*!< Offset: 0x054 (R/W)  Mask Register 3 */
+  __IOM uint32_t FUNCTION3;              /*!< Offset: 0x058 (R/W)  Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28U                                         /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27U                                         /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26U                                         /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25U                                         /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24U                                         /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22U                                         /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21U                                         /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20U                                         /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19U                                         /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18U                                         /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17U                                         /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16U                                         /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12U                                         /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10U                                         /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9U                                         /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5U                                         /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1U                                         /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0U                                         /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0U                                         /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0U                                         /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0U                                         /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0U                                         /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0U                                         /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24U                                         /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16U                                         /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12U                                         /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10U                                         /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9U                                         /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8U                                         /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7U                                         /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5U                                         /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0U                                         /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+  \brief    Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IOM uint32_t SSPSR;                  /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register */
+  __IOM uint32_t CSPSR;                  /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACPR;                   /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+        uint32_t RESERVED1[55U];
+  __IOM uint32_t SPPR;                   /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+        uint32_t RESERVED2[131U];
+  __IM  uint32_t FFSR;                   /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IOM uint32_t FFCR;                   /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __IM  uint32_t FSCR;                   /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+        uint32_t RESERVED3[759U];
+  __IM  uint32_t TRIGGER;                /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __IM  uint32_t FIFO0;                  /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __IM  uint32_t ITATBCTR2;              /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+        uint32_t RESERVED4[1U];
+  __IM  uint32_t ITATBCTR0;              /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __IM  uint32_t FIFO1;                  /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IOM uint32_t ITCTRL;                 /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+        uint32_t RESERVED5[39U];
+  __IOM uint32_t CLAIMSET;               /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IOM uint32_t CLAIMCLR;               /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+        uint32_t RESERVED7[8U];
+  __IM  uint32_t DEVID;                  /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __IM  uint32_t DEVTYPE;                /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0U                                         /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0U                                         /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3U                                         /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2U                                         /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1U                                         /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0U                                         /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8U                                         /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1U                                         /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0U                                         /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16U                                         /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8U                                         /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0U                                         /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16U                                         /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8U                                         /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0U                                         /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0U                                         /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11U                                         /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10U                                         /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9U                                         /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6U                                         /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5U                                         /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0U                                         /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4U                                         /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0U                                         /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A1;                /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register */
+  __IOM uint32_t RASR_A1;                /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A2;                /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register */
+  __IOM uint32_t RASR_A2;                /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A3;                /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register */
+  __IOM uint32_t RASR_A3;                /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Type definitions for the Core Debug Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IOM uint32_t DHCSR;                  /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register */
+  __OM  uint32_t DCRSR;                  /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register */
+  __IOM uint32_t DCRDR;                  /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register */
+  __IOM uint32_t DEMCR;                  /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16U                                            /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25U                                            /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24U                                            /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19U                                            /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18U                                            /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17U                                            /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16U                                            /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5U                                            /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3U                                            /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2U                                            /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1U                                            /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0U                                            /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos         16U                                            /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0U                                            /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19U                                            /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18U                                            /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17U                                            /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16U                                            /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10U                                            /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9U                                            /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8U                                            /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7U                                            /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6U                                            /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5U                                            /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4U                                            /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0U                                            /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/**
+  \brief   Set Priority Grouping
+  \details Sets the priority grouping field using the required unlock sequence.
+           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+           Only values from 0..7 are used.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8U)                      );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/**
+  \brief   Get Priority Grouping
+  \details Reads the priority grouping field from the NVIC Interrupt Controller.
+  \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Active Interrupt
+  \details Reads the active register in NVIC and returns the active bit.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else
+  {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]               >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   Encode Priority
+  \details Encodes the priority for an interrupt with the given priority group,
+           preemptive priority value, and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]     PriorityGroup  Used priority group.
+  \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+  \param [in]       SubPriority  Subpriority value (starting from 0).
+  \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/**
+  \brief   Decode Priority
+  \details Decodes an interrupt priority value with a given priority group to
+           preemptive priority value and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+  \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+  \param [in]     PriorityGroup  Used priority group.
+  \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+  \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_core_DebugFunctions ITM Functions
+  \brief    Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters. */
+#define                 ITM_RXBUFFER_EMPTY   0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+  \brief   ITM Send Character
+  \details Transmits a character via the ITM channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0U].u32 == 0UL)
+    {
+      __NOP();
+    }
+    ITM->PORT[0U].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Receive Character
+  \details Inputs a character via the external variable \ref ITM_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+  {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Check Character
+  \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+  {
+    return (0);                              /* no character available */
+  }
+  else
+  {
+    return (1);                              /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM3_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm4.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm4.h
new file mode 100755
index 0000000..dc840eb
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm4.h
@@ -0,0 +1,1937 @@
+/**************************************************************************//**
+ * @file     core_cm4.h
+ * @brief    CMSIS Cortex-M4 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM4_H_GENERIC
+#define __CORE_CM4_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex_M4
+  @{
+ */
+
+/*  CMSIS CM4 definitions */
+#define __CM4_CMSIS_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CMSIS HAL main version */
+#define __CM4_CMSIS_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CMSIS HAL sub version */
+#define __CM4_CMSIS_VERSION       ((__CM4_CMSIS_VERSION_MAIN << 16U) | \
+                                    __CM4_CMSIS_VERSION_SUB           )        /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x04U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1U
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+#include "core_cmSimd.h"                 /* Compiler specific SIMD Intrinsics */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM4_H_DEPENDANT
+#define __CORE_CM4_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM4_REV
+    #define __CM4_REV               0x0000U
+    #warning "__CM4_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __FPU_PRESENT
+    #define __FPU_PRESENT             0U
+    #warning "__FPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M4 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+  - Core FPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27U                                            /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+#define APSR_GE_Pos                        16U                                            /*!< APSR: GE Position */
+#define APSR_GE_Msk                        (0xFUL << APSR_GE_Pos)                         /*!< APSR: GE Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0) */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27U                                            /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25U                                            /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_GE_Pos                        16U                                            /*!< xPSR: GE Position */
+#define xPSR_GE_Msk                        (0xFUL << xPSR_GE_Pos)                         /*!< xPSR: GE Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_FPCA_Pos                    2U                                            /*!< CONTROL: FPCA Position */
+#define CONTROL_FPCA_Msk                   (1UL << CONTROL_FPCA_Pos)                      /*!< CONTROL: FPCA Mask */
+
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[24U];
+  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[24U];
+  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[24U];
+  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[24U];
+  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
+        uint32_t RESERVED4[56U];
+  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+        uint32_t RESERVED5[644U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0U                                         /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+  __IOM uint8_t  SHP[12U];               /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
+  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
+  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
+  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
+  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
+  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
+  __IM  uint32_t PFR[2U];                /*!< Offset: 0x040 (R/ )  Processor Feature Register */
+  __IM  uint32_t DFR;                    /*!< Offset: 0x048 (R/ )  Debug Feature Register */
+  __IM  uint32_t ADR;                    /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
+  __IM  uint32_t MMFR[4U];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
+  __IM  uint32_t ISAR[5U];               /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
+        uint32_t RESERVED0[5U];
+  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11U                                            /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8U                                            /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0U                                            /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8U                                            /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4U                                            /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1U                                            /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0U                                            /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18U                                            /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17U                                            /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16U                                            /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14U                                            /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13U                                            /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12U                                            /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11U                                            /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10U                                            /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8U                                            /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7U                                            /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3U                                            /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1U                                            /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0U                                            /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16U                                            /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8U                                            /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0U                                            /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31U                                            /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30U                                            /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1U                                            /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4U                                            /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3U                                            /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2U                                            /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1U                                            /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0U                                            /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t ICTR;                   /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register */
+  __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0U                                         /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISOOFP_Pos            9U                                         /*!< ACTLR: DISOOFP Position */
+#define SCnSCB_ACTLR_DISOOFP_Msk           (1UL << SCnSCB_ACTLR_DISOOFP_Pos)           /*!< ACTLR: DISOOFP Mask */
+
+#define SCnSCB_ACTLR_DISFPCA_Pos            8U                                         /*!< ACTLR: DISFPCA Position */
+#define SCnSCB_ACTLR_DISFPCA_Msk           (1UL << SCnSCB_ACTLR_DISFPCA_Pos)           /*!< ACTLR: DISFPCA Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2U                                         /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1U                                         /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0U                                         /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+  \brief    Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __OM  union
+  {
+    __OM  uint8_t    u8;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit */
+    __OM  uint16_t   u16;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit */
+    __OM  uint32_t   u32;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit */
+  }  PORT [32U];                         /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers */
+        uint32_t RESERVED0[864U];
+  __IOM uint32_t TER;                    /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register */
+        uint32_t RESERVED1[15U];
+  __IOM uint32_t TPR;                    /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register */
+        uint32_t RESERVED2[15U];
+  __IOM uint32_t TCR;                    /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register */
+        uint32_t RESERVED3[29U];
+  __OM  uint32_t IWR;                    /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register */
+  __IM  uint32_t IRR;                    /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register */
+  __IOM uint32_t IMCR;                   /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register */
+        uint32_t RESERVED4[43U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register */
+        uint32_t RESERVED5[6U];
+  __IM  uint32_t PID4;                   /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __IM  uint32_t PID5;                   /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __IM  uint32_t PID6;                   /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __IM  uint32_t PID7;                   /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __IM  uint32_t PID0;                   /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __IM  uint32_t PID1;                   /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __IM  uint32_t PID2;                   /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __IM  uint32_t PID3;                   /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __IM  uint32_t CID0;                   /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __IM  uint32_t CID1;                   /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __IM  uint32_t CID2;                   /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __IM  uint32_t CID3;                   /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0U                                            /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23U                                            /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16U                                            /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10U                                            /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8U                                            /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4U                                            /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3U                                            /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2U                                            /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1U                                            /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0U                                            /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0U                                            /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0U                                            /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0U                                            /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2U                                            /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1U                                            /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0U                                            /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+  \brief    Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control Register */
+  __IOM uint32_t CYCCNT;                 /*!< Offset: 0x004 (R/W)  Cycle Count Register */
+  __IOM uint32_t CPICNT;                 /*!< Offset: 0x008 (R/W)  CPI Count Register */
+  __IOM uint32_t EXCCNT;                 /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register */
+  __IOM uint32_t SLEEPCNT;               /*!< Offset: 0x010 (R/W)  Sleep Count Register */
+  __IOM uint32_t LSUCNT;                 /*!< Offset: 0x014 (R/W)  LSU Count Register */
+  __IOM uint32_t FOLDCNT;                /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register */
+  __IM  uint32_t PCSR;                   /*!< Offset: 0x01C (R/ )  Program Counter Sample Register */
+  __IOM uint32_t COMP0;                  /*!< Offset: 0x020 (R/W)  Comparator Register 0 */
+  __IOM uint32_t MASK0;                  /*!< Offset: 0x024 (R/W)  Mask Register 0 */
+  __IOM uint32_t FUNCTION0;              /*!< Offset: 0x028 (R/W)  Function Register 0 */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t COMP1;                  /*!< Offset: 0x030 (R/W)  Comparator Register 1 */
+  __IOM uint32_t MASK1;                  /*!< Offset: 0x034 (R/W)  Mask Register 1 */
+  __IOM uint32_t FUNCTION1;              /*!< Offset: 0x038 (R/W)  Function Register 1 */
+        uint32_t RESERVED1[1U];
+  __IOM uint32_t COMP2;                  /*!< Offset: 0x040 (R/W)  Comparator Register 2 */
+  __IOM uint32_t MASK2;                  /*!< Offset: 0x044 (R/W)  Mask Register 2 */
+  __IOM uint32_t FUNCTION2;              /*!< Offset: 0x048 (R/W)  Function Register 2 */
+        uint32_t RESERVED2[1U];
+  __IOM uint32_t COMP3;                  /*!< Offset: 0x050 (R/W)  Comparator Register 3 */
+  __IOM uint32_t MASK3;                  /*!< Offset: 0x054 (R/W)  Mask Register 3 */
+  __IOM uint32_t FUNCTION3;              /*!< Offset: 0x058 (R/W)  Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28U                                         /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27U                                         /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26U                                         /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25U                                         /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24U                                         /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22U                                         /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21U                                         /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20U                                         /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19U                                         /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18U                                         /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17U                                         /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16U                                         /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12U                                         /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10U                                         /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9U                                         /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5U                                         /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1U                                         /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0U                                         /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0U                                         /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0U                                         /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0U                                         /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0U                                         /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0U                                         /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24U                                         /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16U                                         /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12U                                         /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10U                                         /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9U                                         /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8U                                         /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7U                                         /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5U                                         /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0U                                         /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+  \brief    Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IOM uint32_t SSPSR;                  /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register */
+  __IOM uint32_t CSPSR;                  /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACPR;                   /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+        uint32_t RESERVED1[55U];
+  __IOM uint32_t SPPR;                   /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+        uint32_t RESERVED2[131U];
+  __IM  uint32_t FFSR;                   /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IOM uint32_t FFCR;                   /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __IM  uint32_t FSCR;                   /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+        uint32_t RESERVED3[759U];
+  __IM  uint32_t TRIGGER;                /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __IM  uint32_t FIFO0;                  /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __IM  uint32_t ITATBCTR2;              /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+        uint32_t RESERVED4[1U];
+  __IM  uint32_t ITATBCTR0;              /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __IM  uint32_t FIFO1;                  /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IOM uint32_t ITCTRL;                 /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+        uint32_t RESERVED5[39U];
+  __IOM uint32_t CLAIMSET;               /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IOM uint32_t CLAIMCLR;               /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+        uint32_t RESERVED7[8U];
+  __IM  uint32_t DEVID;                  /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __IM  uint32_t DEVTYPE;                /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0U                                         /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0U                                         /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3U                                         /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2U                                         /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1U                                         /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0U                                         /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8U                                         /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1U                                         /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0U                                         /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16U                                         /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8U                                         /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0U                                         /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16U                                         /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8U                                         /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0U                                         /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0U                                         /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11U                                         /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10U                                         /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9U                                         /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6U                                         /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5U                                         /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0U                                         /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4U                                         /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0U                                         /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A1;                /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register */
+  __IOM uint32_t RASR_A1;                /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A2;                /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register */
+  __IOM uint32_t RASR_A2;                /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A3;                /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register */
+  __IOM uint32_t RASR_A3;                /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_FPU     Floating Point Unit (FPU)
+  \brief    Type definitions for the Floating Point Unit (FPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t FPCCR;                  /*!< Offset: 0x004 (R/W)  Floating-Point Context Control Register */
+  __IOM uint32_t FPCAR;                  /*!< Offset: 0x008 (R/W)  Floating-Point Context Address Register */
+  __IOM uint32_t FPDSCR;                 /*!< Offset: 0x00C (R/W)  Floating-Point Default Status Control Register */
+  __IM  uint32_t MVFR0;                  /*!< Offset: 0x010 (R/ )  Media and FP Feature Register 0 */
+  __IM  uint32_t MVFR1;                  /*!< Offset: 0x014 (R/ )  Media and FP Feature Register 1 */
+} FPU_Type;
+
+/* Floating-Point Context Control Register Definitions */
+#define FPU_FPCCR_ASPEN_Pos                31U                                            /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk                (1UL << FPU_FPCCR_ASPEN_Pos)                   /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos                30U                                            /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk                (1UL << FPU_FPCCR_LSPEN_Pos)                   /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos                8U                                            /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk               (1UL << FPU_FPCCR_MONRDY_Pos)                  /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos                 6U                                            /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk                (1UL << FPU_FPCCR_BFRDY_Pos)                   /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos                 5U                                            /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk                (1UL << FPU_FPCCR_MMRDY_Pos)                   /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos                 4U                                            /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk                (1UL << FPU_FPCCR_HFRDY_Pos)                   /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos                3U                                            /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk               (1UL << FPU_FPCCR_THREAD_Pos)                  /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos                  1U                                            /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk                 (1UL << FPU_FPCCR_USER_Pos)                    /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos                0U                                            /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk               (1UL /*<< FPU_FPCCR_LSPACT_Pos*/)              /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register Definitions */
+#define FPU_FPCAR_ADDRESS_Pos               3U                                            /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk              (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos)        /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register Definitions */
+#define FPU_FPDSCR_AHP_Pos                 26U                                            /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk                 (1UL << FPU_FPDSCR_AHP_Pos)                    /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos                  25U                                            /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk                  (1UL << FPU_FPDSCR_DN_Pos)                     /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos                  24U                                            /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk                  (1UL << FPU_FPDSCR_FZ_Pos)                     /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos               22U                                            /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk               (3UL << FPU_FPDSCR_RMode_Pos)                  /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 Definitions */
+#define FPU_MVFR0_FP_rounding_modes_Pos    28U                                            /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk    (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos)     /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos        24U                                            /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk        (0xFUL << FPU_MVFR0_Short_vectors_Pos)         /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos          20U                                            /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk          (0xFUL << FPU_MVFR0_Square_root_Pos)           /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos               16U                                            /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk               (0xFUL << FPU_MVFR0_Divide_Pos)                /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos    12U                                            /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk    (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos)     /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos      8U                                            /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk     (0xFUL << FPU_MVFR0_Double_precision_Pos)      /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos      4U                                            /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk     (0xFUL << FPU_MVFR0_Single_precision_Pos)      /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos      0U                                            /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk     (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/)  /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 Definitions */
+#define FPU_MVFR1_FP_fused_MAC_Pos         28U                                            /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk         (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos)          /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos              24U                                            /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk              (0xFUL << FPU_MVFR1_FP_HPFP_Pos)               /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos            4U                                            /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk           (0xFUL << FPU_MVFR1_D_NaN_mode_Pos)            /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos              0U                                            /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk             (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/)          /*!< MVFR1: FtZ mode bits Mask */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Type definitions for the Core Debug Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IOM uint32_t DHCSR;                  /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register */
+  __OM  uint32_t DCRSR;                  /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register */
+  __IOM uint32_t DCRDR;                  /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register */
+  __IOM uint32_t DEMCR;                  /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16U                                            /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25U                                            /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24U                                            /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19U                                            /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18U                                            /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17U                                            /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16U                                            /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5U                                            /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3U                                            /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2U                                            /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1U                                            /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0U                                            /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos         16U                                            /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0U                                            /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19U                                            /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18U                                            /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17U                                            /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16U                                            /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10U                                            /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9U                                            /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8U                                            /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7U                                            /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6U                                            /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5U                                            /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4U                                            /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0U                                            /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+#if (__FPU_PRESENT == 1U)
+  #define FPU_BASE          (SCS_BASE +  0x0F30UL)                    /*!< Floating Point Unit */
+  #define FPU               ((FPU_Type       *)     FPU_BASE      )   /*!< Floating Point Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/**
+  \brief   Set Priority Grouping
+  \details Sets the priority grouping field using the required unlock sequence.
+           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+           Only values from 0..7 are used.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8U)                      );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/**
+  \brief   Get Priority Grouping
+  \details Reads the priority grouping field from the NVIC Interrupt Controller.
+  \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Active Interrupt
+  \details Reads the active register in NVIC and returns the active bit.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else
+  {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]               >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   Encode Priority
+  \details Encodes the priority for an interrupt with the given priority group,
+           preemptive priority value, and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]     PriorityGroup  Used priority group.
+  \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+  \param [in]       SubPriority  Subpriority value (starting from 0).
+  \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/**
+  \brief   Decode Priority
+  \details Decodes an interrupt priority value with a given priority group to
+           preemptive priority value and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+  \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+  \param [in]     PriorityGroup  Used priority group.
+  \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+  \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_core_DebugFunctions ITM Functions
+  \brief    Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters. */
+#define                 ITM_RXBUFFER_EMPTY   0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+  \brief   ITM Send Character
+  \details Transmits a character via the ITM channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0U].u32 == 0UL)
+    {
+      __NOP();
+    }
+    ITM->PORT[0U].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Receive Character
+  \details Inputs a character via the external variable \ref ITM_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+  {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Check Character
+  \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+  {
+    return (0);                              /* no character available */
+  }
+  else
+  {
+    return (1);                              /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm7.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm7.h
new file mode 100755
index 0000000..3b7530a
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cm7.h
@@ -0,0 +1,2512 @@
+/**************************************************************************//**
+ * @file     core_cm7.h
+ * @brief    CMSIS Cortex-M7 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM7_H_GENERIC
+#define __CORE_CM7_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup Cortex_M7
+  @{
+ */
+
+/*  CMSIS CM7 definitions */
+#define __CM7_CMSIS_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CMSIS HAL main version */
+#define __CM7_CMSIS_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CMSIS HAL sub version */
+#define __CM7_CMSIS_VERSION       ((__CM7_CMSIS_VERSION_MAIN << 16U) | \
+                                    __CM7_CMSIS_VERSION_SUB           )        /*!< CMSIS HAL version number */
+
+#define __CORTEX_M                (0x07U)                                      /*!< Cortex-M Core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1U
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #if (__FPU_PRESENT == 1U)
+      #define __FPU_USED       1U
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0U
+    #endif
+  #else
+    #define __FPU_USED         0U
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+#include "core_cmSimd.h"                 /* Compiler specific SIMD Intrinsics */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM7_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM7_H_DEPENDANT
+#define __CORE_CM7_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM7_REV
+    #define __CM7_REV               0x0000U
+    #warning "__CM7_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __FPU_PRESENT
+    #define __FPU_PRESENT             0U
+    #warning "__FPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __ICACHE_PRESENT
+    #define __ICACHE_PRESENT          0U
+    #warning "__ICACHE_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __DCACHE_PRESENT
+    #define __DCACHE_PRESENT          0U
+    #warning "__DCACHE_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __DTCM_PRESENT
+    #define __DTCM_PRESENT            0U
+    #warning "__DTCM_PRESENT        not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          3U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M7 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+  - Core FPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27U                                            /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+#define APSR_GE_Pos                        16U                                            /*!< APSR: GE Position */
+#define APSR_GE_Msk                        (0xFUL << APSR_GE_Pos)                         /*!< APSR: GE Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0) */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27U                                            /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25U                                            /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_GE_Pos                        16U                                            /*!< xPSR: GE Position */
+#define xPSR_GE_Msk                        (0xFUL << xPSR_GE_Pos)                         /*!< xPSR: GE Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_FPCA_Pos                    2U                                            /*!< CONTROL: FPCA Position */
+#define CONTROL_FPCA_Msk                   (1UL << CONTROL_FPCA_Pos)                      /*!< CONTROL: FPCA Mask */
+
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[24U];
+  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[24U];
+  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[24U];
+  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[24U];
+  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
+        uint32_t RESERVED4[56U];
+  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+        uint32_t RESERVED5[644U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0U                                         /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+  __IOM uint8_t  SHPR[12U];              /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
+  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
+  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
+  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
+  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
+  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
+  __IM  uint32_t ID_PFR[2U];             /*!< Offset: 0x040 (R/ )  Processor Feature Register */
+  __IM  uint32_t ID_DFR;                 /*!< Offset: 0x048 (R/ )  Debug Feature Register */
+  __IM  uint32_t ID_AFR;                 /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
+  __IM  uint32_t ID_MFR[4U];             /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
+  __IM  uint32_t ID_ISAR[5U];            /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t CLIDR;                  /*!< Offset: 0x078 (R/ )  Cache Level ID register */
+  __IM  uint32_t CTR;                    /*!< Offset: 0x07C (R/ )  Cache Type register */
+  __IM  uint32_t CCSIDR;                 /*!< Offset: 0x080 (R/ )  Cache Size ID Register */
+  __IOM uint32_t CSSELR;                 /*!< Offset: 0x084 (R/W)  Cache Size Selection Register */
+  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
+        uint32_t RESERVED3[93U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0x200 ( /W)  Software Triggered Interrupt Register */
+        uint32_t RESERVED4[15U];
+  __IM  uint32_t MVFR0;                  /*!< Offset: 0x240 (R/ )  Media and VFP Feature Register 0 */
+  __IM  uint32_t MVFR1;                  /*!< Offset: 0x244 (R/ )  Media and VFP Feature Register 1 */
+  __IM  uint32_t MVFR2;                  /*!< Offset: 0x248 (R/ )  Media and VFP Feature Register 1 */
+        uint32_t RESERVED5[1U];
+  __OM  uint32_t ICIALLU;                /*!< Offset: 0x250 ( /W)  I-Cache Invalidate All to PoU */
+        uint32_t RESERVED6[1U];
+  __OM  uint32_t ICIMVAU;                /*!< Offset: 0x258 ( /W)  I-Cache Invalidate by MVA to PoU */
+  __OM  uint32_t DCIMVAC;                /*!< Offset: 0x25C ( /W)  D-Cache Invalidate by MVA to PoC */
+  __OM  uint32_t DCISW;                  /*!< Offset: 0x260 ( /W)  D-Cache Invalidate by Set-way */
+  __OM  uint32_t DCCMVAU;                /*!< Offset: 0x264 ( /W)  D-Cache Clean by MVA to PoU */
+  __OM  uint32_t DCCMVAC;                /*!< Offset: 0x268 ( /W)  D-Cache Clean by MVA to PoC */
+  __OM  uint32_t DCCSW;                  /*!< Offset: 0x26C ( /W)  D-Cache Clean by Set-way */
+  __OM  uint32_t DCCIMVAC;               /*!< Offset: 0x270 ( /W)  D-Cache Clean and Invalidate by MVA to PoC */
+  __OM  uint32_t DCCISW;                 /*!< Offset: 0x274 ( /W)  D-Cache Clean and Invalidate by Set-way */
+        uint32_t RESERVED7[6U];
+  __IOM uint32_t ITCMCR;                 /*!< Offset: 0x290 (R/W)  Instruction Tightly-Coupled Memory Control Register */
+  __IOM uint32_t DTCMCR;                 /*!< Offset: 0x294 (R/W)  Data Tightly-Coupled Memory Control Registers */
+  __IOM uint32_t AHBPCR;                 /*!< Offset: 0x298 (R/W)  AHBP Control Register */
+  __IOM uint32_t CACR;                   /*!< Offset: 0x29C (R/W)  L1 Cache Control Register */
+  __IOM uint32_t AHBSCR;                 /*!< Offset: 0x2A0 (R/W)  AHB Slave Control Register */
+        uint32_t RESERVED8[1U];
+  __IOM uint32_t ABFSR;                  /*!< Offset: 0x2A8 (R/W)  Auxiliary Bus Fault Status Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11U                                            /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8U                                            /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0U                                            /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_BP_Pos                      18U                                           /*!< SCB CCR: Branch prediction enable bit Position */
+#define SCB_CCR_BP_Msk                     (1UL << SCB_CCR_BP_Pos)                        /*!< SCB CCR: Branch prediction enable bit Mask */
+
+#define SCB_CCR_IC_Pos                      17U                                           /*!< SCB CCR: Instruction cache enable bit Position */
+#define SCB_CCR_IC_Msk                     (1UL << SCB_CCR_IC_Pos)                        /*!< SCB CCR: Instruction cache enable bit Mask */
+
+#define SCB_CCR_DC_Pos                      16U                                           /*!< SCB CCR: Cache enable bit Position */
+#define SCB_CCR_DC_Msk                     (1UL << SCB_CCR_DC_Pos)                        /*!< SCB CCR: Cache enable bit Mask */
+
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8U                                            /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4U                                            /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1U                                            /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0U                                            /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18U                                            /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17U                                            /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16U                                            /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14U                                            /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13U                                            /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12U                                            /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11U                                            /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10U                                            /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8U                                            /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7U                                            /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3U                                            /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1U                                            /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0U                                            /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16U                                            /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8U                                            /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0U                                            /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31U                                            /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30U                                            /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1U                                            /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4U                                            /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3U                                            /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2U                                            /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1U                                            /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0U                                            /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/* SCB Cache Level ID Register Definitions */
+#define SCB_CLIDR_LOUU_Pos                 27U                                            /*!< SCB CLIDR: LoUU Position */
+#define SCB_CLIDR_LOUU_Msk                 (7UL << SCB_CLIDR_LOUU_Pos)                    /*!< SCB CLIDR: LoUU Mask */
+
+#define SCB_CLIDR_LOC_Pos                  24U                                            /*!< SCB CLIDR: LoC Position */
+#define SCB_CLIDR_LOC_Msk                  (7UL << SCB_CLIDR_LOC_Pos)                     /*!< SCB CLIDR: LoC Mask */
+
+/* SCB Cache Type Register Definitions */
+#define SCB_CTR_FORMAT_Pos                 29U                                            /*!< SCB CTR: Format Position */
+#define SCB_CTR_FORMAT_Msk                 (7UL << SCB_CTR_FORMAT_Pos)                    /*!< SCB CTR: Format Mask */
+
+#define SCB_CTR_CWG_Pos                    24U                                            /*!< SCB CTR: CWG Position */
+#define SCB_CTR_CWG_Msk                    (0xFUL << SCB_CTR_CWG_Pos)                     /*!< SCB CTR: CWG Mask */
+
+#define SCB_CTR_ERG_Pos                    20U                                            /*!< SCB CTR: ERG Position */
+#define SCB_CTR_ERG_Msk                    (0xFUL << SCB_CTR_ERG_Pos)                     /*!< SCB CTR: ERG Mask */
+
+#define SCB_CTR_DMINLINE_Pos               16U                                            /*!< SCB CTR: DminLine Position */
+#define SCB_CTR_DMINLINE_Msk               (0xFUL << SCB_CTR_DMINLINE_Pos)                /*!< SCB CTR: DminLine Mask */
+
+#define SCB_CTR_IMINLINE_Pos                0U                                            /*!< SCB CTR: ImInLine Position */
+#define SCB_CTR_IMINLINE_Msk               (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/)            /*!< SCB CTR: ImInLine Mask */
+
+/* SCB Cache Size ID Register Definitions */
+#define SCB_CCSIDR_WT_Pos                  31U                                            /*!< SCB CCSIDR: WT Position */
+#define SCB_CCSIDR_WT_Msk                  (1UL << SCB_CCSIDR_WT_Pos)                     /*!< SCB CCSIDR: WT Mask */
+
+#define SCB_CCSIDR_WB_Pos                  30U                                            /*!< SCB CCSIDR: WB Position */
+#define SCB_CCSIDR_WB_Msk                  (1UL << SCB_CCSIDR_WB_Pos)                     /*!< SCB CCSIDR: WB Mask */
+
+#define SCB_CCSIDR_RA_Pos                  29U                                            /*!< SCB CCSIDR: RA Position */
+#define SCB_CCSIDR_RA_Msk                  (1UL << SCB_CCSIDR_RA_Pos)                     /*!< SCB CCSIDR: RA Mask */
+
+#define SCB_CCSIDR_WA_Pos                  28U                                            /*!< SCB CCSIDR: WA Position */
+#define SCB_CCSIDR_WA_Msk                  (1UL << SCB_CCSIDR_WA_Pos)                     /*!< SCB CCSIDR: WA Mask */
+
+#define SCB_CCSIDR_NUMSETS_Pos             13U                                            /*!< SCB CCSIDR: NumSets Position */
+#define SCB_CCSIDR_NUMSETS_Msk             (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos)           /*!< SCB CCSIDR: NumSets Mask */
+
+#define SCB_CCSIDR_ASSOCIATIVITY_Pos        3U                                            /*!< SCB CCSIDR: Associativity Position */
+#define SCB_CCSIDR_ASSOCIATIVITY_Msk       (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos)      /*!< SCB CCSIDR: Associativity Mask */
+
+#define SCB_CCSIDR_LINESIZE_Pos             0U                                            /*!< SCB CCSIDR: LineSize Position */
+#define SCB_CCSIDR_LINESIZE_Msk            (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/)           /*!< SCB CCSIDR: LineSize Mask */
+
+/* SCB Cache Size Selection Register Definitions */
+#define SCB_CSSELR_LEVEL_Pos                1U                                            /*!< SCB CSSELR: Level Position */
+#define SCB_CSSELR_LEVEL_Msk               (7UL << SCB_CSSELR_LEVEL_Pos)                  /*!< SCB CSSELR: Level Mask */
+
+#define SCB_CSSELR_IND_Pos                  0U                                            /*!< SCB CSSELR: InD Position */
+#define SCB_CSSELR_IND_Msk                 (1UL /*<< SCB_CSSELR_IND_Pos*/)                /*!< SCB CSSELR: InD Mask */
+
+/* SCB Software Triggered Interrupt Register Definitions */
+#define SCB_STIR_INTID_Pos                  0U                                            /*!< SCB STIR: INTID Position */
+#define SCB_STIR_INTID_Msk                 (0x1FFUL /*<< SCB_STIR_INTID_Pos*/)            /*!< SCB STIR: INTID Mask */
+
+/* SCB D-Cache Invalidate by Set-way Register Definitions */
+#define SCB_DCISW_WAY_Pos                  30U                                            /*!< SCB DCISW: Way Position */
+#define SCB_DCISW_WAY_Msk                  (3UL << SCB_DCISW_WAY_Pos)                     /*!< SCB DCISW: Way Mask */
+
+#define SCB_DCISW_SET_Pos                   5U                                            /*!< SCB DCISW: Set Position */
+#define SCB_DCISW_SET_Msk                  (0x1FFUL << SCB_DCISW_SET_Pos)                 /*!< SCB DCISW: Set Mask */
+
+/* SCB D-Cache Clean by Set-way Register Definitions */
+#define SCB_DCCSW_WAY_Pos                  30U                                            /*!< SCB DCCSW: Way Position */
+#define SCB_DCCSW_WAY_Msk                  (3UL << SCB_DCCSW_WAY_Pos)                     /*!< SCB DCCSW: Way Mask */
+
+#define SCB_DCCSW_SET_Pos                   5U                                            /*!< SCB DCCSW: Set Position */
+#define SCB_DCCSW_SET_Msk                  (0x1FFUL << SCB_DCCSW_SET_Pos)                 /*!< SCB DCCSW: Set Mask */
+
+/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */
+#define SCB_DCCISW_WAY_Pos                 30U                                            /*!< SCB DCCISW: Way Position */
+#define SCB_DCCISW_WAY_Msk                 (3UL << SCB_DCCISW_WAY_Pos)                    /*!< SCB DCCISW: Way Mask */
+
+#define SCB_DCCISW_SET_Pos                  5U                                            /*!< SCB DCCISW: Set Position */
+#define SCB_DCCISW_SET_Msk                 (0x1FFUL << SCB_DCCISW_SET_Pos)                /*!< SCB DCCISW: Set Mask */
+
+/* Instruction Tightly-Coupled Memory Control Register Definitions */
+#define SCB_ITCMCR_SZ_Pos                   3U                                            /*!< SCB ITCMCR: SZ Position */
+#define SCB_ITCMCR_SZ_Msk                  (0xFUL << SCB_ITCMCR_SZ_Pos)                   /*!< SCB ITCMCR: SZ Mask */
+
+#define SCB_ITCMCR_RETEN_Pos                2U                                            /*!< SCB ITCMCR: RETEN Position */
+#define SCB_ITCMCR_RETEN_Msk               (1UL << SCB_ITCMCR_RETEN_Pos)                  /*!< SCB ITCMCR: RETEN Mask */
+
+#define SCB_ITCMCR_RMW_Pos                  1U                                            /*!< SCB ITCMCR: RMW Position */
+#define SCB_ITCMCR_RMW_Msk                 (1UL << SCB_ITCMCR_RMW_Pos)                    /*!< SCB ITCMCR: RMW Mask */
+
+#define SCB_ITCMCR_EN_Pos                   0U                                            /*!< SCB ITCMCR: EN Position */
+#define SCB_ITCMCR_EN_Msk                  (1UL /*<< SCB_ITCMCR_EN_Pos*/)                 /*!< SCB ITCMCR: EN Mask */
+
+/* Data Tightly-Coupled Memory Control Register Definitions */
+#define SCB_DTCMCR_SZ_Pos                   3U                                            /*!< SCB DTCMCR: SZ Position */
+#define SCB_DTCMCR_SZ_Msk                  (0xFUL << SCB_DTCMCR_SZ_Pos)                   /*!< SCB DTCMCR: SZ Mask */
+
+#define SCB_DTCMCR_RETEN_Pos                2U                                            /*!< SCB DTCMCR: RETEN Position */
+#define SCB_DTCMCR_RETEN_Msk               (1UL << SCB_DTCMCR_RETEN_Pos)                   /*!< SCB DTCMCR: RETEN Mask */
+
+#define SCB_DTCMCR_RMW_Pos                  1U                                            /*!< SCB DTCMCR: RMW Position */
+#define SCB_DTCMCR_RMW_Msk                 (1UL << SCB_DTCMCR_RMW_Pos)                    /*!< SCB DTCMCR: RMW Mask */
+
+#define SCB_DTCMCR_EN_Pos                   0U                                            /*!< SCB DTCMCR: EN Position */
+#define SCB_DTCMCR_EN_Msk                  (1UL /*<< SCB_DTCMCR_EN_Pos*/)                 /*!< SCB DTCMCR: EN Mask */
+
+/* AHBP Control Register Definitions */
+#define SCB_AHBPCR_SZ_Pos                   1U                                            /*!< SCB AHBPCR: SZ Position */
+#define SCB_AHBPCR_SZ_Msk                  (7UL << SCB_AHBPCR_SZ_Pos)                     /*!< SCB AHBPCR: SZ Mask */
+
+#define SCB_AHBPCR_EN_Pos                   0U                                            /*!< SCB AHBPCR: EN Position */
+#define SCB_AHBPCR_EN_Msk                  (1UL /*<< SCB_AHBPCR_EN_Pos*/)                 /*!< SCB AHBPCR: EN Mask */
+
+/* L1 Cache Control Register Definitions */
+#define SCB_CACR_FORCEWT_Pos                2U                                            /*!< SCB CACR: FORCEWT Position */
+#define SCB_CACR_FORCEWT_Msk               (1UL << SCB_CACR_FORCEWT_Pos)                  /*!< SCB CACR: FORCEWT Mask */
+
+#define SCB_CACR_ECCEN_Pos                  1U                                            /*!< SCB CACR: ECCEN Position */
+#define SCB_CACR_ECCEN_Msk                 (1UL << SCB_CACR_ECCEN_Pos)                    /*!< SCB CACR: ECCEN Mask */
+
+#define SCB_CACR_SIWT_Pos                   0U                                            /*!< SCB CACR: SIWT Position */
+#define SCB_CACR_SIWT_Msk                  (1UL /*<< SCB_CACR_SIWT_Pos*/)                 /*!< SCB CACR: SIWT Mask */
+
+/* AHBS Control Register Definitions */
+#define SCB_AHBSCR_INITCOUNT_Pos           11U                                            /*!< SCB AHBSCR: INITCOUNT Position */
+#define SCB_AHBSCR_INITCOUNT_Msk           (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos)           /*!< SCB AHBSCR: INITCOUNT Mask */
+
+#define SCB_AHBSCR_TPRI_Pos                 2U                                            /*!< SCB AHBSCR: TPRI Position */
+#define SCB_AHBSCR_TPRI_Msk                (0x1FFUL << SCB_AHBPCR_TPRI_Pos)               /*!< SCB AHBSCR: TPRI Mask */
+
+#define SCB_AHBSCR_CTL_Pos                  0U                                            /*!< SCB AHBSCR: CTL Position*/
+#define SCB_AHBSCR_CTL_Msk                 (3UL /*<< SCB_AHBPCR_CTL_Pos*/)                /*!< SCB AHBSCR: CTL Mask */
+
+/* Auxiliary Bus Fault Status Register Definitions */
+#define SCB_ABFSR_AXIMTYPE_Pos              8U                                            /*!< SCB ABFSR: AXIMTYPE Position*/
+#define SCB_ABFSR_AXIMTYPE_Msk             (3UL << SCB_ABFSR_AXIMTYPE_Pos)                /*!< SCB ABFSR: AXIMTYPE Mask */
+
+#define SCB_ABFSR_EPPB_Pos                  4U                                            /*!< SCB ABFSR: EPPB Position*/
+#define SCB_ABFSR_EPPB_Msk                 (1UL << SCB_ABFSR_EPPB_Pos)                    /*!< SCB ABFSR: EPPB Mask */
+
+#define SCB_ABFSR_AXIM_Pos                  3U                                            /*!< SCB ABFSR: AXIM Position*/
+#define SCB_ABFSR_AXIM_Msk                 (1UL << SCB_ABFSR_AXIM_Pos)                    /*!< SCB ABFSR: AXIM Mask */
+
+#define SCB_ABFSR_AHBP_Pos                  2U                                            /*!< SCB ABFSR: AHBP Position*/
+#define SCB_ABFSR_AHBP_Msk                 (1UL << SCB_ABFSR_AHBP_Pos)                    /*!< SCB ABFSR: AHBP Mask */
+
+#define SCB_ABFSR_DTCM_Pos                  1U                                            /*!< SCB ABFSR: DTCM Position*/
+#define SCB_ABFSR_DTCM_Msk                 (1UL << SCB_ABFSR_DTCM_Pos)                    /*!< SCB ABFSR: DTCM Mask */
+
+#define SCB_ABFSR_ITCM_Pos                  0U                                            /*!< SCB ABFSR: ITCM Position*/
+#define SCB_ABFSR_ITCM_Msk                 (1UL /*<< SCB_ABFSR_ITCM_Pos*/)                /*!< SCB ABFSR: ITCM Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t ICTR;                   /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register */
+  __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0U                                         /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos    12U                                         /*!< ACTLR: DISITMATBFLUSH Position */
+#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk    (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos)    /*!< ACTLR: DISITMATBFLUSH Mask */
+
+#define SCnSCB_ACTLR_DISRAMODE_Pos         11U                                         /*!< ACTLR: DISRAMODE Position */
+#define SCnSCB_ACTLR_DISRAMODE_Msk         (1UL << SCnSCB_ACTLR_DISRAMODE_Pos)         /*!< ACTLR: DISRAMODE Mask */
+
+#define SCnSCB_ACTLR_FPEXCODIS_Pos         10U                                         /*!< ACTLR: FPEXCODIS Position */
+#define SCnSCB_ACTLR_FPEXCODIS_Msk         (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos)         /*!< ACTLR: FPEXCODIS Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2U                                         /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0U                                         /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+  \brief    Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __OM  union
+  {
+    __OM  uint8_t    u8;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit */
+    __OM  uint16_t   u16;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit */
+    __OM  uint32_t   u32;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit */
+  }  PORT [32U];                         /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers */
+        uint32_t RESERVED0[864U];
+  __IOM uint32_t TER;                    /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register */
+        uint32_t RESERVED1[15U];
+  __IOM uint32_t TPR;                    /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register */
+        uint32_t RESERVED2[15U];
+  __IOM uint32_t TCR;                    /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register */
+        uint32_t RESERVED3[29U];
+  __OM  uint32_t IWR;                    /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register */
+  __IM  uint32_t IRR;                    /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register */
+  __IOM uint32_t IMCR;                   /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register */
+        uint32_t RESERVED4[43U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register */
+        uint32_t RESERVED5[6U];
+  __IM  uint32_t PID4;                   /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __IM  uint32_t PID5;                   /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __IM  uint32_t PID6;                   /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __IM  uint32_t PID7;                   /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __IM  uint32_t PID0;                   /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __IM  uint32_t PID1;                   /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __IM  uint32_t PID2;                   /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __IM  uint32_t PID3;                   /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __IM  uint32_t CID0;                   /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __IM  uint32_t CID1;                   /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __IM  uint32_t CID2;                   /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __IM  uint32_t CID3;                   /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0U                                            /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23U                                            /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16U                                            /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10U                                            /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8U                                            /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4U                                            /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3U                                            /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2U                                            /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1U                                            /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0U                                            /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0U                                            /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0U                                            /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0U                                            /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2U                                            /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1U                                            /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0U                                            /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+  \brief    Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control Register */
+  __IOM uint32_t CYCCNT;                 /*!< Offset: 0x004 (R/W)  Cycle Count Register */
+  __IOM uint32_t CPICNT;                 /*!< Offset: 0x008 (R/W)  CPI Count Register */
+  __IOM uint32_t EXCCNT;                 /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register */
+  __IOM uint32_t SLEEPCNT;               /*!< Offset: 0x010 (R/W)  Sleep Count Register */
+  __IOM uint32_t LSUCNT;                 /*!< Offset: 0x014 (R/W)  LSU Count Register */
+  __IOM uint32_t FOLDCNT;                /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register */
+  __IM  uint32_t PCSR;                   /*!< Offset: 0x01C (R/ )  Program Counter Sample Register */
+  __IOM uint32_t COMP0;                  /*!< Offset: 0x020 (R/W)  Comparator Register 0 */
+  __IOM uint32_t MASK0;                  /*!< Offset: 0x024 (R/W)  Mask Register 0 */
+  __IOM uint32_t FUNCTION0;              /*!< Offset: 0x028 (R/W)  Function Register 0 */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t COMP1;                  /*!< Offset: 0x030 (R/W)  Comparator Register 1 */
+  __IOM uint32_t MASK1;                  /*!< Offset: 0x034 (R/W)  Mask Register 1 */
+  __IOM uint32_t FUNCTION1;              /*!< Offset: 0x038 (R/W)  Function Register 1 */
+        uint32_t RESERVED1[1U];
+  __IOM uint32_t COMP2;                  /*!< Offset: 0x040 (R/W)  Comparator Register 2 */
+  __IOM uint32_t MASK2;                  /*!< Offset: 0x044 (R/W)  Mask Register 2 */
+  __IOM uint32_t FUNCTION2;              /*!< Offset: 0x048 (R/W)  Function Register 2 */
+        uint32_t RESERVED2[1U];
+  __IOM uint32_t COMP3;                  /*!< Offset: 0x050 (R/W)  Comparator Register 3 */
+  __IOM uint32_t MASK3;                  /*!< Offset: 0x054 (R/W)  Mask Register 3 */
+  __IOM uint32_t FUNCTION3;              /*!< Offset: 0x058 (R/W)  Function Register 3 */
+        uint32_t RESERVED3[981U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 (  W)  Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R  )  Lock Status Register */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28U                                         /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27U                                         /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26U                                         /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25U                                         /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24U                                         /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22U                                         /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21U                                         /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20U                                         /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19U                                         /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18U                                         /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17U                                         /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16U                                         /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12U                                         /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10U                                         /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9U                                         /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5U                                         /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1U                                         /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0U                                         /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0U                                         /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0U                                         /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0U                                         /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0U                                         /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0U                                         /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24U                                         /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16U                                         /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12U                                         /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10U                                         /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9U                                         /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8U                                         /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7U                                         /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5U                                         /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0U                                         /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+  \brief    Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IOM uint32_t SSPSR;                  /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register */
+  __IOM uint32_t CSPSR;                  /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACPR;                   /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+        uint32_t RESERVED1[55U];
+  __IOM uint32_t SPPR;                   /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+        uint32_t RESERVED2[131U];
+  __IM  uint32_t FFSR;                   /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IOM uint32_t FFCR;                   /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __IM  uint32_t FSCR;                   /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+        uint32_t RESERVED3[759U];
+  __IM  uint32_t TRIGGER;                /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __IM  uint32_t FIFO0;                  /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __IM  uint32_t ITATBCTR2;              /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+        uint32_t RESERVED4[1U];
+  __IM  uint32_t ITATBCTR0;              /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __IM  uint32_t FIFO1;                  /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IOM uint32_t ITCTRL;                 /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+        uint32_t RESERVED5[39U];
+  __IOM uint32_t CLAIMSET;               /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IOM uint32_t CLAIMCLR;               /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+        uint32_t RESERVED7[8U];
+  __IM  uint32_t DEVID;                  /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __IM  uint32_t DEVTYPE;                /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0U                                         /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0U                                         /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3U                                         /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2U                                         /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1U                                         /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0U                                         /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8U                                         /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1U                                         /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0U                                         /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16U                                         /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8U                                         /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0U                                         /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16U                                         /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8U                                         /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0U                                         /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0U                                         /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11U                                         /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10U                                         /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9U                                         /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6U                                         /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5U                                         /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0U                                         /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4U                                         /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0U                                         /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A1;                /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register */
+  __IOM uint32_t RASR_A1;                /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A2;                /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register */
+  __IOM uint32_t RASR_A2;                /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A3;                /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register */
+  __IOM uint32_t RASR_A3;                /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_FPU     Floating Point Unit (FPU)
+  \brief    Type definitions for the Floating Point Unit (FPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t FPCCR;                  /*!< Offset: 0x004 (R/W)  Floating-Point Context Control Register */
+  __IOM uint32_t FPCAR;                  /*!< Offset: 0x008 (R/W)  Floating-Point Context Address Register */
+  __IOM uint32_t FPDSCR;                 /*!< Offset: 0x00C (R/W)  Floating-Point Default Status Control Register */
+  __IM  uint32_t MVFR0;                  /*!< Offset: 0x010 (R/ )  Media and FP Feature Register 0 */
+  __IM  uint32_t MVFR1;                  /*!< Offset: 0x014 (R/ )  Media and FP Feature Register 1 */
+  __IM  uint32_t MVFR2;                  /*!< Offset: 0x018 (R/ )  Media and FP Feature Register 2 */
+} FPU_Type;
+
+/* Floating-Point Context Control Register Definitions */
+#define FPU_FPCCR_ASPEN_Pos                31U                                            /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk                (1UL << FPU_FPCCR_ASPEN_Pos)                   /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos                30U                                            /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk                (1UL << FPU_FPCCR_LSPEN_Pos)                   /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos                8U                                            /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk               (1UL << FPU_FPCCR_MONRDY_Pos)                  /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos                 6U                                            /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk                (1UL << FPU_FPCCR_BFRDY_Pos)                   /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos                 5U                                            /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk                (1UL << FPU_FPCCR_MMRDY_Pos)                   /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos                 4U                                            /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk                (1UL << FPU_FPCCR_HFRDY_Pos)                   /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos                3U                                            /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk               (1UL << FPU_FPCCR_THREAD_Pos)                  /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos                  1U                                            /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk                 (1UL << FPU_FPCCR_USER_Pos)                    /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos                0U                                            /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk               (1UL /*<< FPU_FPCCR_LSPACT_Pos*/)              /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register Definitions */
+#define FPU_FPCAR_ADDRESS_Pos               3U                                            /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk              (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos)        /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register Definitions */
+#define FPU_FPDSCR_AHP_Pos                 26U                                            /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk                 (1UL << FPU_FPDSCR_AHP_Pos)                    /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos                  25U                                            /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk                  (1UL << FPU_FPDSCR_DN_Pos)                     /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos                  24U                                            /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk                  (1UL << FPU_FPDSCR_FZ_Pos)                     /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos               22U                                            /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk               (3UL << FPU_FPDSCR_RMode_Pos)                  /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 Definitions */
+#define FPU_MVFR0_FP_rounding_modes_Pos    28U                                            /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk    (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos)     /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos        24U                                            /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk        (0xFUL << FPU_MVFR0_Short_vectors_Pos)         /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos          20U                                            /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk          (0xFUL << FPU_MVFR0_Square_root_Pos)           /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos               16U                                            /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk               (0xFUL << FPU_MVFR0_Divide_Pos)                /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos    12U                                            /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk    (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos)     /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos      8U                                            /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk     (0xFUL << FPU_MVFR0_Double_precision_Pos)      /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos      4U                                            /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk     (0xFUL << FPU_MVFR0_Single_precision_Pos)      /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos      0U                                            /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk     (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/)  /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 Definitions */
+#define FPU_MVFR1_FP_fused_MAC_Pos         28U                                            /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk         (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos)          /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos              24U                                            /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk              (0xFUL << FPU_MVFR1_FP_HPFP_Pos)               /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos            4U                                            /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk           (0xFUL << FPU_MVFR1_D_NaN_mode_Pos)            /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos              0U                                            /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk             (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/)          /*!< MVFR1: FtZ mode bits Mask */
+
+/* Media and FP Feature Register 2 Definitions */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Type definitions for the Core Debug Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IOM uint32_t DHCSR;                  /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register */
+  __OM  uint32_t DCRSR;                  /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register */
+  __IOM uint32_t DCRDR;                  /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register */
+  __IOM uint32_t DEMCR;                  /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16U                                            /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25U                                            /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24U                                            /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19U                                            /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18U                                            /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17U                                            /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16U                                            /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5U                                            /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3U                                            /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2U                                            /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1U                                            /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0U                                            /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos         16U                                            /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0U                                            /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19U                                            /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18U                                            /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17U                                            /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16U                                            /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10U                                            /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9U                                            /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8U                                            /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7U                                            /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6U                                            /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5U                                            /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4U                                            /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0U                                            /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+#if (__FPU_PRESENT == 1U)
+  #define FPU_BASE          (SCS_BASE +  0x0F30UL)                    /*!< Floating Point Unit */
+  #define FPU               ((FPU_Type       *)     FPU_BASE      )   /*!< Floating Point Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/**
+  \brief   Set Priority Grouping
+  \details Sets the priority grouping field using the required unlock sequence.
+           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+           Only values from 0..7 are used.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8U)                      );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/**
+  \brief   Get Priority Grouping
+  \details Reads the priority grouping field from the NVIC Interrupt Controller.
+  \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Active Interrupt
+  \details Reads the active register in NVIC and returns the active bit.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else
+  {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]                = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]                >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   Encode Priority
+  \details Encodes the priority for an interrupt with the given priority group,
+           preemptive priority value, and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]     PriorityGroup  Used priority group.
+  \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+  \param [in]       SubPriority  Subpriority value (starting from 0).
+  \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/**
+  \brief   Decode Priority
+  \details Decodes an interrupt priority value with a given priority group to
+           preemptive priority value and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+  \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+  \param [in]     PriorityGroup  Used priority group.
+  \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+  \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+/* ##########################  FPU functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_FpuFunctions FPU Functions
+  \brief    Function that provides FPU type.
+  @{
+ */
+
+/**
+  \brief   get FPU type
+  \details returns the FPU type
+  \returns
+   - \b  0: No FPU
+   - \b  1: Single precision FPU
+   - \b  2: Double + Single precision FPU
+ */
+__STATIC_INLINE uint32_t SCB_GetFPUType(void)
+{
+  uint32_t mvfr0;
+
+  mvfr0 = SCB->MVFR0;
+  if        ((mvfr0 & 0x00000FF0UL) == 0x220UL)
+  {
+    return 2UL;           /* Double + Single precision FPU */
+  }
+  else if ((mvfr0 & 0x00000FF0UL) == 0x020UL)
+  {
+    return 1UL;           /* Single precision FPU */
+  }
+  else
+  {
+    return 0UL;           /* No FPU */
+  }
+}
+
+
+/*@} end of CMSIS_Core_FpuFunctions */
+
+
+
+/* ##########################  Cache functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_CacheFunctions Cache Functions
+  \brief    Functions that configure Instruction and Data cache.
+  @{
+ */
+
+/* Cache Size ID Register Macros */
+#define CCSIDR_WAYS(x)         (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
+#define CCSIDR_SETS(x)         (((x) & SCB_CCSIDR_NUMSETS_Msk      ) >> SCB_CCSIDR_NUMSETS_Pos      )
+
+
+/**
+  \brief   Enable I-Cache
+  \details Turns on I-Cache
+  */
+__STATIC_INLINE void SCB_EnableICache (void)
+{
+  #if (__ICACHE_PRESENT == 1U)
+    __DSB();
+    __ISB();
+    SCB->ICIALLU = 0UL;                     /* invalidate I-Cache */
+    SCB->CCR |=  (uint32_t)SCB_CCR_IC_Msk;  /* enable I-Cache */
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Disable I-Cache
+  \details Turns off I-Cache
+  */
+__STATIC_INLINE void SCB_DisableICache (void)
+{
+  #if (__ICACHE_PRESENT == 1U)
+    __DSB();
+    __ISB();
+    SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk;  /* disable I-Cache */
+    SCB->ICIALLU = 0UL;                     /* invalidate I-Cache */
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Invalidate I-Cache
+  \details Invalidates I-Cache
+  */
+__STATIC_INLINE void SCB_InvalidateICache (void)
+{
+  #if (__ICACHE_PRESENT == 1U)
+    __DSB();
+    __ISB();
+    SCB->ICIALLU = 0UL;
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Enable D-Cache
+  \details Turns on D-Cache
+  */
+__STATIC_INLINE void SCB_EnableDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+                                            /* invalidate D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
+                      ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+    __DSB();
+
+    SCB->CCR |=  (uint32_t)SCB_CCR_DC_Msk;  /* enable D-Cache */
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Disable D-Cache
+  \details Turns off D-Cache
+  */
+__STATIC_INLINE void SCB_DisableDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+    SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk;  /* disable D-Cache */
+
+                                            /* clean & invalidate D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
+                       ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Invalidate D-Cache
+  \details Invalidates D-Cache
+  */
+__STATIC_INLINE void SCB_InvalidateDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+                                            /* invalidate D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
+                      ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Clean D-Cache
+  \details Cleans D-Cache
+  */
+__STATIC_INLINE void SCB_CleanDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+                                            /* clean D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
+                      ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   Clean & Invalidate D-Cache
+  \details Cleans and Invalidates D-Cache
+  */
+__STATIC_INLINE void SCB_CleanInvalidateDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1U)
+    uint32_t ccsidr;
+    uint32_t sets;
+    uint32_t ways;
+
+    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
+    __DSB();
+
+    ccsidr = SCB->CCSIDR;
+
+                                            /* clean & invalidate D-Cache */
+    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+    do {
+      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+      do {
+        SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
+                       ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk)  );
+        #if defined ( __CC_ARM )
+          __schedule_barrier();
+        #endif
+      } while (ways--);
+    } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   D-Cache Invalidate by address
+  \details Invalidates D-Cache for the given address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1U)
+     int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t)addr;
+     int32_t linesize = 32U;                /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCIMVAC = op_addr;
+      op_addr += linesize;
+      op_size -= linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   D-Cache Clean by address
+  \details Cleans D-Cache for the given address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1)
+     int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t) addr;
+     int32_t linesize = 32U;                /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCCMVAC = op_addr;
+      op_addr += linesize;
+      op_size -= linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \brief   D-Cache Clean and Invalidate by address
+  \details Cleans and invalidates D_Cache for the given address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1U)
+     int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t) addr;
+     int32_t linesize = 32U;                /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCCIMVAC = op_addr;
+      op_addr += linesize;
+      op_size -= linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/*@} end of CMSIS_Core_CacheFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_core_DebugFunctions ITM Functions
+  \brief    Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters. */
+#define                 ITM_RXBUFFER_EMPTY   0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+  \brief   ITM Send Character
+  \details Transmits a character via the ITM channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0U].u32 == 0UL)
+    {
+      __NOP();
+    }
+    ITM->PORT[0U].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Receive Character
+  \details Inputs a character via the external variable \ref ITM_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+  {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Check Character
+  \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+  {
+    return (0);                              /* no character available */
+  }
+  else
+  {
+    return (1);                              /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM7_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmFunc.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmFunc.h
new file mode 100755
index 0000000..652a48a
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmFunc.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file     core_cmFunc.h
+ * @brief    CMSIS Cortex-M Core Function Access Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if   defined ( __CC_ARM )
+  #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+  #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+  #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+  #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+  /*
+   * The CMSIS functions have been implemented as intrinsics in the compiler.
+   * Please use "carm -?i" to get an up to date list of all intrinsics,
+   * Including the CMSIS ones.
+   */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+  #include <cmsis_csm.h>
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+#endif /* __CORE_CMFUNC_H */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmInstr.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmInstr.h
new file mode 100755
index 0000000..f474b0e
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmInstr.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file     core_cmInstr.h
+ * @brief    CMSIS Cortex-M Core Instruction Access Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if   defined ( __CC_ARM )
+  #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+  #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+  #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+  #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+  /*
+   * The CMSIS functions have been implemented as intrinsics in the compiler.
+   * Please use "carm -?i" to get an up to date list of all intrinsics,
+   * Including the CMSIS ones.
+   */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+  #include <cmsis_csm.h>
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmSimd.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmSimd.h
new file mode 100755
index 0000000..66bf5c2
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_cmSimd.h
@@ -0,0 +1,96 @@
+/**************************************************************************//**
+ * @file     core_cmSimd.h
+ * @brief    CMSIS Cortex-M SIMD Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMSIMD_H
+#define __CORE_CMSIMD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if   defined ( __CC_ARM )
+  #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+  #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+  #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+  #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+  /*
+   * The CMSIS functions have been implemented as intrinsics in the compiler.
+   * Please use "carm -?i" to get an up to date list of all intrinsics,
+   * Including the CMSIS ones.
+   */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+  #include <cmsis_csm.h>
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CMSIMD_H */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_sc000.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_sc000.h
new file mode 100755
index 0000000..514dbd8
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_sc000.h
@@ -0,0 +1,926 @@
+/**************************************************************************//**
+ * @file     core_sc000.h
+ * @brief    CMSIS SC000 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_SC000_H_GENERIC
+#define __CORE_SC000_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup SC000
+  @{
+ */
+
+/*  CMSIS SC000 definitions */
+#define __SC000_CMSIS_VERSION_MAIN  (0x04U)                                    /*!< [31:16] CMSIS HAL main version */
+#define __SC000_CMSIS_VERSION_SUB   (0x1EU)                                    /*!< [15:0]  CMSIS HAL sub version */
+#define __SC000_CMSIS_VERSION       ((__SC000_CMSIS_VERSION_MAIN << 16U) | \
+                                      __SC000_CMSIS_VERSION_SUB           )    /*!< CMSIS HAL version number */
+
+#define __CORTEX_SC                 (000U)                                     /*!< Cortex secure core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC000_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_SC000_H_DEPENDANT
+#define __CORE_SC000_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __SC000_REV
+    #define __SC000_REV             0x0000U
+    #warning "__SC000_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group SC000 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core MPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:28;              /*!< bit:  0..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t _reserved1:3;               /*!< bit: 25..27  Reserved */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:1;               /*!< bit:      0  Reserved */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[1U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[31U];
+  __IOM uint32_t ICER[1U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[31U];
+  __IOM uint32_t ISPR[1U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[31U];
+  __IOM uint32_t ICPR[1U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[31U];
+        uint32_t RESERVED4[64U];
+  __IOM uint32_t IP[8U];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t SHP[2U];                /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+        uint32_t RESERVED1[154U];
+  __IOM uint32_t SFCR;                   /*!< Offset: 0x290 (R/W)  Security Features Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACTLR;                  /*!< Offset: 0x008 (R/W)  Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0U                                         /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   8U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0xFFFFFFUL << MPU_RBAR_ADDR_Pos)              /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+            Therefore they are not covered by the SC000 header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of SC000 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
+#define _SHP_IDX(IRQn)           ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >>    2UL)      )
+#define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      )
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+  else
+  {
+    NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+       (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC000_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/K32W061DK6/CMSIS/Include/core_sc300.h b/third_party/nxp/K32W061DK6/CMSIS/Include/core_sc300.h
new file mode 100755
index 0000000..8bd18aa
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/CMSIS/Include/core_sc300.h
@@ -0,0 +1,1745 @@
+/**************************************************************************//**
+ * @file     core_sc300.h
+ * @brief    CMSIS SC300 Core Peripheral Access Layer Header File
+ * @version  V4.30
+ * @date     20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if   defined ( __ICCARM__ )
+ #pragma system_include         /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang system_header   /* treat file as system include file */
+#endif
+
+#ifndef __CORE_SC300_H_GENERIC
+#define __CORE_SC300_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+  \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/**
+  \ingroup SC3000
+  @{
+ */
+
+/*  CMSIS SC300 definitions */
+#define __SC300_CMSIS_VERSION_MAIN  (0x04U)                                    /*!< [31:16] CMSIS HAL main version */
+#define __SC300_CMSIS_VERSION_SUB   (0x1EU)                                    /*!< [15:0]  CMSIS HAL sub version */
+#define __SC300_CMSIS_VERSION       ((__SC300_CMSIS_VERSION_MAIN << 16U) | \
+                                      __SC300_CMSIS_VERSION_SUB           )    /*!< CMSIS HAL version number */
+
+#define __CORTEX_SC                 (300U)                                     /*!< Cortex secure core */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler */
+  #define __INLINE         inline                                    /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+  #define __STATIC_INLINE  static inline
+
+#else
+  #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0U
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #if defined __ARM_PCS_VFP
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )
+  #if ( __CSMC__ & 0x400U)
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#endif
+
+#include "core_cmInstr.h"                /* Core Instruction Access */
+#include "core_cmFunc.h"                 /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC300_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_SC300_H_DEPENDANT
+#define __CORE_SC300_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __SC300_REV
+    #define __SC300_REV               0x0000U
+    #warning "__SC300_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0U
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4U
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0U
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile            /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group SC300 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_core_register Defines and Type Definitions
+  \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31U                                            /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30U                                            /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29U                                            /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28U                                            /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27U                                            /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+
+/**
+  \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0U                                            /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number */
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0) */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0) */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31U                                            /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30U                                            /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29U                                            /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28U                                            /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27U                                            /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25U                                            /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24U                                            /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos                        0U                                            /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/**
+  \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used */
+    uint32_t _reserved1:30;              /*!< bit:  2..31  Reserved */
+  } b;                                   /*!< Structure used for bit  access */
+  uint32_t w;                            /*!< Type      used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos                   1U                                            /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0U                                            /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+  \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
+        uint32_t RESERVED0[24U];
+  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
+        uint32_t RSERVED1[24U];
+  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
+        uint32_t RESERVED2[24U];
+  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
+        uint32_t RESERVED3[24U];
+  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
+        uint32_t RESERVED4[56U];
+  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+        uint32_t RESERVED5[644U];
+  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0U                                         /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCB     System Control Block (SCB)
+  \brief    Type definitions for the System Control Block Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
+  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
+  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
+  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
+  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
+  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
+  __IOM uint8_t  SHP[12U];               /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
+  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
+  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
+  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
+  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
+  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
+  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
+  __IM  uint32_t PFR[2U];                /*!< Offset: 0x040 (R/ )  Processor Feature Register */
+  __IM  uint32_t DFR;                    /*!< Offset: 0x048 (R/ )  Debug Feature Register */
+  __IM  uint32_t ADR;                    /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
+  __IM  uint32_t MMFR[4U];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
+  __IM  uint32_t ISAR[5U];               /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
+        uint32_t RESERVED0[5U];
+  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
+        uint32_t RESERVED1[129U];
+  __IOM uint32_t SFCR;                   /*!< Offset: 0x290 (R/W)  Security Features Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24U                                            /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20U                                            /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16U                                            /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4U                                            /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0U                                            /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31U                                            /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28U                                            /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27U                                            /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26U                                            /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25U                                            /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23U                                            /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22U                                            /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12U                                            /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11U                                            /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0U                                            /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLBASE_Pos               29U                                            /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk               (1UL << SCB_VTOR_TBLBASE_Pos)                  /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16U                                            /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16U                                            /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15U                                            /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8U                                            /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2U                                            /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1U                                            /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0U                                            /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4U                                            /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2U                                            /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1U                                            /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9U                                            /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8U                                            /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4U                                            /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3U                                            /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1U                                            /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0U                                            /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18U                                            /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17U                                            /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16U                                            /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15U                                            /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14U                                            /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13U                                            /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12U                                            /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11U                                            /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10U                                            /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8U                                            /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7U                                            /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3U                                            /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1U                                            /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0U                                            /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16U                                            /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8U                                            /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0U                                            /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31U                                            /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30U                                            /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1U                                            /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4U                                            /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3U                                            /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2U                                            /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1U                                            /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0U                                            /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+  \brief    Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+        uint32_t RESERVED0[1U];
+  __IM  uint32_t ICTR;                   /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register */
+        uint32_t RESERVED1[1U];
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0U                                         /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
+  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
+  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16U                                            /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1U                                            /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0U                                            /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0U                                            /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0U                                            /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31U                                            /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30U                                            /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0U                                            /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+  \brief    Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __OM  union
+  {
+    __OM  uint8_t    u8;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit */
+    __OM  uint16_t   u16;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit */
+    __OM  uint32_t   u32;                /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit */
+  }  PORT [32U];                         /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers */
+        uint32_t RESERVED0[864U];
+  __IOM uint32_t TER;                    /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register */
+        uint32_t RESERVED1[15U];
+  __IOM uint32_t TPR;                    /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register */
+        uint32_t RESERVED2[15U];
+  __IOM uint32_t TCR;                    /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register */
+        uint32_t RESERVED3[29U];
+  __OM  uint32_t IWR;                    /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register */
+  __IM  uint32_t IRR;                    /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register */
+  __IOM uint32_t IMCR;                   /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register */
+        uint32_t RESERVED4[43U];
+  __OM  uint32_t LAR;                    /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register */
+  __IM  uint32_t LSR;                    /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register */
+        uint32_t RESERVED5[6U];
+  __IM  uint32_t PID4;                   /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __IM  uint32_t PID5;                   /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __IM  uint32_t PID6;                   /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __IM  uint32_t PID7;                   /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __IM  uint32_t PID0;                   /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __IM  uint32_t PID1;                   /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __IM  uint32_t PID2;                   /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __IM  uint32_t PID3;                   /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __IM  uint32_t CID0;                   /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __IM  uint32_t CID1;                   /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __IM  uint32_t CID2;                   /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __IM  uint32_t CID3;                   /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0U                                            /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23U                                            /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16U                                            /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10U                                            /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8U                                            /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4U                                            /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3U                                            /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2U                                            /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1U                                            /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0U                                            /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0U                                            /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0U                                            /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0U                                            /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2U                                            /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1U                                            /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0U                                            /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+  \brief    Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control Register */
+  __IOM uint32_t CYCCNT;                 /*!< Offset: 0x004 (R/W)  Cycle Count Register */
+  __IOM uint32_t CPICNT;                 /*!< Offset: 0x008 (R/W)  CPI Count Register */
+  __IOM uint32_t EXCCNT;                 /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register */
+  __IOM uint32_t SLEEPCNT;               /*!< Offset: 0x010 (R/W)  Sleep Count Register */
+  __IOM uint32_t LSUCNT;                 /*!< Offset: 0x014 (R/W)  LSU Count Register */
+  __IOM uint32_t FOLDCNT;                /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register */
+  __IM  uint32_t PCSR;                   /*!< Offset: 0x01C (R/ )  Program Counter Sample Register */
+  __IOM uint32_t COMP0;                  /*!< Offset: 0x020 (R/W)  Comparator Register 0 */
+  __IOM uint32_t MASK0;                  /*!< Offset: 0x024 (R/W)  Mask Register 0 */
+  __IOM uint32_t FUNCTION0;              /*!< Offset: 0x028 (R/W)  Function Register 0 */
+        uint32_t RESERVED0[1U];
+  __IOM uint32_t COMP1;                  /*!< Offset: 0x030 (R/W)  Comparator Register 1 */
+  __IOM uint32_t MASK1;                  /*!< Offset: 0x034 (R/W)  Mask Register 1 */
+  __IOM uint32_t FUNCTION1;              /*!< Offset: 0x038 (R/W)  Function Register 1 */
+        uint32_t RESERVED1[1U];
+  __IOM uint32_t COMP2;                  /*!< Offset: 0x040 (R/W)  Comparator Register 2 */
+  __IOM uint32_t MASK2;                  /*!< Offset: 0x044 (R/W)  Mask Register 2 */
+  __IOM uint32_t FUNCTION2;              /*!< Offset: 0x048 (R/W)  Function Register 2 */
+        uint32_t RESERVED2[1U];
+  __IOM uint32_t COMP3;                  /*!< Offset: 0x050 (R/W)  Comparator Register 3 */
+  __IOM uint32_t MASK3;                  /*!< Offset: 0x054 (R/W)  Mask Register 3 */
+  __IOM uint32_t FUNCTION3;              /*!< Offset: 0x058 (R/W)  Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28U                                         /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27U                                         /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26U                                         /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25U                                         /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24U                                         /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22U                                         /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21U                                         /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20U                                         /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19U                                         /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18U                                         /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17U                                         /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16U                                         /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12U                                         /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10U                                         /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9U                                         /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5U                                         /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1U                                         /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0U                                         /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0U                                         /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0U                                         /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0U                                         /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0U                                         /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0U                                         /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24U                                         /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16U                                         /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12U                                         /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10U                                         /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9U                                         /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8U                                         /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7U                                         /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5U                                         /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0U                                         /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+  \brief    Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IOM uint32_t SSPSR;                  /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register */
+  __IOM uint32_t CSPSR;                  /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+        uint32_t RESERVED0[2U];
+  __IOM uint32_t ACPR;                   /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+        uint32_t RESERVED1[55U];
+  __IOM uint32_t SPPR;                   /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+        uint32_t RESERVED2[131U];
+  __IM  uint32_t FFSR;                   /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IOM uint32_t FFCR;                   /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __IM  uint32_t FSCR;                   /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+        uint32_t RESERVED3[759U];
+  __IM  uint32_t TRIGGER;                /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __IM  uint32_t FIFO0;                  /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __IM  uint32_t ITATBCTR2;              /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+        uint32_t RESERVED4[1U];
+  __IM  uint32_t ITATBCTR0;              /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __IM  uint32_t FIFO1;                  /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IOM uint32_t ITCTRL;                 /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+        uint32_t RESERVED5[39U];
+  __IOM uint32_t CLAIMSET;               /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IOM uint32_t CLAIMCLR;               /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+        uint32_t RESERVED7[8U];
+  __IM  uint32_t DEVID;                  /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __IM  uint32_t DEVTYPE;                /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0U                                         /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0U                                         /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3U                                         /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2U                                         /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1U                                         /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0U                                         /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8U                                         /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1U                                         /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0U                                         /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16U                                         /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8U                                         /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0U                                         /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29U                                         /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27U                                         /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26U                                         /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24U                                         /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16U                                         /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8U                                         /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0U                                         /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0U                                         /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0U                                         /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11U                                         /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10U                                         /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9U                                         /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6U                                         /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5U                                         /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0U                                         /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4U                                         /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0U                                         /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+  \brief    Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __IM  uint32_t TYPE;                   /*!< Offset: 0x000 (R/ )  MPU Type Register */
+  __IOM uint32_t CTRL;                   /*!< Offset: 0x004 (R/W)  MPU Control Register */
+  __IOM uint32_t RNR;                    /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register */
+  __IOM uint32_t RBAR;                   /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register */
+  __IOM uint32_t RASR;                   /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A1;                /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register */
+  __IOM uint32_t RASR_A1;                /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A2;                /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register */
+  __IOM uint32_t RASR_A2;                /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IOM uint32_t RBAR_A3;                /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register */
+  __IOM uint32_t RASR_A3;                /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos               16U                                            /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8U                                            /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0U                                            /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos             2U                                            /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1U                                            /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0U                                            /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos                  0U                                            /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4U                                            /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0U                                            /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos                 16U                                            /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28U                                            /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24U                                            /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19U                                            /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18U                                            /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17U                                            /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16U                                            /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8U                                            /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1U                                            /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0U                                            /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+  \ingroup  CMSIS_core_register
+  \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+  \brief    Type definitions for the Core Debug Registers
+  @{
+ */
+
+/**
+  \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IOM uint32_t DHCSR;                  /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register */
+  __OM  uint32_t DCRSR;                  /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register */
+  __IOM uint32_t DCRDR;                  /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register */
+  __IOM uint32_t DEMCR;                  /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16U                                            /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25U                                            /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24U                                            /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19U                                            /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18U                                            /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17U                                            /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16U                                            /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5U                                            /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3U                                            /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2U                                            /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1U                                            /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0U                                            /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos         16U                                            /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0U                                            /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19U                                            /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18U                                            /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17U                                            /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16U                                            /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10U                                            /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9U                                            /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8U                                            /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7U                                            /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6U                                            /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5U                                            /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4U                                            /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0U                                            /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+  \ingroup    CMSIS_core_register
+  \defgroup   CMSIS_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+  \brief    Functions that manage interrupts and exceptions via the NVIC.
+  @{
+ */
+
+/**
+  \brief   Set Priority Grouping
+  \details Sets the priority grouping field using the required unlock sequence.
+           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+           Only values from 0..7 are used.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8U)                      );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/**
+  \brief   Get Priority Grouping
+  \details Reads the priority grouping field from the NVIC Interrupt Controller.
+  \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Disable External Interrupt
+  \details Disables a device-specific interrupt in the NVIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Pending Interrupt
+  \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Pending Interrupt
+  \details Sets the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clears the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+  \brief   Get Active Interrupt
+  \details Reads the active register in NVIC and returns the active bit.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+  \brief   Set Interrupt Priority
+  \details Sets the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if ((int32_t)(IRQn) < 0)
+  {
+    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else
+  {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/**
+  \brief   Get Interrupt Priority
+  \details Reads the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if ((int32_t)(IRQn) < 0)
+  {
+    return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+  }
+  else
+  {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]               >> (8U - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/**
+  \brief   Encode Priority
+  \details Encodes the priority for an interrupt with the given priority group,
+           preemptive priority value, and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+  \param [in]     PriorityGroup  Used priority group.
+  \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+  \param [in]       SubPriority  Subpriority value (starting from 0).
+  \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/**
+  \brief   Decode Priority
+  \details Decodes an interrupt priority value with a given priority group to
+           preemptive priority value and subpriority value.
+           In case of a conflict between priority grouping and available
+           priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+  \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+  \param [in]     PriorityGroup  Used priority group.
+  \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+  \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+
+  for(;;)                                                           /* wait until reset */
+  {
+    __NOP();
+  }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+  \brief   System Tick Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+  {
+    return (1UL);                                                   /* Reload value impossible */
+  }
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+  \ingroup  CMSIS_Core_FunctionInterface
+  \defgroup CMSIS_core_DebugFunctions ITM Functions
+  \brief    Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters. */
+#define                 ITM_RXBUFFER_EMPTY   0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+  \brief   ITM Send Character
+  \details Transmits a character via the ITM channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0U].u32 == 0UL)
+    {
+      __NOP();
+    }
+    ITM->PORT[0U].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Receive Character
+  \details Inputs a character via the external variable \ref ITM_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+  {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/**
+  \brief   ITM Check Character
+  \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+  {
+    return (0);                              /* no character available */
+  }
+  else
+  {
+    return (1);                              /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC300_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/board.c b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/board.c
new file mode 100755
index 0000000..7e27ab4
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/board.c
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#include "fsl_debug_console.h"
+#include "fsl_clock.h"
+#include "board.h"
+
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+#if (defined TCXO_32M_MODE_EN) && (TCXO_32M_MODE_EN != 0)
+/* Table of load capacitance versus temperature for 32MHz crystal. Values below
+   are for NDK NX2016SA 32MHz EXS00A-CS11213-6(IEC). Values are for temperatures
+   from -40 to +130 in steps of 5 */
+int32_t CLOCK_ai32MXtalIecLoadPfVsTemp_x1000[HW_32M_LOAD_VS_TEMP_SIZE] =
+    {  960,  1097,  1194,  1246,  1253,  1216,  1137,  1023, /* -40, -35, ... -5 */
+       879,   710,   523,   325,   122,   -81,  -277,  -464, /* 0, 5, ... 35 */
+      -637,  -794,  -933, -1052, -1150, -1227, -1283, -1317, /* 40, 45, ... 75 */
+     -1328, -1315, -1274, -1202, -1090,  -930,  -709,  -409, /* 80, 85, ... 115 */
+        -9,   518,  1205};                                   /* 120, 125, 130 */
+#endif
+
+#if (defined TCXO_32k_MODE_EN) && (TCXO_32k_MODE_EN != 0)
+/* Table of load capacitance versus temperature for 32kHz crystal. Values are
+   for temperatures from -20 to +100 in steps of 20. *Note* values below are
+   just for example */
+int32_t CLOCK_ai32kXtalIecLoadPfVsTemp_x1000[HW_32k_LOAD_VS_TEMP_SIZE] =
+    {  960,  /* -20 */
+      1097,  /*   0 */
+      1194,  /*  20 */
+      1246,  /*  40 */
+      1253,  /*  60 */
+      1216,  /*  80 */
+      1137}; /* 100 */
+#endif
+
+/*******************************************************************************
+* Local Prototypes
+******************************************************************************/
+
+/*****************************************************************************
+* Local functions
+****************************************************************************/
+
+/*****************************************************************************
+ * Public functions
+ ****************************************************************************/
+
+/* Initialize debug console. */
+status_t BOARD_InitDebugConsole(void)
+{
+    status_t result;
+
+    uint32_t uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ;
+
+    result = DbgConsole_Init(BOARD_DEBUG_UART_BASEADDR, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
+
+#ifndef RTL_SIMU_ON_ES2
+    CLOCK_uDelay(500);
+#endif
+
+    return result;
+}
+
+
diff --git a/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/board.h b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/board.h
new file mode 100755
index 0000000..786cc88
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/board.h
@@ -0,0 +1,206 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#include "fsl_device_registers.h"
+#include "fsl_common.h"
+#include "clock_config.h"
+#include "fsl_clock.h"
+#include "fsl_power.h"
+#include "fsl_gpio.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*! @brief The board name */
+#define BOARD_NAME "DK6"
+
+/* The UART to use for debug messages. */
+#define BOARD_DEBUG_UART_TYPE       DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM
+#define BOARD_DEBUG_UART_BAUDRATE   115200U
+#define BOARD_DEBUG_UART_BASEADDR   (uint32_t) USART0
+#define BOARD_DEBUG_UART_CLK_FREQ   CLOCK_GetFreq(kCLOCK_Fro32M)
+#define BOARD_UART_IRQ              LPUART0_IRQn
+#define BOARD_UART_IRQ_HANDLER      LPUART0_IRQHandler
+#define BOARD_DEBUG_UART_CLK_ATTACH kOSC32M_to_USART_CLK
+
+/* There are 2 red LEDs on DK6 board: PIO0 and PIO3 */
+#define BOARD_LED_RED_GPIO        GPIO
+#define BOARD_LED_RED_GPIO_PORT   0U
+#define BOARD_LED_RED_GPIO_PIN    0U
+#define BOARD_LED_GREEN_GPIO      GPIO
+#define BOARD_LED_GREEN_GPIO_PORT 0U
+#define BOARD_LED_GREEN_GPIO_PIN  5U
+#define BOARD_LED_BLUE_GPIO       GPIO
+#define BOARD_LED_BLUE_GPIO_PORT  0U
+#define BOARD_LED_BLUE_GPIO_PIN   3U
+
+/* Board led color mapping */
+#define LOGIC_LED_ON  0U
+#define LOGIC_LED_OFF 1U
+
+#define LED_RED_INIT(output)                                                          \
+    GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, BOARD_LED_RED_GPIO_PIN, \
+                 &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_RED */
+#define LED_RED_ON()                                                  \
+    GPIO_ClearPinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
+                         1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn on target LED_RED */
+#define LED_RED_OFF()                                               \
+    GPIO_SetPinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
+                       1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn off target LED_RED */
+#define LED_RED_TOGGLE()                                               \
+    GPIO_TogglePinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
+                          1U << BOARD_LED_RED_GPIO_PIN) /*!< Toggle on target LED_RED */
+
+#define LED_GREEN_INIT(output)                                                              \
+    GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, BOARD_LED_GREEN_GPIO_PIN, \
+                 &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_GREEN */
+#define LED_GREEN_ON()                                                    \
+    GPIO_ClearPinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
+                         1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn on target LED_GREEN */
+#define LED_GREEN_OFF()                                                 \
+    GPIO_SetPinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
+                       1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn off target LED_GREEN */
+#define LED_GREEN_TOGGLE()                                                 \
+    GPIO_TogglePinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
+                          1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Toggle on target LED_GREEN */
+
+#define LED_BLUE_INIT(output)                                                            \
+    GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, BOARD_LED_BLUE_GPIO_PIN, \
+                 &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_BLUE */
+#define LED_BLUE_ON()                                                   \
+    GPIO_ClearPinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
+                         1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn on target LED_BLUE */
+#define LED_BLUE_OFF()                                                \
+    GPIO_SetPinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
+                       1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn off target LED_BLUE */
+#define LED_BLUE_TOGGLE()                                                \
+    GPIO_TogglePinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
+                          1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Toggle on target LED_BLUE */
+
+/* There are 2 red LEDs on USB Dongle: PIO4 and PIO10 */
+#define BOARD_LED_USB_DONGLE_GPIO GPIO
+#define BOARD_LED_USB_DONGLE_GPIO_PORT 0U
+#define BOARD_LED_USB_DONGLE1_GPIO_PIN 4U
+#define BOARD_LED_USB_DONGLE2_GPIO_PIN 10U
+
+#define BOARD_SW1_GPIO GPIO
+#define BOARD_SW1_GPIO_PORT 0U
+#define BOARD_SW1_GPIO_PIN  1U
+#define BOARD_SW1_NAME "SW1"
+#define BOARD_SW3_IRQ PIN_INT0_IRQn
+#define BOARD_SW3_IRQ_HANDLER PIN_INT0_IRQHandler
+
+#define BOARD_SW2_GPIO GPIO
+#define BOARD_SW2_GPIO_PORT 0U
+#define BOARD_SW2_GPIO_PIN  5U
+#define BOARD_SW2_NAME "SW2"
+#define BOARD_SW3_IRQ PIN_INT0_IRQn
+#define BOARD_SW3_IRQ_HANDLER PIN_INT0_IRQHandler
+
+/* Capacitance values for 32MHz and 32kHz crystals; board-specific. Value is
+   pF x 100. For example, 6pF becomes 600, 1.2pF becomes 120 */
+#define CLOCK_32MfXtalIecLoadpF_x100    (600) /* 6.0pF */
+#define CLOCK_32MfXtalPPcbParCappF_x100 (20)  /* 0.2pF */
+#define CLOCK_32MfXtalNPcbParCappF_x100 (40)  /* 0.4pF */
+#define CLOCK_32kfXtalIecLoadpF_x100    (600) /* 6.0pF */
+#define CLOCK_32kfXtalPPcbParCappF_x100 (40)  /* 0.4pF */
+#define CLOCK_32kfXtalNPcbParCappF_x100 (40)  /* 0.4pF */
+
+/* Capacitance variation for 32MHz crystal across temperature
+   ----------------------------------------------------------
+
+   TCXO_32M_MODE_EN should be 1 to indicate that temperature-compensated 32MHz
+   XO is supported and required. If so, HW_32M_LOAD_VS_TEMP_MIN,
+   _MAX, _STEP must be defined here and CLOCK_ai32MXtalIecLoadPfVsTemp_x1000
+   must be defined in board.c.
+
+   Values are used as follows:
+   CLOCK_ai32MXtalIecLoadPfVsTemp_x1000 is an array of crystal load capacitance
+   values across temp, with each value being at a specific temp. First value is
+   for temp given by HW_32M_LOAD_VS_TEMP_MIN, next value is for
+   temp given by HW_32M_LOAD_VS_TEMP_MIN + _STEP, next value is
+   for temp given by HW_32M_LOAD_VS_TEMP_MIN + _ STEP x 2, etc.
+   Final value is for temp given by HW_32M_LOAD_VS_TEMP_MAX. It is
+   important for HW_32M_LOAD_VS_TEMP_x defines and the table to be
+   matched to one another */
+#define TCXO_32M_MODE_EN                     (1)
+
+/* Values below are for NDK NX2016SA 32MHz EXS00A-CS11213-6(IEC) */
+
+/* Temperature related to element 0 of CLOCK_ai32MXtalIecLoadPfVsTemp_x1000 */
+#define HW_32M_LOAD_VS_TEMP_MIN  (-40)
+
+/* Temperature related to final element of CLOCK_ai32MXtalIecLoadPfVsTemp_x1000 */
+#define HW_32M_LOAD_VS_TEMP_MAX  (130)
+
+/* Temperature step between elements of CLOCK_ai32MXtalIecLoadPfVsTemp_x1000 */
+#define HW_32M_LOAD_VS_TEMP_STEP (5)
+
+#define HW_32M_LOAD_VS_TEMP_SIZE ((HW_32M_LOAD_VS_TEMP_MAX \
+                                   - HW_32M_LOAD_VS_TEMP_MIN) \
+                                  / HW_32M_LOAD_VS_TEMP_STEP + 1U)
+
+/* Table of load capacitance versus temperature for 32MHz crystal. Values are
+   for temperatures from -40 to +130 in steps of 5 */
+extern int32_t CLOCK_ai32MXtalIecLoadPfVsTemp_x1000[HW_32M_LOAD_VS_TEMP_SIZE];
+
+/* Capacitance variation for 32kHz crystal across temperature
+   ----------------------------------------------------------
+
+   TCXO_32k_MODE_EN should be 1 to indicate that temperature-compensated 32kHz
+   XO is supported and required. If so, HW_32k_LOAD_VS_TEMP_MIN,
+   _MAX, _STEP must be defined here and CLOCK_ai32kXtalIecLoadPfVsTemp_x1000
+   must be defined in board.c.
+
+   Values are used as follows:
+   CLOCK_ai32kXtalIecLoadPfVsTemp_x1000 is an array of crystal load capacitance
+   values across temp, with each value being at a specific temp. First value is
+   for temp given by HW_32k_LOAD_VS_TEMP_MIN, next value is for
+   temp given by HW_32k_LOAD_VS_TEMP_MIN + _STEP, next value is
+   for temp given by HW_32k_LOAD_VS_TEMP_MIN + _ STEP x 2, etc.
+   Final value is for temp given by HW_32k_LOAD_VS_TEMP_MAX. It is
+   important for HW_32k_LOAD_VS_TEMP_x defines and the table to be
+   matched to one another */
+#define TCXO_32k_MODE_EN                     (0) /* Disabled because table is
+                                                    *not* correct: values below
+                                                    are just for example */
+
+/* Temperature related to element 0 of CLOCK_ai32kXtalIecLoadPfVsTemp_x1000 */
+#define HW_32k_LOAD_VS_TEMP_MIN  (-20)
+
+/* Temperature related to final element of CLOCK_ai32kXtalIecLoadPfVsTemp_x1000 */
+#define HW_32k_LOAD_VS_TEMP_MAX  (100)
+
+/* Temperature step between elements of CLOCK_ai32kXtalIecLoadPfVsTemp_x1000 */
+#define HW_32k_LOAD_VS_TEMP_STEP (20)
+
+#define HW_32k_LOAD_VS_TEMP_SIZE ((HW_32k_LOAD_VS_TEMP_MAX \
+                                   - HW_32k_LOAD_VS_TEMP_MIN) \
+                                  / HW_32k_LOAD_VS_TEMP_STEP + 1U)
+
+/* Table of load capacitance versus temperature for 32kHz crystal. Values are
+   for temperatures from -20 to +100 in steps of 20 */
+extern int32_t CLOCK_ai32kXtalIecLoadPfVsTemp_x1000[HW_32k_LOAD_VS_TEMP_SIZE];
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+status_t BOARD_InitDebugConsole(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+#endif /* _BOARD_H_ */
diff --git a/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/clock_config.c b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/clock_config.c
new file mode 100755
index 0000000..1a4ca32
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/clock_config.c
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#include "fsl_common.h"
+#include "clock_config.h"
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/* System clock frequency. */
+extern uint32_t SystemCoreClock;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+void BOARD_BootClockVLPR(void)
+{
+}
+
+void BOARD_BootClockRUN(void)
+{
+    /* Set PMC FRO selection */
+    CLOCK_EnableClock(kCLOCK_Fro32M);
+    CLOCK_EnableClock(kCLOCK_Fro48M);
+    CLOCK_EnableClock(kCLOCK_Gpio0);
+    CLOCK_EnableClock(kCLOCK_Rtc);
+
+    /* INMUX and IOCON are used by many apps, enable both INMUX and IOCON clock bits here. */
+    CLOCK_AttachClk(kOSC32M_to_FRG_CLK);
+    CLOCK_AttachClk(kMAIN_CLK_to_DMI_CLK);
+
+    CLOCK_EnableAPBBridge();
+    SYSCON->DMICCLKDIV=0;
+    CLOCK_SetClkDiv(kCLOCK_DivClkout, 1, false);
+
+    CLOCK_EnableClock(kCLOCK_Xtal32M);
+    CLOCK_EnableClock(kCLOCK_Xtal32k);
+    CLOCK_AttachClk(kXTAL32K_to_OSC32K_CLK);
+
+    /* Enable 48MHz CPU freq */
+    CLOCK_AttachClk(kFRO48M_to_MAIN_CLK);
+    /* Enable 32MHZ XTAL to Ctimer */
+    CLOCK_AttachClk(kXTAL32M_to_ASYNC_APB);
+
+    /* WWDT clock config (32k oscillator, no division) */
+    CLOCK_AttachClk(kOSC32K_to_WDT_CLK);
+    CLOCK_SetClkDiv(kCLOCK_DivWdtClk, 1, true);
+
+    /* enable the clocks for the cryto blocks */
+    CLOCK_EnableClock(kCLOCK_Aes);
+
+    SystemCoreClockUpdate();
+}
+
+void BOARD_BootClockHSRUN(void)
+{
+}
diff --git a/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/clock_config.h b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/clock_config.h
new file mode 100755
index 0000000..54630dc
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/clock_config.h
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _CLOCK_CONFIG_H_
+#define _CLOCK_CONFIG_H_
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus*/
+
+void BOARD_BootClockVLPR(void);
+void BOARD_BootClockRUN(void);
+void BOARD_BootClockHSRUN(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus*/
+
+#endif /* _CLOCK_CONFIG_H_ */
diff --git a/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/pin_mux.c b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/pin_mux.c
new file mode 100755
index 0000000..f1facfa
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/pin_mux.c
@@ -0,0 +1,139 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#include "fsl_common.h"
+#include "fsl_iocon.h"
+#include "fsl_gpio.h"
+#include "pin_mux.h"
+
+/*****************************************************************************
+ * Private types/enumerations/variables
+ ****************************************************************************/
+
+#ifndef BOARD_USECLKINSRC
+#define BOARD_USECLKINSRC (0)
+#endif
+
+/*****************************************************************************
+ * Public types/enumerations/variables
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Prototypes
+ ****************************************************************************/
+/*****************************************************************************
+* Private functions
+****************************************************************************/
+static void ConfigureConsolePort(void)
+{
+    /* UART0 RX/TX pins */
+    IOCON_PinMuxSet(IOCON, 0, 8, IOCON_MODE_INACT | IOCON_FUNC2 | IOCON_DIGITAL_EN);
+    IOCON_PinMuxSet(IOCON, 0, 9, IOCON_MODE_INACT | IOCON_FUNC2 | IOCON_DIGITAL_EN);
+}
+
+static void ConfigureDebugPort(void)
+{
+    /* SWD SWCLK/SWDIO pins */
+    IOCON_PinMuxSet(IOCON, 0, 12, IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN);
+    IOCON_PinMuxSet(IOCON, 0, 13, IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN);
+#ifdef ENABLE_DEBUG_PORT_SWO
+    /* SWD SWO pin (optional) */
+    IOCON_PinMuxSet(IOCON, 0, 14, IOCON_FUNC5 | IOCON_MODE_INACT | IOCON_DIGITAL_EN);
+    SYSCON->TRACECLKDIV = 0; /* Clear HALT bit */
+#endif
+}
+
+static void ConfigureDongleLEDs(void)
+{
+    const uint32_t port0_pin4_config = (/* Pin is configured as PIO0_4 */
+                                        IOCON_PIO_FUNC0 |
+                                        /* Selects pull-up function */
+                                        IOCON_PIO_MODE_PULLUP |
+                                        /* Standard mode, output slew rate control is disabled */
+                                        IOCON_PIO_SLEW0_STANDARD |
+                                        /* Input function is not inverted */
+                                        IOCON_PIO_INV_DI |
+                                        /* Enables digital function */
+                                        IOCON_PIO_DIGITAL_EN |
+                                        /* Input filter disabled */
+                                        IOCON_PIO_INPFILT_OFF |
+                                        /* Standard mode, output slew rate control is disabled */
+                                        IOCON_PIO_SLEW1_STANDARD |
+                                        /* Open drain is disabled */
+                                        IOCON_PIO_OPENDRAIN_DI |
+                                        /* SSEL is disabled */
+                                        IOCON_PIO_SSEL_DI);
+    /* PORT0 PIN4 (coords: 7) is configured as PIO0_4 */
+    IOCON_PinMuxSet(IOCON, 0U, 4U, port0_pin4_config);
+
+    const uint32_t port0_pin10_config = (/* Pin is configured as PIO0_10 */
+                                         IOCON_PIO_FUNC0 |
+                                         /* GPIO mode */
+                                         IOCON_PIO_EGP_GPIO |
+                                         /* IO is an open drain cell */
+                                         IOCON_PIO_ECS_DI |
+                                         /* High speed IO for GPIO mode, IIC not */
+                                         IOCON_PIO_EHS_DI |
+                                         /* Input function is not inverted */
+                                         IOCON_PIO_INV_DI |
+                                         /* Enables digital function */
+                                         IOCON_PIO_DIGITAL_EN |
+                                         /* Input filter disabled */
+                                         IOCON_PIO_INPFILT_OFF |
+                                         /* IIC mode:Noise pulses below approximately 50ns are filtered out. GPIO mode:a 3ns filter */
+                                         IOCON_PIO_FSEL_DI |
+                                         /* Open drain is disabled */
+                                         IOCON_PIO_OPENDRAIN_DI |
+                                         /* IO_CLAMP disabled */
+                                         IOCON_PIO_IO_CLAMP_DI);
+    /* PORT0 PIN10 (coords: 13) is configured as PIO0_10 */
+    IOCON_PinMuxSet(IOCON, 0U, 10U, port0_pin10_config);
+}
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+void BOARD_InitPins(void)
+{
+    /* Define the init structure for the output LED pin*/
+    gpio_pin_config_t led_config = {
+        kGPIO_DigitalOutput,
+        0,
+    };
+
+    /* Enable IOCON clock */
+    CLOCK_EnableClock(kCLOCK_Iocon);
+    CLOCK_EnableClock(kCLOCK_InputMux);
+
+    /* Console signals */
+    ConfigureConsolePort();
+
+    /* Debugger signals */
+    ConfigureDebugPort();
+
+    ConfigureDongleLEDs();
+
+    /* IOCON clock left on, this is needed if CLKIN is used. */
+    /* Initialize GPIO */
+    CLOCK_EnableClock(kCLOCK_Gpio0);
+    RESET_PeripheralReset(kGPIO0_RST_SHIFT_RSTn);
+
+    /* Init output LED GPIO. */
+    GPIO_PortInit(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT);
+    GPIO_PinInit(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, BOARD_LED_USB_DONGLE1_GPIO_PIN, &led_config);
+    GPIO_PinInit(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, BOARD_LED_USB_DONGLE2_GPIO_PIN, &led_config);
+
+    GPIO_PortToggle(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, 1u << BOARD_LED_USB_DONGLE1_GPIO_PIN);
+}
+
+
+void BOARD_LedDongleToggle(void)
+{
+    GPIO_PortToggle(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, 1u << BOARD_LED_USB_DONGLE1_GPIO_PIN);
+    GPIO_PortToggle(BOARD_LED_USB_DONGLE_GPIO, BOARD_LED_USB_DONGLE_GPIO_PORT, 1u << BOARD_LED_USB_DONGLE2_GPIO_PIN);
+}
diff --git a/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/pin_mux.h b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/pin_mux.h
new file mode 100755
index 0000000..307ed13
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/boards/k32w061dk6/wireless_examples/openthread/enablement/pin_mux.h
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _PIN_MUX_H_
+#define _PIN_MUX_H_
+
+#include "board.h"
+#include "fsl_common.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus*/
+       /*!
+        * @brief configure all pins for this demo/example
+        *
+        */
+
+#define IOCON_PIO_DIGITAL_EN 0x80u     /*!<@brief Enables digital function */
+#define IOCON_PIO_ECS_DI 0x00u         /*!<@brief IO is an open drain cell */
+#define IOCON_PIO_EGP_GPIO 0x08u       /*!<@brief GPIO mode */
+#define IOCON_PIO_EHS_DI 0x00u         /*!<@brief High speed IO for GPIO mode, IIC not */
+#define IOCON_PIO_FSEL_DI 0x00u        /*!<@brief IIC mode:Noise pulses below approximately 50ns are filtered out. GPIO mode:a 3ns filter */
+#define IOCON_PIO_FUNC0 0x00u          /*!<@brief Selects pin function 2 */
+#define IOCON_PIO_FUNC2 0x02u          /*!<@brief Selects pin function 2 */
+#define IOCON_PIO_INPFILT_OFF 0x0100u  /*!<@brief Input filter disabled */
+#define IOCON_PIO_INV_DI 0x00u         /*!<@brief Input function is not inverted */
+#define IOCON_PIO_MODE_PULLUP 0x00u    /*!<@brief Selects pull-up function */
+#define IOCON_PIO_OPENDRAIN_DI 0x00u   /*!<@brief Open drain is disabled */
+#define IOCON_PIO_SLEW0_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is disabled */
+#define IOCON_PIO_SLEW1_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is disabled */
+#define IOCON_PIO_SSEL_DI 0x00u        /*!<@brief SSEL is disabled */
+#define IOCON_PIO_IO_CLAMP_DI 0x00u    /*!<@brief IO_CLAMP disabled */
+
+void BOARD_InitPins(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus*/
+
+#endif /* _PIN_MUX_H_  */
diff --git a/third_party/nxp/K32W061DK6/components/serial_manager/serial_manager.c b/third_party/nxp/K32W061DK6/components/serial_manager/serial_manager.c
new file mode 100755
index 0000000..42dc0a4
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/components/serial_manager/serial_manager.c
@@ -0,0 +1,1326 @@
+/*
+ * Copyright 2018-2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include <string.h>
+
+#include "serial_manager.h"
+#include "serial_port_internal.h"
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#include "generic_list.h"
+
+/*
+ * The OSA_USED macro can only be defined when the OSA component is used.
+ * If the source code of the OSA component does not exist, the OSA_USED cannot be defined.
+ * OR, If OSA component is not added into project event the OSA source code exists, the OSA_USED
+ * also cannot be defined.
+ * The source code path of the OSA component is <MCUXpresso_SDK>/components/osa.
+ *
+ */
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#include "common_task.h"
+#else
+#include "fsl_os_abstraction.h"
+#endif
+
+#endif
+
+#endif
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+#ifndef NDEBUG
+#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
+#undef assert
+#define assert(n)
+#endif
+#endif
+
+#define SERIAL_EVENT_DATA_RECEIVED (1U << 0)
+#define SERIAL_EVENT_DATA_SENT (1U << 1)
+
+#define SERIAL_MANAGER_WRITE_TAG 0xAABB5754U
+#define SERIAL_MANAGER_READ_TAG 0xBBAA5244U
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+typedef enum _serial_manager_transmission_mode
+{
+    kSerialManager_TransmissionBlocking    = 0x0U, /*!< Blocking transmission*/
+    kSerialManager_TransmissionNonBlocking = 0x1U, /*!< None blocking transmission*/
+} serial_manager_transmission_mode_t;
+
+/* TX transfer structure */
+typedef struct _serial_manager_transfer
+{
+    uint8_t *buffer;
+    volatile uint32_t length;
+    volatile uint32_t soFar;
+    serial_manager_transmission_mode_t mode;
+    serial_manager_status_t status;
+} serial_manager_transfer_t;
+#endif
+
+/* write handle structure */
+typedef struct _serial_manager_send_handle
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    list_element_t link; /*!< list element of the link */
+    serial_manager_transfer_t transfer;
+#endif
+    struct _serial_manager_handle *serialManagerHandle;
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serial_manager_callback_t callback;
+    void *callbackParam;
+    uint32_t tag;
+#endif
+} serial_manager_write_handle_t;
+
+typedef serial_manager_write_handle_t serial_manager_read_handle_t;
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+/* receive state structure */
+typedef struct _serial_manager_read_ring_buffer
+{
+    uint8_t *ringBuffer;
+    uint32_t ringBufferSize;
+    volatile uint32_t ringHead;
+    volatile uint32_t ringTail;
+} serial_manager_read_ring_buffer_t;
+#endif
+
+#if defined(__CC_ARM)
+#pragma anon_unions
+#endif
+/* The serial manager handle structure */
+typedef struct _serial_manager_handle
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    list_label_t runningWriteHandleHead;   /*!< The queue of running write handle */
+    list_label_t completedWriteHandleHead; /*!< The queue of completed write handle */
+#endif
+    serial_manager_read_handle_t *volatile openedReadHandleHead;
+    volatile uint32_t openedWriteHandleCount;
+    union
+    {
+        uint8_t lowLevelhandleBuffer[1];
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        uint8_t uartHandleBuffer[SERIAL_PORT_UART_HANDLE_SIZE];
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        uint8_t usbcdcHandleBuffer[SERIAL_PORT_USB_CDC_HANDLE_SIZE];
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        uint8_t swoHandleBuffer[SERIAL_PORT_SWO_HANDLE_SIZE];
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        uint8_t usbcdcVirtualHandleBuffer[SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE];
+#endif
+    };
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serial_manager_read_ring_buffer_t ringBuffer;
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+    common_task_message_t commontaskMsg;
+#else
+    uint8_t event[OSA_EVENT_HANDLE_SIZE]; /*!< Event instance */
+    uint8_t taskId[OSA_TASK_HANDLE_SIZE]; /*!< Task handle */
+#endif
+
+#endif
+
+#endif
+
+    serial_port_type_t type;
+} serial_manager_handle_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+static void SerialManager_Task(void *param);
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+
+#else
+                                          /*
+                                           * \brief Defines the serial manager task's stack
+                                           */
+OSA_TASK_DEFINE(SerialManager_Task, SERIAL_MANAGER_TASK_PRIORITY, 1, SERIAL_MANAGER_TASK_STACK_SIZE, false);
+#endif
+
+#endif
+
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+static void SerialManager_AddTail(list_label_t *queue, serial_manager_write_handle_t *node)
+{
+    (void)LIST_AddTail(queue, &node->link);
+}
+
+static void SerialManager_RemoveHead(list_label_t *queue)
+{
+    (void)LIST_RemoveHead(queue);
+}
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+static serial_manager_status_t SerialManager_StartWriting(serial_manager_handle_t *handle)
+{
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+    serial_manager_write_handle_t *writeHandle =
+        (serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->runningWriteHandleHead);
+
+    if (writeHandle != NULL)
+    {
+        switch (handle->type)
+        {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+            case kSerialPort_Uart:
+                status = Serial_UartWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                          writeHandle->transfer.buffer, writeHandle->transfer.length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+            case kSerialPort_UsbCdc:
+                status = Serial_UsbCdcWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                            writeHandle->transfer.buffer, writeHandle->transfer.length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+            case kSerialPort_Swo:
+                status = Serial_SwoWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                         writeHandle->transfer.buffer, writeHandle->transfer.length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+            case kSerialPort_UsbCdcVirtual:
+                status = Serial_UsbCdcVirtualWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                   writeHandle->transfer.buffer, writeHandle->transfer.length);
+                break;
+#endif
+            default:
+                status = kStatus_SerialManager_Error;
+                break;
+        }
+    }
+    return status;
+}
+
+static serial_manager_status_t SerialManager_StartReading(serial_manager_handle_t *handle,
+                                                          serial_manager_read_handle_t *readHandle,
+                                                          uint8_t *buffer,
+                                                          uint32_t length)
+{
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+
+    if (readHandle != NULL)
+    {
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        if (handle->type == kSerialPort_UsbCdc)
+        {
+            status = Serial_UsbCdcRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+        }
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        if (handle->type == kSerialPort_UsbCdcVirtual)
+        {
+            status = Serial_UsbCdcVirtualRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+        }
+#endif
+    }
+    return status;
+}
+
+#else
+
+static serial_manager_status_t SerialManager_StartWriting(serial_manager_handle_t *handle,
+                                                          serial_manager_write_handle_t *writeHandle,
+                                                          uint8_t *buffer,
+                                                          uint32_t length)
+{
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+
+    if (writeHandle != NULL)
+    {
+        switch (handle->type)
+        {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+            case kSerialPort_Uart:
+                status = Serial_UartWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+            case kSerialPort_UsbCdc:
+                status = Serial_UsbCdcWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+            case kSerialPort_Swo:
+                status = Serial_SwoWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+            case kSerialPort_UsbCdcVirtual:
+                status = Serial_UsbCdcVirtualWrite(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+            default:
+                status = kStatus_SerialManager_Error;
+                break;
+        }
+    }
+    return status;
+}
+
+static serial_manager_status_t SerialManager_StartReading(serial_manager_handle_t *handle,
+                                                          serial_manager_read_handle_t *readHandle,
+                                                          uint8_t *buffer,
+                                                          uint32_t length)
+{
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+
+    if (readHandle != NULL)
+    {
+        switch (handle->type)
+        {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+            case kSerialPort_Uart:
+                status = Serial_UartRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+            case kSerialPort_UsbCdc:
+                status = Serial_UsbCdcRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+            case kSerialPort_Swo:
+                status = Serial_SwoRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+            case kSerialPort_UsbCdcVirtual:
+                status = Serial_UsbCdcVirtualRead(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), buffer, length);
+                break;
+#endif
+            default:
+                status = kStatus_SerialManager_Error;
+                break;
+        }
+    }
+    return status;
+}
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+static void SerialManager_IsrFunction(serial_manager_handle_t *handle)
+{
+    uint32_t regPrimask = DisableGlobalIRQ();
+    switch (handle->type)
+    {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        case kSerialPort_Uart:
+            Serial_UartIsrFunction(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        case kSerialPort_UsbCdc:
+            Serial_UsbCdcIsrFunction(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        case kSerialPort_Swo:
+            Serial_SwoIsrFunction(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        case kSerialPort_UsbCdcVirtual:
+            Serial_UsbCdcVirtualIsrFunction(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+        default:
+            /*MISRA rule 16.4*/
+            break;
+    }
+    EnableGlobalIRQ(regPrimask);
+}
+
+static void SerialManager_Task(void *param)
+{
+    serial_manager_handle_t *handle = (serial_manager_handle_t *)param;
+    serial_manager_write_handle_t *serialWriteHandle;
+    serial_manager_read_handle_t *serialReadHandle;
+    uint32_t primask;
+    serial_manager_callback_message_t msg;
+
+    if (NULL != handle)
+    {
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#else
+        osa_event_flags_t ev = 0;
+
+        do
+        {
+            if (KOSA_StatusSuccess ==
+                OSA_EventWait((osa_event_handle_t)handle->event, osaEventFlagsAll_c, false, osaWaitForever_c, &ev))
+            {
+                if (ev & SERIAL_EVENT_DATA_SENT)
+#endif
+
+#endif
+        {
+            serialWriteHandle =
+                (serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->completedWriteHandleHead);
+            while (NULL != serialWriteHandle)
+            {
+                SerialManager_RemoveHead(&handle->completedWriteHandleHead);
+                msg.buffer                         = serialWriteHandle->transfer.buffer;
+                msg.length                         = serialWriteHandle->transfer.soFar;
+                serialWriteHandle->transfer.buffer = NULL;
+                if (serialWriteHandle->callback != NULL)
+                {
+                    serialWriteHandle->callback(serialWriteHandle->callbackParam, &msg,
+                                                serialWriteHandle->transfer.status);
+                }
+                serialWriteHandle =
+                    (serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->completedWriteHandleHead);
+            }
+        }
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#else
+                if (ev & SERIAL_EVENT_DATA_RECEIVED)
+#endif
+
+#endif
+        {
+            primask          = DisableGlobalIRQ();
+            serialReadHandle = handle->openedReadHandleHead;
+            EnableGlobalIRQ(primask);
+
+            if (serialReadHandle != NULL)
+            {
+                if (serialReadHandle->transfer.buffer != NULL)
+                {
+                    if (serialReadHandle->transfer.soFar >= serialReadHandle->transfer.length)
+                    {
+                        msg.buffer                        = serialReadHandle->transfer.buffer;
+                        msg.length                        = serialReadHandle->transfer.soFar;
+                        serialReadHandle->transfer.buffer = NULL;
+                        if (serialReadHandle->callback != NULL)
+                        {
+                            serialReadHandle->callback(serialReadHandle->callbackParam, &msg,
+                                                       serialReadHandle->transfer.status);
+                        }
+                    }
+                }
+            }
+        }
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#else
+            }
+        } while (gUseRtos_c);
+#endif
+
+#endif
+    }
+}
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+static void SerialManager_TxCallback(void *callbackParam,
+                                     serial_manager_callback_message_t *message,
+                                     serial_manager_status_t status)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_write_handle_t *writeHandle;
+
+    assert(callbackParam);
+    assert(message);
+
+    handle = (serial_manager_handle_t *)callbackParam;
+
+    writeHandle = (serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->runningWriteHandleHead);
+
+    if (NULL != writeHandle)
+    {
+        SerialManager_RemoveHead(&handle->runningWriteHandleHead);
+        (void)SerialManager_StartWriting(handle);
+        writeHandle->transfer.soFar  = message->length;
+        writeHandle->transfer.status = status;
+        if (kSerialManager_TransmissionNonBlocking == writeHandle->transfer.mode)
+        {
+            SerialManager_AddTail(&handle->completedWriteHandleHead, writeHandle);
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+            handle->commontaskMsg.callback      = SerialManager_Task;
+            handle->commontaskMsg.callbackParam = handle;
+            COMMON_TASK_post_message(&handle->commontaskMsg);
+#else
+            (void)OSA_EventSet((osa_event_handle_t)handle->event, SERIAL_EVENT_DATA_SENT);
+#endif
+
+#else
+            SerialManager_Task(handle);
+#endif
+        }
+        else
+        {
+            writeHandle->transfer.buffer = NULL;
+        }
+    }
+}
+
+static void SerialManager_RxCallback(void *callbackParam,
+                                     serial_manager_callback_message_t *message,
+                                     serial_manager_status_t status)
+{
+    serial_manager_handle_t *handle;
+    uint32_t ringBufferLength;
+    uint32_t primask;
+
+    assert(callbackParam);
+    assert(message);
+
+    handle = (serial_manager_handle_t *)callbackParam;
+
+    status = kStatus_SerialManager_Notify;
+
+    for (uint32_t i = 0; i < message->length; i++)
+    {
+        handle->ringBuffer.ringBuffer[handle->ringBuffer.ringHead++] = message->buffer[i];
+        if (handle->ringBuffer.ringHead >= handle->ringBuffer.ringBufferSize)
+        {
+            handle->ringBuffer.ringHead = 0U;
+        }
+        if (handle->ringBuffer.ringHead == handle->ringBuffer.ringTail)
+        {
+            status = kStatus_SerialManager_RingBufferOverflow;
+            handle->ringBuffer.ringTail++;
+            if (handle->ringBuffer.ringTail >= handle->ringBuffer.ringBufferSize)
+            {
+                handle->ringBuffer.ringTail = 0U;
+            }
+        }
+    }
+
+    ringBufferLength = handle->ringBuffer.ringHead + handle->ringBuffer.ringBufferSize - handle->ringBuffer.ringTail;
+    ringBufferLength = ringBufferLength % handle->ringBuffer.ringBufferSize;
+
+    primask = DisableGlobalIRQ();
+    if ((handle->openedReadHandleHead != NULL) && (handle->openedReadHandleHead->transfer.buffer != NULL))
+    {
+        if (handle->openedReadHandleHead->transfer.length > handle->openedReadHandleHead->transfer.soFar)
+        {
+            uint32_t remainLength =
+                handle->openedReadHandleHead->transfer.length - handle->openedReadHandleHead->transfer.soFar;
+            for (uint32_t i = 0; i < MIN(ringBufferLength, remainLength); i++)
+            {
+                handle->openedReadHandleHead->transfer.buffer[handle->openedReadHandleHead->transfer.soFar] =
+                    handle->ringBuffer.ringBuffer[handle->ringBuffer.ringTail];
+                handle->ringBuffer.ringTail++;
+                handle->openedReadHandleHead->transfer.soFar++;
+                if (handle->ringBuffer.ringTail >= handle->ringBuffer.ringBufferSize)
+                {
+                    handle->ringBuffer.ringTail = 0U;
+                }
+            }
+            ringBufferLength = ringBufferLength - MIN(ringBufferLength, remainLength);
+        }
+
+        if (handle->openedReadHandleHead->transfer.length > handle->openedReadHandleHead->transfer.soFar)
+        {
+        }
+        else
+        {
+            if (kSerialManager_TransmissionBlocking == handle->openedReadHandleHead->transfer.mode)
+            {
+                handle->openedReadHandleHead->transfer.buffer = NULL;
+            }
+            else
+            {
+                handle->openedReadHandleHead->transfer.status = kStatus_SerialManager_Success;
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+                handle->commontaskMsg.callback      = SerialManager_Task;
+                handle->commontaskMsg.callbackParam = handle;
+                COMMON_TASK_post_message(&handle->commontaskMsg);
+#else
+                (void)OSA_EventSet((osa_event_handle_t)handle->event, SERIAL_EVENT_DATA_RECEIVED);
+#endif
+
+#else
+                SerialManager_Task(handle);
+#endif
+            }
+        }
+    }
+
+    if (ringBufferLength != 0U)
+    {
+        message->buffer = NULL;
+        message->length = ringBufferLength;
+        if ((NULL != handle->openedReadHandleHead) && (NULL != handle->openedReadHandleHead->callback))
+        {
+            handle->openedReadHandleHead->callback(handle->openedReadHandleHead->callbackParam, message, status);
+        }
+    }
+
+    ringBufferLength = handle->ringBuffer.ringBufferSize - 1U - ringBufferLength;
+
+    if (NULL != handle->openedReadHandleHead)
+    {
+        (void)SerialManager_StartReading(handle, handle->openedReadHandleHead, NULL, ringBufferLength);
+    }
+    EnableGlobalIRQ(primask);
+}
+
+static serial_manager_status_t SerialManager_Write(serial_write_handle_t writeHandle,
+                                                   uint8_t *buffer,
+                                                   uint32_t length,
+                                                   serial_manager_transmission_mode_t mode)
+{
+    serial_manager_write_handle_t *serialWriteHandle;
+    serial_manager_handle_t *handle;
+    serial_manager_status_t status = kStatus_SerialManager_Success;
+    uint32_t primask;
+    uint8_t isEmpty = 0U;
+
+    assert(writeHandle);
+    assert(buffer);
+    assert(length);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+    handle            = serialWriteHandle->serialManagerHandle;
+
+    assert(handle);
+    assert(SERIAL_MANAGER_WRITE_TAG == serialWriteHandle->tag);
+    assert(!((kSerialManager_TransmissionNonBlocking == mode) && (NULL == serialWriteHandle->callback)));
+
+    primask = DisableGlobalIRQ();
+    if (serialWriteHandle->transfer.buffer != NULL)
+    {
+        EnableGlobalIRQ(primask);
+        return kStatus_SerialManager_Busy;
+    }
+    serialWriteHandle->transfer.buffer = buffer;
+    serialWriteHandle->transfer.length = length;
+    serialWriteHandle->transfer.soFar  = 0U;
+    serialWriteHandle->transfer.mode   = mode;
+
+    if (NULL == LIST_GetHead(&handle->runningWriteHandleHead))
+    {
+        isEmpty = 1U;
+    }
+    SerialManager_AddTail(&handle->runningWriteHandleHead, serialWriteHandle);
+    EnableGlobalIRQ(primask);
+
+    if (isEmpty != 0U)
+    {
+        status = SerialManager_StartWriting(handle);
+        if ((serial_manager_status_t)kStatus_SerialManager_Success != status)
+        {
+            return status;
+        }
+    }
+
+    if (kSerialManager_TransmissionBlocking == mode)
+    {
+        while (serialWriteHandle->transfer.length > serialWriteHandle->transfer.soFar)
+        {
+#if defined(__GIC_PRIO_BITS)
+            if ((__get_CPSR() & CPSR_M_Msk) == 0x13)
+#else
+            if (__get_IPSR() != 0U)
+#endif
+            {
+                SerialManager_IsrFunction(handle);
+            }
+        }
+    }
+    return kStatus_SerialManager_Success;
+}
+
+static serial_manager_status_t SerialManager_Read(serial_read_handle_t readHandle,
+                                                  uint8_t *buffer,
+                                                  uint32_t length,
+                                                  serial_manager_transmission_mode_t mode,
+                                                  uint32_t *receivedLength)
+{
+    serial_manager_read_handle_t *serialReadHandle;
+    serial_manager_handle_t *handle;
+    uint32_t dataLength;
+    uint32_t primask;
+
+    assert(readHandle);
+    assert(buffer);
+    assert(length);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+    handle           = serialReadHandle->serialManagerHandle;
+
+    assert(handle);
+    assert(SERIAL_MANAGER_READ_TAG == serialReadHandle->tag);
+    assert(!((kSerialManager_TransmissionNonBlocking == mode) && (NULL == serialReadHandle->callback)));
+
+    primask = DisableGlobalIRQ();
+    if (serialReadHandle->transfer.buffer != NULL)
+    {
+        EnableGlobalIRQ(primask);
+        return kStatus_SerialManager_Busy;
+    }
+    serialReadHandle->transfer.buffer = buffer;
+    serialReadHandle->transfer.length = length;
+    serialReadHandle->transfer.soFar  = 0U;
+    serialReadHandle->transfer.mode   = mode;
+
+    dataLength = handle->ringBuffer.ringHead + handle->ringBuffer.ringBufferSize - handle->ringBuffer.ringTail;
+    dataLength = dataLength % handle->ringBuffer.ringBufferSize;
+
+    for (serialReadHandle->transfer.soFar = 0U; serialReadHandle->transfer.soFar < MIN(dataLength, length);
+         serialReadHandle->transfer.soFar++)
+    {
+        buffer[serialReadHandle->transfer.soFar] = handle->ringBuffer.ringBuffer[handle->ringBuffer.ringTail];
+        handle->ringBuffer.ringTail++;
+        if (handle->ringBuffer.ringTail >= handle->ringBuffer.ringBufferSize)
+        {
+            handle->ringBuffer.ringTail = 0U;
+        }
+    }
+
+    dataLength = handle->ringBuffer.ringHead + handle->ringBuffer.ringBufferSize - handle->ringBuffer.ringTail;
+    dataLength = dataLength % handle->ringBuffer.ringBufferSize;
+    dataLength = handle->ringBuffer.ringBufferSize - 1U - dataLength;
+
+    (void)SerialManager_StartReading(handle, readHandle, NULL, dataLength);
+
+    if (receivedLength != NULL)
+    {
+        *receivedLength                   = serialReadHandle->transfer.soFar;
+        serialReadHandle->transfer.buffer = NULL;
+        EnableGlobalIRQ(primask);
+    }
+    else
+    {
+        if (serialReadHandle->transfer.soFar >= serialReadHandle->transfer.length)
+        {
+            serialReadHandle->transfer.buffer = NULL;
+            EnableGlobalIRQ(primask);
+            if (kSerialManager_TransmissionNonBlocking == mode)
+            {
+                if (serialReadHandle->callback != NULL)
+                {
+                    serial_manager_callback_message_t msg;
+                    msg.buffer = buffer;
+                    msg.length = serialReadHandle->transfer.soFar;
+                    serialReadHandle->callback(serialReadHandle->callbackParam, &msg, kStatus_SerialManager_Success);
+                }
+            }
+        }
+        else
+        {
+            EnableGlobalIRQ(primask);
+        }
+
+        if (kSerialManager_TransmissionBlocking == mode)
+        {
+            while (serialReadHandle->transfer.length > serialReadHandle->transfer.soFar)
+            {
+            }
+        }
+    }
+
+    return kStatus_SerialManager_Success;
+}
+
+#else
+
+static serial_manager_status_t SerialManager_Write(serial_write_handle_t writeHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_manager_write_handle_t *serialWriteHandle;
+    serial_manager_handle_t *handle;
+
+    assert(writeHandle);
+    assert(buffer);
+    assert(length);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+    handle            = serialWriteHandle->serialManagerHandle;
+
+    assert(handle);
+
+    return SerialManager_StartWriting(handle, serialWriteHandle, buffer, length);
+}
+
+static serial_manager_status_t SerialManager_Read(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_manager_read_handle_t *serialReadHandle;
+    serial_manager_handle_t *handle;
+
+    assert(readHandle);
+    assert(buffer);
+    assert(length);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+    handle           = serialReadHandle->serialManagerHandle;
+
+    assert(handle);
+
+    return SerialManager_StartReading(handle, serialReadHandle, buffer, length);
+}
+#endif
+
+serial_manager_status_t SerialManager_Init(serial_handle_t serialHandle, serial_manager_config_t *config)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_status_t status = kStatus_SerialManager_Error;
+
+    assert(config);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    assert(config->ringBuffer);
+    assert(config->ringBufferSize);
+#endif
+    assert(serialHandle);
+    assert(SERIAL_MANAGER_HANDLE_SIZE >= sizeof(serial_manager_handle_t));
+
+    handle = (serial_manager_handle_t *)serialHandle;
+
+    (void)memset(handle, 0, SERIAL_MANAGER_HANDLE_SIZE);
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+
+    COMMON_TASK_init();
+
+#else
+    if (KOSA_StatusSuccess != OSA_EventCreate((osa_event_handle_t)handle->event, true))
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+    if (KOSA_StatusSuccess != OSA_TaskCreate((osa_task_handle_t)handle->taskId, OSA_TASK(SerialManager_Task), handle))
+    {
+        return kStatus_SerialManager_Error;
+    }
+#endif
+
+#endif
+
+#endif
+
+    handle->type = config->type;
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    handle->ringBuffer.ringBuffer     = config->ringBuffer;
+    handle->ringBuffer.ringBufferSize = config->ringBufferSize;
+#endif
+
+    switch (config->type)
+    {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        case kSerialPort_Uart:
+            status = Serial_UartInit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), config->portConfig);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+            if ((serial_manager_status_t)kStatus_SerialManager_Success == status)
+            {
+                status = Serial_UartInstallTxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                      SerialManager_TxCallback, handle);
+                if ((serial_manager_status_t)kStatus_SerialManager_Success == status)
+                {
+                    status = Serial_UartInstallRxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                          SerialManager_RxCallback, handle);
+                }
+            }
+#endif
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        case kSerialPort_UsbCdc:
+            status = Serial_UsbCdcInit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), config->portConfig);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+            if (kStatus_SerialManager_Success == status)
+            {
+                status = Serial_UsbCdcInstallTxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                        SerialManager_TxCallback, handle);
+                if (kStatus_SerialManager_Success == status)
+                {
+                    status = Serial_UsbCdcInstallRxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                            SerialManager_RxCallback, handle);
+                }
+            }
+#endif
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        case kSerialPort_Swo:
+            status = Serial_SwoInit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), config->portConfig);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+            if (kStatus_SerialManager_Success == status)
+            {
+                status = Serial_SwoInstallTxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                     SerialManager_TxCallback, handle);
+            }
+#endif
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        case kSerialPort_UsbCdcVirtual:
+            status = Serial_UsbCdcVirtualInit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]), config->portConfig);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+            if (kStatus_SerialManager_Success == status)
+            {
+                status = Serial_UsbCdcVirtualInstallTxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                               SerialManager_TxCallback, handle);
+                if (kStatus_SerialManager_Success == status)
+                {
+                    status = Serial_UsbCdcVirtualInstallRxCallback(((serial_handle_t)&handle->lowLevelhandleBuffer[0]),
+                                                                   SerialManager_RxCallback, handle);
+                }
+            }
+#endif
+            break;
+#endif
+        default:
+            /*MISRA rule 16.4*/
+            break;
+    }
+
+    return status;
+}
+
+serial_manager_status_t SerialManager_Deinit(serial_handle_t serialHandle)
+{
+    serial_manager_handle_t *handle;
+    uint32_t primask;
+
+    assert(serialHandle);
+
+    handle = (serial_manager_handle_t *)serialHandle;
+
+    primask = DisableGlobalIRQ();
+    if ((handle->openedReadHandleHead != NULL) || (handle->openedWriteHandleCount != 0U))
+    {
+        EnableGlobalIRQ(primask);
+        return kStatus_SerialManager_Busy;
+    }
+    EnableGlobalIRQ(primask);
+
+    switch (handle->type)
+    {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        case kSerialPort_Uart:
+            (void)Serial_UartDeinit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        case kSerialPort_UsbCdc:
+            (void)Serial_UsbCdcDeinit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        case kSerialPort_Swo:
+            (void)Serial_SwoDeinit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        case kSerialPort_UsbCdcVirtual:
+            (void)Serial_UsbCdcVirtualDeinit(((serial_handle_t)&handle->lowLevelhandleBuffer[0]));
+            break;
+#endif
+        default:
+            /*MISRA rule 16.4*/
+            break;
+    }
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+#else
+    OSA_EventDestroy((osa_event_handle_t)handle->event);
+    OSA_TaskDestroy((osa_task_handle_t)handle->taskId);
+#endif
+
+#endif
+
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_OpenWriteHandle(serial_handle_t serialHandle, serial_write_handle_t writeHandle)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_write_handle_t *serialWriteHandle;
+    uint32_t primask;
+
+    assert(serialHandle);
+    assert(writeHandle);
+    assert(SERIAL_MANAGER_WRITE_HANDLE_SIZE >= sizeof(serial_manager_write_handle_t));
+
+    handle            = (serial_manager_handle_t *)serialHandle;
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+
+    (void)memset(writeHandle, 0, SERIAL_MANAGER_WRITE_HANDLE_SIZE);
+
+    primask = DisableGlobalIRQ();
+    handle->openedWriteHandleCount++;
+    EnableGlobalIRQ(primask);
+
+    serialWriteHandle->serialManagerHandle = handle;
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serialWriteHandle->tag = SERIAL_MANAGER_WRITE_TAG;
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_CloseWriteHandle(serial_write_handle_t writeHandle)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_write_handle_t *serialWriteHandle;
+    uint32_t primask;
+
+    assert(writeHandle);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+    handle            = (serial_manager_handle_t *)(void *)serialWriteHandle->serialManagerHandle;
+
+    assert(handle);
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    assert(SERIAL_MANAGER_WRITE_TAG == serialWriteHandle->tag);
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    (void)SerialManager_CancelWriting(writeHandle);
+#endif
+    primask = DisableGlobalIRQ();
+    if (handle->openedWriteHandleCount > 0U)
+    {
+        handle->openedWriteHandleCount--;
+    }
+    EnableGlobalIRQ(primask);
+
+    (void)memset(writeHandle, 0, SERIAL_MANAGER_WRITE_HANDLE_SIZE);
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_OpenReadHandle(serial_handle_t serialHandle, serial_read_handle_t readHandle)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_read_handle_t *serialReadHandle;
+    uint32_t primask;
+
+    assert(serialHandle);
+    assert(readHandle);
+    assert(SERIAL_MANAGER_READ_HANDLE_SIZE >= sizeof(serial_manager_read_handle_t));
+
+    handle           = (serial_manager_handle_t *)serialHandle;
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+
+    primask = DisableGlobalIRQ();
+    if (handle->openedReadHandleHead != NULL)
+    {
+        EnableGlobalIRQ(primask);
+        return kStatus_SerialManager_Busy;
+    }
+    handle->openedReadHandleHead = serialReadHandle;
+    EnableGlobalIRQ(primask);
+
+    (void)memset(readHandle, 0, SERIAL_MANAGER_READ_HANDLE_SIZE);
+
+    serialReadHandle->serialManagerHandle = handle;
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serialReadHandle->tag = SERIAL_MANAGER_READ_TAG;
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_CloseReadHandle(serial_read_handle_t readHandle)
+{
+    serial_manager_handle_t *handle;
+    serial_manager_read_handle_t *serialReadHandle;
+    uint32_t primask;
+
+    assert(readHandle);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+    handle           = (serial_manager_handle_t *)(void *)serialReadHandle->serialManagerHandle;
+
+    assert(handle && (handle->openedReadHandleHead == serialReadHandle));
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    assert(SERIAL_MANAGER_READ_TAG == serialReadHandle->tag);
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    (void)SerialManager_CancelReading(readHandle);
+#endif
+
+    primask                      = DisableGlobalIRQ();
+    handle->openedReadHandleHead = NULL;
+    EnableGlobalIRQ(primask);
+
+    (void)memset(readHandle, 0, SERIAL_MANAGER_READ_HANDLE_SIZE);
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_WriteBlocking(serial_write_handle_t writeHandle, uint8_t *buffer, uint32_t length)
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    return SerialManager_Write(writeHandle, buffer, length, kSerialManager_TransmissionBlocking);
+#else
+    return SerialManager_Write(writeHandle, buffer, length);
+#endif
+}
+
+serial_manager_status_t SerialManager_ReadBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length)
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    return SerialManager_Read(readHandle, buffer, length, kSerialManager_TransmissionBlocking, NULL);
+#else
+    return SerialManager_Read(readHandle, buffer, length);
+#endif
+}
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t SerialManager_WriteNonBlocking(serial_write_handle_t writeHandle,
+                                                       uint8_t *buffer,
+                                                       uint32_t length)
+{
+    return SerialManager_Write(writeHandle, buffer, length, kSerialManager_TransmissionNonBlocking);
+}
+
+serial_manager_status_t SerialManager_ReadNonBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length)
+{
+    return SerialManager_Read(readHandle, buffer, length, kSerialManager_TransmissionNonBlocking, NULL);
+}
+
+serial_manager_status_t SerialManager_CancelWriting(serial_write_handle_t writeHandle)
+{
+    serial_manager_write_handle_t *serialWriteHandle;
+    uint32_t primask;
+    uint8_t isNotUsed = 0;
+
+    assert(writeHandle);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+
+    assert(serialWriteHandle->serialManagerHandle);
+    assert(SERIAL_MANAGER_WRITE_TAG == serialWriteHandle->tag);
+
+    if ((serialWriteHandle->transfer.buffer != NULL) &&
+        (kSerialManager_TransmissionBlocking == serialWriteHandle->transfer.mode))
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+    primask = DisableGlobalIRQ();
+    if (serialWriteHandle != (serial_manager_write_handle_t *)(void *)LIST_GetHead(
+                                 &serialWriteHandle->serialManagerHandle->runningWriteHandleHead))
+    {
+        (void)LIST_RemoveElement(&serialWriteHandle->link);
+        isNotUsed = 1;
+    }
+    EnableGlobalIRQ(primask);
+
+    if (isNotUsed != 0U)
+    {
+        serialWriteHandle->transfer.soFar  = 0;
+        serialWriteHandle->transfer.status = kStatus_SerialManager_Canceled;
+
+        SerialManager_AddTail(&serialWriteHandle->serialManagerHandle->completedWriteHandleHead, serialWriteHandle);
+#if defined(OSA_USED)
+
+#if (defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U))
+        serialWriteHandle->serialManagerHandle->commontaskMsg.callback      = SerialManager_Task;
+        serialWriteHandle->serialManagerHandle->commontaskMsg.callbackParam = serialWriteHandle->serialManagerHandle;
+        COMMON_TASK_post_message(&serialWriteHandle->serialManagerHandle->commontaskMsg);
+#else
+        (void)OSA_EventSet((osa_event_handle_t)serialWriteHandle->serialManagerHandle->event, SERIAL_EVENT_DATA_SENT);
+#endif
+
+#else
+        SerialManager_Task(serialWriteHandle->serialManagerHandle);
+#endif
+    }
+    else
+    {
+        switch (serialWriteHandle->serialManagerHandle->type)
+        {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+            case kSerialPort_Uart:
+                (void)Serial_UartCancelWrite(
+                    ((serial_handle_t)&serialWriteHandle->serialManagerHandle->lowLevelhandleBuffer[0]));
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+            case kSerialPort_UsbCdc:
+                (void)Serial_UsbCdcCancelWrite(
+                    ((serial_handle_t)&serialWriteHandle->serialManagerHandle->lowLevelhandleBuffer[0]));
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+            case kSerialPort_Swo:
+                (void)Serial_SwoCancelWrite(
+                    ((serial_handle_t)&serialWriteHandle->serialManagerHandle->lowLevelhandleBuffer[0]));
+                break;
+#endif
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+            case kSerialPort_UsbCdcVirtual:
+                (void)Serial_UsbCdcVirtualCancelWrite(
+                    ((serial_handle_t)&serialWriteHandle->serialManagerHandle->lowLevelhandleBuffer[0]));
+                break;
+#endif
+            default:
+                /*MISRA rule 16.4*/
+                break;
+        }
+    }
+
+    (void)SerialManager_StartWriting(serialWriteHandle->serialManagerHandle);
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_CancelReading(serial_read_handle_t readHandle)
+{
+    serial_manager_read_handle_t *serialReadHandle;
+    serial_manager_callback_message_t msg;
+    uint8_t *buffer;
+    uint32_t primask;
+
+    assert(readHandle);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+
+    assert(SERIAL_MANAGER_READ_TAG == serialReadHandle->tag);
+
+    if ((serialReadHandle->transfer.buffer != NULL) &&
+        (kSerialManager_TransmissionBlocking == serialReadHandle->transfer.mode))
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+    primask                           = DisableGlobalIRQ();
+    buffer                            = serialReadHandle->transfer.buffer;
+    serialReadHandle->transfer.buffer = NULL;
+    serialReadHandle->transfer.length = 0;
+    msg.buffer                        = buffer;
+    msg.length                        = serialReadHandle->transfer.soFar;
+    EnableGlobalIRQ(primask);
+
+    if (buffer != NULL)
+    {
+        if (serialReadHandle->callback != NULL)
+        {
+            serialReadHandle->callback(serialReadHandle->callbackParam, &msg, kStatus_SerialManager_Canceled);
+        }
+    }
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_TryRead(serial_read_handle_t readHandle,
+                                              uint8_t *buffer,
+                                              uint32_t length,
+                                              uint32_t *receivedLength)
+{
+    assert(receivedLength);
+
+    return SerialManager_Read(readHandle, buffer, length, kSerialManager_TransmissionBlocking, receivedLength);
+}
+
+serial_manager_status_t SerialManager_InstallTxCallback(serial_write_handle_t writeHandle,
+                                                        serial_manager_callback_t callback,
+                                                        void *callbackParam)
+{
+    serial_manager_write_handle_t *serialWriteHandle;
+
+    assert(writeHandle);
+
+    serialWriteHandle = (serial_manager_write_handle_t *)writeHandle;
+
+    assert(SERIAL_MANAGER_WRITE_TAG == serialWriteHandle->tag);
+
+    serialWriteHandle->callbackParam = callbackParam;
+    serialWriteHandle->callback      = callback;
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_InstallRxCallback(serial_read_handle_t readHandle,
+                                                        serial_manager_callback_t callback,
+                                                        void *callbackParam)
+{
+    serial_manager_read_handle_t *serialReadHandle;
+
+    assert(readHandle);
+
+    serialReadHandle = (serial_manager_read_handle_t *)readHandle;
+
+    assert(SERIAL_MANAGER_READ_TAG == serialReadHandle->tag);
+
+    serialReadHandle->callbackParam = callbackParam;
+    serialReadHandle->callback      = callback;
+
+    return kStatus_SerialManager_Success;
+}
+#endif
+
+serial_manager_status_t SerialManager_EnterLowpower(serial_handle_t serialHandle)
+{
+    assert(serialHandle);
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t SerialManager_ExitLowpower(serial_handle_t serialHandle)
+{
+    assert(serialHandle);
+
+    return kStatus_SerialManager_Success;
+}
diff --git a/third_party/nxp/K32W061DK6/components/serial_manager/serial_manager.h b/third_party/nxp/K32W061DK6/components/serial_manager/serial_manager.h
new file mode 100755
index 0000000..0b4e334
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/components/serial_manager/serial_manager.h
@@ -0,0 +1,548 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SERIAL_MANAGER_H__
+#define __SERIAL_MANAGER_H__
+
+/*!
+ * @addtogroup serialmanager
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*! @brief Enable or disable serial manager non-blocking mode (1 - enable, 0 - disable) */
+#define SERIAL_MANAGER_NON_BLOCKING_MODE (1U)
+#else
+#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
+#define SERIAL_MANAGER_NON_BLOCKING_MODE (0U)
+#endif
+#endif
+
+/*! @brief Enable or disable uart port (1 - enable, 0 - disable) */
+#ifndef SERIAL_PORT_TYPE_UART
+#define SERIAL_PORT_TYPE_UART (1U)
+#endif
+
+/*! @brief Enable or disable USB CDC port (1 - enable, 0 - disable) */
+#ifndef SERIAL_PORT_TYPE_USBCDC
+#define SERIAL_PORT_TYPE_USBCDC (0U)
+#endif
+
+/*! @brief Enable or disable SWO port (1 - enable, 0 - disable) */
+#ifndef SERIAL_PORT_TYPE_SWO
+#define SERIAL_PORT_TYPE_SWO (0U)
+#endif
+
+/*! @brief Enable or disable USB CDC virtual port (1 - enable, 0 - disable) */
+#ifndef SERIAL_PORT_TYPE_USBCDC_VIRTUAL
+#define SERIAL_PORT_TYPE_USBCDC_VIRTUAL (0U)
+#endif
+
+/*! @brief Set serial manager write handle size */
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#define SERIAL_MANAGER_WRITE_HANDLE_SIZE (44U)
+#define SERIAL_MANAGER_READ_HANDLE_SIZE (44U)
+#else
+#define SERIAL_MANAGER_WRITE_HANDLE_SIZE (4U)
+#define SERIAL_MANAGER_READ_HANDLE_SIZE (4U)
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+#include "serial_port_uart.h"
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+
+#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#error The serial manager blocking mode cannot be supported for USB CDC.
+#endif
+
+#include "serial_port_usb.h"
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+#include "serial_port_swo.h"
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+
+#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#error The serial manager blocking mode cannot be supported for USB CDC.
+#endif
+
+#include "serial_port_usb_virtual.h"
+#endif
+
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP 0U
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+
+#if (SERIAL_PORT_UART_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
+#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_UART_HANDLE_SIZE
+#endif
+
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+
+#if (SERIAL_PORT_USB_CDC_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
+#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_CDC_HANDLE_SIZE
+#endif
+
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+
+#if (SERIAL_PORT_SWO_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
+#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_SWO_HANDLE_SIZE
+#endif
+
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+
+#if (SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
+#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
+#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE
+#endif
+
+#endif
+
+/*! @brief SERIAL_PORT_UART_HANDLE_SIZE/SERIAL_PORT_USB_CDC_HANDLE_SIZE + serial manager dedicated size */
+#if ((defined(SERIAL_MANAGER_HANDLE_SIZE_TEMP) && (SERIAL_MANAGER_HANDLE_SIZE_TEMP > 0U)))
+#else
+#error SERIAL_PORT_TYPE_UART, SERIAL_PORT_TYPE_USBCDC, SERIAL_PORT_TYPE_SWO and SERIAL_PORT_TYPE_USBCDC_VIRTUAL should not be cleared at same time.
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 120U)
+#else
+#define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 12U)
+#endif
+
+#define SERIAL_MANAGER_USE_COMMON_TASK (1U)
+#define SERIAL_MANAGER_TASK_PRIORITY (2U)
+#define SERIAL_MANAGER_TASK_STACK_SIZE (1000U)
+
+typedef void *serial_handle_t;
+typedef void *serial_write_handle_t;
+typedef void *serial_read_handle_t;
+
+/*! @brief serial port type*/
+typedef enum _serial_port_type
+{
+    kSerialPort_Uart = 1U,     /*!< Serial port UART */
+    kSerialPort_UsbCdc,        /*!< Serial port USB CDC */
+    kSerialPort_Swo,           /*!< Serial port SWO */
+    kSerialPort_UsbCdcVirtual, /*!< Serial port USB CDC Virtual */
+} serial_port_type_t;
+
+/*! @brief serial manager config structure*/
+typedef struct _serial_manager_config
+{
+    uint8_t *ringBuffer;     /*!< Ring buffer address, it is used to buffer data received by the hardware.
+                                  Besides, the memory space cannot be free during the lifetime of the serial
+                                  manager module. */
+    uint32_t ringBufferSize; /*!< The size of the ring buffer */
+    serial_port_type_t type; /*!< Serial port type */
+    void *portConfig;        /*!< Serial port configuration */
+} serial_manager_config_t;
+
+/*! @brief serial manager error code*/
+typedef enum _serial_manager_status
+{
+    kStatus_SerialManager_Success = kStatus_Success,                            /*!< Success */
+    kStatus_SerialManager_Error   = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 1), /*!< Failed */
+    kStatus_SerialManager_Busy    = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 2), /*!< Busy */
+    kStatus_SerialManager_Notify  = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 3), /*!< Ring buffer is not empty */
+    kStatus_SerialManager_Canceled =
+        MAKE_STATUS(kStatusGroup_SERIALMANAGER, 4), /*!< the non-blocking request is canceled */
+    kStatus_SerialManager_HandleConflict = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 5), /*!< The handle is opened */
+    kStatus_SerialManager_RingBufferOverflow =
+        MAKE_STATUS(kStatusGroup_SERIALMANAGER, 6), /*!< The ring buffer is overflowed */
+} serial_manager_status_t;
+
+/*! @brief Callback message structure */
+typedef struct _serial_manager_callback_message
+{
+    uint8_t *buffer; /*!< Transferred buffer */
+    uint32_t length; /*!< Transferred data length */
+} serial_manager_callback_message_t;
+
+/*! @brief callback function */
+typedef void (*serial_manager_callback_t)(void *callbackParam,
+                                          serial_manager_callback_message_t *message,
+                                          serial_manager_status_t status);
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+/*!
+ * @brief Initializes a serial manager module with the serial manager handle and the user configuration structure.
+ *
+ * This function configures the Serial Manager module with user-defined settings. The user can configure the
+ * configuration
+ * structure. The parameter serialHandle is a pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE
+ * allocated by the caller.
+ * The Serial Manager module supports two types of serial port, UART (includes UART, USART, LPSCI, LPUART, etc) and USB
+ * CDC.
+ * Please refer to #serial_port_type_t for serial port setting. These two types can be set by using
+ * #serial_manager_config_t.
+ *
+ * Example below shows how to use this API to configure the Serial Manager.
+ * For UART,
+ *  @code
+ *   #define SERIAL_MANAGER_RING_BUFFER_SIZE          (256U)
+ *   static uint8_t s_serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
+ *   static serial_handle_t s_serialHandle = &s_serialHandleBuffer[0];
+ *   static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
+ *
+ *   serial_manager_config_t config;
+ *   serial_port_uart_config_t uartConfig;
+ *   config.type = kSerialPort_Uart;
+ *   config.ringBuffer = &s_ringBuffer[0];
+ *   config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
+ *   uartConfig.instance = 0;
+ *   uartConfig.clockRate = 24000000;
+ *   uartConfig.baudRate = 115200;
+ *   uartConfig.parityMode = kSerialManager_UartParityDisabled;
+ *   uartConfig.stopBitCount = kSerialManager_UartOneStopBit;
+ *   uartConfig.enableRx = 1;
+ *   uartConfig.enableTx = 1;
+ *   config.portConfig = &uartConfig;
+ *   SerialManager_Init(s_serialHandle, &config);
+ *  @endcode
+ * For USB CDC,
+ *  @code
+ *   #define SERIAL_MANAGER_RING_BUFFER_SIZE          (256U)
+ *   static uint8_t s_serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
+ *   static serial_handle_t s_serialHandle = &s_serialHandleBuffer[0];
+ *   static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
+ *
+ *   serial_manager_config_t config;
+ *   serial_port_usb_cdc_config_t usbCdcConfig;
+ *   config.type = kSerialPort_UsbCdc;
+ *   config.ringBuffer = &s_ringBuffer[0];
+ *   config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
+ *   usbCdcConfig.controllerIndex = kSerialManager_UsbControllerKhci0;
+ *   config.portConfig = &usbCdcConfig;
+ *   SerialManager_Init(s_serialHandle, &config);
+ *  @endcode
+ *
+ * @param serialHandle Pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE allocated by the caller.
+ * @param config Pointer to user-defined configuration structure.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ * @retval kStatus_SerialManager_Success The Serial Manager module initialization succeed.
+ */
+serial_manager_status_t SerialManager_Init(serial_handle_t serialHandle, serial_manager_config_t *config);
+
+/*!
+ * @brief De-initializes the serial manager module instance.
+ *
+ * This function de-initializes the serial manager module instance. If the opened writing or
+ * reading handle is not closed, the function will return kStatus_SerialManager_Busy.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success The serial manager de-initialization succeed.
+ * @retval kStatus_SerialManager_Busy Opened reading or writing handle is not closed.
+ */
+serial_manager_status_t SerialManager_Deinit(serial_handle_t serialHandle);
+
+/*!
+ * @brief Opens a writing handle for the serial manager module.
+ *
+ * This function Opens a writing handle for the serial manager module. If the serial manager needs to
+ * be used in different tasks, the task should open a dedicated write handle for itself by calling
+ * #SerialManager_OpenWriteHandle. Since there can only one buffer for transmission for the writing
+ * handle at the same time, multiple writing handles need to be opened when the multiple transmission
+ * is needed for a task.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @param writeHandle The serial manager module writing handle pointer.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ * @retval kStatus_SerialManager_HandleConflict The writing handle was opened.
+ * @retval kStatus_SerialManager_Success The writing handle is opened.
+ *
+ * Example below shows how to use this API to write data.
+ * For task 1,
+ *  @code
+ *   static uint8_t s_serialWriteHandleBuffer1[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
+ *   static serial_write_handle_t s_serialWriteHandle1 = &s_serialWriteHandleBuffer1[0];
+ *   static uint8_t s_nonBlockingWelcome1[] = "This is non-blocking writing log for task1!\r\n";
+ *   SerialManager_OpenWriteHandle(serialHandle, s_serialWriteHandle1);
+ *   SerialManager_InstallTxCallback(s_serialWriteHandle1, Task1_SerialManagerTxCallback, s_serialWriteHandle1);
+ *   SerialManager_WriteNonBlocking(s_serialWriteHandle1, s_nonBlockingWelcome1, sizeof(s_nonBlockingWelcome1) - 1);
+ *  @endcode
+ * For task 2,
+ *  @code
+ *   static uint8_t s_serialWriteHandleBuffer2[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
+ *   static serial_write_handle_t s_serialWriteHandle2 = &s_serialWriteHandleBuffer2[0];
+ *   static uint8_t s_nonBlockingWelcome2[] = "This is non-blocking writing log for task2!\r\n";
+ *   SerialManager_OpenWriteHandle(serialHandle, s_serialWriteHandle2);
+ *   SerialManager_InstallTxCallback(s_serialWriteHandle2, Task2_SerialManagerTxCallback, s_serialWriteHandle2);
+ *   SerialManager_WriteNonBlocking(s_serialWriteHandle2, s_nonBlockingWelcome2, sizeof(s_nonBlockingWelcome2) - 1);
+ *  @endcode
+ */
+serial_manager_status_t SerialManager_OpenWriteHandle(serial_handle_t serialHandle, serial_write_handle_t writeHandle);
+
+/*!
+ * @brief Closes a writing handle for the serial manager module.
+ *
+ * This function Closes a writing handle for the serial manager module.
+ *
+ * @param writeHandle The serial manager module writing handle pointer.
+ * @retval kStatus_SerialManager_Success The writing handle is closed.
+ */
+serial_manager_status_t SerialManager_CloseWriteHandle(serial_write_handle_t writeHandle);
+
+/*!
+ * @brief Opens a reading handle for the serial manager module.
+ *
+ * This function Opens a reading handle for the serial manager module. The reading handle can not be
+ * opened multiple at the same time. The error code kStatus_SerialManager_Busy would be returned when
+ * the previous reading handle is not closed. And There can only be one buffer for receiving for the
+ * reading handle at the same time.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @param readHandle The serial manager module reading handle pointer.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ * @retval kStatus_SerialManager_Success The reading handle is opened.
+ * @retval kStatus_SerialManager_Busy Previous reading handle is not closed.
+ *
+ * Example below shows how to use this API to read data.
+ *  @code
+ *   static uint8_t s_serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE];
+ *   static serial_read_handle_t s_serialReadHandle = &s_serialReadHandleBuffer[0];
+ *   SerialManager_OpenReadHandle(serialHandle, s_serialReadHandle);
+ *   static uint8_t s_nonBlockingBuffer[64];
+ *   SerialManager_InstallRxCallback(s_serialReadHandle, APP_SerialManagerRxCallback, s_serialReadHandle);
+ *   SerialManager_ReadNonBlocking(s_serialReadHandle, s_nonBlockingBuffer, sizeof(s_nonBlockingBuffer));
+ *  @endcode
+ */
+serial_manager_status_t SerialManager_OpenReadHandle(serial_handle_t serialHandle, serial_read_handle_t readHandle);
+
+/*!
+ * @brief Closes a reading for the serial manager module.
+ *
+ * This function Closes a reading for the serial manager module.
+ *
+ * @param readHandle The serial manager module reading handle pointer.
+ * @retval kStatus_SerialManager_Success The reading handle is closed.
+ */
+serial_manager_status_t SerialManager_CloseReadHandle(serial_read_handle_t readHandle);
+
+/*!
+ * @brief Transmits data with the blocking mode.
+ *
+ * This is a blocking function, which polls the sending queue, waits for the sending queue to be empty.
+ * This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
+ * And There can only one buffer for transmission for the writing handle at the same time.
+ *
+ * @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
+ * cannot be used at the same time.
+ * And, the function #SerialManager_CancelWriting cannot be used to abort the transmission of this function.
+ *
+ * @param writeHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to write.
+ * @param length Length of the data to write.
+ * @retval kStatus_SerialManager_Success Successfully sent all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_WriteBlocking(serial_write_handle_t writeHandle,
+                                                    uint8_t *buffer,
+                                                    uint32_t length);
+
+/*!
+ * @brief Reads data with the blocking mode.
+ *
+ * This is a blocking function, which polls the receiving buffer, waits for the receiving buffer to be full.
+ * This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
+ * And There can only one buffer for receiving for the reading handle at the same time.
+ *
+ * @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
+ * cannot be used at the same time.
+ * And, the function #SerialManager_CancelReading cannot be used to abort the transmission of this function.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to store the received data.
+ * @param length The length of the data to be received.
+ * @retval kStatus_SerialManager_Success Successfully received all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_ReadBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length);
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+/*!
+ * @brief Transmits data with the non-blocking mode.
+ *
+ * This is a non-blocking function, which returns directly without waiting for all data to be sent.
+ * When all data is sent, the module notifies the upper layer through a TX callback function and passes
+ * the status parameter @ref kStatus_SerialManager_Success.
+ * This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
+ * And There can only one buffer for transmission for the writing handle at the same time.
+ *
+ * @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
+ * cannot be used at the same time. And, the TX callback is mandatory before the function could be used.
+ *
+ * @param writeHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to write.
+ * @param length Length of the data to write.
+ * @retval kStatus_SerialManager_Success Successfully sent all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_WriteNonBlocking(serial_write_handle_t writeHandle,
+                                                       uint8_t *buffer,
+                                                       uint32_t length);
+
+/*!
+ * @brief Reads data with the non-blocking mode.
+ *
+ * This is a non-blocking function, which returns directly without waiting for all data to be received.
+ * When all data is received, the module driver notifies the upper layer
+ * through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Success.
+ * This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
+ * And There can only one buffer for receiving for the reading handle at the same time.
+ *
+ * @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
+ * cannot be used at the same time. And, the RX callback is mandatory before the function could be used.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to store the received data.
+ * @param length The length of the data to be received.
+ * @retval kStatus_SerialManager_Success Successfully received all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_ReadNonBlocking(serial_read_handle_t readHandle,
+                                                      uint8_t *buffer,
+                                                      uint32_t length);
+
+/*!
+ * @brief Tries to read data.
+ *
+ * The function tries to read data from internal ring buffer. If the ring buffer is not empty, the data will be
+ * copied from ring buffer to up layer buffer. The copied length is the minimum of the ring buffer and up layer length.
+ * After the data is copied, the actual data length is passed by the parameter length.
+ * And There can only one buffer for receiving for the reading handle at the same time.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @param buffer Start address of the data to store the received data.
+ * @param length The length of the data to be received.
+ * @param receivedLength Length received from the ring buffer directly.
+ * @retval kStatus_SerialManager_Success Successfully received all data.
+ * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_TryRead(serial_read_handle_t readHandle,
+                                              uint8_t *buffer,
+                                              uint32_t length,
+                                              uint32_t *receivedLength);
+
+/*!
+ * @brief Cancels unfinished send transmission.
+ *
+ * The function cancels unfinished send transmission. When the transfer is canceled, the module notifies the upper layer
+ * through a TX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
+ *
+ * @note The function #SerialManager_CancelWriting cannot be used to abort the transmission of
+ * the function #SerialManager_WriteBlocking.
+ *
+ * @param writeHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success Get successfully abort the sending.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_CancelWriting(serial_write_handle_t writeHandle);
+
+/*!
+ * @brief Cancels unfinished receive transmission.
+ *
+ * The function cancels unfinished receive transmission. When the transfer is canceled, the module notifies the upper
+ * layer
+ * through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
+ *
+ * @note The function #SerialManager_CancelReading cannot be used to abort the transmission of
+ * the function #SerialManager_ReadBlocking.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success Get successfully abort the receiving.
+ * @retval kStatus_SerialManager_Error An error occurred.
+ */
+serial_manager_status_t SerialManager_CancelReading(serial_read_handle_t readHandle);
+
+/*!
+ * @brief Installs a TX callback and callback parameter.
+ *
+ * This function is used to install the TX callback and callback parameter for the serial manager module.
+ * When any status of TX transmission changed, the driver will notify the upper layer by the installed callback
+ * function. And the status is also passed as status parameter when the callback is called.
+ *
+ * @param writeHandle The serial manager module handle pointer.
+ * @param callback The callback function.
+ * @param callbackParam The parameter of the callback function.
+ * @retval kStatus_SerialManager_Success Successfully install the callback.
+ */
+serial_manager_status_t SerialManager_InstallTxCallback(serial_write_handle_t writeHandle,
+                                                        serial_manager_callback_t callback,
+                                                        void *callbackParam);
+
+/*!
+ * @brief Installs a RX callback and callback parameter.
+ *
+ * This function is used to install the RX callback and callback parameter for the serial manager module.
+ * When any status of RX transmission changed, the driver will notify the upper layer by the installed callback
+ * function. And the status is also passed as status parameter when the callback is called.
+ *
+ * @param readHandle The serial manager module handle pointer.
+ * @param callback The callback function.
+ * @param callbackParam The parameter of the callback function.
+ * @retval kStatus_SerialManager_Success Successfully install the callback.
+ */
+serial_manager_status_t SerialManager_InstallRxCallback(serial_read_handle_t readHandle,
+                                                        serial_manager_callback_t callback,
+                                                        void *callbackParam);
+
+#endif
+
+/*!
+ * @brief Prepares to enter low power consumption.
+ *
+ * This function is used to prepare to enter low power consumption.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success Successful operation.
+ */
+serial_manager_status_t SerialManager_EnterLowpower(serial_handle_t serialHandle);
+
+/*!
+ * @brief Restores from low power consumption.
+ *
+ * This function is used to restore from low power consumption.
+ *
+ * @param serialHandle The serial manager module handle pointer.
+ * @retval kStatus_SerialManager_Success Successful operation.
+ */
+serial_manager_status_t SerialManager_ExitLowpower(serial_handle_t serialHandle);
+
+#if defined(__cplusplus)
+}
+#endif
+/*! @} */
+#endif /* __SERIAL_MANAGER_H__ */
diff --git a/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_internal.h b/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_internal.h
new file mode 100755
index 0000000..abccd47
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_internal.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SERIAL_PORT_INTERNAL_H__
+#define __SERIAL_PORT_INTERNAL_H__
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+serial_manager_status_t Serial_UartInit(serial_handle_t serialHandle, void *serialConfig);
+serial_manager_status_t Serial_UartDeinit(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UartWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_UartRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_UartCancelWrite(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UartInstallTxCallback(serial_handle_t serialHandle,
+                                                     serial_manager_callback_t callback,
+                                                     void *callbackParam);
+serial_manager_status_t Serial_UartInstallRxCallback(serial_handle_t serialHandle,
+                                                     serial_manager_callback_t callback,
+                                                     void *callbackParam);
+void Serial_UartIsrFunction(serial_handle_t serialHandle);
+#endif
+
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+serial_manager_status_t Serial_UsbCdcInit(serial_handle_t serialHandle, void *config);
+serial_manager_status_t Serial_UsbCdcDeinit(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UsbCdcWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+serial_manager_status_t Serial_UsbCdcRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+serial_manager_status_t Serial_UsbCdcCancelWrite(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UsbCdcInstallTxCallback(serial_handle_t serialHandle,
+                                                       serial_manager_callback_t callback,
+                                                       void *callbackParam);
+serial_manager_status_t Serial_UsbCdcInstallRxCallback(serial_handle_t serialHandle,
+                                                       serial_manager_callback_t callback,
+                                                       void *callbackParam);
+void Serial_UsbCdcIsrFunction(serial_handle_t serialHandle);
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+serial_manager_status_t Serial_SwoInit(serial_handle_t serialHandle, void *config);
+serial_manager_status_t Serial_SwoDeinit(serial_handle_t serialHandle);
+serial_manager_status_t Serial_SwoWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_SwoRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+#endif
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_SwoCancelWrite(serial_handle_t serialHandle);
+serial_manager_status_t Serial_SwoInstallTxCallback(serial_handle_t serialHandle,
+                                                    serial_manager_callback_t callback,
+                                                    void *callbackParam);
+serial_manager_status_t Serial_SwoInstallRxCallback(serial_handle_t serialHandle,
+                                                    serial_manager_callback_t callback,
+                                                    void *callbackParam);
+void Serial_SwoIsrFunction(serial_handle_t serialHandle);
+#endif
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+serial_manager_status_t Serial_UsbCdcVirtualInit(serial_handle_t serialHandle, void *config);
+serial_manager_status_t Serial_UsbCdcVirtualDeinit(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UsbCdcVirtualWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+serial_manager_status_t Serial_UsbCdcVirtualRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length);
+serial_manager_status_t Serial_UsbCdcVirtualCancelWrite(serial_handle_t serialHandle);
+serial_manager_status_t Serial_UsbCdcVirtualInstallTxCallback(serial_handle_t serialHandle,
+                                                              serial_manager_callback_t callback,
+                                                              void *callbackParam);
+serial_manager_status_t Serial_UsbCdcVirtualInstallRxCallback(serial_handle_t serialHandle,
+                                                              serial_manager_callback_t callback,
+                                                              void *callbackParam);
+void Serial_UsbCdcVirtualIsrFunction(serial_handle_t serialHandle);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __SERIAL_PORT_INTERNAL_H__ */
diff --git a/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_uart.c b/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_uart.c
new file mode 100755
index 0000000..f60320d
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_uart.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "serial_manager.h"
+#include "serial_port_internal.h"
+
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+#include "uart.h"
+
+#include "serial_port_uart.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifndef NDEBUG
+#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
+#undef assert
+#define assert(n)
+#endif
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#define SERIAL_PORT_UART_RECEIVE_DATA_LENGTH 1U
+
+typedef struct _serial_uart_send_state
+{
+    serial_manager_callback_t callback;
+    void *callbackParam;
+    uint8_t *buffer;
+    uint32_t length;
+    volatile uint8_t busy;
+} serial_uart_send_state_t;
+
+typedef struct _serial_uart_recv_state
+{
+    serial_manager_callback_t callback;
+    void *callbackParam;
+    volatile uint8_t busy;
+    uint8_t readBuffer[SERIAL_PORT_UART_RECEIVE_DATA_LENGTH];
+} serial_uart_recv_state_t;
+#endif
+
+typedef struct _serial_uart_state
+{
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serial_uart_send_state_t tx;
+    serial_uart_recv_state_t rx;
+#endif
+    uint8_t usartHandleBuffer[HAL_UART_HANDLE_SIZE];
+} serial_uart_state_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+/* UART user callback */
+static void Serial_UartCallback(hal_uart_handle_t handle, hal_uart_status_t status, void *userData)
+{
+    serial_uart_state_t *serialUartHandle;
+    serial_manager_callback_message_t msg;
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    hal_uart_transfer_t transfer;
+#endif
+
+    if (NULL == userData)
+    {
+        return;
+    }
+
+    serialUartHandle = (serial_uart_state_t *)userData;
+
+    if ((hal_uart_status_t)kStatus_HAL_UartRxIdle == status)
+    {
+        if ((NULL != serialUartHandle->rx.callback))
+        {
+            msg.buffer = &serialUartHandle->rx.readBuffer[0];
+            msg.length = sizeof(serialUartHandle->rx.readBuffer);
+            serialUartHandle->rx.callback(serialUartHandle->rx.callbackParam, &msg, kStatus_SerialManager_Success);
+        }
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+        transfer.data     = &serialUartHandle->rx.readBuffer[0];
+        transfer.dataSize = sizeof(serialUartHandle->rx.readBuffer);
+        if (kStatus_HAL_UartSuccess ==
+            HAL_UartTransferReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
+#else
+        if ((hal_uart_status_t)kStatus_HAL_UartSuccess ==
+            HAL_UartReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                       &serialUartHandle->rx.readBuffer[0], sizeof(serialUartHandle->rx.readBuffer)))
+#endif
+        {
+            serialUartHandle->rx.busy = 1U;
+        }
+        else
+        {
+            serialUartHandle->rx.busy = 0U;
+        }
+    }
+    else if ((hal_uart_status_t)kStatus_HAL_UartTxIdle == status)
+    {
+        if (serialUartHandle->tx.busy != 0U)
+        {
+            serialUartHandle->tx.busy = 0U;
+            if ((NULL != serialUartHandle->tx.callback))
+            {
+                msg.buffer = serialUartHandle->tx.buffer;
+                msg.length = serialUartHandle->tx.length;
+                serialUartHandle->tx.callback(serialUartHandle->tx.callbackParam, &msg, kStatus_SerialManager_Success);
+            }
+        }
+    }
+    else
+    {
+    }
+}
+#endif
+
+serial_manager_status_t Serial_UartInit(serial_handle_t serialHandle, void *serialConfig)
+{
+    serial_uart_state_t *serialUartHandle;
+    serial_port_uart_config_t *uartConfig;
+    hal_uart_config_t config;
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    hal_uart_transfer_t transfer;
+#endif
+#endif
+
+    assert(serialConfig);
+    assert(serialHandle);
+    assert(SERIAL_PORT_UART_HANDLE_SIZE >= sizeof(serial_uart_state_t));
+
+    uartConfig       = (serial_port_uart_config_t *)serialConfig;
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    config.baudRate_Bps = uartConfig->baudRate;
+    config.parityMode   = (hal_uart_parity_mode_t)uartConfig->parityMode;
+    config.stopBitCount = (hal_uart_stop_bit_count_t)uartConfig->stopBitCount;
+    config.enableRx     = uartConfig->enableRx;
+    config.enableTx     = uartConfig->enableTx;
+    config.srcClock_Hz  = uartConfig->clockRate;
+    config.instance     = uartConfig->instance;
+
+    if (kStatus_HAL_UartSuccess != HAL_UartInit(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &config))
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    if (kStatus_HAL_UartSuccess !=
+        HAL_UartTransferInstallCallback(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                        Serial_UartCallback, serialUartHandle))
+#else
+    if (kStatus_HAL_UartSuccess != HAL_UartInstallCallback(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                                           Serial_UartCallback, serialUartHandle))
+#endif
+    {
+        return kStatus_SerialManager_Error;
+    }
+
+    if (uartConfig->enableRx != 0U)
+    {
+        serialUartHandle->rx.busy = 1U;
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+        transfer.data     = &serialUartHandle->rx.readBuffer[0];
+        transfer.dataSize = sizeof(serialUartHandle->rx.readBuffer);
+        if (kStatus_HAL_UartSuccess !=
+            HAL_UartTransferReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
+#else
+        if (kStatus_HAL_UartSuccess !=
+            HAL_UartReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                       &serialUartHandle->rx.readBuffer[0], sizeof(serialUartHandle->rx.readBuffer)))
+#endif
+        {
+            serialUartHandle->rx.busy = 0U;
+            return kStatus_SerialManager_Error;
+        }
+    }
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t Serial_UartDeinit(serial_handle_t serialHandle)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    (void)HAL_UartTransferAbortReceive(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+#else
+    (void)HAL_UartAbortReceive(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+#endif
+#endif
+    (void)HAL_UartDeinit(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+    serialUartHandle->tx.busy = 0U;
+    serialUartHandle->rx.busy = 0U;
+#endif
+
+    return kStatus_SerialManager_Success;
+}
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+
+serial_manager_status_t Serial_UartWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_uart_state_t *serialUartHandle;
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    hal_uart_transfer_t transfer;
+#endif
+
+    assert(serialHandle);
+    assert(buffer);
+    assert(length);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    if (serialUartHandle->tx.busy != 0U)
+    {
+        return kStatus_SerialManager_Busy;
+    }
+    serialUartHandle->tx.busy = 1U;
+
+    serialUartHandle->tx.buffer = buffer;
+    serialUartHandle->tx.length = length;
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    transfer.data     = buffer;
+    transfer.dataSize = length;
+    if (kStatus_HAL_UartSuccess !=
+        HAL_UartTransferSendNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
+#else
+    if (kStatus_HAL_UartSuccess !=
+        HAL_UartSendNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), buffer, length))
+#endif
+    {
+        serialUartHandle->tx.busy = 0U;
+        return kStatus_SerialManager_Error;
+    }
+    return kStatus_SerialManager_Success;
+}
+
+#else
+
+serial_manager_status_t Serial_UartWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+    assert(buffer);
+    assert(length);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    return (serial_manager_status_t)HAL_UartSendBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
+                                                         buffer, length);
+}
+
+serial_manager_status_t Serial_UartRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+    assert(buffer);
+    assert(length);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    return (serial_manager_status_t)HAL_UartReceiveBlocking(
+        ((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), buffer, length);
+}
+
+#endif
+
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+serial_manager_status_t Serial_UartCancelWrite(serial_handle_t serialHandle)
+{
+    serial_uart_state_t *serialUartHandle;
+    serial_manager_callback_message_t msg;
+    uint32_t primask;
+    uint8_t isBusy = 0U;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    primask                   = DisableGlobalIRQ();
+    isBusy                    = serialUartHandle->tx.busy;
+    serialUartHandle->tx.busy = 0U;
+    EnableGlobalIRQ(primask);
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    (void)HAL_UartTransferAbortSend(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+#else
+    (void)HAL_UartAbortSend(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+#endif
+    if (isBusy != 0U)
+    {
+        if ((NULL != serialUartHandle->tx.callback))
+        {
+            msg.buffer = serialUartHandle->tx.buffer;
+            msg.length = serialUartHandle->tx.length;
+            serialUartHandle->tx.callback(serialUartHandle->tx.callbackParam, &msg, kStatus_SerialManager_Canceled);
+        }
+    }
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t Serial_UartInstallTxCallback(serial_handle_t serialHandle,
+                                                     serial_manager_callback_t callback,
+                                                     void *callbackParam)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    serialUartHandle->tx.callback      = callback;
+    serialUartHandle->tx.callbackParam = callbackParam;
+
+    return kStatus_SerialManager_Success;
+}
+
+serial_manager_status_t Serial_UartInstallRxCallback(serial_handle_t serialHandle,
+                                                     serial_manager_callback_t callback,
+                                                     void *callbackParam)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    serialUartHandle->rx.callback      = callback;
+    serialUartHandle->rx.callbackParam = callbackParam;
+
+    return kStatus_SerialManager_Success;
+}
+
+void Serial_UartIsrFunction(serial_handle_t serialHandle)
+{
+    serial_uart_state_t *serialUartHandle;
+
+    assert(serialHandle);
+
+    serialUartHandle = (serial_uart_state_t *)serialHandle;
+
+    HAL_UartIsrFunction(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
+}
+#endif
+
+#endif
diff --git a/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_uart.h b/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_uart.h
new file mode 100755
index 0000000..2d5d21e
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/components/serial_manager/serial_port_uart.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SERIAL_PORT_UART_H__
+#define __SERIAL_PORT_UART_H__
+
+/*!
+ * @addtogroup serial_port_uart
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*! @brief serial port uart handle size*/
+#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
+#define SERIAL_PORT_UART_HANDLE_SIZE (166U)
+#else
+#define SERIAL_PORT_UART_HANDLE_SIZE (4U)
+#endif
+
+/*! @brief serial port uart parity mode*/
+typedef enum _serial_port_uart_parity_mode
+{
+    kSerialManager_UartParityDisabled = 0x0U, /*!< Parity disabled */
+    kSerialManager_UartParityEven     = 0x1U, /*!< Parity even enabled */
+    kSerialManager_UartParityOdd      = 0x2U, /*!< Parity odd enabled */
+} serial_port_uart_parity_mode_t;
+
+/*! @brief serial port uart stop bit count*/
+typedef enum _serial_port_uart_stop_bit_count
+{
+    kSerialManager_UartOneStopBit = 0U, /*!< One stop bit */
+    kSerialManager_UartTwoStopBit = 1U, /*!< Two stop bits */
+} serial_port_uart_stop_bit_count_t;
+
+/*! @brief serial port uart config struct*/
+typedef struct _serial_port_uart_config
+{
+    uint32_t clockRate;                             /*!< clock rate  */
+    uint32_t baudRate;                              /*!< baud rate  */
+    serial_port_uart_parity_mode_t parityMode;      /*!< Parity mode, disabled (default), even, odd */
+    serial_port_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
+    uint8_t instance;                               /*!< Instance (0 - UART0, 1 - UART1, ...), detail information
+                                                         please refer to the SOC corresponding RM. */
+    uint8_t enableRx;                               /*!< Enable RX */
+    uint8_t enableTx;                               /*!< Enable TX */
+} serial_port_uart_config_t;
+/*! @} */
+#endif /* __SERIAL_PORT_UART_H__ */
diff --git a/third_party/nxp/K32W061DK6/components/uart/uart.h b/third_party/nxp/K32W061DK6/components/uart/uart.h
new file mode 100755
index 0000000..11db5c4
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/components/uart/uart.h
@@ -0,0 +1,475 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HAL_UART_ADAPTER_H__
+#define __HAL_UART_ADAPTER_H__
+
+#if defined(FSL_RTOS_FREE_RTOS)
+#include "FreeRTOS.h"
+#endif
+
+/*!
+ * @addtogroup UART_Adapter
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Enable or disable UART adapter non-blocking mode (1 - enable, 0 - disable) */
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+#define UART_ADAPTER_NON_BLOCKING_MODE (1U)
+#else
+#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
+#define UART_ADAPTER_NON_BLOCKING_MODE (0U)
+#else
+#define UART_ADAPTER_NON_BLOCKING_MODE SERIAL_MANAGER_NON_BLOCKING_MODE
+#endif
+#endif
+
+#if defined(__GIC_PRIO_BITS)
+#define HAL_UART_ISR_PRIORITY (25U)
+#else
+#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
+#define HAL_UART_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
+#else
+/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
+ * The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
+ * priority is 3 (2^2 - 1). So, the default value is 3.
+ */
+#define HAL_UART_ISR_PRIORITY (3U)
+#endif
+#endif
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+#define HAL_UART_HANDLE_SIZE (90U)
+#else
+#define HAL_UART_HANDLE_SIZE (4U)
+#endif
+
+/*! @brief Whether enable transactional function of the UART. (0 - disable, 1 - enable) */
+#define HAL_UART_TRANSFER_MODE (0U)
+
+typedef void *hal_uart_handle_t;
+
+/*! @brief UART status */
+typedef enum _hal_uart_status
+{
+    kStatus_HAL_UartSuccess = kStatus_Success,                       /*!< Successfully */
+    kStatus_HAL_UartTxBusy  = MAKE_STATUS(kStatusGroup_HAL_UART, 1), /*!< TX busy */
+    kStatus_HAL_UartRxBusy  = MAKE_STATUS(kStatusGroup_HAL_UART, 2), /*!< RX busy */
+    kStatus_HAL_UartTxIdle  = MAKE_STATUS(kStatusGroup_HAL_UART, 3), /*!< HAL UART transmitter is idle. */
+    kStatus_HAL_UartRxIdle  = MAKE_STATUS(kStatusGroup_HAL_UART, 4), /*!< HAL UART receiver is idle */
+    kStatus_HAL_UartBaudrateNotSupport =
+        MAKE_STATUS(kStatusGroup_HAL_UART, 5), /*!< Baudrate is not support in current clock source */
+    kStatus_HAL_UartProtocolError = MAKE_STATUS(
+        kStatusGroup_HAL_UART,
+        6),                                                        /*!< Error occurs for Noise, Framing, Parity, etc.
+                                                                        For transactional transfer, The up layer needs to abort the transfer and then starts again */
+    kStatus_HAL_UartError = MAKE_STATUS(kStatusGroup_HAL_UART, 7), /*!< Error occurs on HAL UART */
+} hal_uart_status_t;
+
+/*! @brief UART parity mode. */
+typedef enum _hal_uart_parity_mode
+{
+    kHAL_UartParityDisabled = 0x0U, /*!< Parity disabled */
+    kHAL_UartParityEven     = 0x1U, /*!< Parity even enabled */
+    kHAL_UartParityOdd      = 0x2U, /*!< Parity odd enabled */
+} hal_uart_parity_mode_t;
+
+/*! @brief UART stop bit count. */
+typedef enum _hal_uart_stop_bit_count
+{
+    kHAL_UartOneStopBit = 0U, /*!< One stop bit */
+    kHAL_UartTwoStopBit = 1U, /*!< Two stop bits */
+} hal_uart_stop_bit_count_t;
+
+/*! @brief UART configuration structure. */
+typedef struct _hal_uart_config
+{
+    uint32_t srcClock_Hz;                   /*!< Source clock */
+    uint32_t baudRate_Bps;                  /*!< Baud rate  */
+    hal_uart_parity_mode_t parityMode;      /*!< Parity mode, disabled (default), even, odd */
+    hal_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
+    uint8_t enableRx;                       /*!< Enable RX */
+    uint8_t enableTx;                       /*!< Enable TX */
+    uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information please refer to the
+                           SOC corresponding RM.
+                           Invalid instance value will cause initialization failure. */
+} hal_uart_config_t;
+
+/*! @brief UART transfer callback function. */
+typedef void (*hal_uart_transfer_callback_t)(hal_uart_handle_t handle, hal_uart_status_t status, void *callbackParam);
+
+/*! @brief UART transfer structure. */
+typedef struct _hal_uart_transfer
+{
+    uint8_t *data;   /*!< The buffer of data to be transfer.*/
+    size_t dataSize; /*!< The byte count to be transfer. */
+} hal_uart_transfer_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Initializes a UART instance with the UART handle and the user configuration structure.
+ *
+ * This function configures the UART module with user-defined settings. The user can configure the configuration
+ * structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by
+ * the caller. Example below shows how to use this API to configure the UART.
+ *  @code
+ *   uint8_t g_UartHandleBuffer[HAL_UART_HANDLE_SIZE];
+ *   hal_uart_handle_t g_UartHandle = &g_UartHandleBuffer[0];
+ *   hal_uart_config_t config;
+ *   config.srcClock_Hz = 48000000;
+ *   config.baudRate_Bps = 115200U;
+ *   config.parityMode = kHAL_UartParityDisabled;
+ *   config.stopBitCount = kHAL_UartOneStopBit;
+ *   config.enableRx = 1;
+ *   config.enableTx = 1;
+ *   config.instance = 0;
+ *   HAL_UartInit(g_UartHandle, &config);
+ *  @endcode
+ *
+ * @param handle Pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by the caller.
+ * @param config Pointer to user-defined configuration structure.
+ * @retval kStatus_HAL_UartBaudrateNotSupport Baudrate is not support in current clock source.
+ * @retval kStatus_HAL_UartSuccess UART initialization succeed
+ */
+hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, hal_uart_config_t *config);
+
+/*!
+ * @brief Deinitializes a UART instance.
+ *
+ * This function waits for TX complete, disables TX and RX, and disables the UART clock.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_HAL_UartSuccess UART de-initialization succeed
+ */
+hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle);
+
+/*! @}*/
+
+/*!
+ * @name Blocking bus Operations
+ * @{
+ */
+
+/*!
+ * @brief Reads RX data register using a blocking method.
+ *
+ * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
+ * have data, and reads data from the RX register.
+ *
+ * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking
+ * cannot be used at the same time.
+ * And, the function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of this function.
+ *
+ * @param handle UART handle pointer.
+ * @param data Start address of the buffer to store the received data.
+ * @param length Size of the buffer.
+ * @retval kStatus_HAL_UartError An error occurred while receiving data.
+ * @retval kStatus_HAL_UartParityError A parity error occurred while receiving data.
+ * @retval kStatus_HAL_UartSuccess Successfully received all data.
+ */
+hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
+
+/*!
+ * @brief Writes to the TX register using a blocking method.
+ *
+ * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
+ * to have room and writes data to the TX buffer.
+ *
+ * @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking
+ * cannot be used at the same time.
+ * And, the function #HAL_UartTransferAbortSend cannot be used to abort the transmission of this function.
+ *
+ * @param handle UART handle pointer.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ * @retval kStatus_HAL_UartSuccess Successfully sent all data.
+ */
+hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length);
+
+/*! @}*/
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+
+/*!
+ * @name Transactional
+ * @note The transactional API and the functional API cannot be used at the same time. The macro
+ * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
+ * functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
+ * @{
+ */
+
+/*!
+ * @brief Installs a callback and callback parameter.
+ *
+ * This function is used to install the callback and callback parameter for UART module.
+ * When any status of the UART changed, the driver will notify the upper layer by the installed callback
+ * function. And the status is also passed as status parameter when the callback is called.
+ *
+ * @param handle UART handle pointer.
+ * @param callback The callback function.
+ * @param callbackParam The parameter of the callback function.
+ * @retval kStatus_HAL_UartSuccess Successfully install the callback.
+ */
+hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
+                                                  hal_uart_transfer_callback_t callback,
+                                                  void *callbackParam);
+
+/*!
+ * @brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be received.
+ * The receive request is saved by the UART driver.
+ * When the new data arrives, the receive request is serviced first.
+ * When all data is received, the UART driver notifies the upper layer
+ * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
+ *
+ * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking
+ * cannot be used at the same time.
+ *
+ * @param handle UART handle pointer.
+ * @param transfer UART transfer structure, see #hal_uart_transfer_t.
+ * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
+ * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
+ * @retval kStatus_HAL_UartError An error occurred.
+ */
+hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
+
+/*!
+ * @brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the ISR, the UART driver calls the callback
+ * function and passes the @ref kStatus_UART_TxIdle as status parameter.
+ *
+ * @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking
+ * cannot be used at the same time.
+ *
+ * @param handle UART handle pointer.
+ * @param transfer UART transfer structure. See #hal_uart_transfer_t.
+ * @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
+ * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
+ * @retval kStatus_HAL_UartError An error occurred.
+ */
+hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
+
+/*!
+ * @brief Gets the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * @param handle UART handle pointer.
+ * @param count Receive bytes count.
+ * @retval kStatus_HAL_UartError An error occurred.
+ * @retval kStatus_Success Get successfully through the parameter \p count.
+ */
+hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count);
+
+/*!
+ * @brief Gets the number of bytes written to the UART TX register.
+ *
+ * This function gets the number of bytes written to the UART TX
+ * register by using the interrupt method.
+ *
+ * @param handle UART handle pointer.
+ * @param count Send bytes count.
+ * @retval kStatus_HAL_UartError An error occurred.
+ * @retval kStatus_Success Get successfully through the parameter \p count.
+ */
+hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count);
+
+/*!
+ * @brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
+ * how many bytes are not received yet.
+ *
+ * @note The function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of
+ * the function #HAL_UartReceiveBlocking.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_Success Get successfully abort the receiving.
+ */
+hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle);
+
+/*!
+ * @brief Aborts the interrupt-driven data sending.
+ *
+ * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
+ * how many bytes are not sent out.
+ *
+ * @note The function #HAL_UartTransferAbortSend cannot be used to abort the transmission of
+ * the function #HAL_UartSendBlocking.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_Success Get successfully abort the sending.
+ */
+hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle);
+
+/*! @}*/
+
+#else
+
+/*!
+ * @name Functional API with non-blocking mode.
+ * @note The functional API and the transactional API cannot be used at the same time. The macro
+ * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
+ * functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
+ * @{
+ */
+
+/*!
+ * @brief Installs a callback and callback parameter.
+ *
+ * This function is used to install the callback and callback parameter for UART module.
+ * When non-blocking sending or receiving finished, the adapter will notify the upper layer by the installed callback
+ * function. And the status is also passed as status parameter when the callback is called.
+ *
+ * @param handle UART handle pointer.
+ * @param callback The callback function.
+ * @param callbackParam The parameter of the callback function.
+ * @retval kStatus_HAL_UartSuccess Successfully install the callback.
+ */
+hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
+                                          hal_uart_transfer_callback_t callback,
+                                          void *callbackParam);
+
+/*!
+ * @brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be received.
+ * The receive request is saved by the UART adapter.
+ * When the new data arrives, the receive request is serviced first.
+ * When all data is received, the UART adapter notifies the upper layer
+ * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
+ *
+ * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartReceiveNonBlocking
+ * cannot be used at the same time.
+ *
+ * @param handle UART handle pointer.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
+ * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
+ * @retval kStatus_HAL_UartError An error occurred.
+ */
+hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
+
+/*!
+ * @brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the ISR, the UART driver calls the callback
+ * function and passes the @ref kStatus_UART_TxIdle as status parameter.
+ *
+ * @note The function #HAL_UartSendBlocking and the function #HAL_UartSendNonBlocking
+ * cannot be used at the same time.
+ *
+ * @param handle UART handle pointer.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ * @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
+ * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
+ * @retval kStatus_HAL_UartError An error occurred.
+ */
+hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
+
+/*!
+ * @brief Gets the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * @param handle UART handle pointer.
+ * @param count Receive bytes count.
+ * @retval kStatus_HAL_UartError An error occurred.
+ * @retval kStatus_Success Get successfully through the parameter \p count.
+ */
+hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount);
+
+/*!
+ * @brief Gets the number of bytes written to the UART TX register.
+ *
+ * This function gets the number of bytes written to the UART TX
+ * register by using the interrupt method.
+ *
+ * @param handle UART handle pointer.
+ * @param count Send bytes count.
+ * @retval kStatus_HAL_UartError An error occurred.
+ * @retval kStatus_Success Get successfully through the parameter \p count.
+ */
+hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount);
+
+/*!
+ * @brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
+ * how many bytes are not received yet.
+ *
+ * @note The function #HAL_UartAbortReceive cannot be used to abort the transmission of
+ * the function #HAL_UartReceiveBlocking.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_Success Get successfully abort the receiving.
+ */
+hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle);
+
+/*!
+ * @brief Aborts the interrupt-driven data sending.
+ *
+ * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
+ * how many bytes are not sent out.
+ *
+ * @note The function #HAL_UartAbortSend cannot be used to abort the transmission of
+ * the function #HAL_UartSendBlocking.
+ *
+ * @param handle UART handle pointer.
+ * @retval kStatus_Success Get successfully abort the sending.
+ */
+hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle);
+
+/*! @}*/
+
+#endif
+#endif
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+/*!
+ * @brief UART IRQ handle function.
+ *
+ * This function handles the UART transmit and receive IRQ request.
+ *
+ * @param handle UART handle pointer.
+ */
+void HAL_UartIsrFunction(hal_uart_handle_t handle);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+/*! @}*/
+#endif /* __HAL_UART_ADAPTER_H__ */
diff --git a/third_party/nxp/K32W061DK6/components/uart/usart_adapter.c b/third_party/nxp/K32W061DK6/components/uart/usart_adapter.c
new file mode 100755
index 0000000..9b04160
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/components/uart/usart_adapter.c
@@ -0,0 +1,629 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_usart.h"
+#include "fsl_flexcomm.h"
+
+#include "uart.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifndef NDEBUG
+#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
+#undef assert
+#define assert(n)
+#endif
+#endif
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+/*! @brief uart RX state structure. */
+typedef struct _hal_uart_receive_state
+{
+    volatile uint8_t *buffer;
+    volatile uint32_t bufferLength;
+    volatile uint32_t bufferSofar;
+} hal_uart_receive_state_t;
+
+/*! @brief uart TX state structure. */
+typedef struct _hal_uart_send_state
+{
+    volatile uint8_t *buffer;
+    volatile uint32_t bufferLength;
+    volatile uint32_t bufferSofar;
+} hal_uart_send_state_t;
+#endif
+/*! @brief uart state structure. */
+typedef struct _hal_uart_state
+{
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+    hal_uart_transfer_callback_t callback;
+    void *callbackParam;
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    usart_handle_t hardwareHandle;
+#endif
+    hal_uart_receive_state_t rx;
+    hal_uart_send_state_t tx;
+#endif
+    uint8_t instance;
+} hal_uart_state_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+static USART_Type *const s_UsartAdapterBase[] = USART_BASE_PTRS;
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+
+#if !(defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+/* Array of USART IRQ number. */
+static const IRQn_Type s_UsartIRQ[] = USART_IRQS;
+#endif
+
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+static hal_uart_status_t HAL_UartGetStatus(status_t status)
+{
+    hal_uart_status_t uartStatus = kStatus_HAL_UartError;
+    switch (status)
+    {
+        case kStatus_Success:
+            uartStatus = kStatus_HAL_UartSuccess;
+            break;
+        case kStatus_USART_TxBusy:
+            uartStatus = kStatus_HAL_UartTxBusy;
+            break;
+        case kStatus_USART_RxBusy:
+            uartStatus = kStatus_HAL_UartRxBusy;
+            break;
+        case kStatus_USART_TxIdle:
+            uartStatus = kStatus_HAL_UartTxIdle;
+            break;
+        case kStatus_USART_RxIdle:
+            uartStatus = kStatus_HAL_UartRxIdle;
+            break;
+        case kStatus_USART_BaudrateNotSupport:
+            uartStatus = kStatus_HAL_UartBaudrateNotSupport;
+            break;
+        case kStatus_USART_NoiseError:
+        case kStatus_USART_FramingError:
+        case kStatus_USART_ParityError:
+            uartStatus = kStatus_HAL_UartProtocolError;
+            break;
+        default:
+            break;
+    }
+    return uartStatus;
+}
+#else
+static hal_uart_status_t HAL_UartGetStatus(status_t status)
+{
+    if (kStatus_Success == status)
+    {
+        return kStatus_HAL_UartSuccess;
+    }
+    else
+    {
+        return kStatus_HAL_UartError;
+    }
+}
+#endif
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+static void HAL_UartCallback(USART_Type *base, usart_handle_t *handle, status_t status, void *callbackParam)
+{
+    hal_uart_state_t *uartHandle;
+    hal_uart_status_t uartStatus = HAL_UartGetStatus(status);
+    assert(callbackParam);
+
+    uartHandle = (hal_uart_state_t *)callbackParam;
+
+    if (kStatus_HAL_UartProtocolError == uartStatus)
+    {
+        if (uartHandle->hardwareHandle.rxDataSize)
+        {
+            uartStatus = kStatus_HAL_UartError;
+        }
+    }
+
+    if (uartHandle->callback)
+    {
+        uartHandle->callback(uartHandle, uartStatus, uartHandle->callbackParam);
+    }
+}
+
+#else
+
+static void HAL_UartInterruptHandle(USART_Type *base, void *handle)
+{
+    hal_uart_state_t *uartHandle = (hal_uart_state_t *)handle;
+    uint32_t status;
+    uint8_t instance;
+
+    if (NULL == uartHandle)
+    {
+        return;
+    }
+    instance = uartHandle->instance;
+
+    status = USART_GetStatusFlags(s_UsartAdapterBase[instance]);
+
+    /* Receive data register full */
+    if ((USART_FIFOSTAT_RXNOTEMPTY_MASK & status) &&
+        (USART_GetEnabledInterrupts(s_UsartAdapterBase[instance]) & USART_FIFOINTENSET_RXLVL_MASK))
+    {
+        if (uartHandle->rx.buffer)
+        {
+            uartHandle->rx.buffer[uartHandle->rx.bufferSofar++] = USART_ReadByte(s_UsartAdapterBase[instance]);
+            if (uartHandle->rx.bufferSofar >= uartHandle->rx.bufferLength)
+            {
+                USART_DisableInterrupts(s_UsartAdapterBase[instance],
+                                        USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK);
+                uartHandle->rx.buffer = NULL;
+                if (uartHandle->callback)
+                {
+                    uartHandle->callback(uartHandle, kStatus_HAL_UartRxIdle, uartHandle->callbackParam);
+                }
+            }
+        }
+    }
+
+    /* Send data register empty and the interrupt is enabled. */
+    if ((USART_FIFOSTAT_TXNOTFULL_MASK & status) &&
+        (USART_GetEnabledInterrupts(s_UsartAdapterBase[instance]) & USART_FIFOINTENSET_TXLVL_MASK))
+    {
+        if (uartHandle->tx.buffer)
+        {
+            USART_WriteByte(s_UsartAdapterBase[instance], uartHandle->tx.buffer[uartHandle->tx.bufferSofar++]);
+            if (uartHandle->tx.bufferSofar >= uartHandle->tx.bufferLength)
+            {
+                USART_DisableInterrupts(s_UsartAdapterBase[instance], USART_FIFOINTENCLR_TXLVL_MASK);
+                uartHandle->tx.buffer = NULL;
+                if (uartHandle->callback)
+                {
+                    uartHandle->callback(uartHandle, kStatus_HAL_UartTxIdle, uartHandle->callbackParam);
+                }
+            }
+        }
+    }
+
+#if 1
+    USART_ClearStatusFlags(s_UsartAdapterBase[instance], status);
+#endif
+}
+#endif
+
+#endif
+
+hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, hal_uart_config_t *config)
+{
+    hal_uart_state_t *uartHandle;
+    usart_config_t usartConfig;
+    status_t status;
+    assert(handle);
+    assert(config);
+    assert(config->instance < (sizeof(s_UsartAdapterBase) / sizeof(USART_Type *)));
+    assert(s_UsartAdapterBase[config->instance]);
+
+    if (HAL_UART_HANDLE_SIZE < sizeof(hal_uart_state_t))
+    {
+        return kStatus_HAL_UartError;
+    }
+
+    USART_GetDefaultConfig(&usartConfig);
+    usartConfig.baudRate_Bps = config->baudRate_Bps;
+
+    if (kHAL_UartParityEven == config->parityMode)
+    {
+        usartConfig.parityMode = kUSART_ParityEven;
+    }
+    else if (kHAL_UartParityOdd == config->parityMode)
+    {
+        usartConfig.parityMode = kUSART_ParityOdd;
+    }
+    else
+    {
+        usartConfig.parityMode = kUSART_ParityDisabled;
+    }
+
+    if (kHAL_UartTwoStopBit == config->stopBitCount)
+    {
+        usartConfig.stopBitCount = kUSART_TwoStopBit;
+    }
+    else
+    {
+        usartConfig.stopBitCount = kUSART_OneStopBit;
+    }
+    usartConfig.enableRx    = config->enableRx;
+    usartConfig.enableTx    = config->enableTx;
+    usartConfig.txWatermark = kUSART_TxFifo0;
+    usartConfig.rxWatermark = kUSART_RxFifo1;
+
+    status = USART_Init(s_UsartAdapterBase[config->instance], &usartConfig, config->srcClock_Hz);
+
+    if (kStatus_Success != status)
+    {
+        return HAL_UartGetStatus(status);
+    }
+
+    uartHandle           = (hal_uart_state_t *)handle;
+    uartHandle->instance = config->instance;
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+    USART_TransferCreateHandle(s_UsartAdapterBase[config->instance], &uartHandle->hardwareHandle,
+                               (usart_transfer_callback_t)HAL_UartCallback, handle);
+#else
+    /* Enable interrupt in NVIC. */
+    FLEXCOMM_SetIRQHandler(s_UsartAdapterBase[config->instance], (flexcomm_irq_handler_t)HAL_UartInterruptHandle,
+                           handle);
+    NVIC_SetPriority((IRQn_Type)s_UsartIRQ[config->instance], HAL_UART_ISR_PRIORITY);
+    EnableIRQ(s_UsartIRQ[config->instance]);
+#endif
+
+#endif
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+
+    assert(handle);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    USART_Deinit(s_UsartAdapterBase[uartHandle->instance]);
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(data);
+    assert(length);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+    if (uartHandle->rx.buffer)
+    {
+        return kStatus_HAL_UartRxBusy;
+    }
+#endif
+
+    status = USART_ReadBlocking(s_UsartAdapterBase[uartHandle->instance], data, length);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(data);
+    assert(length);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+    if (uartHandle->tx.buffer)
+    {
+        return kStatus_HAL_UartTxBusy;
+    }
+#endif
+
+    USART_WriteBlocking(s_UsartAdapterBase[uartHandle->instance], data, length);
+
+    return kStatus_HAL_UartSuccess;
+}
+
+#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+
+hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
+                                                  hal_uart_transfer_callback_t callback,
+                                                  void *callbackParam)
+{
+    hal_uart_state_t *uartHandle;
+
+    assert(handle);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    uartHandle->callbackParam = callbackParam;
+    uartHandle->callback      = callback;
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(transfer);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    status = USART_TransferReceiveNonBlocking(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle,
+                                              (usart_transfer_t *)transfer, NULL);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(transfer);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    status = USART_TransferSendNonBlocking(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle,
+                                           (usart_transfer_t *)transfer);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(count);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    status =
+        USART_TransferGetReceiveCount(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count)
+{
+    hal_uart_state_t *uartHandle;
+    status_t status;
+    assert(handle);
+    assert(count);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    status = USART_TransferGetSendCount(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count);
+
+    return HAL_UartGetStatus(status);
+}
+
+hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    USART_TransferAbortReceive(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    USART_TransferAbortSend(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
+
+    return kStatus_HAL_UartSuccess;
+}
+
+#else
+
+/* None transactional API with non-blocking mode. */
+hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
+                                          hal_uart_transfer_callback_t callback,
+                                          void *callbackParam)
+{
+    hal_uart_state_t *uartHandle;
+
+    assert(handle);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    uartHandle->callbackParam = callbackParam;
+    uartHandle->callback      = callback;
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(data);
+    assert(length);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->rx.buffer)
+    {
+        return kStatus_HAL_UartRxBusy;
+    }
+
+    uartHandle->rx.bufferLength = length;
+    uartHandle->rx.bufferSofar  = 0;
+    uartHandle->rx.buffer       = data;
+    USART_EnableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENSET_RXLVL_MASK);
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(data);
+    assert(length);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->tx.buffer)
+    {
+        return kStatus_HAL_UartTxBusy;
+    }
+    uartHandle->tx.bufferLength = length;
+    uartHandle->tx.bufferSofar  = 0;
+    uartHandle->tx.buffer       = (volatile uint8_t *)data;
+    USART_EnableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENSET_TXLVL_MASK);
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(reCount);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->rx.buffer)
+    {
+        *reCount = uartHandle->rx.bufferSofar;
+        return kStatus_HAL_UartSuccess;
+    }
+    return kStatus_HAL_UartError;
+}
+
+hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(seCount);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->tx.buffer)
+    {
+        *seCount = uartHandle->tx.bufferSofar;
+        return kStatus_HAL_UartSuccess;
+    }
+    return kStatus_HAL_UartError;
+}
+
+hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->rx.buffer)
+    {
+        USART_DisableInterrupts(s_UsartAdapterBase[uartHandle->instance],
+                                USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK);
+        uartHandle->rx.buffer = NULL;
+    }
+
+    return kStatus_HAL_UartSuccess;
+}
+
+hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+    if (uartHandle->tx.buffer)
+    {
+        USART_DisableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENCLR_TXLVL_MASK);
+        uartHandle->tx.buffer = NULL;
+    }
+
+    return kStatus_HAL_UartSuccess;
+}
+
+#endif
+
+#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
+
+void HAL_UartIsrFunction(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+#if 0
+    DisableIRQ(s_UsartIRQ[uartHandle->instance]);
+#endif
+    USART_TransferHandleIRQ(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
+#if 0
+    NVIC_SetPriority((IRQn_Type)s_UsartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY);
+    EnableIRQ(s_UsartIRQ[uartHandle->instance]);
+#endif
+}
+
+#else
+
+void HAL_UartIsrFunction(hal_uart_handle_t handle)
+{
+    hal_uart_state_t *uartHandle;
+    assert(handle);
+    assert(!HAL_UART_TRANSFER_MODE);
+
+    uartHandle = (hal_uart_state_t *)handle;
+
+#if 0
+    DisableIRQ(s_UsartIRQ[uartHandle->instance]);
+#endif
+    HAL_UartInterruptHandle(s_UsartAdapterBase[uartHandle->instance], (void *)uartHandle);
+#if 0
+    NVIC_SetPriority((IRQn_Type)s_UsartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY);
+    EnableIRQ(s_UsartIRQ[uartHandle->instance]);
+#endif
+}
+
+#endif
+
+#endif
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/K32W061.h b/third_party/nxp/K32W061DK6/devices/K32W061/K32W061.h
new file mode 100755
index 0000000..fa8ccb7
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/K32W061.h
@@ -0,0 +1,15185 @@
+/*
+** ###################################################################
+**     Processors:          K32W041HN
+**                          K32W061HN
+**
+**     Compilers:           GNU C Compiler
+**                          IAR ANSI C/C++ Compiler for ARM
+**                          Keil ARM C/C++ Compiler
+**                          MCUXpresso Compiler
+**
+**     Reference manual:    K32W061UM_Rev.0.3 20 December 2019
+**     Version:             rev. 1.0, 2019-11-05
+**     Build:               b200228
+**
+**     Abstract:
+**         CMSIS Peripheral Access Layer for K32W061
+**
+**     Copyright 1997-2016 Freescale Semiconductor, Inc.
+**     Copyright 2016-2020 NXP
+**     All rights reserved.
+**
+**     SPDX-License-Identifier: BSD-3-Clause
+**
+**     http:                 www.nxp.com
+**     mail:                 support@nxp.com
+**
+**     Revisions:
+**     - rev. 1.0 (2019-11-05)
+**         Initial version.
+**
+** ###################################################################
+*/
+
+/*!
+ * @file K32W061.h
+ * @version 1.0
+ * @date 2019-11-05
+ * @brief CMSIS Peripheral Access Layer for K32W061
+ *
+ * CMSIS Peripheral Access Layer for K32W061
+ */
+
+#ifndef _K32W061_H_
+#define _K32W061_H_                              /**< Symbol preventing repeated inclusion */
+
+/** Memory map major version (memory maps with equal major version number are
+ * compatible) */
+#define MCU_MEM_MAP_VERSION 0x0100U
+/** Memory map minor version */
+#define MCU_MEM_MAP_VERSION_MINOR 0x0000U
+
+
+/* ----------------------------------------------------------------------------
+   -- Interrupt vector numbers
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Interrupt_vector_numbers Interrupt vector numbers
+ * @{
+ */
+
+/** Interrupt Number Definitions */
+#define NUMBER_OF_INT_VECTORS 72                 /**< Number of interrupts in the Vector table */
+
+typedef enum IRQn {
+  /* Auxiliary constants */
+  NotAvail_IRQn                = -128,             /**< Not available device specific interrupt */
+
+  /* Core interrupts */
+  NonMaskableInt_IRQn          = -14,              /**< Non Maskable Interrupt */
+  HardFault_IRQn               = -13,              /**< Cortex-M4 SV Hard Fault Interrupt */
+  MemoryManagement_IRQn        = -12,              /**< Cortex-M4 Memory Management Interrupt */
+  BusFault_IRQn                = -11,              /**< Cortex-M4 Bus Fault Interrupt */
+  UsageFault_IRQn              = -10,              /**< Cortex-M4 Usage Fault Interrupt */
+  SVCall_IRQn                  = -5,               /**< Cortex-M4 SV Call Interrupt */
+  DebugMonitor_IRQn            = -4,               /**< Cortex-M4 Debug Monitor Interrupt */
+  PendSV_IRQn                  = -2,               /**< Cortex-M4 Pend SV Interrupt */
+  SysTick_IRQn                 = -1,               /**< Cortex-M4 System Tick Interrupt */
+
+  /* Device specific interrupts */
+  WDT_BOD_IRQn                 = 0,                /**< System (BOD, Watchdog Timer, Flash controller) interrupt */
+  DMA0_IRQn                    = 1,                /**< DMA interrupt */
+  GINT0_IRQn                   = 2,                /**< GPIO global interrupt */
+  CIC_IRB_IRQn                 = 3,                /**< Infra Red Blaster interrupt */
+  PIN_INT0_IRQn                = 4,                /**< Pin Interrupt and Pattern matching 0 */
+  PIN_INT1_IRQn                = 5,                /**< Pin Interrupt and Pattern matching 1 */
+  PIN_INT2_IRQn                = 6,                /**< Pin Interrupt and Pattern matching 2 */
+  PIN_INT3_IRQn                = 7,                /**< Pin Interrupt and Pattern matching 3 */
+  SPIFI0_IRQn                  = 8,                /**< Quad-SPI flash interface interrupt */
+  CTIMER0_IRQn                 = 9,                /**< Counter/Timer 0 interrupt */
+  CTIMER1_IRQn                 = 10,               /**< Counter/Timer 1 interrupt */
+  FLEXCOMM0_IRQn               = 11,               /**< Flexcomm Interface 0 (USART0, FLEXCOMM0) */
+  FLEXCOMM1_IRQn               = 12,               /**< Flexcomm Interface 1 (USART1, FLEXCOMM1) */
+  FLEXCOMM2_IRQn               = 13,               /**< Flexcomm Interface 2 (I2C0, FLEXCOMM2) */
+  FLEXCOMM3_IRQn               = 14,               /**< Flexcomm Interface 3 (I2C1, FLEXCOMM3) */
+  FLEXCOMM4_IRQn               = 15,               /**< Flexcomm Interface 4 (SPI0, FLEXCOMM4) */
+  FLEXCOMM5_IRQn               = 16,               /**< Flexcomm Interface 5 (SPI5, FLEXCOMM) */
+  PWM0_IRQn                    = 17,               /**< PWM channel 0 interrupt */
+  PWM1_IRQn                    = 18,               /**< PWM channel 1 interrupt */
+  PWM2_IRQn                    = 19,               /**< PWM channel 2 interrupt */
+  PWM3_IRQn                    = 20,               /**< PWM channel 3 interrupt */
+  PWM4_IRQn                    = 21,               /**< PWM channel 4 interrupt */
+  PWM5_IRQn                    = 22,               /**< PWM channel 5 interrupt */
+  PWM6_IRQn                    = 23,               /**< PWM channel 6  interrupt */
+  PWM7_IRQn                    = 24,               /**< PWM channel 7 interrupt */
+  PWM8_IRQn                    = 25,               /**< PWM channel 8 interrupt */
+  PWM9_IRQn                    = 26,               /**< PWM channel 9 interrupt */
+  PWM10_IRQn                   = 27,               /**< PWM channel 10 interrupt */
+  FLEXCOMM6_IRQn               = 28,               /**< Flexcomm Interface6 (I2C2, FLEXCOMM6) */
+  RTC_IRQn                     = 29,               /**< Real Time Clock interrupt */
+  NFCTag_IRQn                  = 30,               /**< NFC Tag interrupt */
+  MAILBOX_IRQn                 = 31,               /**< Mailbox interrupts, Wake-up from Deep Sleep interrupt */
+  ADC0_SEQA_IRQn               = 32,               /**< ADC Sequence A interrupt */
+  ADC0_SEQB_IRQn               = 33,               /**< ADC Sequence B interrupt */
+  ADC0_THCMP_IRQn              = 34,               /**< ADC Threshold compare and overrun interrupt */
+  DMIC0_IRQn                   = 35,               /**< DMIC interrupt */
+  HWVAD0_IRQn                  = 36,               /**< Hardware Voice activity detection interrupt */
+  BLE_DP_IRQn                  = 37,               /**< BLE Data Path interrupt */
+  BLE_DP0_IRQn                 = 38,               /**< BLE Data Path interrupt 0 */
+  BLE_DP1_IRQn                 = 39,               /**< BLE Data Path interrupt 1 */
+  BLE_DP2_IRQn                 = 40,               /**< BLE Data Path interrupt 2 */
+  BLE_LL_ALL_IRQn              = 41,               /**< All BLE link layer interrupts */
+  ZIGBEE_MAC_IRQn              = 42,               /**< Zigbee MAC interrupt */
+  ZIGBEE_MODEM_IRQn            = 43,               /**< Zigbee MoDem interrupt */
+  RFP_TMU_IRQn                 = 44,               /**< RFP Timing Managemnt Unit (TMU) interrupt */
+  RFP_AGC_IRQn                 = 45,               /**< RFP AGC interrupt */
+  ISO7816_IRQn                 = 46,               /**< ISO7816 controller interrupt */
+  ANA_COMP_IRQn                = 47,               /**< Analog Comparator interrupt */
+  WAKE_UP_TIMER0_IRQn          = 48,               /**< Wake up Timer 0 interrupt */
+  WAKE_UP_TIMER1_IRQn          = 49,               /**< Wake up Timer 1 interrupt */
+  PVTVF0_AMBER_IRQn            = 50,               /**< PVT Monitor interrupt */
+  PVTVF0_RED_IRQn              = 51,               /**< PVT Monitor interrupt */
+  PVTVF1_AMBER_IRQn            = 52,               /**< PVT Monitor interrupt */
+  PVTVF1_RED_IRQn              = 53,               /**< PVT Monitor interrupt */
+  BLE_WAKE_UP_TIMER_IRQn       = 54,               /**< BLE Wake up Timer interrupt */
+  SHA_IRQn                     = 55                /**< SHA interrupt */
+} IRQn_Type;
+
+/*!
+ * @}
+ */ /* end of group Interrupt_vector_numbers */
+
+
+/* ----------------------------------------------------------------------------
+   -- Cortex M4 Core Configuration
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Cortex_Core_Configuration Cortex M4 Core Configuration
+ * @{
+ */
+
+#define __MPU_PRESENT                  1         /**< Defines if an MPU is present or not */
+#define __NVIC_PRIO_BITS               3         /**< Number of priority bits implemented in the NVIC */
+#define __Vendor_SysTickConfig         0         /**< Vendor specific implementation of SysTickConfig is defined */
+#define __FPU_PRESENT                  0         /**< Defines if an FPU is present or not */
+
+#include "core_cm4.h"                  /* Core Peripheral Access Layer */
+#include "system_K32W061.h"            /* Device specific configuration file */
+
+/*!
+ * @}
+ */ /* end of group Cortex_Core_Configuration */
+
+
+/* ----------------------------------------------------------------------------
+   -- Mapping Information
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Mapping_Information Mapping Information
+ * @{
+ */
+
+/** Mapping Information */
+/*!
+ * @addtogroup dma_request
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*!
+ * @brief Structure for the DMA hardware request
+ *
+ * Defines the structure for the DMA hardware request collections. The user can configure the
+ * hardware request to trigger the DMA transfer accordingly. The index
+ * of the hardware request varies according  to the to SoC.
+ */
+typedef enum _dma_request_source
+{
+    kDmaRequestUsart0Rx             = 0U,          /**< USART 0 RX */
+    kDmaRequestUsart0Tx             = 1U,          /**< USART 0 TX */
+    kDmaRequestUsart1Rx             = 2U,          /**< USART 1 RX */
+    kDmaRequestUsart1Tx             = 3U,          /**< USART 1 TX */
+    kDmaRequestI2c0Slave            = 4U,          /**< I2C 0 Slave */
+    kDmaRequestI2c0Master           = 5U,          /**< I2C 0 Master */
+    kDmaRequestI2c1Slave            = 6U,          /**< I2C 1 Slave */
+    kDmaRequestI2c1Master           = 7U,          /**< I2C 1 Master */
+    kDmaRequestSpi0Rx               = 8U,          /**< SPI 0 RX */
+    kDmaRequestSpi0Tx               = 9U,          /**< SPI 0 TX */
+    kDmaRequestSpi1Rx               = 10U,         /**< SPI 1 RX */
+    kDmaRequestSpi1Tx               = 11U,         /**< SPI 1 TX */
+    kDmaRequestSPIFI                = 12U,         /**< SPIFI */
+    kDmaRequestI2c2Slave            = 13U,         /**< I2C 2 Slave */
+    kDmaRequestI2c2Master           = 14U,         /**< I2C 2 Master */
+    kDmaRequestDMIC0                = 15U,         /**< DMIC Channel 0 */
+    kDmaRequestDMIC1                = 16U,         /**< DMIC Channel 1 */
+    kDmaRequestHashRx               = 17U,         /**< Hash RX */
+    kDmaRequestHashTx               = 18U,         /**< Hash TX */
+} dma_request_source_t;
+
+/* @} */
+
+
+/*!
+ * @}
+ */ /* end of group Mapping_Information */
+
+
+/* ----------------------------------------------------------------------------
+   -- Device Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Peripheral_access_layer Device Peripheral Access Layer
+ * @{
+ */
+
+
+/*
+** Start of section using anonymous unions
+*/
+
+#if defined(__ARMCC_VERSION)
+  #if (__ARMCC_VERSION >= 6010050)
+    #pragma clang diagnostic push
+  #else
+    #pragma push
+    #pragma anon_unions
+  #endif
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#elif defined(__IAR_SYSTEMS_ICC__)
+  #pragma language=extended
+#else
+  #error Not supported compiler type
+#endif
+
+/* ----------------------------------------------------------------------------
+   -- ADC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer
+ * @{
+ */
+
+/** ADC - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls., offset: 0x0 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t SEQ_CTRL[1];                       /**< ADC Conversion Sequence-A control register: Controls triggering and channel selection for conversion sequence-A. Also specifies interrupt mode for sequence-A., array offset: 0x8, array step: 0x4 */
+       uint8_t RESERVED_1[4];
+  __I  uint32_t SEQ_GDAT[1];                       /**< ADC Sequence-A Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-A., array offset: 0x10, array step: 0x4 */
+       uint8_t RESERVED_2[12];
+  __I  uint32_t DAT[8];                            /**< ADC Channel X [0:7] Data register. This register contains the result of the most recent conversion completed on channel X [0:7] ., array offset: 0x20, array step: 0x4 */
+       uint8_t RESERVED_3[16];
+  __IO uint32_t THR0_LOW;                          /**< ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x50 */
+  __IO uint32_t THR1_LOW;                          /**< ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x54 */
+  __IO uint32_t THR0_HIGH;                         /**< ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x58 */
+  __IO uint32_t THR1_HIGH;                         /**< ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x5C */
+  __IO uint32_t CHAN_THRSEL;                       /**< ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel, offset: 0x60 */
+  __IO uint32_t INTEN;                             /**< ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated., offset: 0x64 */
+  __IO uint32_t FLAGS;                             /**< ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers)., offset: 0x68 */
+  __IO uint32_t STARTUP;                           /**< ADC Startup register (typically only used by the ADC API)., offset: 0x6C */
+  __IO uint32_t GPADC_CTRL0;                       /**< Second ADC Control register : ADC internal LDO (within ADC sub-system), offset: 0x70 */
+  __IO uint32_t GPADC_CTRL1;                       /**< Third ADC Control register : ADC internal gain and offset, offset: 0x74 */
+} ADC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- ADC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ADC_Register_Masks ADC Register Masks
+ * @{
+ */
+
+/*! @name CTRL - ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls. */
+/*! @{ */
+#define ADC_CTRL_CLKDIV_MASK                     (0xFFU)
+#define ADC_CTRL_CLKDIV_SHIFT                    (0U)
+/*! CLKDIV - Reserved. No changes to this fiedl are necessary.
+ */
+#define ADC_CTRL_CLKDIV(x)                       (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_CLKDIV_SHIFT)) & ADC_CTRL_CLKDIV_MASK)
+#define ADC_CTRL_ASYNMODE_MASK                   (0x100U)
+#define ADC_CTRL_ASYNMODE_SHIFT                  (8U)
+/*! ASYNMODE - Select clock mode. 0: Synchronous mode. Not Supported. 1: Asynchronous mode. The ADC
+ *    clock is based on the output of the ADC clock divider ADCCLKSEL in the SYSCON block.
+ */
+#define ADC_CTRL_ASYNMODE(x)                     (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_ASYNMODE_SHIFT)) & ADC_CTRL_ASYNMODE_MASK)
+#define ADC_CTRL_RESOL_MASK                      (0x600U)
+#define ADC_CTRL_RESOL_SHIFT                     (9U)
+/*! RESOL - The number of bits of ADC resolution. Note, whatever the resolution setting, the ADC
+ *    data will always be shifted to use the MSBs of any ADC data words. Accuracy can be reduced to
+ *    achieve higher conversion rates. A single conversion (including one conversion in a burst or
+ *    sequence) requires the selected number of bits of resolution plus 3 ADC clocks. Remark: This field
+ *    must only be altered when the ADC is fully idle. Changing it during any kind of ADC operation
+ *    may have unpredictable results. Remark: ADC clock frequencies for various resolutions must
+ *    not exceed: - 5x the system clock rate for 12-bit resolution. - 4.3x the system clock rate for
+ *    10-bit resolution. - 3.6x the system clock for 8-bit resolution. - 3x the bus clock rate for
+ *    6-bit resolution. Settings: 0x3: 6-bit resolution. An ADC conversion requires 9 ADC clocks, plus
+ *    any clocks specified by the TSAMP field; 0x2: 8-bit resolution. An ADC conversion requires 11
+ *    ADC clocks, plus any clocks specified by the TSAMP field; 0x1:10-bit resolution. An ADC
+ *    conversion requires 13 ADC clocks, plus any clocks specified by the TSAMP field; 0x0: 12-bit
+ *    resolution. An ADC conversion requires 15 ADC clocks, plus any clocks specified by the TSAMP field.
+ */
+#define ADC_CTRL_RESOL(x)                        (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_RESOL_SHIFT)) & ADC_CTRL_RESOL_MASK)
+#define ADC_CTRL_RESOL_MASK_DIS_MASK             (0x800U)
+#define ADC_CTRL_RESOL_MASK_DIS_SHIFT            (11U)
+/*! RESOL_MASK_DIS - According RESOL bit LSB bits are automatickly masked if RESOL_MASK_DIS = 0. If
+ *    RESOL_MASK_DIS = 1, the 12bits comming from ADC are directly connect to register RESULT
+ */
+#define ADC_CTRL_RESOL_MASK_DIS(x)               (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_RESOL_MASK_DIS_SHIFT)) & ADC_CTRL_RESOL_MASK_DIS_MASK)
+#define ADC_CTRL_TSAMP_MASK                      (0x7000U)
+#define ADC_CTRL_TSAMP_SHIFT                     (12U)
+/*! TSAMP - Sample Time. The default sampling period (TSAMP = 000 ) at the start of each conversion
+ *    is 2.5 ADC clock periods. Depending on a variety of factors, including operating conditions
+ *    and the output impedance of the analog source, longer sampling times may be required. The TSAMP
+ *    field should stay to default during application The TSAMP field specifies the number of
+ *    additional ADC clock cycles, from zero to seven, by which the sample period will be extended. The
+ *    total conversion time will increase by the same number of clocks. 000 - The sample period will
+ *    be the default 2.5 ADC clocks. A complete conversion with 12-bits of accuracy will require 15
+ *    clocks. 001- The sample period will be extended by one ADC clock to a total of 3.5 clock
+ *    periods. A complete 12-bit conversion will require 16 clocks. 010 - The sample period will be
+ *    extended by two clocks to 4.5 ADC clock cycles. A complete 12-bit conversion will require 17 ADC
+ *    clocks. ... 111 - The sample period will be extended by seven clocks to 9.5 ADC clock cycles. A
+ *    complete 12-bit conversion will require 22 ADC clocks.
+ */
+#define ADC_CTRL_TSAMP(x)                        (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_TSAMP_SHIFT)) & ADC_CTRL_TSAMP_MASK)
+/*! @} */
+
+/*! @name SEQ_CTRL - ADC Conversion Sequence-A control register: Controls triggering and channel selection for conversion sequence-A. Also specifies interrupt mode for sequence-A. */
+/*! @{ */
+#define ADC_SEQ_CTRL_CHANNELS_MASK               (0xFFU)
+#define ADC_SEQ_CTRL_CHANNELS_SHIFT              (0U)
+/*! CHANNELS - Selects which one or more of the ADC channels will be sampled and converted when this
+ *    sequence is launched. A 1 in any bit of this field will cause the corresponding channel to be
+ *    included in the conversion sequence, where bit 0 corresponds to channel 0, bit 1 to channel 1
+ *    and so forth. Bit 6 is channel 6; the supply monitor. Bit 7 is channel 7; the temperature
+ *    sensor. When this conversion sequence is triggered, either by a hardware trigger or via software
+ *    command, ADC conversions will be performed on each enabled channel, in sequence, beginning
+ *    with the lowest-ordered channel. Remark: This field can ONLY be changed while SEQA_ENA (bit 31)
+ *    is LOW. It is allowed to change this field and set bit 31 in the same write.
+ */
+#define ADC_SEQ_CTRL_CHANNELS(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_CHANNELS_SHIFT)) & ADC_SEQ_CTRL_CHANNELS_MASK)
+#define ADC_SEQ_CTRL_TRIGGER_MASK                (0x3F000U)
+#define ADC_SEQ_CTRL_TRIGGER_SHIFT               (12U)
+/*! TRIGGER - Selects which of the available hardware trigger sources will cause this conversion
+ *    sequence to be initiated. Program the trigger input number in this field. Setting: 0 : PINT0; 1 :
+ *    PWM8; 2 : PWM9; 3 : ARM TX EV. Remark: In order to avoid generating a spurious trigger, it is
+ *    recommended writing to+I32 this field only when SEQA_ENA (bit 31) is low. It is safe to
+ *    change this field and set bit 31 in the same write.
+ */
+#define ADC_SEQ_CTRL_TRIGGER(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGGER_SHIFT)) & ADC_SEQ_CTRL_TRIGGER_MASK)
+#define ADC_SEQ_CTRL_TRIGPOL_MASK                (0x40000U)
+#define ADC_SEQ_CTRL_TRIGPOL_SHIFT               (18U)
+/*! TRIGPOL - Select the polarity of the selected input trigger for this conversion sequence.
+ *    Remark: In order to avoid generating a spurious trigger, it is recommended writing to this field
+ *    only when SEQA_ENA (bit 31) is low. It is safe to change this field and set bit 31 in the same
+ *    write. 0: A negative edge launches the conversion sequence on the selected trigger input. 1: A
+ *    positive edge launches the conversion sequence on the selected trigger input.
+ */
+#define ADC_SEQ_CTRL_TRIGPOL(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGPOL_SHIFT)) & ADC_SEQ_CTRL_TRIGPOL_MASK)
+#define ADC_SEQ_CTRL_SYNCBYPASS_MASK             (0x80000U)
+#define ADC_SEQ_CTRL_SYNCBYPASS_SHIFT            (19U)
+/*! SYNCBYPASS - Setting this bit allows the hardware trigger input to bypass synchronization
+ *    flip-flop stages and therefore shorten the time between the trigger input signal and the start of a
+ *    conversion. There are slightly different criteria for whether or not this bit can be set
+ *    depending on the clock operating mode: Synchronous mode (the ASYNMODE in the CTRL register = 0):
+ *    Synchronization may be bypassed (this bit may be set) if the selected trigger source is already
+ *    synchronous with the main system clock (eg. coming from an on-chip, system-clock-based timer).
+ *    Whether this bit is set or not, a trigger pulse must be maintained for at least one system
+ *    clock period. Asynchronous mode (the ASYNMODE in the CTRL register = 1): Synchronization may be
+ *    bypassed (this bit may be set) if it is certain that the duration of a trigger input pulse
+ *    will be at least one cycle of the ADC clock (regardless of whether the trigger comes from and
+ *    on-chip or off-chip source). If this bit is NOT set, the trigger pulse must at least be
+ *    maintained for one system clock period. 0: Enable trigger synchronization. The hardware trigger bypass
+ *    is not enabled. 1: Bypass trigger synchronization. The hardware trigger bypass is enabled.
+ */
+#define ADC_SEQ_CTRL_SYNCBYPASS(x)               (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SYNCBYPASS_SHIFT)) & ADC_SEQ_CTRL_SYNCBYPASS_MASK)
+#define ADC_SEQ_CTRL_START_BEHAVIOUR_MASK        (0x2000000U)
+#define ADC_SEQ_CTRL_START_BEHAVIOUR_SHIFT       (25U)
+/*! START_BEHAVIOUR - the Start behavior used on gpadc: writing 0 for repeat start after each input
+ *    selection changed, used for seqA with multiple inputs. writing 1 for continuous start, this
+ *    bit is only if seqA is used to have full speed on a single input. Remark: with 0 the word rate
+ *    is divided by two.
+ */
+#define ADC_SEQ_CTRL_START_BEHAVIOUR(x)          (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_START_BEHAVIOUR_SHIFT)) & ADC_SEQ_CTRL_START_BEHAVIOUR_MASK)
+#define ADC_SEQ_CTRL_START_MASK                  (0x4000000U)
+#define ADC_SEQ_CTRL_START_SHIFT                 (26U)
+/*! START - Writing a 1 to this field will launch one pass through this conversion sequence. The
+ *    behavior will be identical to a sequence triggered by a hardware trigger. Do not write 1 to this
+ *    bit if the BURST bit is set. Remark: This bit is only set to a 1 momentarily when written to
+ *    launch a conversion sequence. It will consequently always read back as a zero.
+ */
+#define ADC_SEQ_CTRL_START(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_START_SHIFT)) & ADC_SEQ_CTRL_START_MASK)
+#define ADC_SEQ_CTRL_BURST_MASK                  (0x8000000U)
+#define ADC_SEQ_CTRL_BURST_SHIFT                 (27U)
+/*! BURST - Writing a 1 to this bit will cause this conversion sequence to be continuously cycled
+ *    through. Other sequence A triggers will be ignored while this bit is set. Repeated conversions
+ *    can be halted by clearing this bit. The sequence currently in progress will be completed before
+ *    conversions are terminated. Note that a new sequence could begin just before BURST is cleared.
+ */
+#define ADC_SEQ_CTRL_BURST(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_BURST_SHIFT)) & ADC_SEQ_CTRL_BURST_MASK)
+#define ADC_SEQ_CTRL_SINGLESTEP_MASK             (0x10000000U)
+#define ADC_SEQ_CTRL_SINGLESTEP_SHIFT            (28U)
+/*! SINGLESTEP - When this bit is set, a hardware trigger or a write to the START bit will launch a
+ *    single conversion on the next channel in the sequence instead of the default response of
+ *    launching an entire sequence of conversions. Once all of the channels comprising a sequence have
+ *    been converted, a subsequent trigger will repeat the sequence beginning with the first enabled
+ *    channel. Interrupt generation will still occur either after each individual conversion or at
+ *    the end of the entire sequence, depending on the state of the MODE bit.
+ */
+#define ADC_SEQ_CTRL_SINGLESTEP(x)               (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SINGLESTEP_SHIFT)) & ADC_SEQ_CTRL_SINGLESTEP_MASK)
+#define ADC_SEQ_CTRL_MODE_MASK                   (0x40000000U)
+#define ADC_SEQ_CTRL_MODE_SHIFT                  (30U)
+/*! MODE - Indicates whether the primary method for retrieving conversion results for this sequence
+ *    will be accomplished via reading the global data register (SEQA_GDAT) at the end of each
+ *    conversion, or the individual channel result registers at the end of the entire sequence. Impacts
+ *    when conversion-complete interrupt/DMA trigger for sequence-A will be generated and which
+ *    overrun conditions contribute to an overrun interrupt as described below. 0: End of conversion. The
+ *    sequence A interrupt/DMA trigger will be set at the end of each individual ADC conversion
+ *    performed under sequence A. This flag will mirror the DATAVALID bit in the SEQA_GDAT register.
+ *    The OVERRUN bit in the SEQA_GDAT register will contribute to generation of an overrun
+ *    interrupt/DMA trigger if enabled. 1: End of sequence. The sequence A interrupt/DMA trigger will be set
+ *    when the entire set of sequence-A conversions completes. This flag will need to be explicitly
+ *    cleared by software or by the DMA-clear signal in this mode. The OVERRUN bit in the SEQA_GDAT
+ *    register will NOT contribute to generation of an overrun interrupt/DMA trigger since it is
+ *    assumed this register may not be utilized in this mode.
+ */
+#define ADC_SEQ_CTRL_MODE(x)                     (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_MODE_SHIFT)) & ADC_SEQ_CTRL_MODE_MASK)
+#define ADC_SEQ_CTRL_SEQ_ENA_MASK                (0x80000000U)
+#define ADC_SEQ_CTRL_SEQ_ENA_SHIFT               (31U)
+/*! SEQ_ENA - Sequence Enable. In order to avoid spuriously triggering the sequence, care should be
+ *    taken to only set the SEQA_ENA bit when the selected trigger input is in its INACTIVE state
+ *    (as defined by the TRIGPOL bit). If this condition is not met, the sequence will be triggered
+ *    immediately upon being enabled. Remark: In order to avoid spuriously triggering the sequence,
+ *    care should be taken to only set the SEQA_ENA bit when the selected trigger input is in its
+ *    INACTIVE state (as defined by the TRIGPOL bit). If this condition is not met, the sequence will be
+ *    triggered immediately upon being enabled. 0: Disabled. Sequence A is disabled. Sequence A
+ *    triggers are ignored. If this bit is cleared while sequence A is in progress, the sequence will
+ *    be halted at the end of the current conversion. After the sequence is re-enabled, a new trigger
+ *    will be required to restart the sequence beginning with the next enabled channel. 1: Enabled.
+ *    Sequence A is enabled.
+ */
+#define ADC_SEQ_CTRL_SEQ_ENA(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SEQ_ENA_SHIFT)) & ADC_SEQ_CTRL_SEQ_ENA_MASK)
+/*! @} */
+
+/* The count of ADC_SEQ_CTRL */
+#define ADC_SEQ_CTRL_COUNT                       (1U)
+
+/*! @name SEQ_GDAT - ADC Sequence-A Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-A. */
+/*! @{ */
+#define ADC_SEQ_GDAT_RESULT_MASK                 (0xFFF0U)
+#define ADC_SEQ_GDAT_RESULT_SHIFT                (4U)
+/*! RESULT - This field contains the 12-bit ADC conversion result from the most recent conversion
+ *    performed under conversion sequence associated with this register. DATAVALID = 1 indicates that
+ *    this result has not yet been read. If less than 12-bit resolultion is used the ADC result
+ *    occupies the upper MSBs and unused LSBs should be ignored.
+ */
+#define ADC_SEQ_GDAT_RESULT(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_RESULT_SHIFT)) & ADC_SEQ_GDAT_RESULT_MASK)
+#define ADC_SEQ_GDAT_THCMPRANGE_MASK             (0x30000U)
+#define ADC_SEQ_GDAT_THCMPRANGE_SHIFT            (16U)
+/*! THCMPRANGE - Threshold Range Comparison result. 0x0 = In Range: The last completed conversion
+ *    was greater than or equal to the value programmed into the designated LOW threshold register
+ *    (THRn_LOW) but less than or equal to the value programmed into the designated HIGH threshold
+ *    register (THRn_HIGH). 0x1 = Below Range: The last completed conversion on was less than the value
+ *    programmed into the designated LOW threshold register (THRn_LOW). 0x2 = Above Range: The last
+ *    completed conversion was greater than the value programmed into the designated HIGH threshold
+ *    register (THRn_HIGH). 0x3 = Reserved.
+ */
+#define ADC_SEQ_GDAT_THCMPRANGE(x)               (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPRANGE_SHIFT)) & ADC_SEQ_GDAT_THCMPRANGE_MASK)
+#define ADC_SEQ_GDAT_THCMPCROSS_MASK             (0xC0000U)
+#define ADC_SEQ_GDAT_THCMPCROSS_SHIFT            (18U)
+/*! THCMPCROSS - Threshold Crossing Comparison result. 0x0 = No threshold Crossing detected: The
+ *    most recent completed conversion on this channel had the same relationship (above or below) to
+ *    the threshold value established by the designated LOW threshold register (THRn_LOW) as did the
+ *    previous conversion on this channel. 0x1 = Reserved. 0x2 = Downward Threshold Crossing
+ *    Detected. Indicates that a threshold crossing in the downward direction has occurred - i.e. the
+ *    previous sample on this channel was above the threshold value established by the designated LOW
+ *    threshold register (THRn_LOW) and the current sample is below that threshold. 0x3 = Upward
+ *    Threshold Crossing Detected. Indicates that a threshold crossing in the upward direction has occurred
+ *    - i.e. the previous sample on this channel was below the threshold value established by the
+ *    designated LOW threshold register (THRn_LOW) and the current sample is above that threshold.
+ */
+#define ADC_SEQ_GDAT_THCMPCROSS(x)               (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPCROSS_SHIFT)) & ADC_SEQ_GDAT_THCMPCROSS_MASK)
+#define ADC_SEQ_GDAT_CHN_MASK                    (0x3C000000U)
+#define ADC_SEQ_GDAT_CHN_SHIFT                   (26U)
+/*! CHN - These bits contain the channel from which the RESULT bits were converted (e.g. 0000
+ *    identifies channel 0, 0001 channel 1, etc.).
+ */
+#define ADC_SEQ_GDAT_CHN(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_CHN_SHIFT)) & ADC_SEQ_GDAT_CHN_MASK)
+#define ADC_SEQ_GDAT_OVERRUN_MASK                (0x40000000U)
+#define ADC_SEQ_GDAT_OVERRUN_SHIFT               (30U)
+/*! OVERRUN - This bit is set if a new conversion result is loaded into the RESULT field before a
+ *    previous result has been read - i.e. while the DATAVALID bit is set. This bit is cleared, along
+ *    with the DATAVALID bit, whenever this register is read. This bit will contribute to an overrun
+ *    interrupt/DMA trigger if the MODE bit (in SEQA_CTRL) for the corresponding sequence is set to
+ *    0 (and if the overrun interrupt is enabled).
+ */
+#define ADC_SEQ_GDAT_OVERRUN(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_OVERRUN_SHIFT)) & ADC_SEQ_GDAT_OVERRUN_MASK)
+#define ADC_SEQ_GDAT_DATAVALID_MASK              (0x80000000U)
+#define ADC_SEQ_GDAT_DATAVALID_SHIFT             (31U)
+/*! DATAVALID - This bit is set to 1 at the end of each conversion when a new result is loaded into
+ *    the RESULT field. It is cleared whenever this register is read. This bit will cause a
+ *    conversion-complete interrupt for the corresponding sequence if the MODE bit (in SEQA_CTRL) for that
+ *    sequence is set to 0 (and if the interrupt is enabled).
+ */
+#define ADC_SEQ_GDAT_DATAVALID(x)                (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_DATAVALID_SHIFT)) & ADC_SEQ_GDAT_DATAVALID_MASK)
+/*! @} */
+
+/* The count of ADC_SEQ_GDAT */
+#define ADC_SEQ_GDAT_COUNT                       (1U)
+
+/*! @name DAT - ADC Channel X [0:7] Data register. This register contains the result of the most recent conversion completed on channel X [0:7] . */
+/*! @{ */
+#define ADC_DAT_RESULT_MASK                      (0xFFF0U)
+#define ADC_DAT_RESULT_SHIFT                     (4U)
+/*! RESULT - This field contains the 12-bit ADC conversion result from the most recent conversion
+ *    performed for this channel under conversion sequence associated with this register. DATAVALID =
+ *    1 indicates that this result has not yet been read. If less than 12-bit resolultion is used
+ *    the ADC result occupies the upper MSBs and unused LSBs should be ignored.
+ */
+#define ADC_DAT_RESULT(x)                        (((uint32_t)(((uint32_t)(x)) << ADC_DAT_RESULT_SHIFT)) & ADC_DAT_RESULT_MASK)
+#define ADC_DAT_THCMPRANGE_MASK                  (0x30000U)
+#define ADC_DAT_THCMPRANGE_SHIFT                 (16U)
+/*! THCMPRANGE - Threshold Range Comparison result for this channel. 0x0 = In Range: The last
+ *    completed conversion was greater than or equal to the value programmed into the designated LOW
+ *    threshold register (THRn_LOW) but less than or equal to the value programmed into the designated
+ *    HIGH threshold register (THRn_HIGH). 0x1 = Below Range: The last completed conversion on was
+ *    less than the value programmed into the designated LOW threshold register (THRn_LOW). 0x2 = Above
+ *    Range: The last completed conversion was greater than the value programmed into the
+ *    designated HIGH threshold register (THRn_HIGH). 0x3 = Reserved.
+ */
+#define ADC_DAT_THCMPRANGE(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPRANGE_SHIFT)) & ADC_DAT_THCMPRANGE_MASK)
+#define ADC_DAT_THCMPCROSS_MASK                  (0xC0000U)
+#define ADC_DAT_THCMPCROSS_SHIFT                 (18U)
+/*! THCMPCROSS - Threshold Crossing Comparison result for this channel. 0x0 = No threshold Crossing
+ *    detected: The most recent completed conversion on this channel had the same relationship
+ *    (above or below) to the threshold value established by the designated LOW threshold register
+ *    (THRn_LOW) as did the previous conversion on this channel. 0x1 = Reserved. 0x2 = Downward Threshold
+ *    Crossing Detected. Indicates that a threshold crossing in the downward direction has occurred
+ *    - i.e. the previous sample on this channel was above the threshold value established by the
+ *    designated LOW threshold register (THRn_LOW) and the current sample is below that threshold. 0x3
+ *    = Upward Threshold Crossing Detected. Indicates that a threshold crossing in the upward
+ *    direction has occurred - i.e. the previous sample on this channel was below the threshold value
+ *    established by the designated LOW threshold register (THRn_LOW) and the current sample is above
+ *    that threshold.
+ */
+#define ADC_DAT_THCMPCROSS(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPCROSS_SHIFT)) & ADC_DAT_THCMPCROSS_MASK)
+#define ADC_DAT_CHANNEL_MASK                     (0x3C000000U)
+#define ADC_DAT_CHANNEL_SHIFT                    (26U)
+/*! CHANNEL - This field is hard-coded to contain the channel number that this particular register
+ *    relates to (i.e. this field will contain 0b0000 for the DAT0 register, 0b0001 for the DAT1
+ *    register, etc)
+ */
+#define ADC_DAT_CHANNEL(x)                       (((uint32_t)(((uint32_t)(x)) << ADC_DAT_CHANNEL_SHIFT)) & ADC_DAT_CHANNEL_MASK)
+#define ADC_DAT_OVERRUN_MASK                     (0x40000000U)
+#define ADC_DAT_OVERRUN_SHIFT                    (30U)
+/*! OVERRUN - This bit is set if a new conversion result is loaded into the RESULT field before a
+ *    previous result has been read - i.e. while the DATAVALID bit is set. This bit is cleared, along
+ *    with the DATAVALID bit, whenever this register is read or when the data related to this
+ *    channel is read from the global SEQA_GDAT register. This bit will contribute to an overrun
+ *    interrupt/DMA trigger if the MODE bit (in SEQA_CTRL) for the corresponding sequence is set to 0 (and if
+ *    the overrun interrupt is enabled).
+ */
+#define ADC_DAT_OVERRUN(x)                       (((uint32_t)(((uint32_t)(x)) << ADC_DAT_OVERRUN_SHIFT)) & ADC_DAT_OVERRUN_MASK)
+#define ADC_DAT_DATAVALID_MASK                   (0x80000000U)
+#define ADC_DAT_DATAVALID_SHIFT                  (31U)
+/*! DATAVALID - This bit is set to 1 at the end of each conversion for this channel when a new
+ *    result is loaded into the RESULT field. It is cleared whenever this register is read or when the
+ *    data related to this channel is read from the global SEQA_GDAT regsiter.
+ */
+#define ADC_DAT_DATAVALID(x)                     (((uint32_t)(((uint32_t)(x)) << ADC_DAT_DATAVALID_SHIFT)) & ADC_DAT_DATAVALID_MASK)
+/*! @} */
+
+/* The count of ADC_DAT */
+#define ADC_DAT_COUNT                            (8U)
+
+/*! @name THR0_LOW - ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */
+/*! @{ */
+#define ADC_THR0_LOW_THRLOW_MASK                 (0xFFF0U)
+#define ADC_THR0_LOW_THRLOW_SHIFT                (4U)
+/*! THRLOW - Low threshold value against which ADC results will be compared
+ */
+#define ADC_THR0_LOW_THRLOW(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_THR0_LOW_THRLOW_SHIFT)) & ADC_THR0_LOW_THRLOW_MASK)
+/*! @} */
+
+/*! @name THR1_LOW - ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */
+/*! @{ */
+#define ADC_THR1_LOW_THRLOW_MASK                 (0xFFF0U)
+#define ADC_THR1_LOW_THRLOW_SHIFT                (4U)
+/*! THRLOW - Low threshold value against which ADC results will be compared
+ */
+#define ADC_THR1_LOW_THRLOW(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_THR1_LOW_THRLOW_SHIFT)) & ADC_THR1_LOW_THRLOW_MASK)
+/*! @} */
+
+/*! @name THR0_HIGH - ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */
+/*! @{ */
+#define ADC_THR0_HIGH_THRHIGH_MASK               (0xFFF0U)
+#define ADC_THR0_HIGH_THRHIGH_SHIFT              (4U)
+/*! THRHIGH - High threshold value against which ADC results will be compared
+ */
+#define ADC_THR0_HIGH_THRHIGH(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_THR0_HIGH_THRHIGH_SHIFT)) & ADC_THR0_HIGH_THRHIGH_MASK)
+/*! @} */
+
+/*! @name THR1_HIGH - ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */
+/*! @{ */
+#define ADC_THR1_HIGH_THRHIGH_MASK               (0xFFF0U)
+#define ADC_THR1_HIGH_THRHIGH_SHIFT              (4U)
+/*! THRHIGH - High threshold value against which ADC results will be compared
+ */
+#define ADC_THR1_HIGH_THRHIGH(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_THR1_HIGH_THRHIGH_SHIFT)) & ADC_THR1_HIGH_THRHIGH_MASK)
+/*! @} */
+
+/*! @name CHAN_THRSEL - ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel */
+/*! @{ */
+#define ADC_CHAN_THRSEL_CH0_THRSEL_MASK          (0x1U)
+#define ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT         (0U)
+/*! CH0_THRSEL - Threshold select for channel 0. 0: Threshold 0. Results for this channel will be
+ *    compared against the threshold levels indicated in the THR0_LOW and THR0_HIGH registers. 1:
+ *    Threshold 1. Results for this channel will be compared against the threshold levels indicated in
+ *    the THR1_LOW and THR1_HIGH registers.
+ */
+#define ADC_CHAN_THRSEL_CH0_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH0_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH1_THRSEL_MASK          (0x2U)
+#define ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT         (1U)
+/*! CH1_THRSEL - Threshold select for channel 1. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH1_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH1_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH2_THRSEL_MASK          (0x4U)
+#define ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT         (2U)
+/*! CH2_THRSEL - Threshold select for channel 2. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH2_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH2_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH3_THRSEL_MASK          (0x8U)
+#define ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT         (3U)
+/*! CH3_THRSEL - Threshold select for channel 3. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH3_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH3_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH4_THRSEL_MASK          (0x10U)
+#define ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT         (4U)
+/*! CH4_THRSEL - Threshold select for channel 4. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH4_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH4_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH5_THRSEL_MASK          (0x20U)
+#define ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT         (5U)
+/*! CH5_THRSEL - Threshold select for channel 5. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH5_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH5_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH6_THRSEL_MASK          (0x40U)
+#define ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT         (6U)
+/*! CH6_THRSEL - Threshold select for channel 6. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH6_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH6_THRSEL_MASK)
+#define ADC_CHAN_THRSEL_CH7_THRSEL_MASK          (0x80U)
+#define ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT         (7U)
+/*! CH7_THRSEL - Threshold select for channel 7. See description for channel 0.
+ */
+#define ADC_CHAN_THRSEL_CH7_THRSEL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH7_THRSEL_MASK)
+/*! @} */
+
+/*! @name INTEN - ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated. */
+/*! @{ */
+#define ADC_INTEN_SEQA_INTEN_MASK                (0x1U)
+#define ADC_INTEN_SEQA_INTEN_SHIFT               (0U)
+/*! SEQA_INTEN - Sequence A interrupt enable. 0: Disabled. The sequence A interrupt/DMA trigger is
+ *    disabled. 1: Enabled. The sequence A interrupt/DMA trigger is enabled and will be asserted
+ *    either upon completion of each individual conversion performed as part of sequence A, or upon
+ *    completion of the entire A sequence of conversions, depending on the MODE bit in the SEQA_CTRL
+ *    register.
+ */
+#define ADC_INTEN_SEQA_INTEN(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_SEQA_INTEN_SHIFT)) & ADC_INTEN_SEQA_INTEN_MASK)
+#define ADC_INTEN_OVR_INTEN_MASK                 (0x4U)
+#define ADC_INTEN_OVR_INTEN_SHIFT                (2U)
+/*! OVR_INTEN - Overrun interrupt enable. 0: Disabled. The overrun interrupt is disabled. 1:
+ *    Enabled. The overrun interrupt is enabled. Detection of an overrun condition on any of the 12 channel
+ *    data registers will cause an overrun interrupt/DMA trigger. In addition, if the MODE bit for
+ *    a particular sequence is 0, then an overrun in the global data register for that sequence will
+ *    also cause this interrupt/DMA trigger to be asserted.
+ */
+#define ADC_INTEN_OVR_INTEN(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_OVR_INTEN_SHIFT)) & ADC_INTEN_OVR_INTEN_MASK)
+#define ADC_INTEN_ADCMPINTEN0_MASK               (0x18U)
+#define ADC_INTEN_ADCMPINTEN0_SHIFT              (3U)
+/*! ADCMPINTEN0 - Threshold comparison interrupt enable for channel 0. 0x0: Disabled. 0x1: Outside
+ *    threshold. 0x2: Crossing threshold. 0x3: Reserved
+ */
+#define ADC_INTEN_ADCMPINTEN0(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN0_SHIFT)) & ADC_INTEN_ADCMPINTEN0_MASK)
+#define ADC_INTEN_ADCMPINTEN1_MASK               (0x60U)
+#define ADC_INTEN_ADCMPINTEN1_SHIFT              (5U)
+/*! ADCMPINTEN1 - Channel 1 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN1(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN1_SHIFT)) & ADC_INTEN_ADCMPINTEN1_MASK)
+#define ADC_INTEN_ADCMPINTEN2_MASK               (0x180U)
+#define ADC_INTEN_ADCMPINTEN2_SHIFT              (7U)
+/*! ADCMPINTEN2 - Channel 2 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN2(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN2_SHIFT)) & ADC_INTEN_ADCMPINTEN2_MASK)
+#define ADC_INTEN_ADCMPINTEN3_MASK               (0x600U)
+#define ADC_INTEN_ADCMPINTEN3_SHIFT              (9U)
+/*! ADCMPINTEN3 - Channel 3 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN3(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN3_SHIFT)) & ADC_INTEN_ADCMPINTEN3_MASK)
+#define ADC_INTEN_ADCMPINTEN4_MASK               (0x1800U)
+#define ADC_INTEN_ADCMPINTEN4_SHIFT              (11U)
+/*! ADCMPINTEN4 - Channel 4 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN4(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN4_SHIFT)) & ADC_INTEN_ADCMPINTEN4_MASK)
+#define ADC_INTEN_ADCMPINTEN5_MASK               (0x6000U)
+#define ADC_INTEN_ADCMPINTEN5_SHIFT              (13U)
+/*! ADCMPINTEN5 - Channel 5 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN5(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN5_SHIFT)) & ADC_INTEN_ADCMPINTEN5_MASK)
+#define ADC_INTEN_ADCMPINTEN6_MASK               (0x18000U)
+#define ADC_INTEN_ADCMPINTEN6_SHIFT              (15U)
+/*! ADCMPINTEN6 - Channel 6 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN6(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN6_SHIFT)) & ADC_INTEN_ADCMPINTEN6_MASK)
+#define ADC_INTEN_ADCMPINTEN7_MASK               (0x60000U)
+#define ADC_INTEN_ADCMPINTEN7_SHIFT              (17U)
+/*! ADCMPINTEN7 - Channel 7 threshold comparison interrupt enable. See description for channel 0.
+ */
+#define ADC_INTEN_ADCMPINTEN7(x)                 (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN7_SHIFT)) & ADC_INTEN_ADCMPINTEN7_MASK)
+/*! @} */
+
+/*! @name FLAGS - ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers). */
+/*! @{ */
+#define ADC_FLAGS_THCMP0_MASK                    (0x1U)
+#define ADC_FLAGS_THCMP0_SHIFT                   (0U)
+/*! THCMP0 - Threshold comparison event on Channel 0. Set to 1 upon either an out-of-range result or
+ *    a threshold-crossing result if enabled to do so in the INTEN register. This bit is cleared by
+ *    writing a 1.
+ */
+#define ADC_FLAGS_THCMP0(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP0_SHIFT)) & ADC_FLAGS_THCMP0_MASK)
+#define ADC_FLAGS_THCMP1_MASK                    (0x2U)
+#define ADC_FLAGS_THCMP1_SHIFT                   (1U)
+/*! THCMP1 - Threshold comparison event on Channel 1. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP1(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP1_SHIFT)) & ADC_FLAGS_THCMP1_MASK)
+#define ADC_FLAGS_THCMP2_MASK                    (0x4U)
+#define ADC_FLAGS_THCMP2_SHIFT                   (2U)
+/*! THCMP2 - Threshold comparison event on Channel 2. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP2(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP2_SHIFT)) & ADC_FLAGS_THCMP2_MASK)
+#define ADC_FLAGS_THCMP3_MASK                    (0x8U)
+#define ADC_FLAGS_THCMP3_SHIFT                   (3U)
+/*! THCMP3 - Threshold comparison event on Channel 3. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP3(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP3_SHIFT)) & ADC_FLAGS_THCMP3_MASK)
+#define ADC_FLAGS_THCMP4_MASK                    (0x10U)
+#define ADC_FLAGS_THCMP4_SHIFT                   (4U)
+/*! THCMP4 - Threshold comparison event on Channel 4. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP4(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP4_SHIFT)) & ADC_FLAGS_THCMP4_MASK)
+#define ADC_FLAGS_THCMP5_MASK                    (0x20U)
+#define ADC_FLAGS_THCMP5_SHIFT                   (5U)
+/*! THCMP5 - Threshold comparison event on Channel 5. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP5(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP5_SHIFT)) & ADC_FLAGS_THCMP5_MASK)
+#define ADC_FLAGS_THCMP6_MASK                    (0x40U)
+#define ADC_FLAGS_THCMP6_SHIFT                   (6U)
+/*! THCMP6 - Threshold comparison event on Channel 6. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP6(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP6_SHIFT)) & ADC_FLAGS_THCMP6_MASK)
+#define ADC_FLAGS_THCMP7_MASK                    (0x80U)
+#define ADC_FLAGS_THCMP7_SHIFT                   (7U)
+/*! THCMP7 - Threshold comparison event on Channel 7. See description for channel 0.
+ */
+#define ADC_FLAGS_THCMP7(x)                      (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP7_SHIFT)) & ADC_FLAGS_THCMP7_MASK)
+#define ADC_FLAGS_OVERRUN0_MASK                  (0x1000U)
+#define ADC_FLAGS_OVERRUN0_SHIFT                 (12U)
+/*! OVERRUN0 - Mirrors the OVERRRUN status flag from the result register for ADC channel 0
+ */
+#define ADC_FLAGS_OVERRUN0(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN0_SHIFT)) & ADC_FLAGS_OVERRUN0_MASK)
+#define ADC_FLAGS_OVERRUN1_MASK                  (0x2000U)
+#define ADC_FLAGS_OVERRUN1_SHIFT                 (13U)
+/*! OVERRUN1 - Mirrors the OVERRRUN status flag from the result register for ADC channel 1
+ */
+#define ADC_FLAGS_OVERRUN1(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN1_SHIFT)) & ADC_FLAGS_OVERRUN1_MASK)
+#define ADC_FLAGS_OVERRUN2_MASK                  (0x4000U)
+#define ADC_FLAGS_OVERRUN2_SHIFT                 (14U)
+/*! OVERRUN2 - Mirrors the OVERRRUN status flag from the result register for ADC channel 2
+ */
+#define ADC_FLAGS_OVERRUN2(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN2_SHIFT)) & ADC_FLAGS_OVERRUN2_MASK)
+#define ADC_FLAGS_OVERRUN3_MASK                  (0x8000U)
+#define ADC_FLAGS_OVERRUN3_SHIFT                 (15U)
+/*! OVERRUN3 - Mirrors the OVERRRUN status flag from the result register for ADC channel 3
+ */
+#define ADC_FLAGS_OVERRUN3(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN3_SHIFT)) & ADC_FLAGS_OVERRUN3_MASK)
+#define ADC_FLAGS_OVERRUN4_MASK                  (0x10000U)
+#define ADC_FLAGS_OVERRUN4_SHIFT                 (16U)
+/*! OVERRUN4 - Mirrors the OVERRRUN status flag from the result register for ADC channel 4
+ */
+#define ADC_FLAGS_OVERRUN4(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN4_SHIFT)) & ADC_FLAGS_OVERRUN4_MASK)
+#define ADC_FLAGS_OVERRUN5_MASK                  (0x20000U)
+#define ADC_FLAGS_OVERRUN5_SHIFT                 (17U)
+/*! OVERRUN5 - Mirrors the OVERRRUN status flag from the result register for ADC channel 5
+ */
+#define ADC_FLAGS_OVERRUN5(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN5_SHIFT)) & ADC_FLAGS_OVERRUN5_MASK)
+#define ADC_FLAGS_OVERRUN6_MASK                  (0x40000U)
+#define ADC_FLAGS_OVERRUN6_SHIFT                 (18U)
+/*! OVERRUN6 - Mirrors the OVERRRUN status flag from the result register for ADC channel 6
+ */
+#define ADC_FLAGS_OVERRUN6(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN6_SHIFT)) & ADC_FLAGS_OVERRUN6_MASK)
+#define ADC_FLAGS_OVERRUN7_MASK                  (0x80000U)
+#define ADC_FLAGS_OVERRUN7_SHIFT                 (19U)
+/*! OVERRUN7 - Mirrors the OVERRRUN status flag from the result register for ADC channel 7
+ */
+#define ADC_FLAGS_OVERRUN7(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN7_SHIFT)) & ADC_FLAGS_OVERRUN7_MASK)
+#define ADC_FLAGS_SEQA_OVR_MASK                  (0x1000000U)
+#define ADC_FLAGS_SEQA_OVR_SHIFT                 (24U)
+/*! SEQA_OVR - Mirrors the global OVERRUN status flag in the SEQA_GDAT register
+ */
+#define ADC_FLAGS_SEQA_OVR(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_OVR_SHIFT)) & ADC_FLAGS_SEQA_OVR_MASK)
+#define ADC_FLAGS_SEQA_INT_MASK                  (0x10000000U)
+#define ADC_FLAGS_SEQA_INT_SHIFT                 (28U)
+/*! SEQA_INT - Sequence A interrupt/DMA trigger. If the MODE bit in the SEQA_CTRL register is 0,
+ *    this flag will mirror the DATAVALID bit in the sequence A global data register (SEQA_GDAT), which
+ *    is set at the end of every ADC conversion performed as part of sequence A. It will be cleared
+ *    automatically when the SEQA_GDAT register is read. If the MODE bit in the SEQA_CTRL register
+ *    is 1, this flag will be set upon completion of an entire A sequence. In this case it must be
+ *    cleared by writing a 1 to this SEQA_INT bit. This interrupt must be enabled in the INTEN
+ *    register.
+ */
+#define ADC_FLAGS_SEQA_INT(x)                    (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_INT_SHIFT)) & ADC_FLAGS_SEQA_INT_MASK)
+#define ADC_FLAGS_THCMP_INT_MASK                 (0x40000000U)
+#define ADC_FLAGS_THCMP_INT_SHIFT                (30U)
+/*! THCMP_INT - Threshold Comparison Interrupt. This bit will be set if any of the THCMP flags in
+ *    the lower bits of this register are set to 1 (due to an enabled out-of-range or
+ *    threshold-crossing event on any channel). Each type of threshold comparison interrupt on each channel must be
+ *    individually enabled in the INTEN register to cause this interrupt. This bit will be cleared
+ *    when all of the individual threshold flags are cleared via writing 1s to those bits.
+ */
+#define ADC_FLAGS_THCMP_INT(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP_INT_SHIFT)) & ADC_FLAGS_THCMP_INT_MASK)
+#define ADC_FLAGS_OVR_INT_MASK                   (0x80000000U)
+#define ADC_FLAGS_OVR_INT_SHIFT                  (31U)
+/*! OVR_INT - Overrun Interrupt flag. Any overrun bit in any of the individual channel data
+ *    registers will cause this interrupt. In addition, if the MODE bit in either of the SEQn_CTRL registers
+ *    is 0 then the OVERRUN bit in the corresponding SEQn_GDAT register will also cause this
+ *    interrupt. This interrupt must be enabled in the INTEN register. This bit will be cleared when all
+ *    of the individual overrun bits have been cleared via reading the corresponding data registers.
+ */
+#define ADC_FLAGS_OVR_INT(x)                     (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVR_INT_SHIFT)) & ADC_FLAGS_OVR_INT_MASK)
+/*! @} */
+
+/*! @name STARTUP - ADC Startup register (typically only used by the ADC API). */
+/*! @{ */
+#define ADC_STARTUP_ADC_ENA_MASK                 (0x1U)
+#define ADC_STARTUP_ADC_ENA_SHIFT                (0U)
+/*! ADC_ENA - ADC Enable bit. This bit can only be set to a 1 by software. It is cleared
+ *    automatically whenever the ADC is powered down. This bit must not be set until at least 10 microseconds
+ *    after the ADC is powered up (typically by altering a system-level ADC power control bit).
+ */
+#define ADC_STARTUP_ADC_ENA(x)                   (((uint32_t)(((uint32_t)(x)) << ADC_STARTUP_ADC_ENA_SHIFT)) & ADC_STARTUP_ADC_ENA_MASK)
+/*! @} */
+
+/*! @name GPADC_CTRL0 - Second ADC Control register : ADC internal LDO (within ADC sub-system) */
+/*! @{ */
+#define ADC_GPADC_CTRL0_LDO_POWER_EN_MASK        (0x1U)
+#define ADC_GPADC_CTRL0_LDO_POWER_EN_SHIFT       (0U)
+/*! LDO_POWER_EN - LDO Power enable signal (active high). This is for the LDO within the ADC itself.
+ *    There is also LDOADC controlled from PMC that is outside the ADC block. The LDOADC should
+ *    have been enabled for 10usec before enabling this LDO. After enabling this LDO it is necessary to
+ *    wait for 230usec, before ADC sampling is commenced, so that full accuraccy of the ADC will be
+ *    obtained.
+ */
+#define ADC_GPADC_CTRL0_LDO_POWER_EN(x)          (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_LDO_POWER_EN_SHIFT)) & ADC_GPADC_CTRL0_LDO_POWER_EN_MASK)
+#define ADC_GPADC_CTRL0_LDO_SEL_OUT_MASK         (0xF8U)
+#define ADC_GPADC_CTRL0_LDO_SEL_OUT_SHIFT        (3U)
+/*! LDO_SEL_OUT - Select LDO output voltage (10mV step) [between 0.64V and 0.95V]. This is for the
+ *    LDO within the ADC itself. There is also LDOADC controlled from PMC that is outside the ADC
+ *    block.
+ */
+#define ADC_GPADC_CTRL0_LDO_SEL_OUT(x)           (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_LDO_SEL_OUT_SHIFT)) & ADC_GPADC_CTRL0_LDO_SEL_OUT_MASK)
+#define ADC_GPADC_CTRL0_PASS_ENABLE_MASK         (0x100U)
+#define ADC_GPADC_CTRL0_PASS_ENABLE_SHIFT        (8U)
+/*! PASS_ENABLE - Enable pass mode when set to high. This is for the LDO within the ADC itself.
+ *    There is also LDOADC controlled from PMC that is outside the ADC block.
+ */
+#define ADC_GPADC_CTRL0_PASS_ENABLE(x)           (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_PASS_ENABLE_SHIFT)) & ADC_GPADC_CTRL0_PASS_ENABLE_MASK)
+#define ADC_GPADC_CTRL0_GPADC_TSAMP_MASK         (0x3E00U)
+#define ADC_GPADC_CTRL0_GPADC_TSAMP_SHIFT        (9U)
+/*! GPADC_TSAMP - Extand ADC sampling time according to source impedance 1: 0.621 kOhm 20 (default): 55 kOhm 31: 87 kOhm
+ */
+#define ADC_GPADC_CTRL0_GPADC_TSAMP(x)           (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_GPADC_TSAMP_SHIFT)) & ADC_GPADC_CTRL0_GPADC_TSAMP_MASK)
+#define ADC_GPADC_CTRL0_TEST_MASK                (0xC000U)
+#define ADC_GPADC_CTRL0_TEST_SHIFT               (14U)
+/*! TEST - Mode selection: '00': Normal functional mode (DIV4 mode). Input range is 0 to 3.6V,
+ *    although max input voltage is affected by supply voltage of the device. '01': Multiplexer test mode
+ *    '10': ADC in unity gain mode. (DIV1 mode). Input range is 0 to 0.9V. Voltages above this may
+ *    damage the device. '11': Not used
+ */
+#define ADC_GPADC_CTRL0_TEST(x)                  (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL0_TEST_SHIFT)) & ADC_GPADC_CTRL0_TEST_MASK)
+/*! @} */
+
+/*! @name GPADC_CTRL1 - Third ADC Control register : ADC internal gain and offset */
+/*! @{ */
+#define ADC_GPADC_CTRL1_OFFSET_CAL_MASK          (0x3FFU)
+#define ADC_GPADC_CTRL1_OFFSET_CAL_SHIFT         (0U)
+/*! OFFSET_CAL - offset_cal the setting is used within the ADC to compensate for a DC shift in values for this particular device.
+ */
+#define ADC_GPADC_CTRL1_OFFSET_CAL(x)            (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL1_OFFSET_CAL_SHIFT)) & ADC_GPADC_CTRL1_OFFSET_CAL_MASK)
+#define ADC_GPADC_CTRL1_GAIN_CAL_MASK            (0xFFC00U)
+#define ADC_GPADC_CTRL1_GAIN_CAL_SHIFT           (10U)
+/*! GAIN_CAL - gain_cal the setting is used within the ADC to compensate for any gain variation for this particular device.
+ */
+#define ADC_GPADC_CTRL1_GAIN_CAL(x)              (((uint32_t)(((uint32_t)(x)) << ADC_GPADC_CTRL1_GAIN_CAL_SHIFT)) & ADC_GPADC_CTRL1_GAIN_CAL_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group ADC_Register_Masks */
+
+
+/* ADC - Peripheral instance base addresses */
+/** Peripheral ADC0 base address */
+#define ADC0_BASE                                (0x40089000u)
+/** Peripheral ADC0 base pointer */
+#define ADC0                                     ((ADC_Type *)ADC0_BASE)
+/** Array initializer of ADC peripheral base addresses */
+#define ADC_BASE_ADDRS                           { ADC0_BASE }
+/** Array initializer of ADC peripheral base pointers */
+#define ADC_BASE_PTRS                            { ADC0 }
+/** Interrupt vectors for the ADC peripheral type */
+#define ADC_SEQ_IRQS                             { ADC0_SEQA_IRQn, ADC0_SEQB_IRQn }
+#define ADC_THCMP_IRQS                           { ADC0_THCMP_IRQn }
+
+/*!
+ * @}
+ */ /* end of group ADC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- AES Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup AES_Peripheral_Access_Layer AES Peripheral Access Layer
+ * @{
+ */
+
+/** AES - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CFG;                               /**< Configuration, offset: 0x0 */
+  __IO uint32_t CMD;                               /**< Command, offset: 0x4 */
+  __IO uint32_t STAT;                              /**< Status, offset: 0x8 */
+  __IO uint32_t CTR_INCR;                          /**< Counter Increment. Increment value for HOLDING when in Counter modes, offset: 0xC */
+       uint8_t RESERVED_0[16];
+  __O  uint32_t KEY[8];                            /**< Bits of the AES key, array offset: 0x20, array step: 0x4 */
+  __O  uint32_t INTEXT[4];                         /**< Input text bits, array offset: 0x40, array step: 0x4 */
+  __O  uint32_t HOLDING[4];                        /**< Holding register bits, array offset: 0x50, array step: 0x4 */
+  __I  uint32_t OUTTEXT[4];                        /**< Output text bits, array offset: 0x60, array step: 0x4 */
+  __O  uint32_t GF128_Y[4];                        /**< Y bits input of GF128 hash, array offset: 0x70, array step: 0x4 */
+  __I  uint32_t GF128_Z[4];                        /**< Result bits of GF128 hash, array offset: 0x80, array step: 0x4 */
+  __I  uint32_t GCM_TAG[4];                        /**< GCM Tag bits, array offset: 0x90, array step: 0x4 */
+} AES_Type;
+
+/* ----------------------------------------------------------------------------
+   -- AES Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup AES_Register_Masks AES Register Masks
+ * @{
+ */
+
+/*! @name CFG - Configuration */
+/*! @{ */
+#define AES_CFG_PROC_EN_MASK                     (0x3U)
+#define AES_CFG_PROC_EN_SHIFT                    (0U)
+/*! PROC_EN - Processing Mode Enable. 00: Reserved. 01: Encrypt/Decrypt Only. 10: GF128 Hash Only. 11: Encrypt/Decrypt and Hash.
+ */
+#define AES_CFG_PROC_EN(x)                       (((uint32_t)(((uint32_t)(x)) << AES_CFG_PROC_EN_SHIFT)) & AES_CFG_PROC_EN_MASK)
+#define AES_CFG_GF128_SEL_MASK                   (0x4U)
+#define AES_CFG_GF128_SEL_SHIFT                  (2U)
+/*! GF128_SEL - GF128 Select Mode. 0: GF128 Hash Input Text. 1: GF128 Hash Output Text.
+ */
+#define AES_CFG_GF128_SEL(x)                     (((uint32_t)(((uint32_t)(x)) << AES_CFG_GF128_SEL_SHIFT)) & AES_CFG_GF128_SEL_MASK)
+#define AES_CFG_INTEXT_BSWAP_MASK                (0x10U)
+#define AES_CFG_INTEXT_BSWAP_SHIFT               (4U)
+/*! INTEXT_BSWAP - Input Text Byte Swap
+ */
+#define AES_CFG_INTEXT_BSWAP(x)                  (((uint32_t)(((uint32_t)(x)) << AES_CFG_INTEXT_BSWAP_SHIFT)) & AES_CFG_INTEXT_BSWAP_MASK)
+#define AES_CFG_INTEXT_WSWAP_MASK                (0x20U)
+#define AES_CFG_INTEXT_WSWAP_SHIFT               (5U)
+/*! INTEXT_WSWAP - Input Text Word Swap
+ */
+#define AES_CFG_INTEXT_WSWAP(x)                  (((uint32_t)(((uint32_t)(x)) << AES_CFG_INTEXT_WSWAP_SHIFT)) & AES_CFG_INTEXT_WSWAP_MASK)
+#define AES_CFG_OUTTEXT_BSWAP_MASK               (0x40U)
+#define AES_CFG_OUTTEXT_BSWAP_SHIFT              (6U)
+/*! OUTTEXT_BSWAP - Output Text Byte Swap
+ */
+#define AES_CFG_OUTTEXT_BSWAP(x)                 (((uint32_t)(((uint32_t)(x)) << AES_CFG_OUTTEXT_BSWAP_SHIFT)) & AES_CFG_OUTTEXT_BSWAP_MASK)
+#define AES_CFG_OUTTEXT_WSWAP_MASK               (0x80U)
+#define AES_CFG_OUTTEXT_WSWAP_SHIFT              (7U)
+/*! OUTTEXT_WSWAP - Output Text Word Swap
+ */
+#define AES_CFG_OUTTEXT_WSWAP(x)                 (((uint32_t)(((uint32_t)(x)) << AES_CFG_OUTTEXT_WSWAP_SHIFT)) & AES_CFG_OUTTEXT_WSWAP_MASK)
+#define AES_CFG_KEY_CFG_MASK                     (0x300U)
+#define AES_CFG_KEY_CFG_SHIFT                    (8U)
+/*! KEY_CFG - Key Configuration. 00: 128 Bit Key. 01: 192 Bit Key. 10: 256 Bit Key. 11: Reserved.
+ */
+#define AES_CFG_KEY_CFG(x)                       (((uint32_t)(((uint32_t)(x)) << AES_CFG_KEY_CFG_SHIFT)) & AES_CFG_KEY_CFG_MASK)
+#define AES_CFG_INBLK_SEL_MASK                   (0x30000U)
+#define AES_CFG_INBLK_SEL_SHIFT                  (16U)
+/*! INBLK_SEL - Input Block Selection From: 00: Reserved. 01: Input Text. 10: Holding. 11: Input Text XOR Holding.
+ */
+#define AES_CFG_INBLK_SEL(x)                     (((uint32_t)(((uint32_t)(x)) << AES_CFG_INBLK_SEL_SHIFT)) & AES_CFG_INBLK_SEL_MASK)
+#define AES_CFG_HOLD_SEL_MASK                    (0x300000U)
+#define AES_CFG_HOLD_SEL_SHIFT                   (20U)
+/*! HOLD_SEL - Holding Select From: 00: Counter. 01: Input Text. 10: Output Block. 11: Input Text XOR Output Block.
+ */
+#define AES_CFG_HOLD_SEL(x)                      (((uint32_t)(((uint32_t)(x)) << AES_CFG_HOLD_SEL_SHIFT)) & AES_CFG_HOLD_SEL_MASK)
+#define AES_CFG_OUTTEXT_SEL_MASK                 (0x3000000U)
+#define AES_CFG_OUTTEXT_SEL_SHIFT                (24U)
+/*! OUTTEXT_SEL - Output Text Selection From: 00: Output Block. 01: Output Block XOR Input Text. 10:
+ *    Output Block XOR Holding. 11: Reserved.
+ */
+#define AES_CFG_OUTTEXT_SEL(x)                   (((uint32_t)(((uint32_t)(x)) << AES_CFG_OUTTEXT_SEL_SHIFT)) & AES_CFG_OUTTEXT_SEL_MASK)
+/*! @} */
+
+/*! @name CMD - Command */
+/*! @{ */
+#define AES_CMD_COPY_SKEY_MASK                   (0x1U)
+#define AES_CMD_COPY_SKEY_SHIFT                  (0U)
+/*! COPY_SKEY - Copies Secret Key and enables cipher. Secret key is typically held in OTP or other secure memory.
+ */
+#define AES_CMD_COPY_SKEY(x)                     (((uint32_t)(((uint32_t)(x)) << AES_CMD_COPY_SKEY_SHIFT)) & AES_CMD_COPY_SKEY_MASK)
+#define AES_CMD_COPY_TO_Y_MASK                   (0x2U)
+#define AES_CMD_COPY_TO_Y_SHIFT                  (1U)
+/*! COPY_TO_Y - Copies Output Text to GF128 Y. Typically used for GCM where the Hash requires a Y
+ *    input which is the result of an ECB encryption of 0s. Should be performed after encryption of 0s.
+ */
+#define AES_CMD_COPY_TO_Y(x)                     (((uint32_t)(((uint32_t)(x)) << AES_CMD_COPY_TO_Y_SHIFT)) & AES_CMD_COPY_TO_Y_MASK)
+#define AES_CMD_SWITCH_MODE_MASK                 (0x10U)
+#define AES_CMD_SWITCH_MODE_SHIFT                (4U)
+/*! SWITCH_MODE - Switches mode from Forward to Reverse or from Reverse to Forward. Must wait for
+ *    Idle after command. Typically used for non-counter modes (ECB, CBC, CFB, OFB) to switch from
+ *    forward to reverse mode for decryption.
+ */
+#define AES_CMD_SWITCH_MODE(x)                   (((uint32_t)(((uint32_t)(x)) << AES_CMD_SWITCH_MODE_SHIFT)) & AES_CMD_SWITCH_MODE_MASK)
+#define AES_CMD_ABORT_MASK                       (0x100U)
+#define AES_CMD_ABORT_SHIFT                      (8U)
+/*! ABORT - Aborts Encrypt/Decrypt and GF128 Hash, clears INTEXT, clears OUTTEXT, and clears HOLDING
+ */
+#define AES_CMD_ABORT(x)                         (((uint32_t)(((uint32_t)(x)) << AES_CMD_ABORT_SHIFT)) & AES_CMD_ABORT_MASK)
+#define AES_CMD_WIPE_MASK                        (0x200U)
+#define AES_CMD_WIPE_SHIFT                       (9U)
+/*! WIPE - Performs Abort, clears KEY, disables cipher, and clears GF128_Y
+ */
+#define AES_CMD_WIPE(x)                          (((uint32_t)(((uint32_t)(x)) << AES_CMD_WIPE_SHIFT)) & AES_CMD_WIPE_MASK)
+/*! @} */
+
+/*! @name STAT - Status */
+/*! @{ */
+#define AES_STAT_IDLE_MASK                       (0x1U)
+#define AES_STAT_IDLE_SHIFT                      (0U)
+/*! IDLE - When set, all state machines are idle
+ */
+#define AES_STAT_IDLE(x)                         (((uint32_t)(((uint32_t)(x)) << AES_STAT_IDLE_SHIFT)) & AES_STAT_IDLE_MASK)
+#define AES_STAT_IN_READY_MASK                   (0x2U)
+#define AES_STAT_IN_READY_SHIFT                  (1U)
+/*! IN_READY - When set, input Text can be written
+ */
+#define AES_STAT_IN_READY(x)                     (((uint32_t)(((uint32_t)(x)) << AES_STAT_IN_READY_SHIFT)) & AES_STAT_IN_READY_MASK)
+#define AES_STAT_OUT_READY_MASK                  (0x4U)
+#define AES_STAT_OUT_READY_SHIFT                 (2U)
+/*! OUT_READY - When set, output Text can be read
+ */
+#define AES_STAT_OUT_READY(x)                    (((uint32_t)(((uint32_t)(x)) << AES_STAT_OUT_READY_SHIFT)) & AES_STAT_OUT_READY_MASK)
+#define AES_STAT_REVERSE_MASK                    (0x10U)
+#define AES_STAT_REVERSE_SHIFT                   (4U)
+/*! REVERSE - When set, Cipher in reverse mode
+ */
+#define AES_STAT_REVERSE(x)                      (((uint32_t)(((uint32_t)(x)) << AES_STAT_REVERSE_SHIFT)) & AES_STAT_REVERSE_MASK)
+#define AES_STAT_KEY_VALID_MASK                  (0x20U)
+#define AES_STAT_KEY_VALID_SHIFT                 (5U)
+/*! KEY_VALID - When set, Key is valid
+ */
+#define AES_STAT_KEY_VALID(x)                    (((uint32_t)(((uint32_t)(x)) << AES_STAT_KEY_VALID_SHIFT)) & AES_STAT_KEY_VALID_MASK)
+/*! @} */
+
+/*! @name CTR_INCR - Counter Increment. Increment value for HOLDING when in Counter modes */
+/*! @{ */
+#define AES_CTR_INCR_CTR_INCR_MASK               (0xFFFFFFFFU)
+#define AES_CTR_INCR_CTR_INCR_SHIFT              (0U)
+/*! CTR_INCR - Counter Increment. Increment value for HOLDING when in Counter modes
+ */
+#define AES_CTR_INCR_CTR_INCR(x)                 (((uint32_t)(((uint32_t)(x)) << AES_CTR_INCR_CTR_INCR_SHIFT)) & AES_CTR_INCR_CTR_INCR_MASK)
+/*! @} */
+
+/*! @name KEY - Bits of the AES key */
+/*! @{ */
+#define AES_KEY_KEY_MASK                         (0xFFFFFFFFU)
+#define AES_KEY_KEY_SHIFT                        (0U)
+/*! KEY - Contains the bits of the AES key.
+ */
+#define AES_KEY_KEY(x)                           (((uint32_t)(((uint32_t)(x)) << AES_KEY_KEY_SHIFT)) & AES_KEY_KEY_MASK)
+/*! @} */
+
+/* The count of AES_KEY */
+#define AES_KEY_COUNT                            (8U)
+
+/*! @name INTEXT - Input text bits */
+/*! @{ */
+#define AES_INTEXT_INTEXT_MASK                   (0xFFFFFFFFU)
+#define AES_INTEXT_INTEXT_SHIFT                  (0U)
+/*! INTEXT - Contains bits of the AES key.
+ */
+#define AES_INTEXT_INTEXT(x)                     (((uint32_t)(((uint32_t)(x)) << AES_INTEXT_INTEXT_SHIFT)) & AES_INTEXT_INTEXT_MASK)
+/*! @} */
+
+/* The count of AES_INTEXT */
+#define AES_INTEXT_COUNT                         (4U)
+
+/*! @name HOLDING - Holding register bits */
+/*! @{ */
+#define AES_HOLDING_HOLDING_MASK                 (0xFFFFFFFFU)
+#define AES_HOLDING_HOLDING_SHIFT                (0U)
+/*! HOLDING - Contains the first word (bits 31:0) of the 128 bit Holding value.
+ */
+#define AES_HOLDING_HOLDING(x)                   (((uint32_t)(((uint32_t)(x)) << AES_HOLDING_HOLDING_SHIFT)) & AES_HOLDING_HOLDING_MASK)
+/*! @} */
+
+/* The count of AES_HOLDING */
+#define AES_HOLDING_COUNT                        (4U)
+
+/*! @name OUTTEXT - Output text bits */
+/*! @{ */
+#define AES_OUTTEXT_OUTTEXT_MASK                 (0xFFFFFFFFU)
+#define AES_OUTTEXT_OUTTEXT_SHIFT                (0U)
+/*! OUTTEXT - Contains the bits of the 128 bit Output text data.
+ */
+#define AES_OUTTEXT_OUTTEXT(x)                   (((uint32_t)(((uint32_t)(x)) << AES_OUTTEXT_OUTTEXT_SHIFT)) & AES_OUTTEXT_OUTTEXT_MASK)
+/*! @} */
+
+/* The count of AES_OUTTEXT */
+#define AES_OUTTEXT_COUNT                        (4U)
+
+/*! @name GF128_Y - Y bits input of GF128 hash */
+/*! @{ */
+#define AES_GF128_Y_GF128_Y_MASK                 (0xFFFFFFFFU)
+#define AES_GF128_Y_GF128_Y_SHIFT                (0U)
+/*! GF128_Y - Contains the bits of the Y input of GF128 hash.
+ */
+#define AES_GF128_Y_GF128_Y(x)                   (((uint32_t)(((uint32_t)(x)) << AES_GF128_Y_GF128_Y_SHIFT)) & AES_GF128_Y_GF128_Y_MASK)
+/*! @} */
+
+/* The count of AES_GF128_Y */
+#define AES_GF128_Y_COUNT                        (4U)
+
+/*! @name GF128_Z - Result bits of GF128 hash */
+/*! @{ */
+#define AES_GF128_Z_GF128_Z_MASK                 (0xFFFFFFFFU)
+#define AES_GF128_Z_GF128_Z_SHIFT                (0U)
+/*! GF128_Z - Contains bits of the result of GF128 hash.
+ */
+#define AES_GF128_Z_GF128_Z(x)                   (((uint32_t)(((uint32_t)(x)) << AES_GF128_Z_GF128_Z_SHIFT)) & AES_GF128_Z_GF128_Z_MASK)
+/*! @} */
+
+/* The count of AES_GF128_Z */
+#define AES_GF128_Z_COUNT                        (4U)
+
+/*! @name GCM_TAG - GCM Tag bits */
+/*! @{ */
+#define AES_GCM_TAG_GCM_TAG_MASK                 (0xFFFFFFFFU)
+#define AES_GCM_TAG_GCM_TAG_SHIFT                (0U)
+/*! GCM_TAG - Contains bits of the 128 bit GCM tag.
+ */
+#define AES_GCM_TAG_GCM_TAG(x)                   (((uint32_t)(((uint32_t)(x)) << AES_GCM_TAG_GCM_TAG_SHIFT)) & AES_GCM_TAG_GCM_TAG_MASK)
+/*! @} */
+
+/* The count of AES_GCM_TAG */
+#define AES_GCM_TAG_COUNT                        (4U)
+
+
+/*!
+ * @}
+ */ /* end of group AES_Register_Masks */
+
+
+/* AES - Peripheral instance base addresses */
+/** Peripheral AES0 base address */
+#define AES0_BASE                                (0x40086000u)
+/** Peripheral AES0 base pointer */
+#define AES0                                     ((AES_Type *)AES0_BASE)
+/** Array initializer of AES peripheral base addresses */
+#define AES_BASE_ADDRS                           { AES0_BASE }
+/** Array initializer of AES peripheral base pointers */
+#define AES_BASE_PTRS                            { AES0 }
+
+/*!
+ * @}
+ */ /* end of group AES_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- ASYNC_SYSCON Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ASYNC_SYSCON_Peripheral_Access_Layer ASYNC_SYSCON Peripheral Access Layer
+ * @{
+ */
+
+/** ASYNC_SYSCON - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t ASYNCPRESETCTRL;                   /**< Asynchronous peripherals reset control. The ASYNCPRESETCTRL register allows software to reset specific peripherals attached to the async APB bridge. Writing a zero to any assigned bit in this register clears the reset and allows the specified peripheral to operate. Writing a one asserts the reset., offset: 0x0 */
+  __O  uint32_t ASYNCPRESETCTRLSET;                /**< Set bits in ASYNCPRESETCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCPRESETCTRL register, if they are implemented, offset: 0x4 */
+  __O  uint32_t ASYNCPRESETCTRLCLR;                /**< Clear bits in ASYNCPRESETCTRL. Writing ones to this register clears the corresponding bit or bits in the ASYNCPRESETCTRL register, if they are implemented, offset: 0x8 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t ASYNCAPBCLKCTRL;                   /**< Asynchronous peripherals clock control. This register controls how the clock selected for the asynchronous APB peripherals is divided to provide the clock to the asynchronous peripherals, offset: 0x10 */
+  __O  uint32_t ASYNCAPBCLKCTRLSET;                /**< Set bits in ASYNCAPBCLKCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCAPBCLKCTRLSET register, if they are implemented, offset: 0x14 */
+  __O  uint32_t ASYNCAPBCLKCTRLCLR;                /**< Clear bits in ASYNCAPBCLKCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCAPBCLKCTRLSET register, if they are implemented, offset: 0x18 */
+       uint8_t RESERVED_1[4];
+  __IO uint32_t ASYNCAPBCLKSELA;                   /**< Asynchronous APB clock source select, offset: 0x20 */
+       uint8_t RESERVED_2[124];
+  __IO uint32_t TEMPSENSORCTRL;                    /**< Temperature Sensor controls, offset: 0xA0 */
+  __IO uint32_t NFCTAGPADSCTRL;                    /**< NFC Tag pads control for I2C interface to internal NFC Tag (T parts only): I2C interface + 1 interrupt/ field detect input pad + NTAG VDD output pad, offset: 0xA4 */
+  __IO uint32_t XTAL32MLDOCTRL;                    /**< XTAL 32 MHz LDO control register. If XTAL has been auto started due to EFUSE XTAL32MSTART_ENA or BLE low power timers then the effect of these need disabling via SYSCON.XTAL32MCTRL before the full control by this register is possible., offset: 0xA8 */
+  __IO uint32_t XTAL32MCTRL;                       /**< XTAL 32 MHz control register. If XTAL has been auto started due to EFUSE XTAL32MSTART_ENA or BLE low power timers then the effect of these need disabling via SYSCON.XTAL32MCTRL before the full control by this register is possible., offset: 0xAC */
+  __I  uint32_t ANALOGID;                          /**< Analog Interfaces (PMU and Radio) identity registers, offset: 0xB0 */
+  __I  uint32_t RADIOSTATUS;                       /**< All Radio Analog modules status register., offset: 0xB4 */
+       uint8_t RESERVED_3[4];
+  __IO uint32_t DCBUSCTRL;                         /**< DC Bus can be used during device test and evaluation to give observation of internal signals., offset: 0xBC */
+  __IO uint32_t FREQMECTRL;                        /**< Frequency measure register, offset: 0xC0 */
+       uint8_t RESERVED_4[4];
+  __IO uint32_t NFCTAG_VDD;                        /**< NFCTAG VDD output control, offset: 0xC8 */
+  __O  uint32_t SWRESETCTRL;                       /**< Full IC reset request (from Software application)., offset: 0xCC */
+} ASYNC_SYSCON_Type;
+
+/* ----------------------------------------------------------------------------
+   -- ASYNC_SYSCON Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ASYNC_SYSCON_Register_Masks ASYNC_SYSCON Register Masks
+ * @{
+ */
+
+/*! @name ASYNCPRESETCTRL - Asynchronous peripherals reset control. The ASYNCPRESETCTRL register allows software to reset specific peripherals attached to the async APB bridge. Writing a zero to any assigned bit in this register clears the reset and allows the specified peripheral to operate. Writing a one asserts the reset. */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT (1U)
+/*! CT32B0 - Controls the reset for Counter/Timer CT32B0
+ *  0b0..Clear reset to Counter/Timer CT32B0.
+ *  0b1..Assert reset to Counter/Timer CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT (2U)
+/*! CT32B1 - Controls the reset for Counter/Timer CT32B1
+ *  0b0..Clear reset to Counter/Timer CT32B1.
+ *  0b1..Assert reset to Counter/Timer CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCPRESETCTRLSET - Set bits in ASYNCPRESETCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCPRESETCTRL register, if they are implemented */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0_SHIFT (1U)
+/*! CT32B0 - Writing 1 to this register sets the bit ASYNCPRESETCTRL.CT32B0
+ *  0b0..No effect.
+ *  0b1..Set the bit ASYNCPRESETCTRL.CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1_SHIFT (2U)
+/*! CT32B1 - Writing 1 to this register sets the bit ASYNCPRESETCTRL.CT32B1
+ *  0b0..No effect.
+ *  0b1..Set the bit ASYNCPRESETCTRL.CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLSET_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCPRESETCTRLCLR - Clear bits in ASYNCPRESETCTRL. Writing ones to this register clears the corresponding bit or bits in the ASYNCPRESETCTRL register, if they are implemented */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0_SHIFT (1U)
+/*! CT32B0 - Writing 1 to this register clears the bit ASYNCPRESETCTRL.CT32B0
+ *  0b0..No effect.
+ *  0b1..Clear the bit ASYNCPRESETCTRL.CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1_SHIFT (2U)
+/*! CT32B1 - Writing 1 to this register clears the bit ASYNCPRESETCTRL.CT32B1
+ *  0b0..No effect.
+ *  0b1..Clear the bit ASYNCPRESETCTRL.CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLCLR_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCLKCTRL - Asynchronous peripherals clock control. This register controls how the clock selected for the asynchronous APB peripherals is divided to provide the clock to the asynchronous peripherals */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_SHIFT (1U)
+/*! CT32B0 - Controls the clock for Counter/Timer CT32B0
+ *  0b0..Disable clock to Counter/Timer CT32B0.
+ *  0b1..Enable clock to Counter/Timer CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_SHIFT (2U)
+/*! CT32B1 - Controls the clock for Counter/Timer CT32B1
+ *  0b0..Disable clock to Counter/Timer CT32B1.
+ *  0b1..Enable clock to Counter/Timer CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCLKCTRLSET - Set bits in ASYNCAPBCLKCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCAPBCLKCTRLSET register, if they are implemented */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0_SHIFT (1U)
+/*! CT32B0 - Writing 1 to this register sets the bit ASYNCAPBCLKCTRL.CT32B0
+ *  0b0..No effect.
+ *  0b1..Set the bit ASYNCAPBCLKCTRL.CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1_SHIFT (2U)
+/*! CT32B1 - Writing 1 to this register sets the bit ASYNCAPBCLKCTRL.CT32B1
+ *  0b0..No effect.
+ *  0b1..Set the bit ASYNCAPBCLKCTRL.CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCLKCTRLCLR - Clear bits in ASYNCAPBCLKCTRL. Writing ones to this register sets the corresponding bit or bits in the ASYNCAPBCLKCTRLSET register, if they are implemented */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0_MASK (0x2U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0_SHIFT (1U)
+/*! CT32B0 - Writing 1 to this register clears the bit ASYNCAPBCLKCTRL.CT32B0
+ *  0b0..No effect.
+ *  0b1..Clear the ASYNCAPBCLKCTRL.CT32B0.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B0_MASK)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1_MASK (0x4U)
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1_SHIFT (2U)
+/*! CT32B1 - Writing 1 to this register clears the bit ASYNCAPBCLKCTRL.CT32B1
+ *  0b0..No effect.
+ *  0b1..Clear the bit ASYNCAPBCLKCTRL.CT32B1.
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_CT32B1_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCLKSELA - Asynchronous APB clock source select */
+/*! @{ */
+#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK    (0x3U)
+#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT   (0U)
+/*! SEL - Clock source for modules beyond asynchronous Bus bridge: ASYNC_SYSCON itself, timers 0/1.
+ *  0b00..System Bus clock.
+ *  0b01..32 MHz crystal oscillator (XTAL32M).
+ *  0b10..32 MHz free running oscillator (FRO32M).
+ *  0b11..48 MHz free running oscillator (FRO48M).
+ */
+#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL(x)      (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK)
+/*! @} */
+
+/*! @name TEMPSENSORCTRL - Temperature Sensor controls */
+/*! @{ */
+#define ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_MASK  (0x1U)
+#define ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_SHIFT (0U)
+/*! ENABLE - Temperature sensor enable
+ */
+#define ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE(x)    (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_SHIFT)) & ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_MASK)
+#define ASYNC_SYSCON_TEMPSENSORCTRL_CM_MASK      (0xCU)
+#define ASYNC_SYSCON_TEMPSENSORCTRL_CM_SHIFT     (2U)
+/*! CM - Temerature sensor common mode output voltage selection: 0x0: high negative offset added;
+ *    0x1: intermediate negative offset added; 0x2: no offset added; 0x3: low positive offset added.
+ *    Only setting 0x2 should be used.
+ */
+#define ASYNC_SYSCON_TEMPSENSORCTRL_CM(x)        (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_TEMPSENSORCTRL_CM_SHIFT)) & ASYNC_SYSCON_TEMPSENSORCTRL_CM_MASK)
+/*! @} */
+
+/*! @name NFCTAGPADSCTRL - NFC Tag pads control for I2C interface to internal NFC Tag (T parts only): I2C interface + 1 interrupt/ field detect input pad + NTAG VDD output pad */
+/*! @{ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD_MASK (0x1U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD_SHIFT (0U)
+/*! I2C_SDA_EPD - I2C_SDA, Enable weak pull down on IO pad. 0= disabled. 1=pull down enabled.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN_MASK (0x2U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN_SHIFT (1U)
+/*! I2C_SDA_EPUN - I2C_SDA, Enable weak pull up on IO pad, active low. 0=pullup enabled. 1=pullup disabled
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EPUN_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0_MASK (0x4U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0_SHIFT (2U)
+/*! I2C_SDA_EHS0 - I2C_SDA IO Driver slew rate LSB. (I2C_SDA_EHS1, I2C_SDA_EHS0). RESERVED: use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS0_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT_MASK (0x8U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT_SHIFT (3U)
+/*! I2C_SDA_INVERT - I2C_SDA Input polarity. 0 : Input function is not inverted. 1 : Input function is inverted.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_INVERT_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI_MASK (0x10U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI_SHIFT (4U)
+/*! I2C_SDA_ENZI - I2C_SDA Receiver enable, active high
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_ENZI_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF_MASK (0x20U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF_SHIFT (5U)
+/*! I2C_SDA_FILTEROFF - I2C_SDA input glitch filter control. 0 Filter enabled. Short noise pulses
+ *    are filtered out. 1 Filter disabled. No input filtering is done.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_FILTEROFF_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1_MASK (0x40U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1_SHIFT (6U)
+/*! I2C_SDA_EHS1 - I2C_SDA IO Driver slew rate MSB. (I2C_SDA_EHS1, I2C_SDA_EHS0). RESERVED: use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_EHS1_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD_MASK (0x80U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD_SHIFT (7U)
+/*! I2C_SDA_OD - I2C_SDA, Controls open-drain mode. 0 Normal. Normal push-pull output 1 Open-drain.
+ *    Simulated open-drain output (high drive disabled).
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SDA_OD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD_MASK (0x100U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD_SHIFT (8U)
+/*! I2C_SCL_EPD - I2C_SCL, Enable weak pull down on IO pad. 0: disabled; 1: pull down enabled.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN_MASK (0x200U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN_SHIFT (9U)
+/*! I2C_SCL_EPUN - I2C_SCL, Enable weak pull up on IO pad, active low. 0: pullup enabled; 1: pullup disabled.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EPUN_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0_MASK (0x400U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0_SHIFT (10U)
+/*! I2C_SCL_EHS0 - I2C_SCL IO Driver slew rate LSB. (I2C_SCL_EHS1, I2C_SCL_EHS0). RESERVED: use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS0_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI_MASK (0x1000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI_SHIFT (12U)
+/*! I2C_SCL_ENZI - I2C_SCL Receiver enable, active high
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_ENZI_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF_MASK (0x2000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF_SHIFT (13U)
+/*! I2C_SCL_FILTEROFF - I2C_SCL, input glitch filter control: 0: Filter enabled. Short noise pulses
+ *    are filtered out; 1: Filter disabled. No input filtering is done.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_FILTEROFF_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1_MASK (0x4000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1_SHIFT (14U)
+/*! I2C_SCL_EHS1 - I2C_SCL IO Driver slew rate MSB. (I2C_SCL_EHS1, I2C_SCL_EHS0). RESERVED: use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_EHS1_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD_MASK (0x8000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD_SHIFT (15U)
+/*! I2C_SCL_OD - I2C_SCL open-drain mode control: 0: Normal. Normal push-pull output; 1: Open-drain.
+ *    Simulated open-drain output (high drive disabled).
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_I2C_SCL_OD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT_MASK (0x40000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT_SHIFT (18U)
+/*! INT_INVERT - NTAG INT/FD Input polarity: 0: Input function is not inverted; 1: Input function is inverted.
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_INT_INVERT_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI_MASK (0x80000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI_SHIFT (19U)
+/*! INT_ENZI - Reserved. NTAG INT/FD IO cell always enabled, not configurable
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_INT_ENZI_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF_MASK (0x100000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF_SHIFT (20U)
+/*! INT_FILTEROFF - Reserved. NTAG INT/FD IO cell always filters signal, not configurable
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_INT_FILTEROFF_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD_MASK (0x200000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD_SHIFT (21U)
+/*! VDD_EPD - NTAG VDD, Enable weak pull down on IO pad
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPD_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN_MASK (0x400000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN_SHIFT (22U)
+/*! VDD_EPUN - NTAG_VDD, Enable weak pull up on IO pad, active low
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EPUN_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0_MASK (0x800000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0_SHIFT (23U)
+/*! VDD_EHS0 - NTAG VDD IO Driver slew rate LSB. (VDD_EHS1, VDD_EHS0) sets IO cell speed when
+ *    enabled as an output. 00=Low speed, 01=nominal speed, 10=fast speed, 11=high speed. Recommendation
+ *    is to use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS0_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1_MASK (0x8000000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1_SHIFT (27U)
+/*! VDD_EHS1 - NTAG VDD IO Driver slew rate MSB. (VDD_EHS1, VDD_EHS0) sets IO cell speed when
+ *    enabled as an output. 00: Low speed; 01: nominal speed; 10: fast speed; 11: high speed.
+ *    Recommendation is to use default value (0)
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_EHS1_MASK)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD_MASK  (0x10000000U)
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD_SHIFT (28U)
+/*! VDD_OD - NTAG VDD open-drain mode control: 0: Normal. Normal push-pull output; 1: Open-drain.
+ *    Simulated open-drain output (high drive disabled).
+ */
+#define ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD(x)    (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD_SHIFT)) & ASYNC_SYSCON_NFCTAGPADSCTRL_VDD_OD_MASK)
+/*! @} */
+
+/*! @name XTAL32MLDOCTRL - XTAL 32 MHz LDO control register. If XTAL has been auto started due to EFUSE XTAL32MSTART_ENA or BLE low power timers then the effect of these need disabling via SYSCON.XTAL32MCTRL before the full control by this register is possible. */
+/*! @{ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_MASK  (0x2U)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_SHIFT (1U)
+/*! ENABLE - Enable the LDO when set. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE(x)    (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_MASK    (0x38U)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_SHIFT   (3U)
+/*! VOUT - Adjust the output voltage level, setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT(x)      (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_SHIFT)) & ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_MASK)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_MASK   (0xC0U)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_SHIFT  (6U)
+/*! IBIAS - Adjust the biasing current, setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS(x)     (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_SHIFT)) & ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_MASK)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_MASK (0x300U)
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_SHIFT (8U)
+/*! STABMODE - Stability configuration, only required for test purposes.
+ */
+#define ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE(x)  (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_SHIFT)) & ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_MASK)
+/*! @} */
+
+/*! @name XTAL32MCTRL - XTAL 32 MHz control register. If XTAL has been auto started due to EFUSE XTAL32MSTART_ENA or BLE low power timers then the effect of these need disabling via SYSCON.XTAL32MCTRL before the full control by this register is possible. */
+/*! @{ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK (0x1U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_SHIFT (0U)
+/*! XO_ACBUF_PASS_ENABLE - Bypass enable of XTAL AC buffer enable in pll and top level. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_AMP_MASK     (0xEU)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_AMP_SHIFT    (1U)
+/*! XO_AMP - Amplitude selection , Min amp: 001, Max amp: 110. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_AMP(x)       (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_AMP_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_AMP_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_MASK (0x7F0U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_SHIFT (4U)
+/*! XO_OSC_CAP_IN - Internal Capacitor Selection for XTAL_P. Each XTAL pin has a capacitance value
+ *    up to approximately 25pF. Device test calibration data is stored on chip so that a software
+ *    function can configure a capacitiance with high accuracy.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_MASK (0x3F800U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_SHIFT (11U)
+/*! XO_OSC_CAP_OUT - Internal Capacitor Selection for XTAL_N. Each XTAL pin has a capacitance value
+ *    up to approximately 25pF. Device test calibration data is stored on chip so that a software
+ *    function can configure a capacitiance with high accuracy.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK  (0x400000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_SHIFT (22U)
+/*! XO_ENABLE - Enable signal for 32MHz XTAL.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE(x)    (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_GM_MASK      (0x3800000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_GM_SHIFT     (23U)
+/*! XO_GM - Gm value for XTAL.. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_GM(x)        (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_GM_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_GM_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_MASK   (0x4000000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_SHIFT  (26U)
+/*! XO_SLAVE - XTAL in slave mode. Setting managed by software API.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE(x)     (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_MASK (0x8000000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_SHIFT (27U)
+/*! XO_STANDALONE_ENABLE - Selection of the LDO and core XO reference biasing sources (1uA bandgap
+ *    current and 0.6V bandgap voltage): 0: biasing provided by radio reference biasing sources.
+ *    Don't switch to this value without prior radio biasing, LDO XO, core XO, LDO 1.4V and PLL current
+ *    distribution enabling. 1: biasing is provided by Power Management Unit (PMU). Control of this
+ *    bit is generally managed by the radio or clock software functions.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_MASK (0x10000000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_SHIFT (28U)
+/*! XO32M_TO_MCU_ENABLE - Enable the 32MHz clock to MCU and the clock generators.
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_MASK)
+#define ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE_MASK (0x20000000U)
+#define ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE_SHIFT (29U)
+/*! CLK_TO_GPADC_ENABLE - Enable the 16MHz clock to General Purpose ADC
+ */
+#define ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE_SHIFT)) & ASYNC_SYSCON_XTAL32MCTRL_CLK_TO_GPADC_ENABLE_MASK)
+/*! @} */
+
+/*! @name ANALOGID - Analog Interfaces (PMU and Radio) identity registers */
+/*! @{ */
+#define ASYNC_SYSCON_ANALOGID_PMUID_MASK         (0x3FU)
+#define ASYNC_SYSCON_ANALOGID_PMUID_SHIFT        (0U)
+/*! PMUID - PMU Identitty register used ti indicate a version of the PMU.
+ */
+#define ASYNC_SYSCON_ANALOGID_PMUID(x)           (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ANALOGID_PMUID_SHIFT)) & ASYNC_SYSCON_ANALOGID_PMUID_MASK)
+/*! @} */
+
+/*! @name RADIOSTATUS - All Radio Analog modules status register. */
+/*! @{ */
+#define ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_MASK (0x1U)
+#define ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_SHIFT (0U)
+/*! PLLXOREADY - Value of status output by 32M XTAL oscillator. Aserted to indicate that the clock
+ *    is active. Note that the quality of the 32M clock may improve even after this is asserted.
+ *    Additionally, if settings are changed such as ibias control then this status flag will probably
+ *    remain asserted even though changes to the clock signal will be occuring,
+ */
+#define ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_SHIFT)) & ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_MASK)
+/*! @} */
+
+/*! @name DCBUSCTRL - DC Bus can be used during device test and evaluation to give observation of internal signals. */
+/*! @{ */
+#define ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK         (0x1FFU)
+#define ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT        (0U)
+/*! ADDR - ADDR[8] should be set to 1 before entering power down to prevent the risk of a small
+ *    amount of leakage current during power down.
+ */
+#define ASYNC_SYSCON_DCBUSCTRL_ADDR(x)           (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT)) & ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK)
+/*! @} */
+
+/*! @name FREQMECTRL - Frequency measure register */
+/*! @{ */
+#define ASYNC_SYSCON_FREQMECTRL_CAPVAL_MASK      (0x7FFFFFFFU)
+#define ASYNC_SYSCON_FREQMECTRL_CAPVAL_SHIFT     (0U)
+/*! CAPVAL - Frequency Measure control and status; the function differs for a read and write
+ *    operation. CAPVAL: FREQMECTRL[30:0] (Read-only) : Stores the target counter result from the last
+ *    frequency measure activiation, this is used in the calculation of the unknown clock frequency of
+ *    the reference or target clock. SCALE: FREQMECTRL[4:0] (Write-only) : define the count duration,
+ *    (2^SCALE)-1, that reference counter counts to during measurement. Note that the value is 2
+ *    giving a minimum count 2^2-1 = 3. The result of freq_me_plus can be calculated as follows :
+ *    freq_targetclk =freq_refclk* (CAPVAL+1) / ((2^SCALE)-1);
+ */
+#define ASYNC_SYSCON_FREQMECTRL_CAPVAL(x)        (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_FREQMECTRL_CAPVAL_SHIFT)) & ASYNC_SYSCON_FREQMECTRL_CAPVAL_MASK)
+#define ASYNC_SYSCON_FREQMECTRL_PROG_MASK        (0x80000000U)
+#define ASYNC_SYSCON_FREQMECTRL_PROG_SHIFT       (31U)
+/*! PROG - Set this bit to one to initiate a frequency measurement cycle. Hardware clears this bit
+ *    when the measurement cycle has completed and there is valid capture data in the CAPVAL field
+ *    (bits 13:0).
+ */
+#define ASYNC_SYSCON_FREQMECTRL_PROG(x)          (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_FREQMECTRL_PROG_SHIFT)) & ASYNC_SYSCON_FREQMECTRL_PROG_MASK)
+/*! @} */
+
+/*! @name NFCTAG_VDD - NFCTAG VDD output control */
+/*! @{ */
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT_MASK (0x1U)
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT_SHIFT (0U)
+/*! NFCTAG_VDD_OUT - Output value for the NFC Tag Vdd IO, if enabled with NFCTAG_VDD_OE.
+ */
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT_SHIFT)) & ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OUT_MASK)
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE_MASK (0x2U)
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE_SHIFT (1U)
+/*! NFCTAG_VDD_OE - Output enable for the NFC Tag Vdd IO cell.
+ */
+#define ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE_SHIFT)) & ASYNC_SYSCON_NFCTAG_VDD_NFCTAG_VDD_OE_MASK)
+/*! @} */
+
+/*! @name SWRESETCTRL - Full IC reset request (from Software application). */
+/*! @{ */
+#define ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ_MASK (0x1U)
+#define ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ_SHIFT (0U)
+/*! ICRESETREQ - IC reset request. This bit is only valid if VECTKEY is set correctly. 0: No effect;
+ *    1: Request a fulll IC reset level reset
+ */
+#define ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ(x)   (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ_SHIFT)) & ASYNC_SYSCON_SWRESETCTRL_ICRESETREQ_MASK)
+#define ASYNC_SYSCON_SWRESETCTRL_VECTKEY_MASK    (0xFFFF0000U)
+#define ASYNC_SYSCON_SWRESETCTRL_VECTKEY_SHIFT   (16U)
+/*! VECTKEY - Register Key: On write, write 0x05FA to VECTKEY, otherwise the write is ignored.
+ */
+#define ASYNC_SYSCON_SWRESETCTRL_VECTKEY(x)      (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_SWRESETCTRL_VECTKEY_SHIFT)) & ASYNC_SYSCON_SWRESETCTRL_VECTKEY_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group ASYNC_SYSCON_Register_Masks */
+
+
+/* ASYNC_SYSCON - Peripheral instance base addresses */
+/** Peripheral ASYNC_SYSCON base address */
+#define ASYNC_SYSCON_BASE                        (0x40020000u)
+/** Peripheral ASYNC_SYSCON base pointer */
+#define ASYNC_SYSCON                             ((ASYNC_SYSCON_Type *)ASYNC_SYSCON_BASE)
+/** Array initializer of ASYNC_SYSCON peripheral base addresses */
+#define ASYNC_SYSCON_BASE_ADDRS                  { ASYNC_SYSCON_BASE }
+/** Array initializer of ASYNC_SYSCON peripheral base pointers */
+#define ASYNC_SYSCON_BASE_PTRS                   { ASYNC_SYSCON }
+
+/*!
+ * @}
+ */ /* end of group ASYNC_SYSCON_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- BLE_DP_TOP Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup BLE_DP_TOP_Peripheral_Access_Layer BLE_DP_TOP Peripheral Access Layer
+ * @{
+ */
+
+/** BLE_DP_TOP - Register Layout Typedef */
+typedef struct {
+       uint8_t RESERVED_0[176];
+  __IO uint32_t ANT_DIVERSITY;                     /**< Antenna diversity, offset: 0xB0 */
+} BLE_DP_TOP_Type;
+
+/* ----------------------------------------------------------------------------
+   -- BLE_DP_TOP Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup BLE_DP_TOP_Register_Masks BLE_DP_TOP Register Masks
+ * @{
+ */
+
+/*! @name ANT_DIVERSITY - Antenna diversity */
+/*! @{ */
+#define BLE_DP_TOP_ANT_DIVERSITY_ble_ant_selected_MASK (0x1U)
+#define BLE_DP_TOP_ANT_DIVERSITY_ble_ant_selected_SHIFT (0U)
+/*! ble_ant_selected - Selection of antenna when selection mode is direct from register, see
+ *    ble_ant_mode. 0: ADE is asserted. 1: ADE de-asserted. ADO is always the inverse of ADE and so is also
+ *    controlled by this setting as well.
+ */
+#define BLE_DP_TOP_ANT_DIVERSITY_ble_ant_selected(x) (((uint32_t)(((uint32_t)(x)) << BLE_DP_TOP_ANT_DIVERSITY_ble_ant_selected_SHIFT)) & BLE_DP_TOP_ANT_DIVERSITY_ble_ant_selected_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group BLE_DP_TOP_Register_Masks */
+
+
+/* BLE_DP_TOP - Peripheral instance base addresses */
+/** Peripheral BLE_DP_TOP base address */
+#define BLE_DP_TOP_BASE                          (0x40014000u)
+/** Peripheral BLE_DP_TOP base pointer */
+#define BLE_DP_TOP                               ((BLE_DP_TOP_Type *)BLE_DP_TOP_BASE)
+/** Array initializer of BLE_DP_TOP peripheral base addresses */
+#define BLE_DP_TOP_BASE_ADDRS                    { BLE_DP_TOP_BASE }
+/** Array initializer of BLE_DP_TOP peripheral base pointers */
+#define BLE_DP_TOP_BASE_PTRS                     { BLE_DP_TOP }
+
+/*!
+ * @}
+ */ /* end of group BLE_DP_TOP_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- CIC_IRB Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup CIC_IRB_Peripheral_Access_Layer CIC_IRB Peripheral Access Layer
+ * @{
+ */
+
+/** CIC_IRB - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CONF;                              /**< IR Blaster configuration, offset: 0x0 */
+  __IO uint32_t CARRIER;                           /**< IR Blaster carrier configuration, offset: 0x4 */
+  __IO uint32_t FIFO_IN;                           /**< IR Blaster Envelope FIFO input, offset: 0x8 */
+  __I  uint32_t STATUS;                            /**< IR Blaster Status, offset: 0xC */
+  __O  uint32_t CMD;                               /**< IR Blaster Commands, offset: 0x10 */
+       uint8_t RESERVED_0[4044];
+  __I  uint32_t INT_STATUS;                        /**< Interrupt Status, offset: 0xFE0 */
+  __IO uint32_t INT_ENA;                           /**< Interrupt Enable, offset: 0xFE4 */
+  __O  uint32_t INT_CLR;                           /**< Interrupt Clear, offset: 0xFE8 */
+  __O  uint32_t INT_SET;                           /**< Interrupt Set, offset: 0xFEC */
+       uint8_t RESERVED_1[12];
+  __I  uint32_t MODULE_ID;                         /**< IR Blaster Module Identifier, offset: 0xFFC */
+} CIC_IRB_Type;
+
+/* ----------------------------------------------------------------------------
+   -- CIC_IRB Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup CIC_IRB_Register_Masks CIC_IRB Register Masks
+ * @{
+ */
+
+/*! @name CONF - IR Blaster configuration */
+/*! @{ */
+#define CIC_IRB_CONF_ENV_INI_MASK                (0x1U)
+#define CIC_IRB_CONF_ENV_INI_SHIFT               (0U)
+/*! ENV_INI - Initial envelope value. This is the level of the first envelope after IR Blaster start or restart.
+ *  0b0..First envelope will be a low level
+ *  0b1..First envelope will be a high level
+ */
+#define CIC_IRB_CONF_ENV_INI(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_ENV_INI_SHIFT)) & CIC_IRB_CONF_ENV_INI_MASK)
+#define CIC_IRB_CONF_MODE_MASK                   (0x2U)
+#define CIC_IRB_CONF_MODE_SHIFT                  (1U)
+/*! MODE - Blaster mode
+ *  0b0..Normal mode. IR Blaster will stop when it encouter an envelope with ENV_LAST bit = '1'
+ *  0b1..Automatic restart. IR Blaster will transmit all envelopes and stop only when FIFO becames empty. ENV_LAST
+ *       bit only generates an interrupt but doesn't stop transmission.
+ */
+#define CIC_IRB_CONF_MODE(x)                     (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_MODE_SHIFT)) & CIC_IRB_CONF_MODE_MASK)
+#define CIC_IRB_CONF_OUT_MASK                    (0xCU)
+#define CIC_IRB_CONF_OUT_SHIFT                   (2U)
+/*! OUT - Output logic function
+ *  0b00..envelope AND carrier
+ *  0b01..envelope OR carrier
+ *  0b10..envelope NAND carrier
+ *  0b11..envelope NOR carrier
+ */
+#define CIC_IRB_CONF_OUT(x)                      (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_OUT_SHIFT)) & CIC_IRB_CONF_OUT_MASK)
+#define CIC_IRB_CONF_NO_CAR_MASK                 (0x10U)
+#define CIC_IRB_CONF_NO_CAR_SHIFT                (4U)
+/*! NO_CAR - No carrier
+ *  0b0..Normal. IR_OUT = envelope + carrier
+ *  0b1..Carrier is inhibited. IR_OUT = envelope only
+ */
+#define CIC_IRB_CONF_NO_CAR(x)                   (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_NO_CAR_SHIFT)) & CIC_IRB_CONF_NO_CAR_MASK)
+#define CIC_IRB_CONF_CAR_INI_MASK                (0x20U)
+#define CIC_IRB_CONF_CAR_INI_SHIFT               (5U)
+/*! CAR_INI - Initial carrier value.
+ *  0b0..Carrier starts with '0' (the carrier is low during CHIGH[1:0] and high during CLOW[2:0])
+ *  0b1..Carrier starts with '1' (the carrier is high during CHIGH[1:0] and low during CLOW[2:0])
+ */
+#define CIC_IRB_CONF_CAR_INI(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CONF_CAR_INI_SHIFT)) & CIC_IRB_CONF_CAR_INI_MASK)
+/*! @} */
+
+/*! @name CARRIER - IR Blaster carrier configuration */
+/*! @{ */
+#define CIC_IRB_CARRIER_CTU_MASK                 (0xFFFFU)
+#define CIC_IRB_CARRIER_CTU_SHIFT                (0U)
+/*! CTU - Carrier Time Unit (CTU) CTU = CTU * TIRCP, TIRCP = IR module clock period = 1/48MHz. Value
+ *    0x0 is equivalent to 0x1. It is recommended to modify this field when the blaster unit is
+ *    disable (i.e when ENA_ST = '0' in STATUS register)
+ */
+#define CIC_IRB_CARRIER_CTU(x)                   (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CARRIER_CTU_SHIFT)) & CIC_IRB_CARRIER_CTU_MASK)
+#define CIC_IRB_CARRIER_CLOW_MASK                (0x70000U)
+#define CIC_IRB_CARRIER_CLOW_SHIFT               (16U)
+/*! CLOW - Carrier low period. Carrier low level duration = (CLOW + 1) * CTU. It is recommended to
+ *    modify this field when the blaster unit is disable (i.e when ENA_ST = '0' in STATUS register)
+ */
+#define CIC_IRB_CARRIER_CLOW(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CARRIER_CLOW_SHIFT)) & CIC_IRB_CARRIER_CLOW_MASK)
+#define CIC_IRB_CARRIER_CHIGH_MASK               (0x180000U)
+#define CIC_IRB_CARRIER_CHIGH_SHIFT              (19U)
+/*! CHIGH - Carrier high period Carrier high level duration = (CHIGH + 1) * CTU. It is recommended
+ *    to modify this field when the blaster unit is disable (i.e when ENA_ST = '0' in STATUS register)
+ */
+#define CIC_IRB_CARRIER_CHIGH(x)                 (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CARRIER_CHIGH_SHIFT)) & CIC_IRB_CARRIER_CHIGH_MASK)
+/*! @} */
+
+/*! @name FIFO_IN - IR Blaster Envelope FIFO input */
+/*! @{ */
+#define CIC_IRB_FIFO_IN_ENV_MASK                 (0xFFFU)
+#define CIC_IRB_FIFO_IN_ENV_SHIFT                (0U)
+/*! ENV - Envelope duration expressed in carrier period number. Tenvelope = ENV * (CHIGH + CLOW + 2
+ *    ) * CTU. Value 0x000 has the same behaviour has value 0x001.
+ */
+#define CIC_IRB_FIFO_IN_ENV(x)                   (((uint32_t)(((uint32_t)(x)) << CIC_IRB_FIFO_IN_ENV_SHIFT)) & CIC_IRB_FIFO_IN_ENV_MASK)
+#define CIC_IRB_FIFO_IN_ENV_INT_MASK             (0x1000U)
+#define CIC_IRB_FIFO_IN_ENV_INT_SHIFT            (12U)
+/*! ENV_INT - Generate an interrupt when starting emission of the envelope
+ *  0b0..Don't generate interrupt
+ *  0b1..Generate interrupt
+ */
+#define CIC_IRB_FIFO_IN_ENV_INT(x)               (((uint32_t)(((uint32_t)(x)) << CIC_IRB_FIFO_IN_ENV_INT_SHIFT)) & CIC_IRB_FIFO_IN_ENV_INT_MASK)
+#define CIC_IRB_FIFO_IN_ENV_LAST_MASK            (0x2000U)
+#define CIC_IRB_FIFO_IN_ENV_LAST_SHIFT           (13U)
+/*! ENV_LAST - Last envelope.
+ *  0b0..IR Blaster loads the next envelope when this envelope finishes.
+ *  0b1..IR Blaster stops and generates an interrupt when this envelope is completly transmitted. If MODE = '1',
+ *       then IR Blaster only generates an interrupt
+ */
+#define CIC_IRB_FIFO_IN_ENV_LAST(x)              (((uint32_t)(((uint32_t)(x)) << CIC_IRB_FIFO_IN_ENV_LAST_SHIFT)) & CIC_IRB_FIFO_IN_ENV_LAST_MASK)
+/*! @} */
+
+/*! @name STATUS - IR Blaster Status */
+/*! @{ */
+#define CIC_IRB_STATUS_FIFO_LVL_MASK             (0x1FU)
+#define CIC_IRB_STATUS_FIFO_LVL_SHIFT            (0U)
+/*! FIFO_LVL - Current IR Blaster FIFO level
+ *  0b00000..FIFO is empty
+ *  0b10000..FIFO is full
+ */
+#define CIC_IRB_STATUS_FIFO_LVL(x)               (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_FIFO_LVL_SHIFT)) & CIC_IRB_STATUS_FIFO_LVL_MASK)
+#define CIC_IRB_STATUS_FIFO_FULL_MASK            (0x20U)
+#define CIC_IRB_STATUS_FIFO_FULL_SHIFT           (5U)
+/*! FIFO_FULL - IR Blaster FIFO full flag
+ *  0b0..FIFO is not full
+ *  0b1..FIFO is full (FIFO level = 100000)
+ */
+#define CIC_IRB_STATUS_FIFO_FULL(x)              (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_FIFO_FULL_SHIFT)) & CIC_IRB_STATUS_FIFO_FULL_MASK)
+#define CIC_IRB_STATUS_FIFO_EMPTY_MASK           (0x40U)
+#define CIC_IRB_STATUS_FIFO_EMPTY_SHIFT          (6U)
+/*! FIFO_EMPTY - IR Blaster FIFO empty flag
+ *  0b0..FIFO is not empty
+ *  0b1..FIFO is empty (FIFO level = 000000)
+ */
+#define CIC_IRB_STATUS_FIFO_EMPTY(x)             (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_FIFO_EMPTY_SHIFT)) & CIC_IRB_STATUS_FIFO_EMPTY_MASK)
+#define CIC_IRB_STATUS_ENA_ST_MASK               (0x80U)
+#define CIC_IRB_STATUS_ENA_ST_SHIFT              (7U)
+/*! ENA_ST - IR Blaster status
+ *  0b0..IR Blaster is disabled
+ *  0b1..IR Blaster is enabled
+ */
+#define CIC_IRB_STATUS_ENA_ST(x)                 (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_ENA_ST_SHIFT)) & CIC_IRB_STATUS_ENA_ST_MASK)
+#define CIC_IRB_STATUS_RUN_ST_MASK               (0x100U)
+#define CIC_IRB_STATUS_RUN_ST_SHIFT              (8U)
+/*! RUN_ST - IR Blaster run status
+ *  0b0..IR Blaster is not running. Either transmission has not yet been started or it is finished.
+ *  0b1..IR Blaster is running.
+ */
+#define CIC_IRB_STATUS_RUN_ST(x)                 (((uint32_t)(((uint32_t)(x)) << CIC_IRB_STATUS_RUN_ST_SHIFT)) & CIC_IRB_STATUS_RUN_ST_MASK)
+/*! @} */
+
+/*! @name CMD - IR Blaster Commands */
+/*! @{ */
+#define CIC_IRB_CMD_ENA_MASK                     (0x1U)
+#define CIC_IRB_CMD_ENA_SHIFT                    (0U)
+/*! ENA - Enable IR Blaster. This bit is self clearing.
+ *  0b0..No effect
+ *  0b1..Enable IR Blaster
+ */
+#define CIC_IRB_CMD_ENA(x)                       (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CMD_ENA_SHIFT)) & CIC_IRB_CMD_ENA_MASK)
+#define CIC_IRB_CMD_DIS_MASK                     (0x2U)
+#define CIC_IRB_CMD_DIS_SHIFT                    (1U)
+/*! DIS - Disable IR Blaster. This bit is self clearing.
+ *  0b0..No effect
+ *  0b1..Disable IR Blaster. The transmission of envelopes is immediatly stopped. The FIFO is not reinitialized
+ *       (the content of the FIFO is conserved).
+ */
+#define CIC_IRB_CMD_DIS(x)                       (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CMD_DIS_SHIFT)) & CIC_IRB_CMD_DIS_MASK)
+#define CIC_IRB_CMD_START_MASK                   (0x4U)
+#define CIC_IRB_CMD_START_SHIFT                  (2U)
+/*! START - Start IR Blaster. This bit is self clearing.
+ *  0b0..No effect
+ *  0b1..Start transmission Before setting this field, the blaster must be enable (the bit field ENA must be set first).
+ */
+#define CIC_IRB_CMD_START(x)                     (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CMD_START_SHIFT)) & CIC_IRB_CMD_START_MASK)
+#define CIC_IRB_CMD_FIFO_RST_MASK                (0x8U)
+#define CIC_IRB_CMD_FIFO_RST_SHIFT               (3U)
+/*! FIFO_RST - Reset IR Blaster FIFO. This bit is self clearing.
+ *  0b0..No effect
+ *  0b1..Reset FIFO. IR Blaster FIFO is completly re-initialized all data present in FIFO are erased.
+ */
+#define CIC_IRB_CMD_FIFO_RST(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_CMD_FIFO_RST_SHIFT)) & CIC_IRB_CMD_FIFO_RST_MASK)
+/*! @} */
+
+/*! @name INT_STATUS - Interrupt Status */
+/*! @{ */
+#define CIC_IRB_INT_STATUS_ENV_START_INT_MASK    (0x1U)
+#define CIC_IRB_INT_STATUS_ENV_START_INT_SHIFT   (0U)
+/*! ENV_START_INT - IR Blaster has started to transmit an envelope with ENV_INT bit = '1
+ *  0b0..Interrupt is not pending
+ *  0b1..Interrupt is pending
+ */
+#define CIC_IRB_INT_STATUS_ENV_START_INT(x)      (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_STATUS_ENV_START_INT_SHIFT)) & CIC_IRB_INT_STATUS_ENV_START_INT_MASK)
+#define CIC_IRB_INT_STATUS_ENV_LAST_INT_MASK     (0x2U)
+#define CIC_IRB_INT_STATUS_ENV_LAST_INT_SHIFT    (1U)
+/*! ENV_LAST_INT - IR Blaster has finished to transmit an envelope with ENV_LAST bit = '1'.
+ *  0b0..Interrupt is not pending
+ *  0b1..Interrupt is pending
+ */
+#define CIC_IRB_INT_STATUS_ENV_LAST_INT(x)       (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_STATUS_ENV_LAST_INT_SHIFT)) & CIC_IRB_INT_STATUS_ENV_LAST_INT_MASK)
+#define CIC_IRB_INT_STATUS_FIFO_UFL_INT_MASK     (0x4U)
+#define CIC_IRB_INT_STATUS_FIFO_UFL_INT_SHIFT    (2U)
+/*! FIFO_UFL_INT - IR Blaster FIFO underflow. IR Blaster has tried to transmit a data but the FIFO was empty.
+ *  0b0..Interrupt is not pending
+ *  0b1..Interrupt is pending
+ */
+#define CIC_IRB_INT_STATUS_FIFO_UFL_INT(x)       (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_STATUS_FIFO_UFL_INT_SHIFT)) & CIC_IRB_INT_STATUS_FIFO_UFL_INT_MASK)
+/*! @} */
+
+/*! @name INT_ENA - Interrupt Enable */
+/*! @{ */
+#define CIC_IRB_INT_ENA_ENV_START_ENA_MASK       (0x1U)
+#define CIC_IRB_INT_ENA_ENV_START_ENA_SHIFT      (0U)
+/*! ENV_START_ENA - Enable/Disable ENV_START interrupt
+ *  0b0..Disable ENV_START interrupt
+ *  0b1..Enable ENV_START interrupt
+ */
+#define CIC_IRB_INT_ENA_ENV_START_ENA(x)         (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_ENA_ENV_START_ENA_SHIFT)) & CIC_IRB_INT_ENA_ENV_START_ENA_MASK)
+#define CIC_IRB_INT_ENA_ENV_LAST_ENA_MASK        (0x2U)
+#define CIC_IRB_INT_ENA_ENV_LAST_ENA_SHIFT       (1U)
+/*! ENV_LAST_ENA - Enable/Disable ENV_LAST interrupt
+ *  0b0..Disable ENV_LAST interrupt
+ *  0b1..Enable ENV_LAST interrupt
+ */
+#define CIC_IRB_INT_ENA_ENV_LAST_ENA(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_ENA_ENV_LAST_ENA_SHIFT)) & CIC_IRB_INT_ENA_ENV_LAST_ENA_MASK)
+#define CIC_IRB_INT_ENA_FIFO_UFL_ENA_MASK        (0x4U)
+#define CIC_IRB_INT_ENA_FIFO_UFL_ENA_SHIFT       (2U)
+/*! FIFO_UFL_ENA - Enable/Disable FIFO_UFL interrupt
+ *  0b0..Disable FIFO_UFL interrupt
+ *  0b1..Enable FIFO_UFL nterrupt
+ */
+#define CIC_IRB_INT_ENA_FIFO_UFL_ENA(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_ENA_FIFO_UFL_ENA_SHIFT)) & CIC_IRB_INT_ENA_FIFO_UFL_ENA_MASK)
+/*! @} */
+
+/*! @name INT_CLR - Interrupt Clear */
+/*! @{ */
+#define CIC_IRB_INT_CLR_ENV_START_CLR_MASK       (0x1U)
+#define CIC_IRB_INT_CLR_ENV_START_CLR_SHIFT      (0U)
+/*! ENV_START_CLR - Clear ENV_START interrupt
+ *  0b0..no effect
+ *  0b1..clear ENV_START interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_CLR_ENV_START_CLR(x)         (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_CLR_ENV_START_CLR_SHIFT)) & CIC_IRB_INT_CLR_ENV_START_CLR_MASK)
+#define CIC_IRB_INT_CLR_ENV_LAST_CLR_MASK        (0x2U)
+#define CIC_IRB_INT_CLR_ENV_LAST_CLR_SHIFT       (1U)
+/*! ENV_LAST_CLR - Clear ENV_LAST interrupt
+ *  0b0..no effect
+ *  0b1..clear ENV_LAST interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_CLR_ENV_LAST_CLR(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_CLR_ENV_LAST_CLR_SHIFT)) & CIC_IRB_INT_CLR_ENV_LAST_CLR_MASK)
+#define CIC_IRB_INT_CLR_FIFO_UFL_CLR_MASK        (0x4U)
+#define CIC_IRB_INT_CLR_FIFO_UFL_CLR_SHIFT       (2U)
+/*! FIFO_UFL_CLR - Clear FIFO_UFL interrupt
+ *  0b0..no effect
+ *  0b1..clear FIFO_UFL interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_CLR_FIFO_UFL_CLR(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_CLR_FIFO_UFL_CLR_SHIFT)) & CIC_IRB_INT_CLR_FIFO_UFL_CLR_MASK)
+/*! @} */
+
+/*! @name INT_SET - Interrupt Set */
+/*! @{ */
+#define CIC_IRB_INT_SET_ENV_START_SET_MASK       (0x1U)
+#define CIC_IRB_INT_SET_ENV_START_SET_SHIFT      (0U)
+/*! ENV_START_SET - Set ENV_START interrupt
+ *  0b0..no effect
+ *  0b1..set ENV_START interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_SET_ENV_START_SET(x)         (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_SET_ENV_START_SET_SHIFT)) & CIC_IRB_INT_SET_ENV_START_SET_MASK)
+#define CIC_IRB_INT_SET_ENV_LAST_SET_MASK        (0x2U)
+#define CIC_IRB_INT_SET_ENV_LAST_SET_SHIFT       (1U)
+/*! ENV_LAST_SET - Set ENV_LAST interrupt
+ *  0b0..no effect
+ *  0b1..set ENV_LAST interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_SET_ENV_LAST_SET(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_SET_ENV_LAST_SET_SHIFT)) & CIC_IRB_INT_SET_ENV_LAST_SET_MASK)
+#define CIC_IRB_INT_SET_FIFO_UFL_SET_MASK        (0x4U)
+#define CIC_IRB_INT_SET_FIFO_UFL_SET_SHIFT       (2U)
+/*! FIFO_UFL_SET - Set FIFO_UFL interrupt
+ *  0b0..no effect
+ *  0b1..set FIFO_UFL interrupt This bit is self clearing
+ */
+#define CIC_IRB_INT_SET_FIFO_UFL_SET(x)          (((uint32_t)(((uint32_t)(x)) << CIC_IRB_INT_SET_FIFO_UFL_SET_SHIFT)) & CIC_IRB_INT_SET_FIFO_UFL_SET_MASK)
+/*! @} */
+
+/*! @name MODULE_ID - IR Blaster Module Identifier */
+/*! @{ */
+#define CIC_IRB_MODULE_ID_APERTURE_MASK          (0xFFU)
+#define CIC_IRB_MODULE_ID_APERTURE_SHIFT         (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define CIC_IRB_MODULE_ID_APERTURE(x)            (((uint32_t)(((uint32_t)(x)) << CIC_IRB_MODULE_ID_APERTURE_SHIFT)) & CIC_IRB_MODULE_ID_APERTURE_MASK)
+#define CIC_IRB_MODULE_ID_MIN_REV_MASK           (0xF00U)
+#define CIC_IRB_MODULE_ID_MIN_REV_SHIFT          (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define CIC_IRB_MODULE_ID_MIN_REV(x)             (((uint32_t)(((uint32_t)(x)) << CIC_IRB_MODULE_ID_MIN_REV_SHIFT)) & CIC_IRB_MODULE_ID_MIN_REV_MASK)
+#define CIC_IRB_MODULE_ID_MAJ_REV_MASK           (0xF000U)
+#define CIC_IRB_MODULE_ID_MAJ_REV_SHIFT          (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define CIC_IRB_MODULE_ID_MAJ_REV(x)             (((uint32_t)(((uint32_t)(x)) << CIC_IRB_MODULE_ID_MAJ_REV_SHIFT)) & CIC_IRB_MODULE_ID_MAJ_REV_MASK)
+#define CIC_IRB_MODULE_ID_ID_MASK                (0xFFFF0000U)
+#define CIC_IRB_MODULE_ID_ID_SHIFT               (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define CIC_IRB_MODULE_ID_ID(x)                  (((uint32_t)(((uint32_t)(x)) << CIC_IRB_MODULE_ID_ID_SHIFT)) & CIC_IRB_MODULE_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group CIC_IRB_Register_Masks */
+
+
+/* CIC_IRB - Peripheral instance base addresses */
+/** Peripheral CIC_IRB base address */
+#define CIC_IRB_BASE                             (0x40007000u)
+/** Peripheral CIC_IRB base pointer */
+#define CIC_IRB                                  ((CIC_IRB_Type *)CIC_IRB_BASE)
+/** Array initializer of CIC_IRB peripheral base addresses */
+#define CIC_IRB_BASE_ADDRS                       { CIC_IRB_BASE }
+/** Array initializer of CIC_IRB peripheral base pointers */
+#define CIC_IRB_BASE_PTRS                        { CIC_IRB }
+/** Interrupt vectors for the CIC_IRB peripheral type */
+#define CIC_IRB_IRQS                             { CIC_IRB_IRQn }
+
+/*!
+ * @}
+ */ /* end of group CIC_IRB_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- CTIMER Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup CTIMER_Peripheral_Access_Layer CTIMER Peripheral Access Layer
+ * @{
+ */
+
+/** CTIMER - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t IR;                                /**< Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending., offset: 0x0 */
+  __IO uint32_t TCR;                               /**< Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR., offset: 0x4 */
+  __IO uint32_t TC;                                /**< Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR., offset: 0x8 */
+  __IO uint32_t PR;                                /**< Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC., offset: 0xC */
+  __IO uint32_t PC;                                /**< Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface., offset: 0x10 */
+  __IO uint32_t MCR;                               /**< Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs., offset: 0x14 */
+  __IO uint32_t MR[4];                             /**< Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC., array offset: 0x18, array step: 0x4 */
+  __IO uint32_t CCR;                               /**< Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place., offset: 0x28 */
+  __I  uint32_t CR[2];                             /**< Capture Register . CR is loaded with the value of TC when there is an event on the CAPn.0 input., array offset: 0x2C, array step: 0x4 */
+       uint8_t RESERVED_0[8];
+  __IO uint32_t EMR;                               /**< External Match Register. The EMR controls the match function and the external match pins., offset: 0x3C */
+       uint8_t RESERVED_1[48];
+  __IO uint32_t CTCR;                              /**< Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting., offset: 0x70 */
+  __IO uint32_t PWMC;                              /**< PWM Control Register. The PWMCON enables PWM mode for the external match pins., offset: 0x74 */
+} CTIMER_Type;
+
+/* ----------------------------------------------------------------------------
+   -- CTIMER Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup CTIMER_Register_Masks CTIMER Register Masks
+ * @{
+ */
+
+/*! @name IR - Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */
+/*! @{ */
+#define CTIMER_IR_MR0INT_MASK                    (0x1U)
+#define CTIMER_IR_MR0INT_SHIFT                   (0U)
+/*! MR0INT - Interrupt flag for match channel 0.
+ */
+#define CTIMER_IR_MR0INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR0INT_SHIFT)) & CTIMER_IR_MR0INT_MASK)
+#define CTIMER_IR_MR1INT_MASK                    (0x2U)
+#define CTIMER_IR_MR1INT_SHIFT                   (1U)
+/*! MR1INT - Interrupt flag for match channel 1.
+ */
+#define CTIMER_IR_MR1INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR1INT_SHIFT)) & CTIMER_IR_MR1INT_MASK)
+#define CTIMER_IR_MR2INT_MASK                    (0x4U)
+#define CTIMER_IR_MR2INT_SHIFT                   (2U)
+/*! MR2INT - Interrupt flag for match channel 2.
+ */
+#define CTIMER_IR_MR2INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR2INT_SHIFT)) & CTIMER_IR_MR2INT_MASK)
+#define CTIMER_IR_MR3INT_MASK                    (0x8U)
+#define CTIMER_IR_MR3INT_SHIFT                   (3U)
+/*! MR3INT - Interrupt flag for match channel 3.
+ */
+#define CTIMER_IR_MR3INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR3INT_SHIFT)) & CTIMER_IR_MR3INT_MASK)
+#define CTIMER_IR_CR0INT_MASK                    (0x10U)
+#define CTIMER_IR_CR0INT_SHIFT                   (4U)
+/*! CR0INT - Interrupt flag for capture channel 0 event.
+ */
+#define CTIMER_IR_CR0INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR0INT_SHIFT)) & CTIMER_IR_CR0INT_MASK)
+#define CTIMER_IR_CR1INT_MASK                    (0x20U)
+#define CTIMER_IR_CR1INT_SHIFT                   (5U)
+/*! CR1INT - Interrupt flag for capture channel 1 event.
+ */
+#define CTIMER_IR_CR1INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR1INT_SHIFT)) & CTIMER_IR_CR1INT_MASK)
+#define CTIMER_IR_CR2INT_MASK                    (0x40U)
+#define CTIMER_IR_CR2INT_SHIFT                   (6U)
+/*! CR2INT - Interrupt flag for capture channel 2 event.
+ */
+#define CTIMER_IR_CR2INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR2INT_SHIFT)) & CTIMER_IR_CR2INT_MASK)
+#define CTIMER_IR_CR3INT_MASK                    (0x80U)
+#define CTIMER_IR_CR3INT_SHIFT                   (7U)
+/*! CR3INT - Interrupt flag for capture channel 3 event.
+ */
+#define CTIMER_IR_CR3INT(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR3INT_SHIFT)) & CTIMER_IR_CR3INT_MASK)
+/*! @} */
+
+/*! @name TCR - Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */
+/*! @{ */
+#define CTIMER_TCR_CEN_MASK                      (0x1U)
+#define CTIMER_TCR_CEN_SHIFT                     (0U)
+/*! CEN - Counter enable. 0 Disabled.The counters are disabled. 1 Enabled. The Timer Counter and Prescale Counter are enabled.
+ */
+#define CTIMER_TCR_CEN(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CEN_SHIFT)) & CTIMER_TCR_CEN_MASK)
+#define CTIMER_TCR_CRST_MASK                     (0x2U)
+#define CTIMER_TCR_CRST_SHIFT                    (1U)
+/*! CRST - Counter reset. 0 Disabled. Do nothing. 1 Enabled. The Timer Counter and the Prescale
+ *    Counter are synchronously reset on the next positive edge of the APB bus clock. The counters
+ *    remain reset until TCR[1] is returned to zero.
+ */
+#define CTIMER_TCR_CRST(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CRST_SHIFT)) & CTIMER_TCR_CRST_MASK)
+/*! @} */
+
+/*! @name TC - Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR. */
+/*! @{ */
+#define CTIMER_TC_TCVAL_MASK                     (0xFFFFFFFFU)
+#define CTIMER_TC_TCVAL_SHIFT                    (0U)
+/*! TCVAL - Timer counter value.
+ */
+#define CTIMER_TC_TCVAL(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_TC_TCVAL_SHIFT)) & CTIMER_TC_TCVAL_MASK)
+/*! @} */
+
+/*! @name PR - Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC. */
+/*! @{ */
+#define CTIMER_PR_PRVAL_MASK                     (0xFFFFFFFFU)
+#define CTIMER_PR_PRVAL_SHIFT                    (0U)
+/*! PRVAL - Prescale counter value.
+ */
+#define CTIMER_PR_PRVAL(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_PR_PRVAL_SHIFT)) & CTIMER_PR_PRVAL_MASK)
+/*! @} */
+
+/*! @name PC - Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */
+/*! @{ */
+#define CTIMER_PC_PCVAL_MASK                     (0xFFFFFFFFU)
+#define CTIMER_PC_PCVAL_SHIFT                    (0U)
+/*! PCVAL - Prescale counter value.
+ */
+#define CTIMER_PC_PCVAL(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_PC_PCVAL_SHIFT)) & CTIMER_PC_PCVAL_MASK)
+/*! @} */
+
+/*! @name MCR - Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */
+/*! @{ */
+#define CTIMER_MCR_MR0I_MASK                     (0x1U)
+#define CTIMER_MCR_MR0I_SHIFT                    (0U)
+/*! MR0I - Interrupt on MR0: an interrupt is generated when MR0 matches the value in the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR0I(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0I_SHIFT)) & CTIMER_MCR_MR0I_MASK)
+#define CTIMER_MCR_MR0R_MASK                     (0x2U)
+#define CTIMER_MCR_MR0R_SHIFT                    (1U)
+/*! MR0R - Reset on MR0: the TC will be reset if MR0 matches it. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR0R(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0R_SHIFT)) & CTIMER_MCR_MR0R_MASK)
+#define CTIMER_MCR_MR0S_MASK                     (0x4U)
+#define CTIMER_MCR_MR0S_SHIFT                    (2U)
+/*! MR0S - Stop on MR0: the TC and PC will be stopped and TCR[0] will be set to 0 if MR0 matches the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR0S(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0S_SHIFT)) & CTIMER_MCR_MR0S_MASK)
+#define CTIMER_MCR_MR1I_MASK                     (0x8U)
+#define CTIMER_MCR_MR1I_SHIFT                    (3U)
+/*! MR1I - Interrupt on MR1: an interrupt is generated when MR1 matches the value in the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR1I(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1I_SHIFT)) & CTIMER_MCR_MR1I_MASK)
+#define CTIMER_MCR_MR1R_MASK                     (0x10U)
+#define CTIMER_MCR_MR1R_SHIFT                    (4U)
+/*! MR1R - Reset on MR1: the TC will be reset if MR1 matches it. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR1R(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1R_SHIFT)) & CTIMER_MCR_MR1R_MASK)
+#define CTIMER_MCR_MR1S_MASK                     (0x20U)
+#define CTIMER_MCR_MR1S_SHIFT                    (5U)
+/*! MR1S - Stop on MR1: the TC and PC will be stopped and TCR[0] will be set to 0 if MR1 matches the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR1S(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1S_SHIFT)) & CTIMER_MCR_MR1S_MASK)
+#define CTIMER_MCR_MR2I_MASK                     (0x40U)
+#define CTIMER_MCR_MR2I_SHIFT                    (6U)
+/*! MR2I - Interrupt on MR2: an interrupt is generated when MR2 matches the value in the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR2I(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2I_SHIFT)) & CTIMER_MCR_MR2I_MASK)
+#define CTIMER_MCR_MR2R_MASK                     (0x80U)
+#define CTIMER_MCR_MR2R_SHIFT                    (7U)
+/*! MR2R - Reset on MR2: the TC will be reset if MR2 matches it. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR2R(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2R_SHIFT)) & CTIMER_MCR_MR2R_MASK)
+#define CTIMER_MCR_MR2S_MASK                     (0x100U)
+#define CTIMER_MCR_MR2S_SHIFT                    (8U)
+/*! MR2S - Stop on MR2: the TC and PC will be stopped and TCR[0] will be set to 0 if MR2 matches the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR2S(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2S_SHIFT)) & CTIMER_MCR_MR2S_MASK)
+#define CTIMER_MCR_MR3I_MASK                     (0x200U)
+#define CTIMER_MCR_MR3I_SHIFT                    (9U)
+/*! MR3I - Interrupt on MR3: an interrupt is generated when MR3 matches the value in the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR3I(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3I_SHIFT)) & CTIMER_MCR_MR3I_MASK)
+#define CTIMER_MCR_MR3R_MASK                     (0x400U)
+#define CTIMER_MCR_MR3R_SHIFT                    (10U)
+/*! MR3R - Reset on MR3: the TC will be reset if MR3 matches it. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR3R(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3R_SHIFT)) & CTIMER_MCR_MR3R_MASK)
+#define CTIMER_MCR_MR3S_MASK                     (0x800U)
+#define CTIMER_MCR_MR3S_SHIFT                    (11U)
+/*! MR3S - Stop on MR3: the TC and PC will be stopped and TCR[0] will be set to 0 if MR3 matches the TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_MCR_MR3S(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3S_SHIFT)) & CTIMER_MCR_MR3S_MASK)
+/*! @} */
+
+/*! @name MR - Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */
+/*! @{ */
+#define CTIMER_MR_MATCH_MASK                     (0xFFFFFFFFU)
+#define CTIMER_MR_MATCH_SHIFT                    (0U)
+/*! MATCH - Timer counter match value.
+ */
+#define CTIMER_MR_MATCH(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_MR_MATCH_SHIFT)) & CTIMER_MR_MATCH_MASK)
+/*! @} */
+
+/* The count of CTIMER_MR */
+#define CTIMER_MR_COUNT                          (4U)
+
+/*! @name CCR - Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */
+/*! @{ */
+#define CTIMER_CCR_CAP0RE_MASK                   (0x1U)
+#define CTIMER_CCR_CAP0RE_SHIFT                  (0U)
+/*! CAP0RE - Rising edge of capture channel 0: a sequence of 0 then 1 causes CR0 to be loaded with
+ *    the contents of TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_CCR_CAP0RE(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0RE_SHIFT)) & CTIMER_CCR_CAP0RE_MASK)
+#define CTIMER_CCR_CAP0FE_MASK                   (0x2U)
+#define CTIMER_CCR_CAP0FE_SHIFT                  (1U)
+/*! CAP0FE - Falling edge of capture channel 0: a sequence of 1 then 0 causes CR0 to be loaded with
+ *    the contents of TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_CCR_CAP0FE(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0FE_SHIFT)) & CTIMER_CCR_CAP0FE_MASK)
+#define CTIMER_CCR_CAP0I_MASK                    (0x4U)
+#define CTIMER_CCR_CAP0I_SHIFT                   (2U)
+/*! CAP0I - Generate interrupt on channel 0 capture event: a CR0 load generates an interrupt.
+ */
+#define CTIMER_CCR_CAP0I(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0I_SHIFT)) & CTIMER_CCR_CAP0I_MASK)
+#define CTIMER_CCR_CAP1RE_MASK                   (0x8U)
+#define CTIMER_CCR_CAP1RE_SHIFT                  (3U)
+/*! CAP1RE - Rising edge of capture channel 1: a sequence of 0 then 1 causes CR1 to be loaded with
+ *    the contents of TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_CCR_CAP1RE(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1RE_SHIFT)) & CTIMER_CCR_CAP1RE_MASK)
+#define CTIMER_CCR_CAP1FE_MASK                   (0x10U)
+#define CTIMER_CCR_CAP1FE_SHIFT                  (4U)
+/*! CAP1FE - Falling edge of capture channel 1: a sequence of 1 then 0 causes CR1 to be loaded with
+ *    the contents of TC. 0 = disabled. 1 = enabled.
+ */
+#define CTIMER_CCR_CAP1FE(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1FE_SHIFT)) & CTIMER_CCR_CAP1FE_MASK)
+#define CTIMER_CCR_CAP1I_MASK                    (0x20U)
+#define CTIMER_CCR_CAP1I_SHIFT                   (5U)
+/*! CAP1I - Generate interrupt on channel 1 capture event: a CR1 load generates an interrupt.
+ */
+#define CTIMER_CCR_CAP1I(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1I_SHIFT)) & CTIMER_CCR_CAP1I_MASK)
+/*! @} */
+
+/*! @name CR - Capture Register . CR is loaded with the value of TC when there is an event on the CAPn.0 input. */
+/*! @{ */
+#define CTIMER_CR_CAP_MASK                       (0xFFFFFFFFU)
+#define CTIMER_CR_CAP_SHIFT                      (0U)
+/*! CAP - Timer counter capture value.
+ */
+#define CTIMER_CR_CAP(x)                         (((uint32_t)(((uint32_t)(x)) << CTIMER_CR_CAP_SHIFT)) & CTIMER_CR_CAP_MASK)
+/*! @} */
+
+/* The count of CTIMER_CR */
+#define CTIMER_CR_COUNT                          (2U)
+
+/*! @name EMR - External Match Register. The EMR controls the match function and the external match pins. */
+/*! @{ */
+#define CTIMER_EMR_EM0_MASK                      (0x1U)
+#define CTIMER_EMR_EM0_SHIFT                     (0U)
+/*! EM0 - External Match 0. This bit reflects the state of output MAT0, whether or not this output
+ *    is connected to a pin. When a match occurs between the TC and MR0, this bit can either toggle,
+ *    go LOW, go HIGH, or do nothing, as selected by EMR[5:4]. This bit is driven to the MAT pins if
+ *    the match function is selected via IOCON. 0 = LOW. 1 = HIGH.
+ */
+#define CTIMER_EMR_EM0(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM0_SHIFT)) & CTIMER_EMR_EM0_MASK)
+#define CTIMER_EMR_EM1_MASK                      (0x2U)
+#define CTIMER_EMR_EM1_SHIFT                     (1U)
+/*! EM1 - External Match 1. This bit reflects the state of output MAT1, whether or not this output
+ *    is connected to a pin. When a match occurs between the TC and MR1, this bit can either toggle,
+ *    go LOW, go HIGH, or do nothing, as selected by EMR[7:6]. This bit is driven to the MAT pins if
+ *    the match function is selected via IOCON. 0 = LOW. 1 = HIGH.
+ */
+#define CTIMER_EMR_EM1(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM1_SHIFT)) & CTIMER_EMR_EM1_MASK)
+#define CTIMER_EMR_EM2_MASK                      (0x4U)
+#define CTIMER_EMR_EM2_SHIFT                     (2U)
+/*! EM2 - External Match 2. This bit reflects the state of output MAT2, whether or not this output
+ *    is connected to a pin. When a match occurs between the TC and MR2, this bit can either toggle,
+ *    go LOW, go HIGH, or do nothing, as selected by EMR[9:8]. This bit is driven to the MAT pins if
+ *    the match function is selected via IOCON. 0 = LOW. 1 = HIGH
+ */
+#define CTIMER_EMR_EM2(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM2_SHIFT)) & CTIMER_EMR_EM2_MASK)
+#define CTIMER_EMR_EM3_MASK                      (0x8U)
+#define CTIMER_EMR_EM3_SHIFT                     (3U)
+/*! EM3 - External Match 3. This bit reflects the state of output MAT3, whether or not this output
+ *    is connected to a pin. When a match occurs between the TC and MR3, this bit can either toggle,
+ *    go LOW, go HIGH, or do nothing, as selected by MR[11:10]. This bit is driven to the MAT pins
+ *    if the match function is selected via IOCON. 0 = LOW. 1 = HIGH.
+ */
+#define CTIMER_EMR_EM3(x)                        (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM3_SHIFT)) & CTIMER_EMR_EM3_MASK)
+#define CTIMER_EMR_EMC0_MASK                     (0x30U)
+#define CTIMER_EMR_EMC0_SHIFT                    (4U)
+/*! EMC0 - External Match Control 0. Determines the functionality of External Match 0. 0x0 Do
+ *    Nothing. 0x1 Clear. Clear the corresponding External Match bit/output to 0 (MAT0 pin is LOW if
+ *    pinned out). 0x2 Set. Set the corresponding External Match bit/output to 1 (MAT0 pin is HIGH if
+ *    pinned out). 0x3 Toggle. Toggle the corresponding External Match bit/output.
+ */
+#define CTIMER_EMR_EMC0(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC0_SHIFT)) & CTIMER_EMR_EMC0_MASK)
+#define CTIMER_EMR_EMC1_MASK                     (0xC0U)
+#define CTIMER_EMR_EMC1_SHIFT                    (6U)
+/*! EMC1 - External Match Control 1. Determines the functionality of External Match 1. 0x0 Do
+ *    Nothing. 0x1 Clear. Clear the corresponding External Match bit/output to 0 (MAT1 pin is LOW if
+ *    pinned out). 0x2 Set. Set the corresponding External Match bit/output to 1 (MAT1 pin is HIGH if
+ *    pinned out). 0x3 Toggle. Toggle the corresponding External Match bit/output.
+ */
+#define CTIMER_EMR_EMC1(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC1_SHIFT)) & CTIMER_EMR_EMC1_MASK)
+#define CTIMER_EMR_EMC2_MASK                     (0x300U)
+#define CTIMER_EMR_EMC2_SHIFT                    (8U)
+/*! EMC2 - External Match Control 2. Determines the functionality of External Match 2. 0x0 Do
+ *    Nothing. 0x1 Clear. Clear the corresponding External Match bit/output to 0 (MAT2 pin is LOW if
+ *    pinned out). 0x2 Set. Set the corresponding External Match bit/output to 1 (MAT2 pin is HIGH if
+ *    pinned out). 0x3 Toggle. Toggle the corresponding External Match bit/output.
+ */
+#define CTIMER_EMR_EMC2(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC2_SHIFT)) & CTIMER_EMR_EMC2_MASK)
+#define CTIMER_EMR_EMC3_MASK                     (0xC00U)
+#define CTIMER_EMR_EMC3_SHIFT                    (10U)
+/*! EMC3 - External Match Control 3. Determines the functionality of External Match 3. 0x0 Do
+ *    Nothing. 0x1 Clear. Clear the corresponding External Match bit/output to 0 (MAT3 pin is LOW if
+ *    pinned out). 0x2 Set. Set the corresponding External Match bit/output to 1 (MAT3 pin is HIGH if
+ *    pinned out). 0x3 Toggle. Toggle the corresponding External Match bit/output.
+ */
+#define CTIMER_EMR_EMC3(x)                       (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC3_SHIFT)) & CTIMER_EMR_EMC3_MASK)
+/*! @} */
+
+/*! @name CTCR - Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */
+/*! @{ */
+#define CTIMER_CTCR_CTMODE_MASK                  (0x3U)
+#define CTIMER_CTCR_CTMODE_SHIFT                 (0U)
+/*! CTMODE - Counter/Timer Mode This field selects which rising APB bus clock edges can increment
+ *    Timer s Prescale Counter (PC), or clear PC and increment Timer Counter (TC). Timer Mode: the TC
+ *    is incremented when the Prescale Counter matches the Prescale Register. 0x0 Timer Mode.
+ *    Incremented every rising APB bus clock edge. 0x1 Counter Mode rising edge. TC is incremented on
+ *    rising edges on the CAP input selected by bits 3:2. 0x2 Counter Mode falling edge. TC is
+ *    incremented on falling edges on the CAP input selected by bits 3:2. 0x3 Counter Mode dual edge. TC is
+ *    incremented on both edges on the CAP input selected by bits 3:2.
+ */
+#define CTIMER_CTCR_CTMODE(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CTMODE_SHIFT)) & CTIMER_CTCR_CTMODE_MASK)
+#define CTIMER_CTCR_CINSEL_MASK                  (0xCU)
+#define CTIMER_CTCR_CINSEL_SHIFT                 (2U)
+/*! CINSEL - Count Input Select When bits 1:0 in this register are not 00, these bits select which
+ *    CAP pin is sampled for clocking. Note: If Counter mode is selected for a particular CAPn input
+ *    in the CTCR, the 3 bits for that input in the Capture Control Register (CCR) must be
+ *    programmed as 000. However, capture and/or interrupt can be selected for the other 3 CAPn inputs in the
+ *    same timer. 0x0 Channel 0. CAPn.0 for CT32Bn 0x1 Channel 1. CAPn.1 for CT32Bn 0x2 Channel 2.
+ *    CAPn.2 for CT32Bn 0x3 Channel 3. CAPn.3 for CT32Bn
+ */
+#define CTIMER_CTCR_CINSEL(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CINSEL_SHIFT)) & CTIMER_CTCR_CINSEL_MASK)
+#define CTIMER_CTCR_ENCC_MASK                    (0x10U)
+#define CTIMER_CTCR_ENCC_SHIFT                   (4U)
+/*! ENCC - Setting this bit to 1 enables clearing of the timer and the prescaler when the
+ *    capture-edge event specified in bits 7:5 occurs.
+ */
+#define CTIMER_CTCR_ENCC(x)                      (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_ENCC_SHIFT)) & CTIMER_CTCR_ENCC_MASK)
+#define CTIMER_CTCR_SELCC_MASK                   (0xE0U)
+#define CTIMER_CTCR_SELCC_SHIFT                  (5U)
+/*! SELCC - Edge select. When bit 4 is 1, these bits select which capture input edge will cause the
+ *    timer and prescaler to be cleared. These bits have no effect when bit 4 is low. Values 0x2 to
+ *    0x3 and 0x6 to 0x7 are reserved. 0 0x0 Channel 0 Rising Edge. Rising edge of the signal on
+ *    capture channel 0 clears the timer (if bit 4 is set). 0x1 Channel 0 Falling Edge. Falling edge of
+ *    the signal on capture channel 0 clears the timer (if bit 4 is set). 0x2 Channel 1 Rising
+ *    Edge. Rising edge of the signal on capture channel 1 clears the timer (if bit 4 is set). 0x3
+ *    Channel 1 Falling Edge. Falling edge of the signal on capture channel 1 clears the timer (if bit 4
+ *    is set). 0x4 Channel 2 Rising Edge. Rising edge of the signal on capture channel 2 clears the
+ *    timer (if bit 4 is set). 0x5 Channel 2 Falling Edge. Falling edge of the signal on capture
+ *    channel 2 clears the timer (if bit 4 is set).
+ */
+#define CTIMER_CTCR_SELCC(x)                     (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_SELCC_SHIFT)) & CTIMER_CTCR_SELCC_MASK)
+/*! @} */
+
+/*! @name PWMC - PWM Control Register. The PWMCON enables PWM mode for the external match pins. */
+/*! @{ */
+#define CTIMER_PWMC_PWMEN0_MASK                  (0x1U)
+#define CTIMER_PWMC_PWMEN0_SHIFT                 (0U)
+/*! PWMEN0 - PWM mode enable for channel0. 0 Match. CT32Bn_MAT0 is controlled by EM0. 1 PWM. PWM mode is enabled for CT32Bn_MAT0.
+ */
+#define CTIMER_PWMC_PWMEN0(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN0_SHIFT)) & CTIMER_PWMC_PWMEN0_MASK)
+#define CTIMER_PWMC_PWMEN1_MASK                  (0x2U)
+#define CTIMER_PWMC_PWMEN1_SHIFT                 (1U)
+/*! PWMEN1 - PWM mode enable for channel1. 0 Match. CT32Bn_MAT01 is controlled by EM1. 1 PWM. PWM mode is enabled for CT32Bn_MAT1.
+ */
+#define CTIMER_PWMC_PWMEN1(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN1_SHIFT)) & CTIMER_PWMC_PWMEN1_MASK)
+#define CTIMER_PWMC_PWMEN2_MASK                  (0x4U)
+#define CTIMER_PWMC_PWMEN2_SHIFT                 (2U)
+/*! PWMEN2 - PWM mode enable for channel2. 0 Match. CT32Bn_MAT2 is controlled by EM2. 1 PWM. PWM mode is enabled for CT32Bn_MAT2.
+ */
+#define CTIMER_PWMC_PWMEN2(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN2_SHIFT)) & CTIMER_PWMC_PWMEN2_MASK)
+#define CTIMER_PWMC_PWMEN3_MASK                  (0x8U)
+#define CTIMER_PWMC_PWMEN3_SHIFT                 (3U)
+/*! PWMEN3 - PWM mode enable for channel3. Note: It is recommended to use match channel 3 to set the
+ *    PWM cycle. 0 Match. CT32Bn_MAT3 is controlled by EM3. 1 PWM. PWM mode is enabled for
+ *    CT132Bn_MAT3
+ */
+#define CTIMER_PWMC_PWMEN3(x)                    (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN3_SHIFT)) & CTIMER_PWMC_PWMEN3_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group CTIMER_Register_Masks */
+
+
+/* CTIMER - Peripheral instance base addresses */
+/** Peripheral CTIMER0 base address */
+#define CTIMER0_BASE                             (0x40021000u)
+/** Peripheral CTIMER0 base pointer */
+#define CTIMER0                                  ((CTIMER_Type *)CTIMER0_BASE)
+/** Peripheral CTIMER1 base address */
+#define CTIMER1_BASE                             (0x40022000u)
+/** Peripheral CTIMER1 base pointer */
+#define CTIMER1                                  ((CTIMER_Type *)CTIMER1_BASE)
+/** Array initializer of CTIMER peripheral base addresses */
+#define CTIMER_BASE_ADDRS                        { CTIMER0_BASE, CTIMER1_BASE }
+/** Array initializer of CTIMER peripheral base pointers */
+#define CTIMER_BASE_PTRS                         { CTIMER0, CTIMER1 }
+/** Interrupt vectors for the CTIMER peripheral type */
+#define CTIMER_IRQS                              { CTIMER0_IRQn, CTIMER1_IRQn }
+
+/*!
+ * @}
+ */ /* end of group CTIMER_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- DMA Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup DMA_Peripheral_Access_Layer DMA Peripheral Access Layer
+ * @{
+ */
+
+/** DMA - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< DMA control., offset: 0x0 */
+  __I  uint32_t INTSTAT;                           /**< Interrupt status., offset: 0x4 */
+  __IO uint32_t SRAMBASE;                          /**< SRAM address of the channel configuration table., offset: 0x8 */
+       uint8_t RESERVED_0[20];
+  struct {                                         /* offset: 0x20, array step: 0x5C */
+    __IO uint32_t ENABLESET;                         /**< Channel Enable read and Set for all DMA channels, array offset: 0x20, array step: 0x5C */
+         uint8_t RESERVED_0[4];
+    __O  uint32_t ENABLECLR;                         /**< Channel Enable Clear for all DMA channels., array offset: 0x28, array step: 0x5C */
+         uint8_t RESERVED_1[4];
+    __I  uint32_t ACTIVE;                            /**< Channel Active status for all DMA channels., array offset: 0x30, array step: 0x5C */
+         uint8_t RESERVED_2[4];
+    __I  uint32_t BUSY;                              /**< Channel Busy status for all DMA channels., array offset: 0x38, array step: 0x5C */
+         uint8_t RESERVED_3[4];
+    __IO uint32_t ERRINT;                            /**< Error Interrupt status for all DMA channels., array offset: 0x40, array step: 0x5C */
+         uint8_t RESERVED_4[4];
+    __IO uint32_t INTENSET;                          /**< Interrupt Enable read and Set for all DMA channels., array offset: 0x48, array step: 0x5C */
+         uint8_t RESERVED_5[4];
+    __O  uint32_t INTENCLR;                          /**< Interrupt Enable Clear for all DMA channels., array offset: 0x50, array step: 0x5C */
+         uint8_t RESERVED_6[4];
+    __IO uint32_t INTA;                              /**< Interrupt A status for all DMA channels., array offset: 0x58, array step: 0x5C */
+         uint8_t RESERVED_7[4];
+    __IO uint32_t INTB;                              /**< Interrupt B status for all DMA channels., array offset: 0x60, array step: 0x5C */
+         uint8_t RESERVED_8[4];
+    __O  uint32_t SETVALID;                          /**< Set ValidPending control bits for all DMA channels., array offset: 0x68, array step: 0x5C */
+         uint8_t RESERVED_9[4];
+    __O  uint32_t SETTRIG;                           /**< Set Trigger control bits for all DMA channels., array offset: 0x70, array step: 0x5C */
+         uint8_t RESERVED_10[4];
+    __O  uint32_t ABORT;                             /**< Channel Abort control for all DMA channels., array offset: 0x78, array step: 0x5C */
+  } COMMON[1];
+       uint8_t RESERVED_1[900];
+  struct {                                         /* offset: 0x400, array step: 0x10 */
+    __IO uint32_t CFG;                               /**< Configuration register for DMA channel x, array offset: 0x400, array step: 0x10 */
+    __I  uint32_t CTLSTAT;                           /**< Control and status register for DMA channel x, array offset: 0x404, array step: 0x10 */
+    __IO uint32_t XFERCFG;                           /**< Transfer configuration register for DMA channel x, array offset: 0x408, array step: 0x10 */
+    __IO uint32_t RESERVED0;                         /**< Reserved, array offset: 0x40C, array step: 0x10 */
+  } CHANNEL[19];
+} DMA_Type;
+
+/* ----------------------------------------------------------------------------
+   -- DMA Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup DMA_Register_Masks DMA Register Masks
+ * @{
+ */
+
+/*! @name CTRL - DMA control. */
+/*! @{ */
+#define DMA_CTRL_ENABLE_MASK                     (0x1U)
+#define DMA_CTRL_ENABLE_SHIFT                    (0U)
+/*! ENABLE - DMA controller master enable. 0: Disabled. The DMA controller is disabled. This clears
+ *    any triggers that were asserted at the point when disabled, but does not prevent re-triggering
+ *    when the DMA controller is re-enabled. 1: Enabled. The DMA controller is enabled.
+ */
+#define DMA_CTRL_ENABLE(x)                       (((uint32_t)(((uint32_t)(x)) << DMA_CTRL_ENABLE_SHIFT)) & DMA_CTRL_ENABLE_MASK)
+/*! @} */
+
+/*! @name INTSTAT - Interrupt status. */
+/*! @{ */
+#define DMA_INTSTAT_ACTIVEINT_MASK               (0x2U)
+#define DMA_INTSTAT_ACTIVEINT_SHIFT              (1U)
+/*! ACTIVEINT - Summarizes whether any enabled interrupts (other than error interrupts) are pending.
+ *    0: Not pending. No enabled interrupts are pending. 1: Pending. At least one enabled interrupt
+ *    is pending.
+ */
+#define DMA_INTSTAT_ACTIVEINT(x)                 (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEINT_SHIFT)) & DMA_INTSTAT_ACTIVEINT_MASK)
+#define DMA_INTSTAT_ACTIVEERRINT_MASK            (0x4U)
+#define DMA_INTSTAT_ACTIVEERRINT_SHIFT           (2U)
+/*! ACTIVEERRINT - Summarizes whether any error interrupts are pending. 0: Not pending. No error
+ *    interrupts are pending. 1: Pending. At least one error interrupt is pending.
+ */
+#define DMA_INTSTAT_ACTIVEERRINT(x)              (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEERRINT_SHIFT)) & DMA_INTSTAT_ACTIVEERRINT_MASK)
+/*! @} */
+
+/*! @name SRAMBASE - SRAM address of the channel configuration table. */
+/*! @{ */
+#define DMA_SRAMBASE_OFFSET_MASK                 (0xFFFFFE00U)
+#define DMA_SRAMBASE_OFFSET_SHIFT                (9U)
+/*! OFFSET - Address bits 31:9 of the beginning of the DMA descriptor table. For 19 channels, the
+ *    table must begin on a 512 byte boundary. The SRAMBASE register must be configured with an
+ *    address (preferably in on-chip SRAM) where DMA descriptors will be stored.
+ */
+#define DMA_SRAMBASE_OFFSET(x)                   (((uint32_t)(((uint32_t)(x)) << DMA_SRAMBASE_OFFSET_SHIFT)) & DMA_SRAMBASE_OFFSET_MASK)
+/*! @} */
+
+/*! @name COMMON_ENABLESET - Channel Enable read and Set for all DMA channels */
+/*! @{ */
+#define DMA_COMMON_ENABLESET_ENA_MASK            (0xFFFFFFFFU)
+#define DMA_COMMON_ENABLESET_ENA_SHIFT           (0U)
+/*! ENA - Enable for DMA channels. Bit n enables or disables DMA channel n. 0: disabled. 1: enabled.
+ */
+#define DMA_COMMON_ENABLESET_ENA(x)              (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLESET_ENA_SHIFT)) & DMA_COMMON_ENABLESET_ENA_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ENABLESET */
+#define DMA_COMMON_ENABLESET_COUNT               (1U)
+
+/*! @name COMMON_ENABLECLR - Channel Enable Clear for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_ENABLECLR_CLR_MASK            (0xFFFFFFFFU)
+#define DMA_COMMON_ENABLECLR_CLR_SHIFT           (0U)
+/*! CLR - Writing ones to this register clears the corresponding bits in ENABLESET0. Bit n clears the channel enable bit n.
+ */
+#define DMA_COMMON_ENABLECLR_CLR(x)              (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLECLR_CLR_SHIFT)) & DMA_COMMON_ENABLECLR_CLR_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ENABLECLR */
+#define DMA_COMMON_ENABLECLR_COUNT               (1U)
+
+/*! @name COMMON_ACTIVE - Channel Active status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_ACTIVE_ACT_MASK               (0xFFFFFFFFU)
+#define DMA_COMMON_ACTIVE_ACT_SHIFT              (0U)
+/*! ACT - Active flag for DMA channel n. Bit n corresponds to DMA channel n. 0: not active. 1: active.
+ */
+#define DMA_COMMON_ACTIVE_ACT(x)                 (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ACTIVE_ACT_SHIFT)) & DMA_COMMON_ACTIVE_ACT_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ACTIVE */
+#define DMA_COMMON_ACTIVE_COUNT                  (1U)
+
+/*! @name COMMON_BUSY - Channel Busy status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_BUSY_BSY_MASK                 (0xFFFFFFFFU)
+#define DMA_COMMON_BUSY_BSY_SHIFT                (0U)
+/*! BSY - Busy flag for DMA channel n. Bit n corresponds to DMA channel n. 0 : not busy. 1: busy.
+ */
+#define DMA_COMMON_BUSY_BSY(x)                   (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_BUSY_BSY_SHIFT)) & DMA_COMMON_BUSY_BSY_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_BUSY */
+#define DMA_COMMON_BUSY_COUNT                    (1U)
+
+/*! @name COMMON_ERRINT - Error Interrupt status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_ERRINT_ERR_MASK               (0xFFFFFFFFU)
+#define DMA_COMMON_ERRINT_ERR_SHIFT              (0U)
+/*! ERR - Error Interrupt flag for DMA channel n. Bit n corresponds to DMA channel n. 0: error
+ *    interrupt is not active. 1: error interrupt is active.
+ */
+#define DMA_COMMON_ERRINT_ERR(x)                 (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ERRINT_ERR_SHIFT)) & DMA_COMMON_ERRINT_ERR_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ERRINT */
+#define DMA_COMMON_ERRINT_COUNT                  (1U)
+
+/*! @name COMMON_INTENSET - Interrupt Enable read and Set for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_INTENSET_INTEN_MASK           (0xFFFFFFFFU)
+#define DMA_COMMON_INTENSET_INTEN_SHIFT          (0U)
+/*! INTEN - Interrupt Enable read and set for DMA channel n. Bit n corresponds to DMA channel n. 0:
+ *    interrupt for DMA channel is disabled. 1: interrupt for DMA channel is enabled.
+ */
+#define DMA_COMMON_INTENSET_INTEN(x)             (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENSET_INTEN_SHIFT)) & DMA_COMMON_INTENSET_INTEN_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_INTENSET */
+#define DMA_COMMON_INTENSET_COUNT                (1U)
+
+/*! @name COMMON_INTENCLR - Interrupt Enable Clear for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_INTENCLR_CLR_MASK             (0xFFFFFFFFU)
+#define DMA_COMMON_INTENCLR_CLR_SHIFT            (0U)
+/*! CLR - Writing ones to this register clears corresponding bits in the INTENSET0. Bit n corresponds to DMA channel n.
+ */
+#define DMA_COMMON_INTENCLR_CLR(x)               (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENCLR_CLR_SHIFT)) & DMA_COMMON_INTENCLR_CLR_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_INTENCLR */
+#define DMA_COMMON_INTENCLR_COUNT                (1U)
+
+/*! @name COMMON_INTA - Interrupt A status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_INTA_IA_MASK                  (0xFFFFFFFFU)
+#define DMA_COMMON_INTA_IA_SHIFT                 (0U)
+/*! IA - Interrupt A status for DMA channel n. Bit n corresponds to DMA channel n. 0: the DMA
+ *    channel interrupt A is not active. 1: the DMA channel interrupt A is active.
+ */
+#define DMA_COMMON_INTA_IA(x)                    (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTA_IA_SHIFT)) & DMA_COMMON_INTA_IA_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_INTA */
+#define DMA_COMMON_INTA_COUNT                    (1U)
+
+/*! @name COMMON_INTB - Interrupt B status for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_INTB_IB_MASK                  (0xFFFFFFFFU)
+#define DMA_COMMON_INTB_IB_SHIFT                 (0U)
+/*! IB - Interrupt B status for DMA channel n. Bit n corresponds to DMA channel n. 0: the DMA
+ *    channel interrupt B is not active. 1: the DMA channel interrupt B is active.
+ */
+#define DMA_COMMON_INTB_IB(x)                    (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTB_IB_SHIFT)) & DMA_COMMON_INTB_IB_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_INTB */
+#define DMA_COMMON_INTB_COUNT                    (1U)
+
+/*! @name COMMON_SETVALID - Set ValidPending control bits for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_SETVALID_SV_MASK              (0xFFFFFFFFU)
+#define DMA_COMMON_SETVALID_SV_SHIFT             (0U)
+/*! SV - SETVALID control for DMA channel n. Bit n corresponds to DMA channel n. 0: no effect. 1:
+ *    sets the VALIDPENDING control bit for DMA channel n
+ */
+#define DMA_COMMON_SETVALID_SV(x)                (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETVALID_SV_SHIFT)) & DMA_COMMON_SETVALID_SV_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_SETVALID */
+#define DMA_COMMON_SETVALID_COUNT                (1U)
+
+/*! @name COMMON_SETTRIG - Set Trigger control bits for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_SETTRIG_TRIG_MASK             (0xFFFFFFFFU)
+#define DMA_COMMON_SETTRIG_TRIG_SHIFT            (0U)
+/*! TRIG - Set Trigger control bit for DMA channel n. Bit n corresponds to DMA channel n. 0: no
+ *    effect. 1: sets the TRIG bit for DMA channel n.
+ */
+#define DMA_COMMON_SETTRIG_TRIG(x)               (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETTRIG_TRIG_SHIFT)) & DMA_COMMON_SETTRIG_TRIG_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_SETTRIG */
+#define DMA_COMMON_SETTRIG_COUNT                 (1U)
+
+/*! @name COMMON_ABORT - Channel Abort control for all DMA channels. */
+/*! @{ */
+#define DMA_COMMON_ABORT_ABORTCTRL_MASK          (0xFFFFFFFFU)
+#define DMA_COMMON_ABORT_ABORTCTRL_SHIFT         (0U)
+/*! ABORTCTRL - Abort control for DMA channel 0. Bit n corresponds to DMA channel n. 0: no effect.
+ *    1: aborts DMA operations on channel n.
+ */
+#define DMA_COMMON_ABORT_ABORTCTRL(x)            (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ABORT_ABORTCTRL_SHIFT)) & DMA_COMMON_ABORT_ABORTCTRL_MASK)
+/*! @} */
+
+/* The count of DMA_COMMON_ABORT */
+#define DMA_COMMON_ABORT_COUNT                   (1U)
+
+/*! @name CHANNEL_CFG - Configuration register for DMA channel x */
+/*! @{ */
+#define DMA_CHANNEL_CFG_PERIPHREQEN_MASK         (0x1U)
+#define DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT        (0U)
+/*! PERIPHREQEN - Peripheral request Enable. If a DMA channel is used to perform a memory-to-memory
+ *    move, any peripheral DMA request associated with that channel can be disabled to prevent any
+ *    interaction between the peripheral and the DMA controller. 0 Disabled. Peripheral DMA requests
+ *    are disabled. 1 Enabled. Peripheral DMA requests are enabled.
+ */
+#define DMA_CHANNEL_CFG_PERIPHREQEN(x)           (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT)) & DMA_CHANNEL_CFG_PERIPHREQEN_MASK)
+#define DMA_CHANNEL_CFG_HWTRIGEN_MASK            (0x2U)
+#define DMA_CHANNEL_CFG_HWTRIGEN_SHIFT           (1U)
+/*! HWTRIGEN - Hardware Triggering Enable for this channel. 0 Disabled. Hardware triggering is not
+ *    used. 1 Enabled. Use hardware triggering.
+ */
+#define DMA_CHANNEL_CFG_HWTRIGEN(x)              (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_HWTRIGEN_SHIFT)) & DMA_CHANNEL_CFG_HWTRIGEN_MASK)
+#define DMA_CHANNEL_CFG_TRIGPOL_MASK             (0x10U)
+#define DMA_CHANNEL_CFG_TRIGPOL_SHIFT            (4U)
+/*! TRIGPOL - Trigger Polarity. Selects the polarity of a hardware trigger for this channel. 0
+ *    Active low - falling edge. Hardware trigger is active low or falling edge triggered, based on
+ *    TRIGTYPE. 1 Active high - rising edge. Hardware trigger is active high or rising edge triggered,
+ *    based on TRIGTYPE.
+ */
+#define DMA_CHANNEL_CFG_TRIGPOL(x)               (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGPOL_SHIFT)) & DMA_CHANNEL_CFG_TRIGPOL_MASK)
+#define DMA_CHANNEL_CFG_TRIGTYPE_MASK            (0x20U)
+#define DMA_CHANNEL_CFG_TRIGTYPE_SHIFT           (5U)
+/*! TRIGTYPE - Trigger Type. Selects hardware trigger as edge triggered or level triggered. 0 Edge.
+ *    Hardware trigger is edge triggered. Transfers will be initiated and completed, as specified
+ *    for a single trigger. 1 Level. Hardware trigger is level triggered. Note that when level
+ *    triggering without burst (BURSTPOWER = 0) is selected, only hardware triggers should be used on that
+ *    channel. Transfers continue as long as the trigger level is asserted. Once the trigger is
+ *    de-asserted, the transfer will be paused until the trigger is, again, asserted. However, the
+ *    transfer will not be paused until any remaining transfers within the current BURSTPOWER length are
+ *    completed.
+ */
+#define DMA_CHANNEL_CFG_TRIGTYPE(x)              (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGTYPE_SHIFT)) & DMA_CHANNEL_CFG_TRIGTYPE_MASK)
+#define DMA_CHANNEL_CFG_TRIGBURST_MASK           (0x40U)
+#define DMA_CHANNEL_CFG_TRIGBURST_SHIFT          (6U)
+/*! TRIGBURST - Trigger Burst. Selects whether hardware triggers cause a single or burst transfer. 0
+ *    Single transfer. Hardware trigger causes a single transfer. 1 Burst transfer. When the
+ *    trigger for this channel is set to edge triggered, a hardware trigger causes a burst transfer, as
+ *    defined by BURSTPOWER. When the trigger for this channel is set to level triggered, a hardware
+ *    trigger causes transfers to continue as long as the trigger is asserted, unless the transfer is
+ *    complete.
+ */
+#define DMA_CHANNEL_CFG_TRIGBURST(x)             (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGBURST_SHIFT)) & DMA_CHANNEL_CFG_TRIGBURST_MASK)
+#define DMA_CHANNEL_CFG_BURSTPOWER_MASK          (0xF00U)
+#define DMA_CHANNEL_CFG_BURSTPOWER_SHIFT         (8U)
+/*! BURSTPOWER - Burst Power is used in two ways. It always selects the address wrap size when
+ *    SRCBURSTWRAP and/or DSTBURSTWRAP modes are selected (see descriptions elsewhere in this register).
+ *    When the TRIGBURST field elsewhere in this register = 1, Burst Power selects how many
+ *    transfers are performed for each DMA trigger. This can be used, for example, with peripherals that
+ *    contain a FIFO that can initiate a DMA operation when the FIFO reaches a certain level. 0000:
+ *    Burst size = 1 (2^0). 0001: Burst size = 2 (2^1). 0010: Burst size = 4 (2^2). ... 1010: Burst
+ *    size = 1024 (2^10). This corresponds to the maximum supported transfer count. others: not
+ *    supported. The total transfer length as defined in the XFERCOUNT bits in the XFERCFG register must be
+ *    an even multiple of the burst size.
+ */
+#define DMA_CHANNEL_CFG_BURSTPOWER(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_BURSTPOWER_SHIFT)) & DMA_CHANNEL_CFG_BURSTPOWER_MASK)
+#define DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK        (0x4000U)
+#define DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT       (14U)
+/*! SRCBURSTWRAP - Source Burst Wrap. When enabled, the source data address for the DMA is wrapped ,
+ *    meaning that the source address range for each burst will be the same. As an example, this
+ *    could be used to read several sequential registers from a peripheral for each DMA burst, reading
+ *    the same registers again for each burst. 0 Disabled. Source burst wrapping is not enabled for
+ *    this DMA channel. 1 Enabled. Source burst wrapping is enabled for this DMA channel.
+ */
+#define DMA_CHANNEL_CFG_SRCBURSTWRAP(x)          (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK)
+#define DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK        (0x8000U)
+#define DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT       (15U)
+/*! DSTBURSTWRAP - Destination Burst Wrap. When enabled, the destination data address for the DMA is
+ *    wrapped , meaning that the destination address range for each burst will be the same. As an
+ *    example, this could be used to write several sequential registers to a peripheral for each DMA
+ *    burst, writing the same registers again for each burst. 0 Disabled. Destination burst wrapping
+ *    is not enabled for this DMA channel. 1 Enabled. Destination burst wrapping is enabled for
+ *    this DMA channel.
+ */
+#define DMA_CHANNEL_CFG_DSTBURSTWRAP(x)          (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK)
+#define DMA_CHANNEL_CFG_CHPRIORITY_MASK          (0x70000U)
+#define DMA_CHANNEL_CFG_CHPRIORITY_SHIFT         (16U)
+/*! CHPRIORITY - Priority of this channel when multiple DMA requests are pending. Eight priority
+ *    levels are supported: 0x0 = highest priority. 0x7 = lowest priority.
+ */
+#define DMA_CHANNEL_CFG_CHPRIORITY(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_CHPRIORITY_SHIFT)) & DMA_CHANNEL_CFG_CHPRIORITY_MASK)
+/*! @} */
+
+/* The count of DMA_CHANNEL_CFG */
+#define DMA_CHANNEL_CFG_COUNT                    (19U)
+
+/*! @name CHANNEL_CTLSTAT - Control and status register for DMA channel x */
+/*! @{ */
+#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK    (0x1U)
+#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT   (0U)
+/*! VALIDPENDING - Valid pending flag for this channel. This bit is set when a 1 is written to the
+ *    corresponding bit in the related SETVALID register when CFGVALID = 1 for the same channel. 0 No
+ *    effect. No effect on DMA operation. 1 Valid pending.
+ */
+#define DMA_CHANNEL_CTLSTAT_VALIDPENDING(x)      (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT)) & DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK)
+#define DMA_CHANNEL_CTLSTAT_TRIG_MASK            (0x4U)
+#define DMA_CHANNEL_CTLSTAT_TRIG_SHIFT           (2U)
+/*! TRIG - Trigger flag. Indicates that the trigger for this channel is currently set. This bit is
+ *    cleared at the end of an entire transfer or upon reload when CLRTRIG = 1. 0 Not triggered. The
+ *    trigger for this DMA channel is not set. DMA operations will not be carried out. 1 Triggered.
+ *    The trigger for this DMA channel is set. DMA operations will be carried out.
+ */
+#define DMA_CHANNEL_CTLSTAT_TRIG(x)              (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_TRIG_SHIFT)) & DMA_CHANNEL_CTLSTAT_TRIG_MASK)
+/*! @} */
+
+/* The count of DMA_CHANNEL_CTLSTAT */
+#define DMA_CHANNEL_CTLSTAT_COUNT                (19U)
+
+/*! @name CHANNEL_XFERCFG - Transfer configuration register for DMA channel x */
+/*! @{ */
+#define DMA_CHANNEL_XFERCFG_CFGVALID_MASK        (0x1U)
+#define DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT       (0U)
+/*! CFGVALID - Configuration Valid flag. This bit indicates whether the current channel descriptor
+ *    is valid and can potentially be acted upon, if all other activation criteria are fulfilled. 0
+ *    Not valid. The channel descriptor is not considered valid until validated by an associated
+ *    SETVALID0 setting. 1 Valid. The current channel descriptor is considered valid.
+ */
+#define DMA_CHANNEL_XFERCFG_CFGVALID(x)          (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT)) & DMA_CHANNEL_XFERCFG_CFGVALID_MASK)
+#define DMA_CHANNEL_XFERCFG_RELOAD_MASK          (0x2U)
+#define DMA_CHANNEL_XFERCFG_RELOAD_SHIFT         (1U)
+/*! RELOAD - Indicates whether the channel s control structure will be reloaded when the current
+ *    descriptor is exhausted. Reloading allows ping-pong and linked transfers. 0 Disabled. Do not
+ *    reload the channels control structure when the current descriptor is exhausted. 1 Enabled. Reload
+ *    the channels control structure when the current descriptor is exhausted.
+ */
+#define DMA_CHANNEL_XFERCFG_RELOAD(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_RELOAD_SHIFT)) & DMA_CHANNEL_XFERCFG_RELOAD_MASK)
+#define DMA_CHANNEL_XFERCFG_SWTRIG_MASK          (0x4U)
+#define DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT         (2U)
+/*! SWTRIG - Software Trigger. 0 Not set. When written by software, the trigger for this channel is
+ *    not set. A new trigger, as defined by the HWTRIGEN, TRIGPOL, and TRIGTYPE will be needed to
+ *    start the channel. 1 Set. When written by software, the trigger for this channel is set
+ *    immediately. This feature should not be used with level triggering when TRIGBURST = 0.
+ */
+#define DMA_CHANNEL_XFERCFG_SWTRIG(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_SWTRIG_MASK)
+#define DMA_CHANNEL_XFERCFG_CLRTRIG_MASK         (0x8U)
+#define DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT        (3U)
+/*! CLRTRIG - Clear Trigger. 0 Not cleared. The trigger is not cleared when this descriptor is
+ *    exhausted. If there is a reload, the next descriptor will be started. 1 Cleared. The trigger is
+ *    cleared when this descriptor is exhausted.
+ */
+#define DMA_CHANNEL_XFERCFG_CLRTRIG(x)           (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_CLRTRIG_MASK)
+#define DMA_CHANNEL_XFERCFG_SETINTA_MASK         (0x10U)
+#define DMA_CHANNEL_XFERCFG_SETINTA_SHIFT        (4U)
+/*! SETINTA - Set Interrupt flag A for this channel. There is no hardware distinction between
+ *    interrupt A and B. They can be used by software to assist with more complex descriptor usage. By
+ *    convention, interrupt A may be used when only one interrupt flag is needed. 0 No effect. 1 Set.
+ *    The INTA flag for this channel will be set when the current descriptor is exhausted.
+ */
+#define DMA_CHANNEL_XFERCFG_SETINTA(x)           (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTA_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTA_MASK)
+#define DMA_CHANNEL_XFERCFG_SETINTB_MASK         (0x20U)
+#define DMA_CHANNEL_XFERCFG_SETINTB_SHIFT        (5U)
+/*! SETINTB - Set Interrupt flag B for this channel. There is no hardware distinction between
+ *    interrupt A and B. They can be used by software to assist with more complex descriptor usage. By
+ *    convention, interrupt A may be used when only one interrupt flag is needed. 0 No effect. 1 Set.
+ *    The INTB flag for this channel will be set when the current descriptor is exhausted.
+ */
+#define DMA_CHANNEL_XFERCFG_SETINTB(x)           (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTB_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTB_MASK)
+#define DMA_CHANNEL_XFERCFG_WIDTH_MASK           (0x300U)
+#define DMA_CHANNEL_XFERCFG_WIDTH_SHIFT          (8U)
+/*! WIDTH - Transfer width used for this DMA channel. 0x0 8-bit. 8-bit transfers are performed
+ *    (8-bit source reads and destination writes). 0x1 16-bit. 6-bit transfers are performed (16-bit
+ *    source reads and destination writes). 0x2 32-bit. 32-bit transfers are performed (32-bit source
+ *    reads and destination writes). 0x3 Reserved. Reserved setting, do not use.
+ */
+#define DMA_CHANNEL_XFERCFG_WIDTH(x)             (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_WIDTH_SHIFT)) & DMA_CHANNEL_XFERCFG_WIDTH_MASK)
+#define DMA_CHANNEL_XFERCFG_SRCINC_MASK          (0x3000U)
+#define DMA_CHANNEL_XFERCFG_SRCINC_SHIFT         (12U)
+/*! SRCINC - Determines whether the source address is incremented for each DMA transfer. 0x0 No
+ *    increment. The source address is not incremented for each transfer. This is the usual case when
+ *    the source is a peripheral device. 0x1 1 x width. The source address is incremented by the
+ *    amount specified by Width for each transfer. This is the usual case when the source is memory. 0x2
+ *    2 x width. The source address is incremented by 2 times the amount specified by Width for each
+ *    transfer. 0x3 4 x width. The source address is incremented by 4 times the amount specified by
+ *    Width for each transfer.
+ */
+#define DMA_CHANNEL_XFERCFG_SRCINC(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SRCINC_SHIFT)) & DMA_CHANNEL_XFERCFG_SRCINC_MASK)
+#define DMA_CHANNEL_XFERCFG_DSTINC_MASK          (0xC000U)
+#define DMA_CHANNEL_XFERCFG_DSTINC_SHIFT         (14U)
+/*! DSTINC - Determines whether the destination address is incremented for each DMA transfer. 0x0 No
+ *    increment. The destination address is not incremented for each transfer. This is the usual
+ *    case when the destination is a peripheral device. 0x1 1 x width. The destination address is
+ *    incremented by the amount specified by Width for each transfer. This is the usual case when the
+ *    destination is memory. 0x2 2 x width. The destination address is incremented by 2 times the
+ *    amount specified by Width for each transfer. 0x3 4 x width. The destination address is incremented
+ *    by 4 times the amount specified by Width for each transfer.
+ */
+#define DMA_CHANNEL_XFERCFG_DSTINC(x)            (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_DSTINC_SHIFT)) & DMA_CHANNEL_XFERCFG_DSTINC_MASK)
+#define DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK       (0x3FF0000U)
+#define DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT      (16U)
+/*! XFERCOUNT - Total number of transfers to be performed, minus 1 encoded. The number of bytes
+ *    transferred is: (XFERCOUNT + 1) x data width (as defined by the WIDTH field). Remark: The DMA
+ *    controller uses this bit field during transfer to count down. Hence, it cannot be used by software
+ *    to read back the size of the transfer, for instance, in an interrupt handler. 0x0 = a total
+ *    of 1 transfer will be performed. 0x1 = a total of 2 transfers will be performed. ... 0x3FF = a
+ *    total of 1,024 transfers will be performed.
+ */
+#define DMA_CHANNEL_XFERCFG_XFERCOUNT(x)         (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT)) & DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK)
+/*! @} */
+
+/* The count of DMA_CHANNEL_XFERCFG */
+#define DMA_CHANNEL_XFERCFG_COUNT                (19U)
+
+/*! @name CHANNEL_RESERVED0 - Reserved */
+/*! @{ */
+#define DMA_CHANNEL_RESERVED0_DUMMYWORD_MASK     (0xFFFFFFFFU)
+#define DMA_CHANNEL_RESERVED0_DUMMYWORD_SHIFT    (0U)
+/*! DUMMYWORD - Reserved. The value read from a reserved bit is not defined.
+ */
+#define DMA_CHANNEL_RESERVED0_DUMMYWORD(x)       (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_RESERVED0_DUMMYWORD_SHIFT)) & DMA_CHANNEL_RESERVED0_DUMMYWORD_MASK)
+/*! @} */
+
+/* The count of DMA_CHANNEL_RESERVED0 */
+#define DMA_CHANNEL_RESERVED0_COUNT              (19U)
+
+
+/*!
+ * @}
+ */ /* end of group DMA_Register_Masks */
+
+
+/* DMA - Peripheral instance base addresses */
+/** Peripheral DMA0 base address */
+#define DMA0_BASE                                (0x40085000u)
+/** Peripheral DMA0 base pointer */
+#define DMA0                                     ((DMA_Type *)DMA0_BASE)
+/** Array initializer of DMA peripheral base addresses */
+#define DMA_BASE_ADDRS                           { DMA0_BASE }
+/** Array initializer of DMA peripheral base pointers */
+#define DMA_BASE_PTRS                            { DMA0 }
+/** Interrupt vectors for the DMA peripheral type */
+#define DMA_IRQS                                 { DMA0_IRQn }
+
+/*!
+ * @}
+ */ /* end of group DMA_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- DMIC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup DMIC_Peripheral_Access_Layer DMIC Peripheral Access Layer
+ * @{
+ */
+
+/** DMIC - Register Layout Typedef */
+typedef struct {
+  struct {                                         /* offset: 0x0, array step: 0x100 */
+    __IO uint32_t OSR;                               /**< Oversample Rate register 0. This register selects the oversample rate (CIC decimation rate) for the input channel., array offset: 0x0, array step: 0x100 */
+    __IO uint32_t DIVHFCLK;                          /**< DMIC Clock Register 0. This register controls the clock pre-divider for the input channel., array offset: 0x4, array step: 0x100 */
+    __IO uint32_t PREAC2FSCOEF;                      /**< Pre-Emphasis Filter Coefficient for 2 FS register 0. This register seclects the pre-emphasis filter coeffcient for the input channel when 2 FS mode is used., array offset: 0x8, array step: 0x100 */
+    __IO uint32_t PREAC4FSCOEF;                      /**< Pre-Emphasis Filter Coefficient for 4 FS register 0. This register seclects the pre-emphasis filter coeffcient for the input channel when 4FS mode is used, array offset: 0xC, array step: 0x100 */
+    __IO uint32_t GAINSHIFT;                         /**< Decimator Gain Shift register 0. This register adjusts the gain of the 4FS PCM data from the input filter., array offset: 0x10, array step: 0x100 */
+         uint8_t RESERVED_0[108];
+    __IO uint32_t FIFO_CTRL;                         /**< FIFO Control register 0. This register configures FIFO usage., array offset: 0x80, array step: 0x100 */
+    __IO uint32_t FIFO_STATUS;                       /**< FIFO Status register 0 . This register provides status information for the FIFO and also indicates an interrupt from the peripheral funcion., array offset: 0x84, array step: 0x100 */
+    __IO uint32_t FIFO_DATA;                         /**< FIFO Data Register 0. This register is used to read values that have been received via the PDM stream., array offset: 0x88, array step: 0x100 */
+    __IO uint32_t PHY_CTRL;                          /**< PHY Control / PDM Source Configuration register 0. This register configures how the PDM source signals are interpreted., array offset: 0x8C, array step: 0x100 */
+    __IO uint32_t DC_CTRL;                           /**< DC Control register 0. This register controls the DC filter., array offset: 0x90, array step: 0x100 */
+         uint8_t RESERVED_1[108];
+  } CHANNEL[2];
+       uint8_t RESERVED_0[3328];
+  __IO uint32_t CHANEN;                            /**< Channel Enable register. This register allows enabling either or both PDM channels., offset: 0xF00 */
+       uint8_t RESERVED_1[8];
+  __IO uint32_t IOCFG;                             /**< I/O Configuration register. This register configures the use of the PDM pins., offset: 0xF0C */
+  __IO uint32_t USE2FS;                            /**< Use 2FS register. This register allow selecting 2FS output rather than 1FS output., offset: 0xF10 */
+       uint8_t RESERVED_2[108];
+  __IO uint32_t HWVADGAIN;                         /**< HWVAD input gain register. This register controls the input gain of the HWVAD., offset: 0xF80 */
+  __IO uint32_t HWVADHPFS;                         /**< HWVAD filter control register. This register controls the HWVAD filter setting., offset: 0xF84 */
+  __IO uint32_t HWVADST10;                         /**< HWVAD control register. This register controls the operation of the filter block and resets the internal interrut flag., offset: 0xF88 */
+  __IO uint32_t HWVADRSTT;                         /**< HWVAD filter reset register, offset: 0xF8C */
+  __IO uint32_t HWVADTHGN;                         /**< HWVAD noise estimator gain register, offset: 0xF90 */
+  __IO uint32_t HWVADTHGS;                         /**< HWVAD signal estimator gain register, offset: 0xF94 */
+  __I  uint32_t HWVADLOWZ;                         /**< HWVAD noise envelope estimator register, offset: 0xF98 */
+       uint8_t RESERVED_3[96];
+  __I  uint32_t ID;                                /**< Module Identification register, offset: 0xFFC */
+} DMIC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- DMIC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup DMIC_Register_Masks DMIC Register Masks
+ * @{
+ */
+
+/*! @name CHANNEL_OSR - Oversample Rate register 0. This register selects the oversample rate (CIC decimation rate) for the input channel. */
+/*! @{ */
+#define DMIC_CHANNEL_OSR_OSR_MASK                (0xFFU)
+#define DMIC_CHANNEL_OSR_OSR_SHIFT               (0U)
+/*! OSR - Selects the oversample rate for the related input channel.
+ */
+#define DMIC_CHANNEL_OSR_OSR(x)                  (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_OSR_OSR_SHIFT)) & DMIC_CHANNEL_OSR_OSR_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_OSR */
+#define DMIC_CHANNEL_OSR_COUNT                   (2U)
+
+/*! @name CHANNEL_DIVHFCLK - DMIC Clock Register 0. This register controls the clock pre-divider for the input channel. */
+/*! @{ */
+#define DMIC_CHANNEL_DIVHFCLK_PDMDIV_MASK        (0xFU)
+#define DMIC_CHANNEL_DIVHFCLK_PDMDIV_SHIFT       (0U)
+/*! PDMDIV - PDM clock divider value. 0: divide by 1; 1: divide by 2; 2: divide by 3; 3: divide by
+ *    4; 4: divide by 6; 5: divide by 8; 6: divide by 12; 7: divide by 16; 8: divide by 24; 9: divide
+ *    by 32; 10: divide by 48; 11: divide by 64; 12: divide by 96; 13: divide by 128; others =
+ *    reserved.
+ */
+#define DMIC_CHANNEL_DIVHFCLK_PDMDIV(x)          (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DIVHFCLK_PDMDIV_SHIFT)) & DMIC_CHANNEL_DIVHFCLK_PDMDIV_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_DIVHFCLK */
+#define DMIC_CHANNEL_DIVHFCLK_COUNT              (2U)
+
+/*! @name CHANNEL_PREAC2FSCOEF - Pre-Emphasis Filter Coefficient for 2 FS register 0. This register seclects the pre-emphasis filter coeffcient for the input channel when 2 FS mode is used. */
+/*! @{ */
+#define DMIC_CHANNEL_PREAC2FSCOEF_COMP_MASK      (0x3U)
+#define DMIC_CHANNEL_PREAC2FSCOEF_COMP_SHIFT     (0U)
+/*! COMP - Pre-emphasis filer coefficient for 2 FS mode. 0: Compensation = 0 1: Compensation = -0.16
+ *    2: Compensation = -0.15 3: Compensation = -0.13
+ */
+#define DMIC_CHANNEL_PREAC2FSCOEF_COMP(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PREAC2FSCOEF_COMP_SHIFT)) & DMIC_CHANNEL_PREAC2FSCOEF_COMP_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_PREAC2FSCOEF */
+#define DMIC_CHANNEL_PREAC2FSCOEF_COUNT          (2U)
+
+/*! @name CHANNEL_PREAC4FSCOEF - Pre-Emphasis Filter Coefficient for 4 FS register 0. This register seclects the pre-emphasis filter coeffcient for the input channel when 4FS mode is used */
+/*! @{ */
+#define DMIC_CHANNEL_PREAC4FSCOEF_COMP_MASK      (0x3U)
+#define DMIC_CHANNEL_PREAC4FSCOEF_COMP_SHIFT     (0U)
+/*! COMP - Pre-emphasis filer coefficient for 4 FS mode. 0: Compensation = 0; 1: Compensation =
+ *    -0.16; 2: Compensation = -0.15; 3: Compensation = -0.13.
+ */
+#define DMIC_CHANNEL_PREAC4FSCOEF_COMP(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PREAC4FSCOEF_COMP_SHIFT)) & DMIC_CHANNEL_PREAC4FSCOEF_COMP_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_PREAC4FSCOEF */
+#define DMIC_CHANNEL_PREAC4FSCOEF_COUNT          (2U)
+
+/*! @name CHANNEL_GAINSHIFT - Decimator Gain Shift register 0. This register adjusts the gain of the 4FS PCM data from the input filter. */
+/*! @{ */
+#define DMIC_CHANNEL_GAINSHIFT_GAIN_MASK         (0x3FU)
+#define DMIC_CHANNEL_GAINSHIFT_GAIN_SHIFT        (0U)
+/*! GAIN - Gain control, as a positive or negative (two s complement) number of bits to shift.
+ */
+#define DMIC_CHANNEL_GAINSHIFT_GAIN(x)           (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_GAINSHIFT_GAIN_SHIFT)) & DMIC_CHANNEL_GAINSHIFT_GAIN_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_GAINSHIFT */
+#define DMIC_CHANNEL_GAINSHIFT_COUNT             (2U)
+
+/*! @name CHANNEL_FIFO_CTRL - FIFO Control register 0. This register configures FIFO usage. */
+/*! @{ */
+#define DMIC_CHANNEL_FIFO_CTRL_ENABLE_MASK       (0x1U)
+#define DMIC_CHANNEL_FIFO_CTRL_ENABLE_SHIFT      (0U)
+/*! ENABLE - FIFO enable. 0: FIFO is not enabled. Enabling a DMIC channel with the FIFO disabled
+ *    could be useful in order to avoid a filter settling. delay when a channel is re-enabled after a
+ *    period when the data was not needed. 1: FIFO is enabled. The FIFO must be enabled in order for
+ *    the CPU or DMA to read data from the DMIC via the FIFODATA register.
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_ENABLE(x)         (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_ENABLE_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_ENABLE_MASK)
+#define DMIC_CHANNEL_FIFO_CTRL_RESETN_MASK       (0x2U)
+#define DMIC_CHANNEL_FIFO_CTRL_RESETN_SHIFT      (1U)
+/*! RESETN - FIFO reset. 0: Reset the FIFO. This bit must be cleared before resuming operation. 1: Normal operation.
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_RESETN(x)         (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_RESETN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_RESETN_MASK)
+#define DMIC_CHANNEL_FIFO_CTRL_INTEN_MASK        (0x4U)
+#define DMIC_CHANNEL_FIFO_CTRL_INTEN_SHIFT       (2U)
+/*! INTEN - Interrupt enable. 0: FIFO level interrupts are not enabled. 1: FIFO level interrupts are enabled.
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_INTEN(x)          (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_INTEN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_INTEN_MASK)
+#define DMIC_CHANNEL_FIFO_CTRL_DMAEN_MASK        (0x8U)
+#define DMIC_CHANNEL_FIFO_CTRL_DMAEN_SHIFT       (3U)
+/*! DMAEN - DMA enable. 0: DMA requests are not enabled. 1: DMA requests based on FIFO level are enabled.
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_DMAEN(x)          (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_DMAEN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_DMAEN_MASK)
+#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_MASK      (0x1F0000U)
+#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_SHIFT     (16U)
+/*! TRIGLVL - FIFO trigger level. Selects the data trigger level for interrupt or DMA operation. If
+ *    enabled to do so, the FIFO level can wake up the device. 0: trigger when the FIFO has received
+ *    one entry (is no longer empty). 1: trigger when the FIFO has received two entries. 15:
+ *    trigger when the FIFO has received 16 entries (has become full).
+ */
+#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_FIFO_CTRL */
+#define DMIC_CHANNEL_FIFO_CTRL_COUNT             (2U)
+
+/*! @name CHANNEL_FIFO_STATUS - FIFO Status register 0 . This register provides status information for the FIFO and also indicates an interrupt from the peripheral funcion. */
+/*! @{ */
+#define DMIC_CHANNEL_FIFO_STATUS_INT_MASK        (0x1U)
+#define DMIC_CHANNEL_FIFO_STATUS_INT_SHIFT       (0U)
+/*! INT - Interrupt flag. Asserted when FIFO data reaches the level specified in the FIFOCTRL
+ *    register. Writing a one to this bit clears the flag. Remark: note that the bus clock to the DMIC
+ *    subsystem must be running in order for an interrupt to occur.
+ */
+#define DMIC_CHANNEL_FIFO_STATUS_INT(x)          (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_INT_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_INT_MASK)
+#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN_MASK    (0x2U)
+#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN_SHIFT   (1U)
+/*! OVERRUN - Overrun flag. Indicates that a FIFO overflow has occurred at some point. Writing a one
+ *    to this bit clears the flag. This flag does not cause an interrupt.
+ */
+#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN(x)      (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_OVERRUN_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_OVERRUN_MASK)
+#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_MASK   (0x4U)
+#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_SHIFT  (2U)
+/*! UNDERRUN - Underrun flag. Indicates that a FIFO underflow has occurred at some point. Writing a one to this bit clears the flag.
+ */
+#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN(x)     (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_FIFO_STATUS */
+#define DMIC_CHANNEL_FIFO_STATUS_COUNT           (2U)
+
+/*! @name CHANNEL_FIFO_DATA - FIFO Data Register 0. This register is used to read values that have been received via the PDM stream. */
+/*! @{ */
+#define DMIC_CHANNEL_FIFO_DATA_DATA_MASK         (0xFFFFFFU)
+#define DMIC_CHANNEL_FIFO_DATA_DATA_SHIFT        (0U)
+/*! DATA - Data from the top of the input filter FIFO.
+ */
+#define DMIC_CHANNEL_FIFO_DATA_DATA(x)           (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_DATA_DATA_SHIFT)) & DMIC_CHANNEL_FIFO_DATA_DATA_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_FIFO_DATA */
+#define DMIC_CHANNEL_FIFO_DATA_COUNT             (2U)
+
+/*! @name CHANNEL_PHY_CTRL - PHY Control / PDM Source Configuration register 0. This register configures how the PDM source signals are interpreted. */
+/*! @{ */
+#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL_MASK      (0x1U)
+#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL_SHIFT     (0U)
+/*! PHY_FALL - Capture PDM_DATA. 0: Capture PDM_DATA on the rising edge of PDM_CLK. 1: Capture PDM_DATA on the falling edge of PDM_CLK.
+ */
+#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PHY_CTRL_PHY_FALL_SHIFT)) & DMIC_CHANNEL_PHY_CTRL_PHY_FALL_MASK)
+#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF_MASK      (0x2U)
+#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF_SHIFT     (1U)
+/*! PHY_HALF - Half rate sampling. 0: Standard half rate sampling. The clock to the DMIC is sent at
+ *    the same rate as the decimator is providing. 1: Use half rate sampling. The PDM clock to DMIC
+ *    is divided by 2. Each PDM data is sampled twice into the decimator. The purpose of this mode
+ *    is to allow slower sampling rate in quiet periods of listening for a trigger. Allowing the
+ *    decimator to maintain the same decimation rate between the higher quality, higher PDM clock rate
+ *    and the lower quality lower PDM clock rate means that the user can quickly switch to higher
+ *    quality without re-configuring the decimator, and thus avoiding long filter settling times, when
+ *    switching to higher quality (higher freq PDM clock) for recognition.
+ */
+#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF(x)        (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PHY_CTRL_PHY_HALF_SHIFT)) & DMIC_CHANNEL_PHY_CTRL_PHY_HALF_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_PHY_CTRL */
+#define DMIC_CHANNEL_PHY_CTRL_COUNT              (2U)
+
+/*! @name CHANNEL_DC_CTRL - DC Control register 0. This register controls the DC filter. */
+/*! @{ */
+#define DMIC_CHANNEL_DC_CTRL_DCPOLE_MASK         (0x3U)
+#define DMIC_CHANNEL_DC_CTRL_DCPOLE_SHIFT        (0U)
+/*! DCPOLE - DC block filter. 0: Flat response, no filter. 1: 155 Hz. 2: 78 Hz. 3: 39 Hz. These
+ *    frequencies assume a PCM output frequency of 16 MHz. If the actual PCM output frequency is 8 MHz,
+ *    for example, the noted frequencies would be divided by 2.
+ */
+#define DMIC_CHANNEL_DC_CTRL_DCPOLE(x)           (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_DCPOLE_SHIFT)) & DMIC_CHANNEL_DC_CTRL_DCPOLE_MASK)
+#define DMIC_CHANNEL_DC_CTRL_DCGAIN_MASK         (0xF0U)
+#define DMIC_CHANNEL_DC_CTRL_DCGAIN_SHIFT        (4U)
+/*! DCGAIN - Fine gain adjustment in the form of a number of bits to downshift.
+ */
+#define DMIC_CHANNEL_DC_CTRL_DCGAIN(x)           (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_DCGAIN_SHIFT)) & DMIC_CHANNEL_DC_CTRL_DCGAIN_MASK)
+#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_MASK (0x100U)
+#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_SHIFT (8U)
+/*! SATURATEAT16BIT - Selects 16-bit saturation. 0:Results roll over if out range and do not
+ *    saturate. 1:If the result overflows, it saturates at 0xFFFF for positive overflow and 0x8000 for
+ *    negative overflow.
+ */
+#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT(x)  (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_SHIFT)) & DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_MASK)
+/*! @} */
+
+/* The count of DMIC_CHANNEL_DC_CTRL */
+#define DMIC_CHANNEL_DC_CTRL_COUNT               (2U)
+
+/*! @name CHANEN - Channel Enable register. This register allows enabling either or both PDM channels. */
+/*! @{ */
+#define DMIC_CHANEN_EN_CH0_MASK                  (0x1U)
+#define DMIC_CHANEN_EN_CH0_SHIFT                 (0U)
+/*! EN_CH0 - Enable channel 0. When 1, PDM channel 0 is enabled.
+ */
+#define DMIC_CHANEN_EN_CH0(x)                    (((uint32_t)(((uint32_t)(x)) << DMIC_CHANEN_EN_CH0_SHIFT)) & DMIC_CHANEN_EN_CH0_MASK)
+#define DMIC_CHANEN_EN_CH1_MASK                  (0x2U)
+#define DMIC_CHANEN_EN_CH1_SHIFT                 (1U)
+/*! EN_CH1 - Enable channel 1. When 1, PDM channel 1 is enabled.
+ */
+#define DMIC_CHANEN_EN_CH1(x)                    (((uint32_t)(((uint32_t)(x)) << DMIC_CHANEN_EN_CH1_SHIFT)) & DMIC_CHANEN_EN_CH1_MASK)
+/*! @} */
+
+/*! @name IOCFG - I/O Configuration register. This register configures the use of the PDM pins. */
+/*! @{ */
+#define DMIC_IOCFG_CLK_BYPASS0_MASK              (0x1U)
+#define DMIC_IOCFG_CLK_BYPASS0_SHIFT             (0U)
+/*! CLK_BYPASS0 - Bypass CLK0. When 1, PDM_DATA1 becomes the clock for PDM channel 0. This provides
+ *    for the possibility of an external codec taking over the PDM bus.
+ */
+#define DMIC_IOCFG_CLK_BYPASS0(x)                (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_CLK_BYPASS0_SHIFT)) & DMIC_IOCFG_CLK_BYPASS0_MASK)
+#define DMIC_IOCFG_CLK_BYPASS1_MASK              (0x2U)
+#define DMIC_IOCFG_CLK_BYPASS1_SHIFT             (1U)
+/*! CLK_BYPASS1 - Bypass CLK1. When 1, PDM_DATA1 becomes the clock for PDM channel 1. This provides
+ *    for the possibility of an external codec taking over the PDM bus.
+ */
+#define DMIC_IOCFG_CLK_BYPASS1(x)                (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_CLK_BYPASS1_SHIFT)) & DMIC_IOCFG_CLK_BYPASS1_MASK)
+#define DMIC_IOCFG_STEREO_DATA0_MASK             (0x4U)
+#define DMIC_IOCFG_STEREO_DATA0_SHIFT            (2U)
+/*! STEREO_DATA0 - Stereo PDM select. When 1, PDM_DATA0 is routed to both PDM channels in a
+ *    configuration that supports a single stereo digital microphone.
+ */
+#define DMIC_IOCFG_STEREO_DATA0(x)               (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_STEREO_DATA0_SHIFT)) & DMIC_IOCFG_STEREO_DATA0_MASK)
+/*! @} */
+
+/*! @name USE2FS - Use 2FS register. This register allow selecting 2FS output rather than 1FS output. */
+/*! @{ */
+#define DMIC_USE2FS_USE2FS_MASK                  (0x1U)
+#define DMIC_USE2FS_USE2FS_SHIFT                 (0U)
+/*! USE2FS - Use 2FS register. 0: Use 1FS output for PCM data. 1: Use 2FS output for PCM data.
+ */
+#define DMIC_USE2FS_USE2FS(x)                    (((uint32_t)(((uint32_t)(x)) << DMIC_USE2FS_USE2FS_SHIFT)) & DMIC_USE2FS_USE2FS_MASK)
+/*! @} */
+
+/*! @name HWVADGAIN - HWVAD input gain register. This register controls the input gain of the HWVAD. */
+/*! @{ */
+#define DMIC_HWVADGAIN_INPUTGAIN_MASK            (0xFU)
+#define DMIC_HWVADGAIN_INPUTGAIN_SHIFT           (0U)
+/*! INPUTGAIN - Shift value for input bits. 0x0: -10 bits; 0x1: -8 bits; 0x2: -6 bits; 0x3: -4 bits;
+ *    0x4: -2 bits; 0x5: 0 bits (default); 0x6: +2 bits; 0x7: +4 bits; 0x8: +6 bits; 0x9: +8 bits;
+ *    0xA: +10 bits; 0xB: +12 bits; 0xC: +14 bits; 0xD to 0xF: Reserved.
+ */
+#define DMIC_HWVADGAIN_INPUTGAIN(x)              (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADGAIN_INPUTGAIN_SHIFT)) & DMIC_HWVADGAIN_INPUTGAIN_MASK)
+/*! @} */
+
+/*! @name HWVADHPFS - HWVAD filter control register. This register controls the HWVAD filter setting. */
+/*! @{ */
+#define DMIC_HWVADHPFS_HPFS_MASK                 (0x3U)
+#define DMIC_HWVADHPFS_HPFS_SHIFT                (0U)
+/*! HPFS - High pass filter. 0: First filter by-pass; 1: High pass filter with -3dB cut-off at
+ *    1750Hz; 2: High pass filter with -3dB cut-off at 215Hz.; 3: Reserved. This filter setting parameter
+ *    can be used to optimize performance for different background noise situations. In order to
+ *    find the best setting, software needs to perform a rough spectral analysis of the audio signal.
+ *    Rule of thumb: If the amount of low-frequency content in the background noise is small, then
+ *    set HPFS=0x2, otherwise use 0x1.
+ */
+#define DMIC_HWVADHPFS_HPFS(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADHPFS_HPFS_SHIFT)) & DMIC_HWVADHPFS_HPFS_MASK)
+/*! @} */
+
+/*! @name HWVADST10 - HWVAD control register. This register controls the operation of the filter block and resets the internal interrut flag. */
+/*! @{ */
+#define DMIC_HWVADST10_ST10_MASK                 (0x1U)
+#define DMIC_HWVADST10_ST10_SHIFT                (0U)
+/*! ST10 - ST10. Once the HWVAD has triggered an interrupt, a short '1' pulse on bit ST10 clears the
+ *    interrupt. Alternatively, keeping the bit on '1' level for some time has a special function
+ *    for filter convergence. 0: Normal operation, waiting for HWVAD trigger event (stage 0). 1:
+ *    Reset internal interrupt flag by writing a 1 pulse.
+ */
+#define DMIC_HWVADST10_ST10(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADST10_ST10_SHIFT)) & DMIC_HWVADST10_ST10_MASK)
+/*! @} */
+
+/*! @name HWVADRSTT - HWVAD filter reset register */
+/*! @{ */
+#define DMIC_HWVADRSTT_RSTT_MASK                 (0x1U)
+#define DMIC_HWVADRSTT_RSTT_SHIFT                (0U)
+/*! RSTT - HWVAD filter reset. Writing a 1, then writing a '0' resets all filter values. 0: Filters
+ *    anr not held in reset. 1: Holds the filters in reset.
+ */
+#define DMIC_HWVADRSTT_RSTT(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADRSTT_RSTT_SHIFT)) & DMIC_HWVADRSTT_RSTT_MASK)
+/*! @} */
+
+/*! @name HWVADTHGN - HWVAD noise estimator gain register */
+/*! @{ */
+#define DMIC_HWVADTHGN_THGN_MASK                 (0xFU)
+#define DMIC_HWVADTHGN_THGN_SHIFT                (0U)
+/*! THGN - Gain value for the noise estimator. Values 0 to 14. 0 corresponds to a gain of 1. THGN
+ *    and THGS are used within the hardware to determine when to assert the HWVAD result.
+ */
+#define DMIC_HWVADTHGN_THGN(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADTHGN_THGN_SHIFT)) & DMIC_HWVADTHGN_THGN_MASK)
+/*! @} */
+
+/*! @name HWVADTHGS - HWVAD signal estimator gain register */
+/*! @{ */
+#define DMIC_HWVADTHGS_THGS_MASK                 (0xFU)
+#define DMIC_HWVADTHGS_THGS_SHIFT                (0U)
+/*! THGS - Gain value for the signal estimator. Values 0 to 14. 0 corresponds to a gain of 1. THGN
+ *    and THGS are used within the hardware to determine when to assert the HWVAD result.
+ */
+#define DMIC_HWVADTHGS_THGS(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADTHGS_THGS_SHIFT)) & DMIC_HWVADTHGS_THGS_MASK)
+/*! @} */
+
+/*! @name HWVADLOWZ - HWVAD noise envelope estimator register */
+/*! @{ */
+#define DMIC_HWVADLOWZ_LOWZ_MASK                 (0xFFFFU)
+#define DMIC_HWVADLOWZ_LOWZ_SHIFT                (0U)
+/*! LOWZ - Noise envelope estimator value. This register contains 2 bytes of the output of filter
+ *    stage z7. It can be used as an indication for the noise floor and must be evaluated by software.
+ *    Note: For power saving reasons this register is not synchronized to the AHB bus clock domain.
+ *    To ensure correct data is read, the register should be read twice. If the data is the same,
+ *    then the data is correct, if not, the register should be read one more time. The noise floor is
+ *    a slowly moving calculation, so several reads in a row can guarantee that register value
+ *    being read can be assured to not be in the middle of a transition.
+ */
+#define DMIC_HWVADLOWZ_LOWZ(x)                   (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADLOWZ_LOWZ_SHIFT)) & DMIC_HWVADLOWZ_LOWZ_MASK)
+/*! @} */
+
+/*! @name ID - Module Identification register */
+/*! @{ */
+#define DMIC_ID_ID_MASK                          (0xFFFFFFFFU)
+#define DMIC_ID_ID_SHIFT                         (0U)
+/*! ID - Indicates module ID and the number of channels in this DMIC interface.
+ */
+#define DMIC_ID_ID(x)                            (((uint32_t)(((uint32_t)(x)) << DMIC_ID_ID_SHIFT)) & DMIC_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group DMIC_Register_Masks */
+
+
+/* DMIC - Peripheral instance base addresses */
+/** Peripheral DMIC0 base address */
+#define DMIC0_BASE                               (0x4008A000u)
+/** Peripheral DMIC0 base pointer */
+#define DMIC0                                    ((DMIC_Type *)DMIC0_BASE)
+/** Array initializer of DMIC peripheral base addresses */
+#define DMIC_BASE_ADDRS                          { DMIC0_BASE }
+/** Array initializer of DMIC peripheral base pointers */
+#define DMIC_BASE_PTRS                           { DMIC0 }
+/** Interrupt vectors for the DMIC peripheral type */
+#define DMIC_IRQS                                { DMIC0_IRQn }
+#define DMIC_HWVAD_IRQS                          { HWVAD0_IRQn }
+
+/*!
+ * @}
+ */ /* end of group DMIC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- FLASH Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup FLASH_Peripheral_Access_Layer FLASH Peripheral Access Layer
+ * @{
+ */
+
+/** FLASH - Register Layout Typedef */
+typedef struct {
+  __O  uint32_t CMD;                               /**< command register, offset: 0x0 */
+  __O  uint32_t EVENT;                             /**< event register, offset: 0x4 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t AUTOPROG;                          /**< specifies what commands are performed on AHB write, offset: 0xC */
+  __IO uint32_t STARTA;                            /**< start address for next flash command, offset: 0x10 */
+  __IO uint32_t STOPA;                             /**< end address for next flash command, if command operates on address ranges, offset: 0x14 */
+       uint8_t RESERVED_1[104];
+  __IO uint32_t DATAW[4];                          /**< data register, word 0-3; Memory data, or command parameter, or command result., array offset: 0x80, array step: 0x4 */
+       uint8_t RESERVED_2[3912];
+  __O  uint32_t INT_CLR_ENABLE;                    /**< Clear interrupt enable bits, offset: 0xFD8 */
+  __O  uint32_t INT_SET_ENABLE;                    /**< Set interrupt enable bits, offset: 0xFDC */
+  __I  uint32_t INT_STATUS;                        /**< Interrupt status bits, offset: 0xFE0 */
+  __I  uint32_t INT_ENABLE;                        /**< Interrupt enable bits, offset: 0xFE4 */
+  __O  uint32_t INT_CLR_STATUS;                    /**< Clear interrupt status bits, offset: 0xFE8 */
+  __O  uint32_t INT_SET_STATUS;                    /**< Set interrupt status bits, offset: 0xFEC */
+       uint8_t RESERVED_3[12];
+  __I  uint32_t MODULE_ID;                         /**< Controller and Memory module identification, offset: 0xFFC */
+} FLASH_Type;
+
+/* ----------------------------------------------------------------------------
+   -- FLASH Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup FLASH_Register_Masks FLASH Register Masks
+ * @{
+ */
+
+/*! @name CMD - command register */
+/*! @{ */
+#define FLASH_CMD_CMD_MASK                       (0xFFFFFFFFU)
+#define FLASH_CMD_CMD_SHIFT                      (0U)
+/*! CMD - command register
+ */
+#define FLASH_CMD_CMD(x)                         (((uint32_t)(((uint32_t)(x)) << FLASH_CMD_CMD_SHIFT)) & FLASH_CMD_CMD_MASK)
+/*! @} */
+
+/*! @name EVENT - event register */
+/*! @{ */
+#define FLASH_EVENT_RST_MASK                     (0x1U)
+#define FLASH_EVENT_RST_SHIFT                    (0U)
+/*! RST - When bit is set, the controller and flash are reset.
+ */
+#define FLASH_EVENT_RST(x)                       (((uint32_t)(((uint32_t)(x)) << FLASH_EVENT_RST_SHIFT)) & FLASH_EVENT_RST_MASK)
+#define FLASH_EVENT_WAKEUP_MASK                  (0x2U)
+#define FLASH_EVENT_WAKEUP_SHIFT                 (1U)
+/*! WAKEUP - When bit is set, the controller wakes up from whatever low power or powerdown mode was
+ *    active. If not in a powerdown mode, this bit has no effect.
+ */
+#define FLASH_EVENT_WAKEUP(x)                    (((uint32_t)(((uint32_t)(x)) << FLASH_EVENT_WAKEUP_SHIFT)) & FLASH_EVENT_WAKEUP_MASK)
+#define FLASH_EVENT_ABORT_MASK                   (0x4U)
+#define FLASH_EVENT_ABORT_SHIFT                  (2U)
+/*! ABORT - When bit is set, a running program/erase command is aborted.
+ */
+#define FLASH_EVENT_ABORT(x)                     (((uint32_t)(((uint32_t)(x)) << FLASH_EVENT_ABORT_SHIFT)) & FLASH_EVENT_ABORT_MASK)
+/*! @} */
+
+/*! @name AUTOPROG - specifies what commands are performed on AHB write */
+/*! @{ */
+#define FLASH_AUTOPROG_AUTOPROG_MASK             (0x3U)
+#define FLASH_AUTOPROG_AUTOPROG_SHIFT            (0U)
+/*! AUTOPROG - Auto programmings configuration. 00: auto programming switched off. 01: execute write
+ *    word . 10: execute write word then, if the last word in a page was written, program page .
+ *    11: reserved for future use / no action.
+ */
+#define FLASH_AUTOPROG_AUTOPROG(x)               (((uint32_t)(((uint32_t)(x)) << FLASH_AUTOPROG_AUTOPROG_SHIFT)) & FLASH_AUTOPROG_AUTOPROG_MASK)
+/*! @} */
+
+/*! @name STARTA - start address for next flash command */
+/*! @{ */
+#define FLASH_STARTA_STARTA_MASK                 (0x3FFFFU)
+#define FLASH_STARTA_STARTA_SHIFT                (0U)
+/*! STARTA - Address / Start address for commands that take an address (range) as a parameter. The
+ *    address is in units of memory words, not bytes.
+ */
+#define FLASH_STARTA_STARTA(x)                   (((uint32_t)(((uint32_t)(x)) << FLASH_STARTA_STARTA_SHIFT)) & FLASH_STARTA_STARTA_MASK)
+/*! @} */
+
+/*! @name STOPA - end address for next flash command, if command operates on address ranges */
+/*! @{ */
+#define FLASH_STOPA_STOPA_MASK                   (0x3FFFFU)
+#define FLASH_STOPA_STOPA_SHIFT                  (0U)
+/*! STOPA - Stop address for commands that take an address range as a parameter (the word specified
+ *    by STOPA is included in the address range). The address is in units of memory words, not bytes.
+ */
+#define FLASH_STOPA_STOPA(x)                     (((uint32_t)(((uint32_t)(x)) << FLASH_STOPA_STOPA_SHIFT)) & FLASH_STOPA_STOPA_MASK)
+/*! @} */
+
+/*! @name DATAW - data register, word 0-3; Memory data, or command parameter, or command result. */
+/*! @{ */
+#define FLASH_DATAW_DATAW_MASK                   (0xFFFFFFFFU)
+#define FLASH_DATAW_DATAW_SHIFT                  (0U)
+/*! DATAW - data register, word 0-3; Memory data, or command parameter, or command result.
+ */
+#define FLASH_DATAW_DATAW(x)                     (((uint32_t)(((uint32_t)(x)) << FLASH_DATAW_DATAW_SHIFT)) & FLASH_DATAW_DATAW_MASK)
+/*! @} */
+
+/* The count of FLASH_DATAW */
+#define FLASH_DATAW_COUNT                        (4U)
+
+/*! @name INT_CLR_ENABLE - Clear interrupt enable bits */
+/*! @{ */
+#define FLASH_INT_CLR_ENABLE_FAIL_MASK           (0x1U)
+#define FLASH_INT_CLR_ENABLE_FAIL_SHIFT          (0U)
+/*! FAIL - When a CLR_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is cleared
+ */
+#define FLASH_INT_CLR_ENABLE_FAIL(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_ENABLE_FAIL_SHIFT)) & FLASH_INT_CLR_ENABLE_FAIL_MASK)
+#define FLASH_INT_CLR_ENABLE_ERR_MASK            (0x2U)
+#define FLASH_INT_CLR_ENABLE_ERR_SHIFT           (1U)
+/*! ERR - When a CLR_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is cleared
+ */
+#define FLASH_INT_CLR_ENABLE_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_ENABLE_ERR_SHIFT)) & FLASH_INT_CLR_ENABLE_ERR_MASK)
+#define FLASH_INT_CLR_ENABLE_DONE_MASK           (0x4U)
+#define FLASH_INT_CLR_ENABLE_DONE_SHIFT          (2U)
+/*! DONE - When a CLR_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is cleared
+ */
+#define FLASH_INT_CLR_ENABLE_DONE(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_ENABLE_DONE_SHIFT)) & FLASH_INT_CLR_ENABLE_DONE_MASK)
+#define FLASH_INT_CLR_ENABLE_ECC_ERR_MASK        (0x8U)
+#define FLASH_INT_CLR_ENABLE_ECC_ERR_SHIFT       (3U)
+/*! ECC_ERR - When a CLR_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is cleared
+ */
+#define FLASH_INT_CLR_ENABLE_ECC_ERR(x)          (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_ENABLE_ECC_ERR_SHIFT)) & FLASH_INT_CLR_ENABLE_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_SET_ENABLE - Set interrupt enable bits */
+/*! @{ */
+#define FLASH_INT_SET_ENABLE_FAIL_MASK           (0x1U)
+#define FLASH_INT_SET_ENABLE_FAIL_SHIFT          (0U)
+/*! FAIL - When a SET_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is set
+ */
+#define FLASH_INT_SET_ENABLE_FAIL(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_ENABLE_FAIL_SHIFT)) & FLASH_INT_SET_ENABLE_FAIL_MASK)
+#define FLASH_INT_SET_ENABLE_ERR_MASK            (0x2U)
+#define FLASH_INT_SET_ENABLE_ERR_SHIFT           (1U)
+/*! ERR - When a SET_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is set
+ */
+#define FLASH_INT_SET_ENABLE_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_ENABLE_ERR_SHIFT)) & FLASH_INT_SET_ENABLE_ERR_MASK)
+#define FLASH_INT_SET_ENABLE_DONE_MASK           (0x4U)
+#define FLASH_INT_SET_ENABLE_DONE_SHIFT          (2U)
+/*! DONE - When a SET_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is set
+ */
+#define FLASH_INT_SET_ENABLE_DONE(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_ENABLE_DONE_SHIFT)) & FLASH_INT_SET_ENABLE_DONE_MASK)
+#define FLASH_INT_SET_ENABLE_ECC_ERR_MASK        (0x8U)
+#define FLASH_INT_SET_ENABLE_ECC_ERR_SHIFT       (3U)
+/*! ECC_ERR - When a SET_ENABLE bit is written to 1, the corresponding INT_ENABLE bit is set
+ */
+#define FLASH_INT_SET_ENABLE_ECC_ERR(x)          (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_ENABLE_ECC_ERR_SHIFT)) & FLASH_INT_SET_ENABLE_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_STATUS - Interrupt status bits */
+/*! @{ */
+#define FLASH_INT_STATUS_FAIL_MASK               (0x1U)
+#define FLASH_INT_STATUS_FAIL_SHIFT              (0U)
+/*! FAIL - This status bit is set if execution of a (legal) command failed. The flag can be set at
+ *    any time during command execution, not just at the end.
+ */
+#define FLASH_INT_STATUS_FAIL(x)                 (((uint32_t)(((uint32_t)(x)) << FLASH_INT_STATUS_FAIL_SHIFT)) & FLASH_INT_STATUS_FAIL_MASK)
+#define FLASH_INT_STATUS_ERR_MASK                (0x2U)
+#define FLASH_INT_STATUS_ERR_SHIFT               (1U)
+/*! ERR - This status bit is set if execution of an illegal command is detected. A command is
+ *    illegal if it is unknown, or it is not allowed in the current mode, or it is violating access
+ *    restrictions, or it has invalid parameters.
+ */
+#define FLASH_INT_STATUS_ERR(x)                  (((uint32_t)(((uint32_t)(x)) << FLASH_INT_STATUS_ERR_SHIFT)) & FLASH_INT_STATUS_ERR_MASK)
+#define FLASH_INT_STATUS_DONE_MASK               (0x4U)
+#define FLASH_INT_STATUS_DONE_SHIFT              (2U)
+/*! DONE - This status bit is set at the end of command execution
+ */
+#define FLASH_INT_STATUS_DONE(x)                 (((uint32_t)(((uint32_t)(x)) << FLASH_INT_STATUS_DONE_SHIFT)) & FLASH_INT_STATUS_DONE_MASK)
+#define FLASH_INT_STATUS_ECC_ERR_MASK            (0x8U)
+#define FLASH_INT_STATUS_ECC_ERR_SHIFT           (3U)
+/*! ECC_ERR - This status bit is set if, during a memory read operation (either a user-requested
+ *    read, or a speculative read, or reads performed by a controller command), a correctable or
+ *    uncorrectable error is detected by ECC decoding logic.
+ */
+#define FLASH_INT_STATUS_ECC_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_STATUS_ECC_ERR_SHIFT)) & FLASH_INT_STATUS_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_ENABLE - Interrupt enable bits */
+/*! @{ */
+#define FLASH_INT_ENABLE_FAIL_MASK               (0x1U)
+#define FLASH_INT_ENABLE_FAIL_SHIFT              (0U)
+/*! FAIL - If an INT_ENABLE bit is set, an interrupt request will be generated if the corresponding INT_STATUS bit is high.
+ */
+#define FLASH_INT_ENABLE_FAIL(x)                 (((uint32_t)(((uint32_t)(x)) << FLASH_INT_ENABLE_FAIL_SHIFT)) & FLASH_INT_ENABLE_FAIL_MASK)
+#define FLASH_INT_ENABLE_ERR_MASK                (0x2U)
+#define FLASH_INT_ENABLE_ERR_SHIFT               (1U)
+/*! ERR - If an INT_ENABLE bit is set, an interrupt request will be generated if the corresponding INT_STATUS bit is high.
+ */
+#define FLASH_INT_ENABLE_ERR(x)                  (((uint32_t)(((uint32_t)(x)) << FLASH_INT_ENABLE_ERR_SHIFT)) & FLASH_INT_ENABLE_ERR_MASK)
+#define FLASH_INT_ENABLE_DONE_MASK               (0x4U)
+#define FLASH_INT_ENABLE_DONE_SHIFT              (2U)
+/*! DONE - If an INT_ENABLE bit is set, an interrupt request will be generated if the corresponding INT_STATUS bit is high.
+ */
+#define FLASH_INT_ENABLE_DONE(x)                 (((uint32_t)(((uint32_t)(x)) << FLASH_INT_ENABLE_DONE_SHIFT)) & FLASH_INT_ENABLE_DONE_MASK)
+#define FLASH_INT_ENABLE_ECC_ERR_MASK            (0x8U)
+#define FLASH_INT_ENABLE_ECC_ERR_SHIFT           (3U)
+/*! ECC_ERR - If an INT_ENABLE bit is set, an interrupt request will be generated if the corresponding INT_STATUS bit is high.
+ */
+#define FLASH_INT_ENABLE_ECC_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_ENABLE_ECC_ERR_SHIFT)) & FLASH_INT_ENABLE_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_CLR_STATUS - Clear interrupt status bits */
+/*! @{ */
+#define FLASH_INT_CLR_STATUS_FAIL_MASK           (0x1U)
+#define FLASH_INT_CLR_STATUS_FAIL_SHIFT          (0U)
+/*! FAIL - When a CLR_STATUS bit is written to 1, the corresponding INT_STATUS bit is cleared
+ */
+#define FLASH_INT_CLR_STATUS_FAIL(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_STATUS_FAIL_SHIFT)) & FLASH_INT_CLR_STATUS_FAIL_MASK)
+#define FLASH_INT_CLR_STATUS_ERR_MASK            (0x2U)
+#define FLASH_INT_CLR_STATUS_ERR_SHIFT           (1U)
+/*! ERR - When a CLR_STATUS bit is written to 1, the corresponding INT_STATUS bit is cleared
+ */
+#define FLASH_INT_CLR_STATUS_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_STATUS_ERR_SHIFT)) & FLASH_INT_CLR_STATUS_ERR_MASK)
+#define FLASH_INT_CLR_STATUS_DONE_MASK           (0x4U)
+#define FLASH_INT_CLR_STATUS_DONE_SHIFT          (2U)
+/*! DONE - When a CLR_STATUS bit is written to 1, the corresponding INT_STATUS bit is cleared
+ */
+#define FLASH_INT_CLR_STATUS_DONE(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_STATUS_DONE_SHIFT)) & FLASH_INT_CLR_STATUS_DONE_MASK)
+#define FLASH_INT_CLR_STATUS_ECC_ERR_MASK        (0x8U)
+#define FLASH_INT_CLR_STATUS_ECC_ERR_SHIFT       (3U)
+/*! ECC_ERR - When a CLR_STATUS bit is written to 1, the corresponding INT_STATUS bit is cleared
+ */
+#define FLASH_INT_CLR_STATUS_ECC_ERR(x)          (((uint32_t)(((uint32_t)(x)) << FLASH_INT_CLR_STATUS_ECC_ERR_SHIFT)) & FLASH_INT_CLR_STATUS_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name INT_SET_STATUS - Set interrupt status bits */
+/*! @{ */
+#define FLASH_INT_SET_STATUS_FAIL_MASK           (0x1U)
+#define FLASH_INT_SET_STATUS_FAIL_SHIFT          (0U)
+/*! FAIL - When a SET_STATUS bit is written to 1, the corresponding INT_STATUS bit is set
+ */
+#define FLASH_INT_SET_STATUS_FAIL(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_STATUS_FAIL_SHIFT)) & FLASH_INT_SET_STATUS_FAIL_MASK)
+#define FLASH_INT_SET_STATUS_ERR_MASK            (0x2U)
+#define FLASH_INT_SET_STATUS_ERR_SHIFT           (1U)
+/*! ERR - When a SET_STATUS bit is written to 1, the corresponding INT_STATUS bit is set
+ */
+#define FLASH_INT_SET_STATUS_ERR(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_STATUS_ERR_SHIFT)) & FLASH_INT_SET_STATUS_ERR_MASK)
+#define FLASH_INT_SET_STATUS_DONE_MASK           (0x4U)
+#define FLASH_INT_SET_STATUS_DONE_SHIFT          (2U)
+/*! DONE - When a SET_STATUS bit is written to 1, the corresponding INT_STATUS bit is set
+ */
+#define FLASH_INT_SET_STATUS_DONE(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_STATUS_DONE_SHIFT)) & FLASH_INT_SET_STATUS_DONE_MASK)
+#define FLASH_INT_SET_STATUS_ECC_ERR_MASK        (0x8U)
+#define FLASH_INT_SET_STATUS_ECC_ERR_SHIFT       (3U)
+/*! ECC_ERR - When a SET_STATUS bit is written to 1, the corresponding INT_STATUS bit is set
+ */
+#define FLASH_INT_SET_STATUS_ECC_ERR(x)          (((uint32_t)(((uint32_t)(x)) << FLASH_INT_SET_STATUS_ECC_ERR_SHIFT)) & FLASH_INT_SET_STATUS_ECC_ERR_MASK)
+/*! @} */
+
+/*! @name MODULE_ID - Controller and Memory module identification */
+/*! @{ */
+#define FLASH_MODULE_ID_APERTURE_MASK            (0xFFU)
+#define FLASH_MODULE_ID_APERTURE_SHIFT           (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define FLASH_MODULE_ID_APERTURE(x)              (((uint32_t)(((uint32_t)(x)) << FLASH_MODULE_ID_APERTURE_SHIFT)) & FLASH_MODULE_ID_APERTURE_MASK)
+#define FLASH_MODULE_ID_MINOR_REV_MASK           (0xF00U)
+#define FLASH_MODULE_ID_MINOR_REV_SHIFT          (8U)
+/*! MINOR_REV - Minor revision i.e. with no software consequences
+ */
+#define FLASH_MODULE_ID_MINOR_REV(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_MODULE_ID_MINOR_REV_SHIFT)) & FLASH_MODULE_ID_MINOR_REV_MASK)
+#define FLASH_MODULE_ID_MAJOR_REV_MASK           (0xF000U)
+#define FLASH_MODULE_ID_MAJOR_REV_SHIFT          (12U)
+/*! MAJOR_REV - Major revision i.e. implies software modifications
+ */
+#define FLASH_MODULE_ID_MAJOR_REV(x)             (((uint32_t)(((uint32_t)(x)) << FLASH_MODULE_ID_MAJOR_REV_SHIFT)) & FLASH_MODULE_ID_MAJOR_REV_MASK)
+#define FLASH_MODULE_ID_ID_MASK                  (0xFFFF0000U)
+#define FLASH_MODULE_ID_ID_SHIFT                 (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define FLASH_MODULE_ID_ID(x)                    (((uint32_t)(((uint32_t)(x)) << FLASH_MODULE_ID_ID_SHIFT)) & FLASH_MODULE_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group FLASH_Register_Masks */
+
+
+/* FLASH - Peripheral instance base addresses */
+/** Peripheral FLASH base address */
+#define FLASH_BASE                               (0x40009000u)
+/** Peripheral FLASH base pointer */
+#define FLASH                                    ((FLASH_Type *)FLASH_BASE)
+/** Array initializer of FLASH peripheral base addresses */
+#define FLASH_BASE_ADDRS                         { FLASH_BASE }
+/** Array initializer of FLASH peripheral base pointers */
+#define FLASH_BASE_PTRS                          { FLASH }
+
+/*!
+ * @}
+ */ /* end of group FLASH_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- FLEXCOMM Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup FLEXCOMM_Peripheral_Access_Layer FLEXCOMM Peripheral Access Layer
+ * @{
+ */
+
+/** FLEXCOMM - Register Layout Typedef */
+typedef struct {
+       uint8_t RESERVED_0[4088];
+  __IO uint32_t PSELID;                            /**< Peripheral Select and Flexcomm ID register., offset: 0xFF8 */
+  __IO uint32_t PID;                               /**< Peripheral identification register., offset: 0xFFC */
+} FLEXCOMM_Type;
+
+/* ----------------------------------------------------------------------------
+   -- FLEXCOMM Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup FLEXCOMM_Register_Masks FLEXCOMM Register Masks
+ * @{
+ */
+
+/*! @name PSELID - Peripheral Select and Flexcomm ID register. */
+/*! @{ */
+#define FLEXCOMM_PSELID_PERSEL_MASK              (0x7U)
+#define FLEXCOMM_PSELID_PERSEL_SHIFT             (0U)
+/*! PERSEL - Peripheral Select. This field is writable by software.
+ *  0b000..No peripheral selected.
+ *  0b001..USART function selected.
+ *  0b010..SPI function selected.
+ *  0b011..I2C function selected.
+ *  0b100..I2S transmit function selected.
+ *  0b101..I2S receive function selected.
+ *  0b110..Reserved
+ *  0b111..Reserved
+ */
+#define FLEXCOMM_PSELID_PERSEL(x)                (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_PERSEL_SHIFT)) & FLEXCOMM_PSELID_PERSEL_MASK)
+#define FLEXCOMM_PSELID_LOCK_MASK                (0x8U)
+#define FLEXCOMM_PSELID_LOCK_SHIFT               (3U)
+/*! LOCK - Lock the peripheral select. This field is writable by software.
+ *  0b0..Peripheral select can be changed by software.
+ *  0b1..Peripheral select is locked and cannot be changed until this Flexcomm or the entire device is reset.
+ */
+#define FLEXCOMM_PSELID_LOCK(x)                  (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_LOCK_SHIFT)) & FLEXCOMM_PSELID_LOCK_MASK)
+#define FLEXCOMM_PSELID_USARTPRESENT_MASK        (0x10U)
+#define FLEXCOMM_PSELID_USARTPRESENT_SHIFT       (4U)
+/*! USARTPRESENT - USART present indicator. This field is Read-only.
+ *  0b0..This Flexcomm does not include the USART function.
+ *  0b1..This Flexcomm includes the USART function.
+ */
+#define FLEXCOMM_PSELID_USARTPRESENT(x)          (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_USARTPRESENT_SHIFT)) & FLEXCOMM_PSELID_USARTPRESENT_MASK)
+#define FLEXCOMM_PSELID_SPIPRESENT_MASK          (0x20U)
+#define FLEXCOMM_PSELID_SPIPRESENT_SHIFT         (5U)
+/*! SPIPRESENT - SPI present indicator. This field is Read-only.
+ *  0b0..This Flexcomm does not include the SPI function.
+ *  0b1..This Flexcomm includes the SPI function.
+ */
+#define FLEXCOMM_PSELID_SPIPRESENT(x)            (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_SPIPRESENT_SHIFT)) & FLEXCOMM_PSELID_SPIPRESENT_MASK)
+#define FLEXCOMM_PSELID_I2CPRESENT_MASK          (0x40U)
+#define FLEXCOMM_PSELID_I2CPRESENT_SHIFT         (6U)
+/*! I2CPRESENT - I2C present indicator. This field is Read-only.
+ *  0b0..This Flexcomm does not include the I2C function.
+ *  0b1..This Flexcomm includes the I2C function.
+ */
+#define FLEXCOMM_PSELID_I2CPRESENT(x)            (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_I2CPRESENT_SHIFT)) & FLEXCOMM_PSELID_I2CPRESENT_MASK)
+#define FLEXCOMM_PSELID_I2SPRESENT_MASK          (0x80U)
+#define FLEXCOMM_PSELID_I2SPRESENT_SHIFT         (7U)
+/*! I2SPRESENT - I 2S present indicator. This field is Read-only.
+ *  0b0..This Flexcomm does not include the I2S function.
+ *  0b1..This Flexcomm includes the I2S function.
+ */
+#define FLEXCOMM_PSELID_I2SPRESENT(x)            (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_I2SPRESENT_SHIFT)) & FLEXCOMM_PSELID_I2SPRESENT_MASK)
+#define FLEXCOMM_PSELID_ID_MASK                  (0xFFFFF000U)
+#define FLEXCOMM_PSELID_ID_SHIFT                 (12U)
+/*! ID - Flexcomm ID.
+ */
+#define FLEXCOMM_PSELID_ID(x)                    (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_ID_SHIFT)) & FLEXCOMM_PSELID_ID_MASK)
+/*! @} */
+
+/*! @name PID - Peripheral identification register. */
+/*! @{ */
+#define FLEXCOMM_PID_Minor_Rev_MASK              (0xF00U)
+#define FLEXCOMM_PID_Minor_Rev_SHIFT             (8U)
+/*! Minor_Rev - Minor revision of module implementation.
+ */
+#define FLEXCOMM_PID_Minor_Rev(x)                (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_Minor_Rev_SHIFT)) & FLEXCOMM_PID_Minor_Rev_MASK)
+#define FLEXCOMM_PID_Major_Rev_MASK              (0xF000U)
+#define FLEXCOMM_PID_Major_Rev_SHIFT             (12U)
+/*! Major_Rev - Major revision of module implementation.
+ */
+#define FLEXCOMM_PID_Major_Rev(x)                (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_Major_Rev_SHIFT)) & FLEXCOMM_PID_Major_Rev_MASK)
+#define FLEXCOMM_PID_ID_MASK                     (0xFFFF0000U)
+#define FLEXCOMM_PID_ID_SHIFT                    (16U)
+/*! ID - Module identifier for the selected function.
+ */
+#define FLEXCOMM_PID_ID(x)                       (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_ID_SHIFT)) & FLEXCOMM_PID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group FLEXCOMM_Register_Masks */
+
+
+/* FLEXCOMM - Peripheral instance base addresses */
+/** Peripheral FLEXCOMM0 base address */
+#define FLEXCOMM0_BASE                           (0x4008B000u)
+/** Peripheral FLEXCOMM0 base pointer */
+#define FLEXCOMM0                                ((FLEXCOMM_Type *)FLEXCOMM0_BASE)
+/** Peripheral FLEXCOMM1 base address */
+#define FLEXCOMM1_BASE                           (0x4008C000u)
+/** Peripheral FLEXCOMM1 base pointer */
+#define FLEXCOMM1                                ((FLEXCOMM_Type *)FLEXCOMM1_BASE)
+/** Peripheral FLEXCOMM2 base address */
+#define FLEXCOMM2_BASE                           (0x40003000u)
+/** Peripheral FLEXCOMM2 base pointer */
+#define FLEXCOMM2                                ((FLEXCOMM_Type *)FLEXCOMM2_BASE)
+/** Peripheral FLEXCOMM3 base address */
+#define FLEXCOMM3_BASE                           (0x40004000u)
+/** Peripheral FLEXCOMM3 base pointer */
+#define FLEXCOMM3                                ((FLEXCOMM_Type *)FLEXCOMM3_BASE)
+/** Peripheral FLEXCOMM4 base address */
+#define FLEXCOMM4_BASE                           (0x4008D000u)
+/** Peripheral FLEXCOMM4 base pointer */
+#define FLEXCOMM4                                ((FLEXCOMM_Type *)FLEXCOMM4_BASE)
+/** Peripheral FLEXCOMM5 base address */
+#define FLEXCOMM5_BASE                           (0x4008E000u)
+/** Peripheral FLEXCOMM5 base pointer */
+#define FLEXCOMM5                                ((FLEXCOMM_Type *)FLEXCOMM5_BASE)
+/** Peripheral FLEXCOMM6 base address */
+#define FLEXCOMM6_BASE                           (0x40005000u)
+/** Peripheral FLEXCOMM6 base pointer */
+#define FLEXCOMM6                                ((FLEXCOMM_Type *)FLEXCOMM6_BASE)
+/** Array initializer of FLEXCOMM peripheral base addresses */
+#define FLEXCOMM_BASE_ADDRS                      { FLEXCOMM0_BASE, FLEXCOMM1_BASE, FLEXCOMM2_BASE, FLEXCOMM3_BASE, FLEXCOMM4_BASE, FLEXCOMM5_BASE, FLEXCOMM6_BASE }
+/** Array initializer of FLEXCOMM peripheral base pointers */
+#define FLEXCOMM_BASE_PTRS                       { FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6 }
+/** Interrupt vectors for the FLEXCOMM peripheral type */
+#define FLEXCOMM_IRQS                            { FLEXCOMM0_IRQn, FLEXCOMM1_IRQn, FLEXCOMM2_IRQn, FLEXCOMM3_IRQn, FLEXCOMM4_IRQn, FLEXCOMM5_IRQn, FLEXCOMM6_IRQn }
+
+/*!
+ * @}
+ */ /* end of group FLEXCOMM_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- GINT Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup GINT_Peripheral_Access_Layer GINT Peripheral Access Layer
+ * @{
+ */
+
+/** GINT - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< GPIO Grouped interrupt control register, offset: 0x0 */
+       uint8_t RESERVED_0[28];
+  __IO uint32_t PORT_POL[1];                       /**< GPIO Grouped Interrupt polarity register. Configure the pin polarity of each PIO signal into the group interrupt function. If a bit is low then the corresponding PIO has an active low contribution into the group interrupt. If a bit is high then the corresponding PIO has an active high contribution., array offset: 0x20, array step: 0x4 */
+       uint8_t RESERVED_1[28];
+  __IO uint32_t PORT_ENA[1];                       /**< GPIO Grouped Interrupt port enable register. When a bit is set then the corresponding PIO is enabled for the group interrupt function., array offset: 0x40, array step: 0x4 */
+} GINT_Type;
+
+/* ----------------------------------------------------------------------------
+   -- GINT Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup GINT_Register_Masks GINT Register Masks
+ * @{
+ */
+
+/*! @name CTRL - GPIO Grouped interrupt control register */
+/*! @{ */
+#define GINT_CTRL_INT_MASK                       (0x1U)
+#define GINT_CTRL_INT_SHIFT                      (0U)
+/*! INT - Group interrupt status. This bit is cleared by writing a one to it. Writing zero has no effect.
+ */
+#define GINT_CTRL_INT(x)                         (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_INT_SHIFT)) & GINT_CTRL_INT_MASK)
+#define GINT_CTRL_COMB_MASK                      (0x2U)
+#define GINT_CTRL_COMB_SHIFT                     (1U)
+/*! COMB - Combine enabled inputs for group interrupt. 0: Or, OR functionality: A grouped interrupt
+ *    is generated when any one of the enabled inputs is active (based on its programmed polarity)
+ *    1: And, AND functionality: An interrupt is generated when all enabled bits are active (based on
+ *    their programmed polarity)
+ */
+#define GINT_CTRL_COMB(x)                        (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_COMB_SHIFT)) & GINT_CTRL_COMB_MASK)
+#define GINT_CTRL_TRIG_MASK                      (0x4U)
+#define GINT_CTRL_TRIG_SHIFT                     (2U)
+/*! TRIG - Group interrupt trigger. 0: Edge Triggered. 1: Level Triggered.
+ */
+#define GINT_CTRL_TRIG(x)                        (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_TRIG_SHIFT)) & GINT_CTRL_TRIG_MASK)
+/*! @} */
+
+/*! @name PORT_POL - GPIO Grouped Interrupt polarity register. Configure the pin polarity of each PIO signal into the group interrupt function. If a bit is low then the corresponding PIO has an active low contribution into the group interrupt. If a bit is high then the corresponding PIO has an active high contribution. */
+/*! @{ */
+#define GINT_PORT_POL_POL_MASK                   (0x3FFFFFU)
+#define GINT_PORT_POL_POL_SHIFT                  (0U)
+/*! POL - Configure pin polarity of pin PIOn.
+ */
+#define GINT_PORT_POL_POL(x)                     (((uint32_t)(((uint32_t)(x)) << GINT_PORT_POL_POL_SHIFT)) & GINT_PORT_POL_POL_MASK)
+/*! @} */
+
+/* The count of GINT_PORT_POL */
+#define GINT_PORT_POL_COUNT                      (1U)
+
+/*! @name PORT_ENA - GPIO Grouped Interrupt port enable register. When a bit is set then the corresponding PIO is enabled for the group interrupt function. */
+/*! @{ */
+#define GINT_PORT_ENA_ENA_MASK                   (0x3FFFFFU)
+#define GINT_PORT_ENA_ENA_SHIFT                  (0U)
+/*! ENA - Enable pin PIOn for group interrupt.
+ */
+#define GINT_PORT_ENA_ENA(x)                     (((uint32_t)(((uint32_t)(x)) << GINT_PORT_ENA_ENA_SHIFT)) & GINT_PORT_ENA_ENA_MASK)
+/*! @} */
+
+/* The count of GINT_PORT_ENA */
+#define GINT_PORT_ENA_COUNT                      (1U)
+
+
+/*!
+ * @}
+ */ /* end of group GINT_Register_Masks */
+
+
+/* GINT - Peripheral instance base addresses */
+/** Peripheral GINT0 base address */
+#define GINT0_BASE                               (0x40011000u)
+/** Peripheral GINT0 base pointer */
+#define GINT0                                    ((GINT_Type *)GINT0_BASE)
+/** Array initializer of GINT peripheral base addresses */
+#define GINT_BASE_ADDRS                          { GINT0_BASE }
+/** Array initializer of GINT peripheral base pointers */
+#define GINT_BASE_PTRS                           { GINT0 }
+/** Interrupt vectors for the GINT peripheral type */
+#define GINT_IRQS                                { GINT0_IRQn }
+
+/*!
+ * @}
+ */ /* end of group GINT_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- GPIO Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup GPIO_Peripheral_Access_Layer GPIO Peripheral Access Layer
+ * @{
+ */
+
+/** GPIO - Register Layout Typedef */
+typedef struct {
+  __IO uint8_t B[1][22];                           /**< Byte pin registers. Read 0: pin PIOn is LOW. Read 0xFF: pin PIOn is HIGH. Only 0 or 0xFF can be read. Write 0: clear output bit. Write any value 0x01 to 0xFF: set output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset value, array offset: 0x0, array step: index*0x16, index2*0x1 */
+       uint8_t RESERVED_0[4074];
+  __IO uint32_t W[1][22];                          /**< Word pin registers Read 0: pin PIOn is LOW. Read 0xFFFFFFFF: pin PIOn is HIGH. Only 0 or 0xFFFF FFFF can be read. Write 0: clear output bit. Write any value 0x00000001 to 0xFFFFFFFF: set output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset value, array offset: 0x1000, array step: index*0x58, index2*0x4 */
+       uint8_t RESERVED_1[4008];
+  __IO uint32_t DIR[1];                            /**< Direction register, array offset: 0x2000, array step: 0x4 */
+       uint8_t RESERVED_2[124];
+  __IO uint32_t MASK[1];                           /**< Mask register, array offset: 0x2080, array step: 0x4 */
+       uint8_t RESERVED_3[124];
+  __IO uint32_t PIN[1];                            /**< Pin register, array offset: 0x2100, array step: 0x4 */
+       uint8_t RESERVED_4[124];
+  __IO uint32_t MPIN[1];                           /**< Masked Pin register, array offset: 0x2180, array step: 0x4 */
+       uint8_t RESERVED_5[124];
+  __IO uint32_t SET[1];                            /**< Write: Set Pin register bits Read: output bits, array offset: 0x2200, array step: 0x4 */
+       uint8_t RESERVED_6[124];
+  __O  uint32_t CLR[1];                            /**< Clear Pin register bits, array offset: 0x2280, array step: 0x4 */
+       uint8_t RESERVED_7[124];
+  __O  uint32_t NOT[1];                            /**< Toggle Pin register bits, array offset: 0x2300, array step: 0x4 */
+       uint8_t RESERVED_8[124];
+  __O  uint32_t DIRSET[1];                         /**< Set pin direction bits, array offset: 0x2380, array step: 0x4 */
+       uint8_t RESERVED_9[124];
+  __O  uint32_t DIRCLR[1];                         /**< Clear pin direction bits, array offset: 0x2400, array step: 0x4 */
+       uint8_t RESERVED_10[124];
+  __O  uint32_t DIRNOT[1];                         /**< Toggle pin direction bits, array offset: 0x2480, array step: 0x4 */
+} GPIO_Type;
+
+/* ----------------------------------------------------------------------------
+   -- GPIO Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup GPIO_Register_Masks GPIO Register Masks
+ * @{
+ */
+
+/*! @name B - Byte pin registers. Read 0: pin PIOn is LOW. Read 0xFF: pin PIOn is HIGH. Only 0 or 0xFF can be read. Write 0: clear output bit. Write any value 0x01 to 0xFF: set output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset value */
+/*! @{ */
+#define GPIO_B_B_MASK                            (0xFFU)
+#define GPIO_B_B_SHIFT                           (0U)
+/*! B - Byte pin registers. Read 0: pin PIOn is LOW. Read 0xFF: pin PIOn is HIGH. Only 0 or 0xFF can
+ *    be read. Write 0: clear output bit. Write any value 0x01 to 0xFF: set output bit. Reset
+ *    values reflects the state of pin given by the relevant bit of PIN reset value
+ */
+#define GPIO_B_B(x)                              (((uint8_t)(((uint8_t)(x)) << GPIO_B_B_SHIFT)) & GPIO_B_B_MASK)
+/*! @} */
+
+/* The count of GPIO_B */
+#define GPIO_B_COUNT                             (1U)
+
+/* The count of GPIO_B */
+#define GPIO_B_COUNT2                            (22U)
+
+/*! @name W - Word pin registers Read 0: pin PIOn is LOW. Read 0xFFFFFFFF: pin PIOn is HIGH. Only 0 or 0xFFFF FFFF can be read. Write 0: clear output bit. Write any value 0x00000001 to 0xFFFFFFFF: set output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset value */
+/*! @{ */
+#define GPIO_W_W_MASK                            (0xFFFFFFFFU)
+#define GPIO_W_W_SHIFT                           (0U)
+/*! W - Word pin registers Read 0: pin PIOn is LOW. Read 0xFFFFFFFF: pin PIOn is HIGH. Only 0 or
+ *    0xFFFF FFFF can be read. Write 0: clear output bit. Write any value 0x00000001 to 0xFFFFFFFF: set
+ *    output bit. Reset values reflects the state of pin given by the relevant bit of PIN reset
+ *    value
+ */
+#define GPIO_W_W(x)                              (((uint32_t)(((uint32_t)(x)) << GPIO_W_W_SHIFT)) & GPIO_W_W_MASK)
+/*! @} */
+
+/* The count of GPIO_W */
+#define GPIO_W_COUNT                             (1U)
+
+/* The count of GPIO_W */
+#define GPIO_W_COUNT2                            (22U)
+
+/*! @name DIR - Direction register */
+/*! @{ */
+#define GPIO_DIR_DIRP_PIO0_MASK                  (0x1U)
+#define GPIO_DIR_DIRP_PIO0_SHIFT                 (0U)
+/*! DIRP_PIO0 - Selects pin direction for pin PIO0 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO0_SHIFT)) & GPIO_DIR_DIRP_PIO0_MASK)
+#define GPIO_DIR_DIRP_PIO1_MASK                  (0x2U)
+#define GPIO_DIR_DIRP_PIO1_SHIFT                 (1U)
+/*! DIRP_PIO1 - Selects pin direction for pin PIO1 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO1_SHIFT)) & GPIO_DIR_DIRP_PIO1_MASK)
+#define GPIO_DIR_DIRP_PIO2_MASK                  (0x4U)
+#define GPIO_DIR_DIRP_PIO2_SHIFT                 (2U)
+/*! DIRP_PIO2 - Selects pin direction for pin PIO2 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO2_SHIFT)) & GPIO_DIR_DIRP_PIO2_MASK)
+#define GPIO_DIR_DIRP_PIO3_MASK                  (0x8U)
+#define GPIO_DIR_DIRP_PIO3_SHIFT                 (3U)
+/*! DIRP_PIO3 - Selects pin direction for pin PIO3 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO3_SHIFT)) & GPIO_DIR_DIRP_PIO3_MASK)
+#define GPIO_DIR_DIRP_PIO4_MASK                  (0x10U)
+#define GPIO_DIR_DIRP_PIO4_SHIFT                 (4U)
+/*! DIRP_PIO4 - Selects pin direction for pin PIO4 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO4_SHIFT)) & GPIO_DIR_DIRP_PIO4_MASK)
+#define GPIO_DIR_DIRP_PIO5_MASK                  (0x20U)
+#define GPIO_DIR_DIRP_PIO5_SHIFT                 (5U)
+/*! DIRP_PIO5 - Selects pin direction for pin PIO5 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO5_SHIFT)) & GPIO_DIR_DIRP_PIO5_MASK)
+#define GPIO_DIR_DIRP_PIO6_MASK                  (0x40U)
+#define GPIO_DIR_DIRP_PIO6_SHIFT                 (6U)
+/*! DIRP_PIO6 - Selects pin direction for pin PIO6 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO6_SHIFT)) & GPIO_DIR_DIRP_PIO6_MASK)
+#define GPIO_DIR_DIRP_PIO7_MASK                  (0x80U)
+#define GPIO_DIR_DIRP_PIO7_SHIFT                 (7U)
+/*! DIRP_PIO7 - Selects pin direction for pin PIO7 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO7_SHIFT)) & GPIO_DIR_DIRP_PIO7_MASK)
+#define GPIO_DIR_DIRP_PIO8_MASK                  (0x100U)
+#define GPIO_DIR_DIRP_PIO8_SHIFT                 (8U)
+/*! DIRP_PIO8 - Selects pin direction for pin PIO8 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO8_SHIFT)) & GPIO_DIR_DIRP_PIO8_MASK)
+#define GPIO_DIR_DIRP_PIO9_MASK                  (0x200U)
+#define GPIO_DIR_DIRP_PIO9_SHIFT                 (9U)
+/*! DIRP_PIO9 - Selects pin direction for pin PIO9 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO9_SHIFT)) & GPIO_DIR_DIRP_PIO9_MASK)
+#define GPIO_DIR_DIRP_PIO10_MASK                 (0x400U)
+#define GPIO_DIR_DIRP_PIO10_SHIFT                (10U)
+/*! DIRP_PIO10 - Selects pin direction for pin PIO10 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO10_SHIFT)) & GPIO_DIR_DIRP_PIO10_MASK)
+#define GPIO_DIR_DIRP_PIO11_MASK                 (0x800U)
+#define GPIO_DIR_DIRP_PIO11_SHIFT                (11U)
+/*! DIRP_PIO11 - Selects pin direction for pin PIO11 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO11_SHIFT)) & GPIO_DIR_DIRP_PIO11_MASK)
+#define GPIO_DIR_DIRP_PIO12_MASK                 (0x1000U)
+#define GPIO_DIR_DIRP_PIO12_SHIFT                (12U)
+/*! DIRP_PIO12 - Selects pin direction for pin PIO12 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO12_SHIFT)) & GPIO_DIR_DIRP_PIO12_MASK)
+#define GPIO_DIR_DIRP_PIO13_MASK                 (0x2000U)
+#define GPIO_DIR_DIRP_PIO13_SHIFT                (13U)
+/*! DIRP_PIO13 - Selects pin direction for pin PIO13 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO13_SHIFT)) & GPIO_DIR_DIRP_PIO13_MASK)
+#define GPIO_DIR_DIRP_PIO14_MASK                 (0x4000U)
+#define GPIO_DIR_DIRP_PIO14_SHIFT                (14U)
+/*! DIRP_PIO14 - Selects pin direction for pin PIO14 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO14_SHIFT)) & GPIO_DIR_DIRP_PIO14_MASK)
+#define GPIO_DIR_DIRP_PIO15_MASK                 (0x8000U)
+#define GPIO_DIR_DIRP_PIO15_SHIFT                (15U)
+/*! DIRP_PIO15 - Selects pin direction for pin PIO15 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO15_SHIFT)) & GPIO_DIR_DIRP_PIO15_MASK)
+#define GPIO_DIR_DIRP_PIO16_MASK                 (0x10000U)
+#define GPIO_DIR_DIRP_PIO16_SHIFT                (16U)
+/*! DIRP_PIO16 - Selects pin direction for pin PIO16 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO16_SHIFT)) & GPIO_DIR_DIRP_PIO16_MASK)
+#define GPIO_DIR_DIRP_PIO17_MASK                 (0x20000U)
+#define GPIO_DIR_DIRP_PIO17_SHIFT                (17U)
+/*! DIRP_PIO17 - Selects pin direction for pin PIO17 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO17_SHIFT)) & GPIO_DIR_DIRP_PIO17_MASK)
+#define GPIO_DIR_DIRP_PIO18_MASK                 (0x40000U)
+#define GPIO_DIR_DIRP_PIO18_SHIFT                (18U)
+/*! DIRP_PIO18 - Selects pin direction for pin PIO18 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO18_SHIFT)) & GPIO_DIR_DIRP_PIO18_MASK)
+#define GPIO_DIR_DIRP_PIO19_MASK                 (0x80000U)
+#define GPIO_DIR_DIRP_PIO19_SHIFT                (19U)
+/*! DIRP_PIO19 - Selects pin direction for pin PIO19 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO19_SHIFT)) & GPIO_DIR_DIRP_PIO19_MASK)
+#define GPIO_DIR_DIRP_PIO20_MASK                 (0x100000U)
+#define GPIO_DIR_DIRP_PIO20_SHIFT                (20U)
+/*! DIRP_PIO20 - Selects pin direction for pin PIO20 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO20_SHIFT)) & GPIO_DIR_DIRP_PIO20_MASK)
+#define GPIO_DIR_DIRP_PIO21_MASK                 (0x200000U)
+#define GPIO_DIR_DIRP_PIO21_SHIFT                (21U)
+/*! DIRP_PIO21 - Selects pin direction for pin PIO21 . 0 = input. 1 = output.
+ */
+#define GPIO_DIR_DIRP_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_PIO21_SHIFT)) & GPIO_DIR_DIRP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_DIR */
+#define GPIO_DIR_COUNT                           (1U)
+
+/*! @name MASK - Mask register */
+/*! @{ */
+#define GPIO_MASK_MASKP_PIO0_MASK                (0x1U)
+#define GPIO_MASK_MASKP_PIO0_SHIFT               (0U)
+/*! MASKP_PIO0 - Controls if PIO0 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO0(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO0_SHIFT)) & GPIO_MASK_MASKP_PIO0_MASK)
+#define GPIO_MASK_MASKP_PIO1_MASK                (0x2U)
+#define GPIO_MASK_MASKP_PIO1_SHIFT               (1U)
+/*! MASKP_PIO1 - Controls if PIO1 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO1(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO1_SHIFT)) & GPIO_MASK_MASKP_PIO1_MASK)
+#define GPIO_MASK_MASKP_PIO2_MASK                (0x4U)
+#define GPIO_MASK_MASKP_PIO2_SHIFT               (2U)
+/*! MASKP_PIO2 - Controls if PIO2 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO2(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO2_SHIFT)) & GPIO_MASK_MASKP_PIO2_MASK)
+#define GPIO_MASK_MASKP_PIO3_MASK                (0x8U)
+#define GPIO_MASK_MASKP_PIO3_SHIFT               (3U)
+/*! MASKP_PIO3 - Controls if PIO3 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO3(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO3_SHIFT)) & GPIO_MASK_MASKP_PIO3_MASK)
+#define GPIO_MASK_MASKP_PIO4_MASK                (0x10U)
+#define GPIO_MASK_MASKP_PIO4_SHIFT               (4U)
+/*! MASKP_PIO4 - Controls if PIO4 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO4(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO4_SHIFT)) & GPIO_MASK_MASKP_PIO4_MASK)
+#define GPIO_MASK_MASKP_PIO5_MASK                (0x20U)
+#define GPIO_MASK_MASKP_PIO5_SHIFT               (5U)
+/*! MASKP_PIO5 - Controls if PIO5 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO5(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO5_SHIFT)) & GPIO_MASK_MASKP_PIO5_MASK)
+#define GPIO_MASK_MASKP_PIO6_MASK                (0x40U)
+#define GPIO_MASK_MASKP_PIO6_SHIFT               (6U)
+/*! MASKP_PIO6 - Controls if PIO6 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO6(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO6_SHIFT)) & GPIO_MASK_MASKP_PIO6_MASK)
+#define GPIO_MASK_MASKP_PIO7_MASK                (0x80U)
+#define GPIO_MASK_MASKP_PIO7_SHIFT               (7U)
+/*! MASKP_PIO7 - Controls if PIO7 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO7(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO7_SHIFT)) & GPIO_MASK_MASKP_PIO7_MASK)
+#define GPIO_MASK_MASKP_PIO8_MASK                (0x100U)
+#define GPIO_MASK_MASKP_PIO8_SHIFT               (8U)
+/*! MASKP_PIO8 - Controls if PIO8 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO8(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO8_SHIFT)) & GPIO_MASK_MASKP_PIO8_MASK)
+#define GPIO_MASK_MASKP_PIO9_MASK                (0x200U)
+#define GPIO_MASK_MASKP_PIO9_SHIFT               (9U)
+/*! MASKP_PIO9 - Controls if PIO9 is active in MPIN register. 0 = Mask bit is clear, the PIO will be
+ *    active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO9(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO9_SHIFT)) & GPIO_MASK_MASKP_PIO9_MASK)
+#define GPIO_MASK_MASKP_PIO10_MASK               (0x400U)
+#define GPIO_MASK_MASKP_PIO10_SHIFT              (10U)
+/*! MASKP_PIO10 - Controls if PIO10 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO10(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO10_SHIFT)) & GPIO_MASK_MASKP_PIO10_MASK)
+#define GPIO_MASK_MASKP_PIO11_MASK               (0x800U)
+#define GPIO_MASK_MASKP_PIO11_SHIFT              (11U)
+/*! MASKP_PIO11 - Controls if PIO11 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO11(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO11_SHIFT)) & GPIO_MASK_MASKP_PIO11_MASK)
+#define GPIO_MASK_MASKP_PIO12_MASK               (0x1000U)
+#define GPIO_MASK_MASKP_PIO12_SHIFT              (12U)
+/*! MASKP_PIO12 - Controls if PIO12 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO12(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO12_SHIFT)) & GPIO_MASK_MASKP_PIO12_MASK)
+#define GPIO_MASK_MASKP_PIO13_MASK               (0x2000U)
+#define GPIO_MASK_MASKP_PIO13_SHIFT              (13U)
+/*! MASKP_PIO13 - Controls if PIO13 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO13(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO13_SHIFT)) & GPIO_MASK_MASKP_PIO13_MASK)
+#define GPIO_MASK_MASKP_PIO14_MASK               (0x4000U)
+#define GPIO_MASK_MASKP_PIO14_SHIFT              (14U)
+/*! MASKP_PIO14 - Controls if PIO14 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO14(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO14_SHIFT)) & GPIO_MASK_MASKP_PIO14_MASK)
+#define GPIO_MASK_MASKP_PIO15_MASK               (0x8000U)
+#define GPIO_MASK_MASKP_PIO15_SHIFT              (15U)
+/*! MASKP_PIO15 - Controls if PIO150 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO15(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO15_SHIFT)) & GPIO_MASK_MASKP_PIO15_MASK)
+#define GPIO_MASK_MASKP_PIO16_MASK               (0x10000U)
+#define GPIO_MASK_MASKP_PIO16_SHIFT              (16U)
+/*! MASKP_PIO16 - Controls if PIO16 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO16(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO16_SHIFT)) & GPIO_MASK_MASKP_PIO16_MASK)
+#define GPIO_MASK_MASKP_PIO17_MASK               (0x20000U)
+#define GPIO_MASK_MASKP_PIO17_SHIFT              (17U)
+/*! MASKP_PIO17 - Controls if PIO17 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO17(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO17_SHIFT)) & GPIO_MASK_MASKP_PIO17_MASK)
+#define GPIO_MASK_MASKP_PIO18_MASK               (0x40000U)
+#define GPIO_MASK_MASKP_PIO18_SHIFT              (18U)
+/*! MASKP_PIO18 - Controls if PIO18 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO18(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO18_SHIFT)) & GPIO_MASK_MASKP_PIO18_MASK)
+#define GPIO_MASK_MASKP_PIO19_MASK               (0x80000U)
+#define GPIO_MASK_MASKP_PIO19_SHIFT              (19U)
+/*! MASKP_PIO19 - Controls if PIO19 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO19(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO19_SHIFT)) & GPIO_MASK_MASKP_PIO19_MASK)
+#define GPIO_MASK_MASKP_PIO20_MASK               (0x100000U)
+#define GPIO_MASK_MASKP_PIO20_SHIFT              (20U)
+/*! MASKP_PIO20 - Controls if PIO20 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO20(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO20_SHIFT)) & GPIO_MASK_MASKP_PIO20_MASK)
+#define GPIO_MASK_MASKP_PIO21_MASK               (0x200000U)
+#define GPIO_MASK_MASKP_PIO21_SHIFT              (21U)
+/*! MASKP_PIO21 - Controls if PIO21 is active in MPIN register. 0 = Mask bit is clear, the PIO will
+ *    be active. 1 = Mask bit is set, the PIO will not be active.
+ */
+#define GPIO_MASK_MASKP_PIO21(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_PIO21_SHIFT)) & GPIO_MASK_MASKP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_MASK */
+#define GPIO_MASK_COUNT                          (1U)
+
+/*! @name PIN - Pin register */
+/*! @{ */
+#define GPIO_PIN_PORT_PIO0_MASK                  (0x1U)
+#define GPIO_PIN_PORT_PIO0_SHIFT                 (0U)
+/*! PORT_PIO0 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO0_SHIFT)) & GPIO_PIN_PORT_PIO0_MASK)
+#define GPIO_PIN_PORT_PIO1_MASK                  (0x2U)
+#define GPIO_PIN_PORT_PIO1_SHIFT                 (1U)
+/*! PORT_PIO1 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO1_SHIFT)) & GPIO_PIN_PORT_PIO1_MASK)
+#define GPIO_PIN_PORT_PIO2_MASK                  (0x4U)
+#define GPIO_PIN_PORT_PIO2_SHIFT                 (2U)
+/*! PORT_PIO2 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO2_SHIFT)) & GPIO_PIN_PORT_PIO2_MASK)
+#define GPIO_PIN_PORT_PIO3_MASK                  (0x8U)
+#define GPIO_PIN_PORT_PIO3_SHIFT                 (3U)
+/*! PORT_PIO3 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO3_SHIFT)) & GPIO_PIN_PORT_PIO3_MASK)
+#define GPIO_PIN_PORT_PIO4_MASK                  (0x10U)
+#define GPIO_PIN_PORT_PIO4_SHIFT                 (4U)
+/*! PORT_PIO4 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO4_SHIFT)) & GPIO_PIN_PORT_PIO4_MASK)
+#define GPIO_PIN_PORT_PIO5_MASK                  (0x20U)
+#define GPIO_PIN_PORT_PIO5_SHIFT                 (5U)
+/*! PORT_PIO5 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO5_SHIFT)) & GPIO_PIN_PORT_PIO5_MASK)
+#define GPIO_PIN_PORT_PIO6_MASK                  (0x40U)
+#define GPIO_PIN_PORT_PIO6_SHIFT                 (6U)
+/*! PORT_PIO6 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO6_SHIFT)) & GPIO_PIN_PORT_PIO6_MASK)
+#define GPIO_PIN_PORT_PIO7_MASK                  (0x80U)
+#define GPIO_PIN_PORT_PIO7_SHIFT                 (7U)
+/*! PORT_PIO7 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO7_SHIFT)) & GPIO_PIN_PORT_PIO7_MASK)
+#define GPIO_PIN_PORT_PIO8_MASK                  (0x100U)
+#define GPIO_PIN_PORT_PIO8_SHIFT                 (8U)
+/*! PORT_PIO8 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO8_SHIFT)) & GPIO_PIN_PORT_PIO8_MASK)
+#define GPIO_PIN_PORT_PIO9_MASK                  (0x200U)
+#define GPIO_PIN_PORT_PIO9_SHIFT                 (9U)
+/*! PORT_PIO9 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO9_SHIFT)) & GPIO_PIN_PORT_PIO9_MASK)
+#define GPIO_PIN_PORT_PIO10_MASK                 (0x400U)
+#define GPIO_PIN_PORT_PIO10_SHIFT                (10U)
+/*! PORT_PIO10 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO10_SHIFT)) & GPIO_PIN_PORT_PIO10_MASK)
+#define GPIO_PIN_PORT_PIO11_MASK                 (0x800U)
+#define GPIO_PIN_PORT_PIO11_SHIFT                (11U)
+/*! PORT_PIO11 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO11_SHIFT)) & GPIO_PIN_PORT_PIO11_MASK)
+#define GPIO_PIN_PORT_PIO12_MASK                 (0x1000U)
+#define GPIO_PIN_PORT_PIO12_SHIFT                (12U)
+/*! PORT_PIO12 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO12_SHIFT)) & GPIO_PIN_PORT_PIO12_MASK)
+#define GPIO_PIN_PORT_PIO13_MASK                 (0x2000U)
+#define GPIO_PIN_PORT_PIO13_SHIFT                (13U)
+/*! PORT_PIO13 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO13_SHIFT)) & GPIO_PIN_PORT_PIO13_MASK)
+#define GPIO_PIN_PORT_PIO14_MASK                 (0x4000U)
+#define GPIO_PIN_PORT_PIO14_SHIFT                (14U)
+/*! PORT_PIO14 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO14_SHIFT)) & GPIO_PIN_PORT_PIO14_MASK)
+#define GPIO_PIN_PORT_PIO15_MASK                 (0x8000U)
+#define GPIO_PIN_PORT_PIO15_SHIFT                (15U)
+/*! PORT_PIO15 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO15_SHIFT)) & GPIO_PIN_PORT_PIO15_MASK)
+#define GPIO_PIN_PORT_PIO16_MASK                 (0x10000U)
+#define GPIO_PIN_PORT_PIO16_SHIFT                (16U)
+/*! PORT_PIO16 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO16_SHIFT)) & GPIO_PIN_PORT_PIO16_MASK)
+#define GPIO_PIN_PORT_PIO17_MASK                 (0x20000U)
+#define GPIO_PIN_PORT_PIO17_SHIFT                (17U)
+/*! PORT_PIO17 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO17_SHIFT)) & GPIO_PIN_PORT_PIO17_MASK)
+#define GPIO_PIN_PORT_PIO18_MASK                 (0x40000U)
+#define GPIO_PIN_PORT_PIO18_SHIFT                (18U)
+/*! PORT_PIO18 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO18_SHIFT)) & GPIO_PIN_PORT_PIO18_MASK)
+#define GPIO_PIN_PORT_PIO19_MASK                 (0x80000U)
+#define GPIO_PIN_PORT_PIO19_SHIFT                (19U)
+/*! PORT_PIO19 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO19_SHIFT)) & GPIO_PIN_PORT_PIO19_MASK)
+#define GPIO_PIN_PORT_PIO20_MASK                 (0x100000U)
+#define GPIO_PIN_PORT_PIO20_SHIFT                (20U)
+/*! PORT_PIO20 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO20_SHIFT)) & GPIO_PIN_PORT_PIO20_MASK)
+#define GPIO_PIN_PORT_PIO21_MASK                 (0x200000U)
+#define GPIO_PIN_PORT_PIO21_SHIFT                (21U)
+/*! PORT_PIO21 - Reads pin states or loads output bits. 0 = Read: pin is low; write: clear output
+ *    bit. 1 = Read: pin is high; write: set output bit.
+ */
+#define GPIO_PIN_PORT_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_PIO21_SHIFT)) & GPIO_PIN_PORT_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_PIN */
+#define GPIO_PIN_COUNT                           (1U)
+
+/*! @name MPIN - Masked Pin register */
+/*! @{ */
+#define GPIO_MPIN_MPORT_PIO0_MASK                (0x1U)
+#define GPIO_MPIN_MPORT_PIO0_SHIFT               (0U)
+/*! MPORT_PIO0 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO0(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO0_SHIFT)) & GPIO_MPIN_MPORT_PIO0_MASK)
+#define GPIO_MPIN_MPORT_PIO1_MASK                (0x2U)
+#define GPIO_MPIN_MPORT_PIO1_SHIFT               (1U)
+/*! MPORT_PIO1 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO1(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO1_SHIFT)) & GPIO_MPIN_MPORT_PIO1_MASK)
+#define GPIO_MPIN_MPORT_PIO2_MASK                (0x4U)
+#define GPIO_MPIN_MPORT_PIO2_SHIFT               (2U)
+/*! MPORT_PIO2 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO2(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO2_SHIFT)) & GPIO_MPIN_MPORT_PIO2_MASK)
+#define GPIO_MPIN_MPORT_PIO3_MASK                (0x8U)
+#define GPIO_MPIN_MPORT_PIO3_SHIFT               (3U)
+/*! MPORT_PIO3 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO3(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO3_SHIFT)) & GPIO_MPIN_MPORT_PIO3_MASK)
+#define GPIO_MPIN_MPORT_PIO4_MASK                (0x10U)
+#define GPIO_MPIN_MPORT_PIO4_SHIFT               (4U)
+/*! MPORT_PIO4 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO4(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO4_SHIFT)) & GPIO_MPIN_MPORT_PIO4_MASK)
+#define GPIO_MPIN_MPORT_PIO5_MASK                (0x20U)
+#define GPIO_MPIN_MPORT_PIO5_SHIFT               (5U)
+/*! MPORT_PIO5 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO5(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO5_SHIFT)) & GPIO_MPIN_MPORT_PIO5_MASK)
+#define GPIO_MPIN_MPORT_PIO6_MASK                (0x40U)
+#define GPIO_MPIN_MPORT_PIO6_SHIFT               (6U)
+/*! MPORT_PIO6 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO6(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO6_SHIFT)) & GPIO_MPIN_MPORT_PIO6_MASK)
+#define GPIO_MPIN_MPORT_PIO7_MASK                (0x80U)
+#define GPIO_MPIN_MPORT_PIO7_SHIFT               (7U)
+/*! MPORT_PIO7 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO7(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO7_SHIFT)) & GPIO_MPIN_MPORT_PIO7_MASK)
+#define GPIO_MPIN_MPORT_PIO8_MASK                (0x100U)
+#define GPIO_MPIN_MPORT_PIO8_SHIFT               (8U)
+/*! MPORT_PIO8 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO8(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO8_SHIFT)) & GPIO_MPIN_MPORT_PIO8_MASK)
+#define GPIO_MPIN_MPORT_PIO9_MASK                (0x200U)
+#define GPIO_MPIN_MPORT_PIO9_SHIFT               (9U)
+/*! MPORT_PIO9 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 =
+ *    Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO9(x)                  (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO9_SHIFT)) & GPIO_MPIN_MPORT_PIO9_MASK)
+#define GPIO_MPIN_MPORT_PIO10_MASK               (0x400U)
+#define GPIO_MPIN_MPORT_PIO10_SHIFT              (10U)
+/*! MPORT_PIO10 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO10(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO10_SHIFT)) & GPIO_MPIN_MPORT_PIO10_MASK)
+#define GPIO_MPIN_MPORT_PIO11_MASK               (0x800U)
+#define GPIO_MPIN_MPORT_PIO11_SHIFT              (11U)
+/*! MPORT_PIO11 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO11(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO11_SHIFT)) & GPIO_MPIN_MPORT_PIO11_MASK)
+#define GPIO_MPIN_MPORT_PIO12_MASK               (0x1000U)
+#define GPIO_MPIN_MPORT_PIO12_SHIFT              (12U)
+/*! MPORT_PIO12 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO12(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO12_SHIFT)) & GPIO_MPIN_MPORT_PIO12_MASK)
+#define GPIO_MPIN_MPORT_PIO13_MASK               (0x2000U)
+#define GPIO_MPIN_MPORT_PIO13_SHIFT              (13U)
+/*! MPORT_PIO13 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO13(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO13_SHIFT)) & GPIO_MPIN_MPORT_PIO13_MASK)
+#define GPIO_MPIN_MPORT_PIO14_MASK               (0x4000U)
+#define GPIO_MPIN_MPORT_PIO14_SHIFT              (14U)
+/*! MPORT_PIO14 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO14(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO14_SHIFT)) & GPIO_MPIN_MPORT_PIO14_MASK)
+#define GPIO_MPIN_MPORT_PIO15_MASK               (0x8000U)
+#define GPIO_MPIN_MPORT_PIO15_SHIFT              (15U)
+/*! MPORT_PIO15 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO15(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO15_SHIFT)) & GPIO_MPIN_MPORT_PIO15_MASK)
+#define GPIO_MPIN_MPORT_PIO16_MASK               (0x10000U)
+#define GPIO_MPIN_MPORT_PIO16_SHIFT              (16U)
+/*! MPORT_PIO16 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO16(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO16_SHIFT)) & GPIO_MPIN_MPORT_PIO16_MASK)
+#define GPIO_MPIN_MPORT_PIO17_MASK               (0x20000U)
+#define GPIO_MPIN_MPORT_PIO17_SHIFT              (17U)
+/*! MPORT_PIO17 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO17(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO17_SHIFT)) & GPIO_MPIN_MPORT_PIO17_MASK)
+#define GPIO_MPIN_MPORT_PIO18_MASK               (0x40000U)
+#define GPIO_MPIN_MPORT_PIO18_SHIFT              (18U)
+/*! MPORT_PIO18 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO18(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO18_SHIFT)) & GPIO_MPIN_MPORT_PIO18_MASK)
+#define GPIO_MPIN_MPORT_PIO19_MASK               (0x80000U)
+#define GPIO_MPIN_MPORT_PIO19_SHIFT              (19U)
+/*! MPORT_PIO19 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO19(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO19_SHIFT)) & GPIO_MPIN_MPORT_PIO19_MASK)
+#define GPIO_MPIN_MPORT_PIO20_MASK               (0x100000U)
+#define GPIO_MPIN_MPORT_PIO20_SHIFT              (20U)
+/*! MPORT_PIO20 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO20(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO20_SHIFT)) & GPIO_MPIN_MPORT_PIO20_MASK)
+#define GPIO_MPIN_MPORT_PIO21_MASK               (0x200000U)
+#define GPIO_MPIN_MPORT_PIO21_SHIFT              (21U)
+/*! MPORT_PIO21 - Masked pin register. 0 = Read: pin is LOW and/or the corresponding bit in the MASK
+ *    register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1
+ *    = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit
+ *    if the corresponding bit in the MASK register is 0.
+ */
+#define GPIO_MPIN_MPORT_PIO21(x)                 (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORT_PIO21_SHIFT)) & GPIO_MPIN_MPORT_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_MPIN */
+#define GPIO_MPIN_COUNT                          (1U)
+
+/*! @name SET - Write: Set Pin register bits Read: output bits */
+/*! @{ */
+#define GPIO_SET_SETP_PIO0_MASK                  (0x1U)
+#define GPIO_SET_SETP_PIO0_SHIFT                 (0U)
+/*! SETP_PIO0 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO0_SHIFT)) & GPIO_SET_SETP_PIO0_MASK)
+#define GPIO_SET_SETP_PIO1_MASK                  (0x2U)
+#define GPIO_SET_SETP_PIO1_SHIFT                 (1U)
+/*! SETP_PIO1 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO1_SHIFT)) & GPIO_SET_SETP_PIO1_MASK)
+#define GPIO_SET_SETP_PIO2_MASK                  (0x4U)
+#define GPIO_SET_SETP_PIO2_SHIFT                 (2U)
+/*! SETP_PIO2 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO2_SHIFT)) & GPIO_SET_SETP_PIO2_MASK)
+#define GPIO_SET_SETP_PIO3_MASK                  (0x8U)
+#define GPIO_SET_SETP_PIO3_SHIFT                 (3U)
+/*! SETP_PIO3 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO3_SHIFT)) & GPIO_SET_SETP_PIO3_MASK)
+#define GPIO_SET_SETP_PIO4_MASK                  (0x10U)
+#define GPIO_SET_SETP_PIO4_SHIFT                 (4U)
+/*! SETP_PIO4 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO4_SHIFT)) & GPIO_SET_SETP_PIO4_MASK)
+#define GPIO_SET_SETP_PIO5_MASK                  (0x20U)
+#define GPIO_SET_SETP_PIO5_SHIFT                 (5U)
+/*! SETP_PIO5 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO5_SHIFT)) & GPIO_SET_SETP_PIO5_MASK)
+#define GPIO_SET_SETP_PIO6_MASK                  (0x40U)
+#define GPIO_SET_SETP_PIO6_SHIFT                 (6U)
+/*! SETP_PIO6 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO6_SHIFT)) & GPIO_SET_SETP_PIO6_MASK)
+#define GPIO_SET_SETP_PIO7_MASK                  (0x80U)
+#define GPIO_SET_SETP_PIO7_SHIFT                 (7U)
+/*! SETP_PIO7 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO7_SHIFT)) & GPIO_SET_SETP_PIO7_MASK)
+#define GPIO_SET_SETP_PIO8_MASK                  (0x100U)
+#define GPIO_SET_SETP_PIO8_SHIFT                 (8U)
+/*! SETP_PIO8 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO8_SHIFT)) & GPIO_SET_SETP_PIO8_MASK)
+#define GPIO_SET_SETP_PIO9_MASK                  (0x200U)
+#define GPIO_SET_SETP_PIO9_SHIFT                 (9U)
+/*! SETP_PIO9 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO9_SHIFT)) & GPIO_SET_SETP_PIO9_MASK)
+#define GPIO_SET_SETP_PIO10_MASK                 (0x400U)
+#define GPIO_SET_SETP_PIO10_SHIFT                (10U)
+/*! SETP_PIO10 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO10_SHIFT)) & GPIO_SET_SETP_PIO10_MASK)
+#define GPIO_SET_SETP_PIO11_MASK                 (0x800U)
+#define GPIO_SET_SETP_PIO11_SHIFT                (11U)
+/*! SETP_PIO11 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO11_SHIFT)) & GPIO_SET_SETP_PIO11_MASK)
+#define GPIO_SET_SETP_PIO12_MASK                 (0x1000U)
+#define GPIO_SET_SETP_PIO12_SHIFT                (12U)
+/*! SETP_PIO12 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO12_SHIFT)) & GPIO_SET_SETP_PIO12_MASK)
+#define GPIO_SET_SETP_PIO13_MASK                 (0x2000U)
+#define GPIO_SET_SETP_PIO13_SHIFT                (13U)
+/*! SETP_PIO13 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO13_SHIFT)) & GPIO_SET_SETP_PIO13_MASK)
+#define GPIO_SET_SETP_PIO14_MASK                 (0x4000U)
+#define GPIO_SET_SETP_PIO14_SHIFT                (14U)
+/*! SETP_PIO14 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO14_SHIFT)) & GPIO_SET_SETP_PIO14_MASK)
+#define GPIO_SET_SETP_PIO15_MASK                 (0x8000U)
+#define GPIO_SET_SETP_PIO15_SHIFT                (15U)
+/*! SETP_PIO15 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO15_SHIFT)) & GPIO_SET_SETP_PIO15_MASK)
+#define GPIO_SET_SETP_PIO16_MASK                 (0x10000U)
+#define GPIO_SET_SETP_PIO16_SHIFT                (16U)
+/*! SETP_PIO16 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO16_SHIFT)) & GPIO_SET_SETP_PIO16_MASK)
+#define GPIO_SET_SETP_PIO17_MASK                 (0x20000U)
+#define GPIO_SET_SETP_PIO17_SHIFT                (17U)
+/*! SETP_PIO17 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO17_SHIFT)) & GPIO_SET_SETP_PIO17_MASK)
+#define GPIO_SET_SETP_PIO18_MASK                 (0x40000U)
+#define GPIO_SET_SETP_PIO18_SHIFT                (18U)
+/*! SETP_PIO18 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO18_SHIFT)) & GPIO_SET_SETP_PIO18_MASK)
+#define GPIO_SET_SETP_PIO19_MASK                 (0x80000U)
+#define GPIO_SET_SETP_PIO19_SHIFT                (19U)
+/*! SETP_PIO19 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO19_SHIFT)) & GPIO_SET_SETP_PIO19_MASK)
+#define GPIO_SET_SETP_PIO20_MASK                 (0x100000U)
+#define GPIO_SET_SETP_PIO20_SHIFT                (20U)
+/*! SETP_PIO20 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO20_SHIFT)) & GPIO_SET_SETP_PIO20_MASK)
+#define GPIO_SET_SETP_PIO21_MASK                 (0x200000U)
+#define GPIO_SET_SETP_PIO21_SHIFT                (21U)
+/*! SETP_PIO21 - Read or set output bits. 0 = Read: output bit: write: no operation. 1 = Read: output bit; write: set output bit.
+ */
+#define GPIO_SET_SETP_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_PIO21_SHIFT)) & GPIO_SET_SETP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_SET */
+#define GPIO_SET_COUNT                           (1U)
+
+/*! @name CLR - Clear Pin register bits */
+/*! @{ */
+#define GPIO_CLR_CLRP_PIO0_MASK                  (0x1U)
+#define GPIO_CLR_CLRP_PIO0_SHIFT                 (0U)
+/*! CLRP_PIO0 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO0_SHIFT)) & GPIO_CLR_CLRP_PIO0_MASK)
+#define GPIO_CLR_CLRP_PIO1_MASK                  (0x2U)
+#define GPIO_CLR_CLRP_PIO1_SHIFT                 (1U)
+/*! CLRP_PIO1 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO1_SHIFT)) & GPIO_CLR_CLRP_PIO1_MASK)
+#define GPIO_CLR_CLRP_PIO2_MASK                  (0x4U)
+#define GPIO_CLR_CLRP_PIO2_SHIFT                 (2U)
+/*! CLRP_PIO2 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO2_SHIFT)) & GPIO_CLR_CLRP_PIO2_MASK)
+#define GPIO_CLR_CLRP_PIO3_MASK                  (0x8U)
+#define GPIO_CLR_CLRP_PIO3_SHIFT                 (3U)
+/*! CLRP_PIO3 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO3_SHIFT)) & GPIO_CLR_CLRP_PIO3_MASK)
+#define GPIO_CLR_CLRP_PIO4_MASK                  (0x10U)
+#define GPIO_CLR_CLRP_PIO4_SHIFT                 (4U)
+/*! CLRP_PIO4 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO4_SHIFT)) & GPIO_CLR_CLRP_PIO4_MASK)
+#define GPIO_CLR_CLRP_PIO5_MASK                  (0x20U)
+#define GPIO_CLR_CLRP_PIO5_SHIFT                 (5U)
+/*! CLRP_PIO5 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO5_SHIFT)) & GPIO_CLR_CLRP_PIO5_MASK)
+#define GPIO_CLR_CLRP_PIO6_MASK                  (0x40U)
+#define GPIO_CLR_CLRP_PIO6_SHIFT                 (6U)
+/*! CLRP_PIO6 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO6_SHIFT)) & GPIO_CLR_CLRP_PIO6_MASK)
+#define GPIO_CLR_CLRP_PIO7_MASK                  (0x80U)
+#define GPIO_CLR_CLRP_PIO7_SHIFT                 (7U)
+/*! CLRP_PIO7 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO7_SHIFT)) & GPIO_CLR_CLRP_PIO7_MASK)
+#define GPIO_CLR_CLRP_PIO8_MASK                  (0x100U)
+#define GPIO_CLR_CLRP_PIO8_SHIFT                 (8U)
+/*! CLRP_PIO8 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO8_SHIFT)) & GPIO_CLR_CLRP_PIO8_MASK)
+#define GPIO_CLR_CLRP_PIO9_MASK                  (0x200U)
+#define GPIO_CLR_CLRP_PIO9_SHIFT                 (9U)
+/*! CLRP_PIO9 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO9_SHIFT)) & GPIO_CLR_CLRP_PIO9_MASK)
+#define GPIO_CLR_CLRP_PIO10_MASK                 (0x400U)
+#define GPIO_CLR_CLRP_PIO10_SHIFT                (10U)
+/*! CLRP_PIO10 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO10_SHIFT)) & GPIO_CLR_CLRP_PIO10_MASK)
+#define GPIO_CLR_CLRP_PIO11_MASK                 (0x800U)
+#define GPIO_CLR_CLRP_PIO11_SHIFT                (11U)
+/*! CLRP_PIO11 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO11_SHIFT)) & GPIO_CLR_CLRP_PIO11_MASK)
+#define GPIO_CLR_CLRP_PIO12_MASK                 (0x1000U)
+#define GPIO_CLR_CLRP_PIO12_SHIFT                (12U)
+/*! CLRP_PIO12 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO12_SHIFT)) & GPIO_CLR_CLRP_PIO12_MASK)
+#define GPIO_CLR_CLRP_PIO13_MASK                 (0x2000U)
+#define GPIO_CLR_CLRP_PIO13_SHIFT                (13U)
+/*! CLRP_PIO13 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO13_SHIFT)) & GPIO_CLR_CLRP_PIO13_MASK)
+#define GPIO_CLR_CLRP_PIO14_MASK                 (0x4000U)
+#define GPIO_CLR_CLRP_PIO14_SHIFT                (14U)
+/*! CLRP_PIO14 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO14_SHIFT)) & GPIO_CLR_CLRP_PIO14_MASK)
+#define GPIO_CLR_CLRP_PIO15_MASK                 (0x8000U)
+#define GPIO_CLR_CLRP_PIO15_SHIFT                (15U)
+/*! CLRP_PIO15 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO15_SHIFT)) & GPIO_CLR_CLRP_PIO15_MASK)
+#define GPIO_CLR_CLRP_PIO16_MASK                 (0x10000U)
+#define GPIO_CLR_CLRP_PIO16_SHIFT                (16U)
+/*! CLRP_PIO16 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO16_SHIFT)) & GPIO_CLR_CLRP_PIO16_MASK)
+#define GPIO_CLR_CLRP_PIO17_MASK                 (0x20000U)
+#define GPIO_CLR_CLRP_PIO17_SHIFT                (17U)
+/*! CLRP_PIO17 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO17_SHIFT)) & GPIO_CLR_CLRP_PIO17_MASK)
+#define GPIO_CLR_CLRP_PIO18_MASK                 (0x40000U)
+#define GPIO_CLR_CLRP_PIO18_SHIFT                (18U)
+/*! CLRP_PIO18 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO18_SHIFT)) & GPIO_CLR_CLRP_PIO18_MASK)
+#define GPIO_CLR_CLRP_PIO19_MASK                 (0x80000U)
+#define GPIO_CLR_CLRP_PIO19_SHIFT                (19U)
+/*! CLRP_PIO19 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO19_SHIFT)) & GPIO_CLR_CLRP_PIO19_MASK)
+#define GPIO_CLR_CLRP_PIO20_MASK                 (0x100000U)
+#define GPIO_CLR_CLRP_PIO20_SHIFT                (20U)
+/*! CLRP_PIO20 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO20_SHIFT)) & GPIO_CLR_CLRP_PIO20_MASK)
+#define GPIO_CLR_CLRP_PIO21_MASK                 (0x200000U)
+#define GPIO_CLR_CLRP_PIO21_SHIFT                (21U)
+/*! CLRP_PIO21 - Clear output bits. 0 = No operation. 1 = Clear output bit.
+ */
+#define GPIO_CLR_CLRP_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_PIO21_SHIFT)) & GPIO_CLR_CLRP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_CLR */
+#define GPIO_CLR_COUNT                           (1U)
+
+/*! @name NOT - Toggle Pin register bits */
+/*! @{ */
+#define GPIO_NOT_NOTP_PIO0_MASK                  (0x1U)
+#define GPIO_NOT_NOTP_PIO0_SHIFT                 (0U)
+/*! NOTP_PIO0 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO0(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO0_SHIFT)) & GPIO_NOT_NOTP_PIO0_MASK)
+#define GPIO_NOT_NOTP_PIO1_MASK                  (0x2U)
+#define GPIO_NOT_NOTP_PIO1_SHIFT                 (1U)
+/*! NOTP_PIO1 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO1(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO1_SHIFT)) & GPIO_NOT_NOTP_PIO1_MASK)
+#define GPIO_NOT_NOTP_PIO2_MASK                  (0x4U)
+#define GPIO_NOT_NOTP_PIO2_SHIFT                 (2U)
+/*! NOTP_PIO2 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO2(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO2_SHIFT)) & GPIO_NOT_NOTP_PIO2_MASK)
+#define GPIO_NOT_NOTP_PIO3_MASK                  (0x8U)
+#define GPIO_NOT_NOTP_PIO3_SHIFT                 (3U)
+/*! NOTP_PIO3 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO3(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO3_SHIFT)) & GPIO_NOT_NOTP_PIO3_MASK)
+#define GPIO_NOT_NOTP_PIO4_MASK                  (0x10U)
+#define GPIO_NOT_NOTP_PIO4_SHIFT                 (4U)
+/*! NOTP_PIO4 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO4(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO4_SHIFT)) & GPIO_NOT_NOTP_PIO4_MASK)
+#define GPIO_NOT_NOTP_PIO5_MASK                  (0x20U)
+#define GPIO_NOT_NOTP_PIO5_SHIFT                 (5U)
+/*! NOTP_PIO5 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO5(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO5_SHIFT)) & GPIO_NOT_NOTP_PIO5_MASK)
+#define GPIO_NOT_NOTP_PIO6_MASK                  (0x40U)
+#define GPIO_NOT_NOTP_PIO6_SHIFT                 (6U)
+/*! NOTP_PIO6 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO6(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO6_SHIFT)) & GPIO_NOT_NOTP_PIO6_MASK)
+#define GPIO_NOT_NOTP_PIO7_MASK                  (0x80U)
+#define GPIO_NOT_NOTP_PIO7_SHIFT                 (7U)
+/*! NOTP_PIO7 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO7(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO7_SHIFT)) & GPIO_NOT_NOTP_PIO7_MASK)
+#define GPIO_NOT_NOTP_PIO8_MASK                  (0x100U)
+#define GPIO_NOT_NOTP_PIO8_SHIFT                 (8U)
+/*! NOTP_PIO8 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO8(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO8_SHIFT)) & GPIO_NOT_NOTP_PIO8_MASK)
+#define GPIO_NOT_NOTP_PIO9_MASK                  (0x200U)
+#define GPIO_NOT_NOTP_PIO9_SHIFT                 (9U)
+/*! NOTP_PIO9 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO9(x)                    (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO9_SHIFT)) & GPIO_NOT_NOTP_PIO9_MASK)
+#define GPIO_NOT_NOTP_PIO10_MASK                 (0x400U)
+#define GPIO_NOT_NOTP_PIO10_SHIFT                (10U)
+/*! NOTP_PIO10 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO10(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO10_SHIFT)) & GPIO_NOT_NOTP_PIO10_MASK)
+#define GPIO_NOT_NOTP_PIO11_MASK                 (0x800U)
+#define GPIO_NOT_NOTP_PIO11_SHIFT                (11U)
+/*! NOTP_PIO11 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO11(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO11_SHIFT)) & GPIO_NOT_NOTP_PIO11_MASK)
+#define GPIO_NOT_NOTP_PIO12_MASK                 (0x1000U)
+#define GPIO_NOT_NOTP_PIO12_SHIFT                (12U)
+/*! NOTP_PIO12 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO12(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO12_SHIFT)) & GPIO_NOT_NOTP_PIO12_MASK)
+#define GPIO_NOT_NOTP_PIO13_MASK                 (0x2000U)
+#define GPIO_NOT_NOTP_PIO13_SHIFT                (13U)
+/*! NOTP_PIO13 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO13(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO13_SHIFT)) & GPIO_NOT_NOTP_PIO13_MASK)
+#define GPIO_NOT_NOTP_PIO14_MASK                 (0x4000U)
+#define GPIO_NOT_NOTP_PIO14_SHIFT                (14U)
+/*! NOTP_PIO14 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO14(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO14_SHIFT)) & GPIO_NOT_NOTP_PIO14_MASK)
+#define GPIO_NOT_NOTP_PIO15_MASK                 (0x8000U)
+#define GPIO_NOT_NOTP_PIO15_SHIFT                (15U)
+/*! NOTP_PIO15 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO15(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO15_SHIFT)) & GPIO_NOT_NOTP_PIO15_MASK)
+#define GPIO_NOT_NOTP_PIO16_MASK                 (0x10000U)
+#define GPIO_NOT_NOTP_PIO16_SHIFT                (16U)
+/*! NOTP_PIO16 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO16(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO16_SHIFT)) & GPIO_NOT_NOTP_PIO16_MASK)
+#define GPIO_NOT_NOTP_PIO17_MASK                 (0x20000U)
+#define GPIO_NOT_NOTP_PIO17_SHIFT                (17U)
+/*! NOTP_PIO17 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO17(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO17_SHIFT)) & GPIO_NOT_NOTP_PIO17_MASK)
+#define GPIO_NOT_NOTP_PIO18_MASK                 (0x40000U)
+#define GPIO_NOT_NOTP_PIO18_SHIFT                (18U)
+/*! NOTP_PIO18 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO18(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO18_SHIFT)) & GPIO_NOT_NOTP_PIO18_MASK)
+#define GPIO_NOT_NOTP_PIO19_MASK                 (0x80000U)
+#define GPIO_NOT_NOTP_PIO19_SHIFT                (19U)
+/*! NOTP_PIO19 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO19(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO19_SHIFT)) & GPIO_NOT_NOTP_PIO19_MASK)
+#define GPIO_NOT_NOTP_PIO20_MASK                 (0x100000U)
+#define GPIO_NOT_NOTP_PIO20_SHIFT                (20U)
+/*! NOTP_PIO20 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO20(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO20_SHIFT)) & GPIO_NOT_NOTP_PIO20_MASK)
+#define GPIO_NOT_NOTP_PIO21_MASK                 (0x200000U)
+#define GPIO_NOT_NOTP_PIO21_SHIFT                (21U)
+/*! NOTP_PIO21 - Toggle output bits. 0 = no operation. 1 = Toggle output bit.
+ */
+#define GPIO_NOT_NOTP_PIO21(x)                   (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_PIO21_SHIFT)) & GPIO_NOT_NOTP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_NOT */
+#define GPIO_NOT_COUNT                           (1U)
+
+/*! @name DIRSET - Set pin direction bits */
+/*! @{ */
+#define GPIO_DIRSET_DIRSETP_PIO0_MASK            (0x1U)
+#define GPIO_DIRSET_DIRSETP_PIO0_SHIFT           (0U)
+/*! DIRSETP_PIO0 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO0(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO0_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO0_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO1_MASK            (0x2U)
+#define GPIO_DIRSET_DIRSETP_PIO1_SHIFT           (1U)
+/*! DIRSETP_PIO1 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO1(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO1_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO1_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO2_MASK            (0x4U)
+#define GPIO_DIRSET_DIRSETP_PIO2_SHIFT           (2U)
+/*! DIRSETP_PIO2 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO2(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO2_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO2_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO3_MASK            (0x8U)
+#define GPIO_DIRSET_DIRSETP_PIO3_SHIFT           (3U)
+/*! DIRSETP_PIO3 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO3(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO3_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO3_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO4_MASK            (0x10U)
+#define GPIO_DIRSET_DIRSETP_PIO4_SHIFT           (4U)
+/*! DIRSETP_PIO4 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO4(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO4_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO4_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO5_MASK            (0x20U)
+#define GPIO_DIRSET_DIRSETP_PIO5_SHIFT           (5U)
+/*! DIRSETP_PIO5 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO5(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO5_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO5_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO6_MASK            (0x40U)
+#define GPIO_DIRSET_DIRSETP_PIO6_SHIFT           (6U)
+/*! DIRSETP_PIO6 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO6(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO6_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO6_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO7_MASK            (0x80U)
+#define GPIO_DIRSET_DIRSETP_PIO7_SHIFT           (7U)
+/*! DIRSETP_PIO7 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO7(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO7_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO7_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO8_MASK            (0x100U)
+#define GPIO_DIRSET_DIRSETP_PIO8_SHIFT           (8U)
+/*! DIRSETP_PIO8 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO8(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO8_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO8_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO9_MASK            (0x200U)
+#define GPIO_DIRSET_DIRSETP_PIO9_SHIFT           (9U)
+/*! DIRSETP_PIO9 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO9(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO9_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO9_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO10_MASK           (0x400U)
+#define GPIO_DIRSET_DIRSETP_PIO10_SHIFT          (10U)
+/*! DIRSETP_PIO10 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO10(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO10_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO10_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO11_MASK           (0x800U)
+#define GPIO_DIRSET_DIRSETP_PIO11_SHIFT          (11U)
+/*! DIRSETP_PIO11 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO11(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO11_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO11_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO12_MASK           (0x1000U)
+#define GPIO_DIRSET_DIRSETP_PIO12_SHIFT          (12U)
+/*! DIRSETP_PIO12 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO12(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO12_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO12_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO13_MASK           (0x2000U)
+#define GPIO_DIRSET_DIRSETP_PIO13_SHIFT          (13U)
+/*! DIRSETP_PIO13 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO13(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO13_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO13_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO14_MASK           (0x4000U)
+#define GPIO_DIRSET_DIRSETP_PIO14_SHIFT          (14U)
+/*! DIRSETP_PIO14 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO14(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO14_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO14_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO15_MASK           (0x8000U)
+#define GPIO_DIRSET_DIRSETP_PIO15_SHIFT          (15U)
+/*! DIRSETP_PIO15 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO15(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO15_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO15_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO16_MASK           (0x10000U)
+#define GPIO_DIRSET_DIRSETP_PIO16_SHIFT          (16U)
+/*! DIRSETP_PIO16 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO16(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO16_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO16_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO17_MASK           (0x20000U)
+#define GPIO_DIRSET_DIRSETP_PIO17_SHIFT          (17U)
+/*! DIRSETP_PIO17 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO17(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO17_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO17_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO18_MASK           (0x40000U)
+#define GPIO_DIRSET_DIRSETP_PIO18_SHIFT          (18U)
+/*! DIRSETP_PIO18 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO18(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO18_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO18_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO19_MASK           (0x80000U)
+#define GPIO_DIRSET_DIRSETP_PIO19_SHIFT          (19U)
+/*! DIRSETP_PIO19 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO19(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO19_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO19_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO20_MASK           (0x100000U)
+#define GPIO_DIRSET_DIRSETP_PIO20_SHIFT          (20U)
+/*! DIRSETP_PIO20 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO20(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO20_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO20_MASK)
+#define GPIO_DIRSET_DIRSETP_PIO21_MASK           (0x200000U)
+#define GPIO_DIRSET_DIRSETP_PIO21_SHIFT          (21U)
+/*! DIRSETP_PIO21 - Set direction bits. 0 = no operation. 1 = Set direction bit.
+ */
+#define GPIO_DIRSET_DIRSETP_PIO21(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_PIO21_SHIFT)) & GPIO_DIRSET_DIRSETP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_DIRSET */
+#define GPIO_DIRSET_COUNT                        (1U)
+
+/*! @name DIRCLR - Clear pin direction bits */
+/*! @{ */
+#define GPIO_DIRCLR_DIRCLRP_PIO0_MASK            (0x1U)
+#define GPIO_DIRCLR_DIRCLRP_PIO0_SHIFT           (0U)
+/*! DIRCLRP_PIO0 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO0(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO0_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO0_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO1_MASK            (0x2U)
+#define GPIO_DIRCLR_DIRCLRP_PIO1_SHIFT           (1U)
+/*! DIRCLRP_PIO1 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO1(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO1_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO1_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO2_MASK            (0x4U)
+#define GPIO_DIRCLR_DIRCLRP_PIO2_SHIFT           (2U)
+/*! DIRCLRP_PIO2 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO2(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO2_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO2_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO3_MASK            (0x8U)
+#define GPIO_DIRCLR_DIRCLRP_PIO3_SHIFT           (3U)
+/*! DIRCLRP_PIO3 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO3(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO3_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO3_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO4_MASK            (0x10U)
+#define GPIO_DIRCLR_DIRCLRP_PIO4_SHIFT           (4U)
+/*! DIRCLRP_PIO4 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO4(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO4_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO4_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO5_MASK            (0x20U)
+#define GPIO_DIRCLR_DIRCLRP_PIO5_SHIFT           (5U)
+/*! DIRCLRP_PIO5 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO5(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO5_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO5_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO6_MASK            (0x40U)
+#define GPIO_DIRCLR_DIRCLRP_PIO6_SHIFT           (6U)
+/*! DIRCLRP_PIO6 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO6(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO6_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO6_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO7_MASK            (0x80U)
+#define GPIO_DIRCLR_DIRCLRP_PIO7_SHIFT           (7U)
+/*! DIRCLRP_PIO7 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO7(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO7_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO7_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO8_MASK            (0x100U)
+#define GPIO_DIRCLR_DIRCLRP_PIO8_SHIFT           (8U)
+/*! DIRCLRP_PIO8 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO8(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO8_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO8_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO9_MASK            (0x200U)
+#define GPIO_DIRCLR_DIRCLRP_PIO9_SHIFT           (9U)
+/*! DIRCLRP_PIO9 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO9(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO9_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO9_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO10_MASK           (0x400U)
+#define GPIO_DIRCLR_DIRCLRP_PIO10_SHIFT          (10U)
+/*! DIRCLRP_PIO10 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO10(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO10_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO10_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO11_MASK           (0x800U)
+#define GPIO_DIRCLR_DIRCLRP_PIO11_SHIFT          (11U)
+/*! DIRCLRP_PIO11 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO11(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO11_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO11_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO12_MASK           (0x1000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO12_SHIFT          (12U)
+/*! DIRCLRP_PIO12 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO12(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO12_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO12_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO13_MASK           (0x2000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO13_SHIFT          (13U)
+/*! DIRCLRP_PIO13 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO13(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO13_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO13_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO14_MASK           (0x4000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO14_SHIFT          (14U)
+/*! DIRCLRP_PIO14 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO14(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO14_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO14_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO15_MASK           (0x8000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO15_SHIFT          (15U)
+/*! DIRCLRP_PIO15 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO15(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO15_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO15_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO16_MASK           (0x10000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO16_SHIFT          (16U)
+/*! DIRCLRP_PIO16 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO16(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO16_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO16_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO17_MASK           (0x20000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO17_SHIFT          (17U)
+/*! DIRCLRP_PIO17 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO17(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO17_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO17_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO18_MASK           (0x40000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO18_SHIFT          (18U)
+/*! DIRCLRP_PIO18 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO18(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO18_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO18_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO19_MASK           (0x80000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO19_SHIFT          (19U)
+/*! DIRCLRP_PIO19 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO19(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO19_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO19_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO20_MASK           (0x100000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO20_SHIFT          (20U)
+/*! DIRCLRP_PIO20 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO20(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO20_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO20_MASK)
+#define GPIO_DIRCLR_DIRCLRP_PIO21_MASK           (0x200000U)
+#define GPIO_DIRCLR_DIRCLRP_PIO21_SHIFT          (21U)
+/*! DIRCLRP_PIO21 - Clear direction bits. 0 = no operation. 1 = Clear direction bit.
+ */
+#define GPIO_DIRCLR_DIRCLRP_PIO21(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_PIO21_SHIFT)) & GPIO_DIRCLR_DIRCLRP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_DIRCLR */
+#define GPIO_DIRCLR_COUNT                        (1U)
+
+/*! @name DIRNOT - Toggle pin direction bits */
+/*! @{ */
+#define GPIO_DIRNOT_DIRNOTP_PIO0_MASK            (0x1U)
+#define GPIO_DIRNOT_DIRNOTP_PIO0_SHIFT           (0U)
+/*! DIRNOTP_PIO0 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO0(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO0_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO0_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO1_MASK            (0x2U)
+#define GPIO_DIRNOT_DIRNOTP_PIO1_SHIFT           (1U)
+/*! DIRNOTP_PIO1 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO1(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO1_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO1_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO2_MASK            (0x4U)
+#define GPIO_DIRNOT_DIRNOTP_PIO2_SHIFT           (2U)
+/*! DIRNOTP_PIO2 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO2(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO2_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO2_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO3_MASK            (0x8U)
+#define GPIO_DIRNOT_DIRNOTP_PIO3_SHIFT           (3U)
+/*! DIRNOTP_PIO3 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO3(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO3_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO3_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO4_MASK            (0x10U)
+#define GPIO_DIRNOT_DIRNOTP_PIO4_SHIFT           (4U)
+/*! DIRNOTP_PIO4 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO4(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO4_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO4_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO5_MASK            (0x20U)
+#define GPIO_DIRNOT_DIRNOTP_PIO5_SHIFT           (5U)
+/*! DIRNOTP_PIO5 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO5(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO5_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO5_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO6_MASK            (0x40U)
+#define GPIO_DIRNOT_DIRNOTP_PIO6_SHIFT           (6U)
+/*! DIRNOTP_PIO6 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO6(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO6_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO6_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO7_MASK            (0x80U)
+#define GPIO_DIRNOT_DIRNOTP_PIO7_SHIFT           (7U)
+/*! DIRNOTP_PIO7 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO7(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO7_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO7_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO8_MASK            (0x100U)
+#define GPIO_DIRNOT_DIRNOTP_PIO8_SHIFT           (8U)
+/*! DIRNOTP_PIO8 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO8(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO8_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO8_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO9_MASK            (0x200U)
+#define GPIO_DIRNOT_DIRNOTP_PIO9_SHIFT           (9U)
+/*! DIRNOTP_PIO9 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO9(x)              (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO9_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO9_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO10_MASK           (0x400U)
+#define GPIO_DIRNOT_DIRNOTP_PIO10_SHIFT          (10U)
+/*! DIRNOTP_PIO10 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO10(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO10_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO10_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO11_MASK           (0x800U)
+#define GPIO_DIRNOT_DIRNOTP_PIO11_SHIFT          (11U)
+/*! DIRNOTP_PIO11 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO11(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO11_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO11_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO12_MASK           (0x1000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO12_SHIFT          (12U)
+/*! DIRNOTP_PIO12 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO12(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO12_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO12_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO13_MASK           (0x2000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO13_SHIFT          (13U)
+/*! DIRNOTP_PIO13 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO13(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO13_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO13_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO14_MASK           (0x4000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO14_SHIFT          (14U)
+/*! DIRNOTP_PIO14 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO14(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO14_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO14_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO15_MASK           (0x8000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO15_SHIFT          (15U)
+/*! DIRNOTP_PIO15 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO15(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO15_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO15_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO16_MASK           (0x10000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO16_SHIFT          (16U)
+/*! DIRNOTP_PIO16 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO16(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO16_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO16_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO17_MASK           (0x20000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO17_SHIFT          (17U)
+/*! DIRNOTP_PIO17 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO17(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO17_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO17_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO18_MASK           (0x40000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO18_SHIFT          (18U)
+/*! DIRNOTP_PIO18 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO18(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO18_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO18_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO19_MASK           (0x80000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO19_SHIFT          (19U)
+/*! DIRNOTP_PIO19 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO19(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO19_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO19_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO20_MASK           (0x100000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO20_SHIFT          (20U)
+/*! DIRNOTP_PIO20 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO20(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO20_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO20_MASK)
+#define GPIO_DIRNOT_DIRNOTP_PIO21_MASK           (0x200000U)
+#define GPIO_DIRNOT_DIRNOTP_PIO21_SHIFT          (21U)
+/*! DIRNOTP_PIO21 - Toggle direction bits. 0 = no operation. 1 = Toggle direction bit.
+ */
+#define GPIO_DIRNOT_DIRNOTP_PIO21(x)             (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_PIO21_SHIFT)) & GPIO_DIRNOT_DIRNOTP_PIO21_MASK)
+/*! @} */
+
+/* The count of GPIO_DIRNOT */
+#define GPIO_DIRNOT_COUNT                        (1U)
+
+
+/*!
+ * @}
+ */ /* end of group GPIO_Register_Masks */
+
+
+/* GPIO - Peripheral instance base addresses */
+/** Peripheral GPIO base address */
+#define GPIO_BASE                                (0x40080000u)
+/** Peripheral GPIO base pointer */
+#define GPIO                                     ((GPIO_Type *)GPIO_BASE)
+/** Array initializer of GPIO peripheral base addresses */
+#define GPIO_BASE_ADDRS                          { GPIO_BASE }
+/** Array initializer of GPIO peripheral base pointers */
+#define GPIO_BASE_PTRS                           { GPIO }
+
+/*!
+ * @}
+ */ /* end of group GPIO_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- I2C Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup I2C_Peripheral_Access_Layer I2C Peripheral Access Layer
+ * @{
+ */
+
+/** I2C - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CFG;                               /**< Configuration for shared functions., offset: 0x0 */
+  __IO uint32_t STAT;                              /**< Status register for Master, Slave and Monitor functions., offset: 0x4 */
+  __IO uint32_t INTENSET;                          /**< Interrupt Enable Set and read register., offset: 0x8 */
+  __O  uint32_t INTENCLR;                          /**< Interrupt Enable Clear register. Writing a 1 to this bit clears the corresponding bit in the INTENSET register, disabling that interrupt. This is a Write-only register., offset: 0xC */
+  __IO uint32_t TIMEOUT;                           /**< Time-out value register., offset: 0x10 */
+  __IO uint32_t CLKDIV;                            /**< Clock pre-divider for the entire I2C interface. This determines what time increments are used for the MSTTIME register and controls some timing of the Slave function., offset: 0x14 */
+  __I  uint32_t INTSTAT;                           /**< Interrupt Status register for Master, Slave and Monitor functions., offset: 0x18 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t MSTCTL;                            /**< Master control register., offset: 0x20 */
+  __IO uint32_t MSTTIME;                           /**< Master timing configuration., offset: 0x24 */
+  __IO uint32_t MSTDAT;                            /**< Combined Master receiver and transmitter data register., offset: 0x28 */
+       uint8_t RESERVED_1[20];
+  __IO uint32_t SLVCTL;                            /**< Slave control register., offset: 0x40 */
+  __IO uint32_t SLVDAT;                            /**< Combined Slave receiver and transmitter data register., offset: 0x44 */
+  __IO uint32_t SLVADR[4];                         /**< Slave address 0., array offset: 0x48, array step: 0x4 */
+  __IO uint32_t SLVQUAL0;                          /**< Slave Qualification for address 0., offset: 0x58 */
+       uint8_t RESERVED_2[36];
+  __I  uint32_t MONRXDAT;                          /**< Monitor receiver data register., offset: 0x80 */
+       uint8_t RESERVED_3[3960];
+  __I  uint32_t ID;                                /**< I2C Module Identifier, offset: 0xFFC */
+} I2C_Type;
+
+/* ----------------------------------------------------------------------------
+   -- I2C Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup I2C_Register_Masks I2C Register Masks
+ * @{
+ */
+
+/*! @name CFG - Configuration for shared functions. */
+/*! @{ */
+#define I2C_CFG_MSTEN_MASK                       (0x1U)
+#define I2C_CFG_MSTEN_SHIFT                      (0U)
+/*! MSTEN - Master Enable. When disabled, configurations settings for the Master function are not
+ *    changed, but the Master function is internally reset.
+ */
+#define I2C_CFG_MSTEN(x)                         (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MSTEN_SHIFT)) & I2C_CFG_MSTEN_MASK)
+#define I2C_CFG_SLVEN_MASK                       (0x2U)
+#define I2C_CFG_SLVEN_SHIFT                      (1U)
+/*! SLVEN - Slave Enable. When disabled, configurations settings for the Slave function are not
+ *    changed, but the Slave function is internally reset.
+ */
+#define I2C_CFG_SLVEN(x)                         (((uint32_t)(((uint32_t)(x)) << I2C_CFG_SLVEN_SHIFT)) & I2C_CFG_SLVEN_MASK)
+#define I2C_CFG_MONEN_MASK                       (0x4U)
+#define I2C_CFG_MONEN_SHIFT                      (2U)
+/*! MONEN - Monitor Enable. When disabled, configurations settings for the Monitor function are not
+ *    changed, but the Monitor function is internally reset.
+ */
+#define I2C_CFG_MONEN(x)                         (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONEN_SHIFT)) & I2C_CFG_MONEN_MASK)
+#define I2C_CFG_TIMEOUT_MASK                     (0x8U)
+#define I2C_CFG_TIMEOUT_SHIFT                    (3U)
+/*! TIMEOUT - I2C bus Time-out Enable. When disabled, the time-out function is internally reset.
+ */
+#define I2C_CFG_TIMEOUT(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_CFG_TIMEOUT_SHIFT)) & I2C_CFG_TIMEOUT_MASK)
+#define I2C_CFG_MONCLKSTR_MASK                   (0x10U)
+#define I2C_CFG_MONCLKSTR_SHIFT                  (4U)
+/*! MONCLKSTR - Monitor function Clock Stretching.
+ */
+#define I2C_CFG_MONCLKSTR(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONCLKSTR_SHIFT)) & I2C_CFG_MONCLKSTR_MASK)
+#define I2C_CFG_HSCAPABLE_MASK                   (0x20U)
+#define I2C_CFG_HSCAPABLE_SHIFT                  (5U)
+/*! HSCAPABLE - High-speed mode Capable enable. Since High Speed mode alters the way I2C pins drive
+ *    and filter, as well as the timing for certain I2C signalling, enabling High-speed mode applies
+ *    to all functions: master, slave, and monitor.
+ */
+#define I2C_CFG_HSCAPABLE(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_CFG_HSCAPABLE_SHIFT)) & I2C_CFG_HSCAPABLE_MASK)
+/*! @} */
+
+/*! @name STAT - Status register for Master, Slave and Monitor functions. */
+/*! @{ */
+#define I2C_STAT_MSTPENDING_MASK                 (0x1U)
+#define I2C_STAT_MSTPENDING_SHIFT                (0U)
+/*! MSTPENDING - Master Pending. Indicates that the Master is waiting to continue communication on
+ *    the I2C-bus (pending) or is idle. When the master is pending, the MSTSTATE bits indicate what
+ *    type of software service if any the master expects. This flag will cause an interrupt when set
+ *    if, enabled via the INTENSET register. The MSTPENDING flag is not set when the DMA is handling
+ *    an event (if the MSTDMA bit in the MSTCTL register is set). If the master is in the idle
+ *    state, and no communication is needed, mask this interrupt. 0: In progress. Communication is in
+ *    progress and the Master function is busy and cannot currently accept a command. 1: Pending. The
+ *    Master function needs software service or is in the idle state. If the master is not in the
+ *    idle state, it is waiting to receive or transmit data or the NACK bit.
+ */
+#define I2C_STAT_MSTPENDING(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTPENDING_SHIFT)) & I2C_STAT_MSTPENDING_MASK)
+#define I2C_STAT_MSTSTATE_MASK                   (0xEU)
+#define I2C_STAT_MSTSTATE_SHIFT                  (1U)
+/*! MSTSTATE - Master State code. The master state code reflects the master state when the
+ *    MSTPENDING bit is set, that is the master is pending or in the idle state. Each value of this field
+ *    indicates a specific required service for the Master function. All other values are reserved. 0:
+ *    Idle. The Master function is available to be used for a new transaction. 1: Receive ready.
+ *    Received data available (Master Receiver mode). Address plus Read was previously sent and
+ *    Acknowledged by slave. 2: Transmit ready. Data can be transmitted (Master Transmitter mode). Address
+ *    plus Write was previously sent and Acknowledged by slave. 3: NACK address. Slave NACKed
+ *    address. 4: NACK data. Slave NACKed transmitted data.
+ */
+#define I2C_STAT_MSTSTATE(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTATE_SHIFT)) & I2C_STAT_MSTSTATE_MASK)
+#define I2C_STAT_MSTARBLOSS_MASK                 (0x10U)
+#define I2C_STAT_MSTARBLOSS_SHIFT                (4U)
+/*! MSTARBLOSS - Master Arbitration Loss flag. This flag can be cleared by software writing a 1 to
+ *    this bit. It is also cleared automatically a 1 is written to MSTCONTINUE. 0: No Arbitration
+ *    Loss has occurred. 1: Arbitration Loss. The mater function has experienced an Arbitration Loss.
+ *    At this point, the Master function has already stopped driving the bus and gone to an idle
+ *    state. Software can respond by doing nothing, or by sending a Start in order to attempt to gain
+ *    control of the bus when it next becomes idle.
+ */
+#define I2C_STAT_MSTARBLOSS(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTARBLOSS_SHIFT)) & I2C_STAT_MSTARBLOSS_MASK)
+#define I2C_STAT_MSTSTSTPERR_MASK                (0x40U)
+#define I2C_STAT_MSTSTSTPERR_SHIFT               (6U)
+/*! MSTSTSTPERR - Master Start/Stop Error flag. This flag can be cleared by software writing a 1 to
+ *    this bit. It is also cleared automatically a 1 is written to MSTCONTINUE. 0: No start/stop
+ *    Error has occurred. 1: The master function has experienced a Start/Stop Error. A Start or Stop
+ *    was detected at a time when it is not allowed by the I2C specification. The Master interface has
+ *    stopped driving the bus and gone to an idle state, no action is required. A request for a
+ *    Start could be made, or software could attempt to insure that thet bus has not stalled.
+ */
+#define I2C_STAT_MSTSTSTPERR(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTSTPERR_SHIFT)) & I2C_STAT_MSTSTSTPERR_MASK)
+#define I2C_STAT_SLVPENDING_MASK                 (0x100U)
+#define I2C_STAT_SLVPENDING_SHIFT                (8U)
+/*! SLVPENDING - Slave Pending. Indicates that the Slave function is waiting to continue
+ *    communication on the I2C-bus and needs software service. This flag will cause an interrupt when set if
+ *    enabled via INTENSET. The SLVPENDING flag is not set when the DMA is handling an event (if the
+ *    SLVDMA bit in the SLVCTL register is set). The SLVPENDING flag is read-only and is
+ *    automatically cleared when a 1 is written to the SLVCONTINUE bit in the SLVCTL register. The point in time
+ *    when SlvPending is set depends on whether the I2C interface is in HSCAPABLE mode. When the
+ *    I2C interface is configured to be HSCAPABLE, HS master codes are detected automatically. Due to
+ *    the requirements of the HS I2C specification, slave addresses must also be detected
+ *    automatically, since the address must be acknowledged before the clock can be stretched. 0: In progress.
+ *    The slave function does not currently need service. 1: Pending. The Slave function needs
+ *    service. Information on what is needed can be found in the adjacent SLVSTATE field.
+ */
+#define I2C_STAT_SLVPENDING(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVPENDING_SHIFT)) & I2C_STAT_SLVPENDING_MASK)
+#define I2C_STAT_SLVSTATE_MASK                   (0x600U)
+#define I2C_STAT_SLVSTATE_SHIFT                  (9U)
+/*! SLVSTATE - Slave State code. Each value of this field indicates a specific required service for
+ *    the Slave function. All other values are reserved. See Table 393 for state values and actions.
+ *    Remark: note that the occurrence of some states and how they are handled are affected by DMA
+ *    mode and Automatic Operation modes. Slave state codes are: 0: Slave address. Address plus R/W
+ *    received. At least one of the four slave addresses has been matched by hardware. 1: Slave
+ *    receive. Received data is available (Slave Receiver mode). 2: Slave transmit. Data can be
+ *    transmitted (Slave transmitter mode).
+ */
+#define I2C_STAT_SLVSTATE(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSTATE_SHIFT)) & I2C_STAT_SLVSTATE_MASK)
+#define I2C_STAT_SLVNOTSTR_MASK                  (0x800U)
+#define I2C_STAT_SLVNOTSTR_SHIFT                 (11U)
+/*! SLVNOTSTR - Slave Not Stretching. Indicates when the slave function is stretching the I2C clock.
+ *    This is needed in order to gracefully invoke Deep Sleep or Power-down modes during slave
+ *    operation. This read-only flag reflects the slave function status in real time. 0: stretching. The
+ *    slave function is currently stretching the I2C bus clock. Deep-sleep mode can not be entered
+ *    at this time. 1. Not stretching. The slave function is not currently stretching the I2C bus
+ *    clock. Deep-sleep mode could be entered at this time.
+ */
+#define I2C_STAT_SLVNOTSTR(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVNOTSTR_SHIFT)) & I2C_STAT_SLVNOTSTR_MASK)
+#define I2C_STAT_SLVIDX_MASK                     (0x3000U)
+#define I2C_STAT_SLVIDX_SHIFT                    (12U)
+/*! SLVIDX - Slave address match Index. This field is valid when the I2C slave function has been
+ *    selected by receiving an address that matches one of the slave addresses defined by any enabled
+ *    slave address registers, and provides an identification of the address that was matched. It is
+ *    possible that more than one address could be matched, but only one match can be reported here.
+ *    0: Address 0. Slave address 0 was matched. 1: Address 1. Slave address 1 was matched. 2:
+ *    Address 2. Slave address 2 was matched. 3: Address 3. Slave address 3 was matched.
+ */
+#define I2C_STAT_SLVIDX(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVIDX_SHIFT)) & I2C_STAT_SLVIDX_MASK)
+#define I2C_STAT_SLVSEL_MASK                     (0x4000U)
+#define I2C_STAT_SLVSEL_SHIFT                    (14U)
+/*! SLVSEL - Slave selected flag. SLVSEL is set after an address match when software tells the Slave
+ *    function to acknowledge the address, or when the address has been automatically acknowledged.
+ *    It is cleared when another address cycle presents an address that does not match an enabled
+ *    address on the Slave function, when slave software decides to NACK a matched address, when
+ *    there is a Stop detected on the bus, when the master NACKs slave data, and in some combinations of
+ *    Automatic Operation. SLVSEL is not cleared if software NACKs data. 0: Not selected. The slave
+ *    function is not currently selected. 1: Selected. The slave function is currently selected.
+ */
+#define I2C_STAT_SLVSEL(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSEL_SHIFT)) & I2C_STAT_SLVSEL_MASK)
+#define I2C_STAT_SLVDESEL_MASK                   (0x8000U)
+#define I2C_STAT_SLVDESEL_SHIFT                  (15U)
+/*! SLVDESEL - Slave Deselected flag. This flag will cause an interrupt when set if enabled via
+ *    INTENSET. This flag can be cleared by writing a 1 to this bit. 0: Not deselected. The slave
+ *    function has not become deslected. This does not mean that it is currently selected. That
+ *    information can be found in the SLVSEL flag. 1: Deselected. The slave function has become deselected.
+ *    This is specifically caused by the SLVSEL flag changing from 1 to 0. See the description of
+ *    SLVSEL for details on when that event occurs.
+ */
+#define I2C_STAT_SLVDESEL(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVDESEL_SHIFT)) & I2C_STAT_SLVDESEL_MASK)
+#define I2C_STAT_MONRDY_MASK                     (0x10000U)
+#define I2C_STAT_MONRDY_SHIFT                    (16U)
+/*! MONRDY - Monitor Ready. This flag is cleared when the MONRXDAT register is read. 0: No data. The
+ *    Monitor function does not currently have data available. 1: Data waiting. The Monitor
+ *    function has data waiting to be read.
+ */
+#define I2C_STAT_MONRDY(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONRDY_SHIFT)) & I2C_STAT_MONRDY_MASK)
+#define I2C_STAT_MONOV_MASK                      (0x20000U)
+#define I2C_STAT_MONOV_SHIFT                     (17U)
+/*! MONOV - Monitor Overflow flag. 0: No overrun. Monitor data has not overrun 1: Overrun. A monitor
+ *    data overrun has occurred. This can only happen when Monitor clock stretching is not enabled
+ *    via the MOCCLKSTR bit in the CFG register. Writing 1 to this bit clears the flag.
+ */
+#define I2C_STAT_MONOV(x)                        (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONOV_SHIFT)) & I2C_STAT_MONOV_MASK)
+#define I2C_STAT_MONACTIVE_MASK                  (0x40000U)
+#define I2C_STAT_MONACTIVE_SHIFT                 (18U)
+/*! MONACTIVE - Monitor Active flag. Indicates when the Monitor function considers the I2C bus to be
+ *    active. Active is defined here as when some Master is on the bus: a bus Start has occurred
+ *    more recently than a bus Stop. 0: Inactive. The Monitor function considers the I2C bus to be
+ *    inactive. 1: Active. The Monitor function considers the I2C bus to be active.
+ */
+#define I2C_STAT_MONACTIVE(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONACTIVE_SHIFT)) & I2C_STAT_MONACTIVE_MASK)
+#define I2C_STAT_MONIDLE_MASK                    (0x80000U)
+#define I2C_STAT_MONIDLE_SHIFT                   (19U)
+/*! MONIDLE - Monitor Idle flag. This flag is set when the Monitor function sees the I2C bus change
+ *    from active to inactive. This can be used by software to decide when to process data
+ *    accumulated by the Monitor function. This flag will cause an interrupt when set if enabled via the
+ *    INTENSET register. The flag can be cleared by writing a 1 to this bit. 0: Not idle. The I2C bus is
+ *    not idle, or this flag has been cleared by software. 1: Idle. The I2C bus has gone idle at
+ *    least once since the last time this flag was cleared by software.
+ */
+#define I2C_STAT_MONIDLE(x)                      (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONIDLE_SHIFT)) & I2C_STAT_MONIDLE_MASK)
+#define I2C_STAT_EVENTTIMEOUT_MASK               (0x1000000U)
+#define I2C_STAT_EVENTTIMEOUT_SHIFT              (24U)
+/*! EVENTTIMEOUT - Event Time-out Interrupt flag. Indicates when the time between events has been
+ *    longer than the time specified by the TIMEOUT register. Events include Start, Stop, and clock
+ *    edges. The flag is cleared by writing a 1 to this bit. No time-out is created when the I2C-bus
+ *    is idle. 0: No time-out. I2C bus events have not casued a time-out. 1: Event time-out. The time
+ *    between I2C bus events has been longer than the time specified by the TIMEOUT register.
+ */
+#define I2C_STAT_EVENTTIMEOUT(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_STAT_EVENTTIMEOUT_SHIFT)) & I2C_STAT_EVENTTIMEOUT_MASK)
+#define I2C_STAT_SCLTIMEOUT_MASK                 (0x2000000U)
+#define I2C_STAT_SCLTIMEOUT_SHIFT                (25U)
+/*! SCLTIMEOUT - SCL Time-out Interrupt flag. Indicates when SCL has remained low longer than the
+ *    time specific by the TIMEOUT register. The flag is cleared by writing a 1 to this bit. 0: No
+ *    time-out. SCL low time has not caused a time-out. 1: Time-out. SCL low time has not caused a
+ *    time-out.
+ */
+#define I2C_STAT_SCLTIMEOUT(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SCLTIMEOUT_SHIFT)) & I2C_STAT_SCLTIMEOUT_MASK)
+/*! @} */
+
+/*! @name INTENSET - Interrupt Enable Set and read register. */
+/*! @{ */
+#define I2C_INTENSET_MSTPENDINGEN_MASK           (0x1U)
+#define I2C_INTENSET_MSTPENDINGEN_SHIFT          (0U)
+/*! MSTPENDINGEN - Master Pending interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MSTPENDINGEN(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTPENDINGEN_SHIFT)) & I2C_INTENSET_MSTPENDINGEN_MASK)
+#define I2C_INTENSET_MSTARBLOSSEN_MASK           (0x10U)
+#define I2C_INTENSET_MSTARBLOSSEN_SHIFT          (4U)
+/*! MSTARBLOSSEN - Master Arbitration Loss interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MSTARBLOSSEN(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTARBLOSSEN_SHIFT)) & I2C_INTENSET_MSTARBLOSSEN_MASK)
+#define I2C_INTENSET_MSTSTSTPERREN_MASK          (0x40U)
+#define I2C_INTENSET_MSTSTSTPERREN_SHIFT         (6U)
+/*! MSTSTSTPERREN - Master Start/Stop Error interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MSTSTSTPERREN(x)            (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTSTSTPERREN_SHIFT)) & I2C_INTENSET_MSTSTSTPERREN_MASK)
+#define I2C_INTENSET_SLVPENDINGEN_MASK           (0x100U)
+#define I2C_INTENSET_SLVPENDINGEN_SHIFT          (8U)
+/*! SLVPENDINGEN - Slave Pending interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_SLVPENDINGEN(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVPENDINGEN_SHIFT)) & I2C_INTENSET_SLVPENDINGEN_MASK)
+#define I2C_INTENSET_SLVNOTSTREN_MASK            (0x800U)
+#define I2C_INTENSET_SLVNOTSTREN_SHIFT           (11U)
+/*! SLVNOTSTREN - Slave Not Stretching interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_SLVNOTSTREN(x)              (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVNOTSTREN_SHIFT)) & I2C_INTENSET_SLVNOTSTREN_MASK)
+#define I2C_INTENSET_SLVDESELEN_MASK             (0x8000U)
+#define I2C_INTENSET_SLVDESELEN_SHIFT            (15U)
+/*! SLVDESELEN - Slave Deselect interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_SLVDESELEN(x)               (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVDESELEN_SHIFT)) & I2C_INTENSET_SLVDESELEN_MASK)
+#define I2C_INTENSET_MONRDYEN_MASK               (0x10000U)
+#define I2C_INTENSET_MONRDYEN_SHIFT              (16U)
+/*! MONRDYEN - Monitor data Ready interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MONRDYEN(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONRDYEN_SHIFT)) & I2C_INTENSET_MONRDYEN_MASK)
+#define I2C_INTENSET_MONOVEN_MASK                (0x20000U)
+#define I2C_INTENSET_MONOVEN_SHIFT               (17U)
+/*! MONOVEN - Monitor Overrun interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MONOVEN(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONOVEN_SHIFT)) & I2C_INTENSET_MONOVEN_MASK)
+#define I2C_INTENSET_MONIDLEEN_MASK              (0x80000U)
+#define I2C_INTENSET_MONIDLEEN_SHIFT             (19U)
+/*! MONIDLEEN - Monitor Idle interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_MONIDLEEN(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONIDLEEN_SHIFT)) & I2C_INTENSET_MONIDLEEN_MASK)
+#define I2C_INTENSET_EVENTTIMEOUTEN_MASK         (0x1000000U)
+#define I2C_INTENSET_EVENTTIMEOUTEN_SHIFT        (24U)
+/*! EVENTTIMEOUTEN - Event time-out interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_EVENTTIMEOUTEN(x)           (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_EVENTTIMEOUTEN_SHIFT)) & I2C_INTENSET_EVENTTIMEOUTEN_MASK)
+#define I2C_INTENSET_SCLTIMEOUTEN_MASK           (0x2000000U)
+#define I2C_INTENSET_SCLTIMEOUTEN_SHIFT          (25U)
+/*! SCLTIMEOUTEN - SCL time-out interrupt Enable. 0: interrupt is disabled. 1: interrupt is enabled.
+ */
+#define I2C_INTENSET_SCLTIMEOUTEN(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SCLTIMEOUTEN_SHIFT)) & I2C_INTENSET_SCLTIMEOUTEN_MASK)
+/*! @} */
+
+/*! @name INTENCLR - Interrupt Enable Clear register. Writing a 1 to this bit clears the corresponding bit in the INTENSET register, disabling that interrupt. This is a Write-only register. */
+/*! @{ */
+#define I2C_INTENCLR_MSTPCLRDINGCLR_MASK         (0x1U)
+#define I2C_INTENCLR_MSTPCLRDINGCLR_SHIFT        (0U)
+/*! MSTPCLRDINGCLR - Master Pending interrupt clear.
+ */
+#define I2C_INTENCLR_MSTPCLRDINGCLR(x)           (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTPCLRDINGCLR_SHIFT)) & I2C_INTENCLR_MSTPCLRDINGCLR_MASK)
+#define I2C_INTENCLR_MSTARBLOSSCLR_MASK          (0x10U)
+#define I2C_INTENCLR_MSTARBLOSSCLR_SHIFT         (4U)
+/*! MSTARBLOSSCLR - Master Arbitration Loss interrupt clear.
+ */
+#define I2C_INTENCLR_MSTARBLOSSCLR(x)            (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTARBLOSSCLR_SHIFT)) & I2C_INTENCLR_MSTARBLOSSCLR_MASK)
+#define I2C_INTENCLR_MSTSTSTPERRCLR_MASK         (0x40U)
+#define I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT        (6U)
+/*! MSTSTSTPERRCLR - Master Start/Stop Error interrupt clear.
+ */
+#define I2C_INTENCLR_MSTSTSTPERRCLR(x)           (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT)) & I2C_INTENCLR_MSTSTSTPERRCLR_MASK)
+#define I2C_INTENCLR_SLVPENDINGCLR_MASK          (0x100U)
+#define I2C_INTENCLR_SLVPENDINGCLR_SHIFT         (8U)
+/*! SLVPENDINGCLR - Slave Pending interrupt clear.
+ */
+#define I2C_INTENCLR_SLVPENDINGCLR(x)            (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVPENDINGCLR_SHIFT)) & I2C_INTENCLR_SLVPENDINGCLR_MASK)
+#define I2C_INTENCLR_SLVNOTSTRCLR_MASK           (0x800U)
+#define I2C_INTENCLR_SLVNOTSTRCLR_SHIFT          (11U)
+/*! SLVNOTSTRCLR - Slave Not Stretching interrupt clear.
+ */
+#define I2C_INTENCLR_SLVNOTSTRCLR(x)             (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVNOTSTRCLR_SHIFT)) & I2C_INTENCLR_SLVNOTSTRCLR_MASK)
+#define I2C_INTENCLR_SLVDESELCLR_MASK            (0x8000U)
+#define I2C_INTENCLR_SLVDESELCLR_SHIFT           (15U)
+/*! SLVDESELCLR - Slave Deselect interrupt clear.
+ */
+#define I2C_INTENCLR_SLVDESELCLR(x)              (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVDESELCLR_SHIFT)) & I2C_INTENCLR_SLVDESELCLR_MASK)
+#define I2C_INTENCLR_MONRDYCLR_MASK              (0x10000U)
+#define I2C_INTENCLR_MONRDYCLR_SHIFT             (16U)
+/*! MONRDYCLR - Monitor data Ready interrupt clear.
+ */
+#define I2C_INTENCLR_MONRDYCLR(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONRDYCLR_SHIFT)) & I2C_INTENCLR_MONRDYCLR_MASK)
+#define I2C_INTENCLR_MONOVCLR_MASK               (0x20000U)
+#define I2C_INTENCLR_MONOVCLR_SHIFT              (17U)
+/*! MONOVCLR - Monitor Overrun interrupt clear.
+ */
+#define I2C_INTENCLR_MONOVCLR(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONOVCLR_SHIFT)) & I2C_INTENCLR_MONOVCLR_MASK)
+#define I2C_INTENCLR_MONIDLECLR_MASK             (0x80000U)
+#define I2C_INTENCLR_MONIDLECLR_SHIFT            (19U)
+/*! MONIDLECLR - Monitor Idle interrupt clear.
+ */
+#define I2C_INTENCLR_MONIDLECLR(x)               (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONIDLECLR_SHIFT)) & I2C_INTENCLR_MONIDLECLR_MASK)
+#define I2C_INTENCLR_EVCLRTTIMEOUTCLR_MASK       (0x1000000U)
+#define I2C_INTENCLR_EVCLRTTIMEOUTCLR_SHIFT      (24U)
+/*! EVCLRTTIMEOUTCLR - Event time-out interrupt clear.
+ */
+#define I2C_INTENCLR_EVCLRTTIMEOUTCLR(x)         (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_EVCLRTTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_EVCLRTTIMEOUTCLR_MASK)
+#define I2C_INTENCLR_SCLTIMEOUTCLR_MASK          (0x2000000U)
+#define I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT         (25U)
+/*! SCLTIMEOUTCLR - SCL time-out interrupt clear.
+ */
+#define I2C_INTENCLR_SCLTIMEOUTCLR(x)            (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_SCLTIMEOUTCLR_MASK)
+/*! @} */
+
+/*! @name TIMEOUT - Time-out value register. */
+/*! @{ */
+#define I2C_TIMEOUT_TOMIN_MASK                   (0xFU)
+#define I2C_TIMEOUT_TOMIN_SHIFT                  (0U)
+/*! TOMIN - Time-out time value, bottom four bits. These are hard-wired to 0xF. This gives a minimum
+ *    time-out of 16 I2C function clocks and also a time-out resolution of 16 I2C function clocks.
+ */
+#define I2C_TIMEOUT_TOMIN(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TOMIN_SHIFT)) & I2C_TIMEOUT_TOMIN_MASK)
+#define I2C_TIMEOUT_TO_MASK                      (0xFFF0U)
+#define I2C_TIMEOUT_TO_SHIFT                     (4U)
+/*! TO - Time-out time value. Specifies the time-out interval value in increments of 16 I2C function
+ *    clocks, as defined by the CLKDIV register. To change this value while I2C is in operation,
+ *    disable all time-outs, write a new value to TIMEOUT, then re-enable time-outs. 0x000: A time-out
+ *    will occur after 16 counts of the I2C function clock. 0x001: A time-out will occur after 32
+ *    counts of the I2C function clock. ... 0xFFF: A time-out will occur after 65,536 counts of the
+ *    I2C function clock.
+ */
+#define I2C_TIMEOUT_TO(x)                        (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TO_SHIFT)) & I2C_TIMEOUT_TO_MASK)
+/*! @} */
+
+/*! @name CLKDIV - Clock pre-divider for the entire I2C interface. This determines what time increments are used for the MSTTIME register and controls some timing of the Slave function. */
+/*! @{ */
+#define I2C_CLKDIV_DIVVAL_MASK                   (0xFFFFU)
+#define I2C_CLKDIV_DIVVAL_SHIFT                  (0U)
+/*! DIVVAL - This field controls how the I2C clock (FCLK) is used by the I2C functions that need an
+ *    internal clock in order to operate. I2C block should be configured for 8MHz clock, this will
+ *    limit SCL master clock range from 444kHz to 2MHz. 0x0000 = FCLK is used directly by the I2C.
+ *    0x0001 = FCLK is divided by 2 before use. 0x0002 = FCLK is divided by 3 before use. ... 0xFFFF =
+ *    FCLK is divided by 65,536 before use.
+ */
+#define I2C_CLKDIV_DIVVAL(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_CLKDIV_DIVVAL_SHIFT)) & I2C_CLKDIV_DIVVAL_MASK)
+/*! @} */
+
+/*! @name INTSTAT - Interrupt Status register for Master, Slave and Monitor functions. */
+/*! @{ */
+#define I2C_INTSTAT_MSTPENDING_MASK              (0x1U)
+#define I2C_INTSTAT_MSTPENDING_SHIFT             (0U)
+/*! MSTPENDING - Master Pending interrupt.
+ */
+#define I2C_INTSTAT_MSTPENDING(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTPENDING_SHIFT)) & I2C_INTSTAT_MSTPENDING_MASK)
+#define I2C_INTSTAT_MSTARBLOSS_MASK              (0x10U)
+#define I2C_INTSTAT_MSTARBLOSS_SHIFT             (4U)
+/*! MSTARBLOSS - Master Arbitration Loss interrupt.
+ */
+#define I2C_INTSTAT_MSTARBLOSS(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTARBLOSS_SHIFT)) & I2C_INTSTAT_MSTARBLOSS_MASK)
+#define I2C_INTSTAT_MSTSTSTPERR_MASK             (0x40U)
+#define I2C_INTSTAT_MSTSTSTPERR_SHIFT            (6U)
+/*! MSTSTSTPERR - Master Start/Stop Error interrupt.
+ */
+#define I2C_INTSTAT_MSTSTSTPERR(x)               (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTSTSTPERR_SHIFT)) & I2C_INTSTAT_MSTSTSTPERR_MASK)
+#define I2C_INTSTAT_SLVPENDING_MASK              (0x100U)
+#define I2C_INTSTAT_SLVPENDING_SHIFT             (8U)
+/*! SLVPENDING - Slave Pending interrupt.
+ */
+#define I2C_INTSTAT_SLVPENDING(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVPENDING_SHIFT)) & I2C_INTSTAT_SLVPENDING_MASK)
+#define I2C_INTSTAT_SLVNOTSTR_MASK               (0x800U)
+#define I2C_INTSTAT_SLVNOTSTR_SHIFT              (11U)
+/*! SLVNOTSTR - Slave Not Stretching interrupt.
+ */
+#define I2C_INTSTAT_SLVNOTSTR(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVNOTSTR_SHIFT)) & I2C_INTSTAT_SLVNOTSTR_MASK)
+#define I2C_INTSTAT_SLVDESEL_MASK                (0x8000U)
+#define I2C_INTSTAT_SLVDESEL_SHIFT               (15U)
+/*! SLVDESEL - Slave Deselect interrupt.
+ */
+#define I2C_INTSTAT_SLVDESEL(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVDESEL_SHIFT)) & I2C_INTSTAT_SLVDESEL_MASK)
+#define I2C_INTSTAT_MONRDY_MASK                  (0x10000U)
+#define I2C_INTSTAT_MONRDY_SHIFT                 (16U)
+/*! MONRDY - Monitor data Ready interrupt.
+ */
+#define I2C_INTSTAT_MONRDY(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONRDY_SHIFT)) & I2C_INTSTAT_MONRDY_MASK)
+#define I2C_INTSTAT_MONOV_MASK                   (0x20000U)
+#define I2C_INTSTAT_MONOV_SHIFT                  (17U)
+/*! MONOV - Monitor Overrun interrupt.
+ */
+#define I2C_INTSTAT_MONOV(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONOV_SHIFT)) & I2C_INTSTAT_MONOV_MASK)
+#define I2C_INTSTAT_MONIDLE_MASK                 (0x80000U)
+#define I2C_INTSTAT_MONIDLE_SHIFT                (19U)
+/*! MONIDLE - Monitor Idle interrupt.
+ */
+#define I2C_INTSTAT_MONIDLE(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONIDLE_SHIFT)) & I2C_INTSTAT_MONIDLE_MASK)
+#define I2C_INTSTAT_EVTTIMEOUT_MASK              (0x1000000U)
+#define I2C_INTSTAT_EVTTIMEOUT_SHIFT             (24U)
+/*! EVTTIMEOUT - Event time-out interrupt.
+ */
+#define I2C_INTSTAT_EVTTIMEOUT(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_EVTTIMEOUT_SHIFT)) & I2C_INTSTAT_EVTTIMEOUT_MASK)
+#define I2C_INTSTAT_SCLTIMEOUT_MASK              (0x2000000U)
+#define I2C_INTSTAT_SCLTIMEOUT_SHIFT             (25U)
+/*! SCLTIMEOUT - SCL time-out interrupt.
+ */
+#define I2C_INTSTAT_SCLTIMEOUT(x)                (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SCLTIMEOUT_SHIFT)) & I2C_INTSTAT_SCLTIMEOUT_MASK)
+/*! @} */
+
+/*! @name MSTCTL - Master control register. */
+/*! @{ */
+#define I2C_MSTCTL_MSTCONTINUE_MASK              (0x1U)
+#define I2C_MSTCTL_MSTCONTINUE_SHIFT             (0U)
+/*! MSTCONTINUE - Master Continue. This bit is write-only. 0: No effect. 1: Continue. Informs the
+ *    Master function to continue to the next operation. This must be done after writing transmit
+ *    data, reading received data, or other housekeeping related to the next bus operation.
+ */
+#define I2C_MSTCTL_MSTCONTINUE(x)                (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTCONTINUE_SHIFT)) & I2C_MSTCTL_MSTCONTINUE_MASK)
+#define I2C_MSTCTL_MSTSTART_MASK                 (0x2U)
+#define I2C_MSTCTL_MSTSTART_SHIFT                (1U)
+/*! MSTSTART - Master Start control. This bit is write-only. 0: No effect. 1. Start. A start will be
+ *    generated on the I2C bus at the next allowed time.
+ */
+#define I2C_MSTCTL_MSTSTART(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTART_SHIFT)) & I2C_MSTCTL_MSTSTART_MASK)
+#define I2C_MSTCTL_MSTSTOP_MASK                  (0x4U)
+#define I2C_MSTCTL_MSTSTOP_SHIFT                 (2U)
+/*! MSTSTOP - Master Stop control. This bit is write-only. 0: No effect. 1. Stop. A stop will be
+ *    generated on the I2C bus at the next allowed time, preceded by a NACK to the slave if the master
+ *    is receiving data from the salve (Master Receiver mode).
+ */
+#define I2C_MSTCTL_MSTSTOP(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTOP_SHIFT)) & I2C_MSTCTL_MSTSTOP_MASK)
+#define I2C_MSTCTL_MSTDMA_MASK                   (0x8U)
+#define I2C_MSTCTL_MSTDMA_SHIFT                  (3U)
+/*! MSTDMA - Master DMA enable. Data operations of the I2C can be performed with DMA. Protocol type
+ *    operations such as Start, address, Stop, and address match must always be done with software,
+ *    typically via an interrupt. Address acknowledgement must also be done by software except when
+ *    the I2C is configured to be HSCAPABLE (and address acknowledgement is handled entirely by
+ *    hardware) or when Automatic Operation is enabled. When a DMA data transfer is complete, MSTDMA
+ *    must be cleared prior to beginning the next operation, typically a Start or Stop.This bit is
+ *    read/write. 0: Disable. No DMA requests are generated for master operation. 1: Enable. A DMA
+ *    request is generated for I2C master data operations. When this I2C master is generating Acknowledge
+ *    bits in Master Receiver mode, the acknowledge is generated automatically.
+ */
+#define I2C_MSTCTL_MSTDMA(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTDMA_SHIFT)) & I2C_MSTCTL_MSTDMA_MASK)
+/*! @} */
+
+/*! @name MSTTIME - Master timing configuration. */
+/*! @{ */
+#define I2C_MSTTIME_MSTSCLLOW_MASK               (0x7U)
+#define I2C_MSTTIME_MSTSCLLOW_SHIFT              (0U)
+/*! MSTSCLLOW - Master SCL Low time. Specifies the minimum low time that will be asserted by this
+ *    master on SCL. Other devices on the bus (masters or slaves) could lengthen this time. This
+ *    corresponds to the parameter tLOW in the I2C bus specification. I2C bus specification parameters
+ *    tBUF and tSU;STA have the same values and are also controlled by MSTSCLLOW. The minimum SCL low
+ *    time is (MSTSCLLOW + 2) clocks of the I2C clock pre-divider.
+ */
+#define I2C_MSTTIME_MSTSCLLOW(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLLOW_SHIFT)) & I2C_MSTTIME_MSTSCLLOW_MASK)
+#define I2C_MSTTIME_MSTSCLHIGH_MASK              (0x70U)
+#define I2C_MSTTIME_MSTSCLHIGH_SHIFT             (4U)
+/*! MSTSCLHIGH - Master SCL High time. Specifies the minimum high time that will be asserted by this
+ *    master on SCL. Other masters in a multi-master system could shorten this time. This
+ *    corresponds to the parameter tHIGH in the I2C bus specification. I2C bus specification parameters
+ *    tSU;STO and tHD;STA have the same values and are also controlled by MSTSCLHIGH.
+ */
+#define I2C_MSTTIME_MSTSCLHIGH(x)                (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLHIGH_SHIFT)) & I2C_MSTTIME_MSTSCLHIGH_MASK)
+/*! @} */
+
+/*! @name MSTDAT - Combined Master receiver and transmitter data register. */
+/*! @{ */
+#define I2C_MSTDAT_DATA_MASK                     (0xFFU)
+#define I2C_MSTDAT_DATA_SHIFT                    (0U)
+/*! DATA - Master function data register. Read: read the most recently received data for the Master
+ *    function. Write: transmit data using the Master function.
+ */
+#define I2C_MSTDAT_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_MSTDAT_DATA_SHIFT)) & I2C_MSTDAT_DATA_MASK)
+/*! @} */
+
+/*! @name SLVCTL - Slave control register. */
+/*! @{ */
+#define I2C_SLVCTL_SLVCONTINUE_MASK              (0x1U)
+#define I2C_SLVCTL_SLVCONTINUE_SHIFT             (0U)
+/*! SLVCONTINUE - Slave Continue. 0: no effect 1: Continue. Informs the Slave function to continue
+ *    to the next operation, by clearing the SLVPENDING flag in the STAT register. This must be done
+ *    after writing transmit data, reading recevied data, or any other housekeeping related to the
+ *    next bus operation. Automatic Operation has different requirements. SLVCONTINUE should not be
+ *    set unless SLVPENDING=1.
+ */
+#define I2C_SLVCTL_SLVCONTINUE(x)                (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVCONTINUE_SHIFT)) & I2C_SLVCTL_SLVCONTINUE_MASK)
+#define I2C_SLVCTL_SLVNACK_MASK                  (0x2U)
+#define I2C_SLVCTL_SLVNACK_SHIFT                 (1U)
+/*! SLVNACK - Slave NACK. 0: No effect. 1: NACK. Causes the Slave function to NACK the master when
+ *    the slave is receiving data from the master (Slave Receiver mode).
+ */
+#define I2C_SLVCTL_SLVNACK(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVNACK_SHIFT)) & I2C_SLVCTL_SLVNACK_MASK)
+#define I2C_SLVCTL_SLVDMA_MASK                   (0x8U)
+#define I2C_SLVCTL_SLVDMA_SHIFT                  (3U)
+/*! SLVDMA - Slave DMA enable. 0: Slave DMA enable. 1: Enabled. DMA requests are issued for I2C
+ *    slave data transmission and reception.
+ */
+#define I2C_SLVCTL_SLVDMA(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVDMA_SHIFT)) & I2C_SLVCTL_SLVDMA_MASK)
+#define I2C_SLVCTL_AUTOACK_MASK                  (0x100U)
+#define I2C_SLVCTL_AUTOACK_SHIFT                 (8U)
+/*! AUTOACK - Automatic Acknowledge.When this bit is set, it will cause an I2C header which matches
+ *    SLVADR0 and the direction set by AUTOMATCHREAD to be ACKed immediately; this is used with DMA
+ *    to allow processing of the data without intervention. If this bit is clear and a header
+ *    matches SLVADR0, the behavior is controlled by AUTONACK in the SLVADR0 register: allowing NACK or
+ *    interrupt. 0: Normal, non-automatic operation. If AUTONACK = 0, an SlvPending interrupt is
+ *    generated when a matching address is received. If AUTONACK-1, receiver addresses are NACKed
+ *    (ignored). 1: A header with matching SLVADR0 and matching direction as set by AUTOMATCHREAD will be
+ *    ACKed immediately, allowing the master to move on to the data bytes. If the address matches
+ *    SLVADR0, but the direction does not match AUTOMATCHREAD, the behaviour will depend on the
+ *    AUTONACK bit in the SLVADR0 register: if AUTONACK is set, then it will be Nacked; else if AUTONACK is
+ *    cl;ear, then a SlvPending interrupt is geernated.
+ */
+#define I2C_SLVCTL_AUTOACK(x)                    (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_AUTOACK_SHIFT)) & I2C_SLVCTL_AUTOACK_MASK)
+#define I2C_SLVCTL_AUTOMATCHREAD_MASK            (0x200U)
+#define I2C_SLVCTL_AUTOMATCHREAD_SHIFT           (9U)
+/*! AUTOMATCHREAD - When AUTOACK is set, this bit controls whether it matches a read or write
+ *    request on the next header with an address matching SLVADR0. Since DMA needs to be configured to
+ *    match the transfer direction, the direction needs to be specified. This bit allows a direction to
+ *    be chosen for the next operation. 0: The expected next operation in Automatic Mode is an I2C
+ *    write. 1: The expected next operation in Automatic Mode is an I2C read.
+ */
+#define I2C_SLVCTL_AUTOMATCHREAD(x)              (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_AUTOMATCHREAD_SHIFT)) & I2C_SLVCTL_AUTOMATCHREAD_MASK)
+/*! @} */
+
+/*! @name SLVDAT - Combined Slave receiver and transmitter data register. */
+/*! @{ */
+#define I2C_SLVDAT_DATA_MASK                     (0xFFU)
+#define I2C_SLVDAT_DATA_SHIFT                    (0U)
+/*! DATA - Slave function data register. Read: read the most recently received data for the Slave
+ *    function. Write: transmit data using the Slave function.
+ */
+#define I2C_SLVDAT_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_SLVDAT_DATA_SHIFT)) & I2C_SLVDAT_DATA_MASK)
+/*! @} */
+
+/*! @name SLVADR - Slave address 0. */
+/*! @{ */
+#define I2C_SLVADR_SADISABLE_MASK                (0x1U)
+#define I2C_SLVADR_SADISABLE_SHIFT               (0U)
+/*! SADISABLE - Slave Address 0 Disable. 0: Slave Address 0 is enabled. 1: Slave Address 0 is ignored.
+ */
+#define I2C_SLVADR_SADISABLE(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SADISABLE_SHIFT)) & I2C_SLVADR_SADISABLE_MASK)
+#define I2C_SLVADR_SLVADR_MASK                   (0xFEU)
+#define I2C_SLVADR_SLVADR_SHIFT                  (1U)
+/*! SLVADR - Slave Address. Seven bit slave address that is compared to received addresses if
+ *    enabled. The compare can be affected by the setting of the SLVQUAL0 register.
+ */
+#define I2C_SLVADR_SLVADR(x)                     (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SLVADR_SHIFT)) & I2C_SLVADR_SLVADR_MASK)
+#define I2C_SLVADR_AUTONACK_MASK                 (0x8000U)
+#define I2C_SLVADR_AUTONACK_SHIFT                (15U)
+/*! AUTONACK - Automatic NACK operation. Used in conjunction with AUTOACK and AUTOMATCHREAD, allows
+ *    software to ignore I2C traffic while handling previous I2C data or other operations. 0: Normal
+ *    operation, matching I2C addresses are not ignored. 1: Automatic-only mode. If AUTOACK is not
+ *    set, all incoming I2C addresses are ignored.
+ */
+#define I2C_SLVADR_AUTONACK(x)                   (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_AUTONACK_SHIFT)) & I2C_SLVADR_AUTONACK_MASK)
+/*! @} */
+
+/* The count of I2C_SLVADR */
+#define I2C_SLVADR_COUNT                         (4U)
+
+/*! @name SLVQUAL0 - Slave Qualification for address 0. */
+/*! @{ */
+#define I2C_SLVQUAL0_QUALMODE0_MASK              (0x1U)
+#define I2C_SLVQUAL0_QUALMODE0_SHIFT             (0U)
+/*! QUALMODE0 - Qualify mode for slave address 0. 0: Mask. The SLVQUAL0 field is used as a logical
+ *    mask for matching address 0. 1: Extend. The SLVQAL0 field is used to extend address 0 matching
+ *    in a range of addresses.
+ */
+#define I2C_SLVQUAL0_QUALMODE0(x)                (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_QUALMODE0_SHIFT)) & I2C_SLVQUAL0_QUALMODE0_MASK)
+#define I2C_SLVQUAL0_SLVQUAL0_MASK               (0xFEU)
+#define I2C_SLVQUAL0_SLVQUAL0_SHIFT              (1U)
+/*! SLVQUAL0 - Slave address Qualifier for address 0. A value of 0 causes the address in SLVADR0 to
+ *    be used as-is, assuming that it is enabled. If QUALMODE0 = 0, any bit in this field which is
+ *    set to 1 will cause an automatic match of the corresponding bit of the received address when it
+ *    is compared to the SLVADR0 register. If QUALMODE0 = 1, an address range is matched for
+ *    address 0. This range extends from the value defined by SLVADR0 to the address defined by SLVQUAL0
+ *    (address matches when SLVADR0[7:1] received address SLVQUAL0[7:1]).
+ */
+#define I2C_SLVQUAL0_SLVQUAL0(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_SLVQUAL0_SHIFT)) & I2C_SLVQUAL0_SLVQUAL0_MASK)
+/*! @} */
+
+/*! @name MONRXDAT - Monitor receiver data register. */
+/*! @{ */
+#define I2C_MONRXDAT_MONRXDAT_MASK               (0xFFU)
+#define I2C_MONRXDAT_MONRXDAT_SHIFT              (0U)
+/*! MONRXDAT - Monitor function Receiver Data. This reflects every data byte that passes on the I2C pins.
+ */
+#define I2C_MONRXDAT_MONRXDAT(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRXDAT_SHIFT)) & I2C_MONRXDAT_MONRXDAT_MASK)
+#define I2C_MONRXDAT_MONSTART_MASK               (0x100U)
+#define I2C_MONRXDAT_MONSTART_SHIFT              (8U)
+/*! MONSTART - Monitor Received Start. 0: No start detected. The monitor function has not detected a
+ *    Start event on the I2C bus. 1: Start detected. The Monitor function has detected a Start
+ *    event on the I2C bus.
+ */
+#define I2C_MONRXDAT_MONSTART(x)                 (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONSTART_SHIFT)) & I2C_MONRXDAT_MONSTART_MASK)
+#define I2C_MONRXDAT_MONRESTART_MASK             (0x200U)
+#define I2C_MONRXDAT_MONRESTART_SHIFT            (9U)
+/*! MONRESTART - Monitor Received Repeated Start. 0: No repeated start detected. The Monitor
+ *    function has not detected a Repeated Start event on the I2C bus. 1: Repeate start detected. The
+ *    Monitor function has detected a Repeated Start event on the I2C bus.
+ */
+#define I2C_MONRXDAT_MONRESTART(x)               (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRESTART_SHIFT)) & I2C_MONRXDAT_MONRESTART_MASK)
+#define I2C_MONRXDAT_MONNACK_MASK                (0x400U)
+#define I2C_MONRXDAT_MONNACK_SHIFT               (10U)
+/*! MONNACK - Monitor Received NACK. 0: Acknowledged. The data currently being provided by the
+ *    Monitor function was acknowledged by at least one master or slave recevier. 1: Not Acknowledged.
+ *    The data currently being provided by the Monitor function was not acknowledged by any receiver.
+ */
+#define I2C_MONRXDAT_MONNACK(x)                  (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONNACK_SHIFT)) & I2C_MONRXDAT_MONNACK_MASK)
+/*! @} */
+
+/*! @name ID - I2C Module Identifier */
+/*! @{ */
+#define I2C_ID_APERTURE_MASK                     (0xFFU)
+#define I2C_ID_APERTURE_SHIFT                    (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define I2C_ID_APERTURE(x)                       (((uint32_t)(((uint32_t)(x)) << I2C_ID_APERTURE_SHIFT)) & I2C_ID_APERTURE_MASK)
+#define I2C_ID_MIN_REV_MASK                      (0xF00U)
+#define I2C_ID_MIN_REV_SHIFT                     (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define I2C_ID_MIN_REV(x)                        (((uint32_t)(((uint32_t)(x)) << I2C_ID_MIN_REV_SHIFT)) & I2C_ID_MIN_REV_MASK)
+#define I2C_ID_MAJ_REV_MASK                      (0xF000U)
+#define I2C_ID_MAJ_REV_SHIFT                     (12U)
+/*! MAJ_REV - Major revision i.e. there may be software incompatability between major revisions.
+ */
+#define I2C_ID_MAJ_REV(x)                        (((uint32_t)(((uint32_t)(x)) << I2C_ID_MAJ_REV_SHIFT)) & I2C_ID_MAJ_REV_MASK)
+#define I2C_ID_ID_MASK                           (0xFFFF0000U)
+#define I2C_ID_ID_SHIFT                          (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define I2C_ID_ID(x)                             (((uint32_t)(((uint32_t)(x)) << I2C_ID_ID_SHIFT)) & I2C_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group I2C_Register_Masks */
+
+
+/* I2C - Peripheral instance base addresses */
+/** Peripheral I2C0 base address */
+#define I2C0_BASE                                (0x40003000u)
+/** Peripheral I2C0 base pointer */
+#define I2C0                                     ((I2C_Type *)I2C0_BASE)
+/** Peripheral I2C1 base address */
+#define I2C1_BASE                                (0x40004000u)
+/** Peripheral I2C1 base pointer */
+#define I2C1                                     ((I2C_Type *)I2C1_BASE)
+/** Peripheral I2C2 base address */
+#define I2C2_BASE                                (0x40005000u)
+/** Peripheral I2C2 base pointer */
+#define I2C2                                     ((I2C_Type *)I2C2_BASE)
+/** Array initializer of I2C peripheral base addresses */
+#define I2C_BASE_ADDRS                           { I2C0_BASE, I2C1_BASE, I2C2_BASE }
+/** Array initializer of I2C peripheral base pointers */
+#define I2C_BASE_PTRS                            { I2C0, I2C1, I2C2 }
+/** Interrupt vectors for the I2C peripheral type */
+#define I2C_IRQS                                 { FLEXCOMM2_IRQn, FLEXCOMM3_IRQn, FLEXCOMM6_IRQn }
+
+/*!
+ * @}
+ */ /* end of group I2C_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- INPUTMUX Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup INPUTMUX_Peripheral_Access_Layer INPUTMUX Peripheral Access Layer
+ * @{
+ */
+
+/** INPUTMUX - Register Layout Typedef */
+typedef struct {
+       uint8_t RESERVED_0[192];
+  __IO uint32_t PINTSEL[8];                        /**< Pin interrupt select register, array offset: 0xC0, array step: 0x4 */
+  __IO uint32_t DMA_ITRIG_INMUX[19];               /**< Trigger select register for DMA channel. Configurable for each of the DMA channels., array offset: 0xE0, array step: 0x4 */
+       uint8_t RESERVED_1[52];
+  __IO uint32_t DMA_OTRIG_INMUX[4];                /**< DMA output trigger selection to become an input to the DMA trigger mux. Four selections can be made., array offset: 0x160, array step: 0x4 */
+       uint8_t RESERVED_2[16];
+  __IO uint32_t FREQMEAS_REF;                      /**< Selection for frequency measurement reference clock, offset: 0x180 */
+  __IO uint32_t FREQMEAS_TARGET;                   /**< Selection for frequency measurement target clock, offset: 0x184 */
+} INPUTMUX_Type;
+
+/* ----------------------------------------------------------------------------
+   -- INPUTMUX Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup INPUTMUX_Register_Masks INPUTMUX Register Masks
+ * @{
+ */
+
+/*! @name PINTSEL - Pin interrupt select register */
+/*! @{ */
+#define INPUTMUX_PINTSEL_INTPIN_MASK             (0x1FU)
+#define INPUTMUX_PINTSEL_INTPIN_SHIFT            (0U)
+/*! INTPIN - Pin number select for pin interrupt or pattern match engine input.
+ */
+#define INPUTMUX_PINTSEL_INTPIN(x)               (((uint32_t)(((uint32_t)(x)) << INPUTMUX_PINTSEL_INTPIN_SHIFT)) & INPUTMUX_PINTSEL_INTPIN_MASK)
+/*! @} */
+
+/* The count of INPUTMUX_PINTSEL */
+#define INPUTMUX_PINTSEL_COUNT                   (8U)
+
+/*! @name DMA_ITRIG_INMUX - Trigger select register for DMA channel. Configurable for each of the DMA channels. */
+/*! @{ */
+#define INPUTMUX_DMA_ITRIG_INMUX_INP_MASK        (0x1FU)
+#define INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT       (0U)
+/*! INP - Trigger input number (decimal value) for DMA channel n (n = 0 to 17). 0: ADC0 Sequence A
+ *    interrupt; 1: Reserved; 2: Timer CT32B0 Match 0; 3: Timer CT32B0 Match 1; 4: Timer CT32B1 Match
+ *    0; 5: Timer CT32B1 Match 1; 6: Pin interrupt 0; 7: Pin interrupt 1; 8: Pin interrupt 2; 9:
+ *    Pin interrupt 3; 10: AES RX; 11: AES TX; 12: Hash RX; 13: Hash TX; 14: DMA output trigger mux 0;
+ *    15: DMA output trigger mux 1; 16: DMA output trigger mux 2; 17: DMA output trigger mux 3; 18-
+ *    31: reserved.
+ */
+#define INPUTMUX_DMA_ITRIG_INMUX_INP(x)          (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_ITRIG_INMUX_INP_MASK)
+/*! @} */
+
+/* The count of INPUTMUX_DMA_ITRIG_INMUX */
+#define INPUTMUX_DMA_ITRIG_INMUX_COUNT           (19U)
+
+/*! @name DMA_OTRIG_INMUX - DMA output trigger selection to become an input to the DMA trigger mux. Four selections can be made. */
+/*! @{ */
+#define INPUTMUX_DMA_OTRIG_INMUX_INP_MASK        (0x1FU)
+#define INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT       (0U)
+/*! INP - DMA trigger output number (decimal value) for DMA channel n (n = 0 to 19).
+ */
+#define INPUTMUX_DMA_OTRIG_INMUX_INP(x)          (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_OTRIG_INMUX_INP_MASK)
+/*! @} */
+
+/* The count of INPUTMUX_DMA_OTRIG_INMUX */
+#define INPUTMUX_DMA_OTRIG_INMUX_COUNT           (4U)
+
+/*! @name FREQMEAS_REF - Selection for frequency measurement reference clock */
+/*! @{ */
+#define INPUTMUX_FREQMEAS_REF_CLKIN_MASK         (0xFU)
+#define INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT        (0U)
+/*! CLKIN - Clock source number (decimal value) for frequency measure function ref clock: 0: CLK_IN
+ *    (must be enabled in functional mux); 1: XTAL 32 MHz (must be enabled in clock_ctrl); 2: FRO 1
+ *    MHz (must be enabled in clock_ctrl); 3: 32 kHz oscillator (either FRO 32 KHz or XTAL 32 KHZ);
+ *    4: Main clock (divided); 5: PIO[4] (must be configured as GPIO); 6: PIO[20] (must be
+ *    configured as GPIO); 7: PIO[16] (must be configured as GPIO); 8: PIO[15] (must be configured as GPIO);
+ *    9 - 15: reserved.
+ */
+#define INPUTMUX_FREQMEAS_REF_CLKIN(x)           (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_REF_CLKIN_MASK)
+/*! @} */
+
+/*! @name FREQMEAS_TARGET - Selection for frequency measurement target clock */
+/*! @{ */
+#define INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK      (0xFU)
+#define INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT     (0U)
+/*! CLKIN - Clock source number (decimal value) for frequency measure function target clock: 0:
+ *    CLK_IN (must be enabled in functional mux); 1: XTAL 32 MHz (must be enabled in clock_ctrl); 2: FRO
+ *    1 MHz (must be enabled in clock_ctrl); 3: 32 kHz oscillator (either FRO 32 KHz or XTAL 32
+ *    KHZ); 4: Main clock (divided); 5: PIO[4] (must be configured as GPIO); 6: PIO[20] (must be
+ *    configured as GPIO); 7: PIO[16] (must be configured as GPIO); 8: PIO[15] (must be configured as
+ *    GPIO); 9 - 15: reserved.
+ */
+#define INPUTMUX_FREQMEAS_TARGET_CLKIN(x)        (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group INPUTMUX_Register_Masks */
+
+
+/* INPUTMUX - Peripheral instance base addresses */
+/** Peripheral INPUTMUX base address */
+#define INPUTMUX_BASE                            (0x4000E000u)
+/** Peripheral INPUTMUX base pointer */
+#define INPUTMUX                                 ((INPUTMUX_Type *)INPUTMUX_BASE)
+/** Array initializer of INPUTMUX peripheral base addresses */
+#define INPUTMUX_BASE_ADDRS                      { INPUTMUX_BASE }
+/** Array initializer of INPUTMUX peripheral base pointers */
+#define INPUTMUX_BASE_PTRS                       { INPUTMUX }
+
+/*!
+ * @}
+ */ /* end of group INPUTMUX_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- IOCON Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup IOCON_Peripheral_Access_Layer IOCON Peripheral Access Layer
+ * @{
+ */
+
+/** IOCON - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t PIO[1][22];                        /**< Configuration array for PIO0 to PIO21. PIO[10] and PIO[11] use a different IO cell type to the other PIO pins and so there are some differences in the bit field descriptions of the PIO register for these Ios. Reset values vary depending on whether the IO is configured with a pull-up or pull-down resistor as default. The value is also affected by the IO type. Reset value 0x180 for PIO 0,3,4,5,8,9,12,13,14,15,16,21. Reset value 0x198 for PIO 1,2,6,7,17,18,19,20. Reset value 0x188 for PIO 10,11., array offset: 0x0, array step: index*0x58, index2*0x4 */
+} IOCON_Type;
+
+/* ----------------------------------------------------------------------------
+   -- IOCON Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup IOCON_Register_Masks IOCON Register Masks
+ * @{
+ */
+
+/*! @name PIO - Configuration array for PIO0 to PIO21. PIO[10] and PIO[11] use a different IO cell type to the other PIO pins and so there are some differences in the bit field descriptions of the PIO register for these Ios. Reset values vary depending on whether the IO is configured with a pull-up or pull-down resistor as default. The value is also affected by the IO type. Reset value 0x180 for PIO 0,3,4,5,8,9,12,13,14,15,16,21. Reset value 0x198 for PIO 1,2,6,7,17,18,19,20. Reset value 0x188 for PIO 10,11. */
+/*! @{ */
+#define IOCON_PIO_FUNC_MASK                      (0x7U)
+#define IOCON_PIO_FUNC_SHIFT                     (0U)
+/*! FUNC - Select digital function assigned to this pin.
+ *  0b000..Alternative connection 0.
+ *  0b001..Alternative connection 1.
+ *  0b010..Alternative connection 2.
+ *  0b011..Alternative connection 3.
+ *  0b100..Alternative connection 4.
+ *  0b101..Alternative connection 5.
+ *  0b110..Alternative connection 6.
+ *  0b111..Alternative connection 7.
+ */
+#define IOCON_PIO_FUNC(x)                        (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FUNC_SHIFT)) & IOCON_PIO_FUNC_MASK)
+#define IOCON_PIO_EGP_MASK                       (0x8U)
+#define IOCON_PIO_EGP_SHIFT                      (3U)
+/*! EGP - GPIO Mode of IO Cell.
+ *  0b0..IIC mode.
+ *  0b1..GPIO mode.
+ */
+#define IOCON_PIO_EGP(x)                         (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_EGP_SHIFT)) & IOCON_PIO_EGP_MASK)
+#define IOCON_PIO_MODE_MASK                      (0x18U)
+#define IOCON_PIO_MODE_SHIFT                     (3U)
+/*! MODE - Select function mode (on-chip pull-up/pull-down resistor control). For MFIO type ONLY
+ *    (all PIOs except PIO10 & 11): 0x0 : Pull-up. Pull-up resistor enabled. 0x1 : Repeater mode (bus
+ *    keeper) 0x2 : Plain Input 0x3 : Pull-down. Pull-down resistor enabled. Note: When the register
+ *    is related to a general purpose MFIO type pad (that is all PIOs except PIO10 & 11) - Bit [3]
+ *    (of the register) is connected to EPD (enable pull-down) input of the MFIO pad. - Bit [4] (of
+ *    the register) is connected to EPUN (enable pull-up NOT) input of MFIO pad.
+ *  0b00..Pull-up. Pull-up resistor enabled.
+ *  0b01..Repeater. Repeater mode (bus keeper).
+ *  0b10..Inactive. Plain Input.
+ *  0b11..Pull-down. Pull-down resistor enabled.
+ */
+#define IOCON_PIO_MODE(x)                        (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_MODE_SHIFT)) & IOCON_PIO_MODE_MASK)
+#define IOCON_PIO_ECS_MASK                       (0x10U)
+#define IOCON_PIO_ECS_SHIFT                      (4U)
+/*! ECS - Pull-up current source enable when set. When IO is is IIC mode (EGP=0) and ECS is low, the
+ *    IO cell is an open drain cell.
+ *  0b0..Pull-up current source disabled.
+ *  0b1..Pull-up current source enabled.
+ */
+#define IOCON_PIO_ECS(x)                         (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_ECS_SHIFT)) & IOCON_PIO_ECS_MASK)
+#define IOCON_PIO_EHS_MASK                       (0x20U)
+#define IOCON_PIO_EHS_SHIFT                      (5U)
+/*! EHS - Speed selection. When IO is in GPIO mode set 1 for high speed GPIO, 0 for low speed GPIO.
+ *    For IIC mode, this bit has no effect and the IO is always in low speed.
+ *  0b0..low speed for GPIO mode or i2c mode.
+ *  0b1..High speed for GPIO mode.
+ */
+#define IOCON_PIO_EHS(x)                         (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_EHS_SHIFT)) & IOCON_PIO_EHS_MASK)
+#define IOCON_PIO_SLEW0_MASK                     (0x20U)
+#define IOCON_PIO_SLEW0_SHIFT                    (5U)
+/*! SLEW0 - This bit field is used in combination with SLEW1. The higher [SLEW1,SLEW0] the quicker the IO cell slew rate.
+ *  0b0..Driver slew0 rate is disabled.
+ *  0b1..Driver slew0 rate is enabled.
+ */
+#define IOCON_PIO_SLEW0(x)                       (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SLEW0_SHIFT)) & IOCON_PIO_SLEW0_MASK)
+#define IOCON_PIO_INVERT_MASK                    (0x40U)
+#define IOCON_PIO_INVERT_SHIFT                   (6U)
+/*! INVERT - Input Polarity.
+ *  0b0..Disabled. Input function is not inverted.
+ *  0b1..Enabled. Input function is inverted.
+ */
+#define IOCON_PIO_INVERT(x)                      (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_INVERT_SHIFT)) & IOCON_PIO_INVERT_MASK)
+#define IOCON_PIO_DIGIMODE_MASK                  (0x80U)
+#define IOCON_PIO_DIGIMODE_SHIFT                 (7U)
+/*! DIGIMODE - Select Analog/Digital Mode. 0 Analog mode. 1 Digital mode. When in analog mode, the
+ *    receiver path in the IO cell is disabled. In this mode, it is essential that the digital
+ *    function (e.g. GPIO) is not configured as an output. Otherwise it may conflict with analog stuff
+ *    (loopback of digital on analog input). In other words, the digital output is not automatically
+ *    disabled when the IO is in analog mode. As a consequence, it is not possible to disable the
+ *    receiver path when the IO is used for digital output purpose.
+ *  0b0..Analog mode, digital input is disabled.
+ *  0b1..Digital mode, digital input is enabled.
+ */
+#define IOCON_PIO_DIGIMODE(x)                    (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DIGIMODE_SHIFT)) & IOCON_PIO_DIGIMODE_MASK)
+#define IOCON_PIO_FILTEROFF_MASK                 (0x100U)
+#define IOCON_PIO_FILTEROFF_SHIFT                (8U)
+/*! FILTEROFF - Controls Input Glitch Filter.
+ *  0b0..Filter enabled. Noise pulses below approximately 1 ns are filtered out.
+ *  0b1..Filter disabled. No input filtering is done.
+ */
+#define IOCON_PIO_FILTEROFF(x)                   (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FILTEROFF_SHIFT)) & IOCON_PIO_FILTEROFF_MASK)
+#define IOCON_PIO_FSEL_MASK                      (0x200U)
+#define IOCON_PIO_FSEL_SHIFT                     (9U)
+/*! FSEL - Control Input Glitch Filter.
+ *  0b0..Noise pulses below approximately 50ns are filtered out.
+ *  0b1..Noise pulses below approximately 10 ns are filtered out. If IO is in GPIO mode this control bit is irrelevant, a 3 ns filter is used.
+ */
+#define IOCON_PIO_FSEL(x)                        (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FSEL_SHIFT)) & IOCON_PIO_FSEL_MASK)
+#define IOCON_PIO_SLEW1_MASK                     (0x200U)
+#define IOCON_PIO_SLEW1_SHIFT                    (9U)
+/*! SLEW1 - Driver Slew Rate. This bit is used in combination with SLEW0. The higher [SLEW1,SLEW0], the quicker the slew rate.
+ *  0b0..Driver slew1 rate is disabled.
+ *  0b1..Driver slew1 rate is enabled.
+ */
+#define IOCON_PIO_SLEW1(x)                       (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SLEW1_SHIFT)) & IOCON_PIO_SLEW1_MASK)
+#define IOCON_PIO_OD_MASK                        (0x400U)
+#define IOCON_PIO_OD_SHIFT                       (10U)
+/*! OD - Controls open-drain mode.
+ *  0b0..Normal. Normal push-pull output
+ *  0b1..Open-drain. Simulated open-drain output (high drive disabled).
+ */
+#define IOCON_PIO_OD(x)                          (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_OD_SHIFT)) & IOCON_PIO_OD_MASK)
+#define IOCON_PIO_SSEL_MASK                      (0x800U)
+#define IOCON_PIO_SSEL_SHIFT                     (11U)
+/*! SSEL - IO Clamping Function
+ *  0b0..This bit controls the IO clamping function is disabled.
+ *  0b1..This bit controls the IO clamping function is enabled.
+ */
+#define IOCON_PIO_SSEL(x)                        (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SSEL_SHIFT)) & IOCON_PIO_SSEL_MASK)
+#define IOCON_PIO_IO_CLAMP_MASK                  (0x1000U)
+#define IOCON_PIO_IO_CLAMP_SHIFT                 (12U)
+/*! IO_CLAMP - Assert to freeze the IO. Also needs SYSCON:RETENTIONCTRL set as well. Useful in power
+ *    down mode. This mode is held through power down cycle. Before releasing this mode on a
+ *    wake-up, ensure the IO is set to the required direction and value using GPIO DIR and PIN registers.
+ *  0b0..IO_CLAMP is disabled.
+ *  0b1..IO_CLAMP is enabled.
+ */
+#define IOCON_PIO_IO_CLAMP(x)                    (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_IO_CLAMP_SHIFT)) & IOCON_PIO_IO_CLAMP_MASK)
+/*! @} */
+
+/* The count of IOCON_PIO */
+#define IOCON_PIO_COUNT                          (1U)
+
+/* The count of IOCON_PIO */
+#define IOCON_PIO_COUNT2                         (22U)
+
+
+/*!
+ * @}
+ */ /* end of group IOCON_Register_Masks */
+
+
+/* IOCON - Peripheral instance base addresses */
+/** Peripheral IOCON base address */
+#define IOCON_BASE                               (0x4000F000u)
+/** Peripheral IOCON base pointer */
+#define IOCON                                    ((IOCON_Type *)IOCON_BASE)
+/** Array initializer of IOCON peripheral base addresses */
+#define IOCON_BASE_ADDRS                         { IOCON_BASE }
+/** Array initializer of IOCON peripheral base pointers */
+#define IOCON_BASE_PTRS                          { IOCON }
+
+/*!
+ * @}
+ */ /* end of group IOCON_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- ISO7816 Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ISO7816_Peripheral_Access_Layer ISO7816 Peripheral Access Layer
+ * @{
+ */
+
+/** ISO7816 - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t SSR;                               /**< Slot Select Register, offset: 0x0 */
+  __IO uint32_t PDR1_LSB;                          /**< Programmable Divider Register (LSB) slot 1. Least significant byte of a 16-bit counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock, this defines the ETU. The minimum acceptable value is 0001 0000b., offset: 0x4 */
+  __IO uint32_t PDR1_MSB;                          /**< Programmable Divider Register (MSB) slot 1. Most significant byte of a 16-bit counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock, this defines the ETU, offset: 0x8 */
+  __IO uint32_t FCR;                               /**< FIFO Control Register, offset: 0xC */
+  __IO uint32_t GTR1;                              /**< Guard Time Register slot 1. Value used by the Contact UART notably in transmission mode. The Contact UART will wait this number of ETUs before transmitting the character. In protocol T=1, gtr = FFh means operation at 11 ETUs. In protocol T=0, gtr = FFh means operation at 12 ETUs., offset: 0x10 */
+  __IO uint32_t UCR11;                             /**< UART Configuration Register 1 slot 1, offset: 0x14 */
+  __IO uint32_t UCR21;                             /**< UART Configuration Register 2 slot 1, offset: 0x18 */
+  __IO uint32_t CCR1;                              /**< Clock Configuration Register slot 1, offset: 0x1C */
+  __IO uint32_t PCR;                               /**< Power Control Register, offset: 0x20 */
+  __IO uint32_t ECR;                               /**< Early answer Counter register, offset: 0x24 */
+  __IO uint32_t MCRL_LSB;                          /**< Mute card Counter RST Low register (LSB), offset: 0x28 */
+  __IO uint32_t MCRL_MSB;                          /**< Mute card Counter RST Low register (MSB), offset: 0x2C */
+  __IO uint32_t MCRH_LSB;                          /**< Mute card Counter RST High register (LSB), offset: 0x30 */
+  __IO uint32_t MCRH_MSB;                          /**< Mute card Counter RST High register (MSB), offset: 0x34 */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t URR_UTR;                           /**< UART Receive Register / UART Transmit Register, offset: 0x3C */
+       uint8_t RESERVED_1[12];
+  __O  uint32_t TOR1;                              /**< Time-Out Register 1, offset: 0x4C */
+  __O  uint32_t TOR2;                              /**< Time-Out Register 2, offset: 0x50 */
+  __O  uint32_t TOR3;                              /**< Time-Out Register 3, offset: 0x54 */
+  __IO uint32_t TOC;                               /**< Time-Out Configuration register, offset: 0x58 */
+  __I  uint32_t FSR;                               /**< FIFO Status Register, offset: 0x5C */
+  __I  uint32_t MSR;                               /**< Mixed Status Register, offset: 0x60 */
+  __I  uint32_t USR1;                              /**< UART Status Register 1, offset: 0x64 */
+  __I  uint32_t USR2;                              /**< UART Status Register 2, offset: 0x68 */
+} ISO7816_Type;
+
+/* ----------------------------------------------------------------------------
+   -- ISO7816 Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup ISO7816_Register_Masks ISO7816 Register Masks
+ * @{
+ */
+
+/*! @name SSR - Slot Select Register */
+/*! @{ */
+#define ISO7816_SSR_SOFTRESETN_MASK              (0x1U)
+#define ISO7816_SSR_SOFTRESETN_SHIFT             (0U)
+/*! SOFTRESETN - When set to logic 0 this bit resets the whole Contact UART (software reset), sets
+ *    to logic 1 automatically by hardware after after one clock cycle if slot 1 is not activated
+ *    else after one clock cycle after slot 1 has been automatically deactivated. Software should check
+ *    soft reset is finished by reading SSR register before any further action.
+ */
+#define ISO7816_SSR_SOFTRESETN(x)                (((uint32_t)(((uint32_t)(x)) << ISO7816_SSR_SOFTRESETN_SHIFT)) & ISO7816_SSR_SOFTRESETN_MASK)
+#define ISO7816_SSR_SEQ_EN_MASK                  (0x2U)
+#define ISO7816_SSR_SEQ_EN_SHIFT                 (1U)
+/*! SEQ_EN - Set this bit to enable the sequencer. If this field is 0b, the sequencer will not respond to the Start control bit.
+ */
+#define ISO7816_SSR_SEQ_EN(x)                    (((uint32_t)(((uint32_t)(x)) << ISO7816_SSR_SEQ_EN_SHIFT)) & ISO7816_SSR_SEQ_EN_MASK)
+/*! @} */
+
+/*! @name PDR1_LSB - Programmable Divider Register (LSB) slot 1. Least significant byte of a 16-bit counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock, this defines the ETU. The minimum acceptable value is 0001 0000b. */
+/*! @{ */
+#define ISO7816_PDR1_LSB_PDR1_LSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_PDR1_LSB_PDR1_LSB_SHIFT          (0U)
+/*! PDR1_LSB - Programmable Divider Register (LSB) slot 1. Least significant byte of a 16-bit
+ *    counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock,
+ *    this defines the ETU. The minimum acceptable value is 0001 0000b.
+ */
+#define ISO7816_PDR1_LSB_PDR1_LSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_PDR1_LSB_PDR1_LSB_SHIFT)) & ISO7816_PDR1_LSB_PDR1_LSB_MASK)
+/*! @} */
+
+/*! @name PDR1_MSB - Programmable Divider Register (MSB) slot 1. Most significant byte of a 16-bit counter defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock, this defines the ETU */
+/*! @{ */
+#define ISO7816_PDR1_MSB_PDR1_MSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_PDR1_MSB_PDR1_MSB_SHIFT          (0U)
+/*! PDR1_MSB - Programmable Divider Register (MSB) slot 1. Most significant byte of a 16-bit counter
+ *    defining the ETU. The ETU counter counts a number of cycles of the Contact Interface clock,
+ *    this defines the ETU
+ */
+#define ISO7816_PDR1_MSB_PDR1_MSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_PDR1_MSB_PDR1_MSB_SHIFT)) & ISO7816_PDR1_MSB_PDR1_MSB_MASK)
+/*! @} */
+
+/*! @name FCR - FIFO Control Register */
+/*! @{ */
+#define ISO7816_FCR_FTC_MASK                     (0x1FU)
+#define ISO7816_FCR_FTC_SHIFT                    (0U)
+/*! FTC - FIFO Threshold Configuration: Define the number of received or transmitted characters in
+ *    the FIFO triggering the ft bit in USR1. The FIFO depth is 32 bytes. In reception mode, it
+ *    enables to know that a number equals to ftc(4:0) + 1 bytes have been received. In transmission
+ *    mode, ftc(4:0) equals to the number of remaining bytes into the FIFO. Be careful: in reception
+ *    mode 00000 = length 1, and in transmission mode 00000 = length 0.
+ */
+#define ISO7816_FCR_FTC(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_FCR_FTC_SHIFT)) & ISO7816_FCR_FTC_MASK)
+#define ISO7816_FCR_PEC_MASK                     (0xE0U)
+#define ISO7816_FCR_PEC_SHIFT                    (5U)
+/*! PEC - Parity Error Count [For protocol T = 0] Set the number of allowed repetitions in reception
+ *    or transmission mode before setting pe in ct_usr1_reg. The value 000 indicates that, if only
+ *    one parity error has occurred, bit pe is set at logic 1; the value 111 indicates that bit pe
+ *    will be set at logic 1 after 8 parity errors. If a correct character is received before the
+ *    programmed error number is reached, the error counter will be reset. If the programmed number of
+ *    allowed parity errors is reached, bit pe in register ct_usr1_reg will be set at logic 1. If a
+ *    transmitted character has been naked by the card, then the Contact UART will automatically
+ *    retransmit it up to a number of times equal to the value programmed in bits PEC(2:0); the
+ *    character will be resent at 15 ETU. If a transmitted character is considered as correct by the card
+ *    after having been naked a number of times less than the value programmed in bits PEC(2:0) +1,
+ *    the error counter will be reset. If a transmitted has been naked by the card a number of times
+ *    equal to the value programmed in bits PEC(2:0) +1, the transmission stops and bit pe in
+ *    register ct_usr1_reg is set at logic 1. The firmware is supposed to deactivate the card. If not, the
+ *    firmware has the possibility to pursue the transmission. By reading the number of bytes
+ *    present into the FIFO (ffl bits), it can determine which character has been naked PEC +1 times by
+ *    the card. It will then flush the FIFO (FIFO flush bit). The next step consits in unlocking the
+ *    transmission using dispe bit. By writing this bit at logic level one (and then at logic level
+ *    zero if the firmware still wants to check parity errors), the transmission is unlocked. The
+ *    firmware can now write bytes into the FIFO. In transmission mode, if bits PEC(2:0) are at logic
+ *    0, then the automatic retransmission is invalidated. There is no retransmission; the
+ *    transmission continues with the next character sent at 13 ETU. [For protocol T = 1]: The error counter
+ *    has no action: bit pe is set at logic 1 at the first wrong received character.
+ */
+#define ISO7816_FCR_PEC(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_FCR_PEC_SHIFT)) & ISO7816_FCR_PEC_MASK)
+/*! @} */
+
+/*! @name GTR1 - Guard Time Register slot 1. Value used by the Contact UART notably in transmission mode. The Contact UART will wait this number of ETUs before transmitting the character. In protocol T=1, gtr = FFh means operation at 11 ETUs. In protocol T=0, gtr = FFh means operation at 12 ETUs. */
+/*! @{ */
+#define ISO7816_GTR1_GTR1_MASK                   (0xFFFFFFFFU)
+#define ISO7816_GTR1_GTR1_SHIFT                  (0U)
+/*! GTR1 - Guard Time Register slot 1. Value used by the Contact UART notably in transmission mode.
+ *    The Contact UART will wait this number of ETUs before transmitting the character. In protocol
+ *    T=1, gtr = FFh means operation at 11 ETUs. In protocol T=0, gtr = FFh means operation at 12
+ *    ETUs.
+ */
+#define ISO7816_GTR1_GTR1(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_GTR1_GTR1_SHIFT)) & ISO7816_GTR1_GTR1_MASK)
+/*! @} */
+
+/*! @name UCR11 - UART Configuration Register 1 slot 1 */
+/*! @{ */
+#define ISO7816_UCR11_CONV_MASK                  (0x1U)
+#define ISO7816_UCR11_CONV_SHIFT                 (0U)
+/*! CONV - CONVention: Bit CONV is set to logic 1 if the convention is direct. Bit CONV is either
+ *    automatically written by hardware according to the convention detected during ATR, or by
+ *    software if the bit AUTOCONV in register ct_ucr1_reg is set to logic 1.
+ */
+#define ISO7816_UCR11_CONV(x)                    (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_CONV_SHIFT)) & ISO7816_UCR11_CONV_MASK)
+#define ISO7816_UCR11_LCT_MASK                   (0x2U)
+#define ISO7816_UCR11_LCT_SHIFT                  (1U)
+/*! LCT - Last Character to Transmit: Bit LCT is set to logic 1 by software before writing the last
+ *    character to be transmitted in register ct_utr_reg. It allows automatic change to reception
+ *    mode. It is reset to logic 0 by hardware at the end of a successful transmission after 11.75
+ *    ETUs in protocol T = 0 and after 10.75 ETUs in protocol T = 1. When bit LCT is being reset to
+ *    logic 0, bit T/R is also reset to logic 0 and the UART is ready to receive a character. LCT bit
+ *    can be set to logic 1 by software not only when writing the last character to be transmitted
+ *    but also during the transmission or even at the beginning of the transmission. It will be taken
+ *    into account when the FIFO becomes empty, which implies for the software to be able to
+ *    regularly re-load the FIFO when transmitting more than 32 bytes to ensure there is at least one byte
+ *    into the FIFO as long as the transmission is not finished. Else, a switch to reception mode
+ *    will prematurely occur before having transmitted all the bytes.
+ */
+#define ISO7816_UCR11_LCT(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_LCT_SHIFT)) & ISO7816_UCR11_LCT_MASK)
+#define ISO7816_UCR11_T_R_MASK                   (0x4U)
+#define ISO7816_UCR11_T_R_SHIFT                  (2U)
+/*! T_R - Transmit/Receive: Defines the mode: logic 1 means transmission and logic 0 reception. Bit
+ *    T/R is set by software for transmission mode. Bit T/R is automatically reset to logic 0 by
+ *    hardware, if bit LCT has been used before transmitting the last character. Note that when
+ *    switching from/to reception to/from transmission mode, the FIFO is flushed. Any remaining bytes are
+ *    lost.
+ */
+#define ISO7816_UCR11_T_R(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_T_R_SHIFT)) & ISO7816_UCR11_T_R_MASK)
+#define ISO7816_UCR11_PROT_MASK                  (0x8U)
+#define ISO7816_UCR11_PROT_SHIFT                 (3U)
+/*! PROT - PROTocol: Selects the protocol: logic 1 means T=1 and logic 0 T=0.
+ */
+#define ISO7816_UCR11_PROT(x)                    (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_PROT_SHIFT)) & ISO7816_UCR11_PROT_MASK)
+#define ISO7816_UCR11_FC_MASK                    (0x10U)
+#define ISO7816_UCR11_FC_SHIFT                   (4U)
+/*! FC - Described in a separated document.
+ */
+#define ISO7816_UCR11_FC(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_FC_SHIFT)) & ISO7816_UCR11_FC_MASK)
+#define ISO7816_UCR11_FIP_MASK                   (0x20U)
+#define ISO7816_UCR11_FIP_SHIFT                  (5U)
+/*! FIP - Force Inverse Parity: If bit FIP is set to logic 1, the Contact UART will NAK a correctly
+ *    received character, and will transmit characters with wrong parity bits.
+ */
+#define ISO7816_UCR11_FIP(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR11_FIP_SHIFT)) & ISO7816_UCR11_FIP_MASK)
+/*! @} */
+
+/*! @name UCR21 - UART Configuration Register 2 slot 1 */
+/*! @{ */
+#define ISO7816_UCR21_AUTOCONVN_MASK             (0x1U)
+#define ISO7816_UCR21_AUTOCONVN_SHIFT            (0U)
+/*! AUTOCONVN - AUTOmatically detected CONVention: If bit AUTOCONV = 1, then the convention is set
+ *    by software using bit CONV in register ct_ucr1_reg. If the bit is reset to logic 0, then the
+ *    configuration is automatically detected on the first received character and the bit
+ *    automatically set after convention detection.
+ */
+#define ISO7816_UCR21_AUTOCONVN(x)               (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_AUTOCONVN_SHIFT)) & ISO7816_UCR21_AUTOCONVN_MASK)
+#define ISO7816_UCR21_MANBGT_MASK                (0x2U)
+#define ISO7816_UCR21_MANBGT_SHIFT               (1U)
+/*! MANBGT - MANual BGT: When set to logic 1, BGT is managed by software, else by hardware.
+ */
+#define ISO7816_UCR21_MANBGT(x)                  (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_MANBGT_SHIFT)) & ISO7816_UCR21_MANBGT_MASK)
+#define ISO7816_UCR21_DISFT_MASK                 (0x4U)
+#define ISO7816_UCR21_DISFT_SHIFT                (2U)
+/*! DISFT - DISable Fifo Threshold interrupt bit: When set to logic 1 the bit ft in register
+ *    ct_usr1_reg will not generate interrupt.
+ */
+#define ISO7816_UCR21_DISFT(x)                   (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_DISFT_SHIFT)) & ISO7816_UCR21_DISFT_MASK)
+#define ISO7816_UCR21_DISPE_MASK                 (0x8U)
+#define ISO7816_UCR21_DISPE_SHIFT                (3U)
+/*! DISPE - DISable Parity Error interrupt bit: When set to logic 1, the parity is not checked in
+ *    both reception and transmission modes, the bit pe in register ct_usr1_reg will not generate
+ *    interrupt.
+ */
+#define ISO7816_UCR21_DISPE(x)                   (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_DISPE_SHIFT)) & ISO7816_UCR21_DISPE_MASK)
+#define ISO7816_UCR21_DISATRCOUNTER_MASK         (0x10U)
+#define ISO7816_UCR21_DISATRCOUNTER_SHIFT        (4U)
+/*! DISATRCOUNTER - DISable ATR counter: [For Slot 1 only] When set to logic 1 the bits EARLY and
+ *    MUTE in register ct_usr1_reg will not generate interrupt. This bit should be set before
+ *    activating.
+ */
+#define ISO7816_UCR21_DISATRCOUNTER(x)           (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_DISATRCOUNTER_SHIFT)) & ISO7816_UCR21_DISATRCOUNTER_MASK)
+#define ISO7816_UCR21_FIFOFLUSH_MASK             (0x40U)
+#define ISO7816_UCR21_FIFOFLUSH_SHIFT            (6U)
+/*! FIFOFLUSH - FIFO flush: When set to logic 1, the FIFO is flushed whatever the mode (reception or
+ *    transmission) is. It can be used before any reception or transmission of characters but not
+ *    while receiving or transmitting a character. It is reset to logic 0 by hardware after one
+ *    clk_ip cycle.
+ */
+#define ISO7816_UCR21_FIFOFLUSH(x)               (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_FIFOFLUSH_SHIFT)) & ISO7816_UCR21_FIFOFLUSH_MASK)
+#define ISO7816_UCR21_WRDACC_MASK                (0x80U)
+#define ISO7816_UCR21_WRDACC_SHIFT               (7U)
+/*! WRDACC - FIFO WoRD ACCess: When set to logic 1, the FIFO supports word (4 bytes) access (read
+ *    and write), access failure is indicated by bit wrdaccerr in register USR2. When set to logic 0,
+ *    the FIFO supports byte access (read and write).
+ */
+#define ISO7816_UCR21_WRDACC(x)                  (((uint32_t)(((uint32_t)(x)) << ISO7816_UCR21_WRDACC_SHIFT)) & ISO7816_UCR21_WRDACC_MASK)
+/*! @} */
+
+/*! @name CCR1 - Clock Configuration Register slot 1 */
+/*! @{ */
+#define ISO7816_CCR1_ACC_MASK                    (0x7U)
+#define ISO7816_CCR1_ACC_SHIFT                   (0U)
+/*! ACC - Asynchronous Card Clock: Defines the card clock frequency: 000: card clock frequency =
+ *    fclk_ip; 001: card clock frequency = fclk_ip /2; 010: card clock frequency = fclk_ip /3; 011:
+ *    card clock frequency = fclk_ip /4; 100: card clock frequency = fclk_ip /5; 101: card clock
+ *    frequency = fclk_ip /6; 110: card clock frequency = fclk_ip /8; 111: card clock frequency = fclk_ip
+ *    /16. All frequency changes are synchronous, thus ensuring that no spikes or unwanted pulse
+ *    widths occur during changes. In conjunction with registers ct_etucr_lsb_reg and ct_etucr_msb_reg,
+ *    the bits ACC2, ACC1 and ACC0 defines the baudrate used by the Contact UART.
+ */
+#define ISO7816_CCR1_ACC(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_CCR1_ACC_SHIFT)) & ISO7816_CCR1_ACC_MASK)
+#define ISO7816_CCR1_SAN_MASK                    (0x8U)
+#define ISO7816_CCR1_SAN_SHIFT                   (3U)
+/*! SAN - Synchronous/Asynchronous Card: [For Slot 1]: When set to logic 1, the Contact UART
+ *    supports synchronous card. The Contact UART is then bypassed, only bit 0 of registers ct_urr_reg and
+ *    ct_utr_reg is connected to pin I/O. In this case, the card clock is controlled by bit SHL and
+ *    RST card is controlled by bit RSTIN in register ct_pcr_reg. When set to logic 0, the Contact
+ *    UART supports asynchronous card. Dynamic change (while activated) is not supported. The choice
+ *    should be done before activating the card. [For Slot AUX]: When set to logic 1, the Contact
+ *    UART supports synchronous card. The Contact UART is then bypassed, only bit 0 of registers
+ *    ct_urr_reg and ct_utr_reg is connected to pin I/O. In this case, the card clock is controlled by
+ *    bit SHL. When set to logic 0, the Contact UART supports asynchronous card. Dynamic change (while
+ *    CLKAUXen = 1) is not supported. The choice should be done before enabling CLKAUX clock.
+ */
+#define ISO7816_CCR1_SAN(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_CCR1_SAN_SHIFT)) & ISO7816_CCR1_SAN_MASK)
+#define ISO7816_CCR1_CST_MASK                    (0x10U)
+#define ISO7816_CCR1_CST_SHIFT                   (4U)
+/*! CST - Clock STop: [For Slot 1]: In the case of an asynchronous card, bit CST defines whether the
+ *    clock to the card is stopped or not; if bit CST is reset to logic 0, then the clock is
+ *    determined by bits ACC0, ACC1 and ACC2. [For Slot AUX]+I40: This bit is not available for the
+ *    auxiliary slot (ct_ccr2_reg) since clock stop feature is supported using CLKAUXen bit in ct_ssr_reg
+ *    register.
+ */
+#define ISO7816_CCR1_CST(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_CCR1_CST_SHIFT)) & ISO7816_CCR1_CST_MASK)
+#define ISO7816_CCR1_SHL_MASK                    (0x20U)
+#define ISO7816_CCR1_SHL_SHIFT                   (5U)
+/*! SHL - Stop HIGH or LOW: - Slot 1: If bits SAN = 0 and CST = 1, then the clock is stopped at LOW
+ *    level. If bit SHL = 0, and at HIGH level if bit SHL = 1. I+I10f bit SAN = 1, then contact CLK
+ *    is the copy of the value of bit SHL.
+ */
+#define ISO7816_CCR1_SHL(x)                      (((uint32_t)(((uint32_t)(x)) << ISO7816_CCR1_SHL_SHIFT)) & ISO7816_CCR1_SHL_MASK)
+/*! @} */
+
+/*! @name PCR - Power Control Register */
+/*! @{ */
+#define ISO7816_PCR_PCR_MASK                     (0xFFFFFFFFU)
+#define ISO7816_PCR_PCR_SHIFT                    (0U)
+/*! PCR - Power Control Register
+ */
+#define ISO7816_PCR_PCR(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_PCR_PCR_SHIFT)) & ISO7816_PCR_PCR_MASK)
+/*! @} */
+
+/*! @name ECR - Early answer Counter register */
+/*! @{ */
+#define ISO7816_ECR_ECR_MASK                     (0xFFFFFFFFU)
+#define ISO7816_ECR_ECR_SHIFT                    (0U)
+/*! ECR - Early answer Counter register
+ */
+#define ISO7816_ECR_ECR(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_ECR_ECR_SHIFT)) & ISO7816_ECR_ECR_MASK)
+/*! @} */
+
+/*! @name MCRL_LSB - Mute card Counter RST Low register (LSB) */
+/*! @{ */
+#define ISO7816_MCRL_LSB_MCRL_LSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_MCRL_LSB_MCRL_LSB_SHIFT          (0U)
+/*! MCRL_LSB - Mute card Counter RST Low register (LSB)
+ */
+#define ISO7816_MCRL_LSB_MCRL_LSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_MCRL_LSB_MCRL_LSB_SHIFT)) & ISO7816_MCRL_LSB_MCRL_LSB_MASK)
+/*! @} */
+
+/*! @name MCRL_MSB - Mute card Counter RST Low register (MSB) */
+/*! @{ */
+#define ISO7816_MCRL_MSB_MCRL_MSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_MCRL_MSB_MCRL_MSB_SHIFT          (0U)
+/*! MCRL_MSB - Mute card Counter RST Low register (MSB)
+ */
+#define ISO7816_MCRL_MSB_MCRL_MSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_MCRL_MSB_MCRL_MSB_SHIFT)) & ISO7816_MCRL_MSB_MCRL_MSB_MASK)
+/*! @} */
+
+/*! @name MCRH_LSB - Mute card Counter RST High register (LSB) */
+/*! @{ */
+#define ISO7816_MCRH_LSB_MCRH_LSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_MCRH_LSB_MCRH_LSB_SHIFT          (0U)
+/*! MCRH_LSB - Mute card Counter RST High register (LSB)
+ */
+#define ISO7816_MCRH_LSB_MCRH_LSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_MCRH_LSB_MCRH_LSB_SHIFT)) & ISO7816_MCRH_LSB_MCRH_LSB_MASK)
+/*! @} */
+
+/*! @name MCRH_MSB - Mute card Counter RST High register (MSB) */
+/*! @{ */
+#define ISO7816_MCRH_MSB_MCRH_MSB_MASK           (0xFFFFFFFFU)
+#define ISO7816_MCRH_MSB_MCRH_MSB_SHIFT          (0U)
+/*! MCRH_MSB - Mute card Counter RST High register (MSB)
+ */
+#define ISO7816_MCRH_MSB_MCRH_MSB(x)             (((uint32_t)(((uint32_t)(x)) << ISO7816_MCRH_MSB_MCRH_MSB_SHIFT)) & ISO7816_MCRH_MSB_MCRH_MSB_MASK)
+/*! @} */
+
+/*! @name URR_UTR - UART Receive Register / UART Transmit Register */
+/*! @{ */
+#define ISO7816_URR_UTR_URR_UTR_MASK             (0xFFFFFFFFU)
+#define ISO7816_URR_UTR_URR_UTR_SHIFT            (0U)
+/*! URR_UTR - UART Receive Register / UART Transmit Register
+ */
+#define ISO7816_URR_UTR_URR_UTR(x)               (((uint32_t)(((uint32_t)(x)) << ISO7816_URR_UTR_URR_UTR_SHIFT)) & ISO7816_URR_UTR_URR_UTR_MASK)
+/*! @} */
+
+/*! @name TOR1 - Time-Out Register 1 */
+/*! @{ */
+#define ISO7816_TOR1_TOR1_MASK                   (0xFFFFFFFFU)
+#define ISO7816_TOR1_TOR1_SHIFT                  (0U)
+/*! TOR1 - Time-Out Register 1
+ */
+#define ISO7816_TOR1_TOR1(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_TOR1_TOR1_SHIFT)) & ISO7816_TOR1_TOR1_MASK)
+/*! @} */
+
+/*! @name TOR2 - Time-Out Register 2 */
+/*! @{ */
+#define ISO7816_TOR2_TOR2_MASK                   (0xFFFFFFFFU)
+#define ISO7816_TOR2_TOR2_SHIFT                  (0U)
+/*! TOR2 - Time-Out Register 2
+ */
+#define ISO7816_TOR2_TOR2(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_TOR2_TOR2_SHIFT)) & ISO7816_TOR2_TOR2_MASK)
+/*! @} */
+
+/*! @name TOR3 - Time-Out Register 3 */
+/*! @{ */
+#define ISO7816_TOR3_TOR3_MASK                   (0xFFFFFFFFU)
+#define ISO7816_TOR3_TOR3_SHIFT                  (0U)
+/*! TOR3 - Time-Out Register 3
+ */
+#define ISO7816_TOR3_TOR3(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_TOR3_TOR3_SHIFT)) & ISO7816_TOR3_TOR3_MASK)
+/*! @} */
+
+/*! @name TOC - Time-Out Configuration register */
+/*! @{ */
+#define ISO7816_TOC_TOC_MASK                     (0xFFFFFFFFU)
+#define ISO7816_TOC_TOC_SHIFT                    (0U)
+/*! TOC - Time-Out Configuration register
+ */
+#define ISO7816_TOC_TOC(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_TOC_TOC_SHIFT)) & ISO7816_TOC_TOC_MASK)
+/*! @} */
+
+/*! @name FSR - FIFO Status Register */
+/*! @{ */
+#define ISO7816_FSR_FSR_MASK                     (0xFFFFFFFFU)
+#define ISO7816_FSR_FSR_SHIFT                    (0U)
+/*! FSR - FIFO Status Register
+ */
+#define ISO7816_FSR_FSR(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_FSR_FSR_SHIFT)) & ISO7816_FSR_FSR_MASK)
+/*! @} */
+
+/*! @name MSR - Mixed Status Register */
+/*! @{ */
+#define ISO7816_MSR_MSR_MASK                     (0xFFFFFFFFU)
+#define ISO7816_MSR_MSR_SHIFT                    (0U)
+/*! MSR - Mixed Status Register
+ */
+#define ISO7816_MSR_MSR(x)                       (((uint32_t)(((uint32_t)(x)) << ISO7816_MSR_MSR_SHIFT)) & ISO7816_MSR_MSR_MASK)
+/*! @} */
+
+/*! @name USR1 - UART Status Register 1 */
+/*! @{ */
+#define ISO7816_USR1_USR1_MASK                   (0xFFFFFFFFU)
+#define ISO7816_USR1_USR1_SHIFT                  (0U)
+/*! USR1 - UART Status Register 1
+ */
+#define ISO7816_USR1_USR1(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_USR1_USR1_SHIFT)) & ISO7816_USR1_USR1_MASK)
+/*! @} */
+
+/*! @name USR2 - UART Status Register 2 */
+/*! @{ */
+#define ISO7816_USR2_USR2_MASK                   (0xFFFFFFFFU)
+#define ISO7816_USR2_USR2_SHIFT                  (0U)
+/*! USR2 - UART Status Register 2
+ */
+#define ISO7816_USR2_USR2(x)                     (((uint32_t)(((uint32_t)(x)) << ISO7816_USR2_USR2_SHIFT)) & ISO7816_USR2_USR2_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group ISO7816_Register_Masks */
+
+
+/* ISO7816 - Peripheral instance base addresses */
+/** Peripheral ISO7816 base address */
+#define ISO7816_BASE                             (0x40006000u)
+/** Peripheral ISO7816 base pointer */
+#define ISO7816                                  ((ISO7816_Type *)ISO7816_BASE)
+/** Array initializer of ISO7816 peripheral base addresses */
+#define ISO7816_BASE_ADDRS                       { ISO7816_BASE }
+/** Array initializer of ISO7816 peripheral base pointers */
+#define ISO7816_BASE_PTRS                        { ISO7816 }
+
+/*!
+ * @}
+ */ /* end of group ISO7816_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- OTPC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup OTPC_Peripheral_Access_Layer OTPC Peripheral Access Layer
+ * @{
+ */
+
+/** OTPC - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t ADDR;                              /**< Address register for reading the E-Fuse OTP, offset: 0x0 */
+       uint8_t RESERVED_0[4];
+  __O  uint32_t READ;                              /**< Register for reading the E-Fuse OTP., offset: 0x8 */
+       uint8_t RESERVED_1[8];
+  __I  uint32_t RDATA;                             /**< Register for the OTP read back data., offset: 0x14 */
+} OTPC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- OTPC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup OTPC_Register_Masks OTPC Register Masks
+ * @{
+ */
+
+/*! @name ADDR - Address register for reading the E-Fuse OTP */
+/*! @{ */
+#define OTPC_ADDR_ADDR_MASK                      (0xFFFU)
+#define OTPC_ADDR_ADDR_SHIFT                     (0U)
+/*! ADDR - Address of OTP value to be read
+ */
+#define OTPC_ADDR_ADDR(x)                        (((uint32_t)(((uint32_t)(x)) << OTPC_ADDR_ADDR_SHIFT)) & OTPC_ADDR_ADDR_MASK)
+/*! @} */
+
+/*! @name READ - Register for reading the E-Fuse OTP. */
+/*! @{ */
+#define OTPC_READ_READ_MASK                      (0x1U)
+#define OTPC_READ_READ_SHIFT                     (0U)
+/*! READ - When 1 is written, the OTP is read. Note, this operation only occurs if correct SEQ value is also written.
+ */
+#define OTPC_READ_READ(x)                        (((uint32_t)(((uint32_t)(x)) << OTPC_READ_READ_SHIFT)) & OTPC_READ_READ_MASK)
+#define OTPC_READ_SEQ_MASK                       (0xFFFF0000U)
+#define OTPC_READ_SEQ_SHIFT                      (16U)
+/*! SEQ - Read unlock sequence: only when 0x7F12 is written is the Read command accepted.
+ */
+#define OTPC_READ_SEQ(x)                         (((uint32_t)(((uint32_t)(x)) << OTPC_READ_SEQ_SHIFT)) & OTPC_READ_SEQ_MASK)
+/*! @} */
+
+/*! @name RDATA - Register for the OTP read back data. */
+/*! @{ */
+#define OTPC_RDATA_DATA_MASK                     (0xFFFFU)
+#define OTPC_RDATA_DATA_SHIFT                    (0U)
+/*! DATA - Read back data from the E-Fuse OTP.
+ */
+#define OTPC_RDATA_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << OTPC_RDATA_DATA_SHIFT)) & OTPC_RDATA_DATA_MASK)
+#define OTPC_RDATA_VALID_MASK                    (0x80000000U)
+#define OTPC_RDATA_VALID_SHIFT                   (31U)
+/*! VALID - Valid bit. This bit will be cleared when a Read command has been given and will be set
+ *    when the sequencer has successfully captured the E-Fuse OTP data.
+ */
+#define OTPC_RDATA_VALID(x)                      (((uint32_t)(((uint32_t)(x)) << OTPC_RDATA_VALID_SHIFT)) & OTPC_RDATA_VALID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group OTPC_Register_Masks */
+
+
+/* OTPC - Peripheral instance base addresses */
+/** Peripheral OTPC base address */
+#define OTPC_BASE                                (0x40002000u)
+/** Peripheral OTPC base pointer */
+#define OTPC                                     ((OTPC_Type *)OTPC_BASE)
+/** Array initializer of OTPC peripheral base addresses */
+#define OTPC_BASE_ADDRS                          { OTPC_BASE }
+/** Array initializer of OTPC peripheral base pointers */
+#define OTPC_BASE_PTRS                           { OTPC }
+
+/*!
+ * @}
+ */ /* end of group OTPC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- PINT Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PINT_Peripheral_Access_Layer PINT Peripheral Access Layer
+ * @{
+ */
+
+/** PINT - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t ISEL;                              /**< Pin Interrupt Mode register (only interrupts 0 to 3 supported to processor), offset: 0x0 */
+  __IO uint32_t IENR;                              /**< Pin interrupt level or rising edge interrupt enable register (only interrupts 0 to 3 supported to processor), offset: 0x4 */
+  __O  uint32_t SIENR;                             /**< Pin interrupt level or rising edge interrupt set register (only interrupts 0 to 3 supported to processor), offset: 0x8 */
+  __O  uint32_t CIENR;                             /**< Pin interrupt level (rising edge interrupt) clear register (only interrupts 0 to 3 supported to processor), offset: 0xC */
+  __IO uint32_t IENF;                              /**< Pin interrupt active level or falling edge interrupt enable register, offset: 0x10 */
+  __O  uint32_t SIENF;                             /**< Pin interrupt active level or falling edge interrupt set register, offset: 0x14 */
+  __O  uint32_t CIENF;                             /**< Pin interrupt active level or falling edge interrupt clear register, offset: 0x18 */
+  __IO uint32_t RISE;                              /**< Pin interrupt rising edge register, offset: 0x1C */
+  __IO uint32_t FALL;                              /**< Pin interrupt falling edge register, offset: 0x20 */
+  __IO uint32_t IST;                               /**< Pin interrupt status register. For bits in this regsiter the following functionality occurs for the corresponding PIN bit: Read 0: interrupt is not being requested for this interrupt pin. Write 0: no operation. Read 1: interrupt is being requested for this interrupt pin. Write 1 (edge-sensitive): clear rising- and falling-edge detection for this pin. Write 1 (level-sensitive): switch the active level for this pin (in the IENF register)., offset: 0x24 */
+  __IO uint32_t PMCTRL;                            /**< Pattern match interrupt control register, offset: 0x28 */
+  __IO uint32_t PMSRC;                             /**< Pattern match interrupt bit-slice source register, offset: 0x2C */
+  __IO uint32_t PMCFG;                             /**< Pattern match interrupt bit slice configuration register, offset: 0x30 */
+} PINT_Type;
+
+/* ----------------------------------------------------------------------------
+   -- PINT Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PINT_Register_Masks PINT Register Masks
+ * @{
+ */
+
+/*! @name ISEL - Pin Interrupt Mode register (only interrupts 0 to 3 supported to processor) */
+/*! @{ */
+#define PINT_ISEL_PMODE_PIN0_MASK                (0x1U)
+#define PINT_ISEL_PMODE_PIN0_SHIFT               (0U)
+/*! PMODE_PIN0 - Selects the interrupt mode for pin interrupt 0 (selected in PINTSEL0). 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN0(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN0_SHIFT)) & PINT_ISEL_PMODE_PIN0_MASK)
+#define PINT_ISEL_PMODE_PIN1_MASK                (0x2U)
+#define PINT_ISEL_PMODE_PIN1_SHIFT               (1U)
+/*! PMODE_PIN1 - Selects the interrupt mode for pin interrupt 1 (selected in PINTSEL1). 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN1(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN1_SHIFT)) & PINT_ISEL_PMODE_PIN1_MASK)
+#define PINT_ISEL_PMODE_PIN2_MASK                (0x4U)
+#define PINT_ISEL_PMODE_PIN2_SHIFT               (2U)
+/*! PMODE_PIN2 - Selects the interrupt mode for pin interrupt 2 (selected in PINTSEL2). 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN2(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN2_SHIFT)) & PINT_ISEL_PMODE_PIN2_MASK)
+#define PINT_ISEL_PMODE_PIN3_MASK                (0x8U)
+#define PINT_ISEL_PMODE_PIN3_SHIFT               (3U)
+/*! PMODE_PIN3 - Selects the interrupt mode for pin interrupt 3 (selected in PINTSEL3). 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN3(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN3_SHIFT)) & PINT_ISEL_PMODE_PIN3_MASK)
+#define PINT_ISEL_PMODE_PIN4_MASK                (0x10U)
+#define PINT_ISEL_PMODE_PIN4_SHIFT               (4U)
+/*! PMODE_PIN4 - Selects the interrupt mode for pin interrupt 4 (selected in PINTSEL4). [Note
+ *    interrupt not supported to processor] 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN4(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN4_SHIFT)) & PINT_ISEL_PMODE_PIN4_MASK)
+#define PINT_ISEL_PMODE_PIN5_MASK                (0x20U)
+#define PINT_ISEL_PMODE_PIN5_SHIFT               (5U)
+/*! PMODE_PIN5 - Selects the interrupt mode for pin interrupt 5 (selected in PINTSEL5). [Note
+ *    interrupt not supported to processor] 0: Edge sensitive 1: Level sensitive
+ */
+#define PINT_ISEL_PMODE_PIN5(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN5_SHIFT)) & PINT_ISEL_PMODE_PIN5_MASK)
+#define PINT_ISEL_PMODE_PIN6_MASK                (0x40U)
+#define PINT_ISEL_PMODE_PIN6_SHIFT               (6U)
+/*! PMODE_PIN6 - Selects the interrupt mode for pin interrupt 6 (selected in PINTSEL6). [Note
+ *    interrupt not supported to processor] 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN6(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN6_SHIFT)) & PINT_ISEL_PMODE_PIN6_MASK)
+#define PINT_ISEL_PMODE_PIN7_MASK                (0x80U)
+#define PINT_ISEL_PMODE_PIN7_SHIFT               (7U)
+/*! PMODE_PIN7 - Selects the interrupt mode for pin interrupt 7 (selected in PINTSEL7). [Note
+ *    interrupt not supported to processor] 0: Edge sensitive. 1: Level sensitive.
+ */
+#define PINT_ISEL_PMODE_PIN7(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_PIN7_SHIFT)) & PINT_ISEL_PMODE_PIN7_MASK)
+/*! @} */
+
+/*! @name IENR - Pin interrupt level or rising edge interrupt enable register (only interrupts 0 to 3 supported to processor) */
+/*! @{ */
+#define PINT_IENR_ENRL_PIN0_MASK                 (0x1U)
+#define PINT_IENR_ENRL_PIN0_SHIFT                (0U)
+/*! ENRL_PIN0 - Enables the rising edge or level interrupt for pin interrupt 0 (selected in
+ *    PINTSEL0). 0: Disable rising edge or level interrupt. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN0(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN0_SHIFT)) & PINT_IENR_ENRL_PIN0_MASK)
+#define PINT_IENR_ENRL_PIN1_MASK                 (0x2U)
+#define PINT_IENR_ENRL_PIN1_SHIFT                (1U)
+/*! ENRL_PIN1 - Enables the rising edge or level interrupt for pin interrupt 1 (selected in
+ *    PINTSEL1). 0: Disable rising edge or level interrupt. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN1(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN1_SHIFT)) & PINT_IENR_ENRL_PIN1_MASK)
+#define PINT_IENR_ENRL_PIN2_MASK                 (0x4U)
+#define PINT_IENR_ENRL_PIN2_SHIFT                (2U)
+/*! ENRL_PIN2 - Enables the rising edge or level interrupt for pin interrupt 2 (selected in
+ *    PINTSEL2). 0: Disable rising edge or level interrupt. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN2(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN2_SHIFT)) & PINT_IENR_ENRL_PIN2_MASK)
+#define PINT_IENR_ENRL_PIN3_MASK                 (0x8U)
+#define PINT_IENR_ENRL_PIN3_SHIFT                (3U)
+/*! ENRL_PIN3 - Enables the rising edge or level interrupt for pin interrupt 3 (selected in
+ *    PINTSEL3). 0: Disable rising edge or level interrupt. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN3(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN3_SHIFT)) & PINT_IENR_ENRL_PIN3_MASK)
+#define PINT_IENR_ENRL_PIN4_MASK                 (0x10U)
+#define PINT_IENR_ENRL_PIN4_SHIFT                (4U)
+/*! ENRL_PIN4 - Enables the rising edge or level interrupt for pin interrupt 4 (selected in
+ *    PINTSEL4). [Note interrupt not supported to processor] 0: Disable rising edge or level interrupt. 1:
+ *    Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN4(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN4_SHIFT)) & PINT_IENR_ENRL_PIN4_MASK)
+#define PINT_IENR_ENRL_PIN5_MASK                 (0x20U)
+#define PINT_IENR_ENRL_PIN5_SHIFT                (5U)
+/*! ENRL_PIN5 - Enables the rising edge or level interrupt for pin interrupt 5 (selected in
+ *    PINTSEL5). [Note interrupt not supported to processor] 0: Disable rising edge or level interrupt. 1:
+ *    Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN5(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN5_SHIFT)) & PINT_IENR_ENRL_PIN5_MASK)
+#define PINT_IENR_ENRL_PIN6_MASK                 (0x40U)
+#define PINT_IENR_ENRL_PIN6_SHIFT                (6U)
+/*! ENRL_PIN6 - Enables the rising edge or level interrupt for pin interrupt 6 (selected in
+ *    PINTSEL6). [Note interrupt not supported to processor] 0: Disable rising edge or level interrupt. 1:
+ *    Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN6(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN6_SHIFT)) & PINT_IENR_ENRL_PIN6_MASK)
+#define PINT_IENR_ENRL_PIN7_MASK                 (0x80U)
+#define PINT_IENR_ENRL_PIN7_SHIFT                (7U)
+/*! ENRL_PIN7 - Enables the rising edge or level interrupt for pin interrupt 7 (selected in
+ *    PINTSEL7). [Note interrupt not supported to processor] 0: Disable rising edge or level interrupt. 1:
+ *    Enable rising edge or level interrupt.
+ */
+#define PINT_IENR_ENRL_PIN7(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_PIN7_SHIFT)) & PINT_IENR_ENRL_PIN7_MASK)
+/*! @} */
+
+/*! @name SIENR - Pin interrupt level or rising edge interrupt set register (only interrupts 0 to 3 supported to processor) */
+/*! @{ */
+#define PINT_SIENR_SETENRL_PIN0_MASK             (0x1U)
+#define PINT_SIENR_SETENRL_PIN0_SHIFT            (0U)
+/*! SETENRL_PIN0 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    0 sets bit 0 in the IENR register. 0: No operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN0_SHIFT)) & PINT_SIENR_SETENRL_PIN0_MASK)
+#define PINT_SIENR_SETENRL_PIN1_MASK             (0x2U)
+#define PINT_SIENR_SETENRL_PIN1_SHIFT            (1U)
+/*! SETENRL_PIN1 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    1 sets bit 1 in the IENR register. 0: No operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN1_SHIFT)) & PINT_SIENR_SETENRL_PIN1_MASK)
+#define PINT_SIENR_SETENRL_PIN2_MASK             (0x4U)
+#define PINT_SIENR_SETENRL_PIN2_SHIFT            (2U)
+/*! SETENRL_PIN2 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    2 sets bit 2 in the IENR register. 0: No operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN2_SHIFT)) & PINT_SIENR_SETENRL_PIN2_MASK)
+#define PINT_SIENR_SETENRL_PIN3_MASK             (0x8U)
+#define PINT_SIENR_SETENRL_PIN3_SHIFT            (3U)
+/*! SETENRL_PIN3 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    3 sets bit 3 in the IENR register. 0: No operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN3_SHIFT)) & PINT_SIENR_SETENRL_PIN3_MASK)
+#define PINT_SIENR_SETENRL_PIN4_MASK             (0x10U)
+#define PINT_SIENR_SETENRL_PIN4_SHIFT            (4U)
+/*! SETENRL_PIN4 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    4 sets bit 4 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN4_SHIFT)) & PINT_SIENR_SETENRL_PIN4_MASK)
+#define PINT_SIENR_SETENRL_PIN5_MASK             (0x20U)
+#define PINT_SIENR_SETENRL_PIN5_SHIFT            (5U)
+/*! SETENRL_PIN5 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    5 sets bit 5 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN5_SHIFT)) & PINT_SIENR_SETENRL_PIN5_MASK)
+#define PINT_SIENR_SETENRL_PIN6_MASK             (0x40U)
+#define PINT_SIENR_SETENRL_PIN6_SHIFT            (6U)
+/*! SETENRL_PIN6 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    6 sets bit 6 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN6_SHIFT)) & PINT_SIENR_SETENRL_PIN6_MASK)
+#define PINT_SIENR_SETENRL_PIN7_MASK             (0x80U)
+#define PINT_SIENR_SETENRL_PIN7_SHIFT            (7U)
+/*! SETENRL_PIN7 - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
+ *    7 sets bit 7 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Enable rising edge or level interrupt.
+ */
+#define PINT_SIENR_SETENRL_PIN7(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_PIN7_SHIFT)) & PINT_SIENR_SETENRL_PIN7_MASK)
+/*! @} */
+
+/*! @name CIENR - Pin interrupt level (rising edge interrupt) clear register (only interrupts 0 to 3 supported to processor) */
+/*! @{ */
+#define PINT_CIENR_CLRENRL_PIN0_MASK             (0x1U)
+#define PINT_CIENR_CLRENRL_PIN0_SHIFT            (0U)
+/*! CLRENRL_PIN0 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 0 clears bit 0 in the IENR register. 0: No operation. 1: Disable rising edge or level
+ *    interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN0_SHIFT)) & PINT_CIENR_CLRENRL_PIN0_MASK)
+#define PINT_CIENR_CLRENRL_PIN1_MASK             (0x2U)
+#define PINT_CIENR_CLRENRL_PIN1_SHIFT            (1U)
+/*! CLRENRL_PIN1 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 1 clears bit 1 in the IENR register. 0: No operation. 1: Disable rising edge or level
+ *    interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN1_SHIFT)) & PINT_CIENR_CLRENRL_PIN1_MASK)
+#define PINT_CIENR_CLRENRL_PIN2_MASK             (0x4U)
+#define PINT_CIENR_CLRENRL_PIN2_SHIFT            (2U)
+/*! CLRENRL_PIN2 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 2 clears bit 2 in the IENR register. 0: No operation. 1: Disable rising edge or level
+ *    interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN2_SHIFT)) & PINT_CIENR_CLRENRL_PIN2_MASK)
+#define PINT_CIENR_CLRENRL_PIN3_MASK             (0x8U)
+#define PINT_CIENR_CLRENRL_PIN3_SHIFT            (3U)
+/*! CLRENRL_PIN3 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 3 clears bit 3 in the IENR register. 0: No operation. 1: Disable rising edge or level
+ *    interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN3_SHIFT)) & PINT_CIENR_CLRENRL_PIN3_MASK)
+#define PINT_CIENR_CLRENRL_PIN4_MASK             (0x10U)
+#define PINT_CIENR_CLRENRL_PIN4_SHIFT            (4U)
+/*! CLRENRL_PIN4 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 4 clears bit 4 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Disable rising edge or level interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN4_SHIFT)) & PINT_CIENR_CLRENRL_PIN4_MASK)
+#define PINT_CIENR_CLRENRL_PIN5_MASK             (0x20U)
+#define PINT_CIENR_CLRENRL_PIN5_SHIFT            (5U)
+/*! CLRENRL_PIN5 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 5 clears bit 5 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Disable rising edge or level interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN5_SHIFT)) & PINT_CIENR_CLRENRL_PIN5_MASK)
+#define PINT_CIENR_CLRENRL_PIN6_MASK             (0x40U)
+#define PINT_CIENR_CLRENRL_PIN6_SHIFT            (6U)
+/*! CLRENRL_PIN6 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 6 clears bit 6 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Disable rising edge or level interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN6_SHIFT)) & PINT_CIENR_CLRENRL_PIN6_MASK)
+#define PINT_CIENR_CLRENRL_PIN7_MASK             (0x80U)
+#define PINT_CIENR_CLRENRL_PIN7_SHIFT            (7U)
+/*! CLRENRL_PIN7 - Ones written to this address clear bits in the IENR, thus disabling the
+ *    interrupts. Bit 7 clears bit 7 in the IENR register. [Note interrupt not supported to processor] 0: No
+ *    operation. 1: Disable rising edge or level interrupt.
+ */
+#define PINT_CIENR_CLRENRL_PIN7(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CLRENRL_PIN7_SHIFT)) & PINT_CIENR_CLRENRL_PIN7_MASK)
+/*! @} */
+
+/*! @name IENF - Pin interrupt active level or falling edge interrupt enable register */
+/*! @{ */
+#define PINT_IENF_ENAF_PIN0_MASK                 (0x1U)
+#define PINT_IENF_ENAF_PIN0_SHIFT                (0U)
+/*! ENAF_PIN0 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    0 (selected in PINTSEL0). 0: Disable falling edge interrupt or set active interrupt level LOW.
+ *    1: Enable falling edge interrupt enabled or set active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN0(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN0_SHIFT)) & PINT_IENF_ENAF_PIN0_MASK)
+#define PINT_IENF_ENAF_PIN1_MASK                 (0x2U)
+#define PINT_IENF_ENAF_PIN1_SHIFT                (1U)
+/*! ENAF_PIN1 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    1 (selected in PINTSEL1). 0: Disable falling edge interrupt or set active interrupt level LOW.
+ *    1: Enable falling edge interrupt enabled or set active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN1(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN1_SHIFT)) & PINT_IENF_ENAF_PIN1_MASK)
+#define PINT_IENF_ENAF_PIN2_MASK                 (0x4U)
+#define PINT_IENF_ENAF_PIN2_SHIFT                (2U)
+/*! ENAF_PIN2 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    2 (selected in PINTSEL2). 0: Disable falling edge interrupt or set active interrupt level LOW.
+ *    1: Enable falling edge interrupt enabled or set active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN2(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN2_SHIFT)) & PINT_IENF_ENAF_PIN2_MASK)
+#define PINT_IENF_ENAF_PIN3_MASK                 (0x8U)
+#define PINT_IENF_ENAF_PIN3_SHIFT                (3U)
+/*! ENAF_PIN3 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    3 (selected in PINTSEL3). 0: Disable falling edge interrupt or set active interrupt level LOW.
+ *    1: Enable falling edge interrupt enabled or set active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN3(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN3_SHIFT)) & PINT_IENF_ENAF_PIN3_MASK)
+#define PINT_IENF_ENAF_PIN4_MASK                 (0x10U)
+#define PINT_IENF_ENAF_PIN4_SHIFT                (4U)
+/*! ENAF_PIN4 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    4 (selected in PINTSEL4). [Note interrupt not supported to processor] 0: Disable falling edge
+ *    interrupt or set active interrupt level LOW. 1: Enable falling edge interrupt enabled or set
+ *    active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN4(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN4_SHIFT)) & PINT_IENF_ENAF_PIN4_MASK)
+#define PINT_IENF_ENAF_PIN5_MASK                 (0x20U)
+#define PINT_IENF_ENAF_PIN5_SHIFT                (5U)
+/*! ENAF_PIN5 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    5 (selected in PINTSEL5). [Note interrupt not supported to processor] 0: Disable falling edge
+ *    interrupt or set active interrupt level LOW. 1: Enable falling edge interrupt enabled or set
+ *    active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN5(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN5_SHIFT)) & PINT_IENF_ENAF_PIN5_MASK)
+#define PINT_IENF_ENAF_PIN6_MASK                 (0x40U)
+#define PINT_IENF_ENAF_PIN6_SHIFT                (6U)
+/*! ENAF_PIN6 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    6 (selected in PINTSEL6). [Note interrupt not supported to processor] 0: Disable falling edge
+ *    interrupt or set active interrupt level LOW. 1: Enable falling edge interrupt enabled or set
+ *    active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN6(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN6_SHIFT)) & PINT_IENF_ENAF_PIN6_MASK)
+#define PINT_IENF_ENAF_PIN7_MASK                 (0x80U)
+#define PINT_IENF_ENAF_PIN7_SHIFT                (7U)
+/*! ENAF_PIN7 - Enables the falling edge or configures the active level interrupt for pin interrupt
+ *    7 (selected in PINTSEL7). [Note interrupt not supported to processor] 0: Disable falling edge
+ *    interrupt or set active interrupt level LOW. 1: Enable falling edge interrupt enabled or set
+ *    active interrupt level HIGH.
+ */
+#define PINT_IENF_ENAF_PIN7(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_PIN7_SHIFT)) & PINT_IENF_ENAF_PIN7_MASK)
+/*! @} */
+
+/*! @name SIENF - Pin interrupt active level or falling edge interrupt set register */
+/*! @{ */
+#define PINT_SIENF_SETENAF_PIN0_MASK             (0x1U)
+#define PINT_SIENF_SETENAF_PIN0_SHIFT            (0U)
+/*! SETENAF_PIN0 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    0 sets bit 0 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN0_SHIFT)) & PINT_SIENF_SETENAF_PIN0_MASK)
+#define PINT_SIENF_SETENAF_PIN1_MASK             (0x2U)
+#define PINT_SIENF_SETENAF_PIN1_SHIFT            (1U)
+/*! SETENAF_PIN1 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    1 sets bit 1 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN1_SHIFT)) & PINT_SIENF_SETENAF_PIN1_MASK)
+#define PINT_SIENF_SETENAF_PIN2_MASK             (0x4U)
+#define PINT_SIENF_SETENAF_PIN2_SHIFT            (2U)
+/*! SETENAF_PIN2 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    2 sets bit 2 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN2_SHIFT)) & PINT_SIENF_SETENAF_PIN2_MASK)
+#define PINT_SIENF_SETENAF_PIN3_MASK             (0x8U)
+#define PINT_SIENF_SETENAF_PIN3_SHIFT            (3U)
+/*! SETENAF_PIN3 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    3 sets bit 3 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN3_SHIFT)) & PINT_SIENF_SETENAF_PIN3_MASK)
+#define PINT_SIENF_SETENAF_PIN4_MASK             (0x10U)
+#define PINT_SIENF_SETENAF_PIN4_SHIFT            (4U)
+/*! SETENAF_PIN4 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    4 sets bit 4 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN4_SHIFT)) & PINT_SIENF_SETENAF_PIN4_MASK)
+#define PINT_SIENF_SETENAF_PIN5_MASK             (0x20U)
+#define PINT_SIENF_SETENAF_PIN5_SHIFT            (5U)
+/*! SETENAF_PIN5 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    5 sets bit 5 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN5_SHIFT)) & PINT_SIENF_SETENAF_PIN5_MASK)
+#define PINT_SIENF_SETENAF_PIN6_MASK             (0x40U)
+#define PINT_SIENF_SETENAF_PIN6_SHIFT            (6U)
+/*! SETENAF_PIN6 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    6 sets bit 6 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN6_SHIFT)) & PINT_SIENF_SETENAF_PIN6_MASK)
+#define PINT_SIENF_SETENAF_PIN7_MASK             (0x80U)
+#define PINT_SIENF_SETENAF_PIN7_SHIFT            (7U)
+/*! SETENAF_PIN7 - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
+ *    7 sets bit 7 in the IENF register. 0: No operation. 1: Select HIGH-active interrupt or enable
+ *    falling edge interrupt.
+ */
+#define PINT_SIENF_SETENAF_PIN7(x)               (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_PIN7_SHIFT)) & PINT_SIENF_SETENAF_PIN7_MASK)
+/*! @} */
+
+/*! @name CIENF - Pin interrupt active level or falling edge interrupt clear register */
+/*! @{ */
+#define PINT_CIENF_CLRENAF_PIN0_MASK             (0x1U)
+#define PINT_CIENF_CLRENAF_PIN0_SHIFT            (0U)
+/*! CLRENAF_PIN0 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 0 clears bit 0 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN0_SHIFT)) & PINT_CIENF_CLRENAF_PIN0_MASK)
+#define PINT_CIENF_CLRENAF_PIN1_MASK             (0x2U)
+#define PINT_CIENF_CLRENAF_PIN1_SHIFT            (1U)
+/*! CLRENAF_PIN1 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 1 clears bit 1 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN1_SHIFT)) & PINT_CIENF_CLRENAF_PIN1_MASK)
+#define PINT_CIENF_CLRENAF_PIN2_MASK             (0x4U)
+#define PINT_CIENF_CLRENAF_PIN2_SHIFT            (2U)
+/*! CLRENAF_PIN2 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 2 clears bit 2 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN2_SHIFT)) & PINT_CIENF_CLRENAF_PIN2_MASK)
+#define PINT_CIENF_CLRENAF_PIN3_MASK             (0x8U)
+#define PINT_CIENF_CLRENAF_PIN3_SHIFT            (3U)
+/*! CLRENAF_PIN3 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 3 clears bit 3 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN3_SHIFT)) & PINT_CIENF_CLRENAF_PIN3_MASK)
+#define PINT_CIENF_CLRENAF_PIN4_MASK             (0x10U)
+#define PINT_CIENF_CLRENAF_PIN4_SHIFT            (4U)
+/*! CLRENAF_PIN4 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 4 clears bit 4 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN4_SHIFT)) & PINT_CIENF_CLRENAF_PIN4_MASK)
+#define PINT_CIENF_CLRENAF_PIN5_MASK             (0x20U)
+#define PINT_CIENF_CLRENAF_PIN5_SHIFT            (5U)
+/*! CLRENAF_PIN5 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 5 clears bit 5 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN5_SHIFT)) & PINT_CIENF_CLRENAF_PIN5_MASK)
+#define PINT_CIENF_CLRENAF_PIN6_MASK             (0x40U)
+#define PINT_CIENF_CLRENAF_PIN6_SHIFT            (6U)
+/*! CLRENAF_PIN6 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 6 clears bit 6 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN6_SHIFT)) & PINT_CIENF_CLRENAF_PIN6_MASK)
+#define PINT_CIENF_CLRENAF_PIN7_MASK             (0x80U)
+#define PINT_CIENF_CLRENAF_PIN7_SHIFT            (7U)
+/*! CLRENAF_PIN7 - Ones written to this address clears bits in the IENF, thus disabling interrupts.
+ *    Bit 7 clears bit 7 in the IENF register. 0: No operation. 1: LOW-active interrupt selected or
+ *    falling edge interrupt disabled.
+ */
+#define PINT_CIENF_CLRENAF_PIN7(x)               (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CLRENAF_PIN7_SHIFT)) & PINT_CIENF_CLRENAF_PIN7_MASK)
+/*! @} */
+
+/*! @name RISE - Pin interrupt rising edge register */
+/*! @{ */
+#define PINT_RISE_RDET_MASK                      (0xFFU)
+#define PINT_RISE_RDET_SHIFT                     (0U)
+/*! RDET - Rising edge detect. Bit n detects the rising edge of the pin selected in PINTSELn. Read
+ *    0: No rising edge has been detected on this pin since Reset or the last time a one was written
+ *    to this bit. Write 0: no operation. Read 1: a rising edge has been detected since Reset or the
+ *    last time a one was written to this bit. Write 1: clear rising edge detection for this pin.
+ */
+#define PINT_RISE_RDET(x)                        (((uint32_t)(((uint32_t)(x)) << PINT_RISE_RDET_SHIFT)) & PINT_RISE_RDET_MASK)
+/*! @} */
+
+/*! @name FALL - Pin interrupt falling edge register */
+/*! @{ */
+#define PINT_FALL_FDET_MASK                      (0xFFU)
+#define PINT_FALL_FDET_SHIFT                     (0U)
+/*! FDET - Falling edge detect. Bit n detects the falling edge of the pin selected in PINTSELn. Read
+ *    0: No falling edge has been detected on this pin since Reset or the last time a one was
+ *    written to this bit. Write 0: no operation. Read 1: a falling edge has been detected since Reset or
+ *    the last time a one was written to this bit. Write 1: clear falling edge detection for this
+ *    pin.
+ */
+#define PINT_FALL_FDET(x)                        (((uint32_t)(((uint32_t)(x)) << PINT_FALL_FDET_SHIFT)) & PINT_FALL_FDET_MASK)
+/*! @} */
+
+/*! @name IST - Pin interrupt status register. For bits in this regsiter the following functionality occurs for the corresponding PIN bit: Read 0: interrupt is not being requested for this interrupt pin. Write 0: no operation. Read 1: interrupt is being requested for this interrupt pin. Write 1 (edge-sensitive): clear rising- and falling-edge detection for this pin. Write 1 (level-sensitive): switch the active level for this pin (in the IENF register). */
+/*! @{ */
+#define PINT_IST_PSTAT_PIN0_MASK                 (0x1U)
+#define PINT_IST_PSTAT_PIN0_SHIFT                (0U)
+/*! PSTAT_PIN0 - Pin interrupt status. Bit 0 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 0 (selected in PINTSEL0).
+ */
+#define PINT_IST_PSTAT_PIN0(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN0_SHIFT)) & PINT_IST_PSTAT_PIN0_MASK)
+#define PINT_IST_PSTAT_PIN1_MASK                 (0x2U)
+#define PINT_IST_PSTAT_PIN1_SHIFT                (1U)
+/*! PSTAT_PIN1 - Pin interrupt status. Bit 1 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 1 (selected in PINTSEL0).
+ */
+#define PINT_IST_PSTAT_PIN1(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN1_SHIFT)) & PINT_IST_PSTAT_PIN1_MASK)
+#define PINT_IST_PSTAT_PIN2_MASK                 (0x4U)
+#define PINT_IST_PSTAT_PIN2_SHIFT                (2U)
+/*! PSTAT_PIN2 - Pin interrupt status. Bit 2 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 2 (selected in PINTSEL2).
+ */
+#define PINT_IST_PSTAT_PIN2(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN2_SHIFT)) & PINT_IST_PSTAT_PIN2_MASK)
+#define PINT_IST_PSTAT_PIN3_MASK                 (0x8U)
+#define PINT_IST_PSTAT_PIN3_SHIFT                (3U)
+/*! PSTAT_PIN3 - Pin interrupt status. Bit 3 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 3 (selected in PINTSEL3).
+ */
+#define PINT_IST_PSTAT_PIN3(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN3_SHIFT)) & PINT_IST_PSTAT_PIN3_MASK)
+#define PINT_IST_PSTAT_PIN4_MASK                 (0x10U)
+#define PINT_IST_PSTAT_PIN4_SHIFT                (4U)
+/*! PSTAT_PIN4 - Pin interrupt status. Bit 4 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 4 (selected in PINTSEL4).
+ */
+#define PINT_IST_PSTAT_PIN4(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN4_SHIFT)) & PINT_IST_PSTAT_PIN4_MASK)
+#define PINT_IST_PSTAT_PIN5_MASK                 (0x20U)
+#define PINT_IST_PSTAT_PIN5_SHIFT                (5U)
+/*! PSTAT_PIN5 - Pin interrupt status. Bit 5 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 5 (selected in PINTSEL5).
+ */
+#define PINT_IST_PSTAT_PIN5(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN5_SHIFT)) & PINT_IST_PSTAT_PIN5_MASK)
+#define PINT_IST_PSTAT_PIN6_MASK                 (0x40U)
+#define PINT_IST_PSTAT_PIN6_SHIFT                (6U)
+/*! PSTAT_PIN6 - Pin interrupt status. Bit 6 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 6 (selected in PINTSEL6).
+ */
+#define PINT_IST_PSTAT_PIN6(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN6_SHIFT)) & PINT_IST_PSTAT_PIN6_MASK)
+#define PINT_IST_PSTAT_PIN7_MASK                 (0x80U)
+#define PINT_IST_PSTAT_PIN7_SHIFT                (7U)
+/*! PSTAT_PIN7 - Pin interrupt status. Bit 7 returns the status, clears the edge interrupt, or
+ *    inverts the active level of the pin 7 (selected in PINTSEL7).
+ */
+#define PINT_IST_PSTAT_PIN7(x)                   (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_PIN7_SHIFT)) & PINT_IST_PSTAT_PIN7_MASK)
+/*! @} */
+
+/*! @name PMCTRL - Pattern match interrupt control register */
+/*! @{ */
+#define PINT_PMCTRL_SEL_PMATCH_MASK              (0x1U)
+#define PINT_PMCTRL_SEL_PMATCH_SHIFT             (0U)
+/*! SEL_PMATCH - Specifies whether the 8 pin interrupts are controlled by the pin interrupt function
+ *    or by the pattern match function. 0: Pin interrupt. Interrupts are driven in response to the
+ *    standard pin interrupt function. 1: Pattern match. Interrupts are driven in response to
+ *    pattern matches.
+ */
+#define PINT_PMCTRL_SEL_PMATCH(x)                (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_SEL_PMATCH_SHIFT)) & PINT_PMCTRL_SEL_PMATCH_MASK)
+#define PINT_PMCTRL_ENA_RXEV_MASK                (0x2U)
+#define PINT_PMCTRL_ENA_RXEV_SHIFT               (1U)
+/*! ENA_RXEV - Enables the RXEV output to the CPU when the specified boolean expression evaluates to
+ *    true. 0: Disabled. RXEV output to the CPU is disabled. 1: Enabled. RXEV output to the CPU is
+ *    enabled.
+ */
+#define PINT_PMCTRL_ENA_RXEV(x)                  (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_ENA_RXEV_SHIFT)) & PINT_PMCTRL_ENA_RXEV_MASK)
+#define PINT_PMCTRL_PMAT_MASK                    (0xFF000000U)
+#define PINT_PMCTRL_PMAT_SHIFT                   (24U)
+/*! PMAT - This field displays the current state of pattern matches. A 1 in any bit of this field
+ *    indicates that the corresponding product term is matched by the current state of the appropriate
+ *    inputs.
+ */
+#define PINT_PMCTRL_PMAT(x)                      (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_PMAT_SHIFT)) & PINT_PMCTRL_PMAT_MASK)
+/*! @} */
+
+/*! @name PMSRC - Pattern match interrupt bit-slice source register */
+/*! @{ */
+#define PINT_PMSRC_SRC0_MASK                     (0x700U)
+#define PINT_PMSRC_SRC0_SHIFT                    (8U)
+/*! SRC0 - Selects the input source for bit slice 0. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC0(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC0_SHIFT)) & PINT_PMSRC_SRC0_MASK)
+#define PINT_PMSRC_SRC1_MASK                     (0x3800U)
+#define PINT_PMSRC_SRC1_SHIFT                    (11U)
+/*! SRC1 - Selects the input source for bit slice 1. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC1(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC1_SHIFT)) & PINT_PMSRC_SRC1_MASK)
+#define PINT_PMSRC_SRC2_MASK                     (0x1C000U)
+#define PINT_PMSRC_SRC2_SHIFT                    (14U)
+/*! SRC2 - Selects the input source for bit slice 2. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC2(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC2_SHIFT)) & PINT_PMSRC_SRC2_MASK)
+#define PINT_PMSRC_SRC3_MASK                     (0xE0000U)
+#define PINT_PMSRC_SRC3_SHIFT                    (17U)
+/*! SRC3 - Selects the input source for bit slice 3. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC3(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC3_SHIFT)) & PINT_PMSRC_SRC3_MASK)
+#define PINT_PMSRC_SRC4_MASK                     (0x700000U)
+#define PINT_PMSRC_SRC4_SHIFT                    (20U)
+/*! SRC4 - Selects the input source for bit slice 4. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC4(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC4_SHIFT)) & PINT_PMSRC_SRC4_MASK)
+#define PINT_PMSRC_SRC5_MASK                     (0x3800000U)
+#define PINT_PMSRC_SRC5_SHIFT                    (23U)
+/*! SRC5 - Selects the input source for bit slice 5. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC5(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC5_SHIFT)) & PINT_PMSRC_SRC5_MASK)
+#define PINT_PMSRC_SRC6_MASK                     (0x1C000000U)
+#define PINT_PMSRC_SRC6_SHIFT                    (26U)
+/*! SRC6 - Selects the input source for bit slice 6. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC6(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC6_SHIFT)) & PINT_PMSRC_SRC6_MASK)
+#define PINT_PMSRC_SRC7_MASK                     (0xE0000000U)
+#define PINT_PMSRC_SRC7_SHIFT                    (29U)
+/*! SRC7 - Selects the input source for bit slice 7. Value X selects the pin selected in the
+ *    PINTSELX register as the source to this bit slice. For example 3 selects the pin selected in PINTSEL3
+ *    regsiter.
+ */
+#define PINT_PMSRC_SRC7(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC7_SHIFT)) & PINT_PMSRC_SRC7_MASK)
+/*! @} */
+
+/*! @name PMCFG - Pattern match interrupt bit slice configuration register */
+/*! @{ */
+#define PINT_PMCFG_PROD_ENDPTS0_MASK             (0x1U)
+#define PINT_PMCFG_PROD_ENDPTS0_SHIFT            (0U)
+/*! PROD_ENDPTS0 - Determines whether slice 0 is an endpoint. 0: No effect. Slice 0 is not an
+ *    endpoint. 1: endpoint. Slice 0 is the endpoint of a product term (minterm). Interrupt PINT0 in the
+ *    NVIC is raised if the minterm evaluates as true.
+ */
+#define PINT_PMCFG_PROD_ENDPTS0(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS0_SHIFT)) & PINT_PMCFG_PROD_ENDPTS0_MASK)
+#define PINT_PMCFG_PROD_ENDPTS1_MASK             (0x2U)
+#define PINT_PMCFG_PROD_ENDPTS1_SHIFT            (1U)
+/*! PROD_ENDPTS1 - Determines whether slice 1 is an endpoint. 0: No effect. Slice 1 is not an
+ *    endpoint. 1: endpoint. Slice 1 is the endpoint of a product term (minterm). Interrupt PINT1 in the
+ *    NVIC is raised if the minterm evaluates as true.
+ */
+#define PINT_PMCFG_PROD_ENDPTS1(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS1_SHIFT)) & PINT_PMCFG_PROD_ENDPTS1_MASK)
+#define PINT_PMCFG_PROD_ENDPTS2_MASK             (0x4U)
+#define PINT_PMCFG_PROD_ENDPTS2_SHIFT            (2U)
+/*! PROD_ENDPTS2 - Determines whether slice 2 is an endpoint. 0: No effect. Slice 2 is not an
+ *    endpoint. 1: endpoint. Slice 2 is the endpoint of a product term (minterm). Interrupt PINT2 in the
+ *    NVIC is raised if the minterm evaluates as true.
+ */
+#define PINT_PMCFG_PROD_ENDPTS2(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS2_SHIFT)) & PINT_PMCFG_PROD_ENDPTS2_MASK)
+#define PINT_PMCFG_PROD_ENDPTS3_MASK             (0x8U)
+#define PINT_PMCFG_PROD_ENDPTS3_SHIFT            (3U)
+/*! PROD_ENDPTS3 - Determines whether slice 3 is an endpoint. 0: No effect. Slice 3 is not an
+ *    endpoint. 1: endpoint. Slice 3 is the endpoint of a product term (minterm). Interrupt PINT3 in the
+ *    NVIC is raised if the minterm evaluates as true.
+ */
+#define PINT_PMCFG_PROD_ENDPTS3(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS3_SHIFT)) & PINT_PMCFG_PROD_ENDPTS3_MASK)
+#define PINT_PMCFG_PROD_ENDPTS4_MASK             (0x10U)
+#define PINT_PMCFG_PROD_ENDPTS4_SHIFT            (4U)
+/*! PROD_ENDPTS4 - Determines whether slice 4 is an endpoint. 0: No effect. Slice 4 is not an
+ *    endpoint. 1: endpoint. Slice 4 is the endpoint of a product term (minterm). No NVIC interrupt is
+ *    assocaited with this.
+ */
+#define PINT_PMCFG_PROD_ENDPTS4(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS4_SHIFT)) & PINT_PMCFG_PROD_ENDPTS4_MASK)
+#define PINT_PMCFG_PROD_ENDPTS5_MASK             (0x20U)
+#define PINT_PMCFG_PROD_ENDPTS5_SHIFT            (5U)
+/*! PROD_ENDPTS5 - Determines whether slice 5 is an endpoint. 0 No effect. Slice 5 is not an
+ *    endpoint. 1: endpoint. Slice 5 is the endpoint of a product term (minterm). No NVIC interrupt is
+ *    assocaited with this.
+ */
+#define PINT_PMCFG_PROD_ENDPTS5(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS5_SHIFT)) & PINT_PMCFG_PROD_ENDPTS5_MASK)
+#define PINT_PMCFG_PROD_ENDPTS6_MASK             (0x40U)
+#define PINT_PMCFG_PROD_ENDPTS6_SHIFT            (6U)
+/*! PROD_ENDPTS6 - Determines whether slice 6 is an endpoint. 0: No effect. Slice 6 is not an
+ *    endpoint. 1: endpoint. Slice 6 is the endpoint of a product term (minterm). No NVIC interrupt is
+ *    assocaited with this.
+ */
+#define PINT_PMCFG_PROD_ENDPTS6(x)               (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS6_SHIFT)) & PINT_PMCFG_PROD_ENDPTS6_MASK)
+#define PINT_PMCFG_CFG0_MASK                     (0x700U)
+#define PINT_PMCFG_CFG0_SHIFT                    (8U)
+/*! CFG0 - Specifies the match contribution condition for bit slice 0. 0x0: Constant HIGH. This bit
+ *    slice always contributes to a product term match. 0x1: Sticky rising edge. Match occurs if a
+ *    rising edge on the specified input has occurred since the last time the edge detection for this
+ *    bit slice was cleared. This bit is only cleared when the PMCFG or the PMSRC registers are
+ *    written to. 0x2: Sticky falling edge. Match occurs if a falling edge on the specified input has
+ *    occurred since the last time the edge detection for this bit slice was cleared. This bit is
+ *    only cleared when the PMCFG or the PMSRC registers are written to. 0x3: Sticky rising or falling
+ *    edge. Match occurs if either a rising or falling edge on the specified input has occurred
+ *    since the last time the edge detection for this bit slice was cleared. This bit is only cleared
+ *    when the PMCFG or the PMSRC registers are written to. 0x4: High level. Match (for this bit
+ *    slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC
+ *    register. 0x5: Low level. Match occurs when there is a low level on the specified input. 0x6:
+ *    Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit
+ *    slices). 0x7: Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when
+ *    either a rising or falling edge is first detected on the specified input (this is a non-sticky
+ *    version of value 0x3). This bit is cleared after one clock cycle.
+ */
+#define PINT_PMCFG_CFG0(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG0_SHIFT)) & PINT_PMCFG_CFG0_MASK)
+#define PINT_PMCFG_CFG1_MASK                     (0x3800U)
+#define PINT_PMCFG_CFG1_SHIFT                    (11U)
+/*! CFG1 - Specifies the match contribution condition for bit slice 1. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG1(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG1_SHIFT)) & PINT_PMCFG_CFG1_MASK)
+#define PINT_PMCFG_CFG2_MASK                     (0x1C000U)
+#define PINT_PMCFG_CFG2_SHIFT                    (14U)
+/*! CFG2 - Specifies the match contribution condition for bit slice 2. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG2(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG2_SHIFT)) & PINT_PMCFG_CFG2_MASK)
+#define PINT_PMCFG_CFG3_MASK                     (0xE0000U)
+#define PINT_PMCFG_CFG3_SHIFT                    (17U)
+/*! CFG3 - Specifies the match contribution condition for bit slice 3. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG3(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG3_SHIFT)) & PINT_PMCFG_CFG3_MASK)
+#define PINT_PMCFG_CFG4_MASK                     (0x700000U)
+#define PINT_PMCFG_CFG4_SHIFT                    (20U)
+/*! CFG4 - Specifies the match contribution condition for bit slice 4. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG4(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG4_SHIFT)) & PINT_PMCFG_CFG4_MASK)
+#define PINT_PMCFG_CFG5_MASK                     (0x3800000U)
+#define PINT_PMCFG_CFG5_SHIFT                    (23U)
+/*! CFG5 - Specifies the match contribution condition for bit slice 5. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG5(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG5_SHIFT)) & PINT_PMCFG_CFG5_MASK)
+#define PINT_PMCFG_CFG6_MASK                     (0x1C000000U)
+#define PINT_PMCFG_CFG6_SHIFT                    (26U)
+/*! CFG6 - Specifies the match contribution condition for bit slice 6. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG6(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG6_SHIFT)) & PINT_PMCFG_CFG6_MASK)
+#define PINT_PMCFG_CFG7_MASK                     (0xE0000000U)
+#define PINT_PMCFG_CFG7_SHIFT                    (29U)
+/*! CFG7 - Specifies the match contribution condition for bit slice 7. See CFG0 for the modes available.
+ */
+#define PINT_PMCFG_CFG7(x)                       (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG7_SHIFT)) & PINT_PMCFG_CFG7_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group PINT_Register_Masks */
+
+
+/* PINT - Peripheral instance base addresses */
+/** Peripheral PINT base address */
+#define PINT_BASE                                (0x40010000u)
+/** Peripheral PINT base pointer */
+#define PINT                                     ((PINT_Type *)PINT_BASE)
+/** Array initializer of PINT peripheral base addresses */
+#define PINT_BASE_ADDRS                          { PINT_BASE }
+/** Array initializer of PINT peripheral base pointers */
+#define PINT_BASE_PTRS                           { PINT }
+/** Interrupt vectors for the PINT peripheral type */
+#define PINT_IRQS                                { PIN_INT0_IRQn, PIN_INT1_IRQn, PIN_INT2_IRQn, PIN_INT3_IRQn }
+
+/*!
+ * @}
+ */ /* end of group PINT_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- PMC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PMC_Peripheral_Access_Layer PMC Peripheral Access Layer
+ * @{
+ */
+
+/** PMC - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< Power Management Control [Reset by POR, RSTN, WDT ], offset: 0x0 */
+  __IO uint32_t DCDC0;                             /**< DCDC control register (1st). This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x4 */
+  __IO uint32_t DCDC1;                             /**< DCDC control register (2nd). This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x8 */
+  __IO uint32_t BIAS;                              /**< Bias current source control register. This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ], offset: 0xC */
+  __IO uint32_t LDOPMU;                            /**< PMU & Always On domains LDO control. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x10 */
+  __IO uint32_t LDOMEM;                            /**< Memories LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x14 */
+  __IO uint32_t LDOCORE;                           /**< Digital Core LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x18 */
+  __IO uint32_t LDOFLASHNV;                        /**< Flash LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x1C */
+  __IO uint32_t LDOFLASHCORE;                      /**< Flash Core LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x20 */
+  __IO uint32_t LDOADC;                            /**< General Purpose ADC LDO control register This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset], offset: 0x24 */
+       uint8_t RESERVED_0[8];
+  __IO uint32_t BODVBAT;                           /**< VBAT Brown Out Dectector control register This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ], offset: 0x30 */
+       uint8_t RESERVED_1[12];
+  __IO uint32_t FRO192M;                           /**< High Speed FRO control register This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ], offset: 0x40 */
+  __IO uint32_t FRO1M;                             /**< 1 MHz Free Running Oscillator control register. [Reset by all reset sources, except ARM SystemReset], offset: 0x44 */
+       uint8_t RESERVED_2[8];
+  __IO uint32_t ANAMUXCOMP;                        /**< Analog Comparator and Analog Mux control register. [Reset by all reset sources, except ARM SystemReset], offset: 0x50 */
+       uint8_t RESERVED_3[12];
+  __I  uint32_t PWRSWACK;                          /**< Power Switch acknowledge. [Reset by all reset sources, except ARM SystemReset], offset: 0x60 */
+  __IO uint32_t DPDWKSRC;                          /**< Power Down and Deep Power Down wake-up source. [Reset by POR, RSTN, WDT ], offset: 0x64 */
+  __I  uint32_t STATUSPWR;                         /**< Power OK and Ready signals from various analog modules (DCDC, LDO, ). [Reset by all reset sources, except ARM SystemReset], offset: 0x68 */
+  __I  uint32_t STATUSCLK;                         /**< FRO and XTAL status register. [Reset by all reset sources, except ARM SystemReset], offset: 0x6C */
+  __IO uint32_t RESETCAUSE;                        /**< Reset Cause register. [Reset by POR], offset: 0x70 */
+       uint8_t RESERVED_4[12];
+  __IO uint32_t AOREG0;                            /**< General purpose always on domain data storage. [Reset by all reset sources, except ARM SystemReset], offset: 0x80 */
+  __IO uint32_t AOREG1;                            /**< General purpose always on domain data storage. [Reset by POR, RSTN], offset: 0x84 */
+  __IO uint32_t AOREG2;                            /**< General purpose always on domain data storage. [Reset by POR, RSTN], offset: 0x88 */
+       uint8_t RESERVED_5[12];
+  __IO uint32_t DPDCTRL;                           /**< Configuration parameters for Power Down and Deep Power Down mode. [Reset by POR, RSTN, WDT ], offset: 0x98 */
+  __I  uint32_t PIOPORCAP;                         /**< The PIOPORCAP register captures the state of GPIO at power-on-reset or pin reset. Each bit represents the power-on reset state of one GPIO pin. [Reset by POR, RSTN], offset: 0x9C */
+  __I  uint32_t PIORESCAP;                         /**< The PIORESCAP0 register captures the state of GPIO port 0 when a reset other than a power-on reset or pin reset occurs. Each bit represents the reset state of one GPIO pin. [Reset by WDT, BOD, WAKEUP IO, ARM System reset ], offset: 0xA0 */
+       uint8_t RESERVED_6[12];
+  __IO uint32_t PDSLEEPCFG;                        /**< Controls the power to various modules in Low Power modes. [Reset by all reset sources, except ARM SystemReset], offset: 0xB0 */
+       uint8_t RESERVED_7[4];
+  __IO uint32_t PDRUNCFG;                          /**< Controls the power to various analog blocks. [Reset by all reset sources, except ARM SystemReset], offset: 0xB8 */
+  __I  uint32_t WAKEIOCAUSE;                       /**< Wake-up source from Power Down and Deep Power Down modes. Allow to identify the Wake-up source from Power-Down mode or Deep Power Down mode.[Reset by POR, RSTN, WDT ], offset: 0xBC */
+       uint8_t RESERVED_8[12];
+  __IO uint32_t CTRLNORST;                         /**< Extension of CTRL register, but never reset except by POR, offset: 0xCC */
+} PMC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- PMC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PMC_Register_Masks PMC Register Masks
+ * @{
+ */
+
+/*! @name CTRL - Power Management Control [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_CTRL_LPMODE_MASK                     (0x3U)
+#define PMC_CTRL_LPMODE_SHIFT                    (0U)
+/*! LPMODE - Power Mode Control. 00: Active; 01: Deep Sleep; 10: Power Down; 11: Deep Power Down.
+ */
+#define PMC_CTRL_LPMODE(x)                       (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_LPMODE_SHIFT)) & PMC_CTRL_LPMODE_MASK)
+#define PMC_CTRL_SYSTEMRESETENABLE_MASK          (0x4U)
+#define PMC_CTRL_SYSTEMRESETENABLE_SHIFT         (2U)
+/*! SYSTEMRESETENABLE - ARM system reset request enable. If set enables the ARM system reset to affect the system.
+ */
+#define PMC_CTRL_SYSTEMRESETENABLE(x)            (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_SYSTEMRESETENABLE_SHIFT)) & PMC_CTRL_SYSTEMRESETENABLE_MASK)
+#define PMC_CTRL_WDTRESETENABLE_MASK             (0x8U)
+#define PMC_CTRL_WDTRESETENABLE_SHIFT            (3U)
+/*! WDTRESETENABLE - Watchdog Timer reset enable. If set allow a watchdog timer reset event to affect the system.
+ */
+#define PMC_CTRL_WDTRESETENABLE(x)               (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_WDTRESETENABLE_SHIFT)) & PMC_CTRL_WDTRESETENABLE_MASK)
+#define PMC_CTRL_WAKUPRESETENABLE_MASK           (0x10U)
+#define PMC_CTRL_WAKUPRESETENABLE_SHIFT          (4U)
+/*! WAKUPRESETENABLE - Wake-up I/Os reset enable. When set, the I/O power domain is not shutoff in deep powerdown mode.
+ */
+#define PMC_CTRL_WAKUPRESETENABLE(x)             (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_WAKUPRESETENABLE_SHIFT)) & PMC_CTRL_WAKUPRESETENABLE_MASK)
+#define PMC_CTRL_NTAGWAKUPRESETENABLE_MASK       (0x20U)
+#define PMC_CTRL_NTAGWAKUPRESETENABLE_SHIFT      (5U)
+/*! NTAGWAKUPRESETENABLE - Wake-up NTAG reset enable. When set, the device can wake from deep power
+ *    down by edge on NTAG FD signal, even if I/O power domain is off (see WAKUPRESETENABLE). Note
+ *    that if I/O power domain is ON, wake-up by NTAG FD is enabled by default thus content of this
+ *    bit does not care. Do not set unless entering Deep Power Down.
+ */
+#define PMC_CTRL_NTAGWAKUPRESETENABLE(x)         (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_NTAGWAKUPRESETENABLE_SHIFT)) & PMC_CTRL_NTAGWAKUPRESETENABLE_MASK)
+#define PMC_CTRL_SELLDOVOLTAGE_MASK              (0x100U)
+#define PMC_CTRL_SELLDOVOLTAGE_SHIFT             (8U)
+/*! SELLDOVOLTAGE - 0 = all LDOs current output levels are determined by their associated VADJ
+ *    bitfield. 1 = all LDOs current output levels are determined by their associated VADJ_2 bitfield.
+ */
+#define PMC_CTRL_SELLDOVOLTAGE(x)                (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_SELLDOVOLTAGE_SHIFT)) & PMC_CTRL_SELLDOVOLTAGE_MASK)
+#define PMC_CTRL_SWRRESETENABLE_MASK             (0x200U)
+#define PMC_CTRL_SWRRESETENABLE_SHIFT            (9U)
+/*! SWRRESETENABLE - Software reset enable. If set enables the software reset to affect the system.
+ */
+#define PMC_CTRL_SWRRESETENABLE(x)               (((uint32_t)(((uint32_t)(x)) << PMC_CTRL_SWRRESETENABLE_SHIFT)) & PMC_CTRL_SWRRESETENABLE_MASK)
+/*! @} */
+
+/*! @name DCDC0 - DCDC control register (1st). This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_DCDC0_DCDC0_MASK                     (0xFFFFFFFFU)
+#define PMC_DCDC0_DCDC0_SHIFT                    (0U)
+/*! DCDC0 - DCDC control register (1st). This reigster is controlled by the boot code and the Low
+ *    power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_DCDC0_DCDC0(x)                       (((uint32_t)(((uint32_t)(x)) << PMC_DCDC0_DCDC0_SHIFT)) & PMC_DCDC0_DCDC0_MASK)
+/*! @} */
+
+/*! @name DCDC1 - DCDC control register (2nd). This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_DCDC1_DCDC1_MASK                     (0xFFFFFFFFU)
+#define PMC_DCDC1_DCDC1_SHIFT                    (0U)
+/*! DCDC1 - DCDC control register (2nd). This reigster is controlled by the boot code and the Low
+ *    power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_DCDC1_DCDC1(x)                       (((uint32_t)(((uint32_t)(x)) << PMC_DCDC1_DCDC1_SHIFT)) & PMC_DCDC1_DCDC1_MASK)
+/*! @} */
+
+/*! @name BIAS - Bias current source control register. This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_BIAS_BIAS_MASK                       (0xFFFFFFFFU)
+#define PMC_BIAS_BIAS_SHIFT                      (0U)
+/*! BIAS - Bias current source control register. This reigster is controlled by the boot code and
+ *    the Low power API software. [Reset by POR, RSTN, WDT ]
+ */
+#define PMC_BIAS_BIAS(x)                         (((uint32_t)(((uint32_t)(x)) << PMC_BIAS_BIAS_SHIFT)) & PMC_BIAS_BIAS_MASK)
+/*! @} */
+
+/*! @name LDOPMU - PMU & Always On domains LDO control. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOPMU_LDOPMU_MASK                   (0xFFFFFFFFU)
+#define PMC_LDOPMU_LDOPMU_SHIFT                  (0U)
+/*! LDOPMU - PMU & Always On domains LDO control. This reigster is controlled by the boot code and
+ *    the Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOPMU_LDOPMU(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_LDOPMU_LDOPMU_SHIFT)) & PMC_LDOPMU_LDOPMU_MASK)
+/*! @} */
+
+/*! @name LDOMEM - Memories LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOMEM_LDOMEM_MASK                   (0xFFFFFFFFU)
+#define PMC_LDOMEM_LDOMEM_SHIFT                  (0U)
+/*! LDOMEM - Memories LDO control register. This reigster is controlled by the boot code and the Low
+ *    power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOMEM_LDOMEM(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_LDOMEM_LDOMEM_SHIFT)) & PMC_LDOMEM_LDOMEM_MASK)
+/*! @} */
+
+/*! @name LDOCORE - Digital Core LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOCORE_LDOCORE_MASK                 (0xFFFFFFFFU)
+#define PMC_LDOCORE_LDOCORE_SHIFT                (0U)
+/*! LDOCORE - Digital Core LDO control register. This reigster is controlled by the boot code and
+ *    the Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOCORE_LDOCORE(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_LDOCORE_LDOCORE_SHIFT)) & PMC_LDOCORE_LDOCORE_MASK)
+/*! @} */
+
+/*! @name LDOFLASHNV - Flash LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOFLASHNV_LDOFLASHNV_MASK           (0xFFFFFFFFU)
+#define PMC_LDOFLASHNV_LDOFLASHNV_SHIFT          (0U)
+/*! LDOFLASHNV - Flash LDO control register. This reigster is controlled by the boot code and the
+ *    Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOFLASHNV_LDOFLASHNV(x)             (((uint32_t)(((uint32_t)(x)) << PMC_LDOFLASHNV_LDOFLASHNV_SHIFT)) & PMC_LDOFLASHNV_LDOFLASHNV_MASK)
+/*! @} */
+
+/*! @name LDOFLASHCORE - Flash Core LDO control register. This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOFLASHCORE_LDOFLASHCORE_MASK       (0xFFFFFFFFU)
+#define PMC_LDOFLASHCORE_LDOFLASHCORE_SHIFT      (0U)
+/*! LDOFLASHCORE - Flash Core LDO control register. This reigster is controlled by the boot code and
+ *    the Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOFLASHCORE_LDOFLASHCORE(x)         (((uint32_t)(((uint32_t)(x)) << PMC_LDOFLASHCORE_LDOFLASHCORE_SHIFT)) & PMC_LDOFLASHCORE_LDOFLASHCORE_MASK)
+/*! @} */
+
+/*! @name LDOADC - General Purpose ADC LDO control register This reigster is controlled by the boot code and the Low power API software. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_LDOADC_LDOADC_MASK                   (0xFFFFFFFFU)
+#define PMC_LDOADC_LDOADC_SHIFT                  (0U)
+/*! LDOADC - General Purpose ADC LDO control register This reigster is controlled by the boot code
+ *    and the Low power API software. [Reset by all reset sources, except ARM SystemReset]
+ */
+#define PMC_LDOADC_LDOADC(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_LDOADC_LDOADC_SHIFT)) & PMC_LDOADC_LDOADC_MASK)
+/*! @} */
+
+/*! @name BODVBAT - VBAT Brown Out Dectector control register This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_BODVBAT_TRIGLVL_MASK                 (0x1FU)
+#define PMC_BODVBAT_TRIGLVL_SHIFT                (0U)
+/*! TRIGLVL - BOD trigger level
+ */
+#define PMC_BODVBAT_TRIGLVL(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_BODVBAT_TRIGLVL_SHIFT)) & PMC_BODVBAT_TRIGLVL_MASK)
+#define PMC_BODVBAT_HYST_MASK                    (0x60U)
+#define PMC_BODVBAT_HYST_SHIFT                   (5U)
+/*! HYST - BOD Hysteresis control
+ */
+#define PMC_BODVBAT_HYST(x)                      (((uint32_t)(((uint32_t)(x)) << PMC_BODVBAT_HYST_SHIFT)) & PMC_BODVBAT_HYST_MASK)
+/*! @} */
+
+/*! @name FRO192M - High Speed FRO control register This reigster is controlled by the boot code and the Low power API software. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_FRO192M_DIVSEL_MASK                  (0x1F00000U)
+#define PMC_FRO192M_DIVSEL_SHIFT                 (20U)
+/*! DIVSEL - Mode of operation (which clock to output). Each bit enables a clocks as shown. Enables
+ *    are additive meaning that two or more clocks can be enabled together. xxxx1: 12MHz enabled;
+ *    xxx1x: 32MHz enabled; xx1xx: 48MHz enabled; x1xxx: Not applicable; 1xxxx: Not applicable.
+ */
+#define PMC_FRO192M_DIVSEL(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_FRO192M_DIVSEL_SHIFT)) & PMC_FRO192M_DIVSEL_MASK)
+/*! @} */
+
+/*! @name FRO1M - 1 MHz Free Running Oscillator control register. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_FRO1M_FREQSEL_MASK                   (0x7FU)
+#define PMC_FRO1M_FREQSEL_SHIFT                  (0U)
+/*! FREQSEL - Frequency trimming bits. This field is used to give accurate frequency for each
+ *    device. The required setting is based upon calibration data sotred in flash during device test. This
+ *    setting is applied by the clock driver function.
+ */
+#define PMC_FRO1M_FREQSEL(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_FRO1M_FREQSEL_SHIFT)) & PMC_FRO1M_FREQSEL_MASK)
+#define PMC_FRO1M_ATBCTRL_MASK                   (0x180U)
+#define PMC_FRO1M_ATBCTRL_SHIFT                  (7U)
+/*! ATBCTRL - Debug control bits to set the analog/digital test modes; only required for test purposes.
+ */
+#define PMC_FRO1M_ATBCTRL(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_FRO1M_ATBCTRL_SHIFT)) & PMC_FRO1M_ATBCTRL_MASK)
+#define PMC_FRO1M_DIVSEL_MASK                    (0x3E00U)
+#define PMC_FRO1M_DIVSEL_SHIFT                   (9U)
+/*! DIVSEL - Divider selection bits.
+ */
+#define PMC_FRO1M_DIVSEL(x)                      (((uint32_t)(((uint32_t)(x)) << PMC_FRO1M_DIVSEL_SHIFT)) & PMC_FRO1M_DIVSEL_MASK)
+/*! @} */
+
+/*! @name ANAMUXCOMP - Analog Comparator and Analog Mux control register. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_ANAMUXCOMP_COMP_HYST_MASK            (0x2U)
+#define PMC_ANAMUXCOMP_COMP_HYST_SHIFT           (1U)
+/*! COMP_HYST - Hysteris enabled in comparator when hyst = '1', no hysteresis when = '0'.
+ */
+#define PMC_ANAMUXCOMP_COMP_HYST(x)              (((uint32_t)(((uint32_t)(x)) << PMC_ANAMUXCOMP_COMP_HYST_SHIFT)) & PMC_ANAMUXCOMP_COMP_HYST_MASK)
+#define PMC_ANAMUXCOMP_COMP_INNINT_MASK          (0x4U)
+#define PMC_ANAMUXCOMP_COMP_INNINT_SHIFT         (2U)
+/*! COMP_INNINT - Voltage reference inn_int input is selected for _n comparator input when
+ *    sel_inn_int = 1 . This setting also requires PMU_BIASING to be active. Also flash biasing and DCDC
+ *    converter needs to be enabled. If this setting = '0' then _n input comes from device pins, based
+ *    on COMP_INPUTSWAP setting.
+ */
+#define PMC_ANAMUXCOMP_COMP_INNINT(x)            (((uint32_t)(((uint32_t)(x)) << PMC_ANAMUXCOMP_COMP_INNINT_SHIFT)) & PMC_ANAMUXCOMP_COMP_INNINT_MASK)
+#define PMC_ANAMUXCOMP_COMP_LOWPOWER_MASK        (0x8U)
+#define PMC_ANAMUXCOMP_COMP_LOWPOWER_SHIFT       (3U)
+/*! COMP_LOWPOWER - Comparator Low power mode enabled when set.
+ */
+#define PMC_ANAMUXCOMP_COMP_LOWPOWER(x)          (((uint32_t)(((uint32_t)(x)) << PMC_ANAMUXCOMP_COMP_LOWPOWER_SHIFT)) & PMC_ANAMUXCOMP_COMP_LOWPOWER_MASK)
+#define PMC_ANAMUXCOMP_COMP_INPUTSWAP_MASK       (0x10U)
+#define PMC_ANAMUXCOMP_COMP_INPUTSWAP_SHIFT      (4U)
+/*! COMP_INPUTSWAP - Input swap is enabled when set. Comparator{ _p, _n} ports are connected to
+ *    {ACM, ACP}. Otherwsie normal configuration occurs, {_p, _n} is connected to {ACP, ACM} .
+ */
+#define PMC_ANAMUXCOMP_COMP_INPUTSWAP(x)         (((uint32_t)(((uint32_t)(x)) << PMC_ANAMUXCOMP_COMP_INPUTSWAP_SHIFT)) & PMC_ANAMUXCOMP_COMP_INPUTSWAP_MASK)
+/*! @} */
+
+/*! @name PWRSWACK - Power Switch acknowledge. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_PWRSWACK_PDCOMM0_MASK                (0x2U)
+#define PMC_PWRSWACK_PDCOMM0_SHIFT               (1U)
+/*! PDCOMM0 - Comm0 (USART0, I2C0, SPI0) Power Domain power switch status.
+ */
+#define PMC_PWRSWACK_PDCOMM0(x)                  (((uint32_t)(((uint32_t)(x)) << PMC_PWRSWACK_PDCOMM0_SHIFT)) & PMC_PWRSWACK_PDCOMM0_MASK)
+#define PMC_PWRSWACK_PDSYSTEM_MASK               (0x4U)
+#define PMC_PWRSWACK_PDSYSTEM_SHIFT              (2U)
+/*! PDSYSTEM - System Power Domain power switch status.
+ */
+#define PMC_PWRSWACK_PDSYSTEM(x)                 (((uint32_t)(((uint32_t)(x)) << PMC_PWRSWACK_PDSYSTEM_SHIFT)) & PMC_PWRSWACK_PDSYSTEM_MASK)
+#define PMC_PWRSWACK_PDMCURETENTION_MASK         (0x8U)
+#define PMC_PWRSWACK_PDMCURETENTION_SHIFT        (3U)
+/*! PDMCURETENTION - MCU Retention Power Domain power switch status.
+ */
+#define PMC_PWRSWACK_PDMCURETENTION(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PWRSWACK_PDMCURETENTION_SHIFT)) & PMC_PWRSWACK_PDMCURETENTION_MASK)
+/*! @} */
+
+/*! @name DPDWKSRC - Power Down and Deep Power Down wake-up source. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_DPDWKSRC_PIO0_MASK                   (0x1U)
+#define PMC_DPDWKSRC_PIO0_SHIFT                  (0U)
+/*! PIO0 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO0: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO0(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO0_SHIFT)) & PMC_DPDWKSRC_PIO0_MASK)
+#define PMC_DPDWKSRC_PIO1_MASK                   (0x2U)
+#define PMC_DPDWKSRC_PIO1_SHIFT                  (1U)
+/*! PIO1 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO1: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO1(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO1_SHIFT)) & PMC_DPDWKSRC_PIO1_MASK)
+#define PMC_DPDWKSRC_PIO2_MASK                   (0x4U)
+#define PMC_DPDWKSRC_PIO2_SHIFT                  (2U)
+/*! PIO2 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO2: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO2(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO2_SHIFT)) & PMC_DPDWKSRC_PIO2_MASK)
+#define PMC_DPDWKSRC_PIO3_MASK                   (0x8U)
+#define PMC_DPDWKSRC_PIO3_SHIFT                  (3U)
+/*! PIO3 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO3: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO3(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO3_SHIFT)) & PMC_DPDWKSRC_PIO3_MASK)
+#define PMC_DPDWKSRC_PIO4_MASK                   (0x10U)
+#define PMC_DPDWKSRC_PIO4_SHIFT                  (4U)
+/*! PIO4 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO4: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO4(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO4_SHIFT)) & PMC_DPDWKSRC_PIO4_MASK)
+#define PMC_DPDWKSRC_PIO5_MASK                   (0x20U)
+#define PMC_DPDWKSRC_PIO5_SHIFT                  (5U)
+/*! PIO5 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO5: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO5(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO5_SHIFT)) & PMC_DPDWKSRC_PIO5_MASK)
+#define PMC_DPDWKSRC_PIO6_MASK                   (0x40U)
+#define PMC_DPDWKSRC_PIO6_SHIFT                  (6U)
+/*! PIO6 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO6: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO6(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO6_SHIFT)) & PMC_DPDWKSRC_PIO6_MASK)
+#define PMC_DPDWKSRC_PIO7_MASK                   (0x80U)
+#define PMC_DPDWKSRC_PIO7_SHIFT                  (7U)
+/*! PIO7 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO7: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO7(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO7_SHIFT)) & PMC_DPDWKSRC_PIO7_MASK)
+#define PMC_DPDWKSRC_PIO8_MASK                   (0x100U)
+#define PMC_DPDWKSRC_PIO8_SHIFT                  (8U)
+/*! PIO8 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO8: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO8(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO8_SHIFT)) & PMC_DPDWKSRC_PIO8_MASK)
+#define PMC_DPDWKSRC_PIO9_MASK                   (0x200U)
+#define PMC_DPDWKSRC_PIO9_SHIFT                  (9U)
+/*! PIO9 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO9: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO9(x)                     (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO9_SHIFT)) & PMC_DPDWKSRC_PIO9_MASK)
+#define PMC_DPDWKSRC_PIO10_MASK                  (0x400U)
+#define PMC_DPDWKSRC_PIO10_SHIFT                 (10U)
+/*! PIO10 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO10: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO10(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO10_SHIFT)) & PMC_DPDWKSRC_PIO10_MASK)
+#define PMC_DPDWKSRC_PIO11_MASK                  (0x800U)
+#define PMC_DPDWKSRC_PIO11_SHIFT                 (11U)
+/*! PIO11 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO11: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO11(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO11_SHIFT)) & PMC_DPDWKSRC_PIO11_MASK)
+#define PMC_DPDWKSRC_PIO12_MASK                  (0x1000U)
+#define PMC_DPDWKSRC_PIO12_SHIFT                 (12U)
+/*! PIO12 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO12: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO12(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO12_SHIFT)) & PMC_DPDWKSRC_PIO12_MASK)
+#define PMC_DPDWKSRC_PIO13_MASK                  (0x2000U)
+#define PMC_DPDWKSRC_PIO13_SHIFT                 (13U)
+/*! PIO13 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO13: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO13(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO13_SHIFT)) & PMC_DPDWKSRC_PIO13_MASK)
+#define PMC_DPDWKSRC_PIO14_MASK                  (0x4000U)
+#define PMC_DPDWKSRC_PIO14_SHIFT                 (14U)
+/*! PIO14 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO14: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO14(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO14_SHIFT)) & PMC_DPDWKSRC_PIO14_MASK)
+#define PMC_DPDWKSRC_PIO15_MASK                  (0x8000U)
+#define PMC_DPDWKSRC_PIO15_SHIFT                 (15U)
+/*! PIO15 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO15: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO15(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO15_SHIFT)) & PMC_DPDWKSRC_PIO15_MASK)
+#define PMC_DPDWKSRC_PIO16_MASK                  (0x10000U)
+#define PMC_DPDWKSRC_PIO16_SHIFT                 (16U)
+/*! PIO16 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO16: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO16(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO16_SHIFT)) & PMC_DPDWKSRC_PIO16_MASK)
+#define PMC_DPDWKSRC_PIO17_MASK                  (0x20000U)
+#define PMC_DPDWKSRC_PIO17_SHIFT                 (17U)
+/*! PIO17 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO17: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO17(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO17_SHIFT)) & PMC_DPDWKSRC_PIO17_MASK)
+#define PMC_DPDWKSRC_PIO18_MASK                  (0x40000U)
+#define PMC_DPDWKSRC_PIO18_SHIFT                 (18U)
+/*! PIO18 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO18: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO18(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO18_SHIFT)) & PMC_DPDWKSRC_PIO18_MASK)
+#define PMC_DPDWKSRC_PIO19_MASK                  (0x80000U)
+#define PMC_DPDWKSRC_PIO19_SHIFT                 (19U)
+/*! PIO19 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO19: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO19(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO19_SHIFT)) & PMC_DPDWKSRC_PIO19_MASK)
+#define PMC_DPDWKSRC_PIO20_MASK                  (0x100000U)
+#define PMC_DPDWKSRC_PIO20_SHIFT                 (20U)
+/*! PIO20 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO20: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO20(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO20_SHIFT)) & PMC_DPDWKSRC_PIO20_MASK)
+#define PMC_DPDWKSRC_PIO21_MASK                  (0x200000U)
+#define PMC_DPDWKSRC_PIO21_SHIFT                 (21U)
+/*! PIO21 - Enable / disable wakeup from Power down and Deep Power Down modes by GPIO21: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_PIO21(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_PIO21_SHIFT)) & PMC_DPDWKSRC_PIO21_MASK)
+#define PMC_DPDWKSRC_NTAG_FD_MASK                (0x400000U)
+#define PMC_DPDWKSRC_NTAG_FD_SHIFT               (22U)
+/*! NTAG_FD - Enable / disable wakeup from Power down and Deep Power Down modes by NTAG_FD: 0: Disable; 1: Enable.
+ */
+#define PMC_DPDWKSRC_NTAG_FD(x)                  (((uint32_t)(((uint32_t)(x)) << PMC_DPDWKSRC_NTAG_FD_SHIFT)) & PMC_DPDWKSRC_NTAG_FD_MASK)
+/*! @} */
+
+/*! @name STATUSPWR - Power OK and Ready signals from various analog modules (DCDC, LDO, ). [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_STATUSPWR_DCDCPWROK_MASK             (0x1U)
+#define PMC_STATUSPWR_DCDCPWROK_SHIFT            (0U)
+/*! DCDCPWROK - DCDC converter power OK
+ */
+#define PMC_STATUSPWR_DCDCPWROK(x)               (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_DCDCPWROK_SHIFT)) & PMC_STATUSPWR_DCDCPWROK_MASK)
+#define PMC_STATUSPWR_DCDCVXCTRLMON_MASK         (0x2U)
+#define PMC_STATUSPWR_DCDCVXCTRLMON_SHIFT        (1U)
+/*! DCDCVXCTRLMON - Picture of the DCDC output state.
+ */
+#define PMC_STATUSPWR_DCDCVXCTRLMON(x)           (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_DCDCVXCTRLMON_SHIFT)) & PMC_STATUSPWR_DCDCVXCTRLMON_MASK)
+#define PMC_STATUSPWR_LDOCOREPWROK_MASK          (0x4U)
+#define PMC_STATUSPWR_LDOCOREPWROK_SHIFT         (2U)
+/*! LDOCOREPWROK - CORE LDO power OK. Max switch on time 2us.
+ */
+#define PMC_STATUSPWR_LDOCOREPWROK(x)            (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_LDOCOREPWROK_SHIFT)) & PMC_STATUSPWR_LDOCOREPWROK_MASK)
+#define PMC_STATUSPWR_LDOFLASHNVPWROK_MASK       (0x8U)
+#define PMC_STATUSPWR_LDOFLASHNVPWROK_SHIFT      (3U)
+/*! LDOFLASHNVPWROK - Flash NV LDO power OK Max switch on time 20us.
+ */
+#define PMC_STATUSPWR_LDOFLASHNVPWROK(x)         (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_LDOFLASHNVPWROK_SHIFT)) & PMC_STATUSPWR_LDOFLASHNVPWROK_MASK)
+#define PMC_STATUSPWR_LDOFLASHCOREPWROK_MASK     (0x10U)
+#define PMC_STATUSPWR_LDOFLASHCOREPWROK_SHIFT    (4U)
+/*! LDOFLASHCOREPWROK - Flash Core LDO power OK Max switch on time should be considered as 10us.
+ */
+#define PMC_STATUSPWR_LDOFLASHCOREPWROK(x)       (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_LDOFLASHCOREPWROK_SHIFT)) & PMC_STATUSPWR_LDOFLASHCOREPWROK_MASK)
+#define PMC_STATUSPWR_LDOADC1V1PWROK_MASK        (0x20U)
+#define PMC_STATUSPWR_LDOADC1V1PWROK_SHIFT       (5U)
+/*! LDOADC1V1PWROK - General Purpose ADC LDO power OK. Max switch on time is 8us.
+ */
+#define PMC_STATUSPWR_LDOADC1V1PWROK(x)          (((uint32_t)(((uint32_t)(x)) << PMC_STATUSPWR_LDOADC1V1PWROK_SHIFT)) & PMC_STATUSPWR_LDOADC1V1PWROK_MASK)
+/*! @} */
+
+/*! @name STATUSCLK - FRO and XTAL status register. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_STATUSCLK_FRO192MCLKVALID_MASK       (0x1U)
+#define PMC_STATUSCLK_FRO192MCLKVALID_SHIFT      (0U)
+/*! FRO192MCLKVALID - High Speed FRO (FRO 192 MHz) clock valid signal. The FRO192M clock generator
+ *    also generates the FRO12M, FRO32M and FRO48M clock signals. These will also be valid when this
+ *    flag is assertetd.
+ */
+#define PMC_STATUSCLK_FRO192MCLKVALID(x)         (((uint32_t)(((uint32_t)(x)) << PMC_STATUSCLK_FRO192MCLKVALID_SHIFT)) & PMC_STATUSCLK_FRO192MCLKVALID_MASK)
+#define PMC_STATUSCLK_XTAL32KOK_MASK             (0x2U)
+#define PMC_STATUSCLK_XTAL32KOK_SHIFT            (1U)
+/*! XTAL32KOK - XTAL oscillator 32KHz OK signal. When the XTAL is stable, then a transition from 1
+ *    to 0 will indicate a clock issue. Can not be used to identify a stable clock during XTAL start.
+ */
+#define PMC_STATUSCLK_XTAL32KOK(x)               (((uint32_t)(((uint32_t)(x)) << PMC_STATUSCLK_XTAL32KOK_SHIFT)) & PMC_STATUSCLK_XTAL32KOK_MASK)
+#define PMC_STATUSCLK_FRO1MCLKVALID_MASK         (0x4U)
+#define PMC_STATUSCLK_FRO1MCLKVALID_SHIFT        (2U)
+/*! FRO1MCLKVALID - FRO 1 MHz CCO voltage detector output.
+ */
+#define PMC_STATUSCLK_FRO1MCLKVALID(x)           (((uint32_t)(((uint32_t)(x)) << PMC_STATUSCLK_FRO1MCLKVALID_SHIFT)) & PMC_STATUSCLK_FRO1MCLKVALID_MASK)
+/*! @} */
+
+/*! @name RESETCAUSE - Reset Cause register. [Reset by POR] */
+/*! @{ */
+#define PMC_RESETCAUSE_POR_MASK                  (0x1U)
+#define PMC_RESETCAUSE_POR_SHIFT                 (0U)
+/*! POR - 1 : The last chip reset was caused by a Power On Reset. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_POR(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_POR_SHIFT)) & PMC_RESETCAUSE_POR_MASK)
+#define PMC_RESETCAUSE_PADRESET_MASK             (0x2U)
+#define PMC_RESETCAUSE_PADRESET_SHIFT            (1U)
+/*! PADRESET - 1 : The last chip reset was caused by a Pad Reset. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_PADRESET(x)               (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_PADRESET_SHIFT)) & PMC_RESETCAUSE_PADRESET_MASK)
+#define PMC_RESETCAUSE_BODRESET_MASK             (0x4U)
+#define PMC_RESETCAUSE_BODRESET_SHIFT            (2U)
+/*! BODRESET - 1 : The last chip reset was caused by a Brown Out Detector. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_BODRESET(x)               (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_BODRESET_SHIFT)) & PMC_RESETCAUSE_BODRESET_MASK)
+#define PMC_RESETCAUSE_SYSTEMRESET_MASK          (0x8U)
+#define PMC_RESETCAUSE_SYSTEMRESET_SHIFT         (3U)
+/*! SYSTEMRESET - 1 : The last chip reset was caused by a System Reset requested by the ARM CPU. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_SYSTEMRESET(x)            (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_SYSTEMRESET_SHIFT)) & PMC_RESETCAUSE_SYSTEMRESET_MASK)
+#define PMC_RESETCAUSE_WDTRESET_MASK             (0x10U)
+#define PMC_RESETCAUSE_WDTRESET_SHIFT            (4U)
+/*! WDTRESET - 1 : The last chip reset was caused by the Watchdog Timer. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_WDTRESET(x)               (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_WDTRESET_SHIFT)) & PMC_RESETCAUSE_WDTRESET_MASK)
+#define PMC_RESETCAUSE_WAKEUPIORESET_MASK        (0x20U)
+#define PMC_RESETCAUSE_WAKEUPIORESET_SHIFT       (5U)
+/*! WAKEUPIORESET - 1 : The last chip reset was caused by a Wake-up I/O (GPIO or internal NTAG FD INT). Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_WAKEUPIORESET(x)          (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_WAKEUPIORESET_SHIFT)) & PMC_RESETCAUSE_WAKEUPIORESET_MASK)
+#define PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK      (0x40U)
+#define PMC_RESETCAUSE_WAKEUPPWDNRESET_SHIFT     (6U)
+/*! WAKEUPPWDNRESET - 1 : The last CPU reset was caused by a Wake-up from Power down (many sources
+ *    possible: timer, IO, ...). Write '1' to clear this bit. Check NVIC register if not waken-up by
+ *    IO (NVIC_GetPendingIRQ).
+ */
+#define PMC_RESETCAUSE_WAKEUPPWDNRESET(x)        (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_WAKEUPPWDNRESET_SHIFT)) & PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK)
+#define PMC_RESETCAUSE_SWRRESET_MASK             (0x80U)
+#define PMC_RESETCAUSE_SWRRESET_SHIFT            (7U)
+/*! SWRRESET - 1 : The last chip reset was caused by a Software. Write '1' to clear this bit.
+ */
+#define PMC_RESETCAUSE_SWRRESET(x)               (((uint32_t)(((uint32_t)(x)) << PMC_RESETCAUSE_SWRRESET_SHIFT)) & PMC_RESETCAUSE_SWRRESET_MASK)
+/*! @} */
+
+/*! @name AOREG0 - General purpose always on domain data storage. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_AOREG0_DATA31_0_MASK                 (0xFFFFFFFFU)
+#define PMC_AOREG0_DATA31_0_SHIFT                (0U)
+/*! DATA31_0 - General purpose always on domain data storage. Only writable 1 time after any chip
+ *    reset. After the 1st write, any further writes are blocked. After any chip reset the write block
+ *    is disabled until after next write. The chip reset includes POR, RSTIN, WDT reset, SW reset
+ *    and WAKEUP IO reset.
+ */
+#define PMC_AOREG0_DATA31_0(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_AOREG0_DATA31_0_SHIFT)) & PMC_AOREG0_DATA31_0_MASK)
+/*! @} */
+
+/*! @name AOREG1 - General purpose always on domain data storage. [Reset by POR, RSTN] */
+/*! @{ */
+#define PMC_AOREG1_DATA31_0_MASK                 (0xFFFFFFFFU)
+#define PMC_AOREG1_DATA31_0_SHIFT                (0U)
+/*! DATA31_0 - Reserved for use by NXP system software. General purpose always on domain data
+ *    storage. Only reinitialized on Power On Reset and RSTIN Pin reset.
+ */
+#define PMC_AOREG1_DATA31_0(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_AOREG1_DATA31_0_SHIFT)) & PMC_AOREG1_DATA31_0_MASK)
+/*! @} */
+
+/*! @name AOREG2 - General purpose always on domain data storage. [Reset by POR, RSTN] */
+/*! @{ */
+#define PMC_AOREG2_DATA31_0_MASK                 (0xFFFFFFFFU)
+#define PMC_AOREG2_DATA31_0_SHIFT                (0U)
+/*! DATA31_0 - General purpose always on domain data storage. Only reinitialized on Power On Reset and RSTIN Pin reset.
+ */
+#define PMC_AOREG2_DATA31_0(x)                   (((uint32_t)(((uint32_t)(x)) << PMC_AOREG2_DATA31_0_SHIFT)) & PMC_AOREG2_DATA31_0_MASK)
+/*! @} */
+
+/*! @name DPDCTRL - Configuration parameters for Power Down and Deep Power Down mode. [Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_DPDCTRL_XTAL32MSTARTENA_MASK         (0x1U)
+#define PMC_DPDCTRL_XTAL32MSTARTENA_SHIFT        (0U)
+/*! XTAL32MSTARTENA - Enable XTAL32MHz automatic start-up at power up & wake up from power down or
+ *    deep power down. Reset value is set by eFuse content. This register field will overwrite option
+ *    selected by eFuse content only if power-up or wake-up is NOT triggered by any kind of reset.
+ *    Thus if power-up or wake-up is triggered by I/O or a timer. On the contrary, if power-up or
+ *    wake-up is triggered by POR (typically during initial power up) or watchdog reset or SW reset or
+ *    PAD RSTN then eFuse content will reset this register and will be applied. Take care that
+ *    option selected here can by masked in power down by a register of SYSCON - XTAL32MCTRL - which is
+ *    itself reset after each deep power down. Thus SYSCON/XTAL32MCTRL will not have any impact
+ *    after a deep power down, only after a power down.
+ */
+#define PMC_DPDCTRL_XTAL32MSTARTENA(x)           (((uint32_t)(((uint32_t)(x)) << PMC_DPDCTRL_XTAL32MSTARTENA_SHIFT)) & PMC_DPDCTRL_XTAL32MSTARTENA_MASK)
+#define PMC_DPDCTRL_XTAL32MSTARTDLY_MASK         (0x6U)
+#define PMC_DPDCTRL_XTAL32MSTARTDLY_SHIFT        (1U)
+/*! XTAL32MSTARTDLY - Delay between xtal ldo enable and release of reset to xtal 0:16us 1:32us
+ *    2:48us 3:64us. LSB reset value set by efuse (wake-up by I/O only). This delay is applied within PMC
+ *    for Efuse controlled XTAL start and also BLE link layer for BLE controlled auto-start.
+ */
+#define PMC_DPDCTRL_XTAL32MSTARTDLY(x)           (((uint32_t)(((uint32_t)(x)) << PMC_DPDCTRL_XTAL32MSTARTDLY_SHIFT)) & PMC_DPDCTRL_XTAL32MSTARTDLY_MASK)
+/*! @} */
+
+/*! @name PIOPORCAP - The PIOPORCAP register captures the state of GPIO at power-on-reset or pin reset. Each bit represents the power-on reset state of one GPIO pin. [Reset by POR, RSTN] */
+/*! @{ */
+#define PMC_PIOPORCAP_GPIO_MASK                  (0x3FFFFFU)
+#define PMC_PIOPORCAP_GPIO_SHIFT                 (0U)
+/*! GPIO - Capture of GPIO values at power-on-reset and pin reset.
+ */
+#define PMC_PIOPORCAP_GPIO(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_PIOPORCAP_GPIO_SHIFT)) & PMC_PIOPORCAP_GPIO_MASK)
+#define PMC_PIOPORCAP_NTAG_FD_MASK               (0x400000U)
+#define PMC_PIOPORCAP_NTAG_FD_SHIFT              (22U)
+/*! NTAG_FD - Capture of NTAG_FD value at power-on-reset and pin reset.
+ */
+#define PMC_PIOPORCAP_NTAG_FD(x)                 (((uint32_t)(((uint32_t)(x)) << PMC_PIOPORCAP_NTAG_FD_SHIFT)) & PMC_PIOPORCAP_NTAG_FD_MASK)
+/*! @} */
+
+/*! @name PIORESCAP - The PIORESCAP0 register captures the state of GPIO port 0 when a reset other than a power-on reset or pin reset occurs. Each bit represents the reset state of one GPIO pin. [Reset by WDT, BOD, WAKEUP IO, ARM System reset ] */
+/*! @{ */
+#define PMC_PIORESCAP_GPIO_MASK                  (0x3FFFFFU)
+#define PMC_PIORESCAP_GPIO_SHIFT                 (0U)
+/*! GPIO - Capture of GPIO values.
+ */
+#define PMC_PIORESCAP_GPIO(x)                    (((uint32_t)(((uint32_t)(x)) << PMC_PIORESCAP_GPIO_SHIFT)) & PMC_PIORESCAP_GPIO_MASK)
+#define PMC_PIORESCAP_NTAG_FD_MASK               (0x400000U)
+#define PMC_PIORESCAP_NTAG_FD_SHIFT              (22U)
+/*! NTAG_FD - Capture of NTAG_FD value.
+ */
+#define PMC_PIORESCAP_NTAG_FD(x)                 (((uint32_t)(((uint32_t)(x)) << PMC_PIORESCAP_NTAG_FD_SHIFT)) & PMC_PIORESCAP_NTAG_FD_MASK)
+/*! @} */
+
+/*! @name PDSLEEPCFG - Controls the power to various modules in Low Power modes. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_PDSLEEPCFG_PDEN_DCDC_MASK            (0x1U)
+#define PMC_PDSLEEPCFG_PDEN_DCDC_SHIFT           (0U)
+/*! PDEN_DCDC - Controls DCDC power in Power down and Deep Power down modes. Automatically switched
+ *    off in deep power down. 0: DCDC is disabled in Power down and Deep Power down modes; 1: DCDC
+ *    is enabled in Power down and Deep Power down modes.
+ */
+#define PMC_PDSLEEPCFG_PDEN_DCDC(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_DCDC_SHIFT)) & PMC_PDSLEEPCFG_PDEN_DCDC_MASK)
+#define PMC_PDSLEEPCFG_PDEN_BIAS_MASK            (0x2U)
+#define PMC_PDSLEEPCFG_PDEN_BIAS_SHIFT           (1U)
+/*! PDEN_BIAS - Controls Bias power in Power down and Deep Power down modes. 0: Bias is disabled in
+ *    Power down and Deep Power down modes; 1: Bias is enabled in Power down and Deep Power down
+ *    modes.
+ */
+#define PMC_PDSLEEPCFG_PDEN_BIAS(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_BIAS_SHIFT)) & PMC_PDSLEEPCFG_PDEN_BIAS_MASK)
+#define PMC_PDSLEEPCFG_PDEN_LDO_MEM_MASK         (0x4U)
+#define PMC_PDSLEEPCFG_PDEN_LDO_MEM_SHIFT        (2U)
+/*! PDEN_LDO_MEM - Controls LDO memories power in Power down mode. Automatically switched off in
+ *    deep power down 0: LDO is disabled in Power down mode; 1: LDO is enabled in Power down mode.
+ */
+#define PMC_PDSLEEPCFG_PDEN_LDO_MEM(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_LDO_MEM_SHIFT)) & PMC_PDSLEEPCFG_PDEN_LDO_MEM_MASK)
+#define PMC_PDSLEEPCFG_PDEN_VBAT_BOD_MASK        (0x8U)
+#define PMC_PDSLEEPCFG_PDEN_VBAT_BOD_SHIFT       (3U)
+/*! PDEN_VBAT_BOD - Controls VBAT BOD power in Power down and Deep Power down modes. 0: VBAT BOD is
+ *    disabled in Power down and Deep Power down modes; 1: VBAT BOD is enabled in Power down and
+ *    Deep Power down modes.
+ */
+#define PMC_PDSLEEPCFG_PDEN_VBAT_BOD(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_VBAT_BOD_SHIFT)) & PMC_PDSLEEPCFG_PDEN_VBAT_BOD_MASK)
+#define PMC_PDSLEEPCFG_PDEN_FRO192M_MASK         (0x10U)
+#define PMC_PDSLEEPCFG_PDEN_FRO192M_SHIFT        (4U)
+/*! PDEN_FRO192M - Controls FRO192M power in Deep Sleep, Power down and Deep Power down modes. This
+ *    should be disabled before entering power down or deep power down mode. 0: FRO192M is disabled;
+ *    1: FRO192M is enabled.
+ */
+#define PMC_PDSLEEPCFG_PDEN_FRO192M(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_FRO192M_SHIFT)) & PMC_PDSLEEPCFG_PDEN_FRO192M_MASK)
+#define PMC_PDSLEEPCFG_PDEN_FRO1M_MASK           (0x20U)
+#define PMC_PDSLEEPCFG_PDEN_FRO1M_SHIFT          (5U)
+/*! PDEN_FRO1M - Controls FRO1M power in Deep Sleep, Power down and Deep Power down modes. This
+ *    should be disabled before entering power down (unless needed for low power timers) or deep power
+ *    down mode. 0: FRO1M is disabled; 1: FRO1M is enabled.
+ */
+#define PMC_PDSLEEPCFG_PDEN_FRO1M(x)             (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_FRO1M_SHIFT)) & PMC_PDSLEEPCFG_PDEN_FRO1M_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_FLASH_MASK        (0x40U)
+#define PMC_PDSLEEPCFG_PDEN_PD_FLASH_SHIFT       (6U)
+/*! PDEN_PD_FLASH - Enable Flash power domain Power Down mode (power shutoff) when entering in
+ *    DeepSleep. In PowerDown modes this domain is automatically powered off.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_FLASH(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_FLASH_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_FLASH_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_COMM0_MASK        (0x80U)
+#define PMC_PDSLEEPCFG_PDEN_PD_COMM0_SHIFT       (7U)
+/*! PDEN_PD_COMM0 - Enable Comm0 power domain (USART0, I2C0, SPI0) Power Down mode when entering in
+ *    Powerdown mode. In Deep power down it is disabled by hardware. In deep sleep it is always
+ *    enabled.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_COMM0(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_COMM0_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_COMM0_MASK)
+#define PMC_PDSLEEPCFG_EN_PDMCU_RETENTION_MASK   (0x100U)
+#define PMC_PDSLEEPCFG_EN_PDMCU_RETENTION_SHIFT  (8U)
+/*! EN_PDMCU_RETENTION - Enable MCU Power Domain state retention when entering in 'Powerdown' mode for modem and radio cal values
+ */
+#define PMC_PDSLEEPCFG_EN_PDMCU_RETENTION(x)     (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_EN_PDMCU_RETENTION_SHIFT)) & PMC_PDSLEEPCFG_EN_PDMCU_RETENTION_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM0_MASK         (0x400U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM0_SHIFT        (10U)
+/*! PDEN_PD_MEM0 - Enable Power Down mode of SRAM 0 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM0(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM0_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM0_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM1_MASK         (0x800U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM1_SHIFT        (11U)
+/*! PDEN_PD_MEM1 - Enable Power Down mode of SRAM 1 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM1(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM1_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM1_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM2_MASK         (0x1000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM2_SHIFT        (12U)
+/*! PDEN_PD_MEM2 - Enable Power Down mode of SRAM 2 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM2(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM2_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM2_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM3_MASK         (0x2000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM3_SHIFT        (13U)
+/*! PDEN_PD_MEM3 - Enable Power Down mode of SRAM 3 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM3(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM3_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM3_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM4_MASK         (0x4000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM4_SHIFT        (14U)
+/*! PDEN_PD_MEM4 - Enable Power Down mode of SRAM 4 when entering in Powerdown mode. Automatically switched off in deep power down.
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM4(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM4_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM4_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM5_MASK         (0x8000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM5_SHIFT        (15U)
+/*! PDEN_PD_MEM5 - Enable Power Down mode of SRAM 5 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM5(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM5_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM5_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM6_MASK         (0x10000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM6_SHIFT        (16U)
+/*! PDEN_PD_MEM6 - Enable Power Down mode of SRAM 6 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM6(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM6_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM6_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK         (0x20000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM7_SHIFT        (17U)
+/*! PDEN_PD_MEM7 - Enable Power Down mode of SRAM 7 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM7(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM7_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM8_MASK         (0x40000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM8_SHIFT        (18U)
+/*! PDEN_PD_MEM8 - Enable Power Down mode of SRAM 8 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM8(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM8_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM8_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM9_MASK         (0x80000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM9_SHIFT        (19U)
+/*! PDEN_PD_MEM9 - Enable Power Down mode of SRAM 9 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM9(x)           (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM9_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM9_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM10_MASK        (0x100000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM10_SHIFT       (20U)
+/*! PDEN_PD_MEM10 - Enable Power Down mode of SRAM 10 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM10(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM10_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM10_MASK)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM11_MASK        (0x200000U)
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM11_SHIFT       (21U)
+/*! PDEN_PD_MEM11 - Enable Power Down mode of SRAM 11 when entering in Powerdown mode. Automatically switched off in deep power down
+ */
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM11(x)          (((uint32_t)(((uint32_t)(x)) << PMC_PDSLEEPCFG_PDEN_PD_MEM11_SHIFT)) & PMC_PDSLEEPCFG_PDEN_PD_MEM11_MASK)
+/*! @} */
+
+/*! @name PDRUNCFG - Controls the power to various analog blocks. [Reset by all reset sources, except ARM SystemReset] */
+/*! @{ */
+#define PMC_PDRUNCFG_ENA_LDO_ADC_MASK            (0x400000U)
+#define PMC_PDRUNCFG_ENA_LDO_ADC_SHIFT           (22U)
+/*! ENA_LDO_ADC - LDO ADC enabled. See STATUSPWR.LDOADC1V1PWROK for when the power domain is ready.
+ */
+#define PMC_PDRUNCFG_ENA_LDO_ADC(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_LDO_ADC_SHIFT)) & PMC_PDRUNCFG_ENA_LDO_ADC_MASK)
+#define PMC_PDRUNCFG_ENA_BOD_MEM_MASK            (0x800000U)
+#define PMC_PDRUNCFG_ENA_BOD_MEM_SHIFT           (23U)
+/*! ENA_BOD_MEM - BOD MEM enabled.
+ */
+#define PMC_PDRUNCFG_ENA_BOD_MEM(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_BOD_MEM_SHIFT)) & PMC_PDRUNCFG_ENA_BOD_MEM_MASK)
+#define PMC_PDRUNCFG_ENA_BOD_CORE_MASK           (0x1000000U)
+#define PMC_PDRUNCFG_ENA_BOD_CORE_SHIFT          (24U)
+/*! ENA_BOD_CORE - BOD CORE enabled.
+ */
+#define PMC_PDRUNCFG_ENA_BOD_CORE(x)             (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_BOD_CORE_SHIFT)) & PMC_PDRUNCFG_ENA_BOD_CORE_MASK)
+#define PMC_PDRUNCFG_ENA_FRO32K_MASK             (0x2000000U)
+#define PMC_PDRUNCFG_ENA_FRO32K_SHIFT            (25U)
+/*! ENA_FRO32K - FRO32K enabled.
+ */
+#define PMC_PDRUNCFG_ENA_FRO32K(x)               (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_FRO32K_SHIFT)) & PMC_PDRUNCFG_ENA_FRO32K_MASK)
+#define PMC_PDRUNCFG_ENA_XTAL32K_MASK            (0x4000000U)
+#define PMC_PDRUNCFG_ENA_XTAL32K_SHIFT           (26U)
+/*! ENA_XTAL32K - XTAL32K enabled.
+ */
+#define PMC_PDRUNCFG_ENA_XTAL32K(x)              (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_XTAL32K_SHIFT)) & PMC_PDRUNCFG_ENA_XTAL32K_MASK)
+#define PMC_PDRUNCFG_ENA_ANA_COMP_MASK           (0x8000000U)
+#define PMC_PDRUNCFG_ENA_ANA_COMP_SHIFT          (27U)
+/*! ENA_ANA_COMP - Analog Comparator enabled.
+ */
+#define PMC_PDRUNCFG_ENA_ANA_COMP(x)             (((uint32_t)(((uint32_t)(x)) << PMC_PDRUNCFG_ENA_ANA_COMP_SHIFT)) & PMC_PDRUNCFG_ENA_ANA_COMP_MASK)
+/*! @} */
+
+/*! @name WAKEIOCAUSE - Wake-up source from Power Down and Deep Power Down modes. Allow to identify the Wake-up source from Power-Down mode or Deep Power Down mode.[Reset by POR, RSTN, WDT ] */
+/*! @{ */
+#define PMC_WAKEIOCAUSE_GPIO00_MASK              (0x1U)
+#define PMC_WAKEIOCAUSE_GPIO00_SHIFT             (0U)
+/*! GPIO00 - Wake up was triggered by GPIO 00
+ */
+#define PMC_WAKEIOCAUSE_GPIO00(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO00_SHIFT)) & PMC_WAKEIOCAUSE_GPIO00_MASK)
+#define PMC_WAKEIOCAUSE_GPIO01_MASK              (0x2U)
+#define PMC_WAKEIOCAUSE_GPIO01_SHIFT             (1U)
+/*! GPIO01 - Wake up was triggered by GPIO 01
+ */
+#define PMC_WAKEIOCAUSE_GPIO01(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO01_SHIFT)) & PMC_WAKEIOCAUSE_GPIO01_MASK)
+#define PMC_WAKEIOCAUSE_GPIO02_MASK              (0x4U)
+#define PMC_WAKEIOCAUSE_GPIO02_SHIFT             (2U)
+/*! GPIO02 - Wake up was triggered by GPIO 02
+ */
+#define PMC_WAKEIOCAUSE_GPIO02(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO02_SHIFT)) & PMC_WAKEIOCAUSE_GPIO02_MASK)
+#define PMC_WAKEIOCAUSE_GPIO03_MASK              (0x8U)
+#define PMC_WAKEIOCAUSE_GPIO03_SHIFT             (3U)
+/*! GPIO03 - Wake up was triggered by GPIO 03
+ */
+#define PMC_WAKEIOCAUSE_GPIO03(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO03_SHIFT)) & PMC_WAKEIOCAUSE_GPIO03_MASK)
+#define PMC_WAKEIOCAUSE_GPIO04_MASK              (0x10U)
+#define PMC_WAKEIOCAUSE_GPIO04_SHIFT             (4U)
+/*! GPIO04 - Wake up was triggered by GPIO 04
+ */
+#define PMC_WAKEIOCAUSE_GPIO04(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO04_SHIFT)) & PMC_WAKEIOCAUSE_GPIO04_MASK)
+#define PMC_WAKEIOCAUSE_GPIO05_MASK              (0x20U)
+#define PMC_WAKEIOCAUSE_GPIO05_SHIFT             (5U)
+/*! GPIO05 - Wake up was triggered by GPIO 05
+ */
+#define PMC_WAKEIOCAUSE_GPIO05(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO05_SHIFT)) & PMC_WAKEIOCAUSE_GPIO05_MASK)
+#define PMC_WAKEIOCAUSE_GPIO06_MASK              (0x40U)
+#define PMC_WAKEIOCAUSE_GPIO06_SHIFT             (6U)
+/*! GPIO06 - Wake up was triggered by GPIO 06
+ */
+#define PMC_WAKEIOCAUSE_GPIO06(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO06_SHIFT)) & PMC_WAKEIOCAUSE_GPIO06_MASK)
+#define PMC_WAKEIOCAUSE_GPIO07_MASK              (0x80U)
+#define PMC_WAKEIOCAUSE_GPIO07_SHIFT             (7U)
+/*! GPIO07 - Wake up was triggered by GPIO 07
+ */
+#define PMC_WAKEIOCAUSE_GPIO07(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO07_SHIFT)) & PMC_WAKEIOCAUSE_GPIO07_MASK)
+#define PMC_WAKEIOCAUSE_GPIO08_MASK              (0x100U)
+#define PMC_WAKEIOCAUSE_GPIO08_SHIFT             (8U)
+/*! GPIO08 - Wake up was triggered by GPIO 08
+ */
+#define PMC_WAKEIOCAUSE_GPIO08(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO08_SHIFT)) & PMC_WAKEIOCAUSE_GPIO08_MASK)
+#define PMC_WAKEIOCAUSE_GPIO09_MASK              (0x200U)
+#define PMC_WAKEIOCAUSE_GPIO09_SHIFT             (9U)
+/*! GPIO09 - Wake up was triggered by GPIO 09
+ */
+#define PMC_WAKEIOCAUSE_GPIO09(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO09_SHIFT)) & PMC_WAKEIOCAUSE_GPIO09_MASK)
+#define PMC_WAKEIOCAUSE_GPIO10_MASK              (0x400U)
+#define PMC_WAKEIOCAUSE_GPIO10_SHIFT             (10U)
+/*! GPIO10 - Wake up was triggered by GPIO 10
+ */
+#define PMC_WAKEIOCAUSE_GPIO10(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO10_SHIFT)) & PMC_WAKEIOCAUSE_GPIO10_MASK)
+#define PMC_WAKEIOCAUSE_GPIO11_MASK              (0x800U)
+#define PMC_WAKEIOCAUSE_GPIO11_SHIFT             (11U)
+/*! GPIO11 - Wake up was triggered by GPIO 11
+ */
+#define PMC_WAKEIOCAUSE_GPIO11(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO11_SHIFT)) & PMC_WAKEIOCAUSE_GPIO11_MASK)
+#define PMC_WAKEIOCAUSE_GPIO12_MASK              (0x1000U)
+#define PMC_WAKEIOCAUSE_GPIO12_SHIFT             (12U)
+/*! GPIO12 - Wake up was triggered by GPIO 12
+ */
+#define PMC_WAKEIOCAUSE_GPIO12(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO12_SHIFT)) & PMC_WAKEIOCAUSE_GPIO12_MASK)
+#define PMC_WAKEIOCAUSE_GPIO13_MASK              (0x2000U)
+#define PMC_WAKEIOCAUSE_GPIO13_SHIFT             (13U)
+/*! GPIO13 - Wake up was triggered by GPIO 13
+ */
+#define PMC_WAKEIOCAUSE_GPIO13(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO13_SHIFT)) & PMC_WAKEIOCAUSE_GPIO13_MASK)
+#define PMC_WAKEIOCAUSE_GPIO14_MASK              (0x4000U)
+#define PMC_WAKEIOCAUSE_GPIO14_SHIFT             (14U)
+/*! GPIO14 - Wake up was triggered by GPIO 14
+ */
+#define PMC_WAKEIOCAUSE_GPIO14(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO14_SHIFT)) & PMC_WAKEIOCAUSE_GPIO14_MASK)
+#define PMC_WAKEIOCAUSE_GPIO15_MASK              (0x8000U)
+#define PMC_WAKEIOCAUSE_GPIO15_SHIFT             (15U)
+/*! GPIO15 - Wake up was triggered by GPIO 15
+ */
+#define PMC_WAKEIOCAUSE_GPIO15(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO15_SHIFT)) & PMC_WAKEIOCAUSE_GPIO15_MASK)
+#define PMC_WAKEIOCAUSE_GPIO16_MASK              (0x10000U)
+#define PMC_WAKEIOCAUSE_GPIO16_SHIFT             (16U)
+/*! GPIO16 - Wake up was triggered by GPIO 16
+ */
+#define PMC_WAKEIOCAUSE_GPIO16(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO16_SHIFT)) & PMC_WAKEIOCAUSE_GPIO16_MASK)
+#define PMC_WAKEIOCAUSE_GPIO17_MASK              (0x20000U)
+#define PMC_WAKEIOCAUSE_GPIO17_SHIFT             (17U)
+/*! GPIO17 - Wake up was triggered by GPIO 17
+ */
+#define PMC_WAKEIOCAUSE_GPIO17(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO17_SHIFT)) & PMC_WAKEIOCAUSE_GPIO17_MASK)
+#define PMC_WAKEIOCAUSE_GPIO18_MASK              (0x40000U)
+#define PMC_WAKEIOCAUSE_GPIO18_SHIFT             (18U)
+/*! GPIO18 - Wake up was triggered by GPIO 18
+ */
+#define PMC_WAKEIOCAUSE_GPIO18(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO18_SHIFT)) & PMC_WAKEIOCAUSE_GPIO18_MASK)
+#define PMC_WAKEIOCAUSE_GPIO19_MASK              (0x80000U)
+#define PMC_WAKEIOCAUSE_GPIO19_SHIFT             (19U)
+/*! GPIO19 - Wake up was triggered by GPIO 19
+ */
+#define PMC_WAKEIOCAUSE_GPIO19(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO19_SHIFT)) & PMC_WAKEIOCAUSE_GPIO19_MASK)
+#define PMC_WAKEIOCAUSE_GPIO20_MASK              (0x100000U)
+#define PMC_WAKEIOCAUSE_GPIO20_SHIFT             (20U)
+/*! GPIO20 - Wake up was triggered by GPIO 20
+ */
+#define PMC_WAKEIOCAUSE_GPIO20(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO20_SHIFT)) & PMC_WAKEIOCAUSE_GPIO20_MASK)
+#define PMC_WAKEIOCAUSE_GPIO21_MASK              (0x200000U)
+#define PMC_WAKEIOCAUSE_GPIO21_SHIFT             (21U)
+/*! GPIO21 - Wake up was triggered by GPIO 21
+ */
+#define PMC_WAKEIOCAUSE_GPIO21(x)                (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_GPIO21_SHIFT)) & PMC_WAKEIOCAUSE_GPIO21_MASK)
+#define PMC_WAKEIOCAUSE_NTAG_FD_MASK             (0x400000U)
+#define PMC_WAKEIOCAUSE_NTAG_FD_SHIFT            (22U)
+/*! NTAG_FD - Wake up was triggered by NTAG FD
+ */
+#define PMC_WAKEIOCAUSE_NTAG_FD(x)               (((uint32_t)(((uint32_t)(x)) << PMC_WAKEIOCAUSE_NTAG_FD_SHIFT)) & PMC_WAKEIOCAUSE_NTAG_FD_MASK)
+/*! @} */
+
+/*! @name CTRLNORST - Extension of CTRL register, but never reset except by POR */
+/*! @{ */
+#define PMC_CTRLNORST_FASTLDOENABLE_MASK         (0x7U)
+#define PMC_CTRLNORST_FASTLDOENABLE_SHIFT        (0U)
+/*! FASTLDOENABLE - Fast LDO wake-up enable. 3 bits for the different wake-up sources: {generic
+ *    async wake up event as selected by SLEEPCON/STARTER0&1, IO wake-up event, RSTN pad event}. If
+ *    required, this field should only be managed by the Low power driver software.
+ */
+#define PMC_CTRLNORST_FASTLDOENABLE(x)           (((uint32_t)(((uint32_t)(x)) << PMC_CTRLNORST_FASTLDOENABLE_SHIFT)) & PMC_CTRLNORST_FASTLDOENABLE_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group PMC_Register_Masks */
+
+
+/* PMC - Peripheral instance base addresses */
+/** Peripheral PMC base address */
+#define PMC_BASE                                 (0x40012000u)
+/** Peripheral PMC base pointer */
+#define PMC                                      ((PMC_Type *)PMC_BASE)
+/** Array initializer of PMC peripheral base addresses */
+#define PMC_BASE_ADDRS                           { PMC_BASE }
+/** Array initializer of PMC peripheral base pointers */
+#define PMC_BASE_PTRS                            { PMC }
+
+/*!
+ * @}
+ */ /* end of group PMC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- PWM Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PWM_Peripheral_Access_Layer PWM Peripheral Access Layer
+ * @{
+ */
+
+/** PWM - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL0;                             /**< PWM 1st Control Register (Channel 0 to Channel 10) for channel enables and interrupt enables. Note if all interrupts are enabled with short period timings it will not be possible to manage all the interrupts., offset: 0x0 */
+  __IO uint32_t CTRL1;                             /**< PWM 2nd Control Register (Channel 0 to Channel 10) for channel polarity and output state for a disabled channel., offset: 0x4 */
+  __IO uint32_t PSCL01;                            /**< PWM Channels 0 & 1 prescalers, offset: 0x8 */
+  __IO uint32_t PSCL23;                            /**< PWM Channels 2 & 3 prescalers, offset: 0xC */
+  __IO uint32_t PSCL45;                            /**< PWM Channels 4 & 5 prescalers, offset: 0x10 */
+  __IO uint32_t PSCL67;                            /**< PWM Channels 6 & 7 prescalers, offset: 0x14 */
+  __IO uint32_t PSCL89;                            /**< PWM Channels 8 & 9 prescalers, offset: 0x18 */
+  __IO uint32_t PSCL1011;                          /**< PWM Channel 10 prescaler, offset: 0x1C */
+  __IO uint32_t PCP0;                              /**< PWM Channel 0 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x20 */
+  __IO uint32_t PCP1;                              /**< PWM Channel 1 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x24 */
+  __IO uint32_t PCP2;                              /**< PWM Channel 2 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x28 */
+  __IO uint32_t PCP3;                              /**< PWM Channel 3 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x2C */
+  __IO uint32_t PCP4;                              /**< PWM Channel 4 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x30 */
+  __IO uint32_t PCP5;                              /**< PWM Channel 5 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x34 */
+  __IO uint32_t PCP6;                              /**< PWM Channel 6 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x38 */
+  __IO uint32_t PCP7;                              /**< PWM Channel 7 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x3C */
+  __IO uint32_t PCP8;                              /**< PWM Channel 8 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x40 */
+  __IO uint32_t PCP9;                              /**< PWM Channel 9 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x44 */
+  __IO uint32_t PCP10;                             /**< PWM Channel 10 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached all PWM outputs will change on next counter decrement and be stable from 'Compare-1' to 0., offset: 0x48 */
+  __IO uint32_t PST0;                              /**< PWM 1st Status Register (Channel 0 to Channel 3), offset: 0x4C */
+  __IO uint32_t PST1;                              /**< PWM 2nd Status Register (Channel 4 to Channel 7), offset: 0x50 */
+  __IO uint32_t PST2;                              /**< PWM 3rd Status Register (Channel 8 to Channel 10), offset: 0x54 */
+       uint8_t RESERVED_0[4004];
+  __I  uint32_t MODULE_ID;                         /**< PWM Module Identifier ('PW' in ASCII), offset: 0xFFC */
+} PWM_Type;
+
+/* ----------------------------------------------------------------------------
+   -- PWM Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup PWM_Register_Masks PWM Register Masks
+ * @{
+ */
+
+/*! @name CTRL0 - PWM 1st Control Register (Channel 0 to Channel 10) for channel enables and interrupt enables. Note if all interrupts are enabled with short period timings it will not be possible to manage all the interrupts. */
+/*! @{ */
+#define PWM_CTRL0_PWM_EN_0_MASK                  (0x1U)
+#define PWM_CTRL0_PWM_EN_0_SHIFT                 (0U)
+/*! PWM_EN_0 - PWM channel 0 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_0(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_0_SHIFT)) & PWM_CTRL0_PWM_EN_0_MASK)
+#define PWM_CTRL0_PWM_EN_1_MASK                  (0x2U)
+#define PWM_CTRL0_PWM_EN_1_SHIFT                 (1U)
+/*! PWM_EN_1 - PWM channel 1 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_1(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_1_SHIFT)) & PWM_CTRL0_PWM_EN_1_MASK)
+#define PWM_CTRL0_PWM_EN_2_MASK                  (0x4U)
+#define PWM_CTRL0_PWM_EN_2_SHIFT                 (2U)
+/*! PWM_EN_2 - PWM channel 2 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_2(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_2_SHIFT)) & PWM_CTRL0_PWM_EN_2_MASK)
+#define PWM_CTRL0_PWM_EN_3_MASK                  (0x8U)
+#define PWM_CTRL0_PWM_EN_3_SHIFT                 (3U)
+/*! PWM_EN_3 - PWM channel 3 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_3(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_3_SHIFT)) & PWM_CTRL0_PWM_EN_3_MASK)
+#define PWM_CTRL0_PWM_EN_4_MASK                  (0x10U)
+#define PWM_CTRL0_PWM_EN_4_SHIFT                 (4U)
+/*! PWM_EN_4 - PWM channel 4 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_4(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_4_SHIFT)) & PWM_CTRL0_PWM_EN_4_MASK)
+#define PWM_CTRL0_PWM_EN_5_MASK                  (0x20U)
+#define PWM_CTRL0_PWM_EN_5_SHIFT                 (5U)
+/*! PWM_EN_5 - PWM channel 5 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_5(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_5_SHIFT)) & PWM_CTRL0_PWM_EN_5_MASK)
+#define PWM_CTRL0_PWM_EN_6_MASK                  (0x40U)
+#define PWM_CTRL0_PWM_EN_6_SHIFT                 (6U)
+/*! PWM_EN_6 - PWM channel 6 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_6(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_6_SHIFT)) & PWM_CTRL0_PWM_EN_6_MASK)
+#define PWM_CTRL0_PWM_EN_7_MASK                  (0x80U)
+#define PWM_CTRL0_PWM_EN_7_SHIFT                 (7U)
+/*! PWM_EN_7 - PWM channel 7 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_7(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_7_SHIFT)) & PWM_CTRL0_PWM_EN_7_MASK)
+#define PWM_CTRL0_PWM_EN_8_MASK                  (0x100U)
+#define PWM_CTRL0_PWM_EN_8_SHIFT                 (8U)
+/*! PWM_EN_8 - PWM channel 8 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_8(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_8_SHIFT)) & PWM_CTRL0_PWM_EN_8_MASK)
+#define PWM_CTRL0_PWM_EN_9_MASK                  (0x200U)
+#define PWM_CTRL0_PWM_EN_9_SHIFT                 (9U)
+/*! PWM_EN_9 - PWM channel 9 enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_PWM_EN_9(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_9_SHIFT)) & PWM_CTRL0_PWM_EN_9_MASK)
+#define PWM_CTRL0_PWM_EN_10_MASK                 (0x400U)
+#define PWM_CTRL0_PWM_EN_10_SHIFT                (10U)
+/*! PWM_EN_10 - PWM channel 10 enable. 0 = Disable / 1 = Enable. Note, this enables the common PWM
+ *    mode where PWM10 will be routed to all PWM channels.
+ */
+#define PWM_CTRL0_PWM_EN_10(x)                   (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_PWM_EN_10_SHIFT)) & PWM_CTRL0_PWM_EN_10_MASK)
+#define PWM_CTRL0_INT_EN_0_MASK                  (0x10000U)
+#define PWM_CTRL0_INT_EN_0_SHIFT                 (16U)
+/*! INT_EN_0 - PWM channel 0 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_0(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_0_SHIFT)) & PWM_CTRL0_INT_EN_0_MASK)
+#define PWM_CTRL0_INT_EN_1_MASK                  (0x20000U)
+#define PWM_CTRL0_INT_EN_1_SHIFT                 (17U)
+/*! INT_EN_1 - PWM channel 1 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_1(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_1_SHIFT)) & PWM_CTRL0_INT_EN_1_MASK)
+#define PWM_CTRL0_INT_EN_2_MASK                  (0x40000U)
+#define PWM_CTRL0_INT_EN_2_SHIFT                 (18U)
+/*! INT_EN_2 - PWM channel 2 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_2(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_2_SHIFT)) & PWM_CTRL0_INT_EN_2_MASK)
+#define PWM_CTRL0_INT_EN_3_MASK                  (0x80000U)
+#define PWM_CTRL0_INT_EN_3_SHIFT                 (19U)
+/*! INT_EN_3 - PWM channel 3 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_3(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_3_SHIFT)) & PWM_CTRL0_INT_EN_3_MASK)
+#define PWM_CTRL0_INT_EN_4_MASK                  (0x100000U)
+#define PWM_CTRL0_INT_EN_4_SHIFT                 (20U)
+/*! INT_EN_4 - PWM channel 4 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_4(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_4_SHIFT)) & PWM_CTRL0_INT_EN_4_MASK)
+#define PWM_CTRL0_INT_EN_5_MASK                  (0x200000U)
+#define PWM_CTRL0_INT_EN_5_SHIFT                 (21U)
+/*! INT_EN_5 - PWM channel 5 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_5(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_5_SHIFT)) & PWM_CTRL0_INT_EN_5_MASK)
+#define PWM_CTRL0_INT_EN_6_MASK                  (0x400000U)
+#define PWM_CTRL0_INT_EN_6_SHIFT                 (22U)
+/*! INT_EN_6 - PWM channel 6 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_6(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_6_SHIFT)) & PWM_CTRL0_INT_EN_6_MASK)
+#define PWM_CTRL0_INT_EN_7_MASK                  (0x800000U)
+#define PWM_CTRL0_INT_EN_7_SHIFT                 (23U)
+/*! INT_EN_7 - PWM channel 7 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_7(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_7_SHIFT)) & PWM_CTRL0_INT_EN_7_MASK)
+#define PWM_CTRL0_INT_EN_8_MASK                  (0x1000000U)
+#define PWM_CTRL0_INT_EN_8_SHIFT                 (24U)
+/*! INT_EN_8 - PWM channel 8 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_8(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_8_SHIFT)) & PWM_CTRL0_INT_EN_8_MASK)
+#define PWM_CTRL0_INT_EN_9_MASK                  (0x2000000U)
+#define PWM_CTRL0_INT_EN_9_SHIFT                 (25U)
+/*! INT_EN_9 - PWM channel 9 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_9(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_9_SHIFT)) & PWM_CTRL0_INT_EN_9_MASK)
+#define PWM_CTRL0_INT_EN_10_MASK                 (0x4000000U)
+#define PWM_CTRL0_INT_EN_10_SHIFT                (26U)
+/*! INT_EN_10 - PWM channel 10 interrupt enable. 0 = Disable / 1 = Enable.
+ */
+#define PWM_CTRL0_INT_EN_10(x)                   (((uint32_t)(((uint32_t)(x)) << PWM_CTRL0_INT_EN_10_SHIFT)) & PWM_CTRL0_INT_EN_10_MASK)
+/*! @} */
+
+/*! @name CTRL1 - PWM 2nd Control Register (Channel 0 to Channel 10) for channel polarity and output state for a disabled channel. */
+/*! @{ */
+#define PWM_CTRL1_POL_0_MASK                     (0x1U)
+#define PWM_CTRL1_POL_0_SHIFT                    (0U)
+/*! POL_0 - PWM channel 0 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_0(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_0_SHIFT)) & PWM_CTRL1_POL_0_MASK)
+#define PWM_CTRL1_POL_1_MASK                     (0x2U)
+#define PWM_CTRL1_POL_1_SHIFT                    (1U)
+/*! POL_1 - PWM channel 1 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_1(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_1_SHIFT)) & PWM_CTRL1_POL_1_MASK)
+#define PWM_CTRL1_POL_2_MASK                     (0x4U)
+#define PWM_CTRL1_POL_2_SHIFT                    (2U)
+/*! POL_2 - PWM channel 2 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_2(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_2_SHIFT)) & PWM_CTRL1_POL_2_MASK)
+#define PWM_CTRL1_POL_3_MASK                     (0x8U)
+#define PWM_CTRL1_POL_3_SHIFT                    (3U)
+/*! POL_3 - PWM channel 3 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_3(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_3_SHIFT)) & PWM_CTRL1_POL_3_MASK)
+#define PWM_CTRL1_POL_4_MASK                     (0x10U)
+#define PWM_CTRL1_POL_4_SHIFT                    (4U)
+/*! POL_4 - PWM channel 4 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_4(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_4_SHIFT)) & PWM_CTRL1_POL_4_MASK)
+#define PWM_CTRL1_POL_5_MASK                     (0x20U)
+#define PWM_CTRL1_POL_5_SHIFT                    (5U)
+/*! POL_5 - PWM channel 5 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_5(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_5_SHIFT)) & PWM_CTRL1_POL_5_MASK)
+#define PWM_CTRL1_POL_6_MASK                     (0x40U)
+#define PWM_CTRL1_POL_6_SHIFT                    (6U)
+/*! POL_6 - PWM channel 6 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_6(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_6_SHIFT)) & PWM_CTRL1_POL_6_MASK)
+#define PWM_CTRL1_POL_7_MASK                     (0x80U)
+#define PWM_CTRL1_POL_7_SHIFT                    (7U)
+/*! POL_7 - PWM channel 7 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_7(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_7_SHIFT)) & PWM_CTRL1_POL_7_MASK)
+#define PWM_CTRL1_POL_8_MASK                     (0x100U)
+#define PWM_CTRL1_POL_8_SHIFT                    (8U)
+/*! POL_8 - PWM channel 8 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_8(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_8_SHIFT)) & PWM_CTRL1_POL_8_MASK)
+#define PWM_CTRL1_POL_9_MASK                     (0x200U)
+#define PWM_CTRL1_POL_9_SHIFT                    (9U)
+/*! POL_9 - PWM channel 9 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_9(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_9_SHIFT)) & PWM_CTRL1_POL_9_MASK)
+#define PWM_CTRL1_POL_10_MASK                    (0x400U)
+#define PWM_CTRL1_POL_10_SHIFT                   (10U)
+/*! POL_10 - PWM channel 10 waveform Polarity control. 0: Set high on compare match, set low at the
+ *    end of PWM period. 1: Set low on compare match, set high at the end of PWM period
+ */
+#define PWM_CTRL1_POL_10(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_POL_10_SHIFT)) & PWM_CTRL1_POL_10_MASK)
+#define PWM_CTRL1_DIS_LEVEL_0_MASK               (0x10000U)
+#define PWM_CTRL1_DIS_LEVEL_0_SHIFT              (16U)
+/*! DIS_LEVEL_0 - PWM channel 0 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_0(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_0_SHIFT)) & PWM_CTRL1_DIS_LEVEL_0_MASK)
+#define PWM_CTRL1_DIS_LEVEL_1_MASK               (0x20000U)
+#define PWM_CTRL1_DIS_LEVEL_1_SHIFT              (17U)
+/*! DIS_LEVEL_1 - PWM channel 1 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_1(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_1_SHIFT)) & PWM_CTRL1_DIS_LEVEL_1_MASK)
+#define PWM_CTRL1_DIS_LEVEL_2_MASK               (0x40000U)
+#define PWM_CTRL1_DIS_LEVEL_2_SHIFT              (18U)
+/*! DIS_LEVEL_2 - PWM channel 2 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_2(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_2_SHIFT)) & PWM_CTRL1_DIS_LEVEL_2_MASK)
+#define PWM_CTRL1_DIS_LEVEL_3_MASK               (0x80000U)
+#define PWM_CTRL1_DIS_LEVEL_3_SHIFT              (19U)
+/*! DIS_LEVEL_3 - PWM channel 3 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_3(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_3_SHIFT)) & PWM_CTRL1_DIS_LEVEL_3_MASK)
+#define PWM_CTRL1_DIS_LEVEL_4_MASK               (0x100000U)
+#define PWM_CTRL1_DIS_LEVEL_4_SHIFT              (20U)
+/*! DIS_LEVEL_4 - PWM channel 4 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_4(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_4_SHIFT)) & PWM_CTRL1_DIS_LEVEL_4_MASK)
+#define PWM_CTRL1_DIS_LEVEL_5_MASK               (0x200000U)
+#define PWM_CTRL1_DIS_LEVEL_5_SHIFT              (21U)
+/*! DIS_LEVEL_5 - PWM channel 5 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_5(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_5_SHIFT)) & PWM_CTRL1_DIS_LEVEL_5_MASK)
+#define PWM_CTRL1_DIS_LEVEL_6_MASK               (0x400000U)
+#define PWM_CTRL1_DIS_LEVEL_6_SHIFT              (22U)
+/*! DIS_LEVEL_6 - PWM channel 6 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_6(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_6_SHIFT)) & PWM_CTRL1_DIS_LEVEL_6_MASK)
+#define PWM_CTRL1_DIS_LEVEL_7_MASK               (0x800000U)
+#define PWM_CTRL1_DIS_LEVEL_7_SHIFT              (23U)
+/*! DIS_LEVEL_7 - PWM channel 7 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_7(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_7_SHIFT)) & PWM_CTRL1_DIS_LEVEL_7_MASK)
+#define PWM_CTRL1_DIS_LEVEL_8_MASK               (0x1000000U)
+#define PWM_CTRL1_DIS_LEVEL_8_SHIFT              (24U)
+/*! DIS_LEVEL_8 - PWM channel 8 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_8(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_8_SHIFT)) & PWM_CTRL1_DIS_LEVEL_8_MASK)
+#define PWM_CTRL1_DIS_LEVEL_9_MASK               (0x2000000U)
+#define PWM_CTRL1_DIS_LEVEL_9_SHIFT              (25U)
+/*! DIS_LEVEL_9 - PWM channel 9 output level when PWM channel 0 is disable. 0 = Low Level / 1 = High Level.
+ */
+#define PWM_CTRL1_DIS_LEVEL_9(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_CTRL1_DIS_LEVEL_9_SHIFT)) & PWM_CTRL1_DIS_LEVEL_9_MASK)
+/*! @} */
+
+/*! @name PSCL01 - PWM Channels 0 & 1 prescalers */
+/*! @{ */
+#define PWM_PSCL01_PSCL_0_MASK                   (0x3FFU)
+#define PWM_PSCL01_PSCL_0_SHIFT                  (0U)
+/*! PSCL_0 - PWM channel 0 prescaler. The output frequency equals to clk/(PSCL_0 + 1)
+ */
+#define PWM_PSCL01_PSCL_0(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL01_PSCL_0_SHIFT)) & PWM_PSCL01_PSCL_0_MASK)
+#define PWM_PSCL01_PSCL_1_MASK                   (0x3FF0000U)
+#define PWM_PSCL01_PSCL_1_SHIFT                  (16U)
+/*! PSCL_1 - PWM channel 1 prescaler. The output frequency equals to clk/(PSCL_1 + 1)
+ */
+#define PWM_PSCL01_PSCL_1(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL01_PSCL_1_SHIFT)) & PWM_PSCL01_PSCL_1_MASK)
+/*! @} */
+
+/*! @name PSCL23 - PWM Channels 2 & 3 prescalers */
+/*! @{ */
+#define PWM_PSCL23_PSCL_2_MASK                   (0x3FFU)
+#define PWM_PSCL23_PSCL_2_SHIFT                  (0U)
+/*! PSCL_2 - PWM channel 2 prescaler. The output frequency equals to clk/(PSCL_2 + 1)
+ */
+#define PWM_PSCL23_PSCL_2(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL23_PSCL_2_SHIFT)) & PWM_PSCL23_PSCL_2_MASK)
+#define PWM_PSCL23_PSCL_3_MASK                   (0x3FF0000U)
+#define PWM_PSCL23_PSCL_3_SHIFT                  (16U)
+/*! PSCL_3 - PWM channel 3 prescaler. The output frequency equals to clk/(PSCL_3 + 1)
+ */
+#define PWM_PSCL23_PSCL_3(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL23_PSCL_3_SHIFT)) & PWM_PSCL23_PSCL_3_MASK)
+/*! @} */
+
+/*! @name PSCL45 - PWM Channels 4 & 5 prescalers */
+/*! @{ */
+#define PWM_PSCL45_PSCL_4_MASK                   (0x3FFU)
+#define PWM_PSCL45_PSCL_4_SHIFT                  (0U)
+/*! PSCL_4 - PWM channel 4 prescaler. The output frequency equals to clk/(PSCL_4 + 1)
+ */
+#define PWM_PSCL45_PSCL_4(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL45_PSCL_4_SHIFT)) & PWM_PSCL45_PSCL_4_MASK)
+#define PWM_PSCL45_PSCL_5_MASK                   (0x3FF0000U)
+#define PWM_PSCL45_PSCL_5_SHIFT                  (16U)
+/*! PSCL_5 - PWM channel 5 prescaler. The output frequency equals to clk/(PSCL_5 + 1)
+ */
+#define PWM_PSCL45_PSCL_5(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL45_PSCL_5_SHIFT)) & PWM_PSCL45_PSCL_5_MASK)
+/*! @} */
+
+/*! @name PSCL67 - PWM Channels 6 & 7 prescalers */
+/*! @{ */
+#define PWM_PSCL67_PSCL_6_MASK                   (0x3FFU)
+#define PWM_PSCL67_PSCL_6_SHIFT                  (0U)
+/*! PSCL_6 - PWM channel 6 prescaler. The output frequency equals to clk/(PSCL_6 + 1)
+ */
+#define PWM_PSCL67_PSCL_6(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL67_PSCL_6_SHIFT)) & PWM_PSCL67_PSCL_6_MASK)
+#define PWM_PSCL67_PSCL_7_MASK                   (0x3FF0000U)
+#define PWM_PSCL67_PSCL_7_SHIFT                  (16U)
+/*! PSCL_7 - PWM channel 7 prescaler. The output frequency equals to clk/(PSCL_7 + 1)
+ */
+#define PWM_PSCL67_PSCL_7(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL67_PSCL_7_SHIFT)) & PWM_PSCL67_PSCL_7_MASK)
+/*! @} */
+
+/*! @name PSCL89 - PWM Channels 8 & 9 prescalers */
+/*! @{ */
+#define PWM_PSCL89_PSCL_8_MASK                   (0x3FFU)
+#define PWM_PSCL89_PSCL_8_SHIFT                  (0U)
+/*! PSCL_8 - PWM channel 8 prescaler. The output frequency equals to clk/(PSCL_8 + 1)
+ */
+#define PWM_PSCL89_PSCL_8(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL89_PSCL_8_SHIFT)) & PWM_PSCL89_PSCL_8_MASK)
+#define PWM_PSCL89_PSCL_9_MASK                   (0x3FF0000U)
+#define PWM_PSCL89_PSCL_9_SHIFT                  (16U)
+/*! PSCL_9 - PWM channel 9 prescaler. The output frequency equals to clk/(PSCL_9 + 1)
+ */
+#define PWM_PSCL89_PSCL_9(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PSCL89_PSCL_9_SHIFT)) & PWM_PSCL89_PSCL_9_MASK)
+/*! @} */
+
+/*! @name PSCL1011 - PWM Channel 10 prescaler */
+/*! @{ */
+#define PWM_PSCL1011_PSCL_10_MASK                (0x3FFU)
+#define PWM_PSCL1011_PSCL_10_SHIFT               (0U)
+/*! PSCL_10 - PWM channel 10 prescaler. The output frequency equals to clk/(PSCL_10 + 1)
+ */
+#define PWM_PSCL1011_PSCL_10(x)                  (((uint32_t)(((uint32_t)(x)) << PWM_PSCL1011_PSCL_10_SHIFT)) & PWM_PSCL1011_PSCL_10_MASK)
+/*! @} */
+
+/*! @name PCP0 - PWM Channel 0 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP0_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP0_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 0 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP0_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP0_PERIOD_SHIFT)) & PWM_PCP0_PERIOD_MASK)
+#define PWM_PCP0_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP0_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 0 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP0_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP0_COMPARE_SHIFT)) & PWM_PCP0_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP1 - PWM Channel 1 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP1_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP1_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 1 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP1_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP1_PERIOD_SHIFT)) & PWM_PCP1_PERIOD_MASK)
+#define PWM_PCP1_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP1_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 1 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP1_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP1_COMPARE_SHIFT)) & PWM_PCP1_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP2 - PWM Channel 2 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP2_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP2_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 2 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP2_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP2_PERIOD_SHIFT)) & PWM_PCP2_PERIOD_MASK)
+#define PWM_PCP2_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP2_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 2 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP2_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP2_COMPARE_SHIFT)) & PWM_PCP2_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP3 - PWM Channel 3 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP3_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP3_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 3 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP3_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP3_PERIOD_SHIFT)) & PWM_PCP3_PERIOD_MASK)
+#define PWM_PCP3_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP3_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 3 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP3_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP3_COMPARE_SHIFT)) & PWM_PCP3_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP4 - PWM Channel 4 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP4_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP4_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 4 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP4_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP4_PERIOD_SHIFT)) & PWM_PCP4_PERIOD_MASK)
+#define PWM_PCP4_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP4_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 4 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP4_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP4_COMPARE_SHIFT)) & PWM_PCP4_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP5 - PWM Channel 5 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP5_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP5_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 5 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP5_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP5_PERIOD_SHIFT)) & PWM_PCP5_PERIOD_MASK)
+#define PWM_PCP5_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP5_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 5 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP5_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP5_COMPARE_SHIFT)) & PWM_PCP5_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP6 - PWM Channel 6 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP6_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP6_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 6 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP6_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP6_PERIOD_SHIFT)) & PWM_PCP6_PERIOD_MASK)
+#define PWM_PCP6_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP6_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 6 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP6_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP6_COMPARE_SHIFT)) & PWM_PCP6_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP7 - PWM Channel 7 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP7_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP7_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 7 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP7_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP7_PERIOD_SHIFT)) & PWM_PCP7_PERIOD_MASK)
+#define PWM_PCP7_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP7_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 7 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP7_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP7_COMPARE_SHIFT)) & PWM_PCP7_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP8 - PWM Channel 8 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP8_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP8_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 8 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP8_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP8_PERIOD_SHIFT)) & PWM_PCP8_PERIOD_MASK)
+#define PWM_PCP8_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP8_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 8 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP8_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP8_COMPARE_SHIFT)) & PWM_PCP8_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP9 - PWM Channel 9 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached PWM output will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP9_PERIOD_MASK                     (0xFFFFU)
+#define PWM_PCP9_PERIOD_SHIFT                    (0U)
+/*! PERIOD - PWM channel 9 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP9_PERIOD(x)                       (((uint32_t)(((uint32_t)(x)) << PWM_PCP9_PERIOD_SHIFT)) & PWM_PCP9_PERIOD_MASK)
+#define PWM_PCP9_COMPARE_MASK                    (0xFFFF0000U)
+#define PWM_PCP9_COMPARE_SHIFT                   (16U)
+/*! COMPARE - PWM channel 9 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP9_COMPARE(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP9_COMPARE_SHIFT)) & PWM_PCP9_COMPARE_MASK)
+/*! @} */
+
+/*! @name PCP10 - PWM Channel 10 Period and Compare register. Counter will count down from period to zero. When Comapre value is reached all PWM outputs will change on next counter decrement and be stable from 'Compare-1' to 0. */
+/*! @{ */
+#define PWM_PCP10_PERIOD_MASK                    (0xFFFFU)
+#define PWM_PCP10_PERIOD_SHIFT                   (0U)
+/*! PERIOD - PWM channel 10 period register. The actual period equals to [PERIOD + 1]. 'PERIOD' must not be 0x0.
+ */
+#define PWM_PCP10_PERIOD(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_PCP10_PERIOD_SHIFT)) & PWM_PCP10_PERIOD_MASK)
+#define PWM_PCP10_COMPARE_MASK                   (0xFFFF0000U)
+#define PWM_PCP10_COMPARE_SHIFT                  (16U)
+/*! COMPARE - PWM channel 10 compare register. 'COMPARE' must not be 0x0.
+ */
+#define PWM_PCP10_COMPARE(x)                     (((uint32_t)(((uint32_t)(x)) << PWM_PCP10_COMPARE_SHIFT)) & PWM_PCP10_COMPARE_MASK)
+/*! @} */
+
+/*! @name PST0 - PWM 1st Status Register (Channel 0 to Channel 3) */
+/*! @{ */
+#define PWM_PST0_INT_FLG_0_MASK                  (0x1U)
+#define PWM_PST0_INT_FLG_0_SHIFT                 (0U)
+/*! INT_FLG_0 - PWM channel 0 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST0_INT_FLG_0(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST0_INT_FLG_0_SHIFT)) & PWM_PST0_INT_FLG_0_MASK)
+#define PWM_PST0_INT_FLG_1_MASK                  (0x100U)
+#define PWM_PST0_INT_FLG_1_SHIFT                 (8U)
+/*! INT_FLG_1 - PWM channel 1 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST0_INT_FLG_1(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST0_INT_FLG_1_SHIFT)) & PWM_PST0_INT_FLG_1_MASK)
+#define PWM_PST0_INT_FLG_2_MASK                  (0x10000U)
+#define PWM_PST0_INT_FLG_2_SHIFT                 (16U)
+/*! INT_FLG_2 - PWM channel 2 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST0_INT_FLG_2(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST0_INT_FLG_2_SHIFT)) & PWM_PST0_INT_FLG_2_MASK)
+#define PWM_PST0_INT_FLG_3_MASK                  (0x1000000U)
+#define PWM_PST0_INT_FLG_3_SHIFT                 (24U)
+/*! INT_FLG_3 - PWM channel 3 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST0_INT_FLG_3(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST0_INT_FLG_3_SHIFT)) & PWM_PST0_INT_FLG_3_MASK)
+/*! @} */
+
+/*! @name PST1 - PWM 2nd Status Register (Channel 4 to Channel 7) */
+/*! @{ */
+#define PWM_PST1_INT_FLG_4_MASK                  (0x1U)
+#define PWM_PST1_INT_FLG_4_SHIFT                 (0U)
+/*! INT_FLG_4 - PWM channel 4 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST1_INT_FLG_4(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST1_INT_FLG_4_SHIFT)) & PWM_PST1_INT_FLG_4_MASK)
+#define PWM_PST1_INT_FLG_5_MASK                  (0x100U)
+#define PWM_PST1_INT_FLG_5_SHIFT                 (8U)
+/*! INT_FLG_5 - PWM channel 5 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST1_INT_FLG_5(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST1_INT_FLG_5_SHIFT)) & PWM_PST1_INT_FLG_5_MASK)
+#define PWM_PST1_INT_FLG_6_MASK                  (0x10000U)
+#define PWM_PST1_INT_FLG_6_SHIFT                 (16U)
+/*! INT_FLG_6 - PWM channel 6 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST1_INT_FLG_6(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST1_INT_FLG_6_SHIFT)) & PWM_PST1_INT_FLG_6_MASK)
+#define PWM_PST1_INT_FLG_7_MASK                  (0x1000000U)
+#define PWM_PST1_INT_FLG_7_SHIFT                 (24U)
+/*! INT_FLG_7 - PWM channel 7 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST1_INT_FLG_7(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST1_INT_FLG_7_SHIFT)) & PWM_PST1_INT_FLG_7_MASK)
+/*! @} */
+
+/*! @name PST2 - PWM 3rd Status Register (Channel 8 to Channel 10) */
+/*! @{ */
+#define PWM_PST2_INT_FLG_8_MASK                  (0x1U)
+#define PWM_PST2_INT_FLG_8_SHIFT                 (0U)
+/*! INT_FLG_8 - PWM channel 8 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST2_INT_FLG_8(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST2_INT_FLG_8_SHIFT)) & PWM_PST2_INT_FLG_8_MASK)
+#define PWM_PST2_INT_FLG_9_MASK                  (0x100U)
+#define PWM_PST2_INT_FLG_9_SHIFT                 (8U)
+/*! INT_FLG_9 - PWM channel 9 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST2_INT_FLG_9(x)                    (((uint32_t)(((uint32_t)(x)) << PWM_PST2_INT_FLG_9_SHIFT)) & PWM_PST2_INT_FLG_9_MASK)
+#define PWM_PST2_INT_FLG_10_MASK                 (0x10000U)
+#define PWM_PST2_INT_FLG_10_SHIFT                (16U)
+/*! INT_FLG_10 - PWM channel 10 interrupt flag. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear the interrupt.
+ */
+#define PWM_PST2_INT_FLG_10(x)                   (((uint32_t)(((uint32_t)(x)) << PWM_PST2_INT_FLG_10_SHIFT)) & PWM_PST2_INT_FLG_10_MASK)
+/*! @} */
+
+/*! @name MODULE_ID - PWM Module Identifier ('PW' in ASCII) */
+/*! @{ */
+#define PWM_MODULE_ID_APERTURE_MASK              (0xFFU)
+#define PWM_MODULE_ID_APERTURE_SHIFT             (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define PWM_MODULE_ID_APERTURE(x)                (((uint32_t)(((uint32_t)(x)) << PWM_MODULE_ID_APERTURE_SHIFT)) & PWM_MODULE_ID_APERTURE_MASK)
+#define PWM_MODULE_ID_MIN_REV_MASK               (0xF00U)
+#define PWM_MODULE_ID_MIN_REV_SHIFT              (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define PWM_MODULE_ID_MIN_REV(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_MODULE_ID_MIN_REV_SHIFT)) & PWM_MODULE_ID_MIN_REV_MASK)
+#define PWM_MODULE_ID_MAJ_REV_MASK               (0xF000U)
+#define PWM_MODULE_ID_MAJ_REV_SHIFT              (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define PWM_MODULE_ID_MAJ_REV(x)                 (((uint32_t)(((uint32_t)(x)) << PWM_MODULE_ID_MAJ_REV_SHIFT)) & PWM_MODULE_ID_MAJ_REV_MASK)
+#define PWM_MODULE_ID_ID_MASK                    (0xFFFF0000U)
+#define PWM_MODULE_ID_ID_SHIFT                   (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define PWM_MODULE_ID_ID(x)                      (((uint32_t)(((uint32_t)(x)) << PWM_MODULE_ID_ID_SHIFT)) & PWM_MODULE_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group PWM_Register_Masks */
+
+
+/* PWM - Peripheral instance base addresses */
+/** Peripheral PWM base address */
+#define PWM_BASE                                 (0x4000C000u)
+/** Peripheral PWM base pointer */
+#define PWM                                      ((PWM_Type *)PWM_BASE)
+/** Array initializer of PWM peripheral base addresses */
+#define PWM_BASE_ADDRS                           { PWM_BASE }
+/** Array initializer of PWM peripheral base pointers */
+#define PWM_BASE_PTRS                            { PWM }
+/** Interrupt vectors for the PWM peripheral type */
+#define PWM_IRQS                                 { PWM0_IRQn, PWM1_IRQn, PWM2_IRQn, PWM3_IRQn, PWM4_IRQn, PWM5_IRQn, PWM6_IRQn, PWM7_IRQn, PWM8_IRQn, PWM9_IRQn, PWM10_IRQn }
+
+/*!
+ * @}
+ */ /* end of group PWM_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- RNG Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup RNG_Peripheral_Access_Layer RNG Peripheral Access Layer
+ * @{
+ */
+
+/** RNG - Register Layout Typedef */
+typedef struct {
+  __I  uint32_t RANDOM_NUMBER;                     /**< Random number, offset: 0x0 */
+       uint8_t RESERVED_0[4];
+  __I  uint32_t COUNTER_VAL;                       /**< Counter values to show information about the random process, offset: 0x8 */
+  __IO uint32_t COUNTER_CFG;                       /**< Register linked to the comupting of statistics, not required for normal operation., offset: 0xC */
+  __IO uint32_t ONLINE_TEST_CFG;                   /**< Configuration for the online test features, offset: 0x10 */
+  __I  uint32_t ONLINE_TEST_VAL;                   /**< Online test results, offset: 0x14 */
+       uint8_t RESERVED_1[4060];
+  __IO uint32_t POWERDOWN;                         /**< Powerdown mode and reset control, generally use of this register is not necessary, offset: 0xFF4 */
+       uint8_t RESERVED_2[4];
+  __I  uint32_t MODULEID;                          /**< IP identifier, offset: 0xFFC */
+} RNG_Type;
+
+/* ----------------------------------------------------------------------------
+   -- RNG Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup RNG_Register_Masks RNG Register Masks
+ * @{
+ */
+
+/*! @name RANDOM_NUMBER - Random number */
+/*! @{ */
+#define RNG_RANDOM_NUMBER_RAND_NUM_MASK          (0xFFFFFFFFU)
+#define RNG_RANDOM_NUMBER_RAND_NUM_SHIFT         (0U)
+/*! RAND_NUM - This register contains a random 32 bit number which is computed on demand, at each
+ *    time it is read. Weak cryptographic post-processing is used to maximize throughput. The block
+ *    will start computing before the first register access and so the reset value is not relevant.
+ */
+#define RNG_RANDOM_NUMBER_RAND_NUM(x)            (((uint32_t)(((uint32_t)(x)) << RNG_RANDOM_NUMBER_RAND_NUM_SHIFT)) & RNG_RANDOM_NUMBER_RAND_NUM_MASK)
+/*! @} */
+
+/*! @name COUNTER_VAL - Counter values to show information about the random process */
+/*! @{ */
+#define RNG_COUNTER_VAL_CLK_RATIO_MASK           (0xFFU)
+#define RNG_COUNTER_VAL_CLK_RATIO_SHIFT          (0U)
+/*! CLK_RATIO - Gives the ratio between the internal clocks frequencies and the register clock
+ *    frequency for evaluation and certification purposes. Internal clock frequencies are half the
+ *    incoming ones: COUNTER_VAL = round[ (intFreq/2)/regFreq*256*(1<<(4*shift4x)) ] MODULO 256 If
+ *    shitf4x==0, intFreq ~= regFreq*COUNTER_VAL/256*2 Use clock_sel to select which clock you want to
+ *    measure, in this range: 1..5
+ */
+#define RNG_COUNTER_VAL_CLK_RATIO(x)             (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_VAL_CLK_RATIO_SHIFT)) & RNG_COUNTER_VAL_CLK_RATIO_MASK)
+#define RNG_COUNTER_VAL_REFRESH_CNT_MASK         (0x1F00U)
+#define RNG_COUNTER_VAL_REFRESH_CNT_SHIFT        (8U)
+/*! REFRESH_CNT - Incremented (till max possible value) each time COUNTER was updated since last
+ *    reading to any *_NUMBER. This gives an indication on 'entropy refill'. Note that there is no
+ *    linear accumulation of entropy: as implemented today, entropy refill will be about 4 bits each
+ *    time 'refresh_cnt' reaches its maximum value. See user manual for further details on how to
+ *    benefit from linear entropy accumulation using a specific procedure.
+ */
+#define RNG_COUNTER_VAL_REFRESH_CNT(x)           (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_VAL_REFRESH_CNT_SHIFT)) & RNG_COUNTER_VAL_REFRESH_CNT_MASK)
+/*! @} */
+
+/*! @name COUNTER_CFG - Register linked to the comupting of statistics, not required for normal operation. */
+/*! @{ */
+#define RNG_COUNTER_CFG_MODE_MASK                (0x3U)
+#define RNG_COUNTER_CFG_MODE_SHIFT               (0U)
+/*! MODE - 00: disabled 01: update once. Will return to 00 once done 10: free running: updates countinuously 11: reserved
+ */
+#define RNG_COUNTER_CFG_MODE(x)                  (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_CFG_MODE_SHIFT)) & RNG_COUNTER_CFG_MODE_MASK)
+#define RNG_COUNTER_CFG_CLOCK_SEL_MASK           (0x1CU)
+#define RNG_COUNTER_CFG_CLOCK_SEL_SHIFT          (2U)
+/*! CLOCK_SEL - Selects the internal clock on which to compute statistics. 1 is for first one, 2 for
+ *    second one, . And 0 is for a XOR of results from all clocks
+ */
+#define RNG_COUNTER_CFG_CLOCK_SEL(x)             (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_CFG_CLOCK_SEL_SHIFT)) & RNG_COUNTER_CFG_CLOCK_SEL_MASK)
+#define RNG_COUNTER_CFG_SHIFT4X_MASK             (0xE0U)
+#define RNG_COUNTER_CFG_SHIFT4X_SHIFT            (5U)
+/*! SHIFT4X - To be used to add precision to clock_ratio and determine 'entropy refill'. Supported
+ *    range is 0..4 Used as well for ONLINE_TEST
+ */
+#define RNG_COUNTER_CFG_SHIFT4X(x)               (((uint32_t)(((uint32_t)(x)) << RNG_COUNTER_CFG_SHIFT4X_SHIFT)) & RNG_COUNTER_CFG_SHIFT4X_MASK)
+/*! @} */
+
+/*! @name ONLINE_TEST_CFG - Configuration for the online test features */
+/*! @{ */
+#define RNG_ONLINE_TEST_CFG_ACTIVATE_MASK        (0x1U)
+#define RNG_ONLINE_TEST_CFG_ACTIVATE_SHIFT       (0U)
+/*! ACTIVATE - 0: disabled 1: activated Update rhythm for VAL depends on COUNTER_CFG if data_sel is
+ *    set to COUNTER. Otherwise VAL is updated each time RANDOM_NUMBER is read
+ */
+#define RNG_ONLINE_TEST_CFG_ACTIVATE(x)          (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_CFG_ACTIVATE_SHIFT)) & RNG_ONLINE_TEST_CFG_ACTIVATE_MASK)
+#define RNG_ONLINE_TEST_CFG_DATA_SEL_MASK        (0x6U)
+#define RNG_ONLINE_TEST_CFG_DATA_SEL_SHIFT       (1U)
+/*! DATA_SEL - Selects source on which to apply online test: 00: LSB of COUNTER: raw data from one
+ *    or all sources of entropy 01: MSB of COUNTER: raw data from one or all sources of entropy (do
+ *    not use) 10: RANDOM_NUMBER 11: not valid 'activate' should be set to 'disabled' before changing
+ *    this field
+ */
+#define RNG_ONLINE_TEST_CFG_DATA_SEL(x)          (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_CFG_DATA_SEL_SHIFT)) & RNG_ONLINE_TEST_CFG_DATA_SEL_MASK)
+/*! @} */
+
+/*! @name ONLINE_TEST_VAL - Online test results */
+/*! @{ */
+#define RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED_MASK (0xFU)
+#define RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED_SHIFT (0U)
+/*! LIVE_CHI_SQUARED - This value is updated as described in field 'activate'. This value is a
+ *    statistic value that indicates the quality of entropy generation. Low value means good, high value
+ *    means no good. If 'data_sel'<10, increase 'shift4x' till 'chi' is correct and poll
+ *    'refresh_cnt' before reading RANDOM_NUMBER.
+ */
+#define RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED(x)  (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED_SHIFT)) & RNG_ONLINE_TEST_VAL_LIVE_CHI_SQUARED_MASK)
+#define RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED_MASK (0xF0U)
+#define RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED_SHIFT (4U)
+/*! MIN_CHI_SQUARED - Minimum value of LIVE_CHI_SQUARED since the last reset of this field. This field is reset when 'activate'=0
+ */
+#define RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED(x)   (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED_SHIFT)) & RNG_ONLINE_TEST_VAL_MIN_CHI_SQUARED_MASK)
+#define RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED_MASK (0xF00U)
+#define RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED_SHIFT (8U)
+/*! MAX_CHI_SQUARED - Maximum value of LIVE_CHI_SQUARED since the last reset of this field. This field is reset when 'activate'=0
+ */
+#define RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED(x)   (((uint32_t)(((uint32_t)(x)) << RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED_SHIFT)) & RNG_ONLINE_TEST_VAL_MAX_CHI_SQUARED_MASK)
+/*! @} */
+
+/*! @name POWERDOWN - Powerdown mode and reset control, generally use of this register is not necessary */
+/*! @{ */
+#define RNG_POWERDOWN_SOFT_RESET_MASK            (0x1U)
+#define RNG_POWERDOWN_SOFT_RESET_SHIFT           (0U)
+/*! SOFT_RESET - Request softreset that will go low automaticaly after acknowledge from CORE
+ */
+#define RNG_POWERDOWN_SOFT_RESET(x)              (((uint32_t)(((uint32_t)(x)) << RNG_POWERDOWN_SOFT_RESET_SHIFT)) & RNG_POWERDOWN_SOFT_RESET_MASK)
+#define RNG_POWERDOWN_FORCE_SOFT_RESET_MASK      (0x2U)
+#define RNG_POWERDOWN_FORCE_SOFT_RESET_SHIFT     (1U)
+/*! FORCE_SOFT_RESET - When used with softreset it forces CORE_RESETN to low on acknowledge from CORE
+ */
+#define RNG_POWERDOWN_FORCE_SOFT_RESET(x)        (((uint32_t)(((uint32_t)(x)) << RNG_POWERDOWN_FORCE_SOFT_RESET_SHIFT)) & RNG_POWERDOWN_FORCE_SOFT_RESET_MASK)
+#define RNG_POWERDOWN_POWERDOWN_MASK             (0x80000000U)
+#define RNG_POWERDOWN_POWERDOWN_SHIFT            (31U)
+/*! POWERDOWN - When set all accesses to standard registers are blocked
+ */
+#define RNG_POWERDOWN_POWERDOWN(x)               (((uint32_t)(((uint32_t)(x)) << RNG_POWERDOWN_POWERDOWN_SHIFT)) & RNG_POWERDOWN_POWERDOWN_MASK)
+/*! @} */
+
+/*! @name MODULEID - IP identifier */
+/*! @{ */
+#define RNG_MODULEID_APERTURE_MASK               (0xFFU)
+#define RNG_MODULEID_APERTURE_SHIFT              (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define RNG_MODULEID_APERTURE(x)                 (((uint32_t)(((uint32_t)(x)) << RNG_MODULEID_APERTURE_SHIFT)) & RNG_MODULEID_APERTURE_MASK)
+#define RNG_MODULEID_MIN_REV_MASK                (0xF00U)
+#define RNG_MODULEID_MIN_REV_SHIFT               (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define RNG_MODULEID_MIN_REV(x)                  (((uint32_t)(((uint32_t)(x)) << RNG_MODULEID_MIN_REV_SHIFT)) & RNG_MODULEID_MIN_REV_MASK)
+#define RNG_MODULEID_MAJ_REV_MASK                (0xF000U)
+#define RNG_MODULEID_MAJ_REV_SHIFT               (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define RNG_MODULEID_MAJ_REV(x)                  (((uint32_t)(((uint32_t)(x)) << RNG_MODULEID_MAJ_REV_SHIFT)) & RNG_MODULEID_MAJ_REV_MASK)
+#define RNG_MODULEID_ID_MASK                     (0xFFFF0000U)
+#define RNG_MODULEID_ID_SHIFT                    (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define RNG_MODULEID_ID(x)                       (((uint32_t)(((uint32_t)(x)) << RNG_MODULEID_ID_SHIFT)) & RNG_MODULEID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group RNG_Register_Masks */
+
+
+/* RNG - Peripheral instance base addresses */
+/** Peripheral RNG base address */
+#define RNG_BASE                                 (0x4000D000u)
+/** Peripheral RNG base pointer */
+#define RNG                                      ((RNG_Type *)RNG_BASE)
+/** Array initializer of RNG peripheral base addresses */
+#define RNG_BASE_ADDRS                           { RNG_BASE }
+/** Array initializer of RNG peripheral base pointers */
+#define RNG_BASE_PTRS                            { RNG }
+
+/*!
+ * @}
+ */ /* end of group RNG_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- RTC Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup RTC_Peripheral_Access_Layer RTC Peripheral Access Layer
+ * @{
+ */
+
+/** RTC - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< RTC control register, offset: 0x0 */
+  __IO uint32_t MATCH;                             /**< RTC 32-bit counter match register, offset: 0x4 */
+  __IO uint32_t COUNT;                             /**< RTC 32-bit counter register, offset: 0x8 */
+  __IO uint32_t WAKE;                              /**< 16-bit RTC timer register, offset: 0xC */
+} RTC_Type;
+
+/* ----------------------------------------------------------------------------
+   -- RTC Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup RTC_Register_Masks RTC Register Masks
+ * @{
+ */
+
+/*! @name CTRL - RTC control register */
+/*! @{ */
+#define RTC_CTRL_SWRESET_MASK                    (0x1U)
+#define RTC_CTRL_SWRESET_SHIFT                   (0U)
+/*! SWRESET - Software reset control. 0: Not in reset. The RTC is not held in reset. This bit must
+ *    be cleared prior to configuring or initiating any operation of the RTC. 1: In reset. The RTC is
+ *    held in reset. All register bits within the RTC will be forced to their reset value except
+ *    the OFD bit. This bit must be cleared before writing to any register in the RTC - including
+ *    writes to set any of the other bits within this register. Do not attempt to write to any bits of
+ *    this register at the same time that the reset bit is being cleared.
+ */
+#define RTC_CTRL_SWRESET(x)                      (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_SWRESET_SHIFT)) & RTC_CTRL_SWRESET_MASK)
+#define RTC_CTRL_ALARM1HZ_MASK                   (0x4U)
+#define RTC_CTRL_ALARM1HZ_SHIFT                  (2U)
+/*! ALARM1HZ - RTC 32-bit timer alarm flag status. 0: No match has occurred on the 32-bit RTC timer.
+ *    Writing a 0 has no effect. 1: A match condition has occurred on the 32-bit RTC timer. This
+ *    flag generates an RTC alarm interrupt request. RTC_ALARM which can also wake up the part from
+ *    low power modes (excluding deep power down mode). Writing a 1 clears this bit.
+ */
+#define RTC_CTRL_ALARM1HZ(x)                     (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARM1HZ_SHIFT)) & RTC_CTRL_ALARM1HZ_MASK)
+#define RTC_CTRL_WAKE1KHZ_MASK                   (0x8U)
+#define RTC_CTRL_WAKE1KHZ_SHIFT                  (3U)
+/*! WAKE1KHZ - RTC 16-bit timer wake-up flag status. 0: The RTC 16-bit timer is running. Writing a 0
+ *    has no effect. 1: The 16-bit timer has timed out. This flag generates an RTC wake-up
+ *    interrupt request RTC-WAKE which can also wake up the part from low power modes (excluding deep power
+ *    down mode). Writing a 1 clears this bit.
+ */
+#define RTC_CTRL_WAKE1KHZ(x)                     (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKE1KHZ_SHIFT)) & RTC_CTRL_WAKE1KHZ_MASK)
+#define RTC_CTRL_ALARMDPD_EN_MASK                (0x10U)
+#define RTC_CTRL_ALARMDPD_EN_SHIFT               (4U)
+/*! ALARMDPD_EN - RTC 32-bit timer alarm enable for Low power mode. 0: Disable. A match on the
+ *    32-bit RTC timer will not bring the part out of power-down modes. 1: Enable. A match on the 32-bit
+ *    RTC timer will bring the part out of power-down modes.
+ */
+#define RTC_CTRL_ALARMDPD_EN(x)                  (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARMDPD_EN_SHIFT)) & RTC_CTRL_ALARMDPD_EN_MASK)
+#define RTC_CTRL_WAKEDPD_EN_MASK                 (0x20U)
+#define RTC_CTRL_WAKEDPD_EN_SHIFT                (5U)
+/*! WAKEDPD_EN - RTC 16-bit timer wake-up enable for power-down modes. 0: Disable. A match on the
+ *    16-bit RTC timer will not bring the part out of power-down modes. 1: Enable. A match on the
+ *    16-bit RTC timer will bring the part out of power-down modes.
+ */
+#define RTC_CTRL_WAKEDPD_EN(x)                   (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKEDPD_EN_SHIFT)) & RTC_CTRL_WAKEDPD_EN_MASK)
+#define RTC_CTRL_RTC1KHZ_EN_MASK                 (0x40U)
+#define RTC_CTRL_RTC1KHZ_EN_SHIFT                (6U)
+/*! RTC1KHZ_EN - RTC 16-bit timer clock enable. This bit can be set to 0 to conserve power if the
+ *    16-bit timer is not used. This bit has no effect when the RTC is disabled (bit 7 of this
+ *    register is 0). 0: Disable. A match on the 16-bit RTC timer will not bring the part out of Deep
+ *    power-down mode. 1: Enable. The 16-bit RTC timer is enabled.
+ */
+#define RTC_CTRL_RTC1KHZ_EN(x)                   (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC1KHZ_EN_SHIFT)) & RTC_CTRL_RTC1KHZ_EN_MASK)
+#define RTC_CTRL_RTC_EN_MASK                     (0x80U)
+#define RTC_CTRL_RTC_EN_SHIFT                    (7U)
+/*! RTC_EN - RTC enable. 0: Disable. The RTC 32-bit timer and 16-bit timer clocks are shut down and
+ *    the RTC operation is disabled. This bit should be 0 when writing to load a value in the RTC
+ *    counter register. 1: Enable. The 32-bit RTC clock is running and RTC operation is enabled. This
+ *    bit must be set to initiate operation of the RTC. To also enable the 16-bit timer clock, set
+ *    bit 6 in this register.
+ */
+#define RTC_CTRL_RTC_EN(x)                       (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC_EN_SHIFT)) & RTC_CTRL_RTC_EN_MASK)
+/*! @} */
+
+/*! @name MATCH - RTC 32-bit counter match register */
+/*! @{ */
+#define RTC_MATCH_MATVAL_MASK                    (0xFFFFFFFFU)
+#define RTC_MATCH_MATVAL_SHIFT                   (0U)
+/*! MATVAL - Contains the match value against which the 1 Hz RTC timer will be compared to generate
+ *    the alarm flag RTC_ALARM and generate an alarm interrupt/wake-up if enabled.
+ */
+#define RTC_MATCH_MATVAL(x)                      (((uint32_t)(((uint32_t)(x)) << RTC_MATCH_MATVAL_SHIFT)) & RTC_MATCH_MATVAL_MASK)
+/*! @} */
+
+/*! @name COUNT - RTC 32-bit counter register */
+/*! @{ */
+#define RTC_COUNT_VAL_MASK                       (0xFFFFFFFFU)
+#define RTC_COUNT_VAL_SHIFT                      (0U)
+/*! VAL - A read reflects the current value of the main, 32-bit, RTC timer. A write loads a new
+ *    initial value into the timer. The RTC 32-bit counter will count up continuously at the 32-bit
+ *    timer clock rate once the RTC Software Reset is removed (by clearing bit 0 of the CTRL register).
+ *    Remark: Only write to this register when the RTC_EN bit in the RTC CTRL Register is 0.
+ */
+#define RTC_COUNT_VAL(x)                         (((uint32_t)(((uint32_t)(x)) << RTC_COUNT_VAL_SHIFT)) & RTC_COUNT_VAL_MASK)
+/*! @} */
+
+/*! @name WAKE - 16-bit RTC timer register */
+/*! @{ */
+#define RTC_WAKE_VAL_MASK                        (0xFFFFU)
+#define RTC_WAKE_VAL_SHIFT                       (0U)
+/*! VAL - A read reflects the current value of 16-bit timer. A write pre-loads a start count value
+ *    into the 16-bit timer and initializes a count-down sequence. Do not write to this register
+ *    while counting is in progress.
+ */
+#define RTC_WAKE_VAL(x)                          (((uint32_t)(((uint32_t)(x)) << RTC_WAKE_VAL_SHIFT)) & RTC_WAKE_VAL_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group RTC_Register_Masks */
+
+
+/* RTC - Peripheral instance base addresses */
+/** Peripheral RTC base address */
+#define RTC_BASE                                 (0x4000B000u)
+/** Peripheral RTC base pointer */
+#define RTC                                      ((RTC_Type *)RTC_BASE)
+/** Array initializer of RTC peripheral base addresses */
+#define RTC_BASE_ADDRS                           { RTC_BASE }
+/** Array initializer of RTC peripheral base pointers */
+#define RTC_BASE_PTRS                            { RTC }
+/** Interrupt vectors for the RTC peripheral type */
+#define RTC_IRQS                                 { RTC_IRQn }
+
+/*!
+ * @}
+ */ /* end of group RTC_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- SHA Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SHA_Peripheral_Access_Layer SHA Peripheral Access Layer
+ * @{
+ */
+
+/** SHA - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< Control register, offset: 0x0 */
+  __I  uint32_t STATUS;                            /**< Status Regsiter, offset: 0x4 */
+  __IO uint32_t INTENSET;                          /**< Interrupt Enable and Interrupt enable set function, offset: 0x8 */
+  __O  uint32_t INTENCLR;                          /**< Interrupt Clear Register, offset: 0xC */
+  __IO uint32_t MEMCTRL;                           /**< Setup Master to access memory, offset: 0x10 */
+  __IO uint32_t MEMADDR;                           /**< Address to start memory access from, offset: 0x14 */
+       uint8_t RESERVED_0[8];
+  __IO uint32_t INDATA[8];                         /**< Input Data register, array offset: 0x20, array step: 0x4 */
+  __I  uint32_t DIGEST[8];                         /**< DIGEST or OUTD0, 5 or 8 bytes of output data, depending upon mode, array offset: 0x40, array step: 0x4 */
+       uint8_t RESERVED_1[48];
+  __IO uint32_t MASK;                              /**< Mask register, offset: 0x90 */
+       uint8_t RESERVED_2[3944];
+  __I  uint32_t ID;                                /**< IP identifier, offset: 0xFFC */
+} SHA_Type;
+
+/* ----------------------------------------------------------------------------
+   -- SHA Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SHA_Register_Masks SHA Register Masks
+ * @{
+ */
+
+/*! @name CTRL - Control register */
+/*! @{ */
+#define SHA_CTRL_MODE_MASK                       (0x7U)
+#define SHA_CTRL_MODE_SHIFT                      (0U)
+/*! MODE - Operational mode: 0: Disabled; 1: SHA1; 2: SHA2-256; 3: SHA2-512; 4-7: Not valid
+ */
+#define SHA_CTRL_MODE(x)                         (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_MODE_SHIFT)) & SHA_CTRL_MODE_MASK)
+#define SHA_CTRL_NEW_MASK                        (0x10U)
+#define SHA_CTRL_NEW_SHIFT                       (4U)
+/*! NEW - Written with 1 when starting a new Hash. It self clears. Note that the WAITING Status bit
+ *    will clear for a cycle during the initialization from New=1. Digest/Result is initialized when
+ *    New is set to 1.
+ */
+#define SHA_CTRL_NEW(x)                          (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_NEW_SHIFT)) & SHA_CTRL_NEW_MASK)
+#define SHA_CTRL_DMA_I_MASK                      (0x100U)
+#define SHA_CTRL_DMA_I_SHIFT                     (8U)
+/*! DMA_I - Written with 1 to use DMA to fill INDATA. For Hash, will request from DMA for 16 words
+ *    and then will process the Hash. Normal model is that the DMA interrupts the processor when its
+ *    length expires.
+ */
+#define SHA_CTRL_DMA_I(x)                        (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_DMA_I_SHIFT)) & SHA_CTRL_DMA_I_MASK)
+#define SHA_CTRL_DMA_O_MASK                      (0x200U)
+#define SHA_CTRL_DMA_O_SHIFT                     (9U)
+/*! DMA_O - Written to 1 to use DMA to drain the digest/output. If both DMA_I and DMA_O are set, the
+ *    DMA has to know to switch direction and the locations. If written to 0 the DMA is not used
+ *    and the processor has to read the digest/output in response to the DIGEST interrupt.
+ */
+#define SHA_CTRL_DMA_O(x)                        (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_DMA_O_SHIFT)) & SHA_CTRL_DMA_O_MASK)
+#define SHA_CTRL_HASHSWPB_MASK                   (0x1000U)
+#define SHA_CTRL_HASHSWPB_SHIFT                  (12U)
+/*! HASHSWPB - If 1, will swap bytes in the word for SHA hashing. The default is byte order (so LSB
+ *    is first byte) but this allows swapping to MSB is first.
+ */
+#define SHA_CTRL_HASHSWPB(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_CTRL_HASHSWPB_SHIFT)) & SHA_CTRL_HASHSWPB_MASK)
+/*! @} */
+
+/*! @name STATUS - Status Regsiter */
+/*! @{ */
+#define SHA_STATUS_WAITING_MASK                  (0x1U)
+#define SHA_STATUS_WAITING_SHIFT                 (0U)
+/*! WAITING - Waiting Status 0: Not waiting for data may be disabled or may be busy. Note that for
+ *    cryptographic uses, this is not set if IsLast is set nor will it set until at least 1 word is
+ *    read of the output. 1: Waiting for data to be written in (16 words)
+ */
+#define SHA_STATUS_WAITING(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_WAITING_SHIFT)) & SHA_STATUS_WAITING_MASK)
+#define SHA_STATUS_DIGEST_MASK                   (0x2U)
+#define SHA_STATUS_DIGEST_SHIFT                  (1U)
+/*! DIGEST - If 1 then a DIGEST is ready and waiting and there is no active next block already
+ *    started. This is cleared when any data is written, when New is written, or when the block is
+ *    disabled.
+ */
+#define SHA_STATUS_DIGEST(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_DIGEST_SHIFT)) & SHA_STATUS_DIGEST_MASK)
+#define SHA_STATUS_ERROR_MASK                    (0x4U)
+#define SHA_STATUS_ERROR_SHIFT                   (2U)
+/*! ERROR - If 1, an error occurred. For normal uses, this is due to an attempted overrun: INDATA
+ *    was written when it was not appropriate. Write 1 to clear.
+ */
+#define SHA_STATUS_ERROR(x)                      (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_ERROR_SHIFT)) & SHA_STATUS_ERROR_MASK)
+#define SHA_STATUS_NEEDKEY_MASK                  (0x10U)
+#define SHA_STATUS_NEEDKEY_SHIFT                 (4U)
+/*! NEEDKEY - Indicates the block wants the key to be written in (set along with WAITING). 0: no key
+ *    is needed and writes will not be treated as Key. 1: key is needed and INDATA will be accepted
+ *    as key. Will also set WAITING.
+ */
+#define SHA_STATUS_NEEDKEY(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_NEEDKEY_SHIFT)) & SHA_STATUS_NEEDKEY_MASK)
+#define SHA_STATUS_NEEDIV_MASK                   (0x20U)
+#define SHA_STATUS_NEEDIV_SHIFT                  (5U)
+/*! NEEDIV - Indicates the block wants an IV/NONE to be written in (set along with WAITING). 0: no
+ *    IV is needed, either because written already or because not needed. 1: IV needed and INDATA
+ *    will be accepted as IV.
+ */
+#define SHA_STATUS_NEEDIV(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_STATUS_NEEDIV_SHIFT)) & SHA_STATUS_NEEDIV_MASK)
+/*! @} */
+
+/*! @name INTENSET - Interrupt Enable and Interrupt enable set function */
+/*! @{ */
+#define SHA_INTENSET_WAITING_MASK                (0x1U)
+#define SHA_INTENSET_WAITING_SHIFT               (0U)
+/*! WAITING - 0: Will not interrupt when waiting. 1: Will interrupt when waiting. Write 1 to set this bit.
+ */
+#define SHA_INTENSET_WAITING(x)                  (((uint32_t)(((uint32_t)(x)) << SHA_INTENSET_WAITING_SHIFT)) & SHA_INTENSET_WAITING_MASK)
+#define SHA_INTENSET_DIGEST_MASK                 (0x2U)
+#define SHA_INTENSET_DIGEST_SHIFT                (1U)
+/*! DIGEST - 0: Will not interrupt when Digest is ready. 1: Will interrupt when Digest is ready. Write 1 to set this bit.
+ */
+#define SHA_INTENSET_DIGEST(x)                   (((uint32_t)(((uint32_t)(x)) << SHA_INTENSET_DIGEST_SHIFT)) & SHA_INTENSET_DIGEST_MASK)
+#define SHA_INTENSET_ERROR_MASK                  (0x4U)
+#define SHA_INTENSET_ERROR_SHIFT                 (2U)
+/*! ERROR - 0: Will not interrupt on Error. 1: Will interrupt on Error. Write 1 to set this bit.
+ */
+#define SHA_INTENSET_ERROR(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_INTENSET_ERROR_SHIFT)) & SHA_INTENSET_ERROR_MASK)
+/*! @} */
+
+/*! @name INTENCLR - Interrupt Clear Register */
+/*! @{ */
+#define SHA_INTENCLR_WAITING_MASK                (0x1U)
+#define SHA_INTENCLR_WAITING_SHIFT               (0U)
+/*! WAITING - Write 1 to clear correspnding bit in INTENSET.
+ */
+#define SHA_INTENCLR_WAITING(x)                  (((uint32_t)(((uint32_t)(x)) << SHA_INTENCLR_WAITING_SHIFT)) & SHA_INTENCLR_WAITING_MASK)
+#define SHA_INTENCLR_DIGEST_MASK                 (0x2U)
+#define SHA_INTENCLR_DIGEST_SHIFT                (1U)
+/*! DIGEST - Write 1 to clear correspnding bit in INTENSET.
+ */
+#define SHA_INTENCLR_DIGEST(x)                   (((uint32_t)(((uint32_t)(x)) << SHA_INTENCLR_DIGEST_SHIFT)) & SHA_INTENCLR_DIGEST_MASK)
+#define SHA_INTENCLR_ERROR_MASK                  (0x4U)
+#define SHA_INTENCLR_ERROR_SHIFT                 (2U)
+/*! ERROR - Write 1 to clear correspnding bit in INTENSET.
+ */
+#define SHA_INTENCLR_ERROR(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_INTENCLR_ERROR_SHIFT)) & SHA_INTENCLR_ERROR_MASK)
+/*! @} */
+
+/*! @name MEMCTRL - Setup Master to access memory */
+/*! @{ */
+#define SHA_MEMCTRL_MASTER_MASK                  (0x1U)
+#define SHA_MEMCTRL_MASTER_SHIFT                 (0U)
+/*! MASTER - Enables Mastering. 0: Mastering is not used and the normal DMA or Interrupt based model
+ *    is used with INDATA. 1: Mastering is enabled and DMA and INDATA should not be used.
+ */
+#define SHA_MEMCTRL_MASTER(x)                    (((uint32_t)(((uint32_t)(x)) << SHA_MEMCTRL_MASTER_SHIFT)) & SHA_MEMCTRL_MASTER_MASK)
+#define SHA_MEMCTRL_COUNT_MASK                   (0x7FF0000U)
+#define SHA_MEMCTRL_COUNT_SHIFT                  (16U)
+/*! COUNT - Number of 512-bit blocks to copy starting at MEMADDR. This register will decrement after
+ *    each block is copied, ending in 0. For Hash, the DIGEST interrupt will occur when it reaches
+ *    0. If a bus error occurs, it will stop with this field set to the block that failed
+ */
+#define SHA_MEMCTRL_COUNT(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_MEMCTRL_COUNT_SHIFT)) & SHA_MEMCTRL_COUNT_MASK)
+/*! @} */
+
+/*! @name MEMADDR - Address to start memory access from */
+/*! @{ */
+#define SHA_MEMADDR_BASEADDR_MASK                (0xFFFFFFFFU)
+#define SHA_MEMADDR_BASEADDR_SHIFT               (0U)
+/*! BASEADDR - This field indicates the base address in Internal Flash, SRAM0, SRAMX, or SPIFI to start copying from.
+ */
+#define SHA_MEMADDR_BASEADDR(x)                  (((uint32_t)(((uint32_t)(x)) << SHA_MEMADDR_BASEADDR_SHIFT)) & SHA_MEMADDR_BASEADDR_MASK)
+/*! @} */
+
+/*! @name INDATA - Input Data register */
+/*! @{ */
+#define SHA_INDATA_DATA_MASK                     (0xFFFFFFFFU)
+#define SHA_INDATA_DATA_SHIFT                    (0U)
+/*! DATA - In this field the next word is written in little-endian format.
+ */
+#define SHA_INDATA_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << SHA_INDATA_DATA_SHIFT)) & SHA_INDATA_DATA_MASK)
+/*! @} */
+
+/* The count of SHA_INDATA */
+#define SHA_INDATA_COUNT                         (8U)
+
+/*! @name DIGEST - DIGEST or OUTD0, 5 or 8 bytes of output data, depending upon mode */
+/*! @{ */
+#define SHA_DIGEST_DIGEST_MASK                   (0xFFFFFFFFU)
+#define SHA_DIGEST_DIGEST_SHIFT                  (0U)
+/*! DIGEST - This field contains one word of the Digest.
+ */
+#define SHA_DIGEST_DIGEST(x)                     (((uint32_t)(((uint32_t)(x)) << SHA_DIGEST_DIGEST_SHIFT)) & SHA_DIGEST_DIGEST_MASK)
+/*! @} */
+
+/* The count of SHA_DIGEST */
+#define SHA_DIGEST_COUNT                         (8U)
+
+/*! @name MASK - Mask register */
+/*! @{ */
+#define SHA_MASK_MASK_MASK                       (0xFFFFFFFFU)
+#define SHA_MASK_MASK_SHIFT                      (0U)
+/*! MASK - Mask register
+ */
+#define SHA_MASK_MASK(x)                         (((uint32_t)(((uint32_t)(x)) << SHA_MASK_MASK_SHIFT)) & SHA_MASK_MASK_MASK)
+/*! @} */
+
+/*! @name ID - IP identifier */
+/*! @{ */
+#define SHA_ID_APERTURE_MASK                     (0xFFU)
+#define SHA_ID_APERTURE_SHIFT                    (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define SHA_ID_APERTURE(x)                       (((uint32_t)(((uint32_t)(x)) << SHA_ID_APERTURE_SHIFT)) & SHA_ID_APERTURE_MASK)
+#define SHA_ID_MIN_REV_MASK                      (0xF00U)
+#define SHA_ID_MIN_REV_SHIFT                     (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define SHA_ID_MIN_REV(x)                        (((uint32_t)(((uint32_t)(x)) << SHA_ID_MIN_REV_SHIFT)) & SHA_ID_MIN_REV_MASK)
+#define SHA_ID_MAJ_REV_MASK                      (0xF000U)
+#define SHA_ID_MAJ_REV_SHIFT                     (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define SHA_ID_MAJ_REV(x)                        (((uint32_t)(((uint32_t)(x)) << SHA_ID_MAJ_REV_SHIFT)) & SHA_ID_MAJ_REV_MASK)
+#define SHA_ID_ID_MASK                           (0xFFFF0000U)
+#define SHA_ID_ID_SHIFT                          (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define SHA_ID_ID(x)                             (((uint32_t)(((uint32_t)(x)) << SHA_ID_ID_SHIFT)) & SHA_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group SHA_Register_Masks */
+
+
+/* SHA - Peripheral instance base addresses */
+/** Peripheral SHA0 base address */
+#define SHA0_BASE                                (0x4008F000u)
+/** Peripheral SHA0 base pointer */
+#define SHA0                                     ((SHA_Type *)SHA0_BASE)
+/** Array initializer of SHA peripheral base addresses */
+#define SHA_BASE_ADDRS                           { SHA0_BASE }
+/** Array initializer of SHA peripheral base pointers */
+#define SHA_BASE_PTRS                            { SHA0 }
+/** Interrupt vectors for the SHA peripheral type */
+#define SHA_IRQS                                 { SHA_IRQn }
+
+/*!
+ * @}
+ */ /* end of group SHA_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- SPI Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SPI_Peripheral_Access_Layer SPI Peripheral Access Layer
+ * @{
+ */
+
+/** SPI - Register Layout Typedef */
+typedef struct {
+       uint8_t RESERVED_0[1024];
+  __IO uint32_t CFG;                               /**< SPI Configuration register, offset: 0x400 */
+  __IO uint32_t DLY;                               /**< SPI Delay register, offset: 0x404 */
+  __IO uint32_t STAT;                              /**< SPI Status. Some status flags can be cleared by writing a 1 to that bit position., offset: 0x408 */
+  __IO uint32_t INTENSET;                          /**< SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0x40C */
+  __IO uint32_t INTENCLR;                          /**< SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared., offset: 0x410 */
+       uint8_t RESERVED_1[12];
+  __IO uint32_t TXCTL;                             /**< SPI Transmit Control. If Transmit FIFO is enabled, in FIFOCFG, then values read in this register are affected values in FIFO., offset: 0x420 */
+  __IO uint32_t DIV;                               /**< SPI clock Divider, offset: 0x424 */
+  __I  uint32_t INTSTAT;                           /**< SPI Interrupt Status, offset: 0x428 */
+       uint8_t RESERVED_2[2516];
+  __IO uint32_t FIFOCFG;                           /**< FIFO configuration and enable register., offset: 0xE00 */
+  __IO uint32_t FIFOSTAT;                          /**< FIFO status register., offset: 0xE04 */
+  __IO uint32_t FIFOTRIG;                          /**< FIFO trigger settings for interrupt and DMA request., offset: 0xE08 */
+       uint8_t RESERVED_3[4];
+  __IO uint32_t FIFOINTENSET;                      /**< FIFO interrupt enable set (enable) and read register., offset: 0xE10 */
+  __IO uint32_t FIFOINTENCLR;                      /**< FIFO interrupt enable clear (disable) and read register., offset: 0xE14 */
+  __I  uint32_t FIFOINTSTAT;                       /**< FIFO interrupt status register., offset: 0xE18 */
+       uint8_t RESERVED_4[4];
+  __O  uint32_t FIFOWR;                            /**< FIFO write data. FIFO data not reset by block reset, offset: 0xE20 */
+       uint8_t RESERVED_5[12];
+  __I  uint32_t FIFORD;                            /**< FIFO read data., offset: 0xE30 */
+       uint8_t RESERVED_6[12];
+  __I  uint32_t FIFORDNOPOP;                       /**< FIFO data read with no FIFO pop., offset: 0xE40 */
+       uint8_t RESERVED_7[436];
+  __IO uint32_t PSELID;                            /**< Peripheral function select and ID register, offset: 0xFF8 */
+  __I  uint32_t ID;                                /**< SPI Module Identifier, offset: 0xFFC */
+} SPI_Type;
+
+/* ----------------------------------------------------------------------------
+   -- SPI Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SPI_Register_Masks SPI Register Masks
+ * @{
+ */
+
+/*! @name CFG - SPI Configuration register */
+/*! @{ */
+#define SPI_CFG_ENABLE_MASK                      (0x1U)
+#define SPI_CFG_ENABLE_SHIFT                     (0U)
+/*! ENABLE - SPI enable.
+ */
+#define SPI_CFG_ENABLE(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_CFG_ENABLE_SHIFT)) & SPI_CFG_ENABLE_MASK)
+#define SPI_CFG_MASTER_MASK                      (0x4U)
+#define SPI_CFG_MASTER_SHIFT                     (2U)
+/*! MASTER - Master mode select.
+ */
+#define SPI_CFG_MASTER(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_CFG_MASTER_SHIFT)) & SPI_CFG_MASTER_MASK)
+#define SPI_CFG_LSBF_MASK                        (0x8U)
+#define SPI_CFG_LSBF_SHIFT                       (3U)
+/*! LSBF - LSB First mode enable.
+ */
+#define SPI_CFG_LSBF(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LSBF_SHIFT)) & SPI_CFG_LSBF_MASK)
+#define SPI_CFG_CPHA_MASK                        (0x10U)
+#define SPI_CFG_CPHA_SHIFT                       (4U)
+/*! CPHA - Clock Phase select.
+ */
+#define SPI_CFG_CPHA(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPHA_SHIFT)) & SPI_CFG_CPHA_MASK)
+#define SPI_CFG_CPOL_MASK                        (0x20U)
+#define SPI_CFG_CPOL_SHIFT                       (5U)
+/*! CPOL - Clock Polarity select.
+ */
+#define SPI_CFG_CPOL(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPOL_SHIFT)) & SPI_CFG_CPOL_MASK)
+#define SPI_CFG_LOOP_MASK                        (0x80U)
+#define SPI_CFG_LOOP_SHIFT                       (7U)
+/*! LOOP - Loopback mode enable. Loopback mode applies only to Master mode, and connects transmit
+ *    and receive data connected together to allow simple software testing.
+ */
+#define SPI_CFG_LOOP(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LOOP_SHIFT)) & SPI_CFG_LOOP_MASK)
+#define SPI_CFG_SPOL0_MASK                       (0x100U)
+#define SPI_CFG_SPOL0_SHIFT                      (8U)
+/*! SPOL0 - SSEL0 Polarity select.
+ */
+#define SPI_CFG_SPOL0(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL0_SHIFT)) & SPI_CFG_SPOL0_MASK)
+#define SPI_CFG_SPOL1_MASK                       (0x200U)
+#define SPI_CFG_SPOL1_SHIFT                      (9U)
+/*! SPOL1 - SSEL1 Polarity select. Valid only for SPI-1
+ */
+#define SPI_CFG_SPOL1(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL1_SHIFT)) & SPI_CFG_SPOL1_MASK)
+#define SPI_CFG_SPOL2_MASK                       (0x400U)
+#define SPI_CFG_SPOL2_SHIFT                      (10U)
+/*! SPOL2 - SSEL2 Polarity select. Valid only for SPI-1
+ */
+#define SPI_CFG_SPOL2(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL2_SHIFT)) & SPI_CFG_SPOL2_MASK)
+/*! @} */
+
+/*! @name DLY - SPI Delay register */
+/*! @{ */
+#define SPI_DLY_PRE_DELAY_MASK                   (0xFU)
+#define SPI_DLY_PRE_DELAY_SHIFT                  (0U)
+/*! PRE_DELAY - Controls the amount of time between SSEL assertion and the beginning of a data
+ *    transfer. There is always one SPI clock time between SSEL assertion and the first clock edge. This
+ *    is not considered part of the pre-delay. 0x0 = No additional time is inserted. 0x1 = 1 SPI
+ *    clock time is inserted. 0x2 = 2 SPI clock times are inserted. ... 0xF = 15 SPI clock times are
+ *    inserted.
+ */
+#define SPI_DLY_PRE_DELAY(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_DLY_PRE_DELAY_SHIFT)) & SPI_DLY_PRE_DELAY_MASK)
+#define SPI_DLY_POST_DELAY_MASK                  (0xF0U)
+#define SPI_DLY_POST_DELAY_SHIFT                 (4U)
+/*! POST_DELAY - Controls the amount of time between the end of a data transfer and SSEL
+ *    deassertion. 0x0 = No additional time is inserted. 0x1 = 1 SPI clock time is inserted. 0x2 = 2 SPI clock
+ *    times are inserted. ... 0xF = 15 SPI clock times are inserted.
+ */
+#define SPI_DLY_POST_DELAY(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_DLY_POST_DELAY_SHIFT)) & SPI_DLY_POST_DELAY_MASK)
+#define SPI_DLY_FRAME_DELAY_MASK                 (0xF00U)
+#define SPI_DLY_FRAME_DELAY_SHIFT                (8U)
+/*! FRAME_DELAY - If the EOFR flag is set, controls the minimum amount of time between the current
+ *    frame and the next frame (or SSEL deassertion if EOTR). 0x0 = No additional time is inserted.
+ *    0x1 = 1 SPI clock time is inserted. 0x2 = 2 SPI clock times are inserted. ... 0xF = 15 SPI
+ *    clock times are inserted.
+ */
+#define SPI_DLY_FRAME_DELAY(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_DLY_FRAME_DELAY_SHIFT)) & SPI_DLY_FRAME_DELAY_MASK)
+#define SPI_DLY_TRANSFER_DELAY_MASK              (0xF000U)
+#define SPI_DLY_TRANSFER_DELAY_SHIFT             (12U)
+/*! TRANSFER_DELAY - Controls the minimum amount of time that the SSEL is deasserted between
+ *    transfers. 0x0 = The minimum time that SSEL is deasserted is 1 SPI clock time. (Zero added time.) 0x1
+ *    = The minimum time that SSEL is deasserted is 2 SPI clock times. 0x2 = The minimum time that
+ *    SSEL is deasserted is 3 SPI clock times. ... 0xF = The minimum time that SSEL is deasserted is
+ *    16 SPI clock times.
+ */
+#define SPI_DLY_TRANSFER_DELAY(x)                (((uint32_t)(((uint32_t)(x)) << SPI_DLY_TRANSFER_DELAY_SHIFT)) & SPI_DLY_TRANSFER_DELAY_MASK)
+/*! @} */
+
+/*! @name STAT - SPI Status. Some status flags can be cleared by writing a 1 to that bit position. */
+/*! @{ */
+#define SPI_STAT_RXOV_MASK                       (0x4U)
+#define SPI_STAT_RXOV_SHIFT                      (2U)
+/*! RXOV - Receiver Overrun interrupt flag. This flag applies only to slave mode (Master = 0). This
+ *    flag is set when the beginning of a received character is detected while the receiver buffer
+ *    is still in use. If this occurs, the receiver buffer contents are preserved, and the incoming
+ *    data is lost. Data received by the SPI should be considered undefined if RxOv is set.
+ */
+#define SPI_STAT_RXOV(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_STAT_RXOV_SHIFT)) & SPI_STAT_RXOV_MASK)
+#define SPI_STAT_TXUR_MASK                       (0x8U)
+#define SPI_STAT_TXUR_SHIFT                      (3U)
+/*! TXUR - Transmitter Underrun interrupt flag. This flag applies only to slave mode (Master = 0).
+ *    In this case, the transmitter must begin sending new data on the next input clock if the
+ *    transmitter is idle. If that data is not available in the transmitter holding register at that
+ *    point, there is no data to transmit and the TXUR flag is set. Data transmitted by the SPI should be
+ *    considered undefined if TXUR is set.
+ */
+#define SPI_STAT_TXUR(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_STAT_TXUR_SHIFT)) & SPI_STAT_TXUR_MASK)
+#define SPI_STAT_SSA_MASK                        (0x10U)
+#define SPI_STAT_SSA_SHIFT                       (4U)
+/*! SSA - Slave Select Assert. This flag is set whenever any slave select transitions from
+ *    deasserted to asserted, in both master and slave modes. This allows determining when the SPI
+ *    transmit/receive functions become busy, and allows waking up the device from reduced power modes when a
+ *    slave mode access begins. This flag is cleared by software.
+ */
+#define SPI_STAT_SSA(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSA_SHIFT)) & SPI_STAT_SSA_MASK)
+#define SPI_STAT_SSD_MASK                        (0x20U)
+#define SPI_STAT_SSD_SHIFT                       (5U)
+/*! SSD - Slave Select Deassert. This flag is set whenever any asserted slave selects transition to
+ *    deasserted, in both master and slave modes. This allows determining when the SPI
+ *    transmit/receive functions become idle. This flag is cleared by software.
+ */
+#define SPI_STAT_SSD(x)                          (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSD_SHIFT)) & SPI_STAT_SSD_MASK)
+#define SPI_STAT_STALLED_MASK                    (0x40U)
+#define SPI_STAT_STALLED_SHIFT                   (6U)
+/*! STALLED - Stalled status flag. This indicates whether the SPI is currently in a stall condition.
+ */
+#define SPI_STAT_STALLED(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_STAT_STALLED_SHIFT)) & SPI_STAT_STALLED_MASK)
+#define SPI_STAT_ENDTRANSFER_MASK                (0x80U)
+#define SPI_STAT_ENDTRANSFER_SHIFT               (7U)
+/*! ENDTRANSFER - End Transfer control bit. Software can set this bit to force an end to the current
+ *    transfer when the transmitter finishes any activity already in progress, as if the EOTR flag
+ *    had been set prior to the last transmission. This capability is included to support cases
+ *    where it is not known when transmit data is written that it will be the end of a transfer. The bit
+ *    is cleared when the transmitter becomes idle as the transfer comes to an end. Forcing an end
+ *    of transfer in this manner causes any specified FRAME_DELAY and TRANSFER_DELAY to be inserted.
+ */
+#define SPI_STAT_ENDTRANSFER(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_STAT_ENDTRANSFER_SHIFT)) & SPI_STAT_ENDTRANSFER_MASK)
+#define SPI_STAT_MSTIDLE_MASK                    (0x100U)
+#define SPI_STAT_MSTIDLE_SHIFT                   (8U)
+/*! MSTIDLE - Master idle status flag. This bit is 1 whenever the SPI master function is fully idle.
+ *    This means that the transmit holding register is empty and the transmitter is not in the
+ *    process of sending data.
+ */
+#define SPI_STAT_MSTIDLE(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_STAT_MSTIDLE_SHIFT)) & SPI_STAT_MSTIDLE_MASK)
+/*! @} */
+
+/*! @name INTENSET - SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */
+/*! @{ */
+#define SPI_INTENSET_RXOVEN_MASK                 (0x4U)
+#define SPI_INTENSET_RXOVEN_SHIFT                (2U)
+/*! RXOVEN - RX overrun interrupt enable. Determines whether an interrupt occurs when a receiver
+ *    overrun occurs. This happens in slave mode when there is a need for the receiver to move newly
+ *    received data to the RXDAT register when it is already in use. The interface prevents receiver
+ *    overrun in Master mode by not allowing a new transmission to begin when a receiver overrun
+ *    would otherwise occur.
+ */
+#define SPI_INTENSET_RXOVEN(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_RXOVEN_SHIFT)) & SPI_INTENSET_RXOVEN_MASK)
+#define SPI_INTENSET_TXUREN_MASK                 (0x8U)
+#define SPI_INTENSET_TXUREN_SHIFT                (3U)
+/*! TXUREN - TX underrun interrupt enable. Determines whether an interrupt occurs when a transmitter
+ *    underrun occurs. This happens in slave mode when there is a need to transmit data when none
+ *    is available.
+ */
+#define SPI_INTENSET_TXUREN(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_TXUREN_SHIFT)) & SPI_INTENSET_TXUREN_MASK)
+#define SPI_INTENSET_SSAEN_MASK                  (0x10U)
+#define SPI_INTENSET_SSAEN_SHIFT                 (4U)
+/*! SSAEN - Slave select assert interrupt enable. Determines whether an interrupt occurs when the Slave Select is asserted.
+ */
+#define SPI_INTENSET_SSAEN(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSAEN_SHIFT)) & SPI_INTENSET_SSAEN_MASK)
+#define SPI_INTENSET_SSDEN_MASK                  (0x20U)
+#define SPI_INTENSET_SSDEN_SHIFT                 (5U)
+/*! SSDEN - Slave select deassert interrupt enable. Determines whether an interrupt occurs when the Slave Select is deasserted.
+ */
+#define SPI_INTENSET_SSDEN(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSDEN_SHIFT)) & SPI_INTENSET_SSDEN_MASK)
+#define SPI_INTENSET_MSTIDLEEN_MASK              (0x100U)
+#define SPI_INTENSET_MSTIDLEEN_SHIFT             (8U)
+/*! MSTIDLEEN - Master idle interrupt enable.
+ */
+#define SPI_INTENSET_MSTIDLEEN(x)                (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_MSTIDLEEN_SHIFT)) & SPI_INTENSET_MSTIDLEEN_MASK)
+/*! @} */
+
+/*! @name INTENCLR - SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared. */
+/*! @{ */
+#define SPI_INTENCLR_RXOVCLR_MASK                (0x4U)
+#define SPI_INTENCLR_RXOVCLR_SHIFT               (2U)
+/*! RXOVCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_RXOVCLR(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_RXOVCLR_SHIFT)) & SPI_INTENCLR_RXOVCLR_MASK)
+#define SPI_INTENCLR_TXURCLR_MASK                (0x8U)
+#define SPI_INTENCLR_TXURCLR_SHIFT               (3U)
+/*! TXURCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_TXURCLR(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_TXURCLR_SHIFT)) & SPI_INTENCLR_TXURCLR_MASK)
+#define SPI_INTENCLR_SSACLR_MASK                 (0x10U)
+#define SPI_INTENCLR_SSACLR_SHIFT                (4U)
+/*! SSACLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_SSACLR(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSACLR_SHIFT)) & SPI_INTENCLR_SSACLR_MASK)
+#define SPI_INTENCLR_SSDCLR_MASK                 (0x20U)
+#define SPI_INTENCLR_SSDCLR_SHIFT                (5U)
+/*! SSDCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_SSDCLR(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSDCLR_SHIFT)) & SPI_INTENCLR_SSDCLR_MASK)
+#define SPI_INTENCLR_MSTIDLECLR_MASK             (0x100U)
+#define SPI_INTENCLR_MSTIDLECLR_SHIFT            (8U)
+/*! MSTIDLECLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define SPI_INTENCLR_MSTIDLECLR(x)               (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_MSTIDLECLR_SHIFT)) & SPI_INTENCLR_MSTIDLECLR_MASK)
+/*! @} */
+
+/*! @name TXCTL - SPI Transmit Control. If Transmit FIFO is enabled, in FIFOCFG, then values read in this register are affected values in FIFO. */
+/*! @{ */
+#define SPI_TXCTL_TXSSEL0_N_MASK                 (0x10000U)
+#define SPI_TXCTL_TXSSEL0_N_SHIFT                (16U)
+/*! TXSSEL0_N - Transmit Slave Select 0.
+ */
+#define SPI_TXCTL_TXSSEL0_N(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL0_N_SHIFT)) & SPI_TXCTL_TXSSEL0_N_MASK)
+#define SPI_TXCTL_TXSSEL1_N_MASK                 (0x20000U)
+#define SPI_TXCTL_TXSSEL1_N_SHIFT                (17U)
+/*! TXSSEL1_N - Transmit Slave Select 1. Valid only for SPI-1
+ */
+#define SPI_TXCTL_TXSSEL1_N(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL1_N_SHIFT)) & SPI_TXCTL_TXSSEL1_N_MASK)
+#define SPI_TXCTL_TXSSEL2_N_MASK                 (0x40000U)
+#define SPI_TXCTL_TXSSEL2_N_SHIFT                (18U)
+/*! TXSSEL2_N - Transmit Slave Select 2. Valid only for SPI-1
+ */
+#define SPI_TXCTL_TXSSEL2_N(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL2_N_SHIFT)) & SPI_TXCTL_TXSSEL2_N_MASK)
+#define SPI_TXCTL_TXSSEL3_N_MASK                 (0x80000U)
+#define SPI_TXCTL_TXSSEL3_N_SHIFT                (19U)
+/*! TXSSEL3_N - [Reserved] Transmit Slave Select 3.
+ */
+#define SPI_TXCTL_TXSSEL3_N(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL3_N_SHIFT)) & SPI_TXCTL_TXSSEL3_N_MASK)
+#define SPI_TXCTL_EOTR_MASK                      (0x100000U)
+#define SPI_TXCTL_EOTR_SHIFT                     (20U)
+/*! EOTR - End of Transfer.
+ */
+#define SPI_TXCTL_EOTR(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_EOTR_SHIFT)) & SPI_TXCTL_EOTR_MASK)
+#define SPI_TXCTL_EOFR_MASK                      (0x200000U)
+#define SPI_TXCTL_EOFR_SHIFT                     (21U)
+/*! EOFR - End of Frame.
+ */
+#define SPI_TXCTL_EOFR(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_EOFR_SHIFT)) & SPI_TXCTL_EOFR_MASK)
+#define SPI_TXCTL_RXIGNORE_MASK                  (0x400000U)
+#define SPI_TXCTL_RXIGNORE_SHIFT                 (22U)
+/*! RXIGNORE - Receive Ignore.
+ */
+#define SPI_TXCTL_RXIGNORE(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_RXIGNORE_SHIFT)) & SPI_TXCTL_RXIGNORE_MASK)
+#define SPI_TXCTL_LEN_MASK                       (0xF000000U)
+#define SPI_TXCTL_LEN_SHIFT                      (24U)
+/*! LEN - Data transfer Length.
+ */
+#define SPI_TXCTL_LEN(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_LEN_SHIFT)) & SPI_TXCTL_LEN_MASK)
+/*! @} */
+
+/*! @name DIV - SPI clock Divider */
+/*! @{ */
+#define SPI_DIV_DIVVAL_MASK                      (0xFFFFU)
+#define SPI_DIV_DIVVAL_SHIFT                     (0U)
+/*! DIVVAL - Rate divider value. Specifies how the SPI Module clock is divided to produce the SPI
+ *    clock rate in master mode. DIVVAL is -1 encoded such that the value 0 results in SPICLK/1, the
+ *    value 1 results in SPICLK/2, up to the maximum possible divide value of 0xFFFF, which results
+ *    in SPICLK/65536.
+ */
+#define SPI_DIV_DIVVAL(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_DIV_DIVVAL_SHIFT)) & SPI_DIV_DIVVAL_MASK)
+/*! @} */
+
+/*! @name INTSTAT - SPI Interrupt Status */
+/*! @{ */
+#define SPI_INTSTAT_RXOV_MASK                    (0x4U)
+#define SPI_INTSTAT_RXOV_SHIFT                   (2U)
+/*! RXOV - Receiver Overrun interrupt flag.
+ */
+#define SPI_INTSTAT_RXOV(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_RXOV_SHIFT)) & SPI_INTSTAT_RXOV_MASK)
+#define SPI_INTSTAT_TXUR_MASK                    (0x8U)
+#define SPI_INTSTAT_TXUR_SHIFT                   (3U)
+/*! TXUR - Transmitter Underrun interrupt flag.
+ */
+#define SPI_INTSTAT_TXUR(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_TXUR_SHIFT)) & SPI_INTSTAT_TXUR_MASK)
+#define SPI_INTSTAT_SSA_MASK                     (0x10U)
+#define SPI_INTSTAT_SSA_SHIFT                    (4U)
+/*! SSA - Slave Select Assert.
+ */
+#define SPI_INTSTAT_SSA(x)                       (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSA_SHIFT)) & SPI_INTSTAT_SSA_MASK)
+#define SPI_INTSTAT_SSD_MASK                     (0x20U)
+#define SPI_INTSTAT_SSD_SHIFT                    (5U)
+/*! SSD - Slave Select Deassert.
+ */
+#define SPI_INTSTAT_SSD(x)                       (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSD_SHIFT)) & SPI_INTSTAT_SSD_MASK)
+#define SPI_INTSTAT_MSTIDLE_MASK                 (0x100U)
+#define SPI_INTSTAT_MSTIDLE_SHIFT                (8U)
+/*! MSTIDLE - Master Idle status flag.
+ */
+#define SPI_INTSTAT_MSTIDLE(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_MSTIDLE_SHIFT)) & SPI_INTSTAT_MSTIDLE_MASK)
+/*! @} */
+
+/*! @name FIFOCFG - FIFO configuration and enable register. */
+/*! @{ */
+#define SPI_FIFOCFG_ENABLETX_MASK                (0x1U)
+#define SPI_FIFOCFG_ENABLETX_SHIFT               (0U)
+/*! ENABLETX - Enable the transmit FIFO. This is automatically enabled when PSELID.PERSEL is set to
+ *    2 to configure for SPI functionality
+ */
+#define SPI_FIFOCFG_ENABLETX(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_ENABLETX_SHIFT)) & SPI_FIFOCFG_ENABLETX_MASK)
+#define SPI_FIFOCFG_ENABLERX_MASK                (0x2U)
+#define SPI_FIFOCFG_ENABLERX_SHIFT               (1U)
+/*! ENABLERX - Enable the receive FIFO. This is automatically enabled when PSELID.PERSEL is set to 2 to configure for SPI functionality
+ */
+#define SPI_FIFOCFG_ENABLERX(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_ENABLERX_SHIFT)) & SPI_FIFOCFG_ENABLERX_MASK)
+#define SPI_FIFOCFG_SIZE_MASK                    (0x30U)
+#define SPI_FIFOCFG_SIZE_SHIFT                   (4U)
+/*! SIZE - FIFO size configuration. This is a read-only field. 0x0 = Reset value. 0x1 = FIFO is
+ *    configured as 4 entries of 16bits. This value is read after PSELID.PERSEL=2 for SPI functionlaity.
+ *    0x2, 0x3 = not applicable.
+ */
+#define SPI_FIFOCFG_SIZE(x)                      (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_SIZE_SHIFT)) & SPI_FIFOCFG_SIZE_MASK)
+#define SPI_FIFOCFG_DMATX_MASK                   (0x1000U)
+#define SPI_FIFOCFG_DMATX_SHIFT                  (12U)
+/*! DMATX - DMA configuration for transmit.
+ */
+#define SPI_FIFOCFG_DMATX(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_DMATX_SHIFT)) & SPI_FIFOCFG_DMATX_MASK)
+#define SPI_FIFOCFG_DMARX_MASK                   (0x2000U)
+#define SPI_FIFOCFG_DMARX_SHIFT                  (13U)
+/*! DMARX - DMA configuration for receive.
+ */
+#define SPI_FIFOCFG_DMARX(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_DMARX_SHIFT)) & SPI_FIFOCFG_DMARX_MASK)
+#define SPI_FIFOCFG_EMPTYTX_MASK                 (0x10000U)
+#define SPI_FIFOCFG_EMPTYTX_SHIFT                (16U)
+/*! EMPTYTX - Empty command for the transmit FIFO. When a 1 is written to this bit, the TX FIFO is emptied.
+ */
+#define SPI_FIFOCFG_EMPTYTX(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_EMPTYTX_SHIFT)) & SPI_FIFOCFG_EMPTYTX_MASK)
+#define SPI_FIFOCFG_EMPTYRX_MASK                 (0x20000U)
+#define SPI_FIFOCFG_EMPTYRX_SHIFT                (17U)
+/*! EMPTYRX - Empty command for the receive FIFO. When a 1 is written to this bit, the RX FIFO is emptied.
+ */
+#define SPI_FIFOCFG_EMPTYRX(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_EMPTYRX_SHIFT)) & SPI_FIFOCFG_EMPTYRX_MASK)
+#define SPI_FIFOCFG_POPDBG_MASK                  (0x40000U)
+#define SPI_FIFOCFG_POPDBG_SHIFT                 (18U)
+/*! POPDBG - Pop FIFO for debug reads.
+ */
+#define SPI_FIFOCFG_POPDBG(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_POPDBG_SHIFT)) & SPI_FIFOCFG_POPDBG_MASK)
+/*! @} */
+
+/*! @name FIFOSTAT - FIFO status register. */
+/*! @{ */
+#define SPI_FIFOSTAT_TXERR_MASK                  (0x1U)
+#define SPI_FIFOSTAT_TXERR_SHIFT                 (0U)
+/*! TXERR - TX FIFO error. Will be set if a transmit FIFO error occurs. This could be an overflow
+ *    caused by pushing data into a full FIFO, or by an underflow if the FIFO is empty when data is
+ *    needed. Cleared by writing a 1 to this bit.
+ */
+#define SPI_FIFOSTAT_TXERR(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXERR_SHIFT)) & SPI_FIFOSTAT_TXERR_MASK)
+#define SPI_FIFOSTAT_RXERR_MASK                  (0x2U)
+#define SPI_FIFOSTAT_RXERR_SHIFT                 (1U)
+/*! RXERR - RX FIFO error. Will be set if a receive FIFO overflow occurs, caused by software or DMA
+ *    not emptying the FIFO fast enough. Cleared by writing a 1 to this bit.
+ */
+#define SPI_FIFOSTAT_RXERR(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXERR_SHIFT)) & SPI_FIFOSTAT_RXERR_MASK)
+#define SPI_FIFOSTAT_PERINT_MASK                 (0x8U)
+#define SPI_FIFOSTAT_PERINT_SHIFT                (3U)
+/*! PERINT - Peripheral interrupt. When 1, this indicates that the peripheral function has asserted
+ *    an interrupt. The details can be found by reading the peripheral s STAT register.
+ */
+#define SPI_FIFOSTAT_PERINT(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_PERINT_SHIFT)) & SPI_FIFOSTAT_PERINT_MASK)
+#define SPI_FIFOSTAT_TXEMPTY_MASK                (0x10U)
+#define SPI_FIFOSTAT_TXEMPTY_SHIFT               (4U)
+/*! TXEMPTY - Transmit FIFO empty. When 1, the transmit FIFO is empty. The peripheral may still be processing the last piece of data.
+ */
+#define SPI_FIFOSTAT_TXEMPTY(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXEMPTY_SHIFT)) & SPI_FIFOSTAT_TXEMPTY_MASK)
+#define SPI_FIFOSTAT_TXNOTFULL_MASK              (0x20U)
+#define SPI_FIFOSTAT_TXNOTFULL_SHIFT             (5U)
+/*! TXNOTFULL - Transmit FIFO not full. When 1, the transmit FIFO is not full, so more data can be
+ *    written. When 0, the transmit FIFO is full and another write would cause it to overflow.
+ */
+#define SPI_FIFOSTAT_TXNOTFULL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXNOTFULL_SHIFT)) & SPI_FIFOSTAT_TXNOTFULL_MASK)
+#define SPI_FIFOSTAT_RXNOTEMPTY_MASK             (0x40U)
+#define SPI_FIFOSTAT_RXNOTEMPTY_SHIFT            (6U)
+/*! RXNOTEMPTY - Receive FIFO not empty. When 1, the receive FIFO is not empty, so data can be read. When 0, the receive FIFO is empty.
+ */
+#define SPI_FIFOSTAT_RXNOTEMPTY(x)               (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXNOTEMPTY_SHIFT)) & SPI_FIFOSTAT_RXNOTEMPTY_MASK)
+#define SPI_FIFOSTAT_RXFULL_MASK                 (0x80U)
+#define SPI_FIFOSTAT_RXFULL_SHIFT                (7U)
+/*! RXFULL - Receive FIFO full. When 1, the receive FIFO is full. Data needs to be read out to
+ *    prevent the peripheral from causing an overflow.
+ */
+#define SPI_FIFOSTAT_RXFULL(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXFULL_SHIFT)) & SPI_FIFOSTAT_RXFULL_MASK)
+#define SPI_FIFOSTAT_TXLVL_MASK                  (0x1F00U)
+#define SPI_FIFOSTAT_TXLVL_SHIFT                 (8U)
+/*! TXLVL - Transmit FIFO current level. A 0 means the TX FIFO is currently empty, and the TXEMPTY
+ *    and TXNOTFULL flags will be 1. Other values tell how much data is actually in the TX FIFO at
+ *    the point where the read occurs. If the TX FIFO is full, the TXEMPTY and TXNOTFULL flags will be
+ *    0.
+ */
+#define SPI_FIFOSTAT_TXLVL(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXLVL_SHIFT)) & SPI_FIFOSTAT_TXLVL_MASK)
+#define SPI_FIFOSTAT_RXLVL_MASK                  (0x1F0000U)
+#define SPI_FIFOSTAT_RXLVL_SHIFT                 (16U)
+/*! RXLVL - Receive FIFO current level. A 0 means the RX FIFO is currently empty, and the RXFULL and
+ *    RXNOTEMPTY flags will be 0. Other values tell how much data is actually in the RX FIFO at the
+ *    point where the read occurs. If the RX FIFO is full, the RXFULL and RXNOTEMPTY flags will be
+ *    1.
+ */
+#define SPI_FIFOSTAT_RXLVL(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXLVL_SHIFT)) & SPI_FIFOSTAT_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOTRIG - FIFO trigger settings for interrupt and DMA request. */
+/*! @{ */
+#define SPI_FIFOTRIG_TXLVLENA_MASK               (0x1U)
+#define SPI_FIFOTRIG_TXLVLENA_SHIFT              (0U)
+/*! TXLVLENA - Transmit FIFO level trigger enable. This trigger will become an interrupt if enabled
+ *    in FIFOINTENSET, or a DMA trigger if DMATX in FIFOCFG is set.
+ */
+#define SPI_FIFOTRIG_TXLVLENA(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_TXLVLENA_SHIFT)) & SPI_FIFOTRIG_TXLVLENA_MASK)
+#define SPI_FIFOTRIG_RXLVLENA_MASK               (0x2U)
+#define SPI_FIFOTRIG_RXLVLENA_SHIFT              (1U)
+/*! RXLVLENA - Receive FIFO level trigger enable. This trigger will become an interrupt if enabled
+ *    in FIFOINTENSET, or a DMA trigger if DMARX in FIFOCFG is set.
+ */
+#define SPI_FIFOTRIG_RXLVLENA(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_RXLVLENA_SHIFT)) & SPI_FIFOTRIG_RXLVLENA_MASK)
+#define SPI_FIFOTRIG_TXLVL_MASK                  (0xF00U)
+#define SPI_FIFOTRIG_TXLVL_SHIFT                 (8U)
+/*! TXLVL - Transmit FIFO level trigger point. This field is used only when TXLVLENA = 1. 0 =
+ *    trigger when the TX FIFO becomes empty. 1 = trigger when the TX FIFO level decreases to one entry.
+ *    ... 7 = 1 = trigger when the TX FIFO level decreases to 7 entries (is no longer full).
+ */
+#define SPI_FIFOTRIG_TXLVL(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_TXLVL_SHIFT)) & SPI_FIFOTRIG_TXLVL_MASK)
+#define SPI_FIFOTRIG_RXLVL_MASK                  (0xF0000U)
+#define SPI_FIFOTRIG_RXLVL_SHIFT                 (16U)
+/*! RXLVL - Receive FIFO level trigger point. The RX FIFO level is checked when a new piece of data
+ *    is received. This field is used only when RXLVLENA = 1. 0 = trigger when the RX FIFO has
+ *    received one entry (is no longer empty). 1 = trigger when the RX FIFO has received two entries. ...
+ *    7 = trigger when the RX FIFO has received 8 entries (has become full).
+ */
+#define SPI_FIFOTRIG_RXLVL(x)                    (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_RXLVL_SHIFT)) & SPI_FIFOTRIG_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTENSET - FIFO interrupt enable set (enable) and read register. */
+/*! @{ */
+#define SPI_FIFOINTENSET_TXERR_MASK              (0x1U)
+#define SPI_FIFOINTENSET_TXERR_SHIFT             (0U)
+/*! TXERR - Determines whether an interrupt occurs when a transmit error occurs, based on the TXERR flag in the FIFOSTAT register.
+ */
+#define SPI_FIFOINTENSET_TXERR(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_TXERR_SHIFT)) & SPI_FIFOINTENSET_TXERR_MASK)
+#define SPI_FIFOINTENSET_RXERR_MASK              (0x2U)
+#define SPI_FIFOINTENSET_RXERR_SHIFT             (1U)
+/*! RXERR - Determines whether an interrupt occurs when a receive error occurs, based on the RXERR flag in the FIFOSTAT register.
+ */
+#define SPI_FIFOINTENSET_RXERR(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_RXERR_SHIFT)) & SPI_FIFOINTENSET_RXERR_MASK)
+#define SPI_FIFOINTENSET_TXLVL_MASK              (0x4U)
+#define SPI_FIFOINTENSET_TXLVL_SHIFT             (2U)
+/*! TXLVL - Determines whether an interrupt occurs when a the transmit FIFO reaches the level
+ *    specified by the TXLVL field in the FIFOTRIG register.
+ */
+#define SPI_FIFOINTENSET_TXLVL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_TXLVL_SHIFT)) & SPI_FIFOINTENSET_TXLVL_MASK)
+#define SPI_FIFOINTENSET_RXLVL_MASK              (0x8U)
+#define SPI_FIFOINTENSET_RXLVL_SHIFT             (3U)
+/*! RXLVL - Determines whether an interrupt occurs when a the receive FIFO reaches the level
+ *    specified by the TXLVL field in the FIFOTRIG register.
+ */
+#define SPI_FIFOINTENSET_RXLVL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_RXLVL_SHIFT)) & SPI_FIFOINTENSET_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTENCLR - FIFO interrupt enable clear (disable) and read register. */
+/*! @{ */
+#define SPI_FIFOINTENCLR_TXERR_MASK              (0x1U)
+#define SPI_FIFOINTENCLR_TXERR_SHIFT             (0U)
+/*! TXERR - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define SPI_FIFOINTENCLR_TXERR(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_TXERR_SHIFT)) & SPI_FIFOINTENCLR_TXERR_MASK)
+#define SPI_FIFOINTENCLR_RXERR_MASK              (0x2U)
+#define SPI_FIFOINTENCLR_RXERR_SHIFT             (1U)
+/*! RXERR - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define SPI_FIFOINTENCLR_RXERR(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_RXERR_SHIFT)) & SPI_FIFOINTENCLR_RXERR_MASK)
+#define SPI_FIFOINTENCLR_TXLVL_MASK              (0x4U)
+#define SPI_FIFOINTENCLR_TXLVL_SHIFT             (2U)
+/*! TXLVL - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define SPI_FIFOINTENCLR_TXLVL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_TXLVL_SHIFT)) & SPI_FIFOINTENCLR_TXLVL_MASK)
+#define SPI_FIFOINTENCLR_RXLVL_MASK              (0x8U)
+#define SPI_FIFOINTENCLR_RXLVL_SHIFT             (3U)
+/*! RXLVL - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define SPI_FIFOINTENCLR_RXLVL(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_RXLVL_SHIFT)) & SPI_FIFOINTENCLR_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTSTAT - FIFO interrupt status register. */
+/*! @{ */
+#define SPI_FIFOINTSTAT_TXERR_MASK               (0x1U)
+#define SPI_FIFOINTSTAT_TXERR_SHIFT              (0U)
+/*! TXERR - TX FIFO error.
+ */
+#define SPI_FIFOINTSTAT_TXERR(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_TXERR_SHIFT)) & SPI_FIFOINTSTAT_TXERR_MASK)
+#define SPI_FIFOINTSTAT_RXERR_MASK               (0x2U)
+#define SPI_FIFOINTSTAT_RXERR_SHIFT              (1U)
+/*! RXERR - RX FIFO error.
+ */
+#define SPI_FIFOINTSTAT_RXERR(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_RXERR_SHIFT)) & SPI_FIFOINTSTAT_RXERR_MASK)
+#define SPI_FIFOINTSTAT_TXLVL_MASK               (0x4U)
+#define SPI_FIFOINTSTAT_TXLVL_SHIFT              (2U)
+/*! TXLVL - Transmit FIFO level interrupt.
+ */
+#define SPI_FIFOINTSTAT_TXLVL(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_TXLVL_SHIFT)) & SPI_FIFOINTSTAT_TXLVL_MASK)
+#define SPI_FIFOINTSTAT_RXLVL_MASK               (0x8U)
+#define SPI_FIFOINTSTAT_RXLVL_SHIFT              (3U)
+/*! RXLVL - Receive FIFO level interrupt.
+ */
+#define SPI_FIFOINTSTAT_RXLVL(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_RXLVL_SHIFT)) & SPI_FIFOINTSTAT_RXLVL_MASK)
+#define SPI_FIFOINTSTAT_PERINT_MASK              (0x10U)
+#define SPI_FIFOINTSTAT_PERINT_SHIFT             (4U)
+/*! PERINT - Peripheral interrupt.
+ */
+#define SPI_FIFOINTSTAT_PERINT(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_PERINT_SHIFT)) & SPI_FIFOINTSTAT_PERINT_MASK)
+/*! @} */
+
+/*! @name FIFOWR - FIFO write data. FIFO data not reset by block reset */
+/*! @{ */
+#define SPI_FIFOWR_TXDATA_MASK                   (0xFFFFU)
+#define SPI_FIFOWR_TXDATA_SHIFT                  (0U)
+/*! TXDATA - Transmit data to the FIFO.
+ */
+#define SPI_FIFOWR_TXDATA(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXDATA_SHIFT)) & SPI_FIFOWR_TXDATA_MASK)
+#define SPI_FIFOWR_TXSSEL0_N_MASK                (0x10000U)
+#define SPI_FIFOWR_TXSSEL0_N_SHIFT               (16U)
+/*! TXSSEL0_N - Transmit Slave Select. This field asserts SSEL0 in master mode. The output on the
+ *    pin is active LOW by default. Remark: The active state of the SSEL0 pin is configured by bits in
+ *    the CFG register.
+ */
+#define SPI_FIFOWR_TXSSEL0_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL0_N_SHIFT)) & SPI_FIFOWR_TXSSEL0_N_MASK)
+#define SPI_FIFOWR_TXSSEL1_N_MASK                (0x20000U)
+#define SPI_FIFOWR_TXSSEL1_N_SHIFT               (17U)
+/*! TXSSEL1_N - Transmit Slave Select. This field asserts SSEL1 in master mode. The output on the
+ *    pin is active LOW by default. Remark: The active state of the SSEL1 pin is configured by bits in
+ *    the CFG register.
+ */
+#define SPI_FIFOWR_TXSSEL1_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL1_N_SHIFT)) & SPI_FIFOWR_TXSSEL1_N_MASK)
+#define SPI_FIFOWR_TXSSEL2_N_MASK                (0x40000U)
+#define SPI_FIFOWR_TXSSEL2_N_SHIFT               (18U)
+/*! TXSSEL2_N - Transmit Slave Select. This field asserts SSEL2 in master mode. The output on the
+ *    pin is active LOW by default. Remark: The active state of the SSEL2 pin is configured by bits in
+ *    the CFG register.
+ */
+#define SPI_FIFOWR_TXSSEL2_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL2_N_SHIFT)) & SPI_FIFOWR_TXSSEL2_N_MASK)
+#define SPI_FIFOWR_EOT_MASK                      (0x100000U)
+#define SPI_FIFOWR_EOT_SHIFT                     (20U)
+/*! EOT - End of Transfer. The asserted SSEL will be deasserted at the end of a transfer, and remain
+ *    so for at least the time specified by the Transfer_delay value in the DLY register.
+ */
+#define SPI_FIFOWR_EOT(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_EOT_SHIFT)) & SPI_FIFOWR_EOT_MASK)
+#define SPI_FIFOWR_EOF_MASK                      (0x200000U)
+#define SPI_FIFOWR_EOF_SHIFT                     (21U)
+/*! EOF - End of Frame. Between frames, a delay may be inserted, as defined by the FRAME_DELAY value
+ *    in the DLY register. The end of a frame may not be particularly meaningful if the FRAME_DELAY
+ *    value = 0. This control can be used as part of the support for frame lengths greater than 16
+ *    bits.
+ */
+#define SPI_FIFOWR_EOF(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_EOF_SHIFT)) & SPI_FIFOWR_EOF_MASK)
+#define SPI_FIFOWR_RXIGNORE_MASK                 (0x400000U)
+#define SPI_FIFOWR_RXIGNORE_SHIFT                (22U)
+/*! RXIGNORE - Receive Ignore. This allows data to be transmitted using the SPI without the need to
+ *    read unneeded data from the receiver.Setting this bit simplifies the transmit process and can
+ *    be used with the DMA.
+ */
+#define SPI_FIFOWR_RXIGNORE(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_RXIGNORE_SHIFT)) & SPI_FIFOWR_RXIGNORE_MASK)
+#define SPI_FIFOWR_LEN_MASK                      (0xF000000U)
+#define SPI_FIFOWR_LEN_SHIFT                     (24U)
+/*! LEN - Data Length. Specifies the data length from 1 to 16 bits. Note that transfer lengths
+ *    greater than 16 bits are supported by implementing multiple sequential transmits. 0x0 = Data
+ *    transfer is 1 bit in length. Note: when LEN = 0, the underrun status is not meaningful. 0x1 = Data
+ *    transfer is 2 bits in length. 0x2 = Data transfer is 3 bits in length. ... 0xF = Data transfer
+ *    is 16 bits in length.
+ */
+#define SPI_FIFOWR_LEN(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_LEN_SHIFT)) & SPI_FIFOWR_LEN_MASK)
+/*! @} */
+
+/*! @name FIFORD - FIFO read data. */
+/*! @{ */
+#define SPI_FIFORD_RXDATA_MASK                   (0xFFFFU)
+#define SPI_FIFORD_RXDATA_SHIFT                  (0U)
+/*! RXDATA - Received data from the FIFO.
+ */
+#define SPI_FIFORD_RXDATA(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXDATA_SHIFT)) & SPI_FIFORD_RXDATA_MASK)
+#define SPI_FIFORD_RXSSEL0_N_MASK                (0x10000U)
+#define SPI_FIFORD_RXSSEL0_N_SHIFT               (16U)
+/*! RXSSEL0_N - Slave Select for receive. This field allows the state of the SSEL0 pin to be saved
+ *    along with received data. The value will reflect the SSEL0 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORD_RXSSEL0_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL0_N_SHIFT)) & SPI_FIFORD_RXSSEL0_N_MASK)
+#define SPI_FIFORD_RXSSEL1_N_MASK                (0x20000U)
+#define SPI_FIFORD_RXSSEL1_N_SHIFT               (17U)
+/*! RXSSEL1_N - Slave Select for receive. This field allows the state of the SSEL1 pin to be saved
+ *    along with received data. The value will reflect the SSEL1 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORD_RXSSEL1_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL1_N_SHIFT)) & SPI_FIFORD_RXSSEL1_N_MASK)
+#define SPI_FIFORD_RXSSEL2_N_MASK                (0x40000U)
+#define SPI_FIFORD_RXSSEL2_N_SHIFT               (18U)
+/*! RXSSEL2_N - Slave Select for receive. This field allows the state of the SSEL2 pin to be saved
+ *    along with received data. The value will reflect the SSEL2 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORD_RXSSEL2_N(x)                  (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL2_N_SHIFT)) & SPI_FIFORD_RXSSEL2_N_MASK)
+#define SPI_FIFORD_SOT_MASK                      (0x100000U)
+#define SPI_FIFORD_SOT_SHIFT                     (20U)
+/*! SOT - Start of Transfer flag. This flag will be 1 if this is the first data after the SSELs went
+ *    from deasserted to asserted (i.e., any previous transfer has ended). This information can be
+ *    used to identify the first piece of data in cases where the transfer length is greater than 16
+ *    bit.
+ */
+#define SPI_FIFORD_SOT(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_SOT_SHIFT)) & SPI_FIFORD_SOT_MASK)
+/*! @} */
+
+/*! @name FIFORDNOPOP - FIFO data read with no FIFO pop. */
+/*! @{ */
+#define SPI_FIFORDNOPOP_RXDATA_MASK              (0xFFFFU)
+#define SPI_FIFORDNOPOP_RXDATA_SHIFT             (0U)
+/*! RXDATA - Received data from the FIFO.
+ */
+#define SPI_FIFORDNOPOP_RXDATA(x)                (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXDATA_SHIFT)) & SPI_FIFORDNOPOP_RXDATA_MASK)
+#define SPI_FIFORDNOPOP_RXSSEL0_N_MASK           (0x10000U)
+#define SPI_FIFORDNOPOP_RXSSEL0_N_SHIFT          (16U)
+/*! RXSSEL0_N - Slave Select for receive. This field allows the state of the SSEL0 pin to be saved
+ *    along with received data. The value will reflect the SSEL0 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORDNOPOP_RXSSEL0_N(x)             (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL0_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL0_N_MASK)
+#define SPI_FIFORDNOPOP_RXSSEL1_N_MASK           (0x20000U)
+#define SPI_FIFORDNOPOP_RXSSEL1_N_SHIFT          (17U)
+/*! RXSSEL1_N - Slave Select for receive. This field allows the state of the SSEL1 pin to be saved
+ *    along with received data. The value will reflect the SSEL1 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORDNOPOP_RXSSEL1_N(x)             (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL1_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL1_N_MASK)
+#define SPI_FIFORDNOPOP_RXSSEL2_N_MASK           (0x40000U)
+#define SPI_FIFORDNOPOP_RXSSEL2_N_SHIFT          (18U)
+/*! RXSSEL2_N - Slave Select for receive. This field allows the state of the SSEL2 pin to be saved
+ *    along with received data. The value will reflect the SSEL2 pin for both master and slave
+ *    operation. A zero indicates that a slave select is active. The actual polarity of each slave select
+ *    pin is configured by the related SPOL bit in CFG.
+ */
+#define SPI_FIFORDNOPOP_RXSSEL2_N(x)             (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL2_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL2_N_MASK)
+#define SPI_FIFORDNOPOP_SOT_MASK                 (0x100000U)
+#define SPI_FIFORDNOPOP_SOT_SHIFT                (20U)
+/*! SOT - Start of Transfer flag. This flag will be 1 if this is the first data after the SSELs went
+ *    from deasserted to asserted (i.e., any previous transfer has ended). This information can be
+ *    used to identify the first piece of data in cases where the transfer length is greater than 16
+ *    bit.
+ */
+#define SPI_FIFORDNOPOP_SOT(x)                   (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_SOT_SHIFT)) & SPI_FIFORDNOPOP_SOT_MASK)
+/*! @} */
+
+/*! @name PSELID - Peripheral function select and ID register */
+/*! @{ */
+#define SPI_PSELID_PERSEL_MASK                   (0x7U)
+#define SPI_PSELID_PERSEL_SHIFT                  (0U)
+/*! PERSEL - Peripheral Select. This field is writable by software. Reset value is 0x0 showing that
+ *    no peripheral is selected. Write 0x2 to select the SPI function. All other values are not
+ *    valid.
+ */
+#define SPI_PSELID_PERSEL(x)                     (((uint32_t)(((uint32_t)(x)) << SPI_PSELID_PERSEL_SHIFT)) & SPI_PSELID_PERSEL_MASK)
+#define SPI_PSELID_LOCK_MASK                     (0x8U)
+#define SPI_PSELID_LOCK_SHIFT                    (3U)
+/*! LOCK - Lock the peripheral select. This field is writable by software. 0 Peripheral select can
+ *    be changed by software. 1 Peripheral select is locked and cannot be changed until this
+ *    peripheral or the entire device is reset.
+ */
+#define SPI_PSELID_LOCK(x)                       (((uint32_t)(((uint32_t)(x)) << SPI_PSELID_LOCK_SHIFT)) & SPI_PSELID_LOCK_MASK)
+#define SPI_PSELID_SPIPRESENT_MASK               (0x20U)
+#define SPI_PSELID_SPIPRESENT_SHIFT              (5U)
+/*! SPIPRESENT - SPI present indicator. This field is Read-only and has value 0x1 to indicate SPI function is present.
+ */
+#define SPI_PSELID_SPIPRESENT(x)                 (((uint32_t)(((uint32_t)(x)) << SPI_PSELID_SPIPRESENT_SHIFT)) & SPI_PSELID_SPIPRESENT_MASK)
+#define SPI_PSELID_ID_MASK                       (0xFFFFF000U)
+#define SPI_PSELID_ID_SHIFT                      (12U)
+/*! ID - Peripheral Select ID.
+ */
+#define SPI_PSELID_ID(x)                         (((uint32_t)(((uint32_t)(x)) << SPI_PSELID_ID_SHIFT)) & SPI_PSELID_ID_MASK)
+/*! @} */
+
+/*! @name ID - SPI Module Identifier */
+/*! @{ */
+#define SPI_ID_APERTURE_MASK                     (0xFFU)
+#define SPI_ID_APERTURE_SHIFT                    (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define SPI_ID_APERTURE(x)                       (((uint32_t)(((uint32_t)(x)) << SPI_ID_APERTURE_SHIFT)) & SPI_ID_APERTURE_MASK)
+#define SPI_ID_MIN_REV_MASK                      (0xF00U)
+#define SPI_ID_MIN_REV_SHIFT                     (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define SPI_ID_MIN_REV(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_ID_MIN_REV_SHIFT)) & SPI_ID_MIN_REV_MASK)
+#define SPI_ID_MAJ_REV_MASK                      (0xF000U)
+#define SPI_ID_MAJ_REV_SHIFT                     (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define SPI_ID_MAJ_REV(x)                        (((uint32_t)(((uint32_t)(x)) << SPI_ID_MAJ_REV_SHIFT)) & SPI_ID_MAJ_REV_MASK)
+#define SPI_ID_ID_MASK                           (0xFFFF0000U)
+#define SPI_ID_ID_SHIFT                          (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define SPI_ID_ID(x)                             (((uint32_t)(((uint32_t)(x)) << SPI_ID_ID_SHIFT)) & SPI_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group SPI_Register_Masks */
+
+
+/* SPI - Peripheral instance base addresses */
+/** Peripheral SPI0 base address */
+#define SPI0_BASE                                (0x4008D000u)
+/** Peripheral SPI0 base pointer */
+#define SPI0                                     ((SPI_Type *)SPI0_BASE)
+/** Peripheral SPI1 base address */
+#define SPI1_BASE                                (0x4008E000u)
+/** Peripheral SPI1 base pointer */
+#define SPI1                                     ((SPI_Type *)SPI1_BASE)
+/** Array initializer of SPI peripheral base addresses */
+#define SPI_BASE_ADDRS                           { SPI0_BASE, SPI1_BASE }
+/** Array initializer of SPI peripheral base pointers */
+#define SPI_BASE_PTRS                            { SPI0, SPI1 }
+/** Interrupt vectors for the SPI peripheral type */
+#define SPI_IRQS                                 { FLEXCOMM4_IRQn, FLEXCOMM5_IRQn }
+
+/*!
+ * @}
+ */ /* end of group SPI_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- SPIFI Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SPIFI_Peripheral_Access_Layer SPIFI Peripheral Access Layer
+ * @{
+ */
+
+/** SPIFI - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CTRL;                              /**< SPIFI control register, offset: 0x0 */
+  __IO uint32_t CMD;                               /**< SPIFI command register, offset: 0x4 */
+  __IO uint32_t ADDR;                              /**< SPIFI address register, offset: 0x8 */
+  __IO uint32_t IDATA;                             /**< SPIFI intermediate data register, offset: 0xC */
+  __IO uint32_t CLIMIT;                            /**< SPIFI limit register, offset: 0x10 */
+  __IO uint32_t DATA;                              /**< SPIFI data register. Input or output data, offset: 0x14 */
+  __IO uint32_t MCMD;                              /**< SPIFI memory command register, offset: 0x18 */
+  __IO uint32_t STAT;                              /**< SPIFI status register, offset: 0x1C */
+} SPIFI_Type;
+
+/* ----------------------------------------------------------------------------
+   -- SPIFI Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SPIFI_Register_Masks SPIFI Register Masks
+ * @{
+ */
+
+/*! @name CTRL - SPIFI control register */
+/*! @{ */
+#define SPIFI_CTRL_TIMEOUT_MASK                  (0xFFFFU)
+#define SPIFI_CTRL_TIMEOUT_SHIFT                 (0U)
+/*! TIMEOUT - This field contains the number of serial clock periods without the processor reading
+ *    data in memory mode, which will cause the SPIFI hardware to terminate the command by driving
+ *    the CS pin high and negating the CMD bit in the Status register. (This allows the flash memory
+ *    to enter a lower-power state.) If the processor reads data from the flash region after a
+ *    time-out, the command in the Memory Command Register is issued again.
+ */
+#define SPIFI_CTRL_TIMEOUT(x)                    (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_TIMEOUT_SHIFT)) & SPIFI_CTRL_TIMEOUT_MASK)
+#define SPIFI_CTRL_CSHIGH_MASK                   (0xF0000U)
+#define SPIFI_CTRL_CSHIGH_SHIFT                  (16U)
+/*! CSHIGH - This field controls the minimum CS high time, expressed as a number of serial clock periods minus one.
+ */
+#define SPIFI_CTRL_CSHIGH(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_CSHIGH_SHIFT)) & SPIFI_CTRL_CSHIGH_MASK)
+#define SPIFI_CTRL_D_PRFTCH_DIS_MASK             (0x200000U)
+#define SPIFI_CTRL_D_PRFTCH_DIS_SHIFT            (21U)
+/*! D_PRFTCH_DIS - This bit allows conditioning of memory mode prefetches based on the AHB HPROT
+ *    (instruction/data) access information. A 1 in this register means that the SPIFI will not attempt
+ *    a speculative prefetch when it encounters data accesses.
+ */
+#define SPIFI_CTRL_D_PRFTCH_DIS(x)               (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_D_PRFTCH_DIS_SHIFT)) & SPIFI_CTRL_D_PRFTCH_DIS_MASK)
+#define SPIFI_CTRL_INTEN_MASK                    (0x400000U)
+#define SPIFI_CTRL_INTEN_SHIFT                   (22U)
+/*! INTEN - If this bit is 1 when a command ends, the SPIFI will assert its interrupt request
+ *    output. See INTRQ in the status register for further details.
+ */
+#define SPIFI_CTRL_INTEN(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_INTEN_SHIFT)) & SPIFI_CTRL_INTEN_MASK)
+#define SPIFI_CTRL_MODE3_MASK                    (0x800000U)
+#define SPIFI_CTRL_MODE3_SHIFT                   (23U)
+/*! MODE3 - SPI Mode 3 select. 0: SCK LOW. The SPIFI drives SCK low after the rising edge at which
+ *    the last bit of each command is captured, and keeps it low while CS is HIGH. 1: SCK HIGH. the
+ *    SPIFI keeps SCK high after the rising edge for the last bit of each command and while CS is
+ *    HIGH, and drives it low after it drives CS LOW. (Known serial flash devices can handle either
+ *    mode, but some devices may require a particular mode for proper operation.) Remark: MODE3, RFCLK,
+ *    and FBCLK should not all be 1, because in this case there is no final falling edge on SCK on
+ *    which to sample the last data bit of the frame.
+ */
+#define SPIFI_CTRL_MODE3(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_MODE3_SHIFT)) & SPIFI_CTRL_MODE3_MASK)
+#define SPIFI_CTRL_PRFTCH_DIS_MASK               (0x8000000U)
+#define SPIFI_CTRL_PRFTCH_DIS_SHIFT              (27U)
+/*! PRFTCH_DIS - Cache prefetching enable. The SPIFI includes an internal cache. A 1 in this bit
+ *    disables prefetching of cache lines. 0: Enable. Cache prefetching enabled. 1: Disable. Disables
+ *    prefetching of cache lines.
+ */
+#define SPIFI_CTRL_PRFTCH_DIS(x)                 (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_PRFTCH_DIS_SHIFT)) & SPIFI_CTRL_PRFTCH_DIS_MASK)
+#define SPIFI_CTRL_DUAL_MASK                     (0x10000000U)
+#define SPIFI_CTRL_DUAL_SHIFT                    (28U)
+/*! DUAL - Select dual protocol. 0: Quad protocol. This protocol uses IO3:0. 1: Dual protocol. This protocol uses IO1:0.
+ */
+#define SPIFI_CTRL_DUAL(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_DUAL_SHIFT)) & SPIFI_CTRL_DUAL_MASK)
+#define SPIFI_CTRL_RFCLK_MASK                    (0x20000000U)
+#define SPIFI_CTRL_RFCLK_SHIFT                   (29U)
+/*! RFCLK - Select active clock edge for input data. 0: Rising edge. Read data is sampled on rising
+ *    edges on the clock, as in classic SPI operation. 1: Falling edge. Read data is sampled on
+ *    falling edges of the clock, allowing a full serial clock of of time in order to maximize the
+ *    serial clock frequency. Remark: MODE3, RFCLK, and FBCLK should not all be 1, because in this case
+ *    there is no final falling edge on SCK on which to sample the last data bit of the frame.
+ */
+#define SPIFI_CTRL_RFCLK(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_RFCLK_SHIFT)) & SPIFI_CTRL_RFCLK_MASK)
+#define SPIFI_CTRL_FBCLK_MASK                    (0x40000000U)
+#define SPIFI_CTRL_FBCLK_SHIFT                   (30U)
+/*! FBCLK - Feedback clock select. 0: Internal clock. The SPIFI samples read data using an internal
+ *    clock. 1: Feedback clock. Read data is sampled using a feedback clock from the SCK pin. This
+ *    allows slightly more time for each received bit. Remark: MODE3, RFCLK, and FBCLK should not all
+ *    be 1, because in this case there is no final falling edge on SCK on which to sample the last
+ *    data bit of the frame.
+ */
+#define SPIFI_CTRL_FBCLK(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_FBCLK_SHIFT)) & SPIFI_CTRL_FBCLK_MASK)
+#define SPIFI_CTRL_DMAEN_MASK                    (0x80000000U)
+#define SPIFI_CTRL_DMAEN_SHIFT                   (31U)
+/*! DMAEN - A 1 in this bit enables the DMA Request output from the SPIFI. Set this bit only when a
+ *    DMA channel is used to transfer data in peripheral mode. Do not set this bit when a DMA
+ *    channel is used for memory-to-memory transfers from the SPIFI memory area. DRQEN should only be used
+ *    in Command mode.
+ */
+#define SPIFI_CTRL_DMAEN(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_DMAEN_SHIFT)) & SPIFI_CTRL_DMAEN_MASK)
+/*! @} */
+
+/*! @name CMD - SPIFI command register */
+/*! @{ */
+#define SPIFI_CMD_DATALEN_MASK                   (0x3FFFU)
+#define SPIFI_CMD_DATALEN_SHIFT                  (0U)
+/*! DATALEN - Except when the POLL bit in this register is 1, this field controls how many data
+ *    bytes are in the command. 0 indicates that the command does not contain a data field.
+ */
+#define SPIFI_CMD_DATALEN(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_DATALEN_SHIFT)) & SPIFI_CMD_DATALEN_MASK)
+#define SPIFI_CMD_POLL_MASK                      (0x4000U)
+#define SPIFI_CMD_POLL_SHIFT                     (14U)
+/*! POLL - This bit should be written as 1 only with an opcode that a) contains an input data field,
+ *    and b) causes the serial flash device to return byte status repetitively (e.g., a Read Status
+ *    command). When this bit is 1, the SPIFI hardware continues to read bytes until the test
+ *    specified by the DATALEN field is met. The hardware tests the bit in each status byte selected by
+ *    DATALEN bits 2:0, until a bit is found that is equal to DATALEN bit 3. When the test succeeds,
+ *    the SPIFI captures the byte that meets this test so that it can be read from the Data
+ *    Register, and terminates the command by raising CS. The end-of-command interrupt can be enabled to
+ *    inform software when this occurs
+ */
+#define SPIFI_CMD_POLL(x)                        (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_POLL_SHIFT)) & SPIFI_CMD_POLL_MASK)
+#define SPIFI_CMD_DOUT_MASK                      (0x8000U)
+#define SPIFI_CMD_DOUT_SHIFT                     (15U)
+/*! DOUT - If the DATALEN field is not zero, this bit controls the direction of the data: 0: Input
+ *    from serial flash. 1: Output to serial flash.
+ */
+#define SPIFI_CMD_DOUT(x)                        (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_DOUT_SHIFT)) & SPIFI_CMD_DOUT_MASK)
+#define SPIFI_CMD_INTLEN_MASK                    (0x70000U)
+#define SPIFI_CMD_INTLEN_SHIFT                   (16U)
+/*! INTLEN - This field controls how many intermediate bytes precede the data. (Each such byte may
+ *    require 8 or 2 SCK cycles, depending on whether the intermediate field is in serial, 2-bit, or
+ *    4-bit format.) Intermediate bytes are output by the SPIFI, and include post-address control
+ *    information, dummy and delay bytes. See the description of the Intermediate Data register for
+ *    the contents of such bytes.
+ */
+#define SPIFI_CMD_INTLEN(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_INTLEN_SHIFT)) & SPIFI_CMD_INTLEN_MASK)
+#define SPIFI_CMD_FIELDFORM_MASK                 (0x180000U)
+#define SPIFI_CMD_FIELDFORM_SHIFT                (19U)
+/*! FIELDFORM - This field controls how the fields of the command are sent. 0x0: All serial. All
+ *    fields of the command are serial. 0x1: Quad/dual data. Data field is quad/dual, other fields are
+ *    serial. 0x2: Serial opcode. Opcode field is serial. Other fields are quad/dual. 0x3: All
+ *    quad/dual. All fields of the command are in quad/dual format.
+ */
+#define SPIFI_CMD_FIELDFORM(x)                   (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_FIELDFORM_SHIFT)) & SPIFI_CMD_FIELDFORM_MASK)
+#define SPIFI_CMD_FRAMEFORM_MASK                 (0xE00000U)
+#define SPIFI_CMD_FRAMEFORM_SHIFT                (21U)
+/*! FRAMEFORM - This field controls the opcode and address fields. 0x0: Reserved. 0x1: Opcode.
+ *    Opcode only, no address. 0x2: Opcode one byte. Opcode, least significant byte of address. 0x3:
+ *    Opcode two bytes. Opcode, two least significant bytes of address. 0x4: Opcode three bytes. Opcode,
+ *    three least significant bytes of address. 0x5: Opcode four bytes. Opcode, 4 bytes of address.
+ *    0x6: No opcode three bytes. No opcode, 3 least significant bytes of address. 0x7: No opcode
+ *    four bytes. No opcode, 4 bytes of address.
+ */
+#define SPIFI_CMD_FRAMEFORM(x)                   (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_FRAMEFORM_SHIFT)) & SPIFI_CMD_FRAMEFORM_MASK)
+#define SPIFI_CMD_OPCODE_MASK                    (0xFF000000U)
+#define SPIFI_CMD_OPCODE_SHIFT                   (24U)
+/*! OPCODE - The opcode of the command (not used for some FRAMEFORM values).
+ */
+#define SPIFI_CMD_OPCODE(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_OPCODE_SHIFT)) & SPIFI_CMD_OPCODE_MASK)
+/*! @} */
+
+/*! @name ADDR - SPIFI address register */
+/*! @{ */
+#define SPIFI_ADDR_ADDR_MASK                     (0xFFFFFFFFU)
+#define SPIFI_ADDR_ADDR_SHIFT                    (0U)
+/*! ADDR - SPIFI address register
+ */
+#define SPIFI_ADDR_ADDR(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_ADDR_ADDR_SHIFT)) & SPIFI_ADDR_ADDR_MASK)
+/*! @} */
+
+/*! @name IDATA - SPIFI intermediate data register */
+/*! @{ */
+#define SPIFI_IDATA_IDATA_MASK                   (0xFFFFFFFFU)
+#define SPIFI_IDATA_IDATA_SHIFT                  (0U)
+/*! IDATA - SPIFI intermediate data register
+ */
+#define SPIFI_IDATA_IDATA(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_IDATA_IDATA_SHIFT)) & SPIFI_IDATA_IDATA_MASK)
+/*! @} */
+
+/*! @name CLIMIT - SPIFI limit register */
+/*! @{ */
+#define SPIFI_CLIMIT_CLIMIT_MASK                 (0xFFFFFFFFU)
+#define SPIFI_CLIMIT_CLIMIT_SHIFT                (0U)
+/*! CLIMIT - SPIFI limit register
+ */
+#define SPIFI_CLIMIT_CLIMIT(x)                   (((uint32_t)(((uint32_t)(x)) << SPIFI_CLIMIT_CLIMIT_SHIFT)) & SPIFI_CLIMIT_CLIMIT_MASK)
+/*! @} */
+
+/*! @name DATA - SPIFI data register. Input or output data */
+/*! @{ */
+#define SPIFI_DATA_DATA_MASK                     (0xFFFFFFFFU)
+#define SPIFI_DATA_DATA_SHIFT                    (0U)
+/*! DATA - SPIFI data register. Input or output data
+ */
+#define SPIFI_DATA_DATA(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_DATA_DATA_SHIFT)) & SPIFI_DATA_DATA_MASK)
+/*! @} */
+
+/*! @name MCMD - SPIFI memory command register */
+/*! @{ */
+#define SPIFI_MCMD_POLL_MASK                     (0x4000U)
+#define SPIFI_MCMD_POLL_SHIFT                    (14U)
+/*! POLL - This bit should be written as 0.
+ */
+#define SPIFI_MCMD_POLL(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_POLL_SHIFT)) & SPIFI_MCMD_POLL_MASK)
+#define SPIFI_MCMD_DOUT_MASK                     (0x8000U)
+#define SPIFI_MCMD_DOUT_SHIFT                    (15U)
+/*! DOUT - This bit should be written as 0.
+ */
+#define SPIFI_MCMD_DOUT(x)                       (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_DOUT_SHIFT)) & SPIFI_MCMD_DOUT_MASK)
+#define SPIFI_MCMD_INTLEN_MASK                   (0x70000U)
+#define SPIFI_MCMD_INTLEN_SHIFT                  (16U)
+/*! INTLEN - This field controls how many intermediate bytes precede the data. (Each such byte may
+ *    require 8 or 2 SCK cycles, depending on whether the intermediate field is in serial, 2-bit, or
+ *    4-bit format.) Intermediate bytes are output by the SPIFI, and include post-address control
+ *    information, dummy and delay bytes. See the description of the Intermediate Data register for
+ *    the contents of such bytes.
+ */
+#define SPIFI_MCMD_INTLEN(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_INTLEN_SHIFT)) & SPIFI_MCMD_INTLEN_MASK)
+#define SPIFI_MCMD_FIELDFORM_MASK                (0x180000U)
+#define SPIFI_MCMD_FIELDFORM_SHIFT               (19U)
+/*! FIELDFORM - This field controls how the fields of the command are sent. 0x0 All serial. All
+ *    fields of the command are serial. 0x1 Quad/dual data. Data field is quad/dual, other fields are
+ *    serial. 0x2 Serial opcode. Opcode field is serial. Other fields are quad/dual. 0x3 All
+ *    quad/dual. All fields of the command are in quad/dual format.
+ */
+#define SPIFI_MCMD_FIELDFORM(x)                  (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_FIELDFORM_SHIFT)) & SPIFI_MCMD_FIELDFORM_MASK)
+#define SPIFI_MCMD_FRAMEFORM_MASK                (0xE00000U)
+#define SPIFI_MCMD_FRAMEFORM_SHIFT               (21U)
+/*! FRAMEFORM - This field controls the opcode and address fields. 0x0: Reserved. 0x1: Opcode.
+ *    Opcode only, no address. 0x2: Opcode one byte. Opcode, least-significant byte of address. 0x3:
+ *    Opcode two bytes. Opcode, 2 least-significant bytes of address. 0x4: Opcode three bytes. Opcode, 3
+ *    least-significant bytes of address. 0x5: Opcode four bytes. Opcode, 4 bytes of address. 0x6:
+ *    No opcode three bytes. No opcode, 3 least-significant bytes of address. 0x7: No opcode, 4
+ *    bytes of address.
+ */
+#define SPIFI_MCMD_FRAMEFORM(x)                  (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_FRAMEFORM_SHIFT)) & SPIFI_MCMD_FRAMEFORM_MASK)
+#define SPIFI_MCMD_OPCODE_MASK                   (0xFF000000U)
+#define SPIFI_MCMD_OPCODE_SHIFT                  (24U)
+/*! OPCODE - The opcode of the command (not used for some FRAMEFORM values).
+ */
+#define SPIFI_MCMD_OPCODE(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_OPCODE_SHIFT)) & SPIFI_MCMD_OPCODE_MASK)
+/*! @} */
+
+/*! @name STAT - SPIFI status register */
+/*! @{ */
+#define SPIFI_STAT_MCINIT_MASK                   (0x1U)
+#define SPIFI_STAT_MCINIT_SHIFT                  (0U)
+/*! MCINIT - This bit is set when software successfully writes the Memory Command register, and is
+ *    cleared by Reset or by writing a 1 to the RESET bit in this register.
+ */
+#define SPIFI_STAT_MCINIT(x)                     (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_MCINIT_SHIFT)) & SPIFI_STAT_MCINIT_MASK)
+#define SPIFI_STAT_CMD_MASK                      (0x2U)
+#define SPIFI_STAT_CMD_SHIFT                     (1U)
+/*! CMD - This bit is 1 when the Command register is written. It is cleared by a hardware reset, a
+ *    write to the RESET bit in this register, or the deassertion of CS which indicates that the
+ *    command has completed communication with the SPI Flash.
+ */
+#define SPIFI_STAT_CMD(x)                        (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_CMD_SHIFT)) & SPIFI_STAT_CMD_MASK)
+#define SPIFI_STAT_RESET_MASK                    (0x10U)
+#define SPIFI_STAT_RESET_SHIFT                   (4U)
+/*! RESET - Write a 1 to this bit to abort a current command or memory mode. This bit is cleared
+ *    when the hardware is ready for a new command to be written to the Command register.
+ */
+#define SPIFI_STAT_RESET(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_RESET_SHIFT)) & SPIFI_STAT_RESET_MASK)
+#define SPIFI_STAT_INTRQ_MASK                    (0x20U)
+#define SPIFI_STAT_INTRQ_SHIFT                   (5U)
+/*! INTRQ - This bit reflects the SPIFI interrupt request. Write a 1 to this bit to clear it. This
+ *    bit is set when a CMD was previously 1 and has been cleared due to the deassertion of CS.
+ */
+#define SPIFI_STAT_INTRQ(x)                      (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_INTRQ_SHIFT)) & SPIFI_STAT_INTRQ_MASK)
+#define SPIFI_STAT_VERSION_MASK                  (0xFF000000U)
+#define SPIFI_STAT_VERSION_SHIFT                 (24U)
+#define SPIFI_STAT_VERSION(x)                    (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_VERSION_SHIFT)) & SPIFI_STAT_VERSION_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group SPIFI_Register_Masks */
+
+
+/* SPIFI - Peripheral instance base addresses */
+/** Peripheral SPIFI base address */
+#define SPIFI_BASE                               (0x40084000u)
+/** Peripheral SPIFI base pointer */
+#define SPIFI                                    ((SPIFI_Type *)SPIFI_BASE)
+/** Array initializer of SPIFI peripheral base addresses */
+#define SPIFI_BASE_ADDRS                         { SPIFI_BASE }
+/** Array initializer of SPIFI peripheral base pointers */
+#define SPIFI_BASE_PTRS                          { SPIFI }
+
+/*!
+ * @}
+ */ /* end of group SPIFI_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- SYSCON Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SYSCON_Peripheral_Access_Layer SYSCON Peripheral Access Layer
+ * @{
+ */
+
+/** SYSCON - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t MEMORYREMAP;                       /**< Memory Remap control register, offset: 0x0 */
+       uint8_t RESERVED_0[12];
+  __IO uint32_t AHBMATPRIO;                        /**< AHB Matrix priority control register, offset: 0x10 */
+       uint8_t RESERVED_1[44];
+  __IO uint32_t SYSTCKCAL;                         /**< System tick counter calibration, offset: 0x40 */
+       uint8_t RESERVED_2[4];
+  __IO uint32_t NMISRC;                            /**< NMI Source Select, offset: 0x48 */
+  __IO uint32_t ASYNCAPBCTRL;                      /**< Asynchronous APB Control, offset: 0x4C */
+       uint8_t RESERVED_3[176];
+  union {                                          /* offset: 0x100 */
+    struct {                                         /* offset: 0x100 */
+      __IO uint32_t PRESETCTRL0;                       /**< Peripheral reset control 0, offset: 0x100 */
+      __IO uint32_t PRESETCTRL1;                       /**< Peripheral reset control 1, offset: 0x104 */
+    } PRESETCTRL;
+    __IO uint32_t PRESETCTRLS[2];                    /**< Pin assign register, array offset: 0x100, array step: 0x4 */
+  };
+       uint8_t RESERVED_4[24];
+  union {                                          /* offset: 0x120 */
+    struct {                                         /* offset: 0x120 */
+      __O  uint32_t PRESETCTRLSET0;                    /**< Set bits in PRESETCTRL0. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers., offset: 0x120 */
+      __O  uint32_t PRESETCTRLSET1;                    /**< Set bits in PRESETCTRL1. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers., offset: 0x124 */
+    } PRESETCTRLSET;
+    __IO uint32_t PRESETCTRLSETS[2];                 /**< Pin assign register, array offset: 0x120, array step: 0x4 */
+  };
+       uint8_t RESERVED_5[24];
+  union {                                          /* offset: 0x140 */
+    struct {                                         /* offset: 0x140 */
+      __O  uint32_t PRESETCTRLCLR0;                    /**< Clear bits in PRESETCTRL0. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers., offset: 0x140 */
+      __O  uint32_t PRESETCTRLCLR1;                    /**< Clear bits in PRESETCTRL1. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers., offset: 0x144 */
+    } PRESETCTRLCLR;
+    __IO uint32_t PRESETCTRLCLRS[2];                 /**< Pin assign register, array offset: 0x140, array step: 0x4 */
+  };
+       uint8_t RESERVED_6[184];
+  union {                                          /* offset: 0x200 */
+    struct {                                         /* offset: 0x200 */
+      __IO uint32_t AHBCLKCTRL0;                       /**< AHB Clock control 0, offset: 0x200 */
+      __IO uint32_t AHBCLKCTRL1;                       /**< AHB Clock control 1, offset: 0x204 */
+    } AHBCLKCTRL;
+    __IO uint32_t AHBCLKCTRLS[2];                    /**< Pin assign register, array offset: 0x200, array step: 0x4 */
+  };
+       uint8_t RESERVED_7[24];
+  union {                                          /* offset: 0x220 */
+    struct {                                         /* offset: 0x220 */
+      __O  uint32_t AHBCLKCTRLSET0;                    /**< Set bits in AHBCLKCTRL0, offset: 0x220 */
+      __O  uint32_t AHBCLKCTRLSET1;                    /**< Set bits in AHBCLKCTRL1, offset: 0x224 */
+    } AHBCLKCTRLSET;
+    __IO uint32_t AHBCLKCTRLSETS[2];                 /**< Pin assign register, array offset: 0x220, array step: 0x4 */
+  };
+       uint8_t RESERVED_8[24];
+  union {                                          /* offset: 0x240 */
+    struct {                                         /* offset: 0x240 */
+      __O  uint32_t AHBCLKCTRLCLR0;                    /**< Clear bits in AHBCLKCTRL0, offset: 0x240 */
+      __O  uint32_t AHBCLKCTRLCLR1;                    /**< Clear bits in AHBCLKCTRL1, offset: 0x244 */
+    } AHBCLKCTRLCLR;
+    __IO uint32_t AHBCLKCTRLCLRS[2];                 /**< Pin assign register, array offset: 0x240, array step: 0x4 */
+  };
+       uint8_t RESERVED_9[56];
+  __IO uint32_t MAINCLKSEL;                        /**< Main clock source select, offset: 0x280 */
+  __IO uint32_t OSC32CLKSEL;                       /**< OSC32KCLK and OSC32MCLK clock sources select. Note: this register is not locked by CLOCKGENUPDATELOCKOUT, offset: 0x284 */
+  __IO uint32_t CLKOUTSEL;                         /**< CLKOUT clock source select, offset: 0x288 */
+       uint8_t RESERVED_10[20];
+  __IO uint32_t SPIFICLKSEL;                       /**< SPIFI clock source select, offset: 0x2A0 */
+  __IO uint32_t ADCCLKSEL;                         /**< ADC clock source select, offset: 0x2A4 */
+       uint8_t RESERVED_11[8];
+  __IO uint32_t USARTCLKSEL;                       /**< USART0 & 1 clock source select, offset: 0x2B0 */
+  __IO uint32_t I2CCLKSEL;                         /**< I2C0, 1 and 2 clock source select, offset: 0x2B4 */
+  __IO uint32_t SPICLKSEL;                         /**< SPI0 & 1 clock source select, offset: 0x2B8 */
+  __IO uint32_t IRCLKSEL;                          /**< Infra Red clock source select, offset: 0x2BC */
+  __IO uint32_t PWMCLKSEL;                         /**< PWM clock source select, offset: 0x2C0 */
+  __IO uint32_t WDTCLKSEL;                         /**< Watchdog Timer clock source select, offset: 0x2C4 */
+       uint8_t RESERVED_12[4];
+  __IO uint32_t MODEMCLKSEL;                       /**< Modem clock source select, offset: 0x2CC */
+       uint8_t RESERVED_13[24];
+  __IO uint32_t FRGCLKSEL;                         /**< Fractional Rate Generator (FRG) clock source select. The FRG is one of the USART clocking options., offset: 0x2E8 */
+  __IO uint32_t DMICCLKSEL;                        /**< Digital microphone (DMIC) subsystem clock select, offset: 0x2EC */
+  __IO uint32_t WKTCLKSEL;                         /**< Wake-up Timer clock select, offset: 0x2F0 */
+       uint8_t RESERVED_14[12];
+  __IO uint32_t SYSTICKCLKDIV;                     /**< SYSTICK clock divider. The SYSTICK clock can drive the SYSTICK function within the processor., offset: 0x300 */
+  __IO uint32_t TRACECLKDIV;                       /**< TRACE clock divider, used for part of the Serial debugger (SWD) feature., offset: 0x304 */
+       uint8_t RESERVED_15[100];
+  __IO uint32_t WDTCLKDIV;                         /**< Watchdog Timer clock divider, offset: 0x36C */
+       uint8_t RESERVED_16[8];
+  __IO uint32_t IRCLKDIV;                          /**< Infra Red clock divider, offset: 0x378 */
+       uint8_t RESERVED_17[4];
+  __IO uint32_t AHBCLKDIV;                         /**< System clock divider, offset: 0x380 */
+  __IO uint32_t CLKOUTDIV;                         /**< CLKOUT clock divider, offset: 0x384 */
+       uint8_t RESERVED_18[8];
+  __IO uint32_t SPIFICLKDIV;                       /**< SPIFI clock divider, offset: 0x390 */
+  __IO uint32_t ADCCLKDIV;                         /**< ADC clock divider, offset: 0x394 */
+  __IO uint32_t RTCCLKDIV;                         /**< Real Time Clock divider (1 KHz clock generation), offset: 0x398 */
+       uint8_t RESERVED_19[4];
+  __IO uint32_t FRGCTRL;                           /**< Fractional rate generator divider. The FRG is one of the USART clocking options., offset: 0x3A0 */
+       uint8_t RESERVED_20[4];
+  __IO uint32_t DMICCLKDIV;                        /**< DMIC clock divider, offset: 0x3A8 */
+  __IO uint32_t RTC1HZCLKDIV;                      /**< Real Time Clock divider (1 Hz clock generation. The divider is fixed to 32768), offset: 0x3AC */
+       uint8_t RESERVED_21[76];
+  __IO uint32_t CLOCKGENUPDATELOCKOUT;             /**< Control clock configuration registers access (like xxxDIV, xxxSEL), offset: 0x3FC */
+       uint8_t RESERVED_22[412];
+  __IO uint32_t RNGCLKCTRL;                        /**< Random Number Generator Clocks control, offset: 0x59C */
+  __IO uint32_t SRAMCTRL;                          /**< All SRAMs common control signals, offset: 0x5A0 */
+       uint8_t RESERVED_23[40];
+  __IO uint32_t MODEMCTRL;                         /**< Modem (Bluetooth) control and 32K clock enable, offset: 0x5CC */
+  __I  uint32_t MODEMSTATUS;                       /**< Modem (Bluetooth) status, offset: 0x5D0 */
+  __IO uint32_t XTAL32KCAP;                        /**< XTAL 32 KHz oscillator Capacitor control, offset: 0x5D4 */
+  __IO uint32_t XTAL32MCTRL;                       /**< XTAL 32 MHz oscillator control register, offset: 0x5D8 */
+       uint8_t RESERVED_24[164];
+  union {                                          /* offset: 0x680 */
+    struct {                                         /* offset: 0x680 */
+      __IO uint32_t STARTER0;                          /**< Start logic 0 wake-up enable register. Enable an interrupt for wake-up from deep-sleep mode. Some bits can also control wake-up from powerdown mode, offset: 0x680 */
+      __IO uint32_t STARTER1;                          /**< Start logic 1 wake-up enable register. Enable an interrupt for wake-up from deep-sleep mode. Some bits can also control wake-up from powerdown mode, offset: 0x684 */
+    } STARTER;
+    __IO uint32_t STARTERS[2];                       /**< Pin assign register, array offset: 0x680, array step: 0x4 */
+  };
+       uint8_t RESERVED_25[24];
+  union {                                          /* offset: 0x6A0 */
+    struct {                                         /* offset: 0x6A0 */
+      __O  uint32_t STARTERSET0;                       /**< Set bits in STARTER0, offset: 0x6A0 */
+      __O  uint32_t STARTERSET1;                       /**< Set bits in STARTER1, offset: 0x6A4 */
+    } STARTERSET;
+    __IO uint32_t STARTERSETS[2];                    /**< Pin assign register, array offset: 0x6A0, array step: 0x4 */
+  };
+       uint8_t RESERVED_26[24];
+  union {                                          /* offset: 0x6C0 */
+    struct {                                         /* offset: 0x6C0 */
+      __O  uint32_t STARTERCLR0;                       /**< Clear bits in STARTER0, offset: 0x6C0 */
+      __O  uint32_t STARTERCLR1;                       /**< Clear bits in STARTER1, offset: 0x6C4 */
+    } STARTERCLR;
+    __IO uint32_t STARTERCLRS[2];                    /**< Pin assign register, array offset: 0x6C0, array step: 0x4 */
+  };
+       uint8_t RESERVED_27[64];
+  __IO uint32_t RETENTIONCTRL;                     /**< I/O retention control register, offset: 0x708 */
+       uint8_t RESERVED_28[252];
+  __IO uint32_t CPSTACK;                           /**< CPSTACK, offset: 0x808 */
+       uint8_t RESERVED_29[500];
+  __IO uint32_t ANACTRL_CTRL;                      /**< Analog Interrupt control register. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set., offset: 0xA00 */
+  __I  uint32_t ANACTRL_VAL;                       /**< Analog modules (BOD and Analog Comparator) outputs current values (BOD 'Power OK' and Analog comparator out). Requires AHBCLKCTRL0.ANA_INT_CTRL to be set., offset: 0xA04 */
+  __IO uint32_t ANACTRL_STAT;                      /**< Analog modules (BOD and Analog Comparator) interrupt status. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set., offset: 0xA08 */
+  __IO uint32_t ANACTRL_INTENSET;                  /**< Analog modules (BOD and Analog Comparator) Interrupt Enable Read and Set register. Read value indicates which interrupts are enabled. Writing ones sets the corresponding interrupt enable bits. Note, interrupt enable bits are cleared using ANACTRL_INTENCLR. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register., offset: 0xA0C */
+  __O  uint32_t ANACTRL_INTENCLR;                  /**< Analog modules (BOD and Analog Comparator) Interrupt Enable Clear register. Writing ones clears the corresponding interrupt enable bits. Note, interrupt enable bits are set in ANACTRL_INTENSET. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register., offset: 0xA10 */
+  __I  uint32_t ANACTRL_INTSTAT;                   /**< Analog modules (BOD and Analog Comparator) Interrupt Status register (masked with interrupt enable). Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register. Interrupt status bit are cleared using ANACTRL_STAT., offset: 0xA14 */
+  __IO uint32_t CLOCK_CTRL;                        /**< Various system clock controls : Flash clock (48 MHz) control, clocks to Frequency Measure function, offset: 0xA18 */
+       uint8_t RESERVED_30[4];
+  __IO uint32_t WKT_CTRL;                          /**< Wake-up timers control, offset: 0xA20 */
+  __IO uint32_t WKT_LOAD_WKT0_LSB;                 /**< Wake-up timer 0 reload value least significant bits ([31:0])., offset: 0xA24 */
+  __IO uint32_t WKT_LOAD_WKT0_MSB;                 /**< Wake-up timer 0 reload value most significant bits ([8:0])., offset: 0xA28 */
+  __IO uint32_t WKT_LOAD_WKT1;                     /**< Wake-up timer 1 reload value., offset: 0xA2C */
+  __I  uint32_t WKT_VAL_WKT0_LSB;                  /**< Wake-up timer 0 current value least significant bits ([31:0]). WARNING : reading not reliable: read this register several times until you get a stable value., offset: 0xA30 */
+  __I  uint32_t WKT_VAL_WKT0_MSB;                  /**< Wake-up timer 0 current value most significant bits ([8:0]). WARNING : reading not reliable: read this register several times until you get a stable value., offset: 0xA34 */
+  __I  uint32_t WKT_VAL_WKT1;                      /**< Wake-up timer 1 current value. WARNING : reading not reliable: read this register several times until you get a stable value., offset: 0xA38 */
+  __IO uint32_t WKT_STAT;                          /**< Wake-up timers status, offset: 0xA3C */
+  __IO uint32_t WKT_INTENSET;                      /**< Interrupt Enable Read and Set register, offset: 0xA40 */
+  __O  uint32_t WKT_INTENCLR;                      /**< Interrupt Enable Clear register, offset: 0xA44 */
+  __I  uint32_t WKT_INTSTAT;                       /**< Interrupt Status register, offset: 0xA48 */
+       uint8_t RESERVED_31[956];
+  __IO uint32_t GPIOPSYNC;                         /**< Enable bypass of the first stage of synchonization inside GPIO_INT module., offset: 0xE08 */
+       uint8_t RESERVED_32[420];
+  __I  uint32_t DIEID;                             /**< Chip revision ID & Number, offset: 0xFB0 */
+       uint8_t RESERVED_33[60];
+  __O  uint32_t CODESECURITYPROT;                  /**< Security code to allow test access via SWD/JTAG. Reset with POR, SW reset or BOD, offset: 0xFF0 */
+} SYSCON_Type;
+
+/* ----------------------------------------------------------------------------
+   -- SYSCON Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SYSCON_Register_Masks SYSCON Register Masks
+ * @{
+ */
+
+/*! @name MEMORYREMAP - Memory Remap control register */
+/*! @{ */
+#define SYSCON_MEMORYREMAP_MAP_MASK              (0x3U)
+#define SYSCON_MEMORYREMAP_MAP_SHIFT             (0U)
+/*! MAP - Select the location of the vector table : 0: Vector Table in ROM. 1: Vector Table in RAM.
+ *    2: Vector Table in Flash. 3: Vector Table in Flash.
+ */
+#define SYSCON_MEMORYREMAP_MAP(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_MAP_SHIFT)) & SYSCON_MEMORYREMAP_MAP_MASK)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0_MASK (0x300000U)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0_SHIFT (20U)
+/*! QSPI_REMAP_APP_0 - Address bits to use when QSPI Flash address [19:18] = 0 (256-KB unit page). Setting 00 gives no remapping.
+ */
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0_SHIFT)) & SYSCON_MEMORYREMAP_QSPI_REMAP_APP_0_MASK)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1_MASK (0xC00000U)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1_SHIFT (22U)
+/*! QSPI_REMAP_APP_1 - Address bits to use when QSPI Flash address [19:18] = 1 (256-KB unit page). Setting 01 gives no remapping.
+ */
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1_SHIFT)) & SYSCON_MEMORYREMAP_QSPI_REMAP_APP_1_MASK)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2_MASK (0x3000000U)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2_SHIFT (24U)
+/*! QSPI_REMAP_APP_2 - Address bits to use when QSPI Flash address [19:18] = 2 (256-KB unit page). Setting 10 gives no remapping.
+ */
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2_SHIFT)) & SYSCON_MEMORYREMAP_QSPI_REMAP_APP_2_MASK)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3_MASK (0xC000000U)
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3_SHIFT (26U)
+/*! QSPI_REMAP_APP_3 - Address bits to use when QSPI Flash address [19:18] = 3 (256-KB unit page). Setting 11 gives no remapping.
+ */
+#define SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3_SHIFT)) & SYSCON_MEMORYREMAP_QSPI_REMAP_APP_3_MASK)
+/*! @} */
+
+/*! @name AHBMATPRIO - AHB Matrix priority control register */
+/*! @{ */
+#define SYSCON_AHBMATPRIO_AHBMATPRIO_MASK        (0xFFFFFFFFU)
+#define SYSCON_AHBMATPRIO_AHBMATPRIO_SHIFT       (0U)
+/*! AHBMATPRIO - AHB Matrix priority control register
+ */
+#define SYSCON_AHBMATPRIO_AHBMATPRIO(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_AHBMATPRIO_SHIFT)) & SYSCON_AHBMATPRIO_AHBMATPRIO_MASK)
+/*! @} */
+
+/*! @name SYSTCKCAL - System tick counter calibration */
+/*! @{ */
+#define SYSCON_SYSTCKCAL_CAL_MASK                (0xFFFFFFU)
+#define SYSCON_SYSTCKCAL_CAL_SHIFT               (0U)
+/*! CAL - Cortex System tick timer calibration value, readable from Cortex SYST_CALIB.TENMS register
+ *    field. Set this value to be the number of clock periods to give 10ms period. SYSTICK freq is
+ *    a function of the mainclk and SYSTICKCLKDIV register. If the tick timer is configured to use
+ *    the System clock directly then this value must reflect the 10ms tick count for that clock.
+ */
+#define SYSCON_SYSTCKCAL_CAL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_CAL_SHIFT)) & SYSCON_SYSTCKCAL_CAL_MASK)
+#define SYSCON_SYSTCKCAL_SKEW_MASK               (0x1000000U)
+#define SYSCON_SYSTCKCAL_SKEW_SHIFT              (24U)
+/*! SKEW - Cortex System tick timer SYST_CALIB.SKEW setting. When 0, the value of SYST_CALIB.TENMS
+ *    field is considered to be precise. When 1, the value of TENMS is not considered to be precise.
+ */
+#define SYSCON_SYSTCKCAL_SKEW(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_SKEW_SHIFT)) & SYSCON_SYSTCKCAL_SKEW_MASK)
+#define SYSCON_SYSTCKCAL_NOREF_MASK              (0x2000000U)
+#define SYSCON_SYSTCKCAL_NOREF_SHIFT             (25U)
+/*! NOREF - Cortex System tick timer SYST_CALIB.NOREF setting. When 0, a separate reference clock is
+ *    available. When 1, a separate reference clock is not available.
+ */
+#define SYSCON_SYSTCKCAL_NOREF(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_NOREF_SHIFT)) & SYSCON_SYSTCKCAL_NOREF_MASK)
+/*! @} */
+
+/*! @name NMISRC - NMI Source Select */
+/*! @{ */
+#define SYSCON_NMISRC_IRQM40_MASK                (0x3FU)
+#define SYSCON_NMISRC_IRQM40_SHIFT               (0U)
+/*! IRQM40 - The number of the interrupt source within the interrupt array that acts as the
+ *    Non-Maskable Interrupt (NMI) for the Cortex-M4, if enabled by NMIENM40. This can also cause the device
+ *    to wakeup from sleep.
+ */
+#define SYSCON_NMISRC_IRQM40(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_IRQM40_SHIFT)) & SYSCON_NMISRC_IRQM40_MASK)
+#define SYSCON_NMISRC_NMIENM40_MASK              (0x80000000U)
+#define SYSCON_NMISRC_NMIENM40_SHIFT             (31U)
+/*! NMIENM40 - Write a 1 to this bit to enable the Non-Maskable Interrupt (NMI) source selected by
+ *    IRQM40. The NMI Interrupt should be disabled before changing the source selection (IRQM40)
+ */
+#define SYSCON_NMISRC_NMIENM40(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_NMIENM40_SHIFT)) & SYSCON_NMISRC_NMIENM40_MASK)
+/*! @} */
+
+/*! @name ASYNCAPBCTRL - Asynchronous APB Control */
+/*! @{ */
+#define SYSCON_ASYNCAPBCTRL_ENABLE_MASK          (0x1U)
+#define SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT         (0U)
+/*! ENABLE - Enables the asynchronous APB bridge and subsystem
+ */
+#define SYSCON_ASYNCAPBCTRL_ENABLE(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT)) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK)
+/*! @} */
+
+/*! @name PRESETCTRL0 - Peripheral reset control 0 */
+/*! @{ */
+#define SYSCON_PRESETCTRL0_SPIFI_RST_MASK        (0x400U)
+#define SYSCON_PRESETCTRL0_SPIFI_RST_SHIFT       (10U)
+/*! SPIFI_RST - Quad SPI Flash controller reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_SPIFI_RST(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_SPIFI_RST_SHIFT)) & SYSCON_PRESETCTRL0_SPIFI_RST_MASK)
+#define SYSCON_PRESETCTRL0_MUX_RST_MASK          (0x800U)
+#define SYSCON_PRESETCTRL0_MUX_RST_SHIFT         (11U)
+/*! MUX_RST - Input Mux reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_MUX_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_MUX_RST_SHIFT)) & SYSCON_PRESETCTRL0_MUX_RST_MASK)
+#define SYSCON_PRESETCTRL0_BLE_TIMING_GEN_RST_MASK (0x1000U)
+#define SYSCON_PRESETCTRL0_BLE_TIMING_GEN_RST_SHIFT (12U)
+/*! BLE_TIMING_GEN_RST - BLE Low Power Control module reset. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_BLE_TIMING_GEN_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_BLE_TIMING_GEN_RST_SHIFT)) & SYSCON_PRESETCTRL0_BLE_TIMING_GEN_RST_MASK)
+#define SYSCON_PRESETCTRL0_IOCON_RST_MASK        (0x2000U)
+#define SYSCON_PRESETCTRL0_IOCON_RST_SHIFT       (13U)
+/*! IOCON_RST - I/O controller reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_IOCON_RST(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_IOCON_RST_SHIFT)) & SYSCON_PRESETCTRL0_IOCON_RST_MASK)
+#define SYSCON_PRESETCTRL0_GPIO_RST_MASK         (0x4000U)
+#define SYSCON_PRESETCTRL0_GPIO_RST_SHIFT        (14U)
+/*! GPIO_RST - GPIO reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_GPIO_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_GPIO_RST_SHIFT)) & SYSCON_PRESETCTRL0_GPIO_RST_MASK)
+#define SYSCON_PRESETCTRL0_PINT_RST_MASK         (0x40000U)
+#define SYSCON_PRESETCTRL0_PINT_RST_SHIFT        (18U)
+/*! PINT_RST - Pin interrupt (PINT) reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_PINT_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_PINT_RST_SHIFT)) & SYSCON_PRESETCTRL0_PINT_RST_MASK)
+#define SYSCON_PRESETCTRL0_GINT_RST_MASK         (0x80000U)
+#define SYSCON_PRESETCTRL0_GINT_RST_SHIFT        (19U)
+/*! GINT_RST - Group interrupt (GINT) reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_GINT_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_GINT_RST_SHIFT)) & SYSCON_PRESETCTRL0_GINT_RST_MASK)
+#define SYSCON_PRESETCTRL0_DMA_RST_MASK          (0x100000U)
+#define SYSCON_PRESETCTRL0_DMA_RST_SHIFT         (20U)
+/*! DMA_RST - DMA reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_DMA_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_DMA_RST_SHIFT)) & SYSCON_PRESETCTRL0_DMA_RST_MASK)
+#define SYSCON_PRESETCTRL0_ISO7816_RST_MASK      (0x200000U)
+#define SYSCON_PRESETCTRL0_ISO7816_RST_SHIFT     (21U)
+/*! ISO7816_RST - ISO7816 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_ISO7816_RST(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_ISO7816_RST_SHIFT)) & SYSCON_PRESETCTRL0_ISO7816_RST_MASK)
+#define SYSCON_PRESETCTRL0_WWDT_RST_MASK         (0x400000U)
+#define SYSCON_PRESETCTRL0_WWDT_RST_SHIFT        (22U)
+/*! WWDT_RST - Watchdog Timer reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_WWDT_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_WWDT_RST_SHIFT)) & SYSCON_PRESETCTRL0_WWDT_RST_MASK)
+#define SYSCON_PRESETCTRL0_RTC_RST_MASK          (0x800000U)
+#define SYSCON_PRESETCTRL0_RTC_RST_SHIFT         (23U)
+/*! RTC_RST - Real Time Clock (RTC) reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_RTC_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_RTC_RST_SHIFT)) & SYSCON_PRESETCTRL0_RTC_RST_MASK)
+#define SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_MASK (0x1000000U)
+#define SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_SHIFT (24U)
+/*! ANA_INT_CTRL_RST - Analog Modules Interrupt Controller reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_SHIFT)) & SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_MASK)
+#define SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_MASK (0x2000000U)
+#define SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_SHIFT (25U)
+/*! WAKE_UP_TIMERS_RST - Wake up Timers reset control. 0: Clear reset to this function. 1: Assert
+ *    reset to this function. This will clear interrupt status flag. However, configuration for wake
+ *    timers that is in SYSCON will not be reset, these should be managed through the SYSCON
+ *    regsiters.
+ */
+#define SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_SHIFT)) & SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_MASK)
+#define SYSCON_PRESETCTRL0_ADC_RST_MASK          (0x8000000U)
+#define SYSCON_PRESETCTRL0_ADC_RST_SHIFT         (27U)
+/*! ADC_RST - ADC reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL0_ADC_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL0_ADC_RST_SHIFT)) & SYSCON_PRESETCTRL0_ADC_RST_MASK)
+/*! @} */
+
+/*! @name PRESETCTRL1 - Peripheral reset control 1 */
+/*! @{ */
+#define SYSCON_PRESETCTRL1_USART0_RST_MASK       (0x800U)
+#define SYSCON_PRESETCTRL1_USART0_RST_SHIFT      (11U)
+/*! USART0_RST - UART0 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_USART0_RST(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_USART0_RST_SHIFT)) & SYSCON_PRESETCTRL1_USART0_RST_MASK)
+#define SYSCON_PRESETCTRL1_USART1_RST_MASK       (0x1000U)
+#define SYSCON_PRESETCTRL1_USART1_RST_SHIFT      (12U)
+/*! USART1_RST - UART1 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_USART1_RST(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_USART1_RST_SHIFT)) & SYSCON_PRESETCTRL1_USART1_RST_MASK)
+#define SYSCON_PRESETCTRL1_I2C0_RST_MASK         (0x2000U)
+#define SYSCON_PRESETCTRL1_I2C0_RST_SHIFT        (13U)
+/*! I2C0_RST - I2C0 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_I2C0_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_I2C0_RST_SHIFT)) & SYSCON_PRESETCTRL1_I2C0_RST_MASK)
+#define SYSCON_PRESETCTRL1_I2C1_RST_MASK         (0x4000U)
+#define SYSCON_PRESETCTRL1_I2C1_RST_SHIFT        (14U)
+/*! I2C1_RST - I2C1 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_I2C1_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_I2C1_RST_SHIFT)) & SYSCON_PRESETCTRL1_I2C1_RST_MASK)
+#define SYSCON_PRESETCTRL1_SPI0_RST_MASK         (0x8000U)
+#define SYSCON_PRESETCTRL1_SPI0_RST_SHIFT        (15U)
+/*! SPI0_RST - SPI0 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_SPI0_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_SPI0_RST_SHIFT)) & SYSCON_PRESETCTRL1_SPI0_RST_MASK)
+#define SYSCON_PRESETCTRL1_SPI1_RST_MASK         (0x10000U)
+#define SYSCON_PRESETCTRL1_SPI1_RST_SHIFT        (16U)
+/*! SPI1_RST - SPI1 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_SPI1_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_SPI1_RST_SHIFT)) & SYSCON_PRESETCTRL1_SPI1_RST_MASK)
+#define SYSCON_PRESETCTRL1_IR_RST_MASK           (0x20000U)
+#define SYSCON_PRESETCTRL1_IR_RST_SHIFT          (17U)
+/*! IR_RST - Infra Red reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_IR_RST(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_IR_RST_SHIFT)) & SYSCON_PRESETCTRL1_IR_RST_MASK)
+#define SYSCON_PRESETCTRL1_PWM_RST_MASK          (0x40000U)
+#define SYSCON_PRESETCTRL1_PWM_RST_SHIFT         (18U)
+/*! PWM_RST - PWM reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_PWM_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_PWM_RST_SHIFT)) & SYSCON_PRESETCTRL1_PWM_RST_MASK)
+#define SYSCON_PRESETCTRL1_RNG_RST_MASK          (0x80000U)
+#define SYSCON_PRESETCTRL1_RNG_RST_SHIFT         (19U)
+/*! RNG_RST - Random Number Generator reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_RNG_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_RNG_RST_SHIFT)) & SYSCON_PRESETCTRL1_RNG_RST_MASK)
+#define SYSCON_PRESETCTRL1_I2C2_RST_MASK         (0x100000U)
+#define SYSCON_PRESETCTRL1_I2C2_RST_SHIFT        (20U)
+/*! I2C2_RST - I2C2 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_I2C2_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_I2C2_RST_SHIFT)) & SYSCON_PRESETCTRL1_I2C2_RST_MASK)
+#define SYSCON_PRESETCTRL1_ZIGBEE_RST_MASK       (0x200000U)
+#define SYSCON_PRESETCTRL1_ZIGBEE_RST_SHIFT      (21U)
+/*! ZIGBEE_RST - Zigbee reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_ZIGBEE_RST(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_ZIGBEE_RST_SHIFT)) & SYSCON_PRESETCTRL1_ZIGBEE_RST_MASK)
+#define SYSCON_PRESETCTRL1_BLE_RST_MASK          (0x400000U)
+#define SYSCON_PRESETCTRL1_BLE_RST_SHIFT         (22U)
+/*! BLE_RST - BLE reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_BLE_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_BLE_RST_SHIFT)) & SYSCON_PRESETCTRL1_BLE_RST_MASK)
+#define SYSCON_PRESETCTRL1_MODEM_MASTER_RST_MASK (0x800000U)
+#define SYSCON_PRESETCTRL1_MODEM_MASTER_RST_SHIFT (23U)
+/*! MODEM_MASTER_RST - MODEM AHB Master Interface reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_MODEM_MASTER_RST(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_MODEM_MASTER_RST_SHIFT)) & SYSCON_PRESETCTRL1_MODEM_MASTER_RST_MASK)
+#define SYSCON_PRESETCTRL1_AES_RST_MASK          (0x1000000U)
+#define SYSCON_PRESETCTRL1_AES_RST_SHIFT         (24U)
+/*! AES_RST - AES256 reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_AES_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_AES_RST_SHIFT)) & SYSCON_PRESETCTRL1_AES_RST_MASK)
+#define SYSCON_PRESETCTRL1_RFP_RST_MASK          (0x2000000U)
+#define SYSCON_PRESETCTRL1_RFP_RST_SHIFT         (25U)
+/*! RFP_RST - RFP (Radio controller) reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_RFP_RST(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_RFP_RST_SHIFT)) & SYSCON_PRESETCTRL1_RFP_RST_MASK)
+#define SYSCON_PRESETCTRL1_DMIC_RST_MASK         (0x4000000U)
+#define SYSCON_PRESETCTRL1_DMIC_RST_SHIFT        (26U)
+/*! DMIC_RST - DMIC Reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_DMIC_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_DMIC_RST_SHIFT)) & SYSCON_PRESETCTRL1_DMIC_RST_MASK)
+#define SYSCON_PRESETCTRL1_HASH_RST_MASK         (0x8000000U)
+#define SYSCON_PRESETCTRL1_HASH_RST_SHIFT        (27U)
+/*! HASH_RST - HASH reset control. 0: Clear reset to this function. 1: Assert reset to this function.
+ */
+#define SYSCON_PRESETCTRL1_HASH_RST(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL1_HASH_RST_SHIFT)) & SYSCON_PRESETCTRL1_HASH_RST_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLX_PRESETCTRLS - Pin assign register */
+/*! @{ */
+#define SYSCON_PRESETCTRLX_PRESETCTRLS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_PRESETCTRLX_PRESETCTRLS_DATA_SHIFT (0U)
+#define SYSCON_PRESETCTRLX_PRESETCTRLS_DATA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLX_PRESETCTRLS_DATA_SHIFT)) & SYSCON_PRESETCTRLX_PRESETCTRLS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_PRESETCTRLX_PRESETCTRLS */
+#define SYSCON_PRESETCTRLX_PRESETCTRLS_COUNT     (2U)
+
+/*! @name PRESETCTRLSET0 - Set bits in PRESETCTRL0. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers. */
+/*! @{ */
+#define SYSCON_PRESETCTRLSET0_SPIFI_RST_SET_MASK (0x400U)
+#define SYSCON_PRESETCTRLSET0_SPIFI_RST_SET_SHIFT (10U)
+/*! SPIFI_RST_SET - Writing one to this register sets the SPIFI_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_SPIFI_RST_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_SPIFI_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_SPIFI_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_MUX_RST_SET_MASK   (0x800U)
+#define SYSCON_PRESETCTRLSET0_MUX_RST_SET_SHIFT  (11U)
+/*! MUX_RST_SET - Writing one to this register sets the MUX_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_MUX_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_MUX_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_MUX_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_BLE_TIMING_GEN_RST_SET_MASK (0x1000U)
+#define SYSCON_PRESETCTRLSET0_BLE_TIMING_GEN_RST_SET_SHIFT (12U)
+/*! BLE_TIMING_GEN_RST_SET - Writing one to this register sets the BLE_TIMING_GEN_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_BLE_TIMING_GEN_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_BLE_TIMING_GEN_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_BLE_TIMING_GEN_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_IOCON_RST_SET_MASK (0x2000U)
+#define SYSCON_PRESETCTRLSET0_IOCON_RST_SET_SHIFT (13U)
+/*! IOCON_RST_SET - Writing one to this register sets the IOCON_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_IOCON_RST_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_IOCON_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_IOCON_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_GPIO_RST_SET_MASK  (0x4000U)
+#define SYSCON_PRESETCTRLSET0_GPIO_RST_SET_SHIFT (14U)
+/*! GPIO_RST_SET - Writing one to this register sets the GPIO_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_GPIO_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_GPIO_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_GPIO_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_PINT_RST_SET_MASK  (0x40000U)
+#define SYSCON_PRESETCTRLSET0_PINT_RST_SET_SHIFT (18U)
+/*! PINT_RST_SET - Writing one to this register sets the PINT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_PINT_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_PINT_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_PINT_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_GINT_RST_SET_MASK  (0x80000U)
+#define SYSCON_PRESETCTRLSET0_GINT_RST_SET_SHIFT (19U)
+/*! GINT_RST_SET - Writing one to this register sets the GINT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_GINT_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_GINT_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_GINT_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_DMA_RST_SET_MASK   (0x100000U)
+#define SYSCON_PRESETCTRLSET0_DMA_RST_SET_SHIFT  (20U)
+/*! DMA_RST_SET - Writing one to this register sets the DMA_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_DMA_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_DMA_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_DMA_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_ISO7816_RST_SET_MASK (0x200000U)
+#define SYSCON_PRESETCTRLSET0_ISO7816_RST_SET_SHIFT (21U)
+/*! ISO7816_RST_SET - Writing one to this register sets the ISO7816_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_ISO7816_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_ISO7816_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_ISO7816_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_WWDT_RST_SET_MASK  (0x400000U)
+#define SYSCON_PRESETCTRLSET0_WWDT_RST_SET_SHIFT (22U)
+/*! WWDT_RST_SET - Writing one to this register sets the WWDT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_WWDT_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_WWDT_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_WWDT_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_RTC_RST_SET_MASK   (0x800000U)
+#define SYSCON_PRESETCTRLSET0_RTC_RST_SET_SHIFT  (23U)
+/*! RTC_RST_SET - Writing one to this register sets the RTC_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_RTC_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_RTC_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_RTC_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET_MASK (0x1000000U)
+#define SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET_SHIFT (24U)
+/*! ANA_INT_CTRL_RST_SET - Writing one to this register sets the ANA_INT_CTRL_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_ANA_INT_CTRL_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET_MASK (0x2000000U)
+#define SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET_SHIFT (25U)
+/*! WAKE_UP_TIMERS_RST_SET - Writing one to this register sets the WAKE_UP_TIMERS bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_WAKE_UP_TIMERS_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET0_ADC_RST_SET_MASK   (0x8000000U)
+#define SYSCON_PRESETCTRLSET0_ADC_RST_SET_SHIFT  (27U)
+/*! ADC_RST_SET - Writing one to this register sets the ADC_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLSET0_ADC_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET0_ADC_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET0_ADC_RST_SET_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLSET1 - Set bits in PRESETCTRL1. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers. */
+/*! @{ */
+#define SYSCON_PRESETCTRLSET1_USART0_RST_SET_MASK (0x800U)
+#define SYSCON_PRESETCTRLSET1_USART0_RST_SET_SHIFT (11U)
+/*! USART0_RST_SET - Writing one to this register sets the UART0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_USART0_RST_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_USART0_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_USART0_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_USART1_RST_SET_MASK (0x1000U)
+#define SYSCON_PRESETCTRLSET1_USART1_RST_SET_SHIFT (12U)
+/*! USART1_RST_SET - Writing one to this register sets the UART1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_USART1_RST_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_USART1_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_USART1_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_I2C0_RST_SET_MASK  (0x2000U)
+#define SYSCON_PRESETCTRLSET1_I2C0_RST_SET_SHIFT (13U)
+/*! I2C0_RST_SET - Writing one to this register sets the I2C0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_I2C0_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_I2C0_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_I2C0_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_I2C1_RST_SET_MASK  (0x4000U)
+#define SYSCON_PRESETCTRLSET1_I2C1_RST_SET_SHIFT (14U)
+/*! I2C1_RST_SET - Writing one to this register sets the I2C1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_I2C1_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_I2C1_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_I2C1_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_SPI0_RST_SET_MASK  (0x8000U)
+#define SYSCON_PRESETCTRLSET1_SPI0_RST_SET_SHIFT (15U)
+/*! SPI0_RST_SET - Writing one to this register sets the SPI0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_SPI0_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_SPI0_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_SPI0_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_SPI1_RST_SET_MASK  (0x10000U)
+#define SYSCON_PRESETCTRLSET1_SPI1_RST_SET_SHIFT (16U)
+/*! SPI1_RST_SET - Writing one to this register sets the SPI1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_SPI1_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_SPI1_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_SPI1_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_IR_RST_SET_MASK    (0x20000U)
+#define SYSCON_PRESETCTRLSET1_IR_RST_SET_SHIFT   (17U)
+/*! IR_RST_SET - Writing one to this register sets the IR_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_IR_RST_SET(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_IR_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_IR_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_PWM_RST_SET_MASK   (0x40000U)
+#define SYSCON_PRESETCTRLSET1_PWM_RST_SET_SHIFT  (18U)
+/*! PWM_RST_SET - Writing one to this register sets the PWM_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_PWM_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_PWM_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_PWM_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_RNG_RST_SET_MASK   (0x80000U)
+#define SYSCON_PRESETCTRLSET1_RNG_RST_SET_SHIFT  (19U)
+/*! RNG_RST_SET - Writing one to this register sets the RNG_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_RNG_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_RNG_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_RNG_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_I2C2_RST_SET_MASK  (0x100000U)
+#define SYSCON_PRESETCTRLSET1_I2C2_RST_SET_SHIFT (20U)
+/*! I2C2_RST_SET - Writing one to this register sets the I2C2_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_I2C2_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_I2C2_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_I2C2_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET_MASK (0x200000U)
+#define SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET_SHIFT (21U)
+/*! ZIGBEE_RST_SET - Writing one to this register sets the ZIGBEE_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_ZIGBEE_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_BLE_RST_SET_MASK   (0x400000U)
+#define SYSCON_PRESETCTRLSET1_BLE_RST_SET_SHIFT  (22U)
+/*! BLE_RST_SET - Writing one to this register sets the BLE_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_BLE_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_BLE_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_BLE_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET_MASK (0x800000U)
+#define SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET_SHIFT (23U)
+/*! MODEM_MASTER_RST_SET - Writing one to this register sets the MODEM_MASTER_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_MODEM_MASTER_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_AES_RST_SET_MASK   (0x1000000U)
+#define SYSCON_PRESETCTRLSET1_AES_RST_SET_SHIFT  (24U)
+/*! AES_RST_SET - Writing one to this register sets the AES_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_AES_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_AES_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_AES_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_RFP_RST_SET_MASK   (0x2000000U)
+#define SYSCON_PRESETCTRLSET1_RFP_RST_SET_SHIFT  (25U)
+/*! RFP_RST_SET - Writing one to this register sets the RFP_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_RFP_RST_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_RFP_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_RFP_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_DMIC_RST_SET_MASK  (0x4000000U)
+#define SYSCON_PRESETCTRLSET1_DMIC_RST_SET_SHIFT (26U)
+/*! DMIC_RST_SET - Writing one to this register sets the DMIC_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_DMIC_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_DMIC_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_DMIC_RST_SET_MASK)
+#define SYSCON_PRESETCTRLSET1_HASH_RST_SET_MASK  (0x8000000U)
+#define SYSCON_PRESETCTRLSET1_HASH_RST_SET_SHIFT (27U)
+/*! HASH_RST_SET - Writing one to this register sets the HASH_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLSET1_HASH_RST_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET1_HASH_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET1_HASH_RST_SET_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLSETX_PRESETCTRLSETS - Pin assign register */
+/*! @{ */
+#define SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA_SHIFT (0U)
+#define SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA_SHIFT)) & SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_PRESETCTRLSETX_PRESETCTRLSETS */
+#define SYSCON_PRESETCTRLSETX_PRESETCTRLSETS_COUNT (2U)
+
+/*! @name PRESETCTRLCLR0 - Clear bits in PRESETCTRL0. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers. */
+/*! @{ */
+#define SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR_MASK (0x400U)
+#define SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR_SHIFT (10U)
+/*! SPIFI_RST_CLR - Writing one to this register clears the SPIFI_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_SPIFI_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_MUX_RST_CLR_MASK   (0x800U)
+#define SYSCON_PRESETCTRLCLR0_MUX_RST_CLR_SHIFT  (11U)
+/*! MUX_RST_CLR - Writing one to this register clears the MUX_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_MUX_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_MUX_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_MUX_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_BLE_TIMING_GEN_RST_CLR_MASK (0x1000U)
+#define SYSCON_PRESETCTRLCLR0_BLE_TIMING_GEN_RST_CLR_SHIFT (12U)
+/*! BLE_TIMING_GEN_RST_CLR - Writing one to this register clears the BLE_TIMING_GEN_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_BLE_TIMING_GEN_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_BLE_TIMING_GEN_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_BLE_TIMING_GEN_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR_MASK (0x2000U)
+#define SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR_SHIFT (13U)
+/*! IOCON_RST_CLR - Writing one to this register clears the IOCON_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_IOCON_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR_MASK  (0x4000U)
+#define SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR_SHIFT (14U)
+/*! GPIO_RST_CLR - Writing one to this register clears the GPIO_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_GPIO_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_PINT_RST_CLR_MASK  (0x40000U)
+#define SYSCON_PRESETCTRLCLR0_PINT_RST_CLR_SHIFT (18U)
+/*! PINT_RST_CLR - Writing one to this register clears the PINT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_PINT_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_PINT_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_PINT_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_GINT_RST_CLR_MASK  (0x80000U)
+#define SYSCON_PRESETCTRLCLR0_GINT_RST_CLR_SHIFT (19U)
+/*! GINT_RST_CLR - Writing one to this register clears the GINT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_GINT_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_GINT_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_GINT_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_DMA_RST_CLR_MASK   (0x100000U)
+#define SYSCON_PRESETCTRLCLR0_DMA_RST_CLR_SHIFT  (20U)
+/*! DMA_RST_CLR - Writing one to this register clears the DMA_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_DMA_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_DMA_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_DMA_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR_MASK (0x200000U)
+#define SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR_SHIFT (21U)
+/*! ISO7816_RST_CLR - Writing one to this register clears the ISO7816_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_ISO7816_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR_MASK  (0x400000U)
+#define SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR_SHIFT (22U)
+/*! WWDT_RST_CLR - Writing one to this register clears the WWDT_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_WWDT_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_RTC_RST_CLR_MASK   (0x800000U)
+#define SYSCON_PRESETCTRLCLR0_RTC_RST_CLR_SHIFT  (23U)
+/*! RTC_RST_CLR - Writing one to this register clears the RTC_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_RTC_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_RTC_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_RTC_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR_MASK (0x1000000U)
+#define SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR_SHIFT (24U)
+/*! ANA_INT_CTRL_RST_CLR - Writing one to this register clears the ANA_INT_CTRL_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_ANA_INT_CTRL_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR_MASK (0x2000000U)
+#define SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR_SHIFT (25U)
+/*! WAKE_UP_TIMERS_RST_CLR - Writing one to this register clears the WAKE_UP_TIMERS_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_WAKE_UP_TIMERS_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR0_ADC_RST_CLR_MASK   (0x8000000U)
+#define SYSCON_PRESETCTRLCLR0_ADC_RST_CLR_SHIFT  (27U)
+/*! ADC_RST_CLR - Writing one to this register clears the ADC_RST bit in the PRESETCTRL0 register
+ */
+#define SYSCON_PRESETCTRLCLR0_ADC_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR0_ADC_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR0_ADC_RST_CLR_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLCLR1 - Clear bits in PRESETCTRL1. It is recommended that changes to PRESETCTRL registers be accomplished by using the related PRESETCTRLSET and PRESETCTRLCLR registers. */
+/*! @{ */
+#define SYSCON_PRESETCTRLCLR1_USART0_RST_CLR_MASK (0x800U)
+#define SYSCON_PRESETCTRLCLR1_USART0_RST_CLR_SHIFT (11U)
+/*! USART0_RST_CLR - Writing one to this register clears the UART0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_USART0_RST_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_USART0_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_USART0_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_USART1_RST_CLR_MASK (0x1000U)
+#define SYSCON_PRESETCTRLCLR1_USART1_RST_CLR_SHIFT (12U)
+/*! USART1_RST_CLR - Writing one to this register clears the UART1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_USART1_RST_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_USART1_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_USART1_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR_MASK  (0x2000U)
+#define SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR_SHIFT (13U)
+/*! I2C0_RST_CLR - Writing one to this register clears the I2C0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_I2C0_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR_MASK  (0x4000U)
+#define SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR_SHIFT (14U)
+/*! I2C1_RST_CLR - Writing one to this register clears the I2C1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_I2C1_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR_MASK  (0x8000U)
+#define SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR_SHIFT (15U)
+/*! SPI0_RST_CLR - Writing one to this register clears the SPI0_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_SPI0_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR_MASK  (0x10000U)
+#define SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR_SHIFT (16U)
+/*! SPI1_RST_CLR - Writing one to this register clears the SPI1_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_SPI1_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_IR_RST_CLR_MASK    (0x20000U)
+#define SYSCON_PRESETCTRLCLR1_IR_RST_CLR_SHIFT   (17U)
+/*! IR_RST_CLR - Writing one to this register clears the IR_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_IR_RST_CLR(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_IR_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_IR_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_PWM_RST_CLR_MASK   (0x40000U)
+#define SYSCON_PRESETCTRLCLR1_PWM_RST_CLR_SHIFT  (18U)
+/*! PWM_RST_CLR - Writing one to this register clears the PWM_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_PWM_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_PWM_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_PWM_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_MASK   (0x80000U)
+#define SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_SHIFT  (19U)
+/*! RNG_RST_CLR - Writing one to this register clears the RNG_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_RNG_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR_MASK  (0x100000U)
+#define SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR_SHIFT (20U)
+/*! I2C2_RST_CLR - Writing one to this register clears the I2C2_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_I2C2_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR_MASK (0x200000U)
+#define SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR_SHIFT (21U)
+/*! ZIGBEE_RST_CLR - Writing one to this register clears the ZIGBEE_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_ZIGBEE_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_BLE_RST_CLR_MASK   (0x400000U)
+#define SYSCON_PRESETCTRLCLR1_BLE_RST_CLR_SHIFT  (22U)
+/*! BLE_RST_CLR - Writing one to this register clears the BLE_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_BLE_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_BLE_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_BLE_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR_MASK (0x800000U)
+#define SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR_SHIFT (23U)
+/*! MODEM_MASTER_RST_CLR - Writing one to this register clears the MODEM_MASTER_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_MODEM_MASTER_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_AES_RST_CLR_MASK   (0x1000000U)
+#define SYSCON_PRESETCTRLCLR1_AES_RST_CLR_SHIFT  (24U)
+/*! AES_RST_CLR - Writing one to this register clears the AES_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_AES_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_AES_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_AES_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_RFP_RST_CLR_MASK   (0x2000000U)
+#define SYSCON_PRESETCTRLCLR1_RFP_RST_CLR_SHIFT  (25U)
+/*! RFP_RST_CLR - Writing one to this register clears the RFP_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_RFP_RST_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_RFP_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_RFP_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR_MASK  (0x4000000U)
+#define SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR_SHIFT (26U)
+/*! DMIC_RST_CLR - Writing one to this register clears the DMIC_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_DMIC_RST_CLR_MASK)
+#define SYSCON_PRESETCTRLCLR1_HASH_RST_CLR_MASK  (0x8000000U)
+#define SYSCON_PRESETCTRLCLR1_HASH_RST_CLR_SHIFT (27U)
+/*! HASH_RST_CLR - Writing one to this register clears the HASH_RST bit in the PRESETCTRL1 register
+ */
+#define SYSCON_PRESETCTRLCLR1_HASH_RST_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR1_HASH_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR1_HASH_RST_CLR_MASK)
+/*! @} */
+
+/*! @name PRESETCTRLCLRX_PRESETCTRLCLRS - Pin assign register */
+/*! @{ */
+#define SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA_SHIFT (0U)
+#define SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA_SHIFT)) & SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS */
+#define SYSCON_PRESETCTRLCLRX_PRESETCTRLCLRS_COUNT (2U)
+
+/*! @name AHBCLKCTRL0 - AHB Clock control 0 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL0_MASK       (0x8U)
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL0_SHIFT      (3U)
+/*! SRAM_CTRL0 - Enables the clock for the SRAM Controller 0 (SRAM 0 to SRAM 7). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL0(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_SRAM_CTRL0_SHIFT)) & SYSCON_AHBCLKCTRL0_SRAM_CTRL0_MASK)
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL1_MASK       (0x10U)
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL1_SHIFT      (4U)
+/*! SRAM_CTRL1 - Enables the clock for the SRAM Controller 1 (SRAM 8 to SRAM 11). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_SRAM_CTRL1(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_SRAM_CTRL1_SHIFT)) & SYSCON_AHBCLKCTRL0_SRAM_CTRL1_MASK)
+#define SYSCON_AHBCLKCTRL0_SPIFI_MASK            (0x400U)
+#define SYSCON_AHBCLKCTRL0_SPIFI_SHIFT           (10U)
+/*! SPIFI - Enables the clock for the Quad SPI Flash controller [Note: SPIFI IOs need configuring
+ *    for high drive]. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_SPIFI(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_SPIFI_SHIFT)) & SYSCON_AHBCLKCTRL0_SPIFI_MASK)
+#define SYSCON_AHBCLKCTRL0_MUX_MASK              (0x800U)
+#define SYSCON_AHBCLKCTRL0_MUX_SHIFT             (11U)
+/*! MUX - Enables the clock for the Input Mux. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_MUX(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_MUX_SHIFT)) & SYSCON_AHBCLKCTRL0_MUX_MASK)
+#define SYSCON_AHBCLKCTRL0_IOCON_MASK            (0x2000U)
+#define SYSCON_AHBCLKCTRL0_IOCON_SHIFT           (13U)
+/*! IOCON - Enables the clock for the I/O controller block. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_IOCON(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_IOCON_SHIFT)) & SYSCON_AHBCLKCTRL0_IOCON_MASK)
+#define SYSCON_AHBCLKCTRL0_GPIO_MASK             (0x4000U)
+#define SYSCON_AHBCLKCTRL0_GPIO_SHIFT            (14U)
+/*! GPIO - Enables the clock for the GPIO. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_GPIO(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_GPIO_SHIFT)) & SYSCON_AHBCLKCTRL0_GPIO_MASK)
+#define SYSCON_AHBCLKCTRL0_PINT_MASK             (0x40000U)
+#define SYSCON_AHBCLKCTRL0_PINT_SHIFT            (18U)
+/*! PINT - Enables the clock for the Pin interrupt block (PINT). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_PINT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_PINT_SHIFT)) & SYSCON_AHBCLKCTRL0_PINT_MASK)
+#define SYSCON_AHBCLKCTRL0_GINT_MASK             (0x80000U)
+#define SYSCON_AHBCLKCTRL0_GINT_SHIFT            (19U)
+/*! GINT - Enables the clock for the Group interrupt block (GINT). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_GINT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_GINT_SHIFT)) & SYSCON_AHBCLKCTRL0_GINT_MASK)
+#define SYSCON_AHBCLKCTRL0_DMA_MASK              (0x100000U)
+#define SYSCON_AHBCLKCTRL0_DMA_SHIFT             (20U)
+/*! DMA - Enables the clock for the DMA controller. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_DMA(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_DMA_SHIFT)) & SYSCON_AHBCLKCTRL0_DMA_MASK)
+#define SYSCON_AHBCLKCTRL0_ISO7816_MASK          (0x200000U)
+#define SYSCON_AHBCLKCTRL0_ISO7816_SHIFT         (21U)
+/*! ISO7816 - Enables the clock for the ISO7816 smart card interface. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_ISO7816(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_ISO7816_SHIFT)) & SYSCON_AHBCLKCTRL0_ISO7816_MASK)
+#define SYSCON_AHBCLKCTRL0_WWDT_MASK             (0x400000U)
+#define SYSCON_AHBCLKCTRL0_WWDT_SHIFT            (22U)
+/*! WWDT - Enables the clock for the Watchdog Timer. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_WWDT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_WWDT_SHIFT)) & SYSCON_AHBCLKCTRL0_WWDT_MASK)
+#define SYSCON_AHBCLKCTRL0_RTC_MASK              (0x800000U)
+#define SYSCON_AHBCLKCTRL0_RTC_SHIFT             (23U)
+/*! RTC - Enables the clock for the RTC. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_RTC(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_RTC_SHIFT)) & SYSCON_AHBCLKCTRL0_RTC_MASK)
+#define SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_MASK     (0x1000000U)
+#define SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_SHIFT    (24U)
+/*! ANA_INT_CTRL - Enables the clock for the Analog Interrupt Control module (for BOD and comparator
+ *    status and interrupt control). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_ANA_INT_CTRL(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_SHIFT)) & SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_MASK)
+#define SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_MASK   (0x2000000U)
+#define SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_SHIFT  (25U)
+/*! WAKE_UP_TIMERS - Enables the clock for the Wake up Timers. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_SHIFT)) & SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_MASK)
+#define SYSCON_AHBCLKCTRL0_ADC_MASK              (0x8000000U)
+#define SYSCON_AHBCLKCTRL0_ADC_SHIFT             (27U)
+/*! ADC - Enables the clock for the ADC Controller. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL0_ADC(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL0_ADC_SHIFT)) & SYSCON_AHBCLKCTRL0_ADC_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRL1 - AHB Clock control 1 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRL1_USART0_MASK           (0x800U)
+#define SYSCON_AHBCLKCTRL1_USART0_SHIFT          (11U)
+/*! USART0 - Enable the clock for the UART0. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_USART0(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_USART0_SHIFT)) & SYSCON_AHBCLKCTRL1_USART0_MASK)
+#define SYSCON_AHBCLKCTRL1_USART1_MASK           (0x1000U)
+#define SYSCON_AHBCLKCTRL1_USART1_SHIFT          (12U)
+/*! USART1 - Enable the clock for the UART1. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_USART1(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_USART1_SHIFT)) & SYSCON_AHBCLKCTRL1_USART1_MASK)
+#define SYSCON_AHBCLKCTRL1_I2C0_MASK             (0x2000U)
+#define SYSCON_AHBCLKCTRL1_I2C0_SHIFT            (13U)
+/*! I2C0 - Enable the clock for the I2C0. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_I2C0(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_I2C0_SHIFT)) & SYSCON_AHBCLKCTRL1_I2C0_MASK)
+#define SYSCON_AHBCLKCTRL1_I2C1_MASK             (0x4000U)
+#define SYSCON_AHBCLKCTRL1_I2C1_SHIFT            (14U)
+/*! I2C1 - Enable the clock for the I2C1. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_I2C1(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_I2C1_SHIFT)) & SYSCON_AHBCLKCTRL1_I2C1_MASK)
+#define SYSCON_AHBCLKCTRL1_SPI0_MASK             (0x8000U)
+#define SYSCON_AHBCLKCTRL1_SPI0_SHIFT            (15U)
+/*! SPI0 - Enable the clock for the SPI0. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_SPI0(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_SPI0_SHIFT)) & SYSCON_AHBCLKCTRL1_SPI0_MASK)
+#define SYSCON_AHBCLKCTRL1_SPI1_MASK             (0x10000U)
+#define SYSCON_AHBCLKCTRL1_SPI1_SHIFT            (16U)
+/*! SPI1 - Enable the clock for the SPI1. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_SPI1(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_SPI1_SHIFT)) & SYSCON_AHBCLKCTRL1_SPI1_MASK)
+#define SYSCON_AHBCLKCTRL1_IR_MASK               (0x20000U)
+#define SYSCON_AHBCLKCTRL1_IR_SHIFT              (17U)
+/*! IR - Enable the clock for the Infra Red. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_IR(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_IR_SHIFT)) & SYSCON_AHBCLKCTRL1_IR_MASK)
+#define SYSCON_AHBCLKCTRL1_PWM_MASK              (0x40000U)
+#define SYSCON_AHBCLKCTRL1_PWM_SHIFT             (18U)
+/*! PWM - Enable the clock for the PWM. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_PWM(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_PWM_SHIFT)) & SYSCON_AHBCLKCTRL1_PWM_MASK)
+#define SYSCON_AHBCLKCTRL1_RNG_MASK              (0x80000U)
+#define SYSCON_AHBCLKCTRL1_RNG_SHIFT             (19U)
+/*! RNG - Enable the clock for the Random Number Generator. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_RNG(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_RNG_SHIFT)) & SYSCON_AHBCLKCTRL1_RNG_MASK)
+#define SYSCON_AHBCLKCTRL1_I2C2_MASK             (0x100000U)
+#define SYSCON_AHBCLKCTRL1_I2C2_SHIFT            (20U)
+/*! I2C2 - Enable the clock for the I2C2. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_I2C2(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_I2C2_SHIFT)) & SYSCON_AHBCLKCTRL1_I2C2_MASK)
+#define SYSCON_AHBCLKCTRL1_ZIGBEE_MASK           (0x200000U)
+#define SYSCON_AHBCLKCTRL1_ZIGBEE_SHIFT          (21U)
+/*! ZIGBEE - Enable the clock for the Zigbee Modem . 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_ZIGBEE(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_ZIGBEE_SHIFT)) & SYSCON_AHBCLKCTRL1_ZIGBEE_MASK)
+#define SYSCON_AHBCLKCTRL1_BLE_MASK              (0x400000U)
+#define SYSCON_AHBCLKCTRL1_BLE_SHIFT             (22U)
+/*! BLE - Enable the clock for the BLE Modem. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_BLE(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_BLE_SHIFT)) & SYSCON_AHBCLKCTRL1_BLE_MASK)
+#define SYSCON_AHBCLKCTRL1_MODEM_MASTER_MASK     (0x800000U)
+#define SYSCON_AHBCLKCTRL1_MODEM_MASTER_SHIFT    (23U)
+/*! MODEM_MASTER - Enable the clock for the Modem AHB Master Interface. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_MODEM_MASTER(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_MODEM_MASTER_SHIFT)) & SYSCON_AHBCLKCTRL1_MODEM_MASTER_MASK)
+#define SYSCON_AHBCLKCTRL1_AES_MASK              (0x1000000U)
+#define SYSCON_AHBCLKCTRL1_AES_SHIFT             (24U)
+/*! AES - Enable the clock for the AES. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_AES(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_AES_SHIFT)) & SYSCON_AHBCLKCTRL1_AES_MASK)
+#define SYSCON_AHBCLKCTRL1_RFP_MASK              (0x2000000U)
+#define SYSCON_AHBCLKCTRL1_RFP_SHIFT             (25U)
+/*! RFP - Enable the clock for the RFP (Radio Front End controller). 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_RFP(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_RFP_SHIFT)) & SYSCON_AHBCLKCTRL1_RFP_MASK)
+#define SYSCON_AHBCLKCTRL1_DMIC_MASK             (0x4000000U)
+#define SYSCON_AHBCLKCTRL1_DMIC_SHIFT            (26U)
+/*! DMIC - Enable the clock for the DMIC. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_DMIC(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_DMIC_SHIFT)) & SYSCON_AHBCLKCTRL1_DMIC_MASK)
+#define SYSCON_AHBCLKCTRL1_HASH_MASK             (0x8000000U)
+#define SYSCON_AHBCLKCTRL1_HASH_SHIFT            (27U)
+/*! HASH - Enable the clock for the Hash. 0: Disable. 1: Enable.
+ */
+#define SYSCON_AHBCLKCTRL1_HASH(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL1_HASH_SHIFT)) & SYSCON_AHBCLKCTRL1_HASH_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLX_AHBCLKCTRLS - Pin assign register */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA_SHIFT (0U)
+#define SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA_SHIFT)) & SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_AHBCLKCTRLX_AHBCLKCTRLS */
+#define SYSCON_AHBCLKCTRLX_AHBCLKCTRLS_COUNT     (2U)
+
+/*! @name AHBCLKCTRLSET0 - Set bits in AHBCLKCTRL0 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET_MASK (0x8U)
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET_SHIFT (3U)
+/*! SRAM_CTRL0_CLK_SET - Writing one to this register sets the SRAM_CTRL0 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_SRAM_CTRL0_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET_MASK (0x10U)
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET_SHIFT (4U)
+/*! SRAM_CTRL1_CLK_SET - Writing one to this register sets the SRAM_CTRL1 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_SRAM_CTRL1_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET_MASK (0x400U)
+#define SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET_SHIFT (10U)
+/*! SPIFI_CLK_SET - Writing one to this register sets the SPIFI bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_SPIFI_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET_MASK   (0x800U)
+#define SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET_SHIFT  (11U)
+/*! MUX_CLK_SET - Writing one to this register sets the MUX bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_MUX_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET_MASK (0x2000U)
+#define SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET_SHIFT (13U)
+/*! IOCON_CLK_SET - Writing one to this register sets the IOCON bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_IOCON_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET_MASK  (0x4000U)
+#define SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET_SHIFT (14U)
+/*! GPIO_CLK_SET - Writing one to this register sets the GPIO bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_GPIO_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET_MASK  (0x40000U)
+#define SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET_SHIFT (18U)
+/*! PINT_CLK_SET - Writing one to this register sets the PINT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_PINT_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET_MASK  (0x80000U)
+#define SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET_SHIFT (19U)
+/*! GINT_CLK_SET - Writing one to this register sets the GINT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_GINT_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET_MASK   (0x100000U)
+#define SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET_SHIFT  (20U)
+/*! DMA_CLK_SET - Writing one to this register sets the DMA bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_DMA_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET_MASK (0x200000U)
+#define SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET_SHIFT (21U)
+/*! ISO7816_CLK_SET - Writing one to this register sets the ISO7816 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_ISO7816_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET_MASK  (0x400000U)
+#define SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET_SHIFT (22U)
+/*! WWDT_CLK_SET - Writing one to this register sets the WWDT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_WWDT_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET_MASK   (0x800000U)
+#define SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET_SHIFT  (23U)
+/*! RTC_CLK_SET - Writing one to this register sets the RTC bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_RTC_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET_MASK (0x1000000U)
+#define SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET_SHIFT (24U)
+/*! ANA_INT_CTRL_CLK_SET - Writing one to this register sets the ANA_INT_CTRL bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_ANA_INT_CTRL_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_MASK (0x2000000U)
+#define SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_SHIFT (25U)
+/*! WAKE_UP_TIMERS_CLK_SET - Writing one to this register sets the WAKE_UP_TIMERS bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET_MASK   (0x8000000U)
+#define SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET_SHIFT  (27U)
+/*! ADC_CLK_SET - Writing one to this register sets the ADC bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET0_ADC_CLK_SET_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLSET1 - Set bits in AHBCLKCTRL1 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET_MASK (0x800U)
+#define SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET_SHIFT (11U)
+/*! USART0_CLK_SET - Writing one to this register sets the UART0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_USART0_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET_MASK (0x1000U)
+#define SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET_SHIFT (12U)
+/*! USART1_CLK_SET - Writing one to this register sets the UART1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_USART1_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET_MASK  (0x2000U)
+#define SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET_SHIFT (13U)
+/*! I2C0_CLK_SET - Writing one to this register sets the I2C0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_I2C0_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET_MASK  (0x4000U)
+#define SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET_SHIFT (14U)
+/*! I2C1_CLK_SET - Writing one to this register sets the I2C1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_I2C1_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET_MASK  (0x8000U)
+#define SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET_SHIFT (15U)
+/*! SPI0_CLK_SET - Writing one to this register sets the SPI0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_SPI0_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET_MASK  (0x10000U)
+#define SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET_SHIFT (16U)
+/*! SPI1_CLK_SET - Writing one to this register sets the SPI1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_SPI1_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_IR_CLK_SET_MASK    (0x20000U)
+#define SYSCON_AHBCLKCTRLSET1_IR_CLK_SET_SHIFT   (17U)
+/*! IR_CLK_SET - Writing one to this register sets the IR bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_IR_CLK_SET(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_IR_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_IR_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET_MASK   (0x40000U)
+#define SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET_SHIFT  (18U)
+/*! PWM_CLK_SET - Writing one to this register sets the PWM bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_PWM_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET_MASK   (0x80000U)
+#define SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET_SHIFT  (19U)
+/*! RNG_CLK_SET - Writing one to this register sets the RNG bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_RNG_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET_MASK  (0x100000U)
+#define SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET_SHIFT (20U)
+/*! I2C2_CLK_SET - Writing one to this register sets the I2C2 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_I2C2_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET_MASK (0x200000U)
+#define SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET_SHIFT (21U)
+/*! ZIGBEE_CLK_SET - Writing one to this register sets the ZIGBEE bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_ZIGBEE_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_BLE_CLK_SET_MASK   (0x400000U)
+#define SYSCON_AHBCLKCTRLSET1_BLE_CLK_SET_SHIFT  (22U)
+/*! BLE_CLK_SET - Writing one to this register sets the BLE bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_BLE_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_BLE_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_BLE_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET_MASK (0x800000U)
+#define SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET_SHIFT (23U)
+/*! MODEM_MASTER_CLK_SET - Writing one to this register sets the MODEM_MASTER bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_MODEM_MASTER_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_AES_CLK_SET_MASK   (0x1000000U)
+#define SYSCON_AHBCLKCTRLSET1_AES_CLK_SET_SHIFT  (24U)
+/*! AES_CLK_SET - Writing one to this register sets the AES bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_AES_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_AES_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_AES_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET_MASK   (0x2000000U)
+#define SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET_SHIFT  (25U)
+/*! RFP_CLK_SET - Writing one to this register sets the RFP bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_RFP_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET_MASK  (0x4000000U)
+#define SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET_SHIFT (26U)
+/*! DMIC_CLK_SET - Writing one to this register sets the DMIC bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_DMIC_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET_MASK  (0x8000000U)
+#define SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET_SHIFT (27U)
+/*! HASH_CLK_SET - Writing one to this register sets the HASH bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET1_HASH_CLK_SET_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLSETX_AHBCLKCTRLSETS - Pin assign register */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA_SHIFT (0U)
+#define SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA_SHIFT)) & SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS */
+#define SYSCON_AHBCLKCTRLSETX_AHBCLKCTRLSETS_COUNT (2U)
+
+/*! @name AHBCLKCTRLCLR0 - Clear bits in AHBCLKCTRL0 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR_MASK   (0x2U)
+#define SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR_SHIFT  (1U)
+/*! ROM_CLK_CLR - Writing one to this register clears the ROM bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_ROM_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR_MASK (0x8U)
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR_SHIFT (3U)
+/*! SRAM_CTRL0_CLK_CLR - Writing one to this register clears the SRAM_CTRL0 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL0_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR_MASK (0x10U)
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR_SHIFT (4U)
+/*! SRAM_CTRL1_CLK_CLR - Writing one to this register clears the SRAM_CTRL1 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_SRAM_CTRL1_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR_MASK (0x100U)
+#define SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR_SHIFT (8U)
+/*! FLASH_CLK_CLR - Writing one to this register clears the FLASH bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_FLASH_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR_MASK (0x400U)
+#define SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR_SHIFT (10U)
+/*! SPIFI_CLK_CLR - Writing one to this register clears the SPIFI bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_SPIFI_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR_MASK   (0x800U)
+#define SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR_SHIFT  (11U)
+/*! MUX_CLK_CLR - Writing one to this register clears the MUX bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_MUX_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR_MASK (0x2000U)
+#define SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR_SHIFT (13U)
+/*! IOCON_CLK_CLR - Writing one to this register clears the IOCON bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_IOCON_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR_MASK  (0x4000U)
+#define SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR_SHIFT (14U)
+/*! GPIO_CLK_CLR - Writing one to this register clears the GPIO bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_GPIO_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR_MASK  (0x40000U)
+#define SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR_SHIFT (18U)
+/*! PINT_CLK_CLR - Writing one to this register clears the PINT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_PINT_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR_MASK  (0x80000U)
+#define SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR_SHIFT (19U)
+/*! GINT_CLK_CLR - Writing one to this register clears the GINT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_GINT_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR_MASK   (0x100000U)
+#define SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR_SHIFT  (20U)
+/*! DMA_CLK_CLR - Writing one to this register clears the DMA bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_DMA_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR_MASK (0x200000U)
+#define SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR_SHIFT (21U)
+/*! ISO7816_CLK_CLR - Writing one to this register clears the ISO7816 bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_ISO7816_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR_MASK  (0x400000U)
+#define SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR_SHIFT (22U)
+/*! WWDT_CLK_CLR - Writing one to this register clears the WWDT bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_WWDT_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR_MASK   (0x800000U)
+#define SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR_SHIFT  (23U)
+/*! RTC_CLK_CLR - Writing one to this register clears the RTC bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_RTC_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET_MASK (0x1000000U)
+#define SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET_SHIFT (24U)
+/*! ANA_INT_CTRL_CLK_SET - Writing one to this register clears the ANA_INT_CTRL bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_ANA_INT_CTRL_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET_MASK (0x2000000U)
+#define SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET_SHIFT (25U)
+/*! WAKE_UP_TIMERS_CLK_SET - Writing one to this register clears the WAKE_UP_TIMERS bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_WAKE_UP_TIMERS_CLK_SET_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR_MASK   (0x8000000U)
+#define SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR_SHIFT  (27U)
+/*! ADC_CLK_CLR - Writing one to this register clears the ADC bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_ADC_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR_MASK (0x10000000U)
+#define SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR_SHIFT (28U)
+/*! EFUSE_CLK_CLR - Writing one to this register clears the EFUSE bit in the AHBCLKCTRL0 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR0_EFUSE_CLK_CLR_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLCLR1 - Clear bits in AHBCLKCTRL1 */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR_MASK (0x800U)
+#define SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR_SHIFT (11U)
+/*! USART0_CLK_CLR - Writing one to this register clears the UART0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_USART0_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR_MASK (0x1000U)
+#define SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR_SHIFT (12U)
+/*! USART1_CLK_CLR - Writing one to this register clears the UART1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_USART1_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR_MASK  (0x2000U)
+#define SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR_SHIFT (13U)
+/*! I2C0_CLK_CLR - Writing one to this register clears the I2C0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_I2C0_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR_MASK  (0x4000U)
+#define SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR_SHIFT (14U)
+/*! I2C1_CLK_CLR - Writing one to this register clears the I2C1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_I2C1_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR_MASK  (0x8000U)
+#define SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR_SHIFT (15U)
+/*! SPI0_CLK_CLR - Writing one to this register clears the SPI0 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_SPI0_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR_MASK  (0x10000U)
+#define SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR_SHIFT (16U)
+/*! SPI1_CLK_CLR - Writing one to this register clears the SPI1 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_SPI1_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR_MASK    (0x20000U)
+#define SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR_SHIFT   (17U)
+/*! IR_CLK_CLR - Writing one to this register clears the IR bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_IR_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR_MASK   (0x40000U)
+#define SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR_SHIFT  (18U)
+/*! PWM_CLK_CLR - Writing one to this register clears the PWM bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_PWM_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR_MASK   (0x80000U)
+#define SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR_SHIFT  (19U)
+/*! RNG_CLK_CLR - Writing one to this register clears the RNG bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_RNG_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR_MASK  (0x100000U)
+#define SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR_SHIFT (20U)
+/*! I2C2_CLK_CLR - Writing one to this register clears the I2C2 bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_I2C2_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR_MASK (0x200000U)
+#define SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR_SHIFT (21U)
+/*! ZIGBEE_CLK_CLR - Writing one to this register clears the ZIGBEE bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_ZIGBEE_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_BLE_CLK_CLR_MASK   (0x400000U)
+#define SYSCON_AHBCLKCTRLCLR1_BLE_CLK_CLR_SHIFT  (22U)
+/*! BLE_CLK_CLR - Writing one to this register clears the BLE bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_BLE_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_BLE_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_BLE_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR_MASK (0x800000U)
+#define SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR_SHIFT (23U)
+/*! MODEM_MASTER_CLK_CLR - Writing one to this register clears the MODEM_MASTER bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_MODEM_MASTER_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR_MASK   (0x1000000U)
+#define SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR_SHIFT  (24U)
+/*! AES_CLK_CLR - Writing one to this register clears the AES bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_AES_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR_MASK   (0x2000000U)
+#define SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR_SHIFT  (25U)
+/*! RFP_CLK_CLR - Writing one to this register clears the RFP bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_RFP_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR_MASK  (0x4000000U)
+#define SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR_SHIFT (26U)
+/*! DMIC_CLK_CLR - Writing one to this register clears the DMIC bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_DMIC_CLK_CLR_MASK)
+#define SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR_MASK  (0x8000000U)
+#define SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR_SHIFT (27U)
+/*! HASH_CLK_CLR - Writing one to this register clears the HASH bit in the AHBCLKCTRL1 register.
+ */
+#define SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR1_HASH_CLK_CLR_MASK)
+/*! @} */
+
+/*! @name AHBCLKCTRLCLRX_AHBCLKCTRLCLRS - Pin assign register */
+/*! @{ */
+#define SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA_SHIFT (0U)
+#define SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA_SHIFT)) & SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS */
+#define SYSCON_AHBCLKCTRLCLRX_AHBCLKCTRLCLRS_COUNT (2U)
+
+/*! @name MAINCLKSEL - Main clock source select */
+/*! @{ */
+#define SYSCON_MAINCLKSEL_SEL_MASK               (0x7U)
+#define SYSCON_MAINCLKSEL_SEL_SHIFT              (0U)
+/*! SEL - Main clock source selection:
+ *  0b000..12 MHz free running oscillator (FRO)
+ *  0b010..32 MHz crystal oscillator (XTAL)
+ *  0b011..32 MHz free running oscillator (FRO)
+ *  0b100..48 MHz free running oscillator (FRO)
+ */
+#define SYSCON_MAINCLKSEL_SEL(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_MAINCLKSEL_SEL_SHIFT)) & SYSCON_MAINCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name OSC32CLKSEL - OSC32KCLK and OSC32MCLK clock sources select. Note: this register is not locked by CLOCKGENUPDATELOCKOUT */
+/*! @{ */
+#define SYSCON_OSC32CLKSEL_SEL32MHZ_MASK         (0x1U)
+#define SYSCON_OSC32CLKSEL_SEL32MHZ_SHIFT        (0U)
+/*! SEL32MHZ - OSC32MCLK clock source selection
+ *  0b0..32 MHz free running oscillator (FRO)
+ *  0b1..32 MHz crystal oscillator
+ */
+#define SYSCON_OSC32CLKSEL_SEL32MHZ(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_OSC32CLKSEL_SEL32MHZ_SHIFT)) & SYSCON_OSC32CLKSEL_SEL32MHZ_MASK)
+#define SYSCON_OSC32CLKSEL_SEL32KHZ_MASK         (0x2U)
+#define SYSCON_OSC32CLKSEL_SEL32KHZ_SHIFT        (1U)
+/*! SEL32KHZ - OSC32KCLK clock source selection
+ *  0b0..32 KHz free running oscillator (FRO)
+ *  0b1..32 KHz crystal oscillator
+ */
+#define SYSCON_OSC32CLKSEL_SEL32KHZ(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_OSC32CLKSEL_SEL32KHZ_SHIFT)) & SYSCON_OSC32CLKSEL_SEL32KHZ_MASK)
+/*! @} */
+
+/*! @name CLKOUTSEL - CLKOUT clock source select */
+/*! @{ */
+#define SYSCON_CLKOUTSEL_SEL_MASK                (0x7U)
+#define SYSCON_CLKOUTSEL_SEL_SHIFT               (0U)
+/*! SEL - CLKOUT clock source selection
+ *  0b000..CPU & System Bus clock
+ *  0b001..32 KHz crystal oscillator (XTAL)
+ *  0b010..32 KHz free running oscillator (FRO)
+ *  0b011..32 MHz crystal oscillator (XTAL)
+ *  0b101..48 MHz free running oscillator (FRO)
+ *  0b110..1 MHz free running oscillator (FRO)
+ *  0b111..No clock
+ */
+#define SYSCON_CLKOUTSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTSEL_SEL_SHIFT)) & SYSCON_CLKOUTSEL_SEL_MASK)
+/*! @} */
+
+/*! @name SPIFICLKSEL - SPIFI clock source select */
+/*! @{ */
+#define SYSCON_SPIFICLKSEL_SEL_MASK              (0x7U)
+#define SYSCON_SPIFICLKSEL_SEL_SHIFT             (0U)
+/*! SEL - SPIFICLK clock source selection
+ *  0b000..CPU & System Bus clock
+ *  0b001..32 MHz crystal oscillator (XTAL)
+ *  0b010..No clock
+ *  0b011..No clock
+ *  0b100..No clock
+ *  0b101..No clock
+ *  0b110..No clock
+ *  0b111..No clock
+ */
+#define SYSCON_SPIFICLKSEL_SEL(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKSEL_SEL_SHIFT)) & SYSCON_SPIFICLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name ADCCLKSEL - ADC clock source select */
+/*! @{ */
+#define SYSCON_ADCCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_ADCCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - ADCCLK clock source selection
+ *  0b00..32 MHz crystal oscillator (XTAL)
+ *  0b01..FRO 12 MHz
+ *  0b11..No clock
+ */
+#define SYSCON_ADCCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKSEL_SEL_SHIFT)) & SYSCON_ADCCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name USARTCLKSEL - USART0 & 1 clock source select */
+/*! @{ */
+#define SYSCON_USARTCLKSEL_SEL_MASK              (0x3U)
+#define SYSCON_USARTCLKSEL_SEL_SHIFT             (0U)
+/*! SEL - USARTCLK (USART0 & 1) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b10..Fractional Rate Generator clock (see FRGCLKSEL)
+ *  0b11..No clock
+ */
+#define SYSCON_USARTCLKSEL_SEL(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_USARTCLKSEL_SEL_SHIFT)) & SYSCON_USARTCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name I2CCLKSEL - I2C0, 1 and 2 clock source select */
+/*! @{ */
+#define SYSCON_I2CCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_I2CCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - I2CCLK (I2C0 & 1) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b11..No clock
+ */
+#define SYSCON_I2CCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_I2CCLKSEL_SEL_SHIFT)) & SYSCON_I2CCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name SPICLKSEL - SPI0 & 1 clock source select */
+/*! @{ */
+#define SYSCON_SPICLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_SPICLKSEL_SEL_SHIFT               (0U)
+/*! SEL - SPICLK (SPI0 & 1) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b11..No clock
+ */
+#define SYSCON_SPICLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_SPICLKSEL_SEL_SHIFT)) & SYSCON_SPICLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name IRCLKSEL - Infra Red clock source select */
+/*! @{ */
+#define SYSCON_IRCLKSEL_SEL_MASK                 (0x3U)
+#define SYSCON_IRCLKSEL_SEL_SHIFT                (0U)
+/*! SEL - IRCLK (IR Blaster) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b11..No clock
+ */
+#define SYSCON_IRCLKSEL_SEL(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKSEL_SEL_SHIFT)) & SYSCON_IRCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name PWMCLKSEL - PWM clock source select */
+/*! @{ */
+#define SYSCON_PWMCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_PWMCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - PWMCLK (PWM) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..48 MHz free running oscillator (FRO)
+ *  0b11..No Clock
+ */
+#define SYSCON_PWMCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_PWMCLKSEL_SEL_SHIFT)) & SYSCON_PWMCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name WDTCLKSEL - Watchdog Timer clock source select */
+/*! @{ */
+#define SYSCON_WDTCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_WDTCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - WDTCLK (Watchdog Timer) clock source selection
+ *  0b00..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b01..Either 32 KHz FRO or 32 KHz XTAL (see OSC32CLKSEL)
+ *  0b10..1 MHz FRO
+ *  0b11..No Clock
+ */
+#define SYSCON_WDTCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKSEL_SEL_SHIFT)) & SYSCON_WDTCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name MODEMCLKSEL - Modem clock source select */
+/*! @{ */
+#define SYSCON_MODEMCLKSEL_SEL_ZIGBEE_MASK       (0x1U)
+#define SYSCON_MODEMCLKSEL_SEL_ZIGBEE_SHIFT      (0U)
+/*! SEL_ZIGBEE - Zigbee Modem clock source selection
+ *  0b0..32 MHz XTAL
+ *  0b1..No Clock
+ */
+#define SYSCON_MODEMCLKSEL_SEL_ZIGBEE(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCLKSEL_SEL_ZIGBEE_SHIFT)) & SYSCON_MODEMCLKSEL_SEL_ZIGBEE_MASK)
+#define SYSCON_MODEMCLKSEL_SEL_BLE_MASK          (0x2U)
+#define SYSCON_MODEMCLKSEL_SEL_BLE_SHIFT         (1U)
+/*! SEL_BLE - BLE 32 MHz clock source selection
+ *  0b0..32 MHz XTAL
+ *  0b1..No Clock
+ */
+#define SYSCON_MODEMCLKSEL_SEL_BLE(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCLKSEL_SEL_BLE_SHIFT)) & SYSCON_MODEMCLKSEL_SEL_BLE_MASK)
+/*! @} */
+
+/*! @name FRGCLKSEL - Fractional Rate Generator (FRG) clock source select. The FRG is one of the USART clocking options. */
+/*! @{ */
+#define SYSCON_FRGCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_FRGCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - Fractional Rate Generator clock source selection
+ *  0b00..System Bus clock
+ *  0b01..Either 32 MHz FRO or 32 MHz XTAL (see OSC32CLKSEL)
+ *  0b10..48 MHz free running oscillator (FRO)
+ *  0b11..No Clock
+ */
+#define SYSCON_FRGCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCLKSEL_SEL_SHIFT)) & SYSCON_FRGCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name DMICCLKSEL - Digital microphone (DMIC) subsystem clock select */
+/*! @{ */
+#define SYSCON_DMICCLKSEL_SEL_MASK               (0x7U)
+#define SYSCON_DMICCLKSEL_SEL_SHIFT              (0U)
+/*! SEL - DMIC clock source selection
+ *  0b000..System Bus clock
+ *  0b001..Either 32 KHz FRO or 32 KHz XTAL (see OSC32CLKSEL)
+ *  0b010..48 MHz free running oscillator (FRO)
+ *  0b011..External clock
+ *  0b100..1 MHz free running oscillator (FRO)
+ *  0b101..12 MHz free running oscillator (FRO)
+ *  0b111..No Clock
+ */
+#define SYSCON_DMICCLKSEL_SEL(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKSEL_SEL_SHIFT)) & SYSCON_DMICCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name WKTCLKSEL - Wake-up Timer clock select */
+/*! @{ */
+#define SYSCON_WKTCLKSEL_SEL_MASK                (0x3U)
+#define SYSCON_WKTCLKSEL_SEL_SHIFT               (0U)
+/*! SEL - Wake-up Timers clock source selection
+ *  0b00..Either 32 KHz FRO or 32 KHz XTAL (see OSC32CLKSEL)
+ *  0b11..No Clock
+ */
+#define SYSCON_WKTCLKSEL_SEL(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_WKTCLKSEL_SEL_SHIFT)) & SYSCON_WKTCLKSEL_SEL_MASK)
+/*! @} */
+
+/*! @name SYSTICKCLKDIV - SYSTICK clock divider. The SYSTICK clock can drive the SYSTICK function within the processor. */
+/*! @{ */
+#define SYSCON_SYSTICKCLKDIV_DIV_MASK            (0xFFU)
+#define SYSCON_SYSTICKCLKDIV_DIV_SHIFT           (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_SYSTICKCLKDIV_DIV(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_DIV_SHIFT)) & SYSCON_SYSTICKCLKDIV_DIV_MASK)
+#define SYSCON_SYSTICKCLKDIV_RESET_MASK          (0x20000000U)
+#define SYSCON_SYSTICKCLKDIV_RESET_SHIFT         (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_SYSTICKCLKDIV_RESET(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_RESET_SHIFT)) & SYSCON_SYSTICKCLKDIV_RESET_MASK)
+#define SYSCON_SYSTICKCLKDIV_HALT_MASK           (0x40000000U)
+#define SYSCON_SYSTICKCLKDIV_HALT_SHIFT          (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_SYSTICKCLKDIV_HALT(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_HALT_SHIFT)) & SYSCON_SYSTICKCLKDIV_HALT_MASK)
+#define SYSCON_SYSTICKCLKDIV_REQFLAG_MASK        (0x80000000U)
+#define SYSCON_SYSTICKCLKDIV_REQFLAG_SHIFT       (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_SYSTICKCLKDIV_REQFLAG(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_REQFLAG_SHIFT)) & SYSCON_SYSTICKCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name TRACECLKDIV - TRACE clock divider, used for part of the Serial debugger (SWD) feature. */
+/*! @{ */
+#define SYSCON_TRACECLKDIV_DIV_MASK              (0xFFU)
+#define SYSCON_TRACECLKDIV_DIV_SHIFT             (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_TRACECLKDIV_DIV(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_DIV_SHIFT)) & SYSCON_TRACECLKDIV_DIV_MASK)
+#define SYSCON_TRACECLKDIV_RESET_MASK            (0x20000000U)
+#define SYSCON_TRACECLKDIV_RESET_SHIFT           (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_TRACECLKDIV_RESET(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_RESET_SHIFT)) & SYSCON_TRACECLKDIV_RESET_MASK)
+#define SYSCON_TRACECLKDIV_HALT_MASK             (0x40000000U)
+#define SYSCON_TRACECLKDIV_HALT_SHIFT            (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_TRACECLKDIV_HALT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_HALT_SHIFT)) & SYSCON_TRACECLKDIV_HALT_MASK)
+#define SYSCON_TRACECLKDIV_REQFLAG_MASK          (0x80000000U)
+#define SYSCON_TRACECLKDIV_REQFLAG_SHIFT         (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_TRACECLKDIV_REQFLAG(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_REQFLAG_SHIFT)) & SYSCON_TRACECLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name WDTCLKDIV - Watchdog Timer clock divider */
+/*! @{ */
+#define SYSCON_WDTCLKDIV_DIV_MASK                (0xFFU)
+#define SYSCON_WDTCLKDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_WDTCLKDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKDIV_DIV_SHIFT)) & SYSCON_WDTCLKDIV_DIV_MASK)
+#define SYSCON_WDTCLKDIV_RESET_MASK              (0x20000000U)
+#define SYSCON_WDTCLKDIV_RESET_SHIFT             (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_WDTCLKDIV_RESET(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKDIV_RESET_SHIFT)) & SYSCON_WDTCLKDIV_RESET_MASK)
+#define SYSCON_WDTCLKDIV_HALT_MASK               (0x40000000U)
+#define SYSCON_WDTCLKDIV_HALT_SHIFT              (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_WDTCLKDIV_HALT(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKDIV_HALT_SHIFT)) & SYSCON_WDTCLKDIV_HALT_MASK)
+#define SYSCON_WDTCLKDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_WDTCLKDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_WDTCLKDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTCLKDIV_REQFLAG_SHIFT)) & SYSCON_WDTCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name IRCLKDIV - Infra Red clock divider */
+/*! @{ */
+#define SYSCON_IRCLKDIV_DIV_MASK                 (0xFU)
+#define SYSCON_IRCLKDIV_DIV_SHIFT                (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 15: Divide by 16.
+ */
+#define SYSCON_IRCLKDIV_DIV(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKDIV_DIV_SHIFT)) & SYSCON_IRCLKDIV_DIV_MASK)
+#define SYSCON_IRCLKDIV_RESET_MASK               (0x20000000U)
+#define SYSCON_IRCLKDIV_RESET_SHIFT              (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_IRCLKDIV_RESET(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKDIV_RESET_SHIFT)) & SYSCON_IRCLKDIV_RESET_MASK)
+#define SYSCON_IRCLKDIV_HALT_MASK                (0x40000000U)
+#define SYSCON_IRCLKDIV_HALT_SHIFT               (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_IRCLKDIV_HALT(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKDIV_HALT_SHIFT)) & SYSCON_IRCLKDIV_HALT_MASK)
+#define SYSCON_IRCLKDIV_REQFLAG_MASK             (0x80000000U)
+#define SYSCON_IRCLKDIV_REQFLAG_SHIFT            (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_IRCLKDIV_REQFLAG(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCLKDIV_REQFLAG_SHIFT)) & SYSCON_IRCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name AHBCLKDIV - System clock divider */
+/*! @{ */
+#define SYSCON_AHBCLKDIV_DIV_MASK                (0xFFU)
+#define SYSCON_AHBCLKDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_AHBCLKDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_DIV_SHIFT)) & SYSCON_AHBCLKDIV_DIV_MASK)
+#define SYSCON_AHBCLKDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_AHBCLKDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_AHBCLKDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_REQFLAG_SHIFT)) & SYSCON_AHBCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name CLKOUTDIV - CLKOUT clock divider */
+/*! @{ */
+#define SYSCON_CLKOUTDIV_DIV_MASK                (0xFU)
+#define SYSCON_CLKOUTDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 15: Divide by 16.
+ */
+#define SYSCON_CLKOUTDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_DIV_SHIFT)) & SYSCON_CLKOUTDIV_DIV_MASK)
+#define SYSCON_CLKOUTDIV_RESET_MASK              (0x20000000U)
+#define SYSCON_CLKOUTDIV_RESET_SHIFT             (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_CLKOUTDIV_RESET(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_RESET_SHIFT)) & SYSCON_CLKOUTDIV_RESET_MASK)
+#define SYSCON_CLKOUTDIV_HALT_MASK               (0x40000000U)
+#define SYSCON_CLKOUTDIV_HALT_SHIFT              (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_CLKOUTDIV_HALT(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_HALT_SHIFT)) & SYSCON_CLKOUTDIV_HALT_MASK)
+#define SYSCON_CLKOUTDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_CLKOUTDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_CLKOUTDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_REQFLAG_SHIFT)) & SYSCON_CLKOUTDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name SPIFICLKDIV - SPIFI clock divider */
+/*! @{ */
+#define SYSCON_SPIFICLKDIV_DIV_MASK              (0x3U)
+#define SYSCON_SPIFICLKDIV_DIV_SHIFT             (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 3: Divide by 4.
+ */
+#define SYSCON_SPIFICLKDIV_DIV(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_DIV_SHIFT)) & SYSCON_SPIFICLKDIV_DIV_MASK)
+#define SYSCON_SPIFICLKDIV_RESET_MASK            (0x20000000U)
+#define SYSCON_SPIFICLKDIV_RESET_SHIFT           (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_SPIFICLKDIV_RESET(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_RESET_SHIFT)) & SYSCON_SPIFICLKDIV_RESET_MASK)
+#define SYSCON_SPIFICLKDIV_HALT_MASK             (0x40000000U)
+#define SYSCON_SPIFICLKDIV_HALT_SHIFT            (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_SPIFICLKDIV_HALT(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_HALT_SHIFT)) & SYSCON_SPIFICLKDIV_HALT_MASK)
+#define SYSCON_SPIFICLKDIV_REQFLAG_MASK          (0x80000000U)
+#define SYSCON_SPIFICLKDIV_REQFLAG_SHIFT         (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_SPIFICLKDIV_REQFLAG(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_REQFLAG_SHIFT)) & SYSCON_SPIFICLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name ADCCLKDIV - ADC clock divider */
+/*! @{ */
+#define SYSCON_ADCCLKDIV_DIV_MASK                (0x7U)
+#define SYSCON_ADCCLKDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 7: Divide by 8.
+ */
+#define SYSCON_ADCCLKDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_DIV_SHIFT)) & SYSCON_ADCCLKDIV_DIV_MASK)
+#define SYSCON_ADCCLKDIV_RESET_MASK              (0x20000000U)
+#define SYSCON_ADCCLKDIV_RESET_SHIFT             (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_ADCCLKDIV_RESET(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_RESET_SHIFT)) & SYSCON_ADCCLKDIV_RESET_MASK)
+#define SYSCON_ADCCLKDIV_HALT_MASK               (0x40000000U)
+#define SYSCON_ADCCLKDIV_HALT_SHIFT              (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_ADCCLKDIV_HALT(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_HALT_SHIFT)) & SYSCON_ADCCLKDIV_HALT_MASK)
+#define SYSCON_ADCCLKDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_ADCCLKDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_ADCCLKDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_REQFLAG_SHIFT)) & SYSCON_ADCCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name RTCCLKDIV - Real Time Clock divider (1 KHz clock generation) */
+/*! @{ */
+#define SYSCON_RTCCLKDIV_DIV_MASK                (0x1FU)
+#define SYSCON_RTCCLKDIV_DIV_SHIFT               (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 31: Divide by 32.
+ */
+#define SYSCON_RTCCLKDIV_DIV(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCCLKDIV_DIV_SHIFT)) & SYSCON_RTCCLKDIV_DIV_MASK)
+#define SYSCON_RTCCLKDIV_RESET_MASK              (0x20000000U)
+#define SYSCON_RTCCLKDIV_RESET_SHIFT             (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_RTCCLKDIV_RESET(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCCLKDIV_RESET_SHIFT)) & SYSCON_RTCCLKDIV_RESET_MASK)
+#define SYSCON_RTCCLKDIV_HALT_MASK               (0x40000000U)
+#define SYSCON_RTCCLKDIV_HALT_SHIFT              (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_RTCCLKDIV_HALT(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCCLKDIV_HALT_SHIFT)) & SYSCON_RTCCLKDIV_HALT_MASK)
+#define SYSCON_RTCCLKDIV_REQFLAG_MASK            (0x80000000U)
+#define SYSCON_RTCCLKDIV_REQFLAG_SHIFT           (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_RTCCLKDIV_REQFLAG(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCCLKDIV_REQFLAG_SHIFT)) & SYSCON_RTCCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name FRGCTRL - Fractional rate generator divider. The FRG is one of the USART clocking options. */
+/*! @{ */
+#define SYSCON_FRGCTRL_DIV_MASK                  (0xFFU)
+#define SYSCON_FRGCTRL_DIV_SHIFT                 (0U)
+/*! DIV - Denominator of the fractional divider is equal to the (DIV+1). Always set to 0xFF to use
+ *    with the fractional baud rate generator : fout = fin / (1 + MULT/(DIV+1))
+ */
+#define SYSCON_FRGCTRL_DIV(x)                    (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCTRL_DIV_SHIFT)) & SYSCON_FRGCTRL_DIV_MASK)
+#define SYSCON_FRGCTRL_MULT_MASK                 (0xFF00U)
+#define SYSCON_FRGCTRL_MULT_SHIFT                (8U)
+/*! MULT - Numerator of the fractional divider. MULT is equal to the programmed value
+ */
+#define SYSCON_FRGCTRL_MULT(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCTRL_MULT_SHIFT)) & SYSCON_FRGCTRL_MULT_MASK)
+/*! @} */
+
+/*! @name DMICCLKDIV - DMIC clock divider */
+/*! @{ */
+#define SYSCON_DMICCLKDIV_DIV_MASK               (0xFFU)
+#define SYSCON_DMICCLKDIV_DIV_SHIFT              (0U)
+/*! DIV - Clock divider setting, divider ratio is (DIV+1). E.g. 0: Divide by 1 and 255: Divide by 256.
+ */
+#define SYSCON_DMICCLKDIV_DIV(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_DIV_SHIFT)) & SYSCON_DMICCLKDIV_DIV_MASK)
+#define SYSCON_DMICCLKDIV_RESET_MASK             (0x20000000U)
+#define SYSCON_DMICCLKDIV_RESET_SHIFT            (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_DMICCLKDIV_RESET(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_RESET_SHIFT)) & SYSCON_DMICCLKDIV_RESET_MASK)
+#define SYSCON_DMICCLKDIV_HALT_MASK              (0x40000000U)
+#define SYSCON_DMICCLKDIV_HALT_SHIFT             (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_DMICCLKDIV_HALT(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_HALT_SHIFT)) & SYSCON_DMICCLKDIV_HALT_MASK)
+#define SYSCON_DMICCLKDIV_REQFLAG_MASK           (0x80000000U)
+#define SYSCON_DMICCLKDIV_REQFLAG_SHIFT          (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_DMICCLKDIV_REQFLAG(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_REQFLAG_SHIFT)) & SYSCON_DMICCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name RTC1HZCLKDIV - Real Time Clock divider (1 Hz clock generation. The divider is fixed to 32768) */
+/*! @{ */
+#define SYSCON_RTC1HZCLKDIV_RESET_MASK           (0x20000000U)
+#define SYSCON_RTC1HZCLKDIV_RESET_SHIFT          (29U)
+/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right
+ *    away rather than completing the previous count.
+ */
+#define SYSCON_RTC1HZCLKDIV_RESET(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_RTC1HZCLKDIV_RESET_SHIFT)) & SYSCON_RTC1HZCLKDIV_RESET_MASK)
+#define SYSCON_RTC1HZCLKDIV_HALT_MASK            (0x40000000U)
+#define SYSCON_RTC1HZCLKDIV_HALT_SHIFT           (30U)
+/*! HALT - Halts the divider counter. The intent is to allow the divider s clock source to be
+ *    changed without the risk of a glitch at the output.
+ */
+#define SYSCON_RTC1HZCLKDIV_HALT(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_RTC1HZCLKDIV_HALT_SHIFT)) & SYSCON_RTC1HZCLKDIV_HALT_MASK)
+#define SYSCON_RTC1HZCLKDIV_REQFLAG_MASK         (0x80000000U)
+#define SYSCON_RTC1HZCLKDIV_REQFLAG_SHIFT        (31U)
+/*! REQFLAG - Divider status flag. Set when a change is made to the divider value, cleared when the change is complete.
+ */
+#define SYSCON_RTC1HZCLKDIV_REQFLAG(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_RTC1HZCLKDIV_REQFLAG_SHIFT)) & SYSCON_RTC1HZCLKDIV_REQFLAG_MASK)
+/*! @} */
+
+/*! @name CLOCKGENUPDATELOCKOUT - Control clock configuration registers access (like xxxDIV, xxxSEL) */
+/*! @{ */
+#define SYSCON_CLOCKGENUPDATELOCKOUT_LOCK_MASK   (0x1U)
+#define SYSCON_CLOCKGENUPDATELOCKOUT_LOCK_SHIFT  (0U)
+/*! LOCK - When set, disables access to clock control registers (like xxxDIV, xxxSEL). Affects all
+ *    clock control registers except OSC32CLKSEL.
+ */
+#define SYSCON_CLOCKGENUPDATELOCKOUT_LOCK(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_CLOCKGENUPDATELOCKOUT_LOCK_SHIFT)) & SYSCON_CLOCKGENUPDATELOCKOUT_LOCK_MASK)
+/*! @} */
+
+/*! @name RNGCLKCTRL - Random Number Generator Clocks control */
+/*! @{ */
+#define SYSCON_RNGCLKCTRL_ENABLE_MASK            (0x1U)
+#define SYSCON_RNGCLKCTRL_ENABLE_SHIFT           (0U)
+/*! ENABLE - Enable the clocks used by the Random Number Generator (RNG)
+ */
+#define SYSCON_RNGCLKCTRL_ENABLE(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_RNGCLKCTRL_ENABLE_SHIFT)) & SYSCON_RNGCLKCTRL_ENABLE_MASK)
+/*! @} */
+
+/*! @name SRAMCTRL - All SRAMs common control signals */
+/*! @{ */
+#define SYSCON_SRAMCTRL_SMB_MASK                 (0x3U)
+#define SYSCON_SRAMCTRL_SMB_SHIFT                (0U)
+/*! SMB - SMB
+ */
+#define SYSCON_SRAMCTRL_SMB(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_SRAMCTRL_SMB_SHIFT)) & SYSCON_SRAMCTRL_SMB_MASK)
+/*! @} */
+
+/*! @name MODEMCTRL - Modem (Bluetooth) control and 32K clock enable */
+/*! @{ */
+#define SYSCON_MODEMCTRL_BLE_LP_SLEEP_TRIG_MASK  (0x1U)
+#define SYSCON_MODEMCTRL_BLE_LP_SLEEP_TRIG_SHIFT (0U)
+/*! BLE_LP_SLEEP_TRIG - For normal operation leave at 0. If set to 1 will cause the load of register
+ *    in the BLE low power timing block, as if going into deep sleep. This is not needed for the
+ *    standard method to enter power down modes.
+ */
+#define SYSCON_MODEMCTRL_BLE_LP_SLEEP_TRIG(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_LP_SLEEP_TRIG_SHIFT)) & SYSCON_MODEMCTRL_BLE_LP_SLEEP_TRIG_MASK)
+#define SYSCON_MODEMCTRL_BLE_FREQ_SEL_MASK       (0x2U)
+#define SYSCON_MODEMCTRL_BLE_FREQ_SEL_SHIFT      (1U)
+/*! BLE_FREQ_SEL - For normal BLE operation set to 1. BLE operation with this bit set to 0 is not supported. 1 = 16 MHz ; 0 = 8 MHz
+ */
+#define SYSCON_MODEMCTRL_BLE_FREQ_SEL(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_FREQ_SEL_SHIFT)) & SYSCON_MODEMCTRL_BLE_FREQ_SEL_MASK)
+#define SYSCON_MODEMCTRL_BLE_DP_DIV_EN_MASK      (0x4U)
+#define SYSCON_MODEMCTRL_BLE_DP_DIV_EN_SHIFT     (2U)
+/*! BLE_DP_DIV_EN - For normal BLE operation set to 1. BLE operation with this bit set to 0 is not supported.
+ */
+#define SYSCON_MODEMCTRL_BLE_DP_DIV_EN(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_DP_DIV_EN_SHIFT)) & SYSCON_MODEMCTRL_BLE_DP_DIV_EN_MASK)
+#define SYSCON_MODEMCTRL_BLE_CLK32M_SEL_MASK     (0x8U)
+#define SYSCON_MODEMCTRL_BLE_CLK32M_SEL_SHIFT    (3U)
+/*! BLE_CLK32M_SEL - For normal BLE operation set to 0. BLE operation with this bit set to 1 is not supported.
+ */
+#define SYSCON_MODEMCTRL_BLE_CLK32M_SEL(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_CLK32M_SEL_SHIFT)) & SYSCON_MODEMCTRL_BLE_CLK32M_SEL_MASK)
+#define SYSCON_MODEMCTRL_BLE_AHB_DIV0_MASK       (0x10U)
+#define SYSCON_MODEMCTRL_BLE_AHB_DIV0_SHIFT      (4U)
+/*! BLE_AHB_DIV0 - For normal BLE operation set to 0. BLE operation with this bit set to 1 is not supported.
+ */
+#define SYSCON_MODEMCTRL_BLE_AHB_DIV0(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_AHB_DIV0_SHIFT)) & SYSCON_MODEMCTRL_BLE_AHB_DIV0_MASK)
+#define SYSCON_MODEMCTRL_BLE_AHB_DIV1_MASK       (0x20U)
+#define SYSCON_MODEMCTRL_BLE_AHB_DIV1_SHIFT      (5U)
+/*! BLE_AHB_DIV1 - For normal BLE operation set to 0. BLE operation with this bit set to 1 is not supported.
+ */
+#define SYSCON_MODEMCTRL_BLE_AHB_DIV1(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_AHB_DIV1_SHIFT)) & SYSCON_MODEMCTRL_BLE_AHB_DIV1_MASK)
+#define SYSCON_MODEMCTRL_BLE_HCLK_BLE_EN_MASK    (0x40U)
+#define SYSCON_MODEMCTRL_BLE_HCLK_BLE_EN_SHIFT   (6U)
+/*! BLE_HCLK_BLE_EN - For normal BLE operation set to 1 to enable the register interface clock
+ */
+#define SYSCON_MODEMCTRL_BLE_HCLK_BLE_EN(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_HCLK_BLE_EN_SHIFT)) & SYSCON_MODEMCTRL_BLE_HCLK_BLE_EN_MASK)
+#define SYSCON_MODEMCTRL_BLE_PHASE_MATCH_1_MASK  (0x80U)
+#define SYSCON_MODEMCTRL_BLE_PHASE_MATCH_1_SHIFT (7U)
+/*! BLE_PHASE_MATCH_1 - For normal BLE operation set to 0. BLE operation with this bit set to 1 is not supported.
+ */
+#define SYSCON_MODEMCTRL_BLE_PHASE_MATCH_1(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_PHASE_MATCH_1_SHIFT)) & SYSCON_MODEMCTRL_BLE_PHASE_MATCH_1_MASK)
+#define SYSCON_MODEMCTRL_BLE_ISO_ENABLE_MASK     (0x100U)
+#define SYSCON_MODEMCTRL_BLE_ISO_ENABLE_SHIFT    (8U)
+/*! BLE_ISO_ENABLE - Control isolation of BLE Low Power Control module. When the BLE low power
+ *    controller/timers is being used then the isolation must be enabled before entering power down
+ *    state. Must not be set before MODEMSTATUS.BLE_LL_CLK_STATUS is high ('1'). 0: isolation is
+ *    disabled. 1: isolation is enabled.
+ */
+#define SYSCON_MODEMCTRL_BLE_ISO_ENABLE(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_ISO_ENABLE_SHIFT)) & SYSCON_MODEMCTRL_BLE_ISO_ENABLE_MASK)
+#define SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN_MASK   (0x200U)
+#define SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN_SHIFT  (9U)
+/*! BLE_LP_OSC32K_EN - 1 = enable the 32K clock to the BLE Low power wake up counter, USART 0 & 1,
+ *    LSPI0 & 1, PMC and the frequency measure block
+ */
+#define SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN_SHIFT)) & SYSCON_MODEMCTRL_BLE_LP_OSC32K_EN_MASK)
+/*! @} */
+
+/*! @name MODEMSTATUS - Modem (Bluetooth) status */
+/*! @{ */
+#define SYSCON_MODEMSTATUS_BLE_LL_CLK_STATUS_MASK (0x1U)
+#define SYSCON_MODEMSTATUS_BLE_LL_CLK_STATUS_SHIFT (0U)
+/*! BLE_LL_CLK_STATUS - Status bit to indicate the clocking status from the link layer. 1 = BLE IP
+ *    in deep sleep using low power clock; 0 BLE IP active using 32M clocks
+ */
+#define SYSCON_MODEMSTATUS_BLE_LL_CLK_STATUS(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMSTATUS_BLE_LL_CLK_STATUS_SHIFT)) & SYSCON_MODEMSTATUS_BLE_LL_CLK_STATUS_MASK)
+#define SYSCON_MODEMSTATUS_BLE_LP_OSC_EN_MASK    (0x2U)
+#define SYSCON_MODEMSTATUS_BLE_LP_OSC_EN_SHIFT   (1U)
+/*! BLE_LP_OSC_EN - BLE low power timing block can be configured to start the wake-up sequence from
+ *    power down. This status bit indicates the value of that control bit.
+ */
+#define SYSCON_MODEMSTATUS_BLE_LP_OSC_EN(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMSTATUS_BLE_LP_OSC_EN_SHIFT)) & SYSCON_MODEMSTATUS_BLE_LP_OSC_EN_MASK)
+#define SYSCON_MODEMSTATUS_BLE_LP_RADIO_EN_MASK  (0x4U)
+#define SYSCON_MODEMSTATUS_BLE_LP_RADIO_EN_SHIFT (2U)
+/*! BLE_LP_RADIO_EN - BLE low power timing block can be configured to start the radio early; this is
+ *    not supoorted in this device. However, that control signal can be observed here.
+ */
+#define SYSCON_MODEMSTATUS_BLE_LP_RADIO_EN(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_MODEMSTATUS_BLE_LP_RADIO_EN_SHIFT)) & SYSCON_MODEMSTATUS_BLE_LP_RADIO_EN_MASK)
+/*! @} */
+
+/*! @name XTAL32KCAP - XTAL 32 KHz oscillator Capacitor control */
+/*! @{ */
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_MASK     (0x7FU)
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_SHIFT    (0U)
+/*! XO_OSC_CAP_IN - Internal Capacitor setting for XTAL_32K_P. This setting selects the internal
+ *    capacitance, to ground, that is connected to this XTAL pin. During device testing the capacitor
+ *    banks are calibrated so accurate setting of the capacitance can be achieved. Software function
+ *    are provided to support the setting of this register. Capacitance range is to apporximately
+ *    24pF.
+ */
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_IN(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_SHIFT)) & SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_MASK)
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_MASK    (0x3F80U)
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_SHIFT   (7U)
+/*! XO_OSC_CAP_OUT - Internal Capacitor setting for XTAL_32K_N. This setting selects the internal
+ *    capacitance, to ground, that is connected to this XTAL pin. During device testing the capacitor
+ *    banks are calibrated so accurate setting of the capacitance can be achieved. Software function
+ *    are provided to support the setting of this register. Capacitance range is to apporximately
+ *    24pF.
+ */
+#define SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_SHIFT)) & SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_MASK)
+/*! @} */
+
+/*! @name XTAL32MCTRL - XTAL 32 MHz oscillator control register */
+/*! @{ */
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL_MASK (0x1U)
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL_SHIFT (0U)
+/*! DEACTIVATE_PMC_CTRL - The 32MHz XTAL is enabled whenever the device is active due to internal
+ *    control signals from the PMC. This control bit can deactivate this. 0: Enable XTAL 32 MHz
+ *    controls coming from PMC. 1: Disable XTAL 32 MHz controls coming from PMC.
+ */
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL_SHIFT)) & SYSCON_XTAL32MCTRL_DEACTIVATE_PMC_CTRL_MASK)
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_BLE_CTRL_MASK (0x2U)
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_BLE_CTRL_SHIFT (1U)
+/*! DEACTIVATE_BLE_CTRL - In order to have XTAL ready for BLE after a low power cycle the XTAL must
+ *    be started early by the BLE low power module; this can be deactivated. 0: Enable XTAL 32 MHz
+ *    controls coming from BLE Low Power Control module. 1: Disable XTAL 32 MHz controls coming from
+ *    BLE Low Power Control module.
+ */
+#define SYSCON_XTAL32MCTRL_DEACTIVATE_BLE_CTRL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_XTAL32MCTRL_DEACTIVATE_BLE_CTRL_SHIFT)) & SYSCON_XTAL32MCTRL_DEACTIVATE_BLE_CTRL_MASK)
+/*! @} */
+
+/*! @name STARTER0 - Start logic 0 wake-up enable register. Enable an interrupt for wake-up from deep-sleep mode. Some bits can also control wake-up from powerdown mode */
+/*! @{ */
+#define SYSCON_STARTER0_WDT_BOD_MASK             (0x1U)
+#define SYSCON_STARTER0_WDT_BOD_SHIFT            (0U)
+/*! WDT_BOD - WWDT and BOD Interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_WDT_BOD(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_WDT_BOD_SHIFT)) & SYSCON_STARTER0_WDT_BOD_MASK)
+#define SYSCON_STARTER0_DMA_MASK                 (0x2U)
+#define SYSCON_STARTER0_DMA_SHIFT                (1U)
+/*! DMA - DMA Operation in Deep-Sleep and Powerdown not supported. Leave set to 0.
+ */
+#define SYSCON_STARTER0_DMA(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_DMA_SHIFT)) & SYSCON_STARTER0_DMA_MASK)
+#define SYSCON_STARTER0_GINT_MASK                (0x4U)
+#define SYSCON_STARTER0_GINT_SHIFT               (2U)
+/*! GINT - Group Interrupt 0 (GINT0) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_GINT(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_GINT_SHIFT)) & SYSCON_STARTER0_GINT_MASK)
+#define SYSCON_STARTER0_IRBLASTER_MASK           (0x8U)
+#define SYSCON_STARTER0_IRBLASTER_SHIFT          (3U)
+/*! IRBLASTER - Infra Red Blaster interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_IRBLASTER(x)             (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_IRBLASTER_SHIFT)) & SYSCON_STARTER0_IRBLASTER_MASK)
+#define SYSCON_STARTER0_PINT0_MASK               (0x10U)
+#define SYSCON_STARTER0_PINT0_SHIFT              (4U)
+/*! PINT0 - Pattern Interupt 0 (PINT0) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PINT0(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PINT0_SHIFT)) & SYSCON_STARTER0_PINT0_MASK)
+#define SYSCON_STARTER0_PINT1_MASK               (0x20U)
+#define SYSCON_STARTER0_PINT1_SHIFT              (5U)
+/*! PINT1 - Pattern Interupt 1 (PINT1) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PINT1(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PINT1_SHIFT)) & SYSCON_STARTER0_PINT1_MASK)
+#define SYSCON_STARTER0_PINT2_MASK               (0x40U)
+#define SYSCON_STARTER0_PINT2_SHIFT              (6U)
+/*! PINT2 - Pattern Interupt 2 (PINT2) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PINT2(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PINT2_SHIFT)) & SYSCON_STARTER0_PINT2_MASK)
+#define SYSCON_STARTER0_PINT3_MASK               (0x80U)
+#define SYSCON_STARTER0_PINT3_SHIFT              (7U)
+/*! PINT3 - Pattern Interupt 3 (PINT3) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PINT3(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PINT3_SHIFT)) & SYSCON_STARTER0_PINT3_MASK)
+#define SYSCON_STARTER0_SPIFI_MASK               (0x100U)
+#define SYSCON_STARTER0_SPIFI_SHIFT              (8U)
+/*! SPIFI - SPI Flash Interface (SPIFI) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_SPIFI(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_SPIFI_SHIFT)) & SYSCON_STARTER0_SPIFI_MASK)
+#define SYSCON_STARTER0_TIMER0_MASK              (0x200U)
+#define SYSCON_STARTER0_TIMER0_SHIFT             (9U)
+/*! TIMER0 - Counter/Timer0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_TIMER0(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_TIMER0_SHIFT)) & SYSCON_STARTER0_TIMER0_MASK)
+#define SYSCON_STARTER0_TIMER1_MASK              (0x400U)
+#define SYSCON_STARTER0_TIMER1_SHIFT             (10U)
+/*! TIMER1 - Counter/Timer1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_TIMER1(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_TIMER1_SHIFT)) & SYSCON_STARTER0_TIMER1_MASK)
+#define SYSCON_STARTER0_USART0_MASK              (0x800U)
+#define SYSCON_STARTER0_USART0_SHIFT             (11U)
+/*! USART0 - USART0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_USART0(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_USART0_SHIFT)) & SYSCON_STARTER0_USART0_MASK)
+#define SYSCON_STARTER0_USART1_MASK              (0x1000U)
+#define SYSCON_STARTER0_USART1_SHIFT             (12U)
+/*! USART1 - USART1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_USART1(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_USART1_SHIFT)) & SYSCON_STARTER0_USART1_MASK)
+#define SYSCON_STARTER0_I2C0_MASK                (0x2000U)
+#define SYSCON_STARTER0_I2C0_SHIFT               (13U)
+/*! I2C0 - I2C0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_I2C0(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_I2C0_SHIFT)) & SYSCON_STARTER0_I2C0_MASK)
+#define SYSCON_STARTER0_I2C1_MASK                (0x4000U)
+#define SYSCON_STARTER0_I2C1_SHIFT               (14U)
+/*! I2C1 - I2C1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_I2C1(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_I2C1_SHIFT)) & SYSCON_STARTER0_I2C1_MASK)
+#define SYSCON_STARTER0_SPI0_MASK                (0x8000U)
+#define SYSCON_STARTER0_SPI0_SHIFT               (15U)
+/*! SPI0 - SPI0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_SPI0(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_SPI0_SHIFT)) & SYSCON_STARTER0_SPI0_MASK)
+#define SYSCON_STARTER0_SPI1_MASK                (0x10000U)
+#define SYSCON_STARTER0_SPI1_SHIFT               (16U)
+/*! SPI1 - SPI1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_SPI1(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_SPI1_SHIFT)) & SYSCON_STARTER0_SPI1_MASK)
+#define SYSCON_STARTER0_PWM0_MASK                (0x20000U)
+#define SYSCON_STARTER0_PWM0_SHIFT               (17U)
+/*! PWM0 - PWM0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM0(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM0_SHIFT)) & SYSCON_STARTER0_PWM0_MASK)
+#define SYSCON_STARTER0_PWM1_MASK                (0x40000U)
+#define SYSCON_STARTER0_PWM1_SHIFT               (18U)
+/*! PWM1 - PWM1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM1(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM1_SHIFT)) & SYSCON_STARTER0_PWM1_MASK)
+#define SYSCON_STARTER0_PWM2_MASK                (0x80000U)
+#define SYSCON_STARTER0_PWM2_SHIFT               (19U)
+/*! PWM2 - PWM2 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM2(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM2_SHIFT)) & SYSCON_STARTER0_PWM2_MASK)
+#define SYSCON_STARTER0_PWM3_MASK                (0x100000U)
+#define SYSCON_STARTER0_PWM3_SHIFT               (20U)
+/*! PWM3 - PWM3 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM3(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM3_SHIFT)) & SYSCON_STARTER0_PWM3_MASK)
+#define SYSCON_STARTER0_PWM4_MASK                (0x200000U)
+#define SYSCON_STARTER0_PWM4_SHIFT               (21U)
+/*! PWM4 - PWM4 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM4(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM4_SHIFT)) & SYSCON_STARTER0_PWM4_MASK)
+#define SYSCON_STARTER0_PWM5_MASK                (0x400000U)
+#define SYSCON_STARTER0_PWM5_SHIFT               (22U)
+/*! PWM5 - PWM5 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM5(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM5_SHIFT)) & SYSCON_STARTER0_PWM5_MASK)
+#define SYSCON_STARTER0_PWM6_MASK                (0x800000U)
+#define SYSCON_STARTER0_PWM6_SHIFT               (23U)
+/*! PWM6 - PWM6 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM6(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM6_SHIFT)) & SYSCON_STARTER0_PWM6_MASK)
+#define SYSCON_STARTER0_PWM7_MASK                (0x1000000U)
+#define SYSCON_STARTER0_PWM7_SHIFT               (24U)
+/*! PWM7 - PWM7 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM7(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM7_SHIFT)) & SYSCON_STARTER0_PWM7_MASK)
+#define SYSCON_STARTER0_PWM8_MASK                (0x2000000U)
+#define SYSCON_STARTER0_PWM8_SHIFT               (25U)
+/*! PWM8 - PWM8 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM8(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM8_SHIFT)) & SYSCON_STARTER0_PWM8_MASK)
+#define SYSCON_STARTER0_PWM9_MASK                (0x4000000U)
+#define SYSCON_STARTER0_PWM9_SHIFT               (26U)
+/*! PWM9 - PWM9 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM9(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM9_SHIFT)) & SYSCON_STARTER0_PWM9_MASK)
+#define SYSCON_STARTER0_PWM10_MASK               (0x8000000U)
+#define SYSCON_STARTER0_PWM10_SHIFT              (27U)
+/*! PWM10 - PWM10 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_PWM10(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_PWM10_SHIFT)) & SYSCON_STARTER0_PWM10_MASK)
+#define SYSCON_STARTER0_I2C2_MASK                (0x10000000U)
+#define SYSCON_STARTER0_I2C2_SHIFT               (28U)
+/*! I2C2 - I2C2 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER0_I2C2(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_I2C2_SHIFT)) & SYSCON_STARTER0_I2C2_MASK)
+#define SYSCON_STARTER0_RTC_MASK                 (0x20000000U)
+#define SYSCON_STARTER0_RTC_SHIFT                (29U)
+/*! RTC - Real Time Clock (RTC) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER0_RTC(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_RTC_SHIFT)) & SYSCON_STARTER0_RTC_MASK)
+#define SYSCON_STARTER0_NFCTAG_MASK              (0x40000000U)
+#define SYSCON_STARTER0_NFCTAG_SHIFT             (30U)
+/*! NFCTAG - NFC Tag interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from
+ *    Deep-Sleep. Only supported on devices with internal NFC tag.
+ */
+#define SYSCON_STARTER0_NFCTAG(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER0_NFCTAG_SHIFT)) & SYSCON_STARTER0_NFCTAG_MASK)
+/*! @} */
+
+/*! @name STARTER1 - Start logic 1 wake-up enable register. Enable an interrupt for wake-up from deep-sleep mode. Some bits can also control wake-up from powerdown mode */
+/*! @{ */
+#define SYSCON_STARTER1_ADC_SEQA_MASK            (0x1U)
+#define SYSCON_STARTER1_ADC_SEQA_SHIFT           (0U)
+/*! ADC_SEQA - ADC Sequence A interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ADC_SEQA(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ADC_SEQA_SHIFT)) & SYSCON_STARTER1_ADC_SEQA_MASK)
+#define SYSCON_STARTER1_ADC_THCMP_OVR_MASK       (0x4U)
+#define SYSCON_STARTER1_ADC_THCMP_OVR_SHIFT      (2U)
+/*! ADC_THCMP_OVR - ADC threshold and error interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ADC_THCMP_OVR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ADC_THCMP_OVR_SHIFT)) & SYSCON_STARTER1_ADC_THCMP_OVR_MASK)
+#define SYSCON_STARTER1_DMIC_MASK                (0x8U)
+#define SYSCON_STARTER1_DMIC_SHIFT               (3U)
+/*! DMIC - Digital Microphone (DMIC) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_DMIC(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_DMIC_SHIFT)) & SYSCON_STARTER1_DMIC_MASK)
+#define SYSCON_STARTER1_HWVAD_MASK               (0x10U)
+#define SYSCON_STARTER1_HWVAD_SHIFT              (4U)
+/*! HWVAD - Hardware Voice Activity Detector (HWVAD) interrupt wake-up. 0 = Wake-up disabled. 1 =
+ *    Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_HWVAD(x)                 (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_HWVAD_SHIFT)) & SYSCON_STARTER1_HWVAD_MASK)
+#define SYSCON_STARTER1_BLE_DP_MASK              (0x20U)
+#define SYSCON_STARTER1_BLE_DP_SHIFT             (5U)
+/*! BLE_DP - BLE Datapath interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_BLE_DP(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_BLE_DP_SHIFT)) & SYSCON_STARTER1_BLE_DP_MASK)
+#define SYSCON_STARTER1_BLE_DP0_MASK             (0x40U)
+#define SYSCON_STARTER1_BLE_DP0_SHIFT            (6U)
+/*! BLE_DP0 - BLE Datapath 0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_BLE_DP0(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_BLE_DP0_SHIFT)) & SYSCON_STARTER1_BLE_DP0_MASK)
+#define SYSCON_STARTER1_BLE_DP1_MASK             (0x80U)
+#define SYSCON_STARTER1_BLE_DP1_SHIFT            (7U)
+/*! BLE_DP1 - BLE Datapath 1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_BLE_DP1(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_BLE_DP1_SHIFT)) & SYSCON_STARTER1_BLE_DP1_MASK)
+#define SYSCON_STARTER1_BLE_DP2_MASK             (0x100U)
+#define SYSCON_STARTER1_BLE_DP2_SHIFT            (8U)
+/*! BLE_DP2 - BLE Datapath 2 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_BLE_DP2(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_BLE_DP2_SHIFT)) & SYSCON_STARTER1_BLE_DP2_MASK)
+#define SYSCON_STARTER1_BLE_LL_ALL_MASK          (0x200U)
+#define SYSCON_STARTER1_BLE_LL_ALL_SHIFT         (9U)
+/*! BLE_LL_ALL - BLE Link Layer interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_BLE_LL_ALL(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_BLE_LL_ALL_SHIFT)) & SYSCON_STARTER1_BLE_LL_ALL_MASK)
+#define SYSCON_STARTER1_ZIGBEE_MAC_MASK          (0x400U)
+#define SYSCON_STARTER1_ZIGBEE_MAC_SHIFT         (10U)
+/*! ZIGBEE_MAC - Zigbee MAC interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ZIGBEE_MAC(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ZIGBEE_MAC_SHIFT)) & SYSCON_STARTER1_ZIGBEE_MAC_MASK)
+#define SYSCON_STARTER1_ZIGBEE_MODEM_MASK        (0x800U)
+#define SYSCON_STARTER1_ZIGBEE_MODEM_SHIFT       (11U)
+/*! ZIGBEE_MODEM - Zigbee Modem interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ZIGBEE_MODEM(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ZIGBEE_MODEM_SHIFT)) & SYSCON_STARTER1_ZIGBEE_MODEM_MASK)
+#define SYSCON_STARTER1_RFP_TMU_MASK             (0x1000U)
+#define SYSCON_STARTER1_RFP_TMU_SHIFT            (12U)
+/*! RFP_TMU - Radio Controller Timing Controller (RFP TMU) interrupt wake-up. 0 = Wake-up disabled.
+ *    1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_RFP_TMU(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_RFP_TMU_SHIFT)) & SYSCON_STARTER1_RFP_TMU_MASK)
+#define SYSCON_STARTER1_RFP_AGC_MASK             (0x2000U)
+#define SYSCON_STARTER1_RFP_AGC_SHIFT            (13U)
+/*! RFP_AGC - Radio Control AGC (RFP AGC) interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_RFP_AGC(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_RFP_AGC_SHIFT)) & SYSCON_STARTER1_RFP_AGC_MASK)
+#define SYSCON_STARTER1_ISO7816_MASK             (0x4000U)
+#define SYSCON_STARTER1_ISO7816_SHIFT            (14U)
+/*! ISO7816 - ISO7816 Smart Card interface interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep.
+ */
+#define SYSCON_STARTER1_ISO7816(x)               (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ISO7816_SHIFT)) & SYSCON_STARTER1_ISO7816_MASK)
+#define SYSCON_STARTER1_ANA_COMP_MASK            (0x8000U)
+#define SYSCON_STARTER1_ANA_COMP_SHIFT           (15U)
+/*! ANA_COMP - Analog Comparator interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER1_ANA_COMP(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_ANA_COMP_SHIFT)) & SYSCON_STARTER1_ANA_COMP_MASK)
+#define SYSCON_STARTER1_WAKE_UP_TIMER0_MASK      (0x10000U)
+#define SYSCON_STARTER1_WAKE_UP_TIMER0_SHIFT     (16U)
+/*! WAKE_UP_TIMER0 - Wake-up Timer0 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER1_WAKE_UP_TIMER0(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_WAKE_UP_TIMER0_SHIFT)) & SYSCON_STARTER1_WAKE_UP_TIMER0_MASK)
+#define SYSCON_STARTER1_WAKE_UP_TIMER1_MASK      (0x20000U)
+#define SYSCON_STARTER1_WAKE_UP_TIMER1_SHIFT     (17U)
+/*! WAKE_UP_TIMER1 - Wake-up Timer1 interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER1_WAKE_UP_TIMER1(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_WAKE_UP_TIMER1_SHIFT)) & SYSCON_STARTER1_WAKE_UP_TIMER1_MASK)
+#define SYSCON_STARTER1_BLE_WAKE_UP_TIMER_MASK   (0x400000U)
+#define SYSCON_STARTER1_BLE_WAKE_UP_TIMER_SHIFT  (22U)
+/*! BLE_WAKE_UP_TIMER - BLE Wake-up Timer interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Valid from Deep-Sleep and Powerdown.
+ */
+#define SYSCON_STARTER1_BLE_WAKE_UP_TIMER(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_BLE_WAKE_UP_TIMER_SHIFT)) & SYSCON_STARTER1_BLE_WAKE_UP_TIMER_MASK)
+#define SYSCON_STARTER1_BLE_OSC_EN_MASK          (0x800000U)
+#define SYSCON_STARTER1_BLE_OSC_EN_SHIFT         (23U)
+/*! BLE_OSC_EN - BLE Oscillator Enable interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled.
+ *    Valid from Deep-Sleep and Powerdown. Used as early wake-up trigger to allow 32M XTAL to be
+ *    started and ready for BLE timeslot
+ */
+#define SYSCON_STARTER1_BLE_OSC_EN(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_BLE_OSC_EN_SHIFT)) & SYSCON_STARTER1_BLE_OSC_EN_MASK)
+#define SYSCON_STARTER1_GPIO_MASK                (0x80000000U)
+#define SYSCON_STARTER1_GPIO_SHIFT               (31U)
+/*! GPIO - GPIO interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Set this bit to allow
+ *    GPIO or NTAG_INT to cause a wake-up in Deep-Sleep and Power-down mode.
+ */
+#define SYSCON_STARTER1_GPIO(x)                  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER1_GPIO_SHIFT)) & SYSCON_STARTER1_GPIO_MASK)
+/*! @} */
+
+/*! @name STARTERX_STARTERS - Pin assign register */
+/*! @{ */
+#define SYSCON_STARTERX_STARTERS_DATA_MASK       (0xFFFFFFFFU)
+#define SYSCON_STARTERX_STARTERS_DATA_SHIFT      (0U)
+#define SYSCON_STARTERX_STARTERS_DATA(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERX_STARTERS_DATA_SHIFT)) & SYSCON_STARTERX_STARTERS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_STARTERX_STARTERS */
+#define SYSCON_STARTERX_STARTERS_COUNT           (2U)
+
+/*! @name STARTERSET0 - Set bits in STARTER0 */
+/*! @{ */
+#define SYSCON_STARTERSET0_WDT_BOD_SET_MASK      (0x1U)
+#define SYSCON_STARTERSET0_WDT_BOD_SET_SHIFT     (0U)
+/*! WDT_BOD_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_WDT_BOD_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_WDT_BOD_SET_SHIFT)) & SYSCON_STARTERSET0_WDT_BOD_SET_MASK)
+#define SYSCON_STARTERSET0_DMA_SET_MASK          (0x2U)
+#define SYSCON_STARTERSET0_DMA_SET_SHIFT         (1U)
+/*! DMA_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_DMA_SET(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_DMA_SET_SHIFT)) & SYSCON_STARTERSET0_DMA_SET_MASK)
+#define SYSCON_STARTERSET0_GINT_SET_MASK         (0x4U)
+#define SYSCON_STARTERSET0_GINT_SET_SHIFT        (2U)
+/*! GINT_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_GINT_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_GINT_SET_SHIFT)) & SYSCON_STARTERSET0_GINT_SET_MASK)
+#define SYSCON_STARTERSET0_IRBLASTER_SET_MASK    (0x8U)
+#define SYSCON_STARTERSET0_IRBLASTER_SET_SHIFT   (3U)
+/*! IRBLASTER_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_IRBLASTER_SET(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_IRBLASTER_SET_SHIFT)) & SYSCON_STARTERSET0_IRBLASTER_SET_MASK)
+#define SYSCON_STARTERSET0_PINT0_SET_MASK        (0x10U)
+#define SYSCON_STARTERSET0_PINT0_SET_SHIFT       (4U)
+/*! PINT0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PINT0_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PINT0_SET_SHIFT)) & SYSCON_STARTERSET0_PINT0_SET_MASK)
+#define SYSCON_STARTERSET0_PINT1_SET_MASK        (0x20U)
+#define SYSCON_STARTERSET0_PINT1_SET_SHIFT       (5U)
+/*! PINT1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PINT1_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PINT1_SET_SHIFT)) & SYSCON_STARTERSET0_PINT1_SET_MASK)
+#define SYSCON_STARTERSET0_PINT2_SET_MASK        (0x40U)
+#define SYSCON_STARTERSET0_PINT2_SET_SHIFT       (6U)
+/*! PINT2_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PINT2_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PINT2_SET_SHIFT)) & SYSCON_STARTERSET0_PINT2_SET_MASK)
+#define SYSCON_STARTERSET0_PINT3_SET_MASK        (0x80U)
+#define SYSCON_STARTERSET0_PINT3_SET_SHIFT       (7U)
+/*! PINT3_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PINT3_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PINT3_SET_SHIFT)) & SYSCON_STARTERSET0_PINT3_SET_MASK)
+#define SYSCON_STARTERSET0_SPIFI_SET_MASK        (0x100U)
+#define SYSCON_STARTERSET0_SPIFI_SET_SHIFT       (8U)
+/*! SPIFI_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_SPIFI_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_SPIFI_SET_SHIFT)) & SYSCON_STARTERSET0_SPIFI_SET_MASK)
+#define SYSCON_STARTERSET0_TIMER0_SET_MASK       (0x200U)
+#define SYSCON_STARTERSET0_TIMER0_SET_SHIFT      (9U)
+/*! TIMER0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_TIMER0_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_TIMER0_SET_SHIFT)) & SYSCON_STARTERSET0_TIMER0_SET_MASK)
+#define SYSCON_STARTERSET0_TIMER1_SET_MASK       (0x400U)
+#define SYSCON_STARTERSET0_TIMER1_SET_SHIFT      (10U)
+/*! TIMER1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_TIMER1_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_TIMER1_SET_SHIFT)) & SYSCON_STARTERSET0_TIMER1_SET_MASK)
+#define SYSCON_STARTERSET0_USART0_SET_MASK       (0x800U)
+#define SYSCON_STARTERSET0_USART0_SET_SHIFT      (11U)
+/*! USART0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_USART0_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_USART0_SET_SHIFT)) & SYSCON_STARTERSET0_USART0_SET_MASK)
+#define SYSCON_STARTERSET0_USART1_SET_MASK       (0x1000U)
+#define SYSCON_STARTERSET0_USART1_SET_SHIFT      (12U)
+/*! USART1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_USART1_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_USART1_SET_SHIFT)) & SYSCON_STARTERSET0_USART1_SET_MASK)
+#define SYSCON_STARTERSET0_I2C0_SET_MASK         (0x2000U)
+#define SYSCON_STARTERSET0_I2C0_SET_SHIFT        (13U)
+/*! I2C0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_I2C0_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_I2C0_SET_SHIFT)) & SYSCON_STARTERSET0_I2C0_SET_MASK)
+#define SYSCON_STARTERSET0_I2C1_SET_MASK         (0x4000U)
+#define SYSCON_STARTERSET0_I2C1_SET_SHIFT        (14U)
+/*! I2C1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_I2C1_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_I2C1_SET_SHIFT)) & SYSCON_STARTERSET0_I2C1_SET_MASK)
+#define SYSCON_STARTERSET0_SPI0_SET_MASK         (0x8000U)
+#define SYSCON_STARTERSET0_SPI0_SET_SHIFT        (15U)
+/*! SPI0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_SPI0_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_SPI0_SET_SHIFT)) & SYSCON_STARTERSET0_SPI0_SET_MASK)
+#define SYSCON_STARTERSET0_SPI1_SET_MASK         (0x10000U)
+#define SYSCON_STARTERSET0_SPI1_SET_SHIFT        (16U)
+/*! SPI1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_SPI1_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_SPI1_SET_SHIFT)) & SYSCON_STARTERSET0_SPI1_SET_MASK)
+#define SYSCON_STARTERSET0_PWM0_SET_MASK         (0x20000U)
+#define SYSCON_STARTERSET0_PWM0_SET_SHIFT        (17U)
+/*! PWM0_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM0_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM0_SET_SHIFT)) & SYSCON_STARTERSET0_PWM0_SET_MASK)
+#define SYSCON_STARTERSET0_PWM1_SET_MASK         (0x40000U)
+#define SYSCON_STARTERSET0_PWM1_SET_SHIFT        (18U)
+/*! PWM1_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM1_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM1_SET_SHIFT)) & SYSCON_STARTERSET0_PWM1_SET_MASK)
+#define SYSCON_STARTERSET0_PWM2_SET_MASK         (0x80000U)
+#define SYSCON_STARTERSET0_PWM2_SET_SHIFT        (19U)
+/*! PWM2_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM2_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM2_SET_SHIFT)) & SYSCON_STARTERSET0_PWM2_SET_MASK)
+#define SYSCON_STARTERSET0_PWM3_SET_MASK         (0x100000U)
+#define SYSCON_STARTERSET0_PWM3_SET_SHIFT        (20U)
+/*! PWM3_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM3_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM3_SET_SHIFT)) & SYSCON_STARTERSET0_PWM3_SET_MASK)
+#define SYSCON_STARTERSET0_PWM4_SET_MASK         (0x200000U)
+#define SYSCON_STARTERSET0_PWM4_SET_SHIFT        (21U)
+/*! PWM4_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM4_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM4_SET_SHIFT)) & SYSCON_STARTERSET0_PWM4_SET_MASK)
+#define SYSCON_STARTERSET0_PWM5_SET_MASK         (0x400000U)
+#define SYSCON_STARTERSET0_PWM5_SET_SHIFT        (22U)
+/*! PWM5_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM5_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM5_SET_SHIFT)) & SYSCON_STARTERSET0_PWM5_SET_MASK)
+#define SYSCON_STARTERSET0_PWM6_SET_MASK         (0x800000U)
+#define SYSCON_STARTERSET0_PWM6_SET_SHIFT        (23U)
+/*! PWM6_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM6_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM6_SET_SHIFT)) & SYSCON_STARTERSET0_PWM6_SET_MASK)
+#define SYSCON_STARTERSET0_PWM7_SET_MASK         (0x1000000U)
+#define SYSCON_STARTERSET0_PWM7_SET_SHIFT        (24U)
+/*! PWM7_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM7_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM7_SET_SHIFT)) & SYSCON_STARTERSET0_PWM7_SET_MASK)
+#define SYSCON_STARTERSET0_PWM8_SET_MASK         (0x2000000U)
+#define SYSCON_STARTERSET0_PWM8_SET_SHIFT        (25U)
+/*! PWM8_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM8_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM8_SET_SHIFT)) & SYSCON_STARTERSET0_PWM8_SET_MASK)
+#define SYSCON_STARTERSET0_PWM9_SET_MASK         (0x4000000U)
+#define SYSCON_STARTERSET0_PWM9_SET_SHIFT        (26U)
+/*! PWM9_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM9_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM9_SET_SHIFT)) & SYSCON_STARTERSET0_PWM9_SET_MASK)
+#define SYSCON_STARTERSET0_PWM10_SET_MASK        (0x8000000U)
+#define SYSCON_STARTERSET0_PWM10_SET_SHIFT       (27U)
+/*! PWM10_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_PWM10_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_PWM10_SET_SHIFT)) & SYSCON_STARTERSET0_PWM10_SET_MASK)
+#define SYSCON_STARTERSET0_I2C2_SET_MASK         (0x10000000U)
+#define SYSCON_STARTERSET0_I2C2_SET_SHIFT        (28U)
+/*! I2C2_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_I2C2_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_I2C2_SET_SHIFT)) & SYSCON_STARTERSET0_I2C2_SET_MASK)
+#define SYSCON_STARTERSET0_RTC_SET_MASK          (0x20000000U)
+#define SYSCON_STARTERSET0_RTC_SET_SHIFT         (29U)
+/*! RTC_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_RTC_SET(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_RTC_SET_SHIFT)) & SYSCON_STARTERSET0_RTC_SET_MASK)
+#define SYSCON_STARTERSET0_NFCTAG_SET_MASK       (0x40000000U)
+#define SYSCON_STARTERSET0_NFCTAG_SET_SHIFT      (30U)
+/*! NFCTAG_SET - Writing one to this bit sets the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERSET0_NFCTAG_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET0_NFCTAG_SET_SHIFT)) & SYSCON_STARTERSET0_NFCTAG_SET_MASK)
+/*! @} */
+
+/*! @name STARTERSET1 - Set bits in STARTER1 */
+/*! @{ */
+#define SYSCON_STARTERSET1_ADC_SEQA_SET_MASK     (0x1U)
+#define SYSCON_STARTERSET1_ADC_SEQA_SET_SHIFT    (0U)
+/*! ADC_SEQA_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ADC_SEQA_SET(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ADC_SEQA_SET_SHIFT)) & SYSCON_STARTERSET1_ADC_SEQA_SET_MASK)
+#define SYSCON_STARTERSET1_ADC_THCMP_OVR_SET_MASK (0x4U)
+#define SYSCON_STARTERSET1_ADC_THCMP_OVR_SET_SHIFT (2U)
+/*! ADC_THCMP_OVR_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ADC_THCMP_OVR_SET(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ADC_THCMP_OVR_SET_SHIFT)) & SYSCON_STARTERSET1_ADC_THCMP_OVR_SET_MASK)
+#define SYSCON_STARTERSET1_DMIC_SET_MASK         (0x8U)
+#define SYSCON_STARTERSET1_DMIC_SET_SHIFT        (3U)
+/*! DMIC_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_DMIC_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_DMIC_SET_SHIFT)) & SYSCON_STARTERSET1_DMIC_SET_MASK)
+#define SYSCON_STARTERSET1_HWVAD_SET_MASK        (0x10U)
+#define SYSCON_STARTERSET1_HWVAD_SET_SHIFT       (4U)
+/*! HWVAD_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_HWVAD_SET(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_HWVAD_SET_SHIFT)) & SYSCON_STARTERSET1_HWVAD_SET_MASK)
+#define SYSCON_STARTERSET1_BLE_DP_SET_MASK       (0x20U)
+#define SYSCON_STARTERSET1_BLE_DP_SET_SHIFT      (5U)
+/*! BLE_DP_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_BLE_DP_SET(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_BLE_DP_SET_SHIFT)) & SYSCON_STARTERSET1_BLE_DP_SET_MASK)
+#define SYSCON_STARTERSET1_BLE_DP0_SET_MASK      (0x40U)
+#define SYSCON_STARTERSET1_BLE_DP0_SET_SHIFT     (6U)
+/*! BLE_DP0_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_BLE_DP0_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_BLE_DP0_SET_SHIFT)) & SYSCON_STARTERSET1_BLE_DP0_SET_MASK)
+#define SYSCON_STARTERSET1_BLE_DP1_SET_MASK      (0x80U)
+#define SYSCON_STARTERSET1_BLE_DP1_SET_SHIFT     (7U)
+/*! BLE_DP1_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_BLE_DP1_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_BLE_DP1_SET_SHIFT)) & SYSCON_STARTERSET1_BLE_DP1_SET_MASK)
+#define SYSCON_STARTERSET1_BLE_DP2_SET_MASK      (0x100U)
+#define SYSCON_STARTERSET1_BLE_DP2_SET_SHIFT     (8U)
+/*! BLE_DP2_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_BLE_DP2_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_BLE_DP2_SET_SHIFT)) & SYSCON_STARTERSET1_BLE_DP2_SET_MASK)
+#define SYSCON_STARTERSET1_BLE_LL_ALL_SET_MASK   (0x200U)
+#define SYSCON_STARTERSET1_BLE_LL_ALL_SET_SHIFT  (9U)
+/*! BLE_LL_ALL_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_BLE_LL_ALL_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_BLE_LL_ALL_SET_SHIFT)) & SYSCON_STARTERSET1_BLE_LL_ALL_SET_MASK)
+#define SYSCON_STARTERSET1_ZIGBEE_MAC_SET_MASK   (0x400U)
+#define SYSCON_STARTERSET1_ZIGBEE_MAC_SET_SHIFT  (10U)
+/*! ZIGBEE_MAC_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ZIGBEE_MAC_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ZIGBEE_MAC_SET_SHIFT)) & SYSCON_STARTERSET1_ZIGBEE_MAC_SET_MASK)
+#define SYSCON_STARTERSET1_ZIGBEE_MODEM_SET_MASK (0x800U)
+#define SYSCON_STARTERSET1_ZIGBEE_MODEM_SET_SHIFT (11U)
+/*! ZIGBEE_MODEM_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ZIGBEE_MODEM_SET(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ZIGBEE_MODEM_SET_SHIFT)) & SYSCON_STARTERSET1_ZIGBEE_MODEM_SET_MASK)
+#define SYSCON_STARTERSET1_RFP_TMU_SET_MASK      (0x1000U)
+#define SYSCON_STARTERSET1_RFP_TMU_SET_SHIFT     (12U)
+/*! RFP_TMU_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_RFP_TMU_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_RFP_TMU_SET_SHIFT)) & SYSCON_STARTERSET1_RFP_TMU_SET_MASK)
+#define SYSCON_STARTERSET1_RFP_AGC_SET_MASK      (0x2000U)
+#define SYSCON_STARTERSET1_RFP_AGC_SET_SHIFT     (13U)
+/*! RFP_AGC_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_RFP_AGC_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_RFP_AGC_SET_SHIFT)) & SYSCON_STARTERSET1_RFP_AGC_SET_MASK)
+#define SYSCON_STARTERSET1_ISO7816_SET_MASK      (0x4000U)
+#define SYSCON_STARTERSET1_ISO7816_SET_SHIFT     (14U)
+/*! ISO7816_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ISO7816_SET(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ISO7816_SET_SHIFT)) & SYSCON_STARTERSET1_ISO7816_SET_MASK)
+#define SYSCON_STARTERSET1_ANA_COMP_SET_MASK     (0x8000U)
+#define SYSCON_STARTERSET1_ANA_COMP_SET_SHIFT    (15U)
+/*! ANA_COMP_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_ANA_COMP_SET(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_ANA_COMP_SET_SHIFT)) & SYSCON_STARTERSET1_ANA_COMP_SET_MASK)
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET_MASK (0x10000U)
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET_SHIFT (16U)
+/*! WAKE_UP_TIMER0_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET_SHIFT)) & SYSCON_STARTERSET1_WAKE_UP_TIMER0_SET_MASK)
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET_MASK (0x20000U)
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET_SHIFT (17U)
+/*! WAKE_UP_TIMER1_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET_SHIFT)) & SYSCON_STARTERSET1_WAKE_UP_TIMER1_SET_MASK)
+#define SYSCON_STARTERSET1_BLE_WAKE_UP_TIMER_SET_MASK (0x400000U)
+#define SYSCON_STARTERSET1_BLE_WAKE_UP_TIMER_SET_SHIFT (22U)
+/*! BLE_WAKE_UP_TIMER_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_BLE_WAKE_UP_TIMER_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_BLE_WAKE_UP_TIMER_SET_SHIFT)) & SYSCON_STARTERSET1_BLE_WAKE_UP_TIMER_SET_MASK)
+#define SYSCON_STARTERSET1_BLE_OSC_EN_SET_MASK   (0x800000U)
+#define SYSCON_STARTERSET1_BLE_OSC_EN_SET_SHIFT  (23U)
+/*! BLE_OSC_EN_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_BLE_OSC_EN_SET(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_BLE_OSC_EN_SET_SHIFT)) & SYSCON_STARTERSET1_BLE_OSC_EN_SET_MASK)
+#define SYSCON_STARTERSET1_GPIO_SET_MASK         (0x80000000U)
+#define SYSCON_STARTERSET1_GPIO_SET_SHIFT        (31U)
+/*! GPIO_SET - Writing one to this bit sets the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERSET1_GPIO_SET(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET1_GPIO_SET_SHIFT)) & SYSCON_STARTERSET1_GPIO_SET_MASK)
+/*! @} */
+
+/*! @name STARTERSETX_STARTERSETS - Pin assign register */
+/*! @{ */
+#define SYSCON_STARTERSETX_STARTERSETS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_STARTERSETX_STARTERSETS_DATA_SHIFT (0U)
+#define SYSCON_STARTERSETX_STARTERSETS_DATA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSETX_STARTERSETS_DATA_SHIFT)) & SYSCON_STARTERSETX_STARTERSETS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_STARTERSETX_STARTERSETS */
+#define SYSCON_STARTERSETX_STARTERSETS_COUNT     (2U)
+
+/*! @name STARTERCLR0 - Clear bits in STARTER0 */
+/*! @{ */
+#define SYSCON_STARTERCLR0_WDT_BOD_CLR_MASK      (0x1U)
+#define SYSCON_STARTERCLR0_WDT_BOD_CLR_SHIFT     (0U)
+/*! WDT_BOD_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_WDT_BOD_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_WDT_BOD_CLR_SHIFT)) & SYSCON_STARTERCLR0_WDT_BOD_CLR_MASK)
+#define SYSCON_STARTERCLR0_DMA_CLR_MASK          (0x2U)
+#define SYSCON_STARTERCLR0_DMA_CLR_SHIFT         (1U)
+/*! DMA_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_DMA_CLR(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_DMA_CLR_SHIFT)) & SYSCON_STARTERCLR0_DMA_CLR_MASK)
+#define SYSCON_STARTERCLR0_GINT_CLR_MASK         (0x4U)
+#define SYSCON_STARTERCLR0_GINT_CLR_SHIFT        (2U)
+/*! GINT_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_GINT_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_GINT_CLR_SHIFT)) & SYSCON_STARTERCLR0_GINT_CLR_MASK)
+#define SYSCON_STARTERCLR0_IRBLASTER_CLR_MASK    (0x8U)
+#define SYSCON_STARTERCLR0_IRBLASTER_CLR_SHIFT   (3U)
+/*! IRBLASTER_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_IRBLASTER_CLR(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_IRBLASTER_CLR_SHIFT)) & SYSCON_STARTERCLR0_IRBLASTER_CLR_MASK)
+#define SYSCON_STARTERCLR0_PINT0_CLR_MASK        (0x10U)
+#define SYSCON_STARTERCLR0_PINT0_CLR_SHIFT       (4U)
+/*! PINT0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PINT0_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PINT0_CLR_SHIFT)) & SYSCON_STARTERCLR0_PINT0_CLR_MASK)
+#define SYSCON_STARTERCLR0_PINT1_CLR_MASK        (0x20U)
+#define SYSCON_STARTERCLR0_PINT1_CLR_SHIFT       (5U)
+/*! PINT1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PINT1_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PINT1_CLR_SHIFT)) & SYSCON_STARTERCLR0_PINT1_CLR_MASK)
+#define SYSCON_STARTERCLR0_PINT2_CLR_MASK        (0x40U)
+#define SYSCON_STARTERCLR0_PINT2_CLR_SHIFT       (6U)
+/*! PINT2_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PINT2_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PINT2_CLR_SHIFT)) & SYSCON_STARTERCLR0_PINT2_CLR_MASK)
+#define SYSCON_STARTERCLR0_PINT3_CLR_MASK        (0x80U)
+#define SYSCON_STARTERCLR0_PINT3_CLR_SHIFT       (7U)
+/*! PINT3_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PINT3_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PINT3_CLR_SHIFT)) & SYSCON_STARTERCLR0_PINT3_CLR_MASK)
+#define SYSCON_STARTERCLR0_SPIFI_CLR_MASK        (0x100U)
+#define SYSCON_STARTERCLR0_SPIFI_CLR_SHIFT       (8U)
+/*! SPIFI_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_SPIFI_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_SPIFI_CLR_SHIFT)) & SYSCON_STARTERCLR0_SPIFI_CLR_MASK)
+#define SYSCON_STARTERCLR0_TIMER0_CLR_MASK       (0x200U)
+#define SYSCON_STARTERCLR0_TIMER0_CLR_SHIFT      (9U)
+/*! TIMER0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_TIMER0_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_TIMER0_CLR_SHIFT)) & SYSCON_STARTERCLR0_TIMER0_CLR_MASK)
+#define SYSCON_STARTERCLR0_TIMER1_CLR_MASK       (0x400U)
+#define SYSCON_STARTERCLR0_TIMER1_CLR_SHIFT      (10U)
+/*! TIMER1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_TIMER1_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_TIMER1_CLR_SHIFT)) & SYSCON_STARTERCLR0_TIMER1_CLR_MASK)
+#define SYSCON_STARTERCLR0_USART0_CLR_MASK       (0x800U)
+#define SYSCON_STARTERCLR0_USART0_CLR_SHIFT      (11U)
+/*! USART0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_USART0_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_USART0_CLR_SHIFT)) & SYSCON_STARTERCLR0_USART0_CLR_MASK)
+#define SYSCON_STARTERCLR0_USART1_CLR_MASK       (0x1000U)
+#define SYSCON_STARTERCLR0_USART1_CLR_SHIFT      (12U)
+/*! USART1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_USART1_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_USART1_CLR_SHIFT)) & SYSCON_STARTERCLR0_USART1_CLR_MASK)
+#define SYSCON_STARTERCLR0_I2C0_CLR_MASK         (0x2000U)
+#define SYSCON_STARTERCLR0_I2C0_CLR_SHIFT        (13U)
+/*! I2C0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_I2C0_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_I2C0_CLR_SHIFT)) & SYSCON_STARTERCLR0_I2C0_CLR_MASK)
+#define SYSCON_STARTERCLR0_I2C1_CLR_MASK         (0x4000U)
+#define SYSCON_STARTERCLR0_I2C1_CLR_SHIFT        (14U)
+/*! I2C1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_I2C1_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_I2C1_CLR_SHIFT)) & SYSCON_STARTERCLR0_I2C1_CLR_MASK)
+#define SYSCON_STARTERCLR0_SPI0_CLR_MASK         (0x8000U)
+#define SYSCON_STARTERCLR0_SPI0_CLR_SHIFT        (15U)
+/*! SPI0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_SPI0_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_SPI0_CLR_SHIFT)) & SYSCON_STARTERCLR0_SPI0_CLR_MASK)
+#define SYSCON_STARTERCLR0_SPI1_CLR_MASK         (0x10000U)
+#define SYSCON_STARTERCLR0_SPI1_CLR_SHIFT        (16U)
+/*! SPI1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_SPI1_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_SPI1_CLR_SHIFT)) & SYSCON_STARTERCLR0_SPI1_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM0_CLR_MASK         (0x20000U)
+#define SYSCON_STARTERCLR0_PWM0_CLR_SHIFT        (17U)
+/*! PWM0_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM0_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM0_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM0_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM1_CLR_MASK         (0x40000U)
+#define SYSCON_STARTERCLR0_PWM1_CLR_SHIFT        (18U)
+/*! PWM1_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM1_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM1_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM1_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM2_CLR_MASK         (0x80000U)
+#define SYSCON_STARTERCLR0_PWM2_CLR_SHIFT        (19U)
+/*! PWM2_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM2_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM2_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM2_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM3_CLR_MASK         (0x100000U)
+#define SYSCON_STARTERCLR0_PWM3_CLR_SHIFT        (20U)
+/*! PWM3_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM3_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM3_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM3_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM4_CLR_MASK         (0x200000U)
+#define SYSCON_STARTERCLR0_PWM4_CLR_SHIFT        (21U)
+/*! PWM4_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM4_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM4_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM4_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM5_CLR_MASK         (0x400000U)
+#define SYSCON_STARTERCLR0_PWM5_CLR_SHIFT        (22U)
+/*! PWM5_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM5_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM5_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM5_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM6_CLR_MASK         (0x800000U)
+#define SYSCON_STARTERCLR0_PWM6_CLR_SHIFT        (23U)
+/*! PWM6_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM6_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM6_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM6_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM7_CLR_MASK         (0x1000000U)
+#define SYSCON_STARTERCLR0_PWM7_CLR_SHIFT        (24U)
+/*! PWM7_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM7_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM7_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM7_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM8_CLR_MASK         (0x2000000U)
+#define SYSCON_STARTERCLR0_PWM8_CLR_SHIFT        (25U)
+/*! PWM8_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM8_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM8_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM8_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM9_CLR_MASK         (0x4000000U)
+#define SYSCON_STARTERCLR0_PWM9_CLR_SHIFT        (26U)
+/*! PWM9_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM9_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM9_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM9_CLR_MASK)
+#define SYSCON_STARTERCLR0_PWM10_CLR_MASK        (0x8000000U)
+#define SYSCON_STARTERCLR0_PWM10_CLR_SHIFT       (27U)
+/*! PWM10_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_PWM10_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_PWM10_CLR_SHIFT)) & SYSCON_STARTERCLR0_PWM10_CLR_MASK)
+#define SYSCON_STARTERCLR0_I2C2_CLR_MASK         (0x10000000U)
+#define SYSCON_STARTERCLR0_I2C2_CLR_SHIFT        (28U)
+/*! I2C2_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_I2C2_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_I2C2_CLR_SHIFT)) & SYSCON_STARTERCLR0_I2C2_CLR_MASK)
+#define SYSCON_STARTERCLR0_RTC_CLR_MASK          (0x20000000U)
+#define SYSCON_STARTERCLR0_RTC_CLR_SHIFT         (29U)
+/*! RTC_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_RTC_CLR(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_RTC_CLR_SHIFT)) & SYSCON_STARTERCLR0_RTC_CLR_MASK)
+#define SYSCON_STARTERCLR0_NFCTAG_CLR_MASK       (0x40000000U)
+#define SYSCON_STARTERCLR0_NFCTAG_CLR_SHIFT      (30U)
+/*! NFCTAG_CLR - Writing one to this bit clears the corresponding bit in the STARTER0 register
+ */
+#define SYSCON_STARTERCLR0_NFCTAG_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR0_NFCTAG_CLR_SHIFT)) & SYSCON_STARTERCLR0_NFCTAG_CLR_MASK)
+/*! @} */
+
+/*! @name STARTERCLR1 - Clear bits in STARTER1 */
+/*! @{ */
+#define SYSCON_STARTERCLR1_ADC_SEQA_CLR_MASK     (0x1U)
+#define SYSCON_STARTERCLR1_ADC_SEQA_CLR_SHIFT    (0U)
+/*! ADC_SEQA_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ADC_SEQA_CLR(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ADC_SEQA_CLR_SHIFT)) & SYSCON_STARTERCLR1_ADC_SEQA_CLR_MASK)
+#define SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR_MASK (0x4U)
+#define SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR_SHIFT (2U)
+/*! ADC_THCMP_OVR_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR_SHIFT)) & SYSCON_STARTERCLR1_ADC_THCMP_OVR_CLR_MASK)
+#define SYSCON_STARTERCLR1_DMIC_CLR_MASK         (0x8U)
+#define SYSCON_STARTERCLR1_DMIC_CLR_SHIFT        (3U)
+/*! DMIC_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_DMIC_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_DMIC_CLR_SHIFT)) & SYSCON_STARTERCLR1_DMIC_CLR_MASK)
+#define SYSCON_STARTERCLR1_HWVAD_CLR_MASK        (0x10U)
+#define SYSCON_STARTERCLR1_HWVAD_CLR_SHIFT       (4U)
+/*! HWVAD_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_HWVAD_CLR(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_HWVAD_CLR_SHIFT)) & SYSCON_STARTERCLR1_HWVAD_CLR_MASK)
+#define SYSCON_STARTERCLR1_BLE_DP_CLR_MASK       (0x20U)
+#define SYSCON_STARTERCLR1_BLE_DP_CLR_SHIFT      (5U)
+/*! BLE_DP_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_BLE_DP_CLR(x)         (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_BLE_DP_CLR_SHIFT)) & SYSCON_STARTERCLR1_BLE_DP_CLR_MASK)
+#define SYSCON_STARTERCLR1_BLE_DP0_CLR_MASK      (0x40U)
+#define SYSCON_STARTERCLR1_BLE_DP0_CLR_SHIFT     (6U)
+/*! BLE_DP0_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_BLE_DP0_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_BLE_DP0_CLR_SHIFT)) & SYSCON_STARTERCLR1_BLE_DP0_CLR_MASK)
+#define SYSCON_STARTERCLR1_BLE_DP1_CLR_MASK      (0x80U)
+#define SYSCON_STARTERCLR1_BLE_DP1_CLR_SHIFT     (7U)
+/*! BLE_DP1_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_BLE_DP1_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_BLE_DP1_CLR_SHIFT)) & SYSCON_STARTERCLR1_BLE_DP1_CLR_MASK)
+#define SYSCON_STARTERCLR1_BLE_DP2_CLR_MASK      (0x100U)
+#define SYSCON_STARTERCLR1_BLE_DP2_CLR_SHIFT     (8U)
+/*! BLE_DP2_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_BLE_DP2_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_BLE_DP2_CLR_SHIFT)) & SYSCON_STARTERCLR1_BLE_DP2_CLR_MASK)
+#define SYSCON_STARTERCLR1_BLE_LL_ALL_CLR_MASK   (0x200U)
+#define SYSCON_STARTERCLR1_BLE_LL_ALL_CLR_SHIFT  (9U)
+/*! BLE_LL_ALL_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_BLE_LL_ALL_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_BLE_LL_ALL_CLR_SHIFT)) & SYSCON_STARTERCLR1_BLE_LL_ALL_CLR_MASK)
+#define SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR_MASK   (0x400U)
+#define SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR_SHIFT  (10U)
+/*! ZIGBEE_MAC_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR_SHIFT)) & SYSCON_STARTERCLR1_ZIGBEE_MAC_CLR_MASK)
+#define SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR_MASK (0x800U)
+#define SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR_SHIFT (11U)
+/*! ZIGBEE_MODEM_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR_SHIFT)) & SYSCON_STARTERCLR1_ZIGBEE_MODEM_CLR_MASK)
+#define SYSCON_STARTERCLR1_RFP_TMU_CLR_MASK      (0x1000U)
+#define SYSCON_STARTERCLR1_RFP_TMU_CLR_SHIFT     (12U)
+/*! RFP_TMU_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_RFP_TMU_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_RFP_TMU_CLR_SHIFT)) & SYSCON_STARTERCLR1_RFP_TMU_CLR_MASK)
+#define SYSCON_STARTERCLR1_RFP_AGC_CLR_MASK      (0x2000U)
+#define SYSCON_STARTERCLR1_RFP_AGC_CLR_SHIFT     (13U)
+/*! RFP_AGC_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_RFP_AGC_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_RFP_AGC_CLR_SHIFT)) & SYSCON_STARTERCLR1_RFP_AGC_CLR_MASK)
+#define SYSCON_STARTERCLR1_ISO7816_CLR_MASK      (0x4000U)
+#define SYSCON_STARTERCLR1_ISO7816_CLR_SHIFT     (14U)
+/*! ISO7816_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ISO7816_CLR(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ISO7816_CLR_SHIFT)) & SYSCON_STARTERCLR1_ISO7816_CLR_MASK)
+#define SYSCON_STARTERCLR1_ANA_COMP_CLR_MASK     (0x8000U)
+#define SYSCON_STARTERCLR1_ANA_COMP_CLR_SHIFT    (15U)
+/*! ANA_COMP_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_ANA_COMP_CLR(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_ANA_COMP_CLR_SHIFT)) & SYSCON_STARTERCLR1_ANA_COMP_CLR_MASK)
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR_MASK (0x10000U)
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR_SHIFT (16U)
+/*! WAKE_UP_TIMER0_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR_SHIFT)) & SYSCON_STARTERCLR1_WAKE_UP_TIMER0_CLR_MASK)
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR_MASK (0x20000U)
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR_SHIFT (17U)
+/*! WAKE_UP_TIMER1_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR_SHIFT)) & SYSCON_STARTERCLR1_WAKE_UP_TIMER1_CLR_MASK)
+#define SYSCON_STARTERCLR1_BLE_WAKE_UP_TIMER_CLR_MASK (0x400000U)
+#define SYSCON_STARTERCLR1_BLE_WAKE_UP_TIMER_CLR_SHIFT (22U)
+/*! BLE_WAKE_UP_TIMER_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_BLE_WAKE_UP_TIMER_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_BLE_WAKE_UP_TIMER_CLR_SHIFT)) & SYSCON_STARTERCLR1_BLE_WAKE_UP_TIMER_CLR_MASK)
+#define SYSCON_STARTERCLR1_BLE_OSC_EN_CLR_MASK   (0x800000U)
+#define SYSCON_STARTERCLR1_BLE_OSC_EN_CLR_SHIFT  (23U)
+/*! BLE_OSC_EN_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_BLE_OSC_EN_CLR(x)     (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_BLE_OSC_EN_CLR_SHIFT)) & SYSCON_STARTERCLR1_BLE_OSC_EN_CLR_MASK)
+#define SYSCON_STARTERCLR1_GPIO_CLR_MASK         (0x80000000U)
+#define SYSCON_STARTERCLR1_GPIO_CLR_SHIFT        (31U)
+/*! GPIO_CLR - Writing one to this bit clears the corresponding bit in the STARTER1 register
+ */
+#define SYSCON_STARTERCLR1_GPIO_CLR(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR1_GPIO_CLR_SHIFT)) & SYSCON_STARTERCLR1_GPIO_CLR_MASK)
+/*! @} */
+
+/*! @name STARTERCLRX_STARTERCLRS - Pin assign register */
+/*! @{ */
+#define SYSCON_STARTERCLRX_STARTERCLRS_DATA_MASK (0xFFFFFFFFU)
+#define SYSCON_STARTERCLRX_STARTERCLRS_DATA_SHIFT (0U)
+#define SYSCON_STARTERCLRX_STARTERCLRS_DATA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLRX_STARTERCLRS_DATA_SHIFT)) & SYSCON_STARTERCLRX_STARTERCLRS_DATA_MASK)
+/*! @} */
+
+/* The count of SYSCON_STARTERCLRX_STARTERCLRS */
+#define SYSCON_STARTERCLRX_STARTERCLRS_COUNT     (2U)
+
+/*! @name RETENTIONCTRL - I/O retention control register */
+/*! @{ */
+#define SYSCON_RETENTIONCTRL_IOCLAMP_MASK        (0x1U)
+#define SYSCON_RETENTIONCTRL_IOCLAMP_SHIFT       (0U)
+/*! IOCLAMP - Global control of activation of I/O clamps to allow IOs to hold a value during a power
+ *    mode cycle. To use enable before the power down and then disable after a wake up. Note that
+ *    each I/O clamp must also be enabled/disabled individually in IOCON module and also that for an
+ *    I2C IO cell it must be in GPIO mode for the clamping to work. 0: I/O clamp is disable 1: I/O
+ *    clamp is enable
+ */
+#define SYSCON_RETENTIONCTRL_IOCLAMP(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_RETENTIONCTRL_IOCLAMP_SHIFT)) & SYSCON_RETENTIONCTRL_IOCLAMP_MASK)
+/*! @} */
+
+/*! @name CPSTACK - CPSTACK */
+/*! @{ */
+#define SYSCON_CPSTACK_CPSTACK_MASK              (0xFFFFFFFFU)
+#define SYSCON_CPSTACK_CPSTACK_SHIFT             (0U)
+/*! CPSTACK - CPSTACK
+ */
+#define SYSCON_CPSTACK_CPSTACK(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTACK_CPSTACK_SHIFT)) & SYSCON_CPSTACK_CPSTACK_MASK)
+/*! @} */
+
+/*! @name ANACTRL_CTRL - Analog Interrupt control register. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set. */
+/*! @{ */
+#define SYSCON_ANACTRL_CTRL_COMPINTRLVL_MASK     (0x1U)
+#define SYSCON_ANACTRL_CTRL_COMPINTRLVL_SHIFT    (0U)
+/*! COMPINTRLVL - Analog Comparator interrupt type: 0: Analog Comparator interrupt is edge
+ *    sensitive. 1: Analog Comparator interrupt is level sensitive.
+ */
+#define SYSCON_ANACTRL_CTRL_COMPINTRLVL(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_CTRL_COMPINTRLVL_SHIFT)) & SYSCON_ANACTRL_CTRL_COMPINTRLVL_MASK)
+#define SYSCON_ANACTRL_CTRL_COMPINTRPOL_MASK     (0x6U)
+#define SYSCON_ANACTRL_CTRL_COMPINTRPOL_SHIFT    (1U)
+/*! COMPINTRPOL - Analog Comparator interrupt Polarity: When COMPINTRLVL = 0 (edge sensitive): 00:
+ *    rising edge. 01: falling edge. 10: both edges (rising and falling). 11: both edges (rising and
+ *    falling). When COMPINTRLVL = 1 (level sensitive): 00: Low level ('0'). 01: Low level ('0').
+ *    10: High level ('1'). 11: High level ('1').
+ */
+#define SYSCON_ANACTRL_CTRL_COMPINTRPOL(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_CTRL_COMPINTRPOL_SHIFT)) & SYSCON_ANACTRL_CTRL_COMPINTRPOL_MASK)
+/*! @} */
+
+/*! @name ANACTRL_VAL - Analog modules (BOD and Analog Comparator) outputs current values (BOD 'Power OK' and Analog comparator out). Requires AHBCLKCTRL0.ANA_INT_CTRL to be set. */
+/*! @{ */
+#define SYSCON_ANACTRL_VAL_BODVBAT_MASK          (0x1U)
+#define SYSCON_ANACTRL_VAL_BODVBAT_SHIFT         (0U)
+/*! BODVBAT - BOD VBAT Status : 0 = Power not OK ; 1 = Power OK
+ */
+#define SYSCON_ANACTRL_VAL_BODVBAT(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_VAL_BODVBAT_SHIFT)) & SYSCON_ANACTRL_VAL_BODVBAT_MASK)
+#define SYSCON_ANACTRL_VAL_ANACOMP_MASK          (0x8U)
+#define SYSCON_ANACTRL_VAL_ANACOMP_SHIFT         (3U)
+/*! ANACOMP - Analog comparator Status : 0 = Comparator in 0 < in 1 ; 1 = Comparator in 0 > in 1.
+ */
+#define SYSCON_ANACTRL_VAL_ANACOMP(x)            (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_VAL_ANACOMP_SHIFT)) & SYSCON_ANACTRL_VAL_ANACOMP_MASK)
+#define SYSCON_ANACTRL_VAL_BODVBATHIGH_MASK      (0x10U)
+#define SYSCON_ANACTRL_VAL_BODVBATHIGH_SHIFT     (4U)
+/*! BODVBATHIGH - Not(BOD VBAT). Inverse of BOD VBAT. 0 = Power OK; 1 = Power not OK
+ */
+#define SYSCON_ANACTRL_VAL_BODVBATHIGH(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_VAL_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_VAL_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name ANACTRL_STAT - Analog modules (BOD and Analog Comparator) interrupt status. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set. */
+/*! @{ */
+#define SYSCON_ANACTRL_STAT_BODVBAT_MASK         (0x1U)
+#define SYSCON_ANACTRL_STAT_BODVBAT_SHIFT        (0U)
+/*! BODVBAT - BOD VBAT Interrupt status. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear.
+ */
+#define SYSCON_ANACTRL_STAT_BODVBAT(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_STAT_BODVBAT_SHIFT)) & SYSCON_ANACTRL_STAT_BODVBAT_MASK)
+#define SYSCON_ANACTRL_STAT_ANACOMP_MASK         (0x8U)
+#define SYSCON_ANACTRL_STAT_ANACOMP_SHIFT        (3U)
+/*! ANACOMP - Analog comparator Interrupt status. 0: No interrupt pending. 1: Interrupt pending. Write 1 to clear.
+ */
+#define SYSCON_ANACTRL_STAT_ANACOMP(x)           (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_STAT_ANACOMP_SHIFT)) & SYSCON_ANACTRL_STAT_ANACOMP_MASK)
+#define SYSCON_ANACTRL_STAT_BODVBATHIGH_MASK     (0x10U)
+#define SYSCON_ANACTRL_STAT_BODVBATHIGH_SHIFT    (4U)
+/*! BODVBATHIGH - NOT(BOD VBAT) interrupt status. Will be set when BOD VBAT goes high. Write 1 to clear.
+ */
+#define SYSCON_ANACTRL_STAT_BODVBATHIGH(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_STAT_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_STAT_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name ANACTRL_INTENSET - Analog modules (BOD and Analog Comparator) Interrupt Enable Read and Set register. Read value indicates which interrupts are enabled. Writing ones sets the corresponding interrupt enable bits. Note, interrupt enable bits are cleared using ANACTRL_INTENCLR. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register. */
+/*! @{ */
+#define SYSCON_ANACTRL_INTENSET_BODVBAT_MASK     (0x1U)
+#define SYSCON_ANACTRL_INTENSET_BODVBAT_SHIFT    (0U)
+/*! BODVBAT - BOD VBAT Interrupt Enable Read and Set register
+ */
+#define SYSCON_ANACTRL_INTENSET_BODVBAT(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENSET_BODVBAT_SHIFT)) & SYSCON_ANACTRL_INTENSET_BODVBAT_MASK)
+#define SYSCON_ANACTRL_INTENSET_ANACOMP_MASK     (0x8U)
+#define SYSCON_ANACTRL_INTENSET_ANACOMP_SHIFT    (3U)
+/*! ANACOMP - Analog comparator Interrupt Enable Read and Set register
+ */
+#define SYSCON_ANACTRL_INTENSET_ANACOMP(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENSET_ANACOMP_SHIFT)) & SYSCON_ANACTRL_INTENSET_ANACOMP_MASK)
+#define SYSCON_ANACTRL_INTENSET_BODVBATHIGH_MASK (0x10U)
+#define SYSCON_ANACTRL_INTENSET_BODVBATHIGH_SHIFT (4U)
+/*! BODVBATHIGH - NOT(BOD VBAT) Interrupt Enable Read and Set register
+ */
+#define SYSCON_ANACTRL_INTENSET_BODVBATHIGH(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENSET_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_INTENSET_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name ANACTRL_INTENCLR - Analog modules (BOD and Analog Comparator) Interrupt Enable Clear register. Writing ones clears the corresponding interrupt enable bits. Note, interrupt enable bits are set in ANACTRL_INTENSET. Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register. */
+/*! @{ */
+#define SYSCON_ANACTRL_INTENCLR_BODVBAT_MASK     (0x1U)
+#define SYSCON_ANACTRL_INTENCLR_BODVBAT_SHIFT    (0U)
+/*! BODVBAT - BOD VBAT Interrupt Enable Clear register
+ */
+#define SYSCON_ANACTRL_INTENCLR_BODVBAT(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENCLR_BODVBAT_SHIFT)) & SYSCON_ANACTRL_INTENCLR_BODVBAT_MASK)
+#define SYSCON_ANACTRL_INTENCLR_ANACOMP_MASK     (0x8U)
+#define SYSCON_ANACTRL_INTENCLR_ANACOMP_SHIFT    (3U)
+/*! ANACOMP - Analog comparator Interrupt Enable Clear register
+ */
+#define SYSCON_ANACTRL_INTENCLR_ANACOMP(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENCLR_ANACOMP_SHIFT)) & SYSCON_ANACTRL_INTENCLR_ANACOMP_MASK)
+#define SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_MASK (0x10U)
+#define SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_SHIFT (4U)
+/*! BODVBATHIGH - NOT(BOD VBAT) Interrupt Enable Clear register
+ */
+#define SYSCON_ANACTRL_INTENCLR_BODVBATHIGH(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name ANACTRL_INTSTAT - Analog modules (BOD and Analog Comparator) Interrupt Status register (masked with interrupt enable). Requires AHBCLKCTRL0.ANA_INT_CTRL to be set to use this register. Interrupt status bit are cleared using ANACTRL_STAT. */
+/*! @{ */
+#define SYSCON_ANACTRL_INTSTAT_BODVBAT_MASK      (0x1U)
+#define SYSCON_ANACTRL_INTSTAT_BODVBAT_SHIFT     (0U)
+/*! BODVBAT - BOD VBAT Interrupt (after interrupt mask). 0 = No interrupt pending. 1 = Interrupt
+ *    pending. Only set when BODVBAT is enabled in INTENSET
+ */
+#define SYSCON_ANACTRL_INTSTAT_BODVBAT(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTSTAT_BODVBAT_SHIFT)) & SYSCON_ANACTRL_INTSTAT_BODVBAT_MASK)
+#define SYSCON_ANACTRL_INTSTAT_ANACOMP_MASK      (0x8U)
+#define SYSCON_ANACTRL_INTSTAT_ANACOMP_SHIFT     (3U)
+/*! ANACOMP - Analog comparator Interrupt (after interrupt mask). 0 = No interrupt pending. 1 =
+ *    Interrupt pending. Only set when ANACOMP is enabled in INTENSET
+ */
+#define SYSCON_ANACTRL_INTSTAT_ANACOMP(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTSTAT_ANACOMP_SHIFT)) & SYSCON_ANACTRL_INTSTAT_ANACOMP_MASK)
+#define SYSCON_ANACTRL_INTSTAT_BODVBATHIGH_MASK  (0x10U)
+#define SYSCON_ANACTRL_INTSTAT_BODVBATHIGH_SHIFT (4U)
+/*! BODVBATHIGH - NOT(BOD VBAT) Interrupt (after interrupt mask). 0 = No interrupt pending. 1 =
+ *    Interrupt pending. Only set when BODVBATHIGH is enabled in INTENSET
+ */
+#define SYSCON_ANACTRL_INTSTAT_BODVBATHIGH(x)    (((uint32_t)(((uint32_t)(x)) << SYSCON_ANACTRL_INTSTAT_BODVBATHIGH_SHIFT)) & SYSCON_ANACTRL_INTSTAT_BODVBATHIGH_MASK)
+/*! @} */
+
+/*! @name CLOCK_CTRL - Various system clock controls : Flash clock (48 MHz) control, clocks to Frequency Measure function */
+/*! @{ */
+#define SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA_MASK    (0x1U)
+#define SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA_SHIFT   (0U)
+/*! FLASH48MHZ_ENA - Enable Flash 48 MHz clock. 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA_SHIFT)) & SYSCON_CLOCK_CTRL_FLASH48MHZ_ENA_MASK)
+#define SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_MASK (0x2U)
+#define SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_SHIFT (1U)
+/*! XTAL32MHZ_FREQM_ENA - Enable XTAL32MHz clock for Frequency Measure module. 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_SHIFT)) & SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_MASK)
+#define SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_MASK (0x4U)
+#define SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_SHIFT (2U)
+/*! FRO1MHZ_FREQM_ENA - Enable FRO 1MHz clock for Frequency Measure module. 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA(x)   (((uint32_t)(((uint32_t)(x)) << SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_SHIFT)) & SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_MASK)
+/*! @} */
+
+/*! @name WKT_CTRL - Wake-up timers control */
+/*! @{ */
+#define SYSCON_WKT_CTRL_WKT0_ENA_MASK            (0x1U)
+#define SYSCON_WKT_CTRL_WKT0_ENA_SHIFT           (0U)
+/*! WKT0_ENA - Enable wake-up timer 0: 0 = Disabled. 1 = Enabled (counter is running).
+ */
+#define SYSCON_WKT_CTRL_WKT0_ENA(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_CTRL_WKT0_ENA_SHIFT)) & SYSCON_WKT_CTRL_WKT0_ENA_MASK)
+#define SYSCON_WKT_CTRL_WKT1_ENA_MASK            (0x2U)
+#define SYSCON_WKT_CTRL_WKT1_ENA_SHIFT           (1U)
+/*! WKT1_ENA - Enable wake-up timer 1: 0 = Disabled. 1 = Enabled (counter is running).
+ */
+#define SYSCON_WKT_CTRL_WKT1_ENA(x)              (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_CTRL_WKT1_ENA_SHIFT)) & SYSCON_WKT_CTRL_WKT1_ENA_MASK)
+#define SYSCON_WKT_CTRL_WKT0_CLK_ENA_MASK        (0x4U)
+#define SYSCON_WKT_CTRL_WKT0_CLK_ENA_SHIFT       (2U)
+/*! WKT0_CLK_ENA - Enable wake-up timer 0 clock: 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_WKT_CTRL_WKT0_CLK_ENA(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_CTRL_WKT0_CLK_ENA_SHIFT)) & SYSCON_WKT_CTRL_WKT0_CLK_ENA_MASK)
+#define SYSCON_WKT_CTRL_WKT1_CLK_ENA_MASK        (0x8U)
+#define SYSCON_WKT_CTRL_WKT1_CLK_ENA_SHIFT       (3U)
+/*! WKT1_CLK_ENA - Enable wake-up timer 1 clock: 0 = Disabled. 1 = Enabled.
+ */
+#define SYSCON_WKT_CTRL_WKT1_CLK_ENA(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_CTRL_WKT1_CLK_ENA_SHIFT)) & SYSCON_WKT_CTRL_WKT1_CLK_ENA_MASK)
+/*! @} */
+
+/*! @name WKT_LOAD_WKT0_LSB - Wake-up timer 0 reload value least significant bits ([31:0]). */
+/*! @{ */
+#define SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB_MASK (0xFFFFFFFFU)
+#define SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB_SHIFT (0U)
+/*! WKT0_LOAD_LSB - Wake-up timer 0 reload value, least significant bits ([31:0]). Write when timer is not enabled
+ */
+#define SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB_SHIFT)) & SYSCON_WKT_LOAD_WKT0_LSB_WKT0_LOAD_LSB_MASK)
+/*! @} */
+
+/*! @name WKT_LOAD_WKT0_MSB - Wake-up timer 0 reload value most significant bits ([8:0]). */
+/*! @{ */
+#define SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB_MASK (0x1FFU)
+#define SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB_SHIFT (0U)
+/*! WKT0_LOAD_MSB - Wake-up timer 0 reload value, most significant bits ([8:0]). Write when timer is not enabled
+ */
+#define SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB_SHIFT)) & SYSCON_WKT_LOAD_WKT0_MSB_WKT0_LOAD_MSB_MASK)
+/*! @} */
+
+/*! @name WKT_LOAD_WKT1 - Wake-up timer 1 reload value. */
+/*! @{ */
+#define SYSCON_WKT_LOAD_WKT1_WKT1_LOAD_MASK      (0xFFFFFFFU)
+#define SYSCON_WKT_LOAD_WKT1_WKT1_LOAD_SHIFT     (0U)
+/*! WKT1_LOAD - Wake-up timer 1 reload value. Write when timer is not enabled
+ */
+#define SYSCON_WKT_LOAD_WKT1_WKT1_LOAD(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_LOAD_WKT1_WKT1_LOAD_SHIFT)) & SYSCON_WKT_LOAD_WKT1_WKT1_LOAD_MASK)
+/*! @} */
+
+/*! @name WKT_VAL_WKT0_LSB - Wake-up timer 0 current value least significant bits ([31:0]). WARNING : reading not reliable: read this register several times until you get a stable value. */
+/*! @{ */
+#define SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB_MASK (0xFFFFFFFFU)
+#define SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB_SHIFT (0U)
+/*! WKT0_VAL_LSB - Wake-up timer 0 value, least significant bits ([31:0]). Reread until stable value seen.
+ */
+#define SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB_SHIFT)) & SYSCON_WKT_VAL_WKT0_LSB_WKT0_VAL_LSB_MASK)
+/*! @} */
+
+/*! @name WKT_VAL_WKT0_MSB - Wake-up timer 0 current value most significant bits ([8:0]). WARNING : reading not reliable: read this register several times until you get a stable value. */
+/*! @{ */
+#define SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB_MASK (0x1FFU)
+#define SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB_SHIFT (0U)
+/*! WKT0_VAL_MSB - Wake-up timer 0 value, most significant bits ([8:0]). Reread until stable value seen.
+ */
+#define SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB(x)  (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB_SHIFT)) & SYSCON_WKT_VAL_WKT0_MSB_WKT0_VAL_MSB_MASK)
+/*! @} */
+
+/*! @name WKT_VAL_WKT1 - Wake-up timer 1 current value. WARNING : reading not reliable: read this register several times until you get a stable value. */
+/*! @{ */
+#define SYSCON_WKT_VAL_WKT1_WKT1_VAL_MASK        (0xFFFFFFFU)
+#define SYSCON_WKT_VAL_WKT1_WKT1_VAL_SHIFT       (0U)
+/*! WKT1_VAL - Wake-up timer 1 value. Reread until stable value seen.
+ */
+#define SYSCON_WKT_VAL_WKT1_WKT1_VAL(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_VAL_WKT1_WKT1_VAL_SHIFT)) & SYSCON_WKT_VAL_WKT1_WKT1_VAL_MASK)
+/*! @} */
+
+/*! @name WKT_STAT - Wake-up timers status */
+/*! @{ */
+#define SYSCON_WKT_STAT_WKT0_TIMEOUT_MASK        (0x1U)
+#define SYSCON_WKT_STAT_WKT0_TIMEOUT_SHIFT       (0U)
+/*! WKT0_TIMEOUT - Timeout Status of Wake-up timer 0 : 0 = timeout not reached ; 1 = timeout reached. Write 1 to clear.
+ */
+#define SYSCON_WKT_STAT_WKT0_TIMEOUT(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_STAT_WKT0_TIMEOUT_SHIFT)) & SYSCON_WKT_STAT_WKT0_TIMEOUT_MASK)
+#define SYSCON_WKT_STAT_WKT1_TIMEOUT_MASK        (0x2U)
+#define SYSCON_WKT_STAT_WKT1_TIMEOUT_SHIFT       (1U)
+/*! WKT1_TIMEOUT - Timeout Status of Wake-up timer 1 : 0 = timeout not reached ; 1 = timeout reached. Write 1 to clear.
+ */
+#define SYSCON_WKT_STAT_WKT1_TIMEOUT(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_STAT_WKT1_TIMEOUT_SHIFT)) & SYSCON_WKT_STAT_WKT1_TIMEOUT_MASK)
+#define SYSCON_WKT_STAT_WKT0_RUNNING_MASK        (0x4U)
+#define SYSCON_WKT_STAT_WKT0_RUNNING_SHIFT       (2U)
+/*! WKT0_RUNNING - Running Status of Wake-up timer 0 : 0 = not running ; 1 = running
+ */
+#define SYSCON_WKT_STAT_WKT0_RUNNING(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_STAT_WKT0_RUNNING_SHIFT)) & SYSCON_WKT_STAT_WKT0_RUNNING_MASK)
+#define SYSCON_WKT_STAT_WKT1_RUNNING_MASK        (0x8U)
+#define SYSCON_WKT_STAT_WKT1_RUNNING_SHIFT       (3U)
+/*! WKT1_RUNNING - Running Status of Wake-up timer 1 : 0 = not running ; 1 = running
+ */
+#define SYSCON_WKT_STAT_WKT1_RUNNING(x)          (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_STAT_WKT1_RUNNING_SHIFT)) & SYSCON_WKT_STAT_WKT1_RUNNING_MASK)
+/*! @} */
+
+/*! @name WKT_INTENSET - Interrupt Enable Read and Set register */
+/*! @{ */
+#define SYSCON_WKT_INTENSET_WKT0_TIMEOUT_MASK    (0x1U)
+#define SYSCON_WKT_INTENSET_WKT0_TIMEOUT_SHIFT   (0U)
+/*! WKT0_TIMEOUT - Wake-up Timer 0 Timeout Interrupt Enable Read and Set register. Read value of '1'
+ *    indicates that the interrupt is enabled. Set this bit to enable the interrupt. Use
+ *    WKT_INTENCLR to disable the interrupt.
+ */
+#define SYSCON_WKT_INTENSET_WKT0_TIMEOUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTENSET_WKT0_TIMEOUT_SHIFT)) & SYSCON_WKT_INTENSET_WKT0_TIMEOUT_MASK)
+#define SYSCON_WKT_INTENSET_WKT1_TIMEOUT_MASK    (0x2U)
+#define SYSCON_WKT_INTENSET_WKT1_TIMEOUT_SHIFT   (1U)
+/*! WKT1_TIMEOUT - Wake-up Timer 1 Timeout Interrupt Enable Read and Set register. Read value of '1'
+ *    indicates that the interrupt is enabled. Set this bit to enable the interrupt. Use
+ *    WKT_INTENCLR to disable the interrupt.
+ */
+#define SYSCON_WKT_INTENSET_WKT1_TIMEOUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTENSET_WKT1_TIMEOUT_SHIFT)) & SYSCON_WKT_INTENSET_WKT1_TIMEOUT_MASK)
+/*! @} */
+
+/*! @name WKT_INTENCLR - Interrupt Enable Clear register */
+/*! @{ */
+#define SYSCON_WKT_INTENCLR_WKT0_TIMEOUT_MASK    (0x1U)
+#define SYSCON_WKT_INTENCLR_WKT0_TIMEOUT_SHIFT   (0U)
+/*! WKT0_TIMEOUT - Wake-up Timer 0 Timeout Interrupt Enable Clear register. Set this bit to disable the interrupt.
+ */
+#define SYSCON_WKT_INTENCLR_WKT0_TIMEOUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTENCLR_WKT0_TIMEOUT_SHIFT)) & SYSCON_WKT_INTENCLR_WKT0_TIMEOUT_MASK)
+#define SYSCON_WKT_INTENCLR_WKT1_TIMEOUT_MASK    (0x2U)
+#define SYSCON_WKT_INTENCLR_WKT1_TIMEOUT_SHIFT   (1U)
+/*! WKT1_TIMEOUT - Wake-up Timer 1 Timeout Interrupt Enable Clear register. Set this bit to disable the interrupt.
+ */
+#define SYSCON_WKT_INTENCLR_WKT1_TIMEOUT(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTENCLR_WKT1_TIMEOUT_SHIFT)) & SYSCON_WKT_INTENCLR_WKT1_TIMEOUT_MASK)
+/*! @} */
+
+/*! @name WKT_INTSTAT - Interrupt Status register */
+/*! @{ */
+#define SYSCON_WKT_INTSTAT_WKT0_TIMEOUT_MASK     (0x1U)
+#define SYSCON_WKT_INTSTAT_WKT0_TIMEOUT_SHIFT    (0U)
+/*! WKT0_TIMEOUT - Wake-up Timer 0 Timeout Interrupt. 0: No interrupt pending. 1: Interrupt pending.
+ *    Only set when WKT0_TIMEOUT is enable in INTENSET
+ */
+#define SYSCON_WKT_INTSTAT_WKT0_TIMEOUT(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTSTAT_WKT0_TIMEOUT_SHIFT)) & SYSCON_WKT_INTSTAT_WKT0_TIMEOUT_MASK)
+#define SYSCON_WKT_INTSTAT_WKT1_TIMEOUT_MASK     (0x2U)
+#define SYSCON_WKT_INTSTAT_WKT1_TIMEOUT_SHIFT    (1U)
+/*! WKT1_TIMEOUT - Wake-up Timer 1 Timeout Interrupt. 0: No interrupt pending. 1: Interrupt pending.
+ *    Only set when WKT1_TIMEOUT is enable in INTENSET
+ */
+#define SYSCON_WKT_INTSTAT_WKT1_TIMEOUT(x)       (((uint32_t)(((uint32_t)(x)) << SYSCON_WKT_INTSTAT_WKT1_TIMEOUT_SHIFT)) & SYSCON_WKT_INTSTAT_WKT1_TIMEOUT_MASK)
+/*! @} */
+
+/*! @name GPIOPSYNC - Enable bypass of the first stage of synchonization inside GPIO_INT module. */
+/*! @{ */
+#define SYSCON_GPIOPSYNC_PSYNC_MASK              (0x1U)
+#define SYSCON_GPIOPSYNC_PSYNC_SHIFT             (0U)
+/*! PSYNC - Enable bypass of the first stage of synchonization inside GPIO_INT module.
+ */
+#define SYSCON_GPIOPSYNC_PSYNC(x)                (((uint32_t)(((uint32_t)(x)) << SYSCON_GPIOPSYNC_PSYNC_SHIFT)) & SYSCON_GPIOPSYNC_PSYNC_MASK)
+/*! @} */
+
+/*! @name DIEID - Chip revision ID & Number */
+/*! @{ */
+#define SYSCON_DIEID_REV_ID_MASK                 (0xFU)
+#define SYSCON_DIEID_REV_ID_SHIFT                (0U)
+/*! REV_ID - Chip Revision ID
+ */
+#define SYSCON_DIEID_REV_ID(x)                   (((uint32_t)(((uint32_t)(x)) << SYSCON_DIEID_REV_ID_SHIFT)) & SYSCON_DIEID_REV_ID_MASK)
+#define SYSCON_DIEID_MCO_NUM_IN_DIE_ID_MASK      (0xFFFFF0U)
+#define SYSCON_DIEID_MCO_NUM_IN_DIE_ID_SHIFT     (4U)
+/*! MCO_NUM_IN_DIE_ID - Chip Number
+ */
+#define SYSCON_DIEID_MCO_NUM_IN_DIE_ID(x)        (((uint32_t)(((uint32_t)(x)) << SYSCON_DIEID_MCO_NUM_IN_DIE_ID_SHIFT)) & SYSCON_DIEID_MCO_NUM_IN_DIE_ID_MASK)
+/*! @} */
+
+/*! @name CODESECURITYPROT - Security code to allow test access via SWD/JTAG. Reset with POR, SW reset or BOD */
+/*! @{ */
+#define SYSCON_CODESECURITYPROT_SEC_CODE_MASK    (0xFFFFFFFFU)
+#define SYSCON_CODESECURITYPROT_SEC_CODE_SHIFT   (0U)
+/*! SEC_CODE - Security code to allow debug via SWD and JTAG access in test mode. Write once
+ *    register, value 0x87654321 disables the access and therefore prevents any chance to enable it.
+ *    Writing any other value enables the access and locks the mode. In some cases the boot code will
+ *    secure the device by writing to this register to disable SWD and JTAG. This would prevent the
+ *    application being able to re-enable this access.
+ */
+#define SYSCON_CODESECURITYPROT_SEC_CODE(x)      (((uint32_t)(((uint32_t)(x)) << SYSCON_CODESECURITYPROT_SEC_CODE_SHIFT)) & SYSCON_CODESECURITYPROT_SEC_CODE_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group SYSCON_Register_Masks */
+
+
+/* SYSCON - Peripheral instance base addresses */
+/** Peripheral SYSCON base address */
+#define SYSCON_BASE                              (0x40000000u)
+/** Peripheral SYSCON base pointer */
+#define SYSCON                                   ((SYSCON_Type *)SYSCON_BASE)
+/** Array initializer of SYSCON peripheral base addresses */
+#define SYSCON_BASE_ADDRS                        { SYSCON_BASE }
+/** Array initializer of SYSCON peripheral base pointers */
+#define SYSCON_BASE_PTRS                         { SYSCON }
+
+/*!
+ * @}
+ */ /* end of group SYSCON_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- USART Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup USART_Peripheral_Access_Layer USART Peripheral Access Layer
+ * @{
+ */
+
+/** USART - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t CFG;                               /**< USART Configuration register. Basic USART configuration settings that typically are not changed during operation., offset: 0x0 */
+  __IO uint32_t CTL;                               /**< USART Control register. USART control settings that are more likely to change during operation., offset: 0x4 */
+  __IO uint32_t STAT;                              /**< USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them., offset: 0x8 */
+  __IO uint32_t INTENSET;                          /**< Interrupt Enable read and Set register for USART (not FIFO) status. Contains individual interrupt enable bits for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0xC */
+  __O  uint32_t INTENCLR;                          /**< Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared., offset: 0x10 */
+       uint8_t RESERVED_0[12];
+  __IO uint32_t BRG;                               /**< Baud Rate Generator register. 16-bit integer baud rate divisor value., offset: 0x20 */
+  __I  uint32_t INTSTAT;                           /**< Interrupt status register. Reflects the status of interrupts that are currently enabled., offset: 0x24 */
+  __IO uint32_t OSR;                               /**< Oversample selection register for asynchronous communication., offset: 0x28 */
+  __IO uint32_t ADDR;                              /**< Address register for automatic address matching., offset: 0x2C */
+       uint8_t RESERVED_1[3536];
+  __IO uint32_t FIFOCFG;                           /**< FIFO configuration and enable register., offset: 0xE00 */
+  __IO uint32_t FIFOSTAT;                          /**< FIFO status register., offset: 0xE04 */
+  __IO uint32_t FIFOTRIG;                          /**< FIFO trigger settings for interrupt and DMA request., offset: 0xE08 */
+       uint8_t RESERVED_2[4];
+  __IO uint32_t FIFOINTENSET;                      /**< FIFO interrupt enable set (enable) and read register., offset: 0xE10 */
+  __O  uint32_t FIFOINTENCLR;                      /**< FIFO interrupt enable clear (disable) and read register., offset: 0xE14 */
+  __I  uint32_t FIFOINTSTAT;                       /**< FIFO interrupt status register. Reflects the status of interrupts that are currently enabled., offset: 0xE18 */
+       uint8_t RESERVED_3[4];
+  __O  uint32_t FIFOWR;                            /**< FIFO write data. Used to write values to be transmitted to the FIFO., offset: 0xE20 */
+       uint8_t RESERVED_4[12];
+  __I  uint32_t FIFORD;                            /**< FIFO read data. Used to read values that have been received., offset: 0xE30 */
+       uint8_t RESERVED_5[12];
+  __I  uint32_t FIFORDNOPOP;                       /**< FIFO data read with no FIFO pop. This register acts in exactly the same way as FIFORD, except that it supplies data from the top of the FIFO without popping the FIFO (i.e. leaving the FIFO state unchanged). This could be used to allow system software to observe incoming data without interfering with the peripheral driver., offset: 0xE40 */
+       uint8_t RESERVED_6[436];
+  __IO uint32_t PSELID;                            /**< Flexcomm ID and peripheral function select register, offset: 0xFF8 */
+  __I  uint32_t ID;                                /**< USART Module Identifier, offset: 0xFFC */
+} USART_Type;
+
+/* ----------------------------------------------------------------------------
+   -- USART Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup USART_Register_Masks USART Register Masks
+ * @{
+ */
+
+/*! @name CFG - USART Configuration register. Basic USART configuration settings that typically are not changed during operation. */
+/*! @{ */
+#define USART_CFG_ENABLE_MASK                    (0x1U)
+#define USART_CFG_ENABLE_SHIFT                   (0U)
+/*! ENABLE - USART Enable. 0: Disabled. The USART is disabled and the internal state machine and
+ *    counters are reset. While Enable = 0, all USART interrupts and DMA transfers are disabled. When
+ *    Enable is set again, CFG and most other control bits remain unchanged. When re-enabled, the
+ *    USART will immediately be ready to transmit because the transmitter has been reset and is
+ *    therefore available. 1: Eanbled. The USART is enabled for operation.
+ */
+#define USART_CFG_ENABLE(x)                      (((uint32_t)(((uint32_t)(x)) << USART_CFG_ENABLE_SHIFT)) & USART_CFG_ENABLE_MASK)
+#define USART_CFG_DATALEN_MASK                   (0xCU)
+#define USART_CFG_DATALEN_SHIFT                  (2U)
+/*! DATALEN - Selects the data size for the USART. 0: 7 bit Data Length; 1: 8 bit data length; 2: 9
+ *    bit data length. The 9th bit is commonly used for addressing in multidrop mode. See the
+ *    ADDRDET bit in the CTRL regsiter. 3: Reserved.
+ */
+#define USART_CFG_DATALEN(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_DATALEN_SHIFT)) & USART_CFG_DATALEN_MASK)
+#define USART_CFG_PARITYSEL_MASK                 (0x30U)
+#define USART_CFG_PARITYSEL_SHIFT                (4U)
+/*! PARITYSEL - Selects what type of parity is used by the USART. 0: No parity; 1: Reserved; 2: Even
+ *    Parity. Adds a bit to each character such that the number of 1s in a transmitted character is
+ *    even, and the number of 1s in a received character is expected to be even. 3: Odd parity.
+ *    Adds a bit to each character such that the number of 1s in a transmitted character is odd, and
+ *    the number of 1s in a received character is expected to be odd.
+ */
+#define USART_CFG_PARITYSEL(x)                   (((uint32_t)(((uint32_t)(x)) << USART_CFG_PARITYSEL_SHIFT)) & USART_CFG_PARITYSEL_MASK)
+#define USART_CFG_STOPLEN_MASK                   (0x40U)
+#define USART_CFG_STOPLEN_SHIFT                  (6U)
+/*! STOPLEN - Number of stop bits appended to transmitted data. Only a single stop bit is required
+ *    for received data. 0: 1 stop bit; 1: 2 stop bits. This setting should only be used for
+ *    asynchronous communication.
+ */
+#define USART_CFG_STOPLEN(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_STOPLEN_SHIFT)) & USART_CFG_STOPLEN_MASK)
+#define USART_CFG_MODE32K_MASK                   (0x80U)
+#define USART_CFG_MODE32K_SHIFT                  (7U)
+/*! MODE32K - Selects standard or 32 kHz clocking mode. 0: Disabled. USART uses standard clocking.
+ *    1: Enabled. USART uses the 32 kHz clock from the RTC oscillator as the clock source to the BRG,
+ *    and uses a special bit clocking scheme.
+ */
+#define USART_CFG_MODE32K(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_MODE32K_SHIFT)) & USART_CFG_MODE32K_MASK)
+#define USART_CFG_LINMODE_MASK                   (0x100U)
+#define USART_CFG_LINMODE_SHIFT                  (8U)
+/*! LINMODE - LIN bus break mode enable. 0: Disabled. Break detect and generate is configured for
+ *    normal operation. 1: Enabled. Break detect and generate is configured for LIN bus operation.
+ */
+#define USART_CFG_LINMODE(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_LINMODE_SHIFT)) & USART_CFG_LINMODE_MASK)
+#define USART_CFG_CTSEN_MASK                     (0x200U)
+#define USART_CFG_CTSEN_SHIFT                    (9U)
+/*! CTSEN - CTS Enable. Determines whether CTS is used for flow control. CTS can be from the input
+ *    pin, or from the USART s own RTS if loopback mode is enabled. 0 : No flow control. The
+ *    transmitter does not receive any automatic flow control signal. 1: Flow control enabled. The
+ *    transmitter uses the CTS input (or RTS output in loopback mode) for flow control purposes.
+ */
+#define USART_CFG_CTSEN(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_CTSEN_SHIFT)) & USART_CFG_CTSEN_MASK)
+#define USART_CFG_SYNCEN_MASK                    (0x800U)
+#define USART_CFG_SYNCEN_SHIFT                   (11U)
+/*! SYNCEN - Selects synchronous or asynchronous operation. 0: Asynchronous mode. 1: Synchronous mode.
+ */
+#define USART_CFG_SYNCEN(x)                      (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCEN_SHIFT)) & USART_CFG_SYNCEN_MASK)
+#define USART_CFG_CLKPOL_MASK                    (0x1000U)
+#define USART_CFG_CLKPOL_SHIFT                   (12U)
+/*! CLKPOL - Selects the clock polarity and sampling edge of received data in synchronous mode. 0:
+ *    Falling edge. Un_RXD is sampled on the falling edge of SCLK. 1: Rising edge. Un_RXD is sampled
+ *    on the rising edge of SCLK.
+ */
+#define USART_CFG_CLKPOL(x)                      (((uint32_t)(((uint32_t)(x)) << USART_CFG_CLKPOL_SHIFT)) & USART_CFG_CLKPOL_MASK)
+#define USART_CFG_SYNCMST_MASK                   (0x4000U)
+#define USART_CFG_SYNCMST_SHIFT                  (14U)
+/*! SYNCMST - Synchronous mode Master select. 0: Slave. When synchronous mode is enabled, the USART
+ *    is a slave. 1: Master. When synchronous mode is enabled, the USART is a master.
+ */
+#define USART_CFG_SYNCMST(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCMST_SHIFT)) & USART_CFG_SYNCMST_MASK)
+#define USART_CFG_LOOP_MASK                      (0x8000U)
+#define USART_CFG_LOOP_SHIFT                     (15U)
+/*! LOOP - Selects data loopback mode. 0: Normal operaetion. 1: Loopback mode. This provides a
+ *    mechanism to perform diagnostic loopback testing for USART data. Serial data from the transmitter
+ *    (Un_TXD) is connected internally to serial input of the receive (Un_RXD). Un_TXD and Un_RTS
+ *    activity will also appear on external pins if these functions are configured to appear on device
+ *    pins. The receiver RTS signal is also looped back to CTS and performs flow control if enabled
+ *    by CTSEN.
+ */
+#define USART_CFG_LOOP(x)                        (((uint32_t)(((uint32_t)(x)) << USART_CFG_LOOP_SHIFT)) & USART_CFG_LOOP_MASK)
+#define USART_CFG_OETA_MASK                      (0x40000U)
+#define USART_CFG_OETA_SHIFT                     (18U)
+/*! OETA - Output Enable Turnaround time enable for RS-485 operation. 0: Disabled. If selected by
+ *    OESEL, the Output Enable signal deasserted at the end of the last stop bit of a transmission. 1:
+ *    Enabled. If selected by OESEL, the Output Enable signal remains asserted for one character
+ *    time after the end of the last stop bit of a transmission. OE will also remain asserted if
+ *    another transmit begins before it is deasserted.
+ */
+#define USART_CFG_OETA(x)                        (((uint32_t)(((uint32_t)(x)) << USART_CFG_OETA_SHIFT)) & USART_CFG_OETA_MASK)
+#define USART_CFG_AUTOADDR_MASK                  (0x80000U)
+#define USART_CFG_AUTOADDR_SHIFT                 (19U)
+/*! AUTOADDR - Automatic Address matching enable. 0: Disabled. When addressing is enabled by
+ *    ADDRDET, address matching is done by software. This provides the possibility of versatile addressing
+ *    (e.g. respond to more than one address). 1: Enabled. When addressing is enabled by ADDRDET,
+ *    address matching is done by hardware, using the value in the ADDR register as the address to
+ *    match.
+ */
+#define USART_CFG_AUTOADDR(x)                    (((uint32_t)(((uint32_t)(x)) << USART_CFG_AUTOADDR_SHIFT)) & USART_CFG_AUTOADDR_MASK)
+#define USART_CFG_OESEL_MASK                     (0x100000U)
+#define USART_CFG_OESEL_SHIFT                    (20U)
+/*! OESEL - Output Enable Select. 0: Standard. The RTS signal is used as the standard flow control
+ *    function. 1: RS-485. The RTS signal configured to provide an output enable signal to control an
+ *    RS-485 transceiver.
+ */
+#define USART_CFG_OESEL(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_OESEL_SHIFT)) & USART_CFG_OESEL_MASK)
+#define USART_CFG_OEPOL_MASK                     (0x200000U)
+#define USART_CFG_OEPOL_SHIFT                    (21U)
+/*! OEPOL - Output Enable Polarity. 0: Low. If selected by OESEL, the output enable is active low.
+ *    1: High. If selected by OESEL, the output enable is active high.
+ */
+#define USART_CFG_OEPOL(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_OEPOL_SHIFT)) & USART_CFG_OEPOL_MASK)
+#define USART_CFG_RXPOL_MASK                     (0x400000U)
+#define USART_CFG_RXPOL_SHIFT                    (22U)
+/*! RXPOL - Receive data polarity. 0: Standard. The RX signal is used as it arrives from the pin.
+ *    This means that the RX rest value is 1, start bit is 0, data is not inverted, and the stop bit
+ *    is 1. 1: Inverted. The RX signal is inverted before being used by the USART. This means that
+ *    the RX rest value is 0, start bit is 1, data is inverted, and the stop bit is 0.
+ */
+#define USART_CFG_RXPOL(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_RXPOL_SHIFT)) & USART_CFG_RXPOL_MASK)
+#define USART_CFG_TXPOL_MASK                     (0x800000U)
+#define USART_CFG_TXPOL_SHIFT                    (23U)
+/*! TXPOL - Transmit data polarity. 0: Standard. The TX signal is sent out without change. This
+ *    means that the TX rest value is 1, start bit is 0, data is not inverted, and the stop bit is 1. 1:
+ *    Inverted. The TX signal is inverted by the USART before being sent out. This means that the
+ *    TX rest value is 0, start bit is 1, data is inverted, and the stop bit is 0.
+ */
+#define USART_CFG_TXPOL(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CFG_TXPOL_SHIFT)) & USART_CFG_TXPOL_MASK)
+/*! @} */
+
+/*! @name CTL - USART Control register. USART control settings that are more likely to change during operation. */
+/*! @{ */
+#define USART_CTL_TXBRKEN_MASK                   (0x2U)
+#define USART_CTL_TXBRKEN_SHIFT                  (1U)
+/*! TXBRKEN - Break Enable. 0: Normal Operation. 1: Continuous break. Continuous break is sent
+ *    immediately when this bit is set, and remains until this bit is cleared. A break may be sent
+ *    without danger of corrupting any currently transmitting character if the transmitter is first
+ *    disabled (TXDIS in CTL is set) and then waiting for the transmitter to be disabled (TXDISINT in STAT
+ *    = 1) before writing 1 to TXBRKEN.
+ */
+#define USART_CTL_TXBRKEN(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXBRKEN_SHIFT)) & USART_CTL_TXBRKEN_MASK)
+#define USART_CTL_ADDRDET_MASK                   (0x4U)
+#define USART_CTL_ADDRDET_SHIFT                  (2U)
+/*! ADDRDET - Enable address detect mode. 0: Disabled. The USART presents all incoming data. 1:
+ *    Enabled. The USART receiver ignores incoming data that does not have the most significant bit of
+ *    the data (typically the 9th bit) = 1. When the data MSB bit = 1, the receiver treats the
+ *    incoming data normally, generating a received data interrupt. Software can then check the data to
+ *    see if this is an address that should be handled. If it is, the ADDRDET bit is cleared by
+ *    software and further incoming data is handled normally.
+ */
+#define USART_CTL_ADDRDET(x)                     (((uint32_t)(((uint32_t)(x)) << USART_CTL_ADDRDET_SHIFT)) & USART_CTL_ADDRDET_MASK)
+#define USART_CTL_TXDIS_MASK                     (0x40U)
+#define USART_CTL_TXDIS_SHIFT                    (6U)
+/*! TXDIS - Transmit Disable. 0: Not disabled. USART transmitter is not disabled. 1: Disabled. USART
+ *    transmitter is disabled after any character currently being transmitted is complete. This
+ *    feature can be used to facilitate software flow control.
+ */
+#define USART_CTL_TXDIS(x)                       (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXDIS_SHIFT)) & USART_CTL_TXDIS_MASK)
+#define USART_CTL_CC_MASK                        (0x100U)
+#define USART_CTL_CC_SHIFT                       (8U)
+/*! CC - Continuous Clock generation. By default, SCLK is only output while data is being
+ *    transmitted in synchronous mode. 0: Clock on character. In synchronous mode, SCLK cycles only when
+ *    characters are being sent on Un_TXD or to complete a character that is being received. 1:
+ *    Continuous clock. SCLK runs continuously in synchronous mode, allowing characters to be received on
+ *    Un_RxD independently from transmission on Un_TXD).
+ */
+#define USART_CTL_CC(x)                          (((uint32_t)(((uint32_t)(x)) << USART_CTL_CC_SHIFT)) & USART_CTL_CC_MASK)
+#define USART_CTL_CLRCCONRX_MASK                 (0x200U)
+#define USART_CTL_CLRCCONRX_SHIFT                (9U)
+/*! CLRCCONRX - Clear Continuous Clock. 0: No effect. No effect on the CC bit. 1: Auto-clear. The CC
+ *    bit is automatically cleared when a complete character has been received. This bit is cleared
+ *    at the same time.
+ */
+#define USART_CTL_CLRCCONRX(x)                   (((uint32_t)(((uint32_t)(x)) << USART_CTL_CLRCCONRX_SHIFT)) & USART_CTL_CLRCCONRX_MASK)
+#define USART_CTL_AUTOBAUD_MASK                  (0x10000U)
+#define USART_CTL_AUTOBAUD_SHIFT                 (16U)
+/*! AUTOBAUD - Autobaud enable. 0: Disabled. USART is in normal operating mode. 1: Enabled. USART is
+ *    in auto-baud mode. This bit should only be set when the USART receiver is idle. The first
+ *    start bit of RX is measured and used the update the BRG register to match the received data rate.
+ *    AUTOBAUD is cleared once this process is complete, or if there is an AERR.
+ */
+#define USART_CTL_AUTOBAUD(x)                    (((uint32_t)(((uint32_t)(x)) << USART_CTL_AUTOBAUD_SHIFT)) & USART_CTL_AUTOBAUD_MASK)
+/*! @} */
+
+/*! @name STAT - USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them. */
+/*! @{ */
+#define USART_STAT_RXIDLE_MASK                   (0x2U)
+#define USART_STAT_RXIDLE_SHIFT                  (1U)
+/*! RXIDLE - Receiver Idle. When 0, indicates that the receiver is currently in the process of
+ *    receiving data. When 1, indicates that the receiver is not currently in the process of receiving
+ *    data.
+ */
+#define USART_STAT_RXIDLE(x)                     (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXIDLE_SHIFT)) & USART_STAT_RXIDLE_MASK)
+#define USART_STAT_TXIDLE_MASK                   (0x8U)
+#define USART_STAT_TXIDLE_SHIFT                  (3U)
+/*! TXIDLE - Transmitter Idle. When 0, indicates that the transmitter is currently in the process of
+ *    sending data.When 1, indicate that the transmitter is not currently in the process of sending
+ *    data.
+ */
+#define USART_STAT_TXIDLE(x)                     (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXIDLE_SHIFT)) & USART_STAT_TXIDLE_MASK)
+#define USART_STAT_CTS_MASK                      (0x10U)
+#define USART_STAT_CTS_SHIFT                     (4U)
+/*! CTS - This bit reflects the current state of the CTS signal, regardless of the setting of the
+ *    CTSEN bit in the CFG register. This will be the value of the CTS input pin unless loopback mode
+ *    is enabled. Hence, reset value not applicable.
+ */
+#define USART_STAT_CTS(x)                        (((uint32_t)(((uint32_t)(x)) << USART_STAT_CTS_SHIFT)) & USART_STAT_CTS_MASK)
+#define USART_STAT_DELTACTS_MASK                 (0x20U)
+#define USART_STAT_DELTACTS_SHIFT                (5U)
+/*! DELTACTS - This bit is set when a change in the state is detected for the CTS flag above. This bit is cleared by software.
+ */
+#define USART_STAT_DELTACTS(x)                   (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTACTS_SHIFT)) & USART_STAT_DELTACTS_MASK)
+#define USART_STAT_TXDISSTAT_MASK                (0x40U)
+#define USART_STAT_TXDISSTAT_SHIFT               (6U)
+/*! TXDISSTAT - Transmitter Disabled Status flag. When 1, this bit indicates that the USART
+ *    transmitter is fully idle after being disabled via the TXDIS bit in the CFG register (TXDIS = 1).
+ */
+#define USART_STAT_TXDISSTAT(x)                  (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXDISSTAT_SHIFT)) & USART_STAT_TXDISSTAT_MASK)
+#define USART_STAT_RXBRK_MASK                    (0x400U)
+#define USART_STAT_RXBRK_SHIFT                   (10U)
+/*! RXBRK - Received Break. This bit reflects the current state of the receiver break detection
+ *    logic. It is set when the Un_RXD pin remains low for 16 bit times. Note that FRAMERRINT will also
+ *    be set when this condition occurs because the stop bit(s) for the character would be missing.
+ *    RXBRK is cleared when the Un_RXD pin goes high.
+ */
+#define USART_STAT_RXBRK(x)                      (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXBRK_SHIFT)) & USART_STAT_RXBRK_MASK)
+#define USART_STAT_DELTARXBRK_MASK               (0x800U)
+#define USART_STAT_DELTARXBRK_SHIFT              (11U)
+/*! DELTARXBRK - This bit is set when a change in the state of receiver break detection occurs. Cleared by software.
+ */
+#define USART_STAT_DELTARXBRK(x)                 (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTARXBRK_SHIFT)) & USART_STAT_DELTARXBRK_MASK)
+#define USART_STAT_START_MASK                    (0x1000U)
+#define USART_STAT_START_SHIFT                   (12U)
+/*! START - This bit is set when a start is detected on the receiver input. Its purpose is primarily
+ *    to allow wake-up from Deep sleep or Power-down mode immediately when a start is detected.
+ *    Cleared by software.
+ */
+#define USART_STAT_START(x)                      (((uint32_t)(((uint32_t)(x)) << USART_STAT_START_SHIFT)) & USART_STAT_START_MASK)
+#define USART_STAT_FRAMERRINT_MASK               (0x2000U)
+#define USART_STAT_FRAMERRINT_SHIFT              (13U)
+/*! FRAMERRINT - Framing Error interrupt flag. This flag is set when a character is received with a
+ *    missing stop bit at the expected location. This could be an indication of a baud rate or
+ *    configuration mismatch with the transmitting source.
+ */
+#define USART_STAT_FRAMERRINT(x)                 (((uint32_t)(((uint32_t)(x)) << USART_STAT_FRAMERRINT_SHIFT)) & USART_STAT_FRAMERRINT_MASK)
+#define USART_STAT_PARITYERRINT_MASK             (0x4000U)
+#define USART_STAT_PARITYERRINT_SHIFT            (14U)
+/*! PARITYERRINT - Parity Error interrupt flag. This flag is set when a parity error is detected in a received character.
+ */
+#define USART_STAT_PARITYERRINT(x)               (((uint32_t)(((uint32_t)(x)) << USART_STAT_PARITYERRINT_SHIFT)) & USART_STAT_PARITYERRINT_MASK)
+#define USART_STAT_RXNOISEINT_MASK               (0x8000U)
+#define USART_STAT_RXNOISEINT_SHIFT              (15U)
+/*! RXNOISEINT - Received Noise interrupt flag. Three samples of received data are taken in order to
+ *    determine the value of each received data bit, except in synchronous mode. This acts as a
+ *    noise filter if one sample disagrees. This flag is set when a received data bit contains one
+ *    disagreeing sample. This could indicate line noise, a baud rate or character format mismatch, or
+ *    loss of synchronization during data reception.
+ */
+#define USART_STAT_RXNOISEINT(x)                 (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXNOISEINT_SHIFT)) & USART_STAT_RXNOISEINT_MASK)
+#define USART_STAT_ABERR_MASK                    (0x10000U)
+#define USART_STAT_ABERR_SHIFT                   (16U)
+/*! ABERR - Auto baud Error. An auto baud error can occur if the BRG counts to its limit before the
+ *    end of the start bit that is being measured, essentially an auto baud time-out.
+ */
+#define USART_STAT_ABERR(x)                      (((uint32_t)(((uint32_t)(x)) << USART_STAT_ABERR_SHIFT)) & USART_STAT_ABERR_MASK)
+/*! @} */
+
+/*! @name INTENSET - Interrupt Enable read and Set register for USART (not FIFO) status. Contains individual interrupt enable bits for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */
+/*! @{ */
+#define USART_INTENSET_RXRDYEN_MASK              (0x1U)
+#define USART_INTENSET_RXRDYEN_SHIFT             (0U)
+/*! RXRDYEN - When 1, enables an interrupt when RX becomes ready
+ */
+#define USART_INTENSET_RXRDYEN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXRDYEN_SHIFT)) & USART_INTENSET_RXRDYEN_MASK)
+#define USART_INTENSET_TXRDTEN_MASK              (0x4U)
+#define USART_INTENSET_TXRDTEN_SHIFT             (2U)
+/*! TXRDTEN - When 1, enables an interrupt when TX becomes ready
+ */
+#define USART_INTENSET_TXRDTEN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXRDTEN_SHIFT)) & USART_INTENSET_TXRDTEN_MASK)
+#define USART_INTENSET_TXIDLEEN_MASK             (0x8U)
+#define USART_INTENSET_TXIDLEEN_SHIFT            (3U)
+/*! TXIDLEEN - When 1, enables an interrupt when the transmitter becomes idle (TXIDLE = 1).
+ */
+#define USART_INTENSET_TXIDLEEN(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXIDLEEN_SHIFT)) & USART_INTENSET_TXIDLEEN_MASK)
+#define USART_INTENSET_DELTACTSEN_MASK           (0x20U)
+#define USART_INTENSET_DELTACTSEN_SHIFT          (5U)
+/*! DELTACTSEN - Transmitter Idle. When 0, indicates that the transmitter is currently in the
+ *    process of sending data.When 1, indicate that the transmitter is not currently in the process of
+ *    sending data.
+ */
+#define USART_INTENSET_DELTACTSEN(x)             (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTACTSEN_SHIFT)) & USART_INTENSET_DELTACTSEN_MASK)
+#define USART_INTENSET_TXDISEN_MASK              (0x40U)
+#define USART_INTENSET_TXDISEN_SHIFT             (6U)
+/*! TXDISEN - When 1, enables an interrupt when the transmitter is fully disabled as indicated by
+ *    the TXDISINT flag in STAT. See description of the TXDISINT bit for details.
+ */
+#define USART_INTENSET_TXDISEN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXDISEN_SHIFT)) & USART_INTENSET_TXDISEN_MASK)
+#define USART_INTENSET_DELTARXBRKEN_MASK         (0x800U)
+#define USART_INTENSET_DELTARXBRKEN_SHIFT        (11U)
+/*! DELTARXBRKEN - When 1, enables an interrupt when a change of state has occurred in the detection
+ *    of a received break condition (break condition asserted or deasserted).
+ */
+#define USART_INTENSET_DELTARXBRKEN(x)           (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTARXBRKEN_SHIFT)) & USART_INTENSET_DELTARXBRKEN_MASK)
+#define USART_INTENSET_STARTEN_MASK              (0x1000U)
+#define USART_INTENSET_STARTEN_SHIFT             (12U)
+/*! STARTEN - When 1, enables an interrupt when a received start bit has been detected.
+ */
+#define USART_INTENSET_STARTEN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_STARTEN_SHIFT)) & USART_INTENSET_STARTEN_MASK)
+#define USART_INTENSET_FRAMERREN_MASK            (0x2000U)
+#define USART_INTENSET_FRAMERREN_SHIFT           (13U)
+/*! FRAMERREN - When 1, enables an interrupt when a framing error has been detected.
+ */
+#define USART_INTENSET_FRAMERREN(x)              (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_FRAMERREN_SHIFT)) & USART_INTENSET_FRAMERREN_MASK)
+#define USART_INTENSET_PARITYERREN_MASK          (0x4000U)
+#define USART_INTENSET_PARITYERREN_SHIFT         (14U)
+/*! PARITYERREN - When 1, enables an interrupt when a parity error has been detected.
+ */
+#define USART_INTENSET_PARITYERREN(x)            (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_PARITYERREN_SHIFT)) & USART_INTENSET_PARITYERREN_MASK)
+#define USART_INTENSET_RXNOISEEN_MASK            (0x8000U)
+#define USART_INTENSET_RXNOISEEN_SHIFT           (15U)
+/*! RXNOISEEN - When 1, enables an interrupt when noise is detected.
+ */
+#define USART_INTENSET_RXNOISEEN(x)              (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXNOISEEN_SHIFT)) & USART_INTENSET_RXNOISEEN_MASK)
+#define USART_INTENSET_ABERREN_MASK              (0x10000U)
+#define USART_INTENSET_ABERREN_SHIFT             (16U)
+/*! ABERREN - When 1, enables an interrupt when an auto baud error occurs.
+ */
+#define USART_INTENSET_ABERREN(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_ABERREN_SHIFT)) & USART_INTENSET_ABERREN_MASK)
+/*! @} */
+
+/*! @name INTENCLR - Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared. */
+/*! @{ */
+#define USART_INTENCLR_RXRDYCLR_MASK             (0x1U)
+#define USART_INTENCLR_RXRDYCLR_SHIFT            (0U)
+/*! RXRDYCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_RXRDYCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXRDYCLR_SHIFT)) & USART_INTENCLR_RXRDYCLR_MASK)
+#define USART_INTENCLR_TXRDYCLR_MASK             (0x4U)
+#define USART_INTENCLR_TXRDYCLR_SHIFT            (2U)
+/*! TXRDYCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_TXRDYCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXRDYCLR_SHIFT)) & USART_INTENCLR_TXRDYCLR_MASK)
+#define USART_INTENCLR_TXIDLECLR_MASK            (0x8U)
+#define USART_INTENCLR_TXIDLECLR_SHIFT           (3U)
+/*! TXIDLECLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_TXIDLECLR(x)              (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXIDLECLR_SHIFT)) & USART_INTENCLR_TXIDLECLR_MASK)
+#define USART_INTENCLR_DELTACTSCLR_MASK          (0x20U)
+#define USART_INTENCLR_DELTACTSCLR_SHIFT         (5U)
+/*! DELTACTSCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_DELTACTSCLR(x)            (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTACTSCLR_SHIFT)) & USART_INTENCLR_DELTACTSCLR_MASK)
+#define USART_INTENCLR_TXDISCLR_MASK             (0x40U)
+#define USART_INTENCLR_TXDISCLR_SHIFT            (6U)
+/*! TXDISCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_TXDISCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXDISCLR_SHIFT)) & USART_INTENCLR_TXDISCLR_MASK)
+#define USART_INTENCLR_DELTARXBRKCLR_MASK        (0x800U)
+#define USART_INTENCLR_DELTARXBRKCLR_SHIFT       (11U)
+/*! DELTARXBRKCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_DELTARXBRKCLR(x)          (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTARXBRKCLR_SHIFT)) & USART_INTENCLR_DELTARXBRKCLR_MASK)
+#define USART_INTENCLR_STARTCLR_MASK             (0x1000U)
+#define USART_INTENCLR_STARTCLR_SHIFT            (12U)
+/*! STARTCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_STARTCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_STARTCLR_SHIFT)) & USART_INTENCLR_STARTCLR_MASK)
+#define USART_INTENCLR_FRAMERRCLR_MASK           (0x2000U)
+#define USART_INTENCLR_FRAMERRCLR_SHIFT          (13U)
+/*! FRAMERRCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_FRAMERRCLR(x)             (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_FRAMERRCLR_SHIFT)) & USART_INTENCLR_FRAMERRCLR_MASK)
+#define USART_INTENCLR_PARITYERRCLR_MASK         (0x4000U)
+#define USART_INTENCLR_PARITYERRCLR_SHIFT        (14U)
+/*! PARITYERRCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_PARITYERRCLR(x)           (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_PARITYERRCLR_SHIFT)) & USART_INTENCLR_PARITYERRCLR_MASK)
+#define USART_INTENCLR_RXNOISECLR_MASK           (0x8000U)
+#define USART_INTENCLR_RXNOISECLR_SHIFT          (15U)
+/*! RXNOISECLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_RXNOISECLR(x)             (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXNOISECLR_SHIFT)) & USART_INTENCLR_RXNOISECLR_MASK)
+#define USART_INTENCLR_ABERRCLR_MASK             (0x10000U)
+#define USART_INTENCLR_ABERRCLR_SHIFT            (16U)
+/*! ABERRCLR - Writing 1 clears the corresponding bit in the INTENSET register.
+ */
+#define USART_INTENCLR_ABERRCLR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_ABERRCLR_SHIFT)) & USART_INTENCLR_ABERRCLR_MASK)
+/*! @} */
+
+/*! @name BRG - Baud Rate Generator register. 16-bit integer baud rate divisor value. */
+/*! @{ */
+#define USART_BRG_BRGVAL_MASK                    (0xFFFFU)
+#define USART_BRG_BRGVAL_SHIFT                   (0U)
+/*! BRGVAL - This value is used to divide the USART input clock to determine the baud rate, based on
+ *    the input clock from the FRG. 0: FCLK is used directly by the USART function. 1: FCLK is
+ *    divided by 2 before use by the USART function. 2: FCLK is divided by 3 before use by the USART
+ *    function. ... 0xFFFF = FCLK is divided by 65,536 before use by the USART function.
+ */
+#define USART_BRG_BRGVAL(x)                      (((uint32_t)(((uint32_t)(x)) << USART_BRG_BRGVAL_SHIFT)) & USART_BRG_BRGVAL_MASK)
+/*! @} */
+
+/*! @name INTSTAT - Interrupt status register. Reflects the status of interrupts that are currently enabled. */
+/*! @{ */
+#define USART_INTSTAT_RX_RDY_MASK                (0x1U)
+#define USART_INTSTAT_RX_RDY_SHIFT               (0U)
+/*! RX_RDY - Receiver Ready Status
+ */
+#define USART_INTSTAT_RX_RDY(x)                  (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RX_RDY_SHIFT)) & USART_INTSTAT_RX_RDY_MASK)
+#define USART_INTSTAT_RXIDLE_MASK                (0x2U)
+#define USART_INTSTAT_RXIDLE_SHIFT               (1U)
+/*! RXIDLE - Receiver Idle Status
+ */
+#define USART_INTSTAT_RXIDLE(x)                  (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXIDLE_SHIFT)) & USART_INTSTAT_RXIDLE_MASK)
+#define USART_INTSTAT_TX_RDY_MASK                (0x4U)
+#define USART_INTSTAT_TX_RDY_SHIFT               (2U)
+/*! TX_RDY - Transmitter Ready Status
+ */
+#define USART_INTSTAT_TX_RDY(x)                  (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TX_RDY_SHIFT)) & USART_INTSTAT_TX_RDY_MASK)
+#define USART_INTSTAT_TXIDLE_MASK                (0x8U)
+#define USART_INTSTAT_TXIDLE_SHIFT               (3U)
+/*! TXIDLE - Transmitter Idle status.
+ */
+#define USART_INTSTAT_TXIDLE(x)                  (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXIDLE_SHIFT)) & USART_INTSTAT_TXIDLE_MASK)
+#define USART_INTSTAT_DELTACTS_MASK              (0x20U)
+#define USART_INTSTAT_DELTACTS_SHIFT             (5U)
+/*! DELTACTS - This bit is set when a change in the state of the CTS input is detected.
+ */
+#define USART_INTSTAT_DELTACTS(x)                (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTACTS_SHIFT)) & USART_INTSTAT_DELTACTS_MASK)
+#define USART_INTSTAT_TXDIS_MASK                 (0x40U)
+#define USART_INTSTAT_TXDIS_SHIFT                (6U)
+/*! TXDIS - Transmitter Disabled Interrupt flag.
+ */
+#define USART_INTSTAT_TXDIS(x)                   (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXDIS_SHIFT)) & USART_INTSTAT_TXDIS_MASK)
+#define USART_INTSTAT_DELTARXBRK_MASK            (0x800U)
+#define USART_INTSTAT_DELTARXBRK_SHIFT           (11U)
+/*! DELTARXBRK - This bit is set when a change in the state of receiver break detection occurs.
+ */
+#define USART_INTSTAT_DELTARXBRK(x)              (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTARXBRK_SHIFT)) & USART_INTSTAT_DELTARXBRK_MASK)
+#define USART_INTSTAT_START_MASK                 (0x1000U)
+#define USART_INTSTAT_START_SHIFT                (12U)
+/*! START - This bit is set when a start is detected on the receiver input.
+ */
+#define USART_INTSTAT_START(x)                   (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_START_SHIFT)) & USART_INTSTAT_START_MASK)
+#define USART_INTSTAT_FRAMERR_MASK               (0x2000U)
+#define USART_INTSTAT_FRAMERR_SHIFT              (13U)
+/*! FRAMERR - Framing Error interrupt flag.
+ */
+#define USART_INTSTAT_FRAMERR(x)                 (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_FRAMERR_SHIFT)) & USART_INTSTAT_FRAMERR_MASK)
+#define USART_INTSTAT_PARITYERR_MASK             (0x4000U)
+#define USART_INTSTAT_PARITYERR_SHIFT            (14U)
+/*! PARITYERR - Parity Error interrupt flag.
+ */
+#define USART_INTSTAT_PARITYERR(x)               (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_PARITYERR_SHIFT)) & USART_INTSTAT_PARITYERR_MASK)
+#define USART_INTSTAT_RXNOISE_MASK               (0x8000U)
+#define USART_INTSTAT_RXNOISE_SHIFT              (15U)
+/*! RXNOISE - Received Noise interrupt flag.
+ */
+#define USART_INTSTAT_RXNOISE(x)                 (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXNOISE_SHIFT)) & USART_INTSTAT_RXNOISE_MASK)
+#define USART_INTSTAT_ABERR_MASK                 (0x10000U)
+#define USART_INTSTAT_ABERR_SHIFT                (16U)
+/*! ABERR - Auto baud Error Interrupt flag.
+ */
+#define USART_INTSTAT_ABERR(x)                   (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_ABERR_SHIFT)) & USART_INTSTAT_ABERR_MASK)
+/*! @} */
+
+/*! @name OSR - Oversample selection register for asynchronous communication. */
+/*! @{ */
+#define USART_OSR_OSRVAL_MASK                    (0xFU)
+#define USART_OSR_OSRVAL_SHIFT                   (0U)
+/*! OSRVAL - Oversample Selection Value. 0 to 3: not supported. 0x4: 5 function clocks are used to
+ *    transmit and receive each data bit. 0x5: 6 function clocks are used to transmit and receive
+ *    each data bit. ... 0xF: 16 function clocks are used to transmit and receive each data bit.
+ */
+#define USART_OSR_OSRVAL(x)                      (((uint32_t)(((uint32_t)(x)) << USART_OSR_OSRVAL_SHIFT)) & USART_OSR_OSRVAL_MASK)
+/*! @} */
+
+/*! @name ADDR - Address register for automatic address matching. */
+/*! @{ */
+#define USART_ADDR_ADDRESS_MASK                  (0xFFU)
+#define USART_ADDR_ADDRESS_SHIFT                 (0U)
+/*! ADDRESS - 8-bit address used with automatic address matching. Used when address detection is
+ *    enabled (ADDRDET in CTL = 1) and automatic address matching is enabled (AUTOADDR in CFG = 1).
+ */
+#define USART_ADDR_ADDRESS(x)                    (((uint32_t)(((uint32_t)(x)) << USART_ADDR_ADDRESS_SHIFT)) & USART_ADDR_ADDRESS_MASK)
+/*! @} */
+
+/*! @name FIFOCFG - FIFO configuration and enable register. */
+/*! @{ */
+#define USART_FIFOCFG_ENABLETX_MASK              (0x1U)
+#define USART_FIFOCFG_ENABLETX_SHIFT             (0U)
+/*! ENABLETX - Enable the transmit FIFO. 0: The transmit FIFO is not enabled. 1: The transmit FIFO
+ *    is enabled. This is automatically enabled when PSELID.PERSEL is set to 1 to configure the USART
+ *    functionality.
+ */
+#define USART_FIFOCFG_ENABLETX(x)                (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_ENABLETX_SHIFT)) & USART_FIFOCFG_ENABLETX_MASK)
+#define USART_FIFOCFG_ENABLERX_MASK              (0x2U)
+#define USART_FIFOCFG_ENABLERX_SHIFT             (1U)
+/*! ENABLERX - Enable the receive FIFO. 0: The receive FIFO is not enabled. 1: The receive FIFO is
+ *    enabled. This is automatically enabled when PSELID.PERSEL is set to 1 to configure the USART
+ *    functionality.
+ */
+#define USART_FIFOCFG_ENABLERX(x)                (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_ENABLERX_SHIFT)) & USART_FIFOCFG_ENABLERX_MASK)
+#define USART_FIFOCFG_SIZE_MASK                  (0x30U)
+#define USART_FIFOCFG_SIZE_SHIFT                 (4U)
+/*! SIZE - FIFO size configuration. This is a read-only field. 0x0 = FIFO is configured as 4 entries
+ *    of 8 bits. 0x1, 0x2, 0x3 = not applicable.
+ */
+#define USART_FIFOCFG_SIZE(x)                    (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_SIZE_SHIFT)) & USART_FIFOCFG_SIZE_MASK)
+#define USART_FIFOCFG_DMATX_MASK                 (0x1000U)
+#define USART_FIFOCFG_DMATX_SHIFT                (12U)
+/*! DMATX - DMA configuration for transmit. 0: DMA is not used for the transmit function. 1:
+ *    Generate a DMA request for the transmit function if the FIFO is not full. Generally, data interrupts
+ *    would be disabled if DMA is enabled
+ */
+#define USART_FIFOCFG_DMATX(x)                   (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_DMATX_SHIFT)) & USART_FIFOCFG_DMATX_MASK)
+#define USART_FIFOCFG_DMARX_MASK                 (0x2000U)
+#define USART_FIFOCFG_DMARX_SHIFT                (13U)
+/*! DMARX - DMA configuration for receive. 0: DMA is not used for the receive function. 1: Generate
+ *    a DMA request for the receive function if the FIFO is not empty. Generally, data interrupts
+ *    would be disabled if DMA is enabled.
+ */
+#define USART_FIFOCFG_DMARX(x)                   (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_DMARX_SHIFT)) & USART_FIFOCFG_DMARX_MASK)
+#define USART_FIFOCFG_WAKETX_MASK                (0x4000U)
+#define USART_FIFOCFG_WAKETX_SHIFT               (14U)
+/*! WAKETX - Wakeup for transmit FIFO level. This allows the device to be woken from reduced power
+ *    modes (up to power-down, as long as the peripheral function works in that power mode) without
+ *    enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The
+ *    CPU will remain stopped until woken by another cause, such as DMA completion. 0: Only enabled
+ *    interrupts will wake up the device form reduced power modes. 1: A device wake-up for DMA will
+ *    occur if the transmit FIFO level reaches the value specified by TXLVL in FIFOTRIG, even when the
+ *    TXLVL interrupt is not enabled.
+ */
+#define USART_FIFOCFG_WAKETX(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_WAKETX_SHIFT)) & USART_FIFOCFG_WAKETX_MASK)
+#define USART_FIFOCFG_WAKERX_MASK                (0x8000U)
+#define USART_FIFOCFG_WAKERX_SHIFT               (15U)
+/*! WAKERX - Wakeup for receive FIFO level. This allows the device to be woken from reduced power
+ *    modes (up to power-down, as long as the peripheral function works in that power mode) without
+ *    enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The CPU
+ *    will remain stopped until woken by another cause, such as DMA completion. 0: Only enabled
+ *    interrupts will wake up the device form reduced power modes. 1: A device wake-up for DMA will
+ *    occur if the receive FIFO level reaches the value specified by RXLVL in FIFOTRIG, even when the
+ *    RXLVL interrupt is not enabled.
+ */
+#define USART_FIFOCFG_WAKERX(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_WAKERX_SHIFT)) & USART_FIFOCFG_WAKERX_MASK)
+#define USART_FIFOCFG_EMPTYTX_MASK               (0x10000U)
+#define USART_FIFOCFG_EMPTYTX_SHIFT              (16U)
+/*! EMPTYTX - Empty command for the transmit FIFO. When a 1 is written to this bit, the TX FIFO is emptied.
+ */
+#define USART_FIFOCFG_EMPTYTX(x)                 (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_EMPTYTX_SHIFT)) & USART_FIFOCFG_EMPTYTX_MASK)
+#define USART_FIFOCFG_EMPTYRX_MASK               (0x20000U)
+#define USART_FIFOCFG_EMPTYRX_SHIFT              (17U)
+/*! EMPTYRX - Empty command for the receive FIFO. When a 1 is written to this bit, the RX FIFO is emptied.
+ */
+#define USART_FIFOCFG_EMPTYRX(x)                 (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_EMPTYRX_SHIFT)) & USART_FIFOCFG_EMPTYRX_MASK)
+#define USART_FIFOCFG_POPDBG_MASK                (0x40000U)
+#define USART_FIFOCFG_POPDBG_SHIFT               (18U)
+/*! POPDBG - Pop FIFO for debug reads.
+ */
+#define USART_FIFOCFG_POPDBG(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_POPDBG_SHIFT)) & USART_FIFOCFG_POPDBG_MASK)
+/*! @} */
+
+/*! @name FIFOSTAT - FIFO status register. */
+/*! @{ */
+#define USART_FIFOSTAT_TXERR_MASK                (0x1U)
+#define USART_FIFOSTAT_TXERR_SHIFT               (0U)
+/*! TXERR - TX FIFO error. Will be set if a transmit FIFO error occurs. This could be an overflow
+ *    caused by pushing data into a full FIFO, or by an underflow if the FIFO is empty when data is
+ *    needed. Cleared by writing a 1 to this bit.
+ */
+#define USART_FIFOSTAT_TXERR(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXERR_SHIFT)) & USART_FIFOSTAT_TXERR_MASK)
+#define USART_FIFOSTAT_RXERR_MASK                (0x2U)
+#define USART_FIFOSTAT_RXERR_SHIFT               (1U)
+/*! RXERR - RX FIFO error. Will be set if a receive FIFO overflow occurs, caused by software or DMA
+ *    not emptying the FIFO fast enough. Cleared by writing a 1 to this bit.
+ */
+#define USART_FIFOSTAT_RXERR(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXERR_SHIFT)) & USART_FIFOSTAT_RXERR_MASK)
+#define USART_FIFOSTAT_PERINT_MASK               (0x8U)
+#define USART_FIFOSTAT_PERINT_SHIFT              (3U)
+/*! PERINT - Peripheral interrupt. When 1, this indicates that the peripheral function has asserted
+ *    an interrupt. The details can be found by reading the peripheral s STAT register.
+ */
+#define USART_FIFOSTAT_PERINT(x)                 (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_PERINT_SHIFT)) & USART_FIFOSTAT_PERINT_MASK)
+#define USART_FIFOSTAT_TXEMPTY_MASK              (0x10U)
+#define USART_FIFOSTAT_TXEMPTY_SHIFT             (4U)
+/*! TXEMPTY - Transmit FIFO empty. When 1, the transmit FIFO is empty. The peripheral may still be processing the last piece of data.
+ */
+#define USART_FIFOSTAT_TXEMPTY(x)                (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXEMPTY_SHIFT)) & USART_FIFOSTAT_TXEMPTY_MASK)
+#define USART_FIFOSTAT_TXNOTFULL_MASK            (0x20U)
+#define USART_FIFOSTAT_TXNOTFULL_SHIFT           (5U)
+/*! TXNOTFULL - Transmit FIFO not full. When 1, the transmit FIFO is not full, so more data can be
+ *    written. When 0, the transmit FIFO is full and another write would cause it to overflow.
+ */
+#define USART_FIFOSTAT_TXNOTFULL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXNOTFULL_SHIFT)) & USART_FIFOSTAT_TXNOTFULL_MASK)
+#define USART_FIFOSTAT_RXNOTEMPTY_MASK           (0x40U)
+#define USART_FIFOSTAT_RXNOTEMPTY_SHIFT          (6U)
+/*! RXNOTEMPTY - Receive FIFO not empty. When 1, the receive FIFO is not empty, so data can be read. When 0, the receive FIFO is empty.
+ */
+#define USART_FIFOSTAT_RXNOTEMPTY(x)             (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXNOTEMPTY_SHIFT)) & USART_FIFOSTAT_RXNOTEMPTY_MASK)
+#define USART_FIFOSTAT_RXFULL_MASK               (0x80U)
+#define USART_FIFOSTAT_RXFULL_SHIFT              (7U)
+/*! RXFULL - Receive FIFO full. When 1, the receive FIFO is full. Data needs to be read out to
+ *    prevent the peripheral from causing an overflow.
+ */
+#define USART_FIFOSTAT_RXFULL(x)                 (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXFULL_SHIFT)) & USART_FIFOSTAT_RXFULL_MASK)
+#define USART_FIFOSTAT_TXLVL_MASK                (0x1F00U)
+#define USART_FIFOSTAT_TXLVL_SHIFT               (8U)
+/*! TXLVL - Transmit FIFO current level. A 0 means the TX FIFO is currently empty, and the TXEMPTY
+ *    and TXNOTFULL flags will be 1. Other values tell how much data is actually in the TX FIFO at
+ *    the point where the read occurs. If the TX FIFO is full, the TXEMPTY and TXNOTFULL flags will be
+ *    0.
+ */
+#define USART_FIFOSTAT_TXLVL(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXLVL_SHIFT)) & USART_FIFOSTAT_TXLVL_MASK)
+#define USART_FIFOSTAT_RXLVL_MASK                (0x1F0000U)
+#define USART_FIFOSTAT_RXLVL_SHIFT               (16U)
+/*! RXLVL - Receive FIFO current level. A 0 means the RX FIFO is currently empty, and the RXFULL and
+ *    RXNOTEMPTY flags will be 0. Other values tell how much data is actually in the RX FIFO at the
+ *    point where the read occurs. If the RX FIFO is full, the RXFULL and RXNOTEMPTY flags will be
+ *    1.
+ */
+#define USART_FIFOSTAT_RXLVL(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXLVL_SHIFT)) & USART_FIFOSTAT_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOTRIG - FIFO trigger settings for interrupt and DMA request. */
+/*! @{ */
+#define USART_FIFOTRIG_TXLVLENA_MASK             (0x1U)
+#define USART_FIFOTRIG_TXLVLENA_SHIFT            (0U)
+/*! TXLVLENA - Transmit FIFO level trigger enable. This trigger will become an interrupt if enabled
+ *    in FIFOINTENSET, or a DMA trigger if DMATX in FIFOCFG is set. 0: Transmit FIFO level does not
+ *    generate a FIFO level trigger. 1: An interrupt will be generated if the transmit FIFO level
+ *    reaches the value specified by the TXLVL field in this register.
+ */
+#define USART_FIFOTRIG_TXLVLENA(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_TXLVLENA_SHIFT)) & USART_FIFOTRIG_TXLVLENA_MASK)
+#define USART_FIFOTRIG_RXLVLENA_MASK             (0x2U)
+#define USART_FIFOTRIG_RXLVLENA_SHIFT            (1U)
+/*! RXLVLENA - Receive FIFO level trigger enable. This trigger will become an interrupt if enabled
+ *    in FIFOINTENSET, or a DMA trigger if DMARX in FIFOCFG is set. 0: Receive FIFO level does not
+ *    generate a FIFO level trigger. 1: An interrupt will be generated if the receive FIFO level
+ *    reaches the value specified by the RXLVL field in this register.
+ */
+#define USART_FIFOTRIG_RXLVLENA(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_RXLVLENA_SHIFT)) & USART_FIFOTRIG_RXLVLENA_MASK)
+#define USART_FIFOTRIG_TXLVL_MASK                (0xF00U)
+#define USART_FIFOTRIG_TXLVL_SHIFT               (8U)
+/*! TXLVL - Transmit FIFO level trigger point. This field is used only when TXLVLENA = 1. 0: trigger
+ *    when the TX FIFO becomes empty. 1: trigger when the TX FIFO level decreases to one entry. ...
+ *    3: trigger when the TX FIFO level decreases to 3 entries (is no longer full).
+ */
+#define USART_FIFOTRIG_TXLVL(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_TXLVL_SHIFT)) & USART_FIFOTRIG_TXLVL_MASK)
+#define USART_FIFOTRIG_RXLVL_MASK                (0xF0000U)
+#define USART_FIFOTRIG_RXLVL_SHIFT               (16U)
+/*! RXLVL - Receive FIFO level trigger point. The RX FIFO level is checked when a new piece of data
+ *    is received. This field is used only when RXLVLENA = 1. 0: trigger when the RX FIFO has
+ *    received one entry (is no longer empty). 1: trigger when the RX FIFO has received two entries. ...
+ *    3: trigger when the RX FIFO has received 4 entries (has become full).
+ */
+#define USART_FIFOTRIG_RXLVL(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_RXLVL_SHIFT)) & USART_FIFOTRIG_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTENSET - FIFO interrupt enable set (enable) and read register. */
+/*! @{ */
+#define USART_FIFOINTENSET_TXERR_MASK            (0x1U)
+#define USART_FIFOINTENSET_TXERR_SHIFT           (0U)
+/*! TXERR - Determines whether an interrupt occurs when a transmit error occurs, based on the TXERR
+ *    flag in the FIFOSTAT register. 0: No interrupt will be generated for a transmit error. 1: An
+ *    interrupt will be generated when a transmit error occurs.
+ */
+#define USART_FIFOINTENSET_TXERR(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_TXERR_SHIFT)) & USART_FIFOINTENSET_TXERR_MASK)
+#define USART_FIFOINTENSET_RXERR_MASK            (0x2U)
+#define USART_FIFOINTENSET_RXERR_SHIFT           (1U)
+/*! RXERR - Determines whether an interrupt occurs when a receive error occurs, based on the RXERR
+ *    flag in the FIFOSTAT register. 0: No interrupt will be generated for a receive error. 1: An
+ *    interrupt will be generated when a receive error occurs.
+ */
+#define USART_FIFOINTENSET_RXERR(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_RXERR_SHIFT)) & USART_FIFOINTENSET_RXERR_MASK)
+#define USART_FIFOINTENSET_TXLVL_MASK            (0x4U)
+#define USART_FIFOINTENSET_TXLVL_SHIFT           (2U)
+/*! TXLVL - Determines whether an interrupt occurs when a the transmit FIFO reaches the level
+ *    specified by the TXLVL field in the FIFOTRIG register. 0: No interrupt will be generated based on
+ *    the TX FIFO level. 1: TXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated when
+ *    the TX FIFO level decreases to the level specified by TXLVL in the FIFOTRIG register.
+ */
+#define USART_FIFOINTENSET_TXLVL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_TXLVL_SHIFT)) & USART_FIFOINTENSET_TXLVL_MASK)
+#define USART_FIFOINTENSET_RXLVL_MASK            (0x8U)
+#define USART_FIFOINTENSET_RXLVL_SHIFT           (3U)
+/*! RXLVL - Determines whether an interrupt occurs when a the receive FIFO reaches the level
+ *    specified by the TXLVL field in the FIFOTRIG register. 0: No interrupt will be generated based on the
+ *    RX FIFO level. 1: If RXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated
+ *    when the when the RX FIFO level increases to the level specified by RXLVL in the FIFOTRIG
+ *    register.
+ */
+#define USART_FIFOINTENSET_RXLVL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_RXLVL_SHIFT)) & USART_FIFOINTENSET_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTENCLR - FIFO interrupt enable clear (disable) and read register. */
+/*! @{ */
+#define USART_FIFOINTENCLR_TXERR_MASK            (0x1U)
+#define USART_FIFOINTENCLR_TXERR_SHIFT           (0U)
+/*! TXERR - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define USART_FIFOINTENCLR_TXERR(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_TXERR_SHIFT)) & USART_FIFOINTENCLR_TXERR_MASK)
+#define USART_FIFOINTENCLR_RXERR_MASK            (0x2U)
+#define USART_FIFOINTENCLR_RXERR_SHIFT           (1U)
+/*! RXERR - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define USART_FIFOINTENCLR_RXERR(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_RXERR_SHIFT)) & USART_FIFOINTENCLR_RXERR_MASK)
+#define USART_FIFOINTENCLR_TXLVL_MASK            (0x4U)
+#define USART_FIFOINTENCLR_TXLVL_SHIFT           (2U)
+/*! TXLVL - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define USART_FIFOINTENCLR_TXLVL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_TXLVL_SHIFT)) & USART_FIFOINTENCLR_TXLVL_MASK)
+#define USART_FIFOINTENCLR_RXLVL_MASK            (0x8U)
+#define USART_FIFOINTENCLR_RXLVL_SHIFT           (3U)
+/*! RXLVL - Writing 1 clears the corresponding bit in the FIFOINTENSET register
+ */
+#define USART_FIFOINTENCLR_RXLVL(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_RXLVL_SHIFT)) & USART_FIFOINTENCLR_RXLVL_MASK)
+/*! @} */
+
+/*! @name FIFOINTSTAT - FIFO interrupt status register. Reflects the status of interrupts that are currently enabled. */
+/*! @{ */
+#define USART_FIFOINTSTAT_TXERR_MASK             (0x1U)
+#define USART_FIFOINTSTAT_TXERR_SHIFT            (0U)
+/*! TXERR - TX FIFO error.
+ */
+#define USART_FIFOINTSTAT_TXERR(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_TXERR_SHIFT)) & USART_FIFOINTSTAT_TXERR_MASK)
+#define USART_FIFOINTSTAT_RXERR_MASK             (0x2U)
+#define USART_FIFOINTSTAT_RXERR_SHIFT            (1U)
+/*! RXERR - RX FIFO error.
+ */
+#define USART_FIFOINTSTAT_RXERR(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_RXERR_SHIFT)) & USART_FIFOINTSTAT_RXERR_MASK)
+#define USART_FIFOINTSTAT_TXLVL_MASK             (0x4U)
+#define USART_FIFOINTSTAT_TXLVL_SHIFT            (2U)
+/*! TXLVL - Transmit FIFO level interrupt.
+ */
+#define USART_FIFOINTSTAT_TXLVL(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_TXLVL_SHIFT)) & USART_FIFOINTSTAT_TXLVL_MASK)
+#define USART_FIFOINTSTAT_RXLVL_MASK             (0x8U)
+#define USART_FIFOINTSTAT_RXLVL_SHIFT            (3U)
+/*! RXLVL - Receive FIFO level interrupt.
+ */
+#define USART_FIFOINTSTAT_RXLVL(x)               (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_RXLVL_SHIFT)) & USART_FIFOINTSTAT_RXLVL_MASK)
+#define USART_FIFOINTSTAT_PERINT_MASK            (0x10U)
+#define USART_FIFOINTSTAT_PERINT_SHIFT           (4U)
+/*! PERINT - Peripheral interrupt.
+ */
+#define USART_FIFOINTSTAT_PERINT(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_PERINT_SHIFT)) & USART_FIFOINTSTAT_PERINT_MASK)
+/*! @} */
+
+/*! @name FIFOWR - FIFO write data. Used to write values to be transmitted to the FIFO. */
+/*! @{ */
+#define USART_FIFOWR_TXDATA_MASK                 (0x1FFU)
+#define USART_FIFOWR_TXDATA_SHIFT                (0U)
+/*! TXDATA - Transmit data to the FIFO. The number of bits used depends on the DATALEN
+ */
+#define USART_FIFOWR_TXDATA(x)                   (((uint32_t)(((uint32_t)(x)) << USART_FIFOWR_TXDATA_SHIFT)) & USART_FIFOWR_TXDATA_MASK)
+/*! @} */
+
+/*! @name FIFORD - FIFO read data. Used to read values that have been received. */
+/*! @{ */
+#define USART_FIFORD_RXDATA_MASK                 (0x1FFU)
+#define USART_FIFORD_RXDATA_SHIFT                (0U)
+/*! RXDATA - Received data from the FIFO. The number of bits used depends on the DATALEN and PARITYSEL settings.
+ */
+#define USART_FIFORD_RXDATA(x)                   (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_RXDATA_SHIFT)) & USART_FIFORD_RXDATA_MASK)
+#define USART_FIFORD_FRAMERR_MASK                (0x2000U)
+#define USART_FIFORD_FRAMERR_SHIFT               (13U)
+/*! FRAMERR - Framing Error status flag. This bit reflects the status for the data it is read along
+ *    with from the FIFO, and indicates that the character was received with a missing stop bit at
+ *    the expected location. This could be an indication of a baud rate or configuration mismatch
+ *    with the transmitting source.
+ */
+#define USART_FIFORD_FRAMERR(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_FRAMERR_SHIFT)) & USART_FIFORD_FRAMERR_MASK)
+#define USART_FIFORD_PARITYERR_MASK              (0x4000U)
+#define USART_FIFORD_PARITYERR_SHIFT             (14U)
+/*! PARITYERR - Parity Error status flag. This bit reflects the status for the data it is read along
+ *    with from the FIFO. This bit will be set when a parity error is detected in a received
+ *    character.
+ */
+#define USART_FIFORD_PARITYERR(x)                (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_PARITYERR_SHIFT)) & USART_FIFORD_PARITYERR_MASK)
+#define USART_FIFORD_RXNOISE_MASK                (0x8000U)
+#define USART_FIFORD_RXNOISE_SHIFT               (15U)
+/*! RXNOISE - Received Noise flag.
+ */
+#define USART_FIFORD_RXNOISE(x)                  (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_RXNOISE_SHIFT)) & USART_FIFORD_RXNOISE_MASK)
+/*! @} */
+
+/*! @name FIFORDNOPOP - FIFO data read with no FIFO pop. This register acts in exactly the same way as FIFORD, except that it supplies data from the top of the FIFO without popping the FIFO (i.e. leaving the FIFO state unchanged). This could be used to allow system software to observe incoming data without interfering with the peripheral driver. */
+/*! @{ */
+#define USART_FIFORDNOPOP_RXDATA_MASK            (0x1FFU)
+#define USART_FIFORDNOPOP_RXDATA_SHIFT           (0U)
+/*! RXDATA - Received data from the FIFO. The number of bits used depends on the DATALEN and PARITYSEL settings.
+ */
+#define USART_FIFORDNOPOP_RXDATA(x)              (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_RXDATA_SHIFT)) & USART_FIFORDNOPOP_RXDATA_MASK)
+#define USART_FIFORDNOPOP_FRAMERR_MASK           (0x2000U)
+#define USART_FIFORDNOPOP_FRAMERR_SHIFT          (13U)
+/*! FRAMERR - Framing Error status flag. This bit reflects the status for the data it is read along
+ *    with from the FIFO, and indicates that the character was received with a missing stop bit at
+ *    the expected location. This could be an indication of a baud rate or configuration mismatch
+ *    with the transmitting source.
+ */
+#define USART_FIFORDNOPOP_FRAMERR(x)             (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_FRAMERR_SHIFT)) & USART_FIFORDNOPOP_FRAMERR_MASK)
+#define USART_FIFORDNOPOP_PARITYERR_MASK         (0x4000U)
+#define USART_FIFORDNOPOP_PARITYERR_SHIFT        (14U)
+/*! PARITYERR - Parity Error status flag. This bit reflects the status for the data it is read along
+ *    with from the FIFO. This bit will be set when a parity error is detected in a received
+ *    character.
+ */
+#define USART_FIFORDNOPOP_PARITYERR(x)           (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_PARITYERR_SHIFT)) & USART_FIFORDNOPOP_PARITYERR_MASK)
+#define USART_FIFORDNOPOP_RXNOISE_MASK           (0x8000U)
+#define USART_FIFORDNOPOP_RXNOISE_SHIFT          (15U)
+/*! RXNOISE - Received Noise flag.
+ */
+#define USART_FIFORDNOPOP_RXNOISE(x)             (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_RXNOISE_SHIFT)) & USART_FIFORDNOPOP_RXNOISE_MASK)
+/*! @} */
+
+/*! @name PSELID - Flexcomm ID and peripheral function select register */
+/*! @{ */
+#define USART_PSELID_PERSEL_MASK                 (0x7U)
+#define USART_PSELID_PERSEL_SHIFT                (0U)
+/*! PERSEL - Peripheral Select. This field is writable by software. 0x0: No peripheral selected.
+ *    0x1: USART function selected. 0x2 - 0x7: Reserved.
+ */
+#define USART_PSELID_PERSEL(x)                   (((uint32_t)(((uint32_t)(x)) << USART_PSELID_PERSEL_SHIFT)) & USART_PSELID_PERSEL_MASK)
+#define USART_PSELID_LOCK_MASK                   (0x8U)
+#define USART_PSELID_LOCK_SHIFT                  (3U)
+/*! LOCK - Lock the peripheral select. This field is writable by software. 0: Peripheral select can
+ *    be changed by software. 1: Peripheral select is locked and cannot be changed until this
+ *    Flexcomm or the entire device is reset.
+ */
+#define USART_PSELID_LOCK(x)                     (((uint32_t)(((uint32_t)(x)) << USART_PSELID_LOCK_SHIFT)) & USART_PSELID_LOCK_MASK)
+#define USART_PSELID_USARTPRESENT_MASK           (0x10U)
+#define USART_PSELID_USARTPRESENT_SHIFT          (4U)
+/*! USARTPRESENT - USART present indicator. This field is Read-only. 0: This Flexcomm does not
+ *    include the USART function. 1: This Flexcomm includes the USART function.
+ */
+#define USART_PSELID_USARTPRESENT(x)             (((uint32_t)(((uint32_t)(x)) << USART_PSELID_USARTPRESENT_SHIFT)) & USART_PSELID_USARTPRESENT_MASK)
+#define USART_PSELID_ID_MASK                     (0xFFFFF000U)
+#define USART_PSELID_ID_SHIFT                    (12U)
+/*! ID - Flexcomm ID.
+ */
+#define USART_PSELID_ID(x)                       (((uint32_t)(((uint32_t)(x)) << USART_PSELID_ID_SHIFT)) & USART_PSELID_ID_MASK)
+/*! @} */
+
+/*! @name ID - USART Module Identifier */
+/*! @{ */
+#define USART_ID_APERTURE_MASK                   (0xFFU)
+#define USART_ID_APERTURE_SHIFT                  (0U)
+/*! APERTURE - Aperture i.e. number minus 1 of consecutive packets 4 Kbytes reserved for this IP
+ */
+#define USART_ID_APERTURE(x)                     (((uint32_t)(((uint32_t)(x)) << USART_ID_APERTURE_SHIFT)) & USART_ID_APERTURE_MASK)
+#define USART_ID_MIN_REV_MASK                    (0xF00U)
+#define USART_ID_MIN_REV_SHIFT                   (8U)
+/*! MIN_REV - Minor revision i.e. with no software consequences
+ */
+#define USART_ID_MIN_REV(x)                      (((uint32_t)(((uint32_t)(x)) << USART_ID_MIN_REV_SHIFT)) & USART_ID_MIN_REV_MASK)
+#define USART_ID_MAJ_REV_MASK                    (0xF000U)
+#define USART_ID_MAJ_REV_SHIFT                   (12U)
+/*! MAJ_REV - Major revision i.e. implies software modifications
+ */
+#define USART_ID_MAJ_REV(x)                      (((uint32_t)(((uint32_t)(x)) << USART_ID_MAJ_REV_SHIFT)) & USART_ID_MAJ_REV_MASK)
+#define USART_ID_ID_MASK                         (0xFFFF0000U)
+#define USART_ID_ID_SHIFT                        (16U)
+/*! ID - Identifier. This is the unique identifier of the module
+ */
+#define USART_ID_ID(x)                           (((uint32_t)(((uint32_t)(x)) << USART_ID_ID_SHIFT)) & USART_ID_ID_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group USART_Register_Masks */
+
+
+/* USART - Peripheral instance base addresses */
+/** Peripheral USART0 base address */
+#define USART0_BASE                              (0x4008B000u)
+/** Peripheral USART0 base pointer */
+#define USART0                                   ((USART_Type *)USART0_BASE)
+/** Peripheral USART1 base address */
+#define USART1_BASE                              (0x4008C000u)
+/** Peripheral USART1 base pointer */
+#define USART1                                   ((USART_Type *)USART1_BASE)
+/** Array initializer of USART peripheral base addresses */
+#define USART_BASE_ADDRS                         { USART0_BASE, USART1_BASE }
+/** Array initializer of USART peripheral base pointers */
+#define USART_BASE_PTRS                          { USART0, USART1 }
+/** Interrupt vectors for the USART peripheral type */
+#define USART_IRQS                               { FLEXCOMM0_IRQn, FLEXCOMM1_IRQn }
+
+/*!
+ * @}
+ */ /* end of group USART_Peripheral_Access_Layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- WWDT Peripheral Access Layer
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup WWDT_Peripheral_Access_Layer WWDT Peripheral Access Layer
+ * @{
+ */
+
+/** WWDT - Register Layout Typedef */
+typedef struct {
+  __IO uint32_t MOD;                               /**< Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer., offset: 0x0 */
+  __IO uint32_t TC;                                /**< Watchdog timer constant register. This 24-bit register determines the time-out value., offset: 0x4 */
+  __O  uint32_t FEED;                              /**< Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in TC., offset: 0x8 */
+  __I  uint32_t TV;                                /**< Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer., offset: 0xC */
+       uint8_t RESERVED_0[4];
+  __IO uint32_t WARNINT;                           /**< Watchdog Warning Interrupt compare value., offset: 0x14 */
+  __IO uint32_t WINDOW;                            /**< Watchdog Window compare value., offset: 0x18 */
+} WWDT_Type;
+
+/* ----------------------------------------------------------------------------
+   -- WWDT Register Masks
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup WWDT_Register_Masks WWDT Register Masks
+ * @{
+ */
+
+/*! @name MOD - Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer. */
+/*! @{ */
+#define WWDT_MOD_WDEN_MASK                       (0x1U)
+#define WWDT_MOD_WDEN_SHIFT                      (0U)
+/*! WDEN - Watchdog enable bit. Once this bit is set to one and a watchdog feed is performed, the
+ *    watchdog timer will run permanently. 0: The watchdog timer is stopped. 1: The watchdog timer is
+ *    running.
+ */
+#define WWDT_MOD_WDEN(x)                         (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDEN_SHIFT)) & WWDT_MOD_WDEN_MASK)
+#define WWDT_MOD_WDRESET_MASK                    (0x2U)
+#define WWDT_MOD_WDRESET_SHIFT                   (1U)
+/*! WDRESET - Watchdog reset enable bit. Once this bit has been written with a 1 it cannot be
+ *    re-written with a 0. 0: Interrupt. A watchdog time-out will not cause a chip reset. It will cause an
+ *    interrupt of the watchdog. 1: Reset. A watchdog time-out will cause a chip reset.
+ */
+#define WWDT_MOD_WDRESET(x)                      (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDRESET_SHIFT)) & WWDT_MOD_WDRESET_MASK)
+#define WWDT_MOD_WDTOF_MASK                      (0x4U)
+#define WWDT_MOD_WDTOF_SHIFT                     (2U)
+/*! WDTOF - Watchdog time-out flag. Set when the watchdog timer times out, by a feed error, or by
+ *    events associated with WDPROTECT. Cleared by software writing a 0 to this bit position. Causes a
+ *    chip reset if WDRESET = 1.
+ */
+#define WWDT_MOD_WDTOF(x)                        (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDTOF_SHIFT)) & WWDT_MOD_WDTOF_MASK)
+#define WWDT_MOD_WDINT_MASK                      (0x8U)
+#define WWDT_MOD_WDINT_SHIFT                     (3U)
+/*! WDINT - Warning interrupt flag. Set when the timer reaches the value in WDWARNINT. Cleared by
+ *    software writing a 1 to this bit position. Note that this bit cannot be cleared while the
+ *    WARNINT value is equal to the value of the TV register. This can occur if the value of WARNINT is 0
+ *    and the WDRESET bit is 0 when TV decrements to 0.
+ */
+#define WWDT_MOD_WDINT(x)                        (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDINT_SHIFT)) & WWDT_MOD_WDINT_MASK)
+#define WWDT_MOD_WDPROTECT_MASK                  (0x10U)
+#define WWDT_MOD_WDPROTECT_SHIFT                 (4U)
+/*! WDPROTECT - Watchdog update mode. This bit can be set once by software and is only cleared by a
+ *    reset. 0: Flexible. A feed sequence can be performed at any time; ie. the watchdog timer can
+ *    be reloaded with time-out value (TC) at any time. 1: Threshold. A feed sequence can be
+ *    performed only after the counter is below the value of WDWARNINT and WDWINDOW; ie. the watchdog timer
+ *    can be reloaded with time-out value (TC) only when the counter timer value is below the value
+ *    of WDWARNINT and WDWINDOW, otherwise a 'feed error' is created.
+ */
+#define WWDT_MOD_WDPROTECT(x)                    (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDPROTECT_SHIFT)) & WWDT_MOD_WDPROTECT_MASK)
+/*! @} */
+
+/*! @name TC - Watchdog timer constant register. This 24-bit register determines the time-out value. */
+/*! @{ */
+#define WWDT_TC_COUNT_MASK                       (0xFFFFFFU)
+#define WWDT_TC_COUNT_SHIFT                      (0U)
+/*! COUNT - Watchdog time-out value. If MOD.WDPROTECT is set then changing this value may cause an error.
+ */
+#define WWDT_TC_COUNT(x)                         (((uint32_t)(((uint32_t)(x)) << WWDT_TC_COUNT_SHIFT)) & WWDT_TC_COUNT_MASK)
+/*! @} */
+
+/*! @name FEED - Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in TC. */
+/*! @{ */
+#define WWDT_FEED_FEED_MASK                      (0xFFU)
+#define WWDT_FEED_FEED_SHIFT                     (0U)
+/*! FEED - Feed value should be 0xAA followed by 0x55. Writing 0xAA followed by 0x55 to this
+ *    register will reload the Watchdog timer with the TC value. This operation will also start the
+ *    Watchdog if it is enabled via the WDMOD register. Setting the WDEN bit in the WDMOD register is not
+ *    sufficient to enable the Watchdog. A valid feed sequence must be completed after setting WDEN
+ *    before the Watchdog is capable of generating a reset. Until then, the Watchdog will ignore feed
+ *    errors.
+ */
+#define WWDT_FEED_FEED(x)                        (((uint32_t)(((uint32_t)(x)) << WWDT_FEED_FEED_SHIFT)) & WWDT_FEED_FEED_MASK)
+/*! @} */
+
+/*! @name TV - Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer. */
+/*! @{ */
+#define WWDT_TV_COUNT_MASK                       (0xFFFFFFU)
+#define WWDT_TV_COUNT_SHIFT                      (0U)
+/*! COUNT - Counter timer value. The TV register is used to read the current value of Watchdog timer counter.
+ */
+#define WWDT_TV_COUNT(x)                         (((uint32_t)(((uint32_t)(x)) << WWDT_TV_COUNT_SHIFT)) & WWDT_TV_COUNT_MASK)
+/*! @} */
+
+/*! @name WARNINT - Watchdog Warning Interrupt compare value. */
+/*! @{ */
+#define WWDT_WARNINT_WARNINT_MASK                (0x3FFU)
+#define WWDT_WARNINT_WARNINT_SHIFT               (0U)
+/*! WARNINT - Watchdog warning interrupt compare value.A match of the watchdog timer counter to
+ *    WARNINT occurs when the bottom 10 bits of the counter have the same value as the 10 bits of
+ *    WARNINT, and the remaining upper bits of the counter are all 0. This gives a maximum time of 1,023
+ *    watchdog timer counts (4,096 watchdog clocks) for the interrupt to occur prior to a watchdog
+ *    event. If WARNINT is 0, the interrupt will occur at the same time as the watchdog event.
+ */
+#define WWDT_WARNINT_WARNINT(x)                  (((uint32_t)(((uint32_t)(x)) << WWDT_WARNINT_WARNINT_SHIFT)) & WWDT_WARNINT_WARNINT_MASK)
+/*! @} */
+
+/*! @name WINDOW - Watchdog Window compare value. */
+/*! @{ */
+#define WWDT_WINDOW_WINDOW_MASK                  (0xFFFFFFU)
+#define WWDT_WINDOW_WINDOW_SHIFT                 (0U)
+/*! WINDOW - Watchdog window value. The WINDOW register determines the highest TV value allowed when
+ *    a watchdog feed is performed. If a feed sequence occurs when TV is greater than the value in
+ *    WINDOW, a watchdog event will occur
+ */
+#define WWDT_WINDOW_WINDOW(x)                    (((uint32_t)(((uint32_t)(x)) << WWDT_WINDOW_WINDOW_SHIFT)) & WWDT_WINDOW_WINDOW_MASK)
+/*! @} */
+
+
+/*!
+ * @}
+ */ /* end of group WWDT_Register_Masks */
+
+
+/* WWDT - Peripheral instance base addresses */
+/** Peripheral WWDT base address */
+#define WWDT_BASE                                (0x4000A000u)
+/** Peripheral WWDT base pointer */
+#define WWDT                                     ((WWDT_Type *)WWDT_BASE)
+/** Array initializer of WWDT peripheral base addresses */
+#define WWDT_BASE_ADDRS                          { WWDT_BASE }
+/** Array initializer of WWDT peripheral base pointers */
+#define WWDT_BASE_PTRS                           { WWDT }
+/** Interrupt vectors for the WWDT peripheral type */
+#define WWDT_IRQS                                { WDT_BOD_IRQn }
+
+/*!
+ * @}
+ */ /* end of group WWDT_Peripheral_Access_Layer */
+
+
+/*
+** End of section using anonymous unions
+*/
+
+#if defined(__ARMCC_VERSION)
+  #if (__ARMCC_VERSION >= 6010050)
+    #pragma clang diagnostic pop
+  #else
+    #pragma pop
+  #endif
+#elif defined(__GNUC__)
+  /* leave anonymous unions enabled */
+#elif defined(__IAR_SYSTEMS_ICC__)
+  #pragma language=default
+#else
+  #error Not supported compiler type
+#endif
+
+/*!
+ * @}
+ */ /* end of group Peripheral_access_layer */
+
+
+/* ----------------------------------------------------------------------------
+   -- Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK).
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup Bit_Field_Generic_Macros Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK).
+ * @{
+ */
+
+#if defined(__ARMCC_VERSION)
+  #if (__ARMCC_VERSION >= 6010050)
+    #pragma clang system_header
+  #endif
+#elif defined(__IAR_SYSTEMS_ICC__)
+  #pragma system_include
+#endif
+
+/**
+ * @brief Mask and left-shift a bit field value for use in a register bit range.
+ * @param field Name of the register bit field.
+ * @param value Value of the bit field.
+ * @return Masked and shifted value.
+ */
+#define NXP_VAL2FLD(field, value)    (((value) << (field ## _SHIFT)) & (field ## _MASK))
+/**
+ * @brief Mask and right-shift a register value to extract a bit field value.
+ * @param field Name of the register bit field.
+ * @param value Value of the register.
+ * @return Masked and shifted bit field value.
+ */
+#define NXP_FLD2VAL(field, value)    (((value) & (field ## _MASK)) >> (field ## _SHIFT))
+
+/*!
+ * @}
+ */ /* end of group Bit_Field_Generic_Macros */
+
+
+/* ----------------------------------------------------------------------------
+   -- SDK Compatibility
+   ---------------------------------------------------------------------------- */
+
+/*!
+ * @addtogroup SDK_Compatibility_Symbols SDK Compatibility
+ * @{
+ */
+
+#define USART0_IRQn FLEXCOMM0_IRQn
+#define USART1_IRQn FLEXCOMM1_IRQn
+#define I2C0_IRQn FLEXCOMM2_IRQn
+#define I2C1_IRQn FLEXCOMM3_IRQn
+#define SPI0_IRQn FLEXCOMM4_IRQn
+#define SPI1_IRQn FLEXCOMM5_IRQn
+#define I2C2_IRQn FLEXCOMM6_IRQn
+#define DMA_IRQn DMA0_IRQn
+#define GINT_IRQn GINT0_IRQn
+#define PINT0_IRQn PIN_INT0_IRQn
+#define PINT1_IRQn PIN_INT1_IRQn
+#define PINT2_IRQn PIN_INT2_IRQn
+#define PINT3_IRQn PIN_INT3_IRQn
+#define SPIFI_IRQn SPIFI0_IRQn
+#define GINT_IRQn GINT0_IRQn
+#define Timer0_IRQn CTIMER0_IRQn
+#define Timer1_IRQn CTIMER1_IRQn
+#define DMIC_IRQn DMIC0_IRQn
+#define HWVAD_IRQn HWVAD0_IRQn
+#define AES256_Type AES_Type
+#define NTAG_IRQ NFCTag_IRQn
+#define PRESETCTRL PRESETCTRLS
+#define PRESETCTRLSET PRESETCTRLSETS
+#define PRESETCTRLCLR PRESETCTRLCLRS
+#define AHBCLKCTRL AHBCLKCTRLS
+#define AHBCLKCTRLSET AHBCLKCTRLSETS
+#define AHBCLKCTRLCLR AHBCLKCTRLCLRS
+#define STARTER STARTERS
+#define STARTERSET STARTERSETS
+#define STARTERCLR STARTERCLRS
+
+/*!
+ * @}
+ */ /* end of group SDK_Compatibility_Symbols */
+
+
+#endif  /* _K32W061_H_ */
+
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/K32W061_features.h b/third_party/nxp/K32W061DK6/devices/K32W061/K32W061_features.h
new file mode 100755
index 0000000..2e4881c
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/K32W061_features.h
@@ -0,0 +1,240 @@
+/*
+** ###################################################################
+**     Version:             rev. 1.0, 2019-11-05
+**     Build:               b191121
+**
+**     Abstract:
+**         Chip specific module features.
+**
+**     Copyright 2016 Freescale Semiconductor, Inc.
+**     Copyright 2016-2019 NXP
+**     All rights reserved.
+**
+**     SPDX-License-Identifier: BSD-3-Clause
+**
+**     http:                 www.nxp.com
+**     mail:                 support@nxp.com
+**
+**     Revisions:
+**     - rev. 1.0 (2019-11-05)
+**         Initial version.
+**
+** ###################################################################
+*/
+
+#ifndef _K32W061_FEATURES_H_
+#define _K32W061_FEATURES_H_
+
+/* SOC module features */
+
+/* @brief ADC availability on the SoC. */
+#define FSL_FEATURE_SOC_ADC_COUNT (1)
+/* @brief AES availability on the SoC. */
+#define FSL_FEATURE_SOC_AES_COUNT (1)
+/* @brief ASYNC_SYSCON availability on the SoC. */
+#define FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT (1)
+/* @brief CIC_IRB availability on the SoC. */
+#define FSL_FEATURE_SOC_CIC_IRB_COUNT (1)
+/* @brief CTIMER availability on the SoC. */
+#define FSL_FEATURE_SOC_CTIMER_COUNT (2)
+/* @brief DMA availability on the SoC. */
+#define FSL_FEATURE_SOC_DMA_COUNT (1)
+/* @brief DMIC availability on the SoC. */
+#define FSL_FEATURE_SOC_DMIC_COUNT (1)
+/* @brief FLASH availability on the SoC. */
+#define FSL_FEATURE_SOC_FLASH_COUNT (1)
+/* @brief FLEXCOMM availability on the SoC. */
+#define FSL_FEATURE_SOC_FLEXCOMM_COUNT (7)
+/* @brief GINT availability on the SoC. */
+#define FSL_FEATURE_SOC_GINT_COUNT (1)
+/* @brief HASH availability on the SoC. */
+#define FSL_FEATURE_SOC_HASH_COUNT (1)
+/* @brief I2C availability on the SoC. */
+#define FSL_FEATURE_SOC_I2C_COUNT (3)
+/* @brief INPUTMUX availability on the SoC. */
+#define FSL_FEATURE_SOC_INPUTMUX_COUNT (1)
+/* @brief IOCON availability on the SoC. */
+#define FSL_FEATURE_SOC_IOCON_COUNT (1)
+/* @brief LPC_GPIO availability on the SoC. */
+#define FSL_FEATURE_SOC_LPC_GPIO_COUNT (1)
+/* @brief LPC_RTC availability on the SoC. */
+#define FSL_FEATURE_SOC_LPC_RTC_COUNT (1)
+/* @brief PINT availability on the SoC. */
+#define FSL_FEATURE_SOC_PINT_COUNT (1)
+/* @brief PMC availability on the SoC. */
+#define FSL_FEATURE_SOC_PMC_COUNT (1)
+/* @brief PWM availability on the SoC. */
+#define FSL_FEATURE_SOC_PWM_COUNT (1)
+/* @brief SHA availability on the SoC. */
+#define FSL_FEATURE_SOC_SHA_COUNT (1)
+/* @brief SPI availability on the SoC. */
+#define FSL_FEATURE_SOC_SPI_COUNT (2)
+/* @brief SPIFI availability on the SoC. */
+#define FSL_FEATURE_SOC_SPIFI_COUNT (1)
+/* @brief SYSCON availability on the SoC. */
+#define FSL_FEATURE_SOC_SYSCON_COUNT (1)
+/* @brief TRNG availability on the SoC. */
+#define FSL_FEATURE_SOC_TRNG_COUNT (1)
+/* @brief USART availability on the SoC. */
+#define FSL_FEATURE_SOC_USART_COUNT (2)
+/* @brief WWDT availability on the SoC. */
+#define FSL_FEATURE_SOC_WWDT_COUNT (1)
+
+/* ADC module features */
+
+/* @brief ADC data alignment mode. */
+#define FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT (1)
+/* @brief ADC data alignment mode. */
+#define FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL (1)
+/* @brief Has no Calibration function. */
+#define FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC (1)
+/* @brief ADC has single SEQ. */
+#define FSL_FEATURE_ADC_HAS_SINGLE_SEQ (1)
+/* @brief Has ADC_INIT bitfile in STARTUP register. */
+#define FSL_FEATURE_ADC_HAS_STARTUP_ADC_INIT (0)
+/* @brief Has OFFSET_CAL bitfile in GPADC_CTRL1 reigster. */
+#define FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL (1)
+/* @brief Has LDO_POWER_EN bitfile in GPADC_CTRL0 reigster. */
+#define FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN (1)
+/* @brief ADC require a delay. */
+#define FSL_FEATURE_ADC_REQUIRE_DELAY (1)
+/* @brief ADC TEMPSENSORCTRL in ASYNC_SYSCON. */
+#define FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP (1)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE (1)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_RESOL (1)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL (0)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_TSAMP (1)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE (0)
+/* @brief Has ASYNMODE bitfile in CTRL reigster. */
+#define FSL_FEATURE_ADC_HAS_CTRL_CALMODE (0)
+/* @brief Has ADTrim register */
+#define FSL_FEATURE_ADC_HAS_TRIM_REG (0)
+/* @brief Has Calibration register. */
+#define FSL_FEATURE_ADC_HAS_CALIB_REG (0)
+
+/* ASYNC_SYSCON module features */
+
+/* @brief FMEAS FMEAS_INDEX is 20. */
+#define FSL_FEATURE_FMEAS_INDEX_20 (1)
+/* @brief FMEAS FREQMECTRL in ASYNC_SYSCON. */
+#define FSL_FEATURE_FMEAS_ASYNC_SYSCON_FREQMECTRL (1)
+/* @brief FMEAS SYSCON use ASYNC_SYSCON. */
+#define FSL_FEATURE_FMEAS_USE_ASYNC_SYSCON (1)
+/* @brief FMEAS start frequency with ASYNC_SYSCON. */
+#define FSL_FEATURE_FMEAS_START_FRG_ASYNC_SYSCON (1)
+/* @brief FMEAS get frequency with ASYNC_SYSCON. */
+#define FSL_FEATURE_FMEAS_GET_FRG_ASYNC_SYSCON (1)
+/* @brief FMEAS get clock count with scale. */
+#define FSL_FEATURE_FMEAS_GET_COUNT_SCALE (1)
+/* @brief FMEAS start measure with scale. */
+#define FSL_FEATURE_FMEAS_STARTMEAS_SCALE (1)
+
+/* CTIMER module features */
+
+/* @brief CTIMER capture 3 interrupt. */
+#define FSL_FEATURE_CTIMER_HAS_IR_CR3INT (1)
+/* @brief CTIMER has no capture channel. */
+#define FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE (1)
+
+/* DMA module features */
+
+/* @brief Number of channels */
+#define FSL_FEATURE_DMA_NUMBER_OF_CHANNELS (19)
+/* @brief Align size of DMA descriptor */
+#define FSL_FEATURE_DMA_DESCRIPTOR_ALIGN_SIZE (512)
+/* @brief DMA head link descriptor table align size */
+#define FSL_FEATURE_DMA_LINK_DESCRIPTOR_ALIGN_SIZE (16U)
+
+/* FLASH module features */
+
+/* @brief P-Flash write unit size. */
+#define FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE (512U)
+/* @brief P-Flash sector size. */
+#define FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE (512U)
+/* @brief P-Flash block count. */
+#define FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT (1)
+/* @brief P-Flash block size. */
+#define FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE (0xA0000U)
+/* @brief ADC temp cal flash addr. */
+#define FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL (0x9FC80)
+/* @brief ADC temp cal flash data vaild mask. */
+#define FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL_VALID (0x1)
+
+/* FLEXCOMM module features */
+
+/* @brief Has no reset in FLEXCOMM register. */
+#define FSL_FEATURE_FLEXCOMM_HAS_NO_RESET (1)
+/* @brief USART availability on the SoC. */
+#define FSL_FEATURE_SOC_FLEXCOMM_USART_COUNT (FSL_FEATURE_SOC_USART_COUNT)
+/* @brief SPI are FLEXCOMM on the SoC. */
+#define FSL_FEATURE_SOC_FLEXCOMM_SPI_COUNT (FSL_FEATURE_SOC_SPI_COUNT)
+/* @brief I2C are FLEXCOMM on the SoC. */
+#define FSL_FEATURE_SOC_FLEXCOMM_I2C_COUNT (FSL_FEATURE_SOC_I2C_COUNT)
+
+/* GPIO module features */
+
+/* @brief GPIO DIRSET and DIRCLR register. */
+#define FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR (1)
+/* @brief Number of PIOs. */
+#define FSL_FEATURE_GPIO_PIO_COUNT (22)
+/* @brief GPIO availability on the SoC. */
+#define FSL_FEATURE_SOC_GPIO_COUNT (FSL_FEATURE_SOC_LPC_GPIO_COUNT)
+
+/* I2C module features */
+
+/* @brief I2C peripheral clock frequency 8MHz. */
+#define FSL_FEATURE_I2C_PREPCLKFRG_8MHZ (1)
+
+/* IOCON module features */
+
+/* @brief Func bit field width */
+#define FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH (3)
+
+/* PINT module features */
+
+/* @brief Number of connected outputs */
+#define FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS (4)
+
+/* PMC module features */
+
+/* @brief FRO1M trim address. */
+#define FSL_FEATURE_PMC_FRO1M_ADDRESS (0x9FCD0U)
+/* @brief FRO1M trim valid mask. */
+#define FSL_FEATURE_PMC_FRO1M_VALID_MASK (0x1U)
+
+/* RTC module features */
+
+/* @brief Has no separate RTC OSC PD in CTRL register. */
+#define FSL_FEATURE_RTC_HAS_NO_OSC_PD (1)
+
+/* SPI module features */
+
+/* @brief SPI SIZE bitfile in FIFOCFG register */
+#define FSL_FEATURE_SPI_FIFOSIZE_CFG (1)
+/* @brief SPI has only three SSEL pins */
+#define FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE (1)
+
+/* SPIFI module features */
+
+/* @brief SPIFI start address */
+#define FSL_FEATURE_SPIFI_START_ADDR (0x10000000)
+/* @brief SPIFI end address */
+#define FSL_FEATURE_SPIFI_END_ADDR (0x103FFFFF)
+/* @brief SPIFI DATALEN bitfile in CMD register */
+#define FSL_FEATURE_SPIFI_DATALEN_CTRL (1)
+
+/* WWDT module features */
+
+/* @brief WWDT WDTOF is not set in case of WD reset - get info from PMC instead. */
+#define FSL_FEATURE_WWDT_WDTRESET_FROM_PMC (1)
+/* @brief WWDT NO PDCFG. */
+#define FSL_FEATURE_WWDT_HAS_NO_PDCFG (1)
+/* @brief WWDT LOCK bitfile in MOD register */
+#define FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK (1)
+
+#endif /* _K32W061_FEATURES_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/flash_header.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/flash_header.h
new file mode 100755
index 0000000..9579f70
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/flash_header.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FLASH_HEADER_H_
+#define FLASH_HEADER_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stdint.h>
+
+/*!
+ * @addtogroup jn_flash
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+#define NUMBER_CCSUM_VECTORS (7)
+
+#define IMAGE_SIGNATURE (0x98447902)
+#define IMAGE_HEADER_SIGNATURE_V3_ZB (IMAGE_SIGNATURE + 1)
+#define IMAGE_HEADER_SIGNATURE_V3_BLE (IMAGE_SIGNATURE + 2)
+#define BOOT_BLOCK_HDR_MARKER 0xbb0110bb
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/*!
+ * @brief Image header.
+ *
+ * Be very cautious when modifying the IMG_HEADER_T and the BOOT_BLOCK_T structures (alignment) as
+ * these structures are used in the image_tool.py (which does not take care of alignment).
+ */
+typedef struct
+{
+    uint32_t vectors[NUMBER_CCSUM_VECTORS]; /*!< critical vectors protected by csum */
+    uint32_t vectorCsum;                    /*!< csum of vectors 0-7 */
+    uint32_t imageSignature;                /*!< image signature */
+    uint32_t bootBlockOffset;               /*!< offset of boot block structure */
+    uint32_t header_crc;                    /*!< the CRC of header */
+} IMG_HEADER_T;
+
+/*!
+ * @brief Boot block.
+ *
+ * For some ADC16 channels, there are two pin selections in channel multiplexer. For example, ADC0_SE4a and ADC0_SE4b
+ * are the different channels that share the same channel number.
+ */
+typedef struct
+{
+    uint32_t header_marker;        /*!< Image header marker should always be set to 0xbb0110bb+/-2 */
+    uint32_t img_type;             /*!< Image check type, with or without optional CRC */
+    uint32_t target_addr;          /*!< Target address */
+    uint32_t img_len;              /*!< Image length or the length of image CRC check should be done.
+                           For faster boot application could set a smaller length than actual image.
+                           For Secure boot images, this MUST be the entire image length */
+    uint32_t stated_size;          /*!< max size of any subsequent image : AppSize0 = 2 x stated_size */
+    uint32_t certificate_offset;   /*!< Offset of the certificate list */
+    uint32_t compatibility_offset; /*!< Offset of the compatibility list */
+    uint32_t version;              /*!< Image version for multi-image support */
+} BOOT_BLOCK_T;
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* FLASH_HEADER_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_aes.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_aes.c
new file mode 100755
index 0000000..f92cfbb
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_aes.c
@@ -0,0 +1,1283 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_aes.h"
+#include "string.h"
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.aes"
+#endif
+
+/*!< Use standard C library memcpy  */
+#define aes_memcpy memcpy
+
+/*! @brief Definitions used for writing to the AES module CFG register. */
+typedef enum _aes_configuration
+{
+    kAES_CfgEncryptEcb            = 0x001u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Encrypt Ecb */
+    kAES_CfgDecryptEcb            = 0x001u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Decrypt Ecb */
+    kAES_CfgEncryptCbc            = 0x023u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Encrypt Cbc */
+    kAES_CfgDecryptCbc            = 0x211u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Decrypt Cbc */
+    kAES_CfgEncryptCfb            = 0x132u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Encrypt Cfb */
+    kAES_CfgDecryptCfb            = 0x112u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Decrypt Cfb */
+    kAES_CfgCryptOfb              = 0x122u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Ofb */
+    kAES_CfgCryptCtr              = 0x102u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Ctr */
+    kAES_CfgCryptGcmTag           = 0x102u, /*!< OUTTEXT_SEL, HOLD_SEL and INBLK_SEL = Gcm */
+    kAES_CfgSwap                  = 0x51u,  /*!< INTEXT swap bytes, OUTTEXT swap bytes, PROC_EN = Encrypt/Decrypt */
+    kAES_CfgIntextSwap            = 0x11u,  /*!< INTEXT swap bytes, PROC_EN = Encrypt/Decrypt */
+    kAES_CfgSwapIntextHashIn      = 0x12u,  /*!< Swap INTEXT only, Hash INTEXT */
+    kAES_CfgSwapIntextHashOut     = 0x16u,  /*!< Swap INTEXT only, Hash OUTTEXT */
+    kAES_CfgSwapEnDecHashIn       = 0x53u,  /*!< Swap INTEXT and OUTTEXT, Encrypt/Decrypt and Hash, Hash INTEXT */
+    kAES_CfgSwapEnDecHashOut      = 0x57u,  /*!< Swap INTEXT and OUTTEXT, Encrypt/Decrypt and Hash, Hash OUTTEXT */
+    kAES_CfgSwapIntextEnDecHashIn = 0x13u,  /*!< Swap INTEXT, Encrypt/Decrypt and Hash, Hash INTEXT */
+} aes_configuration_t;
+
+/*! @brief Actual operation with AES. */
+typedef enum _aes_encryption_decryption_mode
+{
+    kAES_ModeEncrypt = 0U, /*!< Encryption */
+    kAES_ModeDecrypt = 1U, /*!< Decryption */
+} aes_encryption_decryption_mode_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+static void aes_gcm_dec32(uint8_t *input);
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * @brief Reads an unaligned word.
+ *
+ * This function creates a 32-bit word from an input array of four bytes.
+ *
+ * @param src Input array of four bytes. The array can start at any address in memory.
+ * @return 32-bit unsigned int created from the input byte array.
+ */
+static inline uint32_t aes_get_word_from_unaligned(const uint8_t *srcAddr)
+{
+#if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
+    register const uint8_t *src = srcAddr;
+    /* Cortex M0 does not support misaligned loads */
+    if ((uint32_t)src & 0x3u)
+    {
+        union _align_bytes_t
+        {
+            uint32_t word;
+            uint8_t byte[sizeof(uint32_t)];
+        } my_bytes;
+
+        my_bytes.byte[0] = *src;
+        my_bytes.byte[1] = *(src + 1);
+        my_bytes.byte[2] = *(src + 2);
+        my_bytes.byte[3] = *(src + 3);
+        return my_bytes.word;
+    }
+    else
+    {
+        /* addr aligned to 0-modulo-4 so it is safe to type cast */
+        return *((const uint32_t *)src);
+    }
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+    /* -O3 optimization in Keil uses LDM instruction here (LDM r4!, {r0})
+     *    which is wrong, because srcAddr might be unaligned.
+     *    LDM on unaligned address causes hard-fault. so use memcpy() */
+    uint32_t ret;
+    memcpy(&ret, srcAddr, sizeof(uint32_t));
+    return ret;
+#else
+    return *((const uint32_t *)srcAddr);
+#endif
+}
+
+/*!
+ * @brief Converts a 32-bit word into a byte array.
+ *
+ * This function creates an output array of four bytes from an input 32-bit word.
+ *
+ * @param srcWord Input 32-bit unsigned integer.
+ * @param[out] dst Output array of four bytes. The array can start at any address in memory.
+ */
+static inline void aes_set_unaligned_from_word(uint32_t srcWord, uint8_t *dstAddr)
+{
+#if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
+    register uint8_t *dst = dstAddr;
+    /* Cortex M0 does not support misaligned stores */
+    if ((uint32_t)dst & 0x3u)
+    {
+        *dst++ = (srcWord & 0x000000FFU);
+        *dst++ = (srcWord & 0x0000FF00U) >> 8;
+        *dst++ = (srcWord & 0x00FF0000U) >> 16;
+        *dst++ = (srcWord & 0xFF000000U) >> 24;
+    }
+    else
+    {
+        *((uint32_t *)dstAddr) = srcWord; /* addr aligned to 0-modulo-4 so it is safe to type cast */
+    }
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+    uint32_t ret;
+    ret = srcWord;
+    memcpy(dstAddr, &ret, sizeof(uint32_t));
+    return;
+#else
+    *((uint32_t *)dstAddr) = srcWord;
+#endif
+}
+
+/*!
+ * @brief Swap bytes withing 32-bit word.
+ *
+ * This function changes endianess of a 32-bit word.
+ *
+ * @param in 32-bit unsigned integer
+ * @return 32-bit unsigned integer with different endianess (big endian to little endian and vice versa).
+ */
+static uint32_t swap_bytes(uint32_t in)
+{
+    return (((in & 0x000000ffu) << 24) | ((in & 0x0000ff00u) << 8) | ((in & 0x00ff0000u) >> 8) |
+            ((in & 0xff000000u) >> 24));
+}
+
+/*!
+ * @brief Loads key into key registers.
+ *
+ * This function loads the key into the AES key registers.
+ *
+ * @param base AES peripheral base address.
+ * @param key Input key in big endian format.
+ * @param keySize Size of the input key in bytes. Must be 16, 24 or 32.
+ * @return Status of the load key operation.
+ */
+static status_t aes_load_key(AES_Type *base, const uint8_t *key, size_t keySize)
+{
+    uint32_t aesCfgKeyCfg;
+    uint32_t aesCfg;
+    int index;
+    int keyWords;
+
+    switch (keySize)
+    {
+        case 16u:
+            aesCfgKeyCfg = 0u;
+            keyWords     = 4;
+            break;
+
+        case 24u:
+            aesCfgKeyCfg = 1u;
+            keyWords     = 6;
+            break;
+
+        case 32u:
+            aesCfgKeyCfg = 2u;
+            keyWords     = 8;
+            break;
+
+        default:
+            keyWords = 0;
+            break;
+    }
+
+    if (!keyWords)
+    {
+        /* invalidate a possibly valid key. user attempted to set a key but gives incorrect size. */
+        base->CMD = AES_CMD_WIPE(1);
+        /* wait for Idle */
+        while (!(base->STAT & AES_STAT_IDLE_MASK))
+        {
+        }
+        base->CMD = AES_CMD_WIPE(0u);
+        return kStatus_InvalidArgument;
+    }
+
+    aesCfg = base->CFG;
+    aesCfg &= ~AES_CFG_KEY_CFG_MASK;
+    aesCfg |= AES_CFG_KEY_CFG(aesCfgKeyCfg);
+    base->CFG = aesCfg;
+
+    for (index = 0; index < keyWords; index++)
+    {
+        base->KEY[index] = swap_bytes(aes_get_word_from_unaligned(key));
+        key += sizeof(uint32_t);
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * @brief AES process one 16-byte block.
+ *
+ * This function pushes 16 bytes of data to INTEXT and pops 16 bytes of data from OUTTEXT.
+ *
+ * @param base AES peripheral base address.
+ * @param[out] output 16-byte block read from the OUTTEXT registers.
+ * @param input 16-byte block written to the INTEXT registers.
+ */
+static void aes_one_block(AES_Type *base, uint8_t *output, const uint8_t *input)
+{
+    int index;
+    uint32_t aesStat;
+
+    /* If the IN_READY bit in STAT register is 1, write the input text in the INTEXT [3:0]
+       registers. */
+    index = 0;
+    while (index < 4)
+    {
+        aesStat = base->STAT;
+
+        if (aesStat & AES_STAT_IN_READY_MASK)
+        {
+            base->INTEXT[index] = aes_get_word_from_unaligned(input);
+            input += sizeof(uint32_t);
+            index++;
+        }
+    }
+
+    index = 0;
+    while (index < 4)
+    {
+        aesStat = base->STAT;
+
+        if (aesStat & AES_STAT_OUT_READY_MASK)
+        {
+            aes_set_unaligned_from_word(base->OUTTEXT[index], output);
+            output += sizeof(uint32_t);
+            index++;
+        }
+    }
+}
+
+/*!
+ * @brief AES switch to forward mode.
+ *
+ * This function sets the AES to forward mode if it is in reverse mode.
+ *
+ * @param base AES peripheral base address.
+ */
+static void aes_set_forward(AES_Type *base)
+{
+    if (AES_STAT_REVERSE_MASK == (base->STAT & AES_STAT_REVERSE_MASK))
+    {
+        /* currently in reverse, switch to forward */
+        base->CMD = AES_CMD_SWITCH_MODE(1u);
+
+        /* wait for Idle */
+        while (!(base->STAT & AES_STAT_IDLE_MASK))
+        {
+        }
+
+        base->CMD = AES_CMD_SWITCH_MODE(0u);
+    }
+}
+
+/*!
+ * @brief AES switch to reverse mode.
+ *
+ * This function sets the AES to reverse mode if it is in forward mode.
+ *
+ * @param base AES peripheral base address.
+ */
+static void aes_set_reverse(AES_Type *base)
+{
+    if (!(base->STAT & AES_STAT_REVERSE_MASK))
+    {
+        /* currently in forward, switch to reverse */
+        base->CMD = AES_CMD_SWITCH_MODE(1u);
+
+        /* wait for Idle */
+        while (!(base->STAT & AES_STAT_IDLE_MASK))
+        {
+        }
+
+        base->CMD = AES_CMD_SWITCH_MODE(0u);
+    }
+}
+
+/*!
+ * @brief AES write HOLDING registers.
+ *
+ * This function writes input 16-byte data to AES HOLDING registers.
+ *
+ * @param base AES peripheral base address.
+ * @param input 16-byte input data.
+ */
+static void aes_set_holding(AES_Type *base, const uint8_t *input)
+{
+    int index;
+
+    for (index = 0; index < 4; index++)
+    {
+        base->HOLDING[index] = swap_bytes(aes_get_word_from_unaligned(input));
+        input += sizeof(uint32_t);
+    }
+}
+
+/*!
+ * @brief AES check KEY_VALID.
+ *
+ * This function check the KEY_VALID bit in AES status register.
+ *
+ * @param base AES peripheral base address.
+ * @return kStatus_Success if the key is valid.
+ * @return kStatus_InvalidArgument if the key is invalid.
+ */
+static status_t aes_check_key_valid(AES_Type *base)
+{
+    status_t status;
+
+    /* Check the key is valid */
+    status =
+        (AES_STAT_KEY_VALID_MASK == (base->STAT & AES_STAT_KEY_VALID_MASK)) ? kStatus_Success : kStatus_InvalidArgument;
+
+    return status;
+}
+
+/*!
+ * brief Sets AES key.
+ *
+ * Sets AES key.
+ *
+ * param base AES peripheral base address
+ * param key Input key to use for encryption or decryption
+ * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
+ * return Status from Set Key operation
+ */
+status_t AES_SetKey(AES_Type *base, const uint8_t *key, size_t keySize)
+{
+    return aes_load_key(base, key, keySize);
+}
+
+/*!
+ * brief Encrypts AES using the ECB block mode.
+ *
+ * Encrypts AES using the ECB block mode.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptEcb(AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size)
+{
+    status_t status;
+
+    /* ECB mode, size must be 16-byte multiple */
+    if (size % 16u)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /*5. Select the required crypto operation (encryption/decryption/hash) and AES mode in the CFG register.*/
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgEncryptEcb;
+
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /* make sure AES is set to forward mode */
+    aes_set_forward(base);
+
+    while (size)
+    {
+        aes_one_block(base, ciphertext, plaintext);
+        ciphertext += 16;
+        plaintext += 16;
+        size -= 16u;
+    }
+
+    return status;
+}
+
+/*!
+ * brief Decrypts AES using the ECB block mode.
+ *
+ * Decrypts AES using the ECB block mode.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input ciphertext to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptEcb(AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size)
+{
+    status_t status;
+
+    /* ECB mode, size must be 16-byte multiple */
+    if (size % 16u)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /*5. Select the required crypto operation (encryption/decryption/hash) and AES mode in the CFG register.*/
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgDecryptEcb;
+
+    /* make sure AES is set to reverse mode */
+    aes_set_reverse(base);
+
+    while (size)
+    {
+        aes_one_block(base, plaintext, ciphertext);
+        ciphertext += 16;
+        plaintext += 16;
+        size -= 16u;
+    }
+
+    return status;
+}
+
+/*!
+ * @brief Main function for CBC, CFB and OFB modes.
+ *
+ * @param base AES peripheral base address
+ * @param input Input plaintext for encryption, input ciphertext for decryption.
+ * @param[out] output Output ciphertext for encryption, output plaintext for decryption.
+ * @param size Size of input and output data in bytes. For CBC and CFB it must be multiple of 16-bytes.
+ * @param iv Input initial vector to combine with the first input block.
+ * @return Status from the operation.
+ */
+static status_t aes_block_mode(AES_Type *base,
+                               const uint8_t *input,
+                               uint8_t *output,
+                               size_t size,
+                               const uint8_t iv[AES_IV_SIZE],
+                               aes_configuration_t configuration)
+{
+    status_t status;
+
+    /* CBC and CFB128 mode, size must be 16-byte multiple */
+    switch (configuration)
+    {
+        case kAES_CfgEncryptCfb:
+        case kAES_CfgDecryptCfb:
+        case kAES_CfgEncryptCbc:
+        case kAES_CfgDecryptCbc:
+            if (size % 16u)
+            {
+                status = kStatus_InvalidArgument;
+            }
+            else
+            {
+                status = kStatus_Success;
+            }
+            break;
+
+        case kAES_CfgCryptOfb:
+            status = kStatus_Success;
+            break;
+
+        default:
+            status = kStatus_InvalidArgument;
+            break;
+    }
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /* Check the key is valid */
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /*5. Select the required crypto operation (encryption/decryption/hash) and AES mode in the CFG register.*/
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)configuration;
+
+    /* CBC decrypt use reverse AES cipher. */
+    switch (configuration)
+    {
+        case kAES_CfgDecryptCbc:
+            aes_set_reverse(base);
+            break;
+
+        default:
+            aes_set_forward(base);
+            break;
+    }
+
+    /* For CBC, CFB and OFB modes write the Initialization Vector (IV) in the HOLDING
+       [3:0] registers. For CTR mode write the initial counter value in the HOLDING [3:0]
+       registers. */
+    aes_set_holding(base, iv);
+
+    while (size >= 16u)
+    {
+        aes_one_block(base, output, input);
+        size -= 16u;
+        output += 16;
+        input += 16;
+    }
+
+    /* OFB can have non-block multiple size. CBC and CFB128 have size zero at this moment. */
+    if (size)
+    {
+        uint8_t blkTemp[16] = {0};
+
+        aes_memcpy(blkTemp, input, size);
+        aes_one_block(base, blkTemp, blkTemp);
+        aes_memcpy(output, blkTemp, size);
+    }
+
+    return status;
+}
+
+/*!
+ * brief Encrypts AES using CBC block mode.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input initial vector to combine with the first input block.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptCbc(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, plaintext, ciphertext, size, iv, kAES_CfgEncryptCbc);
+}
+
+/*!
+ * brief Decrypts AES using CBC block mode.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input initial vector to combine with the first input block.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptCbc(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, ciphertext, plaintext, size, iv, kAES_CfgDecryptCbc);
+}
+
+/*!
+ * brief Encrypts AES using CFB block mode.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input Initial vector to be used as the first input block.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptCfb(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, plaintext, ciphertext, size, iv, kAES_CfgEncryptCfb);
+}
+
+/*!
+ * brief Decrypts AES using CFB block mode.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input Initial vector to be used as the first input block.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptCfb(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, ciphertext, plaintext, size, iv, kAES_CfgDecryptCfb);
+}
+
+/*!
+ * brief Encrypts AES using OFB block mode.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes.
+ * param iv Input Initial vector to be used as the first input block.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptOfb(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, plaintext, ciphertext, size, iv, kAES_CfgCryptOfb);
+}
+
+/*!
+ * brief Decrypts AES using OFB block mode.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes.
+ * param iv Input Initial vector to be used as the first input block.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptOfb(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE])
+{
+    return aes_block_mode(base, ciphertext, plaintext, size, iv, kAES_CfgCryptOfb);
+}
+
+/*!
+ * brief Encrypts or decrypts AES using CTR block mode.
+ *
+ * Encrypts or decrypts AES using CTR block mode.
+ * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
+ * The only difference between encryption and decryption is that, for encryption, the input argument
+ * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
+ * and the output argument is plain text.
+ *
+ * param base AES peripheral base address
+ * param input Input data for CTR block mode
+ * param[out] output Output data for CTR block mode
+ * param size Size of input and output data in bytes
+ * param[in,out] counter Input counter (updates on return)
+ * param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are
+ * not used.
+ * param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
+ * are not used.
+ * return Status from crypt operation
+ */
+status_t AES_CryptCtr(AES_Type *base,
+                      const uint8_t *input,
+                      uint8_t *output,
+                      size_t size,
+                      uint8_t counter[AES_BLOCK_SIZE],
+                      uint8_t counterlast[AES_BLOCK_SIZE],
+                      size_t *szLeft)
+{
+    status_t status;
+    uint32_t lastSize;
+    uint8_t lastBlock[AES_BLOCK_SIZE] = {0};
+    uint8_t *lastEncryptedCounter;
+
+    /* Check the key is valid */
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /*5. Select the required crypto operation (encryption/decryption/hash) and AES mode in the CFG register.*/
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgCryptCtr;
+    aes_set_forward(base);
+
+    /* For CBC, CFB and OFB modes write the Initialization Vector (IV) in the HOLDING
+       [3:0] registers. For CTR mode write the initial counter value in the HOLDING [3:0]
+       registers. */
+    aes_set_holding(base, counter);
+
+    /* set counter increment by one */
+    base->CTR_INCR = 0x1U;
+
+    /* Split the size into full 16-byte chunks and last incomplete block */
+    lastSize = 0U;
+    if (size <= 16U)
+    {
+        lastSize = size;
+        size     = 0U;
+    }
+    else
+    {
+        /* Process all 16-byte data chunks. */
+        lastSize = size % 16U;
+        if (lastSize == 0U)
+        {
+            lastSize = 16U;
+            size -= 16U;
+        }
+        else
+        {
+            size -= lastSize; /* size will be rounded down to 16 byte boundary. remaining bytes in lastSize */
+        }
+    }
+
+    /* full 16-byte blocks */
+    while (size)
+    {
+        aes_one_block(base, output, input);
+        size -= 16u;
+        input += 16;
+        output += 16;
+    }
+
+    /* last block */
+    if (counterlast)
+    {
+        lastEncryptedCounter = counterlast;
+    }
+    else
+    {
+        lastEncryptedCounter = lastBlock;
+    }
+    aes_one_block(base, lastEncryptedCounter, lastBlock); /* lastBlock is all zeroes, so I get directly ECB of the last
+                                                             counter, as the XOR with zeroes doesn't change */
+
+    /* remain output = input XOR counterlast */
+    for (uint32_t i = 0; i < lastSize; i++)
+    {
+        output[i] = input[i] ^ lastEncryptedCounter[i];
+    }
+
+    /* read counter value after last encryption */
+    aes_set_unaligned_from_word(swap_bytes(base->HOLDING[3]), &counter[12]);
+    aes_gcm_dec32(&counter[0]); /* TODO HW problem? (first time it increments HOLDING3 twice) */
+
+    if (szLeft)
+    {
+        *szLeft = 16U - lastSize;
+    }
+
+    return status;
+}
+
+/*!
+ * @brief AES write input to INTEXT registers.
+ *
+ * This function writes input 16-byte data to AES INTEXT registers
+ * and wait for the engine Idle.
+ *
+ * @param base AES peripheral base address.
+ * @param input 16-byte input data.
+ */
+static void aes_gcm_one_block_input_only(AES_Type *base, const uint8_t *input)
+{
+    int index;
+    uint32_t aesStat;
+
+    /* If the IN_READY bit in STAT register is 1, write the input text in the INTEXT [3:0]
+       registers. */
+    index = 0;
+    while (index < 4)
+    {
+        aesStat = base->STAT;
+
+        if (aesStat & AES_STAT_IN_READY_MASK)
+        {
+            base->INTEXT[index] = aes_get_word_from_unaligned(input);
+            input += sizeof(uint32_t);
+            index++;
+        }
+    }
+
+    while (0 == (base->STAT & AES_STAT_IDLE_MASK))
+    {
+    }
+}
+
+/*!
+ * @brief AES execute command.
+ *
+ * This function issues command to AES CMD register.
+ *
+ * @param base AES peripheral base address.
+ * @param cmdMask Bit mask for the command to be issued.
+ */
+static void aes_command(AES_Type *base, uint32_t cmdMask)
+{
+    base->CMD = cmdMask;
+    /* wait for Idle */
+    while (!(base->STAT & AES_STAT_IDLE_MASK))
+    {
+    }
+    base->CMD = 0;
+}
+
+/*!
+ * @brief AES read GCM_TAG.
+ *
+ * This function reads data from GCM_TAG registers.
+ *
+ * @param base AES peripheral base address.
+ * @param output 16 byte memory to write the GCM_TAG to.
+ */
+static void aes_gcm_get_tag(AES_Type *base, uint8_t *output)
+{
+    int index;
+
+    for (index = 0; index < 4; index++)
+    {
+        aes_set_unaligned_from_word(swap_bytes(base->GCM_TAG[index]), output);
+        output += sizeof(uint32_t);
+    }
+}
+
+/*!
+ * @brief AES GCM check validity of input arguments.
+ *
+ * This function checks the validity of input arguments.
+ *
+ * @param base AES peripheral base address.
+ * @param src Source address (plaintext or ciphertext).
+ * @param iv Initialization vector address.
+ * @param aad Additional authenticated data address.
+ * @param dst Destination address (plaintext or ciphertext).
+ * @param inputSize Size of input (same size as output) data in bytes.
+ * @param ivSize Size of Initialization vector in bytes.
+ * @param aadSize Size of additional data in bytes.
+ * @param tagSize Size of the GCM tag in bytes.
+ */
+static status_t aes_gcm_check_input_args(AES_Type *base,
+                                         const uint8_t *src,
+                                         const uint8_t *iv,
+                                         const uint8_t *aad,
+                                         uint8_t *dst,
+                                         size_t inputSize,
+                                         size_t ivSize,
+                                         size_t aadSize,
+                                         size_t tagSize)
+{
+    if (!base)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* tag can be NULL to skip tag processing */
+    if ((ivSize && (!iv)) || (aadSize && (!aad)) || (inputSize && ((!src) || (!dst))))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* octet length of tag (tagSize) must be element of 4,8,12,13,14,15,16 */
+    if (((tagSize > 16u) || (tagSize < 12u)) && (tagSize != 4u) && (tagSize != 8u))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* no IV AAD DATA makes no sense */
+    if (0 == (inputSize + ivSize + aadSize))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* check length of input strings. This is more strict than the GCM specificaiton due to 32-bit architecture.
+     * The API interface would work on 64-bit architecture as well, but as it has not been tested, let it limit to
+     * 32-bits.
+     */
+    if (!((ivSize >= 1u) && (sizeof(size_t) <= 4u)))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Increment a 16 byte integer.
+ *
+ * This function increments by one a 16 byte integer.
+ *
+ * @param input Pointer to a 16 byte integer to be incremented by one.
+ */
+static void aes_gcm_incr32(uint8_t *input)
+{
+    int i = 15;
+    while (input[i] == (uint8_t)0xFFu)
+    {
+        input[i] = (uint8_t)0x00u;
+        i--;
+        if (i < 0)
+        {
+            return;
+        }
+    }
+
+    if (i >= 0)
+    {
+        input[i] += (uint8_t)1u;
+    }
+}
+
+/*!
+ * @brief Decrement a 16 byte integer.
+ *
+ * This function decrements by one a 16 byte integer.
+ *
+ * @param input Pointer to a 16 byte integer to be decremented by one.
+ */
+static void aes_gcm_dec32(uint8_t *input)
+{
+    int i = 15;
+    while (input[i] == (uint8_t)0x00u)
+    {
+        input[i] = (uint8_t)0xFFu;
+        i--;
+        if (i < 0)
+        {
+            return;
+        }
+    }
+
+    if (i >= 0)
+    {
+        input[i] -= (uint8_t)1u;
+    }
+}
+
+/*!
+ * @brief AES read GF128_Z registers.
+ *
+ * This function reads AES module GF128_Z registers.
+ *
+ * @param base AES peripheral base address.
+ * @param input Pointer to a 16 byte integer to write the GF128_Z value to.
+ */
+static void aes_get_gf128(AES_Type *base, uint8_t *output)
+{
+    int i;
+    for (i = 0; i < 4; i++)
+    {
+        aes_set_unaligned_from_word(swap_bytes(base->GF128_Z[i]), output);
+        output += sizeof(uint32_t);
+    }
+}
+
+/*!
+ * @brief GCM process.
+ *
+ * This function is the main function for AES GCM encryption/decryption and tag generation/comparison.
+ *
+ * @param base AES peripheral base address.
+ * @param encryptMode Whether the actual operation is an encryption or a decryption.
+ * @param src Input plaintext for encryption or ciphertext for decryption.
+ * @param inputSize Size of input and output in bytes.
+ * @param iv Input initial vector.
+ * @param ivSize Size of initial vector in bytes.
+ * @param aad Additional authenticated data.
+ * @param aadSize Size of additional authenticated data in bytes.
+ * @param dst Output ciphertext for encryption or plaintext for decryption.
+ * @param tag For encryption, GCM tag output. For decryption, GCM tag input for comparison.
+ * @param tagSize Size of the GCM tag in bytes.
+ */
+static status_t aes_gcm_process(AES_Type *base,
+                                aes_encryption_decryption_mode_t encryptMode,
+                                const uint8_t *src,
+                                size_t inputSize,
+                                const uint8_t *iv,
+                                size_t ivSize,
+                                const uint8_t *aad,
+                                size_t aadSize,
+                                uint8_t *dst,
+                                uint8_t *tag,
+                                size_t tagSize)
+{
+    status_t status;
+    uint8_t blkZero[16] = {0};
+    uint8_t blkJ0[16]   = {0};
+    uint8_t blkTag[16]  = {0};
+    uint32_t saveSize;
+    uint32_t saveAadSize;
+    uint32_t saveIvSize;
+    uint8_t lastBlock[AES_BLOCK_SIZE] = {0};
+
+    status = aes_gcm_check_input_args(base, src, iv, aad, dst, inputSize, ivSize, aadSize, tagSize);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    status = aes_check_key_valid(base);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    saveSize    = inputSize;
+    saveAadSize = aadSize;
+    saveIvSize  = ivSize;
+
+    /* 1. Let H = CIPHK(0_128). */
+    *(volatile uint8_t *)((uint32_t)base) = (uint8_t)
+        kAES_CfgIntextSwap; /* do not swap OUTTEXT, as OUTTEXT is copied for further use into GF128_Y register */
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgEncryptEcb;
+
+    /* make sure AES is set to forward mode */
+    aes_set_forward(base);
+
+    /* move 128-bit zeroes to INTEXT */
+    aes_gcm_one_block_input_only(base, blkZero);
+
+    /* set COPY_TO_Y command */
+    aes_command(base, AES_CMD_COPY_TO_Y(1));
+
+    if (ivSize != 12u)
+    {
+        /* if ivSize is not 12 bytes, we have to compute GF128 hash to get the initial counter J0 */
+        uint8_t ivBlkZero[16] = {0};
+
+        *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwapIntextHashIn;
+        while (ivSize >= 16u)
+        {
+            aes_gcm_one_block_input_only(base, iv);
+            iv += 16;
+            ivSize -= 16u;
+        }
+        if (ivSize)
+        {
+            aes_memcpy(ivBlkZero, iv, ivSize);
+            aes_gcm_one_block_input_only(base, ivBlkZero);
+        }
+
+        aes_memcpy(ivBlkZero, blkZero, 16);
+        aes_set_unaligned_from_word(swap_bytes(8 * saveIvSize), &ivBlkZero[12]);
+        aes_gcm_one_block_input_only(base, ivBlkZero);
+
+        aes_get_gf128(base, blkJ0);
+        aes_gcm_incr32(blkJ0);
+
+        /* put back the hash sub-key. this will abort running GF128, because we have to start new GF128 again for AAD
+         * and C */
+        *(volatile uint8_t *)((uint32_t)base) = (uint8_t)
+            kAES_CfgIntextSwap; /* do not swap OUTTEXT, as OUTTEXT is copied for further use into GF128_Y register */
+        *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgEncryptEcb;
+        aes_gcm_one_block_input_only(base, blkZero);
+        aes_command(base, AES_CMD_COPY_TO_Y(1));
+    }
+    else
+    {
+        aes_memcpy(blkJ0, iv, 12);
+        blkJ0[15] = 0x02U; /* add one to Counter for the first encryption with plaintext - see GCM specification */
+    }
+
+    /* process all AAD as GF128 of INTEXT, pad to full 16-bytes block with zeroes */
+    if (aadSize)
+    {
+        *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwapIntextHashIn;
+        while (aadSize >= 16u)
+        {
+            aes_gcm_one_block_input_only(base, aad);
+            aad += 16;
+            aadSize -= 16u;
+        }
+        if (aadSize)
+        {
+            uint8_t aadBlkZero[16] = {0};
+            aes_memcpy(aadBlkZero, aad, aadSize);
+            aes_gcm_one_block_input_only(base, aadBlkZero);
+        }
+    }
+
+    /* switch to EnryptDecryptHash, Hash of OUTTEXT, EncryptDecrypt in GCM mode */
+    /* Process all plaintext, pad to full 16-bytes block with zeroes */
+    if (encryptMode == kAES_ModeEncrypt)
+    {
+        *(volatile uint8_t *)((uint32_t)base) =
+            (uint8_t)kAES_CfgSwapEnDecHashOut; /* Encrypt operation adds output to hash */
+    }
+    else
+    {
+        *(volatile uint8_t *)((uint32_t)base) =
+            (uint8_t)kAES_CfgSwapEnDecHashIn; /* Decrypt operation adds input to hash */
+    }
+
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t) /*kAES_CfgCryptGcmTag*/ kAES_CfgCryptCtr;
+
+    aes_set_holding(base, blkJ0);
+
+    /* set counter increment by one */
+    base->CTR_INCR = 0x1U;
+
+    if (inputSize)
+    {
+        /* full 16-byte blocks */
+        while (inputSize >= 16u)
+        {
+            aes_one_block(base, dst, src);
+            inputSize -= 16u;
+            src += 16;
+            dst += 16;
+        }
+        /* last incomplete block. output shall be padded. */
+        if (inputSize)
+        {
+            if (encryptMode == kAES_ModeEncrypt)
+            {
+                uint8_t outputBlkZero[16] = {0};
+
+                /* I need to pad ciphertext, so I turn off the hash, and after I have ciphertext, I pad it with zeroes
+                 * and hash manually */
+                *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwap;
+                aes_memcpy(lastBlock, src, inputSize);
+                aes_one_block(base, lastBlock, lastBlock);
+                aes_memcpy(dst, lastBlock, inputSize);
+                /* pad the last output block with zeroes and add it to GF128 hash */
+                aes_memcpy(outputBlkZero, lastBlock, inputSize);
+                *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwapIntextHashIn;
+                aes_gcm_one_block_input_only(base, outputBlkZero);
+            }
+            else
+            {
+                aes_memcpy(lastBlock, src, inputSize);
+                aes_one_block(base, lastBlock, lastBlock);
+                aes_memcpy(dst, lastBlock, inputSize);
+            }
+        }
+    }
+
+    /* Process AAD len plus Ciphertext len */
+    *(volatile uint8_t *)((uint32_t)base)         = (uint8_t)kAES_CfgIntextSwap;
+    *(volatile uint16_t *)(((uint32_t)base + 2u)) = (uint16_t)kAES_CfgEncryptEcb;
+    aes_gcm_dec32(blkJ0);
+    aes_gcm_one_block_input_only(base, blkJ0);
+    *(volatile uint8_t *)((uint32_t)base) = (uint8_t)kAES_CfgSwapIntextHashIn;
+    if (saveSize)
+    {
+        aes_set_unaligned_from_word(swap_bytes(saveSize * 8u), &blkZero[12]);
+    }
+    if (saveAadSize)
+    {
+        aes_set_unaligned_from_word(swap_bytes(saveAadSize * 8u), &blkZero[4]);
+    }
+    aes_gcm_one_block_input_only(base, blkZero); /* len(A) || len(C) */
+    aes_gcm_get_tag(base, blkTag);
+
+    if (tag && tagSize)
+    {
+        if (encryptMode == kAES_ModeEncrypt)
+        {
+            aes_memcpy(tag, blkTag, tagSize);
+        }
+        else
+        {
+            size_t i       = 0;
+            uint32_t equal = 0;
+            uint32_t chXor;
+
+            while (i < tagSize)
+            {
+                chXor = tag[i] ^ blkTag[i];
+                equal |= chXor;
+                i++;
+            }
+
+            if (equal != 0)
+            {
+                status = kStatus_Fail;
+            }
+        }
+    }
+
+    return status;
+}
+
+/*!
+ * brief Encrypts AES and tags using GCM block mode.
+ *
+ * Encrypts AES and optionally tags using GCM block mode. If plaintext is NULL, only the GHASH is calculated and output
+ * in the 'tag' field.
+ *
+ * param base AES peripheral base address
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text.
+ * param size Size of input and output data in bytes
+ * param iv Input initial vector
+ * param ivSize Size of the IV
+ * param aad Input additional authentication data
+ * param aadSize Input size in bytes of AAD
+ * param[out] tag Output hash tag. Set to NULL to skip tag processing.
+ * param tagSize Input size of the tag to generate, in bytes. Must be 4,8,12,13,14,15 or 16.
+ * return Status from encrypt operation
+ */
+status_t AES_EncryptTagGcm(AES_Type *base,
+                           const uint8_t *plaintext,
+                           uint8_t *ciphertext,
+                           size_t size,
+                           const uint8_t *iv,
+                           size_t ivSize,
+                           const uint8_t *aad,
+                           size_t aadSize,
+                           uint8_t *tag,
+                           size_t tagSize)
+{
+    status_t status;
+    status =
+        aes_gcm_process(base, kAES_ModeEncrypt, plaintext, size, iv, ivSize, aad, aadSize, ciphertext, tag, tagSize);
+    return status;
+}
+
+/*!
+ * brief Decrypts AES and authenticates using GCM block mode.
+ *
+ * Decrypts AES and optionally authenticates using GCM block mode. If ciphertext is NULL, only the GHASH is calculated
+ * and compared with the received GHASH in 'tag' field.
+ *
+ * param base AES peripheral base address
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text.
+ * param size Size of input and output data in bytes
+ * param iv Input initial vector
+ * param ivSize Size of the IV
+ * param aad Input additional authentication data
+ * param aadSize Input size in bytes of AAD
+ * param tag Input hash tag to compare. Set to NULL to skip tag processing.
+ * param tagSize Input size of the tag, in bytes. Must be 4, 8, 12, 13, 14, 15, or 16.
+ * return Status from decrypt operation
+ */
+status_t AES_DecryptTagGcm(AES_Type *base,
+                           const uint8_t *ciphertext,
+                           uint8_t *plaintext,
+                           size_t size,
+                           const uint8_t *iv,
+                           size_t ivSize,
+                           const uint8_t *aad,
+                           size_t aadSize,
+                           const uint8_t *tag,
+                           size_t tagSize)
+{
+    uint8_t temp_tag[16] = {0}; /* max. octet length of MAC (tag) is 16 */
+    uint8_t *tag_ptr;
+    status_t status;
+
+    tag_ptr = NULL;
+    if (tag)
+    {
+        aes_memcpy(temp_tag, tag, tagSize);
+        tag_ptr = &temp_tag[0];
+    }
+
+    status = aes_gcm_process(base, kAES_ModeDecrypt, ciphertext, size, iv, ivSize, aad, aadSize, plaintext, tag_ptr,
+                             tagSize);
+    return status;
+}
+
+void AES_Init(AES_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* ungate clock */
+    CLOCK_EnableClock(kCLOCK_Aes);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+void AES_Deinit(AES_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* gate clock */
+    CLOCK_DisableClock(kCLOCK_Aes);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_aes.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_aes.h
new file mode 100755
index 0000000..7f7cf87
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_aes.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_AES_H_
+#define _FSL_AES_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup aes
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief Defines LPC AES driver version 2.0.1.
+ *
+ * Change log:
+ * - Version 2.0.0
+ *   - initial version
+ * - Version 2.0.1
+ *   - GCM constant time tag comparison
+ */
+#define FSL_AES_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
+/*@}*/
+
+/*******************************************************************************
+ * API
+ *******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @name AES Functional Operation
+ * @{
+ */
+
+/*! AES block size in bytes */
+#define AES_BLOCK_SIZE 16
+/*! AES Input Vector size in bytes */
+#define AES_IV_SIZE 16
+
+/*!
+ * @brief Sets AES key.
+ *
+ * Sets AES key.
+ *
+ * @param base AES peripheral base address
+ * @param key Input key to use for encryption or decryption
+ * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
+ * @return Status from Set Key operation
+ */
+status_t AES_SetKey(AES_Type *base, const uint8_t *key, size_t keySize);
+
+/*!
+ * @brief Encrypts AES using the ECB block mode.
+ *
+ * Encrypts AES using the ECB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptEcb(AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size);
+
+/*!
+ * @brief Decrypts AES using the ECB block mode.
+ *
+ * Decrypts AES using the ECB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input ciphertext to decrypt
+ * @param[out] plaintext Output plain text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptEcb(AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size);
+
+/*!
+ * @brief Encrypts AES using CBC block mode.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @param iv Input initial vector to combine with the first input block.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptCbc(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Decrypts AES using CBC block mode.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input cipher text to decrypt
+ * @param[out] plaintext Output plain text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @param iv Input initial vector to combine with the first input block.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptCbc(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Encrypts AES using CFB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @param iv Input Initial vector to be used as the first input block.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptCfb(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Decrypts AES using CFB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input cipher text to decrypt
+ * @param[out] plaintext Output plain text
+ * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * @param iv Input Initial vector to be used as the first input block.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptCfb(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Encrypts AES using OFB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text
+ * @param size Size of input and output data in bytes.
+ * @param iv Input Initial vector to be used as the first input block.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptOfb(
+    AES_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Decrypts AES using OFB block mode.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input cipher text to decrypt
+ * @param[out] plaintext Output plain text
+ * @param size Size of input and output data in bytes.
+ * @param iv Input Initial vector to be used as the first input block.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptOfb(
+    AES_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t iv[AES_IV_SIZE]);
+
+/*!
+ * @brief Encrypts or decrypts AES using CTR block mode.
+ *
+ * Encrypts or decrypts AES using CTR block mode.
+ * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
+ * The only difference between encryption and decryption is that, for encryption, the input argument
+ * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
+ * and the output argument is plain text.
+ *
+ * @param base AES peripheral base address
+ * @param input Input data for CTR block mode
+ * @param[out] output Output data for CTR block mode
+ * @param size Size of input and output data in bytes
+ * @param[in,out] counter Input counter (updates on return)
+ * @param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are
+ * not used.
+ * @param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
+ * are not used.
+ * @return Status from crypt operation
+ */
+status_t AES_CryptCtr(AES_Type *base,
+                      const uint8_t *input,
+                      uint8_t *output,
+                      size_t size,
+                      uint8_t counter[AES_BLOCK_SIZE],
+                      uint8_t counterlast[AES_BLOCK_SIZE],
+                      size_t *szLeft);
+
+/*!
+ * @brief Encrypts AES and tags using GCM block mode.
+ *
+ * Encrypts AES and optionally tags using GCM block mode. If plaintext is NULL, only the GHASH is calculated and output
+ * in the 'tag' field.
+ *
+ * @param base AES peripheral base address
+ * @param plaintext Input plain text to encrypt
+ * @param[out] ciphertext Output cipher text.
+ * @param size Size of input and output data in bytes
+ * @param iv Input initial vector
+ * @param ivSize Size of the IV
+ * @param aad Input additional authentication data
+ * @param aadSize Input size in bytes of AAD
+ * @param[out] tag Output hash tag. Set to NULL to skip tag processing.
+ * @param tagSize Input size of the tag to generate, in bytes. Must be 4,8,12,13,14,15 or 16.
+ * @return Status from encrypt operation
+ */
+status_t AES_EncryptTagGcm(AES_Type *base,
+                           const uint8_t *plaintext,
+                           uint8_t *ciphertext,
+                           size_t size,
+                           const uint8_t *iv,
+                           size_t ivSize,
+                           const uint8_t *aad,
+                           size_t aadSize,
+                           uint8_t *tag,
+                           size_t tagSize);
+
+/*!
+ * @brief Decrypts AES and authenticates using GCM block mode.
+ *
+ * Decrypts AES and optionally authenticates using GCM block mode. If ciphertext is NULL, only the GHASH is calculated
+ * and compared with the received GHASH in 'tag' field.
+ *
+ * @param base AES peripheral base address
+ * @param ciphertext Input cipher text to decrypt
+ * @param[out] plaintext Output plain text.
+ * @param size Size of input and output data in bytes
+ * @param iv Input initial vector
+ * @param ivSize Size of the IV
+ * @param aad Input additional authentication data
+ * @param aadSize Input size in bytes of AAD
+ * @param tag Input hash tag to compare. Set to NULL to skip tag processing.
+ * @param tagSize Input size of the tag, in bytes. Must be 4, 8, 12, 13, 14, 15, or 16.
+ * @return Status from decrypt operation
+ */
+status_t AES_DecryptTagGcm(AES_Type *base,
+                           const uint8_t *ciphertext,
+                           uint8_t *plaintext,
+                           size_t size,
+                           const uint8_t *iv,
+                           size_t ivSize,
+                           const uint8_t *aad,
+                           size_t aadSize,
+                           const uint8_t *tag,
+                           size_t tagSize);
+
+void AES_Init(AES_Type *base);
+
+void AES_Deinit(AES_Type *base);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @}*/
+/*! @}*/ /* end of group aes */
+
+#endif /* _FSL_AES_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_clock.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_clock.c
new file mode 100755
index 0000000..ad8c160
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_clock.c
@@ -0,0 +1,1199 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_clock.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.clock"
+#endif
+#define OSC32K_FREQ 32768UL
+#define FRO32K_FREQ 32768UL
+#define OSC32M_FREQ 32000000UL
+#define XTAL32M_FREQ 32000000UL
+#define FRO64M_FREQ 64000000UL
+#define FRO1M_FREQ 1000000UL
+#define FRO12M_FREQ 12000000UL
+#define FRO32M_FREQ 32000000UL
+#define FRO48M_FREQ 48000000UL
+
+/* Return values from Config (N-2) page of flash */
+#define GET_CAL_DATE() (*(uint32_t *)0x9FC68)
+#define GET_32MXO_TRIM() (*(uint32_t *)0x9FCF0)
+#define GET_32KXO_TRIM() (*(uint32_t *)0x9FCF4)
+#define GET_ATE_TEMP() (*(uint32_t *)0x9FDC8)
+
+#define XO_SLAVE_EN (1)
+
+/*******************************************************************************
+ * Storage
+ ******************************************************************************/
+/** External clock rate on the CLKIN pin in Hz. If not used,
+    set this to 0. Otherwise, set it to the exact rate in Hz this pin is
+    being driven at. */
+const uint32_t g_Ext_Clk_Freq = 0U;
+
+#define CLOCK_32MfXtalIecLoadpF_x100_default (600)   /* 6.0pF */
+#define CLOCK_32MfXtalPPcbParCappF_x100_default (10) /* 0.1pF */
+#define CLOCK_32MfXtalNPcbParCappF_x100_default (5)  /* 0.05pF */
+
+const ClockCapacitanceCompensation_t default_Clock32MCapacitanceCharacteristics = {
+    .clk_XtalIecLoadpF_x100    = CLOCK_32MfXtalIecLoadpF_x100_default,
+    .clk_XtalPPcbParCappF_x100 = CLOCK_32MfXtalPPcbParCappF_x100_default,
+    .clk_XtalNPcbParCappF_x100 = CLOCK_32MfXtalNPcbParCappF_x100_default};
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+uint32_t CLOCK_GetOsc32kFreq(void);
+uint32_t CLOCK_GetOsc32MFreq(void);
+uint32_t CLOCK_GetFRGInputClock(void);
+/*! brief      Return Frequency of Spifi Clock
+ *  return     Frequency of Spifi.
+ */
+uint32_t CLOCK_GetSpifiClkFreq(void);
+uint32_t CLOCK_GetAdcClock(void);
+uint32_t CLOCK_GetSystemClockRate(void);
+uint32_t CLOCK_GetCoreSysClkFreq(void);
+uint32_t CLOCK_GetMainClockRate(void);
+uint32_t CLOCK_GetXtal32kFreq(void);
+uint32_t CLOCK_GetXtal32MFreq(void);
+uint32_t CLOCK_GetFro32kFreq(void);
+uint32_t CLOCK_GetFro1MFreq(void);
+uint32_t CLOCK_GetFro12MFreq(void);
+uint32_t CLOCK_GetFro32MFreq(void);
+uint32_t CLOCK_GetFro48MFreq(void);
+uint32_t CLOCK_GetFro64MFreq(void);
+uint32_t CLOCK_GetSpifiOscFreq(void);
+uint32_t CLOCK_GetWdtOscFreq(void);
+uint32_t CLOCK_GetPWMClockFreq(void);
+
+static uint8_t CLOCK_u8OscCapConvert(uint32_t OscCap, uint8_t u8CapBankDiscontinuity);
+
+/*******************************************************************************
+ * types
+ ******************************************************************************/
+
+/**
+ * brief	Selects clock source using <name>SEL register in syscon
+ * param   clock_attach_id_t  specify clock mapping
+ * return	none
+ * note
+ */
+void CLOCK_AttachClk(clock_attach_id_t connection)
+{
+    uint8_t mux;
+    uint8_t pos;
+    volatile uint32_t *pClkSel;
+    clock_div_name_t clockDiv = kCLOCK_DivNone;
+
+    pClkSel = (uint32_t *)SYSCON;
+
+    switch (connection)
+    {
+        case kXTAL32M_to_MAIN_CLK:
+        case kXTAL32M_to_OSC32M_CLK:
+        case kXTAL32M_to_CLKOUT:
+        case kXTAL32M_to_SPIFI:
+        case kXTAL32M_to_ADC_CLK:
+        case kXTAL32M_to_ASYNC_APB:
+            /* Enable the 32MHz clock distribution to digital core (CGU, MCU) */
+            ASYNC_SYSCON->XTAL32MCTRL |= ASYNC_SYSCON_XTAL32MCTRL_XO32M_TO_MCU_ENABLE_MASK;
+            break;
+
+        default:
+            break;
+    }
+
+    switch (connection & 0xFFF)
+    {
+        case CM_CLKOUTCLKSEL:
+            clockDiv = kCLOCK_DivClkout;
+            break;
+        case CM_SPIFICLKSEL:
+            clockDiv = kCLOCK_DivSpifiClk;
+            break;
+        case CM_ADCCLKSEL:
+            clockDiv = kCLOCK_DivAdcClk;
+            break;
+        case CM_IRCLKSEL:
+            clockDiv = kCLOCK_DivIrClk;
+            break;
+        case CM_WDTCLKSEL:
+            clockDiv = kCLOCK_DivWdtClk;
+            break;
+        case CM_DMICLKSEL:
+            clockDiv = kCLOCK_DivDmicClk;
+            break;
+        default:
+            break;
+    }
+
+    if (clockDiv != 0)
+    {
+        pClkSel[clockDiv] |= (1U << 30U); /* halts the divider counter to avoid glitch */
+    }
+
+    mux = (uint8_t)(connection & 0xfff);
+    if (((uint32_t)connection) != 0)
+    {
+        pos = (uint8_t)((connection & 0xf000U) >> 12U) - 1U;
+        if (mux == CM_ASYNCAPB)
+        {
+            ASYNC_SYSCON->ASYNCAPBCLKSELA = pos;
+        }
+        else if (mux == CM_OSC32CLKSEL)
+        {
+            if (pos < 2)
+            {
+                pClkSel[mux] &= ~SYSCON_OSC32CLKSEL_SEL32MHZ_MASK;
+                pClkSel[mux] |= pos;
+            }
+            else
+            {
+                pClkSel[mux] &= ~SYSCON_OSC32CLKSEL_SEL32KHZ_MASK;
+                pClkSel[mux] |= ((pos - 2) << SYSCON_OSC32CLKSEL_SEL32KHZ_SHIFT);
+            }
+        }
+        else if (mux == CM_MODEMCLKSEL)
+        {
+            if (pos < 2)
+            {
+                pClkSel[mux] |= SYSCON_MODEMCLKSEL_SEL_ZIGBEE_MASK;
+                pClkSel[mux] &= ((uint32_t)pos | 0x2U);
+            }
+            else
+            {
+                pClkSel[mux] |= SYSCON_MODEMCLKSEL_SEL_BLE_MASK;
+                pClkSel[mux] &= ((uint32_t)((pos - 2) << SYSCON_MODEMCLKSEL_SEL_BLE_SHIFT) | 0x1U);
+            }
+        }
+        else
+        {
+            pClkSel[mux] = pos;
+        }
+    }
+
+    if (clockDiv != 0)
+    {
+        pClkSel[clockDiv] &= ~(1U << 30U); /* release the divider counter */
+    }
+}
+
+/**
+ * brief	Selects clock divider using <name>DIV register in syscon
+ * param   clock_div_name_t  	specifies which DIV register we are accessing
+ * param   uint32_t			specifies divisor
+ * param	bool				true if a syscon clock reset should also be carried out
+ * return	none
+ * note
+ */
+void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
+{
+    volatile uint32_t *pClkDiv;
+    pClkDiv = (uint32_t *)SYSCON;
+
+    pClkDiv[div_name] |= (1U << 30U); /* halts the divider counter to avoid glitch */
+
+    if (divided_by_value != 0U)
+    {
+        pClkDiv[div_name] = (1U << 30U) | (divided_by_value - 1U);
+    }
+
+    if (reset)
+    {
+        pClkDiv[div_name] |= 1U << 29U;
+        pClkDiv[div_name] &= ~(1U << 29U);
+    }
+
+    pClkDiv[div_name] &= ~(1U << 30U); /* release the divider counter */
+}
+
+uint32_t CLOCK_GetClkDiv(clock_div_name_t div_name)
+{
+    volatile uint32_t *pClkDiv;
+    uint32_t div = 0;
+
+    pClkDiv = (uint32_t *)SYSCON;
+    div     = pClkDiv[div_name] + 1;
+
+    return div;
+}
+
+uint32_t CLOCK_GetFRGInputClock(void)
+{
+    uint32_t freq = 0;
+
+    switch ((frg_clock_src_t)((SYSCON->FRGCLKSEL & SYSCON_FRGCLKSEL_SEL_MASK) >> SYSCON_FRGCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_FrgMainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+
+        case kCLOCK_FrgOsc32MClk:
+            freq = CLOCK_GetOsc32MFreq();
+            break;
+
+        case kCLOCK_FrgFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+
+        case kCLOCK_FrgNoClock:
+            freq = 0;
+            break;
+
+        default:
+            freq = 0;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_SetFRGClock(uint32_t freq)
+{
+    uint32_t input = CLOCK_GetFRGInputClock();
+    uint32_t mul;
+
+    if ((freq > 48000000) || (freq > input) || ((freq != 0) && (input / freq >= 2)))
+    {
+        /* FRG output frequency should be less than equal to 48MHz */
+        return 0;
+    }
+    else
+    {
+        mul             = ((uint64_t)(input - freq) * 256) / ((uint64_t)freq);
+        SYSCON->FRGCTRL = (mul << SYSCON_FRGCTRL_MULT_SHIFT) | SYSCON_FRGCTRL_DIV_MASK;
+        return 1;
+    }
+}
+
+uint32_t CLOCK_GetFRGClock(void)
+{
+    uint32_t freq = 0;
+
+    if (((SYSCON->FRGCTRL & SYSCON_FRGCTRL_DIV_MASK) >> SYSCON_FRGCTRL_DIV_SHIFT) == 255)
+    {
+        // We can use a shift here since only divide by 256 is supported
+        freq = ((uint64_t)CLOCK_GetFRGInputClock() << 8) /
+               (((SYSCON->FRGCTRL & SYSCON_FRGCTRL_MULT_MASK) >> SYSCON_FRGCTRL_MULT_SHIFT) + 256);
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetClkOutFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((clkout_clock_src_t)((SYSCON->CLKOUTSEL & SYSCON_CLKOUTSEL_SEL_MASK) >> SYSCON_CLKOUTSEL_SEL_SHIFT))
+    {
+        case kCLOCK_ClkoutMainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+
+        case kCLOCK_ClkoutXtal32k:
+            freq = CLOCK_GetXtal32kFreq();
+            break;
+
+        case kCLOCK_ClkoutFro32k:
+            freq = CLOCK_GetFro32kFreq();
+            break;
+
+        case kCLOCK_ClkoutXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_ClkoutDcDcTest:
+            freq = CLOCK_GetFro64MFreq();
+            break;
+
+        case kCLOCK_ClkoutFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        case kCLOCK_ClkoutFro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+        case kCLOCK_ClkoutNoClock:
+            freq = 0;
+            break;
+        default:
+            freq = 0;
+            break;
+    }
+
+    freq /= (((SYSCON->CLKOUTDIV & SYSCON_CLKOUTDIV_DIV_MASK) >> SYSCON_CLKOUTDIV_DIV_SHIFT) + 1);
+
+    return freq;
+}
+
+uint32_t CLOCK_GetWdtOscFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((wdt_clock_src_t)((SYSCON->WDTCLKSEL & SYSCON_WDTCLKSEL_SEL_MASK) >> SYSCON_WDTCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_WdtOsc32MClk:
+            freq = CLOCK_GetOsc32MFreq();
+            break;
+
+        case kCLOCK_WdtOsc32kClk:
+            freq = CLOCK_GetOsc32kFreq();
+            break;
+
+        case kCLOCK_WdtFro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+
+        case kCLOCK_WdtNoClock:
+            freq = 0;
+            break;
+
+        default:
+            freq = 0;
+            break;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetSpifiOscFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((spifi_clock_src_t)((SYSCON->SPIFICLKSEL & SYSCON_SPIFICLKSEL_SEL_MASK) >> SYSCON_SPIFICLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_SpifiMainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+        case kCLOCK_SpifiXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+        case kCLOCK_SpifiFro64M:
+            freq = CLOCK_GetFro64MFreq();
+            break;
+        case kCLOCK_SpifiFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        case kCLOCK_SpifiNoClock:
+            freq = 0;
+            break;
+        default:
+            freq = 0;
+            break;
+    }
+    freq /= (((SYSCON->SPIFICLKDIV & SYSCON_SPIFICLKDIV_DIV_MASK) >> SYSCON_SPIFICLKDIV_DIV_SHIFT) + 1);
+
+    return freq;
+}
+
+uint32_t CLOCK_GetPWMClockFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((pwm_clock_source_t)((SYSCON->PWMCLKSEL & SYSCON_PWMCLKSEL_SEL_MASK) >> SYSCON_PWMCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_PWMOsc32Mclk:
+            freq = CLOCK_GetOsc32MFreq();
+            break;
+        case kCLOCK_PWMFro48Mclk:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        case kCLOCK_PWMNoClkSel:
+            freq = 0;
+            break;
+        case kCLOCK_PWMTestClk:
+            freq = 0;
+            break;
+    }
+
+    return freq;
+}
+
+/**
+ * brief	Obtains frequency of specified clock
+ * param   clock_name_t  specify clock to be read
+ * return	uint32_t      frequency
+ * note
+ */
+uint32_t CLOCK_GetFreq(clock_name_t clockName)
+{
+    uint32_t freq = 0;
+    switch (clockName)
+    {
+        case kCLOCK_MainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+        case kCLOCK_CoreSysClk:
+            freq = CLOCK_GetCoreSysClkFreq();
+            break;
+        case kCLOCK_BusClk:
+            freq = CLOCK_GetCoreSysClkFreq();
+            break;
+        case kCLOCK_Xtal32k:
+            freq = CLOCK_GetXtal32kFreq();
+            break;
+        case kCLOCK_Xtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+        case kCLOCK_Fro32k:
+            freq = CLOCK_GetFro32kFreq();
+            break;
+        case kCLOCK_Fro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+        case kCLOCK_Fro12M:
+            freq = CLOCK_GetFro12MFreq();
+            break;
+        case kCLOCK_Fro32M:
+            freq = CLOCK_GetFro32MFreq();
+            break;
+        case kCLOCK_Fro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        case kCLOCK_Fro64M:
+            freq = CLOCK_GetFro64MFreq();
+            break;
+        case kCLOCK_ExtClk:
+            freq = g_Ext_Clk_Freq;
+            break;
+        case kCLOCK_WdtOsc:
+            freq = CLOCK_GetWdtOscFreq() / ((SYSCON->WDTCLKDIV & SYSCON_WDTCLKDIV_DIV_MASK) + 1);
+            ;
+            break;
+        case kCLOCK_Frg:
+            freq = CLOCK_GetFRGClock();
+            break;
+        case kCLOCK_ClkOut:
+            freq = CLOCK_GetClkOutFreq();
+            break;
+        case kCLOCK_Spifi:
+            freq = CLOCK_GetSpifiOscFreq();
+            break;
+        case kCLOCK_WdtClk:
+            freq = CLOCK_GetWdtOscFreq() / ((SYSCON->WDTCLKDIV & SYSCON_WDTCLKDIV_DIV_MASK) + 1);
+            break;
+        case kCLOCK_Pwm:
+            freq = CLOCK_GetPWMClockFreq();
+            break;
+        case kCLOCK_Timer0:
+        case kCLOCK_Timer1:
+            freq = CLOCK_GetApbCLkFreq();
+            break;
+        default:
+            freq = 0;
+            break;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetCoreSysClkFreq(void)
+{
+    /* No point in checking for divide by 0 */
+    return CLOCK_GetMainClockRate() / ((SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK) + 1U);
+}
+
+/* Return main clock rate */
+uint32_t CLOCK_GetMainClockRate(void)
+{
+    uint32_t freq = 0;
+
+    switch ((main_clock_src_t)((SYSCON->MAINCLKSEL & SYSCON_MAINCLKSEL_SEL_MASK) >> SYSCON_MAINCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_MainFro12M:
+            freq = CLOCK_GetFro12MFreq();
+            break;
+
+        case kCLOCK_MainOsc32k:
+            freq = CLOCK_GetOsc32kFreq();
+            break;
+
+        case kCLOCK_MainXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_MainFro32M:
+            freq = CLOCK_GetFro32MFreq();
+            break;
+
+        case kCLOCK_MainFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+
+        case kCLOCK_MainExtClk:
+            freq = g_Ext_Clk_Freq;
+            break;
+
+        case kCLOCK_MainFro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetOsc32kFreq(void)
+{
+    uint32_t freq = 0;
+    if ((SYSCON->OSC32CLKSEL & SYSCON_OSC32CLKSEL_SEL32KHZ_MASK) != 0)
+    {
+        freq = CLOCK_GetXtal32kFreq();
+    }
+    else
+    {
+        freq = CLOCK_GetFro32kFreq();
+    }
+    return freq;
+}
+
+uint32_t CLOCK_GetOsc32MFreq(void)
+{
+    uint32_t freq = 0;
+    if ((SYSCON->OSC32CLKSEL & SYSCON_OSC32CLKSEL_SEL32MHZ_MASK) != 0)
+    {
+        freq = CLOCK_GetXtal32MFreq();
+    }
+    else
+    {
+        freq = CLOCK_GetFro32MFreq();
+    }
+    return freq;
+}
+
+uint32_t CLOCK_GetXtal32kFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_XTAL32K_MASK) >> PMC_PDRUNCFG_ENA_XTAL32K_SHIFT) != 0)
+    {
+        freq = OSC32K_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetXtal32MFreq(void)
+{
+    return XTAL32M_FREQ;
+}
+
+uint32_t CLOCK_GetFro32kFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_FRO32K_MASK) >> PMC_PDRUNCFG_ENA_FRO32K_SHIFT) != 0)
+    {
+        freq = FRO32K_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetFro1MFreq(void)
+{
+    return FRO1M_FREQ;
+}
+
+uint32_t CLOCK_GetFro12MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO12M_ENA)
+    {
+        freq = FRO12M_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetFro32MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO32M_ENA)
+    {
+        freq = FRO32M_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetFro48MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO48M_ENA)
+    {
+        freq = FRO48M_FREQ;
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetFro64MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO64M_ENA)
+    {
+        freq = FRO64M_FREQ;
+    }
+
+    return freq;
+}
+
+/*! brief      Return Frequency of Spifi Clock
+ *  return     Frequency of Spifi.
+ */
+uint32_t CLOCK_GetSpifiClkFreq(void)
+{
+    uint32_t freq = 0;
+
+    switch ((spifi_clock_src_t)((SYSCON->SPIFICLKSEL & SYSCON_SPIFICLKSEL_SEL_MASK) >> SYSCON_SPIFICLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_SpifiMainClk:
+            freq = CLOCK_GetMainClockRate();
+            break;
+
+        case kCLOCK_SpifiXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_SpifiFro64M:
+            freq = CLOCK_GetFro64MFreq();
+            break;
+
+        case kCLOCK_SpifiFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+
+        case kCLOCK_SpifiNoClock:
+            freq = 0;
+            break;
+
+        default:
+            freq = 0;
+            break;
+    }
+
+    if (freq > 0)
+    {
+    }
+
+    return freq;
+}
+
+uint32_t CLOCK_GetAdcClock(void)
+{
+    uint32_t freq = 0;
+
+    switch ((adc_clock_src_t)((SYSCON->ADCCLKSEL) & SYSCON_ADCCLKSEL_SEL_MASK >> SYSCON_ADCCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_AdcXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_AdcFro12M:
+            freq = CLOCK_GetFro12MFreq();
+            break;
+
+        case kCLOCK_AdcNoClock:
+            freq = 0;
+            break;
+
+        default:
+            freq = 0;
+    }
+
+    if (freq > 0)
+    {
+        freq /= (((SYSCON->ADCCLKDIV & SYSCON_ADCCLKDIV_DIV_MASK) >> SYSCON_ADCCLKDIV_DIV_SHIFT) + 1);
+    }
+
+    return freq;
+}
+
+/**
+ * brief	Obtains frequency of APB Bus clock
+ * param   none
+ * return	uint32_t      frequency
+ * note
+ */
+uint32_t CLOCK_GetApbCLkFreq(void)
+{
+    uint32_t freq = 0;
+    /* ASYNCAPBCLKSEL[1:0] says which Clock Mux input is selected for APB */
+    switch (ASYNC_SYSCON->ASYNCAPBCLKSELA & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK)
+    {
+        case kCLOCK_ApbMainClk: /* Main Clk */
+            freq = CLOCK_GetMainClockRate();
+            break;
+        case kCLOCK_ApbXtal32M: /* XTAL 32M */
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+        case kCLOCK_ApbFro32M: /* FRO32M */
+            freq = CLOCK_GetFro32MFreq();
+            break;
+        case kCLOCK_ApbFro48M: /* FRO48M */
+            freq = CLOCK_GetFro48MFreq();
+            break;
+        default:
+            freq = 0;
+            break;
+    }
+
+    return freq;
+}
+/**
+ * brief	Enables specific AHB clock channel
+ * param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * return	none
+ * note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+void CLOCK_EnableClock(clock_ip_name_t clk)
+{
+    uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
+    switch (index)
+    {
+        case 0:
+        case 1:
+            SYSCON->AHBCLKCTRLSETS[index] = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+            break;
+
+        case 2:
+            SYSCON->ASYNCAPBCTRL             = SYSCON_ASYNCAPBCTRL_ENABLE(1);
+            ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+            break;
+
+        default:
+            switch (clk)
+            {
+                case kCLOCK_Xtal32k:
+                    PMC->PDRUNCFG |= PMC_PDRUNCFG_ENA_XTAL32K_MASK;
+                    SYSCON->OSC32CLKSEL |= SYSCON_OSC32CLKSEL_SEL32KHZ_MASK;
+                    break;
+
+                case kCLOCK_Xtal32M:
+                    /* Only do something if not started already */
+                    if (!(ASYNC_SYSCON->XTAL32MCTRL & ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK))
+                    {
+                        /* XTAL only biased from PMC - force this bit on */
+                        ASYNC_SYSCON->XTAL32MCTRL |= ASYNC_SYSCON_XTAL32MCTRL_XO_STANDALONE_ENABLE_MASK;
+                        /* Enable & set-up XTAL 32 MHz clock core */
+                        CLOCK_XtalBasicTrim();
+
+                        /* Wait for clock to stabilize, plus 200us */
+                        CLOCK_Xtal32M_WaitUntilStable(200);
+                    }
+                    break;
+
+                case kCLOCK_Fro32k:
+                    PMC->PDRUNCFG |= PMC_PDRUNCFG_ENA_FRO32K_MASK;
+                    SYSCON->OSC32CLKSEL &= ~SYSCON_OSC32CLKSEL_SEL32KHZ_MASK;
+                    break;
+
+                case kCLOCK_Fro12M:
+                    PMC->FRO192M |= (FRO12M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro32M:
+                    PMC->FRO192M |= (FRO32M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro48M:
+                    PMC->FRO192M |= (FRO48M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro64M:
+                    PMC->FRO192M |= (FRO64M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fmeas:
+                    /* FRO1M and XTAL32M clock gating (SYSCON->CLOCK_CTRL)
+                     * is handled by FMEAS driver */
+                    break;
+
+                default:
+                    break;
+            }
+            break;
+    }
+}
+
+/**
+ * brief	Disables specific AHB clock channel
+ * param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * return	none
+ * note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+void CLOCK_DisableClock(clock_ip_name_t clk)
+{
+    uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
+    switch (index)
+    {
+        case 0:
+        case 1:
+            SYSCON->AHBCLKCTRLCLRS[index] = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+            break;
+
+        case 2:
+            ASYNC_SYSCON->ASYNCAPBCLKCTRLCLR = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+            break;
+
+        default:
+            switch (clk)
+            {
+                case kCLOCK_Fro32k:
+                    PMC->PDRUNCFG &= ~PMC_PDRUNCFG_ENA_FRO32K_MASK;
+                    break;
+
+                case kCLOCK_Xtal32k:
+                    PMC->PDRUNCFG &= ~PMC_PDRUNCFG_ENA_XTAL32K_MASK;
+                    break;
+
+                case kCLOCK_Xtal32M:
+                    ASYNC_SYSCON->XTAL32MCTRL &= ~(ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK);
+                    break;
+
+                case kCLOCK_Fro12M:
+                    PMC->FRO192M &= ~(FRO12M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro32M:
+                    PMC->FRO192M &= ~(FRO32M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro48M:
+                    PMC->FRO192M &= ~(FRO48M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                case kCLOCK_Fro64M:
+                    PMC->FRO192M &= ~(FRO64M_ENA << PMC_FRO192M_DIVSEL_SHIFT);
+                    break;
+
+                default:
+                    break;
+            }
+            break;
+    }
+}
+
+/**
+ * brief	Check if clock is enabled
+ * param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * return  bool
+ * note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+bool CLOCK_IsClockEnable(clock_ip_name_t clk)
+{
+    uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
+    return (SYSCON->AHBCLKCTRLSETS[index] & (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)));
+}
+
+void CLOCK_EnableAPBBridge(void)
+{
+    SYSCON->ASYNCAPBCTRL |= ((1 << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK);
+}
+
+void CLOCK_DisableAPBBridge(void)
+{
+    SYSCON->ASYNCAPBCTRL &= ~((1 << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK);
+}
+
+/*! brief   Delay execution by busy waiting
+ *  param   delayUs delay duration in micro seconds
+ *  return  none
+ */
+void CLOCK_uDelay(uint32_t delayUs)
+{
+    uint32_t freqMhz, timeout;
+    uint32_t trcena, cyccntena;
+
+    trcena    = CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk;
+    cyccntena = DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk;
+
+    /* EMCR.TRCENA: enable DWT unit */
+    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+
+    /* DWT.CYCCNTENA: enable cycle count register */
+    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+
+    freqMhz = CLOCK_GetFreq(kCLOCK_CoreSysClk) / 1000000;
+    timeout = delayUs * freqMhz + DWT->CYCCNT;
+
+    while ((int32_t)(timeout - DWT->CYCCNT) > 0)
+        ;
+
+    /* Restore TRCENA and CYCCNTENA original states */
+    if (!cyccntena)
+    {
+        DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
+    }
+    if (!trcena)
+    {
+        CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
+    }
+}
+
+void CLOCK_XtalBasicTrim(void)
+{
+#ifdef OBSOLETED_CODE
+    /* Basic trim with default good values */
+    uint32_t u32RegVal;
+
+    /* Enable and set LDO, if not already done */
+    CLOCK_SetXtal32M_LDO();
+
+    /* Read, modify, write ASYNC_SYSCON->XTAL32MCTRL register */
+    u32RegVal = ASYNC_SYSCON->XTAL32MCTRL;
+
+#if (XO_SLAVE_EN == 0)
+#error Code below assumes that trimming always sets \
+       ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK but configuration \
+       of XO_SLAVE_EN means that this may not be the case
+#endif
+
+    /* Reset ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK value is 0,
+     * but all trimming operations set it to 1. This function is called as a
+     * default/catch-all, so if trimming has already been applied since reset
+     * we do not want to overwrite it now in case that previous trimming was
+     * the more sophisticated CLOCK_Xtal32M_Trim. Hence we only apply the trim
+     * values if ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK is 0 */
+    if (0U == (u32RegVal & ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK))
+    {
+        u32RegVal &= ~(ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_MASK | ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_MASK |
+                       ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK | ASYNC_SYSCON_XTAL32MCTRL_XO_GM_MASK);
+
+        u32RegVal |= (ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE(1) | ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE(1) |
+                      ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE(1) | ASYNC_SYSCON_XTAL32MCTRL_XO_GM(3));
+
+        /* ES2 default */
+        u32RegVal |= 34U << ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_SHIFT;
+        u32RegVal |= 30U << ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_SHIFT;
+
+        ASYNC_SYSCON->XTAL32MCTRL = u32RegVal;
+    }
+#else
+    CLOCK_Xtal32M_Trim(0, &default_Clock32MCapacitanceCharacteristics);
+#endif
+}
+
+/*
+ * param  XO_32M_OSC_CAP_Delta_x1000 Osc capacitance expressed in fF (femtoFarad).
+ * Must be 0 if no temperature compensation algorithm is implemented for a given board
+ *
+ */
+void CLOCK_Xtal32M_Trim(int32_t XO_32M_OSC_CAP_Delta_x1000, const ClockCapacitanceCompensation_t *capa_charac)
+{
+    uint32_t u32XOTrimValue;
+    uint8_t u8IECXinCapCal6pF, u8IECXinCapCal8pF, u8IECXoutCapCal6pF, u8IECXoutCapCal8pF, u8XOSlave;
+    int32_t iaXin_x4, ibXin, iaXout_x4, ibXout;
+    int32_t iXOCapInpF_x100, iXOCapOutpF_x100;
+    uint32_t u32XOCapInCtrl, u32XOCapOutCtrl;
+    uint32_t u32RegVal;
+
+    /* Enable and set LDO, if not already done */
+    CLOCK_SetXtal32M_LDO();
+
+    /* Get Cal values from Flash */
+    u32XOTrimValue = GET_32MXO_TRIM();
+
+    /* Check validity and apply */
+    if ((u32XOTrimValue & 1) && ((u32XOTrimValue >> 15) & 1) && (GET_CAL_DATE() >= 20181203))
+    {
+        /* These fields are 7 bits, unsigned */
+        u8IECXinCapCal6pF  = (u32XOTrimValue >> 1) & 0x7f;
+        u8IECXinCapCal8pF  = (u32XOTrimValue >> 8) & 0x7f;
+        u8IECXoutCapCal6pF = (u32XOTrimValue >> 16) & 0x7f;
+        u8IECXoutCapCal8pF = (u32XOTrimValue >> 23) & 0x7f;
+
+        /* This field is 1 bit */
+        u8XOSlave = (u32XOTrimValue >> 30) & 0x1;
+
+        /* Linear fit coefficients calculation */
+        iaXin_x4  = (int)u8IECXinCapCal8pF - (int)u8IECXinCapCal6pF;
+        ibXin     = (int)u8IECXinCapCal6pF - iaXin_x4 * 3;
+        iaXout_x4 = (int)u8IECXoutCapCal8pF - (int)u8IECXoutCapCal6pF;
+        ibXout    = (int)u8IECXoutCapCal6pF - iaXout_x4 * 3;
+    }
+    else
+    {
+        iaXin_x4  = 20;  // gain in LSB/pF 4.882pF
+        ibXin     = -14; // offset in LSB -13.586
+        iaXout_x4 = 19;  // gain in LSB/pF 4.864
+        ibXout    = -15; // offset in LSB -14.5
+        u8XOSlave = 0;
+    }
+
+    /* In & out load cap calculation with derating */
+    iXOCapInpF_x100 = 2 * capa_charac->clk_XtalIecLoadpF_x100 - capa_charac->clk_XtalNPcbParCappF_x100 +
+                      39 * (XO_SLAVE_EN - u8XOSlave) - 15;
+    iXOCapOutpF_x100 = 2 * capa_charac->clk_XtalIecLoadpF_x100 - capa_charac->clk_XtalPPcbParCappF_x100 - 21;
+
+    iXOCapInpF_x100  = iXOCapInpF_x100 + XO_32M_OSC_CAP_Delta_x1000 / 5;
+    iXOCapOutpF_x100 = iXOCapOutpF_x100 + XO_32M_OSC_CAP_Delta_x1000 / 5;
+
+    /* In & out XO_OSC_CAP_Code_CTRL calculation, with rounding */
+    u32XOCapInCtrl  = (uint32_t)(((iXOCapInpF_x100 * iaXin_x4 + ibXin * 400) + 200) / 400);
+    u32XOCapOutCtrl = (uint32_t)(((iXOCapOutpF_x100 * iaXout_x4 + ibXout * 400) + 200) / 400);
+
+    uint8_t u8XOCapInCtrl  = CLOCK_u8OscCapConvert(u32XOCapInCtrl, 13);
+    uint8_t u8XOCapOutCtrl = CLOCK_u8OscCapConvert(u32XOCapOutCtrl, 13);
+
+    /* Read register and clear fields to be written */
+    u32RegVal = ASYNC_SYSCON->XTAL32MCTRL;
+    u32RegVal &= ~(ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN_MASK | ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT_MASK |
+                   ASYNC_SYSCON_XTAL32MCTRL_XO_GM_MASK | ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE_MASK |
+                   ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE_MASK);
+
+/* Configuration of 32 MHz XO output buffers */
+#if (XO_SLAVE_EN != 0)
+    u32RegVal |= (ASYNC_SYSCON_XTAL32MCTRL_XO_SLAVE(1) | ASYNC_SYSCON_XTAL32MCTRL_XO_ACBUF_PASS_ENABLE(1));
+#endif
+
+    /* XO_OSC_CAP_Code_CTRL to XO_OSC_CAP_Code conversion */
+    u32RegVal |= ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE(1);
+    u32RegVal |= ASYNC_SYSCON_XTAL32MCTRL_XO_GM(3);
+    u32RegVal |= ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_IN(u8XOCapInCtrl);
+    u32RegVal |= ASYNC_SYSCON_XTAL32MCTRL_XO_OSC_CAP_OUT(u8XOCapOutCtrl);
+
+    /* Write back to register */
+    ASYNC_SYSCON->XTAL32MCTRL = u32RegVal;
+}
+
+void CLOCK_Xtal32k_Trim(int32_t XO_32k_OSC_CAP_Delta_x1000, const ClockCapacitanceCompensation_t *capa_charac)
+{
+    uint32_t u32XOTrimValue;
+    uint8_t u8IECXinCapCal6pF, u8IECXinCapCal8pF, u8IECXoutCapCal6pF, u8IECXoutCapCal8pF;
+    int32_t iaXin_x4, ibXin, iaXout_x4, ibXout;
+    int32_t iXOCapInpF_x100, iXOCapOutpF_x100;
+    uint32_t u32XOCapInCtrl, u32XOCapOutCtrl;
+    uint32_t u32RegVal;
+
+    /* Get Cal values from Flash */
+    u32XOTrimValue = GET_32KXO_TRIM();
+
+    /* check validity and apply */
+    if ((u32XOTrimValue & 1) && ((u32XOTrimValue >> 15) & 1) && (GET_CAL_DATE() >= 20180301))
+    {
+        /* These fields are 7 bits, unsigned */
+        u8IECXinCapCal6pF  = (u32XOTrimValue >> 1) & 0x7f;
+        u8IECXinCapCal8pF  = (u32XOTrimValue >> 8) & 0x7f;
+        u8IECXoutCapCal6pF = (u32XOTrimValue >> 16) & 0x7f;
+        u8IECXoutCapCal8pF = (u32XOTrimValue >> 23) & 0x7f;
+        /* Linear fit coefficients calculation */
+        iaXin_x4  = (int)u8IECXinCapCal8pF - (int)u8IECXinCapCal6pF;
+        ibXin     = (int)u8IECXinCapCal6pF - iaXin_x4 * 3;
+        iaXout_x4 = (int)u8IECXoutCapCal8pF - (int)u8IECXoutCapCal6pF;
+        ibXout    = (int)u8IECXoutCapCal6pF - iaXout_x4 * 3;
+    }
+    else
+    {
+        iaXin_x4  = 14; // gain in LSB/pF 3.586
+        ibXin     = 9;  // offset in LSB 9.286
+        iaXout_x4 = 14; // gain in LSB/pF 3.618
+        ibXout    = 8;  // offset in LSB 6.786
+    }
+
+    /* In & out load cap calculation with derating */
+    iXOCapInpF_x100  = 2 * capa_charac->clk_XtalIecLoadpF_x100 - capa_charac->clk_XtalPPcbParCappF_x100 - 130;
+    iXOCapOutpF_x100 = 2 * capa_charac->clk_XtalIecLoadpF_x100 - capa_charac->clk_XtalNPcbParCappF_x100 - 41;
+
+    /* Temperature compensation, if not supported XO_32k_OSC_CAP_Delta_x1000 == 0*/
+    iXOCapInpF_x100  = iXOCapInpF_x100 + XO_32k_OSC_CAP_Delta_x1000 / 5;
+    iXOCapOutpF_x100 = iXOCapOutpF_x100 + XO_32k_OSC_CAP_Delta_x1000 / 5;
+
+    /* In & out XO_OSC_CAP_Code_CTRL calculation, with rounding */
+    u32XOCapInCtrl  = (uint32_t)(((iXOCapInpF_x100 * iaXin_x4 + ibXin * 400) + 200) / 400);
+    u32XOCapOutCtrl = (uint32_t)(((iXOCapOutpF_x100 * iaXout_x4 + ibXout * 400) + 200) / 400);
+
+    uint8_t u8XOCapInCtrl  = CLOCK_u8OscCapConvert(u32XOCapInCtrl, 23);
+    uint8_t u8XOCapOutCtrl = CLOCK_u8OscCapConvert(u32XOCapOutCtrl, 23);
+
+    /* Read register and clear fields to be written */
+    u32RegVal = SYSCON->XTAL32KCAP;
+    u32RegVal &= ~(SYSCON_XTAL32KCAP_XO_OSC_CAP_IN_MASK | SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT_MASK);
+
+    /* XO_OSC_CAP_Code_CTRL to XO_OSC_CAP_Code conversion */
+    u32RegVal |= SYSCON_XTAL32KCAP_XO_OSC_CAP_IN(u8XOCapInCtrl);
+    u32RegVal |= SYSCON_XTAL32KCAP_XO_OSC_CAP_OUT(u8XOCapOutCtrl);
+
+    /* Write back to register */
+    SYSCON->XTAL32KCAP = u32RegVal;
+}
+
+void CLOCK_SetXtal32M_LDO(void)
+{
+    uint32_t temp;
+    const uint32_t u32Mask  = (ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE_MASK | ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT_MASK |
+                              ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS_MASK | ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE_MASK);
+    const uint32_t u32Value = (ASYNC_SYSCON_XTAL32MLDOCTRL_ENABLE(1) | ASYNC_SYSCON_XTAL32MLDOCTRL_VOUT(0x5) |
+                               ASYNC_SYSCON_XTAL32MLDOCTRL_IBIAS(0x2) | ASYNC_SYSCON_XTAL32MLDOCTRL_STABMODE(0x1));
+
+    /* Enable & set-up XTAL 32 MHz clock LDO */
+    temp = ASYNC_SYSCON->XTAL32MLDOCTRL;
+
+    if ((temp & u32Mask) != u32Value)
+    {
+        temp &= ~u32Mask;
+
+        /*
+         * Enable the XTAL32M LDO
+         * Adjust the output voltage level, 0x5 for 1.1V
+         * Adjust the biasing current, 0x2 value
+         * Stability configuration, 0x1 default mode
+         */
+        temp |= u32Value;
+
+        ASYNC_SYSCON->XTAL32MLDOCTRL = temp;
+
+        /* Delay for LDO to be up */
+        CLOCK_uDelay(20);
+    }
+}
+
+void CLOCK_Xtal32M_WaitUntilStable(uint32_t u32AdditionalWait_us)
+{
+    /* Spin until XO stable flag is set */
+    while ((ASYNC_SYSCON->RADIOSTATUS & ASYNC_SYSCON_RADIOSTATUS_PLLXOREADY_MASK) == 0)
+    {
+    }
+
+    /* Extra wait to ensure XTAL is accurate enough */
+    CLOCK_uDelay(u32AdditionalWait_us);
+}
+
+static uint8_t CLOCK_u8OscCapConvert(uint32_t OscCap_val, uint8_t u8CapBankDiscontinuity)
+{
+    /* Compensate for discontinuity in the capacitor banks */
+    if (OscCap_val < 64)
+    {
+        if (OscCap_val >= u8CapBankDiscontinuity)
+        {
+            OscCap_val -= u8CapBankDiscontinuity;
+        }
+        else
+        {
+            OscCap_val = 0;
+        }
+    }
+    else
+    {
+        if (OscCap_val <= (127 - u8CapBankDiscontinuity))
+        {
+            OscCap_val += u8CapBankDiscontinuity;
+        }
+        else
+        {
+            OscCap_val = 127;
+        }
+    }
+
+    return (uint8_t)OscCap_val;
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_clock.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_clock.h
new file mode 100755
index 0000000..1e28ade
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_clock.h
@@ -0,0 +1,592 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_CLOCK_H_
+#define _FSL_CLOCK_H_
+
+#include "fsl_device_registers.h"
+#include "fsl_common.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <stddef.h>
+
+/*! @addtogroup clock */
+/*! @{ */
+
+/*! @file */
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief CLOCK driver version 2.1.0. */
+#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
+/*@}*/
+
+#ifdef FPGA_50MHZ
+#define SYSCON_BASE_CLOCK_DIV (6)
+#define SYSCON_BASE_CLOCK_MUL (5)
+
+#define SYS_FREQ(A) ((A * SYSCON_BASE_CLOCK_MUL) / SYSCON_BASE_CLOCK_DIV)
+#else
+#define SYS_FREQ(A) (A)
+#endif
+
+/* Definition for delay API in clock driver, users can redefine it to the real application. */
+#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
+#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (48000000UL)
+#endif
+
+/*! @brief Clock ip name array for FLEXCOMM. */
+#define FLEXCOMM_CLOCKS                                                                               \
+    {                                                                                                 \
+        kCLOCK_Usart0, kCLOCK_Usart1, kCLOCK_I2c0, kCLOCK_I2c1, kCLOCK_Spi0, kCLOCK_Spi1, kCLOCK_I2c2 \
+    }
+/*! @brief Clock ip name array for CTIMER. */
+#define CTIMER_CLOCKS                \
+    {                                \
+        kCLOCK_Timer0, kCLOCK_Timer1 \
+    }
+/*! @brief Clock ip name array for GINT. */
+#define GINT_CLOCKS \
+    {               \
+        kCLOCK_Gint \
+    }
+/*! @brief Clock ip name array for WWDT. */
+#define WWDT_CLOCKS   \
+    {                 \
+        kCLOCK_WdtOsc \
+    }
+/*! @brief Clock ip name array for DMIC. */
+#define DMIC_CLOCKS \
+    {               \
+        kCLOCK_DMic \
+    }
+/*! @brief Clock ip name array for ADC. */
+#define ADC_CLOCKS  \
+    {               \
+        kCLOCK_Adc0 \
+    }
+/*! @brief Clock ip name array for SPIFI. */
+#define SPIFI_CLOCKS \
+    {                \
+        kCLOCK_Spifi \
+    }
+/*! @brief Clock ip name array for GPIO. */
+#define GPIO_CLOCKS  \
+    {                \
+        kCLOCK_Gpio0 \
+    }
+/*! @brief Clock ip name array for DMA. */
+#define DMA_CLOCKS \
+    {              \
+        kCLOCK_Dma \
+    }
+
+/* Test line to verify RCS */
+/* Another test line to verify source control */
+/* Test lines added by Robert Gee */
+
+/**
+ * @brief Clock sources for main system clock.
+ */
+typedef enum
+{
+    SYSCON_MAINCLKSRC_FRO12M,  /*!< FRO 12MHz */
+    SYSCON_MAINCLKSRC_OSC32K,  /*!< OSC 32kHz */
+    SYSCON_MAINCLKSRC_XTAL32M, /*!< XTAL 32MHz */
+    SYSCON_MAINCLKSRC_FRO32M,  /*!< FRO 32MHz */
+    SYSCON_MAINCLKSRC_FRO48M,  /*!< FRO 48MHz */
+    SYSCON_MAINCLKSRC_EXT,     /*!< External clock */
+    SYSCON_MAINCLKSRC_FRO1M,   /*!< FRO 1MHz */
+} CHIP_SYSCON_MAINCLKSRC_T;
+
+/**
+ * @brief	Fractional Divider clock sources
+ */
+typedef enum
+{
+    SYSCON_FRGCLKSRC_MAINCLK,  /*!< Main Clock */
+    SYSCON_FRGCLKSRC_OSC32M,   /*!< 32MHz Clock (XTAL or FRO) */
+    SYSCON_FRGCLKSRC_FRO48MHZ, /*!< FRO 48-MHz */
+    SYSCON_FRGCLKSRC_NONE,     /*!< FRO 48-MHz */
+} CHIP_SYSCON_FRGCLKSRC_T;
+
+/*------------------------------------------------------------------------------
+ clock_ip_name_t definition:
+------------------------------------------------------------------------------*/
+
+#define CLK_GATE_REG_OFFSET_SHIFT 8U
+#define CLK_GATE_REG_OFFSET_MASK 0xFFFFFF00U
+#define CLK_GATE_BIT_SHIFT_SHIFT 0U
+#define CLK_GATE_BIT_SHIFT_MASK 0x000000FFU
+
+#define CLK_GATE_DEFINE(reg_offset, bit_shift)                                  \
+    ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
+     (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
+
+#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((uint32_t)(x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
+#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((uint32_t)(x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
+
+#define AHB_CLK_CTRL0 0
+#define AHB_CLK_CTRL1 1
+#define ASYNC_CLK_CTRL0 2
+
+/**
+ * @brief   Clock name definition
+ */
+typedef enum _clock_name
+{
+    kCLOCK_Sram0    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_SRAM_CTRL0_SHIFT), /*!< SRAM0 clock */
+    kCLOCK_Sram1    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_SRAM_CTRL1_SHIFT), /*!< SRAM1 clock */
+    kCLOCK_Spifi    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_SPIFI_SHIFT),      /*!< SPIFI clock */
+    kCLOCK_InputMux = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_MUX_SHIFT),        /*!< InputMux clock */
+    kCLOCK_Iocon    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_IOCON_SHIFT),      /*!< IOCON clock */
+    kCLOCK_Gpio0    = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_GPIO_SHIFT),       /*!< GPIO0 clock */
+    kCLOCK_Pint     = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_PINT_SHIFT),       /*!< PINT clock */
+    kCLOCK_Gint     = CLK_GATE_DEFINE(
+        AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_GINT_SHIFT), /* GPIO_GLOBALINT0 and GPIO_GLOBALINT1 share the same slot  */
+    kCLOCK_Dma     = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_DMA_SHIFT),     /*!< DMA clock */
+    kCLOCK_Iso7816 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_ISO7816_SHIFT), /*!< ISO7816 clock */
+    kCLOCK_WdtOsc  = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_WWDT_SHIFT),    /*!< WDTOSC clock */
+    kCLOCK_Rtc     = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_RTC_SHIFT),     /*!< RTC clock */
+    kCLOCK_AnaInt  = CLK_GATE_DEFINE(
+        AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_ANA_INT_CTRL_SHIFT), /*!<  Analog Interrupt Control module clock */
+    kCLOCK_WakeTmr =
+        CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_WAKE_UP_TIMERS_SHIFT),        /*!<  Wake up Timers clock */
+    kCLOCK_Adc0      = CLK_GATE_DEFINE(AHB_CLK_CTRL0, SYSCON_AHBCLKCTRL0_ADC_SHIFT),    /*!< ADC0 clock */
+    kCLOCK_FlexComm0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_USART0_SHIFT), /*!< FlexComm0 clock */
+    kCLOCK_FlexComm1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_USART1_SHIFT), /*!< FlexComm1 clock */
+    kCLOCK_FlexComm2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C0_SHIFT),   /*!< FlexComm2 clock */
+    kCLOCK_FlexComm3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C1_SHIFT),   /*!< FlexComm3 clock */
+    kCLOCK_FlexComm4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_SPI0_SHIFT),   /*!< FlexComm4 clock */
+    kCLOCK_FlexComm5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_SPI1_SHIFT),   /*!< FlexComm5 clock */
+    kCLOCK_Ir        = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_IR_SHIFT),     /*!< Infra Red clock */
+    kCLOCK_Pwm       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_PWM_SHIFT),    /*!< PWM clock */
+    kCLOCK_Rng       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_RNG_SHIFT),    /*!< RNG clock */
+    kCLOCK_FlexComm6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C2_SHIFT),   /*!< FlexComm6 clock */
+    kCLOCK_Usart0    = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_USART0_SHIFT), /*!< USART0 clock */
+    kCLOCK_Usart1    = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_USART1_SHIFT), /*!< USART1 clock */
+    kCLOCK_I2c0      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C0_SHIFT),   /*!< I2C0 clock */
+    kCLOCK_I2c1      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C1_SHIFT),   /*!< I2C1 clock */
+    kCLOCK_Spi0      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_SPI0_SHIFT),   /*!< SPI0 clock */
+    kCLOCK_Spi1      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_SPI1_SHIFT),   /*!< SPI1 clock */
+    kCLOCK_I2c2      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_I2C2_SHIFT),   /*!< I2C2 clock */
+    kCLOCK_BLE       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_BLE_SHIFT),    /*!< BLE clock */
+    kCLOCK_Modem     = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_MODEM_MASTER_SHIFT), /*!< MODEM clock */
+    kCLOCK_Aes       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_AES_SHIFT),          /*!< AES clock */
+    kCLOCK_Rfp       = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_RFP_SHIFT),          /*!< RFP clock */
+    kCLOCK_DMic      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_DMIC_SHIFT),         /*!< DMIC clock */
+    kCLOCK_Sha0      = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_HASH_SHIFT),         /*!< SHA0 clock */
+    kCLOCK_Timer0    = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 1),                                   /*!< Timer0 clock */
+    kCLOCK_Timer1    = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 2),                                   /*!< Timer1 clock */
+    kCLOCK_MainClk   = (1 << 16),                                                             /*!< MAIN_CLK */
+    kCLOCK_CoreSysClk,                                                                        /*!< Core/system clock */
+    kCLOCK_BusClk,                                                                            /*!< AHB bus clock */
+    kCLOCK_Xtal32k,                                                             /*!< 32kHz crystal oscillator */
+    kCLOCK_Xtal32M,                                                             /*!< 32MHz crystal oscillator */
+    kCLOCK_Fro32k,                                                              /*!< 32kHz free running oscillator */
+    kCLOCK_Fro1M,                                                               /*!< 1MHz Free Running Oscillator */
+    kCLOCK_Fro12M,                                                              /*!< 12MHz Free Running Oscillator */
+    kCLOCK_Fro32M,                                                              /*!< 32MHz Free Running Oscillator */
+    kCLOCK_Fro48M,                                                              /*!< 48MHz Free Running Oscillator */
+    kCLOCK_Fro64M,                                                              /*!< 64Mhz Free Running Oscillator */
+    kCLOCK_ExtClk,                                                              /*!< External clock */
+    kCLOCK_WdtClk,                                                              /*!< Watchdog clock */
+    kCLOCK_Frg,                                                                 /*!< Fractional divider */
+    kCLOCK_ClkOut,                                                              /*!< Clock out */
+    kCLOCK_Fmeas,                                                               /*!< FMEAS clock */
+    kCLOCK_Sha = CLK_GATE_DEFINE(AHB_CLK_CTRL1, SYSCON_AHBCLKCTRL1_HASH_SHIFT), /*!< Hash clock */
+} clock_name_t;
+
+typedef clock_name_t clock_ip_name_t;
+
+#define REG_OFST(block, member) (offsetof(block##_Type, member) / sizeof(uint32_t))
+
+#define MUX_A(m, choice) (((m) << 0) | ((choice + 1) << 12))
+
+/*! @brief Clock source selector definition */
+typedef enum
+{
+    CM_MAINCLKSEL   = REG_OFST(SYSCON, MAINCLKSEL),  /*!< Clock source selector of Main clock source */
+    CM_OSC32CLKSEL  = REG_OFST(SYSCON, OSC32CLKSEL), /*!< Clock source selector of OSC32KCLK and OSC32MCLK */
+    CM_CLKOUTCLKSEL = REG_OFST(SYSCON, CLKOUTSEL),   /*!< Clock source selector of CLKOUT */
+    CM_SPIFICLKSEL  = REG_OFST(SYSCON, SPIFICLKSEL), /*!< Clock source selector of SPIFI */
+    CM_ADCCLKSEL    = REG_OFST(SYSCON, ADCCLKSEL),   /*!< Clock source selector of ADC */
+    CM_USARTCLKSEL  = REG_OFST(SYSCON, USARTCLKSEL), /*!< Clock source selector of USART0 & 1 */
+    CM_I2CCLKSEL    = REG_OFST(SYSCON, I2CCLKSEL),   /*!< Clock source selector of I2C0, 1 and 2 */
+    CM_SPICLKSEL    = REG_OFST(SYSCON, SPICLKSEL),   /*!< Clock source selector of SPI0 & 1 */
+    CM_IRCLKSEL     = REG_OFST(SYSCON, IRCLKSEL),    /*!< Clock source selector of Infra Red */
+    CM_PWMCLKSEL    = REG_OFST(SYSCON, PWMCLKSEL),   /*!< Clock source selector of PWM */
+    CM_WDTCLKSEL    = REG_OFST(SYSCON, WDTCLKSEL),   /*!< Clock source selector of Watchdog Timer */
+    CM_MODEMCLKSEL  = REG_OFST(SYSCON, MODEMCLKSEL), /*!< Clock source selector of Modem */
+    CM_FRGCLKSEL    = REG_OFST(SYSCON, FRGCLKSEL),   /*!< Clock source selector of Fractional Rate Generator (FRG) */
+    CM_DMICLKSEL    = REG_OFST(SYSCON, DMICCLKSEL),  /*!< Clock source selector of Digital microphone (DMIC) */
+    CM_WKTCLKSEL    = REG_OFST(SYSCON, WKTCLKSEL),   /*!< Clock source selector of Wake-up Timer */
+    CM_ASYNCAPB
+} clock_sel_ofst_t;
+
+/*! @brief Clock attach definition */
+typedef enum _clock_attach_id
+{
+    kFRO12M_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 0), /*!< Select FRO 12M for main clock */
+    kOSC32K_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 1), /*!< Select OSC 32K for main clock */
+    kXTAL32M_to_MAIN_CLK = MUX_A(CM_MAINCLKSEL, 2), /*!< Select XTAL 32M for main clock */
+    kFRO32M_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 3), /*!< Select FRO 32M for main clock */
+    kFRO48M_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 4), /*!< Select FRO 48M for main clock */
+    kEXT_CLK_to_MAIN_CLK = MUX_A(CM_MAINCLKSEL, 5), /*!< Select external clock for main clock */
+    kFROM1M_to_MAIN_CLK  = MUX_A(CM_MAINCLKSEL, 6), /*!< Select FRO 1M for main clock */
+
+    kFRO32M_to_OSC32M_CLK  = MUX_A(CM_OSC32CLKSEL, 0), /*!< Select FRO 32M for OSC32KCLK and OSC32MCLK */
+    kXTAL32M_to_OSC32M_CLK = MUX_A(CM_OSC32CLKSEL, 1), /*!< Select XTAL 32M for OSC32KCLK and OSC32MCLK */
+    kFRO32K_to_OSC32K_CLK  = MUX_A(CM_OSC32CLKSEL, 2), /*!< Select FRO 32K for OSC32KCLK and OSC32MCLK */
+    kXTAL32K_to_OSC32K_CLK = MUX_A(CM_OSC32CLKSEL, 3), /*!< Select XTAL 32K for OSC32KCLK and OSC32MCLK */
+
+    kMAIN_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSEL, 0), /*!< Select main clock for CLKOUT */
+    kXTAL32K_to_CLKOUT  = MUX_A(CM_CLKOUTCLKSEL, 1), /*!< Select XTAL 32K for CLKOUT */
+    kFRO32K_to_CLKOUT   = MUX_A(CM_CLKOUTCLKSEL, 2), /*!< Select FRO 32K for CLKOUT */
+    kXTAL32M_to_CLKOUT  = MUX_A(CM_CLKOUTCLKSEL, 3), /*!< Select XTAL 32M for CLKOUT */
+    kDCDC_to_CLKOUT     = MUX_A(CM_CLKOUTCLKSEL, 4), /*!< Select DCDC for CLKOUT */
+    kFRO48M_to_CLKOUT   = MUX_A(CM_CLKOUTCLKSEL, 5), /*!< Select FRO 48M for CLKOUT */
+    kFRO1M_to_CLKOUT    = MUX_A(CM_CLKOUTCLKSEL, 6), /*!< Select FRO 1M for CLKOUT */
+    kNONE_to_CLKOUT     = MUX_A(CM_CLKOUTCLKSEL, 7), /*!< No clock for CLKOUT */
+
+    kMAIN_CLK_to_SPIFI = MUX_A(CM_SPIFICLKSEL, 0), /*!< Select main clock for SPIFI */
+    kXTAL32M_to_SPIFI  = MUX_A(CM_SPIFICLKSEL, 1), /*!< Select XTAL 32M for SPIFI */
+    kFRO64M_to_SPIFI   = MUX_A(CM_SPIFICLKSEL, 2), /*!< Select FRO 64M for SPIFI */
+    kFRO48M_to_SPIFI   = MUX_A(CM_SPIFICLKSEL, 3), /*!< Select FRO 48M for SPIFI */
+
+    kXTAL32M_to_ADC_CLK = MUX_A(CM_ADCCLKSEL, 0), /*!< Select XTAL 32M for ADC */
+    kFRO12M_to_ADC_CLK  = MUX_A(CM_ADCCLKSEL, 1), /*!< Select FRO 12M for ADC */
+    kNONE_to_ADC_CLK    = MUX_A(CM_ADCCLKSEL, 2), /*!< No clock for ADC */
+
+    kOSC32M_to_USART_CLK  = MUX_A(CM_USARTCLKSEL, 0), /*!< Select OSC 32M for USART0 & 1 */
+    kFRO48M_to_USART_CLK  = MUX_A(CM_USARTCLKSEL, 1), /*!< Select FRO 48M for USART0 & 1 */
+    kFRG_CLK_to_USART_CLK = MUX_A(CM_USARTCLKSEL, 2), /*!< Select FRG clock for USART0 & 1 */
+    kNONE_to_USART_CLK    = MUX_A(CM_USARTCLKSEL, 3), /*!< No clock for USART0 & 1 */
+
+    kOSC32M_to_I2C_CLK = MUX_A(CM_I2CCLKSEL, 0), /*!< Select OSC 32M for I2C0, 1 and 2 */
+    kFRO48M_to_I2C_CLK = MUX_A(CM_I2CCLKSEL, 1), /*!< Select FRO 48M for I2C0, 1 and 2 */
+    kNONE_to_I2C_CLK   = MUX_A(CM_I2CCLKSEL, 2), /*!< No clock for I2C0, 1 and 2 */
+
+    kOSC32M_to_SPI_CLK = MUX_A(CM_SPICLKSEL, 0), /*!< Select OSC 32M for SPI0 & 1 */
+    kFRO48M_to_SPI_CLK = MUX_A(CM_SPICLKSEL, 1), /*!< Select FRO 48M for SPI0 & 1 */
+    kNONE_to_SPI_CLK   = MUX_A(CM_SPICLKSEL, 2), /*!< No clock for SPI0 & 1 */
+
+    kOSC32M_to_IR_CLK = MUX_A(CM_IRCLKSEL, 0), /*!< Select OSC 32M for Infra Red */
+    kFRO48M_to_IR_CLK = MUX_A(CM_IRCLKSEL, 1), /*!< Select FRO 48M for Infra Red */
+    kNONE_to_IR_CLK   = MUX_A(CM_IRCLKSEL, 2), /*!< No clock for Infra Red */
+
+    kOSC32M_to_PWM_CLK = MUX_A(CM_PWMCLKSEL, 0), /*!< Select OSC 32M for PWM */
+    kFRO48M_to_PWM_CLK = MUX_A(CM_PWMCLKSEL, 1), /*!< Select FRO 48M for PWM */
+    kNONE_to_PWM_CLK   = MUX_A(CM_PWMCLKSEL, 2), /*!< No clock for PWM */
+
+    kOSC32M_to_WDT_CLK = MUX_A(CM_WDTCLKSEL, 0), /*!< Select OSC 32M for Watchdog Timer */
+    kOSC32K_to_WDT_CLK = MUX_A(CM_WDTCLKSEL, 1), /*!< Select FRO 32K for Watchdog Timer */
+    kFRO1M_to_WDT_CLK  = MUX_A(CM_WDTCLKSEL, 2), /*!< Select FRO 1M for Watchdog Timer */
+
+    kMAIN_CLK_to_FRG_CLK = MUX_A(CM_FRGCLKSEL, 0), /*!< Select main clock for FRG */
+    kOSC32M_to_FRG_CLK   = MUX_A(CM_FRGCLKSEL, 1), /*!< Select OSC 32M for FRG */
+    kFRO48M_to_FRG_CLK   = MUX_A(CM_FRGCLKSEL, 2), /*!< Select FRO 48M for FRG */
+    kNONE_to_FRG_CLK     = MUX_A(CM_FRGCLKSEL, 3), /*!< No clock for FRG */
+
+    kMAIN_CLK_to_DMI_CLK = MUX_A(CM_DMICLKSEL, 0), /*!< Select main clock for DMIC */
+    kOSC32K_to_DMI_CLK   = MUX_A(CM_DMICLKSEL, 1), /*!< Select OSC 32K for DMIC */
+    kFRO48M_to_DMI_CLK   = MUX_A(CM_DMICLKSEL, 2), /*!< Select FRO 48M for DMIC */
+    kMCLK_to_DMI_CLK     = MUX_A(CM_DMICLKSEL, 3), /*!< Select external clock for DMIC */
+    kFRO1M_to_DMI_CLK    = MUX_A(CM_DMICLKSEL, 4), /*!< Select FRO 1M for DMIC */
+    kFRO12M_to_DMI_CLK   = MUX_A(CM_DMICLKSEL, 5), /*!< Select FRO 12M for DMIC */
+    kNONE_to_DMI_CLK     = MUX_A(CM_DMICLKSEL, 6), /*!< No clock for DMIC */
+
+    kOSC32K_to_WKT_CLK = MUX_A(CM_WKTCLKSEL, 0), /*!< Select OSC 32K for WKT */
+    kNONE_to_WKT_CLK   = MUX_A(CM_WKTCLKSEL, 3), /*!< No clock for WKT */
+
+    kXTAL32M_DIV2_to_ZIGBEE_CLK = MUX_A(CM_MODEMCLKSEL, 0), /*!< Select XTAL 32M for ZIGBEE */
+    kNONE_to_ZIGBEE_CLK         = MUX_A(CM_MODEMCLKSEL, 1), /*!< No clock for ZIGBEE */
+    kXTAL32M_to_BLE_CLK         = MUX_A(CM_MODEMCLKSEL, 2), /*!< Select XTAL 32M for BLE */
+    kNONE_to_BLE_CLK            = MUX_A(CM_MODEMCLKSEL, 3), /*!< No clock for BLE */
+
+    kMAIN_CLK_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 0), /*!< Select main clock for Asynchronous APB */
+    kXTAL32M_to_ASYNC_APB  = MUX_A(CM_ASYNCAPB, 1), /*!< Select XTAL 32M for Asynchronous APB */
+    kFRO32M_to_ASYNC_APB   = MUX_A(CM_ASYNCAPB, 2), /*!< Select FRO 32M for Asynchronous APB */
+    kFRO48M_to_ASYNC_APB   = MUX_A(CM_ASYNCAPB, 3), /*!< Select FRO 48M for Asynchronous APB */
+    kNONE_to_NONE          = 0x80000000U,
+} clock_attach_id_t;
+
+/*  Clock dividers */
+#define FIRST_DIV_MEMBER SYSTICKCLKDIV
+#define CLOCK_DIV_OFST(member) offsetof(SYSCON_Type, member)
+
+/*! @brief Clock divider definition */
+typedef enum _clock_div_name
+{
+    kCLOCK_DivNone       = 0,
+    kCLOCK_DivSystickClk = (offsetof(SYSCON_Type, SYSTICKCLKDIV) / sizeof(uint32_t)), /*!< SYSTICK clock divider */
+    kCLOCK_DivTraceClk   = (offsetof(SYSCON_Type, TRACECLKDIV) / sizeof(uint32_t)),   /*!< TRACE clock divider */
+    kCLOCK_DivWdtClk     = (offsetof(SYSCON_Type, WDTCLKDIV) / sizeof(uint32_t)),   /*!< Watchdog Timer clock divider */
+    kCLOCK_DivIrClk      = (offsetof(SYSCON_Type, IRCLKDIV) / sizeof(uint32_t)),    /*!< Infra Red clock divider */
+    kCLOCK_DivAhbClk     = (offsetof(SYSCON_Type, AHBCLKDIV) / sizeof(uint32_t)),   /*!< System clock divider */
+    kCLOCK_DivClkout     = (offsetof(SYSCON_Type, CLKOUTDIV) / sizeof(uint32_t)),   /*!< CLKOUT clock divider */
+    kCLOCK_DivSpifiClk   = (offsetof(SYSCON_Type, SPIFICLKDIV) / sizeof(uint32_t)), /*!< SPIFI clock divider */
+    kCLOCK_DivAdcClk     = (offsetof(SYSCON_Type, ADCCLKDIV) / sizeof(uint32_t)),   /*!< ADC clock divider */
+    kCLOCK_DivRtcClk     = (offsetof(SYSCON_Type, RTCCLKDIV) / sizeof(uint32_t)),   /*!< Real Time Clock divider */
+    kCLOCK_DivDmicClk    = (offsetof(SYSCON_Type, DMICCLKDIV) / sizeof(uint32_t)),  /*!< DMIC clock divider */
+    kCLOCK_DivRtc1HzClk  = (offsetof(SYSCON_Type, RTC1HZCLKDIV) / sizeof(uint32_t)), /*!< Real Time Clock divider */
+    kCLOCK_DivFrg        = (offsetof(SYSCON_Type, FRGCTRL) / sizeof(uint32_t))       /*!< FRG Clock divider */
+} clock_div_name_t;
+
+/*! @brief Clock source selections for the Main Clock */
+typedef enum _main_clock_src
+{
+    kCLOCK_MainFro12M  = 0, /*!< FRO 12M for main clock */
+    kCLOCK_MainOsc32k  = 1, /*!< OSC 32K for main clock */
+    kCLOCK_MainXtal32M = 2, /*!< XTAL 32M for main clock */
+    kCLOCK_MainFro32M  = 3, /*!< FRO 32M for main clock */
+    kCLOCK_MainFro48M  = 4, /*!< FRO 48M for main clock */
+    kCLOCK_MainExtClk  = 5, /*!< External clock for main clock */
+    kCLOCK_MainFro1M   = 6, /*!< FRO 1M for main clock */
+} main_clock_src_t;
+
+/*! @brief Clock source selections for CLKOUT */
+typedef enum _clkout_clock_src
+{
+    kCLOCK_ClkoutMainClk  = 0, /*!< CPU & System Bus clock for CLKOUT */
+    kCLOCK_ClkoutXtal32k  = 1, /*!< XTAL 32K for CLKOUT */
+    kCLOCK_ClkoutFro32k   = 2, /*!< FRO 32K for CLKOUT */
+    kCLOCK_ClkoutXtal32M  = 3, /*!< XTAL 32M for CLKOUT */
+    kCLOCK_ClkoutDcDcTest = 4, /*!< DCDC Test for CLKOUT */
+    kCLOCK_ClkoutFro48M   = 5, /*!< FRO 48M for CLKOUT */
+    kCLOCK_ClkoutFro1M    = 6, /*!< FRO 1M for CLKOUT */
+    kCLOCK_ClkoutNoClock  = 7  /*!< No clock for CLKOUT */
+} clkout_clock_src_t;
+
+/*! @brief Clock source definition for Watchdog timer */
+typedef enum _wdt_clock_src
+{
+    kCLOCK_WdtOsc32MClk = 0, /*!< OSC 32M for WDT */
+    kCLOCK_WdtOsc32kClk = 1, /*!< OSC 32K for WDT */
+    kCLOCK_WdtFro1M     = 2, /*!< FRO 1M for WDT */
+    kCLOCK_WdtNoClock   = 3  /*!< No clock for WDT */
+} wdt_clock_src_t;
+
+/*! @brief Clock source definition for fractional divider */
+typedef enum _frg_clock_src
+{
+    kCLOCK_FrgMainClk   = 0, /*!< CPU & System Bus clock for FRG */
+    kCLOCK_FrgOsc32MClk = 1, /*!< OSC 32M clock for FRG */
+    kCLOCK_FrgFro48M    = 2, /*!< FRO 48M for FRG */
+    kCLOCK_FrgNoClock   = 3  /*!< No clock for FRG */
+} frg_clock_src_t;
+
+/*! @brief Clock source definition for the APB */
+typedef enum _apb_clock_src
+{
+    kCLOCK_ApbMainClk = 0, /*!< CPU & System Bus clock for APB bridge */
+    kCLOCK_ApbXtal32M = 1, /*!< XTAL 32M for APB bridge */
+    kCLOCK_ApbFro32M  = 2, /*!< FRO 32M for APB bridge */
+    kCLOCK_ApbFro48M  = 3  /*!< FRO 48M for APB bridge */
+} apb_clock_src_t;
+
+/*! @brief Clock source definition for frequency measure  */
+typedef enum _fmeas_clock_src
+{
+    kCLOCK_fmeasClkIn     = 0, /*!< Clock in for FMEAS */
+    kCLOCK_fmeasXtal32Mhz = 1, /*!< XTAL 32M for FMEAS */
+    kCLOCK_fmeasFRO1Mhz   = 2, /*!< FRO 1M for FMEAS */
+    kCLOCK_fmeasXtal32kHz = 3, /*!< XTAL 32K for FMEAS */
+    kCLOCK_fmeasMainClock = 4, /*!< CPU & System Bus clock for FMEAS */
+    kCLOCK_fmeasGPIO_0_4  = 5, /*!< GPIO0_4 input for FMEAS */
+    kCLOCK_fmeasGPIO_0_20 = 6, /*!< GPIO0_20 input for FMEAS */
+    kCLOCK_fmeasGPIO_0_16 = 7, /*!< GPIO0_16 input for FMEAS */
+    kCLOCK_fmeasGPIO_0_15 = 8, /*!< GPIO0_15 input for FMEAS */
+} fmeas_clock_src_t;
+
+/*! @brief Clock source selection for SPIFI */
+typedef enum _spifi_clock_src
+{
+    kCLOCK_SpifiMainClk = 0, /*!< CPU & System Bus clock for SPIFI */
+    kCLOCK_SpifiXtal32M = 1, /*!< XTAL 32M for SPIFI */
+    kCLOCK_SpifiFro64M  = 2, /*!< FRO 64M for SPIFI */
+    kCLOCK_SpifiFro48M  = 3, /*!< FRO 48M for SPIFI */
+    kCLOCK_SpifiNoClock = 4  /*!< No clock for SPIFI */
+} spifi_clock_src_t;
+
+/*! @brief Clock definition for ADC */
+typedef enum _adc_clock_src
+{
+    kCLOCK_AdcXtal32M = 0, /*!< XTAL 32MHz for ADC */
+    kCLOCK_AdcFro12M  = 1, /*!< FRO 12MHz for ADC */
+    kCLOCK_AdcNoClock = 2  /*!< No clock for ADC */
+} adc_clock_src_t;
+
+/*! @brief PWM Clock source selection values */
+typedef enum _pwm_clock_source
+{
+    kCLOCK_PWMOsc32Mclk = 0x0, /*!< 32MHz FRO or XTAL clock */
+    kCLOCK_PWMFro48Mclk = 0x1, /*!< FRO 48MHz clock */
+    kCLOCK_PWMNoClkSel  = 0x2, /*!< No clock selected - Shutdown functional
+                            PWM clock for power saving */
+    kCLOCK_PWMTestClk = 0x3,   /*!< Test clock input - Shutdown functional
+                              PWM clock for power saving */
+} pwm_clock_source_t;
+
+/*! @brief FRO clock selection values */
+typedef enum
+{
+    FRO12M_ENA = (1 << 0), /*!< FRO12M */
+    FRO32M_ENA = (1 << 1), /*!< FRO32M */
+    FRO48M_ENA = (1 << 2), /*!< FRO48M */
+    FRO64M_ENA = (1 << 3), /*!< FRO64M */
+    FRO96M_ENA = (1 << 4)  /*!< FRO96M */
+} Fro_ClkSel_t;
+
+/*! @brief Board specific constant capacitance characteristics
+ * Should be supplied by board manufacturer for best performance.
+ * Capacitances are expressed in hundreds of pF
+ */
+typedef struct
+{
+    uint32_t clk_XtalIecLoadpF_x100;    /*< XTAL Load capacitance */
+    uint32_t clk_XtalPPcbParCappF_x100; /*< XTAL PCB +ve parasitic capacitance */
+    uint32_t clk_XtalNPcbParCappF_x100; /*< XTAL PCB -ve parasitic capacitance */
+} ClockCapacitanceCompensation_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @brief	Obtains frequency of specified clock
+ * @param   clock_name_t  specify clock to be read
+ * @return	uint32_t      frequency
+ * @note
+ */
+uint32_t CLOCK_GetFreq(clock_name_t clock);
+
+/**
+ * @brief	Selects clock source using <name>SEL register in syscon
+ * @param   clock_attach_id_t  specify clock mapping
+ * @return	none
+ * @note
+ */
+void CLOCK_AttachClk(clock_attach_id_t connection);
+
+/**
+ * @brief	Selects clock divider using <name>DIV register in syscon
+ * @param   clock_div_name_t  	specifies which DIV register we are accessing
+ * @param   uint32_t			specifies divisor
+ * @param	bool				true if a syscon clock reset should also be carried out
+ * @return	none
+ * @note
+ */
+void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset);
+
+/**
+ * @brief	Enables specific AHB clock channel
+ * @param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * @return	none
+ * @note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+void CLOCK_EnableClock(clock_ip_name_t clk);
+
+/**
+ * @brief	Disables specific AHB clock channel
+ * @param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * @return	none
+ * @note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+void CLOCK_DisableClock(clock_ip_name_t clk);
+
+/**
+ * @brief	Check if clock is enabled
+ * @param   clock_ip_name_t  	specifies which peripheral clock we are controlling
+ * @return  bool
+ * @note	clock_ip_name_t is a typedef clone of clock_name_t
+ */
+bool CLOCK_IsClockEnable(clock_ip_name_t clk);
+
+/**
+ * @brief	Obtains frequency of APB Bus clock
+ * @param   none
+ * @return	uint32_t      frequency
+ * @note
+ */
+uint32_t CLOCK_GetApbCLkFreq(void);
+
+void CLOCK_EnableAPBBridge(void);
+
+void CLOCK_DisableAPBBridge(void);
+
+/*! @brief      Return Frequency of Spifi Clock
+ *  @return     Frequency of Spifi.
+ */
+uint32_t CLOCK_GetSpifiClkFreq(void);
+
+/*! @brief   Delay execution by busy waiting
+ *  @param   delayUs delay duration in micro seconds
+ *  @return  none
+ */
+void CLOCK_uDelay(uint32_t delayUs);
+
+/**
+ * @brief	Sets default trim values for 32MHz XTAL
+ * @param   none
+ * @return	none
+ * @note    Has no effect if CLOCK_Xtal32M_Trim has been called
+ */
+void CLOCK_XtalBasicTrim(void);
+
+/**
+ * @brief   Sets board-specific trim values for 32MHz XTAL
+ * @param   XO_32M_OSC_CAP_Delta_x1000 capacitance correction in fF (femtoFarad)
+ * @param   capa_charac board 32M capacitance characteristics pointer
+ * @return  none
+ * @note    capa_charac must point to a struct set in board.c using
+ *          CLOCK_32MfXtalIecLoadpF    Load capacitance, pF
+ *          CLOCK_32MfXtalPPcbParCappF PCB +ve parasitic capacitance, pF
+ *          CLOCK_32MfXtalNPcbParCappF PCB -ve parasitic capacitance, pF
+ */
+void CLOCK_Xtal32M_Trim(int32_t XO_32M_OSC_CAP_Delta_x1000, const ClockCapacitanceCompensation_t *capa_charac);
+
+/**
+ * @brief   Sets board-specific trim values for 32kHz XTAL
+ * @param   XO_32k_OSC_CAP_Delta_x1000 capacitance correction in fF
+ * @param   capa_charac board 32k capacitance characteristics pointer
+ * @return  none
+ * @note    capa_charac must point to a struct set in board.c using
+ *          CLOCK_32kfXtalIecLoadpF    Load capacitance, pF
+ *          CLOCK_32kfXtalPPcbParCappF PCB +ve parasitic capacitance, pF
+ *          CLOCK_32kfXtalNPcbParCappF PCB -ve parasitic capacitance, pF
+ */
+void CLOCK_Xtal32k_Trim(int32_t XO_32k_OSC_CAP_Delta_x1000, const ClockCapacitanceCompensation_t *capa_charac);
+
+/**
+ * @brief	Enables and sets LDO for 32MHz XTAL
+ * @param   none
+ * @return	none
+ */
+void CLOCK_SetXtal32M_LDO(void);
+
+/**
+ * @brief	Waits for 32MHz XTAL to stabilise
+ * @param   u32AdditionalWait_us Additional wait after hardware indicates that
+ *                               stability has been reached
+ * @return	none
+ * @note    Operates as a tight loop. Worst case would be ~600ms
+ */
+void CLOCK_Xtal32M_WaitUntilStable(uint32_t u32AdditionalWait_us);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_CLOCK_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_common.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_common.h
new file mode 100755
index 0000000..c5e1c2f
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_common.h
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_COMMON_H_
+#define _FSL_COMMON_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(__ICCARM__)
+#include <stddef.h>
+#endif
+
+#include "fsl_device_registers.h"
+
+/*!
+ * @addtogroup ksdk_common
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Construct a status code value from a group and code number. */
+#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
+
+/*! @brief Construct the version number for drivers. */
+#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief common driver version 2.2.0. */
+#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
+/*@}*/
+
+/* Debug console type definition. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_NONE          0U      /*!< No debug console.             */
+#define DEBUG_CONSOLE_DEVICE_TYPE_UART          1U      /*!< Debug console based on UART.   */
+#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART        2U      /*!< Debug console based on LPUART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI         3U      /*!< Debug console based on LPSCI.  */
+#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC        4U      /*!< Debug console based on USBCDC. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM      5U      /*!< Debug console based on FLEXCOMM. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_IUART         6U      /*!< Debug console based on i.MX UART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART        7U      /*!< Debug console based on LPC_VUSART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART    8U      /*!< Debug console based on LPC_USART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_SWO           9U      /*!< Debug console based on SWO. */
+
+/*! @brief Status group numbers. */
+enum _status_groups
+{
+    kStatusGroup_Generic = 0,                 /*!< Group number for generic status codes. */
+    kStatusGroup_FLASH = 1,                   /*!< Group number for FLASH status codes. */
+    kStatusGroup_LPSPI = 4,                   /*!< Group number for LPSPI status codes. */
+    kStatusGroup_FLEXIO_SPI = 5,              /*!< Group number for FLEXIO SPI status codes. */
+    kStatusGroup_DSPI = 6,                    /*!< Group number for DSPI status codes. */
+    kStatusGroup_FLEXIO_UART = 7,             /*!< Group number for FLEXIO UART status codes. */
+    kStatusGroup_FLEXIO_I2C = 8,              /*!< Group number for FLEXIO I2C status codes. */
+    kStatusGroup_LPI2C = 9,                   /*!< Group number for LPI2C status codes. */
+    kStatusGroup_UART = 10,                   /*!< Group number for UART status codes. */
+    kStatusGroup_I2C = 11,                    /*!< Group number for UART status codes. */
+    kStatusGroup_LPSCI = 12,                  /*!< Group number for LPSCI status codes. */
+    kStatusGroup_LPUART = 13,                 /*!< Group number for LPUART status codes. */
+    kStatusGroup_SPI = 14,                    /*!< Group number for SPI status code.*/
+    kStatusGroup_XRDC = 15,                   /*!< Group number for XRDC status code.*/
+    kStatusGroup_SEMA42 = 16,                 /*!< Group number for SEMA42 status code.*/
+    kStatusGroup_SDHC = 17,                   /*!< Group number for SDHC status code */
+    kStatusGroup_SDMMC = 18,                  /*!< Group number for SDMMC status code */
+    kStatusGroup_SAI = 19,                    /*!< Group number for SAI status code */
+    kStatusGroup_MCG = 20,                    /*!< Group number for MCG status codes. */
+    kStatusGroup_SCG = 21,                    /*!< Group number for SCG status codes. */
+    kStatusGroup_SDSPI = 22,                  /*!< Group number for SDSPI status codes. */
+    kStatusGroup_FLEXIO_I2S = 23,             /*!< Group number for FLEXIO I2S status codes */
+    kStatusGroup_FLEXIO_MCULCD = 24,          /*!< Group number for FLEXIO LCD status codes */
+    kStatusGroup_FLASHIAP = 25,               /*!< Group number for FLASHIAP status codes */
+    kStatusGroup_FLEXCOMM_I2C = 26,           /*!< Group number for FLEXCOMM I2C status codes */
+    kStatusGroup_I2S = 27,                    /*!< Group number for I2S status codes */
+    kStatusGroup_IUART = 28,                  /*!< Group number for IUART status codes */
+    kStatusGroup_CSI = 29,                    /*!< Group number for CSI status codes */
+    kStatusGroup_MIPI_DSI = 30,               /*!< Group number for MIPI DSI status codes */
+    kStatusGroup_SDRAMC = 35,                 /*!< Group number for SDRAMC status codes. */
+    kStatusGroup_POWER = 39,                  /*!< Group number for POWER status codes. */
+    kStatusGroup_ENET = 40,                   /*!< Group number for ENET status codes. */
+    kStatusGroup_PHY = 41,                    /*!< Group number for PHY status codes. */
+    kStatusGroup_TRGMUX = 42,                 /*!< Group number for TRGMUX status codes. */
+    kStatusGroup_SMARTCARD = 43,              /*!< Group number for SMARTCARD status codes. */
+    kStatusGroup_LMEM = 44,                   /*!< Group number for LMEM status codes. */
+    kStatusGroup_QSPI = 45,                   /*!< Group number for QSPI status codes. */
+    kStatusGroup_DMA = 50,                    /*!< Group number for DMA status codes. */
+    kStatusGroup_EDMA = 51,                   /*!< Group number for EDMA status codes. */
+    kStatusGroup_DMAMGR = 52,                 /*!< Group number for DMAMGR status codes. */
+    kStatusGroup_FLEXCAN = 53,                /*!< Group number for FlexCAN status codes. */
+    kStatusGroup_LTC = 54,                    /*!< Group number for LTC status codes. */
+    kStatusGroup_FLEXIO_CAMERA = 55,          /*!< Group number for FLEXIO CAMERA status codes. */
+    kStatusGroup_LPC_SPI = 56,                /*!< Group number for LPC_SPI status codes. */
+    kStatusGroup_LPC_USART = 57,              /*!< Group number for LPC_USART status codes. */
+    kStatusGroup_DMIC = 58,                   /*!< Group number for DMIC status codes. */
+    kStatusGroup_SDIF = 59,                   /*!< Group number for SDIF status codes.*/
+    kStatusGroup_SPIFI = 60,                  /*!< Group number for SPIFI status codes. */
+    kStatusGroup_OTP = 61,                    /*!< Group number for OTP status codes. */
+    kStatusGroup_MCAN = 62,                   /*!< Group number for MCAN status codes. */
+    kStatusGroup_CAAM = 63,                   /*!< Group number for CAAM status codes. */
+    kStatusGroup_ECSPI = 64,                  /*!< Group number for ECSPI status codes. */
+    kStatusGroup_USDHC = 65,                  /*!< Group number for USDHC status codes.*/
+    kStatusGroup_LPC_I2C = 66,                /*!< Group number for LPC_I2C status codes.*/
+    kStatusGroup_DCP = 67,                    /*!< Group number for DCP status codes.*/
+    kStatusGroup_MSCAN = 68,                  /*!< Group number for MSCAN status codes.*/
+    kStatusGroup_ESAI = 69,                   /*!< Group number for ESAI status codes. */
+    kStatusGroup_FLEXSPI = 70,                /*!< Group number for FLEXSPI status codes. */
+    kStatusGroup_MMDC = 71,                   /*!< Group number for MMDC status codes. */
+    kStatusGroup_PDM = 72,                    /*!< Group number for MIC status codes. */
+    kStatusGroup_SDMA = 73,                   /*!< Group number for SDMA status codes. */
+    kStatusGroup_ICS = 74,                    /*!< Group number for ICS status codes. */
+    kStatusGroup_SPDIF = 75,                  /*!< Group number for SPDIF status codes. */
+    kStatusGroup_LPC_MINISPI = 76,            /*!< Group number for LPC_MINISPI status codes. */
+    kStatusGroup_HASHCRYPT = 77,              /*!< Group number for Hashcrypt status codes */
+    kStatusGroup_LPC_SPI_SSP = 78,            /*!< Group number for LPC_SPI_SSP status codes. */
+    kStatusGroup_I3C = 79,                    /*!< Group number for I3C status codes */
+    kStatusGroup_LPC_I2C_1 = 97,              /*!< Group number for LPC_I2C_1 status codes. */
+    kStatusGroup_NOTIFIER = 98,               /*!< Group number for NOTIFIER status codes. */
+    kStatusGroup_DebugConsole = 99,           /*!< Group number for debug console status codes. */
+    kStatusGroup_SEMC = 100,                  /*!< Group number for SEMC status codes. */
+    kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
+    kStatusGroup_IAP = 102,                   /*!< Group number for IAP status codes */
+
+    kStatusGroup_HAL_GPIO = 121,              /*!< Group number for HAL GPIO status codes. */
+    kStatusGroup_HAL_UART = 122,              /*!< Group number for HAL UART status codes. */
+    kStatusGroup_HAL_TIMER = 123,             /*!< Group number for HAL TIMER status codes. */
+    kStatusGroup_HAL_SPI = 124,               /*!< Group number for HAL SPI status codes. */
+    kStatusGroup_HAL_I2C = 125,               /*!< Group number for HAL I2C status codes. */
+    kStatusGroup_HAL_FLASH = 126,             /*!< Group number for HAL FLASH status codes. */
+    kStatusGroup_HAL_PWM = 127,               /*!< Group number for HAL PWM status codes. */
+    kStatusGroup_HAL_RNG = 128,               /*!< Group number for HAL RNG status codes. */
+    kStatusGroup_TIMERMANAGER = 135,          /*!< Group number for TiMER MANAGER status codes. */
+    kStatusGroup_SERIALMANAGER = 136,         /*!< Group number for SERIAL MANAGER status codes. */
+    kStatusGroup_LED = 137,                   /*!< Group number for LED status codes. */
+    kStatusGroup_BUTTON = 138,                /*!< Group number for BUTTON status codes. */
+    kStatusGroup_EXTERN_EEPROM = 139,         /*!< Group number for EXTERN EEPROM status codes. */
+    kStatusGroup_SHELL = 140,                 /*!< Group number for SHELL status codes. */
+    kStatusGroup_MEM_MANAGER = 141,           /*!< Group number for MEM MANAGER status codes. */
+    kStatusGroup_LIST = 142,                  /*!< Group number for List status codes. */
+    kStatusGroup_OSA = 143,                   /*!< Group number for OSA status codes. */
+    kStatusGroup_COMMON_TASK = 144,           /*!< Group number for Common task status codes. */
+    kStatusGroup_MSG = 145,                   /*!< Group number for messaging status codes. */
+    kStatusGroup_SDK_OCOTP = 146,             /*!< Group number for OCOTP status codes. */
+    kStatusGroup_SDK_FLEXSPINOR = 147,        /*!< Group number for FLEXSPINOR status codes.*/
+    kStatusGroup_CODEC = 148,                 /*!< Group number for codec status codes. */
+};
+
+/*! @brief Generic status return codes. */
+enum
+{
+    kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0),
+    kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1),
+    kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2),
+    kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3),
+    kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),
+    kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5),
+    kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6),
+};
+
+/*! @brief Type used for all status and error return values. */
+typedef int32_t status_t;
+
+/*
+ * Macro guard for whether to use default weak IRQ implementation in drivers
+ */
+#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
+#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1
+#endif
+
+/*! @name Min/max macros */
+/* @{ */
+#if !defined(MIN)
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#if !defined(MAX)
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+/* @} */
+
+/*! @brief Computes the number of elements in an array. */
+#if !defined(ARRAY_SIZE)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+/*! @name UINT16_MAX/UINT32_MAX value */
+/* @{ */
+#if !defined(UINT16_MAX)
+#define UINT16_MAX ((uint16_t)-1)
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX ((uint32_t)-1)
+#endif
+/* @} */
+
+/*! @name Timer utilities */
+/* @{ */
+/*! Macro to convert a microsecond period to raw count value */
+#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)
+/*! Macro to convert a raw count value to microsecond */
+#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz)
+
+/*! Macro to convert a millisecond period to raw count value */
+#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U)
+/*! Macro to convert a raw count value to millisecond */
+#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz)
+/* @} */
+
+/*! @name Alignment variable definition macros */
+/* @{ */
+#if (defined(__ICCARM__))
+/**
+ * Workaround to disable MISRA C message suppress warnings for IAR compiler.
+ * http://supp.iar.com/Support/?note=24725
+ */
+_Pragma("diag_suppress=Pm120")
+#define SDK_PRAGMA(x) _Pragma(#x)
+    _Pragma("diag_error=Pm120")
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var
+#endif
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) var
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) var
+#endif
+#elif defined(__GNUC__)
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)))
+#endif
+#else
+#error Toolchain not supported
+#define SDK_ALIGN(var, alignbytes) var
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) var
+#endif
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) var
+#endif
+#endif
+
+/*! Macro to change a value to a given size aligned value */
+#define SDK_SIZEALIGN(var, alignbytes) \
+    ((unsigned int)((var) + ((alignbytes)-1)) & (unsigned int)(~(unsigned int)((alignbytes)-1)))
+/* @} */
+
+/*! @name Non-cacheable region definition macros */
+/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
+ * "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables,
+ * please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables
+ * will be initialized to zero in system startup.
+ */
+/* @{ */
+#if (defined(__ICCARM__))
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
+#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+#endif
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+    __attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+    __attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __attribute__((aligned(alignbytes))) var
+#endif
+#elif(defined(__XCC__))
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+    __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+    __attribute__((section("NonCacheable"))) var __attribute__((aligned(alignbytes)))
+#elif(defined(__GNUC__))
+/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
+ * in your projects to make sure the non-cacheable section variables will be initialized in system startup.
+ */
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+    __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+    __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes)))
+#endif
+#else
+#error Toolchain not supported.
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var
+#endif
+/* @} */
+
+/*! @name Time sensitive region */
+/* @{ */
+#if defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE
+#if (defined(__ICCARM__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
+#define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess"
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
+#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
+#elif(defined(__GNUC__))
+#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
+#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
+#else
+#error Toolchain not supported.
+#endif /* defined(__ICCARM__) */
+#else
+#if (defined(__ICCARM__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#elif(defined(__GNUC__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#else
+#error Toolchain not supported.
+#endif
+#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */
+/* @} */
+
+/*! @name Ram Function */
+#if (defined(__ICCARM__))
+#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction"
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
+#elif(defined(__GNUC__))
+#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
+#else
+#error Toolchain not supported.
+#endif /* defined(__ICCARM__) */
+/* @} */
+
+/*! @name Suppress fallthrough warning macro */
+/* For switch case code block, if case section ends without "break;" statement, there wil be
+ fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc.
+ To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each
+ case section which misses "break;"statement.
+ */
+/* @{ */
+#if (defined(__GNUC__))
+#define SUPPRESS_FALL_THROUGH_WARNING() __attribute__ ((fallthrough))
+#else
+#define SUPPRESS_FALL_THROUGH_WARNING()
+#endif /* defined(__GNUC__) */
+/* @} */
+
+/*
+ * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
+ * defined in previous of this file.
+ */
+#include "fsl_clock.h"
+
+/*
+ * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
+ */
+#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
+     (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
+#include "fsl_reset.h"
+#endif
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+        extern "C"
+{
+#endif
+
+    /*!
+     * @brief Enable specific interrupt.
+     *
+     * Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
+     * levels. For example, there are NVIC and intmux. Here the interrupts connected
+     * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
+     * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
+     * to NVIC first then routed to core.
+     *
+     * This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
+     * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
+     *
+     * @param interrupt The IRQ number.
+     * @retval kStatus_Success Interrupt enabled successfully
+     * @retval kStatus_Fail Failed to enable the interrupt
+     */
+    static inline status_t EnableIRQ(IRQn_Type interrupt)
+    {
+        if (NotAvail_IRQn == interrupt)
+        {
+            return kStatus_Fail;
+        }
+
+#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
+        if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
+        {
+            return kStatus_Fail;
+        }
+#endif
+
+#if defined(__GIC_PRIO_BITS)
+        GIC_EnableIRQ(interrupt);
+#else
+        NVIC_EnableIRQ(interrupt);
+#endif
+        return kStatus_Success;
+    }
+
+    /*!
+     * @brief Disable specific interrupt.
+     *
+     * Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
+     * levels. For example, there are NVIC and intmux. Here the interrupts connected
+     * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
+     * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
+     * to NVIC first then routed to core.
+     *
+     * This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
+     * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
+     *
+     * @param interrupt The IRQ number.
+     * @retval kStatus_Success Interrupt disabled successfully
+     * @retval kStatus_Fail Failed to disable the interrupt
+     */
+    static inline status_t DisableIRQ(IRQn_Type interrupt)
+    {
+        if (NotAvail_IRQn == interrupt)
+        {
+            return kStatus_Fail;
+        }
+
+#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
+        if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
+        {
+            return kStatus_Fail;
+        }
+#endif
+
+#if defined(__GIC_PRIO_BITS)
+        GIC_DisableIRQ(interrupt);
+#else
+    NVIC_DisableIRQ(interrupt);
+#endif
+        return kStatus_Success;
+    }
+
+    /*!
+     * @brief Disable the global IRQ
+     *
+     * Disable the global interrupt and return the current primask register. User is required to provided the primask
+     * register for the EnableGlobalIRQ().
+     *
+     * @return Current primask value.
+     */
+    static inline uint32_t DisableGlobalIRQ(void)
+    {
+#if defined (__XCC__)
+        return 0;
+#else
+#if defined(CPSR_I_Msk)
+        uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
+
+        __disable_irq();
+
+        return cpsr;
+#else
+    uint32_t regPrimask = __get_PRIMASK();
+
+    __disable_irq();
+
+    return regPrimask;
+#endif
+#endif
+    }
+
+    /*!
+     * @brief Enable the global IRQ
+     *
+     * Set the primask register with the provided primask value but not just enable the primask. The idea is for the
+     * convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
+     * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
+     *
+     * @param primask value of primask register to be restored. The primask value is supposed to be provided by the
+     * DisableGlobalIRQ().
+     */
+    static inline void EnableGlobalIRQ(uint32_t primask)
+    {
+#if defined (__XCC__)
+#else
+#if defined(CPSR_I_Msk)
+        __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
+#else
+    __set_PRIMASK(primask);
+#endif
+#endif
+    }
+
+#if defined(ENABLE_RAM_VECTOR_TABLE)
+    /*!
+     * @brief install IRQ handler
+     *
+     * @param irq IRQ number
+     * @param irqHandler IRQ handler address
+     * @return The old IRQ handler address
+     */
+    uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
+#endif /* ENABLE_RAM_VECTOR_TABLE. */
+
+#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
+#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)
+    /*!
+     * @brief Enable specific interrupt for wake-up from deep-sleep mode.
+     *
+     * Enable the interrupt for wake-up from deep sleep mode.
+     * Some interrupts are typically used in sleep mode only and will not occur during
+     * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
+     * those clocks (significantly increasing power consumption in the reduced power mode),
+     * making these wake-ups possible.
+     *
+     * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly).
+     *
+     * @param interrupt The IRQ number.
+     */
+    void EnableDeepSleepIRQ(IRQn_Type interrupt);
+
+    /*!
+     * @brief Disable specific interrupt for wake-up from deep-sleep mode.
+     *
+     * Disable the interrupt for wake-up from deep sleep mode.
+     * Some interrupts are typically used in sleep mode only and will not occur during
+     * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
+     * those clocks (significantly increasing power consumption in the reduced power mode),
+     * making these wake-ups possible.
+     *
+     * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly).
+     *
+     * @param interrupt The IRQ number.
+     */
+    void DisableDeepSleepIRQ(IRQn_Type interrupt);
+#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
+#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
+
+    /*!
+     * @brief Allocate memory with given alignment and aligned size.
+     *
+     * This is provided to support the dynamically allocated memory
+     * used in cache-able region.
+     * @param size The length required to malloc.
+     * @param alignbytes The alignment size.
+     * @retval The allocated memory.
+     */
+    void *SDK_Malloc(size_t size, size_t alignbytes);
+
+    /*!
+     * @brief Free memory.
+     *
+     * @param ptr The memory to be release.
+     */
+    void SDK_Free(void *ptr);
+
+    /*!
+    * @brief Delay at least for some time.
+    *  Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
+    *  if precise delay count was needed, please implement a new delay function with hardware timer.
+    *
+    * @param delay_us  Delay time in unit of microsecond.
+    * @param coreClock_Hz  Core clock frequency with Hz.
+    */
+    void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @} */
+
+#endif /* _FSL_COMMON_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_ctimer.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_ctimer.c
new file mode 100755
index 0000000..590ab32
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_ctimer.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_ctimer.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.ctimer"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Gets the instance from the base address
+ *
+ * @param base Ctimer peripheral base address
+ *
+ * @return The Timer instance
+ */
+static uint32_t CTIMER_GetInstance(CTIMER_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to Timer bases for each instance. */
+static CTIMER_Type *const s_ctimerBases[] = CTIMER_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to Timer clocks for each instance. */
+static const clock_ip_name_t s_ctimerClocks[] = CTIMER_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_RESET) && (FSL_FEATURE_CTIMER_HAS_NO_RESET))
+#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
+#if defined(FSL_FEATURE_CTIMER_WRITE_ZERO_ASSERT_RESET) && FSL_FEATURE_CTIMER_WRITE_ZERO_ASSERT_RESET
+/*! @brief Pointers to Timer resets for each instance, writing a zero asserts the reset */
+static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS_N;
+#else
+/*! @brief Pointers to Timer resets for each instance, writing a one asserts the reset */
+static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS;
+#endif
+#endif
+#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
+
+/*! @brief Pointers real ISRs installed by drivers for each instance. */
+static ctimer_callback_t *s_ctimerCallback[FSL_FEATURE_SOC_CTIMER_COUNT] = {0};
+
+/*! @brief Callback type installed by drivers for each instance. */
+static ctimer_callback_type_t ctimerCallbackType[FSL_FEATURE_SOC_CTIMER_COUNT] = {kCTIMER_SingleCallback};
+
+/*! @brief Array to map timer instance to IRQ number. */
+static const IRQn_Type s_ctimerIRQ[] = CTIMER_IRQS;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static uint32_t CTIMER_GetInstance(CTIMER_Type *base)
+{
+    uint32_t instance;
+    uint32_t ctimerArrayCount = (sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0]));
+
+    /* Find the instance index from base address mappings. */
+    for (instance = 0; instance < ctimerArrayCount; instance++)
+    {
+        if (s_ctimerBases[instance] == base)
+        {
+            break;
+        }
+    }
+
+    assert(instance < ctimerArrayCount);
+
+    return instance;
+}
+
+/*!
+ * brief Ungates the clock and configures the peripheral for basic operation.
+ *
+ * note This API should be called at the beginning of the application before using the driver.
+ *
+ * param base   Ctimer peripheral base address
+ * param config Pointer to the user configuration structure.
+ */
+void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config)
+{
+    assert(config);
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* Enable the timer clock*/
+    CLOCK_EnableClock(s_ctimerClocks[CTIMER_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
+/* Reset the module. */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_RESET) && (FSL_FEATURE_CTIMER_HAS_NO_RESET))
+    RESET_PeripheralReset(s_ctimerResets[CTIMER_GetInstance(base)]);
+#endif
+#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
+
+/* Setup the cimer mode and count select */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    base->CTCR = CTIMER_CTCR_CTMODE(config->mode) | CTIMER_CTCR_CINSEL(config->input);
+#endif
+    /* Setup the timer prescale value */
+    base->PR = CTIMER_PR_PRVAL(config->prescale);
+}
+
+/*!
+ * brief Gates the timer clock.
+ *
+ * param base Ctimer peripheral base address
+ */
+void CTIMER_Deinit(CTIMER_Type *base)
+{
+    uint32_t index = CTIMER_GetInstance(base);
+    /* Stop the timer */
+    base->TCR &= ~CTIMER_TCR_CEN_MASK;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* Disable the timer clock*/
+    CLOCK_DisableClock(s_ctimerClocks[index]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+    /* Disable IRQ at NVIC Level */
+    DisableIRQ(s_ctimerIRQ[index]);
+}
+
+/*!
+ * brief  Fills in the timers configuration structure with the default settings.
+ *
+ * The default values are:
+ * code
+ *   config->mode = kCTIMER_TimerMode;
+ *   config->input = kCTIMER_Capture_0;
+ *   config->prescale = 0;
+ * endcode
+ * param config Pointer to the user configuration structure.
+ */
+void CTIMER_GetDefaultConfig(ctimer_config_t *config)
+{
+    assert(config);
+
+    /* Initializes the configure structure to zero. */
+    memset(config, 0, sizeof(*config));
+
+    /* Run as a timer */
+    config->mode = kCTIMER_TimerMode;
+    /* This field is ignored when mode is timer */
+    config->input = kCTIMER_Capture_0;
+    /* Timer counter is incremented on every APB bus clock */
+    config->prescale = 0;
+}
+
+/*!
+ * brief Configures the PWM signal parameters.
+ *
+ * Enables PWM mode on the match channel passed in and will then setup the match value
+ * and other match parameters to generate a PWM signal.
+ * This function will assign match channel 3 to set the PWM cycle.
+ *
+ * note When setting PWM output from multiple output pins, all should use the same PWM
+ * frequency. Please use CTIMER_SetupPwmPeriod to set up the PWM with high resolution.
+ *
+ * param base             Ctimer peripheral base address
+ * param matchChannel     Match pin to be used to output the PWM signal
+ * param dutyCyclePercent PWM pulse width; the value should be between 0 to 100
+ * param pwmFreq_Hz       PWM signal frequency in Hz
+ * param srcClock_Hz      Timer counter clock in Hz
+ * param enableInt        Enable interrupt when the timer value reaches the match value of the PWM pulse,
+ *                         if it is 0 then no interrupt is generated
+ *
+ * return kStatus_Success on success
+ *         kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM cycle
+ */
+status_t CTIMER_SetupPwm(CTIMER_Type *base,
+                         ctimer_match_t matchChannel,
+                         uint8_t dutyCyclePercent,
+                         uint32_t pwmFreq_Hz,
+                         uint32_t srcClock_Hz,
+                         bool enableInt)
+{
+    assert(pwmFreq_Hz > 0);
+
+    uint32_t reg;
+    uint32_t period, pulsePeriod = 0;
+    uint32_t timerClock = srcClock_Hz / (base->PR + 1);
+    uint32_t index      = CTIMER_GetInstance(base);
+
+    if (matchChannel == kCTIMER_Match_3)
+    {
+        return kStatus_Fail;
+    }
+
+    /* Enable PWM mode on the channel */
+    base->PWMC |= (1U << matchChannel);
+
+    /* Clear the stop, reset and interrupt bits for this channel */
+    reg = base->MCR;
+    reg &= ~((CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR0S_MASK | CTIMER_MCR_MR0I_MASK) << (matchChannel * 3));
+
+    /* If call back function is valid then enable match interrupt for the channel */
+    if (enableInt)
+    {
+        reg |= (CTIMER_MCR_MR0I_MASK << (CTIMER_MCR_MR0I_SHIFT + (matchChannel * 3)));
+    }
+
+    /* Reset the counter when match on channel 3 */
+    reg |= CTIMER_MCR_MR3R_MASK;
+
+    base->MCR = reg;
+
+    /* Calculate PWM period match value */
+    period = (timerClock / pwmFreq_Hz) - 1;
+
+    /* Calculate pulse width match value */
+    if (dutyCyclePercent == 0)
+    {
+        pulsePeriod = period + 1;
+    }
+    else
+    {
+        pulsePeriod = (period * (100 - dutyCyclePercent)) / 100;
+    }
+
+    /* Match on channel 3 will define the PWM period */
+    base->MR[kCTIMER_Match_3] = period;
+
+    /* This will define the PWM pulse period */
+    base->MR[matchChannel] = pulsePeriod;
+    /* Clear status flags */
+    CTIMER_ClearStatusFlags(base, CTIMER_IR_MR0INT_MASK << matchChannel);
+    /* If call back function is valid then enable interrupt and update the call back function */
+    if (enableInt)
+    {
+        EnableIRQ(s_ctimerIRQ[index]);
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Configures the PWM signal parameters.
+ *
+ * Enables PWM mode on the match channel passed in and will then setup the match value
+ * and other match parameters to generate a PWM signal.
+ * This function will assign match channel 3 to set the PWM cycle.
+ *
+ * note When setting PWM output from multiple output pins, all should use the same PWM
+ * period
+ *
+ * param base             Ctimer peripheral base address
+ * param matchChannel     Match pin to be used to output the PWM signal
+ * param pwmPeriod        PWM period match value
+ * param pulsePeriod      Pulse width match value
+ * param enableInt        Enable interrupt when the timer value reaches the match value of the PWM pulse,
+ *                         if it is 0 then no interrupt is generated
+ *
+ * return kStatus_Success on success
+ *         kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM period
+ */
+status_t CTIMER_SetupPwmPeriod(
+    CTIMER_Type *base, ctimer_match_t matchChannel, uint32_t pwmPeriod, uint32_t pulsePeriod, bool enableInt)
+{
+/* Some CTimers only have 16bits , so the value is limited*/
+#if defined(FSL_FEATURE_SOC_CTIMER16B) && FSL_FEATURE_SOC_CTIMER16B
+    assert(!((FSL_FEATURE_CTIMER_BIT_SIZEn(base) < 32) && (pulsePeriod > 0xFFFFU)));
+#endif
+
+    uint32_t reg;
+    uint32_t index = CTIMER_GetInstance(base);
+
+    if (matchChannel == kCTIMER_Match_3)
+    {
+        return kStatus_Fail;
+    }
+
+    /* Enable PWM mode on the channel */
+    base->PWMC |= (1U << matchChannel);
+
+    /* Clear the stop, reset and interrupt bits for this channel */
+    reg = base->MCR;
+    reg &= ~((CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR0S_MASK | CTIMER_MCR_MR0I_MASK) << (matchChannel * 3));
+
+    /* If call back function is valid then enable match interrupt for the channel */
+    if (enableInt)
+    {
+        reg |= (CTIMER_MCR_MR0I_MASK << (CTIMER_MCR_MR0I_SHIFT + (matchChannel * 3)));
+    }
+
+    /* Reset the counter when match on channel 3 */
+    reg |= CTIMER_MCR_MR3R_MASK;
+
+    base->MCR = reg;
+
+    /* Match on channel 3 will define the PWM period */
+    base->MR[kCTIMER_Match_3] = pwmPeriod;
+
+    /* This will define the PWM pulse period */
+    base->MR[matchChannel] = pulsePeriod;
+    /* Clear status flags */
+    CTIMER_ClearStatusFlags(base, CTIMER_IR_MR0INT_MASK << matchChannel);
+    /* If call back function is valid then enable interrupt and update the call back function */
+    if (enableInt)
+    {
+        EnableIRQ(s_ctimerIRQ[index]);
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Updates the duty cycle of an active PWM signal.
+ *
+ * note Please use CTIMER_UpdatePwmPulsePeriod to update the PWM with high resolution.
+ *
+ * param base             Ctimer peripheral base address
+ * param matchChannel     Match pin to be used to output the PWM signal
+ * param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100
+ */
+void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent)
+{
+    uint32_t pulsePeriod = 0, period;
+
+    /* Match channel 3 defines the PWM period */
+    period = base->MR[kCTIMER_Match_3];
+
+    /* Calculate pulse width match value */
+    pulsePeriod = (period * dutyCyclePercent) / 100;
+
+    /* For 0% dutycyle, make pulse period greater than period so the event will never occur */
+    if (dutyCyclePercent == 0)
+    {
+        pulsePeriod = period + 1;
+    }
+    else
+    {
+        pulsePeriod = (period * (100 - dutyCyclePercent)) / 100;
+    }
+
+    /* Update dutycycle */
+    base->MR[matchChannel] = pulsePeriod;
+}
+
+/*!
+ * brief Setup the match register.
+ *
+ * User configuration is used to setup the match value and action to be taken when a match occurs.
+ *
+ * param base         Ctimer peripheral base address
+ * param matchChannel Match register to configure
+ * param config       Pointer to the match configuration structure
+ */
+void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config)
+{
+/* Some CTimers only have 16bits , so the value is limited*/
+#if defined(FSL_FEATURE_SOC_CTIMER16B) && FSL_FEATURE_SOC_CTIMER16B
+    assert(!(FSL_FEATURE_CTIMER_BIT_SIZEn(base) < 32 && config->matchValue > 0xFFFFU));
+#endif
+    uint32_t reg;
+    uint32_t index = CTIMER_GetInstance(base);
+
+    /* Set the counter operation when a match on this channel occurs */
+    reg = base->MCR;
+    reg &= ~((CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR0S_MASK | CTIMER_MCR_MR0I_MASK) << (matchChannel * 3));
+    reg |= (uint32_t)((uint32_t)(config->enableCounterReset) << (CTIMER_MCR_MR0R_SHIFT + (matchChannel * 3)));
+    reg |= (uint32_t)((uint32_t)(config->enableCounterStop) << (CTIMER_MCR_MR0S_SHIFT + (matchChannel * 3)));
+    reg |= (uint32_t)((uint32_t)(config->enableInterrupt) << (CTIMER_MCR_MR0I_SHIFT + (matchChannel * 3)));
+    base->MCR = reg;
+
+    reg = base->EMR;
+    /* Set the match output operation when a match on this channel occurs */
+    reg &= ~(CTIMER_EMR_EMC0_MASK << (matchChannel * 2));
+    reg |= (uint32_t)config->outControl << (CTIMER_EMR_EMC0_SHIFT + (matchChannel * 2));
+
+    /* Set the initial state of the EM bit/output */
+    reg &= ~(CTIMER_EMR_EM0_MASK << matchChannel);
+    reg |= (uint32_t)config->outPinInitState << matchChannel;
+    base->EMR = reg;
+
+    /* Set the match value */
+    base->MR[matchChannel] = config->matchValue;
+    /* Clear status flags */
+    CTIMER_ClearStatusFlags(base, CTIMER_IR_MR0INT_MASK << matchChannel);
+    /* If interrupt is enabled then enable interrupt and update the call back function */
+    if (config->enableInterrupt)
+    {
+        EnableIRQ(s_ctimerIRQ[index]);
+    }
+}
+
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+/*!
+ * brief Setup the capture.
+ *
+ * param base      Ctimer peripheral base address
+ * param capture   Capture channel to configure
+ * param edge      Edge on the channel that will trigger a capture
+ * param enableInt Flag to enable channel interrupts, if enabled then the registered call back
+ *                  is called upon capture
+ */
+void CTIMER_SetupCapture(CTIMER_Type *base,
+                         ctimer_capture_channel_t capture,
+                         ctimer_capture_edge_t edge,
+                         bool enableInt)
+{
+    uint32_t reg   = base->CCR;
+    uint32_t index = CTIMER_GetInstance(base);
+
+    /* Set the capture edge */
+    reg &= ~((CTIMER_CCR_CAP0RE_MASK | CTIMER_CCR_CAP0FE_MASK | CTIMER_CCR_CAP0I_MASK) << (capture * 3));
+    reg |= (uint32_t)edge << (CTIMER_CCR_CAP0RE_SHIFT + (capture * 3));
+    /* Clear status flags */
+    CTIMER_ClearStatusFlags(base, (kCTIMER_Capture0Flag << capture));
+    /* If call back function is valid then enable capture interrupt for the channel and update the call back function */
+    if (enableInt)
+    {
+        reg |= CTIMER_CCR_CAP0I_MASK << (capture * 3);
+        EnableIRQ(s_ctimerIRQ[index]);
+    }
+    base->CCR = reg;
+}
+#endif
+
+/*!
+ * brief Register callback.
+ *
+ * param base      Ctimer peripheral base address
+ * param cb_func   callback function
+ * param cb_type   callback function type, singular or multiple
+ */
+void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type)
+{
+    uint32_t index            = CTIMER_GetInstance(base);
+    s_ctimerCallback[index]   = cb_func;
+    ctimerCallbackType[index] = cb_type;
+}
+
+void CTIMER_GenericIRQHandler(uint32_t index)
+{
+    uint32_t int_stat, i, mask;
+    /* Get Interrupt status flags */
+    int_stat = CTIMER_GetStatusFlags(s_ctimerBases[index]);
+    /* Clear the status flags that were set */
+    CTIMER_ClearStatusFlags(s_ctimerBases[index], int_stat);
+    if (ctimerCallbackType[index] == kCTIMER_SingleCallback)
+    {
+        if (s_ctimerCallback[index][0])
+        {
+            s_ctimerCallback[index][0](int_stat);
+        }
+    }
+    else
+    {
+#if defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE
+        for (i = 0; i <= CTIMER_IR_MR3INT_SHIFT; i++)
+#else
+#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT
+        for (i = 0; i <= CTIMER_IR_CR3INT_SHIFT; i++)
+#else
+        for (i = 0; i <= CTIMER_IR_CR2INT_SHIFT; i++)
+#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */
+#endif
+        {
+            mask = 0x01 << i;
+            /* For each status flag bit that was set call the callback function if it is valid */
+            if ((int_stat & mask) && (s_ctimerCallback[index][i]))
+            {
+                s_ctimerCallback[index][i](int_stat);
+            }
+        }
+    }
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+
+/* IRQ handler functions overloading weak symbols in the startup */
+#if defined(CTIMER0)
+void CTIMER0_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(0);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(CTIMER1)
+void CTIMER1_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(1);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(CTIMER2)
+void CTIMER2_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(2);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(CTIMER3)
+void CTIMER3_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(3);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(CTIMER4)
+void CTIMER4_DriverIRQHandler(void)
+{
+    CTIMER_GenericIRQHandler(4);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_ctimer.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_ctimer.h
new file mode 100755
index 0000000..8ae0d88
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_ctimer.h
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_CTIMER_H_
+#define _FSL_CTIMER_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup ctimer
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+#define FSL_CTIMER_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */
+/*@}*/
+
+/*! @brief List of Timer capture channels */
+typedef enum _ctimer_capture_channel
+{
+    kCTIMER_Capture_0 = 0U, /*!< Timer capture channel 0 */
+    kCTIMER_Capture_1,      /*!< Timer capture channel 1 */
+    kCTIMER_Capture_2,      /*!< Timer capture channel 2 */
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+    kCTIMER_Capture_3 /*!< Timer capture channel 3 */
+#endif                /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */
+} ctimer_capture_channel_t;
+
+/*! @brief List of capture edge options */
+typedef enum _ctimer_capture_edge
+{
+    kCTIMER_Capture_RiseEdge = 1U, /*!< Capture on rising edge */
+    kCTIMER_Capture_FallEdge = 2U, /*!< Capture on falling edge */
+    kCTIMER_Capture_BothEdge = 3U, /*!< Capture on rising and falling edge */
+} ctimer_capture_edge_t;
+
+/*! @brief List of Timer match registers */
+typedef enum _ctimer_match
+{
+    kCTIMER_Match_0 = 0U, /*!< Timer match register 0 */
+    kCTIMER_Match_1,      /*!< Timer match register 1 */
+    kCTIMER_Match_2,      /*!< Timer match register 2 */
+    kCTIMER_Match_3       /*!< Timer match register 3 */
+} ctimer_match_t;
+
+/*! @brief List of output control options */
+typedef enum _ctimer_match_output_control
+{
+    kCTIMER_Output_NoAction = 0U, /*!< No action is taken */
+    kCTIMER_Output_Clear,         /*!< Clear the EM bit/output to 0 */
+    kCTIMER_Output_Set,           /*!< Set the EM bit/output to 1 */
+    kCTIMER_Output_Toggle         /*!< Toggle the EM bit/output */
+} ctimer_match_output_control_t;
+
+/*! @brief List of Timer modes */
+typedef enum _ctimer_timer_mode
+{
+    kCTIMER_TimerMode = 0U,     /* TC is incremented every rising APB bus clock edge */
+    kCTIMER_IncreaseOnRiseEdge, /* TC is incremented on rising edge of input signal */
+    kCTIMER_IncreaseOnFallEdge, /* TC is incremented on falling edge of input signal */
+    kCTIMER_IncreaseOnBothEdge  /* TC is incremented on both edges of input signal */
+} ctimer_timer_mode_t;
+
+/*! @brief List of Timer interrupts */
+typedef enum _ctimer_interrupt_enable
+{
+    kCTIMER_Match0InterruptEnable = CTIMER_MCR_MR0I_MASK, /*!< Match 0 interrupt */
+    kCTIMER_Match1InterruptEnable = CTIMER_MCR_MR1I_MASK, /*!< Match 1 interrupt */
+    kCTIMER_Match2InterruptEnable = CTIMER_MCR_MR2I_MASK, /*!< Match 2 interrupt */
+    kCTIMER_Match3InterruptEnable = CTIMER_MCR_MR3I_MASK, /*!< Match 3 interrupt */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    kCTIMER_Capture0InterruptEnable = CTIMER_CCR_CAP0I_MASK, /*!< Capture 0 interrupt */
+    kCTIMER_Capture1InterruptEnable = CTIMER_CCR_CAP1I_MASK, /*!< Capture 1 interrupt */
+    kCTIMER_Capture2InterruptEnable = CTIMER_CCR_CAP2I_MASK, /*!< Capture 2 interrupt */
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+    kCTIMER_Capture3InterruptEnable = CTIMER_CCR_CAP3I_MASK, /*!< Capture 3 interrupt */
+#endif                                                       /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
+#endif
+} ctimer_interrupt_enable_t;
+
+/*! @brief List of Timer flags */
+typedef enum _ctimer_status_flags
+{
+    kCTIMER_Match0Flag = CTIMER_IR_MR0INT_MASK, /*!< Match 0 interrupt flag */
+    kCTIMER_Match1Flag = CTIMER_IR_MR1INT_MASK, /*!< Match 1 interrupt flag */
+    kCTIMER_Match2Flag = CTIMER_IR_MR2INT_MASK, /*!< Match 2 interrupt flag */
+    kCTIMER_Match3Flag = CTIMER_IR_MR3INT_MASK, /*!< Match 3 interrupt flag */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    kCTIMER_Capture0Flag = CTIMER_IR_CR0INT_MASK, /*!< Capture 0 interrupt flag */
+    kCTIMER_Capture1Flag = CTIMER_IR_CR1INT_MASK, /*!< Capture 1 interrupt flag */
+    kCTIMER_Capture2Flag = CTIMER_IR_CR2INT_MASK, /*!< Capture 2 interrupt flag */
+#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT
+    kCTIMER_Capture3Flag = CTIMER_IR_CR3INT_MASK, /*!< Capture 3 interrupt flag */
+#endif                                            /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */
+#endif
+} ctimer_status_flags_t;
+
+typedef void (*ctimer_callback_t)(uint32_t flags);
+
+/*! @brief Callback type when registering for a callback. When registering a callback
+ *         an array of function pointers is passed the size could be 1 or 8, the callback
+ *         type will tell that.
+ */
+typedef enum
+{
+    kCTIMER_SingleCallback,  /*!< Single Callback type where there is only one callback for the timer.
+                                 based on the status flags different channels needs to be handled differently */
+    kCTIMER_MultipleCallback /*!< Multiple Callback type where there can be 8 valid callbacks, one per channel.
+                                 for both match/capture */
+} ctimer_callback_type_t;
+
+/*!
+ * @brief Match configuration
+ *
+ * This structure holds the configuration settings for each match register.
+ */
+typedef struct _ctimer_match_config
+{
+    uint32_t matchValue;                      /*!< This is stored in the match register */
+    bool enableCounterReset;                  /*!< true: Match will reset the counter
+                                                   false: Match will not reser the counter */
+    bool enableCounterStop;                   /*!< true: Match will stop the counter
+                                                   false: Match will not stop the counter */
+    ctimer_match_output_control_t outControl; /*!< Action to be taken on a match on the EM bit/output */
+    bool outPinInitState;                     /*!< Initial value of the EM bit/output */
+    bool enableInterrupt;                     /*!< true: Generate interrupt upon match
+                                                   false: Do not generate interrupt on match */
+
+} ctimer_match_config_t;
+
+/*!
+ * @brief Timer configuration structure
+ *
+ * This structure holds the configuration settings for the Timer peripheral. To initialize this
+ * structure to reasonable defaults, call the CTIMER_GetDefaultConfig() function and pass a
+ * pointer to the configuration structure instance.
+ *
+ * The configuration structure can be made constant so as to reside in flash.
+ */
+typedef struct _ctimer_config
+{
+    ctimer_timer_mode_t mode;       /*!< Timer mode */
+    ctimer_capture_channel_t input; /*!< Input channel to increment the timer, used only in timer
+                                        modes that rely on this input signal to increment TC */
+    uint32_t prescale;              /*!< Prescale value */
+} ctimer_config_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Ungates the clock and configures the peripheral for basic operation.
+ *
+ * @note This API should be called at the beginning of the application before using the driver.
+ *
+ * @param base   Ctimer peripheral base address
+ * @param config Pointer to the user configuration structure.
+ */
+void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config);
+
+/*!
+ * @brief Gates the timer clock.
+ *
+ * @param base Ctimer peripheral base address
+ */
+void CTIMER_Deinit(CTIMER_Type *base);
+
+/*!
+ * @brief  Fills in the timers configuration structure with the default settings.
+ *
+ * The default values are:
+ * @code
+ *   config->mode = kCTIMER_TimerMode;
+ *   config->input = kCTIMER_Capture_0;
+ *   config->prescale = 0;
+ * @endcode
+ * @param config Pointer to the user configuration structure.
+ */
+void CTIMER_GetDefaultConfig(ctimer_config_t *config);
+
+/*! @}*/
+
+/*!
+ * @name PWM setup operations
+ * @{
+ */
+
+/*!
+ * @brief Configures the PWM signal parameters.
+ *
+ * Enables PWM mode on the match channel passed in and will then setup the match value
+ * and other match parameters to generate a PWM signal.
+ * This function will assign match channel 3 to set the PWM cycle.
+ *
+ * @note When setting PWM output from multiple output pins, all should use the same PWM
+ * period
+ *
+ * @param base             Ctimer peripheral base address
+ * @param matchChannel     Match pin to be used to output the PWM signal
+ * @param pwmPeriod        PWM period match value
+ * @param pulsePeriod      Pulse width match value
+ * @param enableInt        Enable interrupt when the timer value reaches the match value of the PWM pulse,
+ *                         if it is 0 then no interrupt is generated
+ *
+ * @return kStatus_Success on success
+ *         kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM period
+ */
+status_t CTIMER_SetupPwmPeriod(
+    CTIMER_Type *base, ctimer_match_t matchChannel, uint32_t pwmPeriod, uint32_t pulsePeriod, bool enableInt);
+
+/*!
+ * @brief Configures the PWM signal parameters.
+ *
+ * Enables PWM mode on the match channel passed in and will then setup the match value
+ * and other match parameters to generate a PWM signal.
+ * This function will assign match channel 3 to set the PWM cycle.
+ *
+ * @note When setting PWM output from multiple output pins, all should use the same PWM
+ * frequency. Please use CTIMER_SetupPwmPeriod to set up the PWM with high resolution.
+ *
+ * @param base             Ctimer peripheral base address
+ * @param matchChannel     Match pin to be used to output the PWM signal
+ * @param dutyCyclePercent PWM pulse width; the value should be between 0 to 100
+ * @param pwmFreq_Hz       PWM signal frequency in Hz
+ * @param srcClock_Hz      Timer counter clock in Hz
+ * @param enableInt        Enable interrupt when the timer value reaches the match value of the PWM pulse,
+ *                         if it is 0 then no interrupt is generated
+ *
+ * @return kStatus_Success on success
+ *         kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM cycle
+ */
+status_t CTIMER_SetupPwm(CTIMER_Type *base,
+                         ctimer_match_t matchChannel,
+                         uint8_t dutyCyclePercent,
+                         uint32_t pwmFreq_Hz,
+                         uint32_t srcClock_Hz,
+                         bool enableInt);
+
+/*!
+ * @brief Updates the pulse period of an active PWM signal.
+ *
+ * @param base         Ctimer peripheral base address
+ * @param matchChannel Match pin to be used to output the PWM signal
+ * @param pulsePeriod  New PWM pulse width match value
+ */
+static inline void CTIMER_UpdatePwmPulsePeriod(CTIMER_Type *base, ctimer_match_t matchChannel, uint32_t pulsePeriod)
+{
+    /* Update PWM pulse period match value */
+    base->MR[matchChannel] = pulsePeriod;
+}
+
+/*!
+ * @brief Updates the duty cycle of an active PWM signal.
+ *
+ * @note Please use CTIMER_UpdatePwmPulsePeriod to update the PWM with high resolution.
+ *
+ * @param base             Ctimer peripheral base address
+ * @param matchChannel     Match pin to be used to output the PWM signal
+ * @param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100
+ */
+void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent);
+
+/*! @}*/
+
+/*!
+ * @brief Setup the match register.
+ *
+ * User configuration is used to setup the match value and action to be taken when a match occurs.
+ *
+ * @param base         Ctimer peripheral base address
+ * @param matchChannel Match register to configure
+ * @param config       Pointer to the match configuration structure
+ */
+void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config);
+
+/*!
+ * @brief Setup the capture.
+ *
+ * @param base      Ctimer peripheral base address
+ * @param capture   Capture channel to configure
+ * @param edge      Edge on the channel that will trigger a capture
+ * @param enableInt Flag to enable channel interrupts, if enabled then the registered call back
+ *                  is called upon capture
+ */
+void CTIMER_SetupCapture(CTIMER_Type *base,
+                         ctimer_capture_channel_t capture,
+                         ctimer_capture_edge_t edge,
+                         bool enableInt);
+
+/*!
+ * @brief Get the timer count value from TC register.
+ *
+ * @param  base  Ctimer peripheral base address.
+ * @return       return the timer count value.
+ */
+static inline uint32_t CTIMER_GetTimerCountValue(CTIMER_Type *base)
+{
+    return (base->TC);
+}
+
+/*!
+ * @brief Register callback.
+ *
+ * @param base      Ctimer peripheral base address
+ * @param cb_func   callback function
+ * @param cb_type   callback function type, singular or multiple
+ */
+void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type);
+
+/*!
+ * @name Interrupt Interface
+ * @{
+ */
+
+/*!
+ * @brief Enables the selected Timer interrupts.
+ *
+ * @param base Ctimer peripheral base address
+ * @param mask The interrupts to enable. This is a logical OR of members of the
+ *             enumeration ::ctimer_interrupt_enable_t
+ */
+static inline void CTIMER_EnableInterrupts(CTIMER_Type *base, uint32_t mask)
+{
+    /* Enable match interrupts */
+    base->MCR |= mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK);
+
+/* Enable capture interrupts */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    base->CCR |= mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+                         | CTIMER_CCR_CAP3I_MASK
+#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
+                        );
+#endif
+}
+
+/*!
+ * @brief Disables the selected Timer interrupts.
+ *
+ * @param base Ctimer peripheral base address
+ * @param mask The interrupts to enable. This is a logical OR of members of the
+ *             enumeration ::ctimer_interrupt_enable_t
+ */
+static inline void CTIMER_DisableInterrupts(CTIMER_Type *base, uint32_t mask)
+{
+    /* Disable match interrupts */
+    base->MCR &= ~(mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK));
+
+/* Disable capture interrupts */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    base->CCR &= ~(mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+                           | CTIMER_CCR_CAP3I_MASK
+#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
+                           ));
+#endif
+}
+
+/*!
+ * @brief Gets the enabled Timer interrupts.
+ *
+ * @param base Ctimer peripheral base address
+ *
+ * @return The enabled interrupts. This is the logical OR of members of the
+ *         enumeration ::ctimer_interrupt_enable_t
+ */
+static inline uint32_t CTIMER_GetEnabledInterrupts(CTIMER_Type *base)
+{
+    uint32_t enabledIntrs = 0;
+
+    /* Get all the match interrupts enabled */
+    enabledIntrs =
+        base->MCR & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK);
+
+/* Get all the capture interrupts enabled */
+#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
+    enabledIntrs |= base->CCR & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK
+#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
+                                 | CTIMER_CCR_CAP3I_MASK
+#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
+                                );
+#endif
+
+    return enabledIntrs;
+}
+
+/*! @}*/
+
+/*!
+ * @name Status Interface
+ * @{
+ */
+
+/*!
+ * @brief Gets the Timer status flags.
+ *
+ * @param base Ctimer peripheral base address
+ *
+ * @return The status flags. This is the logical OR of members of the
+ *         enumeration ::ctimer_status_flags_t
+ */
+static inline uint32_t CTIMER_GetStatusFlags(CTIMER_Type *base)
+{
+    return base->IR;
+}
+
+/*!
+ * @brief Clears the Timer status flags.
+ *
+ * @param base Ctimer peripheral base address
+ * @param mask The status flags to clear. This is a logical OR of members of the
+ *             enumeration ::ctimer_status_flags_t
+ */
+static inline void CTIMER_ClearStatusFlags(CTIMER_Type *base, uint32_t mask)
+{
+    base->IR = mask;
+}
+
+/*! @}*/
+
+/*!
+ * @name Counter Start and Stop
+ * @{
+ */
+
+/*!
+ * @brief Starts the Timer counter.
+ *
+ * @param base Ctimer peripheral base address
+ */
+static inline void CTIMER_StartTimer(CTIMER_Type *base)
+{
+    base->TCR |= CTIMER_TCR_CEN_MASK;
+}
+
+/*!
+ * @brief Stops the Timer counter.
+ *
+ * @param base Ctimer peripheral base address
+ */
+static inline void CTIMER_StopTimer(CTIMER_Type *base)
+{
+    base->TCR &= ~CTIMER_TCR_CEN_MASK;
+}
+
+/*! @}*/
+
+/*!
+ * @brief Reset the counter.
+ *
+ * The timer counter and prescale counter are reset on the next positive edge of the APB clock.
+ *
+ * @param base Ctimer peripheral base address
+ */
+static inline void CTIMER_Reset(CTIMER_Type *base)
+{
+    base->TCR |= CTIMER_TCR_CRST_MASK;
+    base->TCR &= ~CTIMER_TCR_CRST_MASK;
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_CTIMER_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flash.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flash.c
new file mode 100755
index 0000000..d48b803
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flash.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flash.h"
+#include "rom_api.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.jn_flash"
+#endif
+
+/*****************************************************************************
+ * Private types/enumerations/variables
+ ****************************************************************************/
+
+#define MAX_ERASE_LENGTH (FLASH_PAGE_SIZE * 100)
+
+/*
+ * Macros below participate to the Flash checksum calculation.
+ * FLASH_CheckSum implements CMD_CHECKSUM function of the flash controller for whole pages strictly.
+ * SW is required when needing to program a checksums or check over areas smaller than a whole flash page.
+ */
+#define RSHIFT_128BIT(_WORD_, _SHIFT_)     \
+    _WORD_[0] >>= (uint32_t)_SHIFT_;\
+    _WORD_[0] |= (uint32_t)((_WORD_[1] & (uint32_t)((1<<_SHIFT_)-1)) << (uint32_t)(32-_SHIFT_));\
+    _WORD_[1] >>=(uint32_t)_SHIFT_;\
+    _WORD_[1] |= (uint32_t)((_WORD_[2] & (uint32_t)((1<<_SHIFT_)-1)) << (uint32_t)(32-_SHIFT_));\
+    _WORD_[2] >>=(uint32_t)_SHIFT_;\
+    _WORD_[2] |= (uint32_t)((_WORD_[3] & (uint32_t)((1<<_SHIFT_)-1)) << (uint32_t)(32-_SHIFT_));\
+    _WORD_[3] >>=(uint32_t)_SHIFT_;
+
+#define PARITY(_WORD_) \
+          (uint32_t)((_WORD_ & (uint32_t)(1<<0UL))>>0UL) \
+        ^ (uint32_t)((_WORD_ & (uint32_t)(1<<2UL))>>2UL) \
+        ^ (uint32_t)((_WORD_ & (uint32_t)(1<<27UL))>>27UL)\
+        ^ (uint32_t)((_WORD_ & (uint32_t)(1<<29UL))>>29UL)
+/*****************************************************************************
+ * Public types/enumerations/variables
+ ****************************************************************************/
+flash_config_t gFlashConfig;
+
+/*****************************************************************************
+ * Private functions
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Public functions
+ ****************************************************************************/
+
+/**
+ * @brief      Enable the FLASH
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     Nothing
+ */
+void FLASH_Init(FLASH_Type *pFLASH)
+{
+    int status;
+    /* From Flash Adapter */
+    gFlashConfig.PFlashSectorSize = FLASH_PAGE_SIZE;
+    ROM_GetFlash(&gFlashConfig.PFlashBlockBase, &gFlashConfig.PFlashTotalSize);
+
+    pFLASH->CMD = FLASH_CMD_INIT;
+
+    status = FLASH_Wait(pFLASH);
+    /* Loop if the flash controller detects an unrecoverable error */
+    /* That should have been caught by the ROM code but might not !*/
+    if (status & FLASH_FAIL)
+    {
+        while (1);
+    }
+}
+
+/**
+ * @brief      Power down the FLASH
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     Nothing
+ */
+void FLASH_Powerdown(FLASH_Type *pFLASH)
+{
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    pFLASH->CMD = FLASH_CMD_POWERDOWN;
+
+    FLASH_Wait(pFLASH);
+}
+
+/**
+ * @brief      Wait for FLASH command to complete
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Wait(FLASH_Type *pFLASH)
+{
+    while (!(pFLASH->INT_STATUS & FLASH_DONE));
+    /* mask out ECC_ERR bit that may raise independantly from flash commands */
+    return (pFLASH->INT_STATUS & ~FLASH_ECC_ERR);
+}
+
+/**
+ * @brief      Return unfiltered FLASH INT_STATUS.
+ * In normal operation FLASH_DONE rises systematically but other status bits
+ * may rise at the same time or have risen before to notify of an error.
+ * Usually testing the value returned by FLASH_Wait is sufficionet but in some special
+ * cases the raw value may be needed.
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral.
+ *
+ * @return     INT_STATUS raw value.
+ * @see flash_status_t
+ */
+int FLASH_GetStatus(FLASH_Type *pFLASH)
+{
+    return pFLASH->INT_STATUS;
+}
+
+/**
+ * @brief      Erase page
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Erase(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End)
+{
+    int status = 0;
+
+    uint32_t erase_length = pu8End - pu8Start;
+
+    while (erase_length > 0)
+    {
+        pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+        if (erase_length > MAX_ERASE_LENGTH)
+        {
+            pu8End = pu8Start + MAX_ERASE_LENGTH - 1;
+            erase_length -= MAX_ERASE_LENGTH;
+        }
+        else
+        {
+            pu8End       = pu8Start + erase_length;
+            erase_length = 0;
+        }
+
+        /* Set end address */
+        *pu8End = 0xAA;
+
+        /* Set start address */
+        *pu8Start = 0xBB;
+
+        pu8Start = pu8End + 1;
+
+        pFLASH->CMD = FLASH_CMD_ERASE_RANGE;
+
+        status = FLASH_Wait(pFLASH);
+    }
+
+    return status;
+}
+
+/**
+ * @brief      Erase multiple pages
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  u32StartPage Index of page to start erasing from
+ * @param[in]  u32PageCount Number of pages to erase
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_ErasePages(FLASH_Type *pFLASH, uint32_t u32StartPage, uint32_t u32PageCount)
+{
+    uint8_t *pu8Start = (uint8_t *)(FLASH_PAGE_SIZE * u32StartPage);
+    uint8_t *pu8End   = (pu8Start + FLASH_PAGE_SIZE * u32PageCount) - 1;
+
+    return FLASH_Erase(pFLASH, pu8Start, pu8End);
+}
+
+/**
+ * @brief      Page Blank check
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_BlankCheck(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End)
+{
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    /* Set end address */
+    *pu8End = 0xAA;
+
+    /* Set start address */
+    *pu8Start = 0xBB;
+
+    pFLASH->CMD = FLASH_CMD_BLANK_CHECK;
+
+    return FLASH_Wait(pFLASH);
+}
+
+/**
+ * @brief      Margin Check
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_MarginCheck(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End)
+{
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    /* Set end address */
+    *pu8End = 0xAA;
+
+    /* Set start address */
+    *pu8Start = 0xBB;
+
+    pFLASH->CMD = FLASH_CMD_MARGIN_CHECK;
+
+    return FLASH_Wait(pFLASH);
+}
+
+/**
+ * @brief      Program page
+ *
+ * @param[in]  pFLASH Pointer to selected FLASH peripheral
+ * @param[out] pu32Start Pointer location that must be programmed in flash
+ * @param[in]  pu32Data Pointer to source buffer being written to flash
+ * @param[in]  u32Length Number of bytes to be programmed
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Program(FLASH_Type *pFLASH, uint32_t *pu32Start, uint32_t *pu32Data, uint32_t u32Length)
+{
+    int status = 0;
+
+    uint32_t end  = (uint32_t)pu32Start + u32Length;
+
+    uint32_t padding  = (FLASH_PAGE_SIZE - (end & (FLASH_PAGE_SIZE-1))) & (FLASH_PAGE_SIZE-1);
+
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    pFLASH->AUTOPROG = FLASH_AUTO_PAGE;
+
+    memcpy(pu32Start, pu32Data, u32Length);
+
+    while (padding-- > 0)
+    {
+        *(uint8_t*)end ++ = 0;
+    }
+
+    status = FLASH_Wait(pFLASH);
+
+    pFLASH->AUTOPROG = FLASH_AUTO_OFF;
+
+    return status;
+}
+
+/**
+ * @brief      Page Checksum
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Pointer to data within starting page  page checksum must be computed
+ * @param[in]  pu8End Pointer to data whose page is the last of the checksum calculation
+ * @param[out] au32Checksum Four 32bit word array to store checksum calculation result
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Checksum(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End, uint32_t au32Checksum[4])
+{
+    int status;
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    /* Set end address */
+    *pu8End = 0xAA;
+
+    /* Set start address */
+    *pu8Start = 0xBB;
+
+    pFLASH->CMD = FLASH_CMD_CHECKSUM;
+
+    status = FLASH_Wait(pFLASH);
+
+    au32Checksum[0] = pFLASH->DATAW[0];
+    au32Checksum[1] = pFLASH->DATAW[1];
+    au32Checksum[2] = pFLASH->DATAW[2];
+    au32Checksum[3] = pFLASH->DATAW[3];
+
+    return status;
+}
+
+/**
+ * @brief      Read flash word (16 byte worth of data)
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Pointer to data to be read
+ * @param[in]  u32ReadMode Read mode see also flash_read_mode_t
+ * @param[out] au32Data Four 32bit word array to store read result
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Read(FLASH_Type *pFLASH, uint8_t *pu8Start, uint32_t u32ReadMode, uint32_t au32Data[4])
+{
+    int status;
+    pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+    /* Set start address */
+    *pu8Start = 0xBB;
+
+    /* Set read mode */
+    pFLASH->DATAW[0] = u32ReadMode;
+
+    pFLASH->CMD = FLASH_CMD_READ_SINGLE_WORD;
+
+    status = FLASH_Wait(pFLASH);
+
+    au32Data[0] = pFLASH->DATAW[0];
+    au32Data[1] = pFLASH->DATAW[1];
+    au32Data[2] = pFLASH->DATAW[2];
+    au32Data[3] = pFLASH->DATAW[3];
+
+    return status;
+}
+
+/*
+* Details on the fields that can be updated through the FLASH_CMD_SET_READ_MODE cmd.
+* bit 31   : prefetch enable
+* bit 30   : ignore hprot[0] and assume that all accesses are code accesses
+* bit 29-28: 00: hprot[3] specifies whether an access is cacheable
+*            01: reserved
+*            10: hprot[3] ignored, all accesses are not cacheable
+*            11: hprot[3] ignored, all accesses are cacheable
+* bit 27-8 : reserved
+* bit 7    : ewle read mode active. Default value after reset is: 0
+* bit 6-4  : number of extra precharge states.
+* bit 3-0  : number of extra evaluation states.
+*
+* After reset, the only value field set is the "number of extra evaluation states" field. In other words, if you want to
+* return to the default values, you shall write DEFAULT_READ_MODE to DATAW[0]
+*/
+#define DEFAULT_READ_MODE_VAL          0x00000000
+#define EWLE_MODE_MASK                 0x80
+
+/**
+ * @brief      Configure the flash wait state depending of the elwe mode and CPU frequency.
+ * When the CPU clock frequency is decreased, the Set Read command shall be called after the frequency change.
+ * When the CPU clock frequency is increased, the Set Read command shall be called before the frequency change.
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ * @param      freq_48M_not_32M CPU clock frequency @48MHz - lower or equal to 32Mhz if 0
+ *
+ * @return     Nothing
+ */
+void FLASH_SetReadMode(FLASH_Type *pFLASH, bool cpu_freq_48M_not_32M)
+{
+   int flash_ws = DEFAULT_READ_MODE_VAL;
+
+   pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
+
+   flash_ws += cpu_freq_48M_not_32M ? 1 : 0;
+
+   pFLASH->DATAW[0] = (EWLE_MODE_MASK | flash_ws);
+
+   pFLASH->CMD = FLASH_CMD_SET_READ_MODE;
+
+   /* no need to wait until command is completed: further accesses are stalled
+    * until the command is completed. */
+   //status = FLASH_Wait(pFLASH);
+}
+
+/**
+ * @brief      Calculate checksum using the same checksum algorithm as the CMD_CHECKSUM implementation of the
+ * Flash controller. When executed over a 512 byte page (page size) must return the same value as FLASH_Checksum.
+ *
+ * @param[in]  input Pointer to data over which checksum calculation must be executed.
+ * @param[in]  nb_128b_words Number of 16 byte words on flash.
+ * @param[out] misr Pointer on a four 32bit word array to store calculated checksum.
+ * @param[in]  init Set to true to clear the misr buffer.
+ *
+ * @return     Nothing
+ */
+void FLASH_CalculateChecksum(const uint32_t *input,
+                            size_t nb_128b_words,
+                            uint32_t* misr,
+                            int init)
+{
+    int i;
+
+    if (init)
+    {
+        for (i = 0; i < 4; i++)
+        {
+            misr[i] = 0;
+        }
+    }
+
+    for (i = 0; i < nb_128b_words*4; )
+    {
+        int cy;
+
+        /* Compute carry */
+        cy = PARITY(misr[0]);
+        /* Shift right the 128 bits */
+        RSHIFT_128BIT(misr, 1UL);
+        /* Let Carry become the MISR[127] bit */
+        misr[3] ^= (uint32_t)((cy&1UL) << 31);
+
+        /* Xor with 128 bit word */
+        misr[0] ^= input[i++];
+        misr[1] ^= input[i++];
+        misr[2] ^= input[i++];
+        misr[3] ^= input[i++];
+    }
+
+}
+
+/*
+ * Expected values for Config page checksum and GPO checksum.
+ */
+const uint32_t CONFIG_PAGE_CHSUM[4] = {0x11112222U, 0x33334444U, 0x55556666U, 0x77778888U};
+const uint32_t GPO_CHKSUM[4] =         {0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U};
+
+/**
+ * @brief      Calculate checksum over page (N-2) aka CONFIG page and check it matches the expected value.
+ *
+ * @param[in]  page_buffer Pointer to data over which checksum calculation must be executed.
+ * @param[out] misr Pointer on a four 32bit word array to store calculated checksum.
+ *             Note: this buffer is only useful for debugging purposes.
+ *
+ * @return Result of the page checksum verification:
+ *         -  0: Verification successfully.
+ *         - -1: Verification failed.
+ */
+int FLASH_ConfigPageVerifyPageChecksum(const uint32_t *page_buffer,
+                                      uint32_t *misr)
+{
+    int res = 0;
+    FLASH_CalculateChecksum(page_buffer, 32, &misr[0], 1);
+    for (int i = 0; i < 4; i++)
+    {
+        if (misr[i] != CONFIG_PAGE_CHSUM[i])
+        {
+            res = -1;
+            break;
+        }
+    }
+    return res;
+}
+
+/**
+ * @brief      Calculate checksum over GPO array of CONFIG page and check it matches the expected value
+ *
+ * @param[in]  page_buffer Pointer to data over which checksum calculation must be executed.
+ * @param[out] misr Pointer on a 4 32bit word array to store calculated checksum.
+ *             Note: this buffer is only useful for debugging purposes.
+ *
+ * @return Result of the GPO array checksum verification:
+ *         -  0: Verification successfully.
+ *         - -1: Verification failed.
+ */
+int FLASH_ConfigPageVerifyGpoChecksum(const uint32_t *page_buffer,
+                                     uint32_t *misr)
+{
+    int res = 0;
+    FLASH_CalculateChecksum(page_buffer, 5, misr, 1);
+    for (int i = 0; i < 4; i++)
+    {
+        if (misr[i] != GPO_CHKSUM[i])
+        {
+            res = -1;
+            break;
+        }
+    }
+    return res;
+}
+
+/**
+ * @brief      Configure the flash wait state depending of the elwe mode and CPU frequency.
+ * When the CPU clock frequency is decreased, the Set Read command shall be called after the frequency change.
+ * When the CPU clock frequency is increased, the Set Read command shall be called before the frequency change.
+ *
+ * @param      page_ram_buffer Pointer to RAM page buffer in which the read-modify-write of page (N-2) is performed
+ * @param      gpo_chksum Pointer on a four 32bit word array to store calculated checksum.
+ * @param      page_chksum Pointer on a four 32bit word array to store calculated checksum.
+ *
+ * @return     Nothing
+ */
+void FLASH_ConfigPageUpdate(uint32_t *page_ram_buffer,
+                          uint32_t *gpo_chksum,
+                          uint32_t *page_chksum )
+{
+
+    FLASH_CalculateChecksum(page_ram_buffer, 4, gpo_chksum, 1);
+    FLASH_CalculateChecksum(GPO_CHKSUM, 1, gpo_chksum, 0);
+    for (int i = 0; i < 4; i++)
+    {
+        page_ram_buffer[16+i] = gpo_chksum[i];
+    }
+    FLASH_CalculateChecksum(&page_ram_buffer[0], 31, page_chksum, 1);
+    FLASH_CalculateChecksum(CONFIG_PAGE_CHSUM, 1, page_chksum, 0);
+    for (int i = 0; i < 4; i++)
+    {
+        page_ram_buffer[124+i] = page_chksum[i];
+    }
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flash.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flash.h
new file mode 100755
index 0000000..c21953c
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flash.h
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FSL_FLASH_H_
+#define __FSL_FLASH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup jn_flash
+ * @{
+ */
+
+/*! @file */
+
+/*******************
+ * EXPORTED MACROS  *
+ ********************/
+
+/* FLASH Commands */
+#define FLASH_CMD_INIT 0
+#define FLASH_CMD_POWERDOWN 1
+#define FLASH_CMD_SET_READ_MODE 2
+#define FLASH_CMD_READ_SINGLE_WORD 3
+#define FLASH_CMD_ERASE_RANGE 4
+#define FLASH_CMD_BLANK_CHECK 5
+#define FLASH_CMD_MARGIN_CHECK 6
+#define FLASH_CMD_CHECKSUM 7
+#define FLASH_CMD_WRITE 8
+#define FLASH_CMD_WRITE_PROG 10
+#define FLASH_CMD_PROGRAM 12
+#define FLASH_CMD_REPORT_ECC 13
+
+/* FLASH Autoprogram modes */
+#define FLASH_AUTO_OFF 0
+#define FLASH_AUTO_WORD 1
+#define FLASH_AUTO_PAGE 2
+
+#define FLASH_BASE_ADDRESS 0
+#define FLASH_PAGE_SIZE 512
+#define FLASH_PAGE_SIZE_LOG 9
+
+#define FLASH_CONFIG_PAGE_ADDR 0x9fc00
+#define FLASH_TRIMMING_DATA_ADDR 0x9fe00
+
+/**
+ * @brief FLASH INT_STATUS register definitions
+ */
+#define FLASH_FAIL (1 << 0)    /*!< Command failed */
+#define FLASH_ERR (1 << 1)     /*!< Illegal command */
+#define FLASH_DONE (1 << 2)    /*!< Command complete */
+#define FLASH_ECC_ERR (1 << 3) /*!< ECC error detected */
+
+/**
+ * @brief FLASH INT_ENABLE register definitions
+ */
+#define FLASH_FAIL (1 << 0)    /*!< Command failed */
+#define FLASH_ERR (1 << 1)     /*!< Illegal command */
+#define FLASH_DONE (1 << 2)    /*!< Command complete */
+#define FLASH_ECC_ERR (1 << 3) /*!< ECC error detected */
+
+#define FLASH_STAT_ALL (0xF)
+
+/* FLASH Events */
+#define FLASH_EVENT_RESET (1 << 0)
+//#define FLASH_EVENT_WAKEUP         (1 << 1)
+//#define FLASH_EVENT_ABORT          (1 << 2)
+
+/******************************
+ * EXPORTED TYPE DEFINITIONS  *
+ ******************************/
+typedef enum _flash_status
+{
+    kStatus_FLASH_Success         = FLASH_DONE,                             /*!< flash operation is successful*/
+    kStatus_FLASH_Fail            = FLASH_DONE | FLASH_FAIL,                /*!< flash operation is not successful*/
+    kStatus_FLASH_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),   /*!< Invalid argument */
+    kStatus_FLASH_AlignmentError  = MAKE_STATUS(kStatusGroup_FLASH, 6),     /*!< Alignment Error */
+    kStatus_FLASH_EccError        = FLASH_DONE | FLASH_ECC_ERR,             /*!< ECC error detected */
+    kStatus_FLASH_Error           = FLASH_DONE | FLASH_ERR,                 /*!< Illegal command */
+} flash_status_t;
+
+
+/* Read Mode related definitions */
+#define FLASH_READ_MODE_RD_DMACC_SHIFT    15
+#define FLASH_READ_MODE_SHIFT             10
+#define FLASH_READ_MODE_NORMAL             0
+#define FLASH_READ_MODE_MARGIN_VS_PROGRAM  1
+#define FLASH_READ_MODE_MARGIN_VS_ERASE    2
+#define FLASH_READ_MODE_ILLEGAL            3
+#define FLASH_READ_MODE_MASK (FLASH_READ_MODE_ILLEGAL << FLASH_READ_MODE_SHIFT)
+#define FLASH_READ_MODE_ECC_OFF_SHIFT      2
+
+typedef enum _flash_read_modes
+{
+    FLASH_ReadModeNormal         = (FLASH_READ_MODE_NORMAL << FLASH_READ_MODE_SHIFT),
+    FLASH_ReadModeNormalEccOff   = (FLASH_READ_MODE_NORMAL << FLASH_READ_MODE_SHIFT)|(1<<FLASH_READ_MODE_ECC_OFF_SHIFT),                /*!< flash operation is not successful*/
+    FLASH_ReadModeDMACC          = (1<<FLASH_READ_MODE_RD_DMACC_SHIFT),
+    FLASH_ReadModeMarginProgram  = (FLASH_READ_MODE_MARGIN_VS_PROGRAM << FLASH_READ_MODE_SHIFT),
+    FLASH_ReadModeMarginErase    = (FLASH_READ_MODE_MARGIN_VS_ERASE << FLASH_READ_MODE_SHIFT),
+} flash_read_mode_t;
+
+/*! @brief Flash configuration information.
+ *
+ * An instance of this structure is allocated by the user of the flash driver and
+ * at initialization.
+ */
+typedef struct _flash_config
+{
+    uint32_t PFlashBlockBase;  /*!< A base address of the first PFlash block */
+    uint32_t PFlashTotalSize;  /*!< The size of the combined PFlash block. */
+    uint32_t PFlashSectorSize; /*!< The size in bytes of a sector of PFlash. */
+} flash_config_t;
+
+extern flash_config_t gFlashConfig;
+
+/**
+ * @brief      Enable the FLASH
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     Nothing
+ */
+void FLASH_Init(FLASH_Type *pFLASH);
+
+/**
+ * @brief      Power down the FLASH
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     Nothing
+ */
+void FLASH_Powerdown(FLASH_Type *pFLASH);
+
+/**
+ * @brief      Wait for FLASH command to complete
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ */
+int FLASH_Wait(FLASH_Type *pFLASH);
+
+/**
+ * @brief      Erase page
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Erase(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End);
+
+/**
+ * @brief      Erase multiple pages
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  u32StartPage Index of page to start erasing from
+ * @param[in]  u32PageCount Number of pages to erase
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_ErasePages(FLASH_Type *pFLASH, uint32_t u32StartPage, uint32_t u32PageCount);
+
+/**
+ * @brief      Page Blank check
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_BlankCheck(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End);
+
+/**
+ * @brief      Margin Check
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Start address with page to inspect
+ * @param[in]  pu8End End address (included in check)
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_MarginCheck(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End);
+
+/**
+ * @brief      Program page
+ *
+ * @param[in]  pFLASH Pointer to selected FLASH peripheral
+ * @param[out] pu32Start Pointer location that must be programmed in flash
+ * @param[in]  pu32Data Pointer to source buffer being written to flash
+ * @param[in]  u32Length Number of bytes to be programmed
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Program(FLASH_Type *pFLASH, uint32_t *pu32Start, uint32_t *pu32Data, uint32_t u32Length);
+
+/**
+ * @brief      Page Checksum
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Pointer to data within starting page  page checksum must be computed
+ * @param[in]  pu8End Pointer to data whose page is the last of the checksum calculation
+ * @param[out] au32Checksum Four 32bit word array to store checksum calculation result
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Checksum(FLASH_Type *pFLASH, uint8_t *pu8Start, uint8_t *pu8End, uint32_t au32Checksum[4]);
+
+/**
+ * @brief      Read flash word (16 byte worth of data)
+ *
+ * @param      pFLASH Pointer to selected FLASH peripheral
+ * @param[in]  pu8Start Pointer to data to be read
+ * @param[in]  u32ReadMode Read mode see also flash_read_mode_t
+ * @param[out] au32Data Four 32bit word array to store read result
+ *
+ * @return     INT_STATUS with ECC_ERR bit masked out
+ * @see flash_status_t
+ */
+int FLASH_Read(FLASH_Type *pFLASH, uint8_t *pu8Start, uint32_t u32ReadMode, uint32_t au32Data[4]);
+
+/**
+ * @brief      Configure the flash wait state depending of the elwe mode and CPU frequency.
+ * When the CPU clock frequency is decreased, the Set Read command shall be called after the frequency change.
+ * When the CPU clock frequency is increased, the Set Read command shall be called before the frequency change.
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral
+ * @param      freq_48M_not_32M CPU clock frequency @48MHz - lower or equal to 32Mhz if 0
+ *
+ * @return     Nothing
+ */
+void FLASH_SetReadMode(FLASH_Type *pFLASH, bool freq_48M_not_32M);
+
+/**
+ * @brief      Calculate checksum using the same checksum algorithm as the CMD_CHECKSUM implementation of the
+ * Flash controller. When executed over a 512 byte page (page size) must return the same value as FLASH_Checksum.
+ *
+ * @param[in]  input Pointer to data over which checksum calculation must be executed.
+ * @param[in]  nb_128b_words Number of 16 byte words on flash.
+ * @param[out] misr Pointer on a four 32bit word array to store calculated checksum.
+ * @param[in]  init Set to true to clear the misr buffer.
+ *
+ * @return     Nothing
+ */
+void FLASH_CalculateChecksum(const uint32_t *input,
+                            size_t nb_128b_words,
+                            uint32_t* misr,
+                            int init);
+
+/**
+ * @brief      Calculate checksum over page (N-2) aka CONFIG page and check it matches the expected value.
+ *
+ * @param[in]  page_buffer Pointer to data over which checksum calculation must be executed.
+ * @param[out] misr Pointer on a four 32bit word array to store calculated checksum.
+ *             Note: this buffer is only useful for debugging purposes.
+ *
+ * @return Result of the page checksum verification:
+ *         -  0: Verify successfully.
+ *         - -1: Verification failed.
+ */
+int FLASH_ConfigPageVerifyPageChecksum(const uint32_t *page_buffer,
+                                      uint32_t *misr);
+
+/**
+ * @brief      Calculate checksum over GPO array of CONFIG page and check it matches the expected value
+ *
+ * @param[in]  page_buffer Pointer to data over which checksum calculation must be executed.
+ * @param[out] misr Pointer on a 4 32bit word array to store calculated checksum.
+ *             Note: this buffer is only useful for debugging purposes.
+ *
+ * @return Result of the GPO array checksum verification:
+ *         -  0: Verify successfully.
+ *         - -1: Verification failed.
+ */
+int FLASH_ConfigPageVerifyGpoChecksum(const uint32_t *page_buffer,
+                                     uint32_t *misr);
+
+/**
+ * @brief      Configure the flash wait state depending of the elwe mode and CPU frequency.
+ * When the CPU clock frequency is decreased, the Set Read command shall be called after the frequency change.
+ * When the CPU clock frequency is increased, the Set Read command shall be called before the frequency change.
+ *
+ * @param      page_ram_buffer Pointer to RAM page buffer in which the read-modify-write of page (N-2) is performed
+ * @param      gpo_chksum Pointer on a four 32bit word array to store calculated checksum.
+ * @param      page_chksum Pointer on a four 32bit word array to store calculated checksum.
+ *
+ * @return     Nothing
+ */
+void FLASH_ConfigPageUpdate(uint32_t *page_ram_buffer,
+                          uint32_t *gpo_chksum,
+                          uint32_t *page_chksum);
+
+/**
+ * @brief      Return unfiltered FLASH INT_STATUS.
+ * In normal operation FLASH_DONE rises systematically but other status bits
+ * may rise at the same time or have risen before to notify of an error.
+ * Usually testing the value returned by FLASH_Wait is sufficionet but in some special
+ * cases the raw value may be needed.
+ *
+ * @param      pFLASH Pointer to selected FLASHx peripheral.
+ *
+ * @return     INT_STATUS raw value.
+ * @see flash_status_t
+ */
+int FLASH_GetStatus(FLASH_Type *pFLASH);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FSL_FLASH_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flexcomm.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flexcomm.c
new file mode 100755
index 0000000..d51eb72
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flexcomm.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_flexcomm.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.flexcomm"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*! @brief Set the FLEXCOMM mode . */
+static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);
+
+/*! @brief check whether flexcomm supports peripheral type */
+static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */
+static flexcomm_irq_handler_t s_flexcommIrqHandler[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
+
+/*! @brief Pointers to handles for each instance to provide context to interrupt routines */
+static void *s_flexcommHandle[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
+
+/*! @brief Array to map FLEXCOMM instance number to IRQ number. */
+IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;
+
+/*! @brief Array to map FLEXCOMM instance number to base address. */
+static const uint32_t s_flexcommBaseAddrs[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = FLEXCOMM_BASE_ADDRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief IDs of clock for each FLEXCOMM module */
+static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
+/*! @brief Pointers to FLEXCOMM resets for each instance. */
+static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/* check whether flexcomm supports peripheral type */
+static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)
+{
+    if (periph == FLEXCOMM_PERIPH_NONE)
+    {
+        return true;
+    }
+    else if (periph <= FLEXCOMM_PERIPH_I2S_TX)
+    {
+        return (base->PSELID & (uint32_t)(1 << ((uint32_t)periph + 3))) > (uint32_t)0 ? true : false;
+    }
+    else if (periph == FLEXCOMM_PERIPH_I2S_RX)
+    {
+        return (base->PSELID & (1 << 7)) > (uint32_t)0 ? true : false;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+/* Get the index corresponding to the FLEXCOMM */
+/*! brief Returns instance number for FLEXCOMM module with given base address. */
+uint32_t FLEXCOMM_GetInstance(void *base)
+{
+    int i;
+
+    for (i = 0; i < FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)
+    {
+        if ((uint32_t)base == s_flexcommBaseAddrs[i])
+        {
+            return i;
+        }
+    }
+
+    assert(false);
+    return 0;
+}
+
+/* Changes FLEXCOMM mode */
+static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)
+{
+    /* Check whether peripheral type is present */
+    if (!FLEXCOMM_PeripheralIsPresent(base, periph))
+    {
+        return kStatus_OutOfRange;
+    }
+
+    /* Flexcomm is locked to different peripheral type than expected  */
+    if ((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) && ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != periph))
+    {
+        return kStatus_Fail;
+    }
+
+    /* Check if we are asked to lock */
+    if (lock)
+    {
+        base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;
+    }
+    else
+    {
+        base->PSELID = (uint32_t)periph;
+    }
+
+    return kStatus_Success;
+}
+
+/*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
+status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)
+{
+    int idx = FLEXCOMM_GetInstance(base);
+
+    if (idx < 0)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* Enable the peripheral clock */
+    CLOCK_EnableClock(s_flexcommClocks[idx]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
+    /* Reset the FLEXCOMM module */
+    RESET_PeripheralReset(s_flexcommResets[idx]);
+#endif
+
+    /* Set the FLEXCOMM to given peripheral */
+    return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);
+}
+
+/*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
+ * mode */
+void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle)
+{
+    uint32_t instance;
+
+    /* Look up instance number */
+    instance = FLEXCOMM_GetInstance(base);
+
+    /* Clear handler first to avoid execution of the handler with wrong handle */
+    s_flexcommIrqHandler[instance] = NULL;
+    s_flexcommHandle[instance]     = handle;
+    s_flexcommIrqHandler[instance] = handler;
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+
+/* IRQ handler functions overloading weak symbols in the startup */
+#if defined(FLEXCOMM0)
+void FLEXCOMM0_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[0]);
+    s_flexcommIrqHandler[0]((void *)s_flexcommBaseAddrs[0], s_flexcommHandle[0]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM1)
+void FLEXCOMM1_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[1]);
+    s_flexcommIrqHandler[1]((void *)s_flexcommBaseAddrs[1], s_flexcommHandle[1]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM2)
+void FLEXCOMM2_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[2]);
+    s_flexcommIrqHandler[2]((void *)s_flexcommBaseAddrs[2], s_flexcommHandle[2]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM3)
+void FLEXCOMM3_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[3]);
+    s_flexcommIrqHandler[3]((void *)s_flexcommBaseAddrs[3], s_flexcommHandle[3]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM4)
+void FLEXCOMM4_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[4]);
+    s_flexcommIrqHandler[4]((void *)s_flexcommBaseAddrs[4], s_flexcommHandle[4]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+
+#endif
+
+#if defined(FLEXCOMM5)
+void FLEXCOMM5_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[5]);
+    s_flexcommIrqHandler[5]((void *)s_flexcommBaseAddrs[5], s_flexcommHandle[5]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM6)
+void FLEXCOMM6_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[6]);
+    s_flexcommIrqHandler[6]((void *)s_flexcommBaseAddrs[6], s_flexcommHandle[6]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM7)
+void FLEXCOMM7_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[7]);
+    s_flexcommIrqHandler[7]((void *)s_flexcommBaseAddrs[7], s_flexcommHandle[7]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM8)
+void FLEXCOMM8_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[8]);
+    s_flexcommIrqHandler[8]((void *)s_flexcommBaseAddrs[8], s_flexcommHandle[8]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM9)
+void FLEXCOMM9_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[9]);
+    s_flexcommIrqHandler[9]((void *)s_flexcommBaseAddrs[9], s_flexcommHandle[9]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM10)
+void FLEXCOMM10_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[10]);
+    s_flexcommIrqHandler[10]((void *)s_flexcommBaseAddrs[10], s_flexcommHandle[10]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM11)
+void FLEXCOMM11_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[11]);
+    s_flexcommIrqHandler[11]((void *)s_flexcommBaseAddrs[11], s_flexcommHandle[11]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM12)
+void FLEXCOMM12_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[12]);
+    s_flexcommIrqHandler[12]((void *)s_flexcommBaseAddrs[12], s_flexcommHandle[12]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM13)
+void FLEXCOMM13_DriverIRQHandler(void)
+{
+    assert(s_flexcommIrqHandler[13]);
+    s_flexcommIrqHandler[13]((void *)s_flexcommBaseAddrs[13], s_flexcommHandle[13]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM14)
+void FLEXCOMM14_DriverIRQHandler(void)
+{
+    uint32_t instance;
+
+    /* Look up instance number */
+    instance = FLEXCOMM_GetInstance(FLEXCOMM14);
+    assert(s_flexcommIrqHandler[instance]);
+    s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM15)
+void FLEXCOMM15_DriverIRQHandler(void)
+{
+    uint32_t instance;
+
+    /* Look up instance number */
+    instance = FLEXCOMM_GetInstance(FLEXCOMM15);
+    assert(s_flexcommIrqHandler[instance]);
+    s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM16)
+void FLEXCOMM16_DriverIRQHandler(void)
+{
+    uint32_t instance;
+
+    /* Look up instance number */
+    instance = FLEXCOMM_GetInstance(FLEXCOMM16);
+    assert(s_flexcommIrqHandler[instance]);
+    s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+  exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+    __DSB();
+#endif
+}
+#endif
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flexcomm.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flexcomm.h
new file mode 100755
index 0000000..cf5b6ef
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_flexcomm.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_FLEXCOMM_H_
+#define _FSL_FLEXCOMM_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup flexcomm_driver
+ * @{
+ */
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief FlexCOMM driver version 2.0.2. */
+#define FSL_FLEXCOMM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
+/*@}*/
+
+/*! @brief FLEXCOMM peripheral modes. */
+typedef enum
+{
+    FLEXCOMM_PERIPH_NONE,   /*!< No peripheral */
+    FLEXCOMM_PERIPH_USART,  /*!< USART peripheral */
+    FLEXCOMM_PERIPH_SPI,    /*!< SPI Peripheral */
+    FLEXCOMM_PERIPH_I2C,    /*!< I2C Peripheral */
+    FLEXCOMM_PERIPH_I2S_TX, /*!< I2S TX Peripheral */
+    FLEXCOMM_PERIPH_I2S_RX, /*!< I2S RX Peripheral */
+} FLEXCOMM_PERIPH_T;
+
+/*! @brief Typedef for interrupt handler. */
+typedef void (*flexcomm_irq_handler_t)(void *base, void *handle);
+
+/*! @brief Array with IRQ number for each FLEXCOMM module. */
+extern IRQn_Type const kFlexcommIrqs[];
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*! @brief Returns instance number for FLEXCOMM module with given base address. */
+uint32_t FLEXCOMM_GetInstance(void *base);
+
+/*! @brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
+status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph);
+
+/*! @brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
+ * mode */
+void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*@}*/
+
+#endif /* _FSL_FLEXCOMM_H_*/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_gpio.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_gpio.c
new file mode 100755
index 0000000..926880f
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_gpio.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_gpio.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.lpc_gpio"
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Array to map FGPIO instance number to clock name. */
+static const clock_ip_name_t s_gpioClockName[] = GPIO_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
+/*! @brief Pointers to GPIO resets for each instance. */
+static const reset_ip_name_t s_gpioResets[] = GPIO_RSTS_N;
+#endif
+/*******************************************************************************
+ * Prototypes
+ ************ ******************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+/*!
+ * brief Initializes the GPIO peripheral.
+ *
+ * This function ungates the GPIO clock.
+ *
+ * param base   GPIO peripheral base pointer.
+ * param port   GPIO port number.
+ */
+void GPIO_PortInit(GPIO_Type *base, uint32_t port)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    assert(port < ARRAY_SIZE(s_gpioClockName));
+
+    /* Upgate the GPIO clock */
+    CLOCK_EnableClock(s_gpioClockName[port]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
+    /* Reset the GPIO module */
+    RESET_PeripheralReset(s_gpioResets[port]);
+#endif
+}
+
+/*!
+ * brief Initializes a GPIO pin used by the board.
+ *
+ * To initialize the GPIO, define a pin configuration, either input or output, in the user file.
+ * Then, call the GPIO_PinInit() function.
+ *
+ * This is an example to define an input pin or output pin configuration:
+ * code
+ * // Define a digital input pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalInput,
+ *   0,
+ * }
+ * //Define a digital output pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalOutput,
+ *   0,
+ * }
+ * endcode
+ *
+ * param base   GPIO peripheral base pointer(Typically GPIO)
+ * param port   GPIO port number
+ * param pin    GPIO pin number
+ * param config GPIO pin configuration pointer
+ */
+void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config)
+{
+    if (config->pinDirection == kGPIO_DigitalInput)
+    {
+#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
+        base->DIRCLR[port] = 1U << pin;
+#else
+        base->DIR[port] &= ~(1U << pin);
+#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
+    }
+    else
+    {
+        /* Set default output value */
+        if (config->outputLogic == 0U)
+        {
+            base->CLR[port] = (1U << pin);
+        }
+        else
+        {
+            base->SET[port] = (1U << pin);
+        }
+/* Set pin direction */
+#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
+        base->DIRSET[port] = 1U << pin;
+#else
+        base->DIR[port] |= 1U << pin;
+#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
+    }
+}
+
+#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
+/*!
+ * @brief Configures the gpio pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param pin GPIO pin number.
+ * @param config GPIO pin interrupt configuration..
+ */
+void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config)
+{
+    base->INTEDG[port] = base->INTEDG[port] | (config->mode << pin);
+
+    base->INTPOL[port] = base->INTPOL[port] | (config->polarity << pin);
+}
+
+/*!
+ * @brief Enables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTENA[port] = base->INTENA[port] | mask;
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTENB[port] = base->INTENB[port] | mask;
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @brief Disables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTENA[port] = base->INTENA[port] & ~mask;
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTENB[port] = base->INTENB[port] & ~mask;
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @brief Clears multiple pins interrupt flag. Status flags are cleared by
+ *        writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTSTATA[port] = mask;
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTSTATB[port] = mask;
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @ Read port interrupt status.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param index GPIO interrupt number.
+ * @retval masked GPIO status value
+ */
+uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index)
+{
+    uint32_t status = 0U;
+
+    if (kGPIO_InterruptA == index)
+    {
+        status = base->INTSTATA[port];
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        status = base->INTSTATB[port];
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+    return status;
+
+}
+
+/*!
+ * @brief Enables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTENA[port] = base->INTENA[port] | (1U << pin);
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTENB[port] = base->INTENB[port] | (1U << pin);
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @brief Disables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTENA[port] = base->INTENA[port] & ~(1U << pin);
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTENB[port] = base->INTENB[port] & ~(1U << pin);
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+
+/*!
+ * @brief Clears the specific pin interrupt flag. Status flags are cleared by
+ *        writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+    if (kGPIO_InterruptA == index)
+    {
+        base->INTSTATA[port] = 1U << pin;
+    }
+    else if (kGPIO_InterruptB == index)
+    {
+        base->INTSTATB[port] = 1U << pin;
+    }
+    else
+    {
+        /*Should not enter here*/
+    }
+}
+#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_gpio.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_gpio.h
new file mode 100755
index 0000000..71c7091
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_gpio.h
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _LPC_GPIO_H_
+#define _LPC_GPIO_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup lpc_gpio
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief LPC GPIO driver version 2.1.3. */
+#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 4))
+/*@}*/
+
+/*! @brief LPC GPIO direction definition */
+typedef enum _gpio_pin_direction
+{
+    kGPIO_DigitalInput = 0U,  /*!< Set current pin as digital input*/
+    kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
+} gpio_pin_direction_t;
+
+/*!
+ * @brief The GPIO pin configuration structure.
+ *
+ * Every pin can only be configured as either output pin or input pin at a time.
+ * If configured as a input pin, then leave the outputConfig unused.
+ */
+typedef struct _gpio_pin_config
+{
+    gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */
+    /* Output configurations, please ignore if configured as a input one */
+    uint8_t outputLogic; /*!< Set default output logic, no use in input */
+} gpio_pin_config_t;
+
+#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT)
+#define GPIO_PIN_INT_LEVEL 0x00U
+#define GPIO_PIN_INT_EDGE 0x01U
+
+#define PINT_PIN_INT_HIGH_OR_RISE_TRIGGER 0x00U
+#define PINT_PIN_INT_LOW_OR_FALL_TRIGGER 0x01U
+
+/*! @brief GPIO Pin Interrupt enable mode */
+typedef enum _gpio_pin_enable_mode
+{
+    kGPIO_PinIntEnableLevel = GPIO_PIN_INT_LEVEL, /*!< Generate Pin Interrupt on level mode */
+    kGPIO_PinIntEnableEdge = GPIO_PIN_INT_EDGE    /*!< Generate Pin Interrupt on edge mode */
+} gpio_pin_enable_mode_t;
+
+/*! @brief GPIO Pin Interrupt enable polarity */
+typedef enum _gpio_pin_enable_polarity
+{
+    kGPIO_PinIntEnableHighOrRise =
+        PINT_PIN_INT_HIGH_OR_RISE_TRIGGER, /*!< Generate Pin Interrupt on high level or rising edge */
+    kGPIO_PinIntEnableLowOrFall =
+        PINT_PIN_INT_LOW_OR_FALL_TRIGGER /*!< Generate Pin Interrupt on low level or falling edge */
+} gpio_pin_enable_polarity_t;
+
+/*! @brief LPC GPIO interrupt index definition */
+typedef enum _gpio_interrupt_index
+{
+    kGPIO_InterruptA = 0U, /*!< Set current pin as interrupt A*/
+    kGPIO_InterruptB = 1U, /*!< Set current pin as interrupt B*/
+} gpio_interrupt_index_t;
+
+/*! @brief Configures the interrupt generation condition. */
+typedef struct _gpio_interrupt_config
+{
+    uint8_t mode;         /* The trigger mode of GPIO interrupts */
+    uint8_t polarity;     /* The polarity of GPIO interrupts */
+} gpio_interrupt_config_t;
+#endif
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/*! @name GPIO Configuration */
+/*@{*/
+
+/*!
+ * @brief Initializes the GPIO peripheral.
+ *
+ * This function ungates the GPIO clock.
+ *
+ * @param base   GPIO peripheral base pointer.
+ * @param port   GPIO port number.
+ */
+void GPIO_PortInit(GPIO_Type *base, uint32_t port);
+
+/*!
+ * @brief Initializes a GPIO pin used by the board.
+ *
+ * To initialize the GPIO, define a pin configuration, either input or output, in the user file.
+ * Then, call the GPIO_PinInit() function.
+ *
+ * This is an example to define an input pin or output pin configuration:
+ * @code
+ * // Define a digital input pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalInput,
+ *   0,
+ * }
+ * //Define a digital output pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalOutput,
+ *   0,
+ * }
+ * @endcode
+ *
+ * @param base   GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @param pin    GPIO pin number
+ * @param config GPIO pin configuration pointer
+ */
+void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config);
+
+/*@}*/
+
+/*! @name GPIO Output Operations */
+/*@{*/
+
+/*!
+ * @brief Sets the output level of the one GPIO pin to the logic 1 or 0.
+ *
+ * @param base    GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @param pin    GPIO pin number
+ * @param output  GPIO pin output logic level.
+ *        - 0: corresponding pin output low-logic level.
+ *        - 1: corresponding pin output high-logic level.
+ */
+static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output)
+{
+    base->B[port][pin] = output;
+}
+
+/*@}*/
+/*! @name GPIO Input Operations */
+/*@{*/
+
+/*!
+ * @brief Reads the current input value of the GPIO PIN.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @param pin    GPIO pin number
+ * @retval GPIO port input value
+ *        - 0: corresponding pin input low-logic level.
+ *        - 1: corresponding pin input high-logic level.
+ */
+static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t port, uint32_t pin)
+{
+    return (uint32_t)base->B[port][pin];
+}
+
+/*@}*/
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 1.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortSet(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+    base->SET[port] = mask;
+}
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 0.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortClear(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+    base->CLR[port] = mask;
+}
+
+/*!
+ * @brief Reverses current output logic of the multiple GPIO pins.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+    base->NOT[port] = mask;
+}
+
+/*@}*/
+
+/*!
+ * @brief Reads the current input value of the whole GPIO port.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ */
+static inline uint32_t GPIO_PortRead(GPIO_Type *base, uint32_t port)
+{
+    return (uint32_t)base->PIN[port];
+}
+
+/*@}*/
+/*! @name GPIO Mask Operations */
+/*@{*/
+
+/*!
+ * @brief Sets port mask, 0 - enable pin, 1 - disable pin.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortMaskedSet(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+    base->MASK[port] = mask;
+}
+
+/*!
+ * @brief Sets the output level of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be affected.
+ *
+ * @param base    GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @param output  GPIO port output value.
+ */
+static inline void GPIO_PortMaskedWrite(GPIO_Type *base, uint32_t port, uint32_t output)
+{
+    base->MPIN[port] = output;
+}
+
+/*!
+ * @brief Reads the current input value of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be
+ * affected.
+ *
+ * @param base   GPIO peripheral base pointer(Typically GPIO)
+ * @param port   GPIO port number
+ * @retval       masked GPIO port value
+ */
+static inline uint32_t GPIO_PortMaskedRead(GPIO_Type *base, uint32_t port)
+{
+    return (uint32_t)base->MPIN[port];
+}
+
+#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
+/*!
+ * @brief Configures the gpio pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param pin GPIO pin number.
+ * @param config GPIO pin interrupt configuration..
+ */
+void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config);
+
+/*!
+ * @brief Enables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @brief Disables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @brief Clears pin interrupt flag. Status flags are cleared by
+ *        writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port   GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @ Read port interrupt status.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param index GPIO interrupt number.
+ * @retval masked GPIO status value
+ */
+uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index);
+
+/*!
+ * @brief Enables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+/*!
+ * @brief Disables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+/*!
+ * @brief Clears the specific pin interrupt flag. Status flags are cleared by
+ *        writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */
+
+/*@}*/
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*!
+ * @}
+ */
+
+#endif /* _LPC_GPIO_H_*/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_iocon.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_iocon.h
new file mode 100755
index 0000000..1b0c3da
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_iocon.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_IOCON_H_
+#define _FSL_IOCON_H_
+
+#include "fsl_common.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.jn_iocon"
+#endif
+
+/*!
+ * @addtogroup jn_iocon
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief IOCON driver version 2.0.0. */
+#define LPC_IOCON_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
+/*@}*/
+
+/**
+ * @brief Array of IOCON pin definitions passed to IOCON_SetPinMuxing() must be in this format
+ */
+typedef struct _iocon_group
+{
+    uint32_t port : 8;      /* Pin port */
+    uint32_t pin : 8;       /* Pin number */
+    uint32_t modefunc : 16; /* Function and mode */
+} iocon_group_t;
+
+/**
+ * @brief IOCON function and mode selection definitions
+ * @note See the User Manual for specific modes and functions supported by the various pins.
+ */
+#define IOCON_FUNC0 IOCON_PIO_FUNC(0) /*!< Selects pin function 0 */
+#define IOCON_FUNC1 IOCON_PIO_FUNC(1) /*!< Selects pin function 1 */
+#define IOCON_FUNC2 IOCON_PIO_FUNC(2) /*!< Selects pin function 2 */
+#define IOCON_FUNC3 IOCON_PIO_FUNC(3) /*!< Selects pin function 3 */
+#define IOCON_FUNC4 IOCON_PIO_FUNC(4) /*!< Selects pin function 4 */
+#define IOCON_FUNC5 IOCON_PIO_FUNC(5) /*!< Selects pin function 5 */
+#define IOCON_FUNC6 IOCON_PIO_FUNC(6) /*!< Selects pin function 6 */
+#define IOCON_FUNC7 IOCON_PIO_FUNC(7) /*!< Selects pin function 7 */
+
+#define IOCON_MODE_PULLUP IOCON_PIO_MODE(0)   /*!< Selects pull-up function */
+#define IOCON_MODE_REPEATER IOCON_PIO_MODE(1) /*!< Selects pin repeater function */
+#define IOCON_MODE_INACT IOCON_PIO_MODE(2)    /*!< No addition pin function */
+#define IOCON_MODE_PULLDOWN IOCON_PIO_MODE(3) /*!< Selects pull-down function */
+
+#define IOCON_HYS_EN (0x1 << 5)            /*!< Enables hysteresis ??*/
+#define IOCON_GPIO_MODE IOCON_PIO_EGP(1)   /*!< GPIO Mode */
+#define IOCON_I2C_SLEW IOCON_PIO_SLEW0(1)  /*!< I2C Slew Rate Control */
+
+#define IOCON_INV_EN IOCON_PIO_INVERT(1) /*!< Enables invert function on input */
+
+#define IOCON_ANALOG_EN IOCON_PIO_DIGIMODE(0)  /*!< Enables analog function by setting 0 to bit 7 */
+#define IOCON_DIGITAL_EN IOCON_PIO_DIGIMODE(1) /*!< Enables digital function by setting 1 to bit 7(default) */
+
+#define IOCON_STDI2C_EN IOCON_PIO_FILTEROFF(1) /*!< I2C standard mode/fast-mode */
+
+#define IOCON_INPFILT_OFF IOCON_PIO_FILTEROFF(1) /*!< Input filter Off for GPIO pins */
+#define IOCON_INPFILT_ON IOCON_PIO_FILTEROFF(0)  /*!< Input filter On for GPIO pins */
+
+#define IOCON_SLEW1_OFF IOCON_PIO_SLEW1(0) /*!< Driver Slew Rate Control */
+#define IOCON_SLEW1_ON IOCON_PIO_SLEW1(1)  /*!< Driver Slew Rate Control */
+
+#define IOCON_FASTI2C_EN (IOCON_INPFILT_ON | IOCON_SLEW1_ON) /*!< I2C Fast-mode Plus and high-speed slave */
+
+#define IOCON_OPENDRAIN_EN IOCON_PIO_OD(1) /*!< Enables open-drain function */
+
+#define IOCON_S_MODE_0CLK IOCON_PIO_SSEL(0) /*!< Bypass input filter */
+#define IOCON_S_MODE_1CLK IOCON_PIO_SSEL(1) /*!< Input pulses shorter than 1 filter clock are rejected */
+#define IOCON_S_MODE_2CLK IOCON_PIO_SSEL(2) /*!< Input pulses shorter than 2 filter clock2 are rejected */
+#define IOCON_S_MODE_3CLK IOCON_PIO_SSEL(3) /*!< Input pulses shorter than 3 filter clock2 are rejected */
+
+/* Set IO clamping to the DIO : freeze the IO state.
+ * Requires SYSCON->RETENTIONCTRL.IOCLAMPING=1 . Automatically set in powerdown */
+#define IOCON_IO_CLAMPING_NORMAL_MFIO (1 << 11)
+#define IOCON_IO_CLAMPING_COMBO_MFIO_I2C (1 << 12) /* Use this flag for PIO11 and PIO12 only */
+
+#define IOCON_PIO_DBG_FUNC_MASK        (0xF000U)
+#define IOCON_PIO_DBG_FUNC_SHIFT       (12U)
+#define IOCON_PIO_DBG_FUNC(x)          (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DBG_FUNC_SHIFT)) & IOCON_PIO_DBG_FUNC_MASK)
+#define IOCON_PIO_DBG_MODE_MASK        (0x10000U)
+#define IOCON_PIO_DBG_MODE_SHIFT       (16U)
+#define IOCON_PIO_DBG_MODE(x)          (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DBG_MODE_SHIFT)) & IOCON_PIO_DBG_MODE_MASK)
+
+
+#define IOCON_CFG(dbg_func) (IOCON_PIO_FUNC(0) | IOCON_MODE_PULLDOWN |\
+                             IOCON_DIGITAL_EN | IOCON_INPFILT_OFF | \
+                             IOCON_PIO_DBG_FUNC(dbg_func) | IOCON_PIO_DBG_MODE(1))
+
+#define IOCON_PIO_I2C_EGP_SHIFT        (3U)
+#define IOCON_PIO_I2C_EGP_MASK         (1 << IOCON_PIO_I2C_EGP_SHIFT)
+#define IOCON_PIO_I2C_ECS_SHIFT        (4U)
+#define IOCON_PIO_I2C_ECS_MASK         (1 << IOCON_PIO_I2C_ECS_SHIFT)
+#define IOCON_PIO_I2C_EHS_SHIFT        (5U)
+#define IOCON_PIO_I2C_EHS_MASK         (1 << IOCON_PIO_I2C_EHS_SHIFT)
+#define IOCON_PIO_I2C_FSEL_SHIFT       (9U)
+#define IOCON_PIO_I2C_FSEL_MASK        (1 << IOCON_PIO_I2C_FSEL_SHIFT)
+#define IOCON_PIO_I2C_CLAMP_SHIFT      (12U)
+#define IOCON_PIO_I2C_CLAMP_MASK       (1 << IOCON_PIO_I2C_CLAMP_SHIFT)
+#define IOCON_PIO_I2C_DBG_FUNC_SHIFT   (13U)
+#define IOCON_PIO_I2C_DBG_FUNC_MASK    (0xf << IOCON_PIO_I2C_DBG_FUNC_SHIFT)
+#define IOCON_PIO_I2C_DBG_FUNC(x)      (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2C_DBG_FUNC_SHIFT)) & IOCON_PIO_I2C_DBG_FUNC_MASK)
+#define IOCON_PIO_I2C_DBG_MODE_SHIFT   (17U)
+#define IOCON_PIO_I2C_DBG_MODE_MASK    (1 << IOCON_PIO_I2C_DBG_MODE_SHIFT)
+#define IOCON_PIO_I2C_DBG_MODE(x)      (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2C_DBG_MODE_SHIFT)) & IOCON_PIO_I2C_DBG_MODE_MASK)
+
+
+#define IOCON_I2C_CFG(dbg_func) (IOCON_PIO_FUNC(0) |\
+                                 IOCON_PIO_I2C_EGP_MASK |\
+                                 IOCON_PIO_I2C_ECS_MASK |\
+                                 IOCON_DIGITAL_EN |\
+                                 IOCON_INPFILT_OFF |\
+                                 IOCON_PIO_I2C_DBG_FUNC(dbg_func)|\
+                                 IOCON_PIO_I2C_DBG_MODE(1))
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * @brief   Sets I/O Control pin mux
+ * @param   base        : The base of IOCON peripheral on the chip
+ * @param   port        : GPIO port to mux
+ * @param   pin         : GPIO pin to mux
+ * @param   modefunc    : OR'ed values of type IOCON_*
+ * @return  Nothing
+ */
+__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint32_t modefunc)
+{
+    base->PIO[port][pin] = modefunc;
+}
+
+/**
+ * @brief   Set all I/O Control pin muxing
+ * @param   base        : The base of IOCON peripheral on the chip
+ * @param   pinArray    : Pointer to array of pin mux selections
+ * @param   arrayLength : Number of entries in pinArray
+ * @return  Nothing
+ */
+__STATIC_INLINE void IOCON_SetPinMuxing(IOCON_Type *base, const iocon_group_t *pinArray, uint32_t arrayLength)
+{
+    uint32_t i;
+
+    for (i = 0; i < arrayLength; i++)
+    {
+        IOCON_PinMuxSet(base, pinArray[i].port, pinArray[i].pin, pinArray[i].modefunc);
+    }
+}
+
+/**
+ * @brief   Sets I/O Control pin mux pull select
+ * @param   base        : The base of IOCON peripheral on the chip
+ * @param   port        : GPIO port to mux
+ * @param   pin         : GPIO pin to mux
+ * @param   pull_select : OR'ed values of type IOCON_*
+ * @return  Nothing
+ */
+__STATIC_INLINE void IOCON_PullSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint8_t pull_select)
+{
+    uint32_t reg = base->PIO[port][pin];
+    reg &= ~IOCON_PIO_MODE_MASK;
+    reg |= IOCON_PIO_MODE(pull_select);
+    base->PIO[port][pin] = reg;
+}
+
+/**
+ * @brief   Sets I/O Control pin mux pull select
+ * @param   base        : The base of IOCON peripheral on the chip
+ * @param   port        : GPIO port to mux
+ * @param   pin         : GPIO pin to mux
+ * @param   func        : Pinmux function
+ * @return  Nothing
+ */
+__STATIC_INLINE void IOCON_FuncSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint8_t func)
+{
+    uint32_t reg = base->PIO[port][pin];
+    reg &= ~IOCON_PIO_FUNC_MASK;
+    reg |= IOCON_PIO_FUNC(func);
+    base->PIO[port][pin] = reg;
+}
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _FSL_IOCON_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_power.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_power.c
new file mode 100755
index 0000000..5e3d97a
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_power.c
@@ -0,0 +1,929 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "fsl_common.h"
+#include "fsl_power.h"
+#include "fsl_debug_console.h"
+#include "fsl_iocon.h"
+
+#include "rom_mpu.h"
+#include "rom_pmc.h"
+#include "rom_api.h"
+#include "rom_lowpower.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.power_no_lib"
+#endif
+
+#define POWER_LIB_VERSION 6042018
+
+/* Do not disable the DC bus when going to power modes */
+//#define POWER_DCBUS_NOT_DISABLED
+
+//#define DUMP_CONFIG
+//#define TRACE_ERR
+//#define TRACE_VRB
+//#define DISPLAY_ACTIVE_VOLTAGE
+
+/* Force BODMEM enable in power down mode for test : 1uA power consumption increase */
+//#define POWER_FORCE_BODMEM_IN_PD
+
+/* On ES2, use directly the safe voltage in deep sleep provided by Patrick */
+/* on ES2 powerdown1/2/3/4 , only BANK7 is maintained in retention */
+#define POWER_DOWN_WARM_4K
+
+#if defined(DUMP_CONFIG) || defined(TRACE_ERR) || defined(TRACE_VRB)
+#define POWER_CONSOLE_DEINIT
+#endif
+
+/*******************************************************************************
+ * Macros/Constants
+ *******************************************************************************/
+
+#if 1                         /* Cope with LDO CORE @ 1.0v in Active and LDO MEM @ 0.9 in power down */
+#define POWER_BODMEM_TRIG 0x4 /* 0.80V  Considering LDOMEM = 0.9v */
+#define POWER_BODMEM_HYST 0x1 /* 0.050V */
+
+#define POWER_BODCORE_TRIG 0x6 /* 0.90V   Considering LDOCORE = 1.0v */
+#define POWER_BODCORE_HYST 0x1 /* 0.050V */
+#else                          // safest setting for LDO CORE @ 1.1v and LDO MEM @ 1.0v
+#define POWER_BODMEM_TRIG 0x6  /* 0.90V - 0.925V +/- 3%   Considering LDOMEM = 1.9v */
+#define POWER_BODMEM_HYST 0x0  /* 0.025V */
+
+#define POWER_BODCORE_TRIG 0x7 /* 0.95V - 0.975V +/- 3%   Considering LDOCORE = 1.1v */
+#define POWER_BODCORE_HYST 0x0 /* 0.025V */
+#endif
+
+#define BODVBAT_LVL_DEFAULT POWER_BOD_LVL_1_75V
+#define BODVBAT_HYST_DEFAULT POWER_BOD_HYST_100MV
+
+#define POWER_LDO_TRIM_UNDEFINED 0x7F
+
+/* **********************   END OF POWER MODE DEFINITIONS   **************************************************/
+
+#define VOLTAGE(Vpmu, Vpmuboost, Vmem, Vmemboost, Vcore, Vpmuboostenable, Vflashcore)                                  \
+    (((Vpmu << LOWPOWER_VOLTAGE_LDO_PMU_INDEX) & LOWPOWER_VOLTAGE_LDO_PMU_MASK) |                                      \
+     ((Vpmuboost << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX) & LOWPOWER_VOLTAGE_LDO_PMU_BOOST_MASK) |                     \
+     ((Vpmuboostenable << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_INDEX) & LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_MASK) | \
+     ((Vmem << LOWPOWER_VOLTAGE_LDO_MEM_INDEX) & LOWPOWER_VOLTAGE_LDO_MEM_MASK) |                                      \
+     ((Vmemboost << LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX) & LOWPOWER_VOLTAGE_LDO_MEM_BOOST_MASK) |                     \
+     ((Vcore << LOWPOWER_VOLTAGE_LDO_CORE_INDEX) & LOWPOWER_VOLTAGE_LDO_CORE_MASK) |                                   \
+     ((Vflashcore << LOWPOWER_VOLTAGE_LDO_FLASH_CORE_INDEX) & LOWPOWER_VOLTAGE_LDO_FLASH_CORE_MASK))
+
+/*
+ * Recommended Voltage settings from
+ * https://www.collabnet.nxp.com/svn/lprfprojects/JN5189/Documents/17_Architecture/17_n_Digital/Block_Specification/jn5189_settings.xlsx
+ */
+#define VOLTAGE_PMU_DOWN 0x5      /* 0.8V  */
+#define VOLTAGE_PMUBOOST_DOWN 0x3 /* 0.75V */
+
+#define VOLTAGE_MEM_DOWN_0_9V 0x9       /* 0.9V  */
+#define VOLTAGE_MEM_DOWN_1_0V 0xE       /* 1V    */
+#define VOLTAGE_MEMBOOST_DOWN_0_85V 0x7 /* 0.85V */
+#define VOLTAGE_MEMBOOST_DOWN_0_96V 0xA /* 0.96V */
+
+#define VOLTAGE_PMU_DEEP_SLEEP 0xA       /* 0.96V */
+#define VOLTAGE_PMUBOOST_DEEP_SLEEP 0x9  /* 0.9V  */
+#define VOLTAGE_MEM_DEEP_SLEEP 0x18      /* 1.1V  */
+#define VOLTAGE_MEMBOOST_DEEP_SLEEP 0x13 /* 1.05V */
+#define VOLTAGE_CORE_DEEP_SLEEP 0x2      /* 0.95V */
+#define VOLTAGE_FLASH_CORE_DEEP_SLEEP 2  /* 0.95V */
+
+#define VOLTAGE_PMU_DEEP_DOWN 0x5      /* 0.8V  */
+#define VOLTAGE_PMUBOOST_DEEP_DOWN 0x3 /* 0.75V */
+
+#define VOLTAGE_LDO_PMU_BOOST 0
+
+#define POWER_ULPGB_TRIM_FLASH_ADDR (uint32_t *)0x9FCD4
+
+#define POWER_GET_ACTIVE_TRIM_VALUE(__reg) ((int8_t)((__reg & (1 << 4)) ? -(__reg & 0xF) : (__reg & 0xF)))
+#define POWER_GET_PWD_TRIM_VALUE(__reg) \
+    ((int8_t)(((__reg >> 5) & (1 << 4)) ? -((__reg >> 5) & 0xF) : ((__reg >> 5) & 0xF)))
+
+#define POWER_APPLY_ACTIVE_TRIM(__voltage)                                                                          \
+    ((active_trim_val != POWER_LDO_TRIM_UNDEFINED) ? (MIN(0x1E, MAX(((int8_t)__voltage + active_trim_val), 0xA))) : \
+                                                     (__voltage))
+#define POWER_APPLY_PWD_TRIM(__voltage)                                                                         \
+    ((active_trim_val != POWER_LDO_TRIM_UNDEFINED) ? (MIN(0x9, MAX(((int8_t)__voltage + pwd_trim_val), 0x1))) : \
+                                                     (__voltage))
+
+#define POWER_APPLY_TRIM(__voltage) \
+    ((__voltage < 0xA) ? POWER_APPLY_PWD_TRIM(__voltage) : POWER_APPLY_ACTIVE_TRIM(__voltage))
+
+/*******************************************************************************
+ * Types
+ ******************************************************************************/
+static const LPC_LOWPOWER_LDOVOLTAGE_T lowpower_ldovoltage_reset = {
+    .LDOPMU             = 0x18, // 1.1V
+    .LDOPMUBOOST        = 0x13, // 1.05V
+    .LDOMEM             = 0x18, // 1.1V
+    .LDOMEMBOOST        = 0x13, // 1.05V
+    .LDOCORE            = 0x5,  // 1.1V
+    .LDOFLASHNV         = 0x5,  // 1.9V
+    .LDOFLASHCORE       = 0x6,  // 1.15V
+    .LDOADC             = 0x5,  // 1.1V
+    .LDOPMUBOOST_ENABLE = 1,    // Force Boost activation on LDOPMU
+};
+
+static const LPC_LOWPOWER_LDOVOLTAGE_T lowpower_ldovoltage_min = {
+    .LDOPMU             = 0xE, // 1V
+    .LDOPMUBOOST        = 0xA, // 0.96V
+    .LDOMEM             = 0xE, // 1V
+    .LDOMEMBOOST        = 0xA, // 0.96V
+    .LDOCORE            = 0x3, // 1V
+    .LDOFLASHNV         = 0x5, // 1.9V
+    .LDOFLASHCORE       = 0x6, // 1.15V
+    .LDOADC             = 0x5, // 1.1V
+    .LDOPMUBOOST_ENABLE = 1,   // Force Boost activation on LDOPMU
+};
+
+/* trimming value to apply to active/pwd voltage - Initialized from flash in POWER_Init() */
+static int8_t active_trim_val = POWER_LDO_TRIM_UNDEFINED;
+static int8_t pwd_trim_val    = POWER_LDO_TRIM_UNDEFINED;
+
+/*******************************************************************************
+ * Local prototypes
+ ******************************************************************************/
+
+#ifdef DUMP_CONFIG
+static void LF_DumpConfig(LPC_LOWPOWER_T *LV_LowPowerMode);
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static void POWER_FlexcomClocksDisable(void)
+{
+    CLOCK_AttachClk(kNONE_to_USART_CLK);
+    CLOCK_AttachClk(kNONE_to_FRG_CLK);
+    CLOCK_AttachClk(kNONE_to_I2C_CLK);
+    CLOCK_AttachClk(kNONE_to_SPI_CLK);
+
+    CLOCK_DisableClock(kCLOCK_Usart0);
+    CLOCK_DisableClock(kCLOCK_I2c0);
+    CLOCK_DisableClock(kCLOCK_Spi0);
+}
+
+#ifdef FOR_BOD_DEBUG
+/******   BODMEM ********/
+static void POWER_BodMemDisable(void)
+{
+    PMC->PDRUNCFG &= ~PMC_PDRUNCFG_ENA_BOD_MEM_MASK;
+    PMC->BODMEM &= ~PMC_BODMEM_RESETENABLE_MASK;
+}
+
+static void POWER_BodMemSetup(void)
+{
+    // TODO : really needed?
+    POWER_BodMemDisable();
+
+    /* Configure BODMEM so it can be enabled before going to power down */
+    PMC->BODMEM = (PMC->BODMEM & ~(PMC_BODMEM_TRIGLVL_MASK | PMC_BODMEM_HYST_MASK)) |
+                  (PMC_BODMEM_TRIGLVL(POWER_BODMEM_TRIG) | PMC_BODMEM_HYST(POWER_BODMEM_HYST));
+
+    /* Clear BODMEM interrupt */
+    SYSCON->ANACTRL_INTENCLR = SYSCON_ANACTRL_INTENSET_BODMEM_MASK;
+
+    /* Enable the BODMEM */
+    PMC->PDRUNCFG |= PMC_PDRUNCFG_ENA_BOD_MEM_MASK;
+}
+
+static void POWER_BodMemEnableInt(void)
+{
+    /* Warning, we should wait for the LDO to set up (27us) before clearing the status and enabling the interrupts
+     * (RFT1852) However, we expect this function to be called more than 27us after POWER_BodCoreConfigure() so we can
+     * discard the 27us delay here */
+    // CLOCK_uDelay(27);
+
+    /* clear initial status  (RFT1891) and enable interrupt */
+    SYSCON->ANACTRL_STAT     = SYSCON_ANACTRL_STAT_BODMEM_MASK;
+    SYSCON->ANACTRL_INTENSET = SYSCON_ANACTRL_INTENSET_BODMEM_MASK;
+
+    /* BODMEM Reset enable */
+    PMC->BODMEM |= PMC_BODMEM_RESETENABLE_MASK;
+}
+
+/******   BODCORE ********/
+static void POWER_BodCoreDisable(void)
+{
+    PMC->PDRUNCFG &= ~PMC_PDRUNCFG_ENA_BOD_CORE_MASK;
+    PMC->BODCORE &= ~PMC_BODCORE_RESETENABLE_MASK;
+}
+
+static void POWER_BodCoreSetup(void)
+{
+    /* TODO : shall we disable it first? */
+    POWER_BodCoreDisable();
+
+    /* Configure BODMEM so it can be enabled before going to power down */
+    PMC->BODCORE = (PMC->BODCORE & ~(PMC_BODCORE_TRIGLVL_MASK | PMC_BODCORE_HYST_MASK)) |
+                   (PMC_BODCORE_TRIGLVL(POWER_BODCORE_TRIG) | PMC_BODCORE_HYST(POWER_BODCORE_TRIG));
+
+    /* Clear BODCORE interrupt */
+    SYSCON->ANACTRL_INTENCLR = SYSCON_ANACTRL_INTENSET_BODCORE_MASK;
+
+    /* Enable the BODCORE */
+    PMC->PDRUNCFG |= PMC_PDRUNCFG_ENA_BOD_CORE_MASK;
+}
+
+static void POWER_BodCoreEnableInt(void)
+{
+    /* Warning, we should wait for the LDO to set up (27us) before clearing the status and enabling the interrupts
+     * (RFT1852) However, we expect this function to be called more than 27us after POWER_BodCoreConfigure() so we can
+     * discard the 27us delay here */
+    // CLOCK_uDelay(27);
+
+    /* clear initial status  (RFT1891) and enable interrupt */
+    SYSCON->ANACTRL_STAT     = SYSCON_ANACTRL_STAT_BODCORE_MASK;
+    SYSCON->ANACTRL_INTENSET = SYSCON_ANACTRL_INTENSET_BODCORE_MASK;
+
+    /* BOD IC Reset enable */
+    PMC->BODCORE |= PMC_BODCORE_RESETENABLE_MASK;
+}
+#endif
+
+static void POWER_UpdateTrimmingVoltageValue(void)
+{
+    uint32_t ulpbg_trim_flash_val;
+    /* Save a bit of time is the trimming values are already retrieved */
+
+    if ((active_trim_val == POWER_LDO_TRIM_UNDEFINED) || (pwd_trim_val == POWER_LDO_TRIM_UNDEFINED))
+    {
+        /* set the trimming values for active and pwd from N-2 page Flash */
+        ulpbg_trim_flash_val = *POWER_ULPGB_TRIM_FLASH_ADDR;
+        active_trim_val      = POWER_GET_ACTIVE_TRIM_VALUE(ulpbg_trim_flash_val);
+        pwd_trim_val         = POWER_GET_PWD_TRIM_VALUE(ulpbg_trim_flash_val);
+    }
+#ifdef DUMP_CONFIG
+    PRINTF("reg=0x%x active_trim=0x%X pwd_trim=0x%X\r\n", ulpbg_trim_flash_val, active_trim_val, pwd_trim_val);
+#endif
+}
+
+static uint32_t POWER_GetIoClampConfig(void)
+{
+    uint32_t io_clamp = 0;
+
+    for (int i = 0; i < 22; i++)
+    {
+        if ((i == 10) | (i == 11))
+        {
+            io_clamp |= (((IOCON->PIO[0][i] & IOCON_IO_CLAMPING_COMBO_MFIO_I2C) >> 12) << i);
+        }
+        else
+        {
+            io_clamp |= (((IOCON->PIO[0][i] & IOCON_IO_CLAMPING_NORMAL_MFIO) >> 11) << i);
+        }
+    }
+    return io_clamp;
+}
+
+/*!
+ * brief Power Library API to return the library version.
+ *
+ * param none
+ * return version number of the power library
+ */
+uint32_t POWER_GetLibVersion(void)
+{
+    return POWER_LIB_VERSION;
+}
+
+/*!
+ * brief determine cause of reset
+ * return reset_cause
+ */
+reset_cause_t POWER_GetResetCause(void)
+{
+    reset_cause_t reset_cause = RESET_UNDEFINED;
+    uint32_t pmc_reset        = pmc_reset_get_cause();
+
+    if (pmc_reset & PMC_RESETCAUSE_POR_MASK)
+    {
+        reset_cause |= RESET_POR;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_PADRESET_MASK)
+    {
+        reset_cause |= RESET_EXT_PIN;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_BODRESET_MASK)
+    {
+        reset_cause |= RESET_BOR;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_SYSTEMRESET_MASK)
+    {
+        reset_cause |= RESET_SYS_REQ;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_WDTRESET_MASK)
+    {
+        reset_cause |= RESET_WDT;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_WAKEUPIORESET_MASK)
+    {
+        reset_cause |= RESET_WAKE_DEEP_PD;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK)
+    {
+        reset_cause |= RESET_WAKE_PD;
+    }
+
+    if (pmc_reset & PMC_RESETCAUSE_SWRRESET_MASK)
+    {
+        reset_cause |= RESET_SW_REQ;
+    }
+
+    return reset_cause;
+}
+
+/*!
+ * brief Clear cause of reset
+ */
+void POWER_ClearResetCause(void)
+{
+    pmc_reset_clear_cause(0xFFFFFFFF);
+}
+
+void POWER_DisplayActiveVoltage(void)
+{
+    LPC_LOWPOWER_LDOVOLTAGE_T ldo_voltage;
+
+    Chip_LOWPOWER_GetSystemVoltages(&ldo_voltage);
+
+    PRINTF("LDOPMU       : %d\n", (int)(ldo_voltage.LDOPMU & 0x1fUL));
+    PRINTF("LDOPMUBOOST  : %d\n", (int)(ldo_voltage.LDOPMUBOOST & 0x1fUL));
+    PRINTF("LDOMEM       : %d\n", (int)(ldo_voltage.LDOMEM & 0x1fUL));
+    PRINTF("LDOMEMBOOST  : %d\n", (int)(ldo_voltage.LDOMEMBOOST & 0x1fUL));
+    PRINTF("LDOCORE      : %d\n", (int)(ldo_voltage.LDOCORE & 0x07UL));
+    PRINTF("LDOFLASHCORE : %d\n", (int)(ldo_voltage.LDOFLASHCORE & 0x07UL));
+    PRINTF("LDOFLASHNV   : %d\n", (int)(ldo_voltage.LDOFLASHNV & 0x07UL));
+    PRINTF("LDOADC       : %d\n", (int)(ldo_voltage.LDOADC & 0x07UL));
+
+    PRINTF("LDOPMUBOOST_ENABLE : %d\n", ldo_voltage.LDOPMUBOOST_ENABLE);
+
+    PRINTF("\n");
+}
+
+void POWER_ApplyActiveVoltage(const LPC_LOWPOWER_LDOVOLTAGE_T *ldo_voltage)
+{
+    LPC_LOWPOWER_LDOVOLTAGE_T ldo_voltage_l;
+
+    memcpy(&ldo_voltage_l, ldo_voltage, sizeof(LPC_LOWPOWER_LDOVOLTAGE_T));
+
+    /* Apply some trimming on LDOPMU and LDOMEM to avoid extra consumption */
+    ldo_voltage_l.LDOPMU      = POWER_APPLY_TRIM(ldo_voltage->LDOPMU);
+    ldo_voltage_l.LDOPMUBOOST = POWER_APPLY_TRIM(ldo_voltage->LDOPMUBOOST);
+
+    ldo_voltage_l.LDOMEM      = POWER_APPLY_TRIM(ldo_voltage->LDOMEM);
+    ldo_voltage_l.LDOMEMBOOST = POWER_APPLY_TRIM(ldo_voltage->LDOMEMBOOST);
+
+    Chip_LOWPOWER_SetSystemVoltages(&ldo_voltage_l);
+}
+
+void POWER_ApplyLdoActiveVoltage(pm_ldo_volt_t ldoVolt)
+{
+    switch (ldoVolt)
+    {
+        case PM_LDO_VOLT_1_0V:
+            POWER_ApplyActiveVoltage(&lowpower_ldovoltage_min);
+            break;
+
+        case PM_LDO_VOLT_1_1V_DEFAULT:
+        default:
+            POWER_ApplyActiveVoltage(&lowpower_ldovoltage_reset);
+    }
+}
+
+/*!
+ * brief Initialize the sdk power drivers
+ *
+ * Optimize the LDO voltage for power saving
+ * Initialize the power domains
+ * Activate the BOD
+ *
+ * return none
+ */
+void POWER_Init(void)
+{
+    static bool warm_start = false;
+#ifdef FOR_BOD_DEBUG
+    /* Enable the clock for the analog interrupt control module - required for the BOD
+     * and set up BOD core and mem*/
+    POWER_BodSetUp();
+#endif
+    if (warm_start == false)
+    {
+        POWER_SetTrimDefaultActiveVoltage();
+
+        warm_start = true;
+    }
+
+#ifdef DISPLAY_ACTIVE_VOLTAGE
+    POWER_DisplayActiveVoltage();
+#endif
+
+    /* This time, need to wait for LDO to be set up (27us) */
+    CLOCK_uDelay(27);
+#ifdef FOR_BOD_DEBUG
+    /* enable interrupt and SW reset for the BODCORE */
+    POWER_BodActivate();
+#endif
+}
+
+void POWER_SetTrimDefaultActiveVoltage(void)
+{
+    POWER_UpdateTrimmingVoltageValue();
+
+    /* Always startup at 1.1V to cope with higher current load when enabling clocks */
+    POWER_ApplyLdoActiveVoltage(PM_LDO_VOLT_1_1V_DEFAULT);
+
+#ifdef DISPLAY_ACTIVE_VOLTAGE
+    POWER_DisplayActiveVoltage();
+#endif
+}
+
+#ifdef FOR_BOD_DEBUG
+void POWER_BodSetUp(void)
+{
+    /* Enable the clock for the analog interrupt control module - required for the BOD */
+    CLOCK_EnableClock(kCLOCK_AnaInt);
+
+    POWER_BodCoreSetup();
+    POWER_BodMemSetup();
+}
+
+void POWER_BodActivate(void)
+{
+    /* enable interrupt and SW reset for the BODCORE */
+    POWER_BodCoreEnableInt();
+
+    CLOCK_DisableClock(kCLOCK_AnaInt);
+}
+#endif
+
+/*!
+ * brief Get default Vbat BOD config parameters, level 1.75V, Hysteresis  100mV
+ *
+ * param bod_cfg_p
+ * return none
+ */
+void POWER_BodVbatGetDefaultConfig(pm_bod_cfg_t *bod_cfg_p)
+{
+    bod_cfg_p->bod_level = BODVBAT_LVL_DEFAULT;
+    bod_cfg_p->bod_hyst  = BODVBAT_HYST_DEFAULT;
+    bod_cfg_p->bod_cfg   = POWER_BOD_ENABLE | POWER_BOD_INT_ENABLE;
+}
+
+/*!
+ * brief Configure the VBAT BOD
+ *
+ * param bod_cfg_p
+ * return false if configuration parameters are incorrect
+ */
+bool POWER_BodVbatConfig(pm_bod_cfg_t *bod_cfg_p)
+{
+    uint32_t comparator_interrupt;
+
+    if (bod_cfg_p->bod_cfg & POWER_BOD_ENABLE)
+    {
+        if ((bod_cfg_p->bod_level >= POWER_BOD_LVL_1_75V) && (bod_cfg_p->bod_level <= POWER_BOD_LVL_3_3V) &&
+            (bod_cfg_p->bod_hyst <= POWER_BOD_HYST_100MV))
+        {
+            uint32_t bodvbat = PMC->BODVBAT;
+            bodvbat &= ~(PMC_BODVBAT_TRIGLVL_MASK | PMC_BODVBAT_HYST_MASK);
+            bodvbat |= PMC_BODVBAT_TRIGLVL(bod_cfg_p->bod_level);
+            bodvbat |= PMC_BODVBAT_HYST(bod_cfg_p->bod_hyst);
+            PMC->BODVBAT = bodvbat;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /* enable the clock for the analog interrupt control module */
+    CLOCK_EnableClock(kCLOCK_AnaInt);
+
+    if (bod_cfg_p->bod_cfg & POWER_BOD_HIGH)
+    {
+        /* Disable Interrupt on BODVBAT High */
+        SYSCON->ANACTRL_INTENCLR = SYSCON_ANACTRL_INTENCLR_BODVBATHIGH_MASK;
+
+        /* clear initial status of interrupt */
+        SYSCON->ANACTRL_STAT = SYSCON_ANACTRL_STAT_BODVBATHIGH_MASK;
+
+        /* enable comparator interrupt       */
+        comparator_interrupt = SYSCON_ANACTRL_INTENSET_BODVBATHIGH_MASK;
+    }
+    else
+    {
+        /*  BOD IC Interrupt enable */
+        SYSCON->ANACTRL_INTENCLR = SYSCON_ANACTRL_INTENCLR_BODVBAT_MASK;
+
+        /* clear initial status of interrupt */
+        SYSCON->ANACTRL_STAT = SYSCON_ANACTRL_STAT_BODVBAT_MASK;
+
+        /* enable comparator interrupt      */
+        comparator_interrupt = SYSCON_ANACTRL_INTENSET_BODVBAT_MASK;
+    }
+
+    if (bod_cfg_p->bod_cfg & POWER_BOD_ENABLE)
+    {
+        if (bod_cfg_p->bod_cfg & POWER_BOD_INT_ENABLE)
+        {
+            SYSCON->ANACTRL_INTENSET = comparator_interrupt;
+            NVIC_EnableIRQ(WDT_BOD_IRQn);
+        }
+        else
+        {
+            NVIC_DisableIRQ(WDT_BOD_IRQn);
+        }
+#ifdef FOR_BOD_DEBUG
+        if (bod_cfg_p->bod_cfg & POWER_BOD_RST_ENABLE)
+        {
+            PMC->BODVBAT |= PMC_BODVBAT_RESETENABLE_MASK;
+        }
+        else
+        {
+            PMC->BODVBAT &= ~PMC_BODVBAT_RESETENABLE_MASK;
+        }
+#endif
+    }
+
+    CLOCK_DisableClock(kCLOCK_AnaInt);
+    // PRINTF( "BODVBAT=0x%X ANACTRL_CTRL=0x%X _STAT=0x%X _VAL=0x%X _INTENSET=0x%X\n", PMC->BODVBAT,
+    // SYSCON->ANACTRL_CTRL, SYSCON->ANACTRL_STAT, SYSCON->ANACTRL_VAL, SYSCON->ANACTRL_INTENSET);
+
+    return true;
+}
+
+bool POWER_EnterDeepSleepMode(pm_power_config_t *pm_power_config)
+{
+    /* [RFT1911] Disable the DC bus to prevent extra consumption */
+#ifndef POWER_DCBUS_NOT_DISABLED
+    ASYNC_SYSCON->DCBUSCTRL =
+        (ASYNC_SYSCON->DCBUSCTRL & ~ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK) | (1 << ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT);
+#endif
+
+    /* [artf555998] Enable new ES2 feature for fast wakeup */
+    PMC->CTRLNORST = PMC_CTRLNORST_FASTLDOENABLE_MASK;
+
+    return false;
+}
+
+bool POWER_EnterPowerDownMode(pm_power_config_t *pm_power_config)
+{
+    int radio_retention;
+    int autostart_32mhz_xtal;
+    int keep_ao_voltage;
+    int sram_cfg;
+    int wakeup_src0;
+    int wakeup_src1;
+    uint8_t voltage_mem_down;
+    uint8_t voltage_membootst_down;
+    LPC_LOWPOWER_T lp_config;
+    memset(&lp_config, 0, sizeof(lp_config));
+
+    sram_cfg             = pm_power_config->pm_config & PM_CFG_SRAM_ALL_RETENTION;
+    radio_retention      = pm_power_config->pm_config & PM_CFG_RADIO_RET;
+    autostart_32mhz_xtal = pm_power_config->pm_config & PM_CFG_XTAL32M_AUTOSTART;
+    keep_ao_voltage      = pm_power_config->pm_config & PM_CFG_KEEP_AO_VOLTAGE;
+
+    wakeup_src0 = (int)pm_power_config->pm_wakeup_src & 0xFFFFFFFF;
+    wakeup_src1 = (int)(pm_power_config->pm_wakeup_src >> 32) & 0xFFFFFFFF;
+#ifdef TRACE_VRB
+    PRINTF("POWER_EnterPowerDownMode:\n");
+    PRINTF("  wakeup_src0      : 0x%x\n", wakeup_src0);
+    PRINTF("  wakeup_src1      : 0x%x\n", wakeup_src1);
+    PRINTF("  wakeup_io        : 0x%x\n", pm_power_config->pm_wakeup_io);
+    PRINTF("  pm_config        : 0x%x\n", pm_power_config->pm_config);
+#endif
+
+    lp_config.CFG = LOWPOWER_CFG_MODE_POWERDOWN;
+
+    /* PDRUNCFG : on ES2, flag discard to keep the same configuration than active */
+    lp_config.CFG |= LOWPOWER_CFG_PDRUNCFG_DISCARD_MASK;
+
+    /* PDSLEEPCFG (note: LDOMEM will be enabled by lowpower API if one memory bank in retention*/
+    lp_config.PMUPWDN |= LOWPOWER_PMUPWDN_DCDC | LOWPOWER_PMUPWDN_BIAS | LOWPOWER_PMUPWDN_BODVBAT;
+
+    /* Disable All banks except those given in sram_cfg */
+    lp_config.DIGPWDN |= ((LOWPOWER_DIGPWDN_SRAM_ALL_MASK) & ~(sram_cfg << LOWPOWER_DIGPWDN_SRAM0_INDEX));
+
+    // TODO : if COMM0 is disabled, need to switch off the clocks also for safe wake up
+    lp_config.DIGPWDN |= LOWPOWER_DIGPWDN_COMM0; // PDSLEEP DISABLE COM0
+
+    lp_config.DIGPWDN |=
+        LOWPOWER_DIGPWDN_MCU_RET; // PDSLEEP DISABLE retention  : on ES1, CPU retention, on ES2 Zigbee retention
+
+    // lp_config.DIGPWDN |= LOWPOWER_DIGPWDN_NTAG_FD;         // DPDWKSRC DISABLE NTAG  - not used in lowpower API in
+    // power down
+
+    lp_config.SLEEPPOSTPONE = 0;
+    lp_config.GPIOLATCH     = 0;
+
+#if gPWR_LDOMEM_0_9V_PD /* Warning : do not apply this flag , for experimental use only */
+    voltage_mem_down       = VOLTAGE_MEM_DOWN_0_9V;
+    voltage_membootst_down = VOLTAGE_MEMBOOST_DOWN_0_85V;
+#else
+    /* A bit in the flash is now set (bit 31 at address 0x9FCD4).
+     * If this bit is set, RAM retention in sleep should use voltage of 0.9v.
+     * If it is not set, RAM retention in sleep should use voltage of 1.0v. */
+    uint32_t *ate_setting = (uint32_t *)0x9FCD4;
+
+    if ((*ate_setting & 0x80000000) == 0x80000000)
+    {
+        voltage_mem_down       = VOLTAGE_MEM_DOWN_0_9V;
+        voltage_membootst_down = VOLTAGE_MEMBOOST_DOWN_0_85V;
+    }
+    else
+    {
+        voltage_mem_down       = VOLTAGE_MEM_DOWN_1_0V;
+        voltage_membootst_down = VOLTAGE_MEMBOOST_DOWN_0_96V;
+    }
+#endif
+
+    if (keep_ao_voltage)
+    {
+        LPC_LOWPOWER_LDOVOLTAGE_T ldo_voltage;
+
+        Chip_LOWPOWER_GetSystemVoltages(&ldo_voltage);
+
+        /* keep the same voltage than in active for the Always ON powerdomain */
+        lp_config.VOLTAGE = VOLTAGE(POWER_APPLY_TRIM(ldo_voltage.LDOPMU), POWER_APPLY_TRIM(ldo_voltage.LDOPMUBOOST),
+                                    POWER_APPLY_TRIM(voltage_mem_down), POWER_APPLY_TRIM(voltage_membootst_down), 0,
+                                    VOLTAGE_LDO_PMU_BOOST, 0);
+    }
+    else
+    {
+        lp_config.VOLTAGE = VOLTAGE(POWER_APPLY_TRIM(VOLTAGE_PMU_DOWN), POWER_APPLY_TRIM(VOLTAGE_PMUBOOST_DOWN),
+                                    POWER_APPLY_TRIM(voltage_mem_down), POWER_APPLY_TRIM(voltage_membootst_down), 0,
+                                    VOLTAGE_LDO_PMU_BOOST, 0);
+    }
+
+    lp_config.WAKEUPSRCINT0 = wakeup_src0;
+    lp_config.WAKEUPSRCINT1 = wakeup_src1;
+
+    /* Variation from reference */
+    if (radio_retention)
+    {
+        /* Enable Zigbee retention */
+        lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_MCU_RET;
+    }
+
+    /* Configure IO wakeup source */
+    if (lp_config.WAKEUPSRCINT1 & LOWPOWER_WAKEUPSRCINT1_IO_IRQ)
+    {
+        lp_config.WAKEUPIOSRC = pm_power_config->pm_wakeup_io;
+    }
+
+    if (lp_config.WAKEUPSRCINT0 & LOWPOWER_WAKEUPSRCINT0_SYSTEM_IRQ)
+    {
+        /* Need to enable the BIAS for VBAT BOD */
+        lp_config.PMUPWDN &= ~(LOWPOWER_PMUPWDN_BIAS | LOWPOWER_PMUPWDN_BODVBAT);
+    }
+
+    if (lp_config.WAKEUPSRCINT0 &
+        (LOWPOWER_WAKEUPSRCINT0_USART0_IRQ | LOWPOWER_WAKEUPSRCINT0_I2C0_IRQ | LOWPOWER_WAKEUPSRCINT0_SPI0_IRQ))
+    {
+        /* Keep Flexcom0 in power down mode */
+        lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_COMM0;
+    }
+
+    /* On ES2 , Analog comparator is already enabled in PDRUNCFG + RFT1877 : No need to keep the bias */
+    if (sram_cfg)
+    {
+        /* Configure the SRAM to SMB1 (low leakage biasing) */
+        SYSCON->SRAMCTRL =
+            (SYSCON->SRAMCTRL & (~SYSCON_SRAMCTRL_SMB_MASK)) | (SYSCON_SRAMCTRL_SMB(1) << SYSCON_SRAMCTRL_SMB_SHIFT);
+
+        /*
+         * BODMEM requires the bandgap enable in power down, this induces a power consumption increase of 1uA
+         * so Enable BODMEM only if bandgap is already enabled for BODVBAT (see code above)
+         */
+#ifndef POWER_FORCE_BODMEM_IN_PD
+        if ((lp_config.PMUPWDN & LOWPOWER_PMUPWDN_BIAS) == 0)
+#endif
+        {
+#ifdef FOR_BOD_DEBUG
+            CLOCK_EnableClock(kCLOCK_AnaInt);
+
+            /* Note: BODMEM should be already enabled in the POWER_Init() function but do it again if not */
+            if (!(PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_BOD_MEM_MASK))
+            {
+                POWER_BodMemSetup();
+                /* This time, need to wait for LDO to be set up (27us) */
+                CLOCK_uDelay(27);
+            }
+            POWER_BodMemEnableInt();
+#endif
+        }
+#ifndef POWER_FORCE_BODMEM_IN_PD
+        else
+        {
+#ifdef FOR_BOD_DEBUG
+            /* Disable the BODMEM otherwise */
+            POWER_BodMemDisable();
+#endif
+        }
+#endif
+    }
+    else
+    {
+#ifdef FOR_BOD_DEBUG
+        /* Disable the BODMEM otherwise */
+        POWER_BodMemDisable();
+#endif
+    }
+#ifdef FOR_BOD_DEBUG
+    /* Disable BodCore , no longer used in power down */
+    POWER_BodCoreDisable();
+#endif
+    if (wakeup_src0 & LOWPOWER_WAKEUPSRCINT0_NFCTAG_IRQ)
+    {
+        lp_config.WAKEUPSRCINT1 |= LOWPOWER_WAKEUPSRCINT1_IO_IRQ;
+        lp_config.WAKEUPIOSRC |= LOWPOWER_WAKEUPIOSRC_NTAG_FD;
+    }
+
+    /* On Power down, NTAG field detect is enabled by IO so don t need to set the LOWPOWER_DIGPWDN_NTAG_FD */
+    // lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_NTAG_FD;      // used for deep down only
+
+    if (autostart_32mhz_xtal)
+    {
+        lp_config.CFG |= LOWPOWER_CFG_XTAL32MSTARTENA_MASK;
+    }
+
+    /* get IO clamping state already set by the application and give it to lowpower API
+     * Lowpower API overrides the IO configuration with GPIOLATCH setting
+     */
+    lp_config.GPIOLATCH = POWER_GetIoClampConfig();
+
+    /* [RFT1911] Disable the DC bus to prevent extra consumption */
+#ifndef POWER_DCBUS_NOT_DISABLED
+    ASYNC_SYSCON->DCBUSCTRL =
+        (ASYNC_SYSCON->DCBUSCTRL & ~ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK) | (1 << ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT);
+#endif
+
+    /* [artf555998] Enable new ES2 feature for fast wakeup */
+    PMC->CTRLNORST = PMC_CTRLNORST_FASTLDOENABLE_MASK;
+
+#ifdef DUMP_CONFIG
+    LF_DumpConfig(&lp_config);
+#endif
+
+    /* If flexcom is maintained, do not disable the console and the clocks - let the application do it if needed */
+    if (lp_config.DIGPWDN & LOWPOWER_DIGPWDN_COMM0)
+    {
+        /* remove console if not done */
+        DbgConsole_Deinit();
+
+        /* Disable clocks to FLEXCOM power domain. This power domain is not reseted on wakeup by HW */
+        POWER_FlexcomClocksDisable();
+    }
+    /* Apply default LDO voltage */
+    POWER_ApplyLdoActiveVoltage(PM_LDO_VOLT_1_1V_DEFAULT);
+
+    Chip_LOWPOWER_SetLowPowerMode(&lp_config);
+
+    /* If we go here, the power mode has been aborted - this can happen only if WFI is executed in lowpower API*/
+    return false;
+}
+
+bool POWER_EnterDeepDownMode(pm_power_config_t *pm_power_config)
+{
+    int autostart_32mhz_xtal;
+    int wakeup_src0;
+    int wakeup_src1;
+    LPC_LOWPOWER_T lp_config;
+
+    memset(&lp_config, 0, sizeof(lp_config));
+
+    autostart_32mhz_xtal = pm_power_config->pm_config & PM_CFG_XTAL32M_AUTOSTART;
+
+    wakeup_src0 = (int)pm_power_config->pm_wakeup_src & 0xFFFFFFFF;
+    wakeup_src1 = (int)(pm_power_config->pm_wakeup_src >> 32) & 0xFFFFFFFF;
+
+#ifdef TRACE_VRB
+    PRINTF("POWER_EnterDeepDownMode:\n");
+    PRINTF("  wakeup_src0      : 0x%x\n", wakeup_src0);
+    PRINTF("  wakeup_src1      : 0x%x\n", wakeup_src1);
+#else
+    (void)wakeup_src0;
+#endif
+
+    lp_config.CFG = LOWPOWER_CFG_MODE_DEEPPOWERDOWN;
+
+    lp_config.PMUPWDN = LOWPOWER_PMUPWDN_DCDC | LOWPOWER_PMUPWDN_BIAS | LOWPOWER_PMUPWDN_BODVBAT |
+                        LOWPOWER_PMUPWDN_FRO192M | LOWPOWER_PMUPWDN_FRO1M;
+
+    lp_config.DIGPWDN = LOWPOWER_DIGPWDN_IO;
+
+    if (wakeup_src1 & LOWPOWER_WAKEUPSRCINT1_IO_IRQ)
+    {
+        lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_IO;
+        lp_config.WAKEUPIOSRC = pm_power_config->pm_wakeup_io;
+    }
+
+    if (wakeup_src0 & LOWPOWER_WAKEUPSRCINT0_NFCTAG_IRQ)
+    {
+        lp_config.DIGPWDN &= ~LOWPOWER_DIGPWDN_NTAG_FD;
+    }
+    else
+    {
+        lp_config.DIGPWDN |= LOWPOWER_DIGPWDN_NTAG_FD;
+    }
+
+    lp_config.VOLTAGE = VOLTAGE(POWER_APPLY_TRIM(VOLTAGE_PMU_DEEP_DOWN), POWER_APPLY_TRIM(VOLTAGE_PMUBOOST_DEEP_DOWN),
+                                0, 0, 0, VOLTAGE_LDO_PMU_BOOST, 0);
+
+    if (autostart_32mhz_xtal)
+    {
+        lp_config.CFG |= LOWPOWER_CFG_XTAL32MSTARTENA_MASK;
+    }
+
+    /* [RFT1911] Disable the DC bus to prevent extra consumption */
+#ifndef POWER_DCBUS_NOT_DISABLED
+    ASYNC_SYSCON->DCBUSCTRL =
+        (ASYNC_SYSCON->DCBUSCTRL & ~ASYNC_SYSCON_DCBUSCTRL_ADDR_MASK) | (1 << ASYNC_SYSCON_DCBUSCTRL_ADDR_SHIFT);
+#endif
+
+    /* [artf555998] Enable new ES2 feature for fast wakeup */
+    PMC->CTRLNORST = PMC_CTRLNORST_FASTLDOENABLE_MASK;
+
+#ifdef DUMP_CONFIG
+    LF_DumpConfig(&lp_config);
+#endif
+
+    /* remove console if not done */
+    DbgConsole_Deinit();
+
+    /* Disable clocks to FLEXCOM power domain. This power domain is not reseted on wakeup by HW */
+    POWER_FlexcomClocksDisable();
+
+    Chip_LOWPOWER_SetLowPowerMode(&lp_config);
+
+    /* If we go here, the power mode has been aborted - this can happen only if WFI is executed in lowpower API*/
+    return false;
+}
+
+/*!
+ * brief Power Library API to enter different power mode.
+ *
+ * If requested mode is PM_POWER_DOWN, the API will perform the clamping of the DIOs
+ * if the PIO register has the bit IO_CLAMPING set: SYSCON->RETENTIONCTRL.IOCLAMP
+ * will be set
+ *
+ * return false if chip could not go to sleep. Configuration structure is incorrect
+ */
+bool POWER_EnterPowerMode(pm_power_mode_t pm_power_mode, pm_power_config_t *pm_power_config)
+{
+    bool ret;
+    switch (pm_power_mode)
+    {
+            /*  case PM_DEEP_SLEEP:
+                    ret = POWER_EnterDeepSleepMode(pm_power_config);
+                    break; */
+        case PM_POWER_DOWN:
+            ret = POWER_EnterPowerDownMode(pm_power_config);
+            break;
+        case PM_DEEP_DOWN:
+            ret = POWER_EnterDeepDownMode(pm_power_config);
+            break;
+        default:
+            ret = false;
+    }
+
+    return ret;
+}
+
+#ifdef DUMP_CONFIG
+static void LF_DumpConfig(LPC_LOWPOWER_T *LV_LowPowerMode)
+{
+    PRINTF("Powerdown configuration\n");
+    PRINTF("CFG:             0x%x\n", LV_LowPowerMode->CFG);
+    PRINTF("PMUPWDN:         0x%x\n", LV_LowPowerMode->PMUPWDN);
+    PRINTF("DIGPWDN:         0x%x\n", LV_LowPowerMode->DIGPWDN);
+    PRINTF("VOLTAGE:         0x%x\n", LV_LowPowerMode->VOLTAGE);
+    PRINTF("WAKEUPSRCINT0:   0x%x\n", LV_LowPowerMode->WAKEUPSRCINT0);
+    PRINTF("WAKEUPSRCINT1:   0x%x\n", LV_LowPowerMode->WAKEUPSRCINT1);
+    PRINTF("SLEEPPOSTPONE:   0x%x\n", LV_LowPowerMode->SLEEPPOSTPONE);
+    PRINTF("WAKEUPIOSRC      0x%x\n", LV_LowPowerMode->WAKEUPIOSRC);
+    PRINTF("GPIOLATCH        0x%x\n", LV_LowPowerMode->GPIOLATCH);
+    PRINTF("TIMERCFG         0x%x\n", LV_LowPowerMode->TIMERCFG);
+    PRINTF("TIMERBLECFG      0x%x\n", LV_LowPowerMode->TIMERBLECFG);
+    PRINTF("TIMERCOUNTLSB    0x%x\n", LV_LowPowerMode->TIMERCOUNTLSB);
+    PRINTF("TIMERCOUNTMSB    0x%x\n", LV_LowPowerMode->TIMERCOUNTMSB);
+    PRINTF("TIMER2NDCOUNTLSB 0x%x\n", LV_LowPowerMode->TIMER2NDCOUNTLSB);
+    PRINTF("TIMER2NDCOUNTMSB 0x%x\n", LV_LowPowerMode->TIMER2NDCOUNTMSB);
+}
+
+#endif
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_power.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_power.h
new file mode 100755
index 0000000..5b44bb1
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_power.h
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_POWER_H_
+#define _FSL_POWER_H_
+
+#include "rom_lowpower.h"
+#include "fsl_common.h"
+
+/*! @addtogroup power */
+/*! @{ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief BODVBAT configuration flag */
+#define POWER_BOD_ENABLE           ( 1 << 0 )
+#define POWER_BOD_DISABLE          ( 0 << 0 )
+#define POWER_BOD_INT_ENABLE       ( 1 << 1 )
+#define POWER_BOD_RST_ENABLE       ( 1 << 2 )
+#define POWER_BOD_HIGH             ( 1 << 3 ) /*!< ES2 BOD VBAT only */
+#define POWER_BOD_LOW              ( 0 << 3 )
+
+/*! @brief BOD trigger level setting */
+#define POWER_BOD_LVL_1_75V        9        /*!< Default at Reset , 1.7V on ES1 */
+#define POWER_BOD_LVL_1_8V         10       /*!< BOD trigger level 1.8V */
+#define POWER_BOD_LVL_1_9V         11       /*!< BOD trigger level 1.9V */
+#define POWER_BOD_LVL_2_0V         12       /*!< BOD trigger level 2.0V */
+#define POWER_BOD_LVL_2_1V         13       /*!< BOD trigger level 2.1V */
+#define POWER_BOD_LVL_2_2V         14       /*!< BOD trigger level 2.2V */
+#define POWER_BOD_LVL_2_3V         15       /*!< BOD trigger level 2.3V */
+#define POWER_BOD_LVL_2_4V         16       /*!< BOD trigger level 2.4V */
+#define POWER_BOD_LVL_2_5V         17       /*!< BOD trigger level 2.5V */
+#define POWER_BOD_LVL_2_6V         18       /*!< BOD trigger level 2.6V */
+#define POWER_BOD_LVL_2_7V         19       /*!< BOD trigger level 2.7V */
+#define POWER_BOD_LVL_2_8V         20       /*!< BOD trigger level 2.8V */
+#define POWER_BOD_LVL_2_9V         21       /*!< BOD trigger level 2.9V */
+#define POWER_BOD_LVL_3_0V         22       /*!< BOD trigger level 3.0V */
+#define POWER_BOD_LVL_3_1V         23       /*!< BOD trigger level 3.1V */
+#define POWER_BOD_LVL_3_2V         24       /*!< BOD trigger level 3.2V */
+#define POWER_BOD_LVL_3_3V         25       /*!< BOD trigger level 3.3V */
+
+/*! @brief BOD Hysteresis control setting */
+#define POWER_BOD_HYST_25MV        0        /*!< BOD Hysteresis control 25mV */
+#define POWER_BOD_HYST_50MV        1        /*!< BOD Hysteresis control 50mV */
+#define POWER_BOD_HYST_75MV        2        /*!< BOD Hysteresis control 75mV */
+#define POWER_BOD_HYST_100MV       3        /*!< BOD Hysteresis control 100mV, default at Reset */
+
+/**
+ * @brief  SRAM banks definition list for retention in power down modes !
+ */
+#define        PM_CFG_SRAM_BANK_BIT_BASE   0
+#define        PM_CFG_SRAM_BANK0_RET       (1<<0)   /*!< On ES1, this bank shall be kept in retention for Warmstart from power down */
+#define        PM_CFG_SRAM_BANK1_RET       (1<<1)   /*!< Bank 1 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK2_RET       (1<<2)   /*!< Bank 2 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK3_RET       (1<<3)   /*!< Bank 3 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK4_RET       (1<<4)   /*!< Bank 4 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK5_RET       (1<<5)   /*!< Bank 5 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK6_RET       (1<<6)   /*!< Bank 6 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK7_RET       (1<<7)   /*!< On ES2, this bank shall be kept in retention for Warmstart */
+#define        PM_CFG_SRAM_BANK8_RET       (1<<8)   /*!< Bank 8 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK9_RET       (1<<9)   /*!< Bank 9 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK10_RET      (1<<10)  /*!< Bank 10 shall be kept in retention */
+#define        PM_CFG_SRAM_BANK11_RET      (1<<11)  /*!< Bank 11 shall be kept in retention */
+
+#define        PM_CFG_SRAM_ALL_RETENTION   0xFFF    /*!< All banks shall be kept in retention */
+
+#define        PM_CFG_RADIO_RET            (1<<13)
+#define        PM_CFG_XTAL32M_AUTOSTART    (1<<14)
+#define        PM_CFG_KEEP_AO_VOLTAGE      (1<<15)  /*!< keep the same voltage on the Always-on power domain - typical used with FRO32K to avoid timebase drift */
+
+#define POWER_WAKEUPSRC_SYSTEM         LOWPOWER_WAKEUPSRCINT0_SYSTEM_IRQ         /*!< BOD, Watchdog Timer, Flash controller, [DEEP SLEEP] BODVBAT [POWER_DOWN]*/
+#define POWER_WAKEUPSRC_DMA            LOWPOWER_WAKEUPSRCINT0_DMA_IRQ            /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_GINT           LOWPOWER_WAKEUPSRCINT0_GINT_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_IRBLASTER      LOWPOWER_WAKEUPSRCINT0_IRBLASTER_IRQ      /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PINT0          LOWPOWER_WAKEUPSRCINT0_PINT0_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PINT1          LOWPOWER_WAKEUPSRCINT0_PINT1_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PINT2          LOWPOWER_WAKEUPSRCINT0_PINT2_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PINT3          LOWPOWER_WAKEUPSRCINT0_PINT3_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_SPIFI          LOWPOWER_WAKEUPSRCINT0_SPIFI_IRQ          /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_TIMER0         LOWPOWER_WAKEUPSRCINT0_TIMER0_IRQ         /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_TIMER1         LOWPOWER_WAKEUPSRCINT0_TIMER1_IRQ         /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_USART0         LOWPOWER_WAKEUPSRCINT0_USART0_IRQ         /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_USART1         LOWPOWER_WAKEUPSRCINT0_USART1_IRQ         /*!< [DEEP SLEEP]  */
+#define POWER_WAKEUPSRC_I2C0           LOWPOWER_WAKEUPSRCINT0_I2C0_IRQ           /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_I2C1           LOWPOWER_WAKEUPSRCINT0_I2C1_IRQ           /*!< [DEEP SLEEP]  */
+#define POWER_WAKEUPSRC_SPI0           LOWPOWER_WAKEUPSRCINT0_SPI0_IRQ           /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_SPI1           LOWPOWER_WAKEUPSRCINT0_SPI1_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM0           LOWPOWER_WAKEUPSRCINT0_PWM0_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM1           LOWPOWER_WAKEUPSRCINT0_PWM1_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM2           LOWPOWER_WAKEUPSRCINT0_PWM2_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM3           LOWPOWER_WAKEUPSRCINT0_PWM3_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM4           LOWPOWER_WAKEUPSRCINT0_PWM4_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM5           LOWPOWER_WAKEUPSRCINT0_PWM5_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM6           LOWPOWER_WAKEUPSRCINT0_PWM6_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM7           LOWPOWER_WAKEUPSRCINT0_PWM7_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM8           LOWPOWER_WAKEUPSRCINT0_PWM8_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM9           LOWPOWER_WAKEUPSRCINT0_PWM9_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_PWM10          LOWPOWER_WAKEUPSRCINT0_PWM10_IR           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_I2C2           LOWPOWER_WAKEUPSRCINT0_I2C2_IRQ           /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_RTC            LOWPOWER_WAKEUPSRCINT0_RTC_IRQ            /*!< [DEEP SLEEP, POWER DOWN]  */
+#define POWER_WAKEUPSRC_NFCTAG         LOWPOWER_WAKEUPSRCINT0_NFCTAG_IRQ         /*!< [DEEP SLEEP, POWER DOWN (ES2 Only), DEEP DOWN (ES2 only)]  */
+#define POWER_WAKEUPSRC_MAILBOX        LOWPOWER_WAKEUPSRCINT0_MAILBOX_IRQ        /*!< Mailbox, Wake-up from DEEP SLEEP and POWER DOWN low power mode [DEEP SLEEP, POWER DOWN] */
+
+#define POWER_WAKEUPSRC_ADC_SEQA       ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ADC_SEQA_IRQ       << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ADC_SEQB       ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ADC_SEQB_IRQ       << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ADC_THCMP_OVR  ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ADC_THCMP_OVR_IRQ  << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_DMIC           ((uint64_t)LOWPOWER_WAKEUPSRCINT1_DMIC_IRQ           << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_HWVAD          ((uint64_t)LOWPOWER_WAKEUPSRCINT1_HWVAD_IRQ          << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_DP         ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_DP_IRQ         << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_DP0        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_DP0_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_DP1        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_DP1_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_DP2        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_DP2_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_BLE_LL_ALL     ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_LL_ALL_IRQ     << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ZIGBEE_MAC     ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ZIGBEE_MAC_IRQ     << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ZIGBEE_MODEM   ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ZIGBEE_MODEM_IRQ   << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_RFP_TMU        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_RFP_TMU_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_RFP_AGC        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_RFP_AGC_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ISO7816        ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ISO7816_IRQ        << 32)  /*!< [DEEP SLEEP] */
+#define POWER_WAKEUPSRC_ANA_COMP       ((uint64_t)LOWPOWER_WAKEUPSRCINT1_ANA_COMP_IRQ       << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_WAKE_UP_TIMER0 ((uint64_t)LOWPOWER_WAKEUPSRCINT1_WAKE_UP_TIMER0_IRQ << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_WAKE_UP_TIMER1 ((uint64_t)LOWPOWER_WAKEUPSRCINT1_WAKE_UP_TIMER1_IRQ << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_BLE_WAKE_TIMER ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_WAKE_TIMER_IRQ << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_BLE_OSC_EN     ((uint64_t)LOWPOWER_WAKEUPSRCINT1_BLE_OSC_EN_IRQ     << 32)  /*!< [DEEP SLEEP, POWER DOWN] */
+#define POWER_WAKEUPSRC_IO             ((uint64_t)LOWPOWER_WAKEUPSRCINT1_IO_IRQ             << 32)  /*!< [POWER DOWN, DEEP DOWN]  */
+
+/**
+ * @brief  BOD config
+ */
+typedef struct {
+    uint8_t bod_level;  /*!< BOD trigger level */
+    uint8_t bod_hyst;   /*!< BOD Hysteresis control */
+    uint8_t bod_cfg;    /*!< BOD config setting */
+} pm_bod_cfg_t;
+
+typedef uint64_t       pm_wake_source_t;
+
+/**
+ * @brief  PDRUNCFG bits offset
+ */
+typedef enum pd_bits
+{
+    kPDRUNCFG_PD_LDO_ADC_EN = 22,           /*!< Offset is 22, LDO ADC enabled */
+    kPDRUNCFG_PD_BOD_MEM_EN = 23,           /*!< Offset is 23, BOD MEM enabled */
+    kPDRUNCFG_PD_BOD_CORE_EN = 24,          /*!< Offset is 24, BOD CORE enabled */
+    kPDRUNCFG_PD_FRO32K_EN       = 25,      /*!< Offset is 25, FRO32K enabled */
+    kPDRUNCFG_PD_XTAL32K_EN      = 26,      /*!< Offset is 26, XTAL32K enabled */
+    kPDRUNCFG_PD_BOD_ANA_COMP_EN = 27,      /*!< Offset is 27, Analog Comparator enabled */
+
+    kPDRUNCFG_ForceUnsigned = 0x80000000U
+} pd_bit_t;
+
+/**
+ * @brief  Power modes
+ */
+typedef enum {
+    /* PM_DEEP_SLEEP, */
+    PM_POWER_DOWN,  /*!< Power down mode */
+    PM_DEEP_DOWN,   /*!< Deep power down mode */
+} pm_power_mode_t ;
+
+/**
+ * @brief  Power config
+ */
+typedef struct {
+    pm_wake_source_t pm_wakeup_src; /*!< Wakeup source select */
+    uint32_t         pm_wakeup_io;  /*!< Wakeup IO */
+    uint32_t         pm_config;     /*!< Power mode config */
+} pm_power_config_t;
+
+/**
+ * @brief  Reset Cause definition
+ */
+typedef enum reset_cause
+{
+    RESET_UNDEFINED     = 0,
+    RESET_POR           = (1 << 0), /*!< The last chip reset was caused by a Power On Reset. */
+    RESET_EXT_PIN       = (1 << 1), /*!< The last chip reset was caused by a Pad Reset. */
+    RESET_BOR           = (1 << 2), /*!< The last chip reset was caused by a Brown Out Detector. */
+    RESET_SYS_REQ       = (1 << 3), /*!< The last chip reset was caused by a System Reset requested by the ARM CPU. */
+    RESET_WDT           = (1 << 4), /*!< The last chip reset was caused by the Watchdog Timer. */
+    RESET_WAKE_DEEP_PD  = (1 << 5), /*!< The last chip reset was caused by a Wake-up I/O (GPIO or internal NTAG FD INT). */
+    RESET_WAKE_PD       = (1 << 6), /*!< The last CPU reset was caused by a Wake-up from Power down (many sources possible: timer, IO, ...). */
+    RESET_SW_REQ        = (1 << 7)  /*!< The last chip reset was caused by a Software. ES2 Only */
+} reset_cause_t;
+
+/**
+ * @brief  LDO voltage setting
+ */
+typedef enum {
+    PM_LDO_VOLT_1_1V_DEFAULT,   /*!< LDO voltage 1.1V */
+    PM_LDO_VOLT_1_0V,  /*!< not safe at system start/wakeup and CPU clock switch to higher frequency */
+} pm_ldo_volt_t ;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+* @name Power Configuration
+* @{
+*/
+
+/*!
+ * @brief Initialize the sdk power drivers
+ *
+ * Optimize the LDO voltage for power saving
+ * Initialize the power domains
+ *
+ * @return none
+ */
+void POWER_Init(void);
+
+/*!
+ * @brief  Optimize the LDO voltage for power saving
+ * Initialize the power domains
+ *
+ * @return none
+ */
+void POWER_SetTrimDefaultActiveVoltage(void);
+
+/*!
+ * @brief BODMEM and BODCORE setup
+ *
+ * Enable the BOD core and BOD mem
+ * Disable the analog comnparator clock
+ *
+ * @return none
+ */
+void POWER_BodSetUp(void);
+
+/*!
+ * @brief enable SW reset for the BODCORE
+ *
+ * @return none
+ */
+void POWER_BodActivate(void);
+
+/*!
+ * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
+ *
+ * @param en    peripheral for which to enable the PDRUNCFG bit
+ *
+ * @return none
+ */
+static inline void POWER_EnablePD(pd_bit_t en)
+{
+    /* PDRUNCFGSET */
+    PMC->PDRUNCFG |= (1UL << (en & 0xffU));
+}
+
+/*!
+ * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
+ *
+ * @param en    peripheral for which to disable the PDRUNCFG bit
+ *
+ * @return none
+ */
+static inline void POWER_DisablePD(pd_bit_t en)
+{
+    /* PDRUNCFGCLR */
+    PMC->PDRUNCFG &= ~(1UL << (en & 0xffU));
+}
+
+/*!
+ *  @brief Get IO and Ntag Field detect Wake-up sources from Power Down and Deep Power Down modes.
+ *  Allow to identify the wake-up source when waking up from Power-Down modes or Deep Power Down modes.
+ *  Status is reset by POR, RSTN, WDT.
+ *  bit in range from 0 to 21 are for DIO0 to DIO21
+ *  bit 22 is NTAG field detect wakeup source
+ *
+ *  @return IO and Field detect Wake-up source
+ */
+static inline uint32_t POWER_GetIoWakeStatus(void)
+{
+    return PMC->WAKEIOCAUSE;
+}
+
+/*!
+ * @brief Power API to enter sleep mode (Doze mode)
+ *
+ * @note: The static inline function has not the expecetd effect in -O0. If order to force inline this macro is added
+ *
+ * @return none
+ */
+#define POWER_ENTER_SLEEP()  __DSB(); __WFI(); __ISB();
+
+/*!
+ * @brief Power API to enter sleep mode (Doze mode)
+ *
+ * @note: If the user desires to program a wakeup timer before going to sleep, it needs to use
+ * either the fsl_wtimer.h API or use the POWER_SetLowPower() API instead
+ * see POWER_ENTER_SLEEP
+ *
+ * @return none
+ */
+static inline void POWER_EnterSleep(void)
+{
+    POWER_ENTER_SLEEP();
+}
+
+/*!
+ * @brief Power Library API to enter different power mode.
+ * If requested mode is PM_POWER_DOWN, the API will perform the clamping of the DIOs
+ * if the PIO register has the bit IO_CLAMPING set: SYSCON->RETENTIONCTRL.IOCLAMP
+ * will be set
+ *
+ * @param pm_power_mode  Power modes
+ * @see pm_power_mode_t
+ * @param pm_power_config Power config
+ * @see pm_power_config_t
+ *
+ * @return false if chip could not go to sleep. Configuration structure is incorrect
+ */
+bool POWER_EnterPowerMode(pm_power_mode_t pm_power_mode, pm_power_config_t* pm_power_config);
+
+/*!
+ * @brief determine cause of reset
+ *
+ * @return reset_cause
+ */
+reset_cause_t POWER_GetResetCause(void);
+
+/*!
+ * @brief Clear cause of reset
+ */
+void POWER_ClearResetCause(void);
+
+/*!
+ * @brief Power Library API to return the library version.
+ *
+ * @param none
+ *
+ * @return version number of the power library
+ */
+uint32_t POWER_GetLibVersion(void);
+
+/*!
+ * @brief Get default Vbat BOD config parameters, level @1.75V, Hysteresis @ 100mV
+ *
+ * @param bod_cfg_p BOD config
+ * @see pm_bod_cfg_t
+ *
+ * @return none
+ */
+void POWER_BodVbatGetDefaultConfig(pm_bod_cfg_t * bod_cfg_p);
+
+/*!
+ * @brief Configure the VBAT BOD
+ *
+ * @param bod_cfg_p BOD config
+ * @see pm_bod_cfg_t
+ *
+ * @return false if configuration parameters are incorrect
+ */
+bool POWER_BodVbatConfig(pm_bod_cfg_t * bod_cfg_p);
+
+/*!
+ * @brief Configure the LDO voltage
+ *
+ * @param ldoVolt LDO voltage setting
+ * @see pm_ldo_volt_t
+ *
+ * @return none
+ */
+void POWER_ApplyLdoActiveVoltage(pm_ldo_volt_t ldoVolt);
+
+/* @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*! @} */
+
+#endif /* _FSL_POWER_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_reset.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_reset.c
new file mode 100755
index 0000000..c4a584d
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_reset.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_reset.h"
+
+#include "rom_lowpower.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.reset"
+#endif
+/* RG TODO This should be defined in jn518x.h */
+#define SYSCON_PRESETCTRL_COUNT 2
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
+     (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
+
+/*!
+ * brief Assert reset to peripheral.
+ *
+ * Asserts reset signal to specified peripheral module.
+ *
+ * param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_SetPeripheralReset(reset_ip_name_t peripheral)
+{
+    const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
+    const uint32_t bitPos   = ((uint32_t)peripheral & 0x0000FFFFu);
+    const uint32_t bitMask  = 1u << bitPos;
+
+    assert(bitPos < 32u);
+
+    /* ASYNC_SYSCON registers have offset 1024 */
+    if (regIndex >= SYSCON_PRESETCTRL_COUNT)
+    {
+        /* reset register is in ASYNC_SYSCON */
+
+        /* set bit */
+        ASYNC_SYSCON->ASYNCPRESETCTRLSET = bitMask;
+        /* wait until it reads 0b1 */
+        while (0u == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
+        {
+        }
+    }
+    else
+    {
+        /* reset register is in SYSCON */
+
+        /* set bit */
+        SYSCON->PRESETCTRLSETS[regIndex] = bitMask;
+        /* wait until it reads 0b1 */
+        while (0u == (SYSCON->PRESETCTRLS[regIndex] & bitMask))
+        {
+        }
+    }
+}
+
+/*!
+ * brief Clear reset to peripheral.
+ *
+ * Clears reset signal to specified peripheral module, allows it to operate.
+ *
+ * param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_ClearPeripheralReset(reset_ip_name_t peripheral)
+{
+    const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
+    const uint32_t bitPos   = ((uint32_t)peripheral & 0x0000FFFFu);
+    const uint32_t bitMask  = 1u << bitPos;
+
+    assert(bitPos < 32u);
+
+    /* ASYNC_SYSCON registers have offset > SYSCON_PRESETCTRL_COUNT */
+    if (regIndex >= SYSCON_PRESETCTRL_COUNT)
+    {
+        /* reset register is in ASYNC_SYSCON */
+
+        /* clear bit */
+        ASYNC_SYSCON->ASYNCPRESETCTRLCLR = bitMask;
+        /* wait until it reads 0b0 */
+        while (bitMask == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
+        {
+        }
+    }
+    else
+    {
+        /* reset register is in SYSCON */
+
+        /* clear bit */
+        SYSCON->PRESETCTRLCLRS[regIndex] = bitMask;
+        /* wait until it reads 0b0 */
+        while (bitMask == (SYSCON->PRESETCTRLS[regIndex] & bitMask))
+        {
+        }
+    }
+}
+
+/*!
+ * brief Reset peripheral module.
+ *
+ * Reset peripheral module.
+ *
+ * param peripheral Peripheral to reset. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_PeripheralReset(reset_ip_name_t peripheral)
+{
+    RESET_SetPeripheralReset(peripheral);
+    RESET_ClearPeripheralReset(peripheral);
+}
+
+#endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */
+
+/*!
+ * brief Reset the chip.
+ *
+ * Full software reset of the chip.
+ * On reboot, function POWER_GetResetCause() from fsl_power.h will return RESET_SYS_REQ
+ */
+void RESET_SystemReset(void)
+{
+    /* Disable all interrupts */
+    __disable_irq();
+    /* On ES2, software reset is directly implemented in ROM code so the Flash
+     * controller can be correctly powered OFF before the reset */
+    Chip_LOWPOWER_ChipSoftwareReset();
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_reset.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_reset.h
new file mode 100755
index 0000000..cd43a11
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_reset.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_RESET_H_
+#define _FSL_RESET_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "fsl_device_registers.h"
+
+/*!
+ * @addtogroup ksdk_common
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief RESET driver version 2.0.1. */
+#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
+/*@}*/
+
+/*!
+ * @brief Enumeration for peripheral reset control bits
+ *
+ * Defines the enumeration for peripheral reset control bits in PRESETCTRL/ASYNCPRESETCTRL registers
+ */
+typedef enum _SYSCON_RSTn
+{
+    kSPIFI_RST_SHIFT_RSTn  = (0 | SYSCON_PRESETCTRL0_SPIFI_RST_SHIFT),          /**< SpiFi reset control   */
+    kMUX_RST_SHIFT_RSTn    = (0 | SYSCON_PRESETCTRL0_MUX_RST_SHIFT),            /**< Input mux reset control */
+    kBLE_TG_RST_SHIFT_RSTn = (0 | SYSCON_PRESETCTRL0_BLE_TIMING_GEN_RST_SHIFT), /**< BLE power module reset control   */
+    kIOCON_RST_SHIFT_RSTn  = (0 | SYSCON_PRESETCTRL0_IOCON_RST_SHIFT),          /**< IOCON reset control */
+    kGPIO0_RST_SHIFT_RSTn  = (0 | SYSCON_PRESETCTRL0_GPIO_RST_SHIFT),           /**< GPIO0 reset control */
+    kPINT_RST_SHIFT_RSTn   = (0 | SYSCON_PRESETCTRL0_PINT_RST_SHIFT), /**< Pin interrupt (PINT) reset control */
+    kGINT_RST_SHIFT_RSTn   = (0 | SYSCON_PRESETCTRL0_GINT_RST_SHIFT), /**< Grouped interrupt (PINT) reset control. */
+    kDMA_RST_SHIFT_RSTn    = (0 | SYSCON_PRESETCTRL0_DMA_RST_SHIFT),  /**< DMA reset control */
+    kWWDT_RST_SHIFT_RSTn   = (0 | SYSCON_PRESETCTRL0_WWDT_RST_SHIFT), /**< Watchdog timer reset control */
+    kRTC_RST_SHIFT_RSTn    = (0 | SYSCON_PRESETCTRL0_RTC_RST_SHIFT),  /**< RTC reset control */
+    kANA_INT_RST_SHIFT_RSTn = (0 | SYSCON_PRESETCTRL0_ANA_INT_CTRL_RST_SHIFT), /**< Analog interrupt controller reset */
+    kWKT_RST_SHIFT_RSTn     = (0 | SYSCON_PRESETCTRL0_WAKE_UP_TIMERS_RST_SHIFT), /**< Wakeup timer reset */
+    kADC0_RST_SHIFT_RSTn    = (0 | SYSCON_PRESETCTRL0_ADC_RST_SHIFT),            /**< ADC0 reset control */
+    kFC0_RST_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_USART0_RST_SHIFT), /**< Flexcomm Interface 0 reset control */
+    kFC1_RST_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_USART1_RST_SHIFT),                 /**< Flexcomm Interface 1 reset control */
+    kFC2_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_I2C0_RST_SHIFT), /**< Flexcomm Interface 2 reset control */
+    kFC3_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_I2C1_RST_SHIFT), /**< Flexcomm Interface 3 reset control */
+    kFC4_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_SPI0_RST_SHIFT), /**< Flexcomm Interface 4 reset control */
+    kFC5_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_SPI1_RST_SHIFT), /**< Flexcomm Interface 5 reset control */
+    kIRB_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_IR_RST_SHIFT),   /**< IR Blaster reset control */
+    kPWM_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_PWM_RST_SHIFT),  /**< PWM reset control */
+    kRNG_RST_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_RNG_RST_SHIFT), /**< Random number generator reset control */
+    kFC6_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_I2C2_RST_SHIFT), /**< Flexcomm Interface 6 reset control */
+    kUSART0_RST_SHIFT_RSTn = kFC0_RST_SHIFT_RSTn,                            /**< USART0 reset control == Flexcomm0 */
+    kUSART1_RST_SHIFT_RSTn = kFC1_RST_SHIFT_RSTn,                            /**< USART0 reset control == Flexcomm1 */
+    kI2C0_RST_SHIFT_RSTn   = kFC2_RST_SHIFT_RSTn,                            /**< I2C0 reset control == Flexcomm 2  */
+    kI2C1_RST_SHIFT_RSTn   = kFC3_RST_SHIFT_RSTn,                            /**< I2C1 reset control == Flexcomm 3  */
+    kSPI0_RST_SHIFT_RSTn   = kFC4_RST_SHIFT_RSTn,                            /**< SPI0 reset control == Flexcomm 4  */
+    kSPI1_RST_SHIFT_RSTn   = kFC5_RST_SHIFT_RSTn,                            /**< SPI1 reset control == Flexcomm 5  */
+    kI2C2_RST_SHIFT_RSTn   = kFC6_RST_SHIFT_RSTn,                            /**< I2C2 reset control == Flexcomm 6  */
+    kBLE_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_BLE_RST_SHIFT),  /**< Bluetooth LE modules reset control */
+    kMODEM_MASTER_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_MODEM_MASTER_RST_SHIFT),          /**< AHB Modem master interface reset */
+    kAES_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_AES_RST_SHIFT), /**< Encryption module reset control */
+    kRFP_RST_SHIFT_RSTn = ((1UL << 16) | SYSCON_PRESETCTRL1_RFP_RST_SHIFT), /**< Radio front end controller reset */
+    kDMIC_RST_SHIFT_RSTn =
+        ((1UL << 16) | SYSCON_PRESETCTRL1_DMIC_RST_SHIFT), /**< Digital microphone interface reset control */
+    kHASH_RST_SHIFT_RSTn    = ((1UL << 16) | SYSCON_PRESETCTRL1_HASH_RST_SHIFT),         /**< Hash SHA reset */
+    kCTIMER0_RST_SHIFT_RSTn = ((2UL << 16) | ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT), /**< CT32B0 reset control */
+    kCTIMER1_RST_SHIFT_RSTn = ((2UL << 16) | ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT), /**< CT32B1 reset control */
+} SYSCON_RSTn_t;
+
+/** Array initializers with peripheral reset bits **/
+#define ADC_RSTS             \
+    {                        \
+        kADC0_RST_SHIFT_RSTn \
+    } /* Reset bits for ADC peripheral */
+#define AES_RSTS             \
+    {                        \
+        kAES_RST_SHIFT_RSTbn \
+    } /* Reset bits for Encryption peripheral */
+#define ANA_INT_RSTS            \
+    {                           \
+        kANA_INT_RST_SHIFT_RSTn \
+    } /* Reset bits for Analog interrupts controller */
+#define BLE_RSTS            \
+    {                       \
+        kBLE_RST_SHIFT_RSTn \
+    } /* Reset bits for Bluetooth LE peripheral */
+#define BLE_TG_RSTS            \
+    {                          \
+        kBLE_TG_RST_SHIFT_RSTn \
+    } /* Bluetooth LE power module reset */
+#define CRC_RSTS            \
+    {                       \
+        kCRC_RST_SHIFT_RSTn \
+    } /* Reset bits for CRC peripheral */
+#define CTIMER_RSTS                                      \
+    {                                                    \
+        kCTIMER0_RST_SHIFT_RSTn, kCTIMER1_RST_SHIFT_RSTn \
+    } /* Reset bits for TIMER peripheral */
+#define DMA_RSTS_N          \
+    {                       \
+        kDMA_RST_SHIFT_RSTn \
+    } /* Reset bits for DMA peripheral */
+#define DMIC_RSTS            \
+    {                        \
+        kDMIC_RST_SHIFT_RSTn \
+    } /* Reset bits for ADC peripheral */
+#define EFUSE_RSTS            \
+    {                         \
+        kEFUSE_RST_SHIFT_RSTn \
+    } /* Reset bits for EFuse peripheral */
+#define FLASH_RSTS            \
+    {                         \
+        kFLASH_RST_SHIFT_RSTn \
+    } /* Reset bits for flash controller */
+#define FLEXCOMM_RSTS                                                                                            \
+    {                                                                                                            \
+        kFC0_RST_SHIFT_RSTn, kFC1_RST_SHIFT_RSTn, kFC2_RST_SHIFT_RSTn, kFC3_RST_SHIFT_RSTn, kFC4_RST_SHIFT_RSTn, \
+            kFC5_RST_SHIFT_RSTn, kFC6_RST_SHIFT_RSTn                                                             \
+    } /* Reset bits for FLEXCOMM peripheral */
+#define GINT_RSTS            \
+    {                        \
+        kGINT_RST_SHIFT_RSTn \
+    } /* Reset bits for GINT peripheral. GINT0 & GINT1 share same slot */
+#define GPIO_RSTS_N           \
+    {                         \
+        kGPIO0_RST_SHIFT_RSTn \
+    } /* Reset bits for GPIO peripheral */
+#define INPUTMUX_RSTS       \
+    {                       \
+        kMUX_RST_SHIFT_RSTn \
+    } /* Reset bits for INPUTMUX peripheral */
+#define IOCON_RSTS            \
+    {                         \
+        kIOCON_RST_SHIFT_RSTn \
+    } /* Reset bits for IOCON peripheral */
+#define ZIGBEE_RSTS            \
+    {                          \
+        kZIGBEE_RST_SHIFT_RSTn \
+    } /* Reset bits for RF/Zigbee peripheral */
+#define MAILBOX_RSTS            \
+    {                           \
+        kMAILBOX_RST_SHIFT_RSTn \
+    } /* Reset bits for inter-CPU mailbox peripheral */
+#define MODEM_RSTS               \
+    {                            \
+        kMODEM_MASTER_SHIFT_RSTn \
+    } /* Reset bits for AHB Modem master interface peripheral */
+#define MRT_RSTS            \
+    {                       \
+        kMRT_RST_SHIFT_RSTn \
+    } /* Reset bits for MRT peripheral */
+#define PINT_RSTS            \
+    {                        \
+        kPINT_RST_SHIFT_RSTn \
+    } /* Reset bits for PINT peripheral */
+#define PVT_RSTS            \
+    {                       \
+        kPVT_RST_SHIFT_RSTn \
+    } /* Reset bits for PVT peripheral */
+#define RTC_RSTS            \
+    {                       \
+        kRTC_RST_SHIFT_RSTn \
+    } /* Reset bits for RTC peripheral */
+#define SPIFI_RSTS            \
+    {                         \
+        kSPIFI_RST_SHIFT_RSTn \
+    } /* Reset bits for SPIFI peripheral */
+#define TPR_RSTS            \
+    {                       \
+        kTPR_RST_SHIFT_RSTn \
+    } /* Reset bits for test pointer register peripheral */
+#define WWDT_RSTS            \
+    {                        \
+        kWWDT_RST_SHIFT_RSTn \
+    } /* Reset bits for windowed watchdog timer */
+
+#define WWDT_RSTS            \
+    {                        \
+        kWWDT_RST_SHIFT_RSTn \
+    } /* Reset bits for WWDT peripheral */
+
+typedef SYSCON_RSTn_t reset_ip_name_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @brief Assert reset to peripheral.
+ *
+ * Asserts reset signal to specified peripheral module.
+ *
+ * @param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_SetPeripheralReset(reset_ip_name_t peripheral);
+
+/*!
+ * @brief Clear reset to peripheral.
+ *
+ * Clears reset signal to specified peripheral module, allows it to operate.
+ *
+ * @param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_ClearPeripheralReset(reset_ip_name_t peripheral);
+
+/*!
+ * @brief Reset peripheral module.
+ *
+ * Reset peripheral module.
+ *
+ * @param peripheral Peripheral to reset. The enum argument contains encoding of reset register
+ *                   and reset bit position in the reset register.
+ */
+void RESET_PeripheralReset(reset_ip_name_t peripheral);
+
+/*!
+ * @brief Reset the chip.
+ *
+ * Full software reset of the chip.
+ * On reboot, function POWER_GetResetCause() from fsl_power.h will return RESET_SYS_REQ
+ */
+void RESET_SystemReset(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @} */
+
+#endif /* _FSL_RESET_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_rng.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_rng.c
new file mode 100755
index 0000000..f1ba450
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_rng.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_rng.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.jn_rng"
+#endif
+
+#define TRNG_MODE_SEL_BIT_NUM (0)
+#define TRNG_MODE_SEL_BIT_MASK (0x3 << TRNG_MODE_SEL_BIT_NUM)
+#define TRNG_CLOCK_SEL_BIT_NUM (2)
+#define TRNG_CLOCK_SEL_BIT_MASK (0x7 << TRNG_CLOCK_SEL_BIT_NUM)
+#define TRNG_SHIFT4X_BIT_NUM (5)
+#define TRNG_SHIFT4X_BIT_MASK (0x7 << TRNG_SHIFT4X_BIT_NUM)
+
+/*******************************************************************************
+ * Public APIs
+ ******************************************************************************/
+
+status_t TRNG_GetDefaultConfig(trng_config_t *userConfig)
+{
+    /* Check if valid parameters */
+    if (userConfig == NULL)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Initialise configuration structure */
+    userConfig->shift4x   = 0;
+    userConfig->clock_sel = 0;
+    userConfig->mode      = trng_FreeRunning;
+    return kStatus_Success;
+}
+
+status_t TRNG_Init(RNG_Type *base, const trng_config_t *userConfig)
+{
+    /* Check if valid parameters are passed */
+    if ((base == NULL) || (userConfig == NULL))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Check if valid parameters are passed */
+    if ((userConfig->mode != trng_UpdateOnce) && (userConfig->mode != trng_FreeRunning))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Enable RNG peripheral clock for register access */
+    /* Make sure that the XTAL 32MHz clock is enabled before this */
+    if (!(ASYNC_SYSCON->XTAL32MCTRL & ASYNC_SYSCON_XTAL32MCTRL_XO_ENABLE_MASK))
+    {
+        return kStatus_Fail;
+    }
+    SYSCON->PRESETCTRLSET[1] = SYSCON_PRESETCTRLSET1_RNG_RST_SET_MASK;
+    //CLOCK_EnableClock(kCLOCK_Xtal32M);
+    CLOCK_EnableClock(kCLOCK_Rng);
+    SYSCON->PRESETCTRLCLR[1] = SYSCON_PRESETCTRLCLR1_RNG_RST_CLR_MASK;
+
+    /* Enable Analog clocks for RNG module */
+    SYSCON->RNGCLKCTRL = 1;
+
+    /* Configure TRNG module */
+    base->COUNTER_CFG &= ~(TRNG_CLOCK_SEL_BIT_MASK | TRNG_SHIFT4X_BIT_MASK | TRNG_MODE_SEL_BIT_MASK);
+    base->COUNTER_CFG |=
+        ((userConfig->clock_sel << TRNG_CLOCK_SEL_BIT_NUM) | (userConfig->shift4x << TRNG_SHIFT4X_BIT_NUM));
+
+    /* Set mode */
+    base->COUNTER_CFG |= userConfig->mode;
+
+    return kStatus_Success;
+}
+
+void TRNG_Deinit(RNG_Type *base)
+{
+    /* Disable Analog clocks for RNG module */
+    SYSCON->RNGCLKCTRL = 0;
+
+    /* Disable RNG clock */
+    CLOCK_DisableClock(kCLOCK_Rng);
+    return;
+}
+
+status_t TRNG_GetRandomData(RNG_Type *base, void *data, size_t data_size)
+{
+    uint32_t random_32;
+    uint8_t *random_p;
+    uint32_t random_size;
+    uint8_t *data_p = (uint8_t *)data;
+    uint32_t i;
+
+    /* Check if valid parameters */
+    if ((base == NULL) || (data == NULL) || (data_size == 0))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Read random data as per user request */
+    do
+    {
+        /* Read random data from register Entropy.*/
+        random_32 = base->RANDOM_NUMBER;
+
+        /* Extract required bytes */
+        random_p = (uint8_t *)&random_32;
+
+        if (data_size < sizeof(random_32))
+        {
+            random_size = data_size;
+        }
+        else
+        {
+            random_size = sizeof(random_32);
+        }
+
+        for (i = 0U; i < random_size; i++)
+        {
+            *data_p++ = *random_p++;
+        }
+
+        data_size -= random_size;
+    } while (data_size > 0);
+
+    return kStatus_Success;
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_rng.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_rng.h
new file mode 100755
index 0000000..f1677b2
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_rng.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FSL_RNG_H_
+#define __FSL_RNG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup jn_rng
+ * @{
+ */
+
+/*! @file */
+
+/**
+ * RNG return status types
+ */
+
+/**
+ * RNG operating modes
+ */
+typedef enum _trng_mode
+{
+    trng_UpdateOnce  = 0x1, /*!< TRNG update once & disable */
+    trng_FreeRunning = 0x2, /*!< TRNG updates continuously */
+} trng_mode_t;
+
+typedef struct _trng_config
+{
+    uint8_t shift4x;   /*!< Used to add precision to clock ratio & entropy refill - range from 0 to 4 */
+    uint8_t clock_sel; /*!< Internal clock on which to compute statistics */
+                       /*!< 0 - XOR results from all clocks */
+                       /*!< 1 - First clock */
+                       /*!< 2 - Second clock */
+    trng_mode_t mode;  /*!< TRNG mode select */
+} trng_config_t;
+
+/*!
+ * @brief Gets Default config of TRNG.
+ *
+ * This function initializes the TRNG configuration structure.
+ *
+ * @param userConfig Pointer to TRNG configuration structure
+ */
+status_t TRNG_GetDefaultConfig(trng_config_t *userConfig);
+
+/*!
+ * @brief Initializes the TRNG.
+ *
+ * This function initializes the TRNG.
+ *
+ * @param base TRNG base address
+ * @param userConfig The configuration of TRNG
+ * @return  kStatus_Success - Success
+ *          kStatus_InvalidArgument - Invalid parameter
+ */
+status_t TRNG_Init(RNG_Type *base, const trng_config_t *userConfig);
+
+/*!
+ * @brief Shuts down the TRNG.
+ *
+ * This function shuts down the TRNG.
+ *
+ * @param base TRNG base address
+ */
+void TRNG_Deinit(RNG_Type *base);
+
+/*!
+ * @brief Gets random data.
+ *
+ * This function gets random data from the TRNG.
+ *
+ * @param base TRNG base address
+ * @param data pointer to user buffer to be filled by random data
+ * @param data_size size of data in bytes
+ * @return TRNG status
+ */
+status_t TRNG_GetRandomData(RNG_Type *base, void *data, size_t data_size);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* __RNG_JN518X_H_*/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_sha.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_sha.c
new file mode 100755
index 0000000..81a5c58
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_sha.c
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "fsl_sha.h"
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.sha"
+#endif
+
+/*!< SHA-1 and SHA-256 block size  */
+#define SHA_BLOCK_SIZE 64
+
+/*!< Use standard C library memcpy  */
+#define sha_memcpy memcpy
+
+/*! Internal states of the HASH creation process */
+typedef enum _sha_algo_state
+{
+    kSHA_HashInit = 1u, /*!< Init state, the NEW bit in SHA Control register has not been written yet. */
+    kSHA_HashUpdate, /*!< Update state, DIGEST registers contain running hash, NEW bit in SHA control register has been
+                        written. */
+} sha_algo_state_t;
+
+/*! 64-byte block represented as byte array of 16 32-bit words */
+typedef union _sha_hash_block
+{
+    uint32_t w[SHA_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
+    uint8_t b[SHA_BLOCK_SIZE];      /*!< byte array */
+} sha_block_t;
+
+/*! internal sha context structure */
+typedef struct _sha_ctx_internal
+{
+    sha_block_t blk;        /*!< memory buffer. only full 64-byte blocks are written to SHA during hash updates */
+    size_t blksz;           /*!< number of valid bytes in memory buffer */
+    sha_algo_t algo;        /*!< selected algorithm from the set of supported algorithms */
+    sha_algo_state_t state; /*!< finite machine state of the hash software process */
+    size_t fullMessageSize; /*!< track message size during SHA_Update(). The value is used for padding. */
+} sha_ctx_internal_t;
+
+/*!< SHA-1 and SHA-256 digest length in bytes  */
+enum _sha_digest_len
+{
+    kSHA_OutLenSha1   = 20u,
+    kSHA_OutLenSha256 = 32u,
+};
+
+/*!< macro for checking build time condition. It is used to assure the sha_ctx_internal_t can fit into sha_ctx_t */
+#define BUILD_ASSERT(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * @brief LDM to SHA engine INDATA and ALIAS registers.
+ *
+ * This function writes 16 words starting from the src address (must be word aligned)
+ * to the dst address. Dst address does not increment (destination is peripheral module register INDATA).
+ * Src address increments to load 16 consecutive words.
+ *
+ * @param dst peripheral register address (word aligned)
+ * @param src address of the input 512-bit block (16 words) (word aligned)
+ *
+ */
+#if defined(SHA_ALIAS_DATA_MASK)
+__STATIC_INLINE void sha_ldm_stm_16_words(SHA_Type *base, const uint32_t *src)
+{
+    base->INDATA = src[0];
+    for (int i = 0; i < 7; i++)
+    {
+        base->ALIAS[i] = src[i + 1];
+    }
+    src += 8u;
+    base->INDATA = src[0];
+    for (int i = 0; i < 7; i++)
+    {
+        base->ALIAS[i] = src[i + 1];
+    }
+}
+#else
+__STATIC_INLINE void sha_ldm_stm_16_words(volatile uint32_t *dst, const uint32_t *src)
+{
+    for (int i = 0; i < 8; i++)
+    {
+        dst[i] = src[i];
+    }
+    src += 8u;
+    for (int i = 0; i < 8; i++)
+    {
+        dst[i] = src[i];
+    }
+}
+#endif
+/*!
+ * @brief Swap bytes withing 32-bit word.
+ *
+ * This function changes endianess of a 32-bit word.
+ *
+ * @param in 32-bit unsigned integer
+ * @return 32-bit unsigned integer with different endianess (big endian to little endian and vice versa).
+ */
+static uint32_t swap_bytes(uint32_t in)
+{
+    return (((in & 0x000000ffu) << 24) | ((in & 0x0000ff00u) << 8) | ((in & 0x00ff0000u) >> 8) |
+            ((in & 0xff000000u) >> 24));
+}
+
+/*!
+ * @brief Check validity of algoritm.
+ *
+ * This function checks the validity of input argument.
+ *
+ * @param algo Tested algorithm value.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t sha_check_input_alg(sha_algo_t algo)
+{
+    if ((algo != kSHA_Sha1) && (algo != kSHA_Sha256))
+    {
+        return kStatus_InvalidArgument;
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Check validity of input arguments.
+ *
+ * This function checks the validity of input arguments.
+ *
+ * @param base SHA peripheral base address.
+ * @param ctx Memory buffer given by user application where the SHA_Init/SHA_Update/SHA_Finish store context.
+ * @param algo Tested algorithm value.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t sha_check_input_args(SHA_Type *base, sha_ctx_t *ctx, sha_algo_t algo)
+{
+    /* Check validity of input algorithm */
+    if (kStatus_Success != sha_check_input_alg(algo))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    if ((NULL == ctx) || (NULL == base))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Check validity of internal software context.
+ *
+ * This function checks if the internal context structure looks correct.
+ *
+ * @param ctxInternal Internal context.
+ * @param message Input message address.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t sha_check_context(sha_ctx_internal_t *ctxInternal, const uint8_t *message)
+{
+    if ((NULL == message) || (NULL == ctxInternal) || (kStatus_Success != sha_check_input_alg(ctxInternal->algo)))
+    {
+        return kStatus_InvalidArgument;
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Initialize the SHA engine for new hash.
+ *
+ * This function sets NEW and MODE fields in SHA Control register to start new hash.
+ *
+ * @param base SHA peripheral base address.
+ * @param ctxInternal Internal context.
+ */
+static void sha_engine_init(SHA_Type *base, sha_ctx_internal_t *ctxInternal)
+{
+    uint32_t shaCtrl;
+
+    if (kSHA_Sha1 == ctxInternal->algo)
+    {
+        shaCtrl = SHA_CTRL_MODE(1) | SHA_CTRL_NEW(1);
+    }
+    else
+    {
+        shaCtrl = SHA_CTRL_MODE(2) | SHA_CTRL_NEW(1);
+    }
+    base->CTRL = shaCtrl;
+}
+
+/*!
+ * @brief Load 512-bit block (16 words) into SHA engine.
+ *
+ * This function aligns the input block and moves it into SHA engine INDATA.
+ * CPU polls the WAITING bit and then moves data by using LDM and STM instructions.
+ *
+ * @param base SHA peripheral base address.
+ * @param blk 512-bit block
+ */
+static void sha_one_block(SHA_Type *base, const uint8_t *blk)
+{
+    uint32_t temp[SHA_BLOCK_SIZE / sizeof(uint32_t)];
+    const uint32_t *actBlk;
+
+    /* make sure the 512-bit block is word aligned */
+    if ((uintptr_t)blk & 0x3u)
+    {
+        sha_memcpy(temp, blk, SHA_BLOCK_SIZE);
+        actBlk = (const uint32_t *)(uintptr_t)temp;
+    }
+    else
+    {
+        actBlk = (const uint32_t *)(uintptr_t)blk;
+    }
+
+    /* poll waiting. */
+    while (0 == (base->STATUS & SHA_STATUS_WAITING_MASK))
+    {
+    }
+/* feed INDATA (and ALIASes). use STM instruction. */
+#if defined(SHA_ALIAS_DATA_MASK)
+    sha_ldm_stm_16_words(base, actBlk);
+#else
+    sha_ldm_stm_16_words(&base->INDATA[0], actBlk);
+#endif
+}
+
+/*!
+ * @brief Adds message to current hash.
+ *
+ * This function merges the message to fill the internal buffer, empties the internal buffer if
+ * it becomes full, then process all remaining message data.
+ *
+ *
+ * @param base SHA peripheral base address.
+ * @param ctxInternal Internal context.
+ * @param message Input message.
+ * @param messageSize Size of input message in bytes.
+ * @return kStatus_Success.
+ */
+static status_t sha_process_message_data(SHA_Type *base,
+                                         sha_ctx_internal_t *ctxInternal,
+                                         const uint8_t *message,
+                                         size_t messageSize)
+{
+    /* first fill the internal buffer to full block */
+    size_t toCopy = SHA_BLOCK_SIZE - ctxInternal->blksz;
+    sha_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
+    message += toCopy;
+    messageSize -= toCopy;
+
+    /* process full internal block */
+    sha_one_block(base, &ctxInternal->blk.b[0]);
+
+    /* process all full blocks in message[] */
+    while (messageSize >= SHA_BLOCK_SIZE)
+    {
+        sha_one_block(base, message);
+        message += SHA_BLOCK_SIZE;
+        messageSize -= SHA_BLOCK_SIZE;
+    }
+
+    /* copy last incomplete message bytes into internal block */
+    sha_memcpy(&ctxInternal->blk.b[0], message, messageSize);
+    ctxInternal->blksz = messageSize;
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Finalize the running hash to make digest.
+ *
+ * This function empties the internal buffer, adds padding bits, and generates final digest.
+ *
+ * @param base SHA peripheral base address.
+ * @param ctxInternal Internal context.
+ * @return kStatus_Success.
+ */
+static status_t sha_finalize(SHA_Type *base, sha_ctx_internal_t *ctxInternal)
+{
+    sha_block_t lastBlock;
+
+    memset(&lastBlock, 0, sizeof(sha_block_t));
+
+    /* this is last call, so need to flush buffered message bytes along with padding */
+    if (ctxInternal->blksz <= 55u)
+    {
+        /* last data is 440 bits or less. */
+        sha_memcpy(&lastBlock.b[0], &ctxInternal->blk.b[0], ctxInternal->blksz);
+        lastBlock.b[ctxInternal->blksz]     = (uint8_t)0x80U;
+        lastBlock.w[SHA_BLOCK_SIZE / 4 - 1] = swap_bytes(8u * ctxInternal->fullMessageSize);
+        sha_one_block(base, &lastBlock.b[0]);
+    }
+    else
+    {
+        if (ctxInternal->blksz < SHA_BLOCK_SIZE)
+        {
+            ctxInternal->blk.b[ctxInternal->blksz] = (uint8_t)0x80U;
+            for (uint32_t i = ctxInternal->blksz + 1u; i < SHA_BLOCK_SIZE; i++)
+            {
+                ctxInternal->blk.b[i] = 0;
+            }
+        }
+        else
+        {
+            lastBlock.b[0] = (uint8_t)0x80U;
+        }
+
+        sha_one_block(base, &ctxInternal->blk.b[0]);
+        lastBlock.w[SHA_BLOCK_SIZE / 4 - 1] = swap_bytes(8u * ctxInternal->fullMessageSize);
+        sha_one_block(base, &lastBlock.b[0]);
+    }
+    /* poll wait for final digest */
+    while (0 == (base->STATUS & SHA_STATUS_DIGEST_MASK))
+    {
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * @brief Read DIGEST registers.
+ *
+ * This function copies DIGEST to output buffer.
+ *
+ * @param base SHA peripheral base address.
+ * @param[out] output Output buffer.
+ * @param Number of bytes to copy.
+ * @return kStatus_Success.
+ */
+static void sha_get_digest(SHA_Type *base, uint8_t *output, size_t outputSize)
+{
+    uint32_t digest[8];
+
+    for (int i = 0; i < 8; i++)
+    {
+        digest[i] = swap_bytes(base->DIGEST[i]);
+    }
+
+    if (outputSize > sizeof(digest))
+    {
+        outputSize = sizeof(digest);
+    }
+    sha_memcpy(output, digest, outputSize);
+}
+
+/*!
+ * brief Initialize HASH context
+ *
+ * This function initializes new hash context.
+ *
+ * param base SHA peripheral base address
+ * param[out] ctx Output hash context
+ * param algo Underlaying algorithm to use for hash computation. Either SHA-1 or SHA-256.
+ * return Status of initialization
+ */
+status_t SHA_Init(SHA_Type *base, sha_ctx_t *ctx, sha_algo_t algo)
+{
+    status_t status;
+
+    sha_ctx_internal_t *ctxInternal;
+    /* compile time check for the correct structure size */
+    BUILD_ASSERT(sizeof(sha_ctx_t) >= sizeof(sha_ctx_internal_t), sha_ctx_t_size);
+    uint32_t i;
+
+    status = sha_check_input_args(base, ctx, algo);
+    if (status != kStatus_Success)
+    {
+        return status;
+    }
+
+    /* set algorithm in context struct for later use */
+    ctxInternal        = (sha_ctx_internal_t *)ctx;
+    ctxInternal->algo  = algo;
+    ctxInternal->blksz = 0u;
+    for (i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++)
+    {
+        ctxInternal->blk.w[0] = 0u;
+    }
+    ctxInternal->state           = kSHA_HashInit;
+    ctxInternal->fullMessageSize = 0;
+    return status;
+}
+
+/*!
+ * brief Add data to current HASH
+ *
+ * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
+ * hashed.
+ *
+ * param base SHA peripheral base address
+ * param[in,out] ctx HASH context
+ * param message Input message
+ * param messageSize Size of input message in bytes
+ * return Status of the hash update operation
+ */
+status_t SHA_Update(SHA_Type *base, sha_ctx_t *ctx, const uint8_t *message, size_t messageSize)
+{
+    bool isUpdateState;
+    status_t status;
+    sha_ctx_internal_t *ctxInternal;
+    size_t blockSize;
+
+    if (messageSize == 0)
+    {
+        return kStatus_Success;
+    }
+
+    ctxInternal = (sha_ctx_internal_t *)ctx;
+    status      = sha_check_context(ctxInternal, message);
+    if (kStatus_Success != status)
+    {
+        return status;
+    }
+
+    ctxInternal->fullMessageSize += messageSize;
+    blockSize = SHA_BLOCK_SIZE;
+    /* if we are still less than 64 bytes, keep only in context */
+    if ((ctxInternal->blksz + messageSize) <= blockSize)
+    {
+        sha_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, message, messageSize);
+        ctxInternal->blksz += messageSize;
+        return status;
+    }
+    else
+    {
+        isUpdateState = ctxInternal->state == kSHA_HashUpdate;
+        if (!isUpdateState)
+        {
+            /* start NEW hash */
+            sha_engine_init(base, ctxInternal);
+            ctxInternal->state = kSHA_HashUpdate;
+        }
+    }
+
+    /* process message data */
+    status = sha_process_message_data(base, ctxInternal, message, messageSize);
+    return status;
+}
+
+/*!
+ * brief Finalize hashing
+ *
+ * Outputs the final hash and erases the context. SHA-1 or SHA-256 padding bits are automatically added by this
+ * function.
+ *
+ * param base SHA peripheral base address
+ * param[in,out] ctx HASH context
+ * param[out] output Output hash data
+ * param[in,out] outputSize On input, determines the size of bytes of the output array. On output, tells how many bytes
+ * have been written to output.
+ * return Status of the hash finish operation
+ */
+status_t SHA_Finish(SHA_Type *base, sha_ctx_t *ctx, uint8_t *output, size_t *outputSize)
+{
+    size_t algOutSize = 0;
+    status_t status;
+    sha_ctx_internal_t *ctxInternal;
+    uint32_t *ctxW;
+    uint32_t i;
+
+    ctxInternal = (sha_ctx_internal_t *)ctx;
+    status      = sha_check_context(ctxInternal, output);
+    if (kStatus_Success != status)
+    {
+        return status;
+    }
+
+    if (ctxInternal->state == kSHA_HashInit)
+    {
+        sha_engine_init(base, ctxInternal);
+    }
+
+    size_t outSize = 0u;
+
+    /* compute algorithm output length */
+    switch (ctxInternal->algo)
+    {
+        case kSHA_Sha1:
+            outSize = kSHA_OutLenSha1;
+            break;
+        case kSHA_Sha256:
+            outSize = kSHA_OutLenSha256;
+            break;
+        default:
+            break;
+    }
+    algOutSize = outSize;
+
+    /* flush message last incomplete block, if there is any, and add padding bits */
+    status = sha_finalize(base, ctxInternal);
+
+    if (outputSize)
+    {
+        if (algOutSize < *outputSize)
+        {
+            *outputSize = algOutSize;
+        }
+        else
+        {
+            algOutSize = *outputSize;
+        }
+    }
+
+    sha_get_digest(base, &output[0], algOutSize);
+
+    ctxW = (uint32_t *)ctx;
+    for (i = 0; i < SHA_CTX_SIZE; i++)
+    {
+        ctxW[i] = 0u;
+    }
+    return status;
+}
+
+void SHA_ClkInit(SHA_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* ungate clock */
+    CLOCK_EnableClock(kCLOCK_Sha0);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+void SHA_ClkDeinit(SHA_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+    /* gate clock */
+    CLOCK_DisableClock(kCLOCK_Sha0);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_sha.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_sha.h
new file mode 100755
index 0000000..7ea3462
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_sha.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_SHA_H_
+#define _FSL_SHA_H_
+
+#include "fsl_common.h"
+/*!
+ * @addtogroup sha
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief Defines LPC SHA driver version 2.1.0. */
+#define FSL_SHA_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
+/*@}*/
+
+/*! Supported cryptographic block cipher functions for HASH creation */
+typedef enum _sha_algo_t
+{
+    kSHA_Sha1,   /*!< SHA_1 */
+    kSHA_Sha256, /*!< SHA_256  */
+} sha_algo_t;
+
+/*! @brief SHA Context size. */
+#define SHA_CTX_SIZE 20
+
+/*! @brief Storage type used to save hash context. */
+typedef struct _sha_ctx_t
+{
+    uint32_t x[SHA_CTX_SIZE];
+} sha_ctx_t;
+
+/*******************************************************************************
+ * API
+ *******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @name SHA Functional Operation
+ * @{
+ */
+
+/*!
+ * @addtogroup sha_algorithm_level_api
+ * @{
+ */
+/*!
+ * @brief Initialize HASH context
+ *
+ * This function initializes new hash context.
+ *
+ * @param base SHA peripheral base address
+ * @param[out] ctx Output hash context
+ * @param algo Underlaying algorithm to use for hash computation. Either SHA-1 or SHA-256.
+ * @return Status of initialization
+ */
+status_t SHA_Init(SHA_Type *base, sha_ctx_t *ctx, sha_algo_t algo);
+
+/*!
+ * @brief Add data to current HASH
+ *
+ * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
+ * hashed.
+ *
+ * @param base SHA peripheral base address
+ * @param[in,out] ctx HASH context
+ * @param message Input message
+ * @param messageSize Size of input message in bytes
+ * @return Status of the hash update operation
+ */
+status_t SHA_Update(SHA_Type *base, sha_ctx_t *ctx, const uint8_t *message, size_t messageSize);
+
+/*!
+ * @brief Finalize hashing
+ *
+ * Outputs the final hash and erases the context. SHA-1 or SHA-256 padding bits are automatically added by this
+ * function.
+ *
+ * @param base SHA peripheral base address
+ * @param[in,out] ctx HASH context
+ * @param[out] output Output hash data
+ * @param[in,out] outputSize On input, determines the size of bytes of the output array. On output, tells how many bytes
+ * have been written to output.
+ * @return Status of the hash finish operation
+ */
+status_t SHA_Finish(SHA_Type *base, sha_ctx_t *ctx, uint8_t *output, size_t *outputSize);
+/*!
+ * @brief Start SHA clock
+ *
+ * Start SHA clock
+ *
+ * @param base SHA peripheral base address
+ *
+ */
+void SHA_ClkInit(SHA_Type *base);
+
+/*!
+ * @brief Stop SHA clock
+ *
+ * Stop SHA clock
+ *
+ * @param base SHA peripheral base address
+ *
+ */
+void SHA_ClkDeinit(SHA_Type *base);
+
+/*!
+ *@}
+ */ /* sha_algorithm_level_api */
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @}*/
+/*! @}*/ /* end of group sha */
+
+#endif /* _FSL_SHA_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_usart.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_usart.c
new file mode 100755
index 0000000..998fdb8
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_usart.c
@@ -0,0 +1,939 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_usart.h"
+#include "fsl_device_registers.h"
+#include "fsl_flexcomm.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.flexcomm_usart"
+#endif
+
+enum _usart_transfer_states
+{
+    kUSART_TxIdle, /* TX idle. */
+    kUSART_TxBusy, /* TX busy. */
+    kUSART_RxIdle, /* RX idle. */
+    kUSART_RxBusy  /* RX busy. */
+};
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief IRQ name array */
+static const IRQn_Type s_usartIRQ[] = USART_IRQS;
+
+/*! @brief Array to map USART instance number to base address. */
+static const uint32_t s_usartBaseAddrs[FSL_FEATURE_SOC_USART_COUNT] = USART_BASE_ADDRS;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/* Get the index corresponding to the USART */
+/*! brief Returns instance number for USART peripheral base address. */
+uint32_t USART_GetInstance(USART_Type *base)
+{
+    int i;
+
+    for (i = 0; i < FSL_FEATURE_SOC_USART_COUNT; i++)
+    {
+        if ((uint32_t)base == s_usartBaseAddrs[i])
+        {
+            return i;
+        }
+    }
+
+    assert(false);
+    return 0;
+}
+
+/*!
+ * brief Get the length of received data in RX ring buffer.
+ *
+ * param handle USART handle pointer.
+ * return Length of received data in RX ring buffer.
+ */
+size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle)
+{
+    size_t size;
+
+    /* Check arguments */
+    assert(NULL != handle);
+
+    if (handle->rxRingBufferTail > handle->rxRingBufferHead)
+    {
+        size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail);
+    }
+    else
+    {
+        size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail);
+    }
+    return size;
+}
+
+static bool USART_TransferIsRxRingBufferFull(usart_handle_t *handle)
+{
+    bool full;
+
+    /* Check arguments */
+    assert(NULL != handle);
+
+    if (USART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U))
+    {
+        full = true;
+    }
+    else
+    {
+        full = false;
+    }
+    return full;
+}
+
+/*!
+ * brief Sets up the RX ring buffer.
+ *
+ * This function sets up the RX ring buffer to a specific USART handle.
+ *
+ * When the RX ring buffer is used, data received are stored into the ring buffer even when the
+ * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received
+ * in the ring buffer, the user can get the received data from the ring buffer directly.
+ *
+ * note When using the RX ring buffer, one byte is reserved for internal use. In other
+ * words, if p ringBufferSize is 32, then only 31 bytes are used for saving data.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
+ * param ringBufferSize size of the ring buffer.
+ */
+void USART_TransferStartRingBuffer(USART_Type *base, usart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize)
+{
+    /* Check arguments */
+    assert(NULL != base);
+    assert(NULL != handle);
+    assert(NULL != ringBuffer);
+
+    /* Setup the ringbuffer address */
+    handle->rxRingBuffer     = ringBuffer;
+    handle->rxRingBufferSize = ringBufferSize;
+    handle->rxRingBufferHead = 0U;
+    handle->rxRingBufferTail = 0U;
+    /* ring buffer is ready we can start receiving data */
+    base->FIFOINTENSET |= USART_FIFOINTENSET_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK;
+}
+
+/*!
+ * brief Aborts the background transfer and uninstalls the ring buffer.
+ *
+ * This function aborts the background transfer and uninstalls the ring buffer.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle)
+{
+    /* Check arguments */
+    assert(NULL != base);
+    assert(NULL != handle);
+
+    if (handle->rxState == kUSART_RxIdle)
+    {
+        base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK;
+    }
+    handle->rxRingBuffer     = NULL;
+    handle->rxRingBufferSize = 0U;
+    handle->rxRingBufferHead = 0U;
+    handle->rxRingBufferTail = 0U;
+}
+
+/*!
+ * brief Initializes a USART instance with user configuration structure and peripheral clock.
+ *
+ * This function configures the USART module with the user-defined settings. The user can configure the configuration
+ * structure and also get the default configuration by using the USART_GetDefaultConfig() function.
+ * Example below shows how to use this API to configure USART.
+ * code
+ *  usart_config_t usartConfig;
+ *  usartConfig.baudRate_Bps = 115200U;
+ *  usartConfig.parityMode = kUSART_ParityDisabled;
+ *  usartConfig.stopBitCount = kUSART_OneStopBit;
+ *  USART_Init(USART1, &usartConfig, 20000000U);
+ * endcode
+ *
+ * param base USART peripheral base address.
+ * param config Pointer to user-defined configuration structure.
+ * param srcClock_Hz USART clock source frequency in HZ.
+ * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * retval kStatus_InvalidArgument USART base address is not valid
+ * retval kStatus_Success Status USART initialize succeed
+ */
+status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz)
+{
+    int result;
+
+    /* check arguments */
+    assert(!((NULL == base) || (NULL == config) || (0 == srcClock_Hz)));
+    if ((NULL == base) || (NULL == config) || (0 == srcClock_Hz))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* initialize flexcomm to USART mode */
+    result = FLEXCOMM_Init(base, FLEXCOMM_PERIPH_USART);
+    if (kStatus_Success != result)
+    {
+        return result;
+    }
+
+    if (config->enableTx)
+    {
+        /* empty and enable txFIFO */
+        base->FIFOCFG |= USART_FIFOCFG_EMPTYTX_MASK | USART_FIFOCFG_ENABLETX_MASK;
+        /* setup trigger level */
+        base->FIFOTRIG &= ~(USART_FIFOTRIG_TXLVL_MASK);
+        base->FIFOTRIG |= USART_FIFOTRIG_TXLVL(config->txWatermark);
+        /* enable trigger interrupt */
+        base->FIFOTRIG |= USART_FIFOTRIG_TXLVLENA_MASK;
+    }
+
+    /* empty and enable rxFIFO */
+    if (config->enableRx)
+    {
+        base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK | USART_FIFOCFG_ENABLERX_MASK;
+        /* setup trigger level */
+        base->FIFOTRIG &= ~(USART_FIFOTRIG_RXLVL_MASK);
+        base->FIFOTRIG |= USART_FIFOTRIG_RXLVL(config->rxWatermark);
+        /* enable trigger interrupt */
+        base->FIFOTRIG |= USART_FIFOTRIG_RXLVLENA_MASK;
+    }
+    /* setup configuration and enable USART */
+    base->CFG = USART_CFG_PARITYSEL(config->parityMode) | USART_CFG_STOPLEN(config->stopBitCount) |
+                USART_CFG_DATALEN(config->bitCountPerChar) | USART_CFG_LOOP(config->loopback) |
+                USART_CFG_SYNCEN(config->syncMode >> 1) | USART_CFG_SYNCMST(config->syncMode) |
+                USART_CFG_CLKPOL(config->clockPolarity) | USART_CFG_ENABLE_MASK;
+
+    /* Setup baudrate */
+    result = USART_SetBaudRate(base, config->baudRate_Bps, srcClock_Hz);
+    if (kStatus_Success != result)
+    {
+        return result;
+    }
+    /* Setting continuous Clock configuration. used for synchronous mode. */
+    USART_EnableContinuousSCLK(base, config->enableContinuousSCLK);
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Deinitializes a USART instance.
+ *
+ * This function waits for TX complete, disables TX and RX, and disables the USART clock.
+ *
+ * param base USART peripheral base address.
+ */
+void USART_Deinit(USART_Type *base)
+{
+    /* Check arguments */
+    assert(NULL != base);
+    while (!(base->STAT & USART_STAT_TXIDLE_MASK))
+    {
+    }
+    /* Disable interrupts, disable dma requests, disable peripheral */
+    base->FIFOINTENCLR = USART_FIFOINTENCLR_TXERR_MASK | USART_FIFOINTENCLR_RXERR_MASK | USART_FIFOINTENCLR_TXLVL_MASK |
+                         USART_FIFOINTENCLR_RXLVL_MASK;
+    base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK | USART_FIFOCFG_DMARX_MASK);
+    base->CFG &= ~(USART_CFG_ENABLE_MASK);
+}
+
+/*!
+ * brief Gets the default configuration structure.
+ *
+ * This function initializes the USART configuration structure to a default value. The default
+ * values are:
+ *   usartConfig->baudRate_Bps = 115200U;
+ *   usartConfig->parityMode = kUSART_ParityDisabled;
+ *   usartConfig->stopBitCount = kUSART_OneStopBit;
+ *   usartConfig->bitCountPerChar = kUSART_8BitsPerChar;
+ *   usartConfig->loopback = false;
+ *   usartConfig->enableTx = false;
+ *   usartConfig->enableRx = false;
+ *
+ * param config Pointer to configuration structure.
+ */
+void USART_GetDefaultConfig(usart_config_t *config)
+{
+    /* Check arguments */
+    assert(NULL != config);
+
+    /* Initializes the configure structure to zero. */
+    memset(config, 0, sizeof(*config));
+
+    /* Set always all members ! */
+    config->baudRate_Bps         = 115200U;
+    config->parityMode           = kUSART_ParityDisabled;
+    config->stopBitCount         = kUSART_OneStopBit;
+    config->bitCountPerChar      = kUSART_8BitsPerChar;
+    config->loopback             = false;
+    config->enableRx             = false;
+    config->enableTx             = false;
+    config->txWatermark          = kUSART_TxFifo0;
+    config->rxWatermark          = kUSART_RxFifo1;
+    config->syncMode             = kUSART_SyncModeDisabled;
+    config->enableContinuousSCLK = false;
+    config->clockPolarity        = kUSART_RxSampleOnFallingEdge;
+}
+
+/*!
+ * brief Sets the USART instance baud rate.
+ *
+ * This function configures the USART module baud rate. This function is used to update
+ * the USART module baud rate after the USART module is initialized by the USART_Init.
+ * code
+ *  USART_SetBaudRate(USART1, 115200U, 20000000U);
+ * endcode
+ *
+ * param base USART peripheral base address.
+ * param baudrate_Bps USART baudrate to be set.
+ * param srcClock_Hz USART clock source frequency in HZ.
+ * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * retval kStatus_Success Set baudrate succeed.
+ * retval kStatus_InvalidArgument One or more arguments are invalid.
+ */
+status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz)
+{
+    uint32_t best_diff = (uint32_t)-1, best_osrval = 0xf, best_brgval = (uint32_t)-1;
+    uint32_t osrval, brgval, diff, baudrate;
+
+    /* check arguments */
+    assert(!((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz)));
+    if ((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* If synchronous master mode is enabled, only configure the BRG value. */
+    if (base->CFG & USART_CFG_SYNCEN_MASK)
+    {
+        if (base->CFG & USART_CFG_SYNCMST_MASK)
+        {
+            brgval    = srcClock_Hz / baudrate_Bps;
+            base->BRG = brgval - 1;
+        }
+    }
+    else
+    {
+        /*
+         * Smaller values of OSR can make the sampling position within a data bit less accurate and may
+         * potentially cause more noise errors or incorrect data.
+         */
+        for (osrval = best_osrval; osrval >= 8; osrval--)
+        {
+            brgval = (((srcClock_Hz * 10) / ((osrval + 1) * baudrate_Bps)) - 5) / 10;
+            if (brgval > 0xFFFF)
+            {
+                continue;
+            }
+            baudrate = srcClock_Hz / ((osrval + 1) * (brgval + 1));
+            diff     = baudrate_Bps < baudrate ? baudrate - baudrate_Bps : baudrate_Bps - baudrate;
+            if (diff < best_diff)
+            {
+                best_diff   = diff;
+                best_osrval = osrval;
+                best_brgval = brgval;
+            }
+        }
+
+        /* value over range */
+        if (best_brgval > 0xFFFF)
+        {
+            return kStatus_USART_BaudrateNotSupport;
+        }
+
+        base->OSR = best_osrval;
+        base->BRG = best_brgval;
+    }
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Writes to the TX register using a blocking method.
+ *
+ * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
+ * to have room and writes data to the TX buffer.
+ *
+ * param base USART peripheral base address.
+ * param data Start address of the data to write.
+ * param length Size of the data to write.
+ */
+void USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length)
+{
+    /* Check arguments */
+    assert(!((NULL == base) || (NULL == data)));
+    if ((NULL == base) || (NULL == data))
+    {
+        return;
+    }
+    /* Check whether txFIFO is enabled */
+    if (!(base->FIFOCFG & USART_FIFOCFG_ENABLETX_MASK))
+    {
+        return;
+    }
+    for (; length > 0; length--)
+    {
+        /* Loop until txFIFO get some space for new data */
+        while (!(base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK))
+        {
+        }
+        base->FIFOWR = *data;
+        data++;
+    }
+    /* Wait to finish transfer */
+    while (!(base->STAT & USART_STAT_TXIDLE_MASK))
+    {
+    }
+}
+
+/*!
+ * brief Read RX data register using a blocking method.
+ *
+ * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
+ * have data and read data from the TX register.
+ *
+ * param base USART peripheral base address.
+ * param data Start address of the buffer to store the received data.
+ * param length Size of the buffer.
+ * retval kStatus_USART_FramingError Receiver overrun happened while receiving data.
+ * retval kStatus_USART_ParityError Noise error happened while receiving data.
+ * retval kStatus_USART_NoiseError Framing error happened while receiving data.
+ * retval kStatus_USART_RxError Overflow or underflow rxFIFO happened.
+ * retval kStatus_Success Successfully received all data.
+ */
+status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length)
+{
+    uint32_t status;
+
+    /* check arguments */
+    assert(!((NULL == base) || (NULL == data)));
+    if ((NULL == base) || (NULL == data))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Check whether rxFIFO is enabled */
+    if (!(base->FIFOCFG & USART_FIFOCFG_ENABLERX_MASK))
+    {
+        return kStatus_Fail;
+    }
+    for (; length > 0; length--)
+    {
+        /* loop until rxFIFO have some data to read */
+        while (!(base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK))
+        {
+        }
+        /* check receive status */
+        status = base->STAT;
+        if (status & USART_STAT_FRAMERRINT_MASK)
+        {
+            base->STAT |= USART_STAT_FRAMERRINT_MASK;
+            return kStatus_USART_FramingError;
+        }
+        if (status & USART_STAT_PARITYERRINT_MASK)
+        {
+            base->STAT |= USART_STAT_PARITYERRINT_MASK;
+            return kStatus_USART_ParityError;
+        }
+        if (status & USART_STAT_RXNOISEINT_MASK)
+        {
+            base->STAT |= USART_STAT_RXNOISEINT_MASK;
+            return kStatus_USART_NoiseError;
+        }
+        /* check rxFIFO status */
+        if (base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK)
+        {
+            base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+            base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
+            return kStatus_USART_RxError;
+        }
+
+        *data = base->FIFORD;
+        data++;
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * brief Initializes the USART handle.
+ *
+ * This function initializes the USART handle which can be used for other USART
+ * transactional APIs. Usually, for a specified USART instance,
+ * call this API once to get the initialized handle.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param callback The callback function.
+ * param userData The parameter of the callback function.
+ */
+status_t USART_TransferCreateHandle(USART_Type *base,
+                                    usart_handle_t *handle,
+                                    usart_transfer_callback_t callback,
+                                    void *userData)
+{
+    int32_t instance = 0;
+
+    /* Check 'base' */
+    assert(!((NULL == base) || (NULL == handle)));
+    if ((NULL == base) || (NULL == handle))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    instance = USART_GetInstance(base);
+
+    memset(handle, 0, sizeof(*handle));
+    /* Set the TX/RX state. */
+    handle->rxState = kUSART_RxIdle;
+    handle->txState = kUSART_TxIdle;
+    /* Set the callback and user data. */
+    handle->callback    = callback;
+    handle->userData    = userData;
+    handle->rxWatermark = (usart_rxfifo_watermark_t)USART_FIFOTRIG_RXLVL_GET(base);
+    handle->txWatermark = (usart_txfifo_watermark_t)USART_FIFOTRIG_TXLVL_GET(base);
+
+    FLEXCOMM_SetIRQHandler(base, (flexcomm_irq_handler_t)USART_TransferHandleIRQ, handle);
+
+    /* Enable interrupt in NVIC. */
+    EnableIRQ(s_usartIRQ[instance]);
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the IRQ handler, the USART driver calls the callback
+ * function and passes the ref kStatus_USART_TxIdle as status parameter.
+ *
+ * note The kStatus_USART_TxIdle is passed to the upper layer when all data is written
+ * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX,
+ * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param xfer USART transfer structure. See  #usart_transfer_t.
+ * retval kStatus_Success Successfully start the data transmission.
+ * retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
+ * retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer)
+{
+    /* Check arguments */
+    assert(!((NULL == base) || (NULL == handle) || (NULL == xfer)));
+    if ((NULL == base) || (NULL == handle) || (NULL == xfer))
+    {
+        return kStatus_InvalidArgument;
+    }
+    /* Check xfer members */
+    assert(!((0 == xfer->dataSize) || (NULL == xfer->data)));
+    if ((0 == xfer->dataSize) || (NULL == xfer->data))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* Return error if current TX busy. */
+    if (kUSART_TxBusy == handle->txState)
+    {
+        return kStatus_USART_TxBusy;
+    }
+    else
+    {
+        handle->txData        = xfer->data;
+        handle->txDataSize    = xfer->dataSize;
+        handle->txDataSizeAll = xfer->dataSize;
+        handle->txState       = kUSART_TxBusy;
+        /* Enable transmiter interrupt. */
+        base->FIFOINTENSET |= USART_FIFOINTENSET_TXLVL_MASK;
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * brief Aborts the interrupt-driven data transmit.
+ *
+ * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
+ * how many bytes are still not sent out.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle)
+{
+    assert(NULL != handle);
+
+    /* Disable interrupts */
+    USART_DisableInterrupts(base, kUSART_TxLevelInterruptEnable);
+    /* Empty txFIFO */
+    base->FIFOCFG |= USART_FIFOCFG_EMPTYTX_MASK;
+
+    handle->txDataSize = 0;
+    handle->txState    = kUSART_TxIdle;
+}
+
+/*!
+ * brief Get the number of bytes that have been written to USART TX register.
+ *
+ * This function gets the number of bytes that have been written to USART TX
+ * register by interrupt method.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param count Send bytes count.
+ * retval kStatus_NoTransferInProgress No send in progress.
+ * retval kStatus_InvalidArgument Parameter is invalid.
+ * retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count)
+{
+    assert(NULL != handle);
+    assert(NULL != count);
+
+    if (kUSART_TxIdle == handle->txState)
+    {
+        return kStatus_NoTransferInProgress;
+    }
+
+    *count = handle->txDataSizeAll - handle->txDataSize;
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ *  returns without waiting for all data to be received.
+ * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
+ * the parameter p receivedBytes shows how many bytes are copied from the ring buffer.
+ * After copying, if the data in the ring buffer is not enough to read, the receive
+ * request is saved by the USART driver. When the new data arrives, the receive request
+ * is serviced first. When all data is received, the USART driver notifies the upper layer
+ * through a callback function and passes the status parameter ref kStatus_USART_RxIdle.
+ * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
+ * The 5 bytes are copied to the xfer->data and this function returns with the
+ * parameter p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
+ * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer.
+ * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
+ * to receive data to the xfer->data. When all data is received, the upper layer is notified.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param xfer USART transfer structure, see #usart_transfer_t.
+ * param receivedBytes Bytes received from the ring buffer directly.
+ * retval kStatus_Success Successfully queue the transfer into transmit queue.
+ * retval kStatus_USART_RxBusy Previous receive request is not finished.
+ * retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferReceiveNonBlocking(USART_Type *base,
+                                          usart_handle_t *handle,
+                                          usart_transfer_t *xfer,
+                                          size_t *receivedBytes)
+{
+    uint32_t i;
+    /* How many bytes to copy from ring buffer to user memory. */
+    size_t bytesToCopy = 0U;
+    /* How many bytes to receive. */
+    size_t bytesToReceive;
+    /* How many bytes currently have received. */
+    size_t bytesCurrentReceived;
+    uint32_t regPrimask = 0U;
+
+    /* Check arguments */
+    assert(!((NULL == base) || (NULL == handle) || (NULL == xfer)));
+    if ((NULL == base) || (NULL == handle) || (NULL == xfer))
+    {
+        return kStatus_InvalidArgument;
+    }
+    /* Check xfer members */
+    assert(!((0 == xfer->dataSize) || (NULL == xfer->data)));
+    if ((0 == xfer->dataSize) || (NULL == xfer->data))
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    /* How to get data:
+       1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
+          to uart handle, enable interrupt to store received data to xfer->data. When
+          all data received, trigger callback.
+       2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
+          If there are enough data in ring buffer, copy them to xfer->data and return.
+          If there are not enough data in ring buffer, copy all of them to xfer->data,
+          save the xfer->data remained empty space to uart handle, receive data
+          to this empty space and trigger callback when finished. */
+    if (kUSART_RxBusy == handle->rxState)
+    {
+        return kStatus_USART_RxBusy;
+    }
+    else
+    {
+        bytesToReceive       = xfer->dataSize;
+        bytesCurrentReceived = 0U;
+        /* If RX ring buffer is used. */
+        if (handle->rxRingBuffer)
+        {
+            /* Disable IRQ, protect ring buffer. */
+            regPrimask = DisableGlobalIRQ();
+            /* How many bytes in RX ring buffer currently. */
+            bytesToCopy = USART_TransferGetRxRingBufferLength(handle);
+            if (bytesToCopy)
+            {
+                bytesToCopy = MIN(bytesToReceive, bytesToCopy);
+                bytesToReceive -= bytesToCopy;
+                /* Copy data from ring buffer to user memory. */
+                for (i = 0U; i < bytesToCopy; i++)
+                {
+                    xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
+                    /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
+                    if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
+                    {
+                        handle->rxRingBufferTail = 0U;
+                    }
+                    else
+                    {
+                        handle->rxRingBufferTail++;
+                    }
+                }
+            }
+            /* If ring buffer does not have enough data, still need to read more data. */
+            if (bytesToReceive)
+            {
+                /* No data in ring buffer, save the request to UART handle. */
+                handle->rxData        = xfer->data + bytesCurrentReceived;
+                handle->rxDataSize    = bytesToReceive;
+                handle->rxDataSizeAll = bytesToReceive;
+                handle->rxState       = kUSART_RxBusy;
+            }
+            /* Enable IRQ if previously enabled. */
+            EnableGlobalIRQ(regPrimask);
+            /* Call user callback since all data are received. */
+            if (0 == bytesToReceive)
+            {
+                if (handle->callback)
+                {
+                    handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData);
+                }
+            }
+        }
+        /* Ring buffer not used. */
+        else
+        {
+            handle->rxData        = xfer->data + bytesCurrentReceived;
+            handle->rxDataSize    = bytesToReceive;
+            handle->rxDataSizeAll = bytesToReceive;
+            handle->rxState       = kUSART_RxBusy;
+
+            /* Enable RX interrupt. */
+            base->FIFOINTENSET |= USART_FIFOINTENSET_RXLVL_MASK;
+        }
+        /* Return the how many bytes have read. */
+        if (receivedBytes)
+        {
+            *receivedBytes = bytesCurrentReceived;
+        }
+    }
+    return kStatus_Success;
+}
+
+/*!
+ * brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
+ * how many bytes not received yet.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle)
+{
+    assert(NULL != handle);
+
+    /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
+    if (!handle->rxRingBuffer)
+    {
+        /* Disable interrupts */
+        USART_DisableInterrupts(base, kUSART_RxLevelInterruptEnable);
+        /* Empty rxFIFO */
+        base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+    }
+
+    handle->rxDataSize = 0U;
+    handle->rxState    = kUSART_RxIdle;
+}
+
+/*!
+ * brief Get the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param count Receive bytes count.
+ * retval kStatus_NoTransferInProgress No receive in progress.
+ * retval kStatus_InvalidArgument Parameter is invalid.
+ * retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count)
+{
+    assert(NULL != handle);
+    assert(NULL != count);
+
+    if (kUSART_RxIdle == handle->rxState)
+    {
+        return kStatus_NoTransferInProgress;
+    }
+
+    *count = handle->rxDataSizeAll - handle->rxDataSize;
+
+    return kStatus_Success;
+}
+
+/*!
+ * brief USART IRQ handle function.
+ *
+ * This function handles the USART transmit and receive IRQ request.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle)
+{
+    /* Check arguments */
+    assert((NULL != base) && (NULL != handle));
+
+    bool receiveEnabled = (handle->rxDataSize) || (handle->rxRingBuffer);
+    bool sendEnabled    = handle->txDataSize;
+
+    /* If RX overrun. */
+    if (base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK)
+    {
+        /* Clear rx error state. */
+        base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
+        /* clear rxFIFO */
+        base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+        /* Trigger callback. */
+        if (handle->callback)
+        {
+            handle->callback(base, handle, kStatus_USART_RxError, handle->userData);
+        }
+    }
+    while ((receiveEnabled && (base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK)) ||
+           (sendEnabled && (base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK)))
+    {
+        /* Receive data */
+        if (receiveEnabled && (base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK))
+        {
+            /* Receive to app bufffer if app buffer is present */
+            if (handle->rxDataSize)
+            {
+                *handle->rxData = base->FIFORD;
+                handle->rxDataSize--;
+                handle->rxData++;
+                receiveEnabled = ((handle->rxDataSize != 0) || (handle->rxRingBuffer));
+                if (!handle->rxDataSize)
+                {
+                    if (!handle->rxRingBuffer)
+                    {
+                        base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK;
+                    }
+                    handle->rxState = kUSART_RxIdle;
+                    if (handle->callback)
+                    {
+                        handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData);
+                    }
+                }
+            }
+            /* Otherwise receive to ring buffer if ring buffer is present */
+            else
+            {
+                if (handle->rxRingBuffer)
+                {
+                    /* If RX ring buffer is full, trigger callback to notify over run. */
+                    if (USART_TransferIsRxRingBufferFull(handle))
+                    {
+                        if (handle->callback)
+                        {
+                            handle->callback(base, handle, kStatus_USART_RxRingBufferOverrun, handle->userData);
+                        }
+                    }
+                    /* If ring buffer is still full after callback function, the oldest data is overridden. */
+                    if (USART_TransferIsRxRingBufferFull(handle))
+                    {
+                        /* Increase handle->rxRingBufferTail to make room for new data. */
+                        if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
+                        {
+                            handle->rxRingBufferTail = 0U;
+                        }
+                        else
+                        {
+                            handle->rxRingBufferTail++;
+                        }
+                    }
+                    /* Read data. */
+                    handle->rxRingBuffer[handle->rxRingBufferHead] = base->FIFORD;
+                    /* Increase handle->rxRingBufferHead. */
+                    if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
+                    {
+                        handle->rxRingBufferHead = 0U;
+                    }
+                    else
+                    {
+                        handle->rxRingBufferHead++;
+                    }
+                }
+            }
+        }
+        /* Send data */
+        if (sendEnabled && (base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK))
+        {
+            base->FIFOWR = *handle->txData;
+            handle->txDataSize--;
+            handle->txData++;
+            sendEnabled = handle->txDataSize != 0;
+            if (!sendEnabled)
+            {
+                base->FIFOINTENCLR = USART_FIFOINTENCLR_TXLVL_MASK;
+                handle->txState    = kUSART_TxIdle;
+                if (handle->callback)
+                {
+                    handle->callback(base, handle, kStatus_USART_TxIdle, handle->userData);
+                }
+            }
+        }
+    }
+
+    /* ring buffer is not used */
+    if (NULL == handle->rxRingBuffer)
+    {
+        /* restore if rx transfer ends and rxLevel is different from default value */
+        if ((handle->rxDataSize == 0) && (USART_FIFOTRIG_RXLVL_GET(base) != handle->rxWatermark))
+        {
+            base->FIFOTRIG =
+                (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | USART_FIFOTRIG_RXLVL(handle->rxWatermark);
+        }
+        /* decrease level if rx transfer is bellow */
+        if ((handle->rxDataSize != 0) && (handle->rxDataSize < (USART_FIFOTRIG_RXLVL_GET(base) + 1)))
+        {
+            base->FIFOTRIG =
+                (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | (USART_FIFOTRIG_RXLVL(handle->rxDataSize - 1));
+        }
+    }
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_usart.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_usart.h
new file mode 100755
index 0000000..8a6c5d4
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_usart.h
@@ -0,0 +1,718 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_USART_H_
+#define _FSL_USART_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup usart_driver
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief USART driver version 2.1.0. */
+#define FSL_USART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
+/*@}*/
+
+#define USART_FIFOTRIG_TXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_TXLVL_MASK) >> USART_FIFOTRIG_TXLVL_SHIFT)
+#define USART_FIFOTRIG_RXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_RXLVL_MASK) >> USART_FIFOTRIG_RXLVL_SHIFT)
+
+/*! @brief Error codes for the USART driver. */
+enum _usart_status
+{
+    kStatus_USART_TxBusy              = MAKE_STATUS(kStatusGroup_LPC_USART, 0),  /*!< Transmitter is busy. */
+    kStatus_USART_RxBusy              = MAKE_STATUS(kStatusGroup_LPC_USART, 1),  /*!< Receiver is busy. */
+    kStatus_USART_TxIdle              = MAKE_STATUS(kStatusGroup_LPC_USART, 2),  /*!< USART transmitter is idle. */
+    kStatus_USART_RxIdle              = MAKE_STATUS(kStatusGroup_LPC_USART, 3),  /*!< USART receiver is idle. */
+    kStatus_USART_TxError             = MAKE_STATUS(kStatusGroup_LPC_USART, 7),  /*!< Error happens on txFIFO. */
+    kStatus_USART_RxError             = MAKE_STATUS(kStatusGroup_LPC_USART, 9),  /*!< Error happens on rxFIFO. */
+    kStatus_USART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_LPC_USART, 8),  /*!< Error happens on rx ring buffer */
+    kStatus_USART_NoiseError          = MAKE_STATUS(kStatusGroup_LPC_USART, 10), /*!< USART noise error. */
+    kStatus_USART_FramingError        = MAKE_STATUS(kStatusGroup_LPC_USART, 11), /*!< USART framing error. */
+    kStatus_USART_ParityError         = MAKE_STATUS(kStatusGroup_LPC_USART, 12), /*!< USART parity error. */
+    kStatus_USART_BaudrateNotSupport =
+        MAKE_STATUS(kStatusGroup_LPC_USART, 13), /*!< Baudrate is not support in current clock source */
+};
+
+/*! @brief USART synchronous mode. */
+typedef enum _usart_sync_mode
+{
+    kUSART_SyncModeDisabled = 0x0U, /*!< Asynchronous mode.       */
+    kUSART_SyncModeSlave    = 0x2U, /*!< Synchronous slave mode.  */
+    kUSART_SyncModeMaster   = 0x3U, /*!< Synchronous master mode. */
+} usart_sync_mode_t;
+
+/*! @brief USART parity mode. */
+typedef enum _usart_parity_mode
+{
+    kUSART_ParityDisabled = 0x0U, /*!< Parity disabled */
+    kUSART_ParityEven     = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
+    kUSART_ParityOdd      = 0x3U, /*!< Parity enabled, type odd,  bit setting: PE|PT = 11 */
+} usart_parity_mode_t;
+
+/*! @brief USART stop bit count. */
+typedef enum _usart_stop_bit_count
+{
+    kUSART_OneStopBit = 0U, /*!< One stop bit */
+    kUSART_TwoStopBit = 1U, /*!< Two stop bits */
+} usart_stop_bit_count_t;
+
+/*! @brief USART data size. */
+typedef enum _usart_data_len
+{
+    kUSART_7BitsPerChar = 0U, /*!< Seven bit mode */
+    kUSART_8BitsPerChar = 1U, /*!< Eight bit mode */
+} usart_data_len_t;
+
+/*! @brief USART clock polarity configuration, used in sync mode.*/
+typedef enum _usart_clock_polarity
+{
+    kUSART_RxSampleOnFallingEdge = 0x0U, /*!< Un_RXD is sampled on the falling edge of SCLK. */
+    kUSART_RxSampleOnRisingEdge  = 0x1U, /*!< Un_RXD is sampled on the rising edge of SCLK. */
+} usart_clock_polarity_t;
+
+/*! @brief txFIFO watermark values */
+typedef enum _usart_txfifo_watermark
+{
+    kUSART_TxFifo0 = 0, /*!< USART tx watermark is empty */
+    kUSART_TxFifo1 = 1, /*!< USART tx watermark at 1 item */
+    kUSART_TxFifo2 = 2, /*!< USART tx watermark at 2 items */
+    kUSART_TxFifo3 = 3, /*!< USART tx watermark at 3 items */
+    kUSART_TxFifo4 = 4, /*!< USART tx watermark at 4 items */
+    kUSART_TxFifo5 = 5, /*!< USART tx watermark at 5 items */
+    kUSART_TxFifo6 = 6, /*!< USART tx watermark at 6 items */
+    kUSART_TxFifo7 = 7, /*!< USART tx watermark at 7 items */
+} usart_txfifo_watermark_t;
+
+/*! @brief rxFIFO watermark values */
+typedef enum _usart_rxfifo_watermark
+{
+    kUSART_RxFifo1 = 0, /*!< USART rx watermark at 1 item */
+    kUSART_RxFifo2 = 1, /*!< USART rx watermark at 2 items */
+    kUSART_RxFifo3 = 2, /*!< USART rx watermark at 3 items */
+    kUSART_RxFifo4 = 3, /*!< USART rx watermark at 4 items */
+    kUSART_RxFifo5 = 4, /*!< USART rx watermark at 5 items */
+    kUSART_RxFifo6 = 5, /*!< USART rx watermark at 6 items */
+    kUSART_RxFifo7 = 6, /*!< USART rx watermark at 7 items */
+    kUSART_RxFifo8 = 7, /*!< USART rx watermark at 8 items */
+} usart_rxfifo_watermark_t;
+
+/*!
+ * @brief USART interrupt configuration structure, default settings all disabled.
+ */
+enum _usart_interrupt_enable
+{
+    kUSART_TxErrorInterruptEnable = (USART_FIFOINTENSET_TXERR_MASK),
+    kUSART_RxErrorInterruptEnable = (USART_FIFOINTENSET_RXERR_MASK),
+    kUSART_TxLevelInterruptEnable = (USART_FIFOINTENSET_TXLVL_MASK),
+    kUSART_RxLevelInterruptEnable = (USART_FIFOINTENSET_RXLVL_MASK),
+};
+
+/*!
+ * @brief USART status flags.
+ *
+ * This provides constants for the USART status flags for use in the USART functions.
+ */
+enum _usart_flags
+{
+    kUSART_TxError            = (USART_FIFOSTAT_TXERR_MASK),      /*!< TEERR bit, sets if TX buffer is error */
+    kUSART_RxError            = (USART_FIFOSTAT_RXERR_MASK),      /*!< RXERR bit, sets if RX buffer is error */
+    kUSART_TxFifoEmptyFlag    = (USART_FIFOSTAT_TXEMPTY_MASK),    /*!< TXEMPTY bit, sets if TX buffer is empty */
+    kUSART_TxFifoNotFullFlag  = (USART_FIFOSTAT_TXNOTFULL_MASK),  /*!< TXNOTFULL bit, sets if TX buffer is not full */
+    kUSART_RxFifoNotEmptyFlag = (USART_FIFOSTAT_RXNOTEMPTY_MASK), /*!< RXNOEMPTY bit, sets if RX buffer is not empty */
+    kUSART_RxFifoFullFlag     = (USART_FIFOSTAT_RXFULL_MASK),     /*!< RXFULL bit, sets if RX buffer is full */
+};
+
+/*! @brief USART configuration structure. */
+typedef struct _usart_config
+{
+    uint32_t baudRate_Bps;                /*!< USART baud rate  */
+    usart_parity_mode_t parityMode;       /*!< Parity mode, disabled (default), even, odd */
+    usart_stop_bit_count_t stopBitCount;  /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
+    usart_data_len_t bitCountPerChar;     /*!< Data length - 7 bit, 8 bit  */
+    bool loopback;                        /*!< Enable peripheral loopback */
+    bool enableRx;                        /*!< Enable RX */
+    bool enableTx;                        /*!< Enable TX */
+    bool enableContinuousSCLK;            /*!< USART continuous Clock generation enable in synchronous master mode. */
+    usart_txfifo_watermark_t txWatermark; /*!< txFIFO watermark */
+    usart_rxfifo_watermark_t rxWatermark; /*!< rxFIFO watermark */
+    usart_sync_mode_t syncMode; /*!< Transfer mode select - asynchronous, synchronous master, synchronous slave. */
+    usart_clock_polarity_t clockPolarity; /*!< Selects the clock polarity and sampling edge in synchronous mode. */
+} usart_config_t;
+
+/*! @brief USART transfer structure. */
+typedef struct _usart_transfer
+{
+    uint8_t *data;   /*!< The buffer of data to be transfer.*/
+    size_t dataSize; /*!< The byte count to be transfer. */
+} usart_transfer_t;
+
+/* Forward declaration of the handle typedef. */
+typedef struct _usart_handle usart_handle_t;
+
+/*! @brief USART transfer callback function. */
+typedef void (*usart_transfer_callback_t)(USART_Type *base, usart_handle_t *handle, status_t status, void *userData);
+
+/*! @brief USART handle structure. */
+struct _usart_handle
+{
+    uint8_t *volatile txData;   /*!< Address of remaining data to send. */
+    volatile size_t txDataSize; /*!< Size of the remaining data to send. */
+    size_t txDataSizeAll;       /*!< Size of the data to send out. */
+    uint8_t *volatile rxData;   /*!< Address of remaining data to receive. */
+    volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
+    size_t rxDataSizeAll;       /*!< Size of the data to receive. */
+
+    uint8_t *rxRingBuffer;              /*!< Start address of the receiver ring buffer. */
+    size_t rxRingBufferSize;            /*!< Size of the ring buffer. */
+    volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
+    volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
+
+    usart_transfer_callback_t callback; /*!< Callback function. */
+    void *userData;                     /*!< USART callback function parameter.*/
+
+    volatile uint8_t txState; /*!< TX transfer state. */
+    volatile uint8_t rxState; /*!< RX transfer state */
+
+    usart_txfifo_watermark_t txWatermark; /*!< txFIFO watermark */
+    usart_rxfifo_watermark_t rxWatermark; /*!< rxFIFO watermark */
+};
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+/*! @brief Returns instance number for USART peripheral base address. */
+uint32_t USART_GetInstance(USART_Type *base);
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Initializes a USART instance with user configuration structure and peripheral clock.
+ *
+ * This function configures the USART module with the user-defined settings. The user can configure the configuration
+ * structure and also get the default configuration by using the USART_GetDefaultConfig() function.
+ * Example below shows how to use this API to configure USART.
+ * @code
+ *  usart_config_t usartConfig;
+ *  usartConfig.baudRate_Bps = 115200U;
+ *  usartConfig.parityMode = kUSART_ParityDisabled;
+ *  usartConfig.stopBitCount = kUSART_OneStopBit;
+ *  USART_Init(USART1, &usartConfig, 20000000U);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param config Pointer to user-defined configuration structure.
+ * @param srcClock_Hz USART clock source frequency in HZ.
+ * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * @retval kStatus_InvalidArgument USART base address is not valid
+ * @retval kStatus_Success Status USART initialize succeed
+ */
+status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz);
+
+/*!
+ * @brief Deinitializes a USART instance.
+ *
+ * This function waits for TX complete, disables TX and RX, and disables the USART clock.
+ *
+ * @param base USART peripheral base address.
+ */
+void USART_Deinit(USART_Type *base);
+
+/*!
+ * @brief Gets the default configuration structure.
+ *
+ * This function initializes the USART configuration structure to a default value. The default
+ * values are:
+ *   usartConfig->baudRate_Bps = 115200U;
+ *   usartConfig->parityMode = kUSART_ParityDisabled;
+ *   usartConfig->stopBitCount = kUSART_OneStopBit;
+ *   usartConfig->bitCountPerChar = kUSART_8BitsPerChar;
+ *   usartConfig->loopback = false;
+ *   usartConfig->enableTx = false;
+ *   usartConfig->enableRx = false;
+ *
+ * @param config Pointer to configuration structure.
+ */
+void USART_GetDefaultConfig(usart_config_t *config);
+
+/*!
+ * @brief Sets the USART instance baud rate.
+ *
+ * This function configures the USART module baud rate. This function is used to update
+ * the USART module baud rate after the USART module is initialized by the USART_Init.
+ * @code
+ *  USART_SetBaudRate(USART1, 115200U, 20000000U);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param baudrate_Bps USART baudrate to be set.
+ * @param srcClock_Hz USART clock source frequency in HZ.
+ * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * @retval kStatus_Success Set baudrate succeed.
+ * @retval kStatus_InvalidArgument One or more arguments are invalid.
+ */
+status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz);
+
+/* @} */
+
+/*!
+ * @name Status
+ * @{
+ */
+
+/*!
+ * @brief Get USART status flags.
+ *
+ * This function get all USART status flags, the flags are returned as the logical
+ * OR value of the enumerators @ref _usart_flags. To check a specific status,
+ * compare the return value with enumerators in @ref _usart_flags.
+ * For example, to check whether the TX is empty:
+ * @code
+ *     if (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(USART1))
+ *     {
+ *         ...
+ *     }
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @return USART status flags which are ORed by the enumerators in the _usart_flags.
+ */
+static inline uint32_t USART_GetStatusFlags(USART_Type *base)
+{
+    return base->FIFOSTAT;
+}
+
+/*!
+ * @brief Clear USART status flags.
+ *
+ * This function clear supported USART status flags
+ * Flags that can be cleared or set are:
+ *      kUSART_TxError
+ *      kUSART_RxError
+ * For example:
+ * @code
+ *     USART_ClearStatusFlags(USART1, kUSART_TxError | kUSART_RxError)
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask status flags to be cleared.
+ */
+static inline void USART_ClearStatusFlags(USART_Type *base, uint32_t mask)
+{
+    /* Only TXERR, RXERR fields support write. Remaining fields should be set to zero */
+    base->FIFOSTAT = mask & (USART_FIFOSTAT_TXERR_MASK | USART_FIFOSTAT_RXERR_MASK);
+}
+
+/* @} */
+
+/*!
+ * @name Interrupts
+ * @{
+ */
+
+/*!
+ * @brief Enables USART interrupts according to the provided mask.
+ *
+ * This function enables the USART interrupts according to the provided mask. The mask
+ * is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
+ * For example, to enable TX empty interrupt and RX full interrupt:
+ * @code
+ *     USART_EnableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask The interrupts to enable. Logical OR of @ref _usart_interrupt_enable.
+ */
+static inline void USART_EnableInterrupts(USART_Type *base, uint32_t mask)
+{
+    base->FIFOINTENSET = mask & 0xF;
+}
+
+/*!
+ * @brief Disables USART interrupts according to a provided mask.
+ *
+ * This function disables the USART interrupts according to a provided mask. The mask
+ * is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
+ * This example shows how to disable the TX empty interrupt and RX full interrupt:
+ * @code
+ *     USART_DisableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask The interrupts to disable. Logical OR of @ref _usart_interrupt_enable.
+ */
+static inline void USART_DisableInterrupts(USART_Type *base, uint32_t mask)
+{
+    base->FIFOINTENCLR = mask & 0xF;
+}
+
+/*!
+ * @brief Returns enabled USART interrupts.
+ *
+ * This function returns the enabled USART interrupts.
+ *
+ * @param base USART peripheral base address.
+ */
+static inline uint32_t USART_GetEnabledInterrupts(USART_Type *base)
+{
+    return base->FIFOINTENSET;
+}
+
+/*!
+ * @brief Enable DMA for Tx
+ */
+static inline void USART_EnableTxDMA(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->FIFOCFG |= USART_FIFOCFG_DMATX_MASK;
+    }
+    else
+    {
+        base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK);
+    }
+}
+
+/*!
+ * @brief Enable DMA for Rx
+ */
+static inline void USART_EnableRxDMA(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->FIFOCFG |= USART_FIFOCFG_DMARX_MASK;
+    }
+    else
+    {
+        base->FIFOCFG &= ~(USART_FIFOCFG_DMARX_MASK);
+    }
+}
+
+/*!
+ * @brief Enable CTS.
+ * This function will determine whether CTS is used for flow control.
+ *
+ * @param base    USART peripheral base address.
+ * @param enable  Enable CTS or not, true for enable and false for disable.
+ */
+static inline void USART_EnableCTS(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CFG |= USART_CFG_CTSEN_MASK;
+    }
+    else
+    {
+        base->CFG &= ~USART_CFG_CTSEN_MASK;
+    }
+}
+
+/*!
+ * @brief Continuous Clock generation.
+ * By default, SCLK is only output while data is being transmitted in synchronous mode.
+ * Enable this funciton, SCLK will run continuously in synchronous mode, allowing
+ * characters to be received on Un_RxD independently from transmission on Un_TXD).
+ *
+ * @param base    USART peripheral base address.
+ * @param enable  Enable Continuous Clock generation mode or not, true for enable and false for disable.
+ */
+static inline void USART_EnableContinuousSCLK(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CTL |= USART_CTL_CC_MASK;
+    }
+    else
+    {
+        base->CTL &= ~USART_CTL_CC_MASK;
+    }
+}
+
+/*!
+ * @brief Enable Continuous Clock generation bit auto clear.
+ * While enable this cuntion, the Continuous Clock bit is automatically cleared when a complete
+ * character has been received. This bit is cleared at the same time.
+ *
+ * @param base    USART peripheral base address.
+ * @param enable  Enable auto clear or not, true for enable and false for disable.
+ */
+static inline void USART_EnableAutoClearSCLK(USART_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CTL |= USART_CTL_CLRCCONRX_MASK;
+    }
+    else
+    {
+        base->CTL &= ~USART_CTL_CLRCCONRX_MASK;
+    }
+}
+/* @} */
+
+/*!
+ * @name Bus Operations
+ * @{
+ */
+
+/*!
+ * @brief Writes to the FIFOWR register.
+ *
+ * This function writes data to the txFIFO directly. The upper layer must ensure
+ * that txFIFO has space for data to write before calling this function.
+ *
+ * @param base USART peripheral base address.
+ * @param data The byte to write.
+ */
+static inline void USART_WriteByte(USART_Type *base, uint8_t data)
+{
+    base->FIFOWR = data;
+}
+
+/*!
+ * @brief Reads the FIFORD register directly.
+ *
+ * This function reads data from the rxFIFO directly. The upper layer must
+ * ensure that the rxFIFO is not empty before calling this function.
+ *
+ * @param base USART peripheral base address.
+ * @return The byte read from USART data register.
+ */
+static inline uint8_t USART_ReadByte(USART_Type *base)
+{
+    return base->FIFORD;
+}
+
+/*!
+ * @brief Writes to the TX register using a blocking method.
+ *
+ * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
+ * to have room and writes data to the TX buffer.
+ *
+ * @param base USART peripheral base address.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ */
+void USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length);
+
+/*!
+ * @brief Read RX data register using a blocking method.
+ *
+ * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
+ * have data and read data from the TX register.
+ *
+ * @param base USART peripheral base address.
+ * @param data Start address of the buffer to store the received data.
+ * @param length Size of the buffer.
+ * @retval kStatus_USART_FramingError Receiver overrun happened while receiving data.
+ * @retval kStatus_USART_ParityError Noise error happened while receiving data.
+ * @retval kStatus_USART_NoiseError Framing error happened while receiving data.
+ * @retval kStatus_USART_RxError Overflow or underflow rxFIFO happened.
+ * @retval kStatus_Success Successfully received all data.
+ */
+status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length);
+
+/* @} */
+
+/*!
+ * @name Transactional
+ * @{
+ */
+
+/*!
+ * @brief Initializes the USART handle.
+ *
+ * This function initializes the USART handle which can be used for other USART
+ * transactional APIs. Usually, for a specified USART instance,
+ * call this API once to get the initialized handle.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param callback The callback function.
+ * @param userData The parameter of the callback function.
+ */
+status_t USART_TransferCreateHandle(USART_Type *base,
+                                    usart_handle_t *handle,
+                                    usart_transfer_callback_t callback,
+                                    void *userData);
+
+/*!
+ * @brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the IRQ handler, the USART driver calls the callback
+ * function and passes the @ref kStatus_USART_TxIdle as status parameter.
+ *
+ * @note The kStatus_USART_TxIdle is passed to the upper layer when all data is written
+ * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX,
+ * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param xfer USART transfer structure. See  #usart_transfer_t.
+ * @retval kStatus_Success Successfully start the data transmission.
+ * @retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
+ * @retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer);
+
+/*!
+ * @brief Sets up the RX ring buffer.
+ *
+ * This function sets up the RX ring buffer to a specific USART handle.
+ *
+ * When the RX ring buffer is used, data received are stored into the ring buffer even when the
+ * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received
+ * in the ring buffer, the user can get the received data from the ring buffer directly.
+ *
+ * @note When using the RX ring buffer, one byte is reserved for internal use. In other
+ * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
+ * @param ringBufferSize size of the ring buffer.
+ */
+void USART_TransferStartRingBuffer(USART_Type *base,
+                                   usart_handle_t *handle,
+                                   uint8_t *ringBuffer,
+                                   size_t ringBufferSize);
+
+/*!
+ * @brief Aborts the background transfer and uninstalls the ring buffer.
+ *
+ * This function aborts the background transfer and uninstalls the ring buffer.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the length of received data in RX ring buffer.
+ *
+ * @param handle USART handle pointer.
+ * @return Length of received data in RX ring buffer.
+ */
+size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle);
+
+/*!
+ * @brief Aborts the interrupt-driven data transmit.
+ *
+ * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
+ * how many bytes are still not sent out.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the number of bytes that have been written to USART TX register.
+ *
+ * This function gets the number of bytes that have been written to USART TX
+ * register by interrupt method.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param count Send bytes count.
+ * @retval kStatus_NoTransferInProgress No send in progress.
+ * @retval kStatus_InvalidArgument Parameter is invalid.
+ * @retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
+
+/*!
+ * @brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ *  returns without waiting for all data to be received.
+ * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
+ * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
+ * After copying, if the data in the ring buffer is not enough to read, the receive
+ * request is saved by the USART driver. When the new data arrives, the receive request
+ * is serviced first. When all data is received, the USART driver notifies the upper layer
+ * through a callback function and passes the status parameter @ref kStatus_USART_RxIdle.
+ * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
+ * The 5 bytes are copied to the xfer->data and this function returns with the
+ * parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
+ * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer.
+ * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
+ * to receive data to the xfer->data. When all data is received, the upper layer is notified.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param xfer USART transfer structure, see #usart_transfer_t.
+ * @param receivedBytes Bytes received from the ring buffer directly.
+ * @retval kStatus_Success Successfully queue the transfer into transmit queue.
+ * @retval kStatus_USART_RxBusy Previous receive request is not finished.
+ * @retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferReceiveNonBlocking(USART_Type *base,
+                                          usart_handle_t *handle,
+                                          usart_transfer_t *xfer,
+                                          size_t *receivedBytes);
+
+/*!
+ * @brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
+ * how many bytes not received yet.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param count Receive bytes count.
+ * @retval kStatus_NoTransferInProgress No receive in progress.
+ * @retval kStatus_InvalidArgument Parameter is invalid.
+ * @retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
+
+/*!
+ * @brief USART IRQ handle function.
+ *
+ * This function handles the USART transmit and receive IRQ request.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle);
+
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_USART_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_wtimer.c b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_wtimer.c
new file mode 100755
index 0000000..5ca3070
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_wtimer.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/****************************************************************************/
+/***        Include files                                                 ***/
+/****************************************************************************/
+
+#include "fsl_wtimer.h"
+#include "fsl_clock.h"
+#include "fsl_device_registers.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.wtimer"
+#endif
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+//#define WTIMER_TRACE
+
+#ifndef WTIMER_TRACE
+#define PRINTF(...)
+#else
+#include "fsl_debug_console.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.wtimer"
+#endif
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+typedef struct
+{
+    uint32_t wkt_stat_timeout_mask;
+    uint32_t wkt_stat_running_mask;
+    uint32_t wkt_ctrl_clk_ena_mask;
+    uint32_t wkt_ctrl_ena_mask;
+    uint32_t wkt_intenclr_timeout_mask;
+    volatile uint32_t *wkt_load_lsb_reg;
+    volatile uint32_t *wkt_load_msb_reg;
+    const volatile uint32_t *wkt_val_lsb_reg;
+    const volatile uint32_t *wkt_val_msb_reg;
+    uint8_t wkt_irq_id;
+} timer_param_t;
+
+static const timer_param_t timer_param[2] = {
+    {
+        .wkt_stat_timeout_mask     = SYSCON_WKT_STAT_WKT0_TIMEOUT_MASK,
+        .wkt_stat_running_mask     = SYSCON_WKT_STAT_WKT0_RUNNING_MASK,
+        .wkt_ctrl_clk_ena_mask     = SYSCON_WKT_CTRL_WKT0_CLK_ENA_MASK,
+        .wkt_ctrl_ena_mask         = SYSCON_WKT_CTRL_WKT0_ENA_MASK,
+        .wkt_intenclr_timeout_mask = SYSCON_WKT_INTENSET_WKT0_TIMEOUT_MASK,
+        .wkt_load_lsb_reg          = &SYSCON->WKT_LOAD_WKT0_LSB,
+        .wkt_load_msb_reg          = &SYSCON->WKT_LOAD_WKT0_MSB,
+        .wkt_val_lsb_reg           = &SYSCON->WKT_VAL_WKT0_LSB,
+        .wkt_val_msb_reg           = NULL,
+        .wkt_irq_id                = WAKE_UP_TIMER0_IRQn,
+    },
+    {
+        .wkt_stat_timeout_mask     = SYSCON_WKT_STAT_WKT1_TIMEOUT_MASK,
+        .wkt_stat_running_mask     = SYSCON_WKT_STAT_WKT1_RUNNING_MASK,
+        .wkt_ctrl_clk_ena_mask     = SYSCON_WKT_CTRL_WKT1_CLK_ENA_MASK,
+        .wkt_ctrl_ena_mask         = SYSCON_WKT_CTRL_WKT1_ENA_MASK,
+        .wkt_intenclr_timeout_mask = SYSCON_WKT_INTENSET_WKT1_TIMEOUT_MASK,
+        .wkt_load_lsb_reg          = &SYSCON->WKT_LOAD_WKT1,
+        .wkt_load_msb_reg          = NULL,
+        .wkt_val_lsb_reg           = &SYSCON->WKT_VAL_WKT1,
+        .wkt_val_msb_reg           = NULL,
+        .wkt_irq_id                = WAKE_UP_TIMER1_IRQn,
+    },
+};
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * brief Enable the clocks to the peripheral (functional clock and AHB clock)
+ *
+ * note This function does not reset the wake timer peripheral. Wake timer reset is done in PWRM_vColdStart() from the
+ * PWRM framework module if integrated
+ * If PWRM framework module is integrated, WTIMER_Init() is called in PWRM_vInit() for power modes with Oscillator ON.
+ *
+ */
+void WTIMER_Init(void)
+{
+    /* set clock and divider */
+    SYSCON->AHBCLKCTRLS[0] |= SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_MASK;
+    SYSCON->WKTCLKSEL = SYSCON_WKTCLKSEL_SEL(0); // & ~SYSCON_WKTCLKSEL_SEL_MASK ;
+}
+
+/*!
+ * brief Disable the clocks to the peripheral (functional clock and AHB clock)
+ *
+ * note This function does not reset the wake timer peripheral.
+ *
+ */
+void WTIMER_DeInit(void)
+{
+    /* set clock and divider */
+    SYSCON->AHBCLKCTRLS[0] &= ~SYSCON_AHBCLKCTRLSET0_WAKE_UP_TIMERS_CLK_SET_MASK;
+    SYSCON->WKTCLKSEL = SYSCON_WKTCLKSEL_SEL(2); // No Clock ;
+}
+
+/*!
+ * brief Gets the Timer status flags.
+ *
+ * param timer_id   Wtimer Id
+ *
+ * return The status flags.
+ */
+WTIMER_status_t WTIMER_GetStatusFlags(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+    WTIMER_status_t status             = WTIMER_STATUS_NOT_RUNNING;
+    uint32_t stat                      = SYSCON->WKT_STAT;
+
+    if (stat & timer_param_l->wkt_stat_timeout_mask)
+    {
+        status = WTIMER_STATUS_EXPIRED;
+        PRINTF("WakeTimerFiredStatus[%d] expired\n", timer_id);
+    }
+    else if (stat & timer_param_l->wkt_stat_running_mask)
+    {
+        status = WTIMER_STATUS_RUNNING;
+        PRINTF("WakeTimerFiredStatus[%d] running\n", timer_id);
+    }
+
+    return status;
+}
+
+/*!
+ * brief Enable the selected Timer interrupts.
+ * The application shall implement the Wake timer ISR
+ *
+ * param timer_id   Wtimer Id
+ */
+void WTIMER_EnableInterrupts(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+
+    EnableIRQ((IRQn_Type)timer_param_l->wkt_irq_id);
+    SYSCON->WKT_INTENSET = timer_param_l->wkt_intenclr_timeout_mask;
+}
+
+/*!
+ * brief Starts the Timer counter.
+ * The function performs:
+ * -stop the timer if running, clear the status and interrupt flag if set (WTIMER_ClearStatusFlags())
+ * -set the counter value
+ * -start the timer
+ *
+ * param timer_id   Wtimer Id
+ * param count      number of 32KHz clock periods before expiration
+ */
+void WTIMER_StartTimer(WTIMER_timer_id_t timer_id, uint32_t count)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+
+    PRINTF("-->> vAHI_WakeTimerStart[%d] : STAT=%x count=%d WKT_INTSTAT=%x count=%d\n", timer_id, SYSCON->WKT_STAT,
+           count, SYSCON->WKT_INTSTAT, count);
+
+    /* enable the clock */
+    SYSCON->WKT_CTRL |= timer_param_l->wkt_ctrl_clk_ena_mask;
+
+    /* clear timeout flag if set */
+    SYSCON->WKT_STAT = timer_param_l->wkt_stat_timeout_mask;
+
+    /* stop timer if running */
+    SYSCON->WKT_CTRL &= ~(timer_param_l->wkt_ctrl_ena_mask);
+
+    /* make sure the timer is really stopped */
+    while ((SYSCON->WKT_STAT & (timer_param_l->wkt_stat_running_mask)) == timer_param_l->wkt_stat_running_mask)
+    {
+        __asm volatile("nop");
+    }
+
+    *(timer_param_l->wkt_load_lsb_reg) = count;
+    if (timer_id == WTIMER_TIMER0_ID)
+    {
+        *(timer_param_l->wkt_load_msb_reg) = 0;
+    }
+
+    /* enable the timer */
+    SYSCON->WKT_CTRL |= timer_param_l->wkt_ctrl_ena_mask;
+
+    while ((SYSCON->WKT_STAT & (timer_param_l->wkt_stat_running_mask)) == 0)
+    {
+        __asm volatile("nop");
+    }
+
+    PRINTF("<<-- vAHI_WakeTimerStart[%d] : STAT=%x WKT_INTSTAT=%x\n", timer_id, SYSCON->WKT_STAT, SYSCON->WKT_INTSTAT);
+}
+
+/*!
+ * brief Read the LSB counter of the wake timer
+ * API checks the next counter update (next 32KHz clock edge) so the value is uptodate
+ * Important note : The counter shall be running otherwise, the API gets locked and never return
+ *
+ * param timer_id   Wtimer Id
+ * return  32KHz clock frequency (number of 32KHz clock in one sec) - expect to have 32768
+ */
+uint32_t WTIMER_ReadTimerSafe(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l    = &timer_param[timer_id];
+    volatile uint32_t u32CurrentCount_ini = *timer_param_l->wkt_val_lsb_reg;
+    volatile uint32_t u32CurrentCount     = *timer_param_l->wkt_val_lsb_reg;
+
+    while (u32CurrentCount == u32CurrentCount_ini)
+        u32CurrentCount = *timer_param_l->wkt_val_lsb_reg;
+
+    return u32CurrentCount;
+}
+
+/*!
+ * brief Read the LSB counter of the wake timer
+ * This API is unsafe. If the counter has just been started, the counter value may not be
+ * up to date until the next 32KHz clock edge.
+ * Use WTIMER_ReadTimerSafe() instead
+ *
+ * param timer_id   Wtimer Id
+ * return  counter value - number of ticks before expiration if running
+ */
+uint32_t WTIMER_ReadTimer(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+    volatile uint32_t u32CurrentCount  = *timer_param_l->wkt_val_lsb_reg;
+
+    return u32CurrentCount;
+}
+
+/*!
+ * brief Clears the Timer status flags if expired and clear the pendng interrupt if active
+ * it needs to be called in ISR
+ *
+ * param timer_id   Wtimer Id
+ */
+void WTIMER_ClearStatusFlags(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+
+    /* clear expiration flag */
+    SYSCON->WKT_STAT = timer_param_l->wkt_stat_timeout_mask;
+
+    /* clear interrupt if pending */
+    NVIC_ClearPendingIRQ((IRQn_Type)timer_param_l->wkt_irq_id);
+}
+
+/*!
+ * brief Stops the Timer counter.
+ *
+ * param timer_id   Wtimer Id
+ */
+void WTIMER_StopTimer(WTIMER_timer_id_t timer_id)
+{
+    const timer_param_t *timer_param_l = &timer_param[timer_id];
+
+    /* Stop timer */
+    SYSCON->WKT_CTRL &= ~(timer_param_l->wkt_ctrl_ena_mask);
+
+    /* make sure the timer is really stopped */
+    while ((SYSCON->WKT_STAT & (timer_param_l->wkt_stat_running_mask)) == timer_param_l->wkt_stat_running_mask)
+    {
+        __asm volatile("nop");
+    }
+
+    WTIMER_ClearStatusFlags(timer_id);
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_wtimer.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_wtimer.h
new file mode 100755
index 0000000..1897309
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/fsl_wtimer.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_WTIMER_H_
+#define _FSL_WTIMER_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup wtimer
+ * @{
+ */
+
+/*! @file */
+
+/**
+ * Wake timers provide wakeup capabilities in sleep modes where 32KHz clock is kept active.
+ * Wake timer 0 is a 48bit based counter while wake timer 1 is 32bit based counter.
+ * A special API functions WTIMER_StartTimerLarge(0 and WTIMER_StartTimerLarge() are provided to access the 48bit
+ * counter. The Wake timer 1 is to be used bu the PWRM framework. It shall not be used by the Application directly. API
+ * provides the capability to enable and disable interrupts. The application shall implement the Wake timer ISR on its
+ * side. The wake timer ISR prototypes are : void WAKE_UP_TIMER0_IRQHandler(void); and void
+ * WAKE_UP_TIMER1_IRQHandler(void); The Application shall correctly the 32KHz source amoung the FRO32 or Crystal 32KHz
+ * using CLOCK_EnableClock() API in fsl_clock.h The APi provides the capability to calibrate the 32KHz clock versus a
+ * high reference clock (32MHz crystal).
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+#define FSL_WTIMER_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
+/*@}*/
+
+typedef enum
+{
+    WTIMER_TIMER0_ID = 0,
+    WTIMER_TIMER1_ID = 1,
+} WTIMER_timer_id_t;
+
+typedef enum
+{
+    WTIMER_STATUS_NOT_RUNNING = 0,
+    WTIMER_STATUS_RUNNING     = 1,
+    WTIMER_STATUS_EXPIRED     = 2,
+} WTIMER_status_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Enable the clocks to the peripheral (functional clock and AHB clock)
+ *
+ * @note This function does not reset the wake timer peripheral. Wake timer reset is done in PWRM_vColdStart() from the
+ * PWRM framework module if integrated If PWRM framework module is integrated, WTIMER_Init() is called in PWRM_vInit()
+ * for power modes with Oscillator ON.
+ *
+ */
+void WTIMER_Init(void);
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Disable the clocks to the peripheral (functional clock and AHB clock)
+ *
+ * @note This function does not reset the wake timer peripheral.
+ *
+ */
+void WTIMER_DeInit(void);
+
+/*!
+ * @brief Enable the selected Timer interrupts.
+ * The application shall implement the Wake timer ISR
+ *
+ * @param timer_id   Wtimer Id
+ */
+void WTIMER_EnableInterrupts(WTIMER_timer_id_t timer_id);
+
+#ifdef NOT_IMPLEMENTED_YET
+/*!
+ * @brief Disable the selected Timer interrupts.
+ * Interrupts are disabled by default. The API shall be called if the interrupt was enabled before.
+ *
+ * @param timer_id   Wtimer Id
+ */
+void WTIMER_DisableInterrupts(WTIMER_timer_id_t timer_id);
+#endif
+
+/*!
+ * @brief Gets the Timer status flags.
+ *
+ * @param timer_id   Wtimer Id
+ *
+ * @return The status flags.
+ */
+WTIMER_status_t WTIMER_GetStatusFlags(WTIMER_timer_id_t timer_id);
+
+/*!
+ * @brief Clears the Timer status flags if expired and clear the pendng interrupt if active
+ * it needs to be called in ISR
+ *
+ * @param timer_id   Wtimer Id
+ */
+void WTIMER_ClearStatusFlags(WTIMER_timer_id_t timer_id);
+
+/*!
+ * @brief Starts the Timer counter.
+ * The function performs:
+ * -stop the timer if running, clear the status and interrupt flag if set (WTIMER_ClearStatusFlags())
+ * -set the counter value
+ * -start the timer
+ *
+ * @param timer_id   Wtimer Id
+ * @param count      number of 32KHz clock periods before expiration
+ */
+void WTIMER_StartTimer(WTIMER_timer_id_t timer_id, uint32_t count);
+
+/*!
+ * @brief Stops the Timer counter.
+ *
+ * @param timer_id   Wtimer Id
+ */
+void WTIMER_StopTimer(WTIMER_timer_id_t timer_id);
+
+/*!
+ * @brief Calibrate the 32KHz clock to be used by the wake timer versus the 32MHz crystal clock source
+ * The Applicaton shall switches OFF the 32MHz clock if no longer used by the chip using CLOCK_DisableClock() in
+ * fsl_clock.h
+ *
+ * @return  32KHz clock frequency (number of 32KHz clock in one sec) - expect to have 32768
+ */
+uint32_t WTIMER_CalibrateTimer(void);
+
+/*!
+ * @brief Read the LSB counter of the wake timer
+ * This API is unsafe. If the counter has just been started, the counter value may not be
+ * up to date until the next 32KHz clock edge.
+ * Use WTIMER_ReadTimerSafe() instead
+ *
+ * @param timer_id   Wtimer Id
+ * @return  counter value - number of ticks before expiration if running
+ */
+uint32_t WTIMER_ReadTimer(WTIMER_timer_id_t timer_id);
+
+/*!
+ * @brief Read the LSB counter of the wake timer
+ * API checks the next counter update (next 32KHz clock edge) so the value is uptodate
+ * Important note : The counter shall be running otherwise, the API gets locked and never return
+ *
+ * @param timer_id   Wtimer Id
+ * @return  32KHz clock frequency (number of 32KHz clock in one sec) - expect to have 32768
+ */
+uint32_t WTIMER_ReadTimerSafe(WTIMER_timer_id_t timer_id);
+
+#ifdef NOT_IMPLEMENTED_YET
+/*!
+ * @brief Starts the Timer counter.
+ *
+ * @param timer_id   Wtimer Id
+ * @param count      number of 32KHz clock periods before expiration
+ */
+void WTIMER_StartTimerLarge(WTIMER_timer_id_t timer_id, uint64_t count);
+
+/*!
+ * @brief Read the LSB + MSB counter of the 48bit wake timer, Read the LSB counter for 32bit wale timer
+ *
+ *
+ * @param timer_id   Wtimer Id
+ * @return wake timer counter
+ */
+uint64_t WTIMER_ReadTimerLarge(WTIMER_timer_id_t timer_id);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_WTIMER_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_aes.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_aes.h
new file mode 100755
index 0000000..1e45b24
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_aes.h
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _ROM_AES_H
+#define _ROM_AES_H
+
+/*******************
+ * INCLUDE FILES    *
+ ********************/
+#include <stdint.h>
+#include "rom_common.h"
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+typedef uint32_t ErrorCode_t;  /*!< enum defined in error.h */
+
+/*******************
+ * EXPORTED MACROS  *
+ ********************/
+
+#define AES_ENCDEC_MODE (1 << 0)
+#define AES_GF128HASH_MODE (2 << 0)
+#define AES_ENDEC_GF128HASH_MODE (3 << 0)
+#define AES_GF128_SEL (1 << 2)
+#define AES_INT_BSWAP (1 << 4)
+#define AES_INT_WSWAP (1 << 5)
+#define AES_OUTT_BSWAP (1 << 6)
+#define AES_OUTT_WSWAP (1 << 7)
+#define AES_KEYSIZE_128 (0 << 8)
+#define AES_KEYSIZE_192 (1 << 8)
+#define AES_KEYSIZE_256 (2 << 8)
+#define AES_INB_FSEL(n) ((n) << 16) /*!< n->1=Input Text, n->2=Holding, n->3=Input Text XOR Holding */
+#define AES_HOLD_FSEL(n) \
+    ((n) << 20) /*!< n->0=Counter, n->1=Input Text, n->2=Output Block, n->3=Input Text XOR Output Block */
+#define AES_OUTT_FSEL(n) ((n) << 24) /*!< n->0=OUTT, n->1=Output Block XOR Input Text, n->2=Output Block XOR Holding */
+
+/*********************
+ * EXPORTED TYPEDEFS  *
+ **********************/
+
+/*! @brief AES setup modes */
+typedef enum
+{
+    AES_MODE_ECB_ENCRYPT = 0,
+    AES_MODE_ECB_DECRYPT,
+    AES_MODE_CBC_ENCRYPT,
+    AES_MODE_CBC_DECRYPT,
+    AES_MODE_CFB_ENCRYPT,
+    AES_MODE_CFB_DECRYPT,
+    AES_MODE_OFB,
+    AES_MODE_CTR,
+    AES_MODE_GCM_TAG,
+    AES_MODE_UNUSED = 0x7FFFFFFF /*!< Not used, but forces enum to 32-bit size */
+} AES_MODE_T;
+
+/*! @brief Size of the AES key */
+typedef enum
+{
+    AES_KEY_128BITS = 0, /*!< KEY size 128 bits */
+    AES_KEY_192BITS, /*!< KEY size 192 bits */
+    AES_KEY_256BITS, /*!< KEY size 256 bits */
+    AES_FVAL = 0x7FFFFFFF /*!< Not used, but forces enum to 32-bit size and unsigned */
+} AES_KEY_SIZE_T;
+
+/*******************
+ * EXPORTED DATA    *
+ ********************/
+
+/********************************
+ * EXPORTED FUNCTIONS PROTOTYPES *
+ *********************************/
+
+/**
+ * @brief	Initialize the AES
+ *
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	Driver does not enable AES clock, power, or perform reset peripheral (if needed).
+ */
+static inline ErrorCode_t aesInit(void)
+{
+    ErrorCode_t (*p_aesInit)(void);
+    p_aesInit = (ErrorCode_t (*)(void))0x03001161U;
+
+    return p_aesInit();
+}
+
+/**
+ * @brief	AES control function, byte write (useful for writing configuration register)
+ * @brief	offset	: Register offset in AES, 32-bit aligned value
+ * @brief	val8	: 8-bit value to write
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it perform byte level write access to a register.
+ *			This function is not meant to be public.
+ */
+static inline void aesWriteByte(uint32_t offset, uint8_t val8)
+{
+    void (*p_aesWriteByte)(uint32_t offset, uint8_t val8);
+    p_aesWriteByte = (void (*)(uint32_t offset, uint8_t val8))0x03001175U;
+
+    p_aesWriteByte(offset, val8);
+}
+
+/**
+ * @brief	AES control function, word write
+ * @brief	offset	: Register offset in AES, 32-bit aligned value
+ * @brief	val32	: 32-bit value to write
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it for write access to a register. This function
+ *			is not meant to be public.
+ */
+static inline void aesWrite(uint32_t offset, uint32_t val32)
+{
+    void (*p_aesWrite)(uint32_t offset, uint32_t val32);
+    p_aesWrite = (void (*)(uint32_t offset, uint32_t val32))0x0300118dU;
+
+    p_aesWrite(offset, val32);
+}
+
+/**
+ * @brief	AES control function, word read
+ * @brief	offset	: Register offset in AES, 32-bit aligned value
+ * @brief	pVal32	: Pointer to 32-bit area to read into
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it for read access to a register. This function
+ *			is not meant to be public.
+ */
+static inline void aesRead(uint32_t offset, uint32_t *pVal32)
+{
+    void (*p_aesRead)(uint32_t offset, uint32_t *pVal32);
+    p_aesRead = (void (*)(uint32_t offset, uint32_t *pVal32))0x030011a5U;
+
+    p_aesRead(offset, pVal32);
+}
+
+/**
+ * @brief	AES control function, block write (used for multi-register block writes)
+ * @brief	offset		: Register offset in AES, 32-bit aligned value
+ * @brief	pVal32		: Pointer to 32-bit array to write
+ * @brief	numBytes	: Number of bytes to write, must be 32-bit aligned
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it for write access to a register. This function
+ *			is not meant to be public. Writes occur in 32-bit chunks.
+ */
+static inline void aesWriteBlock(uint32_t offset, uint32_t *pVal32, uint32_t numBytes)
+{
+    void (*p_aesWriteBlock)(uint32_t offset, uint32_t *pVal32, uint32_t numBytes);
+    p_aesWriteBlock = (void (*)(uint32_t offset, uint32_t *pVal32, uint32_t numBytes))0x030011c1U;
+
+    p_aesWriteBlock(offset, pVal32, numBytes);
+}
+
+/**
+ * @brief	AES control function, block read (used for multi-register block read)
+ * @brief	offset		: Register offset in AES, 32-bit aligned value
+ * @brief	pVal32		: Pointer to 32-bit array to read into
+ * @brief	numBytes	: Number of bytes to read, must be 32-bit aligned
+ * @return	Nothing
+ * @note	This is an obfuscated function available from the ROM API as a 2nd level API
+ *			call. An application can used it for read access to a register. This function
+ *			is not meant to be public. Reads occur in 32-bit chunks. Read data if undefined
+ *			if AES not present.
+ */
+static inline void aesReadBlock(uint32_t offset, uint32_t *pVal32, uint32_t numBytes)
+{
+    void (*p_aesReadBlock)(uint32_t offset, uint32_t *pVal32, uint32_t numBytes);
+    p_aesReadBlock = (void (*)(uint32_t offset, uint32_t *pVal32, uint32_t numBytes))0x030011e9U;
+
+    p_aesReadBlock(offset, pVal32, numBytes);
+}
+
+/**
+ * @brief	Sets up the AES mode
+ * @param	wipe	: use true to invalidate AES key and disable cipher
+ * @param	flags	: Applies extra flags (Or'ed in config), normally should be 0, useful for swap bits only
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesMode(AES_MODE_T modeVal, uint32_t flags)
+{
+    ErrorCode_t (*p_aesMode)(AES_MODE_T modeVal, uint32_t flags);
+    p_aesMode = (ErrorCode_t (*)(AES_MODE_T modeVal, uint32_t flags))0x03001211U;
+
+    return p_aesMode(modeVal, flags);
+}
+
+/**
+ * @brief	Aborts optional AES operation and wipes AES engine
+ * @param	wipe	: use true to invalidate AES key and disable cipher
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesAbort(int wipe)
+{
+    ErrorCode_t (*p_aesAbort)(int wipe);
+    p_aesAbort = (ErrorCode_t (*)(int wipe))0x03001269U;
+
+    return p_aesAbort(wipe);
+}
+
+/**
+ * @brief	Loads the increment that is used when in counter modes in the AES block
+ * @param	counter	: 32-bit initial increment counter value
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesLoadCounter(uint32_t counter)
+{
+    ErrorCode_t (*p_aesLoadCounter)(uint32_t counter);
+    p_aesLoadCounter = (ErrorCode_t (*)(uint32_t counter))0x03001291U;
+
+    return p_aesLoadCounter(counter);
+}
+
+/**
+ * @brief	Loads the passed (software) key into the AES block
+ * @param	keySize	: 0 = 128-bits, 1 = 192-bits, 2 = 256-bits, all other values are invalid (AES_KEY_SIZE_T)
+ * @param	key		: Pointer to up to a 256-bit key array
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesLoadKeyFromSW(AES_KEY_SIZE_T keySize, uint32_t *key)
+{
+    ErrorCode_t (*p_aesLoadKeyFromSW)(AES_KEY_SIZE_T keySize, uint32_t *key);
+    p_aesLoadKeyFromSW = (ErrorCode_t (*)(AES_KEY_SIZE_T keySize, uint32_t *key))0x030012a9U;
+
+    return p_aesLoadKeyFromSW(keySize, key);
+}
+
+/**
+ * @brief	Loads the Initialization Vector (IV) into the AES block
+ * @param	iv	: 32-bit initialization vector
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ */
+static inline ErrorCode_t aesLoadIV(uint32_t *pIv)
+{
+    ErrorCode_t (*p_aesLoadIV)(uint32_t *pIv);
+    p_aesLoadIV = (ErrorCode_t (*)(uint32_t *pIv))0x030012fdU;
+
+    return p_aesLoadIV(pIv);
+}
+
+/**
+ * @brief	Process AES blocks (descrypt or encrypt)
+ * @param	pBlockIn	: 32-bit aligned pointer to input block of data
+ * @param	pBlockOut	: 32-bit aligned pointer to output block of data
+ * @param	numBlocks	: Number of blocks to process, block size = 128 bits
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	The AES mode and key must be setup prior to calling this function.
+ *			For encryption. the plain text is used as the input and encrypted
+ *			text is output. For descryption, plain text is output while
+ *			encrypted text is input.
+ */
+static inline ErrorCode_t aesProcess(uint32_t *pBlockIn, uint32_t *pBlockOut, uint32_t numBlocks)
+{
+    ErrorCode_t (*p_aesProcess)(uint32_t *pBlockIn, uint32_t *pBlockOut, uint32_t numBlocks);
+    p_aesProcess = (ErrorCode_t (*)(uint32_t *pBlockIn, uint32_t *pBlockOut, uint32_t numBlocks))0x030013d1U;
+
+    return p_aesProcess(pBlockIn, pBlockOut, numBlocks);
+}
+
+/**
+ * @brief	Sets the Y input of the GF128 hash used in GCM mode
+ * @param	pYGf128	: Y input of GF128 hash (4x32-bit words)
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	Calling this function will reset the hash logic.
+ */
+static inline ErrorCode_t aesWriteYInputGf128(uint32_t *pYGf128)
+{
+    ErrorCode_t (*p_aesWriteYInputGf128)(uint32_t *pYGf128);
+    p_aesWriteYInputGf128 = (ErrorCode_t (*)(uint32_t *pYGf128))0x0300132dU;
+
+    return p_aesWriteYInputGf128(pYGf128);
+}
+
+/**
+ * @brief	Reads the results of the GF128(Z) hash used in GCM mode
+ * @param	pGf128Hash	: Array of 4x32-bit words to read hash into
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	Value is undefined if AES is not present.
+ */
+static inline ErrorCode_t aesReadGf128Hash(uint32_t *pGf128Hash)
+{
+    ErrorCode_t (*p_aesReadGf128Hash)(uint32_t *pGf128Hash);
+    p_aesReadGf128Hash = (ErrorCode_t (*)(uint32_t *pGf128Hash))0x0300135dU;
+
+    return p_aesReadGf128Hash(pGf128Hash);
+}
+
+/**
+ * @brief	Reads the GCM tag
+ * @param	pGcmTag	: Array of 4x32-bit words to read GCM tage into
+ * @return	LPC_OK on success, or an error code (ERRORCODE_T) on failure
+ * @note	The GCM tage is an XOR value of the Output Text and GF128(Z) hash value.
+ *			Value is undefined if AES is not present.
+ */
+static inline ErrorCode_t aesReadGcmTag(uint32_t *pGcmTag)
+{
+    ErrorCode_t (*p_aesReadGcmTag)(uint32_t *pGcmTag);
+    p_aesReadGcmTag = (ErrorCode_t (*)(uint32_t *pGcmTag))0x0300138dU;
+
+    return p_aesReadGcmTag(pGcmTag);
+}
+
+/**
+ * @brief	Returns the version of the AES driver in ROM
+ * @return	Driver version, example 0x00000100 = v1.0
+ */
+static inline uint32_t aesGetDriverVersion(void)
+{
+    uint32_t (*p_aesGetDriverVersion)(void);
+    p_aesGetDriverVersion = (uint32_t (*)(void))0x030013bdU;
+
+    return p_aesGetDriverVersion();
+}
+
+/**
+ * @brief	Returns status of AES IP block (supported or not)
+ * @return	LPC_OK if enabled, ERR_SEC_AES_NOT_SUPPORTED if not supported
+ */
+static inline ErrorCode_t aesIsSupported(void)
+{
+    ErrorCode_t (*p_aesIsSupported)(void);
+    p_aesIsSupported = (ErrorCode_t (*)(void))0x0300115dU;
+
+    return p_aesIsSupported();
+}
+
+#endif /* _ROM_AES_H      Do not add any thing below this line */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_api.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_api.h
new file mode 100755
index 0000000..569bb7e
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_api.h
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_API_H_
+#define ROM_API_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stdint.h>
+#include "rom_common.h"
+#include "rom_psector.h"
+#include "flash_header.h"
+#include "rom_aes.h"
+#include "rom_efuse.h"
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.jn_romapi"
+#endif
+/*! @name Driver version */
+/*@{*/
+/*! @brief JN_ROMAPI driver version 2.0.0. */
+#define FSL_JN_ROMAPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
+/*@}*/
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/*!
+ * @brief Convert logical address into physical address, based on SYSCOM MEMORYREMAP register
+ *
+ * The chip has a remapping capability that allows to remap internal flash areas.
+ * This feature is part of the firmware update mechanism (OTA).
+ *
+ * @param  address logical address to convert
+ *
+ * @return  physical address
+ *
+ */
+static inline uint32_t BOOT_RemapAddress(uint32_t address)
+{
+    uint32_t (*p_BOOT_RemapAddress)(uint32_t address);
+    p_BOOT_RemapAddress = (uint32_t(*)(uint32_t address))0x03000dc9U;
+
+    return p_BOOT_RemapAddress(address);
+}
+
+/*! @brief IMAGE_DATA_T image node : element of single link chained list of images found in flash */
+typedef struct _image_data_t
+{
+    uint32_t version;           /*!< version number found in image  */
+    uint32_t address;           /*!< start address of image */
+    struct _image_data_t *next; /*!< pointer on next IMAGE_DATA_T in list */
+} IMAGE_DATA_T;
+
+/*! @brief IMAGE_VERIFY_T function pointer : verification function  e.g. boot_Verify_eScoreImageList */
+typedef uint32_t (*IMAGE_VERIFY_T)(IMAGE_DATA_T *list_head);
+
+/*!
+ * @brief Parse the image chained list and select the first valid entry.
+ *
+ * The image list is already sorted by version number. Compare image version against
+ * Min version read from PSECT. If it is greater than or equal to Min version, perform the
+ * RSA authentication over the image using the ket found in PFLASH if any.
+ * see IMAGE_VERIFY_T
+ * @param  list_head sorted list of images
+ *
+ * @return  selected image start address
+ *
+ */
+static inline uint32_t boot_Verify_eScoreImageList(IMAGE_DATA_T *list_head)
+{
+    uint32_t (*p_boot_Verify_eScoreImageList)(IMAGE_DATA_T * list_head);
+    p_boot_Verify_eScoreImageList = (uint32_t(*)(IMAGE_DATA_T * list_head))0x030003e5U;
+
+    return p_boot_Verify_eScoreImageList(list_head);
+}
+
+/*!
+ * @brief Search for a valid executable image between boundaries in internal flash.
+ *
+ * This function is involved in the search of a bootable image.
+ * It is called by the boot ROM on Cold boot but can be called by the Selective OTA.
+ *
+ * The application granularity parameter is read from the PSECT, this is used as the
+ * increment used to hop to next position in case of failure.
+ * The function builds up a chained list of image descriptors that it sorts by version number.
+ * The intent is that the most recent version is at the head of the list.
+ *
+ * @param  start_addr address from which to start search
+ *
+ * @param  end_addr  address from which to start search
+ *
+ * @param  signature  magic identifier : constant 0x98447902
+ *
+ * @param  IMAGE_VERIFY_T verification function pointer (see @boot_Verify_eScoreImageList)
+ *         This parameter cannot be NULL.
+ *         The implementer may opt for a version that simply returns the head of the chained list.
+ *
+ * @return  image address if valid, IMAGE_INVALID_ADDR (0xffffffff) otherwise
+ *
+ */
+static inline uint32_t BOOT_FindImage(uint32_t start_addr, uint32_t end_addr, uint32_t signature, IMAGE_VERIFY_T verify)
+{
+    uint32_t (*p_BOOT_FindImage)(uint32_t start_addr, uint32_t end_addr, uint32_t signature, IMAGE_VERIFY_T verify);
+    p_BOOT_FindImage =
+        (uint32_t(*)(uint32_t start_addr, uint32_t end_addr, uint32_t signature, IMAGE_VERIFY_T verify))0x03000519U;
+
+    return p_BOOT_FindImage(start_addr, end_addr, signature, verify);
+}
+
+/*!
+ * @brief Retrieve LPMode value that has been saved previously in retained RAM bank.
+ *
+ * This is mostly used to determine in which power mode the PMC was before reset,
+ * i.e. whether is is a cold or warm reset. This is to be invoked from ResetISR2
+ *
+ * @param  none
+ *
+ * @return  LPMode
+ *
+ */
+static inline uint32_t BOOT_GetStartPowerMode(void)
+{
+    uint32_t (*p_BOOT_GetStartPowerMode)(void);
+    p_BOOT_GetStartPowerMode = (uint32_t(*)(void))0x03000e9dU;
+
+    return p_BOOT_GetStartPowerMode();
+}
+
+/*!
+ * @brief Sets the value of stack pointer to be restored on warm boot.
+ *
+ * @param  stack_pointer address to be written in retained RAM bank so that
+ * boot ROM restores value on warm start
+ *
+ * @return  none
+ *
+ */
+static inline void BOOT_SetResumeStackPointer(uint32_t stack_pointer)
+{
+    void (*p_BOOT_SetResumeStackPointer)(uint32_t stack_pointer);
+    p_BOOT_SetResumeStackPointer = (void (*)(uint32_t stack_pointer))0x03000ea9U;
+
+    p_BOOT_SetResumeStackPointer(stack_pointer);
+}
+
+/*!
+ * @brief Retrieve Internal flash address and size
+ *
+ * The internal flash start address is necessarily 0.
+ * Its size may vary depending on chip options.
+ * The size returned is the number of bytes usable for program and data.
+ * The maximum possible value is 0x9dc00.
+ *
+ * @param address pointer on location to store returned address
+ *
+ * @param size pointer on location to store returned size
+ *
+ * @return  *address is 0x00000000UL and *size is up to 0x9dc00
+ *
+ */
+static inline void ROM_GetFlash(uint32_t *address, uint32_t *size)
+{
+    void (*p_ROM_GetFlash)(uint32_t * address, uint32_t * size);
+    p_ROM_GetFlash = (void (*)(uint32_t * address, uint32_t * size))0x03000e0dU;
+
+    p_ROM_GetFlash(address, size);
+}
+
+/*!
+ * @brief Retrieve SRAM0 address and size
+ *
+ * @param address pointer on location to store returned address
+ *
+ * @param size pointer on location to store returned size
+ *
+ * @return  *address is 0x04000000UL and *size is 88k (0x16000)
+ *
+ */
+static inline void ROM_GetSRAM0(uint32_t *address, uint32_t *size)
+{
+    void (*p_ROM_GetSRAM0)(uint32_t * address, uint32_t * size);
+    p_ROM_GetSRAM0 = (void (*)(uint32_t * address, uint32_t * size))0x03000e21U;
+
+    p_ROM_GetSRAM0(address, size);
+}
+
+/*!
+ * @brief Retrieve SRAM1 address and size.
+ *        SRAM1 presence is optional depending on chip variant
+ *
+ * @param address pointer on location to store returned address
+ *
+ * @param size pointer on location to store returned size
+ *
+ * @return  if SRAM1 not present *address is 0 and *size is 0,
+ *          otherwise *address is  0x04020000UL and *size is up to 64k (0x10000)
+ */
+static inline void ROM_GetSRAM1(uint32_t *address, uint32_t *size)
+{
+    void (*p_ROM_GetSRAM1)(uint32_t * address, uint32_t * size);
+    p_ROM_GetSRAM1 = (void (*)(uint32_t * address, uint32_t * size))0x03000e35U;
+
+    p_ROM_GetSRAM1(address, size);
+}
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_API_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_common.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_common.h
new file mode 100755
index 0000000..ae8efd9
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_common.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_COMMON_H_
+#define ROM_COMMON_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stdbool.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/* Define ROM compilation for ES2 - required for lowpower API as it supports ES1/ES2 compilation */
+//#define CPU_JN518X_REV 2
+
+#ifdef ROM_BUILD
+#define ROM_API __attribute__((section(".text.api")))
+#else
+#ifdef __MINGW32__
+#define ROM_API
+#elif (defined(__CC_ARM) || defined(__ARMCC_VERSION)) || (defined(__ICCARM__))
+#define ROM_API
+#else
+#define ROM_API __attribute__((long_call))
+#endif
+#endif
+
+#ifndef WEAK
+#define WEAK __attribute__((weak))
+#endif
+
+#ifdef __CDT_PARSER__
+#define STATIC_ASSERT(value, message)
+#else
+#define STATIC_ASSERT _Static_assert
+#endif
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_COMMON_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_efuse.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_efuse.h
new file mode 100755
index 0000000..1f1badb
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_efuse.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_EFUSE_H_
+#define ROM_EFUSE_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <rom_common.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+static inline bool efuse_ReadBit(uint8_t efuse_bitpos)
+{
+    bool (*p_efuse_ReadBit)(uint8_t bitpos);
+    p_efuse_ReadBit = (bool (*)(uint8_t bitpos))0x03001671U;
+
+    return p_efuse_ReadBit(efuse_bitpos);
+}
+/****************************************************************************/
+/***        Exported Variables
+ ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_EFUSE_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_lowpower.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_lowpower.h
new file mode 100755
index 0000000..33e03d5
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_lowpower.h
@@ -0,0 +1,508 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ROM_LOWPOWER_H_
+#define __ROM_LOWPOWER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rom_common.h>
+#include <rom_pmc.h>
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/*******************
+ * EXPORTED MACROS  *
+ ********************/
+
+/* Low Power modes  */
+#define LOWPOWER_CFG_MODE_INDEX 0
+#define LOWPOWER_CFG_MODE_MASK (0x3UL << LOWPOWER_CFG_MODE_INDEX)
+
+#define LOWPOWER_CFG_XTAL32MSTARTENA_INDEX 2
+#define LOWPOWER_CFG_XTAL32MSTARTENA_MASK (0x1UL << LOWPOWER_CFG_XTAL32MSTARTENA_INDEX)
+
+#define LOWPOWER_CFG_FLASHPWDNMODE_INDEX 4
+#define LOWPOWER_CFG_FLASHPWDNMODE_MASK (0x1UL << LOWPOWER_CFG_FLASHPWDNMODE_INDEX)
+
+#define LOWPOWER_CFG_SRAMPWDNMODE_INDEX 6
+#define LOWPOWER_CFG_SRAMPWDNMODE_MASK (0x1UL << LOWPOWER_CFG_SRAMPWDNMODE_INDEX)
+
+#define LOWPOWER_CFG_PDRUNCFG_DISCARD_INDEX 7
+#define LOWPOWER_CFG_PDRUNCFG_DISCARD_MASK (0x1UL << LOWPOWER_CFG_PDRUNCFG_DISCARD_INDEX)
+
+#define LOWPOWER_CFG_WFI_NOT_WFE_INDEX 8
+#define LOWPOWER_CFG_WFI_NOT_WFE_MASK (0x1UL << LOWPOWER_CFG_WFI_NOT_WFE_INDEX)
+
+#define LOWPOWER_CFG_LDOMEM_FORCE_ENABLE_INDEX 9
+#define LOWPOWER_CFG_LDOMEM_FORCE_ENABLE_MASK (0x1UL << LOWPOWER_CFG_LDOMEM_FORCE_ENABLE_INDEX)
+
+#define LOWPOWER_CFG_LDOFLASHCORE_UPDATE_INDEX 10
+#define LOWPOWER_CFG_LDOFLASHCORE_UPDATE_MASK (0x1UL << LOWPOWER_CFG_LDOFLASHCORE_UPDATE_INDEX)
+
+/* Delay to wakeup the flash after the LDO Flash Core has been set up to active voltage : 0: 19us, then increment by
+ * 4.75us steps */
+#define LOWPOWER_CFG_LDOFLASHCORE_DELAY_INDEX 11
+#define LOWPOWER_CFG_LDOFLASHCORE_DELAY_MASK (0x7UL << LOWPOWER_CFG_LDOFLASHCORE_DELAY_INDEX)
+
+#define LOWPOWER_CFG_MODE_ACTIVE 0        /*!< ACTIVE mode */
+#define LOWPOWER_CFG_MODE_DEEPSLEEP 1     /*!< DEEP SLEEP mode */
+#define LOWPOWER_CFG_MODE_POWERDOWN 2     /*!< POWER DOWN mode */
+#define LOWPOWER_CFG_MODE_DEEPPOWERDOWN 3 /*!< DEEP POWER DOWN mode */
+
+#define LOWPOWER_CFG_XTAL32MSTART_DISABLE \
+    0 /*!< Disable Crystal 32 MHz automatic start when waking up from POWER DOWN and DEEP POWER DOWN modes */
+#define LOWPOWER_CFG_XTAL32MSTART_ENABLE \
+    1 /*!< Enable Crystal 32 MHz automatic start when waking up from POWER DOWN and DEEP POWER DOWN modes */
+
+#define LOWPOWER_CFG_FLASHPWDNMODE_FLASHPWND \
+    0 /*!< Power down the Flash only (send CMD_POWERDOWN to Flash controller). Only valid in DEEP SLEEP mode */
+#define LOWPOWER_CFG_FLASHPWDNMODE_LDOSHUTOFF                                                                         \
+    1 /*!< Power down the Flash ((send CMD_POWERDOWN to Flash controller) and shutoff both Flash LDOs (Core and NV) \ \
+         (only valid in DEEP SLEEP mode) */
+
+/**
+ * @brief Analog Power Domains (analog components in Power Management Unit) Low Power Modes control
+ */
+#define LOWPOWER_PMUPWDN_DCDC (1UL << 0)     /*!< Power Down DCDC Converter  */
+#define LOWPOWER_PMUPWDN_BIAS (1UL << 1)     /*!< Power Down all Bias and references */
+#define LOWPOWER_PMUPWDN_LDOMEM (1UL << 2)   /*!< Power Down Memories LDO  */
+#define LOWPOWER_PMUPWDN_BODVBAT (1UL << 3)  /*!< Power Down VBAT Brown Out Detector */
+#define LOWPOWER_PMUPWDN_FRO192M (1UL << 4)  /*!< Power Down FRO 192 MHz  */
+#define LOWPOWER_PMUPWDN_FRO1M (1UL << 5)    /*!< Power Down FRO 1 MHz  */
+#define LOWPOWER_PMUPWDN_GPADC (1UL << 22)   /*!< Power Down General Purpose ADC */
+#define LOWPOWER_PMUPWDN_BODMEM (1UL << 23)  /*!< Power Down Memories Brown Out Detector */
+#define LOWPOWER_PMUPWDN_BODCORE (1UL << 24) /*!< Power Down Core Logic Brown Out Detector */
+#define LOWPOWER_PMUPWDN_FRO32K (1UL << 25)  /*!< Power Down FRO 32 KHz */
+#define LOWPOWER_PMUPWDN_XTAL32K (1UL << 26) /*!< Power Down Crystal 32 KHz */
+#define LOWPOWER_PMUPWDN_ANACOMP (1UL << 27) /*!< Power Down Analog Comparator */
+
+#define LOWPOWER_PMUPWDN_XTAL32M (1UL << 28)    /*!< Power Down Crystal 32 MHz */
+#define LOWPOWER_PMUPWDN_TEMPSENSOR (1UL << 29) /*!< Power Down Temperature Sensor   */
+
+/**
+ * @brief Digital Power Domains Low Power Modes control
+ */
+#define LOWPOWER_DIGPWDN_FLASH                                                                                     \
+    (1UL << 6) /*!< Power Down Flash Power Domain (Flash Macro, Flash Controller and/or FLash LDOs, depending on \ \
+                   LOWPOWER_CFG_FLASHPWDNMODE parameter) */
+#define LOWPOWER_DIGPWDN_COMM0 (1UL << 7) /*!< Power Down Digital COMM0 power domain (USART0, I2C0 and SPI0) */
+#define LOWPOWER_DIGPWDN_MCU_RET                                                                                    \
+    (1UL << 8) /*!< Power Down MCU Retention Power Domain (Disable Zigbee IP retention, ES1:Disable CPU retention \ \
+                   flip-flops) */
+#define LOWPOWER_DIGPWDN_ZIGBLE_RET \
+    (1UL << 9) /*!< Power Down ZIGBEE/BLE retention Power Domain (Disable ZIGBEE/BLE retention flip-flops) */
+
+#define LOWPOWER_DIGPWDN_SRAM0_INDEX 10
+#define LOWPOWER_DIGPWDN_SRAM0 \
+    (1UL << LOWPOWER_DIGPWDN_SRAM0_INDEX)   /*!< Power Down SRAM 0  instance [Bank 0, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM1 (1UL << 11)  /*!< Power Down SRAM 1  instance [Bank 0, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM2 (1UL << 12)  /*!< Power Down SRAM 2  instance [Bank 0, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM3 (1UL << 13)  /*!< Power Down SRAM 3  instance [Bank 0, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM4 (1UL << 14)  /*!< Power Down SRAM 4  instance [Bank 0,  8 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM5 (1UL << 15)  /*!< Power Down SRAM 5  instance [Bank 0,  8 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM6 (1UL << 16)  /*!< Power Down SRAM 6  instance [Bank 0,  4 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM7 (1UL << 17)  /*!< Power Down SRAM 7  instance [Bank 0,  4 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM8 (1UL << 18)  /*!< Power Down SRAM 8  instance [Bank 1, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM9 (1UL << 19)  /*!< Power Down SRAM 9  instance [Bank 1, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM10 (1UL << 20) /*!< Power Down SRAM 10 instance [Bank 1, 16 KB], (no retention) */
+#define LOWPOWER_DIGPWDN_SRAM11 (1UL << 21) /*!< Power Down SRAM 11 instance [Bank 1, 16 KB], (no retention) */
+
+#define LOWPOWER_DIGPWDN_SRAM_ALL_MASK                                                                   \
+    (LOWPOWER_DIGPWDN_SRAM0 | LOWPOWER_DIGPWDN_SRAM1 | LOWPOWER_DIGPWDN_SRAM2 | LOWPOWER_DIGPWDN_SRAM3 | \
+     LOWPOWER_DIGPWDN_SRAM4 | LOWPOWER_DIGPWDN_SRAM5 | LOWPOWER_DIGPWDN_SRAM6 | LOWPOWER_DIGPWDN_SRAM7 | \
+     LOWPOWER_DIGPWDN_SRAM8 | LOWPOWER_DIGPWDN_SRAM9 | LOWPOWER_DIGPWDN_SRAM10 | LOWPOWER_DIGPWDN_SRAM11)
+
+#define LOWPOWER_DIGPWDN_IO_INDEX 30
+#define LOWPOWER_DIGPWDN_IO (1UL << LOWPOWER_DIGPWDN_IO_INDEX) /*!< Power Down   */
+
+#define LOWPOWER_DIGPWDN_NTAG_FD_INDEX 31
+#define LOWPOWER_DIGPWDN_NTAG_FD \
+    (1UL << LOWPOWER_DIGPWDN_NTAG_FD_INDEX) /*!< NTAG FD field detect Disable - need the IO source to be set too */
+
+/**
+ * @brief LDO Voltage control in Low Power Modes
+ */
+
+#define LOWPOWER_SRAM_LPMODE_MASK (0xFUL)
+#define LOWPOWER_SRAM_LPMODE_ACTIVE (0x6UL)    /*!<  */
+#define LOWPOWER_SRAM_LPMODE_SLEEP (0xFUL)     /*!<  */
+#define LOWPOWER_SRAM_LPMODE_DEEPSLEEP (0x8UL) /*!<  */
+#define LOWPOWER_SRAM_LPMODE_SHUTDOWN (0x9UL)  /*!<  */
+#define LOWPOWER_SRAM_LPMODE_POWERUP (0xAUL)   /*!<  */
+
+/**
+ * @brief LDO Voltage control in Low Power Modes
+ */
+#define LOWPOWER_VOLTAGE_LDO_PMU_INDEX 0
+#define LOWPOWER_VOLTAGE_LDO_PMU_MASK (0x1FUL << LOWPOWER_VOLTAGE_LDO_PMU_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_MEM_INDEX 5
+#define LOWPOWER_VOLTAGE_LDO_MEM_MASK (0x1FUL << LOWPOWER_VOLTAGE_LDO_MEM_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_CORE_INDEX 10
+#define LOWPOWER_VOLTAGE_LDO_CORE_MASK (0x7UL << LOWPOWER_VOLTAGE_LDO_CORE_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_FLASH_CORE_INDEX 13
+#define LOWPOWER_VOLTAGE_LDO_FLASH_CORE_MASK (0x7UL << LOWPOWER_VOLTAGE_LDO_FLASH_CORE_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_FLASH_NV_INDEX 16
+#define LOWPOWER_VOLTAGE_LDO_FLASH_NV_MASK (0x7UL << LOWPOWER_VOLTAGE_LDO_FLASH_NV_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX 19
+#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_MASK (0x1FUL << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX)
+#define LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX 24
+#define LOWPOWER_VOLTAGE_LDO_MEM_BOOST_MASK (0x1FUL << LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX)
+/* Only for ES2 but defined it for ES1 for easier power driver writing (has no effect on ES1) */
+#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_INDEX 29
+#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_MASK (0x1UL << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_ENABLE_INDEX)
+
+/**
+ * @brief Low Power Modes Wake up Interrupt sources
+ */
+#define LOWPOWER_WAKEUPSRCINT0_SYSTEM_IRQ \
+    (1UL << 0) /*!< BOD, Watchdog Timer, Flash controller, Firewall [DEEP SLEEP] BOD [POWER_DOWN]*/
+#define LOWPOWER_WAKEUPSRCINT0_DMA_IRQ (1UL << 1)       /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_GINT_IRQ (1UL << 2)      /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_IRBLASTER_IRQ (1UL << 3) /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PINT0_IRQ (1UL << 4)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PINT1_IRQ (1UL << 5)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PINT2_IRQ (1UL << 6)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PINT3_IRQ (1UL << 7)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_SPIFI_IRQ (1UL << 8)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_TIMER0_IRQ (1UL << 9)    /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_TIMER1_IRQ (1UL << 10)   /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_USART0_IRQ (1UL << 11)   /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT0_USART1_IRQ (1UL << 12)   /*!< [DEEP SLEEP]  */
+#define LOWPOWER_WAKEUPSRCINT0_I2C0_IRQ (1UL << 13)     /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT0_I2C1_IRQ (1UL << 14)     /*!< [DEEP SLEEP]  */
+#define LOWPOWER_WAKEUPSRCINT0_SPI0_IRQ (1UL << 15)     /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT0_SPI1_IRQ (1UL << 16)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM0_IRQ (1UL << 17)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM1_IRQ (1UL << 18)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM2_IRQ (1UL << 19)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM3_IRQ (1UL << 20)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM4_IRQ (1UL << 21)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM5_IRQ (1UL << 22)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM6_IRQ (1UL << 23)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM7_IRQ (1UL << 24)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM8_IRQ (1UL << 25)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM9_IRQ (1UL << 26)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_PWM10_IRQ (1UL << 27)    /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_I2C2_IRQ (1UL << 28)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT0_RTC_IRQ (1UL << 29)      /*!< [DEEP SLEEP, POWER DOWN]  */
+#define LOWPOWER_WAKEUPSRCINT0_NFCTAG_IRQ (1UL << 30)   /*!< [DEEP SLEEP]  */
+#define LOWPOWER_WAKEUPSRCINT0_MAILBOX_IRQ \
+    (1UL << 31) /*!< Mailbox, Wake-up from DEEP SLEEP and POWER DOWN low power mode [DEEP SLEEP, POWER DOWN] */
+
+#define LOWPOWER_WAKEUPSRCINT1_ADC_SEQA_IRQ (1UL << 0)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ADC_SEQB_IRQ (1UL << 1)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ADC_THCMP_OVR_IRQ (1UL << 2)   /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_DMIC_IRQ (1UL << 3)            /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_HWVAD_IRQ (1UL << 4)           /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_DP_IRQ (1UL << 5)          /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_DP0_IRQ (1UL << 6)         /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_DP1_IRQ (1UL << 7)         /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_DP2_IRQ (1UL << 8)         /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_LL_ALL_IRQ (1UL << 9)      /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ZIGBEE_MAC_IRQ (1UL << 10)     /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ZIGBEE_MODEM_IRQ (1UL << 11)   /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_RFP_TMU_IRQ (1UL << 12)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_RFP_AGC_IRQ (1UL << 13)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ISO7816_IRQ (1UL << 14)        /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_ANA_COMP_IRQ (1UL << 15)       /*!< [DEEP SLEEP] */
+#define LOWPOWER_WAKEUPSRCINT1_WAKE_UP_TIMER0_IRQ (1UL << 16) /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT1_WAKE_UP_TIMER1_IRQ (1UL << 17) /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_WAKE_TIMER_IRQ (1UL << 22) /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT1_BLE_OSC_EN_IRQ (1UL << 23)     /*!< [DEEP SLEEP, POWER DOWN] */
+#define LOWPOWER_WAKEUPSRCINT1_IO_IRQ (1UL << 31)             /*!< [POWER DOWN, DEEP DOWN]  */
+
+/**
+ * @brief Sleep Postpone
+ */
+#define LOWPOWER_SLEEPPOSTPONE_FORCED \
+    (1UL << 0) /*!< Forces postpone of power down modes in case the processor request low power mode*/
+#define LOWPOWER_SLEEPPOSTPONE_PERIPHERALS                                                                             \
+    (1UL << 1) /*!< USART0, USART1, SPI0, SPI1, I2C0, I2C1, I2C2 interrupts can postpone power down modes in case an \ \
+                   interrupt is pending when the processor request low power mode */
+#define LOWPOWER_SLEEPPOSTPONE_DMIC                                                                                   \
+    (1UL << 0) /*!< DMIC interrupt can postpone power down modes in case an interrupt is pending when the processor \ \
+                   request low power mode */
+#define LOWPOWER_SLEEPPOSTPONE_SDMA                                                                               \
+    (1UL << 1) /*!< System DMA interrupt can postpone power down modes in case an interrupt is pending when the \ \
+                   processor request low power mode */
+#define LOWPOWER_SLEEPPOSTPONE_NFCTAG                                                                          \
+    (1UL << 0) /*!< NFC Tag interrupt can postpone power down modes in case an interrupt is pending when the \ \
+                   processor request low power mode */
+#define LOWPOWER_SLEEPPOSTPONE_BLEOSC                                                                             \
+    (1UL << 1) /*!< BLE_OSC_EN interrupt can postpone power down modes in case an interrupt is pending when the \ \
+                   processor request low power mode */
+
+/**
+ * @brief Wake up I/O sources
+ */
+#define LOWPOWER_WAKEUPIOSRC_PIO0 (1UL << 0)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO1 (1UL << 1)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO2 (1UL << 2)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO3 (1UL << 3)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO4 (1UL << 4)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO5 (1UL << 5)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO6 (1UL << 6)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO7 (1UL << 7)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO8 (1UL << 8)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO9 (1UL << 9)   /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO10 (1UL << 10) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO11 (1UL << 11) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO12 (1UL << 12) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO13 (1UL << 13) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO14 (1UL << 14) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO15 (1UL << 15) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO16 (1UL << 16) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO17 (1UL << 17) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO18 (1UL << 18) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO19 (1UL << 19) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO20 (1UL << 20) /*!<    */
+#define LOWPOWER_WAKEUPIOSRC_PIO21 (1UL << 21) /*!<    */
+
+#ifndef LOWPOWER_API_ES1_ONLY
+/* For NTAG FD wakeup source, SW shall enable virtual IO 22 in */
+#define LOWPOWER_WAKEUPIOSRC_NTAG_FD (1UL << 22) /*!<    */
+#endif
+
+/**
+ * @brief I/O whose state must be kept in Power Down mode
+ */
+#define LOWPOWER_GPIOLATCH_PIO0 (1UL << 0)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO1 (1UL << 1)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO2 (1UL << 2)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO3 (1UL << 3)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO4 (1UL << 4)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO5 (1UL << 5)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO6 (1UL << 6)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO7 (1UL << 7)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO8 (1UL << 8)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO9 (1UL << 9)   /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO10 (1UL << 10) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO11 (1UL << 11) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO12 (1UL << 12) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO13 (1UL << 13) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO14 (1UL << 14) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO15 (1UL << 15) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO16 (1UL << 16) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO17 (1UL << 17) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO18 (1UL << 18) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO19 (1UL << 19) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO20 (1UL << 20) /*!<    */
+#define LOWPOWER_GPIOLATCH_PIO21 (1UL << 21) /*!<    */
+
+/**
+ * @brief Wake up timers configuration in Low Power Modes
+ */
+#define LOWPOWER_TIMERCFG_ENABLE_INDEX 0
+#define LOWPOWER_TIMERCFG_ENABLE_MASK (0x1UL << LOWPOWER_TIMERCFG_ENABLE_INDEX)
+#define LOWPOWER_TIMERCFG_TIMER_INDEX 1
+#define LOWPOWER_TIMERCFG_TIMER_MASK (0x7UL << LOWPOWER_TIMERCFG_TIMER_INDEX)
+#define LOWPOWER_TIMERCFG_OSC32K_INDEX 4
+#define LOWPOWER_TIMERCFG_OSC32K_MASK (0x1UL << LOWPOWER_TIMERCFG_OSC32K_INDEX)
+#define LOWPOWER_TIMERCFG_2ND_ENABLE_INDEX 5
+#define LOWPOWER_TIMERCFG_2ND_ENABLE_MASK (0x1UL << LOWPOWER_TIMERCFG_2ND_ENABLE_INDEX)
+#define LOWPOWER_TIMERCFG_2ND_TIMER_INDEX 6
+#define LOWPOWER_TIMERCFG_2ND_TIMER_MASK (0x7UL << LOWPOWER_TIMERCFG_2ND_TIMER_INDEX)
+
+#define LOWPOWER_TIMERCFG_TIMER_ENABLE 1 /*!< Wake Timer Enable */
+
+/**
+ * @brief Primary Wake up timers configuration in Low Power Modes
+ */
+#define LOWPOWER_TIMERCFG_TIMER_WAKEUPTIMER0 0   /*!< Zigbee Wake up Counter 0 used as wake up source */
+#define LOWPOWER_TIMERCFG_TIMER_WAKEUPTIMER1 1   /*!< Zigbee Wake up Counter 1 used as wake up source */
+#define LOWPOWER_TIMERCFG_TIMER_BLEWAKEUPTIMER 2 /*!< BLE Wake up Counter used as wake up source */
+#define LOWPOWER_TIMERCFG_TIMER_RTC1KHZ 3        /*!< 1 KHz Real Time Counter (RTC) used as wake up source */
+#define LOWPOWER_TIMERCFG_TIMER_RTC1HZ 4         /*!< 1 Hz Real Time Counter (RTC) used as wake up source */
+
+/**
+ * @brief Secondary Wake up timers configuration in Low Power Modes
+ */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_WAKEUPTIMER0 0   /*!< Zigbee Wake up Counter 0 used as secondary wake up source */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_WAKEUPTIMER1 1   /*!< Zigbee Wake up Counter 1 used as secondary wake up source */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_BLEWAKEUPTIMER 2 /*!< BLE Wake up Counter used as secondary wake up source */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_RTC1KHZ 3 /*!< 1 KHz Real Time Counter (RTC) used as secondary wake up source */
+#define LOWPOWER_TIMERCFG_2ND_TIMER_RTC1HZ 4  /*!< 1 Hz Real Time Counter (RTC) used as secondary wake up source */
+
+#define LOWPOWER_TIMERCFG_OSC32K_FRO32KHZ 0  /*!< Wake up Timers uses FRO 32 KHz as clock source */
+#define LOWPOWER_TIMERCFG_OSC32K_XTAL32KHZ 1 /*!< Wake up Timers uses Chrystal 32 KHz as clock source */
+
+/**
+ * @brief BLE Wake up timers configuration in Low Power Modes
+ */
+#define LOWPOWER_TIMERBLECFG_RADIOEN_INDEX 0
+#define LOWPOWER_TIMERBLECFG_RADIOEN_MASK (0x3FFUL << LOWPOWER_TIMERBLECFG_RADIOEN_INDEX)
+#define LOWPOWER_TIMERBLECFG_OSCEN_INDEX 10
+#define LOWPOWER_TIMERBLECFG_OSCEN_MASK (0x7FFUL << LOWPOWER_TIMERBLECFG_OSCEN_INDEX)
+
+/** @brief	Low Power Main Structure */
+typedef struct
+{                           /*     */
+    uint32_t CFG;           /*!< Low Power Mode Configuration, and miscallenous options  */
+    uint32_t PMUPWDN;       /*!< Analog Power Domains (analog components in Power Management Unit) Low Power Modes  */
+    uint32_t DIGPWDN;       /*!< Digital Power Domains Low Power Modes */
+    uint32_t VOLTAGE;       /*!< LDO Voltage control in Low Power Modes */
+    uint32_t WAKEUPSRCINT0; /*!< Wake up sources Interrupt control */
+    uint32_t WAKEUPSRCINT1; /*!< Wake up sources Interrupt control */
+    uint32_t SLEEPPOSTPONE; /*!< Interrupt that can postpone power down modes in case an interrupt is pending when the
+                               processor request deepsleep */
+    uint32_t WAKEUPIOSRC;   /*!< Wake up I/O sources */
+    uint32_t GPIOLATCH;     /*!< I/Os which outputs level must be kept (in Power Down  mode)*/
+    uint32_t TIMERCFG;      /*!< Wake up timers configuration */
+    uint32_t TIMERBLECFG;   /*!< BLE wake up timer configuration (OSC_EN and RADIO_EN) */
+    uint32_t TIMERCOUNTLSB; /*!< Wake up Timer LSB*/
+    uint32_t TIMERCOUNTMSB; /*!< Wake up Timer MSB*/
+    uint32_t TIMER2NDCOUNTLSB; /*!< Second Wake up Timer LSB*/
+    uint32_t TIMER2NDCOUNTMSB; /*!< Second Wake up Timer MSB*/
+
+} LPC_LOWPOWER_T;
+
+/** @brief	Low Power Main Structure */
+typedef struct
+{                         /*   */
+    uint8_t LDOPMU;       /*!< Always-ON domain LDO voltage configuration */
+    uint8_t LDOPMUBOOST;  /*!< Always-ON domain LDO Boost voltage configuration */
+    uint8_t LDOMEM;       /*!< Memories LDO voltage configuration */
+    uint8_t LDOMEMBOOST;  /*!< Memories LDO Boost voltage configuration */
+    uint8_t LDOCORE;      /*!< Core Logic domain LDO voltage configuration */
+    uint8_t LDOFLASHNV;   /*!< Flash NV domain LDO voltage configuration */
+    uint8_t LDOFLASHCORE; /*!< Flash Core domain LDO voltage configuration */
+    uint8_t LDOADC;       /*!< General Purpose ADC LDO voltage configuration */
+#ifndef LOWPOWER_API_ES1_ONLY
+    uint8_t LDOPMUBOOST_ENABLE; /*!< Force Boost activation on LDOPMU */
+#endif
+} LPC_LOWPOWER_LDOVOLTAGE_T;
+
+/**
+ * @brief	Configure Wake or RTC timers. used for testing only
+ * @param	p_lowpower_cfg: pointer to a structure that contains all low power mode parameters
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_SetUpLowPowerModeWakeUpTimer(LPC_LOWPOWER_T *p_lowpower_cfg)
+{
+    void (*p_Chip_LOWPOWER_SetUpLowPowerModeWakeUpTimer)(LPC_LOWPOWER_T * p_lowpower_cfg);
+    p_Chip_LOWPOWER_SetUpLowPowerModeWakeUpTimer = (void (*)(LPC_LOWPOWER_T * p_lowpower_cfg))0x030038d1U;
+
+    p_Chip_LOWPOWER_SetUpLowPowerModeWakeUpTimer(p_lowpower_cfg);
+}
+/**
+ * @brief	Configure CPU and System Bus clock frequency
+ * @param	Frequency	:
+ * @return	Nothing
+ */
+static inline int Chip_LOWPOWER_SetSystemFrequency(uint32_t frequency)
+{
+    int (*p_Chip_LOWPOWER_SetSystemFrequency)(uint32_t frequency);
+    p_Chip_LOWPOWER_SetSystemFrequency = (int (*)(uint32_t frequency))0x03003d55U;
+
+    return p_Chip_LOWPOWER_SetSystemFrequency(frequency);
+}
+
+/**
+ * @brief	Configure Memory instances Low Power Mode
+ * @param	p_sram_instance: SRAM instance number, between 0 and 11.
+ * @param	p_sram_lp_mode : Low power mode : LOWPOWER_SRAM_LPMODE_ACTIVE, LOWPOWER_SRAM_LPMODE_SLEEP,
+ * LOWPOWER_SRAM_LPMODE_DEEPSLEEP, LOWPOWER_SRAM_LPMODE_SHUTDOWN
+ * @return	Status code
+ */
+static inline int Chip_LOWPOWER_SetMemoryLowPowerMode(uint32_t p_sram_instance, uint32_t p_sram_lp_mode)
+{
+    int (*p_Chip_LOWPOWER_SetMemoryLowPowerMode)(uint32_t p_sram_instance, uint32_t p_sram_lp_mode);
+    p_Chip_LOWPOWER_SetMemoryLowPowerMode = (int (*)(uint32_t p_sram_instance, uint32_t p_sram_lp_mode))0x03003d89U;
+
+    return p_Chip_LOWPOWER_SetMemoryLowPowerMode(p_sram_instance, p_sram_lp_mode);
+}
+
+/**
+ * @brief	Get System Voltages
+ * @param	p_ldo_voltage: pointer to a structure to fill with current voltages on the chip
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_GetSystemVoltages(LPC_LOWPOWER_LDOVOLTAGE_T *p_ldo_voltage)
+{
+    void (*p_Chip_LOWPOWER_GetSystemVoltages)(LPC_LOWPOWER_LDOVOLTAGE_T * p_ldo_voltage);
+    p_Chip_LOWPOWER_GetSystemVoltages = (void (*)(LPC_LOWPOWER_LDOVOLTAGE_T * p_ldo_voltage))0x03003de1U;
+
+    p_Chip_LOWPOWER_GetSystemVoltages(p_ldo_voltage);
+}
+
+/**
+ * @brief	Configure System Voltages
+ * @param	p_ldo_voltage: pointer to a structure that contains new voltages to be applied
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_SetSystemVoltages(LPC_LOWPOWER_LDOVOLTAGE_T *p_ldo_voltage)
+{
+    void (*p_Chip_LOWPOWER_SetSystemVoltages)(LPC_LOWPOWER_LDOVOLTAGE_T * p_ldo_voltage);
+    p_Chip_LOWPOWER_SetSystemVoltages = (void (*)(LPC_LOWPOWER_LDOVOLTAGE_T * p_ldo_voltage))0x03003e99U;
+
+    p_Chip_LOWPOWER_SetSystemVoltages(p_ldo_voltage);
+}
+
+/**
+ * @brief	Configure and enters in low power mode
+ * @param	p_lowpower_cfg: pointer to a structure that contains all low power mode parameters
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_SetLowPowerMode(LPC_LOWPOWER_T *p_lowpower_cfg)
+{
+    void (*p_Chip_LOWPOWER_SetLowPowerMode)(LPC_LOWPOWER_T * p_lowpower_cfg);
+    p_Chip_LOWPOWER_SetLowPowerMode = (void (*)(LPC_LOWPOWER_T * p_lowpower_cfg))0x0300404dU;
+
+    p_Chip_LOWPOWER_SetLowPowerMode(p_lowpower_cfg);
+}
+
+/**
+ * @brief	Perform a Full chip reset using Software reset bit in PMC
+ *
+ *  Power down the flash then perform the full chip reset as POR or Watchdog do,
+ *  The reset includes JTAG debugger, Digital units and Analog modules.
+ *  Use the Software reset bit in PMC
+ *
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_ChipSoftwareReset(void)
+{
+    void (*p_Chip_LOWPOWER_ChipSoftwareReset)(void);
+    p_Chip_LOWPOWER_ChipSoftwareReset = (void (*)(void))0x03003fa1U;
+
+    p_Chip_LOWPOWER_ChipSoftwareReset();
+}
+
+/**
+ * @brief	Perform a digital System reset
+ *
+ *  Power down the flash then perform the Full chip reset as POR or Watchdog,
+ *  The reset includes the digital units but excludes the JTAG debugger, and the analog modules.
+ *  Use the system reset bit in PMC and ARM reset
+ *
+ * @return	Nothing
+ */
+static inline void Chip_LOWPOWER_ArmSoftwareReset(void)
+{
+    void (*p_Chip_LOWPOWER_ArmSoftwareReset)(void);
+    p_Chip_LOWPOWER_ArmSoftwareReset = (void (*)(void))0x0300400dU;
+
+    p_Chip_LOWPOWER_ArmSoftwareReset();
+}
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ROM_LOWPOWER_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_mpu.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_mpu.h
new file mode 100755
index 0000000..2f40ae7
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_mpu.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _ROM_MPU_H_
+#define _ROM_MPU_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <rom_common.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+/*! @brief bits for access right */
+#define RD_RIGHT (1 << 0)
+#define WR_RIGHT (1 << 1)
+#define X_RIGHT (1 << 2)
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/*! @brief enum MpuRegion_t index of ARM CM4 MPU regions
+ *  The MPU can describe up to 8 region rules.
+ *  Note that a higher order rule prevails over the lower ones.
+ * The boot ROM makes use of upper order rules : 5 .. 7.
+ * Rule 0 is a 'background' rule that opens the whole memory plane.
+ */
+enum MpuRegion_t
+{
+    MPU_REGION_0, /**< Boot Reserved: background rule */
+    MPU_REGION_1, /**< General purpose rule */
+    MPU_REGION_2, /**< General purpose rule */
+    MPU_REGION_3, /**< General purpose rule */
+    MPU_REGION_4, /**< General purpose rule */
+    MPU_APP_LAST_REGION = MPU_REGION_4,
+    MPU_REGION_5, /**< Boot Reserved */
+    MPU_REGION_6, /**< Boot Reserved */
+    MPU_REGION_7, /**< Boot Reserved */
+    MPU_REGIONS_NB
+};
+
+typedef struct __MPU_reg_settings_t
+{
+    uint32_t rbar;
+    uint32_t rasr;
+} MPU_reg_settings_t;
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+/*!
+ * @brief This function is used to grant access to the pSector region.
+ *
+ * Note: The pSector region is 'special' because counter intuitively it requires Write
+ * access in order to be able to read from it using the flash controller indirect method.
+ * The previosuly applied policy.
+ * pSector region is protected under rule 7 (highest precedence).
+ * The previous rule 7 is saved in RAM before changing it.
+ *
+ * @param  addr: address of area to grant access to.
+ * @param  sz:   size in number of bytes of area.
+ * @param  save_rule: save a copy of previous rule
+ * @return  -1 if failure, if succesful return the size of the region.
+ *
+ */
+static inline int MPU_pSectorGrantAccessRights(uint32_t addr, size_t sz, MPU_reg_settings_t *save_rule)
+{
+    int (*p_MPU_pSectorGrantAccessRights)(uint32_t addr, size_t sz, MPU_reg_settings_t * save_rule);
+    p_MPU_pSectorGrantAccessRights = (int (*)(uint32_t addr, size_t sz, MPU_reg_settings_t * save_rule))0x030017e5U;
+
+    return p_MPU_pSectorGrantAccessRights(addr, sz, save_rule);
+}
+
+/*!
+ * @brief This function is used to withdraw access to the pSector region.
+ *
+ * The pSector region is 'special' because counter intuitively it requires Write
+ * access in order to be able to read from it using the flash controller indirect method.
+ *
+ * @param  save_rule: pointer on RAM MPU_reg_settings_t structure saved by MPU_pSectorGrantAccessRights
+ *         used to restore previous settings of region 7 and restrict access to pSector.
+ *
+ * @return  -1 if failure, if succesful return the size of the region.
+ *
+ */
+static inline int MPU_pSectorWithdrawAccessRights(MPU_reg_settings_t *save_rule)
+{
+    int (*p_MPU_pSectorWithdrawAccessRights)(MPU_reg_settings_t * save_rule);
+    p_MPU_pSectorWithdrawAccessRights = (int (*)(MPU_reg_settings_t * save_rule))0x03001841U;
+
+    return p_MPU_pSectorWithdrawAccessRights(save_rule);
+}
+
+/*! @brief MPU_Settings_t structure in RAM to retrieve current MPU configuration
+ * see @MPU_GetCurrentSettings
+ */
+typedef struct
+{
+    uint32_t ctrl;    /*!< MPU Ctrl register */
+    uint32_t rbar[8]; /*!< MPU RBAR array for the 8 rules */
+    uint32_t rasr[8]; /*!< MPU RASR array for the 8 rules */
+} MPU_Settings_t;
+
+/*!
+ * @brief This function is used to read the MPU settings into a RAM structure.
+ *
+ * @param  settings: pointer of structure to receive the MPU register valkues.
+
+ * @return  none
+ *
+ */
+static inline void MPU_GetCurrentSettings(MPU_Settings_t *settings)
+{
+    void (*p_MPU_GetCurrentSettings)(MPU_Settings_t * settings);
+    p_MPU_GetCurrentSettings = (void (*)(MPU_Settings_t * settings))0x0300178dU;
+
+    p_MPU_GetCurrentSettings(settings);
+}
+
+/*!
+ * @brief This function is used to set access rights to a region.
+ *
+ * @param  region_id: 0 .. 7 see @enum MpuRegion_t
+ * @param  addr: address of region
+ * @param  sz: region size
+ * @param  rwx_rights: bit field RD_RIGHT(0) - WR_RIGHT(1) - X_RIGHT(2)
+ * @param  save_rule: save a copy of previous rule
+ *
+ * @return  -1 if failure, if succesful return the size of the region.
+ *
+ */
+static inline int MPU_SetRegionAccessRights(
+    enum MpuRegion_t region_id, uint32_t addr, size_t sz, uint8_t rwx_rights, MPU_reg_settings_t *save_rule)
+{
+    int (*p_MPU_SetRegionAccessRights)(enum MpuRegion_t region_id, uint32_t addr, size_t sz, uint8_t rwx_rights,
+                                       MPU_reg_settings_t * save_rule);
+    p_MPU_SetRegionAccessRights = (int (*)(enum MpuRegion_t region_id, uint32_t addr, size_t sz, uint8_t rwx_rights,
+                                           MPU_reg_settings_t * save_rule))0x03001821U;
+
+    return p_MPU_SetRegionAccessRights(region_id, addr, sz, rwx_rights, save_rule);
+}
+
+/*!
+ * @brief This function is used to set access rights to a region.
+ *
+ * Called after previous call to see @MPU_SetRegionAccessRights
+ *
+ * @param  region_id: 0 .. 7 see @enum MpuRegion_t
+ * @param  save_rule: saved copy of previous rule to be restored.
+ *         if this parameter is NULL, RBAR and RASR of the given region_id
+ *         are cleared.
+ *
+ * @return  -1 if failure, if succesful return the size of the region.
+ *
+ */
+static inline int MPU_ClearRegionSetting(enum MpuRegion_t region_id, MPU_reg_settings_t *saved_rule)
+{
+    int (*p_MPU_ClearRegionSetting)(enum MpuRegion_t region_id, MPU_reg_settings_t * saved_rule);
+    p_MPU_ClearRegionSetting = (int (*)(enum MpuRegion_t region_id, MPU_reg_settings_t * saved_rule))0x0300184dU;
+
+    return p_MPU_ClearRegionSetting(region_id, saved_rule);
+}
+
+/*!
+ * @brief This function is used to select the first available rule.
+ *
+ * Checks if rules have their RASR enable bit set.
+ * This for the application to find free riules that were left unused
+ * by the ROM code.
+ * Implicitly MPU_ClearRegionSetting releases an allocate rule.
+ *
+ *
+ * @param  none
+ *
+ * @return  -1 if none free, value between 1..4 if succesful.
+ *
+ */
+static inline int MPU_AllocateRegionDesc(void)
+{
+    int (*p_MPU_AllocateRegionDesc)(void);
+    p_MPU_AllocateRegionDesc = (int (*)(void))0x030017c1U;
+
+    return p_MPU_AllocateRegionDesc();
+}
+
+#if defined __cplusplus
+}
+#endif
+#endif
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_pmc.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_pmc.h
new file mode 100755
index 0000000..89f1f6a
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_pmc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_RESET_H_
+#define ROM_RESET_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <rom_common.h>
+#include <stdint.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/*!
+ * @brief  Get the cause of the reset.
+ *
+ * @return Reset cause value.
+ * @retval 0x1 POR - The last chip reset was caused by a Power On Reset.
+ * @retval 0x2 PADRESET - The last chip reset was caused by a Pad Reset.
+ * @retval 0x4 BODRESET - The last chip reset was caused by a Brown Out Detector.
+ * @retval 0x8 SYSTEMRESET - The last chip reset was caused by a System Reset requested by the ARM CPU.
+ * @retval 0x10 WDTRESET - The last chip reset was caused by the Watchdog Timer.
+ * @retval 0x20 WAKEUPIORESET -  The last chip reset was caused by a Wake-up I/O (GPIO or internal NTAG FD INT).
+ * @retval 0x40 WAKEUPPWDNRESET - The last CPU reset was caused by a Wake-up from Power down (many sources possible:
+ * timer, IO, ...).
+ * @retval 0x80 SWRRESET - The last chip reset was caused by a Software.
+ */
+static inline uint32_t pmc_reset_get_cause(void)
+{
+    uint32_t (*p_pmc_reset_get_cause)(void);
+    p_pmc_reset_get_cause = (uint32_t(*)(void))0x030046e9U;
+
+    return p_pmc_reset_get_cause();
+}
+
+/*!
+ * @brief  Clear the cause of the reset.
+ *
+ * @param  mask The mask of reset cause which you want to clear.
+ *
+ * @return  none
+ */
+static inline void pmc_reset_clear_cause(uint32_t mask)
+{
+    void (*p_pmc_reset_clear_cause)(uint32_t mask);
+    p_pmc_reset_clear_cause = (void (*)(uint32_t mask))0x030046f5U;
+
+    p_pmc_reset_clear_cause(mask);
+}
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_RESET_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_psector.h b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_psector.h
new file mode 100755
index 0000000..e27d231
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/drivers/rom_psector.h
@@ -0,0 +1,644 @@
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROM_PSECTOR_H_
+#define ROM_PSECTOR_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup ROM_API
+ * @{
+ */
+
+/*! @file */
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stddef.h>
+#include "rom_common.h"
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/*! @brief PSECTOR_PAGE_WORDS number of 16 byte words available in page
+ * A page is 512 bytes in size. That is 32x16 bytes.
+ * The first 32 bytes contain the page header, which leaves 30x16bytes for storage.
+ * Thence the 30.
+ */
+#define PSECTOR_PAGE_WORDS 30
+
+/*! @brief PSECTOR_PAGE0_MAGIC magic word to identify PAGE0 page in header */
+#define PSECTOR_PAGE0_MAGIC  0xc51d8ca9
+/*! @brief PSECTOR_PFLASH_MAGIC magic word to identify PFLASH page in header */
+#define PSECTOR_PFLASH_MAGIC 0xa7b4353d
+
+#ifdef __GNUC__
+#define PSECT_READ(partition, page_type, var)                                               \
+( {                                                                                                \
+    typeof((((page_type *)0)->var)) _a;                                                            \
+    psector_ReadData(partition, 0, offsetof(page_type, var), sizeof((((page_type *)0)->var)), &_a);\
+    _a;                                                                                            \
+} )
+#endif
+
+#define ROM_SEC_BOOT_AUTH_ON_UPGRADE ((1 << 0) | ROM_SEC_BOOT_AUTH_ON_BOOT)
+#define ROM_SEC_BOOT_AUTH_ON_BOOT (1 << 1)
+#define ROM_SEC_BOOT_PREVENT_DOWNGRADE (1 << 2)
+#define ROM_SEC_BOOT_USE_NXP_KEY (1 << 3)
+
+/*! @brief IMG_DIRECTORY_MAX_SIZE max number of entries in image directory
+ * Concerns Secondary Stage Bootloader only
+*/
+#define IMG_DIRECTORY_MAX_SIZE 8
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/*! @brief psector_partition_id_t describes the 2 partitions of psectors.
+ * Note: PAGE0 is termed PSECT in the FlashProgrammer, whereas PFLASH remains PFLASH.
+ *
+ */
+typedef enum {
+
+    PSECTOR_PAGE0_PART,  /*!< Page0 partition : termed PSECT by FLashProgramemr tool
+                         * Image related data */
+    PSECTOR_PFLASH_PART, /*!< PFLASH : Custommer configuration data */
+    MAX_PSECTOR_PARTITIONS,
+} psector_partition_id_t;
+
+/*! @brief psector_page_state_t describes the possible states of the psector partitions. */
+typedef enum
+{
+    PAGE_STATE_BLANK,     /*!< Page has never been programmed or has been erased */
+    PAGE_STATE_ERROR,     /*!< Both subpages constituting the psector contain
+                           *unrecoverable errors that ECC/parity cannot mend */
+    PAGE_STATE_DEGRADED,  /*!< One subpage contains unrecoverable errors or is blank  */
+    PAGE_STATE_OK,        /*!< Both subpages are correct */
+} psector_page_state_t;
+
+/*! @brief psector_write_status_t status code of writes to update page.
+ */
+typedef enum
+{
+    WRITE_OK = 0x0,                    /*!< Succeded in writing page */
+    WRITE_ERROR_BAD_MAGIC,             /*!< Magic word incorrect in page header */
+    WRITE_ERROR_INVALID_PAGE_NUMBER,   /*!< Invalid page number (higher than partition size) */
+    WRITE_ERROR_BAD_VERSION,           /*!< Invalid version number: must increment monotonically */
+    WRITE_ERROR_BAD_CHECKSUM,          /*!< Invalid checksum */
+    WRITE_ERROR_INCORRECT_UPDATE_MODE, /*!< Update mode incorrect */
+    WRITE_ERROR_UPDATE_INVALID,        /*!< Update invalid */
+    WRITE_ERROR_PAGE_ERROR             /*!< Failure to program page in flash */
+} psector_write_status_t;
+
+/*! @brief AuthMode_t authentication options.
+ */
+typedef enum {
+    AUTH_NONE = 0,          /*!< no authentication is performed */
+    AUTH_ON_FW_UPDATE = 1,  /*!< authentication is performed on firmware update */
+    AUTH_ALWAYS = 2,        /*!< authentication is performed at each Cold boot*/
+  AUTH_LEVEL_NB
+} AuthMode_t;
+
+#define IMG_FLAG_BOOTABLE 1
+
+/*! @brief image_directory_entry_t image directory found in PAGE0 (PSECT)
+ * when SSBL is involved in the loading process
+ */
+typedef struct {
+    uint32_t img_base_addr;    /*!< image start address in internal Flash or QSPI flash  */
+    uint16_t img_nb_pages;     /*!< image number of 512 byte pages */
+    uint8_t  flags;            /*!< IMG_FLAG_BOOTABLE : bit 0, other TBD */
+    uint8_t  img_type;         /*!< image type */
+
+} image_directory_entry_t;
+
+typedef union
+{
+    uint8_t data_8[16];
+    uint32_t data_32[4];
+    uint64_t data_64[2];
+} psector_page_word_t;
+
+/*! @brief psector_header_t psector header.
+ */
+typedef struct
+{
+    uint32_t checksum;     /*!< page checksum */
+    uint32_t magic;        /*!< magic:  PSECTOR_PAGE0_MAGIC or PSECTOR_PFLASH_MAGIC*/
+    uint16_t psector_size;
+    uint16_t page_number;  /*!< should be 0 because both partitions contain a single page */
+    uint32_t version;
+    uint8_t update_modes[16];
+
+} psector_header_t;
+
+typedef struct
+{
+    psector_header_t hdr;
+    psector_page_word_t page_word[PSECTOR_PAGE_WORDS];
+} psector_page_t;
+
+typedef struct
+{
+    psector_header_t hdr;
+
+    union
+    {
+        psector_page_word_t page_word[PSECTOR_PAGE_WORDS];
+
+        struct
+        {
+            /* Word 0 - Any */
+            uint32_t SelectedImageAddress;
+            uint32_t RESERVED0[3];
+            /* Word 1 - Increment */
+            uint32_t MinVersion;
+            uint32_t img_pk_valid;
+            uint32_t RESERVED1[2];
+            /* Word [2:17] - OTP */
+            uint8_t image_pubkey[256];
+        } page0_v2;                                   /*!< Deprecated form kept for backward compatibility */
+        struct
+        {
+            /* Word 0 - Any */
+            uint32_t SelectedImageAddress;            /*!< Address of image to be loaded by boot ROM
+                                                       * offset 0x20 */
+            uint32_t preferred_app_index;             /*!< for use with SSBL: index of application to select from image directory value 0..8
+                                                       * offset 0x24 */
+            image_directory_entry_t ota_entry;        /*!< New image written by OTA : SSBL to check validity and authentication
+                                                       * offset 0x28 */
+            /* Word 1 - Increment */
+            uint32_t MinVersion;                      /*!< Minimum version accepted : application's version number must be greater than this one to be accepted.
+                                                       * offset 0x30 */
+            uint32_t img_pk_valid;                    /*!< Image public key valid
+                                                       * offset 0x34 */
+            uint32_t flash_audit_done;                /*!< Flash audit done: already sought for wrongly initialized pages
+                                                       * offset 0x38 */
+            uint32_t RESERVED1;                       /*!< padding reserved word */
+            /* Word [2:17] - OTP */
+            uint8_t image_pubkey[256];                /*!< RSA Public Key to be used to verify authenticity
+                                                       * offset 0x40 */
+            /* Word [18:20] */
+            uint8_t zigbee_install_code[36];          /*!< Zigbee install code
+                                                       * offset 0x140 */
+            uint32_t RESERVED3[3];                    /*!< padding reserved wordes */
+            /* Word 21 */
+            uint8_t zigbee_password[16];              /*!< Zigbee password
+                                                       * offset 0x170 */
+            /*Word 22 */                              /*!< Image directory entries array, used by OTA process to locate images and/or blobs
+                                                       * offset 0x180 */
+            image_directory_entry_t
+                      img_directory[IMG_DIRECTORY_MAX_SIZE];
+
+        } page0_v3;
+        struct
+        {
+            uint32_t rom_patch_region_sz;
+            uint32_t rom_patch_region_addr;    /*!< ROM patch entry point address.
+                                                * A value outside of the address range used to store
+                                                * the ROM patch binary shall be deemed invalid
+                                                */
+            uint32_t rom_patch_checksum;
+            uint32_t rom_patch_checksum_valid; /*!< ROM patch checksum valid:
+                                                * 0 means invalid
+                                                * Any other value means valid
+                                                */
+            uint32_t hwtestmode_disable;       /*< HW test mode control:
+                                                *  0 means enabled
+                                                *  Any other value means disabled
+                                                */
+
+            uint32_t ISP_access_level;         /*!< ISP access level:
+                                                * 0 means full access, unsecure
+                                                * 0x01010101 means full access, secure
+                                                * 0x02020202 means write only, unsecure
+                                                * 0x03030303 means write only, secure
+                                                * 0x04040404 means locked
+                                                * Any other value means disabled
+                                                */
+
+            uint16_t application_flash_sz;     /*!< Application flash size, in kilobytes.
+                                                * 0 is interpreted as maximum (640).
+                                                * This is intended to provide an alternative way of
+                                                * restricting the flash size on a device, and to greater
+                                                * granularity, than the eFuse bit.
+                                                * The actual level of granularity that can be obtained is
+                                                * dependent upon the MPU region configuration
+                                                */
+            uint16_t image_authentication_level; /*!< Image authentication level:
+                                                  * 0 means check only header validity
+                                                  * 1 means check signature of whole image if image has changed
+                                                  * 2 means check signature of whole image on every cold start
+                                                  */
+            uint16_t unlock_key_valid;          /*!<  0: unlock key is not valid, >= 1: is present  */
+            uint16_t ram1_bank_sz;               /*!< RAM bank 1 size, in kilobytes.
+                                                  * This is intended to provide an alternative way of restricting
+                                                  * the RAM size on a device, and to greater granularity,
+                                                  * than the eFuse bit. The actual level of granularity that can
+                                                  * be obtained is dependent upon the MPU region configuration */
+
+            uint32_t app_search_granularity;     /*!< Application search granularity (increment), in bytes.
+                                                  * Value of 0 shall be equated to 4096.
+                                                  * Other values are to be used directly;
+                                                  * configurations that are not using hardware remapping do not
+                                                  * require hard restrictions
+                                                  */
+            uint32_t qspi_app_search_granularity;
+
+            uint32_t reserved1[2];
+
+            uint8_t ISP_protocol_key[16];        /*!< ISP protocol key: key used to encrypt messages over ISP UART
+                                                  * with secure access level
+                                                  */
+            uint64_t ieee_mac_id1;               /*!< IEEE_MAC_ID_1 (Used to over-ride MAC ID_1 in N-2 page) */
+            uint64_t ieee_mac_id2;               /*!< IEEE_MAC_ID_2 if second MAC iID is required */
+
+            uint64_t ble_mac_id;                 /*!< BLE device address : only 6 LSB bytes are significant */
+            uint8_t  reserved2[104];             /*!< Reserved for future use  */
+
+            uint64_t customer_id;                /*!< Customer ID, used for secure handshake */
+            uint64_t min_device_id;              /*!< Min Device ID, used for secure handshake - Certificate compatibility  */
+            uint64_t device_id;                  /*!< Device ID, used for secure handshake */
+            uint64_t max_device_id;              /*!< Max Device ID, used for secure handshake - Certificate compatibility  */
+            uint8_t unlock_key[256];             /*!< 2048-bit public key for secure handshake
+                                                  * (equivalent to ‘unlock’ key). Stored encrypted,
+                                                  * using the AES key in eFuse*/
+        } pFlash;
+
+    };
+} psector_page_data_t;
+
+STATIC_ASSERT(sizeof(psector_page_t) == 512, "Psector page size not equal to flash page");
+STATIC_ASSERT(sizeof(psector_page_data_t) == 512, "Psector data size not equal to flash page");
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/* General access functions */
+
+/*!
+ * @brief This function is used to validate a page content and write it to the update page.
+ *
+ * The actual write to the partition will be effective after a reset only.
+ * Among other checks, the page must have a correct magic, a correct checksum
+ *
+ * @param  part_index: PSECTOR_PAGE0_PART or PFLASH_PAGE0_PART.
+ * @param  page: psector_page_t RAM buffer to be written to update page
+ *
+ * @return  status code see @ psector_write_status_t.
+ *
+ */
+static inline psector_write_status_t psector_WriteUpdatePage(psector_partition_id_t part_index, psector_page_t *page)
+{
+    psector_write_status_t (*p_psector_WriteUpdatePage)(psector_partition_id_t part_index, psector_page_t *page);
+    p_psector_WriteUpdatePage =
+        (psector_write_status_t (*)(psector_partition_id_t part_index, psector_page_t *page))0x03004e11U;
+
+    return p_psector_WriteUpdatePage(part_index, page);
+}
+
+/*!
+ * @brief This function is used to validate a page content and write it to the update page.
+ *
+ * The actual write to the partition will be effective after a reset only.
+ *
+ * @param  part_index: PSECTOR_PAGE0_PART or PFLASH_PAGE0_PART.
+ * @param  page: psector_page_t RAM buffer to be written to update page
+ *
+ * @return  status code see @ psector_write_status_t.
+ *
+ */
+static inline void psector_EraseUpdate(void)
+{
+    void (*p_psector_EraseUpdate)(void);
+    p_psector_EraseUpdate = (void (*)(void))0x03004d59U;
+
+    p_psector_EraseUpdate();
+}
+
+/*!
+ * @brief This function is used to read data from a psector partition.
+ *
+ *
+ * @param  part_index: PSECTOR_PAGE0_PART or PFLASH_PAGE0_PART.
+ * @param  page_number: necessarily 0 since partitions now contain 1 single page.
+ * @param  offset: offset of data from which data is to be read
+ * @param  size: number of bytes to be read
+ * @param  data: pointer on RAM buffer used to copy retrived data.
+ *
+ * @return  status code see @ psector_page_state_t
+ *          if PAGE_STATE_DEGRADED or PAGE_STATE_OK, data is available.
+ *          if PAGE_STATE_ERROR or PAGE_STATE_BLANK, no data was read
+ */
+static inline psector_page_state_t psector_ReadData(
+    psector_partition_id_t part_index, int page_number, uint32_t offset, uint32_t size, void *data)
+{
+    psector_page_state_t (*p_psector_ReadData)(psector_partition_id_t part_index, int page_number, uint32_t offset,
+                                               uint32_t size, void *data);
+    p_psector_ReadData = (psector_page_state_t (*)(psector_partition_id_t part_index, int page_number, uint32_t offset,
+                                                   uint32_t size, void *data))0x03004ef1U;
+
+    return p_psector_ReadData(part_index, page_number, offset, size, data);
+}
+
+/*!
+ * @brief This function is used to calculate a page checksum.
+ *
+ * It is essential to recalculate the checksum when performing a psector page update,
+ * failing to update this field, the write operation would be rejected.
+ *
+ * @param  psector_page: pointer on page over which computation is required.
+ *
+ * @return  checksum value to be checked or to replace checksum field of psector header
+ */
+static inline uint32_t psector_CalculateChecksum(psector_page_t *psector_page)
+{
+    uint32_t (*p_psector_CalculateChecksum)(psector_page_t *psector_page);
+    p_psector_CalculateChecksum = (uint32_t (*)(psector_page_t *psector_page))0x030050bdU;
+
+    return p_psector_CalculateChecksum(psector_page);
+}
+
+/* Access helper functions */
+/*!
+ * @brief This function returns the CustomerId field.
+ *
+ * @param  none
+ *
+ * @return  CustomerId on 64 bit word
+ */
+static inline uint64_t psector_Read_CustomerId(void)
+{
+    uint64_t (*p_psector_Read_CustomerId)(void);
+    p_psector_Read_CustomerId = (uint64_t (*)(void))0x030051ddU;
+
+    return p_psector_Read_CustomerId();
+}
+
+/*!
+ * @brief This function returns the ROM patch information read from the PFLASH.
+ *
+ * @param  patch_region_sz: pointer on unsigned long to return ROM patch size
+ * @param  patch_region_addr: pointer on unsigned long to return ROM patch address
+ * @param  patch_checksum: pointer on unsigned long to return ROM patch checksum value
+ * @param  patch_checksum_valid: pointer on unsigned long to return ROM patch checksum validity (0..1)
+ *
+ * @return -1 if erro is found (any of the input parameters is NULL) or PFLASH is unreadable.
+ */
+static inline int psector_Read_RomPatchInfo(uint32_t *patch_region_sz,
+                                            uint32_t *patch_region_addr,
+                                            uint32_t *patch_checksum,
+                                            uint32_t *patch_checksum_valid)
+{
+    int (*p_psector_Read_RomPatchInfo)(uint32_t *patch_region_sz, uint32_t *patch_region_addr, uint32_t *patch_checksum,
+                                       uint32_t *patch_checksum_valid);
+    p_psector_Read_RomPatchInfo = (int (*)(uint32_t *patch_region_sz, uint32_t *patch_region_addr,
+                                           uint32_t *patch_checksum, uint32_t *patch_checksum_valid))0x03005209U;
+
+    return p_psector_Read_RomPatchInfo(patch_region_sz, patch_region_addr, patch_checksum, patch_checksum_valid);
+}
+
+/*!
+ * @brief This function returns the image authentication level from the PFLASH.
+ *
+ * @param  none.
+ *
+ * @return AUH_NONE if PFLASH unreadable, or the image_authentication_level field value if readable.
+ */
+static inline uint16_t psector_Read_ImgAuthLevel(void)
+{
+    uint16_t (*p_psector_Read_ImgAuthLevel)(void);
+    p_psector_Read_ImgAuthLevel = (uint16_t (*)(void))0x03005299U;
+
+    return p_psector_Read_ImgAuthLevel();
+}
+
+/*!
+ * @brief This function returns the app search granularity value from the PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, or the app_search_granularity field value if not 0 or 4096 if 0.
+ */
+static inline uint32_t psector_Read_AppSearchGranularity(void)
+{
+    uint32_t (*p_psector_Read_AppSearchGranularity)(void);
+    p_psector_Read_AppSearchGranularity = (uint32_t (*)(void))0x030052d5U;
+
+    return p_psector_Read_AppSearchGranularity();
+}
+
+/*!
+ * @brief This function returns the Qspi app search granularity value from the PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, or the qspi_app_search_granularity field value.
+ */
+static inline uint32_t psector_Read_QspiAppSearchGranularity(void)
+{
+    uint32_t (*p_psector_Read_QspiAppSearchGranularity)(void);
+    p_psector_Read_QspiAppSearchGranularity = (uint32_t (*)(void))0x03005305U;
+
+    return p_psector_Read_QspiAppSearchGranularity();
+}
+
+/*!
+ * @brief This function returns the DeviceId value from the PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, or the device_id field value.
+ */
+static inline uint64_t psector_Read_DeviceId(void)
+{
+    uint64_t (*p_psector_Read_DeviceId)(void);
+    p_psector_Read_DeviceId = (uint64_t (*)(void))0x03005329U;
+
+    return p_psector_Read_DeviceId();
+}
+
+/*!
+ * @brief This function returns the unlock key value from the PFLASH.
+ *
+ * @param  valid:  pointer on int to store validity of key (unlock_key_valid field)
+ * @param  key:   pointer on 256 byte storage to receive the key read from PFLASH
+ * @param  raw:    raw  if raw is not requested (0), the key is deciphered
+ *                using the internal AES fused key.
+ *
+ * @return -1 if read error occurred, 0 otherwise
+ */
+static inline int psector_Read_UnlockKey(int *valid, uint8_t key[256], bool raw)
+{
+    int (*p_psector_Read_UnlockKey)(int *valid, uint8_t key[256], bool raw);
+    p_psector_Read_UnlockKey = (int (*)(int *valid, uint8_t key[256], bool raw))0x03005519U;
+
+    return p_psector_Read_UnlockKey(valid, key, raw);
+}
+
+/*!
+ * @brief This function returns the ISP protocol AES key from PFLASH.
+ *
+ * @param  key:   pointer on 16 byte storage to receive the key read from PFLASH.
+ *
+ * @return -1 if read error occurred, 0 otherwise
+ */
+static inline int psector_Read_ISP_protocol_key(uint8_t key[16])
+{
+    int (*p_psector_Read_ISP_protocol_key)(uint8_t key[16]);
+    p_psector_Read_ISP_protocol_key = (int (*)(uint8_t key[16]))0x03005355U;
+
+    return p_psector_Read_ISP_protocol_key(key);
+}
+
+/*!
+ * @brief This function returns the IEEE-802.15.4 Mac address first instance from PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 64 bit word 0 if field unreadable, otherwise MAC address contained in ieee_mac_id1 field.
+ */
+static inline uint64_t psector_ReadIeee802_15_4_MacId1(void)
+{
+    uint64_t (*p_psector_ReadIeee802_15_4_MacId1)(void);
+    p_psector_ReadIeee802_15_4_MacId1 = (uint64_t (*)(void))0x030053b1U;
+
+    return p_psector_ReadIeee802_15_4_MacId1();
+}
+
+/*!
+ * @brief This function returns the IEEE-802.15.4 Mac address second instance from PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 64 bit word 0 if field unreadable, otherwise MAC address contained in ieee_mac_id2 field.
+ */
+static inline uint64_t psector_ReadIeee802_15_4_MacId2(void)
+{
+    uint64_t (*p_psector_ReadIeee802_15_4_MacId2)(void);
+    p_psector_ReadIeee802_15_4_MacId2 = (uint64_t (*)(void))0x03005385U;
+
+    return p_psector_ReadIeee802_15_4_MacId2();
+}
+
+/*!
+ * @brief This function returns the Min Device id from PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, otherwise min_device_id field content.
+ */
+static inline uint64_t psector_Read_MinDeviceId(void)
+{
+    uint64_t (*p_psector_Read_MinDeviceId)(void);
+    p_psector_Read_MinDeviceId = (uint64_t (*)(void))0x030053ddU;
+
+    return p_psector_Read_MinDeviceId();
+}
+
+/*!
+ * @brief This function returns the Max Device id from PFLASH.
+ *
+ * @param  none.
+ *
+ * @return 0 if PFLASH unreadable, otherwise max_device_id field content.
+ */
+static inline uint64_t psector_Read_MaxDeviceId(void)
+{
+    uint64_t (*p_psector_Read_MaxDeviceId)(void);
+    p_psector_Read_MaxDeviceId = (uint64_t (*)(void))0x03005409U;
+
+    return p_psector_Read_MaxDeviceId();
+}
+
+/* Helper functions for reading and writing image data */
+
+/*!
+ * @brief This function returns the Min Version from PAGE0.
+ *
+ * @param  none.
+ *
+ * @return if PAGE0 unreadable, otherwise MinVersion field content.
+ */
+static inline uint32_t psector_Read_MinVersion(void)
+{
+    uint32_t (*p_psector_Read_MinVersion)(void);
+    p_psector_Read_MinVersion = (uint32_t (*)(void))0x03005439U;
+
+    return p_psector_Read_MinVersion();
+}
+
+/*!
+ * @brief This function is used to set the selected image address and MinVersion into PAGE0.
+ *
+ * @param  image_addr:   32 bit value to be written to SelectImageAddress.
+ * @param  min_version:   32 bit value to be written to MinVersion.
+ *
+ * @return psector_write_status_t status of operation see @psector_WriteUpdatePage
+ */
+static inline psector_write_status_t psector_SetEscoreImageData(uint32_t image_addr, uint32_t min_version)
+{
+    psector_write_status_t (*p_psector_SetEscoreImageData)(uint32_t image_addr, uint32_t min_version);
+    p_psector_SetEscoreImageData = (psector_write_status_t (*)(uint32_t image_addr, uint32_t min_version))0x0300545dU;
+
+    return p_psector_SetEscoreImageData(image_addr, min_version);
+}
+
+/*!
+ * @brief This function returns the image address and min version value from PAGE0.
+ *
+ * @param  image_addr:   pointer on 32 bit word to receive SelectImageAddress value.
+ * @param  min_versionm:   pointer on 32 bit word to receive SelectImageAddress value.
+ *
+ * @return -1 if read error occurred, 0 otherwise
+ */
+static inline psector_page_state_t psector_ReadEscoreImageData(uint32_t *image_addr, uint32_t *min_version)
+{
+    psector_page_state_t (*p_psector_ReadEscoreImageData)(uint32_t *image_addr, uint32_t *min_version);
+    p_psector_ReadEscoreImageData = (psector_page_state_t (*)(uint32_t *image_addr, uint32_t *min_version))0x03005491U;
+
+    return p_psector_ReadEscoreImageData(image_addr, min_version);
+}
+
+/*!
+ * @brief This function returns the unlock key value from PAGE0.
+ *
+ * @param  valid:  pointer on int to store validity of key (img_pk_valid field)
+ * @param  key:   pointer on 256 byte storage to receive the key read from PAGE0
+ * @param  raw:   raw  if raw is not requested (0), the key is deciphered
+ *                using the internal AES fused key.
+ *
+ * @return -1 if read error occurred, 0 otherwise
+ */
+static inline int psector_Read_ImagePubKey(int *valid, uint8_t key[256], bool raw)
+{
+    int (*p_psector_Read_ImagePubKey)(int *valid, uint8_t key[256], bool raw);
+    p_psector_Read_ImagePubKey = (int (*)(int *valid, uint8_t key[256], bool raw))0x03005531U;
+
+    return p_psector_Read_ImagePubKey(valid, key, raw);
+}
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ROM_PSECTOR_H_ */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/fsl_device_registers.h b/third_party/nxp/K32W061DK6/devices/K32W061/fsl_device_registers.h
new file mode 100755
index 0000000..396fb9c
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/fsl_device_registers.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __FSL_DEVICE_REGISTERS_H__
+#define __FSL_DEVICE_REGISTERS_H__
+
+/*
+ * Include the cpu specific register header files.
+ *
+ * The CPU macro should be declared in the project or makefile.
+ */
+#if (defined(CPU_K32W061HN) || defined(CPU_K32W041HN) || defined(CPU_JN518X))
+
+#define JN518X_SERIES
+
+#define K32W061_SERIES
+
+/* CMSIS-style register definitions */
+#include "K32W061.h"
+/* CPU specific feature definitions */
+#include "K32W061_features.h"
+
+#else
+#error "No valid CPU defined!"
+#endif
+
+#endif /* __FSL_DEVICE_REGISTERS_H__ */
+
+/*******************************************************************************
+ * EOF
+ ******************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/mcuxpresso/startup_k32w061.c b/third_party/nxp/K32W061DK6/devices/K32W061/mcuxpresso/startup_k32w061.c
new file mode 100755
index 0000000..fdf1128
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/mcuxpresso/startup_k32w061.c
@@ -0,0 +1,917 @@
+//*****************************************************************************
+// K32W061 startup code for use with MCUXpresso IDE
+//
+// Version : 211119
+//*****************************************************************************
+//
+// Copyright 2016-2019 NXP
+// All rights reserved.
+//
+// SPDX-License-Identifier: BSD-3-Clause
+//*****************************************************************************
+
+#if defined(DEBUG)
+#pragma GCC push_options
+#pragma GCC optimize("Og")
+#endif // (DEBUG)
+
+#if defined(__cplusplus)
+#ifdef __REDLIB__
+#error Redlib does not support C++
+#else
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+extern "C" {
+extern void __libc_init_array(void);
+}
+#endif
+#endif
+
+#define WEAK __attribute__((weak))
+#define WEAK_AV __attribute__((weak, section(".after_vectors")))
+#define ALIAS(f) __attribute__((weak, alias(#f)))
+
+//*****************************************************************************
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+//*****************************************************************************
+// Variable to store CRP value in. Will be placed automatically
+// by the linker when "Enable Code Read Protect" selected.
+// See crp.h header for more information
+//*****************************************************************************
+#if (defined(__MCUXPRESSO))
+#include <NXP/crp.h>
+__CRP const unsigned int CRP_WORD = CRP_NO_CRP;
+#endif
+
+#include "fsl_device_registers.h"
+#include "rom_api.h"
+
+#define PMC_PDSLEEPCFG_PDEN_PD_MEM_ALL_MASK                                                                   \
+    (PMC_PDSLEEPCFG_PDEN_PD_MEM0_MASK | PMC_PDSLEEPCFG_PDEN_PD_MEM1_MASK | PMC_PDSLEEPCFG_PDEN_PD_MEM2_MASK | \
+     PMC_PDSLEEPCFG_PDEN_PD_MEM3_MASK | PMC_PDSLEEPCFG_PDEN_PD_MEM4_MASK | PMC_PDSLEEPCFG_PDEN_PD_MEM5_MASK | \
+     PMC_PDSLEEPCFG_PDEN_PD_MEM6_MASK | PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK | PMC_PDSLEEPCFG_PDEN_PD_MEM8_MASK | \
+     PMC_PDSLEEPCFG_PDEN_PD_MEM9_MASK | PMC_PDSLEEPCFG_PDEN_PD_MEM10_MASK | PMC_PDSLEEPCFG_PDEN_PD_MEM11_MASK)
+
+//*****************************************************************************
+// Declaration of external SystemInit function
+//*****************************************************************************
+extern WEAK void SystemInit(void);
+
+//*****************************************************************************
+// Declaration of external WarmMain function
+//*****************************************************************************
+extern WEAK void WarmMain(void);
+
+//*****************************************************************************
+// Forward declaration of the core exception handlers.
+// When the application defines a handler (with the same name), this will
+// automatically take precedence over these weak definitions.
+// If your application is a C++ one, then any interrupt handlers defined
+// in C++ files within in your main application will need to have C linkage
+// rather than C++ linkage. To do this, make sure that you are using extern "C"
+// { .... } around the interrupt handler within your main application code.
+//*****************************************************************************
+void ResetISR(void);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void MemManage_Handler(void);
+WEAK void BusFault_Handler(void);
+WEAK void UsageFault_Handler(void);
+WEAK void SVC_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_Handler(void);
+WEAK void IntDefaultHandler(void);
+
+//*****************************************************************************
+// Forward declaration of the application IRQ handlers. When the application
+// defines a handler (with the same name), this will automatically take
+// precedence over weak definitions below
+//*****************************************************************************
+WEAK void WDT_BOD_IRQHandler(void);
+WEAK void DMA0_IRQHandler(void);
+WEAK void GINT0_IRQHandler(void);
+WEAK void CIC_IRB_IRQHandler(void);
+WEAK void PIN_INT0_IRQHandler(void);
+WEAK void PIN_INT1_IRQHandler(void);
+WEAK void PIN_INT2_IRQHandler(void);
+WEAK void PIN_INT3_IRQHandler(void);
+WEAK void SPIFI0_IRQHandler(void);
+WEAK void CTIMER0_IRQHandler(void);
+WEAK void CTIMER1_IRQHandler(void);
+WEAK void FLEXCOMM0_IRQHandler(void);
+WEAK void FLEXCOMM1_IRQHandler(void);
+WEAK void FLEXCOMM2_IRQHandler(void);
+WEAK void FLEXCOMM3_IRQHandler(void);
+WEAK void FLEXCOMM4_IRQHandler(void);
+WEAK void FLEXCOMM5_IRQHandler(void);
+WEAK void PWM0_IRQHandler(void);
+WEAK void PWM1_IRQHandler(void);
+WEAK void PWM2_IRQHandler(void);
+WEAK void PWM3_IRQHandler(void);
+WEAK void PWM4_IRQHandler(void);
+WEAK void PWM5_IRQHandler(void);
+WEAK void PWM6_IRQHandler(void);
+WEAK void PWM7_IRQHandler(void);
+WEAK void PWM8_IRQHandler(void);
+WEAK void PWM9_IRQHandler(void);
+WEAK void PWM10_IRQHandler(void);
+WEAK void FLEXCOMM6_IRQHandler(void);
+WEAK void RTC_IRQHandler(void);
+WEAK void NFCTag_IRQHandler(void);
+WEAK void MAILBOX_IRQHandler(void);
+WEAK void ADC0_SEQA_IRQHandler(void);
+WEAK void ADC0_SEQB_IRQHandler(void);
+WEAK void ADC0_THCMP_IRQHandler(void);
+WEAK void DMIC0_IRQHandler(void);
+WEAK void HWVAD0_IRQHandler(void);
+WEAK void BLE_DP_IRQHandler(void);
+WEAK void BLE_DP0_IRQHandler(void);
+WEAK void BLE_DP1_IRQHandler(void);
+WEAK void BLE_DP2_IRQHandler(void);
+WEAK void BLE_LL_ALL_IRQHandler(void);
+WEAK void ZIGBEE_MAC_IRQHandler(void);
+WEAK void ZIGBEE_MODEM_IRQHandler(void);
+WEAK void RFP_TMU_IRQHandler(void);
+WEAK void RFP_AGC_IRQHandler(void);
+WEAK void ISO7816_IRQHandler(void);
+WEAK void ANA_COMP_IRQHandler(void);
+WEAK void WAKE_UP_TIMER0_IRQHandler(void);
+WEAK void WAKE_UP_TIMER1_IRQHandler(void);
+WEAK void PVTVF0_AMBER_IRQHandler(void);
+WEAK void PVTVF0_RED_IRQHandler(void);
+WEAK void PVTVF1_AMBER_IRQHandler(void);
+WEAK void PVTVF1_RED_IRQHandler(void);
+WEAK void BLE_WAKE_UP_TIMER_IRQHandler(void);
+WEAK void SHA_IRQHandler(void);
+
+//*****************************************************************************
+// Forward declaration of the driver IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the driver
+// defines a handler (with the same name), this will automatically take
+// precedence over these weak definitions
+//*****************************************************************************
+void WDT_BOD_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void DMA0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void GINT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void CIC_IRB_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void SPIFI0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void CTIMER0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void CTIMER1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM4_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM5_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM4_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM5_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM6_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM7_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM8_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM9_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM10_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void FLEXCOMM6_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void RTC_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void NFCTag_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void MAILBOX_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ADC0_SEQA_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ADC0_SEQB_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ADC0_THCMP_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void DMIC0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void HWVAD0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_DP_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_DP0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_DP1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_DP2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_LL_ALL_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ZIGBEE_MAC_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ZIGBEE_MODEM_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void RFP_TMU_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void RFP_AGC_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ISO7816_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void ANA_COMP_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void WAKE_UP_TIMER0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void WAKE_UP_TIMER1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTVF0_AMBER_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTVF0_RED_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTVF1_AMBER_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTVF1_RED_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void BLE_WAKE_UP_TIMER_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+void SHA_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+// The entry point for the application.
+// __main() is the entry point for Redlib based applications
+// main() is the entry point for Newlib based applications
+//*****************************************************************************
+#if defined(__REDLIB__)
+extern void __main(void);
+#endif
+extern int main(void);
+
+//*****************************************************************************
+// External declaration for the pointer to the stack top from the Linker Script
+//*****************************************************************************
+extern void _vStackTop(void);
+//*****************************************************************************
+// External declaration for LPC MCU vector table checksum from  Linker Script
+//*****************************************************************************
+WEAK extern void __valid_user_code_checksum();
+
+//*****************************************************************************
+//*****************************************************************************
+#if defined(__cplusplus)
+} // extern "C"
+#endif
+//*****************************************************************************
+// The vector table.
+// This relies on the linker script to place at correct location in memory.
+//*****************************************************************************
+extern void (*const g_pfnVectors[])(void);
+extern void *__Vectors __attribute__((alias("g_pfnVectors")));
+
+__attribute__((used, section(".isr_vector"))) void (*const g_pfnVectors[])(void) = {
+    // Core Level - CM4
+    &_vStackTop,                // The initial stack pointer
+    ResetISR,                   // The reset handler
+    NMI_Handler,                // The NMI handler
+    HardFault_Handler,          // The hard fault handler
+    MemManage_Handler,          // The MPU fault handler
+    BusFault_Handler,           // The bus fault handler
+    UsageFault_Handler,         // The usage fault handler
+    __valid_user_code_checksum, // LPC MCU checksum
+    0,                          // ECRP
+    0,                          // Reserved
+    0,                          // Reserved
+    SVC_Handler,                // SVCall handler
+    0,                          // Reserved
+    0,                          // Reserved
+    PendSV_Handler,             // The PendSV handler
+    SysTick_Handler,            // The SysTick handler
+
+    // Chip Level - K32W061
+    WDT_BOD_IRQHandler,           // 16: System (BOD, Watchdog Timer, Flash controller) interrupt
+    DMA0_IRQHandler,              // 17: DMA interrupt
+    GINT0_IRQHandler,             // 18: GPIO global interrupt
+    CIC_IRB_IRQHandler,           // 19: Infra Red Blaster interrupt
+    PIN_INT0_IRQHandler,          // 20: Pin Interrupt and Pattern matching 0
+    PIN_INT1_IRQHandler,          // 21: Pin Interrupt and Pattern matching 1
+    PIN_INT2_IRQHandler,          // 22: Pin Interrupt and Pattern matching 2
+    PIN_INT3_IRQHandler,          // 23: Pin Interrupt and Pattern matching 3
+    SPIFI0_IRQHandler,            // 24: Quad-SPI flash interface interrupt
+    CTIMER0_IRQHandler,           // 25: Counter/Timer 0 interrupt
+    CTIMER1_IRQHandler,           // 26: Counter/Timer 1 interrupt
+    FLEXCOMM0_IRQHandler,         // 27: Flexcomm Interface 0 (USART0, FLEXCOMM0)
+    FLEXCOMM1_IRQHandler,         // 28: Flexcomm Interface 1 (USART1, FLEXCOMM1)
+    FLEXCOMM2_IRQHandler,         // 29: Flexcomm Interface 2 (I2C0, FLEXCOMM2)
+    FLEXCOMM3_IRQHandler,         // 30: Flexcomm Interface 3 (I2C1, FLEXCOMM3)
+    FLEXCOMM4_IRQHandler,         // 31: Flexcomm Interface 4 (SPI0, FLEXCOMM4)
+    FLEXCOMM5_IRQHandler,         // 32: Flexcomm Interface 5 (SPI5, FLEXCOMM)
+    PWM0_IRQHandler,              // 33: PWM channel 0 interrupt
+    PWM1_IRQHandler,              // 34: PWM channel 1 interrupt
+    PWM2_IRQHandler,              // 35: PWM channel 2 interrupt
+    PWM3_IRQHandler,              // 36: PWM channel 3 interrupt
+    PWM4_IRQHandler,              // 37: PWM channel 4 interrupt
+    PWM5_IRQHandler,              // 38: PWM channel 5 interrupt
+    PWM6_IRQHandler,              // 39: PWM channel 6  interrupt
+    PWM7_IRQHandler,              // 40: PWM channel 7 interrupt
+    PWM8_IRQHandler,              // 41: PWM channel 8 interrupt
+    PWM9_IRQHandler,              // 42: PWM channel 9 interrupt
+    PWM10_IRQHandler,             // 43: PWM channel 10 interrupt
+    FLEXCOMM6_IRQHandler,         // 44: Flexcomm Interface6 (I2C2, FLEXCOMM6)
+    RTC_IRQHandler,               // 45: Real Time Clock interrupt
+    NFCTag_IRQHandler,            // 46: NFC Tag interrupt
+    MAILBOX_IRQHandler,           // 47: Mailbox interrupts, Wake-up from Deep Sleep interrupt
+    ADC0_SEQA_IRQHandler,         // 48: ADC Sequence A interrupt
+    ADC0_SEQB_IRQHandler,         // 49: ADC Sequence B interrupt
+    ADC0_THCMP_IRQHandler,        // 50: ADC Threshold compare and overrun interrupt
+    DMIC0_IRQHandler,             // 51: DMIC interrupt
+    HWVAD0_IRQHandler,            // 52: Hardware Voice activity detection interrupt
+    BLE_DP_IRQHandler,            // 53: BLE Data Path interrupt
+    BLE_DP0_IRQHandler,           // 54: BLE Data Path interrupt 0
+    BLE_DP1_IRQHandler,           // 55: BLE Data Path interrupt 1
+    BLE_DP2_IRQHandler,           // 56: BLE Data Path interrupt 2
+    BLE_LL_ALL_IRQHandler,        // 57: All BLE link layer interrupts
+    ZIGBEE_MAC_IRQHandler,        // 58: Zigbee MAC interrupt
+    ZIGBEE_MODEM_IRQHandler,      // 59: Zigbee MoDem interrupt
+    RFP_TMU_IRQHandler,           // 60: RFP Timing Managemnt Unit (TMU) interrupt
+    RFP_AGC_IRQHandler,           // 61: RFP AGC interrupt
+    ISO7816_IRQHandler,           // 62: ISO7816 controller interrupt
+    ANA_COMP_IRQHandler,          // 63: Analog Comparator interrupt
+    WAKE_UP_TIMER0_IRQHandler,    // 64: Wake up Timer 0 interrupt
+    WAKE_UP_TIMER1_IRQHandler,    // 65: Wake up Timer 1 interrupt
+    PVTVF0_AMBER_IRQHandler,      // 66: PVT Monitor interrupt
+    PVTVF0_RED_IRQHandler,        // 67: PVT Monitor interrupt
+    PVTVF1_AMBER_IRQHandler,      // 68: PVT Monitor interrupt
+    PVTVF1_RED_IRQHandler,        // 69: PVT Monitor interrupt
+    BLE_WAKE_UP_TIMER_IRQHandler, // 70: BLE Wake up Timer interrupt
+    SHA_IRQHandler,               // 71: SHA interrupt
+
+}; /* End of g_pfnVectors */
+
+//*****************************************************************************
+// Functions to carry out the initialization of RW and BSS data sections. These
+// are written as separate functions rather than being inlined within the
+// ResetISR() function in order to cope with MCUs with multiple banks of
+// memory.
+//*****************************************************************************
+__attribute__((section(".after_vectors.init_data"))) void data_init(unsigned int romstart,
+                                                                    unsigned int start,
+                                                                    unsigned int len)
+{
+    unsigned int *pulDest = (unsigned int *)start;
+    unsigned int *pulSrc  = (unsigned int *)romstart;
+    unsigned int loop;
+    for (loop = 0; loop < len; loop = loop + 4)
+        *pulDest++ = *pulSrc++;
+}
+
+__attribute__((section(".after_vectors.init_bss"))) void bss_init(unsigned int start, unsigned int len)
+{
+    unsigned int *pulDest = (unsigned int *)start;
+    unsigned int loop;
+    for (loop = 0; loop < len; loop = loop + 4)
+        *pulDest++ = 0;
+}
+
+//*****************************************************************************
+// The following symbols are constructs generated by the linker, indicating
+// the location of various points in the "Global Section Table". This table is
+// created by the linker via the Code Red managed linker script mechanism. It
+// contains the load address, execution address and length of each RW data
+// section and the execution and length of each BSS (zero initialized) section.
+//*****************************************************************************
+extern unsigned int __data_section_table;
+extern unsigned int __data_section_table_end;
+extern unsigned int __bss_section_table;
+extern unsigned int __bss_section_table_end;
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+__attribute__((section(".after_vectors.reset"))) void ResetISR(void)
+{
+    // Disable interrupts
+    __asm volatile("cpsid i");
+
+    // Enable SRAM clock used by Stack
+    __asm volatile(
+        "LDR R0, =0x40000220\n\t"
+        "MOV R1, #56\n\t"
+        "STR R1, [R0]");
+
+    __asm volatile(
+        ".set   cpu_ctrl,       0x40000800\t\n"
+        ".set   coproc_boot,    0x40000804\t\n"
+        ".set   coproc_stack,   0x40000808\t\n"
+        "LDR    R0,=coproc_boot\t\n"  // load co-processor boot address (from CPBOOT)
+        "LDR    R0,[R0]\t\n"          // get address to branch to
+        "MOVS   R0,R0\t\n"            // Check if 0
+        "BEQ.N  masterboot\t\n"       // if zero in boot reg, we just branch to  real reset
+        "LDR    R1,=coproc_stack\t\n" // load co-processor stack pointer (from CPSTACK)
+        "LDR    R1,[R1]\t\n"
+        "MOV    SP,R1\t\n"
+        "BX     R0\t\n" // branch to boot address
+        "masterboot:\t\n"
+        "LDR    R0, =ResetISR2\t\n" // jump to 'real' reset handler
+        "BX     R0\t\n");
+}
+
+__attribute__((used, section(".after_vectors"))) void ResetISR2(void)
+{
+    if (WarmMain)
+    {
+        unsigned int warm_start;
+        uint32_t pmc_lpmode;
+        uint32_t pmc_resetcause;
+        uint32_t pwr_pdsleepcfg;
+
+        pmc_resetcause = PMC->RESETCAUSE;
+        pwr_pdsleepcfg = PMC->PDSLEEPCFG;
+
+        pmc_lpmode = BOOT_GetStartPowerMode();
+
+        warm_start = (pmc_lpmode == 0x02); /* coming from power down mode*/
+
+        // check if the reset cause is only a timer wakeup or io wakeup with all memory banks held
+        warm_start &= (!(pmc_resetcause & (PMC_RESETCAUSE_POR_MASK | PMC_RESETCAUSE_PADRESET_MASK |
+                                           PMC_RESETCAUSE_BODRESET_MASK | PMC_RESETCAUSE_SYSTEMRESET_MASK |
+                                           PMC_RESETCAUSE_WDTRESET_MASK | PMC_RESETCAUSE_WAKEUPIORESET_MASK)) &&
+                       (pmc_resetcause & PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK) &&
+                       ((pwr_pdsleepcfg & PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK) == 0x0) /* BANK7 memory bank held */
+                       && (pwr_pdsleepcfg & PMC_PDSLEEPCFG_PDEN_LDO_MEM_MASK)       /* LDO MEM enabled */
+        );
+
+        if (warm_start)
+        {
+            if (SYSCON->CPSTACK)
+            {
+                /* if CPSTACK is not NULL, switch to CPSTACK value so we avoid to corrupt the stack used before power
+                 * down Note: it looks like enough to switch to new SP now and not earlier */
+                __asm volatile(
+                    ".set   coproc_stack,   0x40000808\t\n"
+                    "LDR    R1,=coproc_stack\t\n" // load co-processor stack pointer (from CPSTACK)
+                    "LDR    R1,[R1]\t\n"
+                    "MOV    SP,R1\t\n");
+            }
+
+            // Check to see if we are running the code from a non-zero
+            // address (eg RAM, external flash), in which case we need
+            // to modify the VTOR register to tell the CPU that the
+            // vector table is located at a non-0x0 address.
+            unsigned int *pSCB_VTOR = (unsigned int *)0xE000ED08;
+            if (((unsigned int)g_pfnVectors != 0))
+            {
+                // CMSIS : SCB->VTOR = <address of vector table>
+                *pSCB_VTOR = (unsigned int)g_pfnVectors;
+            }
+
+            if (SystemInit != 0)
+            {
+                SystemInit();
+            }
+
+            WarmMain();
+
+            //
+            // WarmMain() shouldn't return, but if it does, we'll just enter an infinite loop
+            //
+            while (1)
+            {
+                ;
+            }
+        }
+    }
+
+#if defined(__USE_CMSIS)
+    // If __USE_CMSIS defined, then call CMSIS SystemInit code
+    SystemInit();
+
+#endif // (__USE_CMSIS)
+
+    //
+    // Copy the data sections from flash to SRAM.
+    //
+    unsigned int LoadAddr, ExeAddr, SectionLen;
+    unsigned int *SectionTableAddr;
+
+    // Load base address of Global Section Table
+    SectionTableAddr = &__data_section_table;
+
+    // Copy the data sections from flash to SRAM.
+    while (SectionTableAddr < &__data_section_table_end)
+    {
+        LoadAddr   = *SectionTableAddr++;
+        ExeAddr    = *SectionTableAddr++;
+        SectionLen = *SectionTableAddr++;
+        data_init(LoadAddr, ExeAddr, SectionLen);
+    }
+
+    // At this point, SectionTableAddr = &__bss_section_table;
+    // Zero fill the bss segment
+    while (SectionTableAddr < &__bss_section_table_end)
+    {
+        ExeAddr    = *SectionTableAddr++;
+        SectionLen = *SectionTableAddr++;
+        bss_init(ExeAddr, SectionLen);
+    }
+
+#if !defined(__USE_CMSIS)
+// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code
+// will enable the FPU
+#if defined(__VFP_FP__) && !defined(__SOFTFP__)
+    //
+    // Code to enable the Cortex-M4 FPU only included
+    // if appropriate build options have been selected.
+    // Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C)
+    //
+    // Read CPACR (located at address 0xE000ED88)
+    // Set bits 20-23 to enable CP10 and CP11 coprocessors
+    // Write back the modified value to the CPACR
+    __asm volatile(
+        "LDR.W R0, =0xE000ED88\n\t"
+        "LDR R1, [R0]\n\t"
+        "ORR R1, R1, #(0xF << 20)\n\t"
+        "STR R1, [R0]");
+#endif // (__VFP_FP__) && !(__SOFTFP__)
+#endif // (__USE_CMSIS)
+
+#if !defined(__USE_CMSIS)
+    // Assume that if __USE_CMSIS defined, then CMSIS SystemInit code
+    // will setup the VTOR register
+
+    // Check to see if we are running the code from a non-zero
+    // address (eg RAM, external flash), in which case we need
+    // to modify the VTOR register to tell the CPU that the
+    // vector table is located at a non-0x0 address.
+    unsigned int *pSCB_VTOR = (unsigned int *)0xE000ED08;
+    if ((unsigned int *)g_pfnVectors != (unsigned int *)0x00000000)
+    {
+        *pSCB_VTOR = (unsigned int)g_pfnVectors;
+    }
+#endif // (__USE_CMSIS)
+
+#if defined(__cplusplus)
+    //
+    // Call C++ library initialisation
+    //
+    __libc_init_array();
+#endif
+
+    // Reenable interrupts
+    __asm volatile("cpsie i");
+
+#if defined(__REDLIB__)
+    // Call the Redlib library, which in turn calls main()
+    __main();
+#else
+    main();
+#endif
+
+    //
+    // main() shouldn't return, but if it does, we'll just enter an infinite loop
+    //
+    while (1)
+    {
+        ;
+    }
+}
+
+//*****************************************************************************
+// Default core exception handlers. Override the ones here by defining your own
+// handler routines in your application code.
+//*****************************************************************************
+WEAK_AV void NMI_Handler(void)
+{
+    while (1)
+    {
+    }
+}
+
+WEAK_AV void HardFault_Handler(void)
+{
+    while (1)
+    {
+    }
+}
+
+WEAK_AV void MemManage_Handler(void)
+{
+    while (1)
+    {
+    }
+}
+
+WEAK_AV void BusFault_Handler(void)
+{
+    while (1)
+    {
+    }
+}
+
+WEAK_AV void UsageFault_Handler(void)
+{
+    while (1)
+    {
+    }
+}
+
+WEAK_AV void SVC_Handler(void)
+{
+    while (1)
+    {
+    }
+}
+
+WEAK_AV void PendSV_Handler(void)
+{
+    while (1)
+    {
+    }
+}
+
+WEAK_AV void SysTick_Handler(void)
+{
+    while (1)
+    {
+    }
+}
+
+//*****************************************************************************
+// Processor ends up here if an unexpected interrupt occurs or a specific
+// handler is not present in the application code.
+//*****************************************************************************
+WEAK_AV void IntDefaultHandler(void)
+{
+    while (1)
+    {
+    }
+}
+
+//*****************************************************************************
+// Default application exception handlers. Override the ones here by defining
+// your own handler routines in your application code. These routines call
+// driver exception handlers or IntDefaultHandler() if no driver exception
+// handler is included.
+//*****************************************************************************
+WEAK void WDT_BOD_IRQHandler(void)
+{
+    WDT_BOD_DriverIRQHandler();
+}
+
+WEAK void DMA0_IRQHandler(void)
+{
+    DMA0_DriverIRQHandler();
+}
+
+WEAK void GINT0_IRQHandler(void)
+{
+    GINT0_DriverIRQHandler();
+}
+
+WEAK void CIC_IRB_IRQHandler(void)
+{
+    CIC_IRB_DriverIRQHandler();
+}
+
+WEAK void PIN_INT0_IRQHandler(void)
+{
+    PIN_INT0_DriverIRQHandler();
+}
+
+WEAK void PIN_INT1_IRQHandler(void)
+{
+    PIN_INT1_DriverIRQHandler();
+}
+
+WEAK void PIN_INT2_IRQHandler(void)
+{
+    PIN_INT2_DriverIRQHandler();
+}
+
+WEAK void PIN_INT3_IRQHandler(void)
+{
+    PIN_INT3_DriverIRQHandler();
+}
+
+WEAK void SPIFI0_IRQHandler(void)
+{
+    SPIFI0_DriverIRQHandler();
+}
+
+WEAK void CTIMER0_IRQHandler(void)
+{
+    CTIMER0_DriverIRQHandler();
+}
+
+WEAK void CTIMER1_IRQHandler(void)
+{
+    CTIMER1_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM0_IRQHandler(void)
+{
+    FLEXCOMM0_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM1_IRQHandler(void)
+{
+    FLEXCOMM1_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM2_IRQHandler(void)
+{
+    FLEXCOMM2_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM3_IRQHandler(void)
+{
+    FLEXCOMM3_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM4_IRQHandler(void)
+{
+    FLEXCOMM4_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM5_IRQHandler(void)
+{
+    FLEXCOMM5_DriverIRQHandler();
+}
+
+WEAK void PWM0_IRQHandler(void)
+{
+    PWM0_DriverIRQHandler();
+}
+
+WEAK void PWM1_IRQHandler(void)
+{
+    PWM1_DriverIRQHandler();
+}
+
+WEAK void PWM2_IRQHandler(void)
+{
+    PWM2_DriverIRQHandler();
+}
+
+WEAK void PWM3_IRQHandler(void)
+{
+    PWM3_DriverIRQHandler();
+}
+
+WEAK void PWM4_IRQHandler(void)
+{
+    PWM4_DriverIRQHandler();
+}
+
+WEAK void PWM5_IRQHandler(void)
+{
+    PWM5_DriverIRQHandler();
+}
+
+WEAK void PWM6_IRQHandler(void)
+{
+    PWM6_DriverIRQHandler();
+}
+
+WEAK void PWM7_IRQHandler(void)
+{
+    PWM7_DriverIRQHandler();
+}
+
+WEAK void PWM8_IRQHandler(void)
+{
+    PWM8_DriverIRQHandler();
+}
+
+WEAK void PWM9_IRQHandler(void)
+{
+    PWM9_DriverIRQHandler();
+}
+
+WEAK void PWM10_IRQHandler(void)
+{
+    PWM10_DriverIRQHandler();
+}
+
+WEAK void FLEXCOMM6_IRQHandler(void)
+{
+    FLEXCOMM6_DriverIRQHandler();
+}
+
+WEAK void RTC_IRQHandler(void)
+{
+    RTC_DriverIRQHandler();
+}
+
+WEAK void NFCTag_IRQHandler(void)
+{
+    NFCTag_DriverIRQHandler();
+}
+
+WEAK void MAILBOX_IRQHandler(void)
+{
+    MAILBOX_DriverIRQHandler();
+}
+
+WEAK void ADC0_SEQA_IRQHandler(void)
+{
+    ADC0_SEQA_DriverIRQHandler();
+}
+
+WEAK void ADC0_SEQB_IRQHandler(void)
+{
+    ADC0_SEQB_DriverIRQHandler();
+}
+
+WEAK void ADC0_THCMP_IRQHandler(void)
+{
+    ADC0_THCMP_DriverIRQHandler();
+}
+
+WEAK void DMIC0_IRQHandler(void)
+{
+    DMIC0_DriverIRQHandler();
+}
+
+WEAK void HWVAD0_IRQHandler(void)
+{
+    HWVAD0_DriverIRQHandler();
+}
+
+WEAK void BLE_DP_IRQHandler(void)
+{
+    BLE_DP_DriverIRQHandler();
+}
+
+WEAK void BLE_DP0_IRQHandler(void)
+{
+    BLE_DP0_DriverIRQHandler();
+}
+
+WEAK void BLE_DP1_IRQHandler(void)
+{
+    BLE_DP1_DriverIRQHandler();
+}
+
+WEAK void BLE_DP2_IRQHandler(void)
+{
+    BLE_DP2_DriverIRQHandler();
+}
+
+WEAK void BLE_LL_ALL_IRQHandler(void)
+{
+    BLE_LL_ALL_DriverIRQHandler();
+}
+
+WEAK void ZIGBEE_MAC_IRQHandler(void)
+{
+    ZIGBEE_MAC_DriverIRQHandler();
+}
+
+WEAK void ZIGBEE_MODEM_IRQHandler(void)
+{
+    ZIGBEE_MODEM_DriverIRQHandler();
+}
+
+WEAK void RFP_TMU_IRQHandler(void)
+{
+    RFP_TMU_DriverIRQHandler();
+}
+
+WEAK void RFP_AGC_IRQHandler(void)
+{
+    RFP_AGC_DriverIRQHandler();
+}
+
+WEAK void ISO7816_IRQHandler(void)
+{
+    ISO7816_DriverIRQHandler();
+}
+
+WEAK void ANA_COMP_IRQHandler(void)
+{
+    ANA_COMP_DriverIRQHandler();
+}
+
+WEAK void WAKE_UP_TIMER0_IRQHandler(void)
+{
+    WAKE_UP_TIMER0_DriverIRQHandler();
+}
+
+WEAK void WAKE_UP_TIMER1_IRQHandler(void)
+{
+    WAKE_UP_TIMER1_DriverIRQHandler();
+}
+
+WEAK void PVTVF0_AMBER_IRQHandler(void)
+{
+    PVTVF0_AMBER_DriverIRQHandler();
+}
+
+WEAK void PVTVF0_RED_IRQHandler(void)
+{
+    PVTVF0_RED_DriverIRQHandler();
+}
+
+WEAK void PVTVF1_AMBER_IRQHandler(void)
+{
+    PVTVF1_AMBER_DriverIRQHandler();
+}
+
+WEAK void PVTVF1_RED_IRQHandler(void)
+{
+    PVTVF1_RED_DriverIRQHandler();
+}
+
+WEAK void BLE_WAKE_UP_TIMER_IRQHandler(void)
+{
+    BLE_WAKE_UP_TIMER_DriverIRQHandler();
+}
+
+WEAK void SHA_IRQHandler(void)
+{
+    SHA_DriverIRQHandler();
+}
+
+//*****************************************************************************
+
+#if defined(DEBUG)
+#pragma GCC pop_options
+#endif // (DEBUG)
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/system_K32W061.c b/third_party/nxp/K32W061DK6/devices/K32W061/system_K32W061.c
new file mode 100755
index 0000000..ec550a5
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/system_K32W061.c
@@ -0,0 +1,374 @@
+/*
+** ###################################################################
+**     Processors:          K32W041HN
+**                          K32W061HN
+**
+**     Compilers:           IAR ANSI C/C++ Compiler for ARM
+**                          MCUXpresso Compiler
+**
+**     Reference manual:    K32W061 User manual Rev.1 11 October 2019
+**     Version:             rev. 1.0, 2019-11-05
+**     Build:               b191121
+**
+**     Abstract:
+**         Provides a system configuration function and a global variable that
+**         contains the system frequency. It configures the device and initializes
+**         the oscillator (PLL) that is part of the microcontroller device.
+**
+**     Copyright 2016 Freescale Semiconductor, Inc.
+**     Copyright 2016-2019 NXP
+**     All rights reserved.
+**
+**     SPDX-License-Identifier: BSD-3-Clause
+**
+**     http:                 www.nxp.com
+**     mail:                 support@nxp.com
+**
+**     Revisions:
+**     - rev. 1.0 (2019-11-05)
+**         Initial version.
+**
+** ###################################################################
+*/
+
+/*!
+ * @file K32W061
+ * @version 1.0
+ * @date 2019-02-12
+ * @brief Device specific configuration file for K32W061 (implementation file)
+ *
+ * Provides a system configuration function and a global variable that contains
+ * the system frequency. It configures the device and initializes the oscillator
+ * (PLL) that is part of the microcontroller device.
+ */
+
+#include <stdint.h>
+#include "fsl_device_registers.h"
+#include "rom_api.h"
+
+/**
+ * Clock source selections for the Main Clock
+ */
+typedef enum _main_clock_src
+{
+    kCLOCK_MainFro12M  = 0,
+    kCLOCK_MainOsc32k  = 1,
+    kCLOCK_MainXtal32M = 2,
+    kCLOCK_MainFro32M  = 3,
+    kCLOCK_MainFro48M  = 4,
+    kCLOCK_MainExtClk  = 5,
+    kCLOCK_MainFro1M   = 6,
+} main_clock_src_t;
+
+/**
+ * Clock source selections for CLKOUT
+ */
+typedef enum _clkout_clock_src
+{
+    kCLOCK_ClkoutMainClk  = 0,
+    kCLOCK_ClkoutXtal32k  = 1,
+    kCLOCK_ClkoutFro32k   = 2,
+    kCLOCK_ClkoutXtal32M  = 3,
+    kCLOCK_ClkoutDcDcTest = 4,
+    kCLOCK_ClkoutFro48M   = 5,
+    kCLOCK_ClkoutFro1M    = 6,
+    kCLOCK_ClkoutNoClock  = 7
+} clkout_clock_src_t;
+
+typedef enum
+{
+    FRO12M_ENA = (1 << 0),
+    FRO32M_ENA = (1 << 1),
+    FRO48M_ENA = (1 << 2),
+    FRO64M_ENA = (1 << 3),
+    FRO96M_ENA = (1 << 4)
+} Fro_ClkSel_t;
+
+#define OSC32K_FREQ 32768UL
+#define FRO32K_FREQ 32768UL
+#define OSC32M_FREQ 32000000UL
+#define XTAL32M_FREQ 32000000UL
+#define FRO64M_FREQ 64000000UL
+#define FRO1M_FREQ 1000000UL
+#define FRO12M_FREQ 12000000UL
+#define FRO32M_FREQ 32000000UL
+#define FRO48M_FREQ 48000000UL
+
+static const uint32_t g_Ext_Clk_Freq = 0U;
+
+extern unsigned int __Vectors;
+extern WEAK void SystemInit(void);
+extern WEAK void WarmMain(void);
+
+static uint32_t CLOCK_GetXtal32kFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_XTAL32K_MASK) >> PMC_PDRUNCFG_ENA_XTAL32K_SHIFT) != 0)
+    {
+        freq = OSC32K_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetXtal32MFreq(void)
+{
+    return XTAL32M_FREQ;
+}
+
+static uint32_t CLOCK_GetFro32kFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->PDRUNCFG & PMC_PDRUNCFG_ENA_FRO32K_MASK) >> PMC_PDRUNCFG_ENA_FRO32K_SHIFT) != 0)
+    {
+        freq = FRO32K_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetFro1MFreq(void)
+{
+    return FRO1M_FREQ;
+}
+
+static uint32_t CLOCK_GetFro12MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO12M_ENA)
+    {
+        freq = FRO12M_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetFro32MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO32M_ENA)
+    {
+        freq = FRO32M_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetFro48MFreq(void)
+{
+    uint32_t freq = 0;
+
+    if (((PMC->FRO192M & PMC_FRO192M_DIVSEL_MASK) >> PMC_FRO192M_DIVSEL_SHIFT) & FRO48M_ENA)
+    {
+        freq = FRO48M_FREQ;
+    }
+
+    return freq;
+}
+
+static uint32_t CLOCK_GetOsc32kFreq(void)
+{
+    uint32_t freq = 0;
+    if ((SYSCON->OSC32CLKSEL & SYSCON_OSC32CLKSEL_SEL32KHZ_MASK) != 0)
+    {
+        freq = CLOCK_GetXtal32kFreq();
+    }
+    else
+    {
+        freq = CLOCK_GetFro32kFreq();
+    }
+    return freq;
+}
+
+/* Return main clock rate */
+static uint32_t CLOCK_GetMainClockRate(void)
+{
+    uint32_t freq = 0;
+
+    switch ((main_clock_src_t)((SYSCON->MAINCLKSEL & SYSCON_MAINCLKSEL_SEL_MASK) >> SYSCON_MAINCLKSEL_SEL_SHIFT))
+    {
+        case kCLOCK_MainFro12M:
+            freq = CLOCK_GetFro12MFreq();
+            break;
+
+        case kCLOCK_MainOsc32k:
+            freq = CLOCK_GetOsc32kFreq();
+            break;
+
+        case kCLOCK_MainXtal32M:
+            freq = CLOCK_GetXtal32MFreq();
+            break;
+
+        case kCLOCK_MainFro32M:
+            freq = CLOCK_GetFro32MFreq();
+            break;
+
+        case kCLOCK_MainFro48M:
+            freq = CLOCK_GetFro48MFreq();
+            break;
+
+        case kCLOCK_MainExtClk:
+            freq = g_Ext_Clk_Freq;
+            break;
+
+        case kCLOCK_MainFro1M:
+            freq = CLOCK_GetFro1MFreq();
+            break;
+    }
+
+    return freq;
+}
+
+/* ----------------------------------------------------------------------------
+   -- Core clock
+   ---------------------------------------------------------------------------- */
+
+#if !NO_SYSCORECLK_UPD
+uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
+#endif
+
+#if defined(__ICCARM__)
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+void ResetISR(void)
+{
+    __asm volatile(
+        "LDR    R0,=0x40000804\t\n" // load co-processor boot address (from CPBOOT)
+        "LDR    R0,[R0]\t\n"        // get address to branch to
+        "MOVS   R0,R0\t\n"          // Check if 0
+        "BEQ.N  masterboot\t\n"     // if zero in boot reg, we just branch to  real reset
+        "LDR    R1,=0x40000808\t\n" // load co-processor stack pointer (from CPSTACK)
+        "LDR    R1,[R1]\t\n"
+        "MOV    SP,R1\t\n"
+        "BX     R0\t\n" // branch to boot address
+        "masterboot:\t\n"
+        "LDR    R0, =ResetISR2\t\n" // jump to 'real' reset handler
+        "BX     R0\t\n");
+}
+
+void ResetISR2(void)
+{
+    if ((void (*)(void))WarmMain != NULL)
+    {
+        unsigned int warm_start;
+        uint32_t pmc_lpmode;
+        uint32_t pmc_resetcause;
+        uint32_t pwr_pdsleepcfg;
+
+        pmc_resetcause = PMC->RESETCAUSE;
+        pwr_pdsleepcfg = PMC->PDSLEEPCFG;
+
+        pmc_lpmode = BOOT_GetStartPowerMode();
+
+        warm_start = (pmc_lpmode == 0x02); /* coming from power down mode*/
+
+        // check if the reset cause is only a timer wakeup or io wakeup with all memory banks held
+        warm_start &= (!(pmc_resetcause & (PMC_RESETCAUSE_POR_MASK | PMC_RESETCAUSE_PADRESET_MASK |
+                                           PMC_RESETCAUSE_BODRESET_MASK | PMC_RESETCAUSE_SYSTEMRESET_MASK |
+                                           PMC_RESETCAUSE_WDTRESET_MASK | PMC_RESETCAUSE_WAKEUPIORESET_MASK)) &&
+                       (pmc_resetcause & PMC_RESETCAUSE_WAKEUPPWDNRESET_MASK) &&
+                       ((pwr_pdsleepcfg & PMC_PDSLEEPCFG_PDEN_PD_MEM7_MASK) == 0x0) /* BANK7 memory bank held */
+                       && (pwr_pdsleepcfg & PMC_PDSLEEPCFG_PDEN_LDO_MEM_MASK)       /* LDO MEM enabled */
+        );
+
+        if (warm_start)
+        {
+            if (SYSCON->CPSTACK)
+            {
+                /* if CPSTACK is not NULL, switch to CPSTACK value so we avoid to corrupt the stack used before power
+                 * down Note: it looks like enough to switch to new SP now and not earlier */
+                __asm volatile(
+                    "LDR    R1,=0x40000808\t\n" // load co-processor stack pointer (from CPSTACK)
+                    "LDR    R1,[R1]\t\n"
+                    "MOV    SP,R1\t\n");
+            }
+            // Check to see if we are running the code from a non-zero
+            // address (eg RAM, external flash), in which case we need
+            // to modify the VTOR register to tell the CPU that the
+            // vector table is located at a non-0x0 address.
+            unsigned int *pSCB_VTOR = (unsigned int *)0xE000ED08;
+            if (((unsigned int)(&__Vectors) != 0))
+            {
+                // CMSIS : SCB->VTOR = <address of vector table>
+                *pSCB_VTOR = (unsigned int)(&__Vectors);
+            }
+
+            if ((void (*)(void))SystemInit != NULL)
+            {
+                SystemInit();
+            }
+
+            WarmMain();
+
+            //
+            // WarmMain() shouldn't return, but if it does, we'll just enter an infinite loop
+            //
+            while (1)
+            {
+                ;
+            }
+        }
+    }
+
+    // Check to see if we are running the code from a non-zero
+    // address (eg RAM, external flash), in which case we need
+    // to modify the VTOR register to tell the CPU that the
+    // vector table is located at a non-0x0 address.
+    unsigned int *pSCB_VTOR = (unsigned int *)0xE000ED08;
+    if ((unsigned int)(&__Vectors) != 0)
+    {
+        // CMSIS : SCB->VTOR = <address of vector table>
+        *pSCB_VTOR = (unsigned int)(&__Vectors);
+    }
+
+    SystemInit();
+
+#if defined(__cplusplus)
+    //
+    // Call C++ library initialisation
+    //
+    __libc_init_array();
+#endif
+}
+#endif
+
+/* ----------------------------------------------------------------------------
+   -- SystemInit()
+   ---------------------------------------------------------------------------- */
+
+void SystemInit(void)
+{
+    uint32_t trim;
+#if !NO_SYSCORECLK_UPD
+    /* Initialise SystemCoreClock value */
+    SystemCoreClockUpdate();
+#endif
+    /* Initialise NVIC priority grouping value */
+    NVIC_SetPriorityGrouping(4);
+
+    /* Apply FRO1M trim value */
+    trim = *(uint32_t *)(0x9FCD0U);
+
+    if (trim & 0x1U)
+    {
+        PMC->FRO1M = (PMC->FRO1M & ~PMC_FRO1M_FREQSEL_MASK) | ((trim >> 1) & PMC_FRO1M_FREQSEL_MASK);
+    }
+}
+
+/* ----------------------------------------------------------------------------
+   -- SystemCoreClockUpdate()
+   ---------------------------------------------------------------------------- */
+
+#if !NO_SYSCORECLK_UPD
+void SystemCoreClockUpdate(void)
+{
+    SystemCoreClock = (CLOCK_GetMainClockRate() / ((SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK) + 1U));
+}
+#endif
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/system_K32W061.h b/third_party/nxp/K32W061DK6/devices/K32W061/system_K32W061.h
new file mode 100755
index 0000000..6c3db2b
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/system_K32W061.h
@@ -0,0 +1,89 @@
+/*
+** ###################################################################
+**     Processors:          K32W041HN
+**                          K32W061HN
+**
+**     Compilers:           IAR ANSI C/C++ Compiler for ARM
+**                          MCUXpresso Compiler
+**
+**     Reference manual:    K32W061 User manual Rev.1 11 October 2019
+**     Version:             rev. 1.0, 2019-11-05
+**     Build:               b191121
+**
+**     Abstract:
+**         Provides a system configuration function and a global variable that
+**         contains the system frequency. It configures the device and initializes
+**         the oscillator (PLL) that is part of the microcontroller device.
+**
+**     Copyright 2016 Freescale Semiconductor, Inc.
+**     Copyright 2016-2019 NXP
+**     All rights reserved.
+**
+**     SPDX-License-Identifier: BSD-3-Clause
+**
+**     http:                 www.nxp.com
+**     mail:                 support@nxp.com
+**
+**     Revisions:
+**     - rev. 1.0 (2019-11-05)
+**         Initial version.
+**
+** ###################################################################
+*/
+
+/*!
+ * @file K32W061
+ * @version 1.0
+ * @date 2019-11-05
+ * @brief Device specific configuration file for K32W061 (header file)
+ *
+ * Provides a system configuration function and a global variable that contains
+ * the system frequency. It configures the device and initializes the oscillator
+ * (PLL) that is part of the microcontroller device.
+ */
+
+#ifndef _SYSTEM_K32W061_H_
+#define _SYSTEM_K32W061_H_ /**< Symbol preventing repeated inclusion */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define DEFAULT_SYSTEM_CLOCK 12000000u /* Default System clock value */
+
+/**
+ * @brief System clock frequency (core clock)
+ *
+ * The system clock frequency supplied to the SysTick timer and the processor
+ * core clock. This variable can be used by the user application to setup the
+ * SysTick timer or configure other parameters. It may also be used by debugger to
+ * query the frequency of the debug timer or configure the trace clock speed
+ * SystemCoreClock is initialized with a correct predefined value.
+ */
+extern uint32_t SystemCoreClock;
+
+/**
+ * @brief Setup the microcontroller system.
+ *
+ * Typically this function configures the oscillator (PLL) that is part of the
+ * microcontroller device. For systems with variable clock speed it also updates
+ * the variable SystemCoreClock. SystemInit is called from startup_device file.
+ */
+void SystemInit(void);
+
+/**
+ * @brief Updates the SystemCoreClock variable.
+ *
+ * It must be called whenever the core clock is changed during program
+ * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
+ * the current core clock.
+ */
+void SystemCoreClockUpdate(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYSTEM_K32W061_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console.c b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console.c
new file mode 100755
index 0000000..9f4b4ff
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console.c
@@ -0,0 +1,1131 @@
+/*
+ * This is a modified version of the file printf.c, which was distributed
+ * by Motorola as part of the M5407C3BOOT.zip package used to initialize
+ * the M5407C3 evaluation board.
+ *
+ * Copyright:
+ *      1999-2000 MOTOROLA, INC. All Rights Reserved.
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Motorola, Inc. This
+ *  software is provided on an "AS IS" basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, MOTOROLA
+ *  DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ *  PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE
+ *  SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY
+ *  ACCOMPANYING WRITTEN MATERIALS.
+ *
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING
+ *  WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
+ *  INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
+ *  LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
+ *
+ *  Motorola assumes no responsibility for the maintenance and support
+ *  of this software
+
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
+#include <stdio.h>
+#endif
+
+#ifdef FSL_RTOS_FREE_RTOS
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "task.h"
+#endif
+
+#include "fsl_debug_console_conf.h"
+#include "fsl_str.h"
+
+#include "fsl_common.h"
+#include "serial_manager.h"
+
+#include "fsl_debug_console.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifndef NDEBUG
+#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
+#undef assert
+#define assert(n)
+#endif
+#endif
+
+#if SDK_DEBUGCONSOLE
+#define DEBUG_CONSOLE_FUNCTION_PREFIX
+#else
+#define DEBUG_CONSOLE_FUNCTION_PREFIX static
+#endif
+
+/*! @brief character backspace ASCII value */
+#define DEBUG_CONSOLE_BACKSPACE 127U
+
+/* lock definition */
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS)
+
+static SemaphoreHandle_t s_debugConsoleReadSemaphore;
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+static SemaphoreHandle_t s_debugConsoleReadWaitSemaphore;
+#endif
+
+#elif (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM)
+
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+static volatile uint8_t s_debugConsoleReadWaitSemaphore;
+#endif
+
+#else
+
+#endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */
+
+/*! @brief get current runing environment is ISR or not */
+#ifdef __CA7_REV
+#define IS_RUNNING_IN_ISR() SystemGetIRQNestingLevel()
+#else
+#define IS_RUNNING_IN_ISR() __get_IPSR()
+#endif /* __CA7_REV */
+
+/* semaphore definition */
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS)
+
+/* mutex semaphore */
+#define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex) ((mutex) = xSemaphoreCreateMutex())
+
+/* clang-format off */
+#define DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(mutex) \
+{                                                 \
+        if (IS_RUNNING_IN_ISR() == 0U)            \
+        {                                         \
+            (void)xSemaphoreGive(mutex);                \
+        }                                         \
+}
+
+#define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) \
+{                                                          \
+        if (IS_RUNNING_IN_ISR() == 0U)                     \
+        {                                                  \
+            (void)xSemaphoreTake(mutex, portMAX_DELAY);          \
+        }                                                  \
+}
+
+#define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) \
+{                                                                     \
+        if (IS_RUNNING_IN_ISR() == 0U)                                \
+        {                                                             \
+            result = xSemaphoreTake(mutex, 0U);                       \
+        }                                                             \
+        else                                                          \
+        {                                                             \
+            result = 1U;                                              \
+        }                                                             \
+}
+/* clang-format on */
+
+/* Binary semaphore */
+#define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary) ((binary) = xSemaphoreCreateBinary())
+#define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) ((void)xSemaphoreTake(binary, portMAX_DELAY))
+#define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) ((void)xSemaphoreGiveFromISR(binary, NULL))
+
+#elif (DEBUG_CONSOLE_SYNCHRONIZATION_BM == DEBUG_CONSOLE_SYNCHRONIZATION_MODE)
+
+#define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex)
+#define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex)
+#define DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(mutex)
+#define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) (result = 1U)
+
+#define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary)
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+#define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) \
+    {                                                        \
+        while (!binary)                                      \
+        {                                                    \
+        }                                                    \
+        binary = false;                                      \
+    }
+#define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) (binary = true)
+#else
+#define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary)
+#define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary)
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/* add other implementation here
+ *such as :
+ * #elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DDEBUG_CONSOLE_SYNCHRONIZATION_xxx)
+ */
+
+#else
+
+#error RTOS type is not defined by DEBUG_CONSOLE_SYNCHRONIZATION_MODE.
+
+#endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/* receive state structure */
+typedef struct _debug_console_write_ring_buffer
+{
+    uint32_t ringBufferSize;
+    volatile uint32_t ringHead;
+    volatile uint32_t ringTail;
+    uint8_t ringBuffer[DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN];
+} debug_console_write_ring_buffer_t;
+#endif
+
+typedef struct _debug_console_state_struct
+{
+    uint8_t serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
+    serial_handle_t serialHandle; /*!< serial manager handle */
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+    debug_console_write_ring_buffer_t writeRingBuffer;
+    uint8_t readRingBuffer[DEBUG_CONSOLE_RECEIVE_BUFFER_LEN];
+#endif
+    uint8_t serialWriteHandleBuffer[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
+    uint8_t serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE];
+} debug_console_state_struct_t;
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Debug console state information. */
+static debug_console_state_struct_t s_debugConsoleState;
+serial_handle_t g_serialHandle; /*!< serial manager handle */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief This is a printf call back function which is used to relocate the log to buffer
+ * or print the log immediately when the local buffer is full.
+ *
+ * @param[in] buf   Buffer to store log.
+ * @param[in] indicator Buffer index.
+ * @param[in] val Target character to store.
+ * @param[in] len length of the character
+ *
+ */
+#if SDK_DEBUGCONSOLE
+static void DbgConsole_PrintCallback(char *buf, int32_t *indicator, char dbgVal, int len);
+#endif
+
+status_t DbgConsole_ReadOneCharacter(uint8_t *ch);
+int DbgConsole_SendData(uint8_t *ch, size_t size);
+int DbgConsole_SendDataReliable(uint8_t *ch, size_t size);
+int DbgConsole_ReadLine(uint8_t *buf, size_t size);
+int DbgConsole_ReadCharacter(uint8_t *ch);
+
+#if ((SDK_DEBUGCONSOLE > 0U) ||                                                   \
+     ((SDK_DEBUGCONSOLE == 0U) && defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \
+      (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))))
+DEBUG_CONSOLE_FUNCTION_PREFIX status_t DbgConsole_Flush(void);
+#endif
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+
+static void DbgConsole_SerialManagerTxCallback(void *callbackParam,
+                                               serial_manager_callback_message_t *message,
+                                               serial_manager_status_t status)
+{
+    debug_console_state_struct_t *ioState;
+    uint32_t sendDataLength;
+
+    if ((NULL == callbackParam) || (NULL == message))
+    {
+        return;
+    }
+
+    ioState = (debug_console_state_struct_t *)callbackParam;
+
+    ioState->writeRingBuffer.ringTail += message->length;
+    if (ioState->writeRingBuffer.ringTail >= ioState->writeRingBuffer.ringBufferSize)
+    {
+        ioState->writeRingBuffer.ringTail = 0U;
+    }
+
+    if (kStatus_SerialManager_Success == status)
+    {
+        if (ioState->writeRingBuffer.ringTail != ioState->writeRingBuffer.ringHead)
+        {
+            if (ioState->writeRingBuffer.ringHead > ioState->writeRingBuffer.ringTail)
+            {
+                sendDataLength = ioState->writeRingBuffer.ringHead - ioState->writeRingBuffer.ringTail;
+            }
+            else
+            {
+                sendDataLength = ioState->writeRingBuffer.ringBufferSize - ioState->writeRingBuffer.ringTail;
+            }
+
+            (void)SerialManager_WriteNonBlocking(
+                ((serial_write_handle_t)&ioState->serialWriteHandleBuffer[0]),
+                &ioState->writeRingBuffer.ringBuffer[ioState->writeRingBuffer.ringTail], sendDataLength);
+        }
+    }
+    else if (kStatus_SerialManager_Canceled == status)
+    {
+        ioState->writeRingBuffer.ringTail = 0U;
+        ioState->writeRingBuffer.ringHead = 0U;
+    }
+    else
+    {
+        /*MISRA rule 16.4*/
+    }
+}
+
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+
+static void DbgConsole_SerialManagerRxCallback(void *callbackParam,
+                                               serial_manager_callback_message_t *message,
+                                               serial_manager_status_t status)
+{
+    if ((NULL == callbackParam) || (NULL == message))
+    {
+        return;
+    }
+
+    if (kStatus_SerialManager_Notify == status)
+    {
+    }
+    else if (kStatus_SerialManager_Success == status)
+    {
+        /* release s_debugConsoleReadWaitSemaphore from RX callback */
+        DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(s_debugConsoleReadWaitSemaphore);
+    }
+    else
+    {
+        /*MISRA rule 16.4*/
+    }
+}
+#endif
+
+#endif
+
+status_t DbgConsole_ReadOneCharacter(uint8_t *ch)
+{
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \
+    (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED)
+    return kStatus_Fail;
+#else
+    status_t status = (status_t)kStatus_SerialManager_Error;
+
+/* recieve one char every time */
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    status = (status_t)SerialManager_ReadNonBlocking(
+        ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), ch, 1);
+#else
+    status = (status_t)SerialManager_ReadBlocking(
+        ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), ch, 1);
+#endif
+    if ((status_t)kStatus_SerialManager_Success != status)
+    {
+        return (status_t)kStatus_Fail;
+    }
+    /* wait s_debugConsoleReadWaitSemaphore from RX callback */
+    DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(s_debugConsoleReadWaitSemaphore);
+
+    return (status_t)kStatus_Success;
+#endif
+
+#else
+
+    return (status_t)kStatus_Fail;
+
+#endif
+}
+
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+static status_t DbgConsole_EchoCharacter(uint8_t *ch, bool isGetChar, int *index)
+{
+    /* Due to scanf take \n and \r as end of string,should not echo */
+    if (((*ch != (uint8_t)'\r') && (*ch != (uint8_t)'\n')) || (isGetChar))
+    {
+        /* recieve one char every time */
+        if (1 != DbgConsole_SendDataReliable(ch, 1U))
+        {
+            return (status_t)kStatus_Fail;
+        }
+    }
+
+    if ((!isGetChar) && (index != NULL))
+    {
+        if (DEBUG_CONSOLE_BACKSPACE == *ch)
+        {
+            if ((*index >= 2))
+            {
+                *index -= 2;
+            }
+            else
+            {
+                *index = 0;
+            }
+        }
+    }
+
+    return (status_t)kStatus_Success;
+}
+#endif
+
+int DbgConsole_SendData(uint8_t *ch, size_t size)
+{
+    status_t status = (status_t)kStatus_SerialManager_Error;
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    uint32_t sendDataLength;
+    int txBusy = 0;
+#endif
+    assert(NULL != ch);
+    assert(0 != size);
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    uint32_t regPrimask = DisableGlobalIRQ();
+    if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail)
+    {
+        txBusy = 1;
+        sendDataLength =
+            (s_debugConsoleState.writeRingBuffer.ringHead + s_debugConsoleState.writeRingBuffer.ringBufferSize -
+             s_debugConsoleState.writeRingBuffer.ringTail) %
+            s_debugConsoleState.writeRingBuffer.ringBufferSize;
+    }
+    else
+    {
+        sendDataLength = 0U;
+    }
+    sendDataLength = s_debugConsoleState.writeRingBuffer.ringBufferSize - sendDataLength - 1;
+    if (sendDataLength <= size)
+    {
+        EnableGlobalIRQ(regPrimask);
+        return -1;
+    }
+    for (int i = 0; i < (int)size; i++)
+    {
+        s_debugConsoleState.writeRingBuffer.ringBuffer[s_debugConsoleState.writeRingBuffer.ringHead++] = ch[i];
+        if (s_debugConsoleState.writeRingBuffer.ringHead >= s_debugConsoleState.writeRingBuffer.ringBufferSize)
+        {
+            s_debugConsoleState.writeRingBuffer.ringHead = 0U;
+        }
+    }
+
+    status = (status_t)kStatus_SerialManager_Success;
+
+    if (txBusy == 0)
+    {
+        if (s_debugConsoleState.writeRingBuffer.ringHead > s_debugConsoleState.writeRingBuffer.ringTail)
+        {
+            sendDataLength =
+                s_debugConsoleState.writeRingBuffer.ringHead - s_debugConsoleState.writeRingBuffer.ringTail;
+        }
+        else
+        {
+            sendDataLength =
+                s_debugConsoleState.writeRingBuffer.ringBufferSize - s_debugConsoleState.writeRingBuffer.ringTail;
+        }
+
+        status = (status_t)SerialManager_WriteNonBlocking(
+            ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]),
+            &s_debugConsoleState.writeRingBuffer.ringBuffer[s_debugConsoleState.writeRingBuffer.ringTail],
+            sendDataLength);
+    }
+    EnableGlobalIRQ(regPrimask);
+#else
+    status = (status_t)SerialManager_WriteBlocking(
+        ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), ch, size);
+#endif
+    return (((status_t)kStatus_Success == status) ? (int)size : -1);
+}
+
+int DbgConsole_SendDataReliable(uint8_t *ch, size_t size)
+{
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+#if (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))
+    status_t status = kStatus_SerialManager_Error;
+    uint32_t sendDataLength;
+    uint32_t totalLength = size;
+    int sentLength;
+#endif /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */
+#else
+    status_t status = kStatus_SerialManager_Error;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+    assert(NULL != ch);
+    assert(0 != size);
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+
+#if (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))
+    do
+    {
+        uint32_t regPrimask = DisableGlobalIRQ();
+        if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail)
+        {
+            sendDataLength =
+                (s_debugConsoleState.writeRingBuffer.ringHead + s_debugConsoleState.writeRingBuffer.ringBufferSize -
+                 s_debugConsoleState.writeRingBuffer.ringTail) %
+                s_debugConsoleState.writeRingBuffer.ringBufferSize;
+        }
+        else
+        {
+            sendDataLength = 0U;
+        }
+        sendDataLength = s_debugConsoleState.writeRingBuffer.ringBufferSize - sendDataLength - 1U;
+
+        if (sendDataLength > 0U)
+        {
+            if (sendDataLength > totalLength)
+            {
+                sendDataLength = totalLength;
+            }
+
+            sentLength = DbgConsole_SendData(&ch[size - totalLength], sendDataLength);
+            if (sentLength > 0)
+            {
+                totalLength = totalLength - (uint32_t)sentLength;
+            }
+        }
+        EnableGlobalIRQ(regPrimask);
+
+        if (totalLength != 0U)
+        {
+            status = DbgConsole_Flush();
+            if ((status_t)kStatus_Success != status)
+            {
+                break;
+            }
+        }
+    } while (totalLength != 0U);
+    return (status_t)(uint32_t)((uint32_t)size - totalLength);
+#else
+    return DbgConsole_SendData(ch, size);
+#endif /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */
+
+#else
+    status          = (status_t)SerialManager_WriteBlocking(
+        ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), ch, size);
+    return (((status_t)kStatus_Success == status) ? (int)size : -1);
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+}
+
+int DbgConsole_ReadLine(uint8_t *buf, size_t size)
+{
+    int i = 0;
+
+    assert(buf != NULL);
+
+    /* take mutex lock function */
+    DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore);
+
+    do
+    {
+        /* recieve one char every time */
+        if ((status_t)kStatus_Success != DbgConsole_ReadOneCharacter(&buf[i]))
+        {
+            /* release mutex lock function */
+            DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+            i = -1;
+            break;
+        }
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+        (void)DbgConsole_EchoCharacter(&buf[i], false, &i);
+#endif
+        /* analysis data */
+        if (((uint8_t)'\r' == buf[i]) || ((uint8_t)'\n' == buf[i]))
+        {
+            /* End of Line. */
+            if (0 == i)
+            {
+                buf[i] = (uint8_t)'\0';
+                continue;
+            }
+            else
+            {
+                break;
+            }
+        }
+        i++;
+    } while (i < (int)size);
+
+    /* get char should not add '\0'*/
+    if (i == (int)size)
+    {
+        buf[i] = (uint8_t)'\0';
+    }
+    else
+    {
+        buf[i + 1] = (uint8_t)'\0';
+    }
+
+    /* release mutex lock function */
+    DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+
+    return i;
+}
+
+int DbgConsole_ReadCharacter(uint8_t *ch)
+{
+    int ret;
+
+    assert(ch);
+
+    /* take mutex lock function */
+    DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore);
+    /* read one character */
+    if ((status_t)kStatus_Success == DbgConsole_ReadOneCharacter(ch))
+    {
+        ret = 1;
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+        (void)DbgConsole_EchoCharacter(ch, true, NULL);
+#endif
+    }
+    else
+    {
+        ret = -1;
+    }
+
+    /* release mutex lock function */
+    DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+
+    return ret;
+}
+
+#if SDK_DEBUGCONSOLE
+static void DbgConsole_PrintCallback(char *buf, int32_t *indicator, char dbgVal, int len)
+{
+    int i = 0;
+
+    for (i = 0; i < len; i++)
+    {
+        if (((uint32_t)*indicator + 1UL) >= DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN)
+        {
+            (void)DbgConsole_SendDataReliable((uint8_t *)buf, (uint32_t)(*indicator));
+            *indicator = 0;
+        }
+
+        buf[*indicator] = dbgVal;
+        (*indicator)++;
+    }
+}
+#endif
+
+/*************Code for DbgConsole Init, Deinit, Printf, Scanf *******************************/
+
+/* See fsl_debug_console.h for documentation of this function. */
+status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq)
+{
+    serial_manager_config_t serialConfig;
+    status_t status = (status_t)kStatus_SerialManager_Error;
+
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+    serial_port_uart_config_t uartConfig = {
+        .instance     = instance,
+        .clockRate    = clkSrcFreq,
+        .baudRate     = baudRate,
+        .parityMode   = kSerialManager_UartParityDisabled,
+        .stopBitCount = kSerialManager_UartOneStopBit,
+        .enableRx     = 1,
+        .enableTx     = 1,
+    };
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+    serial_port_usb_cdc_config_t usbCdcConfig = {
+        .controllerIndex = (serial_port_usb_cdc_controller_index_t)instance,
+    };
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+    serial_port_swo_config_t swoConfig = {
+        .clockRate = clkSrcFreq,
+        .baudRate  = baudRate,
+        .port      = instance,
+        .protocol  = kSerialManager_SwoProtocolNrz,
+    };
+#endif
+
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+    serial_port_usb_cdc_virtual_config_t usbCdcVirtualConfig = {
+        .controllerIndex = (serial_port_usb_cdc_virtual_controller_index_t)instance,
+    };
+#endif
+    serialConfig.type = device;
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    serialConfig.ringBuffer     = &s_debugConsoleState.readRingBuffer[0];
+    serialConfig.ringBufferSize = DEBUG_CONSOLE_RECEIVE_BUFFER_LEN;
+#endif
+
+    if (kSerialPort_Uart == device)
+    {
+#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
+        serialConfig.portConfig = &uartConfig;
+#else
+        return status;
+#endif
+    }
+    else if (kSerialPort_UsbCdc == device)
+    {
+#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
+        serialConfig.portConfig = &usbCdcConfig;
+#else
+        return status;
+#endif
+    }
+    else if (kSerialPort_Swo == device)
+    {
+#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
+        serialConfig.portConfig = &swoConfig;
+#else
+        return status;
+#endif
+    }
+    else if (kSerialPort_UsbCdcVirtual == device)
+    {
+#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
+        serialConfig.portConfig = &usbCdcVirtualConfig;
+#else
+        return status;
+#endif
+    }
+    else
+    {
+        return status;
+    }
+
+    (void)memset(&s_debugConsoleState, 0, sizeof(s_debugConsoleState));
+
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+    s_debugConsoleState.writeRingBuffer.ringBufferSize = DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN;
+#endif
+
+    s_debugConsoleState.serialHandle = (serial_handle_t)&s_debugConsoleState.serialHandleBuffer[0];
+    status                           = (status_t)SerialManager_Init(s_debugConsoleState.serialHandle, &serialConfig);
+
+    assert(kStatus_SerialManager_Success == status);
+
+    DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+    DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(s_debugConsoleReadWaitSemaphore);
+#endif
+
+    {
+        status = (status_t)SerialManager_OpenWriteHandle(
+            s_debugConsoleState.serialHandle, ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]));
+        assert(kStatus_SerialManager_Success == status);
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+        (void)SerialManager_InstallTxCallback(((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]),
+                                              DbgConsole_SerialManagerTxCallback, &s_debugConsoleState);
+#endif
+    }
+
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+    {
+        status = (status_t)SerialManager_OpenReadHandle(
+            s_debugConsoleState.serialHandle, ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]));
+        assert(kStatus_SerialManager_Success == status);
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+        (void)SerialManager_InstallRxCallback(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]),
+                                              DbgConsole_SerialManagerRxCallback, &s_debugConsoleState);
+#endif
+    }
+#endif
+
+    g_serialHandle = s_debugConsoleState.serialHandle;
+
+    return kStatus_Success;
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+status_t DbgConsole_Deinit(void)
+{
+    {
+        if (s_debugConsoleState.serialHandle != NULL)
+        {
+            (void)SerialManager_CloseWriteHandle(
+                ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]));
+        }
+    }
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+    {
+        if (s_debugConsoleState.serialHandle != NULL)
+        {
+            (void)SerialManager_CloseReadHandle(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]));
+        }
+    }
+#endif
+    if (s_debugConsoleState.serialHandle)
+    {
+        if (kStatus_SerialManager_Success == SerialManager_Deinit(s_debugConsoleState.serialHandle))
+        {
+            s_debugConsoleState.serialHandle = NULL;
+            g_serialHandle                   = NULL;
+        }
+    }
+    return (status_t)kStatus_Success;
+}
+
+#if ((SDK_DEBUGCONSOLE > 0U) ||                                                   \
+     ((SDK_DEBUGCONSOLE == 0U) && defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \
+      (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))))
+DEBUG_CONSOLE_FUNCTION_PREFIX status_t DbgConsole_Flush(void)
+{
+#if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)
+
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED)
+
+    if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail)
+    {
+        return (status_t)kStatus_Fail;
+    }
+
+#else
+
+    while (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail)
+    {
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS)
+        if (0U == IS_RUNNING_IN_ISR())
+        {
+            if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState())
+            {
+                vTaskDelay(1);
+            }
+        }
+        else
+        {
+            return (status_t)kStatus_Fail;
+        }
+#endif
+    }
+
+#endif
+
+#endif
+    return (status_t)kStatus_Success;
+}
+#endif
+
+#if SDK_DEBUGCONSOLE
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Printf(const char *formatString, ...)
+{
+    va_list ap;
+    int logLength = 0, dbgResult = 0;
+    char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {'\0'};
+
+    if (NULL == g_serialHandle)
+    {
+        return 0;
+    }
+
+    va_start(ap, formatString);
+    /* format print log first */
+    logLength = StrFormatPrintf(formatString, ap, printBuf, DbgConsole_PrintCallback);
+    /* print log */
+    dbgResult = DbgConsole_SendDataReliable((uint8_t *)printBuf, (size_t)logLength);
+
+    va_end(ap);
+
+    return dbgResult;
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Putchar(int ch)
+{
+    /* print char */
+    return DbgConsole_SendDataReliable((uint8_t *)&ch, 1U);
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Scanf(char *formatString, ...)
+{
+    va_list ap;
+    int formatResult;
+    char scanfBuf[DEBUG_CONSOLE_SCANF_MAX_LOG_LEN + 1U] = {'\0'};
+
+    /* scanf log */
+    (void)DbgConsole_ReadLine((uint8_t *)scanfBuf, DEBUG_CONSOLE_SCANF_MAX_LOG_LEN);
+    /* get va_list */
+    va_start(ap, formatString);
+    /* format scanf log */
+    formatResult = StrFormatScanf(scanfBuf, formatString, ap);
+
+    va_end(ap);
+
+    return formatResult;
+}
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+status_t DbgConsole_TryGetchar(char *ch)
+{
+#if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))
+    uint32_t length = 0;
+    status_t status = (status_t)kStatus_Fail;
+
+    assert(ch);
+
+    /* take mutex lock function */
+    DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore);
+
+    if (kStatus_SerialManager_Success ==
+        SerialManager_TryRead(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), (uint8_t *)ch, 1,
+                              &length))
+    {
+        if (length != 0U)
+        {
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+            (void)DbgConsole_EchoCharacter((uint8_t *)ch, true, NULL);
+#endif
+            status = (status_t)kStatus_Success;
+        }
+    }
+    /* release mutex lock function */
+    DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore);
+    return status;
+#else
+    return (status_t)kStatus_Fail;
+#endif
+}
+#endif
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Getchar(void)
+{
+    uint8_t ch = 0U;
+
+    /* Get char */
+    (void)DbgConsole_ReadCharacter(&ch);
+
+    return (int)ch;
+}
+
+#endif /* SDK_DEBUGCONSOLE */
+
+/*************Code to support toolchain's printf, scanf *******************************/
+/* These function __write and __read is used to support IAR toolchain to printf and scanf*/
+#if (defined(__ICCARM__))
+#if defined(SDK_DEBUGCONSOLE_UART)
+#pragma weak __write
+size_t __write(int handle, const unsigned char *buffer, size_t size)
+{
+    if (buffer == 0)
+    {
+        /*
+         * This means that we should flush internal buffers.  Since we don't we just return.
+         * (Remember, "handle" == -1 means that all handles should be flushed.)
+         */
+        return 0;
+    }
+
+    /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+    if ((handle != 1) && (handle != 2))
+    {
+        return ((size_t)-1);
+    }
+
+    /* Send data. */
+    DbgConsole_SendDataReliable((uint8_t *)buffer, size);
+
+    return size;
+}
+
+#pragma weak __read
+size_t __read(int handle, unsigned char *buffer, size_t size)
+{
+    uint8_t ch     = 0U;
+    int actualSize = 0U;
+
+    /* This function only reads from "standard in", for all other file  handles it returns failure. */
+    if (handle != 0)
+    {
+        return ((size_t)-1);
+    }
+
+    /* Receive data.*/
+    for (; size > 0; size--)
+    {
+        DbgConsole_ReadCharacter(&ch);
+        if (ch == 0)
+        {
+            break;
+        }
+
+        *buffer++ = ch;
+        actualSize++;
+    }
+
+    return actualSize;
+}
+#endif /* SDK_DEBUGCONSOLE_UART */
+
+/* support LPC Xpresso with RedLib */
+#elif (defined(__REDLIB__))
+
+#if (defined(SDK_DEBUGCONSOLE_UART))
+int __attribute__((weak)) __sys_write(int handle, char *buffer, int size)
+{
+    if (buffer == 0)
+    {
+        /* return -1 if error. */
+        return -1;
+    }
+
+    /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+    if ((handle != 1) && (handle != 2))
+    {
+        return -1;
+    }
+
+    /* Send data. */
+    DbgConsole_SendDataReliable((uint8_t *)buffer, size);
+
+    return 0;
+}
+
+int __attribute__((weak)) __sys_readc(void)
+{
+    char tmp;
+
+    /* Receive data. */
+    DbgConsole_ReadCharacter((uint8_t *)&tmp);
+
+    return tmp;
+}
+#endif
+
+/* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+#if defined(SDK_DEBUGCONSOLE_UART)
+#if defined(__CC_ARM)
+struct __FILE
+{
+    int handle;
+    /*
+     * Whatever you require here. If the only file you are using is standard output using printf() for debugging,
+     * no file handling is required.
+     */
+};
+#endif
+
+/* FILE is typedef in stdio.h. */
+#pragma weak __stdout
+#pragma weak __stdin
+FILE __stdout;
+FILE __stdin;
+
+#pragma weak fputc
+int fputc(int ch, FILE *f)
+{
+    /* Send data. */
+    return DbgConsole_SendDataReliable((uint8_t *)(&ch), 1);
+}
+
+#pragma weak fgetc
+int fgetc(FILE *f)
+{
+    char ch;
+
+    /* Receive data. */
+    DbgConsole_ReadCharacter((uint8_t *)&ch);
+
+    return ch;
+}
+
+/*
+ * Terminate the program, passing a return code back to the user.
+ * This function may not return.
+ */
+void _sys_exit(int returncode)
+{
+    while (1)
+    {
+    }
+}
+
+/*
+ * Writes a character to the output channel. This function is used
+ * for last-resort error message output.
+ */
+void _ttywrch(int ch)
+{
+    char ench = ch;
+    DbgConsole_SendDataReliable((uint8_t *)(&ench), 1);
+}
+
+char *_sys_command_string(char *cmd, int len)
+{
+    return (cmd);
+}
+#endif /* SDK_DEBUGCONSOLE_UART */
+
+/* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/
+#elif (defined(__GNUC__))
+
+#if ((defined(__GNUC__) && (!defined(__MCUXPRESSO)) && (defined(SDK_DEBUGCONSOLE_UART))) || \
+     (defined(__MCUXPRESSO) && (defined(SDK_DEBUGCONSOLE_UART))))
+int __attribute__((weak)) _write(int handle, char *buffer, int size);
+int __attribute__((weak)) _write(int handle, char *buffer, int size)
+{
+    if (buffer == NULL)
+    {
+        /* return -1 if error. */
+        return -1;
+    }
+
+    /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+    if ((handle != 1) && (handle != 2))
+    {
+        return -1;
+    }
+
+    /* Send data. */
+    (void)DbgConsole_SendDataReliable((uint8_t *)buffer, (size_t)size);
+
+    return size;
+}
+
+int __attribute__((weak)) _read(int handle, char *buffer, int size);
+int __attribute__((weak)) _read(int handle, char *buffer, int size)
+{
+    uint8_t ch     = 0U;
+    int actualSize = 0;
+
+    /* This function only reads from "standard in", for all other file handles it returns failure. */
+    if (handle != 0)
+    {
+        return -1;
+    }
+
+    /* Receive data. */
+    for (; size > 0; size--)
+    {
+        if (DbgConsole_ReadCharacter(&ch) < 0)
+        {
+            break;
+        }
+
+        *buffer++ = (char)ch;
+        actualSize++;
+
+        if ((ch == 0U) || (ch == (uint8_t)'\n') || (ch == (uint8_t)'\r'))
+        {
+            break;
+        }
+    }
+
+    return (actualSize > 0) ? actualSize : -1;
+}
+#endif
+
+#endif /* __ICCARM__ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console.h b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console.h
new file mode 100755
index 0000000..9adf809
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Debug console shall provide input and output functions to scan and print formatted data.
+ * o Support a format specifier for PRINTF follows this prototype "%[flags][width][.precision][length]specifier"
+ *   - [flags] :'-', '+', '#', ' ', '0'
+ *   - [width]:  number (0,1...)
+ *   - [.precision]: number (0,1...)
+ *   - [length]: do not support
+ *   - [specifier]: 'd', 'i', 'f', 'F', 'x', 'X', 'o', 'p', 'u', 'c', 's', 'n'
+ * o Support a format specifier for SCANF follows this prototype " %[*][width][length]specifier"
+ *   - [*]: is supported.
+ *   - [width]: number (0,1...)
+ *   - [length]: 'h', 'hh', 'l','ll','L'. ignore ('j','z','t')
+ *   - [specifier]: 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'a', 'A', 'o', 'c', 's'
+ */
+
+#ifndef _FSL_DEBUGCONSOLE_H_
+#define _FSL_DEBUGCONSOLE_H_
+
+#include "fsl_common.h"
+#include "serial_manager.h"
+
+/*!
+ * @addtogroup debugconsole
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+extern serial_handle_t g_serialHandle; /*!< serial manager handle */
+
+/*! @brief Definition select redirect toolchain printf, scanf to uart or not. */
+#define DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN 0U /*!< Select toolchain printf and scanf. */
+#define DEBUGCONSOLE_REDIRECT_TO_SDK 1U       /*!< Select SDK version printf, scanf. */
+#define DEBUGCONSOLE_DISABLE 2U               /*!< Disable debugconsole function. */
+
+/*! @brief Definition to select sdk or toolchain printf, scanf. The macro only support
+ * to be redefined in project setting.
+ */
+#ifndef SDK_DEBUGCONSOLE
+#define SDK_DEBUGCONSOLE 1U
+#endif
+
+/*! @brief whether provide low level IO implementation to toolchain printf and scanf.
+ * For example, within MCUXpresso, if the macro SDK_DEBUGCONSOLE_UART is defined,
+ * __sys_write and __sys_readc will be used when __REDLIB__ is defined;
+ * _write and _read will be used in other cases.
+ * If the macro SDK_DEBUGCONSOLE_UART is not defined, the semihost will be used.
+ */
+#ifndef SDK_DEBUGCONSOLE_UART
+/* mcux will handle this macro, not define it here */
+#if (!defined(__MCUXPRESSO))
+#define SDK_DEBUGCONSOLE_UART
+#endif
+#endif
+
+#if defined(SDK_DEBUGCONSOLE) && !(SDK_DEBUGCONSOLE)
+#include <stdio.h>
+#endif
+
+/*! @brief Definition to select redirect toolchain printf, scanf to uart or not.
+ *
+ *  if SDK_DEBUGCONSOLE defined to 0,it represents select toolchain printf, scanf.
+ *  if SDK_DEBUGCONSOLE defined to 1,it represents select SDK version printf, scanf.
+ *  if SDK_DEBUGCONSOLE defined to 2,it represents disable debugconsole function.
+ */
+#if SDK_DEBUGCONSOLE == DEBUGCONSOLE_DISABLE /* Disable debug console */
+#define PRINTF(...) \
+    do              \
+    {               \
+    } while (0)
+#define SCANF(...) \
+    do             \
+    {              \
+    } while (0)
+#define PUTCHAR(...) \
+    do               \
+    {                \
+    } while (0)
+#define GETCHAR() -1
+#elif SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK /* Select printf, scanf, putchar, getchar of SDK version. */
+#define PRINTF DbgConsole_Printf
+#define SCANF DbgConsole_Scanf
+#define PUTCHAR DbgConsole_Putchar
+#define GETCHAR DbgConsole_Getchar
+#elif SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN /* Select printf, scanf, putchar, getchar of toolchain. \ \
+                                                              */
+#define PRINTF printf
+#define SCANF scanf
+#define PUTCHAR putchar
+#define GETCHAR getchar
+#endif /* SDK_DEBUGCONSOLE */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*! @name Initialization*/
+/* @{ */
+
+/*!
+ * @brief Initializes the peripheral used for debug messages.
+ *
+ * Call this function to enable debug log messages to be output via the specified peripheral
+ * initialized by the serial manager module.
+ * After this function has returned, stdout and stdin are connected to the selected peripheral.
+ *
+ * @param instance      The instance of the module.
+ * @param baudRate      The desired baud rate in bits per second.
+ * @param device        Low level device type for the debug console, can be one of the following.
+ *                      @arg kSerialPort_Uart,
+ *                      @arg kSerialPort_UsbCdc
+ *                      @arg kSerialPort_UsbCdcVirtual.
+ * @param clkSrcFreq    Frequency of peripheral source clock.
+ *
+ * @return              Indicates whether initialization was successful or not.
+ * @retval kStatus_Success          Execution successfully
+ */
+status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq);
+
+/*!
+ * @brief De-initializes the peripheral used for debug messages.
+ *
+ * Call this function to disable debug log messages to be output via the specified peripheral
+ * initialized by the serial manager module.
+ *
+ * @return Indicates whether de-initialization was successful or not.
+ */
+status_t DbgConsole_Deinit(void);
+
+#if SDK_DEBUGCONSOLE
+/*!
+ * @brief Writes formatted output to the standard output stream.
+ *
+ * Call this function to write a formatted output to the standard output stream.
+ *
+ * @param   formatString Format control string.
+ * @return  Returns the number of characters printed or a negative value if an error occurs.
+ */
+int DbgConsole_Printf(const char *formatString, ...);
+
+/*!
+ * @brief Writes a character to stdout.
+ *
+ * Call this function to write a character to stdout.
+ *
+ * @param   ch Character to be written.
+ * @return  Returns the character written.
+ */
+int DbgConsole_Putchar(int ch);
+
+/*!
+ * @brief Reads formatted data from the standard input stream.
+ *
+ * Call this function to read formatted data from the standard input stream.
+ *
+ * @note Due the limitation in the BM OSA environment (CPU is blocked in the function,
+ * other tasks will not be scheduled), the function cannot be used when the
+ * DEBUG_CONSOLE_TRANSFER_NON_BLOCKING is set in the BM OSA environment.
+ * And an error is returned when the function called in this case. The suggestion
+ * is that polling the non-blocking function DbgConsole_TryGetchar to get the input char.
+ *
+ * @param   formatString Format control string.
+ * @return  Returns the number of fields successfully converted and assigned.
+ */
+int DbgConsole_Scanf(char *formatString, ...);
+
+/*!
+ * @brief Reads a character from standard input.
+ *
+ * Call this function to read a character from standard input.
+ *
+ * @note Due the limitation in the BM OSA environment (CPU is blocked in the function,
+ * other tasks will not be scheduled), the function cannot be used when the
+ * DEBUG_CONSOLE_TRANSFER_NON_BLOCKING is set in the BM OSA environment.
+ * And an error is returned when the function called in this case. The suggestion
+ * is that polling the non-blocking function DbgConsole_TryGetchar to get the input char.
+ *
+ * @return Returns the character read.
+ */
+int DbgConsole_Getchar(void);
+
+/*!
+ * @brief Debug console flush.
+ *
+ * Call this function to wait the tx buffer empty.
+ * If interrupt transfer is using, make sure the global IRQ is enable before call this function
+ * This function should be called when
+ * 1, before enter power down mode
+ * 2, log is required to print to terminal immediately
+ * @return Indicates whether wait idle was successful or not.
+ */
+status_t DbgConsole_Flush(void);
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*!
+ * @brief Debug console try to get char
+ * This function provides a API which will not block current task, if character is
+ * available return it, otherwise return fail.
+ * @param ch the address of char to receive
+ * @return Indicates get char was successful or not.
+ */
+status_t DbgConsole_TryGetchar(char *ch);
+#endif
+
+#endif /* SDK_DEBUGCONSOLE */
+
+/*! @} */
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_DEBUGCONSOLE_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console_conf.h b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console_conf.h
new file mode 100755
index 0000000..366c6cd
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/debug_console/fsl_debug_console_conf.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2017 - 2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_DEBUG_CONSOLE_CONF_H_
+#define _FSL_DEBUG_CONSOLE_CONF_H_
+
+/****************Debug console configuration********************/
+
+/*! @brief If Non-blocking mode is needed, please define it at project setting,
+ * otherwise blocking mode is the default transfer mode.
+ * Warning: If you want to use non-blocking transfer,please make sure the corresponding
+ * IO interrupt is enable, otherwise there is no output.
+ * And non-blocking is combine with buffer, no matter bare-metal or rtos.
+ * Below shows how to configure in your project if you want to use non-blocking mode.
+ * For IAR, right click project and select "Options", define it in "C/C++ Compiler->Preprocessor->Defined symbols".
+ * For KEIL, click "Options for Target…", define it in "C/C++->Preprocessor Symbols->Define".
+ * For ARMGCC, open CmakeLists.txt and add the following lines,
+ * "SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG_CONSOLE_TRANSFER_NON_BLOCKING")" for debug target.
+ * "SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DDEBUG_CONSOLE_TRANSFER_NON_BLOCKING")" for release target.
+ * For MCUxpresso, right click project and select "Properties", define it in "C/C++ Build->Settings->MCU C
+ * Complier->Preprocessor".
+ *
+ */
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*! @brief define the transmit buffer length which is used to store the multi task log, buffer is enabled automatically
+ * when
+ * non-blocking transfer is using,
+ * This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement.
+ * If it is configured too small, log maybe missed , because the log will not be
+ * buffered if the buffer is full, and the print will return immediately with -1.
+ * And this value should be multiple of 4 to meet memory alignment.
+ *
+ */
+#ifndef DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN
+#define DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN (512U)
+#endif /* DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN */
+
+/*! @brief define the receive buffer length which is used to store the user input, buffer is enabled automatically when
+ * non-blocking transfer is using,
+ * This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement.
+ * If it is configured too small, log maybe missed, because buffer will be overwrited if buffer is too small.
+ * And this value should be multiple of 4 to meet memory alignment.
+ *
+ */
+#ifndef DEBUG_CONSOLE_RECEIVE_BUFFER_LEN
+#define DEBUG_CONSOLE_RECEIVE_BUFFER_LEN (1024U)
+#endif /* DEBUG_CONSOLE_RECEIVE_BUFFER_LEN */
+
+/*!@ brief Whether enable the reliable TX function
+ * If the macro is zero, the reliable TX function of the debug console is disabled.
+ * When the macro is zero, the string of PRINTF will be thrown away after the transmit buffer is full.
+ */
+#ifndef DEBUG_CONSOLE_TX_RELIABLE_ENABLE
+#define DEBUG_CONSOLE_TX_RELIABLE_ENABLE (1U)
+#endif /* DEBUG_CONSOLE_RX_ENABLE */
+
+#else
+#define DEBUG_CONSOLE_TRANSFER_BLOCKING
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/*!@ brief Whether enable the RX function
+ * If the macro is zero, the receive function of the debug console is disabled.
+ */
+#ifndef DEBUG_CONSOLE_RX_ENABLE
+#define DEBUG_CONSOLE_RX_ENABLE (1U)
+#endif /* DEBUG_CONSOLE_RX_ENABLE */
+
+/*!@ brief define the MAX log length debug console support , that is when you call printf("log", x);, the log
+ * length can not bigger than this value.
+ * This macro decide the local log buffer length, the buffer locate at stack, the stack maybe overflow if
+ * the buffer is too big and current task stack size not big enough.
+ */
+#ifndef DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN
+#define DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN (128U)
+#endif /* DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN */
+
+/*!@ brief define the buffer support buffer scanf log length, that is when you call scanf("log", &x);, the log
+ * length can not bigger than this value.
+ * As same as the DEBUG_CONSOLE_BUFFER_PRINTF_MAX_LOG_LEN.
+ */
+#ifndef DEBUG_CONSOLE_SCANF_MAX_LOG_LEN
+#define DEBUG_CONSOLE_SCANF_MAX_LOG_LEN (20U)
+#endif /* DEBUG_CONSOLE_SCANF_MAX_LOG_LEN */
+
+/*! @brief Debug console synchronization
+ * User should not change these macro for synchronization mode, but add the
+ * corresponding synchronization mechanism per different software environment.
+ * Such as, if another RTOS is used,
+ * add:
+ *  #define DEBUG_CONSOLE_SYNCHRONIZATION_XXXX 3
+ * in this configuration file and implement the synchronization in fsl.log.c.
+ */
+/*! @brief synchronization for baremetal software */
+#define DEBUG_CONSOLE_SYNCHRONIZATION_BM 0
+/*! @brief synchronization for freertos software */
+#define DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS 1
+
+/*! @brief RTOS synchronization mechanism disable
+ * If not defined, default is enable, to avoid multitask log print mess.
+ * If other RTOS is used, you can implement the RTOS's specific synchronization mechanism in fsl.log.c
+ * If synchronization is disabled, log maybe messed on terminal.
+ */
+#ifndef DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+#ifdef FSL_RTOS_FREE_RTOS
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS
+#else
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM
+#endif /* FSL_RTOS_FREE_RTOS */
+#else
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+#endif /* DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION */
+
+/*! @brief echo function support
+ * If you want to use the echo function,please define DEBUG_CONSOLE_ENABLE_ECHO
+ * at your project setting.
+ */
+#ifndef DEBUG_CONSOLE_ENABLE_ECHO
+#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 0
+#else
+#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 1
+#endif /* DEBUG_CONSOLE_ENABLE_ECHO */
+
+/*********************************************************************/
+
+/***************Debug console other configuration*********************/
+/*! @brief Definition to printf the float number. */
+#ifndef PRINTF_FLOAT_ENABLE
+#define PRINTF_FLOAT_ENABLE 0U
+#endif /* PRINTF_FLOAT_ENABLE */
+
+/*! @brief Definition to scanf the float number. */
+#ifndef SCANF_FLOAT_ENABLE
+#define SCANF_FLOAT_ENABLE 0U
+#endif /* SCANF_FLOAT_ENABLE */
+
+/*! @brief Definition to support advanced format specifier for printf. */
+#ifndef PRINTF_ADVANCED_ENABLE
+#define PRINTF_ADVANCED_ENABLE 0U
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+/*! @brief Definition to support advanced format specifier for scanf. */
+#ifndef SCANF_ADVANCED_ENABLE
+#define SCANF_ADVANCED_ENABLE 0U
+#endif /* SCANF_ADVANCED_ENABLE */
+
+/*! @brief Definition to select virtual com(USB CDC) as the debug console. */
+#ifndef BOARD_USE_VIRTUALCOM
+#define BOARD_USE_VIRTUALCOM 0U
+#endif
+/*******************************************************************/
+
+#endif /* _FSL_DEBUG_CONSOLE_CONF_H_ */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/utilities/fsl_assert.c b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/fsl_assert.c
new file mode 100755
index 0000000..9052faf
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/fsl_assert.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_debug_console.h"
+
+#ifndef NDEBUG
+#if (defined(__CC_ARM)) || (defined(__ARMCC_VERSION)) || (defined(__ICCARM__))
+void __aeabi_assert(const char *failedExpr, const char *file, int line)
+{
+    PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line);
+    for (;;)
+    {
+        __BKPT(0);
+    }
+}
+#elif (defined(__GNUC__))
+void __assert_func(const char *file, int line, const char *func, const char *failedExpr)
+{
+    PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, func);
+    for (;;)
+    {
+        __BKPT(0);
+    }
+}
+#endif /* (defined(__CC_ARM) || (defined(__ICCARM__)) || (defined(__ARMCC_VERSION)) */
+#endif /* NDEBUG */
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str/fsl_str.c b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str/fsl_str.c
new file mode 100755
index 0000000..c4d1a0c
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str/fsl_str.c
@@ -0,0 +1,1324 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <math.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "fsl_str.h"
+#include "fsl_debug_console_conf.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief The overflow value.*/
+#ifndef HUGE_VAL
+#define HUGE_VAL (99.e99)
+#endif /* HUGE_VAL */
+
+#if PRINTF_ADVANCED_ENABLE
+/*! @brief Specification modifier flags for printf. */
+enum _debugconsole_printf_flag
+{
+    kPRINTF_Minus             = 0x01U,  /*!< Minus FLag. */
+    kPRINTF_Plus              = 0x02U,  /*!< Plus Flag. */
+    kPRINTF_Space             = 0x04U,  /*!< Space Flag. */
+    kPRINTF_Zero              = 0x08U,  /*!< Zero Flag. */
+    kPRINTF_Pound             = 0x10U,  /*!< Pound Flag. */
+    kPRINTF_LengthChar        = 0x20U,  /*!< Length: Char Flag. */
+    kPRINTF_LengthShortInt    = 0x40U,  /*!< Length: Short Int Flag. */
+    kPRINTF_LengthLongInt     = 0x80U,  /*!< Length: Long Int Flag. */
+    kPRINTF_LengthLongLongInt = 0x100U, /*!< Length: Long Long Int Flag. */
+};
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+/*! @brief Specification modifier flags for scanf. */
+enum _debugconsole_scanf_flag
+{
+    kSCANF_Suppress   = 0x2U,    /*!< Suppress Flag. */
+    kSCANF_DestMask   = 0x7cU,   /*!< Destination Mask. */
+    kSCANF_DestChar   = 0x4U,    /*!< Destination Char Flag. */
+    kSCANF_DestString = 0x8U,    /*!< Destination String FLag. */
+    kSCANF_DestSet    = 0x10U,   /*!< Destination Set Flag. */
+    kSCANF_DestInt    = 0x20U,   /*!< Destination Int Flag. */
+    kSCANF_DestFloat  = 0x30U,   /*!< Destination Float Flag. */
+    kSCANF_LengthMask = 0x1f00U, /*!< Length Mask Flag. */
+#if SCANF_ADVANCED_ENABLE
+    kSCANF_LengthChar        = 0x100U, /*!< Length Char Flag. */
+    kSCANF_LengthShortInt    = 0x200U, /*!< Length ShortInt Flag. */
+    kSCANF_LengthLongInt     = 0x400U, /*!< Length LongInt Flag. */
+    kSCANF_LengthLongLongInt = 0x800U, /*!< Length LongLongInt Flag. */
+#endif                                 /* SCANF_ADVANCED_ENABLE */
+#if SCANF_FLOAT_ENABLE
+    kSCANF_LengthLongLongDouble = 0x1000U, /*!< Length LongLongDuoble Flag. */
+#endif                                     /*PRINTF_FLOAT_ENABLE */
+    kSCANF_TypeSinged = 0x2000U,           /*!< TypeSinged Flag. */
+};
+
+/*! @brief Keil: suppress ellipsis warning in va_arg usage below. */
+#if defined(__CC_ARM)
+#pragma diag_suppress 1256
+#endif /* __CC_ARM */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Scanline function which ignores white spaces.
+ *
+ * @param[in]   s The address of the string pointer to update.
+ * @return      String without white spaces.
+ */
+static uint32_t ScanIgnoreWhiteSpace(const char **s);
+
+/*!
+ * @brief Converts a radix number to a string and return its length.
+ *
+ * @param[in] numstr    Converted string of the number.
+ * @param[in] nump      Pointer to the number.
+ * @param[in] neg       Polarity of the number.
+ * @param[in] radix     The radix to be converted to.
+ * @param[in] use_caps  Used to identify %x/X output format.
+
+ * @return Length of the converted string.
+ */
+static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps);
+
+#if PRINTF_FLOAT_ENABLE
+/*!
+ * @brief Converts a floating radix number to a string and return its length.
+ *
+ * @param[in] numstr            Converted string of the number.
+ * @param[in] nump              Pointer to the number.
+ * @param[in] radix             The radix to be converted to.
+ * @param[in] precision_width   Specify the precision width.
+
+ * @return Length of the converted string.
+ */
+static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width);
+#endif /* PRINTF_FLOAT_ENABLE */
+
+/*!
+ *
+ */
+double modf(double input_dbl, double *intpart_ptr);
+
+/*************Code for process formatted data*******************************/
+
+static uint32_t ScanIgnoreWhiteSpace(const char **s)
+{
+    uint8_t count = 0;
+    uint8_t c;
+
+    c = **s;
+    while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\v') || (c == '\f'))
+    {
+        count++;
+        (*s)++;
+        c = **s;
+    }
+    return count;
+}
+
+static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps)
+{
+#if PRINTF_ADVANCED_ENABLE
+    int64_t a;
+    int64_t b;
+    int64_t c;
+
+    uint64_t ua;
+    uint64_t ub;
+    uint64_t uc;
+#else
+    int32_t a;
+    int32_t b;
+    int32_t c;
+
+    uint32_t ua;
+    uint32_t ub;
+    uint32_t uc;
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+    int32_t nlen;
+    char *nstrp;
+
+    nlen     = 0;
+    nstrp    = numstr;
+    *nstrp++ = '\0';
+
+    if (neg)
+    {
+#if PRINTF_ADVANCED_ENABLE
+        a = *(int64_t *)nump;
+#else
+        a = *(int32_t *)nump;
+#endif /* PRINTF_ADVANCED_ENABLE */
+        if (a == 0)
+        {
+            *nstrp = '0';
+            ++nlen;
+            return nlen;
+        }
+        while (a != 0)
+        {
+#if PRINTF_ADVANCED_ENABLE
+            b = (int64_t)a / (int64_t)radix;
+            c = (int64_t)a - ((int64_t)b * (int64_t)radix);
+            if (c < 0)
+            {
+                uc = (uint64_t)c;
+                c  = (int64_t)(~uc) + 1 + '0';
+            }
+#else
+            b = a / radix;
+            c = a - (b * radix);
+            if (c < 0)
+            {
+                uc = (uint32_t)c;
+                c  = (uint32_t)(~uc) + 1 + '0';
+            }
+#endif /* PRINTF_ADVANCED_ENABLE */
+            else
+            {
+                c = c + '0';
+            }
+            a        = b;
+            *nstrp++ = (char)c;
+            ++nlen;
+        }
+    }
+    else
+    {
+#if PRINTF_ADVANCED_ENABLE
+        ua = *(uint64_t *)nump;
+#else
+        ua = *(uint32_t *)nump;
+#endif /* PRINTF_ADVANCED_ENABLE */
+        if (ua == 0)
+        {
+            *nstrp = '0';
+            ++nlen;
+            return nlen;
+        }
+        while (ua != 0)
+        {
+#if PRINTF_ADVANCED_ENABLE
+            ub = (uint64_t)ua / (uint64_t)radix;
+            uc = (uint64_t)ua - ((uint64_t)ub * (uint64_t)radix);
+#else
+            ub = ua / (uint32_t)radix;
+            uc = ua - (ub * (uint32_t)radix);
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+            if (uc < 10)
+            {
+                uc = uc + '0';
+            }
+            else
+            {
+                uc = uc - 10 + (use_caps ? 'A' : 'a');
+            }
+            ua       = ub;
+            *nstrp++ = (char)uc;
+            ++nlen;
+        }
+    }
+    return nlen;
+}
+
+#if PRINTF_FLOAT_ENABLE
+static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width)
+{
+    int32_t a;
+    int32_t b;
+    int32_t c;
+    int32_t i;
+    uint32_t uc;
+    double fa;
+    double dc;
+    double fb;
+    double r;
+    double fractpart;
+    double intpart;
+
+    int32_t nlen;
+    char *nstrp;
+    nlen     = 0;
+    nstrp    = numstr;
+    *nstrp++ = '\0';
+    r        = *(double *)nump;
+    if (!r)
+    {
+        *nstrp = '0';
+        ++nlen;
+        return nlen;
+    }
+    fractpart = modf((double)r, (double *)&intpart);
+    /* Process fractional part. */
+    for (i = 0; i < precision_width; i++)
+    {
+        fractpart *= radix;
+    }
+    if (r >= 0)
+    {
+        fa = fractpart + (double)0.5;
+        if (fa >= pow(10, precision_width))
+        {
+            intpart++;
+        }
+    }
+    else
+    {
+        fa = fractpart - (double)0.5;
+        if (fa <= -pow(10, precision_width))
+        {
+            intpart--;
+        }
+    }
+    for (i = 0; i < precision_width; i++)
+    {
+        fb = fa / (int32_t)radix;
+        dc = (fa - (int64_t)fb * (int32_t)radix);
+        c  = (int32_t)dc;
+        if (c < 0)
+        {
+            uc = (uint32_t)c;
+            c  = (int32_t)(~uc) + 1 + '0';
+        }
+        else
+        {
+            c = c + '0';
+        }
+        fa       = fb;
+        *nstrp++ = (char)c;
+        ++nlen;
+    }
+    *nstrp++ = (char)'.';
+    ++nlen;
+    a = (int32_t)intpart;
+    if (a == 0)
+    {
+        *nstrp++ = '0';
+        ++nlen;
+    }
+    else
+    {
+        while (a != 0)
+        {
+            b = (int32_t)a / (int32_t)radix;
+            c = (int32_t)a - ((int32_t)b * (int32_t)radix);
+            if (c < 0)
+            {
+                uc = (uint32_t)c;
+                c  = (int32_t)(~uc) + 1 + '0';
+            }
+            else
+            {
+                c = c + '0';
+            }
+            a        = b;
+            *nstrp++ = (char)c;
+            ++nlen;
+        }
+    }
+    return nlen;
+}
+#endif /* PRINTF_FLOAT_ENABLE */
+
+/*!
+ * brief This function outputs its parameters according to a formatted string.
+ *
+ * note I/O is performed by calling given function pointer using following
+ * (*func_ptr)(c);
+ *
+ * param[in] fmt_ptr   Format string for printf.
+ * param[in] args_ptr  Arguments to printf.
+ * param[in] buf  pointer to the buffer
+ * param cb print callback function pointer
+ *
+ * return Number of characters to be print
+ */
+int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb)
+{
+    /* va_list ap; */
+    char *p;
+    int32_t c;
+
+    char vstr[33];
+    char *vstrp  = NULL;
+    int32_t vlen = 0;
+
+    int32_t done;
+    int32_t count = 0;
+
+    uint32_t field_width;
+    uint32_t precision_width;
+    char *sval;
+    int32_t cval;
+    bool use_caps;
+    uint8_t radix = 0;
+
+#if PRINTF_ADVANCED_ENABLE
+    uint32_t flags_used;
+    int32_t schar, dschar;
+    int64_t ival;
+    uint64_t uval = 0;
+    bool valid_precision_width;
+#else
+    int32_t ival;
+    uint32_t uval = 0;
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+#if PRINTF_FLOAT_ENABLE
+    double fval;
+#endif /* PRINTF_FLOAT_ENABLE */
+
+    /* Start parsing apart the format string and display appropriate formats and data. */
+    for (p = (char *)fmt; (c = *p) != 0; p++)
+    {
+        /*
+         * All formats begin with a '%' marker.  Special chars like
+         * '\n' or '\t' are normally converted to the appropriate
+         * character by the __compiler__.  Thus, no need for this
+         * routine to account for the '\' character.
+         */
+        if (c != '%')
+        {
+            cb(buf, &count, c, 1);
+            /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */
+            continue;
+        }
+
+        use_caps = true;
+
+#if PRINTF_ADVANCED_ENABLE
+        /* First check for specification modifier flags. */
+        flags_used = 0;
+        done       = false;
+        while (!done)
+        {
+            switch (*++p)
+            {
+                case '-':
+                    flags_used |= kPRINTF_Minus;
+                    break;
+                case '+':
+                    flags_used |= kPRINTF_Plus;
+                    break;
+                case ' ':
+                    flags_used |= kPRINTF_Space;
+                    break;
+                case '0':
+                    flags_used |= kPRINTF_Zero;
+                    break;
+                case '#':
+                    flags_used |= kPRINTF_Pound;
+                    break;
+                default:
+                    /* We've gone one char too far. */
+                    --p;
+                    done = true;
+                    break;
+            }
+        }
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+        /* Next check for minimum field width. */
+        field_width = 0;
+        done        = false;
+        while (!done)
+        {
+            c = *++p;
+            if ((c >= '0') && (c <= '9'))
+            {
+                field_width = (field_width * 10) + (c - '0');
+            }
+#if PRINTF_ADVANCED_ENABLE
+            else if (c == '*')
+            {
+                field_width = (uint32_t)va_arg(ap, uint32_t);
+            }
+#endif /* PRINTF_ADVANCED_ENABLE */
+            else
+            {
+                /* We've gone one char too far. */
+                --p;
+                done = true;
+            }
+        }
+        /* Next check for the width and precision field separator. */
+        precision_width = 6;
+#if PRINTF_ADVANCED_ENABLE
+        valid_precision_width = false;
+#endif /* PRINTF_ADVANCED_ENABLE */
+        if (*++p == '.')
+        {
+            /* Must get precision field width, if present. */
+            precision_width = 0;
+            done            = false;
+            while (!done)
+            {
+                c = *++p;
+                if ((c >= '0') && (c <= '9'))
+                {
+                    precision_width = (precision_width * 10) + (c - '0');
+#if PRINTF_ADVANCED_ENABLE
+                    valid_precision_width = true;
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+#if PRINTF_ADVANCED_ENABLE
+                else if (c == '*')
+                {
+                    precision_width       = (uint32_t)va_arg(ap, uint32_t);
+                    valid_precision_width = true;
+                }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                else
+                {
+                    /* We've gone one char too far. */
+                    --p;
+                    done = true;
+                }
+            }
+        }
+        else
+        {
+            /* We've gone one char too far. */
+            --p;
+        }
+#if PRINTF_ADVANCED_ENABLE
+        /*
+         * Check for the length modifier.
+         */
+        switch (/* c = */ *++p)
+        {
+            case 'h':
+                if (*++p != 'h')
+                {
+                    flags_used |= kPRINTF_LengthShortInt;
+                    --p;
+                }
+                else
+                {
+                    flags_used |= kPRINTF_LengthChar;
+                }
+                break;
+            case 'l':
+                if (*++p != 'l')
+                {
+                    flags_used |= kPRINTF_LengthLongInt;
+                    --p;
+                }
+                else
+                {
+                    flags_used |= kPRINTF_LengthLongLongInt;
+                }
+                break;
+            default:
+                /* we've gone one char too far */
+                --p;
+                break;
+        }
+#endif /* PRINTF_ADVANCED_ENABLE */
+        /* Now we're ready to examine the format. */
+        c = *++p;
+        {
+            if ((c == 'd') || (c == 'i') || (c == 'f') || (c == 'F') || (c == 'x') || (c == 'X') || (c == 'o') ||
+                (c == 'b') || (c == 'p') || (c == 'u'))
+            {
+                if ((c == 'd') || (c == 'i'))
+                {
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_LengthLongLongInt)
+                    {
+                        ival = (int64_t)va_arg(ap, int64_t);
+                    }
+                    else
+#endif /* PRINTF_ADVANCED_ENABLE */
+                    {
+                        ival = (int32_t)va_arg(ap, int32_t);
+                    }
+                    vlen  = ConvertRadixNumToString(vstr, &ival, true, 10, use_caps);
+                    vstrp = &vstr[vlen];
+#if PRINTF_ADVANCED_ENABLE
+                    if (ival < 0)
+                    {
+                        schar = '-';
+                        ++vlen;
+                    }
+                    else
+                    {
+                        if (flags_used & kPRINTF_Plus)
+                        {
+                            schar = '+';
+                            ++vlen;
+                        }
+                        else
+                        {
+                            if (flags_used & kPRINTF_Space)
+                            {
+                                schar = ' ';
+                                ++vlen;
+                            }
+                            else
+                            {
+                                schar = 0;
+                            }
+                        }
+                    }
+                    dschar = false;
+                    /* Do the ZERO pad. */
+                    if (flags_used & kPRINTF_Zero)
+                    {
+                        if (schar)
+                        {
+                            cb(buf, &count, schar, 1);
+                        }
+                        dschar = true;
+
+                        cb(buf, &count, '0', field_width - vlen);
+                        vlen = field_width;
+                    }
+                    else
+                    {
+                        if (!(flags_used & kPRINTF_Minus))
+                        {
+                            cb(buf, &count, ' ', field_width - vlen);
+                            if (schar)
+                            {
+                                cb(buf, &count, schar, 1);
+                            }
+                            dschar = true;
+                        }
+                    }
+                    /* The string was built in reverse order, now display in correct order. */
+                    if ((!dschar) && schar)
+                    {
+                        cb(buf, &count, schar, 1);
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+
+#if PRINTF_FLOAT_ENABLE
+                if ((c == 'f') || (c == 'F'))
+                {
+                    fval  = (double)va_arg(ap, double);
+                    vlen  = ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width);
+                    vstrp = &vstr[vlen];
+
+#if PRINTF_ADVANCED_ENABLE
+                    if (fval < 0)
+                    {
+                        schar = '-';
+                        ++vlen;
+                    }
+                    else
+                    {
+                        if (flags_used & kPRINTF_Plus)
+                        {
+                            schar = '+';
+                            ++vlen;
+                        }
+                        else
+                        {
+                            if (flags_used & kPRINTF_Space)
+                            {
+                                schar = ' ';
+                                ++vlen;
+                            }
+                            else
+                            {
+                                schar = 0;
+                            }
+                        }
+                    }
+                    dschar = false;
+                    if (flags_used & kPRINTF_Zero)
+                    {
+                        if (schar)
+                        {
+                            cb(buf, &count, schar, 1);
+                        }
+                        dschar = true;
+                        cb(buf, &count, '0', field_width - vlen);
+                        vlen = field_width;
+                    }
+                    else
+                    {
+                        if (!(flags_used & kPRINTF_Minus))
+                        {
+                            cb(buf, &count, ' ', field_width - vlen);
+                            if (schar)
+                            {
+                                cb(buf, &count, schar, 1);
+                            }
+                            dschar = true;
+                        }
+                    }
+                    if ((!dschar) && schar)
+                    {
+                        cb(buf, &count, schar, 1);
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+#endif /* PRINTF_FLOAT_ENABLE */
+                if ((c == 'X') || (c == 'x'))
+                {
+                    if (c == 'x')
+                    {
+                        use_caps = false;
+                    }
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_LengthLongLongInt)
+                    {
+                        uval = (uint64_t)va_arg(ap, uint64_t);
+                    }
+                    else
+#endif /* PRINTF_ADVANCED_ENABLE */
+                    {
+                        uval = (uint32_t)va_arg(ap, uint32_t);
+                    }
+                    vlen  = ConvertRadixNumToString(vstr, &uval, false, 16, use_caps);
+                    vstrp = &vstr[vlen];
+
+#if PRINTF_ADVANCED_ENABLE
+                    dschar = false;
+                    if (flags_used & kPRINTF_Zero)
+                    {
+                        if (flags_used & kPRINTF_Pound)
+                        {
+                            cb(buf, &count, '0', 1);
+                            cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+                            dschar = true;
+                        }
+                        cb(buf, &count, '0', field_width - vlen);
+                        vlen = field_width;
+                    }
+                    else
+                    {
+                        if (!(flags_used & kPRINTF_Minus))
+                        {
+                            if (flags_used & kPRINTF_Pound)
+                            {
+                                vlen += 2;
+                            }
+                            cb(buf, &count, ' ', field_width - vlen);
+                            if (flags_used & kPRINTF_Pound)
+                            {
+                                cb(buf, &count, '0', 1);
+                                cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+                                dschar = true;
+                            }
+                        }
+                    }
+
+                    if ((flags_used & kPRINTF_Pound) && (!dschar))
+                    {
+                        cb(buf, &count, '0', 1);
+                        cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+                        vlen += 2;
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+                if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u'))
+                {
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_LengthLongLongInt)
+                    {
+                        uval = (uint64_t)va_arg(ap, uint64_t);
+                    }
+                    else
+#endif /* PRINTF_ADVANCED_ENABLE */
+                    {
+                        uval = (uint32_t)va_arg(ap, uint32_t);
+                    }
+
+                    if (c == 'o')
+                    {
+                        radix = 8;
+                    }
+                    else if (c == 'b')
+                    {
+                        radix = 2;
+                    }
+                    else if (c == 'p')
+                    {
+                        radix = 16;
+                    }
+                    else
+                    {
+                        radix = 10;
+                    }
+
+                    vlen  = ConvertRadixNumToString(vstr, &uval, false, radix, use_caps);
+                    vstrp = &vstr[vlen];
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_Zero)
+                    {
+                        cb(buf, &count, '0', field_width - vlen);
+                        vlen = field_width;
+                    }
+                    else
+                    {
+                        if (!(flags_used & kPRINTF_Minus))
+                        {
+                            cb(buf, &count, ' ', field_width - vlen);
+                        }
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+#if !PRINTF_ADVANCED_ENABLE
+                cb(buf, &count, ' ', field_width - vlen);
+#endif /* !PRINTF_ADVANCED_ENABLE */
+                if (vstrp != NULL)
+                {
+                    while (*vstrp)
+                    {
+                        cb(buf, &count, *vstrp--, 1);
+                    }
+                }
+#if PRINTF_ADVANCED_ENABLE
+                if (flags_used & kPRINTF_Minus)
+                {
+                    cb(buf, &count, ' ', field_width - vlen);
+                }
+#endif /* PRINTF_ADVANCED_ENABLE */
+            }
+            else if (c == 'c')
+            {
+                cval = (char)va_arg(ap, uint32_t);
+                cb(buf, &count, cval, 1);
+            }
+            else if (c == 's')
+            {
+                sval = (char *)va_arg(ap, char *);
+                if (sval)
+                {
+#if PRINTF_ADVANCED_ENABLE
+                    if (valid_precision_width)
+                    {
+                        vlen = precision_width;
+                    }
+                    else
+                    {
+                        vlen = strlen(sval);
+                    }
+#else
+                    vlen = strlen(sval);
+#endif /* PRINTF_ADVANCED_ENABLE */
+#if PRINTF_ADVANCED_ENABLE
+                    if (!(flags_used & kPRINTF_Minus))
+#endif /* PRINTF_ADVANCED_ENABLE */
+                    {
+                        cb(buf, &count, ' ', field_width - vlen);
+                    }
+
+#if PRINTF_ADVANCED_ENABLE
+                    if (valid_precision_width)
+                    {
+                        while ((*sval) && (vlen > 0))
+                        {
+                            cb(buf, &count, *sval++, 1);
+                            vlen--;
+                        }
+                        /* In case that vlen sval is shorter than vlen */
+                        vlen = precision_width - vlen;
+                    }
+                    else
+                    {
+#endif /* PRINTF_ADVANCED_ENABLE */
+                        while (*sval)
+                        {
+                            cb(buf, &count, *sval++, 1);
+                        }
+#if PRINTF_ADVANCED_ENABLE
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+#if PRINTF_ADVANCED_ENABLE
+                    if (flags_used & kPRINTF_Minus)
+                    {
+                        cb(buf, &count, ' ', field_width - vlen);
+                    }
+#endif /* PRINTF_ADVANCED_ENABLE */
+                }
+            }
+            else
+            {
+                cb(buf, &count, c, 1);
+            }
+        }
+    }
+
+    return count;
+}
+
+/*!
+ * brief Converts an input line of ASCII characters based upon a provided
+ * string format.
+ *
+ * param[in] line_ptr The input line of ASCII data.
+ * param[in] format   Format first points to the format string.
+ * param[in] args_ptr The list of parameters.
+ *
+ * return Number of input items converted and assigned.
+ * retval IO_EOF When line_ptr is empty string "".
+ */
+int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr)
+{
+    uint8_t base;
+    int8_t neg;
+    /* Identifier for the format string. */
+    char *c = format;
+    char temp;
+    char *buf;
+    /* Flag telling the conversion specification. */
+    uint32_t flag = 0;
+    /* Filed width for the matching input streams. */
+    uint32_t field_width;
+    /* How many arguments are assigned except the suppress. */
+    uint32_t nassigned = 0;
+    /* How many characters are read from the input streams. */
+    uint32_t n_decode = 0;
+
+    int32_t val;
+
+    const char *s;
+    /* Identifier for the input string. */
+    const char *p = line_ptr;
+
+#if SCANF_FLOAT_ENABLE
+    double fnum = 0.0;
+#endif /* SCANF_FLOAT_ENABLE */
+    /* Return EOF error before any conversion. */
+    if (*p == '\0')
+    {
+        return -1;
+    }
+
+    /* Decode directives. */
+    while ((*c) && (*p))
+    {
+        /* Ignore all white-spaces in the format strings. */
+        if (ScanIgnoreWhiteSpace((const char **)&c))
+        {
+            n_decode += ScanIgnoreWhiteSpace(&p);
+        }
+        else if ((*c != '%') || ((*c == '%') && (*(c + 1) == '%')))
+        {
+            /* Ordinary characters. */
+            c++;
+            if (*p == *c)
+            {
+                n_decode++;
+                p++;
+                c++;
+            }
+            else
+            {
+                /* Match failure. Misalignment with C99, the unmatched characters need to be pushed back to stream.
+                 * However, it is deserted now. */
+                break;
+            }
+        }
+        else
+        {
+            /* convernsion specification */
+            c++;
+            /* Reset. */
+            flag        = 0;
+            field_width = 0;
+            base        = 0;
+
+            /* Loop to get full conversion specification. */
+            while ((*c) && (!(flag & kSCANF_DestMask)))
+            {
+                switch (*c)
+                {
+#if SCANF_ADVANCED_ENABLE
+                    case '*':
+                        if (flag & kSCANF_Suppress)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+                        flag |= kSCANF_Suppress;
+                        c++;
+                        break;
+                    case 'h':
+                        if (flag & kSCANF_LengthMask)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+
+                        if (c[1] == 'h')
+                        {
+                            flag |= kSCANF_LengthChar;
+                            c++;
+                        }
+                        else
+                        {
+                            flag |= kSCANF_LengthShortInt;
+                        }
+                        c++;
+                        break;
+                    case 'l':
+                        if (flag & kSCANF_LengthMask)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+
+                        if (c[1] == 'l')
+                        {
+                            flag |= kSCANF_LengthLongLongInt;
+                            c++;
+                        }
+                        else
+                        {
+                            flag |= kSCANF_LengthLongInt;
+                        }
+                        c++;
+                        break;
+#endif /* SCANF_ADVANCED_ENABLE */
+#if SCANF_FLOAT_ENABLE
+                    case 'L':
+                        if (flag & kSCANF_LengthMask)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+                        flag |= kSCANF_LengthLongLongDouble;
+                        c++;
+                        break;
+#endif /* SCANF_FLOAT_ENABLE */
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                        if (field_width)
+                        {
+                            /* Match failure. */
+                            return nassigned;
+                        }
+                        do
+                        {
+                            field_width = field_width * 10 + *c - '0';
+                            c++;
+                        } while ((*c >= '0') && (*c <= '9'));
+                        break;
+                    case 'd':
+                        base = 10;
+                        flag |= kSCANF_TypeSinged;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+                    case 'u':
+                        base = 10;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+                    case 'o':
+                        base = 8;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+                    case 'x':
+                    case 'X':
+                        base = 16;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+                    case 'i':
+                        base = 0;
+                        flag |= kSCANF_DestInt;
+                        c++;
+                        break;
+#if SCANF_FLOAT_ENABLE
+                    case 'a':
+                    case 'A':
+                    case 'e':
+                    case 'E':
+                    case 'f':
+                    case 'F':
+                    case 'g':
+                    case 'G':
+                        flag |= kSCANF_DestFloat;
+                        c++;
+                        break;
+#endif /* SCANF_FLOAT_ENABLE */
+                    case 'c':
+                        flag |= kSCANF_DestChar;
+                        if (!field_width)
+                        {
+                            field_width = 1;
+                        }
+                        c++;
+                        break;
+                    case 's':
+                        flag |= kSCANF_DestString;
+                        c++;
+                        break;
+                    default:
+                        return nassigned;
+                }
+            }
+
+            if (!(flag & kSCANF_DestMask))
+            {
+                /* Format strings are exhausted. */
+                return nassigned;
+            }
+
+            if (!field_width)
+            {
+                /* Large than length of a line. */
+                field_width = 99;
+            }
+
+            /* Matching strings in input streams and assign to argument. */
+            switch (flag & kSCANF_DestMask)
+            {
+                case kSCANF_DestChar:
+                    s   = (const char *)p;
+                    buf = va_arg(args_ptr, char *);
+                    while ((field_width--) && (*p))
+                    {
+                        if (!(flag & kSCANF_Suppress))
+                        {
+                            *buf++ = *p++;
+                        }
+                        else
+                        {
+                            p++;
+                        }
+                        n_decode++;
+                    }
+
+                    if ((!(flag & kSCANF_Suppress)) && (s != p))
+                    {
+                        nassigned++;
+                    }
+                    break;
+                case kSCANF_DestString:
+                    n_decode += ScanIgnoreWhiteSpace(&p);
+                    s   = p;
+                    buf = va_arg(args_ptr, char *);
+                    while ((field_width--) && (*p != '\0') && (*p != ' ') && (*p != '\t') && (*p != '\n') &&
+                           (*p != '\r') && (*p != '\v') && (*p != '\f'))
+                    {
+                        if (flag & kSCANF_Suppress)
+                        {
+                            p++;
+                        }
+                        else
+                        {
+                            *buf++ = *p++;
+                        }
+                        n_decode++;
+                    }
+
+                    if ((!(flag & kSCANF_Suppress)) && (s != p))
+                    {
+                        /* Add NULL to end of string. */
+                        *buf = '\0';
+                        nassigned++;
+                    }
+                    break;
+                case kSCANF_DestInt:
+                    n_decode += ScanIgnoreWhiteSpace(&p);
+                    s   = p;
+                    val = 0;
+                    if ((base == 0) || (base == 16))
+                    {
+                        if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X')))
+                        {
+                            base = 16;
+                            if (field_width >= 1)
+                            {
+                                p += 2;
+                                n_decode += 2;
+                                field_width -= 2;
+                            }
+                        }
+                    }
+
+                    if (base == 0)
+                    {
+                        if (s[0] == '0')
+                        {
+                            base = 8;
+                        }
+                        else
+                        {
+                            base = 10;
+                        }
+                    }
+
+                    neg = 1;
+                    switch (*p)
+                    {
+                        case '-':
+                            neg = -1;
+                            n_decode++;
+                            p++;
+                            field_width--;
+                            break;
+                        case '+':
+                            neg = 1;
+                            n_decode++;
+                            p++;
+                            field_width--;
+                            break;
+                        default:
+                            break;
+                    }
+
+                    while ((*p) && (field_width--))
+                    {
+                        if ((*p <= '9') && (*p >= '0'))
+                        {
+                            temp = *p - '0';
+                        }
+                        else if ((*p <= 'f') && (*p >= 'a'))
+                        {
+                            temp = *p - 'a' + 10;
+                        }
+                        else if ((*p <= 'F') && (*p >= 'A'))
+                        {
+                            temp = *p - 'A' + 10;
+                        }
+                        else
+                        {
+                            temp = base;
+                        }
+
+                        if (temp >= base)
+                        {
+                            break;
+                        }
+                        else
+                        {
+                            val = base * val + temp;
+                        }
+                        p++;
+                        n_decode++;
+                    }
+                    val *= neg;
+                    if (!(flag & kSCANF_Suppress))
+                    {
+#if SCANF_ADVANCED_ENABLE
+                        switch (flag & kSCANF_LengthMask)
+                        {
+                            case kSCANF_LengthChar:
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed char *) = (signed char)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned char *) = (unsigned char)val;
+                                }
+                                break;
+                            case kSCANF_LengthShortInt:
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed short *) = (signed short)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned short *) = (unsigned short)val;
+                                }
+                                break;
+                            case kSCANF_LengthLongInt:
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed long int *) = (signed long int)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned long int *) = (unsigned long int)val;
+                                }
+                                break;
+                            case kSCANF_LengthLongLongInt:
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed long long int *) = (signed long long int)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned long long int *) = (unsigned long long int)val;
+                                }
+                                break;
+                            default:
+                                /* The default type is the type int. */
+                                if (flag & kSCANF_TypeSinged)
+                                {
+                                    *va_arg(args_ptr, signed int *) = (signed int)val;
+                                }
+                                else
+                                {
+                                    *va_arg(args_ptr, unsigned int *) = (unsigned int)val;
+                                }
+                                break;
+                        }
+#else
+                        /* The default type is the type int. */
+                        if (flag & kSCANF_TypeSinged)
+                        {
+                            *va_arg(args_ptr, signed int *) = (signed int)val;
+                        }
+                        else
+                        {
+                            *va_arg(args_ptr, unsigned int *) = (unsigned int)val;
+                        }
+#endif /* SCANF_ADVANCED_ENABLE */
+                        nassigned++;
+                    }
+                    break;
+#if SCANF_FLOAT_ENABLE
+                case kSCANF_DestFloat:
+                    n_decode += ScanIgnoreWhiteSpace(&p);
+                    fnum = strtod(p, (char **)&s);
+
+                    if ((fnum >= HUGE_VAL) || (fnum <= -HUGE_VAL))
+                    {
+                        break;
+                    }
+
+                    n_decode += (int)(s) - (int)(p);
+                    p = s;
+                    if (!(flag & kSCANF_Suppress))
+                    {
+                        if (flag & kSCANF_LengthLongLongDouble)
+                        {
+                            *va_arg(args_ptr, double *) = fnum;
+                        }
+                        else
+                        {
+                            *va_arg(args_ptr, float *) = (float)fnum;
+                        }
+                        nassigned++;
+                    }
+                    break;
+#endif /* SCANF_FLOAT_ENABLE */
+                default:
+                    return nassigned;
+            }
+        }
+    }
+    return nassigned;
+}
diff --git a/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str/fsl_str.h b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str/fsl_str.h
new file mode 100755
index 0000000..bf7adcc
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/devices/K32W061/utilities/str/fsl_str.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _FSL_STR_H
+#define _FSL_STR_H
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup debugconsole
+ * @{
+ */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @brief A function pointer which is used when format printf log.
+ */
+typedef void (*printfCb)(char *buf, int32_t *indicator, char val, int len);
+
+/*!
+ * @brief This function outputs its parameters according to a formatted string.
+ *
+ * @note I/O is performed by calling given function pointer using following
+ * (*func_ptr)(c);
+ *
+ * @param[in] fmt   Format string for printf.
+ * @param[in] ap  Arguments to printf.
+ * @param[in] buf  pointer to the buffer
+ * @param cb print callbck function pointer
+ *
+ * @return Number of characters to be print
+ */
+int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb);
+
+/*!
+ * @brief Converts an input line of ASCII characters based upon a provided
+ * string format.
+ *
+ * @param[in] line_ptr The input line of ASCII data.
+ * @param[in] format   Format first points to the format string.
+ * @param[in] args_ptr The list of parameters.
+ *
+ * @return Number of input items converted and assigned.
+ * @retval IO_EOF When line_ptr is empty string "".
+ */
+int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_STR_H */
diff --git a/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/aes_alt.c b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/aes_alt.c
new file mode 100755
index 0000000..31acea7
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/aes_alt.c
@@ -0,0 +1,1531 @@
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_AES_C)
+
+#include <string.h>
+
+#include "mbedtls/aes.h"
+#include "mbedtls/platform_util.h"
+#if defined(MBEDTLS_PADLOCK_C)
+#include "mbedtls/padlock.h"
+#endif
+#if defined(MBEDTLS_AESNI_C)
+#include "mbedtls/aesni.h"
+#endif
+
+#if defined(MBEDTLS_AES_ALT)
+/* clang-format off */
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ]       )             \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE(n,b,i)                                    \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
+    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
+}
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) &&                      \
+    ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
+static int aes_padlock_ace = -1;
+#endif
+
+#if defined(MBEDTLS_AES_ROM_TABLES)
+#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+/*
+ * Forward S-box
+ */
+static const unsigned char FSb[256] =
+{
+    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+    0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+    0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+    0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+    0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+    0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+    0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+    0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+    0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+    0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+    0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+    0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+    0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+    0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+    0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+    0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+    0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+    0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+    0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+    0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+    0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+    0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+    0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+    0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+    0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+    0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+    0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+    0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+    0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+    0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+    0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+    0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+};
+
+/*
+ * Forward tables
+ */
+#define FT \
+\
+    V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
+    V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
+    V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
+    V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
+    V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
+    V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
+    V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
+    V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
+    V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
+    V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
+    V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
+    V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
+    V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
+    V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
+    V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
+    V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
+    V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
+    V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
+    V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
+    V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
+    V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
+    V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
+    V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
+    V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
+    V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
+    V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
+    V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
+    V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
+    V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
+    V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
+    V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
+    V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
+    V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
+    V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
+    V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
+    V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
+    V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
+    V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
+    V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
+    V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
+    V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
+    V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
+    V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
+    V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
+    V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
+    V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
+    V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
+    V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
+    V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
+    V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
+    V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
+    V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
+    V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
+    V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
+    V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
+    V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
+    V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
+    V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
+    V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
+    V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
+    V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
+    V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
+    V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
+    V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t FT0[256] = { FT };
+#undef V
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t FT1[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t FT2[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t FT3[256] = { FT };
+#undef V
+
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+#undef FT
+
+/*
+ * Reverse S-box
+ */
+static const unsigned char RSb[256] =
+{
+    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+    0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+    0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+    0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+    0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+    0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+    0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+    0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+    0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+    0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+    0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+    0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+    0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+    0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+    0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+    0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+    0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+};
+
+/*
+ * Reverse tables
+ */
+#define RT \
+\
+    V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
+    V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
+    V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
+    V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
+    V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
+    V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
+    V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
+    V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
+    V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
+    V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
+    V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
+    V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
+    V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
+    V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
+    V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
+    V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
+    V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
+    V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
+    V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
+    V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
+    V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
+    V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
+    V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
+    V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
+    V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
+    V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
+    V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
+    V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
+    V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
+    V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
+    V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
+    V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
+    V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
+    V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
+    V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
+    V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
+    V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
+    V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
+    V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
+    V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
+    V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
+    V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
+    V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
+    V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
+    V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
+    V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
+    V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
+    V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
+    V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
+    V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
+    V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
+    V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
+    V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
+    V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
+    V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
+    V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
+    V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
+    V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
+    V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
+    V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
+    V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
+    V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
+    V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
+    V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t RT0[256] = { RT };
+#undef V
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t RT1[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t RT2[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t RT3[256] = { RT };
+#undef V
+
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+#undef RT
+
+/*
+ * Round constants
+ */
+static const uint32_t RCON[10] =
+{
+    0x00000001, 0x00000002, 0x00000004, 0x00000008,
+    0x00000010, 0x00000020, 0x00000040, 0x00000080,
+    0x0000001B, 0x00000036
+};
+
+#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */
+#else /* MBEDTLS_AES_ROM_TABLES */
+
+#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+
+/*
+ * Forward S-box & tables
+ */
+static unsigned char FSb[256];
+static uint32_t FT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+static uint32_t FT1[256];
+static uint32_t FT2[256];
+static uint32_t FT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+/*
+ * Reverse S-box & tables
+ */
+static unsigned char RSb[256];
+static uint32_t RT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+static uint32_t RT1[256];
+static uint32_t RT2[256];
+static uint32_t RT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+/*
+ * Round constants
+ */
+static uint32_t RCON[10];
+
+/*
+ * Tables generation code
+ */
+#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
+#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
+#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
+
+static int aes_init_done = 0;
+
+static void aes_gen_tables( void )
+{
+    int i, x, y, z;
+    int pow[256];
+    int log[256];
+
+    /*
+     * compute pow and log tables over GF(2^8)
+     */
+    for( i = 0, x = 1; i < 256; i++ )
+    {
+        pow[i] = x;
+        log[x] = i;
+        x = ( x ^ XTIME( x ) ) & 0xFF;
+    }
+
+    /*
+     * calculate the round constants
+     */
+    for( i = 0, x = 1; i < 10; i++ )
+    {
+        RCON[i] = (uint32_t) x;
+        x = XTIME( x ) & 0xFF;
+    }
+
+    /*
+     * generate the forward and reverse S-boxes
+     */
+    FSb[0x00] = 0x63;
+    RSb[0x63] = 0x00;
+
+    for( i = 1; i < 256; i++ )
+    {
+        x = pow[255 - log[i]];
+
+        y  = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y ^ 0x63;
+
+        FSb[i] = (unsigned char) x;
+        RSb[x] = (unsigned char) i;
+    }
+
+    /*
+     * generate the forward and reverse tables
+     */
+    for( i = 0; i < 256; i++ )
+    {
+        x = FSb[i];
+        y = XTIME( x ) & 0xFF;
+        z =  ( y ^ x ) & 0xFF;
+
+        FT0[i] = ( (uint32_t) y       ) ^
+                 ( (uint32_t) x <<  8 ) ^
+                 ( (uint32_t) x << 16 ) ^
+                 ( (uint32_t) z << 24 );
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+        FT1[i] = ROTL8( FT0[i] );
+        FT2[i] = ROTL8( FT1[i] );
+        FT3[i] = ROTL8( FT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+        x = RSb[i];
+
+        RT0[i] = ( (uint32_t) MUL( 0x0E, x )       ) ^
+                 ( (uint32_t) MUL( 0x09, x ) <<  8 ) ^
+                 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
+                 ( (uint32_t) MUL( 0x0B, x ) << 24 );
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+        RT1[i] = ROTL8( RT0[i] );
+        RT2[i] = ROTL8( RT1[i] );
+        RT3[i] = ROTL8( RT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+    }
+}
+
+#undef ROTL8
+#endif /*!MBEDTLS_AES_SETKEY_ENC_ALT*/
+#endif /* MBEDTLS_AES_ROM_TABLES */
+
+#if defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define ROTL8(x)  ( (uint32_t)( ( x ) <<  8 ) + (uint32_t)( ( x ) >> 24 ) )
+#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
+#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >>  8 ) )
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) ROTL8(  RT0[idx] )
+#define AES_RT2(idx) ROTL16( RT0[idx] )
+#define AES_RT3(idx) ROTL24( RT0[idx] )
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) ROTL8(  FT0[idx] )
+#define AES_FT2(idx) ROTL16( FT0[idx] )
+#define AES_FT3(idx) ROTL24( FT0[idx] )
+
+#else /* MBEDTLS_AES_FEWER_TABLES */
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) RT1[idx]
+#define AES_RT2(idx) RT2[idx]
+#define AES_RT3(idx) RT3[idx]
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) FT1[idx]
+#define AES_FT2(idx) FT2[idx]
+#define AES_FT3(idx) FT3[idx]
+
+#endif /* MBEDTLS_AES_FEWER_TABLES */
+
+void mbedtls_aes_init( mbedtls_aes_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_aes_context ) );
+}
+
+void mbedtls_aes_free( mbedtls_aes_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
+{
+    mbedtls_aes_init( &ctx->crypt );
+    mbedtls_aes_init( &ctx->tweak );
+}
+
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
+{
+    mbedtls_aes_free( &ctx->crypt );
+    mbedtls_aes_free( &ctx->tweak );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/*
+ * AES key schedule (encryption)
+ */
+#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
+                    unsigned int keybits )
+{
+    unsigned int i;
+    uint32_t *RK;
+
+#if !defined(MBEDTLS_AES_ROM_TABLES)
+    if( aes_init_done == 0 )
+    {
+        aes_gen_tables();
+        aes_init_done = 1;
+
+    }
+#endif
+
+    switch( keybits )
+    {
+        case 128: ctx->nr = 10; break;
+        case 192: ctx->nr = 12; break;
+        case 256: ctx->nr = 14; break;
+        default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+    }
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
+    if( aes_padlock_ace == -1 )
+        aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
+
+    if( aes_padlock_ace )
+        ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
+    else
+#endif
+    ctx->rk = RK = ctx->buf;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+        return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
+#endif
+
+    for( i = 0; i < ( keybits >> 5 ); i++ )
+    {
+        GET_UINT32_LE( RK[i], key, i << 2 );
+    }
+
+    switch( ctx->nr )
+    {
+        case 10:
+
+            for( i = 0; i < 10; i++, RK += 4 )
+            {
+                RK[4]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[3] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[3]       ) & 0xFF ] << 24 );
+
+                RK[5]  = RK[1] ^ RK[4];
+                RK[6]  = RK[2] ^ RK[5];
+                RK[7]  = RK[3] ^ RK[6];
+            }
+            break;
+
+        case 12:
+
+            for( i = 0; i < 8; i++, RK += 6 )
+            {
+                RK[6]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[5] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[5]       ) & 0xFF ] << 24 );
+
+                RK[7]  = RK[1] ^ RK[6];
+                RK[8]  = RK[2] ^ RK[7];
+                RK[9]  = RK[3] ^ RK[8];
+                RK[10] = RK[4] ^ RK[9];
+                RK[11] = RK[5] ^ RK[10];
+            }
+            break;
+
+        case 14:
+
+            for( i = 0; i < 7; i++, RK += 8 )
+            {
+                RK[8]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[7] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[7]       ) & 0xFF ] << 24 );
+
+                RK[9]  = RK[1] ^ RK[8];
+                RK[10] = RK[2] ^ RK[9];
+                RK[11] = RK[3] ^ RK[10];
+
+                RK[12] = RK[4] ^
+                ( (uint32_t) FSb[ ( RK[11]       ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[11] >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+
+                RK[13] = RK[5] ^ RK[12];
+                RK[14] = RK[6] ^ RK[13];
+                RK[15] = RK[7] ^ RK[14];
+            }
+            break;
+    }
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
+
+/*
+ * AES key schedule (decryption)
+ */
+#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
+int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
+                    unsigned int keybits )
+{
+    int i, j, ret;
+    mbedtls_aes_context cty;
+    uint32_t *RK;
+    uint32_t *SK;
+
+    mbedtls_aes_init( &cty );
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
+    if( aes_padlock_ace == -1 )
+        aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
+
+    if( aes_padlock_ace )
+        ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
+    else
+#endif
+    ctx->rk = RK = ctx->buf;
+
+    /* Also checks keybits */
+    if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
+        goto exit;
+
+    ctx->nr = cty.nr;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+    {
+        mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
+                           (const unsigned char *) cty.rk, ctx->nr );
+        goto exit;
+    }
+#endif
+
+    SK = cty.rk + cty.nr * 4;
+
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+
+    for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
+    {
+        for( j = 0; j < 4; j++, SK++ )
+        {
+            *RK++ = AES_RT0( FSb[ ( *SK       ) & 0xFF ] ) ^
+                    AES_RT1( FSb[ ( *SK >>  8 ) & 0xFF ] ) ^
+                    AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
+                    AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
+        }
+    }
+
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+
+exit:
+    mbedtls_aes_free( &cty );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
+                                        unsigned int keybits,
+                                        const unsigned char **key1,
+                                        unsigned int *key1bits,
+                                        const unsigned char **key2,
+                                        unsigned int *key2bits )
+{
+    const unsigned int half_keybits = keybits / 2;
+    const unsigned int half_keybytes = half_keybits / 8;
+
+    switch( keybits )
+    {
+        case 256: break;
+        case 512: break;
+        default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+    }
+
+    *key1bits = half_keybits;
+    *key2bits = half_keybits;
+    *key1 = &key[0];
+    *key2 = &key[half_keybytes];
+
+    return 0;
+}
+
+int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits)
+{
+    int ret;
+    const unsigned char *key1, *key2;
+    unsigned int key1bits, key2bits;
+
+    ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
+                                       &key2, &key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set the tweak key. Always set tweak key for the encryption mode. */
+    ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set crypt key for encryption. */
+    return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
+}
+
+int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits)
+{
+    int ret;
+    const unsigned char *key1, *key2;
+    unsigned int key1bits, key2bits;
+
+    ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
+                                       &key2, &key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set the tweak key. Always set tweak key for encryption. */
+    ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set crypt key for decryption. */
+    return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
+
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)         \
+{                                                   \
+    X0 = *RK++ ^ AES_FT0( ( Y0       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y1 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y3 >> 24 ) & 0xFF );    \
+                                                    \
+    X1 = *RK++ ^ AES_FT0( ( Y1       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y2 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y0 >> 24 ) & 0xFF );    \
+                                                    \
+    X2 = *RK++ ^ AES_FT0( ( Y2       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y3 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y1 >> 24 ) & 0xFF );    \
+                                                    \
+    X3 = *RK++ ^ AES_FT0( ( Y3       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y0 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y2 >> 24 ) & 0xFF );    \
+}
+
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)         \
+{                                                   \
+    X0 = *RK++ ^ AES_RT0( ( Y0       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y3 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y1 >> 24 ) & 0xFF );    \
+                                                    \
+    X1 = *RK++ ^ AES_RT0( ( Y1       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y0 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y2 >> 24 ) & 0xFF );    \
+                                                    \
+    X2 = *RK++ ^ AES_RT0( ( Y2       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y1 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y3 >> 24 ) & 0xFF );    \
+                                                    \
+    X3 = *RK++ ^ AES_RT0( ( Y3       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y2 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y0 >> 24 ) & 0xFF );    \
+}
+
+/*
+ * AES-ECB block encryption
+ */
+#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
+int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] )
+{
+    int i;
+    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+    RK = ctx->rk;
+
+    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
+    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
+    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
+    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+    for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+    {
+        AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+        AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+    }
+
+    AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+    X0 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y0       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+    X1 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y1       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+    X2 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y2       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+    X3 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y3       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+    PUT_UINT32_LE( X0, output,  0 );
+    PUT_UINT32_LE( X1, output,  4 );
+    PUT_UINT32_LE( X2, output,  8 );
+    PUT_UINT32_LE( X3, output, 12 );
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
+                          const unsigned char input[16],
+                          unsigned char output[16] )
+{
+    mbedtls_internal_aes_encrypt( ctx, input, output );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * AES-ECB block decryption
+ */
+#if !defined(MBEDTLS_AES_DECRYPT_ALT)
+int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] )
+{
+    int i;
+    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+    RK = ctx->rk;
+
+    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
+    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
+    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
+    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+    for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+    {
+        AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+        AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+    }
+
+    AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+    X0 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y0       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+    X1 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y1       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+    X2 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y2       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+    X3 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y3       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+    PUT_UINT32_LE( X0, output,  0 );
+    PUT_UINT32_LE( X1, output,  4 );
+    PUT_UINT32_LE( X2, output,  8 );
+    PUT_UINT32_LE( X3, output, 12 );
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_DECRYPT_ALT */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
+                          const unsigned char input[16],
+                          unsigned char output[16] )
+{
+    mbedtls_internal_aes_decrypt( ctx, input, output );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * AES-ECB block encryption/decryption
+ */
+int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
+                    int mode,
+                    const unsigned char input[16],
+                    unsigned char output[16] )
+{
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+        return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
+    if( aes_padlock_ace )
+    {
+        if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
+            return( 0 );
+
+        // If padlock data misaligned, we just fall back to
+        // unaccelerated mode
+        //
+    }
+#endif
+
+    if( mode == MBEDTLS_AES_ENCRYPT )
+        return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
+    else
+        return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+#if !defined(MBEDTLS_AES_CRYPT_CBC_ALT)
+int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[16],
+                    const unsigned char *input,
+                    unsigned char *output )
+{
+    int i;
+    unsigned char temp[16];
+
+    if( length % 16 )
+        return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
+    if( aes_padlock_ace )
+    {
+        if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
+            return( 0 );
+
+        // If padlock data misaligned, we just fall back to
+        // unaccelerated mode
+        //
+    }
+#endif
+
+    if( mode == MBEDTLS_AES_DECRYPT )
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, 16 );
+            mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+
+            for( i = 0; i < 16; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+    else
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < 16; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            memcpy( iv, output, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_CRYPT_CBC_ALT */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+
+/* Endianess with 64 bits values */
+#ifndef GET_UINT64_LE
+#define GET_UINT64_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint64_t) (b)[(i) + 7] << 56 )             \
+        | ( (uint64_t) (b)[(i) + 6] << 48 )             \
+        | ( (uint64_t) (b)[(i) + 5] << 40 )             \
+        | ( (uint64_t) (b)[(i) + 4] << 32 )             \
+        | ( (uint64_t) (b)[(i) + 3] << 24 )             \
+        | ( (uint64_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint64_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint64_t) (b)[(i)    ]       );            \
+}
+#endif
+
+#ifndef PUT_UINT64_LE
+#define PUT_UINT64_LE(n,b,i)                            \
+{                                                       \
+    (b)[(i) + 7] = (unsigned char) ( (n) >> 56 );       \
+    (b)[(i) + 6] = (unsigned char) ( (n) >> 48 );       \
+    (b)[(i) + 5] = (unsigned char) ( (n) >> 40 );       \
+    (b)[(i) + 4] = (unsigned char) ( (n) >> 32 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i)    ] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+typedef unsigned char mbedtls_be128[16];
+
+/*
+ * GF(2^128) multiplication function
+ *
+ * This function multiplies a field element by x in the polynomial field
+ * representation. It uses 64-bit word operations to gain speed but compensates
+ * for machine endianess and hence works correctly on both big and little
+ * endian machines.
+ */
+static void mbedtls_gf128mul_x_ble( unsigned char r[16],
+                                    const unsigned char x[16] )
+{
+    uint64_t a, b, ra, rb;
+
+    GET_UINT64_LE( a, x, 0 );
+    GET_UINT64_LE( b, x, 8 );
+
+    ra = ( a << 1 )  ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
+    rb = ( a >> 63 ) | ( b << 1 );
+
+    PUT_UINT64_LE( ra, r, 0 );
+    PUT_UINT64_LE( rb, r, 8 );
+}
+
+/*
+ * AES-XTS buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
+                           int mode,
+                           size_t length,
+                           const unsigned char data_unit[16],
+                           const unsigned char *input,
+                           unsigned char *output )
+{
+    int ret;
+    size_t blocks = length / 16;
+    size_t leftover = length % 16;
+    unsigned char tweak[16];
+    unsigned char prev_tweak[16];
+    unsigned char tmp[16];
+
+    /* Sectors must be at least 16 bytes. */
+    if( length < 16 )
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+    /* NIST SP 80-38E disallows data units larger than 2**20 blocks. */
+    if( length > ( 1 << 20 ) * 16 )
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+    /* Compute the tweak. */
+    ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
+                                 data_unit, tweak );
+    if( ret != 0 )
+        return( ret );
+
+    while( blocks-- )
+    {
+        size_t i;
+
+        if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
+        {
+            /* We are on the last block in a decrypt operation that has
+             * leftover bytes, so we need to use the next tweak for this block,
+             * and this tweak for the lefover bytes. Save the current tweak for
+             * the leftovers and then update the current tweak for use on this,
+             * the last full block. */
+            memcpy( prev_tweak, tweak, sizeof( tweak ) );
+            mbedtls_gf128mul_x_ble( tweak, tweak );
+        }
+
+        for( i = 0; i < 16; i++ )
+            tmp[i] = input[i] ^ tweak[i];
+
+        ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
+        if( ret != 0 )
+            return( ret );
+
+        for( i = 0; i < 16; i++ )
+            output[i] = tmp[i] ^ tweak[i];
+
+        /* Update the tweak for the next block. */
+        mbedtls_gf128mul_x_ble( tweak, tweak );
+
+        output += 16;
+        input += 16;
+    }
+
+    if( leftover )
+    {
+        /* If we are on the leftover bytes in a decrypt operation, we need to
+         * use the previous tweak for these bytes (as saved in prev_tweak). */
+        unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
+
+        /* We are now on the final part of the data unit, which doesn't divide
+         * evenly by 16. It's time for ciphertext stealing. */
+        size_t i;
+        unsigned char *prev_output = output - 16;
+
+        /* Copy ciphertext bytes from the previous block to our output for each
+         * byte of cyphertext we won't steal. At the same time, copy the
+         * remainder of the input for this final round (since the loop bounds
+         * are the same). */
+        for( i = 0; i < leftover; i++ )
+        {
+            output[i] = prev_output[i];
+            tmp[i] = input[i] ^ t[i];
+        }
+
+        /* Copy ciphertext bytes from the previous block for input in this
+         * round. */
+        for( ; i < 16; i++ )
+            tmp[i] = prev_output[i] ^ t[i];
+
+        ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
+        if( ret != 0 )
+            return ret;
+
+        /* Write the result back to the previous block, overriding the previous
+         * output we copied. */
+        for( i = 0; i < 16; i++ )
+            prev_output[i] = tmp[i] ^ t[i];
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+#if !defined(MBEDTLS_AES_CRYPT_CFB_ALT)
+int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c;
+    size_t n = *iv_off;
+
+    if( mode == MBEDTLS_AES_DECRYPT )
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+            c = *input++;
+            *output++ = (unsigned char)( c ^ iv[n] );
+            iv[n] = (unsigned char) c;
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+    else
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+
+    *iv_off = n;
+
+    return( 0 );
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    unsigned char c;
+    unsigned char ov[17];
+
+    while( length-- )
+    {
+        memcpy( ov, iv, 16 );
+        mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+            ov[16] = *input;
+
+        c = *output++ = (unsigned char)( iv[0] ^ *input++ );
+
+        if( mode == MBEDTLS_AES_ENCRYPT )
+            ov[16] = c;
+
+        memcpy( iv, ov + 1, 16 );
+    }
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_CRYPT_CFB_ALT */
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-OFB (Output Feedback Mode) buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+                           size_t length,
+                           size_t *iv_off,
+                           unsigned char iv[16],
+                           const unsigned char *input,
+                           unsigned char *output )
+{
+    int ret = 0;
+    size_t n = *iv_off;
+
+    while( length-- )
+    {
+        if( n == 0 )
+        {
+            ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            if( ret != 0 )
+                goto exit;
+        }
+        *output++ =  *input++ ^ iv[n];
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *iv_off = n;
+
+exit:
+    return( ret );
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+#if !defined(MBEDTLS_AES_CRYPT_CTR_ALT)
+int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[16],
+                       unsigned char stream_block[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c, i;
+    size_t n = *nc_off;
+
+    if ( n > 0x0F )
+        return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
+    while( length-- )
+    {
+        if( n == 0 ) {
+            mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+
+            for( i = 16; i > 0; i-- )
+                if( ++nonce_counter[i - 1] != 0 )
+                    break;
+        }
+        c = *input++;
+        *output++ = (unsigned char)( c ^ stream_block[n] );
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *nc_off = n;
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_CRYPT_CTR_ALT */
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+/* clang-format on */
+
+/*          HASHCRYPT AES          */
+#if defined(MBEDTLS_FREESCALE_HASHCRYPT_AES)
+
+/*
+ * AES key schedule (encryption)
+ */
+int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
+{
+    size_t key_size;
+
+    switch (keybits)
+    {
+        case 128:
+            key_size = 16;
+            break;
+        case 192:
+            key_size = 24;
+            break;
+        case 256:
+            key_size = 32;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+    /* secret bus is marked as key address == HASHCRYPT base */
+    if ((uint32_t)key == (uint32_t)HASHCRYPT)
+    {
+        ctx->keyType = kHASHCRYPT_SecretKey;
+    }
+    else
+    {
+        ctx->keyType = kHASHCRYPT_UserKey;
+    }
+    if (kStatus_Success != HASHCRYPT_AES_SetKey(HASHCRYPT, ctx, key, key_size))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return (0);
+}
+
+/*
+ * AES key schedule (decryption)
+ */
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
+{
+    size_t key_size;
+
+    switch (keybits)
+    {
+        case 128:
+            key_size = 16;
+            break;
+        case 192:
+            key_size = 24;
+            break;
+        case 256:
+            key_size = 32;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+    /* secret bus is marked as key address == HASHCRYPT base */
+    if ((uint32_t)key == (uint32_t)HASHCRYPT)
+    {
+        ctx->keyType = kHASHCRYPT_SecretKey;
+    }
+    else
+    {
+        ctx->keyType = kHASHCRYPT_UserKey;
+    }
+    if (kStatus_Success != HASHCRYPT_AES_SetKey(HASHCRYPT, ctx, key, key_size))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return 0;
+}
+
+/*
+ * AES-ECB block encryption
+ */
+int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16])
+{
+    if (kStatus_Success != HASHCRYPT_AES_EncryptEcb(HASHCRYPT, ctx, input, output, 16))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return (0);
+}
+
+/*
+ * AES-ECB block decryption
+ */
+int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16])
+{
+    if (kStatus_Success != HASHCRYPT_AES_DecryptEcb(HASHCRYPT, ctx, input, output, 16))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return (0);
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        if (kStatus_Success != HASHCRYPT_AES_DecryptCbc(HASHCRYPT, ctx, input, output, length, iv))
+        {
+            return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+        }
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        if (kStatus_Success != HASHCRYPT_AES_EncryptCbc(HASHCRYPT, ctx, input, output, length, iv))
+        {
+            return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+        }
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t length,
+                          size_t *nc_off,
+                          unsigned char nonce_counter[16],
+                          unsigned char stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    if (kStatus_Success !=
+        HASHCRYPT_AES_CryptCtr(HASHCRYPT, ctx, input, output, length, nonce_counter, stream_block, nc_off))
+    {
+        return (MBEDTLS_ERR_AES_HW_ACCEL_FAILED);
+    }
+
+    return (0);
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#endif /* MBEDTLS_FREESCALE_HASHCRYPT_AES */
+#endif /* MBEDTLS_AES_ALT */
+#endif /* MBEDTLS_AES_C */
diff --git a/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/aes_alt.h b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/aes_alt.h
new file mode 100755
index 0000000..af00028
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/aes_alt.h
@@ -0,0 +1,86 @@
+/**
+ * \file aes_alt.h
+ *
+ * \brief   This file contains alternate AES definitions and functions.
+ *
+ *          The Advanced Encryption Standard (AES) specifies a FIPS-approved
+ *          cryptographic algorithm that can be used to protect electronic
+ *          data.
+ *
+ *          The AES algorithm is a symmetric block cipher that can
+ *          encrypt and decrypt information. For more information, see
+ *          <em>FIPS Publication 197: Advanced Encryption Standard</em> and
+ *          <em>ISO/IEC 18033-2:2006: Information technology -- Security
+ *          techniques -- Encryption algorithms -- Part 2: Asymmetric
+ *          ciphers</em>.
+ *
+ *          The AES-XTS block mode is standardized by NIST SP 800-38E
+ *          <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
+ *          and described in detail by IEEE P1619
+ *          <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
+ */
+
+/*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ *  SPDX-License-Identifier: Apache-2.0
+ *  Copyright 2018 NXP. Not a Contribution
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_AES_ALT_H
+#define MBEDTLS_AES_ALT_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_AES_ALT)
+
+#if defined(MBEDTLS_FREESCALE_HASHCRYPT_AES)
+/**
+ * \brief          AES context structure
+ */
+#define mbedtls_aes_context hashcrypt_handle_t
+
+#else
+// Regular implementation
+//
+
+/**
+ * \brief The AES context-type definition.
+ */
+typedef struct
+{
+    int nr;                     /*!< The number of rounds. */
+    uint32_t *rk;               /*!< AES round keys. */
+    uint32_t buf[68];           /*!< Unaligned data buffer. This buffer can
+                                     hold 32 extra Bytes, which can be used for
+                                     one of the following purposes:
+                                     <ul><li>Alignment if VIA padlock is
+                                             used.</li>
+                                     <li>Simplifying key expansion in the 256-bit
+                                         case by generating an extra round key.
+                                         </li></ul> */
+}
+mbedtls_aes_context;
+#endif /* MBEDTLS_FREESCALE_HASHCRYPT_AES */
+
+#endif /* MBEDTLS_AES_ALT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aes_alt.h */
diff --git a/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c
new file mode 100755
index 0000000..ad9f0a2
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c
@@ -0,0 +1,4516 @@
+/*
+ * Copyright 2015-2016, Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "fsl_common.h"
+
+#if defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0)
+#include "fsl_ltc.h"
+#endif
+#if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0)
+#include "fsl_caam.h"
+#endif
+#if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)
+#include "fsl_cau3.h"
+#endif
+#if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0)
+#include "fsl_dcp.h"
+#endif
+#if defined(FSL_FEATURE_SOC_HASHCRYPT_COUNT) && (FSL_FEATURE_SOC_HASHCRYPT_COUNT > 0)
+#include "fsl_hashcrypt.h"
+#endif
+#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+#if defined CPU_JN518X
+    #include "fsl_rng.h"
+#else
+    #include "fsl_trng.h"
+#endif
+#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+#include "fsl_rnga.h"
+#elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0)
+#include "fsl_rng.h"
+#endif
+
+#define CLEAN_RETURN(value) \
+    {                       \
+        ret = value;        \
+        goto cleanup;       \
+    }
+
+/******************************************************************************/
+/*************************** CAAM *********************************************/
+/******************************************************************************/
+#if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM)
+static caam_handle_t s_caamHandle = {.jobRing = kCAAM_JobRing0};
+#endif
+
+/******************************************************************************/
+/*************************** CAU3 *********************************************/
+/******************************************************************************/
+#if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)
+static cau3_handle_t s_cau3Handle = {.taskDone = MBEDTLS_CAU3_COMPLETION_SIGNAL, .keySlot = kCAU3_KeySlot0};
+#endif
+
+/******************************************************************************/
+/**************************** DCP *********************************************/
+/******************************************************************************/
+#if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0)
+static dcp_handle_t s_dcpHandle = {.channel = kDCP_Channel0, .keySlot = kDCP_KeySlot0, .swapConfig = kDCP_NoSwap};
+#endif
+
+/******************************************************************************/
+/************************* Key slot management ********************************/
+/******************************************************************************/
+#if (defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)) || (defined(MBEDTLS_FREESCALE_DCP_AES))
+static const void *s_mbedtlsCtx[4] = {0};
+
+static void crypto_attach_ctx_to_key_slot(const void *ctx, uint8_t keySlot)
+{
+    s_mbedtlsCtx[keySlot] = ctx;
+}
+
+static void crypto_detach_ctx_from_key_slot(const void *ctx)
+{
+    for (int i = 0; i < 4; i++)
+    {
+        if (ctx == s_mbedtlsCtx[i])
+        {
+            s_mbedtlsCtx[i] = NULL;
+            break;
+        }
+    }
+}
+
+static bool crypto_key_is_loaded(const void *ctx)
+{
+    bool ret = false;
+    for (int i = 0; i < 4; i++)
+    {
+        if (ctx == s_mbedtlsCtx[i])
+        {
+            ret = true;
+            break;
+        }
+    }
+    return ret;
+}
+#endif
+
+#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT)
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize(void *v, size_t n)
+{
+    volatile unsigned char *p = v;
+    while (n--)
+        *p++ = 0;
+}
+#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT */
+
+/******************************************************************************/
+/******************** CRYPTO_InitHardware **************************************/
+/******************************************************************************/
+/*!
+ * @brief Application init for various Crypto blocks.
+ *
+ * This function is provided to be called by MCUXpresso SDK applications.
+ * It calls basic init for Crypto Hw acceleration and Hw entropy modules.
+ */
+void CRYPTO_InitHardware(void)
+{
+#if defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0)
+    /* Initialize LTC driver.
+     * This enables clocking and resets the module to a known state. */
+    LTC_Init(LTC0);
+#endif
+#if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM)
+    /* Initialize CAAM driver. */
+    caam_config_t caamConfig;
+
+    CAAM_GetDefaultConfig(&caamConfig);
+    caamConfig.jobRingInterface[0] = &s_jrif0;
+    caamConfig.jobRingInterface[1] = &s_jrif1;
+    CAAM_Init(CAAM, &caamConfig);
+#endif
+#if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)
+    /* Initialize CAU3 */
+    CAU3_Init(CAU3);
+#endif
+#if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0)
+    /* Initialize DCP */
+    dcp_config_t dcpConfig;
+
+    DCP_GetDefaultConfig(&dcpConfig);
+    DCP_Init(DCP, &dcpConfig);
+#endif
+#if defined(FSL_FEATURE_SOC_CASPER_COUNT) && (FSL_FEATURE_SOC_CASPER_COUNT > 0)
+    /* Initialize CASPER */
+    CASPER_Init(CASPER);
+#endif
+#if defined(FSL_FEATURE_SOC_HASHCRYPT_COUNT) && (FSL_FEATURE_SOC_HASHCRYPT_COUNT > 0)
+    /* Initialize HASHCRYPT */
+    HASHCRYPT_Init(HASHCRYPT);
+#endif
+    { /* Init RNG module.*/
+#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+#if defined CPU_JN518X
+    #if defined(RNG)
+    #define TRNG0 RNG
+    #endif
+#else
+    #if defined(TRNG)
+    #define TRNG0 TRNG
+    #endif
+#endif
+        trng_config_t trngConfig;
+
+        TRNG_GetDefaultConfig(&trngConfig);
+        /* Set sample mode of the TRNG ring oscillator to Von Neumann, for better random data.*/
+        /* Initialize TRNG */
+        TRNG_Init(TRNG0, &trngConfig);
+#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+        RNGA_Init(RNG);
+        RNGA_Seed(RNG, SIM->UIDL);
+#endif
+    }
+}
+
+/******************************************************************************/
+/*************************** DES **********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_DES_C)
+
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_MMCAU_DES) || \
+    defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+
+#include "mbedtls/des.h"
+
+#if defined(MBEDTLS_FREESCALE_MMCAU_DES)
+const unsigned char parityLookup[128] = {1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0,
+                                         0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1,
+                                         0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1,
+                                         1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+                                         0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
+#endif
+
+#if defined(MBEDTLS_FREESCALE_MMCAU_DES) || defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES)
+/*
+ * DES key schedule (56-bit, encryption)
+ */
+int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE);
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_ENCRYPT;
+
+    return (0);
+}
+
+/*
+ * DES key schedule (56-bit, decryption)
+ */
+int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE);
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_DECRYPT;
+
+    return (0);
+}
+#endif /* MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_CAAM_DES */
+
+/*
+ * Triple-DES key schedule (112-bit, encryption)
+ */
+int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 2);
+    memcpy(&ctx->sk[4], key, MBEDTLS_DES_KEY_SIZE); /* K3 = K1 */
+#if defined(MBEDTLS_FREESCALE_CAU3_DES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 2; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+    for (i = MBEDTLS_DES_KEY_SIZE * 2; i < MBEDTLS_DES_KEY_SIZE * 3; i++)
+    {
+        sk_b[i] = ((key[i - MBEDTLS_DES_KEY_SIZE * 2] & 0xFE) | parityLookup[key[i - MBEDTLS_DES_KEY_SIZE * 2] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_ENCRYPT;
+
+    return (0);
+}
+
+/*
+ * Triple-DES key schedule (112-bit, decryption)
+ */
+int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 2);
+    memcpy(&ctx->sk[4], key, MBEDTLS_DES_KEY_SIZE); /* K3 = K1 */
+#if defined(MBEDTLS_FREESCALE_CAU3_DES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 2; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+    for (i = MBEDTLS_DES_KEY_SIZE * 2; i < MBEDTLS_DES_KEY_SIZE * 3; i++)
+    {
+        sk_b[i] = ((key[i - MBEDTLS_DES_KEY_SIZE * 2] & 0xFE) | parityLookup[key[i - MBEDTLS_DES_KEY_SIZE * 2] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_DECRYPT;
+
+    return (0);
+}
+
+/*
+ * Triple-DES key schedule (168-bit, encryption)
+ */
+int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 3);
+#if defined(MBEDTLS_FREESCALE_CAU3_DES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 3; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_ENCRYPT;
+
+    return (0);
+}
+
+/*
+ * Triple-DES key schedule (168-bit, decryption)
+ */
+int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
+{
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES)
+    memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 3);
+#if defined(MBEDTLS_FREESCALE_CAU3_DES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    int i;
+    unsigned char *sk_b = (unsigned char *)ctx->sk;
+
+    /* fix key parity, if needed */
+    for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 3; i++)
+    {
+        sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]);
+    }
+#endif
+    ctx->mode = MBEDTLS_DES_DECRYPT;
+    return (0);
+}
+
+#if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_MMCAU_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES)
+/*
+ * DES-ECB block encryption/decryption
+ */
+int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx, const unsigned char input[8], unsigned char output[8])
+{
+    uint8_t *key = (uint8_t *)ctx->sk;
+#if defined(MBEDTLS_FREESCALE_LTC_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        LTC_DES_EncryptEcb(LTC_INSTANCE, input, output, 8, key);
+    }
+    else
+    {
+        LTC_DES_DecryptEcb(LTC_INSTANCE, input, output, 8, key);
+    }
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        MMCAU_DES_EncryptEcb(input, key, output);
+    }
+    else
+    {
+        MMCAU_DES_DecryptEcb(input, key, output);
+    }
+#elif defined(MBEDTLS_FREESCALE_CAAM_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAAM_DES_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key);
+    }
+    else
+    {
+        CAAM_DES_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key);
+    }
+#endif
+    return (0);
+}
+#endif /* MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_CAAM_DES */
+
+/*
+ * 3DES-ECB block encryption/decryption
+ */
+int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx, const unsigned char input[8], unsigned char output[8])
+{
+    uint8_t *key = (uint8_t *)ctx->sk;
+#if defined(MBEDTLS_FREESCALE_LTC_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        LTC_DES3_EncryptEcb(LTC_INSTANCE, input, output, 8, key, key + 8, key + 16);
+    }
+    else
+    {
+        LTC_DES3_DecryptEcb(LTC_INSTANCE, input, output, 8, key, key + 8, key + 16);
+    }
+#elif defined(MBEDTLS_FREESCALE_MMCAU_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        MMCAU_DES_EncryptEcb(input, key, output);
+        MMCAU_DES_DecryptEcb(output, key + 8, output);
+        MMCAU_DES_EncryptEcb(output, key + 16, output);
+    }
+    else
+    {
+        MMCAU_DES_DecryptEcb(input, key + 16, output);
+        MMCAU_DES_EncryptEcb(output, key + 8, output);
+        MMCAU_DES_DecryptEcb(output, key, output);
+    }
+#elif defined(MBEDTLS_FREESCALE_CAAM_DES)
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAAM_DES3_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key, key + 8, key + 16);
+    }
+    else
+    {
+        CAAM_DES3_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key, key + 8, key + 16);
+    }
+#elif defined(MBEDTLS_FREESCALE_CAU3_DES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        CAU3_TDES_SetKey(CAU3, &s_cau3Handle, key, 24);
+        crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot);
+    }
+
+    if (ctx->mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAU3_TDES_Encrypt(CAU3, &s_cau3Handle, input, output);
+    }
+    else
+    {
+        CAU3_TDES_Decrypt(CAU3, &s_cau3Handle, input, output);
+    }
+#endif
+    return (0);
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * DES-CBC buffer encryption/decryption
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_DES)
+int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[8],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    unsigned char temp[8];
+    uint8_t *key = (uint8_t *)ctx->sk;
+
+    if (length % 8)
+        return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_DES_ENCRYPT)
+    {
+        LTC_DES_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key);
+        memcpy(iv, output + length - 8, 8);
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        memcpy(temp, input + length - 8, 8);
+        LTC_DES_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key);
+        memcpy(iv, temp, 8);
+    }
+    return (0);
+}
+
+/*
+ * 3DES-CBC buffer encryption/decryption
+ */
+int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
+                           int mode,
+                           size_t length,
+                           unsigned char iv[8],
+                           const unsigned char *input,
+                           unsigned char *output)
+{
+    unsigned char temp[8];
+    uint8_t *key = (uint8_t *)ctx->sk;
+
+    if (length % 8)
+        return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_DES_ENCRYPT)
+    {
+        LTC_DES3_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key, key + 8, key + 16);
+        memcpy(iv, output + length - 8, 8);
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        memcpy(temp, input + length - 8, 8);
+        LTC_DES3_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key, key + 8, key + 16);
+        memcpy(iv, temp, 8);
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_DES)
+int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[8],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    unsigned char temp[8];
+    uint8_t *key = (uint8_t *)ctx->sk;
+
+    if (length % 8)
+        return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAAM_DES_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key);
+        memcpy(iv, output + length - 8, 8);
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        memcpy(temp, input + length - 8, 8);
+        CAAM_DES_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key);
+        memcpy(iv, temp, 8);
+    }
+    return (0);
+}
+
+/*
+ * 3DES-CBC buffer encryption/decryption
+ */
+int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
+                           int mode,
+                           size_t length,
+                           unsigned char iv[8],
+                           const unsigned char *input,
+                           unsigned char *output)
+{
+    unsigned char temp[8];
+    uint8_t *key = (uint8_t *)ctx->sk;
+
+    if (length % 8)
+        return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_DES_ENCRYPT)
+    {
+        CAAM_DES3_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, key + 8, key + 16);
+        memcpy(iv, output + length - 8, 8);
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        memcpy(temp, input + length - 8, 8);
+        CAAM_DES3_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, key + 8, key + 16);
+        memcpy(iv, temp, 8);
+    }
+
+    return (0);
+}
+
+#endif /* MBEDTLS_FREESCALE_LTC_DES */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#endif /*MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_CAAM_DES*/
+
+#endif /* MBEDTLS_DES_C */
+
+/******************************************************************************/
+/*************************** AES **********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_AES_C)
+
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_MMCAU_AES) || \
+    defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) ||  \
+    defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+
+#include "mbedtls/aes.h"
+
+/*
+ * AES key schedule (encryption)
+ */
+int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
+{
+    uint32_t *RK;
+    
+#ifdef MBEDTLS_AES_ALT_NO_192
+    if (keybits == 192u)
+    {
+        return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE);
+    }
+#endif
+
+#ifdef MBEDTLS_AES_ALT_NO_256
+    if (keybits == 256u)
+    {
+        return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE);
+    }
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) || \
+    defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+    const unsigned char *key_tmp = key;    
+    ctx->rk = RK = ctx->buf;
+    memcpy(RK, key_tmp, keybits / 8);
+
+#if defined(MBEDTLS_FREESCALE_CAU3_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif /* MBEDTLS_FREESCALE_CAU3_AES || MBEDTLS_FREESCALE_DCP_AES */
+
+    switch (keybits)
+    { /* Set keysize in bytes.*/
+        case 128:
+            ctx->nr = 16;
+            break;
+        case 192:
+            ctx->nr = 24;
+            break;
+        case 256:
+            ctx->nr = 32;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+#elif defined(MBEDTLS_FREESCALE_MMCAU_AES)
+    ctx->rk = RK = ctx->buf;
+
+    switch (keybits)
+    {
+        case 128:
+            ctx->nr = 10;
+            break;
+        case 192:
+            ctx->nr = 12;
+            break;
+        case 256:
+            ctx->nr = 14;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+
+    MMCAU_AES_SetKey(key, keybits / 8, (uint8_t *)RK);
+#endif
+
+    return (0);
+}
+
+/*
+ * AES key schedule (decryption)
+ */
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
+{
+    uint32_t *RK;
+    
+#ifdef MBEDTLS_AES_ALT_NO_192
+    if (keybits == 192u)
+    {
+        return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE);
+    }
+#endif
+
+#ifdef MBEDTLS_AES_ALT_NO_256
+    if (keybits == 256u)
+    {
+        return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE);
+    }
+#endif
+
+    ctx->rk = RK = ctx->buf;
+
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) || \
+    defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+    const unsigned char *key_tmp = key;
+    memcpy(RK, key_tmp, keybits / 8);
+
+#if defined(MBEDTLS_FREESCALE_CAU3_AES) || defined(MBEDTLS_FREESCALE_DCP_AES)
+    crypto_detach_ctx_from_key_slot(ctx);
+#endif /* MBEDTLS_FREESCALE_CAU3_AES || MBEDTLS_FREESCALE_DCP_AES */
+
+    switch (keybits)
+    {
+        case 128:
+            ctx->nr = 16;
+            break;
+        case 192:
+            ctx->nr = 24;
+            break;
+        case 256:
+            ctx->nr = 32;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+#elif defined(MBEDTLS_FREESCALE_MMCAU_AES)
+    ctx->rk = RK = ctx->buf;
+
+    switch (keybits)
+    {
+        case 128:
+            ctx->nr = 10;
+            break;
+        case 192:
+            ctx->nr = 12;
+            break;
+        case 256:
+            ctx->nr = 14;
+            break;
+        default:
+            return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
+    }
+
+    MMCAU_AES_SetKey(key, keybits / 8, (uint8_t *)RK);
+#endif
+
+    return 0;
+}
+
+/*
+ * AES-ECB block encryption
+ */
+int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16])
+{
+    uint8_t *key;
+
+    key = (uint8_t *)ctx->rk;
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+    LTC_AES_EncryptEcb(LTC_INSTANCE, input, output, 16, key, ctx->nr);
+#elif defined(MBEDTLS_FREESCALE_MMCAU_AES)
+    MMCAU_AES_EncryptEcb(input, key, ctx->nr, output);
+#elif defined(MBEDTLS_FREESCALE_CAU3_AES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot);
+    }
+    CAU3_AES_Encrypt(CAU3, &s_cau3Handle, input, output);
+#elif defined(MBEDTLS_FREESCALE_LPC_AES)
+    AES_SetKey(AES_INSTANCE, key, ctx->nr);
+    AES_EncryptEcb(AES_INSTANCE, input, output, 16);
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+    CAAM_AES_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 16, key, ctx->nr);
+#elif defined(MBEDTLS_FREESCALE_DCP_AES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot);
+    }
+    DCP_AES_EncryptEcb(DCP, &s_dcpHandle, input, output, 16);
+#endif
+
+    return (0);
+}
+
+/*
+ * AES-ECB block decryption
+ */
+int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16])
+{
+    uint8_t *key;
+
+    key = (uint8_t *)ctx->rk;
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+    LTC_AES_DecryptEcb(LTC_INSTANCE, input, output, 16, key, ctx->nr, kLTC_EncryptKey);
+#elif defined(MBEDTLS_FREESCALE_MMCAU_AES)
+    MMCAU_AES_DecryptEcb(input, key, ctx->nr, output);
+#elif defined(MBEDTLS_FREESCALE_CAU3_AES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot);
+    }
+    CAU3_AES_Decrypt(CAU3, &s_cau3Handle, input, output);
+#elif defined(MBEDTLS_FREESCALE_LPC_AES)
+    AES_SetKey(AES_INSTANCE, key, ctx->nr);
+    AES_DecryptEcb(AES_INSTANCE, input, output, 16);
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+    CAAM_AES_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 16, key, ctx->nr);
+#elif defined(MBEDTLS_FREESCALE_DCP_AES)
+    if (!crypto_key_is_loaded(ctx))
+    {
+        DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot);
+    }
+    DCP_AES_DecryptEcb(DCP, &s_dcpHandle, input, output, 16);
+#endif
+
+    return (0);
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key = (uint8_t *)ctx->rk;
+    uint32_t keySize = ctx->nr;
+
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        LTC_AES_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key, keySize, kLTC_EncryptKey);
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        LTC_AES_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key, keySize);
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_LPC_AES)
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+    size_t keySize;
+
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    key = (uint8_t *)ctx->rk;
+    keySize = (size_t)ctx->nr;
+    AES_SetKey(AES_INSTANCE, key, keySize);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        AES_DecryptCbc(AES_INSTANCE, tmp, output, length, iv);
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        AES_EncryptCbc(AES_INSTANCE, input, output, length, iv);
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key = (uint8_t *)ctx->rk;
+    uint32_t keySize = ctx->nr;
+
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        CAAM_AES_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, keySize);
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        CAAM_AES_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, keySize);
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_DCP_AES)
+int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+
+    if (length % 16)
+        return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
+
+    key = (uint8_t *)ctx->rk;
+    if (!crypto_key_is_loaded(ctx))
+    {
+        DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr);
+        crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot);
+    }
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        uint8_t tmp[16];
+        memcpy(tmp, input + length - 16, 16);
+        DCP_AES_DecryptCbc(DCP, &s_dcpHandle, input, output, length, iv);
+        memcpy(iv, tmp, 16);
+    }
+    else
+    {
+        DCP_AES_EncryptCbc(DCP, &s_dcpHandle, input, output, length, iv);
+        memcpy(iv, output + length - 16, 16);
+    }
+
+    return (0);
+}
+#endif
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+#if defined(MBEDTLS_FREESCALE_LPC_AES)
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
+                             int mode,
+                             size_t length,
+                             size_t *iv_off,
+                             unsigned char iv[16],
+                             const unsigned char *input,
+                             unsigned char *output)
+{
+    uint8_t *key;
+    size_t keySize;
+
+    key = (uint8_t *)ctx->rk;
+    keySize = (size_t)ctx->nr;
+    AES_SetKey(AES_INSTANCE, key, keySize);
+
+    if (mode == MBEDTLS_AES_DECRYPT)
+    {
+        AES_DecryptCfb(AES_INSTANCE, input, output, length, iv);
+    }
+    else
+    {
+        AES_EncryptCfb(AES_INSTANCE, input, output, length, iv);
+    }
+
+    return (0);
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
+                           int mode,
+                           size_t length,
+                           unsigned char iv[16],
+                           const unsigned char *input,
+                           unsigned char *output)
+{
+    int status;
+    unsigned char c;
+    unsigned char ov[17];
+
+    while (length--)
+    {
+        memcpy(ov, iv, 16);
+        status = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
+        if (status != 0)
+        {
+            return status;
+        }
+
+        if (mode == MBEDTLS_AES_DECRYPT)
+            ov[16] = *input;
+
+        c = *output++ = (unsigned char)(iv[0] ^ *input++);
+
+        if (mode == MBEDTLS_AES_ENCRYPT)
+            ov[16] = c;
+
+        memcpy(iv, ov + 1, 16);
+    }
+
+    return (0);
+}
+#endif /* MBEDTLS_FREESCALE_LPC_AES */
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t length,
+                          size_t *nc_off,
+                          unsigned char nonce_counter[16],
+                          unsigned char stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+    uint32_t keySize;
+
+    key = (uint8_t *)ctx->rk;
+    keySize = ctx->nr;
+    LTC_AES_CryptCtr(LTC_INSTANCE, input, output, length, nonce_counter, key, keySize, stream_block,
+                     (uint32_t *)nc_off);
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_LPC_AES)
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t length,
+                          size_t *nc_off,
+                          unsigned char nonce_counter[16],
+                          unsigned char stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+    size_t keySize;
+
+    key = (uint8_t *)ctx->rk;
+    keySize = (size_t)ctx->nr;
+
+    AES_SetKey(AES_INSTANCE, key, keySize);
+    AES_CryptCtr(AES_INSTANCE, input, output, length, nonce_counter, stream_block, nc_off);
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
+                          size_t length,
+                          size_t *nc_off,
+                          unsigned char nonce_counter[16],
+                          unsigned char stream_block[16],
+                          const unsigned char *input,
+                          unsigned char *output)
+{
+    uint8_t *key;
+    uint32_t keySize;
+
+    key = (uint8_t *)ctx->rk;
+    keySize = ctx->nr;
+
+    CAAM_AES_CryptCtr(CAAM_INSTANCE, &s_caamHandle, input, output, length, nonce_counter, key, keySize, stream_block,
+                      nc_off);
+
+    return (0);
+}
+#endif
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_CMAC_ALT) && defined(MBEDTLS_CMAC_C)
+
+#include "mbedtls/cipher.h"
+#include "mbedtls/cmac.h"
+
+#if defined(MBEDTLS_FREESCALE_CAU3_CIPHER_CMAC)
+int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
+                        const unsigned char *key,
+                        size_t keylen,
+                        const unsigned char *input,
+                        size_t ilen,
+                        unsigned char *output)
+{
+    mbedtls_cipher_context_t ctx;
+    int ret;
+
+    if (cipher_info == NULL || key == NULL || input == NULL || output == NULL)
+        return (MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA);
+
+    mbedtls_cipher_init(&ctx);
+
+    if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0)
+        goto exit;
+
+    ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
+    if (ret != 0)
+        goto exit;
+
+    /* AES-CMAC-128 is directly supported by CAU3 firmware */
+    if (cipher_info->type == MBEDTLS_CIPHER_AES_128_ECB)
+    {
+        status_t status;
+        uint8_t mac[16];
+
+        status = CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, keylen / 8u);
+        if (status != kStatus_Success)
+        {
+            ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+            goto exit;
+        }
+        status = CAU3_AES_Cmac(CAU3, &s_cau3Handle, input, ilen, mac);
+        if (status != kStatus_Success)
+        {
+            ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+            goto exit;
+        }
+        memcpy(output, mac, 16);
+    }
+#if defined(MBEDTLS_CIPHER_CMAC_TDES_ENABLED) || defined(MBEDTLS_CIPHER_CMAC_AES_256_ENABLED)
+    else if (cipher_info->type == MBEDTLS_CIPHER_AES_192_ECB)
+    {
+        /* CAU3 initial firmware does not support AES 192 */
+        ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+        goto exit;
+    }
+    else
+    {
+        /* AES-CMAC-256 and TDES-CMAC.
+         * If both MBEDTLS_DES_C and MBEDTLS_CIPHER_CMAC_WANTS_AES_256 are undefined,
+         * this does not compile
+         */
+        ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
+        if (ret != 0)
+            goto exit;
+
+        ret = mbedtls_cipher_cmac_finish(&ctx, output);
+    }
+#else
+    else
+    {
+        ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+        goto exit;
+    }
+#endif /* MBEDTLS_CIPHER_CMAC_TDES_ENABLED || MBEDTLS_CIPHER_CMAC_AES_256_ENABLED */
+
+exit:
+    mbedtls_cipher_free(&ctx);
+
+    return (ret);
+}
+#endif /* MBEDTLS_FREESCALE_CAU3_CIPHER_CMAC */
+#endif /* MBEDTLS_CIPHER_CMAC_ALT && MBEDTLS_CMAC_C */
+
+#if defined(MBEDTLS_CCM_C)
+
+#include "mbedtls/ccm.h"
+
+#define CCM_ENCRYPT 0
+#define CCM_DECRYPT 1
+
+/*
+ * Authenticated encryption or decryption
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_AES)
+static int ccm_auth_crypt(mbedtls_ccm_context *ctx,
+                          int mode,
+                          size_t length,
+                          const unsigned char *iv,
+                          size_t iv_len,
+                          const unsigned char *add,
+                          size_t add_len,
+                          const unsigned char *input,
+                          unsigned char *output,
+                          unsigned char *tag,
+                          size_t tag_len)
+{
+    status_t status;
+    const uint8_t *key;
+    uint8_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = aes_ctx->nr;
+    if (mode == CCM_ENCRYPT)
+    {
+        status = LTC_AES_EncryptTagCcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag,
+                                       tag_len);
+    }
+    else
+    {
+        status = LTC_AES_DecryptTagCcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag,
+                                       tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    return (0);
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES)
+static int ccm_auth_crypt(mbedtls_ccm_context *ctx,
+                          int mode,
+                          size_t length,
+                          const unsigned char *iv,
+                          size_t iv_len,
+                          const unsigned char *add,
+                          size_t add_len,
+                          const unsigned char *input,
+                          unsigned char *output,
+                          unsigned char *tag,
+                          size_t tag_len)
+{
+    status_t status;
+    const uint8_t *key;
+    uint8_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = aes_ctx->nr;
+    if (mode == CCM_ENCRYPT)
+    {
+        status = CAAM_AES_EncryptTagCcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len,
+                                        key, keySize, tag, tag_len);
+    }
+    else
+    {
+        status = CAAM_AES_DecryptTagCcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len,
+                                        key, keySize, tag, tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    return (0);
+}
+#endif /* MBEDTLS_FREESCALE_LTC_AES */
+
+#if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_CAAM_AES)
+/*
+ * Authenticated encryption
+ */
+int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx,
+                                size_t length,
+                                const unsigned char *iv,
+                                size_t iv_len,
+                                const unsigned char *add,
+                                size_t add_len,
+                                const unsigned char *input,
+                                unsigned char *output,
+                                unsigned char *tag,
+                                size_t tag_len)
+{
+    return (ccm_auth_crypt(ctx, CCM_ENCRYPT, length, iv, iv_len, add, add_len, input, output, tag, tag_len));
+}
+
+/*
+ * Authenticated decryption
+ */
+int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx,
+                             size_t length,
+                             const unsigned char *iv,
+                             size_t iv_len,
+                             const unsigned char *add,
+                             size_t add_len,
+                             const unsigned char *input,
+                             unsigned char *output,
+                             const unsigned char *tag,
+                             size_t tag_len)
+{
+    unsigned char tagCopy[16];
+    unsigned char *actTag = NULL;
+    if (tag)
+    {
+        memcpy(tagCopy, tag, tag_len);
+        actTag = tagCopy;
+    }
+    return (ccm_auth_crypt(ctx, CCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, actTag, tag_len));
+}
+#endif /* MBEDTLS_FREESCALE_LTC_AES || MBEDTLS_FREESCALE_CAAM_AES */
+#endif /* MBEDTLS_CCM_C */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_FREESCALE_LTC_AES_GCM)
+
+#include "mbedtls/gcm.h"
+
+int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
+                              int mode,
+                              size_t length,
+                              const unsigned char *iv,
+                              size_t iv_len,
+                              const unsigned char *add,
+                              size_t add_len,
+                              const unsigned char *input,
+                              unsigned char *output,
+                              size_t tag_len,
+                              unsigned char *tag)
+{
+    status_t status;
+    uint8_t *key;
+    uint32_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    ctx->len = length;
+    ctx->add_len = add_len;
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = aes_ctx->nr;
+    if (mode == MBEDTLS_GCM_ENCRYPT)
+    {
+        status = LTC_AES_EncryptTagGcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag,
+                                       tag_len);
+    }
+    else
+    {
+        status = LTC_AES_DecryptTagGcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag,
+                                       tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
+                             size_t length,
+                             const unsigned char *iv,
+                             size_t iv_len,
+                             const unsigned char *add,
+                             size_t add_len,
+                             const unsigned char *tag,
+                             size_t tag_len,
+                             const unsigned char *input,
+                             unsigned char *output)
+{
+    unsigned char tag_copy[16];
+    unsigned char *actTag = NULL;
+    if (tag)
+    {
+        memcpy(tag_copy, tag, tag_len);
+        actTag = tag_copy;
+    }
+    return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output,
+                                      tag_len, actTag));
+}
+
+#elif defined(MBEDTLS_FREESCALE_LPC_AES_GCM)
+
+#include "mbedtls/gcm.h"
+
+int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
+                              int mode,
+                              size_t length,
+                              const unsigned char *iv,
+                              size_t iv_len,
+                              const unsigned char *add,
+                              size_t add_len,
+                              const unsigned char *input,
+                              unsigned char *output,
+                              size_t tag_len,
+                              unsigned char *tag)
+{
+    status_t status;
+    uint8_t *key;
+    size_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    ctx->len = length;
+    ctx->add_len = add_len;
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = (size_t)aes_ctx->nr;
+
+    status = AES_SetKey(AES_INSTANCE, key, keySize);
+    if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    if (mode == MBEDTLS_GCM_ENCRYPT)
+    {
+        status = AES_EncryptTagGcm(AES_INSTANCE, input, output, length, iv, iv_len, add, add_len, tag, tag_len);
+    }
+    else
+    {
+        status = AES_DecryptTagGcm(AES_INSTANCE, input, output, length, iv, iv_len, add, add_len, tag, tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
+                             size_t length,
+                             const unsigned char *iv,
+                             size_t iv_len,
+                             const unsigned char *add,
+                             size_t add_len,
+                             const unsigned char *tag,
+                             size_t tag_len,
+                             const unsigned char *input,
+                             unsigned char *output)
+{
+    unsigned char tag_copy[16];
+
+    memcpy(tag_copy, tag, tag_len);
+    return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output,
+                                      tag_len, tag_copy));
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_AES_GCM)
+
+#include "mbedtls/gcm.h"
+
+int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
+                              int mode,
+                              size_t length,
+                              const unsigned char *iv,
+                              size_t iv_len,
+                              const unsigned char *add,
+                              size_t add_len,
+                              const unsigned char *input,
+                              unsigned char *output,
+                              size_t tag_len,
+                              unsigned char *tag)
+{
+    status_t status;
+    uint8_t *key;
+    uint32_t keySize;
+    mbedtls_aes_context *aes_ctx;
+
+    ctx->len = length;
+    ctx->add_len = add_len;
+    aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx;
+    key = (uint8_t *)aes_ctx->rk;
+    keySize = aes_ctx->nr;
+    if (mode == MBEDTLS_GCM_ENCRYPT)
+    {
+        status = CAAM_AES_EncryptTagGcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len,
+                                        key, keySize, tag, tag_len);
+    }
+    else
+    {
+        status = CAAM_AES_DecryptTagGcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len,
+                                        key, keySize, tag, tag_len);
+    }
+
+    if (status == kStatus_InvalidArgument)
+    {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+    else if (status != kStatus_Success)
+    {
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
+                             size_t length,
+                             const unsigned char *iv,
+                             size_t iv_len,
+                             const unsigned char *add,
+                             size_t add_len,
+                             const unsigned char *tag,
+                             size_t tag_len,
+                             const unsigned char *input,
+                             unsigned char *output)
+{
+    unsigned char tag_copy[16];
+    unsigned char *actTag = NULL;
+    if (tag)
+    {
+        memcpy(tag_copy, tag, tag_len);
+        actTag = tag_copy;
+    }
+    return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output,
+                                      tag_len, actTag));
+}
+#endif
+#endif /* MBEDTLS_GCM_C */
+
+#endif /* MBEDTLS_FREESCALE_LTC_AES || MBEDTLS_FREESCALE_MMCAU_AES || MBEDTLS_FREESCALE_LPC_AES */
+
+#endif /* MBEDTLS_AES_C */
+
+/******************************************************************************/
+/*************************** PKHA *********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) || defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+static void ltc_reverse_array(uint8_t *src, size_t src_len)
+{
+    int i;
+
+    for (i = 0; i < src_len / 2; i++)
+    {
+        uint8_t tmp;
+
+        tmp = src[i];
+        src[i] = src[src_len - 1 - i];
+        src[src_len - 1 - i] = tmp;
+    }
+}
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#include "mbedtls/bignum.h"
+
+#if defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+#define LTC_PKHA_ModAdd CAU3_PKHA_ModAdd
+#define LTC_PKHA_ModSub1 CAU3_PKHA_ModSub1
+#define LTC_PKHA_ModMul CAU3_PKHA_ModMul
+#define LTC_PKHA_ModRed CAU3_PKHA_ModRed
+#define LTC_PKHA_ModExp CAU3_PKHA_ModExp
+#define LTC_PKHA_GCD CAU3_PKHA_ModGcd
+#define LTC_PKHA_ModInv CAU3_PKHA_ModInv
+#define LTC_PKHA_PrimalityTest CAU3_PKHA_PrimalityTest
+#define LTC_INSTANCE ((CAU3_Type *)CAU3_BASE)
+
+#define kLTC_PKHA_IntegerArith kCAU3_PKHA_IntegerArith
+#define kLTC_PKHA_NormalValue kCAU3_PKHA_NormalValue
+#define kLTC_PKHA_TimingEqualized kCAU3_PKHA_TimingEqualized
+
+#define cau3_reverse_array ltc_reverse_array
+#define cau3_get_from_mbedtls_mpi ltc_get_from_mbedtls_mpi
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA)
+typedef uint16_t pkha_size_t;
+#else
+typedef size_t pkha_size_t;
+#endif
+
+#if defined(MBEDTLS_MPI_ADD_ABS_ALT)
+
+/* Access to original version of mbedtls_mpi_add_abs function. */
+int mbedtls_mpi_add_abs_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Unsigned addition: X = |A| + |B|  (HAC 14.7)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Perform HW acceleration only if the size in bytes is less than maximum.
+     * Since modular add is used below, the result would be wrong
+     * if the real sum of operands exceeded LTC maximum number value.
+     */
+    if ((sizeA < sizeN) && (sizeB < sizeN))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        ret = (int)LTC_PKHA_ModAdd(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC,
+                                   kLTC_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = 1;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_add_abs_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Perform HW acceleration only if the size in bytes is less than maximum.
+     * Since modular add is used below, the result would be wrong
+     * if the real sum of operands exceeded CAAM maximum number value.
+     */
+    if ((sizeA < sizeN) && (sizeB < sizeN))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        ret = (int)CAAM_PKHA_ModAdd(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = 1;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_add_abs_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_ADD_ABS_ALT */
+
+#if defined(MBEDTLS_MPI_SUB_ABS_ALT)
+
+/* Access to original version of mbedtls_mpi_sub_abs function. */
+int mbedtls_mpi_sub_abs_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Unsigned subtraction: X = |A| - |B|  (HAC 14.9)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Perform HW acceleration only if |A| >= |B|. Since modular subtraction is used below,
+     * the result would be wrong if the real sum of operands exceeded maximum.
+     */
+    if ((sizeA <= sizeN) && (sizeB <= sizeN) && (mbedtls_mpi_cmp_abs(A, B) >= 0))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        ret = (int)LTC_PKHA_ModSub1(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = 1;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_sub_abs_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Perform HW acceleration only if |A| >= |B|. Since modular subtraction is used below,
+     * the result would be wrong if the real sum of operands exceeded maximum.
+     */
+    if ((sizeA <= sizeN) && (sizeB <= sizeN) && (mbedtls_mpi_cmp_abs(A, B) >= 0))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        ret = (int)CAAM_PKHA_ModSub1(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = 1;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_sub_abs_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_SUB_ABS_ALT */
+
+#if defined(MBEDTLS_MPI_MUL_MPI_ALT)
+
+/* Access to original version of mbedtls_mpi_mul_mpi function. */
+int mbedtls_mpi_mul_mpi_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Baseline multiplication: X = A * B  (HAC 14.12)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Should be "if ((sizeA + sizeB) <= sizeN)", but if the multiplication result
+     * would be maximum LTC number (the same value as the modulus N below),
+     * zero would be returned instead, which is wrong value.
+     */
+    if ((sizeA + sizeB) < sizeN)
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        int sign = A->s * B->s;
+
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        /*
+         * Modular multiplication operation is used here. Since the modulus N is larger
+         * than the expected result of A * B, the effect is normal multiplication.
+         * TODO use PKHA MUL_IM_OM instead.
+         */
+        ret =
+            (int)LTC_PKHA_ModMul(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC, kLTC_PKHA_IntegerArith,
+                                 kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = sign;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_mul_mpi_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+    pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES;
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    /*
+     * Should be "if ((sizeA + sizeB) <= sizeN)", but if the multiplication result
+     * would be maximum CAAM number (the same value as the modulus N below),
+     * zero would be returned instead, which is wrong value.
+     */
+    if ((sizeA + sizeB) < sizeN)
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        int sign = A->s * B->s;
+
+        uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == N)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        memset(N, 0xFF, sizeN);
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        /*
+         * Modular multiplication operation is used here. Since the modulus N is larger
+         * than the expected result of A * B, the effect is normal multiplication.
+         * TODO use PKHA MUL_IM_OM instead.
+         */
+        ret = (int)CAAM_PKHA_ModMul(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith, kCAAM_PKHA_NormalValue, kCAAM_PKHA_NormalValue,
+                                    kCAAM_PKHA_TimingEqualized);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+        X->s = sign;
+    cleanup:
+        if (N)
+        {
+            mbedtls_free(N);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_mul_mpi_orig(X, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_MUL_MPI_ALT */
+
+#if defined(MBEDTLS_MPI_MOD_MPI_ALT)
+
+/* Access to original version of mbedtls_mpi_mod_mpi function. */
+int mbedtls_mpi_mod_mpi_orig(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Modulo: R = A mod B
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        int sign = A->s;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(R, ptrC, sizeC);
+        R->s = sign;
+
+        while (mbedtls_mpi_cmp_int(R, 0) < 0)
+            mbedtls_mpi_add_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); */
+
+        while (mbedtls_mpi_cmp_mpi(R, B) >= 0)
+            mbedtls_mpi_sub_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); cleanup:*/
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_mod_mpi_orig(R, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        int sign = A->s;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(R, ptrC, sizeC);
+        R->s = sign;
+
+        while (mbedtls_mpi_cmp_int(R, 0) < 0)
+            mbedtls_mpi_add_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); */
+
+        while (mbedtls_mpi_cmp_mpi(R, B) >= 0)
+            mbedtls_mpi_sub_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); cleanup:*/
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_mod_mpi_orig(R, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_MOD_MPI_ALT */
+
+#if defined(MBEDTLS_MPI_EXP_MOD_ALT)
+
+/* Access to original version of mbedtls_mpi_exp_mod function. */
+int mbedtls_mpi_exp_mod_orig(
+    mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR);
+
+/*
+ * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_exp_mod(
+    mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR)
+{
+    int ret;
+    pkha_size_t sizeE = mbedtls_mpi_size(E);
+    pkha_size_t sizeN = mbedtls_mpi_size(N);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeE <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif                   /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        mbedtls_mpi *AA; // TODO rename etc.
+
+        /*
+         * If number is greater than modulus, we must first reduce it due to LTC requirement
+         * on modular exponentiaton that it needs number less than modulus.
+         * We can take advantage of modular arithmetic rule that: A^B mod C = ( (A mod C)^B ) mod C.
+         * So we do (A mod N) first and if the size of A in bytes fits into LTC, it will be done in LTC
+         * (here LTC does not give size requirement on A versus N), otherwise it will be done in SW
+         * and since the size of N fits into LTC, the result of (A mod N) will also fit into LTC.
+         * Then we can do modular exponentiation in LTC.
+         */
+        if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
+        {
+            /* A >= N, perform X = (A mod N). */
+            ret = mbedtls_mpi_mod_mpi(X, A, N);
+
+            if (ret != kStatus_Success)
+                return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+            /* Exponenciation will be performed with X. */
+            AA = X;
+        }
+        else
+        {
+            /* Exponentiation will be performed with original A. */
+            AA = (mbedtls_mpi *)A;
+        }
+
+        pkha_size_t sizeA = mbedtls_mpi_size(AA);
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrE = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrN = ptrE + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(AA, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(E, ptrE, sizeE);
+        ltc_reverse_array(ptrE, sizeE);
+
+        mbedtls_mpi_write_binary(N, ptrN, sizeN);
+        ltc_reverse_array(ptrN, sizeN);
+
+        ret = (int)LTC_PKHA_ModExp(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrE, sizeE, ptrN, &sizeN,
+                                   kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrN, sizeN);
+        mbedtls_mpi_read_binary(X, ptrN, sizeN);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_exp_mod_orig(X, A, E, N, _RR);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_exp_mod(
+    mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR)
+{
+    int ret;
+    pkha_size_t sizeE = mbedtls_mpi_size(E);
+    pkha_size_t sizeN = mbedtls_mpi_size(N);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeE <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        mbedtls_mpi *AA; // TODO rename etc.
+
+        /*
+         * If number is greater than modulus, we must first reduce it due to CAAM requirement
+         * on modular exponentiaton that it needs number less than modulus.
+         * We can take advantage of modular arithmetic rule that: A^B mod C = ( (A mod C)^B ) mod C.
+         * So we do (A mod N) first and if the size of A in bytes fits into CAAM, it will be done in CAAM
+         * (here CAAM does not give size requirement on A versus N), otherwise it will be done in SW
+         * and since the size of N fits into CAAM, the result of (A mod N) will also fit into CAAM.
+         * Then we can do modular exponentiation in CAAM.
+         */
+        if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
+        {
+            /* A >= N, perform X = (A mod N). */
+            ret = mbedtls_mpi_mod_mpi(X, A, N);
+
+            if (ret != kStatus_Success)
+                return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+            /* Exponenciation will be performed with X. */
+            AA = X;
+        }
+        else
+        {
+            /* Exponentiation will be performed with original A. */
+            AA = (mbedtls_mpi *)A;
+        }
+
+        pkha_size_t sizeA = mbedtls_mpi_size(AA);
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrE = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrN = ptrE + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(AA, ptrA, sizeA);
+        mbedtls_mpi_write_binary(E, ptrE, sizeE);
+        mbedtls_mpi_write_binary(N, ptrN, sizeN);
+
+        ret = (int)CAAM_PKHA_ModExp(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrE, sizeE, ptrN, &sizeN,
+                                    kCAAM_PKHA_IntegerArith, kCAAM_PKHA_NormalValue, kCAAM_PKHA_TimingEqualized);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrN, sizeN);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_exp_mod_orig(X, A, E, N, _RR);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_EXP_MOD_ALT */
+
+#if defined(MBEDTLS_MPI_GCD_ALT)
+
+/* Access to original version of mbedtls_mpi_gcd function. */
+int mbedtls_mpi_gcd_orig(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B);
+
+/*
+ * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+        ltc_reverse_array(ptrB, sizeB);
+
+        if (mbedtls_mpi_cmp_mpi(A, B) >= 0)
+        {
+            ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrA, &sizeA, kLTC_PKHA_IntegerArith);
+
+            if (ret != kStatus_Success)
+                CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        ret = (int)LTC_PKHA_GCD(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(G, ptrC, sizeC);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_gcd_orig(G, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeB = mbedtls_mpi_size(B);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(B, ptrB, sizeB);
+
+        if (mbedtls_mpi_cmp_mpi(A, B) >= 0)
+        {
+            ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrA, &sizeA,
+                                        kCAAM_PKHA_IntegerArith);
+
+            if (ret != kStatus_Success)
+                CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        ret = (int)CAAM_PKHA_ModGcd(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(G, ptrC, sizeC);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_gcd_orig(G, A, B);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_GCD_ALT */
+
+#if defined(MBEDTLS_MPI_INV_MOD_ALT)
+
+/* Access to original version of mbedtls_mpi_inv_mod function. */
+int mbedtls_mpi_inv_mod_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N);
+
+/*
+ * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64)
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeN = mbedtls_mpi_size(N);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrN + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        /* N cannot be negative */
+        if (N->s < 0 || mbedtls_mpi_cmp_int(N, 0) == 0)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        ltc_reverse_array(ptrA, sizeA);
+
+        mbedtls_mpi_write_binary(N, ptrN, sizeN);
+        ltc_reverse_array(ptrN, sizeN);
+
+        if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
+        {
+            ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrA, &sizeA, kLTC_PKHA_IntegerArith);
+
+            if (ret != kStatus_Success)
+                CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        ret = (int)LTC_PKHA_ModInv(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrC, &sizeC, kLTC_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        ltc_reverse_array(ptrC, sizeC);
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_inv_mod_orig(X, A, N);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
+{
+    pkha_size_t sizeA = mbedtls_mpi_size(A);
+    pkha_size_t sizeN = mbedtls_mpi_size(N);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES))
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        pkha_size_t sizeC;
+        uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+        uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+        uint8_t *ptrC = ptrN + FREESCALE_PKHA_INT_MAX_BYTES;
+        if (NULL == ptrA)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        /* N cannot be negative */
+        if (N->s < 0 || mbedtls_mpi_cmp_int(N, 0) == 0)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
+        }
+
+        mbedtls_mpi_write_binary(A, ptrA, sizeA);
+        mbedtls_mpi_write_binary(N, ptrN, sizeN);
+
+        if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
+        {
+            ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrA, &sizeA,
+                                        kCAAM_PKHA_IntegerArith);
+
+            if (ret != kStatus_Success)
+                CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        ret = (int)CAAM_PKHA_ModInv(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrC, &sizeC,
+                                    kCAAM_PKHA_IntegerArith);
+
+        if (ret != kStatus_Success)
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+
+        mbedtls_mpi_read_binary(X, ptrC, sizeC);
+    cleanup:
+        if (ptrA)
+        {
+            mbedtls_free(ptrA);
+        }
+        return (ret);
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_inv_mod_orig(X, A, N);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_INV_MOD_ALT */
+
+#if defined(MBEDTLS_MPI_IS_PRIME_ALT)
+
+/* Access to original version of mbedtls_mpi_is_prime function. */
+int mbedtls_mpi_is_prime_orig(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+
+/*
+ * Pseudo-primality test: small factors, then Miller-Rabin
+ */
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int mbedtls_mpi_is_prime(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
+{
+    pkha_size_t sizeX = mbedtls_mpi_size(X);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if (sizeX <= FREESCALE_PKHA_INT_MAX_BYTES)
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        int random;
+        bool result = false;
+        uint8_t *ptrX = mbedtls_calloc(1, FREESCALE_PKHA_INT_MAX_BYTES);
+        if (NULL == ptrX)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(X, ptrX, FREESCALE_PKHA_INT_MAX_BYTES);
+        ltc_reverse_array(ptrX, FREESCALE_PKHA_INT_MAX_BYTES);
+
+        // Get the random seed number
+        f_rng(p_rng, (unsigned char *)(&random), sizeof(random));
+
+        ret = (int)LTC_PKHA_PrimalityTest(LTC_INSTANCE, (unsigned char *)&random, sizeof(random), (const uint8_t *)"1",
+                                          1u, ptrX, sizeX, &result);
+
+        if (ret != kStatus_Success)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        if (result == false)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+    cleanup:
+        if (ptrX)
+        {
+            mbedtls_free(ptrX);
+        }
+        return ret;
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_is_prime_orig(X, f_rng, p_rng);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int mbedtls_mpi_is_prime(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
+{
+    pkha_size_t sizeX = mbedtls_mpi_size(X);
+
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    if (sizeX <= FREESCALE_PKHA_INT_MAX_BYTES)
+    {
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+        int ret;
+        int random;
+        bool result = false;
+        uint8_t *ptrX = mbedtls_calloc(1, FREESCALE_PKHA_INT_MAX_BYTES);
+        if (NULL == ptrX)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+        }
+
+        mbedtls_mpi_write_binary(X, ptrX, FREESCALE_PKHA_INT_MAX_BYTES);
+
+        // Get the random seed number
+        f_rng(p_rng, (unsigned char *)(&random), sizeof(random));
+
+        ret = (int)CAAM_PKHA_PrimalityTest(CAAM_INSTANCE, &s_caamHandle, (unsigned char *)&random, sizeof(random),
+                                           (const uint8_t *)"1", 1u, ptrX, sizeX, &result);
+
+        if (ret != kStatus_Success)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+
+        if (result == false)
+        {
+            CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
+        }
+    cleanup:
+        if (ptrX)
+        {
+            mbedtls_free(ptrX);
+        }
+        return ret;
+#if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE)
+    }
+    else
+    {
+        return mbedtls_mpi_is_prime_orig(X, f_rng, p_rng);
+    }
+#endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_MPI_IS_PRIME_ALT */
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_ECP_C)
+
+#include "mbedtls/ecp.h"
+
+#define LTC_MAX_ECC (512)
+#define CAAM_MAX_ECC (528)
+#define CAU3_MAX_ECC (512)
+
+typedef enum
+{
+    kBigEndian = 0U,
+    kLittleEndian = 1U
+} endian_t;
+
+/* convert from mbedtls_mpi to LTC or CAAM integer, as array of bytes of size sz.
+ * if mbedtls_mpi has less bytes than sz, add zero bytes at most significant byte positions.
+ * This is when for example modulus is 32 bytes (P-256 curve)
+ * and mbedtls_mpi has only 31 bytes, we add leading zeroes
+ * so that result array has 32 bytes, same as modulus (sz).
+ */
+#if defined(MBEDTLS_ECP_MUL_COMB_ALT) || defined(MBEDTLS_ECP_ADD_ALT)
+static int get_and_extend_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz, endian_t endian)
+{
+    size_t szbin;
+    int offset;
+    int ret;
+
+    /* check how many bytes are in the mbedtls_mpi */
+    szbin = mbedtls_mpi_size(a);
+
+    /* compute offset from dst */
+    offset = sz - szbin;
+    if (offset < 0)
+        offset = 0;
+    if (offset > sz)
+        offset = sz;
+
+    /* add leading zeroes */
+    if (offset)
+        memset(dst, 0, offset);
+
+    /* convert mbedtls_mpi to array of bytes */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(a, dst + offset, szbin));
+
+    /* reverse array for LTC direct use */
+    if (endian == kLittleEndian)
+        ltc_reverse_array(dst, sz);
+cleanup:
+    return (ret);
+}
+
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+static int ltc_get_from_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz)
+{
+    return get_and_extend_mbedtls_mpi(dst, a, sz, kLittleEndian);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+static int caam_get_from_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz)
+{
+    return get_and_extend_mbedtls_mpi(dst, a, sz, kBigEndian);
+}
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA */
+#endif /* MBEDTLS_ECP_MUL_COMB_ALT || MBEDTLS_ECP_ADD_ALT */
+
+/*
+ * Multiplication using the comb method,
+ * for curves in short Weierstrass form
+ */
+#if defined(MBEDTLS_ECP_MUL_COMB_ALT)
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA)
+int ecp_mul_comb(mbedtls_ecp_group *grp,
+                 mbedtls_ecp_point *R,
+                 const mbedtls_mpi *m,
+                 const mbedtls_ecp_point *P,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng)
+{
+    int ret;
+    bool is_inf;
+    size_t size;
+    size_t size_bin;
+    int sign = m->s;
+
+    ltc_pkha_ecc_point_t A;
+    ltc_pkha_ecc_point_t result;
+
+    /* Allocate 7 elements with size of (LTC_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */
+    uint8_t *ptrAX = mbedtls_calloc((7 * (LTC_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1);
+    uint8_t *ptrAY = ptrAX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrAY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (LTC_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (LTC_MAX_ECC / 8);
+    uint8_t *ptrE = ptrParamB + (LTC_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (LTC_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(ptrParamA, &grp->A, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(ptrParamB, &grp->B, size));
+
+    /* scalar multiplier integer of any size */
+    size_bin = mbedtls_mpi_size(m);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin));
+    ltc_reverse_array(ptrE, size_bin);
+
+    /* modulus */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+    ltc_reverse_array(ptrN, size);
+
+    /* Multiply */
+    LTC_PKHA_ECC_PointMul(LTC_INSTANCE, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size,
+                          kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, &result, &is_inf);
+    /* Convert result */
+    ltc_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    ltc_reverse_array(ptrRY, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    /* if the integer multiplier is negative, the computation happens with abs() value
+     * and the result (x,y) is changed to (x, -y)
+     */
+    R->Y.s = sign;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int ecp_mul_comb(mbedtls_ecp_group *grp,
+                 mbedtls_ecp_point *R,
+                 const mbedtls_mpi *m,
+                 const mbedtls_ecp_point *P,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng)
+{
+    int ret;
+    size_t size;
+    size_t size_bin;
+    int sign = m->s;
+
+    caam_pkha_ecc_point_t A;
+    caam_pkha_ecc_point_t result;
+
+    /* Allocate 7 elements with size of (CAAM_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */
+    uint8_t *ptrAX = mbedtls_calloc((7 * (CAAM_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1);
+    uint8_t *ptrAY = ptrAX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrAY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrE = ptrParamB + (CAAM_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(ptrParamA, &grp->A, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(ptrParamB, &grp->B, size));
+
+    /* scalar multiplier integer of any size */
+    size_bin = mbedtls_mpi_size(m);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin));
+
+    /* modulus */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+
+    /* Multiply */
+    CAAM_PKHA_ECC_PointMul(CAAM_INSTANCE, &s_caamHandle, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size,
+                           kCAAM_PKHA_TimingEqualized, kCAAM_PKHA_IntegerArith, &result);
+    /* Convert result */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    /* if the integer multiplier is negative, the computation happens with abs() value
+     * and the result (x,y) is changed to (x, -y)
+     */
+    R->Y.s = sign;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int ecp_mul_comb(mbedtls_ecp_group *grp,
+                 mbedtls_ecp_point *R,
+                 const mbedtls_mpi *m,
+                 const mbedtls_ecp_point *P,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng)
+{
+    int ret;
+    status_t status;
+    size_t size;
+    size_t size_bin;
+    int sign = m->s;
+
+    cau3_pkha_ecc_point_t A;
+    cau3_pkha_ecc_point_t result;
+
+    /* Allocate 7 elements with size of (CAU3_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */
+    uint8_t *ptrAX = mbedtls_calloc((7 * (CAU3_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1);
+    uint8_t *ptrAY = ptrAX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrAY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrE = ptrParamB + (CAU3_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAU3_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(ptrParamA, &grp->A, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(ptrParamB, &grp->B, size));
+
+    /* scalar multiplier integer of any size */
+    size_bin = mbedtls_mpi_size(m);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin));
+    cau3_reverse_array(ptrE, size_bin);
+
+    /* modulus */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+    cau3_reverse_array(ptrN, size);
+
+    /* Multiply */
+    status = CAU3_PKHA_ECC_PointMul(CAU3, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size,
+                                    kCAU3_PKHA_TimingEqualized, kCAU3_PKHA_IntegerArith, &result);
+
+    if (status != kStatus_Success)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert result */
+    cau3_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    cau3_reverse_array(ptrRY, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    /* if the integer multiplier is negative, the computation happens with abs() value
+     * and the result (x,y) is changed to (x, -y)
+     */
+    R->Y.s = sign;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA */
+#endif /* MBEDTLS_ECP_MUL_COMB_ALT */
+
+/*
+ * Curve types: internal for now, might be exposed later
+ */
+typedef enum
+{
+    ECP_TYPE_NONE = 0,
+    ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b      */
+    ECP_TYPE_MONTGOMERY,        /* y^2 = x^3 + a x^2 + x    */
+} ecp_curve_type;
+/*
+ * Get the type of a curve
+ */
+static inline ecp_curve_type ecp_get_type(const mbedtls_ecp_group *grp)
+{
+    if (grp->G.X.p == NULL)
+        return (ECP_TYPE_NONE);
+
+    if (grp->G.Y.p == NULL)
+        return (ECP_TYPE_MONTGOMERY);
+    else
+        return (ECP_TYPE_SHORT_WEIERSTRASS);
+}
+
+/*
+ * Addition: R = P + Q, result's coordinates normalized
+ */
+#if defined(MBEDTLS_ECP_ADD_ALT)
+#if defined(MBEDTLS_FREESCALE_LTC_PKHA)
+int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q)
+{
+    int ret;
+    size_t size;
+    ltc_pkha_ecc_point_t A;
+    ltc_pkha_ecc_point_t B;
+    ltc_pkha_ecc_point_t result;
+
+    uint8_t *ptrAX = mbedtls_calloc(9, (LTC_MAX_ECC / 8));
+    uint8_t *ptrAY = ptrAX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrBX = ptrAY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrBY = ptrBX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrBY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (LTC_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (LTC_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (LTC_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (LTC_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS)
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE);
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    B.X = ptrBX;
+    B.Y = ptrBY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (LTC_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(B.X, &Q->X, size));
+    MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(B.Y, &Q->Y, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+    ltc_reverse_array(ptrN, size);
+    /* Multiply */
+    LTC_PKHA_ECC_PointAdd(LTC_INSTANCE, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size, kLTC_PKHA_IntegerArith,
+                          &result);
+    /* Convert result */
+    ltc_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    ltc_reverse_array(ptrRY, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    R->X.s = P->X.s;
+    R->Y.s = P->Y.s;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_PKHA)
+int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q)
+{
+    int ret;
+    size_t size;
+    caam_pkha_ecc_point_t A;
+    caam_pkha_ecc_point_t B;
+    caam_pkha_ecc_point_t result;
+
+    uint8_t *ptrAX = mbedtls_calloc(9, (CAAM_MAX_ECC / 8));
+    uint8_t *ptrAY = ptrAX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrBX = ptrAY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrBY = ptrBX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrBY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (CAAM_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (CAAM_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS)
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE);
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    B.X = ptrBX;
+    B.Y = ptrBY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(B.X, &Q->X, size));
+    MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(B.Y, &Q->Y, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+
+    /* Multiply */
+    CAAM_PKHA_ECC_PointAdd(CAAM_INSTANCE, &s_caamHandle, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size,
+                           kCAAM_PKHA_IntegerArith, &result);
+    /* Convert result */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    R->X.s = P->X.s;
+    R->Y.s = P->Y.s;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q)
+{
+    int ret;
+    status_t status;
+    size_t size;
+    cau3_pkha_ecc_point_t A;
+    cau3_pkha_ecc_point_t B;
+    cau3_pkha_ecc_point_t result;
+
+    uint8_t *ptrAX = mbedtls_calloc(9, (CAU3_MAX_ECC / 8));
+    uint8_t *ptrAY = ptrAX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrBX = ptrAY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrBY = ptrBX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrRX = ptrBY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrRY = ptrRX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrN = ptrRY + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrParamA = ptrN + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrParamB = ptrParamA + (CAU3_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS)
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE);
+
+    A.X = ptrAX;
+    A.Y = ptrAY;
+    B.X = ptrBX;
+    B.Y = ptrBY;
+    result.X = ptrRX;
+    result.Y = ptrRY;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAU3_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.Y, &P->Y, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(B.X, &Q->X, size));
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(B.Y, &Q->Y, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size));
+    cau3_reverse_array(ptrN, size);
+    /* Multiply */
+    status =
+        CAU3_PKHA_ECC_PointAdd(CAU3, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size, kCAU3_PKHA_IntegerArith, &result);
+
+    if (status != kStatus_Success)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert result */
+    cau3_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    cau3_reverse_array(ptrRY, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size));
+    R->X.s = P->X.s;
+    R->Y.s = P->Y.s;
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA */
+
+#endif /* MBEDTLS_ECP_ADD_ALT */
+
+#if defined(MBEDTLS_ECP_MUL_MXZ_ALT)
+#if defined(MBEDTLS_FREESCALE_CAU3_PKHA)
+
+/* curve25519 params - in little endian for CAU3 */
+static const uint8_t s_curve25519_A24[] = {0x42, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const uint8_t s_curve25519_N[] = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
+
+static const uint8_t s_curve25519_R2modN[] = {0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+int ecp_mul_mxz(mbedtls_ecp_group *grp,
+                mbedtls_ecp_point *R,
+                const mbedtls_mpi *m,
+                const mbedtls_ecp_point *P,
+                int (*f_rng)(void *, unsigned char *, size_t),
+                void *p_rng)
+{
+    int ret;
+    status_t status;
+    size_t size;
+    size_t size_bin;
+
+    cau3_pkha_ecc_point_t A;
+    cau3_pkha_ecc_point_t result;
+
+    /* Allocate 2 elements with size of (CAU3_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */
+    uint8_t *ptrAX = mbedtls_calloc((2 * (CAU3_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1);
+    uint8_t *ptrRX = ptrAX + (CAU3_MAX_ECC / 8);
+    uint8_t *ptrE = ptrRX + (CAU3_MAX_ECC / 8);
+    if (NULL == ptrAX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    A.X = ptrAX;
+    result.X = ptrRX;
+    size = mbedtls_mpi_size(&grp->P);
+    if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8))
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert multi precision integers to arrays */
+    MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size));
+
+    /* scalar multiplier integer of any size */
+    size_bin = mbedtls_mpi_size(m);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin));
+    cau3_reverse_array(ptrE, size_bin);
+
+    /* Multiply */
+    status = CAU3_PKHA_ECM_PointMul(CAU3, ptrE, size_bin, A.X, s_curve25519_A24, s_curve25519_N, s_curve25519_R2modN,
+                                    size, kCAU3_PKHA_TimingEqualized, result.X);
+
+    if (status != kStatus_Success)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
+    }
+
+    /* Convert result */
+    cau3_reverse_array(ptrRX, size);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1));
+
+cleanup:
+    if (ptrAX)
+    {
+        mbedtls_free(ptrAX);
+    }
+    return (ret);
+}
+
+#endif /* MBEDTLS_FREESCALE_CAU3_PKHA */
+#endif /* MBEDTLS_ECP_MUL_MXZ_ALT */
+
+#endif /* MBEDTLS_ECP_C */
+
+#endif /* MBEDTLS_FREESCALE_LTC_PKHA */
+
+#if defined(MBEDTLS_RSA_PUBLIC_ALT)
+#if defined(MBEDTLS_FREESCALE_CASPER_PKHA)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#include "mbedtls/bignum.h"
+#include "mbedtls/rsa.h"
+
+static void reverse_array(uint8_t *src, size_t src_len)
+{
+    int i;
+
+    for (i = 0; i < src_len / 2; i++)
+    {
+        uint8_t tmp;
+
+        tmp = src[i];
+        src[i] = src[src_len - 1 - i];
+        src[src_len - 1 - i] = tmp;
+    }
+}
+/*
+ * Do an RSA public key operation
+ */
+static int mbedtls_mpi_exp_mod_shim(mbedtls_mpi *X,
+                                    const mbedtls_mpi *A,
+                                    const mbedtls_mpi *E,
+                                    const mbedtls_mpi *N /*, mbedtls_mpi *_RR */)
+{
+    int ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
+    size_t sizeA = mbedtls_mpi_size(A);
+    size_t sizeN = mbedtls_mpi_size(N);
+    uint8_t *ptrX = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES);
+    uint8_t *ptrA = ptrX + FREESCALE_PKHA_INT_MAX_BYTES;
+    uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES;
+
+    if (NULL == ptrX)
+    {
+        CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED);
+    }
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(A, ptrA, sizeA));
+    reverse_array(ptrA, sizeA);
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(N, ptrN, sizeN));
+    reverse_array(ptrN, sizeN);
+
+    CASPER_ModExp(CASPER, ptrA, ptrN, sizeN / 4, E->p[0], ptrX);
+
+    reverse_array(ptrX, sizeN);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(X, ptrX, sizeN));
+cleanup:
+    if (ptrX != NULL)
+    {
+        mbedtls_free(ptrX);
+    }
+
+    return ret;
+}
+
+int mbedtls_rsa_public(mbedtls_rsa_context *ctx, const unsigned char *input, unsigned char *output)
+{
+    int ret;
+    size_t olen;
+    mbedtls_mpi T;
+
+    mbedtls_mpi_init(&T);
+
+#if defined(MBEDTLS_THREADING_C)
+    if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0)
+        return (ret);
+#endif
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len));
+
+    if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0)
+    {
+        ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    olen = ctx->len;
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod_shim(&T, &T, &ctx->E, &ctx->N /*, &ctx->RN */));
+
+    MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
+
+cleanup:
+#if defined(MBEDTLS_THREADING_C)
+    if (mbedtls_mutex_unlock(&ctx->mutex) != 0)
+        return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
+#endif
+
+    mbedtls_mpi_free(&T);
+
+    if (ret != 0)
+        return (MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret);
+
+    return (0);
+}
+
+#endif /* MBEDTLS_FREESCALE_CASPER_PKHA */
+#endif /* MBEDTLS_RSA_PUBLIC_ALT */
+
+/******************************************************************************/
+/*************************** MD5 **********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_MD5_C)
+
+#if defined(MBEDTLS_FREESCALE_MMCAU_MD5)
+
+#include "mbedtls/md5.h"
+
+int mbedtls_internal_md5_process(mbedtls_md5_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = MMCAU_MD5_HashN(data, 1, ctx->state);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_MD5_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#endif /* MBEDTLS_FREESCALE_MMCAU_MD5 */
+
+#endif /* MBEDTLS_MD5_C */
+
+/******************************************************************************/
+/*************************** SHA1 *********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_SHA1_C)
+
+#if defined(MBEDTLS_FREESCALE_LTC_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha1, NULL, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Update(ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Update(ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Finish(ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_MMCAU_SHA1)
+
+#include "mbedtls/sha1.h"
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = MMCAU_SHA1_HashN(data, 1, ctx->state);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_LPC_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Init(SHA_INSTANCE, ctx, kSHA_Sha1);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Update(SHA_INSTANCE, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Update(SHA_INSTANCE, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    size_t outputSize = 20u;
+    status_t ret = kStatus_Fail;
+    ret = SHA_Finish(SHA_INSTANCE, ctx, output, &outputSize);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+#elif defined(MBEDTLS_FREESCALE_CAAM_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha1, NULL, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Update(ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Update(ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Finish(ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Init(CAU3, ctx, kCAU3_Sha1);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Update(CAU3, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Update(CAU3, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Finish(CAU3, ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_DCP_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Init(DCP, &s_dcpHandle, ctx, kDCP_Sha1);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Update(DCP, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Update(DCP, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Finish(DCP, ctx, output, NULL);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA1)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
+}
+
+void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_sha1_context));
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Init(HASHCRYPT, ctx, kHASHCRYPT_Sha1);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    status_t ret = kStatus_Fail;
+    size_t outputSize = 20;
+    ret = HASHCRYPT_SHA_Finish(HASHCRYPT, ctx, output, &outputSize);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+#endif /* MBEDTLS_FREESCALE_LPC_SHA1 */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SHA1_ALT)
+#include "mbedtls/sha1.h"
+
+void mbedtls_sha1_starts(mbedtls_sha1_context *ctx)
+{
+    mbedtls_sha1_starts_ret(ctx);
+}
+
+void mbedtls_sha1_update(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
+{
+    mbedtls_sha1_update_ret(ctx, input, ilen);
+}
+
+void mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20])
+{
+    mbedtls_sha1_finish_ret(ctx, output);
+}
+
+void mbedtls_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
+{
+    mbedtls_internal_sha1_process(ctx, data);
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_SHA1_C */
+
+/******************************************************************************/
+/*************************** SHA256********************************************/
+/******************************************************************************/
+
+#if defined(MBEDTLS_SHA256_C)
+
+#if defined(MBEDTLS_FREESCALE_LTC_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (is224)
+    {
+        ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha224, NULL, 0);
+    }
+    else
+    {
+        ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha256, NULL, 0);
+    }
+
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Update(ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Update(ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    ret = LTC_HASH_Finish(ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_MMCAU_SHA256)
+
+#include "mbedtls/sha256.h"
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = MMCAU_SHA256_HashN(data, 1, ctx->state);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_SHA256)
+
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (!is224) /* SHA-224 not supported at the moment */
+    {
+        ret = CAU3_HASH_Init(CAU3, ctx, kCAU3_Sha256);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Update(CAU3, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Update(CAU3, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAU3_HASH_Finish(CAU3, ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_LPC_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (!is224) /* SHA-224 not supported */
+    {
+        ret = SHA_Init(SHA_INSTANCE, ctx, kSHA_Sha256);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Update(SHA_INSTANCE, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = SHA_Update(SHA_INSTANCE, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    size_t outputSize = 32u;
+    status_t ret = kStatus_Fail;
+    ret = SHA_Finish(SHA_INSTANCE, ctx, output, &outputSize);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (is224)
+    {
+        ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha224, NULL, 0);
+    }
+    else
+    {
+        ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha256, NULL, 0);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Update(ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Update(ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    ret = CAAM_HASH_Finish(ctx, output, 0);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_DCP_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (!is224)
+    {
+        ret = DCP_HASH_Init(DCP, &s_dcpHandle, ctx, kDCP_Sha256);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Update(DCP, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Update(DCP, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    ret = DCP_HASH_Finish(DCP, ctx, output, NULL);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+#elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA256)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+    memset(ctx, 0, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
+}
+
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+    status_t ret = kStatus_Fail;
+    if (!is224) /* SHA-224 not supported */
+    {
+        ret = HASHCRYPT_SHA_Init(HASHCRYPT, ctx, kHASHCRYPT_Sha256);
+    }
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, data, 64);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    status_t ret = kStatus_Fail;
+    ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, input, ilen);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    status_t ret = kStatus_Fail;
+    size_t outputSize = 32;
+    ret = HASHCRYPT_SHA_Finish(HASHCRYPT, ctx, output, &outputSize);
+    if (ret != kStatus_Success)
+    {
+        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    }
+    return 0;
+}
+#endif /* MBEDTLS_FREESCALE_LTC_SHA256 */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SHA256_ALT)
+#include "mbedtls/sha256.h"
+
+void mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
+{
+    mbedtls_sha256_starts_ret(ctx, is224);
+}
+
+void mbedtls_sha256_update(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
+{
+    mbedtls_sha256_update_ret(ctx, input, ilen);
+}
+
+void mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char output[32])
+{
+    mbedtls_sha256_finish_ret(ctx, output);
+}
+
+void mbedtls_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
+{
+    mbedtls_internal_sha256_process(ctx, data);
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_SHA256_C */
+
+/* Entropy poll callback for a hardware source */
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+
+#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+#if defined CPU_JN518X
+    #include "fsl_rng.h"
+#else
+    #include "fsl_trng.h"
+#endif
+#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+#include "fsl_rnga.h"
+#elif defined(FSL_FEATURE_SOC_LPC_RNG_COUNT) && (FSL_FEATURE_SOC_LPC_RNG_COUNT > 0)
+#include "fsl_rng.h"
+#elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0)
+#include "fsl_rng.h"
+#endif
+
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen)
+{
+    status_t result = kStatus_Success;
+
+#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+#if defined CPU_JN518X
+    #ifndef TRNG0
+    #define TRNG0 RNG
+    #endif
+#else
+    #ifndef TRNG0
+    #define TRNG0 TRNG
+    #endif
+#endif
+    result = TRNG_GetRandomData(TRNG0, output, len);
+#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+    result = RNGA_GetRandomData(RNG, (void *)output, len);
+#elif defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM)
+    result = CAAM_RNG_GetRandomData(CAAM_INSTANCE, &s_caamHandle, kCAAM_RngStateHandle0, output, len, kCAAM_RngDataAny,
+                                    NULL);
+#elif defined(FSL_FEATURE_SOC_LPC_RNG_COUNT) && (FSL_FEATURE_SOC_LPC_RNG_COUNT > 0)
+    uint32_t rn;
+    size_t length;
+    int i;
+
+    length = len;
+
+    while (length > 0)
+    {
+        rn = RNG_GetRandomData();
+
+        if (length >= sizeof(uint32_t))
+        {
+            memcpy(output, &rn, sizeof(uint32_t));
+            length -= sizeof(uint32_t);
+            output += sizeof(uint32_t);
+        }
+        else
+        {
+            memcpy(output, &rn, length);
+            output += length;
+            len = 0U;
+        }
+
+        /* Discard next 32 random words for better entropy */
+        for (i = 0; i < 32; i++)
+        {
+            RNG_GetRandomData();
+        }
+    }
+
+    result = kStatus_Success;
+#elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0)
+    status_t status = kStatus_Fail;
+
+    while(status != kStatus_Success)
+    {
+        status = RNG_GetRandomData(RNG, output, len);
+
+        if(status == kStatus_Fail)
+        {
+            RNG_Init(RNG);
+        }
+    }
+
+    result = status;
+#endif
+    if (result == kStatus_Success)
+    {
+        *olen = len;
+        return 0;
+    }
+    else
+    {
+        return result;
+    }
+}
+
+#endif
+
+/******************************************************************************/
+/*************************** FreeRTOS ********************************************/
+/******************************************************************************/
+#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) && defined(MBEDTLS_FREESCALE_FREERTOS_CALLOC_ALT)
+#include <stdlib.h>
+#include "FreeRTOS.h"
+#include "task.h"
+
+/*---------HEAP_3 calloc --------------------------------------------------*/
+
+void *pvPortCalloc(size_t num, size_t size)
+{
+    void *pvReturn;
+
+    vTaskSuspendAll();
+    {
+        pvReturn = calloc(num, size);
+        traceMALLOC(pvReturn, xWantedSize);
+    }
+    (void)xTaskResumeAll();
+
+#if (configUSE_MALLOC_FAILED_HOOK == 1)
+    {
+        if (pvReturn == NULL)
+        {
+            extern void vApplicationMallocFailedHook(void);
+            vApplicationMallocFailedHook();
+        }
+    }
+#endif
+
+    return pvReturn;
+}
+#endif /* USE_RTOS && defined(FSL_RTOS_FREE_RTOS) && defined(MBEDTLS_FREESCALE_FREERTOS_CALLOC_ALT) */
diff --git a/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.h b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.h
new file mode 100755
index 0000000..cb545c5
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/ksdk_mbedtls.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * 
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+ 
+#ifndef KSDK_MBEDTLS_H
+#define KSDK_MBEDTLS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int fsl_mbedtls_printf(const char *fmt_s, ...);
+void CRYPTO_InitHardware(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* KSDK_MBEDTLS_H */
diff --git a/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/sha1_alt.h b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/sha1_alt.h
new file mode 100755
index 0000000..76d0883
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/sha1_alt.h
@@ -0,0 +1,79 @@
+/**
+ * \file mbedtls_alt_sha1.h
+ *
+ * \brief SHA-1 cryptographic hash function
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *  Copyright 2017 NXP. Not a Contribution
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SHA1_ALT_H
+#define MBEDTLS_SHA1_ALT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context ltc_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_LPC_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context sha_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context caam_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context cau3_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_DCP_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context dcp_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA1)
+
+/**
+ * \brief          SHA-1 context structure
+ */
+#define mbedtls_sha1_context hashcrypt_hash_ctx_t
+
+#endif /* MBEDTLS_FREESCALE_LTC_SHA1 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_SHA1_ALT_H */
diff --git a/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/sha256_alt.h b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/sha256_alt.h
new file mode 100755
index 0000000..2fe0148
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/mbedtls/port/ksdk/sha256_alt.h
@@ -0,0 +1,82 @@
+/**
+ * \file mbedtls_sha256.h
+ *
+ * \brief SHA-224 and SHA-256 cryptographic hash function
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *  Copyright 2017 NXP. Not a Contribution
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SHA256_ALT_H
+#define MBEDTLS_SHA256_ALT_H
+
+// Regular implementation
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_FREESCALE_LTC_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context ltc_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_LPC_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context sha_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_CAAM_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context caam_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_CAU3_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context cau3_hash_ctx_t  
+
+#elif defined(MBEDTLS_FREESCALE_DCP_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context dcp_hash_ctx_t
+
+#elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA256)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+#define mbedtls_sha256_context hashcrypt_hash_ctx_t
+
+#endif /* MBEDTLS_FREESCALE_LTC_SHA256 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha256_alt.h */
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroInt_arm_sdk2.c b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroInt_arm_sdk2.c
new file mode 100755
index 0000000..b1fad83
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroInt_arm_sdk2.c
@@ -0,0 +1,233 @@
+/*****************************************************************************
+ *
+ * MODULE:             Microspecific
+ *
+ * COMPONENT:          Microspecific
+ *
+ * AUTHOR:             Wayne Ellis
+ *
+ * DESCRIPTION:        JN517x Microspecific Interrupt Controller Code
+ *
+ * $HeadURL:  $
+ *
+ * $Revision:  $
+ *
+ * $LastChangedBy: we1 $
+ *
+ * $LastChangedDate:  $
+ *
+ * $Id:  $
+ *
+ *****************************************************************************
+ *
+ * This software is owned by Jennic and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on Jennic products. You, and any third parties must reproduce
+ * the copyright and warranty notice and any other legend of ownership on each
+ * copy or partial copy of the software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". JENNIC MAKES NO WARRANTIES, WHETHER
+ * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * ACCURACY OR LACK OF NEGLIGENCE. JENNIC SHALL NOT, IN ANY CIRCUMSTANCES,
+ * BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, SPECIAL,
+ * INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON WHATSOEVER.
+ *
+ * Copyright Jennic Ltd. 2014 All rights reserved
+ *
+ ****************************************************************************/
+
+/****************************************************************************/
+/***        Include files                                                 ***/
+/****************************************************************************/
+#include "jendefs.h"
+
+#include "MicroSpecific.h"
+//#include "jn518x.h"
+//#include "PeripheralRegs.h"
+//#include <ARMcortexM3Registers_JN51xx.h>
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+// PreEmpt Priority field is [7:5]
+#define PREEMPT_PRIORITY_FIELD          (4)
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Local Function Prototypes                                     ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Local Variables                                               ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+#if 0
+/****************************************************************************
+ * NAME:        vAHI_InitialiseInterruptController
+ *
+ * DESCRIPTION:
+ * Initialise ARM NVIC.
+ *
+ * RETURNS:
+ * Nothing.
+ *
+ * NOTES:
+ *
+ ****************************************************************************/
+
+PUBLIC void vAHI_InitialiseInterruptController(
+            uint32 *pu32InterruptVectorTable)
+{
+    uint32 u32RegisterValue=0;
+
+    // set application interrupt and reset control register
+
+    // write vector key
+    U32_SET_BITS(&u32RegisterValue, REG_APP_INT_RESET_CTRL_VECTKEY);
+    // set priority group
+    U32_SET_BITS(&u32RegisterValue, PREEMPT_PRIORITY_FIELD << REG_APP_INT_RESET_CTRL_PRIGROUP_BIT);
+
+    vREG_Write(REG_APP_INT_RESET_CTRL, u32RegisterValue);
+
+    // set vector table location
+    u32RegisterValue=0;
+
+    // table in RAM - this bit isn't required in the JN5172 at all
+    // U32_SET_BITS(&u32RegisterValue, 1 << REG_INT_VECTOR_TABLE_OFFSET_TBLBASE_BIT);
+
+    // table address
+    U32_SET_BITS(&u32RegisterValue, (uint32)pu32InterruptVectorTable);
+    vREG_Write(REG_INT_VECTOR_TABLE_OFFSET, u32RegisterValue);
+
+    // enable exception features - DIV0 and align errors
+    u32RegisterValue=0;
+
+    U32_SET_BITS(
+       &u32RegisterValue,
+    /*    REG_CONFIGURATION_CONTROL_UNALIGN_TRP_MASK | */REG_CONFIGURATION_CONTROL_DIV_0_TRP_MASK);
+
+    vREG_Write(REG_CONFIGURATION_CONTROL, u32RegisterValue);
+
+    // set the exception priorities here - benign but listed so we know where they are
+    // MemManage
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_4, 0);
+    // BusFault
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_5, 0);
+    // UsageFault
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_6, 0);
+    // SVC
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_11, 0);
+    // debug monitor
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_12, 0);
+    // pend SV
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_14, 0);
+    // SYSTICK
+    vREG_Write8(REG_SYSTEM_HANDLER_PRIORITY_15, MICRO_INTERRUPT_WRITE_PRIORITY_VALUE(MICRO_JENNIC_TO_ARM_PRIORITY_MAP(8)));
+
+    u32RegisterValue=0;
+    U32_SET_BITS(
+       &u32RegisterValue,
+       REG_SYSTEM_HANDLER_CNTRL_STATE_USGFAULTEN_MASK | REG_SYSTEM_HANDLER_CNTRL_STATE_BUSFAULTEN_MASK | REG_SYSTEM_HANDLER_CNTRL_STATE_MEMFAULTEN_MASK);
+    vREG_Write(REG_SYSTEM_HANDLER_CNTRL_STATE, u32RegisterValue);
+
+}
+#endif
+
+#if 0
+/****************************************************************************
+ * NAME:        vMicroIntSetGlobalEnable
+ *
+ * DESCRIPTION:
+ * Enable specified interrupts.
+ *
+ * RETURNS:
+ * Nothing.
+ *
+ * NOTES:
+ *
+ ****************************************************************************/
+
+PUBLIC void vMicroIntSetGlobalEnable(
+        uint32      u32EnableMask)
+{
+    // all API's work with the old BA stack numbers, appropriate translations
+    // occur within the call
+    vAHI_InterruptSetPriority(u32EnableMask, 12);
+}
+#endif
+
+/****************************************************************************
+ * NAME:        vMicroIntEnableOnly
+ *
+ * DESCRIPTION:
+ * Enable specified interrupt.
+ *
+ * RETURNS:
+ * Nothing.
+ *
+ * NOTES:
+ *
+ ****************************************************************************/
+
+PUBLIC void vMicroIntEnableOnly(
+        tsMicroIntStorage      *psIntStorage,
+        uint32                  u32EnableMask)
+{
+    uint32 u32Store;
+
+    /* Not used in this implementation */
+    VARIABLE_INTENTIONALLY_NOT_REFERENCED(u32EnableMask)
+
+    /* Disable interrupts for duration of this function */
+#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
+    /* unroll MICRO_DISABLE_AND_SAVE_INTERRUPTS macro content becasue IAR < 8.40 fails to see u32Store is set */
+    u32Store = __get_PRIMASK();
+    __disable_irq(); 
+#else
+    MICRO_DISABLE_AND_SAVE_INTERRUPTS(u32Store);
+#endif
+    /* Store old priority level */
+    psIntStorage->u8Level = MICRO_GET_ACTIVE_INT_LEVEL();
+
+    /* Update priority level, but only if it is a more restrictive value */
+    MICRO_SET_ACTIVE_INT_LEVEL_MAX(MICRO_INTERRUPT_WRITE_PRIORITY_VALUE(3));
+
+    /* Restore interrupts */
+    MICRO_RESTORE_INTERRUPTS(u32Store);
+}
+
+/****************************************************************************
+ * NAME:        vMicroIntRestoreState
+ *
+ * DESCRIPTION:
+ * Restore Previous Interrupt State.
+ *
+ * RETURNS:
+ * Nothing.
+ *
+ * NOTES:
+ *
+ ****************************************************************************/
+
+PUBLIC void vMicroIntRestoreState(
+        tsMicroIntStorage      *psIntStorage)
+{
+    // write value direct into register ARM to ARM, no translations required
+    MICRO_SET_ACTIVE_INT_LEVEL(psIntStorage->u8Level);
+}
+
+/****************************************************************************/
+/***        End of file                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific.h b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific.h
new file mode 100755
index 0000000..ff8a0fb
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific.h
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ *
+ * MODULE:              Definitions specific to a particular processor
+ *
+ * DESCRIPTION:
+ * Definitions for a specific processor, i.e. functions that can only be
+ * resolved by op codes
+ *
+ ****************************************************************************
+ *
+ * This software is owned by NXP B.V. and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142, JN5139].
+ * You, and any third parties must reproduce the copyright and warranty notice
+ * and any other legend of ownership on each copy or partial copy of the
+ * software.
+ *
+ * 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.
+ *
+ * Copyright NXP B.V. 2012. All rights reserved
+ *
+ ***************************************************************************/
+
+/****************************************************************************/
+/***        Include files                                                 ***/
+/****************************************************************************/
+
+#define EXPAND1(x) x
+#define EXPAND2(x, y)    EXPAND1(x)y
+#define EXPAND3(x, y, z) EXPAND2(x, y)z
+
+/* Convoluted way to #include <MicroSpecific_JN51xx.h> */
+#undef INCLUDE_NAME
+#define INCLUDE_NAME <EXPAND3(MicroSpecific,JENNIC_CHIP_FAMILY_NAME,.h)>
+#include INCLUDE_NAME
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
+
+
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific_JN518x.h b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific_JN518x.h
new file mode 100755
index 0000000..596fae7
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific_JN518x.h
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ *
+ * MODULE:              Definitions specific to a particular processor
+ *
+ * DESCRIPTION:
+ * Definitions for a specific processor, i.e. functions that can only be
+ * resolved by op codes
+ *
+ ****************************************************************************
+ *
+ * This software is owned by NXP B.V. and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142, JN5139].
+ * You, and any third parties must reproduce the copyright and warranty notice
+ * and any other legend of ownership on each copy or partial copy of the
+ * software.
+ *
+ * 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.
+ *
+ * Copyright NXP B.V. 2012. All rights reserved
+ *
+ ***************************************************************************/
+
+/****************************************************************************/
+/***        Include files                                                 ***/
+/****************************************************************************/
+
+#include "MicroSpecific_arm_sdk2.h"
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
+
+
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific_arm_sdk2.h b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific_arm_sdk2.h
new file mode 100755
index 0000000..1639803
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/MicroSpecific_arm_sdk2.h
@@ -0,0 +1,389 @@
+/*****************************************************************************
+ *
+ * MODULE:              Definitions specific to a particular processor
+ *
+ * DESCRIPTION:
+ * Definitions for a specific processor, i.e. functions that can only be
+ * resolved by op codes
+ *
+ ****************************************************************************
+ *
+ * This software is owned by NXP B.V. and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142, JN5139].
+ * You, and any third parties must reproduce the copyright and warranty notice
+ * and any other legend of ownership on each copy or partial copy of the
+ * software.
+ *
+ * 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.
+ *
+ * Copyright NXP B.V. 2012, 2019. All rights reserved
+ *
+ ***************************************************************************/
+
+#ifndef  MICRO_SPECIFIC_INCLUDED
+#define  MICRO_SPECIFIC_INCLUDED
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+#include <jendefs.h>
+#include "fsl_device_registers.h"
+
+extern void (*isr_handlers[])(void);
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/** @{ Defined system call numbers */
+#define SYSCALL_SEMIHOSTING   						0xAB
+
+#define SEMIHOSTING_WRITE0      					0x04
+#define SEMIHOSTING_READC       0x07
+/** @} */
+
+#define MICRO_INTERRUPT_EXCEPTION_OFFSET            16
+
+// number of bits are defined by the hardware
+#define MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS     __NVIC_PRIO_BITS
+
+// this macro depends on the setting of the priority group in the NVIC, setting G=3 in this case
+#define MICRO_INTERRUPT_MAX_PRIORITY                ((1 << MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS) - 1)
+// half way
+#define MICRO_INTERRUPT_MID_PRIORITY                (MICRO_INTERRUPT_MAX_PRIORITY/2)
+
+// Priority levels in the arm are higher for lower values - B-Semi chips were the other way around
+#define MICRO_INTERRUPT_ELEVATED_PRIORITY           (11)
+#define MICRO_INTERRUPT_MEDIUM_PRIORITY             (12)
+
+// priority/sub priority register 8-bits wide
+// read/write priority
+#define MICRO_INTERRUPT_WRITE_PRIORITY_VALUE(W)     ((W) << (8 - MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS))
+#define MICRO_INTERRUPT_READ_PRIORITY_VALUE(R)      ((R) >> (8 - MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS))
+// read/write sub-priority
+#define MICRO_INTERRUPT_SUBPRIORITY_MASK            ((1  << (8 - MICRO_INTERRUPT_NUMBER_OF_PRIORITY_BITS)) -1)
+#define MICRO_INTERRUPT_SUBPRIORITY_VALUE(S)        ((S) & (MICRO_INTERRUPT_SUBPRIORITY_MASK))
+
+
+extern void vAHI_InterruptSetPriority(uint32 u32Mask, uint8 u8Level);
+extern uint8 u8AHI_InterruptGetPriority(uint32 u32InterruptNumber);
+extern void vAHI_InterruptDisable(uint32 u32EnableMask);
+extern void vAHI_TickTimerIntEnable(bool_t bIntEnable);
+extern void vAHI_InterruptSetActivePriorityLevel(uint8 u8Level);
+extern uint8 u8AHI_InterruptReadActivePriorityLevel(void);
+
+#define MICRO_ENABLE_TICK_TIMER_INTERRUPT();                                \
+        vAHI_TickTimerIntEnable(TRUE);
+
+// use same value as Jennic/BA devices
+#define MICRO_SET_PIC_ENABLE(A)                                             \
+    vAHI_InterruptSetPriority(A, 8);
+
+#define MICRO_CLEAR_PIC_ENABLE(A)                                           \
+    vAHI_InterruptDisable(A)
+
+#define MICRO_SET_PIC_PRIORITY_LEVEL(A,B)                                   \
+    vAHI_InterruptSetPriority(A, B);
+
+#define MICRO_GET_PIC_PRIORITY_LEVEL(A)                                     \
+    u8AHI_InterruptGetPriority(A);
+
+/* Actual macros are instantiated in the respective CMSIS files */
+#define MICRO_ENABLE_INTERRUPTS()             __enable_irq()
+
+#define MICRO_DISABLE_INTERRUPTS()            __disable_irq()
+
+#define MICRO_GET_PRIMASK_LEVEL()            __get_PRIMASK()
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_GET_PRIMASK_LEVEL()                                 \
+ *  ({                                                               \
+ *       register uint32 __u32primaskLevelStore;                     \
+ *       asm volatile ("MRS %[primasklevelstore], PRIMASK;"          \
+ *           :[primasklevelstore] "=r"(__u32primaskLevelStore)       \
+ *           :                                                       \
+ *           );                                                      \
+ *       __u32primaskLevelStore;                                     \
+ *  })
+ */
+#define MICRO_SET_PRIMASK_LEVEL(A)           __set_PRIMASK(A)
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_SET_PRIMASK_LEVEL(A)                                \
+ *  ({                                                               \
+ *       register uint32 __u32primaskLevelStore  = A;                \
+ *       asm volatile ("MSR PRIMASK, %[primasklevelstore];"          \
+ *           :                                                       \
+ *           :[primasklevelstore] "r"(__u32primaskLevelStore)        \
+ *           );                                                      \
+ *  })
+ */
+#define MICRO_GET_ACTIVE_INT_LEVEL()         __get_BASEPRI()
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_GET_ACTIVE_INT_LEVEL()                              \
+ *   ({                                                              \
+ *       register uint32 __u32interruptActiveLevel;                  \
+ *       asm volatile ("MRS %[activelevelstore], BASEPRI;"           \
+ *           :[activelevelstore] "=r"(__u32interruptActiveLevel)     \
+ *           : );                                                    \
+ *       __u32interruptActiveLevel;                                  \
+ *   })
+ */
+#define MICRO_SET_ACTIVE_INT_LEVEL_MAX(A)    __set_BASEPRI_MAX(A)
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_SET_ACTIVE_INT_LEVEL_MAX(A)                         \
+ *  ({                                                               \
+ *     register uint32 __u32interruptLevelStore  = A;                \
+ *       asm volatile ("MSR BASEPRI_MAX, %[intlevelstore];"          \
+ *           :                                                       \
+ *           :[intlevelstore] "r"(__u32interruptLevelStore)          \
+ *           );                                                       \
+ *  })
+ */
+#define MICRO_SET_ACTIVE_INT_LEVEL(A)        __set_BASEPRI(A)
+/* Former implementation : deprecated since CMSIS alternative exists
+ * #define MICRO_SET_ACTIVE_INT_LEVEL(A)                             \
+ *  ({                                                               \
+ *      register uint32 __u32interruptLevelStore  = A;               \
+ *       asm volatile ("MSR BASEPRI, %[intlevelstore];"              \
+ *           :                                                       \
+ *           :[intlevelstore] "r"(__u32interruptLevelStore)          \
+ *           );                                                      \
+ *  })
+ */
+/* Read back PRIMASK status into u32Store variable then disable 
+ * the interrupts */
+#define MICRO_DISABLE_AND_SAVE_INTERRUPTS(u32Store)                  \
+   ({                                                                \
+        u32Store = __get_PRIMASK();                                  \
+        __disable_irq();                                             \
+   })
+/* Former implementation : deprecated since combining CMSIS alternative is 
+ * possible.
+ * #define MICRO_DISABLE_AND_SAVE_INTERRUPTS(u32Store)               \
+ *  ({                                                               \
+ *       asm volatile ("MRS %[primasklevelstore], PRIMASK;"          \
+ *               :[primasklevelstore] "=r"(u32Store)                 \
+ *               :                                                   \
+ *               );                                                  \
+ *       asm volatile ("CPSID I;" : : );                             \
+ *  })
+ */
+#define MICRO_RESTORE_INTERRUPTS(u32Store)  __set_PRIMASK(u32Store)
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_RESTORE_INTERRUPTS(u32Store)                        \
+ *  ({                                                               \
+ *       asm volatile ("MSR PRIMASK, %[primasklevelstore];"          \
+ *               :                                                   \
+ *               :[primasklevelstore] "r"(u32Store)                  \
+ *               );                                                  \
+ *  })
+ */
+#define MICRO_GET_EXCEPTION_STACK_FRAME()   __get_MSP()
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * using AAPCS the parameter (the stack frame) wouuld map to r0
+ * #define MICRO_GET_EXCEPTION_STACK_FRAME()                         \
+ *  {                                                                \
+ *       asm volatile("MRS R0, MSP");                                \
+ *  }
+ */
+
+#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
+/* Count Trailing Zeroes implementation for IAR :
+ * no builtin implementation for IAR, whereas __CLZ exists */
+static inline uint32_t __ctz(uint32_t x)
+{
+    uint32_t res;
+    x = __RBIT(x);
+    res = __CLZ(x);
+    return res;
+}
+#define _CTZ(x)             __ctz(x)
+
+/* Find First Set : returns 0 if no bit set, otherwise returns the order 
+ *  of LSB bit set + 1
+ * __ffs(0) return 0, __ffs(1) returns 1, __ffs(0x8000000) returns 31
+ */
+static inline uint32_t __ffs(uint32_t x) 
+{
+   register uint32 __u32Reg;
+   __u32Reg = _CTZ(x);
+   __u32Reg = __u32Reg == 32 ? 0 : __u32Reg + 1U;
+   return __u32Reg;
+}
+
+#define _FFS(x)            __ffs(x)
+#else  /* __IAR_SYSTEMS_ICC__ */
+/* GCC builtin */
+#define _CTZ(x)             __builtin_ctz(x)
+
+#define _FFS(x)                                     \
+({   register uint32_t __u32Reg, __ret;             \
+   __u32Reg = _CTZ(x);                              \
+   __ret = __u32Reg == 32 ? 0 : __u32Reg + 1U;      \
+   __ret;                                           \
+})
+#endif  /* __IAR_SYSTEMS_ICC__ */
+
+/* Bit Scan Reverse */
+#define MICRO_BSR(x) (31 - _CLZ(x))
+/* Bit Scan Forward */
+#define MICRO_BSF(x) _CTZ(x)
+
+#define MICRO_FFS(x)       _FFS(x)
+
+
+#define FF1(__input)      MICRO_FFS(__input)
+
+#define MICRO_GET_LX()           __get_LR()
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_GET_LX()                               \
+ * ({                                                   \
+ *   register uint32 __u32lxRegister;                   \
+ *   asm volatile ("MOV %[lxRegister], R14;"            \
+ *         :[lxRegister] "=r"(__u32lxRegister)          \
+ *           :                                          \
+ *           );                                         \
+ *       __u32lxRegister;                               \
+ * })
+ */
+#define MICRO_GET_STACK_LEVEL()  __get_SP()
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_GET_STACK_LEVEL()                       \
+ *  ({                                                   \
+ *       register uint32 __u32stackRegister;             \
+ *       asm volatile ("MOV %[stackRegister], SP;"       \
+ *           :[stackRegister] "=r"(__u32stackRegister)   \
+ *           :                                           \
+ *           );                                          \
+ *       __u32stackRegister;                             \
+ *  })
+ */
+
+#define MICRO_TRAP()             __BKPT(0)
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_TRAP()         asm volatile("BKPT 0;")
+ */
+#define MICRO_NOP()              __NOP()
+/* Former implementation : deprecated since CMSIS equivalent exist.
+ * #define MICRO_NOP()          asm volatile ("nop;")
+ */
+
+/* macro using privilege/non-privilege model:
+ * u32reg is the register to return the stack pointer that corresponds to 
+ * the mode we are in: either MSP or PSP.
+ * Note: this macro has chnaged fir IAR compatibility u32reg is the return
+ * register so that R0 is not implicitly the returned value
+ */
+#define MICRO_GET_EXCEPTION_STACK_FRAME_PNPM(u32reg)              \
+     register uint32_t u32reg;                                    \
+     asm volatile("TST LR, #4\n\t"                                \
+                  "ITE EQ\n\t"                                    \
+                  "MRSEQ R0, MSP\n\t"                             \
+                  "MRSNE R0, PSP\n\t");                           \
+     asm volatile ("MOV %0, R0" : "=r" (u32reg) : /* no input */ ); 
+
+/* Interrupt Handler registration - only useful if you're putting the handlers
+ * in RAM */
+
+/* Location of isr_handlers is no longer at a known location, but we can link
+   to it directly instead */
+#define MICRO_SET_INT_HANDLER(INT, FUNC);                                   \
+    isr_handlers[(MICRO_INTERRUPT_EXCEPTION_OFFSET + INT)] = (void *)(FUNC);
+
+#define MICRO_GET_INT_HANDLER(INT)                                          \
+    (isr_handlers[(MICRO_INTERRUPT_EXCEPTION_OFFSET + INT)])
+
+/* Nested interrupt control */
+#define MICRO_INT_STORAGE         tsMicroIntStorage sIntStorage
+#define MICRO_INT_ENABLE_ONLY(A)  vMicroIntEnableOnly(&sIntStorage, A)
+#define MICRO_INT_RESTORE_STATE() vMicroIntRestoreState(&sIntStorage)
+
+/* Exception Handlers */
+#define MICRO_ESR_NUM_RESETISR                    1
+#define MICRO_ESR_NUM_NMI                         2
+#define MICRO_ESR_NUM_HARDFAULT                   3
+#define MICRO_ESR_NUM_MEMMANAGE                   4
+#define MICRO_ESR_NUM_BUSFAULT                    5
+#define MICRO_ESR_NUM_USGFAULT                    6
+// 4 reserved handlers here
+#define MICRO_ESR_NUM_SVCALL                      11
+#define MICRO_ESR_NUM_DEBUGMON                    12
+// 1 reserved handler here
+#define MICRO_ESR_NUM_PENDSV                      14
+#define MICRO_ESR_NUM_SYSTICK                     15
+
+/* Location of exception_handlers is no longer at a known location, but we can link
+   to it directly instead - only useful if you're putting the handlers
+ * in RAM */
+#define MICRO_SET_EXCEPTION_HANDLER(EXCEPTION, FUNC)                        \
+    isr_handlers[EXCEPTION] = (void *)(FUNC);
+
+#define MICRO_GET_EXCEPTION_HANDLER(INT)                                    \
+    (isr_handlers[EXCEPTION])
+
+/* NOP instruction */
+
+
+/* TRAP instruction */
+
+#define MICRO_JUMP_TO_ADDRESS(ADDRESS)                                      \
+   ({                                                                       \
+       register uint32 __u32programAddressStore = ADDRESS | 0x1;            \
+       asm volatile ("BLX %[programAddressStore];"                          \
+           :                                                                \
+           :[programAddressStore] "r"(__u32programAddressStore));           \
+    })
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+/* Nested interrupt control */
+typedef struct
+{
+    uint8 u8Level;
+} tsMicroIntStorage;
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+PUBLIC void vAHI_InitialiseInterruptController(uint32 *pu32InterruptVectorTable);
+
+/* Nested interrupt control */
+PUBLIC void vMicroIntSetGlobalEnable(uint32 u32EnableMask);
+PUBLIC void vMicroIntEnableOnly(tsMicroIntStorage *, uint32 u32EnableMask);
+PUBLIC void vMicroIntRestoreState(tsMicroIntStorage *);
+/* Default Exception Handler */
+PUBLIC void vIntDefaultHandler(void);
+
+PUBLIC void __attribute__((noinline)) vMicroSyscall(volatile uint32 u32SysCallNumber, ...);
+PUBLIC void __attribute__((noinline)) vMicroSemihost(volatile uint32 u32SemihostNumber, ...);
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif  /* MICRO_SPECIFIC_INCLUDED */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
+
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/jendefs.h b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/jendefs.h
new file mode 100755
index 0000000..a54189f
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/framework/Common/jendefs.h
@@ -0,0 +1,344 @@
+/*****************************************************************************
+ *
+ * MODULE:             ALL MODULES
+ *
+ * DESCRIPTION:        The JENNIC standard header file defining extensions to
+ *                     ANSI C standard required by the Jennic C coding standard.
+ *
+ ****************************************************************************
+ *
+ * This software is owned by NXP B.V. and/or its supplier and is protected
+ * under applicable copyright laws. All rights are reserved. We grant You,
+ * and any third parties, a license to use this software solely and
+ * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142, JN5139].
+ * You, and any third parties must reproduce the copyright and warranty notice
+ * and any other legend of ownership on each copy or partial copy of the
+ * software.
+ *
+ * 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.
+ *
+ * Copyright NXP B.V. 2012. All rights reserved
+ *
+ ***************************************************************************/
+
+#ifndef  JENDEFS_INCLUDED
+#define  JENDEFS_INCLUDED
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+
+#include <stdint.h>
+
+#ifndef __KERNEL__
+#include <stdarg.h>
+#include <stdio.h>
+#endif
+
+#ifdef ECOS
+#include <cyg/infra/cyg_type.h>
+#endif
+
+/****************************************************************************/
+/***        Macro Definitions                                             ***/
+/****************************************************************************/
+
+/*--------------------------------------------------------------------------*/
+/*          Compiler Constants for GCC compiler                             */
+/*--------------------------------------------------------------------------*/
+
+#if defined(__GNUC__)
+
+/* The following 5 macros force the compiler to align the specified object  */
+/* on a given byte boundary.                                                */
+/* Example:                                                                 */
+/*     int  iVar  ALIGN_(16);  Force iVar to be aligned on the next         */
+/*                             16 byte boundary                             */
+
+#define PACK      __attribute__ ((packed))        /* align to byte boundary  */
+#define ALIGN_2   __attribute__ ((aligned (2)))   /* 16-bit boundary (2 byte)*/
+#define ALIGN_4   __attribute__ ((aligned (4)))   /* 32-bit boundary (4 byte)*/
+#define ALIGN_8   __attribute__ ((aligned (8)))   /* 64-bit boundary (8 byte)*/
+#define ALIGN_(x) __attribute__ (((aligned (x)))) /* arbitrary alignment     */
+
+/* force an unused variable not to be elided */
+#define USED      __attribute__ ((used))
+
+#if __GNUC__ < 5
+#define INLINE    extern inline
+#else
+#if (defined JENNIC_CHIP_FAMILY_JN516x) || (defined JENNIC_CHIP_FAMILY_JN517x)
+#pragma message ( "Unsupported version of GCC is being used!!" )
+#endif
+#define INLINE    inline
+#endif
+
+#define ALWAYS_INLINE __attribute__((always_inline))
+
+#ifndef WEAK
+#define WEAK      __attribute__ ((weak))
+#endif
+#define ALIAS(f)  __attribute__ ((weak, alias (#f)))
+
+#elif defined(_MSC_VER)
+
+#define PACK
+#define USED
+#define __attribute__(x)
+#define ALWAYS_INLINE
+#define INLINE __inline
+
+
+#elif defined(__IAR_SYSTEMS_ICC__)
+// if compiled for IAR, none of the above defines are required
+#else
+#error "Unsupported compiler"
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Alignment masks                                                 */
+/*--------------------------------------------------------------------------*/
+
+#define ALIGNMENT_MASK_4_BYTE     ((uint32)0x00000003)
+#define ALIGNMENT_MASK_16_BYTE    ((uint32)0x0000000F)
+
+/* Test for alignment on an arbitrary byte boundary - TRUE if aligned */
+
+#define IS_ALIGNED(addr, mask) (((((uint32)addr) & mask) ? FALSE : TRUE))
+
+/*--------------------------------------------------------------------------*/
+/*          Boolean Constants                                               */
+/*--------------------------------------------------------------------------*/
+
+#if !defined FALSE && !defined TRUE
+#define TRUE            (1)   /* page 207 K+R 2nd Edition */
+#define FALSE           (0)
+#endif /* !defined FALSE && #if !defined TRUE */
+
+/*     Note that WINDOWS.H also defines TRUE and FALSE                 */
+
+/*--------------------------------------------------------------------------*/
+/*          Null pointers                                                   */
+/*--------------------------------------------------------------------------*/
+
+/* NULL data pointer */
+#if !defined NULL
+#define NULL                    ( (void *) 0 )
+#endif
+
+/* NULL routine pointer */
+#if !defined RNULL
+#define RNULL                   ((void *) 0 ())
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for setting/clearing bits efficiently                    */
+/*--------------------------------------------------------------------------*/
+
+#define U8_CLR_BITS( P, B )   (( *(uint8 *)P ) &= ~( B ))
+#define U8_SET_BITS( P, B )   (( *(uint8 *)P ) |=  ( B ))
+#define U16_CLR_BITS( P, B )  (( *(uint16 *)P ) &= ~( B ))
+#define U16_SET_BITS( P, B )  (( *(uint16 *)P ) |=  ( B ))
+#define U32_CLR_BITS( P, B )  (( *(uint32 *)P ) &= ~( B ))
+#define U32_SET_BITS( P, B )  (( *(uint32 *)P ) |=  ( B ))
+#define U64_CLR_BITS( P, B )  (( *(uint64 *)P ) &= ~( B ))
+#define U64_SET_BITS( P, B )  (( *(uint64 *)P ) |=  ( B ))
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for obtaining maximum/minimum values                     */
+/*--------------------------------------------------------------------------*/
+#ifndef MAX
+#define MAX(A,B)                ( ( ( A ) > ( B ) ) ? ( A ) : ( B ) )
+#endif
+#ifndef MIN
+#define MIN(A,B)                ( ( ( A ) < ( B ) ) ? ( A ) : ( B ) )
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Number of bits in quantities                                    */
+/*--------------------------------------------------------------------------*/
+
+#define BITS_PER_U32            (32)
+#define BITS_PER_U16            (16)
+#define BITS_PER_U8             (8)
+#define BITS_PER_NIBBLE         (4)
+
+/*--------------------------------------------------------------------------*/
+/*          Masking macros                                                  */
+/*--------------------------------------------------------------------------*/
+
+#define U8_LOW_NIBBLE_MASK      (0x0F)
+#define U8_HIGH_NIBBLE_MASK     (0xF0)
+
+#define U16_LOW_U8_MASK         (0x00FF)
+#define U16_HIGH_U8_MASK        (0xFF00)
+
+#define U32_LOWEST_U8_MASK      (0x000000FFL)
+#define U32_LOW_U8_MASK         (0x0000FF00L)
+#define U32_HIGH_U8_MASK        (0x00FF0000L)
+#define U32_HIGHEST_U8_MASK     (0xFF000000L)
+
+#define U32_LOWEST_U16_MASK     (0x0000FFFFL)
+#define U32_HIGHEST_U16_MASK    (0xFFFF0000L)
+
+#define U64_LOWEST_U32_MASK     (0x00000000FFFFFFFFLL)
+#define U64_HIGHEST_U32_MASK    (0xFFFFFFFF00000000LL)
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for extracting uint8s from a uint16                      */
+/*--------------------------------------------------------------------------*/
+
+/* NOTE: U16_UPPER_U8 is only safe for an unsigned U16 as >> fills with the sign bit for signed variables */
+#define U16_UPPER_U8( x )      ((uint8) ((x) >> BITS_PER_U8))
+#define U16_LOWER_U8( x )      ((uint8) (((x) & U16_LOW_U8_MASK)))
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for extracting uint8s from a uint32                      */
+/*--------------------------------------------------------------------------*/
+
+#define U32_HIGHEST_U8( x ) ((uint8)(((x) & U32_HIGHEST_U8_MASK) >> (BITS_PER_U16 + BITS_PER_U8)))
+
+#define U32_HIGH_U8( x ) ((uint8)( ( ( x ) & U32_HIGH_U8_MASK ) >> BITS_PER_U16 ))
+
+#define U32_LOW_U8( x ) ((uint8)( ( ( x ) & U32_LOW_U8_MASK ) >> BITS_PER_U8 ))
+
+#define U32_LOWEST_U8( x ) ((uint8)( ( ( x ) & U32_LOWEST_U8_MASK ) ))
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for extracting uint16s from a uint32                     */
+/*--------------------------------------------------------------------------*/
+
+#define U32_UPPER_U16( x )     ((uint16)( ( ( x ) & U32_HIGHEST_U16_MASK ) >> ( BITS_PER_U16 ) ))
+#define U32_LOWER_U16( x )     ((uint16)( ( ( x ) & U32_LOWEST_U16_MASK ) ))
+
+/*--------------------------------------------------------------------------*/
+/*          Macros for extracting uint32s from a uint64                     */
+/*--------------------------------------------------------------------------*/
+
+#define U64_UPPER_U32( x )     ((uint32)( ( ( x ) & U64_HIGHEST_U32_MASK ) >> ( BITS_PER_U32 ) ))
+#define U64_LOWER_U32( x )     ((uint32)( ( ( x ) & U64_LOWEST_U32_MASK ) ))
+
+/*--------------------------------------------------------------------------*/
+/*         Macros for assembling byte sequences into various word sizes     */
+/*--------------------------------------------------------------------------*/
+
+/* B0 - LSB, B3 - MSB */
+
+#ifdef HOST_PROCESSOR_BIG_ENDIAN
+/* BIG ENDIAN DEFINITIONS */
+#define BYTE_ORDER_32(B3, B2, B1, B0)   ((B0) + (B1<<8) + (B2<<16) + (B3<<24))
+
+#define BYTE_ORDER_24(B2, B1, B0)       ((B0) + (B1<<8) + (B2<<16))
+
+#define BYTE_ORDER_16(B1, B0)           (uint16)(((B0) + (B1<<8)))
+
+#define BYTE_ORDER_8(B0)                (B0)
+
+#define BYTE_ORDER_4(B0)                (B0)
+#else
+/* LITTLE ENDIAN DEFINITIONS */
+#define BYTE_ORDER_32(B3, B2, B1, B0)   ((B3) + (B2<<8) + (B1<<16) + (B0<<24))
+
+#define BYTE_ORDER_24(B2, B1, B0)       ((B2) + (B1<<8) + (B0<<16))
+
+#define BYTE_ORDER_16(B1, B0)           (uint16)(((B1) + (B0<<8)))
+
+#define BYTE_ORDER_8(B0)                (B0)
+
+#define BYTE_ORDER_4(B0)                (B0)
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Storage classes                                                 */
+/*--------------------------------------------------------------------------*/
+
+#if !defined PUBLIC
+#define PUBLIC
+#endif
+
+#if !defined MODULE
+#define MODULE
+#endif
+
+#if !defined PRIVATE
+#define PRIVATE static
+#endif
+
+#if !defined BANKED
+#define BANKED
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Useful macro for variables that are not currently referenced             */
+/* Prevents compiler warnings and should not produce any code               */
+/*--------------------------------------------------------------------------*/
+
+#define VARIABLE_INTENTIONALLY_NOT_REFERENCED(x) (x=x);
+#define CONST_POINTER_INTENTIONALLY_NOT_REFERENCED(p) (*p);
+#define CONST_VARIABLE_INTENTIONALLY_NOT_REFERENCED(x) (x);
+
+/*--------------------------------------------------------------------------*/
+/* Offset of field m in a struct s                                          */
+/*--------------------------------------------------------------------------*/
+
+#if !defined(__GNUC__) && !defined(ECOS) && !defined(offsetof)
+#define offsetof(type, tag)     ( (int)&( (type *)0 )->tag )
+#endif
+
+/*--------------------------------------------------------------------------*/
+/*          Diagnostics                                                     */
+/*--------------------------------------------------------------------------*/
+
+/****************************************************************************/
+/***        Type Definitions                                              ***/
+/****************************************************************************/
+
+    #ifndef __cplusplus /* microsoft specific */
+        #ifndef bool /* Seems to need this in for certain M$ builds*/
+            typedef int                     bool;     /* boolean type */
+        #endif
+    #endif
+
+    typedef uint8_t                 BOOL_T;     /* boolean type nothing to do with C++ */
+    typedef uint8_t                 bool_t;     /* boolean type nothing to do with C++ */
+
+    typedef int8_t                  int8;
+    typedef int16_t                 int16;
+    typedef int32_t                 int32;
+    typedef int64_t                 int64;
+    typedef uint8_t                 uint8;
+    typedef uint16_t                uint16;
+    typedef uint32_t                uint32;
+    typedef uint64_t                uint64;
+
+    typedef char *                  string;
+
+    typedef volatile uint8          u8Register;
+    typedef volatile uint16         u16Register;
+    typedef volatile uint32         u32Register;
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#endif  /* JENDEFS_INCLUDED */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
+
+
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/DK6/radio.h b/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/DK6/radio.h
new file mode 100755
index 0000000..a081ddb
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/DK6/radio.h
@@ -0,0 +1,808 @@
+/*
+ * @brief Radio driver
+ *
+ * @note
+ * Copyright 2019 NXP
+ *
+ * @par
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * LPC products.  This software is supplied "AS IS" without any warranties of
+ * any kind, and NXP Semiconductors and its licensor disclaim any and
+ * all warranties, express or implied, including all implied warranties of
+ * merchantability, fitness for a particular purpose and non-infringement of
+ * intellectual property rights.  NXP Semiconductors assumes no responsibility
+ * or liability for the use of the software, conveys no license or rights under any
+ * patent, copyright, mask work right, or any other intellectual property rights in
+ * or to any products. NXP Semiconductors reserves the right to make changes
+ * in the software without notification. NXP Semiconductors also makes no
+ * representation or warranty that such application will be suitable for the
+ * specified use without further testing or modification.
+ *
+ * @par
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, under NXP Semiconductors' and its
+ * licensor's relevant copyrights in the software, without fee, provided that it
+ * is used in conjunction with NXP Semiconductors microcontrollers.  This
+ * copyright, permission, and disclaimer notice must appear in all copies of
+ * this code.
+ */
+
+#ifndef __RADIO_H_
+#define __RADIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+/****************************************************************************/
+/***        Macro/Type Definitions                                        ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***    Radio driver version (XYYY): X major version, YYY minor version   ***/
+/****************************************************************************/
+#define RADIO_VERSION (2088)
+
+/****************************************************************************/
+/***    Radio calibration data record version                             ***/
+/****************************************************************************/
+#define RADIO_CAL_RECORD_VERSION (1001)
+
+/****************************************************************************/
+/***    Radio driver int time values									  ***/
+/***	RADIO_INIT_TIME_WITH_KMOD_INIT_US full init time with Kmod cal    ***/
+/***	This init is done only when KMOD cal results are not available    ***/
+/***	in flash for the current initialization temperature. As results   ***/
+/***	are valid in a [-40...+40C] temperature range around the cal      ***/
+/***	temperature, only 4 full calibration are needed in the whole live ***/
+/***	of the chip and this init time is quite never reached.            ***/
+/***	RADIO_INIT_TIME_WITHOUT_KMOD_INIT_US full init time without Kmod  ***/
+/***	calibration. This is the typical coldstart radio init time		  ***/
+/***	RADIO_INIT_TIME_WITH_RETENTION_US init time when using retention  ***/
+/***	In that case calibrations are not run and parameters kept in      ***/
+/***	in retention flops are used instead. This is a the typical warm   ***/
+/***	start init time.                                                  ***/
+/****************************************************************************/
+
+#define RADIO_FULL_INIT_FIRST_TIME (80300) // no record available and all cal to be done because TCur far from TCAL ATE
+#define RADIO_FULL_INIT_TIME (85500) // record available but all cal to be done because TCur far from TCAL ATE
+#define RADIO_INIT_ALL_CAL_IN_FLASH (850) // record available, no cal to be done and TCur close to TCAL ATE
+#define RADIO_INIT_NO_DCO_CAL_IN_FLASH (13500) // no record available, DCO cal only and TCur close to TCAL ATE
+#define RADIO_INIT_TIME_WITH_RETENTION_US (250) // can use retention values
+#define RADIO_RECAL_TIME_ALL_CAL_IN_FLASH_US (750) // recal with cal available in flash for TCur
+#define RADIO_RECAL_TIME_NO_CAL_IN_FLASH_US (86800) // recal with cal data not available in flash, all call to be done
+#define RADIO_RECAL_TIME_NO_DCO_CAL_IN_FLASH_US (16100) // recal with DCO cal to do
+#define RADIO_RECAL_TIME_NORECAL_US (8) // recal when not needed
+#define RADIO_GET_NEXT_RECAL_DURATION (20) // u32Radio_Get_Next_Recal_Duration max execution time
+
+/****************************************************************************/
+/***    Number of bytes of the u8AppliData buffer                         ***/
+/***    See vRadio_Save_ApplicationData_Retention                  ***/
+/***    and vRadio_Restore_Retention_ApplicationData               ***/
+/****************************************************************************/
+#define APP_DATA_RET_NB_BYTES (114)
+#define ADD_DATA_RET_NB_BITS (906)
+
+
+
+/****************************************************************************/
+/***    Local defined values        									  ***/
+/****************************************************************************/
+#define RADIO_MODE_LOPOWER          (0)
+#define RADIO_MODE_HITXPOWER        (1)
+
+#define RADIO_INIT_INITCAL			(0)
+#define RADIO_INIT_DEF_VAL			(1)
+#define RADIO_INIT_RETENTION		(2)
+#define RADIO_INIT_FORCE_CAL		(3)
+
+/****************************************************************************/
+/***	Values to be used as u32RadioMode parameter                       ***/
+/***	for vRadio_RadioInit API                                   ***/
+/*** 	RADIO_MODE_STD_USE_INITCAL default init mode to use. in this mode ***/
+/***	the radio init will be done in standard lowpower mode and the     ***/
+/***	calibrations will be launched automatically based on temperature  ***/
+/***	deviation since last calibration. Calibration will also be done   ***/
+/***	if no retention values are available or if it is the first init.  ***/
+/***	Other values are for test or special needs.                       ***/
+/***	RADIO_MODE_STD_USE_DEF_VAL will force using default values for    ***/
+/***	all parameters. No calibration is done.                           ***/
+/***	RADIO_MODE_STD_USE_RETENTION will force usage of retention values ***/
+/***	without any validity test nor temperature control                 ***/
+/***    RADIO_MODE_STD_USE_FORCE_CAL will force calibration, ignoring any ***/
+/***	retention values and even if temperature has not changed          ***/
+/***	RADIO_MODE_HTXP_... have the same meaning but configure radio in  ***/
+/***	high tx power mode.                                               ***/
+/****************************************************************************/
+#define RADIO_MODE_STD_USE_INITCAL		((RADIO_MODE_LOPOWER << 8) | RADIO_INIT_INITCAL)
+#define RADIO_MODE_STD_USE_DEF_VAL      ((RADIO_MODE_LOPOWER << 8) | RADIO_INIT_DEF_VAL)
+#define RADIO_MODE_STD_USE_RETENTION	((RADIO_MODE_LOPOWER << 8) | RADIO_INIT_RETENTION)
+#define RADIO_MODE_STD_USE_FORCE_CAL	((RADIO_MODE_LOPOWER << 8) | RADIO_INIT_FORCE_CAL)
+#define RADIO_MODE_HTXP_USE_INITCAL		((RADIO_MODE_HITXPOWER << 8) | RADIO_INIT_INITCAL)
+#define RADIO_MODE_HTXP_USE_DEF_VAL		((RADIO_MODE_HITXPOWER << 8) | RADIO_INIT_DEF_VAL)
+#define RADIO_MODE_HTXP_USE_RETENTION	((RADIO_MODE_HITXPOWER << 8) | RADIO_INIT_RETENTION)
+#define RADIO_MODE_HTXP_USE_FORCE_CAL	((RADIO_MODE_HITXPOWER << 8) | RADIO_INIT_FORCE_CAL)
+
+/****************************************************************************/
+/***    Local defined values        									  ***/
+/****************************************************************************/
+#define TX_REGULAR 0
+#define TX_PROP_1  1
+#define TX_PROP_2  2
+#define TX_BLE_1MB 3
+#define TX_BLE_2MB 4
+#define TX_UNDEFINED 0xFF
+
+#define RX_DETECTOR_ONLY 0
+#define RX_ENABLE_LUT    1
+#define RX_BLE_1MB       3
+#define RX_BLE_2MB       4
+#define RX_UNDEFINED 0xFF
+
+/****************************************************************************/
+/***	Values to be used as u32RadioStandard parameter                   ***/
+/***	for vRadio_Standard_Init API                               ***/
+/***	RADIO_STANDARD_ZIGBEE_REGULAR standard Zigbee Mode                ***/
+/***	RADIO_STANDARD_ZIGBEE_PROP_1 Zigbee mode with proprietary mode 1  ***/
+/***	Tx configuration (soft spread reduction)                          ***/
+/***	RADIO_STANDARD_ZIGBEE_PROP_2 Zigbee mode with proprietary mode 2  ***/
+/***	Tx configuration (more agressive spread reduction)                ***/
+/***	RADIO_STANDARD_ZIGBEE_REGULAR Zigbee Mode using LUT mode for AGC  ***/
+/***	control. Test only.                                               ***/
+/***	RADIO_STANDARD_ZIGBEE_PROP_1_LUT and _PROP_2_LUT LUT AGC control  ***/
+/***	and Tx mode1/2                                                    ***/
+/***	RADIO_STANDARD_BLE_1MB BLE 1 Mbps mode (for TX and RX)			  ***/
+/***	RADIO_STANDARD_BLE_2MB BLE 2 Mbps mode (for TX and RX)			  ***/
+/***	RADIO_STANDARD_BLE_RX1MB_TX2MB and RADIO_STANDARD_BLE_RX2MB_TX1MB ***/
+/***	are BLE configuration with different RX/TX bitrates               ***/
+/****************************************************************************/
+
+#define RADIO_STANDARD_ZIGBEE_REGULAR ((RX_DETECTOR_ONLY << 8) | (TX_REGULAR))
+#define RADIO_STANDARD_ZIGBEE_PROP_1  ((RX_DETECTOR_ONLY << 8) | (TX_PROP_1))
+#define RADIO_STANDARD_ZIGBEE_PROP_2  ((RX_DETECTOR_ONLY << 8) | (TX_PROP_2))
+#define RADIO_STANDARD_ZIGBEE_REGULAR_LUT ((RX_ENABLE_LUT << 8) | (TX_REGULAR))
+#define RADIO_STANDARD_ZIGBEE_PROP_1_LUT  ((RX_ENABLE_LUT << 8) | (TX_PROP_1))
+#define RADIO_STANDARD_ZIGBEE_PROP_2_LUT  ((RX_ENABLE_LUT << 8) | (TX_PROP_2))
+#define RADIO_STANDARD_BLE_1MB ((RX_BLE_1MB << 8) | (TX_BLE_1MB))
+#define RADIO_STANDARD_BLE_2MB ((RX_BLE_2MB << 8) | (TX_BLE_2MB))
+#define RADIO_STANDARD_BLE_RX1MB_TX2MB ((RX_BLE_1MB << 8) | (TX_BLE_2MB))
+#define RADIO_STANDARD_BLE_RX2MB_TX1MB ((RX_BLE_2MB << 8) | (TX_BLE_1MB))
+
+/****************************************************************************/
+
+/****************************************************************************/
+/*** radio driver types/macros/prototypes                                 ***/
+/****************************************************************************/
+
+/****************************************************************************/
+/***    Type definition for vRadio_SetChannelStandards function			  ***/
+/****************************************************************************/
+typedef enum
+{
+    E_RADIO_TX_MODE_STD    = TX_REGULAR,
+    E_RADIO_TX_MODE_PROP_1 = TX_PROP_1,
+    E_RADIO_TX_MODE_PROP_2 = TX_PROP_2,
+    E_RADIO_TX_MODE_RESET  = TX_UNDEFINED
+} teRadioTxMode;
+
+/* RSSI reported by XCV in 1/4 dBm step */
+#define RADIO_MAX_RSSI_REPORT       40
+#define RADIO_MIN_RSSI_REPORT     -400
+
+/****************************************************************************/
+/*** radio driver API prototypes                                          ***/
+/****************************************************************************/
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_RadioInit
+ *
+ * DESCRIPTION:
+ * Radio driver initialisation function.
+ *
+ * PARAMETERS:
+ * uint32_t u32RadioMode: use one of the defined values described above
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_RadioInit(uint32_t u32RadioMode);
+/****************************************************************************
+ *
+ * NAME:       vRadio_RadioDeInit
+ *
+ * DESCRIPTION:
+ * Radio driver de-initialisation function.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_RadioDeInit(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Standard_Init
+ *
+ * DESCRIPTION:
+ * Set radio parameters for the specified standard in the corresponding
+ * parameter bank of the radio HW block. There is one bank of each radio standard.
+ *
+ * PARAMETERS:
+ * uint32_t u32RadioStandard: use one of the defined values described above
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_Standard_Init(uint32_t u32RadioStandard);
+
+/****************************************************************************
+ *
+ * NAME:       u8Radio_GetEDfromRSSI
+ *
+ * DESCRIPTION:
+ * Returns Energy Detect value calculated from RSSI value
+ *
+ * PARAMETERS:
+ * int16_t i16RSSIval: RSSI value expressed in fourth of dBm (2'complement signed value)
+ *
+ * RETURNS:
+ * uint8_t ED in [0..255] range
+ *
+ ****************************************************************************/
+uint8_t u8Radio_GetEDfromRSSI(int16_t i16RSSIval);
+
+/****************************************************************************
+ *
+ * NAME:       u32Radio_RadioModesAvailable
+ *
+ * DESCRIPTION:
+ * Returns returns bit combination of available radio modes (1 for LOPOWER and/or 2 for HIGHPOWER)
+ * Currently only LOPOWER is implemented so always returns 1
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * uint32_t bit combination of radio modes
+ *
+ ****************************************************************************/
+uint32_t u32Radio_RadioModesAvailable(void);
+
+/****************************************************************************
+ *
+ * NAME:       u32Radio_RadioGetVersion
+ *
+ * DESCRIPTION:
+ * Returns radio driver version. This function can be used to check the version
+ * of the radio driver embedded in the library used for the link against the value
+ * defined above as RADIO_VERSION and detected possible mismatch between this
+ * header file and the driver version itself.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * uint32_t radio version
+ *
+ ****************************************************************************/
+uint32_t u32Radio_RadioGetVersion(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Temp_Update
+ *
+ * DESCRIPTION:
+ * Provides the radio driver with the current temperature value.
+ *
+ * PARAMETERS:
+ * int16_t s16Temp: Temperature expressed in half of degre C (2'complement 16 bit value)
+ * 					For example 40 (or 0x28) for 20 degre Celsius
+ * 					or -40 (0xFFD8) for -20 degre Celsius
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_Temp_Update(int16_t s16Temp);
+
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_ConfigCalFlashUsage
+ *
+ * DESCRIPTION:
+ * Configure usage of flash record for radio calibration parameter.
+ * For example, this function can be used to temporarily disable write of
+ * calibration results in flash if there is a risk that the power can be removed
+ * during next radio init (e.g. energy harvesting application).
+ *
+ * PARAMETERS:
+ * bool bWriteToFlash: Allows radio_init/recal to write calibration results from flash.
+ * 					   If set to false, after new calibration, new results will not be
+ * 					   saved in flash for future re-use.
+ * 					   Default value is true.
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_ConfigCalFlashUsage(bool bWriteToFlash);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Save_ApplicationData_Retention
+ *
+ * DESCRIPTION:
+ * Save application data into radio retention registers.
+ *
+ * PARAMETERS:
+ * uint8_t *u8AppliData: Table of 8bit values to be stored in retention registers
+ * 						 It is the responsibility of the application that data
+ * 						 are compacted in the table as a bit steam of maximum
+ * 						 ADD_DATA_RET_NB_BITS bits over APP_DATA_RET_NB_BYTES bytes
+ * 						 See above for ADD_DATA_RET_NB_BITS and APP_DATA_RET_NB_BYTES
+ * 						 values.
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_Save_ApplicationData_Retention(uint8_t *u8AppliData);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Restore_Retention_ApplicationData
+ *
+ * DESCRIPTION:
+ * Save application data into radio retention registers.
+ *
+ * PARAMETERS:
+ * uint8_t *u8AppliData: Table of 8bit values to restore the table saved using
+ * 						 vRadio_Save_ApplicationData_Retention API
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+void vRadio_Restore_Retention_ApplicationData( uint8_t *u8AppliData);
+
+
+
+
+
+/****************************************************************************/
+/***        Public Functions (to be called by LL or MAC layer)            ***/
+/****************************************************************************/
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Recal
+ *
+ * DESCRIPTION:
+ * This function is to be called when it is possible (from the LL or MAC perspective)
+ * to re-calibrate the radio. This function will check the latest temperature
+ * value provided by the last vRadio_Temp_Update API, and if the difference between
+ * this temperature and the temperature used for the latest calibration is higher than
+ * 40 degre C, a new calibration is done and this new temperature is saved as the
+ * temperature of the latest calibration.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None
+ *
+ ****************************************************************************/
+bool vRadio_Recal(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_RFT1778_bad_crc
+ *
+ * DESCRIPTION:
+ * This function is to be called by the ZB MAC when a CRC error has been detected.
+ * This avoid lockup of the radio in some cases.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * int : 1 if lockup condition has been detected and unlocked, 0 otherwise.
+ *
+ ****************************************************************************/
+int vRadio_RFT1778_bad_crc(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_AD_control
+ *
+ * DESCRIPTION:
+ * When RX antenna diversity is enabled,  function is to be called by the ZB MAC
+ * when PRE_STATE_1 state is reached.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_AD_control(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_LockupCheckAndAbortRadio
+ *
+ * DESCRIPTION:
+ * This function is to be called by the BLE LL when an error has been detected.
+ * This avoid lockup of the radio in some cases.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_LockupCheckAndAbortRadio(void);
+
+/****************************************************************************
+ *
+ * The next 7 APIs are dedicated to the MAC layer for its internal needs.
+ *
+ ****************************************************************************/
+/* There are 3 sets of operating 'standards', which affects the frequency
+   response of the radio:
+     normal
+     proprietary 1
+     proprietary 2
+
+   For compliance it may be necessary to select different standards for
+   different channels, and this function allows that to be configured.
+   Note that this function has the AppApi prefix rather than the MMAC
+   prefix; we have traditionally provided customer-facing functions with
+   the AppApi prefix and this avoids a level of indirection via the shim
+   layer. */
+void vRadio_SetComplianceLimits(int8_t i8TxMaxPower,
+                                       int8_t i8TxMaxPowerCh26);
+void vRadio_SetChannelStandards(teRadioTxMode eNewTxMode,
+                                       teRadioTxMode eNewTxModeCh26);
+void vRadio_InitialiseRadioStandard(void);
+void vRadio_UpdateRadioStandard(uint8_t u8NewChannel);
+void vRadio_SetChannelAndPower(uint8_t u8Channel, int8_t i8TxPower_dBm);
+int8_t i8Radio_GetTxPowerLevel_dBm(void);
+
+int16_t i16Radio_GetRSSI(uint32_t u32DurationSymbols,bool bAverage, uint8_t *u8antenna);
+int16_t i16Radio_GetNbRSSISync(void);
+int16_t i16Radio_GetNbRSSISyncCor(uint8_t u8rate);
+int8_t i8Radio_GetLastPacketRSSI();
+int16_t i16Radio_BoundRssiValue(int16_t value);
+
+/****************************************************************************
+ *
+ * These APIs are dedicated to the BLE LL to reset BLE HW block if needed
+ * and to execute patch at end of RX process
+ *
+ ****************************************************************************/
+
+/* BLE reset APIs */
+void vRadio_BLE_ResetOn(void);
+void vRadio_BLE_ResetOff(void);
+
+void vRadio_remove_patch_ISR(void);
+void vRadio_SingleRX_AgcReadyPatch(void);
+void vRadio_MultiRX_AgcReadyPatch(void);
+void vRadio_Enable_AgcReadyPatch(void);
+void vRadio_Disable_AgcReadyPatch(void);
+
+
+
+/****************************************************************************
+ *
+ * The next 2 APIs are for temporary usage and are to be removed when XTAL init
+ * will be put out of radio driver
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_SkipXTALInit
+ *
+ * DESCRIPTION:
+ * Set an internal flag in the radio driver to skip any XTAL 32MHz handling
+ * by the radio driver. With this flag set, the radio driver does not start
+ * nor Trim the 32M XO.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_SkipXTALInit(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_EnableXTALInit
+ *
+ * DESCRIPTION:
+ * Reset the internal flag in the radio driver used to skip any XTAL 32MHz handling
+ * by the radio driver. With this flag cleared, the radio driver checks if 32M XO is
+ * running and start it if not already started. It also trim the 32M XO.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_EnableXTALInit(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_ActivateXtal32MRadioBiasing
+ *
+ * DESCRIPTION:
+ * Reset Radio HW block and switch XTAL32M to radio biasing control.
+ * ASSUMES THAT XTAL32M IS ALREADY SETUP, TRIMMED AND RUNNING UNDER PMC BIASING
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_ActivateXtal32MRadioBiasing(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_DisableZBRadio
+ *
+ * DESCRIPTION:
+ * Disable ZB radio block.
+ * This API needs to be called before vRadio_RadioInit and vRadio_ActivateXtal32MRadioBiasing.
+ * When ZB radio block is disabled, it is not reset and clocks are not enabled for this
+ * HW block.
+ * ONLY ONE OF vRadio_DisableZBRadio or vRadio_DisableBLERadio can be called.
+ * IF BOTH APIS ARE CALLED, ONLY THE FIRST ONE HAS EFFECT.
+ * IT CANNOT BE REVERSED. NEED HW RESET TO USE ZB RADIO AGAIN.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_DisableZBRadio(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_DisableBLERadio
+ *
+ * DESCRIPTION:
+ * Disable BLE radio block.
+ * This API needs to be called before vRadio_RadioInit and vRadio_ActivateXtal32MRadioBiasing.
+ * When BLEB radio block is disabled, clocks are not enabled for this HW block.
+ * ONLY ONE OF vRadio_DisableZBRadio or vRadio_DisableBLERadio can be called.
+ * IF BOTH APIS ARE CALLED, ONLY THE FIRST ONE HAS EFFECT.
+ * IT CANNOT BE REVERSED. NEED HW RESET TO USE BLE RADIO AGAIN.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_DisableBLERadio(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_EnableBLEFastTX
+ *
+ * DESCRIPTION:
+ * Enable keeping G1 and G2 on to give more time between RX and TX.
+ * On ES2MF it is also possible to keep PLL group using bKeepPll parameter.
+ *
+ * PARAMETERS:
+ * bool bKeepPll: when true, PLL group is kept active (ES2MF only, no effect
+ *                otherwise)
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_EnableBLEFastTX(bool bKeepPll);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_DisableBLEFastTX
+ *
+ * DESCRIPTION:
+ * Disable keeping G1 and G2 on to give more time between RX and TX.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_DisableBLEFastTX(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_Disable_DCO_DAC
+ *
+ * DESCRIPTION:
+ * Disable keeping DCO DAC always on. By default vRadio_ActivateXtal32MRadioBiasing
+ * and vRadio_RadioInit force DCO DAC to on state to ensure it is ready to operate
+ * at the very beginning of RX process. If no RX is foreseen before next powerdown or sleep
+ * DCO DAC can be disable to reduce power consumption.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_Disable_DCO_DAC(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_ZBtoBLE
+ *
+ * DESCRIPTION:
+ * Change some settings needed when switching from ZB to BLE.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_ZBtoBLE(void);
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_BLEtoZB
+ *
+ * DESCRIPTION:
+ * Change some settings needed when switching from BLE to ZB.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_BLEtoZB(void);
+
+/****************************************************************************
+ *
+ * NAME:       u16Radio_Get_Next_Recal_Duration
+ *
+ * DESCRIPTION:
+ * Returns estimate time duration of the next calibration. This estimate is
+ * based on the last temperature provided by the vRadio_Temp_Update,
+ * the temperature of the last calibration and the operations to do for this
+ * calibrations.
+ * If no calibration is needed or vRadio_RadioInit has not bee called before,
+ * the API returns 0. Otherwise it returns the estimated duration in us.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+uint32_t u32Radio_Get_Next_Recal_Duration(void);
+
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_AntennaDiversityTxRxEnable
+ *
+ * DESCRIPTION:
+ * Enables Antenna Diversity for Tx and/or Rx.
+ *
+ * PARAMETERS:
+ * bool bRxEnabled: true to enable Rx AD, false to disable it
+ * bool bTxEnabled: true to enable Tx AD, false to disable it
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_AntennaDiversityTxRxEnable(bool bRxEnabled, bool bTxEnabled);
+/****************************************************************************
+ *
+ * NAME:       vRadio_AntennaDiversityConfigure
+ *
+ * DESCRIPTION:
+ * Configure some AD setings.
+ *
+ * PARAMETERS:
+ * uint16_t rssi_thr: RSSI threshold to switch antenna (10bit fourth dBm in two complement)
+ *                    Default value is 0x278 (-98dBm)
+ * uint8_t rx_timer: Timer before to check received power again (4us steps, 4bits)
+ *                   Default value is 0x8 (32us)
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_AntennaDiversityConfigure(uint16_t rssi_thr, uint8_t rx_timer);
+/****************************************************************************
+ *
+ * NAME:       vRadio_AntennaDiversitySwitch
+ *
+ * DESCRIPTION:
+ * Toggle antenna selection.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_AntennaDiversitySwitch(void);
+/****************************************************************************
+ *
+ * NAME:       u8Radio_AntennaDiversityStatus
+ *
+ * DESCRIPTION:
+ * Returns current selected antenna.
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * Selected antenna (0 or 1) on uint8_t .
+ *
+ ****************************************************************************/
+uint8_t u8Radio_AntennaDiversityStatus(void);
+
+
+/****************************************************************************
+ *
+ * NAME:       vRadio_SetBLEdpTopEmAddr
+ *
+ * DESCRIPTION:
+ * Configure LL_EM_BASE_ADDRESS of BLEMODEM parameter.
+ *
+ * PARAMETERS:
+ * uint32_t em_addr: EM address.
+ *
+ * RETURNS:
+ * None.
+ *
+ ****************************************************************************/
+void vRadio_SetBLEdpTopEmAddr(uint32_t em_addr);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RADIO_H_ */
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/lib/libRadio.a b/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/lib/libRadio.a
new file mode 100755
index 0000000..b4e3ae9
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/framework/XCVR/lib/libRadio.a
Binary files differ
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/ieee-802.15.4/lib/libMiniMac.a b/third_party/nxp/K32W061DK6/middleware/wireless/ieee-802.15.4/lib/libMiniMac.a
new file mode 100755
index 0000000..4c5bd12
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/ieee-802.15.4/lib/libMiniMac.a
Binary files differ
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/ieee-802.15.4/uMac/Include/MMAC.h b/third_party/nxp/K32W061DK6/middleware/wireless/ieee-802.15.4/uMac/Include/MMAC.h
new file mode 100755
index 0000000..dba5a96
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/ieee-802.15.4/uMac/Include/MMAC.h
@@ -0,0 +1,251 @@
+/*
+* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
+* Copyright 2016-2019 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef MICRO_MAC_H
+#define MICRO_MAC_H
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+
+/****************************************************************************/
+/***        Include Files                                                 ***/
+/****************************************************************************/
+#include "jendefs.h"
+
+/****************************************************************************/
+/***        Macro/Type Definitions                                        ***/
+/****************************************************************************/
+
+typedef struct
+{
+    uint32 u32L;  /**< Low word */
+    uint32 u32H;  /**< High word */
+} tsExtAddr;
+
+typedef union
+{
+    uint16    u16Short;
+    tsExtAddr sExt;
+} tuAddr;
+
+/* Structure for building a MAC frame, where the MAC header alignment is
+   handled by the hardware */
+typedef struct
+{
+    uint8           u8PayloadLength;
+    uint8           u8SequenceNum;
+    uint16          u16FCF;
+    uint16          u16DestPAN;
+    uint16          u16SrcPAN;
+    tuAddr          uDestAddr;
+    tuAddr          uSrcAddr;
+    uint16          u16FCS;
+    uint16          u16Unused;
+    union
+    {
+        uint8     au8Byte[127]; /* Payload as both bytes and words */
+        uint32    au32Word[32];
+    } uPayload;
+} tsMacFrame;
+
+/* Structure for building a PHY frame, where the MAC header format is
+   undefined */
+typedef struct
+{
+    uint8           u8PayloadLength;
+    uint8           au8Padding[3];
+    union
+    {
+        uint8     au8Byte[127]; /* Payload as both bytes and words */
+        uint32    au32Word[32];
+    } uPayload;
+} tsPhyFrame;
+
+typedef struct
+{
+    uint8  u8SecurityLevel;
+    uint8  u8KeyIdMode;
+    uint8  u8KeyIndex;
+    bool_t bPassedSecurity;
+} tsSecurity;
+
+typedef struct
+{
+    tsMacFrame     sFrameBody;
+    tsSecurity     sSecurityData;
+    uint32         u32Timestamp;
+    uint8          u8LinkQuality;
+    uint8          u8Msq;
+} tsRxFrameFormat;
+
+/* Options for reception, to pass to vMMAC_StartReceive. User should select
+   one from each pair of options, and logical OR the options together */
+typedef enum
+{
+    /* Receive start time: now or delayed */
+    E_MMAC_RX_START_NOW        = 0x0002,
+    E_MMAC_RX_DELAY_START      = 0x0003,
+
+    /* Timing alignment for auto ack transmission: normal or aligned to
+       backoff clock (used in CAP period in beacon networks) */
+    E_MMAC_RX_ALIGN_NORMAL     = 0x0000,
+    E_MMAC_RX_ALIGNED          = 0x0004,
+
+    /* Wait for auto ack and retry: don't use or use */
+    E_MMAC_RX_NO_AUTO_ACK      = 0x0000,
+    E_MMAC_RX_USE_AUTO_ACK     = 0x0008,
+
+    /* Malformed packets: reject or accept */
+    E_MMAC_RX_NO_MALFORMED     = 0x0000,
+    E_MMAC_RX_ALLOW_MALFORMED  = 0x0400,
+
+    /* Frame Check Sequence errors: reject or accept */
+    E_MMAC_RX_NO_FCS_ERROR     = 0x0000,
+    E_MMAC_RX_ALLOW_FCS_ERROR  = 0x0200,
+
+    /* Address matching: enable or disable */
+    E_MMAC_RX_NO_ADDRESS_MATCH = 0x0000,
+    E_MMAC_RX_ADDRESS_MATCH    = 0x0100
+
+} teRxOption;
+
+/* Options for transmission, to pass to vMMAC_StartMacTransmit or
+   vMMAC_StartPhyTransmit. User should select one from each set of options,
+   and logical OR the options together */
+typedef enum
+{
+    /* Transmit start time: now or delayed */
+    E_MMAC_TX_START_NOW       = 0x02,
+    E_MMAC_TX_DELAY_START     = 0x03,
+
+    /* Wait for auto ack and retry: don't use or use */
+    E_MMAC_TX_NO_AUTO_ACK     = 0x00,
+    E_MMAC_TX_USE_AUTO_ACK    = 0x08,
+
+    /* Clear channel assessment: don't use or use, plus option to align to
+       backoff clock */
+    E_MMAC_TX_NO_CCA          = 0x00,
+    E_MMAC_TX_USE_CCA         = 0x10,
+    E_MMAC_TX_USE_CCA_ALIGNED = 0x20
+
+} teTxOption;
+
+/* Flags for receive status, as returned by u32MMAC_GetRxErrors */
+typedef enum
+{
+    E_MMAC_RXSTAT_ERROR     = 0x01, /* Frame check sequence error */
+    E_MMAC_RXSTAT_ABORTED   = 0x02, /* Reception aborted by user */
+    E_MMAC_RXSTAT_MALFORMED = 0x20  /* Frame was malformed */
+} teRxStatus;
+
+/* Flags for transmit status, as returned by u32MMAC_GetTxErrors */
+typedef enum
+{
+    E_MMAC_TXSTAT_CCA_BUSY = 0x01, /* Channel wasn't free */
+    E_MMAC_TXSTAT_NO_ACK   = 0x02, /* Ack requested but not seen */
+    E_MMAC_TXSTAT_ABORTED  = 0x04, /* Transmission aborted by user */
+    E_MMAC_TXSTAT_TXTO     = 0x20, /* Radio transmission timeout */
+    E_MMAC_TXSTAT_TXPCTO   = 0x40  /* Modem transmission timeout */
+} teTxStatus;
+
+/* Flags for interrupt status, as returned to handler registered with
+   vMMAC_EnableInterrupts and as used in the mask passed to
+   vMMAC_ConfigureInterruptSources, u32MMAC_PollInterruptSource,
+   u32MMAC_PollInterruptSourceUntilFired */
+typedef enum
+{
+    E_MMAC_INT_TX_COMPLETE  = 0x01, /* Transmission attempt has finished */
+    E_MMAC_INT_RX_HEADER    = 0x02, /* MAC header has been received */
+    E_MMAC_INT_RX_COMPLETE  = 0x04  /* Complete frame has been received */
+} teIntStatus;
+
+/* CCA mode to use when transmitting. Use with vMMAC_SetCcaMode(). Default is
+   E_MMAC_CCAMODE_ENERGY */
+typedef enum
+{
+    E_MMAC_CCAMODE_ENERGY            = 0x01, /* Energy above threshold */
+    E_MMAC_CCAMODE_CARRIER           = 0x02, /* Carrier sense */
+    E_MMAC_CCAMODE_ENERGY_OR_CARRIER = 0x03  /* Either energy or carrier */
+} teCcaMode;
+
+/****************************************************************************/
+/***        Exported Functions                                            ***/
+/****************************************************************************/
+/* Initialisation */
+PUBLIC void vMMAC_Enable(void);
+PUBLIC void vMMAC_Disable(void);
+PUBLIC void vMMAC_ConfigureRadio(void);
+PUBLIC void vMMAC_SetChannel(uint8 u8Channel);
+PUBLIC void vMMAC_SetChannelAndPower(uint8 u8Channel, int i8TxPower);
+PUBLIC int8 i8MMAC_GetTxPowerLevel(void);
+
+/* Interrupt control */
+PUBLIC void vMMAC_EnableInterrupts(void (*prHandler)(uint32 u32Mask));
+PUBLIC void vMMAC_RegisterPhyIntHandler(void (*prHandler)(uint32 u32Mask));
+PUBLIC void vMMAC_ConfigureInterruptSources(uint32 u32Mask);
+PUBLIC uint32 u32MMAC_PollInterruptSource(uint32 u32Mask);
+PUBLIC uint32 u32MMAC_PollInterruptSourceUntilFired(uint32 u32Mask);
+
+/* Miscellaneous */
+PUBLIC uint32 u32MMAC_GetTime(void);
+PUBLIC void vMMAC_RadioOff(void);
+PUBLIC void vMMAC_RadioToOffAndWait(void);
+PUBLIC void vMMAC_SetCutOffTimer(uint32 u32CutOffTime, bool_t bEnable);
+PUBLIC void vMMAC_SynchroniseBackoffClock(bool_t bEnable);
+PUBLIC void vMMAC_GetMacAddress(tsExtAddr *psMacAddr);
+PUBLIC uint8 u8MMAC_EnergyDetect(uint32 u32DurationSymbols);
+PUBLIC uint32 u32MMAC_GetPhyState(void);
+PUBLIC void vMMAC_RxCtlUpdate(uint32 u32NewValue);
+PUBLIC void vMMAC_AbortRadio(void);
+PUBLIC void vMMAC_SetHighPowerOptions(void);
+PUBLIC void vMMAC_PromiscuousMode(bool_t bPromiscuous);
+PUBLIC void vMMAC_WriteCcaThreshold(uint8 u8CcaThreshold);
+PUBLIC uint8 u8MMAC_ReadCcaThreshold(void);
+
+/* Receive */
+PUBLIC void vMMAC_SetRxAddress(uint32 u32PanId, uint16 u16Short,
+                               tsExtAddr *psMacAddr);
+PUBLIC void vMMAC_SetRxPanId(uint32 u32PanId);
+PUBLIC void vMMAC_SetRxShortAddr(uint16 u16Short);
+PUBLIC void vMMAC_SetRxExtendedAddr(tsExtAddr *psMacAddr);
+PUBLIC void vMMAC_SetRxStartTime(uint32 u32Time);
+PUBLIC void vMMAC_StartMacReceive(tsMacFrame *psFrame, teRxOption eOptions);
+PUBLIC void vMMAC_StartPhyReceive(tsPhyFrame *psFrame, teRxOption eOptions);
+PUBLIC void vMMAC_SetRxFrame(tsRxFrameFormat *pRxFrame);
+PUBLIC void vMMAC_SetRxProm(uint32_t u32Prom);
+PUBLIC bool_t bMMAC_RxDetected(void);
+PUBLIC uint32 u32MMAC_GetRxErrors(void);
+PUBLIC uint32 u32MMAC_GetRxTime(void);
+PUBLIC uint8 u8MMAC_GetRxLqi(uint8 *pu8Msq);
+
+/* Transmit */
+PUBLIC void vMMAC_SetTxParameters(uint8 u8Attempts, uint8 u8MinBE,
+                                  uint8 u8MaxBE, uint8 u8MaxBackoffs);
+PUBLIC void vMMAC_SetTxStartTime(uint32 u32Time);
+PUBLIC void vMMAC_SetCcaMode(teCcaMode eCcaMode);
+PUBLIC void vMMAC_StartMacTransmit(tsMacFrame *psFrame, teTxOption eOptions);
+PUBLIC void vMMAC_StartPhyTransmit(tsPhyFrame *psFrame, teTxOption eOptions);
+PUBLIC void vMMAC_SetTxPend(bool_t bTxPend);
+PUBLIC uint32 u32MMAC_GetTxErrors(void);
+PUBLIC bool_t bMMAC_PowerStatus(void);
+
+/****************************************************************************/
+/***        Exported Variables                                            ***/
+/****************************************************************************/
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* #ifndef MICRO_MAC_H */
+
+/****************************************************************************/
+/***        END OF FILE                                                   ***/
+/****************************************************************************/
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h
new file mode 100755
index 0000000..df7d876
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h
@@ -0,0 +1,379 @@
+/*
+* Copyright 2019-2020 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _APP_OTA_H
+#define _APP_OTA_H
+
+/*!=================================================================================================
+\file       app_ota.h
+\brief      This is the header file for the ota module
+==================================================================================================*/
+
+/*==================================================================================================
+Include Files
+==================================================================================================*/
+#include <openthread/coap.h>
+#include <openthread/thread.h>
+/*==================================================================================================
+Public macros
+==================================================================================================*/
+#define OTA_CLIENT_URI_PATH                     "otaclient"
+#define OTA_SERVER_URI_PATH                     "otaserver"
+
+#ifndef OTA_USE_NWK_DATA
+    #define OTA_USE_NWK_DATA                    FALSE
+#endif
+
+#if OTA_USE_NWK_DATA
+    #define GET_OTA_ADDRESS(otInst)             otThreadGetRloc(otInst)
+#else
+    #define GET_OTA_ADDRESS(otInst)             otThreadGetMeshLocalEid(otInst)
+#endif
+
+/* ota params */
+#define gOtaFileIdentifierNo_c                  0x0BEEF11E
+#define gOtaManufacturerCode_c                  0x04, 0x10
+#define gOtaManufacturerCodeNo_c                0x1004
+#define gOtaCurrentImageType_c                  0x00, 0x00
+#define gOtaCurrentImageTypeNo_c                0x0000
+#define gOtaCurrentFileVersion_c                0x05, 0x40, 0x03, 0x40
+#define gOtaCurrentFileVersionNo_c              0x40034005
+#define gOtaHardwareVersion_c                   0x21, 0x24
+#define gOtaHardwareVersionNo_c                 0x2421
+
+#define gOtaMaxBlockDataSize_c                  64 /* 60 bytes */
+
+#define gOtaServer_MaxSimultaneousClients_c     0x0A
+
+/*==================================================================================================
+Public type definitions
+==================================================================================================*/
+
+/* ota commands */
+typedef enum
+{
+    gOtaCmd_ImageNotify_c          =       0x00,
+    gOtaCmd_QueryImageReq_c,
+    gOtaCmd_QueryImageRsp_c,
+    gOtaCmd_BlockReq_c,
+    gOtaCmd_BlockRsp_c,
+    gOtaCmd_UpgradeEndReq_c,
+    gOtaCmd_UpgradeEndRsp_c,
+    gOtaCmd_ServerDiscovery_c,
+    gOtaCmd_Invalid_c              =       0xFF
+} gOtaCmd_t;
+
+/*! Ota status */
+typedef enum otaStatus_tag
+{
+    gOtaStatus_Success_c                       = 0x00,
+    gOtaStatus_Failed_c                        = 0x01,
+    gOtaStatus_InvalidInstance_c               = 0x02,
+    gOtaStatus_InvalidParam_c                  = 0x03,
+    gOtaStatus_NotPermitted_c                  = 0x04,
+    gOtaStatus_NotStarted_c                    = 0x05,
+    gOtaStatus_NoMem_c                         = 0x06,
+    gOtaStatus_UnsupportedAttr_c               = 0x07,
+    gOtaStatus_EmptyEntry_c                    = 0x08,
+    gOtaStatus_InvalidValue_c                  = 0x09,
+    gOtaStatus_AlreadyStarted_c                = 0x0A,
+    gOtaStatus_NoTimers_c                      = 0x0B,
+    gOtaStatus_NoUdpSocket_c                   = 0x0C,
+	gOtaStatus_FlashError_c                    = 0x0D,
+    gOtaStatus_TransferTypeNotSupported_c      = 0x0E,
+    gOtaStatus_EntryNotFound_c                 = 0xFF
+} otaStatus_t;
+
+/* OTA File Status */
+typedef enum otaFileStatus_tag
+{
+    gOtaFileStatus_Success_c          = 0x00, /* Success Operation */
+    gOtaFileStatus_NotAuthorized_c    = 0x7E, /* Server is not authorized to upgrade the client. */
+    gOtaFileStatus_Abort_c            = 0x95, /* Failed case when a client or a server decides to abort the upgrade process. */
+    gOtaFileStatus_InvalidImage_c     = 0x96, /* Invalid OTA upgrade image. */
+    gOtaFileStatus_ServerBusy_c       = 0x97, /* Server is busy, retry later. */
+    gOtaFileStatus_NoImageAvailable_c = 0x98, /* No OTA upgrade image available for a particular client. */
+    gOtaFileStatus_ImageTooLarge_c    = 0x99, /* Received OTA image is larger than the available storage space. */
+    gOtaFileStatus_InvalidOperation_c = 0x9A, /* Client encountered an invalid operation error. */
+    gOtaFileStatus_InvalidParameter_c = 0x9B, /* Client encountered an invalid parameter error. */
+    gOtaFileStatus_ExtFlashError_c    = 0x9C, /* Client encountered an external flash error. */
+    gOtaFileStatus_ClientError_c      = 0x9D /* Generic client error. */
+} otaFileStatus_t;
+
+typedef enum otaTransferType_tag
+{
+    gOtaUnicast_c = 0x00,
+    gOtaMulticast_c
+} otaTransferType_t;
+
+/* ota command format */
+typedef struct otaCommand_tag
+{
+    uint8_t commandId;
+    uint8_t pPayload[1];
+} otaCommand_t;
+
+/* ota image notify command format*/
+typedef struct otaServerCmd_ImageNotify_tag
+{
+    uint8_t commandId;
+    uint8_t transferType;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t imageSize[4];
+    uint8_t fileSize[4];
+    uint8_t fileVersion[4];
+    uint8_t serverDownloadPort[2];
+    uint8_t fragmentSize[2];
+} otaServerCmd_ImageNotify_t;
+
+/* ota query image req command format*/
+typedef struct otaCmd_QueryImageReq_tag
+{
+    uint8_t commandId;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+    uint8_t hardwareVersion[2];
+} otaCmd_QueryImageReq_t;
+
+/* ota query image rsp - success */
+typedef struct otaCmd_QueryImageRspSuccess_tag
+{
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+    uint8_t fileSize[4];
+    uint8_t serverDownloadPort[2];
+} otaCmd_QueryImageRspSuccess_t;
+
+/* ota query image rsp - wait */
+typedef struct otaCmd_QueryImageRspWait_tag
+{
+    uint8_t currentTime[4];
+    uint8_t requestTime[4];
+} otaCmd_QueryImageRspWait_t;
+
+/* ota query image rsp command format*/
+typedef struct otaCmd_QueryImageRsp_tag
+{
+    uint8_t commandId;
+    uint8_t status;
+    union
+    {
+        otaCmd_QueryImageRspSuccess_t success;
+        otaCmd_QueryImageRspWait_t wait;
+    } data;
+} otaCmd_QueryImageRsp_t;
+
+/* ota block req command format*/
+typedef struct otaCmd_BlockReq_tag
+{
+    uint8_t commandId;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+    uint8_t fileOffset[4];
+    uint8_t maxDataSize;
+} otaCmd_BlockReq_t;
+
+/* ota block rsp - success */
+typedef struct otaCmd_BlockRspSuccess_tag
+{
+    uint8_t fileVersion[4];
+    uint8_t fileOffset[4];
+    uint8_t dataSize;
+    uint8_t pData[1];
+} otaCmd_BlockRspSuccess_t;
+
+/* ota block rsp - wait for data */
+typedef struct otaCmd_BlockRspWaitForData_tag
+{
+    uint8_t currentTime[4];
+    uint8_t requestTime[4];
+} otaCmd_BlockRspWaitForData_t;
+
+/* ota block rsp command format*/
+typedef struct otaCmd_BlockRsp_tag
+{
+    uint8_t commandId;
+    uint8_t status;
+    union
+    {
+        otaCmd_BlockRspSuccess_t success;
+        otaCmd_BlockRspWaitForData_t wait;
+    } data;
+} otaCmd_BlockRsp_t;
+
+/* ota upgrade end req command format*/
+typedef struct otaCmd_UpgradeEndReq_tag
+{
+    uint8_t commandId;
+    uint8_t status;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+} otaCmd_UpgradeEndReq_t;
+
+/* ota upgrade end rsp - success */
+typedef struct otaCmd_UpgradeEndRspSuccess_tag
+{
+    uint8_t currentTime[4];     /* milliseconds */
+    uint8_t upgradeTime[4];     /* milliseconds */
+    uint8_t fileVersion[4];
+} otaCmd_UpgradeEndRspSuccess_t;
+
+/* ota upgrade end rsp - wait for data */
+typedef struct otaCmd_UpgradeEndRspWaitForData_tag
+{
+    uint8_t currentTime[4];
+    uint8_t requestTime[4];
+} otaCmd_UpgradeEndRspWaitForData_t;
+
+/* ota upgrade end rsp command format*/
+typedef struct otaCmd_UpgradeEndRsp_tag
+{
+    uint8_t commandId;
+    uint8_t status;
+    union
+    {
+        otaCmd_UpgradeEndRspSuccess_t success;
+        otaCmd_UpgradeEndRspWaitForData_t wait;
+    } data;
+} otaCmd_UpgradeEndRsp_t;
+
+/* ota upgrade server discovery command format */
+typedef struct otaCmd_ServerDiscovery_tag
+{
+    uint8_t commandId;
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+} otaCmd_ServerDiscovery_t;
+
+/* ota file header */
+typedef struct otaFileHeader_tag
+{
+    uint8_t fileIdentifier[4];
+    uint8_t headerVersion[2];
+    uint8_t headerLength[2];
+    uint8_t fieldControl[2];
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t fileVersion[4];
+    uint8_t stackVersion[2];
+    uint8_t headerString[32];
+    uint8_t totalImageSize[4];
+    uint8_t minHwVersion[2];
+    uint8_t maxHwVersion[2];
+} otaFileHeader_t;
+
+typedef struct otaFileSubElement_tag
+{
+    uint8_t id[2];
+    uint8_t length[4];
+} otaFileSubElement_t;
+
+/* OTA Server Serial Protocol */
+
+/* Image notify command format */
+typedef struct otaServer_ImageNotify_tag
+{
+    uint8_t deviceId[2];
+    uint8_t manufacturerCode[2];
+    uint8_t imageType[2];
+    uint8_t imageSize[4];
+    uint8_t fileSize[4];
+    uint8_t fileVersion[4];
+} otaServer_ImageNotify_t;
+
+/* OTA unicast and multicast finished percentage information structures */
+typedef struct otaServerUnicastClientEntry_tag
+{
+    uint16_t clientId;
+    uint8_t percentage;
+} otaServerUnicastClientEntry_t;
+
+typedef struct otaServerPercentageInfo_tag
+{
+	uint8_t otaType;
+	uint8_t multicastPercentage;
+	otaServerUnicastClientEntry_t unicastEntry[gOtaServer_MaxSimultaneousClients_c];
+} otaServerPercentageInfo_t;
+
+/* ota server operation mode */
+typedef enum
+{
+    gOtaServerOpMode_Reserved_c = 0,
+    gOtaServerOpMode_Standalone_c,           /* requires an external memory or a reserved region of internal MCU flash to keep the client image */
+    gOtaServerOpMode_Dongle_c,               /* without internal/external memory capacity */
+} otaServerOpMode_t;
+
+/*==================================================================================================
+Public global variables declarations
+==================================================================================================*/
+
+extern otCoapResource gOTA_CLIENT_URI_PATH;
+extern otCoapResource gOTA_SERVER_URI_PATH;
+
+/*==================================================================================================
+Public function prototypes
+==================================================================================================*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!*************************************************************************************************
+\public
+\fn  otaStatus_t OtaServerInit(taskMsgQueue_t *pMsgQueue)
+\brief  Initialize OTA server application
+
+\param  [in]    pMsgQueue   Pointer to task message queue
+
+\return   otaStatus_t
+ ***************************************************************************************************/
+otaStatus_t OtaServerInit(otInstance *pOtInstance);
+
+/*!*************************************************************************************************
+\public
+\fn  otaStatus_t OtaServer_StartOta()
+\brief  Start OTA process
+
+\param  [in]    otaType        Type of OTA process (unicast or multicast)
+\param  [in]    pFilePath      Path to binary
+
+\return         otaStatus_t    Status of the operation
+ ***************************************************************************************************/
+otaStatus_t OtaServer_StartOta(uint8_t otaType, const char *pFilePath);
+
+/*!*************************************************************************************************
+\fn     otaResult_t OtaServer_StopOta(void)
+\brief  Process Stop OTA command received from an external application.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+otaStatus_t OtaServer_StopOta(void);
+
+/*!*************************************************************************************************
+\fn     void OtaServer_CheckTime(void)
+\brief  This function is used to check if a timer callback for OTA needs to be called.
+***************************************************************************************************/
+void OtaServer_CheckTime(void);
+
+/*!*************************************************************************************************
+\fn     void OtaServer_GetOtaStatus(otaServerPercentageInfo_t *pData)
+\brief  This function is used to check the status of the OTA transfer.
+
+\param  [in]    pData        Pointer to output structure
+***************************************************************************************************/
+void OtaServer_GetOtaStatus(otaServerPercentageInfo_t *pData);
+
+#ifdef __cplusplus
+}
+#endif
+
+/*================================================================================================*/
+#endif  /*  _APP_OTA_H */
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c
new file mode 100755
index 0000000..8c7792a
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c
@@ -0,0 +1,2081 @@
+/*
+* Copyright 2019-2020 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+/*!=================================================================================================
+\file       app_ota_server.c
+\brief      This is a public source file for the OTA server module
+==================================================================================================*/
+
+/*==================================================================================================
+Include Files
+==================================================================================================*/
+
+/* Application */
+#include <openthread/udp.h>
+#include <openthread/coap.h>
+#include <openthread/instance.h>
+#include <openthread/error.h>
+#include <openthread/platform/alarm-milli.h>
+#include <openthread/platform/alarm-micro.h>
+#include <openthread/ip6.h>
+#include <openthread/random_noncrypto.h>
+
+#include "app_ota.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "network_utils.h"
+
+/*==================================================================================================
+Private macros
+==================================================================================================*/
+
+#ifndef OTA_SERVER_DEFAULT_PORT
+    #define OTA_SERVER_DEFAULT_PORT (61630)
+#endif
+
+#ifndef gOtaServer_DefaultTransferType_c
+    #define gOtaServer_DefaultTransferType_c             gOtaMulticast_c
+#endif
+
+#define gOtaServer_MinDelayForEndRequestMs_c             20000
+#define gOtaServer_MaxDelayForEndRequestMs_c             40000
+#define gOtaServer_InvalidClientId_c                     0xFFFF
+#define gOtaServer_MaxOtaImages_c                        0x01
+
+#define gOtaServer_DelayForNextRequestMs_c               60000   /* 60 seconds */
+#define gOtaServer_ClientSessionExpirationMs_c           30000   /* 30 seconds */
+
+#define gOtaServer_MulticastInterval_c                   500     /* 500 miliseconds */
+#define gOtaServer_MulticastImgNtfInterval_c             1000    /* 1 second */
+#define gOtaServer_MulticastImgNtfRetransmissions_c      4
+#define gOtaServer_MulticastBlockRspInterval_c           300
+#define gOtaServer_MulticastUpgradeEndDelay_c            1000
+#define gOtaServer_MulticastNoOfBlockRsps_c              0
+#define gOtaServer_MulticastWindowSize_c                 32      /* Must be multiple of 8 */
+#define gOtaServer_MulticastWindowRetries_c              0
+#define gOtaServer_MulticastAckTimeout_c                 300
+
+#define gOtaFileVersionPolicies_Upgrade_c       (1<<0)
+#define gOtaFileVersionPolicies_Reinstall_c     (1<<1)
+#define gOtaFileVersionPolicies_Downgrade_c     (1<<2)
+
+#define gOtaFileVersionDefaultPolicies_c         gOtaFileVersionPolicies_Upgrade_c | \
+                                                 gOtaFileVersionPolicies_Reinstall_c | \
+                                                 gOtaFileVersionPolicies_Downgrade_c
+
+/*==================================================================================================
+Private type definitions
+==================================================================================================*/
+/* ota server multicast state: */
+typedef enum
+{
+    gOtaServerMulticastState_NotInit_c = 0,
+    gOtaServerMulticastState_Idle_c,
+    gOtaServerMulticastState_SendImgNtf_c,
+    gOtaServerMulticastState_GenBlockReq_c,
+    gOtaServerMulticastState_WaitForAck_c,
+    gOtaServerMulticastState_SendUpgradeEnd_c,
+    gOtaServerMulticastState_ResetMulticast_c
+} otaServerMulticastState_t;
+
+/* ota server multicast state: */
+typedef enum
+{
+	otaServerClientImageTypeREED = 0x0000,
+	otaServerClientImageTypeED   = 0x0001,
+	otaServerClientImageTypeLPED = 0x0002
+} otaServerClientImageType;
+
+typedef struct otaServerSetup_tag
+{
+    otInstance *pOtInstance;
+    otUdpSocket *pOtaUdpSrvSocket;
+    bool_t            isActive;
+    uint8_t           fileVersionPolicy;
+    otaTransferType_t transferType;
+    uint16_t          downloadPort;
+    /* Multicast parameters */
+    otaServerMulticastState_t multicastState;
+    uint8_t ackBitmask[4];
+    uint32_t currentWindowOffset;
+    uint8_t multicastNoOfImgNtf;
+    uint8_t multicastNoOfBlockRsp;
+    uint8_t multicastNoOfWindowRetries;
+    uint16_t multicastManufacturerCode;
+    uint16_t multicastImageType;
+    uint32_t multicastImageSize;
+    uint32_t multicastFileVersion;
+} otaServerSetup_t;
+
+typedef struct otaServerImageList_tag
+{
+    uint16_t manufCode;
+    uint16_t imageType;
+    uint32_t fileSize;
+    uint32_t imageAddr;
+    uint32_t fileVersion;
+    bool_t isValidEntry;
+} otaServerImageList_t;
+
+typedef struct otaClientInfo_tag
+{
+    otIp6Address  remoteAddr;
+    otIp6Address  sourceAddr;
+    uint16_t  port;
+    uint32_t  timeStamp;
+    uint32_t  dataLen;
+    uint8_t   pData[1];
+} otaClientInfo_t;
+
+typedef struct otaClientSessionInfo_tag
+{
+    otIp6Address remoteAddr;
+    uint32_t timeStamp;
+} otaClientSessionInfo_t;
+
+typedef void ( *otaTmrCallback ) ( void *param );
+
+/*==================================================================================================
+Private function prototypes
+==================================================================================================*/
+/* OTA Server Coap command handlers */
+static void OtaServer_ClientProcess(otaClientInfo_t *pOtaClientInfo);
+static void OtaServer_CmdProcess(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_CmdCheck(uint8_t otaCommand, uint32_t dataLen);
+static otaStatus_t OtaServer_QueryImageReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_BlockReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_UpgradeEndReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_ServerDiscoveryHandler(otaClientInfo_t *pOtaClientInfo);
+static void OtaServer_CoapCb(void *pCtx, otMessage *pMsg, const otMessageInfo *pMsgInfo);
+
+/* OTA Server Coap commands */
+static otaStatus_t OtaServer_SendImageNotifty(otaServer_ImageNotify_t *pImgNtf, otIp6Address *pAddr);
+static otaStatus_t OtaServer_CoapSendImageNotify(otaServer_ImageNotify_t *pImageNotify, otIp6Address *pDestAddr);
+static otaStatus_t OtaServer_CoapSendRsp(otaClientInfo_t *pOtaClientInfo, uint8_t *pData, uint32_t pDataLen);
+static otaStatus_t OtaServer_CoapSendRspWaitAbortData(otaClientInfo_t *pOtaClientInfo, uint8_t status,
+        uint32_t delayInMs);
+
+/* OTA Server utility functions */
+static void OtaServer_SetTimeCallback(otaTmrCallback pFunc, void *pData, uint32_t setTime);
+static void OtaServer_StopTimeCallback(void);
+static bool_t OtaServer_IsClientValid(uint16_t clientId);
+static bool_t OtaServer_RemoveClientFromPercentageInfo(uint16_t clientId);
+static void OtaServer_ResetPercentageInfo(void);
+static otaStatus_t OtaServer_CheckClientSessionTable(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServer_HandleBlockSocket(bool_t onOff);
+
+/* OTA Server standalone functions: */
+static void OtaServer_InitStandaloneOpMode(void);
+static uint8_t OtaServerStandalone_ValidateImage(uint16_t manufCode, uint16_t imageType, uint32_t fileVersion, bool_t serialProtocol);
+static uint8_t OtaServerStandalone_KeepImageInfo(uint16_t manufCode, uint16_t imageType, uint32_t fileVersion, uint32_t fileSize);
+static otaStatus_t OtaServerStandalone_QueryImageReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServerStandalone_BlockReqHandler(otaClientInfo_t *pOtaClientInfo);
+static otaStatus_t OtaServerStandalone_ServerDiscoveryHandler(otaClientInfo_t *pOtaClientInfo);
+
+/* OTA Server Multicast */
+static otaStatus_t OtaServer_InitMulticast(void *pParam);
+static void OtaServer_MulticastMngr(void *pParam);
+static void OtaServer_MulticastTimeoutCb(void *pParam);
+static otaStatus_t OtaServer_SendImgNtf(void *pParam);
+static otaStatus_t OtaServer_ProcessAckTimeout(void *pParam);
+static otaStatus_t OtaServer_MulticastUpgradeEnd(void *pParam);
+static otaStatus_t OtaServer_GenerateBlockReq(void *pParam);
+static void OtaServer_ResetMulticastModule(void *pParam);
+
+/*==================================================================================================
+Private global variables declarations
+==================================================================================================*/
+/* Ota server setup parameters */
+static otaServerSetup_t mOtaServerSetup = {.pOtaUdpSrvSocket = NULL,
+                                           .downloadPort = OTA_SERVER_DEFAULT_PORT,
+                                           .multicastState = gOtaServerMulticastState_NotInit_c,
+                                           .transferType = gOtaServer_DefaultTransferType_c
+                                          };
+
+/* Ota server standalone informations: */
+static otaServerImageList_t mOtaServerImageList[gOtaServer_MaxOtaImages_c];
+static uint32_t mOtaServerTempImageIdx = gOtaServer_MaxOtaImages_c;
+
+/* Ota server percentages information */
+static otaServerPercentageInfo_t mOtaServerPercentageInformation;
+
+static otaClientSessionInfo_t mOtaClientSessionInfoTable[gOtaServer_MaxSimultaneousClients_c];
+static otUdpSocket mOtaUdpSrvSocket;
+
+static char binary_file_path[255];
+/*==================================================================================================
+Public global variables declarations
+==================================================================================================*/
+otCoapResource gOTA_CLIENT_URI_PATH = {.mUriPath = OTA_CLIENT_URI_PATH, .mHandler = NULL/*OtaServer_CoapCb*/, .mContext = NULL, .mNext = NULL };
+otCoapResource gOTA_SERVER_URI_PATH = {.mUriPath = OTA_SERVER_URI_PATH, .mHandler = NULL/*OtaClient_CoapCb*/, .mContext = NULL, .mNext = NULL };
+
+/* Parameters for simple timer callback */
+uint32_t setMilliTime = 0;
+otaTmrCallback gpFunction = NULL;
+void *gpParameter = NULL;
+bool_t callbackIsSet = false;
+
+/*==================================================================================================
+Public functions
+==================================================================================================*/
+/*!*************************************************************************************************
+\fn     void OtaServer_CheckTime(void)
+\brief  This function is used to check if a timer callback for OTA needs to be called.
+***************************************************************************************************/
+void OtaServer_CheckTime(void)
+{
+    if((otPlatAlarmMilliGetNow() > setMilliTime) && (callbackIsSet == true) && (setMilliTime != 0))
+    {
+        setMilliTime = 0;
+
+        if(gpFunction != NULL)
+        {
+            callbackIsSet = false;
+            gpFunction(gpParameter);
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\fn     otaStatus_t OtaServerInit(taskMsgQueue_t *pMsgQueue)
+\brief  Initialize OTA server application.
+
+\param  [in]    pMsgQueue      Pointer to task message queue
+
+\return         otaStatus_t    Status of the operation
+ ***************************************************************************************************/
+otaStatus_t OtaServerInit
+(
+    otInstance *pOtInstance
+)
+{
+    otaStatus_t otaStatus = gOtaStatus_Success_c;
+
+    if (pOtInstance == NULL)
+    {
+        otaStatus = gOtaStatus_InvalidInstance_c;
+    }
+
+    if (otaStatus == gOtaStatus_Success_c)
+    {
+        /* Register Services in COAP */
+        mOtaServerSetup.pOtInstance = pOtInstance;
+        otCoapStart(mOtaServerSetup.pOtInstance, OT_DEFAULT_COAP_PORT);
+        gOTA_CLIENT_URI_PATH.mContext = mOtaServerSetup.pOtInstance;
+        gOTA_CLIENT_URI_PATH.mHandler = OtaServer_CoapCb;
+        otCoapAddResource(mOtaServerSetup.pOtInstance, &gOTA_CLIENT_URI_PATH);
+
+        // Set operation mode to standalone
+        mOtaServerSetup.isActive = false;
+
+        OtaServer_ResetPercentageInfo();
+
+        memset(&mOtaClientSessionInfoTable, 0x00,
+               sizeof(otaClientSessionInfo_t) * gOtaServer_MaxSimultaneousClients_c);
+        mOtaServerSetup.fileVersionPolicy = gOtaFileVersionDefaultPolicies_c;
+        memset(&binary_file_path[0], 0x00, sizeof(binary_file_path));
+
+        if (true == mOtaServerSetup.isActive)
+        {
+            OtaServer_HandleBlockSocket(true);
+        }
+    }
+
+    return otaStatus;
+}
+
+/*!*************************************************************************************************
+\public
+\fn  otaStatus_t OtaServer_StartOta()
+\brief  Start OTA process
+
+\param  [in]    otaType        Type of OTA process (unicast or multicast)
+\param  [in]    pFilePath      Path to binary
+
+\return         otaStatus_t    Status of the operation
+ ***************************************************************************************************/
+otaStatus_t OtaServer_StartOta(uint8_t otaType, const char *pFilePath)
+{
+    otaServer_ImageNotify_t *pImageNotify = NULL;
+    otaStatus_t status = gOtaStatus_Success_c;
+
+    if ((otaType != gOtaUnicast_c) && (otaType != gOtaMulticast_c))
+    {
+        status = gOtaStatus_Failed_c;
+        goto exit;
+    }
+
+    // Check if device is connected before starting OTA
+    if (otThreadGetDeviceRole(mOtaServerSetup.pOtInstance) < OT_DEVICE_ROLE_CHILD)
+    {
+        status = gOtaStatus_NotPermitted_c;
+        goto exit;
+    }
+
+    // Check if OTA process is already active
+    if (mOtaServerSetup.isActive == true)
+    {
+        status = gOtaStatus_AlreadyStarted_c;
+        goto exit;
+    }
+
+    if (pFilePath != NULL)
+    {
+        memcpy(binary_file_path, pFilePath, strlen(pFilePath));
+
+        if (!(access(binary_file_path, F_OK) != -1))
+        {
+            status = gOtaStatus_InvalidValue_c;
+            goto exit;
+        }
+    }
+    else
+    {
+        status = gOtaStatus_EmptyEntry_c;
+        goto exit;
+    }
+
+    // Set multicast addresses used in OTA process
+    NWKU_OtSetMulticastAddresses(mOtaServerSetup.pOtInstance);
+    mOtaServerSetup.transferType = otaType;
+
+    OtaServer_ResetPercentageInfo();
+    mOtaServerPercentageInformation.otaType = otaType;
+
+    /* clear current image entries */
+    for (uint8_t i = 0; i < gOtaServer_MaxOtaImages_c; i++)
+    {
+        mOtaServerImageList[i].isValidEntry = false;
+    }
+
+    mOtaServerTempImageIdx = gOtaServer_MaxOtaImages_c;
+
+    OtaServer_InitStandaloneOpMode();
+
+    if (mOtaServerImageList[mOtaServerTempImageIdx].imageType == otaServerClientImageTypeLPED)
+    {
+        if (otaType == gOtaMulticast_c)
+        {
+            mOtaServerSetup.transferType = gOtaUnicast_c;
+            mOtaServerPercentageInformation.otaType = gOtaUnicast_c;
+            status = gOtaStatus_TransferTypeNotSupported_c;
+        }
+    }
+
+    // OTA Multicast parameters. Not used for OTA unicast.
+    if (mOtaServerSetup.transferType == gOtaMulticast_c)
+    {
+        // OTA multicast.
+        pImageNotify = (otaServer_ImageNotify_t *)calloc(1, sizeof(otaServer_ImageNotify_t));
+    }
+
+    OtaServer_SendImageNotifty(pImageNotify, &in6addr_realmlocal_allthreadnodes);
+
+    if (mOtaServerSetup.transferType == gOtaMulticast_c)
+    {
+        OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, (void *)pImageNotify, 100);
+    }
+
+exit:
+    return status;
+}
+
+/*!*************************************************************************************************
+\fn     otaResult_t OtaServer_StopOta(void)
+\brief  Process Stop OTA command received from an external application.
+
+\return         otaStatus_t    Result of the operation
+***************************************************************************************************/
+otaStatus_t OtaServer_StopOta
+(
+    void
+)
+{
+    otaStatus_t result = gOtaStatus_NoMem_c;
+    uint8_t size = sizeof(otaClientInfo_t) - 1 + sizeof(otaCmd_UpgradeEndRsp_t);
+    otaClientInfo_t *pOtaClientInfo;
+
+    pOtaClientInfo = calloc(1, size);
+    mOtaServerSetup.isActive = false;
+
+    /* clear current image entries */
+    for (uint8_t i = 0; i < gOtaServer_MaxOtaImages_c; i++)
+    {
+        mOtaServerImageList[i].isValidEntry = false;
+    }
+
+    mOtaServerTempImageIdx = gOtaServer_MaxOtaImages_c;
+
+    if (pOtaClientInfo)
+    {
+        otaCmd_QueryImageRsp_t queryRsp = {0};
+        uint32_t timeInMs = otPlatAlarmMilliGetNow();
+        uint32_t delayInMs = 0;
+
+        queryRsp.commandId = gOtaCmd_UpgradeEndRsp_c;
+        queryRsp.status = gOtaFileStatus_Abort_c;
+
+        memcpy(&pOtaClientInfo->remoteAddr, &in6addr_realmlocal_allthreadnodes, sizeof(otIp6Address));
+        memcpy(&pOtaClientInfo->sourceAddr, GET_OTA_ADDRESS(mOtaServerSetup.pOtInstance), sizeof(otIp6Address));
+
+        pOtaClientInfo->port = OTA_SERVER_DEFAULT_PORT;
+        pOtaClientInfo->dataLen = size - sizeof(otaClientInfo_t) + 1;
+        pOtaClientInfo->pData[0] = gOtaCmd_UpgradeEndRsp_c;
+
+        memcpy(&queryRsp.data.wait.currentTime, &timeInMs, sizeof(uint32_t));
+        timeInMs = timeInMs + delayInMs;
+        memcpy(&queryRsp.data.wait.requestTime, &timeInMs, sizeof(uint32_t));
+
+        // Send the Block Req to the OTA Server.
+        result = OtaServer_CoapSendRsp(pOtaClientInfo, (uint8_t *)&queryRsp, sizeof(queryRsp));
+    }
+
+    OtaServer_ResetMulticastModule(NULL);
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\fn     void OtaServer_GetOtaStatus(otaServerPercentageInfo_t *pData)
+\brief  This function is used to check the status of the OTA transfer.
+
+\param  [in]    pData        Pointer to output structure
+***************************************************************************************************/
+void OtaServer_GetOtaStatus(otaServerPercentageInfo_t *pData)
+{
+    memcpy(pData, (uint8_t *)&mOtaServerPercentageInformation, sizeof(mOtaServerPercentageInformation));
+}
+
+/*==================================================================================================
+Private functions
+==================================================================================================*/
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_SetTimeCallback(otaTmrCallback pFunc, void *param, uint32_t setTime)
+\brief  This function sets a timer callback for OTA functions.
+
+\param  [in]    pFunc           Callback function
+\param  [in]    pData           Callback function parameter
+\param  [in]    setTime         Set time for callback in milliseconds
+***************************************************************************************************/
+static void OtaServer_SetTimeCallback
+(
+    otaTmrCallback pFunc,
+    void *pData,
+    uint32_t setTime
+)
+{
+    if(mOtaServerSetup.isActive == true)
+    {
+        if(pFunc != NULL)
+        {
+            gpFunction = pFunc;
+        }
+
+        gpParameter = pData;
+        setMilliTime = otPlatAlarmMilliGetNow() + setTime;
+        callbackIsSet = true;
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_StopTimeCallback(void)
+\brief  This function stops and clears the timer callback for OTA functions.
+***************************************************************************************************/
+static void OtaServer_StopTimeCallback(void)
+{
+    gpFunction = NULL;
+    gpParameter = NULL;
+    setMilliTime = 0;
+    callbackIsSet = false;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_CoapCb(void *pCtx, otMessage *pMsg, const otMessageInfo *pMsgInfo)
+\brief  This function is the callback function for CoAP message.
+
+\param  [in]    pCtx            Pointer to OpenThread context
+\param  [in]    pMsg            Pointer to CoAP message
+\param  [in]    pMsgInfo        Pointer to CoAP message information
+***************************************************************************************************/
+static void OtaServer_CoapCb
+(
+    void *pCtx,
+    otMessage *pMsg,
+    const otMessageInfo *pMsgInfo
+)
+{
+    uint16_t dataLen = otMessageGetLength(pMsg) - otMessageGetOffset(pMsg);
+    uint8_t otaCommand = gOtaCmd_Invalid_c;
+
+    otMessageRead(pMsg, otMessageGetOffset(pMsg), (void *)&otaCommand, sizeof(otaCommand));
+
+    if (gOtaStatus_Success_c == OtaServer_CmdCheck(otaCommand, dataLen))
+    {
+        otaClientInfo_t *pOtaClientInfo = (otaClientInfo_t *)calloc(1, sizeof(otaClientInfo_t) + dataLen);
+    
+        if (NULL != pOtaClientInfo)
+        {
+            otIp6Address nullAddr = {0};
+
+            /* Save client info params */
+            otMessageRead(pMsg, otMessageGetOffset(pMsg), (void *)&pOtaClientInfo->pData, dataLen);
+            pOtaClientInfo->dataLen = dataLen;
+            memcpy(&pOtaClientInfo->remoteAddr, &pMsgInfo->mPeerAddr, sizeof(otIp6Address));
+
+            if (memcmp(&pOtaClientInfo->remoteAddr, &nullAddr, sizeof(otIp6Address)))
+            {
+                memcpy(&pOtaClientInfo->sourceAddr, &in6addr_realmlocal_allthreadnodes, sizeof(otIp6Address));
+            }
+
+            pOtaClientInfo->timeStamp = otPlatAlarmMilliGetNow();
+            OtaServer_ClientProcess(pOtaClientInfo);
+        }
+    }
+    (void)pCtx;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaClient_UdpServerService(uint8_t *pInData)
+\brief  This function is the callback function for Ota server socket.
+
+\param  [in]    pCtx            Pointer to OpenThread context
+\param  [in]    pMsg            Pointer to CoAP message
+\param  [in]    pMsgInfo        Pointer to CoAP message information
+***************************************************************************************************/
+static void OtaClient_UdpServerService
+(
+    void *pCtx,
+    otMessage *pMsg,
+    const otMessageInfo *pMsgInfo
+)
+{
+    uint16_t dataLen = otMessageGetLength(pMsg) - otMessageGetOffset(pMsg);
+    uint8_t otaCommand = gOtaCmd_Invalid_c;
+
+    otMessageRead(pMsg, otMessageGetOffset(pMsg), (void *)&otaCommand, sizeof(otaCommand));
+
+    if (gOtaCmd_BlockReq_c == otaCommand)
+    {
+        otaClientInfo_t *pOtaClientInfo = (otaClientInfo_t *)calloc(1, sizeof(otaClientInfo_t) + dataLen);
+
+        if (NULL != pOtaClientInfo)
+        {
+            /* Save client info params */
+            otMessageRead(pMsg, otMessageGetOffset(pMsg), (void *)pOtaClientInfo->pData, dataLen);
+            memcpy(&pOtaClientInfo->remoteAddr, (void *)&pMsgInfo->mPeerAddr, sizeof(otIp6Address));
+            memcpy(&pOtaClientInfo->sourceAddr, (void *)&pMsgInfo->mSockAddr, sizeof(otIp6Address));
+            pOtaClientInfo->port = pMsgInfo->mPeerPort;
+            pOtaClientInfo->dataLen = dataLen;
+            pOtaClientInfo->timeStamp = otPlatAlarmMilliGetNow();
+            OtaServer_ClientProcess(pOtaClientInfo);
+        }
+    }
+    (void) pCtx;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_SendImageNotifty(otaServer_ImageNotify_t *pImgNtf, otIp6Address *pAddr)
+\brief  This function is used for the transmission of Image Notification commands.
+
+\param  [in]    pImgNtf         Pointer to the otaServer_ImageNotify_t structure
+\param  [in]    pAddr           Pointer to peer address
+
+\return         otaStatus_t     Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_SendImageNotifty
+(
+    otaServer_ImageNotify_t *pImgNtf,
+    otIp6Address *pAddr
+)
+{
+    bool_t status = false;
+    FILE *pFile = fopen(binary_file_path,"rb");
+    
+    if(pFile != NULL)
+    {
+        otaServer_ImageNotify_t imageNotify;
+        otaFileSubElement_t imageTag;
+
+        /* transfer completed */
+        mOtaServerImageList[mOtaServerTempImageIdx].isValidEntry = true;
+        mOtaServerSetup.isActive = true;
+
+        /* Set position after file header */
+        fseek(pFile, mOtaServerImageList[mOtaServerTempImageIdx].imageAddr + sizeof(otaFileHeader_t), SEEK_SET);
+
+        if(fread((void *)&imageTag, sizeof(otaFileSubElement_t), 1, pFile))
+        {
+            // Inform clients that a new image is available
+            memset(&imageNotify, 0, sizeof(otaServer_ImageNotify_t));
+            memcpy(&imageNotify.fileVersion, &mOtaServerImageList[mOtaServerTempImageIdx].fileVersion, sizeof(uint32_t));
+            memcpy(&imageNotify.imageType, &mOtaServerImageList[mOtaServerTempImageIdx].imageType, sizeof(uint16_t));
+            memcpy(&imageNotify.manufacturerCode, &mOtaServerImageList[mOtaServerTempImageIdx].manufCode, sizeof(uint16_t));
+            memcpy(&imageNotify.imageSize, &imageTag.length, sizeof(imageNotify.imageSize));
+            memcpy(&imageNotify.fileSize, &mOtaServerImageList[mOtaServerTempImageIdx].fileSize, sizeof(uint32_t));
+        }
+
+        /* return image notify data for multicast usage */
+        if(pImgNtf != NULL)
+        {
+            memcpy(pImgNtf, &imageNotify, sizeof(otaServer_ImageNotify_t));
+        }
+
+        status = (OtaServer_CoapSendImageNotify(&imageNotify, pAddr) == gOtaStatus_Success_c) ? true : false;
+    }
+
+    if (pFile != NULL)
+    {
+        fclose(pFile);
+    }
+
+    return (status == true) ? gOtaStatus_Success_c : gOtaStatus_Failed_c;
+}
+
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_ClientProcess(uint8_t *param)
+\brief  This function is used to process ota client commands.
+
+\param  [in]    pOtaClientInfo    Pointer to pOtaClientInfo structure
+***************************************************************************************************/
+static void OtaServer_ClientProcess
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    bool_t isServerBusy = false;
+    uint16_t clientId;
+
+    if (false == mOtaServerSetup.isActive)
+    {
+        /* Server is not active -  send back a Rsp command with status no image available */
+        OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo, gOtaFileStatus_NoImageAvailable_c, 0);
+    }
+    else
+    {
+        if ((gOtaStatus_Success_c == OtaServer_CheckClientSessionTable(pOtaClientInfo)) &&
+                (gOtaStatus_Success_c == OtaServer_HandleBlockSocket(true)))
+        {
+            if (mOtaServerSetup.transferType == gOtaUnicast_c)
+            {
+                clientId = (pOtaClientInfo->remoteAddr.mFields.m8[14] << 8) + pOtaClientInfo->remoteAddr.mFields.m8[15];
+
+                if((clientId != gOtaServer_InvalidClientId_c) && OtaServer_IsClientValid(clientId))
+                {
+                    OtaServer_CmdProcess(pOtaClientInfo);
+                }
+                else
+                {
+                    isServerBusy = true;
+                }
+            }
+            else if (mOtaServerSetup.transferType == gOtaMulticast_c)
+            {
+                OtaServer_CmdProcess(pOtaClientInfo);
+            }
+        }
+        else
+        {
+            isServerBusy = true;
+        }
+
+        if (isServerBusy)
+        {
+            OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo,
+                                               gOtaFileStatus_ServerBusy_c,
+                                               gOtaServer_DelayForNextRequestMs_c);
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CheckClientSessionTable(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to check if the server can process this new client request.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_CheckClientSessionTable
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    uint8_t idxInfoTable;
+    uint8_t firstExpiredEntry = gOtaServer_MaxSimultaneousClients_c;
+
+    for (idxInfoTable = 0; idxInfoTable < gOtaServer_MaxSimultaneousClients_c; idxInfoTable++)
+    {
+        if (memcmp(&pOtaClientInfo->remoteAddr, &mOtaClientSessionInfoTable[idxInfoTable].remoteAddr, sizeof(otIp6Address)))
+        {
+            mOtaClientSessionInfoTable[idxInfoTable].timeStamp = pOtaClientInfo->timeStamp;
+            return gOtaStatus_Success_c;
+        }
+
+        if (((mOtaClientSessionInfoTable[idxInfoTable].timeStamp == 0) ||
+                (mOtaClientSessionInfoTable[idxInfoTable].timeStamp + (gOtaServer_ClientSessionExpirationMs_c) < pOtaClientInfo->timeStamp)) &&
+                (firstExpiredEntry == gOtaServer_MaxSimultaneousClients_c))
+        {
+            firstExpiredEntry = idxInfoTable;
+        }
+    }
+
+    if (firstExpiredEntry < gOtaServer_MaxSimultaneousClients_c)
+    {
+        memcpy(&mOtaClientSessionInfoTable[firstExpiredEntry].remoteAddr, &pOtaClientInfo->remoteAddr, sizeof(otIp6Address));
+        mOtaClientSessionInfoTable[firstExpiredEntry].timeStamp = pOtaClientInfo->timeStamp;
+        status = gOtaStatus_Success_c;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CmdCheck(void *pData, uint32_t dataLen)
+\brief  This function is used to check if ota client command is valid.
+
+\param  [in]    pData          OTA cmd data
+\param  [in]    dataLen        OTA cmd length
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_CmdCheck
+(
+    uint8_t otaCommand,
+    uint32_t dataLen
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+
+    switch (otaCommand)
+    {
+        case gOtaCmd_QueryImageReq_c:
+            if (dataLen == sizeof(otaCmd_QueryImageReq_t))
+            {
+                status = gOtaStatus_Success_c;
+            }
+
+            break;
+
+        case gOtaCmd_BlockReq_c:
+            if (dataLen == (sizeof(otaCmd_BlockReq_t)))
+            {
+                status = gOtaStatus_Success_c;
+            }
+
+            break;
+
+        case gOtaCmd_UpgradeEndReq_c:
+            if (dataLen == sizeof(otaCmd_UpgradeEndReq_t))
+            {
+                status = gOtaStatus_Success_c;
+            }
+
+            break;
+
+        case gOtaCmd_ServerDiscovery_c:
+            if (dataLen == sizeof(otaCmd_ServerDiscovery_t))
+            {
+                status = gOtaStatus_Success_c;
+            }
+
+            break;
+
+        default:
+            break;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_CmdProcess(void *param)
+\brief  This function is used to process ota client commands.
+
+\param  [in]    pOtaClientInfo    Pointer to pOtaClientInfo structure
+***************************************************************************************************/
+static void OtaServer_CmdProcess
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    uint8_t otaCommand = *pOtaClientInfo->pData;
+
+    switch (otaCommand)
+    {
+        case gOtaCmd_QueryImageReq_c:
+            (void)OtaServer_QueryImageReqHandler(pOtaClientInfo);
+            break;
+
+        case gOtaCmd_BlockReq_c:
+            (void)OtaServer_BlockReqHandler(pOtaClientInfo);
+            break;
+
+        case gOtaCmd_UpgradeEndReq_c:
+            (void)OtaServer_UpgradeEndReqHandler(pOtaClientInfo);
+            break;
+
+        case gOtaCmd_ServerDiscovery_c:
+            (void)OtaServer_ServerDiscoveryHandler(pOtaClientInfo);
+            break;
+
+        default:
+            free((void *)pOtaClientInfo);
+            break;
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_QueryImageReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a QueryImageReq command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_QueryImageReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    return OtaServerStandalone_QueryImageReqHandler(pOtaClientInfo);
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_BlockReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a BlockRequest command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_BlockReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    return OtaServerStandalone_BlockReqHandler(pOtaClientInfo);
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_UpgradeEndReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process an UpdateEndRequest command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_UpgradeEndReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaCmd_UpgradeEndRsp_t upgradeRsp = {0};
+    uint32_t timeInMs = otPlatAlarmMilliGetNow();
+    /* Get the client status from the received packet */
+    otaFileStatus_t client_status = (otaFileStatus_t) (*(pOtaClientInfo->pData + 1));
+    uint16_t clientId = 0;
+
+    upgradeRsp.commandId = gOtaCmd_UpgradeEndRsp_c;
+    upgradeRsp.status = gOtaStatus_Success_c;
+    memcpy(&upgradeRsp.data.success.currentTime, &timeInMs, sizeof(uint32_t));
+    timeInMs += otRandomNonCryptoGetUint32InRange(gOtaServer_MinDelayForEndRequestMs_c, gOtaServer_MaxDelayForEndRequestMs_c);
+    memcpy(&upgradeRsp.data.success.upgradeTime, &timeInMs, sizeof(uint32_t));
+
+    if (client_status == gOtaFileStatus_Success_c)
+    {
+        (void)OtaServer_CoapSendRsp(pOtaClientInfo, (uint8_t *)&upgradeRsp, sizeof(otaCmd_UpgradeEndRsp_t));
+    }
+
+    NWKU_MemCpyReverseOrder(&clientId, &pOtaClientInfo->remoteAddr.mFields.m8[14], sizeof(uint16_t));
+
+    OtaServer_RemoveClientFromPercentageInfo(clientId);
+
+    if (client_status != gOtaFileStatus_Success_c)
+    {
+        free(pOtaClientInfo);
+    }
+
+    return gOtaStatus_Success_c;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_ServerDiscoveryHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a ServerDiscovery command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_ServerDiscoveryHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    return OtaServerStandalone_ServerDiscoveryHandler(pOtaClientInfo);
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CoapSendImageNotify(otaServer_ImageNotify_t *pThciImageNotify,
+                                                         otIp6Address *pDestAddr)
+\brief  This function is used to send multicast a coap Image notify command to all thread nodes
+
+\param  [in]   pThciImageNotify    Pointer to image notify message
+\param  [in]   pDestAddr           Pointer to IPv6 address
+
+\return        otaStatus_t         Status of the operation
+ ***************************************************************************************************/
+static otaStatus_t OtaServer_CoapSendImageNotify
+(
+    otaServer_ImageNotify_t *pImageNotify,
+    otIp6Address *pDestAddr
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    uint16_t fragmentSize = gOtaMaxBlockDataSize_c;
+    otCoapType coapType = OT_COAP_TYPE_NON_CONFIRMABLE;
+    otCoapCode coapCode = OT_COAP_CODE_POST;
+    otError error = OT_ERROR_NONE;
+
+    otMessage *pMsg = otCoapNewMessage(mOtaServerSetup.pOtInstance, NULL);
+
+    if(pMsg)
+    {
+        otMessageInfo messageInfo = {0};
+        otaServerCmd_ImageNotify_t imageNotify;
+
+        otCoapMessageInit(pMsg, coapType, coapCode);
+        otCoapMessageGenerateToken(pMsg, 4);
+
+        /* Complete command */
+        imageNotify.commandId = gOtaCmd_ImageNotify_c;
+        imageNotify.transferType = mOtaServerSetup.transferType;
+        memcpy(&imageNotify.manufacturerCode, &pImageNotify->manufacturerCode,
+                    sizeof(otaServer_ImageNotify_t) - 2);
+        memcpy(&imageNotify.serverDownloadPort[0], (void *)&mOtaServerSetup.downloadPort, sizeof(uint16_t));
+        memcpy(&imageNotify.fragmentSize[0], &fragmentSize, sizeof(imageNotify.fragmentSize));
+
+        error = otCoapMessageAppendUriPathOptions(pMsg, OTA_SERVER_URI_PATH);
+        error = otCoapMessageSetPayloadMarker(pMsg);
+        error = otMessageAppend(pMsg, (const void *)&imageNotify, sizeof(imageNotify));
+        
+        memset(&messageInfo, 0, sizeof(messageInfo));
+
+        messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
+        memcpy(&messageInfo.mSockAddr, GET_OTA_ADDRESS(mOtaServerSetup.pOtInstance), sizeof(otIp6Address));
+        memcpy(&messageInfo.mPeerAddr, pDestAddr, sizeof(otIp6Address));
+        
+        error = otCoapSendRequest(mOtaServerSetup.pOtInstance, pMsg, &messageInfo, NULL, NULL);
+
+        if ((error != OT_ERROR_NONE) && (pMsg != NULL))
+        {
+            otMessageFree(pMsg);
+        }
+        else
+        {
+            status = gOtaStatus_Success_c;
+        }
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CoapSendRsp(otaClientInfo_t *pOtaClientInfo, uint8_t *pData, uint32_t dataLen)
+\brief  This function is used to send a coap response to a OTA client node.
+
+\param  [in]   pOtaClientInfo    Pointer to client info
+\param  [in]   pData             Pointer to data
+\param  [in]   dataLen           Payload length
+
+\return        otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_CoapSendRsp
+(
+    otaClientInfo_t *pOtaClientInfo,
+    uint8_t *pData,
+    uint32_t dataLen
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    otCoapType coapType = OT_COAP_TYPE_NON_CONFIRMABLE;
+    otCoapCode coapCode = OT_COAP_CODE_POST;
+    otError error = OT_ERROR_NONE;
+    otMessage *pMsg = otCoapNewMessage(mOtaServerSetup.pOtInstance, NULL);
+
+    if(pMsg)
+    {
+        otMessageInfo messageInfo = {0};
+
+        otCoapMessageInit(pMsg, coapType, coapCode);
+        otCoapMessageGenerateToken(pMsg, 4);
+
+        /* Complete command */
+        error = otCoapMessageAppendUriPathOptions(pMsg, OTA_SERVER_URI_PATH);
+        error = otCoapMessageSetPayloadMarker(pMsg);
+        error = otMessageAppend(pMsg, (const void *)pData, dataLen);
+
+        memset(&messageInfo, 0, sizeof(messageInfo));
+
+        messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
+        memcpy(&messageInfo.mSockAddr, GET_OTA_ADDRESS(mOtaServerSetup.pOtInstance), sizeof(otIp6Address));
+        memcpy(&messageInfo.mPeerAddr, &pOtaClientInfo->remoteAddr, sizeof(otIp6Address));
+
+        error = otCoapSendRequest(mOtaServerSetup.pOtInstance, pMsg, &messageInfo, NULL, NULL);
+
+        if ((error != OT_ERROR_NONE) && (pMsg != NULL))
+        {
+            otMessageFree(pMsg);
+        }
+        else
+        {
+            status = gOtaStatus_Success_c;
+        }
+    }
+
+    free((void *)pOtaClientInfo);
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_SocketSendRsp(otaClientInfo_t *pOtaClientInfo, uint8_t *pData, uint32_t dataLen)
+\brief  This function is used to send a socket response to a OTA client node.
+
+\param  [in]   pOtaClientInfo    Pointer to client info
+\param  [in]   pData             Pointer to data
+\param  [in]   dataLen           Payload length
+
+\return        otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_SocketSendRsp
+(
+    otaClientInfo_t *pOtaClientInfo,
+    uint8_t *pData,
+    uint32_t dataLen
+)
+{
+    otMessageInfo messageInfo;
+    otMessage *message = NULL;
+    otError error = OT_ERROR_NONE;
+
+    /* Set remote address and local port */
+    memset(&messageInfo, 0, sizeof(messageInfo));
+    messageInfo.mPeerPort = pOtaClientInfo->port;
+    memcpy(&messageInfo.mPeerAddr, &pOtaClientInfo->remoteAddr, sizeof(otIp6Address));
+
+    message = otUdpNewMessage(mOtaServerSetup.pOtInstance, NULL);
+    error = otMessageAppend(message, (const void *)pData, dataLen);
+    error = otUdpSend(mOtaServerSetup.pOtaUdpSrvSocket, message, &messageInfo);
+
+    if (error != OT_ERROR_NONE && message != NULL)
+    {
+        otMessageFree(message);
+    }
+
+    free((void *)pOtaClientInfo);
+
+    return gOtaStatus_Success_c;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_CoapSendRspWaitAbortData(otaClientInfo_t *pOtaClientInfo, uint8_t status,
+                                                              uint32_t delayInMs)
+\brief  This function is used to send a Query Image Rsp command to the OTA client node using
+        a status != Success
+
+\param  [in]   pOtaClientInfo    Pointer to client info
+\param  [in]   status            Query image response status != Success
+\param  [in]   delayInMs         Delay in milliseconds
+
+\return        otaStatus_t       Status of the operation
+ ***************************************************************************************************/
+static otaStatus_t OtaServer_CoapSendRspWaitAbortData
+(
+    otaClientInfo_t *pOtaClientInfo,
+    uint8_t status,
+    uint32_t delayInMs
+)
+{
+    otaStatus_t result = gOtaStatus_Failed_c;
+
+    if (status != gOtaFileStatus_Success_c)
+    {
+        /* All busy / abort responses have the same structure as queryRsp*/
+        otaCmd_QueryImageRsp_t queryRsp = {0};
+        uint8_t len = 2 + sizeof(otaCmd_QueryImageRspWait_t);
+        uint8_t otaCommand = *pOtaClientInfo->pData;
+        uint32_t timeInMs = otPlatAlarmMilliGetNow();
+
+        queryRsp.commandId = gOtaCmd_QueryImageRsp_c;
+
+        switch (otaCommand)
+        {
+            case gOtaCmd_BlockReq_c:
+                queryRsp.commandId = gOtaCmd_BlockRsp_c;
+                break;
+
+            case gOtaCmd_QueryImageReq_c:
+                queryRsp.commandId = gOtaCmd_QueryImageRsp_c;
+                break;
+
+            case gOtaCmd_UpgradeEndReq_c:
+                queryRsp.commandId = gOtaCmd_UpgradeEndRsp_c;
+                break;
+
+            default:
+                free((void *)pOtaClientInfo);
+                return gOtaStatus_InvalidParam_c;
+        }
+
+        queryRsp.status = status;
+        memcpy(&queryRsp.data.wait.currentTime, &timeInMs, sizeof(uint32_t));
+        timeInMs = timeInMs + delayInMs;
+        memcpy(&queryRsp.data.wait.requestTime, &timeInMs, sizeof(uint32_t));
+
+        if (gOtaStatus_Success_c == OtaServer_CoapSendRsp(pOtaClientInfo, (uint8_t *)&queryRsp, len))
+        {
+            result = gOtaStatus_Success_c;
+        }
+    }
+    else
+    {
+        free((void *)pOtaClientInfo);
+    }
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static bool_t OtaServer_IsClientValid(uint16_t clientId)
+\brief  This function is used to validate client ID and add it to percentage list.
+
+\param  [in]   clientId    Client ID
+
+\return        bool_t    TRUE - client valid, FALSE - client is in the abort list
+ ***************************************************************************************************/
+static bool_t OtaServer_IsClientValid
+(
+    uint16_t clientId
+)
+{
+    bool_t result = false;
+    uint8_t i;
+
+    for (i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+    {
+        if (mOtaServerPercentageInformation.unicastEntry[i].clientId == clientId)
+        {
+            result = true;
+            break;
+        }
+    }
+
+    if (result == false)
+    {
+        for (i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+        {
+            if (mOtaServerPercentageInformation.unicastEntry[i].clientId == gOtaServer_InvalidClientId_c)
+            {
+                mOtaServerPercentageInformation.unicastEntry[i].clientId = clientId;
+                mOtaServerPercentageInformation.unicastEntry[i].percentage = 0;
+                result = true;
+                break;
+            }
+        }
+    }
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static bool_t OtaServer_RemoveClientFromPercentageInfo(uint16_t clientId)
+\brief  This function is used to remove a client ID from percentage information list.
+
+\param [in]   clientId    Client ID
+
+\return       bool_t      TRUE - client removed, FALSE - otherwise
+ ***************************************************************************************************/
+static bool_t OtaServer_RemoveClientFromPercentageInfo
+(
+    uint16_t clientId
+)
+{
+    bool_t result = false;
+
+    for (uint8_t i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+    {
+        if (mOtaServerPercentageInformation.unicastEntry[i].clientId == clientId)
+        {
+            mOtaServerPercentageInformation.unicastEntry[i].clientId = gOtaServer_InvalidClientId_c;
+            mOtaServerPercentageInformation.unicastEntry[i].percentage = 0;
+            result = true;
+            break;
+        }
+    }
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_ResetPercentageInfo(void)
+\brief  This function is resets the percentage information.
+ ***************************************************************************************************/
+static void OtaServer_ResetPercentageInfo
+(
+    void
+)
+{
+    mOtaServerPercentageInformation.multicastPercentage = 0;
+    mOtaServerPercentageInformation.otaType = 0xFF;
+
+    for (uint8_t i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+    {
+        mOtaServerPercentageInformation.unicastEntry[i].clientId = gOtaServer_InvalidClientId_c;
+        mOtaServerPercentageInformation.unicastEntry[i].percentage = 0;
+    }
+}
+
+/*************************************************************************************************
+*
+*  OTA Server Standalone functions
+*
+**************************************************************************************************/
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_InitStandaloneOpMode(void)
+\brief  Initialize ota server standalone operation mode.
+***************************************************************************************************/
+static void OtaServer_InitStandaloneOpMode
+(
+    void
+)
+{
+    bool_t imageAvailable = false;
+    uint8_t index = 0;
+    otaFileHeader_t otaHeader;
+    FILE *pFile = NULL;
+
+    /* init external memory */
+    pFile = fopen(binary_file_path,"rb");
+
+    /* process OTA header information */
+    while ((index < gOtaServer_MaxOtaImages_c) && (pFile != NULL))
+    {
+        uint32_t fileIdentifier;
+
+        /* Read OTA Header */
+        if (fread((void *)&otaHeader, sizeof(otaFileHeader_t), 1, pFile))
+        {
+            memcpy(&fileIdentifier, otaHeader.fileIdentifier, sizeof(fileIdentifier));
+
+            if (fileIdentifier == gOtaFileIdentifierNo_c)
+            {
+                uint16_t manufCode, imageType;
+                uint32_t fileVersion, fileSize;
+
+                memcpy(&fileVersion, &otaHeader.fileVersion, sizeof(uint32_t));
+                memcpy(&imageType, &otaHeader.imageType, sizeof(uint16_t));
+                memcpy(&manufCode, &otaHeader.manufacturerCode, sizeof(uint16_t));
+                memcpy(&fileSize, &otaHeader.totalImageSize, sizeof(uint32_t));
+                
+                index = OtaServerStandalone_KeepImageInfo(manufCode, imageType, fileVersion, fileSize);
+
+                if (index < gOtaServer_MaxOtaImages_c)
+                {
+                    mOtaServerTempImageIdx = index;
+                    mOtaServerImageList[index].isValidEntry = true;
+                    imageAvailable = true;
+                }
+            }
+            else
+            {
+                break;
+            }
+        }
+        else
+        {
+            /* ignore other data */
+            break;
+        }
+    }
+
+    if (pFile != NULL)
+    {
+        fclose(pFile);
+    }
+
+    mOtaServerSetup.isActive = imageAvailable;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static uint8_t OtaServerStandalone_ValidateImage(uint16_t manufCode, uint16_t imageType,
+                                                         uint32_t fileVersion, bool_t serialProtocol)
+\brief  Validate image by checking internal table.
+
+\param  [in]    manufCode         Manufacturer code
+        [in]    imageType         Image type
+        [in]    fileVersion       File version
+        [in]    serialProtocol    Image validation is required for the ota Server serial protocol
+
+\return         uint8_t           Image index if success, otherwise returns gOtaServer_MaxOtaImages_c
+***************************************************************************************************/
+static uint8_t OtaServerStandalone_ValidateImage
+(
+    uint16_t manufCode,
+    uint16_t imageType,
+    uint32_t fileVersion,
+    bool_t serialProtocol
+)
+{
+    uint8_t result = gOtaServer_MaxOtaImages_c;
+
+    /* validate internal list */
+    for (uint8_t i = 0; i < gOtaServer_MaxOtaImages_c; i++)
+    {
+        if ((manufCode == mOtaServerImageList[i].manufCode) &&
+                (imageType == mOtaServerImageList[i].imageType) &&
+                (mOtaServerImageList[i].isValidEntry))
+        {
+            if (((fileVersion ==  mOtaServerImageList[i].fileVersion) && (mOtaServerSetup.fileVersionPolicy & gOtaFileVersionPolicies_Reinstall_c)) ||
+                    ((fileVersion <  mOtaServerImageList[i].fileVersion) && (mOtaServerSetup.fileVersionPolicy & gOtaFileVersionPolicies_Upgrade_c)) ||
+                    ((fileVersion >  mOtaServerImageList[i].fileVersion) && (mOtaServerSetup.fileVersionPolicy & gOtaFileVersionPolicies_Downgrade_c)) ||
+                    ((serialProtocol) && (fileVersion ==  mOtaServerImageList[i].fileVersion)) || (fileVersion == 0xFFFFFFFF))
+            {
+                result = i;
+                break;
+            }
+        }
+    }
+
+    return result;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServerStandalone_QueryImageReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a QueryImageReq command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServerStandalone_QueryImageReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    uint8_t index = 0;
+    otaCmd_QueryImageReq_t *pQueryImgReq = (otaCmd_QueryImageReq_t *)pOtaClientInfo->pData;
+
+    index = OtaServerStandalone_ValidateImage((uint16_t)(pQueryImgReq->manufacturerCode[0] + (pQueryImgReq->manufacturerCode[1] << 8)),
+            (uint16_t)(pQueryImgReq->imageType[0] + (pQueryImgReq->imageType[1] << 8)),
+            (uint32_t)(pQueryImgReq->fileVersion[0] + (pQueryImgReq->fileVersion[1] << 8) +
+                       (pQueryImgReq->fileVersion[2] << 16) + (pQueryImgReq->fileVersion[3] << 24)), false);
+
+    if (index < gOtaServer_MaxOtaImages_c)
+    {
+        otaCmd_QueryImageRsp_t queryImgRsp = {0};
+        /* image size */
+        uint8_t len = sizeof(otaCmd_QueryImageRsp_t) - sizeof(queryImgRsp.data);
+
+        queryImgRsp.commandId = gOtaCmd_QueryImageRsp_c;
+        queryImgRsp.status = gOtaFileStatus_Success_c;
+        memcpy(&queryImgRsp.data.success.manufacturerCode, &mOtaServerImageList[index].manufCode, sizeof(uint16_t));
+        memcpy(&queryImgRsp.data.success.fileVersion, &mOtaServerImageList[index].fileVersion, sizeof(uint32_t));
+        memcpy(&queryImgRsp.data.success.imageType, &mOtaServerImageList[index].imageType, sizeof(uint16_t));
+        memcpy(&queryImgRsp.data.success.fileSize, &mOtaServerImageList[index].fileSize, sizeof(uint32_t));
+        memcpy(&queryImgRsp.data.success.serverDownloadPort, &mOtaServerSetup.downloadPort, sizeof(uint16_t));
+
+        len += sizeof(otaCmd_QueryImageRspSuccess_t);
+        (void)OtaServer_CoapSendRsp(pOtaClientInfo, (uint8_t *)&queryImgRsp, len);
+        status = gOtaStatus_Success_c;
+    }
+    else
+    {
+        /* packet in progress -  send back a Query Image Rsp command with status no image available */
+        OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo, gOtaFileStatus_NoImageAvailable_c, 0);
+        status = gOtaStatus_Success_c;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_AddPercentageInfoPerClient(uint16_t clientId, uint8_t percent)
+\brief  This function is used to process a BlockRequest command.
+
+\param  [in]    clientId    Client ID
+\param  [in]    percent     Unicast OTAP percent done
+***************************************************************************************************/
+static void OtaServer_AddPercentageInfoPerClient
+(
+    uint16_t clientId,
+    uint8_t percent
+)
+{
+    for (int i = 0; i < gOtaServer_MaxSimultaneousClients_c; i++)
+    {
+        if (mOtaServerPercentageInformation.unicastEntry[i].clientId == clientId)
+        {
+            mOtaServerPercentageInformation.unicastEntry[i].percentage = percent;
+            break;
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServerStandalone_BlockReqHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a BlockRequest command.
+
+\param  [in]    pOtaClientInfo    Pointer to client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServerStandalone_BlockReqHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    uint8_t index = gOtaServer_MaxOtaImages_c;
+    otaCmd_BlockReq_t *pBlockReq = (otaCmd_BlockReq_t *)pOtaClientInfo->pData;
+    index = OtaServerStandalone_ValidateImage((uint16_t)(pBlockReq->manufacturerCode[0] + (pBlockReq->manufacturerCode[1] << 8)),
+            (uint16_t)(pBlockReq->imageType[0] + (pBlockReq->imageType[1] << 8)),
+            (uint32_t)(pBlockReq->fileVersion[0] + (pBlockReq->fileVersion[1] << 8) +
+                       (pBlockReq->fileVersion[2] << 16) + (pBlockReq->fileVersion[3] << 24)), false);
+
+    if (index < gOtaServer_MaxOtaImages_c)
+    {
+        otaCmd_BlockRsp_t *pBlockRsp = NULL;
+        uint32_t respLength = 0;
+        uint32_t len =  pBlockReq->maxDataSize;
+        uint32_t imageOffset = (uint32_t)(pBlockReq->fileOffset[0] + (pBlockReq->fileOffset[1] << 8) +
+                                          (pBlockReq->fileOffset[2] << 16) + (pBlockReq->fileOffset[3] << 24));
+
+        if ((mOtaServerImageList[index].fileSize - imageOffset) < len)
+        {
+            len = mOtaServerImageList[index].fileSize - imageOffset;
+        }
+
+        respLength = 2 + sizeof(otaCmd_BlockRspSuccess_t) - 1 + len;
+        pBlockRsp = (otaCmd_BlockRsp_t *)calloc(1, respLength);
+
+        if (pBlockRsp)
+        {
+            uint32_t addr = imageOffset + mOtaServerImageList[index].imageAddr;
+            FILE *pFile = fopen(binary_file_path,"rb");
+            fseek(pFile, addr, SEEK_SET);
+
+            status = gOtaStatus_Success_c;
+            pBlockRsp->commandId = gOtaCmd_BlockRsp_c;
+            pBlockRsp->status = gOtaFileStatus_Success_c;
+            memcpy(pBlockRsp->data.success.fileVersion, pBlockReq->fileVersion, sizeof(uint32_t));
+            memcpy(pBlockRsp->data.success.fileOffset, &imageOffset, sizeof(uint32_t));
+            pBlockRsp->data.success.dataSize = len;
+
+            if(fread((void *)&pBlockRsp->data.success.pData[0], len, 1, pFile) == 0)
+            {
+                (void)OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo, gOtaFileStatus_Abort_c, 0);
+            }
+            else
+            {
+                uint16_t clientId = (pOtaClientInfo->remoteAddr.mFields.m8[14] << 8) + pOtaClientInfo->remoteAddr.mFields.m8[15];
+                uint8_t percent = 0;
+
+                OtaServer_SocketSendRsp(pOtaClientInfo, (uint8_t *)pBlockRsp, respLength);
+
+                //Calculate percentage of image already sent
+                percent = (uint8_t)(((imageOffset + len) * 100) / mOtaServerImageList[index].fileSize);
+                mOtaServerPercentageInformation.otaType = mOtaServerSetup.transferType;
+
+                if (mOtaServerSetup.transferType == gOtaMulticast_c)
+                {
+                    //Percentage of sent packages over multicast OTA
+                    mOtaServerPercentageInformation.multicastPercentage = percent;
+                }
+                else
+                {
+                    //Percentage of sent packages for a unicast client
+                    OtaServer_AddPercentageInfoPerClient(clientId, percent);
+                }
+            }
+
+            free(pBlockRsp);
+
+            if(pFile != NULL)
+            {
+                fclose(pFile);    
+            }
+        }
+    }
+    else
+    {
+        /* image is not available, abort current session */
+        status = gOtaStatus_Success_c;
+        (void)OtaServer_CoapSendRspWaitAbortData(pOtaClientInfo, gOtaFileStatus_Abort_c, 0);
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServerStandalone_ServerDiscoveryHandler(otaClientInfo_t *pOtaClientInfo)
+\brief  This function is used to process a ServerDiscovery command.
+
+\param  [in]    pOtaClientInfo    Pointer to OTA client info
+
+\return         otaStatus_t       Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServerStandalone_ServerDiscoveryHandler
+(
+    otaClientInfo_t *pOtaClientInfo
+)
+{
+    otaStatus_t status = gOtaStatus_Success_c;
+    uint8_t index = gOtaServer_MaxOtaImages_c;
+    otaCmd_ServerDiscovery_t *pCmdData = (otaCmd_ServerDiscovery_t *)pOtaClientInfo->pData;
+
+    index = OtaServerStandalone_ValidateImage((uint16_t)(pCmdData->manufacturerCode[0] + (pCmdData->manufacturerCode[1] << 8)),
+            (uint16_t)(pCmdData->imageType[0] + (pCmdData->imageType[1] << 8)),
+            0xFFFFFFFF, false);
+
+    if (index < gOtaServer_MaxOtaImages_c)
+    {
+        /* send back a unicast image notify command */
+        status = OtaServer_SendImageNotifty(NULL, &pOtaClientInfo->remoteAddr);
+    }
+
+    free(pOtaClientInfo);
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static uint8_t OtaServerStandalone_KeepImageInfo(uint16_t manufCode, uint16_t imageType,
+                                                        uint32_t fileVersion, uint32_t fileSize)
+\brief  This function is used to store image information in local table.
+
+\param  [in]    manufCode      Manufacturer code
+        [in]    imageType      Image type
+        [in]    fileVersion    File version
+        [in]    imageSize      Image size
+
+\return         uint8_t        Image index if success, otherwise returns gOtaServer_MaxOtaImages_c
+***************************************************************************************************/
+static uint8_t OtaServerStandalone_KeepImageInfo
+(
+    uint16_t manufCode,
+    uint16_t imageType,
+    uint32_t fileVersion,
+    uint32_t fileSize
+)
+{
+    uint8_t result = gOtaServer_MaxOtaImages_c;
+    uint32_t imageAddrOffset = 0;
+
+    for (uint8_t i = 0; i < gOtaServer_MaxOtaImages_c; i++)
+    {
+        if (mOtaServerImageList[i].isValidEntry)
+        {
+            /* entry is valid, update image offset */
+            imageAddrOffset += mOtaServerImageList[i].fileSize;
+        }
+        else
+        {
+            /* entry is free */
+            mOtaServerImageList[i].fileVersion = fileVersion;
+            mOtaServerImageList[i].imageAddr = imageAddrOffset;
+            mOtaServerImageList[i].imageType = imageType;
+            mOtaServerImageList[i].manufCode = manufCode;
+            mOtaServerImageList[i].fileSize = fileSize;
+            mOtaServerImageList[i].isValidEntry = false; /* True when the download is completed */
+            result = i;
+            break;
+        }
+    }
+
+    return result;
+}
+
+/*************************************************************************************************
+*
+*  OTA Server Serial Protocol callbacks
+*
+**************************************************************************************************/
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_HandleBlockSocket(bool_t onOff)
+\brief  This function is used to handle block sockets.
+
+\param  [in]   onOff          If TRUE, create and bind and if FALSE, close socket
+
+\return        otaStatus_t    Status of the operation
+ ***************************************************************************************************/
+static otaStatus_t OtaServer_HandleBlockSocket
+(
+    bool_t onOff
+)
+{
+    otaStatus_t status = gOtaStatus_Success_c;
+
+    if (true == onOff)
+    {
+        if (mOtaServerSetup.pOtaUdpSrvSocket == NULL)
+        {
+            otError    error;
+            otSockAddr portAddr;
+            
+            /* Set Ota Server local address and local port */
+            memset(&portAddr, 0, sizeof(portAddr));
+            portAddr.mPort = OTA_SERVER_DEFAULT_PORT;
+            mOtaServerSetup.pOtaUdpSrvSocket = &mOtaUdpSrvSocket;
+
+            /* Open Ota Server UDP socket */
+            error = otUdpOpen(mOtaServerSetup.pOtInstance, mOtaServerSetup.pOtaUdpSrvSocket, OtaClient_UdpServerService, NULL);
+
+            if (error != OT_ERROR_NONE)
+            {
+                status = gOtaStatus_NoUdpSocket_c;
+            }
+
+            if(status == gOtaStatus_Success_c)
+            {
+                error = otUdpBind(mOtaServerSetup.pOtaUdpSrvSocket, &portAddr);
+
+                if (error != OT_ERROR_NONE)
+                {
+                    otUdpClose(mOtaServerSetup.pOtaUdpSrvSocket);
+                    mOtaServerSetup.pOtaUdpSrvSocket = NULL;
+                    status = gOtaStatus_Failed_c;
+                }
+            }
+        }
+        else
+        {
+            status = gOtaStatus_Success_c;
+        }
+    }
+    else
+    {
+        if (mOtaServerSetup.pOtaUdpSrvSocket != NULL)
+        {
+            otUdpClose(mOtaServerSetup.pOtaUdpSrvSocket);
+            mOtaServerSetup.pOtaUdpSrvSocket = NULL;
+        }
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_MulticastTimeoutCb(void *pParam)
+\brief  This function is used for the ota server multicast timer callback.
+
+\param  [in]    pParam    Generic pointer containing information dependent on the multicast state.
+***************************************************************************************************/
+static void OtaServer_MulticastTimeoutCb
+(
+    void *pParam
+)
+{
+    OtaServer_MulticastMngr(pParam);
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_InitMulticast(void *pParam)
+\brief  This function is used for the initialization of the OTA Multicast mechanism.
+
+\param  [in]    pParam         Pointer to the otaServer_ImageNotify_t structure containing
+                               the Image Notification information required for initialization.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_InitMulticast
+(
+    void *pParam
+)
+{
+    otaServer_ImageNotify_t *pImageNotify;
+    otaStatus_t status = gOtaStatus_Failed_c;
+
+    if (pParam)
+    {
+        uint32_t delay;
+
+        pImageNotify = (otaServer_ImageNotify_t *)pParam;
+        memcpy(&mOtaServerSetup.multicastManufacturerCode, pImageNotify->manufacturerCode, sizeof(uint16_t));
+        memcpy(&mOtaServerSetup.multicastImageType, pImageNotify->imageType, sizeof(uint16_t));
+        memcpy(&mOtaServerSetup.multicastFileVersion, pImageNotify->fileVersion, sizeof(uint32_t));
+        memset(&mOtaServerSetup.ackBitmask, 0xFF, sizeof(mOtaServerSetup.ackBitmask));
+        mOtaServerSetup.currentWindowOffset = 0;
+        memcpy(&mOtaServerSetup.multicastImageSize, pImageNotify->fileSize, sizeof(mOtaServerSetup.multicastImageSize));
+        mOtaServerSetup.multicastNoOfImgNtf = gOtaServer_MulticastImgNtfRetransmissions_c;
+        mOtaServerSetup.multicastNoOfBlockRsp = gOtaServer_MulticastNoOfBlockRsps_c;
+        mOtaServerSetup.multicastNoOfWindowRetries = gOtaServer_MulticastWindowRetries_c;
+
+        if (mOtaServerSetup.multicastNoOfImgNtf)
+        {
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_SendImgNtf_c;
+            delay = gOtaServer_MulticastImgNtfInterval_c;
+        }
+        else
+        {
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_GenBlockReq_c;
+            delay = gOtaServer_MulticastInterval_c;
+            free(pParam);
+            pParam = NULL;
+        }
+
+        OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, pParam, delay);
+        status = gOtaStatus_Success_c;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_SendImgNtf(void *pParam)
+\brief  This function is used for the retransmission of Image Notification commands.
+
+\param  [in]    pParam          Pointer to the otaServer_ImageNotify_t structure containing
+                                the Image Notification information used for the OTA command.
+
+\return         otaStatus_t     Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_SendImgNtf
+(
+    void *pParam
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+
+    if (pParam)
+    {
+        uint32_t delay;
+        otaServer_ImageNotify_t *pImageNotify = pParam;
+        status = OtaServer_CoapSendImageNotify(pImageNotify, &in6addr_realmlocal_allthreadnodes);
+
+        if (status == gOtaStatus_Success_c)
+        {
+            mOtaServerSetup.multicastNoOfImgNtf--;
+        }
+
+        if (mOtaServerSetup.multicastNoOfImgNtf)
+        {
+            delay = gOtaServer_MulticastImgNtfInterval_c;
+        }
+        else
+        {
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_GenBlockReq_c;
+            delay = gOtaServer_MulticastInterval_c;
+            free(pParam);
+            pParam = NULL;
+        }
+
+        OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, pParam, delay);
+
+        status = gOtaStatus_Success_c;
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_GenerateBlockReq(void *pParam)
+\brief  This function is used for generating a Block Request to the local OTA Server
+        that will result in a OTA Block Response sent as a multicast.
+
+\param  [in]    pParam         Pointer to additional data. Reserved for future enhancements. Not used.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_GenerateBlockReq
+(
+    void *pParam
+)
+{
+    otaStatus_t status = gOtaStatus_Failed_c;
+    otaClientInfo_t *pOtaClientInfo;
+    otaCmd_BlockReq_t *pBlockReq;
+
+    /* Calculate the size of the Block Req taking into acount the variable length ACK bitfield. */
+    uint8_t size = sizeof(otaClientInfo_t) - 1 + sizeof(otaCmd_BlockReq_t);
+
+    (void)pParam;
+
+    pOtaClientInfo = (otaClientInfo_t *)calloc(1, size);
+
+    if (NULL == pOtaClientInfo)
+    {
+        status = gOtaStatus_NoMem_c;
+    }
+    else
+    {
+        uint32_t fragIdx, imageOffset;
+        uint32_t delay = gOtaServer_MulticastBlockRspInterval_c;
+
+        memcpy(&pOtaClientInfo->remoteAddr, &in6addr_realmlocal_allthreadnodes, sizeof(otIp6Address));
+        memcpy(&pOtaClientInfo->sourceAddr, GET_OTA_ADDRESS(mOtaServerSetup.pOtInstance), sizeof(otIp6Address));
+        pOtaClientInfo->port = OTA_SERVER_DEFAULT_PORT;
+        pOtaClientInfo->dataLen = size - sizeof(otaClientInfo_t) + 1;
+        pOtaClientInfo->timeStamp = otPlatAlarmMilliGetNow();
+
+        pBlockReq = (otaCmd_BlockReq_t *)pOtaClientInfo->pData;
+        pBlockReq->commandId = gOtaCmd_BlockReq_c;
+        memcpy(pBlockReq->manufacturerCode, &mOtaServerSetup.multicastManufacturerCode, sizeof(pBlockReq->manufacturerCode));
+        memcpy(pBlockReq->imageType, &mOtaServerSetup.multicastImageType, sizeof(pBlockReq->imageType));
+        memcpy(pBlockReq->fileVersion, &mOtaServerSetup.multicastFileVersion, sizeof(pBlockReq->fileVersion));
+        fragIdx = NWKU_GetFirstBitValue(mOtaServerSetup.ackBitmask, gOtaServer_MulticastWindowSize_c / 8, true);
+
+        imageOffset = mOtaServerSetup.currentWindowOffset + (fragIdx * gOtaMaxBlockDataSize_c);
+        memcpy(pBlockReq->fileOffset, &imageOffset, sizeof(pBlockReq->fileOffset));
+        pBlockReq->maxDataSize = gOtaMaxBlockDataSize_c;
+
+        /* Send the Block Req to the OTA Server. */
+        OtaServer_ClientProcess(pOtaClientInfo);
+
+        if (mOtaServerSetup.multicastNoOfBlockRsp == 0)
+        {
+            if (fragIdx < gOtaServer_MulticastWindowSize_c)
+            {
+                /* Last retry. */
+                NWKU_ClearBit(fragIdx, mOtaServerSetup.ackBitmask);
+                mOtaServerSetup.multicastNoOfBlockRsp = gOtaServer_MulticastNoOfBlockRsps_c;
+                /* Get next fragment index */
+                fragIdx = NWKU_GetFirstBitValue(mOtaServerSetup.ackBitmask, gOtaServer_MulticastWindowSize_c / 8, true);
+
+                if (fragIdx > (gOtaServer_MulticastWindowSize_c - 1))
+                {
+                    /* Last retry of last fragment from current window. */
+                    mOtaServerSetup.multicastState = gOtaServerMulticastState_WaitForAck_c;
+                    delay = gOtaServer_MulticastAckTimeout_c;
+                }
+            }
+        }
+        else
+        {
+            mOtaServerSetup.multicastNoOfBlockRsp--;
+        }
+
+        OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, NULL, delay);
+    }
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_MulticastUpgradeEnd(void *pParam)
+\brief  This function is used for sending the Upgrade End Response command at the end of
+        the OTA multicast process.
+
+\param  [in]    pParam         Pointer to additional data. Reserved for future enhancements. Not used.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_MulticastUpgradeEnd
+(
+    void *pParam
+)
+{
+    (void)pParam;
+    OtaServer_ResetMulticastModule(NULL);
+
+    return gOtaStatus_Success_c;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static otaStatus_t OtaServer_ProcessAckTimeout(void *pParam)
+\brief  This function is used for determining the next steps after the ACK window closes.
+
+\param  [in]    pParam         Pointer to additional data. Reserved for future enhancements. Not used.
+
+\return         otaStatus_t    Status of the operation
+***************************************************************************************************/
+static otaStatus_t OtaServer_ProcessAckTimeout
+(
+    void *pParam
+)
+{
+    otaStatus_t status = gOtaStatus_Success_c;
+    uint32_t fragIdx;
+    uint32_t delay = gOtaServer_MulticastBlockRspInterval_c;
+
+    (void)pParam;
+
+    fragIdx = NWKU_GetFirstBitValue(mOtaServerSetup.ackBitmask, gOtaServer_MulticastWindowSize_c / 8, true);
+
+    /* Check if there are fragments that require retransmission. */
+    if ((fragIdx < gOtaServer_MulticastWindowSize_c - 1) && (mOtaServerSetup.multicastNoOfWindowRetries))
+    {
+        /* Retransmit current window. */
+        mOtaServerSetup.multicastNoOfWindowRetries--;
+    }
+    else
+    {
+        /* Last window? */
+        if (mOtaServerSetup.currentWindowOffset + (gOtaServer_MulticastWindowSize_c * gOtaMaxBlockDataSize_c) >= mOtaServerSetup.multicastImageSize)
+        {
+            /* Move to the next state */
+            delay = gOtaServer_MulticastUpgradeEndDelay_c;
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_SendUpgradeEnd_c;
+        }
+        else
+        {
+            /* Window completed. Move to the next window. */
+            mOtaServerSetup.currentWindowOffset += (gOtaServer_MulticastWindowSize_c * gOtaMaxBlockDataSize_c);
+
+            if (mOtaServerSetup.currentWindowOffset + (gOtaServer_MulticastWindowSize_c * gOtaMaxBlockDataSize_c) <= mOtaServerSetup.multicastImageSize)
+            {
+                /* Current window is full */
+                memset(mOtaServerSetup.ackBitmask, 0xFF, sizeof(mOtaServerSetup.ackBitmask));
+            }
+            else
+            {
+                /* Calculate the number of fragments remaining */
+                uint8_t fragsInWindow = (mOtaServerSetup.multicastImageSize - mOtaServerSetup.currentWindowOffset) / gOtaMaxBlockDataSize_c;
+
+                if ((mOtaServerSetup.multicastImageSize - mOtaServerSetup.currentWindowOffset) % gOtaMaxBlockDataSize_c != 0)
+                {
+                    fragsInWindow++;
+                }
+
+                /* Set corresponding bits in ack bitmask. */
+                for (int i = 0; i < fragsInWindow; i++)
+                {
+                    NWKU_SetBit(i, mOtaServerSetup.ackBitmask);
+                }
+            }
+
+            mOtaServerSetup.multicastState = gOtaServerMulticastState_GenBlockReq_c;
+            /* Debug only */
+            /* Get fragment index. Should be 0, should not fail. */
+            fragIdx = NWKU_GetFirstBitValue(mOtaServerSetup.ackBitmask, gOtaServer_MulticastWindowSize_c / 8, true);
+
+        }
+    }
+
+    OtaServer_SetTimeCallback(OtaServer_MulticastTimeoutCb, NULL, delay);
+
+    return status;
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_ResetMulticastModule(void *pParam)
+\brief  Reset the OTA Multicast mechanism.
+
+\param  [in]    pParam    Pointer to data
+***************************************************************************************************/
+static void OtaServer_ResetMulticastModule
+(
+    void *pParam
+)
+{
+    if (callbackIsSet == true)
+    {
+        mOtaServerSetup.multicastState = gOtaServerMulticastState_ResetMulticast_c;
+    }
+    else
+    {
+        mOtaServerSetup.multicastState = gOtaServerMulticastState_NotInit_c;
+        mOtaServerSetup.transferType = gOtaUnicast_c;
+
+        OtaServer_ResetPercentageInfo();
+        OtaServer_StopTimeCallback();
+
+        if (pParam)
+        {
+            free(pParam);
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\private
+\fn     static void OtaServer_MulticastMngr(void *pParam)
+\brief  Ota Multicast state machine.
+
+\param  [in]    pParam    Generic pointer containing state depended information
+***************************************************************************************************/
+static void OtaServer_MulticastMngr
+(
+    void *pParam
+)
+{
+    switch (mOtaServerSetup.multicastState)
+    {
+        case gOtaServerMulticastState_NotInit_c:
+            (void)OtaServer_InitMulticast(pParam);
+            break;
+
+        case gOtaServerMulticastState_SendImgNtf_c:
+            (void)OtaServer_SendImgNtf(pParam);
+            break;
+
+        case gOtaServerMulticastState_GenBlockReq_c:
+            (void)OtaServer_GenerateBlockReq(pParam);
+            break;
+
+        case gOtaServerMulticastState_WaitForAck_c:
+            (void)OtaServer_ProcessAckTimeout(pParam);
+            break;
+
+        case gOtaServerMulticastState_SendUpgradeEnd_c:
+            (void)OtaServer_MulticastUpgradeEnd(pParam);
+            break;
+
+        case gOtaServerMulticastState_ResetMulticast_c:
+            OtaServer_ResetMulticastModule(pParam);
+            break;
+
+        case gOtaServerMulticastState_Idle_c:
+            break;
+    }
+}
+
+/*==================================================================================================
+Private debug functions
+==================================================================================================*/
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp
new file mode 100755
index 0000000..4d62cd0
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp
@@ -0,0 +1,195 @@
+/*
+ *    Copyright (c) 2019-2020, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *   This file shows how to implement the NCP vendor hook.
+ */
+
+#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
+
+#include "ncp_base.hpp"
+
+#include "../../third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h"
+namespace ot {
+namespace Ncp {
+
+otError NcpBase::VendorCommandHandler(uint8_t aHeader, unsigned int aCommand)
+{
+    otError error = OT_ERROR_NONE;
+
+    switch (aCommand)
+    {
+
+    // TODO: Implement your command handlers here.
+    case SPINEL_CMD_VENDOR_NXP_OTA_START:
+        uint8_t        otaType, start_result;
+        const char *   file_path;
+
+        SuccessOrExit(error = mDecoder.ReadUint8(otaType));
+        SuccessOrExit(error = mDecoder.ReadUtf8(file_path));
+
+        //Start OTA process
+        start_result = OtaServer_StartOta(otaType, file_path);
+
+        SuccessOrExit(error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_NXP_OTA_START_RET));
+        SuccessOrExit(error = mEncoder.WriteUint8(start_result));
+        SuccessOrExit(error = mEncoder.EndFrame());
+
+        break;
+
+    case SPINEL_CMD_VENDOR_NXP_OTA_STOP:
+        //Stop OTA process
+        SuccessOrExit(error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_NXP_OTA_STOP_RET));
+        SuccessOrExit(error = mEncoder.WriteUint8(OtaServer_StopOta()));
+        SuccessOrExit(error = mEncoder.EndFrame());
+
+        break;
+
+    case SPINEL_CMD_VENDOR_NXP_OTA_STATUS:
+        //Get OTA process status
+        otaServerPercentageInfo_t otaInfo;
+        OtaServer_GetOtaStatus(&otaInfo);
+
+        SuccessOrExit(error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_NXP_OTA_STATUS_RET));
+        SuccessOrExit(error = mEncoder.WriteData((uint8_t *)&otaInfo, sizeof(otaInfo)));
+        SuccessOrExit(error = mEncoder.EndFrame());
+
+        break;
+
+    default:
+        error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_INVALID_COMMAND);
+    }
+
+exit:
+
+    return error;
+}
+
+void NcpBase::VendorHandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag)
+{
+    // This method is a callback which mirrors `NcpBase::HandleFrameRemovedFromNcpBuffer()`.
+    // It is called when a spinel frame is sent and removed from NCP buffer.
+    //
+    // (a) This can be used to track and verify that a vendor spinel frame response is
+    //     delivered to the host (tracking the frame using its tag).
+    //
+    // (b) It indicates that NCP buffer space is now available (since a spinel frame is
+    //     removed). This can be used to implement reliability mechanisms to re-send
+    //     a failed spinel command response (or an async spinel frame) transmission
+    //     (failed earlier due to NCP buffer being full).
+
+    OT_UNUSED_VARIABLE(aFrameTag);
+}
+
+otError NcpBase::VendorGetPropertyHandler(spinel_prop_key_t aPropKey)
+{
+    otError error = OT_ERROR_NONE;
+
+    switch (aPropKey)
+    {
+
+    // TODO: Implement your property get handlers here.
+    //
+    // Get handler should retrieve the property value and then encode and write the
+    // value into the NCP buffer. If the "get" operation itself fails, handler should
+    // write a `LAST_STATUS` with the error status into the NCP buffer. `OT_ERROR_NO_BUFS`
+    // should be returned if NCP buffer is full and response cannot be written.
+
+    default:
+        error = OT_ERROR_NOT_FOUND;
+        break;
+    }
+
+    return error;
+}
+
+otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey)
+{
+    otError error = OT_ERROR_NONE;
+
+    switch (aPropKey)
+    {
+
+    // TODO: Implement your property set handlers here.
+    //
+    // Set handler should first decode the value from the input Spinel frame and then
+    // perform the corresponding set operation. The handler should not prepare the
+    // spinel response and therefore should not write anything to the NCP buffer.
+    // The error returned from handler (other than `OT_ERROR_NOT_FOUND`) indicates the
+    // error in either parsing of the input or the error of the set operation. In case
+    // of a successful "set", `NcpBase` set command handler will invoke the
+    // `VendorGetPropertyHandler()` for the same property key to prepare the response.
+
+    default:
+        error = OT_ERROR_NOT_FOUND;
+        break;
+    }
+
+    return error;
+}
+
+}  // namespace Ncp
+}  // namespace ot
+
+//-------------------------------------------------------------------------------------------------------------------
+// When OPENTHREAD_ENABLE_NCP_VENDOR_HOOK is enabled, vendor code is
+// expected to provide the `otNcpInit()` function. The reason behind
+// this is to enable vendor code to define its own sub-class of
+// `NcpBase` or `NcpUart`/`NcpSpi`.
+//
+// Example below show how to add a vendor sub-class over `NcpUart`.
+
+#include "ncp_uart.hpp"
+#include "common/new.hpp"
+
+class NcpVendorUart : public ot::Ncp::NcpUart
+{
+public:
+    NcpVendorUart(ot::Instance *aInstance)
+        : ot::Ncp::NcpUart(aInstance)
+    {}
+
+    // Add public/private methods or member variables
+};
+
+static otDEFINE_ALIGNED_VAR(sNcpVendorRaw, sizeof(NcpVendorUart), uint64_t);
+
+extern "C" void otNcpInit(otInstance *aInstance)
+{
+    NcpVendorUart *ncpVendor = NULL;
+    ot::Instance * instance  = static_cast<ot::Instance *>(aInstance);
+
+    ncpVendor = new (&sNcpVendorRaw) NcpVendorUart(instance);
+
+    if (ncpVendor == NULL || ncpVendor != ot::Ncp::NcpBase::GetNcpInstance())
+    {
+        assert(false);
+    }
+}
+
+#endif // #if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c
new file mode 100755
index 0000000..6cd1baf
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c
@@ -0,0 +1,239 @@
+/*
+* Copyright 2019-2020 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+/*==================================================================================================
+Include Files
+==================================================================================================*/
+
+#include <string.h>
+
+#include "network_utils.h"
+
+#include <openthread/ip6.h>
+
+/*==================================================================================================
+Private macros
+==================================================================================================*/
+
+/*==================================================================================================
+Private type definitions
+==================================================================================================*/
+
+/*==================================================================================================
+Private prototypes
+==================================================================================================*/
+
+/*==================================================================================================
+Private global variables declarations
+==================================================================================================*/
+
+/*==================================================================================================
+Public global variables declarations
+==================================================================================================*/
+
+/* RAM global addresses - updated when the device join the network */
+otIp6Address in6addr_linklocal_allthreadnodes = {0};
+otIp6Address in6addr_realmlocal_allthreadnodes = {0};
+otIp6Address in6addr_realmlocal_threadleaderanycast = {0};
+
+/*==================================================================================================
+Public functions
+==================================================================================================*/
+void NWKU_MemCpyReverseOrder(void* pDst, void* pSrc, uint32_t cBytes)
+{
+    if(cBytes)
+    {
+        pDst = (uint8_t *)pDst + (uint32_t)(cBytes - 1);
+
+        while (cBytes)
+        {
+            *((uint8_t *)pDst) = *((uint8_t *)pSrc);
+            pDst = (uint8_t *)pDst-1;
+            pSrc = (uint8_t *)pSrc+1;
+            cBytes--;
+        }
+    }
+}
+
+/*!*************************************************************************************************
+\fn     bool_t NWKU_GetBit(uint32_t bitNr, uint8_t *pArray)
+\brief  This function returns the value of a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+
+\retval         TRUE            if the bit is set
+\retval         FALSE           if the bit is not set
+***************************************************************************************************/
+bool_t NWKU_GetBit
+(
+    uint32_t bitNr,
+    uint8_t *pArray
+)
+{
+    return ((pArray[bitNr / 8] & (1 << (bitNr % 8))) ? true : false);
+}
+
+/*!*************************************************************************************************
+\fn     void NWKU_ClearBit(uint32_t bitNr, uint8_t* pArray)
+\brief  This function clears a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+***************************************************************************************************/
+void NWKU_ClearBit
+(
+    uint32_t bitNr,
+    uint8_t *pArray
+)
+{
+    pArray[bitNr / 8] &= ~(1 << (bitNr % 8));
+}
+
+/*!*************************************************************************************************
+\fn     void NWKU_SetBit(uint32_t bitNr, uint8_t* pArray)
+\brief  This function sets a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+***************************************************************************************************/
+void NWKU_SetBit
+(
+    uint32_t bitNr,
+    uint8_t *pArray
+)
+{
+    pArray[bitNr / 8] |= (1 << (bitNr % 8));
+}
+
+/*!*************************************************************************************************
+\fn     uint32_t NWKU_GetFirstBitValueInRange(uint8_t* pArray, uint32_t lowBitNr, uint32_t
+        highBitNr, bool_t bitValue)
+\brief  This function returns the first bit with value=bitValue in a range in the array.
+
+\param  [in]    pArray          pointer to the start of the array
+\param  [in]    lowBitNr        starting bit number
+\param  [in]    highBitNr       ending bit number
+\param  [in]    bitValue        bit value
+
+\return         uint32_t        bit number
+***************************************************************************************************/
+uint32_t NWKU_GetFirstBitValueInRange
+(
+    uint8_t *pArray,
+    uint32_t lowBitNr,
+    uint32_t highBitNr,
+    bool_t bitValue
+)
+{
+    for (; lowBitNr < highBitNr; lowBitNr++)
+    {
+        if (bitValue == NWKU_GetBit(lowBitNr, pArray))
+        {
+            return lowBitNr;
+        }
+    }
+
+    return ((uint32_t) - 1); // invalid
+}
+
+/*!*************************************************************************************************
+\fn     uint32_t getFirstBitValue(uint8_t* pArray, uint32_t arrayBytes, bool_t bitValue)
+\brief  This function returns the index of the first bit with value=bitValue.
+
+\param  [in]    pArray          pointer to the start of the array
+\param  [in]    arrayBytes      number of bytes in the array
+\param  [in]    bitValue        bit value
+
+\return         uint32_t        bit value
+***************************************************************************************************/
+uint32_t NWKU_GetFirstBitValue
+(
+    uint8_t *pArray,
+    uint32_t arrayBytes,
+    bool_t bitValue
+)
+{
+    return NWKU_GetFirstBitValueInRange(pArray, 0, (arrayBytes * 8), bitValue);
+}
+
+/*!*************************************************************************************************
+\fn    otIp6Address *NWKU_GetSpecificMcastAddr(otInstance *pOtInstance, thrMcastAllThrNodes_t type)
+\brief This function is used to get a specific multicast address (Mesh Local All nodes multicast or
+       link local All nodes multicast)
+
+\param [in]    pOtInstance         Pointer to the OpenThread instance
+\param [in]    type                Ip address type: gMcastLLAddrAllThrNodes_c, gMcastMLAddrAllThrNodes_c
+
+\retval        otIp6Address        Pointer to requested multicast address
+***************************************************************************************************/
+
+otIp6Address *NWKU_GetSpecificMcastAddr
+(
+    otInstance *pOtInstance,
+    thrMcastAllThrNodes_t type
+)
+{
+    otIp6Address *pAddr = NULL;
+    const otNetifMulticastAddress *pMCastAddr = otIp6GetMulticastAddresses(pOtInstance);
+
+    while(pMCastAddr != NULL)
+    {
+        if((type == gMcastLLAddrAllThrNodes_c) && (pMCastAddr->mAddress.mFields.m8[1] == 0x32))
+        {
+            pAddr = (otIp6Address *)&pMCastAddr->mAddress;
+            break;
+        }
+        else if((type == gMcastMLAddrAllThrNodes_c) && (pMCastAddr->mAddress.mFields.m8[1] == 0x33))
+        {
+            pAddr = (otIp6Address *)&pMCastAddr->mAddress;
+            break;
+        }
+
+        pMCastAddr = pMCastAddr->mNext;
+    }
+
+    return pAddr;
+}
+
+/*!*************************************************************************************************
+\fn     void APP_OtSetMulticastAddresses(otInstance *pOtInstance)
+\brief  This function is used to set the multicast addresses from the stack for application usage.
+
+\param  [in]    pOtInstance      Pointer to OpenThread instance
+
+\return         NONE
+***************************************************************************************************/
+void NWKU_OtSetMulticastAddresses
+(
+    otInstance *pOtInstance
+)
+{
+    otIp6Address *pAddr = NULL;
+
+    pAddr = NWKU_GetSpecificMcastAddr(pOtInstance, gMcastLLAddrAllThrNodes_c);
+
+    if(pAddr != NULL)
+    {
+        memcpy(&in6addr_linklocal_allthreadnodes, pAddr, sizeof(otIp6Address));
+    }
+
+    pAddr = NWKU_GetSpecificMcastAddr(pOtInstance, gMcastMLAddrAllThrNodes_c);
+
+    if(pAddr != NULL)
+    {
+    	memcpy(&in6addr_realmlocal_allthreadnodes, pAddr, sizeof(otIp6Address));
+    }
+}
+
+/*==================================================================================================
+Private functions
+==================================================================================================*/
+
+/*==================================================================================================
+Private debug functions
+==================================================================================================*/
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.h b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.h
new file mode 100755
index 0000000..2145c94
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/network_utils.h
@@ -0,0 +1,129 @@
+/*
+* Copyright 2019-2020 NXP
+* All rights reserved.
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+#ifndef _NETWORK_UTILS_H
+#define _NETWORK_UTILS_H
+
+/*!
+\file       network_utils.h
+\brief      This is a header file for the Network Utils module.
+*/
+
+/*==================================================================================================
+Include Files
+==================================================================================================*/
+#include <openthread/ip6.h>
+
+typedef bool bool_t;
+
+/*! Macro for IP address copy */
+#define IP_AddrCopy(dst, src) \
+        (dst)->m32[0] = (src)->m32[0]; \
+        (dst)->m32[1] = (src)->m32[1]; \
+        (dst)->m32[2] = (src)->m32[2]; \
+        (dst)->m32[3] = (src)->m32[3];
+
+/*! Macro for IPV6 address comparison */
+#define IP_IsAddrEqual(addr1, addr2) \
+        (((addr1)->m32[0] == (addr2)->m32[0]) && \
+         ((addr1)->m32[1] == (addr2)->m32[1]) && \
+         ((addr1)->m32[2] == (addr2)->m32[2]) && \
+         ((addr1)->m32[3] == (addr2)->m32[3]))
+
+/* RAM global addresses - updated when the device join the network */
+extern otIp6Address in6addr_linklocal_allthreadnodes;
+extern otIp6Address in6addr_realmlocal_allthreadnodes;
+extern otIp6Address in6addr_realmlocal_threadleaderanycast;
+
+/*==================================================================================================
+Public type definitions
+==================================================================================================*/
+/*! Multicast all thread nodes */
+typedef enum thrMcastAllThrNodes_tag
+{
+    gMcastLLAddrAllThrNodes_c,  /*!< Multicast link local - all thread nodes */
+    gMcastMLAddrAllThrNodes_c,  /*!< Multicast mesh local - all thread nodes */
+} thrMcastAllThrNodes_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!*************************************************************************************************
+\fn    otIp6Address *NWKU_GetSpecificMcastAddr(otInstance *pOtInstance, thrMcastAllThrNodes_t type)
+\brief This function is used to get a specific multicast address (Mesh Local All nodes multicast or
+       link local All nodes multicast)
+
+\param [in]    pOtInstance         Pointer to the OpenThread instance
+\param [in]    type                Ip address type: gMcastLLAddrAllThrNodes_c, gMcastMLAddrAllThrNodes_c
+
+\retval        otIp6Address        Pointer to requested multicast address
+***************************************************************************************************/
+otIp6Address *NWKU_GetSpecificMcastAddr(otInstance *pOtInstance, thrMcastAllThrNodes_t type);
+
+void NWKU_MemCpyReverseOrder(void* pDst, void* pSrc, uint32_t cBytes);
+
+/*!*************************************************************************************************
+\fn     uint32_t NWKU_GetFirstBitValueInRange(uint8_t* pArray, uint32_t lowBitNr, uint32_t
+        highBitNr, bool_t bitValue)
+\brief  This function returns the first bit with value=bitValue in a range in the array.
+
+\param  [in]    pArray          pointer to the start of the array
+\param  [in]    lowBitNr        starting bit number
+\param  [in]    highBitNr       ending bit number
+\param  [in]    bitValue        bit value
+
+\return         uint32_t        bit number
+***************************************************************************************************/
+uint32_t NWKU_GetFirstBitValueInRange(uint8_t *pArray, uint32_t lowBitNr, uint32_t highBitNr, bool_t bitValue);
+
+/*!*************************************************************************************************
+\fn     void NWKU_ClearBit(uint32_t bitNr, uint8_t* pArray)
+\brief  This function clears a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+***************************************************************************************************/
+void NWKU_ClearBit(uint32_t bitNr, uint8_t *pArray);
+
+/*!*************************************************************************************************
+\fn     void NWKU_SetBit(uint32_t bitNr, uint8_t* pArray)
+\brief  This function sets a bit in an array.
+
+\param  [in]    bitNr           bit number in the whole array
+\param  [in]    pArray          pointer to the start of the array
+***************************************************************************************************/
+void NWKU_SetBit(uint32_t bitNr, uint8_t *pArray);
+
+/*!*************************************************************************************************
+\fn     uint32_t getFirstBitValue(uint8_t* pArray, uint32_t arrayBytes, bool_t bitValue)
+\brief  This function returns the index of the first bit with value=bitValue.
+
+\param  [in]    pArray          pointer to the start of the array
+\param  [in]    arrayBytes      number of bytes in the array
+\param  [in]    bitValue        bit value
+
+\return         uint32_t        bit value
+***************************************************************************************************/
+uint32_t NWKU_GetFirstBitValue(uint8_t *pArray, uint32_t arrayBytes, bool_t bitValue);
+
+/*!*************************************************************************************************
+\fn     void APP_OtSetMulticastAddresses(otInstance *pOtInstance)
+\brief  This function is used to set the multicast addresses from the stack for application usage.
+
+\param  [in]    pOtInstance      Pointer to OpenThread instance
+
+\return         NONE
+***************************************************************************************************/
+void NWKU_OtSetMulticastAddresses(otInstance *pOtInstance);
+
+#ifdef __cplusplus
+}
+#endif
+/*================================================================================================*/
+#endif  /* _NETWORK_UTILS_H */
diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/posix_ota_server_readme.txt b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/posix_ota_server_readme.txt
new file mode 100755
index 0000000..8a11ceb
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/posix_ota_server_readme.txt
@@ -0,0 +1,64 @@
+This readme is intended to be used as a guideline for building the OpenThread POSIX Border Router application with NXP OTA server support,
+available for JN5189/K32W061(041) OpenThread SDK.
+
+The following steps must be followed:
+1. Clone the OpenThread repository available here: https://github.com/openthread
+
+2. Search for the spinel.h header file and open it. In older releases, the file was located in <ot_root>\src\ncp\, while in newer releases, the file resides in <ot_root>\src\lib\spinel\.
+
+	a. Beneath the line containing "SPINEL_CMD_VENDOR__BEGIN = 15360,", add the following lines:
+"
+    // NXP OTA START COMMAND
+	SPINEL_CMD_VENDOR_NXP_OTA_START = SPINEL_CMD_VENDOR__BEGIN + 1,
+	SPINEL_CMD_VENDOR_NXP_OTA_START_RET = SPINEL_CMD_VENDOR__BEGIN + 2,
+    SPINEL_CMD_VENDOR_NXP_OTA_STOP = SPINEL_CMD_VENDOR__BEGIN + 3,
+	SPINEL_CMD_VENDOR_NXP_OTA_STOP_RET = SPINEL_CMD_VENDOR__BEGIN + 4,
+    SPINEL_CMD_VENDOR_NXP_OTA_STATUS = SPINEL_CMD_VENDOR__BEGIN + 5,
+	SPINEL_CMD_VENDOR_NXP_OTA_STATUS_RET = SPINEL_CMD_VENDOR__BEGIN + 6,
+"
+
+	b. Beneath the line containing "SPINEL_PROP_VENDOR__BEGIN = 0x3C00,", add the following lines:
+"
+    SPINEL_PROP_NXP_OTA_START_RET = SPINEL_PROP_VENDOR__BEGIN + 0,
+    SPINEL_PROP_NXP_OTA_STOP_RET = SPINEL_PROP_VENDOR__BEGIN + 1,
+    SPINEL_PROP_NXP_OTA_STATUS_RET = SPINEL_PROP_VENDOR__BEGIN + 2,
+"
+
+	c. Save and close the file.
+
+3. Open main.c source file from <ot_root>\src\posix\.
+	a. Add the following include at the beginning of the file: #include "app_ota.h"
+	b. Before the "while (true)" loop, add a function call to OtaServerInit, for example "OtaServerInit(instance);".
+	c. At the end of the loop, before the closing brackets, add a function call to OtaServer_CheckTime, for example "OtaServer_CheckTime();".
+	d. Save and close the file.
+
+4. In Makefile.am from <ot_root>\src\posix\, do the following changes:
+	a. Add the following entry to CPPFLAGS_COMMON before $(NULL):
+"-I$(top_srcdir)/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server \"
+
+	b. Add the following entry to ot_ncp_SOURCES before $(NULL):
+"
+@top_builddir@/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c           \
+@top_builddir@/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c            \
+"
+
+	c. Add the following entry to ot_cli_SOURCES before $(NULL):
+"
+@top_builddir@/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/app_ota_server.c           \
+@top_builddir@/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/network_utils.c            \
+"
+
+	d. Save and close the file.
+
+5. In Makefile-posix from <ot_root>\src\posix\, do the following changes:
+	a. Add the following entry to configure_OPTIONS before $(NULL):
+"--with-ncp-vendor-hook-source="$(AbsTopSourceDir)/third_party/nxp/<sdk_root>/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp"\"
+
+	b. Add the following line under "# Platform specific switches":
+"COMMONCFLAGS                   += -DOPENTHREAD_ENABLE_NCP_VENDOR_HOOK=1"
+
+	c. Save and close the file.
+
+6. Run the bootstrap script and follow the rest of the steps to build and run the POSIX application described in <ot_root>\src\posix\README.md.
+
+Note: <sdk_root> needs to be replaced with JN5189DK6 or K32W061DK6.
\ No newline at end of file
diff --git a/third_party/nxp/K32W061DK6/tools/imagetool/dk6_image_tool.py b/third_party/nxp/K32W061DK6/tools/imagetool/dk6_image_tool.py
new file mode 100755
index 0000000..48ea6a2
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/tools/imagetool/dk6_image_tool.py
@@ -0,0 +1,503 @@
+#!python
+
+from collections import namedtuple
+import re
+import argparse
+import subprocess
+import struct
+from Crypto.Signature import pkcs1_15
+from Crypto.PublicKey import RSA
+from Crypto.Hash import SHA256
+from Crypto.Util import number
+import binascii
+import os
+import StringIO
+
+def auto_int(x):
+   return int(x, 0)
+
+parser = argparse.ArgumentParser(description='DK6 Image Header Generator')
+parser.add_argument('in_file', help="Binary to be post-processed: generating header and optionally appending certificate and/or signature.")
+parser.add_argument('out_file', nargs='?')
+parser.add_argument('-g', '--signature_path', help="Sets directory from which certificate and private key are to be retrieved")
+parser.add_argument('-k', '--key', action='store_true', help="2048 bits RSA private key in PEM format used to sign the full image. If -c option is used the full image includes the certificate + the signature of the certificate. The key shall be located in the same directory as the image_tool script. See priv_key.pem example.")
+parser.add_argument('-p', '--password',help="This is the pass phrase from which the encryption key is derived. This parameter is only required if key provided through the -k option is a PEM encrypted key.")
+parser.add_argument('-c', '--certificate', action='store_true', help="When option is selected, the certificate cert.bin is appended to the image.")
+parser.add_argument('-i', '--image_identifier', type=int, help="This parameter is to set the archive identifier. 0: SSBL or legacy JN518x/QN9090 applications, loaded at 0x00000000. 1: application (ZB) loaded at address 0x00004000 by default. 2: application (BLE) image loaded at address 0x00053000 by default")
+parser.add_argument('-a', '--appcore_image', action='store_true',help="This parameter is only relevant if dual application (app1 image) shall reside in flash. Do not use in conjunction with -i option.")
+parser.add_argument('-t', '--target_addr', type=int, help="Target address of image. Used in conjunction with -i option to override the default set by image identifier, or with -a option to specify address of the appcore image (app1 image).")
+parser.add_argument('-s', '--stated_size', type=int, help="This is the stated size of the image in bytes. Default is 0x48000.")
+parser.add_argument('-v', '--version', type=auto_int, default=0, help="Image version. Default is 0.")
+parser.add_argument('-b', '--verbose', type=int, default=0, help="verbosity level. Default is 0.")
+parser.add_argument('-cl', '--compatibility_list', help="Compatibility list")
+parser.add_argument('-sota', '--sota_number_of_blob', type=int, help="This parameter is used to generate the image directory command to be provisioned")
+parser.add_argument('-bid', '--blob_id', type=auto_int, help="This parameter is to add a blob id. Can be used only if the sota arg is given")
+
+
+JN518x_ES1 = 0
+args = parser.parse_args()
+
+elf_file_name = args.in_file
+bin_file_name = elf_file_name.split(".")[0]+'_temp.bin'
+
+if args.out_file is None:
+    args.out_file = elf_file_name
+
+verbose = args.verbose != 0
+
+
+def get_symbol_value(file, symb_name):
+    val = 0
+
+    objdump = subprocess.check_output(['arm-none-eabi-objdump', '--syms', file])
+
+    symb_re = re.compile(r'^([0-9a-f]{8})[\s\S]+[\s]+([0-9a-f]{8})\s([\w\.]+)')
+
+    for ln in StringIO.StringIO(objdump):
+        m = symb_re.match(ln)
+        if m:
+            if m.group(3) == symb_name:
+                val = int(m.group(1), 16)
+                break
+
+    return val
+
+def parse_sections(file):
+    sections = {}
+
+    Section = namedtuple('Section', ['idx', 'name', 'size', 'vma', 'lma', 'offset', 'align', 'flags'])
+
+    objdump = subprocess.check_output(['arm-none-eabi-objdump', '-h', file])
+
+    section_re = re.compile(r'(?P<idx>[0-9]+)\s'
+                            r'(?P<name>.{13,})s*'
+                            r'(?P<size>[0-9a-f]{8})\s*'
+                            r'(?P<vma>[0-9a-f]{8})\s*'
+                            r'(?P<lma>[0-9a-f]{8})\s*'
+                            r'(?P<offset>[0-9a-f]{8})\s*'
+                            r'(?P<align>[0-9*]*)\s*'
+                            r'(?P<flags>[[[\w]*[, [\w]*]*)')
+
+    for match in re.finditer(section_re, objdump):
+        sec_dict = match.groupdict()
+
+        sec_dict['idx'] = int(sec_dict['idx'])
+
+        for attr in ['vma', 'lma', 'size', 'offset']:
+            sec_dict[attr] = int(sec_dict[attr], 16)
+
+        sec_dict['align'] = eval(sec_dict['align'])
+
+        sections[sec_dict['name']] = Section(**sec_dict)
+
+    return sections
+
+def reverseString2by2(string, stringLength):
+    result = ""
+    i = stringLength-1
+    while i >=0:
+        result = result + string[i-1]
+        result = result + string[i]
+        i = i-2
+    return result
+
+def print_sota_img_directory_cmd(blobNumber):
+    nbBlobFound = 0
+    sota_final_print = ""
+    sota_final_print += "=================> SOTA information\n"
+    # Generate the image directory command that will be used to provison the device
+    valueToPrint = ".\\DK6Programmer.exe -V5 -s <COM_PORT> -P 1000000 -w PSECT:64@0x160="
+    for i in range(1,9):
+        bootable = "00"
+        if i==1:
+            bootable = "01"
+        position_in_flash = get_symbol_value(elf_file_name, "m_blob_position"+str(i))
+        position_in_flash = '%0*X' % (2,position_in_flash)
+        blobTargetAddr = get_symbol_value(elf_file_name, "m_blob"+str(i)+"_start")
+        blobTargetAddr = '%0*X' % (8,blobTargetAddr)
+        blobStatedSize = get_symbol_value(elf_file_name, "m_blob"+str(i)+"_size")
+        if position_in_flash != "00" and blobStatedSize != 0:
+            nbBlobFound=nbBlobFound+1
+            sota_final_print += "Position in flash = "+ position_in_flash+" - targetAddr = 0x" +blobTargetAddr+ "\n"
+        blobTargetAddr = reverseString2by2(blobTargetAddr, len(blobTargetAddr))
+        blobNbPage = blobStatedSize/512
+        blobNbPage = '%0*X' % (4,blobNbPage)
+        blobNbPage = reverseString2by2(blobNbPage, len(blobNbPage))
+        if blobStatedSize != 0:
+            valueToPrint = valueToPrint + blobTargetAddr + blobNbPage + bootable + position_in_flash
+        else:
+            valueToPrint = valueToPrint + "0000000000000000"
+    sota_final_print += "=====> Image directory command"
+    sota_final_print += valueToPrint
+    sota_final_print += "=================> (end) SOTA information"
+    if nbBlobFound == blobNumber:
+        print sota_final_print
+
+#
+# JN518x ES1 version
+######################
+if JN518x_ES1 == 1: # deprecated
+
+    BOOT_BLOCK_MARKER = 0xBB0110BB
+
+    header_struct     = struct.Struct('<7LLLLL')
+    boot_block_struct = struct.Struct('<6LQ')
+
+    sections = parse_sections(args.in_file)
+
+    last_section = None
+
+    for name, section in sections.iteritems():
+        if 'LOAD' in section.flags:
+            if last_section is None or section.lma > last_section.lma:
+                if section.size > 0:
+                    last_section = section
+
+    if args.appcore_image is True:
+        image_size = last_section.lma + last_section.size - args.target_appcore_addr
+    else:
+        image_size = last_section.lma + last_section.size
+
+    dump_section = subprocess.check_output(['arm-none-eabi-objcopy', '--dump-section', '%s=data.bin' % last_section.name, args.in_file])
+
+    if args.appcore_image is True:
+        boot_block = boot_block_struct.pack(BOOT_BLOCK_MARKER, 1, args.target_appcore_addr, image_size + boot_block_struct.size, 0, 0, 0)
+    else:
+        boot_block = boot_block_struct.pack(BOOT_BLOCK_MARKER, 0, 0, image_size + boot_block_struct.size, 0, 0, 0)
+
+    with open('data.bin', 'ab') as out_file:
+        out_file.write(boot_block)
+
+    update_section = subprocess.check_output(['arm-none-eabi-objcopy', '--update-section', '%s=data.bin' % last_section.name, args.in_file, args.out_file])
+
+    first_section = None
+
+    for name, section in sections.iteritems():
+        if 'LOAD' in section.flags:
+            if first_section is None or section.lma < first_section.lma:
+                first_section = section
+
+    with open(args.out_file, 'r+b') as elf_file:
+        elf_file.seek(first_section.offset)
+        vectors = elf_file.read(header_struct.size)
+
+        fields = list(header_struct.unpack(vectors))
+
+        vectsum = 0
+
+        for x in range(7):
+            vectsum += fields[x]
+
+        fields[7]  = (~vectsum & 0xFFFFFFFF) + 1
+        if args.appcore_image is True:
+            fields[9]  = 0x02794498
+        else:
+            fields[9]  = 0x98447902
+        #fields[9]  = 0x98447902
+        fields[10] = image_size
+
+        print "Writing checksum {:08x} to file {:s}".format(vectsum, args.out_file)
+
+        elf_file.seek(first_section.offset)
+        elf_file.write(header_struct.pack(*fields))
+
+#
+# JN518x ES2 version
+######################
+else:
+    is_signature = False
+    error = 0
+    if args.signature_path is not None:
+        sign_dir_path = os.path.join(os.path.dirname(__file__), args.signature_path)
+        priv_key_file_path = os.path.join(sign_dir_path, 'priv_key.pem')
+        cert_file_path = os.path.join(sign_dir_path, 'cert.bin')
+    else:
+        sign_dir_path = os.path.join(os.path.dirname(__file__), '')
+        priv_key_file_path = os.path.join(sign_dir_path, 'testkey_es2.pem')
+        cert_file_path = os.path.join(sign_dir_path, 'certif_es2')
+
+    if args.key is True:
+        key_file_path = priv_key_file_path
+        if verbose:
+            print "key path is " + key_file_path
+        if (os.path.isfile(key_file_path)):
+            key_file=open(key_file_path, 'r')
+            key = RSA.importKey(key_file.read(), args.password)
+            print "Private RSA key processing..."
+            is_signature = True
+
+    compatibility_struct     = struct.Struct('<2L')
+    compatibility_len_struct = struct.Struct('<L')
+    if args.compatibility_list is not None:
+        print "Compatibility list:"
+        if verbose:
+            print "    {}".format(args.compatibility_list)
+        compatibility_list = [map(auto_int, compatibility_item.split(",")) for compatibility_item in args.compatibility_list.split(";")]
+        print "    Length: {}".format(len(compatibility_list))
+        for i in range(len(compatibility_list)):
+            item = compatibility_list[i]
+            for j in range(len(item)):
+                if j ==1:
+                    blobIdCompatibilityList = "     Blob ID 0x="  + '%0*X' % (8,item[j-1])
+                    print "Blob ID =0x"+'%0*X' % (4,item[j-1]) +" - version =0x"+'%0*X' % (8,item[j])
+        compatibility_len = len(compatibility_list) * compatibility_struct.size + compatibility_len_struct.size
+        if verbose:
+            print "    {}".format(compatibility_len)
+    else:
+        compatibility_list = []
+        compatibility_len = 0
+        print "No compatibility list"
+
+    # make sure that the compatibility list is added and equals to nb_blob - 1
+    if args.sota_number_of_blob is not None and (compatibility_len/compatibility_struct.size) != args.sota_number_of_blob-1:
+        print "!!! Error the compatibility list length must be = to the number of blobs -1 : "+str(compatibility_len/compatibility_struct.size)+"(len) != "+ str(args.sota_number_of_blob-1)
+        error = 1
+    #make sure that the blob ID is given
+    if args.sota_number_of_blob is not None and args.blob_id is None:
+        print "!!! Error the blob ID is missing"
+        error = 1
+
+    bin_output = subprocess.check_output(['arm-none-eabi-objcopy', '-O', 'binary', elf_file_name, bin_file_name])
+
+    with open(bin_file_name, 'rb') as in_file:
+        input_file = in_file.read()
+
+    BOOT_BLOCK_MARKER      = 0xBB0110BB
+    IMAGE_HEADER_MARKER    = 0x98447902
+    IMAGE_HEADER_APP_CORE  = 0x02794498
+    IMAGE_HEADER_ESCORE    = IMAGE_HEADER_MARKER
+    SSBL_OR_LEGACY_ADDRESS = 0x00000000
+    SSBL_STATED_SIZE       = 0x2000
+    ZB_TARGET_ADDRESS      = SSBL_STATED_SIZE * 2
+    ZB_STATED_SIZE         = 0x4f000
+    BLE_TARGET_ADDRESS     = ZB_TARGET_ADDRESS + ZB_STATED_SIZE
+    BLE_STATED_SIZE        = 0x40000
+
+    header_struct     = struct.Struct('<7LLLLL')
+    boot_block_struct = struct.Struct('<8L')
+
+    boot_block_marker = BOOT_BLOCK_MARKER
+    if args.image_identifier is not None:
+        image_iden = args.image_identifier
+    else:
+        image_iden = 0
+
+    if verbose:
+        print "Image Identifier is {:d}".format(image_iden)
+
+   #Default value initialization
+    image_addr = 0
+    stated_size = 0
+
+    #Default value for SSBL, ZigbeeFull and BleFull image id
+    if image_iden == 0:
+        image_addr = SSBL_OR_LEGACY_ADDRESS
+        stated_size = SSBL_STATED_SIZE
+    elif image_iden == 1:
+        image_addr = ZB_TARGET_ADDRESS
+    elif image_iden == 2:
+        image_addr = BLE_TARGET_ADDRESS
+
+    image_addr = get_symbol_value(elf_file_name, 'm_app_start')
+
+    stated_size = get_symbol_value(elf_file_name, 'm_app_size')
+
+    # In case of SOTA get the position in flash from the linker it should be the app_id
+    if args.sota_number_of_blob is not None:
+        if args.image_identifier is None:
+            image_iden = get_symbol_value(elf_file_name, '__blob_position__')
+            print "Blob position in flash = #"+str(image_iden)
+
+    img_header_marker = IMAGE_HEADER_MARKER + image_iden
+
+    # Overwrite defaults for image address, stated size and header marker (-t, -s, -a options)
+    if args.target_addr is not None:
+        image_addr = args.target_addr
+    if args.stated_size is not None:
+        stated_size = args.stated_size
+    if args.appcore_image is True:
+        img_header_marker  = IMAGE_HEADER_APP_CORE
+
+    if verbose:
+        print "image_iden=%d image_addr=%x" % (image_iden, image_addr)
+        print "stated_size=%d" % (stated_size)
+        print "version=0x%0*X" % (8,args.version)
+        print "boot_block_marker=%x" % (boot_block_marker)
+
+    sections = parse_sections(elf_file_name)
+
+    last_section = None
+    for name, section in sections.iteritems():
+        if 'LOAD' in section.flags:
+            if last_section is None or section.lma > last_section.lma:
+                if section.size > 0:
+                    last_section = section
+
+    # IAR toolchain uses odd section names that contain spaces
+    # the regexp now may now return trailing spaces too, need to strip them
+    last_section_name = last_section.name.rstrip()
+    # and add quotes around the section name 
+    last_section_name = r"%s" % (last_section_name)
+	
+    boot_block_offset = last_section.lma + last_section.size + compatibility_len - image_addr
+
+    # Correction for image size not being multiple of 4 (IAR)
+    padding_len = ((4 - (boot_block_offset%4)) & 3)
+    padding_bytes = bytearray(padding_len)
+    boot_block_offset = boot_block_offset + padding_len
+
+    print "boot block offset =%x" % (boot_block_offset)
+    if verbose:
+        print "Last Section LMA={:08x} Size={:08x}".format(last_section.lma, last_section.size)
+        print "ImageAddress={:08x}".format(image_addr)
+
+    first_section = None
+
+    for name, section in sections.iteritems():
+        # print "Section: {:s} {:s} {:x} {:x}".format(name, section.flags, section.lma, section.size)
+        if 'LOAD' in section.flags:
+            if first_section is None or section.lma < first_section.lma:
+                first_section = section
+
+    header=""
+    with open(args.out_file, 'r+b') as elf_file:
+        elf_file.seek(first_section.offset)
+        vectors = elf_file.read(header_struct.size)
+
+        fields = list(header_struct.unpack(vectors))
+
+        vectsum = 0
+        for x in range(7):
+            vectsum += fields[x]
+
+        fields[7]  = (~vectsum & 0xFFFFFFFF) + 1
+        fields[8]  = img_header_marker
+        fields[9]  = boot_block_offset
+
+        #Compute crc
+        head_struct     = struct.Struct('<10L')
+        try:
+            if verbose:
+                for i in range(10):
+                    print "Header[{:d}]= {:08x}".format(i, fields[i])
+            values = head_struct.pack(fields[0],
+                                  fields[1],
+                                  fields[2],
+                                  fields[3],
+                                  fields[4],
+                                  fields[5],
+                                  fields[6],
+                                  fields[7],
+                                  fields[8],
+                                  fields[9])
+            fields[10] = binascii.crc32(values) & 0xFFFFFFFF
+        except:
+            error = 1
+
+        print "Writing checksum {:08x} to file {:s}".format(vectsum, args.out_file)
+        print "Writing CRC32 of header {:08x} to file {:s}".format(fields[10], args.out_file)
+
+
+        elf_file.seek(first_section.offset)
+        header = header_struct.pack(*fields);
+        elf_file.write(header)
+
+    dump_section = subprocess.check_output(['arm-none-eabi-objcopy',
+                                            '--dump-section',
+                                            '%s=data.bin' % last_section_name,
+                                            args.out_file])
+
+    certificate = ""
+    certificate_offset = 0
+    signature = ""
+    compatibility = ""
+    compatibility_offset = 0
+
+    if args.compatibility_list is not None:
+        compatibility_offset = last_section.lma + last_section.size - image_addr
+        compatibility = compatibility_len_struct.pack(len(compatibility_list)) + ''.join([compatibility_struct.pack(*compatibility_item) for compatibility_item in compatibility_list])
+        print "Compatibility processing..."
+
+    if (args.certificate is True):
+        certificate_offset = boot_block_offset + boot_block_struct.size
+        certif_file_path = cert_file_path
+        if verbose:
+            print "Cert key path is " + cert_file_path
+        if (os.path.isfile(certif_file_path)):
+            certif_file=open(certif_file_path, 'rb')
+            certificate = certif_file.read()
+
+        print "Certificate processing..."
+        if len(certificate) != (40+256+256):
+            print "Certificate error"
+            error = 1
+
+    if verbose:
+        print "stated size is {:08x} ({})".format(stated_size,stated_size)
+
+    if args.appcore_image is True:
+        boot_block_id = 1
+    else:
+        boot_block_id = 0
+
+    if args.blob_id is not None:
+        boot_block_id = args.blob_id
+
+    boot_block = boot_block_struct.pack(boot_block_marker,
+                                        boot_block_id,
+                                        image_addr,
+                                        boot_block_offset + boot_block_struct.size + len(certificate), # padding already included in the boot_block_offset
+                                        stated_size,
+                                        certificate_offset,
+                                        compatibility_offset,
+                                        args.version)
+
+    if (is_signature == True):
+        # Sign the complete image
+        message = header + input_file[header_struct.size:] + boot_block + certificate
+        hash = SHA256.new(message)
+
+        out_file_path = os.path.join(os.path.dirname(__file__), 'dump_python.bin')
+        file_out=open(out_file_path, 'wb')
+        file_out.write(message)
+
+        signer = pkcs1_15.new(key)
+        signature = signer.sign(hash)
+
+        print "Signature processing..."
+
+    with open('data.bin', 'ab') as out_file:
+        out_file.write(compatibility+padding_bytes+boot_block+certificate+signature)
+    if verbose:
+        print "Updating last section " + last_section.name
+
+    update_section = subprocess.check_output(['arm-none-eabi-objcopy',
+                                              '--update-section',
+                                              '%s=data.bin' % last_section_name,
+                                              elf_file_name,
+                                              args.out_file])
+
+
+    if (is_signature == True):
+        file_out.close()
+
+    bin_output = subprocess.check_output(['arm-none-eabi-objcopy',
+                                          '-O',
+                                          'binary',
+                                          elf_file_name,
+                                          bin_file_name])
+
+    print "Binary size is {:08x} ({})".format(os.stat(bin_file_name).st_size,os.stat(bin_file_name).st_size)
+
+    if args.sota_number_of_blob is not None:
+        print_sota_img_directory_cmd(args.sota_number_of_blob)
+
+    if os.stat(bin_file_name).st_size > stated_size:
+        print "Error: Binary file size ({:08x}) must be less or equal to stated size {:08x}".format(os.stat(bin_file_name).st_size, stated_size)
+        error = 1
+
+    if error != 0:
+        os.remove(elf_file_name)
+        os.remove(out_file_path)
+
+    os.remove(bin_file_name)
diff --git a/third_party/nxp/K32W061DK6/tools/imagetool/sign_images.sh b/third_party/nxp/K32W061DK6/tools/imagetool/sign_images.sh
new file mode 100755
index 0000000..5e0105a
--- /dev/null
+++ b/third_party/nxp/K32W061DK6/tools/imagetool/sign_images.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+# Copyright 2019 NXP
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Script gets as first command line argument the directory
+# containing the ELF files which will be signed using
+# $SIGNING_TOOL. After the signing process, the binary
+# is extracted from the ELF file and placed in an equivalent
+# filename with the .bin extension.
+
+
+function is_linux_package_installed()
+{
+	dpkg -s ${1} &> /dev/null
+
+	if [ $? -ne 0 ]; then
+        echo "Linux package ** ${1} ** is not installed! Please install it then recompile."
+        echo "Installation command (Debian-based Linux system): sudo apt-get install ${1}"
+		exit 1
+	fi
+}
+
+function is_python_package_installed()
+{
+	pip list --format=columns | grep -F ${1} &> /dev/null
+
+	if [ $? -ne 0 ]; then
+        echo "Python package ** ${1} ** is not installed! Please install it then recompile."
+        echo "Installation command: pip install ${1}"
+		exit 1
+	fi
+}
+
+is_linux_package_installed "python"
+is_linux_package_installed "python-pip"
+is_python_package_installed "pycrypto"
+is_python_package_installed "pycryptodome"
+
+CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+SIGNING_TOOL=$CURR_DIR/dk6_image_tool.py
+MIME_PATTERN="application/x-executable"
+
+if [ "$#" -eq 1 ]; then
+	DIR_WITH_ELFS=$1
+
+	for FILENAME in $DIR_WITH_ELFS/*; do
+		MIME_SET="$(file -ib $FILENAME)"
+
+		if [[ $MIME_SET == *"$MIME_PATTERN"* ]]; then
+			python $SIGNING_TOOL $FILENAME
+			arm-none-eabi-objcopy -O binary $FILENAME $FILENAME.bin
+		fi
+	done
+fi
diff --git a/third_party/silabs/Makefile.am b/third_party/silabs/Makefile.am
index 68fefc7..82087c3 100644
--- a/third_party/silabs/Makefile.am
+++ b/third_party/silabs/Makefile.am
@@ -28,6 +28,12 @@
 
 include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
 
+if OPENTHREAD_EXAMPLES_EFR32MG1
+lib_LIBRARIES                                                                 = \
+    libsilabs-efr32mg1-sdk.a                                                    \
+    $(NULL)
+endif
+
 if OPENTHREAD_EXAMPLES_EFR32MG12
 lib_LIBRARIES                                                                 = \
     libsilabs-efr32mg12-sdk.a                                                   \
@@ -58,6 +64,14 @@
 override CFLAGS    := $(filter-out -Wshadow,$(CFLAGS))
 override CXXFLAGS  := $(filter-out -Wshadow,$(CXXFLAGS))
 
+# Do not enable -Wundef for Silicon Labs SDK sources
+override CFLAGS    := $(filter-out -Wundef,$(CFLAGS))
+override CXXFLAGS  := $(filter-out -Wundef,$(CXXFLAGS))
+
+# Do not enable -Wcast-align for Silicon Labs SDK sources
+override CFLAGS    := $(filter-out -Wcast-align,$(CFLAGS))
+override CXXFLAGS  := $(filter-out -Wcast-align,$(CXXFLAGS))
+
 EFR32_BOARD_DIR = $(shell echo $(BOARD) | tr A-Z a-z)
 
 SDK_SRC_DIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.7
@@ -86,6 +100,8 @@
     -I$(SDK_SRC_DIR)/platform/emdrv/ustimer/inc                                 \
     -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/inc                                  \
     -I$(SDK_SRC_DIR)/platform/emdrv/dmadrv/config                               \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/inc                                    \
+    -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/config                                 \
     -I$(SDK_SRC_DIR)/platform/emlib/inc                                         \
     -I$(SDK_SRC_DIR)/platform/halconfig/inc/hal-config                          \
     -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32                         \
@@ -104,6 +120,12 @@
     -Wno-missing-field-initializers                                             \
     $(NULL)
 
+SILABS_EFR32MG1_CPPFLAGS                                                      = \
+    -I$(SDK_SRC_DIR)/hardware/kit/EFR32MG1_$(BOARD)/config                      \
+    -I$(SDK_SRC_DIR)/platform/Device/SiliconLabs/EFR32MG1P/Include              \
+    -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32/efr32xg1x               \
+    $(NULL)
+
 SILABS_EFR32MG12_CPPFLAGS                                                     = \
     -I$(SDK_SRC_DIR)/hardware/kit/EFR32MG12_$(BOARD)/config                     \
     -I$(SDK_SRC_DIR)/platform/Device/SiliconLabs/EFR32MG12P/Include             \
@@ -130,6 +152,9 @@
     gecko_sdk_suite/v2.7/hardware/kit/common/bsp/bsp_stk_leds.c                           \
     gecko_sdk_suite/v2.7/platform/emdrv/dmadrv/src/dmadrv.c                               \
     gecko_sdk_suite/v2.7/platform/emdrv/gpiointerrupt/src/gpiointerrupt.c                 \
+    gecko_sdk_suite/v2.7/platform/emdrv/nvm3/src/nvm3_default.c                           \
+    gecko_sdk_suite/v2.7/platform/emdrv/nvm3/src/nvm3_hal_flash.c                         \
+    gecko_sdk_suite/v2.7/platform/emdrv/nvm3/src/nvm3_lock.c                              \
     gecko_sdk_suite/v2.7/platform/emdrv/uartdrv/src/uartdrv.c                             \
     gecko_sdk_suite/v2.7/platform/emdrv/ustimer/src/ustimer.c                             \
     gecko_sdk_suite/v2.7/platform/emlib/src/em_adc.c                                      \
@@ -155,6 +180,13 @@
     gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/crypto_aes.c              \
     gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/crypto_ecp.c              \
     gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/crypto_management.c       \
+    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/crypto_sha.c              \
+    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/shax.c                    \
+    $(NULL)
+
+SILABS_EFR32MG1_SOURCES                                                                           = \
+    gecko_sdk_suite/v2.7/platform/Device/SiliconLabs/EFR32MG1P/Source/system_efr32mg1p.c            \
+    gecko_sdk_suite/v2.7/platform/Device/SiliconLabs/EFR32MG1P/Source/GCC/startup_efr32mg1p.c       \
     $(NULL)
 
 SILABS_EFR32MG12_SOURCES                                                                          = \
@@ -173,9 +205,24 @@
     gecko_sdk_suite/v2.7/platform/Device/SiliconLabs/EFR32MG21/Source/system_efr32mg21.c        \
     gecko_sdk_suite/v2.7/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/startup_efr32mg21.c   \
     gecko_sdk_suite/v2.7/platform/emlib/src/em_se.c                                             \
-    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_trng.c                       \
     gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_aes.c                        \
+    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_ccm.c                        \
+    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_cmac.c                       \
+    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_ecp.c                        \
+    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_jpake.c                      \
     gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_management.c                 \
+    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_sha.c                        \
+    gecko_sdk_suite/v2.7/util/third_party/mbedtls/sl_crypto/src/se_trng.c                       \
+    $(NULL)
+
+libsilabs_efr32mg1_sdk_a_CPPFLAGS                                                             = \
+    $(COMMONCPPFLAGS)                                                                           \
+    $(SILABS_EFR32MG1_CPPFLAGS)                                                                 \
+    $(NULL)
+
+libsilabs_efr32mg1_sdk_a_SOURCES                                                              = \
+    $(SILABS_COMMON_SOURCES)                                                                    \
+    $(SILABS_EFR32MG1_SOURCES)                                                                  \
     $(NULL)
 
 libsilabs_efr32mg12_sdk_a_CPPFLAGS                                                            = \
diff --git a/third_party/ti/CMakeLists.txt b/third_party/ti/CMakeLists.txt
new file mode 100644
index 0000000..b53b071
--- /dev/null
+++ b/third_party/ti/CMakeLists.txt
@@ -0,0 +1,53 @@
+#
+#  Copyright (c) 2020, The OpenThread Authors.
+#  All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. Neither the name of the copyright holder nor the
+#     names of its contributors may be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+if(OT_PLATFORM STREQUAL "cc2650")
+    add_library(cc26x0-driver INTERFACE)
+
+    target_link_libraries(cc26x0-driver
+        INTERFACE
+            ${CMAKE_CURRENT_SOURCE_DIR}/devices/cc26x0/driverlib/bin/gcc/driverlib.a
+    )
+
+    target_link_options(cc26x0-driver
+        INTERFACE
+            -T${CMAKE_CURRENT_SOURCE_DIR}/devices/cc26x0/linker_files/cc26x0f128.lds
+    )
+elseif(OT_PLATFORM STREQUAL "cc1352" OR OT_PLATFORM STREQUAL "cc2652")
+    add_library(cc13x2-cc26x2-driver INTERFACE)
+
+    target_link_libraries(cc13x2-cc26x2-driver
+        INTERFACE
+            ${CMAKE_CURRENT_SOURCE_DIR}/devices/cc13x2_cc26x2/driverlib/bin/gcc/driverlib.a
+    )
+
+    target_link_options(cc13x2-cc26x2-driver
+        INTERFACE
+            -T${CMAKE_CURRENT_SOURCE_DIR}/devices/cc13x2_cc26x2/linker_files/cc26x2r1f.lds
+    )
+endif()
diff --git a/third_party/ti/ti-openthread_1.01.0_manifest.html b/third_party/ti/ti-openthread_1.01.0_manifest.html
index d9508f9..bf3ecf2 100644
--- a/third_party/ti/ti-openthread_1.01.0_manifest.html
+++ b/third_party/ti/ti-openthread_1.01.0_manifest.html
@@ -732,7 +732,7 @@
  </td> 
  		<td><b>Location</b></td> 
  		<td id="location" name="location"> 
- [as_installed]/examples/Makefile-posix 
+ [as_installed]/examples/Makefile-simulation 
  </td> 
  	</tr> 
  	<tr> 
@@ -745,7 +745,7 @@
  <tbody> 
  	<tr> 
  		<td id="name" name="name" rowspan="2"> 
- posix platform layer 
+ simulation platform layer 
  </td> 
  		<td id="version" name="version" rowspan="2"> 
  0.01.00 
@@ -761,7 +761,7 @@
  </td> 
  		<td><b>Location</b></td> 
  		<td id="location" name="location"> 
- [as_installed]/examples/platforms/posix 
+ [as_installed]/examples/platforms/simulation 
  </td> 
  	</tr> 
  	<tr> 
@@ -1813,4 +1813,4 @@
   with 100,000+ analog ICs and embedded processors, along with software, tools
   and the industry's largest sales/support staff.</p>
 </footer>
-</body></html>
\ No newline at end of file
+</body></html>
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 86075d8..521505f 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -47,10 +47,4 @@
 endif
 endif # OPENTHREAD_BUILD_TOOLS
 
-# Always pretty (e.g. for 'make pretty') these subdirectories.
-
-PRETTY_SUBDIRS                          = \
-    spi-hdlc-adapter                      \
-    $(NULL)
-
 include $(abs_top_nlbuild_autotools_dir)/automake/post.am
diff --git a/tools/gerrit/README.md b/tools/gerrit/README.md
index eea429e..d455e87 100644
--- a/tools/gerrit/README.md
+++ b/tools/gerrit/README.md
@@ -1,29 +1,26 @@
-git-squash-merge tool
-================
+# git-squash-merge tool
 
-`git-squash-merge` is a bash script to help squash merge a given branch
-into the current branch. This tool is helpful for synchronizing
-git repositories which work with `gerrit`.
+`git-squash-merge` is a bash script to help squash merge a given branch into the current branch. This tool is helpful for synchronizing git repositories which work with `gerrit`.
 
-This command squash merges all commits from a given branch into the current branch.
-By default the changes are committed with a commit message containing the list
-of all squashed commits.
+This command squash merges all commits from a given branch into the current branch. By default the changes are committed with a commit message containing the list of all squashed commits.
 
-## Syntax ##
+## Syntax
 
 ```
 git-squash-merge [--no-list] [--no-commit] <branch> [<commit msg>]"
 ```
 
-## Parameters ##
-*  `<branch>` specifies the name of branch to merge into current branch.
-*  `<commit msg>` is an optional parameter specifying text to add to the commit message.
+## Parameters
 
-## Options ##
-* `--no-list` when used the commit message will not include the list of squashed commits.
-* `--no-commit` when used, the tool squashes and stages the changes but does not commit"
+- `<branch>` specifies the name of branch to merge into current branch.
+- `<commit msg>` is an optional parameter specifying text to add to the commit message.
 
-## Example of Use ##
+## Options
+
+- `--no-list` when used the commit message will not include the list of squashed commits.
+- `--no-commit` when used, the tool squashes and stages the changes but does not commit"
+
+## Example of Use
 
 ```
 ~/sw/openthread $ ./tools/gerrit/git-squash-merge.sh github/master "OpenThread GitHub sync"
@@ -64,4 +61,4 @@
     Change-Id: I2fd7b537fc1e0251082f091cb897b9ac25e105dd
 
 Successfully squash merged branch 'github/master' into 'HEAD'
-```
\ No newline at end of file
+```
diff --git a/tools/gerrit/git-squash-merge.sh b/tools/gerrit/git-squash-merge.sh
index c8cc919..eff4ee7 100755
--- a/tools/gerrit/git-squash-merge.sh
+++ b/tools/gerrit/git-squash-merge.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 #  Copyright (c) 2018, The OpenThread Authors.
 #  All rights reserved.
@@ -27,12 +27,13 @@
 #  POSSIBILITY OF SUCH DAMAGE.
 #
 
-die() {
-    echo " *** ERROR: " $*
+die()
+{
+    echo " *** ERROR: " "$*"
     exit 1
 }
 
-display_usage ()
+display_usage()
 {
     echo "Squash merge a given branch into the current branch"
     echo ""
@@ -40,7 +41,7 @@
     echo "By default, the changes are committed with a commit message which includes the list of all squashed commits"
     echo "(use --no-commit and --no-list options to change default behavior)."
     echo ""
-    echo "Usage: $(basename $0) [--no-list] [--no-commit] <branch> [<commit msg>]"
+    echo "Usage: $(basename "$0") [--no-list] [--no-commit] <branch> [<commit msg>]"
     echo ""
     echo "     <branch>       Specifies the name of branch to merge into current branch"
     echo "     <commit msg>   An optional parameter specifying text to add to the commit message"
@@ -53,42 +54,35 @@
 SHOULD_ADD_LIST=true
 SHOULD_COMMIT=true
 
-while test $# != 0
-do
+while test $# != 0; do
     case "$1" in
-    --help|-h|-[?])
-        display_usage
-        exit 0
-        ;;
+        --help | -h | -[?])
+            display_usage
+            exit 0
+            ;;
 
-    --no-list)
-        SHOULD_ADD_LIST=false
-        ;;
-    --no-commit)
-        SHOULD_COMMIT=false
-        ;;
-    --debug) set -x ;;
-    --*) die "Unknown argument $1" ;;
-    --)
-        shift
-        break
-        ;;
-    -*) die "Unknown argument $1" ;;
-    *)
-        break
-        ;;
+        --no-list)
+            SHOULD_ADD_LIST=false
+            ;;
+        --no-commit)
+            SHOULD_COMMIT=false
+            ;;
+        --debug) set -x ;;
+        --*) die "Unknown argument $1" ;;
+        -*) die "Unknown argument $1" ;;
+        *)
+            break
+            ;;
     esac
     shift
 done
 
-if [ "$#" -eq 0 ]
-then
+if [ "$#" -eq 0 ]; then
     display_usage
     die "No branch name"
 fi
 
-if [ "$#" -gt 2 ]
-then
+if [ "$#" -gt 2 ]; then
     display_usage
     die "Extra argument"
 fi
@@ -101,9 +95,8 @@
 # Get the list of commits (diff between current and new branch)
 # Note that the list starts with older commits
 
-if ${SHOULD_ADD_LIST}
-then
-    commit_list=$(git log HEAD..$branch --oneline --decorate=no --reverse)
+if ${SHOULD_ADD_LIST}; then
+    commit_list=$(git log HEAD.."$branch" --oneline --decorate=no --reverse)
 else
     commit_list=""
 fi
@@ -116,19 +109,17 @@
     commit_msg="${commit_msg_header}${NEWLINE}${NEWLINE}$2${NEWLINE}${NEWLINE}${commit_list}"
 fi
 
-git merge --squash $branch  1> /dev/null 2> /dev/null || die "Failed to perform 'git merge -squash $branch'"
+git merge --squash "$branch" 1>/dev/null 2>/dev/null || die "Failed to perform 'git merge -squash $branch'"
 
 # Check if there is anything staged
-git diff --cached --quiet
-if [ $? -eq 0 ]; then
+if ! git diff --cached --quiet; then
     echo "No changes to commit when squash merging branch '$branch' into '$cur_branch'"
     exit 0
 fi
 
-if ${SHOULD_COMMIT}
-then
+if ${SHOULD_COMMIT}; then
     # Commit the staged changes
-    git commit -m "$commit_msg" 1> /dev/null 2> /dev/null || die "git commit failed${NEWLINE}${NEWLINE}$(cat $TMP)"
+    git commit -m "$commit_msg" 1>/dev/null 2>/dev/null || die "git commit failed${NEWLINE}${NEWLINE}$(cat "$TMP")"
 
     git log -1
 
@@ -136,4 +127,3 @@
 else
     echo "Successfully prepared squash merge of branch '$branch' into '$cur_branch' - ready to commit"
 fi
-
diff --git a/tools/harness-automation/autothreadharness/harness_case.py b/tools/harness-automation/autothreadharness/harness_case.py
index 5cf8fa4..fa5ba60 100644
--- a/tools/harness-automation/autothreadharness/harness_case.py
+++ b/tools/harness-automation/autothreadharness/harness_case.py
@@ -154,7 +154,8 @@
     auto_dut = settings.AUTO_DUT
     """bool: whether use harness auto dut feature"""
 
-    timeout = hasattr(settings, 'TIMEOUT') and settings.TIMEOUT or DEFAULT_TIMEOUT
+    timeout = hasattr(settings,
+                      'TIMEOUT') and settings.TIMEOUT or DEFAULT_TIMEOUT
     """number: timeout in seconds to stop running this test case"""
 
     started = 0
@@ -170,17 +171,19 @@
         self.dut = None
         self._browser = None
         self._hc = None
-        self.result_dir = '%s\\%s' % (settings.OUTPUT_PATH, self.__class__.__name__)
+        self.result_dir = '%s\\%s' % (settings.OUTPUT_PATH,
+                                      self.__class__.__name__)
         self.history = HistoryHelper()
         self.add_all_devices = False
         self.new_th = False
 
         harness_info = ConfigParser.ConfigParser()
         harness_info.read('%s\\info.ini' % settings.HARNESS_HOME)
-        if harness_info.has_option('Thread_Harness_Info', 'Version') and harness_info.has_option(
-            'Thread_Harness_Info', 'Mode'
-        ):
-            harness_version = harness_info.get('Thread_Harness_Info', 'Version').rsplit(' ', 1)[1]
+        if harness_info.has_option('Thread_Harness_Info',
+                                   'Version') and harness_info.has_option(
+                                       'Thread_Harness_Info', 'Mode'):
+            harness_version = harness_info.get('Thread_Harness_Info',
+                                               'Version').rsplit(' ', 1)[1]
             harness_mode = harness_info.get('Thread_Harness_Info', 'Mode')
 
             if harness_mode == 'External' and harness_version > '1.4.0':
@@ -218,7 +221,8 @@
 
         while True:
             try:
-                pdu = pdu_factory.create_pdu_controller(settings.PDU_CONTROLLER_TYPE)
+                pdu = pdu_factory.create_pdu_controller(
+                    settings.PDU_CONTROLLER_TYPE)
                 pdu.open(**settings.PDU_CONTROLLER_OPEN_PARAMS)
             except EOFError:
                 logger.warning('Failed to connect to telnet')
@@ -248,18 +252,25 @@
         time.sleep(2)
 
         harness_config = ConfigParser.ConfigParser()
-        harness_config.read('%s\\Config\\Configuration.ini' % settings.HARNESS_HOME)
-        if harness_config.has_option('THREAD_HARNESS_CONFIG', 'BrowserAutoNavigate') and harness_config.getboolean(
-            'THREAD_HARNESS_CONFIG', 'BrowserAutoNavigate'
-        ):
-            logger.error('BrowserAutoNavigate in Configuration.ini should be False')
-            raise FailError('BrowserAutoNavigate in Configuration.ini should be False')
+        harness_config.read('%s\\Config\\Configuration.ini' %
+                            settings.HARNESS_HOME)
+        if harness_config.has_option(
+                'THREAD_HARNESS_CONFIG',
+                'BrowserAutoNavigate') and harness_config.getboolean(
+                    'THREAD_HARNESS_CONFIG', 'BrowserAutoNavigate'):
+            logger.error(
+                'BrowserAutoNavigate in Configuration.ini should be False')
+            raise FailError(
+                'BrowserAutoNavigate in Configuration.ini should be False')
         if settings.MIXED_DEVICE_TYPE:
             if harness_config.has_option(
-                'THREAD_HARNESS_CONFIG', 'EnableDeviceSelection'
-            ) and not harness_config.getboolean('THREAD_HARNESS_CONFIG', 'EnableDeviceSelection'):
-                logger.error('EnableDeviceSelection in Configuration.ini should be True')
-                raise FailError('EnableDeviceSelection in Configuration.ini should be True')
+                    'THREAD_HARNESS_CONFIG',
+                    'EnableDeviceSelection') and not harness_config.getboolean(
+                        'THREAD_HARNESS_CONFIG', 'EnableDeviceSelection'):
+                logger.error(
+                    'EnableDeviceSelection in Configuration.ini should be True')
+                raise FailError(
+                    'EnableDeviceSelection in Configuration.ini should be True')
 
     def _destroy_harness(self):
         """Stop harness backend service
@@ -299,14 +310,14 @@
             chrome_options.add_argument('--disable-infobars')
             chrome_options.add_argument('--ignore-certificate-errors')
             chrome_options.add_experimental_option(
-                'prefs', {'profile.managed_default_content_settings.notifications': 1}
-            )
+                'prefs',
+                {'profile.managed_default_content_settings.notifications': 1})
 
             browser = webdriver.Chrome(chrome_options=chrome_options)
             browser.set_page_load_timeout(20)
             browser.implicitly_wait(1)
-            browser.maximize_window()
             browser.get(settings.HARNESS_URL)
+            browser.maximize_window()
             self._browser = browser
             if not wait_until(lambda: 'Thread' in browser.title, 30):
                 self.assertIn('Thread', browser.title)
@@ -323,10 +334,11 @@
         self._browser = None
 
     def _init_rf_shield(self):
-        if getattr(settings, 'SHIELD_CONTROLLER_TYPE', None) and getattr(settings, 'SHIELD_CONTROLLER_PARAMS', None):
+        if getattr(settings, 'SHIELD_CONTROLLER_TYPE', None) and getattr(
+                settings, 'SHIELD_CONTROLLER_PARAMS', None):
             self.rf_shield = get_rf_shield_controller(
-                shield_type=settings.SHIELD_CONTROLLER_TYPE, params=settings.SHIELD_CONTROLLER_PARAMS
-            )
+                shield_type=settings.SHIELD_CONTROLLER_TYPE,
+                params=settings.SHIELD_CONTROLLER_PARAMS)
         else:
             self.rf_shield = None
 
@@ -355,7 +367,8 @@
             os.system('del /q "%s\\Reports\\*.*"' % settings.HARNESS_HOME)
         else:
             logger.info('Empty files in temps')
-            os.system('del /q "%s\\Thread_Harness\\temp\\*.*"' % settings.HARNESS_HOME)
+            os.system('del /q "%s\\Thread_Harness\\temp\\*.*"' %
+                      settings.HARNESS_HOME)
 
         # create directory
         os.system('mkdir %s' % self.result_dir)
@@ -393,16 +406,19 @@
             if dialog and dialog.get_attribute('aria-hidden') == 'false':
                 times = 100
                 while times:
-                    status = dialog.find_element_by_class_name('status-notify').text
+                    status = dialog.find_element_by_class_name(
+                        'status-notify').text
                     if 'Searching' in status:
                         logger.info('Still detecting..')
                     elif 'Not' in status:
                         logger.warning('Sniffer device not verified!')
-                        button = dialog.find_element_by_id('snifferAutoDetectBtn')
+                        button = dialog.find_element_by_id(
+                            'snifferAutoDetectBtn')
                         button.click()
                     elif 'Verified' in status:
                         logger.info('Verified!')
-                        button = dialog.find_element_by_id('saveCaptureSettings')
+                        button = dialog.find_element_by_id(
+                            'saveCaptureSettings')
                         button.click()
                         break
                     else:
@@ -446,12 +462,14 @@
                 if dialog.get_attribute('aria-hidden') != 'false':
                     raise Exception('Missing General Setup dialog')
 
-                field = dialog.find_element_by_id('inp_general_child_update_wait_time')
+                field = dialog.find_element_by_id(
+                    'inp_general_child_update_wait_time')
                 field.clear()
                 if self.child_timeout:
                     field.send_keys(str(self.child_timeout))
 
-                field = dialog.find_element_by_id('inp_general_sed_polling_rate')
+                field = dialog.find_element_by_id(
+                    'inp_general_sed_polling_rate')
                 field.clear()
                 if self.sed_polling_interval:
                     field.send_keys(str(self.sed_polling_interval))
@@ -508,31 +526,33 @@
         selected_hw_num = len(selected_hw_set)
 
         while selected_hw_num:
-            remove_button = selected_hw_set[selected_hw_num - 1].find_element_by_class_name('removeSelectedDevice')
+            remove_button = selected_hw_set[selected_hw_num -
+                                            1].find_element_by_class_name(
+                                                'removeSelectedDevice')
             remove_button.click()
             selected_hw_num = selected_hw_num - 1
 
         devices = [
-            device
-            for device in settings.GOLDEN_DEVICES
-            if not self.history.is_bad_golden_device(device[0])
-            and not (settings.DUT_DEVICE and device[0] == settings.DUT_DEVICE[0])
+            device for device in settings.GOLDEN_DEVICES
+            if not self.history.is_bad_golden_device(device[0]) and
+            not (settings.DUT_DEVICE and device[0] == settings.DUT_DEVICE[0])
         ]
-        logger.info('Available golden devices: %s', json.dumps(devices, indent=2))
+        logger.info('Available golden devices: %s', json.dumps(devices,
+                                                               indent=2))
 
         shield_devices = [
-            shield_device
-            for shield_device in settings.SHIELD_GOLDEN_DEVICES
-            if not self.history.is_bad_golden_device(shield_device[0])
-            and not (settings.DUT2_DEVICE and shield_device[0] == settings.DUT2_DEVICE[0])
+            shield_device for shield_device in settings.SHIELD_GOLDEN_DEVICES
+            if not self.history.is_bad_golden_device(shield_device[0]) and
+            not (settings.DUT2_DEVICE and
+                 shield_device[0] == settings.DUT2_DEVICE[0])
         ]
-        logger.info('Available shield golden devices: %s', json.dumps(shield_devices, indent=2))
+        logger.info('Available shield golden devices: %s',
+                    json.dumps(shield_devices, indent=2))
         golden_devices_required = self.golden_devices_required
 
         dut_device = ()
         if settings.DUT_DEVICE:
             dut_device = settings.DUT_DEVICE
-
         """check if test case needs to use RF-shield box and its device order in Testbed page
         Two parameters case_need_shield & device_order should be set in the case script
         according to the requires: https://openthread.io/certification/test-cases#rf_shielding
@@ -562,9 +582,11 @@
                 logger.info('Must set DUT2_DEVICE')
                 raise FailError('DUT2_DEVICE must be set in settings.py')
             if isinstance(self.device_order, list) and self.device_order:
-                logger.info('case %s devices ordered by %s ', self.case, self.device_order)
+                logger.info('case %s devices ordered by %s ', self.case,
+                            self.device_order)
             else:
-                logger.info('case %s uses %s as DUT', self.case, settings.DUT2_DEVICE)
+                logger.info('case %s uses %s as DUT', self.case,
+                            settings.DUT2_DEVICE)
 
         # for test bed with multi-vendor devices
         if settings.MIXED_DEVICE_TYPE:
@@ -586,7 +608,8 @@
                     case_id = match_line.group(1)
 
                     if re.sub(r'\.', ' ', case_id) == self.case:
-                        logger.info('Get line by case %s: %s', case_id, topo_line)
+                        logger.info('Get line by case %s: %s', case_id,
+                                    topo_line)
                         topo_device_list = re.split(',', match_line.group(2))
                         for i in range(len(topo_device_list)):
                             topo_device = re.split(':', topo_device_list[i])
@@ -595,9 +618,12 @@
                     else:
                         continue
             except Exception as e:
-                logger.info('Get devices from topology config file error: %s', e)
+                logger.info('Get devices from topology config file error: %s',
+                            e)
                 raise GoldenDeviceNotEnoughError()
-            logger.info('Golden devices in topology config file for case %s: %s', case_id, topo_mixed_devices)
+            logger.info(
+                'Golden devices in topology config file for case %s: %s',
+                case_id, topo_mixed_devices)
             f_topo.close()
             golden_device_candidates = []
             missing_golden_devices = topo_mixed_devices[:]
@@ -611,16 +637,16 @@
                         # mapping device in device_order which needs to be shielded
                         if device_order_item[1]:
                             if 'DUT' in device_order_item[0]:
-                                golden_device_candidates.append(settings.DUT2_DEVICE)
+                                golden_device_candidates.append(
+                                    settings.DUT2_DEVICE)
                                 dut_device = settings.DUT2_DEVICE
                                 matched_dut = True
                                 matched = True
                                 break
                             for device_item in shield_devices:
-                                if (
-                                    device_order_item[0] == mixed_device_item[0]
-                                    and mixed_device_item[1] == device_item[1]
-                                ):
+                                if (device_order_item[0] == mixed_device_item[0]
+                                        and
+                                        mixed_device_item[1] == device_item[1]):
                                     golden_device_candidates.append(device_item)
                                     shield_devices.remove(device_item)
                                     matched = True
@@ -628,21 +654,22 @@
                         # mapping device in device_order which does not need to be shielded
                         else:
                             if 'DUT' in device_order_item[0]:
-                                golden_device_candidates.append(settings.DUT_DEVICE)
+                                golden_device_candidates.append(
+                                    settings.DUT_DEVICE)
                                 matched_dut = True
                                 matched = True
                                 break
                             for device_item in devices:
-                                if (
-                                    device_order_item[0] == mixed_device_item[0]
-                                    and mixed_device_item[1] == device_item[1]
-                                ):
+                                if (device_order_item[0] == mixed_device_item[0]
+                                        and
+                                        mixed_device_item[1] == device_item[1]):
                                     golden_device_candidates.append(device_item)
                                     devices.remove(device_item)
                                     matched = True
                                     break
                     if not matched:
-                        logger.info('Golden device not enough in : no %s', device_order_item)
+                        logger.info('Golden device not enough in : no %s',
+                                    device_order_item)
                         raise GoldenDeviceNotEnoughError()
                 if not matched_dut:
                     raise FailError('Failed to find DUT in device_order')
@@ -656,7 +683,9 @@
                             devices.remove(device_item)
                             missing_golden_devices.remove(mixed_device_item)
                             break
-                logger.info('Golden devices in topology config file mapped in settings : %s', golden_device_candidates)
+                logger.info(
+                    'Golden devices in topology config file mapped in settings : %s',
+                    golden_device_candidates)
                 if len(topo_mixed_devices) != len(golden_device_candidates):
                     device_dict = dict()
                     for missing_device in missing_golden_devices:
@@ -669,7 +698,8 @@
                 else:
                     devices = golden_device_candidates
                     golden_devices_required = len(devices)
-                    logger.info('All case-needed golden devices: %s', json.dumps(devices, indent=2))
+                    logger.info('All case-needed golden devices: %s',
+                                json.dumps(devices, indent=2))
         # for test bed with single vendor devices
         else:
             golden_device_candidates = []
@@ -680,7 +710,8 @@
                     # choose device which needs to be shielded
                     if device_order_item[1]:
                         if 'DUT' in device_order_item[0]:
-                            golden_device_candidates.append(settings.DUT2_DEVICE)
+                            golden_device_candidates.append(
+                                settings.DUT2_DEVICE)
                             dut_device = settings.DUT2_DEVICE
                             matched_dut = True
                             matched = True
@@ -703,7 +734,8 @@
                                 matched = True
                                 break
                     if not matched:
-                        logger.info('Golden device not enough in : no %s', device_order_item)
+                        logger.info('Golden device not enough in : no %s',
+                                    device_order_item)
                         raise GoldenDeviceNotEnoughError()
                 if not matched_dut:
                     raise FailError('Failed to find DUT in device_order')
@@ -720,7 +752,8 @@
             raise GoldenDeviceNotEnoughError()
 
         # add golden devices
-        number_of_devices_to_add = len(devices) if self.add_all_devices else golden_devices_required
+        number_of_devices_to_add = len(
+            devices) if self.add_all_devices else golden_devices_required
         for i in range(number_of_devices_to_add):
             self._add_device(*devices.pop())
 
@@ -734,24 +767,29 @@
 
         # enable AUTO DUT
         if self.auto_dut:
-            checkbox_auto_dut = browser.find_element_by_id('EnableAutoDutSelection')
+            checkbox_auto_dut = browser.find_element_by_id(
+                'EnableAutoDutSelection')
             if not checkbox_auto_dut.is_selected():
                 checkbox_auto_dut.click()
                 time.sleep(1)
 
             if settings.DUT_DEVICE:
-                radio_auto_dut = browser.find_element_by_class_name('AutoDUT_RadBtns')
+                radio_auto_dut = browser.find_element_by_class_name(
+                    'AutoDUT_RadBtns')
                 if not radio_auto_dut.is_selected() and not self.device_order:
                     radio_auto_dut.click()
 
                 if self.device_order:
-                    selected_hw_set = test_bed.find_elements_by_class_name('selected-hw')
+                    selected_hw_set = test_bed.find_elements_by_class_name(
+                        'selected-hw')
                     for selected_hw in selected_hw_set:
-                        form_inputs = selected_hw.find_elements_by_tag_name('input')
+                        form_inputs = selected_hw.find_elements_by_tag_name(
+                            'input')
                         form_port = form_inputs[0]
                         port = form_port.get_attribute('value').encode('utf8')
                         if port == dut_device[0]:
-                            radio_auto_dut = selected_hw.find_element_by_class_name('AutoDUT_RadBtns')
+                            radio_auto_dut = selected_hw.find_element_by_class_name(
+                                'AutoDUT_RadBtns')
                             if not radio_auto_dut.is_selected():
                                 radio_auto_dut.click()
 
@@ -760,19 +798,23 @@
                 self._connect_devices()
                 button_next = browser.find_element_by_id('nextBtn')
                 if not wait_until(
-                    lambda: 'disabled' not in button_next.get_attribute('class'),
-                    times=(30 + 4 * number_of_devices_to_add),
+                        lambda: 'disabled' not in button_next.get_attribute(
+                            'class'),
+                        times=(30 + 4 * number_of_devices_to_add),
                 ):
                     bad_ones = []
-                    selected_hw_set = test_bed.find_elements_by_class_name('selected-hw')
+                    selected_hw_set = test_bed.find_elements_by_class_name(
+                        'selected-hw')
                     for selected_hw in selected_hw_set:
-                        form_inputs = selected_hw.find_elements_by_tag_name('input')
+                        form_inputs = selected_hw.find_elements_by_tag_name(
+                            'input')
                         form_port = form_inputs[0]
                         if form_port.is_enabled():
                             bad_ones.append(selected_hw)
 
                     for selected_hw in bad_ones:
-                        form_inputs = selected_hw.find_elements_by_tag_name('input')
+                        form_inputs = selected_hw.find_elements_by_tag_name(
+                            'input')
                         form_port = form_inputs[0]
                         port = form_port.get_attribute('value').encode('utf8')
                         if port == dut_device[0]:
@@ -788,7 +830,8 @@
                             self.history.mark_bad_golden_device(port)
 
                         # remove the bad one
-                        selected_hw.find_element_by_class_name('removeSelectedDevice').click()
+                        selected_hw.find_element_by_class_name(
+                            'removeSelectedDevice').click()
                         time.sleep(0.1)
 
                         if len(devices):
@@ -804,14 +847,17 @@
                         continue
 
                 if self.auto_dut and not settings.DUT_DEVICE:
-                    radio_auto_dut = browser.find_element_by_class_name('AutoDUT_RadBtns')
+                    radio_auto_dut = browser.find_element_by_class_name(
+                        'AutoDUT_RadBtns')
                     if not radio_auto_dut.is_selected():
                         radio_auto_dut.click()
 
                     time.sleep(5)
 
                 button_next.click()
-                if not wait_until(lambda: self._browser.current_url.endswith('TestExecution.html'), 20):
+                if not wait_until(
+                        lambda: self._browser.current_url.endswith(
+                            'TestExecution.html'), 20):
                     raise Exception('Failed to load TestExecution page')
             except FailError:
                 raise
@@ -829,11 +875,22 @@
         time.sleep(1)
 
         checkbox = None
-        wait_until(lambda: self._browser.find_elements_by_css_selector('.tree-node .tree-title') and True)
-        elems = self._browser.find_elements_by_css_selector('.tree-node .tree-title')
+        wait_until(lambda: self._browser.find_elements_by_css_selector(
+            '.tree-node .tree-title') and True)
+        elems = self._browser.find_elements_by_css_selector(
+            '.tree-node .tree-title')
         finder = re.compile(r'.*\b' + case + r'\b')
         finder_dotted = re.compile(r'.*\b' + case.replace(' ', r'\.') + r'\b')
         for elem in elems:
+            # elem.txt might be null when the required reference devices could
+            # not be met (either due to the quantity or the type) for specific test.
+            # perform() will throw exceptions if elem.text is null since Chrome
+            # and chromedriver 80. If elem is not shown in current case list
+            # window, move_to_element() will not work either.
+            if not elem.text:
+                continue
+            # execute a javascript to scroll the window to the elem
+            self._browser.execute_script('arguments[0].scrollIntoView();', elem)
             action_chains = ActionChains(self._browser)
             action_chains.move_to_element(elem)
             action_chains.perform()
@@ -853,7 +910,9 @@
 
         elem = self._browser.find_element_by_id('runTest')
         elem.click()
-        if not wait_until(lambda: self._browser.find_element_by_id('stopTest') and True, 10):
+        if not wait_until(
+                lambda: self._browser.find_element_by_id('stopTest') and True,
+                10):
             raise Exception('Failed to start test case')
 
     def _collect_result(self):
@@ -863,11 +922,14 @@
         """
 
         if self.new_th:
-            os.system('copy "%s\\Reports\\*.*" "%s"' % (settings.HARNESS_HOME, self.result_dir))
+            os.system('copy "%s\\Reports\\*.*" "%s"' %
+                      (settings.HARNESS_HOME, self.result_dir))
         else:
-            os.system('copy "%s\\Thread_Harness\\temp\\*.*" "%s"' % (settings.HARNESS_HOME, self.result_dir))
+            os.system('copy "%s\\Thread_Harness\\temp\\*.*" "%s"' %
+                      (settings.HARNESS_HOME, self.result_dir))
 
-        os.system('copy "%s\\Captures\\*.pcapng" %s\\' % (settings.HARNESS_HOME, self.result_dir))
+        os.system('copy "%s\\Captures\\*.pcapng" %s\\' %
+                  (settings.HARNESS_HOME, self.result_dir))
 
     def _wait_dialog(self):
         """Wait for dialogs and handle them until done.
@@ -884,7 +946,8 @@
                 logger.exception('Failed to get dialog.')
             else:
                 if dialog and dialog.get_attribute('aria-hidden') == 'false':
-                    title = dialog.find_element_by_class_name('modal-title').text
+                    title = dialog.find_element_by_class_name(
+                        'modal-title').text
                     time.sleep(1)
                     logger.info('Handling dialog[%s]', title)
 
@@ -918,15 +981,21 @@
             if self.timeout % 10 == 0:
                 lines = self._hc.tail()
                 if 'SUCCESS: The process "dumpcap.exe" with PID ' in lines:
-                    logger.info('Tshark should be ended now, lets wait at most 30 seconds.')
-                    if not wait_until(lambda: 'tshark.exe' not in subprocess.check_output('tasklist'), 30):
+                    logger.info(
+                        'Tshark should be ended now, lets wait at most 30 seconds.'
+                    )
+                    if not wait_until(
+                            lambda: 'tshark.exe' not in subprocess.check_output(
+                                'tasklist'), 30):
                         res = subprocess.check_output(
-                            'taskkill /t /f /im tshark.exe', stderr=subprocess.STDOUT, shell=True
-                        )
+                            'taskkill /t /f /im tshark.exe',
+                            stderr=subprocess.STDOUT,
+                            shell=True)
                         logger.info(res)
 
         # Wait until case really stopped
-        wait_until(lambda: self._browser.find_element_by_id('runTest') and True, 30)
+        wait_until(lambda: self._browser.find_element_by_id('runTest') and True,
+                   30)
 
         if error:
             raise FailError('Fail for previous exceptions')
@@ -963,7 +1032,8 @@
             self.dut.extpanid = settings.THREAD_EXTPANID
             self.dut.start()
 
-        elif title.startswith('MAC Address Required') or title.startswith('DUT Random Extended MAC Address Required'):
+        elif title.startswith('MAC Address Required') or title.startswith(
+                'DUT Random Extended MAC Address Required'):
             mac = self.dut.mac
             inp = dialog.find_element_by_id('cnfrmInpText')
             inp.clear()
@@ -973,7 +1043,8 @@
             ll64 = None
             for addr in self.dut.addrs:
                 addr = addr.lower()
-                if addr.startswith('fe80') and not re.match('.+ff:fe00:[0-9a-f]{0,4}$', addr):
+                if addr.startswith('fe80') and not re.match(
+                        '.+ff:fe00:[0-9a-f]{0,4}$', addr):
                     ll64 = addr
                     break
 
@@ -1006,7 +1077,8 @@
         elif title.startswith('ML64 Address'):
             ml64 = None
             for addr in self.dut.addrs:
-                if addr.startswith('fd') and not re.match('.+ff:fe00:[0-9a-f]{0,4}$', addr):
+                if addr.startswith('fd') and not re.match(
+                        '.+ff:fe00:[0-9a-f]{0,4}$', addr):
                     ml64 = addr
                     break
 
@@ -1018,18 +1090,21 @@
             inp.clear()
             inp.send_keys(ml64)
 
-        elif title.startswith('Shield Devices') or title.startswith('Shield DUT'):
+        elif title.startswith('Shield Devices') or title.startswith(
+                'Shield DUT'):
             time.sleep(2)
             if self.rf_shield:
                 logger.info('Shielding devices')
                 with self.rf_shield:
                     self.rf_shield.shield()
             elif self.dut and settings.SHIELD_SIMULATION:
-                self.dut.channel = (self.channel == THREAD_CHANNEL_MAX and THREAD_CHANNEL_MIN) or (self.channel + 1)
+                self.dut.channel = (self.channel == THREAD_CHANNEL_MAX and
+                                    THREAD_CHANNEL_MIN) or (self.channel + 1)
             else:
                 input('Shield DUT and press enter to continue..')
 
-        elif title.startswith('Unshield Devices') or title.startswith('Bring DUT back to network'):
+        elif title.startswith('Unshield Devices') or title.startswith(
+                'Bring DUT back to network'):
             time.sleep(5)
             if self.rf_shield:
                 logger.info('Unshielding devices')
@@ -1044,7 +1119,8 @@
             body = dialog.find_element_by_id('cnfrmMsg').text
             body = body.split(': ')[1]
             params = reduce(
-                lambda params, param: params.update(((param[0].strip(' '), param[1]),)) or params,
+                lambda params, param: params.update(
+                    ((param[0].strip(' '), param[1]),)) or params,
                 [it.split('=') for it in body.split(', ')],
                 {},
             )
diff --git a/tools/harness-automation/autothreadharness/harness_controller.py b/tools/harness-automation/autothreadharness/harness_controller.py
index 5f9ad4a..d1b8bd9 100644
--- a/tools/harness-automation/autothreadharness/harness_controller.py
+++ b/tools/harness-automation/autothreadharness/harness_controller.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import ConfigParser
 import logging
 import os
@@ -93,7 +92,8 @@
                 % (settings.HARNESS_HOME, settings.HARNESS_HOME),
             )
 
-            self.harness_file = '%s\\harness-%s.log' % (self.result_dir, time.strftime('%Y%m%d%H%M%S'))
+            self.harness_file = '%s\\harness-%s.log' % (
+                self.result_dir, time.strftime('%Y%m%d%H%M%S'))
             with open(self.harness_file, 'w') as harness_out:
                 self.harness = subprocess.Popen(
                     [
@@ -113,7 +113,10 @@
         if self.miniweb:
             logger.warning('Miniweb already started')
         else:
-            with open('%s\\miniweb-%s.log' % (self.result_dir, time.strftime('%Y%m%d%H%M%S')), 'w') as miniweb_out:
+            with open(
+                    '%s\\miniweb-%s.log' %
+                (self.result_dir, time.strftime('%Y%m%d%H%M%S')),
+                    'w') as miniweb_out:
                 self.miniweb = subprocess.Popen(
                     [settings.HARNESS_HOME + '\\MiniWeb\\miniweb.exe'],
                     stdout=miniweb_out,
diff --git a/tools/harness-automation/autothreadharness/helpers.py b/tools/harness-automation/autothreadharness/helpers.py
index 1a931de..e8834a1 100644
--- a/tools/harness-automation/autothreadharness/helpers.py
+++ b/tools/harness-automation/autothreadharness/helpers.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import json
 import logging
 
diff --git a/tools/harness-automation/autothreadharness/open_thread_controller.py b/tools/harness-automation/autothreadharness/open_thread_controller.py
index 5bfda3a..44ad8ac 100644
--- a/tools/harness-automation/autothreadharness/open_thread_controller.py
+++ b/tools/harness-automation/autothreadharness/open_thread_controller.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import logging
 import re
 import socket
@@ -107,7 +106,10 @@
             self.handle.setblocking(0)
             self._is_net = True
         else:
-            self.handle = serial.Serial(self.port, 115200, timeout=0, xonxoff=True)
+            self.handle = serial.Serial(self.port,
+                                        115200,
+                                        timeout=0,
+                                        xonxoff=True)
             self._is_net = False
 
     def _read(self, size=512):
diff --git a/tools/harness-automation/autothreadharness/pdu_controller.py b/tools/harness-automation/autothreadharness/pdu_controller.py
index 058a11c..d0801b1 100644
--- a/tools/harness-automation/autothreadharness/pdu_controller.py
+++ b/tools/harness-automation/autothreadharness/pdu_controller.py
@@ -42,8 +42,16 @@
 
 logger = logging.getLogger(__name__)
 
+try:
+    from pysnmp.hlapi import SnmpEngine, CommunityData, UdpTransportTarget, ContextData, getCmd, setCmd, ObjectType, ObjectIdentity, Integer32
+except ImportError:
+    logger.warning(
+        'PySNMP module is not installed. Install if EATON_PDU_CONTROLLER is used'
+    )
+
 
 class PduController(object):
+
     def open(self, **params):
         """Open PDU controller connection"""
         raise NotImplementedError
@@ -71,6 +79,7 @@
 
 
 class ApcPduController(PduController):
+
     def __init__(self):
         self.tn = None
 
@@ -89,10 +98,10 @@
 
     def open(self, **params):
         """Open telnet connection
-
+        
         Args:
             params (dict), must contain two parameters "ip" - ip address or hostname and "port" - port number
-
+            
         Example:
             params = {'port': 23, 'ip': 'localhost'}
         """
@@ -122,10 +131,10 @@
 
     def reboot(self, **params):
         """Reboot outlet
-
+        
         Args:
             params (dict), must contain parameter "outlet" - outlet number
-
+            
         Example:
             params = {'outlet': 1}
         """
@@ -168,6 +177,7 @@
 
 
 class NordicBoardPduController(PduController):
+
     def open(self, **params):
         pass
 
@@ -178,18 +188,233 @@
         boards_serial_numbers = params['boards_serial_numbers']
 
         for serial_number in boards_serial_numbers:
-            logger.info('Resetting board with the serial number: %s', serial_number)
+            logger.info('Resetting board with the serial number: %s',
+                        serial_number)
             self._pin_reset(serial_number)
 
     def close(self):
         pass
 
 
+class EatonPduController(PduController):
+
+    outlet_oid_cmd_get_state_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.2.0.'
+    outlet_oid_cmd_set_on_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.4.0.'
+    outlet_oid_cmd_set_off_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.3.0.'
+    outlet_oid_cmd_reboot_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.5.0.'
+    outlet_oid_cmd_set_reboot_delay_seconds_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.8.0.'
+
+    PDU_COMMAND_TIMEOUT = 5
+
+    def open(self, **params):
+        missing_fields = ['ip', 'port']
+        missing_fields = [
+            field for field in missing_fields if field not in params.keys()
+        ]
+        if missing_fields:
+            raise KeyError(
+                'Missing keys in PDU params: {}'.format(missing_fields))
+        self.params = params
+        self.type = 'pdu'
+        self.ip = self.params['ip']
+        self.snmp_agent_port = int(self.params['port'])
+        self._community = 'public'
+        self._snmp_engine = SnmpEngine()
+        self._community_data = CommunityData(self._community, mpModel=0)
+        self._udp_transport_target = UdpTransportTarget(
+            (self.ip, self.snmp_agent_port))
+        self._context = ContextData()
+
+    def _outlet_oid_get(self, param, socket):
+        """
+        Translates command to the OID number representing a command for the specific power socket.
+
+        Args:
+            param (str), command string
+            socket (int), socket index
+
+        Return:
+            full OID identifying the SNMP object (str)
+        """
+        parameters = {
+            'get_state':
+                self.outlet_oid_cmd_get_state_base,
+            'set_on':
+                self.outlet_oid_cmd_set_on_base,
+            'set_off':
+                self.outlet_oid_cmd_set_off_base,
+            'set_reboot_delay':
+                self.outlet_oid_cmd_set_reboot_delay_seconds_base,
+            'reboot':
+                self.outlet_oid_cmd_reboot_base
+        }
+
+        return parameters[param.lower()] + str(socket)
+
+    # Performs set command to specific OID with a given value by sending a SNMP Set message.
+    def _oid_set(self, oid, value):
+        """
+        Performs set command to specific OID with a given value by sending a SNMP Set message.
+
+        Args:
+            oid (str): Full OID identifying the object to be read.
+            value (int): Value to be written to the OID as Integer32.
+        """
+        errorIndication, errorStatus, errorIndex, varBinds = next(
+            setCmd(self._snmp_engine, self._community_data,
+                   self._udp_transport_target, self._context,
+                   ObjectType(ObjectIdentity(oid), Integer32(value))))
+
+        if errorIndication:
+            msg = 'Found PDU errorIndication: {}'.format(errorIndication)
+            logger.exception(msg)
+            raise RuntimeError(msg)
+        elif errorStatus:
+            msg = 'Found PDU errorStatus: {}'.format(errorStatus)
+            logger.exception(msg)
+            raise RuntimeError(msg)
+
+    def _oid_get(self, oid):
+        """
+        Performs SNMP get command and returns OID value by sending a SNMP Get message.
+
+        Args:
+            oid (str): Full OID identifying the object to be read.
+
+        Return:
+            OID value (int)
+        """
+        errorIndication, errorStatus, errorIndex, varBinds = next(
+            getCmd(self._snmp_engine, self._community_data,
+                   self._udp_transport_target, self._context,
+                   ObjectType(ObjectIdentity(oid))))
+
+        if errorIndication:
+            msg = 'Found PDU errorIndication: {}'.format(errorIndication)
+            logger.exception(msg)
+            raise RuntimeError(msg)
+        elif errorStatus:
+            msg = 'Found PDU errorStatus: {}'.format(errorStatus)
+            logger.exception(msg)
+            raise RuntimeError(msg)
+
+        return int(str(varBinds[-1]).partition('= ')[-1])
+
+    def _outlet_value_set(self, cmd, socket, value=1):
+        """
+        Sets outlet parameter value.
+
+        Args:
+            cmd (str): OID base
+            socket (int): socket index (last OID number)
+            value (int): value to be set
+        """
+        oid = self._outlet_oid_get(cmd, socket)
+
+        # Values other than 1 does not make sense with commands other than "set_reboot_delay".
+        if cmd != 'set_reboot_delay':
+            value = 1
+
+        self._oid_set(oid, value)
+
+    def _outlet_value_get(self, cmd, socket):
+        """
+        Read outlet parameter value.
+
+        Args:
+            cmd (str): OID base
+            socket (int): socket index (last OID number)
+
+        Return:
+            parameter value (int)
+        """
+        oid = self._outlet_oid_get(cmd, socket)
+
+        return self._oid_get(oid)
+
+    def validate_state(self, socket, state):
+        return (self._outlet_value_get('get_state', socket) == state)
+
+    def turn_off(self, sockets):
+        """
+        Turns the specified socket off.
+
+        Args:
+            sockets (list(int)): sockets to be turned off
+        """
+        logger.info('Executing turn OFF for: {}'.format(sockets))
+
+        for socket in sockets:
+            self._outlet_value_set('set_off', socket)
+            time.sleep(2)
+
+            timeout = time.time() + self.PDU_COMMAND_TIMEOUT
+            while ((time.time() < timeout) and
+                   not self.validate_state(socket, 0)):
+                time.sleep(0.1)
+
+            if self.validate_state(socket, 0):
+                logger.debug('Turned OFF socket {} at {}'.format(
+                    socket, self.ip))
+            else:
+                logger.error('Failed to turn OFF socket {} at {}'.format(
+                    socket, self.ip))
+
+    def turn_on(self, sockets):
+        """
+        Turns the specified socket on.
+
+        Args:
+            sockets (list(int)): sockets to be turned on
+        """
+
+        logger.info('Executing turn ON for: {}'.format(sockets))
+
+        for socket in sockets:
+            self._outlet_value_set('set_on', socket)
+            time.sleep(2)
+
+            timeout = time.time() + self.PDU_COMMAND_TIMEOUT
+            while ((time.time() < timeout) and
+                   not self.validate_state(socket, 1)):
+                time.sleep(0.1)
+
+            if self.validate_state(socket, 1):
+                logger.debug('Turned ON socket {} at {}'.format(
+                    socket, self.ip))
+            else:
+                logger.error('Failed to turn ON socket {} at {}'.format(
+                    socket, self.ip))
+
+    def close(self):
+        self._community = None
+        self._snmp_engine = None
+        self._community_data = None
+        self._udp_transport_target = None
+        self._context = None
+
+    def reboot(self, **params):
+        """
+        Reboots the sockets specified in the constructor with off and on delays.
+
+        Args:
+            sockets (list(int)): sockets to reboot
+        """
+
+        logger.info('Executing power cycle for: {}'.format(params['sockets']))
+        self.turn_off(params['sockets'])
+        time.sleep(10)
+        self.turn_on(params['sockets'])
+        time.sleep(5)
+
+
 class IpPowerSocketPduController(PduController):
+
     def open(self, **params):
         self._base_url = 'http://{}/outs.cgi?out'.format(params['ip'])
         password_manager = HTTPPasswordMgrWithDefaultRealm()
-        password_manager.add_password(None, self._base_url, params['user'], params['pass'])
+        password_manager.add_password(None, self._base_url, params['user'],
+                                      params['pass'])
         authentication_handler = HTTPBasicAuthHandler(password_manager)
         self._opener = build_opener(authentication_handler)
 
@@ -216,6 +441,7 @@
 
 
 class ManualPduController(PduController):
+
     def open(self, **kwargs):
         pass
 
diff --git a/tools/harness-automation/autothreadharness/pdu_controller_factory.py b/tools/harness-automation/autothreadharness/pdu_controller_factory.py
index 1f0531c..8a43828 100644
--- a/tools/harness-automation/autothreadharness/pdu_controller_factory.py
+++ b/tools/harness-automation/autothreadharness/pdu_controller_factory.py
@@ -40,5 +40,7 @@
             return pdu_controller.IpPowerSocketPduController()
         elif _type == 'MANUAL_PDU_CONTROLLER':
             return pdu_controller.ManualPduController()
+        elif _type == 'EATON_PDU_CONTROLLER':
+            return pdu_controller.EatonPduController()
         else:
             return pdu_controller.DummyPduController()
diff --git a/tools/harness-automation/autothreadharness/rf_shield_controller.py b/tools/harness-automation/autothreadharness/rf_shield_controller.py
index e172654..cf885d1 100644
--- a/tools/harness-automation/autothreadharness/rf_shield_controller.py
+++ b/tools/harness-automation/autothreadharness/rf_shield_controller.py
@@ -33,12 +33,12 @@
 import serial
 import time
 
-
 ABC = abc.ABC if sys.version_info >= (3, 4) else abc.ABCMeta('ABC', (), {})
 logger = logging.getLogger(__name__)
 
 
 class RfShieldController(ABC):
+
     @abc.abstractmethod
     def shield(self):
         pass
@@ -57,6 +57,7 @@
 
 
 class RfSwitchController(RfShieldController):
+
     def __init__(self, channel, port):
         self._channel = channel
         self._port = port
@@ -96,4 +97,5 @@
 def get_rf_shield_controller(shield_type, params):
     if shield_type in CONTROLLERS:
         return CONTROLLERS[shield_type](**params)
-    logger.exception('Unknown RF shield controller type: {}'.format(shield_type))
+    logger.exception(
+        'Unknown RF shield controller type: {}'.format(shield_type))
diff --git a/tools/harness-automation/autothreadharness/runner.py b/tools/harness-automation/autothreadharness/runner.py
index 2b2c60a..c748894 100644
--- a/tools/harness-automation/autothreadharness/runner.py
+++ b/tools/harness-automation/autothreadharness/runner.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import ConfigParser
 import argparse
 import fnmatch
@@ -57,7 +56,11 @@
 
     executions = 0
 
-    def __init__(self, path, auto_reboot_args=None, keep_explorer=False, add_all_devices=False):
+    def __init__(self,
+                 path,
+                 auto_reboot_args=None,
+                 keep_explorer=False,
+                 add_all_devices=False):
         """Record test results in json file
 
         Args:
@@ -86,17 +89,20 @@
         if self.auto_reboot_args:
             test.auto_reboot = True
             os.system(
-                'echo %s > "%s"'
-                % (' '.join(self.auto_reboot_args + ['-c', test.__class__.__name__]), RESUME_SCRIPT_PATH)
-            )
+                'echo %s > "%s"' %
+                (' '.join(self.auto_reboot_args +
+                          ['-c', test.__class__.__name__]), RESUME_SCRIPT_PATH))
 
         # record start timestamp
         self.started = time.strftime('%Y-%m-%dT%H:%M:%S')
 
         os.system('mkdir %s' % test.result_dir)
-        self.log_handler = logging.FileHandler('%s\\auto-%s.log' % (test.result_dir, time.strftime('%Y%m%d%H%M%S')))
+        self.log_handler = logging.FileHandler(
+            '%s\\auto-%s.log' %
+            (test.result_dir, time.strftime('%Y%m%d%H%M%S')))
         self.log_handler.setLevel(logging.DEBUG)
-        self.log_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
+        self.log_handler.setFormatter(
+            logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
         logger.addHandler(self.log_handler)
 
     def add_result(self, test, passed, error=None):
@@ -120,7 +126,9 @@
         if self.auto_reboot_args:
             os.system('del "%s"' % RESUME_SCRIPT_PATH)
 
-        json.dump(OrderedDict(sorted(self.result.items(), key=lambda t: t[0])), open(self.path, 'w'), indent=2)
+        json.dump(OrderedDict(sorted(self.result.items(), key=lambda t: t[0])),
+                  open(self.path, 'w'),
+                  indent=2)
 
         # save logs
         logger.removeHandler(self.log_handler)
@@ -161,7 +169,10 @@
     """List devices in settings file and print versions"""
 
     if not names:
-        names = [device for device, _type in settings.GOLDEN_DEVICES if _type == 'OpenThread']
+        names = [
+            device for device, _type in settings.GOLDEN_DEVICES
+            if _type == 'OpenThread'
+        ]
 
     if continue_from:
         continue_from = names.index(continue_from)
@@ -207,7 +218,11 @@
 
     if blacklist:
         try:
-            excludes = [line.strip('\n') for line in open(blacklist, 'r').readlines() if not line.startswith('#')]
+            excludes = [
+                line.strip('\n')
+                for line in open(blacklist, 'r').readlines()
+                if not line.startswith('#')
+            ]
         except BaseException:
             logger.exception('Failed to open test case black list file')
             raise
@@ -228,10 +243,11 @@
     new_th = False
     harness_info = ConfigParser.ConfigParser()
     harness_info.read('%s\\info.ini' % settings.HARNESS_HOME)
-    if harness_info.has_option('Thread_Harness_Info', 'Version') and harness_info.has_option(
-        'Thread_Harness_Info', 'Mode'
-    ):
-        harness_version = harness_info.get('Thread_Harness_Info', 'Version').rsplit(' ', 1)[1]
+    if harness_info.has_option('Thread_Harness_Info',
+                               'Version') and harness_info.has_option(
+                                   'Thread_Harness_Info', 'Mode'):
+        harness_version = harness_info.get('Thread_Harness_Info',
+                                           'Version').rsplit(' ', 1)[1]
         harness_mode = harness_info.get('Thread_Harness_Info', 'Mode')
 
         if harness_mode == 'External' and harness_version > '1.4.0':
@@ -247,7 +263,7 @@
         discovered = unittest.defaultTestLoader.discover('cases_R140', pattern)
 
     if names and continue_from:
-        names = names[names.index(continue_from) :]
+        names = names[names.index(continue_from):]
 
     for s1 in discovered:
         for s2 in s1:
@@ -257,7 +273,9 @@
                 case_name = str(case.__class__.__name__)
 
                 # grep name
-                if name_greps and not any(fnmatch.fnmatch(case_name, name_grep) for name_grep in name_greps):
+                if name_greps and not any(
+                        fnmatch.fnmatch(case_name, name_grep)
+                        for name_grep in name_greps):
                     logger.info('case[%s] skipped by name greps', case_name)
                     continue
 
@@ -267,19 +285,19 @@
                     continue
 
                 # skip cases
-                if case_name in log.keys():
-                    if (
-                        (log[case_name]['passed'] and ('p' in skip))
-                        or (log[case_name]['passed'] is False and ('f' in skip))
-                        or (log[case_name]['passed'] is None and ('e' in skip))
-                    ):
-                        logger.warning('case[%s] skipped for its status[%s]', case_name, log[case_name]['passed'])
+                if case_name in log:
+                    if ((log[case_name]['passed'] and ('p' in skip)) or
+                        (log[case_name]['passed'] is False and ('f' in skip)) or
+                        (log[case_name]['passed'] is None and ('e' in skip))):
+                        logger.warning('case[%s] skipped for its status[%s]',
+                                       case_name, log[case_name]['passed'])
                         continue
 
                 # continue from
                 if continue_from:
                     if continue_from != case_name:
-                        logger.warning('case[%s] skipped for continue from[%s]', case_name, continue_from)
+                        logger.warning('case[%s] skipped for continue from[%s]',
+                                       case_name, continue_from)
                         continue
                     else:
                         continue_from = None
@@ -292,8 +310,8 @@
                 # max devices
                 if max_devices and case.golden_devices_required > max_devices:
                     logger.warning(
-                        'case[%s] skipped for exceeding max golden devices allowed[%d]', case_name, max_devices
-                    )
+                        'case[%s] skipped for exceeding max golden devices allowed[%d]',
+                        case_name, max_devices)
                     continue
 
                 suite.addTest(case)
@@ -325,7 +343,8 @@
         settings.PDU_CONTROLLER_OPEN_PARAMS = {}
         settings.PDU_CONTROLLER_REBOOT_PARAMS = {}
 
-    result = SimpleTestResult(result_file, auto_reboot_args, keep_explorer, add_all_devices)
+    result = SimpleTestResult(result_file, auto_reboot_args, keep_explorer,
+                              add_all_devices)
     for case in suite:
         logger.info(case.__class__.__name__)
 
@@ -337,23 +356,50 @@
 
 
 def main():
-    parser = argparse.ArgumentParser(description='Thread harness test case runner')
-    parser.add_argument(
-        '--auto-reboot', '-a', action='store_true', default=False, help='restart system when harness service die'
-    )
-    parser.add_argument(
-        'names', metavar='NAME', type=str, nargs='*', default=None, help='test case name, omit to test all'
-    )
-    parser.add_argument(
-        '--blacklist', '-b', metavar='BLACKLIST_FILE', type=str, help='file to list test cases to skip', default=None
-    )
-    parser.add_argument('--continue-from', '-c', type=str, default=None, help='first case to test')
-    parser.add_argument('--delete-history', '-d', action='store_true', default=False, help='clear history on startup')
-    parser.add_argument(
-        '--keep-explorer', '-e', action='store_true', default=False, help='do not restart explorer.exe at the end'
-    )
-    parser.add_argument('--name-greps', '-g', action='append', default=None, help='grep case by names')
-    parser.add_argument('--list-file', '-i', type=str, default=None, help='file to list cases names to test')
+    parser = argparse.ArgumentParser(
+        description='Thread harness test case runner')
+    parser.add_argument('--auto-reboot',
+                        '-a',
+                        action='store_true',
+                        default=False,
+                        help='restart system when harness service die')
+    parser.add_argument('names',
+                        metavar='NAME',
+                        type=str,
+                        nargs='*',
+                        default=None,
+                        help='test case name, omit to test all')
+    parser.add_argument('--blacklist',
+                        '-b',
+                        metavar='BLACKLIST_FILE',
+                        type=str,
+                        help='file to list test cases to skip',
+                        default=None)
+    parser.add_argument('--continue-from',
+                        '-c',
+                        type=str,
+                        default=None,
+                        help='first case to test')
+    parser.add_argument('--delete-history',
+                        '-d',
+                        action='store_true',
+                        default=False,
+                        help='clear history on startup')
+    parser.add_argument('--keep-explorer',
+                        '-e',
+                        action='store_true',
+                        default=False,
+                        help='do not restart explorer.exe at the end')
+    parser.add_argument('--name-greps',
+                        '-g',
+                        action='append',
+                        default=None,
+                        help='grep case by names')
+    parser.add_argument('--list-file',
+                        '-i',
+                        type=str,
+                        default=None,
+                        help='file to list cases names to test')
     parser.add_argument(
         '--skip',
         '-k',
@@ -362,9 +408,21 @@
         help='type of results to skip. e for error, f for fail, p for pass.',
         default='',
     )
-    parser.add_argument('--list-devices', '-l', action='store_true', default=False, help='list devices')
-    parser.add_argument('--manual-reset', '-m', action='store_true', default=False, help='reset devices manually')
-    parser.add_argument('--dry-run', '-n', action='store_true', default=False, help='just show what to run')
+    parser.add_argument('--list-devices',
+                        '-l',
+                        action='store_true',
+                        default=False,
+                        help='list devices')
+    parser.add_argument('--manual-reset',
+                        '-m',
+                        action='store_true',
+                        default=False,
+                        help='reset devices manually')
+    parser.add_argument('--dry-run',
+                        '-n',
+                        action='store_true',
+                        default=False,
+                        help='just show what to run')
     parser.add_argument(
         '--result-file',
         '-o',
@@ -372,20 +430,37 @@
         default=settings.OUTPUT_PATH + '\\result.json',
         help='file to store and read current status',
     )
-    parser.add_argument(
-        '--pattern', '-p', metavar='PATTERN', type=str, help='file name pattern, default to "*.py"', default='*.py'
-    )
-    parser.add_argument('--rerun-fails', '-r', type=int, default=0, help='number of times to rerun failed test cases')
-    parser.add_argument(
-        '--add-all-devices', '-t', action='store_true', default=False, help='add all devices to the test bed'
-    )
-    parser.add_argument('--max-devices', '-u', type=int, default=0, help='max golden devices allowed')
+    parser.add_argument('--pattern',
+                        '-p',
+                        metavar='PATTERN',
+                        type=str,
+                        help='file name pattern, default to "*.py"',
+                        default='*.py')
+    parser.add_argument('--rerun-fails',
+                        '-r',
+                        type=int,
+                        default=0,
+                        help='number of times to rerun failed test cases')
+    parser.add_argument('--add-all-devices',
+                        '-t',
+                        action='store_true',
+                        default=False,
+                        help='add all devices to the test bed')
+    parser.add_argument('--max-devices',
+                        '-u',
+                        type=int,
+                        default=0,
+                        help='max golden devices allowed')
 
     args = vars(parser.parse_args())
 
     if args['list_file']:
         try:
-            names = [line.strip('\n') for line in open(args['list_file'], 'r').readlines() if not line.startswith('#')]
+            names = [
+                line.strip('\n')
+                for line in open(args['list_file'], 'r').readlines()
+                if not line.startswith('#')
+            ]
         except BaseException:
             logger.exception('Failed to open test case list file')
             raise
@@ -403,7 +478,10 @@
 
     if rerun_fails > 0:
         for i in range(rerun_fails):
-            failed_names = {name for name in result.result if result.result[name]['passed'] is False}
+            failed_names = {
+                name for name in result.result
+                if result.result[name]['passed'] is False
+            }
             if not failed_names:
                 break
             logger.info('Rerunning failed test cases')
diff --git a/tools/harness-automation/autothreadharness/settings_sample.py b/tools/harness-automation/autothreadharness/settings_sample.py
index 6ac25ce..fad1e43 100644
--- a/tools/harness-automation/autothreadharness/settings_sample.py
+++ b/tools/harness-automation/autothreadharness/settings_sample.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 AUTO_DUT = True
 """bool: Whether use the auto DUT feature of thread harness."""
 
@@ -123,6 +122,7 @@
     - 'APC_PDU_CONTROLLER' - when APC PDU controller connected
     - 'NORDIC_BOARD_PDU_CONTOLLER' - when Nordic boards PDU controller connected
     - 'IP_POWER_SOCKET_PDU_CONTROLLER' - when IP Power Socket 5G10A connected
+    - 'EATON_PDU_CONTROLLER' - when EATON PDU controller connected
 """
 
 PDU_CONTROLLER_OPEN_PARAMS = {'port': 23, 'ip': '127.0.0.1'}
@@ -149,6 +149,8 @@
 
 Example parameters for the 'IP_POWER_SOCKET_PDU_CONTROLLER':
     {'sockets': [0, 1]}
+Example parameters for the 'EATON_PDU_CONTROLLER':
+    {'ip': '127.0.0.1'}
 """
 
 SHIELD_CONTROLLER_TYPE = None
diff --git a/tools/harness-automation/cases/border_7_1_1.py b/tools/harness-automation/cases/border_7_1_1.py
index 8b221a1..e28f50c 100644
--- a/tools/harness-automation/cases/border_7_1_1.py
+++ b/tools/harness-automation/cases/border_7_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/border_7_1_2.py b/tools/harness-automation/cases/border_7_1_2.py
index d1d056a..b72979d 100644
--- a/tools/harness-automation/cases/border_7_1_2.py
+++ b/tools/harness-automation/cases/border_7_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/border_7_1_3.py b/tools/harness-automation/cases/border_7_1_3.py
index 9de68b5..40e9fe7 100644
--- a/tools/harness-automation/cases/border_7_1_3.py
+++ b/tools/harness-automation/cases/border_7_1_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/border_7_1_4.py b/tools/harness-automation/cases/border_7_1_4.py
index 00ecfcb..62755f1 100644
--- a/tools/harness-automation/cases/border_7_1_4.py
+++ b/tools/harness-automation/cases/border_7_1_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/border_7_1_5.py b/tools/harness-automation/cases/border_7_1_5.py
index f77fdb8..c675995 100644
--- a/tools/harness-automation/cases/border_7_1_5.py
+++ b/tools/harness-automation/cases/border_7_1_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/border_7_1_6.py b/tools/harness-automation/cases/border_7_1_6.py
index 81b60a6..53ae7f4 100644
--- a/tools/harness-automation/cases/border_7_1_6.py
+++ b/tools/harness-automation/cases/border_7_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/border_7_1_7.py b/tools/harness-automation/cases/border_7_1_7.py
index a37674b..6993eb2 100644
--- a/tools/harness-automation/cases/border_7_1_7.py
+++ b/tools/harness-automation/cases/border_7_1_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/border_7_1_8.py b/tools/harness-automation/cases/border_7_1_8.py
index c56fe81..7841804 100644
--- a/tools/harness-automation/cases/border_7_1_8.py
+++ b/tools/harness-automation/cases/border_7_1_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_8_1_1.py b/tools/harness-automation/cases/commissioner_8_1_1.py
index 32b09f7..db4cb8b 100644
--- a/tools/harness-automation/cases/commissioner_8_1_1.py
+++ b/tools/harness-automation/cases/commissioner_8_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_8_1_2.py b/tools/harness-automation/cases/commissioner_8_1_2.py
index f31177c..2022a8f 100644
--- a/tools/harness-automation/cases/commissioner_8_1_2.py
+++ b/tools/harness-automation/cases/commissioner_8_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_8_1_6.py b/tools/harness-automation/cases/commissioner_8_1_6.py
index ab4d094..141fa60 100644
--- a/tools/harness-automation/cases/commissioner_8_1_6.py
+++ b/tools/harness-automation/cases/commissioner_8_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_8_2_1.py b/tools/harness-automation/cases/commissioner_8_2_1.py
index 990f08a..1851118 100644
--- a/tools/harness-automation/cases/commissioner_8_2_1.py
+++ b/tools/harness-automation/cases/commissioner_8_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_8_2_2.py b/tools/harness-automation/cases/commissioner_8_2_2.py
index 5ada36a..e365967 100644
--- a/tools/harness-automation/cases/commissioner_8_2_2.py
+++ b/tools/harness-automation/cases/commissioner_8_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_8_2_5.py b/tools/harness-automation/cases/commissioner_8_2_5.py
index a284b39..ceebaec 100644
--- a/tools/harness-automation/cases/commissioner_8_2_5.py
+++ b/tools/harness-automation/cases/commissioner_8_2_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_8_3_1.py b/tools/harness-automation/cases/commissioner_8_3_1.py
index 26eef23..0376820 100644
--- a/tools/harness-automation/cases/commissioner_8_3_1.py
+++ b/tools/harness-automation/cases/commissioner_8_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_9_2_1.py b/tools/harness-automation/cases/commissioner_9_2_1.py
index a264e55..471ba97 100644
--- a/tools/harness-automation/cases/commissioner_9_2_1.py
+++ b/tools/harness-automation/cases/commissioner_9_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_9_2_14.py b/tools/harness-automation/cases/commissioner_9_2_14.py
index d090d47..2f87c6b 100644
--- a/tools/harness-automation/cases/commissioner_9_2_14.py
+++ b/tools/harness-automation/cases/commissioner_9_2_14.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_9_2_19.py b/tools/harness-automation/cases/commissioner_9_2_19.py
index 78265a7..13db307 100755
--- a/tools/harness-automation/cases/commissioner_9_2_19.py
+++ b/tools/harness-automation/cases/commissioner_9_2_19.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_9_2_2.py b/tools/harness-automation/cases/commissioner_9_2_2.py
index 7ea4ab5..94ed5fa 100644
--- a/tools/harness-automation/cases/commissioner_9_2_2.py
+++ b/tools/harness-automation/cases/commissioner_9_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_9_2_3.py b/tools/harness-automation/cases/commissioner_9_2_3.py
index e13cae2..61aa37b 100644
--- a/tools/harness-automation/cases/commissioner_9_2_3.py
+++ b/tools/harness-automation/cases/commissioner_9_2_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/commissioner_9_2_4.py b/tools/harness-automation/cases/commissioner_9_2_4.py
index 9d46c6e..c0c8b61 100644
--- a/tools/harness-automation/cases/commissioner_9_2_4.py
+++ b/tools/harness-automation/cases/commissioner_9_2_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_1_1.py b/tools/harness-automation/cases/ed_6_1_1.py
index 52d2e4b..79deead 100644
--- a/tools/harness-automation/cases/ed_6_1_1.py
+++ b/tools/harness-automation/cases/ed_6_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_1_2.py b/tools/harness-automation/cases/ed_6_1_2.py
index a5eb4b0..1336c49 100644
--- a/tools/harness-automation/cases/ed_6_1_2.py
+++ b/tools/harness-automation/cases/ed_6_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_1_3.py b/tools/harness-automation/cases/ed_6_1_3.py
index c6a65ec..e99f86d 100644
--- a/tools/harness-automation/cases/ed_6_1_3.py
+++ b/tools/harness-automation/cases/ed_6_1_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_1_4.py b/tools/harness-automation/cases/ed_6_1_4.py
index 99894dc..dfcd85d 100644
--- a/tools/harness-automation/cases/ed_6_1_4.py
+++ b/tools/harness-automation/cases/ed_6_1_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_1_5.py b/tools/harness-automation/cases/ed_6_1_5.py
index 9e09ab8..70b9007 100644
--- a/tools/harness-automation/cases/ed_6_1_5.py
+++ b/tools/harness-automation/cases/ed_6_1_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_1_6.py b/tools/harness-automation/cases/ed_6_1_6.py
index 399799b..7d9d9e3 100644
--- a/tools/harness-automation/cases/ed_6_1_6.py
+++ b/tools/harness-automation/cases/ed_6_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_3_1.py b/tools/harness-automation/cases/ed_6_3_1.py
index e19a0a5..f8c6cf4 100644
--- a/tools/harness-automation/cases/ed_6_3_1.py
+++ b/tools/harness-automation/cases/ed_6_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_4_1.py b/tools/harness-automation/cases/ed_6_4_1.py
index 261bfa6..924ea4e 100644
--- a/tools/harness-automation/cases/ed_6_4_1.py
+++ b/tools/harness-automation/cases/ed_6_4_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_4_2.py b/tools/harness-automation/cases/ed_6_4_2.py
index cb5337d..23bb14a 100644
--- a/tools/harness-automation/cases/ed_6_4_2.py
+++ b/tools/harness-automation/cases/ed_6_4_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_5_1.py b/tools/harness-automation/cases/ed_6_5_1.py
index fae820c..7074de4 100644
--- a/tools/harness-automation/cases/ed_6_5_1.py
+++ b/tools/harness-automation/cases/ed_6_5_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 import time
 
diff --git a/tools/harness-automation/cases/ed_6_5_2.py b/tools/harness-automation/cases/ed_6_5_2.py
index 0825880..501d343 100644
--- a/tools/harness-automation/cases/ed_6_5_2.py
+++ b/tools/harness-automation/cases/ed_6_5_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_5_3.py b/tools/harness-automation/cases/ed_6_5_3.py
index 2a9b20e..5d1e35d 100644
--- a/tools/harness-automation/cases/ed_6_5_3.py
+++ b/tools/harness-automation/cases/ed_6_5_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_6_1.py b/tools/harness-automation/cases/ed_6_6_1.py
index 117c881..e6baa88 100644
--- a/tools/harness-automation/cases/ed_6_6_1.py
+++ b/tools/harness-automation/cases/ed_6_6_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_6_6_2.py b/tools/harness-automation/cases/ed_6_6_2.py
index 8bc84b4..4d53ab0 100644
--- a/tools/harness-automation/cases/ed_6_6_2.py
+++ b/tools/harness-automation/cases/ed_6_6_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_9_2_17.py b/tools/harness-automation/cases/ed_9_2_17.py
index e245fea..98f4ef0 100644
--- a/tools/harness-automation/cases/ed_9_2_17.py
+++ b/tools/harness-automation/cases/ed_9_2_17.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/ed_9_2_8.py b/tools/harness-automation/cases/ed_9_2_8.py
index 4e254b1..94f5544 100644
--- a/tools/harness-automation/cases/ed_9_2_8.py
+++ b/tools/harness-automation/cases/ed_9_2_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/fed_5_7_1.py b/tools/harness-automation/cases/fed_5_7_1.py
index feb29e6..780fd5a 100755
--- a/tools/harness-automation/cases/fed_5_7_1.py
+++ b/tools/harness-automation/cases/fed_5_7_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/fed_5_7_3.py b/tools/harness-automation/cases/fed_5_7_3.py
index c34f1c3..4e341e5 100755
--- a/tools/harness-automation/cases/fed_5_7_3.py
+++ b/tools/harness-automation/cases/fed_5_7_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/fed_6_1_7.py b/tools/harness-automation/cases/fed_6_1_7.py
index 7fba55f..6822e0d 100644
--- a/tools/harness-automation/cases/fed_6_1_7.py
+++ b/tools/harness-automation/cases/fed_6_1_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/fed_9_2_13.py b/tools/harness-automation/cases/fed_9_2_13.py
index 7b84b45..5217a20 100644
--- a/tools/harness-automation/cases/fed_9_2_13.py
+++ b/tools/harness-automation/cases/fed_9_2_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/joiner_8_1_1.py b/tools/harness-automation/cases/joiner_8_1_1.py
index d71a7b7..d022e72 100644
--- a/tools/harness-automation/cases/joiner_8_1_1.py
+++ b/tools/harness-automation/cases/joiner_8_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/joiner_8_1_6.py b/tools/harness-automation/cases/joiner_8_1_6.py
index 8444997..3622f55 100644
--- a/tools/harness-automation/cases/joiner_8_1_6.py
+++ b/tools/harness-automation/cases/joiner_8_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_1_1.py b/tools/harness-automation/cases/leader_5_1_1.py
index 465d2bf..149b7f4 100644
--- a/tools/harness-automation/cases/leader_5_1_1.py
+++ b/tools/harness-automation/cases/leader_5_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_1_13.py b/tools/harness-automation/cases/leader_5_1_13.py
index 0017368..a99e489 100644
--- a/tools/harness-automation/cases/leader_5_1_13.py
+++ b/tools/harness-automation/cases/leader_5_1_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import time
 import unittest
diff --git a/tools/harness-automation/cases/leader_5_1_5.py b/tools/harness-automation/cases/leader_5_1_5.py
index 386496c..3e3d706 100644
--- a/tools/harness-automation/cases/leader_5_1_5.py
+++ b/tools/harness-automation/cases/leader_5_1_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/leader_5_2_3.py b/tools/harness-automation/cases/leader_5_2_3.py
index 15bd2af..4ee3d7f 100644
--- a/tools/harness-automation/cases/leader_5_2_3.py
+++ b/tools/harness-automation/cases/leader_5_2_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_3_6.py b/tools/harness-automation/cases/leader_5_3_6.py
index 89cd19c..f96c723 100644
--- a/tools/harness-automation/cases/leader_5_3_6.py
+++ b/tools/harness-automation/cases/leader_5_3_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/leader_5_3_7.py b/tools/harness-automation/cases/leader_5_3_7.py
index 68df333..d9a0245 100644
--- a/tools/harness-automation/cases/leader_5_3_7.py
+++ b/tools/harness-automation/cases/leader_5_3_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_3_8.py b/tools/harness-automation/cases/leader_5_3_8.py
index 1e64255..3d505a0 100644
--- a/tools/harness-automation/cases/leader_5_3_8.py
+++ b/tools/harness-automation/cases/leader_5_3_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_5_1.py b/tools/harness-automation/cases/leader_5_5_1.py
index 9bbc273..ecff0d6 100644
--- a/tools/harness-automation/cases/leader_5_5_1.py
+++ b/tools/harness-automation/cases/leader_5_5_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import re
 import time
 import unittest
diff --git a/tools/harness-automation/cases/leader_5_5_2.py b/tools/harness-automation/cases/leader_5_5_2.py
index 4f97bef..7ab9539 100644
--- a/tools/harness-automation/cases/leader_5_5_2.py
+++ b/tools/harness-automation/cases/leader_5_5_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import time
 import unittest
 
diff --git a/tools/harness-automation/cases/leader_5_5_3.py b/tools/harness-automation/cases/leader_5_5_3.py
index 07eb2fe..5997c82 100644
--- a/tools/harness-automation/cases/leader_5_5_3.py
+++ b/tools/harness-automation/cases/leader_5_5_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_5_4.py b/tools/harness-automation/cases/leader_5_5_4.py
index 0547e7a..dcabecd 100644
--- a/tools/harness-automation/cases/leader_5_5_4.py
+++ b/tools/harness-automation/cases/leader_5_5_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_5_7.py b/tools/harness-automation/cases/leader_5_5_7.py
index b9a5802..f4a8f19 100644
--- a/tools/harness-automation/cases/leader_5_5_7.py
+++ b/tools/harness-automation/cases/leader_5_5_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 
 import unittest
diff --git a/tools/harness-automation/cases/leader_5_6_2.py b/tools/harness-automation/cases/leader_5_6_2.py
index 06080a7..2163cb2 100644
--- a/tools/harness-automation/cases/leader_5_6_2.py
+++ b/tools/harness-automation/cases/leader_5_6_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/leader_5_6_4.py b/tools/harness-automation/cases/leader_5_6_4.py
index a588660..8d3584f 100644
--- a/tools/harness-automation/cases/leader_5_6_4.py
+++ b/tools/harness-automation/cases/leader_5_6_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_6_5.py b/tools/harness-automation/cases/leader_5_6_5.py
index aa18f53..6da7d23 100644
--- a/tools/harness-automation/cases/leader_5_6_5.py
+++ b/tools/harness-automation/cases/leader_5_6_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_6_6.py b/tools/harness-automation/cases/leader_5_6_6.py
index 51d80b1..80d83d9 100644
--- a/tools/harness-automation/cases/leader_5_6_6.py
+++ b/tools/harness-automation/cases/leader_5_6_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_5_8_4.py b/tools/harness-automation/cases/leader_5_8_4.py
index 12c984c..04aec35 100644
--- a/tools/harness-automation/cases/leader_5_8_4.py
+++ b/tools/harness-automation/cases/leader_5_8_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_8_3_1.py b/tools/harness-automation/cases/leader_8_3_1.py
index 8e3edf1..0f2d8ef 100644
--- a/tools/harness-automation/cases/leader_8_3_1.py
+++ b/tools/harness-automation/cases/leader_8_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_1.py b/tools/harness-automation/cases/leader_9_2_1.py
index 923782d..f1d6d5b 100644
--- a/tools/harness-automation/cases/leader_9_2_1.py
+++ b/tools/harness-automation/cases/leader_9_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_11.py b/tools/harness-automation/cases/leader_9_2_11.py
index 0174d82..26203b0 100644
--- a/tools/harness-automation/cases/leader_9_2_11.py
+++ b/tools/harness-automation/cases/leader_9_2_11.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_12.py b/tools/harness-automation/cases/leader_9_2_12.py
index b35f110..42b8f03 100644
--- a/tools/harness-automation/cases/leader_9_2_12.py
+++ b/tools/harness-automation/cases/leader_9_2_12.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_18.py b/tools/harness-automation/cases/leader_9_2_18.py
index 2a549df..4b231dc 100644
--- a/tools/harness-automation/cases/leader_9_2_18.py
+++ b/tools/harness-automation/cases/leader_9_2_18.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_19.py b/tools/harness-automation/cases/leader_9_2_19.py
index ae60535..7065382 100755
--- a/tools/harness-automation/cases/leader_9_2_19.py
+++ b/tools/harness-automation/cases/leader_9_2_19.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_2.py b/tools/harness-automation/cases/leader_9_2_2.py
index 449a63f..4ae535f 100644
--- a/tools/harness-automation/cases/leader_9_2_2.py
+++ b/tools/harness-automation/cases/leader_9_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_3.py b/tools/harness-automation/cases/leader_9_2_3.py
index 4d17627..ec5714c 100644
--- a/tools/harness-automation/cases/leader_9_2_3.py
+++ b/tools/harness-automation/cases/leader_9_2_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_4.py b/tools/harness-automation/cases/leader_9_2_4.py
index e18cb36..35dc7d5 100644
--- a/tools/harness-automation/cases/leader_9_2_4.py
+++ b/tools/harness-automation/cases/leader_9_2_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_5.py b/tools/harness-automation/cases/leader_9_2_5.py
index e4626ce..453cd15 100644
--- a/tools/harness-automation/cases/leader_9_2_5.py
+++ b/tools/harness-automation/cases/leader_9_2_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_6.py b/tools/harness-automation/cases/leader_9_2_6.py
index aecca92..a6f5191 100644
--- a/tools/harness-automation/cases/leader_9_2_6.py
+++ b/tools/harness-automation/cases/leader_9_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_7.py b/tools/harness-automation/cases/leader_9_2_7.py
index a6f2dee..7b07fdd 100644
--- a/tools/harness-automation/cases/leader_9_2_7.py
+++ b/tools/harness-automation/cases/leader_9_2_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/leader_9_2_9.py b/tools/harness-automation/cases/leader_9_2_9.py
index 2fa91a2..d0a4b4f 100644
--- a/tools/harness-automation/cases/leader_9_2_9.py
+++ b/tools/harness-automation/cases/leader_9_2_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 9'
     golden_devices_required = 3
     case_need_shield = True
-    device_order = [('Router_2', False), ('Commissioner', True), ('Router_1', False), ('DUT', True)]
+    device_order = [('Router_2', False), ('Commissioner', True),
+                    ('Router_1', False), ('DUT', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases/med_6_2_1.py b/tools/harness-automation/cases/med_6_2_1.py
index 6599b77..2011d60 100644
--- a/tools/harness-automation/cases/med_6_2_1.py
+++ b/tools/harness-automation/cases/med_6_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/med_6_2_2.py b/tools/harness-automation/cases/med_6_2_2.py
index 973a8c4..dbd6de0 100644
--- a/tools/harness-automation/cases/med_6_2_2.py
+++ b/tools/harness-automation/cases/med_6_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/med_6_3_2.py b/tools/harness-automation/cases/med_6_3_2.py
index 676a676..8586fd5 100644
--- a/tools/harness-automation/cases/med_6_3_2.py
+++ b/tools/harness-automation/cases/med_6_3_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/med_9_2_10.py b/tools/harness-automation/cases/med_9_2_10.py
index 9153669..ef3b473 100644
--- a/tools/harness-automation/cases/med_9_2_10.py
+++ b/tools/harness-automation/cases/med_9_2_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 10'
     golden_devices_required = 4
     case_need_shield = True
-    device_order = [('SED_1', False), ('DUT', False), ('Router_1', False), ('Commissioner', True), ('Leader', True)]
+    device_order = [('SED_1', False), ('DUT', False), ('Router_1', False),
+                    ('Commissioner', True), ('Leader', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases/med_9_2_12.py b/tools/harness-automation/cases/med_9_2_12.py
index 7c93f3c..8882406 100644
--- a/tools/harness-automation/cases/med_9_2_12.py
+++ b/tools/harness-automation/cases/med_9_2_12.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/med_9_2_13.py b/tools/harness-automation/cases/med_9_2_13.py
index f45bf21..0f69823 100644
--- a/tools/harness-automation/cases/med_9_2_13.py
+++ b/tools/harness-automation/cases/med_9_2_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/med_9_2_18.py b/tools/harness-automation/cases/med_9_2_18.py
index 3c17bb8..bc7bdaf 100644
--- a/tools/harness-automation/cases/med_9_2_18.py
+++ b/tools/harness-automation/cases/med_9_2_18.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/med_9_2_6.py b/tools/harness-automation/cases/med_9_2_6.py
index 5b8411c..40096d7 100644
--- a/tools/harness-automation/cases/med_9_2_6.py
+++ b/tools/harness-automation/cases/med_9_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/reed_5_2_4.py b/tools/harness-automation/cases/reed_5_2_4.py
index 8deba1c..b73f018 100644
--- a/tools/harness-automation/cases/reed_5_2_4.py
+++ b/tools/harness-automation/cases/reed_5_2_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/reed_5_2_5.py b/tools/harness-automation/cases/reed_5_2_5.py
index f9e3a8e..43fa627 100644
--- a/tools/harness-automation/cases/reed_5_2_5.py
+++ b/tools/harness-automation/cases/reed_5_2_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/reed_5_2_7.py b/tools/harness-automation/cases/reed_5_2_7.py
index d77e80f..54a3b18 100644
--- a/tools/harness-automation/cases/reed_5_2_7.py
+++ b/tools/harness-automation/cases/reed_5_2_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/reed_5_5_5.py b/tools/harness-automation/cases/reed_5_5_5.py
index c2d71b9..82cb40c 100644
--- a/tools/harness-automation/cases/reed_5_5_5.py
+++ b/tools/harness-automation/cases/reed_5_5_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/reed_5_6_7.py b/tools/harness-automation/cases/reed_5_6_7.py
index 270fc1d..ece67ba 100644
--- a/tools/harness-automation/cases/reed_5_6_7.py
+++ b/tools/harness-automation/cases/reed_5_6_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/reed_5_7_2.py b/tools/harness-automation/cases/reed_5_7_2.py
index 6b35781..99f3c18 100755
--- a/tools/harness-automation/cases/reed_5_7_2.py
+++ b/tools/harness-automation/cases/reed_5_7_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_1.py b/tools/harness-automation/cases/router_5_1_1.py
index 637a15c..31962d4 100644
--- a/tools/harness-automation/cases/router_5_1_1.py
+++ b/tools/harness-automation/cases/router_5_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_10.py b/tools/harness-automation/cases/router_5_1_10.py
index 8ac8817..58fbd53 100644
--- a/tools/harness-automation/cases/router_5_1_10.py
+++ b/tools/harness-automation/cases/router_5_1_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_11.py b/tools/harness-automation/cases/router_5_1_11.py
index a818612..1c01dbe 100644
--- a/tools/harness-automation/cases/router_5_1_11.py
+++ b/tools/harness-automation/cases/router_5_1_11.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_12.py b/tools/harness-automation/cases/router_5_1_12.py
index d69b9e8..a2cd21e 100644
--- a/tools/harness-automation/cases/router_5_1_12.py
+++ b/tools/harness-automation/cases/router_5_1_12.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_13.py b/tools/harness-automation/cases/router_5_1_13.py
index 80e7413..94398af 100644
--- a/tools/harness-automation/cases/router_5_1_13.py
+++ b/tools/harness-automation/cases/router_5_1_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_2.py b/tools/harness-automation/cases/router_5_1_2.py
index c430aca..2cd73fb 100644
--- a/tools/harness-automation/cases/router_5_1_2.py
+++ b/tools/harness-automation/cases/router_5_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_3.py b/tools/harness-automation/cases/router_5_1_3.py
index b60d16f..a928717 100644
--- a/tools/harness-automation/cases/router_5_1_3.py
+++ b/tools/harness-automation/cases/router_5_1_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_4.py b/tools/harness-automation/cases/router_5_1_4.py
index 477336f..1f7839a 100644
--- a/tools/harness-automation/cases/router_5_1_4.py
+++ b/tools/harness-automation/cases/router_5_1_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_6.py b/tools/harness-automation/cases/router_5_1_6.py
index f641609..8d97cbd 100644
--- a/tools/harness-automation/cases/router_5_1_6.py
+++ b/tools/harness-automation/cases/router_5_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_7.py b/tools/harness-automation/cases/router_5_1_7.py
index dfecd89..2c4bd2a 100644
--- a/tools/harness-automation/cases/router_5_1_7.py
+++ b/tools/harness-automation/cases/router_5_1_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_8.py b/tools/harness-automation/cases/router_5_1_8.py
index adfcf26..a97b967 100644
--- a/tools/harness-automation/cases/router_5_1_8.py
+++ b/tools/harness-automation/cases/router_5_1_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_1_9.py b/tools/harness-automation/cases/router_5_1_9.py
index 85f3083..8a9d552 100644
--- a/tools/harness-automation/cases/router_5_1_9.py
+++ b/tools/harness-automation/cases/router_5_1_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_2_1.py b/tools/harness-automation/cases/router_5_2_1.py
index 9ac6fb2..d213607 100644
--- a/tools/harness-automation/cases/router_5_2_1.py
+++ b/tools/harness-automation/cases/router_5_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_2_6.py b/tools/harness-automation/cases/router_5_2_6.py
index d572e00..cf7c274 100644
--- a/tools/harness-automation/cases/router_5_2_6.py
+++ b/tools/harness-automation/cases/router_5_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_2_7.py b/tools/harness-automation/cases/router_5_2_7.py
index 90b5ba0..ecb1e99 100644
--- a/tools/harness-automation/cases/router_5_2_7.py
+++ b/tools/harness-automation/cases/router_5_2_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_3_1.py b/tools/harness-automation/cases/router_5_3_1.py
index 7bedcf6..f2a517b 100644
--- a/tools/harness-automation/cases/router_5_3_1.py
+++ b/tools/harness-automation/cases/router_5_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_3_10.py b/tools/harness-automation/cases/router_5_3_10.py
index b55513a..0af1b09 100644
--- a/tools/harness-automation/cases/router_5_3_10.py
+++ b/tools/harness-automation/cases/router_5_3_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_3_11.py b/tools/harness-automation/cases/router_5_3_11.py
index 74c25b1..89bf237 100644
--- a/tools/harness-automation/cases/router_5_3_11.py
+++ b/tools/harness-automation/cases/router_5_3_11.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_3_2.py b/tools/harness-automation/cases/router_5_3_2.py
index e915136..546f860 100644
--- a/tools/harness-automation/cases/router_5_3_2.py
+++ b/tools/harness-automation/cases/router_5_3_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_3_3.py b/tools/harness-automation/cases/router_5_3_3.py
index 9b1d50d..9c736f4 100644
--- a/tools/harness-automation/cases/router_5_3_3.py
+++ b/tools/harness-automation/cases/router_5_3_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_3_4.py b/tools/harness-automation/cases/router_5_3_4.py
index 19170b8..50efcbf 100644
--- a/tools/harness-automation/cases/router_5_3_4.py
+++ b/tools/harness-automation/cases/router_5_3_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_3_5.py b/tools/harness-automation/cases/router_5_3_5.py
index d527431..0c6644e 100644
--- a/tools/harness-automation/cases/router_5_3_5.py
+++ b/tools/harness-automation/cases/router_5_3_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_3_9.py b/tools/harness-automation/cases/router_5_3_9.py
index c6388c4..f9e196c 100644
--- a/tools/harness-automation/cases/router_5_3_9.py
+++ b/tools/harness-automation/cases/router_5_3_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_5_1.py b/tools/harness-automation/cases/router_5_5_1.py
index 1019970..45c42bf 100644
--- a/tools/harness-automation/cases/router_5_5_1.py
+++ b/tools/harness-automation/cases/router_5_5_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_5_2.py b/tools/harness-automation/cases/router_5_5_2.py
index a1e7364..b3a8a7c 100644
--- a/tools/harness-automation/cases/router_5_5_2.py
+++ b/tools/harness-automation/cases/router_5_5_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_5_3.py b/tools/harness-automation/cases/router_5_5_3.py
index e2bfcd6..a94c84c 100644
--- a/tools/harness-automation/cases/router_5_5_3.py
+++ b/tools/harness-automation/cases/router_5_5_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_5_4.py b/tools/harness-automation/cases/router_5_5_4.py
index d620448..a10de7c 100644
--- a/tools/harness-automation/cases/router_5_5_4.py
+++ b/tools/harness-automation/cases/router_5_5_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_5_7.py b/tools/harness-automation/cases/router_5_5_7.py
index 45c5a73..e6e1e91 100644
--- a/tools/harness-automation/cases/router_5_5_7.py
+++ b/tools/harness-automation/cases/router_5_5_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_6_1.py b/tools/harness-automation/cases/router_5_6_1.py
index 90a260e..2cf5317 100644
--- a/tools/harness-automation/cases/router_5_6_1.py
+++ b/tools/harness-automation/cases/router_5_6_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_6_3.py b/tools/harness-automation/cases/router_5_6_3.py
index 16d75cd..ad81f56 100644
--- a/tools/harness-automation/cases/router_5_6_3.py
+++ b/tools/harness-automation/cases/router_5_6_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_6_9.py b/tools/harness-automation/cases/router_5_6_9.py
index 29effa0..c79d8fa 100644
--- a/tools/harness-automation/cases/router_5_6_9.py
+++ b/tools/harness-automation/cases/router_5_6_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_7_1.py b/tools/harness-automation/cases/router_5_7_1.py
index 760df76..e521896 100644
--- a/tools/harness-automation/cases/router_5_7_1.py
+++ b/tools/harness-automation/cases/router_5_7_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_7_3.py b/tools/harness-automation/cases/router_5_7_3.py
index f3c4752..a2489fc 100755
--- a/tools/harness-automation/cases/router_5_7_3.py
+++ b/tools/harness-automation/cases/router_5_7_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_5_8_2.py b/tools/harness-automation/cases/router_5_8_2.py
index f7ea1e7..60f737e 100644
--- a/tools/harness-automation/cases/router_5_8_2.py
+++ b/tools/harness-automation/cases/router_5_8_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_5_8_3.py b/tools/harness-automation/cases/router_5_8_3.py
index e6ceff5..644059c 100644
--- a/tools/harness-automation/cases/router_5_8_3.py
+++ b/tools/harness-automation/cases/router_5_8_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases/router_8_2_1.py b/tools/harness-automation/cases/router_8_2_1.py
index dd98c87..04d3d82 100644
--- a/tools/harness-automation/cases/router_8_2_1.py
+++ b/tools/harness-automation/cases/router_8_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_8_2_2.py b/tools/harness-automation/cases/router_8_2_2.py
index 3701ec4..938a856 100644
--- a/tools/harness-automation/cases/router_8_2_2.py
+++ b/tools/harness-automation/cases/router_8_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_8_2_5.py b/tools/harness-automation/cases/router_8_2_5.py
index 553fd6d..9ab985a 100644
--- a/tools/harness-automation/cases/router_8_2_5.py
+++ b/tools/harness-automation/cases/router_8_2_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_10.py b/tools/harness-automation/cases/router_9_2_10.py
index c63cc34..ad0aa5e 100644
--- a/tools/harness-automation/cases/router_9_2_10.py
+++ b/tools/harness-automation/cases/router_9_2_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 10'
     golden_devices_required = 4
     case_need_shield = True
-    device_order = [('SED_1', False), ('MED_1', False), ('DUT', False), ('Commissioner', True), ('Leader', True)]
+    device_order = [('SED_1', False), ('MED_1', False), ('DUT', False),
+                    ('Commissioner', True), ('Leader', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases/router_9_2_12.py b/tools/harness-automation/cases/router_9_2_12.py
index 003e348..d4f2300 100644
--- a/tools/harness-automation/cases/router_9_2_12.py
+++ b/tools/harness-automation/cases/router_9_2_12.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_13.py b/tools/harness-automation/cases/router_9_2_13.py
index eea2599..3bab134 100644
--- a/tools/harness-automation/cases/router_9_2_13.py
+++ b/tools/harness-automation/cases/router_9_2_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_14.py b/tools/harness-automation/cases/router_9_2_14.py
index 1ebff32..7e2cc65 100644
--- a/tools/harness-automation/cases/router_9_2_14.py
+++ b/tools/harness-automation/cases/router_9_2_14.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_15.py b/tools/harness-automation/cases/router_9_2_15.py
index 23f58f9..799ef37 100644
--- a/tools/harness-automation/cases/router_9_2_15.py
+++ b/tools/harness-automation/cases/router_9_2_15.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_16.py b/tools/harness-automation/cases/router_9_2_16.py
index 9283de7..7ef4030 100644
--- a/tools/harness-automation/cases/router_9_2_16.py
+++ b/tools/harness-automation/cases/router_9_2_16.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_18.py b/tools/harness-automation/cases/router_9_2_18.py
index edd44c5..e5c4fb0 100644
--- a/tools/harness-automation/cases/router_9_2_18.py
+++ b/tools/harness-automation/cases/router_9_2_18.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_6.py b/tools/harness-automation/cases/router_9_2_6.py
index 7b2deb6..9cba0c7 100644
--- a/tools/harness-automation/cases/router_9_2_6.py
+++ b/tools/harness-automation/cases/router_9_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_8.py b/tools/harness-automation/cases/router_9_2_8.py
index 1f20cc6..9e7f190 100644
--- a/tools/harness-automation/cases/router_9_2_8.py
+++ b/tools/harness-automation/cases/router_9_2_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/router_9_2_9.py b/tools/harness-automation/cases/router_9_2_9.py
index cc53ddc..ea16126 100644
--- a/tools/harness-automation/cases/router_9_2_9.py
+++ b/tools/harness-automation/cases/router_9_2_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 9'
     golden_devices_required = 3
     case_need_shield = True
-    device_order = [('Router_2', False), ('Commissioner', True), ('DUT', False), ('Leader', True)]
+    device_order = [('Router_2', False), ('Commissioner', True), ('DUT', False),
+                    ('Leader', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases/sed_6_1_1.py b/tools/harness-automation/cases/sed_6_1_1.py
index 81221a7..6f27b24 100644
--- a/tools/harness-automation/cases/sed_6_1_1.py
+++ b/tools/harness-automation/cases/sed_6_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_1_2.py b/tools/harness-automation/cases/sed_6_1_2.py
index c3acbc6..92f3355 100644
--- a/tools/harness-automation/cases/sed_6_1_2.py
+++ b/tools/harness-automation/cases/sed_6_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_1_3.py b/tools/harness-automation/cases/sed_6_1_3.py
index 42fab23..bb989a0 100644
--- a/tools/harness-automation/cases/sed_6_1_3.py
+++ b/tools/harness-automation/cases/sed_6_1_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_1_4.py b/tools/harness-automation/cases/sed_6_1_4.py
index c508b82..49eb27d 100644
--- a/tools/harness-automation/cases/sed_6_1_4.py
+++ b/tools/harness-automation/cases/sed_6_1_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_1_5.py b/tools/harness-automation/cases/sed_6_1_5.py
index 49048f4..f7483fb 100644
--- a/tools/harness-automation/cases/sed_6_1_5.py
+++ b/tools/harness-automation/cases/sed_6_1_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_1_6.py b/tools/harness-automation/cases/sed_6_1_6.py
index 5c20abc..6cc8d69 100644
--- a/tools/harness-automation/cases/sed_6_1_6.py
+++ b/tools/harness-automation/cases/sed_6_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_2_1.py b/tools/harness-automation/cases/sed_6_2_1.py
index 8f340d8..2715266 100644
--- a/tools/harness-automation/cases/sed_6_2_1.py
+++ b/tools/harness-automation/cases/sed_6_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_2_2.py b/tools/harness-automation/cases/sed_6_2_2.py
index a8e3176..d0b68e3 100644
--- a/tools/harness-automation/cases/sed_6_2_2.py
+++ b/tools/harness-automation/cases/sed_6_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_3_1.py b/tools/harness-automation/cases/sed_6_3_1.py
index c790349..1ef1c61 100644
--- a/tools/harness-automation/cases/sed_6_3_1.py
+++ b/tools/harness-automation/cases/sed_6_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_3_2.py b/tools/harness-automation/cases/sed_6_3_2.py
index e2ca907..88a24a4 100644
--- a/tools/harness-automation/cases/sed_6_3_2.py
+++ b/tools/harness-automation/cases/sed_6_3_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_4_1.py b/tools/harness-automation/cases/sed_6_4_1.py
index 092ce63..16c0ad4 100644
--- a/tools/harness-automation/cases/sed_6_4_1.py
+++ b/tools/harness-automation/cases/sed_6_4_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_4_2.py b/tools/harness-automation/cases/sed_6_4_2.py
index d798867..1589b95 100644
--- a/tools/harness-automation/cases/sed_6_4_2.py
+++ b/tools/harness-automation/cases/sed_6_4_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_5_1.py b/tools/harness-automation/cases/sed_6_5_1.py
index c9704e2..f50f456 100644
--- a/tools/harness-automation/cases/sed_6_5_1.py
+++ b/tools/harness-automation/cases/sed_6_5_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import time
 import unittest
 
diff --git a/tools/harness-automation/cases/sed_6_5_2.py b/tools/harness-automation/cases/sed_6_5_2.py
index e2f3b41..c4ffff9 100644
--- a/tools/harness-automation/cases/sed_6_5_2.py
+++ b/tools/harness-automation/cases/sed_6_5_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_5_3.py b/tools/harness-automation/cases/sed_6_5_3.py
index f8a0ca3..896301a 100644
--- a/tools/harness-automation/cases/sed_6_5_3.py
+++ b/tools/harness-automation/cases/sed_6_5_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_6_1.py b/tools/harness-automation/cases/sed_6_6_1.py
index f948aa9..241d6a9 100644
--- a/tools/harness-automation/cases/sed_6_6_1.py
+++ b/tools/harness-automation/cases/sed_6_6_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_6_6_2.py b/tools/harness-automation/cases/sed_6_6_2.py
index 99d423c..befce7b 100644
--- a/tools/harness-automation/cases/sed_6_6_2.py
+++ b/tools/harness-automation/cases/sed_6_6_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_9_2_10.py b/tools/harness-automation/cases/sed_9_2_10.py
index 3ca4953..dc363ad 100644
--- a/tools/harness-automation/cases/sed_9_2_10.py
+++ b/tools/harness-automation/cases/sed_9_2_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 10'
     golden_devices_required = 4
     case_need_shield = True
-    device_order = [('DUT', False), ('MED_1', False), ('Router_1', False), ('Commissioner', True), ('Leader', True)]
+    device_order = [('DUT', False), ('MED_1', False), ('Router_1', False),
+                    ('Commissioner', True), ('Leader', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases/sed_9_2_13.py b/tools/harness-automation/cases/sed_9_2_13.py
index f4e877f..428086f 100644
--- a/tools/harness-automation/cases/sed_9_2_13.py
+++ b/tools/harness-automation/cases/sed_9_2_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_9_2_17.py b/tools/harness-automation/cases/sed_9_2_17.py
index 5b718d6..c641ed6 100644
--- a/tools/harness-automation/cases/sed_9_2_17.py
+++ b/tools/harness-automation/cases/sed_9_2_17.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_9_2_18.py b/tools/harness-automation/cases/sed_9_2_18.py
index 800763d..df32b93 100644
--- a/tools/harness-automation/cases/sed_9_2_18.py
+++ b/tools/harness-automation/cases/sed_9_2_18.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_9_2_6.py b/tools/harness-automation/cases/sed_9_2_6.py
index c32a2f2..ebd60a6 100644
--- a/tools/harness-automation/cases/sed_9_2_6.py
+++ b/tools/harness-automation/cases/sed_9_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases/sed_9_2_8.py b/tools/harness-automation/cases/sed_9_2_8.py
index 49cf7cb..1d0efc3 100644
--- a/tools/harness-automation/cases/sed_9_2_8.py
+++ b/tools/harness-automation/cases/sed_9_2_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_8_1_1.py b/tools/harness-automation/cases_R140/commissioner_8_1_1.py
index 32b09f7..db4cb8b 100755
--- a/tools/harness-automation/cases_R140/commissioner_8_1_1.py
+++ b/tools/harness-automation/cases_R140/commissioner_8_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_8_1_2.py b/tools/harness-automation/cases_R140/commissioner_8_1_2.py
index f31177c..2022a8f 100755
--- a/tools/harness-automation/cases_R140/commissioner_8_1_2.py
+++ b/tools/harness-automation/cases_R140/commissioner_8_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_8_1_6.py b/tools/harness-automation/cases_R140/commissioner_8_1_6.py
index ab4d094..141fa60 100755
--- a/tools/harness-automation/cases_R140/commissioner_8_1_6.py
+++ b/tools/harness-automation/cases_R140/commissioner_8_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_8_2_1.py b/tools/harness-automation/cases_R140/commissioner_8_2_1.py
index 990f08a..1851118 100755
--- a/tools/harness-automation/cases_R140/commissioner_8_2_1.py
+++ b/tools/harness-automation/cases_R140/commissioner_8_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_8_2_2.py b/tools/harness-automation/cases_R140/commissioner_8_2_2.py
index 5ada36a..e365967 100755
--- a/tools/harness-automation/cases_R140/commissioner_8_2_2.py
+++ b/tools/harness-automation/cases_R140/commissioner_8_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_8_2_5.py b/tools/harness-automation/cases_R140/commissioner_8_2_5.py
index a284b39..ceebaec 100755
--- a/tools/harness-automation/cases_R140/commissioner_8_2_5.py
+++ b/tools/harness-automation/cases_R140/commissioner_8_2_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_8_3_1.py b/tools/harness-automation/cases_R140/commissioner_8_3_1.py
index 26eef23..0376820 100755
--- a/tools/harness-automation/cases_R140/commissioner_8_3_1.py
+++ b/tools/harness-automation/cases_R140/commissioner_8_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_9_2_1.py b/tools/harness-automation/cases_R140/commissioner_9_2_1.py
index a264e55..471ba97 100755
--- a/tools/harness-automation/cases_R140/commissioner_9_2_1.py
+++ b/tools/harness-automation/cases_R140/commissioner_9_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_9_2_14.py b/tools/harness-automation/cases_R140/commissioner_9_2_14.py
index d090d47..2f87c6b 100755
--- a/tools/harness-automation/cases_R140/commissioner_9_2_14.py
+++ b/tools/harness-automation/cases_R140/commissioner_9_2_14.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_9_2_19.py b/tools/harness-automation/cases_R140/commissioner_9_2_19.py
index 073d37f..c69d915 100755
--- a/tools/harness-automation/cases_R140/commissioner_9_2_19.py
+++ b/tools/harness-automation/cases_R140/commissioner_9_2_19.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_9_2_2.py b/tools/harness-automation/cases_R140/commissioner_9_2_2.py
index 7ea4ab5..94ed5fa 100755
--- a/tools/harness-automation/cases_R140/commissioner_9_2_2.py
+++ b/tools/harness-automation/cases_R140/commissioner_9_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_9_2_3.py b/tools/harness-automation/cases_R140/commissioner_9_2_3.py
index e13cae2..61aa37b 100755
--- a/tools/harness-automation/cases_R140/commissioner_9_2_3.py
+++ b/tools/harness-automation/cases_R140/commissioner_9_2_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/commissioner_9_2_4.py b/tools/harness-automation/cases_R140/commissioner_9_2_4.py
index 9d46c6e..c0c8b61 100755
--- a/tools/harness-automation/cases_R140/commissioner_9_2_4.py
+++ b/tools/harness-automation/cases_R140/commissioner_9_2_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_1_1.py b/tools/harness-automation/cases_R140/ed_6_1_1.py
index 52d2e4b..79deead 100755
--- a/tools/harness-automation/cases_R140/ed_6_1_1.py
+++ b/tools/harness-automation/cases_R140/ed_6_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_1_2.py b/tools/harness-automation/cases_R140/ed_6_1_2.py
index a5eb4b0..1336c49 100755
--- a/tools/harness-automation/cases_R140/ed_6_1_2.py
+++ b/tools/harness-automation/cases_R140/ed_6_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_1_3.py b/tools/harness-automation/cases_R140/ed_6_1_3.py
index c6a65ec..e99f86d 100755
--- a/tools/harness-automation/cases_R140/ed_6_1_3.py
+++ b/tools/harness-automation/cases_R140/ed_6_1_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_1_4.py b/tools/harness-automation/cases_R140/ed_6_1_4.py
index 99894dc..dfcd85d 100755
--- a/tools/harness-automation/cases_R140/ed_6_1_4.py
+++ b/tools/harness-automation/cases_R140/ed_6_1_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_1_5.py b/tools/harness-automation/cases_R140/ed_6_1_5.py
index 9e09ab8..70b9007 100755
--- a/tools/harness-automation/cases_R140/ed_6_1_5.py
+++ b/tools/harness-automation/cases_R140/ed_6_1_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_1_6.py b/tools/harness-automation/cases_R140/ed_6_1_6.py
index 399799b..7d9d9e3 100755
--- a/tools/harness-automation/cases_R140/ed_6_1_6.py
+++ b/tools/harness-automation/cases_R140/ed_6_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_2_1.py b/tools/harness-automation/cases_R140/ed_6_2_1.py
index 5740c62..26778a6 100755
--- a/tools/harness-automation/cases_R140/ed_6_2_1.py
+++ b/tools/harness-automation/cases_R140/ed_6_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_2_2.py b/tools/harness-automation/cases_R140/ed_6_2_2.py
index 4ee44ac..778afca 100755
--- a/tools/harness-automation/cases_R140/ed_6_2_2.py
+++ b/tools/harness-automation/cases_R140/ed_6_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_3_1.py b/tools/harness-automation/cases_R140/ed_6_3_1.py
index e19a0a5..f8c6cf4 100755
--- a/tools/harness-automation/cases_R140/ed_6_3_1.py
+++ b/tools/harness-automation/cases_R140/ed_6_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_4_1.py b/tools/harness-automation/cases_R140/ed_6_4_1.py
index 261bfa6..924ea4e 100755
--- a/tools/harness-automation/cases_R140/ed_6_4_1.py
+++ b/tools/harness-automation/cases_R140/ed_6_4_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_4_2.py b/tools/harness-automation/cases_R140/ed_6_4_2.py
index cb5337d..23bb14a 100755
--- a/tools/harness-automation/cases_R140/ed_6_4_2.py
+++ b/tools/harness-automation/cases_R140/ed_6_4_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_5_1.py b/tools/harness-automation/cases_R140/ed_6_5_1.py
index fae820c..7074de4 100755
--- a/tools/harness-automation/cases_R140/ed_6_5_1.py
+++ b/tools/harness-automation/cases_R140/ed_6_5_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 import time
 
diff --git a/tools/harness-automation/cases_R140/ed_6_5_2.py b/tools/harness-automation/cases_R140/ed_6_5_2.py
index 0825880..501d343 100755
--- a/tools/harness-automation/cases_R140/ed_6_5_2.py
+++ b/tools/harness-automation/cases_R140/ed_6_5_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_5_3.py b/tools/harness-automation/cases_R140/ed_6_5_3.py
index 2a9b20e..5d1e35d 100755
--- a/tools/harness-automation/cases_R140/ed_6_5_3.py
+++ b/tools/harness-automation/cases_R140/ed_6_5_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_6_1.py b/tools/harness-automation/cases_R140/ed_6_6_1.py
index 117c881..e6baa88 100755
--- a/tools/harness-automation/cases_R140/ed_6_6_1.py
+++ b/tools/harness-automation/cases_R140/ed_6_6_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_6_6_2.py b/tools/harness-automation/cases_R140/ed_6_6_2.py
index 8bc84b4..4d53ab0 100755
--- a/tools/harness-automation/cases_R140/ed_6_6_2.py
+++ b/tools/harness-automation/cases_R140/ed_6_6_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_9_2_17.py b/tools/harness-automation/cases_R140/ed_9_2_17.py
index e245fea..98f4ef0 100755
--- a/tools/harness-automation/cases_R140/ed_9_2_17.py
+++ b/tools/harness-automation/cases_R140/ed_9_2_17.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/ed_9_2_8.py b/tools/harness-automation/cases_R140/ed_9_2_8.py
index 4e254b1..94f5544 100755
--- a/tools/harness-automation/cases_R140/ed_9_2_8.py
+++ b/tools/harness-automation/cases_R140/ed_9_2_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/fed_5_7_1.py b/tools/harness-automation/cases_R140/fed_5_7_1.py
index 5fb533c..526d591 100755
--- a/tools/harness-automation/cases_R140/fed_5_7_1.py
+++ b/tools/harness-automation/cases_R140/fed_5_7_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/fed_5_7_3.py b/tools/harness-automation/cases_R140/fed_5_7_3.py
index 6e5fa35..c8ce6b6 100755
--- a/tools/harness-automation/cases_R140/fed_5_7_3.py
+++ b/tools/harness-automation/cases_R140/fed_5_7_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/fed_6_1_7.py b/tools/harness-automation/cases_R140/fed_6_1_7.py
index 7fba55f..6822e0d 100755
--- a/tools/harness-automation/cases_R140/fed_6_1_7.py
+++ b/tools/harness-automation/cases_R140/fed_6_1_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/fed_9_2_13.py b/tools/harness-automation/cases_R140/fed_9_2_13.py
index 7b84b45..5217a20 100755
--- a/tools/harness-automation/cases_R140/fed_9_2_13.py
+++ b/tools/harness-automation/cases_R140/fed_9_2_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/joiner_8_1_1.py b/tools/harness-automation/cases_R140/joiner_8_1_1.py
index d71a7b7..d022e72 100755
--- a/tools/harness-automation/cases_R140/joiner_8_1_1.py
+++ b/tools/harness-automation/cases_R140/joiner_8_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/joiner_8_1_6.py b/tools/harness-automation/cases_R140/joiner_8_1_6.py
index 8444997..3622f55 100755
--- a/tools/harness-automation/cases_R140/joiner_8_1_6.py
+++ b/tools/harness-automation/cases_R140/joiner_8_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_1_1.py b/tools/harness-automation/cases_R140/leader_5_1_1.py
index 465d2bf..149b7f4 100755
--- a/tools/harness-automation/cases_R140/leader_5_1_1.py
+++ b/tools/harness-automation/cases_R140/leader_5_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_1_13.py b/tools/harness-automation/cases_R140/leader_5_1_13.py
index d321240..5e55f85 100755
--- a/tools/harness-automation/cases_R140/leader_5_1_13.py
+++ b/tools/harness-automation/cases_R140/leader_5_1_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 import time
 
diff --git a/tools/harness-automation/cases_R140/leader_5_1_5.py b/tools/harness-automation/cases_R140/leader_5_1_5.py
index 386496c..3e3d706 100755
--- a/tools/harness-automation/cases_R140/leader_5_1_5.py
+++ b/tools/harness-automation/cases_R140/leader_5_1_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/leader_5_2_3.py b/tools/harness-automation/cases_R140/leader_5_2_3.py
index 15bd2af..4ee3d7f 100755
--- a/tools/harness-automation/cases_R140/leader_5_2_3.py
+++ b/tools/harness-automation/cases_R140/leader_5_2_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_3_6.py b/tools/harness-automation/cases_R140/leader_5_3_6.py
index 89cd19c..f96c723 100755
--- a/tools/harness-automation/cases_R140/leader_5_3_6.py
+++ b/tools/harness-automation/cases_R140/leader_5_3_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/leader_5_3_7.py b/tools/harness-automation/cases_R140/leader_5_3_7.py
index 68df333..d9a0245 100755
--- a/tools/harness-automation/cases_R140/leader_5_3_7.py
+++ b/tools/harness-automation/cases_R140/leader_5_3_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_3_8.py b/tools/harness-automation/cases_R140/leader_5_3_8.py
index 1e64255..3d505a0 100755
--- a/tools/harness-automation/cases_R140/leader_5_3_8.py
+++ b/tools/harness-automation/cases_R140/leader_5_3_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_5_1.py b/tools/harness-automation/cases_R140/leader_5_5_1.py
index 9bbc273..ecff0d6 100755
--- a/tools/harness-automation/cases_R140/leader_5_5_1.py
+++ b/tools/harness-automation/cases_R140/leader_5_5_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import re
 import time
 import unittest
diff --git a/tools/harness-automation/cases_R140/leader_5_5_2.py b/tools/harness-automation/cases_R140/leader_5_5_2.py
index 4f97bef..7ab9539 100755
--- a/tools/harness-automation/cases_R140/leader_5_5_2.py
+++ b/tools/harness-automation/cases_R140/leader_5_5_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import time
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/leader_5_5_3.py b/tools/harness-automation/cases_R140/leader_5_5_3.py
index 07eb2fe..5997c82 100755
--- a/tools/harness-automation/cases_R140/leader_5_5_3.py
+++ b/tools/harness-automation/cases_R140/leader_5_5_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_5_4.py b/tools/harness-automation/cases_R140/leader_5_5_4.py
index 0547e7a..dcabecd 100755
--- a/tools/harness-automation/cases_R140/leader_5_5_4.py
+++ b/tools/harness-automation/cases_R140/leader_5_5_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_5_7.py b/tools/harness-automation/cases_R140/leader_5_5_7.py
index a719394..e7bb575 100755
--- a/tools/harness-automation/cases_R140/leader_5_5_7.py
+++ b/tools/harness-automation/cases_R140/leader_5_5_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 from autothreadharness.harness_case import HarnessCase
 
diff --git a/tools/harness-automation/cases_R140/leader_5_6_2.py b/tools/harness-automation/cases_R140/leader_5_6_2.py
index 06080a7..2163cb2 100755
--- a/tools/harness-automation/cases_R140/leader_5_6_2.py
+++ b/tools/harness-automation/cases_R140/leader_5_6_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/leader_5_6_4.py b/tools/harness-automation/cases_R140/leader_5_6_4.py
index a588660..8d3584f 100755
--- a/tools/harness-automation/cases_R140/leader_5_6_4.py
+++ b/tools/harness-automation/cases_R140/leader_5_6_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_6_5.py b/tools/harness-automation/cases_R140/leader_5_6_5.py
index aa18f53..6da7d23 100755
--- a/tools/harness-automation/cases_R140/leader_5_6_5.py
+++ b/tools/harness-automation/cases_R140/leader_5_6_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_6_6.py b/tools/harness-automation/cases_R140/leader_5_6_6.py
index 51d80b1..80d83d9 100755
--- a/tools/harness-automation/cases_R140/leader_5_6_6.py
+++ b/tools/harness-automation/cases_R140/leader_5_6_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_5_8_4.py b/tools/harness-automation/cases_R140/leader_5_8_4.py
index 12c984c..04aec35 100755
--- a/tools/harness-automation/cases_R140/leader_5_8_4.py
+++ b/tools/harness-automation/cases_R140/leader_5_8_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_7_1_1.py b/tools/harness-automation/cases_R140/leader_7_1_1.py
index 8f8253e..0ee4c18 100755
--- a/tools/harness-automation/cases_R140/leader_7_1_1.py
+++ b/tools/harness-automation/cases_R140/leader_7_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/leader_7_1_3.py b/tools/harness-automation/cases_R140/leader_7_1_3.py
index 58db178..9db6a94 100755
--- a/tools/harness-automation/cases_R140/leader_7_1_3.py
+++ b/tools/harness-automation/cases_R140/leader_7_1_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/leader_7_1_6.py b/tools/harness-automation/cases_R140/leader_7_1_6.py
index fd1d76a..1ce1c7e 100755
--- a/tools/harness-automation/cases_R140/leader_7_1_6.py
+++ b/tools/harness-automation/cases_R140/leader_7_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/leader_7_1_7.py b/tools/harness-automation/cases_R140/leader_7_1_7.py
index 9559a74..0626580 100755
--- a/tools/harness-automation/cases_R140/leader_7_1_7.py
+++ b/tools/harness-automation/cases_R140/leader_7_1_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/leader_8_3_1.py b/tools/harness-automation/cases_R140/leader_8_3_1.py
index 8e3edf1..0f2d8ef 100755
--- a/tools/harness-automation/cases_R140/leader_8_3_1.py
+++ b/tools/harness-automation/cases_R140/leader_8_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_1.py b/tools/harness-automation/cases_R140/leader_9_2_1.py
index 923782d..f1d6d5b 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_1.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_11.py b/tools/harness-automation/cases_R140/leader_9_2_11.py
index 0174d82..26203b0 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_11.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_11.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_12.py b/tools/harness-automation/cases_R140/leader_9_2_12.py
index b35f110..42b8f03 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_12.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_12.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_18.py b/tools/harness-automation/cases_R140/leader_9_2_18.py
index 2a549df..4b231dc 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_18.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_18.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_19.py b/tools/harness-automation/cases_R140/leader_9_2_19.py
index 5c9dc21..a661064 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_19.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_19.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_2.py b/tools/harness-automation/cases_R140/leader_9_2_2.py
index 449a63f..4ae535f 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_2.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_3.py b/tools/harness-automation/cases_R140/leader_9_2_3.py
index 4d17627..ec5714c 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_3.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_4.py b/tools/harness-automation/cases_R140/leader_9_2_4.py
index e18cb36..35dc7d5 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_4.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_5.py b/tools/harness-automation/cases_R140/leader_9_2_5.py
index e4626ce..453cd15 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_5.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_6.py b/tools/harness-automation/cases_R140/leader_9_2_6.py
index aecca92..a6f5191 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_6.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_7.py b/tools/harness-automation/cases_R140/leader_9_2_7.py
index a6f2dee..7b07fdd 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_7.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/leader_9_2_9.py b/tools/harness-automation/cases_R140/leader_9_2_9.py
index 2fa91a2..d0a4b4f 100755
--- a/tools/harness-automation/cases_R140/leader_9_2_9.py
+++ b/tools/harness-automation/cases_R140/leader_9_2_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 9'
     golden_devices_required = 3
     case_need_shield = True
-    device_order = [('Router_2', False), ('Commissioner', True), ('Router_1', False), ('DUT', True)]
+    device_order = [('Router_2', False), ('Commissioner', True),
+                    ('Router_1', False), ('DUT', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases_R140/med_6_3_2.py b/tools/harness-automation/cases_R140/med_6_3_2.py
index 676a676..8586fd5 100755
--- a/tools/harness-automation/cases_R140/med_6_3_2.py
+++ b/tools/harness-automation/cases_R140/med_6_3_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/med_9_2_10.py b/tools/harness-automation/cases_R140/med_9_2_10.py
index 9153669..ef3b473 100755
--- a/tools/harness-automation/cases_R140/med_9_2_10.py
+++ b/tools/harness-automation/cases_R140/med_9_2_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 10'
     golden_devices_required = 4
     case_need_shield = True
-    device_order = [('SED_1', False), ('DUT', False), ('Router_1', False), ('Commissioner', True), ('Leader', True)]
+    device_order = [('SED_1', False), ('DUT', False), ('Router_1', False),
+                    ('Commissioner', True), ('Leader', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases_R140/med_9_2_12.py b/tools/harness-automation/cases_R140/med_9_2_12.py
index 7c93f3c..8882406 100755
--- a/tools/harness-automation/cases_R140/med_9_2_12.py
+++ b/tools/harness-automation/cases_R140/med_9_2_12.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/med_9_2_13.py b/tools/harness-automation/cases_R140/med_9_2_13.py
index f45bf21..0f69823 100755
--- a/tools/harness-automation/cases_R140/med_9_2_13.py
+++ b/tools/harness-automation/cases_R140/med_9_2_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/med_9_2_18.py b/tools/harness-automation/cases_R140/med_9_2_18.py
index 3c17bb8..bc7bdaf 100755
--- a/tools/harness-automation/cases_R140/med_9_2_18.py
+++ b/tools/harness-automation/cases_R140/med_9_2_18.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/med_9_2_6.py b/tools/harness-automation/cases_R140/med_9_2_6.py
index 5b8411c..40096d7 100755
--- a/tools/harness-automation/cases_R140/med_9_2_6.py
+++ b/tools/harness-automation/cases_R140/med_9_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/reed_5_2_4.py b/tools/harness-automation/cases_R140/reed_5_2_4.py
index 8deba1c..b73f018 100755
--- a/tools/harness-automation/cases_R140/reed_5_2_4.py
+++ b/tools/harness-automation/cases_R140/reed_5_2_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/reed_5_2_5.py b/tools/harness-automation/cases_R140/reed_5_2_5.py
index f9e3a8e..43fa627 100755
--- a/tools/harness-automation/cases_R140/reed_5_2_5.py
+++ b/tools/harness-automation/cases_R140/reed_5_2_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/reed_5_2_7.py b/tools/harness-automation/cases_R140/reed_5_2_7.py
index d77e80f..54a3b18 100755
--- a/tools/harness-automation/cases_R140/reed_5_2_7.py
+++ b/tools/harness-automation/cases_R140/reed_5_2_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/reed_5_5_5.py b/tools/harness-automation/cases_R140/reed_5_5_5.py
index c2d71b9..82cb40c 100755
--- a/tools/harness-automation/cases_R140/reed_5_5_5.py
+++ b/tools/harness-automation/cases_R140/reed_5_5_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/reed_5_6_7.py b/tools/harness-automation/cases_R140/reed_5_6_7.py
index 270fc1d..ece67ba 100755
--- a/tools/harness-automation/cases_R140/reed_5_6_7.py
+++ b/tools/harness-automation/cases_R140/reed_5_6_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/reed_5_7_2.py b/tools/harness-automation/cases_R140/reed_5_7_2.py
index 2e33bf4..f7b8162 100755
--- a/tools/harness-automation/cases_R140/reed_5_7_2.py
+++ b/tools/harness-automation/cases_R140/reed_5_7_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_1.py b/tools/harness-automation/cases_R140/router_5_1_1.py
index 637a15c..31962d4 100755
--- a/tools/harness-automation/cases_R140/router_5_1_1.py
+++ b/tools/harness-automation/cases_R140/router_5_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_10.py b/tools/harness-automation/cases_R140/router_5_1_10.py
index 8ac8817..58fbd53 100755
--- a/tools/harness-automation/cases_R140/router_5_1_10.py
+++ b/tools/harness-automation/cases_R140/router_5_1_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_11.py b/tools/harness-automation/cases_R140/router_5_1_11.py
index a818612..1c01dbe 100755
--- a/tools/harness-automation/cases_R140/router_5_1_11.py
+++ b/tools/harness-automation/cases_R140/router_5_1_11.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_12.py b/tools/harness-automation/cases_R140/router_5_1_12.py
index d69b9e8..a2cd21e 100755
--- a/tools/harness-automation/cases_R140/router_5_1_12.py
+++ b/tools/harness-automation/cases_R140/router_5_1_12.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_13.py b/tools/harness-automation/cases_R140/router_5_1_13.py
index 80e7413..94398af 100755
--- a/tools/harness-automation/cases_R140/router_5_1_13.py
+++ b/tools/harness-automation/cases_R140/router_5_1_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_2.py b/tools/harness-automation/cases_R140/router_5_1_2.py
index c430aca..2cd73fb 100755
--- a/tools/harness-automation/cases_R140/router_5_1_2.py
+++ b/tools/harness-automation/cases_R140/router_5_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_3.py b/tools/harness-automation/cases_R140/router_5_1_3.py
index b60d16f..a928717 100755
--- a/tools/harness-automation/cases_R140/router_5_1_3.py
+++ b/tools/harness-automation/cases_R140/router_5_1_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_4.py b/tools/harness-automation/cases_R140/router_5_1_4.py
index 477336f..1f7839a 100755
--- a/tools/harness-automation/cases_R140/router_5_1_4.py
+++ b/tools/harness-automation/cases_R140/router_5_1_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_6.py b/tools/harness-automation/cases_R140/router_5_1_6.py
index f641609..8d97cbd 100755
--- a/tools/harness-automation/cases_R140/router_5_1_6.py
+++ b/tools/harness-automation/cases_R140/router_5_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_7.py b/tools/harness-automation/cases_R140/router_5_1_7.py
index dfecd89..2c4bd2a 100755
--- a/tools/harness-automation/cases_R140/router_5_1_7.py
+++ b/tools/harness-automation/cases_R140/router_5_1_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_8.py b/tools/harness-automation/cases_R140/router_5_1_8.py
index adfcf26..a97b967 100755
--- a/tools/harness-automation/cases_R140/router_5_1_8.py
+++ b/tools/harness-automation/cases_R140/router_5_1_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_1_9.py b/tools/harness-automation/cases_R140/router_5_1_9.py
index 85f3083..8a9d552 100755
--- a/tools/harness-automation/cases_R140/router_5_1_9.py
+++ b/tools/harness-automation/cases_R140/router_5_1_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_2_1.py b/tools/harness-automation/cases_R140/router_5_2_1.py
index 9ac6fb2..d213607 100755
--- a/tools/harness-automation/cases_R140/router_5_2_1.py
+++ b/tools/harness-automation/cases_R140/router_5_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_2_6.py b/tools/harness-automation/cases_R140/router_5_2_6.py
index d572e00..cf7c274 100755
--- a/tools/harness-automation/cases_R140/router_5_2_6.py
+++ b/tools/harness-automation/cases_R140/router_5_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_2_7.py b/tools/harness-automation/cases_R140/router_5_2_7.py
index 90b5ba0..ecb1e99 100755
--- a/tools/harness-automation/cases_R140/router_5_2_7.py
+++ b/tools/harness-automation/cases_R140/router_5_2_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_3_1.py b/tools/harness-automation/cases_R140/router_5_3_1.py
index 7bedcf6..f2a517b 100755
--- a/tools/harness-automation/cases_R140/router_5_3_1.py
+++ b/tools/harness-automation/cases_R140/router_5_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_3_10.py b/tools/harness-automation/cases_R140/router_5_3_10.py
index b55513a..0af1b09 100755
--- a/tools/harness-automation/cases_R140/router_5_3_10.py
+++ b/tools/harness-automation/cases_R140/router_5_3_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_3_11.py b/tools/harness-automation/cases_R140/router_5_3_11.py
index 74c25b1..89bf237 100755
--- a/tools/harness-automation/cases_R140/router_5_3_11.py
+++ b/tools/harness-automation/cases_R140/router_5_3_11.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_3_2.py b/tools/harness-automation/cases_R140/router_5_3_2.py
index e915136..546f860 100755
--- a/tools/harness-automation/cases_R140/router_5_3_2.py
+++ b/tools/harness-automation/cases_R140/router_5_3_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_3_3.py b/tools/harness-automation/cases_R140/router_5_3_3.py
index 9b1d50d..9c736f4 100755
--- a/tools/harness-automation/cases_R140/router_5_3_3.py
+++ b/tools/harness-automation/cases_R140/router_5_3_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_3_4.py b/tools/harness-automation/cases_R140/router_5_3_4.py
index 19170b8..50efcbf 100755
--- a/tools/harness-automation/cases_R140/router_5_3_4.py
+++ b/tools/harness-automation/cases_R140/router_5_3_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_3_5.py b/tools/harness-automation/cases_R140/router_5_3_5.py
index d527431..0c6644e 100755
--- a/tools/harness-automation/cases_R140/router_5_3_5.py
+++ b/tools/harness-automation/cases_R140/router_5_3_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_3_9.py b/tools/harness-automation/cases_R140/router_5_3_9.py
index c6388c4..f9e196c 100755
--- a/tools/harness-automation/cases_R140/router_5_3_9.py
+++ b/tools/harness-automation/cases_R140/router_5_3_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_5_1.py b/tools/harness-automation/cases_R140/router_5_5_1.py
index 1019970..45c42bf 100755
--- a/tools/harness-automation/cases_R140/router_5_5_1.py
+++ b/tools/harness-automation/cases_R140/router_5_5_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_5_2.py b/tools/harness-automation/cases_R140/router_5_5_2.py
index a1e7364..b3a8a7c 100755
--- a/tools/harness-automation/cases_R140/router_5_5_2.py
+++ b/tools/harness-automation/cases_R140/router_5_5_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_5_3.py b/tools/harness-automation/cases_R140/router_5_5_3.py
index e2bfcd6..a94c84c 100755
--- a/tools/harness-automation/cases_R140/router_5_5_3.py
+++ b/tools/harness-automation/cases_R140/router_5_5_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_5_4.py b/tools/harness-automation/cases_R140/router_5_5_4.py
index d620448..a10de7c 100755
--- a/tools/harness-automation/cases_R140/router_5_5_4.py
+++ b/tools/harness-automation/cases_R140/router_5_5_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_5_7.py b/tools/harness-automation/cases_R140/router_5_5_7.py
index 45c5a73..e6e1e91 100755
--- a/tools/harness-automation/cases_R140/router_5_5_7.py
+++ b/tools/harness-automation/cases_R140/router_5_5_7.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_6_1.py b/tools/harness-automation/cases_R140/router_5_6_1.py
index 90a260e..2cf5317 100755
--- a/tools/harness-automation/cases_R140/router_5_6_1.py
+++ b/tools/harness-automation/cases_R140/router_5_6_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_6_3.py b/tools/harness-automation/cases_R140/router_5_6_3.py
index 16d75cd..ad81f56 100755
--- a/tools/harness-automation/cases_R140/router_5_6_3.py
+++ b/tools/harness-automation/cases_R140/router_5_6_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_6_9.py b/tools/harness-automation/cases_R140/router_5_6_9.py
index 29effa0..c79d8fa 100755
--- a/tools/harness-automation/cases_R140/router_5_6_9.py
+++ b/tools/harness-automation/cases_R140/router_5_6_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_7_1.py b/tools/harness-automation/cases_R140/router_5_7_1.py
index 760df76..e521896 100755
--- a/tools/harness-automation/cases_R140/router_5_7_1.py
+++ b/tools/harness-automation/cases_R140/router_5_7_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_7_3.py b/tools/harness-automation/cases_R140/router_5_7_3.py
index 08856f5..0b5cef1 100755
--- a/tools/harness-automation/cases_R140/router_5_7_3.py
+++ b/tools/harness-automation/cases_R140/router_5_7_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_5_8_2.py b/tools/harness-automation/cases_R140/router_5_8_2.py
index f7ea1e7..60f737e 100755
--- a/tools/harness-automation/cases_R140/router_5_8_2.py
+++ b/tools/harness-automation/cases_R140/router_5_8_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_5_8_3.py b/tools/harness-automation/cases_R140/router_5_8_3.py
index e6ceff5..644059c 100755
--- a/tools/harness-automation/cases_R140/router_5_8_3.py
+++ b/tools/harness-automation/cases_R140/router_5_8_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 from autothreadharness.harness_case import HarnessCase
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/router_7_1_2.py b/tools/harness-automation/cases_R140/router_7_1_2.py
index e6a93c5..93877ff 100755
--- a/tools/harness-automation/cases_R140/router_7_1_2.py
+++ b/tools/harness-automation/cases_R140/router_7_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_7_1_4.py b/tools/harness-automation/cases_R140/router_7_1_4.py
index 9b5a189..eb738c3 100755
--- a/tools/harness-automation/cases_R140/router_7_1_4.py
+++ b/tools/harness-automation/cases_R140/router_7_1_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_7_1_5.py b/tools/harness-automation/cases_R140/router_7_1_5.py
index c4fbcaf..fe9f11b 100755
--- a/tools/harness-automation/cases_R140/router_7_1_5.py
+++ b/tools/harness-automation/cases_R140/router_7_1_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_7_1_8.py b/tools/harness-automation/cases_R140/router_7_1_8.py
index 1cd9a3d..9c96664 100755
--- a/tools/harness-automation/cases_R140/router_7_1_8.py
+++ b/tools/harness-automation/cases_R140/router_7_1_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_8_2_1.py b/tools/harness-automation/cases_R140/router_8_2_1.py
index dd98c87..04d3d82 100755
--- a/tools/harness-automation/cases_R140/router_8_2_1.py
+++ b/tools/harness-automation/cases_R140/router_8_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_8_2_2.py b/tools/harness-automation/cases_R140/router_8_2_2.py
index 3701ec4..938a856 100755
--- a/tools/harness-automation/cases_R140/router_8_2_2.py
+++ b/tools/harness-automation/cases_R140/router_8_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_8_2_5.py b/tools/harness-automation/cases_R140/router_8_2_5.py
index 553fd6d..9ab985a 100755
--- a/tools/harness-automation/cases_R140/router_8_2_5.py
+++ b/tools/harness-automation/cases_R140/router_8_2_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_10.py b/tools/harness-automation/cases_R140/router_9_2_10.py
index c63cc34..ad0aa5e 100755
--- a/tools/harness-automation/cases_R140/router_9_2_10.py
+++ b/tools/harness-automation/cases_R140/router_9_2_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 10'
     golden_devices_required = 4
     case_need_shield = True
-    device_order = [('SED_1', False), ('MED_1', False), ('DUT', False), ('Commissioner', True), ('Leader', True)]
+    device_order = [('SED_1', False), ('MED_1', False), ('DUT', False),
+                    ('Commissioner', True), ('Leader', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases_R140/router_9_2_12.py b/tools/harness-automation/cases_R140/router_9_2_12.py
index 003e348..d4f2300 100755
--- a/tools/harness-automation/cases_R140/router_9_2_12.py
+++ b/tools/harness-automation/cases_R140/router_9_2_12.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_13.py b/tools/harness-automation/cases_R140/router_9_2_13.py
index eea2599..3bab134 100755
--- a/tools/harness-automation/cases_R140/router_9_2_13.py
+++ b/tools/harness-automation/cases_R140/router_9_2_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_14.py b/tools/harness-automation/cases_R140/router_9_2_14.py
index 1ebff32..7e2cc65 100755
--- a/tools/harness-automation/cases_R140/router_9_2_14.py
+++ b/tools/harness-automation/cases_R140/router_9_2_14.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_15.py b/tools/harness-automation/cases_R140/router_9_2_15.py
index 23f58f9..799ef37 100755
--- a/tools/harness-automation/cases_R140/router_9_2_15.py
+++ b/tools/harness-automation/cases_R140/router_9_2_15.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_16.py b/tools/harness-automation/cases_R140/router_9_2_16.py
index 9283de7..7ef4030 100755
--- a/tools/harness-automation/cases_R140/router_9_2_16.py
+++ b/tools/harness-automation/cases_R140/router_9_2_16.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_18.py b/tools/harness-automation/cases_R140/router_9_2_18.py
index edd44c5..e5c4fb0 100755
--- a/tools/harness-automation/cases_R140/router_9_2_18.py
+++ b/tools/harness-automation/cases_R140/router_9_2_18.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_6.py b/tools/harness-automation/cases_R140/router_9_2_6.py
index 7b2deb6..9cba0c7 100755
--- a/tools/harness-automation/cases_R140/router_9_2_6.py
+++ b/tools/harness-automation/cases_R140/router_9_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_8.py b/tools/harness-automation/cases_R140/router_9_2_8.py
index 1f20cc6..9e7f190 100755
--- a/tools/harness-automation/cases_R140/router_9_2_8.py
+++ b/tools/harness-automation/cases_R140/router_9_2_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/router_9_2_9.py b/tools/harness-automation/cases_R140/router_9_2_9.py
index cc53ddc..ea16126 100755
--- a/tools/harness-automation/cases_R140/router_9_2_9.py
+++ b/tools/harness-automation/cases_R140/router_9_2_9.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 9'
     golden_devices_required = 3
     case_need_shield = True
-    device_order = [('Router_2', False), ('Commissioner', True), ('DUT', False), ('Leader', True)]
+    device_order = [('Router_2', False), ('Commissioner', True), ('DUT', False),
+                    ('Leader', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases_R140/sed_6_1_1.py b/tools/harness-automation/cases_R140/sed_6_1_1.py
index 81221a7..6f27b24 100755
--- a/tools/harness-automation/cases_R140/sed_6_1_1.py
+++ b/tools/harness-automation/cases_R140/sed_6_1_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_1_2.py b/tools/harness-automation/cases_R140/sed_6_1_2.py
index c3acbc6..92f3355 100755
--- a/tools/harness-automation/cases_R140/sed_6_1_2.py
+++ b/tools/harness-automation/cases_R140/sed_6_1_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_1_3.py b/tools/harness-automation/cases_R140/sed_6_1_3.py
index 42fab23..bb989a0 100755
--- a/tools/harness-automation/cases_R140/sed_6_1_3.py
+++ b/tools/harness-automation/cases_R140/sed_6_1_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_1_4.py b/tools/harness-automation/cases_R140/sed_6_1_4.py
index c508b82..49eb27d 100755
--- a/tools/harness-automation/cases_R140/sed_6_1_4.py
+++ b/tools/harness-automation/cases_R140/sed_6_1_4.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_1_5.py b/tools/harness-automation/cases_R140/sed_6_1_5.py
index 49048f4..f7483fb 100755
--- a/tools/harness-automation/cases_R140/sed_6_1_5.py
+++ b/tools/harness-automation/cases_R140/sed_6_1_5.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_1_6.py b/tools/harness-automation/cases_R140/sed_6_1_6.py
index 5c20abc..6cc8d69 100755
--- a/tools/harness-automation/cases_R140/sed_6_1_6.py
+++ b/tools/harness-automation/cases_R140/sed_6_1_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_2_1.py b/tools/harness-automation/cases_R140/sed_6_2_1.py
index 8f340d8..2715266 100755
--- a/tools/harness-automation/cases_R140/sed_6_2_1.py
+++ b/tools/harness-automation/cases_R140/sed_6_2_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_2_2.py b/tools/harness-automation/cases_R140/sed_6_2_2.py
index a8e3176..d0b68e3 100755
--- a/tools/harness-automation/cases_R140/sed_6_2_2.py
+++ b/tools/harness-automation/cases_R140/sed_6_2_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_3_1.py b/tools/harness-automation/cases_R140/sed_6_3_1.py
index c790349..1ef1c61 100755
--- a/tools/harness-automation/cases_R140/sed_6_3_1.py
+++ b/tools/harness-automation/cases_R140/sed_6_3_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_3_2.py b/tools/harness-automation/cases_R140/sed_6_3_2.py
index e2ca907..88a24a4 100755
--- a/tools/harness-automation/cases_R140/sed_6_3_2.py
+++ b/tools/harness-automation/cases_R140/sed_6_3_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_4_1.py b/tools/harness-automation/cases_R140/sed_6_4_1.py
index 092ce63..16c0ad4 100755
--- a/tools/harness-automation/cases_R140/sed_6_4_1.py
+++ b/tools/harness-automation/cases_R140/sed_6_4_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_4_2.py b/tools/harness-automation/cases_R140/sed_6_4_2.py
index d798867..1589b95 100755
--- a/tools/harness-automation/cases_R140/sed_6_4_2.py
+++ b/tools/harness-automation/cases_R140/sed_6_4_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_5_1.py b/tools/harness-automation/cases_R140/sed_6_5_1.py
index c9704e2..f50f456 100755
--- a/tools/harness-automation/cases_R140/sed_6_5_1.py
+++ b/tools/harness-automation/cases_R140/sed_6_5_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import time
 import unittest
 
diff --git a/tools/harness-automation/cases_R140/sed_6_5_2.py b/tools/harness-automation/cases_R140/sed_6_5_2.py
index e2f3b41..c4ffff9 100755
--- a/tools/harness-automation/cases_R140/sed_6_5_2.py
+++ b/tools/harness-automation/cases_R140/sed_6_5_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_5_3.py b/tools/harness-automation/cases_R140/sed_6_5_3.py
index f8a0ca3..896301a 100755
--- a/tools/harness-automation/cases_R140/sed_6_5_3.py
+++ b/tools/harness-automation/cases_R140/sed_6_5_3.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_6_1.py b/tools/harness-automation/cases_R140/sed_6_6_1.py
index f948aa9..241d6a9 100755
--- a/tools/harness-automation/cases_R140/sed_6_6_1.py
+++ b/tools/harness-automation/cases_R140/sed_6_6_1.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_6_6_2.py b/tools/harness-automation/cases_R140/sed_6_6_2.py
index 99d423c..befce7b 100755
--- a/tools/harness-automation/cases_R140/sed_6_6_2.py
+++ b/tools/harness-automation/cases_R140/sed_6_6_2.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_9_2_10.py b/tools/harness-automation/cases_R140/sed_9_2_10.py
index 3ca4953..dc363ad 100755
--- a/tools/harness-automation/cases_R140/sed_9_2_10.py
+++ b/tools/harness-automation/cases_R140/sed_9_2_10.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
@@ -38,7 +37,8 @@
     case = '9 2 10'
     golden_devices_required = 4
     case_need_shield = True
-    device_order = [('DUT', False), ('MED_1', False), ('Router_1', False), ('Commissioner', True), ('Leader', True)]
+    device_order = [('DUT', False), ('MED_1', False), ('Router_1', False),
+                    ('Commissioner', True), ('Leader', True)]
 
     def on_dialog(self, dialog, title):
         pass
diff --git a/tools/harness-automation/cases_R140/sed_9_2_13.py b/tools/harness-automation/cases_R140/sed_9_2_13.py
index f4e877f..428086f 100755
--- a/tools/harness-automation/cases_R140/sed_9_2_13.py
+++ b/tools/harness-automation/cases_R140/sed_9_2_13.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_9_2_17.py b/tools/harness-automation/cases_R140/sed_9_2_17.py
index 5b718d6..c641ed6 100755
--- a/tools/harness-automation/cases_R140/sed_9_2_17.py
+++ b/tools/harness-automation/cases_R140/sed_9_2_17.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_9_2_18.py b/tools/harness-automation/cases_R140/sed_9_2_18.py
index 800763d..df32b93 100755
--- a/tools/harness-automation/cases_R140/sed_9_2_18.py
+++ b/tools/harness-automation/cases_R140/sed_9_2_18.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_9_2_6.py b/tools/harness-automation/cases_R140/sed_9_2_6.py
index c32a2f2..ebd60a6 100755
--- a/tools/harness-automation/cases_R140/sed_9_2_6.py
+++ b/tools/harness-automation/cases_R140/sed_9_2_6.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/cases_R140/sed_9_2_8.py b/tools/harness-automation/cases_R140/sed_9_2_8.py
index 49cf7cb..1d0efc3 100755
--- a/tools/harness-automation/cases_R140/sed_9_2_8.py
+++ b/tools/harness-automation/cases_R140/sed_9_2_8.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 import unittest
 
 from autothreadharness.harness_case import HarnessCase
diff --git a/tools/harness-automation/doc/conf.py b/tools/harness-automation/doc/conf.py
index 4a1f028..25ef992 100644
--- a/tools/harness-automation/doc/conf.py
+++ b/tools/harness-automation/doc/conf.py
@@ -27,7 +27,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 #
 # Thread Harness Automation documentation build configuration file, created by
 # sphinx-quickstart on Wed Jun 29 15:18:24 2016.
@@ -144,7 +143,6 @@
 # If true, `todo` and `todoList` produce output, else they produce nothing.
 todo_include_todos = False
 
-
 # -- Options for HTML output ----------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
@@ -288,15 +286,13 @@
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
-latex_documents = [
-    (
-        master_doc,
-        'ThreadHarnessAutomation.tex',
-        u'Thread Harness Automation Documentation',
-        u'OpenThread',
-        'manual',
-    )
-]
+latex_documents = [(
+    master_doc,
+    'ThreadHarnessAutomation.tex',
+    u'Thread Harness Automation Documentation',
+    u'OpenThread',
+    'manual',
+)]
 
 # The name of an image file (relative to this directory) to place at the top of
 # the title page.
@@ -324,42 +320,36 @@
 #
 # latex_domain_indices = True
 
-
 # -- Options for manual page output ---------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
-man_pages = [
-    (
-        master_doc,
-        'threadharnessautomation',
-        u'Thread Harness Automation Documentation',
-        [author],
-        1,
-    )
-]
+man_pages = [(
+    master_doc,
+    'threadharnessautomation',
+    u'Thread Harness Automation Documentation',
+    [author],
+    1,
+)]
 
 # If true, show URL addresses after external links.
 #
 # man_show_urls = False
 
-
 # -- Options for Texinfo output -------------------------------------------
 
 # Grouping the document tree into Texinfo files. List of tuples
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
-texinfo_documents = [
-    (
-        master_doc,
-        'ThreadHarnessAutomation',
-        u'Thread Harness Automation Documentation',
-        author,
-        'ThreadHarnessAutomation',
-        'One line description of project.',
-        'Miscellaneous',
-    )
-]
+texinfo_documents = [(
+    master_doc,
+    'ThreadHarnessAutomation',
+    u'Thread Harness Automation Documentation',
+    author,
+    'ThreadHarnessAutomation',
+    'One line description of project.',
+    'Miscellaneous',
+)]
 
 # Documents to append as an appendix to all manuals.
 #
diff --git a/tools/harness-automation/gencsv.py b/tools/harness-automation/gencsv.py
index 93a4c24..9f9b867 100755
--- a/tools/harness-automation/gencsv.py
+++ b/tools/harness-automation/gencsv.py
@@ -2,7 +2,6 @@
 import json
 import sys
 
-
 if len(sys.argv) > 1:
     filename = sys.argv[1]
 else:
@@ -20,13 +19,10 @@
 o = open('./result.csv', 'w')
 o.write('Case,Status,Started,Stopped,Reason\n')
 for k, v in sorted(result.items(), key=get_key):
-    o.write(
-        '%s,%s,%s,%s,%s\n'
-        % (
-            k,
-            (v['passed'] and 'Pass') or 'Fail',
-            v['started'],
-            v['stopped'],
-            (v['error'] or '').replace('\n', ' '),
-        )
-    )
+    o.write('%s,%s,%s,%s,%s\n' % (
+        k,
+        (v['passed'] and 'Pass') or 'Fail',
+        v['started'],
+        v['stopped'],
+        (v['error'] or '').replace('\n', ' '),
+    ))
diff --git a/tools/harness-automation/parse_topofile.py b/tools/harness-automation/parse_topofile.py
new file mode 100644
index 0000000..f34c353
--- /dev/null
+++ b/tools/harness-automation/parse_topofile.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2020, The OpenThread Authors.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the copyright holder nor the
+#    names of its contributors may be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+"""
+parse_topofile.py
+-----------------
+This script is used to parse TopologyConfig.txt file to list vendor device info
+when preparing for the Thread Certification testbed
+
+usage: parse_topofile.py [-h] [-f TOPO_FILE] [-c CASE_LIST [CASE_LIST ...]]
+
+    parse TopologyConfig file and list all devices by case
+
+    optional arguments:
+      -h, --help            show this help message and exit
+      -f TOPO_FILE          Topology config file (default: C:/GRL/Thread1.1/Thread
+                            _Harness/TestScripts/TopologyConfig.txt)
+      -c CASE_LIST [CASE_LIST ...]
+                            Test case list (e.g. 5.1.1 9.2.1, default: all)
+
+Examples:
+    1. Get case 5.1.1 vendor info
+       cmd:   python parse_topofile.py -f TopologyConfig.txt -c 5.1.1
+       output:
+       case 5.1.1:
+            role-vendor pair: [('Leader', 'ARM'), ('Router_1', 'ARM')]
+            vendor devices  : {'ARM': 2}
+
+       Testbed needed vendor devices:{'ARM': 2}
+
+    2. Get case 5.1.1 and 5.2.1 vendor info
+       cmd:    python parse_topofile.py -f TopologyConfig.txt -c 5.1.1 5.2.1
+       output:
+       case 5.1.1:
+           role-vendor pair: [('Leader', 'ARM'), ('Router_1', 'ARM')]
+           vendor devices  : {'ARM': 2}
+       case 5.2.1:
+           role-vendor pair: [('Leader', 'OpenThread'), ('REED_1', 'Kirale'), ('MED_1', 'SiLabs')]
+           vendor devices  : {'OpenThread': 1, 'Kirale': 1, 'SiLabs': 1}
+
+       Testbed needed vendor devices:{'ARM': 2, 'OpenThread': 1, 'Kirale': 1, 'SiLabs': 1}
+
+    3. Get all cases vendor info
+       cmd:    python parse_topofile.py -f TopologyConfig.txt
+       output:
+           ... ... ...
+
+       Testbed needed vendor devices:{'ARM': 4, 'NXP': 5, 'OpenThread': 5, 'Kirale': 6, 'SiLabs': 5, 'Any': 7}
+
+Notes:
+    The result is just for reference, the exact requirement per vendor may be equal or less than what is generated by the script.
+
+"""
+
+import argparse
+import logging
+import re
+from collections import Counter
+
+logging.basicConfig(format='%(message)s', level=logging.DEBUG)
+MAX_VENDOR_DEVICE = 32
+
+
+def device_calculate(topo_file, case_list):
+    testbed_vendor_dict = Counter()
+    with open(topo_file, 'r') as f:
+        for line in f:
+
+            case_vendor_dict = Counter()
+
+            if not line:
+                break
+            line = line.strip()
+
+            # line example :
+            # 5.5.1-Leader:Kirale,Router_1:OpenThread
+            try:
+                if re.match(r'\s*#.*', line):
+                    continue
+
+                matched_case = re.match(r'(.*)-(.*)', line, re.M | re.I)
+
+                if 'all' not in case_list and matched_case.group(
+                        1) not in case_list:
+                    continue
+
+                logging.info('case %s:' % matched_case.group(1))
+                if 'all' not in case_list:
+                    case_list.remove(matched_case.group(1))
+                role_vendor_str = matched_case.group(2)
+                role_vendor_raw_list = re.split(',', role_vendor_str)
+                role_vendor_list = []
+
+                for device_pair in role_vendor_raw_list:
+                    device_pair = re.split(':', device_pair)
+                    role_vendor_list.append(tuple(device_pair))
+                logging.info('\trole-vendor pair: %s' % role_vendor_list)
+            except Exception as e:
+                logging.info('Unrecognized format: %s\n%s' % (line, format(e)))
+                raise
+
+            for _, vendor in role_vendor_list:
+                case_vendor_dict[vendor] += 1
+                testbed_vendor_dict[vendor] = max(testbed_vendor_dict[vendor],
+                                                  case_vendor_dict[vendor])
+
+            logging.info('\tvendor devices  : %s' % dict(case_vendor_dict))
+
+    if case_list and 'all' not in case_list:
+        logging.info('Case %s not found' % str(case_list)[1:-1])
+
+    # vendor 'Any' stands for any other vendors
+    # override 'Any' counter when overlapping with other vendors
+    count_any = MAX_VENDOR_DEVICE
+    for key in testbed_vendor_dict:
+        if key != 'Any':
+            count_any -= testbed_vendor_dict[key]
+        if 'Any' in testbed_vendor_dict:
+            testbed_vendor_dict['Any'] = count_any
+
+    logging.info('\nTestbed needed vendor devices:%s' %
+                 dict(testbed_vendor_dict))
+
+
+def main():
+    parser = argparse.ArgumentParser(
+        description='parse TopologyConfig file and list all devices by case')
+    parser.add_argument(
+        '-f',
+        dest='topo_file',
+        default='C:/GRL/Thread1.1/Thread_Harness/TestScripts/TopologyConfig.txt',
+        help=
+        'Topology config file (default: C:/GRL/Thread1.1/Thread_Harness/TestScripts/TopologyConfig.txt)',
+    )
+
+    parser.add_argument('-c',
+                        dest='case_list',
+                        nargs='+',
+                        default=['all'],
+                        help='Test case list (e.g. 5.1.1 9.2.1, default: all) ')
+    args = parser.parse_args()
+    device_calculate(args.topo_file, args.case_list)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/tools/harness-automation/requirements.txt b/tools/harness-automation/requirements.txt
index e36117d..e3e4eaf 100644
--- a/tools/harness-automation/requirements.txt
+++ b/tools/harness-automation/requirements.txt
@@ -1,2 +1,3 @@
 pyserial
 selenium
+pysnmp
\ No newline at end of file
diff --git a/tools/harness-automation/start.sh b/tools/harness-automation/start.sh
index d5d639b..b3217da 100755
--- a/tools/harness-automation/start.sh
+++ b/tools/harness-automation/start.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
-cd $(dirname $0)
-python -u -m autothreadharness.runner $@
+cd "$(dirname "$0")" || exit 1
+python -u -m autothreadharness.runner "$@"
diff --git a/tools/harness-sniffer/OT_Sniffer.py b/tools/harness-sniffer/OT_Sniffer.py
index 3df900a..21a8678 100644
--- a/tools/harness-sniffer/OT_Sniffer.py
+++ b/tools/harness-sniffer/OT_Sniffer.py
@@ -25,7 +25,6 @@
 # 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.
-
 ''''OpenThread Sniffer API implementation'''
 
 import os
@@ -35,6 +34,7 @@
 
 
 class OT_Sniffer(ISniffer):
+
     def __init__(self, **kwargs):
         try:
             self.channel = kwargs.get('channel', 11)
@@ -43,20 +43,27 @@
             self.is_active = False
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('OT_Sniffer: [intialize] --> ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('OT_Sniffer: [intialize] --> ' +
+                                              str(e))
 
     def discoverSniffer(self):
         sniffers = []
 
-        p_discover = subprocess.Popen('extcap_ot.bat --extcap-interfaces', stdout=subprocess.PIPE, shell=True)
+        p_discover = subprocess.Popen('extcap_ot.bat --extcap-interfaces',
+                                      stdout=subprocess.PIPE,
+                                      shell=True)
         for line in p_discover.stdout.readlines():
             if line.startswith('interface'):
                 try:
                     # e.g. interface {value=COM10:460800}{display=OpenThread Sniffer COM10}
-                    interface_port = line[line.index('value=') + 6 : line.index('}{display')]
-                    sniffers.append(OT_Sniffer(addressofDevice=interface_port, channel=ModuleHelper.Default_Channel))
+                    interface_port = line[line.index('value=') +
+                                          6:line.index('}{display')]
+                    sniffers.append(
+                        OT_Sniffer(addressofDevice=interface_port,
+                                   channel=ModuleHelper.Default_Channel))
                 except Exception as e:
-                    ModuleHelper.WriteIntoDebugLogger('OT_Sniffer: [discoverSniffer] --> Error: ' + str(e))
+                    ModuleHelper.WriteIntoDebugLogger(
+                        'OT_Sniffer: [discoverSniffer] --> Error: ' + str(e))
 
         p_discover.wait()
         return sniffers
@@ -72,14 +79,17 @@
             # start sniffer
             self.setChannel(channelToCapture)
             p_where = subprocess.Popen(
-                'py -3 -c "import sys; print(sys.executable)"', stdout=subprocess.PIPE, shell=True,
+                'py -3 -c "import sys; print(sys.executable)"',
+                stdout=subprocess.PIPE,
+                shell=True,
             )
             # python_exe: e.g. C:\Python37\python.exe
             python_exe = p_where.stdout.readline().strip()
 
             if python_exe.endswith(".exe"):
                 # sniffer_py: e.g. C:\Python37\Scripts\sniffer.py
-                sniffer_py = str(os.path.dirname(python_exe)) + '\\Scripts\\sniffer.py'
+                sniffer_py = str(
+                    os.path.dirname(python_exe)) + '\\Scripts\\sniffer.py'
 
                 cmd = [
                     python_exe,
@@ -95,11 +105,13 @@
                     captureFileLocation,
                 ]
                 self.is_active = True
-                ModuleHelper.WriteIntoDebugLogger('OT_Sniffer: [cmd] --> %s' % str(cmd))
+                ModuleHelper.WriteIntoDebugLogger('OT_Sniffer: [cmd] --> %s' %
+                                                  str(cmd))
                 self.subprocess = subprocess.Popen(cmd)
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('OT_Sniffer: [startSniffer] --> Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger(
+                'OT_Sniffer: [startSniffer] --> Error: ' + str(e))
 
     def stopSniffer(self):
         """
diff --git a/tools/harness-sniffer/README.md b/tools/harness-sniffer/README.md
index 9206e6d..4af6809 100644
--- a/tools/harness-sniffer/README.md
+++ b/tools/harness-sniffer/README.md
@@ -1,17 +1,16 @@
-OpenThread Sniffer Integration with Thread Test Harness
-=============================
+# OpenThread Sniffer Integration with Thread Test Harness
+
 After following the steps below, you will be able to run Test Harness with OpenThread sniffer.
-1) require python3 is installed on windows and in the system environment path.
-2) require TestHarness is updated on `ReportEngine.pyd`
+
+1. require python3 is installed on windows and in the system environment path.
+2. require TestHarness is updated on `ReportEngine.pyd`
 
 ## Setup
+
 1. install pyspinel (for python3 only)
-    ```
-    git clone https://github.com/openthread/pyspinel.git
-    cd <path-to-pyspinel>
-    python setup.py install
-    ```
+   ```
+   git clone https://github.com/openthread/pyspinel.git
+   cd <path-to-pyspinel>
+   python setup.py install
+   ```
 2. Copy "OT_Sniffer.py" to `C:\GRL\Thread1.1\Thread_Harness\Sniffer`.
-
-
-
diff --git a/tools/harness-thci/OpenThread.py b/tools/harness-thci/OpenThread.py
index f364e84..d388384 100644
--- a/tools/harness-thci/OpenThread.py
+++ b/tools/harness-thci/OpenThread.py
@@ -25,7 +25,6 @@
 # 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.
-
 """
 >> Thread Host Controller Interface
 >> Device : OpenThread THCI
@@ -208,10 +207,8 @@
         logging.info('%s: sendCommand[%s]', self.port, cmd)
         if self.logThreadStatus == self.logStatus['running']:
             self.logThreadStatus = self.logStatus['pauseReq']
-            while (
-                self.logThreadStatus != self.logStatus['paused']
-                and self.logThreadStatus != self.logStatus['stop']
-            ):
+            while (self.logThreadStatus != self.logStatus['paused'] and
+                   self.logThreadStatus != self.logStatus['stop']):
                 pass
 
         try:
@@ -248,9 +245,8 @@
                     retry_times -= 1
                     time.sleep(0.2)
             if line != 'Done':
-                raise Exception(
-                    '%s: failed to find end of response' % self.port
-                )
+                raise Exception('%s: failed to find end of response' %
+                                self.port)
             logging.info('%s: send command[%s] done!', self.port, cmd)
             return response
         except Exception as e:
@@ -266,8 +262,7 @@
             self.__sendCommand(cmd)
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                '__disableRouterEligible() Error: ' + str(e)
-            )
+                '__disableRouterEligible() Error: ' + str(e))
 
     def __setDeviceMode(self, mode):
         """set thread device mode:
@@ -289,9 +284,8 @@
             cmd = 'mode %s' % mode
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setDeviceMode() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setDeviceMode() Error: ' +
+                                              str(e))
 
     def __setRouterUpgradeThreshold(self, iThreshold):
         """set router upgrade threshold
@@ -311,8 +305,7 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                'setRouterUpgradeThreshold() Error: ' + str(e)
-            )
+                'setRouterUpgradeThreshold() Error: ' + str(e))
 
     def __setRouterDowngradeThreshold(self, iThreshold):
         """set router downgrade threshold
@@ -333,8 +326,7 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                'setRouterDowngradeThreshold() Error: ' + str(e)
-            )
+                'setRouterDowngradeThreshold() Error: ' + str(e))
 
     def __setRouterSelectionJitter(self, iRouterJitter):
         """set ROUTER_SELECTION_JITTER parameter for REED to upgrade to Router
@@ -353,8 +345,7 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                'setRouterSelectionJitter() Error: ' + str(e)
-            )
+                'setRouterSelectionJitter() Error: ' + str(e))
 
     def __setAddressfilterMode(self, mode):
         """set address filter mode
@@ -371,8 +362,7 @@
             return False
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                '__setAddressFilterMode() Error: ' + str(e)
-            )
+                '__setAddressFilterMode() Error: ' + str(e))
 
     def __startOpenThread(self):
         """start OpenThread stack
@@ -402,9 +392,9 @@
                             self.addBlockedMAC(addr)
 
             if self.deviceRole in [
-                Thread_Device_Role.Leader,
-                Thread_Device_Role.Router,
-                Thread_Device_Role.REED,
+                    Thread_Device_Role.Leader,
+                    Thread_Device_Role.Router,
+                    Thread_Device_Role.REED,
             ]:
                 self.__setRouterSelectionJitter(1)
 
@@ -415,9 +405,8 @@
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'startOpenThread() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('startOpenThread() Error: ' +
+                                              str(e))
 
     def __stopOpenThread(self):
         """stop OpenThread stack
@@ -433,9 +422,8 @@
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'stopOpenThread() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('stopOpenThread() Error: ' +
+                                              str(e))
 
     def __isOpenThreadRunning(self):
         """check whether or not OpenThread is running
@@ -508,8 +496,7 @@
         hexIter = iter(hexPrefix)
         finalMac = ':'.join(
             a + b + c + d
-            for a, b, c, d in zip(hexIter, hexIter, hexIter, hexIter)
-        )
+            for a, b, c, d in zip(hexIter, hexIter, hexIter, hexIter))
         prefix = str(finalMac)
         strIp6Prefix = prefix[:19]
         return strIp6Prefix + '::'
@@ -559,9 +546,7 @@
                     logs.put(line)
 
                     if 'Join success' in line:
-                        self.joinCommissionedStatus = self.joinStatus[
-                            'succeed'
-                        ]
+                        self.joinCommissionedStatus = self.joinStatus['succeed']
                         break
                     elif 'Join failed' in line:
                         self.joinCommissionedStatus = self.joinStatus['failed']
@@ -597,9 +582,8 @@
             self.hasActiveDatasetToCommit = True
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setChannelMask() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setChannelMask() Error: ' +
+                                              str(e))
 
     def __setSecurityPolicy(self, securityPolicySecs, securityPolicyFlags):
         print('call _setSecurityPolicy')
@@ -611,9 +595,8 @@
             self.hasActiveDatasetToCommit = True
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setSecurityPolicy() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setSecurityPolicy() Error: ' +
+                                              str(e))
 
     def __setKeySwitchGuardTime(self, iKeySwitchGuardTime):
         """ set the Key switch guard time
@@ -636,14 +619,27 @@
                 return False
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                'setKeySwitchGuardTime() Error; ' + str(e)
-            )
+                'setKeySwitchGuardTime() Error; ' + str(e))
 
     def __getCommissionerSessionId(self):
         """ get the commissioner session id allocated from Leader """
         print('%s call getCommissionerSessionId' % self.port)
         return self.__sendCommand('commissioner sessionid')[0]
 
+    def __escapeEscapable(self, string):
+        """Escape CLI escapable characters in the given string.
+
+        Args:
+            string (str): UTF-8 input string.
+
+        Returns:
+            [str]: The modified string with escaped characters.
+        """
+        escapable_chars = '\\ \t\r\n'
+        for char in escapable_chars:
+            string = string.replace(char, '\\%s' % char)
+        return string
+
     def _connect(self):
         print('My port is %s' % self.port)
         if self.port.startswith('COM'):
@@ -669,9 +665,8 @@
                 self.handle.close()
                 self.handle = None
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'closeConnection() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('closeConnection() Error: ' +
+                                              str(e))
 
     def intialize(self):
         """initialize the serial port with baudrate, timeout parameters"""
@@ -685,15 +680,11 @@
             if self.firmwarePrefix in self.UIStatusMsg:
                 self.deviceConnected = True
             else:
-                self.UIStatusMsg = (
-                    'Firmware Not Matching Expecting '
-                    + self.firmwarePrefix
-                    + ' Now is '
-                    + self.UIStatusMsg
-                )
+                self.UIStatusMsg = ('Firmware Not Matching Expecting ' +
+                                    self.firmwarePrefix + ' Now is ' +
+                                    self.UIStatusMsg)
                 ModuleHelper.WriteIntoDebugLogger(
-                    'Err: OpenThread device Firmware not matching..'
-                )
+                    'Err: OpenThread device Firmware not matching..')
 
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('intialize() Error: ' + str(e))
@@ -711,18 +702,16 @@
         """
         print('%s call setNetworkName' % self.port)
         print(networkName)
+        networkName = self.__escapeEscapable(networkName)
         try:
             cmd = 'networkname %s' % networkName
             datasetCmd = 'dataset networkname %s' % networkName
             self.hasActiveDatasetToCommit = True
-            return (
-                self.__sendCommand(cmd)[-1] == 'Done'
-                and self.__sendCommand(datasetCmd)[-1] == 'Done'
-            )
+            return (self.__sendCommand(cmd)[-1] == 'Done' and
+                    self.__sendCommand(datasetCmd)[-1] == 'Done')
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setNetworkName() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setNetworkName() Error: ' +
+                                              str(e))
 
     def setChannel(self, channel=11):
         """set channel of Thread device operates on.
@@ -743,10 +732,8 @@
             cmd = 'channel %s' % channel
             datasetCmd = 'dataset channel %s' % channel
             self.hasActiveDatasetToCommit = True
-            return (
-                self.__sendCommand(cmd)[-1] == 'Done'
-                and self.__sendCommand(datasetCmd)[-1] == 'Done'
-            )
+            return (self.__sendCommand(cmd)[-1] == 'Done' and
+                    self.__sendCommand(datasetCmd)[-1] == 'Done')
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('setChannel() Error: ' + str(e))
 
@@ -769,9 +756,6 @@
         print(xEUI)
         address64 = ''
         try:
-            if not xEUI:
-                address64 = self.mac
-
             if not isinstance(xEUI, str):
                 address64 = self.__convertLongToHex(xEUI, 16)
             else:
@@ -888,14 +872,11 @@
 
             self.networkKey = masterKey
             self.hasActiveDatasetToCommit = True
-            return (
-                self.__sendCommand(cmd)[-1] == 'Done'
-                and self.__sendCommand(datasetCmd)[-1] == 'Done'
-            )
+            return (self.__sendCommand(cmd)[-1] == 'Done' and
+                    self.__sendCommand(datasetCmd)[-1] == 'Done')
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setNetworkkey() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setNetworkkey() Error: ' +
+                                              str(e))
 
     def addBlockedMAC(self, xEUI):
         """add a given extended address to the blacklist entry
@@ -935,9 +916,8 @@
 
             return ret
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'addBlockedMAC() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('addBlockedMAC() Error: ' +
+                                              str(e))
 
     def addAllowMAC(self, xEUI):
         """add a given extended address to the whitelist addressfilter
@@ -999,9 +979,8 @@
                     return True
             return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'clearBlockList() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('clearBlockList() Error: ' +
+                                              str(e))
 
     def clearAllowList(self):
         """clear all entries in whitelist table
@@ -1028,9 +1007,8 @@
                     return True
             return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'clearAllowList() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('clearAllowList() Error: ' +
+                                              str(e))
 
     def getDeviceRole(self):
         """get current device role in Thread Network"""
@@ -1102,7 +1080,9 @@
             if self._update_router_status and eRoleId == Thread_Device_Role.Router:
                 self.__updateRouterStatus()
 
-            time.sleep(5)  # increase delay temporally (+5s) to remedy TH's delay updates
+            time.sleep(
+                5
+            )  # increase delay temporally (+5s) to remedy TH's delay updates
 
             return True
         except Exception as e:
@@ -1204,7 +1184,9 @@
             self._sendline(cmd)
             self._expect(cmd)
             # wait echo reply
-            time.sleep(6)  # increase delay temporally (+5s) to remedy TH's delay updates
+            time.sleep(
+                6
+            )  # increase delay temporally (+5s) to remedy TH's delay updates
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('ping() Error: ' + str(e))
 
@@ -1226,9 +1208,8 @@
             # wait echo reply
             time.sleep(1)
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'multicast_ping() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('multicast_ping() Error: ' +
+                                              str(e))
 
     def getVersionNumber(self):
         """get OpenThread stack firmware version number"""
@@ -1256,10 +1237,8 @@
             cmd = 'panid %s' % panid
             datasetCmd = 'dataset panid %s' % panid
             self.hasActiveDatasetToCommit = True
-            return (
-                self.__sendCommand(cmd)[-1] == 'Done'
-                and self.__sendCommand(datasetCmd)[-1] == 'Done'
-            )
+            return (self.__sendCommand(cmd)[-1] == 'Done' and
+                    self.__sendCommand(datasetCmd)[-1] == 'Done')
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('setPANID() Error: ' + str(e))
 
@@ -1298,9 +1277,7 @@
             cmd = 'releaserouterid %s' % routerId
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'removeRouter() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('removeRouter() Error: ' + str(e))
 
     def setDefaultValues(self):
         """set default mandatory Thread Network parameter value"""
@@ -1342,9 +1319,8 @@
         try:
             self.setMAC(self.mac)
             self.__setChannelMask(self.channelMask)
-            self.__setSecurityPolicy(
-                self.securityPolicySecs, self.securityPolicyFlags
-            )
+            self.__setSecurityPolicy(self.securityPolicySecs,
+                                     self.securityPolicyFlags)
             self.setChannel(self.channel)
             self.setPANID(self.panId)
             self.setXpanId(self.xpanId)
@@ -1354,9 +1330,8 @@
             self.setPSKc(self.pskc)
             self.setActiveTimestamp(self.activetimestamp)
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setDefaultValue() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setDefaultValue() Error: ' +
+                                              str(e))
 
     def getDeviceConncetionStatus(self):
         """check if serial port connection is ready or not"""
@@ -1402,9 +1377,8 @@
             print(cmd)
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                '__setPollPeriod() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('__setPollPeriod() Error: ' +
+                                              str(e))
 
     def setLinkQuality(self, EUIadr, LinkQuality):
         """set custom LinkQualityIn for all receiving messages from the specified EUIadr
@@ -1442,9 +1416,8 @@
             print(cmd)
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setLinkQuality() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setLinkQuality() Error: ' +
+                                              str(e))
 
     def setOutBoundLinkQuality(self, LinkQuality):
         """set custom LinkQualityIn for all receiving messages from the any address
@@ -1469,8 +1442,7 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                'setOutBoundLinkQuality() Error: ' + str(e)
-            )
+                'setOutBoundLinkQuality() Error: ' + str(e))
 
     def removeRouterPrefix(self, prefixEntry):
         """remove the configured prefix on a border router
@@ -1495,9 +1467,8 @@
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'removeRouterPrefix() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('removeRouterPrefix() Error: ' +
+                                              str(e))
 
     def resetAndRejoin(self, timeout):
         """reset and join back Thread Network with a given timeout delay
@@ -1527,9 +1498,8 @@
                 return False
             return True
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'resetAndRejoin() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('resetAndRejoin() Error: ' +
+                                              str(e))
 
     def configBorderRouter(
         self,
@@ -1603,9 +1573,8 @@
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'configBorderRouter() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('configBorderRouter() Error: ' +
+                                              str(e))
 
     def setNetworkIDTimeout(self, iNwkIDTimeOut):
         """set networkid timeout for Thread device
@@ -1625,9 +1594,8 @@
             print(cmd)
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setNetworkIDTimeout() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setNetworkIDTimeout() Error: ' +
+                                              str(e))
 
     def setKeepAliveTimeOut(self, iTimeOut):
         """set keep alive timeout for device
@@ -1648,9 +1616,8 @@
             print(cmd)
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setKeepAliveTimeOut() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setKeepAliveTimeOut() Error: ' +
+                                              str(e))
 
     def setKeySequenceCounter(self, iKeySequenceValue):
         """ set the Key sequence counter corresponding to Thread Network master key
@@ -1676,8 +1643,7 @@
                 return False
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                'setKeySequenceCounter() Error; ' + str(e)
-            )
+                'setKeySequenceCounter() Error; ' + str(e))
 
     def getKeySequenceCounter(self):
         """get current Thread Network key sequence"""
@@ -1708,8 +1674,7 @@
             return self.setKeySequenceCounter(keySequence)
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                'incrementKeySequenceCounter() Error: ' + str(e)
-            )
+                'incrementKeySequenceCounter() Error: ' + str(e))
 
     def setNetworkDataRequirement(self, eDataRequirement):
         """set whether the Thread device requires the full network data
@@ -1768,9 +1733,8 @@
                 # send server data ntf to leader
                 return self.__sendCommand('netdataregister')[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'configExternalRouter() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('configExternalRouter() Error: ' +
+                                              str(e))
 
     def getNeighbouringRouters(self):
         """get neighboring routers information
@@ -1813,8 +1777,7 @@
             return routerInfo
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger(
-                'getNeighbouringDevice() Error: ' + str(e)
-            )
+                'getNeighbouringDevice() Error: ' + str(e))
 
     def getChildrenInfo(self):
         """get all children information
@@ -1862,9 +1825,8 @@
             print(childrenInfoAll)
             return childrenInfoAll
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'getChildrenInfo() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('getChildrenInfo() Error: ' +
+                                              str(e))
 
     def setXpanId(self, xPanId):
         """set extended PAN ID of Thread Network
@@ -1891,10 +1853,8 @@
 
             self.xpanId = xpanid
             self.hasActiveDatasetToCommit = True
-            return (
-                self.__sendCommand(cmd)[-1] == 'Done'
-                and self.__sendCommand(datasetCmd)[-1] == 'Done'
-            )
+            return (self.__sendCommand(cmd)[-1] == 'Done' and
+                    self.__sendCommand(datasetCmd)[-1] == 'Done')
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('setXpanId() Error: ' + str(e))
 
@@ -2025,9 +1985,8 @@
             print(cmd)
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'forceSetSlaac() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('forceSetSlaac() Error: ' +
+                                              str(e))
 
     def setSleepyNodePollTime(self):
         pass
@@ -2076,7 +2035,7 @@
     def diagnosticQuery(self, strDestinationAddr, listTLV_ids=[]):
         self.diagnosticGet(strDestinationAddr, listTLV_ids)
 
-    def startNativeCommissioner(self, strPSKc='GRLpassWord'):
+    def startNativeCommissioner(self, strPSKc='GRLPASSPHRASE'):
         # TODO: Support the whole Native Commissioner functionality
         # Currently it only aims to trigger a Discovery Request message to pass
         # Certification test 5.8.4
@@ -2110,7 +2069,7 @@
     def setJoinKey(self, strPSKc):
         pass
 
-    def scanJoiner(self, xEUI='*', strPSKd='threadjpaketest'):
+    def scanJoiner(self, xEUI='*', strPSKd='THREADJPAKETEST'):
         """scan Joiner
 
         Args:
@@ -2140,8 +2099,7 @@
         if self.__sendCommand(cmd)[-1] == 'Done':
             if self.logThreadStatus == self.logStatus['stop']:
                 self.logThread = ThreadRunner.run(
-                    target=self.__readCommissioningLogs, args=(120,)
-                )
+                    target=self.__readCommissioningLogs, args=(120,))
             return True
         else:
             return False
@@ -2182,11 +2140,10 @@
             else:
                 return False
         except Exception as e:
-            ModuleHelper.writeintodebuglogger(
-                'allowcommission() error: ' + str(e)
-            )
+            ModuleHelper.writeintodebuglogger('allowcommission() error: ' +
+                                              str(e))
 
-    def joinCommissioned(self, strPSKd='threadjpaketest', waitTime=20):
+    def joinCommissioned(self, strPSKd='THREADJPAKETEST', waitTime=20):
         """start joiner
 
         Args:
@@ -2206,8 +2163,7 @@
 
             if self.logThreadStatus == self.logStatus['stop']:
                 self.logThread = ThreadRunner.run(
-                    target=self.__readCommissioningLogs, args=(maxDuration,)
-                )
+                    target=self.__readCommissioningLogs, args=(maxDuration,))
 
             t_end = time.time() + maxDuration
             while time.time() < t_end:
@@ -2249,29 +2205,26 @@
                 if 'direction' in infoType:
                     EncryptedPacket.Direction = (
                         PlatformDiagnosticPacket_Direction.IN
-                        if 'recv' in infoValue
-                        else PlatformDiagnosticPacket_Direction.OUT
-                        if 'send' in infoValue
-                        else PlatformDiagnosticPacket_Direction.UNKNOWN
-                    )
+                        if 'recv' in infoValue else
+                        PlatformDiagnosticPacket_Direction.OUT
+                        if 'send' in infoValue else
+                        PlatformDiagnosticPacket_Direction.UNKNOWN)
                 elif 'type' in infoType:
                     EncryptedPacket.Type = (
                         PlatformDiagnosticPacket_Type.JOIN_FIN_req
-                        if 'JOIN_FIN.req' in infoValue
-                        else PlatformDiagnosticPacket_Type.JOIN_FIN_rsp
-                        if 'JOIN_FIN.rsp' in infoValue
-                        else PlatformDiagnosticPacket_Type.JOIN_ENT_req
-                        if 'JOIN_ENT.ntf' in infoValue
-                        else PlatformDiagnosticPacket_Type.JOIN_ENT_rsp
-                        if 'JOIN_ENT.rsp' in infoValue
-                        else PlatformDiagnosticPacket_Type.UNKNOWN
-                    )
+                        if 'JOIN_FIN.req' in infoValue else
+                        PlatformDiagnosticPacket_Type.JOIN_FIN_rsp
+                        if 'JOIN_FIN.rsp' in infoValue else
+                        PlatformDiagnosticPacket_Type.JOIN_ENT_req
+                        if 'JOIN_ENT.ntf' in infoValue else
+                        PlatformDiagnosticPacket_Type.
+                        JOIN_ENT_rsp if 'JOIN_ENT.rsp' in
+                        infoValue else PlatformDiagnosticPacket_Type.UNKNOWN)
                 elif 'len' in infoType:
                     bytesInEachLine = 16
                     EncryptedPacket.TLVsLength = int(infoValue)
-                    payloadLineCount = (
-                        int(infoValue) + bytesInEachLine - 1
-                    ) / bytesInEachLine
+                    payloadLineCount = (int(infoValue) + bytesInEachLine -
+                                        1) / bytesInEachLine
                     while payloadLineCount > 0:
                         payloadLineCount = payloadLineCount - 1
                         payloadLine = rawLogs.get()
@@ -2283,11 +2236,8 @@
                                 if '..' not in payloadValues[num]:
                                     payload.append(int(payloadValues[num], 16))
 
-                    EncryptedPacket.TLVs = (
-                        PlatformPackets.read(EncryptedPacket.Type, payload)
-                        if payload != []
-                        else []
-                    )
+                    EncryptedPacket.TLVs = (PlatformPackets.read(
+                        EncryptedPacket.Type, payload) if payload != [] else [])
 
             ProcessedLogs.append(EncryptedPacket)
         return ProcessedLogs
@@ -2318,8 +2268,7 @@
         print('%s call MGMT_ED_SCAN' % self.port)
         channelMask = ''
         channelMask = '0x' + self.__convertLongToHex(
-            self.__convertChannelMask(listChannelMask)
-        )
+            self.__convertChannelMask(listChannelMask))
         try:
             cmd = 'commissioner energy %s %s %s %s %s' % (
                 channelMask,
@@ -2331,13 +2280,10 @@
             print(cmd)
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.writeintodebuglogger(
-                'MGMT_ED_SCAN() error: ' + str(e)
-            )
+            ModuleHelper.writeintodebuglogger('MGMT_ED_SCAN() error: ' + str(e))
 
-    def MGMT_PANID_QUERY(
-        self, sAddr, xCommissionerSessionId, listChannelMask, xPanId
-    ):
+    def MGMT_PANID_QUERY(self, sAddr, xCommissionerSessionId, listChannelMask,
+                         xPanId):
         """send MGMT_PANID_QUERY message to a given destination
 
         Args:
@@ -2351,8 +2297,7 @@
         panid = ''
         channelMask = ''
         channelMask = '0x' + self.__convertLongToHex(
-            self.__convertChannelMask(listChannelMask)
-        )
+            self.__convertChannelMask(listChannelMask))
 
         if not isinstance(xPanId, str):
             panid = str(hex(xPanId))
@@ -2362,13 +2307,11 @@
             print(cmd)
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.writeintodebuglogger(
-                'MGMT_PANID_QUERY() error: ' + str(e)
-            )
+            ModuleHelper.writeintodebuglogger('MGMT_PANID_QUERY() error: ' +
+                                              str(e))
 
-    def MGMT_ANNOUNCE_BEGIN(
-        self, sAddr, xCommissionerSessionId, listChannelMask, xCount, xPeriod
-    ):
+    def MGMT_ANNOUNCE_BEGIN(self, sAddr, xCommissionerSessionId,
+                            listChannelMask, xCount, xPeriod):
         """send MGMT_ANNOUNCE_BEGIN message to a given destination
 
         Returns:
@@ -2378,8 +2321,7 @@
         print('%s call MGMT_ANNOUNCE_BEGIN' % self.port)
         channelMask = ''
         channelMask = '0x' + self.__convertLongToHex(
-            self.__convertChannelMask(listChannelMask)
-        )
+            self.__convertChannelMask(listChannelMask))
         try:
             cmd = 'commissioner announce %s %s %s %s' % (
                 channelMask,
@@ -2390,9 +2332,8 @@
             print(cmd)
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.writeintodebuglogger(
-                'MGMT_ANNOUNCE_BEGIN() error: ' + str(e)
-            )
+            ModuleHelper.writeintodebuglogger('MGMT_ANNOUNCE_BEGIN() error: ' +
+                                              str(e))
 
     def MGMT_ACTIVE_GET(self, Addr='', TLVs=[]):
         """send MGMT_ACTIVE_GET command
@@ -2419,9 +2360,8 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'MGMT_ACTIVE_GET() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('MGMT_ACTIVE_GET() Error: ' +
+                                              str(e))
 
     def MGMT_ACTIVE_SET(
         self,
@@ -2465,7 +2405,7 @@
 
             if sNetworkName is not None:
                 cmd += ' networkname '
-                cmd += str(sNetworkName)
+                cmd += self.__escapeEscapable(str(sNetworkName))
 
             if xChannel is not None:
                 cmd += ' channel '
@@ -2488,18 +2428,12 @@
             if listChannelMask is not None:
                 cmd += ' channelmask '
                 cmd += '0x' + self.__convertLongToHex(
-                    self.__convertChannelMask(listChannelMask)
-                )
+                    self.__convertChannelMask(listChannelMask))
 
-            if (
-                sPSKc is not None
-                or listSecurityPolicy is not None
-                or xCommissioningSessionId is not None
-                or xTmfPort is not None
-                or xSteeringData is not None
-                or xBorderRouterLocator is not None
-                or BogusTLV is not None
-            ):
+            if (sPSKc is not None or listSecurityPolicy is not None or
+                    xCommissioningSessionId is not None or
+                    xTmfPort is not None or xSteeringData is not None or
+                    xBorderRouterLocator is not None or BogusTLV is not None):
                 cmd += ' binary '
 
             if sPSKc is not None:
@@ -2585,9 +2519,8 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'MGMT_ACTIVE_SET() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('MGMT_ACTIVE_SET() Error: ' +
+                                              str(e))
 
     def MGMT_PENDING_GET(self, Addr='', TLVs=[]):
         """send MGMT_PENDING_GET command
@@ -2614,9 +2547,8 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'MGMT_PENDING_GET() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('MGMT_PENDING_GET() Error: ' +
+                                              str(e))
 
     def MGMT_PENDING_SET(
         self,
@@ -2674,7 +2606,7 @@
 
             if sNetworkName is not None:
                 cmd += ' networkname '
-                cmd += str(sNetworkName)
+                cmd += self.__escapeEscapable(str(sNetworkName))
 
             if xCommissionerSessionId is not None:
                 cmd += ' binary '
@@ -2691,9 +2623,8 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'MGMT_PENDING_SET() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('MGMT_PENDING_SET() Error: ' +
+                                              str(e))
 
     def MGMT_COMM_GET(self, Addr='ff02::1', TLVs=[]):
         """send MGMT_COMM_GET command
@@ -2716,9 +2647,8 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'MGMT_COMM_GET() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('MGMT_COMM_GET() Error: ' +
+                                              str(e))
 
     def MGMT_COMM_SET(
         self,
@@ -2768,9 +2698,8 @@
             return self.__sendCommand(cmd)[-1] == 'Done'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'MGMT_COMM_SET() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('MGMT_COMM_SET() Error: ' +
+                                              str(e))
 
     def setActiveDataset(self, listActiveDataset=[]):
         print('%s call setActiveDataset' % self.port)
@@ -2795,9 +2724,8 @@
             self.hasActiveDatasetToCommit = True
             return self.__sendCommand(cmd)[-1] == 'Done'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger(
-                'setActiveTimestamp() Error: ' + str(e)
-            )
+            ModuleHelper.WriteIntoDebugLogger('setActiveTimestamp() Error: ' +
+                                              str(e))
 
     def setUdpJoinerPort(self, portNumber):
         """set Joiner UDP Port
@@ -2826,9 +2754,8 @@
         print(cmd)
         return self.__sendCommand(cmd)[-1] == 'Done'
 
-    def sendBeacons(
-        self, sAddr, xCommissionerSessionId, listChannelMask, xPanId
-    ):
+    def sendBeacons(self, sAddr, xCommissionerSessionId, listChannelMask,
+                    xPanId):
         print('%s call sendBeacons' % self.port)
         self._sendline('scan')
         return True
diff --git a/tools/harness-thci/OpenThread_WpanCtl.py b/tools/harness-thci/OpenThread_WpanCtl.py
index 44ac566..ddd5148 100644
--- a/tools/harness-thci/OpenThread_WpanCtl.py
+++ b/tools/harness-thci/OpenThread_WpanCtl.py
@@ -25,7 +25,6 @@
 # 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.
-
 """
 >> Thread Host Controller Interface
 >> Device : OpenThread_WpanCtl THCI
@@ -45,7 +44,6 @@
 from GRLLibs.UtilityModules.ModuleHelper import ModuleHelper
 from GRLLibs.ThreadPacket.PlatformPackets import PlatformDiagnosticPacket, PlatformPackets
 from GRLLibs.UtilityModules.Plugins.AES_CMAC import Thread_PBKDF2
-
 """regex: used to split lines"""
 LINESEPX = re.compile(r'\r\n|\n')
 
@@ -71,25 +69,35 @@
             self.handle = None
             self.AutoDUTEnable = False
             self._is_net = False  # whether device is through ser2net
-            self.logStatus = {'stop': 'stop', 'running': 'running', 'pauseReq': 'pauseReq', 'paused': 'paused'}
+            self.logStatus = {
+                'stop': 'stop',
+                'running': 'running',
+                'pauseReq': 'pauseReq',
+                'paused': 'paused'
+            }
             self.logThreadStatus = self.logStatus['stop']
             # connection type 'ip' stands for SSH
-            self.connectType = (kwargs.get('Param5')).strip().lower() if kwargs.get('Param5') is not None else 'usb'
+            self.connectType = (kwargs.get('Param5')).strip().lower(
+            ) if kwargs.get('Param5') is not None else 'usb'
             # comma separated CLI prompt, wpanctl cmd prefix, Wpan interface
-            (self.prompt, self.wpan_cmd_prefix, self.wpan_interface) = (
-                kwargs.get('Param8').strip().split(',') if kwargs.get('Param8') else ['#', 'wpanctl', 'wpan0']
-            )
+            (self.prompt, self.wpan_cmd_prefix,
+             self.wpan_interface) = (kwargs.get('Param8').strip().split(',')
+                                     if kwargs.get('Param8') else
+                                     ['#', 'wpanctl', 'wpan0'])
             self.wpan_cmd_prefix += ' '
             # comma separated setting commands
-            self.precmd = (kwargs.get('Param9')).strip().split(',') if kwargs.get('Param9') else []
+            self.precmd = (kwargs.get('Param9')
+                          ).strip().split(',') if kwargs.get('Param9') else []
             if self.connectType == 'ip':
                 self.dutIpv4 = kwargs.get('TelnetIP')
                 self.dutPort = kwargs.get('TelnetPort')
                 self.port = self.dutIpv4 + ':' + self.dutPort
                 # username for SSH
-                self.username = kwargs.get('Param6').strip() if kwargs.get('Param6') else None
+                self.username = kwargs.get('Param6').strip() if kwargs.get(
+                    'Param6') else None
                 # password for SSH
-                self.password = kwargs.get('Param7').strip() if kwargs.get('Param7') else None
+                self.password = kwargs.get('Param7').strip() if kwargs.get(
+                    'Param7') else None
             else:
                 self.port = kwargs.get('SerialPort')
             self.intialize()
@@ -202,7 +210,8 @@
         logging.info('%s: sendCommand[%s]', self.port, cmd)
         if self.logThreadStatus == self.logStatus['running']:
             self.logThreadStatus = self.logStatus['pauseReq']
-            while self.logThreadStatus not in (self.logStatus['paused'], self.logStatus['stop']):
+            while self.logThreadStatus not in (self.logStatus['paused'],
+                                               self.logStatus['stop']):
                 pass
 
         ssh_stdin = None
@@ -215,12 +224,14 @@
                 retry_times -= 1
                 try:
                     if self._is_net:
-                        ssh_stdin, ssh_stdout, ssh_stderr = self.handle.exec_command(cmd)
+                        ssh_stdin, ssh_stdout, ssh_stderr = self.handle.exec_command(
+                            cmd)
                     else:
                         self._sendline(cmd)
                         self._expect(cmd)
                 except Exception as e:
-                    logging.exception('%s: failed to send command[%s]: %s', self.port, cmd, str(e))
+                    logging.exception('%s: failed to send command[%s]: %s',
+                                      self.port, cmd, str(e))
                     if retry_times == 0:
                         raise
                 else:
@@ -236,20 +247,25 @@
                 stderr_lines = ssh_stderr.readlines()
                 if stderr_lines:
                     for stderr_line in stderr_lines:
-                        if re.search(r'Not\s+Found|failed\s+with\s+error', stderr_line.strip(), re.M | re.I):
+                        if re.search(r'Not\s+Found|failed\s+with\s+error',
+                                     stderr_line.strip(), re.M | re.I):
                             print('Command failed: %s' % stderr_line)
                             return 'Fail'
                         print('Got line: %s' % stderr_line)
-                        logging.info('%s: the read line is[%s]', self.port, stderr_line)
+                        logging.info('%s: the read line is[%s]', self.port,
+                                     stderr_line)
                         response.append(str(stderr_line.strip()))
                 elif stdout_lines:
                     for stdout_line in stdout_lines:
-                        logging.info('%s: the read line is[%s]', self.port, stdout_line)
-                        if re.search(r'Not\s+Found|failed\s+with\s+error', stdout_line.strip(), re.M | re.I):
+                        logging.info('%s: the read line is[%s]', self.port,
+                                     stdout_line)
+                        if re.search(r'Not\s+Found|failed\s+with\s+error',
+                                     stdout_line.strip(), re.M | re.I):
                             print('Command failed')
                             return 'Fail'
                         print('Got line: ' + stdout_line)
-                        logging.info('%s: send command[%s] done!', self.port, cmd)
+                        logging.info('%s: send command[%s] done!', self.port,
+                                     cmd)
                         response.append(str(stdout_line.strip()))
                 response.append(self.prompt)
                 return response
@@ -262,7 +278,8 @@
                         response.append(line)
                         if re.match(self.prompt, line):
                             break
-                        elif re.search(r'Not\s+Found|failed\s+with\s+error', line, re.M | re.I):
+                        elif re.search(r'Not\s+Found|failed\s+with\s+error',
+                                       line, re.M | re.I):
                             print('Command failed')
                             return 'Fail'
 
@@ -270,7 +287,8 @@
                     time.sleep(0.1)
 
                 if retry_times == 0:
-                    raise Exception('%s: failed to find end of response' % self.port)
+                    raise Exception('%s: failed to find end of response' %
+                                    self.port)
                 logging.info('%s: send command[%s] done!', self.port, cmd)
                 return response
         except Exception as e:
@@ -287,7 +305,8 @@
                     value string without special characters
         """
         if isinstance(value, str):
-            if (value[0] == '"' and value[-1] == '"') or (value[0] == '[' and value[-1] == ']'):
+            if (value[0] == '"' and value[-1] == '"') or (value[0] == '[' and
+                                                          value[-1] == ']'):
                 return value[1:-1]
         return value
 
@@ -301,7 +320,8 @@
                 segments[i] = '0' * (4 - len(element)) + element
 
         if empty is not None:
-            segments = segments[:empty] + ['0000'] * (8 - len(segments) + 1) + segments[empty + 1 :]
+            segments = segments[:empty] + ['0000'] * (8 - len(segments) +
+                                                      1) + segments[empty + 1:]
 
         return ':'.join(segments)
 
@@ -325,7 +345,8 @@
             cmd = self.wpan_cmd_prefix + 'setprop Thread:DeviceMode %d' % mode
             return self.__sendCommand(cmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setDeviceMode() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('setDeviceMode() Error: ' +
+                                              str(e))
 
     def __setRouterUpgradeThreshold(self, iThreshold):
         """set router upgrade threshold
@@ -340,10 +361,12 @@
         """
         print('call __setRouterUpgradeThreshold')
         try:
-            cmd = self.wpan_cmd_prefix + 'setprop Thread:RouterUpgradeThreshold %s' % str(iThreshold)
+            cmd = self.wpan_cmd_prefix + 'setprop Thread:RouterUpgradeThreshold %s' % str(
+                iThreshold)
             return self.__sendCommand(cmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setRouterUpgradeThreshold() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger(
+                'setRouterUpgradeThreshold() Error: ' + str(e))
 
     def __setRouterDowngradeThreshold(self, iThreshold):
         """set router downgrade threshold
@@ -359,10 +382,12 @@
         """
         print('call __setRouterDowngradeThreshold')
         try:
-            cmd = self.wpan_cmd_prefix + 'setprop Thread:RouterDowngradeThreshold %s' % str(iThreshold)
+            cmd = self.wpan_cmd_prefix + 'setprop Thread:RouterDowngradeThreshold %s' % str(
+                iThreshold)
             return self.__sendCommand(cmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setRouterDowngradeThreshold() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger(
+                'setRouterDowngradeThreshold() Error: ' + str(e))
 
     def __setRouterSelectionJitter(self, iRouterJitter):
         """set ROUTER_SELECTION_JITTER parameter for REED to upgrade to Router
@@ -376,10 +401,12 @@
         """
         print('call _setRouterSelectionJitter')
         try:
-            cmd = self.wpan_cmd_prefix + 'setprop Thread:RouterSelectionJitter %s' % str(iRouterJitter)
+            cmd = self.wpan_cmd_prefix + 'setprop Thread:RouterSelectionJitter %s' % str(
+                iRouterJitter)
             return self.__sendCommand(cmd) != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setRouterSelectionJitter() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger(
+                'setRouterSelectionJitter() Error: ' + str(e))
 
     def __setAddressfilterMode(self, mode):
         """set address filter mode
@@ -390,18 +417,27 @@
         """
         print('call setAddressFilterMode() %s' % mode)
         try:
-            if re.match('list', mode, re.M | re.I):
-                cmd = self.wpan_cmd_prefix + 'setprop MAC:' + mode + ':Enabled 1'
-            elif mode == 'disabled':
-                cmd = self.wpan_cmd_prefix + 'setprop MAC:' + mode + ':Enabled 0'
+            if mode in ('whitelist', 'blacklist'):
+                cmd = self.wpan_cmd_prefix + 'setprop MAC:' + mode.capitalize(
+                ) + ':Enabled 1'
+            elif mode == 'disable':
+                if self._addressfilterMode != 'disable':
+                    assert self._addressfilterMode in (
+                        'whitelist', 'blacklist'), self._addressfilterMode
+                    cmd = self.wpan_cmd_prefix + 'setprop MAC:' + self._addressfilterMode.capitalize(
+                    ) + ':Enabled 0'
+                else:
+                    return True
             else:
-                print('no such option')
-                return False
+                assert False, 'unknown address filter mode: %s' % mode
+
             if self.__sendCommand(cmd)[0] != 'Fail':
+                self._addressfilterMode = mode
                 return True
             return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('__setAddressFilterMode() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger(
+                '__setAddressFilterMode() Error: ' + str(e))
 
     def __startOpenThreadWpan(self):
         """start OpenThreadWpan
@@ -447,7 +483,10 @@
             else:
                 pass
 
-            if self.deviceRole in [Thread_Device_Role.Leader, Thread_Device_Role.Router, Thread_Device_Role.REED]:
+            if self.deviceRole in [
+                    Thread_Device_Role.Leader, Thread_Device_Role.Router,
+                    Thread_Device_Role.REED
+            ]:
                 self.__setRouterSelectionJitter(1)
 
             if startType == 'form':
@@ -469,7 +508,10 @@
                 if self.__isOpenThreadWpanRunning():
                     self.isPowerDown = False
                     if self.hasActiveDatasetToCommit:
-                        if self.__sendCommand(self.wpan_cmd_prefix + 'setprop Dataset:Command SetActive')[0] == 'Fail':
+                        if self.__sendCommand(
+                                self.wpan_cmd_prefix +
+                                'setprop Dataset:Command SetActive'
+                        )[0] == 'Fail':
                             raise Exception('failed to commit active dataset')
                         else:
                             self.hasActiveDatasetToCommit = False
@@ -478,7 +520,8 @@
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('startOpenThreadWpan() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('startOpenThreadWpan() Error: ' +
+                                              str(e))
 
     def __stopOpenThreadWpan(self):
         """stop OpenThreadWpan
@@ -489,15 +532,15 @@
         """
         print('call stopOpenThreadWpan')
         try:
-            if (
-                self.__sendCommand(self.wpan_cmd_prefix + 'leave')[0] != 'Fail'
-                and self.__sendCommand(self.wpan_cmd_prefix + 'dataset erase')[0] != 'Fail'
-            ):
+            if (self.__sendCommand(self.wpan_cmd_prefix + 'leave')[0] != 'Fail'
+                    and self.__sendCommand(self.wpan_cmd_prefix +
+                                           'dataset erase')[0] != 'Fail'):
                 return True
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('stopOpenThreadWpan() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('stopOpenThreadWpan() Error: ' +
+                                              str(e))
 
     def __isOpenThreadWpanRunning(self):
         """check whether or not OpenThreadWpan is running
@@ -507,7 +550,9 @@
             False: OpenThreadWpan is not running
         """
         print('call __isOpenThreadWpanRunning')
-        if self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:State')[0]) == 'associated':
+        if self.__stripValue(
+                self.__sendCommand(self.wpan_cmd_prefix +
+                                   'getprop -v NCP:State')[0]) == 'associated':
             print('*****OpenThreadWpan is running')
             return True
         else:
@@ -526,7 +571,8 @@
             actual router id allocated by leader
         """
         routerList = []
-        routerList = self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Thread:RouterTable')
+        routerList = self.__sendCommand(self.wpan_cmd_prefix +
+                                        'getprop -v Thread:RouterTable')
         print(routerList)
         print(xRloc16)
 
@@ -574,7 +620,9 @@
         prefix2 = self.__lstrip0x(prefix1)
         hexPrefix = str(prefix2).ljust(16, '0')
         hexIter = iter(hexPrefix)
-        finalMac = ':'.join(a + b + c + d for a, b, c, d in zip(hexIter, hexIter, hexIter, hexIter))
+        finalMac = ':'.join(
+            a + b + c + d
+            for a, b, c, d in zip(hexIter, hexIter, hexIter, hexIter))
         prefix = str(finalMac)
         strIp6Prefix = prefix[:19]
         return strIp6Prefix + '::'
@@ -639,23 +687,28 @@
             cmd = self.wpan_cmd_prefix + 'setprop NCP:ChannelMask %s' % channelMask
             datasetCmd = self.wpan_cmd_prefix + 'setprop Dataset:ChannelMaskPage0 %s' % channelMask
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(datasetCmd)[0] != 'Fail'
+            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(
+                datasetCmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setChannelMask() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('setChannelMask() Error: ' +
+                                              str(e))
 
     def __setSecurityPolicy(self, securityPolicySecs, securityPolicyFlags):
         print('call _setSecurityPolicy')
         try:
-            cmd1 = self.wpan_cmd_prefix + 'setprop Dataset:SecPolicy:KeyRotation %s' % str(securityPolicySecs)
+            cmd1 = self.wpan_cmd_prefix + 'setprop Dataset:SecPolicy:KeyRotation %s' % str(
+                securityPolicySecs)
             if securityPolicyFlags == 'onrcb':
                 cmd2 = self.wpan_cmd_prefix + 'setprop Dataset:SecPolicy:Flags 0xff'
             else:
                 print('unknown policy flag :' + securityPolicyFlags)
                 return False
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd1) != 'Fail' and self.__sendCommand(cmd2) != 'Fail'
+            return self.__sendCommand(cmd1) != 'Fail' and self.__sendCommand(
+                cmd2) != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setSecurityPolicy() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('setSecurityPolicy() Error: ' +
+                                              str(e))
 
     def __setKeySwitchGuardTime(self, iKeySwitchGuardTime):
         """ set the Key switch guard time
@@ -670,26 +723,31 @@
         print('%s call setKeySwitchGuardTime' % self.port)
         print(iKeySwitchGuardTime)
         try:
-            cmd = self.wpan_cmd_prefix + 'setprop Network:KeySwitchGuardTime %s' % str(iKeySwitchGuardTime)
+            cmd = self.wpan_cmd_prefix + 'setprop Network:KeySwitchGuardTime %s' % str(
+                iKeySwitchGuardTime)
             if self.__sendCommand(cmd)[0] != 'Fail':
                 time.sleep(1)
                 return True
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setKeySwitchGuardTime() Error; ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger(
+                'setKeySwitchGuardTime() Error; ' + str(e))
 
     def __getCommissionerSessionId(self):
         """ get the commissioner session id allocated from Leader """
         print('%s call getCommissionerSessionId' % self.port)
-        return self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Commissioner:SessionId')[0]
+        return self.__sendCommand(self.wpan_cmd_prefix +
+                                  'getprop -v Commissioner:SessionId')[0]
 
     def __getJoinerState(self):
         """ get joiner state """
         maxDuration = 150  # seconds
         t_end = time.time() + maxDuration
         while time.time() < t_end:
-            joinerState = self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:State')[0])
+            joinerState = self.__stripValue(
+                self.__sendCommand(self.wpan_cmd_prefix +
+                                   'getprop -v NCP:State')[0])
             if joinerState == 'offline:commissioned':
                 return True
             elif joinerState == 'associating:credentials-needed':
@@ -750,7 +808,8 @@
                 else:
                     self._is_net = False
             except Exception as e:
-                ModuleHelper.WriteIntoDebugLogger('connect to serial Error: ' + str(e))
+                ModuleHelper.WriteIntoDebugLogger('connect to serial Error: ' +
+                                                  str(e))
 
         elif self.connectType == 'ip':
             print('My IP: %s Port: %s' % (self.dutIpv4, self.dutPort))
@@ -758,18 +817,22 @@
                 import paramiko
 
                 if not self.password:
-                    transport = paramiko.Transport((self.dutIpv4, int(self.dutPort)))
+                    transport = paramiko.Transport(
+                        (self.dutIpv4, int(self.dutPort)))
                     transport.start_client()
                     transport.auth_none(self.username)
                     self.handle = paramiko.SSHClient()
-                    self.handle.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+                    self.handle.set_missing_host_key_policy(
+                        paramiko.AutoAddPolicy())
                     self.handle._transport = transport
                 else:
                     self.handle = paramiko.SSHClient()
-                    self.handle.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-                    self.handle.connect(
-                        self.dutIpv4, port=int(self.dutPort), username=self.username, password=self.password
-                    )
+                    self.handle.set_missing_host_key_policy(
+                        paramiko.AutoAddPolicy())
+                    self.handle.connect(self.dutIpv4,
+                                        port=int(self.dutPort),
+                                        username=self.username,
+                                        password=self.password)
                 print('login success (ssh)')
                 self.deviceConnected = True
                 for precmd in self.precmd:
@@ -778,7 +841,8 @@
                 self._is_net = True
 
             except Exception as e:
-                ModuleHelper.WriteIntoDebugLogger('connect to ssh Error: ' + str(e))
+                ModuleHelper.WriteIntoDebugLogger('connect to ssh Error: ' +
+                                                  str(e))
         else:
             raise Exception('Unknown port schema')
 
@@ -790,7 +854,8 @@
                 self.handle.close()
                 self.handle = None
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('closeConnection() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('closeConnection() Error: ' +
+                                              str(e))
 
     def intialize(self):
         """initialize the serial port with baudrate, timeout parameters"""
@@ -804,10 +869,11 @@
                 self.UIStatusMsg = self.getVersionNumber()
                 if self.firmwarePrefix not in self.UIStatusMsg:
                     self.deviceConnected = False
-                    self.UIStatusMsg = (
-                        'Firmware Not Matching Expecting ' + self.firmwarePrefix + ' Now is ' + self.UIStatusMsg
-                    )
-                    raise Exception('Err: OpenThread device Firmware not matching..')
+                    self.UIStatusMsg = ('Firmware Not Matching Expecting ' +
+                                        self.firmwarePrefix + ' Now is ' +
+                                        self.UIStatusMsg)
+                    raise Exception(
+                        'Err: OpenThread device Firmware not matching..')
                 self.__sendCommand(self.wpan_cmd_prefix + 'leave')
                 self.__sendCommand(self.wpan_cmd_prefix + 'dataset erase')
             else:
@@ -832,9 +898,11 @@
             cmd = self.wpan_cmd_prefix + 'setprop -s Network:Name %s' % networkName
             datasetCmd = self.wpan_cmd_prefix + 'setprop Dataset:NetworkName %s' % networkName
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(datasetCmd)[0] != 'Fail'
+            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(
+                datasetCmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setNetworkName() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('setNetworkName() Error: ' +
+                                              str(e))
 
     def setChannel(self, channel=15):
         """set channel of Thread device operates on.
@@ -855,14 +923,16 @@
             cmd = self.wpan_cmd_prefix + 'setprop NCP:Channel %s' % channel
             datasetCmd = self.wpan_cmd_prefix + 'setprop Dataset:Channel %s' % channel
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(datasetCmd)[0] != 'Fail'
+            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(
+                datasetCmd)[0] != 'Fail'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('setChannel() Error: ' + str(e))
 
     def getChannel(self):
         """get current channel"""
         print('%s call getChannel' % self.port)
-        return self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:Channel')[0]
+        return self.__sendCommand(self.wpan_cmd_prefix +
+                                  'getprop -v NCP:Channel')[0]
 
     def setMAC(self, xEUI):
         """set the extended addresss of Thread device
@@ -878,9 +948,6 @@
 
         address64 = ''
         try:
-            if not xEUI:
-                address64 = self.mac
-
             if not isinstance(xEUI, str):
                 address64 = self.__convertLongToHex(xEUI, 16)
             else:
@@ -914,41 +981,50 @@
         else:
             if bType == MacType.FactoryMac:
                 macAddr64 = self.__stripValue(
-                    self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:HardwareAddress')[0]
-                )
+                    self.__sendCommand(self.wpan_cmd_prefix +
+                                       'getprop -v NCP:HardwareAddress')[0])
             elif bType == MacType.HashMac:
                 macAddr64 = self.__stripValue(
-                    self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:MACAddress')[0]
-                )
+                    self.__sendCommand(self.wpan_cmd_prefix +
+                                       'getprop -v NCP:MACAddress')[0])
             else:
                 macAddr64 = self.__stripValue(
-                    self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:ExtendedAddress')[0]
-                )
+                    self.__sendCommand(self.wpan_cmd_prefix +
+                                       'getprop -v NCP:ExtendedAddress')[0])
 
         return int(macAddr64, 16)
 
     def getLL64(self):
         """get link local unicast IPv6 address"""
         print('%s call getLL64' % self.port)
-        return self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v IPv6:LinkLocalAddress')[0])
+        return self.__stripValue(
+            self.__sendCommand(self.wpan_cmd_prefix +
+                               'getprop -v IPv6:LinkLocalAddress')[0])
 
     def getMLEID(self):
         """get mesh local endpoint identifier address"""
         print('%s call getMLEID' % self.port)
-        return self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v IPv6:MeshLocalAddress')[0])
+        return self.__stripValue(
+            self.__sendCommand(self.wpan_cmd_prefix +
+                               'getprop -v IPv6:MeshLocalAddress')[0])
 
     def getRloc16(self):
         """get rloc16 short address"""
         print('%s call getRloc16' % self.port)
-        rloc16 = self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Thread:RLOC16')[0]
+        rloc16 = self.__sendCommand(self.wpan_cmd_prefix +
+                                    'getprop -v Thread:RLOC16')[0]
         return int(rloc16, 16)
 
     def getRloc(self):
         """get router locator unicast IPv6 address"""
         print('%s call getRloc' % self.port)
-        prefix = self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v IPv6:MeshLocalPrefix')[0])
+        prefix = self.__stripValue(
+            self.__sendCommand(self.wpan_cmd_prefix +
+                               'getprop -v IPv6:MeshLocalPrefix')[0])
         mlprefix = prefix.split('/')[0]
-        rloc16 = self.__lstrip0x(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Thread:RLOC16')[0])
+        rloc16 = self.__lstrip0x(
+            self.__sendCommand(self.wpan_cmd_prefix +
+                               'getprop -v Thread:RLOC16')[0])
 
         print('prefix: %s' % prefix)
         print('mlprefix: %s ' % mlprefix)
@@ -965,11 +1041,14 @@
         print('%s call getGlobal' % self.port)
         globalAddrs = []
 
-        mleid = self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v IPv6:MeshLocalAddress')[0])
+        mleid = self.__stripValue(
+            self.__sendCommand(self.wpan_cmd_prefix +
+                               'getprop -v IPv6:MeshLocalAddress')[0])
 
         mleid = ModuleHelper.GetFullIpv6Address(mleid).lower()
 
-        addrs = self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v IPv6:AllAddresses')
+        addrs = self.__sendCommand(self.wpan_cmd_prefix +
+                                   'getprop -v IPv6:AllAddresses')
 
         # find rloc address firstly as a reference for current mesh local prefix as for some TCs,
         # mesh local prefix may be updated through pending dataset management.
@@ -1021,9 +1100,11 @@
 
             self.networkKey = masterKey
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(datasetCmd)[0] != 'Fail'
+            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(
+                datasetCmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setNetworkkey() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('setNetworkkey() Error: ' +
+                                              str(e))
 
     def addBlockedMAC(self, xEUI):
         """add a given extended address to the blacklist entry
@@ -1049,8 +1130,7 @@
                 return True
 
             if self._addressfilterMode != 'blacklist':
-                if self.__setAddressfilterMode('Blacklist'):
-                    self._addressfilterMode = 'blacklist'
+                self.__setAddressfilterMode('blacklist')
 
             cmd = self.wpan_cmd_prefix + 'insert MAC:Blacklist:Entries %s' % macAddr
             ret = self.__sendCommand(cmd)[0] != 'Fail'
@@ -1062,7 +1142,8 @@
 
             return ret
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('addBlockedMAC() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('addBlockedMAC() Error: ' +
+                                              str(e))
 
     def addAllowMAC(self, xEUI):
         """add a given extended address to the whitelist addressfilter
@@ -1083,8 +1164,7 @@
 
         try:
             if self._addressfilterMode != 'whitelist':
-                if self.__setAddressfilterMode('Whitelist'):
-                    self._addressfilterMode = 'whitelist'
+                self.__setAddressfilterMode('whitelist')
 
             cmd = self.wpan_cmd_prefix + 'insert MAC:Whitelist:Entries %s' % macAddr
             ret = self.__sendCommand(cmd)[0] != 'Fail'
@@ -1115,15 +1195,18 @@
 
             # disable blacklist
             if self.__setAddressfilterMode('disable'):
-                self._addressfilterMode = 'disable'
                 # clear ops
-                cmd = self.wpan_cmd_prefix + 'remove MAC:Blocklist:Entries'
-                if self.__sendCommand(cmd)[0] != 'Fail':
-                    self._addressfilterSet.clear()
-                    return True
+                for addr in self._addressfilterSet:
+                    cmd = self.wpan_cmd_prefix + 'remove MAC:Blacklist:Entries ' + addr
+                    self.__sendCommand(cmd)
+
+                self._addressfilterSet.clear()
+                return True
+
             return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('clearBlockList() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('clearBlockList() Error: ' +
+                                              str(e))
 
     def clearAllowList(self):
         """clear all entries in whitelist table
@@ -1142,20 +1225,25 @@
 
             # disable whitelist
             if self.__setAddressfilterMode('disable'):
-                self._addressfilterMode = 'disable'
                 # clear ops
-                cmd = self.wpan_cmd_prefix + 'insert MAC:Whitelist:Entries'
-                if self.__sendCommand(cmd)[0] != 'Fail':
-                    self._addressfilterSet.clear()
-                    return True
+                for addr in self._addressfilterSet:
+                    cmd = self.wpan_cmd_prefix + 'remove MAC:Whitelist:Entries ' + addr
+                    self.__sendCommand(cmd)
+
+                self._addressfilterSet.clear()
+                return True
+
             return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('clearAllowList() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('clearAllowList() Error: ' +
+                                              str(e))
 
     def getDeviceRole(self):
         """get current device role in Thread Network"""
         print('%s call getDeviceRole' % self.port)
-        return self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Network:NodeType')[0])
+        return self.__stripValue(
+            self.__sendCommand(self.wpan_cmd_prefix +
+                               'getprop -v Network:NodeType')[0])
 
     def joinNetwork(self, eRoleId):
         """make device ready to join the Thread Network with a given role
@@ -1241,7 +1329,8 @@
             print('OpenThreadWpan is not running')
             return None
 
-        return self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Network:PartitionId')[0]
+        return self.__sendCommand(self.wpan_cmd_prefix +
+                                  'getprop -v Network:PartitionId')[0]
 
     def getParentAddress(self):
         """get Thread device's parent extended address and rloc16 short address
@@ -1251,16 +1340,18 @@
         """
         print('%s call getParentAddress' % self.port)
         parentInfo = []
-        parentInfo = self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Thread:Parent')).split(
-            ' '
-        )
+        parentInfo = self.__stripValue(
+            self.__sendCommand(self.wpan_cmd_prefix +
+                               'getprop -v Thread:Parent')).split(' ')
 
         return parentInfo[0]
 
     def powerDown(self):
         """power down the OpenThreadWpan"""
         print('%s call powerDown' % self.port)
-        if self.__sendCommand(self.wpan_cmd_prefix + 'setprop Daemon:AutoAssociateAfterReset false')[0] != 'Fail':
+        if self.__sendCommand(
+                self.wpan_cmd_prefix +
+                'setprop Daemon:AutoAssociateAfterReset false')[0] != 'Fail':
             time.sleep(0.5)
             if self.__sendCommand(self.wpan_cmd_prefix + 'reset')[0] != 'Fail':
                 self.isPowerDown = True
@@ -1282,10 +1373,14 @@
         else:
             return False
 
-        if self.__sendCommand(self.wpan_cmd_prefix + 'setprop Daemon:AutoAssociateAfterReset true')[0] == 'Fail':
+        if self.__sendCommand(
+                self.wpan_cmd_prefix +
+                'setprop Daemon:AutoAssociateAfterReset true')[0] == 'Fail':
             return False
 
-        if self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:State')[0]) != 'associated':
+        if self.__stripValue(
+                self.__sendCommand(self.wpan_cmd_prefix +
+                                   'getprop -v NCP:State')[0]) != 'associated':
             print('powerUp failed')
             return False
         else:
@@ -1303,7 +1398,8 @@
             self._sendline(self.wpan_cmd_prefix + 'reset')
             self.isPowerDown = True
 
-            if self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:State')[0] != 'associated':
+            if self.__sendCommand(self.wpan_cmd_prefix +
+                                  'getprop -v NCP:State')[0] != 'associated':
                 print('[FAIL] reboot')
                 return False
             else:
@@ -1322,9 +1418,10 @@
         print('%s call ping' % self.port)
         print('destination: %s' % destination)
         try:
-            cmd = 'ping %s -c 1 -s %s -I %s' % (destination, str(length), self.wpan_interface)
+            cmd = 'ping %s -c 1 -s %s -I %s' % (destination, str(length),
+                                                self.wpan_interface)
             if self._is_net:
-                ssh_stdin, ssh_stdout, ssh_stderr = self.handle.exec_command(cmd)
+                self.handle.exec_command(cmd)
             else:
                 self._sendline(cmd)
                 self._expect(cmd)
@@ -1344,21 +1441,24 @@
         print('%s call multicast_Ping' % self.port)
         print('destination: %s' % destination)
         try:
-            cmd = 'ping %s -c 1 -s %s -I %s' % (destination, str(length), self.wpan_interface)
+            cmd = 'ping %s -c 1 -s %s -I %s' % (destination, str(length),
+                                                self.wpan_interface)
             if self._is_net:
-                ssh_stdin, ssh_stdout, ssh_stderr = self.handle.exec_command(cmd)
+                self.handle.exec_command(cmd)
             else:
                 self._sendline(cmd)
                 self._expect(cmd)
             # wait echo reply
             time.sleep(1)
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('multicast_ping() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('multicast_ping() Error: ' +
+                                              str(e))
 
     def getVersionNumber(self):
         """get OpenThreadWpan stack firmware version number"""
         print('%s call getVersionNumber' % self.port)
-        versionStr = self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:Version')[0]
+        versionStr = self.__sendCommand(self.wpan_cmd_prefix +
+                                        'getprop -v NCP:Version')[0]
 
         return self.__stripValue(versionStr)
 
@@ -1383,7 +1483,8 @@
             cmd = self.wpan_cmd_prefix + 'setprop -s Network:PANID %s' % panid
             datasetCmd = self.wpan_cmd_prefix + 'setprop Dataset:PanId %s' % panid
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(datasetCmd)[0] != 'Fail'
+            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(
+                datasetCmd)[0] != 'Fail'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('setPANID() Error: ' + str(e))
 
@@ -1468,7 +1569,8 @@
         try:
             self.setMAC(self.mac)
             self.__setChannelMask(self.channelMask)
-            self.__setSecurityPolicy(self.securityPolicySecs, self.securityPolicyFlags)
+            self.__setSecurityPolicy(self.securityPolicySecs,
+                                     self.securityPolicyFlags)
             self.setChannel(self.channel)
             self.setPANID(self.panId)
             self.setXpanId(self.xpanId)
@@ -1478,7 +1580,8 @@
             self.setPSKc(self.pskc)
             self.setActiveTimestamp(self.activetimestamp)
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setDefaultValue() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('setDefaultValue() Error: ' +
+                                              str(e))
 
     def getDeviceConncetionStatus(self):
         """check if serial port connection is ready or not"""
@@ -1520,11 +1623,13 @@
             False: fail to set the data poll period for sleepy end device
         """
         try:
-            cmd = self.wpan_cmd_prefix + 'setprop NCP:SleepyPollInterval %s' % str(iPollPeriod)
+            cmd = self.wpan_cmd_prefix + 'setprop NCP:SleepyPollInterval %s' % str(
+                iPollPeriod)
             print(cmd)
             return self.__sendCommand(cmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('__setPollingRate() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('__setPollingRate() Error: ' +
+                                              str(e))
 
     def setLinkQuality(self, EUIadr, LinkQuality):
         """set custom LinkQualityIn for all receiving messages from the specified EUIadr
@@ -1589,9 +1694,12 @@
         print('%s call resetAndRejoin' % self.port)
         print(timeout)
         try:
-            if self.__sendCommand(self.wpan_cmd_prefix + 'setprop Daemon:AutoAssociateAfterReset false')[0] != 'Fail':
+            if self.__sendCommand(self.wpan_cmd_prefix +
+                                  'setprop Daemon:AutoAssociateAfterReset false'
+                                 )[0] != 'Fail':
                 time.sleep(0.5)
-                if self.__sendCommand(self.wpan_cmd_prefix + 'reset')[0] != 'Fail':
+                if self.__sendCommand(self.wpan_cmd_prefix +
+                                      'reset')[0] != 'Fail':
                     self.isPowerDown = True
                 else:
                     return False
@@ -1607,19 +1715,31 @@
             else:
                 return False
 
-            if self.__sendCommand(self.wpan_cmd_prefix + 'setprop Daemon:AutoAssociateAfterReset true')[0] == 'Fail':
+            if self.__sendCommand(
+                    self.wpan_cmd_prefix +
+                    'setprop Daemon:AutoAssociateAfterReset true')[0] == 'Fail':
                 return False
 
-            if self.__stripValue(self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v NCP:State')[0]) != 'associated':
+            if self.__stripValue(
+                    self.__sendCommand(self.wpan_cmd_prefix +
+                                       'getprop -v NCP:State')
+                [0]) != 'associated':
                 print('[FAIL] reset and rejoin')
                 return False
             return True
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('resetAndRejoin() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('resetAndRejoin() Error: ' +
+                                              str(e))
 
-    def configBorderRouter(
-        self, P_Prefix, P_stable=1, P_default=1, P_slaac_preferred=0, P_Dhcp=0, P_preference=0, P_on_mesh=1, P_nd_dns=0
-    ):
+    def configBorderRouter(self,
+                           P_Prefix,
+                           P_stable=1,
+                           P_default=1,
+                           P_slaac_preferred=0,
+                           P_Dhcp=0,
+                           P_preference=0,
+                           P_on_mesh=1,
+                           P_nd_dns=0):
         """configure the border router with a given prefix entry parameters
 
         Args:
@@ -1657,7 +1777,8 @@
             if P_on_mesh == 1:
                 parameter += ' -o'
 
-            cmd = self.wpan_cmd_prefix + 'add-prefix %s %s -P %d' % (prefix, parameter, P_preference)
+            cmd = self.wpan_cmd_prefix + 'add-prefix %s %s -P %d' % (
+                prefix, parameter, P_preference)
             print(parameter)
             print(cmd)
             if self.__sendCommand(cmd)[0] != 'Fail':
@@ -1665,7 +1786,8 @@
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('configBorderRouter() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('configBorderRouter() Error: ' +
+                                              str(e))
 
     def setNetworkIDTimeout(self, iNwkIDTimeOut):
         """set networkid timeout for OpenThreadWpan
@@ -1694,11 +1816,13 @@
         print('%s call setKeepAliveTimeOut' % self.port)
         print(iTimeOut)
         try:
-            cmd = self.wpan_cmd_prefix + 'setprop NCP:SleepyPollInterval %s' % str(iTimeOut * 1000)
+            cmd = self.wpan_cmd_prefix + 'setprop NCP:SleepyPollInterval %s' % str(
+                iTimeOut * 1000)
             print(cmd)
             return self.__sendCommand(cmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setKeepAliveTimeOut() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('setKeepAliveTimeOut() Error: ' +
+                                              str(e))
 
     def setKeySequenceCounter(self, iKeySequenceValue):
         """ set the Key sequence counter corresponding to Thread Network master key
@@ -1716,20 +1840,23 @@
             # avoid key switch guard timer protection for reference device
             self.__setKeySwitchGuardTime(0)
 
-            cmd = self.wpan_cmd_prefix + 'setprop Network:KeyIndex %s' % str(iKeySequenceValue)
+            cmd = self.wpan_cmd_prefix + 'setprop Network:KeyIndex %s' % str(
+                iKeySequenceValue)
             if self.__sendCommand(cmd)[0] != 'Fail':
                 time.sleep(1)
                 return True
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setKeySequenceCounter() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger(
+                'setKeySequenceCounter() Error: ' + str(e))
 
     def getKeySequenceCounter(self):
         """get current Thread Network key sequence"""
         print('%s call getKeySequenceCounter' % self.port)
         keySequence = ''
-        keySequence = self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Network:KeyIndex')[0]
+        keySequence = self.__sendCommand(self.wpan_cmd_prefix +
+                                         'getprop -v Network:KeyIndex')[0]
         return keySequence
 
     def incrementKeySequenceCounter(self, iIncrementValue=1):
@@ -1754,7 +1881,8 @@
             print(keySequence)
             return self.setKeySequenceCounter(keySequence)
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('incrementKeySequenceCounter() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger(
+                'incrementKeySequenceCounter() Error: ' + str(e))
 
     def setNetworkDataRequirement(self, eDataRequirement):
         """set whether the Thread device requires the full network data
@@ -1793,9 +1921,11 @@
         prefix = self.__convertIp6PrefixStringToIp6Address(str(P_Prefix))
         try:
             if P_stable:
-                cmd = self.wpan_cmd_prefix + 'add-route %s -l 64 -p %d' % (prefix, R_Preference)
+                cmd = self.wpan_cmd_prefix + 'add-route %s -l 64 -p %d' % (
+                    prefix, R_Preference)
             else:
-                cmd = self.wpan_cmd_prefix + 'add-route %s -l 64 -p %d -n' % (prefix, R_Preference)
+                cmd = self.wpan_cmd_prefix + 'add-route %s -l 64 -p %d -n' % (
+                    prefix, R_Preference)
             print(cmd)
 
             if self.__sendCommand(cmd)[0] != 'Fail':
@@ -1803,7 +1933,8 @@
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('configExternalRouter() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('configExternalRouter() Error: ' +
+                                              str(e))
 
     def getNeighbouringRouters(self):
         """get neighboring routers information
@@ -1849,7 +1980,8 @@
 
             self.xpanId = xpanid
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(datasetCmd)[0] != 'Fail'
+            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(
+                datasetCmd)[0] != 'Fail'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('setXpanId() Error: ' + str(e))
 
@@ -1897,7 +2029,8 @@
         print('%s call setPartationId' % self.port)
         print(partationId)
 
-        cmd = self.wpan_cmd_prefix + 'setprop Network:PartitionId %s' % (str(hex(partationId)).rstrip('L'))
+        cmd = self.wpan_cmd_prefix + 'setprop Network:PartitionId %s' % (str(
+            hex(partationId)).rstrip('L'))
         print(cmd)
         return self.__sendCommand(cmd)[0] != 'Fail'
 
@@ -1950,7 +2083,8 @@
             cmd = self.wpan_cmd_prefix + 'setprop IPv6:MeshLocalPrefix %s' % sMeshLocalPrefix
             datasetCmd = self.wpan_cmd_prefix + 'setprop Dataset:MeshLocalPrefix %s' % sMeshLocalPrefix
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(datasetCmd)[0] != 'Fail'
+            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(
+                datasetCmd)[0] != 'Fail'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('setMLPrefix() Error: ' + str(e))
 
@@ -1979,7 +2113,8 @@
     def getChildTimeoutValue(self):
         """get child timeout"""
         print('%s call getChildTimeoutValue' % self.port)
-        childTimeout = self.__sendCommand(self.wpan_cmd_prefix + 'getprop -v Thread:ChildTimeout')[0]
+        childTimeout = self.__sendCommand(self.wpan_cmd_prefix +
+                                          'getprop -v Thread:ChildTimeout')[0]
         return int(childTimeout)
 
     def diagnosticGet(self, strDestinationAddr, listTLV_ids=[]):
@@ -1992,7 +2127,7 @@
     def diagnosticReset(self, strDestinationAddr, listTLV_ids=[]):
         """@todo : required if as reference device"""
 
-    def startNativeCommissioner(self, strPSKc='GRLpassWord'):
+    def startNativeCommissioner(self, strPSKc='GRLPASSPHRASE'):
         # TODO: Support the whole Native Commissioner functionality
         # Currently it only aims to trigger a Discovery Request message to pass
         # Certification test 5.8.4
@@ -2012,7 +2147,8 @@
             False: fail to start Commissioner
         """
         print('%s call startCollapsedCommissioner' % self.port)
-        startCmd = self.wpan_cmd_prefix + 'form %s -c %s -T router' % (self.networkName, str(self.channel))
+        startCmd = self.wpan_cmd_prefix + 'form %s -c %s -T router' % (
+            self.networkName, str(self.channel))
         if self.__sendCommand(startCmd) != 'Fail':
             time.sleep(2)
             cmd = self.wpan_cmd_prefix + 'commissioner start'
@@ -2026,7 +2162,7 @@
     def setJoinKey(self, strPSKc):
         pass
 
-    def scanJoiner(self, xEUI='*', strPSKd='threadjpaketest'):
+    def scanJoiner(self, xEUI='*', strPSKd='THREADJPAKETEST'):
         """scan Joiner
 
         Args:
@@ -2046,7 +2182,8 @@
         # long timeout value to avoid automatic joiner removal (in seconds)
         timeout = 500
 
-        cmd = self.wpan_cmd_prefix + 'commissioner joiner-add %s %s %s' % (eui64, str(timeout), strPSKd)
+        cmd = self.wpan_cmd_prefix + 'commissioner joiner-add %s %s %s' % (
+            eui64, str(timeout), strPSKd)
         print(cmd)
         if not self.isActiveCommissioner:
             self.startCollapsedCommissioner()
@@ -2068,7 +2205,8 @@
         print('%s call setProvisioningUrl' % self.port)
         self.provisioningUrl = strURL
         if self.deviceRole == Thread_Device_Role.Commissioner:
-            cmd = self.wpan_cmd_prefix + 'setprop Commissioner:ProvisioningUrl %s' % (strURL)
+            cmd = self.wpan_cmd_prefix + 'setprop Commissioner:ProvisioningUrl %s' % (
+                strURL)
             print(cmd)
             return self.__sendCommand(cmd)[0] != 'Fail'
         return True
@@ -2088,14 +2226,16 @@
                 return True
             if self.__sendCommand(cmd)[0] != 'Fail':
                 self.isActiveCommissioner = True
-                time.sleep(40)  # time for petition process and at least one keep alive
+                time.sleep(
+                    40)  # time for petition process and at least one keep alive
                 return True
             else:
                 return False
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('allowcommission() error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('allowcommission() error: ' +
+                                              str(e))
 
-    def joinCommissioned(self, strPSKd='threadjpaketest', waitTime=20):
+    def joinCommissioned(self, strPSKd='THREADJPAKETEST', waitTime=20):
         """start joiner
 
         Args:
@@ -2106,7 +2246,8 @@
             False: fail to start joiner
         """
         print('%s call joinCommissioned' % self.port)
-        cmd = self.wpan_cmd_prefix + 'joiner --start %s %s' % (strPSKd, self.provisioningUrl)
+        cmd = self.wpan_cmd_prefix + 'joiner --start %s %s' % (
+            strPSKd, self.provisioningUrl)
         print(cmd)
         if self.__sendCommand(cmd)[0] != 'Fail':
             if self.__getJoinerState():
@@ -2143,27 +2284,26 @@
                 if 'direction' in infoType:
                     EncryptedPacket.Direction = (
                         PlatformDiagnosticPacket_Direction.IN
-                        if 'recv' in infoValue
-                        else PlatformDiagnosticPacket_Direction.OUT
-                        if 'send' in infoValue
-                        else PlatformDiagnosticPacket_Direction.UNKNOWN
-                    )
+                        if 'recv' in infoValue else
+                        PlatformDiagnosticPacket_Direction.OUT
+                        if 'send' in infoValue else
+                        PlatformDiagnosticPacket_Direction.UNKNOWN)
                 elif 'type' in infoType:
                     EncryptedPacket.Type = (
                         PlatformDiagnosticPacket_Type.JOIN_FIN_req
-                        if 'JOIN_FIN.req' in infoValue
-                        else PlatformDiagnosticPacket_Type.JOIN_FIN_rsp
-                        if 'JOIN_FIN.rsp' in infoValue
-                        else PlatformDiagnosticPacket_Type.JOIN_ENT_req
-                        if 'JOIN_ENT.ntf' in infoValue
-                        else PlatformDiagnosticPacket_Type.JOIN_ENT_rsp
-                        if 'JOIN_ENT.rsp' in infoValue
-                        else PlatformDiagnosticPacket_Type.UNKNOWN
-                    )
+                        if 'JOIN_FIN.req' in infoValue else
+                        PlatformDiagnosticPacket_Type.JOIN_FIN_rsp
+                        if 'JOIN_FIN.rsp' in infoValue else
+                        PlatformDiagnosticPacket_Type.JOIN_ENT_req
+                        if 'JOIN_ENT.ntf' in infoValue else
+                        PlatformDiagnosticPacket_Type.
+                        JOIN_ENT_rsp if 'JOIN_ENT.rsp' in
+                        infoValue else PlatformDiagnosticPacket_Type.UNKNOWN)
                 elif 'len' in infoType:
                     bytesInEachLine = 16
                     EncryptedPacket.TLVsLength = int(infoValue)
-                    payloadLineCount = (int(infoValue) + bytesInEachLine - 1) / bytesInEachLine
+                    payloadLineCount = (int(infoValue) + bytesInEachLine -
+                                        1) / bytesInEachLine
                     while payloadLineCount > 0:
                         payloadLineCount = payloadLineCount - 1
                         payloadLine = rawLogs.get()
@@ -2175,12 +2315,14 @@
                                 if '..' not in payloadValues[num]:
                                     payload.append(int(payloadValues[num], 16))
 
-                    EncryptedPacket.TLVs = PlatformPackets.read(EncryptedPacket.Type, payload) if payload != [] else []
+                    EncryptedPacket.TLVs = PlatformPackets.read(
+                        EncryptedPacket.Type, payload) if payload != [] else []
 
             ProcessedLogs.append(EncryptedPacket)
         return ProcessedLogs
 
-    def MGMT_ED_SCAN(self, sAddr, xCommissionerSessionId, listChannelMask, xCount, xPeriod, xScanDuration):
+    def MGMT_ED_SCAN(self, sAddr, xCommissionerSessionId, listChannelMask,
+                     xCount, xPeriod, xScanDuration):
         """send MGMT_ED_SCAN message to a given destinaition.
 
         Args:
@@ -2211,7 +2353,8 @@
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('MGMT_ED_SCAN() error: ' + str(e))
 
-    def MGMT_PANID_QUERY(self, sAddr, xCommissionerSessionId, listChannelMask, xPanId):
+    def MGMT_PANID_QUERY(self, sAddr, xCommissionerSessionId, listChannelMask,
+                         xPanId):
         """send MGMT_PANID_QUERY message to a given destination
 
         Args:
@@ -2230,13 +2373,16 @@
             panid = str(hex(xPanId))
 
         try:
-            cmd = self.wpan_cmd_prefix + 'commissioner pan-id-query %s %s %s' % (panid, channelMask, sAddr)
+            cmd = self.wpan_cmd_prefix + 'commissioner pan-id-query %s %s %s' % (
+                panid, channelMask, sAddr)
             print(cmd)
             return self.__sendCommand(cmd) != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('MGMT_PANID_QUERY() error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('MGMT_PANID_QUERY() error: ' +
+                                              str(e))
 
-    def MGMT_ANNOUNCE_BEGIN(self, sAddr, xCommissionerSessionId, listChannelMask, xCount, xPeriod):
+    def MGMT_ANNOUNCE_BEGIN(self, sAddr, xCommissionerSessionId,
+                            listChannelMask, xCount, xPeriod):
         """send MGMT_ANNOUNCE_BEGIN message to a given destination
 
         Returns:
@@ -2256,7 +2402,8 @@
             print(cmd)
             return self.__sendCommand(cmd) != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('MGMT_ANNOUNCE_BEGIN() error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('MGMT_ANNOUNCE_BEGIN() error: ' +
+                                              str(e))
 
     def MGMT_ACTIVE_GET(self, Addr='', TLVs=[]):
         """send MGMT_ACTIVE_GET command
@@ -2276,7 +2423,8 @@
                 if self.__sendCommand(setTLVCmd)[0] == 'Fail':
                     return False
             else:
-                if self.__sendCommand(self.wpan_cmd_prefix + 'dataset erase')[0] == 'Fail':
+                if self.__sendCommand(self.wpan_cmd_prefix +
+                                      'dataset erase')[0] == 'Fail':
                     return False
 
             if Addr != '':
@@ -2289,7 +2437,8 @@
             return self.__sendCommand(cmd)[0] != 'Fail'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('MGMT_ACTIVE_GET() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('MGMT_ACTIVE_GET() Error: ' +
+                                              str(e))
 
     def MGMT_ACTIVE_SET(
         self,
@@ -2321,7 +2470,8 @@
         try:
             cmd = self.wpan_cmd_prefix + 'dataset mgmt-set-active'
 
-            if self.__sendCommand(self.wpan_cmd_prefix + 'dataset erase')[0] == 'Fail':
+            if self.__sendCommand(self.wpan_cmd_prefix +
+                                  'dataset erase')[0] == 'Fail':
                 return False
 
             if listActiveTimestamp is not None:
@@ -2337,17 +2487,20 @@
                     return False
 
             if sNetworkName is not None:
-                setNetworkNameCmd = self.wpan_cmd_prefix + 'setprop Dataset:NetworkName ' + str(sNetworkName)
+                setNetworkNameCmd = self.wpan_cmd_prefix + 'setprop Dataset:NetworkName ' + str(
+                    sNetworkName)
                 if self.__sendCommand(setNetworkNameCmd)[0] == 'Fail':
                     return False
 
             if xChannel is not None:
-                setChannelCmd = self.wpan_cmd_prefix + 'setprop Dataset:Channel ' + str(xChannel)
+                setChannelCmd = self.wpan_cmd_prefix + 'setprop Dataset:Channel ' + str(
+                    xChannel)
                 if self.__sendCommand(setChannelCmd)[0] == 'Fail':
                     return False
 
             if sMeshLocalPrefix is not None:
-                setMLPrefixCmd = self.wpan_cmd_prefix + 'setprop Dataset:MeshLocalPrefix ' + str(sMeshLocalPrefix)
+                setMLPrefixCmd = self.wpan_cmd_prefix + 'setprop Dataset:MeshLocalPrefix ' + str(
+                    sMeshLocalPrefix)
                 if self.__sendCommand(setMLPrefixCmd)[0] == 'Fail':
                     return False
 
@@ -2358,34 +2511,30 @@
                     return False
 
             if xPanId is not None:
-                setPanIdCmd = self.wpan_cmd_prefix + 'setprop Dataset:PanId ' + str(xPanId)
+                setPanIdCmd = self.wpan_cmd_prefix + 'setprop Dataset:PanId ' + str(
+                    xPanId)
                 if self.__sendCommand(setPanIdCmd)[0] == 'Fail':
                     return False
 
             if listChannelMask is not None:
                 setChannelMaskCmd = (
-                    self.wpan_cmd_prefix
-                    + 'setprop Dataset:ChannelMaskPage0 '
-                    + '0x'
-                    + self.__convertLongToHex(self.__convertChannelMask(listChannelMask))
-                )
+                    self.wpan_cmd_prefix + 'setprop Dataset:ChannelMaskPage0 ' +
+                    '0x' + self.__convertLongToHex(
+                        self.__convertChannelMask(listChannelMask)))
                 if self.__sendCommand(setChannelMaskCmd)[0] == 'Fail':
                     return False
 
-            if (
-                sPSKc is not None
-                or listSecurityPolicy is not None
-                or xCommissioningSessionId is not None
-                or xTmfPort is not None
-                or xSteeringData is not None
-                or xBorderRouterLocator is not None
-                or BogusTLV is not None
-            ):
+            if (sPSKc is not None or listSecurityPolicy is not None or
+                    xCommissioningSessionId is not None or
+                    xTmfPort is not None or xSteeringData is not None or
+                    xBorderRouterLocator is not None or BogusTLV is not None):
                 setRawTLVCmd = self.wpan_cmd_prefix + 'setprop Dataset:RawTlvs '
 
             if sPSKc is not None:
                 setRawTLVCmd += '0410'
-                stretchedPskc = Thread_PBKDF2.get(sPSKc, ModuleHelper.Default_XpanId, ModuleHelper.Default_NwkName)
+                stretchedPskc = Thread_PBKDF2.get(sPSKc,
+                                                  ModuleHelper.Default_XpanId,
+                                                  ModuleHelper.Default_NwkName)
                 pskc = '%x' % stretchedPskc
 
                 if len(pskc) < 32:
@@ -2466,7 +2615,8 @@
             return self.__sendCommand(cmd)[0] != 'Fail'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('MGMT_ACTIVE_SET() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('MGMT_ACTIVE_SET() Error: ' +
+                                              str(e))
 
     def MGMT_PENDING_GET(self, Addr='', TLVs=[]):
         """send MGMT_PENDING_GET command
@@ -2485,7 +2635,8 @@
                 if self.__sendCommand(setTLVCmd)[0] == 'Fail':
                     return False
             else:
-                if self.__sendCommand(self.wpan_cmd_prefix + 'dataset erase')[0] == 'Fail':
+                if self.__sendCommand(self.wpan_cmd_prefix +
+                                      'dataset erase')[0] == 'Fail':
                     return False
 
             if Addr != '':
@@ -2498,7 +2649,8 @@
             return self.__sendCommand(cmd)[0] != 'Fail'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('MGMT_PENDING_GET() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('MGMT_PENDING_GET() Error: ' +
+                                              str(e))
 
     def MGMT_PENDING_SET(
         self,
@@ -2522,7 +2674,8 @@
         print('%s call MGMT_PENDING_SET' % self.port)
         try:
             cmd = self.wpan_cmd_prefix + 'dataset mgmt-set-pending'
-            if self.__sendCommand(self.wpan_cmd_prefix + 'dataset erase')[0] == 'Fail':
+            if self.__sendCommand(self.wpan_cmd_prefix +
+                                  'dataset erase')[0] == 'Fail':
                 return False
 
             if listPendingTimestamp is not None:
@@ -2538,22 +2691,26 @@
                     return False
 
             if xDelayTimer is not None:
-                setDelayTimerCmd = self.wpan_cmd_prefix + 'setprop Dataset:Delay ' + str(xDelayTimer)
+                setDelayTimerCmd = self.wpan_cmd_prefix + 'setprop Dataset:Delay ' + str(
+                    xDelayTimer)
                 if self.__sendCommand(setDelayTimerCmd)[0] == 'Fail':
                     return False
 
             if sNetworkName is not None:
-                setNetworkNameCmd = self.wpan_cmd_prefix + 'setprop Dataset:NetworkName ' + str(sNetworkName)
+                setNetworkNameCmd = self.wpan_cmd_prefix + 'setprop Dataset:NetworkName ' + str(
+                    sNetworkName)
                 if self.__sendCommand(setNetworkNameCmd)[0] == 'Fail':
                     return False
 
             if xChannel is not None:
-                setChannelCmd = self.wpan_cmd_prefix + 'setprop Dataset:Channel ' + str(xChannel)
+                setChannelCmd = self.wpan_cmd_prefix + 'setprop Dataset:Channel ' + str(
+                    xChannel)
                 if self.__sendCommand(setChannelCmd)[0] == 'Fail':
                     return False
 
             if sMeshLocalPrefix is not None:
-                setMLPrefixCmd = self.wpan_cmd_prefix + 'setprop Dataset:MeshLocalPrefix ' + str(sMeshLocalPrefix)
+                setMLPrefixCmd = self.wpan_cmd_prefix + 'setprop Dataset:MeshLocalPrefix ' + str(
+                    sMeshLocalPrefix)
                 if self.__sendCommand(setMLPrefixCmd)[0] == 'Fail':
                     return False
 
@@ -2564,7 +2721,8 @@
                     return False
 
             if xPanId is not None:
-                setPanIdCmd = self.wpan_cmd_prefix + 'setprop Dataset:PanId ' + str(xPanId)
+                setPanIdCmd = self.wpan_cmd_prefix + 'setprop Dataset:PanId ' + str(
+                    xPanId)
                 if self.__sendCommand(setPanIdCmd)[0] == 'Fail':
                     return False
 
@@ -2576,7 +2734,8 @@
             return self.__sendCommand(cmd)[0] != 'Fail'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('MGMT_PENDING_SET() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('MGMT_PENDING_SET() Error: ' +
+                                              str(e))
 
     def MGMT_COMM_GET(self, Addr='ff02::1', TLVs=[]):
         """send MGMT_COMM_GET command
@@ -2600,7 +2759,8 @@
             return self.__sendCommand(cmd)[0] != 'Fail'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('MGMT_COMM_GET() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('MGMT_COMM_GET() Error: ' +
+                                              str(e))
 
     def MGMT_COMM_SET(
         self,
@@ -2635,12 +2795,14 @@
             elif xCommissionerSessionID is None:
                 # use original session id
                 if self.isActiveCommissioner is True:
-                    cmd += '0b02' + self.__lstrip0x(self.__getCommissionerSessionId())
+                    cmd += '0b02' + self.__lstrip0x(
+                        self.__getCommissionerSessionId())
                 else:
                     pass
 
             if xSteeringData is not None:
-                cmd += '08' + str(len(hex(xSteeringData)[2:])) + str(hex(xSteeringData)[2:])
+                cmd += '08' + str(len(hex(xSteeringData)[2:])) + str(
+                    hex(xSteeringData)[2:])
 
             if xBorderRouterLocator is not None:
                 cmd += '0902' + str(hex(xBorderRouterLocator))
@@ -2653,7 +2815,8 @@
             return self.__sendCommand(cmd)[0] != 'Fail'
 
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('MGMT_COMM_SET() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('MGMT_COMM_SET() Error: ' +
+                                              str(e))
 
     def setActiveDataset(self, listActiveDataset=[]):
         print('%s call setActiveDataset' % self.port)
@@ -2667,7 +2830,8 @@
             cmd = self.wpan_cmd_prefix + 'setprop Network:PSKc %s' % strPSKc
             datasetCmd = self.wpan_cmd_prefix + 'setprop Dataset:PSKc %s' % strPSKc
             self.hasActiveDatasetToCommit = True
-            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(datasetCmd)[0] != 'Fail'
+            return self.__sendCommand(cmd)[0] != 'Fail' and self.__sendCommand(
+                datasetCmd)[0] != 'Fail'
         except Exception as e:
             ModuleHelper.WriteIntoDebugLogger('setPSKc() Error: ' + str(e))
 
@@ -2682,7 +2846,8 @@
             self.hasActiveDatasetToCommit = True
             return self.__sendCommand(cmd)[0] != 'Fail'
         except Exception as e:
-            ModuleHelper.WriteIntoDebugLogger('setActiveTimestamp() Error: ' + str(e))
+            ModuleHelper.WriteIntoDebugLogger('setActiveTimestamp() Error: ' +
+                                              str(e))
 
     def setUdpJoinerPort(self, portNumber):
         """set Joiner UDP Port
@@ -2713,7 +2878,8 @@
         else:
             return False
 
-    def sendBeacons(self, sAddr, xCommissionerSessionId, listChannelMask, xPanId):
+    def sendBeacons(self, sAddr, xCommissionerSessionId, listChannelMask,
+                    xPanId):
         print('%s call sendBeacons' % self.port)
         self._sendline(self.wpan_cmd_prefix + 'scan')
         return True
diff --git a/tools/harness-thci/README.md b/tools/harness-thci/README.md
index 31016d4..d6105a5 100644
--- a/tools/harness-thci/README.md
+++ b/tools/harness-thci/README.md
@@ -1,21 +1,15 @@
-THCI & Test Environment Setup
-=============================
+# THCI & Test Environment Setup
 
-THCI (Thread Host Controller Interface) is an implementation of the Python abstract class template "IThci",
-which is used by the Thread Test Harness Software to control OpenThread-based reference devices according to each test
-scenario.
+THCI (Thread Host Controller Interface) is an implementation of the Python abstract class template "IThci", which is used by the Thread Test Harness Software to control OpenThread-based reference devices according to each test scenario.
 
 Currently, there are two THCI implementations for OpenThread:
 
-* OpenThread CLI — Based on the CC2538 example platform, which is included in the current Thread Test Harness Software
-  release.
-* OpenThread `wpanctl` — Based on `wpantund` running on a Linux host (for example, a Raspberry Pi 3B) working with a Network
-  Co-Processor (NCP) (for example, a Nordic Semiconductor nRF52840) running an OpenThread NCP image.
+- OpenThread CLI — Based on the CC2538 example platform, which is included in the current Thread Test Harness Software release.
+- OpenThread `wpanctl` — Based on `wpantund` running on a Linux host (for example, a Raspberry Pi 3B) working with a Network Co-Processor (NCP) (for example, a Nordic Semiconductor nRF52840) running an OpenThread NCP image.
 
-Platform developers should modify the THCI implementation directly to match their platform (for example, serial baud rate).
-Alternatively, platform developers may follow the instructions below to add a new THCI implementation to the Test Harness.
+Platform developers should modify the THCI implementation directly to match their platform (for example, serial baud rate). Alternatively, platform developers may follow the instructions below to add a new THCI implementation to the Test Harness.
 
-## OpenThread Environment Setup ##
+## OpenThread Environment Setup
 
 1. Copy "OpenThread.png" to `C:\GRL\Thread1.1\Web\images`.
 
@@ -23,8 +17,7 @@
 
 3. Copy "OpenThread.py" to `C:GRL\Thread1.1\Thread_Harness\THCI`.
 
-4. Connect the DUT (Device Under Test), a sniffer, and CC2538DK (or other hardware running OpenThread, as the reference device)
-   to the Host PC.
+4. Connect the DUT (Device Under Test), a sniffer, and CC2538DK (or other hardware running OpenThread, as the reference device) to the Host PC.
 
 5. Launch the Thread Test Harness Software, modify the default configuration if needed, and select **Start**.
 
@@ -32,8 +25,7 @@
 
 7. Select one or more test cases to execute.
 
-
-## OpenThread WpanCtl Environment Setup ##
+## OpenThread WpanCtl Environment Setup
 
 1. Copy "OpenThread_WpanCtl.png" to `C:\GRL\Thread1.1\Web\images`.
 
@@ -43,14 +35,11 @@
 
 4. Connect the NCP board (nRF52840) to the Raspberry Pi's USB port and verify that the `wpanctl` command works.
 
-5. Connect the Raspberry Pi's GPIOs (for Raspberry Pi 3B, link Pin8 as TXD, Pin10 as RXD, and Pin14 as GND) with
-   a UART2USB adapter.
+5. Connect the Raspberry Pi's GPIOs (for Raspberry Pi 3B, link Pin8 as TXD, Pin10 as RXD, and Pin14 as GND) with a UART2USB adapter.
 
 6. Connect the DUT (with Step 5's adapter), sniffer, and other golden devices (as reference devices) to the Host PC.
 
-7. Get the DUT serial port hardware identifier and add a new platform group named OpenThread_WpanCtl in
-   `C:\GRL\Thread1.1\Config\Configuration.ini`. See https://openthread.io/certification/automation-setup#acting_as_a_new_reference_platform
-   for more information.
+7. Get the DUT serial port hardware identifier and add a new platform group named OpenThread_WpanCtl in `C:\GRL\Thread1.1\Config\Configuration.ini`. See https://openthread.io/certification/automation-setup#acting_as_a_new_reference_platform for more information.
 
 8. Launch the Thread Test Harness Software, modify the default configuration if needed, and select **Start**.
 
@@ -58,10 +47,7 @@
 
 10. Select one or more test cases to execute.
 
-
-The above is for the serial connection mode between the DUT and the Host PC. The ssh connection mode is
-also supported for OpenThread WpanCtl, but it can not be auto-discovered and only can be used via ‘Drag and Add’ way
-in the ‘Configure Test Bed’ Page of Test Harness. The configuration is as following:
+The above is for the serial connection mode between the DUT and the Host PC. The ssh connection mode is also supported for OpenThread WpanCtl, but it can not be auto-discovered and only can be used via ‘Drag and Add’ way in the ‘Configure Test Bed’ Page of Test Harness. The configuration is as following:
 
 1. Make Raspberry Pi and Host PC in the same LAN.
 
@@ -71,20 +57,12 @@
 
 4. Copy "OpenThread_WpanCtl.png" to `C:\GRL\Thread1.1\Web\images`.
 
-5. Modify the Device section "forParam" values referring to the following indication then
-   Copy "deviceInputFields.xml" to `C:\GRL\Thread1.1\Web\data`.
-        TelnetIP : device's IP address
-        Param5 : 'ip' for SSH login
-        Param6 : SSH username
-        Param7 : SSH password
-        Param8 : comma separated CLI prompt, Wpan command prefix, Wpan interface
-        Param9 : comma separated device's setting commands before test
+5. Modify the Device section "forParam" values referring to the following indication then Copy "deviceInputFields.xml" to `C:\GRL\Thread1.1\Web\data`. TelnetIP : device's IP address Param5 : 'ip' for SSH login Param6 : SSH username Param7 : SSH password Param8 : comma separated CLI prompt, Wpan command prefix, Wpan interface Param9 : comma separated device's setting commands before test
 
 6. Copy "OpenThread_WpanCtl.py" to `C:\GRL\Thread1.1\Thread_Harness\THCI`.
 
 7. Launch the Thread Test Harness Software, modify the default configuration if needed, and select **Start**.
 
-8. Drag the "OpenThread_WpanCtl: Wpantund + NCP (SSH)" reference device to the **Test Bed** section with the desired number.
-   Then fill in the Raspberry Pi IPv4 address and port and click `connect` icon button to get the NCP version.
+8. Drag the "OpenThread_WpanCtl: Wpantund + NCP (SSH)" reference device to the **Test Bed** section with the desired number. Then fill in the Raspberry Pi IPv4 address and port and click `connect` icon button to get the NCP version.
 
 9. Select one or more test cases to execute.
diff --git a/tools/spi-hdlc-adapter/README.md b/tools/spi-hdlc-adapter/README.md
index f98a29a..8bd310a 100644
--- a/tools/spi-hdlc-adapter/README.md
+++ b/tools/spi-hdlc-adapter/README.md
@@ -1,93 +1,52 @@
-SPI/HDLC Adapter
-================
+# SPI/HDLC Adapter
 
-`spi-hdlc-adapter` is an adapter tool for using a SPI interface as if
-it were an HDLC-lite encoded bidirectional asynchronous serial stream.
-It uses the SPI protocol outlined in [Appendix A.2][1] of the Spinel
-protocol document.
+`spi-hdlc-adapter` is an adapter tool for using a SPI interface as if it were an HDLC-lite encoded bidirectional asynchronous serial stream. It uses the SPI protocol outlined in [Appendix A.2][1] of the Spinel protocol document.
 
 [1]: https://goo.gl/gt18O4
 
-## Syntax ##
+## Syntax
 
     spi-hdlc-adapter [options] <spi-device-path>
 
-## Options ##
+## Options
 
-*   `--stdio`: Use `stdin` and `stdout` for HDLC input/output. Useful
-    when directly started by the program that will be using it.
-*   `--pty`: Create a pseudo terminal for HDLC input/output. The path
-    of the newly-created PTY will be written to `stdout`, followed by
-    a newline.
-*   `--raw`: Do not encode/decode packets using HDLC. Instead, write
-    whole, raw frames to the specified input and output FDs. This is
-    useful for emulating a serial port, or when datagram-based sockets
-    are supplied for `stdin` and `stdout` (when used with `--stdio`).
-*   `--mtu=[MTU]`: Specify the MTU. Currently only used in raw mode.
-    Default and maximum value is 2043. Must be greater than zero.
-*   `--gpio-int[=gpio-path]`: Specify a path to the Linux
-    sysfs-exported GPIO directory for the `I̅N̅T̅` pin. If not
-    specified, `spi-hdlc-adapter` will fall back to polling, which is
-    inefficient.
-*   `--gpio-reset[=gpio-path]`: Specify a path to the Linux
-    sysfs-exported GPIO directory for the `R̅E̅S̅` pin.
-*   `--spi-mode[=mode]`: Specify the SPI mode to use (0-3). Default
-    value is `0`.
-*   `--spi-speed[=hertz]`: Specify the SPI speed in hertz. Default
-    value is `1000000` (1MHz).
-*   `--spi-cs-delay[=usec]`: Specify the delay after C̅S̅ assertion,
-    in microseconds. Default is 20µs. Note that this may need to be
-    set to zero for spi-hdlc-adapter to work with some SPI drivers.
-*   `--spi-align-allowance[=n]`: Specify the maximum number of 0xFF
-    bytes to clip from start of MISO frame. This makes this tool usable
-    with SPI slaves which have buggy SPI blocks that prepend a variable
-    number of 0xFF bytes to the start of MISO frame. Default value is `0`.
-    Maximum value is `16`. *This should be set to `7` for chips in the
-    SiLabs EM35x family.*
-*   `--spi-small-packet=[n]`: Specify the smallest packet we can receive
-    in a single SPI transaction. Packets sent by the slave which are smaller
-    than or equal to this size will require only a single SPI transaction
-    to be successfully transmitted. Increasing this value will (up to a point)
-    decrease latency for smaller packets at the expense of overall bandwidth.
-    Default value is 32. The minimum value is 0. The maximum value is 2043.
-*   `--verbose[=num]`: Change log verbosity level (Repeatable).
-    num argument is optional and value 1 is default when not specified. Every
-    instance of this option will increment or decrement (when num is negative)
-    the syslog log level accordingly. Starting log level is LOG_NOTICE (5).
-*   `--help`: Print out usage information to `stdout` and exit.
+- `--stdio`: Use `stdin` and `stdout` for HDLC input/output. Useful when directly started by the program that will be using it.
+- `--pty`: Create a pseudo terminal for HDLC input/output. The path of the newly-created PTY will be written to `stdout`, followed by a newline.
+- `--raw`: Do not encode/decode packets using HDLC. Instead, write whole, raw frames to the specified input and output FDs. This is useful for emulating a serial port, or when datagram-based sockets are supplied for `stdin` and `stdout` (when used with `--stdio`).
+- `--mtu=[MTU]`: Specify the MTU. Currently only used in raw mode. Default and maximum value is 2043. Must be greater than zero.
+- `--gpio-int[=gpio-path]`: Specify a path to the Linux sysfs-exported GPIO directory for the `I̅N̅T̅` pin. If not specified, `spi-hdlc-adapter` will fall back to polling, which is inefficient.
+- `--gpio-reset[=gpio-path]`: Specify a path to the Linux sysfs-exported GPIO directory for the `R̅E̅S̅` pin.
+- `--spi-mode[=mode]`: Specify the SPI mode to use (0-3). Default value is `0`.
+- `--spi-speed[=hertz]`: Specify the SPI speed in hertz. Default value is `1000000` (1MHz).
+- `--spi-cs-delay[=usec]`: Specify the delay after C̅S̅ assertion, in microseconds. Default is 20µs. Note that this may need to be set to zero for spi-hdlc-adapter to work with some SPI drivers.
+- `--spi-align-allowance[=n]`: Specify the maximum number of 0xFF bytes to clip from start of MISO frame. This makes this tool usable with SPI slaves which have buggy SPI blocks that prepend a variable number of 0xFF bytes to the start of MISO frame. Default value is `0`. Maximum value is `16`. _This should be set to `7` for chips in the SiLabs EM35x family._
+- `--spi-small-packet=[n]`: Specify the smallest packet we can receive in a single SPI transaction. Packets sent by the slave which are smaller than or equal to this size will require only a single SPI transaction to be successfully transmitted. Increasing this value will (up to a point) decrease latency for smaller packets at the expense of overall bandwidth. Default value is 32. The minimum value is 0. The maximum value is 2043.
+- `--verbose[=num]`: Change log verbosity level (Repeatable). num argument is optional and value 1 is default when not specified. Every instance of this option will increment or decrement (when num is negative) the syslog log level accordingly. Starting log level is LOG_NOTICE (5).
+- `--help`: Print out usage information to `stdout` and exit.
 
-`spi-device-path` is a required argument since it indicates which SPI
-device to use. An example path might be `/dev/spidev1.0`.
+`spi-device-path` is a required argument since it indicates which SPI device to use. An example path might be `/dev/spidev1.0`.
 
-The GPIO paths are to the top-level directory for that GPIO. They must
-be already be exported before `spi-hdlc-adapter` can use them.
+The GPIO paths are to the top-level directory for that GPIO. They must be already be exported before `spi-hdlc-adapter` can use them.
 
-## Behavior ##
+## Behavior
 
-If an MCU reset is detected by the reset bit being set on a SPI frame,
-the special vendor-specific HDLC-lite symbol `0xF8` is emitted. If
-`--gpio-reset` is specified, the HDLC client can trigger an MCU reset
-by sending the symbols `0x7E 0x13 0x11 0x7E` or by sending `SIGUSR1`.
+If an MCU reset is detected by the reset bit being set on a SPI frame, the special vendor-specific HDLC-lite symbol `0xF8` is emitted. If `--gpio-reset` is specified, the HDLC client can trigger an MCU reset by sending the symbols `0x7E 0x13 0x11 0x7E` or by sending `SIGUSR1`.
 
-When started, `spi-hdlc-adapter` will configure the following
-properties on the GPIOs:
+When started, `spi-hdlc-adapter` will configure the following properties on the GPIOs:
 
 1.  Set `I̅N̅T̅/direction` to `in`.
 2.  Set `I̅N̅T̅/edge` to `falling`.
 3.  Set `R̅E̅S̅/direction` to `high`.
 
-When resetting the slave device, `spi-hdlc` performs the following
-procedure:
+When resetting the slave device, `spi-hdlc` performs the following procedure:
 
 1.  Set `R̅E̅S̅/direction` to `low`.
 2.  Sleep for 30ms.
 3.  Set `R̅E̅S̅/direction` to `high`.
 
-## Statistics ##
+## Statistics
 
-Some simple usage statistics are printed out to syslog at exit and
-whenever the `SIGUSR1` signal is received. The easiest way to send
-that signal to `spi-hdlc-adapter` is like this:
+Some simple usage statistics are printed out to syslog at exit and whenever the `SIGUSR1` signal is received. The easiest way to send that signal to `spi-hdlc-adapter` is like this:
 
     # killall -sigusr1 spi-hdlc-adapter